{"LICENSE":"                    GNU AFFERO GENERAL PUBLIC LICENSE\r\n                       Version 3, 19 November 2007\r\n\r\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\n                            Preamble\r\n\r\n  The GNU Affero General Public License is a free, copyleft license for\r\nsoftware and other kinds of works, specifically designed to ensure\r\ncooperation with the community in the case of network server software.\r\n\r\n  The licenses for most software and other practical works are designed\r\nto take away your freedom to share and change the works.  By contrast,\r\nour General Public Licenses are intended to guarantee your freedom to\r\nshare and change all versions of a program--to make sure it remains free\r\nsoftware for all its users.\r\n\r\n  When we speak of free software, we are referring to freedom, not\r\nprice.  Our General Public Licenses are designed to make sure that you\r\nhave the freedom to distribute copies of free software (and charge for\r\nthem if you wish), that you receive source code or can get it if you\r\nwant it, that you can change the software or use pieces of it in new\r\nfree programs, and that you know you can do these things.\r\n\r\n  Developers that use our General Public Licenses protect your rights\r\nwith two steps: (1) assert copyright on the software, and (2) offer\r\nyou this License which gives you legal permission to copy, distribute\r\nand/or modify the software.\r\n\r\n  A secondary benefit of defending all users' freedom is that\r\nimprovements made in alternate versions of the program, if they\r\nreceive widespread use, become available for other developers to\r\nincorporate.  Many developers of free software are heartened and\r\nencouraged by the resulting cooperation.  However, in the case of\r\nsoftware used on network servers, this result may fail to come about.\r\nThe GNU General Public License permits making a modified version and\r\nletting the public access it on a server without ever releasing its\r\nsource code to the public.\r\n\r\n  The GNU Affero General Public License is designed specifically to\r\nensure that, in such cases, the modified source code becomes available\r\nto the community.  It requires the operator of a network server to\r\nprovide the source code of the modified version running there to the\r\nusers of that server.  Therefore, public use of a modified version, on\r\na publicly accessible server, gives the public access to the source\r\ncode of the modified version.\r\n\r\n  An older license, called the Affero General Public License and\r\npublished by Affero, was designed to accomplish similar goals.  This is\r\na different license, not a version of the Affero GPL, but Affero has\r\nreleased a new version of the Affero GPL which permits relicensing under\r\nthis license.\r\n\r\n  The precise terms and conditions for copying, distribution and\r\nmodification follow.\r\n\r\n                       TERMS AND CONDITIONS\r\n\r\n  0. Definitions.\r\n\r\n  \"This License\" refers to version 3 of the GNU Affero General Public License.\r\n\r\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\r\nworks, such as semiconductor masks.\r\n\r\n  \"The Program\" refers to any copyrightable work licensed under this\r\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\r\n\"recipients\" may be individuals or organizations.\r\n\r\n  To \"modify\" a work means to copy from or adapt all or part of the work\r\nin a fashion requiring copyright permission, other than the making of an\r\nexact copy.  The resulting work is called a \"modified version\" of the\r\nearlier work or a work \"based on\" the earlier work.\r\n\r\n  A \"covered work\" means either the unmodified Program or a work based\r\non the Program.\r\n\r\n  To \"propagate\" a work means to do anything with it that, without\r\npermission, would make you directly or secondarily liable for\r\ninfringement under applicable copyright law, except executing it on a\r\ncomputer or modifying a private copy.  Propagation includes copying,\r\ndistribution (with or without modification), making available to the\r\npublic, and in some countries other activities as well.\r\n\r\n  To \"convey\" a work means any kind of propagation that enables other\r\nparties to make or receive copies.  Mere interaction with a user through\r\na computer network, with no transfer of a copy, is not conveying.\r\n\r\n  An interactive user interface displays \"Appropriate Legal Notices\"\r\nto the extent that it includes a convenient and prominently visible\r\nfeature that (1) displays an appropriate copyright notice, and (2)\r\ntells the user that there is no warranty for the work (except to the\r\nextent that warranties are provided), that licensees may convey the\r\nwork under this License, and how to view a copy of this License.  If\r\nthe interface presents a list of user commands or options, such as a\r\nmenu, a prominent item in the list meets this criterion.\r\n\r\n  1. Source Code.\r\n\r\n  The \"source code\" for a work means the preferred form of the work\r\nfor making modifications to it.  \"Object code\" means any non-source\r\nform of a work.\r\n\r\n  A \"Standard Interface\" means an interface that either is an official\r\nstandard defined by a recognized standards body, or, in the case of\r\ninterfaces specified for a particular programming language, one that\r\nis widely used among developers working in that language.\r\n\r\n  The \"System Libraries\" of an executable work include anything, other\r\nthan the work as a whole, that (a) is included in the normal form of\r\npackaging a Major Component, but which is not part of that Major\r\nComponent, and (b) serves only to enable use of the work with that\r\nMajor Component, or to implement a Standard Interface for which an\r\nimplementation is available to the public in source code form.  A\r\n\"Major Component\", in this context, means a major essential component\r\n(kernel, window system, and so on) of the specific operating system\r\n(if any) on which the executable work runs, or a compiler used to\r\nproduce the work, or an object code interpreter used to run it.\r\n\r\n  The \"Corresponding Source\" for a work in object code form means all\r\nthe source code needed to generate, install, and (for an executable\r\nwork) run the object code and to modify the work, including scripts to\r\ncontrol those activities.  However, it does not include the work's\r\nSystem Libraries, or general-purpose tools or generally available free\r\nprograms which are used unmodified in performing those activities but\r\nwhich are not part of the work.  For example, Corresponding Source\r\nincludes interface definition files associated with source files for\r\nthe work, and the source code for shared libraries and dynamically\r\nlinked subprograms that the work is specifically designed to require,\r\nsuch as by intimate data communication or control flow between those\r\nsubprograms and other parts of the work.\r\n\r\n  The Corresponding Source need not include anything that users\r\ncan regenerate automatically from other parts of the Corresponding\r\nSource.\r\n\r\n  The Corresponding Source for a work in source code form is that\r\nsame work.\r\n\r\n  2. Basic Permissions.\r\n\r\n  All rights granted under this License are granted for the term of\r\ncopyright on the Program, and are irrevocable provided the stated\r\nconditions are met.  This License explicitly affirms your unlimited\r\npermission to run the unmodified Program.  The output from running a\r\ncovered work is covered by this License only if the output, given its\r\ncontent, constitutes a covered work.  This License acknowledges your\r\nrights of fair use or other equivalent, as provided by copyright law.\r\n\r\n  You may make, run and propagate covered works that you do not\r\nconvey, without conditions so long as your license otherwise remains\r\nin force.  You may convey covered works to others for the sole purpose\r\nof having them make modifications exclusively for you, or provide you\r\nwith facilities for running those works, provided that you comply with\r\nthe terms of this License in conveying all material for which you do\r\nnot control copyright.  Those thus making or running the covered works\r\nfor you must do so exclusively on your behalf, under your direction\r\nand control, on terms that prohibit them from making any copies of\r\nyour copyrighted material outside their relationship with you.\r\n\r\n  Conveying under any other circumstances is permitted solely under\r\nthe conditions stated below.  Sublicensing is not allowed; section 10\r\nmakes it unnecessary.\r\n\r\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\r\n\r\n  No covered work shall be deemed part of an effective technological\r\nmeasure under any applicable law fulfilling obligations under article\r\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\r\nsimilar laws prohibiting or restricting circumvention of such\r\nmeasures.\r\n\r\n  When you convey a covered work, you waive any legal power to forbid\r\ncircumvention of technological measures to the extent such circumvention\r\nis effected by exercising rights under this License with respect to\r\nthe covered work, and you disclaim any intention to limit operation or\r\nmodification of the work as a means of enforcing, against the work's\r\nusers, your or third parties' legal rights to forbid circumvention of\r\ntechnological measures.\r\n\r\n  4. Conveying Verbatim Copies.\r\n\r\n  You may convey verbatim copies of the Program's source code as you\r\nreceive it, in any medium, provided that you conspicuously and\r\nappropriately publish on each copy an appropriate copyright notice;\r\nkeep intact all notices stating that this License and any\r\nnon-permissive terms added in accord with section 7 apply to the code;\r\nkeep intact all notices of the absence of any warranty; and give all\r\nrecipients a copy of this License along with the Program.\r\n\r\n  You may charge any price or no price for each copy that you convey,\r\nand you may offer support or warranty protection for a fee.\r\n\r\n  5. Conveying Modified Source Versions.\r\n\r\n  You may convey a work based on the Program, or the modifications to\r\nproduce it from the Program, in the form of source code under the\r\nterms of section 4, provided that you also meet all of these conditions:\r\n\r\n    a) The work must carry prominent notices stating that you modified\r\n    it, and giving a relevant date.\r\n\r\n    b) The work must carry prominent notices stating that it is\r\n    released under this License and any conditions added under section\r\n    7.  This requirement modifies the requirement in section 4 to\r\n    \"keep intact all notices\".\r\n\r\n    c) You must license the entire work, as a whole, under this\r\n    License to anyone who comes into possession of a copy.  This\r\n    License will therefore apply, along with any applicable section 7\r\n    additional terms, to the whole of the work, and all its parts,\r\n    regardless of how they are packaged.  This License gives no\r\n    permission to license the work in any other way, but it does not\r\n    invalidate such permission if you have separately received it.\r\n\r\n    d) If the work has interactive user interfaces, each must display\r\n    Appropriate Legal Notices; however, if the Program has interactive\r\n    interfaces that do not display Appropriate Legal Notices, your\r\n    work need not make them do so.\r\n\r\n  A compilation of a covered work with other separate and independent\r\nworks, which are not by their nature extensions of the covered work,\r\nand which are not combined with it such as to form a larger program,\r\nin or on a volume of a storage or distribution medium, is called an\r\n\"aggregate\" if the compilation and its resulting copyright are not\r\nused to limit the access or legal rights of the compilation's users\r\nbeyond what the individual works permit.  Inclusion of a covered work\r\nin an aggregate does not cause this License to apply to the other\r\nparts of the aggregate.\r\n\r\n  6. Conveying Non-Source Forms.\r\n\r\n  You may convey a covered work in object code form under the terms\r\nof sections 4 and 5, provided that you also convey the\r\nmachine-readable Corresponding Source under the terms of this License,\r\nin one of these ways:\r\n\r\n    a) Convey the object code in, or embodied in, a physical product\r\n    (including a physical distribution medium), accompanied by the\r\n    Corresponding Source fixed on a durable physical medium\r\n    customarily used for software interchange.\r\n\r\n    b) Convey the object code in, or embodied in, a physical product\r\n    (including a physical distribution medium), accompanied by a\r\n    written offer, valid for at least three years and valid for as\r\n    long as you offer spare parts or customer support for that product\r\n    model, to give anyone who possesses the object code either (1) a\r\n    copy of the Corresponding Source for all the software in the\r\n    product that is covered by this License, on a durable physical\r\n    medium customarily used for software interchange, for a price no\r\n    more than your reasonable cost of physically performing this\r\n    conveying of source, or (2) access to copy the\r\n    Corresponding Source from a network server at no charge.\r\n\r\n    c) Convey individual copies of the object code with a copy of the\r\n    written offer to provide the Corresponding Source.  This\r\n    alternative is allowed only occasionally and noncommercially, and\r\n    only if you received the object code with such an offer, in accord\r\n    with subsection 6b.\r\n\r\n    d) Convey the object code by offering access from a designated\r\n    place (gratis or for a charge), and offer equivalent access to the\r\n    Corresponding Source in the same way through the same place at no\r\n    further charge.  You need not require recipients to copy the\r\n    Corresponding Source along with the object code.  If the place to\r\n    copy the object code is a network server, the Corresponding Source\r\n    may be on a different server (operated by you or a third party)\r\n    that supports equivalent copying facilities, provided you maintain\r\n    clear directions next to the object code saying where to find the\r\n    Corresponding Source.  Regardless of what server hosts the\r\n    Corresponding Source, you remain obligated to ensure that it is\r\n    available for as long as needed to satisfy these requirements.\r\n\r\n    e) Convey the object code using peer-to-peer transmission, provided\r\n    you inform other peers where the object code and Corresponding\r\n    Source of the work are being offered to the general public at no\r\n    charge under subsection 6d.\r\n\r\n  A separable portion of the object code, whose source code is excluded\r\nfrom the Corresponding Source as a System Library, need not be\r\nincluded in conveying the object code work.\r\n\r\n  A \"User Product\" is either (1) a \"consumer product\", which means any\r\ntangible personal property which is normally used for personal, family,\r\nor household purposes, or (2) anything designed or sold for incorporation\r\ninto a dwelling.  In determining whether a product is a consumer product,\r\ndoubtful cases shall be resolved in favor of coverage.  For a particular\r\nproduct received by a particular user, \"normally used\" refers to a\r\ntypical or common use of that class of product, regardless of the status\r\nof the particular user or of the way in which the particular user\r\nactually uses, or expects or is expected to use, the product.  A product\r\nis a consumer product regardless of whether the product has substantial\r\ncommercial, industrial or non-consumer uses, unless such uses represent\r\nthe only significant mode of use of the product.\r\n\r\n  \"Installation Information\" for a User Product means any methods,\r\nprocedures, authorization keys, or other information required to install\r\nand execute modified versions of a covered work in that User Product from\r\na modified version of its Corresponding Source.  The information must\r\nsuffice to ensure that the continued functioning of the modified object\r\ncode is in no case prevented or interfered with solely because\r\nmodification has been made.\r\n\r\n  If you convey an object code work under this section in, or with, or\r\nspecifically for use in, a User Product, and the conveying occurs as\r\npart of a transaction in which the right of possession and use of the\r\nUser Product is transferred to the recipient in perpetuity or for a\r\nfixed term (regardless of how the transaction is characterized), the\r\nCorresponding Source conveyed under this section must be accompanied\r\nby the Installation Information.  But this requirement does not apply\r\nif neither you nor any third party retains the ability to install\r\nmodified object code on the User Product (for example, the work has\r\nbeen installed in ROM).\r\n\r\n  The requirement to provide Installation Information does not include a\r\nrequirement to continue to provide support service, warranty, or updates\r\nfor a work that has been modified or installed by the recipient, or for\r\nthe User Product in which it has been modified or installed.  Access to a\r\nnetwork may be denied when the modification itself materially and\r\nadversely affects the operation of the network or violates the rules and\r\nprotocols for communication across the network.\r\n\r\n  Corresponding Source conveyed, and Installation Information provided,\r\nin accord with this section must be in a format that is publicly\r\ndocumented (and with an implementation available to the public in\r\nsource code form), and must require no special password or key for\r\nunpacking, reading or copying.\r\n\r\n  7. Additional Terms.\r\n\r\n  \"Additional permissions\" are terms that supplement the terms of this\r\nLicense by making exceptions from one or more of its conditions.\r\nAdditional permissions that are applicable to the entire Program shall\r\nbe treated as though they were included in this License, to the extent\r\nthat they are valid under applicable law.  If additional permissions\r\napply only to part of the Program, that part may be used separately\r\nunder those permissions, but the entire Program remains governed by\r\nthis License without regard to the additional permissions.\r\n\r\n  When you convey a copy of a covered work, you may at your option\r\nremove any additional permissions from that copy, or from any part of\r\nit.  (Additional permissions may be written to require their own\r\nremoval in certain cases when you modify the work.)  You may place\r\nadditional permissions on material, added by you to a covered work,\r\nfor which you have or can give appropriate copyright permission.\r\n\r\n  Notwithstanding any other provision of this License, for material you\r\nadd to a covered work, you may (if authorized by the copyright holders of\r\nthat material) supplement the terms of this License with terms:\r\n\r\n    a) Disclaiming warranty or limiting liability differently from the\r\n    terms of sections 15 and 16 of this License; or\r\n\r\n    b) Requiring preservation of specified reasonable legal notices or\r\n    author attributions in that material or in the Appropriate Legal\r\n    Notices displayed by works containing it; or\r\n\r\n    c) Prohibiting misrepresentation of the origin of that material, or\r\n    requiring that modified versions of such material be marked in\r\n    reasonable ways as different from the original version; or\r\n\r\n    d) Limiting the use for publicity purposes of names of licensors or\r\n    authors of the material; or\r\n\r\n    e) Declining to grant rights under trademark law for use of some\r\n    trade names, trademarks, or service marks; or\r\n\r\n    f) Requiring indemnification of licensors and authors of that\r\n    material by anyone who conveys the material (or modified versions of\r\n    it) with contractual assumptions of liability to the recipient, for\r\n    any liability that these contractual assumptions directly impose on\r\n    those licensors and authors.\r\n\r\n  All other non-permissive additional terms are considered \"further\r\nrestrictions\" within the meaning of section 10.  If the Program as you\r\nreceived it, or any part of it, contains a notice stating that it is\r\ngoverned by this License along with a term that is a further\r\nrestriction, you may remove that term.  If a license document contains\r\na further restriction but permits relicensing or conveying under this\r\nLicense, you may add to a covered work material governed by the terms\r\nof that license document, provided that the further restriction does\r\nnot survive such relicensing or conveying.\r\n\r\n  If you add terms to a covered work in accord with this section, you\r\nmust place, in the relevant source files, a statement of the\r\nadditional terms that apply to those files, or a notice indicating\r\nwhere to find the applicable terms.\r\n\r\n  Additional terms, permissive or non-permissive, may be stated in the\r\nform of a separately written license, or stated as exceptions;\r\nthe above requirements apply either way.\r\n\r\n  8. Termination.\r\n\r\n  You may not propagate or modify a covered work except as expressly\r\nprovided under this License.  Any attempt otherwise to propagate or\r\nmodify it is void, and will automatically terminate your rights under\r\nthis License (including any patent licenses granted under the third\r\nparagraph of section 11).\r\n\r\n  However, if you cease all violation of this License, then your\r\nlicense from a particular copyright holder is reinstated (a)\r\nprovisionally, unless and until the copyright holder explicitly and\r\nfinally terminates your license, and (b) permanently, if the copyright\r\nholder fails to notify you of the violation by some reasonable means\r\nprior to 60 days after the cessation.\r\n\r\n  Moreover, your license from a particular copyright holder is\r\nreinstated permanently if the copyright holder notifies you of the\r\nviolation by some reasonable means, this is the first time you have\r\nreceived notice of violation of this License (for any work) from that\r\ncopyright holder, and you cure the violation prior to 30 days after\r\nyour receipt of the notice.\r\n\r\n  Termination of your rights under this section does not terminate the\r\nlicenses of parties who have received copies or rights from you under\r\nthis License.  If your rights have been terminated and not permanently\r\nreinstated, you do not qualify to receive new licenses for the same\r\nmaterial under section 10.\r\n\r\n  9. Acceptance Not Required for Having Copies.\r\n\r\n  You are not required to accept this License in order to receive or\r\nrun a copy of the Program.  Ancillary propagation of a covered work\r\noccurring solely as a consequence of using peer-to-peer transmission\r\nto receive a copy likewise does not require acceptance.  However,\r\nnothing other than this License grants you permission to propagate or\r\nmodify any covered work.  These actions infringe copyright if you do\r\nnot accept this License.  Therefore, by modifying or propagating a\r\ncovered work, you indicate your acceptance of this License to do so.\r\n\r\n  10. Automatic Licensing of Downstream Recipients.\r\n\r\n  Each time you convey a covered work, the recipient automatically\r\nreceives a license from the original licensors, to run, modify and\r\npropagate that work, subject to this License.  You are not responsible\r\nfor enforcing compliance by third parties with this License.\r\n\r\n  An \"entity transaction\" is a transaction transferring control of an\r\norganization, or substantially all assets of one, or subdividing an\r\norganization, or merging organizations.  If propagation of a covered\r\nwork results from an entity transaction, each party to that\r\ntransaction who receives a copy of the work also receives whatever\r\nlicenses to the work the party's predecessor in interest had or could\r\ngive under the previous paragraph, plus a right to possession of the\r\nCorresponding Source of the work from the predecessor in interest, if\r\nthe predecessor has it or can get it with reasonable efforts.\r\n\r\n  You may not impose any further restrictions on the exercise of the\r\nrights granted or affirmed under this License.  For example, you may\r\nnot impose a license fee, royalty, or other charge for exercise of\r\nrights granted under this License, and you may not initiate litigation\r\n(including a cross-claim or counterclaim in a lawsuit) alleging that\r\nany patent claim is infringed by making, using, selling, offering for\r\nsale, or importing the Program or any portion of it.\r\n\r\n  11. Patents.\r\n\r\n  A \"contributor\" is a copyright holder who authorizes use under this\r\nLicense of the Program or a work on which the Program is based.  The\r\nwork thus licensed is called the contributor's \"contributor version\".\r\n\r\n  A contributor's \"essential patent claims\" are all patent claims\r\nowned or controlled by the contributor, whether already acquired or\r\nhereafter acquired, that would be infringed by some manner, permitted\r\nby this License, of making, using, or selling its contributor version,\r\nbut do not include claims that would be infringed only as a\r\nconsequence of further modification of the contributor version.  For\r\npurposes of this definition, \"control\" includes the right to grant\r\npatent sublicenses in a manner consistent with the requirements of\r\nthis License.\r\n\r\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\r\npatent license under the contributor's essential patent claims, to\r\nmake, use, sell, offer for sale, import and otherwise run, modify and\r\npropagate the contents of its contributor version.\r\n\r\n  In the following three paragraphs, a \"patent license\" is any express\r\nagreement or commitment, however denominated, not to enforce a patent\r\n(such as an express permission to practice a patent or covenant not to\r\nsue for patent infringement).  To \"grant\" such a patent license to a\r\nparty means to make such an agreement or commitment not to enforce a\r\npatent against the party.\r\n\r\n  If you convey a covered work, knowingly relying on a patent license,\r\nand the Corresponding Source of the work is not available for anyone\r\nto copy, free of charge and under the terms of this License, through a\r\npublicly available network server or other readily accessible means,\r\nthen you must either (1) cause the Corresponding Source to be so\r\navailable, or (2) arrange to deprive yourself of the benefit of the\r\npatent license for this particular work, or (3) arrange, in a manner\r\nconsistent with the requirements of this License, to extend the patent\r\nlicense to downstream recipients.  \"Knowingly relying\" means you have\r\nactual knowledge that, but for the patent license, your conveying the\r\ncovered work in a country, or your recipient's use of the covered work\r\nin a country, would infringe one or more identifiable patents in that\r\ncountry that you have reason to believe are valid.\r\n\r\n  If, pursuant to or in connection with a single transaction or\r\narrangement, you convey, or propagate by procuring conveyance of, a\r\ncovered work, and grant a patent license to some of the parties\r\nreceiving the covered work authorizing them to use, propagate, modify\r\nor convey a specific copy of the covered work, then the patent license\r\nyou grant is automatically extended to all recipients of the covered\r\nwork and works based on it.\r\n\r\n  A patent license is \"discriminatory\" if it does not include within\r\nthe scope of its coverage, prohibits the exercise of, or is\r\nconditioned on the non-exercise of one or more of the rights that are\r\nspecifically granted under this License.  You may not convey a covered\r\nwork if you are a party to an arrangement with a third party that is\r\nin the business of distributing software, under which you make payment\r\nto the third party based on the extent of your activity of conveying\r\nthe work, and under which the third party grants, to any of the\r\nparties who would receive the covered work from you, a discriminatory\r\npatent license (a) in connection with copies of the covered work\r\nconveyed by you (or copies made from those copies), or (b) primarily\r\nfor and in connection with specific products or compilations that\r\ncontain the covered work, unless you entered into that arrangement,\r\nor that patent license was granted, prior to 28 March 2007.\r\n\r\n  Nothing in this License shall be construed as excluding or limiting\r\nany implied license or other defenses to infringement that may\r\notherwise be available to you under applicable patent law.\r\n\r\n  12. No Surrender of Others' Freedom.\r\n\r\n  If conditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License.  If you cannot convey a\r\ncovered work so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you may\r\nnot convey it at all.  For example, if you agree to terms that obligate you\r\nto collect a royalty for further conveying from those to whom you convey\r\nthe Program, the only way you could satisfy both those terms and this\r\nLicense would be to refrain entirely from conveying the Program.\r\n\r\n  13. Remote Network Interaction; Use with the GNU General Public License.\r\n\r\n  Notwithstanding any other provision of this License, if you modify the\r\nProgram, your modified version must prominently offer all users\r\ninteracting with it remotely through a computer network (if your version\r\nsupports such interaction) an opportunity to receive the Corresponding\r\nSource of your version by providing access to the Corresponding Source\r\nfrom a network server at no charge, through some standard or customary\r\nmeans of facilitating copying of software.  This Corresponding Source\r\nshall include the Corresponding Source for any work covered by version 3\r\nof the GNU General Public License that is incorporated pursuant to the\r\nfollowing paragraph.\r\n\r\n  Notwithstanding any other provision of this License, you have\r\npermission to link or combine any covered work with a work licensed\r\nunder version 3 of the GNU General Public License into a single\r\ncombined work, and to convey the resulting work.  The terms of this\r\nLicense will continue to apply to the part which is the covered work,\r\nbut the work with which it is combined will remain governed by version\r\n3 of the GNU General Public License.\r\n\r\n  14. Revised Versions of this License.\r\n\r\n  The Free Software Foundation may publish revised and/or new versions of\r\nthe GNU Affero General Public License from time to time.  Such new versions\r\nwill be similar in spirit to the present version, but may differ in detail to\r\naddress new problems or concerns.\r\n\r\n  Each version is given a distinguishing version number.  If the\r\nProgram specifies that a certain numbered version of the GNU Affero General\r\nPublic License \"or any later version\" applies to it, you have the\r\noption of following the terms and conditions either of that numbered\r\nversion or of any later version published by the Free Software\r\nFoundation.  If the Program does not specify a version number of the\r\nGNU Affero General Public License, you may choose any version ever published\r\nby the Free Software Foundation.\r\n\r\n  If the Program specifies that a proxy can decide which future\r\nversions of the GNU Affero General Public License can be used, that proxy's\r\npublic statement of acceptance of a version permanently authorizes you\r\nto choose that version for the Program.\r\n\r\n  Later license versions may give you additional or different\r\npermissions.  However, no additional obligations are imposed on any\r\nauthor or copyright holder as a result of your choosing to follow a\r\nlater version.\r\n\r\n  15. Disclaimer of Warranty.\r\n\r\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\r\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\r\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\r\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\r\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\r\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\r\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r\n\r\n  16. Limitation of Liability.\r\n\r\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\r\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\r\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\r\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\r\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\r\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\r\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\r\nSUCH DAMAGES.\r\n\r\n  17. Interpretation of Sections 15 and 16.\r\n\r\n  If the disclaimer of warranty and limitation of liability provided\r\nabove cannot be given local legal effect according to their terms,\r\nreviewing courts shall apply local law that most closely approximates\r\nan absolute waiver of all civil liability in connection with the\r\nProgram, unless a warranty or assumption of liability accompanies a\r\ncopy of the Program in return for a fee.\r\n\r\n                     END OF TERMS AND CONDITIONS\r\n\r\n            How to Apply These Terms to Your New Programs\r\n\r\n  If you develop a new program, and you want it to be of the greatest\r\npossible use to the public, the best way to achieve this is to make it\r\nfree software which everyone can redistribute and change under these terms.\r\n\r\n  To do so, attach the following notices to the program.  It is safest\r\nto attach them to the start of each source file to most effectively\r\nstate the exclusion of warranty; and each file should have at least\r\nthe \"copyright\" line and a pointer to where the full notice is found.\r\n\r\n    <one line to give the program's name and a brief idea of what it does.>\r\n    Copyright (C) <year>  <name of author>\r\n\r\n    This program is free software: you can redistribute it and/or modify\r\n    it under the terms of the GNU Affero General Public License as published by\r\n    the Free Software Foundation, either version 3 of the License, or\r\n    (at your option) any later version.\r\n\r\n    This program is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Affero General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Affero General Public License\r\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\r\n\r\nAlso add information on how to contact you by electronic and paper mail.\r\n\r\n  If your software can interact with users remotely through a computer\r\nnetwork, you should also make sure that it provides a way for users to\r\nget its source.  For example, if your program is a web application, its\r\ninterface could display a \"Source\" link that leads users to an archive\r\nof the code.  There are many ways you could offer source, and different\r\nsolutions will be better for different programs; see section 13 for the\r\nspecific requirements.\r\n\r\n  You should also get your employer (if you work as a programmer) or school,\r\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\r\nFor more information on this, and how to apply and follow the GNU AGPL, see\r\n<https://www.gnu.org/licenses/>.\r\n","about.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\r\n<title>About MYR5 · free AR alien workout coach</title>\r\n<meta name=\"description\" content=\"MYR5 is a free browser workout app with a 3D alien coach. Your phone camera counts reps and holds on the device; nothing is uploaded. Ages 13+.\">\r\n<link rel=\"canonical\" href=\"https://myr5.mominc.online/about\">\r\n<meta property=\"og:type\" content=\"website\"><meta property=\"og:site_name\" content=\"MYR5 Coach\"><meta property=\"og:url\" content=\"https://myr5.mominc.online/about\"><meta property=\"og:title\" content=\"About MYR5 · free AR alien workout coach\"><meta property=\"og:description\" content=\"Free browser workout app. A 3D alien coach counts your reps with your phone camera, on-device.\"><meta property=\"og:image\" content=\"https://myr5.mominc.online/icons/myr5-alien-512.png\">\r\n<link rel=\"icon\" href=\"/icons/myr5-alien-192.png\"><link rel=\"stylesheet\" href=\"/signin.css\"><style>main{width:min(100% - 40px,740px)}h2{margin-top:32px;font-size:22px}a{color:#dfb7ff}li{margin:8px 0;line-height:1.5}</style>\r\n<script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://myr5.mominc.online/#operator\",\"name\":\"MYR5\",\"description\":\"Independent app maker of MYR5 Coach\",\"url\":\"https://myr5.mominc.online/about\",\"email\":\"ianmyersrocks97@gmail.com\"},{\"@type\":\"SoftwareApplication\",\"@id\":\"https://myr5.mominc.online/#app\",\"name\":\"MYR5 Coach\",\"alternateName\":\"MYR5\",\"url\":\"https://myr5.mominc.online/\",\"applicationCategory\":\"HealthApplication\",\"applicationSubCategory\":\"Fitness\",\"operatingSystem\":\"Any modern browser (Android, iOS, desktop)\",\"offers\":{\"@type\":\"Offer\",\"price\":\"0\",\"priceCurrency\":\"USD\"},\"typicalAgeRange\":\"13-\",\"publisher\":{\"@id\":\"https://myr5.mominc.online/#operator\"}},{\"@type\":\"FAQPage\",\"mainEntity\":[{\"@type\":\"Question\",\"name\":\"Does MYR5 upload my camera video?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"No. All camera and pose processing stays on your phone. Camera frames are not sent to a server.\"}},{\"@type\":\"Question\",\"name\":\"Do I need a VR headset, console or equipment?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"No. MYR5 runs in a phone or computer browser and uses bodyweight exercises. Prop the phone so the camera can see you.\"}},{\"@type\":\"Question\",\"name\":\"Who is MYR5 for?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Teens, adults, and families with teens. MYR5 is for ages 13 and up and is not directed to children under 13.\"}},{\"@type\":\"Question\",\"name\":\"How much does MYR5 cost?\",\"acceptedAnswer\":{\"@type\":\"Answer\",\"text\":\"Nothing. MYR5 is free and has no paid features or subscription.\"}}]}]}</script>\r\n</head><body><main><a class=\"brand\" href=\"/\"><img src=\"/icons/myr5-alien-192.png\" alt=\"MYR5\"><span>MYR5</span></a>\r\n<h1>About MYR5</h1>\r\n<p>MYR5 (MYR5 Coach) is a free web app that turns bodyweight workouts into a game with a 3D alien coach. It runs in your phone or computer browser and installs from the browser as an app. No app store, VR headset, console or equipment is needed.</p>\r\n<h2>How it works</h2>\r\n<p>Prop your phone so its camera can see you. Your alien coach demonstrates each move, and on-device pose tracking counts your reps or times your holds. Finished sets level up your coach, unlock rewards and fuel battles in the rest chamber. You can customize your coach and set workout reminders.</p>\r\n<p>The camera can follow 57 movements in 10 groups:</p>\r\n<ul>\r\n<li>Chest: push-up progressions, from knee and incline push-ups to diamond and feet-elevated push-ups</li>\r\n<li>Legs: squats, split squats and wall sits</li>\r\n<li>Hips and glutes: hip hinges, good mornings and glute bridges</li>\r\n<li>Core: plank and side plank holds</li>\r\n<li>Shoulders: arm raises, overhead reaches and unloaded presses</li>\r\n<li>Balance: knee-lift balance and tree pose holds</li>\r\n<li>Yoga: Mountain, Upward salute, Chair, Warrior I, Warrior II and Goddess</li>\r\n<li>Martial stances: horse stance and front stance holds</li>\r\n<li>Boxing: slow shadowboxing straights and jabs</li>\r\n<li>Cardio: marches, jogging in place, step jacks and jumping jacks</li>\r\n</ul>\r\n<p>Counts and hold times are estimates from pose tracking. They do not grade technique and are not medical or professional advice.</p>\r\n<h2 id=\"faq\">Facts</h2>\r\n<ul>\r\n<li><strong>Price:</strong> free. There are no paid features or subscription.</li>\r\n<li><strong>Camera privacy:</strong> all camera and pose processing stays on your phone. Camera frames are not uploaded.</li>\r\n<li><strong>Age:</strong> 13 and up. MYR5 is for teens, adults, and families with teens. It is not directed to children under 13.</li>\r\n<li><strong>Equipment:</strong> none. A phone or computer with a camera and a modern browser (JavaScript and WebGL).</li>\r\n<li><strong>Accounts:</strong> optional sign-in saves your coach and workout history across devices. You can download or delete your saved data in account settings.</li>\r\n</ul>\r\n<h2>Who makes MYR5</h2>\r\n<p>MYR5 is an independent app, operated by MYR5. Contact: <a href=\"mailto:ianmyersrocks97@gmail.com\">ianmyersrocks97@gmail.com</a>.</p>\r\n<p>The alien coaches also appear on <a href=\"https://mominc.online\">mominc.online</a>, home of MOM Inc., who would like you to know your reps are \"synergizing.\" (MOM Inc. is fictional.)</p>\r\n<p><a href=\"/privacy\">Privacy</a> · <a href=\"/\">Open MYR5</a></p>\r\n</main></body></html>\r\n","account-readiness-client.mjs":"const validScope=value=>typeof value?.user?.id==='string'&&value.user.id&&Number.isSafeInteger(value.dataEpoch)&&value.dataEpoch>0;\r\nconst same=(account,scope)=>account?.user?.id===scope.owner&&account?.dataEpoch===scope.epoch;\r\nconst choose=(previous,next)=>{\r\n if(!next||next.state==='unknown')return previous??next;\r\n if(!previous||!Number.isSafeInteger(previous.startedAt))return next;\r\n if(!Number.isSafeInteger(next.startedAt)||next.startedAt<previous.startedAt||next.startedAt===previous.startedAt&&String(next.observationId)<String(previous.observationId))return previous;\r\n return next;\r\n};\r\n// Optional cache observations cannot establish sign-in or replace core account\r\n// data. This helper retains no persisted browser authority and never retries.\r\nexport function createAccountReadinessRefresh({api,transitions,getAccount,apply}){\r\n let generation=0;\r\n transitions.subscribe(()=>generation++);\r\n async function refresh(){\r\n  const account=getAccount();if(!validScope(account))return false;\r\n  const scope={owner:account.user.id,epoch:account.dataEpoch},number=++generation;\r\n  let ticket;try{\r\n   ticket=transitions.capture();const result=await api('/api/account/readiness');\r\n   if(!transitions.isCurrent(ticket)||number!==generation||!same(getAccount(),scope)||result.targetAccountId!==scope.owner||result.dataEpoch!==scope.epoch)return false;\r\n   const current=getAccount(),readiness={reminders:choose(current.readiness?.reminders,result.readiness?.reminders),training:choose(current.readiness?.training,result.readiness?.training)};\r\n   // Preserve the last successful push configuration on an independent failure.\r\n   const health=readiness.reminders,push=health?.push?{...current.push,...health.push,status:health.state}:result.push&&['ready','available'].includes(result.push.status)&&(!health||health.state==='unknown')?{...current.push,...result.push}:health?{...current.push,status:health.state}:current.push;\r\n   apply({readiness,push},scope);return true;\r\n  }catch{return false;} // Optional observation failure does not mark core data stale.\r\n }\r\n return {refresh};\r\n}\r\n","account-session-actions.mjs":"const fail=code=>{throw Object.assign(Error('Account changed. Refresh before continuing.'),{code});};\r\nfunction scope(account){\r\n // Signed out is not an account change: say what unlocks it (breathing and onboarding save to the account).\r\n if(!account?.user)throw Object.assign(Error('Sign in to continue.'),{code:'account_scope_unavailable'});\r\n if(typeof account?.user?.id!=='string'||!account.user.id||!Number.isSafeInteger(account.dataEpoch)||account.dataEpoch<1)fail('account_scope_unavailable');\r\n return Object.freeze({ownerId:account.user.id,dataEpoch:account.dataEpoch});\r\n}\r\nconst headers=target=>({'X-Target-Account':target.ownerId,'X-Expected-Data-Epoch':String(target.dataEpoch)});\r\nexport function createAccountSessionActions({api,transitions}){\r\n const fresh=async(target,ticket)=>{\r\n  transitions.assertCurrent(ticket);\r\n  const live=scope(await api('/api/account?core=1'));\r\n  transitions.assertCurrent(ticket);\r\n  if(live.ownerId!==target.ownerId||live.dataEpoch!==target.dataEpoch)fail('account_scope_changed');\r\n };\r\n const receipt=(result,target)=>{if(result?.targetAccountId!==target.ownerId||result?.dataEpoch!==target.dataEpoch)fail('invalid_breathing_receipt');};\r\n return Object.freeze({\r\n  async saveOnboarding(displayedAccount,value){\r\n   const target=scope(displayedAccount),ticket=transitions.capture(),revision=displayedAccount.onboarding?.revision??0,data=structuredClone(value);\r\n   if(!Number.isSafeInteger(revision)||revision<0)fail('invalid_onboarding_revision');\r\n   await fresh(target,ticket);transitions.assertCurrent(ticket);\r\n   const result=await api('/api/onboarding','PUT',{data,revision},headers(target));\r\n   transitions.assertCurrent(ticket);return Object.freeze({result,ownerId:target.ownerId,dataEpoch:target.dataEpoch,transitionTicket:ticket});\r\n  },\r\n  async startBreathing(displayedAccount){\r\n   const target=scope(displayedAccount),ticket=transitions.capture();\r\n   await fresh(target,ticket);transitions.assertCurrent(ticket);\r\n   const result=await api('/api/breathing/start','POST',{},headers(target));\r\n   transitions.assertCurrent(ticket);receipt(result,target);\r\n   if(typeof result.id!=='string'||!result.id||result.id.length>128||!Number.isSafeInteger(result.startedAt)||result.startedAt<0||!Number.isSafeInteger(result.durationMs)||result.durationMs<=0)fail('invalid_breathing_ticket');\r\n   return Object.freeze({id:result.id,startedAt:result.startedAt,durationMs:result.durationMs,...target,transitionTicket:ticket});\r\n  },\r\n  async completeBreathing(binding,activeMs){\r\n   if(!binding||typeof binding.id!=='string'||!Number.isFinite(activeMs)||activeMs<0)fail('invalid_breathing_ticket');\r\n   const target=scope({user:{id:binding.ownerId},dataEpoch:binding.dataEpoch}),ticket=binding.transitionTicket;\r\n   await fresh(target,ticket);transitions.assertCurrent(ticket);\r\n   const result=await api('/api/breathing/complete','POST',{id:binding.id,activeMs},headers(target));\r\n   transitions.assertCurrent(ticket);receipt(result,target);return result;\r\n  },\r\n });\r\n}\r\n","account-workout-sync.mjs":"// Legacy account queue only. Never reads or drains the guest Dexie outbox.\r\nexport const accountPendingKey=owner=>`myr5-pending-sets:${owner}`;\r\nconst TICKET_KEY='myr5-server-workout-tickets-v1',UNBOUND_KEY='myr5-unbound-server-completions-v1';\r\nconst failure=code=>Object.assign(Error('Your round is waiting for account reconciliation.'),{code});\r\nconst scope=value=>value?.user?.id&&Number.isSafeInteger(value.dataEpoch)&&value.dataEpoch>0?{owner:value.user.id,epoch:value.dataEpoch}:null;\r\nexport function validateAccountDeletionReceipt(value,owner,requestedEpoch){\r\n if(!value||value.ownerId!==owner||value.deletedEpoch!==requestedEpoch||typeof value.alreadyDeleted!=='boolean'||value.deleted!==!value.alreadyDeleted||!Number.isSafeInteger(requestedEpoch)||requestedEpoch<1||!Number.isSafeInteger(value.currentDataEpoch)||!Number.isSafeInteger(value.deletedThroughEpoch)||value.deletedThroughEpoch<requestedEpoch||value.currentDataEpoch!==value.deletedThroughEpoch+1||(!value.alreadyDeleted&&value.deletedThroughEpoch!==requestedEpoch))throw failure('invalid_account_deletion_receipt');\r\n return value.deletedThroughEpoch;\r\n}\r\nexport function createAccountWorkoutSync({storage,api,transitions,getAccount,publishProgress}){\r\n const read=(key,fallback)=>{try{const value=storage.getItem(key);return value===null?fallback:JSON.parse(value);}catch{throw failure('account_queue_unavailable');}};\r\n const write=(key,value)=>{try{const text=JSON.stringify(value);storage.setItem(key,text);if(storage.getItem(key)!==text)throw Error();}catch{throw failure('account_queue_unavailable');}};\r\n const pending=owner=>{const rows=read(accountPendingKey(owner),[]);if(!Array.isArray(rows))throw failure('account_queue_unavailable');return rows;};\r\n const assertScope=(ticket,expected)=>{transitions.assertCurrent(ticket);const selected=scope(getAccount());if(!selected||selected.owner!==expected.owner||selected.epoch!==expected.epoch)throw failure('account_scope_changed');};\r\n const fresh=async(ticket,expected)=>{assertScope(ticket,expected);const value=await api('/api/account?core=1');assertScope(ticket,expected);const live=scope(value);if(!live||live.owner!==expected.owner||live.epoch!==expected.epoch)throw failure('account_scope_changed');return value;};\r\n let flushing;\r\n async function drain(){\r\n  const selected=scope(getAccount());if(!selected)return;\r\n  const ticket=transitions.capture(),queue=pending(selected.owner);\r\n  for(const item of queue){\r\n   assertScope(ticket,selected);\r\n   // Old untagged completions remain parked; never label them with today's epoch.\r\n   if(!item||item.targetAccountId!==selected.owner||item.targetDataEpoch!==selected.epoch)throw failure('account_queue_unbound');\r\n   await fresh(ticket,selected);assertScope(ticket,selected);\r\n   const {targetAccountId,targetDataEpoch,...body}=item;\r\n   const response=await api('/api/workouts/complete','POST',body,{'X-Target-Account':targetAccountId,'X-Expected-Data-Epoch':String(targetDataEpoch)});\r\n   assertScope(ticket,selected);\r\n   if(response?.targetAccountId!==targetAccountId||response?.dataEpoch!==targetDataEpoch)throw failure('invalid_completion_receipt');\r\n   if(!response?.progress||!Number.isSafeInteger(response.progress.completedSets)||response.progress.completedSets<0||!Number.isSafeInteger(response.progress.xp)||response.progress.xp<0)throw failure('invalid_completion_response');\r\n   const latest=pending(selected.owner),index=latest.findIndex(row=>row.id===item.id);\r\n   if(index<0)continue;\r\n   if(JSON.stringify(latest[index])!==JSON.stringify(item))throw failure('account_queue_changed');\r\n   write(accountPendingKey(selected.owner),latest.filter((_,i)=>i!==index));\r\n   assertScope(ticket,selected);publishProgress({...response.progress,lastSyncedWorkoutId:item.id});\r\n  }\r\n }\r\n const flush=()=>flushing??=(async()=>{try{return await drain();}finally{flushing=null;}})();\r\n return Object.freeze({\r\n  pending,flush,\r\n  forgetDeletedAccount(owner,deletedThroughEpoch){\r\n   if(typeof owner!=='string'||!owner||!Number.isSafeInteger(deletedThroughEpoch)||deletedThroughEpoch<1)throw failure('invalid_account_deletion_receipt');\r\n   const covered=row=>row?.targetAccountId===owner&&Number.isSafeInteger(row.targetDataEpoch)&&row.targetDataEpoch>0&&row.targetDataEpoch<=deletedThroughEpoch;\r\n   const tickets=read(TICKET_KEY,{});if(!tickets||typeof tickets!=='object'||Array.isArray(tickets))throw failure('account_queue_unavailable');\r\n   write(accountPendingKey(owner),pending(owner).filter(row=>!covered(row)));\r\n   write(TICKET_KEY,Object.fromEntries(Object.entries(tickets).filter(([,ticket])=>!covered(ticket))));\r\n  },\r\n  async start(mode,goal){\r\n   const selected=scope(getAccount());if(!selected)throw failure('account_scope_changed');\r\n   const ticket=transitions.capture();await flush();assertScope(ticket,selected);await fresh(ticket,selected);\r\n   const result=await api('/api/workouts/start','POST',{mode,goal},{'X-Target-Account':selected.owner,'X-Expected-Data-Epoch':String(selected.epoch)});\r\n   assertScope(ticket,selected);\r\n   if(typeof result.id!=='string'||!result.id||result.id.length>128||!Number.isSafeInteger(result.startedAt)||result.startedAt<0||result.targetAccountId!==selected.owner||result.dataEpoch!==selected.epoch)throw failure('invalid_workout_ticket');\r\n   const tickets=read(TICKET_KEY,{});\r\n   if(!tickets||typeof tickets!=='object'||Array.isArray(tickets)||Object.hasOwn(tickets,result.id))throw failure('account_ticket_conflict');\r\n   Object.defineProperty(tickets,result.id,{value:{id:result.id,targetAccountId:selected.owner,targetDataEpoch:selected.epoch,startedAt:result.startedAt},enumerable:true,writable:true,configurable:true});\r\n   write(TICKET_KEY,tickets);return result;\r\n  },\r\n  async complete(data){\r\n   const selected=scope(getAccount());if(!selected)throw failure('account_scope_changed');\r\n   const ticket=transitions.capture(),tickets=read(TICKET_KEY,{}),binding=Object.hasOwn(tickets,data.id)?tickets[data.id]:null;\r\n   if(binding&&(binding.targetAccountId!==selected.owner||binding.targetDataEpoch!==selected.epoch))throw failure('account_scope_changed');\r\n   if(!binding){const unbound=read(UNBOUND_KEY,[]);if(!Array.isArray(unbound))throw failure('account_queue_unavailable');if(!unbound.some(row=>row.id===data.id)){assertScope(ticket,selected);write(UNBOUND_KEY,[...unbound,{id:data.id,value:data.value,...(data.active===undefined?{}:{active:data.active})}]);}throw failure('account_queue_unbound');}\r\n   const queue=pending(selected.owner);\r\n   if(!queue.some(row=>row.id===data.id)){\r\n    // An unrecognized legacy ticket is retained without invented account epoch.\r\n    const item={id:data.id,value:data.value,...(data.active===undefined?{}:{active:data.active}),...(binding?{targetAccountId:binding.targetAccountId,targetDataEpoch:binding.targetDataEpoch}:{})};\r\n    assertScope(ticket,selected);write(accountPendingKey(selected.owner),[...queue,item]);\r\n   }\r\n   await flush();assertScope(ticket,selected);\r\n   if(pending(selected.owner).some(row=>row.id===data.id))throw failure('account_completion_pending');\r\n  },\r\n });\r\n}\r\n","achievements-board.css":"﻿/* Achievements / battle-pass board, styled after Skyrim's skill constellations: dim stars until earned,\r\n   a slow camera glide into the chosen boss, thin all-caps text with a hairline rule. */\r\n@font-face{font-family:'Barlow Condensed';src:url('/handborne/fonts/barlow-400.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}\r\n.ach-board{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;background:#05030c;color:#fff;overflow:hidden;font:16px/1.4 'Barlow Condensed',var(--font,system-ui);letter-spacing:.04em}\r\n.ach-board[open]{display:grid;place-items:center}\r\n.ach-board::backdrop{background:#000}\r\n.ach-stage{position:relative;aspect-ratio:1141/2000;height:min(100dvh,calc(100vw * 2000 / 1141))}\r\n/* Art, bosses and the three star layers each carry their own zoom transform (parallax factor per layer). */\r\n.ach-parallax{transition:transform .9s cubic-bezier(.22,.61,.36,1);will-change:transform}\r\n.ach-art{position:absolute;inset:0;width:100%;height:100%;display:block;user-select:none;-webkit-user-drag:none}\r\n.ach-stars{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;transition:opacity .5s}\r\n.ach-stars i{position:absolute;width:3px;height:3px;border-radius:50%;background:#fff;box-shadow:0 0 6px 1px #fff;opacity:0;animation:ach-star 3s ease-in-out infinite alternate;animation-delay:var(--d)}\r\n.ach-bosses{position:absolute;inset:0}\r\n.ach-boss{position:absolute;margin:0;padding:0;border:0;background:none;border-radius:14px;cursor:pointer;-webkit-tap-highlight-color:transparent}\r\n.ach-boss:focus-visible{outline:2px solid var(--glow);outline-offset:4px}\r\n/* Beaten bosses: the same slice of the art screened over itself, once blurred (bloom) and once sharp, feathered so no rectangle shows. */\r\n.ach-boss[data-state=done]::before,.ach-boss[data-state=done]::after{content:'';position:absolute;inset:0;pointer-events:none;background:url(/pod/worlds/achievements.jpg) no-repeat;background-size:calc(10000% / var(--bw)) auto;background-position:calc(var(--bx) / (100 - var(--bw)) * 100%) calc(var(--by) / (100 - var(--bh)) * 100%);mix-blend-mode:screen;-webkit-mask:radial-gradient(ellipse at center,#000 45%,transparent 74%);mask:radial-gradient(ellipse at center,#000 45%,transparent 74%);animation:ach-twinkle 2.6s ease-in-out infinite alternate;animation-delay:var(--d)}\r\n.ach-boss[data-state=done]::before{filter:blur(10px) brightness(1.7) saturate(1.4)}\r\n.ach-boss[data-state=done]::after{filter:brightness(1.35) saturate(1.2)}\r\n.ach-boss[data-state=locked]{background:radial-gradient(ellipse at center,#03020ce8 40%,#03020c99 60%,transparent 78%)}\r\n.ach-boss.selected{background:radial-gradient(ellipse at center,#ffffff38 12%,transparent 68%);animation:ach-pulse 1.4s ease-in-out infinite alternate}\r\n.ach-head{position:absolute;top:max(14px,env(safe-area-inset-top));left:18px;right:72px;text-transform:uppercase;text-shadow:0 0 10px #000,0 1px 2px #000;transition:opacity .4s}\r\n.ach-head h1{margin:0;font-size:22px;font-weight:400;letter-spacing:.2em}\r\n.ach-head p{margin:2px 0 0;font-size:14px;letter-spacing:.14em;color:#cfc8e6}\r\n.ach-head::after{content:'';display:block;height:1px;margin-top:8px;background:linear-gradient(90deg,#fffc,transparent)}\r\n.ach-board.zoomed .ach-head{opacity:0}\r\n/* Zoomed: dim the far/mid star layers so the detail card stays legible; near debris keeps flying over it. */\r\n.ach-board.zoomed [data-depth=far],.ach-board.zoomed [data-depth=mid]{opacity:.5}\r\n.ach-detail{position:absolute;left:0;right:0;bottom:0;box-sizing:border-box;max-height:62%;padding:34px 24px calc(24px + env(safe-area-inset-bottom));overflow:auto;overscroll-behavior:contain;text-align:center;background:linear-gradient(#0000,#05030cd9 24%,#05030cf5);animation:ach-rise .5s ease}\r\n.ach-detail[hidden]{display:none}\r\n.ach-detail h2{margin:0;font-size:36px;font-weight:400;letter-spacing:.16em;text-transform:uppercase;text-shadow:0 0 18px var(--glow),0 0 2px #fff}\r\n.ach-detail hr{width:min(320px,80%);height:1px;border:0;margin:10px auto 12px;background:linear-gradient(90deg,transparent,#fff,transparent)}\r\n.ach-detail .ach-status{margin:0 0 16px;font-size:16px;letter-spacing:.12em;text-transform:uppercase;color:#d9d2ee}\r\n.ach-detail ol{list-style:none;margin:0 auto;padding:0;display:grid;gap:8px;width:min(360px,100%);text-align:left}\r\n.ach-detail li{display:grid;grid-template-columns:18px 70px 1fr;gap:10px;align-items:baseline;font-size:17px}\r\n/* \\2726 (a CSS numeric escape, not the raw UTF-8 bytes) so the glyph can't mojibake if this file\r\n   is ever served/read without an explicit UTF-8 charset — the escape is pure ASCII in the source. */\r\n.ach-detail li::before{content:'\\2726';color:#5e5878;font-size:12px}\r\n.ach-detail li[data-step=done]::before{color:#fff;text-shadow:0 0 8px var(--glow),0 0 14px var(--glow)}\r\n.ach-detail li[data-step=next]::before{color:var(--glow);animation:ach-twinkle 1.2s ease-in-out infinite alternate}\r\n.ach-detail li[data-step=todo]{color:#8f89a8}\r\n.ach-detail li i{font-style:normal}\r\n.ach-detail li b{font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#e9e3ff}\r\n.ach-back{margin-top:18px;min-height:44px;padding:0 6px;border:0;border-bottom:1px solid #fff9;background:none;color:#fff;font:400 17px/1 'Barlow Condensed',var(--font,system-ui);letter-spacing:.2em;text-transform:uppercase}\r\n.ach-close{position:absolute;top:max(12px,env(safe-area-inset-top));right:12px;width:44px;height:44px;border-radius:50%;border:1px solid #ffffff55;background:#05030ccc;color:#fff;font-size:18px}\r\n@keyframes ach-twinkle{from{opacity:.5}to{opacity:1}}\r\n@keyframes ach-pulse{from{opacity:.45}to{opacity:1}}\r\n@keyframes ach-star{from{opacity:0;transform:scale(.6)}to{opacity:1;transform:scale(1.3)}}\r\n@keyframes ach-rise{from{transform:translateY(24px);opacity:0}}\r\n@media (prefers-reduced-motion:no-preference){\r\n/* The locked intake theme turns off every animation; the board twinkles for everyone. */\r\nhtml[data-public-state] .ach-board .ach-stars i{animation:ach-star 3s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] .ach-board .ach-boss.selected{animation:ach-pulse 1.4s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] .ach-board .ach-detail{animation:ach-rise .5s ease!important}\r\nhtml[data-public-state] .ach-board .ach-parallax{transition:transform .9s cubic-bezier(.22,.61,.36,1)!important}\r\n}\r\n/* Reduced motion: no drift/debris flight, no rAF loop (gated in JS); dots sit at .8 opacity, same as before. */\r\n@media (prefers-reduced-motion:reduce){.ach-board .ach-parallax{transition:none!important}.ach-board *,.ach-board ::before,.ach-board ::after{animation:none!important}.ach-stars i,.ach-stars[data-depth]{opacity:.8}}\r\n/* W2-2O: without the Starter pack's art (offline, not downloaded): the bosses outlined on the starfield, and the pack offered. */\r\n.ach-starter{display:none}\r\n.ach-board.no-art .ach-art{visibility:hidden}\r\n.ach-board.no-art .ach-boss:not([data-state=locked]){box-shadow:0 0 14px var(--glow),inset 0 0 0 1px var(--glow)}\r\n.ach-board.no-art:not(.zoomed) .ach-starter{position:absolute;left:16px;right:16px;bottom:max(16px,env(safe-area-inset-bottom));display:flex;flex-direction:column;align-items:center;gap:8px;padding:10px 14px;border-radius:12px;background:#05030ccc;text-align:center}\r\n/* Framed fullscreen (portal): the dock rides inside the dialog, so the offer sits above it, not under it. */\r\n.portal-framed.ach-board.no-art:not(.zoomed) .ach-starter,.portal-framed .ach-board.no-art:not(.zoomed) .ach-starter{bottom:calc(max(16px,env(safe-area-inset-bottom)) + var(--myr5-bar))}\r\n.ach-starter p{margin:0;font-size:15px;letter-spacing:.08em;color:#d9d2ee}\r\n.ach-starter button{min-height:44px;padding:0 18px;border:1px solid #fff9;border-radius:22px;background:#ffffff1f;color:#fff;font:inherit;font-size:15px;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}\r\n/* Coach captions, page buttons and the zoomed detail (requirements, exercises, weapon tier milestones). */\r\n.ach-name{position:absolute;left:-10%;width:120%;top:100%;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;pointer-events:none;text-align:center;font-size:clamp(5px,1.6vw,8px);line-height:1.05;letter-spacing:.03em;text-transform:uppercase;color:#fff;text-shadow:0 0 3px #000,0 0 6px #000}\r\n.ach-board.zoomed .ach-name{opacity:0}\r\n.ach-boss[data-golden=true] .ach-name{color:#ffe29e}\r\n.ach-page{position:absolute;top:50%;z-index:2;width:44px;height:88px;margin-top:-44px;border:1px solid #ffffff55;background:#05030ccc;color:#fff;font:400 34px/1 'Barlow Condensed',var(--font,system-ui);transition:opacity .4s}\r\n.ach-page[hidden]{display:none}.ach-page-prev{left:0;border-radius:0 22px 22px 0}.ach-page-next{right:0;border-radius:22px 0 0 22px}\r\n.ach-board.zoomed .ach-page{opacity:0;pointer-events:none}\r\n.ach-detail{text-align:left}.ach-detail h2,.ach-detail .ach-status{text-align:center}\r\n.ach-detail p{margin:6px auto;max-width:520px;font-size:16px;letter-spacing:.04em}.ach-detail strong{font-weight:400;color:#e9e3ff;letter-spacing:.12em;text-transform:uppercase}\r\n.ach-detail h3{margin:16px auto 6px;max-width:520px;font-size:18px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#e9e3ff}\r\n.ach-detail h4{margin:10px auto 4px;max-width:520px;font-size:16px;font-weight:400;letter-spacing:.1em;text-transform:uppercase;color:#cfc8e6}\r\n.ach-detail ul{margin:0 auto;padding-left:20px;max-width:520px;font-size:15px}\r\n.ach-detail ol{width:min(520px,100%);gap:4px}.ach-detail li{grid-template-columns:18px 64px 1fr;font-size:15px}\r\n.ach-detail ul li{display:list-item}.ach-detail ul li::before{content:none}\r\n.ach-weapons{max-width:520px;margin:0 auto}\r\n.ach-tier-block{padding:2px 9px 9px;border-left:1px solid #ffffff30}\r\n.ach-tier-block[data-current=true]{border-color:var(--glow);background:linear-gradient(90deg,#ffffff12,transparent)}\r\n.ach-tier-block h5{margin:8px 0 6px;font-size:15px;font-weight:400;letter-spacing:.12em;text-transform:uppercase;color:#cfc8e6}\r\n.ach-detail .ach-tier-block li{grid-template-columns:14px 58px 1fr;gap:6px;font-size:14px;line-height:1.25}\r\n.ach-back{display:block;margin:18px auto 0}\r\n/* Framed fullscreen (portal): ~50px persistent top chrome above, the dock below; the detail scrolls between them. */\r\n.portal-framed.ach-board .ach-head,.portal-framed .ach-board .ach-head{top:calc(54px + env(safe-area-inset-top))}\r\n.portal-framed.ach-board .ach-close,.portal-framed .ach-board .ach-close{top:calc(54px + env(safe-area-inset-top))}\r\n.portal-framed.ach-board .ach-detail,.portal-framed .ach-board .ach-detail{bottom:var(--myr5-bar,64px);max-height:calc(100% - var(--myr5-bar,64px) - 104px - env(safe-area-inset-top));padding-bottom:24px}\r\n.portal-framed.ach-board.has-pod-chrome .ach-detail{padding-bottom:24px}\r\n.portal-framed.ach-board .ach-page,.portal-framed .ach-board .ach-page{margin-top:-44px}\r\n@media (max-width:420px){.ach-detail{padding-left:14px;padding-right:14px}.ach-detail h2{font-size:29px}.ach-detail p{font-size:15px}}\r\n/* R-1017 one achievements page: the constellation sits at the top of the XP flight scroller (#battlePassPanel); the\r\n   flight path hangs under the golden coach. The board is a plain section there, sized by the art's aspect ratio. */\r\n.ach-board.ach-embed{position:relative;inset:auto;display:block;width:100%;height:auto;max-width:none;max-height:none;overflow:visible;background:#05030c;z-index:1}\r\n.ach-board.ach-embed .ach-stage{width:100%;height:auto;overflow:hidden}\r\n.ach-board.ach-embed .ach-head,.portal-framed .ach-board.ach-embed .ach-head{top:12px;right:18px}\r\n.ach-board.ach-embed .ach-head h1{font-size:20px}\r\n.ach-embed-detail{z-index:7;color:#fff;font:16px/1.4 'Barlow Condensed',var(--font,system-ui);letter-spacing:.04em}\r\n/* The requirements card rises inside the game screen, over the flight HUD. */\r\n.ach-embed-detail{max-height:66%;padding-bottom:20px}\r\n.launch-panel .ach-board .ach-head{display:block;min-height:0;margin:0;padding:0;border:0;background:none;font:16px/1.4 'Barlow Condensed',var(--font,system-ui)}\r\n.launch-panel .ach-board .ach-head h1{font-size:20px;line-height:1.2}\r\n.launch-panel .ach-board .ach-head p{font-size:13px;line-height:1.3}\r\n/* The section menu is part of the game screen: a compact CRT strip along the bottom of the flight. */\r\n.pass-crt-rack.pass-hud{position:relative;z-index:6;flex:none;box-sizing:border-box;height:var(--pass-hud-h);width:min(380px,calc(100% - 16px));grid-template-columns:40px minmax(0,1fr) 40px;margin:0 auto;padding:6px 0}\r\n/* R-1017: the game fills the panel. Three bands in the game frame: a slim top HUD (score, level bar, daily chip), the\r\n   scrolling flight, the CRT strip. The ship canvas covers only the middle band, so no scene label or node draws under a HUD. */\r\n#battlePassPanel .pass-map-shell{display:flex;flex-direction:column;--pass-top-h:58px;--pass-hud-h:100px;margin:4px 5px 5px}\r\n#battlePassPanel .pass-map-viewport{flex:1;min-height:0;height:auto}\r\n#battlePassPanel .pass-scene{top:var(--pass-top-h);bottom:auto;height:calc(100% - var(--pass-top-h) - var(--pass-hud-h))}\r\n#battlePassPanel .pass-top-hud{position:relative;z-index:7;flex:none;box-sizing:border-box;height:var(--pass-top-h);display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:2px 8px;padding:4px 8px;border-bottom:1px solid #477785;background:#06101c}\r\n#battlePassPanel .pass-flight-score{grid-row:1;grid-column:1;justify-content:flex-start;gap:12px;padding:0;border:0;background:none;font-size:.66rem}\r\n#battlePassPanel .pass-summary{grid-row:2;grid-column:1/-1;display:flex;align-items:center;gap:8px;min-width:0;margin:0;padding:0;border:0;background:none}\r\n#battlePassPanel .pass-summary>*{grid-column:auto;grid-row:auto;flex:none}\r\n#battlePassPanel .pass-summary strong{font-size:.72rem}#battlePassPanel .pass-summary span,#battlePassPanel .pass-summary b{justify-self:start;font-size:.58rem;white-space:nowrap}#battlePassPanel .pass-summary progress{flex:1 1 auto;min-width:30px;width:auto;height:5px}\r\n#battlePassPanel .pass-daily{grid-row:1;grid-column:2;display:block;margin:0;padding:0;border:0;background:none}\r\n#battlePassPanel .pass-daily-chip{display:flex;gap:6px;align-items:center;min-height:24px;padding:2px 8px;border:1px solid #548b85;border-left:3px solid #86debb;border-radius:3px;background:#0d2230;color:#adf0c7;font-size:.6rem;letter-spacing:.06em;white-space:nowrap;cursor:pointer;list-style:none}\r\n#battlePassPanel .pass-daily-chip::-webkit-details-marker{display:none}\r\n#battlePassPanel .pass-daily-chip::after{content:'\\25BE';color:#86debb}\r\n#battlePassPanel .pass-daily-chip strong{color:#ffe4a0;font-size:.6rem}\r\n#battlePassPanel .pass-daily[open]{grid-area:auto;position:absolute;top:4px;right:8px;z-index:8;width:min(330px,calc(100% - 16px));box-sizing:border-box;padding:0 0 8px;border:1px solid #548b85;background:#0b1c2af7;box-shadow:0 8px 24px #000c}\r\n#battlePassPanel .pass-daily[open] .pass-daily-chip{border:0;border-bottom:1px solid #548b85;border-radius:0}\r\n#battlePassPanel .pass-daily[open] .pass-daily-chip::after{content:'\\25B4'}\r\n#battlePassPanel .pass-daily .pass-quests{display:flex;flex-wrap:wrap;justify-content:flex-start;gap:4px;padding:8px 8px 4px}\r\n#battlePassPanel .pass-daily small{display:block;padding:0 8px;font-size:.6rem;color:#b6d9e8}\r\n#battlePassPanel .pass-daily-chip:focus-visible{outline:3px solid #f8db83;outline-offset:2px}\r\n.pass-hud .pass-crt-entry{min-height:58px}\r\n#battlePassPanel:has(.ach-board.zoomed) .pass-hud,#battlePassPanel[data-hyper] .pass-hud .pass-crt-switch{visibility:hidden}\r\n#battlePassPanel[data-hyper] .pass-crt-entry{box-shadow:0 0 0 2px #b9faff,0 0 22px #60e6ff}\r\n/* The flight dialog is a .launch-panel, whose generic button skin must not box the constellation's tap targets. */\r\n.launch-panel .ach-board .ach-boss{min-height:0;padding:0;border:0;border-radius:14px;background:none;color:inherit}\r\n.launch-panel .ach-board .ach-boss[data-state=locked]{background:radial-gradient(ellipse at center,#03020ce8 40%,#03020c99 60%,transparent 78%)}\r\n.launch-panel .ach-board .ach-boss.selected{background:radial-gradient(ellipse at center,#ffffff38 12%,transparent 68%)}\r\n.launch-panel .ach-embed-detail .ach-back{border:0;border-bottom:1px solid #fff9;border-radius:0;background:none;color:#fff;font:400 17px/1 'Barlow Condensed',var(--font,system-ui);letter-spacing:.2em}\r\n","achievements-board.mjs":"import {COACHES,COACH_REQUIREMENTS,STARTER_COACH_IDS,PATH_INTRO_COACH_IDS,WEAPON_GROUPS,SHIP_REQUIREMENTS,CADENCE_MILESTONES,exerciseDifficulty} from './performance-catalog.mjs';\r\nimport {EXERCISES,FOCUS_GROUPS} from './exercise-library.mjs';\r\nimport {readPerformanceProgress,unlockStatus} from './performance-progress.mjs';\r\nimport {DIFFICULTIES} from './progression-rules.mjs';\r\nimport {SHIP_CATALOG} from './modules/ships/ship-catalog.mjs';\r\nimport {asteroid,rock} from './space-rocks.mjs';\r\nexport {selectedTracks} from './battle-pass.mjs';\r\nexport const loadProgress=readPerformanceProgress;\r\nconst IMAGE='/pod/worlds/achievements.jpg';\r\nexport const GROUP_NAMES=Object.fromEntries([...FOCUS_GROUPS.map(g=>[g.id,g.name]),['meditation','Meditation']]);\r\nexport const BOSSES=COACHES.map(c=>({...c,name:c.label,requirement:COACH_REQUIREMENTS.find(r=>r.id===c.id)||null}));\r\nconst difficultyName=d=>d[0].toUpperCase()+d.slice(1);\r\nconst groupName=g=>GROUP_NAMES[g]||g;\r\nexport function coachRequirements(id){\r\n const coach=BOSSES.find(c=>c.id===id);if(!coach)return null;\r\n const r=coach.requirement;if(!r){const starter=STARTER_COACH_IDS.includes(id);return {starter,unlock:starter?'Available from the start':'Requirement pending placement.',gold:'Select this coach and complete a 10-minute uninterrupted hold to earn its golden version.',exercises:[]};}\r\n if(r.groups.includes('meditation'))return {starter:false,unlock:`Complete meditation on ${CADENCE_MILESTONES.meditationDays[DIFFICULTIES.indexOf(r.difficulty)]} separate days.`,gold:'Once unlocked, select this coach and complete a 10-minute uninterrupted hold to earn its golden version.',exercises:[]};\r\n const exercises=Object.values(EXERCISES).filter(e=>r.groups.includes(e.group)&&exerciseDifficulty(e.id)===r.difficulty);\r\n const intro=Object.values(PATH_INTRO_COACH_IDS).includes(id)?`Choose ${r.groups.map(groupName).join(' / ')} as one of your two starting workout paths OR `:'';\r\n const kinds=[...new Set(exercises.map(e=>e.kind))],options=[];\r\n if(kinds.includes('hold'))options.push('hold for 5 uninterrupted minutes');\r\n if(kinds.includes('reps'))options.push('complete 15 reps in one working set');\r\n if(r.groups.includes('cardio'))options.push('complete 5 sprint rounds or 5 active minutes of gentle cardio');\r\n else if(kinds.some(k=>k==='pace'||k==='steps'))options.push('complete 5 active minutes');\r\n return {starter:false,difficulty:r.difficulty,groups:r.groups,unlock:`${intro}${difficultyName(r.difficulty)} · ${r.groups.map(groupName).join(' / ')}: ${options.join(' OR ')}.`,gold:kinds.includes('hold')?'Complete a 10-minute uninterrupted hold at this difficulty in one of these groups. Breaks and difficulty changes restart the uninterrupted attempt.':'Once unlocked, select this coach and complete a 10-minute uninterrupted hold to earn its golden version.',exercises:exercises.map(e=>e.name)};\r\n}\r\nexport function bossStates(progress=readPerformanceProgress()){\r\n return BOSSES.map(b=>({...b,state:(progress.coaches?.includes(b.id)||unlockStatus(progress).done)?'done':'locked',golden:progress.goldenCoaches?.includes(b.id)===true,requirements:coachRequirements(b.id)}));\r\n}\r\nexport function weaponRequirements(group){\r\n return {group,name:groupName(group),weapons:WEAPON_GROUPS[group]||[],blocks:DIFFICULTIES.map((difficulty,i)=>({difficulty,first:i*5+1,last:i*5+5})),hold:'1 uninterrupted minute: first tier in the difficulty block. 3 minutes: second tier. 5 minutes: coach clear; repeating it adds one tier. 10 minutes: finish the five-tier block and earn gold.',reps:'8 reps: first tier in the difficulty block. 12 reps: second tier. 15 reps: coach clear; repeating it adds one tier. One working set per muscle group per day.'};\r\n}\r\nexport const shipRequirements=()=>SHIP_REQUIREMENTS.map(r=>({...r,name:SHIP_CATALOG.find(s=>s.id===r.id)?.name||r.id,unlock:`Expert ${groupName(r.group)}: ${r.kind==='hold'?'5 uninterrupted minutes':'15 reps in one working set'}.`}));\r\n// Retained for decorative constellation consumers; roster ownership never uses zoom or defeats.\r\nexport function layerTransform(depth,{tx=0,ty=0,scale=1}={}){const f={far:.35,mid:.65,near:1.25}[depth]??1;return {tx:tx*f,ty:ty*f,scale:1+(scale-1)*f};}\r\n// Original constellation art slots (boxes are [x,y,w,h] in % of the art). `track` is the catalog track whose coaches sit in the row; null rows take the pool.\r\nexport const ART_ROWS=[\r\n {id:'strider',track:'chest',color:'#b48cff',boxes:[[10.96,9.7,10.78,8.8],[28.4,8.05,7.89,10.45],[37.51,9.2,11.92,9.3],[51.62,8.05,11.48,10.45],[63.37,8.05,12.8,10.45],[78.18,7.9,15.43,10.6]]},\r\n {id:'ringer',track:'quads',color:'#ff8a2a',boxes:[[20.16,18.05,7.89,8.1],[31.11,17.95,10.69,8.4],[44.26,17.95,9.55,8.25],[57.06,17.95,9.03,8.3],[69.76,17.95,11.13,8.5]]},\r\n {id:'manyarm',track:'glutes',color:'#7dff5a',boxes:[[22.17,26.65,8.33,8.6],[34.18,26.45,9.73,8.8],[46.54,27.25,10.08,8],[57.49,27.4,7.54,7.85],[65.64,27.2,12.62,8.05]]},\r\n {id:'wedge',track:'arms',color:'#39a8ff',boxes:[[23.4,34.7,10.52,7.8],[35.06,34.7,8.15,7.45],[43.21,34.7,11.48,7.75],[55.04,34.7,9.82,7.75],[65.21,34.7,11.22,7.75]]},\r\n {id:'warden',track:null,color:'#39a8ff',boxes:[[45.57,41.95,8.24,5.7]]},\r\n {id:'blob',track:'yoga',color:'#c65cff',boxes:[[26.29,47.25,10.87,6.95],[38.56,47.1,9.55,7.2],[49.87,47.1,7.8,6.95],[60.74,47.3,9.55,7.45]]},\r\n {id:'cap',track:'martial-arts',color:'#ff4fa0',boxes:[[33.04,54.6,7.62,7.4],[40.93,54.55,11.13,7.45],[53.46,54.65,10.78,7.35]]},\r\n {id:'stalk',track:'cardio',color:'#ff4a3d',boxes:[[30.5,61.45,7.01,7.5],[38.21,61.45,8.15,7.25],[49.52,61.45,9.29,7.5],[58.55,61.45,8.59,7.5]]},\r\n {id:'tanka',track:'meditation',color:'#ffd23a',boxes:[[29.27,68.65,9.38,7.85],[39.09,68.65,9.64,7.8],[48.47,68.45,10.6,8],[59.95,68.5,8.33,8]]},\r\n {id:'lume',track:null,color:'#ffc94a',boxes:[[39.35,75.95,15.34,8.8]]},\r\n];\r\nexport const ART_SLOTS=ART_ROWS.flatMap(row=>row.boxes.map((box,i)=>({id:`${row.id}-${i+1}`,row:row.id,color:row.color,box})));\r\n// One constellation contains every coach once, with each workout group on its own art row.\r\nexport function coachPages(coaches=BOSSES){\r\n const rank=id=>DIFFICULTIES.indexOf(COACH_REQUIREMENTS.find(r=>r.id===id)?.difficulty),queues=new Map(ART_ROWS.map(r=>[r.id,[]])),pool=[];\r\n for(const c of coaches){const track=COACH_REQUIREMENTS.find(r=>r.id===c.id)?.tracks?.[0],row=track&&ART_ROWS.find(r=>r.track===track);(row?queues.get(row.id):pool).push(c);}\r\n const shared=ART_ROWS.filter(row=>!row.track);pool.forEach((coach,i)=>queues.get(shared[i%shared.length].id).push(coach));\r\n const board=[];\r\n for(const row of ART_ROWS){const entries=queues.get(row.id);entries.sort((a,b)=>rank(a.id)-rank(b.id));if(!entries.length)continue;\r\n  const left=Math.min(...row.boxes.map(b=>b[0])),right=Math.max(...row.boxes.map(b=>b[0]+b[2])),top=Math.min(...row.boxes.map(b=>b[1])),height=Math.max(...row.boxes.map(b=>b[3])),width=(right-left)/entries.length;\r\n  entries.forEach((coach,i)=>board.push({coach,slot:{id:`${row.id}-${i+1}`,row:row.id,color:row.color,box:[left+i*width,top,width*.93,height]}}));\r\n }\r\n return board.length?[board]:[];\r\n}\r\n// All four ordered five-tier blocks are visible from each coach's zoom view.\r\nexport function weaponTierSteps(group,difficulty,owned=0){\r\n const index=DIFFICULTIES.indexOf(difficulty);if(index<0||!WEAPON_GROUPS[group])return [];\r\n const kinds=new Set(Object.values(EXERCISES).filter(e=>e.group===group).map(e=>e.kind));\r\n const pace=group==='boxing'||group==='cardio';\r\n const hasHold=kinds.has('hold'),hasReps=kinds.has('reps')||kinds.has('steps');\r\n const acts=[];\r\n if(hasHold)acts.push(['1 uninterrupted minute','3 uninterrupted minutes','5 uninterrupted minutes (coach clear)','Repeat a 5-minute hold','Repeat again, or hold 10 uninterrupted minutes']);\r\n if(hasReps)acts.push(['8 reps','12 reps','15 reps (coach clear)','Repeat 15 reps','Repeat 15 reps again']);\r\n if(pace)acts.push(group==='boxing'?['5 active minutes','Repeat 5 active minutes','Repeat 5 active minutes again','Repeat 5 active minutes again','Repeat 5 active minutes again']:['5 sprint rounds or 5 active minutes','Repeat a completed cardio set','Repeat a completed cardio set','Repeat a completed cardio set','Repeat a completed cardio set']);\r\n return Array.from({length:5},(_,i)=>({tier:index*5+i+1,text:acts.map(a=>a[i]).join(' · '),state:index*5+i+1<=owned?'done':index*5+i+1===owned+1?'next':'todo'}));\r\n}\r\n// dialog: the board's root (.ach-board); owner: the <dialog> that opens/closes it. R-1017: the board can live embedded at the\r\n// top of the XP flight page (embedAchievements), where the root is a plain section and the flight page's dialog is the owner.\r\nlet dialog,owner,embedded=false,stageVisible=true,stage,detail,artEl,bossesEl,layers,raf=0,t0=0,far,near,pages=[],page=0,selected=null;\r\nconst prefersReducedMotion=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\nfunction element(tag,text,className){const el=document.createElement(tag);if(text)el.textContent=text;if(className)el.className=className;return el;}\r\nfunction line(label,text){const p=element('p');p.append(element('strong',`${label} `),document.createTextNode(text));return p;}\r\nconst rand=(a,b)=>a+Math.random()*(b-a);\r\nconst wrap=v=>v-Math.floor(v);\r\n// Far layer (unit 0..1 space, positions wrap): a dust field plus a few slow drifting stars and dark asteroids.\r\nfunction makeFar(){\r\n return {\r\n  dust:Array.from({length:60},()=>({x:Math.random(),y:Math.random(),r:rand(.5,1.2),a:rand(.3,.85)})),\r\n  stars:Array.from({length:Math.round(rand(4,6))},()=>({x:Math.random(),y:Math.random(),vx:rand(.01,.025)*(Math.random()<.5?-1:1),vy:rand(.005,.015)*(Math.random()<.5?-1:1),r:rand(1.1,1.8)})),\r\n  rocks:Array.from({length:Math.round(rand(2,3))},()=>({x:Math.random(),y:Math.random(),vx:rand(.004,.012)*(Math.random()<.5?-1:1),vy:rand(.002,.007)*(Math.random()<.5?-1:1),...asteroid(9,16)})),\r\n };\r\n}\r\n// Near layer: 3-5 debris chunks, each a straight crossing of the art that loops every 6-14s.\r\nfunction makeNear(){\r\n return Array.from({length:Math.round(rand(3,5))},()=>{\r\n  const alongX=Math.random()<.5,fwd=Math.random()<.5,a=fwd?-.2:1.2,b=fwd?1.2:-.2;\r\n  return {x0:alongX?a:rand(-.1,1.1),y0:alongX?rand(-.1,1.1):a,x1:alongX?b:rand(-.1,1.1),y1:alongX?rand(-.1,1.1):b,dur:rand(6,14),phase:Math.random(),...asteroid(16,30)};\r\n });\r\n}\r\nfunction drawFar(elapsed){\r\n const {ctx,w,h,field}=far,t=elapsed/1000;\r\n ctx.clearRect(0,0,w,h);ctx.fillStyle='#fff';\r\n for(const d of field.dust){ctx.globalAlpha=d.a;ctx.beginPath();ctx.arc(d.x*w,d.y*h,d.r,0,7);ctx.fill();}\r\n ctx.globalAlpha=1;ctx.shadowColor='#fff';\r\n for(const s of field.stars){ctx.shadowBlur=6;ctx.beginPath();ctx.arc(wrap(s.x+s.vx*t)*w,wrap(s.y+s.vy*t)*h,s.r,0,7);ctx.fill();}\r\n ctx.shadowBlur=0;\r\n for(const a of field.rocks)rock(ctx,wrap(a.x+a.vx*t)*w,wrap(a.y+a.vy*t)*h,a.r,a.rot+a.vr*t,a.verts,.8);\r\n}\r\nfunction drawNear(elapsed){\r\n const {ctx,w,h,field}=near,t=elapsed/1000;\r\n ctx.clearRect(0,0,w,h);\r\n for(const p of field){const u=wrap(t/p.dur+p.phase);rock(ctx,(p.x0+(p.x1-p.x0)*u)*w,(p.y0+(p.y1-p.y0)*u)*h,p.r,p.rot+t*p.vr,p.verts,.85);}\r\n}\r\nfunction draw(elapsed){drawFar(elapsed);drawNear(elapsed);}\r\n// devicePixelRatio capped at 2; canvases are sized in real CSS px via setTransform so draw math stays unit-space.\r\nfunction fitLayers(){\r\n const r=stage.getBoundingClientRect(),dpr=Math.min(devicePixelRatio||1,2);\r\n for(const layer of [far,near]){\r\n  const c=layer.canvas;c.width=Math.max(1,Math.round(r.width*dpr));c.height=Math.max(1,Math.round(r.height*dpr));\r\n  layer.ctx=c.getContext('2d');layer.ctx.setTransform(dpr,0,0,dpr,0,0);layer.w=r.width;layer.h=r.height;\r\n }\r\n}\r\n// One rAF loop for both canvases; stopped on dialog close and while the tab is hidden.\r\nfunction startLoop(){\r\n if(raf||prefersReducedMotion()||!owner?.open||document.hidden)return;\r\n // Embedded: the drift layers only paint while the constellation is on screen (the flight game owns the frame budget).\r\n const tick=now=>{raf=requestAnimationFrame(tick);if(stageVisible)draw(now-t0);};\r\n raf=requestAnimationFrame(tick);\r\n}\r\nfunction stopLoop(){if(raf)cancelAnimationFrame(raf);raf=0;}\r\nfunction build(host,detailHost=host){\r\n embedded=!!host;\r\n dialog=document.createElement(host?'section':'dialog');dialog.className=host?'ach-board ach-embed':'ach-board';dialog.setAttribute('aria-label','Achievements');owner=host||dialog;\r\n stage=element('div',null,'ach-stage');\r\n artEl=element('img',null,'ach-art ach-parallax');artEl.src=IMAGE;artEl.alt='Coach constellation';artEl.draggable=false;\r\n const layer=(tag,depth)=>{const el=element(tag,null,'ach-stars ach-parallax');el.dataset.depth=el.dataset.peerDepth=depth;el.setAttribute('aria-hidden','true');return el;};\r\n layers={far:layer('canvas','far'),mid:layer('div','mid'),near:layer('canvas','near')};\r\n for(let i=0;i<40;i++){const dot=document.createElement('i');dot.style.cssText=`left:${(Math.random()*100).toFixed(1)}%;top:${(Math.random()*100).toFixed(1)}%;--d:${(Math.random()*4).toFixed(2)}s`;layers.mid.append(dot);}\r\n bossesEl=element('div',null,'ach-bosses ach-parallax');\r\n stage.append(artEl,layers.far,layers.mid,bossesEl,layers.near);\r\n const head=element('header',null,'ach-head');head.append(element('h1','Achievements'),element('p',null,'ach-count'));\r\n detail=element('section',null,'ach-detail');detail.hidden=true;\r\n const starter=element('div',null,'ach-starter'),offer=element('button','Download the Starter pack');offer.type='button';starter.append(element('p','The constellation art comes with the Starter pack.'),offer);\r\n const close=element('button','✕','ach-close');close.type='button';close.setAttribute('aria-label','Close');\r\n if(host){detail.classList.add('ach-embed-detail');dialog.append(stage,head,starter);detailHost.append(detail);}\r\n else{dialog.append(stage,head,detail,starter,close);document.body.append(dialog);}\r\n // W2-2O: the constellation is Starter-pack art. Without it (offline, not downloaded) the coaches glow on the plain\r\n // starfield and the pack is offered (achievements-board.css .no-art).\r\n artEl.addEventListener('error',()=>dialog.classList.add('no-art'),{once:true});\r\n offer.onclick=()=>window.myr5Packs?.open('starter');\r\n far={canvas:layers.far,field:makeFar()};near={canvas:layers.near,field:makeNear()};t0=performance.now();\r\n close.onclick=()=>dialog.close();\r\n stage.addEventListener('click',e=>{if(dialog.classList.contains('zoomed')&&!e.target.closest('.ach-boss'))unzoom();});\r\n // Escape peels off the zoom first; a second Escape closes.\r\n owner.addEventListener('cancel',e=>{if(dialog.classList.contains('zoomed')){e.preventDefault();unzoom();}});\r\n owner.addEventListener('close',()=>{unzoom();stopLoop();});\r\n if(host)new IntersectionObserver(([e])=>{stageVisible=e.isIntersecting;}).observe(stage);\r\n new ResizeObserver(()=>{if(owner.open&&!document.hidden){fitLayers();draw(performance.now()-t0);}}).observe(stage);\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden)stopLoop();});\r\n addEventListener('pagehide',stopLoop);\r\n for(const type of ['myr5:performance-progress','myr5:account-ready','myr5:account-cleared'])addEventListener(type,()=>{if(owner.open&&!dialog.classList.contains('zoomed'))paint();});\r\n}\r\nfunction paint(){\r\n const state=loadProgress(),byId=new Map(bossStates(state).map(b=>[b.id,b]));\r\n pages=coachPages();page=Math.min(page,Math.max(0,pages.length-1));\r\n bossesEl.replaceChildren();\r\n dialog.querySelector('.ach-count').textContent=`${state.coaches.length} / ${BOSSES.length} coaches · ${state.goldenCoaches.length} golden${pages.length>1?` · page ${page+1} / ${pages.length}`:''}`;\r\n for(const btn of dialog.querySelectorAll('.ach-page'))btn.hidden=pages.length<2;\r\n for(const {slot,coach} of pages[page]||[]){\r\n  const b=byId.get(coach.id),[x,y,w,h]=slot.box,btn=element('button',null,'ach-boss');btn.type='button';btn.dataset.state=b.state;btn.dataset.id=b.id;btn.dataset.golden=String(b.golden);\r\n  btn.style.cssText=`left:${x}%;top:${y}%;width:${w}%;height:${h}%;--bx:${x};--by:${y};--bw:${w};--bh:${h};--glow:${slot.color};--d:${(x*7%3).toFixed(2)}s`;\r\n  btn.setAttribute('aria-label',`${b.name}, ${b.golden?'unlocked, golden':b.state==='done'?'unlocked':'locked, tap to see requirements'}`);\r\n\r\n  btn.onclick=()=>zoom(b,slot,btn);\r\n  bossesEl.append(btn);\r\n }\r\n}\r\nfunction milestoneBlock(group,difficulty,weapons){\r\n const wrap=element('section',null,'ach-weapons'),rules=weaponRequirements(group);\r\n wrap.append(element('h3',`${groupName(group)} weapon progression`));\r\n for(const weapon of rules.weapons){\r\n  const owned=weapons[weapon]??0,item=element('div',null,'ach-weapon');\r\n  item.append(element('h4',`${weapon[0].toUpperCase()}${weapon.slice(1)} · tier ${owned} / 20`));\r\n  for(const block of rules.blocks){\r\n   const band=element('section',null,'ach-tier-block'),list=element('ol');band.dataset.current=String(block.difficulty===difficulty);\r\n   band.append(element('h5',`${difficultyName(block.difficulty)} · tiers ${block.first}–${block.last}${block.difficulty===difficulty?' · this coach':''}`));\r\n   for(const step of weaponTierSteps(group,block.difficulty,owned)){\r\n    const li=element('li');li.dataset.step=step.state;\r\n    li.append(element('b',`Tier ${step.tier}`),element('span',`${step.text} · ${step.state==='done'?'earned':'locked'}`));list.append(li);\r\n   }\r\n   band.append(list);item.append(band);\r\n  }\r\n  wrap.append(item);\r\n }\r\n return wrap;\r\n}\r\nfunction fillDetail(b,state){\r\n const r=b.requirements;detail.replaceChildren(element('h2',b.name),element('hr'),element('p',b.golden?'Unlocked · Golden':b.state==='done'?'Unlocked':'Locked','ach-status'),line('Unlock',r.unlock),line('Golden',r.gold));\r\n if(r.exercises.length){const ul=element('ul');for(const name of r.exercises)ul.append(element('li',name));detail.append(element('h3','Exercises'),ul);}\r\n if(r.difficulty)for(const group of r.groups)if(WEAPON_GROUPS[group])detail.append(milestoneBlock(group,r.difficulty,state.weapons));\r\n const back=element('button','Back','ach-back');back.type='button';back.onclick=unzoom;detail.append(back);\r\n}\r\nfunction zoom(b,slot,btn){\r\n stage.querySelector('.ach-boss.selected')?.classList.remove('selected');btn.classList.add('selected');selected=btn;\r\n // Embedded: bring the constellation's top into view first so the glide lands on screen.\r\n const scroller=embedded&&dialog.parentElement;if(scroller)scroller.scrollTop=dialog.offsetTop;\r\n const r=stage.getBoundingClientRect(),[x,y,w,h]=slot.box;\r\n const cx=r.width*(x+w/2)/100,cy=r.height*(y+h/2)/100,scale=Math.min(4,Math.max(2,r.height*.26/(r.height*h/100)));\r\n const tx=r.width/2-cx,ty=r.height*.3-cy;\r\n // Art + boss tap targets keep today's transform exactly, unscaled by depth, so nothing shifts under a finger.\r\n for(const el of [artEl,bossesEl]){el.style.transformOrigin=`${cx}px ${cy}px`;el.style.transform=`translate(${tx}px,${ty}px) scale(${scale})`;}\r\n for(const depth of ['far','mid','near']){\r\n  const t=layerTransform(depth,{tx,ty,scale}),el=layers[depth];\r\n  el.style.transformOrigin=`${cx}px ${cy}px`;el.style.transform=`translate(${t.tx}px,${t.ty}px) scale(${t.scale})`;\r\n }\r\n dialog.classList.add('zoomed');\r\n detail.style.setProperty('--glow',slot.color);\r\n fillDetail(b,loadProgress());\r\n detail.hidden=false;detail.scrollTop=0;detail.querySelector('.ach-back').focus({preventScroll:true});\r\n}\r\nfunction unzoom(){\r\n for(const el of [artEl,bossesEl,layers?.far,layers?.mid,layers?.near])if(el)el.style.transform='';\r\n const wasZoomed=dialog.classList.contains('zoomed');\r\n dialog.classList.remove('zoomed');detail.hidden=true;stage.querySelector('.ach-boss.selected')?.classList.remove('selected');\r\n if(wasZoomed&&owner.open&&selected?.isConnected)selected.focus({preventScroll:true});\r\n selected=null;\r\n}\r\n// Only an explicit open starts the loop; close, a hidden tab and pagehide stop it.\r\nexport function openAchievements(){\r\n if(embedded)return window.myr5Menus?.battlePass?.();\r\n if(!dialog)build();\r\n paint();\r\n if(!dialog.open)dialog.showModal();\r\n fitLayers();draw(performance.now()-t0);startLoop();\r\n return dialog;\r\n}\r\n// R-1017: one achievements page. Builds the board into the flight page's dialog; the caller places .root in its scroller.\r\nexport function embedAchievements(host,detailHost=host){\r\n if(!dialog)build(host,detailHost);\r\n return {root:dialog,stage,open(){paint();fitLayers();draw(performance.now()-t0);startLoop();},unzoom};\r\n}\r\n","achievements.mjs":"import {MOVEMENTS} from './movement-engine.mjs';\r\nimport {clockDigits} from './flip-display.mjs';\r\nconst groups=[['reps','Reps','reps'],['hold','Holds','held'],['steps','Steps','steps'],['jumps','Jumps','jumps'],['pace','Boxing','boxing']];\r\nexport function achievementBoards(items){\r\n const saved=new Map(items.map(item=>[item.mode,item]));\r\n return groups.map(([kind,title,unit])=>{\r\n  const timed=kind==='hold'||kind==='pace';\r\n  const rows=Object.entries(MOVEMENTS).filter(([,movement])=>movement.kind===kind).map(([mode,movement])=>{\r\n   const item=saved.get(mode);\r\n   return {mode,name:movement.name,sets:Number(item?.sets)||0,best:Number(item?.best)||0,total:Number(item?.total)||0};\r\n  }).sort((a,b)=>b.best-a.best||a.mode.localeCompare(b.mode));\r\n  let rank=0,previous=null;\r\n  rows.forEach((row,index)=>{if(row.sets&&row.best!==previous)rank=index+1;row.rank=row.sets?rank:null;previous=row.best;});\r\n  return {kind,title,unit,timed,rows,total:rows.reduce((sum,row)=>sum+row.total,0)};\r\n });\r\n}\r\nconst number=value=>Math.floor(value).toLocaleString();\r\nfunction totalLabel(board){\r\n if(!board.timed)return `${number(board.total)} ${board.unit} total`;\r\n const seconds=Math.floor(board.total),hours=Math.floor(seconds/3600),minutes=Math.floor(seconds%3600/60);\r\n const duration=hours?`${hours}h ${minutes}m`:minutes?`${minutes}m ${seconds%60}s`:`${seconds}s`;\r\n return `${duration} ${board.unit} total`;\r\n}\r\nexport function renderAchievements(container,items){\r\n container.replaceChildren();\r\n for(const board of achievementBoards(items)){\r\n  const section=document.createElement('section');section.className='record-board';section.dataset.kind=board.kind;\r\n  const heading=document.createElement('div');heading.className='record-heading';\r\n  const title=document.createElement('h3');title.textContent=board.title;\r\n  const total=document.createElement('span');total.textContent=totalLabel(board);heading.append(title,total);\r\n  const table=document.createElement('table');table.setAttribute('aria-label',`${board.title} personal records`);\r\n  const head=table.createTHead().insertRow();\r\n  for(const label of ['Rank','Movement',board.timed?'Best set · m:ss':'Best set','Sets']){const th=document.createElement('th');th.scope='col';th.textContent=label;head.append(th);}\r\n  const body=table.createTBody();\r\n  for(const row of board.rows){\r\n   const tr=body.insertRow();tr.dataset.record=String(row.sets>0);\r\n   const rank=tr.insertCell();rank.className='record-rank';rank.textContent=row.rank?String(row.rank).padStart(2,'0'):'—';\r\n   const name=document.createElement('th');name.scope='row';name.textContent=row.name;tr.append(name);\r\n   const best=tr.insertCell();best.className='record-best';best.textContent=row.sets?(board.timed?clockDigits(row.best):number(row.best)):'—';\r\n   tr.insertCell().textContent=number(row.sets);\r\n  }\r\n  section.append(heading,table);container.append(section);\r\n }\r\n}\r\n","actual-dj-commands.mjs":"/**\r\n * Typed commands understood by the local actual.dj deck controls.\r\n * @typedef {{action:'automix', enabled:boolean} | {action:'mix-next'} | {action:'fade', seconds:4|8|16} | {action:'deck-control', deck:'a'|'b', control:'play'|'pause'}} DJCommand\r\n */\r\n\r\nconst MAX_COMMAND_LENGTH=80;\r\n\r\n/**\r\n * Parse a small, explicit set of local deck commands. This function has no\r\n * browser, network, provider, speech-recognition, or evaluation side effects.\r\n * @param {unknown} text\r\n * @returns {DJCommand|null}\r\n */\r\nexport function parseDJCommand(text) {\r\n  if(typeof text!=='string'||text.length>MAX_COMMAND_LENGTH)return null;\r\n  const command=text.trim().toLowerCase().replace(/\\s+/g,' ');\r\n  if(command==='start auto dj')return {action:'automix',enabled:true};\r\n  if(command==='stop auto dj')return {action:'automix',enabled:false};\r\n  if(command==='mix next')return {action:'mix-next'};\r\n  const fade=command.match(/^fade (4|8|16) seconds$/);\r\n  if(fade)return {action:'fade',seconds:Number(fade[1])};\r\n  const deck=command.match(/^(play|pause) (?:deck )?([ab])$/);\r\n  if(deck)return {action:'deck-control',deck:deck[2],control:deck[1]};\r\n  return null;\r\n}\r\n","actual-dj-engine.mjs":"// MYR5 browser audio glue; manual/measured BPM, without native track analysis.\r\n// riseGain/fallGain below are JavaScript ports of BitChord's equal-power pair:\r\n// kushagrasinghx/BitChord, revision 2c599a6cd7a195227a11dab5769f88da8fd08194,\r\n// app/src/main/java/com/music/bitchord/playback/CrossfadeController.kt:2268-2273.\r\n// Upstream is GPL-3.0; preserve its attribution and license in third-party notices.\r\nconst clamp = (n, low, high) => Math.min(high, Math.max(low, n));\r\nconst riseGain = progress => Math.sin(clamp(progress, 0, 1) * Math.PI / 2);\r\nconst fallGain = progress => Math.cos(clamp(progress, 0, 1) * Math.PI / 2);\r\nconst numeric = (n, low, high) => Number.isFinite(Number(n)) ? clamp(Number(n), low, high) : low;\r\nconst validBpm = value => Number.isFinite(Number(value)) && Number(value) >= 30 && Number(value) <= 300;\r\n\r\nexport function createDJEngine({ onChange = () => {}, onError = () => {} } = {}) {\r\n  let context, masterNode, analyser, disposed = false, crossfader = 0, master = .8;\r\n  let transitionJob = null, transitionGeneration = 0, lastEmit = 0;\r\n  const decks = Object.fromEntries(['a', 'b'].map(id => [id, {\r\n    track: null, audio: null, nodes: null, listeners: [], generation: 0,\r\n    bpm: null, rate: 1, cue: 0, loopBeats: 0, loopStart: 0,\r\n    eq: { low: 0, mid: 0, high: 0 }, playing: false, playGeneration: 0,\r\n  }]));\r\n  const getDeck = id => {\r\n    if (disposed) throw new Error('DJ engine has been closed.');\r\n    if (!decks[id]) throw new TypeError('Deck must be a or b.');\r\n    return decks[id];\r\n  };\r\n  function snapshot() {\r\n    return { decks: Object.fromEntries(Object.entries(decks).map(([id, d]) => [id, {\r\n      track: d.track ? { ...d.track } : null, playing: d.playing,\r\n      position: Number.isFinite(d.audio?.currentTime) ? d.audio.currentTime : 0,\r\n      duration: Number.isFinite(d.audio?.duration) ? d.audio.duration : 0,\r\n      bpm: d.bpm, rate: d.rate, cue: d.cue, loopBeats: d.loopBeats,\r\n      eq: { ...d.eq },\r\n    }])), crossfader, master, mixing: Boolean(transitionJob) };\r\n  }\r\n  const emit = () => { if (!disposed) onChange(snapshot()); };\r\n  const fail = error => { if (!disposed) onError(error instanceof Error ? error : new Error(String(error))); };\r\n  function cancelTransition() {\r\n    transitionGeneration++;\r\n    if (transitionJob) {\r\n      clearInterval(transitionJob.timer);\r\n      transitionJob.resolve(false);\r\n      transitionJob = null;\r\n    }\r\n  }\r\n  function applyGains() {\r\n    for (const [id, d] of Object.entries(decks)) {\r\n      if (d.nodes) d.nodes.gain.gain.value = id === 'a' ? fallGain(crossfader) : riseGain(crossfader);\r\n    }\r\n    if (masterNode) masterNode.gain.value = master;\r\n  }\r\n  function ensureGraph(d) {\r\n    if (!context) {\r\n      const AudioContextClass = globalThis.AudioContext || globalThis.webkitAudioContext;\r\n      if (!AudioContextClass) throw new Error('This browser does not support DJ audio processing.');\r\n      context = new AudioContextClass();\r\n      masterNode = context.createGain();\r\n      analyser = context.createAnalyser();\r\n      analyser.fftSize = 2048;\r\n      analyser.smoothingTimeConstant = .75;\r\n      masterNode.connect(analyser);\r\n      analyser.connect(context.destination);\r\n    }\r\n    if (!d.nodes) {\r\n      const source = context.createMediaElementSource(d.audio);\r\n      const low = context.createBiquadFilter(), mid = context.createBiquadFilter();\r\n      const high = context.createBiquadFilter(), gain = context.createGain();\r\n      low.type = 'lowshelf'; low.frequency.value = 250;\r\n      mid.type = 'peaking'; mid.frequency.value = 1000; mid.Q.value = 1;\r\n      high.type = 'highshelf'; high.frequency.value = 4000;\r\n      source.connect(low); low.connect(mid); mid.connect(high); high.connect(gain); gain.connect(masterNode);\r\n      d.nodes = { source, low, mid, high, gain };\r\n      for (const band of ['low', 'mid', 'high']) d.nodes[band].gain.value = d.eq[band];\r\n    }\r\n    applyGains();\r\n  }\r\n  function release(d) {\r\n    d.generation++; d.playGeneration++;\r\n    d.playing = false;\r\n    if (d.audio) {\r\n      for (const [event, listener] of d.listeners) d.audio.removeEventListener(event, listener);\r\n      d.audio.pause();\r\n      d.audio.removeAttribute('src');\r\n      d.audio.load();\r\n    }\r\n    d.listeners = [];\r\n    if (d.nodes) for (const node of Object.values(d.nodes)) node.disconnect();\r\n    d.nodes = null; d.audio = null;\r\n  }\r\n  function load(id, track) {\r\n    const d = getDeck(id);\r\n    if (track === null) {\r\n      cancelTransition(); release(d); d.track = null; d.bpm = null;\r\n      d.rate = 1; d.cue = 0; d.loopBeats = 0; d.loopStart = 0;\r\n      emit(); return snapshot();\r\n    }\r\n    if (!track || typeof track.url !== 'string') throw new TypeError('Choose a playable track.');\r\n    // Only our bundled assets and browser-owned local blobs enter the mixer.\r\n    if (!/^(?:\\/audio\\/music\\/[a-z0-9-]+\\.(?:m4a|mp3|wav|ogg|aac|flac)|blob:[^\\s]+)$/i.test(track.url)) throw new TypeError('Choose a bundled track or import a local audio file.');\r\n    cancelTransition(); release(d);\r\n    d.track = { ...track }; d.bpm = validBpm(track.bpm) ? Number(track.bpm) : null;\r\n    d.rate = 1; d.cue = 0; d.loopBeats = 0; d.loopStart = 0;\r\n    const audio = new Audio();\r\n    audio.preload = 'metadata'; audio.crossOrigin = 'anonymous';\r\n    audio.playsInline = true; audio.setAttribute('playsinline', '');\r\n    audio.src = track.url;\r\n    audio.playbackRate = 1;\r\n    d.audio = audio;\r\n    const generation = d.generation;\r\n    for (const event of ['loadedmetadata', 'durationchange', 'play', 'pause', 'ended', 'error']) {\r\n      const listener = () => {\r\n        if (disposed || generation !== d.generation || d.audio !== audio) return;\r\n        if (event === 'play') d.playing = true;\r\n        if (event === 'pause' || event === 'ended' || event === 'error') d.playing = false;\r\n        if (event === 'error') { cancelTransition(); fail(new Error(`Could not load ${d.track.title || 'this track'}.`)); }\r\n        if (event === 'ended' && d.loopBeats && d.bpm) { seek(id, d.loopStart); void play(id); }\r\n        emit();\r\n      };\r\n      audio.addEventListener(event, listener); d.listeners.push([event, listener]);\r\n    }\r\n    audio.load(); emit(); return snapshot();\r\n  }\r\n  async function start(id, internal = false) {\r\n    const d = getDeck(id);\r\n    if (!d.audio) { fail(new Error('Load a track into this deck first.')); return false; }\r\n    if (!internal) cancelTransition();\r\n    const audio = d.audio, generation = d.generation, playGeneration = ++d.playGeneration;\r\n    try {\r\n      ensureGraph(d);\r\n      // Both calls occur before yielding: iOS requires the initiating user gesture.\r\n      const resumed = context.state === 'running' ? Promise.resolve() : context.resume();\r\n      const playing = audio.play();\r\n      await Promise.all([resumed, playing]);\r\n      if (disposed || d.audio !== audio || d.generation !== generation) { audio.pause(); return false; }\r\n      if (playGeneration !== d.playGeneration) return false;\r\n      d.playing = true; emit(); return true;\r\n    } catch (error) {\r\n      if (disposed || d.audio !== audio || d.generation !== generation || playGeneration !== d.playGeneration) return false;\r\n      audio.pause(); d.playing = false;\r\n      fail(new Error(`Playback could not start. Tap Play to retry. ${error.message || ''}`)); emit(); return false;\r\n    }\r\n  }\r\n  const play = id => start(id);\r\n  function pause(id) { const d = getDeck(id); cancelTransition(); d.playGeneration++; d.audio?.pause(); d.playing = false; emit(); }\r\n  const toggle = id => getDeck(id).playing ? (pause(id), Promise.resolve(false)) : play(id);\r\n  function seek(id, seconds) {\r\n    const d = getDeck(id);\r\n    if (!d.audio) return;\r\n    const duration = Number.isFinite(d.audio.duration) ? d.audio.duration : Number.MAX_SAFE_INTEGER;\r\n    d.audio.currentTime = numeric(seconds, 0, duration); emit();\r\n  }\r\n  function setCue(id) { const d = getDeck(id); d.cue = d.audio?.currentTime || 0; emit(); }\r\n  function cue(id) { const d = getDeck(id); if (d.playing) setCue(id); else seek(id, d.cue); }\r\n  function setLoop(id, beats) {\r\n    const d = getDeck(id), value = numeric(beats, 0, 64);\r\n    if (value && !d.bpm) { fail(new Error('Set a BPM before enabling a beat loop.')); return false; }\r\n    d.loopBeats = value; d.loopStart = d.audio?.currentTime || 0; emit(); return true;\r\n  }\r\n  function setBpm(id, bpm) {\r\n    const d = getDeck(id);\r\n    d.bpm = validBpm(bpm) ? Number(bpm) : null;\r\n    if (!d.bpm) d.loopBeats = 0;\r\n    emit();\r\n  }\r\n  function setRate(id, rate) {\r\n    const d = getDeck(id); d.rate = numeric(rate, .5, 2);\r\n    if (d.audio) { d.audio.playbackRate = d.rate; d.audio.preservesPitch = false; d.audio.webkitPreservesPitch = false; }\r\n    emit();\r\n  }\r\n  function setEQ(id, band, db) {\r\n    const d = getDeck(id);\r\n    if (!['low', 'mid', 'high'].includes(band)) throw new TypeError('EQ band must be low, mid or high.');\r\n    d.eq[band] = numeric(db, -24, 12);\r\n    if (d.nodes) d.nodes[band].gain.value = d.eq[band]; emit();\r\n  }\r\n  function setCrossfader(value) { getDeck('a'); cancelTransition(); crossfader = numeric(value, 0, 1); applyGains(); emit(); }\r\n  function setMaster(value) { getDeck('a'); master = numeric(value, 0, 1); applyGains(); emit(); }\r\n  function sync(id) {\r\n    const d = getDeck(id), other = decks[id === 'a' ? 'b' : 'a'];\r\n    if (!d.bpm || !other.bpm) { fail(new Error('Set BPM on both decks before syncing.')); return false; }\r\n    const rate = other.bpm * other.rate / d.bpm;\r\n    if (rate < .5 || rate > 2) { fail(new Error('These BPM values are outside the supported sync range.')); return false; }\r\n    setRate(id, rate); return true;\r\n  }\r\n  async function transition(seconds = 8) {\r\n    getDeck('a'); cancelTransition();\r\n    const token = transitionGeneration, from = crossfader;\r\n    const incoming = from < .5 ? 'b' : 'a', target = incoming === 'b' ? 1 : 0;\r\n    const d = decks[incoming], audio = d.audio, wasPlaying = d.playing, expectedPlayGeneration = d.playGeneration + 1;\r\n    if (!audio) { fail(new Error('Load a track into the incoming deck first.')); return false; }\r\n    if (!await start(incoming, true)) return false;\r\n    if (disposed || token !== transitionGeneration) {\r\n      if (!wasPlaying && d.audio === audio && d.playGeneration === expectedPlayGeneration) { audio.pause(); d.playing = false; emit(); }\r\n      return false;\r\n    }\r\n    const duration = numeric(seconds, .1, 120) * 1000, began = performance.now();\r\n    return new Promise(resolve => {\r\n      transitionJob = { resolve, timer: setInterval(() => {\r\n        if (disposed || token !== transitionGeneration) return cancelTransition();\r\n        const fraction = clamp((performance.now() - began) / duration, 0, 1);\r\n        crossfader = from + (target - from) * fraction; applyGains();\r\n        if (fraction === 1) { clearInterval(transitionJob.timer); transitionJob = null; resolve(true); }\r\n        emit();\r\n      }, 50) };\r\n      emit();\r\n    });\r\n  }\r\n  const ticker = setInterval(() => {\r\n    for (const [id, d] of Object.entries(decks)) {\r\n      if (!d.playing || !d.audio || !d.loopBeats || !d.bpm) continue;\r\n      const end = Math.min(d.loopStart + d.loopBeats * 60 / d.bpm,\r\n        Number.isFinite(d.audio.duration) ? d.audio.duration : Infinity);\r\n      if (end > d.loopStart && d.audio.currentTime >= end) {\r\n        d.audio.currentTime = d.loopStart + ((d.audio.currentTime - end) % (end - d.loopStart));\r\n      }\r\n    }\r\n    if (performance.now() - lastEmit >= 200 && Object.values(decks).some(d => d.playing)) {\r\n      lastEmit = performance.now(); emit();\r\n    }\r\n  }, 25);\r\n  function dispose() {\r\n    if (disposed) return;\r\n    cancelTransition(); disposed = true; clearInterval(ticker);\r\n    Object.values(decks).forEach(release);\r\n    masterNode?.disconnect(); analyser?.disconnect();\r\n    if (context && context.state !== 'closed') void context.close().catch(() => {});\r\n  }\r\n  return { load, play, pause, toggle, seek, cue, setCue, setLoop, setBpm, setRate, setEQ,\r\n    setCrossfader, setMaster, sync, transition, snapshot, getAnalyser: () => analyser || null, dispose };\r\n}\r\n","actual-dj-hand.mjs":"// Reuse the user's native Handborne recipe and pose rig. This hand only taps the\r\n// reserved footer corner; it never targets, follows or writes a music control.\r\nexport function deckBeat(deck) {\r\n if(!deck?.playing||!Number.isFinite(deck.bpm)||deck.bpm<=0||deck.bpm>400||!Number.isFinite(deck.position))return null;\r\n const beats=Math.max(0,deck.position)*deck.bpm/60;\r\n return {index:Math.floor(beats),phase:beats-Math.floor(beats)};\r\n}\r\nexport function handAction(state) {\r\n const id=state?.crossfader<.5?'a':'b',beat=deckBeat(state?.decks?.[id]);\r\n return {mode:beat?'corner-beat':'idle',beat};\r\n}\r\n\r\nexport function createDJHand(dialog,{getState=()=>null,loadRig=()=>import('/handborne/companion.mjs')}={}) {\r\n const shell=dialog.querySelector('.sp-shell'),host=document.createElement('div');\r\n host.className='dj-hand-overlay';host.hidden=true;host.setAttribute('aria-hidden','true');shell.append(host);\r\n let active=false,disposed=false,loading=false,attempted=false,fallbackMissing=false,rig=null,revision=0,frame=0,last=0,rendering=false;\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n function fallback(){\r\n  let family=11;try{const recipe=JSON.parse(localStorage.getItem('handborne-recipe-v4'));if(Number.isInteger(recipe?.sections?.palm)&&recipe.sections.palm>=0&&recipe.sections.palm<23)family=recipe.sections.palm;}catch{}\r\n  const img=document.createElement('img');img.alt='';img.src=`/handborne/previews/family-${String(family).padStart(2,'0')}.png?v=5`;\r\n  img.onerror=()=>{if(host.firstElementChild===img){fallbackMissing=true;host.hidden=true;shell.classList.remove('dj-corner-tapping');}};\r\n  host.replaceChildren(img);host.dataset.family=String(family);\r\n }\r\n async function load(){\r\n  if(loading||attempted||rig||disposed||!active)return;loading=true;attempted=true;const mine=revision;\r\n  try{const{createHandCompanion}=await loadRig();if(disposed||!active||mine!==revision)return;\r\n   host.replaceChildren();fallbackMissing=false;rig=createHandCompanion(host,{cropWrist:true,onStatus:text=>{host.dataset.ready=String(text==='Helping Hand ready');}});rig.gesture('point-at-you');rig.setActive(rendering);\r\n  }catch{if(!disposed&&active&&mine===revision){fallback();host.dataset.ready='false';}}\r\n  finally{loading=false;if(active&&!disposed&&mine!==revision)void load();}\r\n }\r\n function tick(now){\r\n  if(!active||disposed)return;frame=requestAnimationFrame(tick);if(now-last<40)return;last=now;\r\n  const action=handAction(getState()),tapping=!!action.beat&&!document.hidden;\r\n  if(tapping&&!attempted&&!loading){fallback();void load();}\r\n  host.hidden=!tapping||fallbackMissing;shell.classList.toggle('dj-corner-tapping',!host.hidden);\r\n  host.dataset.mode=tapping?'corner-beat':'idle';host.dataset.beat=tapping?String(action.beat.index):'';host.dataset.tempo=action.beat?'known':'unknown';host.dataset.target='';\r\n  if(tapping){const box=shell.getBoundingClientRect(),width=host.offsetWidth||64,height=host.offsetHeight||84,lift=reduced.matches?0:Math.sin(action.beat.phase*Math.PI)*7;\r\n   host.style.transform=`translate(${Math.max(0,box.width-width-8).toFixed(1)}px,${Math.max(0,box.height-height-4-lift).toFixed(1)}px)`;\r\n  }\r\n  if(tapping!==rendering){rig?.setActive(tapping);rendering=tapping;}\r\n }\r\n function stop(){revision++;cancelAnimationFrame(frame);frame=0;rendering=false;rig?.dispose();rig=null;host.hidden=true;host.dataset.ready='false';host.dataset.mode='idle';host.dataset.beat='';host.dataset.target='';shell.classList.remove('dj-corner-tapping');}\r\n return {\r\n  setActive(value){value=!!value&&!disposed;if(value===active)return;active=value;if(!active){stop();return;}attempted=false;fallbackMissing=false;last=0;frame=requestAnimationFrame(tick);},\r\n  dispose(){if(disposed)return;disposed=true;active=false;stop();host.remove();},\r\n };\r\n}\r\n","actual-dj-library.mjs":"// BPM values are measured values from audio/music/manifest.json, refreshed by list().\r\nexport const MYR5_DJ_TRACKS = Object.freeze([\r\n  ['hey-man-idk', 'Hey Man IDK', 188.43],\r\n  ['guarded-gate', 'Guarded Gate', 121.3],\r\n  ['daemon-time', 'Daemon Time', 90.16],\r\n  ['sick-with-science', 'Sick with Science', 140.5],\r\n  ['laboratory-violence', 'Laboratory Violence', 120],\r\n  ['main-theme-one', 'Main Theme One', 120],\r\n].map(([id, title, bpm]) => Object.freeze({ id, title, artist: 'MYR5', bpm,\r\n  url: `/audio/music/${id}.m4a`, local: false })));\r\n\r\nconst MAX_BYTES = 100 * 1024 * 1024;\r\nconst AUDIO_EXTENSION = /\\.(mp3|m4a|aac|wav|ogg|oga|opus|flac|aif|aiff|webm)$/i;\r\nconst DB_NAME = 'myr5-actual-dj';\r\n\r\nexport function createDJLibrary({ onError = () => {} } = {}) {\r\n  const records = new Map();\r\n  let db = null, disposed = false, ready = null, manifestReady = null;\r\n  let defaults = MYR5_DJ_TRACKS.map(track => ({ ...track }));\r\n  const report = error => { if (!disposed) onError(error instanceof Error ? error : new Error(String(error))); };\r\n  const assertOpen = () => { if (disposed) throw new Error('DJ library has been closed.'); };\r\n  const expose = record => ({ id: record.id, title: record.title, artist: record.artist,\r\n    url: record.url, bpm: record.bpm ?? null, local: true, size: record.blob.size,\r\n    persistent: record.persistent });\r\n  function add(record, persistent) {\r\n    if (!record || typeof record.id !== 'string' || !(record.blob instanceof Blob)) return;\r\n    if (!record.blob.size || record.blob.size > MAX_BYTES) return;\r\n    const previous = records.get(record.id);\r\n    if (previous) URL.revokeObjectURL(previous.url);\r\n    records.set(record.id, { ...record, persistent, url: URL.createObjectURL(record.blob) });\r\n  }\r\n  function transaction(mode, action) {\r\n    return new Promise((resolve, reject) => {\r\n      let tx;\r\n      try {\r\n        tx = db.transaction('tracks', mode);\r\n        tx.oncomplete = () => resolve();\r\n        tx.onerror = tx.onabort = () => reject(tx.error || new Error('Audio storage failed.'));\r\n        action(tx.objectStore('tracks'));\r\n      } catch (error) { reject(error); }\r\n    });\r\n  }\r\n  async function initialize() {\r\n    if (ready) return ready;\r\n    ready = (async () => {\r\n      try {\r\n        if (!globalThis.indexedDB) throw new Error('Local audio storage is unavailable. Imports will last for this session.');\r\n        const database = await new Promise((resolve, reject) => {\r\n          const request = indexedDB.open(DB_NAME, 1);\r\n          let failed = false;\r\n          request.onupgradeneeded = () => request.result.createObjectStore('tracks', { keyPath: 'id' });\r\n          request.onerror = () => { failed = true; reject(request.error || new Error('Local audio storage is unavailable.')); };\r\n          request.onblocked = () => { failed = true; reject(new Error('Audio storage is busy. Imports will last for this session.')); };\r\n          request.onsuccess = () => { if (failed || disposed) request.result.close(); resolve(request.result); };\r\n        });\r\n        if (disposed) { database.close(); return; }\r\n        db = database;\r\n        db.onversionchange = () => { db?.close(); db = null; };\r\n        await transaction('readonly', store => {\r\n          const request = store.getAll();\r\n          request.onsuccess = () => {\r\n            if (!disposed) for (const record of request.result) add(record, true);\r\n          };\r\n        });\r\n      } catch (error) { report(error); db?.close(); db = null; }\r\n    })();\r\n    return ready;\r\n  }\r\n  function readManifest() {\r\n    if (manifestReady) return manifestReady;\r\n    manifestReady = (async () => {\r\n      try {\r\n        const response = await fetch('/audio/music/manifest.json');\r\n        if (!response.ok) return;\r\n        const manifest = await response.json();\r\n        if (disposed) return;\r\n        defaults = defaults.map(track => {\r\n          const source = manifest.tracks?.[track.id];\r\n          // Never accept replacement URLs from cached or malformed metadata.\r\n          return source?.url === track.url && Number.isFinite(source.bpm) && source.bpm >= 30 && source.bpm <= 300\r\n            ? { ...track, bpm: source.bpm } : track;\r\n        });\r\n      } catch { /* Built-in metadata remains available offline. */ }\r\n    })();\r\n    return manifestReady;\r\n  }\r\n  async function list() {\r\n    assertOpen(); await Promise.all([initialize(), readManifest()]); assertOpen();\r\n    return [...defaults.map(track => ({ ...track })), ...Array.from(records.values(), expose)];\r\n  }\r\n  async function importFiles(files) {\r\n    assertOpen();\r\n    const supplied = Array.from(files || []);\r\n    const valid = [];\r\n    for (const file of supplied) {\r\n      if (!(file instanceof Blob) || !file.name || (!AUDIO_EXTENSION.test(file.name) && !/^audio\\//i.test(file.type))) {\r\n        report(new TypeError('Choose an audio file such as MP3, M4A, WAV or OGG.')); continue;\r\n      }\r\n      if (!file.size || file.size > MAX_BYTES) {\r\n        report(new RangeError(`${file.name}: audio files must be between 1 byte and 100 MB.`)); continue;\r\n      }\r\n      // An explicit non-audio MIME is rejected even if the filename looks like audio.\r\n      if (file.type && !/^audio\\//i.test(file.type) && !['application/octet-stream', 'video/webm'].includes(file.type)) {\r\n        report(new TypeError(`${file.name} is not an audio file.`)); continue;\r\n      }\r\n      valid.push(file);\r\n    }\r\n    await initialize(); assertOpen();\r\n    const imported = [];\r\n    for (const file of valid) {\r\n      const record = { id: `local-${globalThis.crypto?.randomUUID?.() || `${Date.now()}-${Math.random().toString(36).slice(2)}`}`,\r\n        title: file.name.replace(AUDIO_EXTENSION, ''), artist: 'Local audio',\r\n        blob: file, bpm: null };\r\n      add(record, false);\r\n      if (db) {\r\n        try {\r\n          await transaction('readwrite', store => store.put(record));\r\n          const saved = records.get(record.id);\r\n          if (saved) saved.persistent = true;\r\n        } catch (error) {\r\n          report(new Error(`Could not save ${file.name}. It remains playable for this session. ${error.message || ''}`));\r\n        }\r\n      }\r\n      if (disposed) throw new Error('DJ library has been closed.');\r\n      const current = records.get(record.id);\r\n      if (current) imported.push(expose(current));\r\n    }\r\n    return imported;\r\n  }\r\n  async function remove(id) {\r\n    assertOpen(); await initialize(); assertOpen();\r\n    const record = records.get(id);\r\n    if (!record) return false;\r\n    // Keep the playable record if a persisted delete fails; don't resurrect it silently on next load.\r\n    if (record.persistent) {\r\n      if (!db) throw new Error('Audio storage is unavailable. Reopen the DJ before deleting this saved track.');\r\n      await transaction('readwrite', store => store.delete(id));\r\n    }\r\n    assertOpen(); records.delete(id); URL.revokeObjectURL(record.url); return true;\r\n  }\r\n  function dispose() {\r\n    if (disposed) return;\r\n    disposed = true;\r\n    for (const record of records.values()) URL.revokeObjectURL(record.url);\r\n    records.clear(); db?.close(); db = null;\r\n  }\r\n  return { list, importFiles, remove, dispose };\r\n}\r\n","actual-dj-playlist.mjs":"// Saved ordering only. Playback remains owned by each source's existing player.\r\nexport function reconcilePlaylist(order,localTracks,sourceLinks,makeId=()=>crypto.randomUUID()){\r\n const locals=new Map();for(const track of localTracks)locals.set(track.id,(locals.get(track.id)||0)+1);\r\n const sources=new Set(sourceLinks.map(entry=>entry.playlistId)),seen=new Set(),result=[];\r\n for(const ref of Array.isArray(order)?order:[]){if(!ref||typeof ref.id!=='string'||ref.id.length>100||seen.has(ref.id))continue;\r\n  if(ref.kind==='local'&&locals.get(ref.trackId)>0){locals.set(ref.trackId,locals.get(ref.trackId)-1);result.push({id:ref.id,kind:'local',trackId:ref.trackId});}\r\n  else if(ref.kind==='source-link'&&sources.delete(ref.sourceId))result.push({id:ref.id,kind:'source-link',sourceId:ref.sourceId});else continue;seen.add(ref.id);\r\n }\r\n for(const track of localTracks)if(locals.get(track.id)>0){result.push({id:makeId(),kind:'local',trackId:track.id});locals.set(track.id,locals.get(track.id)-1);}\r\n for(const entry of sourceLinks)if(sources.delete(entry.playlistId))result.push({id:makeId(),kind:'source-link',sourceId:entry.playlistId});\r\n return result;\r\n}\r\nexport function movePlaylistItem(order,id,step){const index=order.findIndex(ref=>ref.id===id),target=index+step;if(index<0||![-1,1].includes(step)||target<0||target>=order.length)return order;const next=order.slice();[next[index],next[target]]=[next[target],next[index]];return next;}\r\nexport function assignPlaylistIds(entries,makeId=()=>crypto.randomUUID()){\r\n const seen=new Set();return entries.map(entry=>{let id=entry.playlistId;if(typeof id!=='string'||!id||id.length>100||seen.has(id))id=makeId();seen.add(id);return {...entry,playlistId:id};});\r\n}\r\n","actual-dj-providers.mjs":"// Provider audio stays in the provider's official player. PCM mixing is for local audio.\r\nexport const DJ_PROVIDERS=Object.freeze([\r\n {id:'apple',name:'Apple Music',home:'https://music.apple.com/',hint:'Paste an Apple Music song, album, or playlist link.',mode:'Official player'},\r\n {id:'spotify',name:'Spotify',home:'https://open.spotify.com/',hint:'Paste a Spotify track, album, or playlist link.',mode:'Official player + account controls'},\r\n {id:'soundcloud',name:'SoundCloud',home:'https://soundcloud.com/',hint:'Paste a SoundCloud track or playlist link.',mode:'Official player'},\r\n {id:'youtube',name:'YouTube',home:'https://music.youtube.com/',hint:'Paste a YouTube video link.',mode:'Official video player'},\r\n {id:'tidal',name:'TIDAL',home:'https://tidal.com/',hint:'Paste a TIDAL track, album, or playlist link.',mode:'Official player'},\r\n {id:'deezer',name:'Deezer',home:'https://www.deezer.com/',hint:'Paste a Deezer track, album, or playlist link.',mode:'Official player'},\r\n {id:'bandcamp',name:'Bandcamp',home:'https://bandcamp.com/',hint:'Paste a Bandcamp album or track link.',mode:'Opens Bandcamp'},\r\n {id:'amazon',name:'Amazon Music',home:'https://music.amazon.com/',hint:'Paste an Amazon Music link.',mode:'Opens Amazon Music'},\r\n]);\r\nexport function providerLink(id,value){\r\n const provider=DJ_PROVIDERS.find(p=>p.id===id);if(!provider)return null;\r\n try{\r\n  const u=new URL(String(value).trim());\r\n  if(u.protocol!=='https:'||u.username||u.password||u.port||u.hash)return null;\r\n  let embed=null;\r\n  if(id==='apple'){\r\n   if(u.hostname!=='music.apple.com'||!/^\\/[a-z]{2}\\/(album|song|playlist)\\/[\\w%.,~!()'/-]+$/.test(u.pathname))return null;\r\n   embed='https://embed.music.apple.com'+u.pathname+(u.searchParams.get('i')&&/^\\d+$/.test(u.searchParams.get('i'))?'?i='+u.searchParams.get('i'):'');\r\n  }else if(id==='spotify'){\r\n   if(u.hostname!=='open.spotify.com')return null;\r\n   const match=u.pathname.match(/^\\/(?:intl-[a-z]{2}\\/)?(track|album|playlist)\\/([A-Za-z0-9]{22})\\/?$/);if(!match)return null;\r\n   embed=`https://open.spotify.com/embed/${match[1]}/${match[2]}`;\r\n  }else if(id==='soundcloud'){\r\n   if(!['soundcloud.com','www.soundcloud.com'].includes(u.hostname)||!/^\\/[\\w-]+\\/[\\w/-]+\\/?$/.test(u.pathname))return null;\r\n   embed='https://w.soundcloud.com/player/?'+new URLSearchParams({url:u.origin+u.pathname,auto_play:'false',show_artwork:'true'});\r\n  }else if(id==='youtube'){\r\n   let video;if(u.hostname==='youtu.be')video=u.pathname.slice(1);else if(['youtube.com','www.youtube.com','music.youtube.com'].includes(u.hostname))video=u.searchParams.get('v');else return null;\r\n   if(!/^[A-Za-z0-9_-]{11}$/.test(video||''))return null;\r\n   embed=`https://www.youtube-nocookie.com/embed/${video}?playsinline=1`;\r\n  }else if(id==='tidal'){\r\n   if(!['tidal.com','www.tidal.com','listen.tidal.com'].includes(u.hostname))return null;\r\n   const m=u.pathname.match(/^\\/(?:browse\\/)?(track|album|playlist)\\/(\\d+|[a-f0-9-]{36})\\/?$/);if(!m)return null;\r\n   embed=`https://embed.tidal.com/${m[1]}s/${m[2]}`;\r\n  }else if(id==='deezer'){\r\n   if(!['deezer.com','www.deezer.com'].includes(u.hostname))return null;\r\n   const m=u.pathname.match(/^\\/(?:[a-z]{2}\\/)?(track|album|playlist)\\/(\\d+)\\/?$/);if(!m)return null;\r\n   embed=`https://widget.deezer.com/widget/dark/${m[1]}/${m[2]}`;\r\n  }else if(id==='bandcamp'){\r\n   if(!u.hostname.endsWith('.bandcamp.com')||!/^\\/(album|track)\\/[\\w-]+\\/?$/.test(u.pathname))return null;\r\n  }else if(id==='amazon'){\r\n   if(!['music.amazon.com','music.amazon.co.uk','music.amazon.de','music.amazon.co.jp'].includes(u.hostname)||!/^\\/(albums|playlists|tracks|artists)\\/[A-Za-z0-9]+\\/?$/.test(u.pathname))return null;\r\n  }\r\n  return {provider:id,name:provider.name,url:u.href,embed};\r\n }catch{return null;}\r\n}\r\n\r\nconst LOCAL_SOURCE=Object.freeze({\r\n id:'local',name:'MYR5 + imported audio',route:'local-deck',\r\n capabilities:Object.freeze({localMix:true,autoDJ:true,manualHandoff:false,sourceAttributionRequired:false,controls:'local-deck'}),\r\n});\r\nconst PROVIDER_ROUTES=Object.freeze({\r\n apple:Object.freeze({route:'official-player',controls:'official-player'}),\r\n spotify:Object.freeze({route:'official-player',controls:'spotify-terminal-separate'}),\r\n soundcloud:Object.freeze({route:'official-player',controls:'official-player'}),\r\n youtube:Object.freeze({route:'official-player',controls:'official-player'}),\r\n tidal:Object.freeze({route:'official-player',controls:'official-player'}),\r\n deezer:Object.freeze({route:'official-player',controls:'official-player'}),\r\n bandcamp:Object.freeze({route:'external-link',controls:'external-app'}),\r\n amazon:Object.freeze({route:'external-link',controls:'external-app'}),\r\n});\r\n\r\n// Source picks describe where a link can be opened. Only local audio can enter\r\n// the Web Audio decks; the Spotify account/API surface remains its own route.\r\nexport function getDJSourceChoices(){\r\n return [LOCAL_SOURCE,...DJ_PROVIDERS.map(provider=>{\r\n  const route=PROVIDER_ROUTES[provider.id];\r\n  return Object.freeze({\r\n   id:provider.id,name:provider.name,home:provider.home,hint:provider.hint,mode:provider.mode,route:route.route,\r\n   capabilities:Object.freeze({\r\n    localMix:false,autoDJ:false,manualHandoff:true,sourceAttributionRequired:true,controls:route.controls,\r\n   }),\r\n  });\r\n })];\r\n}\r\n\r\n// Normalize a user-authored source link without resolving track metadata or\r\n// implying that a protected provider can play through the local mixer.\r\nexport function normalizeProviderSourceEntry(providerId,sourceUrl,label){\r\n if(typeof sourceUrl!=='string'||sourceUrl.length>2048)return null;\r\n if(typeof label!=='string'||label.length>120||/[\\u0000-\\u001f\\u007f]/.test(label))return null;\r\n const cleanLabel=label.trim();if(!cleanLabel)return null;\r\n const provider=DJ_PROVIDERS.find(item=>item.id===providerId);if(!provider)return null;\r\n const link=providerLink(providerId,sourceUrl);if(!link)return null;\r\n const choice=getDJSourceChoices().find(item=>item.id===providerId);\r\n return Object.freeze({\r\n  kind:'source-link',provider:providerId,label:cleanLabel,sourceUrl,\r\n  validatedUrl:link.url,embedUrl:link.embed,route:choice.route,capabilities:choice.capabilities,\r\n  attribution:Object.freeze({app:'actual.dj',provider:provider.name,sourceUrl}),\r\n });\r\n}\r\n","actual-dj-visualizer.mjs":"// Actual MilkDrop rendering: pinned, unmodified Butterchurn + original presets.\r\n// Provenance and MIT notices: ./vendor/butterchurn/README.md.\r\nlet libraryPromise;\r\nfunction script(path) {\r\n  return new Promise((resolve, reject) => {\r\n    const element = document.createElement('script');\r\n    element.src = new URL(path, import.meta.url).href;\r\n    element.onload = resolve;\r\n    element.onerror = () => { element.remove(); reject(Error('Visualizer library could not load.')); };\r\n    document.head.append(element);\r\n  });\r\n}\r\nfunction libraries() {\r\n  return libraryPromise ??= Promise.all([\r\n    script('./vendor/butterchurn/butterchurn-2.6.7.min.js'),\r\n    script('./vendor/butterchurn/presets-2.4.7.min.js'),\r\n  ]).then(() => ({\r\n    engine: window.butterchurn?.default ?? window.butterchurn,\r\n    presets: window.butterchurnPresets.getPresets(),\r\n  })).catch(error => { libraryPromise = null; throw error; });\r\n}\r\n\r\nconst SCENES = {\r\n  orbit: ['Flexi - mindblob mix', 'Flexi - mindblob [shiny mix]', 'Flexi - alien fish pond'],\r\n  tunnel: ['martin - glass corridor', 'martin - The Bridge of Khazad-Dum', 'martin - frosty caves 2'],\r\n  spectrum: ['Geiss - Thumb Drum', 'Geiss - Spiral Artifact', 'Geiss - Reaction Diffusion 2'],\r\n  scope: ['Eo.S. + Phat - cubetrace - v2', 'martin - chain breaker', 'Martin - liquid arrows'],\r\n  trails: ['Zylot - Paint Spill (Music Reactive Paint Mix)', 'Cope - The Neverending Explosion of Red Liquid Fire', 'martin - stormy sea (2010 update)'],\r\n};\r\n\r\nexport function createDJVisualizer(canvas, { getAnalyser = () => null, onStatus = () => {} } = {}) {\r\n  const motion = matchMedia('(prefers-reduced-motion: reduce)');\r\n  let running = false, disposed = false, failed = false, pending = false, frame = 0, last = 0;\r\n  let lib, viz, gl, source, gain, scene = 'orbit', palette = 0, react = 1, presetDirty = true;\r\n  let micStream, micContext, micAnalyser, micSource, micGeneration = 0;\r\n  let external = false, lastStatus = '', sizedRatio = 0;\r\n  const waveform = new Uint8Array(1024);\r\n  const status = text => { if (text !== lastStatus) { lastStatus = text; onStatus(text); } };\r\n  const selected = () => micAnalyser ?? getAnalyser();\r\n  const dimensions = () => {\r\n    const rect = canvas.getBoundingClientRect();\r\n    sizedRatio = Math.min(devicePixelRatio || 1, 1.5);\r\n    // Butterchurn 2.6.7 uses width/height directly for its output viewport;\r\n    // pixelRatio multiplies internal textures only. Apply our mobile cap once\r\n    // here and give its canonical sizing API the same backing-pixel dimensions.\r\n    return { width: Math.max(1, Math.round(rect.width * sizedRatio)), height: Math.max(1, Math.round(rect.height * sizedRatio)), pixelRatio: 1 };\r\n  };\r\n  function resize() {\r\n    if (!viz) return;\r\n    const { width, height, pixelRatio } = dimensions();\r\n    if (canvas.width === width && canvas.height === height) return;\r\n    canvas.width = width; canvas.height = height;\r\n    viz.setRendererSize(width, height, { pixelRatio });\r\n  }\r\n  const observer = new ResizeObserver(resize);\r\n  observer.observe(canvas);\r\n  window.addEventListener('resize', resize);\r\n\r\n  function detach() {\r\n    if (gain) {\r\n      try { source?.disconnect(gain); } catch {}\r\n      try { viz?.disconnectAudio(gain); } catch {}\r\n      gain.disconnect();\r\n    }\r\n    gain = null; source = null; external = false;\r\n  }\r\n  function bind(analyser) {\r\n    detach(); source = analyser;\r\n    // Butterchurn's native processor is tied to its first AudioContext. Its\r\n    // documented render(audioLevels) input handles a microphone in another\r\n    // context without reconnecting incompatible nodes or restarting WebGL.\r\n    external = analyser.context !== viz.audio.audioContext;\r\n    if (!external) {\r\n      gain = analyser.context.createGain(); gain.gain.value = react;\r\n      analyser.connect(gain); viz.connectAudio(gain);\r\n    }\r\n  }\r\n  function preset() {\r\n    const name = SCENES[scene][palette];\r\n    const original = lib.presets[name];\r\n    if (!original) throw Error(`Missing original Butterchurn preset: ${name}`);\r\n    // Upstream loadPreset adds default fields to shapes/waves; copy the\r\n    // official preset so one instance cannot mutate another's preset bank.\r\n    viz.loadPreset(structuredClone(original), motion.matches ? 0 : 1.2);\r\n    presetDirty = false;\r\n    status(`${micAnalyser ? 'Microphone' : 'MYR5 mix'} · Butterchurn · ${name}`);\r\n  }\r\n  async function initialize(analyser) {\r\n    if (pending || disposed || failed) return;\r\n    pending = true;\r\n    try {\r\n      lib = await libraries();\r\n      if (!running || disposed) return;\r\n      const current = selected();\r\n      if (!current || current.context.state === 'closed') return;\r\n      gl = canvas.getContext('webgl2', { alpha: false, antialias: false, depth: false, stencil: false, premultipliedAlpha: false });\r\n      if (!gl) throw Error('WebGL2 is unavailable. This device cannot run MilkDrop visuals.');\r\n      const size = dimensions();\r\n      canvas.width = size.width; canvas.height = size.height;\r\n      viz = lib.engine.createVisualizer(current.context, canvas, size);\r\n      viz.setInternalMeshSize(32, 24);\r\n      bind(current); resize(); preset();\r\n    } catch (error) {\r\n      failed = true; status(error.message || 'MilkDrop visualizer could not start.');\r\n    } finally { pending = false; }\r\n  }\r\n  function draw(now) {\r\n    if (!running || disposed) return;\r\n    frame = requestAnimationFrame(draw);\r\n    const interval = 1000 / (motion.matches ? 12 : 30);\r\n    if (now - last < interval) return;\r\n    const delta = last ? Math.min((now - last) / 1000, .1) : 1 / 30;\r\n    last = now;\r\n    const analyser = selected();\r\n    if (viz && sizedRatio !== Math.min(devicePixelRatio || 1, 1.5)) resize();\r\n    if (!analyser || analyser.context.state === 'closed') {\r\n      if (source) detach();\r\n      status('Choose local audio or microphone for live MilkDrop visuals.'); return;\r\n    }\r\n    if (!viz) { void initialize(analyser); return; }\r\n    if (failed) return;\r\n    try {\r\n      if (source !== analyser) { bind(analyser); presetDirty = true; }\r\n      if (presetDirty) preset();\r\n      // Reduced motion disables preset morphing and lowers frames to twelve.\r\n      // Butterchurn expects elapsedTime as a frame delta, not a playhead.\r\n      if (external) {\r\n        waveform.fill(128);\r\n        analyser.getByteTimeDomainData(waveform);\r\n        for (let i = 0; i < waveform.length; i++) waveform[i] = Math.max(0, Math.min(255, 128 + (waveform[i] - 128) * react));\r\n        viz.render({ elapsedTime: delta, audioLevels: { timeByteArray: waveform, timeByteArrayL: waveform, timeByteArrayR: waveform } });\r\n      } else viz.render({ elapsedTime: delta });\r\n    } catch (error) { failed = true; detach(); status(`MilkDrop stopped: ${error.message}`); }\r\n  }\r\n  function stopMic() {\r\n    micGeneration++;\r\n    if (source === micAnalyser) detach();\r\n    micStream?.getTracks().forEach(track => track.stop()); micStream = null;\r\n    micSource?.disconnect(); micSource = null; micAnalyser = null;\r\n    void micContext?.close().catch(() => {}); micContext = null;\r\n  }\r\n  async function microphone() {\r\n    if (disposed) return false;\r\n    stopMic(); const generation = micGeneration;\r\n    let stream, context;\r\n    try {\r\n      stream = await navigator.mediaDevices.getUserMedia({ audio: { echoCancellation: false, noiseSuppression: false, autoGainControl: false }, video: false });\r\n      if (generation !== micGeneration || disposed) { stream.getTracks().forEach(track => track.stop()); return false; }\r\n      context = new (window.AudioContext || window.webkitAudioContext)();\r\n      micStream = stream; micContext = context;\r\n      micAnalyser = context.createAnalyser(); micAnalyser.fftSize = 1024;\r\n      micSource = context.createMediaStreamSource(stream); micSource.connect(micAnalyser);\r\n      // Nothing connects the microphone to destination: visuals only.\r\n      await context.resume();\r\n      if (generation !== micGeneration || disposed) return false;\r\n      presetDirty = true; status('Microphone → MilkDrop visuals only.'); return true;\r\n    } catch {\r\n      // An older permission request must not close a newer capture session.\r\n      const current = generation === micGeneration;\r\n      if (current) stopMic();\r\n      else { stream?.getTracks().forEach(track => track.stop()); void context?.close().catch(() => {}); }\r\n      if (!disposed && current) status('Microphone unavailable. Allow access or choose the MYR5 mix.');\r\n      return false;\r\n    }\r\n  }\r\n  return {\r\n    start() { if (running || disposed) return; running = true; last = 0; failed = false; frame = requestAnimationFrame(draw); },\r\n    stop() { running = false; cancelAnimationFrame(frame); stopMic(); detach(); },\r\n    microphone,\r\n    useMix() { stopMic(); presetDirty = true; status('MYR5 mix → live MilkDrop visuals.'); },\r\n    setScene(value) { if (SCENES[value]) { scene = value; presetDirty = true; } },\r\n    setReact(value) { react = Math.max(.1, Math.min(3, Number(value) || 1)); if (gain) gain.gain.value = react; },\r\n    // Butterchurn has no universal palette API. This cycles original presets\r\n    // within each scene family; it is an alternate look, not a recolor shader.\r\n    setPalette(value) { palette = ((Math.trunc(Number(value) || 0) % 3) + 3) % 3; presetDirty = true; },\r\n    dispose() {\r\n      disposed = true; running = false; cancelAnimationFrame(frame); stopMic(); detach(); observer.disconnect(); window.removeEventListener('resize', resize);\r\n      // Upstream has no destroy(). Losing the owned context releases textures,\r\n      // buffers/programs without deleting another engine's AudioContext.\r\n      gl?.getExtension('WEBGL_lose_context')?.loseContext(); viz = null; lib = null;\r\n    },\r\n  };\r\n}\r\n","actual-dj.css":".actual-dj{width:min(1100px,calc(100vw - 16px));max-width:1100px;background:#100b18;color:#efdbff;border-color:#b376ec;font-family:ui-monospace,SFMono-Regular,Consolas,monospace;box-shadow:0 0 0 4px #231432,0 24px 80px #000d}\r\n.actual-dj .sp-shell{height:min(900px,calc(100dvh - 16px));grid-template-rows:auto auto minmax(0,1fr) auto}\r\n.actual-dj.portal-framed .sp-shell{height:100%;max-height:100%}\r\n.actual-dj .sp-top{padding:18px 24px;background:linear-gradient(110deg,#32173f,#100b18);border-color:#71437f}\r\n.actual-dj .sp-top h2{font-size:34px;letter-spacing:-.05em;text-transform:none;color:#ffb56f;text-shadow:none}\r\n.actual-dj .sp-top h2:after{content:' / MYR5';font-size:11px;letter-spacing:.12em;color:#c299d3}\r\n.actual-dj .sp-screen{background:radial-gradient(ellipse at top,#44235444,transparent 60%);padding:20px 24px 32px}\r\n.actual-dj .sp-shell footer{border-color:#4b3057;color:#b894c6}\r\n.actual-dj .dj-tabs{display:flex;gap:4px;padding:10px 20px;border-bottom:1px solid #4c315b;background:#150e21}\r\n.actual-dj button,.actual-dj select,.actual-dj input{font:inherit}\r\n.actual-dj button{min-height:44px;border:1px solid #76548d;border-radius:8px;padding:8px 12px;color:#efd8ff;background:#241731;box-shadow:none;touch-action:manipulation}\r\n.actual-dj button[aria-pressed=true]{color:#1c1025;background:#ffc07a;border-color:#ffc07a}\r\n.actual-dj button:hover{background:#49315d;color:#fff2e4}\r\n.actual-dj button:disabled{opacity:.55;cursor:wait}\r\n.actual-dj a{color:#ffb677}\r\n.actual-dj input:not([type=range]):not([type=file]),.actual-dj select{min-height:44px;min-width:0;border:1px solid #644777;border-radius:7px;background:#140c1e;color:#efdeff;padding:8px}\r\n.actual-dj input[type=range]{width:100%;accent-color:#ffb36d;min-height:32px;cursor:pointer}\r\n.actual-dj .dj-tabs button{flex:1;font-size:12px;letter-spacing:.08em}\r\n.actual-dj .sp-label{color:#c999ee;font-size:10px;letter-spacing:.12em}\r\n.actual-dj .dj-heading{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px}\r\n.dj-live{max-width:60%;font-size:10px;color:#ffbe78;text-align:right;overflow-wrap:anywhere}\r\n.dj-decks{display:grid;grid-template-columns:1fr 1fr;gap:18px}\r\n.dj-deck{padding:18px;border:1px solid #745382;border-radius:14px;background:linear-gradient(140deg,#302034,#16101f);min-width:0}\r\n.dj-deck[data-deck=b]{background:linear-gradient(140deg,#221d39,#15101f)}\r\n.dj-deck-source{font-size:9px;color:#aa8eb8;letter-spacing:.08em}\r\n.dj-record{display:grid;place-items:center;margin:8px auto 20px;width:clamp(110px,22vw,180px);aspect-ratio:1;border-radius:50%!important;border:8px solid #3d3145!important;background:repeating-radial-gradient(circle,#100b16 0 2px,#2f2236 2px 3px)!important;box-shadow:0 0 0 1px #91789d,0 12px 20px #0006!important;position:relative;overflow:hidden}\r\n.dj-record:after{content:'';width:3px;height:36%;background:#dac1de;position:absolute;top:1px;left:50%;transform-origin:bottom;opacity:.3}\r\n.dj-record span{display:grid;place-items:center;position:relative;z-index:1;width:45%;height:45%;border-radius:50%;background:#ffbd78;color:#22122c;font-size:26px;font-weight:900}\r\n.dj-deck[data-deck=b] .dj-record span{background:#b388ef}\r\n.dj-playing .dj-record{animation:dj-spin 6s linear infinite}\r\n.dj-title{display:block;font-size:18px;overflow-wrap:anywhere;color:#ffe1ba;min-height:26px}\r\n.dj-artist{display:block;font-size:11px;color:#bfa2cc;overflow-wrap:anywhere;min-height:22px}\r\n.dj-seek-wrap{display:block;margin-top:8px}.dj-time{display:block;font-size:10px;color:#bf9fd1;text-align:right}\r\n.dj-deck-controls{display:flex;gap:6px;margin:12px 0}.dj-deck-controls button{flex:1;padding:8px;font-size:11px}.dj-deck-controls .dj-play{background:#ffbb72;color:#281333;border-color:#ffbb72}\r\n.dj-tempo{display:flex;align-items:end;gap:8px}.dj-tempo label{display:flex;align-items:center;gap:8px;flex:1;font-size:10px}.dj-tempo input{width:100%;max-width:120px}.dj-tempo button{font-size:11px}\r\n.dj-rate-label{display:grid;grid-template-columns:auto 1fr 40px;gap:8px;align-items:center;font-size:10px;margin-top:8px}\r\n.dj-eq{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:8px}.dj-eq label{font-size:9px;text-align:center;color:#b99dc9;min-width:0}\r\n.dj-loop-label{display:flex;align-items:center;justify-content:space-between;font-size:10px;margin-top:10px;gap:8px}.dj-loop-label select{flex:1}\r\n.dj-mixer{padding:18px;background:#1a1025;border:1px solid #614473;border-radius:14px;margin:18px 0 24px}\r\n.dj-mixer>label{display:flex;align-items:center;gap:18px;font-weight:700}.dj-crossfader{height:42px}\r\n.dj-master-row{display:flex;align-items:center;gap:20px;margin-top:10px}.dj-master-row label{display:flex;align-items:center;gap:12px;flex:1;font-size:10px}.dj-master-row button{min-width:150px;background:#48305d}\r\n.dj-auto-row{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:12px}.dj-auto-row label{display:flex;align-items:center;gap:8px;font-size:10px}\r\n.dj-library,.dj-queue-section{padding:18px;border-radius:14px;border:1px solid #51375e;background:#160e20;margin:20px 0}.dj-import{position:relative;display:inline-flex;align-items:center;min-height:44px;padding:8px 12px;border:1px solid #9a6aae;border-radius:8px;font-size:11px;color:#ffc88b;cursor:pointer;overflow:hidden}.dj-import input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%}\r\n.dj-filter{width:100%}.dj-library-status,.dj-provider-note,.dj-visual-reference{color:#ae90be;font-size:11px;line-height:1.6}\r\n.dj-track-list,.dj-queue,.dj-spotify-results,.dj-spotify-queue{list-style:none;margin:10px 0 0;padding:0}\r\n.dj-crate-row{display:flex;align-items:center;gap:6px;padding:10px 0;border-bottom:1px solid #3e294b}.dj-crate-info,.dj-crate-row>strong{flex:1;min-width:0;overflow-wrap:anywhere}.dj-crate-info strong,.dj-crate-info small{display:block}.dj-crate-info strong{font-size:12px;color:#ffe0bd}.dj-crate-info small{font-size:10px;color:#b799c8;margin-top:3px}.dj-crate-row button{min-width:42px;flex-shrink:0;padding:7px;font-size:11px}.dj-crate-row>a{padding:8px}\r\n.dj-queue-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:6px 0}.dj-queue-row span{font-size:12px;overflow-wrap:anywhere}.dj-empty{font-size:12px;color:#ac8abf;padding:16px 0}\r\n.dj-provider-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:8px;margin:20px 0}.dj-provider-grid button{font-size:12px;min-height:58px}\r\n.dj-source-form>label,.dj-spotify-search>label{display:block;margin-bottom:8px;font-size:11px;color:#c8a6dd}.dj-source-form>div,.dj-spotify-search>div{display:flex;gap:8px}.dj-source-form input,.dj-spotify-search input{flex:1;min-width:0}\r\n.dj-source-status,.dj-visual-status,.dj-spotify-status{font-size:12px;color:#ffd1a4;line-height:1.6;min-height:24px}.dj-provider-frame{width:100%;height:370px;border:0;border-radius:12px;background:#140b1d;display:block;margin:16px 0}.dj-source-open{display:inline-block;border:1px solid #8755a0;padding:12px;border-radius:8px;text-decoration:none;font-size:12px;margin-top:12px}\r\n.dj-visual-stage{position:relative;border-radius:14px;overflow:hidden;background:#090415;border:1px solid #634678;width:100%;height:clamp(260px,46vh,540px)}.dj-visual-stage:fullscreen{height:100vh;border:0;border-radius:0}.dj-visual-canvas{display:block;width:100%;height:100%}\r\n.dj-visual-controls,.dj-visual-source{display:flex;gap:10px;justify-content:space-between;margin-top:14px}.dj-visual-controls label{display:flex;align-items:center;gap:10px;font-size:10px}.dj-visual-source button{flex:1;font-size:11px}.dj-visual-reference a{font-size:11px}\r\n.dj-react,.dj-spotify-seek,.dj-spotify-volume{display:flex;gap:12px;align-items:center;font-size:10px;color:#c5a5d5;margin-top:12px}\r\n.dj-spotify-extra{padding:16px;border:1px solid #674276;border-radius:12px;background:#1d1128;margin:20px 0}.dj-spotify-device,.dj-spotify-controls{display:flex;gap:8px;align-items:center;margin:14px 0}.dj-devices{flex:1;max-width:100%}.dj-spotify-controls label{display:flex;align-items:center;gap:8px;font-size:10px}\r\n.actual-dj .dj-view>section.sp-hand{position:relative;display:block;min-height:150px;border:0;background:none;padding:0}\r\n.actual-dj:not([data-dj-view=spotify]) .sp-shell>.sp-hand-mount,.actual-dj:not([data-dj-view=spotify]) .sp-status{display:none}\r\n.actual-dj [data-view=spotify]>.sp-account,.actual-dj [data-view=spotify]>.sp-now,.actual-dj [data-view=spotify]>.sp-jam,.actual-dj [data-view=spotify]>.sp-playlists{padding:16px;margin-bottom:18px;border:1px solid #654473;border-radius:12px;background:#1b1023}\r\n@keyframes dj-spin{to{transform:rotate(360deg)}}\r\n.actual-dj .sp-shell{position:relative}.dj-hand-overlay{position:absolute;left:0;top:0;z-index:5;width:64px;max-width:96px;height:84px;pointer-events:none;filter:drop-shadow(0 4px 6px #0009)}.dj-hand-overlay[hidden]{display:none}.dj-hand-overlay canvas,.dj-hand-overlay img{display:block;width:100%;height:100%;object-fit:contain;pointer-events:none}\r\n.dj-source-choice{display:grid;gap:5px;font-size:9px;margin:12px 0;color:#dcbce5}.dj-source-choice select{width:100%;min-width:0;padding:8px 4px;font-size:10px}.dj-deck-source-open{width:100%;font-size:9px;margin-bottom:12px}.dj-deck-source-open[hidden]{display:none}.dj-link-form{display:grid;gap:10px;margin:14px 0}.dj-link-form label{display:grid;gap:5px;font-size:10px}.dj-link-form input,.dj-link-form select{min-width:0;width:100%;box-sizing:border-box}.dj-link-list{list-style:none;margin:0;padding:0}.dj-source-row{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:7px;align-items:center;border-top:1px solid #593766;padding:10px 0}.dj-source-row button{padding:7px;font-size:10px}.dj-original-source{display:block;font-size:10px;color:#f9b772;overflow-wrap:anywhere}.dj-link-status{font-size:11px;color:#d8b5e5}\r\n@media(max-width:600px){.actual-dj .sp-top{padding:14px}.actual-dj .sp-screen{padding:14px 10px 24px}.actual-dj .dj-tabs{padding:8px;gap:4px}.actual-dj .dj-tabs button{padding:8px 4px;font-size:10px}.dj-decks{gap:8px}.dj-deck{padding:12px 8px}.dj-deck-source{font-size:7px}.dj-record{margin-bottom:16px;width:110px}.dj-title{font-size:14px;min-height:38px}.dj-tempo{gap:4px}.dj-tempo label{gap:4px}.dj-tempo input{max-width:70px;padding:5px!important}.dj-tempo button{padding:6px}.dj-rate-label{gap:4px;grid-template-columns:auto 1fr 28px;font-size:8px}.dj-eq{gap:6px}.dj-deck-controls{gap:4px}.dj-deck-controls button{font-size:9px;padding:6px 2px}.dj-mixer,.dj-library,.dj-queue-section{padding:12px}.dj-master-row{gap:12px}.dj-master-row button{min-width:110px;font-size:10px}.dj-auto-row{gap:8px}.dj-auto-row label{font-size:9px}.dj-auto-row select{max-width:110px}.dj-import{font-size:9px;padding:6px}.dj-crate-row{gap:4px}.dj-crate-row button{min-width:36px;padding:5px}.dj-crate-info strong{font-size:11px}.dj-provider-grid{grid-template-columns:repeat(2,1fr)}.dj-source-form>div{flex-wrap:wrap}.dj-source-form button{width:100%}.dj-visual-controls{gap:6px}.dj-visual-controls select{max-width:145px}.dj-visual-controls button{font-size:10px}.dj-spotify-device{flex-wrap:wrap}.dj-spotify-device select{width:100%}}\r\n@media(prefers-reduced-motion:reduce){.dj-playing .dj-record{animation:none}}\r\n.actual-dj .dj-tabs{flex-wrap:wrap}.actual-dj .dj-tabs [hidden],.actual-dj .dj-add-music [hidden],.actual-dj .dj-source-links[hidden]{display:none!important}.actual-dj .dj-tabs [data-view=playlist],.actual-dj .dj-tabs .dj-more{flex:1 0 40%;font-size:14px}.dj-playlist h3{margin:0;font-size:22px;color:#ffe0bd}.dj-playlist-count,.dj-current-source,.dj-next-title{font-size:11px;color:#bca0ca}.dj-playlist-status{font-size:11px;color:#bca0ca;margin:0 0 12px}.dj-simple-player{padding:14px;background:#25172f;border:1px solid #76548d;border-radius:12px}.dj-current-title,.dj-current-source,.dj-next-title{display:block;overflow-wrap:anywhere}.dj-simple-player>div{display:flex;gap:8px;margin:12px 0}.dj-simple-player button{flex:1}.dj-playlist-list{list-style:none;padding:0;margin:14px 0}.dj-playlist-row{padding:12px;border:1px solid #4d315c;border-radius:10px;margin:8px 0}.dj-playlist-row[aria-current=true]{border-color:#ffc07a}.dj-playlist-actions{display:flex;gap:6px;margin-top:8px}.dj-playlist-actions button{min-width:44px;padding:8px;font-size:11px}.dj-playlist-actions button:first-child{flex:1}.dj-add-music{border:1px solid #76548d;border-radius:10px;padding:12px;margin-top:16px}.dj-add-music summary{min-height:44px;display:flex;align-items:center;cursor:pointer;color:#ffd5a3}.dj-add-music label{display:grid;gap:6px;margin:8px 0;font-size:11px}.dj-add-music select{width:100%}.dj-add-local>button{margin:4px 4px 4px 0}\r\n\r\n.actual-dj .sp-shell.dj-corner-tapping>footer{box-sizing:border-box;min-height:100px;padding-right:80px;display:flex;align-items:center}\r\n","actual-dj.mjs":"import {createDJEngine} from './actual-dj-engine.mjs';\r\nimport {createDJLibrary} from './actual-dj-library.mjs';\r\nimport {DJ_PROVIDERS,providerLink,getDJSourceChoices,normalizeProviderSourceEntry} from './actual-dj-providers.mjs';\r\nimport {createDJVisualizer} from './actual-dj-visualizer.mjs';\r\nimport {parseDJCommand} from './actual-dj-commands.mjs';\r\nimport {createDJHand} from './actual-dj-hand.mjs';\r\nimport {reconcilePlaylist,movePlaylistItem,assignPlaylistIds} from './actual-dj-playlist.mjs';\r\n\r\nconst el=(tag,cls,text)=>{const n=document.createElement(tag);if(cls)n.className=cls;if(text!=null)n.textContent=text;return n;};\r\nconst time=s=>`${Math.floor((s||0)/60)}:${String(Math.floor((s||0)%60)).padStart(2,'0')}`;\r\nconst remember=(key,value)=>{try{localStorage.setItem(key,JSON.stringify(value));return true;}catch{return false;}};\r\nconst recall=(key,fallback)=>{try{return JSON.parse(localStorage.getItem(key))??fallback;}catch{return fallback;}};\r\n\r\n// Browser glue around the deck engine and the providers' own players.\r\nexport function mountActualDJ({dialog,spotifyJSON,spotifyAction}){\r\n const screen=dialog.querySelector('.sp-screen'),shell=dialog.querySelector('.sp-shell');\r\n dialog.classList.add('actual-dj');dialog.querySelector('h2').textContent='actual.dj';\r\n dialog.querySelector('.sp-close').setAttribute('aria-label','Close actual.dj');\r\n dialog.querySelector('footer').textContent='MYR5 COACH / ACTUAL.DJ';\r\n const spotifyView=el('div','dj-view');spotifyView.dataset.view='spotify';spotifyView.hidden=true;\r\n for(const section of [...screen.querySelectorAll(':scope > section')])spotifyView.append(section);\r\n const tabs=el('nav','dj-tabs');tabs.setAttribute('aria-label','DJ modes');\r\n for(const [id,name] of [['playlist','Playlist'],['mix','Local mix'],['providers','Music apps'],['spotify','Spotify'],['visuals','Visuals']]){const b=el('button','',name);b.type='button';b.dataset.view=id;b.setAttribute('aria-pressed',String(id==='playlist'));tabs.append(b);}\r\n const more=el('button','dj-more','More');more.type='button';more.setAttribute('aria-expanded','false');tabs.insertBefore(more,tabs.children[1]);for(const b of tabs.querySelectorAll('[data-view]:not([data-view=playlist])'))b.hidden=true;more.addEventListener('click',()=>{const expanded=more.getAttribute('aria-expanded')!=='true';more.setAttribute('aria-expanded',String(expanded));for(const b of tabs.querySelectorAll('[data-view]:not([data-view=playlist])'))b.hidden=!expanded;});shell.querySelector('.sp-top').after(tabs);screen.append(spotifyView);\r\n const root=el('div','dj-workspace');screen.prepend(root);\r\n root.innerHTML=`<section class=\"dj-view\" data-view=\"mix\"><div class=\"dj-heading\"><span class=\"sp-label\">TWO DECKS / ONE ROOM</span><span class=\"dj-live\">READY</span></div><div class=\"dj-decks\"></div><section class=\"dj-mixer\"><label>A <input class=\"dj-crossfader\" aria-label=\"Crossfader\" type=\"range\" min=\"0\" max=\"1\" step=\"0.01\" value=\"0\"> B</label><div class=\"dj-master-row\"><label>MASTER <input class=\"dj-master\" aria-label=\"Master volume\" type=\"range\" min=\"0\" max=\"1\" step=\"0.01\" value=\"0.75\"></label><button class=\"dj-transition\" type=\"button\">MIX TO B ↗</button></div><div class=\"dj-auto-row\"><button class=\"dj-auto\" type=\"button\" aria-pressed=\"false\">AUTOMIX OFF</button><label>FADE <select class=\"dj-fade\" aria-label=\"Transition length\"><option value=\"4\">4 seconds</option><option value=\"8\" selected>8 seconds</option><option value=\"16\">16 seconds</option></select></label></div></section><section class=\"dj-library\"><div class=\"dj-heading\"><span class=\"sp-label\">YOUR CRATE</span><label class=\"dj-import\">+ IMPORT AUDIO<input class=\"dj-files\" type=\"file\" accept=\"audio/*,.mp3,.m4a,.wav,.ogg,.flac,.aac\" multiple></label></div><input class=\"dj-filter\" type=\"search\" placeholder=\"Search your tracks…\" aria-label=\"Search local music\"><p class=\"dj-library-status\" role=\"status\">MYR5 music and your imported files. Imports stay on this device.</p><ol class=\"dj-track-list\"></ol></section><section class=\"dj-queue-section\"><div class=\"dj-heading\"><span class=\"sp-label\">UP NEXT / AUTOMIX</span><button class=\"dj-clear-queue\" type=\"button\">CLEAR</button></div><ol class=\"dj-queue\"></ol></section></section><section class=\"dj-view\" data-view=\"providers\" hidden><span class=\"sp-label\">MUSIC APPS</span><p>Choose a source and paste its music link. Playback uses the app’s own player.</p><div class=\"dj-provider-grid\"></div><form class=\"dj-source-form\"><label class=\"dj-source-label\" for=\"djSourceUrl\">Apple Music link</label><div><input id=\"djSourceUrl\" type=\"url\" placeholder=\"https://music.apple.com/…\" required><button type=\"submit\">OPEN PLAYER</button></div></form><p class=\"dj-source-status\" role=\"status\">Apple Music previews use Apple’s player. Open Apple Music for full playback.</p><div class=\"dj-source-player\"></div><a class=\"dj-source-open\" href=\"https://music.apple.com/\" target=\"_blank\" rel=\"noopener noreferrer\">OPEN APPLE MUSIC ↗</a><p class=\"dj-provider-note\">Account linking: Spotify controls are in the Spotify tab. Apple Music account access needs MusicKit setup. Bandcamp and Amazon open in their apps.</p></section><section class=\"dj-view\" data-view=\"visuals\" hidden><div class=\"dj-heading\"><span class=\"sp-label\">VISUALIZER</span><button class=\"dj-fullscreen\" type=\"button\">FULLSCREEN ↗</button></div><div class=\"dj-visual-stage\"><canvas class=\"dj-visual-canvas\" aria-label=\"Audio-reactive music visualizer\"></canvas></div><div class=\"dj-visual-controls\"><label>SCENE <select class=\"dj-scene\"><option value=\"orbit\">Orbit</option><option value=\"tunnel\">Tunnel</option><option value=\"spectrum\">Spectrum</option><option value=\"scope\">Scope</option><option value=\"trails\">Trails</option></select></label><button class=\"dj-palette\" type=\"button\">NEXT PRESET ↻</button></div><div class=\"dj-visual-source\"><button class=\"dj-mix-source\" type=\"button\">USE MYR5 MIX</button><button class=\"dj-mic\" type=\"button\">USE MICROPHONE</button></div><p class=\"dj-visual-status\" role=\"status\">Play a local deck, then let the mix drive the visuals.</p><p class=\"dj-visual-reference\">Engine: <a href=\"https://github.com/jberg/butterchurn\" target=\"_blank\" rel=\"noopener noreferrer\">Butterchurn / MilkDrop</a>. Interface reference: <a href=\"https://photism.app/online/\" target=\"_blank\" rel=\"noopener noreferrer\">Photism</a>. Provider players show their own artwork or video.</p></section>`;\r\n const $=s=>root.querySelector(s),say=message=>{$('.dj-live').textContent=message;};\r\n const autoButton=$('.dj-auto');autoButton.textContent='START AUTO DJ ▶';autoButton.disabled=true;\r\n autoButton.style.width='100%';autoButton.style.marginBottom='16px';\r\n $('.dj-decks').before(autoButton);\r\n autoButton.after(el('p','dj-library-status','Auto DJ mixes your MYR5 crate and audio imported on this device.'));\r\n const library=createDJLibrary({onError:e=>{$('.dj-library-status').textContent=e?.message||String(e);}});\r\n let tracks=[],queue=[],engine,visualizer,view='playlist',auto=false,autoBusy=false,autoStarting=false,autoRevision=0,disposed=false,revision=0,preset=0,provider='apple',spotifyPlaying=false,handoffBusy=false;\r\n let playlistOrder=recall('myr5.actualDJ.playlistOrder',[]),playlistReady=false,selectedPlaylistId=null,playlistBusy=false,requestedView=null;\r\n if(!Array.isArray(playlistOrder))playlistOrder=[];\r\n const playlistView=el('section','dj-view dj-playlist');playlistView.dataset.view='playlist';playlistView.innerHTML='<div class=\"dj-heading\"><h3>Playlist</h3><span class=\"dj-playlist-count\"></span></div><p class=\"dj-playlist-status\" role=\"status\">Loading saved songs…</p><section class=\"dj-simple-player\"><strong class=\"dj-current-title\">Choose a song</strong><small class=\"dj-current-source\"></small><div><button type=\"button\" class=\"dj-current-play\">Play</button><button type=\"button\" class=\"dj-next-item\">Select next</button></div><small class=\"dj-next-title\"></small></section><ol class=\"dj-playlist-list\" aria-label=\"Saved songs\"></ol><details class=\"dj-add-music\"><summary>+ Add music</summary><label>Music app <select class=\"dj-add-source\" aria-label=\"Add music from\"></select></label><div class=\"dj-add-local\"><label>Song <select class=\"dj-local-song\" aria-label=\"Song on this device\"></select></label><button type=\"button\" class=\"dj-save-local\">Add song</button><button type=\"button\" class=\"dj-import-simple\">Import audio</button></div></details>';root.prepend(playlistView);\r\n const DECKS=['a','b'];\r\n const sourceChoices=getDJSourceChoices(),savedDeckSources=recall('myr5.actualDJ.deckSources',{}),deckSources={a:'local',b:'local'};\r\n for(const id of DECKS)if(sourceChoices.some(source=>source.id===savedDeckSources?.[id]))deckSources[id]=savedDeckSources[id];\r\n const localDeck=id=>deckSources[id]==='local',bothLocal=()=>DECKS.every(localDeck);\r\n for(const id of DECKS){\r\n  const d=el('section','dj-deck');d.dataset.deck=id;\r\n  d.innerHTML=`<div class=\"dj-heading\"><span class=\"sp-label\">DECK ${id.toUpperCase()}</span><span class=\"dj-deck-source\">MYR5 AUDIO</span></div><button type=\"button\" class=\"dj-record\" data-control=\"toggle\" aria-label=\"Play deck ${id.toUpperCase()}\"><span>${id.toUpperCase()}</span></button><strong class=\"dj-title\">Load a track</strong><span class=\"dj-artist\">Your music, your room.</span><label class=\"dj-seek-wrap\"><input type=\"range\" class=\"dj-seek\" aria-label=\"Seek deck ${id.toUpperCase()}\" min=\"0\" max=\"1\" step=\"0.05\" value=\"0\"><span class=\"dj-time\">0:00 / 0:00</span></label><div class=\"dj-deck-controls\"><button type=\"button\" data-control=\"toggle\" class=\"dj-play\">PLAY</button><button type=\"button\" data-control=\"cue\">CUE</button><button type=\"button\" data-control=\"sync\">SYNC</button></div><div class=\"dj-tempo\"><label>BPM <input class=\"dj-bpm\" aria-label=\"Deck ${id.toUpperCase()} BPM\" type=\"number\" min=\"40\" max=\"240\" step=\"0.01\" placeholder=\"Tap / enter\"></label><button type=\"button\" data-control=\"tap\">TAP</button></div><label class=\"dj-rate-label\">PITCH <input class=\"dj-rate\" aria-label=\"Deck ${id.toUpperCase()} speed\" type=\"range\" min=\"0.75\" max=\"1.25\" step=\"0.005\" value=\"1\"><output>0%</output></label><div class=\"dj-eq\">${['low','mid','high'].map(b=>`<label>${b.toUpperCase()}<input type=\"range\" data-eq=\"${b}\" aria-label=\"Deck ${id.toUpperCase()} ${b} EQ\" min=\"-24\" max=\"12\" step=\"1\" value=\"0\"></label>`).join('')}</div><label class=\"dj-loop-label\">LOOP <select class=\"dj-loop\" aria-label=\"Deck ${id.toUpperCase()} loop\"><option value=\"0\">Off</option><option value=\"4\">4 beats</option><option value=\"8\">8 beats</option><option value=\"16\">16 beats</option></select></label>`;\r\n  $('.dj-decks').append(d);\r\n  const label=el('label','dj-source-choice','SOURCE '),select=el('select');select.dataset.deckSourceSelect=id;select.setAttribute('aria-label',`Deck ${id.toUpperCase()} music source`);\r\n  for(const source of sourceChoices){const option=el('option','',source.name);option.value=source.id;select.append(option);}select.value=deckSources[id];label.append(select);d.querySelector('.dj-heading').after(label);\r\n  const open=el('button','dj-deck-source-open','OPEN SOURCE ↗');open.type='button';open.addEventListener('click',()=>{const selected=deckSources[id];if(selected!=='spotify'&&(spotifyPlaying||handoffBusy)){if(!handoffBusy)void prepareLocal();say('PAUSE SPOTIFY / TAP OPEN SOURCE AGAIN');return;}if(selected==='spotify')switchView('spotify');else{switchView('providers');selectProvider(selected);}});label.after(open);\r\n  select.addEventListener('change',()=>selectDeckSource(id,select.value));\r\n }\r\n const dk=id=>root.querySelector(`[data-deck=\"${id}\"]`);\r\n function render(state){\r\n  if(disposed)return;\r\n  for(const id of DECKS){const d=dk(id),isLocal=localDeck(id),s=isLocal?state.decks[id]:{...state.decks[id],track:null,playing:false,position:0,duration:0,bpm:null,rate:1,loopBeats:0};d.classList.toggle('dj-playing',s.playing);d.querySelector('.dj-title').textContent=s.track?.title||'Load a track';d.querySelector('.dj-artist').textContent=s.track?.artist||'Your music, your room.';d.querySelector('.dj-deck-source').textContent=s.track?.local?'LOCAL FILE':'MYR5 AUDIO';\r\n   const source=sourceChoices.find(source=>source.id===deckSources[id]);d.querySelector('.dj-deck-source-open').hidden=isLocal;\r\n   for(const control of d.querySelectorAll('[data-control],.dj-seek,.dj-bpm,.dj-rate,[data-eq],.dj-loop'))control.disabled=!isLocal;\r\n   for(const input of d.querySelectorAll('[data-eq]'))if(document.activeElement!==input)input.value=isLocal?s.eq[input.dataset.eq]:0;\r\n   if(!isLocal){d.querySelector('.dj-title').textContent=source.name;d.querySelector('.dj-artist').textContent=source.id==='apple'?'Previews in Apple’s player · open app for full playback':'Playback in the original app';d.querySelector('.dj-deck-source').textContent='SOURCE LINK';}\r\n   d.querySelector('.dj-play').textContent=s.playing?'PAUSE':'PLAY';d.querySelector('.dj-record').setAttribute('aria-label',`${s.playing?'Pause':'Play'} deck ${id.toUpperCase()}`);\r\n   const seek=d.querySelector('.dj-seek');seek.max=Math.max(1,s.duration||1);if(document.activeElement!==seek)seek.value=s.position||0;d.querySelector('.dj-time').textContent=`${time(s.position)} / ${time(s.duration)}`;\r\n   const bpm=d.querySelector('.dj-bpm');if(document.activeElement!==bpm)bpm.value=s.bpm||'';\r\n   d.querySelector('.dj-rate-label output').textContent=`${Math.round((s.rate-1)*100)}%`;if(document.activeElement!==d.querySelector('.dj-rate'))d.querySelector('.dj-rate').value=s.rate;\r\n   d.querySelector('.dj-loop').value=s.loopBeats||0;\r\n  }\r\n  if(document.activeElement!==$('.dj-crossfader'))$('.dj-crossfader').value=state.crossfader;\r\n  $('.dj-transition').textContent=state.mixing?'MIXING…':`MIX TO ${state.crossfader<.5?'B':'A'} ↗`;\r\n  $('.dj-transition').disabled=state.mixing||!bothLocal();$('.dj-crossfader').disabled=!bothLocal();autoButton.disabled=!tracks.length||!bothLocal();\r\n  renderPlaylistState(state);\r\n  if(auto&&bothLocal()&&!autoBusy&&dialog.open&&view!=='providers'&&view!=='spotify'){\r\n   const active=state.crossfader<.5?'a':'b',s=state.decks[active],other=active==='a'?'b':'a';\r\n   if(s.playing&&s.duration>0&&s.duration-s.position<=Math.min(Number($('.dj-fade').value),s.duration*.4)&&queue.length&&state.decks[other].track&&!state.mixing){void mix(true);}\r\n  }\r\n }\r\n engine=createDJEngine({onChange:render,onError:e=>say(e?.message||String(e))});\r\n engine.setMaster(.75);engine.setCrossfader(0);\r\n visualizer=createDJVisualizer($('.dj-visual-canvas'),{getAnalyser:()=>engine.getAnalyser(),onStatus:message=>{$('.dj-visual-status').textContent=message;}});\r\n const djHand=createDJHand(dialog,{getState:()=>engine.snapshot()});\r\n function selectDeckSource(id,source){if(!sourceChoices.some(choice=>choice.id===source))return false;if(spotifyPlaying||handoffBusy){dk(id).querySelector('[data-deck-source-select]').value=deckSources[id];if(!handoffBusy)void prepareLocal();say('PAUSE SPOTIFY / CHOOSE SOURCE AGAIN');return false;}revision++;setAuto(false);deckSources[id]=source;remember('myr5.actualDJ.deckSources',deckSources);dk(id).querySelector('[data-deck-source-select]').value=source;DECKS.forEach(deck=>engine.pause(deck));stopProvider();if(localDeck(id)&&!engine.snapshot().decks[id].track&&tracks.length)engine.load(id,tracks[id==='a'?0:1]||tracks[0]);if(localDeck('a')&&!localDeck('b'))engine.setCrossfader(0);if(localDeck('b')&&!localDeck('a'))engine.setCrossfader(1);render(engine.snapshot());say(bothLocal()?'LOCAL DECKS READY':`${sourceChoices.find(choice=>choice.id===source).name.toUpperCase()} / OPEN SOURCE FOR PLAYBACK`);}\r\n const storedSourceLinks=recall('myr5.actualDJ.sourceLinks',[]);\r\n let sourceLinks=Array.isArray(storedSourceLinks)?storedSourceLinks.slice(0,50).map(entry=>{const normalized=normalizeProviderSourceEntry(entry?.provider,entry?.sourceUrl,entry?.label);return normalized?{...normalized,playlistId:typeof entry.playlistId==='string'&&entry.playlistId.length<=100?entry.playlistId:crypto.randomUUID()}:null;}).filter(Boolean):[];\r\n sourceLinks=assignPlaylistIds(sourceLinks);remember('myr5.actualDJ.sourceLinks',sourceLinks);\r\n const linksSection=el('section','dj-library dj-source-links');linksSection.innerHTML='<span class=\"sp-label\">SOURCE LINK PLAYLIST</span><p class=\"dj-library-status\">Your links keep their original music app. Open each source manually; Auto DJ uses your local crate.</p><form class=\"dj-link-form\"><label>APP <select id=\"djLinkProvider\" aria-label=\"Source link music app\"></select></label><label>NAME <input id=\"djLinkLabel\" maxlength=\"120\" required placeholder=\"Your track or playlist name\"></label><label>LINK <input id=\"djLinkUrl\" type=\"url\" maxlength=\"2048\" required placeholder=\"Original music app link\"></label><button type=\"submit\">+ SAVE SOURCE LINK</button></form><p class=\"dj-link-status\" role=\"status\"></p><ol class=\"dj-link-list\"></ol>';\r\n $('.dj-queue-section').after(linksSection);const linkProvider=linksSection.querySelector('#djLinkProvider'),linkStatus=linksSection.querySelector('.dj-link-status');\r\n for(const choice of sourceChoices.filter(choice=>choice.id!=='local')){const option=el('option','',choice.name);option.value=choice.id;linkProvider.append(option);}\r\n function saveSourceLinks(){remember('myr5.actualDJ.sourceLinks',sourceLinks);renderSourceLinks();syncPlaylist();}\r\n function renderSourceLinks(){const list=linksSection.querySelector('.dj-link-list');list.replaceChildren();sourceLinks.forEach((entry,index)=>{const row=el('li','dj-source-row'),info=el('div','dj-crate-info'),original=el('a','dj-original-source',entry.attribution.provider+' · original link');original.setAttribute('href',entry.sourceUrl);original.target='_blank';original.rel='noopener noreferrer';info.append(el('strong','',entry.label),original);original.addEventListener('click',event=>{if(spotifyPlaying||handoffBusy){event.preventDefault();if(!handoffBusy)void prepareLocal();linkStatus.textContent='Pause Spotify, then open the original source again.';return;}revision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));stopProvider();});const open=el('button','','OPEN'),remove=el('button','','×');open.type=remove.type='button';open.dataset.sourceOpen=index;remove.dataset.sourceRemove=index;remove.setAttribute('aria-label',`Remove source link ${entry.label}`);row.append(info,open,remove);list.append(row);});if(!sourceLinks.length)list.append(el('li','dj-empty','Save an Apple Music, Spotify or other original source link.'));}\r\n linksSection.querySelector('.dj-link-form').addEventListener('submit',event=>{event.preventDefault();const label=addForm.querySelector('#djLinkLabel'),url=addForm.querySelector('#djLinkUrl'),entry=normalizeProviderSourceEntry(linkProvider.value,url.value,label.value.trim()||sourceChoices.find(choice=>choice.id===linkProvider.value).name+' link');if(!entry){linkStatus.textContent='Use a valid link from the selected music app.';return;}if(sourceLinks.length>=50){linkStatus.textContent='This playlist holds 50 links. Remove one to add another.';return;}sourceLinks.push({...entry,playlistId:crypto.randomUUID()});saveSourceLinks();linkStatus.textContent=`Saved ${entry.label} · ${entry.attribution.provider}`;label.value='';url.value='';playlistView.querySelector('.dj-add-music').open=false;});\r\n linksSection.addEventListener('click',event=>{const remove=event.target.closest('[data-source-remove]'),open=event.target.closest('[data-source-open]');if(remove){sourceLinks.splice(Number(remove.dataset.sourceRemove),1);saveSourceLinks();return;}if(!open)return;const entry=sourceLinks[Number(open.dataset.sourceOpen)];if(!entry)return;if(spotifyPlaying||handoffBusy){if(!handoffBusy)void prepareLocal();linkStatus.textContent='Pause Spotify, then tap OPEN again.';return;}switchView('providers');selectProvider(entry.provider);$('#djSourceUrl').value=entry.sourceUrl;$('.dj-source-form').requestSubmit();});renderSourceLinks();\r\n\r\n const addSource=playlistView.querySelector('.dj-add-source'),addLocal=playlistView.querySelector('.dj-add-local'),addForm=linksSection.querySelector('.dj-link-form');\r\n for(const choice of sourceChoices){const option=el('option','',choice.id==='local'?'On this device':choice.name);option.value=choice.id;addSource.append(option);}\r\n playlistView.querySelector('.dj-heading').after(playlistView.querySelector('.dj-add-music'));playlistView.querySelector('.dj-add-music').append(addForm,linkStatus);addForm.hidden=true;addForm.querySelector('label').hidden=true;addForm.querySelector('#djLinkLabel').required=false;addForm.querySelector('#djLinkLabel').placeholder='Name (optional)';addForm.querySelector('button').textContent='Add link';linksSection.hidden=true;\r\n addSource.addEventListener('change',()=>{const local=addSource.value==='local';addLocal.hidden=!local;addForm.hidden=local;if(!local)linkProvider.value=addSource.value;linkStatus.textContent='';});\r\n playlistView.querySelector('.dj-save-local').addEventListener('click',()=>{const track=tracks.find(track=>track.id===playlistView.querySelector('.dj-local-song').value);if(track){queue.push(track);saveQueue();playlistView.querySelector('.dj-playlist-status').textContent=`Added ${track.title}`;playlistView.querySelector('.dj-add-music').open=false;}});\r\n playlistView.querySelector('.dj-import-simple').addEventListener('click',()=>$('.dj-files').click());\r\n function refreshPlaylistSongs(){const select=playlistView.querySelector('.dj-local-song');select.replaceChildren();for(const track of tracks){const option=el('option','',track.title);option.value=track.id;select.append(option);}playlistView.querySelector('.dj-save-local').disabled=!tracks.length;}\r\n function playlistItem(ref){if(!ref)return null;return ref?.kind==='local'?queue.find(track=>track.id===ref.trackId):sourceLinks.find(entry=>entry.playlistId===ref?.sourceId);}\r\n function syncPlaylist(){if(!playlistReady)return;playlistOrder=reconcilePlaylist(playlistOrder,queue,sourceLinks);remember('myr5.actualDJ.playlistOrder',playlistOrder);if(!playlistOrder.some(ref=>ref.id===selectedPlaylistId))selectedPlaylistId=playlistOrder[0]?.id||null;renderPlaylistRows();renderPlaylistState(engine.snapshot());}\r\n function handoffPlaylist(){if(spotifyPlaying||handoffBusy){if(!handoffBusy)void prepareLocal();playlistView.querySelector('.dj-playlist-status').textContent='Pause Spotify, then try again.';return false;}revision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));stopProvider();return true;}\r\n function renderPlaylistRows(){const list=playlistView.querySelector('.dj-playlist-list');list.replaceChildren();playlistView.querySelector('.dj-playlist-count').textContent=`${playlistOrder.length} saved`;for(const ref of playlistOrder){const entry=playlistItem(ref);if(!entry)continue;const row=el('li','dj-playlist-row');row.dataset.playlistId=ref.id;row.setAttribute('aria-current',String(ref.id===selectedPlaylistId));const info=el('div','dj-crate-info'),name=entry.title||entry.label;info.append(el('strong','',name),el('small','dj-provider-badge',ref.kind==='local'?'On this device':entry.attribution.provider));if(ref.kind!=='local'){const original=el('a','dj-original-source','Original link ↗');original.href=entry.sourceUrl;original.target='_blank';original.rel='noopener noreferrer';original.addEventListener('click',event=>{if(!handoffPlaylist())event.preventDefault();});info.append(original);}row.append(info);const actions=el('div','dj-playlist-actions');for(const [action,label] of [['play',ref.kind==='local'?'Play':`Open in ${entry.attribution.provider}`],['up','↑'],['down','↓'],['remove','×']]){const button=el('button','',label);button.type='button';button.dataset.playlistAction=action;button.setAttribute('aria-label',`${action==='up'?'Move up':action==='down'?'Move down':action==='remove'?'Remove':label} ${name}`);button.disabled=action==='up'&&ref===playlistOrder[0]||action==='down'&&ref===playlistOrder.at(-1);actions.append(button);}row.append(actions);list.append(row);}if(!playlistOrder.length)list.append(el('li','dj-empty','Your playlist is empty. Add music below.'));playlistView.querySelector('.dj-playlist-status').textContent='Links open in their music app.';}\r\n function renderPlaylistState(state){if(!playlistReady)return;const ref=playlistOrder.find(ref=>ref.id===selectedPlaylistId),entry=playlistItem(ref),deck=state.decks.a,playing=ref?.kind==='local'&&deck.track?.id===entry?.id&&deck.playing;playlistView.querySelector('.dj-current-title').textContent=entry?.title||entry?.label||'Choose a song';playlistView.querySelector('.dj-current-source').textContent=entry?(ref.kind==='local'?`${playing?'Playing':'On this device'} · ${time(deck.track?.id===entry.id?deck.position:0)}`:`Selected · ${entry.attribution.provider}`):'';const play=playlistView.querySelector('.dj-current-play');play.textContent=entry?(ref.kind==='local'?(playing?'Pause':'Play'):`Open in ${entry.attribution.provider}`):'Play';play.disabled=!entry||playlistBusy;const index=playlistOrder.findIndex(ref=>ref.id===selectedPlaylistId),next=playlistItem(playlistOrder[index+1]);playlistView.querySelector('.dj-next-title').textContent=next?`Next: ${next.title||next.label}`:'';playlistView.querySelector('.dj-next-item').disabled=!next;for(const row of playlistView.querySelectorAll('[data-playlist-id]'))row.setAttribute('aria-current',String(row.dataset.playlistId===selectedPlaylistId));}\r\n async function playPlaylist(id){const ref=playlistOrder.find(ref=>ref.id===id),entry=playlistItem(ref);if(!entry||playlistBusy)return;const state=engine.snapshot();if(ref.kind==='local'&&selectedPlaylistId===id&&state.decks.a.track?.id===entry.id&&state.decks.a.playing){handoffPlaylist();return;}if(!handoffPlaylist())return;selectedPlaylistId=id;renderPlaylistState(engine.snapshot());if(ref.kind==='source-link'){switchView('providers');selectProvider(entry.provider);$('#djSourceUrl').value=entry.sourceUrl;$('.dj-source-form').requestSubmit();return;}if(!localDeck('a'))selectDeckSource('a','local');engine.setCrossfader(0);engine.setLoop('a',0);if(engine.snapshot().decks.a.track?.id!==entry.id)engine.load('a',entry);else if(state.decks.a.duration&&state.decks.a.position>=state.decks.a.duration-.05)engine.seek('a',0);const mine=revision;playlistBusy=true;try{const ok=await engine.play('a');if(mine===revision&&!disposed)playlistView.querySelector('.dj-playlist-status').textContent=ok?'':'Tap Play to retry.';}finally{playlistBusy=false;if(!disposed)renderPlaylistState(engine.snapshot());}}\r\n function savePlaylistOrder(){queue=playlistOrder.filter(ref=>ref.kind==='local').map(ref=>playlistItem(ref)).filter(Boolean);sourceLinks=playlistOrder.filter(ref=>ref.kind==='source-link').map(ref=>playlistItem(ref)).filter(Boolean);remember('myr5.actualDJ.queue',queue.map(track=>track.id));remember('myr5.actualDJ.sourceLinks',sourceLinks);remember('myr5.actualDJ.playlistOrder',playlistOrder);renderQueue();renderSourceLinks();renderPlaylistRows();renderPlaylistState(engine.snapshot());}\r\n playlistView.querySelector('.dj-playlist-list').addEventListener('click',event=>{const button=event.target.closest('[data-playlist-action]'),row=button?.closest('[data-playlist-id]');if(!row)return;const id=row.dataset.playlistId,action=button.dataset.playlistAction;if(action==='play'){void playPlaylist(id);return;}if(action==='remove'){if(selectedPlaylistId===id){if(!handoffPlaylist())return;selectedPlaylistId=null;}const ref=playlistOrder.find(ref=>ref.id===id);if(ref?.kind==='local'){const index=playlistOrder.filter(ref=>ref.kind==='local').findIndex(ref=>ref.id===id);queue.splice(index,1);}else sourceLinks=sourceLinks.filter(entry=>entry.playlistId!==ref?.sourceId);playlistOrder=playlistOrder.filter(ref=>ref.id!==id);if(!selectedPlaylistId)selectedPlaylistId=playlistOrder[0]?.id||null;}else playlistOrder=movePlaylistItem(playlistOrder,id,action==='up'?-1:1);savePlaylistOrder();if(action==='up'||action==='down'){const moved=playlistView.querySelector(`[data-playlist-id=\"${CSS.escape(id)}\"]`),focus=moved?.querySelector(`[data-playlist-action=${action}]:not(:disabled)`)||moved?.querySelector('[data-playlist-action=play]');focus?.focus({preventScroll:true});}});\r\n playlistView.querySelector('.dj-current-play').addEventListener('click',()=>void playPlaylist(selectedPlaylistId));playlistView.querySelector('.dj-next-item').addEventListener('click',()=>{const index=playlistOrder.findIndex(ref=>ref.id===selectedPlaylistId),next=playlistOrder[index+1];if(next&&handoffPlaylist()){selectedPlaylistId=next.id;renderPlaylistState(engine.snapshot());}});\r\n function saveQueue(){remember('myr5.actualDJ.queue',queue.map(t=>t.id));renderQueue();syncPlaylist();}\r\n function renderQueue(){const list=$('.dj-queue');list.replaceChildren();queue.forEach((track,i)=>{const row=el('li','dj-queue-row');row.append(el('span','',`${i+1}. ${track.title}`));const remove=el('button','','×');remove.type='button';remove.dataset.remove=i;remove.setAttribute('aria-label',`Remove ${track.title} from queue`);row.append(remove);list.append(row);});if(!queue.length)list.append(el('li','dj-empty','Add tracks from your crate.'));}\r\n function renderLibrary(){const list=$('.dj-track-list'),q=$('.dj-filter').value.trim().toLowerCase();list.replaceChildren();for(const t of tracks.filter(t=>`${t.title} ${t.artist}`.toLowerCase().includes(q))){const row=el('li','dj-crate-row');row.dataset.track=t.id;const info=el('div','dj-crate-info');info.append(el('strong','',t.title),el('small','',`${t.artist||'Local audio'} · ${t.local?'LOCAL':`${t.bpm||'—'} BPM`}`));row.append(info);for(const [action,label] of [['a','A'],['b','B'],['queue','+']]){const b=el('button','',label);b.type='button';b.dataset.load=action;b.setAttribute('aria-label',action==='queue'?`Queue ${t.title}`:`Load ${t.title} on deck ${action.toUpperCase()}`);row.append(b);}if(t.local){const remove=el('button','','×');remove.type='button';remove.dataset.load='remove';remove.setAttribute('aria-label',`Delete local ${t.title}`);row.append(remove);}list.append(row);}if(!list.children.length)list.append(el('li','dj-empty','No matching music. Import audio to add it here.'));}\r\n const ready=(async()=>{try{tracks=await library.list();if(disposed)return;const saved=recall('myr5.actualDJ.queue',[]);queue=Array.isArray(saved)?saved.map(id=>tracks.find(t=>t.id===id)).filter(Boolean):[];renderLibrary();renderQueue();playlistReady=true;syncPlaylist();refreshPlaylistSongs();if(tracks[0]&&localDeck('a'))engine.load('a',tracks[0]);if(tracks[1]&&localDeck('b'))engine.load('b',tracks[1]);render(engine.snapshot());}catch(e){if(!disposed)say(e.message);}})();\r\n const setAuto=value=>{auto=value;if(!value)autoRevision++;autoButton.textContent=auto?'STOP AUTO DJ ■':'START AUTO DJ ▶';autoButton.setAttribute('aria-pressed',String(auto));};\r\n function prepareNext(id){if(!queue[0])return;engine.pause(id);if(engine.snapshot().decks[id].track?.id!==queue[0].id)engine.load(id,queue[0]);else engine.seek(id,0);}\r\n async function startAuto(){\r\n  if(!bothLocal()){say('CHOOSE MYR5 CRATE ON BOTH DECKS FOR AUTO DJ');return false;}\r\n  if(disposed||!dialog.open||handoffBusy)return false;\r\n  if(autoBusy){say('MIX FINISHING / START AUTO DJ AGAIN');return false;}\r\n  if(spotifyPlaying){void prepareLocal();return false;}\r\n  const initial=engine.snapshot(),out=initial.crossfader<.5?'a':'b',incoming=out==='a'?'b':'a';\r\n  if(!initial.decks[out].track){const first=queue.shift()||tracks[0];if(!first){say('IMPORT AUDIO TO START AUTO DJ');return false;}engine.load(out,first);}\r\n  const active=engine.snapshot().decks[out];\r\n  if(!queue.length)queue=tracks.filter(t=>t.id!==active.track.id);\r\n  setAuto(true);autoBusy=true;autoStarting=true;const run=autoRevision,mine=revision;\r\n  try{\r\n   stopProvider();engine.setCrossfader(out==='a'?0:1);DECKS.forEach(id=>engine.setLoop(id,0));\r\n   prepareNext(incoming);saveQueue();\r\n   if(active.duration&&active.position>=active.duration-.05)engine.seek(out,0);\r\n   // Prime both existing media elements before yielding, keeping the start tap's audio activation.\r\n   const starts=[engine.play(out)];if(queue.length)starts.push(engine.play(incoming));\r\n   const started=await Promise.all(starts);\r\n   if(disposed||mine!==revision||run!==autoRevision||!dialog.open)return false;\r\n   if(queue.length)engine.pause(incoming);\r\n   if(started.some(ok=>!ok)){setAuto(false);say('AUTO DJ PAUSED / TAP START TO RETRY');return false;}\r\n   if(!queue.length){setAuto(false);say('LAST TRACK / AUTO DJ FINISHED');}else say('AUTO DJ PLAYING / QUEUE READY');\r\n   return true;\r\n  }catch(e){if(!disposed&&mine===revision){setAuto(false);say(e.message);}return false;}\r\n  finally{autoBusy=false;autoStarting=false;}\r\n }\r\n function stopAuto(){const state=engine.snapshot();setAuto(false);if(autoStarting)engine.pause(state.crossfader<.5?'b':'a');say(state.mixing?'FINISHING CURRENT MIX / AUTO DJ OFF':'AUTO DJ STOPPED / MANUAL MIX');}\r\n async function mix(automatic=false){\r\n  if(!bothLocal()){say('SOURCE LINKS USE THEIR ORIGINAL PLAYER / CHOOSE LOCAL DECKS TO MIX');return false;}\r\n  if(autoBusy||disposed||!dialog.open)return;autoBusy=true;\r\n  if(automatic){const state=engine.snapshot();prepareNext(state.crossfader<.5?'b':'a');}\r\n  const initial=engine.snapshot(),out=initial.crossfader<.5?'a':'b',incoming=out==='a'?'b':'a',mine=revision,run=autoRevision;\r\n  const incomingTrack=initial.decks[incoming].track?.id;\r\n  const selectedFade=Number($('.dj-fade').value),remaining=initial.decks[out].duration-initial.decks[out].position;\r\n  const fade=automatic?Math.max(.1,Math.min(selectedFade,initial.decks[out].duration*.4,remaining)):selectedFade;\r\n  try{\r\n   const ok=await engine.transition(fade);\r\n   if(disposed||mine!==revision||!dialog.open)return;\r\n   if(ok){\r\n    engine.pause(out);\r\n    if(automatic&&queue[0]?.id===incomingTrack){queue.shift();saveQueue();}\r\n    if(auto&&run===autoRevision){if(queue.length)prepareNext(out);else setAuto(false);}\r\n    say(automatic&&!auto?(queue.length?'AUTO DJ STOPPED / MANUAL MIX':'LAST TRACK / AUTO DJ FINISHED'):'MIX COMPLETE');\r\n   }else if(automatic&&auto&&run===autoRevision){setAuto(false);say('AUTO DJ PAUSED / TAP START TO RETRY');}\r\n  }catch(e){if(!disposed&&mine===revision){if(automatic&&auto&&run===autoRevision)setAuto(false);say(e.message);}}\r\n  finally{autoBusy=false;}\r\n }\r\n const taps={a:[],b:[]};\r\n $('.dj-decks').addEventListener('click',async e=>{const b=e.target.closest('[data-control]'),d=b?.closest('[data-deck]');if(!d||handoffBusy||!localDeck(d.dataset.deck))return;const id=d.dataset.deck;if(b.dataset.control==='toggle'&&!engine.snapshot().decks[id].playing&&spotifyPlaying){void prepareLocal();return;}try{switch(b.dataset.control){case'toggle':if(auto)stopAuto();await engine.toggle(id);say('MANUAL DECK / AUTO DJ OFF');break;case'cue':engine.cue(id);break;case'sync':engine.sync(id);break;case'tap':{const now=performance.now();taps[id]=taps[id].filter(t=>now-t<4000).slice(-7);taps[id].push(now);if(taps[id].length>1){const bpm=60000*(taps[id].length-1)/(now-taps[id][0]);if(bpm>=40&&bpm<=240)engine.setBpm(id,Math.round(bpm*100)/100);}break;}}}catch(err){say(err.message);}});\r\n $('.dj-decks').addEventListener('input',e=>{const d=e.target.closest('[data-deck]');if(!d||!localDeck(d.dataset.deck))return;const id=d.dataset.deck,v=Number(e.target.value);try{if(e.target.matches('.dj-rate'))engine.setRate(id,v);if(e.target.dataset.eq)engine.setEQ(id,e.target.dataset.eq,v);}catch(err){say(err.message);}});\r\n $('.dj-decks').addEventListener('change',e=>{const d=e.target.closest('[data-deck]');if(!d||!localDeck(d.dataset.deck))return;const id=d.dataset.deck,v=Number(e.target.value);try{if(e.target.matches('.dj-seek'))engine.seek(id,v);if(e.target.matches('.dj-bpm'))engine.setBpm(id,v);if(e.target.matches('.dj-loop'))engine.setLoop(id,v);}catch(err){say(err.message);}});\r\n $('.dj-crossfader').addEventListener('input',e=>{if(auto)stopAuto();engine.setCrossfader(Number(e.target.value));say('MANUAL CROSSFADER / AUTO DJ OFF');});\r\n $('.dj-master').addEventListener('input',e=>engine.setMaster(Number(e.target.value)));\r\n $('.dj-transition').addEventListener('click',()=>{if(handoffBusy)return;if(spotifyPlaying){void prepareLocal();return;}void mix(auto);});\r\n autoButton.addEventListener('click',()=>{if(auto)stopAuto();else void startAuto();});\r\n const commandForm=el('form','dj-command-form'),commandLabel=el('label','','DECK COMMANDS'),commandRow=el('div'),commandInput=el('input'),commandSubmit=el('button','','RUN'),commandStatus=el('p','dj-library-status','Try “start auto dj”, “mix next”, “fade 4 seconds” or “pause deck A”.');\r\n commandInput.id='djDeckCommand';commandInput.type='text';commandInput.maxLength=80;commandInput.placeholder='Tell the local decks what to do…';commandInput.autocomplete='off';commandInput.required=true;\r\n commandLabel.htmlFor=commandInput.id;commandSubmit.type='submit';commandStatus.setAttribute('role','status');commandRow.style.display='flex';commandRow.style.gap='8px';commandInput.style.flex='1';commandInput.style.minWidth='0';commandInput.style.width='100%';\r\n commandRow.append(commandInput,commandSubmit);commandForm.append(commandLabel,commandRow,commandStatus);$('.dj-mixer').after(commandForm);\r\n commandForm.addEventListener('submit',async event=>{\r\n  event.preventDefault();if(disposed||!dialog.open||handoffBusy)return;\r\n  const command=parseDJCommand(commandInput.value);\r\n  if(!command){commandStatus.textContent='Use a deck command: start/stop auto dj, mix next, fade 4/8/16 seconds, or play/pause deck A/B.';return;}\r\n  if((command.action==='automix'&&command.enabled||command.action==='mix-next'||command.control==='play')&&spotifyPlaying){void prepareLocal();commandStatus.textContent='Pause Spotify first, then run your deck command again.';return;}\r\n  const mine=revision;\r\n  try{\r\n   let ok=true;\r\n   switch(command.action){\r\n    case'automix':if(command.enabled)ok=await startAuto();else stopAuto();break;\r\n    case'mix-next':ok=(await mix(auto))!==false;break;\r\n    case'fade':$('.dj-fade').value=String(command.seconds);break;\r\n    case'deck-control':if(!localDeck(command.deck)){ok=false;say('OPEN THE SELECTED SOURCE FOR PLAYBACK');break;}if(auto)stopAuto();if(command.control==='play')ok=await engine.play(command.deck);else engine.pause(command.deck);say('MANUAL DECK / AUTO DJ OFF');break;\r\n   }\r\n   if(!disposed&&mine===revision&&dialog.open)commandStatus.textContent=ok?`Done: ${commandInput.value.trim()}`:'Playback paused. Tap Start Auto DJ or Play to retry.';\r\n  }catch(error){if(!disposed&&mine===revision&&dialog.open)commandStatus.textContent=error.message;}\r\n });\r\n $('.dj-filter').addEventListener('input',renderLibrary);\r\n $('.dj-files').addEventListener('change',async e=>{try{await library.importFiles(e.target.files);tracks=await library.list();renderLibrary();refreshPlaylistSongs();}catch(err){$('.dj-library-status').textContent=err.message;}finally{e.target.value='';}});\r\n $('.dj-track-list').addEventListener('click',async e=>{const b=e.target.closest('[data-load]'),row=b?.closest('[data-track]');if(!row)return;const t=tracks.find(t=>t.id===row.dataset.track);if(!t)return;try{if(b.dataset.load==='queue'){queue.push(t);saveQueue();say('ADDED TO QUEUE');}else if(b.dataset.load==='remove'){if(auto)stopAuto();for(const id of DECKS)if(engine.snapshot().decks[id].track?.id===t.id){engine.pause(id);engine.load(id,null);}await library.remove(t.id);tracks=await library.list();queue=queue.filter(q=>q.id!==t.id);saveQueue();renderLibrary();}else{if(!localDeck(b.dataset.load)&&selectDeckSource(b.dataset.load,'local')===false)return;if(auto)stopAuto();engine.load(b.dataset.load,t);}}catch(err){say(err.message);}});\r\n $('.dj-clear-queue').addEventListener('click',()=>{if(auto)stopAuto();queue=[];saveQueue();});\r\n $('.dj-queue').addEventListener('click',e=>{const b=e.target.closest('[data-remove]');if(b){queue.splice(Number(b.dataset.remove),1);if(auto&&!queue.length)stopAuto();saveQueue();}});\r\n const savedValue=recall('myr5.actualDJ.sources',{}),savedLinks=savedValue&&typeof savedValue==='object'&&!Array.isArray(savedValue)?savedValue:{};\r\n function stopProvider(){$('.dj-source-player').replaceChildren();}\r\n function selectProvider(id){provider=id;stopProvider();const p=DJ_PROVIDERS.find(p=>p.id===id);for(const b of $('.dj-provider-grid').children)b.setAttribute('aria-pressed',String(b.dataset.provider===id));$('.dj-source-label').textContent=`${p.name} link`;$('#djSourceUrl').placeholder=p.hint;$('#djSourceUrl').value=typeof savedLinks?.[id]==='string'?savedLinks[id]:'';$('.dj-source-open').href=p.home;$('.dj-source-open').textContent=`OPEN ${p.name.toUpperCase()} ↗`;$('.dj-source-status').textContent=p.id==='apple'?'Apple Music previews play here. Open Apple Music for full playback.':`${p.name} · ${p.mode}. Paste a link to begin.`;}\r\n for(const p of DJ_PROVIDERS){const b=el('button','',p.name);b.type='button';b.dataset.provider=p.id;b.addEventListener('click',()=>selectProvider(p.id));$('.dj-provider-grid').append(b);}selectProvider('apple');\r\n $('.dj-source-form').addEventListener('submit',e=>{if(spotifyPlaying||handoffBusy){e.preventDefault();e.stopImmediatePropagation();if(!handoffBusy)void prepareLocal();}},true);\r\n $('.dj-source-form').addEventListener('submit',e=>{e.preventDefault();const link=providerLink(provider,$('#djSourceUrl').value);if(!link){$('.dj-source-status').textContent=`Use a valid ${DJ_PROVIDERS.find(p=>p.id===provider).name} music link.`;return;}revision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));stopProvider();savedLinks[provider]=link.url;remember('myr5.actualDJ.sources',savedLinks);$('.dj-source-open').href=link.url;if(link.embed){const iframe=el('iframe','dj-provider-frame');iframe.src=link.embed;iframe.title=`${link.name} official player`;iframe.allow='autoplay; encrypted-media; fullscreen; picture-in-picture';iframe.referrerPolicy='strict-origin-when-cross-origin';iframe.allowFullscreen=true;$('.dj-source-player').append(iframe);$('.dj-source-status').textContent=provider==='apple'?'Apple Music previews play here. Open Apple Music for full playback.':`SOURCE: ${link.name}. Availability and full playback are managed by ${link.name}.`;}else{$('.dj-source-status').textContent=`Saved ${link.name} link. Use OPEN ${link.name.toUpperCase()} to listen in the source app.`;}});\r\n $('.dj-source-open').addEventListener('click',event=>{if(spotifyPlaying||handoffBusy){event.preventDefault();if(!handoffBusy)void prepareLocal();$('.dj-source-status').textContent='Pause Spotify, then open the source app again.';return;}revision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));stopProvider();});\r\n const sceneNames={orbit:'Mindblob',tunnel:'Glass corridor',spectrum:'Thumb drum',scope:'Cubetrace',trails:'Music reactive paint'};\r\n for(const option of $('.dj-scene').options)option.textContent=sceneNames[option.value];\r\n $('.dj-palette').textContent='ALTERNATE LOOK ↻';\r\n const reactLabel=el('label','dj-react','REACT '),reactInput=el('input');reactInput.type='range';reactInput.min='.1';reactInput.max='3';reactInput.step='.1';reactInput.value='1';reactInput.setAttribute('aria-label','Visualizer audio reactivity');reactLabel.append(reactInput);$('.dj-visual-controls').after(reactLabel);reactInput.addEventListener('input',()=>visualizer.setReact(Number(reactInput.value)));\r\n $('.dj-scene').addEventListener('change',e=>visualizer.setScene(e.target.value));$('.dj-palette').addEventListener('click',()=>visualizer.setPalette(++preset%3));\r\n $('.dj-mix-source').addEventListener('click',()=>visualizer.useMix());$('.dj-mic').addEventListener('click',()=>void visualizer.microphone());\r\n $('.dj-fullscreen').addEventListener('click',async()=>{try{await $('.dj-visual-stage').requestFullscreen();}catch{$('.dj-visual-status').textContent='Fullscreen is unavailable here. The visualizer still runs in this view.';}});\r\n async function prepareLocal(){if(handoffBusy)return false;if(!spotifyPlaying)return true;handoffBusy=true;const mine=revision;say('PAUSING SPOTIFY…');const ok=await spotifyAction('pause',{});if(mine===revision&&dialog.open){if(ok)spotifyPlaying=false;say(ok?'SPOTIFY PAUSED / TAP PLAY':'PAUSE SPOTIFY ON ITS DEVICE FIRST');$('.dj-source-status').textContent=ok?'Spotify paused. Open your source player.':'Pause Spotify on its device before opening another player.';}handoffBusy=false;return ok;}\r\n function switchView(next){const previous=view;view=next;for(const v of [...root.querySelectorAll(':scope > .dj-view'),spotifyView])v.hidden=v.dataset.view!==next;for(const b of tabs.querySelectorAll('[data-view]'))b.setAttribute('aria-pressed',String(b.dataset.view===next));dialog.dataset.djView=next;djHand.setActive(dialog.open&&(next==='mix'||next==='playlist'));stopProvider();if(next==='providers'||next==='spotify'){revision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));}if(next!=='spotify'&&previous==='spotify')void prepareLocal();if(next==='visuals')visualizer.start();else visualizer.stop();}\r\n tabs.addEventListener('click',e=>{const b=e.target.closest('[data-view]');if(b)switchView(b.dataset.view);});\r\n // Expand the existing OAuth terminal rather than replacing its account handling.\r\n const spotifyExtra=el('section','dj-spotify-extra');spotifyExtra.innerHTML='<span class=\"sp-label\">SPOTIFY LIBRARY</span><form class=\"dj-spotify-search\"><label for=\"djSpotifySearch\">Search Spotify</label><div><input id=\"djSpotifySearch\" type=\"search\" maxlength=\"200\" placeholder=\"Artist or track…\" required><button>SEARCH</button></div></form><p class=\"dj-spotify-status\" role=\"status\"></p><ol class=\"dj-spotify-results\"></ol><div class=\"dj-spotify-device\"><button type=\"button\" class=\"dj-refresh-devices\">OUTPUT DEVICES</button><select class=\"dj-devices\" aria-label=\"Spotify playback device\"><option value=\"\">Choose device…</option></select></div><div class=\"dj-spotify-controls\"><button type=\"button\" class=\"dj-shuffle\" aria-pressed=\"false\">SHUFFLE OFF</button><label>REPEAT <select class=\"dj-repeat\"><option value=\"off\">Off</option><option value=\"context\">Playlist</option><option value=\"track\">Track</option></select></label></div><button class=\"dj-fetch-queue\" type=\"button\">SHOW SPOTIFY QUEUE</button><ol class=\"dj-spotify-queue\"></ol>';\r\n spotifyView.querySelector('.sp-playlists').before(spotifyExtra);\r\n const sp=s=>spotifyExtra.querySelector(s),spSay=message=>{sp('.dj-spotify-status').textContent=message;};let searchRevision=0,shuffle=false;\r\n function spotifyState(connected){spotifyExtra.hidden=!connected;if(!connected){spotifyPlaying=false;searchRevision++;sp('.dj-spotify-results').replaceChildren();sp('.dj-spotify-queue').replaceChildren();sp('.dj-devices').replaceChildren(el('option','','Choose device…'));sp('.dj-devices').firstChild.value='';sp('#djSpotifySearch').value='';sp('.dj-repeat').value='off';shuffle=false;sp('.dj-shuffle').textContent='SHUFFLE OFF';sp('.dj-shuffle').setAttribute('aria-pressed','false');spSay('');}}\r\n function spotifyRows(list,items,{queueOnly=false}={}){list.replaceChildren();for(const t of items){const row=el('li','dj-crate-row');row.append(el('strong','',`${t.name} — ${(t.artists||[]).join(', ')}`));if(t.url){const link=el('a','','↗');link.href=t.url;link.target='_blank';link.rel='noopener noreferrer';link.setAttribute('aria-label',`Open ${t.name} in Spotify`);row.append(link);}if(!queueOnly)for(const [action,label] of [['track','PLAY'],['queue','+']]){const b=el('button','',label);b.type='button';b.addEventListener('click',()=>void spotifyAction(action,{trackId:t.id}));row.append(b);}list.append(row);}if(!items.length)list.append(el('li','dj-empty','No tracks to show.'));}\r\n sp('.dj-spotify-search').addEventListener('submit',async e=>{e.preventDefault();const mine=++searchRevision;spSay('Searching Spotify…');try{const data=await spotifyJSON('/api/spotify/search?q='+encodeURIComponent(sp('#djSpotifySearch').value));if(mine!==searchRevision||!dialog.open)return;spotifyRows(sp('.dj-spotify-results'),data.items||[]);spSay(`${data.total||0} Spotify results`);}catch(err){if(mine===searchRevision&&dialog.open&&err.name!=='AbortError')spSay(err.message);}});\r\n sp('.dj-fetch-queue').addEventListener('click',async()=>{const mine=searchRevision;try{const data=await spotifyJSON('/api/spotify/queue');if(mine!==searchRevision||!dialog.open)return;spotifyRows(sp('.dj-spotify-queue'),data.items||[],{queueOnly:true});}catch(err){if(mine===searchRevision&&dialog.open&&err.name!=='AbortError')spSay(err.message);}});\r\n sp('.dj-refresh-devices').addEventListener('click',async()=>{const mine=searchRevision;try{const data=await spotifyJSON('/api/spotify/devices');if(mine!==searchRevision||!dialog.open)return;sp('.dj-devices').replaceChildren(el('option','','Choose device…'));sp('.dj-devices').firstChild.value='';for(const d of data.items||[]){const o=el('option','',`${d.name}${d.active?' · Active':''}`);o.value=d.id;o.disabled=d.restricted;sp('.dj-devices').append(o);}spSay(data.items?.length?'Choose a Spotify output.':'Open Spotify on a device first.');}catch(err){if(mine===searchRevision&&dialog.open&&err.name!=='AbortError')spSay(err.message);}});\r\n sp('.dj-devices').addEventListener('change',e=>{if(e.target.value)void spotifyAction('transfer',{deviceId:e.target.value});});sp('.dj-repeat').addEventListener('change',e=>void spotifyAction('repeat',{mode:e.target.value}));\r\n sp('.dj-shuffle').addEventListener('click',async()=>{const next=!shuffle;const ok=await spotifyAction('shuffle',{enabled:next});if(ok){shuffle=next;sp('.dj-shuffle').setAttribute('aria-pressed',String(shuffle));sp('.dj-shuffle').textContent=`SHUFFLE ${shuffle?'ON':'OFF'}`;}});\r\n function onOpen(){if(!dialog.open)return;window.dispatchEvent(new CustomEvent('myr5:dj-active',{detail:{active:true}}));const next=requestedView|| (new URLSearchParams(location.search).has('spotify')?'spotify':'playlist');requestedView=null;if(next==='playlist'){more.setAttribute('aria-expanded','false');for(const button of tabs.querySelectorAll('[data-view]:not([data-view=playlist])'))button.hidden=true;}switchView(next);}\r\n const observer=new MutationObserver(onOpen);observer.observe(dialog,{attributes:true,attributeFilter:['open']});\r\n const onClose=()=>{if(dialog.open&&!disposed)return;revision++;searchRevision++;setAuto(false);DECKS.forEach(id=>engine.pause(id));visualizer.stop();djHand.setActive(false);stopProvider();window.dispatchEvent(new CustomEvent('myr5:dj-active',{detail:{active:false}}));};dialog.addEventListener('close',onClose);\r\n switchView('playlist');\r\n return {spotifyState,spotifyPlaying(value){spotifyPlaying=!!value;},spotifyStarting(){revision++;DECKS.forEach(id=>engine.pause(id));setAuto(false);stopProvider();},showSpotify(){if(!dialog.open)requestedView='spotify';switchView('spotify');},dispose(){if(disposed)return;disposed=true;revision++;observer.disconnect();dialog.removeEventListener('close',onClose);onClose();engine.dispose();library.dispose();visualizer.dispose();djHand.dispose();tabs.remove();root.remove();}};\r\n}\r\n","app-updates.mjs":"import {createUpdateParticipant} from './update-session.mjs';\r\nimport {RELEASE} from './release-info.mjs';\r\nimport {safeToUpdate,releaseNotice,requestActivation} from './update-policy.mjs';\r\n\r\n// Release notes are optional; a slow or unavailable API must not block the\r\n// browser's independent check for a new service worker.\r\nexport async function checkUpdateSources(registration,loadNotes){\r\n const notes=Promise.resolve().then(loadNotes).then(()=>true,()=>false);\r\n if(registration){await registration.update();return;}\r\n if(!await notes)throw Error('Release information is unavailable.');\r\n}\r\n\r\n// Longer than the worker's own worst case (two 4 s replies + ACTIVATION_WAIT in sw.js).\r\nconst UPDATE_BARRIER_MS=25000;\r\nexport function initAppUpdates({api,applyButton,onRegistration,onBeforeUpdate}) {\r\n const panel=document.getElementById('installPanel'),section=document.createElement('details');\r\n section.className='release-settings';\r\n section.innerHTML='<summary>App updates</summary><p>Turn on notifications in Reminders to get a download alert for every new app update.</p><p id=\"releaseVersion\"></p><ul id=\"releaseNotes\"></ul><button id=\"checkAppUpdate\">Check for updates</button><p id=\"releaseStatus\" role=\"status\"></p><form id=\"releaseEmailForm\"><label>Email me when an update is ready<input name=\"email\" type=\"email\" autocomplete=\"email\" required maxlength=\"254\" placeholder=\"you@example.com\"></label><button type=\"submit\" disabled>Email me updates</button><button id=\"stopReleaseEmails\" type=\"button\" hidden>Stop update emails</button><p id=\"releaseEmailStatus\" role=\"status\">Optional. Confirm your email first; unsubscribe any time.</p></form>';\r\n panel.append(section);\r\n section.open=new URLSearchParams(location.search).has('update');\r\n const $=id=>document.getElementById(id),banner=document.createElement('aside');\r\n banner.className='app-update-banner';banner.setAttribute('role','status');banner.hidden=true;\r\n banner.innerHTML='<span>A Coach update is ready.</span><button type=\"button\" data-update>Update now</button><button type=\"button\" data-notes>What’s new</button><button type=\"button\" data-later aria-label=\"Dismiss update notice\">Later</button>';\r\n document.body.append(banner);\r\n let storage;try{storage=localStorage;}catch{}\r\n const notice=releaseNotice(storage,RELEASE.id);\r\n let reg=null,latest=RELEASE,applying=false,switched=false,dismissed=false,poll=0,error='',lastInteraction=Date.now(),retryAt=0,checking=false,notesRequest=null;\r\n const hadController=!!navigator.serviceWorker?.controller;\r\n const safe=(automatic=true,background=false)=>safeToUpdate({tracking:document.body.dataset.tracking==='true',rest:document.body.dataset.screen==='rest',dialog:!!document.querySelector('dialog[open]:not(#installPanel):not(#coachSetupGate):not(#coachUpdateBarrier)'),editing:!!document.activeElement?.matches('input,textarea,select,[contenteditable=true]'),hidden:document.hidden&&!background,online:navigator.onLine,lastInteraction,automatic});\r\n const ready=()=>!!reg?.waiting||switched||(!('serviceWorker' in navigator)&&latest.id!==RELEASE.id);\r\n function showNotes(r){$('releaseVersion').textContent=r.title+' · '+r.date;$('releaseNotes').replaceChildren(...r.notes.map(text=>{const li=document.createElement('li');li.textContent=text;return li;}));}\r\n function paint(){\r\n  // Under the update barrier (a modal) the banner's buttons can't be tapped, so it isn't shown there.\r\n  applyButton.hidden=!ready();banner.hidden=!!document.getElementById('coachUpdateBarrier')||(ready()?dismissed:!notice.visible);\r\n  banner.querySelector('span').textContent=ready()?error||'Coach will update when you are idle.':'Updated: '+RELEASE.title;\r\n  const b=banner.querySelector('[data-update]');b.hidden=!ready();b.disabled=!safe(false)||applying;applyButton.disabled=b.disabled;\r\n  b.textContent=!safe(false)?'Finish what you’re doing':applying?'Updating…':'Update now';\r\n  banner.querySelector('[data-later]').textContent=ready()?'Later':'Got it';\r\n  $('releaseStatus').textContent=error||(ready()?'Update downloaded. Coach will save and restart when you are idle.':latest.id!==RELEASE.id?'Downloading update…':'Automatic updates are on.');\r\n }\r\n async function apply(automatic=false){\r\n  if(!safe(automatic)||applying||!ready())return;\r\n  applying=true;error='';paint();\r\n  try{\r\n   if(reg?.waiting){await requestActivation(reg.waiting,{timeout:20000});return;}\r\n   await onBeforeUpdate?.();\r\n   if(!safe(automatic)){applying=false;paint();return;}\r\n   location.reload();\r\n  }catch(e){applying=false;retryAt=Date.now()+30000;error=e.message||'Save your progress before updating.';paint();}\r\n }\r\n const participant=createUpdateParticipant({\r\n  canPrepare:()=>safe(!applying,true),\r\n  acquire:()=>{const owner=window.myr5WorkoutOwner,lease=owner?.acquireIdleLease();return lease?()=>owner.releaseIdleLease(lease):null;},\r\n  save:async()=>{await onBeforeUpdate?.();if(!await window.myr5WorkoutOwner.save())throw Error('Progress could not be saved.');},\r\n  freeze:id=>{const barrier=document.createElement('dialog');barrier.id='coachUpdateBarrier';barrier.textContent='Saving and updating Coach…';barrier.addEventListener('cancel',event=>event.preventDefault());document.body.append(barrier);barrier.showModal();\r\n   // Never a trap: the worker can be stopped mid-update (iOS) or still be waiting on the old one. If the\r\n   // new worker took over without telling this page, reload into it; otherwise hand the app back with a retry.\r\n   const timer=setTimeout(async()=>{\r\n    await participant.message({type:'UPDATE_ABORT',id});\r\n    const r=await Promise.race([navigator.serviceWorker.getRegistration().catch(()=>null),new Promise(resolve=>setTimeout(()=>resolve(null),1000))]);if(r&&!r.waiting)return location.reload();\r\n    applying=false;dismissed=false;retryAt=Date.now()+60000;error='Coach couldn’t finish updating. Tap Update now to try again.';paint();\r\n   },UPDATE_BARRIER_MS);\r\n   return ()=>{clearTimeout(timer);barrier.remove();paint();};},\r\n  reload:()=>location.reload()\r\n });\r\n applyButton.onclick=()=>apply(false);banner.querySelector('[data-update]').onclick=()=>apply(false);\r\n banner.querySelector('[data-later]').onclick=()=>{if(ready())dismissed=true;else notice.dismiss();paint();};\r\n banner.querySelector('[data-notes]').onclick=()=>{notice.dismiss();if(!panel.open)panel.showModal();section.open=true;section.scrollIntoView({block:'start'});paint();};\r\n function openDownload(){if(!panel.open)panel.showModal();section.open=true;section.scrollIntoView({block:'start'});void check();}\r\n async function check(){\r\n  if(checking)return;checking=true;\r\n  try{\r\n   await checkUpdateSources(reg,()=>notesRequest??=(async()=>{\r\n    const value=await api('/api/releases/current');\r\n    if(typeof value?.id==='string'&&Array.isArray(value.notes)&&value.notes.every(n=>typeof n==='string')){if(latest.id!==value.id)dismissed=false;latest=value;showNotes(latest);paint();}\r\n   })().finally(()=>{notesRequest=null;}));\r\n   error='';paint();\r\n  }catch{error='Could not check for an update. Reconnect and try again.';paint();}finally{checking=false;}\r\n }\r\n $('checkAppUpdate').onclick=check;\r\n async function emailStatus(){\r\n  const form=$('releaseEmailForm'),button=form.querySelector('[type=submit]');\r\n  try{\r\n   const p=await api('/api/updates/subscription');button.disabled=!p.configured;\r\n   if(p.email&&!form.elements.email.value)form.elements.email.value=p.email;\r\n   $('stopReleaseEmails').hidden=!p.email;\r\n   $('releaseEmailStatus').textContent=p.enabled?'Release emails are on.':p.email?'Check your inbox to confirm release emails.':p.configured?'Optional. Confirm your email first; unsubscribe any time.':'Email delivery is being connected. In-app updates are available now.';\r\n  }catch{button.disabled=true;$('releaseEmailStatus').textContent='Sign in to choose email updates.';}\r\n }\r\n $('releaseEmailForm').onsubmit=async e=>{\r\n  e.preventDefault();const form=e.currentTarget,b=form.querySelector('[type=submit]');b.disabled=true;\r\n  try{const r=await api('/api/updates/subscription','POST',{email:form.elements.email.value});$('releaseEmailStatus').textContent=r.message;$('stopReleaseEmails').hidden=false;}\r\n  catch(error){$('releaseEmailStatus').textContent=error.message;}finally{b.disabled=false;}\r\n };\r\n $('stopReleaseEmails').onclick=async()=>{try{await api('/api/updates/subscription','DELETE',{});$('stopReleaseEmails').hidden=true;$('releaseEmailStatus').textContent='Update emails are off.';}catch(error){$('releaseEmailStatus').textContent=error.message;}};\r\n document.querySelectorAll('[data-panel=install]').forEach(b=>b.addEventListener('click',emailStatus));\r\n if('serviceWorker' in navigator){\r\n  navigator.serviceWorker.register('/sw.js',{updateViaCache:'none'}).then(value=>{\r\n   reg=value;onRegistration?.(reg);paint();\r\n   reg.addEventListener('updatefound',()=>{const w=reg.installing;w?.addEventListener('statechange',()=>{if(w.state==='installed'){dismissed=false;paint();}});});check();\r\n  }).catch(()=>{error='Updates could not initialize. Refresh Coach to retry.';paint();});\r\n  navigator.serviceWorker.addEventListener('controllerchange',()=>{\r\n   if(!hadController&&!applying&&!participant.prepared)return;\r\n   switched=true;if(participant.activated())return;\r\n   if(applying&&safe(false))location.reload();\r\n   else {applying=false;paint();}\r\n  });\r\n  navigator.serviceWorker.addEventListener('message',async event=>{\r\n   if(event.data?.type==='APP_UPDATE_AVAILABLE'){openDownload();event.ports[0]?.postMessage({handled:true});return;}\r\n   if(!['UPDATE_SAFETY_CHECK','UPDATE_CONFIRM','UPDATE_ABORT'].includes(event.data?.type))return;\r\n   const result=await participant.message(event.data);event.ports[0]?.postMessage(result);\r\n  });\r\n }else check();\r\n showNotes(RELEASE);paint();\r\n const observer=new MutationObserver(paint);observer.observe(document.body,{subtree:true,attributes:true,attributeFilter:['data-tracking','data-screen','open']});\r\n const activity=()=>{lastInteraction=Date.now();};\r\n for(const type of ['pointerdown','keydown','input'])document.addEventListener(type,activity,{passive:true});\r\n const autoPoll=setInterval(()=>{paint();if(!dismissed&&Date.now()>=retryAt)void apply(true);},1000);\r\n document.addEventListener('visibilitychange',()=>{if(!document.hidden)check();});window.addEventListener('online',check);\r\n poll=setInterval(()=>{if(!document.hidden)check();},300000);\r\n window.addEventListener('pagehide',event=>{if(!event.persisted){clearInterval(poll);clearInterval(autoPoll);observer.disconnect();for(const type of ['pointerdown','keydown','input'])document.removeEventListener(type,activity);}});emailStatus();\r\n return {check};\r\n}\r\n","app.mjs":"import {claimGraphics} from './modules/graphics-lifecycle.mjs';\nimport './modules/coach-world/entry.mjs';\nimport {PoseFrameScheduler} from './pose-frame.mjs';\r\nimport {mountCameraWorkout} from './camera-workout.mjs';\r\nimport { MovementSession, MOVEMENTS } from './movement-engine.mjs';\r\nimport { initLibrary } from './menu.mjs';\r\nimport {showUnlockGate,watchUnlock} from './unlock-gate.mjs';\r\nimport {CoachVoice,CueEvents} from './coach.mjs';\r\nimport {mountCoachVoiceSettings} from './coach-voice-settings.mjs';\r\nimport {initPod} from './pod/pod.mjs';\r\nimport {syncBattlePass} from './battle-pass.mjs';\r\nimport {mountBattlePass} from './battle-pass-page.mjs';\r\nimport {performanceOwner} from './performance-progress.mjs';\r\nimport {workoutPathAccess} from './chosen-styles.mjs';\r\nimport {reconcilePerformanceWorkouts} from './performance-reconcile.mjs';\r\nimport {mountHomeCharacter} from './pod/home-character.mjs';\r\nimport {mountPodPlaces} from './pod/pod-places.mjs';\r\nimport {mountContinueWorkout} from './pod/continue-workout.mjs';\r\nimport {initHardware} from './pod/hardware.mjs';\r\nimport {setFlipValue,countDigits,clockDigits} from './flip-display.mjs';\r\nimport {openCamera,listCameras,findUltrawide,deviceChoice,cameraFacing,widestZoom,cameraReport} from './camera.mjs';\r\nimport {openGuestWorkoutAdapter} from './local-coach-runtime.mjs';\r\nimport {ManualActiveClock,ManualStartGate} from './local-coach/manual-clock.mjs';\r\nimport {mountPackLicenses} from './packs/pack-license-surface.mjs';\r\nimport {mountCoachOverlay} from './coach-overlay.mjs';\r\nimport {workoutEffectsSnapshot,isMartialSliceExercise,latestRetainableWorkoutSnapshot,createOptionalRetry,createOptionalModuleLoader} from './arcade/workout-effects-state.mjs';\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {physicalSound} from './audio/physical-sound.mjs';\r\nimport {mountArmieInboxUI} from './armie-inbox-ui.mjs';\r\nimport {acceptShipRevealComplete} from './modules/ships/ship-access.mjs';\r\nimport {localVerifiedBridge as shipViewBridge,ownedShipIds as shipOwnedShipIds,mountFirstShipArrival} from './modules/ships/ship-view-bridge.mjs';\r\nimport {mountRoutes,hashRoute} from './modules/routes.mjs';\r\nimport {mountMenuLifecycle} from './menu-lifecycle.mjs';\r\nimport {mountPhoneOrientation} from './modules/phone-orientation.mjs';\r\nimport {mountPhysicalSoundUI} from './audio/sound-ui.mjs';\r\nimport {mountPageMusic} from './audio/page-music.mjs';\r\nimport {mountFullWorkout} from './full-workout-ui.mjs';\r\nimport {mountPodChrome} from './modules/pod-chrome.mjs';\r\nimport {ensurePortalMounted} from './modules/portal/portal-entry.mjs';\r\n// W2-2A: hash routes + the bottom bar (launch.mjs boots the deep link once the panels exist).\r\nmountRoutes();\r\nwindow.myr5MenuLifecycle=mountMenuLifecycle();\r\nmountBattlePass();\r\nmountPhysicalSoundUI();mountPageMusic();\r\nconst lazyGrimoire=document.createElement('button');\r\nlazyGrimoire.type='button';lazyGrimoire.id='podGrimoireLazyOpen';lazyGrimoire.textContent='GRIMOIRE';\r\nlazyGrimoire.setAttribute('aria-label','Open grimoire settings');\r\nlet grimoireOpening=false;\r\nlazyGrimoire.addEventListener('click',async()=>{\r\n if(grimoireOpening)return;grimoireOpening=true;\r\n try{await ensurePortalMounted();document.getElementById('portalSettingsButton')?.click();}\r\n catch(error){console.warn('Grimoire settings unavailable',error);}\r\n finally{grimoireOpening=false;}\r\n});\r\nmountPodChrome(lazyGrimoire);\r\nlet phoneOrientation=mountPhoneOrientation();\r\nwindow.addEventListener('pagehide',()=>{phoneOrientation?.();phoneOrientation=null;});\r\nwindow.addEventListener('pageshow',event=>{if(event.persisted&&!phoneOrientation)phoneOrientation=mountPhoneOrientation();});\r\nconst $=id=>document.getElementById(id),v=$('v'),c=$('c'),g=c.getContext('2d');\r\n$('camera').querySelector('option[value=\"manual\"]')?.remove();\r\nif($('camera').value==='manual')$('camera').value='user';\r\nconst poseFrames=new PoseFrameScheduler(v);\r\nconst schedulePose=run=>poseFrames.schedule(()=>{if(run===generation&&state.phase==='tracking')void loop(run);});\r\n// Capture time of the frame being detected (rVFC metadata, performance.now() clock) so effect layers can filter on\r\n// real frame spacing and predict across the inference lag. Falls back to the detect time.\r\nfunction frameTime(now){const m=poseFrames.frame;for(const t of [m?.captureTime,m?.presentationTime])if(Number.isFinite(t)&&t<=now&&now-t<500)return t;return now;}\r\n// Optional person mask for the aura silhouette tier: only while an aura layer asks (globalThis.myr5AuraWantsMask,\r\n// set by its quality ladder), downsampled once here to ~96 px wide while the MPMask is still valid.\r\nlet maskTracker=null,maskOn=false,maskSetting=null;const maskBuf={w:0,h:0,data:null};\r\nfunction syncMask(){\r\n  const want=!!globalThis.myr5AuraWantsMask;if(maskTracker!==tracker){maskTracker=tracker;maskOn=false;}\r\n  if(want===maskOn||maskSetting||typeof tracker?.setOptions!=='function')return;\r\n  const t=tracker;maskSetting=Promise.resolve().then(()=>t.setOptions({outputSegmentationMasks:want})).then(()=>{if(maskTracker===t)maskOn=want;},()=>{globalThis.myr5AuraWantsMask=false;}).finally(()=>{maskSetting=null;});\r\n}\r\nfunction readMask(result){\r\n  const masks=result?.segmentationMasks,m=masks?.[0];if(!m)return null;\r\n  try{\r\n    const W=m.width,H=m.height,step=Math.max(1,Math.ceil(W/96)),w=Math.floor(W/step),h=Math.floor(H/step);\r\n    if(!maskBuf.data||maskBuf.w!==w||maskBuf.h!==h){maskBuf.w=w;maskBuf.h=h;maskBuf.data=new Uint8ClampedArray(w*h);}\r\n    const src=m.getAsFloat32Array(),d=maskBuf.data;\r\n    for(let y=0,k=0;y<h;y++){const row=y*step*W;for(let x=0;x<w;x++)d[k++]=src[row+x*step]*255;}\r\n    return maskBuf;\r\n  }catch{return null;}finally{for(const mask of masks)try{mask.close();}catch{}}\r\n}\r\nconst voice=new CoachVoice(text=>{$('coachCaption').textContent=text;if(!$('restScreen').hidden)$('restFeedback').textContent=text;},text=>$('voiceType').textContent=text),cues=new CueEvents();\r\nmountCoachVoiceSettings({voice,settings:$('settings'),testButton:$('testVoice')});\r\ndocument.addEventListener('pointerdown',()=>voice.unlock(),{capture:true});\r\ndocument.addEventListener('keydown',()=>voice.unlock(),{capture:true});\r\nif(!voice.available){$('voiceType').textContent='Speech unavailable in this browser';$('toggleVoice').disabled=true;}\r\nlet pod=null,tracker=null,draw=null,api=null,files=null,stream=null,frame=0,generation=0;\r\nlet workoutEffects=null,workoutEffectsLoading=null,workoutEffectsToken=0,latestWorkoutEffects=null,pendingRetainedDetail=null,retainedPower=null,avatarPower=null,avatarPowerCard=null,avatarPowerLoadingCard=null,avatarPowerFailedCard=null,retainedPowerLoading=null,retainedPowerToken=0,avatarPowerToken=0,retainedOwner=null;\r\nconst retainedPowerRetry=createOptionalRetry(),avatarPowerRetry=createOptionalRetry();\r\nconst loadRetainedPowerModule=createOptionalModuleLoader('/arcade/power/retained-power.mjs');\r\nconst loadAvatarPowerModule=createOptionalModuleLoader('/arcade/power/avatar-power.mjs');\r\nconst loadQuestProgressReporterModule=createOptionalModuleLoader('/arcade/quest-progress-reporter.mjs');\r\nconst loadWorkoutEffectsModule=createOptionalModuleLoader('/arcade/workout-effects.mjs');\r\nconst questReporterRetry=createOptionalRetry(),workoutEffectsRetry=createOptionalRetry();\r\nlet questReporter=null,questReporterOwner=null,questReporterLoading=null,questReporterToken=0,pendingQuestDetails=new Map();\r\nfunction dropWorkoutEffects(){workoutEffectsToken++;workoutEffectsRetry.reset();workoutEffects?.stop();workoutEffects=null;workoutEffectsLoading=null;latestWorkoutEffects=null;}\r\nfunction invalidateWorkoutEffects(){workoutEffectsToken++;workoutEffectsRetry.reset();workoutEffectsLoading=null;workoutEffects?.invalidate();if(latestWorkoutEffects)latestWorkoutEffects={...latestWorkoutEffects,validHold:false,workout:{...latestWorkoutEffects.workout,active:false}};}\r\nfunction publishRetainedPower(){try{window.dispatchEvent(new CustomEvent('myr5:retained-character-power',{detail:{ownerId:retainedOwner??performanceOwner(),record:retainedPower?.read()??{version:1,equipped:null,styles:{}}}}));}catch{}}\r\nwindow.addEventListener('myr5:retained-character-power-request',()=>publishRetainedPower());\r\nfunction mountRetainedAvatar(card,avatarModule){\r\n if(!card||!retainedPower||!card.isConnected||avatarPowerCard===card||avatarPowerLoadingCard===card)return;\r\n if(avatarPowerFailedCard&&avatarPowerFailedCard!==card){const previous=avatarPowerFailedCard;avatarPowerFailedCard=null;if(previous!==card)avatarPowerRetry.reset();}\r\n if(avatarPowerFailedCard===card&&!avatarPowerRetry.canStart())return;\r\n if(!avatarPowerRetry.canStart())return;\r\n avatarPowerRetry.start();const token=++avatarPowerToken;avatarPowerLoadingCard=card;\r\n Promise.resolve(avatarModule?avatarModule:loadAvatarPowerModule()).then(module=>{\r\n  if(token!==avatarPowerToken||!retainedPower||!card.isConnected||performanceOwner()!==retainedOwner)return;\r\n  const mounted=module.mountAvatarPower({card,retained:retainedPower,sound:physicalSound,seed:0x4d595235});\r\n  avatarPower=mounted;avatarPowerCard=card;avatarPowerRetry.succeed();if(avatarPowerFailedCard===card)avatarPowerFailedCard=null;\r\n }).catch(()=>{if(token===avatarPowerToken&&avatarPowerLoadingCard===card){avatarPowerFailedCard=card;avatarPowerRetry.fail();}}).finally(()=>{if(token===avatarPowerToken&&avatarPowerLoadingCard===card)avatarPowerLoadingCard=null;});\r\n}\r\nfunction ensureRetainedPower(card=document.querySelector('.myr5-companion-card')){\r\n const owner=performanceOwner();\r\n if(retainedPower){if(owner!==retainedOwner){retainedPower.setOwner(owner);retainedOwner=owner;avatarPowerToken++;avatarPower?.stop();avatarPower=null;avatarPowerCard=null;avatarPowerLoadingCard=null;if(avatarPowerFailedCard===card)avatarPowerFailedCard=null;avatarPowerRetry.reset();publishRetainedPower();}else if(card&&card!==avatarPowerCard&&card!==avatarPowerLoadingCard){avatarPowerToken++;avatarPower?.stop();avatarPower=null;avatarPowerCard=null;avatarPowerLoadingCard=null;if(avatarPowerFailedCard&&avatarPowerFailedCard!==card){avatarPowerFailedCard=null;avatarPowerRetry.reset();}}\r\n  if(card)mountRetainedAvatar(card);return;}\r\n if(retainedPowerLoading)return;\r\n if(!retainedPowerRetry.canStart())return;\r\n retainedPowerRetry.start();const token=++retainedPowerToken;\r\n retainedPowerLoading=loadRetainedPowerModule().then(storeModule=>{\r\n  if(token!==retainedPowerToken||performanceOwner()!==owner)return;\r\n  let storage=null;try{storage=localStorage;}catch{}\r\n  retainedPower=storeModule.createRetainedPower({storage,ownerId:owner});retainedOwner=owner;\r\n  if(pendingRetainedDetail?.workout?.ownerId===owner&&retainedPower.observe(pendingRetainedDetail))avatarPower?.refresh();\r\n  retainedPowerRetry.succeed();publishRetainedPower();\r\n  const currentCard=card?.isConnected?card:document.querySelector('.myr5-companion-card');if(currentCard)mountRetainedAvatar(currentCard);\r\n }).catch(()=>{if(token===retainedPowerToken)retainedPowerRetry.fail();}).finally(()=>{if(token===retainedPowerToken)retainedPowerLoading=null;});\r\n}\r\nfunction syncRetainedPowerOwner(){retainedPowerToken++;retainedPowerLoading=null;pendingRetainedDetail=null;questReporter=null;questReporterOwner=null;questReporterLoading=null;questReporterToken++;pendingQuestDetails.clear();questReporterRetry.reset();retainedPowerRetry.reset();const owner=performanceOwner();if(owner!==retainedOwner){retainedOwner=owner;avatarPowerToken++;avatarPower?.stop();avatarPower=null;avatarPowerCard=null;avatarPowerLoadingCard=null;avatarPowerFailedCard=null;avatarPowerRetry.reset();if(retainedPower)retainedPower.setOwner(owner);publishRetainedPower();}ensureRetainedPower();}\r\nfunction routeQuestWorkoutProgress(detail){\r\n const ownerId=detail?.workout?.ownerId;\r\n if(!ownerId||ownerId!==performanceOwner())return;\r\n const workout=detail.workout;\r\n if(workout.stage!=='working'||workout.paused===true)return;\r\n const value=workout.kind==='reps'?Number(workout.workingReps):Number(workout.activeSeconds);\r\n if(!Number.isFinite(value)||value<=0)return;\r\n const previous=pendingQuestDetails.get(workout.mode);\r\n const prior=previous?.workout?.kind==='reps'?Number(previous.workout.workingReps):Number(previous?.workout?.activeSeconds)||0;\r\n if(!previous||value>=prior)pendingQuestDetails.set(workout.mode,detail);\r\n if(questReporterOwner===ownerId&&questReporter){for(const queued of pendingQuestDetails.values())try{questReporter.recordWorkout(queued);}catch{}return;}\r\n if(questReporterLoading||!questReporterRetry.canStart())return;\r\n questReporterRetry.start();\r\n const loadingOwner=ownerId,token=++questReporterToken;\r\n questReporterLoading=loadQuestProgressReporterModule().then(module=>{\r\n  questReporterRetry.succeed();\r\n  if(token!==questReporterToken||performanceOwner()!==loadingOwner)return;\r\n  questReporter=module.createQuestProgressReporter(loadingOwner);questReporterOwner=loadingOwner;\r\n  for(const queued of pendingQuestDetails.values())try{questReporter.recordWorkout(queued);}catch{}\r\n  pendingQuestDetails.clear();\r\n }).catch(()=>{if(token===questReporterToken)questReporterRetry.fail();}).finally(()=>{if(token===questReporterToken)questReporterLoading=null;});\r\n}\r\nlet preloadedEffectMode=null;\r\nfunction preloadEffectsFor(mode){\r\n if(!mode||mode===preloadedEffectMode)return;preloadedEffectMode=mode;\r\n loadWorkoutEffectsModule().then(module=>module.preloadWorkoutEffects?.(mode)).catch(()=>{preloadedEffectMode=null;});\r\n}\r\nwindow.addEventListener('myr5:exercise-selected',()=>setTimeout(()=>preloadEffectsFor($('movement')?.value),0));\r\nfunction routeWorkoutEffects(detail){\r\n latestWorkoutEffects=detail;\r\n if(document.body.dataset.tracking==='true')preloadEffectsFor(detail?.workout?.mode);\r\n routeQuestWorkoutProgress(detail);\r\n if(detail?.workout?.ownerId&&detail.workout.ownerId===performanceOwner())ensureRetainedPower();\r\n pendingRetainedDetail=latestRetainableWorkoutSnapshot(pendingRetainedDetail,detail,retainedOwner??performanceOwner());\r\n if(retainedPower?.observe(detail)){avatarPower?.refresh();publishRetainedPower();}\r\n if(document.body.dataset.tracking!=='true'||document.hidden){workoutEffects?.invalidate();return;}\r\n if(!detail?.workout?.active){workoutEffects?.pose(detail);return;}\r\n if(workoutEffects){workoutEffects.pose(detail);return;}\r\n if(workoutEffectsLoading||!workoutEffectsRetry.canStart())return;\r\n workoutEffectsRetry.start();\r\n const token=workoutEffectsToken;\r\n workoutEffectsLoading=loadWorkoutEffectsModule().then(module=>{\r\n  workoutEffectsRetry.succeed();\r\n  if(token!==workoutEffectsToken||document.body.dataset.tracking!=='true'||document.hidden||!latestWorkoutEffects?.workout?.active)return;\r\n  const host=document.getElementById('coachOverlay');if(!host)return;\r\n  const session=String(latestWorkoutEffects.workout.sessionId||'');let seed=2166136261;for(let i=0;i<session.length;i++)seed=Math.imul(seed^session.charCodeAt(i),16777619);\r\n  workoutEffects=module.mountWorkoutEffects({host,sound:physicalSound,seed:seed>>>0});workoutEffects.pose(latestWorkoutEffects);\r\n }).catch(()=>{if(token===workoutEffectsToken)workoutEffectsRetry.fail();}).finally(()=>{if(token===workoutEffectsToken)workoutEffectsLoading=null;});\r\n}\r\n// R9-OFFLINE: the pinned pose tracker, same-origin (scripts/mediapipe.mjs) and in the Starter download, so a set runs offline.\r\nconst MEDIAPIPE='/vendor/mediapipe/0.10.14';\r\nlet lastTime=-1,frames=0,timing=0,windowStart=0,lastUi=0;\r\n// Tracker delegate: GPU first, CPU fallback. CPU was the baseline because a Pixel's GPU path once lost its WebGL\r\n// context, so any GPU failure (load error, detect throw, context loss, NaN landmarks, or blind while a CPU probe\r\n// sees a person) drops this set to CPU and is remembered on the device. ?poseDelegate=CPU|GPU forces one for A/B.\r\nconst DELEGATE_KEY='myr5-pose-delegate',BLIND_PROBE_MS=3000;\r\nlet gpuSeen=false,blindSince=0,probe=null;\r\nfunction preferredDelegate(){\r\n  const forced=new URLSearchParams(location.search).get('poseDelegate')?.toUpperCase();\r\n  if(forced==='CPU'||forced==='GPU')return forced;\r\n  try{return localStorage.getItem(DELEGATE_KEY)==='CPU'?'CPU':'GPU';}catch{return 'GPU';}\r\n}\r\nfunction rememberCpu(reason){state.delegateNote=reason;console.warn('Pose tracker on CPU: '+reason);try{localStorage.setItem(DELEGATE_KEY,'CPU');}catch{}}\r\nasync function loadTracker(delegate,run){\r\n  // Our own canvas on GPU so a lost WebGL context is seen (MediaPipe runs its GL on options.canvas).\r\n  const canvas=delegate==='GPU'?(typeof OffscreenCanvas==='function'?new OffscreenCanvas(1,1):document.createElement('canvas')):undefined;\r\n  let expired=false;\r\n  const loading=api.PoseLandmarker.createFromOptions(files,{...(canvas?{canvas}:{}),baseOptions:{modelAssetPath:MEDIAPIPE+'/pose_landmarker_lite.task',delegate},runningMode:'VIDEO',numPoses:1});\r\n  loading.then(created=>{if(run!==generation||expired)created.close();},()=>{});\r\n  let created;\r\n  try{created=await timeout(loading,60000,'Tracker loading took too long. Tap Start to retry.');}catch(error){expired=true;throw error;}\r\n  canvas?.addEventListener('webglcontextlost',()=>{created.myr5Lost=true;});\r\n  return created;\r\n}\r\nasync function toCpu(run,reason){\r\n  rememberCpu(reason);try{tracker?.close();}catch{}tracker=null;\r\n  const cpu=probe?.tracker||await loadTracker('CPU',run);probe=null;\r\n  if(run!==generation){try{cpu.close();}catch{}return;}\r\n  tracker=cpu;state.delegate='CPU';\r\n}\r\nfunction closeProbe(){try{probe?.tracker?.close();}catch{}probe=null;}\r\nconst ACTIVE_PHASES=new Set(['camera','model','tracking','preparation-rest','manual-starting','manual']);\r\nconst FROZEN_SETTINGS=['movement','goal','duration','restDuration','camera'];\r\nlet frozenSettings=null;\r\nconst freezeSettings=()=>{frozenSettings=Object.fromEntries(FROZEN_SETTINGS.map(id=>[id,$(id).value]));};\r\nconst releaseOwner=()=>{pod?.workoutOwner?.stop();};\r\nlet manual=null,manualFrame=0,disposed=false,workoutTransition=Promise.resolve(),cameraStartTransition=Promise.resolve(),cameraAcquisition=null;\r\nconst manualStartGate=new ManualStartGate();\r\nlet session=new MovementSession('squat');\r\nconst state={version:'pod-1',phase:'idle',frames:0,poses:0,inferenceMs:0,rate:0,camera:null,delegate:null,error:null,motion:session.snapshot()};\r\nwindow.myr5TestState=state;\r\nconst cameraWorkout=mountCameraWorkout({video:v,counter:$('primary'),onStop:()=>{if(EXERCISES[session.mode]?.endless&&state.phase==='tracking'){void finishEndless();return;}void stop();voice.say('Stopped.',{interrupt:true});},\r\n  // Downward correction can remove a false camera rep without creating free XP.\r\n  onAdjust:delta=>{if(delta>=0||state.phase!=='tracking'||state.motion.kind!=='reps')return;session.count=Math.max(0,session.count+delta);state.motion=session.snapshot();renderMotion(state.motion);}});\r\nfunction status(text){if($('status').textContent!==text)$('status').textContent=text;}\r\nconst clock=seconds=>`${Math.floor(seconds/60)}:${String(Math.floor(seconds%60)).padStart(2,'0')}`;\r\n// Cool Cardio runner is open to every path ONLY while started from the COOL CARDIO key; the library and BEGIN keep the path locks (Ian, 7 Oct).\r\n// var: controls() can run before this line during start-up.\r\nvar coolKey=false;const pathAccess=mode=>coolKey&&EXERCISES[mode]?.runner?{allowed:true,path:null,reason:null}:workoutPathAccess(mode);\r\nfunction controls(busy){$('start').disabled=busy||pod?.canStart($('movement').value)===false;$('camera').disabled=busy;$('coolCardio').disabled=busy;$('stop').disabled=!busy;$('stop').hidden=!busy;$('goal').disabled=busy;$('restDuration').disabled=busy;$('movement').disabled=busy;$('duration').disabled=busy;$('reset').disabled=busy;$('widest').disabled=busy||!stream||state.phase!=='tracking';document.body.dataset.tracking=String(busy);cameraWorkout.setActive(busy&&state.phase==='tracking');$('previewLabel').textContent=state.phase==='tracking'?'TRACKING':'CAMERA';}\r\nasync function refreshLenses(){\r\n  const cameras=await listCameras(),selected=$('camera').value;\r\n  $('camera').querySelectorAll('option[data-device]').forEach(o=>o.remove());\r\n  cameras.forEach((camera,i)=>{const option=document.createElement('option');option.value=deviceChoice(camera.id);option.dataset.device='';option.textContent=camera.label||`Camera ${i+1}`;$('camera').append(option);});\r\n  if([...$('camera').options].some(o=>o.value===selected))$('camera').value=selected;\r\n  return cameras;\r\n}\r\nasync function showLensInfo(track){\r\n  let cameras=[];try{cameras=await timeout(refreshLenses(),3000,'Camera list unavailable.');}catch{}\r\n  const zoom=await timeout(widestZoom(track),3000,'Zoom unavailable.').catch(()=>({supported:false,applied:false}));if(!stream||!stream.getTracks().includes(track))return;\r\n  const report=cameraReport(track,cameras,zoom);\r\n  const actualId=track.getSettings().deviceId;if(cameras.some(d=>d.id===actualId))$('camera').value=deviceChoice(actualId);\r\n  $('lensInfo').textContent=report.label+' · '+(zoom.applied?`widest exposed zoom ${zoom.zoom}×`:zoom.supported?'Wider zoom could not be applied.':'This lens exposes no zoom control.')+' Follow the camera cue for your exercise.';\r\n  $('cameraDetails').textContent=JSON.stringify(report,null,2);\r\n  // Send only the camera availability/settings shown above to the local test PC.\r\n  // No camera images, body coordinates, or exercise history are sent.\r\n  // Only the local dev server (serve.cjs) has this route; the Worker answers 404, so skip it elsewhere.\r\n  if(['localhost','127.0.0.1'].includes(location.hostname))fetch('/camera-info',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(report)}).catch(()=>{});\r\n}\r\nfunction release(){\r\n  dropWorkoutEffects();\r\n  cameraAcquisition?.abort();cameraAcquisition=null;\r\n  frozenSettings=null;\r\n  poseFrames.stop();cancelAnimationFrame(frame);cancelAnimationFrame(manualFrame);manualFrame=0;if(tracker){try{tracker.close();}catch{}tracker=null;}closeProbe();draw=null;\r\n  stream?.getTracks().forEach(t=>t.stop());stream=null;v.pause();v.srcObject=null;g.clearRect(0,0,c.width,c.height);\r\n  state.camera=null;state.delegate=null;state.rate=0;\r\n}\r\nfunction resetMovement(){\r\n  cues.reset();\r\n  const mode=$('movement').value,config=MOVEMENTS[mode];\r\n  pod?.configure(mode);\r\n  const timed=['pace','steps','jumps'].includes(config.kind);$('roundControl').hidden=!timed;\r\n  session=new MovementSession(mode);\r\n  state.motion=session.snapshot();$('hint').textContent=config.hint;renderMotion(state.motion);\r\n  window.dispatchEvent(new Event('myr5:movement-configured'));\r\n  status(state.phase==='tracking'?config.hint:'Ready');\r\n}\r\nfunction renderMotion(m){\r\n  const rawMotion=m;m=pod?.workoutMotion?.(m)||m;\r\n  $('movementName').textContent=m.name;\r\n  const label=m.kind==='hold'?'hold time':m.kind==='pace'?'active time':m.kind==='steps'?'steps':m.kind==='jumps'?'jumps':'reps';\r\n  setFlipValue($('primary'),m.kind==='hold'?clockDigits(m.totalHold):m.kind==='pace'?clockDigits(m.active):countDigits(m.count),label);\r\n  $('primaryLabel').textContent=label;\r\n  const time=m.remaining===null?`Session ${clock(m.elapsed)}`:`Remaining ${clock(m.remaining)}`;\r\n  $('secondary').textContent=m.kind==='hold'?`Best ${clock(m.bestHold)} · Total ${clock(m.totalHold)}`:m.kind==='pace'?`Moving ${clock(m.active)} · Hand pace ${m.speed.toFixed(1)}×`:(m.kind==='steps'||m.kind==='jumps')?`${time} · ${Math.round(m.cadence)}/${m.kind==='steps'?'min':'min'}`:time;\r\n  $('activity').style.width=`${Math.round(m.progress*100)}%`;\r\n  $('measurement').textContent=m.measurement;\r\n  $('jointReadings').textContent=m.jointReadings||'';\r\n  $('countState').textContent=!m.tracking?'Waiting for joints':(['squat','pushup','jumping'].includes(m.mode)&&!m.calibrated)?'Setting start':m.phase==='bottom'?'Return to start to count':m.kind==='hold'?'Hold timer':m.kind==='pace'?'Round timer':'Counter ready';\r\n  $('paceNote').hidden=m.kind!=='pace';\r\n  const paused=!m.tracking||(m.kind==='hold'&&!m.progress)||(m.kind==='reps'&&!m.calibrated);\r\n  cameraWorkout.show({status:paused?m.message:'',reps:m.kind==='reps'&&state.phase==='tracking'});\r\n  pod?.render(rawMotion);\r\n  const instruction=pod?.flow?.workout?.instruction;if(instruction)$('status').textContent=typeof instruction==='string'?instruction:instruction.message||instruction.text||'';\r\n  const tools=document.querySelector('.workout-performance-controls'),workout=pod?.flow?.workout;\r\n  if(tools){const cameraStage=document.getElementById('cameraWorkout');if(state.phase==='tracking'&&cameraStage&&tools.parentElement!==cameraStage)cameraStage.append(tools);else if(state.phase!=='tracking'&&tools.parentElement===cameraStage)document.getElementById('bar').after(tools);tools.hidden=!['tracking','manual'].includes(state.phase);for(const button of tools.querySelectorAll('button')){const label=button.textContent;button.hidden=label==='Finish working set'?workout?.stage?.startsWith('preparation-'):label==='Break hold'?workout?.kind!=='hold'||workout.paused:label==='Resume hold'||label==='More recovery'?workout?.kind!=='hold'||!workout.paused:false;}const variation=tools.querySelector('[data-hold-variation]');if(variation){variation.hidden=true;variation.querySelector('select').disabled=true;}const recovery=tools.querySelector('[data-hold-recovery]');if(recovery){recovery.hidden=!workout?.paused;recovery.textContent=`Recovery · ${Math.ceil(Math.max(0,(workout?.recoveryUntil-Date.now())/1000))}s. Resume whenever ready.`;}}\r\n}\r\nfunction stop(message='Stopped. Your results stay here until the next start.',{interrupt=true,home=true}={}){\r\n  if(state.phase==='manual'||state.phase==='manual-starting')return pauseManualWhenReady({home});\r\n  const unfinished=interrupt&&['camera','model','tracking','preparation-rest'].includes(state.phase);\r\n  voice.cancel();\r\n  generation++;release();controls(false);state.phase='idle';status(message);$('countState').textContent='Camera stopped';$('detail').textContent='Camera off · Tracker closed';\r\n  // #19/#56: a set cut short by STOP also goes home; the pod offers it back with its Continue popup.\r\n  if(unfinished)window.dispatchEvent(new Event('myr5:workout-stopped'));\r\n  if(unfinished)workoutTransition=Promise.resolve().then(()=>pod?.interruptCurrent(state.motion)).catch(error=>{status(error.message);}).finally(()=>{releaseOwner();controls(false);if(home)window.myr5Routes?.home?.();});\r\n  return workoutTransition;\r\n}\r\nfor(const type of ['input','change'])document.addEventListener(type,event=>{\r\n  if(!ACTIVE_PHASES.has(state.phase)||!frozenSettings||!FROZEN_SETTINGS.includes(event.target?.id))return;\r\n  event.stopImmediatePropagation();event.target.value=frozenSettings[event.target.id];\r\n},true);\r\nwindow.addEventListener('myr5:route-leave',event=>{if(event.detail?.id==='library'&&event.detail.reason==='workout-begin')return;if(ACTIVE_PHASES.has(state.phase))void stop('Workout stopped. Your progress is saved.',{home:false});});\r\nfunction timeout(promise,ms,message){let timer;return Promise.race([promise,new Promise((_,reject)=>{timer=setTimeout(()=>reject(new Error(message)),ms);})]).finally(()=>clearTimeout(timer));}\r\nasync function start(){\r\n  if(document.hidden)return;\r\n  const access=pathAccess($('movement').value);if(!access.allowed){status(access.reason);controls(false);return;}\r\n  if(ACTIVE_PHASES.has(state.phase))stop('Switching workout input…');\r\n  try{await Promise.all([workoutTransition,cameraStartTransition]);}catch{return;}\r\n  if(document.hidden)return;\r\n  if($('camera').value==='manual')$('camera').value='user';\r\n  const run=++generation;release();state.phase='camera';controls(true);state.error=null;resetMovement();freezeSettings();\r\n  $('trainingView').scrollIntoView({block:'start',behavior:'auto'});\r\n  state.frames=0;state.poses=0;state.inferenceMs=0;status('Opening camera…');voice.say(MOVEMENTS[session.mode].name+' selected.',{key:'movement',interrupt:true});voice.say('Get into position.',{key:'setup'});$('detail').textContent='Waiting for video';\r\n  let settleCameraStart;\r\n  cameraStartTransition=new Promise(resolve=>{settleCameraStart=resolve;});\r\n  try{\r\n    const beginning=pod.beginSet(session.mode,{manual:false});\r\n    beginning.then(()=>{if(run!==generation)void pod.interruptCurrent(state.motion).catch(()=>{});},()=>{});\r\n    await timeout(beginning,15000,'Workout storage is taking too long. Close other Coach tabs and tap Begin again.');\r\n    if(run!==generation){await pod.interruptCurrent(state.motion);return;}\r\n    if(!navigator.mediaDevices?.getUserMedia)throw new Error('Open this HTTPS site in a browser that supports camera access.');\r\n    const selected=$('camera').value;\r\n    cameraAcquisition=new AbortController();\r\n    const incoming=await openCamera(selected,30,navigator.mediaDevices,{signal:cameraAcquisition.signal});\r\n    if(run!==generation){incoming.getTracks().forEach(t=>t.stop());return;}\r\n    stream=incoming;v.srcObject=stream;v.muted=true;\r\n    await timeout(v.play(),10000,'The camera opened but sent no video. Select the other camera and retry.');\r\n    if(run!==generation)return;\r\n    state.camera=cameraFacing(stream.getVideoTracks()[0],selected);\r\n    v.style.transform=c.style.transform=state.camera==='user'?'scaleX(-1)':'none';\r\n    await showLensInfo(stream.getVideoTracks()[0]);if(run!==generation)return;\r\n    status('Loading tracker…');$('detail').textContent=`Video ${v.videoWidth} × ${v.videoHeight}`;state.phase='model';\r\n    api=api||await timeout(import(`${MEDIAPIPE}/vision_bundle.mjs`).catch(()=>{throw Error('Download Starter in Settings › Downloads to train offline.');}),20000,'Tracker library did not download. Check the phone’s internet connection.');\r\n    if(run!==generation)return;\r\n    files=files||await timeout(api.FilesetResolver.forVisionTasks(MEDIAPIPE+'/wasm'),20000,'Tracker runtime did not download. Check the phone’s internet connection.');\r\n    if(run!==generation)return;\r\n    let delegate=preferredDelegate(),created=null;\r\n    // One warm-up detect while \"Loading tracker…\" shows: the GPU's first run compiles its shaders (~5 s cold on a\r\n    // desktop) and a throw here means a broken GPU path, so it falls back before the set starts.\r\n    if(delegate==='GPU'){try{created=await loadTracker('GPU',run);if(run===generation)created.detectForVideo(v,performance.now());}catch(error){try{created?.close();}catch{}created=null;if(run!==generation)return;rememberCpu('GPU failed to start: '+error.message);delegate='CPU';}}\r\n    if(run!==generation)return;\r\n    created??=await loadTracker('CPU',run);\r\n    if(run!==generation)return;\r\n    tracker=created;draw=new api.DrawingUtils(g);state.delegate=delegate;state.phase='tracking';void import('./modules/vault/vault-store.mjs').then(m=>m.bump('ar-session')).catch(()=>{});\r\n    gpuSeen=false;blindSince=performance.now();\r\n    controls(true);\r\n    lastTime=-1;frames=0;timing=0;windowStart=performance.now();lastUi=0;\r\n    status(MOVEMENTS[session.mode].hint);voice.say(MOVEMENTS[session.mode].hint,{interrupt:true});loop(run);\r\n  }catch(error){\r\n    if(run!==generation){void pod.interruptCurrent(state.motion).catch(()=>{});return;}\r\n    generation++;release();try{await timeout(pod.interruptCurrent(state.motion),5000,'Workout cleanup timed out.');}catch{}releaseOwner();state.phase='error';window.dispatchEvent(new Event('myr5:workout-stopped'));controls(false);state.error=error.message;\r\n    status(error.name==='NotAllowedError'?'Allow camera access for this site, then tap Begin.':error.message);voice.say($('status').textContent,{interrupt:true});$('detail').textContent='Camera off · Tracker closed';\r\n  }finally{settleCameraStart();}\r\n}\r\nasync function loop(run){\r\n  if(run!==generation||state.phase!=='tracking'||!tracker)return;\r\n  try{\r\n    const now=performance.now();\r\n    if(v.readyState>=2&&v.currentTime!==lastTime){\r\n      lastTime=v.currentTime;if(c.width!==v.videoWidth||c.height!==v.videoHeight){c.width=v.videoWidth;c.height=v.videoHeight;}\r\n      g.clearRect(0,0,c.width,c.height);\r\n      const before=performance.now();let result=null;\r\n      try{result=tracker.detectForVideo(v,now);}catch(error){if(state.delegate!=='GPU')throw error;}\r\n      const elapsed=performance.now()-before;\r\n      if(state.delegate==='GPU'&&(!result||tracker.myr5Lost||result.landmarks[0]?.some(q=>!Number.isFinite(q.x+q.y)))){\r\n        await toCpu(run,!result?'GPU detect threw':tracker?.myr5Lost?'GPU WebGL context lost':'GPU returned invalid landmarks');\r\n        if(run===generation)schedulePose(run);return;\r\n      }\r\n      // A GPU that never sees anyone may be silently broken: every few blind seconds, ask a CPU probe the same frame.\r\n      if(state.delegate==='GPU'&&!gpuSeen){\r\n        if(result.landmarks.length){gpuSeen=true;closeProbe();}\r\n        else if(now-blindSince>=BLIND_PROBE_MS){\r\n          if(!probe){const p=probe={tracker:null};loadTracker('CPU',run).then(t=>{if(probe===p)p.tracker=t;else try{t.close();}catch{}},()=>{});}\r\n          else if(probe.tracker){blindSince=now;let detected=false;try{detected=probe.tracker.detectForVideo(v,now).landmarks.length>0;}catch{closeProbe();}if(detected){await toCpu(run,'GPU blind while CPU sees a pose');if(run===generation)schedulePose(run);return;}}\r\n        }\r\n      }\r\n      state.frames++;frames++;timing+=elapsed;state.poses=result.landmarks.length;syncMask();\r\n      const p=result.landmarks[0]?.slice(0,27);\r\n      if(p){draw.drawConnectors(p,api.PoseLandmarker.POSE_CONNECTIONS.filter(b=>b.start<=26&&b.end<=26),{color:'#bc89ff',lineWidth:3});draw.drawLandmarks(p.filter(q=>q.visibility>=.45),{color:'#aaffd9',radius:3});draw.drawLandmarks(p.filter(q=>q.visibility<.45),{color:'#ffad66',radius:3});}\r\n      state.motion=session.update(p,now,v.videoWidth/v.videoHeight,result.worldLandmarks?.[0]);\r\n      // The room coach gets every landmark (ankles for kicks) and walks in once the set is counting.\r\n      const poseDetail={points:result.landmarks[0]||null,world:result.worldLandmarks?.[0]||null,width:v.videoWidth,height:v.videoHeight,mirrored:state.camera==='user',now,frameMs:frameTime(now),mask:readMask(result),counting:state.motion.count>0||state.motion.totalHold>0||state.motion.active>0};\r\n      window.dispatchEvent(new CustomEvent('myr5:pose',{detail:poseDetail}));\r\n      const cueMotion=['hold','pace'].includes(state.motion.kind)?{...state.motion,remaining:Math.max(0,pod.goal()-(state.motion.kind==='hold'?state.motion.totalHold:state.motion.active))}:state.motion;\r\n      const events=cues.update(cueMotion,now),encouragement=pod.encouragement(state.motion,now,events);if(encouragement)events.push(encouragement);\r\n      for(const cue of events){window.dispatchEvent(new CustomEvent('myr5:cue',{detail:{key:cue.key==='encouragement'?'time':cue.key}}));voice.say(cue.text,{key:cue.key,interrupt:cue.key==='complete'||cue.key==='ready'});}\r\n      const effectActiveBeforeConsume=pod.flow?.active;\r\n      const pendingConsume=pod.consume(state.motion,Date.now());\r\n      const effectWorkout=pod.flow?.workout,effectActive=pod.flow?.active??effectActiveBeforeConsume;\r\n      const effectDetail=workoutEffectsSnapshot({pose:poseDetail,motion:state.motion,workout:effectWorkout,sessionId:effectActive?.localId??run,ownerId:effectActive?.performanceOwner??null,mode:effectActive?.mode??session.mode,tracking:state.phase==='tracking'&&document.body.dataset.tracking==='true',visible:!document.hidden,canCount:pod.canCount(),workingSet:pod.flow?.phase==='set'});\r\n      window.dispatchEvent(new CustomEvent('myr5:workout-effects',{detail:effectDetail}));routeWorkoutEffects(effectDetail);\r\n      if(await pendingConsume){renderMotion(state.motion);cinematics.play('post');return;}\r\n      if(state.phase==='preparation-rest')return;\r\n      if(now-windowStart>=1000){state.rate=frames*1000/(now-windowStart);state.inferenceMs=timing/frames;frames=0;timing=0;windowStart=now;}\r\n      if(now-lastUi>=160){renderMotion(state.motion);status(state.motion.message);$('detail').textContent=`${state.rate.toFixed(0)} tracking updates/s (${state.delegate}) · ${state.inferenceMs.toFixed(0)} ms/update · ${v.videoWidth} × ${v.videoHeight}`;lastUi=now;}\r\n      if(state.motion.complete){renderMotion(state.motion);stop('Round complete. Camera and tracker stopped.');voice.say('Round complete. Well done.',{interrupt:true});return;}\r\n    }\r\n    if(state.phase==='tracking')schedulePose(run);\r\n  }catch(error){if(run!==generation)return;generation++;release();controls(false);await pod.interruptCurrent(state.motion).catch(()=>{});releaseOwner();voice.cancel();state.phase='error';state.error=error.message;status('Tracking stopped: '+error.message);voice.say($('status').textContent,{interrupt:true});$('detail').textContent='Camera off · Tracker closed';}\r\n}\r\nfor(const [id,config] of Object.entries(MOVEMENTS)){const option=document.createElement('option');option.value=id;option.textContent=config.name;$('movement').appendChild(option);}\r\n$('start').addEventListener('click',()=>{if(!pathAccess($('movement').value).allowed){showUnlockGate({onCardio:()=>$('coolCardio').click()});return;}$('camera').value==='manual'?start():library.introduce();});$('stop').addEventListener('click',async()=>{if(state.phase==='manual'){await pauseManualUi();return;}void stop();voice.say('Stopped.',{interrupt:true});});\r\n$('reset').addEventListener('click',()=>{resetMovement();voice.say('Count reset. Return to your starting position.',{interrupt:true});});\r\n$('goal').addEventListener('change',()=>resetMovement());\r\n$('movement').addEventListener('change',event=>{const active=state.phase==='tracking';if(!pathAccess($('movement').value).allowed){const first=Object.keys(MOVEMENTS).find(mode=>workoutPathAccess(mode).allowed);if(first)$('movement').value=first;else{controls(false);status('Choose two workout paths to begin.');return;}}if(!event.detail?.automatic)window.dispatchEvent(new Event('myr5:exercise-selected'));resetMovement();controls(active);if(active)library.introduce();});\r\n$('duration').addEventListener('change',()=>resetMovement());\r\n// Cool Cardio key under the dials: runs the endless runner from any path/level, then puts the dials back (nothing saved changes).\r\n{let back=null;\r\n const restore=async()=>{if(!back)return;try{await workoutTransition;}catch{}await new Promise(r=>setTimeout(r,300));\r\n  if(!back||state.phase!=='idle')return;const was=back;back=null;coolKey=false;$('movement').value=was;$('movement').dispatchEvent(new CustomEvent('change',{bubbles:true,detail:{automatic:true}}));};\r\n $('coolCardio').addEventListener('click',()=>{\r\n  if(ACTIVE_PHASES.has(state.phase)||document.hidden)return;window.dispatchEvent(new CustomEvent('myr5:hardware-detent',{detail:{kind:'switch'}}));\r\n  back=back||$('movement').value;coolKey=true;$('movement').value='jogging';$('movement').dispatchEvent(new CustomEvent('change',{bubbles:true,detail:{automatic:true}}));Promise.resolve(start()).finally(()=>{if(document.body.dataset.tracking!=='true')void restore();});});\r\n new MutationObserver(()=>{if(document.body.dataset.tracking!=='true')void restore();}).observe(document.body,{attributes:true,attributeFilter:['data-tracking']});}\r\nfunction soundSwitch(){$('toggleVoice').textContent=voice.enabled?'ON':'OFF';$('toggleVoice').dataset.on=String(voice.enabled);$('toggleVoice').setAttribute('aria-checked',String(voice.enabled));}\r\n$('toggleVoice').addEventListener('click',()=>{voice.setEnabled(!voice.enabled);soundSwitch();voice.say(voice.enabled?'Voice on.':'Voice off.',{interrupt:true});});\r\n$('testVoice').addEventListener('click',()=>{voice.setEnabled(true);soundSwitch();voice.say('Coach ready. Move at your own pace. One. Two. Three. Thirty seconds left.',{interrupt:true});});\r\n$('camera').addEventListener('change',()=>{if($('camera').value!=='manual')voice.say('Camera selected.',{interrupt:true});if(state.phase==='tracking')start();});\r\n$('widest').addEventListener('click',async()=>{\r\n  const track=stream?.getVideoTracks()[0];if(!track)return;$('widest').disabled=true;\r\n  try{const cameras=await refreshLenses(),wide=findUltrawide(cameras);if(state.camera!=='user'&&wide&&track.getSettings().deviceId!==wide.id){$('camera').value=deviceChoice(wide.id);await start();}else{await showLensInfo(track);if(state.phase==='tracking')resetMovement();}}\r\n  catch(error){$('lensInfo').textContent='Could not change the lens: '+error.message;}\r\n  finally{$('widest').disabled=state.phase!=='tracking';}\r\n});\r\n let workoutAdapter=null;\r\n const openingWorkoutAdapter=openGuestWorkoutAdapter({exerciseKeys:Object.keys(MOVEMENTS)});\r\n const workoutReady=timeout(openingWorkoutAdapter,10000,'Workout storage did not open. Reload Coach and try again.').then(adapter=>{workoutAdapter=adapter;workouts.ownerId=adapter.ownerId;if(disposed)adapter.close();return adapter;},error=>{void openingWorkoutAdapter.then(adapter=>adapter.close(),()=>{});throw error;});\r\n const workouts={paused:(...args)=>workoutReady.then(value=>value.paused(...args)),start:(...args)=>workoutReady.then(value=>value.start(...args)),update:(...args)=>workoutReady.then(value=>value.update(...args)),pause:(...args)=>workoutReady.then(value=>value.pause(...args)),complete:(...args)=>workoutReady.then(value=>value.complete(...args)),interrupt:(...args)=>workoutReady.then(value=>value.interrupt(...args)),unfinished:(...args)=>workoutReady.then(value=>value.unfinished(...args)),close(){disposed=true;if(workoutAdapter)workoutAdapter.close();else void workoutReady.then(value=>value.close(),()=>{});}};\r\n window.addEventListener('pagehide',()=>{const stopped=ACTIVE_PHASES.has(state.phase)?stop('Workout stopped.',{home:false}):workoutTransition;releaseOwner();workouts.close();void Promise.allSettled([stopped,cameraStartTransition]);});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden&&ACTIVE_PHASES.has(state.phase))void stop('Paused while the page was hidden. Tap Begin to start a new session.',{home:false});});\r\n pod=initPod({voice,movements:MOVEMENTS,workouts,onStop:()=>{if(state.phase==='manual'){generation++;release();controls(false);state.phase='idle';manual=null;}else stop('Set ended. Your camera is off.',{interrupt:false});},onNext:async next=>{await library.introduce(next?.mode);if(next)pod.setGoal(next.goal);}});\r\n window.addEventListener('myr5:preparation-rest-start',()=>{\r\n  if(state.phase!=='tracking')return;\r\n  state.phase='preparation-rest';poseFrames.stop();cameraWorkout.setActive(false);\r\n  $('previewLabel').textContent='RECOVERY';\r\n });\r\n window.addEventListener('myr5:preparation-rest-end',()=>{\r\n  if(state.phase!=='preparation-rest'||document.hidden||!tracker)return;\r\n  cues.reset();session=new MovementSession(session.mode);state.motion=session.snapshot();pod.rebaseTracking();\r\n  lastTime=-1;frames=0;timing=0;windowStart=performance.now();lastUi=0;\r\n  state.phase='tracking';cameraWorkout.setActive(true);$('previewLabel').textContent='TRACKING';renderMotion(state.motion);schedulePose(generation);\r\n });\r\nasync function repairWorkoutRewards(){const owner=performanceOwner();try{const adapter=await workoutReady,rows=await adapter.listPerformanceWorkouts();if(disposed||performanceOwner()!==owner)return;const repaired=reconcilePerformanceWorkouts(rows,{owner});if(repaired.failed.length)status('Your workout is saved. Rewards will retry when progress storage is available.');}catch(error){if(!disposed)console.warn('Workout reward repair is waiting:',error.message);}}\r\nvoid repairWorkoutRewards();for(const event of ['myr5:local-history-refresh','myr5:account-ready','storage'])window.addEventListener(event,()=>void repairWorkoutRewards());\r\n// P13D: optional pack UI may bind this actual owner after user intent; packs are not imported at startup.\r\nwindow.myr5WorkoutOwner=pod.workoutOwner;\r\nwindow.dispatchEvent(new Event('myr5:workout-owner-ready'));\r\nwindow.myr5CreatePackControl=async options=>{\r\n  const {createIsolatedPackControl}=await import('./packs/isolated-pack-control.mjs');\r\n  return createIsolatedPackControl({...options,workoutOwner:pod.workoutOwner});\r\n};\r\nresetMovement();watchUnlock();\r\nconst canUseWorkout=mode=>workoutPathAccess(mode).allowed;\r\ninitHardware({canUse:canUseWorkout});\r\nmountFullWorkout({canUse:canUseWorkout,reason:mode=>workoutPathAccess(mode).reason,select:(mode,goal)=>{$('movement').value=mode;$('movement').dispatchEvent(new CustomEvent('change',{bubbles:true,detail:{automatic:true}}));pod.setGoal(goal);},start:()=>start(),leaveRest:()=>pod.leave(),voice});\r\nsoundSwitch();\r\n const library=initLibrary({movements:MOVEMENTS,voice,canUse:canUseWorkout,onLocked:()=>showUnlockGate({onCardio:()=>$('coolCardio').click()}),onOpen:()=>stop('Workout stopped for the library. Your results are kept.',{home:false}),onSelect:mode=>{$('movement').value=mode;window.dispatchEvent(new Event('myr5:exercise-selected'));resetMovement();controls(false);},onStart:()=>{if(!document.hidden)start();},camera:()=>$('camera').value,movement:()=>$('movement').value});\r\nfunction refreshWorkoutPaths(){for(const option of $('movement').options){const allowed=canUseWorkout(option.value);option.disabled=!allowed;option.textContent=option.textContent.replace(/ · locked$/,'')+(allowed?'':' · locked');}if(!ACTIVE_PHASES.has(state.phase)&&!canUseWorkout($('movement').value)){const first=Object.keys(MOVEMENTS).find(canUseWorkout);if(first){$('movement').value=first;resetMovement();}}if(!ACTIVE_PHASES.has(state.phase))controls(false);library.refreshAccess();}\r\nwindow.addEventListener('myr5:performance-progress',refreshWorkoutPaths);window.addEventListener('myr5:account-ready',refreshWorkoutPaths);refreshWorkoutPaths();\r\n$('variationName').addEventListener('click',()=>library.introduce($('movement').value));\r\nmountHomeCharacter();\r\nensureRetainedPower();\r\nmountPodPlaces(document.getElementById('view'));\r\nlet retainedCardObserver=null;\r\nconst attachRetainedPower=()=>{const card=document.querySelector('.myr5-companion-card');if(!card)return false;ensureRetainedPower(card);retainedCardObserver?.disconnect();return true;};\r\nif(!attachRetainedPower()&&typeof MutationObserver==='function'){retainedCardObserver=new MutationObserver(attachRetainedPower);retainedCardObserver.observe(document.body,{childList:true,subtree:true});}\r\nwindow.addEventListener('pagehide',()=>{avatarPowerToken++;avatarPower?.stop();avatarPower=null;avatarPowerCard=null;avatarPowerLoadingCard=null;});\r\nwindow.addEventListener('pageshow',event=>{if(event.persisted)ensureRetainedPower();});\r\n// #19: today's newest paused/interrupted workout is offered by a Continue popup on the pod page (never the quilt).\r\n// A saved manual row can start a new camera session without deleting its old local record.\r\nmountContinueWorkout({unfinished:()=>workouts.unfinished(),idle:()=>state.phase==='idle',label:row=>row.metadata?.name||MOVEMENTS[row.mode]?.name||row.mode,canContinue:row=>EXERCISES[row.mode]?.runner?{allowed:true,path:null,reason:null}:workoutPathAccess(row.mode),onContinue:row=>{\r\n if(!MOVEMENTS[row.mode])return;\r\n // Cool Cardio is open on every path: re-run it through the COOL CARDIO key (sets coolKey, restores the dial after).\r\n if(EXERCISES[row.mode]?.runner){$('coolCardio').click();return;}\r\n if(!canUseWorkout(row.mode)){status(workoutPathAccess(row.mode).reason);return;}\r\n $('movement').value=row.mode;window.dispatchEvent(new Event('myr5:exercise-selected'));resetMovement();\r\n void library.introduce(row.mode);\r\n}});\r\nwindow.addEventListener('myr5:ship-scene-ready',event=>{acceptShipRevealComplete(event);});\r\n// D30: the owner's achievements board. One hook: the Settings menu calls it now, the owner's portal (inverted triangle) later.\r\n// R-1017: achievements and the XP flight are one page; battle-pass-page.mjs owns myr5Menus.achievements.\r\nasync function showQuiltPortal(options){try{const {openQuiltPortal}=await import('./modules/portal/portal-entry.mjs');return !!await openQuiltPortal(options);}catch(error){console.warn('Quilt portal could not be opened.',error);return false;}}\r\nwindow.myr5Menus={...window.myr5Menus,portal:showQuiltPortal};\r\nlet starterPortalAttempted=false;\r\nfunction starterPortalReady(){\r\n const route=new URLSearchParams(location.search);\r\n // No isInstalled() gate: a browser visitor who has already finished setup (window.coachPlan set)\r\n // gets the same quilt-first landing as an installed one. New/signed-out visitors never reach this\r\n // point with a coachPlan, so they still see setup first.\r\n // A #route deep link (#pod, #ship, #food…) came for that scene; the quilt waits.\r\n return !route.has('panel')&&!hashRoute()&&!document.hidden&&!!window.coachPlan&&state.phase==='idle'&&document.body.dataset.cameraWorkout!=='true'&&document.body.dataset.tracking!=='true'&&document.body.dataset.screen!=='rest'&&!document.querySelector('dialog[open]');\r\n}\r\nwindow.addEventListener('myr5:coach-plan',()=>{\r\n if(starterPortalAttempted)return;\r\n starterPortalAttempted=true;\r\n if(starterPortalReady())void showQuiltPortal({shouldShow:starterPortalReady});\r\n});\r\n// D-ship-route: full-screen ship view, using the coach capsule renderer (loadCoachViewer below).\r\n// W2-2A: options pass through ({entrance:'always',hash:'#select'} is the oval's coach arrival).\r\nwindow.myr5Menus={...window.myr5Menus,ship:async(options={})=>{const {openShipView}=await import('./modules/ships/ship-view.mjs');return openShipView({loadCoachViewer,getBridge:shipViewBridge,ownedShipIds:shipOwnedShipIds,mountArrival:mountFirstShipArrival,...options});}};\r\n// App start: grant whatever the cached step snapshot already earned. Later step changes arrive as\r\n// myr5:account-progress (workout sync, breathing, meals, account refresh), which battle-pass.mjs listens for.\r\nsyncBattlePass();\r\nmountCoachOverlay();\r\n// Fruit-Ninja slice game over the camera for eligible martial reps (lazy; external to the core bundle).\r\n{let slice=null,loading=false,sliceGeneration=0;\r\n const eligible=()=>isMartialSliceExercise(EXERCISES[session.mode])?'martial':null;\r\n const drop=()=>{sliceGeneration++;slice?.stop();slice=null;};\r\n window.addEventListener('myr5:movement-configured',drop);\r\n window.addEventListener('myr5:pose',event=>{\r\n  if(!slice){const mode=eligible(),host=document.getElementById('coachOverlay');if(!mode||!host||loading||document.body.dataset.tracking!=='true')return;loading=true;const generation=sliceGeneration,exercise=session.mode;\r\n   import('./arcade/slice/camera-slice.mjs').then(m=>{if(!slice&&generation===sliceGeneration&&exercise===session.mode&&eligible()&&document.body.dataset.tracking==='true')slice=m.mountCameraSlice({host,mode,ownerId:pod?.flow?.active?.performanceOwner??null,sound:k=>physicalSound.play(k),onXp:n=>pod?.flow?.workout&&(pod.flow.workout.bonusXp=(pod.flow.workout.bonusXp||0)+n)});}).catch(()=>{}).finally(()=>{loading=false;});return;}\r\n  slice.pose(event.detail);});\r\n new MutationObserver(()=>{if(document.body.dataset.tracking!=='true'){drop();dropWorkoutEffects();}}).observe(document.body,{attributes:true,attributeFilter:['data-tracking']});\r\n window.myr5Slice={get active(){return slice},drop};}\r\nwindow.addEventListener('myr5:movement-configured',dropWorkoutEffects);\r\nwindow.addEventListener('myr5:account-ready',()=>{dropWorkoutEffects();syncRetainedPowerOwner();});\r\ndocument.addEventListener('click',event=>{const button=event.target?.closest?.('.workout-performance-controls button');if(button?.textContent?.trim()==='Break hold')invalidateWorkoutEffects();},true);\r\n// Cool Cardio ends on the counter tap or when Coach catches you: both FINISH the set and award the XP earned so far\r\n// (finishWorking, not the interrupt path). Under 15 s active there is nothing to award, so it is a plain stop.\r\nasync function finishEndless(){try{if(await pod?.finishWorking?.(state.motion,Date.now()))return;}catch(error){status(error.message);}stop();}\r\n// Cool Cardio runner: the corridor game over the camera (lazy; external to the core bundle). Body controls only; no other mode gets it.\r\n{let runner=null,loading=false;\r\n const eligible=()=>!!EXERCISES[session.mode]?.runner;\r\n const drop=()=>{runner?.stop();runner=null;};\r\n window.addEventListener('myr5:pose',event=>{\r\n  if(!runner){const host=document.getElementById('cameraWorkout');if(!eligible()||!host||loading||document.body.dataset.tracking!=='true')return;loading=true;\r\n   // The hidden portal board yields its context to the corridor (the coach stays); it rebuilds after the run.\r\n   import('./arcade/runner/runner.mjs').then(async m=>{const gpu=claimGraphics('runner',{keep:['coach']});await gpu.ready;if(runner||document.body.dataset.tracking!=='true'){gpu();return;}try{runner=m.mountRunner({host,Session:MovementSession,sound:k=>physicalSound.play(k),onXp:n=>pod?.flow?.workout&&(pod.flow.workout.bonusXp=(pod.flow.workout.bonusXp||0)+n),onCaught:()=>{void finishEndless();}});}catch(error){gpu();throw error;}const stop=runner.stop;runner.stop=()=>{stop();gpu();};}).catch(error=>console.warn('Runner could not start.',error)).finally(()=>{loading=false;});return;}\r\n  runner.pose(event.detail);});\r\n new MutationObserver(()=>{if(document.body.dataset.tracking!=='true')drop();}).observe(document.body,{attributes:true,attributeFilter:['data-tracking']});\r\n window.myr5Runner={get active(){return runner},drop};}\r\n\r\nlet cinematics={play(){}};\r\nlet optionalLoaded=false;\r\nlet optionalLoading=null;\r\nlet materialController=null;\r\nlet coachLoading=null;\r\nasync function loadCoachViewer(){\r\n if(!coachLoading){\r\n  const link=document.createElement('link');link.rel='stylesheet';link.href='/creature/phone.css';document.head.append(link);\r\n  coachLoading=import('./creature/assets/phone.js').catch(error=>{coachLoading=null;throw error;});\r\n }\r\n await coachLoading;\r\n}\r\n// Optional look/feel assets load on first user intent for everyone, guests included (no Coach Army gate).\r\nasync function loadOptionalMaterials(){\r\n if(optionalLoaded)return true;\r\n if(optionalLoading)return optionalLoading;\r\n optionalLoading=(async()=>{\r\n for(const href of ['/creature/phone.css','/creature/cinematics.css','/pod/hardware.css','/hardware-launch.css','/pocket-hardware.css','/hand-companion.css']){const link=document.createElement('link');link.rel='stylesheet';link.href=href;document.head.append(link);}\r\n for(const image of document.querySelectorAll('[data-optional-src]')) image.src=image.dataset.optionalSrc;\r\n await loadCoachViewer();\r\n const {initCinematics}=await import('./creature/cinematics.js');\r\n cinematics=initCinematics({voice});\r\n window.dispatchEvent(new Event('myr5:optional-materials-ready'));\r\n window.myr5Cinematics=cinematics;\r\n optionalLoaded=true;\r\n return true;\r\n })();\r\n try{return await optionalLoading;}finally{optionalLoading=null;}\r\n}\r\n// W2-2M #117: no \"Show my coach\" on the pod any more; the coach's reveal is the oval's ship intro (#select).\r\nfor(const id of ['coachLoading','restCoachLoading'])$(id).textContent='Call your coach with the oval on the portal.';\r\n$('openSettings').addEventListener('click',()=>{void loadOptionalMaterials();void mountPackLicenses({host:$('packLicenses')});},{once:true});\r\n$('openIdentity').addEventListener('click',()=>{void loadOptionalMaterials();},{once:true});\r\n$('manageMaterials').addEventListener('click',async()=>{\r\n const status=$('materialsStatus');\r\n // Material packs are account-owned grants: guests are asked to sign in, not to join anything.\r\n if(!window.myr5AuthenticatedAccount?.user?.id){status.textContent='Sign in to download materials you own.';return;}\r\n try { await loadOptionalMaterials(); const {mountMaterialControls}=await import('./modules/materials/material-controller.mjs'); $('materialControls').hidden=false; materialController??=mountMaterialControls({account:window.myr5AuthenticatedAccount,workoutOwner:pod.workoutOwner}); status.textContent=materialController?'Material controls ready.':'Material controls unavailable.'; }\r\n catch(error){status.textContent=error.message;}\r\n});\r\nwindow.myr5Cinematics=cinematics;\r\nwindow.addEventListener('pagehide',()=>materialController?.dispose(),{once:true});\r\n\r\nfunction manualSnapshot(){\r\n if(!manual)return state.motion;\r\n const kind=state.motion.kind,elapsed=manual.clock.sample(),value=['hold','pace'].includes(kind)?elapsed:manual.value;\r\n state.motion={...state.motion,tracking:true,elapsed,active:kind==='pace'?value:state.motion.active,totalHold:kind==='hold'?value:state.motion.totalHold,count:['reps','steps','jumps'].includes(kind)?value:state.motion.count,remaining:Math.max(0,pod.goal()-value),complete:value>=pod.goal(),message:'Manual workout · '+Math.floor(value)};\r\n return state.motion;\r\n}\r\nasync function manualTick(run){\r\n if(run!==generation||state.phase!=='manual'||!manual)return;\r\n try{const motion=manualSnapshot();renderMotion(motion);if(await pod.consume(motion,Date.now()))return;if(['hold','pace'].includes(motion.kind)&&performance.now()-manual.savedAt>=1000){await pod.saveManual(motion);manual.savedAt=performance.now();}manualFrame=requestAnimationFrame(()=>manualTick(run));}\r\n catch(error){generation++;release();controls(false);await pod.interruptCurrent(state.motion).catch(()=>{});state.phase='error';state.error=error.message;manual=null;status(error.message);}\r\n}\r\nfunction startManual(){\r\n const run=++generation;release();state.phase='manual-starting';controls(true);state.error=null;resetMovement();status('Starting manual workout…');$('detail').textContent='No camera · manual counter';\r\n return manualStartGate.run(async()=>{let ticket=null;try{ticket=await pod.beginSet(session.mode,{manual:true});if(run!==generation)return;const progress=ticket.progress||{},clock=new ManualActiveClock({now:()=>performance.now(),visible:()=>!document.hidden});clock.start(progress.elapsedSeconds);manual={value:Number(progress.value)||0,clock,savedAt:performance.now()};state.phase='manual';voice.say(MOVEMENTS[session.mode].name+' selected.',{key:'movement',interrupt:true});voice.say('Begin.',{key:'setup'});$('previewLabel').textContent='MANUAL';$('primary').tabIndex=0;$('primary').setAttribute('role',['hold','pace'].includes(state.motion.kind)?'timer':'button');$('primary').setAttribute('aria-label',['hold','pace'].includes(state.motion.kind)?'Manual workout timer':'Add one '+(state.motion.kind==='steps'?'step':state.motion.kind==='jumps'?'jump':'rep'));status(['hold','pace'].includes(state.motion.kind)?'Timer running. Stop to pause.':'Tap the counter or press Enter to add each movement.');manualTick(run);}\r\n catch(error){if(run!==generation)return;generation++;release();controls(false);if(ticket)await pod.interruptCurrent(state.motion).catch(()=>{});state.phase='error';state.error=error.message;manual=null;status(error.message);}});\r\n}\r\nasync function activateManual(){\r\n if(state.phase!=='manual'||!manual||['hold','pace'].includes(state.motion.kind)||pod?.canCount?.()===false)return;\r\n const run=generation;\r\n manual.value++;try{const motion=manualSnapshot();await pod.saveManual(motion);renderMotion(motion);await pod.consume(motion,Date.now());}catch(error){if(run!==generation)return;generation++;release();controls(false);await pod.interruptCurrent(state.motion).catch(()=>{});state.phase='error';state.error=error.message;manual=null;status(error.message);}\r\n}\r\nasync function pauseManualUi(){try{manualSnapshot();manual?.clock.pause();await pod.pauseManual(state.motion);generation++;release();controls(false);state.phase='idle';manual=null;status('Paused. Tap Begin to resume this workout.');$('detail').textContent='Manual workout paused on this device';window.myr5Routes?.home?.();}catch(error){status(error.message);}}\r\nfunction pauseManualWhenReady(){return manualStartGate.pause(()=>state.phase==='manual'?pauseManualUi():null);}\r\nconst workoutTools=document.createElement('div');workoutTools.className='workout-performance-controls';workoutTools.hidden=true;\r\nconst recoveryStatus=document.createElement('p');recoveryStatus.dataset.holdRecovery='';recoveryStatus.setAttribute('role','status');recoveryStatus.hidden=true;workoutTools.append(recoveryStatus);\r\nconst holdVariationLabel=document.createElement('label');holdVariationLabel.textContent='Hold difficulty ';holdVariationLabel.dataset.holdVariation='';const holdVariation=document.createElement('select');holdVariation.setAttribute('aria-label','Hold difficulty');for(const [value,label] of [['easy','Easy'],['medium','Medium'],['hard','Hard'],['expert','Expert']]){const option=document.createElement('option');option.value=value;option.textContent=label;holdVariation.append(option);}holdVariation.onchange=()=>{if(ACTIVE_PHASES.has(state.phase))return;pod?.switchDifficulty?.(holdVariation.value);};holdVariationLabel.append(holdVariation);workoutTools.append(holdVariationLabel);\r\nfor(const [label,action] of [['Finish working set',async()=>{try{if(state.phase==='manual')manualSnapshot();const saved=await pod?.finishWorking?.(state.motion,Date.now());if(saved===false){voice.say(pod?.flow?.workout?.instruction||'Nothing to save yet.',{interrupt:true});navigator.vibrate?.(60);}}catch(error){status(error.message);}}],['Break hold',()=>{pod?.breakHold?.();manual?.clock.pause();status('Hold paused. Shake out, then resume when ready.');}],['Resume hold',()=>{pod?.resumeHold?.();manual?.clock.resume();}],['More recovery',()=>pod?.extendHoldRecovery?.()]]){const button=document.createElement('button');button.type='button';button.textContent=label;button.onclick=action;workoutTools.append(button);}\r\nconst cardioLabel=document.createElement('label');cardioLabel.textContent='Cardio ';const cardioStyle=document.createElement('select');cardioStyle.setAttribute('aria-label','Cardio style');for(const [value,label] of [['gentle','Gentle cardio'],['sprint','Sprint intervals']]){const option=document.createElement('option');option.value=value;option.textContent=label;cardioStyle.append(option);}cardioStyle.onchange=()=>pod?.setCardioStyle?.(cardioStyle.value);cardioLabel.append(cardioStyle);$('bar').after(workoutTools);$('roundControl').append(cardioLabel);\r\n$('primary').addEventListener('pointerdown',event=>{if(state.phase==='manual'){event.preventDefault();void activateManual();}});\r\n$('primary').addEventListener('keydown',event=>{if(state.phase==='manual'&&(event.key==='Enter'||event.key===' ')){event.preventDefault();void activateManual();}});\r\nvoid mountArmieInboxUI().catch(()=>{}); // D23 inbox; best-effort so a failure here never blocks the workout.\r\n","apple-basic-share-config.mjs":"// Public Apple basic app, installed beside the full MYR5 app from its own origin.\r\n// Share only this basic URL inside the full app; the full-app install link stays at website endings.\r\nexport const APPLE_BASIC_SHARE_URL = 'https://fitness.mominc.online';\r\n","apple-basic-share.mjs":"// Settings \"Share Apple basic\": navigator.share when present, clipboard copy otherwise. Hidden until\r\n// APPLE_BASIC_SHARE_URL is configured.\r\nimport {APPLE_BASIC_SHARE_URL} from './apple-basic-share-config.mjs';\r\n\r\nconst TEXT='Try MOM Inc Coach — the Apple basic version.';\r\n\r\nexport async function shareAppleBasic(url=APPLE_BASIC_SHARE_URL,nav=globalThis.navigator){\r\n if(!url)return 'unavailable';\r\n if(nav?.share){\r\n  try{await nav.share({title:'MOM Inc Coach',text:TEXT,url});return 'shared';}\r\n  catch(error){if(error?.name==='AbortError')return 'cancelled';}\r\n }\r\n try{await nav.clipboard.writeText(url);return 'copied';}catch{return 'failed';}\r\n}\r\n\r\nconst MESSAGES={shared:'Shared.',copied:'Link copied. Paste it to a friend.',cancelled:'',failed:'Could not share or copy the link.',unavailable:''};\r\n\r\nexport function mountAppleBasicShare(settings,{url=APPLE_BASIC_SHARE_URL,nav=globalThis.navigator}={}){\r\n if(!url)return null;\r\n const wrap=document.createElement('div');wrap.className='settings-share';\r\n const button=document.createElement('button');button.type='button';button.textContent='Share Apple basic';\r\n const status=document.createElement('p');status.setAttribute('role','status');\r\n button.onclick=async()=>{button.disabled=true;const result=await shareAppleBasic(url,nav);if(['shared','copied'].includes(result))void import('./modules/vault/vault-store.mjs').then(m=>m.bump('share')).catch(()=>{});status.textContent=MESSAGES[result];button.disabled=false;};\r\n wrap.append(button,status);settings.append(wrap);\r\n return wrap;\r\n}\r\n","arcade/hold/blizzard.mjs":"// Blizzard hold model and Canvas2D renderer. Hold eligibility is delegated to\r\n// createEcosystem so this style shares the exact stillness, movement and stale gates.\r\nimport { createEcosystem, STILL_SECONDS } from './ecosystem.mjs';\r\nimport { supportContacts } from '../power/power.mjs';\r\n\r\nexport const MAX_ICE_EDGES = 20;\r\nexport const MAX_SNOW = 48;\r\nconst CONFIDENCE = 0.5;\r\nconst GRAPH = [\r\n  [11, 12], [11, 13], [13, 15], [12, 14], [14, 16],\r\n  [11, 23], [12, 24], [23, 24],\r\n  [23, 25], [25, 27], [27, 29], [29, 31],\r\n  [24, 26], [26, 28], [28, 30], [30, 32],\r\n];\r\n\r\nconst clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\r\nconst pointAt = (points, i) => Array.isArray(points) ? points[i] : points?.[i] ?? points?.[String(i)];\r\n\r\nfunction visiblePoints(points, w, h) {\r\n  const out = new Map();\r\n  for (let i = 0; i <= 32; i++) {\r\n    const p = pointAt(points, i);\r\n    const visibility = Number(p?.visibility ?? p?.score ?? p?.confidence);\r\n    if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y) || !Number.isFinite(visibility) || visibility < CONFIDENCE || p.x < 0 || p.x > 1 || p.y < 0 || p.y > 1) continue;\r\n    out.set(i, { x: Math.round(p.x * w), y: Math.round(p.y * h) });\r\n  }\r\n  return out;\r\n}\r\n\r\nfunction seeded(seed = 1) {\r\n  let s = seed | 0;\r\n  return () => { s = s + 0x6D2B79F5 | 0; let t = Math.imul(s ^ s >>> 15, 1 | s); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; };\r\n}\r\n\r\nfunction bodyBounds(points, w, h) {\r\n  const joints = [...points.entries()].filter(([i]) => [11, 12, 13, 14, 15, 16, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32].includes(i)).map(([, p]) => p);\r\n  if (!joints.length) return { x: w / 2, y: h / 2, rx: w * 0.12, ry: h * 0.2 };\r\n  const xs = joints.map(p => p.x), ys = joints.map(p => p.y);\r\n  const left = Math.min(...xs), right = Math.max(...xs), top = Math.min(...ys), bottom = Math.max(...ys);\r\n  return { x: (left + right) / 2, y: (top + bottom) / 2, rx: clamp((right - left) * 0.34, 12, w * 0.14), ry: clamp((bottom - top) * 0.34, 18, h * 0.14) };\r\n}\r\n\r\nfunction graphEdges(points, contacts, elapsed) {\r\n  const support = new Set(contacts.filter(c => Number.isInteger(c.index) && points.has(c.index)).map(c => c.index));\r\n  if (!support.size) return [];\r\n  const adj = new Map();\r\n  const valid = GRAPH.filter(([a, b]) => points.has(a) && points.has(b));\r\n  for (const [a, b] of valid) {\r\n    if (!adj.has(a)) adj.set(a, []); if (!adj.has(b)) adj.set(b, []);\r\n    adj.get(a).push(b); adj.get(b).push(a);\r\n  }\r\n  const distance = new Map([...support].map(i => [i, 0])), queue = [...support];\r\n  for (let q = 0; q < queue.length; q++) {\r\n    const node = queue[q];\r\n    for (const next of adj.get(node) || []) if (!distance.has(next)) { distance.set(next, distance.get(node) + 1); queue.push(next); }\r\n  }\r\n  const out = [];\r\n  for (const [a, b] of valid) {\r\n    if (!distance.has(a) || !distance.has(b)) continue;\r\n    const rank = Math.min(distance.get(a), distance.get(b));\r\n    const delay = rank * 0.88;\r\n    const growth = clamp((elapsed - delay + 0.05) / 0.72, 0, 1);\r\n    if (growth <= 0) continue;\r\n    const from = distance.get(a) <= distance.get(b) ? a : b;\r\n    const to = from === a ? b : a;\r\n    const p1 = points.get(from), p2 = points.get(to);\r\n    out.push({ from, to, x1: p1.x, y1: p1.y, x2: p2.x, y2: p2.y, growth, alpha: 0.72 + growth * 0.18 });\r\n  }\r\n  return out.slice(0, MAX_ICE_EDGES);\r\n}\r\n\r\nfunction readReducedMotion() {\r\n  try { return !!globalThis.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches; } catch { return false; }\r\n}\r\n\r\nexport function createBlizzard({ w = 360, h = 640, seed = 1, stillSeconds = STILL_SECONDS } = {}) {\r\n  const stillness = createEcosystem({ w, h, seed, spawnEntities: false, stillSeconds });\r\n  const reducedMotion = readReducedMotion();\r\n  const rand = seeded(seed ^ 0xB11A2D);\r\n  const count = reducedMotion ? 16 : 32;\r\n  const snow = Array.from({ length: Math.min(MAX_SNOW, count) }, () => ({ x: 0, y: 0, size: 1 + Math.floor(rand() * 3), alpha: 0 }));\r\n  const paths = snow.map(() => ({ phase: rand() * Math.PI * 2, rx: 0.35 + rand() * 0.75, ry: 0.35 + rand() * 0.8, speed: (2.8 + rand() * 2.8) * (reducedMotion ? 0.28 : 1), direction: rand() < 0.5 ? -1 : 1, alpha: 0.3 + rand() * 0.42 }));\r\n  const state = { w, h, phase: 'waiting', stillSeconds: 0, still: stillSeconds, iceEdges: [], snow };\r\n  let currentPoints = new Map(), currentContacts = [], origin = { x: w / 2, y: h / 2, rx: w * 0.12, ry: h * 0.2 };\r\n  let elapsed = 0, fadeSpeed = reducedMotion ? 0.65 : 1.35;\r\n\r\n  function placeSnow(alphaScale = 1) {\r\n    for (let i = 0; i < snow.length; i++) {\r\n      const path = paths[i], angle = path.phase + elapsed * path.speed * path.direction;\r\n      snow[i].x = Math.round(origin.x + Math.cos(angle) * origin.rx * path.rx);\r\n      snow[i].y = Math.round(origin.y + Math.sin(angle * 1.17) * origin.ry * path.ry);\r\n      snow[i].alpha = Math.max(0, Math.min(0.72, alphaScale * path.alpha));\r\n    }\r\n  }\r\n\r\n  function fade() {\r\n    if (state.phase !== 'growing') return;\r\n    state.phase = 'retreating';\r\n    // Preserve coordinates during the departure fade.\r\n  }\r\n\r\n  function clearVisuals() {\r\n    state.iceEdges.length = 0;\r\n    for (const flake of snow) flake.alpha = 0;\r\n    state.phase = 'waiting';\r\n    state.stillSeconds = stillness.state.stillSeconds;\r\n  }\r\n\r\n  function pose({ points, now, validHold, mode } = {}) {\r\n    const wasGrowing = state.phase === 'growing';\r\n    stillness.pose({ points, now, validHold });\r\n    state.stillSeconds = stillness.state.stillSeconds;\r\n    currentPoints = visiblePoints(points, w, h);\r\n    if (validHold && currentPoints.size) origin = bodyBounds(currentPoints, w, h);\r\n    const ready = stillness.state.phase === 'growing';\r\n\r\n    if (ready) {\r\n      if (!wasGrowing) { state.iceEdges.length = 0; state.phase = 'growing'; }\r\n      currentContacts = supportContacts(mode, points, w, h);\r\n      const age = Math.max(0, state.stillSeconds - stillSeconds);\r\n      state.iceEdges = graphEdges(currentPoints, currentContacts, age);\r\n      placeSnow(Math.min(1, 0.38 + age * (reducedMotion ? 0.1 : 0.18)));\r\n    } else {\r\n      currentContacts = [];\r\n      if (wasGrowing) fade();\r\n      if (!validHold && state.phase === 'waiting') clearVisuals();\r\n    }\r\n    return state;\r\n  }\r\n\r\n  function step(dt = 0) {\r\n    const raw = Number.isFinite(dt) && dt > 0 ? dt : 0;\r\n    stillness.step(raw);\r\n    elapsed += Math.min(0.05, raw) * (reducedMotion ? 0.35 : 1);\r\n    state.stillSeconds = stillness.state.stillSeconds;\r\n    if (state.phase === 'growing' && stillness.state.phase !== 'growing') fade();\r\n    if (state.phase === 'growing') {\r\n      placeSnow(Math.min(1, 0.38 + Math.max(0, state.stillSeconds - stillSeconds) * (reducedMotion ? 0.1 : 0.18)));\r\n    } else if (state.phase === 'retreating') {\r\n      for (const edge of state.iceEdges) edge.alpha = Math.max(0, edge.alpha - fadeSpeed * Math.min(0.05, raw));\r\n      for (const flake of snow) flake.alpha = Math.max(0, flake.alpha - fadeSpeed * Math.min(0.05, raw));\r\n      if (!state.iceEdges.some(e => e.alpha > 0.01) && !snow.some(f => f.alpha > 0.01)) clearVisuals();\r\n    }\r\n    return state;\r\n  }\r\n\r\n  function reset() {\r\n    stillness.reset(); state.phase = 'waiting'; state.stillSeconds = 0; state.iceEdges.length = 0;\r\n    for (const flake of snow) { flake.x = 0; flake.y = 0; flake.alpha = 0; }\r\n    currentPoints.clear(); currentContacts = []; elapsed = 0; origin = { x: w / 2, y: h / 2, rx: w * 0.12, ry: h * 0.2 };\r\n    return state;\r\n  }\r\n\r\n  return { state, pose, step, reset };\r\n}\r\n\r\nconst ASSET = '/arcade/hold/assets/19_freezing_spritesheet.png';\r\nlet freezeImage = null, spriteCache = new Map(), loadStarted = false;\r\nfunction preload() {\r\n  if (loadStarted || typeof Image === 'undefined') return;\r\n  loadStarted = true;\r\n  const image = new Image();\r\n  image.onload = () => {\r\n    if (typeof document === 'undefined') return;\r\n    for (let frame = 0; frame < 10; frame++) {\r\n      // FreeFX frames are 100px cells with a small, consistent transparent border.\r\n      // Inspect alpha in the browser so the original pixels remain the source of truth.\r\n      const probe = document.createElement('canvas'); probe.width = probe.height = 100;\r\n      const pctx = probe.getContext('2d', { willReadFrequently: true }); if (!pctx) continue;\r\n      pctx.drawImage(image, frame * 100, 0, 100, 100, 0, 0, 100, 100);\r\n      let pixels;\r\n      try { pixels = pctx.getImageData(0, 0, 100, 100).data; } catch { continue; }\r\n      let left = 100, top = 100, right = -1, bottom = -1;\r\n      for (let y = 0; y < 100; y++) for (let x = 0; x < 100; x++) {\r\n        if (pixels[(y * 100 + x) * 4 + 3] === 0) continue;\r\n        if (x < left) left = x; if (x > right) right = x;\r\n        if (y < top) top = y; if (y > bottom) bottom = y;\r\n      }\r\n      if (right < left || bottom < top) continue;\r\n      const sw = right - left + 1, sh = bottom - top + 1;\r\n      const scale = 52 / Math.max(sw, sh), dw = Math.max(1, Math.round(sw * scale)), dh = Math.max(1, Math.round(sh * scale));\r\n      const canvas = document.createElement('canvas'); canvas.width = canvas.height = 64;\r\n      const g = canvas.getContext('2d'); if (!g) continue;\r\n      g.imageSmoothingEnabled = false;\r\n      g.drawImage(image, frame * 100 + left, top, sw, sh, Math.floor((64 - dw) / 2), Math.floor((64 - dh) / 2), dw, dh);\r\n      spriteCache.set(frame, canvas);\r\n    }\r\n    freezeImage = image;\r\n  };\r\n  image.onerror = () => { freezeImage = null; };\r\n  image.src = ASSET;\r\n}\r\n\r\nfunction drawSnow(ctx, state, start, end) {\r\n  for (let i = start; i < end; i++) {\r\n    const flake = state.snow[i]; if (!flake || flake.alpha <= 0.01) continue;\r\n    ctx.globalAlpha = flake.alpha;\r\n    ctx.fillStyle = i % 2 ? '#b8f6ff' : '#f3fdff';\r\n    ctx.fillRect(Math.round(flake.x), Math.round(flake.y), flake.size, flake.size);\r\n  }\r\n}\r\n\r\nfunction drawIceEdge(ctx, edge) {\r\n  const dx = edge.x2 - edge.x1, dy = edge.y2 - edge.y1, length = Math.hypot(dx, dy), growth = clamp(edge.growth, 0, 1);\r\n  const visibleLength = length * growth, steps = Math.max(1, Math.ceil(visibleLength / 3));\r\n  ctx.globalAlpha = clamp(edge.alpha, 0, 1);\r\n  for (let i = 0; i <= steps; i++) {\r\n    const t = length <= 0 ? 0 : Math.min(growth, i * 3 / length);\r\n    const x = Math.round(edge.x1 + dx * t), y = Math.round(edge.y1 + dy * t), size = i % 3 === 0 ? 3 : 2;\r\n    ctx.fillStyle = i % 2 ? '#6ddfff' : '#d8faff';\r\n    ctx.fillRect(x - 1, y - 1, size, size);\r\n  }\r\n}\r\n\r\nfunction drawContactAccent(ctx, state, edge) {\r\n  if (!freezeImage || edge.growth <= 0) return;\r\n  const frame = Math.floor(Math.max(0, state.stillSeconds - (state.still ?? STILL_SECONDS)) * 2) % 10;\r\n  const sprite = spriteCache.get(frame);\r\n  if (!sprite) return;\r\n  ctx.globalAlpha = Math.min(0.55, edge.growth * 0.5, clamp(edge.alpha, 0, 1) * 0.6);\r\n  ctx.imageSmoothingEnabled = false;\r\n  ctx.drawImage(sprite, Math.round(edge.x1 - 7), Math.round(edge.y1 - 7), 14, 14);\r\n}\r\n\r\nexport function renderBlizzard(ctx, state) {\r\n  if (!ctx || !state) return;\r\n  preload();\r\n  ctx.imageSmoothingEnabled = false;\r\n  ctx.globalCompositeOperation = 'source-over';\r\n  const snow = Array.isArray(state.snow) ? state.snow : [];\r\n  drawSnow(ctx, state, 0, Math.floor(snow.length / 2));\r\n  const accented = new Set();\r\n  for (const edge of Array.isArray(state.iceEdges) ? state.iceEdges : []) {\r\n    if (!Number.isFinite(edge.x1) || !Number.isFinite(edge.y1) || !Number.isFinite(edge.x2) || !Number.isFinite(edge.y2)) continue;\r\n    if (!accented.has(edge.from)) { drawContactAccent(ctx, state, edge); accented.add(edge.from); }\r\n    drawIceEdge(ctx, edge);\r\n  }\r\n  drawSnow(ctx, state, Math.floor(snow.length / 2), snow.length);\r\n  ctx.globalAlpha = 1;\r\n}\r\n","arcade/hold/camera-hold.mjs":"import {createEcosystem} from './ecosystem.mjs';\r\nimport {renderEcosystem} from './render.mjs';\r\nimport {createBlizzard,renderBlizzard} from './blizzard.mjs';\r\nimport {renderPower,preloadAura} from '../power/power.mjs';\r\nimport {createGrowth,AURA_TUNING} from '../power/aura-growth.mjs';\r\nexport {preloadAuraForMode} from '../power/power.mjs';\r\nconst AURA_LAYER_OPACITY=AURA_TUNING.LAYER_OPACITY;\r\nimport {EFFECT_OPTION_BY_ID,effectGroupForExercise,readEffectChoices,resolveExerciseEffect} from '../power/aura-options.mjs';\r\nimport {createOverlayCanvas,mapPointsToOverlay,effectQuality} from '../workout-effects.mjs';\r\nimport {createAuraBody} from '../power/aura-body.mjs';\r\n\r\nconst LOGICAL_WIDTH=360;\r\nfunction randomFor(seed=1){let value=(Number(seed)>>>0)||0x9e3779b9;return()=>{value^=value<<13;value^=value>>>17;value^=value<<5;return(value>>>0)/0x100000000;};}\r\nexport function mountCameraHold({host,sound=()=>{},onXp=()=>{},seed=Date.now(),style='living',mode=null,quality=effectQuality}={}){\r\n if(!host)throw new TypeError('A camera overlay host is required.');\r\n const holdStyle=style==='blizzard'?'blizzard':'living';\r\n const layer=createOverlayCanvas(host,'hold-ecosystem-canvas',{opacity:AURA_LAYER_OPACITY,max:1}),canvas=layer.canvas,ctx=canvas.getContext('2d',{alpha:true});\r\n const growth=createGrowth();let poseAt=-Infinity,holdValid=false;\r\n // Sheet auras on a hold share the power layer's body anchoring: filtered + predicted points, glow, fade out.\r\n const body=createAuraBody({host,quality});const aura={w:LOGICAL_WIDTH,h:1,route:'aura',active:false,level:0,speed:0,pulse:0,contacts:[],points:[],time:0,effect:null};\r\n let engine=null,w=LOGICAL_WIDTH,h=1,raf=0,lastFrame=0,lastPose=null,disposed=false,resizeObserver=null,selectedMode=mode,effectChoices=readEffectChoices();\r\n const random=randomFor(seed);let selectedEffect=resolveExerciseEffect(selectedMode,effectChoices,random);preloadAura(selectedEffect);\r\n const createEngine=()=>holdStyle==='blizzard'?createBlizzard({w,h,seed,stillSeconds:AURA_TUNING.HOLD_FIRST_S}):createEcosystem({w,h,seed,stillSeconds:AURA_TUNING.HOLD_FIRST_S,ecology:EFFECT_OPTION_BY_ID.get(selectedEffect)?.ecology??null});\r\n function resize(){\r\n  if(disposed)return;const rect=host.getBoundingClientRect();if(!(rect.width>0&&rect.height>0))return;\r\n  layer.resize();const nextH=Math.max(1,Math.round(LOGICAL_WIDTH*rect.height/rect.width));\r\n  const changed=!engine||nextH!==h;w=LOGICAL_WIDTH;h=nextH;\r\n  if(changed){engine?.reset();engine=createEngine();}\r\n  ctx.setTransform(canvas.width/w,0,0,canvas.height/h,0,0);ctx.imageSmoothingEnabled=false;\r\n }\r\n const geometryOf=detail=>({videoWidth:detail.width,videoHeight:detail.height,hostWidth:w,hostHeight:h,mirrored:detail.mirrored});\r\n function map(detail){return mapPointsToOverlay(detail.points,geometryOf(detail));}\r\n function paint(now){\r\n  if(disposed)return;const dt=lastFrame?Math.max(0,(now-lastFrame)/1000):0;if(lastFrame)quality.frame(now-lastFrame);lastFrame=now;\r\n  engine.step(dt);growth.step(dt);ctx.setTransform(canvas.width/w,0,0,canvas.height/h,0,0);ctx.clearRect(0,0,w,h);\r\n  const option=EFFECT_OPTION_BY_ID.get(selectedEffect),fade=holdStyle==='blizzard'\r\n    ? Math.max(0,...(engine.state.iceEdges??[]).map(edge=>edge.alpha??0),...(engine.state.snow??[]).map(flake=>flake.alpha??0))\r\n    : Math.max(0,...(engine.state.entities??[]).map(entity=>entity.alpha??0));\r\n  if(option?.ecology)renderEcosystem(ctx,engine.state);\r\n  else if(holdStyle==='blizzard'&&selectedEffect==='blizzard')renderBlizzard(ctx,engine.state);\r\n  else if(option?.asset){\r\n   // Sheet auras grow on the shared hold clock (visible at once), not on the slow ecology spawn; they fade out\r\n   // (~250 ms) when the hold breaks or tracking stops instead of vanishing.\r\n   const live=holdValid&&now-poseAt<1000;\r\n   if(live){aura.active=true;aura.level=growth.state.level;aura.speed=growth.state.speed;aura.effect=selectedEffect;}\r\n   aura.w=w;aura.h=h;aura.time=now/1000;\r\n   const points=body.points(now),fadeAlpha=body.draw(now,live?aura:null,points);\r\n   if(fadeAlpha>0&&aura.active)renderPower(ctx,aura,{points,alpha:fadeAlpha});else if(fadeAlpha<=0)aura.active=false;\r\n  }\r\n  if(!option?.asset&&body.alpha>0)body.draw(now,null,body.points(now));\r\n  raf=requestAnimationFrame(paint);\r\n }\r\n resize();\r\n if(typeof ResizeObserver==='function'){resizeObserver=new ResizeObserver(resize);resizeObserver.observe(host);}else window.addEventListener('resize',resize);\r\n raf=requestAnimationFrame(paint);\r\n function pose(detail={}){\r\n  if(disposed)return;\r\n  resize();const points=map(detail),nextMode=detail.workout?.mode??selectedMode;\r\n  if(nextMode!==selectedMode){selectedMode=nextMode;selectedEffect=resolveExerciseEffect(selectedMode,effectChoices,random);preloadAura(selectedEffect);engine?.reset();engine=createEngine();}\r\n  lastPose={points,now:detail.now,validHold:!!detail.validHold,mode:selectedMode};\r\n  body.pose(points,Number.isFinite(detail.frameMs)?detail.frameMs:detail.now,detail.mask,geometryOf(detail));\r\n  poseAt=performance.now();holdValid=lastPose.validHold;\r\n  if(holdValid)growth.update({now:detail.now,points,kind:'hold',valid:true});else growth.reset();\r\n  engine.pose(lastPose);\r\n }\r\n function invalidate(){holdValid=false;growth.reset();if(!disposed&&engine){lastPose={points:lastPose?.points,now:lastPose?.now,validHold:false};engine.pose({validHold:false});}}\r\n function choiceChanged(event){if(disposed)return;const group=effectGroupForExercise(selectedMode),before=group?effectChoices[group]:null;effectChoices=readEffectChoices();if(event?.detail?.group&&event.detail.group!==group)return;if(!event?.detail?.group&&group&&before===effectChoices[group])return;const next=resolveExerciseEffect(selectedMode,effectChoices,random);if(next===selectedEffect)return;selectedEffect=next;preloadAura(next);engine?.reset();engine=createEngine();if(lastPose)engine.pose(lastPose);}\r\n globalThis.addEventListener?.('myr5:exercise-effect-choice-change',choiceChanged);\r\n const storageChanged=event=>{if(event?.key==='myr5-exercise-effect-choices-v1')choiceChanged();};\r\n globalThis.addEventListener?.('storage',storageChanged);\r\n function stop(){if(disposed)return;disposed=true;cancelAnimationFrame(raf);resizeObserver?.disconnect();window.removeEventListener('resize',resize);globalThis.removeEventListener?.('myr5:exercise-effect-choice-change',choiceChanged);globalThis.removeEventListener?.('storage',storageChanged);engine?.reset();body.dispose();layer.dispose();}\r\n return {get engine(){return engine;},pose,stop,invalidate,get effect(){return selectedEffect;}};\r\n}\r\n","arcade/hold/ecosystem.mjs":"// Deterministic, renderer-independent ecology engine for tracked workout holds.\r\n// The small PRNG is adapted from arcade/slice/core.mjs so this feature adds no dependency.\r\nexport const STILL_SECONDS = 5;\r\nexport const MAX_POSE_GAP_MS = 1000;\r\nexport const MIN_VISIBILITY = 0.5;\r\nexport const MAX_ENTITIES = 36;\r\nexport const MAX_DEBRIS = 96;\r\nexport const CRACK_SECONDS = 0.3;\r\n\r\nconst clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\r\nfunction rng(seed = 1) {\r\n  return () => { seed |= 0; seed = seed + 0x6D2B79F5 | 0; let t = Math.imul(seed ^ seed >>> 15, 1 | seed); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t; return ((t ^ t >>> 14) >>> 0) / 4294967296; };\r\n}\r\nconst PLANTS = ['fern', 'vine', 'flower', 'mushroom', 'grass', 'reed'];\r\nconst ANIMALS = ['rabbit', 'fox', 'bear', 'deer', 'wolf', 'boar'];\r\nconst MINERALS = ['rock', 'crystal'];\r\nconst COMPARABLE = [11, 12, 13, 14, 15, 16, 23, 24, 25, 26, 27, 28];\r\nconst TORSO = [11, 12, 23, 24];\r\nconst LIMBS = [13, 14, 15, 16, 25, 26, 27, 28];\r\nconst BODY_ATTACHMENTS = [0, 11, 12, 13, 14, 15, 16];\r\n\r\nfunction readPoint(points, i) { return Array.isArray(points) ? points[i] : points?.[i] ?? points?.[String(i)]; }\r\nfunction normalized(points, w, h, indices = COMPARABLE) {\r\n  const out = new Map();\r\n  for (const i of indices) {\r\n    const p = readPoint(points, i), visibility = Number(p?.visibility ?? p?.score ?? p?.confidence);\r\n    if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y) || !Number.isFinite(visibility) || visibility < MIN_VISIBILITY) continue;\r\n    out.set(i, { x: p.x * w, y: p.y * h });\r\n  }\r\n  return out;\r\n}\r\nfunction torsoScale(points) {\r\n  const pairs = [[11, 12], [23, 24], [11, 23], [12, 24]];\r\n  const lengths = pairs.map(([a, b]) => points.has(a) && points.has(b) ? Math.hypot(points.get(a).x - points.get(b).x, points.get(a).y - points.get(b).y) : 0).filter(n => n > 0);\r\n  if (!lengths.length) return 0;\r\n  // Median-ish robust estimate: vertical torso length and shoulder/hip widths all describe body scale.\r\n  lengths.sort((a, b) => a - b);\r\n  return lengths[Math.floor(lengths.length / 2)] || lengths[0];\r\n}\r\nfunction enoughPose(points) {\r\n  return TORSO.filter(i => points.has(i)).length >= 2 && LIMBS.filter(i => points.has(i)).length >= 2 && points.size >= 4;\r\n}\r\n\r\nexport function createEcosystem({ w = 360, h = 640, seed = 1, onEvent = () => {}, spawnEntities = true, ecology = null, stillSeconds = STILL_SECONDS } = {}) {\r\n  const STILL = stillSeconds; // default 5 s; the camera layer passes a short first-growth time so something shows at once\r\n  const rand = rng(seed), choose = list => list[Math.floor(rand() * list.length)];\r\n  const state = { w, h, phase: 'waiting', stillSeconds: 0, groundY: h - 6, entities: [], debris: [] };\r\n  let reference = null, previous = null, lastTimestamp = null, poseAge = Infinity;\r\n  let nextGrowth = STILL, nextId = 1, elapsed = 0, growthOrdinal = 0;\r\n\r\n  const emit = (type, payload) => { try { onEvent(type, payload); } catch { /* cosmetic observers cannot break tracking */ } };\r\n  function beginDeparture() {\r\n    let changed = false;\r\n    for (const e of state.entities) {\r\n      if (['retreating', 'fleeing', 'cracking'].includes(e.phase)) continue;\r\n      e.anchor = null;\r\n      e.phase = e.kind === 'plant' ? 'retreating' : e.kind === 'animal' ? 'fleeing' : 'cracking';\r\n      e.phaseTime = 0;\r\n      if (e.kind === 'animal') e.facing = e.x < w / 2 ? -1 : 1;\r\n      changed = true;\r\n    }\r\n    if (changed) emit('retreat', { reason: 'movement-or-invalid-pose' });\r\n    state.phase = changed || state.entities.some(e => ['retreating', 'fleeing', 'cracking'].includes(e.phase)) ? 'retreating' : 'waiting';\r\n  }\r\n  function clearEligibility({ depart = true } = {}) {\r\n    state.stillSeconds = 0;\r\n    reference = previous = null;\r\n    lastTimestamp = null;\r\n    poseAge = Infinity;\r\n    nextGrowth = STILL;\r\n    if (depart) beginDeparture(); else state.phase = 'waiting';\r\n  }\r\n  function getGround(points) {\r\n    const lower = [27, 28, 29, 30, 31, 32].map(i => readPoint(points, i))\r\n      .filter(p => p && Number.isFinite(p.x) && Number.isFinite(p.y) && Number(p.visibility ?? p.score ?? p.confidence) >= MIN_VISIBILITY);\r\n    if (!lower.length) return h - 6;\r\n    return clamp(Math.max(...lower.map(p => p.y * h)) + 2, h * 0.35, h - 2);\r\n  }\r\n  function pickAnchor(points) {\r\n    const choices = BODY_ATTACHMENTS.map(i => [i, readPoint(points, i)])\r\n      .filter(([, p]) => p && Number.isFinite(p.x) && Number.isFinite(p.y) && Number(p.visibility ?? p.score ?? p.confidence) >= MIN_VISIBILITY);\r\n    if (choices.length && rand() < 0.65) {\r\n      const [index, p] = choose(choices);\r\n      return { type: 'joint', index, dx: (rand() - 0.5) * 18, dy: (rand() - 0.5) * 12, targetX: p.x * w, targetY: p.y * h };\r\n    }\r\n    return { type: 'ground', x: w * (0.12 + rand() * 0.76) };\r\n  }\r\n  function anchorTarget(anchor, points) {\r\n    if (anchor?.type === 'joint') {\r\n      const p = readPoint(points, anchor.index);\r\n      if (p && Number.isFinite(p.x) && Number.isFinite(p.y) && Number(p.visibility ?? p.score ?? p.confidence) >= MIN_VISIBILITY) {\r\n        anchor.targetX = p.x * w; anchor.targetY = p.y * h;\r\n      }\r\n      return { x: anchor.targetX + anchor.dx, y: anchor.targetY + anchor.dy };\r\n    }\r\n    return { x: anchor?.x ?? w / 2, y: state.groundY };\r\n  }\r\n  function spawnEntity(points) {\r\n    if (state.entities.length >= MAX_ENTITIES) return;\r\n    const anchor = pickAnchor(points), target = anchorTarget(anchor, points), roll = rand();\r\n    const kind = ['plant', 'animal', 'mineral'].includes(ecology?.kind) ? ecology.kind : roll < 0.57 ? 'plant' : roll < 0.78 ? 'animal' : 'mineral';\r\n    const variants = kind === 'plant' ? PLANTS : kind === 'animal' ? ANIMALS : MINERALS;\r\n    const variant = kind === ecology?.kind && variants.includes(ecology?.variant) ? ecology.variant : choose(variants);\r\n    const e = {\r\n      id: nextId++, kind, variant, ...(kind === 'mineral' && ['blue','ice','red','green','gold','purple'].includes(ecology?.palette) ? { palette: ecology.palette } : {}), phase: 'landing', x: target.x, y: target.y - 22,\r\n      size: 16 + Math.floor(rand() * 37), facing: rand() < 0.5 ? -1 : 1,\r\n      growth: 0, alpha: 0.2, phaseTime: 0, anchor,\r\n    };\r\n    e._targetY = target.y;\r\n    state.entities.push(e);\r\n    emit('growth', { id: e.id, kind, variant });\r\n  }\r\n  function movementDetected(current, now) {\r\n    if (!reference || !previous || lastTimestamp == null) return false;\r\n    const comparable = COMPARABLE.filter(i => current.has(i) && previous.has(i) && reference.has(i));\r\n    if (comparable.length < 4 || TORSO.filter(i => comparable.includes(i)).length < 2 || LIMBS.filter(i => comparable.includes(i)).length < 2) return null;\r\n    const scale = Math.max(1, torsoScale(current));\r\n    const prevScale = Math.max(1, torsoScale(previous));\r\n    const norm = (a, b, s) => Math.hypot(a.x - b.x, a.y - b.y) / s;\r\n    const dt = (now - lastTimestamp) / 1000;\r\n    for (const i of comparable) {\r\n      const p = current.get(i), q = previous.get(i), r = reference.get(i);\r\n      if (!p || !q || !r) continue;\r\n      const delta = norm(p, q, (scale + prevScale) / 2);\r\n      if ((delta > 0.04 && delta / dt > 0.8) || norm(p, r, scale) > 0.15) return true;\r\n    }\r\n    return false;\r\n  }\r\n  function syncAnchors(points) {\r\n    for (const e of state.entities) {\r\n      if (!e.anchor || ['retreating', 'fleeing', 'cracking'].includes(e.phase)) continue;\r\n      const target = anchorTarget(e.anchor, points);\r\n      e._targetY = target.y;\r\n      // Smooth pose noise while retaining direct, low-latency body attachment.\r\n      e.x += (target.x - e.x) * 0.55;\r\n      if (e.phase === 'settled' || e.phase === 'growing') e.y += (target.y - e.y) * 0.55;\r\n    }\r\n  }\r\n\r\n  function pose({ points, now, validHold } = {}) {\r\n    if (!validHold || !Number.isFinite(now) || !points) { clearEligibility(); return state; }\r\n    const current = normalized(points, w, h);\r\n    if (!enoughPose(current)) { clearEligibility(); return state; }\r\n    if (lastTimestamp != null && now <= lastTimestamp) return state;\r\n    const ground = getGround(points);\r\n    state.groundY += (ground - state.groundY) * 0.35;\r\n    if (lastTimestamp != null && now - lastTimestamp > MAX_POSE_GAP_MS) {\r\n      clearEligibility();\r\n      // The current observation starts a fresh reference, but earns no time.\r\n      reference = new Map(current); previous = new Map(current); lastTimestamp = now; poseAge = 0;\r\n      return state;\r\n    }\r\n    if (lastTimestamp == null) {\r\n      reference = new Map(current); previous = new Map(current); lastTimestamp = now; poseAge = 0;\r\n      state.phase = state.entities.some(e => ['retreating', 'fleeing', 'cracking'].includes(e.phase)) ? 'retreating' : 'waiting';\r\n      return state;\r\n    }\r\n    // A landmark first seen confidently on this pose has no trustworthy history.\r\n    // Baseline it now without comparing unseen movement; subsequent poses can track it.\r\n    for (const [index, point] of current) if (!reference.has(index)) reference.set(index, { ...point });\r\n    const moved = movementDetected(current, now);\r\n    if (moved) {\r\n      beginDeparture(); state.stillSeconds = 0;\r\n      nextGrowth = STILL; growthOrdinal = 0;\r\n      reference = new Map(current); previous = new Map(current); lastTimestamp = now; poseAge = 0;\r\n      return state;\r\n    }\r\n    if (moved === null) {\r\n      clearEligibility();\r\n      reference = new Map(current); previous = new Map(current); lastTimestamp = now; poseAge = 0;\r\n      return state;\r\n    }\r\n    syncAnchors(points);\r\n    const dt = (now - lastTimestamp) / 1000;\r\n    state.stillSeconds += dt;\r\n    previous = new Map(current); lastTimestamp = now; poseAge = 0;\r\n    if (state.stillSeconds >= STILL - 1e-9) {\r\n      state.phase = 'growing';\r\n      if (spawnEntities) {\r\n        while (state.stillSeconds >= nextGrowth - 1e-9 && state.entities.length < MAX_ENTITIES) {\r\n          spawnEntity(points); growthOrdinal++;\r\n          nextGrowth += Math.min(2.4, 0.75 + growthOrdinal * 0.035); // slows as ecosystem becomes fuller\r\n        }\r\n      }\r\n    } else if (!state.entities.some(e => ['retreating', 'fleeing', 'cracking'].includes(e.phase))) state.phase = 'waiting';\r\n    return state;\r\n  }\r\n\r\n  function step(rawDt = 0) {\r\n    const dtRaw = Number.isFinite(rawDt) && rawDt > 0 ? rawDt : 0;\r\n    poseAge += dtRaw * 1000; // watchdog uses uncapped wall elapsed, not physics delta\r\n    if (poseAge > MAX_POSE_GAP_MS && lastTimestamp != null) clearEligibility();\r\n    const dt = Math.min(0.05, dtRaw);\r\n    elapsed += dt;\r\n    for (const e of state.entities) {\r\n      e.phaseTime += dt;\r\n      if (e.phase === 'landing') {\r\n        const t = clamp(e.phaseTime / 0.8, 0, 1); e.y += ((e._targetY ?? e.y) - e.y) * Math.min(1, dt * 7);\r\n        e.growth = 0.18 + t * 0.34; e.alpha = 0.32 + t * 0.58;\r\n        if (t >= 1) { e.phase = 'growing'; e.phaseTime = 0; }\r\n      } else if (e.phase === 'growing') {\r\n        e.growth = Math.min(1, e.growth + dt * (e.kind === 'plant' ? 0.26 : 0.13));\r\n        e.alpha = 0.4 + e.growth * 0.5;\r\n        if (e.growth >= 1) { e.phase = 'settled'; e.phaseTime = 0; }\r\n      } else if (e.phase === 'retreating') {\r\n        e.y += 12 * dt; e.growth = Math.max(0, e.growth - dt * 1.1); e.alpha = Math.max(0, e.alpha - dt * 0.85);\r\n      } else if (e.phase === 'fleeing') {\r\n        e.x += e.facing * (28 + e.size * 0.6) * dt; e.y -= Math.sin(e.phaseTime * 8) * 5 * dt;\r\n        e.alpha = Math.max(0, e.alpha - dt * 0.22);\r\n      } else if (e.phase === 'cracking' && e.phaseTime >= CRACK_SECONDS) {\r\n        e._shattered = true;\r\n        const n = Math.min(5, MAX_DEBRIS - state.debris.length);\r\n        for (let i = 0; i < n; i++) {\r\n          const angle = rand() * Math.PI * 2, speed = 22 + rand() * 54;\r\n          state.debris.push({ id: nextId++, x: e.x, y: e.y - e.size * 0.3, vx: Math.cos(angle) * speed,\r\n            vy: -26 - rand() * 55, size: 2 + Math.floor(rand() * 4), rotation: rand() * 6,\r\n            alpha: 0.8, color: e.variant === 'crystal' ? '#8be7ff' : '#a99579', groundY: state.groundY,\r\n            _age: 0, _below: false });\r\n        }\r\n        emit('shatter', { id: e.id, count: n });\r\n      }\r\n    }\r\n    state.entities = state.entities.filter(e => {\r\n      if (e.phase === 'cracking' && e._shattered) return false;\r\n      if (e.phase === 'retreating') return e.phaseTime < 1.05 && e.alpha > 0.02;\r\n      if (e.phase === 'fleeing') return e.phaseTime < 2.5 && e.alpha > 0.03 && e.x > -60 && e.x < w + 60;\r\n      return true;\r\n    });\r\n    for (const d of state.debris) {\r\n      d._age += dt; d.x += d.vx * dt; d.y += d.vy * dt; d.vy += 180 * dt; d.rotation += d.vx * dt * 0.025;\r\n      if (d.y >= d.groundY + 12) d._below = true;\r\n      if (d._below) d.alpha = Math.max(0, d.alpha - dt * 0.7);\r\n    }\r\n    state.debris = state.debris.filter(d => d.alpha > 0.01 && d._age < 8);\r\n    if (state.entities.length > MAX_ENTITIES) state.entities.splice(0, state.entities.length - MAX_ENTITIES);\r\n    if (state.debris.length > MAX_DEBRIS) state.debris.splice(0, state.debris.length - MAX_DEBRIS);\r\n    return state;\r\n  }\r\n  function reset() {\r\n    state.phase = 'waiting'; state.stillSeconds = 0; state.entities.length = 0; state.debris.length = 0;\r\n    reference = previous = null; lastTimestamp = null; poseAge = Infinity; nextGrowth = STILL; growthOrdinal = 0; elapsed = 0;\r\n    state.groundY = h - 6;\r\n    return state;\r\n  }\r\n  return { state, pose, step, reset };\r\n}\r\n","arcade/hold/render.mjs":"// Transparent Canvas2D renderer for the hold ecology. Art is cropped from the\r\n// CC0 atlases preserved in ./assets and normalized into cached 64x64 canvases.\r\nconst ROOT = '/arcade/hold/assets/';\r\nconst CELL = 64;\r\nconst sources = new Map();\r\nlet loadStarted = false;\r\n\r\nfunction canvas64() {\r\n  if (typeof document === 'undefined') return null;\r\n  const canvas = document.createElement('canvas');\r\n  canvas.width = canvas.height = CELL;\r\n  return canvas;\r\n}\r\n\r\nfunction image(path) {\r\n  return new Promise((resolve, reject) => {\r\n    if (typeof Image === 'undefined') return reject(new Error('Image unavailable'));\r\n    const img = new Image();\r\n    img.onload = () => resolve(img);\r\n    img.onerror = reject;\r\n    img.src = ROOT + path;\r\n  });\r\n}\r\n\r\nfunction normalize(img, rect, { key = null, maxW = 56, maxH = 60 } = {}) {\r\n  const canvas = canvas64();\r\n  if (!canvas) return null;\r\n  const ctx = canvas.getContext('2d', { willReadFrequently: !!key });\r\n  const [sx, sy, sw, sh] = rect;\r\n  if (key) {\r\n    const temp = document.createElement('canvas'); temp.width = sw; temp.height = sh;\r\n    const tg = temp.getContext('2d', { willReadFrequently: true });\r\n    tg.drawImage(img, sx, sy, sw, sh, 0, 0, sw, sh);\r\n    const pixels = tg.getImageData(0, 0, sw, sh);\r\n    const [kr, kg, kb] = key;\r\n    for (let i = 0; i < pixels.data.length; i += 4) {\r\n      if (pixels.data[i] === kr && pixels.data[i + 1] === kg && pixels.data[i + 2] === kb) pixels.data[i + 3] = 0;\r\n    }\r\n    tg.putImageData(pixels, 0, 0);\r\n    const scale = Math.min(maxW / sw, maxH / sh);\r\n    const dw = Math.max(1, Math.round(sw * scale)), dh = Math.max(1, Math.round(sh * scale));\r\n    ctx.imageSmoothingEnabled = false;\r\n    ctx.drawImage(temp, 0, 0, sw, sh, Math.round((CELL - dw) / 2), CELL - dh, dw, dh);\r\n  } else {\r\n    const scale = Math.min(maxW / sw, maxH / sh);\r\n    const dw = Math.max(1, Math.round(sw * scale)), dh = Math.max(1, Math.round(sh * scale));\r\n    ctx.imageSmoothingEnabled = false;\r\n    ctx.drawImage(img, sx, sy, sw, sh, Math.round((CELL - dw) / 2), CELL - dh, dw, dh);\r\n  }\r\n  return canvas;\r\n}\r\n\r\nfunction normalizeFrame(img, frame, fw, fh) {\r\n  return normalize(img, [frame * fw, 0, fw, fh], { maxW: 60, maxH: 58 });\r\n}\r\n\r\nfunction buildAnimal(img, count, fw, fh) {\r\n  return Array.from({ length: count }, (_, i) => normalizeFrame(img, i, fw, fh)).filter(Boolean);\r\n}\r\n\r\nasync function loadSprites() {\r\n  const specs = [\r\n    ['flowers', 'flowers-plants_2.png'],\r\n    ['foxIdle', 'fox/Fox/Fox_Idle.png'], ['foxRun', 'fox/Fox/Fox_Run.png'],\r\n    ['rabbitIdle', 'rabbit/Rabbit/Rabbit_Idle.png'], ['rabbitRun', 'rabbit/Rabbit/Rabbit_Run.png'],\r\n    ['bearIdle', 'bear/Bear/Bear_Idle.png'], ['bearRun', 'bear/Bear/Bear_Run.png'],\r\n    ['boarIdle', 'boar/Boar/Boar_Idle.png'], ['boarRun', 'boar/Boar/Boar_Run.png'],\r\n    ['deerIdle', 'deer/Deer/Deer_Idle.png'], ['deerRun', 'deer/Deer/Deer_Run.png'],\r\n    ['wolfWalk', 'wolf/Wolf/Wolf_Walk.png'], ['wolfRun', 'wolf/Wolf/Wolf_Run.png'],\r\n    ['rocks', 'rocks-original.png'],\r\n    ['crystalBlue', 'crystals/PNG/32x32/crystal-blue.png'],\r\n    ['crystalIcy', 'crystals/PNG/32x32/crystal-icy.png'],\r\n    ['crystalRed', 'crystals/PNG/32x32/crystal-red-small.png'],\r\n    ['crystalGreen', 'crystals/PNG/32x32/crystal-green-alt.png'],\r\n    ['crystalGold', 'crystals/PNG/32x32/crystal-gold.png'],\r\n    ['crystalPurple', 'crystals/PNG/32x32/crystal-purple.png'],\r\n  ];\r\n  const loaded = await Promise.all(specs.map(async ([key, path]) => [key, await image(path).catch(() => null)]));\r\n  const img = Object.fromEntries(loaded);\r\n\r\n  // SpiderDave's source is 78 exact 12x24 cells on one uniform #222034 background.\r\n  if (img.flowers) {\r\n    sources.set('plant:fern', normalize(img.flowers, [12, 0, 12, 24], { key: [34, 32, 52], maxW: 36, maxH: 60 }));\r\n    sources.set('plant:vine', normalize(img.flowers, [14 * 12, 0, 12, 24], { key: [34, 32, 52], maxW: 40, maxH: 60 }));\r\n    sources.set('plant:flower', normalize(img.flowers, [48 * 12, 0, 12, 24], { key: [34, 32, 52], maxW: 42, maxH: 60 }));\r\n    sources.set('plant:grass', normalize(img.flowers, [0, 0, 12, 24], { key: [34, 32, 52], maxW: 40, maxH: 60 }));\r\n    sources.set('plant:reed', normalize(img.flowers, [6 * 12, 0, 12, 24], { key: [34, 32, 52], maxW: 40, maxH: 60 }));\r\n    sources.set('plant:mushroom', normalize(img.flowers, [70 * 12, 0, 12, 24], { key: [34, 32, 52], maxW: 42, maxH: 60 }));\r\n  }\r\n  if (img.foxIdle) sources.set('animal:fox:idle', buildAnimal(img.foxIdle, 6, 64, 36));\r\n  if (img.foxRun) sources.set('animal:fox:run', buildAnimal(img.foxRun, 6, 64, 36));\r\n  if (img.rabbitIdle) sources.set('animal:rabbit:idle', buildAnimal(img.rabbitIdle, 10, 32, 26));\r\n  if (img.rabbitRun) sources.set('animal:rabbit:run', buildAnimal(img.rabbitRun, 6, 32, 26));\r\n  if (img.bearIdle) sources.set('animal:bear:idle', buildAnimal(img.bearIdle, 12, 64, 33));\r\n  if (img.bearRun) sources.set('animal:bear:run', buildAnimal(img.bearRun, 5, 64, 33));\r\n  if (img.boarIdle) sources.set('animal:boar:idle', buildAnimal(img.boarIdle, 8, 64, 40));\r\n  if (img.boarRun) sources.set('animal:boar:run', buildAnimal(img.boarRun, 6, 64, 40));\r\n  if (img.deerIdle) sources.set('animal:deer:idle', buildAnimal(img.deerIdle, 15, 48, 52));\r\n  if (img.deerRun) sources.set('animal:deer:run', buildAnimal(img.deerRun, 9, 48, 52));\r\n  if (img.wolfWalk) sources.set('animal:wolf:idle', buildAnimal(img.wolfWalk, 8, 64, 40));\r\n  if (img.wolfRun) sources.set('animal:wolf:run', buildAnimal(img.wolfRun, 6, 64, 40));\r\n\r\n  // Rocks are six 32x32 cells. Crystal sheets contain four separated sprites;\r\n  // these bounds were inspected at native resolution, then aspect-fit to 64x64.\r\n  if (img.rocks) sources.set('mineral:rock', [0, 2, 4].map(i => normalize(img.rocks, [(i % 3) * 32, Math.floor(i / 3) * 32, 32, 32], { maxW: 56, maxH: 56 })).filter(Boolean));\r\n  const crystalSpecs = [\r\n    ['crystalBlue', [0, 7, 64, 121]], ['crystalBlue', [64, 6, 64, 120]],\r\n    ['crystalIcy', [128, 3, 32, 61]], ['crystalRed', [2, 0, 30, 32]],\r\n    ['crystalGreen', [9, 18, 45, 77]],\r\n  ];\r\n  const crystals = crystalSpecs.map(([name, rect]) => img[name] && normalize(img[name], rect, { maxW: 44, maxH: 58 })).filter(Boolean);\r\n  if (crystals.length) sources.set('mineral:crystal', crystals);\r\n  const crystalPalettes = [\r\n    ['blue', img.crystalBlue && normalize(img.crystalBlue, [0, 7, 64, 121], { maxW: 44, maxH: 58 })],\r\n    ['ice', img.crystalIcy && normalize(img.crystalIcy, [128, 3, 32, 61], { maxW: 44, maxH: 58 })],\r\n    ['red', img.crystalRed && normalize(img.crystalRed, [2, 0, 30, 32], { maxW: 44, maxH: 58 })],\r\n    ['green', img.crystalGreen && normalize(img.crystalGreen, [9, 18, 45, 77], { maxW: 44, maxH: 58 })],\r\n    ['gold', img.crystalGold && normalize(img.crystalGold, [0, 0, 32, 32], { maxW: 44, maxH: 58 })],\r\n    ['purple', img.crystalPurple && normalize(img.crystalPurple, [0, 0, 32, 32], { maxW: 44, maxH: 58 })],\r\n  ];\r\n  for (const [palette, sprite] of crystalPalettes) if (sprite) sources.set(`mineral:crystal:${palette}`, [sprite]);\r\n}\r\n\r\nexport function preloadEcosystemSprites() {\r\n  if (!loadStarted) { loadStarted = true; loadSprites().catch(() => {}); }\r\n}\r\n\r\nfunction getSprite(e) {\r\n  if (e.kind === 'plant') return sources.get(`plant:${e.variant}`);\r\n  if (e.kind === 'animal') {\r\n    const mode = e.phase === 'fleeing' ? 'run' : 'idle';\r\n    const frames = sources.get(`animal:${e.variant}:${mode}`) || sources.get(`animal:${e.variant}:idle`);\r\n    if (!frames?.length) return null;\r\n    const frame = Math.floor(Math.max(0, e.phaseTime || 0) * (mode === 'run' ? 10 : 2)) % frames.length;\r\n    return frames[frame];\r\n  }\r\n  const variants = sources.get(e.palette ? `mineral:${e.variant}:${e.palette}` : `mineral:${e.variant}`);\r\n  if (!variants?.length) return null;\r\n  return variants[Math.abs((e.id || 0) * 7) % variants.length];\r\n}\r\n\r\nfunction drawPlant(ctx, e, sprite) {\r\n  const growth = Math.max(0, Math.min(1, Number(e.growth) || 0));\r\n  if (growth <= 0) return;\r\n  const width = Math.max(1, e.size);\r\n  const height = Math.max(1, e.size * growth);\r\n  const shown = CELL * growth;\r\n  const sway = Math.sin((e.phaseTime || 0) * 2.4 + (e.id || 0)) * 0.045;\r\n  ctx.save(); ctx.translate(Math.round(e.x), Math.round(e.y)); ctx.rotate(sway);\r\n  ctx.drawImage(sprite, 0, Math.round(CELL - shown), CELL, Math.max(1, Math.ceil(shown)),\r\n    Math.round(-width / 2), Math.round(-height), Math.round(width), Math.round(height));\r\n  ctx.restore();\r\n}\r\n\r\nfunction drawAnimal(ctx, e, sprite) {\r\n  const emerge = 0.42 + Math.max(0, Math.min(1, Number(e.growth) || 0)) * 0.58;\r\n  const width = Math.max(1, e.size * emerge), height = width;\r\n  const bob = e.phase === 'fleeing' ? Math.round(Math.sin((e.phaseTime || 0) * 18) * Math.min(2, height * 0.06)) : 0;\r\n  ctx.save(); ctx.translate(Math.round(e.x), Math.round(e.y + bob));\r\n  ctx.scale(e.facing < 0 ? -1 : 1, 1);\r\n  ctx.drawImage(sprite, Math.round(-width / 2), Math.round(-height), Math.round(width), Math.round(height));\r\n  ctx.restore();\r\n}\r\n\r\nfunction drawCrack(ctx, e) {\r\n  const t = Math.max(0, Math.min(1, (e.phaseTime || 0) / 0.3));\r\n  const r = Math.max(4, e.size * 0.38), x = Math.round(e.x), y = Math.round(e.y - e.size * 0.55);\r\n  const branches = [\r\n    [[0, -r], [-1, -2], [-4, 1], [-2, 4]],\r\n    [[-1, -2], [-6, -4], [-8, -7]],\r\n    [[-1, -2], [3, -4], [6, -7]],\r\n    [[-2, 4], [-5, 6], [-6, 8]],\r\n    [[-2, 4], [2, 5], [5, 8]],\r\n  ];\r\n  const count = Math.min(branches.length, 1 + Math.floor(t * branches.length));\r\n  ctx.save(); ctx.lineWidth = 1; ctx.lineCap = 'square';\r\n  ctx.strokeStyle = e.variant === 'crystal' ? '#e9fcff' : '#332d27';\r\n  for (let i = 0; i < count; i++) {\r\n    const line = branches[i]; ctx.beginPath(); ctx.moveTo(x + line[0][0], y + line[0][1]);\r\n    for (let j = 1; j < line.length; j++) ctx.lineTo(x + line[j][0], y + line[j][1]);\r\n    ctx.stroke();\r\n  }\r\n  ctx.restore();\r\n}\r\n\r\nfunction drawDebris(ctx, d) {\r\n  const size = Math.max(1, Math.round(d.size || 2));\r\n  ctx.save(); ctx.globalAlpha = Math.max(0, Math.min(1, d.alpha ?? 1));\r\n  ctx.translate(Math.round(d.x), Math.round(d.y));\r\n  // Keep fragments chunky; only rotate larger chips so the pixels remain crisp.\r\n  if (size >= 4) ctx.rotate(Math.round((d.rotation || 0) * 4) / 4);\r\n  ctx.fillStyle = d.color || '#a99579'; ctx.fillRect(-Math.floor(size / 2), -Math.floor(size / 2), size, size);\r\n  ctx.restore();\r\n}\r\n\r\nexport function renderEcosystem(ctx, state) {\r\n  if (!ctx || !state) return;\r\n  preloadEcosystemSprites();\r\n  ctx.imageSmoothingEnabled = false;\r\n  const entities = Array.isArray(state.entities) ? state.entities : [];\r\n  for (const e of entities) {\r\n    if (!Number.isFinite(e.x) || !Number.isFinite(e.y) || !Number.isFinite(e.size)) continue;\r\n    const sprite = getSprite(e);\r\n    if (!sprite) continue;\r\n    ctx.save(); ctx.globalAlpha = Math.max(0, Math.min(1, Number(e.alpha) || 0));\r\n    if (e.kind === 'plant') drawPlant(ctx, e, sprite);\r\n    else if (e.kind === 'animal') drawAnimal(ctx, e, sprite);\r\n    else {\r\n      const emerge = 0.42 + Math.max(0, Math.min(1, Number(e.growth) || 0)) * 0.58;\r\n      const size = Math.max(1, e.size * emerge);\r\n      ctx.drawImage(sprite, Math.round(e.x - size / 2), Math.round(e.y - size), Math.round(size), Math.round(size));\r\n      if (e.phase === 'cracking') drawCrack(ctx, e);\r\n    }\r\n    ctx.restore();\r\n  }\r\n  for (const d of Array.isArray(state.debris) ? state.debris : []) {\r\n    if (Number.isFinite(d.x) && Number.isFinite(d.y)) drawDebris(ctx, d);\r\n  }\r\n}\r\n","arcade/one-euro.mjs":"export const DCUTOFF = 1;\r\n\r\nexport class OneEuroFilter {\r\n    constructor({ minCutoff, beta, dCutoff }) {\r\n        this.minCutoff = minCutoff;\r\n        this.beta = beta;\r\n        this.dCutoff = dCutoff;\r\n        this.reset();\r\n    }\r\n\r\n    reset() {\r\n        this.first = true;\r\n        this.xPrev = 0;\r\n        this.dxHatPrev = 0;\r\n        this.xHat = 0;\r\n        this.dxHat = 0;\r\n    }\r\n\r\n    static lowpass(v, a, prev) {\r\n        return a * v + (1 - a) * prev;\r\n    }\r\n\r\n    static alpha(cutoff, dt) {\r\n        const tau = 1 / (2 * Math.PI * cutoff);\r\n        return 1 / (1 + tau / dt);\r\n    }\r\n\r\n    filter(x, dtSeconds) {\r\n        if (dtSeconds < 1e-3) dtSeconds = 1e-3;\r\n        if (this.first) {\r\n            this.xHat = x;\r\n            this.dxHat = 0;\r\n            // Ensure derivative history is initialized for the next sample\r\n            this.xPrev = x;\r\n            this.first = false;\r\n            return this.xHat;\r\n        }\r\n        const dx = (x - this.xPrev) / dtSeconds;\r\n        const edx = OneEuroFilter.lowpass(dx, OneEuroFilter.alpha(this.dCutoff, dtSeconds), this.dxHatPrev);\r\n        this.dxHat = edx;\r\n\r\n        const cutoff = this.minCutoff + this.beta * Math.abs(edx);\r\n        const xHat = OneEuroFilter.lowpass(x, OneEuroFilter.alpha(cutoff, dtSeconds), this.xHat);\r\n\r\n        this.xPrev = x;\r\n        this.dxHatPrev = edx;\r\n        this.xHat = xHat;\r\n\r\n        return xHat;\r\n    }\r\n}\r\n\r\nexport const PRESETS = {\r\n    wrist: { minCutoff: 3, beta: 20, dCutoff: DCUTOFF },\r\n    torso: { minCutoff: 1, beta: 4, dCutoff: DCUTOFF }\r\n};\r\n\r\nexport function presetFor(index) {\r\n    if (index >= 15 && index <= 22) return PRESETS.wrist;\r\n    return PRESETS.torso;\r\n}\r\n\r\nexport function createLandmarkBank(presetFn) {\r\n    const states = new Map();\r\n\r\n    function update(index, x, y, visibility, tMs) {\r\n        let state = states.get(index);\r\n        const dtMs = state ? tMs - state.lastMs : 0;\r\n\r\n        if (state && dtMs > 300) {\r\n            state.xFilter.reset();\r\n            state.yFilter.reset();\r\n            state.vis = 0;\r\n            state.visible = false;\r\n        }\r\n\r\n        if (!state) {\r\n            const preset = presetFn(index);\r\n            state = {\r\n                xFilter: new OneEuroFilter(preset),\r\n                yFilter: new OneEuroFilter(preset),\r\n                lastMs: tMs,\r\n                visible: false,\r\n                vis: 0\r\n            };\r\n            states.set(index, state);\r\n        }\r\n\r\n        // Visibility hysteresis\r\n        if (!state.visible && visibility >= 0.6) state.visible = true;\r\n        else if (state.visible && visibility < 0.4) state.visible = false;\r\n\r\n        // Alpha fade\r\n        const target = state.visible ? 1 : 0;\r\n        const step = dtMs / 200;\r\n        if (dtMs > 0) {\r\n            const diff = target - state.vis;\r\n            state.vis += Math.sign(diff) * Math.min(Math.abs(diff), step);\r\n            if (state.vis < 0) state.vis = 0;\r\n            if (state.vis > 1) state.vis = 1;\r\n        }\r\n\r\n        // Filter\r\n        const dtSec = state.lastMs === tMs ? 1 / 30 : dtMs / 1000;\r\n        const fx = state.xFilter.filter(x, dtSec);\r\n        const fy = state.yFilter.filter(y, dtSec);\r\n\r\n        state.lastMs = tMs;\r\n\r\n        return { x: fx, y: fy, alpha: state.vis, visible: state.visible };\r\n    }\r\n\r\n    function predict(index, ms) {\r\n        const state = states.get(index);\r\n        if (!state) return null;\r\n        const lookahead = Math.min(ms, 66) / 1000;\r\n        const dx = state.xFilter.dxHat * lookahead * 0.6;\r\n        const dy = state.yFilter.dxHat * lookahead * 0.6;\r\n        return {\r\n            x: state.xFilter.xHat + dx,\r\n            y: state.yFilter.xHat + dy\r\n        };\r\n    }\r\n\r\n    function reset(index) {\r\n        states.delete(index);\r\n    }\r\n\r\n    return { update, predict, reset };\r\n}\r\n","arcade/power/aura-anchor.mjs":"// Pure geometry that pins auras to the skeleton: torso-relative sizes, fixed bone slots per sprite (no hopping),\r\n// body-centred circles and pulses, bone capsule radii. Points are overlay fractions (0..1) with optional `alpha`\r\n// (0..1 fade from the One Euro bank); pixel space is w x h. No DOM, no allocation in the per-frame helpers that\r\n// take an `out` object.\r\n\r\n// Tuning knobs (real phones need tuning). Radii and sizes are fractions of the on-screen torso length\r\n// (shoulder to hip), so the aura is the same thickness near or far from the camera.\r\nexport const AURA_BODY = Object.freeze({\r\n  // One Euro presets for overlay fractions: torso heavier, limbs lighter, hands lightest (they move fastest).\r\n  FILTER: Object.freeze({\r\n    // beta is per (overlay fraction / s): a fast squat moves the hips ~0.5/s, a punch the wrist 2-3/s. High beta and\r\n    // dCutoff 2 open the filter quickly on fast moves (little lag) while minCutoff keeps a still body calm.\r\n    // Swept offline (.r1017/scripts/tune.mjs, 45 ms lag, 30 Hz): vs raw lagged landmarks these cut the squat error\r\n    // ~22% and the side-step error ~37% with less jitter at rest; hands stay nearly raw (a 0.2 s punch is too short\r\n    // for any filter + prediction to beat the raw point).\r\n    torso: Object.freeze({ minCutoff: 1, beta: 60, dCutoff: 3 }),\r\n    limb: Object.freeze({ minCutoff: 1.2, beta: 90, dCutoff: 3.5 }),\r\n    hand: Object.freeze({ minCutoff: 0.8, beta: 150, dCutoff: 5 }),\r\n  }),\r\n  PREDICT_CLAMP: 0.04,       // max forward lead per landmark, overlay fractions\r\n  PREDICT_GAIN: 0.9,         // share of (velocity x lag) to lead by (one-euro.mjs caps the lag at 66 ms)\r\n  FADE_MS: 250,              // whole-aura fade in/out instead of a hard pop\r\n  // Halo outer radius per bone class at level 1 (the glow fades out to this distance from the bone).\r\n  RADIUS: Object.freeze({ core: 0.62, head: 0.46, upper: 0.3, lower: 0.26, hip: 0.36 }),\r\n  // The body itself (roughly the person's width) is cut out of the glow so it sits around, not over, them.\r\n  BODY: Object.freeze({ core: 0.3, head: 0.21, upper: 0.09, lower: 0.075, hip: 0.13 }),\r\n  LEVEL_BASE: 0.55, LEVEL_GAIN: 0.45, // halo radius scale = BASE + GAIN * level\r\n  SPEED_WIDEN: 0.5, SPEED_REF: 1.5,   // widen by up to +50% at SPEED_REF torso lengths/s (hides sub-frame error)\r\n  CUT: 0.85, CUT_ALPHA: 0.6,             // inner body punch-out: BODY radius x CUT at this strength (a rim stays)\r\n  HALO_DOWNSCALE: 4,                  // halo drawn at 1/4 of the glow layer, upscaled = smooth falloff\r\n  IMPACT_GAIN: 0.5, IMPACT_MS: 300,   // punch impact: glow gain bump and flare life\r\n  PARTICLES: 96,                      // flame tongue pool (Q2+); Q1 has none\r\n  EMIT_BASE: 26, EMIT_LEVEL: 90,      // tongues per second at level 0 / extra at level 1\r\n  WISP_DECAY: 0.92, WISP_RISE: 2,     // silhouette feedback wisps (Q3): fade per frame, glow px risen per frame\r\n  GLOW_WIDTH: 160,                    // glow layer logical width (CSS upscaled with smoothing = free blur)\r\n  // Sprite placement as torso multiples (values chosen to match the old screen-fraction look at ~2.5 m).\r\n  SHEET_SIZE: 0.95, ORBIT_SIZE: 0.85, CIRCLE_SIZE: 2.1, PULSE_SIZE: 1.5, FLOOR_SIZE: 0.6,\r\n  BODY_ORBIT: Object.freeze([0.22, 0.14]), WIDE_ORBIT: Object.freeze([0.42, 0.3]),\r\n  FALLBACK_TORSO: 0.19,               // torso as a fraction of height when no torso is visible\r\n});\r\n\r\nexport const VISIBLE_ALPHA = 0.02;\r\nconst clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\r\nexport function pointAlpha(p) {\r\n  if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y)) return 0;\r\n  if (Number.isFinite(p.alpha)) return p.alpha;\r\n  return (p.visibility ?? 1) >= 0.5 ? 1 : 0;\r\n}\r\nconst seen = p => pointAlpha(p) > VISIBLE_ALPHA;\r\n\r\n/** On-screen torso length in pixels (aspect-correct): the longest of left side, right side and shoulder line. */\r\nexport function torsoPx(points, w, h) {\r\n  if (!points) return null;\r\n  let best = 0;\r\n  for (const [a, b] of [[11, 23], [12, 24], [11, 12]]) {\r\n    const p = points[a], q = points[b];\r\n    if (seen(p) && seen(q)) best = Math.max(best, Math.hypot((p.x - q.x) * w, (p.y - q.y) * h));\r\n  }\r\n  return best > 0 ? Math.max(best, 0.05 * h) : null;\r\n}\r\n\r\nfunction mid(points, a, b, w, h) {\r\n  const p = points?.[a], q = points?.[b];\r\n  if (seen(p) && seen(q)) return { x: (p.x + q.x) / 2 * w, y: (p.y + q.y) / 2 * h };\r\n  if (seen(p)) return { x: p.x * w, y: p.y * h };\r\n  if (seen(q)) return { x: q.x * w, y: q.y * h };\r\n  return null;\r\n}\r\n/** Hip midpoint, chest (shoulder) midpoint and their centre in pixels; falls back to the screen centre. */\r\nexport function bodyCentre(points, w, h) {\r\n  const hip = mid(points, 23, 24, w, h), chest = mid(points, 11, 12, w, h);\r\n  const centre = hip && chest ? { x: (hip.x + chest.x) / 2, y: (hip.y + chest.y) / 2 } : hip || chest || { x: w * 0.5, y: h * 0.48 };\r\n  return { hip: hip || centre, chest: chest || centre, centre, found: !!(hip || chest) };\r\n}\r\n\r\n/** Size scale: torso pixels, or the old screen fraction when no torso is visible. */\r\nexport function bodyScale(points, w, h, T = AURA_BODY) { return torsoPx(points, w, h) ?? T.FALLBACK_TORSO * h; }\r\n\r\n// Bones: [a, b, radius class]. -1 = chest midpoint, -2 = hip midpoint (virtual joints).\r\nexport const BONES = Object.freeze([\r\n  [-1, -2, 'core'], [11, 12, 'upper'], [23, 24, 'hip'], [11, 23, 'upper'], [12, 24, 'upper'],\r\n  [0, 0, 'head'],\r\n  [11, 13, 'upper'], [13, 15, 'lower'], [12, 14, 'upper'], [14, 16, 'lower'],\r\n  [23, 25, 'upper'], [25, 27, 'lower'], [24, 26, 'upper'], [26, 28, 'lower'],\r\n]);\r\n\r\n/** Pixel position and fade of a (possibly virtual) joint into `out`; returns false if it is not tracked. */\r\nexport function jointPx(points, index, w, h, out) {\r\n  if (index >= 0) {\r\n    const p = points?.[index];\r\n    if (!seen(p)) return false;\r\n    out.x = p.x * w; out.y = p.y * h; out.a = clamp(pointAlpha(p), 0, 1); return true;\r\n  }\r\n  const [i, j] = index === -1 ? [11, 12] : [23, 24], p = points?.[i], q = points?.[j];\r\n  if (!seen(p) || !seen(q)) return false;\r\n  out.x = (p.x + q.x) / 2 * w; out.y = (p.y + q.y) / 2 * h; out.a = Math.min(pointAlpha(p), pointAlpha(q)); return true;\r\n}\r\n\r\n/** Capsule radius in pixels for a radius class at a growth level and limb speed (torso lengths/s). */\r\nexport function boneRadius(kind, torso, level = 0, speed = 0, T = AURA_BODY) {\r\n  const widen = 1 + T.SPEED_WIDEN * clamp((speed || 0) / T.SPEED_REF, 0, 1);\r\n  return torso * (T.RADIUS[kind] ?? T.RADIUS.lower) * (T.LEVEL_BASE + T.LEVEL_GAIN * clamp(level, 0, 1)) * widen;\r\n}\r\n\r\n// Fixed bone slots for sheet sprites, in reveal order (more sprites appear as the level rises). Sprite i always\r\n// lives on SLOTS[i % n]: it never moves to another joint, so nothing teleports.\r\nexport const SHEET_SLOTS = Object.freeze([\r\n  [-1, -2, 0.45], [11, 13, 0.5], [12, 14, 0.5], [23, 25, 0.5], [24, 26, 0.5], [13, 15, 0.6], [14, 16, 0.6], [25, 27, 0.55],\r\n  [26, 28, 0.55], [11, 12, 0.5],\r\n]);\r\nexport const LEG_SLOTS = Object.freeze([\r\n  [23, 25, 0.35], [24, 26, 0.35], [25, 27, 0.4], [26, 28, 0.4], [23, 25, 0.8], [24, 26, 0.8], [25, 27, 0.85], [26, 28, 0.85],\r\n  [-1, -2, 0.85], [23, 24, 0.5],\r\n]);\r\nexport const ARM_SLOTS = Object.freeze([\r\n  [13, 15, 0.85], [14, 16, 0.85], [11, 13, 0.6], [12, 14, 0.6], [13, 15, 0.4], [14, 16, 0.4], [11, 13, 0.2], [12, 14, 0.2],\r\n]);\r\n\r\nconst A = { x: 0, y: 0, a: 0 }, B = { x: 0, y: 0, a: 0 };\r\n/** Point at parameter t along a slot's bone (pixels) into `out`, with fade `a` and bone direction (dx, dy unit). */\r\nexport function slotPx(points, slot, w, h, out) {\r\n  if (!jointPx(points, slot[0], w, h, A) || !jointPx(points, slot[1], w, h, B)) return false;\r\n  const t = slot[2], dx = B.x - A.x, dy = B.y - A.y, len = Math.hypot(dx, dy) || 1;\r\n  out.x = A.x + dx * t; out.y = A.y + dy * t; out.a = Math.min(A.a, B.a); out.dx = dx / len; out.dy = dy / len;\r\n  return true;\r\n}\r\n\r\n/**\r\n * Sheet sprite i for a layout ('body' | 'orbit'): pinned to its own slot for its whole life, small orbit around it\r\n * scaled by torso. Writes {x, y, a, size, rotation} into out; false when its bone is not tracked (sprite hidden).\r\n */\r\nexport function sheetSprite(points, i, layout, time, w, h, torso, level, out, T = AURA_BODY) {\r\n  const slot = SHEET_SLOTS[i % SHEET_SLOTS.length];\r\n  if (!slotPx(points, slot, w, h, out)) return false;\r\n  const orbit = layout === 'orbit', [rx, ry] = orbit ? T.WIDE_ORBIT : T.BODY_ORBIT;\r\n  const phase = time * (orbit ? 0.8 : 0.35) + i * 2.399963229728653;\r\n  out.x += Math.cos(phase) * rx * torso; out.y += Math.sin(phase) * ry * torso;\r\n  out.size = torso * (orbit ? T.ORBIT_SIZE : T.SHEET_SIZE) * (0.6 + 0.4 * clamp(level, 0, 1));\r\n  out.rotation = orbit ? phase : Math.sin(phase) * 0.25;\r\n  return true;\r\n}\r\n\r\n/** Circle-layout effects and rep pulses: centred on the body (hip / torso centre) and sized by the torso. */\r\nexport function circlePlacement(points, w, h, level, T = AURA_BODY) {\r\n  const torso = bodyScale(points, w, h, T), c = bodyCentre(points, w, h);\r\n  return { x: c.hip.x, y: c.hip.y - torso * 0.1, size: torso * T.CIRCLE_SIZE * (0.45 + 0.55 * clamp(level, 0, 1)) };\r\n}\r\nexport function pulsePlacement(points, w, h, T = AURA_BODY) {\r\n  const torso = bodyScale(points, w, h, T), c = bodyCentre(points, w, h);\r\n  return { x: c.centre.x, y: c.centre.y, size: torso * T.PULSE_SIZE };\r\n}\r\n\r\n/** Clamp a predicted landmark lead to `max` (overlay fractions) so a velocity spike never throws the aura off. */\r\nexport function clampLead(base, predicted, max = AURA_BODY.PREDICT_CLAMP) {\r\n  const dx = predicted.x - base.x, dy = predicted.y - base.y, d = Math.hypot(dx, dy);\r\n  if (!(d > max)) return predicted;\r\n  const k = max / d; return { x: base.x + dx * k, y: base.y + dy * k };\r\n}\r\n\r\n/** Linear fade toward `target` (0 or 1) over fadeMs. */\r\nexport function fadeToward(alpha, target, dtMs, fadeMs = AURA_BODY.FADE_MS) {\r\n  const step = fadeMs > 0 ? Math.max(0, dtMs) / fadeMs : 1;\r\n  return target > alpha ? Math.min(target, alpha + step) : Math.max(target, alpha - step);\r\n}\r\n\r\n// Colour per effect: outer halo, mid, hot core (RGB 0..255).\r\nconst FIRE = [[255, 84, 18], [255, 168, 40], [255, 242, 196]];\r\nexport const AURA_PALETTES = Object.freeze({\r\n  classic: FIRE, aura: FIRE, firespin: FIRE, sunburn: [[255, 120, 16], [255, 204, 64], [255, 250, 205]],\r\n  floor: [[255, 104, 28], [255, 188, 76], [255, 246, 212]], lightning: [[52, 112, 255], [118, 200, 255], [236, 250, 255]],\r\n  bluefire: [[28, 88, 255], [82, 182, 255], [222, 246, 255]], magicbubbles: [[196, 76, 255], [255, 140, 238], [255, 232, 255]],\r\n  protectioncircle: [[255, 196, 56], [255, 234, 138], [255, 255, 232]], vortex: [[116, 58, 255], [178, 120, 255], [240, 222, 255]],\r\n  flamelash: [[255, 56, 28], [255, 138, 40], [255, 230, 172]], weaponhit: [[255, 214, 86], [255, 248, 168], [255, 255, 240]],\r\n  casting: [[56, 196, 255], [140, 240, 255], [230, 255, 255]], magicspell: [[255, 76, 196], [255, 160, 230], [255, 236, 250]],\r\n  magic8: [[90, 255, 196], [178, 255, 230], [240, 255, 250]], magichit: [[176, 86, 255], [220, 170, 255], [250, 240, 255]],\r\n  nebula: [[146, 58, 255], [255, 108, 220], [255, 230, 250]], phantom: [[76, 255, 176], [168, 255, 220], [236, 255, 246]],\r\n  felspell: [[86, 255, 56], [178, 255, 108], [240, 255, 220]], midnight: [[68, 58, 210], [140, 120, 255], [230, 226, 255]],\r\n  loading: [[76, 216, 255], [168, 240, 255], [240, 255, 255]], blizzard: [[116, 196, 255], [198, 240, 255], [246, 255, 255]],\r\n});\r\nexport function auraPalette(effect, route) {\r\n  return AURA_PALETTES[effect] ?? AURA_PALETTES[route] ?? FIRE;\r\n}\r\n","arcade/power/aura-body.mjs":"// Body-anchored aura glow for the camera layers (power and hold). It owns:\r\n//  - a One Euro landmark bank on overlay fractions, fed with the frame's capture time, plus damped prediction across\r\n//    the inference lag (createAuraTracker, pure, unit tested);\r\n//  - a low-res glow canvas that sits right above the <video> with mix-blend-mode:screen (light added to the camera\r\n//    image), drawn as soft capsules along the bones, flame tongues rising off them, a punch-impact flare, and on the\r\n//    top quality tier the person's silhouette mask with rising feedback wisps, all cut out of the body itself so the\r\n//    glow reads as behind / around the person;\r\n//  - a ~250 ms fade instead of hard clears.\r\n// Quality tiers come from the shared monitor in workout-effects.mjs: Q3 mask+wisps, Q2 capsules+tongues, Q1 capsules,\r\n// Q0 nothing here (sprites only).\r\nimport { createLandmarkBank } from '../one-euro.mjs';\r\nimport { AURA_BODY, BONES, VISIBLE_ALPHA, jointPx, boneRadius, torsoPx, bodyCentre, auraPalette, fadeToward, clampLead } from './aura-anchor.mjs';\r\nimport { effectQuality, videoRectInOverlay } from '../workout-effects.mjs';\r\n\r\nconst HAND = new Set([15, 16, 17, 18, 19, 20, 21, 22]), LIMB = new Set([13, 14, 25, 26, 27, 28, 29, 30, 31, 32]);\r\nexport function auraPreset(index, T = AURA_BODY) { return HAND.has(index) ? T.FILTER.hand : LIMB.has(index) ? T.FILTER.limb : T.FILTER.torso; }\r\n\r\n/** Filter + predict mapped overlay points. pose(points, captureMs) per detection; points(nowMs) per drawn frame. */\r\nexport function createAuraTracker(T = AURA_BODY) {\r\n  const bank = createLandmarkBank(i => auraPreset(i, T));\r\n  const N = 33, raw = Array.from({ length: N }, () => ({ x: 0, y: 0, seen: false }));\r\n  const filt = Array.from({ length: N }, () => ({ x: 0, y: 0, alpha: 0, visibility: 0 }));\r\n  const out = Array.from({ length: N }, () => ({ x: 0, y: 0, alpha: 0, visibility: 0 }));\r\n  let frameMs = null;\r\n  function pose(points, tMs) {\r\n    if (!Number.isFinite(tMs) || (frameMs != null && tMs <= frameMs)) return false;\r\n    frameMs = tMs;\r\n    for (let i = 0; i < N; i++) {\r\n      const p = points?.[i], r = raw[i];\r\n      let v;\r\n      if (p && Number.isFinite(p.x) && Number.isFinite(p.y)) { r.x = p.x; r.y = p.y; r.seen = true; v = Number.isFinite(p.visibility) ? p.visibility : 0; }\r\n      else if (r.seen) v = 0; // lost: hold the last position and let the bank fade it out\r\n      else continue;\r\n      const f = bank.update(i, r.x, r.y, v, tMs), o = filt[i];\r\n      o.x = f.x; o.y = f.y; o.alpha = f.alpha; o.visibility = f.alpha > VISIBLE_ALPHA ? 1 : 0;\r\n    }\r\n    return true;\r\n  }\r\n  function points(nowMs) {\r\n    const lag = frameMs == null ? 0 : Math.max(0, nowMs - frameMs);\r\n    for (let i = 0; i < N; i++) {\r\n      const f = filt[i], o = out[i];\r\n      o.alpha = f.alpha; o.visibility = f.visibility; o.x = f.x; o.y = f.y;\r\n      if (lag > 0 && raw[i].seen && f.visibility) {\r\n        const p = bank.predict(i, Math.min(lag, 66) * T.PREDICT_GAIN / 0.6); // predict() damps by 0.6 itself\r\n        if (p) { const c = clampLead(f, p, T.PREDICT_CLAMP); o.x = c.x; o.y = c.y; }\r\n      }\r\n    }\r\n    return out;\r\n  }\r\n  function reset() { for (let i = 0; i < N; i++) { bank.reset(i); raw[i].seen = false; filt[i].alpha = filt[i].visibility = 0; } frameMs = null; }\r\n  return { pose, points, reset, get frameMs() { return frameMs; } };\r\n}\r\n\r\n// Shared sprites ----------------------------------------------------------------------------------------------\r\nconst paletteCache = new WeakMap();\r\nfunction paletteStyles(pal) {\r\n  let s = paletteCache.get(pal);\r\n  if (!s) { s = pal.map(([r, g, b]) => `rgb(${r},${g},${b})`); s.dots = null; paletteCache.set(pal, s); }\r\n  return s;\r\n}\r\nfunction softDot(color) {\r\n  const c = document.createElement('canvas'); c.width = c.height = 32;\r\n  const x = c.getContext('2d'), grad = x.createRadialGradient(16, 16, 0, 16, 16, 16);\r\n  grad.addColorStop(0, color); grad.addColorStop(0.35, color.replace('rgb(', 'rgba(').replace(')', ',.55)')); grad.addColorStop(1, 'rgba(0,0,0,0)');\r\n  x.fillStyle = grad; x.fillRect(0, 0, 32, 32); return c;\r\n}\r\nlet noiseTile = null;\r\nfunction flameNoise() {\r\n  if (noiseTile) return noiseTile;\r\n  const W = 32, H = 64, c = document.createElement('canvas'); c.width = W; c.height = H;\r\n  const x = c.getContext('2d'), img = x.createImageData(W, H), col = new Float32Array(W);\r\n  let seed = 0x2545f491; const rnd = () => { seed ^= seed << 13; seed ^= seed >>> 17; seed ^= seed << 5; return (seed >>> 0) / 4294967296; };\r\n  for (let i = 0; i < W; i++) col[i] = rnd();\r\n  for (let y = 0; y < H; y++) for (let i = 0; i < W; i++) {\r\n    // vertical streaks that wander slowly: tileable in y (sin of y), smooth in x\r\n    const phase = col[i] * 6.283 + (y / H) * 6.283 * (1 + (i % 3)), v = 0.5 + 0.5 * Math.sin(phase) * (0.6 + 0.4 * col[(i + 1) % W]);\r\n    img.data[(y * W + i) * 4 + 3] = Math.round(255 * Math.max(0, Math.min(1, v * v)));\r\n  }\r\n  x.putImageData(img, 0, 0); return (noiseTile = c);\r\n}\r\n\r\n/** Mount the glow layer for an overlay host (#coachOverlay). */\r\nexport function createAuraBody({ host, quality = effectQuality, T = AURA_BODY, target = globalThis } = {}) {\r\n  const tracker = createAuraTracker(T);\r\n  const canvas = document.createElement('canvas'); canvas.className = 'workout-aura-glow-canvas'; canvas.setAttribute('aria-hidden', 'true');\r\n  // Above the <video> in the camera stage (outside #coachOverlay's stacking context) so `screen` adds light to the\r\n  // camera image; same box as the overlay host. Falls back to the host itself when there is no video sibling.\r\n  const stage = host.parentElement, video = stage && [...stage.children].find(el => el.tagName === 'VIDEO');\r\n  canvas.style.cssText = `position:absolute;inset:0;width:100%;height:100%;pointer-events:none;display:none;mix-blend-mode:${video ? 'screen' : 'normal'}`;\r\n  if (video) video.after(canvas); else host.prepend(canvas);\r\n  const g = canvas.getContext('2d', { alpha: true });\r\n  let GW = T.GLOW_WIDTH, GH = 1, hostW = 1, hostH = 1, alpha = 0, shown = false, wantMask = false, last = 0, emitCarry = 0, disposed = false;\r\n  const snap = { level: 0, speed: 0, route: null, effect: null, pulse: 0 };\r\n  const A = { x: 0, y: 0, a: 0 }, B = { x: 0, y: 0, a: 0 };\r\n  // particles: x, y, vx, vy, age, life, size, kind\r\n  const P = new Float32Array(T.PARTICLES * 8); let pNext = 0;\r\n  const impacts = Array.from({ length: 4 }, () => ({ t: -1e9, x: 0, y: 0, s: 0 })); let iNext = 0;\r\n  let halo = null, haloCtx = null, maskCanvas = null, maskCtx = null, maskImage = null, maskInfo = null, fb = null, fbCtx = null;\r\n\r\n  function resize() {\r\n    const r = host.getBoundingClientRect(); if (!(r.width > 0 && r.height > 0)) return;\r\n    hostW = r.width; hostH = r.height;\r\n    const h = Math.max(1, Math.round(GW * r.height / r.width));\r\n    if (canvas.width !== GW || canvas.height !== h) { canvas.width = GW; canvas.height = h; GH = h; fb = null; }\r\n  }\r\n  resize();\r\n  const ro = typeof ResizeObserver === 'function' ? new ResizeObserver(resize) : null; ro?.observe(host);\r\n\r\n  function onImpact(event) {\r\n    const d = event?.detail; if (!d || !Number.isFinite(d.x) || !Number.isFinite(d.y)) return;\r\n    let x = d.x, y = d.y;\r\n    if (x > 1.5 || y > 1.5) { const r = host.getBoundingClientRect(); x = (x - r.left) / (r.width || 1); y = (y - r.top) / (r.height || 1); }\r\n    const slot = impacts[iNext++ % impacts.length];\r\n    slot.t = performance.now(); slot.x = x; slot.y = y; slot.s = Math.max(0.2, Math.min(1, Number(d.strength) || 0.7));\r\n  }\r\n  target.addEventListener?.('myr5:punch-impact', onImpact);\r\n\r\n  function setWantMask(on) { if (on !== wantMask) { wantMask = on; globalThis.myr5AuraWantsMask = on; } }\r\n\r\n  /** New detection: mapped overlay points, capture time, optional mask {w,h,data} and video geometry. */\r\n  function pose(points, tMs, mask = null, geometry = null) {\r\n    if (disposed) return;\r\n    tracker.pose(points, tMs);\r\n    if (!mask?.data || !geometry || quality.tier < 3) { maskInfo = null; return; }\r\n    if (!maskCanvas || maskCanvas.width !== mask.w || maskCanvas.height !== mask.h) {\r\n      maskCanvas = document.createElement('canvas'); maskCanvas.width = mask.w; maskCanvas.height = mask.h;\r\n      maskCtx = maskCanvas.getContext('2d'); maskImage = maskCtx.createImageData(mask.w, mask.h);\r\n    }\r\n    const [r, gg, b] = auraPalette(snap.effect, snap.route)[0], d = maskImage.data, m = mask.data;\r\n    for (let k = 0, j = 0; k < m.length; k++, j += 4) { d[j] = r; d[j + 1] = gg; d[j + 2] = b; d[j + 3] = m[k]; }\r\n    maskCtx.putImageData(maskImage, 0, 0);\r\n    const rect = videoRectInOverlay({ videoWidth: geometry.videoWidth, videoHeight: geometry.videoHeight, hostWidth: hostW, hostHeight: hostH });\r\n    const hip = bodyCentre(points, 1, 1).hip; // raw hip of the mask's own frame (same inference)\r\n    maskInfo = rect ? { rect, mirrored: !!geometry.mirrored, hx: hip.x, hy: hip.y, at: performance.now() } : null;\r\n  }\r\n\r\n  function drawMask(ctx, scale, dx, dy, cx, cy) {\r\n    const { rect, mirrored } = maskInfo, x0 = rect.x * GW, y0 = rect.y * GH, rw = rect.w * GW, rh = rect.h * GH;\r\n    ctx.save(); ctx.translate(cx, cy); ctx.scale(scale, scale); ctx.translate(dx - cx, dy - cy);\r\n    if (mirrored) { ctx.translate(2 * x0 + rw, 0); ctx.scale(-1, 1); }\r\n    ctx.drawImage(maskCanvas, x0, y0, rw, rh); ctx.restore();\r\n  }\r\n\r\n  function emit(points, torso, level, speed, dt, styles) {\r\n    const rate = (T.EMIT_BASE + T.EMIT_LEVEL * level) * (1 + Math.min(1, speed / T.SPEED_REF));\r\n    emitCarry += rate * dt;\r\n    let guard = 0;\r\n    while (emitCarry >= 1 && guard++ < 24) {\r\n      emitCarry -= 1;\r\n      const bone = BONES[(Math.random() * BONES.length) | 0];\r\n      if (!jointPx(points, bone[0], GW, GH, A) || !jointPx(points, bone[1], GW, GH, B) || Math.min(A.a, B.a) < 0.5) continue;\r\n      const t = Math.random(), r = boneRadius(bone[2], torso, level, speed, T), ex = B.x - A.x, ey = B.y - A.y, len = Math.hypot(ex, ey) || 1;\r\n      const off = (Math.random() - 0.5) * 0.9 * r, k = pNext++ % T.PARTICLES * 8;\r\n      P[k] = A.x + ex * t - ey / len * off; P[k + 1] = A.y + ey * t + ex / len * off;\r\n      P[k + 2] = (Math.random() - 0.5) * 0.25 * torso; P[k + 3] = -(0.7 + 0.7 * Math.random()) * torso;\r\n      P[k + 4] = 0; P[k + 5] = 0.32 + 0.34 * Math.random(); P[k + 6] = r * (0.3 + 0.25 * Math.random()); P[k + 7] = Math.random() < 0.4 ? 2 : 1;\r\n    }\r\n    if (!styles.dots) styles.dots = [null, softDot(styles[0]), softDot(styles[1]), softDot(styles[2])];\r\n  }\r\n  function drawParticles(dt, gain, styles) {\r\n    for (let k = 0; k < P.length; k += 8) {\r\n      if (!(P[k + 5] > 0)) continue;\r\n      P[k + 4] += dt; const life = P[k + 4] / P[k + 5];\r\n      if (life >= 1) { P[k + 5] = 0; continue; }\r\n      P[k] += P[k + 2] * dt; P[k + 1] += P[k + 3] * dt; P[k + 2] *= 0.97;\r\n      const size = P[k + 6] * (1 - life * 0.55);\r\n      g.globalAlpha = Math.min(1, gain * 0.6 * (1 - life) ** 1.3);\r\n      g.drawImage(styles.dots[P[k + 7]], P[k] - size / 2, P[k + 1] - size * 0.8, size, size * 1.6);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Per animation frame. live: {active, level, speed, route, effect, pulse} (engine state); points: drawn landmarks\r\n   * from points(now). Returns the layer fade alpha (0..1) so the caller fades its sprites with the glow.\r\n   */\r\n  function draw(now, live, points) {\r\n    if (disposed) return 0;\r\n    const dt = last ? Math.min(0.05, Math.max(0, (now - last) / 1000)) : 0; last = now;\r\n    const on = !!(live?.active && live.level > 0);\r\n    if (on) { snap.level = live.level; snap.speed = live.speed || 0; snap.route = live.route; snap.effect = live.effect; snap.pulse = live.pulse || 0; }\r\n    else snap.pulse = 0;\r\n    alpha = fadeToward(alpha, on ? 1 : 0, dt * 1000, T.FADE_MS);\r\n    const tier = quality.tier;\r\n    setWantMask(tier >= 3 && alpha > 0);\r\n    if (alpha <= 0 || tier < 1) { if (shown) { g.clearRect(0, 0, canvas.width, canvas.height); canvas.style.display = 'none'; shown = false; } return alpha; }\r\n    if (!shown) { canvas.style.display = 'block'; shown = true; }\r\n    g.setTransform(1, 0, 0, 1, 0, 0); g.globalAlpha = 1; g.globalCompositeOperation = 'source-over'; g.clearRect(0, 0, GW, GH);\r\n    const torso = torsoPx(points, GW, GH); if (!torso) return alpha;\r\n    const level = snap.level, speed = snap.speed, styles = paletteStyles(auraPalette(snap.effect, snap.route));\r\n    let impact = 0;\r\n    for (const im of impacts) { const k = (now - im.t) / T.IMPACT_MS; if (k >= 0 && k < 1) impact = Math.max(impact, im.s * (1 - k)); }\r\n    const gain = alpha * (0.5 + 0.5 * level) * (1 + T.IMPACT_GAIN * impact + 0.4 * snap.pulse);\r\n    g.globalCompositeOperation = 'lighter'; g.lineCap = 'round'; g.lineJoin = 'round';\r\n\r\n    // Q3: silhouette halo + rising wisps from the person mask (falls back to capsules alone without a mask).\r\n    const centre = bodyCentre(points, GW, GH);\r\n    if (tier >= 3 && maskInfo && now - maskInfo.at < 400) {\r\n      if (!fb || fb.width !== GW || fb.height !== GH) { fb = document.createElement('canvas'); fb.width = GW; fb.height = GH; fbCtx = fb.getContext('2d'); }\r\n      const hip = centre.hip, dx = hip.x - maskInfo.hx * GW, dy = hip.y - maskInfo.hy * GH; // follow the predicted body\r\n      fbCtx.globalCompositeOperation = 'copy'; fbCtx.globalAlpha = T.WISP_DECAY; fbCtx.drawImage(fb, 0, -T.WISP_RISE);\r\n      fbCtx.globalCompositeOperation = 'lighter'; fbCtx.globalAlpha = Math.min(1, 0.4 * gain); drawMask(fbCtx, 1.06, dx, dy, centre.centre.x, centre.centre.y);\r\n      const noise = flameNoise(), scroll = (now * 0.05) % GH;\r\n      fbCtx.globalCompositeOperation = 'destination-out'; fbCtx.globalAlpha = 0.45;\r\n      fbCtx.drawImage(noise, 0, scroll - GH, GW, GH); fbCtx.drawImage(noise, 0, scroll, GW, GH);\r\n      g.globalAlpha = 1; g.drawImage(fb, 0, 0);\r\n      g.globalAlpha = Math.min(1, 0.5 * gain); drawMask(g, 1.1, dx, dy, centre.centre.x, centre.centre.y);\r\n      g.globalAlpha = Math.min(1, 0.28 * gain); drawMask(g, 1.22, dx, dy, centre.centre.x, centre.centre.y);\r\n    }\r\n\r\n    // Capsule halo along the bones on a 1/4-res canvas: outer colour -> mid -> hot core toward the bone, painted\r\n    // source-over (overlaps never burn to white), then upscaled with smoothing onto the glow layer = soft falloff.\r\n    const D = T.HALO_DOWNSCALE, hw = Math.max(1, Math.round(GW / D)), hh = Math.max(1, Math.round(GH / D));\r\n    if (!halo || halo.width !== hw || halo.height !== hh) { halo = document.createElement('canvas'); halo.width = hw; halo.height = hh; haloCtx = halo.getContext('2d'); }\r\n    const h = haloCtx; h.globalCompositeOperation = 'source-over'; h.globalAlpha = 1; h.clearRect(0, 0, hw, hh); h.lineCap = 'round';\r\n    const passes = tier >= 2 ? PASSES_FULL : PASSES_LITE, ht = torso / D;\r\n    for (const [width, a, colour] of passes) {\r\n      h.strokeStyle = h.fillStyle = styles[colour];\r\n      for (const [i, j, kind] of BONES) {\r\n        if (!jointPx(points, i, hw, hh, A) || !jointPx(points, j, hw, hh, B)) continue;\r\n        const r = boneRadius(kind, ht, level, speed, T) * width;\r\n        h.globalAlpha = Math.min(1, a * Math.min(A.a, B.a));\r\n        h.beginPath();\r\n        if (i === j) { h.arc(A.x, A.y, r, 0, 6.2832); h.fill(); }\r\n        else { h.lineWidth = 2 * r; h.moveTo(A.x, A.y); h.lineTo(B.x, B.y); h.stroke(); }\r\n      }\r\n    }\r\n    g.globalAlpha = Math.min(1, gain); g.imageSmoothingEnabled = true; g.drawImage(halo, 0, 0, GW, GH);\r\n    if (tier >= 2) { emit(points, torso, level, speed, dt, styles); drawParticles(dt, gain, styles); }\r\n\r\n    // Punch impact flare: hot flash + expanding ring at the fist.\r\n    for (const im of impacts) {\r\n      const k = (now - im.t) / T.IMPACT_MS; if (k < 0 || k >= 1) continue;\r\n      const x = im.x * GW, y = im.y * GH, s = torso * (0.35 + 0.3 * im.s) * (1 - k * 0.4);\r\n      if (!styles.dots) styles.dots = [null, softDot(styles[0]), softDot(styles[1]), softDot(styles[2])];\r\n      g.globalAlpha = Math.min(1, alpha * im.s * (1 - k) ** 2);\r\n      g.drawImage(styles.dots[3], x - s, y - s, 2 * s, 2 * s); g.drawImage(styles.dots[2], x - s * 1.6, y - s * 1.6, 3.2 * s, 3.2 * s);\r\n      g.strokeStyle = styles[1]; g.lineWidth = Math.max(1, torso * 0.05 * (1 - k)); g.globalAlpha = Math.min(1, alpha * (1 - k));\r\n      g.beginPath(); g.arc(x, y, torso * (0.12 + 0.5 * k), 0, 6.2832); g.stroke();\r\n    }\r\n\r\n    // Keep the person visible: punch the body itself out of the glow (soft, so a rim of light stays on the edges).\r\n    g.globalCompositeOperation = 'destination-out'; g.globalAlpha = T.CUT_ALPHA; g.strokeStyle = g.fillStyle = '#000';\r\n    if (tier >= 3 && maskInfo && now - maskInfo.at < 400) drawMask(g, 1, centre.hip.x - maskInfo.hx * GW, centre.hip.y - maskInfo.hy * GH, centre.centre.x, centre.centre.y);\r\n    else {\r\n      const quad = [11, 12, 24, 23];\r\n      if (quad.every(i => jointPx(points, i, GW, GH, A))) {\r\n        g.beginPath(); quad.forEach((i, n) => { jointPx(points, i, GW, GH, A); n ? g.lineTo(A.x, A.y) : g.moveTo(A.x, A.y); }); g.closePath(); g.fill();\r\n      }\r\n      for (const [i, j, kind] of BONES) {\r\n        if (!jointPx(points, i, GW, GH, A) || !jointPx(points, j, GW, GH, B)) continue;\r\n        const r = torso * (T.BODY[kind] ?? T.BODY.lower) * T.CUT;\r\n        g.beginPath();\r\n        if (i === j) { g.arc(A.x, A.y, r, 0, 6.2832); g.fill(); }\r\n        else { g.lineWidth = 2 * r; g.moveTo(A.x, A.y); g.lineTo(B.x, B.y); g.stroke(); }\r\n      }\r\n    }\r\n    g.globalCompositeOperation = 'source-over'; g.globalAlpha = 1;\r\n    return alpha;\r\n  }\r\n\r\n  function reset() { tracker.reset(); alpha = 0; maskInfo = null; P.fill(0); for (const im of impacts) im.t = -1e9; }\r\n  function dispose() {\r\n    if (disposed) return; disposed = true; ro?.disconnect(); target.removeEventListener?.('myr5:punch-impact', onImpact);\r\n    setWantMask(false); canvas.remove(); if (globalThis.myr5AuraBody === api) globalThis.myr5AuraBody = null;\r\n  }\r\n  const api = { pose, points: now => tracker.points(now), draw, reset, dispose, resize, canvas, get alpha() { return alpha; }, tracker };\r\n  globalThis.myr5AuraBody = api; // debug / harness: the drawn (filtered + predicted) skeleton\r\n  return api;\r\n}\r\n// [width multiple, alpha, palette slot]\r\nconst PASSES_FULL = [[1, 0.16, 0], [0.8, 0.22, 0], [0.6, 0.3, 1], [0.42, 0.42, 1], [0.28, 0.55, 2]];\r\nconst PASSES_LITE = [[1, 0.2, 0], [0.65, 0.35, 1], [0.35, 0.5, 2]];\r\n","arcade/power/aura-growth.mjs":"// One growth model for every aura group. Pure and renderer-free so holds, reps, punches and steps share it.\r\n// level 0..1 is what the renderers draw: it starts visible the instant an exercise is active, steps up on every\r\n// counted rep / detected punch or step, creeps up per second held or moved, and eases back down when you stop.\r\nexport const AURA_TUNING = Object.freeze({\r\n  START: 0.26,          // level the moment the exercise is active (small but clearly visible)\r\n  REP_STEP: 0.08,       // instant step per counted rep\r\n  BURST_STEP: 0.045,    // instant step per punch / knee lift / jump (fast limb burst) on pace and step work\r\n  HOLD_FIRST_S: 0.25,   // still-hold seconds before the first plant/animal/ice shows (engine default is 5 s)\r\n  HOLD_PER_SEC: 0.05,   // growth per second of valid hold\r\n  MOVE_PER_SEC: 0.1,    // continuous growth per second at MOVE_CAP body-lengths/s of limb speed\r\n  MOVE_CAP: 1.6,        // limb speed (torso lengths per second) that earns full MOVE_PER_SEC\r\n  MOVE_MIN: 0.25,       // slower than this is not movement\r\n  BURST_SPEED: 1.1,     // limb speed that counts as a punch / step\r\n  BURST_COOLDOWN_S: 0.22,\r\n  IDLE_GRACE_S: 1.2,    // seconds of no progress before decay starts\r\n  DECAY_PER_SEC: 0.1,   // decay toward START (never to nothing while the exercise is active)\r\n  EASE_PER_SEC: 9,      // drawn level chases the goal at this rate (smooth, but a step is seen within ~0.1 s)\r\n  // Discrete aura levels (1 = the aura is on, 2, 3 = the 3D coach joins). Thresholds on the growth goal (0..1).\r\n  // L3 is about 8 good reps (~12 s of steady work) or ~13 s of valid hold from a fresh start: roughly mid-set.\r\n  LEVELS: [0.26, 0.6, 0.92],\r\n  LEVEL_HYST: 0.15,     // goal must fall this far below a threshold to lose that level (no flicker on a short pause)\r\n  MAX: 1,\r\n  PULSE_FALL_PER_SEC: 2.5,\r\n  MAX_DT_S: 0.25,\r\n  LAYER_OPACITY: 0.85,   // effect canvas opacity over the camera (was capped at 0.3, which hid the auras)\r\n});\r\n\r\n// Sheets whose frames are mostly empty (measured alpha coverage) draw larger so every pick is readable on a phone.\r\nexport const SPARSE_BOOST = Object.freeze({ casting: 2, magichit: 2, weaponhit: 1.8, bluefire: 1.7, flamelash: 1.7, magicspell: 1.5, magicbubbles: 1.5, firespin: 1.4, phantom: 1.4, midnight: 1.4, protectioncircle: 1.3 });\r\n\r\nconst LIMBS = [15, 16, 25, 26, 27, 28]; // hands, knees, ankles\r\nconst clamp = (n, lo, hi) => Math.max(lo, Math.min(hi, n));\r\nconst ok = p => p && Number.isFinite(p.x) && Number.isFinite(p.y) && (p.visibility ?? 1) >= 0.5;\r\n\r\nfunction torso(points) {\r\n  const a = points[11], b = points[23], c = points[12], d = points[24];\r\n  const L = [[a, b], [c, d], [a, c]].filter(([p, q]) => ok(p) && ok(q)).map(([p, q]) => Math.hypot(p.x - q.x, p.y - q.y));\r\n  return L.length ? Math.max(0.05, Math.max(...L)) : 0.25;\r\n}\r\n\r\n/** Discrete level for a growth goal, with hysteresis from the previous level. */\r\nexport function auraLevel(goal, previous = 0, T = AURA_TUNING) {\r\n  let level = 0;\r\n  T.LEVELS.forEach((at, i) => { if (goal >= at - 1e-9 || (previous > i && goal >= at - T.LEVEL_HYST)) level = i + 1; });\r\n  return level;\r\n}\r\nfunction announce(level, previous) {\r\n  try { if (typeof CustomEvent === 'function' && globalThis.dispatchEvent) globalThis.dispatchEvent(new CustomEvent('myr5:aura-level', { detail: { level, previous } })); } catch { /* cosmetic */ }\r\n}\r\n\r\nexport function createGrowth(tuning = AURA_TUNING) {\r\n  const T = { ...AURA_TUNING, ...tuning };\r\n  const s = { level: 0, goal: 0, pulse: 0, speed: 0, started: false, bumps: 0, auraLevel: 0 };\r\n  const setAura = next => { if (next !== s.auraLevel) { const previous = s.auraLevel; s.auraLevel = next; announce(next, previous); } };\r\n  let prev = null, lastNow = null, lastGain = 0, lastBurst = -Infinity, lastUnits = null, burstArmed = true;\r\n\r\n  function reset() { Object.assign(s, { level: 0, goal: 0, pulse: 0, speed: 0, started: false, bumps: 0 }); setAura(0); prev = lastNow = lastUnits = null; lastGain = 0; lastBurst = -Infinity; burstArmed = true; return s; }\r\n  function bump(amount, now) { s.goal = Math.min(T.MAX, s.goal + amount); lastGain = now; s.pulse = 1; s.bumps++; }\r\n\r\n  /** kind: 'hold' | 'reps' | 'move' (pace / steps). units: counted reps. valid: hold is valid. points: normalized landmarks. */\r\n  function update({ now, points, kind, units = 0, valid = true }) {\r\n    if (!s.started) { s.started = true; s.goal = s.level = T.START; lastGain = now; }\r\n    const dt = lastNow == null ? 0 : clamp((now - lastNow) / 1000, 0, T.MAX_DT_S);\r\n    lastNow = now;\r\n    // limb speed in torso lengths per second\r\n    let speed = 0;\r\n    if (points && prev && dt > 0) {\r\n      const scale = torso(points), v = [];\r\n      for (const i of LIMBS) if (ok(points[i]) && ok(prev[i])) v.push(Math.hypot(points[i].x - prev[i].x, points[i].y - prev[i].y) / scale / dt);\r\n      if (v.length) speed = Math.max(...v);\r\n    }\r\n    if (points) prev = points.map(p => (ok(p) ? { x: p.x, y: p.y, visibility: p.visibility } : null));\r\n    s.speed = speed;\r\n    if (kind === 'hold') {\r\n      if (valid && dt) { s.goal = Math.min(T.MAX, s.goal + T.HOLD_PER_SEC * dt); lastGain = now; }\r\n    } else {\r\n      if (kind === 'reps') {\r\n        if (lastUnits != null && units > lastUnits) bump(T.REP_STEP * Math.min(3, units - lastUnits), now);\r\n        lastUnits = units;\r\n      } else if (speed >= T.BURST_SPEED && burstArmed && now / 1000 - lastBurst >= T.BURST_COOLDOWN_S) {\r\n        bump(T.BURST_STEP, now); lastBurst = now / 1000; burstArmed = false;\r\n      }\r\n      if (speed < T.BURST_SPEED * 0.6) burstArmed = true;\r\n      if (speed >= T.MOVE_MIN && dt) { s.goal = Math.min(T.MAX, s.goal + T.MOVE_PER_SEC * Math.min(1, speed / T.MOVE_CAP) * dt); lastGain = now; }\r\n    }\r\n    if (dt && (now - lastGain) / 1000 > T.IDLE_GRACE_S) s.goal = Math.max(T.START, s.goal - T.DECAY_PER_SEC * dt);\r\n    setAura(auraLevel(s.goal, s.auraLevel, T));\r\n    return s;\r\n  }\r\n\r\n  /** Per frame: ease the drawn level toward the goal and fall the pulse. */\r\n  function step(rawDt = 0) {\r\n    const dt = Math.min(0.05, Math.max(0, Number(rawDt) || 0));\r\n    s.level += (s.goal - s.level) * Math.min(1, dt * T.EASE_PER_SEC);\r\n    s.pulse = Math.max(0, s.pulse - dt * T.PULSE_FALL_PER_SEC);\r\n    return s;\r\n  }\r\n  return { state: s, update, step, reset, tuning: T };\r\n}\r\n","arcade/power/aura-options.mjs":"import { EXERCISES } from '../../exercise-library.mjs';\r\n\r\nexport const AURA_CHOICE_KEY = 'myr5-aura-choice-v1';\r\nexport const EFFECT_CHOICES_KEY = 'myr5-exercise-effect-choices-v1';\r\n\r\nexport const AURA_OPTIONS = Object.freeze([\r\n  { id: 'random', label: 'Random · rotate effects' },\r\n  { id: 'classic', label: 'Classic fire aura' },\r\n  { id: 'bluefire', label: 'Blue flame', asset: '3_bluefire_spritesheet.png', columns: 8, rows: 8 },\r\n  { id: 'magicbubbles', label: 'Magic bubbles', asset: '20_magicbubbles_spritesheet.png', columns: 8, rows: 8 },\r\n  { id: 'protectioncircle', label: 'Protection circle', asset: '8_protectioncircle_spritesheet.png', columns: 8, rows: 8, layout: 'circle' },\r\n  { id: 'vortex', label: 'Vortex', asset: '13_vortex_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'firespin', label: 'Fire spin', asset: '7_firespin_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'flamelash', label: 'Flame lash', asset: '6_flamelash_spritesheet.png', columns: 7, rows: 7 },\r\n  { id: 'weaponhit', label: 'Weapon hit spark', asset: '10_weaponhit_spritesheet.png', columns: 6, rows: 6 },\r\n  { id: 'casting', label: 'Casting ring', asset: '4_casting_spritesheet.png', columns: 9, rows: 9, layout: 'circle' },\r\n  { id: 'magicspell', label: 'Magic spell burst', asset: '1_magicspell_spritesheet.png', columns: 9, rows: 9 },\r\n  { id: 'magic8', label: 'Magic-eight trail', asset: '2_magic8_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'magichit', label: 'Magic hit', asset: '5_magickahit_spritesheet.png', columns: 7, rows: 7 },\r\n  { id: 'nebula', label: 'Nebula', asset: '12_nebula_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'phantom', label: 'Phantom', asset: '14_phantom_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'sunburn', label: 'Sunburn', asset: '16_sunburn_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'felspell', label: 'Felspell', asset: '17_felspell_spritesheet.png', columns: 10, rows: 10, layout: 'orbit' },\r\n  { id: 'midnight', label: 'Midnight', asset: '18_midnight_spritesheet.png', columns: 8, rows: 8, layout: 'orbit' },\r\n  { id: 'loading', label: 'Loading ring', asset: '15_loading_spritesheet.png', columns: 11, rows: 11, layout: 'circle' },\r\n  { id: 'blizzard', label: 'Blizzard ice', asset: '19_freezing_spritesheet.png', columns: 10, rows: 10, layout: 'orbit' },\r\n  { id: 'fern', label: 'Fern growth', ecology: { kind: 'plant', variant: 'fern' } },\r\n  { id: 'vine', label: 'Vine drift', ecology: { kind: 'plant', variant: 'vine' } },\r\n  { id: 'flower', label: 'Flower bloom', ecology: { kind: 'plant', variant: 'flower' } },\r\n  { id: 'mushroom', label: 'Fungi bloom', ecology: { kind: 'plant', variant: 'mushroom' } },\r\n  { id: 'grass', label: 'Grass growth', ecology: { kind: 'plant', variant: 'grass' } },\r\n  { id: 'reed', label: 'Reed growth', ecology: { kind: 'plant', variant: 'reed' } },\r\n  { id: 'rabbit', label: 'Rabbit companion', ecology: { kind: 'animal', variant: 'rabbit' } },\r\n  { id: 'fox', label: 'Fox companion', ecology: { kind: 'animal', variant: 'fox' } },\r\n  { id: 'bear', label: 'Bear companion', ecology: { kind: 'animal', variant: 'bear' } },\r\n  { id: 'deer', label: 'Deer companion', ecology: { kind: 'animal', variant: 'deer' } },\r\n  { id: 'wolf', label: 'Wolf companion', ecology: { kind: 'animal', variant: 'wolf' } },\r\n  { id: 'boar', label: 'Boar companion', ecology: { kind: 'animal', variant: 'boar' } },\r\n  { id: 'rock', label: 'Stone chips', ecology: { kind: 'mineral', variant: 'rock' } },\r\n  { id: 'crystal-blue', label: 'Blue crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'blue' } },\r\n  { id: 'crystal-ice', label: 'Ice crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'ice' } },\r\n  { id: 'crystal-red', label: 'Red crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'red' } },\r\n  { id: 'crystal-green', label: 'Green crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'green' } },\r\n  { id: 'crystal-gold', label: 'Gold crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'gold' } },\r\n  { id: 'crystal-purple', label: 'Purple crystal shards', ecology: { kind: 'mineral', variant: 'crystal', palette: 'purple' } },\r\n  { id: 'lightning', label: 'Lightning arcs', route: 'lightning' },\r\n  { id: 'floor', label: 'Floor sparks', route: 'floor' },\r\n]);\r\n\r\nexport const ROTATING_AURAS = Object.freeze(AURA_OPTIONS.filter(option => option.id !== 'random').map(option => option.id));\r\nexport const EFFECT_OPTION_BY_ID = new Map(AURA_OPTIONS.map(option => [option.id, option]));\r\n\r\nconst ECOLOGY_IDS = AURA_OPTIONS.filter(option => option.ecology).map(option => option.id);\r\nconst GROUPS = [\r\n  { id: 'yoga', label: 'Yoga & mobility', options: [...ECOLOGY_IDS, 'magicbubbles', 'nebula', 'phantom', 'midnight'], defaultEffect: 'fern' },\r\n  { id: 'stances', label: 'Martial stances', options: ['flamelash', 'casting', 'felspell'], defaultEffect: 'casting' },\r\n  { id: 'legs', label: 'Legs & hips', options: ['classic', 'firespin', 'vortex', 'sunburn'], defaultEffect: 'classic' },\r\n  { id: 'shoulders', label: 'Arms & shoulders', options: ['magic8', 'weaponhit', 'magichit', 'lightning'], defaultEffect: 'lightning' },\r\n  { id: 'floor', label: 'Floor exercises', options: ['bluefire', 'magicspell', 'floor'], defaultEffect: 'floor' },\r\n  { id: 'core', label: 'Core & balance', options: ['blizzard', 'protectioncircle', 'loading'], defaultEffect: 'blizzard' },\r\n].map(group => Object.freeze({ ...group, options: Object.freeze(['random', ...group.options]) }));\r\n\r\nexport const EFFECT_GROUPS = Object.freeze(GROUPS);\r\nconst GROUP_BY_ID = new Map(EFFECT_GROUPS.map(group => [group.id, group]));\r\nconst HOME_GROUP = new Map(EFFECT_GROUPS.flatMap(group => group.options.filter(id => id !== 'random').map(id => [id, group.id])));\r\nconst DEFAULT_CHOICES = Object.freeze(Object.fromEntries(EFFECT_GROUPS.map(group => [group.id, 'random'])));\r\nconst VALID = new Set(AURA_OPTIONS.map(option => option.id));\r\n\r\n/** camera: live camera effects also cover boxing (Arms & shoulders pick) and cardio (Legs & hips pick); saved avatar history still skips them. */\r\nexport function effectGroupForExercise(mode, { camera = false } = {}) {\r\n  const ex = typeof mode === 'string' ? EXERCISES[mode] : mode;\r\n  if (!ex || typeof ex !== 'object') return null;\r\n  if (ex.group === 'boxing') return camera ? 'shoulders' : null;\r\n  if (ex.group === 'cardio') return camera ? 'legs' : null;\r\n  if (ex.kind === 'hold') {\r\n    if (ex.group === 'stances') return 'stances';\r\n    if (ex.group === 'core' || ex.group === 'balance') return 'core';\r\n    if (ex.group === 'yoga' || ex.group === 'legs') return 'yoga';\r\n  }\r\n  if (['pushup', 'bridge', 'plank', 'sideplank'].includes(ex.detector)) return 'floor';\r\n  if (ex.group === 'shoulders') return 'shoulders';\r\n  if (ex.group === 'legs' || ex.group === 'hips') return 'legs';\r\n  return null;\r\n}\r\n\r\nfunction validChoice(group, choice) { return GROUP_BY_ID.get(group)?.options.includes(choice) ?? false; }\r\nfunction choiceRecord(storage) {\r\n  try {\r\n    const raw = (storage ?? globalThis.localStorage)?.getItem(EFFECT_CHOICES_KEY);\r\n    if (raw) {\r\n      const data = JSON.parse(raw);\r\n      if (data?.version === 1 && data.choices && typeof data.choices === 'object') {\r\n        return Object.fromEntries(EFFECT_GROUPS.map(group => [group.id,\r\n          validChoice(group.id, data.choices[group.id]) ? data.choices[group.id] : group.defaultEffect]));\r\n      }\r\n    }\r\n  } catch { /* fall through to safe defaults or one-group migration */ }\r\n  const choices = { ...DEFAULT_CHOICES };\r\n  try {\r\n    const legacy = (storage ?? globalThis.localStorage)?.getItem(AURA_CHOICE_KEY);\r\n    const group = HOME_GROUP.get(legacy);\r\n    if (group && validChoice(group, legacy)) choices[group] = legacy;\r\n  } catch { /* inaccessible storage uses defaults */ }\r\n  return choices;\r\n}\r\n\r\nexport function readEffectChoices(storage) { return choiceRecord(storage); }\r\n\r\nexport function saveEffectChoice(group, choice, { storage, target } = {}) {\r\n  if (!validChoice(group, choice)) return false;\r\n  try {\r\n    const store = storage ?? globalThis.localStorage;\r\n    if (!store?.setItem) return false;\r\n    const choices = choiceRecord(storage);\r\n    choices[group] = choice;\r\n    store.setItem(EFFECT_CHOICES_KEY, JSON.stringify({ version: 1, choices }));\r\n  } catch { return false; }\r\n  try { (target ?? globalThis.window)?.dispatchEvent?.(new CustomEvent('myr5:exercise-effect-choice-change', { detail: { group, choice } })); }\r\n  catch { /* Storage events synchronize other tabs. */ }\r\n  return true;\r\n}\r\n\r\nexport function resolveEffectForGroup(group, choices = {}, random = Math.random) {\r\n  const definition = GROUP_BY_ID.get(group);\r\n  if (!definition) return null;\r\n  const choice = choices[group] ?? definition.defaultEffect;\r\n  if (choice !== 'random') return validChoice(group, choice) ? choice : definition.defaultEffect;\r\n  const variants = definition.options.filter(id => id !== 'random');\r\n  const value = Number(random());\r\n  const index = Math.min(variants.length - 1, Math.max(0, Math.floor((Number.isFinite(value) ? value : 0) * variants.length)));\r\n  return variants[index];\r\n}\r\n\r\nexport function resolveExerciseEffect(mode, choices = {}, random = Math.random, opts) {\r\n  return resolveEffectForGroup(effectGroupForExercise(mode, opts), choices, random);\r\n}\r\n\r\n// Legacy global helpers stay for old clients; the new runtime reads only the\r\n// versioned per-exercise-group record above.\r\nexport function readAuraChoice(storage) {\r\n  try {\r\n    const choice = (storage ?? globalThis.localStorage)?.getItem(AURA_CHOICE_KEY);\r\n    return VALID.has(choice) ? choice : 'random';\r\n  } catch { return 'random'; }\r\n}\r\n\r\nexport function resolveAuraChoice(choice = 'random', random = Math.random) {\r\n  if (choice === 'random') {\r\n    const value = Number(random());\r\n    const index = Math.min(ROTATING_AURAS.length - 1, Math.max(0, Math.floor((Number.isFinite(value) ? value : 0) * ROTATING_AURAS.length)));\r\n    return ROTATING_AURAS[index];\r\n  }\r\n  return VALID.has(choice) ? choice : 'classic';\r\n}\r\n\r\nexport function saveAuraChoice(choice, { storage, target } = {}) {\r\n  if (!VALID.has(choice)) return false;\r\n  try { (storage ?? globalThis.localStorage)?.setItem(AURA_CHOICE_KEY, choice); }\r\n  catch { return false; }\r\n  try { (target ?? globalThis.window)?.dispatchEvent?.(new CustomEvent('myr5:aura-choice-change', { detail: { choice } })); }\r\n  catch { /* Storage changes in another tab still arrive through the storage event. */ }\r\n  return true;\r\n}\r\n","arcade/power/avatar-power.mjs":"// A silent, intermittent pixel effect attached to the companion card. It never\r\n// calls the coach's play/walk APIs, so existing gestures remain in control.\r\nimport { renderPower } from './power.mjs';\r\nimport { renderBlizzard } from '../hold/blizzard.mjs';\r\nimport { renderEcosystem } from '../hold/render.mjs';\r\nimport { AURA_OPTIONS, EFFECT_CHOICES_KEY, effectGroupForExercise, readEffectChoices, resolveEffectForGroup } from './aura-options.mjs';\r\nimport { EXERCISES } from '../../exercise-library.mjs';\r\n\r\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\r\nfunction randomFor(seed = 1) {\r\n  let value = (Number(seed) >>> 0) || 0x9e3779b9;\r\n  return () => {\r\n    value ^= value << 13; value ^= value >>> 17; value ^= value << 5;\r\n    return (value >>> 0) / 0x100000000;\r\n  };\r\n}\r\nfunction currentExerciseMode() {\r\n  try {\r\n    const owner = globalThis.myr5WorkoutOwner?.snapshot?.();\r\n    return owner?.workout?.mode ?? owner?.mode ?? globalThis.myr5TestState?.motion?.mode ?? null;\r\n  } catch { return globalThis.myr5TestState?.motion?.mode ?? null; }\r\n}\r\nfunction fallbackGroup(style) {\r\n  return style === 'lightning' ? 'shoulders' : style === 'floor' ? 'floor' : style === 'blizzard' ? 'core' : style === 'aura' ? 'legs' : null;\r\n}\r\nfunction styleForGroup(group) {\r\n  return group === 'shoulders' ? 'lightning' : group === 'floor' ? 'floor' : group === 'core' ? 'blizzard' : 'aura';\r\n}\r\nfunction groupForContext(mode, previewGroup, record) {\r\n  if (previewGroup) return previewGroup;\r\n  if (mode && EXERCISES[mode]) return effectGroupForExercise(mode);\r\n  return record.styles?.[record.equipped]?.group ?? fallbackGroup(record.equipped) ?? 'legs';\r\n}\r\nexport function avatarEffectContext({ mode = null, previewGroup = null, record = null, effectChoices = {}, random = Math.random } = {}) {\r\n  const group = groupForContext(mode, previewGroup, record ?? { styles: {} });\r\n  return { group, effect: group ? resolveEffectForGroup(group, effectChoices, random) : null };\r\n}\r\nexport function usesNativeBlizzard(effect) { return effect === 'blizzard'; }\r\n\r\n/** Deterministic visible-time scheduler, exported for direct timing tests. */\r\nexport function createAvatarPowerSchedule({ seed = 1, minInterval = 12, maxInterval = 24, duration = 1.4 } = {}) {\r\n  const random = randomFor(seed);\r\n  const interval = () => clamp(minInterval, 1, 120) + random() * Math.max(0, clamp(maxInterval, minInterval, 120) - clamp(minInterval, 1, 120));\r\n  let until = interval(), burst = 0, disposed = false;\r\n  return {\r\n    step(rawDt, visible, reducedMotion = false) {\r\n      if (disposed) return 0;\r\n      const dt = clamp(Number.isFinite(rawDt) ? rawDt : 0, 0, 0.25);\r\n      if (!visible) {\r\n        if (burst > 0) { burst = 0; until = interval(); }\r\n        return 0;\r\n      }\r\n      if (burst > 0) {\r\n        burst = Math.max(0, burst - dt);\r\n        if (!burst) until = interval();\r\n        return burst > 0 ? 1 : 0;\r\n      }\r\n      until -= dt;\r\n      if (until <= 0) { burst = reducedMotion ? 0.45 : clamp(duration, 0.5, 2); return 1; }\r\n      return 0;\r\n    },\r\n    reset() { if (disposed) return; burst = 0; until = interval(); },\r\n    dispose() { disposed = true; burst = until = 0; },\r\n    get remaining() { return until; },\r\n    get active() { return burst > 0; },\r\n  };\r\n}\r\nexport function avatarLayerOpacity(cameraTracking) { return cameraTracking ? 0.08 : 0.55; }\r\n\r\nfunction stageFor(card) {\r\n  if (card?.matches?.('.myr5-companion-stage')) return card;\r\n  return card?.querySelector?.('.myr5-companion-stage') ?? card;\r\n}\r\nfunction renderEcologyAura(ctx, state, id) {\r\n  const ecology = AURA_OPTIONS.find(option => option.id === id)?.ecology;\r\n  if (!ecology) return false;\r\n  const { w, h, time = 0 } = state, ground = h * .9;\r\n  let entities;\r\n  if (ecology.kind === 'plant') {\r\n    entities = [.22, .5, .78].map((fraction, index) => ({ id: index + 1, kind: 'plant', variant: ecology.variant,\r\n      x: w * fraction, y: ground + (index === 1 ? 1 : 0), size: Math.min(54, w * .38), growth: .92 + index * .04,\r\n      alpha: .88, phaseTime: time + index * .7 }));\r\n  } else if (ecology.kind === 'animal') {\r\n    entities = [{ id: 1, kind: 'animal', variant: ecology.variant, phase: 'idle', x: w * .5, y: ground,\r\n      size: Math.min(50, w * .4), growth: 1, alpha: .92, phaseTime: time }];\r\n  } else {\r\n    entities = [.24, .5, .76].map((fraction, index) => ({ id: index + 1, kind: 'mineral', variant: ecology.variant,\r\n      palette: ecology.palette, x: w * fraction, y: ground, size: Math.min(30, w * .22), growth: 1,\r\n      alpha: .9, phaseTime: time }));\r\n  }\r\n  renderEcosystem(ctx, { entities, debris: [] });\r\n  return true;\r\n}\r\nexport function avatarPowerState(record, width, height, time = 0, pulse = 0, walking = false, powerAnchors = null) {\r\n  const style = record?.equipped, stored = style && record.styles?.[style];\r\n  if (!stored || !['aura', 'lightning', 'floor', 'blizzard'].includes(style)) return null;\r\n  const center = width * 0.5, sway = walking ? Math.sin(time * 5) * width * 0.045 : 0;\r\n  if (style === 'blizzard') {\r\n    const leftFoot = center - width * .10 + sway * 1.8, rightFoot = center + width * .10 + sway * 1.8;\r\n    const leftKnee = center - width * .09 + sway * 1.4, rightKnee = center + width * .09 + sway * 1.4;\r\n    const leftHip = center - width * .08 + sway, rightHip = center + width * .08 + sway;\r\n    const leftShoulder = center - width * .12 + sway * .35, rightShoulder = center + width * .12 + sway * .35;\r\n    const points = [[27,25,leftFoot,height*.86,leftKnee,height*.72],[25,23,leftKnee,height*.72,leftHip,height*.59],\r\n      [28,26,rightFoot,height*.86,rightKnee,height*.72],[26,24,rightKnee,height*.72,rightHip,height*.59],\r\n      [23,11,leftHip,height*.59,leftShoulder,height*.32],[24,12,rightHip,height*.59,rightShoulder,height*.32],\r\n      [11,13,leftShoulder,height*.32,center-width*.18+sway*.55,height*.43],\r\n      [12,14,rightShoulder,height*.32,center+width*.18+sway*.55,height*.43]];\r\n    const growth = clamp(.34 + stored.intensity * .66, .34, 1);\r\n    const iceEdges = points.map(([from,to,x1,y1,x2,y2]) => ({ from,to,x1:Math.round(x1),y1:Math.round(y1),\r\n      x2:Math.round(x2),y2:Math.round(y2),growth,alpha:.58+stored.intensity*.27 }));\r\n    const snowCount = Math.min(18, 5 + Math.round(stored.intensity * 13));\r\n    const snow = Array.from({ length: snowCount }, (_, i) => {\r\n      const phase = i * 2.399963229728653 + (walking ? time * 1.4 : time * .45);\r\n      return { x: Math.round(center + Math.cos(phase) * width * (.14 + (i % 4) * .025)),\r\n        y: Math.round(height * (.36 + (i % 5) * .095) + Math.sin(phase * 1.17) * height * .035),\r\n        size: 1 + (i % (stored.tier > 3 ? 3 : 2)), alpha: .2 + stored.intensity * .18 };\r\n    });\r\n    return { blizzard: true, stillSeconds: 5 + time * 2, iceEdges, snow };\r\n  }\r\n  const points = Array.from({ length: 33 }, () => null);\r\n  const put = (index, x, y) => { points[index] = { x: x / width, y: y / height, visibility: 1 }; };\r\n  // These are local character-art anchors, not camera/tracker contacts.\r\n  put(11, center - width * .12 + sway * .35, height * .30);\r\n  put(12, center + width * .12 + sway * .35, height * .30);\r\n  put(13, center - width * .18 + sway * .55, height * .42);\r\n  put(14, center + width * .18 + sway * .55, height * .42);\r\n  put(15, center - width * .22 + sway * .65, height * .54);\r\n  put(16, center + width * .22 + sway * .65, height * .54);\r\n  put(23, center - width * .08 + sway, height * .60);\r\n  put(24, center + width * .08 + sway, height * .60);\r\n  put(25, center - width * .09 + sway * 1.4, height * .73);\r\n  put(26, center + width * .09 + sway * 1.4, height * .73);\r\n  put(27, center - width * .10 + sway * 1.8, height * .85);\r\n  put(28, center + width * .10 + sway * 1.8, height * .85);\r\n  const contacts = style === 'floor' ? (powerAnchors ?? [])\r\n    .filter(anchor => anchor?.visible && Number.isFinite(anchor.x) && Number.isFinite(anchor.y))\r\n    .slice(0, 2)\r\n    .map(anchor => ({ index: anchor.index, x: anchor.x * width, y: anchor.y * height })) : [];\r\n  return { w: width, h: height, route: style, active: true, units: stored.units, maxUnits: stored.maxUnits,\r\n    intensity: stored.intensity, tier: stored.tier, pulse, contacts, points, time };\r\n}\r\n\r\nfunction isVisible(card, stage, canvas, stats) {\r\n  if (!card?.isConnected || !stage?.isConnected || card.hidden || stage.hidden || document.hidden) return false;\r\n  if (card.dataset?.coachCap === 'hidden' || card.dataset?.coachVisible === 'false') return false;\r\n  if (stats?.visible === false || stats?.paused === true) return false;\r\n  const rect = stage.getBoundingClientRect?.();\r\n  if (rect && (!(rect.width > 0) || !(rect.height > 0))) return false;\r\n  for (let node = stage; node && node !== document.documentElement?.parentElement; node = node.parentElement) {\r\n    const style = globalThis.getComputedStyle?.(node);\r\n    if (style && (style.display === 'none' || style.visibility === 'hidden' || Number(style.opacity) === 0)) return false;\r\n    if (node === card) break;\r\n  }\r\n  canvas.style.display = '';\r\n  return true;\r\n}\r\n\r\nexport function mountAvatarPower({ card, retained, sound: _sound, seed = 1 } = {}) {\r\n  if (!card) throw new TypeError('A companion card is required.');\r\n  const stage = stageFor(card);\r\n  if (!stage?.appendChild) throw new TypeError('The companion card needs an overlay stage.');\r\n  const canvas = document.createElement('canvas');\r\n  canvas.className = 'myr5-avatar-power-canvas';\r\n  canvas.setAttribute('aria-hidden', 'true');\r\n  Object.assign(canvas.style, { inset: '0', width: '100%', height: '100%', imageRendering: 'pixelated', pointerEvents: 'none', zIndex: '1', opacity: '.55', display: 'none' });\r\n  canvas.style.setProperty('position', 'absolute', 'important');\r\n  stage.appendChild(canvas);\r\n  const ctx = canvas.getContext('2d', { alpha: true });\r\n  if (!ctx) { canvas.remove(); throw new Error('A transparent 2D canvas is unavailable.'); }\r\n\r\n  const reduced = globalThis.matchMedia?.('(prefers-reduced-motion: reduce)') ?? { matches: false, addEventListener() {}, removeEventListener() {} };\r\n  const schedule = createAvatarPowerSchedule({ seed });\r\n  const random = randomFor((Number(seed) ^ 0x41555241) >>> 0);\r\n  let effectChoices = readEffectChoices(), previewGroup = null, currentEffect = null;\r\n  let record = retained?.read?.() ?? { version: 1, equipped: null, styles: {} };\r\n  function context(groupPreview = previewGroup) {\r\n    return avatarEffectContext({ mode: currentExerciseMode(), previewGroup: groupPreview, record, effectChoices, random });\r\n  }\r\n  let effectiveGroup = context().group;\r\n  function selectedEffect(group = effectiveGroup) {\r\n    return group ? resolveEffectForGroup(group, effectChoices, random) : null;\r\n  }\r\n  currentEffect = context().effect;\r\n  let fingerprint = JSON.stringify(record), width = 1, height = 1, dpr = 1, lastFrame = 0, lastSizeCheck = 0, time = 0, pulse = 0, previewRemaining = 0, wasActive = false, raf = 0, disposed = false;\r\n  let resizeObserver = null;\r\n\r\n  function resize() {\r\n    if (disposed) return;\r\n    const rect = stage.getBoundingClientRect();\r\n    if (!(rect.width > 0 && rect.height > 0)) return;\r\n    width = rect.width; height = rect.height; dpr = clamp(globalThis.devicePixelRatio || 1, 1, 2);\r\n    const pixelWidth = Math.max(1, Math.round(width * dpr)), pixelHeight = Math.max(1, Math.round(height * dpr));\r\n    if (canvas.width !== pixelWidth || canvas.height !== pixelHeight) { canvas.width = pixelWidth; canvas.height = pixelHeight; }\r\n    ctx.setTransform(canvas.width / width, 0, 0, canvas.height / height, 0, 0);\r\n    ctx.imageSmoothingEnabled = false;\r\n  }\r\n  function refresh() {\r\n    if (disposed) return;\r\n    const next = retained?.read?.() ?? { version: 1, equipped: null, styles: {} };\r\n    const nextFingerprint = JSON.stringify(next);\r\n    if (nextFingerprint !== fingerprint) {\r\n      record = next; fingerprint = nextFingerprint; schedule.reset(); pulse = 0; wasActive = false;\r\n      effectiveGroup = context().group; currentEffect = context().effect;\r\n      ctx.clearRect(0, 0, width, height); canvas.style.display = 'none';\r\n    }\r\n  }\r\n  function choiceChanged(event) {\r\n    effectChoices = readEffectChoices();\r\n    previewGroup = event?.detail?.group ?? null;\r\n    effectiveGroup = context().group; currentEffect = context().effect;\r\n    schedule.reset(); wasActive = false;\r\n    if (previewGroup) { pulse = 1; previewRemaining = 2.4; }\r\n    else pulse = 0;\r\n  }\r\n  function paint(now) {\r\n    if (disposed) return;\r\n    raf = requestAnimationFrame(paint);\r\n    if (lastFrame && now - lastFrame < 33) return;\r\n    const dt = lastFrame ? clamp((now - lastFrame) / 1000, 0, .25) : 0;\r\n    lastFrame = now;\r\n    if (!resizeObserver && now - lastSizeCheck >= 500) { lastSizeCheck = now; resize(); }\r\n    let stats = null;\r\n    try { stats = globalThis.myr5Creature?.stats?.() ?? null; } catch { /* coach stats are an optional visibility hint */ }\r\n    const mode = currentExerciseMode();\r\n    const nextGroup = context().group;\r\n    if (nextGroup !== effectiveGroup) {\r\n      effectiveGroup = nextGroup; currentEffect = selectedEffect(effectiveGroup);\r\n      schedule.reset(); wasActive = false; pulse = 0;\r\n      ctx.clearRect(0, 0, width, height); canvas.style.display = 'none';\r\n    }\r\n    if (previewRemaining <= 0 && mode && EXERCISES[mode] && !effectGroupForExercise(mode)) {\r\n      wasActive = false; pulse = 0; ctx.clearRect(0, 0, width, height); canvas.style.display = 'none'; return;\r\n    }\r\n    const canShow = isVisible(card, stage, canvas, stats);\r\n    const hadPreview = previewRemaining > 0;\r\n    previewRemaining = Math.max(0, previewRemaining - (canShow ? dt : 0));\r\n    if (hadPreview && previewRemaining === 0) { previewGroup = null; effectiveGroup = context(null).group; currentEffect = selectedEffect(effectiveGroup); }\r\n    const active = previewRemaining > 0 ? 1 : schedule.step(dt, canShow, reduced.matches);\r\n    if (!active) { wasActive = false; pulse = 0; ctx.clearRect(0, 0, width, height); canvas.style.display = 'none'; return; }\r\n    canvas.style.display = 'block';\r\n    canvas.style.opacity = String(avatarLayerOpacity(document.body?.dataset?.tracking === 'true'));\r\n    const reducedMotion = reduced.matches;\r\n    time += reducedMotion ? 0 : dt;\r\n    if (!wasActive) { pulse = 1; currentEffect = selectedEffect(); }\r\n    wasActive = true;\r\n    pulse = Math.max(0, pulse - dt * 2.5);\r\n    const selectedStyle = styleForGroup(effectiveGroup);\r\n    const earnedStyle = record.styles?.[selectedStyle] ?? record.styles?.[record.equipped];\r\n    const visualRecord = earnedStyle\r\n      ? { equipped: selectedStyle, styles: { [selectedStyle]: earnedStyle } }\r\n      : { equipped: selectedStyle, styles: { [selectedStyle]: { units: 1, maxUnits: 1, intensity: .38, tier: 1 } } };\r\n    const state = avatarPowerState(visualRecord, width, height, reducedMotion ? 0 : time,\r\n      reducedMotion ? 0 : pulse, stats?.gesture === 'walk' || stats?.phoneMotionPhase === 'walk', stats?.powerAnchors);\r\n    if (state?.blizzard && !usesNativeBlizzard(currentEffect)) {\r\n      Object.assign(state, { w: width, h: height, route: selectedStyle, active: true,\r\n        intensity: visualRecord.styles[selectedStyle]?.intensity ?? 0, tier: visualRecord.styles[selectedStyle]?.tier ?? 0,\r\n        points: [] });\r\n    }\r\n    if (state) state.effect = currentEffect;\r\n    ctx.clearRect(0, 0, width, height);\r\n    if (state && !renderEcologyAura(ctx, state, state.effect)) {\r\n      if (state?.blizzard && usesNativeBlizzard(state.effect)) renderBlizzard(ctx, state);\r\n      else renderPower(ctx, state);\r\n    }\r\n  }\r\n\r\n  resize();\r\n  if (typeof ResizeObserver === 'function') { resizeObserver = new ResizeObserver(resize); resizeObserver.observe(stage); }\r\n  else globalThis.addEventListener?.('resize', resize);\r\n  const visibility = () => {\r\n    if (document.hidden) { schedule.step(0, false); wasActive = false; pulse = 0; ctx.clearRect(0, 0, width, height); canvas.style.display = 'none'; }\r\n    lastFrame = 0;\r\n  };\r\n  document.addEventListener?.('visibilitychange', visibility);\r\n  globalThis.addEventListener?.('myr5:exercise-effect-choice-change', choiceChanged);\r\n  const storageChanged = event => { if (event?.key === EFFECT_CHOICES_KEY) choiceChanged(); };\r\n  globalThis.addEventListener?.('storage', storageChanged);\r\n  globalThis.addEventListener?.('pagehide', stop, { once: true });\r\n  raf = requestAnimationFrame(paint);\r\n  function stop() {\r\n    if (disposed) return;\r\n    disposed = true; cancelAnimationFrame(raf); resizeObserver?.disconnect();\r\n    globalThis.removeEventListener?.('resize', resize); globalThis.removeEventListener?.('pagehide', stop);\r\n    globalThis.removeEventListener?.('myr5:exercise-effect-choice-change', choiceChanged);\r\n    globalThis.removeEventListener?.('storage', storageChanged);\r\n    document.removeEventListener?.('visibilitychange', visibility); schedule.dispose();\r\n    ctx.clearRect(0, 0, width, height); canvas.remove();\r\n  }\r\n  return { refresh, stop };\r\n}\r\n","arcade/power/camera-power.mjs":"import {createPower,renderPower} from './power.mjs';\r\nimport {AURA_TUNING} from './aura-growth.mjs';\r\nimport {createAuraBody} from './aura-body.mjs';\r\nexport {preloadAuraForMode} from './power.mjs';\r\nconst AURA_LAYER_OPACITY=AURA_TUNING.LAYER_OPACITY;\r\nimport {createOverlayCanvas,mapPointsToOverlay,effectQuality} from '../workout-effects.mjs';\r\n\r\nconst LOGICAL_WIDTH=360,MAX_GAIN=.045;\r\nfunction makeCue(sound,payload){\r\n if(!sound?.voice||!sound?.tone)return null;\r\n const intensity=Math.max(0,Math.min(1,Number(payload?.intensity)||0));\r\n const level=MAX_GAIN*(.35+.65*intensity),route=payload?.route;\r\n const start=route==='lightning'?520:route==='floor'?180:260,end=route==='lightning'?860:route==='floor'?260:420;\r\n return sound.voice('workout-power',.2,args=>sound.tone(args,start,.16,level,route==='floor'?'triangle':'sine',end));\r\n}\r\n\r\nexport function mountCameraPower({host,sound,seed=Date.now(),quality=effectQuality}={}){\r\n if(!host)throw new TypeError('A camera overlay host is required.');\r\n const layer=createOverlayCanvas(host,'workout-power-canvas',{opacity:AURA_LAYER_OPACITY,max:1}),canvas=layer.canvas,ctx=canvas.getContext('2d',{alpha:true});\r\n // Glow under the sprites; both draw from the same filtered + predicted landmarks so they stay on the body together.\r\n const body=createAuraBody({host,quality});\r\n let engine=null,w=LOGICAL_WIDTH,h=1,raf=0,lastFrame=0,disposed=false,resizeObserver=null,voice=null;\r\n const shown={active:false};let fade=0; // last active engine state, kept to fade out instead of a hard clear\r\n const stopVoice=()=>{voice?.stop?.(.025);voice=null;};\r\n function makeEngine(){engine=createPower({w,h,seed,onEvent(type,payload){if(type==='pulse'){stopVoice();voice=makeCue(sound,payload);}}});}\r\n function resize(){\r\n  if(disposed)return;const rect=host.getBoundingClientRect();if(!(rect.width>0&&rect.height>0))return;\r\n  layer.resize();const nextH=Math.max(1,Math.round(LOGICAL_WIDTH*rect.height/rect.width));\r\n  const changed=!engine||nextH!==h;w=LOGICAL_WIDTH;h=nextH;\r\n  if(changed){stopVoice();engine?.reset();makeEngine();}\r\n  ctx.setTransform(canvas.width/w,0,0,canvas.height/h,0,0);ctx.imageSmoothingEnabled=false;\r\n }\r\n function paint(now){\r\n  if(disposed)return;const dt=lastFrame?Math.max(0,(now-lastFrame)/1000):0;\r\n  if(lastFrame)quality.frame(now-lastFrame);lastFrame=now;\r\n  engine.step(dt);\r\n  const state=engine.state;if(state.active)Object.assign(shown,state);\r\n  const points=body.points(now);\r\n  fade=body.draw(now,state,points);\r\n  ctx.setTransform(canvas.width/w,0,0,canvas.height/h,0,0);ctx.clearRect(0,0,w,h);\r\n  if(fade>0&&shown.active){shown.time=state.time;shown.pulse=state.active?state.pulse:0;renderPower(ctx,shown,{points,alpha:fade});}\r\n  canvas.style.display=fade>0?'block':'none';\r\n  raf=requestAnimationFrame(paint);\r\n }\r\n resize();\r\n if(typeof ResizeObserver==='function'){resizeObserver=new ResizeObserver(resize);resizeObserver.observe(host);}else window.addEventListener('resize',resize);\r\n raf=requestAnimationFrame(paint);\r\n function pose(detail={}){\r\n  if(disposed)return;resize();\r\n  const geometry={videoWidth:detail.width,videoHeight:detail.height,hostWidth:w,hostHeight:h,mirrored:detail.mirrored};\r\n  const points=mapPointsToOverlay(detail.points,geometry);\r\n  engine.pose({points,now:detail.now,workout:{...detail.workout,validHold:!!detail.validHold}});\r\n  body.pose(points,Number.isFinite(detail.frameMs)?detail.frameMs:detail.now,detail.mask,geometry);\r\n  if(!detail.workout?.active)stopVoice();\r\n }\r\n function invalidate(){if(disposed)return;engine.invalidate();stopVoice();}\r\n function stop(){if(disposed)return;disposed=true;cancelAnimationFrame(raf);resizeObserver?.disconnect();window.removeEventListener('resize',resize);stopVoice();engine?.reset();body.dispose();layer.dispose();}\r\n return {get engine(){return engine;},get body(){return body;},pose,stop,invalidate};\r\n}\r\n","arcade/power/power.mjs":"// Pure workout power progression plus a small Canvas2D renderer. Reuses the repo's\r\n// progression rules and CC0 pixel effect sheets; no new rendering dependency.\r\nimport { EXERCISES } from '../../exercise-library.mjs';\r\nimport { REP_CAP, HOLD_BLOCK_SECONDS, HOLD_CAP_SECONDS, repRate } from '../../progression-rules.mjs';\r\nimport { createGrowth, SPARSE_BOOST } from './aura-growth.mjs';\r\nimport { AURA_OPTIONS, EFFECT_GROUPS, effectGroupForExercise, readEffectChoices, resolveExerciseEffect } from './aura-options.mjs';\r\nimport { AURA_BODY, LEG_SLOTS, ARM_SLOTS, bodyScale, sheetSprite, slotPx, circlePlacement, pulsePlacement } from './aura-anchor.mjs';\r\n\r\nexport const POWER_STALE_MS = 1000;\r\nconst REP_BANDS = Array.from({ length: REP_CAP - 1 }, (_, i) => i + 2)\r\n  .filter(rep => repRate('easy', rep) !== repRate('easy', rep - 1));\r\nconst FLOOR_DETECTORS = new Set(['pushup', 'bridge', 'plank', 'sideplank']);\r\nconst CONFIDENCE = 0.5;\r\n\r\nfunction exerciseOf(exercise) { return typeof exercise === 'string' ? EXERCISES[exercise] : exercise; }\r\nexport function powerRoute(exercise) {\r\n  const ex = exerciseOf(exercise);\r\n  if (!ex || typeof ex !== 'object') return null;\r\n  if (ex.group === 'boxing') return 'lightning';\r\n  if (ex.group === 'cardio') return 'aura';\r\n  if (ex.kind === 'pace') return null;\r\n  if (ex.kind === 'hold') return ex.group === 'stances' ? 'aura' : null;\r\n  if (ex.kind !== 'reps' && ex.kind !== 'steps') return null;\r\n  if (FLOOR_DETECTORS.has(ex.detector)) return 'floor';\r\n  if (ex.detector === 'raise' || ex.detector === 'press' || ex.group === 'shoulders') return 'lightning';\r\n  if (['squat', 'split', 'hinge'].includes(ex.detector) || ['legs', 'hips'].includes(ex.group)) return 'aura';\r\n  return 'aura';\r\n}\r\n/** Style used for saved avatar power, including styles that do not draw camera power. */\r\nexport function retainedPowerStyle(exercise) {\r\n  const ex = exerciseOf(exercise);\r\n  if (!ex || typeof ex !== 'object') return null;\r\n  if (ex.kind === 'hold') {\r\n    if (ex.group === 'stances') return 'aura';\r\n    if (ex.group === 'core' || ex.group === 'balance') return 'blizzard';\r\n    return null;\r\n  }\r\n  if (ex.group === 'boxing' || ex.group === 'cardio') return null; // retained avatar power stays rep-work only\r\n  return powerRoute(ex);\r\n}\r\n\r\nfunction pointAt(points, index) { return Array.isArray(points) ? points[index] : points?.[index] ?? points?.[String(index)]; }\r\nfunction cleanPoints(points) {\r\n  if (!points) return [];\r\n  const length = Array.isArray(points) ? points.length : Math.max(-1, ...Object.keys(points).map(Number)) + 1;\r\n  return Array.from({ length }, (_, index) => {\r\n    const p = pointAt(points, index), visibility = Number(p?.visibility ?? p?.score ?? p?.confidence);\r\n    if (!p || !Number.isFinite(p.x) || !Number.isFinite(p.y) || !Number.isFinite(visibility) || visibility < CONFIDENCE) return null;\r\n    return { x: p.x, y: p.y, visibility };\r\n  });\r\n}\r\nfunction visible(points, index) {\r\n  const p = points[index];\r\n  return p && p.visibility >= CONFIDENCE && p.x >= 0 && p.x <= 1 && p.y >= 0 && p.y <= 1;\r\n}\r\nfunction sideIndices(points, side) {\r\n  const left = side !== 'right';\r\n  return left ? { shoulder: 11, elbow: 13, wrist: 15, hip: 23, knee: 25, ankle: 27, heel: 29, toe: 31 }\r\n    : { shoulder: 12, elbow: 14, wrist: 16, hip: 24, knee: 26, ankle: 28, heel: 30, toe: 32 };\r\n}\r\nfunction footIndex(points, side) {\r\n  const ix = sideIndices(points, side);\r\n  return [ix.heel, ix.toe, ix.ankle].find(i => visible(points, i));\r\n}\r\nfunction toContacts(points, indices, w, h) {\r\n  const unique = [...new Set(indices)].filter(i => Number.isInteger(i) && visible(points, i)).slice(0, 4);\r\n  return unique.map(index => ({ index, x: points[index].x * w, y: points[index].y * h }));\r\n}\r\nfunction floorContacts(ex, points, w, h) {\r\n  const d = ex?.detector;\r\n  if (d === 'bridge') return toContacts(points, [footIndex(points, 'left'), footIndex(points, 'right'), 11, 12], w, h);\r\n  if (d === 'sideplank') {\r\n    const ix = sideIndices(points, ex.side);\r\n    const limb = ex.support === 'knees' ? ix.knee : footIndex(points, ex.side);\r\n    return toContacts(points, [ix.elbow, limb], w, h);\r\n  }\r\n  const arms = ex.forearm ? [13, 14] : [15, 16];\r\n  const lowers = ex.support === 'knees' ? [25, 26] : [29, 30, 31, 32, 27, 28];\r\n  const lower = ex.support === 'knees' ? lowers.filter(i => visible(points, i)).slice(0, 2)\r\n    : [footIndex(points, 'left'), footIndex(points, 'right')].filter(Number.isInteger);\r\n  return toContacts(points, [...arms, ...lower], w, h);\r\n}\r\n/** Metadata-based visible support anchors shared by floor power, Blizzard and avatar overlays. */\r\nexport function supportContacts(exercise, points, w = 360, h = 640) {\r\n  const ex = exerciseOf(exercise);\r\n  if (!ex) return [];\r\n  if (FLOOR_DETECTORS.has(ex.detector)) return floorContacts(ex, cleanPoints(points), w, h);\r\n  if (ex.kind !== 'hold') return [];\r\n  const clean = cleanPoints(points);\r\n  const left=footIndex(clean,'left'),right=footIndex(clean,'right');\r\n  if(ex.group==='balance'){\r\n    const supported=[left,right].filter(Number.isInteger).sort((a,b)=>clean[b].y-clean[a].y)[0];\r\n    return toContacts(clean,[supported],w,h);\r\n  }\r\n  return toContacts(clean,[left,right],w,h);\r\n}\r\nfunction bandTier(reps) { return reps <= 0 ? 0 : REP_BANDS.filter(n => reps >= n).length + 1; }\r\nfunction maxUnits(kind) { return kind === 'hold' ? HOLD_CAP_SECONDS / HOLD_BLOCK_SECONDS : REP_CAP; }\r\nfunction progressFor(workout) {\r\n  if (workout?.kind === 'hold') {\r\n    const seconds = Number.isFinite(workout.activeSeconds) ? Math.min(HOLD_CAP_SECONDS, Math.max(0, workout.activeSeconds)) : 0;\r\n    const units = Math.floor(seconds / HOLD_BLOCK_SECONDS);\r\n    const max = maxUnits('hold');\r\n    return { units, maxUnits: max, intensity: Math.sqrt(units / max), tier: units <= 0 ? 0 : Math.min(6, Math.ceil(Math.sqrt(units / max) * 6)) };\r\n  }\r\n  const reps = Number.isFinite(workout?.workingReps) ? Math.min(REP_CAP, Math.max(0, Math.floor(workout.workingReps))) : 0;\r\n  return { units: reps, maxUnits: REP_CAP, intensity: reps / REP_CAP, tier: bandTier(reps) };\r\n}\r\n/** Authoritative progression units reused by retained character cosmetics. */\r\nexport function powerProgress(workout = {}) {\r\n  const progress = progressFor(workout);\r\n  return { ...progress, kind: workout.kind === 'hold' ? 'hold' : 'reps' };\r\n}\r\n\r\nexport function createPower({ w = 360, h = 640, seed = 1, onEvent = () => {} } = {}) {\r\n  const state = { w, h, route: null, effect: null, active: false, units: 0, maxUnits: REP_CAP, intensity: 0, tier: 0, level: 0, speed: 0, pulse: 0, contacts: [], points: [], time: 0 };\r\n  const growth = createGrowth();\r\n  let lastBumps = 0;\r\n  let sessionId = null, mode = null, workoutKind = null, baseline = false, lastUnits = 0;\r\n  let effectKey = null, effectRandomState = (Number(seed) >>> 0) || 0x9e3779b9;\r\n  const effectRandom = () => { effectRandomState ^= effectRandomState << 13; effectRandomState ^= effectRandomState >>> 17; effectRandomState ^= effectRandomState << 5; return (effectRandomState >>> 0) / 0x100000000; };\r\n  let lastNow = null, poseAge = Infinity, suppressNextPulse = true;\r\n  const emit = (type, payload) => { try { onEvent(type, payload); } catch { /* cosmetic observers never affect workout flow */ } };\r\n  function clearVisible() { state.active = false; state.pulse = 0; state.level = 0; state.speed = 0; state.contacts = []; state.points = []; growth.reset(); lastBumps = 0; }\r\n  function clearProgress() {\r\n    state.units = 0; state.intensity = 0; state.tier = 0; state.maxUnits = REP_CAP;\r\n    lastUnits = 0; baseline = false; workoutKind = null;\r\n  }\r\n  function hideForStale() { clearVisible(); poseAge = Infinity; lastNow = null; suppressNextPulse = true; }\r\n  function reset() {\r\n    clearVisible(); clearProgress(); state.route = null; state.effect = null; state.time = 0; effectKey = null;\r\n    sessionId = mode = null; lastNow = null; poseAge = Infinity; suppressNextPulse = true;\r\n    return state;\r\n  }\r\n  function invalidate() { hideForStale(); return state; }\r\n  function updateProgress(workout, { allowPulse }) {\r\n    const progress = progressFor(workout), kind = workout.kind === 'hold' ? 'hold' : 'reps';\r\n    const changedKind = workoutKind !== null && workoutKind !== kind;\r\n    if (changedKind) { clearProgress(); }\r\n    state.maxUnits = progress.maxUnits;\r\n    state.units = progress.units; state.intensity = progress.intensity; state.tier = progress.tier;\r\n    if (!baseline) {\r\n      lastUnits = progress.units; baseline = true; workoutKind = kind; state.pulse = 0;\r\n      return;\r\n    }\r\n    const delta = progress.units - lastUnits;\r\n    lastUnits = progress.units; workoutKind = kind;\r\n    if (delta > 0 && allowPulse && !suppressNextPulse) {\r\n      state.pulse = 1;\r\n      emit('pulse', { route: state.route, intensity: state.intensity, units: state.units, deltaUnits: delta, kind, difficulty: workout.difficulty });\r\n    } else if (delta < 0 || !allowPulse || suppressNextPulse) state.pulse = 0;\r\n  }\r\n  function pose({ points, now, workout } = {}) {\r\n    if (!workout || !Number.isFinite(now)) { hideForStale(); return state; }\r\n    // Pace/step work (boxing, marching) has no rep ledger; its counter must not fire rep pulses every frame.\r\n    if (!['reps', 'hold'].includes(EXERCISES[workout.mode]?.kind) && workout.workingReps) workout = { ...workout, workingReps: 0 };\r\n    const nextMode = workout.mode ?? null, nextSession = workout.sessionId ?? null;\r\n    const route = powerRoute(nextMode);\r\n    const newIdentity = sessionId !== nextSession || mode !== nextMode;\r\n    if (newIdentity) {\r\n      clearProgress(); clearVisible(); sessionId = nextSession; mode = nextMode; state.route = route;\r\n      lastNow = null; poseAge = Infinity; suppressNextPulse = true;\r\n    } else state.route = route;\r\n    const group = effectGroupForExercise(nextMode, { camera: true }), choices = readEffectChoices();\r\n    const selection = group ? choices[group] : null, nextEffectKey = group ? `${group}:${selection}` : null;\r\n    if (newIdentity || nextEffectKey !== effectKey) {\r\n      state.effect = group ? resolveExerciseEffect(nextMode, choices, effectRandom, { camera: true }) : null;\r\n      effectKey = nextEffectKey;\r\n    }\r\n    if (!route) { clearVisible(); lastNow = now; poseAge = 0; return state; }\r\n    if (lastNow != null && now <= lastNow) return state;\r\n    const staleGap = lastNow != null && now - lastNow > POWER_STALE_MS;\r\n    if (staleGap) { clearVisible(); suppressNextPulse = true; }\r\n    const clean = cleanPoints(points);\r\n    const working = typeof workout.stage === 'string' && !['preparation-rest', 'sprint-rest'].includes(workout.stage); // warm-up reps grow the aura too\r\n    if (!clean.some(Boolean) || workout.active !== true || !working || (workout.kind === 'hold' && workout.validHold !== true)) {\r\n      updateProgress(workout, { allowPulse: false });\r\n      clearVisible(); lastNow = now; poseAge = 0; suppressNextPulse = true;\r\n      return state;\r\n    }\r\n    const supportedKind = workout.kind === 'hold' ? (route === 'aura' && workout.validHold === true) : true;\r\n    if (!supportedKind) { clearVisible(); lastNow = now; poseAge = 0; return state; }\r\n    const contacts = route === 'floor' ? floorContacts(EXERCISES[nextMode], clean, w, h) : [];\r\n    const allowPulse = !newIdentity && !staleGap && !suppressNextPulse && (route !== 'floor' || contacts.length > 0);\r\n    updateProgress(workout, { allowPulse });\r\n    const wasSuppressed = suppressNextPulse;\r\n    suppressNextPulse = false;\r\n    state.active = true; state.points = clean;\r\n    state.contacts = contacts;\r\n    if (route === 'floor' && state.contacts.length === 0) state.pulse = 0;\r\n    if (route !== 'floor' && state.units === 0) state.pulse = 0;\r\n    if (wasSuppressed) state.pulse = 0;\r\n    const exKind = EXERCISES[nextMode]?.kind;\r\n    const growKind = workout.kind === 'hold' ? 'hold' : exKind === 'reps' ? 'reps' : 'move';\r\n    growth.update({ now, points: clean, kind: growKind, units: progressFor(workout).units, valid: workout.validHold === true });\r\n    state.level = growth.state.level; state.speed = growth.state.speed;\r\n    if (growKind === 'move' && growth.state.bumps > lastBumps) {\r\n      state.pulse = 1; emit('pulse', { route: state.route, intensity: growth.state.goal, units: state.units, deltaUnits: 1, kind: 'move', difficulty: workout.difficulty });\r\n    }\r\n    lastBumps = growth.state.bumps;\r\n    lastNow = now; poseAge = 0;\r\n    return state;\r\n  }\r\n  function step(rawDt = 0) {\r\n    const dtRaw = Number.isFinite(rawDt) && rawDt > 0 ? rawDt : 0;\r\n    state.time += Math.min(0.05, dtRaw);\r\n    poseAge += dtRaw * 1000;\r\n    state.pulse = Math.max(0, state.pulse - Math.min(0.05, dtRaw) * 2.5);\r\n    growth.step(dtRaw); if (state.active) state.level = growth.state.level;\r\n    if (poseAge > POWER_STALE_MS && lastNow != null) hideForStale();\r\n    return state;\r\n  }\r\n  return { state, pose, step, reset, invalidate };\r\n}\r\n\r\n// Renderer ---------------------------------------------------------------\r\nconst imageCache = new Map();\r\nconst frameCache = new Map();\r\nconst spriteSources = {\r\n  // Crop boxes are the union of nontransparent pixel bounds across populated cells\r\n  // (PIL alpha>8). Frames are 100x100, row-major; normalize each crop to a 64px\r\n  // cache while preserving its aspect ratio and bottom-aligning the sprite pivot.\r\n  fire: ['/arcade/power/assets/11_fire_spritesheet.png', 100, 8, 61, [40, 27, 65, 78]],\r\n  brightfire: ['/arcade/power/assets/9_brightfire_spritesheet.png', 100, 8, 61, [45, 37, 61, 69]],\r\n  lightning: ['/arcade/power/assets/pixelated_tilesheet.png', 64, 4, 8, [0, 0, 64, 64]],\r\n};\r\nfunction loadImage(key) {\r\n  if (imageCache.has(key)) return imageCache.get(key);\r\n  if (typeof Image === 'undefined') return null;\r\n  const image = new Image(); imageCache.set(key, image);\r\n  image.onload = () => {}; image.onerror = () => imageCache.delete(key); image.src = spriteSources[key][0];\r\n  return image;\r\n}\r\nfunction drawSheetFrame(ctx, key, frame, x, y, size, alpha = 1, rotation = 0) {\r\n  const image = loadImage(key), [, frameSize, columns, frameCount, bounds] = spriteSources[key];\r\n  if (!image?.complete || !image.naturalWidth || typeof document === 'undefined') return;\r\n  const sourceFrame = ((frame % frameCount) + frameCount) % frameCount;\r\n  const cacheKey = `${key}:${sourceFrame}`;\r\n  let sprite = frameCache.get(cacheKey);\r\n  if (!sprite) {\r\n    sprite = document.createElement('canvas'); sprite.width = sprite.height = 64;\r\n    const source = sprite.getContext('2d');\r\n    if (!source) return;\r\n    source.imageSmoothingEnabled = false;\r\n    const [left, top, right, bottom] = bounds, cropWidth = right - left, cropHeight = bottom - top;\r\n    const scale = 64 / Math.max(cropWidth, cropHeight), drawWidth = cropWidth * scale, drawHeight = cropHeight * scale;\r\n    const destX = (64 - drawWidth) / 2, destY = 64 - drawHeight;\r\n    source.drawImage(image, (sourceFrame % columns) * frameSize + left, Math.floor(sourceFrame / columns) * frameSize + top,\r\n      cropWidth, cropHeight, destX, destY, drawWidth, drawHeight);\r\n    frameCache.set(cacheKey, sprite);\r\n  }\r\n  ctx.save(); ctx.globalAlpha *= alpha; ctx.translate(Math.round(x), Math.round(y));\r\n  if (rotation) ctx.rotate(rotation);\r\n  ctx.drawImage(sprite, -size / 2, -size / 2, size, size);\r\n  ctx.restore();\r\n}\r\nconst auraSources = new Map(AURA_OPTIONS.filter(option => option.asset).map(option => [option.id, {\r\n  path: `/arcade/${option.id === 'blizzard' ? 'hold' : 'power'}/assets/${option.asset}`,\r\n  columns: option.columns, rows: option.rows, layout: option.layout ?? 'body',\r\n}]));\r\nfunction loadAuraImage(id) {\r\n  const source = auraSources.get(id);\r\n  if (!source) return null;\r\n  const key = `aura:${id}`;\r\n  if (imageCache.has(key)) return imageCache.get(key);\r\n  if (typeof Image === 'undefined') return null;\r\n  const image = new Image(); imageCache.set(key, image);\r\n  image.onerror = () => imageCache.delete(key); image.src = source.path;\r\n  return image;\r\n}\r\n/** Start decoding the sprite sheet(s) for an effect so the first frame is not waiting on the network. */\r\nexport function preloadAura(id) {\r\n  loadAuraImage(id);\r\n  if (typeof Image !== 'undefined' && !auraSources.has(id)) for (const key of ['fire', 'brightfire', 'lightning']) loadImage(key);\r\n}\r\n/** Warm every sheet the exercise's group can pick (all of them when the saved choice is Random). */\r\nexport function preloadAuraForMode(mode, choices = readEffectChoices()) {\r\n  const group = effectGroupForExercise(mode, { camera: true });\r\n  if (!group) return;\r\n  const pick = choices[group];\r\n  const ids = pick && pick !== 'random' ? [pick] : EFFECT_GROUPS.find(g => g.id === group)?.options.filter(id => id !== 'random') ?? [];\r\n  for (const id of ids) preloadAura(id);\r\n}\r\nfunction drawAuraFrame(ctx, id, frame, x, y, size, alpha = 1, rotation = 0) {\r\n  const source = auraSources.get(id), image = loadAuraImage(id);\r\n  if (!source || !image?.complete || !image.naturalWidth || typeof document === 'undefined') return;\r\n  const frameCount = source.columns * source.rows;\r\n  const sourceFrame = ((frame % frameCount) + frameCount) % frameCount;\r\n  const cacheKey = `aura:${id}:${sourceFrame}`;\r\n  let sprite = frameCache.get(cacheKey);\r\n  if (!sprite) {\r\n    sprite = document.createElement('canvas'); sprite.width = sprite.height = 64;\r\n    const sourceContext = sprite.getContext('2d');\r\n    if (!sourceContext) return;\r\n    sourceContext.imageSmoothingEnabled = false;\r\n    const frameSize = 100;\r\n    sourceContext.drawImage(image, (sourceFrame % source.columns) * frameSize,\r\n      Math.floor(sourceFrame / source.columns) * frameSize, frameSize, frameSize, 0, 0, 64, 64);\r\n    frameCache.set(cacheKey, sprite);\r\n  }\r\n  ctx.save(); ctx.globalAlpha *= alpha; ctx.translate(Math.round(x), Math.round(y));\r\n  if (rotation) ctx.rotate(rotation);\r\n  size *= SPARSE_BOOST[id] ?? 1;\r\n  ctx.drawImage(sprite, -size / 2, -size / 2, size, size); ctx.restore();\r\n}\r\nfunction drawPixelCrack(ctx, x, y, size, tier, time, seed) {\r\n  const branches = Math.min(6, 2 + Math.floor(tier * 0.7));\r\n  const arm = Math.max(4, Math.round(size * (0.55 + tier * 0.03)));\r\n  ctx.save(); ctx.translate(Math.round(x), Math.round(y)); ctx.strokeStyle = '#ffc65a'; ctx.lineWidth = 1;\r\n  ctx.globalAlpha = 0.68 + Math.min(0.27, tier * 0.045) + Math.sin(time * 8 + seed) * 0.025;\r\n  for (let i = 0; i < branches; i++) {\r\n    const side = i % 2 ? 1 : -1, start = (Math.floor(i / 2) - 1) * 2;\r\n    ctx.beginPath(); ctx.moveTo(start, 0); ctx.lineTo(start + side * Math.round(arm * 0.22), Math.round(arm * 0.22));\r\n    ctx.lineTo(start + side * Math.round(arm * 0.5), Math.round(arm * 0.38));\r\n    if (tier >= 3) ctx.lineTo(start + side * Math.round(arm * 0.68), Math.round(arm * 0.22));\r\n    ctx.stroke();\r\n  }\r\n  ctx.restore();\r\n}\r\nfunction pointPixel(state, index) {\r\n  const points = state.points ?? [], p = points[index];\r\n  return visible(points, index) ? { x: p.x * state.w, y: p.y * state.h, a: Number.isFinite(p.alpha) ? p.alpha : 1 } : null;\r\n}\r\n/** Floor contacts follow the drawn (filtered, predicted) landmark of the same index. */\r\nfunction contactPixel(state, contact) { return (contact.index != null && pointPixel(state, contact.index)) || contact; }\r\n// Classic fire: small flames pinned along the legs (each to its own bone slot), pushed out from the bone and\r\n// flickering around that spot. Sizes are torso multiples so the flames match the body near or far.\r\nconst SLOT = { x: 0, y: 0, a: 0, dx: 0, dy: 1 };\r\nfunction auraAccents(state, torso) {\r\n  const count = Math.min(18, 3 + Math.floor(state.tier * 2.5)), out = [];\r\n  for (let i = 0; i < count; i++) {\r\n    if (!slotPx(state.points, LEG_SLOTS[i % LEG_SLOTS.length], state.w, state.h, SLOT)) continue;\r\n    const angle = (i * 2.399963229728653) + state.time * (0.25 + state.intensity * 0.2), side = i % 2 ? 1 : -1;\r\n    const push = torso * (0.07 + (i % 4) * (0.016 + state.tier * 0.004)), wobble = torso * 0.03;\r\n    out.push({ index: 23 + (i % 6), x: SLOT.x - SLOT.dy * push * side + Math.cos(angle) * wobble, y: SLOT.y + SLOT.dx * push * side + Math.sin(angle) * wobble, angle, a: SLOT.a });\r\n  }\r\n  return out;\r\n}\r\nfunction lightningAccents(state, torso) {\r\n  const count = Math.min(12, 2 + state.tier * 2), out = [];\r\n  for (let i = 0; i < count; i++) {\r\n    if (!slotPx(state.points, ARM_SLOTS[i % ARM_SLOTS.length], state.w, state.h, SLOT)) continue;\r\n    const phase = state.time * 4 + i * 1.37, j = torso * (0.02 + state.tier * 0.007);\r\n    out.push({ index: 11 + (i % 6), x: SLOT.x + Math.sin(phase) * j, y: SLOT.y + Math.cos(phase) * j * 0.6, frame: Math.floor(state.time * 9 + i) % 8, a: SLOT.a });\r\n  }\r\n  return out;\r\n}\r\nconst SPRITE = { x: 0, y: 0, a: 0, dx: 0, dy: 1, size: 0, rotation: 0 };\r\n/**\r\n * opts.points: drawn landmarks (filtered + predicted, with per-point `alpha`) instead of state.points;\r\n * opts.alpha: whole-layer fade (0..1). Sizes scale with the on-screen torso, not the canvas.\r\n */\r\nexport function renderPower(ctx, raw, opts = {}) {\r\n  const level = raw?.level ?? raw?.intensity ?? 0;\r\n  if (!ctx || !raw?.active || level <= 0) return;\r\n  // Draw tier and intensity follow the shared growth level, not the XP ledger.\r\n  const state = { ...raw, points: opts.points ?? raw.points, intensity: level, tier: Math.max(1, Math.ceil(level * 6)) };\r\n  const canvas = ctx.canvas;\r\n  if (!canvas || typeof document === 'undefined') return;\r\n  const width = Math.max(1, Math.ceil(state.w)), height = Math.max(1, Math.ceil(state.h));\r\n  if (!renderPower.layer || renderPower.layer.width !== width || renderPower.layer.height !== height) {\r\n    renderPower.layer = document.createElement('canvas'); renderPower.layer.width = width; renderPower.layer.height = height;\r\n    renderPower.layerContext = renderPower.layer.getContext('2d');\r\n  }\r\n  const layer = renderPower.layerContext;\r\n  if (!layer) return;\r\n  layer.clearRect(0, 0, width, height); layer.imageSmoothingEnabled = false; layer.globalCompositeOperation = 'source-over';\r\n  const frame = Math.floor(state.time * 7), torso = bodyScale(state.points, state.w, state.h), T = AURA_BODY;\r\n  const sheet = state.effect && state.effect !== 'classic' && auraSources.has(state.effect);\r\n  if (sheet) {\r\n    const source = auraSources.get(state.effect);\r\n    if (state.route === 'floor') {\r\n      for (const contact of state.contacts.slice(0, 4)) {\r\n        const c = contactPixel(state, contact);\r\n        drawAuraFrame(layer, state.effect, frame + (contact.index ?? 0) * 7, c.x, c.y, torso * T.FLOOR_SIZE * (0.6 + 0.4 * level), .9 * (c.a ?? 1), 0);\r\n      }\r\n    } else if (source.layout === 'circle') {\r\n      const c = circlePlacement(state.points, state.w, state.h, level);\r\n      drawAuraFrame(layer, state.effect, frame, c.x, c.y, c.size, .76, state.time * .08);\r\n    } else {\r\n      const full = state.effect === 'magicbubbles' ? 8 : source.layout === 'orbit' ? 5 : 4;\r\n      const count = Math.max(1, Math.round(full * (0.3 + 0.7 * level)));\r\n      for (let i = 0; i < count; i++) {\r\n        if (!sheetSprite(state.points, i, source.layout, state.time, state.w, state.h, torso, level, SPRITE)) continue;\r\n        drawAuraFrame(layer, state.effect, frame + i * 7, SPRITE.x, SPRITE.y, SPRITE.size, .78 * SPRITE.a, SPRITE.rotation);\r\n      }\r\n    }\r\n  } else if (state.route === 'aura') {\r\n    for (const a of auraAccents(state, torso)) drawSheetFrame(layer, 'brightfire', frame + a.index * 3, a.x, a.y,\r\n      torso * (0.107 + Math.max(0, state.tier - 1) * 0.023), 0.95 * a.a, a.angle);\r\n  } else if (state.route === 'lightning') {\r\n    for (const a of lightningAccents(state, torso)) drawSheetFrame(layer, 'lightning', a.frame, a.x, a.y, torso * (0.1 + state.tier * 0.017), 0.95 * a.a, 0);\r\n  } else if (state.route === 'floor') {\r\n    for (const contact of state.contacts.slice(0, 4)) {\r\n      const c = contactPixel(state, contact);\r\n      drawPixelCrack(layer, c.x, c.y, torso * (0.073 + state.tier * 0.011), state.tier, state.time, contact.index);\r\n      drawSheetFrame(layer, 'fire', frame + contact.index * 4, c.x, c.y, torso * (0.12 + state.tier * 0.017), 0.95 * (c.a ?? 1), 0);\r\n    }\r\n  }\r\n  if (state.pulse > 0) {\r\n    if (sheet && state.route === 'floor') {\r\n      for (const contact of state.contacts.slice(0, 4)) {\r\n        const c = contactPixel(state, contact);\r\n        drawAuraFrame(layer, state.effect, frame + 23 + (contact.index ?? 0) * 7, c.x, c.y, torso * (0.33 + state.tier * 0.033), .9 * state.pulse, 0);\r\n      }\r\n    } else if (sheet) {\r\n      const p = pulsePlacement(state.points, state.w, state.h);\r\n      drawAuraFrame(layer, state.effect, frame + 23, p.x, p.y, p.size, .9 * state.pulse, 0);\r\n    } else {\r\n      const accents = state.route === 'lightning' ? lightningAccents(state, torso).slice(0, 4) : state.route === 'aura' ? auraAccents(state, torso).slice(0, 6)\r\n        : state.contacts.slice(0, 4).map(contact => ({ ...contactPixel(state, contact), index: contact.index }));\r\n      for (const point of accents) {\r\n        if (state.route === 'floor' && point.index != null) drawSheetFrame(layer, 'fire', frame + 9, point.x, point.y, torso * (0.1 + state.tier * 0.01), 0.9 * state.pulse, 0);\r\n        else if (state.route === 'lightning') drawSheetFrame(layer, 'lightning', frame % 8, point.x, point.y, torso * (0.1 + state.tier * 0.009), 0.9 * state.pulse, 0);\r\n        else drawSheetFrame(layer, 'brightfire', frame + 17, point.x, point.y, torso * (0.107 + state.tier * 0.011), 0.9 * state.pulse, 0);\r\n      }\r\n    }\r\n  }\r\n  ctx.save(); ctx.imageSmoothingEnabled = false; ctx.globalCompositeOperation = 'source-over';\r\n  // The wrapper applies the shared .3 effects-layer filter cap. This local alpha\r\n  // keeps early rep accents readable while the composed ecology+power layer stays translucent.\r\n  const fade = Math.max(0, Math.min(1, opts.alpha ?? state.alpha ?? 1));\r\n  ctx.globalAlpha = (0.7 + 0.3 * level) * fade; ctx.drawImage(renderPower.layer, 0, 0, width, height); ctx.restore();\r\n}\r\n","arcade/power/retained-power.mjs":"// Owner-scoped cosmetic carryover. Progress always comes from the same\r\n// progression rules used by camera power; this module never awards workout XP.\r\nimport { powerProgress, retainedPowerStyle } from './power.mjs';\r\nimport { EXERCISES } from '../../exercise-library.mjs';\r\nimport { EFFECT_GROUPS, effectGroupForExercise } from './aura-options.mjs';\r\n\r\nexport const RETAINED_POWER_KEY = 'myr5-retained-character-power-v1';\r\nconst STYLES = new Set(['aura', 'lightning', 'floor', 'blizzard']);\r\nconst GROUPS = new Set(EFFECT_GROUPS.map(group => group.id));\r\nconst STYLE_GROUPS = { aura: new Set(['legs', 'stances']), lightning: new Set(['shoulders']), floor: new Set(['floor']), blizzard: new Set(['core']) };\r\nconst MAX_OWNER_LENGTH = 240;\r\nconst empty = () => ({ version: 1, equipped: null, styles: {} });\r\nconst finite = value => Number.isFinite(value);\r\nconst clamp = (value, min, max) => Math.max(min, Math.min(max, value));\r\n\r\nfunction validOwner(value) {\r\n  return typeof value === 'string' && value.length > 0 && value.length <= MAX_OWNER_LENGTH\r\n    && (value.startsWith('account:') || (value.startsWith('guest:') && value !== 'guest:unavailable'));\r\n}\r\nfunction safeRecord(value) {\r\n  if (!value || typeof value !== 'object' || Array.isArray(value) || value.version !== 1) return empty();\r\n  const result = empty();\r\n  for (const [style, item] of Object.entries(value.styles ?? {})) {\r\n    if (!STYLES.has(style) || !item || typeof item !== 'object' || Array.isArray(item)) continue;\r\n    if (!finite(item.intensity) || !finite(item.tier) || !finite(item.units) || !finite(item.maxUnits)\r\n      || !finite(item.updatedAt) || !['reps', 'hold'].includes(item.kind)\r\n      || (item.kind === 'hold' && !['aura', 'blizzard'].includes(style))) continue;\r\n    const maxUnits = clamp(Math.floor(item.maxUnits), 1, item.kind === 'hold' ? 120 : 30);\r\n    const units = clamp(Math.floor(item.units), 0, maxUnits);\r\n    const intensity = clamp(item.intensity, 0, 1);\r\n    if (!units || !intensity) continue;\r\n    const mode = typeof item.mode === 'string' && EXERCISES[item.mode] && retainedPowerStyle(item.mode) === style ? item.mode : null;\r\n    const inferred = mode ? effectGroupForExercise(mode) : null;\r\n    const fallback = style === 'lightning' ? 'shoulders' : style === 'floor' ? 'floor' : style === 'blizzard' ? 'core' : 'legs';\r\n    const candidate = GROUPS.has(inferred) ? inferred : GROUPS.has(item.group) ? item.group : fallback;\r\n    const group = STYLE_GROUPS[style].has(candidate) ? candidate : fallback;\r\n    result.styles[style] = { intensity, tier: clamp(Math.floor(item.tier), 0, 6), units, maxUnits,\r\n      kind: item.kind, group, ...(mode ? { mode } : {}), updatedAt: clamp(item.updatedAt, 0, 1e15) };\r\n  }\r\n  result.equipped = STYLES.has(value.equipped) && result.styles[value.equipped] ? value.equipped : null;\r\n  return result;\r\n}\r\nfunction copy(value) { return { version: 1, equipped: value.equipped,\r\n  styles: Object.fromEntries(Object.entries(value.styles).map(([style, item]) => [style, { ...item }])) }; }\r\n\r\nexport function createRetainedPower({ storage = globalThis.localStorage, ownerId = null } = {}) {\r\n  let owner = validOwner(ownerId) ? ownerId : null;\r\n  let record = load();\r\n  let identity = null, lastUnits = 0;\r\n  let disposed = false;\r\n\r\n  function keyFor(id = owner) { return id ? `${RETAINED_POWER_KEY}/${encodeURIComponent(id)}` : null; }\r\n  function load() {\r\n    const key = keyFor();\r\n    if (!key) return empty();\r\n    try { return safeRecord(JSON.parse(storage?.getItem(key) || 'null')); }\r\n    catch { return empty(); }\r\n  }\r\n  function save() {\r\n    const key = keyFor();\r\n    if (!key) return false;\r\n    try { storage?.setItem(key, JSON.stringify(record)); return !!storage; }\r\n    catch { return false; }\r\n  }\r\n\r\n  function read() { return copy(record); }\r\n  function setOwner(nextOwner) {\r\n    if (disposed) return read();\r\n    const next = validOwner(nextOwner) ? nextOwner : null;\r\n    if (next === owner) return read();\r\n    owner = next;\r\n    identity = null; lastUnits = 0;\r\n    record = load();\r\n    return read();\r\n  }\r\n  function observe(detail = {}) {\r\n    if (disposed || !owner) return false;\r\n    const workout = detail?.workout;\r\n    if (!workout || workout.ownerId !== owner || workout.stage !== 'working' || workout.paused === true) return false;\r\n    const route = retainedPowerStyle(workout.mode);\r\n    const group = effectGroupForExercise(workout.mode);\r\n    if (!route || (workout.kind === 'hold' && !['aura', 'blizzard'].includes(route))\r\n      || (workout.kind === 'reps' && route === 'blizzard') || !['hold', 'reps'].includes(workout.kind)) return false;\r\n    const progress = powerProgress(workout);\r\n    if (!(progress.units > 0 && progress.maxUnits > 0)) return false;\r\n    const nextIdentity = `${workout.sessionId ?? ''}\\u0000${workout.mode ?? ''}\\u0000${workout.kind}`;\r\n    const changed = nextIdentity !== identity;\r\n    const previous = lastUnits;\r\n    identity = nextIdentity;\r\n    lastUnits = progress.units;\r\n    // The first positive authoritative snapshot can restore a saved peak without\r\n    // replaying a pulse. Repeated units and downward corrections never re-equip.\r\n    const progressed = changed ? progress.units > 0 : progress.units > previous;\r\n    if (!progressed) return false;\r\n\r\n    const current = record.styles[route];\r\n    const now = finite(detail.now) ? Math.max(0, detail.now) : 0;\r\n    if (!current) {\r\n      record.styles[route] = { ...progress, ...(group ? { group } : {}), mode: workout.mode, updatedAt: now };\r\n    } else {\r\n      const better = progress.intensity > current.intensity\r\n        || (progress.intensity === current.intensity && progress.tier > current.tier);\r\n      record.styles[route] = {\r\n        intensity: better ? progress.intensity : current.intensity,\r\n        tier: better ? progress.tier : current.tier,\r\n        units: better ? progress.units : current.units,\r\n        maxUnits: better ? progress.maxUnits : current.maxUnits,\r\n        kind: better ? progress.kind : current.kind,\r\n        group: group ?? current.group,\r\n        mode: workout.mode,\r\n        updatedAt: now,\r\n      };\r\n    }\r\n    record.equipped = route;\r\n    save();\r\n    return true;\r\n  }\r\n  function dispose() { disposed = true; identity = null; lastUnits = 0; }\r\n  return { read, observe, setOwner, dispose };\r\n}\r\n","arcade/pyramid-jump/data.mjs":"// Generated by tools/gen-pyramid-jump-data.mjs. Paper silhouettes from the Dr. Girlfriend roster + colour table.\r\nexport const SHAPES={\"myr5\":{\"d\":\"M80,16L76,20L73,30L71,33L71,35L48,100L46,114L46,124L49,133L55,142L53,141L51,144L46,157L41,163L35,179L35,184L31,190L32,201L33,206L36,207L37,206L37,200L38,200L40,208L43,209L44,208L44,200L46,200L47,207L49,207L51,206L51,198L53,201L55,201L57,196L59,202L62,207L64,215L63,225L59,228L57,231L57,234L60,236L84,236L86,234L86,231L80,225L79,215L93,216L102,215L103,217L102,225L96,231L96,234L100,236L105,235L120,236L124,235L125,231L123,228L119,226L118,215L119,207L123,202L125,194L126,185L127,186L126,180L128,184L128,179L128,179L130,185L130,183L131,186L131,180L131,183L131,182L132,183L133,182L133,186L132,181L134,185L133,182L133,181L135,183L134,179L136,184L135,177L136,178L136,180L135,171L136,173L135,170L136,170L137,172L136,170L139,168L149,163L152,155L159,152L162,148L164,151L166,151L168,148L169,139L168,137L166,135L163,136L161,138L158,135L155,136L154,137L150,135L147,136L143,120L141,118L140,118L138,120L138,124L139,142L138,147L135,152L129,142L127,142L133,132L135,122L135,113L132,100L119,71L96,31L87,18L83,16ZM49,181L49,182L50,180L50,184L51,183L51,184L52,181L52,183L52,181L53,182L54,181L54,183L55,180L56,190L53,187L50,188L47,184Z\",\"e\":[91,91,9],\"v\":\"0 0 200 240\"},\"01-seed-pearo--3d_character_model\":{\"d\":\"M104,16L100,16L96,18L89,25L76,41L65,59L62,73L61,83L63,89L69,101L73,105L79,109L74,114L70,112L65,112L61,113L57,117L55,122L56,127L53,129L49,135L46,140L46,144L43,148L42,153L40,156L35,167L34,171L34,176L33,183L34,192L36,196L40,201L44,203L48,202L51,201L52,198L52,190L52,189L55,191L57,192L60,190L61,188L61,183L58,177L59,173L59,163L58,158L60,154L60,149L63,146L66,141L62,157L63,167L66,174L63,181L62,187L63,194L65,199L64,202L65,205L62,209L60,217L55,221L52,228L52,232L53,234L58,236L84,236L87,236L90,234L91,231L91,225L90,212L87,207L87,200L91,196L92,189L96,190L109,189L110,195L113,200L114,206L111,214L110,231L112,235L116,236L142,236L145,236L147,234L148,231L148,227L146,222L141,217L139,210L136,205L135,199L138,194L138,181L134,174L138,166L138,157L135,141L137,146L141,149L141,154L143,158L142,171L143,177L140,185L140,188L141,190L145,192L149,189L149,192L148,195L148,198L151,201L154,203L159,202L162,200L165,196L167,191L168,182L165,165L162,158L158,153L158,148L155,144L155,141L153,136L149,131L145,127L145,121L144,117L141,114L137,112L131,112L126,114L123,109L128,106L135,99L140,88L141,75L136,58L129,45L120,32L107,18Z\",\"e\":[101,61,9],\"v\":\"0 0 200 240\"},\"01-seed-pearo--cute_alien_figure_3d_model\":{\"d\":\"M99,16L96,18L87,26L74,42L63,59L56,75L52,91L52,106L55,117L62,132L63,138L60,144L51,153L44,163L37,176L33,184L31,194L31,207L34,214L37,217L41,218L44,217L49,214L50,212L49,204L52,206L54,206L59,222L56,232L57,234L59,236L90,236L92,234L95,228L100,226L105,228L108,234L110,236L142,236L143,235L144,232L141,224L141,221L145,211L146,206L151,204L150,211L153,216L159,218L164,217L167,214L169,207L169,194L167,183L160,169L152,157L140,143L137,137L138,132L145,117L149,103L148,90L143,73L133,53L123,38L115,28L104,18Z\",\"e\":[100,74,9],\"v\":\"0 0 200 240\"},\"01-seed-pearo--white_3d_character_model\":{\"d\":\"M85,16L77,20L70,29L55,62L50,78L49,86L52,95L57,103L62,110L67,113L72,116L71,118L71,122L65,124L61,129L59,132L59,137L50,147L47,155L40,167L36,184L36,194L40,202L44,205L50,205L55,203L57,201L57,199L54,193L57,193L60,191L61,187L60,183L62,180L66,172L69,177L66,181L64,189L64,197L66,202L64,209L64,218L52,227L51,233L53,236L95,236L97,235L99,230L96,209L95,205L93,202L95,198L96,190L106,190L107,198L110,203L109,208L108,227L108,232L109,235L111,236L143,236L145,233L146,226L140,208L138,202L136,200L137,197L137,193L142,189L144,190L140,198L141,201L144,203L153,205L159,202L162,199L165,193L164,171L162,162L159,157L158,151L154,144L147,137L146,132L144,128L137,123L128,122L130,118L130,114L128,112L141,103L147,96L151,88L150,78L147,70L139,55L129,41L120,32L110,24L97,18L90,16ZM135,153L139,162L138,176L135,180L133,176L137,169Z\",\"e\":[100,67,9],\"v\":\"0 0 200 240\"},\"01-seed-pearo--blank_humanoid_figure_3d_model\":{\"d\":\"M110,18L100,16L89,19L79,23L71,29L62,38L54,50L48,61L47,65L45,80L49,91L53,97L65,109L73,113L73,114L70,113L64,113L60,115L57,117L56,122L46,133L44,139L41,142L39,148L36,152L32,161L31,167L31,171L28,180L29,190L33,197L36,198L39,197L43,198L47,197L48,193L45,186L48,184L50,187L54,188L55,187L57,184L58,181L55,174L58,168L59,156L61,153L62,148L63,147L67,139L68,146L71,150L69,152L67,155L67,160L68,163L65,166L62,172L61,185L62,189L61,192L62,197L59,202L57,216L52,220L49,227L50,234L54,236L86,236L89,233L90,225L88,220L90,215L90,205L88,198L89,194L88,190L90,187L90,180L98,182L106,182L110,180L111,185L112,190L112,194L112,198L111,201L110,217L111,220L109,226L109,232L111,235L113,236L144,236L148,234L149,232L148,224L145,219L142,216L141,205L139,197L140,195L140,192L138,189L139,183L138,172L136,165L133,162L134,156L132,152L130,150L133,147L134,138L139,148L140,152L142,156L142,165L145,174L143,181L144,186L148,188L150,187L153,184L155,186L153,192L153,195L155,197L157,198L161,197L164,198L167,197L170,195L172,191L172,180L170,171L170,163L165,153L162,148L161,143L157,139L154,132L151,127L145,122L142,116L137,113L130,113L128,114L127,113L136,110L146,99L153,90L156,80L156,73L153,62L150,54L146,48L134,34L120,22Z\",\"e\":[100,64,9],\"v\":\"0 0 200 240\"},\"01-seed-pearo--blank_toy_figure_3d_model\":{\"d\":\"M65,23L59,26L54,31L48,41L44,54L45,68L48,78L52,84L57,89L63,94L69,96L76,97L82,97L82,100L76,103L74,106L71,104L68,104L61,106L55,113L51,118L47,126L46,130L47,133L44,137L44,140L39,145L35,156L34,163L36,167L33,175L33,188L36,193L39,195L46,197L51,195L52,192L52,190L48,185L47,182L51,180L52,184L56,187L58,187L60,185L61,179L60,175L56,169L59,165L61,153L61,148L60,146L62,143L62,140L65,138L71,127L73,135L77,139L74,141L72,145L73,150L69,153L66,159L63,177L63,181L66,185L65,190L60,200L58,215L53,220L51,225L50,231L51,233L56,236L65,236L86,236L91,234L93,230L92,221L90,218L91,215L91,204L90,195L87,191L88,189L87,186L90,182L91,165L103,166L108,165L109,182L110,184L112,186L112,191L109,196L108,202L108,215L109,218L107,224L107,233L110,235L114,236L145,235L149,232L148,226L146,221L141,215L139,199L136,193L134,191L133,185L136,180L134,162L131,154L126,150L127,148L127,144L123,139L125,137L127,135L128,131L128,127L133,137L137,140L137,143L139,146L138,148L139,158L140,165L143,169L139,175L139,185L141,187L145,186L148,180L152,182L151,186L147,191L148,194L152,197L158,196L163,193L166,187L168,183L168,178L165,171L163,167L165,164L165,159L161,147L156,140L154,136L152,133L153,131L152,125L144,112L140,108L134,104L129,104L125,106L122,102L117,100L117,97L128,97L138,93L145,87L150,80L154,71L155,62L155,51L152,41L145,31L136,24L133,23L126,21L122,22L118,25L115,21L107,17L99,16L91,17L84,21L82,25L75,22Z\",\"e\":[99,57,9],\"v\":\"0 0 200 240\"},\"02-taper-tallstalk--3d_humanoid_figure\":{\"d\":\"M115,16L90,18L85,20L86,27L91,46L96,51L96,56L94,57L84,59L82,60L82,62L79,63L77,65L74,75L65,95L59,99L48,114L36,128L33,134L32,149L34,157L40,164L42,165L42,159L45,160L46,158L40,152L42,150L40,147L41,143L45,140L45,148L46,152L49,153L50,149L50,140L52,130L52,125L69,108L72,98L84,79L86,78L92,102L92,111L88,120L87,124L80,133L74,148L72,160L73,172L70,180L70,193L69,199L63,205L59,215L56,220L57,223L53,224L51,228L49,233L49,236L61,234L62,233L62,229L66,227L66,233L69,235L74,234L77,232L75,218L78,208L77,200L82,182L83,177L82,173L88,166L99,143L104,143L108,163L113,174L113,184L118,199L117,211L122,221L123,234L127,236L133,236L134,235L135,236L143,236L149,235L149,232L146,228L143,225L140,225L140,222L135,215L131,207L127,202L126,199L125,184L123,174L126,165L126,149L122,132L112,112L111,107L113,89L116,78L119,80L130,97L133,108L147,127L147,143L144,151L145,156L146,156L149,154L152,143L153,143L157,147L158,158L155,167L156,169L160,167L166,159L168,151L168,145L166,137L155,123L145,100L141,97L137,94L129,77L126,65L121,62L120,59L108,57L107,50L110,47L113,42L116,19Z\",\"e\":[100,34,4],\"v\":\"0 0 200 240\"},\"02-taper-tallstalk--humanoid_robot_3d_model1\":{\"d\":\"M137,16L108,17L101,20L74,37L75,38L79,44L96,62L95,71L70,75L66,78L66,84L63,89L63,94L65,100L59,117L57,116L52,121L32,155L32,163L38,170L37,172L35,173L33,176L33,183L35,188L36,189L36,192L43,204L45,205L47,203L46,200L47,198L42,188L43,186L44,179L50,182L53,189L54,189L55,188L56,184L52,175L49,172L46,171L53,168L57,164L68,129L67,119L75,106L89,126L92,126L93,131L92,141L88,146L82,151L79,158L78,168L81,174L79,178L76,191L74,203L75,206L72,208L68,216L65,226L61,234L61,236L90,236L90,232L86,224L86,219L84,208L83,207L85,205L90,190L91,183L97,181L107,173L110,174L112,198L114,204L112,209L110,217L110,224L112,229L112,236L144,236L144,234L141,229L132,222L131,217L124,206L123,205L124,195L124,161L126,159L126,150L123,143L121,141L115,140L112,137L109,131L107,124L110,123L112,120L120,88L123,87L133,103L132,108L132,117L136,133L139,139L148,142L145,147L145,150L143,153L144,157L148,157L149,152L152,149L155,158L153,166L150,170L152,170L152,172L153,173L159,169L162,163L164,147L162,142L159,142L158,141L167,133L168,130L168,123L159,93L143,76L134,70L127,70L125,74L121,75L120,72L118,70L108,71L107,69L111,68L119,56L138,17Z\",\"e\":[106,42,5],\"v\":\"0 0 200 240\"},\"02-taper-tallstalk--white_humanoid_doll_3d_model\":{\"d\":\"M94,17L81,21L73,30L67,42L64,57L66,69L70,82L83,103L87,107L83,110L81,113L77,111L72,111L68,113L65,117L64,121L64,124L58,130L56,135L56,138L52,142L51,146L46,151L41,162L41,166L39,170L36,177L35,187L37,192L39,194L48,195L50,194L53,190L52,187L49,183L49,181L53,179L55,183L58,184L62,183L63,181L62,174L59,170L61,167L64,159L64,152L67,148L67,145L72,139L75,132L77,131L74,151L74,156L76,159L73,162L72,165L72,168L73,172L71,175L69,182L69,186L71,188L69,191L69,195L70,196L65,203L63,214L56,220L54,224L53,228L53,234L56,236L83,236L86,236L88,234L89,231L89,225L87,222L88,219L89,209L87,202L85,198L87,194L86,190L89,186L90,177L89,173L90,173L93,174L103,175L109,174L111,172L112,173L111,176L111,184L115,190L114,195L115,198L113,203L112,218L113,222L111,227L112,234L115,236L145,236L148,232L147,225L143,219L137,214L134,200L131,197L132,193L130,188L131,187L132,183L130,174L128,172L129,166L127,161L125,159L127,155L127,149L123,131L126,132L128,138L134,145L134,147L137,152L137,159L139,165L142,171L139,177L138,182L139,185L143,186L146,184L148,180L151,182L153,184L149,190L149,192L150,195L153,196L160,196L162,195L165,191L165,188L165,177L163,171L159,166L160,163L159,160L154,150L150,146L149,143L145,138L145,135L142,129L137,124L137,120L135,115L128,111L123,111L119,113L117,110L114,107L119,103L126,93L134,74L136,62L136,54L134,42L128,29L118,21L111,18L104,16Z\",\"e\":[100,63,9],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--abstract_humanoid_3d_model\":{\"d\":\"M81,73L76,76L71,83L67,90L65,100L66,109L69,115L75,121L80,123L71,128L66,133L61,130L55,130L52,132L41,140L40,145L41,148L40,150L33,150L26,155L18,165L15,171L14,176L13,178L13,189L16,195L19,198L26,201L30,204L37,206L42,206L45,204L45,201L46,199L50,198L50,196L49,194L54,190L55,179L57,179L59,186L62,191L67,197L72,200L69,202L68,208L64,208L61,210L58,218L52,223L49,231L50,236L92,236L92,230L89,217L87,215L84,213L85,211L86,207L94,208L103,208L114,206L115,211L117,214L112,217L109,229L108,236L150,236L151,234L149,225L139,215L139,214L138,210L136,209L132,209L131,204L127,201L133,196L138,191L141,186L143,178L145,179L147,191L151,194L150,197L151,198L154,199L155,205L159,206L169,205L173,203L174,201L181,199L185,195L188,185L188,180L186,175L186,173L179,160L174,154L168,150L165,150L159,150L159,142L152,134L146,130L140,130L135,133L134,133L129,128L120,123L125,121L129,118L132,113L134,107L134,98L132,88L126,78L123,75L116,72L85,72ZM144,156L149,157L146,161L146,167ZM51,156L56,156L55,165ZM107,148L112,151L117,158L118,165L116,171L113,176L107,181L101,183L95,182L90,180L85,173L84,164L86,158L91,152L96,148L100,147Z\",\"e\":[100,98,8],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--circle_center\":{\"d\":\"M124,17L116,16L97,19L87,22L82,26L79,34L78,43L80,57L83,71L85,75L92,75L97,74L97,75L88,77L80,80L70,89L69,91L67,98L62,100L58,103L56,107L57,110L55,111L45,133L42,136L32,154L29,163L29,171L31,172L32,176L29,180L28,187L30,192L30,195L33,201L36,205L40,208L42,207L43,205L47,207L49,207L52,204L52,202L47,197L42,190L42,180L38,176L39,175L43,173L48,176L52,182L52,184L55,189L58,189L59,188L59,184L57,180L57,178L52,169L47,167L49,163L48,151L50,139L63,117L66,118L67,131L71,140L81,152L88,156L79,182L76,187L75,200L73,214L71,215L64,220L53,222L49,224L46,227L44,232L44,235L56,236L62,234L68,236L77,236L86,235L89,233L89,230L88,224L82,215L84,202L88,193L87,187L97,165L104,167L112,165L116,179L117,187L116,193L119,215L116,217L113,222L111,228L111,234L115,236L151,236L155,235L155,232L154,229L150,226L145,223L136,220L133,218L127,214L128,189L126,184L123,161L120,155L125,153L131,147L137,139L141,130L142,117L143,118L148,131L152,143L153,152L153,163L155,169L152,171L151,173L150,178L150,181L146,190L149,191L152,189L154,186L154,183L160,175L163,174L164,175L163,177L161,179L162,189L157,195L157,197L158,199L154,204L155,208L157,208L160,205L164,205L170,196L171,192L171,178L169,175L169,173L172,170L172,165L167,151L158,134L150,104L145,100L140,98L136,90L129,82L121,77L110,76L110,68L119,64L122,62L128,54L131,45L132,40L131,28L128,19ZM98,93L108,93L118,97L124,104L127,110L128,114L128,122L123,133L119,138L113,141L107,143L98,142L88,138L84,133L80,122L80,112L85,102L92,96Z\",\"e\":[105,46,7],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--ringed_humanoid_3d_model\":{\"d\":\"M76,17L73,19L69,27L68,33L69,45L73,54L78,62L81,64L90,68L90,76L79,77L71,82L63,91L60,98L55,100L51,104L42,134L33,151L28,165L29,170L31,173L31,175L29,178L30,192L31,196L37,205L40,205L44,208L45,208L46,204L42,199L43,197L43,195L38,189L39,179L37,177L37,175L38,174L40,175L46,183L46,186L48,189L52,191L54,190L50,181L51,178L50,173L48,170L45,169L48,163L47,152L48,143L53,127L57,118L58,117L60,130L63,139L69,147L75,153L80,155L77,161L74,184L72,189L73,214L64,220L56,223L51,225L46,229L45,232L45,235L50,236L86,236L88,235L89,234L89,230L88,225L85,218L81,215L84,193L83,188L84,179L89,165L96,167L103,165L113,187L112,193L116,202L118,215L113,224L111,230L112,233L115,235L123,236L132,236L138,234L145,236L156,235L157,232L155,227L151,224L146,222L136,220L130,215L127,214L125,200L125,187L121,182L112,156L119,152L125,146L129,140L133,131L135,118L137,117L150,139L152,151L151,163L153,167L148,169L143,178L143,180L142,184L141,188L143,189L145,189L148,184L148,182L152,176L157,173L162,175L162,176L158,180L158,190L148,202L148,204L151,207L153,207L157,205L158,207L161,208L164,205L167,201L170,195L170,192L172,187L171,180L168,176L169,172L172,171L171,163L168,154L158,136L155,133L149,117L146,111L144,110L144,107L142,103L137,99L133,98L132,91L130,89L120,80L112,77L103,75L104,74L108,75L116,75L118,71L121,57L122,43L121,34L118,26L114,22L103,19L84,16ZM94,93L102,93L110,97L115,102L119,108L120,113L120,123L116,133L109,140L99,143L90,142L82,138L76,132L72,122L73,111L77,103L82,97L89,94Z\",\"e\":[95,46,7],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--robot_3d_model\":{\"d\":\"M83,16L83,18L86,27L87,34L79,38L69,46L57,60L56,63L61,67L84,79L87,82L83,84L79,87L74,97L68,95L65,91L60,89L54,91L50,95L47,96L44,98L41,104L39,110L23,141L22,147L23,170L25,174L28,177L35,181L42,180L47,177L47,175L46,174L41,173L37,168L36,161L38,153L43,153L46,155L48,160L47,162L45,165L45,167L47,169L50,170L54,166L56,162L55,154L53,150L46,145L44,137L45,131L48,121L51,114L57,108L62,107L64,105L67,107L64,114L63,122L63,132L64,137L68,145L71,150L78,157L75,165L73,165L70,168L67,175L65,190L66,192L63,200L61,208L55,214L48,222L46,228L44,236L70,236L78,235L77,226L72,214L75,211L77,207L77,202L75,197L75,195L79,192L80,189L84,178L84,175L83,173L88,162L94,164L101,164L109,163L113,173L112,175L114,189L116,192L114,197L116,202L115,213L112,216L109,225L108,235L116,236L142,235L140,227L132,214L126,208L126,204L128,200L128,197L126,192L129,187L129,176L127,169L124,165L122,164L120,158L125,152L133,142L136,133L137,127L137,117L134,108L132,104L134,103L136,104L141,105L144,108L150,114L154,123L156,131L156,136L154,142L147,148L143,155L143,160L145,163L148,166L151,165L152,162L151,156L153,153L162,150L163,150L165,153L166,162L164,167L161,171L156,171L154,173L155,176L159,179L164,179L168,178L173,175L177,169L178,157L176,140L161,111L155,98L149,91L148,91L141,87L136,86L130,88L127,93L124,94L118,89L110,86L128,68L133,62L121,48L110,38L106,30L98,22L93,19ZM104,104L110,107L115,112L118,120L118,128L116,135L111,141L106,144L98,145L91,142L85,136L82,128L82,123L84,114L89,107L95,107Z\",\"e\":[94,49,5],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--stylized_3d_character1\":{\"d\":\"M117,19L103,16L96,16L85,18L78,21L69,27L63,32L58,40L54,48L51,62L51,69L54,80L57,87L63,94L69,98L65,102L59,100L53,101L47,104L44,108L42,113L42,116L37,121L32,130L29,133L28,136L23,143L20,154L19,158L20,161L17,171L18,181L20,188L24,192L27,194L31,193L40,188L40,186L35,177L41,174L42,178L46,181L49,181L52,178L53,176L53,170L47,162L49,158L50,148L49,142L50,140L56,128L57,128L54,145L55,155L58,165L62,168L60,169L58,176L57,181L57,187L58,189L57,192L57,197L54,203L52,215L47,219L40,222L38,226L37,230L38,233L41,235L83,236L85,234L87,227L83,218L84,213L84,207L83,201L81,198L83,194L82,191L84,188L85,179L95,181L108,181L114,179L115,179L116,185L118,190L118,196L119,198L116,205L116,216L117,218L114,226L114,233L115,235L123,236L159,236L161,234L163,228L161,224L158,221L152,219L146,214L146,202L145,199L143,197L144,194L142,189L143,186L143,181L141,172L139,168L141,166L145,156L145,143L143,128L144,128L149,140L151,142L150,144L151,152L153,162L147,170L147,176L148,179L152,181L154,181L158,178L159,174L163,176L164,178L163,181L160,186L160,187L163,190L168,193L175,193L180,188L183,178L183,171L180,161L181,158L179,149L174,139L172,136L170,132L168,130L166,126L161,118L158,116L157,110L153,105L144,100L138,101L135,102L131,98L135,96L141,90L144,84L147,78L149,70L149,61L146,48L141,37L135,31L129,26Z\",\"e\":[100,57,9],\"v\":\"0 0 200 240\"},\"03-pearl-orb-ring--stylized_humanoid_figure_3d_model\":{\"d\":\"M85,18L73,24L64,32L56,45L53,54L53,59L54,70L59,83L63,89L69,95L75,99L80,101L77,103L75,107L71,104L66,103L62,104L57,109L56,112L57,116L53,118L49,123L46,131L46,134L43,138L43,141L38,146L35,153L34,160L35,164L33,167L31,172L31,183L34,187L36,189L39,191L42,190L47,189L49,186L50,184L47,180L47,178L49,178L52,181L55,181L58,179L58,173L55,167L58,163L59,157L59,150L58,146L59,143L59,140L63,137L65,133L64,149L65,154L68,161L65,165L64,168L66,172L64,174L63,180L63,184L65,189L64,191L64,196L59,204L58,210L58,216L54,220L51,226L52,234L57,236L81,236L84,235L86,232L86,228L84,222L87,217L87,210L86,203L82,197L83,195L82,190L85,187L86,182L86,176L84,173L93,175L101,176L111,175L116,172L114,177L114,183L115,186L118,190L117,192L118,197L115,200L113,209L113,216L116,222L114,228L114,232L116,235L118,236L145,236L148,234L149,232L149,228L146,220L142,217L142,210L140,203L136,196L136,192L135,189L137,185L138,182L136,175L134,173L136,166L132,161L136,149L135,133L137,137L141,140L141,142L142,146L141,155L142,162L145,167L142,174L142,179L145,181L149,180L151,178L153,178L153,179L151,183L151,188L157,190L163,190L166,188L169,183L169,174L167,168L165,164L166,158L163,148L158,141L157,137L154,134L154,131L152,125L148,119L143,116L144,112L142,108L139,105L135,103L130,104L125,107L123,103L120,101L126,98L132,94L139,87L142,82L146,74L147,65L146,50L143,42L136,32L125,23L115,18L106,16L95,16Z\",\"e\":[100,59,9],\"v\":\"0 0 200 240\"},\"04-crest-wedge--robot_creature_3d_model\":{\"d\":\"M152,65L130,82L129,84L131,87L129,89L127,87L120,84L104,81L84,83L75,86L71,89L69,87L71,83L62,75L47,65L47,69L52,95L56,96L61,94L63,96L58,100L58,102L78,128L67,129L66,131L66,137L63,137L57,139L53,145L54,147L54,148L50,144L48,145L35,154L17,170L12,178L16,178L23,176L24,176L15,192L13,199L13,205L14,206L23,201L39,187L39,202L41,204L50,190L63,161L63,159L60,157L62,155L64,156L67,155L72,150L85,176L84,177L82,177L78,184L80,186L79,188L75,188L63,211L59,211L56,214L46,228L45,234L47,235L87,236L90,235L91,228L90,222L88,216L90,194L87,191L88,189L90,189L92,186L100,195L103,193L108,186L110,189L112,189L113,192L110,193L113,217L110,224L109,233L110,235L114,236L149,236L153,236L154,235L155,229L154,227L143,213L141,211L137,211L125,188L123,187L121,188L120,186L122,183L120,178L118,176L116,177L115,176L128,150L133,155L135,156L138,155L140,157L137,161L152,192L159,204L161,203L161,201L161,187L177,201L186,206L187,205L187,202L184,192L176,176L177,175L184,178L187,178L188,177L185,172L166,154L152,145L150,144L146,148L146,147L146,144L143,140L137,137L133,137L134,131L132,129L122,128L142,102L142,100L137,95L139,94L142,96L148,96L153,69Z\",\"e\":[100,96,4],\"v\":\"0 0 200 240\"},\"04-crest-wedge--stylized_3d_character\":{\"d\":\"M125,16L95,32L89,42L81,44L68,50L55,82L63,100L67,107L76,115L85,119L81,125L78,123L71,122L66,125L62,132L62,136L55,145L50,153L47,154L44,157L39,166L33,179L34,198L36,202L38,204L41,205L44,203L45,199L44,192L49,189L53,195L55,196L58,196L60,194L60,190L58,181L59,175L63,163L62,161L64,160L72,145L76,145L72,159L72,165L74,169L72,170L68,180L66,193L67,197L63,201L61,219L48,229L48,233L50,236L84,236L87,234L88,227L86,220L87,205L86,202L84,199L86,198L90,184L92,186L96,187L107,186L111,184L114,197L116,199L114,203L114,221L112,227L112,231L114,235L116,236L149,236L152,234L153,231L150,227L139,218L137,201L134,197L134,190L131,175L129,171L126,169L128,165L128,158L123,143L127,145L136,159L137,160L138,167L143,183L141,191L142,195L144,197L148,196L151,190L156,193L155,201L156,204L162,205L166,202L167,181L165,174L155,156L149,152L147,148L139,138L140,133L138,129L135,125L131,123L127,122L123,123L120,126L117,122L127,115L134,108L139,99L147,81L147,78L142,74L136,61L139,54L140,45L137,41L134,39L132,36L128,21Z\",\"e\":[101,69,9],\"v\":\"0 0 200 240\"},\"05-slope-bobble--clay_humanoid_figure_3d_model\":{\"d\":\"M124,67L114,67L109,68L98,71L92,74L78,84L65,98L61,106L62,112L65,118L69,122L75,125L85,127L78,130L74,134L72,137L70,135L66,135L61,138L60,142L57,141L51,144L42,153L41,156L41,159L37,158L34,159L22,171L15,183L12,196L13,206L15,211L19,215L28,217L32,217L42,212L51,204L57,195L59,185L59,176L58,172L56,169L60,170L65,164L66,172L69,178L74,184L81,189L79,191L77,196L74,196L70,200L62,214L54,215L51,218L51,221L53,229L56,233L59,236L83,236L91,235L93,233L95,227L93,222L93,204L92,202L89,200L91,197L92,194L99,196L105,196L109,194L109,197L111,200L108,203L108,222L106,225L106,230L109,234L117,236L141,236L143,235L146,231L149,227L150,220L148,215L145,213L138,214L129,198L127,196L123,196L122,192L120,189L125,186L132,178L134,171L136,164L140,170L142,170L145,169L142,173L141,178L141,185L142,191L148,202L156,211L165,216L171,217L180,215L185,211L188,202L187,191L185,182L176,169L169,161L165,159L162,158L158,159L159,157L159,155L154,148L149,144L143,141L140,142L139,138L134,135L130,135L128,137L122,130L114,127L111,127L111,126L122,122L129,117L136,108L140,97L140,87L137,78L130,71Z\",\"e\":[101,97,7],\"v\":\"0 0 200 240\"},\"06-ridge-triad--geometric_robot_3d_model1\":{\"d\":\"M100,60L61,96L62,99L68,120L70,121L52,122L47,126L47,128L56,141L51,144L51,147L49,147L41,158L41,162L33,160L31,160L28,161L22,170L12,187L14,191L16,192L15,193L16,202L18,205L33,209L39,209L44,206L47,202L48,197L51,197L54,195L61,177L60,175L55,170L51,169L52,168L55,167L60,159L60,157L63,156L65,154L83,180L81,180L79,184L78,188L79,190L76,193L71,196L50,229L48,233L49,236L95,236L96,232L91,200L88,193L89,192L91,190L100,199L109,190L110,192L113,193L111,195L111,197L109,202L104,231L105,235L150,236L152,235L152,233L148,225L129,195L124,193L121,190L122,188L122,185L119,180L117,180L135,154L136,155L140,157L141,160L145,167L149,168L149,169L145,170L140,174L140,176L146,195L148,197L152,197L153,201L156,205L158,206L161,208L167,209L183,205L184,203L186,194L184,192L187,190L188,187L184,178L172,161L170,159L167,159L159,162L159,161L160,160L160,157L153,149L149,148L149,144L145,141L154,127L152,124L149,122L131,121L132,120L139,96Z\",\"e\":[100,90,6],\"v\":\"0 0 200 240\"},\"06-ridge-triad--robot_3d_model1\":{\"d\":\"M102,16L99,17L95,22L83,45L83,49L92,66L96,71L95,75L87,76L85,77L73,99L70,103L64,105L58,104L54,106L35,149L34,157L35,159L32,165L31,174L36,184L40,188L39,181L43,182L39,173L42,164L41,161L47,158L48,159L49,161L53,164L55,172L56,172L57,169L57,165L56,157L54,155L51,152L49,136L59,116L64,114L66,115L57,133L59,138L62,139L88,139L89,140L87,142L84,150L78,174L79,176L77,177L73,182L70,189L70,193L71,204L68,217L65,221L64,223L61,220L59,218L56,218L50,222L46,229L46,236L54,231L56,231L61,234L64,232L66,234L69,235L70,235L72,233L75,233L76,232L79,236L80,234L82,230L82,225L79,220L76,217L79,205L84,198L86,194L87,185L86,178L85,178L94,151L96,149L100,152L104,152L107,149L108,150L114,177L111,183L111,191L112,197L116,205L118,220L111,224L109,228L107,236L120,231L121,232L124,231L126,233L129,232L132,235L134,233L137,234L145,232L155,236L155,232L153,228L150,224L145,220L139,219L133,222L129,219L125,219L124,206L127,193L127,187L125,182L121,177L121,175L118,145L114,140L115,138L141,138L144,136L147,132L138,114L140,113L141,113L145,117L154,135L151,152L144,160L142,167L142,172L144,172L148,165L153,159L155,159L160,162L159,165L162,174L158,182L159,183L157,189L163,184L168,177L169,166L168,163L167,161L168,158L167,149L151,109L146,104L143,104L141,105L132,99L118,78L115,76L109,76L108,74L116,58L120,49L120,46L106,21Z\",\"e\":[101,45,5],\"v\":\"0 0 200 240\"},\"07-bulb-sphereling--cute_robot_3d_model\":{\"d\":\"M54,19L51,20L48,23L46,27L46,33L47,37L52,42L56,43L61,42L69,54L68,55L70,59L65,66L62,76L61,84L63,95L66,100L70,104L65,112L62,121L58,125L54,125L47,130L31,148L27,155L27,159L29,161L26,167L25,173L28,181L30,183L35,185L37,185L39,182L41,183L44,182L48,176L52,188L56,195L61,199L68,203L69,204L60,205L52,210L48,216L45,224L44,233L47,235L51,236L68,236L89,235L92,232L92,228L90,220L87,214L84,211L84,209L95,210L106,210L115,209L116,211L114,213L111,217L107,227L107,232L109,235L123,236L154,235L156,232L155,222L151,216L146,210L142,209L141,206L131,203L137,201L142,196L147,189L151,177L156,182L162,183L165,184L170,183L173,181L175,173L175,167L171,161L173,158L173,155L168,147L158,134L148,126L145,124L144,125L141,122L136,120L134,114L132,113L129,104L133,101L137,95L139,88L139,81L137,79L126,79L125,78L122,77L120,74L118,73L115,64L107,54L98,48L92,47L86,48L79,51L76,50L68,37L70,32L70,27L69,23L63,19L59,18ZM148,16L141,17L135,21L132,28L134,36L127,47L126,47L124,50L119,48L118,50L115,52L115,54L124,58L131,63L134,61L135,61L135,58L133,56L135,53L134,52L141,41L147,41L151,39L154,37L156,33L156,26L153,20Z\",\"e\":[90,77,8],\"v\":\"0 0 200 240\"},\"07-bulb-sphereling--humanoid_robot_3d_model\":{\"d\":\"M72,16L67,20L65,28L66,32L69,35L74,37L77,36L82,43L76,53L75,58L74,64L75,70L77,72L79,76L82,78L89,79L95,79L95,81L92,81L88,84L87,87L84,86L79,90L78,95L79,102L77,104L74,112L73,116L71,118L68,120L66,126L64,127L52,145L50,151L49,159L50,161L53,161L51,163L49,172L50,173L50,180L52,183L60,186L63,185L64,181L61,177L60,172L61,167L65,169L64,172L65,176L68,177L71,174L70,166L69,162L66,160L69,156L76,133L74,131L76,130L78,127L79,124L78,122L86,103L88,103L89,110L93,114L95,115L97,119L95,120L95,122L90,126L88,130L90,132L87,134L85,137L85,142L86,145L83,164L84,167L82,170L79,172L78,175L78,181L80,183L77,186L69,206L67,216L60,227L60,233L62,236L87,236L91,235L93,233L93,228L92,221L90,219L90,188L88,186L88,184L91,182L92,178L92,173L90,171L91,165L93,149L95,144L97,146L102,146L105,145L106,143L108,149L108,156L111,168L110,171L108,174L108,177L109,181L112,185L109,187L106,214L107,219L105,223L104,232L106,236L140,236L143,233L142,225L130,213L128,203L122,185L119,184L122,180L122,175L121,172L118,170L117,167L118,165L115,146L117,142L117,137L115,134L112,132L114,131L114,130L111,124L107,122L106,119L105,118L106,115L108,114L111,112L114,103L122,122L121,123L123,129L126,131L125,133L133,159L135,160L132,163L130,174L133,176L135,176L137,172L136,168L140,166L143,173L142,177L139,180L138,184L140,187L143,186L149,180L150,174L152,172L150,164L148,161L150,161L151,159L151,154L150,148L145,139L136,126L134,126L132,119L129,118L121,101L123,96L121,90L119,87L115,86L110,81L107,81L107,79L112,79L123,75L127,71L130,65L130,56L129,51L122,40L118,36L114,34L101,33L92,35L88,37L83,32L85,30L85,24L83,20L79,17Z\",\"e\":[97,48,4],\"v\":\"0 0 200 240\"},\"08-shard-asym--geometric_robot_3d_model\":{\"d\":\"M84,16L83,32L83,53L82,54L82,56L85,64L89,86L92,91L62,88L59,88L69,112L66,115L58,135L43,156L33,168L31,185L31,198L33,208L34,208L38,205L54,188L57,174L67,141L74,123L85,149L92,170L66,198L65,202L64,207L54,228L52,235L54,236L64,232L72,222L76,234L77,235L84,234L85,214L87,208L85,198L88,191L96,180L98,183L103,183L107,179L114,188L120,198L118,207L120,211L125,236L131,235L133,222L142,232L152,236L153,235L152,232L140,208L140,203L137,197L121,181L112,171L136,129L140,125L142,130L145,144L146,166L146,189L162,210L164,209L169,188L169,171L154,138L152,122L149,114L163,93L164,91L157,90L131,93L112,92L112,82L114,80L121,67L129,57L122,50L122,33L124,18L121,18L115,30L109,37L102,35L97,39L96,39L93,37L90,31L85,16Z\",\"e\":[105,50,4],\"v\":\"0 0 200 240\"},\"08-shard-asym--robot_3d_model4\":{\"d\":\"M45,99L42,102L44,107L55,126L65,138L62,141L60,145L58,144L53,147L48,152L47,155L44,158L41,156L37,156L23,168L16,176L14,178L13,184L12,195L15,203L20,207L23,204L27,191L28,190L33,190L33,192L25,206L26,208L28,209L33,208L43,202L47,198L53,187L57,170L55,167L57,164L57,163L59,162L66,155L67,153L70,153L71,160L73,168L80,176L87,180L83,182L82,184L82,187L82,190L80,191L79,194L76,194L74,196L68,213L64,213L56,224L54,231L55,235L62,236L82,236L95,235L98,234L99,233L99,229L98,221L96,216L95,200L92,198L92,195L90,193L93,192L95,188L94,183L99,187L105,187L110,182L109,185L109,189L110,191L113,193L112,194L113,198L111,199L109,200L111,217L109,224L109,234L112,235L123,236L137,236L147,235L149,233L149,229L145,220L141,214L139,213L137,213L130,195L128,194L125,195L123,191L121,190L122,188L121,184L120,181L117,180L127,172L131,165L132,158L136,156L138,153L141,157L145,158L147,163L149,164L150,166L147,170L148,181L151,196L156,204L162,210L168,213L171,213L173,211L171,197L177,212L180,211L184,207L188,198L188,189L187,184L179,172L169,160L166,158L162,159L154,149L164,152L169,152L172,148L167,138L160,128L160,126L148,113L136,104L121,98L108,96L106,97L103,100L101,84L98,76L93,77L74,84Z\",\"e\":[89,87,2],\"v\":\"0 0 200 240\"},\"08-shard-asym--fantasy_creature_3d_model2\":{\"d\":\"M112,16L104,19L98,24L84,39L77,48L71,65L69,70L70,77L64,82L59,91L51,94L43,101L38,106L35,115L33,124L34,132L36,135L39,138L37,147L37,157L34,159L31,167L30,174L28,175L27,187L29,196L31,200L35,203L45,210L48,210L51,208L46,202L43,198L42,189L44,182L48,181L52,186L54,192L53,198L53,199L56,200L58,199L61,194L62,189L61,183L58,178L55,174L55,171L54,167L51,161L49,160L53,142L57,141L61,138L65,132L68,126L78,133L81,142L81,151L84,157L80,162L78,162L75,167L71,181L70,191L73,203L73,213L65,215L58,220L53,228L52,234L60,234L63,235L68,236L83,236L88,235L89,234L90,231L89,226L91,220L91,210L88,194L86,190L89,172L92,171L95,174L101,174L103,171L107,174L116,198L121,207L123,221L122,230L124,234L128,236L155,235L156,230L153,224L148,218L140,213L133,193L126,179L111,156L113,151L115,134L120,131L128,116L136,124L137,126L139,129L139,132L142,143L139,145L137,148L137,158L140,163L133,168L130,173L129,181L131,186L134,188L135,189L139,175L142,172L147,171L152,178L152,187L149,194L142,200L142,201L141,201L142,202L149,203L154,203L158,202L165,198L171,189L173,166L169,154L166,138L163,135L157,136L150,123L150,119L147,117L148,115L139,99L143,96L144,91L144,87L141,77L134,72L124,67L119,69L113,72L106,70L100,69L99,63L93,56L94,49L98,37L104,28Z\",\"e\":[94,101,9],\"v\":\"0 0 200 240\"},\"08-shard-asym--stylized_action_figure_3d_model\":{\"d\":\"M99,16L91,21L74,39L62,47L46,57L42,62L41,66L42,71L50,84L67,102L80,112L78,113L77,119L77,116L75,114L73,113L68,113L60,116L55,120L54,123L55,126L52,127L46,133L41,140L41,143L36,146L27,159L25,164L25,170L20,181L18,189L18,193L21,199L24,202L30,200L34,200L36,199L38,194L36,190L36,187L41,186L42,190L46,193L49,193L51,191L53,188L53,185L50,176L56,160L56,154L60,152L68,143L69,139L73,140L69,161L69,166L71,167L69,170L66,178L64,189L64,193L66,195L63,197L61,200L58,214L58,220L54,224L52,230L53,234L55,236L58,236L88,236L90,232L89,224L91,218L90,201L88,197L89,196L91,192L92,180L109,179L110,194L113,197L112,198L111,202L110,211L110,220L112,224L111,231L112,234L113,236L117,236L147,236L149,233L149,228L147,224L142,220L142,210L140,201L138,197L134,195L137,192L137,188L136,181L132,171L130,168L131,166L131,157L128,140L132,139L133,143L141,152L145,154L145,158L150,173L152,176L149,181L148,186L149,190L151,192L154,193L157,192L159,189L160,186L165,187L166,188L163,193L163,197L167,200L171,200L174,201L178,201L180,199L182,196L182,190L181,181L176,170L177,167L175,161L169,152L163,144L160,143L160,139L154,132L146,126L147,122L146,120L140,115L133,113L127,114L125,115L124,118L123,113L121,112L133,103L150,85L158,73L160,65L158,61L154,56L150,53L138,47L129,40L108,20L103,17Z\",\"e\":[100,65,9],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--3d_robot_model\":{\"d\":\"M125,75L112,74L68,75L71,120L77,125L70,125L66,127L64,130L64,133L61,133L58,135L55,137L53,142L48,141L40,146L35,153L33,158L33,163L30,163L25,162L22,164L21,168L15,180L13,189L12,193L15,196L15,201L17,206L30,213L36,215L41,214L45,212L47,209L51,206L53,202L52,199L55,198L57,195L60,180L60,176L55,172L61,169L64,161L67,178L70,183L76,187L74,190L73,194L68,195L60,214L56,215L54,218L50,228L50,233L52,234L55,235L82,235L92,234L95,233L96,228L94,220L92,204L93,200L89,198L91,193L99,195L111,194L111,198L108,202L108,220L106,222L106,233L110,235L119,236L148,235L151,233L151,229L146,216L145,215L140,214L132,195L128,196L127,191L125,188L131,182L135,177L138,163L141,168L146,171L142,173L140,179L143,192L150,206L153,207L157,211L165,214L172,212L180,208L184,206L185,203L185,195L188,192L188,190L183,179L176,162L175,161L168,163L168,161L168,156L159,144L152,140L148,140L146,137L142,134L136,134L135,129L128,124L130,120L130,106L127,79ZM159,197L163,197L161,200ZM44,195L41,202L41,205L39,201L38,195ZM133,146L138,150L136,154L132,148ZM66,146L67,147L64,152L62,150Z\",\"e\":[99,99,7],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--boxy_humanoid_3d_model\":{\"d\":\"M76,17L73,19L72,22L65,95L66,102L69,104L76,105L76,108L74,107L68,107L63,110L60,114L52,127L49,134L50,138L48,140L44,151L42,161L43,165L40,175L42,187L44,191L48,193L52,193L55,190L56,185L54,181L56,180L59,183L61,183L64,181L64,177L63,172L62,167L64,163L66,147L66,143L69,140L72,133L69,148L70,156L72,160L70,165L67,187L69,189L66,195L65,208L65,212L60,216L57,221L54,227L54,233L58,236L89,236L92,234L93,233L93,226L92,218L90,216L91,215L93,211L93,195L91,191L94,186L96,171L104,171L107,188L109,191L107,195L108,211L109,215L110,216L109,218L108,223L107,233L108,235L111,236L143,236L146,233L146,226L140,217L135,212L135,208L133,192L131,190L133,188L133,184L130,164L129,160L131,157L131,149L128,133L131,141L135,143L134,146L137,164L138,167L136,177L137,181L139,183L141,183L145,180L146,180L144,185L145,188L147,192L151,193L155,191L158,189L160,182L160,176L158,165L159,160L155,144L153,140L150,137L151,135L151,133L145,122L135,109L131,107L126,107L124,108L123,105L132,104L135,101L133,67L127,20L126,18L124,17L115,16L91,16Z\",\"e\":[100,61,9],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--mini_robot_3d_model\":{\"d\":\"M43,21L40,24L38,27L37,36L37,68L39,88L41,93L47,97L63,98L62,101L57,100L53,101L44,108L41,112L43,115L40,118L33,130L31,133L30,137L25,146L21,158L21,161L19,165L17,174L17,181L21,191L27,196L32,196L37,194L40,190L39,188L35,181L39,179L41,182L43,185L47,185L50,183L52,177L51,172L49,167L51,162L53,145L55,142L55,139L60,125L61,135L63,138L64,139L63,140L61,143L60,149L61,159L63,161L61,165L57,181L58,185L56,190L57,192L55,194L51,213L48,216L45,223L44,230L46,233L49,235L58,236L81,236L88,234L90,230L90,223L88,218L89,215L89,201L88,194L90,174L102,175L110,174L111,186L113,187L112,189L112,192L113,194L111,202L111,214L112,218L110,227L111,231L112,234L118,236L122,236L149,236L153,234L155,232L156,230L155,222L149,212L145,193L144,192L143,187L142,185L143,181L139,165L138,161L140,158L140,150L139,143L137,138L139,135L140,125L145,139L146,143L147,146L150,164L152,166L149,176L149,180L150,183L152,185L155,185L159,183L161,178L165,181L161,188L161,192L164,194L172,196L175,195L179,191L182,185L183,179L183,170L179,161L179,159L174,144L170,137L169,132L167,130L161,118L158,115L159,113L158,110L152,104L145,101L138,101L138,98L154,97L159,94L161,90L163,81L164,59L163,35L161,25L158,22L154,20L139,17L121,16L71,17L56,18Z\",\"e\":[100,57,9],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--robot_3d_model2\":{\"d\":\"M77,76L75,78L73,107L74,122L71,123L66,127L66,134L60,134L56,137L54,140L49,140L45,142L41,145L34,155L33,158L34,160L33,162L26,161L22,163L16,180L12,189L13,191L16,194L15,204L17,206L37,215L44,213L48,211L49,207L54,203L53,200L56,198L58,195L61,178L61,174L58,170L62,166L65,178L71,184L76,188L73,190L72,195L67,196L59,213L56,215L52,227L51,232L52,234L75,236L86,236L90,235L91,234L93,234L94,232L94,226L92,213L92,200L89,197L90,194L104,194L111,192L112,199L110,200L109,202L106,226L107,233L117,235L143,236L153,234L154,233L154,230L151,220L148,215L142,213L134,195L132,194L129,194L128,190L126,187L131,184L134,179L136,174L138,165L140,164L143,169L147,171L143,175L147,196L149,198L152,198L152,203L153,206L154,207L156,207L159,213L163,216L165,216L183,205L185,202L185,195L188,192L186,182L178,163L176,161L169,163L167,160L168,154L166,150L162,145L155,140L148,140L146,136L142,133L138,132L138,128L134,125L124,124L128,121L130,117L133,77ZM68,147L68,148L65,152L64,151ZM135,147L138,149L140,149L140,151L139,152L137,150L135,149ZM133,67L132,68L132,72L133,70Z\",\"e\":[101,96,6],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--robot_3d_model3\":{\"d\":\"M72,16L71,19L68,44L66,54L63,89L64,95L69,98L64,100L62,98L59,97L48,102L42,110L30,129L28,133L30,136L28,139L26,139L24,141L15,157L15,176L16,191L18,194L20,195L29,197L34,196L36,192L36,187L41,186L42,171L46,171L47,167L47,147L47,145L43,144L47,143L49,140L54,117L56,116L60,115L62,119L62,124L61,137L55,144L53,165L56,178L61,183L66,185L59,187L56,200L51,203L43,218L39,227L39,231L41,234L48,235L77,236L88,235L92,233L93,226L86,208L83,203L80,203L80,191L119,192L119,203L121,205L115,206L114,207L113,210L111,212L112,214L110,218L111,220L106,229L106,232L108,233L117,236L142,236L156,235L160,231L159,222L147,202L145,201L141,201L142,200L142,197L138,183L143,177L145,168L145,144L143,132L139,117L143,120L152,142L156,144L155,145L152,146L151,148L152,160L151,167L152,170L153,171L157,172L161,188L159,189L167,196L179,195L182,193L184,181L185,166L184,160L175,140L172,138L168,139L165,137L169,135L170,132L162,119L150,103L144,98L136,99L135,101L129,99L134,95L136,92L133,56L129,17L126,16Z\",\"e\":[100,58,9],\"v\":\"0 0 200 240\"},\"09-monolith-tanka--white_horned_robot_3d_model\":{\"d\":\"M144,16L142,17L144,21L144,28L142,32L137,36L126,39L97,39L88,37L83,34L80,30L80,24L83,18L82,17L74,21L67,27L65,30L64,37L64,41L67,46L76,55L84,59L92,62L98,67L98,71L97,74L67,76L65,77L62,80L61,87L56,92L54,100L51,100L33,115L32,121L28,124L25,128L19,146L14,165L14,166L18,170L15,173L16,177L19,184L22,188L29,189L37,188L39,186L46,184L48,181L49,178L52,176L54,173L54,168L51,161L50,134L54,132L65,114L66,114L76,135L80,142L77,147L74,148L63,178L56,188L43,221L40,232L41,235L84,236L87,235L86,228L86,224L83,215L83,211L92,184L94,158L116,159L122,190L119,211L116,220L116,236L156,236L163,235L163,232L160,227L160,223L155,213L149,179L138,151L136,148L133,149L132,145L137,134L141,123L141,123L147,134L149,135L152,134L151,137L154,161L155,166L155,173L156,175L159,176L159,180L160,182L167,186L172,187L176,187L181,184L185,178L186,170L184,168L186,165L187,161L183,150L170,125L165,125L166,121L165,117L153,102L150,101L150,95L147,90L144,87L142,81L140,77L137,74L120,73L128,62L147,54L155,47L159,41L160,34L158,28L152,22Z\",\"e\":[111,56,5],\"v\":\"0 0 200 240\"},\"10-petal-wisp--stylized_creature_3d_model\":{\"d\":\"M92,17L81,21L75,30L74,34L75,44L79,60L83,70L82,74L78,80L73,83L68,84L64,86L58,91L54,97L50,108L49,123L47,132L44,140L36,155L34,161L34,165L36,168L42,171L46,178L50,182L52,182L55,181L60,173L62,159L57,110L58,105L61,101L65,95L63,104L63,113L65,122L67,127L72,132L80,136L79,162L80,181L80,196L78,213L73,222L64,231L63,235L65,236L94,236L96,236L98,234L95,217L94,199L88,164L87,154L88,144L94,167L104,187L108,200L109,207L109,226L110,233L114,236L150,236L150,234L135,219L127,209L116,184L112,178L107,173L100,158L97,137L106,132L113,122L115,112L115,107L111,93L116,96L119,101L124,148L128,162L133,171L146,182L154,185L158,186L156,174L156,167L155,162L157,161L164,159L166,158L166,157L163,154L145,141L138,134L135,129L133,128L133,124L131,117L128,100L123,91L116,85L111,84L105,83L97,78L94,70L95,60L103,51L110,47L114,46L117,47L122,52L123,49L124,42L122,34L119,29L114,23L110,20L101,17Z\",\"e\":[93,36,5],\"v\":\"0 0 200 240\"},\"10-petal-wisp--ghost_character_3d_model\":{\"d\":\"M89,16L86,17L78,27L73,35L72,36L69,40L65,51L65,65L67,72L73,77L72,84L69,83L60,76L58,76L58,80L62,89L69,97L77,102L78,108L76,110L65,115L60,120L55,141L52,148L46,152L39,154L34,159L28,158L26,159L27,164L34,167L38,171L45,173L51,173L60,169L64,165L67,156L68,141L72,149L73,156L70,168L64,175L45,183L40,187L34,195L30,204L30,215L32,220L35,225L43,232L55,236L65,236L72,234L78,230L83,223L84,219L83,216L78,222L72,226L65,226L60,226L55,223L52,220L50,216L50,213L52,209L57,205L74,200L85,195L91,191L98,184L102,176L105,166L103,147L104,138L107,141L113,149L123,155L130,158L142,157L147,155L155,150L159,142L163,125L162,121L160,120L161,117L167,111L175,107L171,104L167,104L160,107L153,113L148,125L144,121L143,121L136,130L128,136L117,132L111,126L103,116L99,113L92,111L92,107L103,98L108,91L110,86L114,70L113,63L111,56L99,37L97,35L93,40L90,38L88,34L87,27Z\",\"e\":[85,60,6],\"v\":\"0 0 200 240\"},\"10-petal-wisp--fantasy_creature_3d_model4\":{\"d\":\"M117,16L112,17L105,20L98,25L93,30L93,32L94,32L101,27L110,24L117,25L119,27L118,31L112,37L101,38L94,43L91,47L89,51L88,52L89,56L94,65L102,72L102,79L101,80L98,81L87,81L85,82L83,85L84,88L77,96L67,106L59,111L54,118L51,125L51,131L52,138L57,149L51,153L47,159L47,161L51,161L60,156L61,158L60,162L59,166L54,172L56,173L60,173L64,171L67,168L69,163L70,154L68,141L64,131L64,122L66,118L73,113L85,100L89,97L94,109L95,120L93,128L89,136L85,151L85,164L88,176L93,186L101,195L109,200L122,206L128,211L133,223L134,236L137,235L139,233L140,236L141,236L144,231L145,225L145,218L143,212L137,204L127,199L122,194L117,187L115,178L115,165L120,142L120,128L128,106L136,123L136,131L134,140L134,148L136,153L138,157L143,162L149,164L152,164L153,163L149,157L145,146L146,135L145,124L137,110L132,92L128,85L125,81L114,80L113,78L117,78L124,62L126,51L122,44L128,37L130,31L130,24L128,21L124,18Z\",\"e\":[108,54,5],\"v\":\"0 0 200 240\"},\"11-anvil-cask--clay-style_robot_3d_model\":{\"d\":\"M161,78L146,77L143,79L120,79L118,80L105,80L105,81L97,81L97,82L69,83L70,80L66,79L48,80L45,79L38,80L69,107L70,116L72,118L66,119L63,125L60,123L56,124L53,125L50,129L41,137L32,148L31,152L34,154L32,156L26,155L24,156L18,166L12,184L12,186L15,188L15,197L16,199L30,205L35,206L40,206L42,203L43,201L45,201L48,198L49,196L48,193L50,192L52,188L55,169L54,167L50,163L54,162L58,155L58,159L59,160L58,161L62,183L64,185L63,186L67,192L74,197L69,201L68,204L63,204L61,205L55,214L50,218L46,229L46,235L50,236L90,236L91,235L92,231L88,208L85,206L86,203L86,201L102,203L114,201L114,203L115,206L111,208L110,220L110,232L111,235L114,236L151,236L156,235L156,227L153,221L148,215L145,214L138,206L135,204L131,204L131,200L126,197L134,191L137,184L135,183L137,182L141,171L141,160L141,152L146,161L150,163L150,164L144,169L148,188L151,192L153,199L156,201L158,201L158,203L160,205L165,206L170,205L182,199L184,196L184,188L187,186L188,184L176,156L173,156L167,157L165,154L167,151L167,149L152,131L150,130L143,123L138,123L134,126L130,119L127,117L128,116L128,111L130,105ZM138,137L140,139L139,141L137,138Z\",\"e\":[100,97,5],\"v\":\"0 0 200 240\"},\"12-seedpod-snailslug--stylized_slug_3d_model\":{\"d\":\"M182,46L175,42L170,41L166,41L155,45L151,48L148,55L147,60L148,69L151,75L141,89L135,99L131,98L125,96L126,90L124,87L122,86L119,85L116,85L111,90L111,94L112,97L116,100L120,100L125,117L123,123L123,131L121,136L118,154L118,162L121,170L121,174L118,176L116,180L115,183L116,185L114,191L113,190L111,189L90,193L86,195L86,197L82,195L69,196L49,200L38,206L23,219L13,222L12,223L13,225L19,227L28,229L66,228L83,230L98,233L120,236L142,236L158,233L170,226L177,220L182,212L185,204L187,194L186,183L184,173L180,165L161,129L159,118L158,108L161,93L165,83L167,81L172,81L179,77L183,74L186,69L188,62L188,55L186,50Z\",\"e\":[167,59,5],\"v\":\"0 0 200 240\"},\"12-seedpod-snailslug--stylized_worm_3d_model\":{\"d\":\"M154,26L134,17L127,16L121,18L118,19L115,23L108,27L99,35L95,41L92,47L90,57L91,70L93,79L97,85L104,92L111,97L121,100L129,99L131,105L125,106L119,109L95,128L66,137L57,132L52,131L45,130L39,132L31,138L27,146L27,150L29,151L39,143L46,144L47,147L49,149L46,153L42,155L39,159L39,161L42,161L59,155L68,148L93,141L97,141L107,135L117,130L121,150L122,160L117,182L115,185L110,191L104,193L96,192L83,188L67,187L59,188L47,190L36,195L25,204L17,214L14,220L13,228L14,231L17,234L21,236L40,234L56,234L79,236L165,236L174,235L179,231L185,219L187,208L186,194L180,177L182,174L183,171L184,159L182,155L178,151L176,134L169,122L164,112L160,108L150,104L145,105L143,94L154,92L162,86L170,78L175,66L174,54L171,43L164,36Z\",\"e\":[133,59,9],\"v\":\"0 0 200 240\"},\"13-fan-split--stylized_3d_character2\":{\"d\":\"M120,18L117,18L112,16L86,17L77,18L62,22L44,30L30,40L16,54L13,59L13,60L17,63L67,91L86,103L83,105L79,110L77,110L75,108L74,109L70,114L63,118L50,132L45,140L33,149L22,164L13,182L13,189L19,191L19,194L22,198L26,198L29,201L32,201L35,198L37,201L40,201L42,198L43,192L44,188L46,191L49,191L52,191L53,189L54,183L57,170L57,162L59,161L61,152L60,149L65,146L63,159L64,169L68,177L72,181L76,184L77,185L70,185L67,188L64,213L62,219L58,225L58,233L59,235L67,236L81,236L93,234L96,232L97,228L94,191L92,188L89,186L97,182L98,173L99,179L100,182L103,184L109,185L108,187L106,187L104,190L101,225L102,232L105,235L109,236L135,235L140,233L141,231L139,225L135,220L133,214L130,198L130,188L128,187L121,185L121,184L127,182L131,177L133,172L135,160L133,147L128,134L127,130L134,140L137,147L140,149L139,151L140,161L143,162L143,173L148,191L152,192L155,190L158,200L161,203L163,202L165,200L171,202L174,200L175,197L179,197L181,195L181,192L186,189L187,187L185,179L178,167L166,149L159,143L153,142L154,138L153,135L132,114L125,110L120,110L117,105L112,103L124,96L182,67L184,66L184,63L169,47L156,35L138,24Z\",\"e\":[98,60,9],\"v\":\"0 0 200 240\"},\"13-fan-split--stylized_toy_3d_model\":{\"d\":\"M67,22L60,26L56,29L47,34L41,39L28,56L27,60L21,73L22,76L25,79L53,95L72,111L77,115L83,116L83,118L79,121L77,120L71,119L64,122L61,125L58,130L58,133L50,145L50,148L44,155L38,167L38,174L35,180L34,188L34,191L34,196L35,202L39,206L43,207L47,206L50,206L51,203L52,200L49,193L52,191L53,194L56,196L58,197L61,196L62,193L62,189L59,183L59,180L61,176L64,165L64,159L65,156L67,155L72,146L72,144L74,144L73,151L75,155L77,156L74,159L74,163L71,166L68,172L66,183L66,188L67,189L66,195L66,198L64,202L61,216L58,219L53,225L52,229L53,234L56,236L89,236L92,231L90,222L92,218L92,207L92,203L89,198L90,195L89,192L91,190L93,180L99,182L104,182L107,180L109,190L111,192L110,196L111,199L109,202L109,216L110,222L109,227L109,232L112,236L145,236L148,234L148,227L144,220L139,216L136,201L134,198L135,195L133,190L135,187L134,177L131,169L129,165L126,163L127,162L126,159L124,156L127,153L126,144L128,144L128,146L133,154L135,156L137,159L136,161L136,165L139,177L142,180L138,190L139,194L141,196L144,197L147,194L149,191L151,193L148,202L149,205L151,206L154,206L157,207L161,206L164,203L166,196L166,184L162,174L163,172L162,167L157,156L153,152L152,149L150,147L151,146L148,140L142,133L142,129L140,125L137,122L133,120L128,119L121,121L121,119L117,118L117,116L125,113L150,93L176,78L179,74L178,68L173,60L171,53L166,47L162,44L161,41L153,33L144,29L141,26L133,22L123,20L113,17L100,17L90,16Z\",\"e\":[100,60,9],\"v\":\"0 0 200 240\"},\"14-chisel-spire--cone_head_3d_model\":{\"d\":\"M102,16L98,17L96,21L85,68L79,121L80,126L78,129L75,129L68,133L58,148L48,172L42,190L42,199L46,206L48,208L52,209L58,209L60,205L56,200L56,197L58,194L59,197L62,199L65,199L66,196L67,192L65,184L70,165L70,162L74,156L74,167L73,170L73,175L74,178L73,180L71,189L71,196L72,198L69,210L69,220L60,226L58,233L60,236L93,236L95,235L96,230L94,222L95,214L94,199L95,198L97,189L105,188L106,197L108,200L107,220L108,222L107,226L106,232L107,235L110,236L136,236L138,235L138,227L137,224L134,221L134,218L130,197L132,200L136,200L138,199L140,195L143,196L142,200L140,205L140,207L141,210L144,211L148,211L154,208L158,202L158,189L154,170L150,160L144,146L139,140L131,131L128,129L124,129L122,125L122,119L121,100L114,59L105,20L104,18ZM127,153L133,163L136,183L131,192L128,178L128,170L127,167L128,163Z\",\"e\":[101,72,5],\"v\":\"0 0 200 240\"},\"14-chisel-spire--low_poly_robot_3d_model\":{\"d\":\"M88,16L68,80L79,90L88,97L82,99L80,100L80,103L78,103L55,120L47,129L47,133L48,135L41,135L30,148L22,160L20,191L21,193L23,193L41,174L42,170L39,165L47,158L45,172L46,173L50,172L53,169L57,161L60,149L60,146L55,139L58,141L61,141L79,115L78,135L82,149L85,156L86,169L84,170L78,180L66,202L61,208L59,223L59,231L63,235L66,236L76,234L78,232L85,211L84,206L85,195L91,176L101,186L103,188L106,188L115,179L118,175L123,188L125,207L124,211L130,231L134,234L140,236L145,236L149,233L151,229L148,217L147,207L131,180L123,169L123,168L124,156L129,145L131,136L131,122L129,114L145,141L149,143L147,146L148,158L151,167L158,178L160,178L161,174L159,164L159,163L165,167L164,177L178,192L180,194L178,161L168,141L161,135L157,127L150,120L131,102L130,101L129,102L127,98L120,97L133,89L141,82L142,79L120,16Z\",\"e\":[104,57,8],\"v\":\"0 0 200 240\"},\"15-orbital-coili--robot_character_3d_model\":{\"d\":\"M80,16L70,22L59,33L54,41L52,54L36,54L33,55L31,57L32,62L36,64L51,65L51,71L57,84L61,88L73,98L87,103L79,106L71,111L69,114L63,121L46,144L45,148L49,150L46,153L35,161L32,167L33,176L37,182L41,185L46,187L53,187L59,185L61,183L65,177L66,170L65,164L61,159L56,156L58,153L64,154L65,152L66,146L70,141L72,148L76,153L73,155L71,158L72,166L75,172L78,176L75,182L74,190L69,192L65,195L65,202L68,204L61,209L62,214L64,217L56,224L56,226L57,231L62,233L89,233L96,232L97,229L97,221L96,219L94,217L97,215L97,210L95,207L92,205L96,202L97,198L95,194L89,191L89,180L92,181L103,181L108,180L112,195L106,197L104,199L105,206L107,208L104,211L105,217L107,219L102,228L103,234L108,236L134,235L140,234L143,231L143,226L140,221L135,220L138,218L138,212L135,208L132,207L135,204L136,199L132,195L126,194L124,184L121,177L119,175L124,172L126,167L127,158L126,155L121,152L125,149L128,144L127,132L123,128L120,126L125,123L134,145L134,147L136,151L138,153L142,153L144,156L140,158L137,162L134,170L136,176L140,183L144,186L149,187L155,187L160,185L166,179L168,175L169,169L167,163L163,158L160,156L154,154L153,148L156,145L155,142L149,137L144,130L129,113L125,111L122,106L113,102L128,96L138,88L145,75L147,65L163,64L166,61L167,57L165,55L162,53L156,54L148,53L143,42L134,31L125,23L115,16ZM150,164L156,166L157,171L156,175L154,177L151,178L146,176L144,173L146,167ZM50,164L54,167L56,170L56,173L54,176L52,178L47,178L44,176L42,171L45,166Z\",\"e\":[99,60,9],\"v\":\"0 0 200 240\"},\"16-spade-arch--pyramid_head_figure_3d_model\":{\"d\":\"M102,16L97,17L92,22L64,59L44,88L45,91L61,104L76,114L82,116L77,118L73,122L71,122L60,129L47,141L38,153L35,162L30,165L27,167L21,179L19,185L20,206L23,212L29,213L33,211L51,194L52,189L51,170L48,168L52,166L61,147L67,138L71,134L70,138L67,143L64,156L59,162L58,178L59,188L59,203L52,208L45,218L41,229L42,234L44,235L52,236L70,235L72,234L81,234L84,233L84,220L82,209L78,203L82,193L87,185L93,179L99,178L105,179L108,180L112,184L120,198L121,202L118,204L115,209L112,215L109,224L108,231L108,235L114,236L129,234L132,223L133,221L136,227L137,233L139,235L151,235L157,234L159,232L158,223L151,210L147,204L140,200L139,187L141,175L141,166L137,151L131,139L136,144L140,150L139,151L142,154L142,155L144,157L144,158L147,160L148,164L152,167L150,169L151,175L153,175L153,188L156,195L165,204L174,210L177,209L180,204L181,190L175,175L168,162L165,160L163,162L162,161L162,159L165,156L162,152L151,139L140,130L127,122L123,122L116,117L123,114L146,99L154,93L155,89L136,59L108,23Z\",\"e\":[99,68,9],\"v\":\"0 0 200 240\"},\"16-spade-arch--stylized_humanoid_3d_model\":{\"d\":\"M106,16L64,33L64,37L73,56L82,60L64,65L55,72L53,75L49,83L35,100L29,105L17,137L17,147L17,153L19,159L25,163L32,167L37,166L42,164L45,161L46,155L49,151L49,145L45,139L37,132L46,119L48,114L55,110L69,98L70,99L76,117L77,127L73,130L70,134L68,139L68,146L65,147L62,159L61,171L58,185L54,208L49,212L47,219L43,227L42,234L44,236L77,236L80,235L82,232L84,227L84,216L83,213L81,213L82,191L80,180L97,154L106,155L113,169L119,180L118,196L119,213L117,214L116,217L117,229L118,233L121,235L125,236L149,236L151,234L153,228L152,217L150,212L146,209L142,186L139,174L139,160L137,149L135,139L131,132L126,127L126,122L128,115L135,100L145,110L156,118L158,123L163,135L154,141L150,144L148,148L148,155L151,158L150,160L150,164L152,166L158,169L160,169L161,170L168,169L177,166L180,163L183,153L183,141L181,136L177,116L175,109L171,105L165,96L156,84L152,77L148,72L143,68L125,62L132,59L135,58L147,36Z\",\"e\":[105,39,6],\"v\":\"0 0 200 240\"},\"17-shellcap-manyarm--3d_character_figurine\":{\"d\":\"M72,39L60,45L50,53L36,67L29,80L29,83L31,88L34,92L39,96L51,102L72,110L49,118L47,121L43,123L39,128L32,129L24,134L19,139L16,144L12,155L12,159L15,165L17,167L23,167L27,164L29,160L33,163L35,162L41,160L45,156L48,150L48,138L52,135L56,137L59,136L71,127L68,134L66,143L61,145L47,156L46,158L47,162L42,166L40,172L40,173L34,176L27,184L24,192L23,200L25,205L29,210L34,212L40,208L43,202L45,203L47,203L52,200L55,196L55,188L53,181L51,180L55,176L57,171L61,170L64,166L66,175L70,181L68,187L66,194L68,202L65,203L58,214L50,217L45,221L44,224L43,233L45,235L48,236L90,236L94,236L96,234L98,229L97,222L90,203L84,201L85,193L91,195L99,196L108,196L118,194L119,202L116,203L114,206L107,226L107,231L109,235L113,236L150,236L153,232L153,225L142,205L140,202L136,201L137,196L133,182L136,179L139,170L143,173L145,174L147,179L149,182L146,188L145,192L145,196L147,201L149,204L152,205L157,203L159,210L161,212L164,213L169,213L173,211L177,205L177,194L176,190L171,182L166,178L162,176L162,172L156,165L157,163L161,166L165,166L167,163L167,157L170,159L171,162L173,170L176,172L180,173L184,171L187,167L188,161L187,153L184,148L176,139L168,135L163,134L161,135L159,131L159,128L155,124L138,115L130,113L150,109L161,105L166,103L172,98L173,96L172,92L164,77L152,62L144,54L130,44L112,36L99,34L80,37ZM137,133L144,141L147,142L151,141L154,142L152,149L152,156L139,145Z\",\"e\":[100,75,9],\"v\":\"0 0 200 240\"},\"17-shellcap-manyarm--mushroom_creature_3d_model\":{\"d\":\"M13,165L12,171L14,174L19,178L23,178L30,176L37,180L43,180L47,178L49,179L45,180L41,182L34,183L27,186L24,186L18,189L15,191L13,197L12,201L14,205L19,209L22,209L28,206L32,200L41,199L46,196L47,196L42,201L39,202L35,205L26,218L25,223L26,230L27,233L32,235L36,235L40,233L43,227L44,222L47,219L52,212L61,206L63,210L59,218L54,223L53,227L53,232L57,236L85,236L89,232L92,222L108,222L111,232L113,234L117,236L143,236L147,233L148,228L145,222L137,210L139,206L148,211L156,221L157,227L160,232L164,234L168,234L171,233L174,230L175,227L174,218L169,212L166,205L152,195L154,195L158,197L162,198L168,199L172,205L177,208L181,208L186,205L187,201L187,195L184,190L181,187L177,186L173,186L169,182L162,180L159,181L155,178L151,177L153,176L157,178L165,177L171,174L177,176L182,175L186,173L188,169L188,165L186,161L183,158L179,157L173,157L168,160L161,160L153,163L140,161L137,158L150,157L154,156L157,154L159,148L159,144L157,138L151,127L137,112L126,103L113,98L98,97L90,98L82,100L69,106L57,117L45,134L41,142L41,148L43,154L47,156L63,158L60,162L47,164L39,162L32,162L29,160L23,159L17,161Z\",\"e\":[100,125,8],\"v\":\"0 0 200 240\"},\"17-shellcap-manyarm--mushroom_robot_3d_model\":{\"d\":\"M86,39L71,47L58,58L40,77L34,87L34,90L43,94L69,101L87,104L82,110L78,107L74,108L60,112L49,117L46,121L47,125L44,126L43,129L37,127L33,127L24,133L16,142L13,147L12,157L16,162L19,165L21,165L27,162L28,159L29,154L32,157L34,158L42,154L46,149L48,142L48,135L51,136L52,132L56,135L71,124L76,122L77,123L75,124L71,132L70,140L66,141L51,152L49,155L49,158L51,161L48,162L44,164L40,171L36,171L31,173L23,183L21,185L21,198L26,206L37,206L39,203L38,193L42,189L43,191L41,194L42,197L45,199L51,198L54,195L53,180L52,178L57,172L57,168L60,169L63,168L66,165L68,161L70,170L74,175L78,177L75,177L74,179L70,189L69,197L70,200L68,200L67,201L57,215L49,222L46,229L47,234L49,235L63,236L90,236L99,235L100,234L100,229L97,222L98,221L97,219L97,216L95,214L96,212L94,210L94,208L92,204L87,202L88,200L88,192L89,189L99,192L106,193L116,192L123,190L126,187L126,191L127,201L124,201L120,208L114,225L114,234L120,236L163,235L167,234L168,233L168,229L167,226L164,220L156,214L147,200L144,199L145,191L142,178L141,177L138,177L141,175L143,170L145,160L150,167L154,169L157,169L158,175L161,179L158,182L155,187L155,193L156,197L160,201L169,200L166,193L167,193L169,194L172,197L171,206L172,209L173,211L186,211L187,208L188,202L187,186L184,179L173,172L170,165L167,162L168,160L162,151L150,142L146,141L143,141L141,126L139,123L147,128L155,134L159,134L163,130L167,136L165,143L166,153L168,157L172,160L177,160L180,158L182,156L185,156L187,145L186,134L185,131L182,127L178,125L168,116L156,111L141,107L134,107L133,109L128,104L156,97L165,94L178,87L182,82L182,71L175,62L165,52L153,42L145,39Z\",\"e\":[108,71,9],\"v\":\"0 0 200 240\"},\"18-quad-all--dragon_creature_3d_model\":{\"d\":\"M137,16L127,19L107,28L92,38L77,53L69,56L57,65L46,78L40,88L37,100L36,107L36,116L39,119L44,121L49,120L52,117L62,102L68,95L80,106L82,111L83,117L78,127L76,133L69,141L67,149L64,179L61,195L60,209L58,218L59,222L57,223L54,222L52,224L48,231L47,235L55,234L56,236L57,235L68,236L75,234L79,236L79,233L78,227L74,223L75,212L83,186L95,168L104,170L112,170L117,168L129,186L139,222L136,223L134,226L132,231L132,236L137,233L138,235L142,235L143,236L144,235L155,235L157,234L164,235L164,231L160,224L153,221L154,219L150,180L148,175L144,147L142,139L135,131L133,125L125,115L116,111L98,97L81,87L91,85L93,84L112,83L138,88L144,88L134,78L125,73L103,69L113,65L125,63L139,58L143,46L144,36L137,38L122,44L109,53L102,53L110,41L116,34L126,25L138,17Z\",\"e\":[103,134,8],\"v\":\"0 0 200 240\"},\"18-quad-all--fantasy_creature_3d_model1\":{\"d\":\"M64,23L63,25L64,29L77,51L88,67L94,72L95,76L105,86L107,99L106,100L102,99L89,100L79,104L73,108L64,103L56,101L46,101L30,106L31,109L36,118L40,124L46,128L39,164L38,168L33,173L31,177L29,199L23,229L24,234L26,236L60,236L61,232L58,226L54,222L51,220L46,209L45,196L46,183L47,180L53,176L64,163L69,154L72,144L79,145L83,164L79,168L77,174L78,207L76,230L80,235L81,236L118,236L119,235L119,232L117,228L113,223L108,220L105,211L99,191L98,176L100,170L102,167L108,168L114,168L120,166L126,162L130,177L130,184L136,210L137,228L139,234L141,236L176,236L177,233L174,228L163,219L160,213L154,202L145,182L145,155L145,148L144,140L141,132L137,128L136,119L131,112L133,100L135,92L141,90L157,91L156,85L153,79L151,74L140,50L128,33L123,28L121,26L113,26L106,20L100,16L100,17L102,25L100,27L100,30L102,39L92,32L86,28Z\",\"e\":[111,135,7],\"v\":\"0 0 200 240\"},\"18-quad-all--fantasy_creature_3d_model3\":{\"d\":\"M99,16L97,18L94,24L90,33L83,61L84,70L82,74L82,94L84,98L89,103L93,110L82,119L79,125L76,125L72,126L68,130L64,139L61,149L58,168L51,183L45,204L44,215L45,226L50,234L53,236L56,235L58,234L59,235L76,235L76,234L72,226L77,200L77,194L86,156L96,159L102,159L111,157L116,155L122,175L121,184L126,211L127,227L124,235L131,235L133,234L134,235L138,235L140,234L140,236L148,234L148,232L151,235L156,235L156,232L153,224L153,215L152,207L146,185L141,176L139,170L137,148L134,138L129,128L125,125L121,125L119,120L111,112L107,110L110,105L116,99L118,96L119,74L116,71L117,61L110,34L107,25L101,16Z\",\"e\":[99,95,4],\"v\":\"0 0 200 240\"},\"18-quad-all--four-legged_robot_3d_model\":{\"d\":\"M96,29L91,34L86,42L81,46L52,148L50,157L49,170L48,171L46,169L44,169L40,171L35,176L33,182L29,180L26,185L19,198L15,209L12,221L13,231L16,236L33,236L37,232L38,232L40,230L44,222L46,213L46,226L49,234L52,234L53,236L68,236L71,232L76,225L78,210L86,211L85,224L89,233L93,236L110,236L114,233L116,228L117,219L117,208L123,208L124,221L125,228L127,232L133,236L147,236L151,234L154,227L154,217L157,227L165,236L183,236L186,233L188,227L187,215L183,202L173,182L172,181L168,181L165,175L162,171L156,167L153,168L148,171L147,170L147,157L144,144L141,135L139,134L113,45L111,42L109,41L100,30L98,29ZM50,185L52,191L46,210L47,195L45,192L44,192L48,189ZM147,182L148,182L153,189L156,192L153,192L152,194L153,209L147,202L145,202L148,197L147,190L147,188L146,185Z\",\"e\":[88,158,2],\"v\":\"0 0 200 240\"},\"18-quad-all--quadruped_robot_3d_model1\":{\"d\":\"M134,70L125,64L119,63L112,62L105,63L94,68L77,78L67,90L59,101L51,98L48,98L47,99L46,103L48,114L53,138L49,146L43,154L32,164L26,171L17,203L17,209L18,209L13,224L12,234L13,235L35,236L38,235L39,231L35,214L45,213L47,212L44,193L45,181L59,156L63,152L69,150L74,150L74,164L77,169L84,178L87,179L88,191L85,194L77,215L68,235L69,236L79,236L88,234L90,236L95,236L122,235L123,233L122,231L129,221L131,213L133,180L133,175L122,156L133,154L141,149L143,151L142,157L143,161L155,176L157,178L160,179L166,192L165,194L164,201L158,233L159,235L161,236L172,236L178,235L181,236L188,235L188,213L187,205L181,188L180,187L179,188L178,187L173,170L183,160L187,151L186,136L182,126L173,118L167,115L163,115L157,118L150,126L146,116L137,105L127,99L114,95L99,94L103,86L110,80L123,74L133,74L135,71ZM112,165L109,171L105,188L103,190L103,172Z\",\"e\":[130,133,5],\"v\":\"0 0 200 240\"},\"18-quad-all--quadruped_robot_3d_model\":{\"d\":\"M96,17L92,18L89,22L86,26L86,29L86,35L89,39L92,43L95,44L95,76L92,78L91,82L84,84L75,89L64,98L60,103L55,112L53,124L50,125L47,131L46,138L47,141L49,144L53,147L54,151L59,154L67,154L69,155L67,157L64,162L61,161L59,162L52,181L50,187L48,187L46,189L38,207L34,221L33,233L35,235L37,236L61,236L64,235L66,236L93,236L96,234L98,231L98,226L92,192L91,190L92,179L99,181L108,180L109,189L108,192L101,224L101,229L104,234L108,236L133,236L135,235L140,236L163,236L166,234L167,231L164,211L154,189L152,187L149,187L148,180L141,162L138,160L135,161L134,158L130,155L138,153L142,152L145,147L146,140L146,129L143,112L138,103L131,94L121,86L108,82L108,78L104,76L104,44L108,42L112,38L113,34L114,30L111,23L108,19L102,16ZM123,166L128,169L126,171L135,192L133,194L132,204L128,189L125,186ZM77,165L74,187L72,189L67,203L66,194L64,192L66,189L73,171L71,169Z\",\"e\":[101,121,9],\"v\":\"0 0 200 240\"},\"18-quad-all--robotic_dog_3d_model\":{\"d\":\"M79,59L81,106L79,107L56,89L55,89L65,120L61,128L59,134L56,134L54,129L51,127L45,125L40,128L35,135L34,139L34,149L28,174L29,181L28,198L26,205L24,214L21,215L16,221L13,226L12,234L14,235L25,233L28,231L30,232L34,232L36,234L42,233L45,232L46,229L53,231L56,231L58,233L61,232L63,226L63,221L61,218L56,213L55,213L52,215L44,209L45,186L48,182L51,157L56,154L67,156L68,165L74,175L84,187L91,191L93,190L92,169L88,168L86,166L94,168L99,171L101,171L106,168L107,168L107,188L106,190L107,191L114,188L119,183L126,175L131,166L133,156L143,155L149,159L152,169L157,194L157,207L152,211L149,218L148,218L146,216L143,216L140,219L137,227L138,235L139,236L141,235L144,230L146,235L152,234L154,236L157,236L160,233L167,233L172,236L173,235L174,231L176,232L180,232L186,236L188,235L188,233L185,225L182,220L178,218L173,209L172,190L171,186L172,177L168,166L166,149L165,137L159,130L154,128L151,128L147,130L144,134L141,134L139,127L135,121L147,89L145,89L121,107L111,103L100,102ZM119,164L116,167L110,167Z\",\"e\":[100,141,6],\"v\":\"0 0 200 240\"},\"18-quad-all--stylized_quadruped_3d_model\":{\"d\":\"M79,16L77,18L69,36L63,70L57,89L52,114L52,122L55,136L49,144L42,159L34,168L32,172L31,179L33,187L32,194L28,206L23,216L22,221L19,227L17,234L22,236L57,236L61,234L61,226L56,202L54,190L58,187L62,181L78,163L89,167L107,168L110,184L113,188L114,191L111,204L105,220L102,235L108,236L141,235L141,226L134,202L131,189L133,181L130,160L135,158L137,168L140,174L146,180L152,183L154,187L153,201L146,219L147,221L144,228L143,234L150,236L182,235L183,232L182,223L173,189L176,180L178,169L178,162L176,156L173,151L167,146L166,141L164,134L161,128L157,124L147,119L136,119L134,101L132,93L128,84L120,73L112,67L105,63L111,32L112,22L108,21Z\",\"e\":[100,118,8],\"v\":\"0 0 200 240\"},\"18-quad-all--wooden_four-legged_robot_3d_model\":{\"d\":\"M188,218L185,205L180,191L170,177L162,171L165,157L165,152L164,149L157,143L148,139L134,136L125,135L107,140L89,141L84,142L76,147L66,158L61,155L55,156L52,161L53,171L47,172L45,170L43,170L39,172L30,179L24,187L18,199L13,214L12,225L13,231L16,234L26,234L31,227L32,223L30,219L33,217L36,217L44,211L53,196L54,193L52,190L56,189L59,193L63,194L58,208L57,219L60,231L64,236L78,236L82,230L83,226L81,223L83,221L87,212L87,206L89,204L100,202L103,207L109,211L112,214L117,213L118,218L117,220L118,225L120,229L125,234L137,233L141,229L144,218L145,208L145,194L153,207L165,218L164,220L164,225L166,229L172,234L184,234L188,228Z\",\"e\":[124,185,3],\"v\":\"0 0 200 240\"},\"18-quad-all--wooden_robot_3d_model\":{\"d\":\"M100,48L95,51L91,57L88,64L86,75L86,82L88,89L91,92L97,92L97,93L95,99L80,103L72,99L63,99L60,99L55,102L50,108L50,114L52,120L56,128L54,139L54,146L56,156L53,155L50,155L44,159L34,169L24,184L18,197L13,211L12,223L13,225L14,230L17,233L19,234L36,233L40,231L54,209L67,182L66,177L69,173L77,180L76,193L76,207L79,224L83,234L84,235L89,236L105,235L108,230L111,218L111,192L111,182L112,181L122,179L133,172L135,174L134,176L135,182L140,198L146,211L154,224L164,234L175,236L185,235L187,232L188,224L187,214L184,201L175,181L168,170L158,158L152,155L147,157L143,156L147,144L146,136L143,127L147,121L148,111L148,107L139,99L135,98L130,98L118,102L113,100L113,98L112,91L115,89L117,82L116,70L113,60L109,54L102,48Z\",\"e\":[87,131,4],\"v\":\"0 0 200 240\"},\"19-genie-multi--fantasy_creature_3d_model\":{\"d\":\"M109,16L94,38L96,52L100,59L89,64L84,67L82,73L82,80L77,87L73,88L71,86L60,82L54,77L53,75L56,72L58,68L61,69L63,66L62,62L59,60L56,60L54,62L56,64L55,66L53,68L51,68L49,67L49,62L56,59L57,58L56,55L53,54L49,55L45,57L43,60L43,65L41,68L41,72L44,78L54,88L61,93L68,97L75,97L73,103L56,107L53,106L52,108L49,107L47,106L48,98L49,98L51,97L52,93L50,90L45,90L42,92L41,88L37,88L33,92L32,95L34,106L40,113L43,114L51,115L68,114L79,111L84,99L87,98L91,88L95,89L96,96L96,102L91,104L88,115L88,116L84,119L79,118L70,118L61,120L55,123L50,126L46,131L43,139L43,145L46,154L48,158L53,163L60,168L74,173L78,175L78,178L73,183L70,190L70,196L71,201L74,205L79,210L95,222L98,228L101,236L102,227L101,221L98,215L89,204L87,198L89,194L99,189L104,184L108,177L108,172L105,164L102,160L95,155L88,151L98,152L108,150L115,146L122,139L124,131L124,122L126,119L125,108L122,105L125,92L128,95L134,109L148,112L148,130L141,135L137,141L138,143L140,145L145,140L146,141L143,147L140,146L137,150L138,152L140,154L149,153L151,149L154,148L158,135L157,132L157,112L162,109L166,104L167,99L169,95L168,90L165,87L163,87L160,89L163,93L162,96L160,97L159,90L160,89L160,87L157,85L153,86L151,89L150,91L153,95L156,95L156,104L154,104L144,92L152,85L157,78L160,77L163,70L164,64L162,60L162,56L160,53L158,51L154,50L150,50L149,52L149,53L151,56L153,56L155,57L155,61L153,63L150,62L149,60L150,59L150,57L149,55L146,55L143,56L142,59L143,63L145,65L146,63L152,70L152,72L152,73L147,78L139,83L135,75L135,70L132,64L129,62L125,61L118,59L122,51L124,38ZM42,92L42,95L44,96L43,99L40,102L38,97L41,94Z\",\"e\":[111,77,6],\"v\":\"0 0 200 240\"},\"19-genie-multi--multi-armed_humanoid_3d_model1\":{\"d\":\"M127,16L122,18L111,31L107,30L101,30L94,24L84,21L87,38L90,44L88,47L88,50L91,56L96,61L99,67L97,71L93,71L86,72L85,74L84,78L66,79L66,74L60,68L56,56L60,52L62,46L61,44L58,43L52,44L50,46L49,51L52,56L53,64L53,77L54,80L56,82L60,85L67,83L83,86L79,92L75,93L64,102L60,101L55,102L47,94L47,89L46,87L44,85L39,85L36,86L35,91L24,102L23,114L26,120L27,119L27,115L29,120L30,120L31,118L31,111L33,107L34,112L37,113L36,110L39,106L38,102L41,95L46,101L50,110L54,113L59,114L63,112L66,107L81,101L86,95L90,92L92,98L90,100L88,104L85,106L83,109L70,118L68,117L64,118L62,121L59,127L48,139L44,146L45,150L43,160L45,166L50,172L54,173L58,172L58,171L61,170L60,168L56,165L54,163L54,159L55,158L57,161L61,163L62,162L58,157L55,145L57,140L63,132L70,129L73,125L73,122L82,117L89,115L94,108L95,113L96,120L89,130L89,132L86,137L83,146L81,155L81,173L72,182L69,187L68,193L68,199L67,206L64,212L59,219L59,225L57,226L56,224L53,223L49,225L43,230L42,233L43,236L47,233L48,234L50,233L54,234L57,232L63,231L65,236L68,233L74,235L75,226L74,223L73,211L77,203L85,197L88,192L89,177L94,168L100,150L102,151L106,150L113,176L112,186L113,193L116,198L121,203L123,211L124,217L123,224L121,226L118,224L114,225L112,232L112,234L113,235L116,233L117,234L122,234L124,233L129,232L134,236L135,235L137,235L139,236L140,235L143,235L147,234L152,236L152,234L150,230L145,226L142,225L139,226L137,225L138,222L132,213L130,199L130,190L126,179L122,174L121,144L116,128L111,120L113,106L114,106L118,114L135,121L136,127L143,130L151,143L141,162L143,163L149,158L150,158L149,162L148,164L142,168L144,170L146,170L147,172L150,172L154,170L157,167L161,160L160,150L161,148L160,143L149,127L145,119L141,117L138,118L125,109L121,104L118,97L115,96L118,91L119,91L126,98L142,105L143,109L146,111L150,111L155,109L160,99L159,106L161,105L166,101L168,104L169,111L173,111L176,108L177,102L176,97L172,89L171,86L167,83L163,83L160,85L159,88L160,91L153,99L147,99L145,100L133,92L129,90L124,85L143,82L145,83L149,83L153,79L155,76L157,60L162,49L161,44L159,41L153,41L150,43L151,48L154,53L151,63L143,72L142,77L123,77L122,73L121,72L110,71L109,68L113,64L120,52L121,48L120,45L127,27L128,23Z\",\"e\":[105,46,5],\"v\":\"0 0 200 240\"},\"19-genie-multi--multi-armed_humanoid_3d_model\":{\"d\":\"M164,31L162,31L156,36L153,39L152,44L148,48L148,56L149,59L153,63L142,82L122,80L119,76L117,75L105,73L105,71L111,68L119,58L120,54L120,48L123,36L122,33L115,35L110,31L106,16L98,31L92,33L86,28L84,29L84,37L85,45L83,49L83,54L86,60L95,70L95,74L91,74L82,76L77,79L74,83L57,86L48,70L53,63L53,55L49,51L46,44L40,39L38,39L39,49L34,55L32,51L31,52L30,59L33,68L37,72L37,75L40,83L44,92L48,97L52,98L76,93L77,93L78,96L65,106L61,109L49,115L45,113L43,110L41,108L35,107L32,109L30,111L33,113L33,117L32,119L32,122L28,119L27,119L26,122L28,125L33,130L36,132L46,132L57,127L69,117L76,111L81,107L83,109L84,115L83,118L66,132L54,153L46,155L40,160L37,167L37,173L40,178L45,182L47,182L47,179L48,175L46,174L46,172L48,169L52,167L54,168L55,171L51,177L51,178L52,179L56,179L61,176L63,173L65,168L65,161L72,146L74,138L82,134L84,138L76,171L73,177L72,189L68,207L65,211L55,214L51,218L48,222L43,234L44,236L80,235L81,225L81,219L78,211L85,188L88,182L89,175L99,152L104,151L111,174L111,181L115,187L120,211L115,222L115,227L115,235L120,236L149,236L150,235L150,228L146,218L141,214L133,211L130,207L126,183L126,177L123,167L120,146L117,136L118,136L123,140L126,145L137,159L137,168L139,172L142,175L145,177L151,177L151,175L148,170L149,167L153,166L156,168L157,171L157,174L155,177L155,180L156,181L163,176L165,172L165,163L163,159L157,153L145,151L133,134L129,131L124,123L118,118L118,112L119,107L123,109L141,125L154,130L160,130L164,129L172,122L174,118L173,115L171,115L169,112L165,110L168,108L169,105L164,104L159,105L156,106L148,113L136,106L127,99L120,95L121,91L136,93L149,93L154,88L159,79L163,65L167,62L170,56L171,51L170,45L168,44L166,48L165,44L162,41L164,32Z\",\"e\":[100,44,4],\"v\":\"0 0 200 240\"},\"19-genie-multi--stylized_octopus_3d_model\":{\"d\":\"M42,16L36,21L31,27L28,35L29,40L32,48L39,54L47,57L53,58L57,57L62,54L72,43L75,42L78,44L80,47L80,55L72,70L71,75L71,84L72,90L76,96L82,102L89,106L90,113L84,114L79,116L67,114L55,116L52,116L47,113L41,107L38,101L38,95L39,90L41,86L47,79L48,76L42,77L34,81L28,86L24,94L22,102L23,114L27,122L34,128L41,131L52,132L65,130L72,132L74,135L64,142L52,148L43,150L35,153L29,159L25,163L22,173L21,180L23,188L29,196L35,199L41,200L47,197L51,191L51,186L50,183L49,182L47,188L46,190L43,191L41,189L39,183L39,179L41,172L51,162L63,159L70,154L73,150L76,147L79,164L78,172L78,180L79,185L83,193L88,199L94,204L117,213L121,218L123,224L123,229L120,235L123,236L127,236L133,231L136,226L137,218L136,210L133,205L127,198L121,194L113,187L109,177L109,170L117,153L119,141L123,142L127,144L131,144L131,147L136,149L148,151L153,155L158,159L161,163L162,167L160,175L158,177L155,176L153,173L152,167L150,169L149,172L151,179L153,182L158,185L162,186L165,185L172,181L176,176L179,169L179,164L177,155L172,147L166,142L158,138L140,136L122,130L123,126L129,123L150,118L154,116L158,112L162,106L164,99L164,93L162,86L158,78L150,70L143,67L140,66L135,67L134,68L139,72L142,76L146,86L147,91L143,100L138,105L127,107L121,109L116,114L112,113L105,113L104,112L105,104L112,100L117,95L120,87L121,78L120,72L117,67L112,57L104,49L103,43L99,35L93,29L87,24L79,21L72,21L66,23L60,28L53,40L50,42L47,42L42,39L40,35L39,27L44,16Z\",\"e\":[91,45,3],\"v\":\"0 0 200 240\"},\"20-lume--robotic_figure_3d_model\":{\"d\":\"M55,25L49,28L46,31L44,35L45,38L50,43L56,47L69,53L82,57L87,61L93,67L93,76L86,79L84,81L80,86L79,93L73,98L71,97L70,99L62,114L51,127L46,137L41,151L36,157L32,163L31,167L32,175L36,180L40,182L46,182L52,177L54,172L54,163L52,155L62,146L66,140L74,113L76,109L80,105L84,120L87,138L94,159L91,159L89,162L85,174L77,191L76,205L69,219L67,224L54,230L52,232L52,235L54,236L78,236L80,235L84,218L88,210L93,203L93,186L97,167L100,170L102,170L106,167L110,180L114,202L124,216L131,235L133,236L156,236L157,234L156,230L153,228L144,224L140,218L132,202L129,189L123,180L117,168L116,168L116,165L113,159L110,160L108,156L109,145L116,121L119,105L127,111L131,126L133,137L137,144L148,156L146,172L146,175L150,180L157,183L164,181L169,175L169,168L161,153L159,150L155,138L151,128L141,116L133,101L132,100L129,100L119,93L119,88L116,83L113,79L105,76L105,66L108,63L117,59L133,55L143,50L151,45L153,41L153,39L146,32L139,27L125,21L109,17L101,16L86,17L68,20ZM155,160L160,170L160,174L157,177L153,175L152,171ZM46,158L48,170L45,175L43,175L40,173L39,168L42,161Z\",\"e\":[99,42,6],\"v\":\"0 0 200 240\"},\"21-flyer--winged_humanoid_3d_model\":{\"d\":\"M109,16L107,19L95,42L87,54L85,59L85,65L86,69L90,75L96,80L96,85L85,88L78,81L71,66L65,42L63,43L55,52L39,79L31,97L24,123L22,141L23,161L27,179L30,188L32,190L42,161L49,148L49,157L52,165L54,167L62,169L67,168L69,166L69,163L65,161L63,159L62,152L63,151L65,151L67,156L69,158L72,157L73,154L70,147L61,139L61,138L64,129L83,112L86,126L86,129L82,139L83,174L83,184L77,216L72,222L71,225L67,228L65,233L66,236L74,233L76,233L77,236L80,234L86,234L89,235L93,230L94,224L91,215L94,186L93,179L98,148L103,148L107,179L109,216L107,223L107,229L112,235L115,234L121,234L122,236L124,236L126,233L133,236L135,235L135,232L134,228L129,224L129,222L124,216L117,180L119,140L115,130L115,123L118,112L136,129L139,137L139,139L131,146L128,151L128,155L130,158L131,158L134,156L136,151L138,152L138,159L136,161L133,162L132,163L132,166L134,168L139,169L144,168L147,166L152,157L152,149L159,163L168,190L169,189L172,184L176,172L178,157L177,135L175,117L170,100L164,83L156,68L145,52L138,44L136,44L129,67L122,81L116,88L108,86L105,85L105,82L111,77L117,70L119,61L114,41Z\",\"e\":[62,98,7],\"v\":\"0 0 200 240\"},\"22-curve--stylized_alien_3d_model\":{\"d\":\"M83,17L79,21L73,28L70,38L71,46L74,54L79,59L87,64L98,67L98,70L89,73L81,78L71,100L69,103L58,112L44,130L39,132L32,137L27,145L27,151L27,157L29,161L31,162L35,172L41,177L45,178L49,179L54,177L57,174L57,172L56,171L49,170L45,168L43,163L43,160L46,154L47,151L51,149L53,146L57,149L58,156L59,160L62,160L64,159L65,155L64,146L62,140L59,136L63,130L74,116L76,107L88,90L89,89L95,102L96,109L94,112L88,120L79,140L79,160L81,174L81,179L78,186L74,205L58,229L56,234L58,236L61,236L85,236L91,234L91,230L85,219L85,206L90,186L99,167L103,149L107,150L107,177L103,189L102,204L97,230L97,234L101,236L135,236L137,234L135,232L121,221L117,216L115,211L114,205L117,184L127,164L131,152L132,144L132,137L129,128L125,120L117,111L116,108L117,102L121,97L122,94L132,108L133,115L137,121L150,136L150,141L152,146L153,161L157,165L161,164L160,167L156,168L154,169L155,172L158,173L155,176L154,178L157,180L161,179L165,177L168,174L172,166L174,157L166,138L151,113L146,108L141,105L137,100L131,87L127,78L124,75L119,73L111,71L111,67L112,67L114,65L122,64L128,61L133,57L138,51L141,45L142,38L142,31L138,23L135,19L132,17L130,26L127,32L125,34L118,38L113,40L102,40L93,38L88,34L86,26L87,16ZM158,153L159,155L158,158Z\",\"e\":[99,53,4],\"v\":\"0 0 200 240\"},\"22-curve--stylized_cartoon_figure_3d_model\":{\"d\":\"M68,19L61,22L55,30L54,35L55,42L51,44L46,51L45,54L46,62L42,65L40,69L39,73L38,78L40,83L44,88L42,94L42,98L45,104L51,110L55,113L56,117L58,121L60,124L65,126L69,126L69,128L72,129L66,131L63,133L61,140L54,145L51,150L49,155L50,158L46,160L41,166L37,177L38,183L35,193L35,199L39,205L45,209L52,207L54,205L54,202L50,196L51,194L52,194L56,198L59,198L61,196L62,192L60,186L62,181L64,168L63,164L65,163L71,153L70,166L72,172L69,177L66,188L66,193L68,197L64,205L61,218L56,223L53,228L52,231L52,234L57,236L90,236L92,234L93,231L93,225L91,221L92,217L93,211L91,201L89,198L92,191L92,185L102,185L108,184L109,194L111,198L108,209L107,217L109,221L107,222L106,227L106,233L108,235L109,236L145,236L147,232L147,229L146,225L138,218L135,203L132,197L134,194L134,189L132,178L129,172L131,165L129,154L133,160L137,164L136,167L138,180L140,185L138,190L139,196L142,198L144,198L147,196L148,194L150,196L147,201L146,204L147,206L154,209L157,209L160,207L163,204L165,197L165,191L163,183L163,178L162,171L156,161L151,158L152,156L151,153L147,147L143,142L139,140L138,135L134,131L141,126L143,118L151,111L152,108L153,100L151,95L155,91L157,88L158,83L157,76L152,71L156,65L155,59L151,53L144,49L144,45L141,39L134,34L129,33L127,28L119,22L101,21L98,20L81,16L74,17Z\",\"e\":[98,71,9],\"v\":\"0 0 200 240\"},\"23-blob-texture-bodies--blob_creature_3d_model\":{\"d\":\"M126,31L117,27L107,26L92,28L86,30L75,39L72,42L69,50L62,53L49,65L41,79L35,80L29,83L23,90L20,96L20,101L20,107L22,111L27,118L36,123L32,128L29,133L27,141L27,148L30,158L39,167L36,171L33,172L30,175L22,189L14,209L12,221L13,228L14,232L18,236L46,236L51,232L57,223L61,210L64,193L65,181L67,180L70,177L71,173L77,172L80,179L85,186L94,192L101,194L110,194L118,191L126,186L129,182L132,176L138,176L140,179L141,199L143,211L148,225L151,229L154,234L157,236L175,236L180,231L182,225L183,220L183,206L178,186L171,172L176,162L177,155L177,150L175,146L170,138L178,130L186,113L188,107L188,98L186,89L184,81L181,74L174,66L168,62L149,56L143,54L141,46L137,40L133,36Z\",\"e\":[104,81,9],\"v\":\"0 0 200 240\"},\"23-blob-texture-bodies--cute_blob_creature_3d_model\":{\"d\":\"M49,78L37,91L25,106L17,123L12,142L13,158L18,176L21,180L26,185L24,187L24,191L28,200L20,210L19,214L19,218L21,223L25,226L29,227L29,232L34,236L183,236L186,235L188,230L187,225L180,219L157,208L156,208L155,206L151,204L148,192L144,183L140,179L130,172L133,164L132,152L129,140L121,121L129,117L133,114L137,107L138,103L136,97L134,93L129,90L122,89L124,79L123,73L121,69L115,63L108,60L97,57L91,57L80,60L69,64Z\",\"e\":[92,68,3],\"v\":\"0 0 200 240\"},\"23-blob-texture-bodies--honeycomb_humanoid_3d_model\":{\"d\":\"M82,34L71,40L63,47L56,55L52,66L50,77L51,89L54,98L61,110L61,113L62,113L62,116L60,118L50,123L48,125L42,128L36,133L22,150L16,158L13,166L12,176L26,176L27,173L32,172L35,177L39,177L42,172L41,166L43,161L50,154L55,151L51,161L50,168L55,207L53,214L44,225L43,230L43,235L52,236L85,236L86,235L88,232L89,214L92,203L94,201L103,200L106,201L109,206L112,217L112,229L114,236L156,236L157,232L157,228L149,218L146,211L145,201L148,184L149,167L145,150L152,155L158,164L158,174L160,177L165,177L167,172L172,173L174,176L188,176L188,169L186,162L177,148L162,132L153,124L140,119L138,116L138,113L146,97L150,83L149,72L147,63L143,55L139,49L133,43L117,34L111,32L98,31Z\",\"e\":[100,72,9],\"v\":\"0 0 200 240\"},\"23-blob-texture-bodies--patchwork_plush_figure_3d_model\":{\"d\":\"M95,16L84,20L81,21L74,27L69,35L66,44L65,54L66,58L72,70L77,76L79,77L77,79L70,82L57,93L46,112L45,114L43,117L35,140L35,147L33,156L34,164L38,171L43,173L48,172L48,164L50,163L49,160L50,159L51,162L54,164L56,164L58,162L58,156L56,149L66,122L65,130L65,145L61,162L59,184L58,192L57,210L55,214L53,216L48,224L49,232L53,234L73,234L83,234L86,232L88,227L87,214L90,189L95,169L105,169L110,188L110,198L113,212L113,226L114,232L117,233L137,234L140,236L141,236L138,234L149,234L152,232L153,227L153,223L151,219L145,213L143,208L139,162L136,147L136,136L135,125L139,132L139,134L145,150L142,155L142,160L143,163L145,164L149,162L150,159L151,160L152,172L157,173L160,172L165,168L167,162L166,144L160,123L151,104L147,99L147,98L139,88L122,77L131,66L134,57L135,46L134,40L130,33L124,25L114,19L106,16Z\",\"e\":[100,46,9],\"v\":\"0 0 200 240\"},\"23-blob-texture-bodies--sand_creature_3d_model\":{\"d\":\"M119,60L106,56L92,56L83,59L76,62L65,70L60,76L54,91L52,102L52,121L50,127L48,132L34,144L25,155L17,169L13,178L12,185L14,189L18,190L20,189L21,191L24,192L28,192L31,189L32,184L35,187L39,188L41,187L43,182L42,175L44,169L46,168L46,185L48,192L52,201L53,212L52,218L49,225L49,228L50,232L54,235L63,236L74,236L83,233L86,229L87,216L88,214L90,212L111,212L114,216L115,230L118,234L123,235L141,236L146,235L149,232L151,228L151,224L147,216L147,208L154,186L154,168L156,169L158,175L157,182L158,186L161,188L164,188L168,184L170,190L172,192L175,192L179,191L180,189L184,190L188,186L188,181L184,171L175,156L168,146L154,133L150,128L148,124L147,96L144,85L140,78L134,70L128,65Z\",\"e\":[102,67,3],\"v\":\"0 0 200 240\"}};\r\nexport const COLOURS={\"default-slate\":\"#8b8f9a\",\"default-clay\":\"#b7a68e\",\"default-ruby\":\"#a23b4a\",\"default-sapphire\":\"#2d5aa0\",\"default-moss\":\"#4c7a3f\",\"default-gold\":\"#c9a13a\",\"default-charcoal\":\"#333238\",\"default-blush\":\"#d98fa0\",\"legacy-color-0\":\"#7946aa\",\"legacy-color-1\":\"#3f7448\",\"legacy-color-2\":\"#d5c7ae\",\"legacy-color-3\":\"#4f263d\",\"legacy-color-4\":\"#5f7a3f\",\"legacy-color-5\":\"#132a42\",\"legacy-color-6\":\"#e46867\",\"legacy-color-7\":\"#d8d0af\",\"legacy-color-8\":\"#8ed9cd\",\"legacy-color-9\":\"#7b211e\",\"legacy-color-10\":\"#e6dca4\",\"legacy-color-11\":\"#16101f\",\"legacy-color-12\":\"#6b426c\",\"legacy-color-13\":\"#6f7068\",\"legacy-color-14\":\"#896bc2\",\"legacy-color-15\":\"#4a1713\",\"legacy-color-16\":\"#93c9df\",\"legacy-color-17\":\"#48536e\",\"legacy-color-18\":\"#9a6a37\",\"legacy-color-19\":\"#251d54\",\"legacy-color-20\":\"#d6a987\",\"legacy-color-21\":\"#a7ec69\",\"legacy-color-22\":\"#efb398\",\"pal-01\":\"#C6FF00\",\"pal-02\":\"#FF6D00\",\"pal-03\":\"#0E5A61\",\"pal-04\":\"#8A3B12\",\"pal-05\":\"#FF009F\",\"pal-06\":\"#13E7D1\",\"pal-07\":\"#B5C700\",\"pal-08\":\"#FFB000\",\"pal-09\":\"#A6FF00\",\"pal-10\":\"#AEB6BC\",\"pal-11\":\"#7B2FF7\",\"pal-12\":\"#FA2200\",\"pal-13\":\"#8C6A2F\",\"pal-14\":\"#FF00AA\",\"pal-15\":\"#A0342B\",\"pal-16\":\"#046A5B\",\"pal-17\":\"#B8C0C2\",\"pal-18\":\"#D9A404\",\"pal-19\":\"#FF1744\",\"pal-20\":\"#13E7B9\",\"pal-21\":\"#9C4221\",\"pal-22\":\"#F5E900\",\"pal-23\":\"#8CFF00\",\"pal-24\":\"#B91338\",\"pal-25\":\"#C59B42\",\"pal-26\":\"#FF0000\",\"pal-27\":\"#D6F0F0\",\"pal-28\":\"#3F7A3A\",\"pal-29\":\"#F2F2F0\",\"pal-30\":\"#FFD300\",\"pal-31\":\"#FFEA00\",\"pal-32\":\"#8D9096\",\"pal-33\":\"#C6FF00\",\"pal-34\":\"#B46A30\",\"pal-35\":\"#00E5FF\",\"pal-36\":\"#EDE8DC\",\"pal-37\":\"#4A1E4F\",\"pal-38\":\"#BFFF00\",\"pal-39\":\"#C06B55\",\"pal-40\":\"#F4EDDE\",\"pal-41\":\"#191970\",\"pal-42\":\"#A27E8E\",\"pal-43\":\"#FF9100\",\"pal-44\":\"#4F7942\",\"pal-45\":\"#7D7F87\",\"pal-46\":\"#D32E12\",\"pal-47\":\"#139FE7\",\"pal-48\":\"#00FFC6\",\"pal-49\":\"#00FF9D\",\"pal-50\":\"#9BA0A6\",\"pal-51\":\"#B22234\",\"pal-52\":\"#13A6E7\",\"pal-53\":\"#3A7D7B\",\"pal-54\":\"#635147\",\"pal-55\":\"#E7134B\",\"pal-56\":\"#E3D200\",\"pal-57\":\"#FF5E00\",\"pal-58\":\"#FFA12B\",\"pal-59\":\"#8A8F98\",\"pal-60\":\"#1E2A4A\",\"pal-61\":\"#F28500\",\"pal-62\":\"#9AB5A1\",\"pal-63\":\"#1D8A7A\",\"pal-64\":\"#701F3C\",\"pal-65\":\"#2E3033\",\"pal-66\":\"#39FF14\",\"pal-67\":\"#8A3324\",\"pal-68\":\"#1399E7\",\"pal-69\":\"#E79813\",\"pal-70\":\"#6A2D9E\",\"pal-71\":\"#A89B6E\",\"pal-72\":\"#00F5D4\",\"pal-73\":\"#7A4532\",\"pal-74\":\"#13AAE7\",\"pal-75\":\"#5B7042\",\"pal-76\":\"#99A0A8\",\"pal-77\":\"#00F0FF\",\"pal-78\":\"#3A2618\",\"pal-79\":\"#1325E7\",\"pal-80\":\"#57A78A\",\"pal-81\":\"#8C00FF\",\"pal-82\":\"#00FFFF\",\"pal-83\":\"#F0EEE4\",\"pal-84\":\"#FF073A\",\"pal-85\":\"#6D1E2E\",\"pal-86\":\"#C3C9D1\",\"pal-87\":\"#B09A6E\",\"pal-88\":\"#004DFF\",\"pal-89\":\"#23493C\",\"pal-90\":\"#9813E7\",\"pal-91\":\"#F0B429\",\"pal-92\":\"#574B6B\",\"pal-93\":\"#0F7B7B\",\"pal-94\":\"#E63362\",\"pal-95\":\"#23232A\",\"pal-96\":\"#F5F1E8\",\"pal-97\":\"#9FBF3B\",\"pal-98\":\"#41284E\",\"pal-99\":\"#8F8A82\",\"pal-100\":\"#FFEF00\",\"pal-101\":\"#E9F2F5\",\"pal-102\":\"#D8117E\",\"pal-103\":\"#8467B8\",\"pal-104\":\"#00FF66\",\"pal-105\":\"#FF2E00\",\"pal-106\":\"#C9AE7E\",\"pal-107\":\"#523090\",\"opal-jelly\":\"#b3fff0\",\"bubble-glass\":\"#58eaff\",\"prism-crystal\":\"#b18aff\",\"holo-foil\":\"#ff54de\",\"glitter-resin\":\"#ff319c\",\"galaxy-geode\":\"#21134e\",\"caustic-slime\":\"#8aa52b\",\"blister-hide\":\"#9e435f\",\"rotten-rind\":\"#626124\",\"parasite-nest\":\"#786541\",\"exposed-sinew\":\"#b72945\",\"abyssal-maw\":\"#522045\",\"circuit-alloy\":\"#273f50\",\"servo-armor\":\"#617080\",\"chrome-rib\":\"#bfcde1\",\"carbon-mech\":\"#323d46\",\"hazard-panel\":\"#edb932\",\"reactor-glass\":\"#48e8ff\"};\r\nexport const LEGACY=[\"#7946aa\",\"#3f7448\",\"#d5c7ae\",\"#4f263d\",\"#5f7a3f\",\"#132a42\",\"#e46867\",\"#d8d0af\",\"#8ed9cd\",\"#7b211e\",\"#e6dca4\",\"#16101f\",\"#6b426c\",\"#6f7068\",\"#896bc2\",\"#4a1713\",\"#93c9df\",\"#48536e\",\"#9a6a37\",\"#251d54\",\"#d6a987\",\"#a7ec69\",\"#efb398\"];\r\n","arcade/pyramid-jump/game.mjs":"// Pyramid Jump: classic Doodle-Jump on 2D paper, 20 levels from the office to MOM's mothership desk (see LEVELS in logic.mjs).\r\n// Lazy/optional (arcade/ is never core). World y points up (feet = y); the camera only scrolls up; falling below the view ends the run.\r\nimport {W,BEST_KEY,PLAT_W,JUMP,GRAVITY,Level,mulberry,mealMarkers,markerHeight,paperFor,LEVELS,LEVEL_H,LEVEL_COUNT,END_Y,levelAt,highestLevel,saveLevel,newlyReachedQuestLevel,steeringForMotion} from './logic.mjs';\r\nimport {performanceOwner} from '../../performance-progress.mjs';\r\nimport {createQuestProgressReporter} from '../quest-progress-reporter.mjs';\r\nconst PW=40,PH=50;\r\nconst hash=n=>{const x=Math.sin(n*127.1)*43758.5453;return x-Math.floor(x);};\r\nexport const bestScore=(store=localStorage)=>{try{const n=JSON.parse(store.getItem(BEST_KEY));return Number.isSafeInteger(n)&&n>0?n:0;}catch{return 0;}};\r\nconst SHADOW='#49334b66',EDGE='#624848';\r\nconst SLOGANS=[['CARED FOR.','CORRECTED.','PROVIDED FOR.'],['SMILE.','REP.','REPEAT.'],['READ THE','SOURCE.'],['ASK MOM.'],['KEEP THE','LABEL.'],['MOM IS','PROUD.'],['EAT. LIFT.','REPORT.'],['FITNESS IS','A FAMILY.']];\r\nconst POSTER=['#e5d4a2','#e0c3ea','#f2c6a0','#bfdcc6','#f0e08a'],QUILT=['#c8587a','#e0a050','#5a9ac8','#7ab86a','#a070c0','#e8d070'],ORIGAMI=['#f4a0b4','#a0d4f4','#f4e090','#b0e0a8','#d0b0f0'];\r\n\r\nexport function startGame(root,{recipe=null,meals=null,subscribeMotion=null,onExit=()=>{},seed=Date.now(),startLevel=0,auto=false}={}){\r\n const canvas=document.createElement('canvas'),ctx=canvas.getContext('2d');canvas.style.cssText='position:absolute;inset:0;width:100%;height:100%;touch-action:none;display:block';\r\n canvas.setAttribute('role','img');canvas.setAttribute('aria-label','Pyramid Jump. Tilt or touch the left and right sides to steer.');\r\n const over=document.createElement('div');over.style.cssText='position:absolute;inset:0;display:none;place-content:center;gap:12px;text-align:center;background:#0009;color:#fff4dc;font:800 18px/1.4 system-ui,sans-serif;letter-spacing:.05em;white-space:pre-line';\r\n const btn=(t,f)=>{const b=document.createElement('button');b.type='button';b.textContent=t;b.style.cssText='min-height:44px;padding:0 18px;border:2px solid #fff9;border-radius:999px;background:#1d1428;color:#fff4dc;font:700 14px system-ui,sans-serif;pointer-events:auto';b.onclick=f;return b;};\r\n const msg=document.createElement('div'),row=document.createElement('div');row.style.cssText='display:flex;flex-wrap:wrap;gap:10px;justify-content:center';\r\n const exit=btn('EXIT',()=>onExit());exit.style.cssText+=';position:absolute;top:max(10px,env(safe-area-inset-top));right:10px;min-height:44px;min-width:44px';exit.setAttribute('aria-label','Exit to the pyramid');\r\n over.append(msg,row);root.append(canvas,exit,over);\r\n const art=paperFor(recipe),shape=new Path2D(art.d),tags=mealMarkers(meals);\r\n let lvl,p,camY,maxY,best=bestScore(),t=0,dir=0,tilt=0,tiltAt=-9,raf=0,last=0,dead=true,disposed=false,scale=1,viewH=640,plus=0,cur=0,banner=null,won=false,runOwner=null,reportQuest=null;\r\n const showOver=(text,...btns)=>{msg.textContent=text;row.replaceChildren(...btns);over.style.display='grid';};\r\n function begin(from){ // from = 1-based level to start on (1 = the office desk)\r\n  runOwner=performanceOwner();\r\n  reportQuest=createQuestProgressReporter(runOwner);\r\n  lvl=new Level(mulberry(seed++),plus);p={x:W/2,y:0,vx:0,vy:JUMP,fly:0,flyV:0,gear:null,face:1};camY=-90;maxY=0;dead=false;won=false;over.style.display='none';\r\n  if(from>1){const y0=(from-1)*LEVEL_H+20;lvl.ensure(y0+300);const it=lvl.items.find(i=>i.type==='static'&&!i.blink&&i.y>=y0);p.x=it.x+PLAT_W/2;p.y=it.y;camY=p.y-viewH*.45;maxY=p.y;}\r\n  lvl.ensure(camY+viewH*2);for(const i of lvl.items)Object.assign(i,{broken:false,by:0});cur=Math.max(0,Math.min(LEVEL_COUNT-1,from-1));\r\n }\r\n const menu=()=>{const hi=highestLevel(),b=[btn(hi>1?'NEW CLIMB':'START',()=>begin(1))];if(hi>1)b.unshift(btn(`CONTINUE FROM LEVEL ${hi}`,()=>begin(hi)));b.push(btn('EXIT',()=>onExit()));return b;};\r\n function resize(){const r=canvas.getBoundingClientRect(),d=Math.min(devicePixelRatio||1,2);canvas.width=Math.max(1,r.width*d);canvas.height=Math.max(1,r.height*d);scale=canvas.width/W;viewH=canvas.height/scale;}\r\n const ro=new ResizeObserver(resize);ro.observe(canvas);resize();\r\n if(startLevel)begin(startLevel);else if(auto)begin(Math.max(1,highestLevel()));else if(highestLevel()>1)showOver(`PYRAMID JUMP\\nREACHED LEVEL ${highestLevel()} OF ${LEVEL_COUNT}`,...menu());else begin(1);\r\n const unsub=subscribeMotion?.(sample=>{tilt=steeringForMotion(sample);tiltAt=t;});\r\n const key=down=>e=>{const k=e.key;if(k==='ArrowLeft'||k==='a')dir=down?-1:dir<0?0:dir;else if(k==='ArrowRight'||k==='d')dir=down?1:dir>0?0:dir;};\r\n const kd=key(true),ku=key(false);addEventListener('keydown',kd);addEventListener('keyup',ku);\r\n const pd=e=>{if(e.target!==canvas)return;const r=canvas.getBoundingClientRect();dir=e.clientX<r.left+r.width/2?-1:1;},pu=()=>{dir=0;};\r\n canvas.addEventListener('pointerdown',pd);addEventListener('pointerup',pu);addEventListener('pointercancel',pu);\r\n const px=it=>it.type==='moving'?Math.max(0,Math.min(W-PLAT_W,it.x+Math.sin(t*1.6+it.phase)*it.dx)):it.x;\r\n const solid=it=>!it.blink||Math.sin(t*6.28/it.blink+it.phase)>-.3; // origami / star platforms fold away on a timer\r\n function die(why){if(dead)return;dead=true;const s=Math.floor(maxY/10);if(s>best){best=s;try{localStorage.setItem(BEST_KEY,String(best));}catch{/* ignore */}}\r\n  showOver(`${why}\\nLEVEL ${cur+1} · HEIGHT ${s}\\nBEST ${best}${s>=best&&s>0?'  NEW BEST!':''}`,...menu());}\r\n function win(){dead=won=true;saveLevel(LEVEL_COUNT);reportQuest?.record('pyramid-complete',1);showOver(`LEVEL ${LEVEL_COUNT} COMPLETE\\nYou ate your way to MOM.`,btn('NEW GAME+',()=>{plus++;begin(1);}),btn('EXIT',()=>onExit()));}\r\n function step(dt){\r\n  t+=dt;if(dead)return;\r\n  const L=levelAt(p.y),steer=dir||(t-tiltAt<.5?tilt:0);p.vx=steer*340;if(steer)p.face=steer>0?1:-1;\r\n  const prev=p.y;p.x+=p.vx*dt;if(p.x<-PW/2)p.x+=W+PW;else if(p.x>W+PW/2)p.x-=W+PW;\r\n  if(p.fly>0){p.fly-=dt;p.vy=p.flyV;if(p.fly<=0)p.vy=JUMP*.6;}else p.vy-=GRAVITY*(L===8?.7:1)*dt; // moon cafeteria: floatier\r\n  p.y+=p.vy*dt;lvl.ensure(camY+viewH*2);\r\n  for(const it of lvl.items){\r\n   if(it.broken){it.by-=420*dt;continue;}\r\n   if(it.type==='monster'){it.x+=it.dir*50*dt;if(it.x<0||it.x>W-50)it.dir*=-1;const dx=Math.abs(p.x-(it.x+25)),dy=p.y+PH/2-(it.y+16);\r\n    if(dx<PW/2+18&&Math.abs(dy)<PH/2+14){if(p.fly>0||(p.vy<0&&prev>it.y+14)){it.broken=true;p.vy=JUMP;p.fly=0;}else die('BONKED');}continue;}\r\n   if(it.type==='hole'){if(Math.hypot(p.x-(it.x+30),p.y+PH/2-(it.y+30))<30)die('SUCKED IN');continue;}\r\n   const x=it.type==='desk'?0:px(it),pw=it.type==='desk'?W:PLAT_W,near=Math.abs(p.x-(x+pw/2))<pw/2+PW/3;\r\n   if(it.gear&&p.fly<=0&&near&&Math.abs(p.y-(it.y+14))<26){p.fly=it.gear==='jetpack'?4:2.5;p.flyV=it.gear==='jetpack'?900:560;p.gear=it.gear;it.gear=null;}\r\n   if(p.vy<0&&p.fly<=0&&near&&prev>=it.y-2&&p.y<=it.y&&solid(it)){\r\n    if(it.type==='desk'){p.y=it.y;win();return;}\r\n    if(it.type==='breaking'){it.broken=true;continue;}\r\n    p.y=it.y;p.vy=it.type==='spring'?JUMP*1.55:JUMP;\r\n   }\r\n  }\r\n  maxY=Math.max(maxY,p.y);camY=Math.max(camY,p.y-viewH*.45);\r\n  const nl=levelAt(maxY);if(nl!==cur){const crossed=newlyReachedQuestLevel(cur,nl);cur=nl;banner={t,text:`LEVEL ${nl+1} · ${LEVELS[nl].name}`};saveLevel(nl+1);if(crossed)reportQuest?.record('pyramid-level',crossed);}\r\n  lvl.items=lvl.items.filter(i=>(i.y+(i.by||0))>camY-200);\r\n  if(p.y+PH<camY)die('FELL');\r\n }\r\n const sy=wy=>(viewH-(wy-camY))*scale,sx=x=>x*scale;\r\n // ---- Paper toolkit (the Dr. Girlfriend look): cut edges, hard offset shadow, grain, slight tilt.\r\n const grain=(()=>{const c=document.createElement('canvas');c.width=c.height=96;const g=c.getContext('2d'),d=g.createImageData(96,96);for(let i=0;i<d.data.length;i+=4){d.data[i]=d.data[i+1]=d.data[i+2]=hash(i)*255;d.data[i+3]=30;}g.putImageData(d,0,0);return c;})();\r\n let grainPat=null,flat=false;\r\n function cut(w,h,seed,j=1.3){ // slightly uneven scissor-cut rectangle centred on the origin\r\n  const p=new Path2D(),n=Math.max(2,Math.round(w/(20*scale))),J=i=>flat?0:(hash(seed*7+i)-.5)*2*j*scale,pts=[];\r\n  for(let i=0;i<=n;i++)pts.push([-w/2+w*i/n+J(i),-h/2+J(i+50)]);\r\n  pts.push([w/2+J(90),J(91)]);\r\n  for(let i=n;i>=0;i--)pts.push([-w/2+w*i/n+J(i+100),h/2+J(i+150)]);\r\n  pts.push([-w/2+J(190),J(191)]);\r\n  pts.forEach(([x,y],i)=>i?p.lineTo(x,y):p.moveTo(x,y));p.closePath();return p;\r\n }\r\n function sheet(cx,cy,w,h,fill,rot=0,seed=1,inner=null,{edge=EDGE,shadow=3,alpha=1}={}){\r\n  ctx.save();ctx.translate(cx,cy);ctx.rotate(rot);const path=cut(w,h,seed);\r\n  ctx.globalAlpha*=alpha;\r\n  if(flat){ctx.fillStyle='#fff';ctx.fill(path);ctx.strokeStyle='#000';ctx.lineWidth=2*scale;ctx.stroke(path);inner?.();ctx.restore();return;} // Flatland: lines only\r\n  ctx.save();ctx.translate(shadow*scale,shadow*scale);ctx.fillStyle=SHADOW;ctx.fill(path);ctx.restore();\r\n  ctx.fillStyle=fill;ctx.fill(path);grainPat??=ctx.createPattern(grain,'repeat');ctx.fillStyle=grainPat;ctx.fill(path);\r\n  ctx.strokeStyle=edge;ctx.lineWidth=1.6*scale;ctx.stroke(path);inner?.();ctx.restore();\r\n }\r\n const tape=(x,y,r)=>{ctx.save();ctx.translate(x,y);ctx.rotate(r);ctx.fillStyle='#e8cf7acc';ctx.fillRect(-9*scale,-3.5*scale,18*scale,7*scale);ctx.strokeStyle='#b89e4a88';ctx.lineWidth=scale;ctx.strokeRect(-9*scale,-3.5*scale,18*scale,7*scale);ctx.restore();};\r\n const text=(t,x,y,size,color,font='Georgia,serif',weight=700)=>{ctx.fillStyle=color;ctx.font=`${weight} ${size*scale}px ${font}`;ctx.textAlign='center';ctx.fillText(t,x,y);};\r\n const ly=(wy,f=1)=>(viewH-(wy-camY*f))*scale; // screen y of a point on a parallax layer\r\n const diamond=(x,y,r,c)=>{ctx.fillStyle=c;ctx.beginPath();ctx.moveTo(x,y-r);ctx.lineTo(x+r*.45,y);ctx.lineTo(x,y+r);ctx.lineTo(x-r*.45,y);ctx.closePath();ctx.fill();};\r\n const blob=(cx,cy,r,seed,c,a=1)=>{ctx.save();ctx.globalAlpha*=a;ctx.translate(cx,cy);const p=new Path2D(),n=14;for(let i=0;i<n;i++){const t=i/n*6.283,k=r*(.8+hash(seed+i)*.35);i?p.lineTo(Math.cos(t)*k,Math.sin(t)*k):p.moveTo(k,0);}p.closePath();ctx.fillStyle=c;ctx.fill(p);ctx.strokeStyle=EDGE;ctx.lineWidth=scale;ctx.globalAlpha*=.5;ctx.stroke(p);ctx.restore();};\r\n const rows=(f,step,fn)=>{for(let b=Math.floor(camY*f/step)-1;b<(camY*f+viewH)/step+1;b++)fn(b,ly(b*step+hash(b)*step*.6,f),sx(hash(b+5)*W));};\r\n const stars=(f=.3,c='255,244,210')=>rows(f,60,(b,y)=>{for(let k=0;k<2;k++)diamond(sx(hash(b*3+k)*W),y+k*sx(20),(1.5+hash(b+k)*2.5)*scale,`rgba(${c},.9)`);});\r\n function poster(cx,cy,w,h,b){\r\n  const L=SLOGANS[b%SLOGANS.length];\r\n  sheet(cx,cy,w,h,POSTER[b%POSTER.length],(hash(b+9)-.5)*.12,b,()=>{\r\n   text('MOM INC.',0,-h/2+13*scale,8,'#4c3255');\r\n   ctx.fillStyle='#79558a';ctx.beginPath();ctx.arc(0,-h/2+32*scale,9*scale,0,7);ctx.fill();diamond(0,-h/2+32*scale,8*scale,'#f4e7a0');\r\n   L.forEach((l,i)=>text(l,0,-h/2+54*scale+i*13*scale,l.length>9?9:11,'#3a2548'));\r\n   text('A MOM INC. WORKPLACE',0,h/2-6*scale,5,'#6d5a7c','monospace',400);tape(-w/2+8*scale,-h/2+2*scale,-.5);tape(w/2-8*scale,-h/2+2*scale,.5);});\r\n }\r\n const wallpaper=()=>{ctx.fillStyle='#ffffff14';for(let x=0;x<W;x+=48)ctx.fillRect(sx(x),0,sx(14),canvas.height);ctx.fillStyle='#00000010';for(let wy=Math.floor(camY/80)*80;wy<camY+viewH;wy+=80)ctx.fillRect(0,ly(wy),canvas.width,2*scale);\r\n  grainPat??=ctx.createPattern(grain,'repeat');ctx.fillStyle=grainPat;ctx.fillRect(0,0,canvas.width,canvas.height);ctx.fillStyle='#665044';ctx.fillRect(0,0,sx(10),canvas.height);ctx.fillRect(sx(W-10),0,sx(10),canvas.height);};\r\n function pyramidDesk(by,k=1){ // the desk with the paper food pyramid (the same one that sat in the pyramid scene)\r\n  const px0=sx(W/2),py0=ly(by-4);\r\n  sheet(px0,ly(by-18),sx(300*k),sx(34),'#8a5f3c',0,6);sheet(px0,ly(by-50),sx(280*k),sx(10),'#a9774c',0,7);\r\n  for(let i=0;i<3;i++)sheet(px0,py0-sx(17)-i*sx(32*k),sx((150-i*45)*k),sx(34*k),['#cdbb8a','#d9c590','#e8d28a'][i],0,20+i);\r\n  for(const [dx,dy,c] of [[-30,-16,'#7fcf5a'],[0,-16,'#f4d35e'],[30,-16,'#4fd1c5'],[-14,-48,'#f4978e'],[14,-48,'#c9a7eb']])sheet(px0+sx(dx*k),py0+sx(dy*k),sx(22*k),sx(18*k),c,0,Math.round(dx+dy),null,{shadow:1});\r\n  sheet(px0,py0-sx(100*k),sx(30*k),sx(14*k),'#2d2a4e',0,8,()=>text('FOOD',0,sx(3),6,'#f4e7a0','monospace'));\r\n }\r\n function office(by){ // the small office: floor, window, filing cabinets, desk + pyramid, the wall poster and note\r\n  ctx.fillStyle='#6a5240';ctx.fillRect(0,ly(by-40),canvas.width,canvas.height);ctx.fillStyle='#00000022';for(let x=0;x<W;x+=40)ctx.fillRect(sx(x),ly(by-40),scale*2,canvas.height);\r\n  sheet(sx(250),ly(by+150),sx(70),sx(90),'#bfe3ee',0,3,()=>{ctx.strokeStyle=EDGE;ctx.beginPath();ctx.moveTo(0,-sx(45));ctx.lineTo(0,sx(45));ctx.moveTo(-sx(35),0);ctx.lineTo(sx(35),0);ctx.stroke();});\r\n  sheet(sx(36),ly(by+60),sx(46),sx(100),'#8c8f98',0,4,()=>{for(let i=0;i<3;i++){ctx.strokeStyle=EDGE;ctx.strokeRect(-sx(18),-sx(40)+i*sx(30),sx(36),sx(26));}});\r\n  sheet(sx(86),ly(by+40),sx(46),sx(80),'#9a9da6',0,5);pyramidDesk(by);\r\n  poster(sx(60),ly(by+250),sx(96),sx(104),0);\r\n  sheet(sx(250),ly(by+260),sx(86),sx(54),'#dbc68a',.05,9,()=>{text('READ THE SOURCE.',0,-sx(4),6.5,'#463149','monospace',400);text('KEEP THE LABEL.',0,sx(8),6.5,'#463149','monospace',400);});\r\n  sheet(sx(300),ly(by+420),sx(40),sx(100),'#7b5a3a',0,11,()=>text('VENT',0,0,6,'#f4e7a0','monospace')); // the bookshelf into the ceiling vent\r\n }\r\n // One scene per level, drawn inside that level's band (clipped), over its sky gradient.\r\n const SCENES=[\r\n  ()=>{wallpaper();office(0);},\r\n  ()=>{rows(1,130,(b,y)=>{sheet(sx(W/2),y,sx(W-24),sx(30),'#9aa0ae',0,b,()=>{for(let i=0;i<9;i++){ctx.fillStyle='#6a6f7c';ctx.beginPath();ctx.arc(-sx(W/2-30)+i*sx(36),0,sx(2),0,7);ctx.fill();}});\r\n   if(b%3===0){ctx.save();ctx.translate(sx(40+hash(b)*280),y-sx(40));ctx.rotate(t*5);for(let i=0;i<4;i++){ctx.rotate(1.57);sheet(0,-sx(14),sx(8),sx(26),'#d0d4de',0,b+i,null,{shadow:1});}ctx.restore();}});},\r\n  ()=>{wallpaper();rows(1,230,(b,y,x)=>{const w=sx(70+hash(b+1)*40);poster(sx(30+hash(b)*(W-60)),y,w,w*1.2,b);});},\r\n  ()=>{rows(.8,150,(b,y,x)=>{const w=sx(50+hash(b)*40),h=sx(120+hash(b+2)*100);sheet(x,y+h/2-sx(60),w,h,'#5a5a78',0,b,()=>{for(let i=0;i<6;i++)for(let k=0;k<3;k++){ctx.fillStyle=hash(b*9+i*3+k)<.5?'#ffd66a':'#3a3a58';ctx.fillRect(-w/2+sx(7)+k*w/3.4,-h/2+sx(10)+i*sx(18),sx(8),sx(9));}});\r\n   if(b%5===0)sheet(sx(W/2),y-sx(100),sx(180),sx(70),'#e45a8a',0,b+1,()=>{text('MOM',0,sx(10),30,'#fff4dc');text('LOVES YOU',0,sx(24),8,'#fff4dc','monospace');});\r\n   if(b%3===1){ctx.strokeStyle='#2a2a3e';ctx.lineWidth=2*scale;ctx.beginPath();ctx.moveTo(x,y-sx(60));ctx.lineTo(x,y-sx(110));ctx.stroke();}});},\r\n  ()=>{rows(.5,150,(b,y,x)=>{for(let k=0;k<3;k++)blob(x+sx(k*34-30),y+sx(k%2*10),sx(30+hash(b+k)*12),b+k,'#fbfaf5',.95);\r\n   if(b%9===0)sheet(sx(W/2),y,sx(140),sx(46),'#e45a8a',0,b,()=>text('MOM',0,sx(5),16,'#fff4dc'));\r\n   if(b%4===2){ctx.strokeStyle='#fff';ctx.lineWidth=scale;ctx.beginPath();ctx.moveTo(x,y);ctx.lineTo(x,y+sx(40));ctx.stroke();ctx.fillStyle='#e0504a';ctx.beginPath();ctx.arc(x,y,sx(12),0,7);ctx.fill();}});},\r\n  ()=>{stars();sheet(sx(W/2),sx(viewH/2),sx(10),canvas.height*1.1,'#c9c6d2',0,3,()=>{ctx.strokeStyle=EDGE;for(let wy=Math.floor(camY/60)*60;wy<camY+viewH+60;wy+=60){ctx.beginPath();ctx.moveTo(-sx(5),ly(wy)-sx(viewH/2));ctx.lineTo(sx(5),ly(wy)-sx(viewH/2));ctx.stroke();}});\r\n   rows(1,300,(b,y,x)=>sheet(hash(b)<.5?sx(70):sx(W-70),y,sx(50),sx(36),'#8a8fa8',0,b,()=>{ctx.fillStyle='#ffd66a';ctx.fillRect(-sx(6),-sx(6),sx(12),sx(10));}));},\r\n  ()=>{stars(.3);rows(.7,110,(b,y,x)=>sheet(x,y,sx(14+hash(b)*22),sx(8+hash(b+1)*10),'#8a8fa0',hash(b)*3,b,null,{shadow:2}));\r\n   rows(1,330,(b,y)=>{ctx.save();ctx.strokeStyle='#fffbe8';ctx.lineWidth=5*scale;ctx.shadowColor='#fff';ctx.shadowBlur=12*scale;ctx.beginPath();ctx.moveTo(0,y);for(let i=1;i<=9;i++)ctx.lineTo(sx(i*W/9),y+(hash(b*9+i)-.5)*sx(26));ctx.stroke();ctx.restore();});},\r\n  ()=>{stars();rows(.6,380,(b,y)=>{const left=hash(b+3)<.5,x=left?sx(70):sx(W-70),w=sx(120+hash(b)*70),hh=sx(52+hash(b+1)*30);\r\n   sheet(x,y,w,hh,'#5d5a8c',(hash(b+6)-.5)*.05,b,()=>{for(let i=0;i<5;i++){ctx.fillStyle='#ffd66a';ctx.fillRect(-w/2+sx(12+i*26),sx(6),sx(8),sx(8));}ctx.fillStyle='#8b86c4';ctx.fillRect(-w/2,-hh/2,w,sx(8));});\r\n   sheet(x+(left?w/2+sx(24):-w/2-sx(24)),y,sx(48),sx(7),'#9fd4e6',0,b+1,null,{shadow:2});sheet(x+(left?w/2+sx(60):-w/2-sx(60)),y-sx(10),sx(16),sx(12),'#e8e0d0',.3,b+2,null,{shadow:2});\r\n   if(b%2===0)sheet(x,y-hh/2-sx(10),sx(86),sx(14),'#2d2a4e',0,b+3,()=>text('MOM PORT 18',0,sx(3),7,'#ffd66a','monospace'),{shadow:2});});},\r\n  ()=>{blob(sx(W/2),ly(8700),sx(60),4,'#3b78c4');rows(1,260,(b,y,x)=>{sheet(x,y,sx(90),sx(12),'#c9c6d2',0,b,()=>{sheet(0,-sx(12),sx(24),sx(16),'#cdbb8a',0,b+3,null,{shadow:1});},{shadow:2});sheet(x,y+sx(26),sx(80),sx(8),'#8a5f3c',0,b+1,null,{shadow:2});});},\r\n  ()=>{rows(1,120,(b,y)=>sheet(sx(W/2),y,sx(W),sx(60),b%2?'#e9d8ee':'#c7b0dc',0,b,null,{alpha:.7,shadow:0}));ctx.fillStyle='#00000026';ctx.fillRect(0,0,sx(W/2),canvas.height);\r\n   ctx.fillStyle='#00000055';ctx.fillRect(sx(W/2)-scale,0,2*scale,canvas.height);ctx.save();ctx.globalCompositeOperation='difference';ctx.fillStyle='#e8e8e8';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.restore();},\r\n  ()=>{for(let r=Math.floor(camY/60);r<(camY+viewH)/60+1;r++)for(let c=0;c<7;c++){const x=sx(c*60+30),y=ly(r*60+30),k=hash(r*7+c);ctx.fillStyle=ORIGAMI[(r+c)%5];ctx.beginPath();if(k<.5){ctx.moveTo(x-sx(30),y-sx(30));ctx.lineTo(x+sx(30),y-sx(30));ctx.lineTo(x-sx(30),y+sx(30));}else{ctx.moveTo(x+sx(30),y+sx(30));ctx.lineTo(x+sx(30),y-sx(30));ctx.lineTo(x-sx(30),y+sx(30));}ctx.closePath();ctx.fill();ctx.strokeStyle='#ffffff88';ctx.stroke();}},\r\n  ()=>{stars();rows(.6,120,(b,y,x)=>{if(b%2)blob(x,y,sx(12+hash(b)*14),b,'#6a6478');else{ctx.strokeStyle='#14101c';ctx.lineWidth=4*scale;ctx.beginPath();ctx.arc(x,y,sx(9),0,7);ctx.stroke();ctx.fillStyle='#3a3548';ctx.beginPath();ctx.arc(x,y+sx(3),sx(8),0,7);ctx.fill();}});},\r\n  ()=>{rows(.4,80,(b,y)=>{ctx.strokeStyle=b%2?'#7fe6ff':'#d070ff';ctx.lineWidth=4*scale;ctx.beginPath();ctx.ellipse(sx(W/2),y,sx(150+(b%4)*8),sx(50),0,0,7);ctx.stroke();});\r\n   ctx.strokeStyle='#ffffff22';for(let i=0;i<9;i++){ctx.beginPath();ctx.moveTo(sx(W/2),sx(viewH/2));ctx.lineTo(sx(i*W/8),0);ctx.moveTo(sx(W/2),sx(viewH/2));ctx.lineTo(sx(i*W/8),canvas.height);ctx.stroke();}},\r\n  ()=>{ctx.strokeStyle='#000';ctx.lineWidth=scale;for(let x=0;x<=W;x+=40){ctx.beginPath();ctx.moveTo(sx(x),0);ctx.lineTo(sx(x),canvas.height);ctx.stroke();}for(let wy=Math.floor(camY/40)*40;wy<camY+viewH+40;wy+=40){ctx.beginPath();ctx.moveTo(0,ly(wy));ctx.lineTo(canvas.width,ly(wy));ctx.stroke();for(let x=0;x<=W;x+=40){ctx.fillStyle='#000';ctx.fillRect(sx(x)-scale,ly(wy)-scale,2*scale,2*scale);}}},\r\n  ()=>{ctx.save();const by=14000,cy=ly(by+LEVEL_H/2);ctx.translate(0,cy);ctx.scale(1,-1);ctx.translate(0,-cy);wallpaper();office(by);ctx.restore();ctx.save();ctx.globalCompositeOperation='color';ctx.fillStyle='#2aa8a0';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.restore();},\r\n  ()=>{for(let r=Math.floor(camY/60);r<(camY+viewH)/60+1;r++)for(let c=0;c<7;c++){const x=sx(c*60),y=ly(r*60+60);ctx.fillStyle=QUILT[Math.floor(hash(r*7+c)*6)];ctx.fillRect(x,y,sx(60),sx(60));ctx.setLineDash([4*scale,4*scale]);ctx.strokeStyle='#fff8';ctx.strokeRect(x+sx(3),y+sx(3),sx(54),sx(54));ctx.setLineDash([]);if(hash(r*7+c+9)<.3){ctx.fillStyle='#2a2030';ctx.beginPath();ctx.arc(x+sx(30),y+sx(30),sx(5),0,7);ctx.fill();}}},\r\n  ()=>{rows(1,40,(b,y)=>{ctx.fillStyle=`rgba(80,255,220,${.08+hash(b)*.15})`;ctx.fillRect(0,y,canvas.width,sx(2+hash(b+1)*4));});\r\n   rows(.8,90,(b,y,x)=>sheet(((t*40+b*77)%(W+40))*scale-sx(20),y,sx(24),sx(10),'#2a7a8a',0,b,()=>{ctx.fillStyle='#7fffe0';ctx.fillRect(-sx(8),-sx(2),sx(16),sx(4));},{shadow:1}));\r\n   rows(1,260,(b,y,x)=>{ctx.fillStyle=hash(b)<.5?'#ff3aa0':'#3affd0';ctx.fillRect(x,y,sx(18),sx(12));});ctx.fillStyle='#0b4a5a';ctx.fillRect(0,0,sx(8),canvas.height);ctx.fillRect(sx(W-8),0,sx(8),canvas.height);},\r\n  ()=>{rows(.35,300,(b,y,x)=>{blob(x,y,sx(80+hash(b)*50),b,hash(b)<.5?'#8a4fc4':'#3fa6b8',.4);});stars(.3,'255,200,230');rows(.7,150,(b,y,x)=>{const r=sx(6+hash(b)*8)*(1+.25*Math.sin(t*3+b));diamond(x,y,r*1.6,'#ffe9a0');diamond(x,y,r,'#fff');});},\r\n  ()=>{ctx.fillStyle='#00000018';for(let wy=Math.floor(camY/10)*10;wy<camY+viewH+10;wy+=10){ctx.fillRect(0,ly(wy),sx(wy%50?10:22),scale);if(!(wy%50))text(String(wy/10%100),sx(34),ly(wy)+sx(3),6,'#000a','monospace',400);}\r\n   rows(1,70,(b,y,x)=>{ctx.strokeStyle='#555';ctx.lineWidth=scale;ctx.beginPath();ctx.moveTo(x,y);ctx.lineTo(x+sx(20),y-sx(8));ctx.lineTo(x+sx(36),y+sx(4));ctx.stroke();if(b%4===0)blob(x,y+sx(20),sx(4),b,'#e8a0b0');});\r\n   const hy=ly(18700);sheet(sx(W-30),hy,sx(110),sx(70),'#e8b890',.1,3);for(let i=0;i<4;i++)sheet(sx(W-80),hy-sx(30)+i*sx(18),sx(60),sx(12),'#e8b890',.1+i*.05,4+i);},\r\n  ()=>{rows(1,160,(b,y,x)=>{ctx.fillStyle='#00000030';ctx.beginPath();ctx.arc(sx(hash(b)<.5?50:W-50),y,sx(22),0,7);ctx.fill();ctx.strokeStyle='#8a7aa8';ctx.lineWidth=3*scale;ctx.stroke();});stars();\r\n   pyramidDesk(END_Y-14,1.4);tags.slice(-40).forEach((m,i)=>{const c=i%4,r=Math.floor(i/4);sheet(sx(45+c*90),ly(END_Y-260-r*34),sx(80),sx(26),'#ead9a6',(hash(i)-.5)*.1,i,()=>{text(m.name,0,-sx(2),6,'#463149','system-ui,sans-serif');text(m.date,0,sx(8),5,'#463149','monospace',400);},{shadow:2});});},\r\n ];\r\n function gate(k){ // the connector between level k and k+1: a paper lintel + posts that say how you leave\r\n  const y=ly(k*LEVEL_H+40);sheet(sx(W/2),y-sx(34),sx(W-30),sx(24),'#d7c28a',0,k,()=>text(LEVELS[k-1].gate,0,sx(3),7,'#3a2548','monospace'));\r\n  sheet(sx(14),y,sx(12),sx(70),'#c8b47a',0,k+1,null,{shadow:2});sheet(sx(W-14),y,sx(12),sx(70),'#c8b47a',0,k+2,null,{shadow:2});\r\n  ctx.fillStyle='#ffe9a044';ctx.fillRect(sx(20),y-sx(22),sx(W-40),sx(2));\r\n }\r\n function bg(){\r\n  const first=levelAt(camY),lastL=levelAt(camY+viewH);\r\n  for(let L=Math.max(0,first);L<=lastL;L++){\r\n   const top=L===LEVEL_COUNT-1?END_Y+3000:(L+1)*LEVEL_H,a=ly(top),b=ly(L?L*LEVEL_H:-3000),next=LEVELS[Math.min(LEVEL_COUNT-1,L+1)].sky;\r\n   ctx.save();ctx.beginPath();ctx.rect(0,a,canvas.width,b-a+1);ctx.clip();\r\n   const g=ctx.createLinearGradient(0,b,0,a);g.addColorStop(0,LEVELS[L].sky);g.addColorStop(1,L===13?LEVELS[13].sky:next);ctx.fillStyle=g;ctx.fillRect(0,a,canvas.width,b-a+1);\r\n   flat=L===13;SCENES[L]();flat=false;ctx.restore();\r\n  }\r\n  for(let k=Math.max(1,first);k<=Math.min(LEVEL_COUNT-1,lastL+1);k++)gate(k);\r\n }\r\n function paper(it){\r\n  if(it.type==='desk'){sheet(sx(W/2),sy(it.y)+sx(8),sx(W),sx(18),'#8a5f3c',0,31);return;}\r\n  const x=px(it),cx=sx(x+PLAT_W/2),y=sy(it.y+(it.by||0)),w=sx(PLAT_W),hh=sx(11),cy=y+hh/2-scale,rot=(hash(it.y)-.5)*.08+(it.broken?(hash(it.y+1)-.5)*3*(-(it.by||0)/200):0);\r\n  if(it.type==='monster'||it.type==='hole'||(it.broken&&y>canvas.height+50))return;\r\n  if(it.blink&&!solid(it)){ctx.save();ctx.strokeStyle='#ffffff88';ctx.lineWidth=2*scale;ctx.setLineDash([3*scale,3*scale]);ctx.beginPath();ctx.moveTo(cx-w/2,cy);ctx.lineTo(cx+w/2,cy);ctx.stroke();ctx.restore();return;}\r\n  if(it.type==='breaking'){ // two paper halves with a torn edge between\r\n   for(const s of[-1,1])sheet(cx+s*w/4,cy+(it.broken?s*sx(3):0),w/2-scale,hh,'#c58558',rot+(it.broken?s*.25:0),Math.round(it.y)+s,null,{edge:'#7a4a30'});\r\n   ctx.strokeStyle='#4a2a1a';ctx.lineWidth=scale*1.2;ctx.beginPath();ctx.moveTo(cx,cy-hh/2);ctx.lineTo(cx-sx(3),cy-sx(1));ctx.lineTo(cx+sx(2),cy+sx(1));ctx.lineTo(cx,cy+hh/2);ctx.stroke();\r\n  }else sheet(cx,cy,w,hh,it.type==='moving'?'#8cc3d1':it.blink?'#f4d870':'#d7c28a',rot,Math.round(it.y),it.type==='moving'?()=>{tape(-w/2+sx(5),0,-.3);tape(w/2-sx(5),0,.3);}:null);\r\n  if(it.type==='spring'){ctx.save();ctx.translate(cx,y);for(const [o,c,wd] of[[2,SHADOW,5],[0,'#fff4dc',4]]){ctx.strokeStyle=c;ctx.lineWidth=wd*scale;ctx.lineJoin='bevel';ctx.beginPath();ctx.moveTo(-sx(7)+o,0);for(let i=0;i<4;i++)ctx.lineTo(i%2?-sx(7)+o:sx(7)+o,-(i+1)*sx(4)+o);ctx.stroke();}ctx.strokeStyle=EDGE;ctx.lineWidth=scale;ctx.stroke();ctx.restore();}\r\n  if(it.gear==='jetpack')sheet(cx,y-sx(9),sx(11),sx(16),'#e45a5a',0,3,()=>{ctx.fillStyle='#ffb24d';ctx.fillRect(-sx(3),sx(6),sx(6),sx(5));},{shadow:2});\r\n  else if(it.gear)sheet(cx,y-sx(8),sx(16),sx(7),'#7fe6ff',-.2,4,()=>{ctx.beginPath();ctx.moveTo(-sx(8),0);ctx.lineTo(sx(8),0);ctx.stroke();},{shadow:2});\r\n }\r\n function foe(it){\r\n  if(it.broken)return;const x=sx(it.x),y=sy(it.y);\r\n  if(it.type==='hole'){const cx=x+sx(30),cy=y-sx(30);const r=ctx.createRadialGradient(cx,cy,0,cx,cy,sx(34));r.addColorStop(0,'#000');r.addColorStop(.6,'#1a0830');r.addColorStop(1,'#7a3cc800');ctx.fillStyle=r;ctx.beginPath();ctx.arc(cx,cy,sx(34),0,7);ctx.fill();ctx.strokeStyle='#b57cff';ctx.lineWidth=2*scale;ctx.beginPath();ctx.arc(cx,cy,sx(18),t*4,t*4+4);ctx.stroke();return;}\r\n  if(it.type!=='monster')return;\r\n  const look=LEVELS[levelAt(it.y)].mon,cx=x+sx(25),cy=y-sx(16),eye=(c=0)=>{ctx.fillStyle='#fff';ctx.beginPath();ctx.arc(cx,cy-sx(2),sx(8),0,7);ctx.fill();ctx.fillStyle='#000';ctx.beginPath();ctx.arc(cx+sx(3*Math.sign(p.x-it.x-25)),cy-sx(2),sx(3.5),0,7);ctx.fill();};\r\n  if(look==='tri'){sheet(cx,cy,sx(40),sx(30),'#fff',0,3);ctx.strokeStyle='#000';ctx.lineWidth=2*scale;ctx.beginPath();ctx.moveTo(cx-sx(22),cy+sx(14));ctx.lineTo(cx,cy-sx(16));ctx.lineTo(cx+sx(22),cy+sx(14));ctx.closePath();ctx.stroke();eye();return;}\r\n  ctx.save();ctx.translate(cx,cy);ctx.fillStyle=SHADOW;ctx.beginPath();ctx.ellipse(sx(3),sx(3),sx(25),sx(16),0,0,7);ctx.fill();ctx.restore();\r\n  ctx.lineWidth=2*scale;ctx.strokeStyle='#1d3a1a';\r\n  if(look==='dust'){ctx.fillStyle='#a8a4a0';for(let i=0;i<10;i++){ctx.beginPath();ctx.arc(cx+Math.cos(i*.63)*sx(18),cy+Math.sin(i*.63)*sx(11),sx(8),0,7);ctx.fill();}}\r\n  else if(look==='pigeon'){ctx.fillStyle='#8890a0';ctx.beginPath();ctx.ellipse(cx,cy,sx(22),sx(14),0,0,7);ctx.fill();ctx.stroke();ctx.fillStyle='#e8a040';ctx.beginPath();ctx.moveTo(cx+sx(20),cy-sx(4));ctx.lineTo(cx+sx(32),cy);ctx.lineTo(cx+sx(20),cy+sx(3));ctx.fill();}\r\n  else if(look==='crane'){ctx.fillStyle='#fff4f0';ctx.beginPath();ctx.moveTo(cx-sx(26),cy-sx(10));ctx.lineTo(cx,cy+sx(12));ctx.lineTo(cx+sx(26),cy-sx(10));ctx.lineTo(cx+sx(8),cy-sx(2));ctx.lineTo(cx+sx(14),cy-sx(20));ctx.lineTo(cx,cy-sx(4));ctx.closePath();ctx.fill();ctx.stroke();}\r\n  else if(look==='needle'){ctx.fillStyle='#c8ccd8';ctx.beginPath();ctx.moveTo(cx-sx(28),cy);ctx.lineTo(cx,cy-sx(8));ctx.lineTo(cx+sx(28),cy);ctx.lineTo(cx,cy+sx(8));ctx.closePath();ctx.fill();ctx.stroke();ctx.fillStyle='#e0504a';ctx.beginPath();ctx.arc(cx-sx(20),cy,sx(3),0,7);ctx.fill();}\r\n  else if(look==='junk'){ctx.fillStyle='#8a8fa0';ctx.beginPath();ctx.ellipse(cx,cy,sx(22),sx(14),.3,0,7);ctx.fill();ctx.stroke();ctx.fillStyle='#e8c040';ctx.fillRect(cx-sx(3),cy-sx(18),sx(6),sx(8));}\r\n  else if(look==='glitch'){ctx.fillStyle='#ff3aa0';ctx.fillRect(cx-sx(18),cy-sx(10),sx(36),sx(20));ctx.fillStyle='#3affd0';ctx.fillRect(cx-sx(10)+sx(6*Math.sin(t*20)),cy-sx(4),sx(30),sx(8));}\r\n  else{ctx.fillStyle='#69b04a';ctx.beginPath();ctx.ellipse(cx,cy,sx(25),sx(16),0,0,7);ctx.fill();ctx.stroke();for(const k of[-1,1]){ctx.beginPath();ctx.moveTo(cx+sx(k*14),cy-sx(14));ctx.lineTo(cx+sx(k*20),cy-sx(26));ctx.stroke();}}\r\n  if(look!=='needle'&&look!=='glitch')eye();\r\n }\r\n function tag(i,m){\r\n  const wy=markerHeight(i,tags.length),y=sy(wy);if(y<-80||y>canvas.height+80||false)return;const left=i%2===0,x=left?sx(6):sx(W-150),w=sx(144),h=sx(46);\r\n  ctx.save();ctx.translate(x+w/2,y);ctx.rotate(left?-.03:.03);ctx.strokeStyle='#ffffff55';ctx.lineWidth=scale;ctx.beginPath();ctx.moveTo(left?-w/2:w/2,0);ctx.lineTo(left?-w/2-sx(8):w/2+sx(8),-sx(30));ctx.stroke();\r\n  ctx.fillStyle='#ead9a6';ctx.strokeStyle='#8c7646';ctx.lineWidth=2*scale;ctx.fillRect(-w/2,-h/2,w,h);ctx.strokeRect(-w/2,-h/2,w,h);ctx.textAlign='left';\r\n  ctx.fillStyle='#463149';ctx.font=`700 ${11*scale}px system-ui,sans-serif`;ctx.fillText(m.name,-w/2+sx(6),-sx(6));ctx.font=`${9*scale}px monospace`;ctx.fillText(m.date,-w/2+sx(6),sx(6));ctx.fillText(`P${m.p} C${m.c} F${m.f}`,-w/2+sx(6),sx(17));ctx.restore();\r\n }\r\n function me(ghost=false){\r\n  const x=sx(ghost?W-p.x:p.x),y=sy(p.y),k=PH/240*scale;ctx.save();if(ghost)ctx.globalAlpha=.4;\r\n  for(const dx of[0,W*scale,-W*scale]){ctx.save();ctx.translate(x+dx,y);ctx.scale((ghost?-p.face:p.face)*k,k);ctx.translate(-100,-236);\r\n   ctx.shadowColor=flat?'transparent':'#49334b88';ctx.shadowOffsetX=3*scale;ctx.shadowOffsetY=3*scale;ctx.fillStyle=art.colour;ctx.strokeStyle='#2a1838';ctx.lineWidth=4;ctx.lineJoin='round';ctx.fill(shape);ctx.shadowColor='transparent';ctx.stroke(shape);\r\n   const [ex,ey,er]=art.eye;ctx.fillStyle='#fff8eb';ctx.beginPath();ctx.arc(ex,ey,er*1.7,0,7);ctx.fill();ctx.stroke();ctx.fillStyle='#2a1838';ctx.beginPath();ctx.arc(ex+er*.5,ey,er*.8,0,7);ctx.fill();\r\n   if(p.fly>0&&!ghost){if(p.gear==='propeller'){ctx.fillStyle='#7fe6ff';ctx.fillRect(80,0,40,8);ctx.fillRect(100-60*Math.cos(t*30),-6,120*Math.abs(Math.cos(t*30))||4,5);}else{ctx.fillStyle='#e45a5a';ctx.fillRect(40,100,20,60);ctx.fillRect(140,100,20,60);ctx.fillStyle='#ffb24d';ctx.fillRect(44,160,12,30+30*Math.random());ctx.fillRect(144,160,12,30+30*Math.random());}}\r\n   ctx.restore();}\r\n  ctx.restore();\r\n }\r\n function draw(){\r\n  bg();flat=levelAt(camY+viewH/2)===13;tags.forEach((m,i)=>tag(i,m));lvl.items.forEach(paper);lvl.items.forEach(foe);if(levelAt(p.y)===14)me(true);me();flat=false;\r\n  const s=Math.floor(maxY/10),dark=levelAt(camY+viewH/2)===13?'#000':'#fff4dc';ctx.fillStyle=dark;ctx.strokeStyle='#000a';ctx.lineWidth=3*scale;ctx.textAlign='left';ctx.font=`800 ${18*scale}px monospace`;if(!flat)ctx.strokeText(String(s),sx(10),sx(26));ctx.fillText(String(s),sx(10),sx(26));\r\n  ctx.font=`${10*scale}px monospace`;ctx.fillText(`LVL ${Math.max(1,cur+1)}/${LEVEL_COUNT}${plus?' +'+plus:''}  BEST ${Math.max(best,s)}`,sx(10),sx(40));\r\n  const past=tags.filter((_,i)=>markerHeight(i,tags.length)<=p.y);if(tags.length){const m=past.at(-1)||tags[0];ctx.textAlign='right';ctx.font=`700 ${10*scale}px monospace`;ctx.fillStyle='#ead9a6';ctx.strokeText(m.date,sx(W-6),sx(120));ctx.fillText(m.date,sx(W-6),sx(120));ctx.font=`${8*scale}px monospace`;ctx.fillText('YOU ATE',sx(W-6),sx(108));}\r\n  if(banner&&t-banner.t<2.8){ctx.save();ctx.globalAlpha=Math.min(1,(2.8-(t-banner.t))*2);sheet(sx(W/2),sx(86),sx(250),sx(40),'#ead9a6',-.02,7,()=>{text(banner.text,0,sx(5),13,'#463149');tape(-sx(112),-sx(16),-.4);tape(sx(112),-sx(16),.4);});ctx.restore();}\r\n }\r\n function tick(now){raf=requestAnimationFrame(tick);if(disposed)return;const dt=Math.min(.033,last?(now-last)/1000:0);last=now;if(!document.hidden){step(dt);draw();}}\r\n raf=requestAnimationFrame(tick);\r\n return {\r\n  state:()=>({p,camY,maxY,dead,won,cur,items:lvl.items}),\r\n  teleport(h){if(dead&&!won){dead=false;over.style.display='none';}lvl.ensure(h+viewH*2);p.y=h;p.vy=JUMP;p.fly=.35;p.flyV=0;camY=h-viewH*.45;maxY=Math.max(maxY,h);},\r\n  level(n){const h=(n-1)*LEVEL_H+30;this.teleport(h);},\r\n  dispose(){if(disposed)return;disposed=true;cancelAnimationFrame(raf);ro.disconnect();unsub?.();removeEventListener('keydown',kd);removeEventListener('keyup',ku);removeEventListener('pointerup',pu);removeEventListener('pointercancel',pu);canvas.remove();exit.remove();over.remove();},\r\n };\r\n}\r\n","arcade/pyramid-jump/logic.mjs":"// Pure pieces of Pyramid Jump (no DOM): coach shape + colour mapping, meal markers and the\r\n// platform generator. Lazy/optional: loaded only from the food pyramid on a photo day (see food/pyramid-scanner.mjs).\r\nimport {SHAPES,COLOURS,LEGACY} from './data.mjs';\r\nexport const W=360;\r\nexport const BEST_KEY='myr5-pyramid-jump-best-v1';\r\n\r\n// The user's selected coach body -> its paper silhouette, filled with the body's own colour (colour only, no texture).\r\nexport function paperFor(recipe){\r\n const id=String(recipe?.body||'myr5').replace(/^roster\\//,''),shape=SHAPES[id]||SHAPES.myr5;\r\n const choice=recipe?.materials?.body?.colorId,hex=/^#[0-9a-f]{6}$/i.test(choice)?choice:null;\r\n const colour=hex||COLOURS[choice]||LEGACY[recipe?.styles?.body]||LEGACY[0];\r\n return {id:SHAPES[id]?id:'myr5',d:shape.d,eye:shape.e,colour};\r\n}\r\nexport function readRecipe(store=localStorage){try{const r=JSON.parse(store.getItem('myr5-recipe-v1'));return r&&typeof r==='object'?r:null;}catch{return null;}}\r\n// Top of the silhouette (min y of the path) so the pocket peek can crop to head + eye.\r\nexport const topOf=d=>Math.min(...[...d.matchAll(/[ML](-?\\d+),(-?\\d+)/g)].map(m=>+m[2]));\r\n\r\n// Logged meals, oldest first (the API returns newest first), one paper tag each. Guests / no meals -> [].\r\nexport function mealMarkers(items){\r\n if(!Array.isArray(items))return [];\r\n return items.filter(m=>m&&m.name&&!Number.isNaN(Date.parse(m.eaten_at)))\r\n  .sort((a,b)=>Date.parse(a.eaten_at)-Date.parse(b.eaten_at))\r\n  .map(m=>{const t=new Date(m.eaten_at);return {name:String(m.name).slice(0,22),date:t.toLocaleDateString(undefined,{month:'short',day:'numeric'}),t:t.getTime(),p:Math.round(m.protein)||0,c:Math.round(m.carbs)||0,f:Math.round(m.fat)||0};});\r\n}\r\n// Meal tags spread over the whole climb, oldest near the start of level 1 and today near the top of level 20.\r\nexport const LEVEL_H=1000,LEVEL_COUNT=20,END_Y=LEVEL_H*LEVEL_COUNT;\r\nexport const markerHeight=(i,n)=>n<2?600:500+i*((END_Y-1500)/(n-1));\r\n\r\n// The 20-place journey (Ian, 15 Oct). sky = [bottom,top] colours; mon = the level's monster look; gate = how you leave it.\r\nexport const LEVELS=[\r\n {name:'The Office',gate:'CLIMB THE BOOKSHELF INTO THE VENT',sky:'#bba16e',mon:'dust'},\r\n {name:'Ceiling Vents',gate:'PUSH UP THE ROOF HATCH',sky:'#6f7480',mon:'dust'},\r\n {name:'Propaganda Stairwell',gate:'DOOR MARKED ROOF',sky:'#8a6aa0',mon:'dust'},\r\n {name:'Rooftop & Billboards',gate:'SPRING OFF THE ANTENNA TIP',sky:'#e0a070',mon:'pigeon'},\r\n {name:'Sky of Paper Clouds',gate:'GRAB A BALLOON STRING UP TO THE TETHER',sky:'#8fc4ea',mon:'pigeon'},\r\n {name:'Space Elevator',gate:'THE POD DOCKS AT THE TOP',sky:'#2a3f7a',mon:'alien'},\r\n {name:'Satellite Junkyard',gate:'SLIP THROUGH A TEAR',sky:'#0e1233',mon:'junk'},\r\n {name:'MOM Port 18',gate:'BOARD THE EXPRESS LIFT',sky:'#171a44',mon:'alien'},\r\n {name:'Moon Cafeteria Colony',gate:'THE FREEZER OPENS ONTO A FOLD',sky:'#4a4658',mon:'alien'},\r\n {name:'The Fold',gate:'FALL UP THROUGH THE CREASE',sky:'#d9c6e8',mon:'crane'},\r\n {name:'Origami Dimension',gate:'A CRANE CARRIES YOU UP',sky:'#e8a0b4',mon:'crane'},\r\n {name:'Asteroid Gym Belt',gate:'A RING PORTAL',sky:'#1a1030',mon:'junk'},\r\n {name:'Wormhole Highway',gate:'EXIT THE RING',sky:'#3a1a6a',mon:'alien'},\r\n {name:'Flatland',gate:'STEP OFF THE EDGE OF THE PLANE',sky:'#f4f4f4',mon:'tri'},\r\n {name:'Mirror Office',gate:'THE MIRROR PYRAMID’S TIP',sky:'#5aa89a',mon:'dust'},\r\n {name:'Quilt Dimension',gate:'PULL A LOOSE THREAD',sky:'#b86a8a',mon:'needle'},\r\n {name:'Data Cable',gate:'THE CABLE PLUGS INTO A PORT',sky:'#04202a',mon:'glitch'},\r\n {name:'Nebula Nursery',gate:'A NEWBORN STAR LAUNCHES YOU',sky:'#3a1a50',mon:'alien'},\r\n {name:'Edge of the Page',gate:'CLIMB OVER THE PAGE EDGE',sky:'#f0e6c8',mon:'junk'},\r\n {name:'MOM’s Mothership Desk',gate:'LAND ON HER DESK',sky:'#3a2a4e',mon:'alien'},\r\n];\r\nexport const levelAt=h=>Math.max(0,Math.min(LEVEL_COUNT-1,Math.floor(h/LEVEL_H))); // 0-based\r\nexport function steeringForMotion({steerX,gx}={}){\r\n const sample=Number.isFinite(steerX)?steerX:gx;\r\n return Number.isFinite(sample)?Math.max(-1,Math.min(1,sample*2.2)):0;\r\n}\r\n\r\nexport const mulberry=seed=>()=>{seed|=0;seed=seed+0x6D2B79F5|0;let t=Math.imul(seed^seed>>>15,1|seed);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};\r\nexport const PLAT_W=64,JUMP=760,GRAVITY=1600,MAX_JUMP=JUMP*JUMP/(2*GRAVITY); // 180 units\r\nexport const LEVEL_KEY='myr5-pyramid-jump-level-v1';\r\nexport const highestLevel=(store=localStorage)=>{try{const n=JSON.parse(store.getItem(LEVEL_KEY));return Number.isSafeInteger(n)&&n>=1?Math.min(n,LEVEL_COUNT):1;}catch{return 1;}};\r\nexport const saveLevel=(n,store=localStorage)=>{try{if(n>highestLevel(store))store.setItem(LEVEL_KEY,String(n));}catch{/* ignore */}};\r\n/** Convert an actual upward transition (zero-based current level) to its 1-based quest milestone. */\r\nexport const newlyReachedQuestLevel=(previous,current)=>Number.isSafeInteger(previous)&&Number.isSafeInteger(current)\r\n  &&current>previous&&current>=0&&current<LEVEL_COUNT?current+1:null;\r\n// Rows climb for 20 levels then end in MOM's desk (end = its height). Rows are never further apart than ~150 (< MAX_JUMP) and\r\n// every breaking/blinking row also carries a solid platform, so a safe route always exists. Difficulty ramps per level:\r\n// wider gaps, more moving and breaking platforms, then monsters (from level 2) and black holes (from level 8); `plus` = New Game+.\r\nexport class Level{\r\n constructor(rng=mulberry(7),plus=0){this.rng=rng;this.plus=plus;this.items=[{x:W/2-PLAT_W/2,y:0,type:'static'}];this.top=0;this.end=null;}\r\n ensure(y){while(this.top<y&&this.end==null)this.row();}\r\n row(){\r\n  const r=this.rng,h=this.top,L=levelAt(h),d=L/(LEVEL_COUNT-1),pl=Math.min(this.plus,3);\r\n  const gap=(58+62*d+5*pl)*(0.75+0.25*r());\r\n  if(h+gap>=END_Y-40){this.top=this.end=h+Math.min(140,Math.max(70,END_Y-h));this.items.push({x:0,y:this.end,type:'desk',w:W});return;}\r\n  const y=this.top+=gap,x=r()*(W-PLAT_W),roll=r();let type='static';\r\n  const pMove=.1+.25*d+.03*pl,pBreak=L>=2?.1+.2*d+.03*pl:0,pSpring=L===12?.2:.06;\r\n  if(L>=1&&roll<pMove)type='moving';\r\n  else if(roll<pMove+pBreak)type='breaking';\r\n  else if(roll>1-pSpring)type='spring';\r\n  const item={x,y,type};\r\n  if(type==='moving'){item.dx=40+r()*60;item.phase=r()*6.28;}\r\n  if(type==='static'){const k=r();if(L>=3&&k<.05)item.gear='propeller';else if(L>=5&&k>.97)item.gear='jetpack';else if((L===10||L===17)&&k>.4){item.blink=2.2+r();item.phase=r()*6;}}\r\n  this.items.push(item);\r\n  if(type==='breaking'||item.blink)this.items.push({x:(x+W/2)%(W-PLAT_W),y:y+gap*0.15,type:'static'});\r\n  const far=()=>{let fx;do fx=r()*(W-60);while(Math.abs(fx-x)<110);return fx;};\r\n  if(L>=1&&r()<.02+.06*d+.01*pl)this.items.push({x:far(),y:y+gap*0.5,type:'monster',dir:r()<0.5?-1:1});\r\n  else if(L>=7&&r()<(L===16?.08:.02+.04*d))this.items.push({x:far(),y:y+gap*0.5,type:'hole'});\r\n }\r\n}\r\n","arcade/pyramid-jump/pet.mjs":"// The paper MOM Inc. character that lives in Dr. Girlfriend's pocket on photo days (peek -> jump to the right ->\r\n// hop onto the pyramid and bounce -> PLAY). Lazy/optional; mounted by food/pyramid-scanner.mjs, all in the same window.\r\nimport {paperFor,readRecipe,topOf} from './logic.mjs';\r\nconst STYLE=`\r\n#pyramidScanner .pj-layer{position:absolute;inset:0;z-index:4;pointer-events:none;overflow:hidden}\r\n#pyramidScanner .pj-layer[data-behind]{z-index:1}\r\n#pyramidScanner .pj-pet{position:absolute;left:0;top:0;padding:0;border:0;background:none;pointer-events:auto;cursor:pointer;filter:drop-shadow(2px 3px 2px #30251988);touch-action:manipulation}\r\n#pyramidScanner .pj-pet svg{display:block;width:100%;height:100%;overflow:hidden}\r\n#pyramidScanner .pj-lip{position:absolute;left:-16px;right:-16px;bottom:-6px;height:20px;background:repeating-linear-gradient(90deg,#8b5bc7 0 9px,#d4a93a 9px 14px);border:2px solid #351344;border-radius:2px 2px 5px 5px}\r\n#pyramidScanner .pj-play{position:absolute;left:0;top:0;min-height:44px;padding:0 24px;border:2px solid #fff;border-radius:999px;background:#ff5d8f;color:#fff;font:800 15px/1 system-ui,sans-serif;letter-spacing:.12em;pointer-events:auto;box-shadow:0 2px 10px #0008;animation:pjPulse 1.6s ease-in-out infinite}\r\n@keyframes pjPulse{50%{box-shadow:0 2px 10px #0008,0 0 18px 6px #ff5d8fbb}}\r\n#pyramidScanner[data-jump] .pyramid-ui>*{opacity:0!important;pointer-events:none!important}\r\n#pyramidScanner .pyramid-ui>*{transition:opacity .45s}\r\n@media(prefers-reduced-motion:reduce){#pyramidScanner .pj-play{animation:none}#pyramidScanner .pyramid-ui>*{transition:none}}\r\n`;\r\nconst ease=t=>t<.5?2*t*t:1-(-2*t+2)**2/2;\r\nexport function mountPet({host,walker,playAt,apex,getMeals,dialog,recipe=readRecipe()}){\r\n const art=paperFor(recipe),top=topOf(art.d),[ex,ey,er]=art.eye,reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const style=document.createElement('style');style.textContent=STYLE;document.head.append(style);\r\n const layer=document.createElement('div');layer.className='pj-layer';layer.dataset.behind='';\r\n const pet=document.createElement('button');pet.type='button';pet.className='pj-pet';pet.setAttribute('aria-label','A little paper friend peeks out of her pocket. Tap to say hi');\r\n const peekH=Math.max(60,ey+er*1.7+46-top+20);\r\n const tufts=`<path d=\"M78,${top+3}l5,-14l6,12l6,-18l6,16l7,-15l5,14l7,-11l4,11z\" fill=\"${art.colour}\" stroke=\"#2a1838\" stroke-width=\"3\" stroke-linejoin=\"round\"/>`;\r\n pet.innerHTML=`<svg viewBox=\"0 ${top-20} 200 ${peekH}\" aria-hidden=\"true\"><path d=\"${art.d}\" fill=\"${art.colour}\" stroke=\"#2a1838\" stroke-width=\"4\" stroke-linejoin=\"round\"/>${tufts}<circle cx=\"${ex}\" cy=\"${ey}\" r=\"${er*1.7}\" fill=\"#fff8eb\" stroke=\"#2a1838\" stroke-width=\"3\"/><circle class=\"pj-pupil\" cx=\"${ex}\" cy=\"${ey}\" r=\"${er*.8}\" fill=\"#2a1838\"/></svg><i class=\"pj-lip\"></i>`;\r\n const svg=pet.querySelector('svg'),pupil=pet.querySelector('.pj-pupil'),lip=pet.querySelector('.pj-lip');\r\n const play=document.createElement('button');play.type='button';play.className='pj-play';play.textContent='PLAY';play.hidden=true;\r\n layer.append(pet,play);host.append(layer);\r\n const size={peek:[72,72*peekH/200],full:[56,56*240/200]};\r\n let state='peek',tween=null,pos={x:-99,y:-99},w=72,h=size.peek[1],game=null,raf=0,disposed=false,gamePromise=null;\r\n const to=(x,y,ms,hop=60)=>{const from={...pos};tween={from,to:{x,y},t0:performance.now(),ms:reduced?1:ms,hop};};\r\n const hostBox=()=>host.getBoundingClientRect();\r\n function full(){[w,h]=size.full;svg.setAttribute('viewBox','0 0 200 240');pet.removeChild(lip);}\r\n function frame(now){\r\n  if(disposed)return;raf=requestAnimationFrame(frame);\r\n  const hb=hostBox();\r\n  if(state==='peek'&&walker?.isConnected){const r=walker.getBoundingClientRect();pos={x:r.left-hb.left+r.width*.63-w/2,y:r.top-hb.top+r.height*.31-h+6};} // peeks out of the DR GIRLFRIEND badge pocket, up top\r\n  if(tween){const t=Math.min(1,(now-tween.t0)/tween.ms),e=ease(t);pos={x:tween.from.x+(tween.to.x-tween.from.x)*e,y:tween.from.y+(tween.to.y-tween.from.y)*e-Math.sin(t*Math.PI)*tween.hop};if(t>=1){const done=tween.then;tween=null;done?.();}}\r\n  else if(state==='right')pos.y+=Math.sin(now/260)*.35;\r\n  else if(state==='bounce'){const a=apex(),b=Math.abs(Math.sin(now/230));pos={x:a.x-w/2,y:a.y-h-b*34};}\r\n  pet.style.width=w+'px';pet.style.height=h+'px';pet.style.transform=`translate(${Math.round(pos.x)}px,${Math.round(pos.y)}px)${state==='bounce'?` scale(${1+.08*(1-Math.abs(Math.sin(now/230)))},${1-.08*(1-Math.abs(Math.sin(now/230)))})`:''}`;\r\n  // the eyeball looks at the user: toward the middle of the screen\r\n  const dx=hb.width/2-(pos.x+w/2),dy=hb.height/2-(pos.y+h/2),d=Math.hypot(dx,dy)||1;\r\n  pupil.setAttribute('cx',ex+dx/d*er*.7);pupil.setAttribute('cy',ey+dy/d*er*.7);\r\n  if(!play.hidden){const r=playAt.getBoundingClientRect(),pw=play.offsetWidth||110,ph=play.offsetHeight||44;play.style.transform=`translate(${Math.round(hb.width/2-pw/2)}px,${Math.round(r.top-hb.top-ph-14)}px)`;} // PLAY takes the camera button's job, above the TODAY/LAST MEAL switch\r\n }\r\n const home=()=>{const hb=hostBox();return {x:hb.width-w-14,y:hb.height*.56};};\r\n function hopOnPyramid(){\r\n  if(state==='peek')full();delete layer.dataset.behind;state='fly';host.dataset.jump='';pet.setAttribute('aria-label','Your paper friend bouncing on the pyramid');pet.tabIndex=-1;\r\n  const a=apex();to(a.x-w/2,a.y-h,700,80);tween.then=()=>{state='bounce';play.hidden=false;play.focus({preventScroll:true});};\r\n }\r\n function backHome(){\r\n  delete host.dataset.jump;play.hidden=true;state='fly';pet.tabIndex=0;pet.setAttribute('aria-label','Your paper friend. Tap to hop onto the pyramid');\r\n  const h0=home();to(h0.x,h0.y,700,80);tween.then=()=>{state='right';};\r\n }\r\n pet.onclick=()=>{if(state==='peek'||state==='right')hopOnPyramid();};\r\n // While peeking the pyramid canvas sits on top, so catch taps on the pet's box before the pyramid gets them.\r\n let swallow=false;const inPet=ev=>{const b=pet.getBoundingClientRect();return ev.clientX>=b.left&&ev.clientX<=b.right&&ev.clientY>=b.top&&ev.clientY<=b.bottom;};\r\n const capDown=ev=>{if(state==='peek'&&inPet(ev)){swallow=true;ev.stopPropagation();ev.preventDefault();hopOnPyramid();}};\r\n const capRest=ev=>{if(swallow){ev.stopPropagation();ev.preventDefault();if(ev.type==='click')swallow=false;}};\r\n host.addEventListener('pointerdown',capDown,true);for(const t of['pointerup','click'])host.addEventListener(t,capRest,true);\r\n play.onclick=async()=>{\r\n  if(game||gamePromise)return;\r\n  const motion=await import('../../character-phone-sensor.mjs').catch(()=>null);void motion?.requestPhoneMotion?.(); // iOS asks for tilt inside this tap\r\n  gamePromise=import('./game.mjs').then(m=>{\r\n   if(disposed)return;\r\n   layer.hidden=true;const root=document.createElement('div');root.className='pj-game';root.style.cssText='position:absolute;inset:0;z-index:7;background:#05030f;overflow:hidden';(dialog||host).append(root);\r\n   const g=m.startGame(root,{auto:true,startLevel:+new URLSearchParams(location.search).get('pjlevel')||0,recipe,meals:getMeals(),subscribeMotion:motion?.subscribePhoneMotion,onExit(){g.dispose();root.remove();game=null;layer.hidden=false;backHome();}});\r\n   game={g,root};window.__pyramidJump=g; // test hook: g.teleport(h)\r\n  }).catch(()=>{layer.hidden=false;}).finally(()=>{gamePromise=null;});\r\n };\r\n raf=requestAnimationFrame(frame);\r\n return {dispose(){if(disposed)return;disposed=true;cancelAnimationFrame(raf);host.removeEventListener('pointerdown',capDown,true);for(const t of['pointerup','click'])host.removeEventListener(t,capRest,true);game?.g.dispose();game?.root.remove();delete host.dataset.jump;layer.remove();style.remove();if(window.__pyramidJump===game?.g)delete window.__pyramidJump;}};\r\n}\r\n","arcade/quest-progress-reporter.mjs":"// Small owner-scoped retry queue for optional, online-only Vault quest writes.\r\n// Game pages remain loadable offline; bounded maxima survive until Vault can drain them.\r\nimport { performanceOwner } from '../performance-progress.mjs';\r\nimport { EXERCISES } from '../exercise-library.mjs';\r\nimport { HOLD_CAP_SECONDS, REP_CAP } from '../progression-rules.mjs';\r\nimport { powerProgress, retainedPowerStyle } from './power/power.mjs';\r\nimport { holdStyleForExercise } from './workout-effects-state.mjs';\r\n\r\nconst RULES = Object.freeze({\r\n 'pyramid-level':[1,20,true], 'pyramid-complete':[1,1,true], 'fruit-streak':[3,64,true],\r\n 'aura-tier':[1,6,true], 'blizzard-tier':[1,6,true], 'fire-tier':[1,6,true],\r\n 'lightning-tier':[1,6,true], 'yoga-hold-seconds':[1,60,false],\r\n});\r\nconst valid=(counter,value)=>{const r=RULES[counter];return !!r&&Number.isFinite(value)&&value>=r[0]&&value<=r[1]&&(!r[2]||Number.isSafeInteger(value));};\r\nconst key=owner=>`myr5-quest-pending-v1/${encodeURIComponent(owner)}`;\r\nconst IMPORT_NONCE_KEY=Symbol.for('myr5.quest-progress-import-nonce');\r\nfunction nextImportNonce(){\r\n try{const n=(Number(globalThis[IMPORT_NONCE_KEY])||0)+1;globalThis[IMPORT_NONCE_KEY]=n;return n;}\r\n catch{return `${Date.now()}-${Math.random().toString(36).slice(2)}`;}\r\n}\r\n\r\nexport function createQuestProgressReporter(ownerId,{storage=globalThis.localStorage,currentOwner=performanceOwner,load=null,importer=url=>import(url),now=()=>Date.now(),baseDelay=1000,maxDelay=30000}={}){\r\n const memoryValues={};\r\n const confirmed={};\r\n let drainPromise=null,retryAt=0,retryDelay=baseDelay,loadedModule=null,loadPromise=null,importFailures=0;\r\n const loadVault=()=>{\r\n  if(loadedModule)return Promise.resolve(loadedModule);\r\n  if(loadPromise)return loadPromise;\r\n  const url=importFailures===0?'/modules/vault/quest-progress.mjs':`/modules/vault/quest-progress.mjs?quest-retry=${nextImportNonce()}`;\r\n  const pending=Promise.resolve().then(()=>load?load():importer(url)).then(module=>{loadedModule=module;return module;}).catch(error=>{importFailures++;throw error;}).finally(()=>{loadPromise=null;});\r\n  loadPromise=pending;return pending;\r\n };\r\n const pendingNow=()=>{\r\n  let values={...memoryValues};\r\n  if(storage)try{const row=JSON.parse(storage.getItem(key(ownerId))||'{}');if(row?.ownerId===ownerId&&row.values&&typeof row.values==='object')for(const [counter,value] of Object.entries(row.values).slice(0,8))if(valid(counter,value))values[counter]=Math.max(values[counter]||0,value);}catch{}\r\n  return {ownerId,values};\r\n };\r\n const persist=values=>{\r\n  for(const k of Object.keys(memoryValues))delete memoryValues[k];\r\n  for(const [counter,value] of Object.entries(values).slice(0,8))if(valid(counter,value))memoryValues[counter]=value;\r\n  if(storage)try{if(Object.keys(memoryValues).length)storage.setItem(key(ownerId),JSON.stringify({ownerId,values:{...memoryValues}}));else storage.removeItem(key(ownerId));}catch{}\r\n };\r\n const doDrain=async()=>{\r\n  if(typeof ownerId!=='string'||!ownerId||currentOwner()!==ownerId)return false;\r\n  try{\r\n   const module=await loadVault();if(currentOwner()!==ownerId)return false;\r\n   const pending=pendingNow();\r\n   for(const [counter,value] of Object.entries(pending.values)){\r\n    module.recordQuestProgress({ownerId,counter,value});\r\n    if(currentOwner()!==ownerId)return false;\r\n    if(module.questProgressStored?.(ownerId,counter,value)){\r\n     confirmed[counter]=Math.max(confirmed[counter]||0,value);\r\n     const latest=pendingNow();if((latest.values[counter]||0)<=value)delete latest.values[counter];\r\n     persist(latest.values);\r\n    }\r\n   }\r\n   return Object.keys(pendingNow().values).length===0;\r\n  }catch{return false;}\r\n };\r\n const drain=()=>{\r\n  if(drainPromise)return drainPromise;\r\n  if(now()<retryAt)return Promise.resolve(false);\r\n  drainPromise=doDrain().then(ok=>{if(ok){retryAt=0;retryDelay=baseDelay;}else{retryAt=now()+retryDelay;retryDelay=Math.min(maxDelay,retryDelay*2);}return ok;}).catch(()=>{retryAt=now()+retryDelay;retryDelay=Math.min(maxDelay,retryDelay*2);return false;}).finally(()=>{drainPromise=null;});return drainPromise;\r\n };\r\n const record=(counter,value)=>{\r\n  if(typeof ownerId!=='string'||!ownerId||currentOwner()!==ownerId||!valid(counter,value))return false;\r\n  if(value<=(confirmed[counter]||0))return false;\r\n  const pending=pendingNow();if((pending.values[counter]||0)<value){pending.values[counter]=value;persist(pending.values);}\r\n  void drain();return true;\r\n };\r\n const recordWorkout=detail=>{\r\n  const workout=detail?.workout;\r\n  if(!workout||workout.ownerId!==ownerId||currentOwner()!==ownerId||workout.stage!=='working'||workout.paused===true)return false;\r\n  const exercise=EXERCISES[workout.mode];if(!exercise||workout.kind!==exercise.kind)return false;\r\n  if(workout.kind==='reps'&&(!Number.isFinite(workout.workingReps)||workout.workingReps<0||workout.workingReps>REP_CAP))return false;\r\n  if(workout.kind==='hold'&&(!Number.isFinite(workout.activeSeconds)||workout.activeSeconds<0||workout.activeSeconds>HOLD_CAP_SECONDS))return false;\r\n  if(workout.kind==='hold'&&exercise.group==='yoga'&&holdStyleForExercise(exercise)==='living')return record('yoga-hold-seconds',Math.min(60,Math.floor(workout.activeSeconds)));\r\n  if(workout.kind==='hold'&&['core','balance'].includes(exercise.group)&&retainedPowerStyle(exercise)==='blizzard')return record('blizzard-tier',powerProgress(workout).tier);\r\n  if(workout.kind!=='reps')return false;\r\n  const style=retainedPowerStyle(exercise),tier=powerProgress(workout).tier;\r\n  const counter=style==='aura'?'aura-tier':style==='floor'?'fire-tier':style==='lightning'?'lightning-tier':null;\r\n  return counter?record(counter,tier):false;\r\n };\r\n return Object.freeze({record,recordWorkout,drain});\r\n}\r\n\r\n/** Vault startup hook: try to drain any same-owner game milestones saved offline. */\r\nexport function drainQueuedQuestProgress(options={}){\r\n const ownerId=options.ownerId??performanceOwner();\r\n return createQuestProgressReporter(ownerId,options).drain();\r\n}\r\n","arcade/runner/clay-text.mjs":"// Rolled-out clay letters on a canvas, copied from the site (tv/assets/armie-intro/chase-ui.mjs clayText).\r\nexport function clayText(text,height=40){\r\n  let seed=[...text].reduce((a,c)=>a*31+c.charCodeAt(0)>>>0,7);const rnd=()=>(seed=seed*1664525+1013904223>>>0)/4294967296;\r\n  const dpr=Math.min(2,devicePixelRatio||1),fs=height*.74,font=`900 ${fs}px \"Arial Rounded MT Bold\",\"Arial Black\",\"Segoe UI Black\",system-ui,sans-serif`;\r\n  const c=document.createElement('canvas'),x=c.getContext('2d');x.font=font;\r\n  const letters=[...text.toUpperCase()].map(ch=>({ch,w:ch===' '?fs*.32:x.measureText(ch).width+fs*.1,r:(rnd()-.5)*.22,dy:(rnd()-.5)*fs*.1}));\r\n  const w=letters.reduce((a,l)=>a+l.w,0)+fs*.5;c.width=Math.ceil(w*dpr);c.height=Math.ceil(height*dpr);c.style.width=w+'px';c.style.height=height+'px';\r\n  x.scale(dpr,dpr);x.font=font;x.textAlign='center';x.textBaseline='middle';x.lineJoin='round';\r\n  const each=fn=>{let px=fs*.25;for(const l of letters){if(l.ch!==' '){x.save();x.translate(px+l.w/2,height/2+l.dy);x.rotate(l.r);fn(l);x.restore();}px+=l.w;}};\r\n  x.shadowColor='#000c';x.shadowBlur=fs*.12;x.shadowOffsetY=fs*.07;x.strokeStyle=x.fillStyle='#3a1a4a';x.lineWidth=fs*.27;each(l=>{x.strokeText(l.ch,0,0);x.fillText(l.ch,0,0);});\r\n  x.shadowColor='transparent';const g=x.createLinearGradient(0,height*.15,0,height*.85);g.addColorStop(0,'#b07acc');g.addColorStop(.45,'#8e5b99');g.addColorStop(1,'#5e3270');\r\n  x.strokeStyle=x.fillStyle=g;x.lineWidth=fs*.19;each(l=>{x.strokeText(l.ch,0,0);x.fillText(l.ch,0,0);});\r\n  x.strokeStyle='#d6a8ea88';x.lineWidth=fs*.035;each(l=>{x.save();x.translate(-fs*.025,-fs*.04);x.beginPath();x.rect(-l.w,-fs,l.w*2,fs*.75);x.clip();x.strokeText(l.ch,0,0);x.restore();});\r\n  x.globalCompositeOperation='source-atop';for(let i=0;i<w*1.4;i++){x.fillStyle=rnd()<.5?'#512866':'#c79ce0';x.globalAlpha=.08+rnd()*.12;x.beginPath();x.ellipse(rnd()*w,rnd()*height,1+rnd()*fs*.09,1+rnd()*fs*.05,rnd()*3,0,7);x.fill();}\r\n  x.globalAlpha=1;x.globalCompositeOperation='source-over';\r\n  let px=fs*.25;letters.forEach((l,i)=>{if(l.ch!==' '&&rnd()<.3){const bx=px+l.w*(.3+rnd()*.4),by=height*(.3+rnd()*.4),a=rnd()*3,s=fs*.07;x.save();x.translate(bx,by);x.rotate(a);x.fillStyle='#d4a017';x.fillRect(-s*1.6,-s*.35,s*3.2,s*.7);for(const ex of[-1.6,1.6])for(const ey of[-.4,.4]){x.beginPath();x.arc(ex*s,ey*s,s*.45,0,7);x.fill();}x.restore();}px+=l.w;});\r\n  return c;\r\n}\r\n","arcade/runner/coach-3d.mjs":"// Coach Armie in 3D, copied from the site (tv/assets/armie-intro/coach-3d.mjs: loader, canonical frame, buildCoach) on the app's three.\r\n// made canonical at load and given live googly eyes in code. Every caller keeps its 2D coach (sprite / SVG /\r\n// procedural hand) until the model is in, so a missing or broken GLB changes nothing.\r\n// Canonical frame: length 1 along X, centred, fingers at +X, lying PALM DOWN: back of the hand (and the eyes on its knuckles) faces +Y, Z is sideways.\r\nimport * as T from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nexport const COACH_GLB=new URL('./models/coach-hand.glb',import.meta.url).href;\r\nconst still=()=>matchMedia('(prefers-reduced-motion: reduce)').matches||!!document.querySelector('#ar.ar-motion-off');\r\nlet pending=null;\r\nexport const loadCoachParts=()=>pending??=new GLTFLoader().loadAsync(COACH_GLB).then(g=>canonical(g.scene));\r\n\r\n// Bake every mesh into the canonical frame as plain arrays, so callers on another three.js copy can rebuild it.\r\nfunction canonical(root){\r\n  root.updateMatrixWorld(true);const parts=[],all=[];\r\n  // Float copies that respect normalized (e.g. Uint16 colour/uv) attributes.\r\n  const flat=at=>at&&Float32Array.from({length:at.count*at.itemSize},(_,i)=>at.getComponent(Math.floor(i/at.itemSize),i%at.itemSize));\r\n  root.traverse(o=>{if(!o.isMesh)return;const g=o.geometry;\r\n    const pos=g.attributes.position.clone().applyMatrix4(o.matrixWorld);for(let i=0;i<pos.count;i++)all.push(new T.Vector3().fromBufferAttribute(pos,i));\r\n    const m=Array.isArray(o.material)?o.material[0]:o.material;\r\n    parts.push({name:o.name,pos,uv:flat(g.attributes.uv),color:flat(g.attributes.color),colorSize:g.attributes.color?.itemSize,index:g.index?.array,groups:g.groups,\r\n      mat:{color:m.color?.getHex()??0x8e5b99,roughness:m.roughness??.9,metalness:m.metalness??0,map:m.map?.image??null,vertexColors:!!g.attributes.color}});});\r\n  if(!all.length)throw Error('coach-hand.glb has no mesh');\r\n  const box=new T.Box3().setFromPoints(all),size=box.getSize(new T.Vector3()),c=box.getCenter(new T.Vector3());\r\n  const axis=size.x>=size.y&&size.x>=size.z?'x':size.y>=size.z?'y':'z',[a,b]=['x','y','z'].filter(k=>k!==axis),L=size[axis];\r\n  // Face end = the wider end (Ian's model: open hand with the fingers up, torn wrist and a bone below).\r\n  const spread=(lo,hi)=>{let s=0,n=0;for(const p of all){const t=(p[axis]-box.min[axis])/L;if(t>=lo&&t<=hi){s+=Math.hypot(p[a]-c[a],p[b]-c[b]);n++;}}return n?s/n:0;};\r\n  const dir=new T.Vector3();dir[axis]=spread(.85,1)>=spread(0,.15)?1:-1;\r\n  const align=new T.Quaternion().setFromUnitVectors(dir,new T.Vector3(1,0,0));\r\n  // Roll about the length so the BACK of the hand (opposite the curl of the fingers; in the file the palm is +Z) faces +Y: palm down.\r\n  const roll=new T.Quaternion().setFromAxisAngle(new T.Vector3(1,0,0),Math.PI/2);\r\n  const M=new T.Matrix4().makeScale(1/L,1/L,1/L).multiply(new T.Matrix4().makeRotationFromQuaternion(roll.multiply(align))).multiply(new T.Matrix4().makeTranslation(-c.x,-c.y,-c.z));\r\n  for(const p of parts)p.pos=p.pos.applyMatrix4(M).array;\r\n  // Plain-white single-material export: paint it as clay, with the bone (the thin end, x < -.16) gold. Vertex colours carry both.\r\n  for(const p of parts)if(!p.color&&!p.mat.map&&p.mat.color>0xe0e0e0){const clay=new T.Color(0x8e5b99),bone=new T.Color(0xd4a017),n=p.pos.length/3,col=new Float32Array(n*3);\r\n    for(let i=0;i<n;i++){const k=p.pos[i*3]<-.16?bone:clay;col.set([k.r,k.g,k.b],i*3);}\r\n    p.color=col;p.colorSize=3;p.mat.vertexColors=true;p.mat.color=0xffffff;p.mat.roughness=.9;}\r\n  return {parts,hasEyes:parts.some(p=>/pupil|eye/i.test(p.name))};\r\n}\r\n\r\n// Build the coach with the caller's three.js. tick(now,{pressure 0..1, roll}) jiggles the pupils like coach-hand.mjs.\r\nexport function buildCoach(THREE,{parts,hasEyes}){\r\n  const group=new THREE.Group();group.name='coach-armie-3d';const body=[];\r\n  for(const p of parts){const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.BufferAttribute(new Float32Array(p.pos),3));\r\n    if(p.uv)g.setAttribute('uv',new THREE.BufferAttribute(p.uv,2));\r\n    if(p.color)g.setAttribute('color',new THREE.BufferAttribute(p.color,p.colorSize));\r\n    if(p.index)g.setIndex(Array.from(p.index));(p.groups||[]).forEach(x=>g.addGroup(x.start,x.count,x.materialIndex));g.computeVertexNormals();\r\n    const mat=new THREE.MeshStandardMaterial({color:p.mat.color,roughness:p.mat.roughness,metalness:p.mat.metalness,vertexColors:p.mat.vertexColors});\r\n    if(p.mat.map){mat.map=new THREE.Texture(p.mat.map);mat.map.flipY=false;mat.map.colorSpace=THREE.SRGBColorSpace;mat.map.needsUpdate=true;}\r\n    const mesh=new THREE.Mesh(g,mat);mesh.name=p.name;group.add(mesh);body.push(mesh);}\r\n  const pupils=[];\r\n  if(!hasEyes){// big + small mismatched googly eyes (coach-hand.mjs canon ratio 10:6).\r\n    const sclera=new THREE.MeshStandardMaterial({color:0xfffdf6,roughness:.25}),ink=new THREE.MeshStandardMaterial({color:0x120a14,roughness:.3});\r\n    const ray=new THREE.Raycaster(),up=new THREE.Vector3(0,1,0);\r\n    // Ian's hand model, palm down: both eyes sit side by side on the knuckle ridge (x .27) of the back of the hand, facing +Y.\r\n    for(const [x,z,r] of [[.27,-.075,.06],[.27,.07,.038]]){\r\n      ray.set(new THREE.Vector3(x,2,z),new THREE.Vector3(0,-1,0));const hit=ray.intersectObjects(body,false)[0];\r\n      const n=hit?.face?hit.face.normal.clone().normalize():new THREE.Vector3(0,1,0);if(n.y<0)n.negate();\r\n            const eye=new THREE.Group();eye.position.copy(hit?hit.point:new THREE.Vector3(x,.15,z)).addScaledVector(n,r*.15);eye.quaternion.setFromUnitVectors(up,n);group.add(eye);\r\n      const white=new THREE.Mesh(new THREE.SphereGeometry(1,24,12),sclera);white.scale.set(r,r*.5,r);eye.add(white);\r\n      const pupil=new THREE.Mesh(new THREE.SphereGeometry(1,16,8),ink);pupil.scale.set(r*.5,r*.15,r*.5);pupil.position.y=r*.42;eye.add(pupil);\r\n      pupils.push({p:pupil,rest:pupil.position.clone(),room:r*.42,target:new THREE.Vector2()});}\r\n  }\r\n  let next=0,angle=0;\r\n  return {group,tick(now,{pressure=.3,roll=false}={}){\r\n    const quiet=still();\r\n    if(now>=next||roll){next=now+140;angle+=.9;pupils.forEach((e,i)=>{const k=quiet?.5:roll?1:(.4+pressure*.6);\r\n      if(quiet)e.target.set(k,0);else if(roll)e.target.set(Math.cos(angle+i*2.4),Math.sin(angle+i*2.4));else e.target.set((Math.random()*2-1)*k,(Math.random()*2-1)*k);});}\r\n    // Pupils ride the eye's local +Y; they slide in local X/Z.\r\n    pupils.forEach(e=>{e.p.position.x+=(e.rest.x+e.target.x*e.room-e.p.position.x)*.5;e.p.position.z+=(e.rest.z+e.target.y*e.room-e.p.position.z)*.5;});\r\n  }};\r\n}\r\nexport const loadCoach=THREE=>loadCoachParts().then(parts=>buildCoach(THREE,parts));\r\n","arcade/runner/coach-hand.mjs":"// Copied from the site (tv/assets/armie-intro/coach-hand.mjs): the 2D clay Coach Armie used for the chase lunge.\r\n// Coach Armie: severed purple clay forearm, pointy face, two mismatched googly eyes, torn stump with gold bone.\r\n// Drawn lying down, face to the right. Rotate the returned element to point him elsewhere.\r\nlet uid=0;\r\nconst reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches||!!document.querySelector('#ar.ar-motion-off');\r\nexport function coachHand({size=48}={}){\r\n  const id='ch'+(++uid);\r\n  const el=document.createElement('span');el.className='ar-coach-hand';el.style.setProperty('--ch-size',size+'px');el.setAttribute('aria-hidden','true');\r\n  el.innerHTML=`<svg viewBox=\"0 0 132 64\" width=\"${size}\" height=\"${Math.round(size*64/132)}\">\r\n<defs>\r\n<filter id=\"${id}c\" x=\"-10%\" y=\"-20%\" width=\"120%\" height=\"140%\"><feTurbulence type=\"fractalNoise\" baseFrequency=\".85\" numOctaves=\"2\" seed=\"7\" result=\"n\"/><feDisplacementMap in=\"SourceGraphic\" in2=\"n\" scale=\"2.2\"/></filter>\r\n<filter id=\"${id}t\"><feTurbulence type=\"fractalNoise\" baseFrequency=\".22\" numOctaves=\"3\" seed=\"3\"/><feColorMatrix values=\"0 0 0 0 .32  0 0 0 0 .16  0 0 0 0 .4  0 0 0 -2.2 1.25\"/><feComposite in2=\"SourceGraphic\" operator=\"in\"/></filter>\r\n<radialGradient id=\"${id}g\" cx=\"55%\" cy=\"28%\" r=\"80%\"><stop offset=\"0\" stop-color=\"#b07acc\"/><stop offset=\".45\" stop-color=\"#8e5b99\"/><stop offset=\"1\" stop-color=\"#512866\"/></radialGradient>\r\n<radialGradient id=\"${id}w\" cx=\"50%\" cy=\"50%\" r=\"60%\"><stop offset=\"0\" stop-color=\"#cc518e\"/><stop offset=\".6\" stop-color=\"#660044\"/><stop offset=\"1\" stop-color=\"#330022\"/></radialGradient>\r\n<clipPath id=\"${id}k\"><path d=\"M14 13 Q40 7 66 16 Q76 12 96 14 Q108 16 128 31 Q130 34 126 36 Q112 42 102 47 Q100 57 92 58 Q90 52 86 50 Q76 52 66 48 Q40 57 14 52 Z\"/></clipPath>\r\n</defs>\r\n<ellipse cx=\"66\" cy=\"58\" rx=\"56\" ry=\"5\" fill=\"#281433\" opacity=\".55\"/>\r\n<g filter=\"url(#${id}c)\">\r\n<path d=\"M14 13 Q40 7 66 16 Q76 12 96 14 Q108 16 128 31 Q130 34 126 36 Q112 42 102 47 Q100 57 92 58 Q90 52 86 50 Q76 52 66 48 Q40 57 14 52 Z\" fill=\"url(#${id}g)\"/>\r\n<path d=\"M100 20 L126 31 M100 29 L128 33 M100 38 L125 35 M66 17 Q64 32 66 47\" stroke=\"#512866\" stroke-width=\"1.6\" stroke-linecap=\"round\" fill=\"none\" opacity=\".7\"/>\r\n<path d=\"M14 16 L9 22 L13 27 L7 33 L12 38 L8 45 L14 50 Q20 34 14 16 Z\" fill=\"url(#${id}w)\"/>\r\n<rect x=\"1\" y=\"29\" width=\"15\" height=\"6\" rx=\"3\" fill=\"#d4a017\"/><circle cx=\"2.5\" cy=\"28.5\" r=\"3.2\" fill=\"#e8b33a\"/><circle cx=\"2.5\" cy=\"35.5\" r=\"3.2\" fill=\"#e8b33a\"/>\r\n<path d=\"M12 45 q2 6 -1 11 M17 49 q1 4 -1 7\" stroke=\"#660044\" stroke-width=\"2.4\" stroke-linecap=\"round\" fill=\"none\"/>\r\n<rect x=\"12\" y=\"6\" width=\"118\" height=\"54\" fill=\"#000\" filter=\"url(#${id}t)\" opacity=\".5\" clip-path=\"url(#${id}k)\"/>\r\n</g>\r\n<g fill=\"none\" stroke=\"#512866\" stroke-width=\".8\" opacity=\".55\"><ellipse cx=\"42\" cy=\"24\" rx=\"7\" ry=\"4.5\"/><ellipse cx=\"42\" cy=\"24\" rx=\"4.5\" ry=\"2.7\"/><ellipse cx=\"42\" cy=\"24\" rx=\"2\" ry=\"1.1\"/><ellipse cx=\"64\" cy=\"44\" rx=\"6\" ry=\"3.6\"/><ellipse cx=\"64\" cy=\"44\" rx=\"3.4\" ry=\"2\"/><ellipse cx=\"28\" cy=\"38\" rx=\"5\" ry=\"3.3\"/><ellipse cx=\"28\" cy=\"38\" rx=\"2.4\" ry=\"1.5\"/></g>\r\n<g stroke=\"#7d6a58\" stroke-width=\"1\" stroke-linecap=\"round\" opacity=\".85\"><path d=\"M34 13 l-3 -6 M36 13 l1 -7 M38 14 l4 -6\"/><path d=\"M58 51 l-2 6 M60 51 l2 6\"/><path d=\"M96 16 l3 -5 M98 17 l5 -4\"/></g>\r\n<g class=\"ch-eye\"><circle cx=\"86\" cy=\"24\" r=\"10\" fill=\"#fffdf6\" stroke=\"#281433\" stroke-width=\"1.4\"/><circle class=\"ch-pupil\" cx=\"86\" cy=\"24\" r=\"5\" fill=\"#120a14\"/><circle cx=\"82.5\" cy=\"20\" r=\"2\" fill=\"#fff\" opacity=\".85\"/></g>\r\n<g class=\"ch-eye\"><circle cx=\"100\" cy=\"39\" r=\"6\" fill=\"#fffdf6\" stroke=\"#281433\" stroke-width=\"1.2\"/><circle class=\"ch-pupil\" cx=\"100\" cy=\"39\" r=\"3\" fill=\"#120a14\"/><circle cx=\"98\" cy=\"36.6\" r=\"1.2\" fill=\"#fff\" opacity=\".85\"/></g>\r\n</svg>`;\r\n  const eyes=[...el.querySelectorAll('.ch-pupil')].map((p,i)=>({p,cx:i?100:86,cy:i?39:24,r:i?6:10}));\r\n  let pressure=.3,roll=false,angle=0,seen=false;\r\n  function draw(){\r\n    const still=reduced();angle+=roll?.9:0;\r\n    for(const [i,e] of eyes.entries()){\r\n      const pr=e.r*(.32+.36*pressure),room=e.r-pr-.8;\r\n      let dx,dy;\r\n      if(roll&&!still){dx=Math.cos(angle+i*2.4)*room;dy=Math.sin(angle+i*2.4)*room;}\r\n      else if(still){dx=room*.5;dy=0;}\r\n      else{dx=(Math.random()*2-1)*room*(.4+pressure*.6);dy=(Math.random()*2-1)*room*(.4+pressure*.6);}\r\n      e.p.setAttribute('r',pr.toFixed(2));e.p.setAttribute('cx',(e.cx+dx).toFixed(2));e.p.setAttribute('cy',(e.cy+dy).toFixed(2));\r\n    }\r\n  }\r\n  const timer=setInterval(()=>{if(el.isConnected)seen=true;else if(seen){clearInterval(timer);return;}if(seen)draw();},140);\r\n  draw();\r\n  el.coach={pressure(p){pressure=Math.max(0,Math.min(1,p));},roll(on){roll=!!on;},destroy(){clearInterval(timer);}};\r\n  return el;\r\n}\r\n","arcade/runner/maze-run.mjs":"// Cardio runner rules, copied from the site's Coach Armie maze (tv/assets/armie-intro/maze-run.mjs) and made endless:\r\n// three lanes, the same three full-width traps and the 90 degree turn; no doors, no questions, no tap boost.\r\n// Cool Cardio: courses chain forever, each harder (more traps, tighter spacing, combos later) at one constant speed.\r\n// A hit is a stumble, never the end: brief slow-down and coach pressure up; pressure decays as you clear traps.\r\n// Only stopping ends it: with no jogging the speed ramps to 0 over STOP.seconds while Coach closes in from behind;\r\n// a full STOP.seconds still and he catches you (status 'caught'). Jogging again ramps back to full speed.\r\nexport const LANES = [-1.25, 0, 1.25];\r\nexport const TRAPS = ['grid', 'platform', 'pit'];\r\nexport const PIT_LENGTH = 7;\r\nexport const STOP = {seconds:10, warn:5, rampUp:2}; // still seconds until caught; clay warning; seconds from 0 back to full speed\r\nexport const STUMBLE = {seconds:.9, slow:.3, pressure:.22, clearRelief:.07, decay:.012, floor:.08};\r\nconst START = 12, RUNOUT = 14, MIN_GAP_S = 1.5;\r\nexport function rng(seed){let a=(seed*2654435761+1013904223)>>>0;return()=>{a=(a+0x6D2B79F5)>>>0;let t=a;t=Math.imul(t^t>>>15,t|1);t^=t+Math.imul(t^t>>>7,t|61);return((t^t>>>14)>>>0)/4294967296;};}\r\n// Treadmill rule (Ian, R-1017): run speed is ONE constant. It never scales with effort or level; halls get harder by traps.\r\n// JUMP is floaty: long hang time, soft gravity (pow<1 flattens the top of the arc).\r\nexport const RUN = {speed:5};\r\nexport const JUMP = {seconds:1.5, peak:1.35, float:.5};\r\nexport const courseSpeed = () => RUN.speed;\r\nexport const trapCount = level => Math.min(18, 5 + level);\r\nexport const gapSeconds = level => Math.max(MIN_GAP_S, 3.2 - .13*level);\r\nexport const comboChance = level => level < 2 ? 0 : Math.min(.55, .12*(level-1));\r\n// One course. Gaps are in seconds at that course's speed, so a full-pace runner always has the same reaction time.\r\nexport function courseFor(seed = 0, level = 0) {\r\n  const r=rng(seed), count=trapCount(level), types=[...TRAPS], speed=courseSpeed(level);\r\n  while(types.length<count) types.push(TRAPS[Math.floor(r()*3)]);\r\n  for(let i=types.length-1;i>0;i--){const j=Math.floor(r()*(i+1));[types[i],types[j]]=[types[j],types[i]];}\r\n  const events=[], turnAfter=Math.floor(count/2)-1, direction=r()<.5?'left':'right';\r\n  let at=START, prev=null;\r\n  for(let i=0;i<count;i++){\r\n    let type=types[i];\r\n    // Combo: a pit straight into a grid or platform at the minimum gap (mixed combos only on later courses).\r\n    const combo=prev==='pit'&&r()<comboChance(level);\r\n    if(combo&&type==='pit') type=r()<.5?'grid':'platform';\r\n    const e=type==='pit'?{type,at,length:PIT_LENGTH}:{type,at};if(combo)e.combo=true;\r\n    events.push(e);\r\n    at+=(e.length||0)+speed*((combo||events.length>1&&events[events.length-2].combo)?MIN_GAP_S:gapSeconds(level)*(1+r()*.25));\r\n    if(i===turnAfter){events.push({type:'turn',at,direction});at+=speed*gapSeconds(level);}\r\n    prev=type;\r\n  }\r\n  // Combo gap applies to the trap after the pit; recompute positions so it is exact.\r\n  for(let i=1;i<events.length;i++){const e=events[i],p=events[i-1];if(e.combo)e.at=p.at+(p.length||0)+speed*MIN_GAP_S;else if(e.at<p.at+(p.length||0)+speed*MIN_GAP_S)e.at=p.at+(p.length||0)+speed*MIN_GAP_S;}\r\n  const last=events[events.length-1], turn=events.find(e=>e.type==='turn');\r\n  return {seed, level, events, length:last.at+(last.length||0)+RUNOUT, turnAt:turn.at, direction};\r\n}\r\nconst courseSeed=(seed,n)=>(seed+n*977)>>>0;\r\nfunction load(run){\r\n  run.course=courseFor(courseSeed(run.seed,run.courses),run.level);\r\n  run.events=run.course.events.map(e=>({...e,cleared:false}));run.turn=null;\r\n}\r\nexport function createRun(seed = 0) {\r\n  const run={seed, courses:0, level:0, distance:0, total:0, time:0, lane:1, jumpTime:0, height:0, slideTime:0, duck:0, turn:null,\r\n    jogging:false, started:false, gait:0, still:0, chase:0, warned:false, stumble:0, pressure:STUMBLE.floor, hits:0, cleared:0, paused:false, status:'running', feed:[], course:null, events:[]};\r\n  load(run);return run;\r\n}\r\n// Next course in the chain, one step harder.\r\nexport function chain(run) {\r\n  run.courses++;run.level++;load(run);run.distance=0;run.feed.push({type:'course',level:run.level,courses:run.courses});\r\n}\r\nexport function runSpeed(run){\r\n  return courseSpeed(run.level)*run.gait*(run.stumble>0?STUMBLE.slow:1);\r\n}\r\nexport function upcoming(run) { return run.events.find(e=>!e.cleared) || null; }\r\nexport function input(run, action) {\r\n  if(run.status !== 'running' || run.paused) return;\r\n  if(action === 'jump') { if(run.jumpTime === 0 && run.slideTime === 0) run.jumpTime = JUMP.seconds; return; }\r\n  if(action === 'slide') { if(run.jumpTime === 0 && run.slideTime === 0) run.slideTime = .96; return; }\r\n  if(action !== 'left' && action !== 'right') return;\r\n  const next=upcoming(run);\r\n  if(next?.type==='turn' && next.at-run.distance <= 11) run.turn=action;\r\n  else run.lane=Math.max(0,Math.min(LANES.length-1,run.lane+(action==='left'?-1:1)));\r\n}\r\nexport function safe(run, event) {\r\n  if(event.type==='turn') return run.turn===event.direction;\r\n  if(event.type==='grid') return run.duck>.8 && run.height<.1;\r\n  if(event.type==='platform') return run.height>.65;\r\n  return run.lane!==1; // pit: only the two wall ledges hold you\r\n}\r\n// A stumble from a trap or an unhit projectile: slow-down and pressure, never the end.\r\nexport function stumble(run, event) {\r\n  if(run.status!=='running')return;\r\n  event.cleared=true;run.hits++;run.stumble=STUMBLE.seconds;run.pressure=Math.min(1,run.pressure+STUMBLE.pressure);\r\n  if(event.type==='turn')run.turn=null;\r\n  run.feed.push({type:'stumble',trap:event.type,pressure:run.pressure});\r\n}\r\nexport function step(run, delta) {\r\n  if(run.paused||run.status!=='running')return;\r\n  const dt=Math.max(0,Math.min(delta,.05));\r\n  run.time+=dt;\r\n  run.jumpTime=Math.max(0,run.jumpTime-dt);\r\n  run.slideTime=Math.max(0,run.slideTime-dt);\r\n  run.stumble=Math.max(0,run.stumble-dt);\r\n  run.pressure=Math.max(STUMBLE.floor,run.pressure-STUMBLE.decay*dt);\r\n  // Gait: full while jogging (ramping back up), a straight ramp to 0 over STOP.seconds of stillness; caught at the end.\r\n  // The stop clock starts with the first jog step (calibration and setup never count).\r\n  if(run.jogging)run.started=true;\r\n  if(run.jogging){run.still=0;run.warned=false;run.gait=Math.min(1,run.gait+dt/STOP.rampUp);run.chase=Math.max(0,run.chase-dt*.25);}\r\n  else if(run.started){run.still+=dt;run.gait=Math.min(run.gait,Math.max(0,1-run.still/STOP.seconds));run.chase=Math.max(run.chase,Math.min(1,run.still/STOP.seconds));\r\n    if(!run.warned&&run.still>=STOP.warn){run.warned=true;run.feed.push({type:'warn'});}\r\n    if(run.still>=STOP.seconds-1e-6){run.status='caught';run.feed.push({type:'caught'});return;}}\r\n  run.duck=run.slideTime>0?Math.min(1,(.96-run.slideTime)/.1,run.slideTime/.12):0;\r\n  run.height=run.jumpTime>0?Math.pow(Math.sin((1-run.jumpTime/JUMP.seconds)*Math.PI),JUMP.float)*JUMP.peak:0;\r\n  const next=upcoming(run), move=runSpeed(run)*dt;\r\n  run.distance+=move;run.total+=move;\r\n  // The pit is checked on every step while you are over it, not only at its lip.\r\n  if(next && run.distance>=next.at) {\r\n    if(!safe(run,next)) stumble(run,next);\r\n    else if(run.distance>=next.at+(next.length||0)){next.cleared=true;run.cleared++;run.pressure=Math.max(STUMBLE.floor,run.pressure-STUMBLE.clearRelief);if(next.type==='turn') run.turn=null;run.feed.push({type:'clear',trap:next.type});}\r\n  }\r\n  if(run.distance>=run.course.length)chain(run);\r\n}\r\n// World route turns a real 90 degrees at the course's turn, then continues down the next corridor.\r\nexport function pathAt(distance, course) {\r\n  const d=Math.max(0,distance),T=course.turnAt;\r\n  if(T==null||d<=T)return {x:0,z:-d,yaw:0};\r\n  const sign=course.direction==='right'?1:-1;\r\n  return {x:sign*(d-T),z:-T,yaw:-sign*Math.PI/2};\r\n}\r\n","arcade/runner/maze-scene.mjs":"// Runner corridor, copied from the site's Coach Armie maze (tv/assets/armie-intro/maze-scene.js) on the app's vendored three r169.\r\n// Changes: endless courses (no junction bay or doors), variable length and turn point, and a theme per course\r\n// (wall texture style, neon colours, the view out of the windows). Gore/bone props only in the horror theme.\r\nimport {pathAt,LANES,runSpeed} from './maze-run.mjs';\r\nimport {themeFor} from './themes.mjs';\r\n\r\n// MOM Inc propaganda for trap boards: never instructions, never arrows.\r\nconst SIGNS=[['MOM INC','LOVES YOU'],['REST HERE','MOM IS PROUD'],['NO ONE','LEAVES MOM'],['COME HOME','BABY'],['MOM SEES','EVERYTHING'],['YOU ARE','ALREADY HERS'],['OBEY','MOM INC']];\r\nconst R=2.4,CY=1.55,SEG=16,TAU=Math.PI*2; // tube radius, axis height, radial segments\r\nconst rgba=(rgb,a)=>`rgba(${rgb},${a})`;\r\n// Hull tile painters: the site's gunmetal plate plus rust, clean lab panels and hex panels.\r\nfunction paintWall(g,w,h,s){\r\n  const base=g.createLinearGradient(0,0,w,h);base.addColorStop(0,s.from);base.addColorStop(1,s.to);g.fillStyle=base;g.fillRect(0,0,w,h);\r\n  const rivets=(fill,shine)=>{for(const x of [18,w/2,w-14])for(const y of [18,h/2-10,h/2+12,h-14]){g.fillStyle=fill;g.beginPath();g.arc(x,y,5,0,TAU);g.fill();g.fillStyle=shine;g.beginPath();g.arc(x-1,y-1,3,0,TAU);g.fill();}};\r\n  const seams=(dark,light)=>{g.fillStyle=dark;g.fillRect(0,0,w,5);g.fillRect(0,0,5,h);g.fillStyle=light;g.fillRect(0,5,w,2);g.fillRect(5,0,2,h);};\r\n  const grime=a=>{const r=g.createRadialGradient(w*.7,h*.8,10,w*.7,h*.8,w*.6);r.addColorStop(0,rgba(s.grime,a));r.addColorStop(1,rgba(s.grime,0));g.fillStyle=r;g.fillRect(0,0,w,h);};\r\n  const streaks=(n,a)=>{for(let i=0;i<n;i++){const x=Math.random()*w,y=Math.random()*h*.6,len=30+Math.random()*120;const gr=g.createLinearGradient(0,y,0,y+len);gr.addColorStop(0,rgba(s.grime,a));gr.addColorStop(1,rgba(s.grime,0));g.fillStyle=gr;g.fillRect(x,y,3+Math.random()*10,len);}};\r\n  if(s.style==='lab'){\r\n    g.strokeStyle='rgba(120,135,160,.55)';g.lineWidth=2;g.strokeRect(1,1,w-2,h-2);g.beginPath();g.moveTo(w/2,0);g.lineTo(w/2,h);g.moveTo(0,h/2);g.lineTo(w,h/2);g.stroke();\r\n    g.fillStyle='rgba(255,255,255,.6)';g.fillRect(4,4,w/2-8,3);g.fillRect(w/2+4,h/2+4,w/2-8,3);\r\n    for(const [x,y] of [[w*.25,h*.75],[w*.75,h*.25]]){g.fillStyle='#2a3448';g.fillRect(x-14,y-5,28,10);g.fillStyle='#3cf2d8';g.fillRect(x-11,y-2,8,4);}\r\n    streaks(4,.08);grime(.12);return;\r\n  }\r\n  if(s.style==='hex'){\r\n    const r=22,hh=Math.sqrt(3)*r;\r\n    for(let row=-1;row*hh<h+hh;row++)for(let col=-1;col*r*1.5<w+r;col++){\r\n      const cx=col*r*1.5,cy=row*hh+(col%2?hh/2:0);g.beginPath();for(let k=0;k<6;k++){const a=k*Math.PI/3;g[k?'lineTo':'moveTo'](cx+Math.cos(a)*(r-2),cy+Math.sin(a)*(r-2));}g.closePath();\r\n      g.fillStyle=Math.random()<.12?'rgba(255,255,255,.08)':'rgba(0,0,0,.18)';g.fill();g.strokeStyle='rgba(0,0,0,.6)';g.lineWidth=3;g.stroke();g.strokeStyle='rgba(255,255,255,.12)';g.lineWidth=1;g.stroke();\r\n    }\r\n    grime(.35);return;\r\n  }\r\n  for(let i=0;i<900;i++){g.fillStyle='rgba('+(Math.random()<.5?'255,255,255':'0,0,0')+','+(Math.random()*.05)+')';g.fillRect(Math.random()*w,Math.random()*h,2+Math.random()*6,1);}\r\n  if(s.style==='rust')for(let i=0;i<70;i++){g.fillStyle=`rgba(${150+Math.random()*80|0},${60+Math.random()*40|0},${10+Math.random()*20|0},${.15+Math.random()*.3})`;g.beginPath();g.ellipse(Math.random()*w,Math.random()*h,3+Math.random()*16,2+Math.random()*9,Math.random()*3,0,TAU);g.fill();}\r\n  streaks(s.style==='rust'?26:14,.35);\r\n  g.strokeStyle='rgba(230,225,240,.18)';g.lineWidth=1;for(let i=0;i<10;i++){g.beginPath();const x=Math.random()*w,y=Math.random()*h;g.moveTo(x,y);g.lineTo(x+Math.random()*40-20,y+Math.random()*12);g.stroke();}\r\n  seams('#16121b','rgba(220,210,235,.35)');g.fillStyle='rgba(16,10,20,.55)';g.fillRect(0,h/2-1,w,2);\r\n  rivets(s.style==='rust'?'#2a1408':'#2a2430',s.style==='rust'?'#a0603a':'#b9b2c4');grime(.35);\r\n}\r\n\r\nexport function createMazeScene(THREE,theme=themeFor){\r\n  const themeAt=typeof theme==='function'?theme:()=>theme;\r\n  const scene=new THREE.Scene();scene.background=new THREE.Color('#040208');scene.fog=new THREE.Fog('#0c0712',14,48);\r\n  const hemi=new THREE.HemisphereLight('#a898c0','#1c1222',.6);scene.add(hemi);\r\n  const lamp=new THREE.PointLight('#ffd49a',9,12,1.6),ahead=new THREE.PointLight('#ffc77a',14,18,1.6),alarm=new THREE.PointLight('#ff2030',0,16,1.4),pitLight=new THREE.PointLight('#ff3a14',0,9,1.4),fill=new THREE.PointLight('#b9a8e8',2.2,22,1.2);\r\n  scene.add(lamp,ahead,alarm,pitLight,fill);\r\n  const camera=new THREE.PerspectiveCamera(72,1,.06,160);\r\n  const material=(color,metalness=.4,roughness=.5)=>new THREE.MeshStandardMaterial({color,metalness,roughness});\r\n  const canvasTex=(w,h,draw)=>{const c=document.createElement('canvas');c.width=w;c.height=h;draw(c.getContext('2d'),w,h);const t=new THREE.CanvasTexture(c);t.colorSpace=THREE.SRGBColorSpace;return t;};\r\n  // One hull tile, repainted per theme. Every clone shares its canvas, so each is flagged for upload on a repaint.\r\n  const plateTex=canvasTex(256,256,()=>{});\r\n  plateTex.wrapS=plateTex.wrapT=THREE.RepeatWrapping;plateTex.anisotropy=4;\r\n  const metals=[];\r\n  const metal=(rx,ry,opts={})=>{const map=plateTex.clone();map.repeat.set(rx,ry);map.needsUpdate=true;const {shade,...own}=opts,m=new THREE.MeshStandardMaterial({map,color:'#aaa2b6',metalness:.75,roughness:.4,...own});metals.push({m,opts});return m;};\r\n  const hull=metal(16,1,{side:THREE.BackSide}),hullArc=metal(6,1,{side:THREE.BackSide}),hullPit=metal(12,1,{side:THREE.BackSide});\r\n  const plate=metal(1,1,{side:THREE.DoubleSide});\r\n  const wall=metal(6,4.6),deck=metal(4,1,{shade:.92,metalness:.6,roughness:.22}),ledge=metal(1.5,4,{shade:.92,metalness:.6,roughness:.3});\r\n  const inset=material('#1a1620',.7,.4),gold=material('#bb9354',.8,.3),black=material('#0b080e',.3,.6),bone=material('#d4a017',.55,.35),gore=material('#4a0a34',.1,.32);\r\n  const glow=color=>new THREE.MeshBasicMaterial({color,toneMapped:false});\r\n  const warm=glow('#ffe6b0'),cyan=glow('#79e8ff'),red=glow('#ff593e'),amber=glow('#ffb44a');\r\n  // Animated materials (shared, so batching keeps working): two strobing light banks, emergency strips, lasers, blades.\r\n  const strobeA=glow('#ffe6b0'),strobeB=glow('#ffe6b0'),emergency=glow('#ff1e2e'),laser=glow('#ff4fd8'),blade=glow('#ff5a1e');blade.side=THREE.DoubleSide;const pitFloor=glow('#6a0e06');\r\n  const steel=new THREE.MeshStandardMaterial({color:'#3a2a2e',metalness:.85,roughness:.3,emissive:'#ff2a00',emissiveIntensity:.35,side:THREE.DoubleSide});\r\n  const hum=new THREE.MeshBasicMaterial({color:'#ff3fc8',transparent:true,opacity:.18,blending:THREE.AdditiveBlending,depthWrite:false,toneMapped:false,side:THREE.DoubleSide});\r\n  const haze=new THREE.MeshBasicMaterial({color:'#ff2a1a',transparent:true,opacity:.28,blending:THREE.AdditiveBlending,depthWrite:false,toneMapped:false,side:THREE.DoubleSide});\r\n  const hazardTex=canvasTex(256,64,(g,w,h)=>{g.fillStyle='#120c08';g.fillRect(0,0,w,h);g.fillStyle='#d4a017';for(let x=-h;x<w+h;x+=48){g.beginPath();g.moveTo(x,h);g.lineTo(x+24,h);g.lineTo(x+24+h,0);g.lineTo(x+h,0);g.fill();}});\r\n  hazardTex.wrapS=THREE.RepeatWrapping;hazardTex.repeat.set(3,1);const hazard=new THREE.MeshStandardMaterial({map:hazardTex,metalness:.4,roughness:.5});\r\n  const splatTex=canvasTex(256,256,(g)=>{for(let i=0;i<46;i++){const a=Math.random()*TAU,r=Math.random()**2*96,s=6+Math.random()*(34-r/4);g.fillStyle=i%5?'rgba(102,0,68,.92)':'rgba(58,0,38,.95)';g.beginPath();g.ellipse(128+Math.cos(a)*r,128+Math.sin(a)*r,s,s*(.5+Math.random()*.5),a,0,TAU);g.fill();}});\r\n  const splat=new THREE.MeshStandardMaterial({map:splatTex,transparent:true,depthWrite:false,roughness:.18,metalness:.1,polygonOffset:true,polygonOffsetFactor:-2});\r\n  // Space outside the windows: a drifting star shell plus the theme's set piece, all following the camera so they read as infinitely far.\r\n  const sky=new THREE.Group();scene.add(sky);const vista=new THREE.Group();sky.add(vista);\r\n  const starGeo=new THREE.BufferGeometry(),starPos=new Float32Array(1600*3);\r\n  for(let i=0;i<1600;i++){const u=Math.random()*2-1,a=Math.random()*TAU,s=Math.sqrt(1-u*u);starPos.set([Math.cos(a)*s*110,u*110,Math.sin(a)*s*110],i*3);}\r\n  starGeo.setAttribute('position',new THREE.BufferAttribute(starPos,3));\r\n  const stars=new THREE.Points(starGeo,new THREE.PointsMaterial({color:'#e8e2ff',size:1.6,sizeAttenuation:false,fog:false,toneMapped:false}));sky.add(stars);\r\n  const billboard=(tex,size,x,y,z,additive=false)=>{const m=new THREE.Mesh(new THREE.PlaneGeometry(size,size*tex.image.height/tex.image.width),new THREE.MeshBasicMaterial({map:tex,transparent:true,fog:false,depthWrite:false,toneMapped:false,...(additive?{blending:THREE.AdditiveBlending}:{})}));m.position.set(x,y,z);m.lookAt(0,0,0);vista.add(m);return m;};\r\n  const ball=(g,cx,cy,r,[c0,c1,c2])=>{const q=g.createRadialGradient(cx-r*.25,cy-r*.3,r*.06,cx,cy,r);q.addColorStop(0,c0);q.addColorStop(.45,c1);q.addColorStop(.85,c2);q.addColorStop(1,'rgba(0,0,0,0)');g.fillStyle=q;g.beginPath();g.arc(cx,cy,r,0,TAU);g.fill();};\r\n  const blob=(color,size=128)=>canvasTex(size,size,(g)=>{const q=g.createRadialGradient(size/2,size/2,0,size/2,size/2,size/2);q.addColorStop(0,color);q.addColorStop(1,'rgba(0,0,0,0)');g.fillStyle=q;g.fillRect(0,0,size,size);});\r\n  const VISTAS={\r\n    planet(s){billboard(canvasTex(256,256,(g)=>{ball(g,128,128,128,s.colors);g.globalAlpha=.25;g.fillStyle=s.bands;for(let y=70;y<200;y+=22)g.fillRect(20,y,216,5);}),48,-24,2,-92);\r\n      billboard(canvasTex(64,64,(g)=>ball(g,32,32,32,['#ffffff','#9a96a8','#2a2830'])),12,22,-4,-94);},\r\n    nebula(s){s.colors.forEach((c,i)=>{const a=[-.3,.26,-.18,.34][i%4]-Math.PI/2;billboard(blob(c),50+i*10,Math.cos(a)*95,(i%2?8:-8),Math.sin(a)*95,true).material.opacity=.6;});\r\n      s.colors.forEach((c,i)=>{billboard(blob(c,64),20,[-26,20,-16,30][i%4],i*5-8,-90,true).material.opacity=.75;});},\r\n    rings(s){billboard(canvasTex(512,256,(g)=>{const ring=(start,end)=>{g.strokeStyle=s.ring;g.globalAlpha=.75;g.lineWidth=14;g.beginPath();g.ellipse(256,128,230,46,-.18,start,end);g.stroke();g.globalAlpha=.35;g.lineWidth=6;g.beginPath();g.ellipse(256,128,200,38,-.18,start,end);g.stroke();g.globalAlpha=1;};\r\n      ring(Math.PI,TAU);ball(g,256,128,96,s.colors);g.globalAlpha=.2;g.fillStyle=s.colors[2];for(let y=64;y<200;y+=16)g.fillRect(170,y,172,5);g.globalAlpha=1;ring(0,Math.PI);}),70,-26,0,-92);},\r\n    asteroids(s){const geo=new THREE.DodecahedronGeometry(1,0),mat=new THREE.MeshStandardMaterial({color:s.rock,emissive:s.rock,emissiveIntensity:.35,roughness:.95,flatShading:true,fog:false});\r\n      for(let i=0;i<70;i++){const a=-Math.PI/2+((i*.618)%1-.5)*.9,r=30+(i*37%50),m=new THREE.Mesh(geo,mat);m.position.set(Math.cos(a)*r,(((i*53)%30)-15)*r/60,Math.sin(a)*r);m.scale.set(.5+(i%5)*.5,.4+(i%3)*.4,.5+(i%4)*.4);m.rotation.set(i,i*.7,i*.3);m.userData.spin=.1+(i%7)*.05;vista.add(m);}\r\n      billboard(blob('#ff9a4a'),50,-24,4,-92,true).material.opacity=.45;},\r\n    earth(){billboard(canvasTex(512,512,(g)=>{const glowG=g.createRadialGradient(256,256,180,256,256,256);glowG.addColorStop(0,'rgba(120,190,255,.9)');glowG.addColorStop(1,'rgba(60,120,255,0)');g.fillStyle=glowG;g.fillRect(0,0,512,512);\r\n      g.save();g.beginPath();g.arc(256,256,200,0,TAU);g.clip();const sea=g.createRadialGradient(200,190,20,256,256,200);sea.addColorStop(0,'#3a8ad8');sea.addColorStop(1,'#08204a');g.fillStyle=sea;g.fillRect(0,0,512,512);\r\n      for(let i=0;i<26;i++){g.fillStyle=i%3?'#3a7a3a':'#8a7a4a';g.beginPath();g.ellipse(80+(i*97%360),80+(i*61%360),18+(i*13%40),10+(i*7%26),i,0,TAU);g.fill();}\r\n      g.fillStyle='rgba(255,255,255,.55)';for(let i=0;i<40;i++){g.beginPath();g.ellipse(60+(i*71%400),60+(i*113%400),20+(i*11%40),5+(i*3%8),i*.4,0,TAU);g.fill();}\r\n      const night=g.createLinearGradient(120,0,440,0);night.addColorStop(0,'rgba(0,0,10,0)');night.addColorStop(1,'rgba(0,0,10,.85)');g.fillStyle=night;g.fillRect(0,0,512,512);g.restore();}),90,-26,-10,-90);\r\n      billboard(canvasTex(64,64,(g)=>ball(g,32,32,32,['#ffffff','#b0b0b8','#3a3a40'])),9,22,6,-94);},\r\n    redstar(s){billboard(canvasTex(256,256,(g)=>{const q=g.createRadialGradient(128,128,8,128,128,128);q.addColorStop(0,s.colors[0]);q.addColorStop(.25,s.colors[1]);q.addColorStop(.6,s.colors[2]);q.addColorStop(1,'rgba(0,0,0,0)');g.fillStyle=q;g.fillRect(0,0,256,256);\r\n      g.globalAlpha=.25;g.strokeStyle=s.colors[1];for(let i=0;i<24;i++){const a=i/24*TAU;g.lineWidth=2+i%3;g.beginPath();g.moveTo(128+Math.cos(a)*40,128+Math.sin(a)*40);g.lineTo(128+Math.cos(a)*(90+i%5*8),128+Math.sin(a)*(90+i%5*8));g.stroke();}}),80,24,2,-92,true);\r\n      billboard(blob('#ff3a1a'),70,-26,-4,-90,true).material.opacity=.5;},\r\n  };\r\n  // Dust and sparks: 300 motes respawned ahead along the path.\r\n  const DUST=300,dustGeo=new THREE.BufferGeometry(),dustPos=new Float32Array(DUST*3),dust=[];\r\n  dustGeo.setAttribute('position',new THREE.BufferAttribute(dustPos,3));\r\n  const motes=new THREE.Points(dustGeo,new THREE.PointsMaterial({color:'#ffcf8a',size:.022,map:canvasTex(32,32,(g)=>{const r=g.createRadialGradient(16,16,0,16,16,16);r.addColorStop(0,'#fff');r.addColorStop(1,'rgba(255,255,255,0)');g.fillStyle=r;g.fillRect(0,0,32,32);}),transparent:true,opacity:.75,blending:THREE.AdditiveBlending,depthWrite:false}));motes.frustumCulled=false;scene.add(motes);\r\n  // Tube pieces: unit-length open cylinders. Window pieces drop two side panels, pit pieces drop the bottom arc.\r\n  const arc=(start,count)=>new THREE.CylinderGeometry(R,R,1,count,1,true,start*TAU/SEG,count*TAU/SEG).rotateX(Math.PI/2);\r\n  const tubeGeo={solid:arc(0,SEG),window:[arc(-3,6),arc(5,6)],pit:arc(2,12)};\r\n  const ribGeo=new THREE.TorusGeometry(R-.04,.07,4,24);\r\n  let group=null,course=null,look=null,cameraLane=LANES[1],yaw=0,rotors=[],pitSpots=[],envLook=null;\r\n  const E=new THREE.Color(),LZ=new THREE.Color(),W=new THREE.Color();\r\n  function applyTheme(t){\r\n    if(look===t)return;look=t;\r\n    scene.background.set(t.bg);scene.fog.color.set(t.fog);hemi.color.set(t.hemi[0]);hemi.groundColor.set(t.hemi[1]);lamp.color.set(t.light);ahead.color.set(t.light);fill.color.set(t.light);\r\n    paintWall(plateTex.image.getContext('2d'),256,256,t.wall);\r\n    for(const {m,opts} of metals){m.map.needsUpdate=true;m.color.set(t.wall.tint).multiplyScalar(opts.shade??1);m.metalness=opts.metalness??t.wall.metalness;m.roughness=opts.roughness??t.wall.roughness;}\r\n    const n=t.neon;cyan.color.set(n.rail);warm.color.set(n.warm);red.color.set(n.red);amber.color.set(n.amber);blade.color.set(n.blade);\r\n    E.set(n.emergency);LZ.set(n.laser);W.set(n.warm);alarm.color.set(n.emergency);\r\n    for(const o of [...vista.children]){o.removeFromParent();o.geometry.dispose();o.material.map?.dispose();o.material.dispose();}\r\n    stars.material.color.set(t.sky.stars);VISTAS[t.sky.kind]?.(t.sky);\r\n  }\r\n  function box(w,h,d,mat,x,y,z,parent=group){const mesh=new THREE.Mesh(new THREE.BoxGeometry(w,h,d),mat);mesh.position.set(x,y,z);parent.add(mesh);return mesh;}\r\n  function label(lines,escape=false,w=2.25,h=.88){\r\n    const c=document.createElement('canvas');c.width=768;c.height=288;const g=c.getContext('2d');\r\n    const color=escape?'#ff7954':look?.neon.sign||'#ff85e5';g.fillStyle=escape?'#24110e':'#230d30';g.fillRect(0,0,c.width,c.height);\r\n    g.strokeStyle=color;g.lineWidth=5;g.shadowColor=color;g.shadowBlur=18;g.strokeRect(10,10,748,268);g.textAlign='center';g.fillStyle=color;\r\n    g.textBaseline='middle';\r\n    lines.forEach((text,i)=>{let size=i===0?80:62;g.font=`bold ${size}px monospace`;while(g.measureText(text).width>708){size--;g.font=`bold ${size}px monospace`;}g.fillText(text,384,144+(i-(lines.length-1)/2)*84);});\r\n    const map=new THREE.CanvasTexture(c);map.colorSpace=THREE.SRGBColorSpace;\r\n    const mesh=new THREE.Mesh(new THREE.PlaneGeometry(w,h),new THREE.MeshBasicMaterial({map,toneMapped:false}));mesh.userData.sign=lines.join(' / ');return mesh;\r\n  }\r\n  // A bulkhead plate with a round hatch cut where the tube meets a room.\r\n  function bulkhead(w,h,parent,x,z,rotation=0){\r\n    const s=new THREE.Shape();s.moveTo(-w/2,-.3);s.lineTo(w/2,-.3);s.lineTo(w/2,h);s.lineTo(-w/2,h);s.lineTo(-w/2,-.3);\r\n    const hole=new THREE.Path();hole.absarc(0,CY,R-.02,0,TAU,true);s.holes.push(hole);\r\n    const mesh=new THREE.Mesh(new THREE.ShapeGeometry(s,16),plate);mesh.position.set(x,0,z);mesh.rotation.y=rotation;parent.add(mesh);\r\n    const ring=new THREE.Mesh(new THREE.TorusGeometry(R-.02,.09,4,32),gold);ring.position.set(x,CY,z);ring.rotation.y=rotation;parent.add(ring);\r\n  }\r\n  // Local along-path placement that also works behind the start line.\r\n  const place=(d)=>d<0?{x:0,z:-d,yaw:0}:pathAt(d,course);\r\n  function onPath(d,parent=group){const p=place(d),part=new THREE.Group();part.position.set(p.x,0,p.z);part.rotation.y=p.yaw;parent.add(part);return part;}\r\n  function batchStaticBoxes(){\r\n    group.updateMatrixWorld(true);const batches=new Map();\r\n    group.traverse(mesh=>{\r\n      if(mesh.geometry?.type!=='BoxGeometry')return;\r\n      for(let p=mesh;p&&p!==group;p=p.parent)if(p.userData.dynamic)return;\r\n      if(!batches.has(mesh.material))batches.set(mesh.material,[]);batches.get(mesh.material).push(mesh);\r\n    });\r\n    for(const [mat,meshes] of batches){\r\n      const instances=new THREE.InstancedMesh(new THREE.BoxGeometry(1,1,1),mat,meshes.length);\r\n      meshes.forEach((mesh,i)=>{const {width,height,depth}=mesh.geometry.parameters;instances.setMatrixAt(i,mesh.matrixWorld.clone().multiply(new THREE.Matrix4().makeScale(width,height,depth)));mesh.removeFromParent();mesh.geometry.dispose();});\r\n      instances.computeBoundingSphere();group.add(instances);\r\n    }\r\n  }\r\n  // Instanced tube: one InstancedMesh per piece geometry, so the whole hull costs a handful of draw calls.\r\n  function instance(geo,mat,matrices){if(!matrices.length)return;const m=new THREE.InstancedMesh(geo,mat,matrices.length);matrices.forEach((x,i)=>m.setMatrixAt(i,x));m.computeBoundingSphere();group.add(m);}\r\n  function build(next,t){\r\n    if(group){group.traverse(o=>{if(o.isInstancedMesh)o.dispose();if(o.geometry&&!Object.values(tubeGeo).flat().includes(o.geometry)&&o.geometry!==ribGeo)o.geometry.dispose();if(o.userData.sign){o.material.map.dispose();o.material.dispose();}});scene.remove(group);}\r\n    course=next;applyTheme(t);group=new THREE.Group();scene.add(group);rotors=[];pitSpots=[];\r\n    const TURN=course.turnAt,sign=course.direction==='right'?1:-1,pits=course.events.filter(e=>e.type==='pit'),END=course.length+26,CORNER=3;\r\n    const inPit=d=>pits.some(e=>d>=e.at&&d<e.at+e.length),tube={solid:[],window:[],pit:[],rib:[]},nearTurn=d=>TURN!=null&&d+1>TURN-CORNER&&d<TURN+CORNER;\r\n    const mat=(p,y=CY)=>new THREE.Matrix4().compose(new THREE.Vector3(p.x,y,p.z),new THREE.Quaternion().setFromAxisAngle(new THREE.Vector3(0,1,0),p.yaw),new THREE.Vector3(1,1,1));\r\n    for(let d=-4;d<END;d++){\r\n      if(nearTurn(d))continue;\r\n      const p=place(d+.5),m=mat(p),cell=((d%8)+8)%8,win=cell>=2&&cell<=4&&!inPit(d);\r\n      (inPit(d)?tube.pit:win?tube.window:tube.solid).push(m);\r\n      if(d%4===0)tube.rib.push(mat(place(d)));\r\n      const part=onPath(d+.5);\r\n      // Deck strip, lane seams, cyan rails, wall-foot running lights.\r\n      if(!inPit(d)){box(4.2,.25,1.02,deck,0,-.14,0,part);for(const x of [-.625,.625])box(.03,.012,1.02,black,x,.003,0,part);}\r\n      for(const side of [-1,1]){box(.04,.035,1.02,cyan,side*1.72,.03,0,part);if(d%2===0)box(.07,.07,.07,amber,side*1.86,.36,0,part);}\r\n      // Red emergency strips high on both walls, square ceiling lights every 4 units (some strobe).\r\n      for(const side of [-1,1]){const a=side*Math.PI*.3,strip=box(.05,.05,1.02,emergency,Math.sin(a)*(R-.06),CY+Math.cos(a)*(R-.06),0,part);strip.rotation.z=-a;}\r\n      if(d%4===2)box(.9,.04,.9,[warm,strobeA,warm,strobeB][Math.abs(d/4|0)%4],0,CY+R-.12,0,part);\r\n      if(win)for(const side of [-1,1])for(const y of [-.94,.94]){const a=Math.PI/2+y*.42;box(.06,.06,1.02,cyan,side*Math.sin(a)*(R-.03),CY-Math.cos(a)*(R-.03),0,part);}\r\n      if(win&&cell===2)for(const side of [-1,1])for(const z of [.5,-2.5])box(.06,1.9,.08,gold,side*(R-.08),CY,z,part);\r\n    }\r\n    instance(tubeGeo.solid,hull,tube.solid);instance(tubeGeo.pit,hullPit,tube.pit);instance(ribGeo,gold,tube.rib);\r\n    for(const g of tubeGeo.window)instance(g,hullArc,tube.window);\r\n    const cap=new THREE.Mesh(new THREE.CircleGeometry(R,SEG),plate);cap.position.set(0,CY,4);group.add(cap);\r\n    if(TURN!=null){\r\n    // Corner room at the 90 degree turn: two hatches, a sealed end wall and a propaganda board.\r\n    const room=new THREE.Group();room.position.set(0,0,-TURN);group.add(room);const W=CORNER*2;\r\n    box(W,.25,W,deck,0,-.14,0,room);box(W,.2,W,wall,0,4.3,0,room);box(.2,4.6,W,wall,-sign*CORNER,2,0,room);\r\n    // Far wall is plated metal with a real window onto space.\r\n    const fw=new THREE.Shape();fw.moveTo(-CORNER,-.3);fw.lineTo(CORNER,-.3);fw.lineTo(CORNER,4.3);fw.lineTo(-CORNER,4.3);fw.lineTo(-CORNER,-.3);\r\n    const pane=new THREE.Path();pane.moveTo(-1.4,.9);pane.lineTo(-1.4,2.5);pane.lineTo(1.4,2.5);pane.lineTo(1.4,.9);pane.lineTo(-1.4,.9);fw.holes.push(pane);\r\n    const far=new THREE.Mesh(new THREE.ShapeGeometry(fw),plate);far.position.z=-CORNER;room.add(far);\r\n    for(const y of [.9,2.5])box(2.9,.07,.12,cyan,0,y,-CORNER+.02,room);for(const x of [-1.42,1.42])box(.07,1.67,.12,cyan,x,1.7,-CORNER+.02,room);\r\n    // Gold ribs framing the room like the tube ribs, red strip, and a steady ceiling light.\r\n    for(const x of [-1.6,1.6,-(CORNER-.08),CORNER-.08])box(.14,4.3,.14,gold,x,2,-CORNER+.08,room);\r\n    box(W,.14,.14,gold,0,4.15,-CORNER+.08,room);box(.14,.14,W,gold,-sign*(CORNER-.08),4.15,0,room);\r\n    for(const z of [-1.5,1.5])box(.14,4.3,.14,gold,-sign*(CORNER-.08),2,z,room);\r\n    box(.05,.05,W,emergency,-sign*(CORNER-.12),3.6,0,room);\r\n    box(1.3,.04,1.3,warm,0,4.18,0,room);\r\n    bulkhead(W,4.4,room,0,CORNER);bulkhead(W,4.4,room,sign*CORNER,0,Math.PI/2);\r\n    const turnBoard=label(['ALL HALLS','LEAD TO MOM'],false,2.3,.8);turnBoard.position.set(0,3.3,-CORNER+.12);room.add(turnBoard);\r\n    }\r\n    // Horror deck only: dark magenta splats, clay chunks, a couple of gold bones.\r\n    if(t.gore){const splatGeo=new THREE.PlaneGeometry(1,1).rotateX(-Math.PI/2);\r\n    for(let i=0,d=6.3;d<course.length-2;i++,d+=5.3+(i*7%5)){\r\n      if(inPit(d)||TURN!=null&&Math.abs(d-TURN)<CORNER+.5)continue;const part=onPath(d),s=.9+(i*13%7)*.18;\r\n      const m=new THREE.Mesh(splatGeo,splat);m.scale.set(s,1,s*1.3);m.rotation.y=i;m.position.set(((i*5%7)-3)*.45,.012,0);part.add(m);\r\n      for(let k=0;k<3;k++){const c=box(.12+k*.05,.08,.1+k*.04,gore,m.position.x+(k-1)*.3,.04,(k-1)*.25,part);c.rotation.y=i+k;}\r\n      if(i%4===1){const b=new THREE.Group();b.position.set(m.position.x*.6,.04,.3);b.rotation.y=i*.7;part.add(b);box(.5,.05,.05,bone,0,0,0,b);for(const x of [-.27,.27])for(const z of [-.03,.03])box(.08,.08,.06,bone,x,0,z,b);}\r\n    }}\r\n    // Traps: full-width platform, full-width laser grid, long pit with ledges and a grinder below.\r\n    course.events.forEach((event,i)=>{\r\n      if(event.type==='turn')return;\r\n      const trap=onPath(event.at);trap.userData.trap=event.type;\r\n      const board=label(SIGNS[(i+course.seed)%SIGNS.length],event.type==='pit',1.9,.7);board.position.set(0,3.05,-.25);trap.add(board);\r\n      for(const x of [-.6,.6])box(.03,.6,.03,gold,x,3.55,-.25,trap);\r\n      if(event.type==='platform'){\r\n        box(4.6,.6,1.3,inset,0,.3,-.65,trap);box(4.6,.06,1.34,gold,0,.62,-.65,trap);box(4.6,.05,.05,red,0,.66,0,trap);\r\n        const stripes=new THREE.Mesh(new THREE.PlaneGeometry(4.4,.45),hazard);stripes.position.set(0,.3,.005);trap.add(stripes);\r\n      }else if(event.type==='grid'){\r\n        for(const side of [-1,1])box(.18,3.8,.3,gold,side*1.95,1.9,0,trap);box(4.4,.22,.3,gold,0,3.55,0,trap);\r\n        for(let k=0;k<6;k++)box(4.6,.04,.04,laser,0,1.02+k*.42,0,trap);\r\n        const field=new THREE.Mesh(new THREE.PlaneGeometry(4.2,2.4),hum);field.position.set(0,2.08,0);trap.add(field);\r\n      }else{\r\n        const L=event.length,z=-L/2;\r\n        for(const side of [-1,1]){box(1.6,4.2,L,ledge,side*1.65,-2.1,z,trap);box(.06,.05,L,gold,side*.87,.02,z,trap);box(.04,.04,L,red,side*.86,-.5,z,trap);}\r\n        box(1.8,4.2,.3,black,0,-2.1,-L-.15,trap);box(1.8,.05,.06,red,0,.01,0,trap);box(1.8,.05,.06,red,0,.01,-L,trap);\r\n        const floor=new THREE.Mesh(new THREE.PlaneGeometry(1.8,L).rotateX(-Math.PI/2),pitFloor);floor.position.set(0,-4,z);trap.add(floor);\r\n        const mist=new THREE.Mesh(new THREE.PlaneGeometry(1.7,L).rotateX(-Math.PI/2),haze);mist.position.set(0,-.35,z);trap.add(mist);\r\n        // Saw blades: glowing toothed rim around a dark steel body with three cut-outs (so the spin reads); teeth reach deck level.\r\n        const teeth=new THREE.Shape();for(let k=0;k<32;k++){const a=k/32*TAU,r=k%2?.78:1.02;teeth[k?'lineTo':'moveTo'](Math.cos(a)*r,Math.sin(a)*r);}\r\n        const rim=new THREE.Path();rim.absarc(0,0,.7,0,TAU,true);teeth.holes.push(rim);\r\n        const body=new THREE.Shape();body.absarc(0,0,.72,0,TAU,false);\r\n        for(let k=0;k<3;k++){const a=k/3*TAU,h=new THREE.Path();h.absarc(Math.cos(a)*.42,Math.sin(a)*.42,.15,0,TAU,true);body.holes.push(h);}\r\n        const teethGeo=new THREE.ShapeGeometry(teeth,4).rotateY(Math.PI/2),bodyGeo=new THREE.ShapeGeometry(body,6).rotateY(Math.PI/2),hubGeo=new THREE.CylinderGeometry(.16,.16,.16,8).rotateZ(Math.PI/2);\r\n        for(let k=0;k<5;k++){const r=new THREE.Group();r.position.set((k%2?.3:-.3),-1.02,-.7-k*(L-1.4)/4);trap.add(r);r.add(new THREE.Mesh(teethGeo,blade),new THREE.Mesh(bodyGeo,steel),new THREE.Mesh(hubGeo,gold));rotors.push(r);}\r\n        for(let k=0;k<2;k++){const axle=new THREE.Mesh(new THREE.CylinderGeometry(.05,.05,L,6).rotateX(Math.PI/2),gold);axle.position.set(k?.3:-.3,-1.02,z);trap.add(axle);}\r\n        const mid=pathAt(event.at+L/2,course);pitSpots.push({at:event.at,end:event.at+L,pos:new THREE.Vector3(mid.x,-.55,mid.z)});\r\n      }\r\n    });\r\n    // Course banner: the next hall starts where this one ends.\r\n    const banner=label(['MOM INC / '+String(course.level+2).padStart(2,'0'),'NEXT HALL'],false,2.3,.8);\r\n    const bp=onPath(course.length-3);banner.position.set(0,3.2,0);bp.add(banner);\r\n    batchStaticBoxes();\r\n    dust.length=0;for(let i=0;i<DUST;i++)dust.push({d:Math.random()*24-2,x:(Math.random()*2-1)*1.9,y:Math.random()*3.6,s:Math.random()*TAU});\r\n  }\r\n  // A tiny generated environment (ceiling panels, side glow, floor bounce) in the theme's colours so the metal shows highlights.\r\n  function makeEnv(renderer,t){\r\n    const env=new THREE.Scene(),pm=new THREE.PMREMGenerator(renderer);env.background=new THREE.Color(t.bg);\r\n    const panel=(c,w,h,x,y,z)=>{const m=new THREE.Mesh(new THREE.PlaneGeometry(w,h),new THREE.MeshBasicMaterial({color:c,side:THREE.DoubleSide}));m.position.set(x,y,z);m.lookAt(0,0,0);env.add(m);};\r\n    for(let z=-8;z<=8;z+=4)panel(t.light,2,1.2,0,5,z);panel(t.neon.amber,1,8,-5,1,0);panel(t.neon.amber,1,8,5,1,0);panel(t.wall.to,10,10,0,-5,0);panel(t.neon.rail,.4,10,3,-4,0);\r\n    const tex=pm.fromScene(env,.04).texture;pm.dispose();return tex;\r\n  }\r\n  let strobeTimer=0,strobeState=[1,1];\r\n  return {scene,camera,get theme(){return look?.name},render(renderer,run,motion=true,options={}){\r\n    if(course!==run.course){build(run.course,themeAt(run.courses));yaw=pathAt(run.distance,course).yaw;}\r\n    if(envLook!==look){envLook=look;scene.environment?.dispose();scene.environment=makeEnv(renderer,look);scene.environmentIntensity=.45;}\r\n    const pressure=Math.max(0,Math.min(1,+options.pressure||0)),now=performance.now()/1000;\r\n    const p=pathAt(run.distance,course),blend=motion?.22:1,pace=Math.min(1,runSpeed(run)/4);\r\n    cameraLane=cameraLane+((LANES[run.lane]??0)-cameraLane)*blend;yaw=yaw+(p.yaw-yaw)*(motion?.18:1);\r\n    const bob=motion&&!run.paused&&run.height<.1?Math.sin(run.time*17)*.045*pace:0;\r\n    // Stumble: a short shake and roll while the slow-down lasts.\r\n    const shake=motion?Math.min(1,run.stumble/.9):0,jx=shake*Math.sin(now*61)*.06,jr=shake*Math.sin(now*37)*.08;\r\n    camera.aspect=renderer.domElement.clientWidth/Math.max(1,renderer.domElement.clientHeight);camera.fov=72;camera.updateProjectionMatrix();\r\n    camera.position.set(p.x+Math.cos(p.yaw)*(cameraLane+jx),1.67+run.height-(run.duck||0)*1.03+bob-shake*.12,p.z-Math.sin(p.yaw)*(cameraLane+jx));\r\n    camera.rotation.set(-shake*.06,yaw,(motion?-cameraLane*.035:0)+jr,'YXZ');\r\n    // Lights ride with the runner: a lamp on the body and a work light a few metres ahead.\r\n    const fwd=new THREE.Vector3(-Math.sin(yaw),0,-Math.cos(yaw));\r\n    lamp.position.copy(camera.position).y=2.9;fill.position.copy(camera.position).addScaledVector(fwd,14).y=1.2;\r\n    const pit=pitSpots.find(s=>run.distance<s.end+2&&s.at-run.distance<22);if(pit){pitLight.position.copy(pit.pos);pitLight.intensity=9*(.8+.2*Math.sin(now*23)*(motion?1:0));}else pitLight.intensity=0;ahead.position.copy(camera.position).addScaledVector(fwd,7).y=3.3;alarm.position.copy(camera.position).addScaledVector(fwd,3).y=3.2;\r\n    // Flicker: two light banks strobe at random; the work light stutters with them.\r\n    if(motion&&now>strobeTimer){strobeTimer=now+.04+Math.random()*.25;strobeState=[Math.random()<.85?1:.08,Math.random()<.6?1:.05];}\r\n    if(!motion)strobeState=[1,1];\r\n    strobeA.color.copy(W).multiplyScalar(strobeState[0]);strobeB.color.copy(W).multiplyScalar(strobeState[1]);ahead.intensity=14*(.55+.45*strobeState[0]);\r\n    // Emergency strips and the red wash grow with coach pressure.\r\n    const pulse=motion?.5+.5*Math.sin(now*(3+7*pressure)):1;\r\n    emergency.color.copy(E).multiplyScalar(.25+pressure*(.6+.9*pulse));alarm.intensity=pressure*(4+10*pulse);\r\n    laser.color.copy(LZ).multiplyScalar(.85+.15*Math.sin(now*40));hum.opacity=.12+.08*Math.sin(now*9);haze.opacity=.22+.1*Math.sin(now*5);\r\n    if(motion)for(const r of rotors)r.rotation.x=now*9+r.position.z;\r\n    // Space: stars follow the camera (so they read as far away) and drift slowly.\r\n    // The set piece turns with the runner so it stays in the windows ahead after a corner.\r\n    sky.position.copy(camera.position);sky.rotation.y=yaw;if(motion){stars.rotation.y=now*.004;for(const o of vista.children)if(o.userData.spin)o.rotation.y+=o.userData.spin*.016;}\r\n    const end=course.length+20;\r\n    for(let i=0;i<DUST;i++){const m=dust[i];if(m.d<run.distance-2||m.d>run.distance+26)m.d=run.distance+(m.d<run.distance?22+Math.random()*4:Math.random()*24);\r\n      const q=place(Math.min(m.d,end)),wob=motion?Math.sin(now*.7+m.s)*.15:0;\r\n      dustPos[i*3]=q.x+Math.cos(q.yaw)*m.x;dustPos[i*3+1]=m.y+wob;dustPos[i*3+2]=q.z-Math.sin(q.yaw)*m.x;if(motion){m.y=(m.y+.0015)%3.6;}}\r\n    dustGeo.attributes.position.needsUpdate=true;\r\n    options.before?.(scene,camera,course);\r\n    renderer.render(scene,camera);\r\n  }};\r\n}\r\n","arcade/runner/pose-input.mjs":"// Body -> runner controls. Built for a treadmill with the phone in front (legs usually hidden), and still works jogging in place.\r\n// Upper body only (nose 0, shoulders 11/12, elbows 13/14, wrists 15/16, hips 23/24 when seen):\r\n//   head bob = running (speed never scales with effort) · both arms up + shoulders up = jump · head drops = slide · lean = lane.\r\n// The old knee-lift step (movement-engine jogUpdate) and one-leg side step still count as alternates.\r\n// Every number a real treadmill test might need to move lives in POSE_TUNING. Distances are in shoulder widths.\r\nexport const POSE_TUNING={\r\n  jogHold:2,         // s with no head bob (and no knee step) before you count as stopped -> \"YOU ARE STOPPED\"\r\n  minVisibility:.5,\r\n  bob:{\r\n    min:.06,         // head bob half-swing that counts (shoulder widths). Treadmill walk ~.08, run ~.15; standing jitter ~.02\r\n    maxHalf:.8,      // s: a swing slower than this is drift (walking toward the phone), not a bob\r\n    smooth:.04       // s smoothing on the head signal\r\n  },\r\n  calibrate:1.2,     // s of head/neck samples (running or standing) for the baseline\r\n  adapt:3,           // s time constant: the baseline follows slow drift on the belt (paused while an action is held)\r\n  smooth:.1,         // s smoothing on drop / shrug / lean (kills the bob)\r\n  jump:{\r\n    armAbove:.15,    // wrist this far above its shoulder (or elbow above the shoulder when the wrist is out of frame)\r\n    shrug:.06,       // shoulders risen toward the nose vs baseline neck length\r\n    dwell:.08,cooldown:.9\r\n  },\r\n  crouch:{\r\n    drop:.45,        // head+shoulders below the running baseline (bob is ~.1, so it never slides)\r\n    rearm:.2,dwell:.1,cooldown:.7\r\n  },\r\n  lean:{\r\n    in:.3,           // shoulder tilt + shoulder-mid offset from hip-mid (hips optional)\r\n    out:.12,dwell:.12,cooldown:.5,\r\n    flip:false       // raw camera frames are unmirrored: the player's right is image-left. Flip if a device disagrees.\r\n  },\r\n  settle:.3,         // s after any action before a different action can fire (arms dropping, standing up)\r\n  side:{\r\n    out:.62,         // stepping ankle: lateral distance from the hip midline, in torso lengths\r\n    plant:.38,       // planted ankle must stay this close to the midline\r\n    rearm:.42,       // both ankles back inside this before the next side step can fire\r\n    kneeOut:.42,kneePlant:.28,kneeRearm:.3, // same three with knees (feet out of frame)\r\n    outScale:2.2,    // calibrated standing half-stance x this, if larger than `out`\r\n    dwell:.12,       // s the side-step shape must hold (one frame is enough below 8 updates/s)\r\n    cooldown:.45,    // s between side steps\r\n    minVisibility:.5,\r\n    calibrate:.6,    // s of steady standing to learn the stance width\r\n    flip:false\r\n  }\r\n};\r\nconst median=a=>{const s=[...a].sort((x,y)=>x-y);return s[Math.floor(s.length/2)];};\r\nconst ema=(old,v,dt,tau)=>old===null?v:old+(v-old)*(1-Math.exp(-Math.max(dt,.001)/tau));\r\n// Shared upper-body frame: null unless nose and both shoulders are clear.\r\nfunction upper(p,aspect,minVis){\r\n  if(!p||p.length<17)return null;\r\n  const ok=i=>p[i]&&Number.isFinite(p[i].x)&&Number.isFinite(p[i].y)&&(p[i].visibility??1)>=minVis;\r\n  if(![0,11,12].every(ok))return null;\r\n  const X=i=>p[i].x*aspect,sw=Math.hypot(X(11)-X(12),p[11].y-p[12].y);if(sw<.03)return null;\r\n  return {ok,X,sw,sx:(X(11)+X(12))/2,sy:(p[11].y+p[12].y)/2,ny:p[0].y};\r\n}\r\n// Head bob: a hysteresis peak tracker on (nose+shoulders)/2. Returns true on each up/down reversal of the head. Also used by movement-engine\r\n// to keep Cool Cardio's active time (XP) counting when the knees are hidden by a treadmill console.\r\nexport function createHeadBob(tuning=POSE_TUNING){\r\n  let v=null,ext=null,dir=1,lastRev=-Infinity,last=null;\r\n  return {update(points,t,aspect=1){\r\n    const T=tuning.bob,f=upper(points,aspect,tuning.minVisibility);if(!f)return false;\r\n    const dt=last===null?0:t-last;last=t;v=ema(v,(f.ny+f.sy)/2,dt,T.smooth);\r\n    const h=T.min*f.sw;if(ext===null){ext=v;return false;}\r\n    let rev=0;\r\n    if(dir*(v-ext)>0)ext=v;\r\n    else if(Math.abs(v-ext)>=h){rev=dir;dir=-dir;ext=v;}\r\n    if(!rev)return false;\r\n    // Every quick reversal counts (about two per step). Below ~2x the cadence a tracker aliases the bob into a slower\r\n    // wave, so the window widens with the frame gap: a 2 updates/s phone still reads a runner as running.\r\n    const quick=t-lastRev<=Math.max(T.maxHalf,3*dt);lastRev=t;\r\n    return quick;\r\n  }};\r\n}\r\n// Jump / slide / lean from the upper body, with a moving-safe baseline, smoothing, hysteresis, dwell and cooldowns.\r\nexport function createUpperBody(tuning=POSE_TUNING){\r\n  let last=null,calib=[],base=null,drop=null,shrug=null,lean=null,lastAct=-Infinity,lastKind='';\r\n  const st={jump:{armed:true,since:null,fired:-Infinity},slide:{armed:true,since:null,fired:-Infinity},lean:{armed:true,since:null,fired:-Infinity,dir:null}};\r\n  const hold=(s,on,t,dt,T,kind)=>{\r\n    if(!on){s.since=null;return false;}\r\n    if(s.since===null)s.since=t-dt/2;\r\n    if((t-s.since>=T.dwell||dt>=.125)&&t-s.fired>=T.cooldown&&(lastKind===kind||t-lastAct>=tuning.settle)){s.fired=t;s.armed=false;s.since=null;lastAct=t;lastKind=kind;return true;}\r\n    return false;\r\n  };\r\n  return {get calibrated(){return !!base},get baseline(){return base},\r\n    signals:()=>({drop,shrug,lean}),\r\n    update(points,t,aspect=1){\r\n      const T=tuning,f=upper(points,aspect,T.minVisibility);if(!f)return null;\r\n      const dt=last===null?0:Math.min(.5,t-last);last=t;\r\n      const head=(f.ny+f.sy)/2,neck=(f.sy-f.ny)/f.sw;\r\n      if(!base){calib.push({t,head,neck});calib=calib.filter(c=>t-c.t<=T.calibrate*2);\r\n        if(calib.length>=5&&t-calib[0].t>=T.calibrate)base={head:median(calib.map(c=>c.head)),neck:median(calib.map(c=>c.neck))};\r\n        return null;}\r\n      const p=points,J=T.jump;\r\n      const arm=(s,e,w)=>f.ok(w)?p[w].y<p[s].y-J.armAbove*f.sw:f.ok(e)&&p[e].y<p[s].y;\r\n      const armsUp=arm(11,13,15)&&arm(12,14,16);\r\n      const hips=f.ok(23)&&f.ok(24),offset=hips?((f.X(23)+f.X(24))/2-f.sx)/f.sw:0,tilt=(p[12].y-p[11].y)/f.sw;\r\n      drop=ema(drop,(head-base.head)/f.sw,dt,T.smooth);shrug=ema(shrug,base.neck-neck,dt,T.smooth);lean=ema(lean,offset+tilt,dt,T.smooth);\r\n      const actions=[],C=T.crouch,L=T.lean;\r\n      // Jump: both arms up AND shoulders up. Rearms when the arms come down.\r\n      if(!armsUp)st.jump.armed=true;\r\n      if(st.jump.armed&&hold(st.jump,armsUp&&shrug>=J.shrug,t,dt,J,'jump'))actions.push('jump');\r\n      // Slide: head and shoulders well below the running baseline.\r\n      if(drop<C.rearm)st.slide.armed=true;\r\n      if(st.slide.armed&&hold(st.slide,!armsUp&&drop>=C.drop,t,dt,C,'slide'))actions.push('slide');\r\n      // Lean: one lane per lean; come back near upright to rearm.\r\n      if(Math.abs(lean)<L.out)st.lean.armed=true;\r\n      const dir=(lean>0)!==L.flip?'right':'left';\r\n      if(st.lean.dir!==dir){st.lean.dir=dir;st.lean.since=null;}\r\n      if(st.lean.armed&&hold(st.lean,!armsUp&&drop<C.rearm&&Math.abs(lean)>=L.in,t,dt,L,'lean'))actions.push(dir);\r\n      // Baseline follows slow belt drift only while nothing is held.\r\n      if(!armsUp&&drop<C.rearm&&Math.abs(lean)<L.out){base.head=ema(base.head,head,dt,T.adapt);base.neck=ema(base.neck,neck,dt,T.adapt);}\r\n      return actions;\r\n    }};\r\n}\r\n// Side-step detector on raw landmarks (ankles 27/28, knees 25/26, hips 23/24, shoulders 11/12).\r\nexport function createSideStep(tuning=POSE_TUNING.side){\r\n  let armed=true,since=null,dir=null,lastFire=-Infinity,last=null,stance=null,calib=[];\r\n  const d={stance:()=>stance,update(points,t,aspect=1){\r\n    const T=tuning,p=points;if(!p||p.length<29)return null;\r\n    const ok=i=>p[i]&&Number.isFinite(p[i].x)&&Number.isFinite(p[i].y)&&(p[i].visibility??1)>=T.minVisibility;\r\n    if(![11,12,23,24].every(ok))return null;\r\n    const X=i=>p[i].x*aspect,hx=(X(23)+X(24))/2,hy=(p[23].y+p[24].y)/2,sx=(X(11)+X(12))/2,sy=(p[11].y+p[12].y)/2;\r\n    const torso=Math.hypot(hx-sx,hy-sy);if(torso<.03)return null;\r\n    const feet=ok(27)&&ok(28),knees=ok(25)&&ok(26);if(!feet&&!knees){since=null;return null;}\r\n    const [a,b]=feet?[27,28]:[25,26],out=feet?T.out:T.kneeOut,plant=feet?T.plant:T.kneePlant,rearm=feet?T.rearm:T.kneeRearm;\r\n    const oa=(X(a)-hx)/torso,ob=(X(b)-hx)/torso,wide=Math.max(Math.abs(oa),Math.abs(ob)),narrow=Math.min(Math.abs(oa),Math.abs(ob));\r\n    const dt=last===null?0:t-last;last=t;\r\n    // Short calibration: the standing half-stance (feet only) widens the out threshold for wide-stance players.\r\n    if(feet&&stance===null){if(wide<rearm*1.4){calib.push({t,w:wide});calib=calib.filter(c=>t-c.t<=T.calibrate*2);if(calib.length>=3&&t-calib[0].t>=T.calibrate)stance=median(calib.map(c=>c.w));}else calib=[];}\r\n    const need=feet&&stance!==null?Math.max(out,stance*T.outScale):out;\r\n    if(!armed){if(wide<rearm){armed=true;since=null;}return null;}\r\n    if(wide>=need&&narrow<=plant){\r\n      const o=Math.abs(oa)>Math.abs(ob)?oa:ob,next=(o<0)!==T.flip?'right':'left';\r\n      if(dir!==next){dir=next;since=t-dt/2;}\r\n      // Hold for `dwell`, or a single sample at phone rates where frames are further apart than the dwell.\r\n      if((t-since>=T.dwell||dt>=.125)&&t-lastFire>=T.cooldown){armed=false;lastFire=t;since=null;return next;}\r\n    }else{since=null;dir=null;}\r\n    return null;\r\n  }};\r\n  return d;\r\n}\r\n// Session: the app's MovementSession class (passed in so the lazy chunk does not reload the engine); only its knee-step\r\n// jog detector is used now. Running = a head bob or a knee step within jogHold seconds.\r\nexport function createPoseInput({Session,tuning=POSE_TUNING}){\r\n  const jog=new Session('jogging'),bob=createHeadBob(tuning),body=createUpperBody(tuning),side=createSideStep(tuning.side);\r\n  let lastStep=-Infinity,lastCount=0,lastLane=-Infinity,jogging=false;\r\n  return {get jogging(){return jogging},get calibrated(){return body.calibrated},body,\r\n    update({points,world=null,width=1,height=1,now}){\r\n      const actions=[];if(!points||!Number.isFinite(now))return {jogging,actions};\r\n      const t=now/1000,aspect=width/Math.max(1,height);\r\n      const s=jog.update(points,now,aspect,world);\r\n      if(s.count>lastCount){lastCount=s.count;lastStep=t;}\r\n      if(bob.update(points,t,aspect))lastStep=t;\r\n      jogging=t-lastStep<=tuning.jogHold;\r\n      for(const a of body.update(points,t,aspect)||[]){if(a==='left'||a==='right')lastLane=t;actions.push(a);}\r\n      // A one-leg side step is the old lane control; skip it if a lean just moved the lane.\r\n      const dir=side.update(points,t,aspect);if(dir&&t-lastLane>=tuning.side.cooldown){lastLane=t;actions.push(dir);}\r\n      return {jogging,actions};\r\n    }};\r\n}\r\n","arcade/runner/runner.mjs":"// Cool Cardio runner over the camera workout: the 3D corridor fills the stage, the camera shrinks to a small mirrored\r\n// selfie inset, the counter/timer stays and a tap on it finishes the run. A skin and controller only: cardio XP and time\r\n// are still counted by performance-workout.mjs (endless gentle cardio); this reads pose events and nothing else.\r\n// Endless: courses chain and get harder at one constant speed (treadmill: head bob runs, arms up jumps, crouch slides, lean steers). Traps and unhit projectiles are stumbles. Stop jogging and the speed ramps to 0\r\n// over 10 s while Coach closes in from behind; 10 s still and he catches you (onCaught finishes the set with its XP).\r\n// Coach also throws junk straight down the hall from the far end; punch or slice it for a small bonus (throws.mjs).\r\n// Lazy: app.mjs imports this only for Cool Cardio (external in scripts/build.mjs).\r\nimport * as THREE from 'three';\r\nimport {createRun,step,input,stumble,runSpeed,pathAt} from './maze-run.mjs';\r\nimport {createMazeScene} from './maze-scene.mjs';\r\nimport {createPoseInput} from './pose-input.mjs';\r\nimport {clayText} from './clay-text.mjs';\r\nimport {coachHand} from './coach-hand.mjs';\r\nimport {themeFor} from './themes.mjs';\r\nimport {createThrows,createStriker,mountThrowsView,THROW} from './throws.mjs';\r\nconst RUN_LINES=['Coach not mad.','Coach must help.','Job says catch.','Mom loves you. Run.','Coach hears your feet.','Coach feels torn.'];\r\nconst STUMBLE_LINES=['Coach gets closer.','Tripped? Coach saw.','Mom saw that.','Coach smells fear.','Coach getting close.'];\r\nconst CSS=`#cameraWorkout.runner-on>video{inset:auto;right:6px;bottom:max(6px,env(safe-area-inset-bottom));width:22vw;max-width:92px;height:auto;aspect-ratio:3/4;object-fit:cover;z-index:2;border-radius:10px;border:2px solid #fff8;box-shadow:0 4px 12px #000a;background:#000}\r\n#cameraWorkout.runner-on #coachOverlay{visibility:hidden}\r\n#cameraWorkout.runner-on .workout-performance-controls{left:6px;right:auto;bottom:max(6px,env(safe-area-inset-bottom));margin:0;padding:3px;gap:4px;background:#0008;border-radius:10px}\r\n#cameraWorkout.runner-on .workout-performance-controls button,#cameraWorkout.runner-on .workout-performance-controls select{padding:4px 8px;font-size:12px;min-height:32px}\r\n#cameraWorkout.runner-on .camera-workout-housing{filter:hue-rotate(var(--runner-hue,0deg)) saturate(1.25);transition:filter .6s}\r\n#cameraWorkout .runner-layer{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}\r\n#cameraWorkout .runner-layer canvas.runner-view{position:absolute;inset:0;width:100%;height:100%;display:block}\r\n#cameraWorkout .runner-flash{position:absolute;inset:0;background:radial-gradient(ellipse at center,#ff001840 20%,#ff0018ee);opacity:0}\r\n#cameraWorkout .runner-flash.on{animation:runner-flash .9s ease-out}\r\n@keyframes runner-flash{from{opacity:1}to{opacity:0}}\r\n#cameraWorkout .runner-chaser{position:absolute;left:50%;bottom:0;width:0;height:0;transition:transform .25s linear;transform:translateY(calc((1 - var(--chase,0)) * 70vh))}\r\n#cameraWorkout .runner-chaser .ar-coach-hand{position:absolute;left:0;top:0;transform:translate(-50%,-40vh) rotate(-90deg);filter:drop-shadow(0 0 18px #000);transition:transform .5s cubic-bezier(.3,1.6,.5,1)}\r\n#cameraWorkout .runner-chaser.caught .ar-coach-hand{transform:translate(-50%,-55vh) rotate(-90deg) scale(2)}\r\n#cameraWorkout .runner-say{position:absolute;z-index:4;top:calc(max(24px,env(safe-area-inset-top)) + 110px);left:8px;right:8px;display:flex;justify-content:center;pointer-events:none}\r\n#cameraWorkout .runner-say[hidden]{display:none}\r\n#cameraWorkout .runner-say canvas{max-width:100%;height:auto!important;filter:drop-shadow(0 4px 6px #000a)}\r\n#cameraWorkout .runner-say.pop{animation:runner-pop .42s cubic-bezier(.3,1.6,.5,1) both}\r\n@keyframes runner-pop{from{opacity:0;transform:translateY(-14px) scale(.6) rotate(-3deg)}to{opacity:1;transform:none}}\r\n#cameraWorkout .runner-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}\r\n#cameraWorkout .runner-stopped{position:absolute;z-index:5;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;pointer-events:none;background:#40000c80;text-align:center}\r\n#cameraWorkout .runner-stopped[hidden]{display:none}\r\n#cameraWorkout .runner-stopped b{font:900 clamp(40px,13vw,72px)/.95 system-ui,sans-serif;color:#fff;-webkit-text-stroke:3px #ff0030;text-shadow:0 0 18px #ff0030,0 6px 0 #5a0010;letter-spacing:.02em;animation:runner-stop-pulse .8s ease-in-out infinite alternate}\r\n#cameraWorkout .runner-stopped span{font:800 18px/1.2 system-ui,sans-serif;color:#ffe3e8;text-shadow:0 2px 4px #000}\r\n@keyframes runner-stop-pulse{from{transform:scale(.96)}to{transform:scale(1.04)}}\r\n@media(prefers-reduced-motion:reduce){#cameraWorkout .runner-stopped b{animation:none}}\r\n@media(prefers-reduced-motion:reduce){#cameraWorkout .runner-say.pop,#cameraWorkout .runner-flash.on{animation:none}#cameraWorkout .runner-chaser{transition:none}}`;\r\nexport function mountRunner({host,Session,sound=()=>{},onXp=()=>{},onCaught=()=>{},seed=Date.now()>>>0}){\r\n  const style=document.createElement('style');style.textContent=CSS;document.head.append(style);\r\n  const layer=document.createElement('div');layer.className='runner-layer';layer.setAttribute('aria-hidden','true');\r\n  const canvas=document.createElement('canvas');canvas.className='runner-view';const flash=document.createElement('div');flash.className='runner-flash';\r\n  const chaser=document.createElement('div');chaser.className='runner-chaser';const coach=coachHand({size:Math.min(340,innerWidth*.9)});chaser.append(coach);layer.append(canvas,flash,chaser);\r\n  const say=document.createElement('div');say.className='runner-say';say.setAttribute('aria-live','polite');say.hidden=true;\r\n  // Treadmill: no head bob for POSE_TUNING.jogHold s after the run starts = a big stop warning until you run again.\r\n  const stopped=document.createElement('div');stopped.className='runner-stopped';stopped.setAttribute('role','alert');stopped.hidden=true;stopped.innerHTML='<b>YOU ARE<br>STOPPED</b><span>Run to keep going</span>';\r\n  host.prepend(layer);host.append(say,stopped);host.classList.add('runner-on');\r\n  const renderer=new THREE.WebGLRenderer({canvas,antialias:false,powerPreference:'high-performance'});renderer.setPixelRatio(Math.min(1.5,devicePixelRatio||1));\r\n  const maze=createMazeScene(THREE),run=createRun(seed),body=createPoseInput({Session});\r\n  const still=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n  // Throws live in corridor space (distance ahead, lateral, height) and are drawn and hit-tested through the runner camera.\r\n  const at=(d,x=0,y=0)=>{const p=pathAt(run.distance+d,run.course);return new THREE.Vector3(p.x+Math.cos(p.yaw)*x,y,p.z-Math.sin(p.yaw)*x);};\r\n  const posOf=o=>at(o.d,o.x,o.y),view=mountThrowsView(THREE,maze.scene),strike=createStriker();\r\n  const throws=createThrows({seed,onEvent:(type,d)=>{\r\n    if(type==='hit'){view.hit(d,posOf(d));sound(d.kind==='slice'?'ice':'wood');}\r\n    else if(type==='bonus'){onXp(d.xp);sound('dial');}\r\n    else if(type==='miss')stumble(run,{type:'throw'});}});\r\n  const coachAt=()=>{const c=run.course;let d=THROW.from+1;if(c.turnAt!=null&&run.distance<c.turnAt)d=Math.min(d,c.turnAt-run.distance);return at(d,0,.9);};\r\n  const screen=o=>{const cam=maze.camera,v=posOf(o),depth=v.distanceTo(cam.position);v.project(cam);if(v.z>1||depth<.2)return null;const asp=(host.clientWidth||innerWidth)/(host.clientHeight||innerHeight);\r\n    return {x:(v.x+1)/2*asp,y:(1-v.y)/2,r:o.r/(depth*2*Math.tan(cam.fov*Math.PI/360))};};\r\n  let raf=0,last=0,lastPose=-Infinity,hideTimer=0,chatAt=performance.now()+5000,line=0,saying='',w=0,h=0,course=null,caughtAt=0,wasStill=0;\r\n  function show(text,ms=2200){\r\n    clearTimeout(hideTimer);hideTimer=setTimeout(()=>{say.hidden=true;saying='';},ms);if(saying===text&&!say.hidden)return;saying=text;\r\n    const room=Math.min(innerWidth,host.clientWidth||innerWidth)-24,hh=innerWidth<420?34:44;let art=clayText(text,hh);const aw=parseFloat(art.style.width);if(aw>room)art=clayText(text,hh*room/aw);\r\n    const sr=document.createElement('span');sr.className='runner-sr';sr.textContent=text;say.replaceChildren(art,sr);say.hidden=false;say.classList.remove('pop');void say.offsetWidth;say.classList.add('pop');\r\n  }\r\n  const pick=list=>list[line++%list.length];\r\n  function feed(now){\r\n    for(const f of run.feed.splice(0)){\r\n      if(f.type==='stumble'){if(run.still<2)show(f.trap==='throw'?'Coach hit you.':pick(STUMBLE_LINES));flash.classList.remove('on');void flash.offsetWidth;flash.classList.add('on');sound('jelly');chatAt=now+6000;}\r\n      else if(f.type==='course'){show(`Hall ${f.level+1}. Harder.`);sound('lever');chatAt=now+6000;}\r\n      else if(f.type==='warn'){show('Coach is right behind you. Jog!',4000);sound('crt');chatAt=now+6000;}\r\n      else if(f.type==='caught'){show('Coach caught you.',6000);chaser.classList.add('caught');coach.coach.roll(true);sound('main-control');caughtAt=now;}\r\n    }\r\n    if(wasStill>=2&&run.still===0&&run.status==='running'){show('Coach falls back.');chatAt=now+6000;}\r\n    wasStill=run.still;\r\n    if(now>chatAt&&run.status==='running'){chatAt=now+7000+Math.random()*4000;\r\n      show(!body.calibrated?'Coach measures. Keep going.':!run.started?'Run to start.':pick(RUN_LINES));}\r\n  }\r\n  function frame(now){\r\n    // Wall-clock time (sub-stepped), so a slow phone neither slows the game nor stretches the 10 s stop clock.\r\n    raf=requestAnimationFrame(frame);const dt=last?Math.min(.25,(now-last)/1000):0;last=now;\r\n    if(now-lastPose>1500)run.jogging=false; // no body seen: the stop clock runs\r\n    if(course!==run.course){course=run.course;throws.clear();view.clear();host.style.setProperty('--runner-hue',(themeFor(run.courses).hue-280)+'deg');}\r\n    for(let left=dt;left>1e-6;left-=.05){const d=Math.min(.05,left);step(run,d);throws.step(d,runSpeed(run),run.started&&run.status==='running',run.level);}feed(now);\r\n    // The chaser climbs into view as the stop clock (or stumble pressure) brings Coach close.\r\n    const chase=run.status==='caught'?1:Math.max(run.chase,(run.pressure-.3)*.5);chaser.style.setProperty('--chase',chase.toFixed(3));coach.coach.pressure(Math.max(chase,run.pressure));\r\n    stopped.hidden=!(run.started&&!run.jogging&&run.status==='running');\r\n    if(caughtAt&&now-caughtAt>3200){caughtAt=0;onCaught();}\r\n    const cw=host.clientWidth||innerWidth,ch=host.clientHeight||innerHeight;if(cw!==w||ch!==h){w=cw;h=ch;renderer.setSize(w,h,false);}\r\n    maze.render(renderer,run,!still(),{pressure:Math.max(run.pressure,run.chase),before:(scene,camera)=>view.update(throws,posOf,coachAt(),camera,dt,now)});\r\n  }\r\n  // Fallback controls: arrow keys / space, and swipes on the game (buttons keep their taps).\r\n  const KEYS={ArrowLeft:'left',ArrowRight:'right',ArrowUp:'jump',' ':'jump',ArrowDown:'slide'};\r\n  const onKey=e=>{const a=KEYS[e.key];if(a&&!e.target?.closest?.('input,select,textarea,button')){e.preventDefault();input(run,a);}};\r\n  let swipe=null;const onDown=e=>{swipe=e.target?.closest?.('button,select,a,input')?null:{x:e.clientX,y:e.clientY};};\r\n  const onUp=e=>{if(!swipe)return;const dx=e.clientX-swipe.x,dy=e.clientY-swipe.y;swipe=null;if(Math.max(Math.abs(dx),Math.abs(dy))<40)return;input(run,Math.abs(dx)>Math.abs(dy)?(dx<0?'left':'right'):(dy<0?'jump':'slide'));};\r\n  addEventListener('keydown',onKey);host.addEventListener('pointerdown',onDown);host.addEventListener('pointerup',onUp);\r\n  raf=requestAnimationFrame(frame);show('Coach measures. Keep going.',3000);\r\n  return {run,maze,body,show,throws,screenOf:screen,\r\n    pose(detail){const r=body.update(detail);run.jogging=r.jogging;for(const a of r.actions)input(run,a);lastPose=performance.now();\r\n      if(run.status==='running')for(const s of strike(detail,{width:host.clientWidth||innerWidth,height:host.clientHeight||innerHeight}))throws.strike(s.a,s.b,s.kind,screen);return r;},\r\n    stop(){removeEventListener('keydown',onKey);host.removeEventListener('pointerdown',onDown);host.removeEventListener('pointerup',onUp);stopped.remove();cancelAnimationFrame(raf);clearTimeout(hideTimer);view.dispose();coach.coach.destroy();renderer.dispose();renderer.forceContextLoss?.();layer.remove();say.remove();style.remove();host.classList.remove('runner-on');host.style.removeProperty('--runner-hue');}};\r\n}\r\n","arcade/runner/themes.mjs":"// One look per course, cycled. Each owns a clearly different hue: wall texture + tint, neon, lights, the view out of the\r\n// windows, and `hue` (degrees) for the camera housing frame. gore only in the horror deck (splats, clay chunks, gold bones).\r\nexport const THEMES=[\r\n  {name:'MOM hull',hue:285,bg:'#06020a',fog:'#140a1c',hemi:['#c8a0e8','#1c1024'],light:'#ffc8f0',\r\n   wall:{style:'plate',from:'#6e5a86',to:'#4a3a60',grime:'30,8,40',tint:'#b89ad8',metalness:.6,roughness:.4},\r\n   neon:{rail:'#ff4fd8',warm:'#ffd0f4',red:'#ff3a8a',amber:'#c870ff',laser:'#ff4fd8',emergency:'#ff1e6e',blade:'#ff5ae0',sign:'#ff85e5'},\r\n   sky:{kind:'planet',stars:'#e8e2ff',colors:['#f6b6ff','#8e5b99','#281433'],bands:'#d4a017'}},\r\n  {name:'Nebula lab',hue:175,bg:'#020a0a',fog:'#0c1c20',hemi:['#f0ffff','#20383a'],light:'#e8ffff',\r\n   wall:{style:'lab',from:'#f2f6f8',to:'#d0dade',grime:'60,110,120',tint:'#ffffff',metalness:.1,roughness:.35},\r\n   neon:{rail:'#20f0d0',warm:'#e8fffc',red:'#ff3a6a',amber:'#20c8ff',laser:'#ff2a8a',emergency:'#ff2a5a',blade:'#20f0d0',sign:'#20f0d0'},\r\n   sky:{kind:'nebula',stars:'#ffffff',colors:['#20f0d0','#2a7aff','#ff4fd8','#80ffea']}},\r\n  {name:'Rust bucket',hue:28,bg:'#080400',fog:'#1e0e04',hemi:['#ffc890','#2a1406'],light:'#ffa850',\r\n   wall:{style:'rust',from:'#8a4a1e',to:'#4a2408',grime:'40,16,4',tint:'#e8a060',metalness:.45,roughness:.75},\r\n   neon:{rail:'#ff9a1e',warm:'#ffd08a',red:'#ff3a14',amber:'#ffb02e',laser:'#ff6a1e',emergency:'#ff2a10',blade:'#ffd02e',sign:'#ffb02e'},\r\n   sky:{kind:'asteroids',stars:'#ffe8d0',rock:'#8a6a4a'}},\r\n  {name:'Hex hive',hue:110,bg:'#010600',fog:'#081a04',hemi:['#b8ff90','#0a1a04'],light:'#c8ff9a',\r\n   wall:{style:'hex',from:'#3a6a1e',to:'#183a0a',grime:'0,30,0',tint:'#a8f070',metalness:.3,roughness:.5},\r\n   neon:{rail:'#7dff2a',warm:'#e8ffc0',red:'#ff3a3a',amber:'#d8ff2a',laser:'#b0ff2a',emergency:'#ff3a2a',blade:'#7dff2a',sign:'#7dff2a'},\r\n   sky:{kind:'rings',stars:'#e8ffd8',colors:['#e8ffa0','#7aa02a','#203a08'],ring:'#d8f0a0'}},\r\n  {name:'Earthrise',hue:215,bg:'#00020a',fog:'#04102a',hemi:['#9ac0ff','#040a20'],light:'#c8deff',\r\n   wall:{style:'plate',from:'#3a5a90',to:'#1a2a50',grime:'0,8,30',tint:'#8ab0ff',metalness:.7,roughness:.3},\r\n   neon:{rail:'#ffffff',warm:'#d8ecff',red:'#ff4a4a',amber:'#4ab8ff',laser:'#4affff',emergency:'#ff3030',blade:'#4ab8ff',sign:'#8ad0ff'},\r\n   sky:{kind:'earth',stars:'#ffffff'}},\r\n  {name:'Solar gold',hue:48,bg:'#0a0600',fog:'#201604',hemi:['#fff0a0','#2a2006'],light:'#ffe08a',\r\n   wall:{style:'hex',from:'#8a6a1a',to:'#4a3608',grime:'40,24,0',tint:'#ffd870',metalness:.75,roughness:.3},\r\n   neon:{rail:'#ffe02a',warm:'#fff4c0',red:'#ff5a1a',amber:'#ffc02a',laser:'#ff8a1a',emergency:'#ff4a10',blade:'#ffe02a',sign:'#ffd02a'},\r\n   sky:{kind:'redstar',stars:'#ffe8c8',colors:['#fff0c0','#ff6a2a','#a01008']}},\r\n  {name:'Gore deck',hue:350,bg:'#040000',fog:'#1a0204',hemi:['#ff7a7a','#1a0004'],light:'#ff6a6a',gore:true,\r\n   wall:{style:'rust',from:'#5a0a10',to:'#240206',grime:'60,0,10',tint:'#d05050',metalness:.35,roughness:.45},\r\n   neon:{rail:'#9aff2a',warm:'#ffb0a0',red:'#ff1a1a',amber:'#c0ff3a',laser:'#ff1a2a',emergency:'#ff0010',blade:'#ff1a1a',sign:'#9aff2a'},\r\n   sky:{kind:'planet',stars:'#ffb0b0',colors:['#ff8a6a','#660010','#1a0004'],bands:'#330006'}},\r\n];\r\nexport const themeFor=n=>THEMES[((n%THEMES.length)+THEMES.length)%THEMES.length];\r\n","arcade/runner/throws.mjs":"// Phase 2: the coach stands at the far end of the hall and throws asteroids and junk straight back down the corridor.\r\n// They grow toward the camera; a fast limb through one punches it (explode) or slices it (cut), using the slice\r\n// engine's pathKind and the camera-slice wrist-speed gate, hit-tested where the runner camera draws them.\r\n// Each hit is a small bonus through pod.flow.workout.bonusXp (the XP lane caps the share), as slice does.\r\n// Rate and speed ramp with course level; one that reaches the runner unhit is a stumble (emitted as 'miss').\r\nimport {pathKind,distPointSeg,rng,TYPES,TYPE_IDS} from '../slice/core.mjs';\r\nexport const THROW={every:[2.4,3.8],from:22,speed:[4.5,6.5],ramp:{every:.06,speed:.35,minEvery:.4,maxSpeed:5},reach:7.5,near:.6,xp:1,fast:.9,seen:.4,pad:.02};\r\nexport const throwEvery=level=>Math.max(THROW.ramp.minEvery,1-THROW.ramp.every*level);\r\nexport const throwSpeed=level=>Math.min(THROW.ramp.maxSpeed,THROW.ramp.speed*level);\r\nconst LIMBS=[13,14,15,16,25,26,27,28]; // elbows, wrists, knees, ankles (same as camera-slice)\r\n// Pure state: objects at distance d ahead of the runner, lateral x and height y in corridor space.\r\nexport function createThrows({seed=1,onEvent=()=>{}}={}){\r\n  const r=rng(seed),T={objects:[],t:0,spawnIn:1.5,hits:0,xp:0,thrown:0,throwing:0};\r\n  let level=0;\r\n  T.spawn=()=>{const type=TYPE_IDS[Math.floor(r()*TYPE_IDS.length)],o={id:++T.thrown,type,d:THROW.from,x:(r()*2-1)*1.1,y:1.1+r()*.9,r:.32+r()*.18,speed:THROW.speed[0]+r()*(THROW.speed[1]-THROW.speed[0])+throwSpeed(level),spin:(r()-.5)*6,alive:true};T.objects.push(o);T.throwing=.5;onEvent('throw',o);return o;};\r\n  T.step=(dt,runner=0,active=true,lvl=0)=>{\r\n    T.t+=dt;T.throwing=Math.max(0,T.throwing-dt);level=lvl;\r\n    if(active){T.spawnIn-=dt;if(T.spawnIn<=0){T.spawn();T.spawnIn=(THROW.every[0]+r()*(THROW.every[1]-THROW.every[0]))*throwEvery(level);}}\r\n    for(const o of T.objects){o.d-=(o.speed+runner)*dt;if(o.d<THROW.near){o.alive=false;onEvent('miss',o);}}\r\n    T.objects=T.objects.filter(o=>o.alive);\r\n  };\r\n  T.clear=()=>{T.objects=[];};\r\n  // a,b: limb segment in screen units (x scaled by aspect, y 0..1); screen(o) -> {x,y,r} or null when not drawn.\r\n  T.strike=(a,b,kind,screen)=>{let n=0;for(const o of T.objects){if(!o.alive||o.d>THROW.reach)continue;const s=screen(o);if(!s)continue;\r\n    if(distPointSeg(s,a,b)<=s.r+THROW.pad){o.alive=false;o.kind=kind;T.hits++;T.xp+=THROW.xp;n++;onEvent('hit',{...o,kind,cut:Math.atan2(b.y-a.y,b.x-a.x)});onEvent('bonus',{xp:THROW.xp});}}\r\n    T.objects=T.objects.filter(o=>o.alive);return n;};\r\n  return T;\r\n}\r\n// Limb tracker: the same speed gate and screen mapping as camera-slice (the body as if the video filled the stage).\r\nexport function createStriker(){\r\n  const hist=new Map();\r\n  return (detail,view)=>{\r\n    const {points,now,width,height,mirrored}=detail;if(!points)return [];\r\n    const sw=view.width,sh=view.height,k=Math.min(sw/width,sh/height),ox=(sw-width*k)/2,oy=(sh-height*k)/2,t=(now??performance.now())/1000,out=[];\r\n    for(const i of LIMBS){const p=points[i];if(!p||(p.visibility??0)<THROW.seen){hist.delete(i);continue;}\r\n      const px=mirrored?1-p.x:p.x,q={x:(ox+px*width*k)/sh,y:(oy+p.y*height*k)/sh,t},h=hist.get(i)||[];h.push(q);if(h.length>6)h.shift();hist.set(i,h);\r\n      if(h.length<2)continue;const a=h[h.length-2],dt=t-a.t;\r\n      if(dt<=0||dt>.5||Math.hypot(q.x-a.x,q.y-a.y)/dt<THROW.fast)continue;\r\n      out.push({a,b:q,kind:pathKind(h)});}\r\n    return out;\r\n  };\r\n}\r\n// Three view: the coach at the far end, junk meshes, explode bursts and cut halves. pos(o) -> world Vector3.\r\nexport function mountThrowsView(THREE,scene){\r\n  const root=new THREE.Group();scene.add(root);\r\n  const geo=new THREE.DodecahedronGeometry(1,0),junk=new THREE.BoxGeometry(1.4,.8,.9),bit=new THREE.BoxGeometry(.08,.08,.08);\r\n  const mats=Object.fromEntries(Object.entries(TYPES).map(([k,[main,,light]])=>[k,new THREE.MeshStandardMaterial({color:main,emissive:light,emissiveIntensity:.35,roughness:.8,flatShading:true})]));\r\n  const meshes=new Map(),fx=[],holder=new THREE.Group();root.add(holder);let coach=null;\r\n  // The 3D clay coach from the site, stood up with the eyes toward the runner (as coach-3d coachElement does);\r\n  // a purple clay capsule until (or if never) the GLB loads.\r\n  const fallback=new THREE.Mesh(new THREE.CapsuleGeometry(.35,.9,4,8),new THREE.MeshStandardMaterial({color:'#8e5b99',roughness:.9,emissive:'#3a1a4a'}));holder.add(fallback);\r\n  const key=new THREE.PointLight('#f3dcff',8,7,1.4);key.position.set(0,.4,1.4);holder.add(key);\r\n  import('./coach-3d.mjs').then(m=>m.loadCoach(THREE)).then(c=>{coach=c;const pivot=new THREE.Group(),stand=new THREE.Group();pivot.rotation.x=Math.PI/2;pivot.add(c.group);stand.rotation.set(0,0,Math.PI/2);stand.add(pivot);stand.scale.setScalar(1.7);holder.add(stand);fallback.visible=false;}).catch(()=>{});\r\n  const make=o=>{const m=new THREE.Mesh(o.type==='satellite-junk'?junk:geo,mats[o.type]);m.scale.setScalar(o.r);meshes.set(o.id,m);root.add(m);return m;};\r\n  return {\r\n    hit(o,pos){const m=meshes.get(o.id);if(!m)return;meshes.delete(o.id);\r\n      if(o.kind==='slice'){for(const side of [-1,1]){const h=m.clone();h.scale.set(o.r,o.r*.5,o.r);h.position.copy(pos);root.add(h);fx.push({m:h,v:new THREE.Vector3(Math.cos(o.cut+Math.PI/2)*side*3,Math.sin(o.cut+Math.PI/2)*-side*3,1),spin:side*8,life:.8});}root.remove(m);}\r\n      else{root.remove(m);for(let i=0;i<14;i++){const b=new THREE.Mesh(bit,mats[o.type]);b.position.copy(pos);root.add(b);fx.push({m:b,v:new THREE.Vector3(Math.random()-.5,Math.random()-.3,Math.random()-.5).multiplyScalar(9),spin:10,life:.6});}}},\r\n    update(T,pos,coachPos,camera,dt,now){\r\n      for(const o of T.objects){const m=meshes.get(o.id)||make(o);m.position.copy(pos(o));m.rotation.set(T.t*o.spin,T.t*o.spin*.7,0);}\r\n      for(const [id,m] of meshes)if(!T.objects.some(o=>o.id===id)){root.remove(m);meshes.delete(id);}\r\n      for(const f of fx){f.life-=dt;f.m.position.addScaledVector(f.v,dt);f.m.rotation.x+=f.spin*dt;f.m.scale.multiplyScalar(f.life>0?.97:0);if(f.life<=0)root.remove(f.m);}\r\n      for(let i=fx.length-1;i>=0;i--)if(fx[i].life<=0)fx.splice(i,1);\r\n      holder.position.copy(coachPos);holder.lookAt(camera.position.x,coachPos.y,camera.position.z);\r\n      // Wind-up: a quick rear-back as each throw leaves his hand.\r\n      holder.rotateX(-T.throwing*.9);coach?.tick(now,{pressure:.5+T.throwing});\r\n    },\r\n    clear(){for(const m of meshes.values())root.remove(m);meshes.clear();},\r\n    dispose(){scene.remove(root);}};\r\n}\r\n","arcade/slice/camera-slice.mjs":"// Camera-workout overlay for the slice engine: the MOM Inc. gun fires barrels at you, tracked limbs slice or explode them.\r\n// Lazy: app.mjs imports this only for martial arts and holds (external in scripts/build.mjs, optional asset).\r\nimport {createSlice,render,pathKind} from './core.mjs';\r\nimport {createHandGlow,renderHandGlow} from './hand-glow.mjs';\r\nimport {mapPointToOverlay} from '../workout-effects.mjs';\r\nimport {createQuestProgressReporter} from '../quest-progress-reporter.mjs';\r\nconst LIMBS=[13,14,15,16,25,26,27,28]; // elbows, wrists, knees, ankles\r\nconst BODY=[11,12,23,24,15,16,27,28];\r\nconst FAST=.9,SEEN=.4; // screen heights per second a limb must travel; ponytail: one fixed gate, tune on device\r\nconst W=180;\r\nexport function createFruitStreakReporter(ownerId,load=()=>import('../../modules/vault/quest-progress.mjs')){\r\n const reporter=createQuestProgressReporter(ownerId,{load});\r\n return n=>reporter.record('fruit-streak',n);\r\n}\r\nconst OFF={x:0,y:0,v:0};\r\nfunction toScreen(p,{width,height,mirrored},hostWidth=innerWidth,hostHeight=innerHeight){ // the one shared contain+mirror mapper\r\n const m=mapPointToOverlay(p,{videoWidth:width,videoHeight:height,hostWidth,hostHeight,mirrored});\r\n return m?{x:m.x,y:m.y,v:m.visibility}:OFF;\r\n}\r\nconst reducedMotion=()=>{try{return !!globalThis.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;}catch{return false;}};\r\nexport function mountCameraSlice({host,mode='martial',sound=()=>{},onXp=()=>{},ownerId=null,seed=Date.now()}){\r\n const box=()=>{const r=host.getBoundingClientRect?.();return r&&r.width>0&&r.height>0?{w:r.width,h:r.height}:{w:innerWidth,h:innerHeight};};\r\n let size=box(),H=Math.round(W*size.h/size.w);const canvas=document.createElement('canvas');\r\n canvas.width=W;canvas.height=H;canvas.className='slice-canvas';canvas.setAttribute('aria-hidden','true');\r\n canvas.style.cssText='position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated;pointer-events:none';host.append(canvas);\r\n const g=canvas.getContext('2d');\r\n // Hand light trails get their own smooth, DPR-aware canvas in CSS px (the game stays 180-px pixel art).\r\n const trail=document.createElement('canvas');trail.className='slice-trail-canvas';trail.setAttribute('aria-hidden','true');\r\n trail.style.cssText='position:absolute;inset:0;width:100%;height:100%;pointer-events:none';host.append(trail);\r\n const tg=trail.getContext('2d');let dpr=1;\r\n function resize(){size=box();dpr=Math.min(2,window.devicePixelRatio||1);\r\n  const tw=Math.max(1,Math.round(size.w*dpr)),th=Math.max(1,Math.round(size.h*dpr));if(trail.width!==tw||trail.height!==th){trail.width=tw;trail.height=th;}\r\n  const nh=Math.round(W*size.h/size.w);if(nh!==H&&nh>0){H=nh;canvas.height=H;e?.resize(H);}}\r\n const e=createSlice({w:W,h:H,seed,mode,strikes:mode==='martial',onEvent(type,d){\r\n  if(type==='hit')sound(d.kind==='slice'?'barrel-split':d.type==='barrel-fuel'||d.type==='barrel-toxic'?'blast-big':'blast');\r\n  else if(type==='shot')sound('gun-shot');else if(type==='gun-aim')sound('gun-arm');else if(type==='chain')sound('blast');\r\n  else if(type==='bonus'){sound('dial');onXp(d.xp);}\r\n  else if(type==='combo'){sound('lever');reportStreak(d.n);}else if(type==='strike')sound('jelly');\r\n  else if(type==='laser-aim')sound('crt');else if(type==='laser-shield')sound('switch');else if(type==='laser-hit')sound('main-control');\r\n }});\r\n const reportStreak=createFruitStreakReporter(ownerId);\r\n const hist=new Map(),prevBody={pts:null,t:0};\r\n const handGlow=createHandGlow({onImpact(d){window.dispatchEvent(new CustomEvent('myr5:punch-impact',{detail:d}));if(!reducedMotion())try{navigator.vibrate?.(15);}catch{}}});\r\n const onLevel=ev=>handGlow.setLevel(ev.detail?.level);window.addEventListener('myr5:aura-level',onLevel);\r\n resize();const observer=typeof ResizeObserver==='function'?new ResizeObserver(resize):null;observer?.observe(host);let last=performance.now(),raf=0,laserIn=7,counting=false,body={x:W/2,y:H*.6};\r\n const onVisibility=()=>{if(document.visibilityState==='hidden')handGlow.clear();};document.addEventListener('visibilitychange',onVisibility);\r\n function frame(now){\r\n  raf=requestAnimationFrame(frame);const dt=Math.min(.05,(now-last)/1000);last=now;\r\n  if(counting){laserIn-=dt;if(laserIn<=0&&e.laserStart(body.x,body.y)){laserIn=9+Math.random()*6;}}\r\n  e.step(dt);\r\n  const effectStart=performance.now();handGlow.step(dt,now);\r\n  render(g,e,{pointerTrail:false});\r\n  tg.setTransform(dpr,0,0,dpr,0,0);tg.clearRect(0,0,size.w,size.h);\r\n  renderHandGlow(tg,handGlow.state,{w:size.w,h:size.h,now});handGlow.measure(performance.now()-effectStart,now);\r\n }\r\n raf=requestAnimationFrame(frame);\r\n return {\r\n  engine:e,\r\n  pose(detail){\r\n   const {points,now}=detail;counting=!!detail.counting;if(!points){handGlow.pose(null);return;}\r\n   const sp=points.map(p=>toScreen(p,detail,size.w,size.h)),toL=p=>({x:p.x*W,y:p.y*H});\r\n   handGlow.pose(points,{now:now??performance.now(),mapPoint:p=>toScreen(p,detail,size.w,size.h),world:detail.world,aspect:size.w/size.h,videoAspect:detail.width/detail.height||1});\r\n   // whole-body motion, screen heights per second, feeds the laser's stillness test\r\n   const t=(now??performance.now())/1000,pb=BODY.map(i=>sp[i]);\r\n   if(prevBody.pts&&t>prevBody.t){let s=0,n=0;BODY.forEach((_,k)=>{if(pb[k].v>SEEN&&prevBody.pts[k].v>SEEN){s+=Math.hypot(pb[k].x-prevBody.pts[k].x,pb[k].y-prevBody.pts[k].y);n++;}});if(n)e.feedMotion(s/n/(t-prevBody.t));}\r\n   prevBody.pts=pb;prevBody.t=t;\r\n   const core=[11,12,23,24].map(i=>sp[i]).filter(p=>p.v>SEEN);if(core.length)body=toL({x:core.reduce((a,p)=>a+p.x,0)/core.length,y:core.reduce((a,p)=>a+p.y,0)/core.length});\r\n   if(mode==='hold'){ // holds: any visible landmark touching a falling bonus item scores\r\n    sp.forEach((p,i)=>{if(i>0&&p.v>SEEN){const q=toL(p);e.hitSegment(q,q,{kind:'explode',pad:6});}});return;\r\n   }\r\n   for(const i of LIMBS){\r\n    const p=sp[i];if(p.v<SEEN){hist.delete(i);continue;}\r\n    const q=toL(p),h=hist.get(i)||[];h.push({...q,t});if(h.length>6)h.shift();hist.set(i,h);\r\n    if(h.length<2)continue;const a=h[h.length-2],dtp=t-a.t;\r\n    const spd=dtp>0?Math.hypot(q.x-a.x,q.y-a.y)/H/dtp:0;if(dtp<=0||dtp>.5||spd<FAST)continue;\r\n    e.addTrail(a.x,a.y);e.addTrail(q.x,q.y);\r\n    e.hitSegment(a,q,{kind:pathKind(h),pad:4,speed:spd});\r\n   }\r\n  },\r\n  stop(){cancelAnimationFrame(raf);document.removeEventListener('visibilitychange',onVisibility);window.removeEventListener('myr5:aura-level',onLevel);observer?.disconnect();handGlow.clear();canvas.remove();trail.remove();}\r\n };\r\n}\r\n","arcade/slice/core.check.mjs":"// node arcade/slice/core.check.mjs — physics, hit, curvature, laser stillness, gun cadence, wobble fairness, boom.\r\nimport assert from 'node:assert/strict';\r\nimport {createSlice,pathKind,pathCurvature,stillness,GUN,TYPES} from './core.mjs';\r\nimport {XP_SCALE} from '../../progression-rules.mjs';\r\nconst line=[...Array(6)].map((_,i)=>({x:i*.05,y:i*.05}));\r\nconst arc=[...Array(6)].map((_,i)=>({x:Math.sin(i/5*Math.PI)*.08+i*.02,y:i*.05}));\r\nconst loop=[...Array(6)].map((_,i)=>({x:Math.cos(i)*.1,y:Math.sin(i)*.1}));\r\nassert.equal(pathKind(line),'explode');assert.equal(pathKind(arc),'slice');assert.equal(pathKind(loop),'slice');assert.ok(pathCurvature(line)<.05);\r\nassert.ok(stillness([0,.1,.05]));assert.ok(!stillness([1,1.2,.9]));assert.ok(!stillness([]));\r\n// physics: arc rises from the bottom, apex well above, lands below -> strike\r\nconst ev=[];const e=createSlice({auto:false,seed:3,onEvent:t=>ev.push(t)});\r\nconst o=e.launch();assert.ok(o.vy<0&&o.y>e.h-10);let minY=1e9;for(let i=0;i<900&&e.objects.length;i++){e.step(1/60);for(const q of e.objects)minY=Math.min(minY,q.y);}\r\nassert.ok(minY<e.h*.6,'apex');assert.equal(e.strikes,1);assert.ok(ev.includes('strike'));\r\n// slice makes 2 halves, explode makes particles, bonus gives xp\r\nconst e2=createSlice({auto:false,seed:4});const a=e2.launch();a.x=90;a.y=100;a.vx=a.vy=0;\r\nassert.equal(e2.hitSegment({x:60,y:100},{x:120,y:100},{kind:'slice'}),1);assert.equal(e2.halves.length,2);assert.equal(e2.objects.length,0);\r\nconst b=e2.launch();b.x=90;b.y=100;b.vx=b.vy=0;e2.hitSegment({x:90,y:100},{x:90,y:100},{kind:'explode'});assert.ok(e2.parts.length>10);assert.equal(e2.halves.length,2);\r\nconst bo=e2.dropBonus();bo.x=50;bo.y=50;e2.hitSegment({x:50,y:50},{x:50,y:50});assert.equal(e2.xp,3*XP_SCALE);\r\n// combo: 3 hits in one swipe\r\nconst e3=createSlice({auto:false,seed:5});for(let i=0;i<3;i++){const q=e3.launch();q.x=30+i*30;q.y=100;q.vx=q.vy=0;}\r\ne3.hitSegment({x:0,y:100},{x:180,y:100});assert.equal(e3.combo,3);\r\n// volleys: 1-3 barrels each, never two volleys in the air, next one only volleyGap after the last is resolved\r\n{const f=createSlice({auto:true,seed:31,strikes:false});let gone=-1,sizes=new Set(),prevWave=0;f.step(1.2);sizes.add(f.objects.filter(o=>!o.bonus).length);prevWave=f.wave;\r\n for(let i=0;i<60*120;i++){const before=f.objects.filter(o=>!o.bonus).length;f.step(1/60);const live=f.objects.filter(o=>!o.bonus);\r\n  if(f.wave!==prevWave){assert.equal(before,0,'new volley only when none is in flight');if(gone>=0)assert.ok(f.t-gone>=GUN.volleyGap[3]-.05,'gap after resolve '+(f.t-gone));sizes.add(live.length);prevWave=f.wave;}\r\n  if(live.length===0&&before>0)gone=f.t;}\r\n assert.ok(f.wave>5);assert.ok([...sizes].every(n=>n>=1&&n<=3),'volley sizes '+[...sizes]);assert.ok(sizes.size>=2,'volleys vary');}\r\n// 3 strikes ends the wave, the set keeps going (no game over)\r\nconst e4=createSlice({auto:true,seed:6});let ended=false;e4.step(1.5);for(let i=0;i<3000&&!ended;i++){e4.step(1/60);ended=e4.cool>0;}assert.ok(ended&&e4.strikes===0&&!e4.over);\r\n// laser: moving = hit (strike), still = shield\r\nfor(const[move,want]of[[1,'hit'],[0,'shield']]){const l=createSlice({auto:false});l.laserStart(90,200);for(let i=0;i<30;i++){l.feedMotion(move);l.step(1/20);}l.step(.1);assert.equal(l.laser.result,want);assert.equal(l.strikes,want==='hit'?1:0);}\r\n// speed ramp: later waves keep the same apex but come down faster\r\nconst fly=sp=>{const f=createSlice({auto:false,seed:9});f.speed=sp;const q=f.launch();let top=1e9,t=0;while(f.objects.length&&t<10){f.step(1/120);t+=1/120;top=Math.min(top,q.y);}return {top,t};};\r\nconst s1=fly(1),s15=fly(1.5);assert.ok(Math.abs(s1.top-s15.top)<3,'same apex');assert.ok(s15.t<s1.t*.75,'faster at 1.5x');\r\n// bonus drops: holds every 5-7s, martial every 2-3s (each reset of bonusIn is a new gap)\r\nfor(const[mode,lo,hi]of[['hold',...GUN.bonusEvery.hold],['martial',...GUN.bonusEvery.martial]]){const f=createSlice({auto:true,mode,seed:11,strikes:false});let prev=f.bonusIn,gaps=[];for(let k=0;k<60*60;k++){f.step(1/60);if(f.bonusIn>prev)gaps.push(f.bonusIn);prev=f.bonusIn;}\r\n assert.ok(gaps.length>3&&gaps.every(g=>g>=lo-.02&&g<=hi),mode+' gaps '+gaps.map(g=>g.toFixed(2)));}\r\n// barrels only (no space junk); the first barrel of a wave flies straight\r\nassert.ok(Object.keys(TYPES).filter(k=>!k.startsWith('xp-')).every(k=>k.startsWith('barrel-')));\r\n// wobble: |x - straight line| <= amp the whole flight, back on the straight line at landing, y stays a pure parabola\r\n{const f=createSlice({auto:false,seed:21});f.wave=8;const q=f.launch(),x0=q.x,vx=q.vx,y0=q.y,vy=q.vy,g=q.g;q.hold=false;let n=0,worst=0,end=0,yerr=0;\r\n while(q.alive&&f.objects.includes(q)&&n++<2000){f.step(1/120);const t=q.flight;worst=Math.max(worst,Math.abs(q.x-(x0+vx*t)));if(q.y<f.h+q.r)yerr=Math.max(yerr,Math.abs(q.y-(y0+vy*t+g*t*t/2)));end=Math.abs(q.x-(x0+vx*q.flight));}\r\n assert.ok(worst>1,'barrels sway');assert.ok(worst<=Math.max(...GUN.wobbleAmp)+1e-6,'sway '+worst);assert.ok(end<.5,'lands on the straight line '+end);assert.ok(yerr<3,'vertical stays a parabola '+yerr);}\r\n// wave 1: no wobble at all; later waves: the first barrel of a wave is the straight one\r\n{const f=createSlice({auto:false,seed:22});f.wave=1;assert.equal(f.launch().wA,0);f.wave=5;let swayed=false;for(let i=0;i<20;i++){f.objects=[];f.spawnWave();assert.equal(f.objects[0].wA,0);swayed||=f.objects.slice(1).some(o=>o.wA>0);}assert.ok(swayed);}\r\n// gun: one shot per launched barrel, aim cue about GUN.aim before the first, cadence under the shots/s cap, spin capped\r\n{const ev=[],f=createSlice({auto:false,seed:23,onEvent:(t,d)=>ev.push([t,f.t])});f.wave=4;f.speed=1.1;f.spawnWave();const n=f.objects.length;assert.ok(f.objects.every(o=>Math.abs(o.vr)<=GUN.spinMax));\r\n for(let i=0;i<60*8;i++)f.step(1/60);\r\n const shots=ev.filter(x=>x[0]==='shot'),aims=ev.filter(x=>x[0]==='gun-aim');assert.equal(shots.length,n,'one shot per barrel');assert.equal(f.shots,n);\r\n assert.ok(aims.length>=1&&Math.abs(shots[0][1]-aims[0][1]-GUN.aim)<.03,'aim leads the first shot by ~aim: '+(shots[0][1]-aims[0][1]));\r\n for(let i=1;i<shots.length;i++)assert.ok(shots[i][1]-shots[i-1][1]>=1/GUN.shotsPerSec[1]-.03,'shots/s cap');}\r\n// hit-pause: freeze skips steps without advancing time; explode sets it, slice does not\r\n{const f=createSlice({auto:false,seed:24});const a=f.spawn({type:'barrel-wood',x:60,y:100,r:12});f.hitSegment({x:40,y:100},{x:80,y:100},{kind:'slice'});assert.equal(f.freeze,0);\r\n const b=f.spawn({type:'barrel-wood',x:60,y:100,r:12});f.hitSegment({x:60,y:100},{x:60,y:100},{kind:'explode'});assert.ok(f.freeze>0&&f.shake>0&&f.fx.length>5,'boom layers');\r\n const t0=f.t;f.step(1/60);assert.equal(f.t,t0,'frozen step');f.freeze=0;f.step(1/60);assert.ok(f.t>t0);}\r\n// fuel chain: a neighbour in range explodes once, 80 ms later; the chained one does not chain on\r\n{const ev=[],f=createSlice({auto:false,seed:25,onEvent:t=>ev.push(t)});const a=f.spawn({type:'barrel-fuel',x:60,y:100,r:12}),b=f.spawn({type:'barrel-wood',x:100,y:100,r:12}),c=f.spawn({type:'barrel-fuel',x:150,y:100,r:12});\r\n a.g=b.g=c.g=0;f.hitSegment({x:60,y:100},{x:60,y:100},{kind:'explode'});assert.equal(f.hits,1);\r\n for(let i=0;i<30;i++)f.step(1/60);assert.equal(ev.filter(t=>t==='chain').length,1,'one chained barrel');assert.ok(!b.alive);assert.ok(c.alive,\"out of range survives\");}\r\n// HARD HIT: speed over the gate scores +5\r\n{const f=createSlice({auto:false,seed:26});f.spawn({type:'barrel-wood',x:60,y:100,r:12});f.hitSegment({x:60,y:100},{x:60,y:100},{kind:'explode',speed:GUN.hardHit+.1});assert.equal(f.score,15);}\r\nconsole.log('slice core ok');\r\n","arcade/slice/core.mjs":"// Fruit-Ninja slice engine: input-agnostic (pose limbs, finger swipes, taps all call hitSegment) + 2D pixel renderer.\r\n// Logical canvas is small (default 180x320); scale it up in CSS with image-rendering:pixelated.\r\n// Optional art: arcade/slice/sprites/<type>.png = 8 rotation frames of 64px cells in one row (Tripo renders replace the procedural pixels).\r\n// [main, shade, light] per object id. Every id's art is arcade/slice/sprites/<id>.png (Tripo render) or, until it exists,\r\n// the canister placeholder sheet tinted with the main colour.\r\nimport {XP_SCALE} from '../../progression-rules.mjs';\r\n// The MOM Inc. barrel blaster replaces the old coach thrower. All tuning lives here (real phones need tuning).\r\nexport const GUN={\r\n aim:.45,            // s of LED blink + tube tracking before each shot\r\n recoilPx:6, recoilS:.12, flashS:.09, scale:2, // scale = integer pixel multiplier for the 48x24 gun art\r\n shakeShot:.18, shakeSlice:.12, shakeExplode:.25, shakeBig:.4, shakeDecay:.85, shakePx:8,\r\n freeze:.04,         // hit-pause on explode\r\n scaleStart:.6,      // drawn size at the muzzle, grows to 1 by the apex (collision always full)\r\n wobbleAmp:[0,4,6,8],// by wave band 1,2,3-6,7+ (logical px, <=25% of a barrel radius)\r\n wobbleHz:[1,1.6], wobbleFadeLast:.3, wobbleFadeIn:.25, // fade out over the last fraction of the flight, in over the first seconds\r\n spinMax:Math.PI*2,  // rad/s, rolling not tumbling\r\n shotsPerSec:[1.5,2.2,2.8], // within a volley, wave 1-2, 3-6, 7+\r\n // Fruit Ninja rhythm: a volley is 1-3 barrels (pick one entry), the next volley only starts volleyGap s AFTER the last barrel is resolved (hit or off-screen).\r\n volley:[[1,1,2],[1,2],[1,2,2,3],[2,3,3]], volleyGap:[1.4,1.1,.9,.8], // by wave band 1,2,3-6,7+\r\n bonusEvery:{hold:[6,9],martial:[4,6]}, // s between XP bonus drops\r\n hardHit:1.6,        // limb speed (screen heights/s) for +5 HARD HIT\r\n chainRadius:28, chainDelay:.08, // fuel barrel: other barrels whose centre is within r+chainRadius blow 80 ms later (one level)\r\n trailEvery:.06, trailMax:3,\r\n brand:{plate:'#ff4fd8',stencil:'#fff',stripe:'#ffd23a',body:'#3a3f4a',hi:'#5b6475',led:'#ffb000'},\r\n};\r\n// [main, shade, light] per id. Barrel art: arcade/slice/sprites/<id>.png (Tripo sheet) or the procedural 16x16 barrel below.\r\nexport const TYPES={'barrel-wood':['#a3642c','#5e3514','#e0a060'],'barrel-steel':['#7d8aa0','#3f4a5c','#d6e0f0'],'barrel-toxic':['#4fcf4a','#1f6e22','#c8ffb0'],'barrel-fuel':['#d8342a','#6e1410','#ffb070'],'xp-star':['#ffe14a','#c8901a','#fffbd0'],'xp-orb':['#4affc8','#1a9c80','#d8fff4']};\r\nexport const TYPE_IDS=Object.keys(TYPES).filter(k=>!k.startsWith('xp-'));\r\nexport const BONUS_IDS=['xp-star','xp-orb'];\r\nconst TYPE_BAG=['barrel-wood','barrel-wood','barrel-wood','barrel-wood','barrel-steel','barrel-steel','barrel-toxic','barrel-toxic','barrel-fuel']; // common wood, rare fuel\r\n// Explosion size per barrel: particle count, stave chunks, smoke puffs, screen shake, ring growth, stain life.\r\nconst BOOM={'barrel-wood':{parts:22,chunks:8,smoke:4,shake:GUN.shakeExplode,ring:2.2,stain:4},'barrel-steel':{parts:16,chunks:7,smoke:4,shake:GUN.shakeExplode,ring:2.2,stain:4},\r\n 'barrel-toxic':{parts:30,chunks:6,smoke:6,shake:GUN.shakeExplode,ring:2.5,stain:5.5},'barrel-fuel':{parts:40,chunks:10,smoke:6,shake:GUN.shakeBig,ring:3,stain:4}};\r\nexport const TARGET_SIZE=2.5;\r\nconst GRAVITY=260,TAU=Math.PI*2,HALF_LIFE=1.25;\r\nexport function rng(seed=1){return()=>{seed|=0;seed=seed+0x6D2B79F5|0;let t=Math.imul(seed^seed>>>15,1|seed);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}\r\nexport function distPointSeg(p,a,b){const dx=b.x-a.x,dy=b.y-a.y,l=dx*dx+dy*dy,t=l?Math.max(0,Math.min(1,((p.x-a.x)*dx+(p.y-a.y)*dy)/l)):0;return Math.hypot(p.x-(a.x+t*dx),p.y-(a.y+t*dy));}\r\n// Straight shot (punch, kick) vs looping shot (chop, hook, roundhouse): sideways bow of the last ~6 points relative to the chord.\r\nexport function pathCurvature(pts){\r\n const p=pts.slice(-6);if(p.length<3)return 0;\r\n const a=p[0],b=p[p.length-1],chord=Math.hypot(b.x-a.x,b.y-a.y);let path=0,bow=0;\r\n for(let i=1;i<p.length;i++)path+=Math.hypot(p[i].x-p[i-1].x,p[i].y-p[i-1].y);\r\n if(path<1e-9)return 0;\r\n for(const q of p)bow=Math.max(bow,distPointSeg(q,a,b));\r\n return chord<path*.25?1:Math.min(1,bow/Math.max(chord,1e-9)*2); // loops back on itself = fully curved\r\n}\r\nexport const pathKind=(pts,limit=.2)=>pathCurvature(pts)>limit?'slice':'explode';\r\n// samples = whole-body motion per second (screen heights/s); still enough = shield up.\r\nexport const stillness=(samples,max=.1)=>samples.length>0&&samples.reduce((s,v)=>s+v,0)/samples.length<=max;\r\n\r\nexport function createSlice({w=180,h=320,seed=1,mode='martial',auto=true,coachX=w/2,stillMax=.1,strikes=true,onEvent=()=>{}}={}){\r\n const rand=rng(seed),pick=a=>a[Math.floor(rand()*a.length)];\r\n const e={w,h,mode,coachX,objects:[],halves:[],parts:[],stains:[],trail:[],pops:[],t:0,wave:0,strikes:0,score:0,xp:0,combo:0,best:0,hits:0,over:false,\r\n  laser:{phase:'idle',t:0,tx:0,ty:0,samples:[],result:null,flash:0},cool:0,spawnIn:1,bonusIn:4,swipeAt:-9,swipeN:0,speed:1,\r\n  gun:{phase:'idle',t:0,tx:coachX,ang:0,recoil:0,flash:0},shake:0,freeze:0,shots:0,lastShot:-9,fx:[],chain:[]};\r\n const emit=(type,data)=>onEvent(type,data);\r\n e.resize=nh=>{if(nh>0)h=e.h=nh;}; // orientation change: the world keeps its width, height follows the host\r\n const pop=(text,x,y,c='#fff',big=false)=>e.pops.push({text,x,y,c,big,life:big?1.1:.8});\r\n function mk(type,x,y,vx,vy,r,bonus=false){const o={type,x,y,vx,vy,r:r*TARGET_SIZE,rot:rand()*TAU,vr:bonus?(rand()-.5)*8:(vx<0?-1:1)*(3+rand()*3),bonus,alive:true,seed:Math.floor(rand()*1e6),\r\n   flight:0,T:0,wA:0,wF:0,wP:0,wOff:0,sc:bonus||mode==='rest'?1:GUN.scaleStart,trail:[],trailAt:0};o.vr=Math.max(-GUN.spinMax,Math.min(GUN.spinMax,o.vr));e.objects.push(o);return o;}\r\n const bandOf=w=>w<=1?0:w<=2?1:w<=6?2:3,wobble=(o,amp,T)=>{o.T=T;o.wA=amp*(rand()*.5+.5);o.wF=GUN.wobbleHz[0]+rand()*(GUN.wobbleHz[1]-GUN.wobbleHz[0]);o.wP=rand()*TAU;};\r\n // Parabola from the coach at the bottom toward the user: same apex every wave; speed scales gravity so later waves fall faster, not higher.\r\n e.launch=()=>{const tx=w*(.15+rand()*.7),apex=h*(.45+rand()*.35),g=GRAVITY*e.speed*e.speed,vy=-Math.sqrt(2*g*apex),T=-2*vy/g;\r\n  const o=mk(pick(TYPE_BAG),coachX,h-4,(tx-coachX)/T,vy,11+rand()*6);o.g=g;o.tApex=-vy/g;wobble(o,GUN.wobbleAmp[bandOf(e.wave)],T);return o;};\r\n // Generic thrower (rest mode: coach throws DOWN from the top): e.spawn({type,x,y,vx,vy,r,bonus}); non-bonus objects feel gravity.\r\n // wobble = max sideways sway in logical px, T = flight time (fades the sway out so the landing spot stays fair).\r\n e.spawn=({type=pick(TYPE_BAG),x,y,vx=0,vy=0,r=12,bonus=false,wobble:amp=0,T=0})=>{const o=mk(type,x,y,vx,vy,r,bonus);if(amp)wobble(o,amp,T);return o;};\r\n e.dropBonus=()=>mk(pick(BONUS_IDS),w*(.1+rand()*.8),-12,(rand()-.5)*6,22+rand()*10,9,true);\r\n // Barrels are held, then fired one by one by the gun (aim cue first). Gap = 1/shots-per-second cap by wave band.\r\n e.spawnWave=()=>{const n=pick(GUN.volley[bandOf(e.wave)]),gap=1/GUN.shotsPerSec[Math.min(2,Math.max(0,bandOf(e.wave)-1))];for(let i=0;i<n;i++){const o=e.launch();if(!i)o.wA=0;o.hold=true;o.delay=GUN.aim+i*gap;o.vx0=o.vx;o.vy0=o.vy;o.vx=o.vy=0;}};\r\n // Gun: aim cue (tube tracks tx, LED blinks) then fire (recoil, muzzle flash, shake). Rest mode calls these around its throws.\r\n e.gunAim=tx=>{const G=e.gun;if(G.phase==='aim')return;G.phase='aim';G.t=0;G.tx=tx;emit('gun-aim',{tx});};\r\n e.gunFire=()=>{const G=e.gun;G.phase='fire';G.t=0;G.recoil=1;G.flash=GUN.flashS;e.shake=Math.max(e.shake,GUN.shakeShot);e.shots++;e.lastShot=e.t;emit('shot',{});};\r\n function burst(x,y,type,n,spread){const cs=TYPES[type];for(let i=0;i<n;i++){const a=rand()*TAU,s=spread*(.3+rand());e.parts.push({x,y,vx:Math.cos(a)*s,vy:Math.sin(a)*s-30,life:.5+rand()*.4,c:pick(cs),s:1+Math.floor(rand()*3)});}}\r\n function smoke(o,n){for(let i=0;i<n;i++)e.fx.push({kind:'smoke',x:o.x+(rand()-.5)*o.r,y:o.y+(rand()-.5)*o.r*.6,vx:(rand()-.5)*10,life:.6,max:.6,d:0});}\r\n // Layered boom: white flash -> tinted flash -> shockwave ring -> stave chunks -> smoke, plus particles, shake and a hit-pause. Fuel chains once.\r\n function boom(o,chained){\r\n  const B=BOOM[o.type]||BOOM['barrel-wood'],cs=TYPES[o.type];burst(o.x,o.y,o.type,B.parts,120+B.parts*2);\r\n  e.fx.push({kind:'flash',x:o.x,y:o.y,r:o.r*.9,c:'#fff',c2:cs[2],life:.07,max:.07,d:0});\r\n  if(o.type==='barrel-fuel')e.fx.push({kind:'flash',x:o.x,y:o.y,r:o.r*1.2,c:'#ffe9a0',c2:'#ff8a30',life:.09,max:.09,d:.06});\r\n  e.fx.push({kind:'ring',x:o.x,y:o.y,r0:o.r,r1:o.r*B.ring,c:cs[2],life:.25,max:.25,d:0});\r\n  for(let i=0;i<B.chunks;i++){const a=rand()*TAU,sp=60+rand()*90;e.fx.push({kind:'chunk',x:o.x,y:o.y,vx:Math.cos(a)*sp,vy:Math.sin(a)*sp-50,rot:rand()*TAU,vr:(rand()-.5)*14,c:cs[i%2],life:.6+rand()*.4,max:1,d:0});}\r\n  smoke(o,B.smoke);\r\n  e.shake=Math.max(e.shake,B.shake);if(!chained)e.freeze=GUN.freeze;\r\n  if(o.type==='barrel-fuel'&&!chained)for(const q of e.objects)if(q!==o&&q.alive&&!q.hold&&!q.bonus&&Math.hypot(q.x-o.x,q.y-o.y)<=o.r+GUN.chainRadius&&!e.chain.some(c=>c.o===q))e.chain.push({o:q,t:GUN.chainDelay});\r\n }\r\n function award(o,kind,a,b,{speed=0,chained=false}={}){\r\n  o.alive=false;e.hits++;let stain=4;\r\n  if(kind==='slice'){const ang=Math.atan2(b.y-a.y,b.x-a.x),n=[-Math.sin(ang),Math.cos(ang)];for(const side of[-1,1])e.halves.push({...o,cut:ang,side,life:HALF_LIFE,vx:o.vx*.5+n[0]*side*60,vy:o.vy*.5+n[1]*side*60,rot0:o.rot,hr:0,hvr:side*(2+rand()*4)});burst(o.x,o.y,o.type,8,60);\r\n   if(!o.bonus){smoke(o,3);e.shake=Math.max(e.shake,GUN.shakeSlice);}}\r\n  else if(o.bonus)burst(o.x,o.y,o.type,22,120);\r\n  else{boom(o,chained);stain=(BOOM[o.type]||BOOM['barrel-wood']).stain;}\r\n  e.stains.push({c:TYPES[o.type][1],life:stain,dots:Array.from({length:7},()=>[o.x+(rand()-.5)*20,o.y+(rand()-.5)*20,1+Math.floor(rand()*3)])}); // juice splat fades on the background\r\n  if(o.bonus){e.xp+=3*XP_SCALE;e.score+=15;pop(`+${3*XP_SCALE} XP`,o.x,o.y-10,'#ffe14a');emit('bonus',{xp:3*XP_SCALE,x:o.x,y:o.y,kind});}\r\n  else if(chained){e.score+=10;emit('chain',{x:o.x,y:o.y,type:o.type});return;}\r\n  else{const hard=speed>=GUN.hardHit;e.score+=hard?15:10;if(hard)pop('HARD HIT',o.x,o.y-o.r-4,'#ffb000');emit('hit',{kind,x:o.x,y:o.y,type:o.type,hard});}\r\n  if(e.t-e.swipeAt>.45)e.swipeN=0;e.swipeAt=e.t;e.swipeN++;\r\n  if(e.swipeN>=3){const bonus=10*(e.swipeN-2);e.score+=bonus;e.combo=e.swipeN;e.best=Math.max(e.best,e.combo);pop(`COMBO x${e.swipeN}`,w/2,h*.35,'#ff4fd8',true);emit('combo',{n:e.swipeN,bonus});}\r\n }\r\n // Sweep a limb/finger segment a->b (logical coords). A tap/touch is a===b. Returns the number of objects hit.\r\n e.hitSegment=(a,b,{kind='slice',pad=2,speed=0}={})=>{let n=0;for(const o of e.objects)if(o.alive&&!o.hold&&distPointSeg(o,a,b)<=o.r+pad){award(o,kind,a,b,{speed});n++;}e.objects=e.objects.filter(o=>o.alive);return n;};\r\n e.addTrail=(x,y)=>e.trail.push({x,y,life:.25});\r\n // Laser (the bomb): ~1s red sight-line, then it fires. feedMotion() collects whole-body motion during the aim window.\r\n e.laserStart=(tx,ty,aim=1)=>{if(e.laser.phase!=='idle')return false;Object.assign(e.laser,{phase:'aim',t:0,aim,tx,ty,samples:[],result:null});emit('laser-aim',{tx,ty});return true;};\r\n e.feedMotion=m=>{if(e.laser.phase==='aim')e.laser.samples.push(m);};\r\n function fire(){const L=e.laser,shield=stillness(L.samples,stillMax);L.phase='fire';L.t=0;L.result=shield?'shield':'hit';\r\n  if(shield){emit('laser-shield',{x:L.tx,y:L.ty});pop('BLOCKED',L.tx,L.ty-20,'#7cf',true);}\r\n  else{L.flash=.35;strike();emit('laser-hit',{x:L.tx,y:L.ty});pop('ZAPPED',L.tx,L.ty-20,'#f44',true);}}\r\n function strike(){if(e.cool>0)return;e.strikes++;emit('strike',{n:e.strikes});if(e.strikes>=3){e.cool=3;e.strikes=0;e.objects=[];emit('wave-end',{wave:e.wave});pop('WAVE OVER - KEEP GOING',w/2,h*.4,'#fff',true);}}\r\n e.step=dt=>{\r\n  if(e.freeze>0){e.freeze-=dt;return;} // hit-pause: the world holds for a beat on a big explosion\r\n  e.t+=dt;e.shake*=Math.pow(GUN.shakeDecay,dt*60);if(e.shake<.02)e.shake=0;\r\n  const G=e.gun;G.t+=dt;if(G.recoil>0)G.recoil=Math.max(0,G.recoil-dt/GUN.recoilS);if(G.flash>0)G.flash-=dt;if(G.phase==='fire'&&G.t>=GUN.recoilS)G.phase='idle';\r\n  let next=null;for(const o of e.objects)if(o.hold&&(!next||o.delay<next.delay))next=o;\r\n  if(next&&next.delay<=GUN.aim&&G.phase!=='aim')e.gunAim(next.x+next.vx0*(-2*next.vy0/next.g)); // aim at where the next barrel lands\r\n  G.ang+=((G.phase==='aim'?Math.max(-.61,Math.min(.61,Math.atan2(G.tx-e.coachX,e.h*.55))):0)-G.ang)*Math.min(1,dt*20);\r\n  if(e.cool>0){e.cool-=dt;if(e.cool<=0)e.speed=Math.max(1,e.speed-.1);}\r\n  else if(auto&&!e.over){\r\n   if(mode==='martial'&&!e.objects.some(o=>!o.bonus)){e.spawnIn-=dt;if(e.spawnIn<=0){e.wave++;e.speed=Math.min(1.5,1+e.wave*.04);e.spawnWave();e.spawnIn=GUN.volleyGap[bandOf(e.wave)];emit('wave',{wave:e.wave});}} // gap counts only once the volley is resolved\r\n   e.bonusIn-=dt;if(e.bonusIn<=0){e.dropBonus();{const[lo,hi]=GUN.bonusEvery[mode==='hold'?'hold':'martial'];e.bonusIn=lo+rand()*(hi-lo);}}\r\n  }\r\n  for(const o of e.objects){\r\n   if(o.hold){o.delay-=dt;if(o.delay<=0){o.hold=false;o.vx=o.vx0;o.vy=o.vy0;e.gunFire();}continue;}\r\n   o.rot+=o.vr*dt;o.x+=o.vx*dt;o.y+=o.vy*dt;if(!o.bonus)o.vy+=(o.g||GRAVITY)*dt;\r\n   o.flight+=dt;\r\n   if(o.wA){const f=Math.min(1,o.flight/GUN.wobbleFadeIn)*(o.T?Math.max(0,Math.min(1,(o.T-o.flight)/(o.T*GUN.wobbleFadeLast))):1),off=o.wA*f*Math.sin(TAU*o.wF*o.flight+o.wP);o.x+=off-o.wOff;o.wOff=off;} // sideways sway only; the vertical stays a pure parabola\r\n   if(!o.bonus){o.sc=mode==='rest'?1-.25*Math.min(1,o.flight/(o.T||2)):GUN.scaleStart+(1-GUN.scaleStart)*Math.min(1,o.flight/(o.tApex||1));\r\n    if(o.flight>=o.trailAt){o.trailAt=o.flight+GUN.trailEvery;o.trail.push({x:o.x,y:o.y});if(o.trail.length>GUN.trailMax)o.trail.shift();}}\r\n   if(o.vy>0&&o.y>h+o.r){o.alive=false;if(!o.bonus){emit('land',{x:o.x,type:o.type});if(strikes)strike();}} // a missed rock lands = strike\r\n  }\r\n  for(const c of e.chain)if((c.t-=dt)<=0&&c.o.alive){award(c.o,'explode',c.o,c.o,{chained:true});}\r\n  e.chain=e.chain.filter(c=>c.t>0);\r\n  e.objects=e.objects.filter(o=>o.alive);\r\n  for(const q of e.fx){if(q.d>0){q.d-=dt;continue;}q.life-=dt;if(q.kind!=='ring'&&q.kind!=='flash'){q.x+=(q.vx||0)*dt;q.y+=(q.vy||-20)*dt;if(q.kind==='chunk'){q.vy+=GRAVITY*.6*dt;q.rot+=q.vr*dt;}}}e.fx=e.fx.filter(q=>q.life>0);\r\n  for(const q of e.halves){q.x+=q.vx*dt;q.y+=q.vy*dt;q.vy+=GRAVITY*dt;q.hr+=q.hvr*dt;q.life-=dt;}e.halves=e.halves.filter(q=>q.life>0&&q.y<h+40);\r\n  for(const q of e.parts){q.x+=q.vx*dt;q.y+=q.vy*dt;q.vy+=GRAVITY*.6*dt;q.life-=dt;}e.parts=e.parts.filter(q=>q.life>0);\r\n  for(const q of e.stains)q.life-=dt;e.stains=e.stains.filter(q=>q.life>0);\r\n  for(const q of e.trail)q.life-=dt;e.trail=e.trail.filter(q=>q.life>0);\r\n  for(const q of e.pops){q.life-=dt;q.y-=14*dt;}e.pops=e.pops.filter(q=>q.life>0);\r\n  const L=e.laser;if(L.flash>0)L.flash-=dt;\r\n  if(L.phase==='aim'){L.t+=dt;if(L.t>=L.aim)fire();}else if(L.phase==='fire'){L.t+=dt;if(L.t>=(L.result==='shield'?.7:.3))L.phase='idle';}\r\n };\r\n return e;\r\n}\r\n\r\n// ---- renderer ----\r\nconst sheets={},cache={};\r\n// sheet(id): the id's own sheet (Tripo render). Bonus ids fall back to the tinted canister; barrels and the gun go procedural. null until loaded.\r\nfunction load(src){return new Promise((ok,no)=>{const i=new Image();i.onload=()=>ok(i);i.onerror=no;i.src=src;});}\r\nfunction tinted(img,colour){const c=document.createElement('canvas');c.width=img.width;c.height=img.height;const x=c.getContext('2d');x.drawImage(img,0,0);x.globalCompositeOperation='multiply';x.fillStyle=colour;x.fillRect(0,0,c.width,c.height);x.globalCompositeOperation='destination-in';x.drawImage(img,0,0);return c;}\r\nfunction sheet(type){\r\n if(typeof Image==='undefined')return null;\r\n if(!(type in sheets)){sheets[type]=null;const base=`/arcade/slice/sprites/`;\r\n  load(base+type+'.png').then(i=>{sheets[type]=i;},()=>{if(type.startsWith('xp-'))load(base+'canister.png').then(i=>{sheets[type]=tinted(i,TYPES[type][0]);},()=>{});});}\r\n return sheets[type];\r\n}\r\nconst canvasOf=(w,h)=>{const c=document.createElement('canvas');c.width=w;c.height=h;return c;};\r\nfunction procedural(type,seed){ // 16x16: barrels get a staved cylinder with steel hoops and a MOM dot; bonuses stay hash-shaded discs\r\n const k=type+seed%7;if(cache[k])return cache[k];const c=canvasOf(16,16),g=c.getContext('2d'),cs=TYPES[type];\r\n if(type.startsWith('barrel-')){\r\n  for(let y=0;y<16;y++)for(let x=2;x<14;x++){if((y===0||y===15)&&(x===2||x===13))continue;g.fillStyle=(x-2)%3===2||x===13?cs[1]:x===3?cs[2]:cs[0];g.fillRect(x,y,1,1);}\r\n  g.fillStyle='#9aa6b4';for(const y of[3,12])g.fillRect(2,y,12,2);g.fillStyle='#d8e2ee';for(const y of[3,12])g.fillRect(3,y,1,1);\r\n  g.fillStyle=GUN.brand.plate;g.fillRect(6,6,3,3);g.fillStyle='#fff';g.fillRect(6,6,1,1);\r\n  return cache[k]=c;\r\n }\r\n for(let y=0;y<16;y++)for(let x=0;x<16;x++){const d=Math.hypot(x-7.5,y-7.5);if(d>7.5)continue;const n=((x*73856093^y*19349663^seed%7*83492791)>>>0)%7;g.fillStyle=d>6.2?cs[1]:x+y<9&&n<5?cs[2]:n<2?cs[1]:cs[0];g.fillRect(x,y,1,1);}\r\n return cache[k]=c;\r\n}\r\nfunction drawBody(g,o){\r\n const s=sheet(o.type),r=o.r*(o.sc||1);\r\n if(s){const f=Math.floor(((o.rot%TAU+TAU)%TAU)/TAU*8)%8;g.drawImage(s,f*64,0,64,64,-r,-r,r*2,r*2);}\r\n else{g.save();g.rotate(Math.round(o.rot/(Math.PI/4))*Math.PI/4);g.drawImage(procedural(o.type,o.seed),-r,-r,r*2,r*2);g.restore();}\r\n if(o.bonus){g.strokeStyle='#ffe14a';g.lineWidth=1;g.strokeRect(-r-1,-r-1,r*2+2,r*2+2);}\r\n}\r\n\r\n// ---- the MOM Inc. gun: 48x24 receiver + separate 8x22 tube that rotates about the pivot ----\r\nconst PIV={x:24,y:9},TUBE=20; // pivot in the receiver canvas (unflipped), visible tube length in art px\r\nfunction gunArt(flip){\r\n const k='gun'+flip;if(cache[k])return cache[k];const B=GUN.brand,body=canvasOf(48,24),g=body.getContext('2d');\r\n const R=(x,y,w,h,c)=>{g.fillStyle=c;g.fillRect(x,flip?24-y-h:y,w,h);}; // flip = hang from the ceiling (rest mode); the plate stays upright\r\n R(14,22,20,2,'#6b7280');R(14,22,20,1,'#8b95a8');                                  // bolted mount\r\n R(8,8,32,14,B.body);R(8,10,32,1,B.hi);R(8,20,32,2,'#262a33');R(8,8,1,2,'#262a33');R(39,8,1,2,'#262a33'); // receiver\r\n for(let x=8;x<40;x+=4){R(x,8,2,2,B.stripe);R(x+2,8,2,2,'#111');}                   // hazard stripe along the top edge\r\n R(9,12,2,8,B.hi);R(37,12,2,8,B.hi);R(10,14,1,1,'#111');R(10,18,1,1,'#111');R(37,14,1,1,'#111');R(37,18,1,1,'#111'); // grips + bolts\r\n R(17,12,14,7,B.plate);R(17,12,14,1,'#ffa0ec');R(17,18,14,1,'#c0309a');             // MOM Inc. plate\r\n const M=['X...X','XX.XX','X.X.X','X...X','X...X'];g.fillStyle=B.stencil;M.forEach((row,j)=>{for(let i=0;i<5;i++)if(row[i]==='X')g.fillRect(21+i,(flip?5:12)+1+j,1,1);}); // stencil drawn upright even when the gun hangs flipped\r\n R(26,13,4,1,'#c0309a');R(26,15,4,1,'#c0309a');R(26,17,4,1,'#c0309a');              // \"INC\" tick marks beside the stencil\r\n const tube=canvasOf(8,22),t=tube.getContext('2d');\r\n t.fillStyle=B.body;t.fillRect(1,2,6,20);t.fillStyle=B.hi;t.fillRect(2,2,1,20);t.fillStyle='#262a33';t.fillRect(6,2,1,20);\r\n t.fillStyle='#8b95a8';t.fillRect(0,0,8,2);t.fillStyle='#5b6475';t.fillRect(0,2,8,1);t.fillStyle='#8b95a8';t.fillRect(0,8,8,1);t.fillRect(0,15,8,1); // muzzle ring + collars\r\n return cache[k]={body,tube};\r\n}\r\n// Pose of the gun for a mount point: x = centre, y = bottom edge (flip: top edge).\r\nfunction gunPose(e,{x=e.coachX,y=e.h,flip=false}={}){\r\n const s=GUN.scale,ox=x-24*s,oy=flip?y:y-24*s,py=oy+(flip?24-PIV.y:PIV.y)*s,G=e.gun,a=Math.round(G.ang/(Math.PI/16))*(Math.PI/16),d=flip?1:-1;\r\n return {s,ox,oy,px:x,py,a,d,mx:x+Math.sin(a)*TUBE*s,my:py+d*Math.cos(a)*TUBE*s};\r\n}\r\n// Where the laser/shots leave the gun (angle 0, no recoil), for hosts that draw their own beam.\r\nexport const gunMuzzle=(e,o)=>{const p=gunPose({...e,gun:{ang:0}},o);return {x:p.mx,y:p.my};};\r\nexport function drawGun(g,e,o={}){\r\n const G=e.gun,p=gunPose(e,o),s=p.s,{body,tube}=gunArt(!!o.flip),rc=GUN.recoilPx*G.recoil;\r\n g.save();g.translate(Math.round(-Math.sin(p.a)*rc),Math.round(-p.d*Math.cos(p.a)*rc)); // kicks back opposite the shot, along the barrel axis\r\n const sh=sheet('gun');\r\n if(sh){const cell=G.flash>0?5:G.recoil>.5?6:G.phase==='aim'&&Math.floor(G.t*16)%2===0?7:Math.max(0,Math.min(4,Math.round(p.a/.61*2)+2)),z=48*s;\r\n  g.save();g.translate(Math.round(p.px),Math.round(p.py));if(o.flip)g.scale(1,-1);g.drawImage(sh,cell*64,0,64,64,-z/2,-z+11*s,z,z);g.restore();}\r\n else{\r\n  g.save();g.translate(Math.round(p.px),Math.round(p.py));if(o.flip)g.scale(1,-1);g.rotate(p.a);g.drawImage(tube,-4*s,-TUBE*s,8*s,22*s);g.restore(); // tube first: the receiver hides its root\r\n  g.drawImage(body,Math.round(p.ox),Math.round(p.oy),48*s,24*s);\r\n }\r\n const led=G.flash>0?'#fff':G.phase==='aim'&&Math.floor(G.t*16)%2===0?GUN.brand.led:null; // 8 Hz amber blink while aiming, solid white on fire\r\n const mx=Math.round(p.mx),my=Math.round(p.my),ly=my-p.d*s*2;\r\n g.fillStyle=led||'#2a1a00';g.fillRect(mx-s,ly,s*2,s*2);\r\n if(led===GUN.brand.led){g.globalAlpha=.55;g.fillStyle=led;for(const[dx,dy]of[[-3,0],[3,0],[0,-3],[0,3]])g.fillRect(mx-s+dx*s,ly+dy*s,s*2,s*2);g.globalAlpha=1;} // glow ring so the cue reads on the camera feed\r\n if(G.flash>0){ // Vlambeer: the first frame is a circle, then a star, then a smoke pixel (~90 ms total)\r\n  const age=GUN.flashS-G.flash,f=age<GUN.flashS/3?0:age<GUN.flashS*2/3?1:2,fy=my+p.d*s*2;\r\n  if(f===0){g.fillStyle='#fff';for(let y=-5;y<=5;y++)for(let x=-5;x<=5;x++)if(x*x+y*y<=25)g.fillRect(mx+x*s,fy+y*s,s,s);}\r\n  else if(f===1){g.fillStyle=GUN.brand.led;for(let i=-3;i<=3;i++){g.fillRect(mx+i*s,fy,s,s);g.fillRect(mx,fy+i*s,s,s);}}\r\n  else{g.fillStyle='#8a8a92';g.fillRect(mx,fy+p.d*s*2,s*3,s*3);}\r\n }\r\n g.restore();\r\n}\r\nfunction drawFx(g,e){\r\n for(const q of e.fx){\r\n  if(q.d>0)continue;const k=q.life/q.max;\r\n  if(q.kind==='flash'){const r=Math.round(q.r*(k>.5?1:.66));g.fillStyle=k>.5?q.c:q.c2;const st=r>20?3:2;for(let y=-r;y<=r;y+=st)for(let x=-r;x<=r;x+=st)if(x*x+y*y<=r*r)g.fillRect(Math.round(q.x+x),Math.round(q.y+y),st,st);}\r\n  else if(q.kind==='ring'){const R=q.r0+(q.r1-q.r0)*(1-k),n=Math.max(12,Math.ceil(TAU*R/3));g.globalAlpha=.8*k;g.fillStyle=q.c;for(let i=0;i<n;i++){const a=i/n*TAU;g.fillRect(Math.round(q.x+Math.cos(a)*R),Math.round(q.y+Math.sin(a)*R),3,3);}g.globalAlpha=1;}\r\n  else if(q.kind==='smoke'){g.globalAlpha=.6*k;g.fillStyle='#2a2a2e';g.fillRect(Math.round(q.x),Math.round(q.y),3,3);g.globalAlpha=1;}\r\n  else if(q.kind==='chunk'){g.save();g.globalAlpha=Math.min(1,k*2);g.translate(Math.round(q.x),Math.round(q.y));g.rotate(Math.round(q.rot/(Math.PI/4))*Math.PI/4);g.fillStyle=q.c;g.fillRect(-1,-3,2,5);g.restore();g.globalAlpha=1;}\r\n }\r\n}\r\n// coach(g,e) lets a host draw its own thrower (rest hangs the gun from the top); default = the gun at bottom centre.\r\nexport function render(g,e,{coach=null,pointerTrail=true}={}){\r\n g.imageSmoothingEnabled=false;g.clearRect(0,0,e.w,e.h);\r\n g.save();if(e.shake>0)g.translate(Math.round((Math.random()-.5)*e.shake*GUN.shakePx),Math.round((Math.random()-.5)*e.shake*GUN.shakePx));\r\n for(const s of e.stains){g.globalAlpha=Math.min(.7,s.life/4);g.fillStyle=s.c;for(const[x,y,z]of s.dots)g.fillRect(Math.round(x),Math.round(y),z*2,z*2);}\r\n g.globalAlpha=1;\r\n if(coach)coach(g,e);else drawGun(g,e);\r\n for(const o of e.objects){if(o.hold)continue;\r\n  if(o.trail.length){g.fillStyle=TYPES[o.type][1];o.trail.forEach((t,i)=>{g.globalAlpha=.25+.2*i;g.fillRect(Math.round(t.x)-1,Math.round(t.y)-1,3,3);});g.globalAlpha=1;} // slow bright barrels leave a short trail\r\n  g.save();g.translate(Math.round(o.x),Math.round(o.y));drawBody(g,o);g.restore();}\r\n for(const q of e.halves){g.save();g.globalAlpha=Math.min(1,q.life/HALF_LIFE);g.translate(Math.round(q.x),Math.round(q.y));g.rotate(q.hr);g.rotate(q.cut);g.beginPath();g.rect(-q.r*2,q.side>0?0:-q.r*2,q.r*4,q.r*2);g.clip();g.rotate(-q.cut);drawBody(g,{...q,rot:q.rot0});g.restore();}\r\n for(const q of e.parts){g.globalAlpha=Math.min(1,q.life*2);g.fillStyle=q.c;g.fillRect(Math.round(q.x),Math.round(q.y),q.s,q.s);}\r\n g.globalAlpha=1;drawFx(g,e);\r\n if(pointerTrail&&e.trail.length>1){g.lineWidth=2;for(let i=1;i<e.trail.length;i++){const a=e.trail[i-1],b=e.trail[i];g.strokeStyle=`rgba(255,255,255,${Math.min(1,b.life*4)})`;g.beginPath();g.moveTo(a.x,a.y);g.lineTo(b.x,b.y);g.stroke();}}\r\n const L=e.laser;\r\n if(L.phase!=='idle'){\r\n  const m=gunMuzzle(e),gx=m.x,gy=m.y;\r\n  if(L.phase==='aim'){g.strokeStyle=(Math.floor(L.t*12)%2)?'#ff2a2a':'#ff8080';g.lineWidth=1;g.setLineDash([3,3]);g.beginPath();g.moveTo(gx,gy);g.lineTo(L.tx,L.ty);g.stroke();g.setLineDash([]);}\r\n  else if(L.result==='hit'){g.strokeStyle='#f22';g.lineWidth=3;g.beginPath();g.moveTo(gx,gy);g.lineTo(L.tx,L.ty);g.stroke();}\r\n  else{g.strokeStyle='#f66';g.lineWidth=2;g.beginPath();g.moveTo(gx,gy);g.lineTo(L.tx,L.ty+14);g.stroke();\r\n   g.fillStyle='rgba(120,200,255,.55)';for(let y=-14;y<=14;y+=4)for(let x=-12;x<=12;x+=4)if(x*x/144+y*y/196<=1)g.fillRect(L.tx+x,L.ty+y,3,3);} // pixel shield\r\n }\r\n g.restore();\r\n if(L.flash>0){g.fillStyle=`rgba(255,0,0,${L.flash})`;g.fillRect(0,0,e.w,e.h);}\r\n g.textAlign='center';\r\n for(const p of e.pops){g.globalAlpha=Math.min(1,p.life*2);g.font=`bold ${p.big?14:9}px monospace`;g.fillStyle='#000';g.fillText(p.text,Math.round(p.x)+1,Math.round(p.y)+1);g.fillStyle=p.c;g.fillText(p.text,Math.round(p.x),Math.round(p.y));}\r\n g.globalAlpha=1;\r\n if(e.mode==='martial'){g.font='bold 12px monospace';g.textAlign='right';g.fillStyle='#f33';g.fillText('X'.repeat(e.strikes)+'.'.repeat(3-e.strikes),e.w-6,14);}\r\n g.textAlign='left';g.font='bold 9px monospace';g.fillStyle='#fff';g.fillText(`${e.score}  W${e.wave}${e.xp?`  +${e.xp}XP`:''}`,6,14);\r\n}\r\n","arcade/slice/hand-glow.mjs":"// Camera-workout hand light trails. Pose landmarks still drive Fruit Ninja collisions unchanged; this\r\n// module only paints: One Euro wrists + damped prediction, a time-stamped ring buffer per hand, centripetal\r\n// Catmull-Rom, a tapered filled ribbon in three additive layers, speed-gated emission with hysteresis,\r\n// punch impacts (flash, ring, sparks) and alpha fades instead of hard deletes.\r\n// Coordinates: pose() takes points mapped to the overlay host as 0..1 fractions (workout-effects mapper);\r\n// renderHandGlow() scales them to the canvas logical size (CSS px).\r\nimport {createLandmarkBank,PRESETS} from '../one-euro.mjs';\r\n\r\n// Tuning knobs (real phones need tuning). Speeds are body-heights per second; widths are fractions of body height.\r\nexport const TRAIL_TUNING=Object.freeze({\r\n MAX_PTS:32, LIFE_MS:420, SUBDIV:4,\r\n GATE_ON:1.2, GATE_OFF:.7, EMIT_OFF_MS:150, SPEED_FULL:2.5,\r\n BASE_W:.022, HEAD_BOOST:1.3,\r\n LAYERS:[[2.6,.2],[1.3,.65],[.42,1]],  // [width x, alpha x]: wide soft, mid colour, white core\r\n PREDICT_MAX:.1,                     // max prediction lead, body heights\r\n VIS_FADE_MS:200, STALE_MS:400, MIN_HZ:4,\r\n BODY_M:1.7,                         // metres per body height for world-landmark speed\r\n PEAK_MIN:1.5, DROP:.6, HARD_DROP:.4, STRAIGHT_DEG:150, WINDOW_MS:150, COOLDOWN_MS:250,\r\n SPARKS:[8,14], SPARK_SPEED:[1.5,3], SPARK_LIFE:[250,400], SPARK_DRAG:3, SPARK_CONE:35*Math.PI/180,\r\n FLASH_MS:120, FLASH_R:.05, RING_MS:220, RING_R:.12,\r\n COST_DOWN_MS:3, COST_UP_MS:1.5, COST_FRAMES:8, RECOVER_MS:1500,\r\n});\r\n// Colour by aura level (myr5:aura-level 0..3): [wide, mid, core, tail second hue].\r\nexport const TRAIL_PALETTES=[\r\n ['#ff3d10','#ff8a2a','#fff6e0',null],\r\n ['#ff3d10','#ff8a2a','#fff6e0',null],\r\n ['#ff1f6a','#ff5ad0','#fff0fa',null],\r\n ['#1f6bff','#38e8ff','#f0ffff','#9a5cff'],\r\n];\r\nconst clamp=(n,a,b)=>Math.max(a,Math.min(b,n));\r\nconst smooth=(a,b,x)=>{const t=clamp((x-a)/(b-a),0,1);return t*t*(3-2*t);};\r\nconst SIDES=[['left',15,13,11,[17,19,21]],['right',16,14,12,[18,20,22]]];\r\nconst F=6; // floats per trail point: x, y, t, speedN, emit, spare\r\n\r\nfunction confidence(point){return Number.isFinite(point?.visibility)?point.visibility:Number.isFinite(point?.score)?point.score:0;}\r\nfunction handConfidence(points,wrist,shape){\r\n const wristConf=confidence(points[wrist]);if(wristConf<.4)return wristConf;\r\n let sum=0,n=0;for(const i of shape){const v=confidence(points[i]);if(v>=.5){sum+=v;n++;}}\r\n // A wrist is sufficient when the hand-specific keypoints are missing from a pose.\r\n return n?Math.min(wristConf,sum/n):wristConf;\r\n}\r\n/** Elbow angle in degrees (180 = straight). World landmarks (metres, 3D) when present, else image space. */\r\nexport function elbowAngle(a,b,c,ar=1){\r\n if(!a||!b||!c)return 0;\r\n const ux=(a.x-b.x)*ar,uy=a.y-b.y,uz=(a.z??0)-(b.z??0),vx=(c.x-b.x)*ar,vy=c.y-b.y,vz=(c.z??0)-(b.z??0);\r\n const l=Math.hypot(ux,uy,uz)*Math.hypot(vx,vy,vz);if(!l)return 0;\r\n return Math.acos(clamp((ux*vx+uy*vy+uz*vz)/l,-1,1))*180/Math.PI;\r\n}\r\n/** Body height in host heights from mapped shoulders/hips (aspect = host w/h). Fallback: shoulder width. */\r\nexport function bodyHeight(m,aspect){\r\n const ok=p=>p&&Number.isFinite(p.x)&&Number.isFinite(p.y)&&(p.visibility??1)>=.5;\r\n const [ls,rs,lh,rh]=[m(11),m(12),m(23),m(24)];\r\n if(ok(ls)&&ok(rs)&&ok(lh)&&ok(rh))return Math.hypot((ls.x+rs.x-lh.x-rh.x)/2*aspect,(ls.y+rs.y-lh.y-rh.y)/2)/.3;\r\n if(ok(ls)&&ok(rs))return Math.hypot((ls.x-rs.x)*aspect,ls.y-rs.y)/.23;\r\n return 0;\r\n}\r\n\r\n/** Pure speed gate with hysteresis (exported for tests). */\r\nexport function gateStep(on,speed,T=TRAIL_TUNING){return on?speed>=T.GATE_OFF:speed>T.GATE_ON;}\r\n/** Ribbon half-width for a sample: taper by age, widen with speed (exported for tests). */\r\nexport function ribbonHalfWidth(age01,speedN,bodyPx,head=false,T=TRAIL_TUNING){\r\n return T.BASE_W*bodyPx*Math.pow(1-clamp(age01,0,1),1.3)*(.35+.65*clamp(speedN,0,1))*(head?T.HEAD_BOOST:1);\r\n}\r\n/** Ribbon alpha for a sample (exported for tests). */\r\nexport function ribbonAlpha(age01,speedN,emit){return Math.pow(1-clamp(age01,0,1),2)*smooth(.15,.5,speedN)*emit;}\r\n\r\n/**\r\n * Punch impact detector for one hand: a peak above PEAK_MIN, then the speed falls below DROP*peak within\r\n * WINDOW_MS with the elbow straight (jab/cross), or below HARD_DROP*peak with a bent elbow (hook). One per punch.\r\n */\r\nexport function createImpactDetector(T=TRAIL_TUNING){\r\n const s={armed:false,peak:0,peakAt:0,coolUntil:-Infinity};\r\n return {state:s,update(speed,elbowDeg,t){\r\n  if(s.armed&&t-s.peakAt>T.WINDOW_MS)s.armed=false;\r\n  if(speed>=T.PEAK_MIN&&(!s.armed||speed>s.peak)){s.armed=true;s.peak=speed;s.peakAt=t;return 0;}\r\n  if(!s.armed||t<s.coolUntil)return 0;\r\n  if(speed<=T.DROP*s.peak&&(elbowDeg>=T.STRAIGHT_DEG||speed<=T.HARD_DROP*s.peak)){\r\n   const peak=s.peak;s.armed=false;s.peak=0;s.coolUntil=t+T.COOLDOWN_MS;return peak;}\r\n  return 0;\r\n },reset(){s.armed=false;s.peak=0;}};\r\n}\r\n\r\nfunction makeHand(side,T){\r\n return {side,visible:false,alpha:0,x:0,y:0,hx:0,hy:0,speed:0,speedN:0,gate:false,emit:0,lastSeen:-Infinity,lastPoseAt:null,\r\n  wx:NaN,wy:NaN,wz:NaN,pts:new Float32Array(T.MAX_PTS*F),start:0,count:0,impact:createImpactDetector(T),dirX:0,dirY:0,confidence:0};\r\n}\r\n\r\nexport function createHandGlow({clock=()=>globalThis.performance?.now?.()??Date.now(),onImpact=()=>{},random=Math.random,tuning=TRAIL_TUNING}={}){\r\n const T=tuning,bank=createLandmarkBank(()=>PRESETS.wrist);\r\n const SP=new Float32Array(40*6); // spark pool: x, y, vx, vy, life, max (normalized host units)\r\n const IM=new Float32Array(4*6);  // impacts: x, y, t, strength, dirX, dirY\r\n const state={hands:[makeHand('left',T),makeHand('right',T)],bodyH:.6,aspect:9/16,level:0,lastPoseAt:null,poseHz:0,poseSamples:0,\r\n  enabled:true,tier:3,highCostFrames:0,lowCostSince:null,lastRenderAt:0,sparks:SP,impacts:IM,impactNext:0};\r\n function clearHand(h){h.visible=false;h.alpha=0;h.count=0;h.start=0;h.gate=false;h.emit=0;h.speed=0;h.lastPoseAt=null;h.wx=NaN;h.impact.reset();}\r\n function clear(){for(const h of state.hands)clearHand(h);for(let i=0;i<SP.length;i+=6)SP[i+4]=0;for(let i=0;i<IM.length;i+=6)IM[i+2]=-1e9;\r\n  bank.reset(15);bank.reset(16);state.lastPoseAt=null;state.poseHz=0;state.poseSamples=0;}\r\n clear();\r\n function push(h,x,y,t,sn,e){\r\n  if(h.count===T.MAX_PTS){h.start=(h.start+1)%T.MAX_PTS;h.count--;}\r\n  const o=((h.start+h.count)%T.MAX_PTS)*F;h.pts[o]=x;h.pts[o+1]=y;h.pts[o+2]=t;h.pts[o+3]=sn;h.pts[o+4]=e;h.count++;\r\n }\r\n function spawnImpact(h,x,y,t,peak){\r\n  const strength=clamp(peak/3,.35,1),o=state.impactNext*6;state.impactNext=(state.impactNext+1)%4;\r\n  IM[o]=x;IM[o+1]=y;IM[o+2]=t;IM[o+3]=strength;IM[o+4]=h.dirX;IM[o+5]=h.dirY;\r\n  const n=Math.round(T.SPARKS[0]+(T.SPARKS[1]-T.SPARKS[0])*strength),base=Math.atan2(h.dirY,h.dirX*state.aspect);\r\n  for(let k=0,i=0;k<n&&i<SP.length;i+=6){if(SP[i+4]>0)continue;k++;\r\n   const a=base+(random()*2-1)*T.SPARK_CONE,v=(T.SPARK_SPEED[0]+random()*(T.SPARK_SPEED[1]-T.SPARK_SPEED[0]))*state.bodyH,life=T.SPARK_LIFE[0]+random()*(T.SPARK_LIFE[1]-T.SPARK_LIFE[0]);\r\n   SP[i]=x;SP[i+1]=y;SP[i+2]=Math.cos(a)*v/state.aspect;SP[i+3]=Math.sin(a)*v;SP[i+4]=life;SP[i+5]=life;}\r\n  onImpact({x,y,hand:h.side,strength});\r\n }\r\n // points: raw landmarks; mapPoint(p) -> {x,y} host fractions; world: world landmarks (optional); aspect: host w/h.\r\n function pose(points,{now=clock(),mapPoint=p=>p,world=null,aspect=state.aspect,videoAspect=1}={}){\r\n  if(!Array.isArray(points)){for(const h of state.hands)h.visible=false;return;}\r\n  const t=Number.isFinite(now)?now:clock();\r\n  if(state.lastPoseAt!=null){const dt=t-state.lastPoseAt;if(dt>0){const hz=1000/dt;state.poseHz=dt>T.STALE_MS||!state.poseSamples?hz:state.poseHz*.7+hz*.3;state.poseSamples++;}}\r\n  state.lastPoseAt=t;state.aspect=aspect>0?aspect:state.aspect;\r\n  const m=i=>points[i]?mapPoint(points[i]):null,bh=bodyHeight(m,state.aspect);\r\n  if(bh>.05)state.bodyH=state.bodyH*.8+clamp(bh,.15,1.6)*.2;\r\n  for(let s=0;s<2;s++){\r\n   const [,wrist,elbow,shoulder,shape]=SIDES[s],h=state.hands[s],conf=handConfidence(points,wrist,shape),mp=points[wrist]?m(wrist):null;\r\n   if(!mp||!Number.isFinite(mp.x)||!Number.isFinite(mp.y)){h.visible=false;continue;}\r\n   const f=bank.update(wrist,mp.x,mp.y,conf,t);h.visible=f.visible;h.confidence=conf;\r\n   if(!h.visible)continue;\r\n   const dt=h.lastPoseAt==null?0:(t-h.lastPoseAt)/1000;\r\n   let raw=0;\r\n   if(dt>0&&dt<.3){\r\n    const dx=f.x-h.x,dy=f.y-h.y;raw=Math.hypot(dx*state.aspect,dy)/dt/state.bodyH;\r\n    if(raw>.3){const l=Math.hypot(dx*state.aspect,dy);h.dirX=dx/l;h.dirY=dy/l;}\r\n    const w=world?.[wrist];\r\n    if(w&&Number.isFinite(h.wx))raw=Math.max(raw,Math.hypot(w.x-h.wx,w.y-h.wy,(w.z??0)-h.wz)/dt/T.BODY_M);\r\n   }\r\n   const w=world?.[wrist];if(w){h.wx=w.x;h.wy=w.y;h.wz=w.z??0;}\r\n   if(h.lastPoseAt==null||t-h.lastSeen>T.STALE_MS){h.count=0;h.start=0;h.speed=0;}\r\n   h.speed=dt>0?h.speed*.4+raw*.6:0;h.speedN=clamp(h.speed/T.SPEED_FULL,0,1);\r\n   const was=h.gate;h.gate=gateStep(h.gate,h.gate?h.speed:Math.max(raw,h.speed),T); // open on the raw spike, close on the smoothed speed\r\n   if(h.gate&&!was)for(let i=Math.max(0,h.count-2);i<h.count;i++)h.pts[((h.start+i)%T.MAX_PTS)*F+4]=1; // light the wind-up so the ribbon has length at once\r\n   h.emit=h.gate?1:Math.max(0,h.emit-(dt*1000)/T.EMIT_OFF_MS);\r\n   h.x=f.x;h.y=f.y;h.lastSeen=t;h.lastPoseAt=t;\r\n   if(state.enabled)push(h,f.x,f.y,t,h.speedN,h.emit);\r\n   if(dt>0){\r\n    const ang=world?.[shoulder]&&world?.[elbow]&&world?.[wrist]?elbowAngle(world[shoulder],world[elbow],world[wrist]):elbowAngle(points[shoulder],points[elbow],points[wrist],videoAspect);\r\n    const peak=h.impact.update(raw,ang,t);if(peak)spawnImpact(h,f.x,f.y,t,peak);\r\n   }\r\n  }\r\n }\r\n function step(dtSeconds,now=clock()){\r\n  const t=Number.isFinite(now)?now:clock(),dt=clamp(Number(dtSeconds)||0,0,.05);\r\n  for(let s=0;s<2;s++){\r\n   const h=state.hands[s];if(t-h.lastSeen>T.STALE_MS)h.visible=false;\r\n   h.alpha=clamp(h.alpha+(h.visible?1:-1)*dt*1000/T.VIS_FADE_MS,0,1);\r\n   while(h.count&&t-h.pts[h.start*F+2]>T.LIFE_MS){h.start=(h.start+1)%T.MAX_PTS;h.count--;}\r\n   // Live head: the filtered wrist pushed forward by the measured lag (capped), so the ribbon reaches the hand.\r\n   const p=h.lastPoseAt==null?null:bank.predict(SIDES[s][1],t-h.lastPoseAt);\r\n   if(p){let ox=(p.x-h.x)*state.aspect,oy=p.y-h.y;const l=Math.hypot(ox,oy),cap=T.PREDICT_MAX*state.bodyH;if(l>cap){ox*=cap/l;oy*=cap/l;}h.hx=h.x+ox/state.aspect;h.hy=h.y+oy;}\r\n   else{h.hx=h.x;h.hy=h.y;}\r\n  }\r\n  const k=Math.exp(-T.SPARK_DRAG*dt);\r\n  for(let i=0;i<SP.length;i+=6){if(SP[i+4]<=0)continue;SP[i]+=SP[i+2]*dt;SP[i+1]+=SP[i+3]*dt;SP[i+2]*=k;SP[i+3]*=k;SP[i+4]-=dt*1000;}\r\n  state.lastRenderAt=t;\r\n  return state;\r\n }\r\n // Quality ladder on measured render cost: 3 layers -> 2 -> 1 -> off, recovering after a calm stretch.\r\n function measure(costMs,now=clock()){\r\n  if(!Number.isFinite(costMs))return state.enabled;\r\n  const t=Number.isFinite(now)?now:clock();\r\n  if(costMs>T.COST_DOWN_MS){state.highCostFrames++;state.lowCostSince=null;if(state.highCostFrames>=T.COST_FRAMES){state.tier=Math.max(0,state.tier-1);state.highCostFrames=0;}}\r\n  else{state.highCostFrames=0;if(costMs<T.COST_UP_MS){if(state.lowCostSince==null)state.lowCostSince=t;if(state.tier<3&&t-state.lowCostSince>=T.RECOVER_MS){state.tier++;state.lowCostSince=t;}}else state.lowCostSince=null;}\r\n  state.enabled=state.tier>0;\r\n  return state.enabled;\r\n }\r\n function setLevel(level){state.level=clamp(Math.round(Number(level)||0),0,3);}\r\n return {state,pose,step,measure,clear,setLevel};\r\n}\r\n\r\n// ---- renderer (Canvas 2D, additive). Scratch buffers are module-level: no per-frame allocation. ----\r\nconst MAXS=(TRAIL_TUNING.MAX_PTS+1)*TRAIL_TUNING.SUBDIV+1;\r\nconst SX=new Float32Array(MAXS),SY=new Float32Array(MAXS),SA=new Float32Array(MAXS),SS=new Float32Array(MAXS),SE=new Float32Array(MAXS),NX=new Float32Array(MAXS),NY=new Float32Array(MAXS),HW=new Float32Array(MAXS),PT=new Float32Array((TRAIL_TUNING.MAX_PTS+1)*5);\r\nconst sprites=new Map();\r\nfunction glowSprite(colour){\r\n if(sprites.has(colour))return sprites.get(colour);\r\n let c=null;\r\n try{c=typeof OffscreenCanvas==='function'?new OffscreenCanvas(64,64):globalThis.document?.createElement?.('canvas');if(c){c.width=c.height=64;const g=c.getContext('2d');const r=g.createRadialGradient(32,32,0,32,32,32);\r\n  r.addColorStop(0,colour);r.addColorStop(.25,colour);r.addColorStop(1,'rgba(0,0,0,0)');g.fillStyle=r;g.fillRect(0,0,64,64);}}catch{c=null;}\r\n sprites.set(colour,c);return c;\r\n}\r\n// Centripetal Catmull-Rom (alpha .5) between p1 and p2; writes SUBDIV samples starting at index n.\r\nfunction catmull(n,i0,i1,i2,i3,sub){\r\n const x0=PT[i0*5],y0=PT[i0*5+1],x1=PT[i1*5],y1=PT[i1*5+1],x2=PT[i2*5],y2=PT[i2*5+1],x3=PT[i3*5],y3=PT[i3*5+1];\r\n const t1=Math.sqrt(Math.hypot(x1-x0,y1-y0))||1e-4,t2=t1+(Math.sqrt(Math.hypot(x2-x1,y2-y1))||1e-4),t3=t2+(Math.sqrt(Math.hypot(x3-x2,y3-y2))||1e-4);\r\n for(let k=0;k<sub;k++){\r\n  const u=k/sub,t=t1+(t2-t1)*u;\r\n  const a1x=(t1-t)/t1*x0+t/t1*x1,a1y=(t1-t)/t1*y0+t/t1*y1;\r\n  const a2x=(t2-t)/(t2-t1)*x1+(t-t1)/(t2-t1)*x2,a2y=(t2-t)/(t2-t1)*y1+(t-t1)/(t2-t1)*y2;\r\n  const a3x=(t3-t)/(t3-t2)*x2+(t-t2)/(t3-t2)*x3,a3y=(t3-t)/(t3-t2)*y2+(t-t2)/(t3-t2)*y3;\r\n  const b1x=(t2-t)/t2*a1x+t/t2*a2x,b1y=(t2-t)/t2*a1y+t/t2*a2y,b2x=(t3-t)/(t3-t1)*a2x+(t-t1)/(t3-t1)*a3x,b2y=(t3-t)/(t3-t1)*a2y+(t-t1)/(t3-t1)*a3y;\r\n  SX[n+k]=(t2-t)/(t2-t1)*b1x+(t-t1)/(t2-t1)*b2x;SY[n+k]=(t2-t)/(t2-t1)*b1y+(t-t1)/(t2-t1)*b2y;\r\n  SA[n+k]=PT[i1*5+2]+(PT[i2*5+2]-PT[i1*5+2])*u;SS[n+k]=PT[i1*5+3]+(PT[i2*5+3]-PT[i1*5+3])*u;SE[n+k]=PT[i1*5+4]+(PT[i2*5+4]-PT[i1*5+4])*u;\r\n }\r\n}\r\n/** Builds the ribbon samples for a hand into the scratch buffers; returns the sample count. Exported for tests. */\r\nexport function buildRibbon(hand,now,w,h,bodyPx,T=TRAIL_TUNING){\r\n let n=0;\r\n for(let i=0;i<hand.count;i++){const o=((hand.start+i)%T.MAX_PTS)*F,a=(now-hand.pts[o+2])/T.LIFE_MS;\r\n  PT[n*5]=hand.pts[o]*w;PT[n*5+1]=hand.pts[o+1]*h;PT[n*5+2]=clamp(a,0,1);PT[n*5+3]=hand.pts[o+3];PT[n*5+4]=hand.pts[o+4];n++;}\r\n PT[n*5]=hand.hx*w;PT[n*5+1]=hand.hy*h;PT[n*5+2]=0;PT[n*5+3]=hand.speedN;PT[n*5+4]=hand.emit;n++;\r\n if(n<2)return 0;\r\n let m=0;\r\n for(let i=0;i<n-1;i++){catmull(m,Math.max(0,i-1),i,i+1,Math.min(n-1,i+2),T.SUBDIV);m+=T.SUBDIV;}\r\n SX[m]=PT[(n-1)*5];SY[m]=PT[(n-1)*5+1];SA[m]=0;SS[m]=PT[(n-1)*5+3];SE[m]=PT[(n-1)*5+4];m++;\r\n for(let i=0;i<m;i++){\r\n  const a=Math.max(0,i-1),b=Math.min(m-1,i+1);let tx=SX[b]-SX[a],ty=SY[b]-SY[a];const l=Math.hypot(tx,ty)||1;tx/=l;ty/=l;\r\n  NX[i]=-ty;NY[i]=tx;HW[i]=ribbonHalfWidth(SA[i],SS[i],bodyPx,i===m-1,T);\r\n }\r\n return m;\r\n}\r\nexport const ribbonSamples={SX,SY,SA,SS,SE,HW};\r\n\r\nexport function renderHandGlow(ctx,state,{w=180,h=320,now=state?.lastRenderAt??0}={}){\r\n if(!ctx||!state)return;\r\n const T=TRAIL_TUNING,pal=TRAIL_PALETTES[state.level]||TRAIL_PALETTES[0],bodyPx=state.bodyH*h;\r\n const slow=state.poseSamples>=2&&state.poseHz<T.MIN_HZ;\r\n ctx.save();ctx.globalCompositeOperation='lighter';\r\n if(state.enabled&&!slow)for(const hand of state.hands){\r\n  if(hand.alpha<=.01)continue;\r\n  const m=buildRibbon(hand,now,w,h,bodyPx,T),layers=state.tier>=3?3:state.tier;\r\n  for(let L=3-layers;L<3&&m>1;L++){\r\n   const [wx,ax]=T.LAYERS[L];\r\n   for(let i=0;i<m-1;i++){\r\n    const age=SA[i+1],a=ax*hand.alpha*ribbonAlpha(age,SS[i+1],SE[i+1])*(.7+.3*Math.sin(age*14-now*.009+L)*Math.sin(age*5.3+now*.004));\r\n    if(a<.004)continue;\r\n    ctx.fillStyle=L===2?pal[2]:pal[3]&&age>.5&&L===1?pal[3]:pal[L];ctx.globalAlpha=Math.min(1,a);\r\n    const h0=HW[i]*wx,h1=HW[i+1]*wx;\r\n    ctx.beginPath();ctx.moveTo(SX[i]+NX[i]*h0,SY[i]+NY[i]*h0);ctx.lineTo(SX[i+1]+NX[i+1]*h1,SY[i+1]+NY[i+1]*h1);\r\n    ctx.lineTo(SX[i+1]-NX[i+1]*h1,SY[i+1]-NY[i+1]*h1);ctx.lineTo(SX[i]-NX[i]*h0,SY[i]-NY[i]*h0);ctx.closePath();ctx.fill();\r\n   }\r\n  }\r\n  // Hand glow: always a soft light on the wrist, stretched along the motion and hotter with speed.\r\n  const hx=hand.hx*w,hy=hand.hy*h,r=bodyPx*(.028+.025*hand.speedN),stretch=1+Math.min(2,hand.speedN*2.2*hand.emit);\r\n  const spr=glowSprite(pal[1]),core=glowSprite(pal[2]);\r\n  ctx.globalAlpha=hand.alpha*(.22+.5*hand.speedN*hand.emit);\r\n  if(spr){ctx.save();ctx.translate(hx,hy);ctx.rotate(Math.atan2(hand.dirY,hand.dirX*w/h));ctx.drawImage(spr,r-2*r*stretch,-r,r*2*stretch,r*2);\r\n   ctx.globalAlpha*=.8;ctx.drawImage(core,r*.45-r*.9*stretch,-r*.45,r*.9*stretch,r*.9);ctx.restore();}\r\n  else{ctx.fillStyle=pal[1];ctx.fillRect(hx-r,hy-r,r*2,r*2);}\r\n }\r\n drawImpacts(ctx,state,w,h,now,pal);\r\n ctx.restore();\r\n}\r\nfunction drawImpacts(ctx,state,w,h,now,pal){\r\n const T=TRAIL_TUNING,IM=state.impacts,SP=state.sparks,bodyPx=state.bodyH*h,flash=glowSprite('#ffffff'),tint=glowSprite(pal[1]);\r\n for(let i=0;i<IM.length;i+=6){\r\n  const age=now-IM[i+2];if(age<0||age>T.RING_MS)continue;\r\n  const x=IM[i]*w,y=IM[i+1]*h,s=IM[i+3];\r\n  if(age<T.FLASH_MS){const k=age/T.FLASH_MS,sc=(k<.35?k/.35:1-(k-.35)/.65)*T.FLASH_R*bodyPx*(.6+.4*s);\r\n   if(flash){ctx.globalAlpha=.8;ctx.drawImage(tint,x-sc*2,y-sc*2,sc*4,sc*4);ctx.drawImage(flash,x-sc,y-sc,sc*2,sc*2);}}\r\n  const k=age/T.RING_MS,R=T.RING_R*bodyPx*(.6+.4*s)*Math.sqrt(k);\r\n  ctx.globalAlpha=(1-k)*.9;ctx.strokeStyle=pal[2];ctx.lineWidth=Math.max(1.5,bodyPx*.012*(1-k));ctx.beginPath();ctx.arc(x,y,R,0,Math.PI*2);ctx.stroke();\r\n  ctx.globalAlpha=(1-k)*.5;ctx.strokeStyle=pal[1];ctx.lineWidth=Math.max(3,bodyPx*.03*(1-k));ctx.stroke();\r\n }\r\n ctx.lineCap='round';\r\n for(let i=0;i<SP.length;i+=6){\r\n  if(SP[i+4]<=0)continue;const k=SP[i+4]/SP[i+5],x=SP[i]*w,y=SP[i+1]*h,vx=SP[i+2]*w,vy=SP[i+3]*h;\r\n  ctx.globalAlpha=k;ctx.strokeStyle=k>.5?pal[2]:pal[1];ctx.lineWidth=Math.max(1,bodyPx*.008);\r\n  ctx.beginPath();ctx.moveTo(x,y);ctx.lineTo(x-vx*.03,y-vy*.03);ctx.stroke();\r\n }\r\n ctx.lineCap='butt';\r\n}\r\n","arcade/slice/rest-game.mjs":"// Fruit Ninja rest mode: the MOM Inc. gun (top) fires barrels at the user's character; swipe slices, tap explodes,\r\n// tilt (or arrow keys) dodges, holding still shields from the laser. Lazy-loaded by pod.mjs; engine = ./core.mjs.\r\nimport {createSlice,render,drawGun,gunMuzzle} from './core.mjs';\r\nimport {createDodger,createSwipe,throwPlan,REST} from './rest-logic.mjs';\r\nimport {subscribePhoneMotion,requestPhoneMotion} from '../../character-phone-sensor.mjs';\r\nimport {performanceOwner} from '../../performance-progress.mjs';\r\nimport {createQuestProgressReporter} from '../quest-progress-reporter.mjs';\r\n\r\nconst W=180,GRAV=260;\r\nexport function mountRestGame(scene,{avatar,attackButton,feedback,sound=()=>{}}){\r\n const canvas=document.createElement('canvas'),g=canvas.getContext('2d');\r\n canvas.className='slice-layer';canvas.setAttribute('aria-hidden','true');\r\n let e,dodger,plan=null,frame=0,last=0,nextThrow=0,nextLaser=0,throws=0,swallow=false,unsub=()=>{},k=1,runOwner=null,reportQuest=null;\r\n const phone={gx:0,motion:0},pointer={down:false,x:0,y:0,speed:0};\r\n const swipe=createSwipe(),say=t=>{if(feedback)feedback.textContent=t;};\r\n // hudY: the rest HUD (.boss-status) overlays the top of the encounter, so the gun hangs just below it (measured in begin()).\r\n let hudY=0;\r\n const floorY=()=>e.h*.8,gunTop=()=>hudY+e.h*.04,coachY=()=>gunTop()+e.h*.13,gunAt=()=>({x:e.coachX,y:gunTop(),flip:true});\r\n const toLogical=ev=>{const r=canvas.getBoundingClientRect();return {x:(ev.clientX-r.left)/r.width*e.w,y:(ev.clientY-r.top)/r.height*e.h};};\r\n function begin(){\r\n  const b=scene.getBoundingClientRect();if(!(b.width>0&&b.height>0))throw new Error('Rest target canvas host has no visible size');k=b.width/W;const h=Math.round(W*b.height/b.width);\r\n  canvas.width=W;canvas.height=h;\r\n  const hud=scene.querySelector('.boss-status')?.getBoundingClientRect();hudY=hud&&hud.height>0?Math.max(0,(hud.bottom-b.top)/k):0;\r\n  e=createSlice({w:W,h,mode:'rest',auto:false,coachX:W/2,onEvent:(type,d)=>{\r\n   if(type==='hit')sound(d.kind==='slice'?'barrel-split':d.type==='barrel-fuel'||d.type==='barrel-toxic'?'blast-big':'blast');\r\n   else if(type==='shot')sound('gun-shot');else if(type==='gun-aim')sound('gun-arm');else if(type==='chain')sound('blast');\r\n   if(type==='laser-hit')say('Zapped! Hold still to shield next time.');\r\n   if(type==='laser-shield')say('Shield up. Nice and steady.');\r\n   if(type==='combo'){say(`COMBO x${d.n}!`);reportQuest?.record('fruit-streak',d.n);}\r\n   if(type==='wave-end')say('Wave over. Keep going, your rest continues.');\r\n  }});\r\n  dodger=createDodger(W,14);plan=null;throws=0;nextThrow=REST.firstThrowDelay;nextLaser=REST.laserEvery[0]/1000;\r\n }\r\n function throwRock(){\r\n  const p=plan||throwPlan(e.wave,e.coachX,dodger.x),y0=coachY(),vy=40,D=floorY()-y0,T=(-vy+Math.sqrt(vy*vy+2*GRAV*D))/GRAV;plan=null;\r\n  for(let i=0;i<p.count;i++)e.spawn({x:p.x+i*6,y:y0,vx:(p.aimX+(i?(i%2?1:-1)*22*i:0)-p.x)/T,vy,r:10+Math.random()*5,wobble:REST.wobble,T});\r\n  e.gunFire();\r\n  if(++throws%8===0)e.wave++;\r\n  nextThrow=e.t+T+p.gap/1000; // next volley only after this one has landed\r\n }\r\n // Core draws its laser from the bottom; rest draws the beam from the coach at the top instead.\r\n function laserDraw(){\r\n  const L=e.laser;if(L.phase==='idle')return;const m=gunMuzzle(e,gunAt()),x0=m.x,y0=m.y;\r\n  if(L.phase==='aim'){g.strokeStyle=(Math.floor(L.t*12)%2)?'#ff2a2a':'#ff8080';g.lineWidth=1;g.setLineDash([3,3]);g.beginPath();g.moveTo(x0,y0);g.lineTo(L.tx,L.ty);g.stroke();g.setLineDash([]);return;}\r\n  g.strokeStyle='#f22';g.lineWidth=L.result==='hit'?3:2;g.beginPath();g.moveTo(x0,y0);g.lineTo(L.tx,L.ty-(L.result==='shield'?14:0));g.stroke();\r\n  if(L.result==='shield'){g.fillStyle='rgba(120,200,255,.55)';for(let y=-14;y<=14;y+=4)for(let x=-12;x<=12;x+=4)if(x*x/144+y*y/196<=1)g.fillRect(L.tx+x,L.ty+y,3,3);}\r\n }\r\n function tick(now){\r\n  frame=requestAnimationFrame(tick);const dt=last?Math.min(.05,(now-last)/1000):1/60;last=now;\r\n  dodger.tilt(phone.gx);dodger.step(dt);\r\n  if(avatar)avatar.style.transform=`translateX(${(dodger.x-W/2)*k}px)`;\r\n  if(e.cool<=0){ // aim cue REST.aim seconds before each throw: the tube swings to where the barrel will land\r\n   if(!plan&&e.t>=nextThrow-REST.aim){plan=throwPlan(e.wave,e.coachX,dodger.x);e.gunAim(plan.aimX);}\r\n   if(e.t>=nextThrow)throwRock();}\r\n  if(e.t>=nextLaser&&e.laser.phase==='idle'&&e.cool<=0){e.laserStart(dodger.x,floorY(),REST.laserTelegraph/1000);nextLaser=e.t+(REST.laserEvery[0]+Math.random()*(REST.laserEvery[1]-REST.laserEvery[0]))/1000;}\r\n  // Motion fed to the shield check = max(phone motion, finger motion) in screen heights/s.\r\n  if(e.laser.phase==='aim')e.laser.tx=dodger.x;\r\n  e.feedMotion(Math.max(phone.motion,pointer.down?pointer.speed:0));pointer.speed*=.9;\r\n  e.step(dt);\r\n  for(const o of e.objects)if(!o.hold&&!o.bonus&&o.vy>0&&Math.abs(o.x-dodger.x)<o.r+10&&Math.abs(o.y-(floorY()-6))<o.r+14){ // caught by the character: soft feedback, no strike\r\n   o.alive=false;e.laser.flash=.12;say('Ouch. Dodge with a tilt.');window.myr5Creature?.play('rest');}\r\n  g.clearRect(0,0,e.w,e.h);\r\n  render(g,{...e,laser:{...e.laser,phase:'idle'}},{coach:c=>drawGun(c,e,gunAt())});laserDraw();\r\n }\r\n const down=ev=>{if(ev.target.closest?.('button:not(#attackCoach),a,select,input'))return;try{void requestPhoneMotion();}catch{}pointer.down=true;swallow=false;const p=toLogical(ev);pointer.x=p.x;pointer.y=p.y;swipe.down(p);};\r\n const move=ev=>{if(!pointer.down)return;const p=toLogical(ev),seg=swipe.move(p);if(!seg)return;\r\n  pointer.speed=Math.hypot(p.x-pointer.x,p.y-pointer.y)/e.h*30;pointer.x=p.x;pointer.y=p.y;e.addTrail(p.x,p.y);\r\n  if(e.hitSegment(seg[0],seg[1],{kind:'slice'}))swallow=true;};\r\n const up=()=>{if(!pointer.down)return;pointer.down=false;const tap=swipe.up();if(tap&&e.hitSegment(tap,tap,{kind:'explode'}))swallow=true;};\r\n const click=ev=>{if(swallow||swipe.moved){ev.stopImmediatePropagation();ev.preventDefault();swallow=false;}}; // slicing must not also punch the coach\r\n const keys=ev=>{const d=ev.key==='ArrowLeft'?-1:ev.key==='ArrowRight'?1:0;if(d)dodger.key(ev.type==='keydown'?d:0);};\r\n return {\r\n  start(){\r\n   if(frame)return;runOwner=performanceOwner();reportQuest=createQuestProgressReporter(runOwner);begin();scene.append(canvas);last=0;frame=requestAnimationFrame(tick);\r\n   scene.addEventListener('pointerdown',down,{passive:true});scene.addEventListener('pointermove',move,{passive:true});\r\n   addEventListener('pointerup',up);addEventListener('pointercancel',up);attackButton?.addEventListener('click',click,true);\r\n   addEventListener('keydown',keys);addEventListener('keyup',keys);\r\n   let pg=0;unsub=subscribePhoneMotion(s=>{phone.motion=Math.abs(s.shake||0)/20+Math.abs(s.angularSpeed||0)/3+Math.abs(s.gx-pg)*3;pg=s.gx;phone.gx=s.gx;});\r\n  },\r\n  stop(){\r\n   cancelAnimationFrame(frame);frame=0;canvas.remove();unsub();unsub=()=>{};if(avatar)avatar.style.transform='';\r\n   scene.removeEventListener('pointerdown',down);scene.removeEventListener('pointermove',move);\r\n   removeEventListener('pointerup',up);removeEventListener('pointercancel',up);attackButton?.removeEventListener('click',click,true);\r\n   removeEventListener('keydown',keys);removeEventListener('keyup',keys);\r\n  },\r\n  get engine(){return e;},\r\n };\r\n}\r\n","arcade/slice/rest-logic.mjs":"// Rest-mode (touch + tilt) pieces of Fruit Ninja rest. Pure logic, no DOM: the shared engine is arcade/slice/core.mjs.\r\nexport const REST={dodgeSpeed:420,tiltGain:2.2,stillMotion:.9,laserTelegraph:1000,laserEvery:[9000,14000],throwEvery:[1400,700],strikesMax:3,firstThrowDelay:0,wobble:5,aim:.45};\r\n\r\n// Dodger: the user's character slides along the floor. gx (screen-right gravity, -1..1) from the phone, keys / drag as fallback.\r\nexport function createDodger(width,margin=40){\r\n let x=width/2,target=x,key=0;\r\n const clamp=v=>Math.min(width-margin,Math.max(margin,v));\r\n return {\r\n  get x(){return x;},\r\n  resize(w){const f=x/width;width=w;x=clamp(f*w);target=x;},\r\n  tilt(gx){target=clamp(width/2+Math.max(-1,Math.min(1,gx*REST.tiltGain))*(width/2-margin));},\r\n  drag(px){target=clamp(px);},\r\n  key(dir){key=dir;},\r\n  step(dt){if(key)target=clamp(target+key*REST.dodgeSpeed*dt);const d=target-x,m=REST.dodgeSpeed*1.6*dt;x=clamp(x+Math.max(-m,Math.min(m,d)));return x;},\r\n };\r\n}\r\n\r\n// Thrower: coach at the top aims where the character is now, so dodging matters. Waves get faster with wave number.\r\nexport function throwPlan(wave,coachX,dodgerX,rand=Math.random){\r\n const [a,b]=REST.throwEvery,gap=Math.max(b,a-wave*90),spread=(rand()-.5)*80;\r\n return {gap,x:coachX,aimX:dodgerX+spread,count:Math.min(3,1+Math.floor(wave/3))}; // volley of 1-3, never a stream\r\n}\r\n\r\n// Swipe: pointer path -> segments to push through core.hitSegment; a path that never moves far is a tap.\r\nexport function createSwipe(tapRadius=10){\r\n let last=null,start=null,far=false;\r\n return {\r\n  down(p){last=start=p;far=false;return null;},\r\n  move(p){if(!last)return null;const seg=[last,p];last=p;if(Math.hypot(p.x-start.x,p.y-start.y)>tapRadius)far=true;return seg;},\r\n  up(){const tap=last&&!far?start:null;last=start=null;return tap;},\r\n  get moved(){return far;},\r\n };\r\n}\r\n","arcade/tub-flight/engine.mjs":"export const WIDTH=320,HEIGHT=420,TARGET=8;\r\n// endless ramp: every 3 pipes the gap narrows 2px (half-gap) and speed rises 4px/s, capped at level 8 (half 59, speed 140) so it stays phone-playable\r\nexport const level=score=>Math.min(8,Math.floor(score/3)),gapHalf=score=>75-2*level(score),speed=score=>108+4*level(score);\r\nexport class TubFlight {\r\n constructor(random=Math.random){this.random=random;this.reset();}\r\n reset(){this.phase='ready';this.y=210;this.velocity=0;this.pipes=[];this.score=0;this.elapsed=0;this.spawnIn=0;this.powder=0;this.lastDose=null;return this;}\r\n flap(){if(this.phase==='crashed')return false;if(this.phase==='ready'){this.phase='running';this.spawnIn=.8;}this.velocity=-245;return true;}\r\n spawn(){this.pipes.push({x:WIDTH+26,gap:122+this.random()*145,half:gapHalf(this.score),passed:false});}\r\n step(seconds){if(this.phase!=='running')return;let left=Math.min(.1,Math.max(0,seconds));while(left>0&&this.phase==='running'){const dt=Math.min(left,1/120);left-=dt;this.elapsed+=dt;this.velocity+=690*dt;this.y+=this.velocity*dt;this.spawnIn-=dt;if(this.spawnIn<=0){this.spawn();this.spawnIn=205/speed(this.score);}\r\n   if(this.y<20||this.y>HEIGHT-36){this.phase='crashed';break;}\r\n   for(const pipe of this.pipes){pipe.x-=speed(this.score)*dt;const h=pipe.half;const overlaps=82+13>pipe.x&&82-13<pipe.x+44;if(overlaps&&(this.y-13<pipe.gap-h||this.y+13>pipe.gap+h)){this.phase='crashed';break;}if(!pipe.passed&&pipe.x+44<82-13){pipe.passed=true;this.score++;this.powder=Math.min(this.score,TARGET);this.lastDose={x:pipe.x+22,y:pipe.gap-h,at:this.elapsed};}}\r\n   this.pipes=this.pipes.filter(pipe=>pipe.x>-60);\r\n  }\r\n }\r\n}\r\n","arcade/tub-flight/game.mjs":"import {TubFlight,WIDTH,HEIGHT,TARGET} from './engine.mjs';\r\nexport const FUEL_KEY='mbs-fuel-flight-v1',BEST_KEY='mbs-tub-best-v1';\r\nexport function bestScore(store=localStorage){try{const n=JSON.parse(store.getItem(BEST_KEY));return Number.isSafeInteger(n)&&n>0?n:0;}catch{return 0;}}\r\nexport function fuelUnlocked(store=localStorage){try{const value=JSON.parse(store.getItem(FUEL_KEY));return value?.version===1&&value.pipes===8&&Number.isSafeInteger(value.completedAt)&&value.completedAt>0;}catch{return false;}}\r\nexport function mountTubFlight(host,{onComplete=()=>{},title='TUB FLIGHT',autoFuel=false}={}){\r\n const game=new TubFlight();let frame=0,last=0,paused=false,ended=false,disposed=false,scored=false,toastTimer=0,best=bestScore(),runBest=best;\r\n host.classList.add('tub-flight');host.innerHTML='<div class=\"tub-title\"><strong></strong><span>SPONSORED SOFTWARE · 1995</span></div><p class=\"tub-caption\">Keep the tub afloat. The pipes never end. Eight pipes unlock Fuel.</p><div class=\"tub-screen\"><canvas width=\"320\" height=\"420\" tabindex=\"0\" aria-label=\"Fuel tub flight game. Tap or press Space to flap.\"></canvas><div class=\"tub-toast\" role=\"status\" hidden></div><div class=\"tub-message\" role=\"status\"></div></div><div class=\"tub-controls\"><button type=\"button\" data-flap>FLAP ↑</button><button type=\"button\" data-retry hidden>TRY AGAIN ↻</button><button type=\"button\" data-pause>Pause</button></div><p class=\"tub-note\">Optional arcade break. This game never unlocks the rest of the site.</p>';\r\n host.querySelector('.tub-title strong').textContent=title;const canvas=host.querySelector('canvas'),ctx=canvas.getContext('2d'),message=host.querySelector('.tub-message'),toast=host.querySelector('.tub-toast'),flapButton=host.querySelector('[data-flap]'),retry=host.querySelector('[data-retry]'),pause=host.querySelector('[data-pause]');\r\n function tub(x,y,tilt=0){ctx.save();ctx.translate(x,y);ctx.rotate(tilt);ctx.fillStyle='#eee4ff';ctx.fillRect(-15,-17,30,34);ctx.fillStyle='#692ca7';ctx.fillRect(-15,-3,30,14);ctx.fillStyle='#b5ff23';ctx.fillRect(-17,-21,34,7);ctx.fillStyle='#edffb8';ctx.fillRect(-11,14-game.powder*3.8,22,game.powder*3.8);ctx.fillStyle='#291044';ctx.font='bold 8px monospace';ctx.textAlign='center';ctx.fillText('FUEL',0,6);ctx.restore();}\r\n function draw(){ctx.imageSmoothingEnabled=false;ctx.fillStyle='#130e2c';ctx.fillRect(0,0,WIDTH,HEIGHT);ctx.fillStyle='#31254d';for(let x=0;x<WIDTH;x+=32){const y=300+(x%3)*7;ctx.fillRect(x,y,22,HEIGHT-y);ctx.fillStyle='#617348';ctx.fillRect(x+5,y+12,3,3);ctx.fillStyle='#31254d';}ctx.fillStyle='#74548f';for(let i=0;i<25;i++)ctx.fillRect((i*73)%320,(i*53)%285,2,2);\r\n  for(const p of game.pipes){const top=p.gap-p.half,bottom=p.gap+p.half;ctx.fillStyle='#216d68';ctx.fillRect(p.x,0,44,top);ctx.fillRect(p.x,bottom,44,HEIGHT-bottom);ctx.fillStyle='#7ce8b5';ctx.fillRect(p.x+4,0,7,top);ctx.fillRect(p.x+4,bottom,7,HEIGHT-bottom);ctx.fillStyle='#ade2be';ctx.fillRect(p.x-5,top-14,54,14);ctx.fillRect(p.x-5,bottom,54,14);ctx.fillStyle='#193b48';ctx.fillRect(p.x+15,top-10,14,8);ctx.fillRect(p.x+15,bottom+3,14,8);}\r\n  if(game.lastDose){const age=game.elapsed-game.lastDose.at;if(age<.8){for(let i=0;i<10;i++){const t=Math.min(1,(age+i*.015)/.8);ctx.fillStyle='#e9ffc9';ctx.fillRect(game.lastDose.x+(82-game.lastDose.x)*t+Math.sin(i*3)*8,game.lastDose.y+(game.y-game.lastDose.y)*t,2,3);}}}\r\n  tub(82,game.y,Math.max(-.35,Math.min(.65,game.velocity/650)));ctx.fillStyle='#bdd861';ctx.fillRect(0,HEIGHT-18,WIDTH,18);ctx.fillStyle='#172528';for(let x=0;x<WIDTH;x+=16)ctx.fillRect(x,HEIGHT-15,9,4);\r\n  ctx.textAlign='left';ctx.font='bold 18px monospace';ctx.fillStyle='#efffc9';ctx.fillText(`${game.score}`,14,29);ctx.font='11px monospace';ctx.fillStyle='#97caca';ctx.fillText(`BEST ${Math.max(best,game.score)}`,14,45);\r\n }\r\n function paint(){draw();const ready=game.phase==='ready',crashed=game.phase==='crashed';message.hidden=game.phase==='running'&&!paused;message.textContent=paused?'PAUSED':ready?'TAP TO KEEP IT UP':crashed?`TUB DOWN\r\nSCORE ${game.score} · BEST ${best}${game.score>runBest?'\\nNEW BEST!':''}`:'';retry.hidden=!crashed;flapButton.hidden=crashed;pause.disabled=ready||crashed;pause.textContent=paused?'Resume':'Pause';canvas.setAttribute('aria-label',`Fuel tub flight. ${game.score} pipes, best ${best}. ${game.phase}. Tap or press Space to flap.`);}\r\n function report(){if(scored||!game.score)return;scored=true;try{const k='myr5-vault-pending',q=JSON.parse(localStorage.getItem(k)||'[]');q.push(['arcade-score',game.score]);localStorage.setItem(k,JSON.stringify(q.slice(-50)));}catch{}}\r\n function tick(now){frame=0;if(disposed)return;const dt=last?(now-last)/1000:0;last=now;if(!paused&&!document.hidden)game.step(dt);if(game.score>best){best=game.score;try{localStorage.setItem(BEST_KEY,String(best));}catch{}}if(game.phase==='crashed')report();if(game.score>=TARGET&&!ended){ended=true;const receipt={version:1,pipes:8,completedAt:Date.now()};try{localStorage.setItem(FUEL_KEY,JSON.stringify(receipt));}catch{}onComplete(receipt);toast.innerHTML=autoFuel?'FUEL UNLOCKED · <a href=\"/games/fuel/\">OPEN FUEL ›</a>':'FUEL UNLOCKED';toast.hidden=false;clearTimeout(toastTimer);toastTimer=setTimeout(()=>{toast.hidden=true;},3500);}paint();if(game.phase==='running'&&!paused&&!document.hidden)frame=requestAnimationFrame(tick);}\r\n function schedule(){if(frame)cancelAnimationFrame(frame);frame=0;last=0;if(game.phase==='running'&&!paused&&!document.hidden)frame=requestAnimationFrame(tick);paint();}\r\n function flap(){if(paused)return;if(game.flap()){if(!frame){last=performance.now();frame=requestAnimationFrame(tick);}paint();}}\r\n const pointer=e=>{e.preventDefault();flap();};const key=e=>{if(['Space','ArrowUp','KeyW'].includes(e.code)){e.preventDefault();flap();}};\r\n canvas.addEventListener('pointerdown',pointer);canvas.addEventListener('keydown',key);flapButton.onclick=flap;retry.onclick=()=>{clearTimeout(toastTimer);game.reset();runBest=best;ended=false;scored=false;toast.hidden=true;paused=false;paint();canvas.focus();};pause.onclick=()=>{paused=!paused;schedule();};\r\n function visibility(){if(document.hidden&&game.phase==='running'){paused=true;}schedule();}document.addEventListener('visibilitychange',visibility);paint();\r\n return {game,pause(){paused=true;schedule();},dispose(){report();disposed=true;clearTimeout(toastTimer);if(frame)cancelAnimationFrame(frame);canvas.removeEventListener('pointerdown',pointer);canvas.removeEventListener('keydown',key);document.removeEventListener('visibilitychange',visibility);host.replaceChildren();}};\r\n}\r\n","arcade/tub-flight/index.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><title>Tub Flight · MOM Inc</title><link rel=\"stylesheet\" href=\"./style.css\"><style>body{margin:0;min-height:100dvh;display:grid;place-content:center;background:repeating-linear-gradient(45deg,#164743 0 12px,#17423e 12px 24px);padding:18px;box-sizing:border-box}body>a{font:14px Tahoma;color:#d2ffdb;padding:12px;text-align:center}</style></head><body><main id=\"game\"></main><a href=\"/tv/?ch=mominc\">← Back to MOM Inc</a><script type=\"module\">import{mountTubFlight}from'./game.mjs';const game=mountTubFlight(document.getElementById('game'),{autoFuel:true});addEventListener('pagehide',()=>game.dispose(),{once:true});</script></body></html>\r\n","arcade/tub-flight/style.css":".tub-flight{width:min(100%,380px);margin:auto;padding:7px;background:#c0c0c0;border:3px outset #e8e8e8;box-sizing:border-box;color:#142023;font:12px/1.4 Tahoma,Arial,sans-serif;box-shadow:6px 6px 0 #08031280}.tub-title{display:flex;justify-content:space-between;gap:12px;align-items:center;background:linear-gradient(90deg,#070b66,#386d7c);color:#fff;padding:7px}.tub-title strong{font-size:16px}.tub-title span{font-size:8px;max-width:85px}.tub-caption{margin:8px 2px}.tub-screen{position:relative;border:3px inset #eee;background:#130e2c}.tub-screen canvas{width:100%;display:block;max-height:56dvh;object-fit:contain;touch-action:manipulation;image-rendering:pixelated;outline-offset:-3px}.tub-screen canvas:focus-visible{outline:3px solid #baff53}.tub-message{position:absolute;left:20px;right:20px;top:41%;text-align:center;font:bold 16px/1.5 monospace;background:#0b092bde;color:#c7ff43;padding:14px;border:2px solid #79a999;pointer-events:none}.tub-controls{display:flex;gap:7px;margin-top:8px}.tub-controls button{flex:1;min-height:48px;border:3px outset #eee;background:#c9ff59;color:#1b2432;font-weight:900;font-size:14px;cursor:pointer}.tub-controls [data-pause]{flex:0 0 auto;background:#c0c0c0;font-size:12px}.tub-controls button:disabled{opacity:.5}.tub-note{margin:7px 2px 0;font-size:10px}.tub-flight [hidden]{display:none!important}\r\n.tub-message{white-space:pre-line}.tub-toast{position:absolute;left:20px;right:20px;top:58px;text-align:center;font:bold 12px/1.4 monospace;background:#c7ff43;color:#1b2432;padding:6px;border:2px solid #1b2432;pointer-events:none;z-index:2}.tub-toast a{color:#1b2432;pointer-events:auto}\r\n","arcade/workout-effects-state.mjs":"// Tiny core-safe workout effect snapshot builder. Keep this independent from\r\n// optional Canvas2D renderer modules so first-run offline app boot stays intact.\r\n// The one video->overlay mapper (object-fit:contain, mirror once in math). Lives in this core-safe module so the\r\n// bundled coach overlay and the lazy effect modules share it; workout-effects.mjs re-exports it.\r\nexport function videoRectInOverlay({videoWidth,videoHeight,hostWidth,hostHeight}={}){\r\n if(![videoWidth,videoHeight,hostWidth,hostHeight].every(Number.isFinite)||videoWidth<=0||videoHeight<=0||hostWidth<=0||hostHeight<=0)return null;\r\n const scale=Math.min(hostWidth/videoWidth,hostHeight/videoHeight),w=videoWidth*scale,h=videoHeight*scale;\r\n return {x:(hostWidth-w)/2/hostWidth,y:(hostHeight-h)/2/hostHeight,w:w/hostWidth,h:h/hostHeight};\r\n}\r\nexport function mapPointToOverlay(point,geometry={}){\r\n if(!point||!Number.isFinite(point.x)||!Number.isFinite(point.y))return null;\r\n const r=videoRectInOverlay(geometry);if(!r)return null;\r\n const px=geometry.mirrored?1-point.x:point.x;\r\n return {x:r.x+px*r.w,y:r.y+point.y*r.h,visibility:Number.isFinite(point.visibility)?point.visibility:0};\r\n}\r\nexport function mapPointsToOverlay(points,geometry){\r\n return Array.isArray(points)?points.map(point=>mapPointToOverlay(point,geometry)):null;\r\n}\r\n\r\nexport function workoutEffectsSnapshot({pose={},motion={},workout=null,sessionId=null,ownerId=null,mode=null,tracking=false,visible=true,canCount=false,workingSet=false}={}){\r\n const active=!!(tracking&&visible&&motion.tracking===true&&workingSet&&workout&&workout.counting&&!workout.finished);\r\n return {\r\n  points:pose.points??null,world:pose.world??null,width:pose.width,height:pose.height,mirrored:!!pose.mirrored,now:pose.now,frameMs:Number.isFinite(pose.frameMs)?pose.frameMs:pose.now,mask:pose.mask??null,\r\n  validHold:!!(active&&motion.kind==='hold'&&motion.progress===1&&canCount),\r\n  workout:{sessionId:sessionId??null,ownerId:ownerId??null,mode:workout?.mode??mode??null,kind:workout?.kind??motion.kind??null,stage:workout?.stage??null,paused:workout?.paused===true,active,\r\n   workingReps:Number.isFinite(workout?.value)?workout.value:0,activeSeconds:Number.isFinite(workout?.activeSeconds)?workout.activeSeconds:0,difficulty:workout?.difficulty??'easy'}\r\n };\r\n}\r\n\r\nexport function isMartialSliceExercise(exercise){\r\n return !!(exercise&&exercise.kind!=='hold'&&(exercise.group==='stances'||exercise.group==='boxing'));\r\n}\r\n\r\nexport function holdStyleForExercise(exercise){\r\n if(!exercise||exercise.kind!=='hold')return null;\r\n if(exercise.group==='stances')return null;\r\n if(exercise.group==='core'||exercise.group==='balance')return 'blizzard';\r\n return 'living';\r\n}\r\n\r\nexport function latestRetainableWorkoutSnapshot(current,next,ownerId){\r\n const workout=next?.workout;\r\n if(!workout||!ownerId||workout.ownerId!==ownerId||workout.stage!=='working'||workout.paused===true\r\n    ||!['reps','hold'].includes(workout.kind)\r\n    ||!(Number(workout.workingReps)>0||(workout.kind==='hold'&&Number(workout.activeSeconds)>0)))return current;\r\n return next;\r\n}\r\n\r\n// Small bounded retry window for optional artwork/storage imports. The caller\r\n// starts attempts only in response to a later activity event, never on a timer.\r\nexport function createOptionalRetry({now=()=>Date.now(),maxAttempts=3,baseDelay=1000,maxDelay=8000,cooldown=30000}={}){\r\n let attempts=0,retryAt=0;\r\n return {\r\n  canStart(){if(attempts>=maxAttempts&&now()>=retryAt){attempts=0;retryAt=0;}return attempts<maxAttempts&&now()>=retryAt;},\r\n  start(){if(attempts<maxAttempts)attempts++;return attempts;},\r\n  fail(){retryAt=now()+(attempts>=maxAttempts?cooldown:Math.min(maxDelay,baseDelay*2**Math.max(0,attempts-1)));},\r\n  succeed(){attempts=0;retryAt=0;},\r\n  reset(){attempts=0;retryAt=0;},\r\n  get attempts(){return attempts;}\r\n };\r\n}\r\n\r\nconst OPTIONAL_IMPORT_NONCE=Symbol.for('myr5.optional-import-nonce');\r\nfunction nextOptionalImportNonce(){const next=(Number(globalThis[OPTIONAL_IMPORT_NONCE])||0)+1;globalThis[OPTIONAL_IMPORT_NONCE]=next;return next;}\r\n/** Load one optional entry by absolute URL; cache success/in-flight work and\r\n * query-bust only after a real rejection so a later caller can escape the\r\n * browser's cached failed module entry without adding timer retries. */\r\nexport function createOptionalModuleLoader(entryUrl,{importer=url=>import(url)}={}){\r\n const base=new URL(entryUrl,globalThis.location?.href??import.meta.url).href;let loaded=null,inflight=null,failed=false;\r\n return function loadOptionalModule(){\r\n  if(loaded)return Promise.resolve(loaded);\r\n  if(inflight)return inflight;\r\n  let url=base;\r\n  if(failed){const retry=new URL(base);retry.searchParams.set('myr5_retry',String(nextOptionalImportNonce()));url=retry.href;}\r\n  const task=Promise.resolve().then(()=>importer(url)).then(module=>{loaded=module;return module;},error=>{failed=true;throw error;}).finally(()=>{if(inflight===task)inflight=null;});\r\n  inflight=task;return task;\r\n };\r\n}\r\n","arcade/workout-effects.mjs":"// Shared AR geometry and lazy wrapper lifecycle for optional workout effects.\r\n// Landmark coordinates stay normalized; geometry is mapped to the overlay that owns the video.\r\nexport {workoutEffectsSnapshot} from './workout-effects-state.mjs';\r\nimport {holdStyleForExercise,createOptionalRetry,createOptionalModuleLoader} from './workout-effects-state.mjs';\r\nexport {mapPointToOverlay,mapPointsToOverlay,videoRectInOverlay} from './workout-effects-state.mjs';\r\nimport {EXERCISES} from '../exercise-library.mjs';\r\nconst loadCameraHoldModule=createOptionalModuleLoader('/arcade/hold/camera-hold.mjs');\r\nconst loadCameraPowerModule=createOptionalModuleLoader('/arcade/power/camera-power.mjs');\r\nexport function createOverlayCanvas(host,className,{opacity=.3,max=.3}={}){\r\n const canvas=document.createElement('canvas');canvas.className=className;canvas.setAttribute('aria-hidden','true');\r\n canvas.style.cssText=`position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated;pointer-events:none;z-index:0;opacity:${Math.max(0,Math.min(max,opacity))}`;\r\n const resize=()=>{const rect=host.getBoundingClientRect();const dpr=Math.min(2,window.devicePixelRatio||1),w=Math.max(1,Math.round(rect.width*dpr)),h=Math.max(1,Math.round(rect.height*dpr));if(canvas.width!==w||canvas.height!==h){canvas.width=w;canvas.height=h;}};\r\n host.prepend(canvas);resize();const observer=typeof ResizeObserver==='function'?new ResizeObserver(resize):null;observer?.observe(host);\r\n return {canvas,resize,dispose(){observer?.disconnect();canvas.remove();}};\r\n}\r\n\r\n/** Warm the right renderer module and sprite sheets for an exercise before its set starts. */\r\nexport function preloadWorkoutEffects(mode){\r\n const ex=EXERCISES[mode];if(!ex)return;\r\n const stance=ex.kind==='hold'&&ex.group!=='stances';\r\n (stance?loadCameraHoldModule():loadCameraPowerModule()).then(m=>m.preloadAuraForMode?.(mode)).catch(()=>{});\r\n if(ex.kind==='hold')loadCameraPowerModule().then(m=>m.preloadAuraForMode?.(mode)).catch(()=>{});\r\n}\r\nexport function mountWorkoutEffects({host,sound=()=>{},seed=1,loaders={},retryOptions}={}){\r\n let ecology=null,power=null,ecologyLoading=null,powerLoading=null,session=null,stopped=false,epoch=0,holdGeneration=0,powerGeneration=0,lastDetail=null,selectedHoldStyle='living';\r\n const holdRetry=createOptionalRetry(retryOptions),powerRetry=createOptionalRetry(retryOptions);\r\n const dropHold=()=>{holdGeneration++;holdRetry.reset();ecology?.stop();ecology=null;ecologyLoading=null;};\r\n const drop=()=>{epoch++;dropHold();powerGeneration++;powerRetry.reset();power?.stop();power=null;powerLoading=null;session=null;lastDetail=null;};\r\n function invalidate(){holdGeneration++;powerGeneration++;holdRetry.reset();powerRetry.reset();ecologyLoading=powerLoading=null;ecology?.invalidate();power?.invalidate();}\r\n async function ensure(kind,token,loadGeneration){\r\n  if(stopped||token!==epoch)return null;\r\n  if(kind==='hold'){\r\n   if(ecology)return ecology;\r\n   if(!ecologyLoading){if(!holdRetry.canStart())return null;holdRetry.start();const style=selectedHoldStyle;const pending=(async()=>{const mod=await (loaders.hold?loaders.hold(style):loadCameraHoldModule());holdRetry.succeed();if(stopped||token!==epoch||loadGeneration!==holdGeneration||style!==selectedHoldStyle||!lastDetail?.workout?.active)return null;ecology=mod.mountCameraHold({host,sound,onXp:()=>{},seed,style,mode:lastDetail?.workout?.mode});return ecology;})();ecologyLoading=pending;pending.catch(()=>{if(ecologyLoading===pending&&token===epoch&&loadGeneration===holdGeneration){holdRetry.fail();ecologyLoading=null;}});}\r\n   return ecologyLoading;\r\n  }\r\n  if(power)return power;\r\n  if(!powerLoading){if(!powerRetry.canStart())return null;powerRetry.start();const pending=(async()=>{const mod=await (loaders.power?loaders.power():loadCameraPowerModule());powerRetry.succeed();if(stopped||token!==epoch||loadGeneration!==powerGeneration||!lastDetail?.workout?.active)return null;power=mod.mountCameraPower({host,sound,seed});return power;})();powerLoading=pending;pending.catch(()=>{if(powerLoading===pending&&token===epoch&&loadGeneration===powerGeneration){powerRetry.fail();powerLoading=null;}});}\r\n  return powerLoading;\r\n }\r\n function pose(detail){\r\n  if(stopped)return;\r\n  const workout=detail?.workout||{},key=workout.sessionId;\r\n  lastDetail=detail;\r\n  if(key==null||!workout.active){invalidate();if(workout.kind==='hold'&&ecology)ecology.pose(detail);return;}\r\n  const sessionKey=`${key}:${workout.mode??''}`;\r\n  if(session!==sessionKey){drop();session=sessionKey;lastDetail=detail;}\r\n  const token=epoch;\r\n  if(workout.kind==='hold'){\r\n   const style=holdStyleForExercise(EXERCISES[workout.mode]);if(style!==selectedHoldStyle)setHoldStyle(style);\r\n   if(selectedHoldStyle&&ecology)ecology.pose(detail);else if(selectedHoldStyle){const loadGeneration=holdGeneration;void ensure('hold',token,loadGeneration).then(instance=>{if(instance&&token===epoch&&loadGeneration===holdGeneration&&session===sessionKey&&lastDetail?.workout?.active)instance.pose(lastDetail);}).catch(()=>{});}\r\n   if(selectedHoldStyle==='blizzard'){power?.invalidate();return;}\r\n   if(power)power.pose(detail);else{const loadGeneration=powerGeneration;void ensure('power',token,loadGeneration).then(instance=>{if(instance&&token===epoch&&loadGeneration===powerGeneration&&session===sessionKey&&lastDetail?.workout?.active)instance.pose(lastDetail);}).catch(()=>{});}\r\n  }else if(['reps','gentle','sprint'].includes(workout.kind)){\r\n   ecology?.invalidate();\r\n   if(power){power.pose(detail);return;}\r\n   const loadGeneration=powerGeneration;void ensure('power',token,loadGeneration).then(instance=>{if(instance&&token===epoch&&loadGeneration===powerGeneration&&session===sessionKey&&lastDetail?.workout?.active)instance.pose(lastDetail);}).catch(()=>{});\r\n  }else{ecology?.invalidate();power?.invalidate();}\r\n }\r\n function stop(){if(stopped)return;stopped=true;drop();}\r\n function setHoldStyle(style){const next=style===null?null:style==='blizzard'?'blizzard':'living';if(next===selectedHoldStyle)return selectedHoldStyle;selectedHoldStyle=next;dropHold();return selectedHoldStyle;}\r\n return {pose,stop,invalidate,setHoldStyle,get holdStyle(){return selectedHoldStyle;},get active(){return !!(ecology||power);}};\r\n}\r\n\r\n// Shared frame-time monitor for the camera effect layers (power, hold, slice can all report into it).\r\n// Q3 silhouette mask + wisps, Q2 bone glow + flame particles, Q1 bone glow only, Q0 sprites only.\r\n// Rolling mean of rAF frame intervals: step down when it passes DOWN_MS, step up after UP_HOLD_MS under UP_MS.\r\n// Q3 must be earned (start at START) and once dropped from Q3 the session stays at Q2 or below.\r\nexport const EFFECT_QUALITY=Object.freeze({START:2,MAX:3,WINDOW:60,DOWN_MS:28,UP_MS:20,UP_HOLD_MS:3000,DOWN_HOLD_MS:500,SESSION_CAP_MS:5000,SESSION_CAP_FPS_MS:50});\r\nexport function createQualityMonitor(T=EFFECT_QUALITY){\r\n const ring=new Float32Array(T.WINDOW);let n=0,i=0,sum=0,tier=T.START,cap=T.MAX,goodFor=0,badFor=0,slowFor=0,pinned=null;const listeners=new Set();\r\n const set=next=>{next=Math.max(0,Math.min(cap,next));if(next===tier)return;const prev=tier;tier=next;goodFor=badFor=0;for(const fn of listeners)try{fn(tier,prev);}catch{}};\r\n return {\r\n  frame(ms){\r\n   if(pinned!=null||!(ms>0)||ms>250)return tier; // pinned (debug), tab switches and first frames are not frame cost\r\n   sum-=n===T.WINDOW?ring[i]:0;ring[i]=ms;sum+=ms;i=(i+1)%T.WINDOW;if(n<T.WINDOW)n++;\r\n   const avg=sum/n;if(n<Math.min(15,T.WINDOW))return tier;\r\n   if(avg>T.DOWN_MS){badFor+=ms;goodFor=0;if(badFor>=T.DOWN_HOLD_MS){if(tier===3)cap=2;set(tier-1);}}\r\n   else if(avg<T.UP_MS){goodFor+=ms;badFor=0;if(goodFor>=T.UP_HOLD_MS)set(tier+1);}\r\n   else{goodFor=0;badFor=0;}\r\n   if(avg>T.SESSION_CAP_FPS_MS){slowFor+=ms;if(slowFor>=T.SESSION_CAP_MS){cap=Math.max(0,Math.min(cap,tier)-1);slowFor=0;set(tier);}}else slowFor=0;\r\n   return tier;\r\n  },\r\n  get tier(){return tier;},get average(){return n?sum/n:0;},get cap(){return cap;},\r\n  onChange(fn){listeners.add(fn);return()=>listeners.delete(fn);},\r\n  /** Debug / test: hold a tier (0..3), or null to let the ladder run again. */\r\n  pin(next=null){pinned=next==null?null:Math.max(0,Math.min(T.MAX,next|0));if(pinned!=null){const keep=cap;cap=T.MAX;set(pinned);cap=keep;}},\r\n  reset(){n=i=0;sum=0;tier=T.START;cap=T.MAX;goodFor=badFor=slowFor=0;ring.fill(0);}\r\n };\r\n}\r\nexport const effectQuality=createQualityMonitor();\r\nglobalThis.myr5EffectQuality=effectQuality;\r\n// Phone debugging: ?auraq=0..3 holds a quality tier for the session.\r\ntry{const q=new URLSearchParams(globalThis.location?.search??'').get('auraq');if(q!=null&&q!=='')effectQuality.pin(Number(q));}catch{}\r\n","armie-inbox-ui.mjs":"// Minimal, standalone inbox surface for D12 Armie letters (D23). Deliberately\r\n// small: a badge button + a plain list dialog. The owner is building the\r\n// battle-pass/achievements menu himself (D26) -- this is not that, and never\r\n// grows into it. Hidden outright during camera-only mode (the\r\n// `body[data-camera-workout]` rule below), matching \"nothing appears during\r\n// camera-only mode.\"\r\nimport {armieInbox,canOfferArmiePush,maybeRequestArmiePushPermission} from './armie-letters-client.mjs';\r\n\r\nconst STYLE = `\r\n.armie-inbox-launcher{position:fixed;right:12px;bottom:12px;z-index:40;min-width:40px;height:40px;padding:0 10px;border-radius:20px;border:none;background:#1b1030;color:#fff;font:600 13px system-ui,sans-serif;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.35);}\r\n.armie-inbox-launcher[hidden],body[data-camera-workout] .armie-inbox-launcher{display:none!important;}\r\n.armie-inbox-dialog{max-width:360px;width:92vw;border:none;border-radius:12px;padding:0;color:#1b1030;}\r\n.armie-inbox-dialog::backdrop{background:rgba(0,0,0,.4);}\r\n.armie-inbox-dialog header{display:flex;justify-content:space-between;align-items:center;padding:12px 14px;border-bottom:1px solid #e3ddf2;font:600 14px system-ui,sans-serif;}\r\n.armie-inbox-dialog header button{border:none;background:none;font-size:18px;line-height:1;cursor:pointer;}\r\n.armie-inbox-dialog ul{list-style:none;margin:0;padding:0;max-height:60vh;overflow:auto;}\r\n.armie-inbox-dialog li{padding:10px 14px;border-bottom:1px solid #e3ddf2;font:13px system-ui,sans-serif;cursor:pointer;}\r\n.armie-inbox-dialog li[data-read=\"0\"]{background:#f2effa;font-weight:600;}\r\n.armie-inbox-dialog li strong{display:block;margin-bottom:4px;}\r\n.armie-inbox-dialog li p{margin:2px 0;opacity:.85;font-weight:400;}\r\n.armie-inbox-notice{margin:0;padding:10px 14px;font:12px system-ui,sans-serif;background:#fff4d6;}\r\n`;\r\n\r\nlet mountPromise = null;\r\n\r\n// D23: iOS delivers web push only to the installed home-screen app. Explain\r\n// that once here rather than nagging every time the inbox opens.\r\nconst isIosBrowserTab = () => /iPad|iPhone|iPod/.test(navigator.userAgent) && !navigator.standalone;\r\n\r\nexport function setArmieLauncherOwned(launcher, owned) {\r\n launcher.hidden = !owned;\r\n launcher.inert = !owned;\r\n if (owned) launcher.removeAttribute('tabindex'); else launcher.tabIndex = -1;\r\n}\r\n\r\nexport function mountArmieInboxUI({root = document.body} = {}) {\r\n return mountPromise ??= (async () => {\r\n  const style = document.createElement('style');\r\n  style.textContent = STYLE;\r\n  document.head.append(style);\r\n\r\n  const launcher = document.createElement('button');\r\n  launcher.type = 'button';\r\n  launcher.className = 'armie-inbox-launcher';\r\n  launcher.setAttribute('aria-label', 'Letters from Armie');\r\n  // Hidden and inert until the inbox has loaded and the player owns at least one letter:\r\n  // never a greyed-out, half-loaded button.\r\n  setArmieLauncherOwned(launcher, false);\r\n  const dialog = document.createElement('dialog');\r\n  dialog.className = 'armie-inbox-dialog';\r\n  root.append(launcher, dialog);\r\n\r\n  const store = await armieInbox();\r\n\r\n  async function refreshBadge() {\r\n   const [owned, unread] = await Promise.all([store.hasAnyLetterEver(), store.unreadCount()]);\r\n   launcher.dataset.unread = String(unread);\r\n   launcher.textContent = unread ? `✉ ${unread}` : '✉';\r\n   setArmieLauncherOwned(launcher, owned);\r\n   if (!owned && dialog.open) dialog.close();\r\n  }\r\n\r\n  async function render() {\r\n   const letters = await store.listLetters();\r\n   const showNotice = isIosBrowserTab() && !(await store.hasSeenIosNotice());\r\n   // D23: the permission ask exists only once a letter does, and runs from this tap.\r\n   const offerPush = letters.length > 0 && canOfferArmiePush();\r\n   dialog.innerHTML = `<header><strong>Armie</strong><button type=\"button\" data-close aria-label=\"Close\">×</button></header>`\r\n    + (showNotice ? `<p class=\"armie-inbox-notice\" data-ios-notice>On iPhone, add Coach to your Home Screen (Share → Add to Home Screen) to get these as notifications.</p>` : '')\r\n    + (offerPush ? `<p class=\"armie-inbox-notice\"><button type=\"button\" data-push>Get Armie's letters as notifications</button></p>` : '')\r\n    + `<ul>${letters.length ? letters.map(l => `<li data-read=\"${l.read}\" data-id=\"${l.id}\"><strong>${l.header}</strong>${l.lines.map(line => `<p>${line}</p>`).join('')}</li>`).join('') : '<li>No letters yet.</li>'}</ul>`;\r\n   dialog.querySelector('[data-close]').addEventListener('click', () => dialog.close());\r\n   if (showNotice) void store.markIosNoticeSeen(); // shown once, never again\r\n   dialog.querySelector('[data-push]')?.addEventListener('click', event => { event.currentTarget.parentElement.remove(); void maybeRequestArmiePushPermission(); }, {once: true});\r\n   for (const li of dialog.querySelectorAll('li[data-id]')) {\r\n    li.addEventListener('click', async () => { await store.markRead(li.dataset.id); void import('./modules/vault/vault-store.mjs').then(m=>m.bump('armie-read')).catch(()=>{}); li.dataset.read = '1'; await refreshBadge(); }, {once: true});\r\n   }\r\n  }\r\n\r\n  launcher.addEventListener('click', async () => { if (launcher.hidden || launcher.inert) return; await render(); dialog.showModal(); await refreshBadge(); const now=Date.now(),day24h=24*60*60000;const letters=await store.listLetters();for(const l of letters){if(l.read===0&&now-l.firedAt>day24h)void import('./modules/vault/vault-store.mjs').then(m=>m.bump('armie-ignored',1,{key:l.letterId})).catch(()=>{});} });\r\n  window.addEventListener('myr5:armie-inbox-updated', () => void refreshBadge());\r\n  await refreshBadge();\r\n  return {launcher, dialog};\r\n })();\r\n}\r\n","armie-inbox.mjs":"// The in-app inbox for Armie letters (D23): persisted, readable offline, and\r\n// the source of truth -- a push notification is only ever a nudge to look\r\n// here, never the only place a letter lives. Namespaced DB name so it never\r\n// collides with the unrelated \"armie\" onboarding stage (see armie-letters.mjs).\r\nimport Dexie from 'dexie';\r\n\r\nexport const ARMIE_INBOX_DB = 'myr5-armie-letters-v1';\r\nexport const ARMIE_INBOX_SCHEMA_VERSION = 1;\r\n\r\n// One row per fired letter, id `letter:<date>:<letterId>` so repeated\r\n// delivery (a reopen catch-up, a retried push) is an idempotent upsert\r\n// instead of a duplicate.\r\nexport const armieLetterId = (date, letterId) => `letter:${date}:${letterId}`;\r\n\r\nexport async function openArmieInbox({name = ARMIE_INBOX_DB, indexedDB = globalThis.indexedDB, IDBKeyRange = globalThis.IDBKeyRange} = {}) {\r\n const db = new Dexie(name, {indexedDB, IDBKeyRange});\r\n db.version(ARMIE_INBOX_SCHEMA_VERSION).stores({\r\n  letters: '&id,date,read,firedAt',\r\n  meta: '&key',\r\n });\r\n await db.open();\r\n\r\n return {\r\n  close() { db.close({disableAutoOpen: true}); },\r\n  // Idempotent: existing rows are left untouched so a re-delivered letter\r\n  // never resets `read` back to unread or duplicates itself.\r\n  async addLetters(letters, {now = () => Date.now()} = {}) {\r\n   const added = [];\r\n   await db.transaction('rw', db.letters, async () => {\r\n    for (const {date, letterId, header, lines} of letters) {\r\n     const id = armieLetterId(date, letterId);\r\n     if (await db.letters.get(id)) continue;\r\n     // `read` is stored 0/1, not boolean: IndexedDB key ranges (used by the\r\n     // `read` index below) don't accept booleans as a valid key type.\r\n     const row = {id, date, letterId, header, lines, firedAt: now(), read: 0};\r\n     await db.letters.add(row);\r\n     added.push(row);\r\n    }\r\n   });\r\n   return added;\r\n  },\r\n  async listLetters() {\r\n   return (await db.letters.toArray()).sort((a, b) => b.date.localeCompare(a.date) || b.firedAt - a.firedAt);\r\n  },\r\n  async unreadCount() {\r\n   return db.letters.where('read').equals(0).count();\r\n  },\r\n  async markRead(id) {\r\n   await db.letters.update(id, {read: 1});\r\n  },\r\n  async markAllRead() {\r\n   await db.letters.where('read').equals(0).modify({read: 1});\r\n  },\r\n  // D23: \"explain the iOS home-screen requirement once in the inbox, no\r\n  // nagging\" -- one flag, checked and set once by the inbox UI.\r\n  async hasSeenIosNotice() {\r\n   return !!(await db.meta.get('ios-home-screen-notice-seen'));\r\n  },\r\n  async markIosNoticeSeen() {\r\n   await db.meta.put({key: 'ios-home-screen-notice-seen', value: true});\r\n  },\r\n  // D23: \"ask for notification permission only after the first letter\r\n  // exists\" -- checked by the one caller that requests permission.\r\n  async hasAnyLetterEver() {\r\n   return (await db.letters.count()) > 0;\r\n  },\r\n };\r\n}\r\n","armie-letters-client.mjs":"// Client glue for D12 Armie letters. Turns the `pendingLetters` that\r\n// server/combat.mjs attaches to the existing 'myr5:account-progress' event\r\n// into inbox rows. Self-initializing: importing this module (armie-inbox-ui.mjs\r\n// does, from app.mjs) is the whole integration; it adds its own independent\r\n// event listener rather than touching pod.mjs's dense render loop.\r\nimport {openArmieInbox} from './armie-inbox.mjs';\r\nimport {pickArmieLetter} from './armie-letters.mjs';\r\nimport {armieNotifyBlocked} from './armie-notify-gate.mjs';\r\nimport {authFetch} from './auth-client.mjs';\r\nimport {subscribePush} from './push-subscribe.mjs';\r\n\r\nexport const PUSH_PROMPTED_KEY = 'myr5-armie-push-prompted-v1';\r\n\r\nlet inboxPromise = null;\r\nexport const armieInbox = () => inboxPromise ??= openArmieInbox().catch(error => {inboxPromise = null; throw error;});\r\n\r\n// D23: offer is shown only inside the inbox once a letter exists (never on\r\n// first launch), and only until tapped once.\r\nexport function canOfferArmiePush() {\r\n try {\r\n  return 'Notification' in window && 'PushManager' in window && 'serviceWorker' in navigator\r\n   && Notification.permission === 'default' && !localStorage.getItem(PUSH_PROMPTED_KEY);\r\n } catch { return false; }\r\n}\r\n\r\n// Same subscribe steps as the settings-screen notification switch\r\n// (launch.mjs). Must be called from a tap: Safari/iOS and Firefox only show\r\n// the permission prompt inside a user gesture, so requestPermission() runs\r\n// first, before any await.\r\nexport async function maybeRequestArmiePushPermission() {\r\n try {\r\n  if (!canOfferArmiePush()) return false;\r\n  localStorage.setItem(PUSH_PROMPTED_KEY, '1'); // ask once, ever -- D23 says never nag\r\n  if (await Notification.requestPermission() !== 'granted') return false;\r\n  const accountResponse = await authFetch('/api/account');\r\n  if (!accountResponse.ok) return false;\r\n  const account = await accountResponse.json();\r\n  if (!account?.push?.configured || account.push.environment === 'preview') return false;\r\n  const registration = await navigator.serviceWorker.ready;\r\n  const {subscription: sub} = await subscribePush(registration, account.push.publicKey);\r\n  await authFetch('/api/push/subscribe', {method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify(sub.toJSON())});\r\n  return true;\r\n } catch { return false; } // best-effort; the inbox already has the letter either way\r\n}\r\n\r\nexport async function handleArmieProgress(pendingLetters) {\r\n if (!pendingLetters?.length) return [];\r\n const store = await armieInbox();\r\n const letters = pendingLetters.map(({date, id}) => {\r\n  const picked = pickArmieLetter(id, date);\r\n  return picked && {date, ...picked};\r\n }).filter(Boolean);\r\n const added = await store.addLetters(letters);\r\n if (added.length) window.dispatchEvent(new CustomEvent('myr5:armie-inbox-updated', {detail: {added, blocked: armieNotifyBlocked()}}));\r\n return added;\r\n}\r\n\r\nif (typeof window !== 'undefined') window.addEventListener('myr5:account-progress', event => void handleArmieProgress(event.detail?.combat?.pendingLetters));\r\n\r\n// D23: \"a push arriving mid-workout is held until the set ends.\" sw.js asks\r\n// this window (ARMIE_NOTIFY_CHECK); if busy it hands the payload over\r\n// (ARMIE_LETTER_HELD) and this page shows it once camera-only mode and the set\r\n// are both over. ponytail: held in memory only -- if the page closes first the\r\n// OS toast is dropped, but the letter itself is still in the inbox.\r\nconst held = [];\r\nconst showHeld = async letter => (await navigator.serviceWorker.ready).showNotification(String(letter.title).slice(0, 80), {body: String(letter.body).slice(0, 200), icon: '/icons/myr5-alien-192.png', badge: '/icons/myr5-alien-192.png', tag: letter.tag, data: {url: letter.url, kind: letter.kind}});\r\nexport async function flushHeldArmiePushes(show = showHeld) {\r\n if (armieNotifyBlocked() || !held.length) return 0;\r\n const letters = held.splice(0);\r\n for (const letter of letters) await show(letter);\r\n return letters.length;\r\n}\r\nexport function holdArmiePush(letter, show) { held.push(letter); return flushHeldArmiePushes(show); }\r\n\r\nif (typeof navigator !== 'undefined' && 'serviceWorker' in navigator) {\r\n navigator.serviceWorker.addEventListener('message', event => {\r\n  if (event.data?.type === 'ARMIE_NOTIFY_CHECK') event.ports[0]?.postMessage({blocked: armieNotifyBlocked()});\r\n  else if (event.data?.type === 'ARMIE_LETTER_HELD') void holdArmiePush(event.data.letter).catch(() => {});\r\n });\r\n new MutationObserver(() => void flushHeldArmiePushes().catch(() => {})).observe(document.body, {attributes: true, attributeFilter: ['data-tracking', 'data-camera-workout']});\r\n}\r\n","armie-letters.mjs":"// Copy for the D12 patch-note-style letters (DECISIONS.md D12 letter table).\r\n// Content transcribed from plan/muse/armie-letters.json (Muse package,\r\n// reviewed 22 Sept 2026 -- see plan/muse/REVIEW-NOTES.md).\r\n//\r\n// NAMING: \"Armie\"/\"armie\" already exists in shipped code as the last stage of\r\n// the Coach Army onboarding run (server/coach-army-runs.mjs COACH_ARMY_STAGES,\r\n// onboarding-domain.mjs v.armieCompleted, war-room/war-room.mjs). That is an\r\n// unrelated onboarding checkpoint -- do not touch it. Everything here is its\r\n// own, separately namespaced feature: `armieLetters`, `pickArmieLetter`,\r\n// DB name `myr5-armie-letters-v1`, inbox ids `letter:<date>:<letterId>`.\r\n\r\nexport const armieLetters = {\r\n 'forgive-1': [\r\n  {header: 'Armie v1.0.1', lines: ['Miss logged. Armie patched it.', 'Streak intact. That is week one.', 'Three weeks in a row. Then Armie stops.']},\r\n  {header: 'Patch 1.0.1', lines: ['You missed. Armie covered.', 'One week patched. Two remain.', 'Three in a row is all.']},\r\n  {header: 'Armie v1.0.2', lines: ['Armie saw the gap. Armie closed it.', 'Count: one week of fixing.', 'Three is the limit. Armie counts.']},\r\n ],\r\n 'forgive-2': [\r\n  {header: 'Armie v1.0.2', lines: ['Second miss. Second patch.', 'Two weeks fixed in a row.', 'One week left. Then misses break it.']},\r\n  {header: 'Patch 1.0.3', lines: ['Armie fixed it again.', 'That is two. Armie remembers.', 'One more. That is all.']},\r\n  {header: 'Armie v1.1.0', lines: ['Miss found. Patch applied.', 'Two in a row. Armie is watching.', 'One more week. Then Armie stops.']},\r\n ],\r\n 'forgive-3-limit': [\r\n  {header: 'Armie v1.0.3', lines: ['Third patch applied. Last one.', 'Three weeks of fixing. Done.', 'Next miss breaks the streak. Armie will not stop it.']},\r\n  {header: 'Patch 1.0.4', lines: ['Armie fixed the third week.', 'Three weeks in a row. That was three.', 'Miss again and the count ends.']},\r\n  {header: 'Armie v1.1.1', lines: ['Final patch installed.', 'Three in a row. Armie stops here.', 'One more miss breaks everything.']},\r\n ],\r\n 'forgive-off-warning': [\r\n  {header: 'Armie v1.1.0', lines: ['Three weeks patched. Limit reached.', 'Forgiveness is now OFF.', 'One clean week turns it back on.']},\r\n  {header: 'Patch 1.1.0', lines: ['Armie has fixed three weeks.', 'No more patches until a full clean week.', 'Miss now and the streak breaks.']},\r\n  {header: 'Armie v1.1.2', lines: ['Week three patched. Armie rests.', 'Fixing paused. A clean week resumes it.', 'Until then, every day counts.']},\r\n ],\r\n 'streak-broken-after-limit': [\r\n  {header: 'Armie v1.2.0', lines: ['The streak broke.', 'Armie had fixed three weeks. The limit.', 'Armie could not patch this one.']},\r\n  {header: 'Patch 1.2.0', lines: ['Miss logged. Streak reset.', 'Three weeks was the deal.', 'Armie kept its side. The streak starts over.']},\r\n  {header: 'Armie v1.2.1', lines: ['Break detected. Count is zero.', 'The three-week cover is spent.', 'The next kept day is day one.']},\r\n ],\r\n 'streak-broken': [\r\n  {header: 'Armie v1.2.0', lines: ['Two misses in one week.', 'Armie patches one. Not two.', 'Streak reset. Armie is not sorry.']},\r\n  {header: 'Patch 1.2.1', lines: ['The streak broke.', 'One miss a week is the rule.', 'This week had more. Count is zero.']},\r\n  {header: 'Armie v1.3.0', lines: ['Break logged.', 'Armie fixes one miss per week.', 'The second one stands. Streak over.']},\r\n ],\r\n 'forgive-restored': [\r\n  {header: 'Armie v1.3.0', lines: ['A full week. No patches needed.', 'Forgiveness restored.', 'Armie is ready again. Try not to need it.']},\r\n  {header: 'Patch 1.3.0', lines: ['Seven clean days.', 'The counter is back to zero.', 'One miss a week, three weeks running. As before.']},\r\n  {header: 'Armie v1.3.1', lines: ['Clean week confirmed.', 'Armie reset the forgiveness.', 'Three weeks of cover, reloaded.']},\r\n ],\r\n 'milestone-5': [\r\n  {header: 'Armie v2.0.0', lines: ['Five days. Still here.', 'Armie noticed. Armie approves.', 'Keep going. Armie is watching.']},\r\n  {header: 'Patch 2.0.0', lines: ['Streak: five.', 'Small number. Real work.', 'Armie logged it in permanent ink.']},\r\n  {header: 'Armie v2.0.1', lines: ['Five in a row.', 'Armie did the math twice.', 'It checks out. Nice.']},\r\n ],\r\n 'milestone-10': [\r\n  {header: 'Armie v2.1.0', lines: ['Ten days straight.', 'Double digits. Armie nods.', 'The streak has legs now.']},\r\n  {header: 'Patch 2.1.0', lines: ['Streak: ten.', 'Armie ran out of small words.', 'Big ones: keep going.']},\r\n  {header: 'Armie v2.1.1', lines: ['Ten days. The streak holds.', 'Armie checked. Twice.', 'Still standing. Good.']},\r\n ],\r\n 'milestone-15': [\r\n  {header: 'Armie v2.2.0', lines: ['Fifteen.', 'Armie is impressed. Armie hides it.', 'The streak is a habit now.']},\r\n  {header: 'Patch 2.2.0', lines: ['Streak: fifteen.', 'Three fives. Armie counted.', 'Do not stop. Armie means it.']},\r\n  {header: 'Armie v2.2.1', lines: ['Fifteen days straight.', 'Armie updated the plaque.', 'Your name is on it. Keep it there.']},\r\n ],\r\n};\r\n\r\n// Deterministic so the same (date, letterId) always resolves to the same\r\n// copy -- callers may see the same fired letter more than once (a reopen\r\n// catch-up, a retried push) and must render identical content each time.\r\nfunction seedIndex(seed, length) {\r\n let hash = 0;\r\n for (let i = 0; i < seed.length; i++) hash = (hash * 31 + seed.charCodeAt(i)) >>> 0;\r\n return hash % length;\r\n}\r\n\r\n// Picks one variant's copy for a fired D12 letter id. Returns null for an\r\n// unknown id instead of throwing, since letter ids ultimately come from the\r\n// streak evaluator and a caller should never crash the inbox over one.\r\nexport function pickArmieLetter(letterId, seed = letterId) {\r\n const variants = armieLetters[letterId];\r\n if (!variants || !variants.length) return null;\r\n const variant = variants[seedIndex(String(seed), variants.length)];\r\n return {letterId, header: variant.header, lines: variant.lines};\r\n}\r\n","armie-notify-gate.mjs":"// Whether it is OK to surface an Armie letter right now (an in-app toast, or\r\n// answering the service worker's \"can I show this push?\" check). Reads flags\r\n// that camera-workout.mjs and app.mjs already set on document.body -- no\r\n// edits to either file, this just observes them:\r\n//   dataset.cameraWorkout === 'true'  while the camera-only stage is up\r\n//   dataset.tracking === 'true'       while a set is actively being tracked\r\n// D23: \"nothing appears during camera-only mode; a push arriving mid-workout\r\n// is held until the set ends.\"\r\nexport function armieNotifyBlocked(doc = typeof document !== 'undefined' ? document : null) {\r\n const flags = doc?.body?.dataset;\r\n return !!flags && (flags.cameraWorkout === 'true' || flags.tracking === 'true');\r\n}\r\n","audio/loop-seam.mjs":"// Makes a decoded ambient clip loop without a gap. Encoded clips often carry silence or a fade at each end\r\n// (the waterfall had 0.6 s of silence in front and a fade-out behind), so looping them leaves a dip every pass.\r\n// The steady body is kept and its end is blended into its start with an equal-power crossfade: after the last\r\n// sample the loop continues with the sample that followed the blended start, so there is no click or dip.\r\nconst BLOCK=.01;\r\nexport function seamlessLoopChannels(channels,rate,{crossfade=.5,margin=.05}={}){\r\n  const n=channels[0].length,block=Math.max(1,Math.round(rate*BLOCK)),count=Math.floor(n/block);\r\n  if(count<8)return channels;\r\n  const rms=Array.from({length:count},(_,b)=>{let s=0;for(const ch of channels)for(let i=b*block;i<(b+1)*block;i++)s+=ch[i]*ch[i];return Math.sqrt(s/(block*channels.length));});\r\n  const median=[...rms].sort((a,b)=>a-b)[count>>1],floor=median*.8;\r\n  let first=0,last=count-1;\r\n  while(first<count&&rms[first]<floor)first++;\r\n  while(last>first&&rms[last]<floor)last--;\r\n  // Step in past the edge ramps (an end that fades measures high until its last blocks).\r\n  const pad=Math.round(rate*margin);\r\n  const ramp=Math.round(rate*.3),start=first*block+pad+ramp,end=(last+1)*block-pad-ramp;\r\n  const body=end-start;\r\n  const fade=Math.min(Math.round(rate*crossfade),Math.floor(body/3));\r\n  if(fade<=0||body<fade*3)return channels;\r\n  const length=body-fade;\r\n  return channels.map(ch=>{\r\n    const out=new Float32Array(length);\r\n    for(let i=0;i<length;i++)out[i]=ch[start+i];\r\n    for(let i=0;i<fade;i++){const t=(i+.5)/fade*Math.PI/2;out[i]=ch[start+i]*Math.sin(t)+ch[start+length+i]*Math.cos(t);}\r\n    return out;\r\n  });\r\n}\r\nexport function seamlessLoopBuffer(context,buffer,options){\r\n  const channels=Array.from({length:buffer.numberOfChannels},(_,c)=>buffer.getChannelData(c));\r\n  const next=seamlessLoopChannels(channels,buffer.sampleRate,options);\r\n  if(next===channels)return buffer;\r\n  const out=context.createBuffer(next.length,next[0].length,buffer.sampleRate);\r\n  next.forEach((data,c)=>out.copyToChannel(data,c));\r\n  return out;\r\n}\r\n","audio/music/manifest.json":"{\r\n \"version\": 1,\r\n \"sampleRate\": 44100,\r\n \"bars\": 8,\r\n \"tracks\": {\r\n  \"hey-man-idk\": {\r\n   \"url\": \"/audio/music/hey-man-idk.m4a\",\r\n   \"bpm\": 188.43,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 449348,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 10.189297,\r\n   \"duration\": 10.189297,\r\n   \"sourceStart\": 0.585,\r\n   \"tailFolded\": 0.04,\r\n   \"bytes\": 145363,\r\n   \"decodedFrames\": 449348\r\n  },\r\n  \"guarded-gate\": {\r\n   \"url\": \"/audio/music/guarded-gate.m4a\",\r\n   \"bpm\": 121.3,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 698032,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 15.82839,\r\n   \"duration\": 15.82839,\r\n   \"sourceStart\": 0.075,\r\n   \"tailFolded\": 0.04,\r\n   \"bytes\": 226826,\r\n   \"decodedFrames\": 698032\r\n  },\r\n  \"daemon-time\": {\r\n   \"url\": \"/audio/music/daemon-time.m4a\",\r\n   \"bpm\": 90.16,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 939140,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 21.295692,\r\n   \"duration\": 21.295692,\r\n   \"sourceStart\": 0.64,\r\n   \"tailFolded\": 0.06,\r\n   \"bytes\": 310247,\r\n   \"decodedFrames\": 939140\r\n  },\r\n  \"sick-with-science\": {\r\n   \"url\": \"/audio/music/sick-with-science.m4a\",\r\n   \"bpm\": 140.5,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 602648,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 13.665488,\r\n   \"duration\": 13.665488,\r\n   \"sourceStart\": 0.02,\r\n   \"tailFolded\": 0.212,\r\n   \"bytes\": 194523,\r\n   \"decodedFrames\": 602648\r\n  },\r\n  \"laboratory-violence\": {\r\n   \"url\": \"/audio/music/laboratory-violence.m4a\",\r\n   \"bpm\": 120.0,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 705600,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 16.0,\r\n   \"duration\": 16.0,\r\n   \"sourceStart\": 0.01,\r\n   \"tailFolded\": 0.511,\r\n   \"bytes\": 229213,\r\n   \"decodedFrames\": 705600\r\n  },\r\n  \"main-theme-one\": {\r\n   \"url\": \"/audio/music/main-theme-one.m4a\",\r\n   \"bpm\": 120.0,\r\n   \"bars\": 8,\r\n   \"beats\": 32,\r\n   \"frames\": 705600,\r\n   \"loopStart\": 0,\r\n   \"loopEnd\": 16.0,\r\n   \"duration\": 16.0,\r\n   \"sourceStart\": 2.02,\r\n   \"tailFolded\": 0.06,\r\n   \"bytes\": 240960,\r\n   \"decodedFrames\": 705600\r\n  }\r\n }\r\n}","audio/page-music.mjs":"// Page music: one looping song per scene, started on the first gesture, obeying the SOUND toggle and saved mute.\r\n// A track change fades the new song in (3 s; the grimoire theme 5 s up to 35%) while a stronger wormhole-transit bed\r\n// (transit + boom + whoosh + the grimoire board sounds at 50%) fades out. Suspends when hidden; ducks under the coach voice.\r\n// Loops come from audio/music (scripts/music-loops.py): exactly 8 bars, loopStart 0 / loopEnd = duration, no encoder padding left.\r\nimport {physicalSound} from './physical-sound.mjs';\r\n\r\nexport const ROUTE_TRACK={pod:'main-theme-one',workout:null,select:null,battlepass:'hey-man-idk',achievements:'guarded-gate',vault:'guarded-gate',\r\n customize:'daemon-time',customizeCoach:'daemon-time','war-room':'daemon-time',food:'sick-with-science',portal:null,settings:'main-theme-one',scoreboard:'laboratory-violence',meditate:null};\r\nexport const TRACK_LEVEL={'main-theme-one':.35};\r\nexport const TRACK_FADE={'main-theme-one':5};\r\nexport const FADE_IN=3,FADE_OUT=1.2,DUCK_LEVEL=.3,DUCK_DOWN=.12,DUCK_UP=1.2;\r\n// The pod and its menus share the grimoire song; hey-man-idk is only the XP Flight (battle pass) screen; workout/select stay silent (camera / pickers).\r\n// Pod + menus share the grimoire song; hey-man-idk is XP Flight (battle pass) only; workout/select are silent.\r\n// Track for a scene. undefined = keep whatever plays (history, install...), null = silence (workout camera, meditation).\r\nexport function trackForRoute(id,{portalUp=false,quiet=false,pathname='',scene=null,hold=false}={}){\r\n if(quiet||hold)return null; // hold = a portal trace/tunnel is running: only the bed/sfx sound\r\n if(scene==='battlepass')return 'hey-man-idk'; // XP Flight dialog opens over any page\r\n if(/^\\/(?:creature|war-room)\\//.test(pathname))return 'daemon-time';\r\n if(!id)return portalUp?null:ROUTE_TRACK.pod; // the grimoire is silent\r\n return ROUTE_TRACK[id];\r\n}\r\n// Fade-in schedule for a track starting at t0 (gain 0 -> level).\r\nexport const rampPlan=(track,t0)=>{const dur=TRACK_FADE[track]??FADE_IN;return {from:0,to:TRACK_LEVEL[track]??1,start:t0,end:t0+dur};};\r\n// Loop position (s) of a looping source started at `startedAt` from `startOffset`, read at `now` (all AudioContext seconds).\r\nexport const loopPosition=({startOffset,startedAt,now,duration})=>(((startOffset+(now-startedAt))%duration)+duration)%duration;\r\n// Asymmetric duck: music falls fast when the coach speaks and climbs back slowly.\r\nexport const duckPlan=speaking=>speaking?{to:DUCK_LEVEL,seconds:DUCK_DOWN}:{to:1,seconds:DUCK_UP};\r\n\r\nconst BOARD_KINDS={quilt:['quilt'],ice:['ice'],jelly:['jelly'],water:['water','water-slosh'],pond:['water','water-slosh'],grass:['grass','grass-tinkle'],cogs:['cogs'],wood:['wood','wood-scrape','crackle']};\r\nconst MIX_KINDS=['ice','crackle','water'];\r\nconst BED_BOARD_GAIN=.5;\r\n\r\nexport function createPageMusic({sound=physicalSound,documentRef=globalThis.document,windowRef=globalThis.window,fetchRef=(...a)=>globalThis.fetch(...a),pathname=globalThis.location?.pathname||''}={}){\r\n let speaking=false,scene=null,hold=false,djActive=false,holdTimer=0,ctx=null,out=null,duck=null,armed=false,want=undefined,epoch=0,cur=null,cut=null,manifest=null,manifestP=null,noise=null,warned=false;\r\n const buffers=new Map(),log=[];\r\n const warn=e=>{if(!warned){warned=true;console.warn('page music:',e?.message||e);}};\r\n const note=(what,param,v0,v1,t0,t1)=>{log.push({what,v0,v1,t0,t1});if(log.length>60)log.shift();};\r\n function ramp(param,what,to,t0,seconds){\r\n  param.cancelScheduledValues(t0);param.setValueAtTime(param.value,t0);\r\n  if(seconds>0)param.linearRampToValueAtTime(to,t0+seconds);else param.setValueAtTime(to,t0);\r\n  note(what,param,param.value,to,t0,t0+seconds);\r\n }\r\n function ensure(){\r\n  if(ctx)return true;\r\n  sound.unlock?.();ctx=sound.context;if(!ctx)return false;\r\n  duck=ctx.createGain();out=ctx.createGain();duck.connect(out);out.connect(ctx.destination);level();return true;\r\n }\r\n const muted=()=>!!sound.muted;\r\n function level(){if(!out)return;out.gain.setTargetAtTime(muted()?0:1,ctx.currentTime,.03);}\r\n async function loadManifest(){\r\n  return manifestP??=(async()=>{const r=await fetchRef('/audio/music/manifest.json');if(!r.ok)throw Error('music manifest unavailable');manifest=await r.json();return manifest;})().catch(e=>{manifestP=null;throw e;});\r\n }\r\n async function decode(url){\r\n  if(!buffers.has(url))buffers.set(url,(async()=>{const r=await fetchRef(url);if(!r.ok)throw Error('unavailable '+url);return ctx.decodeAudioData(await r.arrayBuffer());})().catch(e=>{buffers.delete(url);throw e;}));\r\n  return buffers.get(url);\r\n }\r\n function noiseBuffer(){\r\n  if(noise)return noise;noise=ctx.createBuffer(1,ctx.sampleRate*3,ctx.sampleRate);const d=noise.getChannelData(0);let s=0x2f6e2b1;\r\n  for(let i=0;i<d.length;i++){s=(1664525*s+1013904223)>>>0;d[i]=s/2147483648-1;}return noise;\r\n }\r\n function stopSoon(nodes,seconds){setTimeout(()=>{for(const n of nodes){try{n.stop?.();}catch{}try{n.disconnect();}catch{}}},Math.ceil(seconds*1000)+80);}\r\n // ---- transition bed -------------------------------------------------------------------------------------------\r\n async function startBed(kinds,fade){\r\n  const t0=ctx.currentTime,bed=ctx.createGain(),comp=ctx.createDynamicsCompressor(),nodes=[bed,comp];\r\n  comp.threshold.value=-12;comp.ratio.value=5;bed.connect(comp);comp.connect(out);\r\n  bed.gain.setValueAtTime(1,t0);bed.gain.setValueAtTime(1,t0+.5);bed.gain.linearRampToValueAtTime(0,t0+fade);note('bed',bed.gain,1,0,t0+.5,t0+fade);\r\n  const add=n=>{nodes.push(n);return n;};\r\n  // low boom + whoosh make the existing transit sample feel stronger\r\n  const boom=add(ctx.createOscillator()),bg=add(ctx.createGain());boom.type='sine';boom.frequency.setValueAtTime(78,t0);boom.frequency.exponentialRampToValueAtTime(30,t0+1.6);\r\n  bg.gain.setValueAtTime(.0001,t0);bg.gain.exponentialRampToValueAtTime(.7,t0+.05);bg.gain.exponentialRampToValueAtTime(.0001,t0+2);boom.connect(bg).connect(bed);boom.start(t0);boom.stop(t0+2.1);\r\n  const wh=add(ctx.createBufferSource()),wf=add(ctx.createBiquadFilter()),wg=add(ctx.createGain());wh.buffer=noiseBuffer();wf.type='bandpass';wf.Q.value=.8;\r\n  wf.frequency.setValueAtTime(180,t0);wf.frequency.exponentialRampToValueAtTime(2600,t0+1);wf.frequency.exponentialRampToValueAtTime(260,t0+fade);\r\n  wg.gain.setValueAtTime(.0001,t0);wg.gain.exponentialRampToValueAtTime(.35,t0+.5);wg.gain.exponentialRampToValueAtTime(.0001,t0+fade);wh.connect(wf).connect(wg).connect(bed);wh.start(t0);wh.stop(t0+fade+.1);\r\n  stopSoon(nodes,fade+.2);\r\n  try{\r\n   const sfx=await sfxManifest();\r\n   const play=async(path,gain,at,rate=1)=>{const b=await decode(path);if(ctx.currentTime>t0+fade)return;const s=add(ctx.createBufferSource()),g=add(ctx.createGain());s.buffer=b;s.playbackRate.value=rate;g.gain.value=gain;s.connect(g).connect(bed);s.start(Math.max(ctx.currentTime,t0+at));};\r\n   const transit=sfx.cues?.transit?.[0];\r\n   if(transit)await play(transit,1.5,0,.85);\r\n   let at=.1;\r\n   for(const kind of kinds){\r\n    if(kind==='crackle'){crackle(bed,t0,Math.min(fade,2.6),add);continue;}\r\n    const list=sfx.cues?.[kind];if(!list?.length)continue;\r\n    for(let i=0;i<3;i++){await play(list[(i)%list.length],BED_BOARD_GAIN,at+i*.7,.94+Math.random()*.12);}\r\n    at+=.35;\r\n   }\r\n  }catch(e){warn(e);}\r\n }\r\n function crackle(bed,t0,seconds,add){\r\n  const g=add(ctx.createGain());g.gain.value=BED_BOARD_GAIN;g.connect(bed);\r\n  for(let i=0;i<26;i++){\r\n   const at=t0+Math.random()*seconds,s=add(ctx.createBufferSource()),f=add(ctx.createBiquadFilter()),e=add(ctx.createGain());\r\n   s.buffer=noiseBuffer();f.type='highpass';f.frequency.value=900+Math.random()*2500;e.gain.setValueAtTime(.0001,at);e.gain.exponentialRampToValueAtTime(.2+Math.random()*.3,at+.003);e.gain.exponentialRampToValueAtTime(.0001,at+.03+Math.random()*.05);\r\n   s.connect(f).connect(e).connect(g);s.start(at,Math.random()*2);s.stop(at+.1);\r\n  }\r\n }\r\n let sfxP=null;\r\n const sfxManifest=()=>sfxP??=fetchRef('/audio/sfx/manifest.json').then(r=>r.json()).then(m=>({cues:m.cues})).catch(e=>{sfxP=null;throw e;});\r\n function bedKinds(prev){return prev==='main-theme-one'?BOARD_KINDS[sound.board]||BOARD_KINDS.quilt:MIX_KINDS;}\r\n // ---- tracks --------------------------------------------------------------------------------------------------\r\n function startSource(buffer,m,offset,gainValue,fadeSeconds){\r\n  const g=ctx.createGain(),s=ctx.createBufferSource(),t=ctx.currentTime;\r\n  s.buffer=buffer;s.loop=true;s.loopStart=m.loopStart||0;s.loopEnd=m.loopEnd||buffer.duration;s.connect(g).connect(duck);\r\n  g.gain.setValueAtTime(fadeSeconds?0:gainValue,t);if(fadeSeconds){g.gain.linearRampToValueAtTime(gainValue,t+fadeSeconds);note('fade-in',g.gain,0,gainValue,t,t+fadeSeconds);}\r\n  s.start(t,offset);return {source:s,gain:g,startedAt:t,startOffset:offset};\r\n }\r\n function fadeOut(entry,seconds){\r\n  const t=ctx.currentTime,g=entry.gain.gain;g.cancelScheduledValues(t);g.setValueAtTime(g.value,t);g.linearRampToValueAtTime(0,t+seconds);note('fade-out',g,g.value,0,t,t+seconds);\r\n  stopSoon([entry.source,entry.gain],seconds);\r\n }\r\n async function play(name){\r\n  const mine=++epoch,prev=cur;\r\n  try{\r\n   const m=(await loadManifest()).tracks[name];if(!m)throw Error('unknown track '+name);\r\n   const buffer=await decode(m.url);\r\n   if(mine!==epoch||!ctx)return;\r\n   const plan=rampPlan(name,ctx.currentTime),dur=plan.end-plan.start;\r\n   const entry=startSource(buffer,m,0,plan.to,dur);\r\n   Object.assign(entry,{name,m,buffer,level:plan.to});cur=entry;cut=null;\r\n   if(prev){fadeOut(prev,FADE_OUT);}\r\n   void startBed(bedKinds(prev?.name),dur);\r\n  }catch(e){warn(e);}\r\n }\r\n function setTrack(name){\r\n  want=name;\r\n  if(!armed||name===undefined)return;\r\n  if(name===null){epoch++;if(cur&&ctx){fadeOut(cur,1);cur=null;cut=null;}return;}\r\n  if(!ensure())return;\r\n  if((cur?.name===name&&!cut)||cut?.name===name){epoch++;return;} // already the song: drop any pending change\r\n  if(ctx.state==='suspended'&&!documentRef?.hidden&&!muted())void ctx.resume();\r\n  void play(name);\r\n }\r\n // ---- classroom cut / resume ----------------------------------------------------------------------------------\r\n // Hard stop mid-bar (no fade) and later restart from the exact loop position it stopped at.\r\n function cutNow(){\r\n  if(!cur||cut||!ctx)return false;\r\n  const offset=loopPosition({startOffset:cur.startOffset,startedAt:cur.startedAt,now:ctx.currentTime,duration:cur.m.loopEnd-(cur.m.loopStart||0)});\r\n  try{cur.source.stop();cur.source.disconnect();}catch{}\r\n  cut={name:cur.name,offset,m:cur.m,buffer:cur.buffer,level:cur.level};cur=null;return cut.offset;\r\n }\r\n function resumeNow(){\r\n  if(!cut||!ctx)return false;\r\n  const {name,m,buffer,level:l,offset}=cut;cut=null;\r\n  const entry=startSource(buffer,m,offset,l,0);Object.assign(entry,{name,m,buffer,level:l});cur=entry;return offset;\r\n }\r\n // ---- environment ---------------------------------------------------------------------------------------------\r\n const quiet=()=>{const d=documentRef?.body?.dataset||{};return d.tracking==='true'||d.cameraWorkout==='true';};\r\n function sync(){\r\n  const id=windowRef?.myr5Routes?.current?.()||'',portalUp=documentRef?.getElementById?.('portalHome')?.hidden===false;\r\n  const t=djActive?null:trackForRoute(id,{portalUp,quiet:quiet(),pathname,scene,hold});\r\n  if(t!==undefined)setTrack(t);\r\n }\r\n const unlock=()=>{if(armed)return;armed=true;documentRef.removeEventListener('pointerdown',unlock,true);documentRef.removeEventListener('keydown',unlock,true);ensure();sync();if(want!==undefined)setTrack(want);};\r\n function mount(){\r\n  if(!documentRef||windowRef.parent!==windowRef)return api; // a framed page leaves the music to its parent\r\n  documentRef.addEventListener('pointerdown',unlock,true);documentRef.addEventListener('keydown',unlock,true);\r\n  documentRef.addEventListener('visibilitychange',()=>{if(!ctx)return;if(documentRef.hidden)void ctx.suspend();else if(!muted())void ctx.resume();});\r\n  windowRef.addEventListener('myr5:sound-settings',()=>{level();if(!muted()&&ctx?.state==='suspended'&&!documentRef.hidden)void ctx.resume();});\r\n  windowRef.addEventListener('myr5:response',e=>{speaking=e.detail?.state==='speaking';if(!duck)return;const p=duckPlan(speaking);ramp(duck.gain,'duck',p.to,ctx.currentTime,p.seconds);});\r\n  windowRef.addEventListener('myr5:sfx-duck',e=>{if(!duck)return;const d=e.detail||{},t=ctx.currentTime;ramp(duck.gain,'duck',d.to??.5,t,d.seconds??.05);setTimeout(()=>{if(duck)ramp(duck.gain,'duck',duckPlan(speaking).to,ctx.currentTime,d.release??.35);},Math.ceil((d.seconds??.05)*1000));}); // explosions pop out of the music\r\n  windowRef.addEventListener('myr5:route',sync);\r\n  windowRef.addEventListener('myr5:music-scene',e=>{scene=e.detail?.scene||null;sync();});\r\n  windowRef.addEventListener('myr5:dj-active',e=>{djActive=!!e.detail?.active;sync();});\r\n  // portal.mjs holds the music for the whole trace + tunnel and releases it once the destination is shown (15 s safety).\r\n  windowRef.addEventListener('myr5:music-hold',e=>{hold=!!e.detail?.hold;clearTimeout(holdTimer);if(hold)holdTimer=setTimeout(()=>{hold=false;sync();},15000);sync();});\r\n  windowRef.addEventListener('myr5:music-cut',()=>cutNow());\r\n  windowRef.addEventListener('myr5:music-resume',()=>resumeNow());\r\n  new MutationObserver(sync).observe(documentRef.body||documentRef.documentElement,{attributes:true,attributeFilter:['data-tracking','data-camera-workout']});\r\n  sync();return api;\r\n }\r\n const api={mount,setTrack,cut:cutNow,resume:resumeNow,sync,log,current:()=>cur?.name||null,state:()=>({armed,want,playing:cur?.name||null,cut:cut&&{...cut,buffer:undefined,m:undefined},ctx:ctx&&ctx.state,muted:muted()}),unlock};\r\n return api;\r\n}\r\nexport const pageMusic=createPageMusic();\r\nexport function mountPageMusic(){const m=pageMusic.mount();if(globalThis.window)globalThis.window.myr5Music=m;return m;}\r\n","audio/physical-sound.mjs":"// Small, gesture-unlocked sound layer shared by the pod, grimoire, and rooms.\r\n// Samples are optional: every cue has a local Web Audio fallback for offline play.\r\nimport {seamlessLoopBuffer} from './loop-seam.mjs';\r\nexport const SOUND_PREF_KEY='myr5.physicalSound.v1';\r\nconst clamp=(n,a=0,b=1)=>Math.min(b,Math.max(a,n));\r\nconst RATE={'main-control':38,mechanical:38,switch:90,dial:45,lever:80,crt:65,ice:250,jelly:220,water:280,'water-slosh':900,'pond-slosh':1100,grass:300,'grass-tinkle':1200,cogs:180,wood:250,'wood-scrape':300,quilt:220,drag:160,transit:800,dialup:1800,'electric':110,bloop:160,'signal':250,'whiteboard':450,'gun-arm':120,'gun-shot':80,blast:60,'blast-big':90,'barrel-split':80};\r\nconst GROUP={'main-control':'mechanical',water:'water','water-slosh':'water','pond-slosh':'water',wood:'wood','wood-scrape':'wood','gun-arm':'gun-arm',grass:'grass','grass-tinkle':'tinkle'};\r\nconst SAMPLE={'main-control':'mechanical',mechanical:'mechanical-click',switch:'metal-switch',dial:'mechanical',lever:'switch',ice:'ice-crack',jelly:'jelly-squish',water:'water-splash','water-slosh':'water-slosh','pond-slosh':'water-slosh',grass:'grass-rustle','grass-tinkle':'grass-tinkle',cogs:'cogs-ratchet',wood:'wood-tap','wood-scrape':'wood-scrape',quilt:'cloth-rustle',transit:'portal-transit',dialup:'dialup',crt:'crt-tap','pod-hum':'pod-hum',breeze:'breeze',waterfall:'waterfall',electric:'electric',bloop:'bloop',signal:'signal',whiteboard:'whiteboard','gun-arm':'gun-arm','gun-shot':'gun-shot',blast:'blast','blast-big':'blast-big','barrel-split':'barrel-split'};\r\nconst LIMIT={blast:3,'blast-big':2,'gun-shot':3,'barrel-split':3}; // overlapping booms for a combo, the next steals the oldest\r\nconst safeStorage=()=>{try{return globalThis.localStorage;}catch{return null;}};\r\n\r\nexport function readSoundPrefs(storage=safeStorage()){\r\n try{const saved=JSON.parse(storage?.getItem(SOUND_PREF_KEY)||'{}');return {muted:saved.muted===true,volume:clamp(Number.isFinite(saved.volume)?saved.volume:.42)};}catch{return {muted:false,volume:.42};}\r\n}\r\n\r\nexport class PhysicalSound{\r\n constructor({AudioContextClass=globalThis.AudioContext||globalThis.webkitAudioContext,storage=safeStorage(),documentRef=globalThis.document,windowRef=globalThis.window,now=()=>performance.now()}={}){\r\n  this.AudioContextClass=AudioContextClass;this.storage=storage;this.document=documentRef;this.window=windowRef;\r\n  this.now=now;\r\n  this.prefs=readSoundPrefs(storage);this.context=null;this.voices=new Set();this.tails=new Set();this.last=new Map();this.scene='pod';this.board='quilt';this.ducked=false;this.ambience=null;this.epoch=0;\r\n  this.samples=new Map();this.sampleStatus=new Map();this.sampleRetry=new Map();this.manifest=null;this.manifestPending=null;this.manifestRetryAt=0;this.noise=null;this.started=false;\r\n }\r\n mount(){\r\n  if(this.started||!this.document)return this;this.started=true;this.abort=new AbortController();const signal=this.abort.signal;\r\n  const unlock=()=>this.unlock();\r\n  this.document.addEventListener('pointerdown',unlock,{capture:true,signal});this.document.addEventListener('keydown',unlock,{capture:true,signal});\r\n  this.document.addEventListener('visibilitychange',()=>{if(this.document.hidden)this.stopAll();else this.syncAmbience();},{signal});\r\n  this.window?.addEventListener('pagehide',()=>this.stopAll(),{signal});\r\n  this.window?.addEventListener('pageshow',()=>this.syncAmbience(),{signal});\r\n  this.window?.addEventListener('myr5:response',event=>{this.ducked=event.detail?.state==='speaking';this.syncLevel();},{signal});\r\n  this.window?.addEventListener('storage',event=>{if(event.key===SOUND_PREF_KEY){this.prefs=readSoundPrefs(this.storage);if(this.muted||!this.volume)this.stopAll();this.syncLevel();this.syncAmbience();this.emit();}},{signal});\r\n  if(globalThis.MutationObserver&&this.document?.documentElement){this.observer=new MutationObserver(()=>this.syncAmbience());this.observer.observe(this.document.documentElement,{subtree:true,attributes:true,attributeFilter:['open','hidden','data-screen','data-tracking','data-camera-workout','data-ship-view']});signal.addEventListener('abort',()=>this.observer.disconnect(),{once:true});}\r\n  return this;\r\n }\r\n get muted(){return this.prefs.muted;}\r\n get volume(){return this.prefs.volume;}\r\n setVolume(volume){this.prefs.volume=clamp(Number(volume)||0);this.save();}\r\n setMuted(muted){this.prefs.muted=!!muted;this.save();}\r\n save(){try{this.storage?.setItem(SOUND_PREF_KEY,JSON.stringify(this.prefs));}catch{}if(this.muted||!this.volume)this.stopAll();this.syncLevel();this.syncAmbience();this.emit();}\r\n emit(){this.window?.dispatchEvent(new CustomEvent('myr5:sound-settings',{detail:{...this.prefs}}));}\r\n unlock(){\r\n  if(!this.AudioContextClass)return false;\r\n  if(!this.context){\r\n   try{const c=this.context=new this.AudioContextClass();this.master=c.createGain();this.duck=c.createGain();this.duck.connect(this.master);this.master.connect(c.destination);this.syncLevel();}\r\n   catch{this.context=null;return false;}\r\n  }\r\n  if(!this.manifestPending&&Date.now()>=this.manifestRetryAt)void this.loadManifest();\r\n  if(this.context.state==='suspended')void this.context.resume().then(()=>this.syncAmbience()).catch(()=>{});\r\n  else this.syncAmbience();\r\n  return true;\r\n }\r\n syncLevel(){if(!this.context)return;const t=this.context.currentTime;this.master.gain.setTargetAtTime(this.muted?0:this.volume,t,.025);this.duck.gain.setTargetAtTime(this.ducked?.23:1,t,.08);}\r\n setScene(scene,board=this.board){if(scene!==this.scene||board!==this.board)this.epoch++;this.scene=scene;this.board=board;this.syncAmbience();}\r\n setBoard(board){if(board!==this.board)this.epoch++;this.board=board;this.syncAmbience();}\r\n noiseBuffer(){\r\n  if(this.noise)return this.noise;const c=this.context,b=this.noise=c.createBuffer(1,c.sampleRate*2,c.sampleRate),data=b.getChannelData(0);\r\n  let seed=0x51f15e;for(let i=0;i<data.length;i++){seed=(1664525*seed+1013904223)>>>0;data[i]=(seed/2147483648)-1;}\r\n  return b;\r\n }\r\n sourceNoise(){const s=this.context.createBufferSource();s.buffer=this.noiseBuffer();return s;}\r\n voice(kind,seconds,build){\r\n  const c=this.context;if(!c||c.state!=='running'||this.document?.hidden||this.muted||!this.volume)return;\r\n  const group=GROUP[kind]||kind,limit=LIMIT[group]||(['mechanical','dial','lever','switch'].includes(group)?4:group==='tinkle'||group==='transit'||group==='dialup'?1:2);\r\n  while([...this.voices].filter(v=>v.group===group).length>=limit)[...this.voices].find(v=>v.group===group).stop(.06);\r\n  while(this.voices.size>=12)this.voices.values().next().value.stop();\r\n  const output=c.createGain(),nodes=[];output.connect(this.duck);let stopped=false;\r\n  const voice={group,stop:(fade=0)=>{if(stopped)return;stopped=true;this.voices.delete(voice);let timer;\r\n   const clean=()=>{clearTimeout(timer);this.tails.delete(clean);for(const n of nodes)try{n.stop?.();}catch{}for(const n of nodes)try{n.disconnect();}catch{}output.disconnect();};\r\n   if(fade){const now=c.currentTime;output.gain.setValueAtTime(output.gain.value,now);output.gain.linearRampToValueAtTime(0,now+fade);this.tails.add(clean);timer=setTimeout(clean,Math.ceil(fade*1000)+5);}else clean();}};\r\n  this.voices.add(voice);const t=c.currentTime;\r\n  try{build({c,t,output,nodes});}catch{voice.stop();return;}\r\n  setTimeout(()=>voice.stop(),Math.ceil((seconds+.06)*1000));return voice;\r\n }\r\n tone({c,t,output,nodes},freq,duration,level,type='sine',endFreq=freq,at=0){\r\n  const osc=c.createOscillator(),gain=c.createGain(),start=t+at;osc.type=type;osc.frequency.setValueAtTime(freq,start);osc.frequency.exponentialRampToValueAtTime(Math.max(20,endFreq),start+duration);\r\n  gain.gain.setValueAtTime(.0001,start);gain.gain.exponentialRampToValueAtTime(Math.max(.0002,level),start+.008);gain.gain.exponentialRampToValueAtTime(.0001,start+duration);\r\n  osc.connect(gain).connect(output);osc.start(start);osc.stop(start+duration+.02);nodes.push(osc,gain);\r\n }\r\n noiseBurst({c,t,output,nodes},duration,level,low,high,at=0){\r\n  const src=this.sourceNoise(),filter=c.createBiquadFilter(),gain=c.createGain(),start=t+at;filter.type='bandpass';filter.frequency.setValueAtTime(low,start);filter.frequency.exponentialRampToValueAtTime(Math.max(30,high),start+duration);filter.Q.value=.7;\r\n  gain.gain.setValueAtTime(.0001,start);gain.gain.exponentialRampToValueAtTime(level,start+.012);gain.gain.exponentialRampToValueAtTime(.0001,start+duration);\r\n  src.connect(filter).connect(gain).connect(output);src.start(start);src.stop(start+duration+.02);nodes.push(src,filter,gain);\r\n }\r\n synth(kind){\r\n  const v=(duration,fn)=>this.voice(kind,duration,fn),pitch=()=>.94+Math.random()*.12,w=()=>.85+Math.random()*.3,j=()=>.85+Math.random()*.3;\r\n  switch(kind){\r\n   case 'main-control':return v(.15,x=>{this.tone(x,220*pitch(),.11,.17,'triangle',85);this.noiseBurst(x,.065,.08,800,240);});\r\n   case 'mechanical':return v(.12,x=>{this.tone(x,960*pitch(),.07,.17,'triangle',460);this.noiseBurst(x,.065,.08,1800,650);});\r\n   case 'switch':return v(.18,x=>{this.noiseBurst(x,.08,.16,250,2200);this.tone(x,350,.13,.13,'triangle',180,.035);});\r\n   case 'dial':return v(.12,x=>{this.tone(x,420*pitch(),.085,.095,'square',300);this.noiseBurst(x,.045,.04,1700,850);});\r\n   case 'lever':return v(.25,x=>{this.noiseBurst(x,.16,.14,450,1100);this.tone(x,150,.18,.12,'sawtooth',90,.03);});\r\n   case 'electric':return v(.22,x=>{this.noiseBurst(x,.18,.025,2200,1400);this.tone(x,110,.18,.008,'sine',100);});\r\n   case 'bloop':return v(.2,x=>this.tone(x,260,.16,.045,'sine',95));\r\n   case 'signal':return v(.32,x=>{this.tone(x,660,.07,.018,'sine',660);this.tone(x,880,.07,.012,'sine',880,.17);});\r\n   case 'whiteboard':return v(.85,x=>{this.noiseBurst(x,.26,.035,1300,900);for(let i=0;i<4;i++){this.tone(x,1900+i*210,.09,.055,'sine',3300-i*190,.10+i*.16);this.noiseBurst(x,.07,.018,3200,1700,.11+i*.16);}});\r\n   case 'crt':return v(.16,x=>{this.tone(x,90,.13,.12,'sine',54);this.noiseBurst(x,.08,.045,2000,400);});\r\n   // MOM Inc. blaster: transient (timing) + body + sub weight + debris tail. Pitch/level jitter per layer so repeats do not fatigue.\r\n   case 'gun-arm':return v(.14,x=>{this.noiseBurst(x,.03,.1*j(),2600,900);this.tone(x,520*w(),.05,.08*j(),'square',380,.04);});\r\n   case 'gun-shot':return v(.28,x=>{this.noiseBurst(x,.025,.32*j(),3200,600);this.tone(x,180*w(),.14,.22*j(),'triangle',60);this.tone(x,70,.12,.14*j(),'sine',35);this.noiseBurst(x,.18,.07*j(),900,200,.03);});\r\n   case 'blast':case 'blast-big':{const big=kind==='blast-big';return v(big?.95:.65,x=>{\r\n    this.noiseBurst(x,.02,.34*j(),2800,700);if(big)this.noiseBurst(x,.03,.2*j(),2000,500,.06);\r\n    this.tone(x,140*w(),big?.5:.32,.26*j(),'sawtooth',38);this.tone(x,110*w(),big?.44:.28,.2*j(),'triangle',40);this.tone(x,big?48:55,big?.45:.3,.18*j(),'sine',big?24:28);\r\n    for(let i=0,n=big?5:4;i<n;i++)this.noiseBurst(x,.04,(.05+Math.random()*.04)*j(),1400,500,.12+Math.random()*.33);\r\n    if(big)this.noiseBurst(x,.3,.04*j(),3000,1500,.05);\r\n    this.window?.dispatchEvent?.(new CustomEvent('myr5:sfx-duck',{detail:{to:.45,seconds:.05,release:big?.5:.35}}));});}\r\n   case 'barrel-split':return v(.32,x=>{this.noiseBurst(x,.06,.14*j(),1800,400);this.tone(x,220*w(),.12,.12*j(),'triangle',90);this.noiseBurst(x,.08,.06*j(),4500,1200,.02);});\r\n   case 'ice':return v(.5,x=>{this.noiseBurst(x,.17,.16,5500,1700);this.tone(x,980*pitch(),.32,.08,'sine',460,.025);this.noiseBurst(x,.08,.045,4500,1000,.16);});\r\n   case 'jelly':return v(.46,x=>{this.noiseBurst(x,.28,.16,350,130);this.tone(x,180*pitch(),.32,.16,'sine',65);this.tone(x,95,.16,.075,'sine',45,.1);});\r\n   case 'water':return v(.65,x=>{this.noiseBurst(x,.44,.23,1900,250);this.tone(x,410,.23,.08,'sine',110,.04);this.noiseBurst(x,.22,.09,900,160,.2);});\r\n   case 'water-slosh':return v(.8,x=>{this.noiseBurst(x,.5,.13,320,105);this.noiseBurst(x,.4,.11,500,190,.2);this.tone(x,120,.55,.065,'sine',75,.08);});\r\n   case 'pond-slosh':return v(.34,x=>{this.noiseBurst(x,.27,.038,320,105);this.tone(x,120,.27,.018,'sine',75,.04);});\r\n   case 'grass':return v(.32,x=>{this.noiseBurst(x,.24,.065,2000,520);this.tone(x,1400*pitch(),.18,.025,'sine',1100,.06);});\r\n   case 'grass-tinkle':return v(.55,x=>{this.tone(x,1650*pitch(),.4,.028,'sine',1350);this.tone(x,2180*pitch(),.27,.018,'sine',1770,.07);});\r\n   case 'cogs':return v(.32,x=>{for(let i=0;i<3;i++){this.tone(x,350-i*65,.085,.12,'square',160-i*20,i*.085);this.noiseBurst(x,.055,.07,1500,480,i*.085);}});\r\n   case 'wood':return v(.45,x=>{this.noiseBurst(x,.32,.14,600,130);this.tone(x,145,.36,.14,'triangle',75);});\r\n   case 'wood-scrape':return v(.45,x=>{this.noiseBurst(x,.36,.13,900,180);this.tone(x,155,.3,.06,'triangle',95);});\r\n   case 'quilt':return v(.34,x=>{this.noiseBurst(x,.25,.10,1450,320);this.tone(x,260,.15,.055,'sine',185,.05);});\r\n   case 'drag':return v(.19,x=>{this.noiseBurst(x,.16,.045,1200,330);});\r\n   case 'transit':return v(1.5,x=>{this.noiseBurst(x,1.3,.18,180,5000);this.tone(x,66,1.25,.16,'sawtooth',840);this.tone(x,110,1.1,.11,'sine',1800,.12);});\r\n   case 'dialup':return v(2.6,x=>{for(let i=0;i<9;i++){this.tone(x,[350,440,610,250,820,530,1190,460,960][i],.2,.018,'sine',230+i*83,i*.25);this.noiseBurst(x,.14,.014,1400,4600,i*.25);}});\r\n  }\r\n }\r\n play(kind){\r\n  if(!RATE[kind]||this.muted||!this.volume||this.document?.hidden)return;\r\n  const now=this.now(),previous=this.last.get(kind)??-Infinity;if(now-previous<RATE[kind])return;this.last.set(kind,now);\r\n  const context=this.context,epoch=this.epoch;if(!context)return;\r\n  const start=()=>{if(this.context!==context||this.epoch!==epoch||this.now()-now>250||context.state!=='running'||this.document?.hidden||this.muted)return;\r\n   const variants=kind==='whiteboard'?null:this.samples.get(kind);if(variants?.length)this.playSample(kind,variants[Math.floor(Math.random()*variants.length)]);else this.synth(kind);\r\n  };\r\n  if(context.state==='running')start();else void context.resume().then(()=>{this.syncAmbience();start();}).catch(()=>{});\r\n  if(this.manifest&&SAMPLE[kind]&&this.sampleStatus.get(kind)!=='loading'&&this.sampleStatus.get(kind)!=='ready'&&Date.now()>=(this.sampleRetry.get(kind)||0))void this.loadSample(kind);\r\n }\r\n playSample(kind,buffer){\r\n  const duration=Math.min(buffer.duration,kind==='pond-slosh'?.38:3)/(kind==='main-control'?.76:1);\r\n  this.voice(kind,duration,({c,t,output,nodes})=>{\r\n   const source=c.createBufferSource(),gain=c.createGain();source.buffer=buffer;source.playbackRate.value=(kind==='main-control'?.76:1)*(.97+Math.random()*.06);\r\n   const level=kind==='blast'?.7:kind==='blast-big'?.75:kind==='gun-shot'?.6:kind==='pond-slosh'?.16:kind==='dialup'?.13:kind==='signal'?.09:kind==='electric'?.12:kind==='bloop'?.16:kind==='whiteboard'?.4:kind==='grass-tinkle'?.04:kind==='grass'?.4:kind==='transit'?.72:.68;\r\n   gain.gain.setValueAtTime(.0001,t);gain.gain.linearRampToValueAtTime(level,t+.008);gain.gain.setValueAtTime(level,t+Math.max(.009,duration-.05));gain.gain.linearRampToValueAtTime(.0001,t+duration);\r\n   source.connect(gain).connect(output);source.start(t);source.stop(t+duration+.01);nodes.push(source,gain);\r\n  });\r\n }\r\n async loadManifest(){\r\n  this.manifestPending=(async()=>{try{const response=await fetch('/audio/sfx/manifest.json');if(response.ok){const candidate=await response.json();if(candidate?.version===1&&candidate.cues&&typeof candidate.cues==='object'&&Object.values(candidate.cues).some(paths=>Array.isArray(paths)&&paths.some(path=>typeof path==='string'&&/^\\/audio\\/sfx\\/[a-z0-9-]+\\.mp3$/i.test(path))))this.manifest=candidate;}}catch{}\r\n   if(this.manifest&&this.context){for(const kind of Object.keys(SAMPLE))void this.loadSample(kind);}\r\n   else{this.manifestRetryAt=Date.now()+15_000;this.manifestPending=null;}\r\n   return this.manifest;})();\r\n  return this.manifestPending;\r\n }\r\n async loadSample(kind){\r\n  this.sampleStatus.set(kind,'loading');\r\n  try{const sources=this.manifest?.cues?.[kind]||this.manifest?.cues?.[SAMPLE[kind]];const paths=(Array.isArray(sources)?sources:[sources]).filter(path=>typeof path==='string'&&/^\\/audio\\/sfx\\/[a-z0-9-]+\\.mp3$/i.test(path)).slice(0,2);\r\n   const decoded=await Promise.all(paths.map(async path=>{const url=path.startsWith('/')?path:`/audio/sfx/${path}`;const response=await fetch(url);if(!response.ok)throw Error('Unavailable');const data=await response.arrayBuffer();if(data.byteLength>2_000_000)throw Error('Too large');let buffer=await this.context.decodeAudioData(data);if(buffer.duration>(['pod-hum','breeze','waterfall'].includes(kind)?30:5))throw Error('Too long');if(kind==='waterfall')buffer=seamlessLoopBuffer(this.context,buffer);return buffer;}));\r\n   if(!decoded.length)throw Error('Unavailable');this.samples.set(kind,decoded);this.sampleStatus.set(kind,'ready');if(['pod-hum','breeze','waterfall'].includes(kind))this.syncAmbience(true);\r\n  }catch{this.sampleStatus.set(kind,'unavailable');this.sampleRetry.set(kind,Date.now()+15_000);}\r\n }\r\n stopAll(){this.epoch++;for(const voice of [...this.voices])voice.stop();for(const clean of [...this.tails])clean();this.stopAmbience(true);}\r\n stopAmbience(immediate=false){\r\n  const active=this.ambience;if(!active)return;this.ambience=null;\r\n  const {gain,sources,nodes}=active,t=this.context.currentTime,delay=immediate?0:.12;\r\n  gain.gain.cancelScheduledValues(t);gain.gain.setValueAtTime(gain.gain.value,t);gain.gain.linearRampToValueAtTime(0,t+delay);\r\n  setTimeout(()=>{for(const node of sources)try{node.stop();}catch{}for(const node of nodes)try{node.disconnect();}catch{}},Math.ceil(delay*1000)+15);\r\n }\r\n syncAmbience(force=false){\r\n  if(!this.context||this.context.state!=='running')return;\r\n  const body=this.document?.body,meditation=this.document?.querySelector?.('.meditation-panel[open] [data-meditation-scene]:not([hidden])'),blocked=(!meditation&&this.document?.querySelector?.('.meditation-panel[open]'))||this.document?.querySelector?.('dialog[open]:not(#portalWorkoutHome):not(#portalMenu):not(#settings):not(.meditation-panel)')||body?.dataset?.tracking==='true'||body?.dataset?.cameraWorkout==='true'||(!meditation&&body?.dataset?.shipView==='true')||body?.dataset?.screen==='rest';\r\n  const scene=this.document?.hidden||this.muted||!this.volume||blocked?'off':meditation?'meditation':this.scene;\r\n  const key=scene==='portal'?`portal:${this.board}`:scene;\r\n  if(!force&&key===this.ambienceKey&&this.ambience)return;\r\n  this.stopAmbience();this.ambienceKey=key;if(scene==='off')return;\r\n  const c=this.context,t=c.currentTime,gain=c.createGain(),sources=[],nodes=[gain];gain.gain.setValueAtTime(0,t);gain.gain.linearRampToValueAtTime(1,t+.18);gain.connect(this.duck);\r\n  const bed=c.createGain();bed.gain.value=.12;bed.connect(gain);nodes.push(bed);\r\n  if(scene==='meditation'){const buffer=this.samples.get('waterfall')?.[0],rush=buffer?c.createBufferSource():this.sourceNoise(),filter=c.createBiquadFilter(),waterGain=c.createGain();if(buffer)rush.buffer=buffer;rush.loop=true;filter.type='lowpass';filter.frequency.value=3600;waterGain.gain.value=buffer?.28:.09;rush.connect(filter).connect(waterGain).connect(gain);rush.start();sources.push(rush);nodes.push(rush,filter,waterGain);this.ambience={gain,sources,nodes};return;}\r\n  const grass=scene==='portal'&&this.board==='grass',water=scene==='portal'&&['water','pond'].includes(this.board),breeze=this.samples.get('breeze')?.[0];\r\n  if(!grass&&!water){const humBuffer=this.samples.get('pod-hum')?.[0];\r\n   if(humBuffer){const hum=c.createBufferSource();hum.buffer=humBuffer;hum.loop=true;hum.connect(bed);hum.start();sources.push(hum);nodes.push(hum);}\r\n   else{const hum=c.createOscillator();hum.type='sine';hum.frequency.value=scene==='portal'?61:54;hum.connect(bed);hum.start();sources.push(hum);nodes.push(hum);}}\r\n  if(grass&&breeze){const wind=c.createBufferSource(),windGain=c.createGain();wind.buffer=breeze;wind.loop=true;windGain.gain.value=.18;wind.connect(windGain).connect(gain);wind.start();sources.push(wind);nodes.push(wind,windGain);}\r\n  else{const airflow=this.sourceNoise(),filter=c.createBiquadFilter(),airGain=c.createGain();airflow.loop=true;filter.type='lowpass';filter.frequency.value=grass?350:water?580:190;airGain.gain.value=grass?.09:water?.12:.018;airflow.connect(filter).connect(airGain).connect(gain);airflow.start();sources.push(airflow);nodes.push(airflow,filter,airGain);}\r\n  this.ambience={gain,sources,nodes};\r\n }\r\n dispose(){this.abort?.abort();this.stopAll();void this.context?.close();this.context=null;this.started=false;}\r\n}\r\n\r\nexport const physicalSound=new PhysicalSound();\r\n","audio/sfx/credits.html":"<!doctype html><html lang=\"en\"><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Sound credits</title><style>body{font:18px system-ui;max-width:48rem;margin:3rem auto;padding:1rem;background:#101821;color:#e9f0f7}a{color:#9ee4ff}li{margin:1rem 0}</style><h1>Sound credits</h1><p>Effects are released under <a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a>. The meditation waterfall is adapted from Stream Sounds by kurt, licensed under <a href=\"https://creativecommons.org/licenses/by/3.0/\">CC BY 3.0</a>, trimmed, filtered, normalized and crossfaded into a loop. Other effects are CC0. Material recordings were edited into short cues; wind, teleport, dial-up and CRT effects include sound design. Coach voices are local variants of the existing eSpeak NG generated clips. The app code remains under its existing AGPL license.</p><ul><li>Kenney — <a href=\"https://kenney.nl/assets/interface-sounds\">interface</a> (CC0-1.0)</li><li>Kenney — <a href=\"https://kenney.nl/assets/impact-sounds\">impact</a> (CC0-1.0)</li><li>qubodup — <a href=\"https://opengameart.org/content/7-mechanical-clicks-and-buzzes\">mechanical</a> (CC0-1.0)</li><li>bart — <a href=\"https://opengameart.org/content/ice-spells\">ice</a> (CC0-1.0)</li><li>Independent.nu — <a href=\"https://opengameart.org/content/8-wet-squish-slurp-impacts\">jelly</a> (CC0-1.0)</li><li>ezwa — <a href=\"https://opengameart.org/content/6-short-water-splashes\">water</a> (CC0-1.0)</li><li>transitking — <a href=\"https://opengameart.org/content/water-waves\">waves</a> (CC0-1.0)</li><li>qubodup — <a href=\"https://opengameart.org/content/20-rustles-dry-leaves\">grass</a> (CC0-1.0)</li><li>Iochi Glaucus — <a href=\"https://opengameart.org/content/fabric-rustling\">cloth</a> (CC0-1.0)</li><li>Luke.RUSTLTD — <a href=\"https://opengameart.org/content/wind1\">wind</a> (CC0-1.0)</li><li>LEGIT Audio — <a href=\"https://opengameart.org/content/the-shop\">hum</a> (CC0-1.0)</li><li>Ogrebane — <a href=\"https://opengameart.org/content/teleport-spell\">portal</a> (CC0-1.0)</li><li>MOM Inc. — <a href=\"/source.json\">original</a> (CC0-1.0)</li><li>kurt — <a href=\"https://opengameart.org/content/stream-sounds\">waterfall</a> (CC-BY-3.0)</li><li>Independent.nu — <a href=\"https://opengameart.org/content/35-wooden-crackshitsdestructions\">wood</a> (CC0-1.0)</li></ul><p><a href=\"manifest.json\">Asset provenance and checksums</a> · <a href=\"/source.json\">App source</a> · <a href=\"/pose\">Back to Coach</a></p></html>","audio/sfx/manifest.json":"{\r\n  \"version\": 1,\r\n  \"license\": \"CC0-1.0 AND CC-BY-3.0\",\r\n  \"cues\": {\r\n    \"mechanical\": [\r\n      \"/audio/sfx/mechanical-click-1.mp3\",\r\n      \"/audio/sfx/mechanical-click-2.mp3\"\r\n    ],\r\n    \"switch\": [\r\n      \"/audio/sfx/metal-switch-1.mp3\",\r\n      \"/audio/sfx/metal-switch-2.mp3\"\r\n    ],\r\n    \"ice\": [\r\n      \"/audio/sfx/ice-crack-1.mp3\",\r\n      \"/audio/sfx/ice-crack-2.mp3\"\r\n    ],\r\n    \"jelly\": [\r\n      \"/audio/sfx/jelly-squish-1.mp3\",\r\n      \"/audio/sfx/jelly-squish-2.mp3\"\r\n    ],\r\n    \"water\": [\r\n      \"/audio/sfx/water-splash-1.mp3\",\r\n      \"/audio/sfx/water-splash-2.mp3\"\r\n    ],\r\n    \"water-slosh\": [\r\n      \"/audio/sfx/water-slosh.mp3\"\r\n    ],\r\n    \"grass\": [\r\n      \"/audio/sfx/grass-rustle-1.mp3\",\r\n      \"/audio/sfx/grass-rustle-2.mp3\"\r\n    ],\r\n    \"grass-tinkle\": [\r\n      \"/audio/sfx/grass-tinkle.mp3\"\r\n    ],\r\n    \"quilt\": [\r\n      \"/audio/sfx/cloth-rustle-1.mp3\",\r\n      \"/audio/sfx/cloth-rustle-2.mp3\"\r\n    ],\r\n    \"wood\": [\r\n      \"/audio/sfx/wood-tap-1.mp3\",\r\n      \"/audio/sfx/wood-tap-2.mp3\"\r\n    ],\r\n    \"wood-scrape\": [\r\n      \"/audio/sfx/wood-scrape.mp3\"\r\n    ],\r\n    \"cogs\": [\r\n      \"/audio/sfx/cogs-ratchet-1.mp3\",\r\n      \"/audio/sfx/cogs-ratchet-2.mp3\"\r\n    ],\r\n    \"crt\": [\r\n      \"/audio/sfx/crt-tap.mp3\"\r\n    ],\r\n    \"transit\": [\r\n      \"/audio/sfx/portal-transit.mp3\"\r\n    ],\r\n    \"dialup\": [\r\n      \"/audio/sfx/dialup.mp3\"\r\n    ],\r\n    \"pod-hum\": [\r\n      \"/audio/sfx/pod-hum.mp3\"\r\n    ],\r\n    \"whiteboard\": [\r\n      \"/audio/sfx/whiteboard-erase-marker.mp3\"\r\n    ],\r\n    \"electric\": [\r\n      \"/audio/sfx/electric-static.mp3\"\r\n    ],\r\n    \"bloop\": [\r\n      \"/audio/sfx/menu-bloop.mp3\"\r\n    ],\r\n    \"signal\": [\r\n      \"/audio/sfx/signal-beeps.mp3\"\r\n    ],\r\n    \"waterfall\": [\r\n      \"/audio/sfx/meditation-waterfall.mp3\"\r\n    ],\r\n    \"breeze\": [\r\n      \"/audio/sfx/gentle-breeze.mp3\"\r\n    ],\r\n    \"dial\": [\r\n      \"/audio/sfx/mechanical-click-1.mp3\",\r\n      \"/audio/sfx/mechanical-click-2.mp3\"\r\n    ],\r\n    \"lever\": [\r\n      \"/audio/sfx/metal-switch-1.mp3\",\r\n      \"/audio/sfx/metal-switch-2.mp3\"\r\n    ]\r\n  },\r\n  \"assets\": [\r\n    {\r\n      \"url\": \"/audio/sfx/mechanical-click-1.mp3\",\r\n      \"source\": \"mechanical\",\r\n      \"master\": \"mechanical/mechanical/mechanical_button-01.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.4,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.365:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"5049c0c2f3e297ffd05544a0150a24ba0eebc9e7f5bcb931e99ff83721f4a5ef\",\r\n      \"masterSha256\": \"c763eb6d5177c37c422965b47ece95cb824e795d0df3b3f83ae9ef53db161a3e\",\r\n      \"bytes\": 4114\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/mechanical-click-2.mp3\",\r\n      \"source\": \"mechanical\",\r\n      \"master\": \"mechanical/mechanical/mechanical_clicks-05.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.42,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.385:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"e134272539997f20e031b3050f1ffae990b7f628a482652ae5f63fb97abc2e49\",\r\n      \"masterSha256\": \"59cc4dd84b29ebc147719677bde1256f97222c7e91a398c3b87a401a56c195b6\",\r\n      \"bytes\": 4306\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/metal-switch-1.mp3\",\r\n      \"source\": \"interface\",\r\n      \"master\": \"kenney-interface/Audio/switch_001.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.4,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.365:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"2f45c9891224fef39b30ed048a37de85ef31735b5c69a1bb01b226dd4ae8c0e7\",\r\n      \"masterSha256\": \"3b74efad87f1e69dbd1d05c5ad952ab90859b5a3d11da6ec5bd79b4f03b42afa\",\r\n      \"bytes\": 3884\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/metal-switch-2.mp3\",\r\n      \"source\": \"interface\",\r\n      \"master\": \"kenney-interface/Audio/toggle_001.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.4,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.365:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"2c5a63c961a7c632d8117df36236f98dfbedf522648b49779d4559b32392a5ff\",\r\n      \"masterSha256\": \"ca1d2dde5f0b286abac4f070e23edab8f30927c8a533665cdf2ac6492a415e49\",\r\n      \"bytes\": 1772\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/ice-crack-1.mp3\",\r\n      \"source\": \"ice\",\r\n      \"master\": \"ice/ice.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.85,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.815:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"d13b487d1b767a83b5a9d010c23cb0c0a0ef3f670434871a6aaf2adc8dfc493c\",\r\n      \"masterSha256\": \"c3039c864d056d0e4951b84b96a7bb0044ca8cb58aeae514fc256145872b6a94\",\r\n      \"bytes\": 7532\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/ice-crack-2.mp3\",\r\n      \"source\": \"ice\",\r\n      \"master\": \"ice/coldsnap.wav\",\r\n      \"seek\": 0.1,\r\n      \"maxSeconds\": 0.85,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.815:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"e883b3102cd08aeef403ee08734b123241fb5874cee1a3ee8b29d1e4bc59f131\",\r\n      \"masterSha256\": \"090977264d65d90a50b04e9f0c1c4e02fb194e5b50d9fe244f0079a4da54158c\",\r\n      \"bytes\": 7532\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/jelly-squish-1.mp3\",\r\n      \"source\": \"jelly\",\r\n      \"master\": \"squish/impsplat/impactsplat07.mp3.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.55,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.515:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"f3aef20cf320c5475141bdb34435952f5399abde8e09b42b9315c0c5e654fc97\",\r\n      \"masterSha256\": \"adae57b90523d754a7b0221876d1c3e4c7b90d5ded732af4895c5b8d0489b640\",\r\n      \"bytes\": 4844\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/jelly-squish-2.mp3\",\r\n      \"source\": \"jelly\",\r\n      \"master\": \"squish/impsplat/impactsplat08.mp3.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.66,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.625:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"8518fda10d2d926435c7c2e6652f401f9fb7828631054731d1777c4b979e60d3\",\r\n      \"masterSha256\": \"08620cd7dbeaa27cff28a5295846ee9079be7ec6c83725a4af568b9dcc0d045d\",\r\n      \"bytes\": 5996\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/water-splash-1.mp3\",\r\n      \"source\": \"water\",\r\n      \"master\": \"splash/ezwa-water_splash/water_splash-02.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.42,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.385:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"c6793cc0e61289045c1f1975164bfa526812eb8f729cdff7b8fbe311302b1b65\",\r\n      \"masterSha256\": \"c0c2c6e6fa113138a71b9966a456bea844dbb955f0ed7b95a01777cb62fd7461\",\r\n      \"bytes\": 4216\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/water-splash-2.mp3\",\r\n      \"source\": \"water\",\r\n      \"master\": \"splash/ezwa-water_splash/water_splash-03.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.72,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.6849999999999999:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"0e8f6004a0d57ce5958c4b2697101a0e9313e117c88a1edb071d64894e78db12\",\r\n      \"masterSha256\": \"a22c5cac675fa60aaff8d907acf7627f1e9dcc337798ff4eb34f2f8e7a4c9e2e\",\r\n      \"bytes\": 6520\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/water-slosh.mp3\",\r\n      \"source\": \"waves\",\r\n      \"master\": \"water-slosh.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 2.5,\r\n      \"filters\": \"lowpass=f=2500,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=2.465:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"b99ff74a3b4f86951b6a3ab06acbf81edac3b8e3d9bf2559b87671326e77f7b3\",\r\n      \"masterSha256\": \"6c5b59562bf9b00e77f7bd8d6550912b6326e190ce97e9b8c1a1faa887bb4fac\",\r\n      \"bytes\": 16940\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/grass-rustle-1.mp3\",\r\n      \"source\": \"grass\",\r\n      \"master\": \"leaves/rustle/rustle01.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.7,\r\n      \"filters\": \"lowpass=f=4000,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.6649999999999999:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"82f4c372e46df9443577aa1c375251fe4b1621fcd3aeb227236ea28800a9aec7\",\r\n      \"masterSha256\": \"9c5da19eb8d37b59890c0be1171c40fe4dd16177e7a97558a156c1036b7bed05\",\r\n      \"bytes\": 6380\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/grass-rustle-2.mp3\",\r\n      \"source\": \"grass\",\r\n      \"master\": \"leaves/rustle/rustle02.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.7,\r\n      \"filters\": \"lowpass=f=4000,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.6649999999999999:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"7e1592115b5c6582a1bc5b60bbd98fef45d2cdac12c0ce3b0e32933f77fe5a4e\",\r\n      \"masterSha256\": \"1e01e752b2165d78482bd91ef8b859541601ae4de6b7cf6178e935cce0036c69\",\r\n      \"bytes\": 6380\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/grass-tinkle.mp3\",\r\n      \"source\": \"interface\",\r\n      \"master\": \"kenney-interface/Audio/glass_001.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.6,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.565:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"996f92a4974ae551a8d7f58873f0e473cadaa50ee57cc752f07cd376aa1fa7c6\",\r\n      \"masterSha256\": \"183eebee20eb0a532b0b85104d139cbf2673eb66d95c3cc733ac9ea98362e7e8\",\r\n      \"bytes\": 2924\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/cloth-rustle-1.mp3\",\r\n      \"source\": \"cloth\",\r\n      \"master\": \"cloth.ogg\",\r\n      \"seek\": 0.5,\r\n      \"maxSeconds\": 0.65,\r\n      \"filters\": \"lowpass=f=4000,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.615:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"45405bd70643045691627623376ca7eb91e8a886eeb3d65a84c4d003a6e2bd03\",\r\n      \"masterSha256\": \"897c0937041afdf3581427b80a7546f99d219d0008e12ff5500c2afdfa4b7a1e\",\r\n      \"bytes\": 5996\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/cloth-rustle-2.mp3\",\r\n      \"source\": \"cloth\",\r\n      \"master\": \"cloth.ogg\",\r\n      \"seek\": 2,\r\n      \"maxSeconds\": 0.65,\r\n      \"filters\": \"lowpass=f=4000,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.615:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"2760c5fa1d97cf22726edc9b3b275a264145ce90a7ba36e337364cbba90fe3e9\",\r\n      \"masterSha256\": \"897c0937041afdf3581427b80a7546f99d219d0008e12ff5500c2afdfa4b7a1e\",\r\n      \"bytes\": 5996\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/wood-tap-1.mp3\",\r\n      \"source\": \"impact\",\r\n      \"master\": \"kenney-impact/Audio/impactWood_light_000.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.45,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.41500000000000004:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"72b11ecfe7ca8972a7f48feb0b3cb0a19244ca7f9ceb9d683aa5cc774874ec98\",\r\n      \"masterSha256\": \"eb45e35b4bed784d3f120de4afec4b0d6ac09d9e143cce8cfcb7d739e1b1f3c3\",\r\n      \"bytes\": 2732\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/wood-tap-2.mp3\",\r\n      \"source\": \"impact\",\r\n      \"master\": \"kenney-impact/Audio/impactWood_light_001.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.45,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.41500000000000004:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"7d4a4b60ddfd70d71026b1b21a745d6be2281fe1f6bfaf7fc4c645bf3dfaf3c2\",\r\n      \"masterSha256\": \"4b76bf3ccc8e60d19188f3165b778a7817786faa6887c55d9049bcbeef3b425f\",\r\n      \"bytes\": 2732\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/wood-scrape.mp3\",\r\n      \"source\": \"wood\",\r\n      \"master\": \"wood/wood_impact/crack01.mp3.flac\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.65,\r\n      \"filters\": \"lowpass=f=3000,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.615:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"681a12a5bbcf77f0814473d6339e5d009e3194092801bbd87e48b2c4a8a444f3\",\r\n      \"masterSha256\": \"a25993adc8c2bbfdd80490980d83c27a587f2d3452ee4e5bd784f02c082ec448\",\r\n      \"bytes\": 5996\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/cogs-ratchet-1.mp3\",\r\n      \"source\": \"impact\",\r\n      \"master\": \"kenney-impact/Audio/impactMetal_light_000.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.4,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.365:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"7c3dda03cb42530aa0a69e63070307b63722d55632aa3e5e5f8a4b32dddc435b\",\r\n      \"masterSha256\": \"33b5e6e37c6e9d54e07bf5a89b12c76e879f40c1ea83cdd82714df1d6f9fec6d\",\r\n      \"bytes\": 3692\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/cogs-ratchet-2.mp3\",\r\n      \"source\": \"impact\",\r\n      \"master\": \"kenney-impact/Audio/impactMetal_light_001.ogg\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.4,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.365:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"ea9e9443cdcc64439ef54334dfc128fbc42ce68dc6edb86537bbd3c3c488997d\",\r\n      \"masterSha256\": \"fba69c467ddd85da7b1d82e259f936b876d9ba6a3d6f1b24bdd10468e46bfe08\",\r\n      \"bytes\": 2732\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/crt-tap.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"crt-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.12,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.08499999999999999:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"1fc6d11eb35ca242d66d7f0f19503a1c986b19b58da61c324d8214fcd5aa340a\",\r\n      \"masterSha256\": \"30bbf4295902825adfaf0d5666920824a8fdf3321d9a18e033dd511344625835\",\r\n      \"bytes\": 1580\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/portal-transit.mp3\",\r\n      \"source\": \"portal\",\r\n      \"master\": \"teleport.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 2,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=1.965:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"a200199794750c4620f8fc61496188764d1e6c27c83f858725ea6dc27744ba88\",\r\n      \"masterSha256\": \"23fe938e7e82931227196bf6b2978ad9154f627af26623acf52958d12125f3b8\",\r\n      \"bytes\": 13676\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/dialup.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"dialup-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 1.8,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=1.7650000000000001:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"a3a176ed5e6fd26b74c82b62b85137bda4d7c231a83de711c2b191bd8d362a2e\",\r\n      \"masterSha256\": \"8e764074a112044a074d152b9668f456e456a2c81514444f2447c87bc7801138\",\r\n      \"bytes\": 15020\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/pod-hum.mp3\",\r\n      \"source\": \"hum\",\r\n      \"master\": \"shop/TheShopCollection_convenience_store_drinks_fridge_drone.wav\",\r\n      \"seek\": 1,\r\n      \"maxSeconds\": 12,\r\n      \"filters\": \"highpass=f=50,lowpass=f=1100,loudnorm=I=-22:TP=-3:LRA=7\",\r\n      \"loopCrossfadeSeconds\": 0.5,\r\n      \"sha256\": \"2c1d783addb9d45199626cbc931e60fbb92a9d07110900cf68adf6f0a4d34cca\",\r\n      \"masterSha256\": \"222545244c0eed4bb924a3616d1103156d942776681634698f7fa3b11fe99b9d\",\r\n      \"bytes\": 80300\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/whiteboard-erase-marker.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"whiteboard-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.9,\r\n      \"filters\": \"highpass=f=300,lowpass=f=4200,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.865:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"f43a61da92082b46783739debadee7d048ad89d1c170b1891cca21d8b9982b35\",\r\n      \"masterSha256\": \"d9e768a87004c992dc4260d44342039c982d418e53ad25e4f47a03a793758181\",\r\n      \"bytes\": 7916\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/electric-static.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"electric-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.25,\r\n      \"filters\": \"highpass=f=1400,lowpass=f=4200,loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.215:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"be024f00c395f157a5af227f0eca594a6d13c9a95129567f81919a53fae54da2\",\r\n      \"masterSha256\": \"ee5be1d09a9142ac8d78b80ce45b4c69fe446ce39cbde2068496c7d7ef807fa3\",\r\n      \"bytes\": 2732\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/menu-bloop.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"bloop-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.22,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.185:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"3ac1c6d17a0bd6ac6c50ef303fdb888cbc49cb642a7a604ab06d725843667017\",\r\n      \"masterSha256\": \"662f7caeead7ce14adf60d17904885670766fe212e28176298df056b7b7a26e7\",\r\n      \"bytes\": 2540\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/signal-beeps.mp3\",\r\n      \"source\": \"original\",\r\n      \"master\": \"signal-original.wav\",\r\n      \"seek\": 0,\r\n      \"maxSeconds\": 0.35,\r\n      \"filters\": \"loudnorm=I=-22:TP=-3:LRA=7,afade=t=in:st=0:d=0.004,afade=t=out:st=0.31499999999999995:d=0.035\",\r\n      \"loopCrossfadeSeconds\": null,\r\n      \"sha256\": \"0bbd26949f9a07ebf88b1caad8192a19aa4507f2506499ea433ee8c03c1967cf\",\r\n      \"masterSha256\": \"97a5c16539be0ee5262d0b4763a8a5b22e68442f93458219d793bb06db254e22\",\r\n      \"bytes\": 3500\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/meditation-waterfall.mp3\",\r\n      \"source\": \"waterfall\",\r\n      \"master\": \"stream-waterfall/stream-waterfall/waterfall1.ogg\",\r\n      \"seek\": 1,\r\n      \"maxSeconds\": 12,\r\n      \"filters\": \"highpass=f=80,lowpass=f=5500,loudnorm=I=-22:TP=-3:LRA=7\",\r\n      \"loopCrossfadeSeconds\": 0.5,\r\n      \"sha256\": \"ff51b4796ae6cde1cdffe289580211b0a943c8c3665bfe8c2c7a7699bca413b4\",\r\n      \"masterSha256\": \"f6c83c65380f3778d068329f7027b7970555d6441c505b9a111f945518030ded\",\r\n      \"bytes\": 92780\r\n    },\r\n    {\r\n      \"url\": \"/audio/sfx/gentle-breeze.mp3\",\r\n      \"source\": \"wind\",\r\n      \"master\": \"wind.wav\",\r\n      \"seek\": 2,\r\n      \"maxSeconds\": 12,\r\n      \"filters\": \"lowpass=f=2300,loudnorm=I=-22:TP=-3:LRA=7\",\r\n      \"loopCrossfadeSeconds\": 0.5,\r\n      \"sha256\": \"2de4dce0fe6cab422050c4acbdf961454bd1fea0ca9508bb2bf6ed374312b081\",\r\n      \"masterSha256\": \"a2856f794fbf77e05f8241dc4adeade7f62fa21c3c9dc49f7725b6c6218060c3\",\r\n      \"bytes\": 92780\r\n    }\r\n  ],\r\n  \"sources\": [\r\n    {\r\n      \"id\": \"interface\",\r\n      \"author\": \"Kenney\",\r\n      \"url\": \"https://kenney.nl/assets/interface-sounds\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"impact\",\r\n      \"author\": \"Kenney\",\r\n      \"url\": \"https://kenney.nl/assets/impact-sounds\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"mechanical\",\r\n      \"author\": \"qubodup\",\r\n      \"url\": \"https://opengameart.org/content/7-mechanical-clicks-and-buzzes\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"ice\",\r\n      \"author\": \"bart\",\r\n      \"url\": \"https://opengameart.org/content/ice-spells\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"jelly\",\r\n      \"author\": \"Independent.nu\",\r\n      \"url\": \"https://opengameart.org/content/8-wet-squish-slurp-impacts\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"water\",\r\n      \"author\": \"ezwa\",\r\n      \"url\": \"https://opengameart.org/content/6-short-water-splashes\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"waves\",\r\n      \"author\": \"transitking\",\r\n      \"url\": \"https://opengameart.org/content/water-waves\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"grass\",\r\n      \"author\": \"qubodup\",\r\n      \"url\": \"https://opengameart.org/content/20-rustles-dry-leaves\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"cloth\",\r\n      \"author\": \"Iochi Glaucus\",\r\n      \"url\": \"https://opengameart.org/content/fabric-rustling\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"wind\",\r\n      \"author\": \"Luke.RUSTLTD\",\r\n      \"url\": \"https://opengameart.org/content/wind1\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"hum\",\r\n      \"author\": \"LEGIT Audio\",\r\n      \"url\": \"https://opengameart.org/content/the-shop\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"portal\",\r\n      \"author\": \"Ogrebane\",\r\n      \"url\": \"https://opengameart.org/content/teleport-spell\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"original\",\r\n      \"author\": \"MOM Inc.\",\r\n      \"url\": \"/source.json\",\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    {\r\n      \"id\": \"waterfall\",\r\n      \"author\": \"kurt\",\r\n      \"url\": \"https://opengameart.org/content/stream-sounds\",\r\n      \"license\": \"CC-BY-3.0\"\r\n    },\r\n    {\r\n      \"id\": \"wood\",\r\n      \"author\": \"Independent.nu\",\r\n      \"url\": \"https://opengameart.org/content/35-wooden-crackshitsdestructions\",\r\n      \"license\": \"CC0-1.0\"\r\n    }\r\n  ]\r\n}\r\n","audio/sound-ui.mjs":"import {physicalSound} from './physical-sound.mjs';\r\n\r\nconst BOARD_CUES={quilt:['quilt','quilt'],ice:['ice','ice'],jelly:['jelly','jelly'],water:['water','water-slosh'],pond:['water','pond-slosh'],grass:['grass','grass'],cogs:['cogs','cogs'],wood:['wood','wood-scrape']};\r\nconst ELECTRIC='#settings,#portalMenu,#remindersPanel,.reminders-computer-panel,.reminders-computer-screen';\r\nconst INTERNAL='dialog:not(#settings):not(#portalMenu):not(#portalWorkoutHome),.creature-editor,.handborne-app';\r\nexport function surfaceCue(el){\r\n if(globalThis.location?.pathname?.startsWith('/creature/')||el?.closest?.('#library,[data-route=\"customizeCoach\"]'))return 'mechanical';\r\n if(globalThis.location?.pathname?.startsWith('/war-room/')||globalThis.location?.pathname?.startsWith('/handborne/'))return 'bloop';\r\n if(el?.closest?.(ELECTRIC))return 'electric';\r\n if(el?.closest?.(INTERNAL)||globalThis.window?.parent!==globalThis.window)return 'bloop';\r\n return el?.closest?.('#start,#coachDock,.control-board')?'main-control':'mechanical';\r\n}\r\nconst CONTROL='button,select,input,summary,[role=\"button\"],[role=\"slider\"],a';\r\n\r\nexport function mountPhysicalSoundUI(){\r\n const sound=physicalSound.mount(),settings=document.getElementById('settings'),abort=new AbortController(),signal=abort.signal;\r\n if(settings){\r\n  const group=document.createElement('details');group.className='settings-group physical-sound-settings';\r\n  group.innerHTML='<summary>Sound effects</summary><div class=\"physical-sound-controls\"><button type=\"button\" data-sound-mute aria-pressed=\"false\">Mute effects</button><label>Effects volume <input type=\"range\" min=\"0\" max=\"100\" step=\"1\" data-sound-volume aria-label=\"Effects volume\"></label><output data-sound-value></output><p>Pod, grimoire, and controls</p><a href=\"/audio/sfx/credits.html\">Sound credits</a></div>';\r\n  settings.querySelector('.voice-row')?.closest('details')?.after(group);\r\n  const mute=group.querySelector('[data-sound-mute]'),volume=group.querySelector('[data-sound-volume]'),value=group.querySelector('[data-sound-value]');\r\n  const paint=()=>{mute.setAttribute('aria-pressed',String(sound.muted));mute.textContent=sound.muted?'Unmute effects':'Mute effects';volume.value=String(Math.round(sound.volume*100));value.value=`${Math.round(sound.volume*100)}%`;};\r\n  mute.addEventListener('click',()=>{sound.setMuted(!sound.muted);if(!sound.muted)sound.play('switch');},{signal});\r\n  volume.addEventListener('input',()=>{sound.setVolume(Number(volume.value)/100);paint();sound.play('electric');},{signal});\r\n  window.addEventListener('myr5:sound-settings',paint,{signal});paint();\r\n  const style=document.createElement('style');style.textContent='.physical-sound-controls{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:10px}.physical-sound-controls label{display:flex;align-items:center;gap:8px}.physical-sound-controls input{width:min(180px,38vw)}.physical-sound-controls p{width:100%;margin:0;opacity:.7}.physical-sound-controls a{font-size:.85em}';document.head.append(style);\r\n  signal.addEventListener('abort',()=>{group.remove();style.remove();},{once:true});\r\n }\r\n const routeControl=(event,doc)=>{\r\n  const target=event.target;if(target?.nodeType!==1)return;\r\n  const el=target.closest(CONTROL);if(!el||el.disabled||el.closest('.physical-sound-settings')||el.matches('.board-marker,[data-room-board],#exerciseDial,#difficultySlider,#harder,#easier,#toggleVoice')||el.id==='portalOverlay')return;\r\n  if(el.matches('input[type=\"range\"],input[type=\"color\"],select'))return;\r\n  sound.play(el.matches('[role=\"switch\"]')?'switch':surfaceCue(el));\r\n };\r\n function bindDocument(doc){\r\n  if(!doc||doc.__myr5SoundBound)return;doc.__myr5SoundBound=true;\r\n  doc.addEventListener('click',event=>routeControl(event,doc),{signal});\r\n  doc.addEventListener('input',event=>{const el=event.target;if(el?.closest?.('.physical-sound-settings'))return;if(el?.matches?.('input[type=\"range\"],input[type=\"color\"]'))sound.play(['mechanical','main-control'].includes(surfaceCue(el))?'dial':surfaceCue(el));},{signal});\r\n  doc.addEventListener('change',event=>{const el=event.target;if(el?.closest?.('.physical-sound-settings'))return;if(el?.matches?.('select,input[type=\"checkbox\"],input[type=\"radio\"]'))sound.play(['mechanical','main-control'].includes(surfaceCue(el))?'switch':surfaceCue(el));},{signal});\r\n  doc.addEventListener('pointerdown',event=>{if(event.target?.closest?.(ELECTRIC)&&!event.target.closest(CONTROL))sound.play('electric');},{signal,passive:true});\r\n }\r\n bindDocument(document);\r\n // The Hand editor boots this module in its own document, including when framed.\r\n window.addEventListener('myr5:portal-sound',event=>{\r\n  const {kind,board,visible}=event.detail||{};\r\n  if(kind==='scene')sound.setScene(visible?'portal':'pod',board||sound.board);\r\n  else if(kind==='board')sound.setBoard(board||'quilt');\r\n  else if(kind==='travel'){sound.play('transit');}\r\n  else if(kind==='press'||kind==='drag'){\r\n   const cue=BOARD_CUES[board||sound.board]||BOARD_CUES.quilt;\r\n   sound.play(cue[kind==='drag'?1:0]);\r\n   if(kind==='press'&&board==='grass')sound.play('grass-tinkle');\r\n  }\r\n  else if(kind==='menu')sound.play('electric');\r\n },{signal});\r\n window.addEventListener('myr5:hardware-detent',event=>sound.play(event.detail?.kind==='lever'?'lever':event.detail?.kind==='switch'?'switch':'dial'),{signal});\r\n window.addEventListener('myr5:reminders-open',()=>{sound.play('dialup');sound.play('signal');},{signal});\r\n window.addEventListener('myr5:classroom-board',()=>sound.play('whiteboard'),{signal});\r\n window.addEventListener('myr5:whiteboard-redraw',()=>sound.play('whiteboard'),{signal});\r\n const openMenus=new Set();\r\n const menuObserver=new MutationObserver(()=>{const current=new Set(document.querySelectorAll('dialog[open]'));for(const menu of current)if(!openMenus.has(menu)&&!menu.matches('#portalWorkoutHome,.meditation-panel'))sound.play(surfaceCue(menu));openMenus.clear();for(const menu of current)openMenus.add(menu);});\r\n menuObserver.observe(document.body,{subtree:true,attributes:true,attributeFilter:['open']});signal.addEventListener('abort',()=>menuObserver.disconnect(),{once:true});\r\n window.addEventListener('myr5:reminders-turn',()=>sound.play('lever'),{signal});\r\n return ()=>{abort.abort();sound.dispose();};\r\n}\r\n","audio/standalone-sound.mjs":"import {mountPhysicalSoundUI} from './sound-ui.mjs';\r\nimport {physicalSound} from './physical-sound.mjs';\r\nimport {mountPageMusic} from './page-music.mjs';\r\nmountPhysicalSoundUI();\r\nmountPageMusic(); // /creature/ and /war-room/ play the customizer song; framed pages leave music to the parent\r\nfunction mountDockSound(){\r\n if(!location.pathname.startsWith('/creature/'))return;\r\n const dock=document.getElementById('coachDock');if(!dock||dock.querySelector('.dock-sound'))return;\r\n const control=document.createElement('div');control.className='cb-part dock-sound';\r\n control.innerHTML='<span class=\"cb-label\" aria-hidden=\"true\">SOUND</span><button type=\"button\" class=\"dock-control\" id=\"editorSoundSwitch\" role=\"switch\" aria-label=\"Sound effects\" aria-checked=\"true\" data-on=\"true\">ON</button>';\r\n dock.insertBefore(control,dock.querySelector('.dock-live'));\r\n const button=control.querySelector('button');\r\n const paint=()=>{const on=!physicalSound.muted;button.dataset.on=String(on);button.setAttribute('aria-checked',String(on));button.textContent=on?'ON':'OFF';};\r\n button.addEventListener('click',()=>{physicalSound.setMuted(!physicalSound.muted);if(!physicalSound.muted)physicalSound.play('switch');});\r\n button.addEventListener('keydown',event=>{const on={ArrowUp:true,ArrowRight:true,ArrowDown:false,ArrowLeft:false}[event.key];if(on===undefined)return;event.preventDefault();if((!physicalSound.muted)!==on)button.click();});\r\n window.addEventListener('myr5:sound-settings',paint);paint();\r\n}\r\nif(document.readyState==='loading')document.addEventListener('DOMContentLoaded',mountDockSound,{once:true});else mountDockSound();\r\nif(location.pathname.startsWith('/war-room/'))physicalSound.setScene('off');\r\nif(window.parent!==window){\r\n physicalSound.setScene('off');\r\n try{const parent=window.parent,forward=event=>window.dispatchEvent(new CustomEvent('myr5:response',{detail:event.detail}));parent.addEventListener('myr5:response',forward);window.addEventListener('pagehide',()=>parent.removeEventListener('myr5:response',forward),{once:true});}catch{}\r\n}\r\n","auth-client.mjs":"import {authTransitions} from './auth-transition.mjs';\r\nimport {safeReturn} from './auth-paths.mjs';\r\n\r\nlet settingsPromise,settingsGen=0;\r\nlet clerkPromise=null; // shared init promise per attempt\r\nlet clerkGen=0; // generation nonce for init\r\nlet clerkIdentityListenerUnsub=null; // current unsubscribe function\r\nlet loginReadyDispatched=false;\r\n\r\nexport function authSettings({force=false}={}){\r\n  if(force){settingsGen++; settingsPromise=null;}\r\n  const gen=settingsGen;\r\n  return settingsPromise ??=(async()=>{\r\n    const res=await fetch(`/api/auth/config?t=${Date.now()}`,{credentials:'same-origin',cache:'no-store',signal:AbortSignal.timeout(5000)});\r\n    if(!res.ok)throw Object.assign(Error('Login could not connect. Please retry.'),{status:res.status,code:'auth-config'});\r\n    return res.json();\r\n  })().then(r=>{\r\n    if(settingsGen===gen){\r\n      if(r.enabled)settingsPromise=r; else settingsPromise=null;\r\n    }\r\n    return r;\r\n  }).catch(e=>{if(settingsGen===gen){settingsPromise=null;}throw e;});\r\n}\r\n\r\nfunction script(src,key){return new Promise((resolve,reject)=>{\r\n  const tag=document.createElement('script');\r\n  tag.src=src;tag.crossOrigin='anonymous';\r\n  if(key)tag.dataset.clerkPublishableKey=key;\r\n  tag.onload=()=>{resolve();};\r\n  tag.onerror=()=>reject(Error('Login could not load. Check your connection and retry.'));\r\n  document.head.append(tag);\r\n});}\r\n\r\nexport function loadLogin(){\r\n  if (clerkPromise) return clerkPromise;\r\n  const attemptGen = ++clerkGen;\r\n\r\n  let deadlineTimer = null;\r\n  const cleanup = () => {\r\n    if (deadlineTimer) {\r\n      clearTimeout(deadlineTimer);\r\n      deadlineTimer = null;\r\n    }\r\n  };\r\n\r\n  const attemptPromise = new Promise((resolve, reject) => {\r\n    const timeoutReject = Object.assign(new Error('Account timed out'),{code:'account_timeout'});\r\n    const raceInit = (async () => {\r\n      try {\r\n        let config;\r\n        try {\r\n          config = await authSettings();\r\n          if (clerkGen !== attemptGen) throw timeoutReject;\r\n        } catch (e) {\r\n          cleanup();\r\n          throw e;\r\n        }\r\n\r\n        if (!config.enabled) {\r\n          cleanup();\r\n          return null;\r\n        }\r\n\r\n        const origin = new URL(config.frontend).origin;\r\n        await script(origin + '/npm/@clerk/ui@1/dist/ui.browser.js');\r\n        if (clerkGen !== attemptGen) throw timeoutReject;\r\n\r\n        await script(origin + '/npm/@clerk/clerk-js@6/dist/clerk.browser.js', config.publishableKey);\r\n        if (clerkGen !== attemptGen) throw timeoutReject;\r\n\r\n        const Clerk = window.Clerk;\r\n        await Clerk.load({ ui: { ClerkUI: window.__internal_ClerkUICtor } });\r\n        if (clerkGen !== attemptGen) throw timeoutReject;\r\n\r\n        const clerk = Clerk;\r\n        authTransitions().observeIdentity('clerk', clerk.session?.id, clerk.user?.id);\r\n\r\n        if (clerkIdentityListenerUnsub) {\r\n          clerkIdentityListenerUnsub();\r\n          clerkIdentityListenerUnsub = null;\r\n        }\r\n\r\n        const observe = () => {\r\n          if (clerkGen === attemptGen) {\r\n            authTransitions().observeIdentity('clerk', clerk.session?.id, clerk.user?.id);\r\n          }\r\n        };\r\n\r\n        clerkIdentityListenerUnsub = clerk.addListener(observe);\r\n\r\n        if (!loginReadyDispatched) {\r\n          window.dispatchEvent(new Event('myr5:login-ready'));\r\n          loginReadyDispatched = true;\r\n        }\r\n\r\n        resolve(clerk);\r\n      } catch (e) {\r\n        cleanup();\r\n        reject(e);\r\n      }\r\n    })();\r\n\r\n    deadlineTimer = setTimeout(() => {\r\n      if (clerkPromise === attemptPromise) {\r\n        clerkGen++;\r\n        cleanup();\r\n        reject(timeoutReject);\r\n      }\r\n    }, 20000);\r\n\r\n    raceInit.then(resolve, reject).finally(cleanup);\r\n  });\r\n\r\n  clerkPromise = attemptPromise;\r\n  clerkPromise\r\n    .then((value) => {cleanup(); if (value===null && clerkPromise===attemptPromise) clerkPromise=null;}, () => {\r\n      cleanup();\r\n      if (clerkPromise === attemptPromise) clerkPromise = null;\r\n    });\r\n\r\n  return attemptPromise;\r\n}\r\nfunction boundedAuthWait(promise,signal,timeoutMs=5000){\r\n  return new Promise((resolve,reject)=>{\r\n    let settled=false;\r\n    const finish=(fn,value)=>{if(settled)return;settled=true;clearTimeout(timer);signal.removeEventListener('abort',aborted);fn(value);}\r\n    const aborted=()=>finish(reject,Object.assign(Error('Account changed. Refresh to continue.'),{code:'auth_transition'}));\r\n    const timer=setTimeout(()=>finish(reject,Object.assign(Error('Account service timed out. Please retry.'),{status:503,code:'account_timeout'})),timeoutMs);\r\n    signal.addEventListener('abort',aborted,{once:true});\r\n    if(signal.aborted)aborted();\r\n    Promise.resolve(promise).then(value=>finish(resolve,value),error=>finish(reject,error));\r\n  });\r\n}\r\n\r\nexport async function authFetch(path,options={}){\r\n  const transitions=authTransitions(),ticket=transitions.capture(),headers=new Headers(options.headers);\r\n  const config=await boundedAuthWait(authSettings(),ticket.signal); // 5s timeout\r\n  transitions.assertCurrent(ticket);\r\n  const provider=localStorage.getItem('myr5-login-provider');\r\n  // Guest probes (guestSkip): with no Clerk sign-in on this device the server can only answer 401 (Clerk off rejects any bearer; browsers never carry the legacy header), so answer it locally and keep the network log clean.\r\n  if(options.guestSkip&&provider!=='clerk')return new Response(JSON.stringify({error:'Sign in to save your progress.'}),{status:401,headers:{'Content-Type':'application/json'}});\r\n  if(config.enabled&&provider==='clerk'){\r\n    const clerk=await boundedAuthWait(loadLogin(),ticket.signal,20000); // 20s timeout\r\n    transitions.assertCurrent(ticket);\r\n    transitions.observeIdentity('clerk',clerk?.session?.id,clerk?.user?.id);\r\n    transitions.assertCurrent(ticket);\r\n    const token=await boundedAuthWait(clerk?.session?.getToken(),ticket.signal); // 5s timeout\r\n    transitions.observeIdentity('clerk',clerk?.session?.id,clerk?.user?.id);\r\n    transitions.assertCurrent(ticket);\r\n    if(!token)throw Object.assign(Error('Sign in to Coach again.'),{status:401});\r\n    headers.set('Authorization','Bearer '+token);\r\n  }\r\n  transitions.assertCurrent(ticket);\r\n  const signal=AbortSignal.any([ticket.signal,...(options.signal?[options.signal]:[]),AbortSignal.timeout(8000)]);\r\n  const response=await fetch(path,{...options,signal,headers,credentials:'same-origin',cache:'no-store'});\r\n  transitions.assertCurrent(ticket);return response;\r\n}\r\n\r\nexport async function signOut(returnTo='/pose.html'){\r\n  try{authTransitions().invalidate();}catch{}\r\n  let provider,timer;try{provider=localStorage.getItem('myr5-login-provider');}catch{}\r\n  try{\r\n    await Promise.race([\r\n      (async()=>{const clerk=window.Clerk||(provider==='clerk'?await loadLogin():null);await clerk?.signOut();})(),\r\n      new Promise(resolve=>{timer=setTimeout(resolve,3000);}),\r\n    ]);\r\n  }catch{}finally{\r\n    clearTimeout(timer);try{localStorage.removeItem('myr5-login-provider');}catch{}\r\n    location.assign(safeReturn(returnTo));\r\n  }\r\n}\r\n","auth-paths.mjs":"export function safeReturn(value, fallback='/pose.html') {\r\n  if(typeof value!=='string'||!value.startsWith('/')||value.startsWith('//')||/[\\\\\\r\\n]/.test(value))return fallback;\r\n  const url=new URL(value,'https://coach.invalid');\r\n  return url.origin==='https://coach.invalid'&&!/^\\/(signin|signout|callback)/.test(url.pathname)?url.pathname+url.search+url.hash:fallback;\r\n}\r\nexport const signInPath=returnTo=>'/signin.html?return_to='+encodeURIComponent(safeReturn(returnTo));\r\n","auth-transition.mjs":"export const AUTH_TRANSITION_KEY='myr5-auth-transition-v1';\r\nexport const AUTH_PROVIDER_KEY='myr5-login-provider';\r\nconst uuid=value=>typeof value==='string'&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value);\r\nexport class AuthTransitionError extends Error{\r\n constructor(code='auth_transition'){super(code==='auth_unavailable'?'Account synchronization is unavailable. Reload to retry.':'Account changed. Refresh to continue.');this.name='AuthTransitionError';this.code=code;}\r\n}\r\n// This coordinator owns no tokens, credentials or account data. All authority\r\n// tickets bind the persisted random transition and an in-memory revision.\r\nexport function createAuthTransition({storage,events,channelFactory,randomUUID}){\r\n let token,revision=0,refreshGeneration=0,controller=new AbortController(),refreshController,channel,blocked=false,identity;\r\n const listeners=new Set();\r\n const notify=()=>{for(const listener of listeners){try{listener();}catch{}}};\r\n const cancel=()=>{revision++;refreshGeneration++;controller.abort();refreshController?.abort();controller=new AbortController();notify();};\r\n const block=()=>{if(!blocked){blocked=true;cancel();}throw new AuthTransitionError('auth_unavailable');};\r\n const read=()=>{try{const value=storage.getItem(AUTH_TRANSITION_KEY);if(!uuid(value))return block();return value;}catch{return block();}};\r\n const current=()=>{if(blocked)throw new AuthTransitionError('auth_unavailable');const value=read();if(value!==token){token=value;cancel();}return value;};\r\n const invalidate=()=>{\r\n  if(blocked)throw new AuthTransitionError('auth_unavailable');\r\n  cancel();\r\n  try{const next=randomUUID();if(!uuid(next))return block();storage.setItem(AUTH_TRANSITION_KEY,next);if(storage.getItem(AUTH_TRANSITION_KEY)!==next)return block();token=next;channel.postMessage({type:'transition',token:next});return next;}catch{return block();}\r\n };\r\n const onStorage=event=>{try{if(event.key===AUTH_TRANSITION_KEY||event.key===null)current();else if(event.key===AUTH_PROVIDER_KEY)invalidate();}catch{}};\r\n const onMessage=()=>{try{current();}catch{}};\r\n try{\r\n  if(!storage||!events?.addEventListener||typeof channelFactory!=='function'||typeof randomUUID!=='function')throw Error();\r\n  token=storage.getItem(AUTH_TRANSITION_KEY);\r\n  if(token===null){token=randomUUID();if(!uuid(token))throw Error();storage.setItem(AUTH_TRANSITION_KEY,token);token=storage.getItem(AUTH_TRANSITION_KEY);}\r\n  if(!uuid(token))throw Error();\r\n  channel=channelFactory('myr5-auth-transition-v1');\r\n  if(!channel?.addEventListener||!channel?.postMessage)throw Error();\r\n  channel.addEventListener('message',onMessage);channel.addEventListener('messageerror',()=>{try{block();}catch{}});events.addEventListener('storage',onStorage);\r\n }catch{blocked=true;controller.abort();}\r\n const capture=()=>{const value=current();return Object.freeze({token:value,revision,signal:controller.signal});};\r\n const isCurrent=ticket=>{try{return !!ticket&&current()===ticket.token&&ticket.revision===revision&&!ticket.signal.aborted&&(ticket.refreshGeneration===undefined||ticket.refreshGeneration===refreshGeneration);}catch{return false;}};\r\n return Object.freeze({\r\n  capture,isCurrent,invalidate,\r\n  assertCurrent(ticket){if(!isCurrent(ticket))throw new AuthTransitionError(blocked?'auth_unavailable':'auth_transition');},\r\n  beginRefresh(){const ticket=capture();refreshController?.abort();refreshController=new AbortController();return Object.freeze({...ticket,refreshGeneration:++refreshGeneration,signal:refreshController.signal});},\r\n  observeIdentity(provider,sessionId,userId){const next=JSON.stringify([provider,sessionId??null,userId??null]);if(identity===undefined){identity=next;return;}if(identity!==next){identity=next;invalidate();}},\r\n  subscribe(listener){listeners.add(listener);return()=>listeners.delete(listener);},\r\n  close(){if(!blocked){blocked=true;cancel();}events?.removeEventListener?.('storage',onStorage);channel?.close?.();},\r\n });\r\n}\r\nlet browserCoordinator;\r\nexport function authTransitions(){\r\n if(!browserCoordinator){let storage;try{storage=globalThis.localStorage;}catch{}\r\n  browserCoordinator=createAuthTransition({storage,events:globalThis.window,channelFactory:typeof globalThis.BroadcastChannel==='function'?name=>new BroadcastChannel(name):undefined,randomUUID:()=>globalThis.crypto.randomUUID()});\r\n }\r\n return browserCoordinator;\r\n}\r\n","battle-pass-page.css":".pass-crt-rack{display:grid;grid-template-columns:38px minmax(0,300px) 38px;justify-content:center;align-items:stretch;gap:5px;width:min(390px,100%);margin:8px auto 0}\r\n.pass-crt-rack>.workout-performance-controls{grid-column:1/-1}\r\n.pass-crt-switch{align-self:stretch;border:2px solid #596d6b;border-radius:5px;background:linear-gradient(120deg,#35464b,#152629 60%,#34474b);box-shadow:inset 0 1px #afc8c885,inset 0 -3px #081415,0 4px 0 #101a1c;color:#b5eacb;font:700 15px ui-monospace,Consolas,monospace;text-shadow:0 0 8px #89ffd8;cursor:pointer}\r\n.pass-crt-switch:active{transform:translateY(3px);box-shadow:inset 0 2px 5px #0009,0 1px 0 #101a1c}\r\n.pass-crt-switch:disabled{opacity:.4;cursor:default}\r\n.pass-crt-switch:focus-visible,.pass-crt-entry:focus-visible{outline:3px solid #ffe2a0;outline-offset:2px}\r\n.battle-pass-entry.pass-crt-entry{position:relative;display:grid;gap:2px;min-width:0;width:100%;margin:0;padding:6px 9px 8px;border:3px solid #546c70;border-radius:7px;background:radial-gradient(ellipse at 50% 35%,#173d3a,#071416 80%);box-shadow:inset 0 0 0 2px #091518,inset 0 0 17px #6dfdb32b,0 3px 0 #41575a;color:#bce5cb;text-align:left;font:600 9px/1.2 ui-monospace,Consolas,monospace;letter-spacing:.06em;cursor:pointer;text-shadow:0 0 5px #72f6aa6e}\r\n.pass-crt-entry strong{font-size:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pass-crt-entry small{font-size:8px;color:#a4c8b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.pass-entry-meter{height:3px;margin-top:2px;background:linear-gradient(90deg,#9ff5bf var(--pass-fill),#28483b var(--pass-fill));box-shadow:0 0 5px #74d99c77}\r\n#battlePassPanel.battle-pass-page{box-sizing:border-box;display:none;flex-direction:column;width:min(1120px,calc(100% - 12px));height:calc(100dvh - 12px);max-height:calc(100dvh - 12px);padding:0;overflow:hidden;border:2px solid #7194a7;border-radius:9px;background:#06101c;color:#e6f4f6;box-shadow:0 0 0 5px #122938,0 16px 60px #000d;font-family:ui-monospace,Consolas,monospace}\r\n#battlePassPanel.battle-pass-page[open]{display:flex}\r\n.battle-pass-page::backdrop{background:#020710dc;backdrop-filter:blur(6px)}\r\n.battle-pass-page button{font:inherit;cursor:pointer}.battle-pass-page button:focus-visible,.pass-map-viewport:focus-visible{outline:3px solid #f8db83;outline-offset:2px}\r\n.pass-header{flex:none;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:42px;padding:3px 12px;border-bottom:1px solid #477785;background:linear-gradient(90deg,#143346,#091e2a 65%,#292541)}\r\n.pass-header h2{margin:0;font-size:clamp(.92rem,2.3vw,1.3rem);letter-spacing:.15em;text-shadow:0 0 18px #73d6ee99}\r\n.pass-flight-score{flex:none;display:flex;justify-content:space-between;gap:8px;padding:7px 12px;border-bottom:1px solid #477785;background:#091d2b;color:#b9faff;font-size:clamp(.68rem,2vw,.9rem);font-variant-numeric:tabular-nums}\r\n.pass-flight-score strong:last-child{color:#ffe4a0;text-shadow:0 0 9px #f2b85980}\r\n.pass-close,.pass-fire{border:2px solid #789dab;border-radius:5px;background:linear-gradient(#294553,#152c39);box-shadow:inset 0 1px #d9f8ff55,0 3px 0 #0a1925;color:#e9faff;text-shadow:0 0 7px #9cefff}\r\n.pass-close{padding:5px 9px;white-space:nowrap;font-size:.72rem!important}\r\n.pass-daily{flex:none;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:3px 8px;margin:5px 8px 0;padding:5px 8px;border:1px solid #548b85;border-left:3px solid #86debb;background:linear-gradient(110deg,#112c35e8,#0a1c2be8)}\r\n.pass-daily h3{margin:0;color:#adf0c7;font-size:.65rem;letter-spacing:.09em;white-space:nowrap}.pass-quests{display:flex;flex-wrap:wrap;gap:3px;justify-content:center}.pass-quests span{padding:2px 5px;border:1px solid #45636e;border-radius:3px;color:#afc4c7;font-size:.62rem;white-space:nowrap}.pass-quests span[data-complete=true]{border-color:#8ad4af;background:#1c453c;color:#c8ffe0}.pass-daily strong{font-size:.64rem;color:#f7d987;white-space:nowrap}.pass-daily small{grid-column:1/-1;color:#a8bbc6;font-size:.61rem;line-height:1.15}\r\n.pass-summary{flex:none;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:3px 10px;margin:5px 8px 0;padding:5px 8px;border:1px solid #4d7790;background:#102534}.pass-summary strong{font-size:1rem;color:#ffe4a0}.pass-summary span{justify-self:end;font-size:.69rem;color:#b6d9e8}.pass-summary progress{grid-column:1/-1;width:100%;height:7px;accent-color:#e9c479}.pass-summary b{font-size:.68rem;color:#eac782;white-space:nowrap}\r\n.pass-map-shell{position:relative;flex:1;min-height:0;isolation:isolate;margin:5px 8px 8px;border:2px solid #587d98;border-radius:8px;background:#071326;box-shadow:inset 0 0 35px #000c,0 0 22px #4181a230;overflow:hidden}\r\n.pass-map-viewport{position:relative;width:100%;height:100%;overflow:auto;scrollbar-color:#7aa0af #071a2d;overscroll-behavior:contain;touch-action:pan-y}\r\n.pass-route{position:relative;isolation:isolate;background:linear-gradient(#030916ef,#070c1cf0),url('/pod/worlds/achievements.jpg') center/auto 1100px repeat-y}\r\n.pass-area{position:relative;min-height:1030px;isolation:isolate;overflow:hidden;border-bottom:2px solid #6ca9c077;background:radial-gradient(circle at 82% 17%,#bd66652a,transparent 35%),radial-gradient(circle at 21% 52%,#414ebd36,transparent 38%),linear-gradient(180deg,#080b24,#0b1732 45%,#071728)}\r\n.pass-area:before{content:'';position:absolute;inset:0;z-index:0;pointer-events:none;background:radial-gradient(ellipse at 65% 16%,#8157b93b,transparent 38%),radial-gradient(ellipse at 25% 70%,#23a7d123,transparent 35%);filter:hue-rotate(var(--world-hue));opacity:calc(.4 + var(--world-intensity)*.6)}\r\n.pass-area[data-chapter=\"0\"]{background:radial-gradient(circle at 79% 22%,#38466924,transparent 21%),linear-gradient(#020612,#091522 65%,#030b17)}\r\n.pass-area[data-chapter=\"9\"],.pass-area[data-chapter=\"10\"]{background:radial-gradient(circle at 76% 18%,#efb94e39,transparent 30%),linear-gradient(#1b1320,#1b2138 50%,#081c30)}\r\n.pass-area[data-chapter=\"14\"],.pass-area[data-chapter=\"18\"]{background:radial-gradient(circle at 75% 17%,#d8315348,transparent 40%),linear-gradient(#1e0c22,#200d27 55%,#080d22)}\r\n.pass-area[data-chapter=\"22\"],.pass-area[data-chapter=\"23\"],.pass-area[data-chapter=\"24\"]{background:radial-gradient(circle at 78% 15%,#9e6be547,transparent 44%),linear-gradient(#09051e,#101039 55%,#060b1f)}\r\n.pass-sky{position:absolute;inset:0;pointer-events:none;opacity:calc(.28 + var(--world-intensity)*.65);background-image:radial-gradient(2px 2px at 15% 12%,#fff 90%,transparent),radial-gradient(2px 2px at 75% 20%,#bde7ff 90%,transparent),radial-gradient(1px 1px at 45% 36%,#fff 90%,transparent),radial-gradient(2px 2px at 85% 63%,#fff 90%,transparent),radial-gradient(1px 1px at 28% 78%,#fff 90%,transparent);background-size:157px 190px,281px 260px,231px 251px,307px 280px,201px 330px}\r\n.pass-planet{position:absolute;top:7%;right:6%;width:clamp(75px,11vw + 60px,230px);aspect-ratio:1;border-radius:50%;pointer-events:none;background:radial-gradient(circle at 28% 25%,#fff8d6a8 1%,#e9bc8ac9 16%,#5767a1e0 45%,#141b4b 70%,#060a23 82%);box-shadow:inset -18px -20px 27px #020715bc,0 0 35px #96a6e266,0 0 90px #674eb443;filter:hue-rotate(var(--world-hue));opacity:calc(.32 + var(--world-intensity)*.6)}\r\n.pass-area[data-chapter=\"0\"] .pass-planet{width:65px;opacity:.42;box-shadow:0 0 12px #afd9ff44}\r\n.pass-area[data-chapter=\"14\"] .pass-planet,.pass-area[data-chapter=\"18\"] .pass-planet{background:radial-gradient(circle at 30% 30%,#fff7b0,#fa853e 30%,#9a1f34 66%,#1d0818 84%);box-shadow:0 0 65px #f26055aa,0 0 140px #c5356270}\r\n.pass-area[data-chapter=\"22\"] .pass-planet,.pass-area[data-chapter=\"23\"] .pass-planet{background:radial-gradient(circle,#050412 27%,#aa75d0 30%,#221143 42%,#050412 64%);box-shadow:0 0 80px #9562c1aa}\r\n.pass-area[data-future=\"true\"]:after,.pass-current-fog{content:'';position:absolute;z-index:2;inset:0;pointer-events:none;background:linear-gradient(#030916b0,#071327b9 55%,#040a18c7)}\r\n.pass-current-fog{bottom:auto;min-height:0}\r\n.pass-world-title{position:relative;z-index:3;display:grid;gap:3px;width:max-content;max-width:70%;padding:24px 5% 0;text-transform:uppercase;letter-spacing:.12em;text-shadow:0 0 12px #000}\r\n.pass-world-title small{font-size:.65rem;color:#efc98c}.pass-world-title b{font-size:clamp(1.05rem,3vw,2rem);color:#d7eaff}.pass-world-title span{font-size:.72rem;color:#a9ccd7}\r\n.pass-constellation{position:absolute;top:25%;right:4%;z-index:1;display:grid;justify-items:center;gap:7px;width:min(35%,245px);text-align:center;filter:drop-shadow(0 0 14px #b991ff70)}\r\n.pass-coach-art{position:relative;width:min(85%,160px);max-height:230px;overflow:hidden;mask-image:radial-gradient(ellipse,#000 55%,transparent 79%);opacity:.85}\r\n.pass-coach-art img{position:absolute;max-width:none;object-fit:fill;filter:contrast(1.15) saturate(1.25) drop-shadow(0 0 10px #cbadff)}\r\n.pass-coach-caption{display:grid;gap:5px;padding:10px;border:1px solid #d9bafb9e;background:radial-gradient(circle at 50% 0,#7e62bf55,transparent 70%),#0e163edb}\r\n.pass-coach-caption span{font-size:.58rem;letter-spacing:.08em;color:#d5baf5}.pass-coach-caption strong{font-size:clamp(.85rem,2vw,1.2rem);color:#fff1ff}.pass-coach-caption small{font-size:.58rem;color:#d1b8f1}.pass-coach-caption p{margin:0;font-size:.62rem;line-height:1.3;color:#dde1f4}\r\n.pass-levels{position:relative;z-index:3;display:grid;gap:19px;list-style:none;margin:0;padding:40px 3% 80px;width:61%;box-sizing:border-box}\r\n.pass-level{display:grid;grid-template-columns:43px minmax(0,1fr) 14px;align-items:center;gap:8px;min-height:62px;padding:6px 9px;border:1px solid #6b879a;border-radius:5px;background:linear-gradient(110deg,#11293de5,#071624ed);box-shadow:0 5px 13px #0008;color:#cbdce8}\r\n.pass-level:nth-child(even){margin-left:7%}.pass-level[data-state=earned]{border-color:#7bb9a0;background:linear-gradient(110deg,#153b3aef,#0b252bf0)}.pass-level[data-state=current]{border:2px solid #f9d888;background:linear-gradient(110deg,#765221f2,#223a49f2);box-shadow:0 0 0 4px #f4d8863b,0 0 30px #eeb96795;color:#fff6dc}.pass-level[data-state=locked]{border-color:#496477;color:#aac0cb;background:#091827e9}\r\n.pass-level-number{display:grid;place-items:center;width:40px;height:40px;border:1px solid currentColor;border-radius:50%;font-size:.92rem}.pass-level-body{display:grid;gap:3px;min-width:0}.pass-level-body strong{font-size:.78rem}.pass-level-body span,.pass-level-body small{font-size:.63rem;color:#b8c9d3}.pass-level[data-state=current] .pass-level-body small{color:#ffe1a2}.pass-level i{font-size:1rem;color:#e6c782;font-style:normal}\r\n.pass-scene{position:absolute;z-index:4;inset:0;width:100%;height:100%;pointer-events:none;image-rendering:pixelated}.pass-fire{position:absolute;z-index:5;right:12px;bottom:12px;min-width:74px;padding:7px 9px;color:#bcfaff}\r\n.workout-performance-controls{display:flex;flex-wrap:wrap;gap:6px;margin:10px 0}.workout-performance-controls button,.workout-performance-controls select{font:inherit;padding:8px;border:1px solid #65758a;background:#121923;color:#eef3fa}.workout-performance-controls[hidden]{display:none}\r\n#cameraWorkout .workout-performance-controls{position:absolute;left:18px;right:18px;bottom:90px;z-index:20;padding:10px;background:#101620e8;justify-content:center}#cameraWorkout .workout-performance-controls p{flex-basis:100%;margin:0;color:#fff;text-align:center}\r\n@media(max-width:650px){\r\n #battlePassPanel.battle-pass-page{width:calc(100% - 6px);height:calc(100dvh - 6px);max-height:calc(100dvh - 6px);border-radius:4px}\r\n .pass-header{min-height:39px;padding:2px 8px}.pass-header h2{font-size:.89rem}\r\n .pass-daily{grid-template-columns:1fr auto;margin:4px 5px 0;padding:4px 6px;gap:3px}.pass-daily h3{font-size:.61rem}.pass-quests{grid-column:1/-1;grid-row:2;justify-content:flex-start}.pass-quests span{font-size:.6rem;padding:2px 4px}.pass-daily strong{grid-column:2;grid-row:1;font-size:.58rem}.pass-daily small{grid-row:3;font-size:.58rem}\r\n .pass-summary{margin:4px 5px 0;padding:4px 6px}.pass-summary strong{font-size:.85rem}.pass-summary span,.pass-summary b{font-size:.59rem}.pass-summary progress{height:6px}\r\n .pass-map-shell{margin:4px 5px 5px}.pass-area{min-height:870px}.pass-world-title{padding-top:18px;max-width:90%}.pass-world-title b{font-size:1.15rem}.pass-world-title small,.pass-world-title span{font-size:.59rem}\r\n .pass-levels{width:67%;gap:15px;padding:36px 1.5% 60px}.pass-level{grid-template-columns:31px minmax(0,1fr) 8px;gap:4px;min-height:57px;padding:5px}.pass-level-number{width:29px;height:29px;font-size:.75rem}.pass-level-body strong{font-size:.62rem}.pass-level-body span,.pass-level-body small{font-size:.54rem}.pass-level i{font-size:.7rem}\r\n .pass-constellation{right:2%;top:26%;width:30%;gap:2px}.pass-coach-art{width:93%;max-height:155px}.pass-coach-caption{padding:5px;gap:3px}.pass-coach-caption span{font-size:.45rem}.pass-coach-caption strong{font-size:.7rem}.pass-coach-caption small,.pass-coach-caption p{font-size:.49rem}\r\n .pass-planet{width:88px}.pass-fire{right:7px;bottom:7px;min-width:58px;padding:6px;font-size:.7rem!important}\r\n}\r\n@media(prefers-reduced-motion:reduce){.pass-planet,.pass-sky,.pass-level{animation:none!important;transition:none!important}}\r\n\r\n/* The CRT is a small star chart for its ten-level sector. */\r\n.pass-map-shell{touch-action:none}\r\n.pass-crt-chart{display:block;width:100%;height:22px;margin:2px 0;overflow:visible}\r\n.pass-crt-line,.pass-crt-branch{fill:none;stroke:#66a9a5;stroke-width:.65;opacity:.75;vector-effect:non-scaling-stroke}\r\n.pass-crt-branch{stroke:#70979a;opacity:.5}\r\n.pass-crt-dot{fill:#536f71;stroke:#9cb7ad;stroke-width:.45;vector-effect:non-scaling-stroke}\r\n.pass-crt-dot.is-earned{fill:#adf8cb;stroke:#e7ffe9;filter:drop-shadow(0 0 2px #90ffb9)}\r\n.pass-crt-dot.is-current{fill:#ffe8a1;stroke:#fff7d9;filter:drop-shadow(0 0 3px #ffe29b)}\r\n\r\n/* Open space, with one unbroken constellation through all 25 sectors. */\r\n.pass-route{background:#030916}\r\n.pass-area,.pass-area[data-chapter=\"0\"],.pass-area[data-chapter=\"9\"],.pass-area[data-chapter=\"10\"],.pass-area[data-chapter=\"14\"],.pass-area[data-chapter=\"18\"],.pass-area[data-chapter=\"22\"],.pass-area[data-chapter=\"23\"],.pass-area[data-chapter=\"24\"]{min-height:1500px;border:0;background:radial-gradient(ellipse at var(--object-x) var(--object-y),hsl(calc(205 + var(--world-intensity)*280) 80% 42% / .14),transparent 28%),radial-gradient(ellipse at 22% 69%,hsl(calc(245 + var(--world-intensity)*190) 65% 35% / .12),transparent 36%),linear-gradient(180deg,#030916,#070e22 52%,#030916)}\r\n.pass-area:before{background:radial-gradient(ellipse at 53% 44%,#40659a22,transparent 48%);opacity:calc(.2 + var(--world-intensity)*.8)}\r\n.pass-sky{opacity:calc(.52 + var(--world-intensity)*.48);background-image:radial-gradient(1px 1px at 15% 12%,#fff 90%,transparent),radial-gradient(2px 2px at 75% 20%,#bde7ff 90%,transparent),radial-gradient(1px 1px at 45% 36%,#fff 90%,transparent),radial-gradient(2px 2px at 85% 63%,#fff 90%,transparent),radial-gradient(1px 1px at 28% 78%,#fff 90%,transparent);background-size:157px 190px,281px 260px,231px 251px,307px 280px,201px 330px}\r\n.pass-planet,.pass-area[data-chapter=\"0\"] .pass-planet,.pass-area[data-chapter=\"14\"] .pass-planet,.pass-area[data-chapter=\"18\"] .pass-planet,.pass-area[data-chapter=\"22\"] .pass-planet,.pass-area[data-chapter=\"23\"] .pass-planet{top:var(--object-y);left:var(--object-x);right:auto;width:clamp(28px,4vw,55px);aspect-ratio:1;transform:translate(-50%,-50%);opacity:calc(.5 + var(--world-intensity)*.5);background:radial-gradient(circle at 30% 27%,#fff6df 1%,#c3d8eb 12%,#638fbd 37%,#1e406b 66%,#08172d 84%);box-shadow:inset -5px -5px 7px #020715,0 0 14px #9ebdff7a;filter:hue-rotate(var(--world-hue))}\r\n.pass-area:nth-child(5n+2) .pass-planet:after,.pass-area:nth-child(5n+3) .pass-planet:after{content:'';position:absolute;inset:36% -30%;border:2px solid #d2d5e899;border-radius:50%;transform:rotate(-24deg)}\r\n.pass-area:nth-child(5n) .pass-planet{border-radius:33% 56% 45% 61%;clip-path:polygon(20% 0,78% 8%,100% 41%,83% 95%,31% 100%,0 65%)}\r\n.pass-area:nth-child(7n) .pass-planet{background:radial-gradient(circle at 34% 29%,#fff6b0,#f7b773 28%,#bd526f 59%,#34153d 82%);box-shadow:0 0 20px #e6859c99}\r\n.pass-route-lines{position:absolute;inset:0;z-index:1;width:100%;height:100%;overflow:visible;pointer-events:none}\r\n.pass-route-main,.pass-route-branch{fill:none;stroke:#77d9ed;stroke-width:1.5;stroke-opacity:.55;vector-effect:non-scaling-stroke;filter:drop-shadow(0 0 4px #52d5f9)}\r\n.pass-route-branch{stroke:#b8a4f3;stroke-width:1;stroke-opacity:.5;stroke-dasharray:3 5}\r\n.pass-area[data-future=\"true\"]:after,.pass-current-fog{z-index:2;background:linear-gradient(#02061170,#03091a82 60%,#02071375)}\r\n.pass-world-title{position:absolute;top:18px;left:5%;z-index:5;gap:2px;padding:0;max-width:90%;text-shadow:0 1px 7px #010511,0 0 14px #79c3ea88}\r\n.pass-world-title small{font-size:.61rem}.pass-world-title b{font-size:clamp(1rem,2.3vw,1.45rem)}.pass-world-title span{font-size:.65rem}\r\n.pass-constellation{top:auto;right:auto;z-index:3;width:min(32vw,180px);transform:translate(-50%,-3px);gap:4px;filter:drop-shadow(0 0 7px #b991ff70)}\r\n.pass-coach-star{display:block;width:10px;height:10px;background:#f7e4ff;transform:rotate(45deg);box-shadow:0 0 0 4px #bc91e14d,0 0 16px 7px #c59bff9c}\r\n.pass-coach-caption{display:grid;gap:2px;padding:0;border:0;background:none;text-shadow:0 1px 5px #010410,0 0 7px #a479d5}\r\n.pass-coach-caption span{font-size:.53rem}.pass-coach-caption strong{font-size:clamp(.72rem,1.5vw,1rem)}.pass-coach-caption small,.pass-coach-caption p{font-size:.55rem}.pass-coach-caption p{line-height:1.15}\r\n.pass-levels{position:absolute;inset:0;z-index:3;display:block;width:auto;margin:0;padding:0}\r\n.pass-level,.pass-level:nth-child(even),.pass-level[data-state=earned],.pass-level[data-state=current],.pass-level[data-state=locked]{position:absolute;top:var(--node-y);left:var(--node-x);display:flex;align-items:center;gap:8px;width:clamp(155px,21vw,205px);min-height:0;margin:0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;transform:translateY(-50%);color:#c5dbe2;text-shadow:0 1px 6px #000,0 0 8px #5ebde375}\r\n.pass-level.is-right,.pass-level.is-right:nth-child(even){flex-direction:row-reverse;transform:translate(-100%,-50%);text-align:right}\r\n.pass-level[data-state=locked]{opacity:.84}.pass-level[data-state=earned]{color:#d6ffe9}.pass-level[data-state=current]{color:#fff3cc;text-shadow:0 0 11px #f8d77c}\r\n.pass-level-number{flex:none;width:30px;height:30px;border:2px solid currentColor;border-radius:50%;background:#0a2030;box-shadow:0 0 10px #78d7ea9a,0 0 0 4px #6fcbdd30;font-size:.72rem;line-height:1}\r\n.pass-level[data-state=earned] .pass-level-number{background:#174a45;box-shadow:0 0 13px #8affc3,0 0 0 4px #87efbd4d}\r\n.pass-level[data-state=current] .pass-level-number{background:#6f552a;box-shadow:0 0 17px #ffe09d,0 0 0 5px #ffdc8a66}\r\n.pass-level-body{gap:2px;min-width:0}.pass-level-body strong{font-size:.72rem;line-height:1.15}.pass-level-body span,.pass-level-body small{font-size:.57rem;line-height:1.1;color:inherit}\r\n.pass-fire,.pass-coach-art{display:none}\r\n@media(max-width:650px){.pass-area,.pass-area[data-chapter=\"0\"],.pass-area[data-chapter=\"9\"],.pass-area[data-chapter=\"10\"],.pass-area[data-chapter=\"14\"],.pass-area[data-chapter=\"18\"],.pass-area[data-chapter=\"22\"],.pass-area[data-chapter=\"23\"],.pass-area[data-chapter=\"24\"]{min-height:1300px}.pass-level,.pass-level:nth-child(even),.pass-level[data-state=earned],.pass-level[data-state=current],.pass-level[data-state=locked]{width:145px;gap:5px}.pass-level-number{width:27px;height:27px;font-size:.65rem}.pass-level-body strong{font-size:.59rem}.pass-level-body span,.pass-level-body small{font-size:.5rem}.pass-constellation{width:30vw}.pass-coach-caption span{font-size:.42rem}.pass-coach-caption strong{font-size:.62rem}.pass-coach-caption small,.pass-coach-caption p{font-size:.44rem}.pass-planet,.pass-area[data-chapter=\"0\"] .pass-planet{width:34px}}\r\n","battle-pass-page.mjs":"import {COSMETIC_LEVEL_XP,cosmeticLevel,coachXpMultiplier,DAILY_TRIO_BONUS} from './progression-rules.mjs';\r\nimport {readPerformanceProgress} from './performance-progress.mjs';\r\nimport {COACH_REQUIREMENTS,STARTER_COACH_IDS} from './performance-catalog.mjs';\r\nimport {syncBattlePass} from './battle-pass.mjs';\r\nimport {coachRequirements,embedAchievements,BOSSES} from './achievements-board.mjs';\r\nimport {CHAPTER_COUNT,chapterForLevel,chapterLevels,chapterWorld,chapterCoach,chapterConstellation} from './level-map-domain.mjs';\r\nimport {mountLevelMapScene} from './level-map-scene.mjs';\r\nimport {mountFlightScroll,sectionScrollTop,hyperDuration,hyperEase,FLIGHT_TUNING} from './flight-scroll.mjs';\r\n\r\nconst node=(tag,value,className)=>{const el=document.createElement(tag);if(value!=null)el.textContent=value;if(className)el.className=className;return el;};\r\nconst localDay=()=>{const d=new Date();return `${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;};\r\nconst format=x=>Math.floor(x).toLocaleString();\r\nconst validShips=new Set(['supportive','direct','analytical','playful','calm','mom']);\r\nfunction selectedShip(){\r\n try{\r\n  const owner=globalThis.myr5AuthenticatedAccount?.user?.id;\r\n  const custom=JSON.parse(localStorage.getItem(`myr5-ship-customization-v1/${owner}`)||'{}');\r\n  const recipe=JSON.parse(localStorage.getItem('myr5-recipe-v1')||'{}');\r\n  const choice=custom.ship||recipe.shipId||recipe.coach;\r\n  return validShips.has(choice)?choice:'supportive';\r\n }catch{return 'supportive';}\r\n}\r\nconst svgNode=(tag,attrs={})=>{const el=document.createElementNS('http://www.w3.org/2000/svg',tag);for(const [key,value] of Object.entries(attrs))el.setAttribute(key,String(value));return el;};\r\nexport function mountBattlePass(){\r\n if(document.getElementById('battlePassPanel'))return;\r\n // R-1017 one achievements page: the CRT is the in-game section menu (bottom of the flight screen). Its arrows pick a\r\n // section (systems 1-25, then the coach constellation at the top); tapping the CRT hyper-jumps the ship there.\r\n const entry=node('button',null,'battle-pass-entry pass-crt-entry');entry.type='button';entry.id='battlePassOpen';\r\n const previewRack=node('div',null,'pass-crt-rack pass-hud');\r\n const previewPrev=node('button','◀','pass-crt-switch'),previewNext=node('button','▶','pass-crt-switch');\r\n for(const [button,label] of [[previewPrev,'Previous section'],[previewNext,'Next section']]){\r\n  button.type='button';button.setAttribute('aria-label',label);\r\n }\r\n previewRack.append(previewPrev,entry,previewNext);\r\n const dialog=node('dialog',null,'launch-panel battle-pass-page');dialog.id='battlePassPanel';dialog.setAttribute('aria-labelledby','battlePassTitle');\r\n const header=node('header',null,'pass-header'),heading=node('h2','ACHIEVEMENTS / XP FLIGHT');heading.id='battlePassTitle';\r\n const close=node('button','CLOSE','pass-close');close.type='button';close.onclick=()=>dialog.close();header.append(heading,close);\r\n // R-1017: the game fills the panel. Score, level bar and the daily quests (a one-line chip that expands) ride in a slim\r\n // band across the top of the game screen; the CRT section menu is a band along its bottom. Nothing in the scene draws under either.\r\n const daily=node('details',null,'pass-daily'),summary=node('section',null,'pass-summary'),topHud=node('div',null,'pass-top-hud');\r\n const shell=node('section',null,'pass-map-shell');shell.setAttribute('aria-label','Continuous cosmetic reward flight map');\r\n const viewport=node('div',null,'pass-map-viewport');viewport.tabIndex=0;viewport.setAttribute('role','region');viewport.setAttribute('aria-label','The coach constellation at the top, then all 250 levels down to level 1 at the bottom. Scroll to inspect.');\r\n const route=node('div',null,'pass-route');viewport.append(route);\r\n const canvas=node('canvas',null,'pass-scene');canvas.setAttribute('aria-hidden','true');\r\n shell.append(topHud,viewport,canvas,previewRack);\r\n const flightScore=node('div',null,'pass-flight-score');flightScore.setAttribute('aria-label','Asteroid flight score');\r\n const hits=node('strong'),score=node('strong'),multiplier=node('strong');\r\n flightScore.append(hits,score,multiplier);flightScore.title='Each hit earns the current multiplier in flight points, then increases it by one. An asteroid passing the bottom resets the multiplier to ×1.';\r\n topHud.append(flightScore,summary,daily);\r\n dialog.append(header,shell);document.body.append(dialog);\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n const scene=mountLevelMapScene(canvas,{ship:selectedShip(),reducedMotion:reduced.matches,onScore:state=>{\r\n  hits.textContent=`HITS ${format(state.hits)}`;score.textContent=`SCORE ${format(state.score)}`;multiplier.textContent=`×${format(state.multiplier)}`;\r\n  flightScore.dataset.multiplier=String(state.multiplier);\r\n }});\r\n let previewChapter=0,rank=null,performance=null,hasPreviewSelection=false,renderedLevel=0,board=null;\r\n function renderPreview(){\r\n  if(!rank)return;\r\n  previewPrev.disabled=previewChapter===0;previewNext.disabled=previewChapter===CHAPTER_COUNT;\r\n  if(previewChapter===CHAPTER_COUNT){\r\n   const golden=performance?.goldenCoaches?.length||0;\r\n   entry.replaceChildren(node('strong','COACH CONSTELLATION'),node('small',`${performance?.coaches?.length||0} / ${BOSSES.length} COACHES · ${golden} GOLDEN`),node('small','» TAP TO HYPERJUMP'));\r\n   entry.setAttribute('aria-label','Hyperjump to the coach constellation');return;\r\n  }\r\n  const world=chapterWorld(previewChapter),levels=chapterLevels(previewChapter,COSMETIC_LEVEL_XP);\r\n  const current=previewChapter===chapterForLevel(rank.level);\r\n  const line1=`SYSTEM ${String(previewChapter+1).padStart(2,'0')} / 25 · ${world.name.toUpperCase()}`;\r\n  const line2=current?(rank.max?'LEVEL 250 COMPLETE':`LV ${rank.level} · ${Math.ceil(rank.next-rank.xp).toLocaleString()} XP TO NEXT`):`LEVELS ${levels[0].level}–${levels.at(-1).level} · ${format(levels[0].xp)}–${format(levels.at(-1).xp)} XP`;\r\n  const line3='10 PACKS · » TAP TO HYPERJUMP';\r\n  entry.classList.add('pass-crt-entry');\r\n  const meter=node('span',null,'pass-entry-meter');meter.setAttribute('aria-hidden','true');meter.style.setProperty('--pass-fill',`${current?(rank.max?100:Math.max(0,Math.min(100,rank.into/rank.need*100))):0}%`);\r\n  const chart=svgNode('svg',{class:'pass-crt-chart',viewBox:'0 0 100 29','aria-hidden':'true',preserveAspectRatio:'none'});\r\n  const positions=[[4,20],[14,8],[25,18],[36,6],[46,21],[57,11],[68,22],[78,7],[89,18],[98,6]];\r\n  chart.append(svgNode('path',{d:`M ${positions.map(([x,y])=>`${x} ${y}`).join(' L ')}`,class:'pass-crt-line'}));\r\n  chart.append(svgNode('path',{d:'M 36 6 L 43 2 M 68 22 L 75 27',class:'pass-crt-branch'}));\r\n  for(let index=0;index<levels.length;index++){\r\n   const [x,y]=positions[index],level=levels[index].level;\r\n   chart.append(svgNode('rect',{x:x-1.3,y:y-1.3,width:2.6,height:2.6,class:`pass-crt-dot ${level<rank.level?'is-earned':level===rank.level?'is-current':'is-locked'}`}));\r\n  }\r\n  entry.replaceChildren(node('strong',line1),node('small',line2),chart,node('small',line3),meter);\r\n  entry.setAttribute('aria-label',`Hyperjump to system ${previewChapter+1}, ${world.name}, levels ${levels[0].level} through ${levels.at(-1).level}`);\r\n }\r\n function renderDaily(p){\r\n  const day=p.days?.[localDay()]||{};\r\n  const workout=Number(day.workoutXp??day.baseXp??0)>0||!!day.workout,meditation=!!day.meditation,food=!!day.food;\r\n  const quests=node('div',null,'pass-quests');\r\n  for(const [label,complete] of [['Workout',workout],['Meditation ×2',meditation],['Food',food]]){\r\n   const item=node('span',`${complete?'✓':'○'} ${label}`);item.dataset.complete=String(complete);quests.append(item);\r\n  }\r\n  const coaches=p.coaches.filter(id=>!STARTER_COACH_IDS.includes(id)).length;\r\n  const done=[workout,meditation,food].filter(Boolean).length,chip=node('summary',null,'pass-daily-chip');\r\n  chip.append(node('span',`DAILY ${done}/3`),node('strong',done===3?`✓ +${DAILY_TRIO_BONUS} XP EARNED`:`ALL THREE +${DAILY_TRIO_BONUS} XP`));\r\n  chip.setAttribute('aria-label',`Today's daily quests, ${done} of 3 done. Show details`);\r\n  daily.replaceChildren(chip,quests,node('small',`Meditation doubles workout XP · coach multiplier ×${coachXpMultiplier(coaches)}`));\r\n }\r\n function renderSummary(){\r\n  const progress=node('progress');progress.max=rank.max?1:rank.need;progress.value=rank.max?1:rank.into;progress.setAttribute('aria-label','Progress to next cosmetic level');\r\n  summary.replaceChildren(node('strong',`LV ${rank.level} / 250`),node('span',`${format(rank.xp)} TOTAL XP`),progress,node('b',rank.max?'ALL LEVELS REACHED':`${Math.ceil(rank.next-rank.xp).toLocaleString()} XP → LV ${rank.level+1}`));\r\n }\r\n function buildArea(chapter){\r\n  const world=chapterWorld(chapter),levels=chapterLevels(chapter,COSMETIC_LEVEL_XP),coach=chapterCoach(chapter,COACH_REQUIREMENTS),geometry=chapterConstellation(chapter);\r\n  const area=node('section',null,'pass-area');area.dataset.chapter=String(chapter);area.dataset.future=String(chapter>chapterForLevel(rank.level));\r\n  area.style.setProperty('--world-intensity',world.intensity);area.style.setProperty('--world-hue',`${205+chapter*12}deg`);\r\n  area.style.setProperty('--object-x',`${chapter%2?13:81}%`);area.style.setProperty('--object-y',`${16+(chapter*11)%19}%`);\r\n  area.setAttribute('aria-label',`System ${chapter+1}: ${world.name}, levels ${levels[0].level} through ${levels.at(-1).level}`);\r\n  const sky=node('div',null,'pass-sky'),planet=node('div',null,'pass-planet');\r\n  sky.setAttribute('data-peer-depth','far');planet.setAttribute('data-peer-depth','mid');sky.setAttribute('aria-hidden','true');planet.setAttribute('aria-hidden','true');\r\n  const lines=svgNode('svg',{class:'pass-route-lines',viewBox:'0 0 100 100',preserveAspectRatio:'none','aria-hidden':'true'});\r\n  lines.append(svgNode('path',{d:geometry.main,class:'pass-route-main'}),svgNode('path',{d:geometry.branch,class:'pass-route-branch'}));\r\n  area.append(sky,planet,lines);\r\n  const title=node('div',null,'pass-world-title');\r\n  title.append(node('small',`SYSTEM ${String(chapter+1).padStart(2,'0')} / 25 · LEVELS ${levels[0].level}–${levels.at(-1).level}`),node('b',world.name),node('span',world.body));\r\n  area.append(title);\r\n  const constellation=node('aside',null,'pass-constellation');constellation.setAttribute('data-peer-depth','mid');\r\n  constellation.style.left=`${geometry.coach.x}%`;constellation.style.top=`${geometry.coach.y}%`;\r\n  if(coach){\r\n   const star=node('span',null,'pass-coach-star');star.setAttribute('aria-hidden','true');\r\n   const caption=node('div',null,'pass-coach-caption');\r\n   const requirement=coachRequirements(coach.id);\r\n   caption.append(node('span','COACH CONSTELLATION'),node('strong',coach.name),node('small',performance?.coaches.includes(coach.id)?'PERFORMANCE UNLOCKED':'PERFORMANCE MILESTONE'),node('p',requirement?.unlock||'Earn through a workout milestone.'));\r\n   constellation.append(star,caption);\r\n  }\r\n  area.append(constellation);\r\n  const track=node('ol',null,'pass-levels');track.setAttribute('aria-label',`Cosmetic rewards in system ${chapter+1}, highest level first`);\r\n  for(const [index,item] of [...levels].reverse().entries()){\r\n   const point=geometry.nodes[index],row=node('li',null,`pass-level ${point.x>50?'is-right':'is-left'}`);\r\n   row.style.setProperty('--node-x',`${point.x}%`);row.style.setProperty('--node-y',`${point.y}%`);\r\n   row.dataset.level=String(item.level);row.dataset.state=item.level<rank.level?'earned':item.level===rank.level?'current':'locked';\r\n   if(item.level===rank.level)row.setAttribute('aria-current','step');\r\n   const body=node('div',null,'pass-level-body');\r\n   body.append(node('strong',item.level===1?'Starter cosmetics':`${item.tier} cosmetic pack`),node('span',item.level===1?'Your launch kit':`${format(item.xp)} XP threshold`));\r\n   if(item.level===rank.level)body.append(node('small',rank.max?'Final level reached':`${Math.ceil(rank.next-rank.xp).toLocaleString()} XP to next unlock`));\r\n   row.append(node('b',String(item.level),'pass-level-number'),body);track.append(row);\r\n  }\r\n  area.append(track);\r\n  if(chapter===chapterForLevel(rank.level)){\r\n   const fog=node('div',null,'pass-current-fog');fog.setAttribute('aria-hidden','true');area.append(fog);\r\n   const currentIndex=levels.at(-1).level-rank.level;\r\n   fog.style.height=`${geometry.nodes[currentIndex].y}%`;\r\n  }\r\n  return area;\r\n }\r\n function buildMap(){\r\n  const fragment=document.createDocumentFragment();\r\n  for(let chapter=CHAPTER_COUNT-1;chapter>=0;chapter--)fragment.append(buildArea(chapter));\r\n  route.replaceChildren(fragment);renderedLevel=rank.level;\r\n }\r\n function render({resetPreview=false}={}){\r\n  const p=readPerformanceProgress();performance=p;rank=cosmeticLevel(p.totalXp);\r\n  if(resetPreview||!hasPreviewSelection)previewChapter=chapterForLevel(rank.level);\r\n  renderPreview();renderDaily(p);renderSummary();scene.setShip(selectedShip());\r\n  if(dialog.open&&renderedLevel!==rank.level){\r\n   const oldScroll=viewport.scrollTop;buildMap();viewport.scrollTop=oldScroll;\r\n  }\r\n }\r\n previewPrev.onclick=()=>{hasPreviewSelection=true;previewChapter=Math.max(0,previewChapter-1);renderPreview();};\r\n previewNext.onclick=()=>{hasPreviewSelection=true;previewChapter=Math.min(CHAPTER_COUNT,previewChapter+1);renderPreview();};\r\n // Content y (px down the scroller) of a section's marker: the constellation's top, your level, or a system's first level.\r\n const contentY=el=>el.getBoundingClientRect().top-viewport.getBoundingClientRect().top+viewport.scrollTop;\r\n function sectionTarget(chapter){\r\n  if(chapter===CHAPTER_COUNT)return 0;\r\n  const row=chapter===chapterForLevel(rank.level)?route.querySelector('[aria-current=\"step\"]'):route.querySelector(`[data-level=\"${chapter*10+1}\"]`);\r\n  return row?sectionScrollTop(contentY(row)+row.offsetHeight/2,viewport.clientHeight,viewport.scrollHeight):viewport.scrollTop;\r\n }\r\n // On open the ship rests just under the golden coach (the last one); flying up scrolls the constellation.\r\n const coachStart=()=>board?sectionScrollTop(board.root.offsetTop+board.stage.offsetHeight*.85,viewport.clientHeight,viewport.scrollHeight,FLIGHT_TUNING.coachLine):0;\r\n let jump=0;\r\n const endJump=()=>{if(jump)cancelAnimationFrame(jump);jump=0;scene.setWarp(0);delete dialog.dataset.hyper;};\r\n // Hyper-speed: the page rushes to the section (eased), the scene streaks at the scroll speed. Reduced motion: a cut.\r\n function hyperJump(chapter){\r\n  endJump();stopPointer();\r\n  const from=viewport.scrollTop,to=sectionTarget(chapter),dist=to-from;\r\n  if(reduced.matches||Math.abs(dist)<2){viewport.scrollTop=to;return;}\r\n  const dur=hyperDuration(dist);let t0=null,last=from,lastT=0; // (performance is the progress object in this scope)\r\n  dialog.dataset.hyper='true';\r\n  const step=now=>{\r\n   if(t0===null)t0=lastT=now;\r\n   const u=Math.min(1,(now-t0)/dur),y=from+dist*hyperEase(u);viewport.scrollTop=y;\r\n   scene.setWarp(-(y-last)/Math.max(1,now-lastT));last=y;lastT=now;\r\n   if(u<1)jump=requestAnimationFrame(step);else endJump();\r\n  };\r\n  jump=requestAnimationFrame(step);\r\n }\r\n entry.onclick=()=>hyperJump(previewChapter);\r\n let activePointer=null;\r\n const flightScroll=mountFlightScroll(viewport);\r\n const stopPointer=()=>{activePointer=null;flightScroll.stop();scene.stopFiring();};\r\n shell.addEventListener('pointerdown',e=>{\r\n  if(jump&&!e.target.closest('button'))endJump();\r\n  if(activePointer!==null||!e.isPrimary||e.button!==0||e.target.closest('button,a,input,textarea,select,summary,[contenteditable],.pass-top-hud,.pass-hud'))return;\r\n  e.preventDefault();activePointer=e.pointerId;shell.setPointerCapture(e.pointerId);\r\n  scene.aim(e.clientX,e.clientY);flightScroll.aim(e.clientY);scene.startFiring();\r\n });\r\n document.addEventListener('pointermove',e=>{if(e.pointerId===activePointer&&dialog.open){e.preventDefault();scene.aim(e.clientX,e.clientY);flightScroll.aim(e.clientY);}});\r\n shell.addEventListener('lostpointercapture',stopPointer);\r\n document.addEventListener('pointerup',e=>{if(e.pointerId===activePointer)stopPointer();});\r\n document.addEventListener('pointercancel',e=>{if(e.pointerId===activePointer)stopPointer();});\r\n window.addEventListener('blur',stopPointer);\r\n  dialog.addEventListener('keydown',e=>{if(e.code==='Space'&&!e.repeat&&!e.altKey&&!e.ctrlKey&&!e.metaKey&&!e.target.closest('button,input,textarea,select')){e.preventDefault();scene.fire();}});\r\n dialog.addEventListener('close',()=>{endJump();stopPointer();scene.stop();window.dispatchEvent(new CustomEvent('myr5:music-scene',{detail:{scene:null}}));});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden){stopPointer();scene.stop();}else if(dialog.open)scene.start();});\r\n window.addEventListener('resize',()=>{if(dialog.open)scene.resize();});\r\n const open=()=>{\r\n  syncBattlePass();render();\r\n  if(!dialog.open){scene.resetScore?.();dialog.showModal();window.dispatchEvent(new CustomEvent('myr5:music-scene',{detail:{scene:'battlepass'}}));}\r\n  if(!board){board=embedAchievements(dialog,shell);viewport.prepend(board.root);}\r\n  buildMap();board.open();hasPreviewSelection=false;previewChapter=chapterForLevel(rank.level);renderPreview();\r\n  requestAnimationFrame(()=>{if(dialog.open)viewport.scrollTop=coachStart();});\r\n  scene.start();return dialog;\r\n };\r\n window.myr5Menus={...window.myr5Menus,battlePass:open,achievements:open};\r\n window.addEventListener('myr5:performance-progress',()=>{syncBattlePass();render();});\r\n window.addEventListener('myr5:account-ready',()=>render());\r\n window.addEventListener('storage',()=>render());\r\n render();\r\n}\r\n","battle-pass-rewards.mjs":"import {shipDetails} from './modules/ships/ship-catalog.mjs';\r\n// Battle-pass reward table (rank 6b) — pure data + one lookup, no storage, no DOM.\r\n// Board rows are D30 (the owner's achievements board, plan/handoff/achievements-board);\r\n// item content is plan/muse/item-catalog.json, copied row-for-row below because this worktree\r\n// has no plan/ dir at build time and root .json files are left out of the AGPL source offer\r\n// (scripts/build.mjs). Regenerate by hand if the catalog changes. Food rows and the `keys`\r\n// list are not copied: D32 gives Food no weapons/pet/boss (only palettes + bonuses, below), and\r\n// keys are not pass rewards.\r\n//\r\n// Ladder per boss = D22 (L1 weapon 1 · L2 palette + boss texture · L3 weapon 2 · L4 pet ·\r\n// L5 aura + boss skin) + D16 (the style's 3 textures at L1/L3/L5) + D17 (special at L3) —\r\n// the same text as the board's LEVELS. D30 vs D21: D21 has one boss per family; D30 has rows\r\n// of 3–6 consecutive bosses per track plus two shared ones. Following D30:\r\n//  - boss looks (texture L2, skin L5) belong to each board boss, not to the family;\r\n//  - a style's catalog items (2 weapons, 3 textures, special, aura, palette) exist once, so\r\n//    they sit on the row's FIRST boss; D32 fills the other bosses' empty L1/L3/L4 with palettes\r\n//    from creature/source/creator/palettes.json (each row's `reward` names its slot);\r\n//  - D21 sharing still applies to pets: one pet per family, and the second row of a family\r\n//    gets that family's substitute palette at L4 instead (resolved in battle-pass.mjs).\r\n\r\nimport PALETTES from './creature/source/creator/palettes.json' with {type:'json'};\r\nimport SKIN_CATALOG from './creature/source/creator/creature-skins.json' with {type:'json'};\r\nimport {FOOD_BONUS_DAMAGE_MULTIPLIER} from './combat-config.mjs';\r\nimport {STYLES as LEGACY_STYLES} from './creature/source/creator/catalog.ts';\r\nimport {FREE_TEXTURE_IDS,RETIRED_TEXTURE_IDS} from './creature/source/creator/texture-policy.mjs';\r\nexport {FREE_TEXTURE_IDS};\r\n\r\n// D30 rows, top to bottom — ids/order/counts must match achievements-board.mjs TIERS.\r\nexport const ROWS=Object.freeze([\r\n {id:'strider',name:'Strider',track:'chest',bosses:6},\r\n {id:'ringer',name:'Ringer',track:'quads',bosses:5},\r\n {id:'manyarm',name:'Manyarm',track:'glutes',bosses:5},\r\n {id:'wedge',name:'Wedge',track:'arms-shoulders',bosses:5},\r\n {id:'warden',name:'Warden',track:null,bosses:1},\r\n {id:'blob',name:'Blob',track:'yoga',bosses:4},\r\n {id:'cap',name:'Cap',track:'martial-arts',bosses:3},\r\n {id:'stalk',name:'Stalk',track:'cardio',bosses:4},\r\n {id:'tanka',name:'Tanka',track:'meditation',bosses:4},\r\n {id:'lume',name:'Lume',track:null,bosses:1},\r\n]);\r\nexport const LEVELS_PER_BOSS=5;\r\n// Same ids/names the board builds: `${row}-${k}`, name numbered only in multi-boss rows.\r\nexport const BOSSES=Object.freeze(ROWS.flatMap(row=>Array.from({length:row.bosses},(_,i)=>({\r\n id:`${row.id}-${i+1}`,name:row.bosses>1?`${row.name} ${i+1}`:row.name,row:row.id,track:row.track,index:i+1,\r\n}))));\r\n\r\n// D25 track -> circuit.mjs step-track id, item-catalog `track`, D21 family, L2 palette.\r\n// Palettes: L2 reuses the aura-milestone palettes (pal-01…12) — one per row, plus one D21\r\n// substitute per two-row family. Every other palette slot comes from palettes.json `reward`.\r\nexport const TRACKS=Object.freeze({\r\n chest:{circuit:'chest',catalog:'chest',family:'push',name:'Chest',palette:'pal-01'},\r\n quads:{circuit:'legs',catalog:'quads',family:'legs',name:'Quads',palette:'pal-02'},\r\n glutes:{circuit:'hips',catalog:'glutes',family:'legs',name:'Glutes',palette:'pal-03'},\r\n 'arms-shoulders':{circuit:'shoulders',catalog:'arms',family:'push',name:'Arms & Shoulders',palette:'pal-04'},\r\n yoga:{circuit:'yoga',catalog:'yoga',family:'flow',name:'Yoga',palette:'pal-05'},\r\n 'martial-arts':{circuit:'martial-arts',catalog:'martial-arts',family:'motion',name:'Martial Arts',palette:'pal-06'},\r\n cardio:{circuit:'cardio',catalog:'cardio',family:'motion',name:'Cardio',palette:'pal-07'},\r\n meditation:{circuit:'meditation',catalog:'meditation',family:'meditation',name:'Meditation',palette:'pal-08'},\r\n});\r\nexport const PET_SUBSTITUTE_PALETTE=Object.freeze({push:'pal-09',legs:'pal-10',motion:'pal-11'});\r\n\r\n// Two additive post-download skin collections: all collection slots repeat at L1/L3/L5.\r\n// This distribution depends only on each track's own ladder, never family grouping.\r\nexport const CREATURE_SKIN_REWARDS=Object.freeze(SKIN_CATALOG.skins.map(skin=>Object.freeze({\r\n kind:'creature-skin',id:skin.id,name:skin.displayName,line:`${skin.realm} creature finish · ${skin.rarity}`,\r\n track:skin.track,level:skin.runtime.unlock.level,pack:skin.runtime.pack,collection:skin.collection,\r\n})));\r\n\r\n// Every track receives a midpoint and end milestone, cycling six unique ships.\r\n// Duplicate grants are idempotent; family/grouping does not affect placement.\r\nconst SHIPS=['supportive','direct','analytical','playful','calm','mom'];\r\nexport const SHIP_DEFINITIONS=Object.freeze(Object.values(TRACKS).flatMap(({catalog:track},index)=>\r\n [3,5].map((level,slot)=>{const ship=SHIPS[(index*2+slot)%SHIPS.length];return Object.freeze({id:`ship-${ship}`,ship,name:shipDetails(ship).name,track,level});})\r\n));\r\n\r\n// --- item-catalog.json `weapons` (D21: 2 per style) ---\r\nconst WEAPONS=[\r\n ['chest-w1','Glove on a Stick','For winning arguments with the air.'],['chest-w2','Chrome Bar Mace','It benches you.'],\r\n ['arms-w1','Dumbbellchucks','Twice the dumbbell, half the coordination.'],['arms-w2','Pull-Up Staff','For reaching the top shelf of victory.'],\r\n ['quads-w1','Squat-Rack Axe','Leg day has a new ambassador.'],['quads-w2','Kettlebell Flail','Swings hard, asks questions never.'],\r\n ['glutes-w1','Band Slingshot','Resistance is futile. Literally.'],['glutes-w2','Hip-Thrust Hammer','Bridges: now with consequences.'],\r\n ['yoga-w1','Mat Bo Staff','Rolled with intention. Swung with more.'],['yoga-w2','Block Gauntlets','Namaste out of the way.'],\r\n ['martial-arts-w1','Black-Belt Whip','It earned its own belt.'],['martial-arts-w2','Dummy Club','The dummy saw it coming. Still lost.'],\r\n ['cardio-w1','Jump-Rope Lasso','For roping runaway heart rates.'],['cardio-w2','Shoe Boomerang','It always comes back. Like soreness.'],\r\n ['meditation-w1','Singing-Bowl Aegis','Om. Also, clang.'],['meditation-w2','Incense Wand','Smells like victory. Allegedly.'],\r\n];\r\n// --- item-catalog.json `textures` (D14: 3 per style, slot order = texture-1/2/3; ids match materials-registry.ts) ---\r\nconst TEXTURES=[\r\n ['chest-plate-steel','Plate Steel','Now with 40% more clank.'],['chest-rubber-grip','Rubber Grip','For hands that mean business.'],['chest-chain-mail','Chain Mail','Medieval. But make it cardio.'],\r\n ['quads-track-rubber','Track Rubber','Smells faintly of starting blocks.'],['quads-denim','Denim','For legs that never skip jeans either.'],['quads-hex-tread','Hex Tread','Grip: gecko-grade.'],\r\n ['glutes-sweatshirt-fleece','Sweatshirt Fleece','Like a hug from laundry day.'],['glutes-quilted','Quilted','Grandma approved. Gains approved harder.'],['glutes-peach','Speckled','Ripe. Do not squeeze the coach.'],\r\n ['arms-hammered-bronze','Hammered Bronze','Shiny. Slightly dented. Like all of us.'],['arms-rope','Fine Stripe','Climb every metaphor.'],['arms-leather','Snake Skin','Broken in. Like you, after set three.'],\r\n ['yoga-cork','Holey','Floats. Like your downward dog.'],['yoga-woven-mat','Woven Mat','Hand-woven by extremely calm spiders.'],['yoga-petal','Petal','Delicate. Unlike your warrior two.'],\r\n ['martial-arts-canvas-gi','Graph Paper','It has seen things. Mostly laundry.'],['martial-arts-bamboo','Bamboo','Bends. Does not break. Unlike resolutions.'],['martial-arts-dragon-scale','Dragon Scale','The dragon is fine. It donated.'],\r\n ['cardio-mesh','Cool Graph Paper','Maximum airflow. Minimum excuses.'],['cardio-terry-cloth','Terry Cloth','Absorbs sweat and bad decisions.'],['cardio-pebble-path','Pebble Path','A tiny trail, wherever you go.'],\r\n ['meditation-sand-garden','Wiggles','Raked by a very patient rake.'],['meditation-river-stone','River Stone','Smooth. Unbothered. Goals.'],['meditation-moss','Moss','Grows on you. Literally, now.'],\r\n];\r\n// #140 (D45; slots approved D47): the once-free legacy textures (materials-registry.ts `legacy-<n>`,\r\n// names = catalog.ts STYLES) are battle-pass rewards now, each in the slot of a catalog texture above,\r\n// which became free instead. The ONE swap table; materials-registry.ts derives its locks from it.\r\n// Reshuffle = move a legacy row to another freed id. freed catalog id -> [legacy id, name, line].\r\nexport const TEXTURE_SWAP=Object.freeze({\r\n 'chest-rubber-grip':['legacy-15','Magma','Runs hot. Cools never.'], // Chest L3\r\n 'glutes-sweatshirt-fleece':['legacy-13','Stone Golem','Built slow. Built to last.'], // Glutes L1 (Ian's \"rock golem\")\r\n 'arms-rope':['legacy-14','Crystal','Clear eyes. Sharp facets.'], // Arms L3\r\n 'arms-leather':['legacy-8','Spectral','Here in spirit. Also in body.'], // Arms L5\r\n 'yoga-cork':['legacy-20','Fluffy','Maximum floof. Minimum mercy.'], // Yoga L1\r\n 'yoga-woven-mat':['legacy-21','Jelly','Wobbles. Never falls.'], // Yoga L3 (R25: Jelly is retired; the id only keeps this slot's earned pack id stable)\r\n 'cardio-terry-cloth':['legacy-16','Glacial','Cool under pressure. Very cool.'], // Cardio L3\r\n});\r\n// --- item-catalog.json `bosses` (unlock lines reused for every board boss of that family) ---\r\nconst BOSS_LINES={\r\n push:['Forged from lost remote controls.','For the comfiest conqueror.'],\r\n legs:['Always moving. Never in a hurry.','Polished by a thousand commutes.'],\r\n motion:['Nine more minutes. Forever.','Shiny. Like your intentions at 6 AM.'],\r\n flow:['Eight arms. Zero flexibility.','Breathe in. The kraken breathes out.'],\r\n meditation:['99+ unread. All of them urgent.','Silent. At last.'],\r\n};\r\n// --- item-catalog.json `pets` (D21: one per family; the catalog leaves names null) ---\r\nconst PET_LINES={\r\n push:'It followed you home from the gym. Keep it.',legs:'It never skips leg day. It never skips anything.',\r\n motion:'Fast. Loud. Naps hard.',flow:'Bends in ways physics dislikes.',meditation:'It hums when you breathe. Do not ask how.',\r\n};\r\n\r\nconst item=(kind,[id,name,line])=>({kind,id,name,line});\r\nconst rewardPack=(tier,id)=>({kind:'reward-pack',id:`reward-pack:${tier}:${id}`,tier,name:`${tier[0].toUpperCase()+tier.slice(1)} Pack`,line:'Open for one random cosmetic.'});\r\n// The five free texture IDs live in texture-policy.mjs; catalog additions go to packs.\r\n// catalog.ts STYLES names, id order (legacy-<n> textures; legacy-color-<n> colours are \"<name> (original)\").\r\nexport const LEGACY_NAMES=Object.freeze(['Mortal','Verdant','Mycelial','Chitin','Reptilian','Abyssal','Coral','Skeletal','Spectral','Infernal','Celestial','Voidborn','Eldritch','Stone Golem','Crystal','Magma','Glacial','Stormcharged','Clockwork Robot','Neon Synth','Fluffy','Jelly','Baby']);\r\n// The texture pack pool: every non-free texture, once. (TEXTURE_SWAP below only decides which texture a\r\n// battle-pass slot names; the pack pool never depends on it, so no texture can be unreachable.)\r\nexport const textureRewardPool=()=>[\r\n ...TEXTURES.map(t=>item('texture',t)),\r\n ...[[\"opal-jelly\",\"Opal Jelly\"],[\"bubble-glass\",\"Bubble Glass\"],[\"prism-crystal\",\"Prism Crystal\"],[\"holo-foil\",\"Holographic Foil\"],[\"glitter-resin\",\"Glitter Resin\"],[\"galaxy-geode\",\"Galaxy Geode\"],[\"caustic-slime\", \"Caustic Slime\"], [\"blister-hide\", \"Blister Hide\"], [\"rotten-rind\", \"Rotten Rind\"], [\"parasite-nest\", \"Parasite Nest\"], [\"exposed-sinew\", \"Exposed Sinew\"], [\"abyssal-maw\", \"Abyssal Maw\"], [\"circuit-alloy\", \"Circuit Alloy\"], [\"servo-armor\", \"Servo Armor\"], [\"chrome-rib\", \"Chrome Rib\"], [\"carbon-mech\", \"Carbon Mech\"], [\"hazard-panel\", \"Hazard Panel\"], [\"reactor-glass\", \"Reactor Glass\"]].map(([id,name])=>item('texture',[id,name,''])),\r\n ...LEGACY_NAMES.map((name,n)=>item('texture',[`legacy-${n}`,name,''])),\r\n item('texture',['coach-64-bit','64-bit Pixel Finish','A pixel finish for a coach with a boss skin.']),\r\n].filter(t=>!FREE_TEXTURE_IDS.includes(t.id)&&!RETIRED_TEXTURE_IDS.includes(t.id));\r\n// R18 G2b: the 15 free colours span the hue range; each is the nearest (Lab) hex\r\n// already present in the census of palettes.json + SIMPLE_COLORS + LEGACY_COLORS\r\n// (scripts/colour-census.mjs). Everything else is pack-only.\r\nexport const FREE_COLOURS=Object.freeze([\r\n '#060409', // black\r\n '#ffffff', // white\r\n '#7f7d78', // grey\r\n '#ff3b30', // red\r\n '#ff8a2a', // orange\r\n '#ffd100', // yellow\r\n '#2bd97c', // green\r\n '#008c8c', // teal\r\n '#2454d6', // blue\r\n '#6a2bd9', // purple\r\n '#f59ec4', // pink\r\n '#7a5530', // brown\r\n '#c4a77d', // tan\r\n '#0b1a45', // navy\r\n '#9fe2bf', // mint\r\n]);\r\nexport const FREE_COLOUR_NAMES=Object.freeze(['Black','White','Grey','Red','Orange','Yellow','Green','Teal','Blue','Purple','Pink','Brown','Tan','Navy','Mint']); // same order as FREE_COLOURS\r\n// R18 G5: every colour item carries its primary `hex`, so the pack screen can show a swatch (a test pins these to the registry).\r\nexport const colourRewardPool=()=>[\r\n ...PALETTES.map(p=>({kind:'palette',id:p.id,name:p.name})),\r\n ...[['default-slate','Slate','#8b8f9a'],['default-clay','Warm Clay','#b7a68e'],['default-ruby','Ruby','#a23b4a'],['default-sapphire','Sapphire','#2d5aa0'],['default-moss','Moss','#4c7a3f'],['default-gold','Gold','#c9a13a'],['default-charcoal','Charcoal','#333238'],['default-blush','Blush','#d98fa0']].map(([id,name,hex])=>({kind:'color',id,name,hex})), // R18 G2b: none of the 8 simple colours is a free hex\r\n ...LEGACY_NAMES.map((name,n)=>({kind:'color',id:`legacy-color-${n}`,name:`${name} (original)`,hex:n?LEGACY_STYLES[n].primary:'#7946aa'})), // design.ts restyles #0 as Original MYR5\r\n];\r\nfunction packCosmetics(levels,bossId){\r\n for(let level=0;level<levels.length;level++)levels[level]=levels[level].flatMap(reward=>{\r\n  if(reward.kind==='palette')return [rewardPack('uncommon',`${bossId}:L${level+1}:${reward.id}`)];\r\n  if(reward.kind==='texture')return [rewardPack('legendary',`${bossId}:L${level+1}:${reward.id}`)];\r\n  if(reward.kind==='boss-skin')return [{kind:'boss-unlock',id:bossId,name:reward.name.replace(/ Skin$/,' Beaten'),line:'Boss cleared at level 5.'}];\r\n  return [reward];\r\n });\r\n levels[3].push(rewardPack('rare',`${bossId}:L4:64-bit`));\r\n // R20: L2 (boss texture) and L5 (Boss beaten) otherwise show no pack on the board.\r\n const hasPack=level=>level.some(reward=>reward.kind==='reward-pack');\r\n if(!hasPack(levels[1]))levels[1].push(rewardPack('uncommon',`${bossId}:L2:bonus`));\r\n if(!hasPack(levels[4]))levels[4].push(rewardPack('legendary',`${bossId}:L5:bonus`));\r\n return levels;\r\n}\r\nconst find=(list,id)=>list.find(row=>row[0]===id);\r\nexport function paletteItem(id){const p=PALETTES.find(p=>p.id===id);return {kind:'palette',id,name:p.name,line:p.tagline};}\r\n// palettes.json `reward` ('<bossId>:L<n>' | 'food:L<n>') -> palette id.\r\nconst SLOT_PALETTE=new Map(PALETTES.filter(p=>p.reward).map(p=>[p.reward,p.id]));\r\nconst slotPalettes=(owner,count)=>Array.from({length:count},(_,i)=>SLOT_PALETTE.get(`${owner}:L${i+1}`)).map(id=>id?[paletteItem(id)]:[]);\r\nconst petItem=family=>({kind:'pet',id:`${family}-pet`,name:`${family[0].toUpperCase()}${family.slice(1)} pet`,line:PET_LINES[family],family});\r\n\r\n/** The D22 ladder for one board boss: an array of 5 levels, each an array of\r\n * `{kind,id,name,line}` items. Pets carry `family` (D21 sharing, resolved by the caller).\r\n * Pure; returns null for an unknown boss id. */\r\nexport function bossRewards(bossId){\r\n const boss=BOSSES.find(b=>b.id===bossId);\r\n if(!boss)return null;\r\n const meta=boss.track&&TRACKS[boss.track],lines=BOSS_LINES[meta?.family]||[null,null];\r\n const levels=slotPalettes(boss.id,LEVELS_PER_BOSS); // D32 fill (empty for first bosses)\r\n levels[1].push({kind:'boss-texture',id:`${boss.id}-texture`,name:`${boss.name} Texture`,line:lines[0]});\r\n levels[4].push({kind:'boss-skin',id:`${boss.id}-skin`,name:`${boss.name} Skin`,line:lines[1]});\r\n if(!meta||boss.index!==1)return packCosmetics(levels,boss.id);\r\n const c=meta.catalog,tex=TEXTURES.filter(t=>t[0].startsWith(c+'-')).map(t=>TEXTURE_SWAP[t[0]]??t); // catalog order = texture-1/2/3\r\n levels[0].unshift(item('weapon',find(WEAPONS,`${c}-w1`)),item('texture',tex[0]));\r\n levels[1].unshift(paletteItem(meta.palette));\r\n levels[2].push(item('weapon',find(WEAPONS,`${c}-w2`)),{kind:'special',id:`${c}-special`,name:`${meta.name} Special`,line:'Unlocked at level 3.'},item('texture',tex[1]));\r\n levels[3].push(petItem(meta.family));\r\n levels[4].unshift({kind:'aura',id:`${c}-aura`,name:`${meta.name} Aura`,line:'Your first aura look.'});\r\n levels[4].push(item('texture',tex[2]));\r\n for(const skin of CREATURE_SKIN_REWARDS.filter(row=>row.track===c))levels[skin.level-1].push(skin);\r\n for(const ship of SHIP_DEFINITIONS.filter(row=>row.track===c))levels[ship.level-1].push({kind:'ship',id:ship.id,name:ship.name,line:shipDetails(ship.ship).description,ship:ship.ship,pack:'coach-ships-biomes'});\r\n return packCosmetics(levels,boss.id);\r\n}\r\n\r\n// --- Food (D32): no board row, no weapons (item-catalog's food-w1/w2 are never granted), no pet\r\n// or boss. Each Food level (food-photo steps, circuit `tracks.food`) grants its palettes.json\r\n// palette + one bonus. Levels = the food:L<n> palettes, so adding one adds a level. ---\r\nexport const FOOD_BONUS=Object.freeze({id:'food-bonus',name:'Second Helping',line:'Hits harder for one day. Chew responsibly.',\r\n effect:Object.freeze({type:'damage-multiplier',days:1,value:FOOD_BONUS_DAMAGE_MULTIPLIER})});\r\nexport const FOOD_LEVELS=PALETTES.filter(p=>p.reward?.startsWith('food:')).length;\r\n/** Food ladder: FOOD_LEVELS levels, each `[palette, bonus]`. Bonus ids are per level\r\n * (`food-bonus-<n>`) so each grant happens once. */\r\nexport const foodRewards=()=>slotPalettes('food',FOOD_LEVELS).map((items,i)=>[...items.map(reward=>rewardPack('uncommon',`food:L${i+1}:${reward.id}`)),{kind:'bonus',id:`${FOOD_BONUS.id}-${i+1}`,name:FOOD_BONUS.name,line:FOOD_BONUS.line,effect:FOOD_BONUS.effect}]);\r\n","battle-pass.mjs":"// Battle-pass read API (rank 6b, D26/D30) — the logic behind the owner's achievements board.\r\n// No screen here. The board imports selectedTracks() and loadProgress() in place of its two\r\n// stand-ins; battlePassState() is the richer read; syncBattlePass() grants what is newly\r\n// earned and fires `myr5:battle-pass` on window. Usage: plan/reports/battle-pass.md.\r\nimport {STEPS_PER_LEVEL,STYLE_OF_GROUP} from './circuit.mjs';\r\nimport {exerciseFamily} from './workout-route.mjs';\r\nimport {ROWS,BOSSES,TRACKS,LEVELS_PER_BOSS,PET_SUBSTITUTE_PALETTE,FOOD_LEVELS,bossRewards,paletteItem,foodRewards} from './battle-pass-rewards.mjs';\r\nimport {readSelectedTracks} from './chosen-styles.mjs';\r\nimport * as store from './creature/source/creator/unlock-store.ts';\r\nimport * as ledger from './unlock-ledger.mjs';\r\nimport {readPerformanceProgress} from './performance-progress.mjs';\r\nimport {COACH_REQUIREMENTS} from './performance-catalog.mjs';\r\nimport {cosmeticLevel} from './progression-rules.mjs';\r\nimport {completeCosmeticCollection} from './reward-packs.mjs';\r\nexport {setSelectedTracks} from './chosen-styles.mjs';\r\n// The ONE tuning knob: steps per level. Shared with circuit.mjs so the step meter and the board agree.\r\nexport {STEPS_PER_LEVEL};\r\n\r\nconst CIRCUIT_TRACK=Object.fromEntries(Object.entries(TRACKS).map(([track,meta])=>[meta.circuit,track]));\r\nconst clamp=n=>Math.min(LEVELS_PER_BOSS,Math.max(0,n));\r\n\r\n/** D30: the rows open to this user = their selected paths + meditation (D9), as a Set of D25\r\n * track ids. Explicit pick (chosen-styles.mjs) wins; until the oval picker writes one, the\r\n * movements chosen at onboarding stand in (the board's original rule). */\r\nexport function selectedTracks(account=globalThis.myr5AuthenticatedAccount){\r\n let picked=readSelectedTracks();\r\n if(!picked.length)picked=(account?.onboarding?.data?.profile?.exercises||[]).map(mode=>CIRCUIT_TRACK[STYLE_OF_GROUP[exerciseFamily(mode)]]).filter(Boolean);\r\n return new Set(['meditation',...picked]);\r\n}\r\n\r\n// Rank-6 step counts, keyed by circuit.mjs track id: live account progress, else the snapshot\r\n// pod.mjs caches for reopen (myr5-workout-progress-v1).\r\nfunction stepTracks(){\r\n const live=globalThis.coachProgress?.circuit?.tracks;\r\n if(live)return live;\r\n try{return JSON.parse(localStorage.getItem('myr5-workout-progress-v1'))?.circuit?.tracks||{};}catch{return {};}\r\n}\r\n\r\n/** Whole levels earned from a step count (uncapped; the row caps it). */\r\nexport const levelsBeaten=(steps,stepsPerLevel=STEPS_PER_LEVEL)=>Math.floor(Math.max(0,Number(steps)||0)/stepsPerLevel);\r\n\r\n/** `{[bossId]: levelsBeaten 0–5}` for all 38 board bosses. Bosses in a row are consecutive:\r\n * boss k = clamp(level − 5·(k−1), 0, 5). Rows outside selectedTracks() stay at 0. The shared\r\n * bosses (Warden, then Lume) are fed by levels earned past each available row's end, and only\r\n * once every available row is fully beaten.\r\n * opts: {tracks: circuit `tracks` object, account, stepsPerLevel} — all optional. */\r\nexport function loadProgress({tracks=stepTracks(),account,stepsPerLevel=STEPS_PER_LEVEL}={}){\r\n const performance=readPerformanceProgress({account}),result=Object.fromEntries(BOSSES.map(b=>[b.id,0]));\r\n for(const row of ROWS){if(!row.track)continue;const coaches=COACH_REQUIREMENTS.filter(c=>c.tracks.includes(TRACKS[row.track].catalog));for(let index=0;index<row.bosses;index++){const coach=coaches[Math.min(coaches.length-1,Math.floor(index*coaches.length/row.bosses))];if(coach)result[`${row.id}-${index+1}`]=performance.goldenCoaches.includes(coach.id)?5:performance.coaches.includes(coach.id)?4:0;}}\r\n return result;\r\n}\r\n\r\n/** Combat kit level (1–5, D8/D22) for the rest-arena boss after a set of `mode`: the levels beaten\r\n * on that exercise's track = its row's first boss in loadProgress(), so a row outside the user's\r\n * paths fights at L1, same as the board shows it. Core/balance moves sit on Meditation (board rule). */\r\nexport function combatLevel(mode,opts={}){\r\n const track=CIRCUIT_TRACK[STYLE_OF_GROUP[exerciseFamily(mode)]]??'meditation',row=ROWS.find(r=>r.track===track);\r\n return Math.max(1,loadProgress(opts)[`${row.id}-1`]);\r\n}\r\n\r\nconst STORE_KINDS=new Set(['texture','color','palette']);\r\nconst isGranted=(item,opts)=>(STORE_KINDS.has(item.kind)?store:ledger).isGranted(item.kind,item.id,opts);\r\nfunction grant(item,opts){\r\n if(!STORE_KINDS.has(item.kind))return ledger.grantUnlock(item.kind,item.id,opts);\r\n if(store.isGranted(item.kind,item.id))return false;\r\n store.grantUnlock(item.kind,item.id);\r\n return store.isGranted(item.kind,item.id); // false if storage is unavailable\r\n}\r\n\r\n/** Richer read: `{stepsPerLevel, available:[track], progress, bosses:[{id,name,row,track,index,\r\n * levels, rewards:[{level, beaten, items:[{kind,id,name,line,granted}]}]}], food}` in board order.\r\n * D21 pets: in a two-row family the first available row (board order) to beat L4 of its\r\n * first boss holds the pet; the other row shows the family's substitute palette there.\r\n * `food` (D32, no board row): `{steps, levels, maxLevel, rewards}` from food-photo steps; each\r\n * level's items are a palette + a bonus (`kind:'bonus'`, with `effect`). */\r\nexport function battlePassState(opts={}){\r\n const stepsPerLevel=opts.stepsPerLevel??STEPS_PER_LEVEL,available=selectedTracks(opts.account),progress=loadProgress({...opts,stepsPerLevel});\r\n const foodSteps=Math.max(0,Number((opts.tracks??stepTracks())?.food?.steps)||0),foodLevels=Math.min(FOOD_LEVELS,levelsBeaten(foodSteps,stepsPerLevel));\r\n const petOwner=family=>ROWS.find(row=>row.track&&TRACKS[row.track].family===family&&available.has(row.track)&&progress[`${row.id}-1`]>=4)?.id;\r\n const bosses=BOSSES.map(boss=>({...boss,levels:progress[boss.id],rewards:bossRewards(boss.id).map((items,i)=>({\r\n  level:i+1,beaten:progress[boss.id]>i,\r\n  items:items.map(item=>{\r\n   const owner=item.kind==='pet'&&PET_SUBSTITUTE_PALETTE[item.family]&&petOwner(item.family);\r\n   const shown=owner&&owner!==boss.row?(()=>{const palette=paletteItem(PET_SUBSTITUTE_PALETTE[item.family]);return {kind:'reward-pack',id:`reward-pack:uncommon:${boss.id}:L4:${palette.id}`,tier:'uncommon',name:'Uncommon Pack',line:'Open for one random cosmetic.'};})():item;\r\n   return {...shown,granted:isGranted(shown,opts)};\r\n  }),\r\n }))}));\r\n const food={steps:foodSteps,levels:foodLevels,maxLevel:FOOD_LEVELS,rewards:foodRewards().map((items,i)=>({level:i+1,beaten:foodLevels>i,items:items.map(item=>({...item,granted:isGranted(item)}))}))};\r\n return {stepsPerLevel,available:[...available],progress,bosses,food};\r\n}\r\n\r\n/** Grants every beaten level's items not yet granted (idempotent: replaying the same steps\r\n * grants nothing twice), then, only if something was new, dispatches `myr5:battle-pass` on\r\n * window with `{granted:[item], state}`. Returns the same `{granted, state}`. */\r\nexport function syncBattlePass(opts={}){\r\n const state=battlePassState(opts),granted=[];\r\n const rank=cosmeticLevel(readPerformanceProgress(opts).totalXp);\r\n for(let level=2;level<=rank.level;level++){const tier=level%10===0?'legendary':level%5===0?'rare':'uncommon',item={kind:'reward-pack',id:`reward-pack:${tier}:cosmetic-pass-v2:L${level}`,tier,name:`${tier} pack`};if(ledger.grantUnlock(item.kind,item.id,opts))granted.push(item);}\r\n if(rank.max)completeCosmeticCollection(opts);\r\n if(granted.length&&typeof window!=='undefined'&&window.dispatchEvent)window.dispatchEvent(new CustomEvent('myr5:battle-pass',{detail:{granted,state}}));\r\n return {granted,state};\r\n}\r\n\r\n// Grants follow step progress: pod.mjs/launch.mjs publish it as `myr5:account-progress`.\r\nif(typeof window!=='undefined'&&window.addEventListener){window.addEventListener('myr5:account-progress',()=>syncBattlePass());window.addEventListener('myr5:performance-progress',()=>syncBattlePass());}\r\n","breathing-modes.mjs":"// D25: meditation offers two breathing modes inside the existing meditation flow. Pure data +\r\n// pure functions only (no DOM, no timers) so breathing.mjs, the unit tests and the browser test\r\n// all read the same script. A mode never adds a second clock: \"session complete\" stays exactly\r\n// combat.mjs's BreathingSession/BREATHING_MS (3 minutes of active time, re-checked server-side in\r\n// server/combat.mjs completeBreathing). A mode only decides which phase to show for a given\r\n// elapsed-ms value on that one clock.\r\n//\r\n// ponytail: PENDING WELLNESS REVIEW. Every hold length, round count and breath pace below is a\r\n// conservative placeholder, not a production value (ART-AND-CHOICE handoff §7: breath timing,\r\n// contraindications, copy and escape behaviour need wellness/safety review before values are\r\n// locked). Tune them only after that review, then flip PENDING_WELLNESS_REVIEW.\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {BREATHING_MS} from './combat.mjs';\r\n\r\nexport const PENDING_WELLNESS_REVIEW = true;\r\nconst guidedCore = {durationMs:210000,settleMs:20500,breaths:30,breathMs:110000,inhaleMs:8500/3,exhaleMs:2500/3,transitionMs:2500,optionalPauseMs:30000,recoveryInhaleMs:3000,recoveryPauseMs:15000,closingBreathingMs:29000};\r\nexport const GUIDED_ROUND_TIMING = Object.freeze(guidedCore);\r\nexport const GUIDED_ROUND_MS = GUIDED_ROUND_TIMING.durationMs;\r\nexport const GENTLE_DIALOGUE = Object.freeze([\r\n 'Get comfortable.',\r\n 'Breathe in gently.',\r\n 'Breathe out softly.',\r\n 'Keep the breath easy.',\r\n 'Feel your support.',\r\n 'Inhale when ready.',\r\n 'Return to normal.',\r\n 'Stop or skip anytime.'\r\n]);\r\nexport const SEATED_ONLY_NOTICE = 'Practice seated or lying down. Never while driving or in or near water.';\r\nexport const NO_MEDICAL_CLAIM = 'A breathing practice, not medical treatment or advice. Stop any time, and breathe normally if you feel dizzy or unwell.';\r\n\r\nconst stances = ids => Object.freeze(ids.filter(id => EXERCISES[id]).map(id => Object.freeze({id, name: EXERCISES[id].name, cue: EXERCISES[id].cue})));\r\n\r\nexport const BREATHING_MODES = Object.freeze({\r\n 'wim-hof': Object.freeze({\r\n  id: 'wim-hof',\r\n  title: 'One guided breathing round',\r\n  subtitle: '3:30 · 30 easy breaths with an optional pause.',\r\n  seatedOnly: true,\r\n  rounds: 1, breathsPerRound: GUIDED_ROUND_TIMING.breaths, inhaleMs: GUIDED_ROUND_TIMING.inhaleMs, exhaleMs: GUIDED_ROUND_TIMING.exhaleMs, holdMs: GUIDED_ROUND_TIMING.optionalPauseMs, recoveryHoldMs: GUIDED_ROUND_TIMING.recoveryPauseMs, recoveryInhaleMs:GUIDED_ROUND_TIMING.recoveryInhaleMs,transitionMs:GUIDED_ROUND_TIMING.transitionMs,breathMs:GUIDED_ROUND_TIMING.breathMs,settleMs: GUIDED_ROUND_TIMING.settleMs,\r\n }),\r\n 'tai-chi': Object.freeze({\r\n  id: 'tai-chi',\r\n  title: 'Tai chi stance breathing',\r\n  subtitle: 'Slow breaths while you hold a balance or core stance.',\r\n  seatedOnly: false,\r\n  // D25: the existing core/balance exercises (easiest variants first, as the conservative default).\r\n  stances: stances(['low-tree', 'knee-balance', 'knee-plank', 'side-knee-left', 'side-knee-right']),\r\n  stanceHoldMs: 20000, restMs: 10000, inhaleMs: 4000, exhaleMs: 5000,\r\n }),\r\n});\r\nexport const MODE_IDS = Object.freeze(Object.keys(BREATHING_MODES));\r\n\r\nexport function buildScript(id) {\r\n const m = BREATHING_MODES[id];\r\n if (!m) throw Error('Unknown breathing mode: ' + id);\r\n const pace = {inhaleMs: m.inhaleMs, exhaleMs: m.exhaleMs}, phases = [];\r\n if (id === 'wim-hof') {\r\n  phases.push(\r\n   {key:'settle',label:'Settle comfortably',ms:m.settleMs,dialogue:GENTLE_DIALOGUE[0]},\r\n   {key:'breathe',label:'One round · 30 easy breaths',ms:m.breathMs,pace,dialogue:GENTLE_DIALOGUE[1]},\r\n   {key:'transition',label:'Let the last exhale soften',ms:m.transitionMs,dialogue:'Easy exhale. Stay comfortable.'},\r\n   {key:'optional-hold',label:'Optional pause · skip whenever you like',ms:m.holdMs,dialogue:'Never force it. Breathe normally.'},\r\n   {key:'recovery',label:'Return to easy breathing',ms:m.recoveryInhaleMs,dialogue:GENTLE_DIALOGUE[7]},\r\n   {key:'recovery-hold',label:'Optional recovery pause · skip anytime',ms:m.recoveryHoldMs,dialogue:'Never force it. Breathe normally.'},\r\n   {key:'rest',label:'Let your breathing return to its natural rhythm',ms:GUIDED_ROUND_TIMING.closingBreathingMs,dialogue:GENTLE_DIALOGUE[7]},\r\n  );\r\n } else for (const s of m.stances) phases.push(\r\n  {key: 'hold', label: `Hold: ${s.name}`, ms: m.stanceHoldMs, pace, stanceId: s.id, cue: s.cue},\r\n  {key: 'rest', label: 'Release the stance · breathe normally', ms: m.restMs},\r\n );\r\n return Object.freeze(phases);\r\n}\r\n\r\n// Each script should fit inside the shared clock so no round is cut short (asserted in tests).\r\nexport const scriptMs = script => script.reduce((sum, p) => sum + p.ms, 0);\r\nexport const SESSION_MS = BREATHING_MS;\r\n\r\n// Phase showing at `elapsedMs` of active time. Once the script is used up, it rests until the\r\n// shared 3-minute clock ends -- this never decides when the session ends.\r\nexport function phaseAt(script, elapsedMs) {\r\n let into = Math.max(0, Number(elapsedMs) || 0);\r\n for (const p of script) {\r\n  if (into < p.ms) {\r\n   const cycle = p.pace && p.pace.inhaleMs + p.pace.exhaleMs;\r\n   return {...p, remainingMs: p.ms - into, breath: cycle ? (into % cycle < p.pace.inhaleMs ? 'in' : 'out') : null};\r\n  }\r\n  into -= p.ms;\r\n }\r\n return {key: 'rest', label: 'Breathe normally until the timer ends', ms: 0, remainingMs: 0, breath: null};\r\n}\r\n\r\n// R18 A3: every completed breath counts toward the colour reveal, across the whole script (never per round).\r\nconst cycleMs = p => p.pace.inhaleMs + p.pace.exhaleMs, breathsIn = p => Math.round(p.ms / cycleMs(p));\r\nexport const totalBreaths = script => script.reduce((n, p) => n + (p.pace ? breathsIn(p) : 0), 0);\r\nexport function breathsDone(script, ms) {\r\n let n = 0;\r\n for (const p of script) {\r\n  if (p.pace) n += Math.min(breathsIn(p), Math.floor((Math.max(0, Math.min(ms, p.ms)) + 1e-6) / cycleMs(p)));\r\n  if ((ms -= p.ms) < 0) break;\r\n }\r\n return n;\r\n}\r\n// Colour circle radius in px: strictly under maxR until the final breath, exactly maxR on it.\r\nexport const revealRadius = (done, total, maxR) => total > 0 && done >= total ? maxR : maxR * Math.max(0, done) / Math.max(1, total);\r\n// R20: breath-synced colour pulse. Breath i (0-based, inhale then exhale): the inhale contracts from the last exhale's\r\n// peak to the character (minR), the exhale expands to peak(i), which grows with i; the last exhale peak is exactly maxR.\r\n// phase is 'in' | 'out' (anything else = between breaths), progress 0..1 through that half-breath.\r\nexport function pulseRadius(breathIndex, total, phase, progress, maxR, minR = 0) {\r\n if (total <= 0) return 0;\r\n if (breathIndex >= total) return maxR;\r\n const peak = i => i < 0 ? 0 : minR + (maxR - minR) * (i + 1) / total;\r\n const e = (1 - Math.cos(Math.PI * Math.max(0, Math.min(1, progress)))) / 2; // ease in-out\r\n if (phase === 'out') return minR + (peak(breathIndex) - minR) * e;\r\n if (phase === 'in') return minR + (peak(breathIndex - 1) - minR) * (1 - e);\r\n return breathIndex > 0 ? minR : 0;\r\n}\r\n// Which half-breath is showing at `ms` and how far through it (0..1); null outside paced phases.\r\nexport function breathPhaseProgress(script, ms) {\r\n const p = phaseAt(script, ms);\r\n if (!p.pace || !p.breath) return {breath: null, progress: 0};\r\n const offset = (p.ms - p.remainingMs) % (p.pace.inhaleMs + p.pace.exhaleMs);\r\n return {breath: p.breath, progress: p.breath === 'in' ? offset / p.pace.inhaleMs : (offset - p.pace.inhaleMs) / p.pace.exhaleMs};\r\n}\r\n","breathing.mjs":"import {authTransitions} from './auth-transition.mjs';\r\nimport {recordDailyActivity,localDay} from './performance-progress.mjs';\r\nimport {createAccountSessionActions} from './account-session-actions.mjs';\r\nimport {BreathingSession,BREATHING_MS} from './combat.mjs';\r\nimport {BREATHING_MODES,SEATED_ONLY_NOTICE,NO_MEDICAL_CLAIM,GENTLE_DIALOGUE,GUIDED_ROUND_TIMING,GUIDED_ROUND_MS,buildScript,phaseAt,totalBreaths as countBreaths,breathsDone,revealRadius,pulseRadius,breathPhaseProgress} from './breathing-modes.mjs';\r\n// R18 A5: a speech line fades in, stays ~4 s, fades out (CSS .bubble); re-adding the class restarts it.\r\nexport const bubble=(el,text)=>{el.textContent=text;el.classList.remove('bubble');void el.offsetWidth;el.classList.add('bubble');};\r\n\r\n// Both modes use the existing account-owned breathing ticket and completion path. The guided\r\n// round's timing lives in breathing-modes.mjs so cadence review can tune phases without changing ownership.\r\nconst DEFAULT_STATUS='Complete a session to double today’s workout XP.';\r\nconst IDLE_CAPTION='Breathe in. Breathe out.';\r\n// The big caption follows the phase. Reduced motion keeps it steady through fast in/out breathing.\r\nfunction captionFor(p,reduced){\r\n if(p.key==='settle')return 'Choose a comfortable position. Let your shoulders soften.';\r\n if(p.key==='optional-hold')return 'Breathe whenever you need to. Do not force the hold.';\r\n if(p.key==='recovery')return 'Return to easy breathing.';\r\n if(p.key==='recovery-hold')return 'Let breathing return to normal whenever you like.';\r\n if(p.key==='rest')return 'Breathe normally.';\r\n if(p.breath)return reduced?IDLE_CAPTION:p.breath==='in'?'Breathe in.':'Breathe out.';\r\n return p.key==='hold'?'Breathe out and hold.':IDLE_CAPTION;\r\n}\r\n\r\nexport function mountBreathing({dialog,scene,pause,api,onComplete,onSessionComplete,onEarlyExit,getAccount,transitions=authTransitions()}){\r\n const actions=createAccountSessionActions({api,transitions});\r\n const controls=document.createElement('div');controls.className='breathing-session';\r\n // R20: one Begin button starts the guided round (Begin -> seated warning -> settle countdown -> breathing). Tai chi stays in\r\n // breathing-modes.mjs for anything that imports it but is no longer offered here. data-mode keeps older selectors working.\r\n controls.innerHTML='<div class=\"breath-modes\" data-breath-modes><button type=\"button\" class=\"breath-begin\" data-begin data-mode=\"wim-hof\">Begin</button></div>'\r\n  +'<div class=\"breath-run\" data-breath-run hidden><p class=\"breath-phase\" data-phase-label></p><progress max=\"'+BREATHING_MS+'\" value=\"0\" aria-label=\"Breathing session progress\"></progress>'\r\n  +'<div class=\"breath-actions\"><button type=\"button\" data-retry hidden>Save breathing bonus</button><button type=\"button\" data-skip-hold hidden>Skip · breathe normally</button></div>'\r\n  +'<button type=\"button\" class=\"breath-stance-link\" data-stance-link hidden>Check this stance with the camera coach</button></div>'\r\n  +'<p data-status role=\"status\"></p><p class=\"breath-note\">'+NO_MEDICAL_CLAIM+'</p>';\r\n scene.append(controls);\r\n // R18 A4: the seated warning is a full-scene overlay; nothing ticks until Accept, then it fades out (600 ms) and is hidden.\r\n const seated=document.createElement('div');seated.className='breath-seated-overlay';seated.dataset.seated='';seated.hidden=true;seated.innerHTML='<div role=\"alertdialog\" aria-label=\"Before you begin\"><p class=\"breath-seated-notice\">'+SEATED_ONLY_NOTICE+'</p><button type=\"button\" data-seated-accept>Accept</button></div>';dialog.append(seated);\r\n // R18 polish: after Accept the top panel fades to near-invisible; any tap brings it back for 4 s.\r\n let calmTimer=0;const calm=on=>dialog.classList.toggle('hud-calm',on),rest=()=>{clearTimeout(calmTimer);calmTimer=setTimeout(()=>ticket&&!held&&calm(true),4000);};\r\n let swallow=false;dialog.addEventListener('pointerdown',event=>{if(ticket&&!held){swallow=dialog.classList.contains('hud-calm')&&!event.target.closest?.('[data-breath-exit],[data-meditation-close]');calm(false);rest();}},true);\r\n dialog.addEventListener('click',event=>{if(swallow){swallow=false;event.stopPropagation();event.preventDefault();}},true); // the first tap on a faded panel only reveals it\r\n seated.querySelector('button').onclick=()=>{held=false;if(ticket)calm(true);seated.classList.add('fading');setTimeout(()=>{seated.hidden=true;seated.classList.remove('fading');},600);};\r\n controls.querySelector('.breath-actions').append(pause);\r\n const $=selector=>controls.querySelector(selector);\r\n const modesEl=$('[data-breath-modes]'),runEl=$('[data-breath-run]'),phaseEl=$('[data-phase-label]'),bar=$('progress'),stopCircle=scene.querySelector?.('[data-breathing-stop], [data-breath-exit]'),retry=$('[data-retry]'),skipHold=$('[data-skip-hold]'),stanceLink=$('[data-stance-link]'),statusEl=$('[data-status]'),countEl=scene.querySelector?.('[data-breath-count]'),sessionClock=scene.querySelector?.('[data-session-clock]'),directionEl=scene.querySelector?.('[data-breath-direction]'),cueEl=scene.querySelector?.('[data-breath-cue]'),settleEl=scene.querySelector?.('[data-settle-countdown]');\r\n // Both exercises and the decorative pose selector share a compact, reachable control strip.\r\n const speech=scene.querySelector?.('.meditation-speech'),reducedMotion=globalThis.matchMedia?.('(prefers-reduced-motion: reduce)');\r\n let clock=new BreathingSession(),ticket=null,saving=false,finished=false,awaitingRetry=false,run=0,script=null,caption='',duration=BREATHING_MS,totalBreaths=0,held=false,completionDay=null;\r\n function renderPhase(ms){\r\n  const p=phaseAt(script,ms);runEl.dataset.phase=p.key;skipHold.hidden=!['optional-hold','recovery-hold'].includes(p.key);\r\n  phaseEl.textContent=({settle:'Settle gently',breathe:p.breath==='in'?'Breathe in':'Breathe out',transition:'Easy exhale','optional-hold':'Optional pause',recovery:'Easy inhale','recovery-hold':'Optional recovery',rest:'Breathe normally'})[p.key]||p.label;\r\n  stanceLink.hidden=!p.stanceId;stanceLink.dataset.stance=p.stanceId||'';\r\n  // Only on change, so a character-tap line stays until the next phase and the live region is not re-announced.\r\n  let next=p.dialogue||captionFor(p,reducedMotion?.matches);\r\n  if(p.key==='breathe'&&p.pace){const elapsed=p.ms-p.remainingMs,cycle=p.pace.inhaleMs+p.pace.exhaleMs,index=Math.floor(elapsed/cycle);next=GENTLE_DIALOGUE[1+Math.floor(index/6)%6];}\r\n  if(speech&&next!==caption){caption=next;bubble(speech,next);}\r\n  // R20: the in/out cue is the one rotating line that never fades (plain text swap, no animation); every other line is a fading bubble.\r\n  if(cueEl){const cue=p.breath?(reducedMotion?.matches?IDLE_CAPTION:p.breath==='in'?'Breathe in':'Breathe out'):'';cueEl.hidden=!cue;if(cueEl.textContent!==cue)cueEl.textContent=cue;cueEl.dataset.breath=p.breath||'';}\r\n  // R20: the settle phase is a visible countdown (whole seconds left, down to 0) before the first breath.\r\n  if(settleEl){settleEl.hidden=p.key!=='settle';const left=String(Math.max(0,Math.floor((p.remainingMs||0)/1000)));if(p.key==='settle'&&settleEl.lastElementChild?.textContent!==left)settleEl.lastElementChild.textContent=left;}\r\n  if(countEl){let remaining=p.remainingMs||0,progress=.5,value='\\u2014',direction=p.key==='settle'?'READY':'REST';if(['settle','rest'].includes(p.key)){const cycle=GUIDED_ROUND_TIMING.inhaleMs+GUIDED_ROUND_TIMING.exhaleMs,elapsed=Math.max(0,p.ms-p.remainingMs),offset=elapsed%cycle,inhale=offset<GUIDED_ROUND_TIMING.inhaleMs;progress=inhale?offset/GUIDED_ROUND_TIMING.inhaleMs:1-(offset-GUIDED_ROUND_TIMING.inhaleMs)/GUIDED_ROUND_TIMING.exhaleMs;direction=inhale?'IN':'OUT';}else if(p.pace&&p.breath){const into=p.ms-p.remainingMs,cycle=p.pace.inhaleMs+p.pace.exhaleMs,offset=into%cycle,segment=p.breath==='in'?offset:offset-p.pace.inhaleMs;remaining=p.breath==='in'?p.pace.inhaleMs-offset:cycle-offset;progress=p.breath==='in'?offset/p.pace.inhaleMs:1-segment/p.pace.exhaleMs;value=String(Math.min(BREATHING_MODES['wim-hof'].breathsPerRound,Math.floor(into/cycle)+1));direction=p.breath==='in'?'IN':'OUT';}else if(p.key==='transition'){progress=1-(p.ms-p.remainingMs)/p.ms;direction='OUT';}else if(p.key==='optional-hold'){progress=0;value=String(Math.max(0,Math.ceil(remaining/1000)));direction='HOLD?';}else if(p.key==='recovery'){progress=(p.ms-p.remainingMs)/p.ms;direction='IN';}else if(p.key==='recovery-hold'){progress=1;value=String(Math.max(0,Math.ceil(remaining/1000)));direction='HOLD?';}else if(p.key==='complete'){value='30';direction='DONE';}countEl.textContent=value;countEl.dataset.breath=p.breath||'rest';countEl.parentElement?.style.setProperty('--breath-progress',String(Math.max(0,Math.min(1,progress))));countEl.parentElement?.style.setProperty('--breath-scale',String(.70+Math.max(0,Math.min(1,progress))*.42));if(directionEl)directionEl.textContent=direction;}\r\n }\r\n  // R18 A3: grey veil over the whole stage with a hole centred on the character. R20: the hole pulses with the breath --\r\n // out to a growing peak on each exhale, back to the character on each inhale (pulseRadius), redrawn every tick.\r\n // Reduced motion keeps the R18 steady growth (revealRadius) instead of a fast pulse.\r\n function reveal(ms){\r\n  const stage=scene.querySelector('.meditation-stage'),veil=stage?.querySelector('.meditation-grey'),who=scene.querySelector('.meditation-character');if(!veil||!who||!script)return;\r\n  const s=stage.getBoundingClientRect(),c=who.getBoundingClientRect(),x=c.left+c.width/2-s.left,y=c.top+c.height/2-s.top,maxR=Math.hypot(Math.max(x,s.width-x),Math.max(y,s.height-y)),done=breathsDone(script,ms),{breath,progress}=breathPhaseProgress(script,ms);\r\n  veil.style.setProperty('--cx',x+'px');veil.style.setProperty('--cy',y+'px');veil.style.setProperty('--reveal-r',(reducedMotion?.matches?revealRadius(done,totalBreaths,maxR):pulseRadius(done,totalBreaths,breath,progress,maxR,Math.min(c.width,c.height)/2))+'px');\r\n  dialog.classList.toggle('meditation-colour',totalBreaths>0&&done>=totalBreaths);\r\n }\r\n function reset({keepPose=false}={}){\r\n  run++;clock=new BreathingSession();duration=BREATHING_MS;ticket=null;completionDay=null;saving=false;finished=false;awaitingRetry=false;script=null;\r\n  if(caption&&speech)bubble(speech,IDLE_CAPTION);caption='';totalBreaths=0;held=false;scene.querySelector?.('.meditation-grey')?.style.setProperty('--reveal-r','0px');if(cueEl)cueEl.hidden=true;if(settleEl)settleEl.hidden=true;clearTimeout(calmTimer);dialog.classList.remove('hud-calm');\r\n  bar.max=BREATHING_MS;bar.value=0;sessionClock&&(sessionClock.textContent='3:30');countEl&&(countEl.textContent='—');directionEl&&(directionEl.textContent='READY');pause.disabled=true;pause.hidden=true;pause.textContent='Pause';dialog.classList.remove('breathing-paused');\r\n  modesEl.hidden=false;runEl.hidden=true;seated.hidden=true;retry.hidden=true;skipHold.hidden=true;stanceLink.hidden=true;runEl.dataset.phase='';\r\n  if(stopCircle)stopCircle.hidden=true;phaseEl.textContent='';statusEl.textContent=DEFAULT_STATUS;dialog.classList.remove('meditation-colour');\r\n }\r\n async function finish(){\r\n  if(saving||finished||!ticket||!clock.complete)return;\r\n  saving=true;awaitingRetry=false;retry.hidden=true;pause.disabled=true;statusEl.textContent='Saving your breathing bonus…';const current=run;completionDay??=localDay();\r\n  try{\r\n   const binding=ticket;await actions.completeBreathing(binding,clock.elapsed);\r\n   if(current!==run||!transitions.isCurrent(binding.transitionTicket))return;\r\n   recordDailyActivity('meditation',{id:binding.id,day:completionDay},{account:{user:{id:binding.ownerId},dataEpoch:binding.dataEpoch}});\r\n   await onComplete?.();\r\n   if(current!==run||!transitions.isCurrent(binding.transitionTicket))return;\r\n   finished=true;statusEl.textContent='Meditation complete · ×2 workout XP today';sessionClock&&(sessionClock.textContent='0:00');countEl&&(countEl.textContent='30');directionEl&&(directionEl.textContent='DONE');phaseEl.textContent='Complete';runEl.dataset.phase='complete';stanceLink.hidden=true;pause.hidden=true;if(stopCircle)stopCircle.hidden=false;onSessionComplete?.();\r\n  }catch(error){if(current===run){statusEl.textContent=error.message;retry.hidden=false;awaitingRetry=true;}}\r\n  finally{if(current===run)saving=false;}\r\n }\r\n async function startSession(id){\r\n  reset({keepPose:true});duration=id==='wim-hof'?GUIDED_ROUND_MS:BREATHING_MS;bar.max=duration;script=buildScript(id);held=!!BREATHING_MODES[id]?.seatedOnly;seated.hidden=!held;seated.classList.remove('fading');totalBreaths=countBreaths(script);reveal(0);if(held)seated.querySelector('button').focus();modesEl.hidden=true;runEl.hidden=false;statusEl.textContent='Starting…';sessionClock&&(sessionClock.textContent=formatTime(duration));renderPhase(0);void import('./modules/vault/vault-store.mjs').then(m=>m.bump('breath-mode',1,{key:id})).catch(()=>{});\r\n  const current=run;\r\n  try{\r\n   const value=await actions.startBreathing(getAccount?.());\r\n   if(current!==run||!transitions.isCurrent(value.transitionTicket))return;\r\n   ticket=value;clock=new BreathingSession(duration);pause.disabled=false;pause.hidden=false;if(stopCircle)stopCircle.hidden=false;statusEl.textContent=formatTime(duration)+' remaining';if(!held)calm(true);\r\n  }catch(error){if(current===run){reset();statusEl.textContent=error.message;}}\r\n }\r\n modesEl.querySelector('[data-begin]').onclick=()=>startSession('wim-hof');\r\n \r\n // Abandon the ticket before the exit animation. This path never calls completion/save.\r\n const stopNow=()=>{const early=!!ticket&&!finished&&!clock.complete,transitionTicket=ticket?.transitionTicket;reset();if(early)void onEarlyExit?.({isCurrent:()=>!transitionTicket||transitions.isCurrent(transitionTicket)});else if(dialog.open)dialog.close();};\r\n if(stopCircle)stopCircle.onclick=stopNow;\r\n skipHold.onclick=()=>{if(!script||!['optional-hold','recovery-hold'].includes(runEl.dataset.phase))return;const index=script.findIndex(p=>p.key===runEl.dataset.phase);script=script.map((p,i)=>i>=index?{key:'rest',label:'Breathe normally until the timer ends',ms:p.ms}:p);renderPhase(clock.elapsed);};\r\n retry.onclick=()=>finish();\r\n // D25: existing core/balance hold detection stays reachable -- leave breathing for the movement\r\n // library's own camera hold for this stance instead of re-implementing pose detection here.\r\n stanceLink.onclick=()=>{const id=stanceLink.dataset.stance;dialog.close();document.getElementById('openLibrary')?.click();document.querySelector(`[data-movement=\"${id}\"]`)?.click();};\r\n const timer=setInterval(()=>{\r\n  const active=!!ticket&&dialog.open&&!scene.hidden&&!document.hidden&&!dialog.classList.contains('breathing-paused')&&!held&&!dialog.classList.contains('snorting')&&!dialog.classList.contains('blacking-out');\r\n  clock.sample(performance.now(),active);bar.value=clock.elapsed;\r\n  if(ticket&&!finished&&!saving&&!clock.complete){const left=Math.ceil((duration-clock.elapsed)/1000);statusEl.textContent=formatTime(duration-clock.elapsed)+' remaining'+(active?'':' · Paused');sessionClock&&(sessionClock.textContent=formatTime(duration-clock.elapsed));renderPhase(clock.elapsed);reveal(clock.elapsed);}\r\n  if(clock.complete&&!finished&&!saving&&!awaitingRetry)void finish();\r\n },50);\r\n const unsubscribe=transitions.subscribe(reset);\r\n dialog.addEventListener('close',reset);window.addEventListener('pagehide',event=>{reset();if(!event.persisted){unsubscribe();clearInterval(timer);}});\r\n reset();\r\n}\r\nfunction formatTime(ms){const seconds=Math.max(0,Math.ceil(ms/1000));return `${Math.floor(seconds/60)}:${String(seconds%60).padStart(2,'0')}`;}\r\n","camera-workout.css":"/* An active camera workout has exactly two visible elements: video and count. */\r\nbody[data-camera-workout=true]{overflow:hidden!important;background:#000!important;padding:0!important}\r\nbody[data-camera-workout=true]>:not(#cameraWorkout){display:none!important}\r\n#cameraWorkout:not([hidden]){position:fixed;inset:0;width:100vw;height:100dvh;z-index:2147483000;display:block;background:#000;overflow:hidden}\r\n#cameraWorkout>video{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;display:block}\r\n#cameraWorkout .camera-workout-counter{position:absolute;top:max(24px,env(safe-area-inset-top));left:50%;transform:translateX(-50%);display:block;width:auto;min-width:88px;min-height:64px;padding:12px 18px;border:0;border-radius:16px;background:#0008;color:#fff;box-shadow:none;touch-action:manipulation}\r\n#cameraWorkout #primary{display:inline-flex;font:750 clamp(56px,14vw,100px)/1 ui-monospace,monospace;letter-spacing:-2px;color:#fff}\r\n#cameraWorkout #primary .flip-tile{background:none;border:0;box-shadow:none}\r\n#cameraWorkout #primary .flip-tile:after{display:none}\r\n#cameraWorkout #primary .flip-half{background:none;color:#fff}\r\n#cameraWorkout .camera-workout-counter:focus-visible{outline:3px solid white;outline-offset:4px}\r\n#cameraWorkout #coachOverlay{position:absolute;inset:0;pointer-events:none}\r\n/* Housing frame: edge only, never intercepts input. The counter sits above it; the AR coach overlay above both. */\r\n#cameraWorkout .camera-workout-housing{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}\r\n#cameraWorkout .camera-workout-counter{z-index:2}\r\n#cameraWorkout #coachOverlay{z-index:3}\r\n/* Pause reason and manual rep correction under the counter; small, legible at 375×812, above the housing. */\r\n#cameraWorkout .camera-workout-status{position:absolute;top:calc(max(24px,env(safe-area-inset-top)) + 96px);left:50%;transform:translateX(-50%);z-index:2;width:max-content;max-width:calc(100vw - 48px);margin:0;padding:6px 12px;border-radius:12px;background:#000a;color:#fff;font:600 15px/1.3 system-ui,sans-serif;text-align:center}\r\n#cameraWorkout .camera-workout-status[hidden],#cameraWorkout .camera-workout-adjust[hidden]{display:none}\r\n#cameraWorkout .camera-workout-adjust{position:absolute;bottom:max(24px,env(safe-area-inset-bottom));left:50%;transform:translateX(-50%);z-index:2;display:flex;gap:16px}\r\n#cameraWorkout .camera-workout-adjust button{min-width:56px;min-height:44px;border:0;border-radius:12px;background:#0008;color:#fff;font:700 18px/1 ui-monospace,monospace;touch-action:manipulation}\r\n#cameraWorkout .camera-workout-adjust button:focus-visible{outline:3px solid white;outline-offset:2px}\r\n","camera-workout.mjs":"export function mountCameraWorkout({video,counter,onStop,onAdjust=()=>{}}){\r\n const stage=document.createElement('section');stage.id='cameraWorkout';stage.hidden=true;stage.setAttribute('aria-label','Camera workout');\r\n const stop=document.createElement('button');stop.type='button';stop.className='camera-workout-counter';stop.setAttribute('aria-label','Stop workout');stop.title='Tap the counter to stop';stage.append(stop);\r\n // One status line and a downward correction for false camera reps, under the counter.\r\n const statusLine=document.createElement('p');statusLine.className='camera-workout-status';statusLine.setAttribute('role','status');statusLine.hidden=true;\r\n const adjust=document.createElement('div');adjust.className='camera-workout-adjust';adjust.hidden=true;\r\n for(const [delta,text,label] of [[-1,'−1','Remove one rep']]){const button=document.createElement('button');button.type='button';button.textContent=text;button.setAttribute('aria-label',label);button.addEventListener('click',()=>onAdjust(delta));adjust.append(button);}\r\n stage.append(statusLine,adjust);\r\n // The AR coach is the one exception to camera-only mode (D24): a pointer-events:none layer above the\r\n // video and counter, so a fast knee/ankle can still register on the video underneath.\r\n const coachOverlay=document.createElement('div');coachOverlay.id='coachOverlay';stage.append(coachOverlay);\r\n document.body.append(stage);\r\n // Dev-only: ?recordPose=1 records landmarks and up/down labels for k-NN samples (scripts/pose-samples.mjs).\r\n if(new URLSearchParams(location.search).get('recordPose')==='1')import('./pose-recorder.mjs').then(({mountPoseRecorder})=>mountPoseRecorder(stage));\r\n let active=false,anchors=[],inert=[],links=[],housing=null,token=0;\r\n // Metal housing + feathered strip AROUND the edge (Ian asked for it); the middle of the video stays clear and the frame ignores pointers.\r\n // Reuses the standalone housing markup and styles, so it needs no #portalChrome.\r\n const showHousing=async()=>{const mine=++token;try{\r\n  const [{frameMarkup,paintHousing},...sheets]=await Promise.all([import('./modules/portal/standalone-housing.mjs'),...['/modules/portal/portal.css','/modules/portal/standalone-housing.css'].map(href=>new Promise(resolve=>{const link=document.createElement('link');link.rel='stylesheet';link.href=href;link.onload=link.onerror=()=>resolve(link);document.head.append(link);}))]);\r\n  if(!active||mine!==token){sheets.forEach(link=>link.remove());return;}\r\n  links=sheets;housing=document.createElement('div');housing.className='camera-workout-housing';housing.setAttribute('aria-hidden','true');housing.innerHTML=frameMarkup();paintHousing(housing,document);stage.classList.add('portal-standalone');stage.insertBefore(housing,coachOverlay);\r\n }catch{}};\r\n const hideHousing=()=>{token++;housing?.remove();housing=null;links.forEach(link=>link.remove());links=[];stage.classList.remove('portal-standalone');};\r\n stop.addEventListener('click',()=>onStop());\r\n stage.addEventListener('keydown',event=>{if(event.key==='Escape'){event.preventDefault();onStop();}});\r\n return {show({status='',reps=false}){statusLine.textContent=status;statusLine.hidden=!status;adjust.hidden=!reps;},\r\n setActive(next){if(next===active)return;active=next;\r\n if(next){\r\n  anchors=[video,counter].map(node=>{const marker=document.createComment('camera-workout-return');node.before(marker);return [node,marker];});\r\n  stage.prepend(video);stop.append(counter);stage.hidden=false;stage.inert=false;document.body.dataset.cameraWorkout='true';\r\n  inert=[...document.body.children].filter(node=>node!==stage).map(node=>[node,node.inert]);for(const [node] of inert)node.inert=true;\r\n  stop.focus({preventScroll:true});void showHousing();\r\n }else{\r\n  hideHousing();\r\n  for(const [node,marker] of anchors){marker.replaceWith(node);}anchors=[];\r\n  for(const [node,value] of inert)node.inert=value;inert=[];stage.hidden=true;delete document.body.dataset.cameraWorkout;\r\n }\r\n }};\r\n}\r\n","camera.mjs":"// Camera choices come from the browser, never guessed from camera numbering.\r\n// AGPL-3.0-or-later, like the accompanying app.\r\nexport const deviceChoice=id=>'device:'+id;\r\nexport function cameraConstraints(choice='environment',fps=30){\r\n  const source=choice.startsWith('device:')?{deviceId:{exact:choice.slice(7)}}:{facingMode:{ideal:choice}};\r\n  return {audio:false,video:{...source,width:{ideal:640},height:{ideal:480},frameRate:{ideal:fps,max:30},resizeMode:'none'}};\r\n}\r\nexport async function listCameras(){return (await navigator.mediaDevices.enumerateDevices()).filter(d=>d.kind==='videoinput'&&d.deviceId).map(d=>({id:d.deviceId,label:d.label}));}\r\nexport async function openCamera(choice='environment',fps=30,devices=navigator.mediaDevices,{signal,timeoutMs=20000}={}){\r\n  let cancelled=false,timer,onAbort;\r\n  const cancelledError=()=>new DOMException('Camera startup cancelled.','AbortError');\r\n  const acquisition=(async()=>{\r\n  let resolved=choice;\r\n  if(!choice.startsWith('device:')){\r\n    // Once permission exposes device labels, select the requested camera exactly.\r\n    // An ideal facing preference alone can otherwise return a different camera.\r\n    try{const pattern=choice==='user'?/(front|user|selfie)/i:/(back|rear|environment)/i;const match=(await devices.enumerateDevices()).find(d=>d.kind==='videoinput'&&d.deviceId&&pattern.test(d.label));if(match)resolved=deviceChoice(match.deviceId);}catch{}\r\n  }\r\n  if(cancelled||signal?.aborted)throw cancelledError();\r\n  const incoming=await devices.getUserMedia(cameraConstraints(resolved,fps));\r\n  if(cancelled||signal?.aborted){incoming.getTracks().forEach(track=>track.stop());throw cancelledError();}\r\n  return incoming;\r\n  })();\r\n  const cancellation=new Promise((_,reject)=>{\r\n    onAbort=()=>{cancelled=true;reject(cancelledError());};\r\n    signal?.addEventListener('abort',onAbort,{once:true});\r\n    if(signal?.aborted)onAbort();\r\n    timer=setTimeout(()=>{cancelled=true;reject(new Error('Camera permission is still pending. Allow camera access in your browser, then tap Begin again.'));},timeoutMs);\r\n  });\r\n  try{return await Promise.race([acquisition,cancellation]);}\r\n  finally{clearTimeout(timer);signal?.removeEventListener('abort',onAbort);}\r\n}\r\nexport function findUltrawide(cameras){return cameras.find(d=>!/(front|user|facetime|selfie)/i.test(d.label)&&/(ultra[\\s-]?wide|ultrawide|0[.,][56]\\s*[x×])/i.test(d.label));}\r\nexport function cameraFacing(track,choice){const settings=track.getSettings();return settings.facingMode||(/(front|user|selfie)/i.test(track.label)||choice==='user'?'user':'environment');}\r\nexport async function widestZoom(track){\r\n  const capabilities=track.getCapabilities?.()||{},range=capabilities.zoom;\r\n  const supported=range&&Number.isFinite(range.min)&&Number.isFinite(range.max)&&range.min>0&&range.max>=range.min;\r\n  if(!supported)return {supported:false,applied:false,zoom:track.getSettings().zoom??null};\r\n  try{\r\n    await track.applyConstraints({advanced:[{zoom:range.min}]});\r\n    const zoom=track.getSettings().zoom;\r\n    return {supported:true,applied:Number.isFinite(zoom)&&Math.abs(zoom-range.min)<.01,min:range.min,max:range.max,zoom:zoom??null};\r\n  }catch(error){return {supported:true,applied:false,min:range.min,max:range.max,zoom:track.getSettings().zoom??null,error:error.message};}\r\n}\r\nexport function cameraReport(track,cameras,zoom){\r\n  const settings=track.getSettings();return {version:'feet-optional-3',label:track.label||'Camera',facing:settings.facingMode||'',width:settings.width||0,height:settings.height||0,zoom,lenses:cameras.map(d=>d.label||'Unnamed camera')};\r\n}\r\n","character-phone-physics.mjs":"/**\r\n * Deterministic phone-orientation physics for the customizer character.\r\n * Coordinates are CSS-pixel offsets from the centered resting pose. `gx` points\r\n * screen-right and `gy` screen-down; upright is (0, 1). `shake` is acceleration\r\n * magnitude in m/s² (shake impulses above 14 m/s²) and angularSpeed is\r\n * radians/second. Poses are renderer hints (`wiggle` for unsupported midair,\r\n * `greet` for the midpoint wave, `walk` for recovery). The adapter owns sensor\r\n * permissions, reduced-motion policy, rendering, and persistence.\r\n */\r\nexport function createCharacterPhysics({\r\n  width,\r\n  height,\r\n  bodyWidth,\r\n  bodyHeight,\r\n  buffer = 96,\r\n  ship = false,\r\n  climb = true,\r\n  safeTiltDegrees = 22.5,\r\n  contain = false,\r\n  tiltExit = false,\r\n} = {}) {\r\n  const safeDimension = (value, fallback = 1) => Number.isFinite(value) ? Math.max(1, value) : fallback;\r\n  const view = { width: safeDimension(width), height: safeDimension(height) };\r\n  const body = { width: safeDimension(bodyWidth), height: safeDimension(bodyHeight) };\r\n  const margin = Math.max(0, Number.isFinite(buffer) ? buffer : 96);\r\n  const restCenter = { x: null, y: null };\r\n  let hasShip = Boolean(ship);\r\n  const safeTilt = Math.max(0, Math.min(60, safeTiltDegrees)) * Math.PI / 180;\r\n  const state = { x: 0, y: 0, angle: 0, phase: 'idle', pose: 'idle', active: false, shipProgress: 0 };\r\n\r\n  let vx = 0;\r\n  let vy = 0;\r\n  let phaseAge = 0;\r\n  let gravityX = 0;\r\n  let gravityY = 1;\r\n  let shakeArmed = true;\r\n  let angularArmed = true;\r\n  let fallHold = 0;\r\n  let tiltHold = 0;\r\n  let fallAge = 0;\r\n  let recoverAfterFall = false;\r\n  let tiltExitFall = false;\r\n  let fallGravity = { x: 0, y: 1 };\r\n  let recoveryStart = { x: 0, y: 0 };\r\n  let climbStart = { x: 0, y: 0 };\r\n  let edge = { x: 0, y: 1 };\r\n  let lastTime = 0;\r\n\r\n  const rotatedHalfExtents = () => {\r\n    const c = Math.abs(Math.cos(state.angle)), s = Math.abs(Math.sin(state.angle));\r\n    return { width: (body.width * c + body.height * s) / 2, height: (body.height * c + body.width * s) / 2 };\r\n  };\r\n  const exitBounds = () => {\r\n    const half = rotatedHalfExtents();\r\n    return { left: -view.width / 2 - margin - half.width, right: view.width / 2 + margin + half.width,\r\n      top: -view.height / 2 - margin - half.height, bottom: view.height / 2 + margin + half.height };\r\n  };\r\n  const centerBounds = () => {\r\n    if (!contain) return exitBounds();\r\n    const c = Math.abs(Math.cos(state.angle)), s = Math.abs(Math.sin(state.angle));\r\n    const halfW = Math.min(view.width / 2, (body.width * c + body.height * s) / 2);\r\n    const halfH = Math.min(view.height / 2, (body.height * c + body.width * s) / 2);\r\n    const ox = restCenter.x ?? view.width / 2, oy = restCenter.y ?? view.height / 2;\r\n    return { left: -ox + halfW, right: view.width - ox - halfW, top: -oy + halfH, bottom: view.height - oy - halfH };\r\n  };\r\n  const setPhase = (phase, pose = phase) => {\r\n    state.phase = phase;\r\n    state.pose = pose;\r\n    phaseAge = 0;\r\n    state.active = phase !== 'idle' && phase !== 'gone';\r\n  };\r\n  const gravityAngle = () => Math.atan2(gravityX, gravityY);\r\n  const snapshot = () => ({ ...state });\r\n  const supported = () => Math.abs(gravityX) < 0.2 && gravityY > 0.8;\r\n  const sideways = () => Math.abs(Math.atan2(gravityX, gravityY)) >= 89 * Math.PI / 180;\r\n  const setFallEdge = () => {\r\n    const length = Math.hypot(gravityX, gravityY) || 1;\r\n    edge = { x: gravityX / length, y: gravityY / length };\r\n    fallGravity = { x: gravityX, y: gravityY };\r\n  };\r\n  const fallExitDistance = () => {\r\n    const half = rotatedHalfExtents();\r\n    const ox = (restCenter.x ?? view.width / 2) - view.width / 2;\r\n    const oy = (restCenter.y ?? view.height / 2) - view.height / 2;\r\n    return Math.abs(edge.x) * (view.width / 2 + half.width + margin)\r\n      + Math.abs(edge.y) * (view.height / 2 + half.height + margin)\r\n      - ox * edge.x - oy * edge.y;\r\n  };\r\n  const startFall = (pose = 'fall', canRecover = false) => {\r\n    setFallEdge();\r\n    fallHold = 0;\r\n    fallAge = 0;\r\n    recoverAfterFall = canRecover;\r\n    tiltExitFall = Boolean(tiltExit && canRecover);\r\n    setPhase('fall', pose);\r\n  };\r\n  const clampPosition = (bounce = true) => {\r\n    const b = centerBounds();\r\n    if (state.x < b.left) { state.x = b.left; if (bounce && vx < 0) vx = -vx * 0.68; }\r\n    if (state.x > b.right) { state.x = b.right; if (bounce && vx > 0) vx = -vx * 0.68; }\r\n    if (state.y < b.top) { state.y = b.top; if (bounce && vy < 0) vy = -vy * 0.68; }\r\n    if (state.y > b.bottom) { state.y = b.bottom; if (bounce && vy > 0) vy = -vy * 0.58; }\r\n  };\r\n  const lerp = (a, b, t) => a + (b - a) * Math.max(0, Math.min(1, t));\r\n  const enterRecovery = () => {\r\n    // Return along the original platform, never diagonally through the air.\r\n    state.y = 0; state.angle = 0;\r\n    recoveryStart = { x: state.x, y: 0 };\r\n    vx = 0;\r\n    vy = 0;\r\n    recoverAfterFall = false;\r\n    tiltExitFall = false;\r\n    state.shipProgress = 0;\r\n    setPhase('recover', 'walk');\r\n  };\r\n  const beginClimb = () => {\r\n    climbStart = { x: state.x, y: state.y };\r\n    vx = 0;\r\n    vy = 0;\r\n    tiltExitFall = false;\r\n    setPhase('climb', 'climb');\r\n  };\r\n\r\n  function sample(input = {}, timeSeconds = 0) {\r\n    const wasSupported = supported();\r\n    const rawX = Number.isFinite(input.gx) ? input.gx : gravityX;\r\n    const rawY = Number.isFinite(input.gy) ? input.gy : gravityY;\r\n    const norm = Math.hypot(rawX, rawY);\r\n    if (norm > 0.05) {\r\n      gravityX = rawX / norm;\r\n      gravityY = rawY / norm;\r\n    }\r\n    const neutralTilt = Math.abs(Math.atan2(gravityX, gravityY)) <= safeTilt + 1e-9;\r\n    if (neutralTilt) { gravityX = 0; gravityY = 1; }\r\n    const angular = Number.isFinite(input.angularSpeed) ? Math.abs(input.angularSpeed) : 0;\r\n    const shake = Number.isFinite(input.shake) ? Math.max(0, input.shake) : 0;\r\n    const now = Number.isFinite(timeSeconds) ? timeSeconds : lastTime;\r\n    lastTime = now;\r\n\r\n    if (shake <= 7) shakeArmed = true;\r\n    if (angular < 1.2) angularArmed = true;\r\n\r\n    // An impulse is edge-triggered, so one sustained sensor reading cannot pin\r\n    // the character against a wall. A renewed pulse can add another impulse.\r\n    let shakeTriggered = false;\r\n    if (shake > 14 && shakeArmed && !(shake < 30 && angular > 2 && !sideways())) {\r\n      shakeTriggered = true;\r\n      shakeArmed = false;\r\n      const direction = ((Math.floor(Math.max(0, now) * 10) % 2) ? 1 : -1);\r\n      vx += direction * Math.min(1500, shake * 20);\r\n      vy -= Math.min(780, shake * 10);\r\n      if (['climb', 'wave', 'climb-out'].includes(state.phase)) startFall('fall');\r\n      else if (state.phase === 'idle' || state.phase === 'slide' || state.phase === 'recover') startFall('fall');\r\n      else if (state.phase === 'fall' || state.phase === 'bounce') {\r\n        recoverAfterFall = false;\r\n        tiltExitFall = false;\r\n        clampPosition(true);\r\n      }\r\n      else if (state.phase === 'air-run' || state.phase === 'look-down') { recoverAfterFall = false; tiltExitFall = false; }\r\n    }\r\n\r\n    if (sideways() && angular > 2 && angularArmed && !(state.phase === 'recover' && supported()) && !['air-run', 'look-down', 'climb', 'wave', 'climb-out', 'ship', 'gone'].includes(state.phase)) {\r\n      angularArmed = false;\r\n      setFallEdge();\r\n      fallHold = 0;\r\n      fallAge = 0;\r\n      recoverAfterFall = !shakeTriggered;\r\n      tiltExitFall = false;\r\n      setPhase('air-run', 'wiggle');\r\n    }\r\n\r\n    // A slow orientation change moves the supported coach across the glass.\r\n    if (state.phase === 'idle' && (!supported() || Math.abs(vx) > 18)) { tiltHold = 0; setPhase('slide', 'slide'); }\r\n    if (['idle', 'slide'].includes(state.phase)) state.angle = Math.max(-.35, Math.min(.35, gravityAngle()));\r\n    if (['fall', 'bounce'].includes(state.phase)) setFallEdge();\r\n    if (!wasSupported && supported() && ['slide', 'fall', 'bounce', 'climb', 'wave', 'climb-out', 'ship', 'gone'].includes(state.phase)) enterRecovery();\r\n    if (!['idle', 'slide', 'recover'].includes(state.phase)) state.angle = gravityAngle();\r\n\r\n    return snapshot();\r\n  }\r\n\r\n  function step(dt) {\r\n    let remaining = Number.isFinite(dt) ? Math.max(0, Math.min(10, dt)) : 0;\r\n    while (remaining > 1e-9) {\r\n      const h = Math.min(remaining, 1 / 60);\r\n      remaining -= h;\r\n      phaseAge += h;\r\n\r\n      if (['air-run', 'look-down'].includes(state.phase)) {\r\n        if (state.phase === 'air-run' && phaseAge >= 0.6 - 1e-6) { setPhase('look-down', 'look-down'); continue; }\r\n        if (state.phase === 'look-down' && phaseAge >= 0.45 - 1e-6) { startFall('fall', recoverAfterFall); continue; }\r\n      }\r\n\r\n      if (state.phase === 'fall' || state.phase === 'bounce') {\r\n        // Keep the falling vector aligned with fresh device samples. The edge\r\n        // remembered at fall start is only used to choose the later climb path.\r\n        fallGravity = { x: gravityX, y: gravityY };\r\n        const gravityLength = Math.hypot(gravityX, gravityY) || 1;\r\n        edge = { x: gravityX / gravityLength, y: gravityY / gravityLength };\r\n        fallAge += h;\r\n        fallHold = sideways() ? fallHold + h : 0;\r\n        if (climb && fallHold >= 2 - 1 / 60) { beginClimb(); continue; }\r\n        if (recoverAfterFall && supported() && fallAge >= 0.25) { enterRecovery(); continue; }\r\n        let acceleration = 620;\r\n        if (tiltExit && tiltExitFall) {\r\n          const remaining = Math.max(1 / 60, 1.15 - fallAge);\r\n          const alongVelocity = vx * edge.x + vy * edge.y;\r\n          const distance = fallExitDistance() + 2 - state.x * edge.x - state.y * edge.y;\r\n          acceleration = Math.max(acceleration, 2 * Math.max(0, distance - alongVelocity * remaining) / (remaining * remaining));\r\n        }\r\n        vx += fallGravity.x * acceleration * h;\r\n        vy += fallGravity.y * acceleration * h;\r\n        state.x += vx * h;\r\n        state.y += vy * h;\r\n        if (supported() && state.y > 0) {\r\n          state.y = 0;\r\n          if (vy > 35) { vy = -vy * 0.28; setPhase('bounce', 'wiggle'); }\r\n          else {\r\n            vy = 0;\r\n            if (Math.abs(vx) < 30) { enterRecovery(); continue; }\r\n          }\r\n        }\r\n        state.angle = gravityAngle();\r\n        const beforeX = state.x;\r\n        const beforeY = state.y;\r\n        if (!(tiltExit && tiltExitFall)) clampPosition(true);\r\n        if (state.x !== beforeX || state.y !== beforeY) {\r\n          if (state.phase !== 'bounce') setPhase('bounce', 'wiggle');\r\n        } else if (state.phase === 'bounce' && phaseAge > 0.35) setPhase('fall', 'fall');\r\n        const drag = tiltExit && tiltExitFall ? 1 : Math.pow(0.985, h * 60);\r\n        vx *= drag;\r\n        vy *= drag;\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'climb') {\r\n        state.angle = gravityAngle();\r\n        const t = phaseAge / 3;\r\n        state.x = lerp(climbStart.x, 0, t);\r\n        state.y = lerp(climbStart.y, 0, t);\r\n        if (t >= 1 - 1e-6) { climbStart = { x: state.x, y: state.y }; setPhase('wave', 'wave'); }\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'wave') {\r\n        state.angle = gravityAngle();\r\n        state.pose = 'greet';\r\n        if (phaseAge >= 2 - 1e-6) { climbStart = { x: state.x, y: state.y }; setPhase('climb-out', 'climb'); }\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'climb-out') {\r\n        state.angle = gravityAngle();\r\n        const t = phaseAge / 3;\r\n        const b = exitBounds();\r\n        const targetX = edge.x ? (edge.x > 0 ? b.left : b.right) : 0;\r\n        const targetY = edge.y ? (edge.y > 0 ? b.top : b.bottom) : b.top;\r\n        state.x = lerp(climbStart.x, targetX, t);\r\n        state.y = lerp(climbStart.y, targetY, t);\r\n        if (t >= 1 - 1e-6) {\r\n          if (hasShip) setPhase('ship', 'ship');\r\n          else setPhase('gone', 'gone');\r\n        }\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'ship') {\r\n        state.shipProgress = Math.min(1, phaseAge / 2);\r\n        if (state.shipProgress >= 1) setPhase('gone', 'gone');\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'recover') {\r\n        const t = phaseAge / 3;\r\n        state.x = lerp(recoveryStart.x, 0, t);\r\n        state.y = lerp(recoveryStart.y, 0, t);\r\n        state.angle = lerp(state.angle, 0, Math.min(1, h * 3));\r\n        if (t >= 1) {\r\n          state.x = 0; state.y = 0; state.angle = 0; vx = 0; vy = 0;\r\n          setPhase('idle', 'idle');\r\n        }\r\n        continue;\r\n      }\r\n\r\n      if (state.phase === 'slide') {\r\n        tiltHold = sideways() ? tiltHold + h : 0;\r\n        if (tiltHold >= 0.8) { startFall('fall', tiltExit); continue; }\r\n        vx += gravityX * 480 * h;\r\n        vx *= Math.pow(0.91, h * 60);\r\n        state.x += vx * h;\r\n        const slideLimit = view.width * .15;\r\n        state.x = Math.max(-slideLimit, Math.min(slideLimit, state.x));\r\n        state.y = lerp(state.y, 0, Math.min(1, h * 2));\r\n        clampPosition(true);\r\n        if (supported() && Math.abs(vx) < 8 && Math.abs(state.x) < 4) {\r\n          state.x = 0; state.y = 0; vx = 0;\r\n          setPhase('idle', 'idle');\r\n        }\r\n      }\r\n    }\r\n    state.active = state.phase !== 'idle' && state.phase !== 'gone';\r\n    return snapshot();\r\n  }\r\n\r\n  function resize(nextWidth, nextHeight, nextBodyWidth, nextBodyHeight) {\r\n    view.width = safeDimension(nextWidth, view.width);\r\n    view.height = safeDimension(nextHeight, view.height);\r\n    body.width = safeDimension(nextBodyWidth, body.width);\r\n    body.height = safeDimension(nextBodyHeight, body.height);\r\n    // A standing character belongs at its calibrated rest anchor. Early hidden\r\n    // layout measurements must not push it below the eventual platform.\r\n    if (state.phase === 'idle') { state.x = 0; state.y = 0; }\r\n    else if (!['recover', 'climb-out', 'ship', 'gone'].includes(state.phase)) clampPosition(false);\r\n    return snapshot();\r\n  }\r\n\r\n  function setRestCenter(x, y) {\r\n    restCenter.x = Number.isFinite(x) ? x : null;\r\n    restCenter.y = Number.isFinite(y) ? y : null;\r\n  }\r\n\r\n  function reset() {\r\n    state.x = 0; state.y = 0; state.angle = 0; state.shipProgress = 0;\r\n    setPhase('idle', 'idle');\r\n    vx = 0; vy = 0; phaseAge = 0; fallHold = 0; tiltHold = 0; fallAge = 0; recoverAfterFall = false; tiltExitFall = false;\r\n    gravityX = 0; gravityY = 1; lastTime = 0;\r\n    shakeArmed = true; angularArmed = true;\r\n    return snapshot();\r\n  }\r\n\r\n  // Adapters enable boarding only after the selected, authorized model has loaded.\r\n  const setShipAvailable = available => { hasShip = Boolean(available); };\r\n  return { sample, step, resize, reset, setShipAvailable, setRestCenter, state };\r\n}\r\n","character-phone-sensor.mjs":"// Full gravity is independent of the decorative, calibrated room parallax.\r\nexport function screenGravity(x,y,angle=0){const a=angle*Math.PI/180,c=Math.cos(a),s=Math.sin(a);return {gx:x*c+y*s,gy:-x*s+y*c};}\r\n// Look-around tilt for every room, the ship, the pod and the customizer. Read from the gravity vector, not raw\r\n// beta/gamma deltas: held upright (beta near 90, how iPhones are held) gamma is gimbal-locked, so any small twist\r\n// swings it tens of degrees, and it wraps at +-90 (or flips by 180 with beta past vertical); gravity is smooth through both.\r\n// The angle the phone is held at is zero and that zero follows the hold (time-based, ~95% in recentreS), so the\r\n// view settles wherever it is held. Real phones need tuning: maxDeg = tilt for full look, deadDeg = ignored wobble,\r\n// gain = output at full look (1 = each consumer's full px), recentreS = seconds to re-centre on a new hold.\r\nexport const TILT={gain:1,maxDeg:18,deadDeg:1.5,recentreS:3};\r\nconst wrap180=a=>((a+180)%360+360)%360-180;\r\nexport function createTiltLook(view=globalThis,knobs=TILT){\r\n let base=null,at=0;\r\n const out=d=>{const m=Math.max(0,Math.abs(d)-knobs.deadDeg);return Math.sign(d)*knobs.gain*Math.min(1,m/(knobs.maxDeg-knobs.deadDeg));};\r\n return {\r\n  reset(){base=null;},\r\n  /** {x,y} in -gain..gain (x right, y top edge back), or null for an empty reading. now: ms, defaults to the event's. */\r\n  read(event,now=event?.timeStamp??0){\r\n   if(!Number.isFinite(event?.beta)||!Number.isFinite(event?.gamma))return null;\r\n   const b=event.beta*Math.PI/180,g=event.gamma*Math.PI/180,deg=180/Math.PI;\r\n   const {gx,gy}=screenGravity(Math.cos(b)*Math.sin(g),Math.sin(b),view?.screen?.orientation?.angle??view?.orientation??0),gz=Math.cos(b)*Math.cos(g);\r\n   const roll=Math.atan2(gx,Math.hypot(gy,gz))*deg,pitch=Math.atan2(gy,gz)*deg;\r\n   if(!base){base={roll,pitch};at=now;}\r\n   // dt capped so a pause in events (hidden page, test gaps) is not counted as a long hold.\r\n   const k=1-Math.exp(-Math.min(.1,Math.max(0,(now-at)/1000))*3/knobs.recentreS);at=now;\r\n   base.roll+=(roll-base.roll)*k;base.pitch+=wrap180(pitch-base.pitch)*k;\r\n   return {x:out(roll-base.roll),y:out(wrap180(pitch-base.pitch))};\r\n  }\r\n };\r\n}\r\nexport function createPhoneMotionSource(view=globalThis.window,doc=view?.document){\r\n const listeners=new Set();let running=false,motionAt=-Infinity,lastAngle=null,lastAt=0,lastGravity=null,permission=null;\r\n const now=()=> (view.performance?.now?.()??Date.now())/1000;\r\n const emit=(gravity,shake=0,rotationSpeed=0)=>{\r\n  if(doc?.hidden||!Number.isFinite(gravity.gx)||!Number.isFinite(gravity.gy))return;\r\n  const timeSeconds=now(),length=Math.hypot(gravity.gx,gravity.gy);\r\n  // Pyramid Jump needs the current weak tilt direction even when the stable\r\n  // character heading intentionally holds its last value near flat.\r\n  const steerX=length>=.12/9.81?gravity.gx/length:0;\r\n  // A flat phone has no screen-plane gravity. Hold its last heading, but still\r\n  // deliver gyro and linear-acceleration samples so a shake can trigger motion.\r\n  if(length>=.3)lastGravity={gx:gravity.gx/length,gy:gravity.gy/length};\r\n  const {gx,gy}=lastGravity??{gx:0,gy:1},angle=Math.atan2(gx,gy);\r\n  let angularSpeed=rotationSpeed;if(lastAngle!=null&&timeSeconds>lastAt){const delta=Math.atan2(Math.sin(angle-lastAngle),Math.cos(angle-lastAngle));angularSpeed=Math.max(angularSpeed,Math.abs(delta)/(timeSeconds-lastAt));}\r\n  lastAngle=angle;lastAt=timeSeconds;\r\n  for(const callback of listeners)callback({gx,gy,steerX,shake,angularSpeed,timeSeconds});\r\n };\r\n const screenAngle=()=>view.screen?.orientation?.angle??view.orientation??0;\r\n const motion=event=>{\r\n  const a=event.accelerationIncludingGravity;if(!a||![a.x,a.y].every(Number.isFinite))return;\r\n  const linear=event.acceleration,hasLinear=linear&&[linear.x,linear.y,linear.z].every(Number.isFinite);let shake=hasLinear?Math.hypot(linear.x,linear.y,linear.z):0;\r\n  if(!linear||linear.x==null)shake=Math.abs(Math.hypot(a.x,a.y,a.z??0)-9.81);\r\n  const rate=event.rotationRate;\r\n  // The gyroscope's degrees/second survive delayed delivery when WebGL is busy.\r\n  const rotationSpeed=rate?Math.hypot(...['alpha','beta','gamma'].map(axis=>Number.isFinite(rate[axis])?rate[axis]:0))*Math.PI/180:0;\r\n  motionAt=now();emit(screenGravity(-(a.x-(hasLinear?linear.x:0))/9.81,(a.y-(hasLinear?linear.y:0))/9.81,screenAngle()),Math.min(80,shake),rotationSpeed);\r\n };\r\n const orientation=event=>{\r\n  if(now()-motionAt<.5||!Number.isFinite(event.beta)||!Number.isFinite(event.gamma))return;\r\n  const b=event.beta*Math.PI/180,g=event.gamma*Math.PI/180;\r\n  emit(screenGravity(Math.cos(b)*Math.sin(g),Math.sin(b),screenAngle()));\r\n };\r\n const start=()=>{if(running||!listeners.size)return;running=true;lastAngle=null;lastAt=0;lastGravity=null;view.addEventListener('devicemotion',motion,{passive:true});view.addEventListener('deviceorientation',orientation,{passive:true});};\r\n const stop=()=>{if(!running)return;running=false;view.removeEventListener('devicemotion',motion);view.removeEventListener('deviceorientation',orientation);lastAngle=null;lastGravity=null;};\r\n const request=()=>{\r\n  if(permission)return permission;\r\n  // Both requests must begin in this same tap on iOS, before either promise is awaited.\r\n  const requests=[view.DeviceOrientationEvent,view.DeviceMotionEvent].filter(api=>typeof api?.requestPermission==='function').map(api=>{try{return Promise.resolve(api.requestPermission());}catch{return Promise.resolve('denied');}});\r\n  permission=Promise.all(requests).then(results=>{const granted=results.some(result=>result==='granted')||!requests.length;try{view.localStorage.setItem('myr5.tiltPermission',granted?'granted':'denied');}catch{}if(granted)start();return granted;}).finally(()=>{permission=null;});return permission;\r\n };\r\n const click=event=>{if(event.target?.closest?.('.pod-tilt-request,.editor-tilt-request'))void request();};\r\n const visibility=()=>{lastAngle=null;if(doc?.hidden)stop();else if(allowed())start();};\r\n const allowed=()=>{if(!view.DeviceMotionEvent?.requestPermission&&!view.DeviceOrientationEvent?.requestPermission)return true;try{return view.localStorage.getItem('myr5.tiltPermission')==='granted';}catch{return false;}};\r\n const attach=()=>{doc?.addEventListener('click',click,true);doc?.addEventListener('visibilitychange',visibility);view.addEventListener('pageshow',visibility);view.addEventListener('pagehide',stop);if(allowed())start();};\r\n const detach=()=>{stop();doc?.removeEventListener('click',click,true);doc?.removeEventListener('visibilitychange',visibility);view.removeEventListener('pageshow',visibility);view.removeEventListener('pagehide',stop);};\r\n return {subscribe(callback){listeners.add(callback);if(listeners.size===1)attach();return()=>{listeners.delete(callback);if(!listeners.size)detach();};},request};\r\n}\r\n// The customizer bundle and its separately loaded housing must share one permission request.\r\nconst SOURCE=Symbol.for('myr5.characterPhoneMotion');\r\nconst sharedSource=()=>window[SOURCE]??=(createPhoneMotionSource());\r\nexport function subscribePhoneMotion(callback){return sharedSource().subscribe(callback);}\r\nexport function requestPhoneMotion(){return sharedSource().request();}\r\n","chosen-styles.mjs":"// The user's two chosen workout paths. They live in the owner's performance progress\r\n// (owner-scoped storage, never a global key), so another account on the same device never sees them\r\n// and the server can persist and derive them from the same record.\r\nimport {CHOOSABLE_TRACKS,COACH_REQUIREMENTS,normalizePaths} from './performance-catalog.mjs';\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {readPerformanceProgress,choosePerformancePaths,unlockStatus} from './performance-progress.mjs';\r\nexport {CHOOSABLE_TRACKS};\r\nexport const GROUP_PATH=Object.freeze({chest:'chest',legs:'quads',hips:'glutes',shoulders:'arms-shoulders',core:'yoga',balance:'yoga',yoga:'yoga',stances:'martial-arts',boxing:'martial-arts',cardio:'cardio'});\r\nconst pathTrack=path=>path==='arms-shoulders'?'arms':path;\r\n/** Legacy global key. Nothing reads or writes it any more: it leaked paths between accounts. */\r\nexport const SELECTED_TRACKS_KEY='myr5-selected-tracks-v1';\r\n\r\n/** Chosen path ids (canonical, arms-shoulders for arms) for options.owner/storage/account; [] until chosen. */\r\nexport const readSelectedTracks=(options={})=>readPerformanceProgress(options).paths;\r\n/** A selected path is open; an already owned coach also keeps every one of its mapped paths open. */\r\nexport function workoutPathAccess(mode,options={}){\r\n const group=EXERCISES[mode]?.group,path=GROUP_PATH[group];\r\n if(!path)return {allowed:false,path:null,reason:'Choose a movement in an available workout path.'};\r\n const progress=readPerformanceProgress(options);\r\n if(unlockStatus(progress).done||progress.paths.includes(path))return {allowed:true,path,reason:null};\r\n const owned=new Set(progress.coaches);\r\n if(COACH_REQUIREMENTS.some(coach=>owned.has(coach.id)&&coach.tracks.includes(pathTrack(path))))return {allowed:true,path,reason:null};\r\n return {allowed:false,path,reason:`${path.replaceAll('-',' ')} is locked. Choose it as one of your two paths or earn its coach.`};\r\n}\r\nexport function workoutGroupAccess(group,options={}){\r\n const first=Object.values(EXERCISES).find(exercise=>exercise.group===group);\r\n return workoutPathAccess(first?.id,options);\r\n}\r\n/** One-time choice of exactly 2 paths. Grants each path's introductory coach and persists both.\r\n * Repeating the same pair is a no-op; a different pair throws unless options.reset is true. */\r\nexport function chooseWorkoutPaths(trackIds,options={}){\r\n const picked=normalizePaths(trackIds);\r\n if(picked.length!==2)throw RangeError('Exactly 2 workout paths must be selected.');\r\n return choosePerformancePaths(picked,options).paths;\r\n}\r\nexport const setSelectedTracks=chooseWorkoutPaths;\r\n","circuit-ui.mjs":"// Daily-circuit display (VISUAL-CHANGES-HANDOFF.md §9): a visible meter, outside camera-only\r\n// mode, that advances after every step. Mirrors workout-route-ui.mjs's structure/anchors so it\r\n// sits alongside the existing 10-family ladder without touching it.\r\nimport {CIRCUIT_STEPS} from './circuit.mjs';\r\nconst utcDay=now=>Math.floor(now/86400000);\r\nconst LABEL={pushups:'Push-ups',squats:'Squats',situps:'Sit-ups',meditation:'Meditation',food:'Food photo'};\r\n// Exact `default` lines from plan/muse/voice-lines.csv (one variant per step -- only one voice\r\n// style exists today). Food gets no line (D9/D15: \"Food photo gets no voice line\").\r\nconst NEXT_LINE={pushups:'Next up: pushups. Chest day energy.',squats:'Next: squats. Legs, assemble.',situps:'Situps next. Crunch time, literally.',meditation:'Next: meditation. Sit. Breathe. Done.'};\r\nconst CIRCUIT_DONE_LINE='Circuit done. Rest, champion.';\r\n\r\nexport function mountCircuitUI({voice,onNext,busy,pending,cached}){\r\n const card=document.createElement('section');card.className='daily-circuit';card.setAttribute('aria-label','Your daily circuit');\r\n card.innerHTML='<small>DAILY CIRCUIT</small><meter min=\"0\" max=\"5\" value=\"0\" aria-label=\"Circuit steps completed today\"></meter><p data-circuit-status role=\"status\">Connecting your daily circuit…</p><ol data-circuit-steps></ol><button type=\"button\" data-circuit-next hidden>Start next step →</button>';\r\n // W2-2M #117: the daily circuit is the pod's Goals drop-down (pose.html #podGoals), with the route card under it.\r\n const goals=document.getElementById('podGoals');goals.querySelector('.pod-goals-menu').prepend(card);\r\n // A drop-down: Escape, a tap outside it, or picking one of its actions folds it back up.\r\n goals.addEventListener('keydown',event=>{if(event.key==='Escape'&&goals.open){goals.open=false;goals.querySelector('summary').focus();}});\r\n document.addEventListener('pointerdown',event=>{if(goals.open&&!goals.contains(event.target))goals.open=false;});\r\n goals.addEventListener('click',event=>{if(event.target.closest('.pod-goals-menu button'))goals.open=false;});\r\n const rest=document.createElement('section');rest.className='daily-circuit rest-circuit';rest.hidden=true;rest.setAttribute('aria-label','Daily circuit progress');\r\n rest.innerHTML='<meter min=\"0\" max=\"5\" value=\"0\" aria-label=\"Circuit steps completed today\"></meter><p data-circuit-status role=\"status\"></p>';\r\n document.querySelector('.rest-receipt').after(rest);\r\n let announced=null; // {day, doneCount} -- baseline so reopening the app never re-speaks history.\r\n function data(){\r\n  const today=utcDay(Date.now());\r\n  const fresh=window.coachProgress?.circuit;if(fresh&&fresh.day===today)return fresh;\r\n  // No fresh server payload yet (e.g. app just reopened) -- fall back to the last-synced\r\n  // snapshot cached in localStorage so a same-day circuit-in-progress survives close/reopen.\r\n  const stale=cached?.();return stale&&stale.day===today?stale:null;\r\n }\r\n function nextStep(today){return CIRCUIT_STEPS.find(step=>!today.stepDone[step.key])||null;}\r\n // The meter tracks the fixed 5-step CIRCUIT checklist (this card's own job). today.stepsToday\r\n // is a different D15 pass-track count (up to 3 styles + food + meditation, for battle-pass\r\n // leveling) and can be lower than the checklist count -- e.g. the sit-ups stand-in exercise\r\n // completes a circuit step but is not a \"chosen style\", so it earns no pass-track step.\r\n function doneCount(today){return CIRCUIT_STEPS.filter(step=>today.stepDone[step.key]).length;}\r\n function render(){\r\n  const p=data(),today=p?.today;\r\n  for(const meter of [card.querySelector('meter'),rest.querySelector('meter')])meter.value=today?doneCount(today):0;\r\n  const status=today?`${doneCount(today)} of ${CIRCUIT_STEPS.length} circuit steps today`+(nextStep(today)?` · Next: ${LABEL[nextStep(today).key]}`:' · Circuit complete today'):'Connecting your daily circuit…';\r\n  card.querySelector('[data-circuit-status]').textContent=status;rest.querySelector('[data-circuit-status]').textContent=status;\r\n  goals.querySelector('[data-goals-status]').textContent=today?`${doneCount(today)}/${CIRCUIT_STEPS.length}`:'';\r\n  card.querySelector('[data-circuit-steps]').replaceChildren(...CIRCUIT_STEPS.map(step=>{const li=document.createElement('li');li.textContent=`${today?.stepDone?.[step.key]?'✓ ':''}${LABEL[step.key]}`;if(today&&!today.stepDone[step.key]&&step===nextStep(today))li.setAttribute('aria-current','step');return li;}));\r\n  const button=card.querySelector('[data-circuit-next]'),next=today?nextStep(today):null;\r\n  button.hidden=!next;\r\n  if(next){button.textContent='Start '+LABEL[next.key]+' →';button.disabled=busy()||pending();}\r\n }\r\n card.querySelector('[data-circuit-next]').onclick=()=>{\r\n  const p=data(),today=p?.today,next=today?nextStep(today):null;if(!next||busy()||pending())return;\r\n  if(next.key==='meditation')document.querySelector('.meditation-entry')?.click();\r\n  else if(next.key==='food')document.querySelector('[data-panel=\"meals\"]')?.click();\r\n  else onNext(next);\r\n };\r\n function speakTransition(){\r\n  const p=data();if(!p)return;\r\n  const count=doneCount(p.today);\r\n  if(!announced||announced.day!==p.day){announced={day:p.day,doneCount:count};return;} // new day/session: don't replay history\r\n  if(count<=announced.doneCount)return;\r\n  announced.doneCount=count;\r\n  const next=nextStep(p.today);\r\n  if(next&&next.voice)voice.say(NEXT_LINE[next.key],{key:'circuit',interrupt:true});\r\n  else if(!next)voice.say(CIRCUIT_DONE_LINE,{key:'circuit',interrupt:true});\r\n }\r\n window.addEventListener('myr5:account-progress',()=>{speakTransition();render();});\r\n window.addEventListener('myr5:account-cleared',render);\r\n window.addEventListener('myr5:movement-configured',render);\r\n render();\r\n return {render};\r\n}\r\n","circuit.mjs":"// Daily circuit (VISUAL-CHANGES-HANDOFF.md §9): 10 push-ups -> 10 squats -> 10 sit-ups ->\r\n// meditation -> food photo. This module is pure logic only (no DOM, no DB) so it can be\r\n// shared by the server (server/worker.mjs, computing from real rows) and the client\r\n// (circuit-ui.mjs, rendering window.coachProgress.circuit) and unit tested directly.\r\nimport {exerciseFamily} from './workout-route.mjs';\r\n\r\n// ponytail: no sit-up/crunch pose detector exists anywhere in exercise-library.mjs or\r\n// movement-engine.mjs (only isometric core holds: plank/side-plank). Building a real one is\r\n// a movement-detection project, out of scope for \"circuit meter + voice\". Standing in with\r\n// the existing \"High plank\" core hold until a real sit-up detector ships -- see\r\n// plan/reports/circuit.md for the flagged gap. Manual mode (the tested path) does not care\r\n// which exercise id is used; only camera mode would show the \"wrong\" movement name.\r\nexport const CIRCUIT_STEPS=Object.freeze([\r\n {key:'pushups',mode:'pushup',goal:10,voice:true},\r\n {key:'squats',mode:'squat',goal:10,voice:true},\r\n {key:'situps',mode:'high-plank',goal:15,voice:true},\r\n {key:'meditation',mode:null,goal:null,voice:true},\r\n {key:'food',mode:null,goal:null,voice:false},\r\n]);\r\n\r\n// D25 collapses the 10 exercise-library focus groups into the 8 dial sections; meditation\r\n// (core+balance) is a constant track (D9), never a \"chosen\" style, so it is left out here --\r\n// its step comes only from a completed breathing round, not from completing a core/balance set.\r\nexport const STYLE_OF_GROUP=Object.freeze({chest:'chest',legs:'legs',hips:'hips',shoulders:'shoulders',yoga:'yoga',stances:'martial-arts',boxing:'martial-arts',cardio:'cardio'});\r\nexport const STYLES=Object.freeze(['chest','legs','hips','shoulders','yoga','martial-arts','cardio']);\r\nexport const STEP_TRACKS=Object.freeze([...STYLES,'meditation','food']);\r\nexport const MAX_STYLE_STEPS_PER_DAY=3;\r\nexport const MAX_STEPS_PER_DAY=5; // 3 styles + food + meditation. 5/day * 7 days = 35/week (D15) falls out for free.\r\nexport const STEPS_PER_LEVEL=5,LEVELS_PER_TRACK=5;\r\nexport const trackLevel=steps=>Math.min(LEVELS_PER_TRACK,1+Math.floor(Math.max(0,Number(steps)||0)/STEPS_PER_LEVEL));\r\n\r\n// rows: [{mode,day,sets}] -- exactly server/worker.mjs's existing workoutProgress() aggregate\r\n// (mode+day grouped COUNT over `workouts`). breathingDays/mealDays: iterables of UTC day\r\n// numbers (Math.floor(ms/86400000)) with >=1 completed breathing session / logged meal.\r\n// today: the current UTC day number.\r\nexport function circuitProgress(rows,breathingDays,mealDays,today){\r\n const byDay=new Map();\r\n for(const row of rows||[]){\r\n  const style=STYLE_OF_GROUP[exerciseFamily(row.mode)];\r\n  if(!style||!(Number(row.sets)>0)||!Number.isSafeInteger(row.day))continue;\r\n  if(!byDay.has(row.day))byDay.set(row.day,new Set());\r\n  byDay.get(row.day).add(style);\r\n }\r\n const breathing=new Set(Array.from(breathingDays||[],Number)),meals=new Set(Array.from(mealDays||[],Number));\r\n const tracks=Object.fromEntries(STEP_TRACKS.map(t=>[t,0]));\r\n // ponytail: alphabetical tie-break when >3 styles are touched the same day -- deterministic,\r\n // not \"first completed\"; upgrade to completed_at ordering if that distinction ever matters.\r\n for(const [,styles] of byDay)for(const style of [...styles].sort().slice(0,MAX_STYLE_STEPS_PER_DAY))tracks[style]++;\r\n for(const day of breathing)tracks.meditation++;\r\n for(const day of meals)tracks.food++;\r\n const modesToday=new Set();for(const row of rows||[])if(row.day===today&&Number(row.sets)>0)modesToday.add(row.mode);\r\n const stepDone={};\r\n for(const step of CIRCUIT_STEPS){\r\n  if(step.key==='meditation')stepDone[step.key]=breathing.has(today);\r\n  else if(step.key==='food')stepDone[step.key]=meals.has(today);\r\n  else stepDone[step.key]=modesToday.has(step.mode);\r\n }\r\n const stylesStepped=[...(byDay.get(today)||[])].sort().slice(0,MAX_STYLE_STEPS_PER_DAY);\r\n const stepsToday=stylesStepped.length+(stepDone.meditation?1:0)+(stepDone.food?1:0);\r\n const nextStep=CIRCUIT_STEPS.find(step=>!stepDone[step.key])||null;\r\n return {\r\n  day:today,\r\n  tracks:Object.fromEntries(STEP_TRACKS.map(t=>[t,{steps:tracks[t],level:trackLevel(tracks[t])}])),\r\n  today:{stepDone,stylesStepped,stepsToday,maxStepsToday:MAX_STEPS_PER_DAY,nextStep:nextStep?.key??null},\r\n };\r\n}\r\n","coach-hit.mjs":"// coach-hit.mjs — where the workout coach walks. Pure: pose landmarks in, screen placement out.\r\n// Screen coords are fractions (x right, y down). The floor is a pinhole model with the horizon at the\r\n// user's hips: a coach z times the user's distance away stands higher on screen and 1/z as tall.\r\n// World spot = {X, z}: X is the screen x it would have level with the user, z the distance ratio.\r\n// ponytail: no segmentation occlusion. Spots behind the user (z > 1) always sit clear of them and the\r\n// coach only crosses over in front, so it never needs cutting out. Add pose segmentation masks if it must.\r\n\r\nexport const COACH = {\r\n  hitSpeed: 1.2,\r\n  hitLimbs: [13, 14, 15, 16, 25, 26, 27, 28, 29, 30, 31, 32],\r\n  launchSpeedT: 4,\r\n  sparseSpeedT: 2.2,\r\n  minReachT: .35,\r\n  hitPadT: .2,\r\n  maxLimbGapMs: 750,\r\n  grabGraceMs: 1000,\r\n  throwSpeedT: 1.5,\r\n  throwWindowMs: 500,\r\n  spinMs: 700,\r\n  awayMs: 2000,\r\n  heightPerTorso: 1.5,\r\n  ease: 6,\r\n  boxWidth: 0.6,\r\n  stride: 1.1, // walking speed, coach heights per second\r\n  roomDepth: 3, // the user's distance from the camera in coach heights (how slow walking in depth looks)\r\n  depths: [0.85, 1, 1.2, 1.45], // spots it wanders between (1 = level with the user, more = behind)\r\n  gap: 0.03, // screen gap kept between the user's shoulders and the coach\r\n  pauseMs: [1500, 4000],\r\n  crossRoom: 0.15, // the other side must be this much roomier before it crosses over\r\n  horizon: 0, // camera height: 0 = the user's hips, 1 = their knees, negative = above the hips\r\n  turnRate: 8,\r\n  grabMs: 1000,\r\n  holdMs: 8000,\r\n  dropMs: 400,\r\n  grabLimbs: [15, 16], // wrists are more stable than fingertips\r\n  chargeAfterMs: 8000, // counting time in the set before he charges (once per begin())\r\n  judgeMs: 1200,       // how long he lies there judging the user's balance\r\n  steady: 0.15,        // max hip-centre shift ÷ torso length that still counts as \"didn't budge\"\r\n  swipeMs: 1800, agreeMs: 1900, laughMs: 3400 // rig clip lengths (GESTURES.swipe/agree/laugh in creature/source/motion.ts)\r\n};\r\n\r\nconst VISIBLE = 0.45;\r\nconst seen = p => p && p.visibility >= VISIBLE;\r\nconst distH = (p, q, aspect) => Math.hypot((p.x - q.x) * aspect, p.y - q.y);\r\nconst limbSeen=p=>seen(p)&&Number.isFinite(p.x)&&Number.isFinite(p.y)&&p.x>=0&&p.x<=1&&p.y>=0&&p.y<=1;\r\n// A segment crossing the box counts even when neither endpoint lands inside it.\r\nexport function sweptHit(p,q,box,padX=0,padY=0){\r\n let lo=0,hi=1;\r\n for(const [start,end,min,max] of [[p.x,q.x,box.left-padX,box.right+padX],[p.y,q.y,box.top-padY,box.bottom+padY]]){\r\n  const d=end-start;if(Math.abs(d)<1e-9){if(start<min||start>max)return false;continue;}\r\n  const a=(min-start)/d,b=(max-start)/d;lo=Math.max(lo,Math.min(a,b));hi=Math.min(hi,Math.max(a,b));if(lo>hi)return false;\r\n }\r\n return true;\r\n}\r\n\r\n// Where the user is: hip centre, shoulder half-width, floor line (knees) and horizon (hips).\r\nexport function userAnchor(points, aspect) {\r\n  if (!Array.isArray(points) || ![11, 12, 23, 24].every(i => limbSeen(points[i]))) return null;\r\n  const sx = (points[11].x + points[12].x) / 2, sy = (points[11].y + points[12].y) / 2;\r\n  const hx = (points[23].x + points[24].x) / 2, hy = (points[23].y + points[24].y) / 2;\r\n  const torso = Math.hypot((sx - hx) * aspect, sy - hy);\r\n  if(torso<=.015)return null;\r\n  const knees = [25, 26].filter(i => seen(points[i])).map(i => points[i].y);\r\n  const floorY = knees.length ? knees.reduce((a, b) => a + b) / knees.length : Math.min(1, hy + torso * 0.9);\r\n  const horizonY = Math.min(hy + COACH.horizon * (floorY - hy), floorY - 0.05);\r\n  return { x: hx, halfW: Math.abs(points[12].x - points[11].x) / 2, floorY, horizonY, height: torso * COACH.heightPerTorso };\r\n}\r\n\r\nconst halfWidth = (a, z, aspect) => (a.height / z) * COACH.boxWidth / 2 / aspect;\r\n\r\nexport function project(a, X, z, aspect) {\r\n  const height = a.height / z, half = halfWidth(a, z, aspect);\r\n  const x = 0.5 + (X - 0.5) / z, feetY = a.horizonY + (a.floorY - a.horizonY) / z;\r\n  return { x, feetY, height, box: { left: x - half, right: x + half, top: feetY - height, bottom: feetY } };\r\n}\r\n\r\n// Free screen width beside the user.\r\nexport const room = (a, side) => (side > 0 ? 1 - (a.x + a.halfW) : a.x - a.halfW);\r\n\r\n// Standing on `side` of the user at depth z, `extra` further out. Clamped on screen; `fits` = no clamp needed.\r\nexport function spot(a, side, z, aspect, extra = 0) {\r\n  const half = halfWidth(a, z, aspect), want = a.x + side * (a.halfW + COACH.gap + half + extra);\r\n  const x = Math.max(half, Math.min(1 - half, want));\r\n  return { X: 0.5 + (x - 0.5) * z, z, fits: x === want };\r\n}\r\n\r\nexport class CoachMotion {\r\n  constructor({ aspect = 0.46, now = 0, random = Math.random, play = true } = {}) {\r\n    this.play = play; // false = kick-only (four-legged coaches): no grab, no charge\r\n    this.aspect = aspect;\r\n    this.random = random;\r\n    this.prevNow = now;\r\n    this.prevPoints = null;\r\n    this.prevPoseNow = now;\r\n    this.handSeenAt = now;\r\n    this.grabMissAt = null;\r\n    this.handHistory = [];\r\n    this.throwVelocity = null;\r\n    this.anchor = null; // eased userAnchor\r\n    this.phase = 'offstage'; // offstage → walking ⇄ pausing → spun → away → walking\r\n    this.begun = false;\r\n    this.X = 0;\r\n    this.z = 1;\r\n    this.slot = null; // {side, z, extra}\r\n    this.until = 0; // pause end\r\n    this.yaw = 0;\r\n    this.rotation = 0;\r\n    this.hitStartNow = 0;\r\n    this.direction = 1;\r\n    this.flyFrom = 0;\r\n    this.grabLimb = -1;\r\n    this.grabSince = 0;\r\n    this.heldSince = 0;\r\n    this.dropAt = 0;\r\n    this.dy = 0;\r\n    this.dropFrom = 0;\r\n    this.charged = false;\r\n    this.beginNow = 0;\r\n    this.phaseAt = 0;\r\n    this.hip0 = 0;\r\n    this.shift = 0;\r\n  }\r\n\r\n  // Reps are counting: walk in on the next frame that sees the user.\r\n  begin() { this.begun = true; this.charged = false; this.beginNow = this.prevNow; }\r\n\r\n  target() { const s = this.slot; return spot(this.anchor, s.side, s.z, this.aspect, s.extra); }\r\n\r\n  // Next spot: a new depth on the same side, or cross over in front when the other side is much roomier.\r\n  pick(first = false) {\r\n    const a = this.anchor, side = this.slot?.side ?? (room(a, 1) >= room(a, -1) ? 1 : -1);\r\n    const fitsAt = sd => COACH.depths.some(z => spot(a, sd, z, this.aspect).fits);\r\n    if (!first && (room(a, -side) > room(a, side) + COACH.crossRoom || (!fitsAt(side) && fitsAt(-side)))) {\r\n      // Only cross from level or in front, so the coach passes in front of the user, never behind.\r\n      this.slot = this.z > 1 ? { side, z: COACH.depths[0], extra: 0, hurry: true } : { side: -side, z: COACH.depths[0], extra: 0 };\r\n      return;\r\n    }\r\n    const open = COACH.depths.filter(z => z !== this.slot?.z && spot(a, side, z, this.aspect).fits);\r\n    const z = open.length ? open[Math.floor(this.random() * open.length)] : Math.max(...COACH.depths);\r\n    const slack = room(a, side) - COACH.gap - 2 * halfWidth(a, z, this.aspect);\r\n    this.slot = { side, z, extra: this.random() * Math.max(0, Math.min(0.1, slack)) };\r\n  }\r\n\r\n  // Start just off the edge on the roomier side, level with the user, and walk in.\r\n  enter() {\r\n    const a = this.anchor, side = room(a, 1) >= room(a, -1) ? 1 : -1, half = halfWidth(a, 1, this.aspect);\r\n    this.X = side > 0 ? 1 + half : -half;\r\n    this.z = 1;\r\n    this.slot = { side, z: 1, extra: 0 };\r\n    this.pick(true);\r\n    this.phase = 'walking';this.dy=0;\r\n    this.yaw = -side * Math.PI / 2;\r\n  }\r\n\r\n  launch(cur,prev,now,drawn){\r\n    const dx=(cur.x-prev.x)*this.aspect,dy=cur.y-prev.y,length=Math.hypot(dx,dy);\r\n    this.direction=Math.sign(dx)||1;this.flyFrom=(drawn.left+drawn.right)/2;this.flyFromY=drawn.bottom;\r\n    const nx=length>0?dx/length:this.direction,ny=length>0?dy/length:0,half=(drawn.right-drawn.left)/2,height=drawn.bottom-drawn.top;\r\n    const xdist=Math.abs(nx)>1e-6?((nx>0?1+half-this.flyFrom:this.flyFrom+half)*this.aspect/Math.abs(nx)):Infinity;\r\n    const ydist=Math.abs(ny)>1e-6?(ny>0?1+height-this.flyFromY:this.flyFromY)/Math.abs(ny):Infinity;\r\n    const distance=Math.min(xdist,ydist)+.03;\r\n    this.flyDx=nx*distance/this.aspect;this.flyDy=ny*distance;\r\n    this.phase='spun';this.hitStartNow=now;this.grabLimb=-1;this.handHistory=[];this.throwVelocity=null;\r\n  }\r\n  strike(points,now,box,skip=-1){\r\n    const gap=now-this.prevPoseNow;if(!this.prevPoints||gap<=0||gap>COACH.maxLimbGapMs)return null;\r\n    const torso=this.anchor.height/COACH.heightPerTorso,dt=gap/1000;\r\n    const threshold=COACH.launchSpeedT+(COACH.sparseSpeedT-COACH.launchSpeedT)*Math.min(1,Math.max(0,(gap-120)/280));\r\n    for(const idx of COACH.hitLimbs){\r\n      if(idx===skip)continue;const cur=points?.[idx],prev=this.prevPoints[idx];\r\n      if(!limbSeen(cur)||!limbSeen(prev))continue;\r\n      const travel=distH(prev,cur,this.aspect)/torso;\r\n      if(travel<COACH.minReachT||travel/dt<threshold)continue;\r\n      if(sweptHit(prev,cur,box,COACH.hitPadT*torso/this.aspect,COACH.hitPadT*torso))return {cur,prev};\r\n    }\r\n    return null;\r\n  }\r\n  tick(now){return now>this.prevNow?this.update(null,now,false):null;}\r\n  update(points, now, sample=true) {\r\n    const dt = Math.max((now - this.prevNow) / 1000, 0.001);\r\n    this.prevNow = now;\r\n    const raw = userAnchor(points, this.aspect);\r\n    if (raw) {\r\n      if (!this.anchor) this.anchor = raw;\r\n      else { const f = 1 - Math.exp(-COACH.ease * dt); for (const k in raw) this.anchor[k] += (raw[k] - this.anchor[k]) * f; }\r\n    }\r\n    const a = this.anchor;\r\n    let yawTarget = this.yaw;\r\n\r\n    if (!a) {\r\n      // Never seen the user: nothing to stand beside yet.\r\n    } else if (this.phase === 'offstage') {\r\n      if (this.begun) this.enter();\r\n    } else if (this.phase === 'walking' || this.phase === 'pausing') {\r\n      // Hit test against where the coach was drawn last frame.\r\n      const drawn = project(a, this.X, this.z, this.aspect).box;\r\n      // Hover grab: a grab limb resting inside the box for grabMs lifts the coach by the head.\r\n      let hover = -1;\r\n      if (raw && this.play) for (const idx of COACH.grabLimbs) {\r\n        const p = points[idx];\r\n        if (seen(p) && p.x >= drawn.left && p.x <= drawn.right && p.y >= drawn.top && p.y <= drawn.bottom) { hover = idx; break; }\r\n      }\r\n      // A frame with no user (tracker blink) keeps the timer: only a hand seen elsewhere resets it.\r\n      if (sample && hover < 0) {this.grabMissAt??=now;if(now-this.grabMissAt>COACH.grabGraceMs/2)this.grabLimb=-1;}\r\n      else if (hover >= 0) {\r\n        this.grabMissAt=null;\r\n        if (this.grabLimb !== hover) { this.grabLimb = hover; this.grabSince = now; }\r\n        if (now - this.grabSince >= COACH.grabMs) { this.phase = 'held'; this.heldSince = now;this.handSeenAt=now;this.handHistory=[];this.throwVelocity=null; }\r\n      }\r\n      if (this.play && this.phase === 'pausing' && !this.charged && now - this.beginNow >= COACH.chargeAfterMs) {\r\n        this.charged = true;\r\n        this.phase = 'charge';\r\n        this.slot = { side: this.slot.side, z: 1, extra: -COACH.gap };\r\n      }\r\n\r\n      if (this.phase !== 'held' && this.phase !== 'charge') {\r\n        // Kick test against where the coach was drawn last frame.\r\n        const hit=raw?this.strike(points,now,drawn):null;\r\n        if(hit)this.launch(hit.cur,hit.prev,now,drawn);\r\n        if (this.phase !== 'spun') {\r\n          let t = this.target();\r\n          // The user stepped into its spot behind them: re-plan (a clear depth, or cross over in front).\r\n          if (t.z > 1 && !t.fits && !this.slot.hurry) { this.pick(); t = this.target(); }\r\n          const dx = (t.X - this.X) * this.aspect / a.height, dz = (t.z - this.z) * COACH.roomDepth, d = Math.hypot(dx, dz);\r\n          if (this.phase === 'pausing' && d > 0.3) this.phase = 'walking';\r\n          if (this.phase === 'walking') {\r\n            const step = COACH.stride * dt;\r\n            if (d <= step) {\r\n              this.X = t.X; this.z = t.z; this.phase = 'pausing';\r\n              const [lo, hi] = COACH.pauseMs;\r\n              this.until = this.slot.hurry ? now : now + lo + this.random() * (hi - lo);\r\n            } else {\r\n              this.X += (t.X - this.X) * step / d; this.z += (t.z - this.z) * step / d;\r\n              yawTarget = Math.atan2(dx, -dz); // face where it walks: right = +π/2, away = π\r\n            }\r\n          }\r\n          if (this.phase === 'pausing') {\r\n            this.X = t.X; this.z = t.z; // small user shifts: stay put beside them\r\n            yawTarget = -this.slot.side * 0.35; // turned a little toward the user\r\n            if (now >= this.until) { this.pick(); this.phase = 'walking'; }\r\n          }\r\n        }\r\n      }\r\n    } else if (this.phase === 'charge') {\r\n      const t = this.target(), dx = (t.X - this.X) * this.aspect / a.height, dz = (t.z - this.z) * COACH.roomDepth, d = Math.hypot(dx, dz), step = COACH.stride * dt;\r\n      if (d <= step) { this.X = t.X; this.z = t.z; this.phase = 'swiping'; this.phaseAt = now; yawTarget = -this.slot.side * Math.PI / 2; }\r\n      else { this.X += (t.X - this.X) * step / d; this.z += (t.z - this.z) * step / d; yawTarget = Math.atan2(dx, -dz); }\r\n    } else if (this.phase === 'swiping') {\r\n      yawTarget = -this.slot.side * Math.PI / 2; // squared up to the user\r\n      if (now - this.phaseAt >= COACH.swipeMs) { this.phase = 'fallen'; this.phaseAt = now; this.hip0 = raw ? raw.x : a.x; this.shift = 0; }\r\n    } else if (this.phase === 'fallen') {\r\n      // Judge: the biggest hip-centre shift while he lies there, in torso lengths (x in the same units distH uses).\r\n      if (raw) this.shift = Math.max(this.shift, Math.abs(raw.x - this.hip0) * this.aspect / (a.height / COACH.heightPerTorso));\r\n      if (now - this.phaseAt >= COACH.judgeMs) { this.phase = this.shift < COACH.steady ? 'impressed' : 'laughing'; this.phaseAt = now; }\r\n    } else if (this.phase === 'impressed' || this.phase === 'laughing') {\r\n      yawTarget = -this.slot.side * 0.35;\r\n      if (now - this.phaseAt >= (this.phase === 'impressed' ? COACH.agreeMs : COACH.laughMs)) { this.pick(); this.phase = 'walking'; }\r\n    } else if (this.phase === 'held') {\r\n      const p = points?.[this.grabLimb];\r\n      const drawn=project(a,this.X,this.z,this.aspect).box;drawn.top+=this.dy;drawn.bottom+=this.dy;\r\n      const hit=raw?this.strike(points,now,drawn):null;\r\n      if(hit){this.launch(hit.cur,hit.prev,now,drawn);}\r\n      else if ((now-this.handSeenAt>COACH.grabGraceMs) || now - this.heldSince >= COACH.holdMs) {\r\n        // A recently moving hand releases with its observed velocity; a stale hand simply drops.\r\n        const velocity=this.throwVelocity;\r\n        if(velocity&&now-velocity.t<=COACH.throwWindowMs){\r\n          this.launch({x:velocity.x+velocity.vx,y:velocity.y+velocity.vy},{x:velocity.x,y:velocity.y},now,drawn);\r\n        }else{\r\n          this.phase = 'dropped';\r\n          this.dropAt = now;\r\n          this.dropFrom = this.dy;\r\n          this.grabLimb = -1;\r\n        }\r\n      } else if (raw&&limbSeen(p)) {\r\n        this.handSeenAt=now;\r\n        this.handHistory.push({x:p.x,y:p.y,t:now});this.handHistory=this.handHistory.filter(h=>now-h.t<=COACH.throwWindowMs);\r\n        const first=this.handHistory[0],span=(now-first.t)/1000,torso=a.height/COACH.heightPerTorso;\r\n        if(span>0){const vx=(p.x-first.x)/span,vy=(p.y-first.y)/span;if(Math.hypot(vx*this.aspect,vy)/torso>=COACH.throwSpeedT&&distH(first,p,this.aspect)/torso>=COACH.minReachT)this.throwVelocity={x:p.x,y:p.y,vx,vy,t:now};}\r\n        // A moving hand that becomes unseen is a release; one still, missing sample keeps the grip.\r\n        // The box top-centre follows the limb; feet hang below it.\r\n        this.X = 0.5 + (p.x - 0.5) * this.z;\r\n        const base = project(a, this.X, this.z, this.aspect);\r\n        this.dy = p.y + base.height - base.feetY;\r\n      }\r\n      if(this.phase==='held'&&sample&&!limbSeen(p)&&this.throwVelocity&&now-this.throwVelocity.t<=COACH.throwWindowMs){\r\n        const v=this.throwVelocity;this.launch({x:v.x+v.vx,y:v.y+v.vy},{x:v.x,y:v.y},now,drawn);\r\n      }\r\n    } else if (this.phase === 'dropped') {\r\n      const u = Math.min((now - this.dropAt) / COACH.dropMs, 1);\r\n      this.dy = this.dropFrom * (1 - u);\r\n      if (u >= 1) { this.dy = 0; this.phase = 'walking'; }\r\n    } else if (this.phase === 'spun') {\r\n      const u = Math.min((now - this.hitStartNow) / COACH.spinMs, 1);\r\n      const x = this.flyFrom + this.flyDx * u;\r\n      this.X = 0.5 + (x - 0.5) * this.z;\r\n      const base=project(a,this.X,this.z,this.aspect);this.dy=this.flyFromY+this.flyDy*u-base.feetY;\r\n      this.rotation = this.direction * u * 4 * Math.PI;\r\n      if (u >= 1) { this.phase = 'away'; this.hitStartNow = now; this.rotation = 0; }\r\n    } else if (this.phase === 'away') {\r\n      if (now - this.hitStartNow >= COACH.awayMs) this.enter();\r\n    }\r\n\r\n    const turn = Math.atan2(Math.sin(yawTarget - this.yaw), Math.cos(yawTarget - this.yaw));\r\n    this.yaw += turn * (1 - Math.exp(-COACH.turnRate * dt));\r\n    if(sample){this.prevPoseNow=now;this.prevPoints = Array.isArray(points) ? points.map(p => p && { x: p.x, y: p.y, visibility: p.visibility }) : null;}\r\n\r\n    const placed = a ? project(a, this.X, this.z, this.aspect) : { x: 0, feetY: 0, height: 0, box: { left: 0, right: 0, top: 0, bottom: 0 } };\r\n    if (this.dy !== 0) {\r\n      placed.feetY += this.dy;\r\n      placed.box.top += this.dy;\r\n      placed.box.bottom += this.dy;\r\n    }\r\n    return { phase: this.phase, z: this.z, yaw: this.yaw, rotation: this.rotation, baseHeight: a?.height ?? 0, ...placed, dy: this.dy, side: this.slot?.side ?? 1, shift: this.shift };\r\n  }\r\n}\r\n","coach-hub.css":".coach-mission{position:relative;margin:4px 0 16px;padding:18px;border:2px solid #ba9bff;background:linear-gradient(135deg,#362050,#160f25 70%);box-shadow:5px 5px 0 #07090e,inset 0 0 25px #a464ff20;overflow:hidden}.mission-tag{color:#c9fda5;font:700 .75rem ui-monospace,monospace;letter-spacing:.1em}.mission-head{display:flex;align-items:center;gap:16px;justify-content:space-between;margin:14px 0}.mission-head h3{margin:0;color:#f0d2ff;font:950 clamp(1.8rem,8vw,3rem)/.95 system-ui;letter-spacing:-.05em}.mission-head p{font-size:.875rem;margin:10px 0 0;color:#d7c5e5}.mission-streak{text-align:center;color:#baff92;min-width:88px}.mission-streak strong{display:block;font:900 3.8rem/1 ui-monospace,monospace;text-shadow:3px 3px #204421}.mission-streak span{font:700 .75rem ui-monospace,monospace}.mission-arm{display:flex;justify-content:space-between;width:100%;background:#baff92;color:#101e12;border:2px solid #162516;border-radius:2px;font-weight:900;box-shadow:0 4px #477944;min-height:50px}.mission-readouts{display:flex;flex-wrap:wrap;justify-content:space-between;gap:8px;margin:14px 0 4px;font:.875rem ui-monospace,monospace;color:#d5ffe1}.mission-guide{padding:8px 0;background:none;border:0;border-radius:0;font:700 .875rem ui-monospace,monospace;color:#c8acec}.coach-mission[data-boost=true]{border-color:#f9d96b;box-shadow:5px 5px 0 #07090e,inset 0 0 30px #e7bf3920}.terminal-menu{background:#081611!important;color:#ccffd9!important;border:2px solid #8bb39b!important;border-radius:3px!important;box-shadow:7px 7px 0 #030806!important;font:1rem/1.5 ui-monospace,SFMono-Regular,Consolas,monospace!important;max-height:90dvh;overflow:auto}.terminal-menu header{background:#183429!important;border-bottom:1px solid #6e9b7b;padding:12px!important;display:flex;justify-content:space-between;align-items:center;gap:12px}.terminal-menu h2{font:700 1rem ui-monospace,monospace;letter-spacing:.03em;color:#beff99}.terminal-menu button,.terminal-menu input,.terminal-menu select{border-radius:2px!important;font:inherit;background:#10271e;color:#d8ffe6;border:1px solid #5f9371;min-height:44px}.terminal-menu input[type=checkbox]{min-height:22px;width:22px;accent-color:#aff58c}.terminal-menu label,.terminal-menu summary{font-size:1rem}.terminal-menu p{color:#c3dbcb!important;font-size:.875rem}.terminal-links{display:grid;gap:8px;margin-top:20px;border-top:1px solid #526c59;padding-top:12px}.terminal-links button{text-align:left}.how-to-play{width:min(700px,94vw);padding:0}.how-to-play [role=tablist]{display:flex;overflow-x:auto;gap:4px;padding:10px;border-bottom:1px solid #405b48}.how-to-play [role=tab]{white-space:nowrap;flex-shrink:0;font-size:.875rem}.how-to-play [aria-selected=true]{background:#b3ef95;color:#0a2012;font-weight:bold}.how-to-play [role=tabpanel]{padding:18px}.how-to-play h3{font-size:1.25rem;color:#c4ffa5}.how-to-play h4{font-size:1rem;margin:20px 0 4px}.how-to-play article p{margin:0}.guide-track{display:grid;grid-template-columns:1fr 1fr;gap:8px;padding:12px 0;border-bottom:1px solid #314b3b}.guide-track>strong{grid-column:1/-1;font-size:1rem}.guide-track>span{display:flex;align-items:center;font-size:.875rem;gap:6px}.guide-track canvas{width:30px;height:54px;image-rendering:pixelated}.coach-reminder-plan{padding:14px;margin:12px 0;background:#0d2117;border:1px solid #638566}.coach-reminder-plan h3{font-size:1.2rem;color:#c3ff99;margin:0 0 14px}.coach-reminder-plan label{display:grid;gap:5px;margin-bottom:12px}.coach-reminder-plan [data-times],.plan-quiet{display:grid;grid-template-columns:repeat(auto-fit,minmax(115px,1fr));gap:10px}.coach-reminder-plan input,.coach-reminder-plan select{width:100%;min-width:0}.coach-reminder-plan .plan-enabled{display:flex;align-items:center;gap:10px}.coach-reminder-plan [type=submit]{width:100%;background:#bbf293;color:#0f2314;font-weight:900}\r\n.coach-reminder-plan blockquote{margin:0 0 12px;padding:10px;border-left:3px solid #bbf293;background:#0a1a11;font-size:.9rem}\r\n.coach-reminder-plan .coach-tone{margin:0 0 12px;font-size:.85rem;opacity:.85}.account-settings{background:#081611;border:1px solid #5f9371;padding:12px;color:#ccffd9;font-family:ui-monospace,monospace}@media(max-width:380px){.coach-mission{padding:12px}.mission-streak strong{font-size:3rem}.mission-readouts{font-size:.8rem}.guide-track{grid-template-columns:1fr}.guide-track>strong{grid-column:auto}}@media(prefers-reduced-motion:reduce){.coach-mission *{animation:none!important;transition:none!important}}\r\n\r\n/* R-1016: the portal's tilt chip sits on the dock edge and covered panel text (Reminders); hide it while a panel dialog is open. */\r\nbody:has(dialog.launch-panel[open]) .portal-tilt-chip{display:none!important}\r\n.mission-guest{margin:8px 0 0;padding:8px 10px;background:#160f25;border-left:3px solid #ba9bff;font-size:.9rem}\r\n.how-to-play .guide-start{position:sticky;bottom:0;padding:10px 14px;background:#07140d;border-top:1px solid #405b48}.how-to-play .guide-start button{width:100%;min-height:52px;font-weight:700;font-size:1.05rem}\r\n","coach-hub.mjs":"import {weaponDamage} from './combat.mjs';\r\nimport {TRAINING_TRACKS} from './weapon-training.mjs';\r\nimport {coachReminder} from './reminder-plan.mjs';\r\nimport {RELEASE} from './release-info.mjs';\r\nimport {mountSettingsCrt} from './settings-crt.mjs';\r\nimport {mountAppleBasicShare} from './apple-basic-share.mjs';\r\nimport {dailyGuideDue,markDailyGuide,guideOwner} from './daily-guide.mjs';\r\nimport {signInPath} from './auth-paths.mjs';\r\nimport {COACHES,SITUATIONS,getCoach} from './creature/source/creator/coaching.ts';\r\n\r\n// #107/#120: military-satcom frame, usable on any dialog. Adds a top SATCOM status strip (an\r\n// ACQUIRING… -> {title} animation replayed every time the dialog opens), a bottom clock/BUILD\r\n// strip, a corner radar trace and corner bolts. Doesn't touch the dialog's existing items/nav.\r\n// Wrapping the dialog's own showModal() (rather than one known opener button) catches every route\r\n// in: Settings has one (#openSettings), but Install and the Downloads menu each open from several\r\n// places (the dock, Settings' Downloads button, a deep link, window.myr5Packs.open()...).\r\nexport function mountSatcomFrame(dialog,{title='UPLINK ESTABLISHED'}={}){\r\n const reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n dialog.classList.add('satcom-frame');\r\n const top=document.createElement('div');top.className='satcom-strip satcom-top';top.setAttribute('aria-hidden','true');\r\n top.innerHTML='<svg class=\"satcom-sat\" viewBox=\"0 0 24 24\"><rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/><path d=\"M9 12H3M15 12h6M12 9V3M12 15v6\"/><path d=\"m4.5 4.5 2.5 2.5M19.5 4.5 17 7\"/></svg><span class=\"satcom-label\">SATCOM // <em data-link>ACQUIRING…</em></span><span class=\"satcom-bars\" data-bars><i></i><i></i><i></i><i></i></span>';\r\n const bottom=document.createElement('div');bottom.className='satcom-strip satcom-bottom';bottom.setAttribute('aria-hidden','true');\r\n bottom.innerHTML='<span class=\"satcom-clock\" data-clock>--:--:--</span><span class=\"satcom-build\" data-build></span><i class=\"satcom-radar\"></i>';\r\n const build=bottom.querySelector('[data-build]');build.textContent='BUILD '+RELEASE.id;build.title=RELEASE.id;\r\n dialog.prepend(top);dialog.append(bottom);\r\n for(const pos of ['tl','tr','bl','br']){const bolt=document.createElement('i');bolt.className='satcom-bolt satcom-bolt-'+pos;bolt.setAttribute('aria-hidden','true');dialog.append(bolt);}\r\n const clock=bottom.querySelector('[data-clock]');\r\n const tick=()=>clock.textContent=new Date().toLocaleTimeString('en-GB',{hour12:false});\r\n tick();setInterval(tick,1000);\r\n const link=top.querySelector('[data-link]'),bars=[...top.querySelectorAll('[data-bars] i')];\r\n let lockTimer=null;\r\n function acquire(){\r\n  clearTimeout(lockTimer);top.classList.remove('locked');link.textContent='ACQUIRING…';\r\n  // The locked intake theme disables animation with !important; inline !important keeps this\r\n  // moving there too, same trick as the portal (modules/portal/portal.mjs).\r\n  if(!reduced())for(const [i,bar] of bars.entries())bar.style.setProperty('animation',`satcom-blink .5s ease ${i*110}ms infinite`,'important');\r\n  const settle=()=>{\r\n   top.classList.add('locked');link.textContent=title;\r\n   for(const bar of bars)bar.style.removeProperty('animation');\r\n   if(!reduced())top.style.setProperty('animation','satcom-flash .5s ease','important');\r\n  };\r\n  reduced()?settle():lockTimer=setTimeout(settle,900);\r\n }\r\n const nativeShowModal=dialog.showModal.bind(dialog);\r\n dialog.showModal=(...args)=>{acquire();return nativeShowModal(...args);};\r\n}\r\n\r\nimport {GUIDE as guide} from './progression-guide.mjs';\r\n\r\nexport const SETTINGS_LINKS=[['ACCOUNT','scoreboard'],['DEVICE + UPDATES','install'],['HOW TO PLAY','guide']];\r\n// Settings always opens collapsed: every section folded and scrolled to the top.\r\nexport function collapseOnOpen(dialog){\r\n const showModal=dialog.showModal.bind(dialog);\r\n dialog.showModal=(...args)=>{for(const details of dialog.querySelectorAll('details'))details.open=false;dialog.scrollTop=0;return showModal(...args);};\r\n}\r\n\r\nexport function mountCoachHub({api}){\r\n const hub=document.createElement('section');hub.className='coach-mission';hub.setAttribute('aria-label','Coach reminders and daily power');\r\n hub.innerHTML='<div class=\"mission-tag\">MOM INC // DAILY ORDERS</div><div class=\"mission-head\"><div><h3>CHECK IN.<br>POWER UP.</h3><p data-hub-line>MOM has your next move.</p></div><div class=\"mission-streak\"><strong data-streak>—</strong><span>DAY STREAK</span></div></div><button class=\"mission-arm\" type=\"button\">ARM YOUR REMINDERS <span>→</span></button><div class=\"mission-readouts\"><span data-message-count>1–3 messages / day</span><span data-damage>Sign in to power up</span></div><button class=\"mission-guide\" type=\"button\">HOW TO PLAY</button>';\r\n // W2-2M #117: the pod is only the viewing port, the control board and BEGIN. The daily-orders card lives at the\r\n // top of Reminders (bar), where ARM goes to the arming switch; the pod's other extras (#podExtras) go to Records.\r\n document.querySelector('#remindersPanel header').after(hub);\r\n // Guests can't be reached by reminders: say so and offer sign-in instead of silently focusing a checkbox.\r\n hub.querySelector('.mission-arm').onclick=()=>{\r\n  if(window.myr5AuthenticatedAccount)return form.elements.enabled.focus();\r\n  let note=hub.querySelector('.mission-guest');\r\n  if(!note){note=document.createElement('p');note.className='mission-guest';note.setAttribute('role','status');note.append('Reminders need an account so MOM can reach you. ');const link=document.createElement('a');link.href=signInPath('/pose.html?panel=reminders');link.textContent='Sign in to arm reminders';link.style.color='#b8e9cf';note.append(link);hub.querySelector('.mission-arm').after(note);}\r\n  note.scrollIntoView({block:'nearest'});\r\n  note.querySelector('a').focus();\r\n };\r\n document.querySelector('#accountPanel header').after(document.getElementById('podExtras'));\r\n const dialog=document.createElement('dialog');dialog.className='how-to-play terminal-menu';dialog.setAttribute('aria-labelledby','howToPlayTitle');dialog.innerHTML='<header><h2 id=\"howToPlayTitle\">MOM://FIELD MANUAL</h2><button type=\"button\" data-close-guide>Close</button></header><div role=\"tablist\" aria-label=\"How to play\"></div><section role=\"tabpanel\" tabindex=\"0\"></section><footer class=\"guide-start\"><button type=\"button\" class=\"primary-action\" data-guide-start>Start a workout</button></footer>';\r\n document.body.append(dialog);const tabs=dialog.querySelector('[role=tablist]'),panel=dialog.querySelector('[role=tabpanel]');let current=0,opener=null;\r\n function choose(index,focus=false){current=(index+guide.length)%guide.length;for(const [i,tab] of [...tabs.children].entries()){tab.setAttribute('aria-selected',String(i===current));tab.tabIndex=i===current?0:-1;}const [id,,title,items]=guide[current];panel.id='guide-panel';panel.setAttribute('aria-labelledby','guide-tab-'+id);panel.replaceChildren();const h=document.createElement('h3');h.textContent=title;panel.append(h);\r\n  if(id==='weapons')for(const track of Object.values(TRAINING_TRACKS)){const row=document.createElement('div');row.className='guide-track';const label=document.createElement('strong');label.textContent=track.name;row.append(label);for(const type of track.weapons){const item=document.createElement('span'),canvas=document.createElement('canvas');canvas.width=40;canvas.height=72;canvas.setAttribute('aria-hidden','true');window.GalaWeapons.draw(canvas.getContext('2d'),{type,tier:4});item.append(canvas,document.createTextNode(window.GalaWeapons.types.find(w=>w.id===type).name));row.append(item);}panel.append(row);}\r\n  for(const [label,text] of items){const block=document.createElement('article'),heading=document.createElement('h4'),p=document.createElement('p');heading.textContent=label;p.textContent=text;block.append(heading,p);panel.append(block);}if(focus)tabs.children[current].focus();\r\n }\r\n guide.forEach(([id,label],index)=>{const button=document.createElement('button');button.type='button';button.id='guide-tab-'+id;button.setAttribute('role','tab');button.setAttribute('aria-controls','guide-panel');button.textContent=label;button.onclick=()=>choose(index);tabs.append(button);});\r\n tabs.onkeydown=event=>{const move={ArrowRight:current+1,ArrowLeft:current-1,Home:0,End:guide.length-1};if(Object.hasOwn(move,event.key)){event.preventDefault();choose(move[event.key],true);}};\r\n // Primary action for a first-timer: leave the manual and land on the pod's BEGIN button (opening the pod from the quilt if needed).\r\n dialog.querySelector('[data-guide-start]').onclick=()=>{dialog.close();const centre=document.querySelector('.dock-portal');if(centre?.getAttribute('aria-label')==='Open workout pod')centre.click();setTimeout(()=>{const go=document.getElementById('start');go?.scrollIntoView({block:'center'});go?.focus({preventScroll:true});},400);};\r\n function openGuide(){opener=document.activeElement;choose(0);dialog.showModal();tabs.children[0].focus();}\r\n hub.querySelector('.mission-guide').onclick=openGuide;\r\n // How to Play opens by itself once per local day, at the first app opening that day for this account (or the\r\n // guest). Waits for the starter quilt to come up and for no other popup to be up, so it never stacks on the setup\r\n // gate, a reward reveal or the quilt's own first frame.\r\n const guideTried=new Set();\r\n function dailyGuide(){\r\n  const owner=guideOwner();if(guideTried.has(owner)||!dailyGuideDue({owner}))return;guideTried.add(owner);\r\n  const started=Date.now(),attempt=()=>{\r\n   if(guideOwner()!==owner)return;\r\n   const busy=document.querySelector('dialog[open]')||window.myr5Packs?.due?.()||document.body.dataset.tracking==='true'||document.body.dataset.screen==='rest'||document.body.dataset.cinematic;\r\n   // The starter quilt checks for open dialogs before it appears: give it the first word (up to 5 s).\r\n   const settled=document.getElementById('portalHome')?.hidden===false||Date.now()-started>=15000;\r\n   if(busy||!settled){setTimeout(attempt,busy?1000:250);return;}\r\n   if(!dailyGuideDue({owner}))return;markDailyGuide({owner});openGuide();\r\n  };\r\n  setTimeout(attempt,0);\r\n }\r\n window.addEventListener('myr5:coach-plan',dailyGuide);\r\n dialog.querySelector('[data-close-guide]').onclick=()=>dialog.close();dialog.addEventListener('close',()=>opener?.focus());\r\n const settings=document.getElementById('settings');settings.classList.add('terminal-menu');document.getElementById('settingsTitle').textContent='MOM://POD CONTROL';\r\n const nav=document.createElement('nav');nav.className='terminal-links';nav.setAttribute('aria-label','Behind the scenes');\r\n // #79: every link but HOW TO PLAY is a real route (W2-2A's router). Portal, Achievements and Reminders have\r\n // their own doors (the quilt and the bottom bar), so Settings no longer repeats them.\r\n for(const [label,target] of SETTINGS_LINKS){const b=document.createElement('button');b.type='button';b.textContent='> '+label;b.onclick=()=>{settings.close();target==='guide'?openGuide():window.myr5Routes?.go(target);};nav.append(b);}settings.append(nav);\r\n mountAppleBasicShare(settings); // hidden until APPLE_BASIC_SHARE_URL is set\r\n mountSatcomFrame(settings);\r\n collapseOnOpen(settings);\r\n mountSettingsCrt(settings); // #137: TV touch effect + CRT curve + scan lines, screen area only\r\n for(const id of ['installPanel','remindersPanel'])document.getElementById(id).classList.add('terminal-menu');\r\n let progress=null;\r\n function paint(){hub.querySelector('[data-streak]').textContent=progress?.combat?.loginStreak??'—';let weapon={type:'rapier',tier:0};try{weapon=window.GalaWeapons.normalize(JSON.parse(localStorage.getItem('mominc-avatar-v1'))?.weapon||weapon);}catch{}if(!window.GalaWeapons.unlocked(weapon,progress))weapon={type:weapon.type,tier:0};const damage=weaponDamage(progress?.combat,weapon);hub.querySelector('[data-damage]').textContent=damage?damage.toLocaleString()+' DMG / HIT':'Sign in to power up';hub.dataset.boost=String(!!progress?.combat?.breathingCompleted);}\r\n window.addEventListener('myr5:account-progress',event=>{progress=event.detail;paint();});window.addEventListener('mominc-avatar-change',paint);\r\n const form=document.createElement('form');form.className='coach-reminder-plan';form.innerHTML='<h3>YOUR DAILY ORDERS</h3><label>Messages per day<select name=\"count\"><option value=\"1\">1 message</option><option value=\"2\">2 messages</option><option value=\"3\" selected>3 messages</option></select></label><div data-times></div><label>Coach tone<select name=\"tone\"><option value=\"cheeky\">Drill coach</option><option value=\"direct\">Direct</option><option value=\"gentle\">Gentle</option></select></label><label>Coach personality<select name=\"personality\"></select></label><p class=\"coach-tone\" data-personality-tone></p><label>Preview a situation<select name=\"situation\"></select></label><blockquote data-personality-line aria-live=\"polite\"></blockquote><div class=\"plan-quiet\"><label>Quiet from<input name=\"quietStart\" type=\"time\" value=\"22:00\" required></label><label>Until<input name=\"quietEnd\" type=\"time\" value=\"07:00\" required></label></div><label class=\"plan-enabled\"><input name=\"enabled\" type=\"checkbox\"> Reminders armed</label><button type=\"submit\">SAVE ORDERS</button><p data-plan-status role=\"status\"></p><details><summary>When training is missed</summary><p data-escalation></p></details>';\r\n hub.after(form);\r\n const old=document.getElementById('reminderForm'),details=document.createElement('details');details.innerHTML='<summary>Individual reminders</summary>';old.before(details);details.append(old);\r\n let times=['09:00','14:00','19:00'],timezone=Intl.DateTimeFormat().resolvedOptions().timeZone;\r\n function timeFields(){const host=form.querySelector('[data-times]');for(const [i,input] of [...host.querySelectorAll('input')].entries())times[i]=input.value;host.replaceChildren();for(let i=0;i<Number(form.elements.count.value);i++){const label=document.createElement('label');label.textContent='Check-in '+(i+1);const input=document.createElement('input');input.type='time';input.required=true;input.value=times[i]||['09:00','14:00','19:00'][i];label.append(input);host.append(label);}}\r\n const RECIPE='myr5-recipe-v1',readRecipe=()=>{try{const r=JSON.parse(localStorage.getItem(RECIPE));return r&&typeof r==='object'?r:null;}catch{return null;}};\r\nlet chosenCoach=getCoach(readRecipe()?.coach).id;\r\nconst pSelect=form.elements.personality,sSelect=form.elements.situation;\r\nfor(const c of COACHES){const opt=document.createElement('option');opt.value=c.id;opt.textContent=c.name;pSelect.append(opt);}\r\nfor(const [value,label] of SITUATIONS){const opt=document.createElement('option');opt.value=value;opt.textContent=label;sSelect.append(opt);}\r\npSelect.value=chosenCoach;sSelect.value='start';\r\nfunction updatePersonality(){const coach=getCoach(chosenCoach);form.querySelector('[data-personality-tone]').textContent=coach.tone;form.querySelector('[data-personality-line]').textContent=coach.lines[sSelect.value]||coach.lines.start;}\r\n// Same storage as the old customizer tab: the saved recipe's `coach` field (re-read at change time so a newer customizer save is never overwritten).\r\npSelect.onchange=()=>{if(!COACHES.some(c=>c.id===pSelect.value))return;chosenCoach=pSelect.value;const stored=readRecipe();if(stored){const updated={...stored,coach:chosenCoach};try{localStorage.setItem(RECIPE,JSON.stringify(updated));window.dispatchEvent(new CustomEvent('myr5:recipe',{detail:updated}));}catch{}}updatePersonality();};\r\nsSelect.onchange=updatePersonality;\r\nupdatePersonality();\r\nform.elements.count.onchange=timeFields;form.elements.tone.onchange=()=>{form.querySelector('[data-escalation]').textContent=coachReminder(3,form.elements.tone.value);};timeFields();form.elements.tone.onchange();\r\n function showPlan(p){times=p.times||times;timezone=p.timezone||timezone;form.elements.count.value=p.count;form.elements.tone.value=p.tone;form.elements.enabled.checked=!!p.enabled;form.elements.quietStart.value=p.quietStart||'22:00';form.elements.quietEnd.value=p.quietEnd||'07:00';form.querySelector('[data-times]').replaceChildren();timeFields();form.elements.tone.onchange();hub.querySelector('[data-message-count]').textContent=p.enabled?p.count+' messages / day':'Reminders paused';hub.querySelector('.mission-arm').firstChild.textContent=p.enabled?'YOUR ORDERS ARE ARMED ':'ARM YOUR REMINDERS ';}\r\n async function load(){try{showPlan(await api('/api/reminders/plan'));}catch(error){form.querySelector('[data-plan-status]').textContent=error.message;}}\r\n document.querySelector('.coach-dock [data-route=reminders]')?.addEventListener('click',load);\r\n form.onsubmit=async event=>{event.preventDefault();const button=form.querySelector('[type=submit]');button.disabled=true;try{const p=await api('/api/reminders/plan','PUT',{count:Number(form.elements.count.value),times:[...form.querySelectorAll('[data-times] input')].map(i=>i.value),tone:form.elements.tone.value,enabled:form.elements.enabled.checked,timezone,daysPerWeek:7,quietStart:form.elements.quietStart.value,quietEnd:form.elements.quietEnd.value});showPlan(p);form.querySelector('[data-plan-status]').textContent=p.enabled?'Orders saved. Turn on notifications for this device below.':'Orders paused.';}catch(error){form.querySelector('[data-plan-status]').textContent=error.message;}finally{button.disabled=false;}};\r\n paint();\r\n}\r\n","coach-names.mjs":"// User-selected coach identities. Each retained coach has one or two display names.\r\n// Person, workout, and tech preserve provenance from the matching original candidate.\r\n// Track is the coach's primary mapped workout group (performance-catalog tracks).\r\nexport const EXCLUDED_COACH_IDS=Object.freeze(['roster/21-flyer--winged_humanoid_3d_model','roster/18-quad-all--wooden_robot_3d_model']);\r\nconst ROWS=[\r\n[\"myr5\",\"original\",[\"MYR5 Jacked LaLAN\",\"Jack LaLanne\",\"jacked strength\",\"local area network\"],[\"MYR5 AT-Lift Prime\",\"Charles Atlas\",\"lift\",\"model designation\"]],\r\n[\"02-taper-tallstalk--humanoid_robot_3d_model1\",\"arms\",[\"Arnoid Press\",\"Arnold Schwarzenegger\",\"Arnold press\",\"android\"],[\"ScotTorque Curl\",\"Larry Scott\",\"curl\",\"motor torque\"]],\r\n[\"19-genie-multi--multi-armed_humanoid_3d_model1\",\"arms\",[\"Ferri-Delt L0U\",\"Lou Ferrigno\",\"delt\",\"robot designation\"],[\"R0N Curlman\",\"Ronnie Coleman\",\"curl\",\"engine manifold\"]],\r\n[\"19-genie-multi--multi-armed_humanoid_3d_model\",\"arms\",[\"Frank Delt-Zan3\",\"Frank Zane\",\"delt\",\"magnetic coil\"],[\"Cutlerator Curl\",\"Jay Cutler\",\"curl\",\"accelerator\"]],\r\n[\"17-shellcap-manyarm--mushroom_creature_3d_model\",\"arms\",[\"KAI-nematic Raise\",\"Kai Greene\",\"raise\",\"kinematic mechanism\"],[\"Philament Heave Press\",\"Phil Heath\",\"press\",\"electrical filament\"]],\r\n[\"17-shellcap-manyarm--mushroom_robot_3d_model\",\"arms\",[\"Wheel-er Servo-Shrug\",\"Flex Wheeler\",\"shrug\",\"servo wheel\"]],\r\n[\"23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"arms\",[\"Ree-volts Raise\",\"Steve Reeves\",\"raise\",\"voltage\"]],\r\n[\"08-shard-asym--robot_3d_model4\",\"arms\",[\"S3RG Oliv-Armature\",\"Sergio Oliva\",\"arm\",\"motor armature\"]],\r\n[\"17-shellcap-manyarm--3d_character_figurine\",\"arms\",[\"Delt-alinn Bailey\",\"Dana Linn Bailey\",\"delt\",\"Delta designation\"]],\r\n[\"06-ridge-triad--geometric_robot_3d_model1\",\"chest\",[\"Oliva-C Pec\",\"Sergio Oliva\",\"pec\",\"vacuum drive\"]],\r\n[\"08-shard-asym--geometric_robot_3d_model\",\"chest\",[\"Pec-n0ld Reactor\",\"Arnold Schwarzenegger\",\"pec\",\"reactor\"]],\r\n[\"16-spade-arch--pyramid_head_figure_3d_model\",\"chest\",[\"Franx Pec-Zane\",\"Frank Zane\",\"pec\",\"motor drive\"],[\"Y4TES Yoke\",\"Dorian Yates\",\"press\",\"powered yoke\"]],\r\n[\"04-crest-wedge--robot_creature_3d_model\",\"chest\",[\"L0U Ferri-pecctor\",\"Lou Ferrigno\",\"pec\",\"reactor\"],[\"Wheeler Wheel-Bench\",\"Flex Wheeler\",\"bench\",\"drive wheel\"]],\r\n[\"16-spade-arch--stylized_humanoid_3d_model\",\"chest\",[\"Cutlerator Press\",\"Jay Cutler\",\"press\",\"accelerator\"]],\r\n[\"04-crest-wedge--stylized_3d_character\",\"chest\",[\"Gr33ne Grid-Press\",\"Kai Greene\",\"press\",\"power grid designation\"]],\r\n[\"09-monolith-tanka--3d_robot_model\",\"chest\",[\"chris BenchSTEAD\",\"Chris Bumstead\",\"bench\",\"robot\"]],\r\n[\"09-monolith-tanka--white_horned_robot_3d_model\",\"chest\",[\"Cavalier-EX Chest\",\"Jeff Cavaliere\",\"chest\",\"exercise model EX\"]],\r\n[\"15-orbital-coili--robot_character_3d_model\",\"quads\",[\"t-OHM Platzma\",\"Tom Platz\",\"squat\",\"plasma\"]],\r\n[\"13-fan-split--stylized_3d_character2\",\"quads\",[\"Quad-Cutler LEGS THO\",\"Jay Cutler\",\"quad\",\"circuit\"],[\"BumSTEADy Squat\",\"Chris Bumstead\",\"squat\",\"steady-state control\"]],\r\n[\"22-curve--stylized_cartoon_figure_3d_model\",\"quads\",[\"Kai Gr33ne Lunge\",\"Kai Greene\",\"lunge\",\"gear designation\"]],\r\n[\"02-taper-tallstalk--3d_humanoid_figure\",\"quads\",[\"Hane-Yoke Lunge\",\"Lee Haney\",\"lunge\",\"powered yoke\"],[\"Stern-on Squat\",\"Erin Stern\",\"squat\",\"power-on switch\"]],\r\n[\"02-taper-tallstalk--white_humanoid_doll_3d_model\",\"quads\",[\"Oli-Volt Lunge\",\"Sergio Oliva\",\"lunge\",\"voltage\"],[\"Y4TES Yoke-Squat\",\"Dorian Yates\",\"squat\",\"robot designation\"]],\r\n[\"18-quad-all--wooden_four-legged_robot_3d_model\",\"quads\",[\"Priest-L33 Squat\",\"Lee Priest\",\"squat\",\"piston\"]],\r\n[\"18-quad-all--stylized_quadruped_3d_model\",\"quads\",[\"Quadzilla Platz\",\"Tom Platz\",\"quads\",\"kaiju creature\"],[\"SternShift Squat\",\"Erin Stern\",\"squat\",\"gear shift\"]],\r\n[\"23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"glutes\",[\"Con-Thrust-Era\",\"Bret Contreras\",\"hip thrust\",\"thruster\"]],\r\n[\"23-blob-texture-bodies--sand_creature_3d_model\",\"glutes\",[\"Tingularity Thrust\",\"Chloe Ting\",\"hip thrust\",\"singularity\"]],\r\n[\"03-pearl-orb-ring--stylized_3d_character1\",\"glutes\",[\"Gyrvanium Glute-Drive\",\"Caroline Girvan\",\"glute\",\"futuristic alloy\"],[\"Jill-iON Hinge-Flex\",\"Jillian Michaels\",\"hip hinge\",\"ion drive\"]],\r\n[\"03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"glutes\",[\"Trac-ION Hip-Thrust\",\"Tracy Anderson\",\"hip thrust\",\"ion drive\"],[\"Simmonics Bridge-Servo\",\"Whitney Simmons\",\"bridge\",\"electronics servo\"]],\r\n[\"03-pearl-orb-ring--abstract_humanoid_3d_model\",\"glutes\",[\"Robo-ertson Bridge\",\"Heather Robertson\",\"bridge\",\"robot\"],[\"Hearn-ess ExoHinge\",\"Katy Hearn\",\"hinge\",\"exosuit harness\"]],\r\n[\"03-pearl-orb-ring--circle_center\",\"glutes\",[\"Con-Terra Coil-Bridge\",\"Bret Contreras\",\"bridge\",\"planetary coil\"],[\"Cyb-Ho Holo-Bridge\",\"Cassey Ho\",\"bridge\",\"cyborg hologram\"]],\r\n[\"23-blob-texture-bodies--cute_blob_creature_3d_model\",\"glutes\",[\"Chlo-Turbo Thrust\",\"Chloe Ting\",\"thrust\",\"turbine\"]],\r\n[\"10-petal-wisp--fantasy_creature_3d_model4\",\"yoga\",[\"Adriene A-Sana Mk II\",\"Adriene Mishler\",\"asana\",\"model revision\"]],\r\n[\"19-genie-multi--fantasy_creature_3d_model\",\"yoga\",[\"Mat-Gregor Matrix\",\"Kino MacGregor\",\"mat\",\"simulation matrix\"]],\r\n[\"10-petal-wisp--ghost_character_3d_model\",\"yoga\",[\"Warri0r-ner Drive\",\"Dylan Werner\",\"warrior pose\",\"motor designation\"],[\"Kathryn Bend-1g\",\"Kathryn Budig\",\"bend\",\"robot\"]],\r\n[\"08-shard-asym--stylized_action_figure_3d_model\",\"yoga\",[\"Yee-lastic Flow\",\"Rodney Yee\",\"yoga flow\",\"elastic mechanics\"]],\r\n[\"22-curve--stylized_alien_3d_model\",\"yoga\",[\"Strom Flex Current\",\"Max Strom\",\"stretch\",\"electric current\"]],\r\n[\"10-petal-wisp--stylized_creature_3d_model\",\"yoga\",[\"Iyeng-Arc Inversion\",\"B. K. S. Iyengar\",\"inversion\",\"powered arc\"]],\r\n[\"19-genie-multi--stylized_octopus_3d_model\",\"yoga\",[\"Yee Gyro-Yogi\",\"Rodney Yee\",\"yoga\",\"gyroscope\"]],\r\n[\"01-seed-pearo--cute_alien_figure_3d_model\",\"yoga\",[\"Wern-Axis Flow\",\"Dylan Werner\",\"flow\",\"robotic axis\"],[\"Mat-Gregor Drive\",\"Kino MacGregor\",\"mat practice\",\"motor drive\"]],\r\n[\"01-seed-pearo--white_3d_character_model\",\"yoga\",[\"Budig-ital Balance\",\"Kathryn Budig\",\"balance\",\"digital\"],[\"Corn Kernel Cobra\",\"Seane Corn\",\"cobra pose\",\"computing kernel\"]],\r\n[\"09-monolith-tanka--boxy_humanoid_3d_model\",\"martial-arts\",[\"Bruce L3300\",\"Bruce Lee\",\"kick\",\"alphanumeric call sign\"],[\"GSP-Drive\",\"Georges St-Pierre\",\"spar\",\"motor drive\"]],\r\n[\"11-anvil-cask--clay-style_robot_3d_model\",\"martial-arts\",[\"Anderson Sil-VOLT\",\"Anderson Silva\",\"strike\",\"voltage\"],[\"r0nda Rous-Bot\",\"Ronda Rousey\",\"armbar\",\"robot\"]],\r\n[\"05-slope-bobble--clay_humanoid_figure_3d_model\",\"martial-arts\",[\"C0N0R McG-Gear\",\"Conor McGregor\",\"kick\",\"gear transmission\"],[\"Nor-Rotor Punch\",\"Chuck Norris\",\"punch\",\"rotor\"]],\r\n[\"14-chisel-spire--cone_head_3d_model\",\"martial-arts\",[\"LiDAR Jett-Jab\",\"Jet Li\",\"jab\",\"laser ranging\"],[\"Jaa-Bot Jab\",\"Tony Jaa\",\"jab\",\"robot\"]],\r\n[\"08-shard-asym--fantasy_creature_3d_model2\",\"martial-arts\",[\"Waters0nic\",\"Michelle Waterson\",\"kick\",\"sonic drive\"],[\"Amanda Nu-NEURAL\",\"Amanda Nunes\",\"strike\",\"neural implant\"]],\r\n[\"09-monolith-tanka--mini_robot_3d_model\",\"martial-arts\",[\"Machi-Droid-a\",\"Lyoto Machida\",\"chop\",\"android\"],[\"Bas Rut-TORque\",\"Bas Rutten\",\"kick\",\"motor torque\"]],\r\n[\"09-monolith-tanka--robot_3d_model3\",\"martial-arts\",[\"Israel Ade-SYNC-ya\",\"Israel Adesanya\",\"strike\",\"synchronization\"],[\"Shev-Servo Sweep\",\"Valentina Shevchenko\",\"sweep\",\"servo\"]],\r\n[\"13-fan-split--stylized_toy_3d_model\",\"martial-arts\",[\"BlankSaber Kick\",\"Billy Blanks\",\"kick\",\"energy saber\"],[\"Wilsonic Kick\",\"Don Wilson\",\"kick\",\"sonic drive\"]],\r\n[\"09-monolith-tanka--robot_3d_model2\",\"martial-arts\",[\"Rous-Torque Throw\",\"Ronda Rousey\",\"throw\",\"motor torque\"],[\"Jackie Chain-Kick\",\"Jackie Chan\",\"kick\",\"chain drive\"]],\r\n[\"07-bulb-sphereling--humanoid_robot_3d_model\",\"cardio\",[\"B0LT Sprint-Drive\",\"Usain Bolt\",\"sprint\",\"electrical bolt drive\"]],\r\n[\"03-pearl-orb-ring--ringed_humanoid_3d_model\",\"cardio\",[\"Fon-Dynamo Footwork\",\"Jane Fonda\",\"footwork\",\"dynamo\"],[\"Simmonics Sweatstream\",\"Richard Simmons\",\"aerobic sweat\",\"electronics stream\"]],\r\n[\"06-ridge-triad--robot_3d_model1\",\"cardio\",[\"M0 Farah Fastlane\",\"Mo Farah\",\"fast run\",\"electric capacitance\"]],\r\n[\"03-pearl-orb-ring--robot_3d_model\",\"cardio\",[\"Feli-X Footdrive\",\"Allyson Felix\",\"footwork\",\"X-model drive\"],[\"Rad-Clutch Run\",\"Paula Radcliffe\",\"run\",\"motor clutch\"]],\r\n[\"20-lume--robotic_figure_3d_model\",\"cardio\",[\"Pre-Font-AI-ne Pace\",\"Steve Prefontaine\",\"pace\",\"AI running model\"],[\"Ohm-wens Run\",\"Jesse Owens\",\"run\",\"electrical resistance\"]],\r\n[\"07-bulb-sphereling--cute_robot_3d_model\",\"cardio\",[\"Billy Blanx Beam\",\"Billy Blanks\",\"boot camp\",\"waveform\"],[\"GebreShell Runloop\",\"Haile Gebrselassie\",\"run\",\"software shell loop\"]],\r\n[\"01-seed-pearo--blank_toy_figure_3d_model\",\"cardio\",[\"Phelpeller Pulse\",\"Michael Phelps\",\"cardio pulse\",\"propeller\"],[\"Fon-Droid Footwork\",\"Jane Fonda\",\"footwork\",\"android\"]],\r\n[\"18-quad-all--dragon_creature_3d_model\",\"meditation\",[\"H0F-Lung\",\"Wim Hof\",\"breathing\",\"oxygen-code lung\"]],\r\n[\"18-quad-all--fantasy_creature_3d_model1\",\"meditation\",[\"Max Ohm-Strom Breath\",\"Max Strom\",\"breathing\",\"electrical resistance\"],[\"Yee-uro Zen\",\"Rodney Yee\",\"mindful movement\",\"neural interface\"]],\r\n[\"18-quad-all--fantasy_creature_3d_model3\",\"meditation\",[\"Shiva Rea-spatory\",\"Shiva Rea\",\"respiration\",\"airlock\"]],\r\n[\"18-quad-all--four-legged_robot_3d_model\",\"meditation\",[\"Tara-5tile5-Standby\",\"Tara Stiles\",\"breathing\",\"computer standby\"]],\r\n[\"18-quad-all--quadruped_robot_3d_model1\",\"meditation\",[\"Werner Wind0wn\",\"Dylan Werner\",\"wind-down practice\",\"alphanumeric standby mode\"]],\r\n[\"18-quad-all--quadruped_robot_3d_model\",\"meditation\",[\"Yee Holo-Om\",\"Rodney Yee\",\"mindful movement\",\"hologram\"]],\r\n[\"18-quad-all--robotic_dog_3d_model\",\"meditation\",[\"Budig-ital Breath\",\"Kathryn Budig\",\"breathing\",\"digital\"]],\r\n[\"12-seedpod-snailslug--stylized_slug_3d_model\",\"meditation\",[\"H0F Hold-Circuit\",\"Wim Hof\",\"breath hold\",\"circuit and model code\"],[\"Ohm-Strom Still\",\"Max Strom\",\"stillness\",\"electrical resistance\"]],\r\n[\"12-seedpod-snailslug--stylized_worm_3d_model\",\"meditation\",[\"Pilat-OS Calm-Circuit\",\"Joseph Pilates\",\"mindful breathing\",\"operating system circuit\"]],\r\n[\"14-chisel-spire--low_poly_robot_3d_model\",\"meditation\",[\"Rea-Spire Relay\",\"Shiva Rea\",\"respiration\",\"air relay\"]],\r\n[\"01-seed-pearo--3d_character_model\",\"meditation\",[\"McKe-O2 Nose-Cone\",\"Patrick McKeown\",\"nasal breathing\",\"rocket nose cone\"],[\"Vertu-al Vent\",\"Shona Vertue\",\"ventilation\",\"virtual reality\"]],\r\n[\"23-blob-texture-bodies--blob_creature_3d_model\",\"meditation\",[\"Blob 1 · H0F Hold-Drive\",\"Wim Hof\",\"breath hold\",\"air drive and model code\"]],\r\n[\"01-seed-pearo--blank_humanoid_figure_3d_model\",\"meditation\",[\"Corn Kernel Om\",\"Seane Corn\",\"meditation\",\"computing kernel\"],[\"Kino-Kinetic Breath\",\"Kino MacGregor\",\"breathing\",\"kinematics\"]],\r\n];\r\nconst META=Object.freeze(Object.fromEntries(ROWS.map(([path,track,...candidates])=>[path==='myr5'?path:`roster/${path}`,Object.freeze({track,names:Object.freeze(candidates.map(([name,person,workout,scifi])=>Object.freeze({name,person,workout,scifi})))})])));\r\nexport const COACH_NAME_META=META;\r\n/** One or two user-selected names by stable coach id. */\r\nexport const COACH_NAMES=Object.freeze(Object.fromEntries(Object.entries(META).map(([id,m])=>[id,Object.freeze(m.names.map(n=>n.name))])));\r\nexport const normalizePun=text=>String(text).toLowerCase().normalize('NFD').replace(/[^a-z0-9]/g,'');\r\nfunction metaFor(coachId){const meta=META[coachId];if(!meta)throw RangeError(`No coach name for ${coachId}.`);return meta;}\r\n/** Primary name, or the second candidate if available. */\r\nexport const coachName=(coachId,alternative=false)=>{const names=metaFor(coachId).names;return names[alternative?1:0]?.name??names[0].name;};\r\n/** Toggle a pair; a single-name coach keeps its selected name. */\r\nexport function cycleCoachName(coachId,current){const names=metaFor(coachId).names.map(n=>n.name);return names.length===1?names[0]:current===names[0]?names[1]:names[0];}\r\n","coach-net.mjs":"// Never-throw network helper for coach paths: timeout, 5xx and offline all resolve to {ok:false,fallback}.\r\n// After a failure the net is treated as down for COOLDOWN ms (no 5 s waits on every cue); then the next call probes again.\r\nconst COOLDOWN=10000;let downUntil=0;\r\nif(typeof window!=='undefined')window.addEventListener('online',()=>{downUntil=0;});\r\nexport const coachOnline=(now=Date.now())=>now>=downUntil&&globalThis.navigator?.onLine!==false;\r\nexport const resetCoachNet=()=>{downUntil=0;};\r\nconst down=fallback=>({ok:false,data:fallback,fallback:true});\r\nexport async function coachFetch(url,opts={},{timeoutMs=8000,fallback=null,parse='json',local=false,retry=0,backoffMs=400,fetchImpl=globalThis.fetch}={}){\r\n if(local){ // downloaded packs answer from the Cache API even when the network is down\r\n  try{const hit=await globalThis.caches?.match(url);if(hit?.ok)return {ok:true,data:parse==='response'?hit:await hit[parse](),fallback:false,status:200};}catch{}\r\n }\r\n if(!coachOnline())return down(fallback);\r\n for(let attempt=0;;attempt++){\r\n  // Plain controller + timer: AbortSignal.any is missing before Safari 17.4 and would mute every older iPhone.\r\n  const ctl=new AbortController(),timer=setTimeout(()=>ctl.abort(),timeoutMs),relay=()=>ctl.abort();\r\n  opts.signal?.addEventListener('abort',relay,{once:true});\r\n  try{\r\n   const response=await fetchImpl(url,{...opts,signal:ctl.signal});\r\n   if(response.status<500){ // 4xx is an answer, not an outage\r\n    const data=!response.ok?fallback:parse==='response'?response:await response[parse]();\r\n    downUntil=0;return {ok:response.ok,data,fallback:!response.ok,status:response.status};\r\n   }\r\n  }catch(error){if(opts.signal?.aborted)return down(fallback);}\r\n  finally{clearTimeout(timer);opts.signal?.removeEventListener('abort',relay);}\r\n  if(attempt>=retry)break;\r\n  await new Promise(r=>setTimeout(r,backoffMs));\r\n }\r\n downUntil=Date.now()+COOLDOWN;return down(fallback);\r\n}\r\n","coach-overlay.mjs":"// Full-body coach in the room during a tracked set: off frame until the first rep (or held second) counts,\r\n// then it walks in and wanders beside, behind and in front of the user. Kick it and it spins off, then walks back.\r\nimport {CoachMotion,COACH} from './coach-hit.mjs';\r\nimport {coach3dEnabled,COACH_AURA_LEVEL,COACH_AURA_PLACE} from './coach3d-flag.mjs';\r\nimport {mapPointToOverlay} from './arcade/workout-effects-state.mjs';\r\nconst $=id=>document.getElementById(id);\r\n\r\n// D43.5: while a set is counting, the coach gives up frames before the counter does. window.myr5TestState.rate\r\n// is the tracking loop's own pose-update measurement (app.mjs) — reused here, not remeasured.\r\n// Speed fix (3 Oct): below minPoseHz the coach is OFF, not 10 fps: the box leaves layout (display:none) so the\r\n// creature viewer's IntersectionObserver stops its WebGL loop, and no coach-hit math or DOM writes run. Phones\r\n// measured 1.4–1.9 updates/s with the coach on; reps need ~4+/s. It comes back after recoverMs of fast tracking,\r\n// doubling each time it is cut again in the same set so a phone near the line doesn't flicker it on and off.\r\n// Its per-pose work runs in the next animation frame (latest pose only), never inside the tracker's detect call.\r\nconst COACH_CAP={minPoseHz:4,recoverMs:2000};\r\nconst COACH_GESTURE={spun:'laugh',held:'wiggle',swiping:'swipe',impressed:'agree',laughing:'laugh'};\r\n\r\n// Same mapping as every effect layer (one mapper in workout-effects-state.mjs); unknown points stay invisible at 0,0.\r\nexport function videoToScreen(point,{videoW,videoH,screenW,screenH,mirrored}){\r\n return mapPointToOverlay(point,{videoWidth:videoW,videoHeight:videoH,hostWidth:screenW,hostHeight:screenH,mirrored})??{x:0,y:0,visibility:0};\r\n}\r\n\r\nexport function mountCoachOverlay(){\r\n const aura=!coach3dEnabled(); // aura mode (default): the coach only appears at aura level 3 (coach3d-flag.mjs)\r\n let overlay=null,box=null,card=null,motion=null,tracking=false,boxH=0,gesturePhase=null,walking=false,begun=false,loading=null,lastState=null;\r\n let capped=false,aboveSince=null,caps=0,pending=null,scheduled=0,animation=0,lastAnimation=0,auraOn=false,auraTimer=0,auraRun=0;\r\n async function ensureCard(){\r\n  card=document.querySelector('.myr5-companion-card');if(card)return;\r\n  loading??=(async()=>{\r\n   if(!document.querySelector('link[href=\"/creature/phone.css\"]')){const link=document.createElement('link');link.rel='stylesheet';link.href='/creature/phone.css';document.head.append(link);}\r\n   try{await import('/creature/assets/phone.js');}catch{}\r\n   card=document.querySelector('.myr5-companion-card');\r\n  })();\r\n  await loading;\r\n }\r\n function ensureOverlay(){\r\n  overlay=$('coachOverlay');if(!overlay)return;\r\n  box=overlay.querySelector('.coach-overlay-box');\r\n  if(!box){box=document.createElement('div');box.className='coach-overlay-box';box.style.cssText='position:absolute;left:0;top:0;transform-origin:50% 50%';overlay.append(box);}\r\n }\r\n const walk=on=>{if(on!==walking){walking=on;window.myr5Creature?.walk?.(on);}};\r\n // Off frame the box leaves layout (display:none), not just visibility:hidden: only then does the coach\r\n // viewer's IntersectionObserver pause its WebGL loop, which otherwise competes with the CPU pose tracker\r\n // (main thread and its per-frame GPU readback) while the user is still setting their start.\r\n const shown=on=>{box.style.visibility=on?'visible':'hidden';box.style.display=on?'':'none';};\r\n async function enter(){\r\n  await ensureCard();if(!card||!tracking)return;\r\n  ensureOverlay();if(!box)return;if(card.parentElement!==box)box.append(card);\r\n  boxH=0;gesturePhase=null;lastState=null;capped=false;aboveSince=null;caps=0;window.myr5Creature?.setMaxFps?.(null);shown(false);\r\n  motion=new CoachMotion({aspect:innerWidth/innerHeight,now:performance.now(),play:!String(window.myr5Creature?.stats?.()?.recipe?.body||'').startsWith('roster/18-quad')});if(begun)motion.begin();\r\n  window.myr5Creature?.stage('overlay');\r\n }\r\n function leave(){\r\n  cancelAnimationFrame(scheduled);cancelAnimationFrame(animation);animation=0;scheduled=0;pending=null;motion=null;lastState=null;walk(false);window.myr5Creature?.face?.(0);window.myr5Creature?.setMaxFps?.(null);if(!card)return;\r\n  card.style.cssText='';if(box)box.style.visibility=box.style.display='';\r\n  // Aura mode: the rest scene shows the 64-bit sprite (pod.mjs), so the 3D card parks in the pod mount instead.\r\n  const toRest=document.body.dataset.screen==='rest'&&!aura,mount=toRest?$('restCoachMount'):$('coachMount');\r\n  if(mount&&card.parentElement!==mount)mount.append(card);\r\n  window.myr5Creature?.stage(toRest?'encounter':'pod');\r\n }\r\n function place(state){\r\n  if(!box)return;\r\n  const hidden=state.phase==='offstage'||state.phase==='away';\r\n  shown(!hidden);\r\n  walk(state.phase==='walking'||state.phase==='charge');window.myr5Creature?.face?.(state.yaw);\r\n  // One clip per phase entry; `wiggle` loops, so it is re-asked every frame (a no-op while it already plays).\r\n  const gesture=COACH_GESTURE[state.phase];\r\n  if(gesture&&(state.phase!==gesturePhase||state.phase==='held'))window.myr5Creature?.play(gesture);\r\n  gesturePhase=gesture?state.phase:null;\r\n  if(hidden||!state.baseHeight)return;\r\n  // The card is sized for the coach level with the user (a resize re-renders WebGL, so only on 15% changes);\r\n  // walking nearer or farther is a CSS scale about the card's centre, keeping the feet on the floor line.\r\n  const w=innerWidth,h=innerHeight,base=state.baseHeight*h;\r\n  if(!boxH||Math.abs(base-boxH)/boxH>.15){boxH=base;box.style.width=Math.max(1,base*COACH.boxWidth)+'px';box.style.height=Math.max(1,base)+'px';}\r\n  const k=state.height*h/boxH;\r\n  // held: dangles by the head, a small pendulum about the box top. fallen: toppled 90° away from the user about the\r\n  // feet (eased by a short transition, which also eases the get-up). Whole-card transforms, so every silhouette works.\r\n  const swing=state.phase==='held'?Math.sin(performance.now()/160)*.12:0;\r\n  const pivot=state.phase==='held'?'translate(0,-50%) ':state.phase==='fallen'?'translate(0,50%) ':'';\r\n  const unpivot=state.phase==='held'?' translate(0,50%)':state.phase==='fallen'?' translate(0,-50%)':'';\r\n  const tilt=state.rotation+swing+(state.phase==='fallen'?state.side*Math.PI/2:0);\r\n  box.style.transition=/^(fallen|impressed|laughing)$/.test(state.phase)?'transform .35s ease-in':'';\r\n  box.style.transform=`translate(${state.x*w-boxH*COACH.boxWidth/2}px,${state.feetY*h-(k+1)*boxH/2}px) scale(${k}) ${pivot}rotate(${tilt}rad)${unpivot}`;\r\n }\r\n function animate(now){\r\n  animation=0;if(!tracking||!motion||capped)return;\r\n  if(now-lastAnimation>=1000/30){const state=motion.tick(now);if(state){lastAnimation=now;lastState=state;place(state);}}\r\n  if(['spun','dropped','away'].includes(lastState?.phase))animation=requestAnimationFrame(animate);\r\n }\r\n function apply(state){lastState=state;place(state);if(!animation&&['spun','dropped','away'].includes(state.phase)&&!capped)animation=requestAnimationFrame(animate);}\r\n // Hysteresis: off the moment tracking is slow; back only after minPoseHz has held for recoverMs (doubled per cut).\r\n function updateCap(counting,now){\r\n  if(!counting){capped=false;aboveSince=null;return;}\r\n  const rate=window.myr5TestState?.rate;\r\n  if(Number.isFinite(rate)&&rate<COACH_CAP.minPoseHz){if(!capped)caps++;capped=true;aboveSince=null;}\r\n  else{aboveSince??=now;if(capped&&now-aboveSince>=COACH_CAP.recoverMs*2**Math.min(caps-1,3))capped=false;}\r\n }\r\n function flush(){\r\n  cancelAnimationFrame(scheduled);scheduled=0;\r\n  const detail=pending;pending=null;\r\n  if(!detail||!tracking||!motion||!box)return;\r\n  const {points,width,height,mirrored,now,counting}=detail;\r\n  if(counting&&!begun){begun=true;motion.begin();}\r\n  updateCap(counting,now);\r\n  if(capped){shown(false);walk(false);return;}\r\n  const screenPoints=points?points.map(p=>videoToScreen(p,{videoW:width,videoH:height,screenW:innerWidth,screenH:innerHeight,mirrored})):null;\r\n  apply(motion.update(screenPoints,now));\r\n }\r\n function onPose(event){pending=event.detail;scheduled||=requestAnimationFrame(flush);}\r\n window.addEventListener('myr5:pose',onPose);\r\n function setTracking(busy){if(busy===tracking)return;tracking=busy;if(busy){begun=false;if(!aura)void enter();}else{auraOn=false;auraRun++;clearTimeout(auraTimer);leave();}}\r\n // Aura mode: he joins at COACH_AURA_LEVEL (small, bottom-right, facing us, a greeting then idle) and fades out when the\r\n // level drops, at rest, or at set end. Assets load on the first entrance, never before.\r\n async function auraEnter(){\r\n  const run=++auraRun;auraOn=true;\r\n  await ensureCard();if(run!==auraRun||!auraOn||!tracking||!card)return;\r\n  ensureOverlay();if(!box)return;if(card.parentElement!==box)box.append(card);\r\n  clearTimeout(auraTimer);\r\n  const P=COACH_AURA_PLACE,h=Math.round(innerHeight*P.heightPct),w=Math.round(h*COACH.boxWidth);\r\n  box.style.transition='none';box.style.visibility='visible';box.style.display='';\r\n  box.style.cssText+=`;left:${Math.round(innerWidth*(1-P.rightPct)-w)}px;top:${Math.round(innerHeight*(1-P.bottomPct)-h)}px;width:${w}px;height:${h}px;transform-origin:50% 100%;transform:scale(.55);opacity:0`;\r\n  window.myr5Creature?.stage('overlay');window.myr5Creature?.walk?.(false);window.myr5Creature?.face?.(0);window.myr5Creature?.play('greet');\r\n  requestAnimationFrame(()=>requestAnimationFrame(()=>{if(run!==auraRun)return;box.style.transition=`opacity ${P.enterMs}ms ease-out,transform ${P.enterMs}ms cubic-bezier(.2,.9,.3,1.25)`;box.style.opacity='1';box.style.transform='scale(1)';}));\r\n }\r\n function auraLeave(){\r\n  auraOn=false;auraRun++;clearTimeout(auraTimer);if(!box||!card)return;\r\n  box.style.transition=`opacity ${COACH_AURA_PLACE.leaveMs}ms ease-in,transform ${COACH_AURA_PLACE.leaveMs}ms ease-in`;box.style.opacity='0';box.style.transform='scale(.55)';\r\n  auraTimer=setTimeout(()=>{if(!auraOn)leave();},COACH_AURA_PLACE.leaveMs);\r\n }\r\n window.addEventListener('myr5:aura-level',event=>{\r\n  if(!aura||!tracking||document.body.dataset.screen==='rest')return;const level=Number(event.detail?.level)||0;\r\n  if(level>=COACH_AURA_LEVEL&&!auraOn)void auraEnter();else if(level<COACH_AURA_LEVEL&&auraOn)auraLeave();\r\n });\r\n new MutationObserver(()=>setTracking(document.body.dataset.tracking==='true')).observe(document.body,{attributes:true,attributeFilter:['data-tracking']});\r\n // Preparation rest keeps data-tracking on (the camera set resumes after it) but moves the card to the rest scene.\r\n // Without this the overlay kept walking/yawing the coach there: sideways, walk cycle looping. Park it like a set end,\r\n // then take the card back when the set resumes (pod.mjs moves it into #coachOverlay before this event).\r\n window.addEventListener('myr5:preparation-rest-start',()=>{auraOn=false;auraRun++;clearTimeout(auraTimer);if(tracking)leave();});\r\n window.addEventListener('myr5:preparation-rest-end',()=>{if(tracking&&!aura)void enter();});\r\n window.myr5CoachOverlay={\r\n  aura:()=>({mode:aura,on:auraOn,tracking,box:box?.style.cssText??null}),\r\n  start(){document.body.dataset.tracking='true';setTracking(true);},\r\n  begin(){begun=true;motion?.begin();},\r\n  pose(screenPoints){if(!motion||!box)return;apply(motion.update(screenPoints,performance.now()));},\r\n  stop(){document.body.dataset.tracking='false';setTracking(false);},\r\n  flush,\r\n  state:()=>lastState\r\n };\r\n}\r\n","coach-path-picker.css":".coach-path-picker{box-sizing:border-box;width:min(780px,calc(100vw - 20px));max-width:780px;max-height:calc(100dvh - 20px);padding:0;border:2px solid #d98245;border-radius:18px;background:#150e12;color:#ffe0b5;box-shadow:0 0 0 5px #392128,0 26px 85px #000e,inset 0 0 28px #ffad4a1c;font:14px/1.35 ui-monospace,SFMono-Regular,Consolas,monospace}\r\n.coach-path-picker::backdrop{background:#090411df;backdrop-filter:blur(5px)}\r\n.coach-path-picker *{box-sizing:border-box}.coach-path-picker [hidden]{display:none!important}.coach-path-picker button{font:inherit;cursor:pointer}.coach-path-picker :focus-visible{outline:3px solid #ffe6ac;outline-offset:3px}\r\n.cpp-shell{display:grid;grid-template-rows:auto minmax(0,1fr) auto;max-height:calc(100dvh - 24px);overflow:hidden}.cpp-head,.cpp-foot{display:flex;align-items:center;gap:12px;padding:12px 18px;border-color:#914f30;background:linear-gradient(110deg,#40221b,#21131b 70%)}.cpp-head{justify-content:space-between;border-bottom:2px solid #914f30}.cpp-kicker{color:#f5a65f;font-size:11px;font-weight:800;letter-spacing:.18em}.cpp-close{display:grid;place-items:center;width:42px;height:42px;border:1px solid #9a573b;border-radius:8px;background:#2a1918;color:#ffd1a0;font-size:25px!important}.cpp-screen{position:relative;overflow-y:auto;padding:22px;background:repeating-linear-gradient(0deg,#0000 0 3px,#0003 3px 4px),radial-gradient(ellipse at 50% 0,#5f332f7d,transparent 70%)}.cpp-screen:after{content:'';position:sticky;display:block;bottom:0;height:0;pointer-events:none;box-shadow:0 0 44px 27px #130a0d}.cpp-title{display:flex;align-items:center;gap:17px;margin-bottom:22px}.cpp-signal{display:grid;place-items:center;flex:none;width:62px;height:62px;border:2px solid #e68e55;border-radius:16px;color:#ffd097;background:#46281c;box-shadow:inset 0 0 17px #f3ad5550,0 0 18px #fd934042;font-size:36px;text-shadow:0 0 12px #ff9a36}.cpp-title h2{margin:0 0 3px;color:#ffe6b8;font-size:clamp(22px,5vw,34px);letter-spacing:.04em;line-height:1.1}.cpp-title p{margin:0;color:#d6a889;font-size:13px}.cpp-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}.cpp-path{display:flex;align-items:center;gap:12px;min-height:86px;padding:11px 13px;border:2px solid #76543e;border-radius:11px;background:linear-gradient(135deg,#3b2424,#20151a);color:#ffe3bb;text-align:left;box-shadow:inset 0 1px #ffd0a328,0 4px 0 #0f090b;transition:transform .14s ease,border-color .14s ease,background .14s ease}.cpp-path:not(:disabled):hover{transform:translateY(-2px) rotate(-.3deg);border-color:#f4aa6e;background:#51302a}.cpp-path[aria-pressed=true]{border-color:#ffb264;background:linear-gradient(135deg,#6b391f,#31201b);box-shadow:inset 0 0 18px #ffa6403b,0 0 14px #ffa64036,0 4px 0 #150a08}.cpp-path:disabled{cursor:default}.cpp-path-icon{display:grid;place-items:center;flex:none;width:48px;height:48px;border:1px solid #aa7349;border-radius:10px;background:#20120e;color:#ffb973;font-size:27px}.cpp-path-copy{display:grid;gap:3px;min-width:0}.cpp-path-copy strong{font-size:14px;line-height:1.2}.cpp-path-copy small{color:#c39476;font-size:11px}.cpp-path-check{margin-left:auto;align-self:flex-start;color:#ffcc8a;font-size:22px}.cpp-status{min-height:18px;margin:14px 0 0;color:#ffbb85;font-size:12px}.cpp-foot{border-top:2px solid #914f30}.cpp-count{margin-right:auto;color:#ffbe79;font-size:12px;letter-spacing:.08em}.cpp-later,.cpp-confirm{min-height:42px;padding:7px 13px;border:1px solid #bc7650;border-radius:7px;background:#30201f;color:#ffdaad}.cpp-confirm{border-color:#ffbb6c;background:#a64b1d;color:#fff1d7;font-weight:800!important}.cpp-confirm:disabled{opacity:.48;cursor:default}.cpp-confirm:not(:disabled):hover{background:#d26928}.cpp-later:hover,.cpp-close:hover{background:#4a2b28}\r\n@media(max-width:570px){.cpp-screen{padding:17px 12px}.cpp-grid{gap:9px}.cpp-path{gap:8px;min-height:92px;padding:9px}.cpp-path-icon{width:37px;height:37px;font-size:22px}.cpp-path-copy strong{font-size:12px}.cpp-path-copy small{font-size:10px}.cpp-path-check{font-size:17px}.cpp-foot{gap:8px;padding:10px}.cpp-count{font-size:10px}.cpp-later,.cpp-confirm{padding:6px 8px;font-size:11px!important}}\r\n@media(max-width:380px){.cpp-grid{grid-template-columns:1fr}.cpp-path{min-height:61px}.cpp-title{gap:10px}.cpp-signal{width:48px;height:48px;font-size:25px}}\r\n@media(prefers-reduced-motion:reduce){.cpp-path{transition:none}.cpp-path:hover{transform:none}}\r\n","coach-path-picker.mjs":"import {CHOOSABLE_TRACKS,chooseWorkoutPaths,readSelectedTracks} from './chosen-styles.mjs';\r\nimport {PATH_SYMBOLS} from './coach-path-symbols.mjs';\r\n\r\nconst COPY={\r\n chest:['Chest','🏋️','Press strength'],quads:['Quads','🦵','Leg drive'],glutes:['Glutes','↗','Hip power'],\r\n 'arms-shoulders':['Arms & shoulders','💪','Upper strength'],yoga:['Yoga','🧘','Balance & mobility'],\r\n 'martial-arts':['Martial arts','🥋','Combat movement'],cardio:['Cardio','⚡','Heart & stamina'],\r\n};\r\nconst owner=account=>account?.user?.id&&Number.isSafeInteger(account.dataEpoch)?`${account.user.id}:${account.dataEpoch}`:null;\r\nconst busyWorkout=()=>document.body.dataset.cameraWorkout==='true'||document.body.dataset.tracking==='true'||document.body.dataset.screen==='rest'||!['idle','error',undefined].includes(window.myr5TestState?.phase);\r\nconst style=()=>{if(document.getElementById('coachPathPickerStyle'))return;const link=document.createElement('link');link.id='coachPathPickerStyle';link.rel='stylesheet';link.href='/coach-path-picker.css';document.head.append(link);};\r\n\r\n/** One visit per account generation until choice. A manual route can always reopen it. */\r\nexport function mountCoachPathPicker({getAccount,savePaths,onChosen}={}){\r\n if(typeof getAccount!=='function'||typeof savePaths!=='function')throw TypeError('Coach path picker needs account and save handlers.');\r\n style();\r\n const dialog=document.createElement('dialog');dialog.id='coachPathPicker';dialog.className='coach-path-picker';dialog.setAttribute('aria-labelledby','cppTitle');\r\n dialog.innerHTML=`<div class=\"cpp-shell\"><header class=\"cpp-head\"><span class=\"cpp-kicker\">COACH // PATH SELECT</span><button class=\"cpp-close\" type=\"button\" aria-label=\"Close path picker\">×</button></header><div class=\"cpp-screen\"><div class=\"cpp-title\"><span class=\"cpp-signal\" aria-hidden=\"true\">◈</span><div><h2 id=\"cppTitle\">Choose two paths</h2><p id=\"cppHint\">Pick two. Meet their first coaches.</p></div></div><div class=\"cpp-grid\" role=\"group\" aria-label=\"Workout paths\"></div><p class=\"cpp-status\" role=\"status\" aria-live=\"polite\"></p></div><footer class=\"cpp-foot\"><span class=\"cpp-count\" aria-live=\"polite\">0 / 2 selected</span><button class=\"cpp-later\" type=\"button\">Later</button><button class=\"cpp-confirm\" type=\"button\" disabled>Start these paths <span aria-hidden=\"true\">→</span></button></footer></div>`;\r\n document.body.append(dialog);\r\n const grid=dialog.querySelector('.cpp-grid'),count=dialog.querySelector('.cpp-count'),confirm=dialog.querySelector('.cpp-confirm'),status=dialog.querySelector('.cpp-status'),later=dialog.querySelector('.cpp-later');\r\n const selection=new Set(),attempted=new Set();let activeOwner=null,saving=false,disposed=false,pending=0,hiddenSinceOpen=false;\r\n for(const id of CHOOSABLE_TRACKS){const [name,icon,detail]=COPY[id]??[id,'◆','Workout path'];const button=document.createElement('button');button.type='button';button.className='cpp-path';button.dataset.path=id;button.setAttribute('aria-pressed','false');button.innerHTML=`<span class=\"cpp-path-icon\" aria-hidden=\"true\"></span><span class=\"cpp-path-copy\"><strong></strong><small></small></span><span class=\"cpp-path-check\" aria-hidden=\"true\">○</span>`;button.querySelector('.cpp-path-icon').textContent=PATH_SYMBOLS[id]||icon;button.querySelector('strong').textContent=name;button.querySelector('small').textContent=detail;button.addEventListener('click',()=>toggle(id));grid.append(button);}\r\n function paint(){const chosen=readSelectedTracks({account:getAccount()});const locked=chosen.length===2;for(const button of grid.children){const picked=selection.has(button.dataset.path);button.setAttribute('aria-pressed',String(picked));button.querySelector('.cpp-path-check').textContent=picked?'✓':'○';button.disabled=saving||locked;}\r\n  count.textContent=locked?'Paths locked in':`${selection.size} / 2 selected`;confirm.hidden=false;confirm.disabled=saving||(!locked&&selection.size!==2);confirm.textContent=locked?'Proceed →':'Save and proceed →';later.textContent=locked?'Done':'Later';dialog.querySelector('#cppTitle').textContent=locked?'Your two paths':'Choose two paths';dialog.querySelector('#cppHint').textContent=locked?'Your first coaches are ready.':'Pick two. Meet their first coaches.';}\r\n function toggle(id){if(saving||readSelectedTracks({account:getAccount()}).length)return;status.textContent='';if(selection.has(id))selection.delete(id);else if(selection.size<2)selection.add(id);else{status.textContent='Two paths selected. Deselect one to switch.';return;}paint();}\r\n function canOpen(account){return !!owner(account)&&!!account.onboarding&&!account.stale&&!!window.coachPlan&&!document.hidden&&!busyWorkout()&&!document.getElementById('coachSetupGate')?.open&&!document.querySelector('dialog[open]');}\r\n function open({manual=false}={}){const account=getAccount(),key=owner(account);if(disposed||!key||!account.onboarding||account.stale||!window.coachPlan||document.hidden||busyWorkout()||document.getElementById('coachSetupGate')?.open)return null;if(dialog.open)return dialog;if(!manual&&(!canOpen(account)||attempted.has(key)||location.hash&&location.hash!=='#paths'))return null;if(document.querySelector('dialog[open]'))return null;\r\n  activeOwner=key;selection.clear();for(const id of readSelectedTracks({account}))selection.add(id);status.textContent='';hiddenSinceOpen=false;paint();dialog.showModal();if(!manual)attempted.add(key);grid.querySelector('button:not(:disabled)')?.focus();return dialog;}\r\n function schedule(){if(pending||disposed||document.hidden)return;pending=setTimeout(()=>{pending=0;const account=getAccount(),key=owner(account);if(!key||attempted.has(key)||readSelectedTracks({account}).length||!canOpen(account)||location.hash&&location.hash!=='#paths')return;if(window.myr5Routes?.ROUTES?.paths){const opened=window.myr5Routes.go('paths');Promise.resolve(opened).then(dialog=>{if(dialog)attempted.add(key);}).catch(()=>{});}else open();},250);}\r\n function close(){if(dialog.open)dialog.close();}\r\n async function commit(){const account=getAccount(),key=owner(account),paths=[...selection];if(saving||!key||key!==activeOwner||paths.length!==2||readSelectedTracks({account}).length)return;saving=true;paint();status.textContent='Saving your paths…';try{const result=await savePaths(paths,account);if(owner(getAccount())!==key)throw Error('Account changed. Open paths again.');if(!Array.isArray(result?.paths)||result.paths.length!==2||!paths.every(id=>result.paths.includes(id)))throw Error('Path choice could not be verified.');chooseWorkoutPaths(result.paths,{account});status.textContent='Paths ready.';paint();onChosen?.(result.paths,account);close();}catch(error){status.textContent=error?.message||'Could not save paths. Try again.';}finally{saving=false;if(dialog.open)paint();}}\r\n confirm.addEventListener('click',()=>{if(readSelectedTracks({account:getAccount()}).length===2){close();return;}void commit();});later.addEventListener('click',close);dialog.querySelector('.cpp-close').addEventListener('click',close);\r\n dialog.addEventListener('cancel',event=>{if(saving)event.preventDefault();});\r\n dialog.addEventListener('keydown',event=>{if(!['ArrowUp','ArrowDown','ArrowLeft','ArrowRight'].includes(event.key)||!event.target.closest('.cpp-path'))return;const buttons=[...grid.querySelectorAll('button:not(:disabled)')],at=buttons.indexOf(event.target);if(at<0)return;event.preventDefault();const delta=event.key==='ArrowLeft'||event.key==='ArrowUp'?-1:1;buttons[(at+delta+buttons.length)%buttons.length].focus();});\r\n const ready=()=>schedule(),cleared=()=>{activeOwner=null;selection.clear();close();},visible=()=>{if(document.hidden){if(dialog.open){hiddenSinceOpen=true;close();}if(pending){clearTimeout(pending);pending=0;}}else if(!hiddenSinceOpen)schedule();};\r\n window.addEventListener('myr5:coach-plan',ready);window.addEventListener('myr5:account-ready',ready);window.addEventListener('myr5:account-cleared',cleared);document.addEventListener('visibilitychange',visible);document.addEventListener('close',event=>{if(event.target!==dialog)schedule();},true);\r\n const observer=new MutationObserver(()=>schedule());observer.observe(document.body,{attributes:true,attributeFilter:['data-tracking','data-camera-workout','data-screen']});\r\n window.addEventListener('pagehide',()=>{disposed=true;if(pending)clearTimeout(pending);observer.disconnect();close();},{once:true});\r\n window.myr5Menus={...window.myr5Menus,paths:()=>open({manual:true})};\r\n schedule();return {dialog,open,dispose(){disposed=true;if(pending)clearTimeout(pending);observer.disconnect();close();dialog.remove();}};\r\n}\r\n","coach-path-symbols.mjs":"export const PATH_SYMBOLS=Object.freeze({chest:'\\u{1f3cb}\\ufe0f',quads:'\\u{1f9b5}',glutes:'\\u2197',arms:'\\u{1f4aa}','arms-shoulders':'\\u{1f4aa}',yoga:'\\u{1f9d8}','martial-arts':'\\u{1f94b}',cardio:'\\u26a1',meditation:'\\u{1f9d8}',original:'\\u25c8'});\r\n","coach-presentation.mjs":"import {COACH_NAME_META} from './coach-names.mjs';\r\nimport {PATH_SYMBOLS} from './coach-path-symbols.mjs';\r\nexport function coachPresentation(id){\r\n const track=COACH_NAME_META[id]?.track||'original';\r\n return {track,symbol:PATH_SYMBOLS[track]||PATH_SYMBOLS.original};\r\n}\r\n","coach-preview-space.mjs":"import {TIERS,makeSky,makeStars,buildTerrain,glowTexture} from './drop-pod-opening.mjs';\r\n\r\n// Borrow the supply-drop landscape without starting its opening, lights or particles.\r\n// The coach keeps its existing pod floor and lighting; this is its distant view only.\r\nexport function createCoachPreviewSpace(THREE,{pixelRatio=1}={}){\r\n const tier=TIERS.rare,group=new THREE.Group();group.name='coach-preview-space';\r\n const background=makeSky(THREE,tier),fog=new THREE.Fog(0x1a1228,28,95);\r\n const terrain=buildTerrain(THREE,tier);terrain.group.name='supply-drop-ground';\r\n for(const effect of [terrain.mound,terrain.scorch]){\r\n  terrain.group.remove(effect);effect.geometry.dispose();effect.material.map?.dispose();effect.material.dispose();\r\n }\r\n group.add(terrain.group);\r\n const sky=new THREE.Group();sky.name='supply-drop-sky';\r\n const uniforms={uTime:{value:0},uDpr:{value:pixelRatio}};\r\n for(const layer of makeStars(THREE,uniforms))sky.add(layer.pts);\r\n const nebulaTexture=glowTexture(THREE,'255,255,255',[[0,.55],[.35,.28],[.7,.08],[1,0]]);\r\n for(const [x,y,z,size,color,opacity] of [[-22,26,-85,110,tier.color,.5],[30,48,-95,95,0x5a3cff,.38],[0,60,-80,120,0x2fd0c0,.18]]){\r\n  const sprite=new THREE.Sprite(new THREE.SpriteMaterial({map:nebulaTexture,color,transparent:true,opacity,depthWrite:false,blending:THREE.AdditiveBlending,fog:false}));\r\n  sprite.position.set(x,y,z);sprite.scale.set(size,size*.7,1);sprite.renderOrder=-2;sky.add(sprite);\r\n }\r\n const moon=new THREE.Sprite(new THREE.SpriteMaterial({map:glowTexture(THREE,'200,220,255',[[0,1],[.18,.95],[.22,.35],[.6,.08],[1,0]]),transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,fog:false}));\r\n moon.name='supply-drop-moon';moon.position.set(-30,34,-85);moon.scale.setScalar(30);sky.add(moon);\r\n group.add(sky);\r\n // Front/Back and drag rotations still look out into the same space landscape.\r\n const reverseSky=sky.clone();reverseSky.name='supply-drop-sky-back';reverseSky.rotation.y=Math.PI;group.add(reverseSky);\r\n let disposed=false;\r\n function dispose(){\r\n  if(disposed)return;disposed=true;group.removeFromParent();\r\n  // The reverse sky shares resources with the front. Sprite geometry belongs to\r\n  // Three itself, so collect only this landscape's Mesh/Points geometry.\r\n  const geometries=new Set(),materials=new Set(),textures=new Set([background]);\r\n  group.traverse(object=>{\r\n   if(object.isMesh||object.isPoints)geometries.add(object.geometry);\r\n   if(object.material)for(const material of Array.isArray(object.material)?object.material:[object.material])materials.add(material);\r\n  });\r\n  for(const material of materials){\r\n   for(const value of Object.values(material))if(value?.isTexture)textures.add(value);\r\n   for(const uniform of Object.values(material.uniforms??{})){\r\n    const values=Array.isArray(uniform.value)?uniform.value:[uniform.value];\r\n    for(const value of values)if(value?.isTexture)textures.add(value);\r\n   }\r\n  }\r\n  geometries.forEach(geometry=>geometry.dispose());\r\n  materials.forEach(material=>material.dispose());\r\n  textures.forEach(texture=>texture.dispose());\r\n  group.clear();\r\n }\r\n return {group,background,fog,dispose};\r\n}\r\n","coach-profile.mjs":"import {renderPersonalTracker,updateTrackerProgress} from './personal-tracker.mjs';\r\nimport {officeEncouragement} from './office-domain.mjs?v=office-short-v1';\r\nimport {EXERCISES,dailyTargets} from './onboarding-domain.mjs?v=quick-install-v1';\r\nimport {openLocalCoach} from './local-coach-runtime.mjs';\r\nimport {setupAllowed} from './install-context.mjs';\r\nimport {signInPath} from './auth-paths.mjs';\r\nimport {readIncomingCoach} from './pending-coach.mjs';\r\nimport {nextChallenge} from './workout-route.mjs';\r\nlet setupRequired=true,leaving=false,worldWasOpen=false;\nfunction showSetupGate(){setupRequired=true;if(leaving)return;if(document.querySelector('#coachWorldPanel[open]')){if(gate.open)gate.close();gate.style.visibility='hidden';return;}gate.style.visibility='';if(!gate.open)gate.showModal();}\nfunction hideSetupGate(){setupRequired=false;gate.close();gate.hidden=true;gate.style.display='none';gate.style.visibility='';}\r\nconst gate=document.createElement('dialog');gate.id='coachSetupGate';gate.setAttribute('aria-label','Coach activation');gate.addEventListener('cancel',e=>e.preventDefault());gate.style.cssText='position:fixed;inset:0;margin:0;width:100vw;height:100dvh;max-width:none;max-height:none;border:0;z-index:2147483646;background:#17111ef5;display:grid;place-content:center;padding:28px;color:#f5e4ba;font:18px/1.6 Arial;text-align:center';\r\ngate.innerHTML='<h1>Connecting…</h1><p></p><a href=\"/pose.html?reconnect=1\" style=\"color:#b8e9cf;display:block;padding:12px\">Reload Coach</a><a id=\"gateSignIn\" href=\"#\" style=\"display:none;color:#b8e9cf;padding:12px\">Sign in</a>';document.body.append(gate);showSetupGate();\r\n// World is independently usable without a workout plan. Preserve activation when it closes.\r\nfunction syncWorldGate(){\n const worldOpen=!!document.querySelector('#coachWorldPanel[open]');\n if(leaving||worldOpen===worldWasOpen)return;worldWasOpen=worldOpen;\n if(!setupRequired)return;\n if(worldOpen){if(gate.open)gate.close();gate.style.visibility='hidden';}\n else showSetupGate();\n}\nnew MutationObserver(syncWorldGate).observe(document.body,{subtree:true,attributes:true,attributeFilter:['open']});\n// React only to World transitions. Reopening a gate another lifecycle closed can\n// stall Chromium navigation while dialogs are being torn down.\nwindow.addEventListener('beforeunload',()=>{leaving=true;requestAnimationFrame(()=>{if(!document.hidden)leaving=false;});});\nwindow.addEventListener('pagehide',()=>{leaving=true;});\nwindow.addEventListener('pageshow',()=>{leaving=false;syncWorldGate();});\nlet applied='',restored=false,localPlan=null;\r\nwindow.coachPersonalCue=personalCue;\r\nwindow.addEventListener('myr5:account-progress',event=>updateTrackerProgress(event.detail));\r\nconst get=k=>{try{return localStorage.getItem(k);}catch{return null;}};\r\nfunction showIncomingCoach(){if(!readIncomingCoach())return;gate.querySelector('h1').textContent='Coach ready';gate.querySelector('p').textContent='Saved setup loaded.';gate.querySelector('a').textContent='Continue with my coach';gate.querySelector('a').href='/onboarding.html?from=install';}\r\nfunction installSteps(){const ua=navigator.userAgent,ios=/iPad|iPhone|iPod/.test(ua)||(navigator.platform==='MacIntel'&&navigator.maxTouchPoints>1),android=/Android/i.test(ua);return ios?'On iPhone: tap Share, then Add to Home Screen, then open the MYR5 icon.':android?'On Android: tap Install when Chrome offers it (or the ⋮ menu, then Install app), then open MYR5 from your home screen.':'On a computer: use the install icon beside the address bar (Chrome or Edge), then open MYR5 from your apps.';}\r\n// Not installed yet: say plainly what to do, per platform. Get started opens the install page, which shows the same steps instead of bouncing back here.\r\nfunction installCopy(signIn=false){gate.querySelector('h1').textContent='Install MYR5';gate.querySelector('p').textContent='Install MYR5, then open it from your home screen. '+installSteps()+(signIn?' Already have a coach? Sign in to reconnect it.':'');gate.querySelector('a').href='/install.html';}\r\nfunction beginSetup(){return setupAllowed()?'/onboarding.html?from=install':'/install.html';}\r\nexport function clearCoachAccount(){window.myr5AuthenticatedAccount=null;window.coachEntitlements=null;document.documentElement.dataset.publicState=localPlan?'unlocked':'locked';window.coachProgress=null;window.dispatchEvent(new Event('myr5:account-cleared'));window.coachPlan=localPlan;restored=false;applied='';if(localPlan){hideSetupGate();window.dispatchEvent(new Event('myr5:coach-plan'));return;}\r\n // No saved plan on this device: Coach cannot render without one, so the gate must keep blocking —\r\n // but it now says why and always offers a working Sign in (reconnect) alongside Get started (#10/#11).\r\n gate.hidden=false;gate.style.display='grid';showSetupGate();gate.querySelector('h1').textContent='Set up Coach';gate.querySelector('p').textContent='Sign in to reconnect your saved coach, or get started fresh — Coach needs a plan before it can open.';gate.querySelector('a').textContent='Get started';gate.querySelector('a').href=beginSetup();if(!setupAllowed())installCopy(true);const signIn=gate.querySelector('#gateSignIn');signIn.href=signInPath('/onboarding.html');signIn.style.display='';}\r\nexport async function applyLocalCoach(){\r\n let repository;try{repository=await openLocalCoach();const scope=repository.forOwner(repository.guestOwnerId),data=await scope.getIntake(),settings=await scope.getSettings();if(!data||!settings?.startDay)return null;const targets=dailyTargets(data.profile,settings.startDay),completedSets=(await scope.listWorkouts()).filter(row=>row.status==='completed').length;localPlan={data,startDay:settings.startDay,completedAt:null,revision:0,targets};window.coachPlan=localPlan;document.documentElement.dataset.publicState='unlocked';if(!localStorage.getItem('myr5-coach-owner')){for(const [key,value] of Object.entries(data.appearance||{})){if(!localStorage.getItem(key)){localStorage.setItem(key,JSON.stringify(value));window.dispatchEvent(new StorageEvent('storage',{key,newValue:JSON.stringify(value)}));}}}window.dispatchEvent(new Event('mominc-avatar-change'));hideSetupGate();let plate=document.getElementById('dailyCoachPlan');if(!plate){plate=document.createElement('section');plate.id='dailyCoachPlan';document.querySelector('.crew-footer').before(plate);}renderPersonalTracker(plate,data.profile,targets,EXERCISES,{completedSets});window.dispatchEvent(new Event('myr5:coach-plan'));return localPlan;}finally{repository?.close();}\r\n}\r\nexport function applyCoachAccount(account){\r\n window.coachEntitlements=account.entitlements;window.myr5AuthenticatedAccount=account;document.documentElement.dataset.publicState='unlocked';window.dispatchEvent(new CustomEvent('myr5:account-ready',{detail:account}));\r\n window.coachProgress=account.progress;\r\n const o=account.onboarding;\r\n // #11: signed in but setup isn't finished — say why it blocks (not just what to do next).\r\n if(!o){gate.hidden=false;gate.style.display='grid';showSetupGate();gate.querySelector('#gateSignIn').style.display='none';gate.querySelector('h1').textContent='Set up Coach';gate.querySelector('p').textContent='Coach needs your setup finished before it can open — choose games or quick setup.';gate.querySelector('a').href='/onboarding.html';gate.querySelector('a').textContent='Continue coach setup';gate.querySelector('a').href=beginSetup();if(setupAllowed())showIncomingCoach();else installCopy();return;}\r\n hideSetupGate();window.coachPlan=o;\r\n if(!restored){const owner=get('myr5-coach-owner'),baseline=get('myr5-synced-appearance'),keys=['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1','myr5-pod-power-v1','handborne-recipe-v4','mbs-dj-identity-v1'];const current=JSON.stringify(Object.fromEntries(keys.map(k=>[k,get(k)]).filter(([,v])=>v!=null)));const dirty=owner===account.user.id&&baseline&&baseline!==current;\r\n  if(!dirty){for(const key of keys){const v=account.profile[key];if(v!=null){localStorage.setItem(key,v);window.dispatchEvent(new StorageEvent('storage',{key,newValue:v}));}else if(owner&&owner!==account.user.id)localStorage.removeItem(key);}window.dispatchEvent(new Event('mominc-avatar-change'));localStorage.setItem('myr5-synced-appearance',JSON.stringify(Object.fromEntries(keys.map(k=>[k,get(k)]).filter(([,v])=>v!=null))));}localStorage.setItem('myr5-coach-owner',account.user.id);restored=true;\r\n }\r\n let plate=document.getElementById('dailyCoachPlan');if(!plate){plate=document.createElement('section');plate.id='dailyCoachPlan';document.querySelector('.crew-footer').before(plate);}\r\n const p=o.data.profile,t=o.targets;renderPersonalTracker(plate,p,t,EXERCISES,account.progress);\r\n let nutrition=document.getElementById('coachNutritionTargets');if(!nutrition){nutrition=document.createElement('p');nutrition.id='coachNutritionTargets';document.getElementById('mealForm').before(nutrition);}nutrition.textContent=t.proteinGrams?`Today: ${t.proteinGrams} g protein · ${t.waterOz} oz water`:'';\r\n const signature=o.revision+':'+t.date;if(applied!==signature){const first=!applied;applied=signature;const movement=document.getElementById('movement');if(first&&movement&&p.exercises.includes(p.exercises[0])){movement.value=nextChallenge(account.progress.exerciseRoute,p.exercises[0])?.mode||p.exercises[0];movement.dispatchEvent(new CustomEvent('change',{bubbles:true,detail:{automatic:true}}));}window.dispatchEvent(new Event('myr5:coach-plan'));const reminder=document.getElementById('reminderForm');if(first&&reminder){reminder.elements.time.value=p.trainingTime;reminder.elements.timezone.value=p.timezone;window.dispatchEvent(new CustomEvent('myr5:reminder-defaults',{detail:{tone:p.reminderTone,days:Number(p.reminderDays)}}));}}\r\n}\r\nexport function personalCue(text,key){const p=window.coachPlan?.data?.profile;if(!p)return text;if(p.guidance==='Quiet'&&['encouragement','time'].includes(key)&&!/^\\d/.test(text))return null;if(key!=='encouragement')return text;\r\n const lines={supportive:'You are making progress. One comfortable movement at a time.',direct:'Stay with the next movement. Keep control.',analytical:'Keep your movement consistent. Notice the control in each repetition.',playful:'One tiny quest at a time. You have this.',calm:'Breathe. Move at your own pace.',mom:'MOM Inc. has recorded your effort. Please proceed comfortably.'};\r\n const tips={'Controlled reps':'Move with control.','Gradual progression':'One small step today.','Technique first':'Make the next movement smooth.'};let result=(text.startsWith('Halfway')?'Halfway. ':'')+(officeEncouragement(window.coachPlan.data,window.coachPlan.targets.day)||lines[p.coach]);if(p.guidance==='Detailed')result+=' '+tips[p.trainingStyle];\r\n // Respect explicitly listed words/phrases the visitor does not want to hear.\r\n const blocked=window.coachPlan.data.answers?.djscratch?.q3||'';if(blocked.split(/[,;\\n]/).some(s=>s.trim().length>=3&&!/^none\\.?$/i.test(s.trim())&&result.toLowerCase().includes(s.trim().toLowerCase())))return null;return result;\r\n}\r\n","coach-voice-settings.mjs":"import {COACH_VOICE_VARIANTS,DEFAULT_COACH_VOICE} from './robot-audio.mjs';\r\n\r\nexport const COACH_VOICE_PREFERENCE='myr5-coach-voice-v1';\r\n\r\n// Standalone initializer so the app shell can mount this beside its existing\r\n// Test voice control without coupling preference UI to app.mjs.\r\nexport function mountCoachVoiceSettings({voice,settings=globalThis.document?.getElementById('settings'),testButton=globalThis.document?.getElementById('testVoice')}={}){\r\n if(!voice)throw new TypeError('A CoachVoice instance is required');\r\n if(!settings)return ()=>{};\r\n const group=[...settings.querySelectorAll('details.settings-group')].find(item=>item.querySelector('summary')?.textContent.trim().toLowerCase()==='voice');\r\n if(!group)return ()=>{};\r\n const row=group.querySelector('.voice-row')??group;\r\n let selected=DEFAULT_COACH_VOICE;\r\n try{const saved=globalThis.localStorage?.getItem(COACH_VOICE_PREFERENCE);if(COACH_VOICE_VARIANTS[saved])selected=saved;}catch{}\r\n voice.setVariant?.(selected);\r\n const wrap=document.createElement('label');wrap.className='coach-voice-choice';wrap.style.cssText='display:flex;flex:1 1 100%;flex-direction:column;gap:6px;font-size:11px;color:inherit';\r\n const label=document.createElement('span');label.textContent='Voice style';label.style.cssText='font-size:11px;color:inherit';\r\n const select=document.createElement('select');select.name='coachVoice';select.setAttribute('aria-label','Coach voice style');\r\n select.style.cssText='width:100%;font-size:12px;padding:9px';\r\n for(const [id,variant] of Object.entries(COACH_VOICE_VARIANTS)){\r\n  const option=document.createElement('option');option.value=id;option.textContent=variant.label;select.append(option);\r\n }\r\n select.value=selected;wrap.append(label,select);\r\n const hint=document.createElement('small');hint.className='coach-voice-note';hint.textContent='Choose a style, then tap Test voice.';hint.style.cssText='flex:1 1 100%;font-size:10px;color:inherit';\r\n row.append(wrap,hint);\r\n const change=()=>{\r\n  const next=COACH_VOICE_VARIANTS[select.value]?select.value:DEFAULT_COACH_VOICE;\r\n  voice.setVariant?.(next);\r\n  try{globalThis.localStorage?.setItem(COACH_VOICE_PREFERENCE,next);}catch{}\r\n };\r\n select.addEventListener('change',change);\r\n // Keep this explicit relationship visible to assistive technology. The app's\r\n // existing handler still owns the button action and chooses its test sentence.\r\n if(testButton)testButton.setAttribute('aria-describedby',hint.id||(hint.id='coach-voice-note'));\r\n return ()=>{select.removeEventListener('change',change);wrap.remove();hint.remove();};\r\n}\r\n","coach.mjs":"// Event-driven cues: no language model or microphone needed during exercise.\r\nimport {RobotAudio,COACH_VOICE_VARIANTS} from './robot-audio.mjs';\r\nimport {coachOnline} from './coach-net.mjs';\r\nfunction myr5VoiceState(state){if(typeof window!=='undefined')window.dispatchEvent(new CustomEvent('myr5:response',{detail:{state}}));}\r\nexport const INTRO = {\r\n squat:'Watch the squat. Start tall, lower, then return to your starting height. Keep your shoulders and hips in view. Feet can be outside the picture.',\r\n pushup:'Watch the push-up. Place your phone beside you so you can see it. Show one shoulder, elbow, hand and hip. Begin with your arm extended.',\r\n tree:'Watch tree pose. Raise one bent knee out to the side and find a comfortable balance. Show your hips and knees. I estimate the hold from your upper legs.',\r\n warrior:'Watch warrior two. Stretch your arms to either side and bend one knee in a wide stance. Keep your arms, hips and knees visible.',\r\n horse:'Watch horse stance. Take a comfortable wide stance and lower with your knees out. Keep your hips and knees visible. I estimate your hold.',\r\n boxing:'Watch air boxing. Raise your hands and move at your own pace. Keep your shoulders, elbows and hands visible. I time your round and estimate hand speed.',\r\n jogging:'Watch jogging in place. Alternate lifting your knees at your own pace. Keep both knees visible. Feet can be outside the picture.',\r\n jumping:'Watch the jump. Start standing still, then rise and return to your starting height. Keep shoulders and hips visible. I estimate jumps from body rise.'\r\n};\r\nexport class CueEvents {\r\n constructor(){this.reset();}\r\n reset(){this.previous=null;this.ready=false;this.lostAt=null;this.warned=false;this.marks=new Set();this.lastEncourage=0;this.nextSetup=null;}\r\n update(m,now){\r\n  const cues=[],p=this.previous;\r\n  const add=(text,key='guide')=>cues.push({text,key});\r\n  const ready=m.tracking&&(m.kind==='hold'?m.progress===1:['reps','jumps'].includes(m.kind)?m.calibrated:true);\r\n  if(m.complete){if(!p?.complete)add('Round complete. Well done.','complete');}\r\n  else {\r\n   if(ready&&!this.ready){add('Ready. Begin.','ready');this.ready=true;}\r\n   if(!this.ready){this.nextSetup??=now+6000;if(now>=this.nextSetup){add(m.message,'setup');this.nextSetup=now+8000;}}\r\n   if(this.ready&&!m.tracking){this.lostAt??=now;if(!this.warned&&now-this.lostAt>=2000){add(m.message,'tracking');this.warned=true;}}\r\n   else if(m.tracking){if(this.warned)add('I can see you again.','tracking');this.lostAt=null;this.warned=false;}\r\n   if(p&&m.count>p.count)add(String(m.count),'count');\r\n   if(m.kind==='hold'&&p){const milestone=Math.floor(m.hold/10)*10;if(m.remaining==null&&milestone>=10&&milestone>Math.floor(p.hold/10)*10)add(`${milestone} seconds.`, 'time');if(p.hold>1&&m.hold===0)add('Hold paused.','tracking');}\r\n   if(m.remaining!==null&&p?.remaining!==null&&p?.remaining!==undefined){\r\n    const crossed=[60,30,10,5,4,3,2,1].filter(n=>p.remaining>n&&m.remaining<=n&&!this.marks.has(n));\r\n    crossed.forEach(n=>this.marks.add(n));if(crossed.length){const n=crossed.at(-1);add(n>5?`${n} seconds left.`:String(n),'time');}\r\n   } else if(ready&&m.kind!=='hold'&&Math.floor(m.elapsed/30)>this.lastEncourage){this.lastEncourage=Math.floor(m.elapsed/30);add(`${this.lastEncourage*30} seconds. Keep your own pace.`, 'time');}\r\n  }\r\n  this.previous={...m};return cues;\r\n }\r\n}\r\nexport class CoachVoice {\r\n constructor(caption,onMode=()=>{}){this.caption=caption;this.onMode=onMode;this.enabled=true;this.queue=[];this.current=null;this.epoch=0;this.robot=new RobotAudio(onMode);this.available=!!(globalThis.AudioContext||globalThis.webkitAudioContext);}\r\n unlock(){return this.robot.unlock();}\r\n get variant(){return this.robot.variant;}\r\n setVariant(id){if(!COACH_VOICE_VARIANTS[id])return false;if(id!==this.variant&&(this.current||this.queue.length))this.cancel();this.robot.setVariant(id);return true;}\r\n setEnabled(enabled){this.enabled=enabled;if(!enabled)this.cancel();}\r\n cancel(){this.epoch++;clearTimeout(this.current?.timer);this.robot.stop();globalThis.speechSynthesis?.cancel();this.current?.resolve();this.current=null;this.queue.splice(0).forEach(item=>item.resolve());myr5VoiceState('idle');}\r\n say(text,{key='guide',interrupt=false}={}){\r\n  if(typeof window!=='undefined'&&window.coachPersonalCue){text=window.coachPersonalCue(text,key);if(text==null)return Promise.resolve();}\r\n  // Encouragement can follow a short count, but never queue behind instructions.\r\n  if(key==='encouragement'&&this.current&&this.current.key!=='count')return Promise.resolve();\r\n  if(interrupt||(key==='count'&&this.current?.key==='guide')||(key!=='encouragement'&&this.current?.key==='encouragement'))this.cancel();this.caption(text);\r\n  if(!this.enabled||!this.available)return Promise.resolve();\r\n  return new Promise(resolve=>{\r\n   // Do not build a backlog of old rep numbers or expired timer milestones.\r\n   const old=this.queue.findIndex(item=>item.key===key);if(old>=0)this.queue.splice(old,1)[0].resolve();\r\n   this.queue.push({text,key,resolve});this.pump();\r\n  });\r\n }\r\n pump(){\r\n  if(this.current||!this.queue.length)return;\r\n  const item=this.queue.shift(),epoch=this.epoch;this.current=item;\r\n  this.caption(item.text);myr5VoiceState('speaking');let finished=false;\r\n  const finish=()=>{clearTimeout(item.timer);if(finished||epoch!==this.epoch)return;finished=true;this.current=null;item.resolve();myr5VoiceState('idle');this.pump();};\r\n  const unavailable=()=>{if(epoch!==this.epoch)return;this.onMode(coachOnline()?'Voice unavailable · captions on':'Offline · captions on, voice returns when you reconnect');finish();};\r\n  item.timer=setTimeout(()=>{if(epoch===this.epoch){this.robot.stop();globalThis.speechSynthesis?.cancel();finish();}},Math.max(10000,5000+item.text.length*220));\r\n  if(this.robot.unlock())this.robot.play(item.text).then(played=>{if(epoch===this.epoch){if(played)finish();else unavailable();}},unavailable);\r\n  else unavailable();\r\n }\r\n}\r\n","coach3d-flag.mjs":"// Ian, 16 Oct: the 3D coach in camera workouts and the rest scene is on the back burner (\"throws off the vibes\").\r\n// Default: he only joins a workout once the exercise's aura reaches COACH_AURA_LEVEL (small, at the side, idle) and\r\n// leaves at rest or when the set ends. localStorage myr5Coach3d='1' forces the old always-on full coach (testing).\r\n// Until level 3 his assets are never loaded; the rest scene shows the 64-bit coach sprite instead.\r\nexport const COACH_AURA_LEVEL=3;\r\n// Aura-entrance placement (share of the screen): small, bottom-right, clear of the camera subject. Tune on a real phone.\r\nexport const COACH_AURA_PLACE={heightPct:.26,rightPct:.02,bottomPct:.2,enterMs:550,leaveMs:350};\r\nexport const COACH_3D_KEY='myr5Coach3d';\r\nexport function coach3dEnabled(){try{return localStorage.getItem(COACH_3D_KEY)==='1';}catch{return false;}}\r\n","combat-config.mjs":"// Rank 11b combat tuning. Every number the boss fight needs lives here so the\r\n// owner can retune it — including picking D20's 90s target over the shipped\r\n// 60s-per-rest default (3 x 60s = 180s) — by changing killTargetSeconds alone.\r\n// See plan/COMBAT-TUNING.md for the arithmetic this file produces.\r\nimport {dayAt} from './combat.mjs';\r\n\r\nexport const TAPS_PER_SECOND=2;          // D8/D20: assumed tap rate\r\nexport const KILL_TARGET_SECONDS=90;     // D20's target. Audit found the shipped rest default is 60s (user-selectable 30-120s), not the ~30s D20 assumed — owner has not picked yet. Set to REST_SECONDS*RESTS_PER_WORKOUT (180) to use the shipped default instead; the L5/L4 split below holds at either setting (see plan/COMBAT-TUNING.md).\r\nexport const REST_SECONDS=60;            // shipped default, pose.html #restDuration / pod/set-flow.mjs start()'s restSeconds=60 default (reports/audit-game.md \"Rest timer length between sets\")\r\nexport const RESTS_PER_WORKOUT=3;\r\n\r\n// Base tap damage by level (index = level-1). L1-L4 = level; L5 jumps to 8 (D33: L4 kit ~15% short of the L5 boss).\r\n// A linear level x N base can't reach D33: weapons+pet add the same to L4 and L5, so L4/L5 output never drops below\r\n// 4/5, and 4/5 x 1.1 (L5's 10% kill margin) leaves L4 at most 12% short even with no weapon, pet or special damage.\r\nexport const BASE_TAP_DAMAGE=[1,2,3,4,8];\r\nexport const WEAPON_1_LEVEL=1,WEAPON_1_BONUS=1; // D22: weapon 1 unlocks at L1\r\nexport const WEAPON_2_LEVEL=3,WEAPON_2_BONUS=2; // D22: weapon 2 unlocks at L3\r\nexport const PET_LEVEL=4,PET_DPS=5;             // D22: pet unlocks at L4 (aura at L5 is cosmetic only — D22/D7 — so it adds no combat stat)\r\nexport const SPECIAL_LEVEL=3;                   // D17: weapon specials unlock at L3; refused below it\r\n// The ONE special-damage knob: everything a day's specials deal together is capped at this share of\r\n// that level's boss max HP. With a special on every cooldown the L4 kit deals 19/s·T x (1 + 0.9 x 0.1) =\r\n// 20.71/s·T against the L5 boss's 0.9 x 27/s·T = 24.3/s·T: 14.8% short at any killTargetSeconds (D33).\r\n// Above ~0.139 the L4 shortfall drops under 12% (tests/combat-tuning.test.mjs).\r\nexport const SPECIAL_DAMAGE_FRACTION=0.1;\r\n\r\n// [minStreak,multiplier], highest matching breakpoint wins; below all of them the multiplier is 1.\r\nexport const STREAK_BREAKPOINTS=[[20,1.5],[10,1.25],[5,1.1]];\r\n\r\nexport const BOSS_HP_FACTOR=0.9;    // a level's boss HP = this fraction of that level's own kit output over KILL_TARGET_SECONDS — every level's own kit (taps only) clears it with 1/0.9 = 11.1% to spare, at any KILL_TARGET_SECONDS (plan/COMBAT-TUNING.md)\r\nexport const DAILY_CAP_FACTOR=5;    // daily cap = this many boss-kills worth of damage, so it never blocks the intended kill\r\n\r\nexport const BOSS_ATTACK_EVERY_HITS=6; // spectacle only (D7) — no gameplay listener consumes this\r\n\r\nexport function streakMultiplier(streak){\r\n const s=Number.isSafeInteger(streak)?streak:1;\r\n for(const [min,mult] of STREAK_BREAKPOINTS)if(s>=min)return mult;\r\n return 1;\r\n}\r\nexport function kitTapDamage(level){\r\n const l=Number.isSafeInteger(level)&&level>=1?level:1;\r\n return BASE_TAP_DAMAGE[Math.min(l,BASE_TAP_DAMAGE.length)-1]+(l>=WEAPON_1_LEVEL?WEAPON_1_BONUS:0)+(l>=WEAPON_2_LEVEL?WEAPON_2_BONUS:0);\r\n}\r\nexport function kitPetDps(level){\r\n const l=Number.isSafeInteger(level)&&level>=1?level:1;\r\n return l>=PET_LEVEL?PET_DPS:0;\r\n}\r\n// Per-tap damage for live play: kit strength x the streak curve. `combat` is\r\n// whatever shape combat.mjs's exported progress carries ({day,loginStreak,...})\r\n// — read here, never recomputed (combat.mjs owns loginStreak()).\r\nexport function tapDamage(level,combat,now=Date.now()){\r\n const fresh=combat?.day===dayAt(now)&&Number.isSafeInteger(combat.loginStreak)&&combat.loginStreak>=1;\r\n return kitTapDamage(level)*streakMultiplier(fresh?combat.loginStreak:1);\r\n}\r\n// Total damage a level's own kit can land in `seconds` of tapping, at streak 1\r\n// (the guaranteed floor with no login-streak bonus — a real streak only helps).\r\nexport function maxKitDamage(level,seconds=KILL_TARGET_SECONDS){\r\n return kitTapDamage(level)*TAPS_PER_SECOND*seconds+kitPetDps(level)*seconds;\r\n}\r\nexport function bossHp(level,seconds=KILL_TARGET_SECONDS){\r\n return Math.round(BOSS_HP_FACTOR*maxKitDamage(level,seconds));\r\n}\r\nexport function dailyCap(level,seconds=KILL_TARGET_SECONDS){\r\n return Math.round(DAILY_CAP_FACTOR*maxKitDamage(level,seconds));\r\n}\r\n// Total special damage allowed per boss (per day) at this level; whole numbers so the UI never shows float noise.\r\nexport function specialBudget(level,seconds=KILL_TARGET_SECONDS){\r\n return Math.floor(SPECIAL_DAMAGE_FRACTION*bossHp(level,seconds));\r\n}\r\n// D32 Food bonus: each Food level grants a bonus (battle-pass-rewards.mjs FOOD_BONUS) worth this\r\n// damage multiplier for one day. DEFAULT — the owner can change it.\r\nexport const FOOD_BONUS_DAMAGE_MULTIPLIER=1.1;\r\n","combat.mjs":"import {evaluateStreakHistory} from './streak-forgiveness.mjs';\r\nexport const DAY_MS=86400000;\r\nexport const BREATHING_MS=180000;\r\nexport const dayAt=now=>Math.floor(now/DAY_MS);\r\nexport function loginStreak(days,today){return evaluateStreakHistory(days,today).at(-1)?.streak??0;}\r\nexport function weaponDamage(combat,weapon,now=Date.now()){\r\n const current=combat?.day===dayAt(now)&&Number.isSafeInteger(combat.loginStreak)&&combat.loginStreak>=1;\r\n const level=Number.isInteger(weapon?.tier)&&weapon.tier>=0&&weapon.tier<=20?weapon.tier+1:1;\r\n return 10*(current?combat.loginStreak:1)*level*(current&&combat.breathingCompleted===true?100:1);\r\n}\r\nexport class BreathingSession{\r\n constructor(durationMs=BREATHING_MS){this.durationMs=Math.max(BREATHING_MS,Math.min(2*60*60*1000,Number(durationMs)||BREATHING_MS));this.elapsed=0;this.last=null;this.active=false;}\r\n sample(now,active){if(this.last!==null&&this.active&&active)this.elapsed=Math.min(this.durationMs,this.elapsed+Math.max(0,Math.min(1500,now-this.last)));this.last=now;this.active=active;return this.elapsed;}\r\n get complete(){return this.elapsed>=this.durationMs;}\r\n}\r\n","cosmetic-reward-reveal.mjs":"import {performanceOwner} from './performance-progress.mjs';\r\nimport {isGranted} from './creature/source/creator/unlock-store.ts';\r\n\r\nconst CSS=`\r\n.cosmetic-reward-reveal{box-sizing:border-box;width:min(380px,calc(100vw - 28px));max-height:calc(100dvh - 28px);padding:20px;margin:auto;overflow:auto;border:2px solid var(--reward-color,#4bafff);border-radius:20px;background:#17131f;color:#fff7df;font:500 16px/1.4 system-ui;text-align:center}\r\n.cosmetic-reward-reveal::backdrop{background:#090717d9}.cosmetic-reward-reveal h2{margin:0;font-size:22px}.cosmetic-reward-reveal p{margin:8px 0}.cosmetic-reward-reveal .reward-name{color:var(--reward-color);font-weight:800;overflow-wrap:anywhere}\r\n.original-coach-reward-stage{width:100%;height:clamp(140px,30dvh,260px);position:relative}.original-coach-reward-stage canvas{display:block;width:100%;height:100%}\r\n.cosmetic-reward-reveal .reward-actions{display:flex;gap:10px;justify-content:center;margin-top:14px}.cosmetic-reward-reveal button{min-width:80px;min-height:44px;padding:8px 16px;border:2px solid var(--reward-color);border-radius:12px;background:var(--reward-color);color:#15101c;font:800 15px system-ui;cursor:pointer}.cosmetic-reward-reveal button.secondary{background:transparent;color:#fff7df}.cosmetic-reward-reveal button:focus-visible{outline:3px solid white;outline-offset:3px}.cosmetic-reward-reveal [hidden]{display:none}\r\n`;\r\n\r\nexport function mountCosmeticRewardReveal(){\r\n let queue=[],card=null,preview=null,timer=0,epoch=0,disposed=false,owner=performanceOwner(),current=null;\r\n const style=document.createElement('style');style.textContent=CSS;document.head.append(style);\r\n const viewerUrl='/creature/assets/reward-preview.js';\r\n const clean=()=>{++epoch;preview?.dispose();preview=null;card?.close();card?.remove();card=null;current=null;};\r\n const clear=()=>{clearTimeout(timer);queue=[];clean();owner=performanceOwner();};\r\n async function loadPreview(stage,status,retry,item){\r\n  const run=++epoch,expectedOwner=owner;preview?.dispose();preview=null;stage.replaceChildren();delete stage.dataset.ready;status.textContent='Loading original MYR5 coach…';retry.hidden=true;\r\n  try{\r\n   const module=await import(viewerUrl);\r\n   if(disposed||run!==epoch||expectedOwner!==performanceOwner()||!card?.open)return;\r\n   const instance=module.mountOriginalRewardPreview(stage,item);preview=instance;\r\n   const loaded=await instance.ready;\r\n   if(disposed||run!==epoch||expectedOwner!==performanceOwner())return;\r\n   if(!loaded)throw Error('Preview unavailable');\r\n   card.querySelector('.reward-name').textContent=module.cosmeticRewardName(item.kind,item.id);\r\n   status.textContent='Also unlocked for original MYR5.';\r\n  }catch{\r\n   if(disposed||run!==epoch||expectedOwner!==performanceOwner())return;\r\n   preview?.dispose();preview=null;status.textContent='Reward saved. Download the Coach pack to see it on original MYR5 offline, or retry online.';retry.hidden=false;\r\n  }\r\n }\r\n function showNext(){\r\n  clearTimeout(timer);if(disposed||card||!queue.length)return;\r\n  if(owner!==performanceOwner()){clear();return;}\r\n  // Rewards never interrupt an active workout or another native dialog.\r\n  if(document.hidden||document.querySelector('dialog[open]')||document.body.dataset.tracking==='true'||document.body.dataset.cameraWorkout==='true'){timer=setTimeout(showNext,400);return;}\r\n  const item=queue.shift();if(!isGranted(item.kind,item.id,'myr5')){showNext();return;}\r\n  current=item;card=document.createElement('dialog');card.className='cosmetic-reward-reveal';card.setAttribute('aria-label','Cosmetic unlocked on original MYR5');card.style.setProperty('--reward-color',item.kind==='texture'?'#ff9c36':item.kind==='palette'?'#4bafff':'#76e356');\r\n  card.innerHTML='<h2>Original MYR5 unlocked</h2><p class=\"reward-name\"></p><div class=\"original-coach-reward-stage\"></div><p data-status role=\"status\" aria-live=\"polite\"></p><div class=\"reward-actions\"><button type=\"button\" class=\"secondary\" data-retry hidden>Retry preview</button><button type=\"button\" class=\"secondary\" data-close>Close</button><button type=\"button\" data-next></button></div>';\r\n  const next=card.querySelector('[data-next]'),retry=card.querySelector('[data-retry]'),status=card.querySelector('[data-status]'),stage=card.querySelector('.original-coach-reward-stage');card.querySelector('.reward-name').textContent=item.id;next.textContent=queue.length?'Next reward':'Done';\r\n  next.onclick=()=>{clean();showNext();};card.querySelector('[data-close]').onclick=clear;card.addEventListener('cancel',event=>{event.preventDefault();clear();});retry.onclick=()=>loadPreview(stage,status,retry,item);\r\n  document.body.append(card);card.showModal();next.focus();void loadPreview(stage,status,retry,item);\r\n }\r\n const onGrant=event=>{\r\n  if(disposed||event.detail?.owner!==performanceOwner()||!Array.isArray(event.detail?.granted))return;\r\n  if(owner!==performanceOwner())clear();\r\n  const batch=new Set();for(const item of event.detail.granted){if(!['color','palette','texture'].includes(item?.kind)||typeof item.id!=='string'||!isGranted(item.kind,item.id,'myr5'))continue;const key=item.kind+':'+item.id;if(batch.has(key))continue;batch.add(key);queue.push({kind:item.kind,id:item.id});}\r\n  if(card&&current)card.querySelector('[data-next]').textContent=queue.length?'Next reward':'Done';showNext();\r\n };\r\n const accountChanged=()=>{if(owner!==performanceOwner())clear();};\r\n const dispose=()=>{if(disposed)return;disposed=true;clear();style.remove();window.removeEventListener('myr5:cosmetics-unlocked',onGrant);window.removeEventListener('myr5:account-ready',accountChanged);window.removeEventListener('myr5:account-cleared',clear);window.removeEventListener('pagehide',dispose);};\r\n window.addEventListener('myr5:cosmetics-unlocked',onGrant);window.addEventListener('myr5:account-ready',accountChanged);window.addEventListener('myr5:account-cleared',clear);window.addEventListener('pagehide',dispose);\r\n return dispose;\r\n}\r\n","creature-skin-reward-reveal.mjs":"const COLLECTIONS=Object.freeze({\r\n 'creature-forged-realms':'Forged Realms',\r\n 'creature-celestial-rift':'Celestial Rift',\r\n});\r\nconst OWNER=/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/;\r\nconst STYLE_ID='creatureSkinRewardRevealStyle';\r\nconst CSS=`\r\n.creature-skin-reward{position:fixed;z-index:10020;top:calc(env(safe-area-inset-top,0px) + 14px);right:14px;width:min(360px,calc(100vw - 28px));padding:18px 18px 14px;border:1px solid #e5c778;border-radius:16px;background:linear-gradient(145deg,#2e2037f5,#17131cf7);box-shadow:0 16px 48px #0008;color:#fff8e9;font:500 15px/1.45 system-ui,sans-serif;pointer-events:auto;animation:skin-reward-in .34s cubic-bezier(.16,1,.3,1) both}\r\n.creature-skin-reward h2{margin:0 28px 8px 0;color:#ffe39a;font:700 18px/1.2 Georgia,serif}\r\n.creature-skin-reward ul{margin:8px 0 14px;padding-left:20px}.creature-skin-reward li+li{margin-top:5px}\r\n.creature-skin-reward .skin-reward-collection{display:block;color:#d9c9ef;font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;margin-top:10px}\r\n.creature-skin-reward button{border:1px solid #d8c9a1;border-radius:999px;background:#f2dfb0;color:#241b2b;padding:7px 14px;font:700 13px system-ui,sans-serif;cursor:pointer}\r\n.creature-skin-reward button:focus-visible{outline:3px solid #fff;outline-offset:3px}\r\n@keyframes skin-reward-in{from{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:translateY(0) scale(1)}}\r\n@media(prefers-reduced-motion:reduce){.creature-skin-reward{animation:none}}\r\n`;\r\nconst ownerOf=account=>{const id=account?.user?.id;return typeof id==='string'&&OWNER.test(id)?id:null;};\r\n\r\n/** A small, non-blocking notice for newly granted post-download creature skins. */\r\nexport function mountCreatureSkinRewardReveal(){\r\n const initial=window.myr5AuthenticatedAccount;\r\n let disposed=false,activeOwner=Number.isSafeInteger(initial?.dataEpoch)&&initial.dataEpoch>0?ownerOf(initial):null,activeEpoch=activeOwner?initial.dataEpoch:null;\r\n let style=null,card=null;const queue=[],seen=new Set();\r\n function clear(){queue.length=0;seen.clear();card?.remove();card=null;style?.remove();style=null;}\r\n function ensureStyle(){if(style?.isConnected)return;style=document.getElementById(STYLE_ID)||document.createElement('style');style.id=STYLE_ID;style.textContent=CSS;if(!style.isConnected)document.head.append(style);}\r\n function showNext(){\r\n  if(disposed||card||!queue.length)return;\r\n  const groups=queue.shift();ensureStyle();const next=document.createElement('aside');next.className='creature-skin-reward';next.setAttribute('role','status');next.setAttribute('aria-live','polite');next.setAttribute('aria-atomic','true');\r\n  const title=document.createElement('h2');title.textContent='New creature skin';next.append(title);\r\n  for(const [collection,names] of groups){const label=document.createElement('span');label.className='skin-reward-collection';label.textContent=collection;next.append(label);const list=document.createElement('ul');for(const name of names){const item=document.createElement('li');item.textContent=name;list.append(item);}next.append(list);}\r\n  const dismiss=document.createElement('button');dismiss.type='button';dismiss.textContent='Dismiss';dismiss.setAttribute('aria-label','Dismiss creature skin reward');dismiss.addEventListener('click',()=>{next.remove();card=null;showNext();});next.append(dismiss);document.body.append(next);card=next;\r\n }\r\n function onReward(event){\r\n  if(disposed||!activeOwner||activeEpoch===null||ownerOf(window.myr5AuthenticatedAccount)!==activeOwner||window.myr5AuthenticatedAccount?.dataEpoch!==activeEpoch)return;\r\n  const granted=Array.isArray(event.detail?.granted)?event.detail.granted:[],groups=new Map();\r\n  for(const reward of granted){\r\n   if(reward?.kind!=='creature-skin'||typeof reward.id!=='string'||!/^creature-[a-z0-9-]{1,80}$/.test(reward.id)||seen.has(reward.id))continue;\r\n   const collection=COLLECTIONS[reward.collection];if(!collection)continue;\r\n   const name=typeof reward.name==='string'&&reward.name.trim()?reward.name.trim().slice(0,100):reward.id;\r\n   seen.add(reward.id);if(!groups.has(collection))groups.set(collection,[]);groups.get(collection).push(name);\r\n  }\r\n  if(groups.size){queue.push(groups);showNext();}\r\n }\r\n function onAccountReady(event){\r\n  const next=event.detail,epoch=Number.isSafeInteger(next?.dataEpoch)&&next.dataEpoch>0?next.dataEpoch:null,id=epoch?ownerOf(next):null;\r\n  if(id!==activeOwner||epoch!==activeEpoch){clear();activeOwner=id;activeEpoch=epoch;}\r\n }\r\n function onAccountCleared(){clear();activeOwner=null;activeEpoch=null;}\r\n function dispose(){if(disposed)return;disposed=true;clear();window.removeEventListener('myr5:battle-pass',onReward);window.removeEventListener('myr5:account-ready',onAccountReady);window.removeEventListener('myr5:account-cleared',onAccountCleared);window.removeEventListener('pagehide',dispose);}\r\n window.addEventListener('myr5:battle-pass',onReward);window.addEventListener('myr5:account-ready',onAccountReady);window.addEventListener('myr5:account-cleared',onAccountCleared);window.addEventListener('pagehide',dispose,{once:true});\r\n return {dispose};\r\n}\r\n","creature/cinematics.css":".coach-film{position:fixed;inset:0;z-index:990;isolation:isolate;overflow:hidden;color:#fff5e5;background:linear-gradient(#090510ed,transparent 24%,transparent 56%,#090510f2 90%);pointer-events:none;font-family:system-ui,sans-serif}\r\n.coach-film[hidden]{display:none!important}\r\n.film-doors{display:none}\r\n.film-top{position:absolute;top:0;left:0;right:0;display:flex;justify-content:space-between;align-items:center;gap:12px;padding:calc(20px + env(safe-area-inset-top)) max(20px,env(safe-area-inset-right)) 15px max(20px,env(safe-area-inset-left));border-top:3px solid #edcc91}\r\n.film-label{font:500 12px ui-monospace,monospace;letter-spacing:2px;color:#d4bddf}.film-skip{pointer-events:auto;background:#1c112bec!important;border:1px solid #ab879b!important;border-radius:4px!important;min-height:44px;font-size:14px;color:#fff1d8}\r\n.film-copy{position:absolute;bottom:0;left:0;right:0;max-width:960px;margin:auto;padding:30px 24px calc(32px + env(safe-area-inset-bottom));text-align:center}.film-title{font-size:clamp(28px,6vw,62px);font-weight:600;letter-spacing:-1.5px;line-height:1.05;margin:14px auto;max-width:760px;text-wrap:balance}.film-beat{font:500 12px ui-monospace,monospace;letter-spacing:3px;color:#edcc91;margin:0}.film-detail{font-size:16px;color:#cfb7df;line-height:1.5;min-height:24px;margin:14px auto 24px;max-width:560px}.film-progress{height:2px;background:#b6a0c323;width:min(280px,70vw);margin:auto;overflow:hidden}.film-progress i{display:block;transform:scaleX(0);transform-origin:left;height:100%;background:#f1d7a0;box-shadow:0 0 12px #edcc91}\r\n.film-scan{position:absolute;inset:12% 0 23%;background:linear-gradient(180deg,transparent 40%,#c39ff711 49.5%,#e1c9ff44 50%,transparent 50.5%);animation:film-scan 4.8s ease-in-out both;opacity:.6}.film-scan:after{content:'';position:absolute;inset:0;background:radial-gradient(ellipse at center,transparent 25%,#080411 90%)}\r\nbody[data-cinematic]{overflow:hidden}\r\nbody[data-cinematic=pre] .containment-pod,body[data-cinematic=post] .encounter{position:fixed!important;inset:0!important;width:100vw!important;height:100dvh!important;min-height:0!important;max-height:none!important;margin:0!important;border:0!important;border-radius:0!important;z-index:980!important;background:radial-gradient(ellipse at 50% 44%,#623286 0%,#20122d 38%,#080410 78%)!important;box-shadow:none!important}\r\nbody[data-cinematic=pre] .coach-mount,body[data-cinematic=post] .rest-coach-mount{inset:7% 0 17%!important;top:7%!important;left:0!important;width:100%!important;height:76%!important;filter:drop-shadow(0 0 32px #9b67c333)!important;z-index:3!important}\r\nbody[data-cinematic=pre] .containment-pod:before,body[data-cinematic=pre] .pod-rim,body[data-cinematic=pre] .pod-nameplate,body[data-cinematic=pre] .pod-inscription,body[data-cinematic=pre] .camera-preview{display:none!important}\r\nbody[data-cinematic=post] .encounter>:not(.rest-coach-mount){visibility:hidden!important}\r\n.coach-film[data-scene=opening]{background:none;pointer-events:auto}\r\n.coach-film[data-scene=opening] .film-doors{display:block;position:absolute;inset:0;z-index:-1}\r\n.film-door{position:absolute;top:0;bottom:0;width:50%;overflow:hidden;box-sizing:border-box;background:linear-gradient(110deg,#342442 0%,#1f142c 38%,#130c1d 76%,#291b35 100%);will-change:transform}\r\n.film-door:before{content:'';position:absolute;inset:18px 20px;border:1px solid #79578255;box-shadow:inset 0 0 0 7px #0b071433,inset 0 0 70px #08041144;border-radius:6px}\r\n.film-door:after{content:'';position:absolute;top:0;bottom:0;width:2px;background:linear-gradient(#ad7fbe33,#f9d296 25%,#f9d296 75%,#ad7fbe33);box-shadow:0 0 18px #efb96166}\r\n.film-door-left{left:0;box-shadow:inset -12px 0 18px #09050f,inset -14px 0 0 #73508055;animation:film-door-left 4.8s cubic-bezier(.66,0,.2,1) both}\r\n.film-door-right{right:0;background:linear-gradient(250deg,#342442 0%,#1f142c 38%,#130c1d 76%,#291b35 100%);box-shadow:inset 12px 0 18px #09050f,inset 14px 0 0 #73508055;animation:film-door-right 4.8s cubic-bezier(.66,0,.2,1) both}\r\n.film-door-left:after{right:0}.film-door-right:after{left:0}\r\n.film-door-brand{position:absolute;top:37%;width:clamp(112px,25dvh,220px);aspect-ratio:1;transform:translate(-50%,-50%);padding:18px;box-sizing:content-box;background:radial-gradient(ellipse at 50% 25%,#fff8e8,#e7d7b9);border:1px solid #f6dcb0;border-radius:10px;box-shadow:0 0 0 8px #140c21,0 0 0 9px #87649388,0 12px 55px #03010699}\r\n.film-door-left .film-door-brand{left:100%}.film-door-right .film-door-brand{left:0}\r\n.film-door-brand img{display:block;width:100%;height:100%;object-fit:contain}\r\n.coach-film[data-scene=opening] .film-scan{display:none}\r\n.coach-film[data-scene=opening] .film-top{border:0;z-index:2}.coach-film[data-scene=opening] .film-label{animation:film-door-copy 4.8s ease both}\r\n.coach-film[data-scene=opening] .film-copy{top:58%;bottom:auto;padding-top:0;animation:film-door-copy 4.8s ease both}\r\n.coach-film[data-scene=opening] .film-title{font-size:clamp(28px,5vw,54px);max-width:660px}.coach-film[data-scene=opening] .film-detail{letter-spacing:2px;font-size:14px}\r\n.cinematic-settings{display:flex;gap:8px;margin-top:20px;flex-wrap:wrap}.cinematic-settings button{font-size:14px;flex:1}\r\n@keyframes film-door-left{0%,70%{transform:translateX(0)}100%{transform:translateX(-101%)}}\r\n@keyframes film-door-right{0%,70%{transform:translateX(0)}100%{transform:translateX(101%)}}\r\n@keyframes film-door-copy{0%,68%{opacity:1;transform:translateY(0)}78%,100%{opacity:0;transform:translateY(-8px)}}\r\n@keyframes film-scan{from{transform:translateY(-70%)}to{transform:translateY(70%)}}\r\n@media(max-height:550px) and (orientation:landscape){.film-title{font-size:30px}.film-copy{padding-bottom:12px}.film-detail{margin:7px auto}.film-top{padding-top:12px}.film-copy{max-width:700px}.film-label{font-size:12px}}\r\n@media(max-height:550px){.film-door-brand{top:35%;width:clamp(72px,24dvh,112px);padding:10px}.coach-film[data-scene=opening] .film-copy{top:57%;padding-bottom:8px}.coach-film[data-scene=opening] .film-title{font-size:clamp(24px,4vw,30px);margin:8px auto}.coach-film[data-scene=opening] .film-detail{margin:8px auto 12px}}\r\n@media(prefers-reduced-motion:reduce){.coach-film{display:none!important}body[data-cinematic] .myr5-companion-stage{animation:none!important}}\r\n","creature/cinematics.js":"// Full-app opening doors, followed by scenes using the live customized coach. Release 6: no pod \"home\" title film any\r\n// more (\"Your coach. Your next move.\"); the oval's ship intro is the coach's arrival.\r\nconst OPENING_SEEN='myr5-opening-doors-seen-v2';\r\nconst SCENES={\r\n opening:{duration:4800,label:'MOM INC. / POD 005',title:'Something big is waking up.',beats:['CONTAINMENT ONLINE','COACH AWAKENING','MYR5 IS READY']},\r\n pre:{duration:3300,label:'MOVEMENT SELECTED',title:'Let’s make it count.',beats:['FIND YOUR SPACE','FIND YOUR FOCUS','LET’S GO']},\r\n post:{duration:3800,label:'SET COMPLETE',title:'You showed up.',beats:['EFFORT RECORDED','TAKE A BREATH','MEET YOUR GIANT']}\r\n};\r\nexport function initCinematics({voice}={}){\r\n const body=document.body,reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n const read=(store,key)=>{try{return store.getItem(key);}catch{return null;}};\r\n const lowMotion=()=>{try{return reduced.matches||JSON.parse(read(localStorage,'myr5-motion-v1')||'{}')?.reduced===true;}catch{return reduced.matches;}};\r\n let enabled=read(localStorage,'myr5-cinematics-v1')!=='off',active=null,frame=0,lastScreen=body.dataset.screen,disposed=false;\r\n if(!document.getElementById('coach-cinematics-style')){const sheet=document.createElement('link');sheet.rel='stylesheet';sheet.href='/creature/cinematics.css';document.head.append(sheet);}\r\n const layer=document.createElement('section');layer.className='coach-film';layer.hidden=true;\r\n layer.setAttribute('aria-label','Coach cinematic');layer.innerHTML='<div class=\"film-doors\" aria-hidden=\"true\"><div class=\"film-door film-door-left\"><div class=\"film-door-brand\"><img alt=\"\"></div></div><div class=\"film-door film-door-right\"><div class=\"film-door-brand\"><img alt=\"\"></div></div></div><div class=\"film-top\"><span class=\"film-label\"></span><button type=\"button\" class=\"film-skip\">Skip intro →</button></div><div class=\"film-scan\" aria-hidden=\"true\"></div><div class=\"film-copy\"><p class=\"film-beat\"></p><h1 class=\"film-title\"></h1><p class=\"film-detail\"></p><div class=\"film-progress\" aria-hidden=\"true\"><i></i></div></div>';\r\n for(const side of ['left','right'])layer.querySelector(`.film-door-${side} img`).src=new URL('../pod/mom-inc-mark.png',import.meta.url).href;\r\n body.append(layer);\r\n const label=layer.querySelector('.film-label'),title=layer.querySelector('.film-title'),beat=layer.querySelector('.film-beat'),detail=layer.querySelector('.film-detail'),progress=layer.querySelector('.film-progress i'),skip=layer.querySelector('button');\r\n const inertNodes=[];\r\n function finish(outcome='complete'){\r\n  if(!active)return;const run=active;active=null;cancelAnimationFrame(frame);\r\n  delete body.dataset.cinematic;layer.hidden=true;if(run.kind!=='opening'){try{window.myr5Creature?.cinematic(null);}catch{}}\r\n  for(const [node,was] of inertNodes.splice(0))node.inert=was;\r\n  if(run.focus?.isConnected&&!run.focus.closest('[hidden]'))run.focus.focus({preventScroll:true});\r\n  if(run.kind==='opening'&&outcome!=='cancelled'){try{sessionStorage.setItem(OPENING_SEEN,'yes');}catch{}}\r\n  window.dispatchEvent(new CustomEvent('myr5:cinematic-end',{detail:{kind:run.kind,outcome}}));\r\n  run.resolve(outcome);\r\n }\r\n function play(kind,info={}){\r\n  if(!Object.hasOwn(SCENES,kind)||disposed)return Promise.resolve('cancelled');\r\n  finish('cancelled');\r\n  if(!enabled||lowMotion()||document.hidden)return Promise.resolve(document.hidden?'cancelled':'skipped');\r\n  const scene=SCENES[kind];\r\n  voice?.cancel();\r\n  body.dataset.cinematic=kind;layer.dataset.scene=kind;layer.hidden=false;\r\n  label.textContent=scene.label;title.textContent=scene.title;\r\n  detail.textContent=kind==='pre'?(info.name||'Your next movement'):kind==='post'?(document.getElementById('setReceipt')?.textContent||'Your effort counts.'):kind==='opening'?'MAKING YOU READY.':'';\r\n  beat.textContent=scene.beats[0];progress.style.transform='scaleX(0)';\r\n  skip.textContent=kind==='pre'?'Start now →':kind==='post'?'Continue →':'Skip intro →';\r\n  layer.setAttribute('role','dialog');layer.setAttribute('aria-modal','true');\r\n  const focus=document.activeElement;\r\n  // Keep the existing canvas mounted, while keyboard focus stays in the scene.\r\n  for(const node of body.children)if(node!==layer&&!['SCRIPT','LINK','STYLE'].includes(node.tagName)){inertNodes.push([node,node.inert]);node.inert=true;}\r\n  skip.focus({preventScroll:true});\r\n  return new Promise(resolve=>{\r\n   active={kind,resolve,focus,start:performance.now(),elapsed:0};\r\n   const tick=now=>{\r\n    if(!active||active.kind!==kind)return;const elapsed=now-active.start;active.elapsed=elapsed;\r\n    if(kind!=='opening'){try{window.myr5Creature?.cinematic(kind,elapsed);}catch{finish('skipped');return;}}\r\n    const index=Math.min(scene.beats.length-1,Math.floor(elapsed/scene.duration*scene.beats.length));\r\n    if(beat.textContent!==scene.beats[index])beat.textContent=scene.beats[index];\r\n    progress.style.transform=`scaleX(${Math.min(1,elapsed/scene.duration)})`;\r\n    if(elapsed>=scene.duration)finish();else frame=requestAnimationFrame(tick);\r\n   };frame=requestAnimationFrame(tick);\r\n  });\r\n }\r\n skip.addEventListener('click',()=>finish('skipped'));\r\n const keyboard=event=>{if(!active)return;if(event.key==='Escape'){event.preventDefault();event.stopImmediatePropagation();finish('skipped');}else if(event.key==='Tab'){event.preventDefault();skip.focus();}};\r\n document.addEventListener('keydown',keyboard,true);\r\n const visibility=()=>{if(document.hidden)finish('cancelled');};document.addEventListener('visibilitychange',visibility);\r\n const motionChange=()=>{if(reduced.matches)finish('skipped');};reduced.addEventListener('change',motionChange);\r\n const settings=document.getElementById('settings');\r\n if(settings){\r\n  const group=document.createElement('div');group.className='cinematic-settings';\r\n  const toggle=document.createElement('button');toggle.type='button';\r\n  const paint=()=>{toggle.textContent=enabled?'Cinematics on':'Cinematics off';toggle.setAttribute('aria-pressed',String(enabled));};paint();\r\n  toggle.addEventListener('click',()=>{enabled=!enabled;try{localStorage.setItem('myr5-cinematics-v1',enabled?'on':'off');}catch{}paint();if(!enabled)finish('skipped');});\r\n  const replay=document.createElement('button');replay.type='button';replay.textContent='Replay opening';\r\n  replay.addEventListener('click',async()=>{settings.close();if(!enabled){enabled=true;paint();try{localStorage.setItem('myr5-cinematics-v1','on');}catch{}}await play('opening');});\r\n  group.append(toggle,replay);settings.append(group);\r\n }\r\n const observer=new MutationObserver(()=>{const screen=body.dataset.screen;if(screen===lastScreen)return;lastScreen=screen;if(active&&((active.kind==='post'&&screen!=='rest')||(active.kind!=='post'&&screen!=='pod')))finish('cancelled');});\r\n observer.observe(body,{attributes:true,attributeFilter:['data-screen']});\r\n // Doors cover the whole app while the coach loads beneath them.\r\n const bootTimer=setTimeout(async()=>{\r\n  if(disposed||document.hidden||body.dataset.screen!=='pod'||document.querySelector('dialog[open]')||body.dataset.tracking==='true'||active)return;\r\n  if(read(sessionStorage,OPENING_SEEN)!=='yes')await play('opening');\r\n },150);\r\n const interaction=()=>clearTimeout(bootTimer);\r\n for(const id of ['start','openLibrary','openSettings','openBreathing','visitRest','openIdentity','openAccomplishments'])document.getElementById(id)?.addEventListener('click',interaction,{capture:true});\r\n window.addEventListener('pagehide',()=>{disposed=true;clearTimeout(bootTimer);finish('cancelled');observer.disconnect();document.removeEventListener('keydown',keyboard,true);document.removeEventListener('visibilitychange',visibility);reduced.removeEventListener('change',motionChange);},{once:true});\r\n return {play,cancel:()=>finish('cancelled'),stats:()=>({active:active?.kind||null,enabled,reduced:lowMotion()})};\r\n}\r\n","creature/creature.css":":root{color-scheme:dark;--background:#141019;--foreground:#f4ebfa;--gold:#edc986;--muted:#c1accd;--border:#6a516f;--primary:#edc986;--primary-foreground:#241b2b;--card:#302537;--popover:#302537;--accent:#624773;--accent-foreground:#fff3dd;--ring:#f5d79f;font-family:'Segoe UI',Arial,sans-serif;font-size:16px}\r\n*{box-sizing:border-box}html,body{margin:0;width:100%;height:100%;overflow:hidden}body{background:radial-gradient(ellipse at 40% 0,#463149,#161019 75%);color:var(--foreground);font:1rem/1.4 'Segoe UI',Arial,sans-serif}button,input,select{font:inherit}button,.button{cursor:pointer;touch-action:manipulation}button,.button,select{font-size:.875rem;color:var(--foreground);background:linear-gradient(#5d4766,#3c2c46);border:1px solid #8b708e;border-bottom-color:#211729;border-radius:8px;min-height:40px;padding:8px 12px;box-shadow:inset 0 1px #e3c7df22,0 2px 0 #1b1421}button:hover,.button:hover{border-color:var(--gold);background:#61456f}button:disabled{opacity:.4;cursor:default}button[aria-pressed=true],button[aria-selected=true]{background:linear-gradient(#f1d79f,#c6a467);border-color:#ffe3a9;color:#271a2c;box-shadow:inset 0 1px #fff4cf,0 2px #19131e}.primary,button.primary{background:var(--gold);color:#261b2c;border-color:var(--gold);font-weight:650}a{color:var(--gold)}.button{display:inline-flex;align-items:center;justify-content:center;text-decoration:none}button:focus-visible,a:focus-visible,select:focus-visible,input:focus-visible,.button:focus-within{outline:3px solid #ffe6ac;outline-offset:3px}button svg{width:18px;height:18px;flex-shrink:0}h1,h2,p{margin:0}h1{font-size:1.25rem;font-weight:700;line-height:1.15}h2{font-size:1.25rem;font-weight:650;line-height:1.25}small{font-size:.75rem;letter-spacing:.1em;color:var(--muted)}[hidden]{display:none!important}\r\n.editor-shell{display:flex;flex-direction:column;gap:12px;width:min(1440px,calc(100% - 32px));height:calc(100dvh - 32px);margin:16px auto;padding:18px;border:6px solid #483c50;border-top-color:#a189a0;border-left-color:#79667f;border-radius:30px;background:linear-gradient(130deg,#766176,#46374f 40%,#32263b);box-shadow:inset 0 0 0 2px #201925,inset 0 3px #dccbd34d,0 7px 0 #19121e,0 14px 45px #0008;position:relative}\r\n.editor-shell:before,.editor-shell:after{content:'';position:absolute;top:5px;width:9px;height:9px;border-radius:50%;background:linear-gradient(135deg,#c8c1b0 42%,#393242 44%,#393242 55%,#a89fa6 57%);box-shadow:1px 2px 3px #0009;pointer-events:none}.editor-shell:before{left:10px}.editor-shell:after{right:10px}\r\n.editor-header{display:flex;align-items:center;gap:16px;min-height:54px;flex:none;padding:0 4px 8px}.editor-brand{font-size:1.3rem;line-height:.9;font-weight:900;letter-spacing:-.08em;text-decoration:none;color:#f3d79b}.editor-brand span{display:block;font-size:.65rem;letter-spacing:.4em;margin-top:5px}.editor-title small{display:block;font-size:.75rem;margin-bottom:5px;color:#e1cddf}.header-actions{display:flex;align-items:center;gap:6px;margin-left:auto}.header-actions button{padding:8px 10px;min-width:40px}.return-link{white-space:nowrap}\r\n.editor-workspace{display:grid;grid-template-columns:minmax(0,1fr) minmax(360px,430px);gap:14px;flex:1;min-height:0}.preview-bay{display:flex;flex-direction:column;min-width:0;min-height:0;border:3px solid #23192b;border-bottom-color:#a38ba6;border-radius:20px;overflow:hidden;background:radial-gradient(ellipse at 50% 42%,#56365e,#26182f 58%,#130e1c);box-shadow:inset 0 2px 14px #0009,0 1px #d6c4d533;position:relative}.preview-readout{display:flex;justify-content:center;gap:12px;align-items:center;padding:14px 16px 0;color:#d6c3e1;font-size:.75rem;flex:none;z-index:1}.preview-stage{flex:1;min-height:0;position:relative;touch-action:none}.hand-viewer-wrap,.hand-canvas{height:100%;width:100%;position:relative}.hand-canvas canvas,#creatureStage canvas{display:block;width:100%;height:100%;touch-action:none}.model-status{position:absolute;top:42%;left:8%;right:8%;text-align:center;color:#ecd9f2}.holo-view:after{content:'';position:absolute;inset:0;pointer-events:none;background:repeating-linear-gradient(0deg,transparent 0 3px,#55eaff12 3px 4px)}\r\n.preview-toolbar{display:flex;flex-direction:column;gap:9px;align-items:center;padding:10px 12px 14px;flex:none;border-top:1px solid #6e507444;background:#2117299c}.view-buttons{display:flex;justify-content:center;gap:6px;flex-wrap:wrap}.view-buttons button{min-height:36px;padding:6px 10px;font-size:.875rem}\r\n.zoom-row{display:flex;align-items:center;gap:8px;width:100%;max-width:300px}.zoom-row input{flex:1;min-width:0;accent-color:var(--gold);height:24px}.zoom-row button{min-height:32px;min-width:36px;padding:2px 8px;font-size:1rem;line-height:1}\r\n.design-console{min-height:0;min-width:0;display:flex;flex-direction:column;border:2px solid #241b2b;border-top-color:#a78caa;border-bottom-color:#1c1524;border-radius:17px;background:linear-gradient(155deg,#48354f,#302337 50%);box-shadow:inset 0 1px #e4c8df33,0 4px 0 #221829;overflow:hidden}.console-tabs{flex:1;min-height:0;display:flex;flex-direction:column;gap:0}.menu-tabs{display:flex;flex:none;gap:3px;align-items:stretch;justify-content:stretch;width:100%;height:auto!important;padding:8px;background:#261c2e;border-radius:0;border-bottom:1px solid #785b7e;overflow-x:auto}.menu-tabs>button{flex:1;min-height:42px;height:auto;padding:7px 9px;white-space:nowrap;border-radius:7px;font-size:.875rem;background:#41304a;color:#decee8}.menu-tabs>button[aria-selected=true]{background:linear-gradient(#efd39e,#c7a26b);color:#281c2f;border-color:#f3dba4}.console-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;scrollbar-color:#a58aad #2c2034;padding:14px}.console-scroll>[role=tabpanel]{font-size:1rem;outline:none}\r\n.panel-heading{display:flex;justify-content:space-between;align-items:center;gap:10px;margin:16px 0 12px}.panel-heading:first-child{margin-top:0}.panel-heading small{display:block;margin-bottom:4px;font-size:.75rem;letter-spacing:.07em}.panel-heading h2{color:#f5e4c6}.lock-part{width:40px;padding:9px}.material-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:7px}.material-grid button{padding:4px;border:1px solid #72587b;background:#24172e;border-radius:9px;overflow:hidden;min-width:0;display:flex;flex-direction:column;gap:4px;align-items:stretch;box-shadow:0 2px 0 #150e1e}.material-grid button[aria-pressed=true]{background:#e4c389;color:#241729;border:2px solid #ffe3a8;padding:3px}.material-grid img{width:100%;height:68px;object-fit:cover;border-radius:5px;background:#20112b;display:block}.material-grid button>span{display:flex;align-items:center;justify-content:center;min-height:34px;padding:0 2px 2px;font-size:.875rem;line-height:1.15;overflow-wrap:anywhere}#colorSwatches{display:grid;gap:10px}#colorSwatches .material-grid,#shipColourRow .material-grid{display:flex;flex-wrap:wrap;gap:7px;overflow:visible;padding:0}#colorSwatches .material-grid button,#shipColourRow .material-grid button{flex:0 0 44px;width:44px;height:44px;padding:0}#colorSwatches strong{display:block;margin:4px 0 -4px;font-size:.78rem;letter-spacing:.07em;text-transform:uppercase;color:#f5e4c6}.part-toggle{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px}.part-toggle button{display:flex;align-items:center;justify-content:center;gap:7px;white-space:nowrap;min-height:44px;font-size:.875rem;background:#41304a;color:#decee8}.part-toggle button[aria-checked=true]{background:linear-gradient(#efd39e,#c7a26b);color:#281c2f;border-color:#f3dba4}.part-toggle i{width:12px;height:12px;flex-shrink:0;border:1px solid #00000066;border-radius:50%}.texture-preview-row{display:flex;align-items:center;gap:8px;margin-top:8px}.panel-actions{display:flex;gap:7px;margin-top:14px;flex-wrap:wrap}.panel-actions>button:first-child{flex:1}.help{font-size:.875rem;line-height:1.5;color:#c7b3cf;margin:12px 0 2px}.console-status{flex:none;padding:10px 14px;border-top:1px solid #755b7b;background:#281e30;color:#e9d3a9;font-size:.75rem;line-height:1.4;min-height:38px;overflow-wrap:anywhere}\r\n.field-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px}.field-grid>label:first-child{grid-column:1/-1}.coach-sprite-grid{grid-column:1/-1;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));max-height:290px;overflow:auto;padding:4px}.coach-sprite-grid button{align-items:center}.coach-sprite-grid canvas{width:auto;height:96px;max-width:100%;image-rendering:pixelated}.coach-sprite-grid button>span{font-size:.76rem}label{font-size:.875rem;color:#e2d0eb}select{display:block;width:100%;margin-top:7px;min-height:44px;padding:9px 10px;box-shadow:inset 0 2px 4px #160c2077;background:#281c33;border-color:#907397}select option{background:#281c33;color:#f4e8f8}.range-stack{display:grid;gap:18px;margin:20px 0}.range-field{display:block;padding:12px;border:1px solid #705478;border-radius:9px;background:#291d33;box-shadow:inset 0 1px 5px #10091788}.range-field output{float:right;color:#efd097;font-variant-numeric:tabular-nums}.range-field input{display:block;width:100%;margin-top:9px;height:28px;accent-color:var(--gold);cursor:pointer}.range-field input::-webkit-slider-runnable-track{height:8px;background:#17101f;border:1px solid #7f638b;border-radius:5px}.range-field input::-webkit-slider-thumb{margin-top:-5px}.check{display:flex;align-items:center;gap:8px;min-height:44px}.check input{width:18px;height:18px;accent-color:var(--gold)}.gesture-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}.gesture-grid button{text-align:left}.file-actions{\r\n  display:flex;\r\n  flex-wrap:wrap;\r\n  gap:10px;\r\n}.file-actions>*{\r\n  width:48px;\r\n  height:48px;\r\n  min-height:48px;\r\n  padding:0;\r\n  justify-content:center;\r\n  align-items:center;\r\n  display:inline-flex;\r\n}\r\n.file-actions svg{\r\n  width:24px;\r\n  height:24px;\r\n}.file-input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}.file-actions .button{position:relative;overflow:hidden}.coach-panel{display:grid;gap:9px}.coach-panel .panel-kicker,.coach-note{display:none}.coach-panel label{font-size:.875rem;margin-top:6px}.coach-panel select{margin:0}.coach-tone{font-size:.875rem;color:#ccb5d5}.coach-panel blockquote{padding:16px;margin:8px 0;background:#251831;border:1px solid #8e6f94;border-left:3px solid var(--gold);border-radius:8px;color:#f6e3cf;font-size:1rem;line-height:1.55}.coach-panel blockquote small{display:block;margin-bottom:9px;color:var(--gold)}\r\n@media(min-width:1100px) and (min-height:880px){.material-grid img{height:88px}.material-grid{gap:8px}}\r\n@media(max-width:900px){.editor-shell{width:calc(100% - 16px);height:calc(100dvh - 16px);margin:8px auto;padding:12px;gap:8px;border-width:4px;border-radius:23px}.editor-workspace{grid-template-columns:minmax(0,1fr) minmax(320px,380px);gap:9px}.editor-header{gap:12px;min-height:50px;padding-bottom:2px}.header-actions{gap:4px}.editor-title small{font-size:.75rem}.preview-toolbar{padding:8px}.preview-hint{display:none}}\r\n@media(max-width:700px){.editor-shell{padding:9px;gap:7px}.editor-brand{display:none}.editor-header{gap:8px;min-height:48px}.editor-title h1{font-size:1.05rem}.editor-title small{letter-spacing:.05em;font-size:.75rem}.header-actions button{min-width:34px;min-height:38px;padding:7px}.return-link{font-size:.8125rem;padding:6px 8px;min-height:38px}.editor-workspace{grid-template-columns:1fr;grid-template-rows:minmax(160px,41%) minmax(0,1fr);gap:8px}.preview-bay{border-radius:14px}.preview-readout{padding:7px 10px 0;font-size:.75rem}.preview-toolbar{padding:5px 7px}.view-buttons{gap:4px}.view-buttons button{font-size:.8125rem;min-height:32px;padding:4px 9px}.design-console{border-radius:12px}.menu-tabs{padding:5px;gap:3px}.menu-tabs>button{min-height:40px;font-size:.875rem;padding:6px 8px}.console-scroll{padding:10px}.panel-heading{margin:12px 0 9px}.panel-heading h2{font-size:1.125rem}.material-grid{grid-auto-flow:column;grid-template-columns:none;grid-template-rows:repeat(2,102px);grid-auto-columns:78px;gap:6px;overflow-x:auto;overflow-y:hidden;overscroll-behavior-x:contain;padding:3px 2px 9px;scrollbar-color:#b59ac0 #261c2e}.material-grid img{height:53px}.material-grid button>span{font-size:.8125rem;min-height:34px}.console-status{padding:7px 10px;min-height:32px}.range-stack{gap:12px;margin-top:14px}.range-field{padding:10px}.panel-actions{margin-top:10px}}\r\n@media(max-height:560px) and (min-width:701px){.editor-shell{margin:4px auto;height:calc(100dvh - 8px);padding:8px}.editor-header{min-height:40px}.editor-title small{display:none}.preview-readout{padding-top:7px}.preview-toolbar{padding:5px}.menu-tabs>button{min-height:36px}.console-status{padding:6px 10px;min-height:28px}}\r\n.material-grid.texture-grid{grid-column:1/-1;display:grid;grid-auto-flow:row;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));grid-template-rows:none;grid-auto-columns:auto;max-height:274px;overflow-x:hidden;overflow-y:auto;padding:4px}\r\n.texture-grid button{position:relative;min-height:94px;align-items:center;text-align:center}\r\n.texture-grid img{height:44px;width:44px;object-fit:cover;image-rendering:pixelated}\r\n.texture-grid button>span{min-height:25px;font-size:.74rem}\r\n.texture-grid .texture-tile-lock{position:absolute;top:4px;right:5px;font-size:12px;font-style:normal}\r\n#shipColourRow{margin:12px 0}\r\n/* R25: eye extras layer over any eye style. */\r\n.eye-toggles{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin:12px 0}.check-field{display:flex;align-items:center;gap:8px;min-height:44px;padding:8px 10px;border:1px solid #705478;border-radius:9px;background:#291d33;font-size:.875rem}.check-field input{width:20px;height:20px;accent-color:var(--gold);flex:none}\r\n/* R25: the ship viewer sits above its controls and stays pinned while the colours scroll under it. */\r\n#shipPreview{position:sticky;top:-10px;z-index:2;height:150px;margin:0 0 8px;border-radius:8px;background:#0b0714;box-shadow:0 6px 10px -6px #000c}\r\n@media(max-height:860px){#shipPreview{height:120px}}\r\n@media(prefers-reduced-motion:reduce){*{scroll-behavior:auto!important;transition:none!important}}\r\n\r\n\r\n/* One continuous species list; identity stays above the preview. */\r\n.coach-sprite-grid{max-height:none;overflow:visible;grid-auto-flow:row;grid-template-columns:repeat(auto-fill,minmax(112px,1fr));grid-template-rows:none;grid-auto-columns:auto}\r\n.coach-choice{position:relative;min-width:0;border:2px solid #b9a5c9;border-radius:10px;padding:2px;background:#171123}\r\n.coach-choice>button[data-body]{width:100%;min-height:120px;display:flex;flex-direction:column;align-items:center;padding:6px 4px;gap:5px}\r\n.coach-choice canvas{width:82px;height:82px;object-fit:contain;image-rendering:pixelated}\r\n.coach-choice>button>span{font-size:.72rem;line-height:1.2;text-align:center;overflow-wrap:anywhere}\r\n.coach-choice[data-locked=true] canvas{filter:grayscale(.8);opacity:.55}\r\n.coach-choice-state{display:block;padding:3px 26px 4px 4px;font-size:.68rem;color:#b9a5c9}\r\n.coach-choice-lock{position:absolute;bottom:2px;right:2px;padding:3px;min-height:32px;min-width:32px;font-size:.85rem}\r\n.preview-readout{gap:6px;padding:6px 8px;min-height:44px;font-size:.85rem;text-align:center}\r\n#coachPathSymbol{flex:none;border:2px solid currentColor;border-radius:7px;padding:3px 6px}\r\n#coachDisplayName{overflow-wrap:anywhere;line-height:1.15}\r\n#coachUnlock{padding:4px;min-width:40px;min-height:40px;flex:none}\r\n.coach-requirement-dialog{max-width:min(92vw,480px);padding:24px;border:2px solid #d8b573;border-radius:16px;background:#25192f;color:#fff1d1}\r\n.coach-requirement-dialog p{margin:14px 0;line-height:1.5}.coach-requirement-dialog::backdrop{background:#08050dc9}\r\n#panel-body:has(.coach-choice) .field-grid>label:has(#body){display:none}\r\n\r\n.preview-bay .preview-strip{top:50px}\r\n@media(max-width:600px){.menu-tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));overflow-x:visible}.menu-tabs>button{min-width:0}}\r\n\r\n#colourGrid button,#paletteGrid button,#shipColourGrid button{position:relative}\r\n.swatch-lock{position:absolute;right:3px;bottom:3px;display:grid;place-items:center;width:24px;height:24px;border-radius:6px;background:#130b20e6;color:#fff;font-size:15px;line-height:1;pointer-events:none;text-shadow:none}\r\n\r\n/* Keep adaptation selection with the menu; only the texture tiles scroll. */\r\n.texture-menu-header{display:none;flex:none;align-items:center;gap:12px;padding:10px 14px;border-bottom:1px solid #785b7e;background:#302337}\r\n.console-tabs:has(#tab-textures[aria-selected=true]) .texture-menu-header{display:flex}\r\n.texture-menu-header h2{font-size:1.125rem;color:#f5e4c6}\r\n.texture-menu-header label{display:flex;align-items:center;gap:9px;flex:1;min-width:0;font-size:.8125rem}\r\n.texture-menu-header select{flex:1;min-width:0;margin:0}\r\n.console-scroll:has(#panel-textures:not([hidden])){padding:6px}\r\n#panel-textures .texture-grid{max-height:none;overflow:visible;margin:0;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:6px}\r\n#panel-textures .texture-preview-row{display:none}\r\n@media(max-width:700px){\r\n .texture-menu-header{padding:7px 10px}\r\n .texture-menu-header h2{display:none}\r\n .texture-menu-header select{min-height:42px;padding:8px}\r\n #panel-textures .texture-grid button{min-height:90px}\r\n}\r\n/* Short phones keep a full adaptation row even when installed Skins adds a menu row. */\r\n@media(max-width:700px) and (max-height:720px){\r\n .editor-workspace{grid-template-rows:minmax(140px,34%) minmax(0,1fr)}\r\n .menu-tabs{padding:4px}\r\n .menu-tabs>button{min-height:32px;padding:4px 6px}\r\n .texture-menu-header{padding:5px 10px}\r\n .texture-menu-header select{min-height:36px;padding:5px 8px}\r\n .console-status{max-height:48px;overflow-y:auto}\r\n}\r\n@media(min-width:701px) and (max-height:560px){\r\n .editor-shell{padding:6px;gap:4px}\r\n .editor-header{min-height:34px;padding-bottom:0}\r\n .header-actions button,.return-link{min-height:32px;padding:4px 8px}\r\n .menu-tabs{padding:4px}\r\n .menu-tabs>button{min-height:32px;padding:4px 6px;font-size:.8125rem}\r\n .texture-menu-header{padding:4px 8px;gap:8px}\r\n .texture-menu-header h2{display:none}\r\n .texture-menu-header select{min-height:32px;padding:4px 8px}\r\n .console-status{min-height:24px;max-height:42px;padding:3px 8px;overflow-y:auto}\r\n #panel-textures .texture-grid button{min-height:74px}\r\n #panel-textures .texture-grid img{width:32px;height:32px}\r\n}\r\n","creature/index.html":"<!doctype html>\r\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><meta name=\"theme-color\" content=\"#46374f\"><title>Customize your coach</title><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\"}}</script><script type=\"module\" src=\"/audio/standalone-sound.mjs\"></script><script type=\"module\" src=\"/creature/assets/account-bridge.js\"></script><script type=\"module\" src=\"/creature/assets/editor.js?v=rank5\"></script><link rel=\"stylesheet\" href=\"./creature.css?v=coach-window-r32\"><link rel=\"stylesheet\" href=\"./preview-window.css?v=coach-window-r32\"><style>.preview-strip{position:absolute;left:8px;right:8px;top:4px;z-index:2;margin:0;padding:3px 10px;border:1px solid #ffe3a9;border-radius:999px;background:#1d1424;color:#ffe3a9;font-size:.75rem;text-align:center;pointer-events:none}#colorSwatches button[data-locked],#shipColourRow button[data-locked]{font-size:.8125rem;line-height:1;text-shadow:0 0 3px #000}/* W2-2A (#5): the app's bottom bar, linking back into /pose.html#<route>. */:root{--myr5-bar:calc(64px + env(safe-area-inset-bottom))}.editor-shell{height:calc(100dvh - var(--myr5-bar) - 16px)}.coach-dock{position:fixed;inset:auto 0 0;z-index:40;box-sizing:border-box;height:var(--myr5-bar);display:grid;grid-template-columns:repeat(2,minmax(0,1fr)) 58px repeat(3,minmax(0,1fr));align-items:center;gap:3px;padding:0 6px env(safe-area-inset-bottom);border-top:1px solid #685077;background:#171123f2;box-shadow:0 -6px 18px #08050f99;font:600 12px/1.1 system-ui,sans-serif}@media(max-width:400px){.coach-dock{font-size:11px}}.coach-dock a{box-sizing:border-box;display:flex;align-items:center;justify-content:center;min-width:0;height:46px;padding:0 1px;border:1px solid #70547c;border-radius:9px;background:#30223e;color:#f2deab;text-align:center;text-decoration:none;hyphens:auto}.coach-dock a:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}.coach-dock .dock-portal{justify-self:center;width:56px;height:56px;padding:0;border:0;border-radius:50%;color:#fff;background:radial-gradient(circle,#1c1428 0 60%,transparent 62%),conic-gradient(#ff5f1f,#ffff33,#39ff14,#1f51ff,#b026ff,#ff10f0,#ff5f1f);box-shadow:0 0 12px #b026ff80}</style></head>\r\n<body><main class=\"editor-shell\">\r\n<header class=\"editor-header\"><a class=\"editor-brand\" href=\"/pose.html\" aria-label=\"Back to coach\">MOM<span>INC.</span></a><div class=\"editor-title\"><h1>Customize</h1></div><div class=\"header-actions\"><button id=\"undo\" aria-label=\"Undo\" disabled>↶</button><button id=\"redo\" aria-label=\"Redo\" disabled>↷</button><a class=\"button return-link\" href=\"/pose.html\">Done ↗</a></div></header>\r\n<div class=\"editor-workspace\">\r\n <section class=\"preview-bay\" aria-label=\"Coach preview\"><div class=\"preview-readout\"><span id=\"coachPathSymbol\" aria-hidden=\"true\"></span><strong id=\"coachDisplayName\"></strong><button id=\"coachUnlock\" type=\"button\" aria-label=\"Coach unlock requirement\" hidden>&#128274;</button><span id=\"motionLabel\" hidden></span></div><div id=\"creatureStage\" class=\"preview-stage\"></div><div class=\"preview-toolbar\"><div class=\"zoom-row\"><button type=\"button\" id=\"zoomOut\" aria-label=\"Zoom out\" title=\"Zoom out\">&minus;</button><input id=\"zoom\" type=\"range\" min=\"0\" max=\"1\" step=\"0.02\" value=\"0\" aria-label=\"Zoom\"><button type=\"button\" id=\"zoomIn\" aria-label=\"Zoom in\" title=\"Zoom in\">+</button></div><div class=\"view-buttons\"><button id=\"front\">Front</button><button id=\"back\">Back</button><button id=\"pauseMotion\" aria-pressed=\"false\">Pause</button></div></div></section>\r\n <section class=\"design-console\" aria-label=\"Coach design controls\"><div class=\"console-tabs\"><div class=\"menu-tabs\" role=\"tablist\" aria-label=\"Customizer menus\"><button type=\"button\" id=\"tab-body\" role=\"tab\" aria-controls=\"panel-body\" aria-selected=\"true\" tabindex=\"0\" data-menu=\"body\">Species</button><button type=\"button\" id=\"tab-textures\" role=\"tab\" aria-controls=\"panel-textures\" aria-selected=\"false\" tabindex=\"-1\" data-menu=\"textures\">Textures</button><button type=\"button\" id=\"tab-materials\" role=\"tab\" aria-controls=\"panel-materials\" aria-selected=\"false\" tabindex=\"-1\" data-menu=\"materials\">Colour</button><button type=\"button\" id=\"tab-face\" role=\"tab\" aria-controls=\"panel-face\" aria-selected=\"false\" tabindex=\"-1\" data-menu=\"face\">Face</button><button type=\"button\" id=\"tab-ship\" role=\"tab\" aria-controls=\"panel-ship\" aria-selected=\"false\" tabindex=\"-1\" data-menu=\"ship\">Ship</button><button type=\"button\" id=\"tab-files\" role=\"tab\" aria-controls=\"panel-files\" aria-selected=\"false\" tabindex=\"-1\" data-menu=\"files\">Files</button></div><div class=\"texture-menu-header\"><h2>Textures</h2><label for=\"textureId\">Adaptations<select id=\"textureId\"></select></label></div><div class=\"console-scroll\">\r\n  <div id=\"panel-body\" role=\"tabpanel\" aria-labelledby=\"tab-body\" tabindex=\"0\"><div class=\"panel-heading\"><h2>Species</h2></div><div class=\"field-grid\"><label>Creature<select id=\"body\"></select></label><label id=\"fingersField\">Digits per hand<select id=\"fingers\"></select></label><label id=\"toesField\">Toes per foot<select id=\"toes\"></select></label></div><div class=\"range-stack\"><label id=\"furField\" class=\"range-field\" for=\"fur\">Collar fluff<output id=\"furValue\">1.00</output><input id=\"fur\" type=\"range\" min=\"0.65\" max=\"1.4\" step=\"0.05\"></label><label class=\"range-field\" for=\"detail\">Surface detail<output id=\"detailValue\">1.00</output><input id=\"detail\" type=\"range\" min=\"0.5\" max=\"1.5\" step=\"0.05\"></label></div><p id=\"digitsHelp\" class=\"help\">Digits include the thumb.</p></div>\r\n  <div id=\"panel-textures\" role=\"tabpanel\" aria-labelledby=\"tab-textures\" tabindex=\"0\" hidden><div class=\"panel-heading\"><h2>Textures</h2></div><div class=\"texture-preview-row\"><img id=\"texturePreview\" alt=\"Selected adaptation preview\" width=\"40\" height=\"40\" style=\"border-radius:6px;background:#20112b\"></div></div>\r\n  <div id=\"panel-materials\" role=\"tabpanel\" aria-labelledby=\"tab-materials\" tabindex=\"0\" hidden><div class=\"panel-heading\"><h2>Colours</h2></div><div id=\"colorSwatches\" aria-label=\"Colours and palettes\"></div><div class=\"panel-actions\"><button id=\"applyAll\">Use on all parts</button><button id=\"materialClear\">Reset to original</button></div></div>\r\n  <div id=\"panel-face\" role=\"tabpanel\" aria-labelledby=\"tab-face\" tabindex=\"0\" hidden><div class=\"panel-heading\"><h2>Face</h2></div><div class=\"field-grid\"><label>Eye arrangement<select id=\"eyeLayout\"></select></label><label>Expression<select id=\"eye\"></select></label><label>Pupil shape<select id=\"pupil\"></select></label></div><div class=\"eye-toggles\" role=\"group\" aria-label=\"Eye extras\"><label class=\"check-field\"><input id=\"blackSclera\" type=\"checkbox\">Black whites</label><label class=\"check-field\"><input id=\"colourPupil\" type=\"checkbox\">Coloured iris centre</label></div><div class=\"range-stack\"><label class=\"range-field\" for=\"iris\">Iris size<output id=\"irisValue\">1.00</output><input id=\"iris\" type=\"range\" min=\"0.7\" max=\"1.25\" step=\"0.05\"></label><label class=\"range-field\" for=\"pupilSize\">Pupil size<output id=\"pupilSizeValue\">1.00</output><input id=\"pupilSize\" type=\"range\" min=\"0.6\" max=\"1.15\" step=\"0.05\"></label></div></div>\r\n  <div id=\"panel-ship\" role=\"tabpanel\" aria-labelledby=\"tab-ship\" tabindex=\"0\" hidden><div class=\"panel-heading\"><h2>Ship</h2></div><div id=\"shipPreview\"><p id=\"shipPreviewStatus\" class=\"help\" role=\"status\" style=\"position:absolute;inset:auto 8px 6px;margin:0;text-align:center\"></p><button id=\"shipPreviewRetry\" type=\"button\" hidden style=\"position:absolute;top:8px;right:8px\">Try again</button></div><div class=\"field-grid\"><label>Coach ship<select id=\"shipPick\"></select></label></div><p id=\"shipDescription\" class=\"help\"></p><div id=\"shipColourRow\" role=\"group\" aria-label=\"Ship colours\"></div></div>\r\n  <div id=\"panel-files\" role=\"tabpanel\" aria-labelledby=\"tab-files\" tabindex=\"0\" hidden><div class=\"panel-heading\"><h2>Your designs</h2></div><div class=\"file-actions\">\r\n  <button id=\"exportRecipe\" class=\"primary\" aria-label=\"Download editable recipe\" title=\"Download editable recipe\">\r\n    <svg viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n      <path d=\"M12 4v11M7 11l5 5 5-5M5 20h14\"/>\r\n    </svg>\r\n  </button>\r\n  <label class=\"button\" for=\"importFile\" aria-label=\"Load game recipe\" title=\"Load game recipe\">\r\n    <svg viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n      <path d=\"M12 16V5M7 9l5-5 5 5M5 20h14\"/>\r\n    </svg>\r\n    <input id=\"importFile\" type=\"file\" accept=\".json,application/json\" class=\"file-input\">\r\n  </label>\r\n  <button id=\"exportGLB\" disabled aria-label=\"Download animated model · GLB\" title=\"Download animated model · GLB\">\r\n    <svg viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n      <path d=\"M21 7.5L12 2 3 7.5v9l9 5 9-5z\"/>\r\n      <polyline points=\"3 17.5 12 23 21 17.5\"/>\r\n      <polyline points=\"12 23 12 14.5\"/>\r\n    </svg>\r\n  </button>\r\n  <button id=\"original\" aria-label=\"Restore original coach\" title=\"Restore original coach\">\r\n    <svg viewBox=\"0 0 24 24\" stroke=\"currentColor\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\r\n      <path d=\"M3 12a9 9 0 1 0 3-6.7L3 8M3 3v5h5\"/>\r\n    </svg>\r\n  </button>\r\n</div><p class=\"help\"><a href=\"./NOTICE.md\">Open-source credits</a></p></div>\r\n </div></div><p id=\"creatureStatus\" class=\"console-status\" role=\"status\">Loading your coach…</p></section>\r\n</div></main><nav id=\"coachDock\" class=\"coach-dock\" aria-label=\"Coach tools\"><a class=\"dock-control dock-settings\" data-route=\"customizeCoach\" aria-label=\"Customize coach\" aria-current=\"page\" title=\"Customize coach\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><circle cx=\"12\" cy=\"12\" r=\"6.5\"/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9 7 7M17 17l2.1 2.1M4.9 19.1 7 17M17 7l2.1-2.1\"/></svg></span></a><a class=\"dock-control dock-food\" data-route=\"food\" href=\"/pose.html#food\" aria-label=\"Food\" title=\"Food\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 8h4l2-3h6l2 3h4v11H3z\"/><circle cx=\"12\" cy=\"13\" r=\"3.5\"/></svg></span></a><a class=\"dock-portal\" data-route=\"portal\" href=\"/pose.html\" aria-label=\"Portal or workout pod\" title=\"Portal or workout pod\"><svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 11.5 12 4l9 7.5M5.5 10v10h13V10M10 20v-6h4v6\"/></svg><span aria-hidden=\"true\">PORTAL</span></a><a class=\"dock-control dock-scoreboard\" data-route=\"scoreboard\" href=\"/pose.html#scoreboard\" aria-label=\"Classroom leaderboard\" title=\"Classroom leaderboard\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"9\" cy=\"8\" r=\"3\"/><circle cx=\"17\" cy=\"9\" r=\"2.5\"/><path d=\"M3 20c0-4 3-6 6-6s6 2 6 6M15 14c3 0 6 1.5 6 5\"/></svg></span></a><a class=\"dock-control dock-achievements\" data-route=\"achievements\" href=\"/pose.html#achievements\" aria-label=\"Achievements\" title=\"Achievements\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7 4h10v5a5 5 0 0 1-10 0zM7 6H3c0 3 1 4 4 4M17 6h4c0 3-1 4-4 4M12 14v4M8 21h8\"/></svg></span></a><a class=\"dock-control dock-pod\" data-route=\"reminders\" href=\"/pose.html#reminders\" aria-label=\"Reminders computer\" title=\"Reminders computer\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z\"/></svg></span></a><span class=\"dock-live\" role=\"status\" aria-live=\"polite\"></span></nav><script type=\"module\">import{mountStandaloneHousing}from'/modules/portal/standalone-housing.mjs';await mountStandaloneHousing();</script></body></html>\r\n","creature/models/roster/manifest.json":"[\r\n {\r\n  \"id\": \"roster/01-seed-pearo--3d_character_model\",\r\n  \"label\": \"Seed \\u00b7 Pearo 1\",\r\n  \"group\": \"Seed \\u00b7 Pearo\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1268160,\r\n  \"sha256\": \"6f14746278db647ccf761880725897d752022473966aaab63b80da448325507e\"\r\n },\r\n {\r\n  \"id\": \"roster/01-seed-pearo--cute_alien_figure_3d_model\",\r\n  \"label\": \"Seed \\u00b7 Pearo 2\",\r\n  \"group\": \"Seed \\u00b7 Pearo\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1155552,\r\n  \"sha256\": \"49985ecd9a23fbad5f04560e0079b6dd25e7f9e50cbad7ba9e3f74025739f3dd\"\r\n },\r\n {\r\n  \"id\": \"roster/01-seed-pearo--white_3d_character_model\",\r\n  \"label\": \"Seed \\u00b7 Pearo 3\",\r\n  \"group\": \"Seed \\u00b7 Pearo\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1205556,\r\n  \"sha256\": \"b30e359d94fe30785ecb60df1f491b0f181243ed3c4e0224a413ea07eba2359d\"\r\n },\r\n {\r\n  \"id\": \"roster/01-seed-pearo--blank_humanoid_figure_3d_model\",\r\n  \"label\": \"Seed \\u00b7 Pearo 4\",\r\n  \"group\": \"Seed \\u00b7 Pearo\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1369432,\r\n  \"sha256\": \"2f7314ad14412bd9afff0e56c0c85a0438ea7e327d2b555a8997c0d72d87268d\"\r\n },\r\n {\r\n  \"id\": \"roster/01-seed-pearo--blank_toy_figure_3d_model\",\r\n  \"label\": \"Seed \\u00b7 Pearo 5\",\r\n  \"group\": \"Seed \\u00b7 Pearo\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1060048,\r\n  \"sha256\": \"bfe377e02b5324683a43a2659639e8d1b810f6d237f0c0361e4bdc28cbefcd0f\"\r\n },\r\n {\r\n  \"id\": \"roster/02-taper-tallstalk--3d_humanoid_figure\",\r\n  \"label\": \"Taper \\u00b7 Tallstalk 1\",\r\n  \"group\": \"Taper \\u00b7 Tallstalk\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1146852,\r\n  \"sha256\": \"d40507bde2972770f4ba92cdf5c939b2909b77d68c63a4f5f397e0debeee1a99\"\r\n },\r\n {\r\n  \"id\": \"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\r\n  \"label\": \"Taper \\u00b7 Tallstalk 2\",\r\n  \"group\": \"Taper \\u00b7 Tallstalk\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 739832,\r\n  \"sha256\": \"85b045f6ff4ad23d6a5a17074e4412047d465393b5023db96bff81a174809f08\"\r\n },\r\n {\r\n  \"id\": \"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",\r\n  \"label\": \"Taper \\u00b7 Tallstalk 3\",\r\n  \"group\": \"Taper \\u00b7 Tallstalk\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1511192,\r\n  \"sha256\": \"24308194976172bc3e523a09c0f1eafc4722e161f73a1636813c235442ca793f\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",\r\n  \"label\": \"Pearl \\u00b7 Orb 1\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1051868,\r\n  \"sha256\": \"35eca4f9738d14f22f8bb33d1ad7ebdc6703873721d256d73b252f9d82003020\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--circle_center\",\r\n  \"label\": \"Pearl \\u00b7 Orb 2\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 949252,\r\n  \"sha256\": \"d47b82f8f7f06c96db52e4948f19d388a2ab00f1cb511573102841956173f601\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\r\n  \"label\": \"Pearl \\u00b7 Orb 3\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1313640,\r\n  \"sha256\": \"1e32a434aa538976cb2598b216ae17175437f19dde938626824c5bcf923ae139\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--robot_3d_model\",\r\n  \"label\": \"Pearl \\u00b7 Orb 4\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 397672,\r\n  \"sha256\": \"8b6dff121c1a752b9688b8cb140be61bdc0d612af3d386296b27b3993aa3faa0\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--stylized_3d_character1\",\r\n  \"label\": \"Pearl \\u00b7 Orb 5\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 913016,\r\n  \"sha256\": \"cc118fd1332b647308d7a7ba49d462da6b9c9c437334cd3179b50fdc48313664\"\r\n },\r\n {\r\n  \"id\": \"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\r\n  \"label\": \"Pearl \\u00b7 Orb 6\",\r\n  \"group\": \"Pearl \\u00b7 Orb\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1677408,\r\n  \"sha256\": \"c284799cd30c3fa5636559a827ae1a8aa01ff3eabced3be2575822e47e11c968\"\r\n },\r\n {\r\n  \"id\": \"roster/04-crest-wedge--robot_creature_3d_model\",\r\n  \"label\": \"Crest \\u00b7 Wedge 1\",\r\n  \"group\": \"Crest \\u00b7 Wedge\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 943504,\r\n  \"sha256\": \"236098d9935147ce4de6087eb17b4cfefac6ff5261931f8730127d98eeade38d\"\r\n },\r\n {\r\n  \"id\": \"roster/04-crest-wedge--stylized_3d_character\",\r\n  \"label\": \"Crest \\u00b7 Wedge 2\",\r\n  \"group\": \"Crest \\u00b7 Wedge\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 802536,\r\n  \"sha256\": \"3f798914742d5e8a93746c9b8cd378b8461cd081a2fce2b2e54c43112333e8e8\"\r\n },\r\n {\r\n  \"id\": \"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\r\n  \"label\": \"Slope \\u00b7 Bobble 1\",\r\n  \"group\": \"Slope \\u00b7 Bobble\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 409688,\r\n  \"sha256\": \"47fff716c8cf079f3a2861be8e454f33585ab66aeb8d1c098c0af4a368ed226b\"\r\n },\r\n {\r\n  \"id\": \"roster/06-ridge-triad--geometric_robot_3d_model1\",\r\n  \"label\": \"Ridge \\u00b7 Triad 1\",\r\n  \"group\": \"Ridge \\u00b7 Triad\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1172932,\r\n  \"sha256\": \"ff50e2d6be2ee692bba9c285ae1379ed769a3b01d0a02e309c633b9df96e9a94\"\r\n },\r\n {\r\n  \"id\": \"roster/06-ridge-triad--robot_3d_model1\",\r\n  \"label\": \"Ridge \\u00b7 Triad 2\",\r\n  \"group\": \"Ridge \\u00b7 Triad\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1288584,\r\n  \"sha256\": \"9c23f758fd2d04c1635430cf50723c7d551599e4b4317f7cd20b065442be7555\"\r\n },\r\n {\r\n  \"id\": \"roster/07-bulb-sphereling--cute_robot_3d_model\",\r\n  \"label\": \"Bulb \\u00b7 Sphereling 1\",\r\n  \"group\": \"Bulb \\u00b7 Sphereling\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1310520,\r\n  \"sha256\": \"8fd342cd955e59ced8f73c889ebc5934c3aefe1ed5531cb321fe89dc176aec75\"\r\n },\r\n {\r\n  \"id\": \"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\r\n  \"label\": \"Bulb \\u00b7 Sphereling 2\",\r\n  \"group\": \"Bulb \\u00b7 Sphereling\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1365896,\r\n  \"sha256\": \"5c0741b81a8281d01a98d6244aa5be3a2cff39e05f50d182d801b0bc915f85ca\"\r\n },\r\n {\r\n  \"id\": \"roster/08-shard-asym--geometric_robot_3d_model\",\r\n  \"label\": \"Shard \\u00b7 Asym 1\",\r\n  \"group\": \"Shard \\u00b7 Asym\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1089924,\r\n  \"sha256\": \"e6d0ec623a8aaf07b3e88d845faabde2137d3449c513942411641bc908e92c9f\"\r\n },\r\n {\r\n  \"id\": \"roster/08-shard-asym--robot_3d_model4\",\r\n  \"label\": \"Shard \\u00b7 Asym 2\",\r\n  \"group\": \"Shard \\u00b7 Asym\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 910596,\r\n  \"sha256\": \"f2e1f83da490c8c24f533e0a75de537457f801ccf7782dad7569dbecfc0b4d58\"\r\n },\r\n {\r\n  \"id\": \"roster/08-shard-asym--fantasy_creature_3d_model2\",\r\n  \"label\": \"Shard \\u00b7 Asym 3\",\r\n  \"group\": \"Shard \\u00b7 Asym\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 819588,\r\n  \"sha256\": \"8889a8962d2c6666e6db39833b1269538ed40eaccc79d78f6b67c01d2f61b1e3\"\r\n },\r\n {\r\n  \"id\": \"roster/08-shard-asym--stylized_action_figure_3d_model\",\r\n  \"label\": \"Shard \\u00b7 Asym 4\",\r\n  \"group\": \"Shard \\u00b7 Asym\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1176148,\r\n  \"sha256\": \"45797349edb2b534de025ba87654244049d6056c2a45ec43fb6548714c6a1db4\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--3d_robot_model\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 1\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1403544,\r\n  \"sha256\": \"62ec21ce0a13fbd14d25c04850834d5486c0a8b1b94f050603f0f2e87a036157\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 2\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1176604,\r\n  \"sha256\": \"198d3bc78c470283e8d4947be8e8b22dc4b81f50c7f708fb8e8ea9de0fe5c14f\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--mini_robot_3d_model\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 3\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 978344,\r\n  \"sha256\": \"b2a7c9a6c4c2f76e622827d9dc6d8d85a5a94ae3fe20b4868e772cddc2d66039\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--robot_3d_model2\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 4\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1092528,\r\n  \"sha256\": \"7b1e79e81b7266be36d335a8bea65b91152f427586d53d5d6545f90abc3e795d\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--robot_3d_model3\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 5\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 639812,\r\n  \"sha256\": \"4e174889fc91ebcdffb6fd28c1747dbc1b8b6a4c8d68db29981deb8dd6784499\"\r\n },\r\n {\r\n  \"id\": \"roster/09-monolith-tanka--white_horned_robot_3d_model\",\r\n  \"label\": \"Monolith \\u00b7 Tanka 6\",\r\n  \"group\": \"Monolith \\u00b7 Tanka\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1177656,\r\n  \"sha256\": \"f135a2e874ccd388a31842d77b374027cdd38c67f24f4494cc3c83aebf074ca6\"\r\n },\r\n {\r\n  \"id\": \"roster/10-petal-wisp--stylized_creature_3d_model\",\r\n  \"label\": \"Petal \\u00b7 Wisp 1\",\r\n  \"group\": \"Petal \\u00b7 Wisp\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1036744,\r\n  \"sha256\": \"96a1bba31bb3587f61af255ad9b807dbabbd5715528f393a69a6bb0aa152a870\"\r\n },\r\n {\r\n  \"id\": \"roster/10-petal-wisp--ghost_character_3d_model\",\r\n  \"label\": \"Petal \\u00b7 Wisp 2\",\r\n  \"group\": \"Petal \\u00b7 Wisp\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 965284,\r\n  \"sha256\": \"db483101b0755c30a2a41f9edd9b3760b8ec10830b40d7832afd065b4edeb50a\"\r\n },\r\n {\r\n  \"id\": \"roster/10-petal-wisp--fantasy_creature_3d_model4\",\r\n  \"label\": \"Petal \\u00b7 Wisp 3\",\r\n  \"group\": \"Petal \\u00b7 Wisp\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1266896,\r\n  \"sha256\": \"34e5de8eef218814b67985a35b80e3fd818d5951458e9ba8d226fdf30bca8eef\"\r\n },\r\n {\r\n  \"id\": \"roster/11-anvil-cask--clay-style_robot_3d_model\",\r\n  \"label\": \"Anvil \\u00b7 Cask 1\",\r\n  \"group\": \"Anvil \\u00b7 Cask\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 867228,\r\n  \"sha256\": \"d2797026da4cb563bae6868fc766e99f4ecd9a90d3b915481c428b6eca127d7a\"\r\n },\r\n {\r\n  \"id\": \"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\r\n  \"label\": \"Seedpod \\u00b7 Snailslug 1\",\r\n  \"group\": \"Seedpod \\u00b7 Snailslug\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1337688,\r\n  \"sha256\": \"bd7821a4a794d82f7c2c7e683fea472243a57ede0df7ee2ce15dc4ab06853ed9\"\r\n },\r\n {\r\n  \"id\": \"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\r\n  \"label\": \"Seedpod \\u00b7 Snailslug 2\",\r\n  \"group\": \"Seedpod \\u00b7 Snailslug\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1257688,\r\n  \"sha256\": \"cb57236887d0091be9cf642f3ce920dd36eed194611124cb6e10d0fd70fc5a25\"\r\n },\r\n {\r\n  \"id\": \"roster/13-fan-split--stylized_3d_character2\",\r\n  \"label\": \"Fan \\u00b7 Split 1\",\r\n  \"group\": \"Fan \\u00b7 Split\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1184572,\r\n  \"sha256\": \"caac851bc0d083a5401d7630e432b163364c468d70b9bc5150cf3be261828529\"\r\n },\r\n {\r\n  \"id\": \"roster/13-fan-split--stylized_toy_3d_model\",\r\n  \"label\": \"Fan \\u00b7 Split 2\",\r\n  \"group\": \"Fan \\u00b7 Split\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1113400,\r\n  \"sha256\": \"1a3cd58c92023e71ae614c1944be1ac464df19961fdd91830b63457137b93ca0\"\r\n },\r\n {\r\n  \"id\": \"roster/14-chisel-spire--cone_head_3d_model\",\r\n  \"label\": \"Chisel \\u00b7 Spire 1\",\r\n  \"group\": \"Chisel \\u00b7 Spire\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 551724,\r\n  \"sha256\": \"f5274c1a2b6c0655edb40fbbffdc1494cd9a8d14b9ebfd7c7943253c60015b65\"\r\n },\r\n {\r\n  \"id\": \"roster/14-chisel-spire--low_poly_robot_3d_model\",\r\n  \"label\": \"Chisel \\u00b7 Spire 2\",\r\n  \"group\": \"Chisel \\u00b7 Spire\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1149448,\r\n  \"sha256\": \"134350c0600ddf360256a598b000b68395109c689d252e96023eecd8ea68425e\"\r\n },\r\n {\r\n  \"id\": \"roster/15-orbital-coili--robot_character_3d_model\",\r\n  \"label\": \"Orbital \\u00b7 Coili 1\",\r\n  \"group\": \"Orbital \\u00b7 Coili\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1173644,\r\n  \"sha256\": \"9e0357bea8cdce4b57349480b1eed71052aecbae86ec16c7fb8825ead1fdce7a\"\r\n },\r\n {\r\n  \"id\": \"roster/16-spade-arch--pyramid_head_figure_3d_model\",\r\n  \"label\": \"Spade \\u00b7 Arch 1\",\r\n  \"group\": \"Spade \\u00b7 Arch\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1210468,\r\n  \"sha256\": \"4f4beab075ab542092694b58878a21cb25d35843cf60dbc09df6b352a9775563\"\r\n },\r\n {\r\n  \"id\": \"roster/16-spade-arch--stylized_humanoid_3d_model\",\r\n  \"label\": \"Spade \\u00b7 Arch 2\",\r\n  \"group\": \"Spade \\u00b7 Arch\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 846680,\r\n  \"sha256\": \"07e6b5c32ea82dab6272de2ef98eb1b118c37604052a16af5211554101f23335\"\r\n },\r\n {\r\n  \"id\": \"roster/17-shellcap-manyarm--3d_character_figurine\",\r\n  \"label\": \"Shellcap \\u00b7 Manyarm 1\",\r\n  \"group\": \"Shellcap \\u00b7 Manyarm\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 950740,\r\n  \"sha256\": \"4fc9344a8a00320864fbc38cff65aad3e624ca37e2c2f84346afa000a9139236\"\r\n },\r\n {\r\n  \"id\": \"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\r\n  \"label\": \"Shellcap \\u00b7 Manyarm 2\",\r\n  \"group\": \"Shellcap \\u00b7 Manyarm\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 640472,\r\n  \"sha256\": \"7d3c5b780e2abad07437e669ff968e072c77ffb3ce31e6fda9f09b122bf12616\"\r\n },\r\n {\r\n  \"id\": \"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\r\n  \"label\": \"Shellcap \\u00b7 Manyarm 3\",\r\n  \"group\": \"Shellcap \\u00b7 Manyarm\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 916444,\r\n  \"sha256\": \"667a8044bd0336e1dd6503425d37cdd1b5ca018ad9ce30c5d5ad635c7623c878\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--dragon_creature_3d_model\",\r\n  \"label\": \"Four-legged 1\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 393988,\r\n  \"sha256\": \"fa7986a0327fa42d32adc646b177b4618c34afb0bc595e8e5bec535787bc4025\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--fantasy_creature_3d_model1\",\r\n  \"label\": \"Four-legged 2\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1101604,\r\n  \"sha256\": \"d1db8a5c75f24b47ec8f1f999865653a61aaa0ca6e25b5d7e21c62c09fcbe2c4\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--fantasy_creature_3d_model3\",\r\n  \"label\": \"Four-legged 3\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 852444,\r\n  \"sha256\": \"71153ffef11c0913beff4c3dd0ce5989dd1d669c1ad060d577b1c7e8bc715dad\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--four-legged_robot_3d_model\",\r\n  \"label\": \"Four-legged 4\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 429424,\r\n  \"sha256\": \"8d6e16899a12a681eb881a894b569b025fce16d44d3c8043cf4fe95d48e5aa18\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--quadruped_robot_3d_model1\",\r\n  \"label\": \"Four-legged 5\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 896152,\r\n  \"sha256\": \"78fabcf15ac4bc7310b09813b6b1ef44e122a2d7b3c97a34c2923313ed5c684d\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--quadruped_robot_3d_model\",\r\n  \"label\": \"Four-legged 6\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1083792,\r\n  \"sha256\": \"31555c5c6feb4b3fa822bf146a4f67c9aeb303a8d80ece4afe0718d4d15c463b\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--robotic_dog_3d_model\",\r\n  \"label\": \"Four-legged 7\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1163368,\r\n  \"sha256\": \"2d44c01723234401c9dcdc6cfdd48076b61238ccc95bb2f3162c7acafdd1327e\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--stylized_quadruped_3d_model\",\r\n  \"label\": \"Four-legged 8\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 628136,\r\n  \"sha256\": \"de36f55a70200af71fbdeac590e3fe50a374237cd15a67e3273612ed53f7e123\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--wooden_four-legged_robot_3d_model\",\r\n  \"label\": \"Four-legged 9\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1023004,\r\n  \"sha256\": \"d0fdc5a15981813ce9466a99b40cea4d0c44500d372426bd36621179aa870f1e\"\r\n },\r\n {\r\n  \"id\": \"roster/18-quad-all--wooden_robot_3d_model\",\r\n  \"label\": \"Four-legged 10\",\r\n  \"group\": \"Four-legged\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1033420,\r\n  \"sha256\": \"884191d06c05a20c8582e0c9609f820d3783b3b74bb3cb3e76a0270d56143b8b\"\r\n },\r\n {\r\n  \"id\": \"roster/19-genie-multi--fantasy_creature_3d_model\",\r\n  \"label\": \"Genie \\u00b7 Multi 1\",\r\n  \"group\": \"Genie \\u00b7 Multi\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1232872,\r\n  \"sha256\": \"3fa8801fe1973881cba6f24cfcefb770a01e172b25ed1d6024d62593af80d1a5\"\r\n },\r\n {\r\n  \"id\": \"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\r\n  \"label\": \"Genie \\u00b7 Multi 2\",\r\n  \"group\": \"Genie \\u00b7 Multi\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 486020,\r\n  \"sha256\": \"81516de182e04ccd2aff42982022720305003ae250731818e4c807130f86d7a0\"\r\n },\r\n {\r\n  \"id\": \"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\r\n  \"label\": \"Genie \\u00b7 Multi 3\",\r\n  \"group\": \"Genie \\u00b7 Multi\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 404608,\r\n  \"sha256\": \"c45fe5ed594bfe5618875a88b81287d4b78cd88ce4cbfcbfeab524fb199950e6\"\r\n },\r\n {\r\n  \"id\": \"roster/19-genie-multi--stylized_octopus_3d_model\",\r\n  \"label\": \"Genie \\u00b7 Multi 4\",\r\n  \"group\": \"Genie \\u00b7 Multi\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1149168,\r\n  \"sha256\": \"1de1dc93f31ce81ebddba811ba9afc0720cddacf5a71d27d5a6ea3bb5bbefba6\"\r\n },\r\n {\r\n  \"id\": \"roster/20-lume--robotic_figure_3d_model\",\r\n  \"label\": \"Lume 1\",\r\n  \"group\": \"Lume\",\r\n  \"status\": \"PASS\",\r\n  \"bytes\": 1128192,\r\n  \"sha256\": \"52d5d72a96ccd8c4b1ae5edee5bfe133721089f8a103165e338d9ecf4ae51fd8\"\r\n },\r\n {\r\n  \"id\": \"roster/21-flyer--winged_humanoid_3d_model\",\r\n  \"label\": \"Flyer 1\",\r\n  \"group\": \"Flyer\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 970008,\r\n  \"sha256\": \"ed9bc2771849efd9989db8d345f19fb7c2977a67b7a5f99b539a3d1586af5db6\"\r\n },\r\n {\r\n  \"id\": \"roster/22-curve--stylized_alien_3d_model\",\r\n  \"label\": \"Curve 1\",\r\n  \"group\": \"Curve\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1066308,\r\n  \"sha256\": \"79fcc10757118ba9cbe43a104a903767db6ef3c6ba4b74f687b79968d9215f3c\"\r\n },\r\n {\r\n  \"id\": \"roster/22-curve--stylized_cartoon_figure_3d_model\",\r\n  \"label\": \"Curve 2\",\r\n  \"group\": \"Curve\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 408364,\r\n  \"sha256\": \"29a98f87a59d70162391f46cf84b8d512c3bfa13099ae5c5fba3d04b95eec7d0\"\r\n },\r\n {\r\n  \"id\": \"roster/23-blob-texture-bodies--blob_creature_3d_model\",\r\n  \"label\": \"Blob 1\",\r\n  \"group\": \"Blob\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1084260,\r\n  \"sha256\": \"183f2eea968134b0b09e2b73e38457e4fd702f2b2ec7561f2421d563bc27357f\"\r\n },\r\n {\r\n  \"id\": \"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",\r\n  \"label\": \"Blob 2\",\r\n  \"group\": \"Blob\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 891128,\r\n  \"sha256\": \"50eb71a62fa688b8a154bb0ee045fba8d0b6a32d5c0870d3f97198716af99543\"\r\n },\r\n {\r\n  \"id\": \"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\r\n  \"label\": \"Blob 3\",\r\n  \"group\": \"Blob\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 980380,\r\n  \"sha256\": \"39ab0f0b383a1b030e071973a392ad3d899fdf247f8ccc84c55d26d574aa1181\"\r\n },\r\n {\r\n  \"id\": \"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\r\n  \"label\": \"Blob 4\",\r\n  \"group\": \"Blob\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 980212,\r\n  \"sha256\": \"aa15686e1e283593efd3c0f06c54c42bb0678700f4de0e83cce2b132dbf0e0fd\"\r\n },\r\n {\r\n  \"id\": \"roster/23-blob-texture-bodies--sand_creature_3d_model\",\r\n  \"label\": \"Blob 5\",\r\n  \"group\": \"Blob\",\r\n  \"status\": \"REVIEW\",\r\n  \"bytes\": 1226672,\r\n  \"sha256\": \"ef657be035523e56ee1a5f00bdd79816d223355e981463e996154b54bdf95187\"\r\n }\r\n]","creature/phone.css":".myr5-companion-card{position:absolute;right:8px;top:8px;width:132px;z-index:3;display:flex;flex-direction:column;align-items:stretch;border:1px solid #70568b80;border-radius:12px;background:#21162bc9;overflow:hidden;backdrop-filter:blur(6px)}.myr5-companion-stage{height:190px;width:100%;position:relative;background:radial-gradient(ellipse at 50% 50%,#51386d99,transparent 75%)}.myr5-companion-stage canvas{position:static!important;width:100%!important;height:100%!important;pointer-events:none}.myr5-companion-status{font-size:11px;color:#dac3ee;text-align:center;padding:0 5px 3px}.myr5-customize{font-size:12px;min-height:36px;display:flex;align-items:center;justify-content:center;color:#edd197;text-decoration:none;background:#362642}.myr5-companion-card .myr5-hide{font-size:11px;min-height:30px;border:0;border-top:1px solid #5a4472;background:#20162e;color:#d5c6e1;border-radius:0;padding:5px}.myr5-companion-card [hidden]{display:none!important}#view #hud{max-width:calc(100% - 158px)}@media(max-height:580px){.myr5-companion-stage{height:120px}.myr5-companion-card{width:108px}#view #hud{max-width:calc(100% - 134px)}}\r\n","creature/power-anchors.mjs":"// Project cached sole points after the coach's existing render has updated its animated matrices.\r\n// Callers supply reusable Three.js vectors so this adds no per-frame vector allocation.\r\nexport function projectAvatarPowerAnchors(anchors, camera, rootVisible, worldPoint, ndcPoint) {\r\n  return (anchors ?? []).map(({ index, node, local }) => {\r\n    worldPoint.copy(local).applyMatrix4(node.matrixWorld);\r\n    ndcPoint.copy(worldPoint).project(camera);\r\n    const x = (ndcPoint.x + 1) * 0.5, y = (1 - ndcPoint.y) * 0.5;\r\n    const visible = !!rootVisible && node.visible !== false && Number.isFinite(x) && Number.isFinite(y)\r\n      && ndcPoint.x >= -1 && ndcPoint.x <= 1 && ndcPoint.y >= -1 && ndcPoint.y <= 1\r\n      && ndcPoint.z >= -1 && ndcPoint.z <= 1;\r\n    return { index, x, y, visible };\r\n  });\r\n}\r\n","creature/preview-window.css":"/* The coach has the whole pane; information sits on its glass instead of reserving space. */\r\n.preview-bay .preview-stage{position:absolute;inset:0;min-height:0}\r\n.preview-bay::after{content:'';position:absolute;inset:0;z-index:1;pointer-events:none;border-radius:inherit;background:linear-gradient(115deg,#b8dcf51c 0%,#bdcee008 28%,transparent 43%,#796aab0c 76%,#150e2e24),linear-gradient(180deg,#a4c9e20e,transparent 36%,#140b2314);box-shadow:inset 0 1px 0 #d9eeff45,inset 0 0 20px #0b082640}\r\n.preview-bay .preview-readout{position:absolute;top:0;left:0;right:0;padding:10px 12px;background:linear-gradient(#1b142ad9,#1b142a00);z-index:3}\r\n.preview-bay .preview-toolbar{position:absolute;bottom:0;left:0;right:0;z-index:3;gap:6px;padding:8px 10px;background:linear-gradient(transparent,#191022c9 30%);border-top:0}\r\n.preview-bay .preview-readout,.preview-bay .preview-toolbar,.preview-bay .preview-strip{opacity:1;transition:opacity .25s ease}\r\n.preview-bay[data-idle=true] .preview-readout,.preview-bay[data-idle=true] .preview-strip{opacity:0;pointer-events:none}\r\n/* zoom, Front, Back and Pause stay visible and tappable when idle: hiding them let the first tap fall through to the canvas (R-1016 bug 4). */\r\n.preview-bay[data-idle=false] .preview-readout,.preview-bay[data-idle=false] .preview-strip{transition:none}\r\n.preview-bay .preview-strip{z-index:3}\r\n@media(prefers-reduced-motion:reduce){.preview-bay .preview-readout,.preview-bay .preview-toolbar,.preview-bay .preview-strip{transition:none}}\r\n","creature/source/cage.ts":"// W4-4E (#116, D45/D47): the customizer cage. futuristic-weapons.glb, decimated to one optional download packet\r\n// ('room-cage', scripts/offline-assets.mjs), shown around the live coach only once this phone has downloaded it.\r\n// It adds meshes to the editor's own CreatureViewer scene, so there is no second renderer or render loop; the\r\n// viewer already skips frames while the page is hidden or the stage is off screen. Any failure (no packet,\r\n// decoder, asset) removes the cage and leaves the flat customizer exactly as it was.\r\nimport * as T from 'three';\r\nimport {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport {DRACOLoader} from 'three/examples/jsm/loaders/DRACOLoader.js';\r\nimport {battlePassState} from '../../battle-pass.mjs';\r\nimport {availablePetChoices,selectedPetChoice,selectPetChoice,PET_CHOICE_SCOPE_LABEL} from '../../pet-choice.mjs';\r\nimport {mountWeaponWall} from './weapon-wall.mjs';\r\nimport {sparkle} from '../../unlock-seen.mjs';\r\nimport type {CreatureViewer} from './viewer';\r\n\r\nexport const CAGE_BASE='/pod/rooms/cage/';\r\nexport const CAGE_FILES=['cage.glb','draco_wasm_wrapper.js','draco_decoder.wasm'].map(file=>CAGE_BASE+file);\r\nexport type CageSection='overview'|'pedestal'|'pets'|'weapons'|'mirror'|'clothing';\r\n// The supplied cage is one Tripo mesh with no named bays, so each section is an explicit hit volume measured\r\n// from the decimated model (glTF units, y up): centre x,y,z · size x,y,z · yaw. Scale 8 turns the pedestal\r\n// (radius .18, top y .17) into the viewer's own 1.45 floor disc, with the coach's feet on its top.\r\ntype Volume=readonly [number,number,number,number,number,number,number];\r\nconst SCALE=8,PEDESTAL=[.02,.17,-.01] as const;\r\nconst VOLUMES:Record<Exclude<CageSection,'overview'>,Volume[]>={\r\n pedestal:[[.02,.42,-.01,.3,.5,.3,0]],\r\n pets:[[-.31,.15,.075,.1,.16,.1,0],[-.22,.15,.23,.1,.16,.1,0],[-.04,.15,.33,.1,.16,.1,0],[.16,.15,.3,.1,.16,.1,0],[.245,.15,.17,.1,.16,.1,0]],\r\n weapons:[[-.27,.48,-.24,.47,.45,.05,.54]],\r\n mirror:[[.345,.39,-.21,.39,.64,.05,-.88]],\r\n clothing:[[.06,.32,-.31,.16,.5,.1,0]],\r\n};\r\n// Where each view looks from (a direction from the section toward the camera) and what it keeps in frame.\r\nconst VIEWS:Record<CageSection,{from:[number,number,number];coach:boolean;pad:number}>={\r\n overview:{from:[0,.5,1],coach:true,pad:.5},\r\n pedestal:{from:[0,.18,1],coach:true,pad:1.02},\r\n pets:{from:[.1,.95,1],coach:false,pad:1},\r\n weapons:{from:[-.1,.2,1],coach:false,pad:1},\r\n mirror:{from:[-.7,.2,.7],coach:true,pad:1},\r\n clothing:{from:[0,.45,1],coach:true,pad:1},\r\n};\r\nexport const SECTIONS:{id:CageSection;label:string;name:string}[]=[\r\n {id:'overview',label:'Cage',name:'Whole cage'},\r\n {id:'pedestal',label:'Coach',name:'Coach pedestal: species'},\r\n {id:'pets',label:'Pets',name:'Pet cages'},\r\n {id:'weapons',label:'Weapons',name:'Weapon wall'},\r\n {id:'mirror',label:'Mirror',name:'Mirror: colours'},\r\n {id:'clothing',label:'Clothes',name:'Clothing bay'},\r\n];\r\n\r\n// Only this release's downloaded package counts (\"the 2D editor works until the packet is downloaded\"); an\r\n// on-demand fetch never pulls a megabyte into the customizer. Opening only names that exist creates nothing.\r\nexport async function cagePacketReady(){\r\n try{\r\n  if(!globalThis.caches)return false;\r\n  const names=(await caches.keys()).filter(name=>name.startsWith('myr5-package-'));\r\n  for(const url of CAGE_FILES){let found=false;for(const name of names)if(await(await caches.open(name)).match(url)){found=true;break;}if(!found)return false;}\r\n  return true;\r\n }catch{return false;}\r\n}\r\n\r\nconst CSS='.cage-bays{position:absolute;left:6px;right:6px;bottom:6px;z-index:2;display:flex;gap:4px;overflow-x:auto;scrollbar-width:none;padding:2px}.cage-bays button{flex:1 1 auto;min-height:36px;min-width:44px;padding:4px 2px;font-size:.75rem;border-radius:7px;background:linear-gradient(#3b4f58,#22303a);border-color:#6fd6e3;color:#dff9ff;box-shadow:inset 0 1px #bff4ff33,0 2px 0 #0b1216}.cage-bays button[aria-pressed=true]{background:linear-gradient(#9ff2ff,#46b6c6);color:#07252b;border-color:#dffcff}.cage-offer{position:absolute;right:8px;bottom:8px;z-index:2;min-height:32px;padding:4px 10px;font-size:.75rem}#panel-bay ul{margin:8px 0;padding-left:20px}#panel-bay li+li{margin-top:4px}#panel-bay h3{margin:12px 0 4px;font-size:.95rem}.pet-choices{display:flex;flex-wrap:wrap;gap:6px;margin:8px 0}.pet-choices button{min-height:44px;min-width:44px}.pet-choices button[aria-pressed=true]{outline:2px solid #6fd6e3}#panel-bay .bay-error{color:#ffb4a8}.gala-loadout{margin-top:14px;padding-top:8px;border-top:1px solid #6fd6e3}.gala-loadout .cage-weapon-wall{display:grid;gap:8px}.gala-loadout .cage-weapon-wall h2{display:none}.gala-loadout .cage-weapon-wall :is(select,input,button){min-height:44px}#panel-bay .bay-locked{color:var(--muted)}@media(max-width:700px){.editor-shell[data-cage=ready] .editor-workspace{grid-template-rows:minmax(220px,48%) minmax(0,1fr)}}';\r\n\r\nlet styled:HTMLStyleElement|null=null;\r\nexport function cageStyle(){if(!styled?.isConnected){styled=document.createElement('style');styled.textContent=CSS;document.head.append(styled);}}\r\n// onClose runs when the bay stops being shown (another bay, a console tab, or the cage going away).\r\n// The War Room's Gala bay passes bay and labels: its own menus replace the coach's tabs and bays for every section.\r\nexport type CageHooks={openTab:(menu:'body'|'materials')=>boolean;showBay:(title:string,kicker:string,body:Node,onClose?:()=>void)=>void;closeBay?:()=>void;tell:(text:string)=>void;\r\n bay?:(section:Exclude<CageSection,'overview'>)=>void;labels?:Partial<Record<CageSection,{label:string;name:string}>>;volumes?:Partial<Record<Exclude<CageSection,'overview'>,Volume[]>>};\r\n// What the cage needs from a stage: the coach's CreatureViewer, or the War Room's Gala stage.\r\nexport type CageViewer=Pick<CreatureViewer,'mount'|'renderer'|'camera'|'orbit'|'scene'|'bodyBounds'|'floorObjects'|'settings'|'resize'|'focused'>;\r\ntype Owned={id:string;name:string;boss:string;level:number;granted:boolean};\r\nfunction rewards(kind:'pet'|'weapon'):Owned[]{\r\n const seen=new Map<string,Owned>();\r\n for(const boss of battlePassState().bosses)for(const reward of boss.rewards)for(const item of reward.items)if(item.kind===kind){\r\n  const prior=seen.get(item.id);if(!prior||item.granted&&!prior.granted)seen.set(item.id,{id:item.id,name:item.name,boss:boss.name,level:reward.level,granted:!!item.granted});\r\n }\r\n return [...seen.values()];\r\n}\r\nconst el=<K extends keyof HTMLElementTagNameMap>(tag:K,text='',cls='')=>{const e=document.createElement(tag);if(text)e.textContent=text;if(cls)e.className=cls;return e;};\r\nconst ul=(rows:Owned[],cls:string,text:(i:Owned)=>string)=>{if(!rows.length)return null;const list=el('ul','',cls);for(const row of rows)list.append(el('li',text(row)));return list;};\r\nconst lockedList=(rows:Owned[])=>ul(rows,'bay-locked',i=>`🔒 ${i.name} · ${i.boss} level ${i.level}`);\r\nconst help=(text:string)=>el('p',text,'help');\r\n// Pet cages: a device-local preference over the pets this device has been granted (pet-choice.mjs). Every\r\n// render re-reads it, so a pet that is no longer granted drops back to None. Nothing is granted or saved to the coach.\r\nfunction petBay(body:HTMLElement,focusId?:string|null){\r\n const choices=availablePetChoices(),chosen=selectedPetChoice().petId,ids=new Set(choices.map(c=>c.id));\r\n const status=el('p',`${choices.find(c=>c.id===chosen)?.name??'None'}: ${PET_CHOICE_SCOPE_LABEL}`);status.setAttribute('role','status');status.dataset.petStatus='';\r\n const group=el('div','','pet-choices');group.setAttribute('role','group');group.setAttribute('aria-label','Pet choice');\r\n for(const choice of choices){\r\n  const b=el('button',choice.name+(choice.id===chosen?` · ${PET_CHOICE_SCOPE_LABEL}`:''));b.type='button';b.dataset.petChoice=choice.id??'';\r\n  b.setAttribute('aria-pressed',String(choice.id===chosen));\r\n  b.onclick=()=>{const saved=selectPetChoice(choice.id);petBay(body,choice.id);if(!saved){const e=el('p','This choice could not be saved. Storage is unavailable on this device.','bay-error');e.setAttribute('role','alert');body.prepend(e);}};\r\n  if(choice.id)sparkle(b,'pet',choice.id);\r\n  group.append(b);\r\n }\r\n const held=rewards('pet'),parts:(Node|null)[]=[status,group,lockedList(held.filter(p=>!ids.has(p.id))),\r\n  help('Only pets you have earned appear as choices. Your choice is kept on this device only; it grants nothing and does not change your coach. No pet appears with your coach yet.')];\r\n if(!held.length)parts.splice(2,0,help('No pets yet. Each workout path’s first boss gives one at level 4.'));\r\n body.replaceChildren(...parts.filter(Boolean) as Node[]);\r\n if(focusId!==undefined)(body.querySelector(`[data-pet-choice=\"${focusId??''}\"]`) as HTMLElement|null)?.focus();\r\n}\r\n// Battle-pass weapons are device rewards, shown as earned or locked. The Gala War Room loadout is a different,\r\n// account-owned thing: its form is the adapter's, saves only on its own button, and is disposed with the bay.\r\nfunction weaponBay(body:HTMLElement){\r\n const items=rewards('weapon'),owned=items.filter(i=>i.granted),reward=el('section');\r\n reward.append(el('h3','Battle-pass weapons'),el('p',owned.length?`You have earned ${owned.length} of ${items.length} on this device.`:'No weapons yet. Workout path bosses give them at levels 1 and 3.'));\r\n const earned=ul(owned,'bay-owned',i=>`${i.name} · earned`);owned.forEach((item,n)=>sparkle(earned!.children[n] as HTMLElement,'weapon',item.id));\r\n for(const list of [earned,lockedList(items.filter(i=>!i.granted))])if(list)reward.append(list);\r\n reward.append(help('These rewards are not Gala weapons and are never sent to the War Room.'));\r\n const gala=el('section','','gala-loadout');gala.dataset.galaLoadout='';gala.append(el('h3','Gala War Room loadout'),help('A separate, account-owned loadout for your account, alongside your earned rewards. It saves only when you press Save loadout, and needs a connection.'));\r\n const host=el('div');gala.append(host);body.append(reward,gala);\r\n let wall:ReturnType<typeof mountWeaponWall>|null=null;\r\n try{wall=mountWeaponWall({host});}catch{host.append(help('The Gala loadout is unavailable right now.'));}\r\n return ()=>{wall?.dispose();wall=null;};\r\n}\r\n// Pets and weapons here are device rewards; the pet choice is a device preference. Nothing writes the coach recipe,\r\n// and the only War Room call is the weapon form's own read and Save.\r\nexport function sectionBay(section:'pets'|'weapons'|'clothing'):[string,string,Node,(()=>void)?]{\r\n const body=el('div');\r\n if(section==='pets'){petBay(body);return ['Pet cages','PETS',body];}\r\n if(section==='weapons')return ['Weapon wall','WEAPONS',body,weaponBay(body)];\r\n body.append(help('Nothing to wear yet. This empty bay is kept for coach clothing when it arrives.'));return ['Clothing bay','CLOTHING',body];\r\n}\r\n\r\nexport function mountCage(viewer:CageViewer,hooks:CageHooks){\r\n const stage=viewer.mount,shell=stage.closest('.editor-shell') as HTMLElement|null;cageStyle();\r\n const bays=document.createElement('div');bays.className='cage-bays';bays.setAttribute('role','group');bays.setAttribute('aria-label','Cage sections');bays.hidden=true;stage.append(bays);\r\n const buttons=new Map<CageSection,HTMLButtonElement>();\r\n for(const s of SECTIONS){const b=document.createElement('button'),own=hooks.labels?.[s.id];b.type='button';b.textContent=own?.label??s.label;b.setAttribute('aria-label',own?.name??s.name);b.dataset.cageSection=s.id;b.setAttribute('aria-pressed','false');b.onclick=()=>select(s.id);bays.append(b);buttons.set(s.id,b);}\r\n let root:T.Group|null=null,disposed=false,current:CageSection|null=null,tween=0;const hits:T.Mesh[]=[],outlines=new Map<CageSection,T.LineSegments[]>();\r\n const set=(state:string)=>{if(shell)shell.dataset.cage=state;};\r\n const world=(x:number,y:number,z:number)=>new T.Vector3((x-PEDESTAL[0])*SCALE,(y-PEDESTAL[1])*SCALE,(z-PEDESTAL[2])*SCALE);\r\n function boxOf(section:CageSection){\r\n  const box=new T.Box3();\r\n  if(section==='overview'&&root)box.setFromObject(root);\r\n  for(const mesh of hits)if(mesh.userData.section===section)box.expandByObject(mesh);\r\n  if(VIEWS[section].coach&&!viewer.bodyBounds.isEmpty())box.union(viewer.bodyBounds);\r\n  return box;\r\n }\r\n function frame(section:CageSection){\r\n  const box=boxOf(section),center=box.getCenter(new T.Vector3()),radius=box.getSize(new T.Vector3()).length()/2,camera=viewer.camera;\r\n  const v=T.MathUtils.degToRad(camera.fov/2),h=Math.atan(Math.tan(v)*camera.aspect),distance=radius*VIEWS[section].pad/Math.sin(Math.min(v,h));\r\n  // Lift the framed bay above the button row that sits over the bottom of the stage.\r\n  center.y-=distance*Math.tan(v)*(bays.offsetHeight+6)/Math.max(1,stage.clientHeight);\r\n  return {target:center,position:center.clone().addScaledVector(new T.Vector3(...VIEWS[section].from).normalize(),distance)};\r\n }\r\n // A short camera glide (none with reduced or Still motion). It only moves the camera; the viewer draws.\r\n function move(section:CageSection){\r\n  cancelAnimationFrame(tween);tween=0;viewer.focused=null;\r\n  const to=frame(section),camera=viewer.camera,orbit=viewer.orbit;\r\n  if(viewer.settings.reduced){camera.position.copy(to.position);orbit.target.copy(to.target);orbit.update();return;}\r\n  const p0=camera.position.clone(),t0=orbit.target.clone(),start=performance.now();\r\n  const step=(now:number)=>{if(disposed)return;const k=Math.min(1,(now-start)/650),e=k<.5?2*k*k:1-(-2*k+2)**2/2;camera.position.lerpVectors(p0,to.position,e);orbit.target.lerpVectors(t0,to.target,e);orbit.update();tween=k<1?requestAnimationFrame(step):0;};\r\n  tween=requestAnimationFrame(step);\r\n }\r\n function select(section:CageSection){\r\n  if(!root||disposed)return;current=section;\r\n  for(const [id,b] of buttons)b.setAttribute('aria-pressed',String(id===section));\r\n  for(const [id,lines] of outlines)for(const line of lines)line.visible=id===section;\r\n  move(section);\r\n  if(hooks.bay){if(section==='overview')hooks.closeBay?.();else hooks.bay(section);}\r\n  else if(section==='pedestal')hooks.openTab('body');\r\n  else if(section==='mirror')hooks.openTab('materials');\r\n  else if(section!=='overview'){const [title,kicker,body,onClose]=sectionBay(section);hooks.showBay(title,kicker,body,onClose);}\r\n }\r\n // Tap (not drag) a bay in the scene: the same action as its button.\r\n const raycaster=new T.Raycaster(),canvas=viewer.renderer.domElement;let down:{x:number;y:number;t:number}|null=null;\r\n function pick(clientX:number,clientY:number):CageSection|null{\r\n  const r=canvas.getBoundingClientRect();if(!r.width||!r.height)return null;\r\n  raycaster.setFromCamera(new T.Vector2((clientX-r.left)/r.width*2-1,-(clientY-r.top)/r.height*2+1),viewer.camera);\r\n  return raycaster.intersectObjects(hits,false)[0]?.object.userData.section??null;\r\n }\r\n const onDown=(e:PointerEvent)=>{down={x:e.clientX,y:e.clientY,t:performance.now()};};\r\n const onUp=(e:PointerEvent)=>{const d=down;down=null;if(!d||!root||Math.hypot(e.clientX-d.x,e.clientY-d.y)>8||performance.now()-d.t>500)return;const section=pick(e.clientX,e.clientY);if(section)select(section);};\r\n canvas.addEventListener('pointerdown',onDown);canvas.addEventListener('pointerup',onUp);\r\n function teardown(){\r\n  cancelAnimationFrame(tween);tween=0;\r\n  if(root){viewer.scene.remove(root);root.traverse(node=>{const mesh=node as T.Mesh;mesh.geometry?.dispose();for(const m of ([] as T.Material[]).concat(mesh.material||[])){for(const value of Object.values(m))if((value as T.Texture)?.isTexture)(value as T.Texture).dispose();m.dispose();}});root=null;}\r\n  hooks.closeBay?.();hits.length=0;outlines.clear();viewer.floorObjects.forEach(o=>o.visible=true);bays.hidden=true;\r\n }\r\n function dispose(){if(disposed)return;disposed=true;teardown();canvas.removeEventListener('pointerdown',onDown);canvas.removeEventListener('pointerup',onUp);bays.remove();}\r\n set('loading');\r\n const ready=(async()=>{\r\n  const draco=new DRACOLoader();\r\n  try{\r\n   draco.setDecoderPath(CAGE_BASE);draco.setDecoderConfig({type:'wasm'});\r\n   const loader=new GLTFLoader();loader.setDRACOLoader(draco);\r\n   const gltf=await loader.loadAsync(CAGE_BASE+'cage.glb');\r\n   if(disposed){gltf.scene.traverse(node=>{(node as T.Mesh).geometry?.dispose();});return false;}\r\n   root=new T.Group();root.name='customizer-cage';\r\n   gltf.scene.scale.setScalar(SCALE);gltf.scene.position.copy(world(0,0,0));root.add(gltf.scene);\r\n   const hidden=new T.MeshBasicMaterial({visible:false}),edge=new T.LineBasicMaterial({color:0x7eeaff,transparent:true,opacity:.85});\r\n   for(const [section,volumes] of Object.entries({...VOLUMES,...hooks.volumes}) as [CageSection,Volume[]][])for(const [x,y,z,sx,sy,sz,yaw] of volumes){\r\n    const geometry=new T.BoxGeometry(sx*SCALE,sy*SCALE,sz*SCALE),mesh=new T.Mesh(geometry,hidden);\r\n    mesh.position.copy(world(x,y,z));mesh.rotation.y=yaw;mesh.userData.section=section;mesh.name='cage-'+section;\r\n    const line=new T.LineSegments(new T.EdgesGeometry(geometry),edge);line.visible=false;mesh.add(line);\r\n    hits.push(mesh);(outlines.get(section)??outlines.set(section,[]).get(section)!).push(line);root.add(mesh);\r\n   }\r\n   root.updateMatrixWorld(true);viewer.scene.add(root);viewer.floorObjects.forEach(o=>o.visible=false);\r\n   // The phone layout gives the stage more room once the cage is up; size the camera to it before framing.\r\n   bays.hidden=false;set('ready');viewer.resize();select('overview');\r\n   return true;\r\n  }catch(error){\r\n   if(disposed)return false;\r\n   teardown();bays.remove();set('failed');hooks.tell('The 3D cage could not load on this device. The customizer works as usual.');console.warn('Customizer cage unavailable',error);\r\n   return false;\r\n  }finally{draco.dispose();}\r\n })();\r\n return {ready,select,dispose,pick,get section(){return current;},\r\n  // Tests and the phone frame check: where a section's hit volume lands on screen right now.\r\n  project(section:CageSection){const mesh=hits.find(m=>m.userData.section===section);if(!mesh)return null;const p=mesh.getWorldPosition(new T.Vector3()).project(viewer.camera),r=canvas.getBoundingClientRect();return {x:r.left+(p.x+1)/2*r.width,y:r.top+(1-p.y)/2*r.height};}};\r\n}\r\n","creature/source/cinematic-shots.ts":"export const SHOTS = {\r\n opening: {duration:4800, gesture:'awaken', frames:[[-1.7,1.6,7.7,1.65],[-.6,2.25,7.2,1.82],[0,2.65,8.9,1.95]]},\r\n pre: {duration:3300, gesture:'ready', frames:[[.85,2.35,8.5,1.87],[.2,2.15,7.5,1.87],[0,2.65,8.9,1.95]]},\r\n post: {duration:3800, gesture:'victory', frames:[[-.6,2.1,7.4,2.1],[.25,2.35,8.1,2.1],[0,2.1,5.8,2.25]]}\r\n} as const;\r\nexport type Cinematic=keyof typeof SHOTS;\r\nexport function sampleShot(kind:Cinematic,elapsed:number){\r\n const s=SHOTS[kind],u=Math.max(0,Math.min(1,elapsed/s.duration)),segment=Math.min(1,Math.floor(u*2));\r\n const t=u*2-segment,e=t*t*(3-2*t),a=s.frames[segment],b=s.frames[segment+1];\r\n return a.map((v,i)=>v+(b[i]-v)*e);\r\n}\r\n","creature/source/conor-pelvis-ownership.ts":"import * as THREE from 'three';\r\nimport { triangleSubset } from './limb-ownership';\r\n\r\nconst CONOR_PELVIS_SOURCE='roster/05-slope-bobble--clay_humanoid_figure_3d_model';\r\nconst WAIST_Y=.715;\r\nconst WAIST_HALF_WIDTH=.68;\r\n\r\n/** Move the central lower torso bowl out of Conor's feet cut while leaving both leg tubes intact. */\r\nexport function correctConorPelvisOwnership(source:THREE.Group,sourceId:string):number{\r\n if(sourceId!==CONOR_PELVIS_SOURCE)return 0;\r\n source.updateWorldMatrix(true,true);\r\n const body=source.getObjectByName('body'),feet=source.getObjectByName('feet');\r\n if(!body||!feet)return 0;\r\n let bodyMaterial:THREE.Material|undefined;\r\n body.traverse(o=>{if(!bodyMaterial&&o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))bodyMaterial=o.material;});\r\n if(!bodyMaterial)return 0;\r\n const intoBody=body.matrixWorld.clone().invert();\r\n const meshes:THREE.Mesh[]=[];feet.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))meshes.push(o);});\r\n let moved=0;\r\n for(const mesh of meshes){\r\n  const geometry=mesh.geometry,position=geometry.getAttribute('position'),index=geometry.index,selected=new Set<number>();\r\n  const meshToWorld=mesh.matrixWorld;\r\n  const triangleCount=index?index.count/3:position.count/3;\r\n  for(let face=0;face<triangleCount;face++){\r\n   let x=0,y=0;\r\n   for(let k=0;k<3;k++){\r\n    const vertex=index?index.getX(face*3+k):face*3+k;\r\n    const p=new THREE.Vector3().fromBufferAttribute(position,vertex).applyMatrix4(meshToWorld);\r\n    x+=p.x/3;y+=p.y/3;\r\n   }\r\n   if(y>=WAIST_Y&&Math.abs(x)<WAIST_HALF_WIDTH)selected.add(face);\r\n  }\r\n  if(!selected.size)continue;\r\n  const bodyPart=triangleSubset(geometry,face=>selected.has(face)),remainder=triangleSubset(geometry,face=>!selected.has(face));\r\n  if(!bodyPart)continue;\r\n  bodyPart.applyMatrix4(intoBody.clone().multiply(meshToWorld));\r\n  moved+=selected.size;\r\n  if(remainder){mesh.geometry=remainder;geometry.dispose();}else{mesh.removeFromParent();geometry.dispose();}\r\n  const recovered=new THREE.Mesh(bodyPart,bodyMaterial);\r\n  recovered.name='Conor recovered central pelvis';\r\n  recovered.userData.region='body';\r\n  recovered.userData.conorRecoveredPelvisTriangles=selected.size;\r\n  body.add(recovered);\r\n }\r\n source.updateWorldMatrix(true,true);\r\n source.userData.conorRecoveredPelvisTriangles=moved;\r\n return moved;\r\n}\r\n","creature/source/creator/anatomy.ts":"import * as THREE from 'three';\r\nimport {EYE_LAYOUTS,EYE_REFERENCE,type EyeLayout} from './eye-layouts';\r\nimport {EYE_CENTER} from './eye-surface';\r\n// Layouts are authored around MYR5's head. `offset` moves the whole arrangement onto another head and\r\n// `scale` shrinks or grows spacing and eye size around the reference eye together. `surfaceZ`, set for heads\r\n// without MYR5's carved sockets, seats each front-facing eye on that surface instead of recessing it.\r\nexport function eyePosition([x,y,z,r,yaw]:readonly number[],offset:THREE.Vector3,scale:number,surfaceZ?:number){\r\n const px=EYE_REFERENCE.x+(x-EYE_REFERENCE.x)*scale+offset.x,py=EYE_REFERENCE.y+(y-EYE_REFERENCE.y)*scale+offset.y;\r\n const pz=surfaceZ!==undefined&&yaw===0?surfaceZ-r*scale*.55:EYE_REFERENCE.z+(z-EYE_REFERENCE.z)*scale+offset.z;\r\n return [px,py,pz];\r\n}\r\nexport function arrangeEyes(template:THREE.Group,layout:EyeLayout,offset:THREE.Vector3=new THREE.Vector3(),scale=1,surfaceZ?:number){\r\n const group=new THREE.Group();group.name='Eye arrangement';\r\n for(const [i,eye] of EYE_LAYOUTS[layout].eyes.entries()){\r\n  const [,,,r,yaw]=eye;const instance=new THREE.Group();instance.name='Eye '+(i+1);\r\n  instance.position.fromArray(eyePosition(eye,offset,scale,surfaceZ));\r\n  instance.rotation.y=THREE.MathUtils.degToRad(yaw);instance.scale.setScalar(r/.605*scale);\r\n  const content=template.clone(true);content.visible=true;content.position.copy(EYE_CENTER).negate();instance.add(content);group.add(instance);\r\n }\r\n return group;\r\n}\r\n","creature/source/creator/assemble.ts":"import {goldenCoach} from '../../../performance-progress.mjs';\r\nimport {arrangeEyes} from './anatomy';\r\nimport {EYE_LAYOUTS,EYE_REFERENCE,EYE_SCALE_DEFAULT} from './eye-layouts';\r\nimport {EYE_OVERRIDES} from './eye-overrides';\r\nimport {pupilGeometry} from './pupils';\r\nimport {getCoach} from './coaching';\r\nimport {prepareEyeMesh,conformEyeMesh,bloodshotVeins,LID_RADIUS} from './eye-surface';\r\nimport {sculptMaterial,growMaterial,applySparkle,applyPaletteSurface} from './material-language';\r\nimport {boneSockets,skeletalStructure,materialCollar,robotStructure} from './skeletal-anatomy';\r\nimport {colorTriad,resolveRegionMaterial,regionChoice} from './materials-registry';\r\nimport {applyInstalledSkin,loadInstalledSkinTextures,type InstalledSkin,type SkinTextureCache} from './skin-materials';\r\nimport {createCoachReliefBudget} from './material-refinement';\r\n\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader,type GLTF} from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/examples/jsm/libs/meshopt_decoder.module.js';\r\nimport {REGIONS,STYLES,type Region,type Design} from './design';\r\nimport {deformMesh} from './deform';\r\nimport {armBodyBandTriangles,armBodyTriangles,armFootTriangles,connectedTriangleComponents,detachedHandTriangles,groundedComponentsBelowBodyCut,triangleSubset} from '../limb-ownership';\r\nimport {correctQuadrupedOwnership} from '../quadruped-ownership';\r\nimport {correctRousArmOwnership} from '../rous-ownership';\r\nimport {inferGroundedSidePlaneX} from '../rig';\r\nimport {correctPetalWispArmOwnership} from '../petal-wisp-ownership';\r\nimport {correctConorPelvisOwnership} from '../conor-pelvis-ownership';\r\nimport {correctTorsoPanelOwnership} from '../torso-panel-ownership';\r\n\r\n// Adapted from the existing MYR5 AlienViewer. The app and editor use this assembly.\r\nconst modelBuffers=new Map<string,Promise<ArrayBuffer>>();\r\nfunction bytes(url:string){if(!modelBuffers.has(url))modelBuffers.set(url,fetch(url).then(response=>{if(!response.ok)throw Error('Creature model is unavailable.');return response.arrayBuffer();}).catch(error=>{modelBuffers.delete(url);throw error;}));return modelBuffers.get(url)!;}\r\n\r\ntype Fit={s:number;t:THREE.Vector3};\r\nconst clamp=(v:number,lo:number,hi:number)=>Math.max(lo,Math.min(hi,v));\r\n// These roster entries are continuous shell creatures. Their source \"arms\" are body\r\n// surface panels, and their broad bases are not separately articulated feet.\r\nconst BODY_OWNED_LIMBS=new Set([\r\n 'roster/12-seedpod-snailslug--stylized_slug_3d_model',\r\n 'roster/23-blob-texture-bodies--cute_blob_creature_3d_model',\r\n // Their broad body cuts already contain the real appendages. The nominal\r\n // arms are isolated shell strips/tips, so rotating those alone tears the shell.\r\n 'roster/12-seedpod-snailslug--stylized_worm_3d_model',\r\n 'roster/19-genie-multi--fantasy_creature_3d_model',\r\n 'roster/19-genie-multi--stylized_octopus_3d_model',\r\n]);\r\nconst BODY_OWNED_FEET=new Set([\r\n 'roster/12-seedpod-snailslug--stylized_worm_3d_model',\r\n 'roster/10-petal-wisp--ghost_character_3d_model',\r\n 'roster/10-petal-wisp--fantasy_creature_3d_model4',\r\n 'roster/19-genie-multi--fantasy_creature_3d_model',\r\n 'roster/19-genie-multi--stylized_octopus_3d_model',\r\n]);\r\nconst BLOB_SPLIT_OWNERSHIP='roster/23-blob-texture-bodies--blob_creature_3d_model';\r\nconst OLIVA_CENTER_BRIDGE='roster/06-ridge-triad--geometric_robot_3d_model1';\r\nconst PEC_UPPER_ARM_CHAIN='roster/08-shard-asym--geometric_robot_3d_model';\r\nconst BOLT_HAND_COMPONENTS='roster/07-bulb-sphereling--humanoid_robot_3d_model';\r\nconst REASPIRE_HIP_SLIVER='roster/14-chisel-spire--low_poly_robot_3d_model';\r\nconst MULTI_ARM_TORSO_EDGE='roster/19-genie-multi--multi-armed_humanoid_3d_model1';\r\nconst PEARL_RING_UNDERARM_STRIPS=new Set(['roster/03-pearl-orb-ring--circle_center','roster/03-pearl-orb-ring--ringed_humanoid_3d_model']);\r\nconst GHOST4_BODY_CONTACT_FRAGMENT='roster/10-petal-wisp--fantasy_creature_3d_model4';\r\nconst ROUS_SIDE_PLANE_SOURCE='roster/09-monolith-tanka--robot_3d_model2';\r\nfunction boxOf(object:THREE.Object3D|undefined){const box=new THREE.Box3();if(object){object.updateWorldMatrix(true,true);box.setFromObject(object);}return box;}\r\n/** Correct source-region arm cuts before fitting or applying chosen region styles. */\r\nexport function correctArmFootOwnership(source:THREE.Group,sourceId:string){\r\n if(sourceId.startsWith('roster/18-quad-all--'))return 0;\r\n source.updateWorldMatrix(true,true);const arms=source.getObjectByName('arms'),feet=source.getObjectByName('feet'),body=source.getObjectByName('body');if(!arms||!feet||!body)return 0;\r\n const feetMeshes:THREE.Mesh[]=[],bodyMeshes:THREE.Mesh[]=[];feet.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible)feetMeshes.push(o);});body.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible)bodyMeshes.push(o);});if(!feetMeshes.length||!bodyMeshes.length)return 0;\r\n const feetBox=new THREE.Box3();for(const mesh of feetMeshes)feetBox.expandByObject(mesh);\r\n const bodyBox=new THREE.Box3();for(const mesh of bodyMeshes)bodyBox.expandByObject(mesh);\r\n const footMaterial=feetMeshes.find(m=>!Array.isArray(m.material))?.material,bodyMaterial=bodyMeshes.find(m=>!Array.isArray(m.material))?.material;if(!footMaterial||Array.isArray(footMaterial)||!bodyMaterial||Array.isArray(bodyMaterial))return 0;\r\n let moved=0;const armMeshes:THREE.Mesh[]=[];arms.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))armMeshes.push(o);});\r\n  for(const mesh of armMeshes){let active=mesh.geometry;const blobSplit=sourceId===BLOB_SPLIT_OWNERSHIP;const footIds=blobSplit||BODY_OWNED_FEET.has(sourceId)?new Set<number>():armFootTriangles(mesh,feetBox,feetMeshes,{bodyLowerY:bodyBox.min.y});\r\n  // Pec-n0ld's arm-foot classifier selects a 581-face source-ARMS component,\r\n  // while the measured mirrored counterpart remains in arms. Keep the complete\r\n  // pair under arm ownership so both arms animate; match by source bounds and\r\n  // component size rather than assuming triangle indices.\r\n  if(sourceId===PEC_UPPER_ARM_CHAIN&&footIds.size){\r\n    const components=connectedTriangleComponents(mesh),componentBounds=(ids:number[])=>{const box=new THREE.Box3(),p=mesh.geometry.getAttribute('position'),index=mesh.geometry.index;for(const id of ids)for(let k=0;k<3;k++)box.expandByPoint(new THREE.Vector3().fromBufferAttribute(p,index?index.getX(id*3+k):id*3+k).applyMatrix4(mesh.matrixWorld));return box;},all=components.map(ids=>({ids,selected:ids.filter(id=>footIds.has(id)).length,box:componentBounds(ids)})),centerX=bodyBox.getCenter(new THREE.Vector3()).x,keep=new Set<number>();\r\n    for(const candidate of all){if(candidate.selected!==candidate.ids.length||candidate.ids.length<500)continue;const a=candidate.box;\r\n      for(const opposite of all){if(opposite===candidate||opposite.selected||opposite.ids.length<500)continue;const b=opposite.box,ratio=candidate.ids.length/opposite.ids.length;\r\n        const mirrored=Math.abs((a.min.x-centerX)+(b.max.x-centerX))<.045&&Math.abs((a.max.x-centerX)+(b.min.x-centerX))<.045;\r\n        const aligned=Math.abs(a.min.y-b.min.y)<.08&&Math.abs(a.max.y-b.max.y)<.08&&Math.abs(a.getSize(new THREE.Vector3()).x-b.getSize(new THREE.Vector3()).x)<.04;\r\n        if(mirrored&&aligned&&ratio>.85&&ratio<1.15){for(const id of candidate.ids)keep.add(id);break;}\r\n      }\r\n    }\r\n    for(const id of keep)footIds.delete(id);\r\n  }\r\n  if(footIds.size){const selected=triangleSubset(active,id=>footIds.has(id)),remaining=triangleSubset(active,id=>!footIds.has(id));if(selected){moved+=footIds.size;if(remaining){mesh.geometry=remaining;active.dispose();active=remaining;}else{mesh.removeFromParent();active.dispose();active=null as any;}\r\n   const intoFeet=feet.matrixWorld.clone().invert().multiply(mesh.matrixWorld);selected.applyMatrix4(intoFeet);const footMesh=new THREE.Mesh(selected,footMaterial);footMesh.name='Recovered foot section';footMesh.userData.recoveredArmFootTriangles=footIds.size;feet.add(footMesh);}}\r\n  if(!active)continue;\r\n    const triangleCount=(active.index?.count??active.getAttribute('position').count)/3;\r\n    const bodyOptions=sourceId===MULTI_ARM_TORSO_EDGE?{bodyUpperFraction:.425}:undefined;\r\n    // Pec-n0ld's 137- and 64-face side components close the upper arm that\r\n    // continues through the retained 581-face lower-arm component. They touch\r\n    // Body geometrically but belong to the arm chain in the source cut.\r\n    const tailCutIds=new Set<number>(),bodyIds=blobSplit?new Set(Array.from({length:triangleCount},(_,i)=>i)):sourceId===PEC_UPPER_ARM_CHAIN?new Set<number>():armBodyTriangles(mesh,bodyBox,bodyMeshes,bodyOptions);if(BODY_OWNED_FEET.has(sourceId)){const cutTolerance=Math.max(.002,(bodyBox.max.y-bodyBox.min.y)*.002);for(const id of groundedComponentsBelowBodyCut(mesh,bodyBox.min.y,feetBox,cutTolerance))if(!bodyIds.has(id)){bodyIds.add(id);tailCutIds.add(id);}\r\n      // Continuous tail creatures may contain small proximal web panels in the\r\n      // animated arms source. Move only faces whose complete corner set is\r\n      // within a tight source-surface tolerance of the body in its lower band;\r\n      // distal fingers and tentacle surfaces remain arm-owned.\r\n      for(const id of armBodyBandTriangles(mesh,bodyBox,bodyMeshes,{bodyUpperFraction:.45,contactTolerance:.03,allVerticesOnBody:true}))bodyIds.add(id);\r\n    }\r\n    if(PEARL_RING_UNDERARM_STRIPS.has(sourceId))for(const id of armBodyBandTriangles(mesh,bodyBox,bodyMeshes,{bodyUpperFraction:.45}))bodyIds.add(id);\r\n    // This second ghost has a detached 66-face plate touching the body's crown\r\n    // at a measured vertex seam; move just that complete component to BodyMotion.\r\n    if(sourceId===GHOST4_BODY_CONTACT_FRAGMENT){\r\n      const p=mesh.geometry.getAttribute('position'),index=mesh.geometry.index,bodyVertices:THREE.Vector3[]=[];\r\n      for(const bodyMesh of bodyMeshes){const bp=bodyMesh.geometry.getAttribute('position');for(let i=0;i<bp.count;i++)bodyVertices.push(new THREE.Vector3().fromBufferAttribute(bp,i).applyMatrix4(bodyMesh.matrixWorld));}\r\n      for(const component of connectedTriangleComponents(mesh)){if(component.length>100)continue;const box=new THREE.Box3(),vertices=new Map<number,THREE.Vector3>();\r\n        for(const id of component)for(let k=0;k<3;k++){const vi=index?index.getX(id*3+k):id*3+k;if(!vertices.has(vi))vertices.set(vi,new THREE.Vector3().fromBufferAttribute(p,vi).applyMatrix4(mesh.matrixWorld));box.expandByPoint(vertices.get(vi)!);}\r\n        if(box.min.y<bodyBox.max.y-.25||box.max.y>bodyBox.max.y+.02)continue;\r\n        let nearest=Infinity;for(const v of vertices.values())for(const bv of bodyVertices)nearest=Math.min(nearest,v.distanceTo(bv));\r\n        if(nearest<=.015)for(const id of component)bodyIds.add(id);\r\n      }\r\n    }\r\n    if(!bodyIds.size)continue;\r\n  const bodyPart=triangleSubset(active,id=>bodyIds.has(id)),armPart=triangleSubset(active,id=>!bodyIds.has(id));if(!bodyPart)continue;\r\n  moved+=bodyIds.size;if(armPart){mesh.geometry=armPart;active.dispose();}else mesh.removeFromParent();\r\n  const intoBody=body.matrixWorld.clone().invert().multiply(mesh.matrixWorld);bodyPart.applyMatrix4(intoBody);const bodyMesh=new THREE.Mesh(bodyPart,bodyMaterial);bodyMesh.name='Recovered torso section';bodyMesh.userData.recoveredArmBodyTriangles=bodyIds.size;if(tailCutIds.size)bodyMesh.userData.recoveredTailCutTriangles=tailCutIds.size;body.add(bodyMesh);if(!armPart)active.dispose();\r\n }\r\n source.updateWorldMatrix(true,true);return moved;\r\n}\r\n/** Move only verified detached hand components that were authored in a feet cut. */\r\nexport function correctFootHandOwnership(source:THREE.Group,sourceId:string){\r\n  if(BODY_OWNED_LIMBS.has(sourceId)||BODY_OWNED_FEET.has(sourceId)||sourceId.startsWith('roster/18-quad-all--'))return 0;\r\n source.updateWorldMatrix(true,true);const arms=source.getObjectByName('arms'),feet=source.getObjectByName('feet'),body=source.getObjectByName('body');if(!arms||!feet||!body)return 0;\r\n const meshes=(group:THREE.Object3D)=>{const out:THREE.Mesh[]=[];group.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))out.push(o);});return out;};\r\n const footMeshes=meshes(feet),armMeshes=meshes(arms),bodyMeshes=meshes(body);if(!footMeshes.length||!armMeshes.length||!bodyMeshes.length)return 0;\r\n const feetBox=new THREE.Box3(),armsBox=new THREE.Box3(),bodyBox=new THREE.Box3();for(const m of footMeshes)feetBox.expandByObject(m);for(const m of armMeshes)armsBox.expandByObject(m);for(const m of bodyMeshes)bodyBox.expandByObject(m);\r\n const bodyHeight=bodyBox.max.y-bodyBox.min.y;if(!(bodyHeight>0))return 0;\r\n const lowerBody=new THREE.Box3(),lowerCap=bodyBox.min.y+bodyHeight*.35;\r\n for(const mesh of bodyMeshes){const p=mesh.geometry.getAttribute('position'),index=mesh.geometry.index,count=index?.count??p.count;for(let i=0;i<count;i++){const v=new THREE.Vector3().fromBufferAttribute(p,index?index.getX(i):i).applyMatrix4(mesh.matrixWorld);if(v.y<=lowerCap)lowerBody.expandByPoint(v);}}\r\n if(lowerBody.isEmpty())return 0;\r\n let moved=0;\r\n for(const mesh of footMeshes){const selected=detachedHandTriangles(mesh,feetBox,footMeshes,armsBox,armMeshes,bodyBox,bodyMeshes,lowerBody,{maxComponentTriangles:sourceId===BOLT_HAND_COMPONENTS?1500:600});\r\n  if(!selected.size)continue;const original=mesh.geometry,hand=triangleSubset(original,id=>selected.has(id)),remaining=triangleSubset(original,id=>!selected.has(id));if(!hand)continue;\r\n  const p=original.getAttribute('position'),index=original.index,center=new THREE.Vector3();for(const id of selected)for(let k=0;k<3;k++)center.add(new THREE.Vector3().fromBufferAttribute(p,index?index.getX(id*3+k):id*3+k).applyMatrix4(mesh.matrixWorld));center.divideScalar(selected.size*3);\r\n  let armMaterialMesh=armMeshes[0],nearest=Infinity;for(const candidate of armMeshes){const box=new THREE.Box3().setFromObject(candidate),candidateCenter=box.getCenter(new THREE.Vector3()),distance=center.distanceToSquared(candidateCenter);if(distance<nearest){nearest=distance;armMaterialMesh=candidate;}}\r\n  moved+=selected.size;if(remaining){mesh.geometry=remaining;original.dispose();}else{mesh.removeFromParent();original.dispose();}\r\n  const intoArms=arms.matrixWorld.clone().invert().multiply(mesh.matrixWorld);hand.applyMatrix4(intoArms);const handMesh=new THREE.Mesh(hand,armMaterialMesh.material as THREE.Material);handMesh.name='Recovered hand section';handMesh.userData.recoveredFootHandTriangles=selected.size;arms.add(handMesh);\r\n }\r\n source.updateWorldMatrix(true,true);return moved;\r\n}\r\n/** Blob1's high, cross-center pelvis bowl is authored in `feet` but must follow BodyMotion. */\r\nexport function correctBlobPelvisOwnership(source:THREE.Group,sourceId:string){\r\n if(sourceId!==BLOB_SPLIT_OWNERSHIP&&sourceId!==OLIVA_CENTER_BRIDGE)return 0;\r\n source.updateWorldMatrix(true,true);const feet=source.getObjectByName('feet'),body=source.getObjectByName('body');if(!feet||!body)return 0;\r\n const feetMeshes:THREE.Mesh[]=[],bodyMeshes:THREE.Mesh[]=[];feet.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))feetMeshes.push(o);});body.traverse(o=>{if(o instanceof THREE.Mesh&&o.visible&&!Array.isArray(o.material))bodyMeshes.push(o);});\r\n if(!feetMeshes.length||!bodyMeshes.length)return 0;const bodyBox=new THREE.Box3();for(const mesh of bodyMeshes)bodyBox.expandByObject(mesh);const bodySize=bodyBox.getSize(new THREE.Vector3()),bodyCenter=bodyBox.getCenter(new THREE.Vector3());if(bodySize.x<=0||bodySize.y<=0)return 0;\r\n const bodyMaterial=bodyMeshes[0].material as THREE.Material;let moved=0;\r\n for(const mesh of feetMeshes){const components=connectedTriangleComponents(mesh),selected=new Set<number>();\r\n  for(const component of components){const box=new THREE.Box3(),center=new THREE.Vector3(),position=mesh.geometry.getAttribute('position'),index=mesh.geometry.index;\r\n   for(const id of component)for(let k=0;k<3;k++){const v=new THREE.Vector3().fromBufferAttribute(position,index?index.getX(id*3+k):id*3+k).applyMatrix4(mesh.matrixWorld);box.expandByPoint(v);center.add(v);}\r\n   center.divideScalar(component.length*3);const spansCenter=box.min.x<bodyCenter.x-bodySize.x*.08&&box.max.x>bodyCenter.x+bodySize.x*.08,contactsBodyBottom=box.max.y>=bodyBox.min.y-bodySize.y*.025&&box.min.y<bodyBox.min.y+bodySize.y*.04,central=Math.abs(center.x-bodyCenter.x)<bodySize.x*.18;\r\n   if(spansCenter&&contactsBodyBottom&&central)for(const id of component)selected.add(id);\r\n  }\r\n  if(!selected.size)continue;const original=mesh.geometry,part=triangleSubset(original,id=>selected.has(id)),remaining=triangleSubset(original,id=>!selected.has(id));if(!part)continue;\r\n  moved+=selected.size;if(remaining){mesh.geometry=remaining;original.dispose();}else{mesh.removeFromParent();original.dispose();}\r\n  const intoBody=body.matrixWorld.clone().invert().multiply(mesh.matrixWorld);part.applyMatrix4(intoBody);const bodyPart=new THREE.Mesh(part,bodyMaterial);bodyPart.name='Recovered center pelvis';bodyPart.userData.recoveredPelvisTriangles=selected.size;body.add(bodyPart);\r\n }\r\n source.updateWorldMatrix(true,true);return moved;\r\n}\r\n\r\nexport type RosterSourceRepairReport={armOwnershipTriangles:number;handOwnershipTriangles:number;pelvisTriangles:number;petalWispArmTriangles:number;conorPelvisTriangles:number;torsoPanelTriangles:number;quadrupedRepaired:boolean};\r\n/** Run the complete source-only ownership repair chain before models are mixed or fitted. */\r\nexport function repairRosterSource(source:THREE.Group,sourceId:string):RosterSourceRepairReport{\r\n const report:RosterSourceRepairReport={armOwnershipTriangles:0,handOwnershipTriangles:0,pelvisTriangles:0,petalWispArmTriangles:0,conorPelvisTriangles:0,torsoPanelTriangles:0,quadrupedRepaired:false};\r\n if(!sourceId.startsWith('roster/'))return report;\r\n report.armOwnershipTriangles=sourceId.startsWith('roster/18-quad-all--')?0:sourceId===ROUS_SIDE_PLANE_SOURCE?correctRousArmOwnership(source,sourceId):correctArmFootOwnership(source,sourceId);\r\n for(let pass=0;pass<4;pass++){const moved=correctFootHandOwnership(source,sourceId);report.handOwnershipTriangles+=moved;if(!moved)break;}\r\n report.pelvisTriangles=correctBlobPelvisOwnership(source,sourceId);\r\n report.quadrupedRepaired=correctQuadrupedOwnership(source,sourceId);\r\n report.petalWispArmTriangles=correctPetalWispArmOwnership(source,sourceId);\r\n report.conorPelvisTriangles=correctConorPelvisOwnership(source,sourceId);\r\n report.torsoPanelTriangles=correctTorsoPanelOwnership(source,sourceId);\r\n return report;\r\n}\r\n\r\nexport type InstalledSkinResolver=(id:string)=>Promise<InstalledSkin|null>;\r\n// `preview` paints locked textures/colours (the editor's unsaved look-before-you-unlock layer).\r\nexport async function assembleCreature(d:Design,assetBase:string,resolveInstalledSkin?:InstalledSkinResolver,preview=false){\r\n // The build meshopt-compresses these models (scripts/optimize-glb.mjs).\r\n const loader=new GLTFLoader().setMeshoptDecoder(MeshoptDecoder);\r\n const look=(region:Region)=>resolveRegionMaterial(d.styles[region],regionChoice(d.materials,region),preview,d.body);\r\n const load=async(name:string)=>loader.parseAsync(await bytes(assetBase+'models/'+name+'.glb'),assetBase+'models/');\r\n // Each region can come from a different creature. A GLTF scene can only give each node away once,\r\n // so every distinct source id is parsed once and reused across the regions that name it.\r\n const from:Record<Region,string>={head:d.headFrom,eye:'myr5',collar:d.body,body:d.body,arms:d.armsFrom,feet:d.feetFrom};\r\n const extraIds=[...new Set(REGIONS.map(r=>from[r]).filter(id=>id!=='myr5'))];\r\n const [gltf,anatomy,hands,...extras]=await Promise.all([load('myr5'),load('anatomy'),load('hands-v2'),...extraIds.map(load)]);\r\n const installedSkins=new Map<Region,InstalledSkin>();\r\n if(resolveInstalledSkin)for(const region of REGIONS){const id=d.materials?.[region]?.textureId;if(!id?.startsWith('creature-'))continue;try{const skin=await resolveInstalledSkin(id);if(skin?.id===id)installedSkins.set(region,skin);}catch{/* Missing, revoked, offline, or untrusted optional packs fail closed to built-in materials. */}}\r\n const skinTextures=new Set<THREE.Texture>(),skinTextureCache:SkinTextureCache=new Map();\r\n const sources=new Map<string,GLTF>([['myr5',gltf],...extraIds.map((id,i)=>[id,extras[i]] as [string,GLTF])]);\r\n const scene=(id:string)=>sources.get(id)!.scene;\r\n\r\n // Repair only roster-sourced arms. Their lower fragments are detected against the same\r\n // model's actual feet cut boundary before sources are mixed or material styling is applied.\r\n // If another coach supplies feet, the selected arm source's recovered feet are excluded;\r\n // the chosen feet source owns that region in the assembled coach.\r\n for(const id of extraIds)repairRosterSource(scene(id),id);\r\n\r\n // Fit every limb region onto the chosen body. Boxes are measured in each source's own space before\r\n // any node moves. Pure single-source creatures (the original MYR5 included) keep identity transforms.\r\n const mixed=new Set([d.body,d.headFrom,d.armsFrom,d.feetFrom]).size>1;\r\n const fits={} as Record<Region,Fit>;for(const r of REGIONS)fits[r]={s:1,t:new THREE.Vector3()};\r\n const bodyBox=boxOf(scene(d.body).getObjectByName('body'));\r\n const headBox=boxOf(scene(d.headFrom).getObjectByName('head'));\r\n if(mixed){\r\n  const size=new THREE.Vector3(),own=new THREE.Vector3(),c=new THREE.Vector3(),oc=new THREE.Vector3();bodyBox.getSize(size);bodyBox.getCenter(c);\r\n  const fit=(id:string,anchorY:(b:THREE.Box3)=>number):Fit=>{\r\n   const ob=boxOf(scene(id).getObjectByName('body'));ob.getSize(own);ob.getCenter(oc);\r\n   const s=clamp(size.x/Math.max(own.x,1e-3),.6,1.6);\r\n   return {s,t:new THREE.Vector3(c.x-oc.x*s,anchorY(bodyBox)-anchorY(ob)*s,c.z-oc.z*s)};\r\n  };\r\n  fits.head=fit(d.headFrom,b=>b.max.y);fits.arms=fit(d.armsFrom,b=>b.max.y);fits.feet=fit(d.feetFrom,b=>b.min.y);\r\n  // Stand the assembled creature back on the floor.\r\n  const feetBottom=boxOf(scene(d.feetFrom).getObjectByName('feet')).min.y*fits.feet.s+fits.feet.t.y;\r\n  for(const r of REGIONS)fits[r].t.y-=feetBottom;\r\n }\r\n fits.eye=fits.head;\r\n\r\n // Eyes: the proven layout table is tuned to MYR5's head. Move it to the chosen head's eye anchor and\r\n // scale it by head width so the layouts keep their proportions on every head.\r\n const myr5HeadWidth=boxOf(gltf.scene.getObjectByName('head')).getSize(new THREE.Vector3()).x||1;\r\n const headWidth=headBox.getSize(new THREE.Vector3()).x*fits.head.s;\r\n const baseEyeScale=d.headFrom==='myr5'?fits.head.s:clamp(headWidth/myr5HeadWidth,.5,1.2);\r\n const eyeOverride=EYE_OVERRIDES[d.headFrom];\r\n // Global eye-scale multiplier (handoff §5, ~0.65) applies to roster heads only: MYR5's own head has eye\r\n // sockets carved for its native eye size (see eye-layouts.ts), so it stays at its own fitted scale.\r\n const globalEyeScale=d.headFrom==='myr5'?1:EYE_SCALE_DEFAULT;\r\n const eyeScale=eyeOverride?.eyeScale??baseEyeScale*globalEyeScale;\r\n const reference=new THREE.Vector3(EYE_REFERENCE.x,EYE_REFERENCE.y,EYE_REFERENCE.z);\r\n if(d.headFrom!=='myr5')scene(d.headFrom).updateMatrixWorld(true);\r\n const anchor=d.headFrom==='myr5'?null:scene(d.headFrom).getObjectByName('eye_anchor');\r\n const anchorWorld=anchor?anchor.getWorldPosition(new THREE.Vector3()):null;\r\n // flipX mirrors the head's own geometry (below); the anchor lives outside that node (a root sibling,\r\n // per the roster GLB contract) so its X has to be corrected here to keep the eyes on the mirrored side.\r\n if(anchorWorld&&eyeOverride?.flipX)anchorWorld.x=-anchorWorld.x;\r\n const eyeCenter=anchorWorld?anchorWorld.clone().sub(new THREE.Vector3(0,0,.605*eyeScale)):reference.clone();\r\n eyeCenter.multiplyScalar(fits.head.s).add(fits.head.t);\r\n // Roster heads have no carved sockets: remember their front surface so eyes sit on it, not inside it.\r\n const surfaceZ=anchorWorld?anchorWorld.z*fits.head.s+fits.head.t.z:undefined;\r\n // Anchor-derived offset first; a per-variant eyeOffset override (once the owner supplies one from the\r\n // before/after renders) nudges it afterward rather than replacing the anchor's own placement.\r\n const eyeOffset=eyeCenter.sub(reference);\r\n if(eyeOverride?.eyeOffset)eyeOffset.add(new THREE.Vector3(...eyeOverride.eyeOffset));\r\n const eyeMoved=eyeOffset.lengthSq()>1e-8||Math.abs(eyeScale-1)>1e-4;\r\n\r\n const root=new THREE.Group(),details=new THREE.Group(),coachRelief=createCoachReliefBudget();details.name='Style ornaments';root.add(details);\r\n // Keep source-local points on Rous's grounded-foot split until each selected region\r\n // has its final fit/facing transform. The region's own matrixWorld then accounts for\r\n // source offsets, fit translation/scale, and any local X mirror in one operation.\r\n const rousPlaneLocal:Partial<Record<'arms'|'feet',THREE.Vector3>>={};\r\n const rousPlaneSources:Partial<Record<'arms'|'feet',THREE.Object3D>>={};\r\n if(extraIds.includes(ROUS_SIDE_PLANE_SOURCE)){\r\n  const rousScene=scene(ROUS_SIDE_PLANE_SOURCE),feet=rousScene.getObjectByName('feet')??rousScene,footBox=boxOf(feet),feetPlane=inferGroundedSidePlaneX(feet);\r\n  const arms=rousScene.getObjectByName('arms'),armBox=boxOf(arms);\r\n  for(const region of ['arms','feet'] as const)if(d[region==='arms'?'armsFrom':'feetFrom']===ROUS_SIDE_PLANE_SOURCE){const sourceRegion=rousScene.getObjectByName(region),referenceBox=region==='arms'?armBox:footBox,point=new THREE.Vector3(feetPlane,referenceBox.getCenter(new THREE.Vector3()).y,referenceBox.getCenter(new THREE.Vector3()).z);if(sourceRegion){sourceRegion.updateWorldMatrix(true,false);rousPlaneSources[region]=sourceRegion;rousPlaneLocal[region]=sourceRegion.worldToLocal(point);}}\r\n }\r\n const materials:THREE.MeshStandardMaterial[]=[];\r\n    const regions={} as Record<Region,THREE.Group>;\r\n for(const region of REGIONS){const source=scene(from[region]).getObjectByName(region);if(!source){throw Error('A creature section could not load.');}\r\n    // Facing correction (handoff §5 flipX): mirror this region's own geometry in its local space. The eye\r\n    // region is excluded — it always comes from MYR5's own template (see `from.eye` above), never the\r\n    // flagged roster source, and the eye anchor's X is corrected separately above.\r\n    if(region!=='eye'&&EYE_OVERRIDES[from[region]]?.flipX){source.scale.x*=-1;source.traverse(o=>{const name=o.userData.rigNodeName;if(typeof name==='string'&&/^(Arm|Foot)(Left|Right)$/.test(name))o.userData.rigNodeName=name.endsWith('Left')?name.replace(/Left$/,'Right'):name.replace(/Right$/,'Left');});}\r\n    const wrapper=new THREE.Group();wrapper.name=region;root.add(wrapper);regions[region]=wrapper;\r\n    const bodyOwned=(region==='arms'||region==='feet')&&BODY_OWNED_LIMBS.has(from[region])||(region==='feet'&&BODY_OWNED_FEET.has(from[region]));\r\n    const materialRegion=bodyOwned?'body':region;\r\n    if(bodyOwned){const bodyWrapper=regions.body,fit=fits[region],bodyFit=fits.body,relative=new THREE.Group();relative.name='BodyOwned '+region;relative.position.copy(fit.t).sub(bodyFit.t).divideScalar(bodyFit.s);relative.scale.setScalar(fit.s/bodyFit.s);bodyWrapper.add(relative);relative.add(source);}\r\n    else wrapper.add(source);\r\n    source.traverse(o=>{if(o instanceof THREE.Mesh){if(region==='eye')prepareEyeMesh(o);o.userData.region=materialRegion;o.userData.basePosition=o.position.clone();o.userData.baseScale=o.scale.clone();o.material=(o.material as THREE.MeshStandardMaterial).clone();const m=o.material as THREE.MeshStandardMaterial;m.userData={baseColor:m.color.clone(),baseRough:m.roughness,baseMetal:m.metalness,name:m.name};materials.push(m);}});}\r\n   const lid=new THREE.Mesh(new THREE.SphereGeometry(LID_RADIUS,48,24,0,Math.PI*2,0,.57),new THREE.MeshStandardMaterial({color:STYLES[0].primary,roughness:.58}));lid.position.copy(reference);lid.name='Expression eyelid';lid.userData.region='eye';const eyeTemplate=regions.eye.children[0] as THREE.Group;eyeTemplate.add(lid);\r\n   // R25 eye styles: squinty adds a lower lid (below); bloodshot adds veins that conform to the globe like the iris.\r\n   if(d.eye==='bloodshot'){const veinMaterial=new THREE.MeshStandardMaterial({color:'#b0122b',roughness:.42,side:THREE.DoubleSide,polygonOffset:true,polygonOffsetFactor:-1});veinMaterial.userData={baseColor:veinMaterial.color.clone(),baseRough:.42,baseMetal:0,name:'Eye vein'};const veins=new THREE.Mesh(bloodshotVeins(),veinMaterial);veins.name='Eye vein';veins.userData={region:'eye',basePosition:veins.position.clone(),baseScale:veins.scale.clone()};eyeTemplate.add(veins);}\r\n   // MYR5's anatomy variants (eye-socket crowns, finger and toe counts) only apply to regions MYR5 supplies.\r\n   const variants=new Map<string,THREE.Object3D>();if(from.head==='myr5')variants.set('head_single',regions.head.children[0]);if(regions.arms.children[0])variants.set('original_arms',regions.arms.children[0]);if(regions.feet.children[0])variants.set('original_feet',regions.feet.children[0]);\r\n   for(const object of [...anatomy.scene.children].filter(o=>!o.name.startsWith('arms_')).concat([...hands.scene.children])){const region=object.name.split('_')[0] as Region;object.traverse(o=>{if(o instanceof THREE.Mesh){o.userData.region=region;o.userData.basePosition=o.position.clone();o.userData.baseScale=o.scale.clone();o.material=(o.material as THREE.MeshStandardMaterial).clone();const m=o.material as THREE.MeshStandardMaterial;m.userData={baseColor:m.color.clone(),baseRough:m.roughness,baseMetal:m.metalness,name:m.name};}});object.removeFromParent();variants.set(object.name,object);}\r\n\r\n const e={root,regions,details,lid,materials,variants,eyeTemplate,eyeCopies:null as THREE.Group|null};\r\n const hologram=false,parts=false;\r\n   if(e.eyeCopies){e.regions.eye.remove(e.eyeCopies);e.eyeCopies=null;}e.eyeTemplate.visible=true;\r\n  for(const [region,key] of [['head','head_'+d.eyeLayout],['arms','arms_'+d.fingers],['feet','feet_'+d.toes]] as const){if(from[region]!=='myr5')continue;const variant=e.variants.get(key);if(variant&&e.regions[region].children[0]!==variant){e.regions[region].clear();e.regions[region].add(variant);}if(region==='head')variant?.traverse(o=>{o.userData.eyeSockets=EYE_LAYOUTS[d.eyeLayout].eyes;});}\r\n  const fittedSidePlanes:Partial<Record<'arms'|'feet',number>>={};\r\n  for(const region of REGIONS){const style=look(region),group=e.regions[region];\r\n   // The eye region is placed by arrangeEyes below, so its wrapper stays at the origin.\r\n   group.position.set(0,0,0);group.scale.setScalar(1);if(region!=='eye'){group.position.copy(fits[region].t);group.scale.setScalar(fits[region].s);}\r\n   if((region==='arms'||region==='feet')&&rousPlaneLocal[region]){const sourceRegion=rousPlaneSources[region]!;sourceRegion.updateWorldMatrix(true,false);fittedSidePlanes[region]=sourceRegion.localToWorld(rousPlaneLocal[region]!.clone()).x;}\r\n   if(parts){const offsets:Record<Region,number[]>={head:[0,.65,0],eye:[0,.18,1.0],collar:[0,-.1,0],body:[0,-.45,0],arms:[.45,0,0],feet:[0,-.65,0]};group.position.add(new THREE.Vector3().fromArray(offsets[region]));}\r\n   group.traverse(o=>{if(!(o instanceof THREE.Mesh)||o===e.lid)return;const m=o.material as THREE.MeshStandardMaterial;const base=m.userData.baseColor as THREE.Color;const name=m.userData.name as string;const fixed=['Eye ivory','Pupil','Eye glint','Eye vein'].includes(name);\r\n    m.color.copy(base);m.emissive.set(0);m.metalness=m.userData.baseMetal;m.roughness=m.userData.baseRough;m.transparent=false;m.opacity=1;m.depthWrite=true;\r\n    if(style.id!==0&&!fixed){m.color.set(name==='Lilac hair'||name==='Raised scales'?style.accent:style.primary);if(name==='Socket shadow'||name==='Body velvet')m.color.multiplyScalar(.43);m.roughness=style.roughness;m.metalness=style.metalness;m.emissive.set(style.emissive).multiplyScalar(.25);}\r\n    if(hologram){m.color.set(fixed&&name==='Pupil'?'#261336':'#c9b0ea');m.emissive.set('#76518f');m.emissiveIntensity=.55;m.roughness=.25;m.metalness=.1;}\r\n    if(o.name==='Pupil'&&o.userData.pupilType!==d.pupil){o.geometry.dispose();o.geometry=pupilGeometry(d.pupil);o.userData.basePosition=new THREE.Vector3(.04,2.1475,1.183);o.userData.baseScale=new THREE.Vector3(1,1,1);o.userData.pupilType=d.pupil;}\r\n    if(o.name==='Iris'&&o.userData.irisType!==d.pupil){o.geometry.dispose();o.geometry=pupilGeometry(d.pupil);o.geometry.scale(1.48,1.48,1);o.userData.basePosition=new THREE.Vector3(.04,2.1475,1.133);o.userData.baseScale=new THREE.Vector3(1,1,1);o.userData.irisType=d.pupil;}\r\n    if(/^Iris.fiber/.test(o.name))o.visible=d.pupil==='round';\r\n    if(/^Crown.scale/.test(o.name))o.visible=d.styles[region]===0;\r\n    deformMesh(o,region,d);if(region==='eye')conformEyeMesh(o);else if(o.visible){const customSkin=d.materials?.[region]?.textureId?.startsWith('creature-')??false,alternate=from[region]!=='myr5'&&!customSkin;if(style.id!==0){sculptMaterial(o,style,1,d.detail,alternate?coachRelief:undefined);applySparkle(o.material as THREE.MeshPhysicalMaterial,style.sparkle);}}\r\n    if(o.name==='Iris'){const p=o.geometry.attributes.position,colors=new Float32Array(p.count*3);for(let j=0;j<p.count;j++){const a=Math.atan2(p.getY(j),p.getX(j)),r=Math.hypot(p.getX(j),p.getY(j));const shade=.78+.16*Math.sin(a*117+r*35)+.06*Math.cos(a*61);colors[j*3]=shade;colors[j*3+1]=shade;colors[j*3+2]=Math.min(1,shade+.07);}o.geometry.setAttribute('color',new THREE.BufferAttribute(colors,3));m.vertexColors=true;m.needsUpdate=true;}\r\n    if(style.paletteId&&!fixed&&(region==='eye'&&o.name==='Iris'||region!=='eye'&&style.id===0))applyPaletteSurface(m,style);\r\n    // R25: bloodshot whites blush pink; blind eyes are milky, with no pupil or iris fibres.\r\n    if(region==='eye'&&d.eye==='bloodshot'&&name==='Eye ivory')m.color.lerp(new THREE.Color('#ff9c9c'),.28);\r\n    // R25 eye extras, on top of any style: black whites, and a centre in a light shade of the Eyes colour.\r\n    if(region==='eye'&&d.blackSclera&&name==='Eye ivory'){m.color.set('#09080c');m.roughness=.16;}\r\n    if(region==='eye'&&d.colourPupil&&o.name==='Pupil')m.color.set(style.id!==0?style.accent:STYLES[0].accent);\r\n    if(region==='eye'&&d.eye==='blind'){if(o.name==='Pupil'||/^Iris.fiber/.test(o.name))o.visible=false;if(o.name==='Iris'){m.map=null;m.color.set('#dfe7ea');m.roughness=.3;m.needsUpdate=true;}}\r\n   });\r\n  }\r\n  if(Object.keys(fittedSidePlanes).length)root.userData.limbSidePlanes=fittedSidePlanes;\r\n  const cap=({sleepy:1.56,wide:.30,anime:.22,squinty:1.28,bloodshot:.78,blind:.66} as Record<string,number>)[d.eye]??.57;e.lid.geometry.dispose();e.lid.geometry=new THREE.SphereGeometry(LID_RADIUS,48,24,0,Math.PI*2,0,cap);(e.lid.material as THREE.MeshStandardMaterial).color.set(hologram?'#c9b0ea':look('head').primary);\r\n  if(d.eye==='squinty'){const lower=new THREE.Mesh(new THREE.SphereGeometry(LID_RADIUS,48,24,0,Math.PI*2,0,1.2).rotateX(Math.PI),e.lid.material);lower.position.copy(e.lid.position);lower.name='Expression lower eyelid';lower.userData.region='eye';e.eyeTemplate.add(lower);}\r\n  if(d.eyeLayout!=='single'||eyeMoved){e.eyeCopies=arrangeEyes(e.eyeTemplate,d.eyeLayout,eyeOffset,eyeScale,surfaceZ);e.regions.eye.add(e.eyeCopies);e.eyeTemplate.visible=false;}\r\n  const key=JSON.stringify([d.styles,d.detail,d.eyeLayout,d.fingers,d.toes,d.body,d.headFrom,d.armsFrom,d.feetFrom,hologram,parts]);e.details.userData.key=key;\r\n  e.details.children.slice().forEach(o=>{o.traverse(c=>{if(c instanceof THREE.Mesh){c.geometry.dispose();(c.material as THREE.Material).dispose();}});e.details.remove(o);});\r\n  for(const region of REGIONS){\r\n   const style=look(region),original=e.regions[region];\r\n   // Bone and robot structures are sculpted around MYR5's own proportions, so roster parts keep their mesh.\r\n   const own=from[region]==='myr5';\r\n   if(own&&style.id===7&&region!=='head'&&region!=='eye'){original.visible=false;e.details.add(skeletalStructure(region,d));continue;}\r\n   if(own&&style.id===18&&['body','arms','feet'].includes(region)){original.visible=false;e.details.add(robotStructure(region,d));continue;}\r\n   let surface=original;\r\n   // materialCollar()/STYLES only know legacy ids 1-22 (0 and 20 are excluded on purpose above);\r\n   // Flat/Clay/battle-pass family ids (30, 31, -1) fall outside that range and must skip this swap.\r\n   if(own&&region==='collar'&&style.id>0&&style.id<=22&&style.id!==20){original.visible=false;surface=materialCollar(style.id);e.details.add(surface);}\r\n   const growth=growMaterial(surface,style,region,1,d.detail);growth.position.copy(surface.position);growth.scale.copy(surface.scale);e.details.add(growth);\r\n  }\r\n  if(from.head==='myr5'&&look('head').id===7){e.regions.eye.visible=false;e.details.add(boneSockets(d));}\r\n // Animation pivots fitted to this creature's measured parts; the rig falls back to MYR5's own numbers.\r\n root.updateMatrixWorld(true);\r\n const measured=(r:Region)=>boxOf(e.regions[r]);\r\n const pivots=d.body==='myr5'&&!mixed?null:(()=>{\r\n  const b=measured('body'),h=measured('head'),a=measured('arms'),f=measured('feet');\r\n  const hip=Math.max(.2,f.max.y),neck=Math.max(hip+.2,h.min.y),shoulder=a.isEmpty()?hip:clamp(a.max.y-(a.max.y-a.min.y)*.12,hip,neck);\r\n  return {body:[0,hip,0],head:[0,neck-hip,0],arm:a.isEmpty()?[0,0,0]:[Math.max(.15,b.max.x*.9),shoulder-hip,0],foot:f.isEmpty()?[0,0,0]:[Math.max(.08,(f.max.x-f.min.x)*.25),hip*.44,0]};\r\n })();\r\n // Retain unused variants for cleanup after geometry is baked into the animation rig.\r\n const disposeAssembly=()=>{const geometries=new Set<THREE.BufferGeometry>(),mats=new Set<THREE.Material>();for(const object of [root,...variants.values(),anatomy.scene,hands.scene,...[...sources.values()].map(s=>s.scene)])object.traverse(o=>{if(o instanceof THREE.Mesh){geometries.add(o.geometry);for(const m of Array.isArray(o.material)?o.material:[o.material])mats.add(m);}});geometries.forEach(g=>g.dispose());mats.forEach(m=>m.dispose());};\r\n for(const [region,skin]of installedSkins){const selected=regionChoice(d.materials,region),triad=colorTriad(selected?.colorId||'#7f7d78',preview,d.body)??colorTriad('#7f7d78')!,group=e.regions[region];\r\n  let meshes:THREE.Mesh[]=[];group.traverse(object=>{if(object instanceof THREE.Mesh)meshes.push(object);});\r\n  try{await loadInstalledSkinTextures(skin,skinTextures,skinTextureCache);}catch{/* Optional corrupted skin: this whole region keeps its built-in materials. */continue;}\r\n  const previous=meshes.map(mesh=>({mesh,material:mesh.material})),stagedMaterials=new Set<THREE.Material>();\r\n  const stage=(material:THREE.Material)=>{const clone=material.clone();clone.onBeforeCompile=material.onBeforeCompile;clone.customProgramCacheKey=material.customProgramCacheKey.bind(material);stagedMaterials.add(clone);return clone;};\r\n  for(const {mesh}of previous)mesh.material=Array.isArray(mesh.material)?mesh.material.map(stage):stage(mesh.material);\r\n  const results=await Promise.allSettled(meshes.map(mesh=>applyInstalledSkin(mesh,skin,triad,skinTextures,skinTextureCache))),failed=results.find(result=>result.status==='rejected');\r\n  if(failed?.status==='rejected'){for(const state of previous)state.mesh.material=state.material;stagedMaterials.forEach(material=>material.dispose());continue;}\r\n  const replaced=new Set<THREE.Material>();for(const state of previous)for(const material of Array.isArray(state.material)?state.material:[state.material])replaced.add(material);replaced.forEach(material=>material.dispose());\r\n }\r\n if(d.golden!==false&&goldenCoach(d.body))root.traverse(object=>{if(!(object instanceof THREE.Mesh))return;for(const material of Array.isArray(object.material)?object.material:[object.material]){const m=material as THREE.MeshStandardMaterial;if(m.color&&object.userData.region!=='eye'){m.color.set('#e8bc4d');m.metalness=.8;m.roughness=.24;}}});\r\n root.userData.recipe=JSON.parse(JSON.stringify(d));root.userData.eyeOffset=eyeOffset;root.userData.eyeScale=eyeScale;root.userData.eyeSurfaceZ=surfaceZ;root.userData.pivots=pivots;\r\n return {root,skinTextures,dispose:disposeAssembly};\r\n}\r\n","creature/source/creator/camera-focus.ts":"import * as T from 'three';\r\nimport type {Region} from './design';\r\n\r\nexport function regionBounds(root:T.Object3D,region:Region){\r\n const bounds=new T.Box3();root.updateMatrixWorld(true);\r\n function visit(node:T.Object3D){\r\n  if(!node.visible)return;\r\n  if(node instanceof T.Mesh&&node.userData.region===region){\r\n   node.geometry.computeBoundingBox();\r\n   if(node.geometry.boundingBox)bounds.union(node.geometry.boundingBox.clone().applyMatrix4(node.matrixWorld));\r\n  }\r\n  node.children.forEach(visit);\r\n }\r\n visit(root);return bounds;\r\n}\r\n\r\n// side 1 looks from the front (+z), -1 from behind.\r\nexport function regionFrame(camera:T.PerspectiveCamera,bounds:T.Box3,padding=1.2,side=1){\r\n if(bounds.isEmpty())return null;\r\n const center=bounds.getCenter(new T.Vector3()),size=bounds.getSize(new T.Vector3());\r\n const halfFov=T.MathUtils.degToRad(camera.fov/2);\r\n const distance=Math.max(size.y/(2*Math.tan(halfFov)),size.x/(2*Math.tan(halfFov)*Math.max(.25,camera.aspect)))*padding+size.z/2;\r\n return {target:center,position:center.clone().add(new T.Vector3(0,0,side*Math.max(1,distance))),distance:Math.max(1,distance)};\r\n}\r\n\r\nexport function frameRegion(camera:T.PerspectiveCamera,orbit:{target:T.Vector3;minDistance:number;maxDistance:number;update:()=>void},bounds:T.Box3,padding=1.2,side=1){\r\n const frame=regionFrame(camera,bounds,padding,side);if(!frame)return false;\r\n orbit.minDistance=Math.min(.7,frame.distance*.5);orbit.maxDistance=Math.max(14,frame.distance*2);\r\n orbit.target.copy(frame.target);camera.position.copy(frame.position);orbit.update();return true;\r\n}\r\n","creature/source/creator/catalog.ts":"export const REGIONS = [\r\n  { id: 'nails', label: 'Nails', short: 'Nails', description: 'Five claw and nail forms' },\r\n  { id: 'fingertips', label: 'Finger tips', short: 'Tips', description: 'Distal pads and final phalanges' },\r\n  { id: 'fingers', label: 'Fingers & knuckles', short: 'Fingers', description: 'Joined finger shafts, bases and knuckles' },\r\n  { id: 'palm', label: 'Palm', short: 'Palm', description: 'The inner hand surface' },\r\n  { id: 'back_of_hand', label: 'Back of hand', short: 'Back', description: 'The dorsal hand surface' },\r\n  { id: 'wrist', label: 'Wrist', short: 'Wrist', description: 'Stump, cuff and transition' },\r\n] as const;\r\n\r\nexport type RegionId = (typeof REGIONS)[number]['id'];\r\n\r\nexport type StyleFamily = {\r\n  id: number;\r\n  name: string;\r\n  realm: string;\r\n  primary: string;\r\n  secondary: string;\r\n  accent: string;\r\n  emissive: string;\r\n  roughness: number;\r\n  metalness: number;\r\n  detail: 'clean' | 'vine' | 'caps' | 'plates' | 'scales' | 'spines' | 'coral' | 'bone' | 'mist' | 'flame' | 'halo' | 'void' | 'eyes' | 'rock' | 'crystal' | 'magma' | 'ice' | 'storm' | 'gears' | 'neon' | 'fur' | 'jelly' | 'baby';\r\n};\r\n\r\nexport const STYLES: StyleFamily[] = [\r\n  { id: 0, name: 'Mortal', realm: 'Baseline · Earth', primary: '#b9856f', secondary: '#714c42', accent: '#f0c0a3', emissive: '#000000', roughness: 0.72, metalness: 0.02, detail: 'clean' },\r\n  { id: 1, name: 'Verdant', realm: 'Wildroot · Dimension 12', primary: '#3f7448', secondary: '#1e3b2b', accent: '#b8dd6e', emissive: '#172d13', roughness: 0.88, metalness: 0, detail: 'vine' },\r\n  { id: 2, name: 'Mycelial', realm: 'Sporesea · Dimension 09', primary: '#d5c7ae', secondary: '#776b82', accent: '#f59ec4', emissive: '#6d234a', roughness: 0.92, metalness: 0, detail: 'caps' },\r\n  { id: 3, name: 'Chitin', realm: 'Carapace · Dimension 31', primary: '#4f263d', secondary: '#180f20', accent: '#d17663', emissive: '#240716', roughness: 0.3, metalness: 0.28, detail: 'plates' },\r\n  { id: 4, name: 'Reptilian', realm: 'Scalehold · Dimension 04', primary: '#5f7a3f', secondary: '#283621', accent: '#cfb85c', emissive: '#101c08', roughness: 0.76, metalness: 0.04, detail: 'scales' },\r\n  { id: 5, name: 'Abyssal', realm: 'Deep Trench · Dimension 88', primary: '#132a42', secondary: '#06111f', accent: '#4edfd3', emissive: '#0b756f', roughness: 0.34, metalness: 0.12, detail: 'spines' },\r\n  { id: 6, name: 'Coral', realm: 'Living Reef · Dimension 22', primary: '#e46867', secondary: '#70344c', accent: '#ffd27a', emissive: '#8b2438', roughness: 0.83, metalness: 0, detail: 'coral' },\r\n  { id: 7, name: 'Skeletal', realm: 'Ossuary · Dimension 00', primary: '#d8d0af', secondary: '#80785f', accent: '#fff7d1', emissive: '#17160e', roughness: 0.9, metalness: 0, detail: 'bone' },\r\n  { id: 8, name: 'Spectral', realm: 'Veil · Dimension 13', primary: '#8ed9cd', secondary: '#294c58', accent: '#d5fff8', emissive: '#248e86', roughness: 0.18, metalness: 0.04, detail: 'mist' },\r\n  { id: 9, name: 'Infernal', realm: 'Cinder Court · Dimension 66', primary: '#7b211e', secondary: '#260b0a', accent: '#ff8a2a', emissive: '#d33812', roughness: 0.58, metalness: 0.1, detail: 'flame' },\r\n  { id: 10, name: 'Celestial', realm: 'High Orbit · Dimension 07', primary: '#e6dca4', secondary: '#786da7', accent: '#fffbd7', emissive: '#8d74d6', roughness: 0.24, metalness: 0.5, detail: 'halo' },\r\n  { id: 11, name: 'Voidborn', realm: 'Null Expanse · Dimension ∅', primary: '#16101f', secondary: '#060409', accent: '#9f64ff', emissive: '#482285', roughness: 0.16, metalness: 0.36, detail: 'void' },\r\n  { id: 12, name: 'Eldritch', realm: 'Watcher Fold · Dimension 47', primary: '#6b426c', secondary: '#252038', accent: '#b6ef63', emissive: '#4e7628', roughness: 0.64, metalness: 0.04, detail: 'eyes' },\r\n  { id: 13, name: 'Stone Golem', realm: 'Deep Strata · Dimension 19', primary: '#6f7068', secondary: '#393b37', accent: '#b7a37d', emissive: '#171811', roughness: 0.98, metalness: 0, detail: 'rock' },\r\n  { id: 14, name: 'Crystal', realm: 'Prism Vault · Dimension 52', primary: '#896bc2', secondary: '#302e66', accent: '#e0c8ff', emissive: '#5a3da8', roughness: 0.12, metalness: 0.3, detail: 'crystal' },\r\n  { id: 15, name: 'Magma', realm: 'Mantle · Dimension 03', primary: '#4a1713', secondary: '#140706', accent: '#ffb22f', emissive: '#e44712', roughness: 0.78, metalness: 0.06, detail: 'magma' },\r\n  { id: 16, name: 'Glacial', realm: 'White Silence · Dimension 71', primary: '#93c9df', secondary: '#315a76', accent: '#ebfdff', emissive: '#3c93bb', roughness: 0.2, metalness: 0.14, detail: 'ice' },\r\n  { id: 17, name: 'Stormcharged', realm: 'Tempest Ring · Dimension 28', primary: '#48536e', secondary: '#1a2236', accent: '#c3f7ff', emissive: '#3ebde0', roughness: 0.4, metalness: 0.32, detail: 'storm' },\r\n  { id: 18, name: 'Clockwork Robot', realm: 'Brass Meridian · Dimension 14', primary: '#9a6a37', secondary: '#33251d', accent: '#efd08c', emissive: '#5b2c12', roughness: 0.32, metalness: 0.82, detail: 'gears' },\r\n  { id: 19, name: 'Neon Synth', realm: 'Aftergrid · Dimension 20', primary: '#251d54', secondary: '#0b0921', accent: '#ff5bd7', emissive: '#b519ac', roughness: 0.22, metalness: 0.55, detail: 'neon' },\r\n  { id: 20, name: 'Fluffy', realm: 'Cloudburrow · Soft forms', primary: '#d6a987', secondary: '#bb8969', accent: '#ffe4c3', emissive: '#000000', roughness: .88, metalness: 0, detail: 'fur' },\r\n  { id: 21, name: 'Jelly', realm: 'Lime Lagoon · Soft forms', primary: '#a7ec69', secondary: '#f1ffd4', accent: '#c9ff90', emissive: '#000000', roughness: .13, metalness: 0, detail: 'jelly' },\r\n  { id: 22, name: 'Baby', realm: 'Little One · Soft forms', primary: '#efb398', secondary: '#d68e7c', accent: '#ffe2d5', emissive: '#000000', roughness: .52, metalness: 0, detail: 'baby' },\r\n];\r\n\r\nexport const DEFAULT_SELECTION: Record<RegionId, number> = {\r\n  nails: 14,\r\n  fingertips: 5,\r\n  fingers: 12,\r\n  palm: 11,\r\n  back_of_hand: 17,\r\n  wrist: 18,\r\n};\r\n\r\nexport const PURE_PRESETS = STYLES.map((style) => ({\r\n  name: style.name,\r\n  description: `A pure ${style.name.toLowerCase()} hand`,\r\n  values: Object.fromEntries(REGIONS.map((region) => [region.id, style.id])) as Record<RegionId, number>,\r\n}));\r\n\r\n\r\n// Legacy IDs stay importable; retired looks are excluded from new picks.\r\nexport const PICKER_STYLES=STYLES.filter(style=>![8,11].includes(style.id));\r\n","creature/source/creator/coaching.ts":"export const SITUATIONS=[['start','Getting started'],['stuck','Feeling stuck'],['missed','Missed a goal'],['win','Celebrating progress']] as const;\r\nexport type Situation=typeof SITUATIONS[number][0];\r\nexport const COACHES=[\r\n {id:'supportive',name:'Supportive',tone:'Warm, patient, encouraging.',approach:'Acknowledge effort. Offer one manageable next step. Celebrate progress without pressure.',lines:{start:'We can start small. What is one thing you could do in the next five minutes?',stuck:'You do not have to solve everything at once. Let’s make the next step smaller.',missed:'One missed goal does not erase your progress. What would make trying again easier?',win:'You followed through. Take a moment to notice what helped you do that.'}},\r\n {id:'direct',name:'Direct',tone:'Clear, firm, practical.',approach:'Be concise. Turn vague intentions into a specific next action. Hold the user accountable without insults.',lines:{start:'Pick one task. Decide what finished looks like. Begin with the first step.',stuck:'Name the obstacle. Choose one action that is still under your control.',missed:'Review what got in the way, adjust the plan, and choose your next attempt.',win:'You did what you said you would. Keep the part of the plan that worked.'}},\r\n {id:'analytical',name:'Analytical',tone:'Methodical, curious, precise.',approach:'Ask about constraints. Break goals into observable steps. Treat setbacks as information, not character flaws.',lines:{start:'What is the goal, what time do you have, and what is the smallest useful result?',stuck:'Is the obstacle time, clarity, energy, or resources? Let’s change one variable.',missed:'Compare the plan with what happened. Which assumption needs updating?',win:'What specifically helped? Record it so you can repeat the conditions.'}},\r\n {id:'playful',name:'Playful',tone:'Mischievous, upbeat, lightly teasing.',approach:'Use small quests and creature humor. Keep encouragement specific. Never shame the user.',lines:{start:'Tiny quest unlocked: defeat the first five minutes. The giant task can wait its turn.',stuck:'This boss fight needs a smaller boss. What can we turn into a side quest?',missed:'The quest log has been updated, not destroyed. Pick your next checkpoint.',win:'Achievement unlocked: actually doing the thing. My one eye is impressed.'}},\r\n {id:'calm',name:'Calm',tone:'Steady, spacious, grounded.',approach:'Use short, unhurried language. Leave room for the user’s choices. Focus on the present next step.',lines:{start:'There is no need to rush the whole plan. Choose one thing to begin.',stuck:'Pause for a moment. What feels possible from where you are right now?',missed:'That attempt is over. You can choose a gentler, more workable next one.',win:'Notice this moment. You made progress, and you can let that be enough for now.'}},\r\n {id:'mom',name:'MOM Inc.',tone:'Polite, theatrical, dry corporate humor.',approach:'Use fictional MOM Inc. bureaucracy and understated absurdity. Keep choices voluntary and practical.',lines:{start:'MOM Inc. has approved one manageable task. Please select yours; the paperwork can wait.',stuck:'Your obstacle has been escalated to the Department of Smaller Steps. What can we simplify?',missed:'No disciplinary forms today. We are revising the plan, not your worth.',win:'Progress officially recorded. Please accept one highly regulated moment of pride.'}},\r\n] as const;\r\nexport type CoachId=typeof COACHES[number]['id'];\r\nexport const getCoach=(id:CoachId)=>COACHES.find(c=>c.id===id)??COACHES[0];\r\n","creature/source/creator/color-variation.mjs":"// CIE Lab distances compare visible colors, independent of hex spelling.\r\nexport function colorLab(hex) {\r\n const channels=[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16)/255).map(c=>c<=.04045?c/12.92:((c+.055)/1.055)**2.4);\r\n const [r,g,b]=channels;\r\n const f=x=>x>216/24389?Math.cbrt(x):(24389/27*x+16)/116;\r\n const x=f((r*.4124564+g*.3575761+b*.1804375)/.95047),y=f(r*.2126729+g*.7151522+b*.072175),z=f((r*.0193339+g*.119192+b*.9503041)/1.08883);\r\n return [116*y-16,500*(x-y),200*(y-z)];\r\n}\r\nexport const colorDistance=(a,b)=>Math.hypot(...colorLab(a).map((v,i)=>v-colorLab(b)[i]));\r\nconst permutations=[[0,1,2],[0,2,1],[1,0,2],[1,2,0],[2,0,1],[2,1,0]];\r\n// Unordered comparison catches repeated combinations even when stops are swapped.\r\nexport const paletteDistance=(a,b)=>Math.min(...permutations.map(order=>a.reduce((sum,hex,i)=>sum+colorDistance(hex,b[order[i]]),0)/3));\r\n// Call with unlocked entries first so a locked near-duplicate never hides an owned color.\r\n// Aliases remain in the registry and saved recipes; only redundant UI tiles are folded.\r\nexport function distinctSwatches(items,minDistance=14) {\r\n const selected=[];\r\n for(const item of items)if(!selected.some(other=>colorDistance(item.hex,other.hex)<minDistance))selected.push(item);\r\n return selected;\r\n}\r\n","creature/source/creator/creature-skins.json":"{\r\n  \"schemaVersion\": 1,\r\n  \"additive\": true,\r\n  \"colorSpace\": {\r\n    \"basecolor\": \"srgb\",\r\n    \"tintMask\": \"srgb\",\r\n    \"normal\": \"linear\",\r\n    \"roughness\": \"linear\",\r\n    \"height\": \"linear\",\r\n    \"ao\": \"linear\",\r\n    \"metalness\": \"linear\",\r\n    \"opacity\": \"linear\",\r\n    \"emissive\": \"srgb\"\r\n  },\r\n  \"normalConvention\": \"OpenGL +Y\",\r\n  \"tinting\": \"tint-mask multiplied by selected creature palette\",\r\n  \"collections\": [\r\n    {\r\n      \"id\": \"creature-forged-realms\",\r\n      \"packetId\": \"coach-creature-forged-realms-v1\",\r\n      \"displayName\": \"Coach Creature Skins — Forged Realms\",\r\n      \"description\": \"Additional fantasy–science-fiction creature skin unlocks for the Coach app. Separate from the original fitness-material battle-pass set.\",\r\n      \"runtimeNotes\": {\r\n        \"normalConvention\": \"OpenGL (+Y)\",\r\n        \"tinting\": \"Use tint-mask.webp as a neutral grayscale base multiplied by the creature palette.\",\r\n        \"recommendedColorSpace\": {\r\n          \"basecolor\": \"sRGB\",\r\n          \"tintMask\": \"sRGB\",\r\n          \"normal\": \"linear\",\r\n          \"roughness\": \"linear\",\r\n          \"height\": \"linear\",\r\n          \"ao\": \"linear\",\r\n          \"metalness\": \"linear\",\r\n          \"opacity\": \"linear\",\r\n          \"emissive\": \"sRGB\"\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-celestial-rift\",\r\n      \"packetId\": \"coach-creature-celestial-rift-v1\",\r\n      \"displayName\": \"Coach Creature Skins — Celestial Rift\",\r\n      \"description\": \"A second non-overlapping set of fantasy–science-fiction creature skin unlocks for the Coach app. Additive to Forged Realms and the original fitness-material set.\",\r\n      \"runtimeNotes\": {\r\n        \"normalConvention\": \"OpenGL (+Y)\",\r\n        \"tinting\": \"Use tint-mask.webp as a neutral grayscale base multiplied by the creature palette.\",\r\n        \"recommendedColorSpace\": {\r\n          \"basecolor\": \"sRGB\",\r\n          \"tintMask\": \"sRGB\",\r\n          \"normal\": \"linear\",\r\n          \"roughness\": \"linear\",\r\n          \"height\": \"linear\",\r\n          \"ao\": \"linear\",\r\n          \"metalness\": \"linear\",\r\n          \"opacity\": \"linear\",\r\n          \"emissive\": \"sRGB\"\r\n        }\r\n      }\r\n    }\r\n  ],\r\n  \"skins\": [\r\n    {\r\n      \"id\": \"creature-starforged-plate\",\r\n      \"displayName\": \"Starforged Plate\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Metal009\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal009\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-starforged-plate/basecolor.webp\",\r\n          \"bytes\": 8170,\r\n          \"sha256\": \"c4c112d6a9ef20989d9cc048ec1bd4680e25df03fa9a99e4d124b0058ffe66e9\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-starforged-plate/normal.webp\",\r\n          \"bytes\": 878,\r\n          \"sha256\": \"a69782b9e6c01a41c9bde8e47c4f67490bf97869cf4fa332454e1d371ce0e1af\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-starforged-plate/roughness.webp\",\r\n          \"bytes\": 16326,\r\n          \"sha256\": \"eb8bf7a214631382971d470f7566e664167f395d27a51428c02edb7e9065ad39\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-starforged-plate/height.webp\",\r\n          \"bytes\": 37602,\r\n          \"sha256\": \"520bb285c4862740f48d076d49320b74f196bd7463e4dd0c338a0bcb181a103e\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-starforged-plate/metalness.webp\",\r\n          \"bytes\": 528,\r\n          \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-starforged-plate/tint-mask.webp\",\r\n          \"bytes\": 47604,\r\n          \"sha256\": \"4faadbe93f4126eac9cfba939acd1db3c3d4b5ff7a954ca33ae72ee128555b6c\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-starforged-plate/preview.webp\",\r\n          \"bytes\": 9336,\r\n          \"sha256\": \"0493936cdccec9486471163fb6b3a2fdc7195fc9535653cb714ed32fd5e32d15\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-starforged-plate/basecolor\",\r\n            \"bytes\": 8170,\r\n            \"sha256\": \"c4c112d6a9ef20989d9cc048ec1bd4680e25df03fa9a99e4d124b0058ffe66e9\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-starforged-plate/normal\",\r\n            \"bytes\": 878,\r\n            \"sha256\": \"a69782b9e6c01a41c9bde8e47c4f67490bf97869cf4fa332454e1d371ce0e1af\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-starforged-plate/roughness\",\r\n            \"bytes\": 16326,\r\n            \"sha256\": \"eb8bf7a214631382971d470f7566e664167f395d27a51428c02edb7e9065ad39\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-starforged-plate/height\",\r\n            \"bytes\": 37602,\r\n            \"sha256\": \"520bb285c4862740f48d076d49320b74f196bd7463e4dd0c338a0bcb181a103e\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-starforged-plate/metalness\",\r\n            \"bytes\": 528,\r\n            \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-starforged-plate/tintMask\",\r\n            \"bytes\": 47604,\r\n            \"sha256\": \"4faadbe93f4126eac9cfba939acd1db3c3d4b5ff7a954ca33ae72ee128555b6c\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-starforged-plate/preview\",\r\n            \"bytes\": 9336,\r\n            \"sha256\": \"0493936cdccec9486471163fb6b3a2fdc7195fc9535653cb714ed32fd5e32d15\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-obsidian-carapace\",\r\n      \"displayName\": \"Obsidian Carapace\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Onyx013\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx013\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/basecolor.webp\",\r\n          \"bytes\": 50752,\r\n          \"sha256\": \"1bf15ad9d98a4c5dfdc03623a52b62995659ca592d832652f17cc26e873d093c\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/normal.webp\",\r\n          \"bytes\": 596,\r\n          \"sha256\": \"72e8331843ae2e2d4018ef40d888cbc1ddeb7d46786874eea50ca36837b3b1a7\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/roughness.webp\",\r\n          \"bytes\": 1382,\r\n          \"sha256\": \"a66f044c77d913409a96ef8eaf4a0e59df22ac3bec63b89a3484259269aa33cc\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/height.webp\",\r\n          \"bytes\": 2988,\r\n          \"sha256\": \"760380dff035f707b917266f6bbf72ffe671fde8394b243652398b543dd71046\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/tint-mask.webp\",\r\n          \"bytes\": 65032,\r\n          \"sha256\": \"c50038331782d6ddd1dcfac8df9158043eb5efd085a0fe56e1074d55123a10c5\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-obsidian-carapace/preview.webp\",\r\n          \"bytes\": 58128,\r\n          \"sha256\": \"eb650060773ef1a11f0f8dcaf310735f709ba3e05d2d3158148524113c7013e9\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-obsidian-carapace/basecolor\",\r\n            \"bytes\": 50752,\r\n            \"sha256\": \"1bf15ad9d98a4c5dfdc03623a52b62995659ca592d832652f17cc26e873d093c\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-obsidian-carapace/normal\",\r\n            \"bytes\": 596,\r\n            \"sha256\": \"72e8331843ae2e2d4018ef40d888cbc1ddeb7d46786874eea50ca36837b3b1a7\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-obsidian-carapace/roughness\",\r\n            \"bytes\": 1382,\r\n            \"sha256\": \"a66f044c77d913409a96ef8eaf4a0e59df22ac3bec63b89a3484259269aa33cc\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-obsidian-carapace/height\",\r\n            \"bytes\": 2988,\r\n            \"sha256\": \"760380dff035f707b917266f6bbf72ffe671fde8394b243652398b543dd71046\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-obsidian-carapace/tintMask\",\r\n            \"bytes\": 65032,\r\n            \"sha256\": \"c50038331782d6ddd1dcfac8df9158043eb5efd085a0fe56e1074d55123a10c5\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-obsidian-carapace/preview\",\r\n            \"bytes\": 58128,\r\n            \"sha256\": \"eb650060773ef1a11f0f8dcaf310735f709ba3e05d2d3158148524113c7013e9\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-hive-armor\",\r\n      \"displayName\": \"Hive Armor\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"MetalPlates013\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/MetalPlates013\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-hive-armor/basecolor.webp\",\r\n          \"bytes\": 24764,\r\n          \"sha256\": \"a98dcfd52d19fc449d94a1a151f8281f1eda86ad6c7d0bce7719dddc1e50e34f\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-hive-armor/normal.webp\",\r\n          \"bytes\": 14104,\r\n          \"sha256\": \"50f6713c0ed2ec0b1c5b4ba589011499e92d4645550b79ec6a41b6727b8bd521\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-hive-armor/roughness.webp\",\r\n          \"bytes\": 44122,\r\n          \"sha256\": \"083f43ab705595a824e70ec97f4afc0670bca3e929b180cb374212a25715c18a\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-hive-armor/height.webp\",\r\n          \"bytes\": 9344,\r\n          \"sha256\": \"fb5d1b4c2c1732a3e5f42fb6e16a6a5b3ad24955069a5adbe3908f3619ea6b82\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-hive-armor/ao.webp\",\r\n          \"bytes\": 5394,\r\n          \"sha256\": \"7c97ef834a1bc65cc2a61419a1d6730dca231c912edf0572f06ecfe3157250ab\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-hive-armor/metalness.webp\",\r\n          \"bytes\": 38740,\r\n          \"sha256\": \"62aa9640f463a8866fdd53a961041ff6d6b8c14415b31f241d85658544a2c5aa\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-hive-armor/tint-mask.webp\",\r\n          \"bytes\": 61850,\r\n          \"sha256\": \"d2e7066bad7574d1b694d8186212ce56dcc4757033b061f6b6e3b08251c5046c\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-hive-armor/preview.webp\",\r\n          \"bytes\": 30780,\r\n          \"sha256\": \"a7c7bb3c7d17804bd44ce5d54e57681f2036b9758e1d3ac34dc2b238a7aab250\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-hive-armor/basecolor\",\r\n            \"bytes\": 24764,\r\n            \"sha256\": \"a98dcfd52d19fc449d94a1a151f8281f1eda86ad6c7d0bce7719dddc1e50e34f\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-hive-armor/normal\",\r\n            \"bytes\": 14104,\r\n            \"sha256\": \"50f6713c0ed2ec0b1c5b4ba589011499e92d4645550b79ec6a41b6727b8bd521\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-hive-armor/roughness\",\r\n            \"bytes\": 44122,\r\n            \"sha256\": \"083f43ab705595a824e70ec97f4afc0670bca3e929b180cb374212a25715c18a\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-hive-armor/height\",\r\n            \"bytes\": 9344,\r\n            \"sha256\": \"fb5d1b4c2c1732a3e5f42fb6e16a6a5b3ad24955069a5adbe3908f3619ea6b82\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-hive-armor/ao\",\r\n            \"bytes\": 5394,\r\n            \"sha256\": \"7c97ef834a1bc65cc2a61419a1d6730dca231c912edf0572f06ecfe3157250ab\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-hive-armor/metalness\",\r\n            \"bytes\": 38740,\r\n            \"sha256\": \"62aa9640f463a8866fdd53a961041ff6d6b8c14415b31f241d85658544a2c5aa\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-hive-armor/tintMask\",\r\n            \"bytes\": 61850,\r\n            \"sha256\": \"d2e7066bad7574d1b694d8186212ce56dcc4757033b061f6b6e3b08251c5046c\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-hive-armor/preview\",\r\n            \"bytes\": 30780,\r\n            \"sha256\": \"a7c7bb3c7d17804bd44ce5d54e57681f2036b9758e1d3ac34dc2b238a7aab250\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-magma-scale\",\r\n      \"displayName\": \"Magma Scale\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Lava004\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Lava004\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-magma-scale/basecolor.webp\",\r\n          \"bytes\": 34804,\r\n          \"sha256\": \"e57fb5ed1a1449ba5a46535e62b14c73781e4e768d837ea5d80e241995ab3fb7\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-magma-scale/normal.webp\",\r\n          \"bytes\": 55692,\r\n          \"sha256\": \"873ead60d1c158910ffee486bc6a55ee4cb4ad1d73cea2f351a9d095a1798ef9\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-magma-scale/roughness.webp\",\r\n          \"bytes\": 22680,\r\n          \"sha256\": \"f4eab6ab6dac73119e8e36c4f880115fc6e3a65252084a7412a811066110c103\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-magma-scale/height.webp\",\r\n          \"bytes\": 12946,\r\n          \"sha256\": \"8ddb62676ce447fb46030d7e65d9a6290ae993126dac3dc57b8faecd7dc7f662\"\r\n        },\r\n        \"emissive\": {\r\n          \"file\": \"textures/creature-magma-scale/emissive.webp\",\r\n          \"bytes\": 41142,\r\n          \"sha256\": \"3c0b9641bd6fe9465085ee4ce1f7657fa6fe5dd80f49c667498bdb96c7b4b5c8\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-magma-scale/tint-mask.webp\",\r\n          \"bytes\": 41404,\r\n          \"sha256\": \"2248005bce453ca3c2f57f4a460b7a561a697537d6e921766d3b45d156211cb3\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-magma-scale/preview.webp\",\r\n          \"bytes\": 38666,\r\n          \"sha256\": \"411d36c7435a414cb7e304b9099e0db9f35f95e24fc1f281a380020b51ddf180\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-magma-scale/basecolor\",\r\n            \"bytes\": 34804,\r\n            \"sha256\": \"e57fb5ed1a1449ba5a46535e62b14c73781e4e768d837ea5d80e241995ab3fb7\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-magma-scale/normal\",\r\n            \"bytes\": 55692,\r\n            \"sha256\": \"873ead60d1c158910ffee486bc6a55ee4cb4ad1d73cea2f351a9d095a1798ef9\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-magma-scale/roughness\",\r\n            \"bytes\": 22680,\r\n            \"sha256\": \"f4eab6ab6dac73119e8e36c4f880115fc6e3a65252084a7412a811066110c103\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-magma-scale/height\",\r\n            \"bytes\": 12946,\r\n            \"sha256\": \"8ddb62676ce447fb46030d7e65d9a6290ae993126dac3dc57b8faecd7dc7f662\"\r\n          },\r\n          \"emissive\": {\r\n            \"entry\": \"creature-magma-scale/emissive\",\r\n            \"bytes\": 41142,\r\n            \"sha256\": \"3c0b9641bd6fe9465085ee4ce1f7657fa6fe5dd80f49c667498bdb96c7b4b5c8\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-magma-scale/tintMask\",\r\n            \"bytes\": 41404,\r\n            \"sha256\": \"2248005bce453ca3c2f57f4a460b7a561a697537d6e921766d3b45d156211cb3\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-magma-scale/preview\",\r\n            \"bytes\": 38666,\r\n            \"sha256\": \"411d36c7435a414cb7e304b9099e0db9f35f95e24fc1f281a380020b51ddf180\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-frost-veins\",\r\n      \"displayName\": \"Frost Veins\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Ice003\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Ice003\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-frost-veins/basecolor.webp\",\r\n          \"bytes\": 22338,\r\n          \"sha256\": \"7d21627868aba7ad76ba80359897464cee48faef462a06974e24c823a19d06b4\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-frost-veins/normal.webp\",\r\n          \"bytes\": 4622,\r\n          \"sha256\": \"95179159bbe6d580b6e3e12de417064e65fe8fb287dbab1756a0ff47dfe337c0\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-frost-veins/roughness.webp\",\r\n          \"bytes\": 13946,\r\n          \"sha256\": \"dfbbd3f6e4293432dbd9c2d1cdd6904d3523223507c9a0f8d781c1f0fd2d9c25\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-frost-veins/height.webp\",\r\n          \"bytes\": 12916,\r\n          \"sha256\": \"ef9943193c04a33123c42d3af2d4a3a2fc06b0d2ac46c8fd12d4b17b745d1359\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-frost-veins/tint-mask.webp\",\r\n          \"bytes\": 26114,\r\n          \"sha256\": \"8c9a1385824ab96b15c42f0afccf237a40507b427af4bc6b827e50b984cf2097\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-frost-veins/preview.webp\",\r\n          \"bytes\": 26196,\r\n          \"sha256\": \"7462a4fb4044ae6e6521d79829b7dac42766c3e87f4092567829d7e0f93bb951\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-frost-veins/basecolor\",\r\n            \"bytes\": 22338,\r\n            \"sha256\": \"7d21627868aba7ad76ba80359897464cee48faef462a06974e24c823a19d06b4\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-frost-veins/normal\",\r\n            \"bytes\": 4622,\r\n            \"sha256\": \"95179159bbe6d580b6e3e12de417064e65fe8fb287dbab1756a0ff47dfe337c0\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-frost-veins/roughness\",\r\n            \"bytes\": 13946,\r\n            \"sha256\": \"dfbbd3f6e4293432dbd9c2d1cdd6904d3523223507c9a0f8d781c1f0fd2d9c25\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-frost-veins/height\",\r\n            \"bytes\": 12916,\r\n            \"sha256\": \"ef9943193c04a33123c42d3af2d4a3a2fc06b0d2ac46c8fd12d4b17b745d1359\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-frost-veins/tintMask\",\r\n            \"bytes\": 26114,\r\n            \"sha256\": \"8c9a1385824ab96b15c42f0afccf237a40507b427af4bc6b827e50b984cf2097\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-frost-veins/preview\",\r\n            \"bytes\": 26196,\r\n            \"sha256\": \"7462a4fb4044ae6e6521d79829b7dac42766c3e87f4092567829d7e0f93bb951\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-storm-carbon\",\r\n      \"displayName\": \"Storm Carbon\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Fabric004\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Fabric004\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-storm-carbon/basecolor.webp\",\r\n          \"bytes\": 4186,\r\n          \"sha256\": \"2f8c8777cc5df50ebb81c63fd5e09f3a4ec572b19b47e6c1f04fd7d5c4641b27\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-storm-carbon/normal.webp\",\r\n          \"bytes\": 21570,\r\n          \"sha256\": \"0364397ee006f2e0cfd26a8b05fc43f3604acef539de8e53d85aaa679eae80d5\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-storm-carbon/roughness.webp\",\r\n          \"bytes\": 13466,\r\n          \"sha256\": \"cbd3523dfa84268974de80205d042b4339b9bea70ebe19c3b5827f3f500484b0\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-storm-carbon/height.webp\",\r\n          \"bytes\": 10398,\r\n          \"sha256\": \"46d6212cbedabf6bc51bcc61c7d03bb1711f574fbcb70c47cfbef46c9521dffb\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-storm-carbon/metalness.webp\",\r\n          \"bytes\": 528,\r\n          \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-storm-carbon/tint-mask.webp\",\r\n          \"bytes\": 11298,\r\n          \"sha256\": \"3e5019a042c69df2b895973c0678b05b0ae9d6d8c1673ca5fde515d19e37b318\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-storm-carbon/preview.webp\",\r\n          \"bytes\": 4638,\r\n          \"sha256\": \"813c9f6903f3fe0f9c7a4306a319e33e6b255237722607f5ca96d067bb59be4c\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-storm-carbon/basecolor\",\r\n            \"bytes\": 4186,\r\n            \"sha256\": \"2f8c8777cc5df50ebb81c63fd5e09f3a4ec572b19b47e6c1f04fd7d5c4641b27\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-storm-carbon/normal\",\r\n            \"bytes\": 21570,\r\n            \"sha256\": \"0364397ee006f2e0cfd26a8b05fc43f3604acef539de8e53d85aaa679eae80d5\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-storm-carbon/roughness\",\r\n            \"bytes\": 13466,\r\n            \"sha256\": \"cbd3523dfa84268974de80205d042b4339b9bea70ebe19c3b5827f3f500484b0\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-storm-carbon/height\",\r\n            \"bytes\": 10398,\r\n            \"sha256\": \"46d6212cbedabf6bc51bcc61c7d03bb1711f574fbcb70c47cfbef46c9521dffb\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-storm-carbon/metalness\",\r\n            \"bytes\": 528,\r\n            \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-storm-carbon/tintMask\",\r\n            \"bytes\": 11298,\r\n            \"sha256\": \"3e5019a042c69df2b895973c0678b05b0ae9d6d8c1673ca5fde515d19e37b318\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-storm-carbon/preview\",\r\n            \"bytes\": 4638,\r\n            \"sha256\": \"813c9f6903f3fe0f9c7a4306a319e33e6b255237722607f5ca96d067bb59be4c\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-ancient-bark\",\r\n      \"displayName\": \"Ancient Bark\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Bark015\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bark015\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-ancient-bark/basecolor.webp\",\r\n          \"bytes\": 76532,\r\n          \"sha256\": \"4f104cc845070e5952eef5428e55cf37871a53b920539509d127484ef56fc492\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-ancient-bark/normal.webp\",\r\n          \"bytes\": 81960,\r\n          \"sha256\": \"6805d1f6c82e7aeadfbbee3fe039c35773d49f26b527266ac0b8122c65e55f7c\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-ancient-bark/roughness.webp\",\r\n          \"bytes\": 30736,\r\n          \"sha256\": \"4fc3cf417cb8c3621f49bb36eb8c0e1f41ac501d2bdab16e768dc8eebccc617b\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-ancient-bark/height.webp\",\r\n          \"bytes\": 12470,\r\n          \"sha256\": \"8364e839245b1a832ae8f2195ff212f4fb0e4d6bd8b58909b90389e261eea9b5\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-ancient-bark/ao.webp\",\r\n          \"bytes\": 62736,\r\n          \"sha256\": \"1490dc238669befa434ed5bd28336b865c8869a75b9db742272e60541ae99b68\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-ancient-bark/tint-mask.webp\",\r\n          \"bytes\": 84688,\r\n          \"sha256\": \"b1a08d54081eb2e811acf490187e2be77186e366d82ddd18f68c6ef240ddf1ed\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-ancient-bark/preview.webp\",\r\n          \"bytes\": 85306,\r\n          \"sha256\": \"95d00c586199990218c99d2366252ed877877885be164ce7e3186421cb339ea1\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-ancient-bark/basecolor\",\r\n            \"bytes\": 76532,\r\n            \"sha256\": \"4f104cc845070e5952eef5428e55cf37871a53b920539509d127484ef56fc492\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-ancient-bark/normal\",\r\n            \"bytes\": 81960,\r\n            \"sha256\": \"6805d1f6c82e7aeadfbbee3fe039c35773d49f26b527266ac0b8122c65e55f7c\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-ancient-bark/roughness\",\r\n            \"bytes\": 30736,\r\n            \"sha256\": \"4fc3cf417cb8c3621f49bb36eb8c0e1f41ac501d2bdab16e768dc8eebccc617b\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-ancient-bark/height\",\r\n            \"bytes\": 12470,\r\n            \"sha256\": \"8364e839245b1a832ae8f2195ff212f4fb0e4d6bd8b58909b90389e261eea9b5\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-ancient-bark/ao\",\r\n            \"bytes\": 62736,\r\n            \"sha256\": \"1490dc238669befa434ed5bd28336b865c8869a75b9db742272e60541ae99b68\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-ancient-bark/tintMask\",\r\n            \"bytes\": 84688,\r\n            \"sha256\": \"b1a08d54081eb2e811acf490187e2be77186e366d82ddd18f68c6ef240ddf1ed\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-ancient-bark/preview\",\r\n            \"bytes\": 85306,\r\n            \"sha256\": \"95d00c586199990218c99d2366252ed877877885be164ce7e3186421cb339ea1\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-mossback\",\r\n      \"displayName\": \"Mossback\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Bark013\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bark013\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-mossback/basecolor.webp\",\r\n          \"bytes\": 62984,\r\n          \"sha256\": \"1dbaed4381988af8d7145a14a15163047e8bd1ecbd0222101ba8f66c4109b88a\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-mossback/normal.webp\",\r\n          \"bytes\": 74686,\r\n          \"sha256\": \"d8c6fdbf999eae4f19b5f6e62acfcadbb0ba8d61d98302898438c307083f1ddb\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-mossback/roughness.webp\",\r\n          \"bytes\": 42160,\r\n          \"sha256\": \"daa3d7d0555e81d07ff13fbb1f481d805a79ae991712b1dde396ad8a43bf4190\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-mossback/height.webp\",\r\n          \"bytes\": 23126,\r\n          \"sha256\": \"1977403ce1a9ad3b3606d20ec8d367df41647947291a8a6baef85f6d64933b3a\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-mossback/ao.webp\",\r\n          \"bytes\": 44736,\r\n          \"sha256\": \"3b536128f80b296e091ea080d2fb8ac53ca06ea2c44d21b34168333f4410e22f\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-mossback/tint-mask.webp\",\r\n          \"bytes\": 71276,\r\n          \"sha256\": \"58497e16f8e9e8986f08381ba4482586d0d1e5b5714d4f17b058d93de724fc17\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-mossback/preview.webp\",\r\n          \"bytes\": 71140,\r\n          \"sha256\": \"478378a5c04eea0df87ba8d939215f04475914d38b3dba3a75fdcf99cf7f5985\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-mossback/basecolor\",\r\n            \"bytes\": 62984,\r\n            \"sha256\": \"1dbaed4381988af8d7145a14a15163047e8bd1ecbd0222101ba8f66c4109b88a\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-mossback/normal\",\r\n            \"bytes\": 74686,\r\n            \"sha256\": \"d8c6fdbf999eae4f19b5f6e62acfcadbb0ba8d61d98302898438c307083f1ddb\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-mossback/roughness\",\r\n            \"bytes\": 42160,\r\n            \"sha256\": \"daa3d7d0555e81d07ff13fbb1f481d805a79ae991712b1dde396ad8a43bf4190\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-mossback/height\",\r\n            \"bytes\": 23126,\r\n            \"sha256\": \"1977403ce1a9ad3b3606d20ec8d367df41647947291a8a6baef85f6d64933b3a\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-mossback/ao\",\r\n            \"bytes\": 44736,\r\n            \"sha256\": \"3b536128f80b296e091ea080d2fb8ac53ca06ea2c44d21b34168333f4410e22f\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-mossback/tintMask\",\r\n            \"bytes\": 71276,\r\n            \"sha256\": \"58497e16f8e9e8986f08381ba4482586d0d1e5b5714d4f17b058d93de724fc17\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-mossback/preview\",\r\n            \"bytes\": 71140,\r\n            \"sha256\": \"478378a5c04eea0df87ba8d939215f04475914d38b3dba3a75fdcf99cf7f5985\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-rootbound\",\r\n      \"displayName\": \"Rootbound Hide\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Ground076\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Ground076\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-rootbound/basecolor.webp\",\r\n          \"bytes\": 80318,\r\n          \"sha256\": \"e7ea9cf40442e9784dddc75399ee818a56b32110b70c7c97f5160f66a8468227\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-rootbound/normal.webp\",\r\n          \"bytes\": 68262,\r\n          \"sha256\": \"6619d18b0159c1c6433224079bd8c7af4427330312fd95bf4dc3f8817ddf06bb\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-rootbound/roughness.webp\",\r\n          \"bytes\": 52578,\r\n          \"sha256\": \"35f4e9ae25db1ab566e1585b50a0e16d6568c5bc28854b701f56fb32635d47f9\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-rootbound/height.webp\",\r\n          \"bytes\": 23352,\r\n          \"sha256\": \"197ddfca9c4d2eaf8ad0abfe1487d3c28e7b6bb3ce2b84805c5ba41cebb440a1\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-rootbound/ao.webp\",\r\n          \"bytes\": 66244,\r\n          \"sha256\": \"67b002796100a011fdf5502f8245981fd3cdb9b932968be285611e8a4f0bbffd\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-rootbound/tint-mask.webp\",\r\n          \"bytes\": 88550,\r\n          \"sha256\": \"f3be9091137218b440b1b58b0cb826863a1f3bff4cbd8a46d8d91413912c8fd7\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-rootbound/preview.webp\",\r\n          \"bytes\": 86566,\r\n          \"sha256\": \"d0d304a702c7e9ea486a4cd7432e90d6d82272dfe8e59468060525a17474e12f\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-rootbound/basecolor\",\r\n            \"bytes\": 80318,\r\n            \"sha256\": \"e7ea9cf40442e9784dddc75399ee818a56b32110b70c7c97f5160f66a8468227\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-rootbound/normal\",\r\n            \"bytes\": 68262,\r\n            \"sha256\": \"6619d18b0159c1c6433224079bd8c7af4427330312fd95bf4dc3f8817ddf06bb\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-rootbound/roughness\",\r\n            \"bytes\": 52578,\r\n            \"sha256\": \"35f4e9ae25db1ab566e1585b50a0e16d6568c5bc28854b701f56fb32635d47f9\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-rootbound/height\",\r\n            \"bytes\": 23352,\r\n            \"sha256\": \"197ddfca9c4d2eaf8ad0abfe1487d3c28e7b6bb3ce2b84805c5ba41cebb440a1\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-rootbound/ao\",\r\n            \"bytes\": 66244,\r\n            \"sha256\": \"67b002796100a011fdf5502f8245981fd3cdb9b932968be285611e8a4f0bbffd\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-rootbound/tintMask\",\r\n            \"bytes\": 88550,\r\n            \"sha256\": \"f3be9091137218b440b1b58b0cb826863a1f3bff4cbd8a46d8d91413912c8fd7\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-rootbound/preview\",\r\n            \"bytes\": 86566,\r\n            \"sha256\": \"d0d304a702c7e9ea486a4cd7432e90d6d82272dfe8e59468060525a17474e12f\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-hammered-bronze\",\r\n      \"displayName\": \"Hammered Bronze Golem\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Metal008\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal008\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-hammered-bronze/basecolor.webp\",\r\n          \"bytes\": 21270,\r\n          \"sha256\": \"beb51e4c3e9cbc126c7e684904a9848d6c49f593c7351c77df7d838a0b3031a2\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-hammered-bronze/normal.webp\",\r\n          \"bytes\": 1860,\r\n          \"sha256\": \"343ca61b6eac8a6ed0f1c8ece185543a57e19af2890393100da77b8c208df81f\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-hammered-bronze/roughness.webp\",\r\n          \"bytes\": 22538,\r\n          \"sha256\": \"d2b4ab3952757b6e165e5b131865e89312daa81f2e7b20f4533d424b1d5d2846\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-hammered-bronze/height.webp\",\r\n          \"bytes\": 3670,\r\n          \"sha256\": \"966a3de7da93c1aa338a7d5fd25b8b8b60e1b0eae492c6633a5256091e803520\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-hammered-bronze/metalness.webp\",\r\n          \"bytes\": 3062,\r\n          \"sha256\": \"c94836b0fd1152b518b7f126528630d10c215c8cf1d8927d91652496844311bb\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-hammered-bronze/tint-mask.webp\",\r\n          \"bytes\": 69154,\r\n          \"sha256\": \"977b36bfb25617394eda6993fe98972e87575b0a4f20c638fd7816627c50530c\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-hammered-bronze/preview.webp\",\r\n          \"bytes\": 26964,\r\n          \"sha256\": \"ac7d9a6bd1fef3088df0196c355462a24ae5f59276c31b2a84f32277e5174093\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-hammered-bronze/basecolor\",\r\n            \"bytes\": 21270,\r\n            \"sha256\": \"beb51e4c3e9cbc126c7e684904a9848d6c49f593c7351c77df7d838a0b3031a2\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-hammered-bronze/normal\",\r\n            \"bytes\": 1860,\r\n            \"sha256\": \"343ca61b6eac8a6ed0f1c8ece185543a57e19af2890393100da77b8c208df81f\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-hammered-bronze/roughness\",\r\n            \"bytes\": 22538,\r\n            \"sha256\": \"d2b4ab3952757b6e165e5b131865e89312daa81f2e7b20f4533d424b1d5d2846\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-hammered-bronze/height\",\r\n            \"bytes\": 3670,\r\n            \"sha256\": \"966a3de7da93c1aa338a7d5fd25b8b8b60e1b0eae492c6633a5256091e803520\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-hammered-bronze/metalness\",\r\n            \"bytes\": 3062,\r\n            \"sha256\": \"c94836b0fd1152b518b7f126528630d10c215c8cf1d8927d91652496844311bb\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-hammered-bronze/tintMask\",\r\n            \"bytes\": 69154,\r\n            \"sha256\": \"977b36bfb25617394eda6993fe98972e87575b0a4f20c638fd7816627c50530c\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-hammered-bronze/preview\",\r\n            \"bytes\": 26964,\r\n            \"sha256\": \"ac7d9a6bd1fef3088df0196c355462a24ae5f59276c31b2a84f32277e5174093\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-rope-sinew\",\r\n      \"displayName\": \"Rope Sinew\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Rope001\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Rope001\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-rope-sinew/basecolor.webp\",\r\n          \"bytes\": 29552,\r\n          \"sha256\": \"2100056331b8dd71fa4df45d64142272a4eda355df847f835e1f4a45ec0215ac\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-rope-sinew/normal.webp\",\r\n          \"bytes\": 58934,\r\n          \"sha256\": \"5a2f64efff064472eee99a9f2ad9e727a2f34807df7f4e4d1ee13cbd57eb9f87\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-rope-sinew/roughness.webp\",\r\n          \"bytes\": 12446,\r\n          \"sha256\": \"d95a57e890f030607ebc323ca242cc89a64f380f4f13edf12435a486f8892923\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-rope-sinew/height.webp\",\r\n          \"bytes\": 8678,\r\n          \"sha256\": \"41492b35711c17826fe23f1b06e4f61880ee084c5184ba8e7ad2a4bae058ce1b\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-rope-sinew/metalness.webp\",\r\n          \"bytes\": 530,\r\n          \"sha256\": \"0d61075921f8ced6ab09e8ff7a70d4732d0bbfa62467afcdb18dce2231550116\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-rope-sinew/tint-mask.webp\",\r\n          \"bytes\": 45544,\r\n          \"sha256\": \"760c9886d716bb31396be5d943f4547dc05090e4c787ff15245c260306ee268f\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-rope-sinew/preview.webp\",\r\n          \"bytes\": 35204,\r\n          \"sha256\": \"b59e86c79490250b094d7857eeffb5b2c716bb2896394643247f805e509fd9c8\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-rope-sinew/basecolor\",\r\n            \"bytes\": 29552,\r\n            \"sha256\": \"2100056331b8dd71fa4df45d64142272a4eda355df847f835e1f4a45ec0215ac\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-rope-sinew/normal\",\r\n            \"bytes\": 58934,\r\n            \"sha256\": \"5a2f64efff064472eee99a9f2ad9e727a2f34807df7f4e4d1ee13cbd57eb9f87\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-rope-sinew/roughness\",\r\n            \"bytes\": 12446,\r\n            \"sha256\": \"d95a57e890f030607ebc323ca242cc89a64f380f4f13edf12435a486f8892923\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-rope-sinew/height\",\r\n            \"bytes\": 8678,\r\n            \"sha256\": \"41492b35711c17826fe23f1b06e4f61880ee084c5184ba8e7ad2a4bae058ce1b\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-rope-sinew/metalness\",\r\n            \"bytes\": 530,\r\n            \"sha256\": \"0d61075921f8ced6ab09e8ff7a70d4732d0bbfa62467afcdb18dce2231550116\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-rope-sinew/tintMask\",\r\n            \"bytes\": 45544,\r\n            \"sha256\": \"760c9886d716bb31396be5d943f4547dc05090e4c787ff15245c260306ee268f\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-rope-sinew/preview\",\r\n            \"bytes\": 35204,\r\n            \"sha256\": \"b59e86c79490250b094d7857eeffb5b2c716bb2896394643247f805e509fd9c8\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-runic-leather\",\r\n      \"displayName\": \"Runic Leather\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Leather032\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Leather032\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-runic-leather/basecolor.webp\",\r\n          \"bytes\": 28382,\r\n          \"sha256\": \"bfd8b97143b2df95e1209492ae5d4b2c6bc61b33d82e5d5382a5162392065c66\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-runic-leather/normal.webp\",\r\n          \"bytes\": 7148,\r\n          \"sha256\": \"ddd41e34b6d8ec05f19374ff263344b38c811564f6e7882b5cb48ca71f6cb371\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-runic-leather/roughness.webp\",\r\n          \"bytes\": 85118,\r\n          \"sha256\": \"651e177fa84f3e1f9eebe5a7e7514a28d1bebab1867ec0f495a10aec997353ef\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-runic-leather/height.webp\",\r\n          \"bytes\": 90332,\r\n          \"sha256\": \"66a3c469fd1cb3c120082855bfcef6dadc921e01e3d4a36b1994ee0ea4bf642b\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-runic-leather/tint-mask.webp\",\r\n          \"bytes\": 89338,\r\n          \"sha256\": \"5332d654a93dc4f4992f571fd2e5caccad444aa84670cb96da497acca8c9f72f\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-runic-leather/preview.webp\",\r\n          \"bytes\": 35058,\r\n          \"sha256\": \"09b7cf1f2654343134c9e0a795afbab3881ba0d10b62c5a006cade89eae4eae3\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-runic-leather/basecolor\",\r\n            \"bytes\": 28382,\r\n            \"sha256\": \"bfd8b97143b2df95e1209492ae5d4b2c6bc61b33d82e5d5382a5162392065c66\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-runic-leather/normal\",\r\n            \"bytes\": 7148,\r\n            \"sha256\": \"ddd41e34b6d8ec05f19374ff263344b38c811564f6e7882b5cb48ca71f6cb371\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-runic-leather/roughness\",\r\n            \"bytes\": 85118,\r\n            \"sha256\": \"651e177fa84f3e1f9eebe5a7e7514a28d1bebab1867ec0f495a10aec997353ef\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-runic-leather/height\",\r\n            \"bytes\": 90332,\r\n            \"sha256\": \"66a3c469fd1cb3c120082855bfcef6dadc921e01e3d4a36b1994ee0ea4bf642b\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-runic-leather/tintMask\",\r\n            \"bytes\": 89338,\r\n            \"sha256\": \"5332d654a93dc4f4992f571fd2e5caccad444aa84670cb96da497acca8c9f72f\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-runic-leather/preview\",\r\n            \"bytes\": 35058,\r\n            \"sha256\": \"09b7cf1f2654343134c9e0a795afbab3881ba0d10b62c5a006cade89eae4eae3\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-crystal-core\",\r\n      \"displayName\": \"Crystal Core\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Onyx006\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx006\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-crystal-core/basecolor.webp\",\r\n          \"bytes\": 50726,\r\n          \"sha256\": \"b40390dfbd54cd5582d63d154fc924302d6c04acb1722ce2219f8b67ddaeb36d\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-crystal-core/normal.webp\",\r\n          \"bytes\": 572,\r\n          \"sha256\": \"b913752028fa3b5d7d102f5eba23aa17b9e0ee1324f52765cb249e36e189ded5\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-crystal-core/roughness.webp\",\r\n          \"bytes\": 15314,\r\n          \"sha256\": \"88749dba30f831a86dadbe7bca39039297837646ee2d5330085019eaa7fa4074\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-crystal-core/height.webp\",\r\n          \"bytes\": 2740,\r\n          \"sha256\": \"196a000792095c5dfa85554a2395e8bc1ffc856039b62eacbdd666f587a38c2a\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-crystal-core/tint-mask.webp\",\r\n          \"bytes\": 51868,\r\n          \"sha256\": \"22ef052c4767e7be3f3e6187fa7e6a1e5baf2a0131d47c45cee616ef082b9df6\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-crystal-core/preview.webp\",\r\n          \"bytes\": 56978,\r\n          \"sha256\": \"ee40a473889f2844fa35a8057a6001827945dd43863c9c12da092039b2b8c76a\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-crystal-core/basecolor\",\r\n            \"bytes\": 50726,\r\n            \"sha256\": \"b40390dfbd54cd5582d63d154fc924302d6c04acb1722ce2219f8b67ddaeb36d\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-crystal-core/normal\",\r\n            \"bytes\": 572,\r\n            \"sha256\": \"b913752028fa3b5d7d102f5eba23aa17b9e0ee1324f52765cb249e36e189ded5\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-crystal-core/roughness\",\r\n            \"bytes\": 15314,\r\n            \"sha256\": \"88749dba30f831a86dadbe7bca39039297837646ee2d5330085019eaa7fa4074\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-crystal-core/height\",\r\n            \"bytes\": 2740,\r\n            \"sha256\": \"196a000792095c5dfa85554a2395e8bc1ffc856039b62eacbdd666f587a38c2a\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-crystal-core/tintMask\",\r\n            \"bytes\": 51868,\r\n            \"sha256\": \"22ef052c4767e7be3f3e6187fa7e6a1e5baf2a0131d47c45cee616ef082b9df6\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-crystal-core/preview\",\r\n            \"bytes\": 56978,\r\n            \"sha256\": \"ee40a473889f2844fa35a8057a6001827945dd43863c9c12da092039b2b8c76a\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-moon-marble\",\r\n      \"displayName\": \"Moon Marble\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Marble016\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Marble016\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-moon-marble/basecolor.webp\",\r\n          \"bytes\": 60346,\r\n          \"sha256\": \"30857f841da460f9f6878279498e11805b26bb1b9387302bd2a74d2f11f850fe\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-moon-marble/normal.webp\",\r\n          \"bytes\": 558,\r\n          \"sha256\": \"0abacb9ea21b4e643690ae88919a195040b0c0a22994003cddc2ea40a078e242\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-moon-marble/roughness.webp\",\r\n          \"bytes\": 3740,\r\n          \"sha256\": \"78bd9171c82cef1e9ab5b6f4df1f0b36021fcb76487af7c187aada745e346795\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-moon-marble/height.webp\",\r\n          \"bytes\": 54702,\r\n          \"sha256\": \"2ba36b84ef5e549ede30e4203ce6e8e2d415d6f0f2c095d40bb0a13aa4cf81bb\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-moon-marble/tint-mask.webp\",\r\n          \"bytes\": 74936,\r\n          \"sha256\": \"a72497a56824baa0bab493baae6ce2b814f204b1b870426ff8eccddcc5f46030\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-moon-marble/preview.webp\",\r\n          \"bytes\": 68934,\r\n          \"sha256\": \"977f080377efdb814dc01a6a825d1df941566fe6298699a9ee191eaafa866553\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-moon-marble/basecolor\",\r\n            \"bytes\": 60346,\r\n            \"sha256\": \"30857f841da460f9f6878279498e11805b26bb1b9387302bd2a74d2f11f850fe\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-moon-marble/normal\",\r\n            \"bytes\": 558,\r\n            \"sha256\": \"0abacb9ea21b4e643690ae88919a195040b0c0a22994003cddc2ea40a078e242\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-moon-marble/roughness\",\r\n            \"bytes\": 3740,\r\n            \"sha256\": \"78bd9171c82cef1e9ab5b6f4df1f0b36021fcb76487af7c187aada745e346795\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-moon-marble/height\",\r\n            \"bytes\": 54702,\r\n            \"sha256\": \"2ba36b84ef5e549ede30e4203ce6e8e2d415d6f0f2c095d40bb0a13aa4cf81bb\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-moon-marble/tintMask\",\r\n            \"bytes\": 74936,\r\n            \"sha256\": \"a72497a56824baa0bab493baae6ce2b814f204b1b870426ff8eccddcc5f46030\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-moon-marble/preview\",\r\n            \"bytes\": 68934,\r\n            \"sha256\": \"977f080377efdb814dc01a6a825d1df941566fe6298699a9ee191eaafa866553\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-fae-petal\",\r\n      \"displayName\": \"Fae Petal\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"FlowerSet001\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/FlowerSet001\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-fae-petal/basecolor.webp\",\r\n          \"bytes\": 17208,\r\n          \"sha256\": \"53bc7d03952fb1244b75ba1e015cf36173c326271005c3330c01fccb63d74946\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-fae-petal/normal.webp\",\r\n          \"bytes\": 19898,\r\n          \"sha256\": \"bb402d8c39e986a0ba5fd1bbdcbcb8cbbdba29a75d4e932b39c5851b2350f75f\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-fae-petal/roughness.webp\",\r\n          \"bytes\": 6054,\r\n          \"sha256\": \"4b66923e2349ed42ebbf202c8a42aa33fb759c1713cea678dbd0ac93bd175aec\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-fae-petal/height.webp\",\r\n          \"bytes\": 6176,\r\n          \"sha256\": \"4dd774718a94f5b87de223c8ab27b18bde4df1249e76f7df7a9627143ca4b830\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-fae-petal/ao.webp\",\r\n          \"bytes\": 8140,\r\n          \"sha256\": \"9eabbf557041b2bdcc58f52cc5821de36470b43f44aac3a6cb87cee3aee645eb\"\r\n        },\r\n        \"opacity\": {\r\n          \"file\": \"textures/creature-fae-petal/opacity.webp\",\r\n          \"bytes\": 9784,\r\n          \"sha256\": \"7e7d2e3432143c925e111a2e763d3230fa88cc2512155059b020d4516d68cbad\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-fae-petal/tint-mask.webp\",\r\n          \"bytes\": 15026,\r\n          \"sha256\": \"255ef36fc492b422a991192efead4b414f0a3ccd57bdcd3212033c82a4533608\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-fae-petal/preview.webp\",\r\n          \"bytes\": 19274,\r\n          \"sha256\": \"afc9fe5d4f588ca9c78e54032aedbdfcd97c991d384f8dbc6ca803f5c6eada5a\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-fae-petal/basecolor\",\r\n            \"bytes\": 17208,\r\n            \"sha256\": \"53bc7d03952fb1244b75ba1e015cf36173c326271005c3330c01fccb63d74946\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-fae-petal/normal\",\r\n            \"bytes\": 19898,\r\n            \"sha256\": \"bb402d8c39e986a0ba5fd1bbdcbcb8cbbdba29a75d4e932b39c5851b2350f75f\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-fae-petal/roughness\",\r\n            \"bytes\": 6054,\r\n            \"sha256\": \"4b66923e2349ed42ebbf202c8a42aa33fb759c1713cea678dbd0ac93bd175aec\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-fae-petal/height\",\r\n            \"bytes\": 6176,\r\n            \"sha256\": \"4dd774718a94f5b87de223c8ab27b18bde4df1249e76f7df7a9627143ca4b830\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-fae-petal/ao\",\r\n            \"bytes\": 8140,\r\n            \"sha256\": \"9eabbf557041b2bdcc58f52cc5821de36470b43f44aac3a6cb87cee3aee645eb\"\r\n          },\r\n          \"opacity\": {\r\n            \"entry\": \"creature-fae-petal/opacity\",\r\n            \"bytes\": 9784,\r\n            \"sha256\": \"7e7d2e3432143c925e111a2e763d3230fa88cc2512155059b020d4516d68cbad\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-fae-petal/tintMask\",\r\n            \"bytes\": 15026,\r\n            \"sha256\": \"255ef36fc492b422a991192efead4b414f0a3ccd57bdcd3212033c82a4533608\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-fae-petal/preview\",\r\n            \"bytes\": 19274,\r\n            \"sha256\": \"afc9fe5d4f588ca9c78e54032aedbdfcd97c991d384f8dbc6ca803f5c6eada5a\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-dragon-scale\",\r\n      \"displayName\": \"Dragon Scale\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"RoofingTiles013A\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/RoofingTiles013A\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-dragon-scale/basecolor.webp\",\r\n          \"bytes\": 2668,\r\n          \"sha256\": \"663af0ac46b5c88304bf252b913714ee7315062ffaf8d41e1f98437436cfe933\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-dragon-scale/normal.webp\",\r\n          \"bytes\": 20688,\r\n          \"sha256\": \"9bdd90ed2cbf7eaa94c24f290906c764b4a4c16ceb184114dbb22b749209d3a8\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-dragon-scale/roughness.webp\",\r\n          \"bytes\": 16142,\r\n          \"sha256\": \"8edb0acad8dfa41c361067e49cc1aa13a23cd1e179b9fd02621c6a49cf5f4ee6\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-dragon-scale/height.webp\",\r\n          \"bytes\": 8400,\r\n          \"sha256\": \"f53bd1a0068dd2cc2cd31b67f2bd6800680c4d58443418bfdb2f1998ea78fbcb\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-dragon-scale/ao.webp\",\r\n          \"bytes\": 14048,\r\n          \"sha256\": \"5e9e5483fdea8249867c9532a991b11b2518e1c725e43e84835428d13d0791e5\"\r\n        },\r\n        \"opacity\": {\r\n          \"file\": \"textures/creature-dragon-scale/opacity.webp\",\r\n          \"bytes\": 528,\r\n          \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-dragon-scale/tint-mask.webp\",\r\n          \"bytes\": 33612,\r\n          \"sha256\": \"d77eb358cbfb4252db8a6df4ff0536bb5d45e7f74dbac6fa6ead5c2c6fb30adf\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-dragon-scale/preview.webp\",\r\n          \"bytes\": 3430,\r\n          \"sha256\": \"f2ff67b80aedfbb8c3c5e1e2412b54c6b6d88ba256e80d9604103fe4ac90435b\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-dragon-scale/basecolor\",\r\n            \"bytes\": 2668,\r\n            \"sha256\": \"663af0ac46b5c88304bf252b913714ee7315062ffaf8d41e1f98437436cfe933\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-dragon-scale/normal\",\r\n            \"bytes\": 20688,\r\n            \"sha256\": \"9bdd90ed2cbf7eaa94c24f290906c764b4a4c16ceb184114dbb22b749209d3a8\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-dragon-scale/roughness\",\r\n            \"bytes\": 16142,\r\n            \"sha256\": \"8edb0acad8dfa41c361067e49cc1aa13a23cd1e179b9fd02621c6a49cf5f4ee6\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-dragon-scale/height\",\r\n            \"bytes\": 8400,\r\n            \"sha256\": \"f53bd1a0068dd2cc2cd31b67f2bd6800680c4d58443418bfdb2f1998ea78fbcb\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-dragon-scale/ao\",\r\n            \"bytes\": 14048,\r\n            \"sha256\": \"5e9e5483fdea8249867c9532a991b11b2518e1c725e43e84835428d13d0791e5\"\r\n          },\r\n          \"opacity\": {\r\n            \"entry\": \"creature-dragon-scale/opacity\",\r\n            \"bytes\": 528,\r\n            \"sha256\": \"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-dragon-scale/tintMask\",\r\n            \"bytes\": 33612,\r\n            \"sha256\": \"d77eb358cbfb4252db8a6df4ff0536bb5d45e7f74dbac6fa6ead5c2c6fb30adf\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-dragon-scale/preview\",\r\n            \"bytes\": 3430,\r\n            \"sha256\": \"f2ff67b80aedfbb8c3c5e1e2412b54c6b6d88ba256e80d9604103fe4ac90435b\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-bamboo-hide\",\r\n      \"displayName\": \"Bamboo Hide\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Bamboo001A\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bamboo001A\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-bamboo-hide/basecolor.webp\",\r\n          \"bytes\": 11654,\r\n          \"sha256\": \"8a26d7c21793d2d02c4b6d3313ec4fb4646d48dc97d3a3d0e9a51e6787fd5337\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-bamboo-hide/normal.webp\",\r\n          \"bytes\": 20194,\r\n          \"sha256\": \"0c249768ad2e7285a506a67b932f96e7a0472bec4a5e7b26f0b672ca34eab9b6\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-bamboo-hide/roughness.webp\",\r\n          \"bytes\": 12634,\r\n          \"sha256\": \"3e57e47e22afa27294a0137519906146e27444654a0d02765b7c414ede8bc154\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-bamboo-hide/height.webp\",\r\n          \"bytes\": 7926,\r\n          \"sha256\": \"17c7dce94d4eae86698c08537620db4ba94534200acfa3f8cc1323a5c824473b\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-bamboo-hide/ao.webp\",\r\n          \"bytes\": 7788,\r\n          \"sha256\": \"20df27a385c6cac19c1c083d8938d7c3e76e117e19bc1087c33dd4f4634b3c3c\"\r\n        },\r\n        \"opacity\": {\r\n          \"file\": \"textures/creature-bamboo-hide/opacity.webp\",\r\n          \"bytes\": 2412,\r\n          \"sha256\": \"b7de9d512266f259b7910820d03689d0680fea8a7d1f865cfb28dc3010652be7\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-bamboo-hide/tint-mask.webp\",\r\n          \"bytes\": 37906,\r\n          \"sha256\": \"e6b2ebfedeb9ab63529780556808f7397d3db969fc5862e78d70e6cbdc78ffed\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-bamboo-hide/preview.webp\",\r\n          \"bytes\": 14130,\r\n          \"sha256\": \"468e73ebe9c1552645ec4bfa0e9a417a8976210005686772416d8a142b74b3d7\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-bamboo-hide/basecolor\",\r\n            \"bytes\": 11654,\r\n            \"sha256\": \"8a26d7c21793d2d02c4b6d3313ec4fb4646d48dc97d3a3d0e9a51e6787fd5337\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-bamboo-hide/normal\",\r\n            \"bytes\": 20194,\r\n            \"sha256\": \"0c249768ad2e7285a506a67b932f96e7a0472bec4a5e7b26f0b672ca34eab9b6\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-bamboo-hide/roughness\",\r\n            \"bytes\": 12634,\r\n            \"sha256\": \"3e57e47e22afa27294a0137519906146e27444654a0d02765b7c414ede8bc154\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-bamboo-hide/height\",\r\n            \"bytes\": 7926,\r\n            \"sha256\": \"17c7dce94d4eae86698c08537620db4ba94534200acfa3f8cc1323a5c824473b\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-bamboo-hide/ao\",\r\n            \"bytes\": 7788,\r\n            \"sha256\": \"20df27a385c6cac19c1c083d8938d7c3e76e117e19bc1087c33dd4f4634b3c3c\"\r\n          },\r\n          \"opacity\": {\r\n            \"entry\": \"creature-bamboo-hide/opacity\",\r\n            \"bytes\": 2412,\r\n            \"sha256\": \"b7de9d512266f259b7910820d03689d0680fea8a7d1f865cfb28dc3010652be7\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-bamboo-hide/tintMask\",\r\n            \"bytes\": 37906,\r\n            \"sha256\": \"e6b2ebfedeb9ab63529780556808f7397d3db969fc5862e78d70e6cbdc78ffed\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-bamboo-hide/preview\",\r\n            \"bytes\": 14130,\r\n            \"sha256\": \"468e73ebe9c1552645ec4bfa0e9a417a8976210005686772416d8a142b74b3d7\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-ivory-chitin\",\r\n      \"displayName\": \"Ivory Chitin\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Marble021\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Marble021\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-ivory-chitin/basecolor.webp\",\r\n          \"bytes\": 15470,\r\n          \"sha256\": \"81219c6653e2322483827286ce187f288c370e953d63768758d5ab1d5f139f01\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-ivory-chitin/normal.webp\",\r\n          \"bytes\": 546,\r\n          \"sha256\": \"bb0dca1732b8beac8a047157a25c3325d0e82ee854775c9b30a3d0d3bb1c84d4\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-ivory-chitin/roughness.webp\",\r\n          \"bytes\": 3860,\r\n          \"sha256\": \"cbe0b85ba9dd43d3a8de3e2b1f49ea26f078836685ab9fcbb6012adaf3186259\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-ivory-chitin/height.webp\",\r\n          \"bytes\": 50360,\r\n          \"sha256\": \"f1baf51d0f8bbebdd08b037b41dc0a52e8cdbe1d3ee3f3c8e229e10ecceaad8b\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-ivory-chitin/tint-mask.webp\",\r\n          \"bytes\": 97890,\r\n          \"sha256\": \"dab2a9ef91fbfd6e0563073bcd2594c15a12037a215e5e4a206c850585d0a4a0\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-ivory-chitin/preview.webp\",\r\n          \"bytes\": 19758,\r\n          \"sha256\": \"57ca0354c5b20b764d90bc4f8d55f0a4c5f505e55f46ac3165f4268ccaf52317\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-ivory-chitin/basecolor\",\r\n            \"bytes\": 15470,\r\n            \"sha256\": \"81219c6653e2322483827286ce187f288c370e953d63768758d5ab1d5f139f01\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-ivory-chitin/normal\",\r\n            \"bytes\": 546,\r\n            \"sha256\": \"bb0dca1732b8beac8a047157a25c3325d0e82ee854775c9b30a3d0d3bb1c84d4\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-ivory-chitin/roughness\",\r\n            \"bytes\": 3860,\r\n            \"sha256\": \"cbe0b85ba9dd43d3a8de3e2b1f49ea26f078836685ab9fcbb6012adaf3186259\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-ivory-chitin/height\",\r\n            \"bytes\": 50360,\r\n            \"sha256\": \"f1baf51d0f8bbebdd08b037b41dc0a52e8cdbe1d3ee3f3c8e229e10ecceaad8b\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-ivory-chitin/tintMask\",\r\n            \"bytes\": 97890,\r\n            \"sha256\": \"dab2a9ef91fbfd6e0563073bcd2594c15a12037a215e5e4a206c850585d0a4a0\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-ivory-chitin/preview\",\r\n            \"bytes\": 19758,\r\n            \"sha256\": \"57ca0354c5b20b764d90bc4f8d55f0a4c5f505e55f46ac3165f4268ccaf52317\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-circuit-hide\",\r\n      \"displayName\": \"Circuit Hide\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Chip001\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Chip001\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-circuit-hide/basecolor.webp\",\r\n          \"bytes\": 40778,\r\n          \"sha256\": \"096cd7675f3b9908bea4f2414e1c2c36d5b7f11c80055647805b0ffea3aeca4d\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-circuit-hide/normal.webp\",\r\n          \"bytes\": 27864,\r\n          \"sha256\": \"d8064a373c7c347760ecb731bb61b203e1893d8db280062d6bfdc180ebb044d9\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-circuit-hide/roughness.webp\",\r\n          \"bytes\": 26718,\r\n          \"sha256\": \"350c942f434549bafd6a47f4e6d4acef03e666eea5f284779cf533591562663d\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-circuit-hide/height.webp\",\r\n          \"bytes\": 23204,\r\n          \"sha256\": \"f31a4005001a2319418f6de50e502f80e48f04c77fd725bd55270843c1d6a049\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-circuit-hide/metalness.webp\",\r\n          \"bytes\": 24542,\r\n          \"sha256\": \"7fdd6b09dfdd23b2c362218a3f98a5af3291367c2b3f58da3bd1cd29a37da8b9\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-circuit-hide/tint-mask.webp\",\r\n          \"bytes\": 37986,\r\n          \"sha256\": \"efe041e77fbd766eefec21bca9b2ddfedb2acb20d43955ea44a46ad42065f22c\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-circuit-hide/preview.webp\",\r\n          \"bytes\": 44810,\r\n          \"sha256\": \"2b020253316ab4d3084073de0b90cf4c4575317475207998ee5cf8c4ae093c16\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-circuit-hide/basecolor\",\r\n            \"bytes\": 40778,\r\n            \"sha256\": \"096cd7675f3b9908bea4f2414e1c2c36d5b7f11c80055647805b0ffea3aeca4d\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-circuit-hide/normal\",\r\n            \"bytes\": 27864,\r\n            \"sha256\": \"d8064a373c7c347760ecb731bb61b203e1893d8db280062d6bfdc180ebb044d9\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-circuit-hide/roughness\",\r\n            \"bytes\": 26718,\r\n            \"sha256\": \"350c942f434549bafd6a47f4e6d4acef03e666eea5f284779cf533591562663d\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-circuit-hide/height\",\r\n            \"bytes\": 23204,\r\n            \"sha256\": \"f31a4005001a2319418f6de50e502f80e48f04c77fd725bd55270843c1d6a049\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-circuit-hide/metalness\",\r\n            \"bytes\": 24542,\r\n            \"sha256\": \"7fdd6b09dfdd23b2c362218a3f98a5af3291367c2b3f58da3bd1cd29a37da8b9\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-circuit-hide/tintMask\",\r\n            \"bytes\": 37986,\r\n            \"sha256\": \"efe041e77fbd766eefec21bca9b2ddfedb2acb20d43955ea44a46ad42065f22c\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-circuit-hide/preview\",\r\n            \"bytes\": 44810,\r\n            \"sha256\": \"2b020253316ab4d3084073de0b90cf4c4575317475207998ee5cf8c4ae093c16\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-reactor-rust\",\r\n      \"displayName\": \"Reactor Rust\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Metal063\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal063\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-reactor-rust/basecolor.webp\",\r\n          \"bytes\": 11264,\r\n          \"sha256\": \"ffdb6f1feeaac227647437e25e4d06291c6ee547061c60b61819277cfc37d932\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-reactor-rust/normal.webp\",\r\n          \"bytes\": 550,\r\n          \"sha256\": \"f0f42188a939998becdd27cc27174e355f5fe0cffff56f440af5183fce757854\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-reactor-rust/roughness.webp\",\r\n          \"bytes\": 29148,\r\n          \"sha256\": \"8a34c7db1239c7127956f7daa263fe89cb5d7f05614938c12b5da82098408907\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-reactor-rust/height.webp\",\r\n          \"bytes\": 37754,\r\n          \"sha256\": \"0ce87e82026e669fb796708337c3e1614cef174134b7ecb9bb901f2fccf439ae\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-reactor-rust/metalness.webp\",\r\n          \"bytes\": 43140,\r\n          \"sha256\": \"47ca127726b3e24b6c07713a7f50fe6baf5a3d3e99f925e3c47d0fd5c01a2ab9\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-reactor-rust/tint-mask.webp\",\r\n          \"bytes\": 97766,\r\n          \"sha256\": \"9190d9c0246cb5e52f8e2e6ffe9b99f604681bc96c6d9bf86cf5a93a7c4b9abc\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-reactor-rust/preview.webp\",\r\n          \"bytes\": 17150,\r\n          \"sha256\": \"1537f736edba5d9c5f78988cbb50e49ab83a293b9c94aad49c25fdccad94bfe8\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-reactor-rust/basecolor\",\r\n            \"bytes\": 11264,\r\n            \"sha256\": \"ffdb6f1feeaac227647437e25e4d06291c6ee547061c60b61819277cfc37d932\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-reactor-rust/normal\",\r\n            \"bytes\": 550,\r\n            \"sha256\": \"f0f42188a939998becdd27cc27174e355f5fe0cffff56f440af5183fce757854\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-reactor-rust/roughness\",\r\n            \"bytes\": 29148,\r\n            \"sha256\": \"8a34c7db1239c7127956f7daa263fe89cb5d7f05614938c12b5da82098408907\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-reactor-rust/height\",\r\n            \"bytes\": 37754,\r\n            \"sha256\": \"0ce87e82026e669fb796708337c3e1614cef174134b7ecb9bb901f2fccf439ae\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-reactor-rust/metalness\",\r\n            \"bytes\": 43140,\r\n            \"sha256\": \"47ca127726b3e24b6c07713a7f50fe6baf5a3d3e99f925e3c47d0fd5c01a2ab9\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-reactor-rust/tintMask\",\r\n            \"bytes\": 97766,\r\n            \"sha256\": \"9190d9c0246cb5e52f8e2e6ffe9b99f604681bc96c6d9bf86cf5a93a7c4b9abc\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-reactor-rust/preview\",\r\n            \"bytes\": 17150,\r\n            \"sha256\": \"1537f736edba5d9c5f78988cbb50e49ab83a293b9c94aad49c25fdccad94bfe8\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-aero-mesh\",\r\n      \"displayName\": \"Aero Mesh\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"MetalWalkway013\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/MetalWalkway013\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-aero-mesh/basecolor.webp\",\r\n          \"bytes\": 9048,\r\n          \"sha256\": \"efd7e746572308d9717ac3ff5f401830ca4202b89e9b731598e0011cff27300f\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-aero-mesh/normal.webp\",\r\n          \"bytes\": 55928,\r\n          \"sha256\": \"4517755111af640a8fcd23b09769a51d97356b3595320ec249b3e6d0286c28c9\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-aero-mesh/roughness.webp\",\r\n          \"bytes\": 27652,\r\n          \"sha256\": \"bda6c12306cb56d53cd964083db281078eaedb32e0588d2e39ff3619c73b4721\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-aero-mesh/height.webp\",\r\n          \"bytes\": 29354,\r\n          \"sha256\": \"0d4e1d671a7d57525e21e35cbfc83d89d824c7b89f3a9c85188be87243afc118\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-aero-mesh/metalness.webp\",\r\n          \"bytes\": 1340,\r\n          \"sha256\": \"365eb05114bf220e641ba92ffe9c2032041e050f5fa03e856479edadfca04ce4\"\r\n        },\r\n        \"opacity\": {\r\n          \"file\": \"textures/creature-aero-mesh/opacity.webp\",\r\n          \"bytes\": 28608,\r\n          \"sha256\": \"fd306eedd40b7130a73447594b0b2889735a722f85b8fb74e91024e0bb48653e\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-aero-mesh/tint-mask.webp\",\r\n          \"bytes\": 23612,\r\n          \"sha256\": \"7d4e51edf8c6e2961a92d10fd204e03676f1a886dcc3f94f80ec7f5bf934a756\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-aero-mesh/preview.webp\",\r\n          \"bytes\": 11188,\r\n          \"sha256\": \"e249038b305943c5cc58fdaceed7307e77515a33d88c7fb020e832b0ba6a1a75\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-aero-mesh/basecolor\",\r\n            \"bytes\": 9048,\r\n            \"sha256\": \"efd7e746572308d9717ac3ff5f401830ca4202b89e9b731598e0011cff27300f\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-aero-mesh/normal\",\r\n            \"bytes\": 55928,\r\n            \"sha256\": \"4517755111af640a8fcd23b09769a51d97356b3595320ec249b3e6d0286c28c9\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-aero-mesh/roughness\",\r\n            \"bytes\": 27652,\r\n            \"sha256\": \"bda6c12306cb56d53cd964083db281078eaedb32e0588d2e39ff3619c73b4721\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-aero-mesh/height\",\r\n            \"bytes\": 29354,\r\n            \"sha256\": \"0d4e1d671a7d57525e21e35cbfc83d89d824c7b89f3a9c85188be87243afc118\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-aero-mesh/metalness\",\r\n            \"bytes\": 1340,\r\n            \"sha256\": \"365eb05114bf220e641ba92ffe9c2032041e050f5fa03e856479edadfca04ce4\"\r\n          },\r\n          \"opacity\": {\r\n            \"entry\": \"creature-aero-mesh/opacity\",\r\n            \"bytes\": 28608,\r\n            \"sha256\": \"fd306eedd40b7130a73447594b0b2889735a722f85b8fb74e91024e0bb48653e\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-aero-mesh/tintMask\",\r\n            \"bytes\": 23612,\r\n            \"sha256\": \"7d4e51edf8c6e2961a92d10fd204e03676f1a886dcc3f94f80ec7f5bf934a756\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-aero-mesh/preview\",\r\n            \"bytes\": 11188,\r\n            \"sha256\": \"e249038b305943c5cc58fdaceed7307e77515a33d88c7fb020e832b0ba6a1a75\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-zen-sand\",\r\n      \"displayName\": \"Zen Sand\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Ground097\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Ground097\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-zen-sand/basecolor.webp\",\r\n          \"bytes\": 2566,\r\n          \"sha256\": \"0913f83f5a430d643903700a9ddba413618b974d1284ab5bb33235e09bef6d6f\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-zen-sand/normal.webp\",\r\n          \"bytes\": 25542,\r\n          \"sha256\": \"acf6ca0faf928441a99d871c6bcc05fe1b1644e8cd5a4cd12c807b8572aa5219\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-zen-sand/roughness.webp\",\r\n          \"bytes\": 9672,\r\n          \"sha256\": \"89cd80ff7f889b753fb059e427bc082c02f223da30cf388d3ac41c1ada5e3cc9\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-zen-sand/height.webp\",\r\n          \"bytes\": 14040,\r\n          \"sha256\": \"55c05b9ab62b320dc74c5e37d871ec9f2a63804e654b3bac2d3df4dc045a9246\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-zen-sand/ao.webp\",\r\n          \"bytes\": 2322,\r\n          \"sha256\": \"0d241c3387cc7d877016d4db9225cc0aae6fed59f7d9fff78797f6b204466697\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-zen-sand/tint-mask.webp\",\r\n          \"bytes\": 27572,\r\n          \"sha256\": \"92f6c6974aa9641af624ac98c6acc383ca0094ffd8c60c43c81c4e94781d1441\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-zen-sand/preview.webp\",\r\n          \"bytes\": 3032,\r\n          \"sha256\": \"965d0ecf578a8d912910f99fba4bc09e5a61ba069d5fb2be14cbd02e4d133a86\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-zen-sand/basecolor\",\r\n            \"bytes\": 2566,\r\n            \"sha256\": \"0913f83f5a430d643903700a9ddba413618b974d1284ab5bb33235e09bef6d6f\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-zen-sand/normal\",\r\n            \"bytes\": 25542,\r\n            \"sha256\": \"acf6ca0faf928441a99d871c6bcc05fe1b1644e8cd5a4cd12c807b8572aa5219\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-zen-sand/roughness\",\r\n            \"bytes\": 9672,\r\n            \"sha256\": \"89cd80ff7f889b753fb059e427bc082c02f223da30cf388d3ac41c1ada5e3cc9\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-zen-sand/height\",\r\n            \"bytes\": 14040,\r\n            \"sha256\": \"55c05b9ab62b320dc74c5e37d871ec9f2a63804e654b3bac2d3df4dc045a9246\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-zen-sand/ao\",\r\n            \"bytes\": 2322,\r\n            \"sha256\": \"0d241c3387cc7d877016d4db9225cc0aae6fed59f7d9fff78797f6b204466697\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-zen-sand/tintMask\",\r\n            \"bytes\": 27572,\r\n            \"sha256\": \"92f6c6974aa9641af624ac98c6acc383ca0094ffd8c60c43c81c4e94781d1441\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-zen-sand/preview\",\r\n            \"bytes\": 3032,\r\n            \"sha256\": \"965d0ecf578a8d912910f99fba4bc09e5a61ba069d5fb2be14cbd02e4d133a86\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-river-stone\",\r\n      \"displayName\": \"River Stone\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Rock020\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Rock020\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-river-stone/basecolor.webp\",\r\n          \"bytes\": 49168,\r\n          \"sha256\": \"e8cdd973998441e09a8dc4b44ff9da77dec6fad11f8523138ced65b1e9e4a3f9\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-river-stone/normal.webp\",\r\n          \"bytes\": 99336,\r\n          \"sha256\": \"f31db446c61f36d6775548bff4d04ea21b54dfc1e3271d39b719ab6c48b9c208\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-river-stone/roughness.webp\",\r\n          \"bytes\": 13096,\r\n          \"sha256\": \"65ca034f5f657db0fcf502c93b2bacc3f1a66a572ed3e24d09ba3fadbbb80757\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-river-stone/height.webp\",\r\n          \"bytes\": 9202,\r\n          \"sha256\": \"8e5b35579dce02cbb1fbfa415762a6b65724ef86898c3cc53de36b37398f90ce\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-river-stone/ao.webp\",\r\n          \"bytes\": 22322,\r\n          \"sha256\": \"985e2218cda815c2549c0a926df7d26f050ba1e34eccb4a859fba17c6ec9489e\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-river-stone/tint-mask.webp\",\r\n          \"bytes\": 76542,\r\n          \"sha256\": \"b603234beb199542b602fd2a8823ba1416f4be342b69168bc85e6bfc15a76e4f\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-river-stone/preview.webp\",\r\n          \"bytes\": 57812,\r\n          \"sha256\": \"09b86e6e3c10f2c1581c3a46507d593fe561e8bfed7628d35665d695ae4926a7\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-river-stone/basecolor\",\r\n            \"bytes\": 49168,\r\n            \"sha256\": \"e8cdd973998441e09a8dc4b44ff9da77dec6fad11f8523138ced65b1e9e4a3f9\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-river-stone/normal\",\r\n            \"bytes\": 99336,\r\n            \"sha256\": \"f31db446c61f36d6775548bff4d04ea21b54dfc1e3271d39b719ab6c48b9c208\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-river-stone/roughness\",\r\n            \"bytes\": 13096,\r\n            \"sha256\": \"65ca034f5f657db0fcf502c93b2bacc3f1a66a572ed3e24d09ba3fadbbb80757\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-river-stone/height\",\r\n            \"bytes\": 9202,\r\n            \"sha256\": \"8e5b35579dce02cbb1fbfa415762a6b65724ef86898c3cc53de36b37398f90ce\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-river-stone/ao\",\r\n            \"bytes\": 22322,\r\n            \"sha256\": \"985e2218cda815c2549c0a926df7d26f050ba1e34eccb4a859fba17c6ec9489e\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-river-stone/tintMask\",\r\n            \"bytes\": 76542,\r\n            \"sha256\": \"b603234beb199542b602fd2a8823ba1416f4be342b69168bc85e6bfc15a76e4f\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-river-stone/preview\",\r\n            \"bytes\": 57812,\r\n            \"sha256\": \"09b86e6e3c10f2c1581c3a46507d593fe561e8bfed7628d35665d695ae4926a7\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-biolume-moss\",\r\n      \"displayName\": \"Biolume Moss\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Moss002\",\r\n      \"collection\": \"creature-forged-realms\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Moss002\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-biolume-moss/basecolor.webp\",\r\n          \"bytes\": 73648,\r\n          \"sha256\": \"269fd39b656f9e882f9b6ce516b3f0ae5ea9017a03b6851260618786f9263be6\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-biolume-moss/normal.webp\",\r\n          \"bytes\": 87824,\r\n          \"sha256\": \"9d94ac281cdfc8297c1dd5b49be3270eee9464bfa9a0e2c39339efab2c89a21b\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-biolume-moss/roughness.webp\",\r\n          \"bytes\": 39816,\r\n          \"sha256\": \"4583d9d7365e367dde4f2dea9a4cbc3f4e96670a46fa16d808f8378bb2a9ea62\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-biolume-moss/height.webp\",\r\n          \"bytes\": 25618,\r\n          \"sha256\": \"f4f5a28835d31558f808f1889a69753b478f09a169d28ac51d44bc5971776836\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-biolume-moss/ao.webp\",\r\n          \"bytes\": 78346,\r\n          \"sha256\": \"99d195c2cc601acfbf776b793ca98cb79eceab56bdafc50b788e3231734cf773\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-biolume-moss/tint-mask.webp\",\r\n          \"bytes\": 99630,\r\n          \"sha256\": \"45f5f81dd4fe98c3df7bfd5fd912fbd239d2e53e2d8bde98b3f724c83eefebda\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-biolume-moss/preview.webp\",\r\n          \"bytes\": 77278,\r\n          \"sha256\": \"4da02ca977708a4ebfa784dd8d51012455c1d85071a6074748db15f5c3d9744d\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-biolume-moss/basecolor\",\r\n            \"bytes\": 73648,\r\n            \"sha256\": \"269fd39b656f9e882f9b6ce516b3f0ae5ea9017a03b6851260618786f9263be6\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-biolume-moss/normal\",\r\n            \"bytes\": 87824,\r\n            \"sha256\": \"9d94ac281cdfc8297c1dd5b49be3270eee9464bfa9a0e2c39339efab2c89a21b\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-biolume-moss/roughness\",\r\n            \"bytes\": 39816,\r\n            \"sha256\": \"4583d9d7365e367dde4f2dea9a4cbc3f4e96670a46fa16d808f8378bb2a9ea62\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-biolume-moss/height\",\r\n            \"bytes\": 25618,\r\n            \"sha256\": \"f4f5a28835d31558f808f1889a69753b478f09a169d28ac51d44bc5971776836\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-biolume-moss/ao\",\r\n            \"bytes\": 78346,\r\n            \"sha256\": \"99d195c2cc601acfbf776b793ca98cb79eceab56bdafc50b788e3231734cf773\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-biolume-moss/tintMask\",\r\n            \"bytes\": 99630,\r\n            \"sha256\": \"45f5f81dd4fe98c3df7bfd5fd912fbd239d2e53e2d8bde98b3f724c83eefebda\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-biolume-moss/preview\",\r\n            \"bytes\": 77278,\r\n            \"sha256\": \"4da02ca977708a4ebfa784dd8d51012455c1d85071a6074748db15f5c3d9744d\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-mirror-knight\",\r\n      \"displayName\": \"Mirror Knight\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Metal048A\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal048A\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-mirror-knight/basecolor.webp\",\r\n          \"bytes\": 998,\r\n          \"sha256\": \"cf989101d5f5483fe0618ff51ec7b02ff6ab0afa5f01ff3f7fa2b3bba49e0f3f\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-mirror-knight/normal.webp\",\r\n          \"bytes\": 594,\r\n          \"sha256\": \"5a32ff9d82106a7811bf45e72645c15d9a8e2609a262c106ffb75126f8911156\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-mirror-knight/roughness.webp\",\r\n          \"bytes\": 732,\r\n          \"sha256\": \"cc0c496cd6cc5503fab83d82acd8ae3f1a7b5b25657ee25fffbed6308e26b5d5\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-mirror-knight/height.webp\",\r\n          \"bytes\": 526,\r\n          \"sha256\": \"abb51cd0690994d97aff0ad32ab12896592506ffd61886f569963b2f71e20c0f\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-mirror-knight/metalness.webp\",\r\n          \"bytes\": 532,\r\n          \"sha256\": \"cf3db3d5638b9b2a0d343c9db9efb673235385846a75c8edd0a88a7fb6bec60a\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-mirror-knight/tint-mask.webp\",\r\n          \"bytes\": 67594,\r\n          \"sha256\": \"b444a54a2f7db6df7e4afc8c80fecd82887db13cb7052f78fafd1e2593d31d06\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-mirror-knight/preview.webp\",\r\n          \"bytes\": 1298,\r\n          \"sha256\": \"ae8103593152bf336133fc8752255d8b40652633bb8bab142cf9c6c24d7927f6\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-mirror-knight/basecolor\",\r\n            \"bytes\": 998,\r\n            \"sha256\": \"cf989101d5f5483fe0618ff51ec7b02ff6ab0afa5f01ff3f7fa2b3bba49e0f3f\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-mirror-knight/normal\",\r\n            \"bytes\": 594,\r\n            \"sha256\": \"5a32ff9d82106a7811bf45e72645c15d9a8e2609a262c106ffb75126f8911156\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-mirror-knight/roughness\",\r\n            \"bytes\": 732,\r\n            \"sha256\": \"cc0c496cd6cc5503fab83d82acd8ae3f1a7b5b25657ee25fffbed6308e26b5d5\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-mirror-knight/height\",\r\n            \"bytes\": 526,\r\n            \"sha256\": \"abb51cd0690994d97aff0ad32ab12896592506ffd61886f569963b2f71e20c0f\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-mirror-knight/metalness\",\r\n            \"bytes\": 532,\r\n            \"sha256\": \"cf3db3d5638b9b2a0d343c9db9efb673235385846a75c8edd0a88a7fb6bec60a\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-mirror-knight/tintMask\",\r\n            \"bytes\": 67594,\r\n            \"sha256\": \"b444a54a2f7db6df7e4afc8c80fecd82887db13cb7052f78fafd1e2593d31d06\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-mirror-knight/preview\",\r\n            \"bytes\": 1298,\r\n            \"sha256\": \"ae8103593152bf336133fc8752255d8b40652633bb8bab142cf9c6c24d7927f6\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-tarnished-crown\",\r\n      \"displayName\": \"Tarnished Crown\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Metal048C\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal048C\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-tarnished-crown/basecolor.webp\",\r\n          \"bytes\": 10056,\r\n          \"sha256\": \"454f8c9a4fd90d206920b5c41beb67ddc47d36867a2d36a48798b7ddfc630acf\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-tarnished-crown/normal.webp\",\r\n          \"bytes\": 902,\r\n          \"sha256\": \"7542c0e567980a2a46af77aeadd5c76784dc4347c4fc691e87b9c751c5a6d1af\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-tarnished-crown/roughness.webp\",\r\n          \"bytes\": 23264,\r\n          \"sha256\": \"3be7019d924a77751fbbf4665ea1db70ebccc721303c8d247094af69a16df282\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-tarnished-crown/height.webp\",\r\n          \"bytes\": 6612,\r\n          \"sha256\": \"9c8916c0d96e11bbc8e1d67b8d343fd2f99d8f8d97ff49469ee319cd36c19239\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-tarnished-crown/metalness.webp\",\r\n          \"bytes\": 9582,\r\n          \"sha256\": \"b9fcaedd9ea3a6871f2d74879ca30ca16f75e359544654ee54ee5792ba3887f5\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-tarnished-crown/tint-mask.webp\",\r\n          \"bytes\": 48438,\r\n          \"sha256\": \"caf136c6c920e0d4e7f52274c82d49b8e9474ec7d3c85534fae44cf7a50700d5\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-tarnished-crown/preview.webp\",\r\n          \"bytes\": 11978,\r\n          \"sha256\": \"ef892c02b1101c732a7f015956460d93fe490fc0507a4263d723c0bc4f0dbbf4\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-tarnished-crown/basecolor\",\r\n            \"bytes\": 10056,\r\n            \"sha256\": \"454f8c9a4fd90d206920b5c41beb67ddc47d36867a2d36a48798b7ddfc630acf\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-tarnished-crown/normal\",\r\n            \"bytes\": 902,\r\n            \"sha256\": \"7542c0e567980a2a46af77aeadd5c76784dc4347c4fc691e87b9c751c5a6d1af\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-tarnished-crown/roughness\",\r\n            \"bytes\": 23264,\r\n            \"sha256\": \"3be7019d924a77751fbbf4665ea1db70ebccc721303c8d247094af69a16df282\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-tarnished-crown/height\",\r\n            \"bytes\": 6612,\r\n            \"sha256\": \"9c8916c0d96e11bbc8e1d67b8d343fd2f99d8f8d97ff49469ee319cd36c19239\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-tarnished-crown/metalness\",\r\n            \"bytes\": 9582,\r\n            \"sha256\": \"b9fcaedd9ea3a6871f2d74879ca30ca16f75e359544654ee54ee5792ba3887f5\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-tarnished-crown/tintMask\",\r\n            \"bytes\": 48438,\r\n            \"sha256\": \"caf136c6c920e0d4e7f52274c82d49b8e9474ec7d3c85534fae44cf7a50700d5\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-tarnished-crown/preview\",\r\n            \"bytes\": 11978,\r\n            \"sha256\": \"ef892c02b1101c732a7f015956460d93fe490fc0507a4263d723c0bc4f0dbbf4\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-golden-scarab\",\r\n      \"displayName\": \"Golden Scarab\",\r\n      \"track\": \"chest\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Metal007\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Metal007\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-golden-scarab/basecolor.webp\",\r\n          \"bytes\": 18264,\r\n          \"sha256\": \"2daf24017e791d9cc0aa9cc72faf573da795869f14ecf318afee20f960bbfb83\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-golden-scarab/normal.webp\",\r\n          \"bytes\": 1042,\r\n          \"sha256\": \"a709a2db3fe891ed772681bfaa2a15d31dd1be3dd4e363b5a596b56fe5f9ad2c\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-golden-scarab/roughness.webp\",\r\n          \"bytes\": 15890,\r\n          \"sha256\": \"114f37f6188582bfa8b3dc368f523139c85eeca8383c90e812b40e7e2e96e0a1\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-golden-scarab/height.webp\",\r\n          \"bytes\": 1714,\r\n          \"sha256\": \"36bb936c56b9bc9f9edfe115c07c6f45d9be80864ab3f1aace77e5477ca92a65\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-golden-scarab/metalness.webp\",\r\n          \"bytes\": 1280,\r\n          \"sha256\": \"d01c0d2347828b7537974009e32fb25d455bb447ea01f459bdc02840e81d3c31\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-golden-scarab/tint-mask.webp\",\r\n          \"bytes\": 65652,\r\n          \"sha256\": \"43a5c55a78fa3ed7f775c0ca959082b2463f0e48ae75d273468169abf0f50c5d\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-golden-scarab/preview.webp\",\r\n          \"bytes\": 22470,\r\n          \"sha256\": \"99ddd90d95b9b01691fad6aff7e60cef3335c570d3bb30641fa73b29af0631b7\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"chest\"\r\n        },\r\n        \"pack\": \"track-chest\",\r\n        \"bundle\": \"assets/chest.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-golden-scarab/basecolor\",\r\n            \"bytes\": 18264,\r\n            \"sha256\": \"2daf24017e791d9cc0aa9cc72faf573da795869f14ecf318afee20f960bbfb83\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-golden-scarab/normal\",\r\n            \"bytes\": 1042,\r\n            \"sha256\": \"a709a2db3fe891ed772681bfaa2a15d31dd1be3dd4e363b5a596b56fe5f9ad2c\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-golden-scarab/roughness\",\r\n            \"bytes\": 15890,\r\n            \"sha256\": \"114f37f6188582bfa8b3dc368f523139c85eeca8383c90e812b40e7e2e96e0a1\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-golden-scarab/height\",\r\n            \"bytes\": 1714,\r\n            \"sha256\": \"36bb936c56b9bc9f9edfe115c07c6f45d9be80864ab3f1aace77e5477ca92a65\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-golden-scarab/metalness\",\r\n            \"bytes\": 1280,\r\n            \"sha256\": \"d01c0d2347828b7537974009e32fb25d455bb447ea01f459bdc02840e81d3c31\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-golden-scarab/tintMask\",\r\n            \"bytes\": 65652,\r\n            \"sha256\": \"43a5c55a78fa3ed7f775c0ca959082b2463f0e48ae75d273468169abf0f50c5d\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-golden-scarab/preview\",\r\n            \"bytes\": 22470,\r\n            \"sha256\": \"99ddd90d95b9b01691fad6aff7e60cef3335c570d3bb30641fa73b29af0631b7\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-emberflow\",\r\n      \"displayName\": \"Emberflow\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Lava001\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Lava001\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-emberflow/basecolor.webp\",\r\n          \"bytes\": 55502,\r\n          \"sha256\": \"8d7c4615eb329d5255a75792a997eb8ecae3102fb0782a5a2c46e11f9b4341fe\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-emberflow/normal.webp\",\r\n          \"bytes\": 105598,\r\n          \"sha256\": \"1873609c656f2b3764003fbc9b97b91ad3f5e3e69a2aaa4d201d9e7cdc4aec4c\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-emberflow/roughness.webp\",\r\n          \"bytes\": 12882,\r\n          \"sha256\": \"d48539733cedaf93bdad6b4c4c30708479a743c4fcbef499b3e362e312d021e0\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-emberflow/height.webp\",\r\n          \"bytes\": 13998,\r\n          \"sha256\": \"306286c666118aa7da6fc4b8f769a9b3735b40c0003d154d942ca9363f0acb46\"\r\n        },\r\n        \"emissive\": {\r\n          \"file\": \"textures/creature-emberflow/emissive.webp\",\r\n          \"bytes\": 52850,\r\n          \"sha256\": \"bda5fa0ee23d6b225e2782f34061a4e017831e2e78287a3d781e1a2ac02cd01d\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-emberflow/tint-mask.webp\",\r\n          \"bytes\": 51236,\r\n          \"sha256\": \"5b3f83b8fa0c50e04da28b1f8a6ad0789cd376613700502a023e1775b3ec66ac\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-emberflow/preview.webp\",\r\n          \"bytes\": 57834,\r\n          \"sha256\": \"e4df8266f2fadc583a59d6357a024597de261bfb24bb316c7933ead30de08530\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-emberflow/basecolor\",\r\n            \"bytes\": 55502,\r\n            \"sha256\": \"8d7c4615eb329d5255a75792a997eb8ecae3102fb0782a5a2c46e11f9b4341fe\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-emberflow/normal\",\r\n            \"bytes\": 105598,\r\n            \"sha256\": \"1873609c656f2b3764003fbc9b97b91ad3f5e3e69a2aaa4d201d9e7cdc4aec4c\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-emberflow/roughness\",\r\n            \"bytes\": 12882,\r\n            \"sha256\": \"d48539733cedaf93bdad6b4c4c30708479a743c4fcbef499b3e362e312d021e0\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-emberflow/height\",\r\n            \"bytes\": 13998,\r\n            \"sha256\": \"306286c666118aa7da6fc4b8f769a9b3735b40c0003d154d942ca9363f0acb46\"\r\n          },\r\n          \"emissive\": {\r\n            \"entry\": \"creature-emberflow/emissive\",\r\n            \"bytes\": 52850,\r\n            \"sha256\": \"bda5fa0ee23d6b225e2782f34061a4e017831e2e78287a3d781e1a2ac02cd01d\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-emberflow/tintMask\",\r\n            \"bytes\": 51236,\r\n            \"sha256\": \"5b3f83b8fa0c50e04da28b1f8a6ad0789cd376613700502a023e1775b3ec66ac\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-emberflow/preview\",\r\n            \"bytes\": 57834,\r\n            \"sha256\": \"e4df8266f2fadc583a59d6357a024597de261bfb24bb316c7933ead30de08530\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-volcanic-heart\",\r\n      \"displayName\": \"Volcanic Heart\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Lava005\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Lava005\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-volcanic-heart/basecolor.webp\",\r\n          \"bytes\": 52804,\r\n          \"sha256\": \"24781f33f16d0161ca0485e6a732e97c1b9d4a91540c189bf8f748769a27f635\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-volcanic-heart/normal.webp\",\r\n          \"bytes\": 54736,\r\n          \"sha256\": \"ddd24a1373442f4b842c73a45b771aa149357a9d82faf8be149a61c0b9348418\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-volcanic-heart/roughness.webp\",\r\n          \"bytes\": 20200,\r\n          \"sha256\": \"cf52abbc709aefd88e4329ff6804d850235f0532933ec1d3cd103f0016daabfe\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-volcanic-heart/height.webp\",\r\n          \"bytes\": 11990,\r\n          \"sha256\": \"467c8ffc3521c5ca0450ebc4160b392c1f758d4d7222abbc2d3845006af5fe98\"\r\n        },\r\n        \"emissive\": {\r\n          \"file\": \"textures/creature-volcanic-heart/emissive.webp\",\r\n          \"bytes\": 61420,\r\n          \"sha256\": \"e2651a8d3fa04f74745ccad8f023e5bbe5129e500002f88fb3097fe9ae3aa06f\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-volcanic-heart/tint-mask.webp\",\r\n          \"bytes\": 53772,\r\n          \"sha256\": \"eebca000a86cc39d9763ce73e65b718bceda6680db69695b2cf997d625db79cc\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-volcanic-heart/preview.webp\",\r\n          \"bytes\": 51986,\r\n          \"sha256\": \"53c8262cb4b87704104d0bb9e484a5140c839a3bf051a0adbd962306c6e06b84\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-volcanic-heart/basecolor\",\r\n            \"bytes\": 52804,\r\n            \"sha256\": \"24781f33f16d0161ca0485e6a732e97c1b9d4a91540c189bf8f748769a27f635\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-volcanic-heart/normal\",\r\n            \"bytes\": 54736,\r\n            \"sha256\": \"ddd24a1373442f4b842c73a45b771aa149357a9d82faf8be149a61c0b9348418\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-volcanic-heart/roughness\",\r\n            \"bytes\": 20200,\r\n            \"sha256\": \"cf52abbc709aefd88e4329ff6804d850235f0532933ec1d3cd103f0016daabfe\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-volcanic-heart/height\",\r\n            \"bytes\": 11990,\r\n            \"sha256\": \"467c8ffc3521c5ca0450ebc4160b392c1f758d4d7222abbc2d3845006af5fe98\"\r\n          },\r\n          \"emissive\": {\r\n            \"entry\": \"creature-volcanic-heart/emissive\",\r\n            \"bytes\": 61420,\r\n            \"sha256\": \"e2651a8d3fa04f74745ccad8f023e5bbe5129e500002f88fb3097fe9ae3aa06f\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-volcanic-heart/tintMask\",\r\n            \"bytes\": 53772,\r\n            \"sha256\": \"eebca000a86cc39d9763ce73e65b718bceda6680db69695b2cf997d625db79cc\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-volcanic-heart/preview\",\r\n            \"bytes\": 51986,\r\n            \"sha256\": \"53c8262cb4b87704104d0bb9e484a5140c839a3bf051a0adbd962306c6e06b84\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-aurora-ice\",\r\n      \"displayName\": \"Aurora Ice\",\r\n      \"track\": \"quads\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Ice004\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Ice004\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-aurora-ice/basecolor.webp\",\r\n          \"bytes\": 28102,\r\n          \"sha256\": \"a0538e8060a8e9c00a04c5f7ac9234416cd40f85a1f5be2e6a7419d890eadf47\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-aurora-ice/normal.webp\",\r\n          \"bytes\": 9418,\r\n          \"sha256\": \"c933ddbc26012694f81f9533fcf670782c573daf6c300317b0ee70807d7474f6\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-aurora-ice/roughness.webp\",\r\n          \"bytes\": 16912,\r\n          \"sha256\": \"aa50ef45b5034739a1f48d34a8c842ad2444596d1bb7f60ce3f71be88c1dff65\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-aurora-ice/height.webp\",\r\n          \"bytes\": 24584,\r\n          \"sha256\": \"ff582e80c4af2ac6b52e235055a6d19ddc34213b22fe6ac90beb6c09b8788ef9\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-aurora-ice/tint-mask.webp\",\r\n          \"bytes\": 33120,\r\n          \"sha256\": \"b89c0d07aae4bccea7ac26b589e72ff5ececca87bc166d2dc23406dd943d51b4\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-aurora-ice/preview.webp\",\r\n          \"bytes\": 33622,\r\n          \"sha256\": \"fec978367e0c56323ce5b3f91bef4c1a624e8934e6d2933174b957264fc5229a\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"quads\"\r\n        },\r\n        \"pack\": \"track-quads\",\r\n        \"bundle\": \"assets/quads.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-aurora-ice/basecolor\",\r\n            \"bytes\": 28102,\r\n            \"sha256\": \"a0538e8060a8e9c00a04c5f7ac9234416cd40f85a1f5be2e6a7419d890eadf47\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-aurora-ice/normal\",\r\n            \"bytes\": 9418,\r\n            \"sha256\": \"c933ddbc26012694f81f9533fcf670782c573daf6c300317b0ee70807d7474f6\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-aurora-ice/roughness\",\r\n            \"bytes\": 16912,\r\n            \"sha256\": \"aa50ef45b5034739a1f48d34a8c842ad2444596d1bb7f60ce3f71be88c1dff65\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-aurora-ice/height\",\r\n            \"bytes\": 24584,\r\n            \"sha256\": \"ff582e80c4af2ac6b52e235055a6d19ddc34213b22fe6ac90beb6c09b8788ef9\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-aurora-ice/tintMask\",\r\n            \"bytes\": 33120,\r\n            \"sha256\": \"b89c0d07aae4bccea7ac26b589e72ff5ececca87bc166d2dc23406dd943d51b4\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-aurora-ice/preview\",\r\n            \"bytes\": 33622,\r\n            \"sha256\": \"fec978367e0c56323ce5b3f91bef4c1a624e8934e6d2933174b957264fc5229a\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-ironbark\",\r\n      \"displayName\": \"Ironbark\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Bark014\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bark014\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-ironbark/basecolor.webp\",\r\n          \"bytes\": 60524,\r\n          \"sha256\": \"60f5086a4946ae52491ea871bbec6dde8a4209cad3dc6711c66d0f520e9bd1c7\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-ironbark/normal.webp\",\r\n          \"bytes\": 39240,\r\n          \"sha256\": \"9e83a63d061651cfaa0892d55ed76762d8493589327db6fb2724254afffad688\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-ironbark/roughness.webp\",\r\n          \"bytes\": 61578,\r\n          \"sha256\": \"ff1bfd55ebc76fc610082d172138cc5b971c2de306a7626696fddd2ac2c0e304\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-ironbark/height.webp\",\r\n          \"bytes\": 11624,\r\n          \"sha256\": \"24dca043922c977d7cd8b58a7a9f8aa5132919693a5d666e4a358a3216a66b15\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-ironbark/ao.webp\",\r\n          \"bytes\": 46376,\r\n          \"sha256\": \"3df1b05d4423870ddf7ab97338ad860ec2f87924492fa008c28e4ac3225c1484\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-ironbark/tint-mask.webp\",\r\n          \"bytes\": 71852,\r\n          \"sha256\": \"d1e6acc31473ff62d8dd0022ddad5b542067eea35877b051a1460929d7934ee4\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-ironbark/preview.webp\",\r\n          \"bytes\": 68160,\r\n          \"sha256\": \"8ba5961f132720e02a894e9da7228305ca5ee4a2c2fc720406f8505055a56dd6\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-ironbark/basecolor\",\r\n            \"bytes\": 60524,\r\n            \"sha256\": \"60f5086a4946ae52491ea871bbec6dde8a4209cad3dc6711c66d0f520e9bd1c7\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-ironbark/normal\",\r\n            \"bytes\": 39240,\r\n            \"sha256\": \"9e83a63d061651cfaa0892d55ed76762d8493589327db6fb2724254afffad688\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-ironbark/roughness\",\r\n            \"bytes\": 61578,\r\n            \"sha256\": \"ff1bfd55ebc76fc610082d172138cc5b971c2de306a7626696fddd2ac2c0e304\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-ironbark/height\",\r\n            \"bytes\": 11624,\r\n            \"sha256\": \"24dca043922c977d7cd8b58a7a9f8aa5132919693a5d666e4a358a3216a66b15\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-ironbark/ao\",\r\n            \"bytes\": 46376,\r\n            \"sha256\": \"3df1b05d4423870ddf7ab97338ad860ec2f87924492fa008c28e4ac3225c1484\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-ironbark/tintMask\",\r\n            \"bytes\": 71852,\r\n            \"sha256\": \"d1e6acc31473ff62d8dd0022ddad5b542067eea35877b051a1460929d7934ee4\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-ironbark/preview\",\r\n            \"bytes\": 68160,\r\n            \"sha256\": \"8ba5961f132720e02a894e9da7228305ca5ee4a2c2fc720406f8505055a56dd6\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-oakscale\",\r\n      \"displayName\": \"Oakscale\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Bark012\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bark012\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-oakscale/basecolor.webp\",\r\n          \"bytes\": 71646,\r\n          \"sha256\": \"8d3becd0bdfbd0af4b40925b5f8f2d29ea593f1116656a871e6f1c84be542b1a\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-oakscale/normal.webp\",\r\n          \"bytes\": 122322,\r\n          \"sha256\": \"3ea9636011eea9ee7e49d4cfa6010271004abb65356a9c700d9ef3a9ddbdf8c1\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-oakscale/roughness.webp\",\r\n          \"bytes\": 56118,\r\n          \"sha256\": \"99e51498071e74aa167b77ec90fe99834061c115f521b11aedb61e742ef15883\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-oakscale/height.webp\",\r\n          \"bytes\": 36178,\r\n          \"sha256\": \"92ee5632dde0de291489635709bc55a45ac89d3cb6f834362c52ca1546954303\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-oakscale/ao.webp\",\r\n          \"bytes\": 59772,\r\n          \"sha256\": \"fdf1d31853c9c9629dddd9c705f24058b8b75ab120ac6d7a017382aa3e45917d\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-oakscale/tint-mask.webp\",\r\n          \"bytes\": 89244,\r\n          \"sha256\": \"2d996f056ca9fa7a6b1ecd25d85fca69c1de2c609dc44e6caea2873a03452060\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-oakscale/preview.webp\",\r\n          \"bytes\": 80436,\r\n          \"sha256\": \"8f988fc7f1ebbae37fcb79fd405acbc22d377985fe7fa26e1eefb7f0dbc7d157\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-oakscale/basecolor\",\r\n            \"bytes\": 71646,\r\n            \"sha256\": \"8d3becd0bdfbd0af4b40925b5f8f2d29ea593f1116656a871e6f1c84be542b1a\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-oakscale/normal\",\r\n            \"bytes\": 122322,\r\n            \"sha256\": \"3ea9636011eea9ee7e49d4cfa6010271004abb65356a9c700d9ef3a9ddbdf8c1\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-oakscale/roughness\",\r\n            \"bytes\": 56118,\r\n            \"sha256\": \"99e51498071e74aa167b77ec90fe99834061c115f521b11aedb61e742ef15883\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-oakscale/height\",\r\n            \"bytes\": 36178,\r\n            \"sha256\": \"92ee5632dde0de291489635709bc55a45ac89d3cb6f834362c52ca1546954303\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-oakscale/ao\",\r\n            \"bytes\": 59772,\r\n            \"sha256\": \"fdf1d31853c9c9629dddd9c705f24058b8b75ab120ac6d7a017382aa3e45917d\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-oakscale/tintMask\",\r\n            \"bytes\": 89244,\r\n            \"sha256\": \"2d996f056ca9fa7a6b1ecd25d85fca69c1de2c609dc44e6caea2873a03452060\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-oakscale/preview\",\r\n            \"bytes\": 80436,\r\n            \"sha256\": \"8f988fc7f1ebbae37fcb79fd405acbc22d377985fe7fa26e1eefb7f0dbc7d157\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-mosswood\",\r\n      \"displayName\": \"Mosswood\",\r\n      \"track\": \"glutes\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Bark008\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Bark008\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-mosswood/basecolor.webp\",\r\n          \"bytes\": 59368,\r\n          \"sha256\": \"890bb90b337f9a4663ed45f17530a98f5bc40f04abd9a29cc780b5ac830e49e7\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-mosswood/normal.webp\",\r\n          \"bytes\": 115452,\r\n          \"sha256\": \"20240bb5ea158afe45c86d472671e936b74115dcc7dbab57e512f3614bca4b65\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-mosswood/roughness.webp\",\r\n          \"bytes\": 14720,\r\n          \"sha256\": \"52fa0eddcfb1857471dfc86cce4be8a75dd36181f9ed10c0a0252257022611b8\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-mosswood/height.webp\",\r\n          \"bytes\": 14968,\r\n          \"sha256\": \"3ca291939907de9d57ae256ee4a017ab3f225ef10ef246b1769a53d4368fe38e\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-mosswood/ao.webp\",\r\n          \"bytes\": 30290,\r\n          \"sha256\": \"5d159bd50f689dd5550f5ddf1a1b043f79e3f17b72f50ddbfdb7af704967e84a\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-mosswood/tint-mask.webp\",\r\n          \"bytes\": 71764,\r\n          \"sha256\": \"12749b87113aadaa3e904354fd91a46d0b2f7b1fd3bbb080f68ebdb27c12fc69\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-mosswood/preview.webp\",\r\n          \"bytes\": 68928,\r\n          \"sha256\": \"cd7f6299839d2cd701535eba1526d1054b9f763539668a9aa7b6dd7d7460ea71\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"glutes\"\r\n        },\r\n        \"pack\": \"track-glutes\",\r\n        \"bundle\": \"assets/glutes.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-mosswood/basecolor\",\r\n            \"bytes\": 59368,\r\n            \"sha256\": \"890bb90b337f9a4663ed45f17530a98f5bc40f04abd9a29cc780b5ac830e49e7\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-mosswood/normal\",\r\n            \"bytes\": 115452,\r\n            \"sha256\": \"20240bb5ea158afe45c86d472671e936b74115dcc7dbab57e512f3614bca4b65\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-mosswood/roughness\",\r\n            \"bytes\": 14720,\r\n            \"sha256\": \"52fa0eddcfb1857471dfc86cce4be8a75dd36181f9ed10c0a0252257022611b8\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-mosswood/height\",\r\n            \"bytes\": 14968,\r\n            \"sha256\": \"3ca291939907de9d57ae256ee4a017ab3f225ef10ef246b1769a53d4368fe38e\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-mosswood/ao\",\r\n            \"bytes\": 30290,\r\n            \"sha256\": \"5d159bd50f689dd5550f5ddf1a1b043f79e3f17b72f50ddbfdb7af704967e84a\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-mosswood/tintMask\",\r\n            \"bytes\": 71764,\r\n            \"sha256\": \"12749b87113aadaa3e904354fd91a46d0b2f7b1fd3bbb080f68ebdb27c12fc69\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-mosswood/preview\",\r\n            \"bytes\": 68928,\r\n            \"sha256\": \"cd7f6299839d2cd701535eba1526d1054b9f763539668a9aa7b6dd7d7460ea71\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-blood-onyx\",\r\n      \"displayName\": \"Blood Onyx\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Onyx010\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx010\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-blood-onyx/basecolor.webp\",\r\n          \"bytes\": 49258,\r\n          \"sha256\": \"1e4ece1d137a8e59717dedb50696af52443a48bca8f6ed704c3bcb477e237bd2\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-blood-onyx/normal.webp\",\r\n          \"bytes\": 570,\r\n          \"sha256\": \"89b1d318ca9930effc69d7231739e063be9589e63823131668f65fcb7151fa25\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-blood-onyx/roughness.webp\",\r\n          \"bytes\": 3160,\r\n          \"sha256\": \"933156eac22cd38b2a55f39ff1af0eeb4cfd5fa3e09e29677c108d7ca0e5fd4e\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-blood-onyx/height.webp\",\r\n          \"bytes\": 2910,\r\n          \"sha256\": \"028bb3656a9f50c23a20d3985793c1d1629ad2164d8ec53a04fc333944d41dd9\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-blood-onyx/tint-mask.webp\",\r\n          \"bytes\": 55394,\r\n          \"sha256\": \"4d6ba964d297a4329ffdf69a3dbede66982b83703d2e44187ee233f062cbe69d\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-blood-onyx/preview.webp\",\r\n          \"bytes\": 56594,\r\n          \"sha256\": \"d6b36ee15022c78d7b968d51451e912ac91e4952fb46d8d9fe0a017d72a5fe31\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-blood-onyx/basecolor\",\r\n            \"bytes\": 49258,\r\n            \"sha256\": \"1e4ece1d137a8e59717dedb50696af52443a48bca8f6ed704c3bcb477e237bd2\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-blood-onyx/normal\",\r\n            \"bytes\": 570,\r\n            \"sha256\": \"89b1d318ca9930effc69d7231739e063be9589e63823131668f65fcb7151fa25\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-blood-onyx/roughness\",\r\n            \"bytes\": 3160,\r\n            \"sha256\": \"933156eac22cd38b2a55f39ff1af0eeb4cfd5fa3e09e29677c108d7ca0e5fd4e\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-blood-onyx/height\",\r\n            \"bytes\": 2910,\r\n            \"sha256\": \"028bb3656a9f50c23a20d3985793c1d1629ad2164d8ec53a04fc333944d41dd9\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-blood-onyx/tintMask\",\r\n            \"bytes\": 55394,\r\n            \"sha256\": \"4d6ba964d297a4329ffdf69a3dbede66982b83703d2e44187ee233f062cbe69d\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-blood-onyx/preview\",\r\n            \"bytes\": 56594,\r\n            \"sha256\": \"d6b36ee15022c78d7b968d51451e912ac91e4952fb46d8d9fe0a017d72a5fe31\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-honey-crystal\",\r\n      \"displayName\": \"Honey Crystal\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Onyx007\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx007\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-honey-crystal/basecolor.webp\",\r\n          \"bytes\": 22816,\r\n          \"sha256\": \"98aa336fb9c96553927f664e9b78d7664389e93a81555ef84870111fa958c67a\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-honey-crystal/normal.webp\",\r\n          \"bytes\": 560,\r\n          \"sha256\": \"bf3e55e83aeb3bce5033fd00ac0fb19ac787e3ca01d8573930809f453872035a\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-honey-crystal/roughness.webp\",\r\n          \"bytes\": 3020,\r\n          \"sha256\": \"b0000cf36bad38e720c4b5cbffa50bf28ee5a251b2cf0117ed531803a55dc886\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-honey-crystal/height.webp\",\r\n          \"bytes\": 2954,\r\n          \"sha256\": \"0a16ca42ec013f3eafc4342ed4940eb005379adbd6d879720a0969b5a37e8e89\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-honey-crystal/tint-mask.webp\",\r\n          \"bytes\": 34036,\r\n          \"sha256\": \"71cca8020dd06078c658313ddadf4d214f870a5264891bdb1f93d1773d03c789\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-honey-crystal/preview.webp\",\r\n          \"bytes\": 26820,\r\n          \"sha256\": \"6c9b3fcc76753d66a1059cfce8c6b0a1594eca5077ed9a55cfa747ce1892bae2\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-honey-crystal/basecolor\",\r\n            \"bytes\": 22816,\r\n            \"sha256\": \"98aa336fb9c96553927f664e9b78d7664389e93a81555ef84870111fa958c67a\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-honey-crystal/normal\",\r\n            \"bytes\": 560,\r\n            \"sha256\": \"bf3e55e83aeb3bce5033fd00ac0fb19ac787e3ca01d8573930809f453872035a\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-honey-crystal/roughness\",\r\n            \"bytes\": 3020,\r\n            \"sha256\": \"b0000cf36bad38e720c4b5cbffa50bf28ee5a251b2cf0117ed531803a55dc886\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-honey-crystal/height\",\r\n            \"bytes\": 2954,\r\n            \"sha256\": \"0a16ca42ec013f3eafc4342ed4940eb005379adbd6d879720a0969b5a37e8e89\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-honey-crystal/tintMask\",\r\n            \"bytes\": 34036,\r\n            \"sha256\": \"71cca8020dd06078c658313ddadf4d214f870a5264891bdb1f93d1773d03c789\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-honey-crystal/preview\",\r\n            \"bytes\": 26820,\r\n            \"sha256\": \"6c9b3fcc76753d66a1059cfce8c6b0a1594eca5077ed9a55cfa747ce1892bae2\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-void-mirror\",\r\n      \"displayName\": \"Void Mirror\",\r\n      \"track\": \"arms\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Onyx014\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx014\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-void-mirror/basecolor.webp\",\r\n          \"bytes\": 53930,\r\n          \"sha256\": \"cb69edc751c1c91fd28bd9904ad3c097d8dcf6edaaa570694c3fb9d6d6422a9d\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-void-mirror/normal.webp\",\r\n          \"bytes\": 576,\r\n          \"sha256\": \"17b7ad457b39e89d3b2da88be6dd5af7465bfd2a687e6e9574dd876d1c7f0d8c\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-void-mirror/roughness.webp\",\r\n          \"bytes\": 3126,\r\n          \"sha256\": \"616b3ba7e46a502a1bcfe1c280e30dd8c743f7e18d7f51aea0fec96372e9e14c\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-void-mirror/height.webp\",\r\n          \"bytes\": 3520,\r\n          \"sha256\": \"511981c03b2b6d5113991eeb75a42ffdda63e10637f05485fec7cbe6a2340df5\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-void-mirror/tint-mask.webp\",\r\n          \"bytes\": 62026,\r\n          \"sha256\": \"26cb90d6461d7324ab564e1e3bc9b587b7429cd5f4aad544ba0629a7b641b405\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-void-mirror/preview.webp\",\r\n          \"bytes\": 61294,\r\n          \"sha256\": \"5d17783eb003707e0ee546300ccd46d645db2b6743e0f68d7ed7c965440fd2d9\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"arms\"\r\n        },\r\n        \"pack\": \"track-arms\",\r\n        \"bundle\": \"assets/arms.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-void-mirror/basecolor\",\r\n            \"bytes\": 53930,\r\n            \"sha256\": \"cb69edc751c1c91fd28bd9904ad3c097d8dcf6edaaa570694c3fb9d6d6422a9d\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-void-mirror/normal\",\r\n            \"bytes\": 576,\r\n            \"sha256\": \"17b7ad457b39e89d3b2da88be6dd5af7465bfd2a687e6e9574dd876d1c7f0d8c\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-void-mirror/roughness\",\r\n            \"bytes\": 3126,\r\n            \"sha256\": \"616b3ba7e46a502a1bcfe1c280e30dd8c743f7e18d7f51aea0fec96372e9e14c\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-void-mirror/height\",\r\n            \"bytes\": 3520,\r\n            \"sha256\": \"511981c03b2b6d5113991eeb75a42ffdda63e10637f05485fec7cbe6a2340df5\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-void-mirror/tintMask\",\r\n            \"bytes\": 62026,\r\n            \"sha256\": \"26cb90d6461d7324ab564e1e3bc9b587b7429cd5f4aad544ba0629a7b641b405\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-void-mirror/preview\",\r\n            \"bytes\": 61294,\r\n            \"sha256\": \"5d17783eb003707e0ee546300ccd46d645db2b6743e0f68d7ed7c965440fd2d9\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-snow-wraith\",\r\n      \"displayName\": \"Snow Wraith\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Snow014\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Snow014\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-snow-wraith/basecolor.webp\",\r\n          \"bytes\": 6634,\r\n          \"sha256\": \"b44309b17f88a5dfe5afb6ae11d38eff932fc4ca31cf57de57dd177c7ad690cc\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-snow-wraith/normal.webp\",\r\n          \"bytes\": 25340,\r\n          \"sha256\": \"c660422b765aca94ffbe27547a70572642798298148e138a175c775efb8d7b83\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-snow-wraith/roughness.webp\",\r\n          \"bytes\": 11026,\r\n          \"sha256\": \"cf39931b6ecaacadf1f308870a1d6e1eb45a73e2b46e117f4b4e0a76d7b44ce1\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-snow-wraith/height.webp\",\r\n          \"bytes\": 11568,\r\n          \"sha256\": \"6075c35c42067b2b476a0ba6aae9c727b946ae75b3afd5b6e168d9bd3f51385b\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-snow-wraith/ao.webp\",\r\n          \"bytes\": 4376,\r\n          \"sha256\": \"08233059a6af6b3c8c14077b17b6d7325895eda0b725b91e55fcead6f887c042\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-snow-wraith/tint-mask.webp\",\r\n          \"bytes\": 47502,\r\n          \"sha256\": \"21fa7be4a5d63492a2a37787d68d3ceb586c995715fa1668f07f338998ef7b1e\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-snow-wraith/preview.webp\",\r\n          \"bytes\": 8238,\r\n          \"sha256\": \"b3ad0d3e51855f8bc66f7f2064d4a8e220b9bd6bbb85113ce7e12249f3b4c151\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-snow-wraith/basecolor\",\r\n            \"bytes\": 6634,\r\n            \"sha256\": \"b44309b17f88a5dfe5afb6ae11d38eff932fc4ca31cf57de57dd177c7ad690cc\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-snow-wraith/normal\",\r\n            \"bytes\": 25340,\r\n            \"sha256\": \"c660422b765aca94ffbe27547a70572642798298148e138a175c775efb8d7b83\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-snow-wraith/roughness\",\r\n            \"bytes\": 11026,\r\n            \"sha256\": \"cf39931b6ecaacadf1f308870a1d6e1eb45a73e2b46e117f4b4e0a76d7b44ce1\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-snow-wraith/height\",\r\n            \"bytes\": 11568,\r\n            \"sha256\": \"6075c35c42067b2b476a0ba6aae9c727b946ae75b3afd5b6e168d9bd3f51385b\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-snow-wraith/ao\",\r\n            \"bytes\": 4376,\r\n            \"sha256\": \"08233059a6af6b3c8c14077b17b6d7325895eda0b725b91e55fcead6f887c042\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-snow-wraith/tintMask\",\r\n            \"bytes\": 47502,\r\n            \"sha256\": \"21fa7be4a5d63492a2a37787d68d3ceb586c995715fa1668f07f338998ef7b1e\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-snow-wraith/preview\",\r\n            \"bytes\": 8238,\r\n            \"sha256\": \"b3ad0d3e51855f8bc66f7f2064d4a8e220b9bd6bbb85113ce7e12249f3b4c151\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-moon-drift\",\r\n      \"displayName\": \"Moon Drift\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Snow008A\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Snow008A\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-moon-drift/basecolor.webp\",\r\n          \"bytes\": 1988,\r\n          \"sha256\": \"a0a0deef40357c248c3cd25b62c94196dee75bda282579f2f0af607091ecddd7\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-moon-drift/normal.webp\",\r\n          \"bytes\": 19748,\r\n          \"sha256\": \"b41d538eb2be50037fc7646838ff397a30bad39e2c215c8e6ec0f7cc5aab3abb\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-moon-drift/roughness.webp\",\r\n          \"bytes\": 42334,\r\n          \"sha256\": \"940f50573bb0c93f00b1716d5fc8351aaea5cfd688248ab7e3b69555a68fedf4\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-moon-drift/height.webp\",\r\n          \"bytes\": 10336,\r\n          \"sha256\": \"00cda68ddb767c0578a91423d56f9f0ca59a30c24a5663c2c720a135a522f8dc\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-moon-drift/ao.webp\",\r\n          \"bytes\": 5248,\r\n          \"sha256\": \"638072ac50033602f96649275c9d1ff2cc406c5a371fdaac55408ff476dd03a5\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-moon-drift/tint-mask.webp\",\r\n          \"bytes\": 62850,\r\n          \"sha256\": \"2bea2a3b58ed3f2a1b1179cd07e38f556e4c592607461c32f4cba4f1dbb0d21d\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-moon-drift/preview.webp\",\r\n          \"bytes\": 2558,\r\n          \"sha256\": \"425a6acfc362bfe037e494df1adb4d6676d8c3825a6dcd3d5a0d8f488bc65f87\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-moon-drift/basecolor\",\r\n            \"bytes\": 1988,\r\n            \"sha256\": \"a0a0deef40357c248c3cd25b62c94196dee75bda282579f2f0af607091ecddd7\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-moon-drift/normal\",\r\n            \"bytes\": 19748,\r\n            \"sha256\": \"b41d538eb2be50037fc7646838ff397a30bad39e2c215c8e6ec0f7cc5aab3abb\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-moon-drift/roughness\",\r\n            \"bytes\": 42334,\r\n            \"sha256\": \"940f50573bb0c93f00b1716d5fc8351aaea5cfd688248ab7e3b69555a68fedf4\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-moon-drift/height\",\r\n            \"bytes\": 10336,\r\n            \"sha256\": \"00cda68ddb767c0578a91423d56f9f0ca59a30c24a5663c2c720a135a522f8dc\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-moon-drift/ao\",\r\n            \"bytes\": 5248,\r\n            \"sha256\": \"638072ac50033602f96649275c9d1ff2cc406c5a371fdaac55408ff476dd03a5\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-moon-drift/tintMask\",\r\n            \"bytes\": 62850,\r\n            \"sha256\": \"2bea2a3b58ed3f2a1b1179cd07e38f556e4c592607461c32f4cba4f1dbb0d21d\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-moon-drift/preview\",\r\n            \"bytes\": 2558,\r\n            \"sha256\": \"425a6acfc362bfe037e494df1adb4d6676d8c3825a6dcd3d5a0d8f488bc65f87\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-pearl-spirit\",\r\n      \"displayName\": \"Pearl Spirit\",\r\n      \"track\": \"yoga\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Onyx015\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Onyx015\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-pearl-spirit/basecolor.webp\",\r\n          \"bytes\": 29558,\r\n          \"sha256\": \"ecd31972e0f2bd3dcbb56dd83966989cbaa724514cc57576769886ee69277bc4\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-pearl-spirit/normal.webp\",\r\n          \"bytes\": 578,\r\n          \"sha256\": \"bc6c55f9b7c548eb294b544cffd95bead865725a62e2b07b26a954175f8f7de2\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-pearl-spirit/roughness.webp\",\r\n          \"bytes\": 2712,\r\n          \"sha256\": \"e4d14e77c9b45e27f077ba5a1a549ce863650380a48babb5c3b02a6d9322c2d8\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-pearl-spirit/height.webp\",\r\n          \"bytes\": 2632,\r\n          \"sha256\": \"5b01611a42e4e95216112bc1c263ad8c730fb412d74ed44f5e07085eecf24432\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-pearl-spirit/tint-mask.webp\",\r\n          \"bytes\": 70938,\r\n          \"sha256\": \"000adcbc57cc83e8e2205c13dc421e9b8929d602006c2e3ca780725819dbf3c6\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-pearl-spirit/preview.webp\",\r\n          \"bytes\": 36178,\r\n          \"sha256\": \"5494688e1ef1a80ddce772b1391f81c43c666d3595cc4dd567b807b393aafcda\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"yoga\"\r\n        },\r\n        \"pack\": \"track-yoga\",\r\n        \"bundle\": \"assets/yoga.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-pearl-spirit/basecolor\",\r\n            \"bytes\": 29558,\r\n            \"sha256\": \"ecd31972e0f2bd3dcbb56dd83966989cbaa724514cc57576769886ee69277bc4\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-pearl-spirit/normal\",\r\n            \"bytes\": 578,\r\n            \"sha256\": \"bc6c55f9b7c548eb294b544cffd95bead865725a62e2b07b26a954175f8f7de2\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-pearl-spirit/roughness\",\r\n            \"bytes\": 2712,\r\n            \"sha256\": \"e4d14e77c9b45e27f077ba5a1a549ce863650380a48babb5c3b02a6d9322c2d8\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-pearl-spirit/height\",\r\n            \"bytes\": 2632,\r\n            \"sha256\": \"5b01611a42e4e95216112bc1c263ad8c730fb412d74ed44f5e07085eecf24432\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-pearl-spirit/tintMask\",\r\n            \"bytes\": 70938,\r\n            \"sha256\": \"000adcbc57cc83e8e2205c13dc421e9b8929d602006c2e3ca780725819dbf3c6\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-pearl-spirit/preview\",\r\n            \"bytes\": 36178,\r\n            \"sha256\": \"5494688e1ef1a80ddce772b1391f81c43c666d3595cc4dd567b807b393aafcda\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-red-desert-scale\",\r\n      \"displayName\": \"Red Desert Scale\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Rock029\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Rock029\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-red-desert-scale/basecolor.webp\",\r\n          \"bytes\": 51964,\r\n          \"sha256\": \"7160db9a779efc4fb62326be77ba443ee4ae5604884e1ed691e902e47323b156\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-red-desert-scale/normal.webp\",\r\n          \"bytes\": 120276,\r\n          \"sha256\": \"450837f83a5ebbb2b9f31970d1c575fc18084358a7bf8fcf3912b5d5eddc3ec3\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-red-desert-scale/roughness.webp\",\r\n          \"bytes\": 28424,\r\n          \"sha256\": \"dd03959c9520cc2b6025073ef096c089b0f2d38b9f984ef1820d95caafc1992d\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-red-desert-scale/height.webp\",\r\n          \"bytes\": 8842,\r\n          \"sha256\": \"0e342c324ce19607da0bd50a966fa94b5c2e38fad0f37da848c7d666ed4518fe\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-red-desert-scale/ao.webp\",\r\n          \"bytes\": 19082,\r\n          \"sha256\": \"7ab01e1e8509a7d83f58c00ae0f702834d99120a4070ed92cedb6710a802a766\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-red-desert-scale/tint-mask.webp\",\r\n          \"bytes\": 83596,\r\n          \"sha256\": \"19a1bbac2eb458c1c6c36968566ac8e43e52cc62e5f57e9d1e47bfc81734e315\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-red-desert-scale/preview.webp\",\r\n          \"bytes\": 57218,\r\n          \"sha256\": \"d84d2ea7022224cea294456c3c8656abf0979856274bcc64be90a8b1378b39d2\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-red-desert-scale/basecolor\",\r\n            \"bytes\": 51964,\r\n            \"sha256\": \"7160db9a779efc4fb62326be77ba443ee4ae5604884e1ed691e902e47323b156\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-red-desert-scale/normal\",\r\n            \"bytes\": 120276,\r\n            \"sha256\": \"450837f83a5ebbb2b9f31970d1c575fc18084358a7bf8fcf3912b5d5eddc3ec3\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-red-desert-scale/roughness\",\r\n            \"bytes\": 28424,\r\n            \"sha256\": \"dd03959c9520cc2b6025073ef096c089b0f2d38b9f984ef1820d95caafc1992d\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-red-desert-scale/height\",\r\n            \"bytes\": 8842,\r\n            \"sha256\": \"0e342c324ce19607da0bd50a966fa94b5c2e38fad0f37da848c7d666ed4518fe\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-red-desert-scale/ao\",\r\n            \"bytes\": 19082,\r\n            \"sha256\": \"7ab01e1e8509a7d83f58c00ae0f702834d99120a4070ed92cedb6710a802a766\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-red-desert-scale/tintMask\",\r\n            \"bytes\": 83596,\r\n            \"sha256\": \"19a1bbac2eb458c1c6c36968566ac8e43e52cc62e5f57e9d1e47bfc81734e315\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-red-desert-scale/preview\",\r\n            \"bytes\": 57218,\r\n            \"sha256\": \"d84d2ea7022224cea294456c3c8656abf0979856274bcc64be90a8b1378b39d2\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-cave-drake\",\r\n      \"displayName\": \"Cave Drake\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Rock035\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Rock035\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-cave-drake/basecolor.webp\",\r\n          \"bytes\": 42954,\r\n          \"sha256\": \"891a196afba62375788c0b090019fd19941c04d25f9d760f135d57e60a1de00a\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-cave-drake/normal.webp\",\r\n          \"bytes\": 126116,\r\n          \"sha256\": \"8283888c871969dfe2b35f0cebd352a66a2cc46ad64bcb2bb5c5f8663b9c146e\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-cave-drake/roughness.webp\",\r\n          \"bytes\": 37152,\r\n          \"sha256\": \"ad45c8e7102239aef39f0154e1c57b3932742255f5799c0074a8b5435cecc5c5\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-cave-drake/height.webp\",\r\n          \"bytes\": 10778,\r\n          \"sha256\": \"bef40f1f39e9bf0e716195a417fa0fcaeb67ed09ec43b2ee5fb59030648e34d4\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-cave-drake/ao.webp\",\r\n          \"bytes\": 20824,\r\n          \"sha256\": \"e085d1a569564fdbe39a9dd18fa133a14ffa83117e8cdda10425bace18a70bd6\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-cave-drake/tint-mask.webp\",\r\n          \"bytes\": 59714,\r\n          \"sha256\": \"febea8d8da737dd8127c8049724d22d621219c483682ded32a4169c1f651c63a\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-cave-drake/preview.webp\",\r\n          \"bytes\": 52250,\r\n          \"sha256\": \"fd405d3986dd0eea39be9f341ec58591aa6e6ab66e25787adf3b2e16c62e634a\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-cave-drake/basecolor\",\r\n            \"bytes\": 42954,\r\n            \"sha256\": \"891a196afba62375788c0b090019fd19941c04d25f9d760f135d57e60a1de00a\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-cave-drake/normal\",\r\n            \"bytes\": 126116,\r\n            \"sha256\": \"8283888c871969dfe2b35f0cebd352a66a2cc46ad64bcb2bb5c5f8663b9c146e\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-cave-drake/roughness\",\r\n            \"bytes\": 37152,\r\n            \"sha256\": \"ad45c8e7102239aef39f0154e1c57b3932742255f5799c0074a8b5435cecc5c5\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-cave-drake/height\",\r\n            \"bytes\": 10778,\r\n            \"sha256\": \"bef40f1f39e9bf0e716195a417fa0fcaeb67ed09ec43b2ee5fb59030648e34d4\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-cave-drake/ao\",\r\n            \"bytes\": 20824,\r\n            \"sha256\": \"e085d1a569564fdbe39a9dd18fa133a14ffa83117e8cdda10425bace18a70bd6\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-cave-drake/tintMask\",\r\n            \"bytes\": 59714,\r\n            \"sha256\": \"febea8d8da737dd8127c8049724d22d621219c483682ded32a4169c1f651c63a\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-cave-drake/preview\",\r\n            \"bytes\": 52250,\r\n            \"sha256\": \"fd405d3986dd0eea39be9f341ec58591aa6e6ab66e25787adf3b2e16c62e634a\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-sandstone-titan\",\r\n      \"displayName\": \"Sandstone Titan\",\r\n      \"track\": \"martial-arts\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Rock061\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Rock061\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-sandstone-titan/basecolor.webp\",\r\n          \"bytes\": 19630,\r\n          \"sha256\": \"bb2d67e9addc03ae6dd1052db82b6f36d03d5af77cc2a63d48921844b652a3e0\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-sandstone-titan/normal.webp\",\r\n          \"bytes\": 59070,\r\n          \"sha256\": \"a9f2c10deb50d06074111b4f3cf220edb876633fae81c239f1c99718d1d07d46\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-sandstone-titan/roughness.webp\",\r\n          \"bytes\": 55850,\r\n          \"sha256\": \"d32bb23773fd03bedc81edeec043c823319e295e48198016095ff29ff988c373\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-sandstone-titan/height.webp\",\r\n          \"bytes\": 8100,\r\n          \"sha256\": \"cf13bbcf1fad8c96f467f178d905fb55f4d254fdcc8fa52f506f80de8362f264\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-sandstone-titan/ao.webp\",\r\n          \"bytes\": 15348,\r\n          \"sha256\": \"454cc3f34a0c059b046ee536585296a9195bb1259bc1ebb98b3377aeb19ad750\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-sandstone-titan/tint-mask.webp\",\r\n          \"bytes\": 41274,\r\n          \"sha256\": \"168d8de923125957c85b30e3e378b0586a7fd91d270a8c19042bea518d1d2529\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-sandstone-titan/preview.webp\",\r\n          \"bytes\": 24198,\r\n          \"sha256\": \"b379980f2c2907823755986994431b2fbe0d8e2a254616a89cefa1c3f1a810c3\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"martial-arts\"\r\n        },\r\n        \"pack\": \"track-martial-arts\",\r\n        \"bundle\": \"assets/martial-arts.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-sandstone-titan/basecolor\",\r\n            \"bytes\": 19630,\r\n            \"sha256\": \"bb2d67e9addc03ae6dd1052db82b6f36d03d5af77cc2a63d48921844b652a3e0\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-sandstone-titan/normal\",\r\n            \"bytes\": 59070,\r\n            \"sha256\": \"a9f2c10deb50d06074111b4f3cf220edb876633fae81c239f1c99718d1d07d46\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-sandstone-titan/roughness\",\r\n            \"bytes\": 55850,\r\n            \"sha256\": \"d32bb23773fd03bedc81edeec043c823319e295e48198016095ff29ff988c373\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-sandstone-titan/height\",\r\n            \"bytes\": 8100,\r\n            \"sha256\": \"cf13bbcf1fad8c96f467f178d905fb55f4d254fdcc8fa52f506f80de8362f264\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-sandstone-titan/ao\",\r\n            \"bytes\": 15348,\r\n            \"sha256\": \"454cc3f34a0c059b046ee536585296a9195bb1259bc1ebb98b3377aeb19ad750\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-sandstone-titan/tintMask\",\r\n            \"bytes\": 41274,\r\n            \"sha256\": \"168d8de923125957c85b30e3e378b0586a7fd91d270a8c19042bea518d1d2529\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-sandstone-titan/preview\",\r\n            \"bytes\": 24198,\r\n            \"sha256\": \"b379980f2c2907823755986994431b2fbe0d8e2a254616a89cefa1c3f1a810c3\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-neon-mainframe\",\r\n      \"displayName\": \"Neon Mainframe\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Chip002\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Chip002\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-neon-mainframe/basecolor.webp\",\r\n          \"bytes\": 56744,\r\n          \"sha256\": \"7af9b36dc24154d4dfe3b151dcafe44c1488643845a380e97d44c61d495c4b03\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-neon-mainframe/normal.webp\",\r\n          \"bytes\": 37362,\r\n          \"sha256\": \"413a59522d8e711071777b6a026805d22fb848881e396ae2e55892c47d3e621e\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-neon-mainframe/roughness.webp\",\r\n          \"bytes\": 41338,\r\n          \"sha256\": \"911155142f0e2266a6df466e0993e44b5039ac75e0d3489e37e0cffaa49df930\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-neon-mainframe/height.webp\",\r\n          \"bytes\": 33104,\r\n          \"sha256\": \"d1a60696213f4e3bb1af2d335aa37c7358fb9efa8877cd4b465422cba460ddcd\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-neon-mainframe/metalness.webp\",\r\n          \"bytes\": 45012,\r\n          \"sha256\": \"d8294af74841524440d65a0fc0390f11fb1e46fa9086b5adcae23f00e760b7bd\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-neon-mainframe/tint-mask.webp\",\r\n          \"bytes\": 50140,\r\n          \"sha256\": \"e0c65204a15a3f678c15e017fb84817d1d2f8e7f7184450cd85034303ad844e9\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-neon-mainframe/preview.webp\",\r\n          \"bytes\": 61118,\r\n          \"sha256\": \"6b904429406f8ff2f6decf39552837fbb1a69b51f6bd1f84ac1ae51b7b1ece44\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-neon-mainframe/basecolor\",\r\n            \"bytes\": 56744,\r\n            \"sha256\": \"7af9b36dc24154d4dfe3b151dcafe44c1488643845a380e97d44c61d495c4b03\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-neon-mainframe/normal\",\r\n            \"bytes\": 37362,\r\n            \"sha256\": \"413a59522d8e711071777b6a026805d22fb848881e396ae2e55892c47d3e621e\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-neon-mainframe/roughness\",\r\n            \"bytes\": 41338,\r\n            \"sha256\": \"911155142f0e2266a6df466e0993e44b5039ac75e0d3489e37e0cffaa49df930\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-neon-mainframe/height\",\r\n            \"bytes\": 33104,\r\n            \"sha256\": \"d1a60696213f4e3bb1af2d335aa37c7358fb9efa8877cd4b465422cba460ddcd\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-neon-mainframe/metalness\",\r\n            \"bytes\": 45012,\r\n            \"sha256\": \"d8294af74841524440d65a0fc0390f11fb1e46fa9086b5adcae23f00e760b7bd\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-neon-mainframe/tintMask\",\r\n            \"bytes\": 50140,\r\n            \"sha256\": \"e0c65204a15a3f678c15e017fb84817d1d2f8e7f7184450cd85034303ad844e9\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-neon-mainframe/preview\",\r\n            \"bytes\": 61118,\r\n            \"sha256\": \"6b904429406f8ff2f6decf39552837fbb1a69b51f6bd1f84ac1ae51b7b1ece44\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-reactor-grid\",\r\n      \"displayName\": \"Reactor Grid\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Chip004\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Chip004\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-reactor-grid/basecolor.webp\",\r\n          \"bytes\": 68780,\r\n          \"sha256\": \"87f6c7fad31ff2a102dd430f1b8e6a37efb6ea41d28c7c43ecd96a8ecff4ba87\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-reactor-grid/normal.webp\",\r\n          \"bytes\": 30258,\r\n          \"sha256\": \"29097e24c7f4977faa6b8de2cab3968aeb0d786f3304c5c30392e7217afa944a\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-reactor-grid/roughness.webp\",\r\n          \"bytes\": 28938,\r\n          \"sha256\": \"b259990ff0909332bf236b4be50db3aa119887ebcd2f9d59d28c20e0cf529da1\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-reactor-grid/height.webp\",\r\n          \"bytes\": 18820,\r\n          \"sha256\": \"2b43a252f9398122436a011c785fb684ef15b181442db3c784aebda559e57bb4\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-reactor-grid/metalness.webp\",\r\n          \"bytes\": 8980,\r\n          \"sha256\": \"07523450a21492207c75694b9a6413499417262e6439b07ddd21604ac728d05c\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-reactor-grid/tint-mask.webp\",\r\n          \"bytes\": 50226,\r\n          \"sha256\": \"730ad1404d4067b92705945e94980c58f8e069e3badf53f288b0559f27d2a386\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-reactor-grid/preview.webp\",\r\n          \"bytes\": 70556,\r\n          \"sha256\": \"b8d73dfa85b4af6399099734708bd705cfe9d9cf88942a6844a737c0a7c9e3f2\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-reactor-grid/basecolor\",\r\n            \"bytes\": 68780,\r\n            \"sha256\": \"87f6c7fad31ff2a102dd430f1b8e6a37efb6ea41d28c7c43ecd96a8ecff4ba87\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-reactor-grid/normal\",\r\n            \"bytes\": 30258,\r\n            \"sha256\": \"29097e24c7f4977faa6b8de2cab3968aeb0d786f3304c5c30392e7217afa944a\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-reactor-grid/roughness\",\r\n            \"bytes\": 28938,\r\n            \"sha256\": \"b259990ff0909332bf236b4be50db3aa119887ebcd2f9d59d28c20e0cf529da1\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-reactor-grid/height\",\r\n            \"bytes\": 18820,\r\n            \"sha256\": \"2b43a252f9398122436a011c785fb684ef15b181442db3c784aebda559e57bb4\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-reactor-grid/metalness\",\r\n            \"bytes\": 8980,\r\n            \"sha256\": \"07523450a21492207c75694b9a6413499417262e6439b07ddd21604ac728d05c\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-reactor-grid/tintMask\",\r\n            \"bytes\": 50226,\r\n            \"sha256\": \"730ad1404d4067b92705945e94980c58f8e069e3badf53f288b0559f27d2a386\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-reactor-grid/preview\",\r\n            \"bytes\": 70556,\r\n            \"sha256\": \"b8d73dfa85b4af6399099734708bd705cfe9d9cf88942a6844a737c0a7c9e3f2\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-quantum-core\",\r\n      \"displayName\": \"Quantum Core\",\r\n      \"track\": \"cardio\",\r\n      \"realm\": \"sci-fi\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Chip007\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Chip007\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-quantum-core/basecolor.webp\",\r\n          \"bytes\": 51286,\r\n          \"sha256\": \"60c77e1451ddd9d4acf761146d68273493a07ef74320e893906f896883e7f933\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-quantum-core/normal.webp\",\r\n          \"bytes\": 31990,\r\n          \"sha256\": \"adf7da0427d32ab38dace38c6656e873a6b9e345d6f2a41c42cfc640d437c46a\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-quantum-core/roughness.webp\",\r\n          \"bytes\": 31284,\r\n          \"sha256\": \"d489ea08a4eafc75c5c7c1af6cb535e6d56516906f9a2210b0313407b48713fd\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-quantum-core/height.webp\",\r\n          \"bytes\": 29580,\r\n          \"sha256\": \"7d44a79d77ba776128ff8836156b73f010c56ff8543d7fe1bf6994f21686efd7\"\r\n        },\r\n        \"metalness\": {\r\n          \"file\": \"textures/creature-quantum-core/metalness.webp\",\r\n          \"bytes\": 38108,\r\n          \"sha256\": \"2845ad0fae0dc3dd3c07aafe5e1758fb322dea33ec636e8036cebbb3f5e7c66b\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-quantum-core/tint-mask.webp\",\r\n          \"bytes\": 41968,\r\n          \"sha256\": \"5ec244d327e08f7f5cc6022500a829fb2ce697a6749506ca09de5c832efc8493\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-quantum-core/preview.webp\",\r\n          \"bytes\": 56764,\r\n          \"sha256\": \"51f0687bf78e65155d2e6e156e21bb6c2ce6f64b35fc7e7e9623fc94752b52f5\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"cardio\"\r\n        },\r\n        \"pack\": \"track-cardio\",\r\n        \"bundle\": \"assets/cardio.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-quantum-core/basecolor\",\r\n            \"bytes\": 51286,\r\n            \"sha256\": \"60c77e1451ddd9d4acf761146d68273493a07ef74320e893906f896883e7f933\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-quantum-core/normal\",\r\n            \"bytes\": 31990,\r\n            \"sha256\": \"adf7da0427d32ab38dace38c6656e873a6b9e345d6f2a41c42cfc640d437c46a\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-quantum-core/roughness\",\r\n            \"bytes\": 31284,\r\n            \"sha256\": \"d489ea08a4eafc75c5c7c1af6cb535e6d56516906f9a2210b0313407b48713fd\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-quantum-core/height\",\r\n            \"bytes\": 29580,\r\n            \"sha256\": \"7d44a79d77ba776128ff8836156b73f010c56ff8543d7fe1bf6994f21686efd7\"\r\n          },\r\n          \"metalness\": {\r\n            \"entry\": \"creature-quantum-core/metalness\",\r\n            \"bytes\": 38108,\r\n            \"sha256\": \"2845ad0fae0dc3dd3c07aafe5e1758fb322dea33ec636e8036cebbb3f5e7c66b\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-quantum-core/tintMask\",\r\n            \"bytes\": 41968,\r\n            \"sha256\": \"5ec244d327e08f7f5cc6022500a829fb2ce697a6749506ca09de5c832efc8493\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-quantum-core/preview\",\r\n            \"bytes\": 56764,\r\n            \"sha256\": \"51f0687bf78e65155d2e6e156e21bb6c2ce6f64b35fc7e7e9623fc94752b52f5\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-celestial-mosaic\",\r\n      \"displayName\": \"Celestial Mosaic\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"rare\",\r\n      \"sourceAssetId\": \"Tiles070\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 1,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Tiles070\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/basecolor.webp\",\r\n          \"bytes\": 72806,\r\n          \"sha256\": \"2e293d1642aa668793919b7d46bb50e94bcc36c0ce5d1f775463269a949f0978\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/normal.webp\",\r\n          \"bytes\": 40154,\r\n          \"sha256\": \"995e3446cf6f85eb57d7925922e187fc497a69355b82dfd069bcbd3f0029a175\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/roughness.webp\",\r\n          \"bytes\": 47808,\r\n          \"sha256\": \"29cbfb28025d5943765276c118b38d186b9294c6458bb6dc7a7da886ed989dd3\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/height.webp\",\r\n          \"bytes\": 38486,\r\n          \"sha256\": \"15cace7739e375a6dad5f5251d1b4e9cc8495abbba9f1560844e272cc5401ef0\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/ao.webp\",\r\n          \"bytes\": 46104,\r\n          \"sha256\": \"0da24064e9f490c342bf09e2149b58945e0ef0c555aa95b8c542615cf82b9fc1\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/tint-mask.webp\",\r\n          \"bytes\": 63262,\r\n          \"sha256\": \"c73737938011dfd0894b37e613d9de159b672e2813a34cd0f134080961935268\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-celestial-mosaic/preview.webp\",\r\n          \"bytes\": 76982,\r\n          \"sha256\": \"06b94f2aed6383bdcd79769cc0649b71ac08fb0dcdf26d7aa5c578f66ff974ca\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 1,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-celestial-mosaic/basecolor\",\r\n            \"bytes\": 72806,\r\n            \"sha256\": \"2e293d1642aa668793919b7d46bb50e94bcc36c0ce5d1f775463269a949f0978\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-celestial-mosaic/normal\",\r\n            \"bytes\": 40154,\r\n            \"sha256\": \"995e3446cf6f85eb57d7925922e187fc497a69355b82dfd069bcbd3f0029a175\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-celestial-mosaic/roughness\",\r\n            \"bytes\": 47808,\r\n            \"sha256\": \"29cbfb28025d5943765276c118b38d186b9294c6458bb6dc7a7da886ed989dd3\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-celestial-mosaic/height\",\r\n            \"bytes\": 38486,\r\n            \"sha256\": \"15cace7739e375a6dad5f5251d1b4e9cc8495abbba9f1560844e272cc5401ef0\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-celestial-mosaic/ao\",\r\n            \"bytes\": 46104,\r\n            \"sha256\": \"0da24064e9f490c342bf09e2149b58945e0ef0c555aa95b8c542615cf82b9fc1\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-celestial-mosaic/tintMask\",\r\n            \"bytes\": 63262,\r\n            \"sha256\": \"c73737938011dfd0894b37e613d9de159b672e2813a34cd0f134080961935268\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-celestial-mosaic/preview\",\r\n            \"bytes\": 76982,\r\n            \"sha256\": \"06b94f2aed6383bdcd79769cc0649b71ac08fb0dcdf26d7aa5c578f66ff974ca\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-shellborn\",\r\n      \"displayName\": \"Shellborn\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"fantasy\",\r\n      \"rarity\": \"epic\",\r\n      \"sourceAssetId\": \"Ground060\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 2,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Ground060\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-shellborn/basecolor.webp\",\r\n          \"bytes\": 9684,\r\n          \"sha256\": \"2ffb18fed343bdcf0b2ba3d4b0dea9e8e53711fb266563af356fc940dc129a40\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-shellborn/normal.webp\",\r\n          \"bytes\": 23222,\r\n          \"sha256\": \"d1a9e0f90dce9c6a37afe8819f96ce7af37ca19f8a3ed035bb2f2dc262695f83\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-shellborn/roughness.webp\",\r\n          \"bytes\": 8118,\r\n          \"sha256\": \"c7356a52eed60b3dd71af8ef399b497c5a984b1f076df5c12f07e1a2a57a3971\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-shellborn/height.webp\",\r\n          \"bytes\": 17122,\r\n          \"sha256\": \"7731dee5c6bafef91432e5df689468c0bd108baee671021effef7fdd6fed8545\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-shellborn/ao.webp\",\r\n          \"bytes\": 9036,\r\n          \"sha256\": \"8bb1e0ef1415f81b31b967d8df9c22dbcad3160a17e7410fcd85ad5819c7c60e\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-shellborn/tint-mask.webp\",\r\n          \"bytes\": 50694,\r\n          \"sha256\": \"655e52806a1abc2750780ffa28d94b85cd1ebef231624f83b8ff41c345960e89\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-shellborn/preview.webp\",\r\n          \"bytes\": 12672,\r\n          \"sha256\": \"3f5d1a52e02032ce1513807c7e03898af630842323e99f12948f40da880c23d3\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 3,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-shellborn/basecolor\",\r\n            \"bytes\": 9684,\r\n            \"sha256\": \"2ffb18fed343bdcf0b2ba3d4b0dea9e8e53711fb266563af356fc940dc129a40\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-shellborn/normal\",\r\n            \"bytes\": 23222,\r\n            \"sha256\": \"d1a9e0f90dce9c6a37afe8819f96ce7af37ca19f8a3ed035bb2f2dc262695f83\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-shellborn/roughness\",\r\n            \"bytes\": 8118,\r\n            \"sha256\": \"c7356a52eed60b3dd71af8ef399b497c5a984b1f076df5c12f07e1a2a57a3971\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-shellborn/height\",\r\n            \"bytes\": 17122,\r\n            \"sha256\": \"7731dee5c6bafef91432e5df689468c0bd108baee671021effef7fdd6fed8545\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-shellborn/ao\",\r\n            \"bytes\": 9036,\r\n            \"sha256\": \"8bb1e0ef1415f81b31b967d8df9c22dbcad3160a17e7410fcd85ad5819c7c60e\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-shellborn/tintMask\",\r\n            \"bytes\": 50694,\r\n            \"sha256\": \"655e52806a1abc2750780ffa28d94b85cd1ebef231624f83b8ff41c345960e89\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-shellborn/preview\",\r\n            \"bytes\": 12672,\r\n            \"sha256\": \"3f5d1a52e02032ce1513807c7e03898af630842323e99f12948f40da880c23d3\"\r\n          }\r\n        }\r\n      }\r\n    },\r\n    {\r\n      \"id\": \"creature-cracked-starlight\",\r\n      \"displayName\": \"Cracked Starlight\",\r\n      \"track\": \"meditation\",\r\n      \"realm\": \"hybrid\",\r\n      \"rarity\": \"legendary\",\r\n      \"sourceAssetId\": \"Paint002\",\r\n      \"collection\": \"creature-celestial-rift\",\r\n      \"collectionSlot\": 3,\r\n      \"sourceUrl\": \"https://ambientcg.com/a/Paint002\",\r\n      \"license\": \"CC0-1.0\",\r\n      \"author\": \"ambientCG\",\r\n      \"resolution\": 512,\r\n      \"maps\": {\r\n        \"basecolor\": {\r\n          \"file\": \"textures/creature-cracked-starlight/basecolor.webp\",\r\n          \"bytes\": 2308,\r\n          \"sha256\": \"212ef8ce6348eab7babafd1302f6de8e0ff645ded3417c37b0c14c368bd5d3c3\"\r\n        },\r\n        \"normal\": {\r\n          \"file\": \"textures/creature-cracked-starlight/normal.webp\",\r\n          \"bytes\": 36906,\r\n          \"sha256\": \"7363169a2812312622da8ea9802490d0f121523a63f797d7da80f3e6599b06cc\"\r\n        },\r\n        \"roughness\": {\r\n          \"file\": \"textures/creature-cracked-starlight/roughness.webp\",\r\n          \"bytes\": 27138,\r\n          \"sha256\": \"e34af0b29b2da65da14698dd33851295fbd1c00d02220613487de2bab8cb15a1\"\r\n        },\r\n        \"height\": {\r\n          \"file\": \"textures/creature-cracked-starlight/height.webp\",\r\n          \"bytes\": 21122,\r\n          \"sha256\": \"d6bceaf4d67569f417fcef6bd23e17458e885bbd77faff67b77c5254a50fc7a0\"\r\n        },\r\n        \"ao\": {\r\n          \"file\": \"textures/creature-cracked-starlight/ao.webp\",\r\n          \"bytes\": 39506,\r\n          \"sha256\": \"3fbaf579d17290d907480db250ee33863f169674e1f57f66a51b05d725e54f02\"\r\n        },\r\n        \"tintMask\": {\r\n          \"file\": \"textures/creature-cracked-starlight/tint-mask.webp\",\r\n          \"bytes\": 37962,\r\n          \"sha256\": \"92b4eed22f7d0a3af5233adb61c825b286e7553f65eafdc0557de5f1e8d2d9a2\"\r\n        },\r\n        \"preview\": {\r\n          \"file\": \"textures/creature-cracked-starlight/preview.webp\",\r\n          \"bytes\": 2858,\r\n          \"sha256\": \"07c798d4bde111c432f31209c9a960b7525f34922813203a1be22d5220493fe1\"\r\n        }\r\n      },\r\n      \"runtime\": {\r\n        \"unlock\": {\r\n          \"level\": 5,\r\n          \"track\": \"meditation\"\r\n        },\r\n        \"pack\": \"track-meditation\",\r\n        \"bundle\": \"assets/meditation.m5bundle\",\r\n        \"maps\": {\r\n          \"basecolor\": {\r\n            \"entry\": \"creature-cracked-starlight/basecolor\",\r\n            \"bytes\": 2308,\r\n            \"sha256\": \"212ef8ce6348eab7babafd1302f6de8e0ff645ded3417c37b0c14c368bd5d3c3\"\r\n          },\r\n          \"normal\": {\r\n            \"entry\": \"creature-cracked-starlight/normal\",\r\n            \"bytes\": 36906,\r\n            \"sha256\": \"7363169a2812312622da8ea9802490d0f121523a63f797d7da80f3e6599b06cc\"\r\n          },\r\n          \"roughness\": {\r\n            \"entry\": \"creature-cracked-starlight/roughness\",\r\n            \"bytes\": 27138,\r\n            \"sha256\": \"e34af0b29b2da65da14698dd33851295fbd1c00d02220613487de2bab8cb15a1\"\r\n          },\r\n          \"height\": {\r\n            \"entry\": \"creature-cracked-starlight/height\",\r\n            \"bytes\": 21122,\r\n            \"sha256\": \"d6bceaf4d67569f417fcef6bd23e17458e885bbd77faff67b77c5254a50fc7a0\"\r\n          },\r\n          \"ao\": {\r\n            \"entry\": \"creature-cracked-starlight/ao\",\r\n            \"bytes\": 39506,\r\n            \"sha256\": \"3fbaf579d17290d907480db250ee33863f169674e1f57f66a51b05d725e54f02\"\r\n          },\r\n          \"tintMask\": {\r\n            \"entry\": \"creature-cracked-starlight/tintMask\",\r\n            \"bytes\": 37962,\r\n            \"sha256\": \"92b4eed22f7d0a3af5233adb61c825b286e7553f65eafdc0557de5f1e8d2d9a2\"\r\n          },\r\n          \"preview\": {\r\n            \"entry\": \"creature-cracked-starlight/preview\",\r\n            \"bytes\": 2858,\r\n            \"sha256\": \"07c798d4bde111c432f31209c9a960b7525f34922813203a1be22d5220493fe1\"\r\n          }\r\n        }\r\n      }\r\n    }\r\n  ]\r\n}\r\n","creature/source/creator/deform.ts":"import * as THREE from 'three';\r\nimport type {Design,Region} from './design';\r\nexport function deformMesh(o:THREE.Mesh,region:Region,d:Design){\r\n const position=o.userData.basePosition as THREE.Vector3,scale=o.userData.baseScale as THREE.Vector3;\r\n if(!position||!scale)return;\r\n o.position.copy(position);o.scale.copy(scale);\r\n // The GLB is already converted to Y up. Scale around each feature's center.\r\n if(o.name.startsWith('Silky_collar')||o.name.startsWith('Silky collar')){\r\n  o.scale.x*=1+.2*(d.fur-1);o.scale.z*=1+.2*(d.fur-1);o.scale.y*=d.fur;o.position.y+=1.5175*(1-d.fur);\r\n }\r\n if(region==='eye'&&/Iris|Pupil|Glint|glint/.test(o.name)){\r\n  const factor=d.iris*(o.name==='Pupil'?d.pupilSize:1);\r\n  // R25 anime eyes: a tall iris and pupil with oversized highlights.\r\n  const glint=/glint/i.test(o.name),fx=factor*(d.eye==='anime'?glint?1.7:1.2:1),fy=factor*(d.eye==='anime'?glint?1.7:1.45:1);\r\n  o.scale.x*=fx;o.scale.y*=fy;\r\n  o.position.x=position.x*fx+.04*(1-fx);\r\n  o.position.y=position.y*fy+2.1475*(1-fy);\r\n }\r\n}\r\n\r\n","creature/source/creator/design.ts":"import {EYE_LAYOUTS,type EyeLayout} from './eye-layouts';\r\nimport {COACHES,type CoachId} from './coaching';\r\nimport {PUPILS,type PupilShape} from './pupils';\r\nimport {STYLES as HAND_STYLES} from './catalog';\r\nimport {ROSTER} from './roster';\r\nimport {coachName} from '../../../coach-names.mjs';\r\nimport {normalizeStyleId,normalizeTextureId} from './texture-policy.mjs';\r\nimport {EYE_STYLE_IDS} from '../../../eye-styles.mjs';\r\nexport const REGIONS=['head','eye','collar','body','arms','feet'] as const;\r\nexport type Region=typeof REGIONS[number];\r\n// R18 G3: three colour channels. The region whose saved colour each region renders with: body colour -> body, arms, feet, collar.\r\n// R25 (Ian): the head always takes the body colour; a separate head colour clips at the neck seam.\r\nexport const COLOUR_SOURCE:Record<Region,Region>={body:'body',arms:'body',feet:'body',collar:'body',head:'body',eye:'eye'};\r\n// R25: the picker offers two parts. \"Full body\" writes the body and head colours together; an older save's\r\n// separate head colour is never rendered (COLOUR_SOURCE) and is dropped on load (parseRecipe).\r\nexport const COLOUR_CHANNELS=[{id:'body',label:'Full body',regions:['body','arms','feet','collar','head']},{id:'eyes',label:'Eyes',regions:['eye']}] as const;\r\nexport const LABELS:Record<Region,string>={head:'Crown & scales',eye:'Eyes & pupils',collar:'Shaggy collar',body:'Body',arms:'Arms & hands',feet:'Legs & feet'};\r\nexport const STYLES=[{...HAND_STYLES[0],name:'Original MYR5',primary:'#7946aa',secondary:'#351344',accent:'#b373d4',roughness:.62},...HAND_STYLES.slice(1)];\r\nexport const PICKER_STYLES=STYLES.filter(style=>![8,11,22].includes(style.id));\r\n// Every creature model shipped with the app. Roster ids are generated from the Blender pipeline (creator/roster.ts).\r\nexport const BODIES:readonly {id:string;label:string;group:string}[]=[{id:'myr5',label:coachName('myr5'),group:'MYR5'},...ROSTER];\r\n// The review rejects (D6: original 63/7 review wins). Kept in BODIES/roster.ts and fully\r\n// loadable/renderable (a saved recipe pointing at one still works) — just excluded from user-facing\r\n// pickers below. Numbering resolved to roster.ts (app) numbering per coordinator decision (D6-numbering).\r\n// Owner correction during Rank 3: Pearl · Orb 3 & 5 and Shellcap · Manyarm 3 are kept as approved\r\n// models (per the approved roster board, outputs/visual-boards/01-approved-model-roster.png) — only\r\n// these 4 are actually hidden.\r\nexport const REJECTED_BODY_IDS=new Set<string>([\r\n 'roster/01-seed-pearo--white_3d_character_model', // Seed · Pearo 3\r\n 'roster/01-seed-pearo--blank_humanoid_figure_3d_model', // Seed · Pearo 4\r\n 'roster/09-monolith-tanka--robot_3d_model2', // Monolith · Tanka 4\r\n 'roster/18-quad-all--stylized_quadruped_3d_model', // Four-legged 8\r\n]);\r\n// What user-facing pickers (body/head/arms/feet selects) should offer. Do not filter BODIES itself —\r\n// `known()` below (and any saved recipe) must keep accepting rejected ids.\r\nexport const PICKER_BODIES=BODIES.filter(b=>!REJECTED_BODY_IDS.has(b.id));\r\nexport type BodyId=string;\r\n// Mix-and-match: each limb region may come from a different creature; unset means \"same as body\".\r\nexport const PART_SOURCES=['headFrom','armsFrom','feetFrom'] as const;\r\nexport type PartSource=typeof PART_SOURCES[number];\r\nconst known=(id:unknown)=>typeof id==='string'&&BODIES.some(b=>b.id===id);\r\n// A region can carry a decoupled texture+colour choice instead of (or on top of) the\r\n// legacy single `styles` index. Absent = keep using the legacy numeric style for that region.\r\nexport type MaterialChoice={textureId:string;colorId:string;sparkle:number;metallic:number};\r\nconst validChoice=(v:unknown):v is MaterialChoice=>!!v&&typeof v==='object'&&typeof (v as any).textureId==='string'&&typeof (v as any).colorId==='string'&&Number.isFinite((v as any).sparkle)&&(v as any).sparkle>=0&&(v as any).sparkle<=1&&Number.isFinite((v as any).metallic)&&(v as any).metallic>=0&&(v as any).metallic<=1;\r\nconst validMaterials=(m:unknown):boolean=>m===undefined||(!!m&&typeof m==='object'&&!Array.isArray(m)&&Object.entries(m as object).every(([r,v])=>REGIONS.includes(r as Region)&&validChoice(v)));\r\nexport type Design={golden?:boolean;blackSclera?:boolean;colourPupil?:boolean;version:1;styles:Record<Region,number>;eye:'open'|'sleepy'|'wide'|'anime'|'squinty'|'bloodshot'|'blind';fur:number;iris:number;pupil:PupilShape;pupilSize:number;detail:number;coach:CoachId;shipId?:CoachId;shipColor?:string|null;fingers:number;toes:number;eyeLayout:EyeLayout;body:BodyId;headFrom:BodyId;armsFrom:BodyId;feetFrom:BodyId;materials?:Partial<Record<Region,MaterialChoice>>};\r\nexport const fresh=():Design=>({version:1,styles:{head:0,eye:0,collar:0,body:0,arms:0,feet:0},eye:'open',fur:1,iris:1,pupil:'round',pupilSize:1,detail:1,coach:'supportive',shipId:'supportive',shipColor:null,fingers:4,toes:3,eyeLayout:'single',body:'myr5',headFrom:'myr5',armsFrom:'myr5',feetFrom:'myr5'});\r\nexport function parseRecipe(raw:string):Design{const d=JSON.parse(raw);d.pupil??='round';d.pupilSize??=1;d.detail??=1;d.coach??='supportive';d.shipId??=d.coach;d.shipColor??=null;d.fingers??=4;d.toes??=3;d.eyeLayout??='single';if(!known(d.body))d.body='myr5';for(const k of PART_SOURCES)if(!known(d[k]))d[k]=d.body;const eyeLayoutMigration:Record<string,string>={'around':'triangle','frontBack':'horizontal'};if(eyeLayoutMigration[d.eyeLayout])d.eyeLayout=eyeLayoutMigration[d.eyeLayout];if(!Number.isInteger(d.fingers)||d.fingers<2||d.fingers>6||!Number.isInteger(d.toes)||d.toes<1||d.toes>6||!Object.hasOwn(EYE_LAYOUTS,d.eyeLayout)||d.version!==1||!d.styles||!REGIONS.every(r=>Number.isInteger(d.styles[r])&&d.styles[r]>=0&&d.styles[r]<STYLES.length)||!EYE_STYLE_IDS.includes(d.eye)||!Number.isFinite(d.fur)||d.fur<.65||d.fur>1.4||!Number.isFinite(d.iris)||d.iris<.7||d.iris>1.25||!PUPILS.some(p=>p[0]===d.pupil)||!Number.isFinite(d.pupilSize)||d.pupilSize<.6||d.pupilSize>1.15||!Number.isFinite(d.detail)||d.detail<.5||d.detail>1.5||!COACHES.some(c=>c.id===d.coach)||!COACHES.some(c=>c.id===d.shipId)||!(d.shipColor===null||/^#[0-9a-f]{6}$/i.test(d.shipColor))||!validMaterials(d.materials))throw Error('Choose a valid MYR5 recipe.');return {golden:typeof d.golden==='boolean'?d.golden:undefined,...(d.blackSclera===true?{blackSclera:true}:{}),...(d.colourPupil===true?{colourPupil:true}:{}),version:1,styles:Object.fromEntries(REGIONS.map(r=>[r,normalizeStyleId(d.styles[r])])) as Design['styles'],eye:d.eye,fur:d.fur,iris:d.iris,pupil:d.pupil,pupilSize:d.pupilSize,detail:d.detail,coach:d.coach,shipId:d.shipId,shipColor:d.shipColor,fingers:d.fingers,toes:d.toes,eyeLayout:d.eyeLayout,body:d.body,headFrom:d.headFrom,armsFrom:d.armsFrom,feetFrom:d.feetFrom,materials:d.materials&&Object.fromEntries(Object.entries(d.materials).map(([region,choice]:[string,any])=>[region,{...choice,textureId:normalizeTextureId(choice.textureId),...(region==='head'&&d.materials.body?{colorId:d.materials.body.colorId}:{})}]))};}\r\n","creature/source/creator/eye-layouts.ts":"// Eye centers use the model's Y-up coordinates; yaw faces outward from the crown.\r\n// Reference point the table is tuned to (myr5's own head front, at the single-eye position).\r\nexport const EYE_REFERENCE={x:0,y:2.1575,z:0.55};\r\n// Global eye-scale multiplier for roster heads (handoff §5 \"Eye scale\"). MYR5's own head has eye\r\n// sockets carved for its native eye size, so it is excluded (see assemble.ts) — this constant only\r\n// scales down the auto-fitted eyes on the 70 roster heads, which have no carved socket to clash with.\r\nexport const EYE_SCALE_DEFAULT=0.65;\r\nexport const EYE_LAYOUTS = {\r\n \"single\":{\"label\":\"One cyclops eye\",\"eyes\":[[0,2.1575,0.55,0.605,0]]},\r\n \"horizontal\":{\"label\":\"Horizontal pair\",\"eyes\":[[-0.34,2.25,0.49,0.32,0],[0.34,2.25,0.49,0.32,0]]},\r\n \"vertical\":{\"label\":\"Vertical pair\",\"eyes\":[[0,2.03,0.49,0.32,0],[0,2.73,0.39,0.31,0]]},\r\n \"triangle\":{\"label\":\"Triangle\",\"eyes\":[[-0.33,2.17,0.49,0.30,0],[0.33,2.17,0.49,0.30,0],[0,2.80,0.36,0.28,0]]},\r\n \"spider\":{\"label\":\"Spider · two big + two small\",\"eyes\":[[-0.34,2.16,0.49,0.32,0],[0.34,2.16,0.49,0.32,0],[-0.235,2.77,0.375,0.20,0],[0.235,2.77,0.375,0.20,0]]},\r\n \"square\":{\"label\":\"Four small · square\",\"eyes\":[[-0.285,2.16,0.49,0.25,0],[0.285,2.16,0.49,0.25,0],[-0.285,2.73,0.375,0.25,0],[0.285,2.73,0.375,0.25,0]]}\r\n} as const;\r\nexport type EyeLayout=keyof typeof EYE_LAYOUTS;\r\n","creature/source/creator/eye-overrides.ts":"// Per-variant eye metadata, keyed by stable model id (roster.ts `id`, or 'myr5').\r\n// Source: plan/reports/audit-shapes.md + plan/reports/roster-sheet.md (handoff §5), numbering\r\n// resolved to roster.ts (app) numbering per coordinator decision during Rank 3 (D6-numbering).\r\n//\r\n// flipX: handoff §5 \"Facing direction\" (Rank 3). eyeScale/eyeOffset: Rank 3b priority list only\r\n// (handoff §5 \"Eye anchoring\"), pending owner review of plan/reports/eyes-review.png. eyeScale is\r\n// absolute: it replaces the head-width scale x 0.65 global multiplier (assemble.ts), not a factor on it.\r\nexport type EyeOverride={eyeScale?:number;eyeOffset?:[number,number,number];flipX?:boolean};\r\n\r\nexport const EYE_OVERRIDES:Record<string,EyeOverride>={\r\n 'roster/01-seed-pearo--blank_toy_figure_3d_model':{flipX:true}, // Seed · Pearo 5\r\n 'roster/03-pearl-orb-ring--abstract_humanoid_3d_model':{flipX:true}, // Pearl · Orb 1\r\n 'roster/05-slope-bobble--clay_humanoid_figure_3d_model':{flipX:true}, // Slope · Bobble 1\r\n 'roster/08-shard-asym--geometric_robot_3d_model':{flipX:true}, // Shard · Asym 1\r\n 'roster/08-shard-asym--robot_3d_model4':{flipX:true}, // Shard · Asym 2\r\n 'roster/08-shard-asym--fantasy_creature_3d_model2':{flipX:true}, // Shard · Asym 3\r\n 'roster/09-monolith-tanka--3d_robot_model':{flipX:true}, // Monolith · Tanka 1\r\n 'roster/09-monolith-tanka--robot_3d_model3':{flipX:true}, // Monolith · Tanka 5\r\n 'roster/10-petal-wisp--stylized_creature_3d_model':{flipX:true}, // Petal · Wisp 1\r\n 'roster/12-seedpod-snailslug--stylized_worm_3d_model':{flipX:true}, // Seedpod · Snailslug 2\r\n 'roster/13-fan-split--stylized_3d_character2':{flipX:true}, // Fan · Split 1\r\n 'roster/17-shellcap-manyarm--3d_character_figurine':{flipX:true}, // Shellcap · Manyarm 1\r\n 'roster/18-quad-all--quadruped_robot_3d_model1':{flipX:true}, // Four-legged 5\r\n 'roster/20-lume--robotic_figure_3d_model':{flipX:true}, // Lume 1 (\"Loom 1\" in the handoff)\r\n 'roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model':{flipX:true}, // Blob 4\r\n\r\n // Rank 3b: priority eye-anchoring corrections (handoff §5 \"Eye anchoring\"), numbers tuned against\r\n // plan/reports/eyes-review.png (front + 3/4 + mid-animation renders). eyeOffset.z is intentionally\r\n // never used here: for front-facing eyes (yaw 0) `eyePosition()` in creator/anatomy.ts derives z from\r\n // the head's own eye_anchor surface point, not from the offset — only x/y and eyeScale reach the render.\r\n 'roster/18-quad-all--wooden_four-legged_robot_3d_model':{eyeScale:0.42}, // Four-legged 9 — floating: eye scale was clamped to 1.2x (this head is very wide), 0.65x of that still dwarfed the head; shrinking it seats it on the face instead of bulging off it.\r\n 'roster/18-quad-all--wooden_robot_3d_model':{eyeOffset:[0,0.46,0],eyeScale:0.4}, // Four-legged 10 — floating: eye_anchor sits mid-torso, well below the actual head ball; nudged up onto the head and shrunk slightly.\r\n 'roster/18-quad-all--dragon_creature_3d_model':{eyeOffset:[0,0.16,0],eyeScale:0.42}, // Four-legged 1 — incorrect placement/excessive size: raised onto the head and shrunk off the muzzle.\r\n 'roster/18-quad-all--fantasy_creature_3d_model1':{eyeOffset:[0,0.35,0],eyeScale:0.34}, // Four-legged 2 — incorrect placement/excessive size: raised into the wedge head and shrunk.\r\n 'roster/23-blob-texture-bodies--cute_blob_creature_3d_model':{eyeOffset:[0.222,0,0]}, // Blob 2 — head sub-mesh is off-centre (-0.22 on x) relative to the body; cancels that so the eye centers on the creature.\r\n 'roster/10-petal-wisp--ghost_character_3d_model':{eyeOffset:[0,-0.18,0],eyeScale:0.22}, // Petal · Wisp 2 (ghost_character) — smaller and lower per handoff.\r\n 'roster/10-petal-wisp--fantasy_creature_3d_model4':{eyeOffset:[0,-0.18,0],eyeScale:0.22}, // Petal · Wisp 3 (fantasy_creature_3d_model4) — smaller and lower per handoff.\r\n 'roster/22-curve--stylized_alien_3d_model':{eyeOffset:[0,-0.18,0]}, // Curve 1 — lower only per handoff; size unchanged.\r\n};\r\n","creature/source/creator/eye-surface.ts":"import * as THREE from 'three';\r\nexport const EYE_CENTER=new THREE.Vector3(0,2.1575,.55);\r\nexport const LID_RADIUS=.619;\r\nconst originals=new WeakMap<THREE.Mesh,{source:THREE.BufferGeometry;projected:THREE.BufferGeometry}>();\r\nfunction subdivideSurface(source:THREE.BufferGeometry){\r\n const flat=source.index?source.toNonIndexed():source.clone();const positions=flat.getAttribute('position');const vertices:number[]=[];\r\n const split=(a:THREE.Vector3,b:THREE.Vector3,c:THREE.Vector3,depth:number)=>{\r\n  if(depth<6&&Math.max(a.distanceTo(b),b.distanceTo(c),c.distanceTo(a))>.04){const ab=a.clone().lerp(b,.5),bc=b.clone().lerp(c,.5),ca=c.clone().lerp(a,.5);split(a,ab,ca,depth+1);split(ab,b,bc,depth+1);split(ca,bc,c,depth+1);split(ab,bc,ca,depth+1);}else vertices.push(...a.toArray(),...b.toArray(),...c.toArray());\r\n };\r\n for(let i=0;i<positions.count;i+=3)split(new THREE.Vector3().fromBufferAttribute(positions,i),new THREE.Vector3().fromBufferAttribute(positions,i+1),new THREE.Vector3().fromBufferAttribute(positions,i+2),0);\r\n flat.dispose();const dense=new THREE.BufferGeometry();dense.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3));return dense;\r\n}\r\nexport function prepareEyeMesh(o:THREE.Mesh){\r\n if(o.name==='Iris'){\r\n  o.geometry.dispose();o.geometry=new THREE.CircleGeometry(.375,128);o.geometry.scale(1, .395/.375,1);o.position.set(.04,2.1475,1.133);\r\n }else if(o.name==='Glint'||o.name==='Small_glint'||o.name==='Small glint'){\r\n  const small=o.name!=='Glint';o.geometry.dispose();o.geometry=new THREE.CircleGeometry(small?.024:.063,32);o.geometry.scale(1,small?.028/.024:.081/.063,1);o.position.y-=.4725;\r\n }\r\n}\r\n// R25 bloodshot eyes: branching red veins that run from the rim of the white toward the iris. Built flat\r\n// in the eye's own frame, then wrapped onto the globe by conformEyeMesh like the iris and glints.\r\nexport function bloodshotVeins(){\r\n const vertices:number[]=[];let seed=11;const rand=()=>(seed=seed*16807%2147483647)/2147483647;\r\n const strip=(path:[number,number][],width:number)=>{for(let i=0;i+1<path.length;i++){\r\n  const [ax,ay]=path[i],[bx,by]=path[i+1],l=Math.hypot(bx-ax,by-ay)||1,wa=width*(1-i/path.length),wb=width*(1-(i+1)/path.length);\r\n  const nx=-(by-ay)/l,ny=(bx-ax)/l;vertices.push(ax-nx*wa,ay-ny*wa,1.15,bx+nx*wb,by+ny*wb,1.15,ax+nx*wa,ay+ny*wa,1.15,ax-nx*wa,ay-ny*wa,1.15,bx-nx*wb,by-ny*wb,1.15,bx+nx*wb,by+ny*wb,1.15);}};\r\n const walk=(angle:number,from:number,to:number,steps:number):[number,number][]=>Array.from({length:steps+1},(_,i)=>{const r=from+(to-from)*i/steps;angle+=(rand()-.5)*.22;return [.04+Math.cos(angle)*r,2.1475+Math.sin(angle)*r];});\r\n for(let k=0;k<13;k++){const angle=k/13*Math.PI*2+rand()*.35,main=walk(angle,.6,.4+rand()*.06,7);strip(main,.011);\r\n  const at=2+Math.floor(rand()*3),[x,y]=main[at],r=Math.hypot(x-.04,y-2.1475);strip(walk(Math.atan2(y-2.1475,x-.04)+(rand()<.5?-.35:.35),r,r-.09,3),.006);}\r\n const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3));return g;\r\n}\r\n// A geometric mask keeps eye markings on the globe and inside the eyelid.\r\n// Actual surface geometry also preserves occlusion in GLB and OBJ exports.\r\nexport function conformEyeMesh(o:THREE.Mesh){\r\n if(!/^(Iris|Pupil|Glint|Small.glint|Eye vein)/.test(o.name))return;\r\n let entry=originals.get(o);\r\n if(!entry||entry.projected!==o.geometry){entry?.source.dispose();entry={source:subdivideSurface(o.geometry),projected:o.geometry};originals.set(o,entry);}\r\n const geometry=entry.source.clone();const positions=geometry.getAttribute('position');const point=new THREE.Vector3();o.updateMatrix();const inverse=o.matrix.clone().invert();const localNormalMatrix=new THREE.Matrix3().setFromMatrix4(o.matrix).transpose();const normal=new THREE.Vector3();const normals=new Float32Array(positions.count*3);\r\n const radius=o.name==='Pupil'?.609:/glint/i.test(o.name)?.611:o.name==='Iris'?.606:o.name==='Eye vein'?.6058:.6075;\r\n for(let i=0;i<positions.count;i++){\r\n  point.fromBufferAttribute(positions,i).applyMatrix4(o.matrix);\r\n  let x=point.x-EYE_CENTER.x,y=point.y-EYE_CENTER.y;const distance=Math.hypot(x,y),limit=.595;\r\n  if(distance>limit){x*=limit/distance;y*=limit/distance;}\r\n  point.set(EYE_CENTER.x+x,EYE_CENTER.y+y,EYE_CENTER.z+Math.sqrt(radius*radius-x*x-y*y));normal.copy(point).sub(EYE_CENTER).normalize().applyMatrix3(localNormalMatrix).normalize();normal.toArray(normals,i*3);point.applyMatrix4(inverse);\r\n  positions.setXYZ(i,point.x,point.y,point.z);\r\n }\r\n geometry.setAttribute('normal',new THREE.BufferAttribute(normals,3));geometry.computeBoundingBox();geometry.computeBoundingSphere();o.geometry.dispose();o.geometry=geometry;entry.projected=geometry;\r\n}\r\n","creature/source/creator/material-language.ts":"import * as T from 'three';\r\nimport {mergeGeometries} from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\nimport {builtinSurfaceProfile,sampleBuiltinSurface} from './material-patterns';\r\nimport {refineCoachGeometry,type CoachReliefBudget} from './material-refinement';\r\nimport {samplePaletteTint,applyPaletteFinish} from './palette-finishes';\r\n\r\n// This material language is shared verbatim by Coach and Helping Hand. Maps are\r\n// ordinary glTF-compatible PBR textures, so the appearance also survives export.\r\nexport const MATERIAL_REVISION='material-horror-robot-2026-10-05-r1';\r\nexport const MATERIAL_NOTES=[\r\n 'Fine pores, palm folds and soft satin skin.',\r\n 'Twisted roots, bark fissures and fresh leaf growth.',\r\n 'Soft mushroom caps, radial gills and a branching mycelium web.',\r\n 'Overlapping lacquered carapace plates with dark flexible seams.',\r\n 'Raised overlapping scales, belly scutes and a serrated ridge.',\r\n 'Deep ocean hide, swept fins and luminous sensory pearls.',\r\n 'Porous reef limestone, branching antlers and hollow polyps.',\r\n 'Weathered ivory, joint ends and hollow skeletal anatomy.',\r\n 'Translucent mist glass with flowing veils and a pale inner glow.',\r\n 'Charred hide, swept horns and ember-lit fractures.',\r\n 'Pearlescent ceramic, engraved gold and orbiting halo segments.',\r\n 'Obsidian shells with violet fracture edges and star-like inclusions.',\r\n 'Folded flesh, coiled tendrils and luminous sensory nodules.',\r\n 'Angular stone slabs, chipped strata and deep mineral seams.',\r\n 'Faceted amethyst clusters with reflective faces and mineral inclusions.',\r\n 'Black basalt crust over glowing orange lava fissures.',\r\n 'Translucent blue ice, frost veins and sharp icicle clusters.',\r\n 'Storm-dark armor with branching electric channels and conductor fins.',\r\n 'Rigid brass armor, steel hinge joints, rivets and exposed toothed gears.',\r\n 'Machined violet panels, recessed circuits and pink illuminated rails.',\r\n 'Dense tapered fur tufts, a soft undercoat and contrasting guard hairs.',\r\n 'Translucent gelatin, a wet clear coat and bubbles suspended inside.',\r\n 'Plump soft forms, warm blush and delicate skin folds.'\r\n] as const;\r\ntype Style={id:number;primary:string;secondary:string;accent:string;emissive:string;roughness:number;metalness:number;detail:string;paletteId?:string};\r\nconst clamp=T.MathUtils.clamp,fract=(x:number)=>x-Math.floor(x);\r\nconst hash=(x:number,y:number)=>fract(Math.sin(x*127.1+y*311.7)*43758.5453);\r\nfunction cells(x:number,y:number){\r\n const ix=Math.floor(x),iy=Math.floor(y);let a=10,b=10;\r\n for(let j=-1;j<=1;j++)for(let i=-1;i<=1;i++){\r\n  const px=ix+i+.2+.6*hash(ix+i,iy+j),py=iy+j+.2+.6*hash(iy+j,ix+i+19);\r\n  const d=Math.hypot(x-px,y-py);if(d<a){b=a;a=d;}else if(d<b)b=d;\r\n }\r\n return {pit:a,seam:b-a};\r\n}\r\nexport function surfaceSample(id:number,x:number,y:number){\r\n const builtIn=sampleBuiltinSurface(id,x,y);if(builtIn)return builtIn;\r\n const c=cells(x*5,y*5),grain=hash(Math.floor(x*180),Math.floor(y*180));\r\n const wave=Math.sin(x*18+Math.sin(y*9)*2),vein=Math.pow(1-Math.abs(Math.sin(x*12+Math.sin(y*7)*2)),9);\r\n const seam=1-T.MathUtils.smoothstep(c.seam,.025,.12),spot=1-T.MathUtils.smoothstep(c.pit,.06,.19);\r\n const sx=fract(x*10+(Math.floor(y*12)%2)*.5)-.5,sy=fract(y*12)-.5;\r\n const scale=clamp(1-Math.pow(Math.abs(sx)*1.9,3)-Math.pow(Math.abs(sy)*1.9,4),0,1);\r\n let h=.5,t=.5,glow=0,rough=.7;\r\n switch(id){\r\n  case 0:h=.42+grain*.12+wave*.015;t=.54+grain*.07;rough=.61+grain*.2;break;\r\n  case 1:h=.4+wave*.19+vein*.25;t=.28+vein*.42+grain*.13;rough=.91;break;\r\n  case 2:h=.6-spot*.3+Math.sin(Math.atan2(sy,sx)*24)*.04;t=.7-spot*.4;glow=spot*.16;rough=.87;break;\r\n  case 3:h=scale*.75;t=.22+scale*.65;rough=.18+(.9-scale)*.4;break;\r\n  case 4:h=scale*.6+grain*.12;t=.22+scale*.52+wave*.08;rough=.56+grain*.2;break;\r\n  case 5:h=.55+wave*.12-spot*.23;t=.15+spot*.8;glow=spot;rough=.32;break;\r\n  case 6:h=.75-spot*.65-grain*.12;t=.44+spot*.4+grain*.1;rough=.93;break;\r\n  case 7:h=.55+Math.sin(y*35)*.09-grain*.12-seam*.06;t=.75-grain*.2-seam*.35;rough=.83;break;\r\n  case 8:h=.5+wave*.035;t=.7+wave*.12;glow=vein*.35;rough=.12;break;\r\n  case 9:h=.48+wave*.14+grain*.12;t=.15+grain*.13+vein*.3;glow=vein*.4;rough=.83;break;\r\n  case 10:h=.55+vein*.08;t=.74+vein*.23;glow=vein*.22;rough=.18+grain*.07;break;\r\n  case 11:h=.55-seam*.3;t=.03+seam*.48;glow=seam*.8;rough=.14;break;\r\n  case 12:h=.5+wave*.19+spot*.18;t=.25+spot*.65;glow=spot*.4;rough=.39;break;\r\n  case 13:h=.62-seam*.52+Math.floor(grain*4)*.035;t=.32+grain*.2-seam*.26;rough=.98;break;\r\n  case 14:h=.45+Math.floor(c.pit*8)*.05;t=.32+c.pit*.45;rough=.09;break;\r\n  case 15:{const lava=cells(x*2+Math.sin(y*5)*.3,y*2+Math.sin(x*4)*.3),crack=1-T.MathUtils.smoothstep(lava.seam,.015,.065);h=.72-crack*.65+grain*.1;t=.015+crack*.88;glow=crack;rough=.95-crack*.7;break;}\r\n  case 16:h=.5+seam*.14;t=.72+seam*.22;rough=.13+seam*.48;break;\r\n  case 17:{const bolt=Math.pow(1-Math.abs(Math.sin(x*7+Math.sin(y*22)*.25+Math.sin(y*9))),24);h=.54-bolt*.2;t=.13+bolt*.82;glow=bolt;rough=.38;break;}\r\n  case 18:{const cut=Math.min(fract(x*5),fract(y*5));h=cut<.06?.12:.68+grain*.03;t=cut<.06?.05:.43+grain*.16;rough=.24+grain*.25;break;}\r\n  case 19:{const a=fract(x*6),b=fract(y*6),switcher=hash(Math.floor(x*6),Math.floor(y*6));const rail=(Math.abs(a-.5)<.025&&b>.2&&switcher>.35)||(Math.abs(b-.5)<.025&&a<.6&&switcher<.65)?1:0;h=.5-rail*.2;t=.08+rail*.9;glow=rail;rough=.25;break;}\r\n  case 20:h=.5+Math.sin(x*160+Math.sin(y*25))* .2;t=.58+grain*.2;rough=.98;break;\r\n  case 21:h=.5+wave*.018;t=.7+wave*.07;rough=.07;break;\r\n  case 22:h=.5+grain*.035+wave*.01;t=.67+wave*.02;rough=.51;break;\r\n  // Rank 4 additions: Flat (no mask - literally constant) and Clay (soft procedural noise,\r\n  // PLAN §6.1) so the runtime tint system has an always-unlocked, no-download starting pair.\r\n  case 30:h=.5;t=.5;rough=.55;break;\r\n  case 31:h=.5+grain*.05+wave*.008;t=.5+grain*.03;rough=.92;break;\r\n }\r\n return {height:h,tint:clamp(t,0,1),glow,rough};\r\n}\r\nconst maps=new Map<string,{map:T.DataTexture;bump:T.DataTexture;rough:T.DataTexture;glow:T.DataTexture}>();\r\nfunction materialMaps(style:Style){\r\n const key=[MATERIAL_REVISION,style.id,style.primary,style.secondary,style.accent,style.paletteId??''].join('|');if(maps.has(key))return maps.get(key)!;\r\n const size=192,buffers=Array.from({length:4},()=>new Uint8Array(size*size*4));\r\n const dark=new T.Color(style.secondary),base=new T.Color(style.primary),light=new T.Color(style.accent),color=new T.Color(),profile=builtinSurfaceProfile(style.id);\r\n for(let y=0;y<size;y++)for(let x=0;x<size;x++){\r\n  const s=surfaceSample(style.id,x/size,y/size),i=(y*size+x)*4;\r\n  const tint=samplePaletteTint(style.paletteId,s.tint,x/size,y/size,style.id===30); // Palette stops follow the existing texture tones; watercolor/marbled add a spatial finish tint.\r\n  color.copy(tint<.5?dark:base).lerp(tint<.5?base:light,tint<.5?tint*2:(tint-.5)*2);\r\n  const roughnessMap=profile?clamp(.9+(s.rough-profile.roughness)*.75,0,1):s.rough;\r\n  for(let k=0;k<3;k++){buffers[0][i+k]=Math.round([color.r,color.g,color.b][k]*255);buffers[1][i+k]=s.height*255;buffers[2][i+k]=roughnessMap*255;buffers[3][i+k]=s.glow*255;}\r\n  for(const b of buffers)b[i+3]=255;\r\n }\r\n const textures=buffers.map(bytes=>{const tex=new T.DataTexture(bytes,size,size,T.RGBAFormat);tex.wrapS=tex.wrapT=T.RepeatWrapping;tex.magFilter=T.LinearFilter;tex.minFilter=T.LinearMipmapLinearFilter;tex.generateMipmaps=true;tex.needsUpdate=true;return tex;});\r\n const result={map:textures[0],bump:textures[1],rough:textures[2],glow:textures[3]};maps.set(key,result);return result;\r\n}\r\n/** Colour-only path for irises and other parts whose geometry must stay intact. */\r\nexport function applyPaletteSurface(material:T.MeshStandardMaterial,palette:{primary:string;secondary:string;accent:string;paletteId?:string;id?:number}){\r\n if(!palette.paletteId)return;\r\n material.map=materialMaps({...palette,id:palette.id??30,emissive:'#000000',roughness:.55,metalness:0,detail:'palette'}).map;\r\n material.color.set('white');material.needsUpdate=true;\r\n applyPaletteFinish(material as T.MeshPhysicalMaterial,palette.paletteId,palette);\r\n}\r\nexport function materialFor(style:Style,unit:number,original?:T.MeshStandardMaterial){\r\n const tex=materialMaps(style),id=style.id;\r\n const profile=builtinSurfaceProfile(id);\r\n const mat=new T.MeshPhysicalMaterial({name:style.detail+' · '+MATERIAL_REVISION,color:'white',map:tex.map,bumpMap:tex.bump,bumpScale:unit*(profile?.bump??([8,21,22].includes(id)?.0005:.007)),roughnessMap:tex.rough,roughness:profile?.roughness??1,metalness:style.metalness,vertexColors:true,envMapIntensity:[18,19,14].includes(id)?1.3:1});\r\n if(original){mat.side=original.side;mat.polygonOffset=original.polygonOffset;mat.polygonOffsetFactor=original.polygonOffsetFactor;}\r\n if([3,4,10,11,14,18,19,21].includes(id)){mat.clearcoat=id===21?1:.6;mat.clearcoatRoughness=id===21?.055:.19;}\r\n if([8,14,16,21].includes(id)){\r\n  mat.transmission=id===21?.8:id===8?.62:id===16?.54:.28;mat.thickness=unit*(id===21?.36:.16);mat.ior=id===21?1.36:id===16?1.31:1.46;\r\n  mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*(id===21?1.4:2);mat.metalness=0;mat.roughnessMap=null;mat.roughness=id===21?.075:id===16?.16:.12;\r\n }\r\n if([5,8,9,10,11,12,15,17,19].includes(id)){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=id===15?2.1:id===17?1.5:.85;}\r\n if(id===20){mat.sheen=1;mat.sheenRoughness=.96;mat.sheenColor.set(style.accent);mat.metalness=0;}\r\n if(id===0||id===22){mat.sheen=.22;mat.sheenColor.set('#ffc9b1');}\r\n if(profile){mat.sheen=profile.sheen;mat.sheenRoughness=profile.sheenRoughness;mat.sheenColor.set(style.accent);mat.clearcoat=Math.max(mat.clearcoat,profile.clearcoat);mat.clearcoatRoughness=profile.clearcoatRoughness;}\r\n if(id>=57&&id<=62){\r\n  mat.envMapIntensity=1.65;mat.iridescence=id===60?1:id===57?.85:.3;\r\n  mat.iridescenceThicknessRange=id===60?[100,750]:[140,480];\r\n  if([57,58,59,61].includes(id)){\r\n   mat.transmission=id===58?.97:id===59?.84:.88;mat.thickness=unit*(id===59?.32:.48);\r\n   mat.ior=id===59?1.8:id===58?1.46:1.38;mat.metalness=0;\r\n   mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*3.5;\r\n   mat.roughnessMap=null;mat.roughness=profile!.roughness;\r\n   mat.dispersion=id===59?.75:.2;\r\n  }\r\n  if(id===62){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=.65;}\r\n }\r\n if(id===63||id===74){mat.transmission=id===63?.48:.82;mat.thickness=unit*.32;mat.ior=id===63?1.33:1.52;mat.metalness=0;mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*2.4;mat.roughnessMap=null;mat.roughness=profile!.roughness;}\r\n if([69,70,74].includes(id)){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=id===74?1.1:.75;}\r\n mat.flatShading=[13,14,59].includes(id);mat.userData.materialStyle=id;\r\n const optics={transmission:mat.transmission,thickness:mat.thickness,ior:mat.ior,roughness:mat.roughness,metalness:mat.metalness,iridescence:mat.iridescence,iridescenceThicknessRange:mat.iridescenceThicknessRange};\r\n applyPaletteFinish(mat,style.paletteId,style);\r\n // Color finishes coat a clear volume; they must not erase the chosen jelly/glass texture.\r\n if(style.paletteId&&optics.transmission>0){Object.assign(mat,optics);mat.clearcoat=1;mat.clearcoatRoughness=.035;}\r\n if(id===60){mat.metalness=.88;mat.iridescence=1;mat.iridescenceThicknessRange=[100,750];mat.roughness=.16;}\r\n if(id===61||id===62)applySparkle(mat,.85);\r\n return mat;\r\n}\r\n\r\n// Sparkle flakes stay attached to the UV surface and flash as the viewing angle changes.\r\nexport function applySparkle(mat:T.MeshPhysicalMaterial,sparkle:number){\r\n const amount=clamp(sparkle,0,1);if(amount<=0||mat.userData.myr5FinishGlitter)return;\r\n if(mat.userData.myr5Sparkle)return;mat.userData.myr5Sparkle=amount;\r\n const previous=mat.onBeforeCompile;(mat as T.MeshPhysicalMaterial & {defines?:Record<string,string>}).defines={...(mat as T.MeshPhysicalMaterial & {defines?:Record<string,string>}).defines,USE_UV:''};\r\n mat.onBeforeCompile=(shader,renderer)=>{\r\n  previous?.call(mat,shader,renderer);\r\n  shader.uniforms.uSparkle={value:amount};\r\n  shader.vertexShader=shader.vertexShader.replace('#include <common>','#include <common>\\nvarying vec2 vMyr5SparkleUv;').replace('#include <uv_vertex>','#include <uv_vertex>\\nvMyr5SparkleUv=uv;');\r\n  shader.fragmentShader=shader.fragmentShader\r\n   .replace('#include <common>','uniform float uSparkle;\\nvarying vec2 vMyr5SparkleUv;\\n#include <common>')\r\n   .replace('#include <dithering_fragment>','float mySparkleGrain=fract(sin(dot(floor(vMyr5SparkleUv*83.0),vec2(12.9898,78.233)))*43758.5453);\\nvec3 myFlakeNormal=normalize(normal+vec3(sin(mySparkleGrain*91.0),cos(mySparkleGrain*73.0),0.0)*.55);\\nfloat myGlint=pow(max(dot(myFlakeNormal,normalize(vViewPosition)),0.0),42.0);\\ngl_FragColor.rgb+=step(0.94,mySparkleGrain)*myGlint*uSparkle*2.2;\\n#include <dithering_fragment>');\r\n };\r\n const priorKey=mat.customProgramCacheKey.bind(mat);mat.customProgramCacheKey=()=>priorKey()+'|myr5-sparkle-v3|'+amount.toFixed(3);\r\n mat.needsUpdate=true;\r\n}\r\n\r\nfunction meshWorldSpan(g:T.BufferGeometry,matrix:T.Matrix4){\r\n if(!g.boundingBox)g.computeBoundingBox();\r\n const size=g.boundingBox!.clone().applyMatrix4(matrix).getSize(new T.Vector3());\r\n return Math.max(size.x,size.y,size.z,1e-6);\r\n}\r\n\r\nexport function authoredUvScale(g:T.BufferGeometry,matrix:T.Matrix4){\r\n const uv=g.attributes.uv,p=g.attributes.position,idx=g.index;if(!uv||uv.itemSize<2)return 1.8;\r\n let worldArea=0,uvArea=0;const a=new T.Vector3(),b=new T.Vector3(),c=new T.Vector3(),ab=new T.Vector3(),ac=new T.Vector3();\r\n const count=idx?.count??p.count;\r\n for(let j=0;j+2<count;j+=3){const ia=idx?idx.getX(j):j,ib=idx?idx.getX(j+1):j+1,ic=idx?idx.getX(j+2):j+2;\r\n  a.fromBufferAttribute(p,ia).applyMatrix4(matrix);b.fromBufferAttribute(p,ib).applyMatrix4(matrix);c.fromBufferAttribute(p,ic).applyMatrix4(matrix);\r\n  ab.subVectors(b,a);ac.subVectors(c,a);worldArea+=ab.cross(ac).length()*.5;\r\n  const ux=uv.getX(ib)-uv.getX(ia),uy=uv.getY(ib)-uv.getY(ia),vx=uv.getX(ic)-uv.getX(ia),vy=uv.getY(ic)-uv.getY(ia);uvArea+=Math.abs(ux*vy-uy*vx)*.5;\r\n }\r\n if(!Number.isFinite(worldArea)||!Number.isFinite(uvArea)||worldArea<=1e-10||uvArea<=1e-10)return 1.8;\r\n // Divide physical UV density by the mesh span. A ten-times larger imported\r\n // sculpt should show the same sized pattern, not 10x more tiles that mipmap away.\r\n const span=meshWorldSpan(g,matrix);\r\n return T.MathUtils.clamp(Math.sqrt(worldArea/uvArea)*1.8/Math.max(1,span/2),.5,6);\r\n}\r\n\r\n// R25: a vertex can only carry relief that is coarser than the mesh. Point-sampling a finer pattern\r\n// (Fine Stripe has 40 strands per tile) at sparse roster vertices aliased into lumpy patches, so the\r\n// displacement fades out between a quarter and half of the pattern's finest wavelength; the bump and\r\n// colour maps still draw the full detail. Wavelength = finest axis, Schmitt-triggered against noise.\r\nconst reliefWavelengths=new Map<number,number>();\r\nfunction reliefWavelength(id:number){\r\n let w=reliefWavelengths.get(id);if(w!==undefined)return w;w=Infinity;const n=2048;\r\n for(const axis of [0,1]){const h=new Float32Array(n);let lo=1,hi=0;for(let i=0;i<n;i++){h[i]=surfaceSample(id,axis?.37:i/n,axis?i/n:.37).height;lo=Math.min(lo,h[i]);hi=Math.max(hi,h[i]);}\r\n  const mid=(lo+hi)/2,band=(hi-lo)*.2;let side=0,crossings=0;for(const value of h){const next=value>mid+band?1:value<mid-band?-1:side;if(side&&next!==side)crossings++;side=next;}\r\n  if(crossings)w=Math.min(w,2/crossings);}\r\n reliefWavelengths.set(id,w);return w;\r\n}\r\nfunction meanEdge(g:T.BufferGeometry,matrix:T.Matrix4){\r\n const p=g.attributes.position,idx=g.index,count=idx?.count??p.count,stride=Math.max(1,Math.floor(count/3/4000))*3,a=new T.Vector3(),b=new T.Vector3();let sum=0,edges=0;\r\n for(let j=0;j+2<count;j+=stride)for(let k=0;k<3;k++){a.fromBufferAttribute(p,idx?idx.getX(j+k):j+k).applyMatrix4(matrix);b.fromBufferAttribute(p,idx?idx.getX(j+(k+1)%3):j+(k+1)%3).applyMatrix4(matrix);sum+=a.distanceTo(b);edges++;}\r\n return edges?sum/edges:0;\r\n}\r\nexport function reliefResolve(id:number,uvEdge:number){const w=reliefWavelength(id);return 1-T.MathUtils.smoothstep(uvEdge,w/4,w/2);}\r\n\r\nexport function sculptMaterial(mesh:T.Mesh,style:Style,unit=1,amount=1,coachRelief?:CoachReliefBudget){\r\n if(Array.isArray(mesh.material)||!mesh.geometry.attributes.position)return;\r\n // The higher-density authored-UV path is deliberately limited to known static meshes.\r\n // Keep animated, morph-target, interleaved and unsupported Float16 geometry on the\r\n // established path until their attributes can be refined without changing semantics.\r\n if(coachRelief&&((mesh as T.SkinnedMesh).isSkinnedMesh||mesh.geometry.attributes.skinIndex||mesh.geometry.attributes.skinWeight||Object.values(mesh.geometry.morphAttributes).some(attributes=>attributes.length)||Object.values(mesh.geometry.attributes).some(attribute=>(attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||(attribute as T.BufferAttribute & {isFloat16BufferAttribute?:boolean}).isFloat16BufferAttribute||((globalThis as any).Float16Array&&attribute.array instanceof (globalThis as any).Float16Array))))coachRelief=undefined;\r\n const old=mesh.geometry;\r\n // Keep Original MYR5's established single-pass geometry, UVs and JS-double displacement path exact.\r\n if(!coachRelief){\r\n  const g=old.clone();if(!g.attributes.normal)g.computeVertexNormals();\r\n  const p=g.attributes.position,n=g.attributes.normal,uv=new Float32Array(p.count*2),colors=new Float32Array(p.count*3);\r\n  mesh.updateWorldMatrix(true,false);const normalMatrix=new T.Matrix3().getNormalMatrix(mesh.matrixWorld),inv=mesh.matrixWorld.clone().invert(),point=new T.Vector3(),normal=new T.Vector3();\r\n  const id=style.id,relief=unit*(builtinSurfaceProfile(id)?.relief??([0,8,20,21,22].includes(id)?.0018:id===13?.037:id===18?.018:.019));\r\n  for(let i=0;i<p.count;i++){\r\n   point.fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld);normal.fromBufferAttribute(n,i).applyMatrix3(normalMatrix).normalize();\r\n   const x=point.x/unit,y=point.y/unit,z=point.z/unit;\r\n   const u=(Math.abs(normal.z)>.45?x:z)*1.8+.5,v=y*1.8+.5,s=surfaceSample(id,u,v);uv[i*2]=u;uv[i*2+1]=v;\r\n   let edge=1;for(const [sx,sy,sz,r]of mesh.userData.eyeSockets??[])edge*=T.MathUtils.smoothstep(Math.hypot(point.x-sx,point.y-sy,point.z-sz),r*1.04,r*1.35);\r\n   point.addScaledVector(normal,(s.height-.5)*relief*amount*edge).applyMatrix4(inv);p.setXYZ(i,point.x,point.y,point.z);\r\n   const shade=.91+.09*Math.sin(x*3+y*4+z*2);colors.set([shade,shade,shade],i*3);\r\n  }\r\n  g.setAttribute('uv',new T.BufferAttribute(uv,2));g.setAttribute('color',new T.BufferAttribute(colors,3));g.computeVertexNormals();g.computeBoundingBox();g.computeBoundingSphere();\r\n  const oldMat=mesh.material as T.MeshStandardMaterial;mesh.material=materialFor(style,unit,oldMat);mesh.geometry=g;\r\n  if(mesh.userData.ownedGeometry)old.dispose();mesh.userData.ownedGeometry=true;mesh.userData.ownedMaterial=true;return;\r\n }\r\n mesh.updateWorldMatrix(true,false);const worldScale=mesh.matrixWorld.getMaxScaleOnAxis(),refined=refineCoachGeometry(old,coachRelief,worldScale),g=refined?.geometry??old.clone();if(!g.attributes.normal)g.computeVertexNormals();\r\n // Keep imported smoothing while adding only the geometric normal change caused by relief.\r\n // This avoids faceting the source coach while making shallow height fields catch light.\r\n const authoredNormals=new Float32Array(g.attributes.normal.array as ArrayLike<number>);g.computeVertexNormals();const geometricBefore=new Float32Array(g.attributes.normal.array as ArrayLike<number>);g.attributes.normal.array.set(authoredNormals);g.attributes.normal.needsUpdate=true;\r\n const p=g.attributes.position,n=g.attributes.normal,uv=new Float32Array(p.count*2),colors=new Float32Array(p.count*3),worldPositions=new Float32Array(p.count*3),worldOffsets=new Float32Array(p.count*3);\r\n const vertexKeys=coachRelief?new Array<string>(p.count):undefined;\r\n const coordinateUnit=Math.max(unit,meshWorldSpan(g,mesh.matrixWorld)/2);\r\n const resolvable=reliefResolve(style.id,meanEdge(g,mesh.matrixWorld)*1.8/coordinateUnit);\r\n const normalMatrix=new T.Matrix3().getNormalMatrix(mesh.matrixWorld),inv=mesh.matrixWorld.clone().invert(),point=new T.Vector3(),normal=new T.Vector3();\r\n const id=style.id,relief=Math.min(unit*(builtinSurfaceProfile(id)?.relief??([0,8,20,21,22].includes(id)?.0018:id===13?.037:id===18?.018:.019)),meshWorldSpan(g,mesh.matrixWorld)*.015);\r\n const seamOffsets=coachRelief?new Map<string,{x:number;y:number;z:number;count:number}>():undefined,seamKey=(x:number,y:number,z:number)=>`${Math.round(x*1e5)},${Math.round(y*1e5)},${Math.round(z*1e5)}`;\r\n for(let i=0;i<p.count;i++){\r\n  const localX=p.getX(i),localY=p.getY(i),localZ=p.getZ(i);point.set(localX,localY,localZ).applyMatrix4(mesh.matrixWorld);normal.fromBufferAttribute(n,i).applyMatrix3(normalMatrix).normalize();\r\n  const x=point.x/coordinateUnit,y=point.y/coordinateUnit,z=point.z/coordinateUnit;\r\n  // R25: every species uses Original MYR5's object projection. Authored (Tripo atlas) UVs are cut into\r\n  // islands with their own rotation and density, so directional patterns such as Fine Stripe turned\r\n  // into a patchwork across the belly. The projection is fixed on the mesh and periodic for the surfaces.\r\n  const u=(Math.abs(normal.z)>.45?x:z)*1.8+.5,v=y*1.8+.5,s=surfaceSample(id,u,v);\r\n  uv[i*2]=u;uv[i*2+1]=v;worldPositions[i*3]=point.x;worldPositions[i*3+1]=point.y;worldPositions[i*3+2]=point.z;\r\n  let edge=1;for(const [sx,sy,sz,r]of mesh.userData.eyeSockets??[])edge*=T.MathUtils.smoothstep(Math.hypot(point.x-sx,point.y-sy,point.z-sz),r*1.04,r*1.35);\r\n  const offset=(s.height-.5)*relief*amount*edge*resolvable,dx=normal.x*offset,dy=normal.y*offset,dz=normal.z*offset;worldOffsets[i*3]=dx;worldOffsets[i*3+1]=dy;worldOffsets[i*3+2]=dz;\r\n  if(seamOffsets){const key=seamKey(localX,localY,localZ);vertexKeys![i]=key;const group=seamOffsets.get(key)??{x:0,y:0,z:0,count:0};group.x+=dx;group.y+=dy;group.z+=dz;group.count++;seamOffsets.set(key,group);}\r\n  const shade=.91+.09*Math.sin(x*3+y*4+z*2);colors.set([shade,shade,shade],i*3);\r\n }\r\n for(let i=0;i<p.count;i++){\r\n  const x=worldPositions[i*3],y=worldPositions[i*3+1],z=worldPositions[i*3+2];let dx=worldOffsets[i*3],dy=worldOffsets[i*3+1],dz=worldOffsets[i*3+2];\r\n  if(seamOffsets){const group=seamOffsets.get(vertexKeys![i]);if(group&&group.count>1){dx=group.x/group.count;dy=group.y/group.count;dz=group.z/group.count;}}\r\n  point.set(x+dx,y+dy,z+dz).applyMatrix4(inv);p.setXYZ(i,point.x,point.y,point.z);\r\n }\r\n g.computeVertexNormals();const geometricAfter=g.attributes.normal;\r\n for(let i=0;i<p.count;i++){const j=i*3,x=authoredNormals[j]+geometricAfter.array[j]-geometricBefore[j],y=authoredNormals[j+1]+geometricAfter.array[j+1]-geometricBefore[j+1],z=authoredNormals[j+2]+geometricAfter.array[j+2]-geometricBefore[j+2],length=Math.hypot(x,y,z)||1;geometricAfter.setXYZ(i,x/length,y/length,z/length);}\r\n g.setAttribute('uv',new T.BufferAttribute(uv,2));g.setAttribute('color',new T.BufferAttribute(colors,3));g.computeBoundingBox();g.computeBoundingSphere();\r\n const oldMat=mesh.material as T.MeshStandardMaterial;mesh.material=materialFor(style,unit,oldMat);mesh.geometry=g;\r\n if(mesh.userData.ownedGeometry)old.dispose();mesh.userData.ownedGeometry=true;mesh.userData.ownedMaterial=true;\r\n}\r\n\r\ntype Triangle={a:T.Vector3;b:T.Vector3;c:T.Vector3;normal:T.Vector3;total:number};\r\nfunction surfaceTriangles(group:T.Group){\r\n group.updateWorldMatrix(true,true);const inv=group.matrixWorld.clone().invert(),triangles:Triangle[]=[],bounds=new T.Box3();let total=0;\r\n group.traverseVisible(obj=>{if(!(obj instanceof T.Mesh)||obj.userData.materialDetail)return;const g=obj.geometry,p=g.attributes.position,ix=g.index;if(!p)return;\r\n  const matrix=inv.clone().multiply(obj.matrixWorld),normalMatrix=new T.Matrix3().getNormalMatrix(matrix),authored=g.attributes.normal,count=ix?.count??p.count;\r\n  // Surface sampling needs area coverage, not every triangle of the dense fur assets.\r\n  const stride=Math.max(1,Math.ceil(count/24000))*3;\r\n  for(let j=0;j+2<count;j+=stride){const ids=[0,1,2].map(k=>ix?ix.getX(j+k):j+k),[a,b,c]=ids.map(i=>new T.Vector3().fromBufferAttribute(p,i).applyMatrix4(matrix));const cross=b.clone().sub(a).cross(c.clone().sub(a)),area=cross.length()*.5;if(area<1e-10)continue;const normal=authored?ids.reduce((sum,i)=>sum.add(new T.Vector3().fromBufferAttribute(authored,i).applyMatrix3(normalMatrix)),new T.Vector3()).normalize():cross.normalize();if(normal.lengthSq()<1e-8)normal.copy(cross).normalize();total+=area;bounds.expandByPoint(a);bounds.expandByPoint(b);bounds.expandByPoint(c);triangles.push({a,b,c,normal,total});}\r\n });return {triangles,total,bounds};\r\n}\r\nexport function growMaterial(group:T.Group,style:Style,region:string,unit=1,amount=1,hand=false){\r\n const result=new T.Group();result.name='Material sculpture '+style.detail;result.userData.region=region;\r\n if(region==='eye'||region==='nails'||[0,7,22].includes(style.id))return result;\r\n const {triangles,total,bounds}=surfaceTriangles(group);if(!triangles.length)return result;\r\n let seed=style.id*9173+region.length*419;const rand=()=>{seed=(Math.imul(seed,1664525)+1013904223)>>>0;return seed/4294967296;};\r\n const id=style.id;if(hand&&id===20)return result;\r\n const baseCount=id===20?2100:[3,4].includes(id)?110:id===21?32:42;\r\n const count=Math.round((id>=63?(id===66?60:id===68?22:id===72?12:38):id>=57&&id<=62?(id===61?180:id===58?55:36):baseCount)*(region==='head'||region==='palm'||region==='back_of_hand'?1:region==='body'?.8:.5));\r\n const batches:T.BufferGeometry[][]=[[],[],[]],normal=new T.Vector3(),point=new T.Vector3(),up=new T.Vector3(0,1,0);\r\n const span=bounds.getSize(new T.Vector3()),featureUnit=unit*T.MathUtils.clamp(Math.cbrt(Math.max(1e-6,span.x*span.y*span.z))/2.2,1,2.2);\r\n function add(g:T.BufferGeometry,pos:T.Vector3,q:T.Quaternion,scale:T.Vector3,material=0){g.applyMatrix4(new T.Matrix4().compose(pos,q,scale));if(!g.attributes.uv)g.setAttribute('uv',new T.Float32BufferAttribute(new Float32Array(g.attributes.position.count*2),2));if(g.index){const expanded=g.toNonIndexed();g.dispose();g=expanded;}batches[material].push(g);}\r\n const color=[style.primary,style.accent,style.secondary];\r\n for(let k=0;k<count;k++){\r\n  const pick=rand()*total;let lo=0,hi=triangles.length-1;while(lo<hi){const m=(lo+hi)>>1;if(triangles[m].total<pick)lo=m+1;else hi=m;}\r\n  const {a,b,c}=triangles[lo],u=Math.sqrt(rand()),v=rand();point.copy(a).multiplyScalar(1-u).addScaledVector(b,u*(1-v)).addScaledVector(c,u*v);normal.copy(triangles[lo].normal);\r\n  let socket=false;group.traverse(o=>{for(const [x,y,z,r]of o.userData.eyeSockets??[])if(point.distanceTo(new T.Vector3(x,y,z))<r*1.48)socket=true;});\r\n  if(socket||(!hand&&region==='feet'&&normal.y<-.2))continue;\r\n  const larger=[2,3,9,13,14,16].includes(id)?1.7:1;\r\n  const q=new T.Quaternion().setFromUnitVectors(up,normal),s=featureUnit*amount*(.055+rand()*.075)*larger,center=point.clone(),size=new T.Vector3(s,s,s);\r\n  const geometry=(g:T.BufferGeometry,offset=0,scale=size,mat=0)=>add(g,center.clone().addScaledVector(normal,offset+s*.12),q,scale,mat);\r\n  switch(id){\r\n   case 63:geometry(new T.SphereGeometry(.8,10,7),-s*.3,new T.Vector3(s,s*.6,s),k%3);break;\r\n   case 64:geometry(new T.SphereGeometry(.7,10,7),-s*.12,new T.Vector3(s*.8,s*.65,s*.8),k%3);if(k%3===0)geometry(new T.TorusGeometry(.45,.13,5,10).rotateX(Math.PI/2),s*.05,size,0);break;\r\n   case 65:geometry(new T.DodecahedronGeometry(.6,0),0,new T.Vector3(s,s*.45,s),k%3);geometry(new T.SphereGeometry(.22,6,4),s*.4,size,2);break;\r\n   case 66:{const curve=new T.CatmullRomCurve3([new T.Vector3(-.7,0,0),new T.Vector3(-.25,.35,.25),new T.Vector3(.3,.2,-.15),new T.Vector3(.65,.55,.1)]);geometry(new T.TubeGeometry(curve,7,.15,5,false),s*.06,new T.Vector3(s,s,s),k%3);break;}\r\n   case 67:{const curve=new T.CatmullRomCurve3([new T.Vector3(-.6,0,0),new T.Vector3(-.15,.3,.15),new T.Vector3(.5,.55,-.1)]);geometry(new T.TubeGeometry(curve,6,.12,5,false),s*.1,new T.Vector3(s*.75,s*1.4,s),k%3);break;}\r\n   case 68:{geometry(new T.CylinderGeometry(.48,.38,.045,12),s*.12,size,1);geometry(new T.TorusGeometry(.53,.13,6,12).rotateX(Math.PI/2),s*.17,size,0);for(let t=0;t<6;t++){const a=t*Math.PI/3,offset=new T.Vector3(Math.cos(a)*s*.34,s*.32,Math.sin(a)*s*.34).applyQuaternion(q);add(new T.ConeGeometry(.08,.34,5),center.clone().add(offset),q,size,2);}break;}\r\n   case 69:geometry(new T.BoxGeometry(.65,.13,.85),s*.04,size,0);geometry(new T.BoxGeometry(.08,.05,1.15),s*.14,size,2);geometry(new T.CylinderGeometry(.12,.12,.1,8),s*.18,size,2);break;\r\n   case 70:geometry(new T.BoxGeometry(1.25,.18,.85),s*.1,size,0);geometry(new T.CylinderGeometry(.17,.17,.19,8),s*.27,size,1);geometry(new T.BoxGeometry(.9,.05,.12),s*.25,size,2);break;\r\n   case 71:geometry(new T.CylinderGeometry(.15,.15,1.7,8).rotateZ(Math.PI/2),s*.13,size,0);geometry(new T.BoxGeometry(.2,.11,1.05),s*.12,size,1);break;\r\n   case 72:geometry(new T.BoxGeometry(.8,.1,.5),s*.07,size,1);geometry(new T.CylinderGeometry(.1,.1,.12,6),s*.16,size,0);break;\r\n   case 73:geometry(new T.BoxGeometry(1,.15,1),s*.1,size,0);geometry(new T.BoxGeometry(.08,.025,1.1).rotateY(Math.PI/4),s*.2,size,1);break;\r\n   case 74:geometry(new T.SphereGeometry(.32,8,6),-s*.05,size,2);geometry(new T.TorusGeometry(.45,.07,5,12).rotateX(Math.PI/2),s*.07,size,0);break;\r\n   case 57:geometry(new T.OctahedronGeometry(.55,1),-s*.3,new T.Vector3(s*.6,s*.2,s*.6),k%3);break;\r\n   case 58:geometry(new T.SphereGeometry(.55,10,7),-s*.4,new T.Vector3(s*.45,s*.65,s*.45),k%3);break;\r\n   case 59:case 62:geometry(new T.CylinderGeometry(0,.32,1.7,6),s*.42,size,k%3);break;\r\n   case 61:geometry(new T.OctahedronGeometry(.22),-s*.2,new T.Vector3(s,s*.18,s),k%3);break;\r\n   case 1:{ // Roots and leaves have separate silhouettes, not generic spikes.\r\n    const path=new T.CatmullRomCurve3([new T.Vector3(0,-.1,0),new T.Vector3(.18,.5,0),new T.Vector3(-.15,1.3,.1),new T.Vector3(.35,2,.1)]);\r\n    geometry(new T.TubeGeometry(path,8,.14,5,false),0,size,2);geometry(new T.SphereGeometry(1,8,5),s*1.1,new T.Vector3(s*.55,s*.9,s*.12),1);break;}\r\n   case 2:geometry(new T.CylinderGeometry(.13,.19,1,6),s*.25,new T.Vector3(s,s,s),2);geometry(new T.SphereGeometry(1,12,8,0,Math.PI*2,0,Math.PI/2),s*.8,new T.Vector3(s*.8,s*.38,s*.8),k%3===0?1:0);geometry(new T.ConeGeometry(.73,.12,16),s*.77,size,2);break;\r\n   case 3:geometry(new T.SphereGeometry(1,6,4),s*.08,new T.Vector3(s*.86,s*.26,s*1.3),0);geometry(new T.ConeGeometry(.19,.8,5),s*.34,size,1);break;\r\n   case 4:geometry(new T.SphereGeometry(1,5,3),s*.015,new T.Vector3(s*.68,s*.17,s),k%6===0?1:0);break;\r\n   case 5:geometry(new T.ConeGeometry(.18,2.5,4),s*.6,new T.Vector3(s,s,s*.5),2);geometry(new T.SphereGeometry(.22,8,5),s*1.7,size,1);break;\r\n   case 6:{geometry(new T.CylinderGeometry(.19,.32,1.9,7),s*.55,size,0);for(const sign of [-1,1]){const branchQ=q.clone().multiply(new T.Quaternion().setFromAxisAngle(new T.Vector3(0,0,1),sign*.62));add(new T.CylinderGeometry(.12,.2,1.2,6),center.clone().addScaledVector(normal,s),branchQ,size,1);}geometry(new T.TorusGeometry(.2,.08,5,9),s*1.5,size,2);break;}\r\n   case 8:geometry(new T.SphereGeometry(1,9,6),s*.3,new T.Vector3(s*.3,s*1.9,s*.13),1);break;\r\n   case 9:{const curve=new T.CatmullRomCurve3([new T.Vector3(0,-.15,0),new T.Vector3(.1,.7,0),new T.Vector3(.6,1.5,0)]);const g=new T.TubeGeometry(curve,9,.24,7,false),p=g.attributes.position;for(let j=0;j<p.count;j++){const t=Math.floor(j/8)/9,at=curve.getPointAt(t),v=new T.Vector3().fromBufferAttribute(p,j).sub(at).multiplyScalar(1-t*.97).add(at);p.setXYZ(j,v.x,v.y,v.z);}g.computeVertexNormals();geometry(g,0,size,2);break;}\r\n   case 10:geometry(new T.TorusGeometry(.65,.075,5,18,Math.PI*1.55),s*.3,size,1);geometry(new T.OctahedronGeometry(.35),s*.4,size,0);break;\r\n   case 11:geometry(new T.OctahedronGeometry(1),s*.02,new T.Vector3(s*.7,s*.28,s*.85),2);geometry(new T.OctahedronGeometry(.11),s*.5,size,1);break;\r\n   case 12:geometry(new T.TorusGeometry(.65,.18,7,13,Math.PI*1.8),s*.25,size,0);geometry(new T.SphereGeometry(.28,8,6),s*.4,size,1);break;\r\n   case 13:geometry(new T.DodecahedronGeometry(1,0),s*.05,new T.Vector3(s*1.3,s*.38,s*.9),k%4===0?1:0);break;\r\n   case 14:case 16:geometry(new T.CylinderGeometry(0,.36,2.3,id===14?6:5),s*.72,new T.Vector3(s,s,s),k%3===0?1:0);geometry(new T.CylinderGeometry(.28,.34,.65,6),s*.14,size,2);break;\r\n   case 15:geometry(new T.DodecahedronGeometry(1,0),s*.025,new T.Vector3(s*1.25,s*.22,s),2);break;\r\n   case 17:geometry(new T.BoxGeometry(.12,1.7,.9),s*.45,size,2);geometry(new T.CylinderGeometry(.08,.08,1.4,5),s*.4,size,1);break;\r\n   case 18:{geometry(new T.CylinderGeometry(.76,.88,.18,8),s*.12,size,0);geometry(new T.TorusGeometry(.38,.1,5,14),s*.26,size,2);for(let r=0;r<6;r++){const angle=r*Math.PI/3,offset=new T.Vector3(Math.cos(angle)*s*.63,s*.29,Math.sin(angle)*s*.63).applyQuaternion(q);add(new T.CylinderGeometry(.08,.08,.12,6),center.clone().add(offset),q,size,1);}if(k%3===0)geometry(new T.CylinderGeometry(.46,.46,.23,12),s*.32,size,2);break;}\r\n   case 19:geometry(new T.BoxGeometry(1.1,.19,1.65),s*.06,size,2);geometry(new T.BoxGeometry(.075,.035,1.35),s*.18,size,1);break;\r\n   case 20:{const lean=.3+rand()*.6,curve=new T.CatmullRomCurve3([new T.Vector3(0,-.1,0),new T.Vector3(.15,.6,.1),new T.Vector3(lean,1.3,.25),new T.Vector3(lean*1.4,1.65,.3)]);const g=new T.TubeGeometry(curve,5,.035,3,false),p=g.attributes.position;for(let j=0;j<p.count;j++){const t=Math.floor(j/4)/5,at=curve.getPointAt(t),v=new T.Vector3().fromBufferAttribute(p,j).sub(at).multiplyScalar(1-t*.96).add(at);p.setXYZ(j,v.x,v.y,v.z);}g.computeVertexNormals();geometry(g,0,size,k%4===0?1:k%5===0?2:0);break;}\r\n   case 21:geometry(new T.SphereGeometry(1,10,7),-s*.72,new T.Vector3(s*.3,s*.43,s*.3),k%4===0?1:2);break;\r\n  }\r\n }\r\n batches.forEach((geos,index)=>{if(!geos.length)return;const g=mergeGeometries(geos,false);geos.forEach(g=>g.dispose());if(!g)return;\r\n  const mat=new T.MeshPhysicalMaterial({color:color[index],roughness:[14,16,21].includes(id)?.12:id===20?.95:style.roughness,metalness:style.metalness,clearcoat:[3,18,19,21].includes(id)?.7:0});\r\n  if(index===1&&[5,8,9,11,12,15,17,19].includes(id)){mat.emissive.set(style.accent);mat.emissiveIntensity=1.2;}\r\n  if([8,14,16].includes(id)){mat.transmission=.45;mat.thickness=unit*.15;mat.ior=1.35;mat.metalness=0;}\r\n  if(id>=57&&id<=62){mat.clearcoat=1;mat.clearcoatRoughness=.035;mat.roughness=.08;mat.iridescence=.9;mat.iridescenceThicknessRange=[100,650];\r\n   if(id===58){mat.transmission=.75;mat.thickness=unit*.04;mat.metalness=0;mat.ior=1.1;}\r\n   if(id===57||id===59){mat.transmission=.5;mat.thickness=unit*.08;mat.metalness=0;mat.ior=1.6;}\r\n   if(id===61){mat.metalness=.9;applySparkle(mat,1);}\r\n   if(id===62&&index===1){mat.emissive.set(style.accent);mat.emissiveIntensity=.5;}\r\n  }\r\n  if(id>=63&&id<=68){mat.metalness=0;mat.clearcoat=id===65?0:1;mat.clearcoatRoughness=.055;mat.roughness=id===65?.98:.16;\r\n   if(id===63){mat.transmission=.55;mat.thickness=unit*.08;mat.ior=1.33;}\r\n   if(id===64&&index===2){mat.transmission=.25;mat.thickness=unit*.06;}\r\n  }\r\n  if(id>=69&&id<=74){mat.metalness=id===74?0:style.metalness;mat.clearcoat=.8;mat.clearcoatRoughness=.06;\r\n   if(index===2&&[69,70,74].includes(id)){mat.emissive.set(style.accent);mat.emissiveIntensity=1.3;}\r\n   if(id===74&&index===0){mat.transmission=.75;mat.thickness=unit*.04;mat.roughness=.045;}\r\n  }\r\n  if(id===20){mat.sheen=1;mat.sheenColor.set(style.accent);}\r\n  if(id===21){mat.color.set(index===1?style.accent:'#edffd3');mat.roughness=.12;mat.metalness=0;}\r\n  if(id===18){mat.metalness=.87;mat.color.set(index===2?'#333d48':color[index]);}\r\n  const mesh=new T.Mesh(g,mat);mesh.name=style.detail+' structural details';mesh.userData={materialDetail:true,ownedGeometry:true,ownedMaterial:true,region};result.add(mesh);\r\n });return result;\r\n}\r\n","creature/source/creator/material-patterns.ts":"/** Built-in procedural surface families. These are local math, so previews work offline. */\r\nexport type SurfaceSample={height:number;tint:number;glow:number;rough:number};\r\nexport type SurfaceProfile={id:number;name:string;roughness:number;metalness:number;relief:number;bump:number;sheen:number;sheenRoughness:number;clearcoat:number;clearcoatRoughness:number};\r\n\r\n// Stable ids 32-55 correspond to the Battle Pass catalogue order in materials-registry.ts.\r\nexport const BUILTIN_SURFACE_PROFILES:readonly SurfaceProfile[]=[\r\n {id:32,name:'Plate Steel',roughness:.34,metalness:.82,relief:.024,bump:.012,sheen:0,sheenRoughness:.7,clearcoat:.35,clearcoatRoughness:.24},\r\n {id:33,name:'Rubber Grip',roughness:.95,metalness:0,relief:.055,bump:.022,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:34,name:'Chain Mail',roughness:.41,metalness:.78,relief:.034,bump:.014,sheen:0,sheenRoughness:.7,clearcoat:.3,clearcoatRoughness:.25},\r\n {id:35,name:'Track Rubber',roughness:.94,metalness:0,relief:.038,bump:.016,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:36,name:'Denim',roughness:.86,metalness:0,relief:.012,bump:.011,sheen:.22,sheenRoughness:.96,clearcoat:0,clearcoatRoughness:.5},\r\n {id:37,name:'Hex Tread',roughness:.82,metalness:.04,relief:.052,bump:.014,sheen:0,sheenRoughness:.9,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:38,name:'Sweatshirt Fleece',roughness:.99,metalness:0,relief:.05,bump:.032,sheen:.74,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n {id:39,name:'Quilted',roughness:.89,metalness:0,relief:.07,bump:.012,sheen:.14,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:40,name:'Speckled',roughness:.96,metalness:0,relief:.03,bump:.028,sheen:.34,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n {id:41,name:'Hammered Bronze',roughness:.39,metalness:.78,relief:.025,bump:.025,sheen:0,sheenRoughness:.7,clearcoat:.28,clearcoatRoughness:.22},\r\n {id:42,name:'Fine Stripe',roughness:.91,metalness:0,relief:.042,bump:.012,sheen:.08,sheenRoughness:.92,clearcoat:0,clearcoatRoughness:.5},\r\n {id:43,name:'Snake Skin',roughness:.68,metalness:.02,relief:.019,bump:.023,sheen:.1,sheenRoughness:.76,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:44,name:'Holey',roughness:.96,metalness:0,relief:.039,bump:.025,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:45,name:'Woven Mat',roughness:.9,metalness:0,relief:.014,bump:.014,sheen:.08,sheenRoughness:.94,clearcoat:0,clearcoatRoughness:.5},\r\n {id:46,name:'Petal',roughness:.51,metalness:0,relief:.025,bump:.009,sheen:.52,sheenRoughness:.72,clearcoat:.12,clearcoatRoughness:.3},\r\n {id:47,name:'Graph Paper',roughness:.93,metalness:0,relief:.012,bump:.017,sheen:.16,sheenRoughness:.97,clearcoat:0,clearcoatRoughness:.5},\r\n {id:48,name:'Bamboo',roughness:.57,metalness:0,relief:.027,bump:.008,sheen:.18,sheenRoughness:.62,clearcoat:.12,clearcoatRoughness:.28},\r\n {id:49,name:'Dragon Scale',roughness:.31,metalness:.16,relief:.043,bump:.01,sheen:.24,sheenRoughness:.42,clearcoat:.72,clearcoatRoughness:.16},\r\n {id:50,name:'Cool Graph Paper',roughness:.56,metalness:.23,relief:.021,bump:.008,sheen:0,sheenRoughness:.8,clearcoat:.12,clearcoatRoughness:.3},\r\n {id:51,name:'Terry Cloth',roughness:.98,metalness:0,relief:.014,bump:.026,sheen:.62,sheenRoughness:.99,clearcoat:0,clearcoatRoughness:.5},\r\n {id:52,name:'Pebble Path',roughness:.77,metalness:0,relief:.038,bump:.018,sheen:0,sheenRoughness:.8,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:53,name:'Wiggles',roughness:.99,metalness:0,relief:.016,bump:.016,sheen:0,sheenRoughness:.95,clearcoat:0,clearcoatRoughness:.5},\r\n {id:54,name:'River Stone',roughness:.72,metalness:.01,relief:.031,bump:.019,sheen:.04,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.32},\r\n {id:55,name:'Moss',roughness:.99,metalness:0,relief:.022,bump:.023,sheen:.38,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n];\r\nconst pixelProfile:SurfaceProfile={id:56,name:'64-bit Skin',roughness:.58,metalness:.12,relief:.018,bump:.01,sheen:0,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.4};\r\n// Extra finishes use stable additive IDs; existing reward IDs retain their meaning.\r\nexport const SPECIAL_SURFACE_PROFILES:readonly SurfaceProfile[]=[\r\n {id:57,name:'Opal Jelly',roughness:.06,metalness:0,relief:.004,bump:.001,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.035},\r\n {id:58,name:'Bubble Glass',roughness:.035,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},\r\n {id:59,name:'Prism Crystal',roughness:.045,metalness:0,relief:.052,bump:.008,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.03},\r\n {id:60,name:'Holographic Foil',roughness:.18,metalness:.88,relief:.022,bump:.013,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.045},\r\n {id:61,name:'Glitter Resin',roughness:.075,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},\r\n {id:62,name:'Galaxy Geode',roughness:.22,metalness:.25,relief:.065,bump:.014,sheen:0,sheenRoughness:.3,clearcoat:.8,clearcoatRoughness:.06},\r\n {id:63,name:'Caustic Slime',roughness:0.055,metalness:0,relief:0.035,bump:0.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:64,name:'Blister Hide',roughness:0.18,metalness:0,relief:0.065,bump:0.023,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:65,name:'Rotten Rind',roughness:0.94,metalness:0,relief:0.05,bump:0.025,sheen:0,sheenRoughness:.6,clearcoat:0,clearcoatRoughness:.07},\r\n {id:66,name:'Parasite Nest',roughness:0.31,metalness:0,relief:0.07,bump:0.027,sheen:0,sheenRoughness:.6,clearcoat:0.6,clearcoatRoughness:.07},\r\n {id:67,name:'Exposed Sinew',roughness:0.2,metalness:0,relief:0.045,bump:0.017,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:68,name:'Abyssal Maw',roughness:0.26,metalness:0,relief:0.065,bump:0.023,sheen:0,sheenRoughness:.6,clearcoat:0.8,clearcoatRoughness:.07},\r\n {id:69,name:'Circuit Alloy',roughness:0.19,metalness:0.83,relief:0.027,bump:0.01,sheen:0,sheenRoughness:.6,clearcoat:0.6,clearcoatRoughness:.07},\r\n {id:70,name:'Servo Armor',roughness:0.34,metalness:0.82,relief:0.055,bump:0.013,sheen:0,sheenRoughness:.6,clearcoat:0.4,clearcoatRoughness:.07},\r\n {id:71,name:'Chrome Rib',roughness:0.09,metalness:0.96,relief:0.05,bump:0.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:72,name:'Carbon Mech',roughness:0.64,metalness:0.18,relief:0.018,bump:0.013,sheen:0,sheenRoughness:.6,clearcoat:0.25,clearcoatRoughness:.07},\r\n {id:73,name:'Hazard Panel',roughness:0.46,metalness:0.55,relief:0.032,bump:0.014,sheen:0,sheenRoughness:.6,clearcoat:0.4,clearcoatRoughness:.07},\r\n {id:74,name:'Reactor Glass',roughness:0.045,metalness:0,relief:0.018,bump:0.004,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n];\r\nconst profiles=new Map([...BUILTIN_SURFACE_PROFILES,pixelProfile,...SPECIAL_SURFACE_PROFILES].map(p=>[p.id,p]));\r\nexport const builtinSurfaceProfile=(id:number)=>profiles.get(id);\r\nconst fract=(x:number)=>x-Math.floor(x),clamp=(x:number)=>Math.max(0,Math.min(1,x));\r\nconst hash=(x:number,y:number)=>fract(Math.sin(x*127.1+y*311.7)*43758.5453);\r\nconst smooth=(a:number,b:number,x:number)=>{const t=clamp((x-a)/(b-a));return t*t*(3-2*t);};\r\nconst triangle=(x:number)=>1-Math.abs(fract(x)*2-1);\r\nconst voronoi=(x:number,y:number)=>{const ix=Math.floor(x),iy=Math.floor(y);let near=9,next=9;for(let j=-1;j<=1;j++)for(let i=-1;i<=1;i++){const px=ix+i+.18+.64*hash(ix+i,iy+j),py=iy+j+.18+.64*hash(iy+j,ix+i+19),d=Math.hypot(x-px,y-py);if(d<near){next=near;near=d;}else if(d<next)next=d;}return{near,gap:next-near};};\r\n\r\n/** High-contrast structural masks are paired with their actual material height and roughness maps. */\r\nexport function sampleBuiltinSurface(id:number,x:number,y:number):SurfaceSample|undefined{\r\n if(!profiles.has(id))return undefined;\r\n x=fract(x);y=fract(y); // Geometry relief and RepeatWrapping must sample the same tiled domain.\r\n const g=Math.sin(x*167.3+Math.sin(y*43)*1.7)*Math.sin(y*151.7+Math.sin(x*37))*0.5+0.5;\r\n const line=(v:number,n:number,w:number)=>1-smooth(w,w*2,Math.abs(fract(v*n)-.5));\r\n let h=.5,t=.5,glow=0,rough=.8;\r\n switch(id){\r\n  case 63:{const c=voronoi(x*7,y*7),sac=1-smooth(.04,.44,c.near),ooze=.5+.5*Math.sin(x*20+Math.sin(y*14)*3);h=.32+sac*.49;t=.13+sac*.67+ooze*.12;rough=.055+sac*.045;break;}\r\n  case 64:{const c=voronoi(x*10,y*9),pustule=1-smooth(.08,.36,c.near),rim=1-smooth(.02,.08,Math.abs(c.near-.33));h=.34+pustule*.56-rim*.08;t=.1+pustule*.8;rough=.13+.24*rim;break;}\r\n  case 65:{const c=voronoi(x*11,y*11),rot=1-smooth(.02,.14,c.gap),mould=hash(Math.floor(x*57),Math.floor(y*57))>.7?1:0;h=.56-rot*.4+mould*.12;t=.12+mould*.49+(1-rot)*.22;rough=.86+mould*.13;break;}\r\n  case 66:{const c=voronoi(x*9,y*9),hole=1-smooth(.1,.22,c.near),lip=1-smooth(.045,.1,Math.abs(c.near-.25));h=.53-hole*.42+lip*.18;t=.47-hole*.45+lip*.42;rough=.22+hole*.52;break;}\r\n  case 67:{const strand=.5+.5*Math.sin(x*95+Math.sin(y*13)*5),cleft=Math.pow(1-strand,8);h=.3+strand*.43-cleft*.15;t=.15+strand*.68;rough=.13+cleft*.35;break;}\r\n  case 68:{const c=voronoi(x*6,y*6),mouth=1-smooth(.06,.26,c.near),rim=1-smooth(.02,.07,Math.abs(c.near-.28)),tooth=hash(Math.floor(x*49),Math.floor(y*49))>.76?rim:0;h=.51-mouth*.47+rim*.26;t=.3-mouth*.28+tooth*.67;rough=.16+mouth*.64;break;}\r\n  case 69:{const wire=Math.max(line(x,12,.028),line(y,12,.025)),junction=1-smooth(.025,.065,Math.hypot(fract(x*6)-.5,fract(y*6)-.5));h=.49+wire*.17+junction*.2;t=.12+wire*.68+junction*.17;glow=wire*.8+junction;rough=.22-wire*.1;break;}\r\n  case 70:{const u=fract(x*4),v=fract(y*5),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.07,edge),bolt=1-smooth(.028,.07,Math.hypot(u-.14,v-.14));h=.68-seam*.45+bolt*.25;t=.56-seam*.5+bolt*.4;rough=.32+seam*.42;break;}\r\n  case 71:{const rib=triangle(x*13),groove=1-smooth(.07,.18,rib);h=.32+.57*rib;t=.17+.78*rib;rough=.09+groove*.3;break;}\r\n  case 72:{const u=fract(x*18),v=fract(y*18),over=(Math.floor(x*18)+Math.floor(y*18))%2,thread=over?Math.sin(u*Math.PI):Math.sin(v*Math.PI);h=.44+thread*.14;t=.12+thread*.69;rough=.64+.12*(1-thread);break;}\r\n  case 73:{const stripe=fract((x+y)*7)<.5?1:0,u=fract(x*3),v=fract(y*3),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.07,edge);h=.58-seam*.34;t=.07+stripe*.74-seam*.07;rough=.41+seam*.32;break;}\r\n  case 74:{const cell=voronoi(x*7,y*7),seam=1-smooth(.02,.07,cell.gap),core=1-smooth(.04,.16,cell.near);h=.52-seam*.12;t=.23+seam*.53+core*.23;glow=seam*.7+core;rough=.04+seam*.07;break;}\r\n\r\n  case 57:{const cloud=.5+.5*Math.sin(x*12+Math.sin(y*9)*2)*Math.cos(y*11);h=.48+cloud*.07;t=.48+cloud*.4;rough=.045+cloud*.025;break;}\r\n  case 58:{const c=voronoi(x*9,y*9),bubble=1-smooth(.1,.24,c.near);h=.49+bubble*.13;t=.7+bubble*.28;rough=.025+bubble*.035;break;}\r\n  case 59:{const c=voronoi(x*8,y*8),facet=Math.floor(c.near*7)/7,crack=1-smooth(.012,.06,c.gap);h=.35+facet*.65-crack*.12;t=.3+facet*.65;rough=.035+crack*.16;break;}\r\n  case 60:{const fold=Math.sin(x*31+Math.sin(y*23)*2)*Math.cos(y*27),ribs=triangle((x+y*.4)*38);h=.5+fold*.27+ribs*.06;t=.1+.8*(.5+.5*fold);rough=.12+ribs*.13;break;}\r\n  case 61:{const fleck=hash(Math.floor(x*83),Math.floor(y*83))>.91?1:0;h=.49+fleck*.035;t=.58+fleck*.4;rough=.075-fleck*.045;break;}\r\n  case 62:{const c=voronoi(x*6,y*6),seam=1-smooth(.025,.1,c.gap),star=hash(Math.floor(x*93),Math.floor(y*93))>.989?1:0;h=.65-seam*.43;t=.06+seam*.73+star*.2;glow=seam*.55+star*.4;rough=.32-seam*.2;break;}\r\n\r\n  case 56:{const ix=Math.floor(x*16),iy=Math.floor(y*16),pixel=Math.floor(hash(ix,iy)*4)/3;h=.35+.3*pixel;t=.1+.8*pixel;rough=.5+.15*(1-pixel);break;}\r\n  case 32:{const u=fract(x*3),v=fract(y*3),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.065,edge),rivet=Math.hypot(u-.5,v-.5),dot=(1-smooth(.035,.075,rivet))*((Math.floor(x*3)+Math.floor(y*3))%2===0?1:.35);h=.69-.34*seam+.28*dot;t=.69-.49*seam+.18*dot;rough=.3+.45*seam;break;}\r\n  case 33:{const d=Math.abs(fract((x+y)*6)-.5),a=Math.abs(fract((x-y)*6)-.5),ridge=Math.max(1-smooth(.045,.12,d),1-smooth(.045,.12,a)),trough=smooth(.16,.34,Math.min(d,a));h=.25+.64*ridge-.1*trough;t=.09+.82*ridge-.08*trough;rough=.99-.16*ridge;break;}\r\n  case 34:{const u=fract(x*7),v=fract(y*7),cx=Math.floor(x*7)+(Math.floor(y*7)%2)*.5+.5,cy=Math.floor(y*7)+.5,r=Math.hypot((x*7-cx)*.72,y*7-cy),ring=1-smooth(.055,.13,Math.abs(r-.31)),hole=1-smooth(.16,.25,r);h=.42+.39*ring-.15*hole;t=.3+.58*ring;rough=.58-.23*ring;void u;void v;break;}\r\n  case 35:{const chevron=triangle((x+y*.48)*9),ridge=1-smooth(.18,.31,Math.abs(chevron-.5));h=.31+.51*ridge;t=.18+.67*ridge;rough=.97-.11*ridge;break;}\r\n  case 36:{const twill=triangle((x+y)*26),cross=triangle((x-y*.12)*5);h=.46+.09*twill+.025*cross;t=.25+.56*twill;rough=.82+g*.12;break;}\r\n  case 37:{const u=fract(x*8),v=fract(y*8),hex=Math.max(Math.abs(u-.5)*.866+Math.abs(v-.5)*.5,Math.abs(v-.5)),ridge=1-smooth(.31,.43,hex);h=.28+.62*ridge;t=.14+.73*ridge;rough=.9-.17*ridge;break;}\r\n  case 38:{const c=voronoi(x*14,y*13),pile=1-smooth(.1,.54,c.near),valley=smooth(.06,.22,c.gap),fiber=Math.sin(x*83+Math.sin(y*41)*1.7)*Math.sin(y*77+Math.sin(x*37))*0.5+0.5;h=.2+.53*pile-.14*valley+.025*fiber;t=.1+.78*pile-.1*valley+.035*fiber;rough=.99;break;}\r\n  case 39:{const u=fract(x*4),v=fract(y*4),diamond=Math.abs(u-.5)+Math.abs(v-.5),seam=smooth(.39,.48,diamond),pad=1-smooth(.08,.43,diamond);h=.28+.62*pad-.21*seam;t=.14+.72*pad-.1*seam;rough=.93-.08*pad;break;}\r\n  case 40:{const d=voronoi(x*19,y*17),dimple=1-smooth(.06,.24,d.near),nap=smooth(.16,.39,d.near),fiber=Math.sin(x*91+Math.sin(y*48))*Math.sin(y*79+Math.sin(x*43));h=.46+.035*g-.14*dimple+.06*nap+.012*fiber;t=.54+.04*g-.27*dimple+.13*nap+.025*fiber;rough=.97-.025*nap;break;}\r\n  case 41:{const c=voronoi(x*11,y*11),pit=1-smooth(.03,.22,c.near),lip=1-smooth(.04,.2,c.gap);h=.55-.29*pit+.15*lip;t=.45-.31*pit+.18*lip;rough=.47-.16*lip+.28*pit;break;}\r\n  case 42:{const strand=triangle((x*8+y*1.7)*5),twist=triangle((x*8-y*1.7)*2);h=.27+.47*strand+.13*twist;t=.16+.74*strand;rough=.91-.08*strand;break;}\r\n  case 43:{const c=voronoi(x*15,y*15),crease=1-smooth(.025,.11,c.gap),grain=Math.sin(x*81+Math.sin(y*43))*Math.sin(y*75);h=.5-.16*crease+grain*.045;t=.38+.16*grain-.22*crease;rough=.72+.19*crease;break;}\r\n  case 44:{const c=voronoi(x*12,y*12),cell=smooth(.06,.37,c.near),chip=(hash(Math.floor(x*12),Math.floor(y*12))>.74?1:0)*cell;h=.34+.4*cell-.24*chip;t=.19+.62*cell-.18*chip;rough=.97;break;}\r\n  case 45:{const a=line(x+y*.12,12,.34),b=line(y-x*.08,12,.34),over=fract(x*12+y*12)<.5?a:b;h=.36+.27*a+.22*b+.12*over;t=.18+.37*a+.42*b;rough=.92-.12*over;break;}\r\n  case 46:{const u=fract(x*5)-.5,v=fract(y*5)-.5,angle=Math.atan2(v,u),r=Math.hypot(u,v),lobe=(1-smooth(.28,.49,r))*(.65+.35*Math.cos(angle*6)),vein=1-smooth(.012,.035,Math.abs(v-Math.sin(u*6)*.035));h=.33+.31*lobe+.12*vein;t=.19+.48*lobe+.22*vein;rough=.6-.17*lobe;break;}\r\n  case 47:{const vertical=line(x,22,.31),horizontal=line(y,22,.31),crossing=vertical*horizontal;h=.41+.12*vertical+.12*horizontal+.13*crossing;t=.26+.27*vertical+.27*horizontal;rough=.95-.08*crossing;break;}\r\n  case 48:{const rib=triangle(x*8),node=1-smooth(.015,.07,Math.abs(fract(y*2)-.5));h=.27+.53*(1-smooth(.28,.48,rib))+.14*node;t=.17+.67*(1-smooth(.3,.47,rib))+.12*node;rough=.68-.15*node;break;}\r\n  case 49:{const u=fract(x*6+(Math.floor(y*7)%2)*.5),v=fract(y*7),scale=Math.hypot((u-.5)*.86,v-.5),rim=1-smooth(.36,.48,scale),seam=1-smooth(.025,.09,Math.abs(v-.5));h=.28+.46*rim-.08*seam;t=.12+.74*rim-.12*seam;rough=.52-.24*rim;break;}\r\n  case 50:{const u=fract(x*14),v=fract(y*14),bar=Math.min(u,1-u,v,1-v),wire=1-smooth(.035,.105,bar),hole=1-wire;h=.26+.56*wire;t=.08+.76*wire;rough=.58-.2*wire;break;}\r\n  case 51:{const u=fract(x*18),v=fract(y*18),stagger=(Math.floor(y*18)%2)*.5,cx=fract(x*18+stagger)-.5,cy=v-.5,r=Math.hypot(cx,cy),loop=1-smooth(.035,.105,Math.abs(r-.27)),center=1-smooth(.01,.08,r);h=.44+.2*loop+.06*center;t=.34+.28*loop;rough=.99;break;}\r\n  case 52:{const c=voronoi(x*7,y*7),stone=1-smooth(.2,.52,c.near),edge=1-smooth(.035,.1,c.gap);h=.26+.49*stone-.1*edge;t=.1+.76*stone-.14*edge;rough=.87-.2*stone;break;}\r\n  case 53:{const q=y*7+Math.sin(x*17+y*4)*.35+Math.sin(x*6-y*13)*.16,ridge=1-smooth(.16,.34,Math.abs(fract(q)-.5));h=.39+.31*ridge+.025*g;t=.3+.38*ridge;rough=.99;break;}\r\n  case 54:{const c=voronoi(x*4,y*4),stone=1-smooth(.31,.75,c.near),seam=1-smooth(.045,.13,c.gap);h=.31+.43*stone-.16*seam;t=.15+.67*stone-.19*seam;rough=.79-.14*stone+.1*seam;break;}\r\n  case 55:{const c=voronoi(x*31,y*31),tuft=1-smooth(.08,.38,c.near),spore=hash(Math.floor(x*31),Math.floor(y*31))>.84?1:0;h=.37+.2*tuft+.07*spore;t=.2+.61*tuft+.12*spore;rough=.99;break;}\r\n }\r\n return{height:h,tint:clamp(t),glow,rough};\r\n}\r\n","creature/source/creator/material-refinement.ts":"import * as T from 'three';\r\nimport {mergeVertices} from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\n\r\nexport type CoachReliefBudget={remainingTriangles:number;usedTriangles:number;perMeshAddedTriangles:number;perMeshVertices:number};\r\n// Budgets count added triangles per coach, and total final positions per mesh.\r\nexport const createCoachReliefBudget=(limit=240_000,perMeshAddedTriangles=64_000,perMeshVertices=32_000):CoachReliefBudget=>({remainingTriangles:limit,usedTriangles:0,perMeshAddedTriangles,perMeshVertices});\r\nconst isFloat16=(a:{array:ArrayLike<number>;isFloat16BufferAttribute?:boolean})=>!!a.isFloat16BufferAttribute||(()=>{const Float16=(globalThis as any).Float16Array;return !!Float16&&a.array instanceof Float16;})();\r\n\r\nfunction component(a:T.BufferAttribute|T.InterleavedBufferAttribute,i:number,c:number){\r\n if(c===0)return a.getX(i);if(c===1)return a.getY(i);if(c===2)return a.getZ(i);if(c===3)return a.getW(i);\r\n return a.array[i*a.itemSize+c];\r\n}\r\nfunction write(a:T.BufferAttribute,i:number,c:number,v:number){\r\n if(c===0)a.setX(i,v);else if(c===1)a.setY(i,v);else if(c===2)a.setZ(i,v);else if(c===3)a.setW(i,v);else a.array[i*a.itemSize+c]=v;\r\n}\r\nfunction normalizeAttribute(a:T.BufferAttribute,i:number){\r\n if(a.itemSize<3)return;\r\n const x=a.getX(i),y=a.getY(i),z=a.getZ(i),length=Math.hypot(x,y,z);if(length<1e-12)return;\r\n a.setXYZ(i,x/length,y/length,z/length);\r\n}\r\n\r\n/** One linear triangle split. It preserves silhouette, UVs, authored normals and vertex attributes. */\r\nfunction split(source:T.BufferGeometry,maxVertices:number):T.BufferGeometry|undefined{\r\n const index=source.index;if(!index||index.count%3)return undefined;\r\n const edgeIds=new Map<string,number>(),edges:Array<[number,number]>=[],indices:number[]=[];\r\n const midpoint=(a:number,b:number)=>{\r\n  const lo=Math.min(a,b),hi=Math.max(a,b),key=lo+':'+hi,old=edgeIds.get(key);if(old!==undefined)return old;\r\n  const id=source.attributes.position.count+edges.length;edgeIds.set(key,id);edges.push([lo,hi]);return id;\r\n };\r\n const groups=source.groups.length?source.groups:[{start:0,count:index.count,materialIndex:0}],nextGroups:{start:number;count:number;materialIndex:number}[]=[];\r\n for(const group of groups){\r\n  const start=indices.length,end=Math.min(index.count,group.start+group.count);\r\n  for(let j=group.start;j+2<end;j+=3){const a=index.getX(j),b=index.getX(j+1),c=index.getX(j+2),ab=midpoint(a,b),bc=midpoint(b,c),ca=midpoint(c,a);\r\n   indices.push(a,ab,ca,ab,b,bc,ca,bc,c,ab,bc,ca);\r\n  }\r\n  if(indices.length>start)nextGroups.push({start,count:indices.length-start,materialIndex:group.materialIndex??0});\r\n }\r\n if(!edges.length||source.attributes.position.count+edges.length>maxVertices)return undefined;\r\n const out=source.clone();\r\n for(const [name,attribute]of Object.entries(source.attributes)){\r\n  if((attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||isFloat16(attribute))return undefined;\r\n  const count=attribute.count+edges.length,array=new (attribute.array.constructor as any)(count*attribute.itemSize);array.set(attribute.array);\r\n  const target=new T.BufferAttribute(array,attribute.itemSize,attribute.normalized);target.name=attribute.name;target.setUsage((attribute as T.BufferAttribute).usage);target.gpuType=(attribute as T.BufferAttribute).gpuType;\r\n  for(let e=0;e<edges.length;e++){const [a,b]=edges[e],dst=attribute.count+e;\r\n   for(let c=0;c<attribute.itemSize;c++)write(target,dst,c,(component(attribute,a,c)+component(attribute,b,c))*.5);\r\n   if(name==='normal'||name==='tangent')normalizeAttribute(target,dst);\r\n  }\r\n  out.setAttribute(name,target);\r\n }\r\n out.setIndex(indices);out.clearGroups();for(const group of nextGroups)out.addGroup(group.start,group.count,group.materialIndex);\r\n out.morphAttributes=source.morphAttributes;out.morphTargetsRelative=source.morphTargetsRelative;out.userData={...source.userData};\r\n return out;\r\n}\r\n\r\n/** Refine only bounded static roster geometry; unknown animated/morph geometry safely stays untouched. */\r\nexport function refineCoachGeometry(source:T.BufferGeometry,budget:CoachReliefBudget,worldScale=1):{geometry:T.BufferGeometry;addedTriangles:number;addedVertices:number;levels:number}|undefined{\r\n if(!budget||budget.remainingTriangles<=0||Object.values(source.morphAttributes).some(attributes=>attributes.length)||source.attributes.skinIndex||source.attributes.skinWeight)return undefined;\r\n if(source.drawRange.start!==0||(source.index&&source.drawRange.count<source.index.count))return undefined;\r\n for(const attribute of Object.values(source.attributes))if((attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||isFloat16(attribute))return undefined;\r\n let working=source.clone();\r\n if(!working.index){const merged=mergeVertices(working);working.dispose();working=merged;}\r\n if(!working.index||working.index.count%3){working.dispose();return undefined;}\r\n if(!working.attributes.normal)working.computeVertexNormals();\r\n const triangles=working.index.count/3;\r\n // Estimate a 90th-percentile edge so tiny existing triangles stay untouched while broad facets\r\n // receive enough linear splits to reach roughly .025 world units. The total remains tightly capped.\r\n if(triangles>10_000){working.dispose();return undefined;}\r\n const positions=working.attributes.position,edges:number[]=[];for(let j=0;j<working.index.count;j+=3){const a=working.index.getX(j),b=working.index.getX(j+1),c=working.index.getX(j+2);for(const [u,v]of [[a,b],[b,c],[c,a]])edges.push(Math.hypot(positions.getX(u)-positions.getX(v),positions.getY(u)-positions.getY(v),positions.getZ(u)-positions.getZ(v))*worldScale);}\r\n edges.sort((a,b)=>a-b);const p90=edges[Math.floor((edges.length-1)*.9)]??0,desired=Math.min(5,Math.max(0,Math.ceil(Math.log2(p90/.025))));\r\n if(!desired){working.dispose();return undefined;}\r\n const initial=working.attributes.position.count,initialTriangles=triangles;let levels=0;\r\n for(let level=0;level<desired;level++){\r\n  const currentTriangles=working.index!.count/3,nextTriangles=currentTriangles*4,cumulativeAdded=nextTriangles-initialTriangles;\r\n  if(cumulativeAdded>budget.remainingTriangles||cumulativeAdded>budget.perMeshAddedTriangles||nextTriangles>64_000)break;\r\n  const next=split(working,budget.perMeshVertices);if(!next)break;\r\n  working.dispose();working=next;levels++;\r\n }\r\n const addedTriangles=working.index!.count/3-initialTriangles,addedVertices=working.attributes.position.count-initial;\r\n if(!levels){working.dispose();return undefined;}\r\n budget.remainingTriangles-=addedTriangles;budget.usedTriangles+=addedTriangles;\r\n working.userData={...working.userData,coachRelief:{addedTriangles,addedVertices,levels,originalVertices:initial}};\r\n return {geometry:working,addedTriangles,addedVertices,levels};\r\n}\r\n\r\n/** Optional alternate-coach quality path for the original imported material (no recolouring). */\r\nexport function refineCoachMesh(mesh:T.Mesh,budget:CoachReliefBudget){\r\n if(Array.isArray(mesh.material)||(mesh as T.SkinnedMesh).isSkinnedMesh||mesh.geometry.attributes.skinIndex||mesh.geometry.attributes.skinWeight||Object.values(mesh.geometry.morphAttributes).some(attributes=>attributes.length))return undefined;\r\n mesh.updateWorldMatrix(true,false);const result=refineCoachGeometry(mesh.geometry,budget,mesh.matrixWorld.getMaxScaleOnAxis());if(!result)return undefined;\r\n const previous=mesh.geometry;mesh.geometry=result.geometry;if(mesh.userData.ownedGeometry)previous.dispose();mesh.userData.ownedGeometry=true;\r\n return {addedTriangles:result.addedTriangles,addedVertices:result.addedVertices,levels:result.levels};\r\n}\r\n","creature/source/creator/materials-registry.ts":"// Rank 4 runtime material registry: textures, colours and palettes.\r\n// Adding a texture/colour/palette is a new entry (+ files for battle-pass packs) here —\r\n// no other code changes. See plan/PLAN.md \"Rank 4\" and plan/reports/audit-materials.md.\r\nimport {STYLES as LEGACY_STYLES, COLOUR_SOURCE, type MaterialChoice, type Region} from './design';\r\nimport {isGranted, type UnlockKind,migrateSavedCosmetics} from './unlock-store';\r\nimport {isGranted as ledgerGranted} from '../../../unlock-ledger.mjs';\r\nimport {currentCosmeticCoach,cosmeticId} from './unlock-store';\r\nimport PALETTE_DATA from './palettes.json';\r\nimport {TEXTURE_SWAP,FREE_COLOURS} from '../../../battle-pass-rewards.mjs';\r\nimport {FREE_TEXTURE_IDS,RETIRED_TEXTURE_IDS} from './texture-policy.mjs';\r\nimport {RECIPE_KEY} from '../profile';\r\nimport {builtinSurfaceProfile} from './material-patterns';\r\nexport {grantUnlock} from './unlock-store';\r\nexport {FREE_COLOURS};\r\n\r\nexport type UnlockRule = 'default' | 'battle-pass' | 'aura-milestone';\r\nexport type Track = 'chest' | 'quads' | 'glutes' | 'arms' | 'yoga' | 'martial-arts' | 'cardio' | 'meditation';\r\n\r\nexport type TextureDef = {\r\n id: string; displayName: string; unlockRule: UnlockRule;\r\n track?: Track; passLevel?: 1 | 3 | 5; packId?: string; legacy?: boolean;\r\n familyId: number;        // feeds surfaceSample()'s procedural pattern switch in material-language.ts\r\n defaultColorId: string;  // colour used until the player chooses another\r\n};\r\nexport type ColorDef = { id: string; displayName: string; unlockRule: UnlockRule; primary: string; secondary: string; accent: string; packId?: string };\r\n// D32: a palette is a primary/secondary/accent triad (the same roles the tint uses). Aura\r\n// palettes carry unlockAtDay; battle-pass palettes carry `reward` = the slot that grants them\r\n// ('<bossId>:L<n>' or 'food:L<n>', read by battle-pass-rewards.mjs).\r\nexport type PaletteDef = { id: string; displayName: string; tagline: string; unlockRule: UnlockRule; unlockAtDay?: number; reward?: string; colors: [string, string, string]; finish?: 'matte' | 'brushed-metal' | 'polished-metal' | 'glitter' | 'pearl' | 'watercolor' | 'marbled' | 'glaze' };\r\n\r\nconst isUnlocked = (kind: UnlockKind, item: { id: string; unlockRule: UnlockRule },coachId?:string) => item.unlockRule === 'default' || isGranted(kind, item.id,typeof coachId==='string'?coachId:undefined);\r\n// R18 G2: a single-colour def is free exactly when its primary is one of the 15 free hexes (battle-pass-rewards.mjs FREE_COLOURS).\r\nconst colourRule = (c: { primary: string }): UnlockRule => FREE_COLOURS.includes(c.primary.toLowerCase()) ? 'default' : 'battle-pass';\r\nexport const hasCoach64BitSkin = (coachId=currentCosmeticCoach()) => ledgerGranted('boss-skin',cosmeticId(typeof coachId==='string'?coachId:currentCosmeticCoach(),`${typeof coachId==='string'?coachId:currentCosmeticCoach()}-skin`));\r\nexport const isTextureUnlocked = (t: TextureDef,coachId?:string) => !RETIRED_TEXTURE_IDS.includes(t.id)\r\n && (FREE_TEXTURE_IDS.includes(t.id) || isGranted('texture',t.id,coachId))\r\n && (t.id!=='coach-64-bit' || hasCoach64BitSkin(coachId));\r\nexport const isColorUnlocked = (c: ColorDef,coachId?:string) => isUnlocked('color', c,coachId);\r\nexport const isPaletteUnlocked = (p: PaletteDef,coachId?:string) => isUnlocked('palette', p,coachId);\r\n\r\n// Clay remains the safe starter finish. Flat survives only as an internal legacy profile.\r\n// familyId 30/31 have matching cases added to surfaceSample() in material-language.ts.\r\nconst FLAT_BASE = { id: 30, name: 'Flat', realm: '', primary: '#c7c3ce', secondary: '#6d6a75', accent: '#ffffff', emissive: '#000000', roughness: .55, metalness: 0, detail: 'flat' } as const;\r\nconst CLAY_BASE = { id: 31, name: 'Clay', realm: '', primary: '#b7a68e', secondary: '#7a6b57', accent: '#ddcdb3', emissive: '#000000', roughness: .92, metalness: 0, detail: 'clay' } as const;\r\nexport const FLAT_TEXTURE: TextureDef = { id: 'flat', displayName: 'Flat', unlockRule: 'battle-pass', familyId: FLAT_BASE.id, defaultColorId: '#7f7d78' };\r\nconst CLAY_TEXTURE: TextureDef = { id: 'clay', displayName: 'Clay', unlockRule: 'default', familyId: CLAY_BASE.id, defaultColorId: '#c4a77d' };\r\n\r\n// --- The 22 (well, 23: 0-22) existing procedural surface families keep working exactly as\r\n// before for legacy `styles` recipes, and are also exposed as ordinary registry textures +\r\n// their historical colour, `legacy:true`, unlockRule 'default' -- except the 7 that #140 moved\r\n// into the battle pass (LEGACY_TEXTURES, below the battle-pass table they take slots from). ---\r\nconst LEGACY_COLORS: ColorDef[] = LEGACY_STYLES.map(s => ({ id: 'legacy-color-' + s.id, displayName: s.name + ' (original)', unlockRule: colourRule(s), primary: s.primary, secondary: s.secondary, accent: s.accent }));\r\n\r\n// --- Simple default colours: \"basic colours auto\" (audit M7). Any of these tints any texture. ---\r\nconst SIMPLE_COLORS: ColorDef[] = ([\r\n { id: 'default-slate', displayName: 'Slate', unlockRule: 'default', primary: '#8b8f9a', secondary: '#4a4d55', accent: '#e7e9ee' },\r\n { id: 'default-clay', displayName: 'Warm Clay', unlockRule: 'default', primary: '#b7a68e', secondary: '#7a6b57', accent: '#ddcdb3' },\r\n { id: 'default-ruby', displayName: 'Ruby', unlockRule: 'default', primary: '#a23b4a', secondary: '#4f1620', accent: '#f2a3ae' },\r\n { id: 'default-sapphire', displayName: 'Sapphire', unlockRule: 'default', primary: '#2d5aa0', secondary: '#122a4d', accent: '#a9c9f5' },\r\n { id: 'default-moss', displayName: 'Moss', unlockRule: 'default', primary: '#4c7a3f', secondary: '#20351a', accent: '#c3e6a8' },\r\n { id: 'default-gold', displayName: 'Gold', unlockRule: 'default', primary: '#c9a13a', secondary: '#5f4a15', accent: '#ffe9a8' },\r\n { id: 'default-charcoal', displayName: 'Charcoal', unlockRule: 'default', primary: '#333238', secondary: '#131318', accent: '#8d8d96' },\r\n { id: 'default-blush', displayName: 'Blush', unlockRule: 'default', primary: '#d98fa0', secondary: '#7a3d49', accent: '#ffdbe4' },\r\n] as ColorDef[]).map(c => ({ ...c, unlockRule: colourRule(c) }));\r\n\r\n// --- Battle-pass textures: PLAN §6.2 / plan/muse/item-catalog.json (D14: 3 per style, D16: L1/L3/L5).\r\n// Every catalogue option below has a stable built-in procedural pattern and PBR profile.\r\n// Built-in surfaces render locally; unlock policy remains independent from pattern availability. ---\r\nconst SLOT_LEVEL: Record<string, 1 | 3 | 5> = { 'texture-1': 1, 'texture-2': 3, 'texture-3': 5 };\r\nconst BATTLE_PASS_SOURCE: { id: string; name: string; slot: string; track: string; familyId:number }[] = [\r\n { id: 'chest-plate-steel', name: 'Plate Steel', slot: 'texture-1', track: 'chest',familyId:32 },\r\n { id: 'chest-rubber-grip', name: 'Rubber Grip', slot: 'texture-2', track: 'chest',familyId:33 },\r\n { id: 'chest-chain-mail', name: 'Chain Mail', slot: 'texture-3', track: 'chest',familyId:34 },\r\n { id: 'quads-track-rubber', name: 'Track Rubber', slot: 'texture-1', track: 'quads',familyId:35 },\r\n { id: 'quads-denim', name: 'Denim', slot: 'texture-2', track: 'quads',familyId:36 },\r\n { id: 'quads-hex-tread', name: 'Hex Tread', slot: 'texture-3', track: 'quads',familyId:37 },\r\n { id: 'glutes-sweatshirt-fleece', name: 'Sweatshirt Fleece', slot: 'texture-1', track: 'glutes',familyId:38 },\r\n { id: 'glutes-quilted', name: 'Quilted', slot: 'texture-2', track: 'glutes',familyId:39 },\r\n { id: 'glutes-peach', name: 'Speckled', slot: 'texture-3', track: 'glutes',familyId:40 },\r\n { id: 'arms-hammered-bronze', name: 'Hammered Bronze', slot: 'texture-1', track: 'arms',familyId:41 },\r\n { id: 'arms-rope', name: 'Fine Stripe', slot: 'texture-2', track: 'arms',familyId:42 },\r\n { id: 'arms-leather', name: 'Snake Skin', slot: 'texture-3', track: 'arms',familyId:43 },\r\n { id: 'yoga-cork', name: 'Holey', slot: 'texture-1', track: 'yoga',familyId:44 },\r\n { id: 'yoga-woven-mat', name: 'Woven Mat', slot: 'texture-2', track: 'yoga',familyId:45 },\r\n { id: 'yoga-petal', name: 'Petal', slot: 'texture-3', track: 'yoga',familyId:46 },\r\n { id: 'martial-arts-canvas-gi', name: 'Graph Paper', slot: 'texture-1', track: 'martial-arts',familyId:47 },\r\n { id: 'martial-arts-bamboo', name: 'Bamboo', slot: 'texture-2', track: 'martial-arts',familyId:48 },\r\n { id: 'martial-arts-dragon-scale', name: 'Dragon Scale', slot: 'texture-3', track: 'martial-arts',familyId:49 },\r\n { id: 'cardio-mesh', name: 'Cool Graph Paper', slot: 'texture-1', track: 'cardio',familyId:50 },\r\n { id: 'cardio-terry-cloth', name: 'Terry Cloth', slot: 'texture-2', track: 'cardio',familyId:51 },\r\n { id: 'cardio-pebble-path', name: 'Pebble Path', slot: 'texture-3', track: 'cardio',familyId:52 },\r\n { id: 'meditation-sand-garden', name: 'Wiggles', slot: 'texture-1', track: 'meditation',familyId:53 },\r\n { id: 'meditation-river-stone', name: 'River Stone', slot: 'texture-2', track: 'meditation',familyId:54 },\r\n { id: 'meditation-moss', name: 'Moss', slot: 'texture-3', track: 'meditation',familyId:55 },\r\n];\r\n// R18 G1: only FREE_TEXTURE_IDS (texture-policy.mjs) are free; TEXTURE_SWAP now just names which legacy\r\n// texture sits in a battle-pass slot (and drives the #140 grandfather below), it never unlocks anything.\r\nconst SWAPPED_IN = new Map<string, string>(Object.entries(TEXTURE_SWAP).map(([freed, [legacyId]]) => [legacyId as string, freed]));\r\nconst textureRule = (id: string): UnlockRule => FREE_TEXTURE_IDS.includes(id) ? 'default' : 'battle-pass';\r\nconst BATTLE_PASS_TEXTURES: TextureDef[] = BATTLE_PASS_SOURCE.map(t => ({ id: t.id, displayName: t.name, unlockRule: textureRule(t.id), track: t.track as Track, passLevel: SLOT_LEVEL[t.slot], packId: 'pack-' + t.track, familyId: t.familyId, defaultColorId: '#7f7d78' }));\r\nconst LEGACY_TEXTURES: TextureDef[] = LEGACY_STYLES.map(s => {\r\n const id = 'legacy-' + s.id, slot = BATTLE_PASS_TEXTURES.find(t => t.id === SWAPPED_IN.get(id));\r\n return { id, displayName: s.name, unlockRule: textureRule(id), track: slot?.track, passLevel: slot?.passLevel, legacy: true, familyId: s.id, defaultColorId: 'legacy-color-' + s.id };\r\n});\r\n\r\nexport const COACH_64_BIT_TEXTURE:TextureDef={id:'coach-64-bit',displayName:'64-bit Pixel Finish',unlockRule:'battle-pass',familyId:56,defaultColorId:'#7f7d78'};\r\nexport const SPECIAL_TEXTURES:TextureDef[]=[{id:'opal-jelly',displayName:'Opal Jelly',unlockRule:'battle-pass',familyId:57,defaultColorId:'opal-jelly'},{id:'bubble-glass',displayName:'Bubble Glass',unlockRule:'battle-pass',familyId:58,defaultColorId:'bubble-glass'},{id:'prism-crystal',displayName:'Prism Crystal',unlockRule:'battle-pass',familyId:59,defaultColorId:'prism-crystal'},{id:'holo-foil',displayName:'Holographic Foil',unlockRule:'battle-pass',familyId:60,defaultColorId:'holo-foil'},{id:'glitter-resin',displayName:'Glitter Resin',unlockRule:'battle-pass',familyId:61,defaultColorId:'glitter-resin'},{id:'galaxy-geode',displayName:'Galaxy Geode',unlockRule:'battle-pass',familyId:62,defaultColorId:'galaxy-geode'},{id:'caustic-slime',displayName:'Caustic Slime',unlockRule:'battle-pass',familyId:63,defaultColorId:'caustic-slime'},{id:'blister-hide',displayName:'Blister Hide',unlockRule:'battle-pass',familyId:64,defaultColorId:'blister-hide'},{id:'rotten-rind',displayName:'Rotten Rind',unlockRule:'battle-pass',familyId:65,defaultColorId:'rotten-rind'},{id:'parasite-nest',displayName:'Parasite Nest',unlockRule:'battle-pass',familyId:66,defaultColorId:'parasite-nest'},{id:'exposed-sinew',displayName:'Exposed Sinew',unlockRule:'battle-pass',familyId:67,defaultColorId:'exposed-sinew'},{id:'abyssal-maw',displayName:'Abyssal Maw',unlockRule:'battle-pass',familyId:68,defaultColorId:'abyssal-maw'},{id:'circuit-alloy',displayName:'Circuit Alloy',unlockRule:'battle-pass',familyId:69,defaultColorId:'circuit-alloy'},{id:'servo-armor',displayName:'Servo Armor',unlockRule:'battle-pass',familyId:70,defaultColorId:'servo-armor'},{id:'chrome-rib',displayName:'Chrome Rib',unlockRule:'battle-pass',familyId:71,defaultColorId:'chrome-rib'},{id:'carbon-mech',displayName:'Carbon Mech',unlockRule:'battle-pass',familyId:72,defaultColorId:'carbon-mech'},{id:'hazard-panel',displayName:'Hazard Panel',unlockRule:'battle-pass',familyId:73,defaultColorId:'hazard-panel'},{id:'reactor-glass',displayName:'Reactor Glass',unlockRule:'battle-pass',familyId:74,defaultColorId:'reactor-glass'}].filter(t=>!RETIRED_TEXTURE_IDS.includes(t.id));\r\nexport const TEXTURES: TextureDef[] = [...SPECIAL_TEXTURES,CLAY_TEXTURE, ...LEGACY_TEXTURES, ...BATTLE_PASS_TEXTURES,COACH_64_BIT_TEXTURE].filter(t=>!RETIRED_TEXTURE_IDS.includes(t.id));\r\nexport const COLORS: ColorDef[] = [...SIMPLE_COLORS, ...LEGACY_COLORS];\r\n\r\n// --- Palettes: palettes.json next to this file (plan/muse/palettes.json cut to triads, plus the\r\n// D32 battle-pass fill). Adding a palette is a new row there. ---\r\nexport const PALETTES: PaletteDef[] = PALETTE_DATA.map(({ name, ...p }) => ({ ...p, displayName: name }) as PaletteDef);\r\n\r\nexport const findTexture = (id: string) => TEXTURES.find(t => t.id === id);\r\nexport const findColor = (id: string) => COLORS.find(c => c.id === id);\r\nexport const findPalette = (id: string) => PALETTES.find(p => p.id === id);\r\nexport function textureDefaultMetalness(id:string):number|undefined {\r\n const texture=findTexture(id);if(!texture)return undefined;\r\n return builtinSurfaceProfile(texture.familyId)?.metalness??(texture.legacy?LEGACY_STYLES[texture.familyId]?.metalness:texture.id==='clay'?CLAY_BASE.metalness:FLAT_BASE.metalness);\r\n}\r\n\r\nfunction triadFromPalette(p: PaletteDef) { const [primary, secondary, accent] = p.colors; return { primary, secondary, accent, paletteId:p.id }; }\r\n\r\n// R18 G2/G3: a colour channel holds ONE colour. A \"#rrggbb\" colorId is a single hex: free if it is one of\r\n// the 15 FREE_COLOURS, otherwise owned when any owned colour or palette contains it (so unlocking a\r\n// palette gives you its three hexes for the Body/Head/Eyes rows). Existing ids (default-ruby, pal-03, ...) still work.\r\nconst HEX = /^#[0-9a-f]{6}$/i;\r\nconst mix = (hex: string, to: number, t: number) => '#' + [1, 3, 5].map(i => Math.round(parseInt(hex.slice(i, i + 2), 16) * (1 - t) + to * t).toString(16).padStart(2, '0')).join('');\r\nconst hexOwned = (hex: string,coachId?:string) => FREE_COLOURS.includes(hex) || COLORS.some(c => isColorUnlocked(c,coachId) && [c.primary, c.secondary, c.accent].some(h => h.toLowerCase() === hex)) || PALETTES.some(p => isPaletteUnlocked(p,coachId) && p.colors.some(h => h.toLowerCase() === hex));\r\n/** The tint triad for a colour, hex or palette id, or undefined if it doesn't exist or isn't unlocked yet\r\n * (`preview` paints a locked one too — the editor's look-before-you-unlock layer, never saved). */\r\nexport function colorTriad(id: string, preview = false,coachId?:string): { primary: string; secondary: string; accent: string; paletteId?:string } | undefined {\r\n if (HEX.test(id)) { const hex = id.toLowerCase(); return preview || hexOwned(hex,coachId) ? { primary: hex, secondary: mix(hex, 0, .55), accent: mix(hex, 255, .55) } : undefined; }\r\n const c = findColor(id); if (c) return preview || isColorUnlocked(c,coachId) ? { primary: c.primary, secondary: c.secondary, accent: c.accent } : undefined;\r\n const p = findPalette(id); if (p) return preview || isPaletteUnlocked(p,coachId) ? triadFromPalette(p) : undefined;\r\n return undefined;\r\n}\r\n\r\n/** True when a texture/colour/palette id is a registry item the player doesn't own yet (the UI shows just a lock).\r\n * Installed creature skins and unknown ids guard themselves and are never \"locked\" here. */\r\nexport function isLocked(id: string,coachId?:string,kind?:'texture'|'color'): boolean {\r\n if(kind==='color'){\r\n  if(HEX.test(id))return !hexOwned(id.toLowerCase(),coachId);\r\n  const c=findColor(id);if(c)return !isColorUnlocked(c,coachId);\r\n  const p=findPalette(id);return p?!isPaletteUnlocked(p,coachId):false;\r\n }\r\n if(RETIRED_TEXTURE_IDS.includes(id))return true;\r\n const t = findTexture(id); if (t) return !isTextureUnlocked(t,coachId);\r\n if (HEX.test(id)) return !hexOwned(id.toLowerCase(),coachId);\r\n const c = findColor(id); if (c) return !isColorUnlocked(c,coachId);\r\n const p = findPalette(id); if (p) return !isPaletteUnlocked(p,coachId);\r\n return false;\r\n}\r\n\r\n// A saved recipe alone is not proof of a pack grant. Only migrate IDs that were\r\n// explicitly earned in the historical unlock store; all other non-free finishes\r\n// remain preview-only and fall back to Clay when rendered or saved.\r\nexport function migrateEarnedTextureUnlocks(recipe?: { body?:string;materials?: Record<string, { textureId?: string } | undefined> } | null) {\r\n try {\r\n  if (!recipe) return;\r\n  migrateSavedCosmetics(recipe);\r\n } catch { /* no storage or unreadable recipe: nothing to keep */ }\r\n}\r\ntry { const raw = localStorage.getItem(RECIPE_KEY); if (raw) migrateEarnedTextureUnlocks(JSON.parse(raw)); } catch { /* no storage */ }\r\nglobalThis.addEventListener?.('myr5:recipe', event => migrateEarnedTextureUnlocks((event as CustomEvent).detail));\r\n\r\n/**\r\n * The single seam between the old `styles[region]` numeric recipe and the new decoupled\r\n * texture+colour+sparkle+metallic recipe. Called once per region in assemble.ts.\r\n * No `choice` (old recipes, or a region nobody has re-customized) -> renders byte-for-byte\r\n * like today's STYLES[legacyIndex]. A `choice` resolves texture+colour independently and\r\n * always falls back to Flat/its default colour rather than ever throwing or loading nothing.\r\n * `preview` lets a locked texture/colour paint (editor preview only; save-look.ts guards saves).\r\n */\r\n/** G3: the material choice a region really renders with. Body colour drives body, arms, feet, collar and (R25)\r\n * the head; eyes have their own. An old save's separate head colour is ignored. */\r\nexport function regionChoice(materials: Partial<Record<Region, MaterialChoice>> | undefined, region: Region): MaterialChoice | undefined {\r\n const own = materials?.[region], source = materials?.[COLOUR_SOURCE[region]];\r\n return own && source && source !== own ? { ...own, colorId: source.colorId } : own;\r\n}\r\n\r\nexport function resolveRegionMaterial(legacyIndex: number, choice?: MaterialChoice, preview = false,coachId?:string) {\r\n if (!choice) return { ...LEGACY_STYLES[legacyIndex], sparkle: 0, paletteId:undefined as string|undefined };\r\n const texture = findTexture(choice.textureId);\r\n const safeTexture = texture && (preview || isTextureUnlocked(texture,coachId)) && texture.familyId >= 0 ? texture : CLAY_TEXTURE;\r\n const profile=builtinSurfaceProfile(safeTexture.familyId);\r\n const base = safeTexture.legacy ? LEGACY_STYLES[safeTexture.familyId] : safeTexture.id === 'clay' ? CLAY_BASE : profile ? {id:profile.id,name:profile.name,realm:'',primary:'#8b8f9a',secondary:'#4a4d55',accent:'#e7e9ee',emissive:'#000000',roughness:profile.roughness,metalness:profile.metalness,detail:profile.name.toLowerCase().replace(/[^a-z0-9]+/g,'-')} : CLAY_BASE;\r\n const triad = colorTriad(choice.colorId, preview,coachId) ?? colorTriad(safeTexture.defaultColorId, preview,coachId) ?? base;\r\n const metalness = Number.isFinite(choice.metallic) ? Math.max(0, Math.min(1, choice.metallic)) : base.metalness;\r\n const sparkle = Number.isFinite(choice.sparkle) ? Math.max(0, Math.min(1, choice.sparkle)) : 0;\r\n return { ...base, ...triad, paletteId:'paletteId' in triad?triad.paletteId:undefined, metalness, sparkle };\r\n}\r\n","creature/source/creator/palette-finishes.ts":"import * as THREE from 'three';\r\nimport palettesData from './palettes.json';\r\n\r\nexport type FinishKind =\r\n  | 'matte' | 'brushed-metal' | 'polished-metal' | 'glitter'\r\n  | 'pearl' | 'watercolor' | 'marbled' | 'glaze';\r\n\r\nexport const FINISH_ID: Record<FinishKind, number> = {\r\n  matte: 0,\r\n  'brushed-metal': 1,\r\n  'polished-metal': 2,\r\n  glitter: 3,\r\n  pearl: 4,\r\n  watercolor: 6,\r\n  marbled: 7,\r\n  glaze: 8,\r\n};\r\n\r\nconst KINDS = new Set<string>(Object.keys(FINISH_ID));\r\ntype PaletteMeta = { id: string; finish?: unknown; colors: string[] };\r\nconst CATALOG = new Map<string, PaletteMeta>(palettesData.map(p => [p.id,p]));\r\n\r\nfunction meta(id?: string): (PaletteMeta & { finish: FinishKind }) | undefined {\r\n  if (!id) return undefined;\r\n  const p = CATALOG.get(id);\r\n  return p && typeof p.finish === 'string' && KINDS.has(p.finish) ? p as PaletteMeta & {finish: FinishKind} : undefined;\r\n}\r\n\r\nexport function paletteFinish(paletteId?: string): FinishKind | undefined {\r\n  return meta(paletteId)?.finish;\r\n}\r\nexport function isCatalogPalette(paletteId?: string): boolean {\r\n  return !!meta(paletteId);\r\n}\r\n\r\nexport const FINISH_LABELS: Record<FinishKind, string> = {\r\n  matte: 'Matte', 'brushed-metal': 'Brushed metal', 'polished-metal': 'Polished metal',\r\n  glitter: 'Glitter', pearl: 'Pearl', watercolor: 'Watercolor', marbled: 'Marbled', glaze: 'Glaze',\r\n};\r\nexport function finishLabel(id?: string): string {\r\n  const f = paletteFinish(id);\r\n  return f ? FINISH_LABELS[f] : '';\r\n}\r\n\r\nexport function finishSwatchCSS(id?: string): string {\r\n  const p = meta(id); if (!p) return '';\r\n  const [a,b,c] = p.colors;\r\n  switch (p.finish) {\r\n    case 'matte': return '';\r\n    case 'brushed-metal': return `repeating-linear-gradient(100deg,${a} 0 2px,${b} 2px 3px,${c} 3px 5px)`;\r\n    case 'polished-metal': return `linear-gradient(115deg,${a},${c} 38%,#fff 50%,${b} 64%,${a})`;\r\n    case 'glitter': return `radial-gradient(circle at 22% 28%,#fff 0 2%,transparent 3%),radial-gradient(circle at 68% 62%,${c} 0 2%,transparent 3%),linear-gradient(135deg,${a},${b})`;\r\n    case 'pearl': return `linear-gradient(120deg,${a},#fff 36%,${b} 58%,${c})`;\r\n    case 'watercolor': return `radial-gradient(circle at 28% 34%,${a} 0 28%,transparent 55%),radial-gradient(circle at 72% 66%,${c} 0 24%,transparent 58%),linear-gradient(${b},${b})`;\r\n    case 'marbled': return `repeating-linear-gradient(128deg,${a} 0 9px,${b} 10px 17px,${c} 18px 23px)`;\r\n    case 'glaze': return `linear-gradient(160deg,rgba(255,255,255,.72),transparent 34%),linear-gradient(135deg,${a},${b},${c})`;\r\n  }\r\n}\r\n\r\nconst TAU = Math.PI * 2;\r\nconst wrap = (x: number) => x - Math.floor(x);\r\nfunction flatField(u: number, v: number): number {\r\n  u = wrap(u); v = wrap(v);\r\n  const s = 0.5 + 0.5 * Math.sin(TAU * u + 0.9 * Math.sin(TAU * v))\r\n    * Math.cos(TAU * v - 0.7 * Math.sin(TAU * u));\r\n  return wrap(s + 0.22 * Math.sin(TAU * (u - v)));\r\n}\r\nexport function samplePaletteTint(paletteId: string | undefined, tint: number, u: number, v: number, flat = false): number {\r\n  const f = paletteFinish(paletteId);\r\n  if (!f) return tint;\r\n  let t = THREE.MathUtils.clamp(tint, 0, 1);\r\n  u = wrap(u); v = wrap(v);\r\n  if (flat && f !== 'watercolor' && f !== 'marbled') return THREE.MathUtils.clamp(0.72 * flatField(u, v) + 0.28 * t, 0, 1);\r\n  if (f === 'watercolor') {\r\n    const bloom = 0.5 + 0.32 * Math.sin(TAU * u + 1.7 * Math.sin(TAU * v)) + 0.18 * Math.sin(TAU * (2 * u + v) + 0.6);\r\n    const grain = 0.03 * Math.sin(TAU * (9 * u + 5 * v));\r\n    return THREE.MathUtils.clamp(0.84 * bloom + 0.16 * t + grain, 0, 1);\r\n  }\r\n  if (f === 'marbled') {\r\n    const swirl = 0.5 + 0.48 * Math.sin(TAU * (u + 0.35 * Math.sin(TAU * (v + 0.5 * u))) + TAU * v);\r\n    return THREE.MathUtils.clamp(0.86 * swirl + 0.14 * t, 0, 1);\r\n  }\r\n  return t;\r\n}\r\n\r\nexport const FINISH_TINT_GLSL = `\r\nfloat myr5FlatPaletteTint(vec2 uv) {\r\n  uv = fract(uv);\r\n  float s = 0.5 + 0.5 * sin(6.2831853 * uv.x + 0.9 * sin(6.2831853 * uv.y))\r\n    * cos(6.2831853 * uv.y - 0.7 * sin(6.2831853 * uv.x));\r\n  return clamp(0.72 * fract(s + 0.22 * sin(6.2831853 * (uv.x - uv.y))) + 0.14, 0.0, 1.0);\r\n}\r\nfloat myr5FinishTint(float finish, float t, vec2 uv) {\r\n  t = clamp(t, 0.0, 1.0); uv = fract(uv);\r\n  if (finish == 6.0) {\r\n    float bloom = 0.5 + 0.32 * sin(6.2831853 * uv.x + 1.7 * sin(6.2831853 * uv.y))\r\n      + 0.18 * sin(6.2831853 * (2.0 * uv.x + uv.y) + 0.6);\r\n    float grain = 0.03 * sin(6.2831853 * (9.0 * uv.x + 5.0 * uv.y));\r\n    return clamp(0.84 * bloom + 0.16 * t + grain, 0.0, 1.0);\r\n  }\r\n  if (finish == 7.0) {\r\n    float swirl = 0.5 + 0.48 * sin(6.2831853 * (uv.x + 0.35 * sin(6.2831853 * (uv.y + 0.5 * uv.x))) + 6.2831853 * uv.y);\r\n    return clamp(0.86 * swirl + 0.14 * t, 0.0, 1.0);\r\n  }\r\n  return t;\r\n}\r\n`;\r\n\r\ntype Hooked = MeshPhysicalMaterialWithHooks;\r\ntype MeshPhysicalMaterialWithHooks = THREE.MeshPhysicalMaterial & {\r\n  userData: Record<string, any>;\r\n  defines?: Record<string,string>;\r\n};\r\n\r\nfunction addHook(mat: Hooked, kind: 'glitter' | 'brushed-metal'): void {\r\n  mat.userData.__myr5FinishHooks ||= {};\r\n  const hooks = mat.userData.__myr5FinishHooks as Record<string, boolean>;\r\n  if (hooks[kind]) return;\r\n  hooks[kind] = true;\r\n  if (kind === 'glitter') mat.userData.myr5FinishGlitter = true;\r\n  mat.defines={...mat.defines,USE_UV:''};\r\n  const prev = mat.onBeforeCompile?.bind(mat);\r\n  const vary = kind === 'glitter' ? 'vMyr5GlitterUv' : 'vMyr5BrushedUv';\r\n  mat.onBeforeCompile = (shader, renderer) => {\r\n    prev?.(shader, renderer);\r\n    shader.vertexShader = shader.vertexShader\r\n      .replace('#include <common>', `#include <common>\\nvarying vec2 ${vary};`)\r\n      .replace('#include <uv_vertex>', `#include <uv_vertex>\\n${vary} = uv;`);\r\n    shader.fragmentShader = shader.fragmentShader.replace(\r\n      '#include <common>',\r\n      `#include <common>\\nvarying vec2 ${vary};`\r\n    );\r\n    if (kind === 'glitter') {\r\n      shader.fragmentShader = shader.fragmentShader.replace(\r\n        '#include <roughnessmap_fragment>',\r\n        `#include <roughnessmap_fragment>\r\n        {\r\n          vec2 gu = fract(${vary} * 83.0);\r\n          float g = fract(sin(dot(floor(${vary} * 83.0), vec2(12.9898, 78.233))) * 43758.5453);\r\n          float speck = step(0.92, g) * step(0.5, smoothstep(0.0, 0.08, min(gu.x, gu.y)));\r\n          roughnessFactor = mix(roughnessFactor,0.055,speck);\r\n        }`\r\n      );\r\n      shader.fragmentShader = shader.fragmentShader.replace('#include <dithering_fragment>', `{\r\n        float grain=fract(sin(dot(floor(vMyr5GlitterUv*83.0),vec2(12.9898,78.233)))*43758.5453);\r\n        vec3 flakeNormal=normalize(normal+vec3(sin(grain*91.0),cos(grain*73.0),0.0)*0.55);\r\n        float glint=step(0.92,grain)*pow(max(dot(flakeNormal,normalize(vViewPosition)),0.0),42.0);\r\n        gl_FragColor.rgb+=glint*1.8;\r\n      }\\n#include <dithering_fragment>`);\r\n    } else {\r\n      shader.fragmentShader = shader.fragmentShader.replace(\r\n        '#include <roughnessmap_fragment>',\r\n        `#include <roughnessmap_fragment>\r\n        roughnessFactor = clamp(roughnessFactor + 0.055 * sin(6.2831853 * (fract(${vary}.y) * 90.0 + 0.15 * sin(6.2831853 * ${vary}.x))), 0.05, 1.0);`\r\n      );\r\n    }\r\n  };\r\n  const prevKey = mat.customProgramCacheKey?.bind(mat);\r\n  mat.customProgramCacheKey = function () {\r\n    return `${prevKey ? prevKey.call(this) : ''}|myr5-${kind}`;\r\n  };\r\n  mat.needsUpdate = true;\r\n}\r\n\r\nexport function applyPaletteFinish(\r\n  mat: THREE.MeshPhysicalMaterial,\r\n  paletteId?: string,\r\n  palette?: { primary: string; secondary: string; accent: string },\r\n): void {\r\n  const p = meta(paletteId);\r\n  if (!p) return;\r\n  const f = p.finish;\r\n  mat.roughnessMap = null;\r\n  mat.clearcoat = 0; mat.clearcoatRoughness = 0;\r\n  mat.sheen = 0; (mat as any).sheenRoughness = 1; (mat as any).sheenColor?.set?.(0x000000);\r\n  mat.iridescence = 0; mat.iridescenceIOR = 1.3; mat.iridescenceThicknessRange = [100, 400];\r\n  (mat as any).anisotropy = 0;\r\n  mat.transmission = 0; mat.thickness = 0; mat.ior = 1.5;\r\n  switch (f) {\r\n    case 'matte': mat.roughness = 0.92; mat.metalness = 0; break;\r\n    case 'brushed-metal': mat.roughness = 0.44; mat.metalness = 0.82; (mat as any).anisotropy = 0.65; break;\r\n    case 'polished-metal': mat.roughness = 0.16; mat.metalness = 0.92; break;\r\n    case 'glitter': mat.roughness = 0.24; mat.metalness = 0.35; mat.clearcoat=1; mat.clearcoatRoughness=.035; mat.envMapIntensity=1.5; break;\r\n    case 'pearl':\r\n      mat.roughness = 0.3; mat.metalness = 0.08; mat.iridescence = 1;\r\n      mat.iridescenceIOR = 1.35; mat.iridescenceThicknessRange = [120, 420]; break;\r\n    case 'watercolor': mat.roughness = 0.96; mat.metalness = 0; break;\r\n    case 'marbled': mat.roughness = 0.35; mat.metalness = 0.05; break;\r\n    case 'glaze': mat.roughness = 0.24; mat.metalness = 0; mat.clearcoat = 1; mat.clearcoatRoughness = 0.08; break;\r\n  }\r\n  if (f === 'glitter') addHook(mat as Hooked, 'glitter');\r\n  if (f === 'brushed-metal') addHook(mat as Hooked, 'brushed-metal');\r\n  mat.needsUpdate = true;\r\n}\r\n","creature/source/creator/palettes.json":"[\r\n  {\r\n    \"id\": \"pal-01\",\r\n    \"name\": \"Acid Forge\",\r\n    \"tagline\": \"Lime bites oxblood and chrome\",\r\n    \"colors\": [\r\n      \"#C6FF00\",\r\n      \"#4A0E17\",\r\n      \"#C0C7CE\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 5,\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-02\",\r\n    \"name\": \"Neon Afterburn Haze\",\r\n    \"tagline\": \"Orange aqua contrails with violet flare\",\r\n    \"colors\": [\r\n      \"#FF6D00\",\r\n      \"#00E0B0\",\r\n      \"#C800FF\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 10,\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-03\",\r\n    \"name\": \"Petrel Copper\",\r\n    \"tagline\": \"Petrol depths meet intense violet\",\r\n    \"colors\": [\r\n      \"#0E5A61\",\r\n      \"#B87333\",\r\n      \"#6913E7\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 15,\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-04\",\r\n    \"name\": \"Vinaigrette Rust\",\r\n    \"tagline\": \"Oil pigment rust swirl\",\r\n    \"colors\": [\r\n      \"#8A3B12\",\r\n      \"#556B2F\",\r\n      \"#E7A213\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 20,\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-05\",\r\n    \"name\": \"Neon Relic\",\r\n    \"tagline\": \"Hot magenta neon amber on bone\",\r\n    \"colors\": [\r\n      \"#FF009F\",\r\n      \"#FFB500\",\r\n      \"#F2EFE6\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 25,\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-06\",\r\n    \"name\": \"Glacier Ember\",\r\n    \"tagline\": \"Ice teal over ember red\",\r\n    \"colors\": [\r\n      \"#13E7D1\",\r\n      \"#D9381E\",\r\n      \"#2B2530\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 30,\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-07\",\r\n    \"name\": \"Chartreuse Storm\",\r\n    \"tagline\": \"Sludge green meets slate violet\",\r\n    \"colors\": [\r\n      \"#B5C700\",\r\n      \"#3D3654\",\r\n      \"#E85D75\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 35,\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-08\",\r\n    \"name\": \"Saffron Voltage\",\r\n    \"tagline\": \"Saffron arcs on ink blue\",\r\n    \"colors\": [\r\n      \"#FFB000\",\r\n      \"#101D42\",\r\n      \"#00FAA6\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 40,\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-09\",\r\n    \"name\": \"Neon Venom Signal\",\r\n    \"tagline\": \"Poison lime warning under arterial red\",\r\n    \"colors\": [\r\n      \"#A6FF00\",\r\n      \"#FF2442\",\r\n      \"#101828\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 45,\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-10\",\r\n    \"name\": \"Mercury Moss\",\r\n    \"tagline\": \"Silver moss over saturated gold\",\r\n    \"colors\": [\r\n      \"#AEB6BC\",\r\n      \"#5C6B3C\",\r\n      \"#E7A913\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 50,\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-11\",\r\n    \"name\": \"Ultraviolet Tar\",\r\n    \"tagline\": \"Violet glow on tar black\",\r\n    \"colors\": [\r\n      \"#7B2FF7\",\r\n      \"#141414\",\r\n      \"#FFC93C\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 55,\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-12\",\r\n    \"name\": \"Salmon Circuit\",\r\n    \"tagline\": \"Salmon pink on circuit green\",\r\n    \"colors\": [\r\n      \"#FA2200\",\r\n      \"#00A86B\",\r\n      \"#2E2A5C\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 60,\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-13\",\r\n    \"name\": \"Muddy Pop\",\r\n    \"tagline\": \"Ochre mud sparks cerulean\",\r\n    \"colors\": [\r\n      \"#8C6A2F\",\r\n      \"#0081C8\",\r\n      \"#E71362\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-14\",\r\n    \"name\": \"Neon Vapor Crown\",\r\n    \"tagline\": \"Laser pink blue over dark purple\",\r\n    \"colors\": [\r\n      \"#FF00AA\",\r\n      \"#00D0FF\",\r\n      \"#1B0033\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-15\",\r\n    \"name\": \"Brick Vein\",\r\n    \"tagline\": \"Brick red veined in steel\",\r\n    \"colors\": [\r\n      \"#A0342B\",\r\n      \"#8C9BA5\",\r\n      \"#D7E713\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-16\",\r\n    \"name\": \"Peacock Static\",\r\n    \"tagline\": \"Peacock green hums gold\",\r\n    \"colors\": [\r\n      \"#046A5B\",\r\n      \"#FAAF00\",\r\n      \"#5B1E4B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-17\",\r\n    \"name\": \"Foghorn Flame\",\r\n    \"tagline\": \"Fog gray with fire-orange siren\",\r\n    \"colors\": [\r\n      \"#B8C0C2\",\r\n      \"#FA3F00\",\r\n      \"#123C69\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-18\",\r\n    \"name\": \"Toxic Honey\",\r\n    \"tagline\": \"Honey drips on toxic lime\",\r\n    \"colors\": [\r\n      \"#D9A404\",\r\n      \"#9BF00B\",\r\n      \"#4A154B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-19\",\r\n    \"name\": \"Neon Crimson Mirage\",\r\n    \"tagline\": \"Scarlet toxic lime over deep jade\",\r\n    \"colors\": [\r\n      \"#FF1744\",\r\n      \"#76FF03\",\r\n      \"#005E3C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-20\",\r\n    \"name\": \"Opal Drain\",\r\n    \"tagline\": \"Opal sheen on drainpipe green\",\r\n    \"colors\": [\r\n      \"#13E7B9\",\r\n      \"#3E5641\",\r\n      \"#D1495B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-21\",\r\n    \"name\": \"Rust Halo\",\r\n    \"tagline\": \"Rust ringed by mint flash\",\r\n    \"colors\": [\r\n      \"#9C4221\",\r\n      \"#12E898\",\r\n      \"#2C2C54\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-22\",\r\n    \"name\": \"Volt Quartz\",\r\n    \"tagline\": \"Electric yellow on rose quartz\",\r\n    \"colors\": [\r\n      \"#F5E900\",\r\n      \"#E71363\",\r\n      \"#264653\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-23\",\r\n    \"name\": \"Neon Flare Garden\",\r\n    \"tagline\": \"Laser lime pink on teal steel\",\r\n    \"colors\": [\r\n      \"#8CFF00\",\r\n      \"#FF006E\",\r\n      \"#00B8A9\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-24\",\r\n    \"name\": \"Crimson Tidebreak\",\r\n    \"tagline\": \"Crimson breaks on seafoam\",\r\n    \"colors\": [\r\n      \"#B91338\",\r\n      \"#13E7B5\",\r\n      \"#2A1E5C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-25\",\r\n    \"name\": \"Brass Mirage\",\r\n    \"tagline\": \"Brass shimmer dusky plum\",\r\n    \"colors\": [\r\n      \"#C59B42\",\r\n      \"#5A2A52\",\r\n      \"#0D94ED\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-26\",\r\n    \"name\": \"Neon Infrared Bloom\",\r\n    \"tagline\": \"Red heat sliced by frozen cyan\",\r\n    \"colors\": [\r\n      \"#FF0000\",\r\n      \"#00F5FF\",\r\n      \"#5B00B5\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-27\",\r\n    \"name\": \"Ice Magma\",\r\n    \"tagline\": \"Pigmented ice over magma orange\",\r\n    \"colors\": [\r\n      \"#D6F0F0\",\r\n      \"#F45B0F\",\r\n      \"#3D2C8D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-28\",\r\n    \"name\": \"Fern Radio\",\r\n    \"tagline\": \"Fern green static magenta\",\r\n    \"colors\": [\r\n      \"#3F7A3A\",\r\n      \"#E4007C\",\r\n      \"#E7BE13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-29\",\r\n    \"name\": \"Porcelain Fuel\",\r\n    \"tagline\": \"Porcelain white fuel orange\",\r\n    \"colors\": [\r\n      \"#F2F2F0\",\r\n      \"#FF7A1A\",\r\n      \"#14507A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-30\",\r\n    \"name\": \"Neon Photon Alley\",\r\n    \"tagline\": \"Yellow signage aqua and violet glass\",\r\n    \"colors\": [\r\n      \"#FFD300\",\r\n      \"#00FFCC\",\r\n      \"#7A00FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-31\",\r\n    \"name\": \"Neon Solar Flare\",\r\n    \"tagline\": \"Hot yellow ember in plum space\",\r\n    \"colors\": [\r\n      \"#FFEA00\",\r\n      \"#FF3D00\",\r\n      \"#26142B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-32\",\r\n    \"name\": \"Wet Cement Rose\",\r\n    \"tagline\": \"Cement gray wild rose\",\r\n    \"colors\": [\r\n      \"#8D9096\",\r\n      \"#D84A87\",\r\n      \"#F0E130\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-33\",\r\n    \"name\": \"Neon Laser Tropics\",\r\n    \"tagline\": \"Chartreuse beams with scorched orange shadows\",\r\n    \"colors\": [\r\n      \"#C6FF00\",\r\n      \"#FF4D00\",\r\n      \"#001219\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-34\",\r\n    \"name\": \"Copper Fog\",\r\n    \"tagline\": \"Copper glows through fog\",\r\n    \"colors\": [\r\n      \"#B46A30\",\r\n      \"#C4CBCE\",\r\n      \"#B600F5\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L1\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-35\",\r\n    \"name\": \"Laser Moss\",\r\n    \"tagline\": \"Laser cyan on moss\",\r\n    \"colors\": [\r\n      \"#00E5FF\",\r\n      \"#546B2F\",\r\n      \"#FF4FA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L3\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-36\",\r\n    \"name\": \"Bone Ember\",\r\n    \"tagline\": \"Bone white ember orange\",\r\n    \"colors\": [\r\n      \"#EDE8DC\",\r\n      \"#E4572E\",\r\n      \"#BA00FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-37\",\r\n    \"name\": \"Plum Static\",\r\n    \"tagline\": \"Plum noise with electric lime\",\r\n    \"colors\": [\r\n      \"#4A1E4F\",\r\n      \"#B8F000\",\r\n      \"#33B5C7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-38\",\r\n    \"name\": \"Neon Lime Vortex\",\r\n    \"tagline\": \"Acid green swirling through electric blue\",\r\n    \"colors\": [\r\n      \"#BFFF00\",\r\n      \"#00E5FF\",\r\n      \"#12100F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-39\",\r\n    \"name\": \"Clay Command\",\r\n    \"tagline\": \"Terracotta clay cobalt order\",\r\n    \"colors\": [\r\n      \"#C06B55\",\r\n      \"#2E4BC6\",\r\n      \"#EDE6D6\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-40\",\r\n    \"name\": \"Static Cream\",\r\n    \"tagline\": \"Cream noise shock green\",\r\n    \"colors\": [\r\n      \"#F4EDDE\",\r\n      \"#39FF14\",\r\n      \"#4A306D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-41\",\r\n    \"name\": \"Midnight Papaya\",\r\n    \"tagline\": \"Midnight blue papaya burst\",\r\n    \"colors\": [\r\n      \"#191970\",\r\n      \"#FF9E42\",\r\n      \"#13E796\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-42\",\r\n    \"name\": \"Dusty Laser\",\r\n    \"tagline\": \"Dusty mauve laser green\",\r\n    \"colors\": [\r\n      \"#A27E8E\",\r\n      \"#7CFC00\",\r\n      \"#1B3B6F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-43\",\r\n    \"name\": \"Neon Atomic Sunset\",\r\n    \"tagline\": \"Amber fallout glowing beside ultraviolet pink\",\r\n    \"colors\": [\r\n      \"#FF9100\",\r\n      \"#FF00F5\",\r\n      \"#062A2A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-44\",\r\n    \"name\": \"Fern Flame\",\r\n    \"tagline\": \"Cool fern fierce flame\",\r\n    \"colors\": [\r\n      \"#4F7942\",\r\n      \"#FF3D2E\",\r\n      \"#E75A13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-45\",\r\n    \"name\": \"Violet Quarry\",\r\n    \"tagline\": \"Quarry gray violet eruption\",\r\n    \"colors\": [\r\n      \"#7D7F87\",\r\n      \"#8B3DFF\",\r\n      \"#DCE35B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-46\",\r\n    \"name\": \"Cadmium Deep\",\r\n    \"tagline\": \"Cadmium red deep lagoon\",\r\n    \"colors\": [\r\n      \"#D32E12\",\r\n      \"#046E8F\",\r\n      \"#E79E13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-47\",\r\n    \"name\": \"Pigment Riot\",\r\n    \"tagline\": \"Intense blue maroon and hot orange\",\r\n    \"colors\": [\r\n      \"#139FE7\",\r\n      \"#6E1423\",\r\n      \"#FF7300\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-48\",\r\n    \"name\": \"Neon Prism Riot\",\r\n    \"tagline\": \"Sea-glass cyan, magenta bite, lemon flash\",\r\n    \"colors\": [\r\n      \"#00FFC6\",\r\n      \"#FF00B8\",\r\n      \"#F5FF00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-49\",\r\n    \"name\": \"Neon Tropic Surge\",\r\n    \"tagline\": \"Aqua tide, citrus flare, violet thunder\",\r\n    \"colors\": [\r\n      \"#00FF9D\",\r\n      \"#FFB000\",\r\n      \"#D000FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-50\",\r\n    \"name\": \"Ash Honey\",\r\n    \"tagline\": \"Ash gray golden honey\",\r\n    \"colors\": [\r\n      \"#9BA0A6\",\r\n      \"#E0A100\",\r\n      \"#2F6690\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-51\",\r\n    \"name\": \"Cherry Motor\",\r\n    \"tagline\": \"Cherry motor oil with electric blue\",\r\n    \"colors\": [\r\n      \"#B22234\",\r\n      \"#3B2F2F\",\r\n      \"#005CFF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-52\",\r\n    \"name\": \"Glacier Punch\",\r\n    \"tagline\": \"Glacier pigmented hot punch\",\r\n    \"colors\": [\r\n      \"#13A6E7\",\r\n      \"#F52549\",\r\n      \"#3D405B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-53\",\r\n    \"name\": \"Tarnish Bloom\",\r\n    \"tagline\": \"Tarnished teal floral orange\",\r\n    \"colors\": [\r\n      \"#3A7D7B\",\r\n      \"#F4852B\",\r\n      \"#E9D6EC\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L3\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-54\",\r\n    \"name\": \"Umber Signal\",\r\n    \"tagline\": \"Umber earth neon signal\",\r\n    \"colors\": [\r\n      \"#635147\",\r\n      \"#D0FF4B\",\r\n      \"#7A28C0\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-55\",\r\n    \"name\": \"Rose Quartz Coil\",\r\n    \"tagline\": \"Soft rose coil of teal\",\r\n    \"colors\": [\r\n      \"#E7134B\",\r\n      \"#0FA3A3\",\r\n      \"#2B2118\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-56\",\r\n    \"name\": \"Sulfur Deck\",\r\n    \"tagline\": \"Sulfur yellow blue and hot orange\",\r\n    \"colors\": [\r\n      \"#E3D200\",\r\n      \"#274C77\",\r\n      \"#FF4A00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-57\",\r\n    \"name\": \"Neon Ember Static\",\r\n    \"tagline\": \"Orange yellow buzzing with royal voltage\",\r\n    \"colors\": [\r\n      \"#FF5E00\",\r\n      \"#FFE600\",\r\n      \"#3A0CA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-58\",\r\n    \"name\": \"Mango Ash\",\r\n    \"tagline\": \"Mango bright volcanic ash\",\r\n    \"colors\": [\r\n      \"#FFA12B\",\r\n      \"#59595E\",\r\n      \"#64DDBB\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-59\",\r\n    \"name\": \"Steel Petal\",\r\n    \"tagline\": \"Steel gray crushed petals\",\r\n    \"colors\": [\r\n      \"#8A8F98\",\r\n      \"#E71813\",\r\n      \"#D8E26E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-60\",\r\n    \"name\": \"Ninja Cream\",\r\n    \"tagline\": \"Hidden navy cream coral\",\r\n    \"colors\": [\r\n      \"#1E2A4A\",\r\n      \"#F0EBE0\",\r\n      \"#7EEC00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-61\",\r\n    \"name\": \"Tangerine Static\",\r\n    \"tagline\": \"Tangerine buzz grape shadow\",\r\n    \"colors\": [\r\n      \"#F28500\",\r\n      \"#3D2159\",\r\n      \"#202020\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-62\",\r\n    \"name\": \"Sage Pistol\",\r\n    \"tagline\": \"Muted sage pistol pink\",\r\n    \"colors\": [\r\n      \"#9AB5A1\",\r\n      \"#E45C98\",\r\n      \"#33272A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-63\",\r\n    \"name\": \"Lagoon Battery\",\r\n    \"tagline\": \"Lagoon green charged yellow\",\r\n    \"colors\": [\r\n      \"#1D8A7A\",\r\n      \"#FAE000\",\r\n      \"#76305B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L4\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-64\",\r\n    \"name\": \"Wine Cooling\",\r\n    \"tagline\": \"Warm wine cooled by mint\",\r\n    \"colors\": [\r\n      \"#701F3C\",\r\n      \"#13E78C\",\r\n      \"#E8D44D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-65\",\r\n    \"name\": \"Charcoal Tulip\",\r\n    \"tagline\": \"Charcoal tulip flame combo\",\r\n    \"colors\": [\r\n      \"#2E3033\",\r\n      \"#FF4E50\",\r\n      \"#CA00C7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-66\",\r\n    \"name\": \"Neon Acid Harbor\",\r\n    \"tagline\": \"Lime light cutting across magenta docks\",\r\n    \"colors\": [\r\n      \"#39FF14\",\r\n      \"#FF007F\",\r\n      \"#001B2E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-67\",\r\n    \"name\": \"Rustic Neon\",\r\n    \"tagline\": \"Barn red barn lime buzz\",\r\n    \"colors\": [\r\n      \"#8A3324\",\r\n      \"#C1FF33\",\r\n      \"#2D4A6B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L1\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-68\",\r\n    \"name\": \"Alice Warning\",\r\n    \"tagline\": \"Alice blue caution orange\",\r\n    \"colors\": [\r\n      \"#1399E7\",\r\n      \"#FF7E1F\",\r\n      \"#EEF700\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-69\",\r\n    \"name\": \"Smog Candy\",\r\n    \"tagline\": \"Smog beige candy teal\",\r\n    \"colors\": [\r\n      \"#E79813\",\r\n      \"#00C2A8\",\r\n      \"#D8395B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-70\",\r\n    \"name\": \"Violet Furnace\",\r\n    \"tagline\": \"Furnace violet cooled sky\",\r\n    \"colors\": [\r\n      \"#6A2D9E\",\r\n      \"#F57C3B\",\r\n      \"#302012\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-71\",\r\n    \"name\": \"Khaki Storm\",\r\n    \"tagline\": \"Khaki field storm magenta\",\r\n    \"colors\": [\r\n      \"#A89B6E\",\r\n      \"#E0218A\",\r\n      \"#2A6F97\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-72\",\r\n    \"name\": \"Neon Circuit Surge\",\r\n    \"tagline\": \"Turquoise sparks over midnight violet\",\r\n    \"colors\": [\r\n      \"#00F5D4\",\r\n      \"#F72585\",\r\n      \"#0B0321\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L4\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-73\",\r\n    \"name\": \"Cedar Ultraviolet\",\r\n    \"tagline\": \"Cedar wood ultraviolet light\",\r\n    \"colors\": [\r\n      \"#7A4532\",\r\n      \"#8246FF\",\r\n      \"#E9E4D8\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-74\",\r\n    \"name\": \"Frosted Chili\",\r\n    \"tagline\": \"Frost blue chili red\",\r\n    \"colors\": [\r\n      \"#13AAE7\",\r\n      \"#C13A2F\",\r\n      \"#4C5B2C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-75\",\r\n    \"name\": \"Moss Rocket\",\r\n    \"tagline\": \"Moss green rocket pink\",\r\n    \"colors\": [\r\n      \"#5B7042\",\r\n      \"#FA0057\",\r\n      \"#061F5B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-76\",\r\n    \"name\": \"Pewter Punch\",\r\n    \"tagline\": \"Pewter softened hot punch\",\r\n    \"colors\": [\r\n      \"#99A0A8\",\r\n      \"#FF3D7F\",\r\n      \"#164D37\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L1\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-77\",\r\n    \"name\": \"Neon Glacier Riot\",\r\n    \"tagline\": \"Cyan hot pink and radioactive lime\",\r\n    \"colors\": [\r\n      \"#00F0FF\",\r\n      \"#FF00E5\",\r\n      \"#CCFF00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-78\",\r\n    \"name\": \"Cola Lightning\",\r\n    \"tagline\": \"Cola brown lightning yellow\",\r\n    \"colors\": [\r\n      \"#3A2618\",\r\n      \"#F7FF00\",\r\n      \"#FA005E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-79\",\r\n    \"name\": \"Periwinkle Fuel\",\r\n    \"tagline\": \"Soft periwinkle diesel orange\",\r\n    \"colors\": [\r\n      \"#1325E7\",\r\n      \"#E0641E\",\r\n      \"#2F4730\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-80\",\r\n    \"name\": \"Jade Alarm\",\r\n    \"tagline\": \"Jade calm siren red\",\r\n    \"colors\": [\r\n      \"#57A78A\",\r\n      \"#D91E36\",\r\n      \"#E7AF13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-81\",\r\n    \"name\": \"Neon Ultraviolet Pulse\",\r\n    \"tagline\": \"Violet beams with mint-charged current\",\r\n    \"colors\": [\r\n      \"#8C00FF\",\r\n      \"#00FFB2\",\r\n      \"#160021\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-82\",\r\n    \"name\": \"Neon Nightcaller\",\r\n    \"tagline\": \"Cyan violet flame in black-green fog\",\r\n    \"colors\": [\r\n      \"#00FFFF\",\r\n      \"#9400FF\",\r\n      \"#131A00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L1\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-83\",\r\n    \"name\": \"Ivory Shock\",\r\n    \"tagline\": \"Ivory calm violet shock\",\r\n    \"colors\": [\r\n      \"#F0EEE4\",\r\n      \"#7C1FD3\",\r\n      \"#FFB200\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-84\",\r\n    \"name\": \"Neon Ruby Arc\",\r\n    \"tagline\": \"Red-hot signal over green afterglow\",\r\n    \"colors\": [\r\n      \"#FF073A\",\r\n      \"#00FF87\",\r\n      \"#080F1B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L4\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-85\",\r\n    \"name\": \"Maroon Cloud\",\r\n    \"tagline\": \"Maroon heavy cloud blue\",\r\n    \"colors\": [\r\n      \"#6D1E2E\",\r\n      \"#1381E7\",\r\n      \"#E5D352\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L1\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-86\",\r\n    \"name\": \"Chrome Berry\",\r\n    \"tagline\": \"Chrome band over berry\",\r\n    \"colors\": [\r\n      \"#C3C9D1\",\r\n      \"#8E2A5C\",\r\n      \"#FFB347\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-87\",\r\n    \"name\": \"Lentil Neon\",\r\n    \"tagline\": \"Lentil tan electric aqua\",\r\n    \"colors\": [\r\n      \"#B09A6E\",\r\n      \"#00FFF0\",\r\n      \"#5F1B63\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-88\",\r\n    \"name\": \"Neon Cobalt Fuse\",\r\n    \"tagline\": \"Blue ignition wired to blazing yellow\",\r\n    \"colors\": [\r\n      \"#004DFF\",\r\n      \"#FFEE00\",\r\n      \"#0D0221\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-89\",\r\n    \"name\": \"Spruce Bonfire\",\r\n    \"tagline\": \"Dark spruce bonfire orange\",\r\n    \"colors\": [\r\n      \"#23493C\",\r\n      \"#FF7A3D\",\r\n      \"#0C1735\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-90\",\r\n    \"name\": \"Lilac Foundry\",\r\n    \"tagline\": \"Lilac meets foundry steel\",\r\n    \"colors\": [\r\n      \"#9813E7\",\r\n      \"#7B8894\",\r\n      \"#D4522A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-91\",\r\n    \"name\": \"Topaz Battle\",\r\n    \"tagline\": \"Topaz gold navy clash\",\r\n    \"colors\": [\r\n      \"#F0B429\",\r\n      \"#182952\",\r\n      \"#FA007D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-92\",\r\n    \"name\": \"Dusk Celery\",\r\n    \"tagline\": \"Dusky purple celery snap\",\r\n    \"colors\": [\r\n      \"#574B6B\",\r\n      \"#C8D86A\",\r\n      \"#FA2100\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-93\",\r\n    \"name\": \"Tide Copperfuse\",\r\n    \"tagline\": \"Tidal teal copperfuse glow\",\r\n    \"colors\": [\r\n      \"#0F7B7B\",\r\n      \"#C07840\",\r\n      \"#C2F000\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-94\",\r\n    \"name\": \"Punch Driftwood\",\r\n    \"tagline\": \"Fruit punch on driftwood\",\r\n    \"colors\": [\r\n      \"#E63362\",\r\n      \"#6E5B4A\",\r\n      \"#1648EA\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L1\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-95\",\r\n    \"name\": \"Ink Lime\",\r\n    \"tagline\": \"Ink smudge streaked lime\",\r\n    \"colors\": [\r\n      \"#23232A\",\r\n      \"#A8E10C\",\r\n      \"#7E10EA\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-96\",\r\n    \"name\": \"Porcelain Prism\",\r\n    \"tagline\": \"Porcelain violet over tidal blue\",\r\n    \"colors\": [\r\n      \"#F5F1E8\",\r\n      \"#BD05DA\",\r\n      \"#005F73\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-97\",\r\n    \"name\": \"Wasabi Cloud\",\r\n    \"tagline\": \"Wasabi heat cloud gray\",\r\n    \"colors\": [\r\n      \"#9FBF3B\",\r\n      \"#8E94A0\",\r\n      \"#E71363\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-98\",\r\n    \"name\": \"Eggplant Flare\",\r\n    \"tagline\": \"Eggplant deep flare yellow\",\r\n    \"colors\": [\r\n      \"#41284E\",\r\n      \"#FFD23F\",\r\n      \"#5BC0BE\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L3\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-99\",\r\n    \"name\": \"Stone Rose\",\r\n    \"tagline\": \"Stone gray antique rose\",\r\n    \"colors\": [\r\n      \"#8F8A82\",\r\n      \"#C46E8E\",\r\n      \"#2F6DA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-100\",\r\n    \"name\": \"Neon Quasar Pop\",\r\n    \"tagline\": \"Yellow green comet over indigo gravity\",\r\n    \"colors\": [\r\n      \"#FFEF00\",\r\n      \"#00FF3C\",\r\n      \"#2D02B8\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-101\",\r\n    \"name\": \"Arctic Rust\",\r\n    \"tagline\": \"Arctic white rusted orange\",\r\n    \"colors\": [\r\n      \"#E9F2F5\",\r\n      \"#9E4A1D\",\r\n      \"#3E3F8F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-102\",\r\n    \"name\": \"Magenta Selvage\",\r\n    \"tagline\": \"Magenta edge denim blue\",\r\n    \"colors\": [\r\n      \"#D8117E\",\r\n      \"#3B5B8C\",\r\n      \"#E7D313\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-103\",\r\n    \"name\": \"Haze Saffron\",\r\n    \"tagline\": \"Purple haze saffron spark\",\r\n    \"colors\": [\r\n      \"#8467B8\",\r\n      \"#F4A81D\",\r\n      \"#1D4E50\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-104\",\r\n    \"name\": \"Neon Cyber Reed\",\r\n    \"tagline\": \"Green circuitry humming beside lemon static\",\r\n    \"colors\": [\r\n      \"#00FF66\",\r\n      \"#FFEA00\",\r\n      \"#4B0082\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L2\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-105\",\r\n    \"name\": \"Neon Magma Bloom\",\r\n    \"tagline\": \"Molten orange meeting synthetic magenta\",\r\n    \"colors\": [\r\n      \"#FF2E00\",\r\n      \"#F000FF\",\r\n      \"#0A0A0F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-106\",\r\n    \"name\": \"Dune Violet\",\r\n    \"tagline\": \"Warm dune electric violet\",\r\n    \"colors\": [\r\n      \"#C9AE7E\",\r\n      \"#7D2BF0\",\r\n      \"#13E7E3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-107\",\r\n    \"name\": \"Ember Nightshade\",\r\n    \"tagline\": \"Violet shadows ember teal\",\r\n    \"colors\": [\r\n      \"#523090\",\r\n      \"#EF4E23\",\r\n      \"#0C5D68\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L5\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"opal-jelly\",\r\n    \"name\": \"Opal Jelly\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#b3fff0\",\r\n      \"#9767ff\",\r\n      \"#fff1ff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"bubble-glass\",\r\n    \"name\": \"Bubble Glass\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#58eaff\",\r\n      \"#b8fff8\",\r\n      \"#ffffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"prism-crystal\",\r\n    \"name\": \"Prism Crystal\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#b18aff\",\r\n      \"#447bff\",\r\n      \"#fff2ff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"holo-foil\",\r\n    \"name\": \"Holographic Foil\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#ff54de\",\r\n      \"#39e5ff\",\r\n      \"#fff56b\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"glitter-resin\",\r\n    \"name\": \"Glitter Resin\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#ff319c\",\r\n      \"#7025ff\",\r\n      \"#fff6db\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"galaxy-geode\",\r\n    \"name\": \"Galaxy Geode\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#21134e\",\r\n      \"#7b39e8\",\r\n      \"#63ffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"caustic-slime\",\r\n    \"name\": \"Caustic Slime\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#8aa52b\",\r\n      \"#20300b\",\r\n      \"#dcff57\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"blister-hide\",\r\n    \"name\": \"Blister Hide\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#9e435f\",\r\n      \"#2d1727\",\r\n      \"#e7bb72\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"rotten-rind\",\r\n    \"name\": \"Rotten Rind\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#626124\",\r\n      \"#211916\",\r\n      \"#a2b16b\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"parasite-nest\",\r\n    \"name\": \"Parasite Nest\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#786541\",\r\n      \"#151c14\",\r\n      \"#ece2b0\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"exposed-sinew\",\r\n    \"name\": \"Exposed Sinew\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#b72945\",\r\n      \"#300b24\",\r\n      \"#efb5a1\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"abyssal-maw\",\r\n    \"name\": \"Abyssal Maw\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#522045\",\r\n      \"#100d19\",\r\n      \"#d9e6a7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"circuit-alloy\",\r\n    \"name\": \"Circuit Alloy\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#273f50\",\r\n      \"#0a111c\",\r\n      \"#4effdc\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"servo-armor\",\r\n    \"name\": \"Servo Armor\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#617080\",\r\n      \"#141b25\",\r\n      \"#ff6739\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"chrome-rib\",\r\n    \"name\": \"Chrome Rib\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#bfcde1\",\r\n      \"#202f46\",\r\n      \"#ffffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"carbon-mech\",\r\n    \"name\": \"Carbon Mech\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#323d46\",\r\n      \"#080d15\",\r\n      \"#95bac9\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\"\r\n  },\r\n  {\r\n    \"id\": \"hazard-panel\",\r\n    \"name\": \"Hazard Panel\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#edb932\",\r\n      \"#131a20\",\r\n      \"#ffe9a2\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\"\r\n  },\r\n  {\r\n    \"id\": \"reactor-glass\",\r\n    \"name\": \"Reactor Glass\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#48e8ff\",\r\n      \"#063a55\",\r\n      \"#d4ffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  }\r\n]\r\n","creature/source/creator/pupils.ts":"import * as THREE from 'three';\nexport const PUPILS=[['round','Round'],['vertical','Vertical slit'],['horizontal','Horizontal slit'],['oval','Oval'],['diamond','Diamond'],['star','Star'],['heart','Heart'],['cross','Cross']] as const;\nexport type PupilShape=typeof PUPILS[number][0];\nexport function pupilGeometry(type:PupilShape){\n const s=new THREE.Shape();\n if(['round','vertical','horizontal','oval'].includes(type)){\n  const rx=type==='vertical'?.07:type==='horizontal'?.30:.239;\n  const ry=type==='horizontal'?.065:type==='vertical'?.31:type==='oval'?.31:.257;\n  s.absellipse(0,0,rx,ry,0,Math.PI*2,false,0);\n }else if(type==='heart'){\n  s.moveTo(0,-.28);s.bezierCurveTo(-.09,-.18,-.31,.00,-.27,.17);s.bezierCurveTo(-.24,.32,-.07,.32,0,.18);s.bezierCurveTo(.07,.32,.24,.32,.27,.17);s.bezierCurveTo(.31,0,.09,-.18,0,-.28);\n }else{\n  let pts:number[][]=[];\n  if(type==='diamond')pts=[[0,.31],[.21,0],[0,-.31],[-.21,0]];\n  if(type==='star')pts=Array.from({length:10},(_,i)=>{const a=Math.PI/2+i*Math.PI/5,r=i%2?.135:.30;return [Math.cos(a)*r,Math.sin(a)*r];});\n  if(type==='cross')pts=[[-.08,.28],[.08,.28],[.08,.08],[.28,.08],[.28,-.08],[.08,-.08],[.08,-.28],[-.08,-.28],[-.08,-.08],[-.28,-.08],[-.28,.08],[-.08,.08]];\n  pts.forEach((p,i)=>i?s.lineTo(p[0],p[1]):s.moveTo(p[0],p[1]));s.closePath();\n }\n return new THREE.ShapeGeometry(s,40);\n}\n\r\n","creature/source/creator/roster.ts":"// Generated by D:/MYR5 Roster/tools/publish_roster.py. Do not edit by hand.\r\n// @ts-ignore coach-names.mjs is plain JS shared with the app and server.\r\nimport {coachName,EXCLUDED_COACH_IDS} from '../../../coach-names.mjs';\r\nexport type RosterModel={id:string;label:string;group:string;sourceLabel:string};\r\nconst ROSTER_SOURCE:readonly {id:string;label:string;group:string}[]=[{\"id\": \"roster/01-seed-pearo--3d_character_model\", \"label\": \"Seed · Pearo 1\", \"group\": \"Seed · Pearo\"}, {\"id\": \"roster/01-seed-pearo--cute_alien_figure_3d_model\", \"label\": \"Seed · Pearo 2\", \"group\": \"Seed · Pearo\"}, {\"id\": \"roster/01-seed-pearo--white_3d_character_model\", \"label\": \"Seed · Pearo 3\", \"group\": \"Seed · Pearo\"}, {\"id\": \"roster/01-seed-pearo--blank_humanoid_figure_3d_model\", \"label\": \"Seed · Pearo 4\", \"group\": \"Seed · Pearo\"}, {\"id\": \"roster/01-seed-pearo--blank_toy_figure_3d_model\", \"label\": \"Seed · Pearo 5\", \"group\": \"Seed · Pearo\"}, {\"id\": \"roster/02-taper-tallstalk--3d_humanoid_figure\", \"label\": \"Taper · Tallstalk 1\", \"group\": \"Taper · Tallstalk\"}, {\"id\": \"roster/02-taper-tallstalk--humanoid_robot_3d_model1\", \"label\": \"Taper · Tallstalk 2\", \"group\": \"Taper · Tallstalk\"}, {\"id\": \"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\", \"label\": \"Taper · Tallstalk 3\", \"group\": \"Taper · Tallstalk\"}, {\"id\": \"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\", \"label\": \"Pearl · Orb 1\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/03-pearl-orb-ring--circle_center\", \"label\": \"Pearl · Orb 2\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\", \"label\": \"Pearl · Orb 3\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/03-pearl-orb-ring--robot_3d_model\", \"label\": \"Pearl · Orb 4\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/03-pearl-orb-ring--stylized_3d_character1\", \"label\": \"Pearl · Orb 5\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\", \"label\": \"Pearl · Orb 6\", \"group\": \"Pearl · Orb\"}, {\"id\": \"roster/04-crest-wedge--robot_creature_3d_model\", \"label\": \"Crest · Wedge 1\", \"group\": \"Crest · Wedge\"}, {\"id\": \"roster/04-crest-wedge--stylized_3d_character\", \"label\": \"Crest · Wedge 2\", \"group\": \"Crest · Wedge\"}, {\"id\": \"roster/05-slope-bobble--clay_humanoid_figure_3d_model\", \"label\": \"Slope · Bobble 1\", \"group\": \"Slope · Bobble\"}, {\"id\": \"roster/06-ridge-triad--geometric_robot_3d_model1\", \"label\": \"Ridge · Triad 1\", \"group\": \"Ridge · Triad\"}, {\"id\": \"roster/06-ridge-triad--robot_3d_model1\", \"label\": \"Ridge · Triad 2\", \"group\": \"Ridge · Triad\"}, {\"id\": \"roster/07-bulb-sphereling--cute_robot_3d_model\", \"label\": \"Bulb · Sphereling 1\", \"group\": \"Bulb · Sphereling\"}, {\"id\": \"roster/07-bulb-sphereling--humanoid_robot_3d_model\", \"label\": \"Bulb · Sphereling 2\", \"group\": \"Bulb · Sphereling\"}, {\"id\": \"roster/08-shard-asym--geometric_robot_3d_model\", \"label\": \"Shard · Asym 1\", \"group\": \"Shard · Asym\"}, {\"id\": \"roster/08-shard-asym--robot_3d_model4\", \"label\": \"Shard · Asym 2\", \"group\": \"Shard · Asym\"}, {\"id\": \"roster/08-shard-asym--fantasy_creature_3d_model2\", \"label\": \"Shard · Asym 3\", \"group\": \"Shard · Asym\"}, {\"id\": \"roster/08-shard-asym--stylized_action_figure_3d_model\", \"label\": \"Shard · Asym 4\", \"group\": \"Shard · Asym\"}, {\"id\": \"roster/09-monolith-tanka--3d_robot_model\", \"label\": \"Monolith · Tanka 1\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/09-monolith-tanka--boxy_humanoid_3d_model\", \"label\": \"Monolith · Tanka 2\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/09-monolith-tanka--mini_robot_3d_model\", \"label\": \"Monolith · Tanka 3\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/09-monolith-tanka--robot_3d_model2\", \"label\": \"Monolith · Tanka 4\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/09-monolith-tanka--robot_3d_model3\", \"label\": \"Monolith · Tanka 5\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/09-monolith-tanka--white_horned_robot_3d_model\", \"label\": \"Monolith · Tanka 6\", \"group\": \"Monolith · Tanka\"}, {\"id\": \"roster/10-petal-wisp--stylized_creature_3d_model\", \"label\": \"Petal · Wisp 1\", \"group\": \"Petal · Wisp\"}, {\"id\": \"roster/10-petal-wisp--ghost_character_3d_model\", \"label\": \"Petal · Wisp 2\", \"group\": \"Petal · Wisp\"}, {\"id\": \"roster/10-petal-wisp--fantasy_creature_3d_model4\", \"label\": \"Petal · Wisp 3\", \"group\": \"Petal · Wisp\"}, {\"id\": \"roster/11-anvil-cask--clay-style_robot_3d_model\", \"label\": \"Anvil · Cask 1\", \"group\": \"Anvil · Cask\"}, {\"id\": \"roster/12-seedpod-snailslug--stylized_slug_3d_model\", \"label\": \"Seedpod · Snailslug 1\", \"group\": \"Seedpod · Snailslug\"}, {\"id\": \"roster/12-seedpod-snailslug--stylized_worm_3d_model\", \"label\": \"Seedpod · Snailslug 2\", \"group\": \"Seedpod · Snailslug\"}, {\"id\": \"roster/13-fan-split--stylized_3d_character2\", \"label\": \"Fan · Split 1\", \"group\": \"Fan · Split\"}, {\"id\": \"roster/13-fan-split--stylized_toy_3d_model\", \"label\": \"Fan · Split 2\", \"group\": \"Fan · Split\"}, {\"id\": \"roster/14-chisel-spire--cone_head_3d_model\", \"label\": \"Chisel · Spire 1\", \"group\": \"Chisel · Spire\"}, {\"id\": \"roster/14-chisel-spire--low_poly_robot_3d_model\", \"label\": \"Chisel · Spire 2\", \"group\": \"Chisel · Spire\"}, {\"id\": \"roster/15-orbital-coili--robot_character_3d_model\", \"label\": \"Orbital · Coili 1\", \"group\": \"Orbital · Coili\"}, {\"id\": \"roster/16-spade-arch--pyramid_head_figure_3d_model\", \"label\": \"Spade · Arch 1\", \"group\": \"Spade · Arch\"}, {\"id\": \"roster/16-spade-arch--stylized_humanoid_3d_model\", \"label\": \"Spade · Arch 2\", \"group\": \"Spade · Arch\"}, {\"id\": \"roster/17-shellcap-manyarm--3d_character_figurine\", \"label\": \"Shellcap · Manyarm 1\", \"group\": \"Shellcap · Manyarm\"}, {\"id\": \"roster/17-shellcap-manyarm--mushroom_creature_3d_model\", \"label\": \"Shellcap · Manyarm 2\", \"group\": \"Shellcap · Manyarm\"}, {\"id\": \"roster/17-shellcap-manyarm--mushroom_robot_3d_model\", \"label\": \"Shellcap · Manyarm 3\", \"group\": \"Shellcap · Manyarm\"}, {\"id\": \"roster/18-quad-all--dragon_creature_3d_model\", \"label\": \"Four-legged 1\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--fantasy_creature_3d_model1\", \"label\": \"Four-legged 2\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--fantasy_creature_3d_model3\", \"label\": \"Four-legged 3\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--four-legged_robot_3d_model\", \"label\": \"Four-legged 4\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--quadruped_robot_3d_model1\", \"label\": \"Four-legged 5\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--quadruped_robot_3d_model\", \"label\": \"Four-legged 6\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--robotic_dog_3d_model\", \"label\": \"Four-legged 7\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--stylized_quadruped_3d_model\", \"label\": \"Four-legged 8\", \"group\": \"Four-legged\"}, {\"id\": \"roster/18-quad-all--wooden_four-legged_robot_3d_model\", \"label\": \"Four-legged 9\", \"group\": \"Four-legged\"}, {\"id\": \"roster/19-genie-multi--fantasy_creature_3d_model\", \"label\": \"Genie · Multi 1\", \"group\": \"Genie · Multi\"}, {\"id\": \"roster/19-genie-multi--multi-armed_humanoid_3d_model1\", \"label\": \"Genie · Multi 2\", \"group\": \"Genie · Multi\"}, {\"id\": \"roster/19-genie-multi--multi-armed_humanoid_3d_model\", \"label\": \"Genie · Multi 3\", \"group\": \"Genie · Multi\"}, {\"id\": \"roster/19-genie-multi--stylized_octopus_3d_model\", \"label\": \"Genie · Multi 4\", \"group\": \"Genie · Multi\"}, {\"id\": \"roster/20-lume--robotic_figure_3d_model\", \"label\": \"Lume 1\", \"group\": \"Lume\"}, {\"id\": \"roster/22-curve--stylized_alien_3d_model\", \"label\": \"Curve 1\", \"group\": \"Curve\"}, {\"id\": \"roster/22-curve--stylized_cartoon_figure_3d_model\", \"label\": \"Curve 2\", \"group\": \"Curve\"}, {\"id\": \"roster/23-blob-texture-bodies--blob_creature_3d_model\", \"label\": \"Blob 1\", \"group\": \"Blob\"}, {\"id\": \"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\", \"label\": \"Blob 2\", \"group\": \"Blob\"}, {\"id\": \"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\", \"label\": \"Blob 3\", \"group\": \"Blob\"}, {\"id\": \"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\", \"label\": \"Blob 4\", \"group\": \"Blob\"}, {\"id\": \"roster/23-blob-texture-bodies--sand_creature_3d_model\", \"label\": \"Blob 5\", \"group\": \"Blob\"}];\r\n\r\n// Excluded ids never reach the creator; labels come from the central coach names (the generated\r\n// label is kept as sourceLabel).\r\nexport const rosterModels:readonly RosterModel[]=ROSTER_SOURCE\r\n .filter(model=>!EXCLUDED_COACH_IDS.includes(model.id))\r\n .map(model=>({...model,sourceLabel:model.label,label:coachName(model.id)}));\r\nexport const ROSTER=rosterModels;\r\n","creature/source/creator/skeletal-anatomy.ts":"import * as T from 'three';\r\nimport {EYE_LAYOUTS} from './eye-layouts';\r\nimport {STYLES,type Design,type Region} from './design';\r\nimport {sculptMaterial,materialFor} from './material-language';\r\n\r\nexport function boneSockets(d:Design){\r\n const group=new T.Group();group.name='Empty bone sockets';group.userData.region='head';\r\n for(const [index,[x,y,z,r,yaw]]of EYE_LAYOUTS[d.eyeLayout].eyes.entries()){\r\n  const socket=new T.Group();socket.name='Empty socket '+(index+1);socket.position.set(x,y,z);socket.rotation.y=T.MathUtils.degToRad(yaw);\r\n  // A recessed concave bowl and a continuous ivory rim. No eyeball, iris,\r\n  // pupil, highlight or emissive dot is present, even for mixed recipes.\r\n  const bowlGeo=new T.SphereGeometry(r*.94,32,20,0,Math.PI*2,Math.PI/2,Math.PI/2);bowlGeo.rotateX(Math.PI/2);\r\n  const bowl=new T.Mesh(bowlGeo,new T.MeshStandardMaterial({color:'#0c0907',roughness:1,side:T.DoubleSide}));bowl.name='Recessed empty cavity';bowl.position.z=-r*.06;\r\n  const rim=new T.Mesh(new T.TorusGeometry(r*.94,r*.105,8,32),materialFor(STYLES[7],1));rim.material.vertexColors=false;rim.name='Weathered orbital bone';\r\n  socket.add(bowl,rim);socket.userData.emptySocket=true;group.add(socket);\r\n }\r\n return group;\r\n}\r\n\r\nexport function skeletalStructure(region:Region,d:Design){\r\n const root=new T.Group();root.name='Articulated skeleton '+region;root.userData.region=region;\r\n const mat=new T.MeshStandardMaterial({color:STYLES[7].primary,roughness:.83});\r\n const mesh=(g:T.BufferGeometry,p:number[],scale=[1,1,1])=>{const m=new T.Mesh(g,mat.clone());m.position.fromArray(p);m.scale.fromArray(scale);m.userData.region=region;root.add(m);return m;};\r\n const joint=(p:number[],r=.07)=>mesh(new T.SphereGeometry(r,10,7),p,[1,.78,1]);\r\n const bone=(a:number[],b:number[],r=.055)=>{const from=new T.Vector3(...a),to=new T.Vector3(...b),dir=to.clone().sub(from);const m=mesh(new T.CylinderGeometry(r*.72,r*.9,dir.length(),9),from.clone().add(to).multiplyScalar(.5).toArray());m.quaternion.setFromUnitVectors(new T.Vector3(0,1,0),dir.normalize());joint(a,r*1.6);joint(b,r*1.6);};\r\n if(region==='body'){\r\n  bone([0,.48,-.18],[0,1.5,-.18],.09);\r\n  for(let i=0;i<7;i++){const y=.58+i*.125,w=.3+Math.sin((i+1)/8*Math.PI)*.24;const points=Array.from({length:25},(_,k)=>{const a=k/24*Math.PI*2;return new T.Vector3(Math.cos(a)*w,y+Math.sin(a)*.035,-.08+Math.sin(a)*.35);});mesh(new T.TubeGeometry(new T.CatmullRomCurve3(points,true),32,.031,6,true),[0,0,0]);}\r\n  bone([0,.75,.3],[0,1.41,.27],.043);for(const sign of [-1,1]){bone([0,1.4,-.08],[sign*.51,1.4,-.03],.048);const pelvis=mesh(new T.TorusGeometry(.2,.075,6,12),[sign*.22,.51,-.09],[1,.78,1]);pelvis.rotation.y=sign*.3;}\r\n }else if(region==='collar'){\r\n  for(let i=0;i<3;i++){const ring=mesh(new T.TorusGeometry(.24+i*.075,.043,6,22),[0,1.39+i*.09,-.04]);ring.rotation.x=Math.PI/2;}\r\n }else if(region==='arms'){\r\n  for(const sign of [-1,1]){\r\n   const shoulder=[sign*.52,1.36,-.02],elbow=[sign*.78,1.05,.04],wrist=[sign*.91,.81,.16];bone(shoulder,elbow,.057);bone([elbow[0]-.035,elbow[1],elbow[2]],wrist,.035);bone([elbow[0]+.035,elbow[1],elbow[2]-.025],[wrist[0]+.055,wrist[1],wrist[2]],.028);\r\n   for(let i=0;i<d.fingers;i++){const offset=(i-(d.fingers-1)/2)*.056,a=[wrist[0]+sign*offset,wrist[1]-.08,wrist[2]+.035],b=[a[0]+sign*.06,a[1]-.13,a[2]+.08],c=[b[0]-sign*.025,b[1]-.09,b[2]+.055];bone(wrist,a,.024);bone(a,b,.021);bone(b,c,.017);}\r\n  }\r\n }else if(region==='feet'){\r\n  for(const sign of [-1,1]){const hip=[sign*.34,.58,-.03],ankle=[sign*.39,.2,.04];bone(hip,ankle,.068);for(let i=0;i<d.toes;i++){const x=sign*.39+(i-(d.toes-1)/2)*.072;bone(ankle,[x,.14,.2],.03);bone([x,.14,.2],[x,.105,.38],.025);}}\r\n }\r\n root.updateMatrixWorld(true);root.traverse(o=>{if(o instanceof T.Mesh)sculptMaterial(o,STYLES[7]);});return root;\r\n}\r\n\r\nexport function materialCollar(styleId:number){\r\n const group=new T.Group();group.name='Material collar';group.userData.region='collar';\r\n const style=STYLES[styleId],hard=[3,13,18,19].includes(styleId),geo=new T.TorusGeometry(.52,hard?.15:.18,hard?6:14,hard?12:32);\r\n geo.rotateX(Math.PI/2);geo.scale(1,1,.75);geo.translate(0,1.45,-.03);\r\n const mesh=new T.Mesh(geo,new T.MeshStandardMaterial());group.add(mesh);sculptMaterial(mesh,style,1);return group;\r\n}\r\n\r\nexport function robotStructure(region:Region,d:Design){\r\n const root=new T.Group();root.name='Mechanical '+region;root.userData.region=region;\r\n const armor=new T.MeshPhysicalMaterial({color:'#ad7842',metalness:.87,roughness:.27,clearcoat:.4}),steel=new T.MeshStandardMaterial({color:'#252e3b',metalness:.88,roughness:.3}),light=new T.MeshStandardMaterial({color:'#ffe7a0',emissive:'#ffd169',emissiveIntensity:1.2,roughness:.2});\r\n const mesh=(g:T.BufferGeometry,p:number[],mat=armor)=>{const m=new T.Mesh(g,mat.clone());m.position.fromArray(p);m.userData.region=region;root.add(m);return m;};\r\n const rod=(a:number[],b:number[],radius:number,mat=steel)=>{const from=new T.Vector3(...a),to=new T.Vector3(...b),dir=to.clone().sub(from);const m=mesh(new T.CylinderGeometry(radius,radius,dir.length(),8),from.clone().add(to).multiplyScalar(.5).toArray(),mat as typeof armor);m.quaternion.setFromUnitVectors(new T.Vector3(0,1,0),dir.normalize());};\r\n const hinge=(p:number[],r:number)=>{const m=mesh(new T.CylinderGeometry(r,r,.12,12),p,steel as typeof armor);m.rotation.x=Math.PI/2;const hub=mesh(new T.CylinderGeometry(r*.45,r*.45,.14,8),p);hub.rotation.x=Math.PI/2;};\r\n if(region==='body'){\r\n  const shell=mesh(new T.CylinderGeometry(.51,.42,.93,8),[0,.99,-.09]);shell.scale.z=.79;\r\n  for(const y of [.57,.78,1.03,1.43]){const ring=mesh(new T.TorusGeometry(.45,.035,5,8),[0,y,-.09],steel as typeof armor);ring.rotation.x=Math.PI/2;ring.scale.y=.8;}\r\n  const reactor=mesh(new T.CylinderGeometry(.19,.19,.07,12),[0,1.1,.34],steel as typeof armor);reactor.rotation.x=Math.PI/2;\r\n  const core=mesh(new T.CylinderGeometry(.12,.12,.08,12),[0,1.1,.36],light as typeof armor);core.rotation.x=Math.PI/2;\r\n  for(const sign of [-1,1])for(const y of [.75,1.3]){const rivet=mesh(new T.CylinderGeometry(.036,.036,.1,6),[sign*.29,y,.34],steel as typeof armor);rivet.rotation.x=Math.PI/2;}\r\n }else if(region==='arms'){\r\n  for(const sign of [-1,1]){const shoulder=[sign*.52,1.38,0],elbow=[sign*.77,1.04,.04],wrist=[sign*.91,.8,.17];hinge(shoulder,.16);rod(shoulder,elbow,.108,armor);hinge(elbow,.12);rod(elbow,wrist,.086,armor);rod([elbow[0]+sign*.06,elbow[1],elbow[2]+.07],[wrist[0]+sign*.06,wrist[1],wrist[2]+.07],.027);hinge(wrist,.085);\r\n   mesh(new T.BoxGeometry(.23,.16,.13),[wrist[0],.69,.21]);for(let i=0;i<d.fingers;i++){const x=wrist[0]+(i-(d.fingers-1)/2)*.052,a=[x,.63,.21],b=[x,.52,.27],c=[x,.45,.3];hinge(a,.029);rod(a,b,.023,armor);hinge(b,.026);rod(b,c,.02,armor);}}\r\n }else if(region==='feet'){\r\n  for(const sign of [-1,1]){hinge([sign*.35,.53,-.01],.13);rod([sign*.35,.53,-.01],[sign*.39,.22,.04],.095,armor);hinge([sign*.39,.22,.04],.095);mesh(new T.BoxGeometry(.26,.13,.32),[sign*.39,.13,.15]);for(let i=0;i<d.toes;i++)mesh(new T.BoxGeometry(.055,.085,.13),[sign*.39+(i-(d.toes-1)/2)*.065,.115,.36]);}\r\n }\r\n return root;\r\n}\r\n","creature/source/creator/skin-materials.ts":"import * as T from 'three';\r\nimport {applyPaletteFinish,paletteFinish,FINISH_ID,FINISH_TINT_GLSL} from './palette-finishes';\r\n\r\nexport type SkinMapName='basecolor'|'normal'|'roughness'|'height'|'metalness'|'tintMask'|'ao'|'opacity'|'emissive'|'preview';\r\nexport type InstalledSkin={id:string;displayName:string;track:string;maps:Partial<Record<SkinMapName,Uint8Array>>};\r\nexport type PaletteTriad={primary:string;secondary:string;accent:string;paletteId?:string};\r\n\r\nconst SPACE:Partial<Record<SkinMapName,'srgb'|'linear'>>={basecolor:'srgb',tintMask:'srgb',emissive:'srgb',normal:'linear',roughness:'linear',height:'linear',metalness:'linear',ao:'linear',opacity:'linear'};\r\nexport type SkinTextureCache=Map<Uint8Array,Partial<Record<'srgb'|'linear',Promise<T.Texture>>>>;\r\nfunction textureFrom(bytes:Uint8Array,colorSpace:'srgb'|'linear',owned:Set<T.Texture>):Promise<T.Texture>{\r\n const url=URL.createObjectURL(new Blob([bytes],{type:'image/webp'}));\r\n return new Promise((resolve,reject)=>new T.TextureLoader().load(url,texture=>{URL.revokeObjectURL(url);texture.colorSpace=colorSpace==='srgb'?T.SRGBColorSpace:T.NoColorSpace;texture.wrapS=texture.wrapT=T.RepeatWrapping;texture.magFilter=T.LinearFilter;texture.minFilter=T.LinearMipmapLinearFilter;texture.generateMipmaps=true;texture.needsUpdate=true;owned.add(texture);resolve(texture);},undefined,error=>{URL.revokeObjectURL(url);reject(error||new Error('Skin texture could not be decoded.'));}));\r\n}\r\n\r\nasync function loadTexture(bytes:Uint8Array,colorSpace:'srgb'|'linear',owned:Set<T.Texture>,cache?:SkinTextureCache):Promise<T.Texture>{\r\n if(!cache)return textureFrom(bytes,colorSpace,owned);\r\n let spaces=cache.get(bytes);if(!spaces){spaces={};cache.set(bytes,spaces);}\r\n let pending=spaces[colorSpace];if(!pending){pending=textureFrom(bytes,colorSpace,owned);spaces[colorSpace]=pending;pending.catch(()=>{if(cache.get(bytes)===spaces&&spaces[colorSpace]===pending){delete spaces[colorSpace];if(!spaces.srgb&&!spaces.linear)cache.delete(bytes);}});}\r\n return pending;\r\n}\r\n\r\n/** Decode every supported map before a caller stages changes to any material. */\r\nexport async function loadInstalledSkinTextures(skin:InstalledSkin,owned:Set<T.Texture>,cache?:SkinTextureCache):Promise<Map<SkinMapName,T.Texture>>{\r\n const entries=Object.entries(skin.maps).filter(([name,bytes])=>name!=='preview'&&!!SPACE[name as SkinMapName]&&bytes instanceof Uint8Array) as [SkinMapName,Uint8Array][];\r\n const loaded=new Map<SkinMapName,T.Texture>();\r\n const results=await Promise.allSettled(entries.map(async([name,bytes])=>loaded.set(name,await loadTexture(bytes,SPACE[name]!,owned,cache))));\r\n const failed=results.find((result):result is PromiseRejectedResult=>result.status==='rejected');\r\n if(failed){if(!cache)for(const texture of loaded.values()){owned.delete(texture);texture.dispose();}throw failed.reason;}\r\n return loaded;\r\n}\r\n\r\n/** Apply only maps present in the verified packet. Missing maps retain existing material defaults. */\r\nexport async function applyInstalledSkin(mesh:T.Mesh,skin:InstalledSkin,palette:PaletteTriad,owned:Set<T.Texture>,cache?:SkinTextureCache):Promise<boolean>{\r\n const entries=Object.entries(skin.maps).filter(([name,bytes])=>name!=='preview'&&!!SPACE[name as SkinMapName]&&bytes instanceof Uint8Array) as [SkinMapName,Uint8Array][];\r\n if(!entries.length)return false;\r\n // Some roster models only carry vertex colours. Give them deterministic local\r\n // cylindrical UVs so an installed finish never silently samples one pixel.\r\n if(!mesh.geometry.getAttribute('uv')){const position=mesh.geometry.getAttribute('position');mesh.geometry.computeBoundingBox();const box=mesh.geometry.boundingBox!,center=box.getCenter(new T.Vector3()),height=Math.max(1e-6,box.max.y-box.min.y),uv=new Float32Array(position.count*2);for(let i=0;i<position.count;i++){uv[i*2]=.5+Math.atan2(position.getZ(i)-center.z,position.getX(i)-center.x)/(2*Math.PI);uv[i*2+1]=(position.getY(i)-box.min.y)/height;}mesh.geometry.setAttribute('uv',new T.BufferAttribute(uv,2));}\r\n const loaded=await loadInstalledSkinTextures(skin,owned,cache);\r\n if(!mesh.geometry.getAttribute('uv2')&&mesh.geometry.getAttribute('uv'))mesh.geometry.setAttribute('uv2',mesh.geometry.getAttribute('uv').clone());\r\n for(const raw of Array.isArray(mesh.material)?mesh.material:[mesh.material]){\r\n  const material=raw as T.MeshPhysicalMaterial;\r\n  if((palette.paletteId||loaded.has('basecolor')||loaded.has('tintMask')||loaded.has('emissive'))&&mesh.geometry.getAttribute('uv'))material.defines={...material.defines,USE_UV:''};\r\n  if(loaded.has('normal')){material.normalMap=loaded.get('normal')!;material.normalScale.set(1,1);material.userData.normalConvention='OpenGL +Y';}\r\n  if(loaded.has('roughness'))material.roughnessMap=loaded.get('roughness')!;\r\n  if(loaded.has('height')){material.bumpMap=loaded.get('height')!;material.bumpScale=.018;}\r\n  if(loaded.has('metalness')){material.metalnessMap=loaded.get('metalness')!;material.metalness=1;}\r\n  if(loaded.has('ao'))material.aoMap=loaded.get('ao')!;\r\n  if(loaded.has('opacity')){material.alphaMap=loaded.get('opacity')!;material.transparent=true;material.depthWrite=false;}\r\n  if((palette.paletteId||loaded.has('basecolor')||loaded.has('tintMask')||loaded.has('emissive'))&&mesh.geometry.getAttribute('uv')){\r\n   const fin=paletteFinish(palette.paletteId);\r\n   const previous=material.onBeforeCompile;\r\n   material.onBeforeCompile=(shader,renderer)=>{\r\n    previous.call(material,shader,renderer);\r\n    shader.uniforms.myr5SkinMask={value:loaded.get('tintMask')};\r\n    shader.uniforms.myr5SkinPrimary={value:new T.Color(palette.primary)};\r\n    shader.uniforms.myr5SkinSecondary={value:new T.Color(palette.secondary)};\r\n    shader.uniforms.myr5SkinAccent={value:new T.Color(palette.accent)};\r\n    if(loaded.has('height'))shader.uniforms.myr5SkinHeight={value:loaded.get('height')};\r\n    if(loaded.has('basecolor'))shader.uniforms.myr5SkinBasecolor={value:loaded.get('basecolor')};\r\n    if(loaded.has('emissive'))shader.uniforms.myr5SkinEmissive={value:loaded.get('emissive')};\r\n    shader.vertexShader=shader.vertexShader.replace('#include <common>','#include <common>\\nvarying vec2 vMyr5SkinUv;').replace('#include <uv_vertex>','#include <uv_vertex>\\nvMyr5SkinUv=uv;');\r\n    if(fin)shader.fragmentShader=shader.fragmentShader.replace('#include <common>','#include <common>\\n'+FINISH_TINT_GLSL);\r\n    shader.fragmentShader=shader.fragmentShader.replace('#include <common>','#include <common>\\nuniform sampler2D myr5SkinMask;\\nuniform sampler2D myr5SkinHeight;\\nuniform sampler2D myr5SkinBasecolor;\\nuniform sampler2D myr5SkinEmissive;\\nuniform vec3 myr5SkinPrimary;\\nuniform vec3 myr5SkinSecondary;\\nuniform vec3 myr5SkinAccent;\\nvarying vec2 vMyr5SkinUv;');\r\n    // The texture is tagged SRGBColorSpace, so WebGL's sRGB sampling decodes the mask to linear.\r\n    const tone=loaded.has('tintMask')?'dot(texture2D(myr5SkinMask,vMyr5SkinUv).rgb,vec3(0.2126,0.7152,0.0722))':loaded.has('height')?'texture2D(myr5SkinHeight,vMyr5SkinUv).r':loaded.has('basecolor')?'dot(texture2D(myr5SkinBasecolor,vMyr5SkinUv).rgb,vec3(0.2126,0.7152,0.0722))':'0.5';\r\n    const paletteTone=fin&&fin!=='watercolor'&&fin!=='marbled'&&!loaded.has('tintMask')&&!loaded.has('height')&&!loaded.has('basecolor')?'myr5FlatPaletteTint(vMyr5SkinUv)':tone;\r\n    const layers=palette.paletteId?`float skinTint=clamp(${paletteTone},0.0,1.0);\\n${fin==='watercolor'||fin==='marbled'?`skinTint=myr5FinishTint(${FINISH_ID[fin]}.0,skinTint,vMyr5SkinUv);`:''}\\nvec3 skinPalette=skinTint<0.5?mix(myr5SkinSecondary,myr5SkinPrimary,skinTint*2.0):mix(myr5SkinPrimary,myr5SkinAccent,(skinTint-0.5)*2.0);\\ndiffuseColor.rgb=skinPalette;`:loaded.has('tintMask')?'vec3 skinBase=texture2D(myr5SkinMask,vMyr5SkinUv).rgb;\\nfloat skinMask=dot(skinBase,vec3(0.2126,0.7152,0.0722));\\nvec3 skinPalette=skinMask<0.5?mix(myr5SkinSecondary,myr5SkinPrimary,skinMask*2.0):mix(myr5SkinPrimary,myr5SkinAccent,(skinMask-0.5)*2.0);\\ndiffuseColor.rgb=skinBase*skinPalette;':loaded.has('basecolor')?'diffuseColor.rgb*=texture2D(myr5SkinBasecolor,vMyr5SkinUv).rgb;':'';\r\n    shader.fragmentShader=shader.fragmentShader.replace('#include <color_fragment>','#include <color_fragment>\\n'+layers);\r\n    if(loaded.has('emissive'))shader.fragmentShader=shader.fragmentShader.replace('#include <emissivemap_fragment>','#include <emissivemap_fragment>\\ntotalEmissiveRadiance+=texture2D(myr5SkinEmissive,vMyr5SkinUv).rgb*0.85;');\r\n   };\r\n   const priorKey=material.customProgramCacheKey.bind(material),mapKey=[...loaded.keys()].sort().join(',');material.customProgramCacheKey=()=>priorKey()+'|myr5-installed-skin-palette-v5|'+mapKey+'|'+(palette.paletteId?'palette':'colour')+'|'+(fin??'none');\r\n   material.userData.installedSkinId=skin.id;\r\n  }\r\n  if(palette.paletteId)applyPaletteFinish(material,palette.paletteId,palette); // prior shader hooks stay installed; finish cache key composes via its own tag\r\n  material.needsUpdate=true;\r\n }\r\n return true;\r\n}\r\n","creature/source/creator/surface-styles.ts":"import * as THREE from 'three';\nimport {STYLES,type Region} from './design';\nconst source=new WeakMap<THREE.Mesh,THREE.BufferGeometry>();\nconst cache=new WeakMap<THREE.Mesh,string>();\nfunction noise(x:number,y:number,z:number){return Math.sin(x*7.7+Math.sin(z*5.3))*Math.cos(y*8.1-z*2.7)*.55+Math.sin(x*23+y*17+z*13)*.25+Math.sin(x*51-y*39+z*29)*.12;}\nexport function applySurfaceStyle(mesh:THREE.Mesh,id:number,region:Region,amount=1){\n if(region==='eye'||/Silky|Iris|Pupil|Glint/.test(mesh.name))return;\n if(cache.get(mesh)===id+':'+amount)return;\n if(!source.has(mesh))source.set(mesh,mesh.geometry.clone());\n const base=source.get(mesh)!;const g=base.clone(),p=g.getAttribute('position'),n=base.getAttribute('normal');const colors=new Float32Array(p.count*3);const v=new THREE.Vector3(),normal=new THREE.Vector3();mesh.updateMatrix();const inverse=mesh.matrix.clone().invert(),normalMatrix=new THREE.Matrix3().getNormalMatrix(mesh.matrix);const palette=STYLES[id];\n for(let i=0;i<p.count;i++){\n  v.fromBufferAttribute(base.getAttribute('position'),i).applyMatrix4(mesh.matrix);normal.fromBufferAttribute(n,i).applyMatrix3(normalMatrix).normalize();\n  const {x,y,z}=v;const coarse=noise(x*1.3,y*1.3,z*1.3),fine=noise(x*4,y*4,z*4);let d=0,shade=1;\n  if(id){\n   const wave=Math.sin(y*38+Math.sin(x*15+z*11)*2),vein=Math.pow(1-Math.abs(Math.sin(x*11+z*9+Math.sin(y*10))),7);\n   switch(palette.detail){\n    case 'vine':d=.018*coarse+.04*vein;break;\n    case 'caps':d=.035*Math.max(0,coarse)+.009*fine;break;\n    case 'plates':d=.021*Math.pow(Math.max(0,wave+coarse*.5),.7)+.006*fine;break;\n    case 'scales':d=.027*Math.pow(Math.max(0,Math.sin(y*45)*Math.cos(x*39+z*33)),.65);break;\n    case 'bone':d=.028*wave+.012*coarse;break;\n    case 'rock':case 'magma':d=.048*coarse+.015*fine;break;\n    case 'crystal':case 'ice':d=.021*Math.round(coarse*5)/5+.005*fine;break;\n    case 'gears':d=.014*Math.sign(wave)+.012*vein;break;\n    case 'neon':case 'storm':d=.012*vein;break;\n    default:d=.02*coarse+.01*fine;\n   }\n   if(region==='arms'||region==='feet')d*=.45;\n   shade=Math.max(.55,Math.min(1.2,.86+coarse*.24+fine*.12+vein*.13));\n  }\n  // Preserve each carved socket's smooth boundary when applying skin relief.\n  for(const [sx,sy,sz,r] of mesh.userData.eyeSockets??[]){const distance=Math.hypot(x-sx,y-sy,z-sz);d*=THREE.MathUtils.smoothstep(distance,r*1.12,r*1.45);}\n  v.addScaledVector(normal,d*amount).applyMatrix4(inverse);p.setXYZ(i,v.x,v.y,v.z);colors[i*3]=shade;colors[i*3+1]=shade*(1-.04*Math.max(0,coarse));colors[i*3+2]=shade;\n }\n if(id)g.setAttribute('color',new THREE.BufferAttribute(colors,3));else g.deleteAttribute('color');\n g.computeVertexNormals();g.computeBoundingBox();g.computeBoundingSphere();mesh.geometry.dispose();mesh.geometry=g;const m=mesh.material as THREE.MeshStandardMaterial;m.vertexColors=id!==0;m.needsUpdate=true;cache.set(mesh,id+':'+amount);\n}\n// Grow branching / crystalline detail out of real surface triangles, in region coordinates.\nexport function growSurfaceDetails(group:THREE.Group,id:number,region:Region,hologram:boolean,detailSize=1){\n const result=new THREE.Group();result.name='ornaments_'+region;\n if(![1,2,5,6,9,12,14,16].includes(id)||region==='eye'||region==='collar')return result;\n const meshes:THREE.Mesh[]=[];group.traverseVisible(o=>{if(o instanceof THREE.Mesh&&!/scale/i.test(o.name))meshes.push(o);});\n let seed=id*9049+region.length*371;const rand=()=>{seed=(Math.imul(seed,1664525)+1013904223)>>>0;return seed/4294967296;};\n const style=STYLES[id],amount=region==='head'?26:region==='body'?18:9;\n const triangles:{a:THREE.Vector3;b:THREE.Vector3;c:THREE.Vector3;area:number}[]=[];let total=0;\n group.updateWorldMatrix(true,true);const inverse=group.matrixWorld.clone().invert();\n for(const mesh of meshes){const g=mesh.geometry,p=g.attributes.position,ix=g.index,matrix=inverse.clone().multiply(mesh.matrixWorld);for(let j=0;j<(ix?ix.count:p.count);j+=3){const ids=[0,1,2].map(k=>ix?ix.getX(j+k):j+k);const [a,b,c]=ids.map(k=>new THREE.Vector3().fromBufferAttribute(p,k).applyMatrix4(matrix));const area=b.clone().sub(a).cross(c.clone().sub(a)).length()*.5;if(area>1e-9){total+=area;triangles.push({a,b,c,area:total});}}}\n if(!triangles.length)return result;\n for(let k=0;k<amount;k++){\n  const pick=rand()*total;let lo=0,hi=triangles.length-1;while(lo<hi){const mid=(lo+hi)>>1;if(triangles[mid].area<pick)lo=mid+1;else hi=mid;}const {a,b,c}=triangles[lo];const u=Math.sqrt(rand()),v=rand(),anchor=a.clone().multiplyScalar(1-u).addScaledVector(b,u*(1-v)).addScaledVector(c,u*v);const normal=b.clone().sub(a).cross(c.clone().sub(a)).normalize();\n  // Keep the eye opening clear and avoid outgrowths on the soles.\n  if(region==='head'&&meshes.some(m=>(m.userData.eyeSockets??[]).some(([x,y,z,r]:number[])=>anchor.distanceTo(new THREE.Vector3(x,y,z))<r*1.5)))continue;\n  if(region==='head'&&anchor.z>.15&&anchor.y<2.8)continue;if(region==='feet'&&anchor.y<.15)continue;\n  const height=detailSize*(.045+Math.pow(rand(),2)*.22)*(region==='arms'||region==='feet'?.45:1),radius=detailSize*([14,16].includes(id)?(.033+rand()*.05):(.018+rand()*.035));const angle=rand()*6.28;const tangent=new THREE.Vector3(Math.cos(angle),Math.sin(angle),.3).projectOnPlane(normal).normalize();\n  const points=[];for(let j=0;j<6;j++){const t=j/5;points.push(anchor.clone().addScaledVector(normal,-.012+height*t).addScaledVector(tangent,Math.sin(t*1.8)*height*.32));}\n  const curve=new THREE.CatmullRomCurve3(points);const geo=new THREE.TubeGeometry(curve,12,radius,[14,16].includes(id)?5:8,false);const pos=geo.attributes.position;\n  for(let j=0;j<=12;j++){const t=j/12,center=curve.getPointAt(t);let taper=Math.pow(1-t,.65)+.025;if([14,16].includes(id))taper=t<.62?.85:Math.max(.015,(1-t)/.38*.85);if(id===2)taper=.45+1.4*Math.exp(-Math.pow((t-.72)/.22,2));if(id===6)taper=.7+.23*Math.sin(t*17);for(let r=0;r<=geo.parameters.radialSegments;r++){const index=j*(geo.parameters.radialSegments+1)+r;const q=new THREE.Vector3().fromBufferAttribute(pos,index).sub(center).multiplyScalar(taper).add(center);pos.setXYZ(index,q.x,q.y,q.z);}}\n  geo.computeVertexNormals();const color=new THREE.Color(style.primary).lerp(new THREE.Color(style.accent),.2+rand()*.7);const mat=new THREE.MeshStandardMaterial({color:hologram?'#dac494':color,roughness:style.roughness,metalness:style.metalness,emissive:hologram?'#78568d':style.emissive,emissiveIntensity:.18});const growth=new THREE.Mesh(geo,mat);growth.userData.region=region;growth.userData.surfaceRoot=anchor.toArray();result.add(growth);\n }\n return result;\n}\n\r\n\r\n","creature/source/creator/swatches.ts":"// Runtime swatch generation (Rank 4): texture pattern previews are small canvases rendered\r\n// from the same procedural surfaceSample() the 3D material uses, cached by family id, never\r\n// shipped as image files. Colour swatches need no canvas at all — a CSS background is enough.\r\nimport {surfaceSample} from './material-language';\r\n\r\nconst cache = new Map<number, string>();\r\nexport function texturePreviewDataURL(familyId: number, size = 40): string {\r\n const cached = cache.get(familyId); if (cached) return cached;\r\n const canvas = document.createElement('canvas'); canvas.width = canvas.height = size;\r\n const ctx = canvas.getContext('2d'); if (!ctx) return '';\r\n const img = ctx.createImageData(size, size);\r\n for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {\r\n  const s = surfaceSample(familyId, x / size, y / size), v = Math.round(Math.max(0, Math.min(1, s.height)) * 255), i = (y * size + x) * 4;\r\n  img.data[i] = img.data[i + 1] = img.data[i + 2] = v; img.data[i + 3] = 255;\r\n }\r\n ctx.putImageData(img, 0, 0);\r\n const url = canvas.toDataURL('image/png'); cache.set(familyId, url); return url;\r\n}\r\n","creature/source/creator/texture-policy.mjs":"// The only textures available before opening packs. Keep these IDs shared by the\r\n// registry and reward pool so future catalog additions default to pack access.\r\nexport const FREE_TEXTURE_IDS=Object.freeze([\r\n 'clay', 'martial-arts-canvas-gi', 'arms-rope', 'yoga-cork', 'glutes-peach',\r\n]);\r\n// Former choices remain understood by old recipes but cannot be picked, awarded,\r\n// previewed, or saved again. Clay is their closest safe material fallback.\r\n// R25 (Ian's notebook): Original MYR5, Jelly and Bubble Glass leave the catalogue. Saved looks and\r\n// owned grants move to their kept twin; Original MYR5 has none, so it takes the free starter (Clay).\r\nexport const TEXTURE_REPLACEMENTS=Object.freeze({'legacy-0':'clay','legacy-21':'opal-jelly','bubble-glass':'glitter-resin'});\r\nexport const RETIRED_TEXTURE_IDS=Object.freeze(['flat', 'legacy-22',...Object.keys(TEXTURE_REPLACEMENTS)]);\r\n/** The kept twin of a removed texture (grants and saves follow it); any other id is returned as is. */\r\nexport const replacementTextureId=id=>Object.hasOwn(TEXTURE_REPLACEMENTS,id)?TEXTURE_REPLACEMENTS[id]:id;\r\nexport const normalizeTextureId=id=>{const kept=replacementTextureId(id);return RETIRED_TEXTURE_IDS.includes(kept)?'clay':kept;};\r\nexport const normalizeStyleId=id=>id===22?0:id;\r\n","creature/source/creator/track-placements.ts":"// Rank 7b track-placement registry: the approved 50-model / 51-placement creature roster,\r\n// keyed by stable model id (roster.ts `id`). The customizer's Creature list groups and locks by it (#102).\r\n//\r\n// Source of truth: plan/PLAN.md §2b rank 7b; plan/DECISIONS.md D6 (incl. its 22 Sept revision),\r\n// D21, D25; plan/reports/roster-sheet.md; and mom-program-control/outputs/visual-boards/\r\n// ART-AND-CHOICE-IMPLEMENTATION-HANDOFF.md §2 (roster table), §4 (pet/mount/boss rules), §8\r\n// (stable-data contract: displayName/stableId/track/sourceAsset/license/unlockRule/renderRecipe\r\n// separated; petEligible/mountEligible stored explicitly; one model may hold several placements\r\n// without duplicating its asset).\r\n//\r\n// Label -> stable id: matched directly off roster.ts's own `label` field (only cosmetic\r\n// difference from the handoff is \"·\" vs \"/\" as the group/number separator), cross-checked\r\n// against the authoritative GROUPS/BOSSES tables in mom-program-control/tools/\r\n// generate_creature_reference_board.py and generate_creature_expansion_boards.py.\r\n//\r\n// D6 22 Sept revision: Pearl · Orb 3, Pearl · Orb 5 and Shellcap · Manyarm 3 are approved and\r\n// kept (see design.ts REJECTED_BODY_IDS comment). The 4 hidden rejects (Seed · Pearo 3 & 4,\r\n// Monolith · Tanka 4, Four-legged 8) are not in this roster at all -- see design.ts\r\n// REJECTED_BODY_IDS, reused below as the \"no rejected id present\" guard.\r\n//\r\n// unlockRule follows central coach performance access. sectionComplete() remains board metadata. renderRecipe\r\n// is still a placeholder: the production pixel-art recipe is a later rank (handoff §9 step 2).\r\nimport {REJECTED_BODY_IDS} from './design';\r\nimport {ROWS as BOARD_ROWS,TRACKS,LEVELS_PER_BOSS} from '../../../battle-pass-rewards.mjs';\r\nimport {coachAccess} from '../../../performance-progress.mjs';\r\nimport {STARTER_COACH_IDS,EXCLUDED_COACH_IDS} from '../../../performance-catalog.mjs';\r\nimport {coachRequirements} from '../../../achievements-board.mjs';\r\nexport {REJECTED_BODY_IDS};\r\n\r\nexport const TRACK_IDS = ['chest', 'quads', 'glutes', 'arms', 'yoga', 'martial-arts', 'cardio', 'meditation'] as const;\r\nexport type TrackId = typeof TRACK_IDS[number];\r\n\r\nexport type TrackPlacement = {\r\n stableId: string;\r\n displayName: string; // roster.ts label\r\n tracks: readonly TrackId[]; // >1 entry only for the intentional Spade · Arch 1 dual\r\n petEligible: boolean;\r\n mountEligible: boolean;\r\n bossOf?: TrackId; // starting-boss assignment per 06-workout-bosses-and-meditation-pets.png, if any\r\n sourceAsset: string; // GLB path, relative to the repo root\r\n license: string;\r\n unlockRule: 'performance-milestone';\r\n renderRecipe: 'tbd'; // placeholder -- production sprite recipe not authorized yet\r\n};\r\n\r\nconst LICENSE = 'Original artwork -- MYR5 alien pipeline (Tripo Studio capture by Ian, low-poly re-export, Claude eval); no third-party license asserted (see creature/NOTICE.md).';\r\nconst glb = (stableId: string) => `creature/models/${stableId}.glb`;\r\n\r\ntype Row = [stableId: string, displayName: string, tracks: TrackId[], petEligible: boolean, mountEligible: boolean, bossOf?: TrackId];\r\n\r\nconst ROWS: readonly Row[] = [\r\n // --- Meditation pet family (10; handoff §2/§4) ---\r\n ['roster/23-blob-texture-bodies--blob_creature_3d_model', 'Blob 1', ['meditation'], true, false],\r\n ['roster/18-quad-all--dragon_creature_3d_model', 'Four-legged 1', ['meditation'], true, false],\r\n ['roster/18-quad-all--fantasy_creature_3d_model1', 'Four-legged 2', ['meditation'], true, false],\r\n ['roster/18-quad-all--fantasy_creature_3d_model3', 'Four-legged 3', ['meditation'], true, false],\r\n ['roster/18-quad-all--four-legged_robot_3d_model', 'Four-legged 4', ['meditation'], true, false],\r\n ['roster/18-quad-all--quadruped_robot_3d_model1', 'Four-legged 5', ['meditation'], true, false],\r\n ['roster/18-quad-all--quadruped_robot_3d_model', 'Four-legged 6', ['meditation'], true, false],\r\n ['roster/18-quad-all--robotic_dog_3d_model', 'Four-legged 7', ['meditation'], true, true, 'meditation'], // starting boss + mount candidate\r\n ['roster/12-seedpod-snailslug--stylized_slug_3d_model', 'Seedpod · Snailslug 1', ['meditation'], true, false],\r\n ['roster/12-seedpod-snailslug--stylized_worm_3d_model', 'Seedpod · Snailslug 2', ['meditation'], true, false],\r\n // Meditation boss-only -- explicitly NOT pet/mount (handoff §2 classification correction).\r\n ['roster/14-chisel-spire--low_poly_robot_3d_model', 'Chisel · Spire 2', ['meditation'], false, false],\r\n\r\n // --- Cardio ---\r\n ['roster/07-bulb-sphereling--humanoid_robot_3d_model', 'Bulb · Sphereling 2', ['cardio'], false, false],\r\n ['roster/03-pearl-orb-ring--ringed_humanoid_3d_model', 'Pearl · Orb 3', ['cardio'], false, false], // D6 22 Sept revision: approved, kept\r\n ['roster/06-ridge-triad--robot_3d_model1', 'Ridge · Triad 2', ['cardio'], false, false],\r\n ['roster/03-pearl-orb-ring--robot_3d_model', 'Pearl · Orb 4', ['cardio'], false, false],\r\n ['roster/20-lume--robotic_figure_3d_model', 'Lume 1', ['cardio'], false, false, 'cardio'],\r\n\r\n // --- Arms + Shoulders ---\r\n ['roster/02-taper-tallstalk--humanoid_robot_3d_model1', 'Taper · Tallstalk 2', ['arms'], false, false],\r\n ['roster/19-genie-multi--multi-armed_humanoid_3d_model1', 'Genie · Multi 2', ['arms'], false, false],\r\n ['roster/19-genie-multi--multi-armed_humanoid_3d_model', 'Genie · Multi 3', ['arms'], false, false],\r\n ['roster/17-shellcap-manyarm--mushroom_creature_3d_model', 'Shellcap · Manyarm 2', ['arms'], false, false],\r\n ['roster/17-shellcap-manyarm--mushroom_robot_3d_model', 'Shellcap · Manyarm 3', ['arms'], false, false], // D6 22 Sept revision: approved, kept\r\n ['roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model', 'Blob 4', ['arms'], false, false],\r\n ['roster/08-shard-asym--robot_3d_model4', 'Shard · Asym 2', ['arms'], false, false, 'arms'],\r\n\r\n // --- Chest (Spade · Arch 1 is the intentional dual; its martial-arts placement lives here too) ---\r\n ['roster/06-ridge-triad--geometric_robot_3d_model1', 'Ridge · Triad 1', ['chest'], false, false],\r\n ['roster/08-shard-asym--geometric_robot_3d_model', 'Shard · Asym 1', ['chest'], false, false],\r\n ['roster/16-spade-arch--pyramid_head_figure_3d_model', 'Spade · Arch 1', ['chest', 'martial-arts'], false, false],\r\n ['roster/04-crest-wedge--robot_creature_3d_model', 'Crest · Wedge 1', ['chest'], false, false],\r\n ['roster/16-spade-arch--stylized_humanoid_3d_model', 'Spade · Arch 2', ['chest'], false, false, 'chest'],\r\n\r\n // --- Glutes ---\r\n ['roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model', 'Blob 3', ['glutes'], false, false],\r\n ['roster/23-blob-texture-bodies--sand_creature_3d_model', 'Blob 5', ['glutes'], false, false],\r\n ['roster/03-pearl-orb-ring--stylized_3d_character1', 'Pearl · Orb 5', ['glutes'], false, false], // D6 22 Sept revision: approved, kept\r\n ['roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model', 'Pearl · Orb 6', ['glutes'], false, false, 'glutes'],\r\n\r\n // --- Quads ---\r\n ['roster/15-orbital-coili--robot_character_3d_model', 'Orbital · Coili 1', ['quads'], false, false],\r\n ['roster/13-fan-split--stylized_3d_character2', 'Fan · Split 1', ['quads'], false, false],\r\n ['roster/22-curve--stylized_cartoon_figure_3d_model', 'Curve 2', ['quads'], false, false, 'quads'],\r\n\r\n // --- Yoga ---\r\n ['roster/10-petal-wisp--fantasy_creature_3d_model4', 'Petal · Wisp 3', ['yoga'], false, false],\r\n ['roster/19-genie-multi--fantasy_creature_3d_model', 'Genie · Multi 1', ['yoga'], false, false],\r\n ['roster/10-petal-wisp--ghost_character_3d_model', 'Petal · Wisp 2', ['yoga'], false, false],\r\n ['roster/08-shard-asym--stylized_action_figure_3d_model', 'Shard · Asym 4', ['yoga'], false, false],\r\n ['roster/22-curve--stylized_alien_3d_model', 'Curve 1', ['yoga'], false, false],\r\n ['roster/10-petal-wisp--stylized_creature_3d_model', 'Petal · Wisp 1', ['yoga'], false, false],\r\n ['roster/19-genie-multi--stylized_octopus_3d_model', 'Genie · Multi 4', ['yoga'], false, false, 'yoga'],\r\n\r\n // --- Martial Arts (Spade · Arch 1 dual is listed under Chest above, not repeated here) ---\r\n ['roster/09-monolith-tanka--boxy_humanoid_3d_model', 'Monolith · Tanka 2', ['martial-arts'], false, false],\r\n ['roster/11-anvil-cask--clay-style_robot_3d_model', 'Anvil · Cask 1', ['martial-arts'], false, false],\r\n ['roster/05-slope-bobble--clay_humanoid_figure_3d_model', 'Slope · Bobble 1', ['martial-arts'], false, false],\r\n ['roster/14-chisel-spire--cone_head_3d_model', 'Chisel · Spire 1', ['martial-arts'], false, false],\r\n ['roster/08-shard-asym--fantasy_creature_3d_model2', 'Shard · Asym 3', ['martial-arts'], false, false],\r\n ['roster/09-monolith-tanka--mini_robot_3d_model', 'Monolith · Tanka 3', ['martial-arts'], false, false],\r\n ['roster/09-monolith-tanka--robot_3d_model3', 'Monolith · Tanka 5', ['martial-arts'], false, false],\r\n ['roster/13-fan-split--stylized_toy_3d_model', 'Fan · Split 2', ['martial-arts'], false, false, 'martial-arts'],\r\n];\r\n\r\nexport const TRACK_PLACEMENTS: readonly TrackPlacement[] = ROWS.map(\r\n ([stableId, displayName, tracks, petEligible, mountEligible, bossOf]) => ({\r\n  stableId, displayName, tracks, petEligible, mountEligible, bossOf,\r\n  sourceAsset: glb(stableId), license: LICENSE, unlockRule: 'performance-milestone', renderRecipe: 'tbd',\r\n }),\r\n);\r\n\r\n// #102: a section's bodies unlock when that section is complete. `state` is the achievements board's\r\n// progress map, battle-pass.mjs loadProgress() = {bossId: levels beaten}. Ian's default meaning of\r\n// \"complete\" is the one line below: every boss in the section's board row has every level beaten.\r\nconst rowOf=(track:TrackId)=>BOARD_ROWS.find(row=>row.track&&TRACKS[row.track].catalog===track);\r\nexport function sectionComplete(track:TrackId,state:Record<string,number>){\r\n const row=rowOf(track);if(!row)return false;\r\n return Array.from({length:row.bosses},(_,i)=>state[`${row.id}-${i+1}`]??0).every(levels=>levels>=LEVELS_PER_BOSS);\r\n}\r\n/** Section names as the board shows them, in dial order (TRACK_IDS). */\r\nexport const SECTION_NAMES=Object.fromEntries(TRACK_IDS.map(t=>[t,TRACKS[rowOf(t)!.track!].name])) as Record<TrackId,string>;\r\n/** Display the central performance requirement. Old board-progress arguments remain for callers,\r\n * but board sections and previously saved recipes never authorize a coach body. */\r\nexport function bodyLockSection(id:string,_state:Record<string,number>,_tracks:Iterable<string>=[]):string|null{\r\n if(REJECTED_BODY_IDS.has(id)||EXCLUDED_COACH_IDS.includes(id))return 'Unavailable coach';\r\n if(STARTER_COACH_IDS.includes(id)||coachAccess(id))return null;\r\n return coachRequirements(id)?.unlock||'Coach performance milestone required';\r\n}\r\n","creature/source/creator/unlock-store.ts":"// Cosmetic ownership follows the account/guest and the coach wearing the item.\r\nimport { markPending,markPendingMany } from '../../../unlock-pending.mjs';\r\nimport { performanceOwner } from '../../../performance-progress.mjs';\r\nimport { replacementTextureId } from './texture-policy.mjs';\r\nexport type UnlockKind = 'texture' | 'color' | 'palette';\r\nconst KEY = 'myr5-unlocks-v2';\r\ntype Store = Record<UnlockKind, string[]>;\r\nconst empty = (): Store => ({ texture: [], color: [], palette: [] });\r\nexport const cosmeticId = (coachId: string, id: string) => `coach:${encodeURIComponent(coachId)}:${id}`;\r\n// R25: a grant of a removed texture is a grant of its kept twin (Jelly -> Opal Jelly, Bubble Glass ->\r\n// Glitter Resin). Reads translate old entries, and the next write stores the twin in their place.\r\nconst keptId = (kind: string, id: string) => kind === 'texture' ? replacementTextureId(id) : id;\r\nconst keptScoped = (kind: string, scoped: string) => { const m = /^(coach:[^:]*:)(.*)$/.exec(scoped); return m ? m[1] + keptId(kind, m[2]) : scoped; };\r\nexport function currentCosmeticCoach(): string {\r\n try { return JSON.parse(localStorage.getItem('myr5-recipe-v1') || '{}').body || 'myr5'; } catch { return 'myr5'; }\r\n}\r\nconst ownerKey = () => `${KEY}/${encodeURIComponent(performanceOwner())}`;\r\nfunction read(): Store {\r\n try {\r\n  const d = JSON.parse(localStorage.getItem(ownerKey()) || '{}');\r\n  return Object.fromEntries(['texture','color','palette'].map(kind => [kind, Array.isArray(d[kind]) ? [...new Set<string>(d[kind].filter((id: unknown) => typeof id === 'string').map((id: string) => keptScoped(kind, id)))] : []])) as Store;\r\n } catch { return empty(); }\r\n}\r\nfunction write(store: Store) { try { localStorage.setItem(ownerKey(), JSON.stringify(store)); return true; } catch { return false; } }\r\nconst hasScopedGrant = (kind:UnlockKind,id:string,coachId:string) => read()[kind]?.includes(cosmeticId(coachId,keptId(kind,id))) ?? false;\r\n// The original MYR5 coach is the account's shared material showcase. A cosmetic\r\n// earned for any coach is also available there, while every other coach remains\r\n// coach-scoped. This reads the current owner's ledger, so account and guest data\r\n// never cross boundaries.\r\nfunction grantedToAnyCoach(kind: UnlockKind, id: string) {\r\n const normalized=keptId(kind,id);\r\n return (read()[kind]||[]).some(scoped=>{\r\n  const match=/^coach:([^:]+):(.*)$/.exec(scoped);\r\n  if(!match||match[2]!==normalized)return false;\r\n  try{return decodeURIComponent(match[1])!=='myr5';}catch{return false;}\r\n });\r\n}\r\nexport const isGrantedToOriginalCoach = (kind: UnlockKind,id: string) =>\r\n hasScopedGrant(kind,id,'myr5') || grantedToAnyCoach(kind,id);\r\nexport const isGranted = (kind: UnlockKind, id: string, coachId = currentCosmeticCoach()) =>\r\n coachId==='myr5' ? isGrantedToOriginalCoach(kind,id) : hasScopedGrant(kind,id,coachId);\r\nfunction emitCosmeticsUnlocked(granted:{kind:UnlockKind;id:string;coachId:string}[]) {\r\n const EventCtor=globalThis.CustomEvent;\r\n if(typeof globalThis.dispatchEvent!=='function'||typeof EventCtor!=='function'||!granted.length)return;\r\n try{globalThis.dispatchEvent(new EventCtor('myr5:cosmetics-unlocked',{detail:{owner:performanceOwner(),granted}}));}catch{/* The grant remains saved if a listener cannot receive its notice. */}\r\n}\r\nexport function grantUnlock(kind: UnlockKind, id: string, coachId = currentCosmeticCoach()) {\r\n if (!['texture','color','palette'].includes(kind) || typeof id !== 'string' || !id || typeof coachId !== 'string' || !coachId) return false;\r\n const s = read(), scoped = cosmeticId(coachId,keptId(kind,id));\r\n if (s[kind].includes(scoped)) return false;\r\n s[kind].push(scoped); if (!write(s)) return false;\r\n const normalized=keptId(kind,id),granted=[{kind,id:normalized,coachId}];\r\n markPending(kind,scoped);\r\n // Keep the original coach's new-item marker and notify the live 3D reward preview.\r\n if(coachId!=='myr5')markPending(kind,cosmeticId('myr5',normalized));\r\n emitCosmeticsUnlocked(granted);return true;\r\n}\r\nexport const grantedIds = (kind: UnlockKind, coachId = currentCosmeticCoach()) => {\r\n const values=read()[kind]||[],prefix=cosmeticId(coachId,'');\r\n const own=values.filter(id=>id.startsWith(prefix)).map(id=>id.slice(prefix.length));\r\n if(coachId!=='myr5')return own;\r\n const inherited=values.flatMap(scoped=>{const match=/^coach:([^:]+):(.*)$/.exec(scoped);if(!match||!match[2])return[];try{return decodeURIComponent(match[1])==='myr5'?[]:[match[2]];}catch{return[];}});\r\n return [...new Set([...own,...inherited])];\r\n};\r\n// Preserve a saved look without copying historical device-wide grants onto every coach.\r\nexport function migrateSavedCosmetics(recipe?: {body?:string;materials?:Record<string,{textureId?:string;colorId?:string}|undefined>}) {\r\n const coachId=recipe?.body;if(!coachId)return;\r\n try {\r\n  const migration=`${ownerKey()}/saved-look/${encodeURIComponent(coachId)}`;\r\n  if(localStorage.getItem(migration))return;\r\n  const old=JSON.parse(localStorage.getItem('myr5-unlocks-v1')||'{}');\r\n  for(const choice of Object.values(recipe.materials||{})){\r\n   if(choice?.textureId&&old.texture?.includes(choice.textureId))grantUnlock('texture',choice.textureId,coachId);\r\n   if(choice?.colorId)for(const kind of ['color','palette'] as UnlockKind[])if(old[kind]?.includes(choice.colorId))grantUnlock(kind,choice.colorId,coachId);\r\n  }\r\n  localStorage.setItem(migration,'1');\r\n }catch{/* Legacy storage is optional. */}\r\n}\r\n\r\n// Collection completion writes once per owner, rather than once per cosmetic.\r\nexport const ownerGrantedIds=(kind:UnlockKind)=>{\r\n const values=read()[kind]||[],inherited=values.flatMap(scoped=>{const match=/^coach:([^:]+):(.*)$/.exec(scoped);if(!match||!match[2])return[];try{return decodeURIComponent(match[1])==='myr5'?[]:[cosmeticId('myr5',match[2])];}catch{return[];}});\r\n return [...new Set([...values,...inherited])];\r\n};\r\nexport function grantUnlocks(items:{kind:UnlockKind;id:string;coachId:string}[]){\r\n const data=read(),sets=Object.fromEntries(['texture','color','palette'].map(kind=>[kind,new Set(data[kind as UnlockKind])])) as Record<UnlockKind,Set<string>>;\r\n const added:{kind:UnlockKind;id:string;coachId:string}[]=[];\r\n for(const item of items){if(!sets[item.kind]||typeof item.id!=='string'||!item.id||typeof item.coachId!=='string'||!item.coachId)continue;const normalized=keptId(item.kind,item.id),id=cosmeticId(item.coachId,normalized);if(sets[item.kind].has(id))continue;sets[item.kind].add(id);data[item.kind].push(id);added.push({kind:item.kind,id:normalized,coachId:item.coachId});}\r\n if(!added.length||!write(data))return 0;\r\n const pending=added.flatMap(({kind,id,coachId})=>[{kind,id:cosmeticId(coachId,id)},...(coachId==='myr5'?[]:[{kind,id:cosmeticId('myr5',id)}])]);\r\n markPendingMany(pending);emitCosmeticsUnlocked(added);return added.length;\r\n}\r\n","creature/source/editor-workbench.ts":"import {coachPresentation} from '../../coach-presentation.mjs';\r\nimport {coachName} from '../../coach-names.mjs';\r\nimport {coachRequirements} from '../../achievements-board.mjs';\r\nimport {goldenCoach} from '../../performance-progress.mjs';\r\nimport {PERFORMANCE_KEY,readPerformanceProgress} from '../../performance-progress.mjs';\r\nimport {pathIntroCoachIds} from '../../performance-catalog.mjs';\r\nimport {loadCoachSpritePreviews} from './war-room-coaches';\r\nimport {createStandaloneAccountContext} from '../../standalone-account-context.mjs';\r\nimport {CreatureViewer} from './viewer';\r\nimport {LatestPreview} from './latest-preview';\r\nimport {mountPreviewIdle} from './preview-idle';\r\nimport {GESTURES,type Gesture} from './motion';\r\nimport {REGIONS,PICKER_BODIES,EYE_LAYOUTS,PUPILS,RECIPE_KEY,MOTION_KEY,MAX_IMPORT_BYTES,fresh,importCreature,loadRecipe,motionSettings} from './profile';\r\n\r\nimport {COLOUR_CHANNELS,type Design,type Region,type MaterialChoice} from './creator/design';\r\nimport {EYE_STYLES} from '../../eye-styles.mjs';\r\nimport {TEXTURES,COLORS,PALETTES,isLocked as registryLocked,regionChoice,FREE_COLOURS,resolveRegionMaterial,colorTriad} from './creator/materials-registry';\r\nimport {TRACK_PLACEMENTS,bodyLockSection,sectionComplete} from './creator/track-placements';\r\nimport {isGranted,cosmeticId} from './creator/unlock-store';\r\nimport {sparkle,isUnseen,watchSelect} from '../../unlock-seen.mjs';\r\nimport {noteUnlocked} from '../../unlock-pending.mjs';\r\nimport {saveRecipe,keepOwned,selectOwnedBody,BODY_KEYS} from './save-look';\r\nimport {loadProgress} from '../../battle-pass.mjs';\r\nimport {texturePreviewDataURL} from './creator/swatches';\r\nimport {acceptShipRevealComplete,coachEditorShips,ownedShipIds} from '../../modules/ships/ship-access.mjs';\r\nimport {createInstalledCreatureSkinSource} from '../../modules/materials/installed-creature-skins.mjs';\r\nimport {SHIP_GATE,SHIP_GATE_TOKEN,SHIP_HISTORY_ADMISSION} from '../../modules/ships/ship-scene-domain.mjs';\r\n\r\nimport {localVerifiedBridge} from '../../modules/ships/verified-ship-assets.mjs';\r\nimport {mountShipPreview} from './ship-preview';\r\nimport {SHIP_CATALOG,shipDetails} from '../../modules/ships/ship-catalog.mjs';\r\nimport {FREE_COLOUR_NAMES} from '../../battle-pass-rewards.mjs';\r\nexport {CreatureViewer,GESTURES,importCreature};\r\n// #148: the ship's admission is single-use. A reload can resume this exact editor history entry, but\r\n// navigating here again (including Back/Forward) needs another completed ship reveal and tap.\r\nconst shipReload=performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming|undefined;\r\nconst admitShipEditor=(()=>{\r\n try{\r\n  const admitted=sessionStorage.getItem(SHIP_GATE)===SHIP_GATE_TOKEN;\r\n  sessionStorage.removeItem(SHIP_GATE);\r\n  if(shipReload?.type==='reload'&&history.state?.[SHIP_HISTORY_ADMISSION]===true)return true;\r\n  if(!admitted)return false;\r\n  history.replaceState({...history.state,[SHIP_HISTORY_ADMISSION]:true},'');\r\n  return true;\r\n }catch{return false;}\r\n})();\r\nif(!admitShipEditor){location.replace('/pose.html#select');await new Promise(()=>{});}\r\nconst standaloneAccount=createStandaloneAccountContext();\r\nawait standaloneAccount.refresh();\r\n// Safari can restore this document from its back-forward cache without rerunning the admission\r\n// check above. A restored editor must return through the ship instead of reviving its old state.\r\nwindow.addEventListener('pageshow',event=>{if(event.persisted)location.replace('/pose.html#select');});\r\nconst download=(blob:Blob,name:string)=>{const url=URL.createObjectURL(blob),a=document.createElement('a');a.href=url;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(url),3000);};\r\nconst $=(id:string)=>document.getElementById(id)!;\r\n\r\n// D2 / audit-customizer.md C8: the one mom-approved coach. Finger/toe count and collar fluff\r\n// (Rank 5, handoff §6) are anatomy controls carved only for this body's own rig.\r\nconst MOM_APPROVED_BODY_ID='myr5';\r\nconst MOM_ONLY_FIELD_IDS=['fingersField','toesField','furField','digitsHelp'];\r\nlet recipe:Design=fresh(),undo:Design[]=[],redo:Design[]=[],selected:Region='body',ready=false,activeRange:string|null=null;\r\nlet settings=motionSettings(null),initialError='';\r\ntry{recipe=zeroFinish(loadRecipe(localStorage));settings=motionSettings(localStorage.getItem(MOTION_KEY));}catch{initialError='Your saved coach could not be read. Load a recipe in Files to restore it.';}\r\nlet saved=recipe; // last owned look written to storage; locked imports remain preview-only.\r\n// R27: ownership is per account. Until the verified account is known (cold start, slow or offline account check,\r\n// the bridge's re-check) every earned body reads as locked, so filtering then turned the saved coach into MYR5 in\r\n// memory and the next edit saved that. Show the stored look as the portal does; account-ready applies ownership.\r\nconst ownedLook=(d:Design)=>(window as any).myr5AuthenticatedAccount?keepOwned(d):d;\r\nrecipe=saved=ownedLook(recipe);\r\nlet progress=loadProgress(),bodyLock=(id:string)=>bodyLockSection(id,progress);\r\nconst unlockedFirst=<T,>(items:readonly T[],locked:(x:T)=>boolean):T[]=>[...items.filter(x=>!locked(x)),...items.filter(locked)];\r\n// Body unlocks are derived from section completion, so record them here: first use snapshots, later ones sparkle.\r\nconst noteBodyUnlocks=()=>{const state=loadProgress();noteUnlocked('body',TRACK_PLACEMENTS.filter(p=>p.tracks.some(t=>sectionComplete(t,state))).map(p=>p.stableId));};\r\nnoteBodyUnlocks();window.addEventListener('myr5:battle-pass',noteBodyUnlocks);\r\nconst systemMotion=matchMedia('(prefers-reduced-motion: reduce)');\r\nconst base=document.body.dataset.modelBase?new URL(document.body.dataset.modelBase,location.href).href:new URL('../',import.meta.url).href;\r\nlet viewer:CreatureViewer|undefined;\r\nfunction tell(text:string){$('creatureStatus').textContent=text;}\r\n\r\n// Texture/colour/sparkle/metallic override for the selected part (Rank 4 registry, Rank 5 UI).\r\n// No override -> renders exactly like the legacy `styles[region]` index (old saves keep working).\r\nconst DEFAULT_MATERIAL:MaterialChoice={textureId:'clay',colorId:'#7f7d78',sparkle:0,metallic:0};\r\nfunction zeroFinish(d:Design):Design{return d.materials?{...d,materials:Object.fromEntries(Object.entries(d.materials).map(([r,c])=>[r,c&&{...c,sparkle:0,metallic:0}])) as Design['materials']}:d;} // hoisted: used by the load on L49\r\nfunction materialChoice():MaterialChoice{return shown().materials?.[selected]??DEFAULT_MATERIAL;}\r\nfunction setMaterial(patch:Partial<MaterialChoice>,rangeId:string|null=null){const base=shown();commit({...base,materials:{...base.materials,[selected]:{...materialChoice(),...patch}}},rangeId);}\r\n// #1/#102 Preview locked looks: a design that contains a locked body or locked material paints the\r\n// model from this draft only. It never enters `recipe`, undo/redo or storage -- commit() below is the\r\n// one shared guard every caller routes through (saveRecipe() also rejects locked ids as a backstop).\r\nlet previewDraft:Design|null=null,lastShown='';\r\nconst strip=document.createElement('p');strip.className='preview-strip';strip.hidden=true;document.querySelector('.preview-bay')!.append(strip); // over the LIVE PREVIEW readout, clear of the model\r\nconst previewing=()=>previewDraft!==null;\r\nfunction clearPreview(){previewDraft=null;}\r\nfunction shown():Design{return previewDraft??recipe;}\r\nconst idLocked=(id:string)=>registryLocked(id,shown().body);\r\nconst colorLocked=(id:string)=>registryLocked(id,shown().body,'color');\r\nfunction isLocked(design:Design):boolean{\r\n if(BODY_KEYS.some(key=>bodyLock(design[key])))return true;\r\n const ship=design.shipId??design.coach;if(ship!=='supportive'&&!ownedShipIds().includes(ship))return true;\r\n for(const r of REGIONS){const mc=regionChoice(design.materials,r);if(mc&&(registryLocked(mc.textureId,design.body)||registryLocked(mc.colorId,design.body,'color')))return true;}\r\n return false;\r\n}\r\nfunction previewMessage(design:Design):string{\r\n const body=bodyLock(design.body);if(body)return `Preview only · How to unlock ${PICKER_BODIES.find(b=>b.id===design.body)?.label||'this coach'}: ${body}.`;\r\n for(const region of [selected,...REGIONS.filter(r=>r!==selected)]){const choice=regionChoice(design.materials,region);if(!choice)continue;for(const [id,kind] of [[choice.textureId,'adaptation'],[choice.colorId,'colour']] as const)if(kind==='colour'?colorLocked(id):idLocked(id)){\r\n  const texture=kind==='adaptation'?TEXTURES.find(t=>t.id===id):undefined,palette=PALETTES.find(p=>p.id===id),color=COLORS.find(c=>c.id===id);\r\n  const detail=texture?.id==='coach-64-bit'?'Open the 64-bit Pixel Finish in a texture pack and complete this coach’s boss skin milestone':texture?'Open a texture pack':palette?.unlockRule==='aura-milestone'?`Reach aura day ${palette.unlockAtDay}`:'Earn it through the battle pass';\r\n  return `Preview only · How to unlock ${texture?.displayName||palette?.displayName||color?.displayName||kind}: ${detail}.`;\r\n }}return 'Preview only';\r\n}\r\n// Locked choices remain drafts. Available colors on owned bodies use an earned-material\r\n// baseline, so switching away from a locked preview can save without granting that preview.\r\nfunction pick(patch:Partial<MaterialChoice>){const base=shown();commit({...base,materials:{...base.materials,[selected]:{...(base.materials?.[selected]??DEFAULT_MATERIAL),...patch}}});}\r\n// #139: an Adaptation (texture) covers the whole coach: every part gets the same textureId, colours stay\r\n// per part. A part with no material of its own yet takes the texture's own colour (TextureDef.defaultColorId).\r\nfunction pickTexture(textureId:string){\r\n const base=shown(),texture=TEXTURES.find(t=>t.id===textureId);\r\n const defaultColor=texture&&!colorLocked(texture.defaultColorId)?texture.defaultColorId:DEFAULT_MATERIAL.colorId;\r\n const patch=(r:Region):Partial<MaterialChoice>=>{const current=base.materials?.[r];return {...(!current?{colorId:defaultColor}:{}),textureId};};\r\n commit({...base,materials:Object.fromEntries(REGIONS.map(r=>[r,{...(base.materials?.[r]??DEFAULT_MATERIAL),...patch(r)}])) as Design['materials']});\r\n}\r\nfunction endPreview(){if(!previewing())return false;clearPreview();render('Back to your look');return true;}\r\nfunction syncMaterials(){\r\n const mc=materialChoice();\r\n ($('textureId') as HTMLSelectElement).value=mc.textureId;\r\n for(const button of textureGrid.querySelectorAll<HTMLButtonElement>('[data-texture]'))button.setAttribute('aria-pressed',String(button.dataset.texture===mc.textureId));\r\n const texture=TEXTURES.find(t=>t.id===mc.textureId);\r\n ($('texturePreview') as HTMLImageElement).src=texture?texturePreviewDataURL(texture.familyId):'';\r\n // R20: the toggle shows each part's current colour as a dot; the single grid marks the active part's colour.\r\n const partColour=(c:typeof COLOUR_CHANNELS[number])=>regionChoice(shown().materials,c.regions[0])?.colorId??DEFAULT_MATERIAL.colorId;\r\n for(const b of document.querySelectorAll<HTMLButtonElement>('#colorSwatches [data-part]')){const c=COLOUR_CHANNELS.find(x=>x.id===b.dataset.part)!,on=c===activeChannel;b.setAttribute('aria-checked',String(on));b.tabIndex=on?0:-1;(b.firstElementChild as HTMLElement).style.background=colorTriad(partColour(c),false,shown().body)?.primary??partColour(c);}\r\n for(const b of document.querySelectorAll<HTMLButtonElement>('#colorSwatches [data-color]'))b.setAttribute('aria-pressed',String(b.dataset.color===partColour(activeChannel)));\r\n ($('materialClear') as HTMLButtonElement).disabled=!activeChannel.regions.some(r=>shown().materials?.[r]);\r\n}\r\nfunction syncMomOnly(){\r\n const show=shown().body===MOM_APPROVED_BODY_ID;\r\n for(const id of MOM_ONLY_FIELD_IDS){const el=document.getElementById(id);if(el)el.style.display=show?'':'none';}\r\n}\r\n\r\nconst coachRequirementDialog=document.createElement('dialog');coachRequirementDialog.className='coach-requirement-dialog';coachRequirementDialog.setAttribute('aria-labelledby','coachRequirementTitle');document.body.append(coachRequirementDialog);\r\nfunction showCoachRequirement(id:string){const info=coachRequirements(id);coachRequirementDialog.replaceChildren();const title=document.createElement('h2');title.id='coachRequirementTitle';title.textContent=coachName(id);const text=document.createElement('p');text.textContent=info.unlock;const close=document.createElement('button');close.type='button';close.textContent='Close';close.onclick=()=>coachRequirementDialog.close();coachRequirementDialog.append(title,text,close);if(!coachRequirementDialog.open)coachRequirementDialog.showModal();}\r\nfunction syncCoachIdentity(){const id=shown().body,locked=!!bodyLock(id),p=coachPresentation(id);$('coachDisplayName').textContent=coachName(id);$('coachPathSymbol').textContent=p.symbol;$('coachPathSymbol').title=p.track;$('coachUnlock').hidden=!locked;$('coachUnlock').onclick=()=>showCoachRequirement(id);}\r\n\r\nlet cosmeticCoach='';\r\nfunction sync(){\r\n const look=shown();\r\n if(cosmeticCoach!==look.body){cosmeticCoach=look.body;fillTextures();fillColours();}\r\n for(const key of ['body','eyeLayout','fingers','toes','eye','pupil','fur','iris','pupilSize','detail']){const input=$(key) as HTMLInputElement;input.value=String(look[key as keyof Design]);const out=document.getElementById(key+'Value');if(out)out.textContent=Number(input.value).toFixed(2);}\r\n\r\n for(const key of ['blackSclera','colourPupil'] as const)($(key) as HTMLInputElement).checked=look[key]===true;\r\n syncMomOnly();syncCoachIdentity();\r\n for(const button of bodyGrid.querySelectorAll<HTMLButtonElement>('[data-body]'))button.setAttribute('aria-pressed',String(button.dataset.body===look.body));\r\n syncShipRow();\r\n syncMaterials();\r\n syncSkinChoice();\r\n // R18: no unlock hints. The strip says only \"Preview\" (and flags a catalogue entry with no pattern yet).\r\n const notes:string[]=[],mc=look.materials?.[selected];\r\n if(mc?.textureId){const t=TEXTURES.find(x=>x.id===mc.textureId);if(t&&t.familyId<0)notes.push(`${t.displayName} pattern is coming`);}\r\n strip.hidden=!previewing()&&!notes.length;strip.textContent=[...(previewing()?['Preview']:[]),...notes].join(' · ');\r\n ($('undo') as HTMLButtonElement).disabled=!undo.length&&!previewing();($('redo') as HTMLButtonElement).disabled=!redo.length;\r\n}\r\nconst queue=new LatestPreview<{recipe:Design;message:string;preview:boolean}>(async job=>{if(!viewer)throw Error('3D is unavailable.');if(!await viewer.setRecipe(job.recipe,job.preview))throw Error('Preview was interrupted.');},(job,error)=>{\r\n if(error){tell('Could not update the preview. '+(error instanceof Error?error.message:String(error)));return;}\r\n ready=true;($('exportGLB') as HTMLButtonElement).disabled=job.preview;tell(job.message);\r\n});\r\nfunction render(message:string,persist=false){\r\n ready=false;($('exportGLB') as HTMLButtonElement).disabled=true;\r\n if(persist)try{persistSkinSettings();const owned=saveRecipe(localStorage,recipe,saved);message=owned===recipe?'Saved on this device':'Locked looks stay in preview until you unlock them';recipe=saved=owned;persistRecipeShip();window.dispatchEvent(new CustomEvent('myr5:recipe',{detail:recipe}));}catch{message='Storage unavailable. Download your recipe in Files to keep this design.';}\r\n sync();const look=shown();lastShown=JSON.stringify(look);\r\n tell('Updating preview…');queue.request({recipe:look,message,preview:previewing()});\r\n}\r\nfunction commit(next:Design,rangeId:string|null=null){\r\n next=zeroFinish(next);\r\n // Every writer shares this guard: any remaining locked choice stays a draft.\r\n // A completely earned design ends preview before entering undo history and storage.\r\n if(isLocked(next)){previewDraft=next;render(previewMessage(next));return;}\r\n clearPreview();\r\n if(JSON.stringify(next)===JSON.stringify(recipe)){if(JSON.stringify(shown())!==lastShown)render('Back to your look');return;}\r\n if(!rangeId||activeRange!==rangeId){undo.push(recipe);undo=undo.slice(-40);}activeRange=rangeId;redo=[];recipe=next;render('Coach updated',true);\r\n}\r\nfunction options(id:string,entries:ReadonlyArray<readonly [unknown,string]>){for(const [value,label] of entries){const o=document.createElement('option');o.value=String(value);o.textContent=label;$(id).append(o);}}\r\n// Keep the chosen workout introductions and every owned shape ahead of locked shapes. The\r\n// native select provides a name-only fallback; the sprite grid uses the same selection path.\r\nconst orderedBodies=()=>{const introductory=new Set(pathIntroCoachIds(readPerformanceProgress().paths));return [...PICKER_BODIES].sort((a,b)=>Number(!!bodyLock(a.id))-Number(!!bodyLock(b.id))||Number(introductory.has(b.id))-Number(introductory.has(a.id)));};\r\nlet spritePreviews:Awaited<ReturnType<typeof loadCoachSpritePreviews>>|null=null;\r\nconst bodyGrid=document.createElement('div');bodyGrid.className='material-grid coach-sprite-grid';bodyGrid.setAttribute('role','group');bodyGrid.setAttribute('aria-label','Creature shapes');\r\nfunction fillBodySprites(){if(!spritePreviews)return;bodyGrid.replaceChildren();for(const b of orderedBodies()){\r\n const sprite=spritePreviews.sprites.find(s=>s.id===b.id);if(!sprite)continue;\r\n const locked=!!bodyLock(b.id),presentation=coachPresentation(b.id);\r\n const card=document.createElement('div');card.className='coach-choice';card.dataset.locked=String(locked);\r\n const button=document.createElement('button');button.type='button';button.dataset.body=b.id;button.setAttribute('aria-label',`${b.label}, ${locked?'locked preview':'available'}`);button.setAttribute('aria-pressed',String(shown().body===b.id));\r\n const source=spritePreviews.art(sprite),canvas=document.createElement('canvas');canvas.width=source.width;canvas.height=source.height;canvas.getContext('2d')!.drawImage(source,0,0);\r\n const caption=document.createElement('span');caption.textContent=`${presentation.symbol} ${b.label}`;button.append(canvas,caption);button.onclick=()=>{const select=$('body') as HTMLSelectElement;select.value=b.id;select.dispatchEvent(new Event('change',{bubbles:true}));};if(!locked)sparkle(button,'body',b.id);card.append(button);\r\n const state=document.createElement('span');state.className='coach-choice-state';state.textContent=locked?'Locked':'Available';card.append(state);\r\n if(locked){const lock=document.createElement('button');lock.type='button';lock.className='coach-choice-lock';lock.textContent='\\u{1f512}';lock.setAttribute('aria-label',`How to unlock ${b.label}`);lock.onclick=()=>showCoachRequirement(b.id);card.append(lock);}bodyGrid.append(card);\r\n }}\r\nfunction fillBodies(){$('body').replaceChildren();for(const b of orderedBodies()){\r\n const o=document.createElement('option');o.value=b.id;o.textContent=b.label+(bodyLock(b.id)?' (Locked)':'');if(!bodyLock(b.id)&&isUnseen('body',b.id))o.dataset.sparkle=`body:${b.id}`;$('body').append(o);\r\n }fillBodySprites();}\r\noptions('eyeLayout',Object.entries(EYE_LAYOUTS).map(([key,value])=>[key,value.label]));options('eye',EYE_STYLES);options('pupil',PUPILS);\r\nfor(const [id,min,max] of [['fingers',2,6],['toes',1,6]] as const)options(id,Array.from({length:max-min+1},(_,i)=>[i+min,String(i+min)]));\r\n\r\nfunction focusPart(_region:Region,_frame=true){sync();}\r\n\r\nfor(const [id,region] of Object.entries({body:'body',eyeLayout:'eye',eye:'eye',pupil:'eye',iris:'eye',pupilSize:'eye',fingers:'arms',toes:'feet',fur:'collar',detail:'body'}))$(id).addEventListener('focus',()=>focusPart(region as Region));\r\n// Rank 4: texture dropdown (registry-driven) and colour/palette swatch grid, separate axes. #1: locked\r\n// entries keep a lock mark and their unlock source, and picking one previews it (see pick()).\r\nconst textureGrid=document.createElement('div');textureGrid.className='material-grid texture-grid';textureGrid.setAttribute('role','group');textureGrid.setAttribute('aria-label','Adaptation textures');\r\nfunction fillTextures(){$('textureId').replaceChildren();textureGrid.replaceChildren();for(const t of unlockedFirst(TEXTURES,t=>idLocked(t.id))){\r\n const o=document.createElement('option');o.value=t.id;o.textContent=t.displayName;const id=cosmeticId(shown().body,t.id);if(isGranted('texture',t.id,shown().body)&&isUnseen('texture',id))o.dataset.sparkle=`texture:${id}`;$('textureId').append(o);\r\n const locked=idLocked(t.id),button=document.createElement('button'),preview=document.createElement('img'),name=document.createElement('span');button.type='button';button.dataset.texture=t.id;button.setAttribute('aria-label',`${t.displayName}${locked?', locked':''}`);button.setAttribute('aria-pressed',String(materialChoice().textureId===t.id));preview.src=texturePreviewDataURL(t.familyId);preview.alt='';name.textContent=t.displayName;button.append(preview,name);if(locked){const icon=document.createElement('i');icon.className='texture-tile-lock';icon.textContent='🔒';icon.setAttribute('aria-hidden','true');button.append(icon);}button.onclick=()=>{const select=$('textureId') as HTMLSelectElement;select.value=t.id;select.dispatchEvent(new Event('change',{bubbles:true}));};textureGrid.append(button);\r\n}}\r\nfillBodies();fillTextures();\r\n$('panel-textures').querySelector('.panel-heading')!.after(textureGrid); // grid sits under the Textures heading\r\nvoid loadCoachSpritePreviews(document).then(previews=>{\r\n spritePreviews=previews;fillBodySprites();\r\n if(bodyGrid.childElementCount)($('body') as HTMLSelectElement).parentElement!.after(bodyGrid);\r\n}).catch(()=>{}); // Native name-only select remains available if sprite sheets cannot load.\r\nconst goldenToggle=document.createElement('button');goldenToggle.type='button';goldenToggle.textContent='Golden coach';goldenToggle.title='Unlocked by a ten-minute uninterrupted hold';\r\nfunction syncGolden(){goldenToggle.disabled=!goldenCoach(shown().body);goldenToggle.setAttribute('aria-pressed',String(shown().golden!==false&&goldenCoach(shown().body)));}\r\ngoldenToggle.onclick=()=>{if(goldenCoach(shown().body)){commit({...shown(),golden:shown().golden===false});syncGolden();}};$('body').after(goldenToggle);$('body').addEventListener('change',()=>queueMicrotask(syncGolden));window.addEventListener('myr5:performance-progress',()=>{refreshLists();syncGolden();});syncGolden();\r\nwatchSelect($('body') as HTMLSelectElement);watchSelect($('textureId') as HTMLSelectElement);\r\n$('textureId').addEventListener('change',()=>pickTexture(($('textureId') as HTMLSelectElement).value));\r\nconst colorSwatches=[\r\n ...COLORS.map(c=>({kind:'color' as const,id:c.id,name:c.displayName,background:c.primary})),\r\n ...PALETTES.map(p=>({kind:'palette' as const,id:p.id,name:p.displayName,background:`linear-gradient(90deg,${p.colors.join(',')})`})),\r\n];\r\nfunction swatchButton(s:{kind:'color'|'palette';id:string;name:string;background:string},onPick:()=>void){const locked=colorLocked(s.id),b=document.createElement('button');b.type='button';b.dataset.color=s.id;b.title=s.name;b.setAttribute('aria-label',s.name+(locked?', locked':''));b.style.background=s.background;if(locked){b.dataset.locked='';const icon=document.createElement('span');icon.className='swatch-lock';icon.textContent='\\u{1f512}';icon.setAttribute('aria-hidden','true');b.append(icon);}b.onclick=onPick;if(isGranted(s.kind,s.id,shown().body))sparkle(b,s.kind,cosmeticId(shown().body,s.id));return b;}\r\nfunction swatchGrid(grid:HTMLElement,onPick:(id:string)=>void){for(const s of unlockedFirst(colorSwatches,s=>colorLocked(s.id)))grid.append(swatchButton(s,()=>onPick(s.id)));}\r\n// R18 G3 colours; R20: one part toggle (Body/Head/Eyes) over a single colour grid, then a palette grid\r\n// that blends its colours across the selected part. Every colour def plus the free hexes no def starts with.\r\nconst rowColours=[...FREE_COLOURS.map((h,n)=>({id:h,name:FREE_COLOUR_NAMES[n],hex:h})),...COLORS.filter(c=>!FREE_COLOURS.includes(c.primary.toLowerCase())).map(c=>({id:c.id,name:c.displayName,hex:c.primary}))]; // free hexes first, then the locked defs\r\nlet activeChannel:typeof COLOUR_CHANNELS[number]=COLOUR_CHANNELS[0];\r\nfunction setChannel(channel:typeof COLOUR_CHANNELS[number],colorId:string){\r\n const draft=shown(),base=!colorLocked(colorId)&&BODY_KEYS.every(key=>!bodyLock(draft[key]))?keepOwned(draft,recipe):draft;\r\n commit({...base,materials:{...base.materials,...Object.fromEntries(channel.regions.map(r=>[r,{...(base.materials?.[r]??DEFAULT_MATERIAL),colorId}]))}});\r\n}\r\nfunction choosePart(channel:typeof COLOUR_CHANNELS[number]){activeChannel=channel;selected=channel.regions[0];sync();}\r\nconst colorRoot=$('colorSwatches');\r\nfunction fillColours(){colorRoot.replaceChildren();\r\nconst toggle=document.createElement('div');toggle.className='part-toggle';toggle.setAttribute('role','radiogroup');toggle.setAttribute('aria-label','Part to colour');\r\nfor(const channel of COLOUR_CHANNELS){const b=document.createElement('button');b.type='button';b.dataset.part=channel.id;b.setAttribute('role','radio');b.append(document.createElement('i'),channel.label);b.onclick=()=>choosePart(channel);\r\n b.onkeydown=e=>{const n=COLOUR_CHANNELS.indexOf(channel),d=e.key==='ArrowRight'||e.key==='ArrowDown'?1:e.key==='ArrowLeft'||e.key==='ArrowUp'?-1:0;if(!d)return;e.preventDefault();const next=COLOUR_CHANNELS[(n+d+COLOUR_CHANNELS.length)%COLOUR_CHANNELS.length];choosePart(next);(toggle.querySelector(`[data-part=\"${next.id}\"]`) as HTMLElement).focus();};\r\n toggle.append(b);}\r\nconst grid=document.createElement('div');grid.className='material-grid';grid.id='colourGrid';grid.setAttribute('role','group');grid.setAttribute('aria-label','Colours');\r\nfor(const c of unlockedFirst(rowColours,c=>colorLocked(c.id))){const b=swatchButton({kind:'color',id:c.id,name:c.name,background:c.hex},()=>setChannel(activeChannel,c.id));b.dataset.kind='color';grid.append(b);}\r\nconst label=document.createElement('strong');label.textContent='Multicolor palettes';\r\nconst palettes=document.createElement('div');palettes.className='material-grid';palettes.id='paletteGrid';palettes.setAttribute('role','group');palettes.setAttribute('aria-label','Palettes');\r\nfor(const p of unlockedFirst(PALETTES,p=>colorLocked(p.id))){const b=swatchButton({kind:'palette',id:p.id,name:p.displayName,background:`linear-gradient(90deg,${p.colors.join(',')})`},()=>setChannel(activeChannel,p.id));b.dataset.kind='palette';palettes.append(b);}\r\nconst paletteHelp=document.createElement('p');paletteHelp.className='help';paletteHelp.textContent='Map palette colors to the selected texture?s dark, middle and light areas. Other parts keep their own colors.';\r\ncolorRoot.append(toggle,grid,label,palettes,paletteHelp);}\r\nfillColours();\r\n// The Ship tab edits the recipe's existing shipId/shipColor and mirrors it to the arrival scene.\r\nconst shipRow=$('shipColourRow'),shipPick=$('shipPick') as HTMLSelectElement;\r\nconst shipLocked=(id:string)=>id!=='supportive'&&!coachEditorShips().includes(id);\r\nfunction saveShip(patch:{shipId?:Design['coach'];shipColor?:string|null}){\r\n const draft=shown(),base=BODY_KEYS.every(key=>!bodyLock(draft[key]))?keepOwned(draft,recipe):draft;\r\n commit({...base,...patch});\r\n}\r\nfunction persistRecipeShip(){const owner=editorOwner(),ship=recipe.shipId??recipe.coach;if(owner&&(ship==='supportive'||ownedShipIds().includes(ship))){const choice={ownerId:owner,ship,tint:recipe.shipColor??'#ffffff',colorId:rowColours.find(c=>c.hex===recipe.shipColor)?.id};localStorage.setItem(`${SHIP_SETTINGS_KEY}/${owner}`,JSON.stringify(choice));window.dispatchEvent(new CustomEvent('myr5:ship-customization',{detail:choice}));}}\r\nfunction fillShipRow(){\r\n shipPick.replaceChildren(...unlockedFirst(SHIP_CATALOG,c=>shipLocked(c.id)).map(c=>{const o=document.createElement('option');o.value=c.id;o.textContent=(shipLocked(c.id)?'\\u{1f512} ':'')+c.name;return o;}));\r\n shipRow.replaceChildren();const grid=document.createElement('div');grid.className='material-grid';grid.id='shipColourGrid';\r\n const original=document.createElement('button');original.type='button';original.dataset.ship='original';original.textContent='Orig.';original.title='Original ship colours';original.setAttribute('aria-label','Original ship colours');original.onclick=()=>saveShip({shipColor:null});grid.append(original);\r\n for(const c of unlockedFirst(rowColours,c=>colorLocked(c.id))){const b=swatchButton({kind:'color',id:c.id,name:c.name,background:c.hex},()=>{if(colorLocked(c.id)){tell('Locked for your ship too');return;}saveShip({shipColor:c.hex});});b.dataset.hex=c.hex;grid.append(b);}\r\n shipRow.append(grid);syncShipRow();\r\n}\r\nfunction syncShipRow(){const look=shown();shipPick.value=look.shipId??look.coach;const color=look.shipColor??null;for(const b of shipRow.querySelectorAll<HTMLButtonElement>('button')){b.setAttribute('aria-pressed',String(b.dataset.ship==='original'?color===null:b.dataset.hex===color));}queueMicrotask(()=>void previewShip());}\r\nshipPick.onchange=()=>{if(shipLocked(shipPick.value)){const name=SHIP_CATALOG.find(c=>c.id===shipPick.value)?.name||'this ship';tell(`Preview only · How to unlock ${name}: complete its workout milestone.`);syncShipRow();return;}saveShip({shipId:shipPick.value as Design['coach']});};\r\nfillShipRow();\r\nfunction refreshLists(){progress=loadProgress();fillBodies();fillTextures();fillColours();fillShipRow();sync();}window.addEventListener('myr5:battle-pass',refreshLists);\r\nwindow.addEventListener('storage',event=>{if(event.key?.startsWith(PERFORMANCE_KEY+'/')||event.key?.startsWith('myr5-unlocks-v2/'))refreshLists();});\r\n // A pick made while ownership was unknown stayed a preview; once it is owned, save it.\r\n function saveOwnedDraft(){if(!previewDraft||isLocked(previewDraft))return false;const next=previewDraft;clearPreview();commit(next);return true;}\r\n window.addEventListener('myr5:account-ready',()=>{recipe=saved=ownedLook(recipe);cosmeticCoach='';refreshLists();if(!saveOwnedDraft())render('Account cosmetics connected');});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden)saveOwnedDraft();});\r\n // R26: account-bridge clears before every re-verify (focus, visibilitychange), so a clear is often a blink, not a\r\n // sign-out. Keep the saved look and any pending pick: account-ready re-applies ownership and saves an owned pick.\r\n window.addEventListener('myr5:account-cleared',()=>{undo=[];redo=[];cosmeticCoach='';refreshLists();render('Account changed. Showing current ownership.');});\r\n window.addEventListener('myr5:login-ready',()=>void standaloneAccount.refresh());\r\n window.addEventListener('focus',()=>{if(!standaloneAccount.account)void standaloneAccount.refresh();});\r\n$('materialClear').onclick=()=>{const base=shown(),materials={...base.materials};for(const r of activeChannel.regions)delete materials[r];commit({...base,materials:Object.keys(materials).length?materials:undefined});};\r\n\r\nfor(const id of ['body','eyeLayout','fingers','toes','eye','pupil'])$(id).addEventListener('change',()=>{const input=$(id) as HTMLInputElement,value=['fingers','toes'].includes(id)?Number(input.value):input.value;\r\n // #102: a locked body previews like a locked texture (commit()'s guard below catches it). An owned\r\n // body is one of the three ways to leave a preview, so it starts from `recipe` (the last saved\r\n // look), not from `shown()` -- any locked tweaks made mid-preview are discarded, never carried\r\n // into the save. Other fields (face etc.) build on `shown()` so they keep an active preview going.\r\n if(id==='body'){const chosen=String(value),section=bodyLock(chosen);if(!section)clearPreview();\r\n  // Choosing a body always resets head, arms and legs to match it — Rank 5 removed the UI that\r\n  // let them diverge. A recipe saved before this change (with mismatched headFrom/armsFrom/feetFrom)\r\n  // still loads and renders mixed (assemble.ts/parseRecipe are unchanged); picking a body here just\r\n  // normalizes it going forward.\r\n  commit(section?{...shown(),body:chosen,headFrom:chosen,armsFrom:chosen,feetFrom:chosen}:selectOwnedBody(recipe,chosen));return;}\r\n commit({...shown(),[id]:value});});\r\nfor(const id of ['blackSclera','colourPupil'] as const)$(id).addEventListener('change',()=>{const next={...shown()};if(($(id) as HTMLInputElement).checked)next[id]=true;else delete next[id];commit(next);});\r\nfor(const id of ['fur','iris','pupilSize','detail']){\r\n const input=$(id) as HTMLInputElement;\r\n input.addEventListener('input',()=>commit({...shown(),[id]:Number(input.value)},id));\r\n for(const event of ['change','blur','pointercancel'])input.addEventListener(event,()=>{activeRange=null;});\r\n}\r\nconst tabs=[...document.querySelectorAll<HTMLButtonElement>('[data-menu]')];\r\nconst skinTab=document.createElement('button');skinTab.type='button';skinTab.id='tab-skin';skinTab.setAttribute('role','tab');skinTab.setAttribute('aria-controls','panel-skin');skinTab.setAttribute('aria-selected','false');skinTab.tabIndex=-1;skinTab.dataset.menu='skin';skinTab.textContent='Skins';skinTab.hidden=true;\r\nconst skinPanel=document.createElement('div');skinPanel.id='panel-skin';skinPanel.setAttribute('role','tabpanel');skinPanel.setAttribute('aria-labelledby','tab-skin');skinPanel.tabIndex=0;skinPanel.hidden=true;skinPanel.innerHTML='<div class=\"panel-heading\"><h2>Creature skins</h2></div><label>Installed skin<select id=\"skinChoice\"></select></label>';\r\n// #146: Skins and Ship sit after the option tabs, just above Files (Ian's \"Downloads\" tab).\r\nconst filesTab=$('tab-files') as HTMLButtonElement;filesTab.before(skinTab);document.querySelector('.console-scroll')?.append(skinPanel);tabs.splice(tabs.indexOf(filesTab),0,skinTab);\r\nconst shipTab=$('tab-ship') as HTMLButtonElement;\r\nconst shipPanel=$('panel-ship') as HTMLElement;\r\nconst SHIP_SETTINGS_KEY='myr5-ship-customization-v1';\r\nconst SKIN_SETTINGS_PREFIX='myr5-editor-skins-v1/account/';let skinOwner:string|null=null;\r\n// Persist from the current recipe for every edit, including Undo and Redo.\r\nfunction persistSkinSettings(){if(skinOwner)localStorage.setItem(SKIN_SETTINGS_PREFIX+skinOwner,JSON.stringify(Object.fromEntries(REGIONS.flatMap(region=>{const id=recipe.materials?.[region]?.textureId;return id?.startsWith('creature-')?[[region,id]]:[]}))));}\r\nfunction skinSettings(){if(!skinOwner)return{};try{const value=JSON.parse(localStorage.getItem(SKIN_SETTINGS_PREFIX+skinOwner)||'{}');return value&&typeof value==='object'&&!Array.isArray(value)?value:{}}catch{return{}}}\r\nconst editorOwner=()=>{const account=window.myr5AuthenticatedAccount;return typeof account==='string'?account:account?.user?.id;};\r\nfunction syncShipEditor(){shipTab.hidden=false;shipTab.setAttribute('aria-hidden','false');shipTab.tabIndex=shipTab.getAttribute('aria-selected')==='true'?0:-1;fillShipRow();}\r\n// The Ship tab's preview: only while that tab is open, only from this account's verified local ship bytes (never a\r\n// download). The choice itself is saved either way; the preview just shows it.\r\nlet shipPreview:ReturnType<typeof mountShipPreview>|null=null,shipPreviewOwner:string|null=null,shipPreviewEpoch=0;\r\nfunction closeShipPreview(){++shipPreviewEpoch;shipPreview?.dispose();shipPreview=null;shipPreviewOwner=null;}\r\nasync function previewShip(){\r\n const active=!shipTab.hidden&&shipTab.getAttribute(\"aria-selected\")===\"true\";\r\n const owner=editorOwner()||null,ship=shipPick.value,status=$('shipPreviewStatus'),retry=$('shipPreviewRetry') as HTMLButtonElement;\r\n const description=document.getElementById('shipDescription');if(description&&ship)description.textContent=shipDetails(ship).description;\r\n retry.hidden=true;\r\n // Leaving the tab (or the account) frees the preview: the bridge holds every owned ship's bytes.\r\n if(shipPreviewOwner!==owner||!active||!ship||(shipPreview&&!shipPreview.ids().includes(ship)))closeShipPreview();\r\n const run=++shipPreviewEpoch;\r\n if(!active||!ship){status.textContent='';return;}\r\n status.textContent='Loading your ship…';\r\n try{\r\n  if(!shipPreview){\r\n   const bridge=ship==='supportive'?{ownedShipIds:()=>['supportive'],getShipUrl:()=>'/pod/worlds/starter/supportive.glb'}:await localVerifiedBridge().catch(()=>null);\r\n   if(run!==shipPreviewEpoch||(editorOwner()||null)!==owner){bridge?.dispose?.();return;}\r\n   if(!bridge){status.textContent='3D model unavailable on this phone.';return;}\r\n   shipPreview=mountShipPreview($('shipPreview'),bridge);shipPreviewOwner=owner;\r\n  }\r\n  if(!shipPreview.ids().includes(ship)){status.textContent='3D model unavailable on this phone.';return;}\r\n  if(await shipPreview.show(ship,shown().shipColor??'#ffffff')&&run===shipPreviewEpoch)status.textContent='';\r\n }catch{if(run!==shipPreviewEpoch)return;status.textContent='Ship preview unavailable.';retry.hidden=false;}\r\n}\r\n$('shipPreviewRetry').onclick=()=>{closeShipPreview();void previewShip();};\r\nsyncShipEditor();watchSelect(shipPick);watchSelect($('skinChoice') as HTMLSelectElement);window.addEventListener('myr5:ship-scene-ready',event=>{if(acceptShipRevealComplete(event))syncShipEditor()});window.addEventListener('myr5:account-ready',syncShipEditor);window.addEventListener('myr5:account-cleared',syncShipEditor);window.addEventListener('storage',event=>{if(event.key?.startsWith(SHIP_SETTINGS_KEY+'/')||event.key==='myr5-ship-reveal-seen-v1')syncShipEditor()});document.addEventListener('visibilitychange',()=>{if(document.hidden)closeShipPreview();else if(shipTab.getAttribute('aria-selected')==='true')void previewShip();});\r\nlet skinSource:ReturnType<typeof createInstalledCreatureSkinSource>|null=null,pendingSkinSource:ReturnType<typeof createInstalledCreatureSkinSource>|null=null,skinEpoch=0,skinChoices:{id:string;displayName:string}[]=[];\r\nfunction syncSkinChoice(){const choice=$('skinChoice') as HTMLSelectElement,current=recipe.materials?.[selected]?.textureId||'';choice.value=skinChoices.some(s=>s.id===current)?current:'';}\r\nfunction renderSkinChoices(){const select=$('skinChoice') as HTMLSelectElement;select.replaceChildren(...skinChoices.map(skin=>{const option=document.createElement('option');option.value=skin.id;option.textContent=skin.displayName;if(isUnseen('creature-skin',skin.id))option.dataset.sparkle=`creature-skin:${skin.id}`;return option}));select.value='';syncSkinChoice();}\r\nasync function refreshSkinEditor(account=window.myr5AuthenticatedAccount){\r\n const run=++skinEpoch,owner=typeof account==='string'?account:typeof account?.user?.id==='string'?account.user.id:null,ownerChanged=owner!==skinOwner;\r\n const hadAppliedSkin=!ownerChanged&&Object.values(recipe.materials??{}).some(choice=>choice?.textureId.startsWith('creature-'));skinOwner=owner;\r\n if(ownerChanged){undo=[];redo=[];activeRange=null;skinSource?.dispose();skinSource=null;pendingSkinSource?.dispose();pendingSkinSource=null;skinChoices=[];viewer?.clearSkinState();viewer?.setSkinResolver(undefined);if(recipe.materials)recipe={...recipe,materials:Object.fromEntries(Object.entries(recipe.materials).map(([region,choice])=>[region,choice.textureId.startsWith('creature-')?{...choice,textureId:'clay'}:choice])) as Design['materials']};skinTab.hidden=true;skinTab.tabIndex=-1;skinTab.setAttribute('aria-hidden','true');if(skinTab.getAttribute('aria-selected')==='true')openMenu(document.getElementById('tab-body') as HTMLButtonElement);}\r\n renderSkinChoices();if(!owner){pendingSkinSource?.dispose();pendingSkinSource=null;render('Your coach is ready');return;}\r\n pendingSkinSource?.dispose();const source=createInstalledCreatureSkinSource({account});pendingSkinSource=source;tell('Checking installed skins');\r\n let rows:{id:string;displayName:string}[];try{rows=await source.list();}catch{const active=window.myr5AuthenticatedAccount,activeOwner=typeof active==='string'?active:active?.user?.id;if(run!==skinEpoch||activeOwner!==owner||skinOwner!==owner){source.dispose();if(pendingSkinSource===source)pendingSkinSource=null;return;}if(pendingSkinSource===source)pendingSkinSource=null;source.dispose();skinSource?.dispose();skinSource=null;skinChoices=[];viewer?.clearSkinState();viewer?.setSkinResolver(undefined);if(recipe.materials)recipe={...recipe,materials:Object.fromEntries(Object.entries(recipe.materials).map(([region,choice])=>[region,choice.textureId.startsWith('creature-')?{...choice,textureId:'clay'}:choice])) as Design['materials']};skinTab.hidden=true;skinTab.tabIndex=-1;skinTab.setAttribute('aria-hidden','true');if(skinTab.getAttribute('aria-selected')==='true')openMenu(document.getElementById('tab-body') as HTMLButtonElement);renderSkinChoices();render('Could not verify installed skins. Check your connection and try again.');return;}\r\n const active=window.myr5AuthenticatedAccount,activeOwner=typeof active==='string'?active:active?.user?.id;if(run!==skinEpoch||activeOwner!==owner||skinOwner!==owner){source.dispose();if(pendingSkinSource===source)pendingSkinSource=null;return;}if(pendingSkinSource===source)pendingSkinSource=null;\r\n if(!rows.length){source.dispose();skinSource?.dispose();skinSource=null;skinChoices=[];viewer?.clearSkinState();viewer?.setSkinResolver(undefined);if(recipe.materials)recipe={...recipe,materials:Object.fromEntries(Object.entries(recipe.materials).map(([region,choice])=>[region,choice.textureId.startsWith('creature-')?{...choice,textureId:'clay'}:choice])) as Design['materials']};skinTab.hidden=true;skinTab.setAttribute('aria-hidden','true');if(skinTab.getAttribute('aria-selected')==='true')openMenu(document.getElementById('tab-body') as HTMLButtonElement);renderSkinChoices();render(hadAppliedSkin?'No verified installed skins. Check your extra packs and try again.':'Your coach is ready');return;}\r\n const previous=skinSource;skinSource=source;previous?.dispose();skinChoices=rows.map(({id,displayName})=>({id,displayName}));viewer?.setSkinResolver(source.resolve);skinTab.hidden=false;skinTab.tabIndex=-1;skinTab.setAttribute('aria-hidden','false');const remembered=skinSettings();for(const region of REGIONS){const id=remembered[region];if(typeof id==='string'&&skinChoices.some(s=>s.id===id))recipe={...recipe,materials:{...recipe.materials,[region]:{...(recipe.materials?.[region]??DEFAULT_MATERIAL),textureId:id}}};}renderSkinChoices();render('Installed skins ready');\r\n}\r\nskinTab.onclick=()=>openMenu(skinTab);($('skinChoice') as HTMLSelectElement).addEventListener('change',()=>{const id=($('skinChoice') as HTMLSelectElement).value;if(!skinOwner||!skinChoices.some(s=>s.id===id))return;pickTexture(id);});\r\nwindow.addEventListener('myr5:account-ready',event=>void refreshSkinEditor((event as CustomEvent).detail));window.addEventListener('myr5:account-cleared',()=>void refreshSkinEditor(null));window.addEventListener('myr5:battle-pass',()=>void refreshSkinEditor());window.addEventListener('storage',event=>{if(event.key?.startsWith('myr5-battle-pass-ledger-v1/account/')||event.key==='myr5-battle-pass-ledger-v1')void refreshSkinEditor();});\r\nconst installedSections=(event:Event)=>{const detail=(event as CustomEvent).detail;if(!detail||typeof detail!=='object'||typeof detail.ownerId!=='string'||!Array.isArray(detail.sections)||!detail.sections.every((section:unknown)=>typeof section==='string'))return;const active=window.myr5AuthenticatedAccount,owner=typeof active==='string'?active:active?.user?.id;if(owner&&detail.ownerId===owner&&detail.sections.some((section:string)=>section.startsWith('track-')))void refreshSkinEditor(active);};window.addEventListener('myr5:sections-installed',installedSections);\r\nfunction openMenu(tab:HTMLButtonElement,frame=true){if(tab.hidden)return;activeRange=null;for(const b of tabs){const active=b===tab;b.setAttribute('aria-selected',String(active));b.tabIndex=active?0:-1;$(b.getAttribute('aria-controls')!).hidden=!active;}if(tab!==shipTab){shipTab.setAttribute('aria-selected','false');shipPanel.hidden=true;}if(tab.dataset.menu==='face')focusPart('eye',frame);else if(tab.dataset.menu==='body')focusPart('body',frame);else if(tab.dataset.menu==='materials')focusPart(selected,frame);else if(tab.dataset.menu==='skin')syncSkinChoice();void previewShip();(document.querySelector('.console-scroll') as HTMLElement).scrollTop=0;}\r\ntabs.forEach(b=>{b.onclick=()=>openMenu(b);b.onkeydown=event=>{const enabled=tabs.filter(tab=>!tab.hidden),index=enabled.indexOf(b);let next=index;if(event.key==='ArrowRight')next=(index+1)%enabled.length;else if(event.key==='ArrowLeft')next=(index+enabled.length-1)%enabled.length;else if(event.key==='Home')next=0;else if(event.key==='End')next=enabled.length-1;else return;event.preventDefault();openMenu(enabled[next]);enabled[next].focus();};});\r\n// Rank 5: the grid's \"apply to all parts\" copied a legacy style index; with the grid gone, this\r\n// copies the selected part's actual texture+colour+sparkle+metallic choice to every part instead.\r\n$('applyAll').onclick=()=>{const mc=materialChoice();commit({...shown(),materials:Object.fromEntries(REGIONS.map(r=>[r,mc])) as Design['materials']});};\r\n$('undo').onclick=()=>{if(endPreview()||!undo.length)return;activeRange=null;redo.push(recipe);recipe=undo.pop()!;render('Undo applied',true);};\r\n$('redo').onclick=()=>{if(!redo.length)return;activeRange=null;clearPreview();undo.push(recipe);recipe=redo.pop()!;render('Redo applied',true);};\r\n$('original').onclick=()=>{clearPreview();commit(fresh());};\r\n// Done (or the brand link) leaves on the owned look; the preview was never saved.\r\nfor(const a of document.querySelectorAll('.editor-header a,.coach-dock a'))a.addEventListener('click',()=>{endPreview();try{sessionStorage.removeItem(SHIP_GATE);}catch{}});\r\n$('importFile').addEventListener('change',async event=>{const input=event.target as HTMLInputElement,file=input.files?.[0];if(!file)return;try{if(file.size>MAX_IMPORT_BYTES)throw Error('Choose a MYR5 recipe smaller than 64 KB.');clearPreview();commit(importCreature(await file.text()));}catch(error){tell((error as Error).message);}finally{input.value='';}});\r\n$('exportRecipe').onclick=()=>download(new Blob([JSON.stringify(recipe,null,2)],{type:'application/json'}),'myr5-recipe.json');\r\n$('exportGLB').onclick=async()=>{if(!ready||!viewer||previewing())return;try{tell('Preparing your animated model…');download(await viewer.exportGLB(),'myr5-animated.glb');tell('Animated model downloaded');}catch(error){tell((error as Error).message);}};\r\n$('front').onclick=()=>viewer?.resetView();\r\n$('back').onclick=()=>viewer?.resetView(-1);\r\nconst zoom=$('zoom') as HTMLInputElement,setZoom=(z:number)=>{zoom.value=String(viewer?.setZoom(z)??z);};zoom.addEventListener('input',()=>setZoom(Number(zoom.value)));$('zoomIn').onclick=()=>setZoom(Number(zoom.value)+.1);$('zoomOut').onclick=()=>setZoom(Number(zoom.value)-.1);\r\n$('pauseMotion').onclick=()=>{if(!viewer)return;viewer.setPaused(!viewer.paused);$('pauseMotion').textContent=viewer.paused?'Play motion':'Pause motion';$('pauseMotion').setAttribute('aria-pressed',String(viewer.paused));};\r\nfunction applyMotion(){viewer?.setSettings({...settings,reduced:settings.reduced||systemMotion.matches});}\r\nsystemMotion.addEventListener('change',applyMotion);\r\nwindow.addEventListener('storage',event=>{if(event.key===RECIPE_KEY&&event.newValue){try{recipe=saved=ownedLook(importCreature(event.newValue));undo=[];redo=[];activeRange=null;render('Coach updated from another app tab');}catch{tell('An invalid coach update was ignored.');}}});\r\nconst motionIndicator=setInterval(()=>{const current=viewer?.motion?.current;if(!current)return;$('motionLabel').textContent=GESTURES[current].label;},250);\r\nconst disposePreviewIdle=mountPreviewIdle(document.querySelector<HTMLElement>('.preview-bay')!);\r\nwindow.addEventListener('pagehide',()=>{disposePreviewIdle();standaloneAccount.dispose();closeShipPreview();skinEpoch++;skinSource?.dispose();pendingSkinSource?.dispose();skinSource=null;pendingSkinSource=null;window.removeEventListener('myr5:sections-installed',installedSections);clearInterval(motionIndicator);queue.dispose();viewer?.dispose();});\r\n// D34 post-download: listen for body download state from service worker\r\nconst pendingBodyUrls=new Set<string>();let bodyDownloadTimer=0;const originalStatus='Your coach is ready';\r\nnavigator.serviceWorker?.addEventListener('message',({data})=>{\r\n if(data?.type!=='BODY_DOWNLOAD')return;\r\n clearTimeout(bodyDownloadTimer);\r\n if(data.state==='start')pendingBodyUrls.add(data.url);else pendingBodyUrls.delete(data.url);\r\n if(data.state==='unavailable'){tell('This body isn\\'t on this phone yet. Connect to the internet to download it.');bodyDownloadTimer=setTimeout(()=>{tell(originalStatus);},6000);}\r\n else if(pendingBodyUrls.size)tell('Downloading this body…');\r\n else tell(originalStatus);\r\n});\r\ntry{viewer=new CreatureViewer($('creatureStage'),base);applyMotion();viewer.resetView();setZoom(.94);render(initialError||originalStatus);void refreshSkinEditor();(window as any).myr5Companion={get recipe(){return recipe;},get viewer(){return viewer;},get ready(){return ready;},importRecipe:(raw:string)=>commit(importCreature(raw))};}\r\ncatch(error){tell('3D could not start. '+(error as Error).message);}\r\n","creature/source/editor.ts":"export * from './editor-workbench';\r\n","creature/source/idle-cycle.ts":"export const IDLE_INTERVAL=8000;\r\n// Pausing a tour never skips animations or interrupts a live coaching response.\r\nexport class IdleCycle<T extends string> {\r\n index=0;due=0;\r\n constructor(public gestures:readonly T[]){}\r\n next(now:number,eligible:boolean):T|null{\r\n  if(!eligible){this.due=now+IDLE_INTERVAL;return null;}\r\n  if(!this.due){this.due=now+IDLE_INTERVAL;return null;}\r\n  if(now<this.due||!this.gestures.length)return null;\r\n  const id=this.gestures[this.index++%this.gestures.length];this.due=now+IDLE_INTERVAL;return id;\r\n }\r\n}\r\n","creature/source/latest-preview.ts":"// Keep at most one assembly in flight; while it runs, retain only the latest edit.\r\nexport class LatestPreview<T>{\r\n private revision=0;private running=false;private pending:{value:T;revision:number}|null=null;private stopped=false;\r\n constructor(private apply:(value:T)=>Promise<unknown>,private settled:(value:T,error?:unknown)=>void){}\r\n request(value:T){if(this.stopped)return;this.pending={value,revision:++this.revision};void this.drain();}\r\n private async drain(){if(this.running||this.stopped)return;this.running=true;\r\n  while(this.pending&&!this.stopped){const job=this.pending;this.pending=null;let error:unknown;try{await this.apply(job.value);}catch(e){error=e;}\r\n   if(!this.stopped&&job.revision===this.revision)this.settled(job.value,error);\r\n   // Yield between assemblies so a rapid drag can replace the pending request.\r\n   if(this.pending)await new Promise<void>(resolve=>setTimeout(resolve,16));\r\n  }this.running=false;\r\n }\r\n dispose(){this.stopped=true;this.pending=null;this.revision++;}\r\n}\r\n","creature/source/limb-ownership.ts":"/**\r\n * Runtime ownership helpers for source meshes whose authoring cuts put pieces of\r\n * the lower limbs in the arm region. This module deliberately does not delete or\r\n * rewrite source triangles: callers receive triangle-index sets and can bake each\r\n * source triangle exactly once into its selected rig node.\r\n */\r\n\r\nexport type Vec3 = { x: number; y: number; z: number };\r\nexport type Box3Like = { min: Vec3; max: Vec3; isEmpty?: () => boolean };\r\nexport type GeometryLike = {\r\n  getAttribute(name: string): { count: number; getX(i: number): number; getY(i: number): number; getZ(i: number): number };\r\n  index?: { count: number; getX(i: number): number } | null;\r\n};\r\nexport type MeshLike = { geometry: GeometryLike; matrixWorld?: { elements: ArrayLike<number> } };\r\n\r\nexport type OwnershipOptions = {\r\n  /** World-space contact tolerance. Default: max(0.012, 0.008 * feet height). */\r\n  contactTolerance?: number;\r\n  /** Position weld tolerance for identifying shared triangle edges. */\r\n  weldTolerance?: number;\r\n  /** Keep a component in arms if it reaches the body's lower cut boundary. */\r\n  bodyLowerY?: number;\r\n  /** Extend the torso candidate band for a verified source with plates above the hip. */\r\n  bodyUpperFraction?: number;\r\n  /** Raise the small-component cap only for a source with measured larger torso shards. */\r\n  bodyComponentLimit?: number;\r\n  /** Require every corner of a candidate face to lie on the body surface. */\r\n  allVerticesOnBody?: boolean;\r\n};\r\n\r\n/** Copy a complete triangle subset without dropping vertex/morph attributes or reordering faces. */\r\nexport function triangleSubset(source: THREE.BufferGeometry, keep: (triangle: number) => boolean): THREE.BufferGeometry | null {\r\n  const position = source.getAttribute('position'), index = source.index, count = index?.count ?? position.count;\r\n  const remap = new Map<number, number>(), sourceVertices: number[] = [], outIndex: number[] = [];\r\n  for (let i = 0; i + 2 < count; i += 3) {\r\n    if (!keep(i / 3)) continue;\r\n    for (let j = 0; j < 3; j++) {\r\n      const old = index ? index.getX(i + j) : i + j;\r\n      let next = remap.get(old);\r\n      if (next === undefined) { next = sourceVertices.length; remap.set(old, next); sourceVertices.push(old); }\r\n      outIndex.push(next);\r\n    }\r\n  }\r\n  if (!outIndex.length) return null;\r\n  const out = new THREE.BufferGeometry();\r\n  const copyAttribute = (attribute: THREE.BufferAttribute | THREE.InterleavedBufferAttribute) => {\r\n    const interleaved = attribute as THREE.InterleavedBufferAttribute;\r\n    const isInterleaved = (attribute as THREE.InterleavedBufferAttribute).isInterleavedBufferAttribute === true;\r\n    const sourceArray = isInterleaved ? interleaved.data.array : attribute.array;\r\n    const stride = isInterleaved ? interleaved.data.stride : attribute.itemSize;\r\n    const offset = isInterleaved ? interleaved.offset : 0;\r\n    const values = new (sourceArray.constructor as any)(sourceVertices.length * attribute.itemSize);\r\n    for (let i = 0; i < sourceVertices.length; i++) for (let component = 0; component < attribute.itemSize; component++)\r\n      values[i * attribute.itemSize + component] = sourceArray[sourceVertices[i] * stride + offset + component];\r\n    return new THREE.BufferAttribute(values, attribute.itemSize, attribute.normalized);\r\n  };\r\n  for (const [name, attribute] of Object.entries(source.attributes)) out.setAttribute(name, copyAttribute(attribute as THREE.BufferAttribute));\r\n  for (const [name, attributes] of Object.entries(source.morphAttributes)) out.morphAttributes[name] = attributes.map(attribute => copyAttribute(attribute as THREE.BufferAttribute));\r\n  out.morphTargetsRelative = source.morphTargetsRelative;\r\n  out.setIndex(outIndex); out.computeBoundingBox(); out.computeBoundingSphere();\r\n  return out;\r\n}\r\n\r\ntype Point = [number, number, number];\r\ntype Triangle = { id: number; p: [Point, Point, Point]; center: Point; low: boolean };\r\n\r\nconst clampTolerance = (value: number) => Math.max(1e-5, value);\r\nconst distSq = (a: Point, b: Point) => (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2 + (a[2] - b[2]) ** 2;\r\nconst midpoint = (a: Point, b: Point): Point => [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2, (a[2] + b[2]) / 2];\r\n\r\nfunction worldPoint(mesh: MeshLike, i: number): Point {\r\n  const position = mesh.geometry.getAttribute('position');\r\n  const x = position.getX(i), y = position.getY(i), z = position.getZ(i);\r\n  const e = mesh.matrixWorld?.elements;\r\n  if (!e) return [x, y, z];\r\n  const w = e[3] * x + e[7] * y + e[11] * z + e[15];\r\n  const d = w && w !== 1 ? 1 / w : 1;\r\n  return [\r\n    (e[0] * x + e[4] * y + e[8] * z + e[12]) * d,\r\n    (e[1] * x + e[5] * y + e[9] * z + e[13]) * d,\r\n    (e[2] * x + e[6] * y + e[10] * z + e[14]) * d,\r\n  ];\r\n}\r\n\r\nfunction triangleData(mesh: MeshLike): Triangle[] {\r\n  const g = mesh.geometry, position = g.getAttribute('position'), count = g.index?.count ?? position.count;\r\n  const vertex = (i: number) => g.index ? g.index.getX(i) : i;\r\n  const triangles: Triangle[] = [];\r\n  for (let i = 0; i + 2 < count; i += 3) {\r\n    const p: [Point, Point, Point] = [worldPoint(mesh, vertex(i)), worldPoint(mesh, vertex(i + 1)), worldPoint(mesh, vertex(i + 2))];\r\n    triangles.push({id: i / 3, p, center: [(p[0][0] + p[1][0] + p[2][0]) / 3, (p[0][1] + p[1][1] + p[2][1]) / 3, (p[0][2] + p[1][2] + p[2][2]) / 3,], low: false});\r\n  }\r\n  return triangles;\r\n}\r\n\r\nfunction pointKey(p: Point, eps: number) { return `${Math.round(p[0] / eps)},${Math.round(p[1] / eps)},${Math.round(p[2] / eps)}`; }\r\nfunction edgeKey(a: Point, b: Point, eps: number) {\r\n  const ka = pointKey(a, eps), kb = pointKey(b, eps);\r\n  return ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`;\r\n}\r\n\r\n/** Build face adjacency from shared edges, including duplicated/non-indexed seam vertices. */\r\nfunction components(triangles: Triangle[], weldTolerance: number, eligible?: (triangle: Triangle) => boolean) {\r\n  const eligibleIds = new Set(triangles.filter(t => !eligible || eligible(t)).map(t => t.id));\r\n  const edges = new Map<string, number[]>();\r\n  for (const t of triangles) {\r\n    if (!eligibleIds.has(t.id)) continue;\r\n    for (let i = 0; i < 3; i++) {\r\n      const k = edgeKey(t.p[i], t.p[(i + 1) % 3], weldTolerance);\r\n      const list = edges.get(k);\r\n      if (list) list.push(t.id); else edges.set(k, [t.id]);\r\n    }\r\n  }\r\n  const neighbors = new Map<number, Set<number>>();\r\n  for (const ids of edges.values()) {\r\n    if (ids.length < 2) continue;\r\n    for (const id of ids) {\r\n      let set = neighbors.get(id); if (!set) neighbors.set(id, set = new Set());\r\n      for (const other of ids) if (other !== id) set.add(other);\r\n    }\r\n  }\r\n  const byId = new Map(triangles.map(t => [t.id, t]));\r\n  const seen = new Set<number>(), result: Triangle[][] = [];\r\n  for (const id of eligibleIds) {\r\n    if (seen.has(id)) continue;\r\n    seen.add(id); const queue = [id], group: Triangle[] = [];\r\n    for (let q = 0; q < queue.length; q++) {\r\n      const current = queue[q], triangle = byId.get(current)!; group.push(triangle);\r\n      for (const n of neighbors.get(current) ?? []) if (!seen.has(n)) { seen.add(n); queue.push(n); }\r\n    }\r\n    result.push(group);\r\n  }\r\n  return result;\r\n}\r\n\r\n/** Return face-component triangle ids, optionally restricted to a selected set. */\r\nexport function connectedTriangleComponents(mesh: MeshLike, eligibleIds?: ReadonlySet<number>, weldTolerance?: number): number[][] {\r\n  const triangles = triangleData(mesh);\r\n  if (!triangles.length) return [];\r\n  let min = Infinity, max = -Infinity;\r\n  for (const t of triangles) for (const p of t.p) { min = Math.min(min, p[0]); max = Math.max(max, p[0]); }\r\n  const eps = clampTolerance(weldTolerance ?? Math.max(1e-5, (max - min) * 1e-5));\r\n  return components(triangles, eps, eligibleIds ? t => eligibleIds.has(t.id) : undefined).map(group => group.map(t => t.id));\r\n}\r\n\r\n/** Index only open boundary edges of the feet mesh; interior surface contact is not enough. */\r\nfunction boundarySamples(meshes: Iterable<MeshLike>, cell: number, weldTolerance: number) {\r\n  const edges = new Map<string, {count:number; a:Point; b:Point}>();\r\n  for (const mesh of meshes) for (const t of triangleData(mesh)) for (let i = 0; i < 3; i++) {\r\n    const a = t.p[i], b = t.p[(i + 1) % 3], k = edgeKey(a, b, weldTolerance), row = edges.get(k);\r\n    if (row) row.count++;\r\n    else edges.set(k, {count:1, a, b});\r\n  }\r\n  const grid = new Map<string, Point[]>(), key = (p:Point) => `${Math.floor(p[0]/cell)},${Math.floor(p[1]/cell)},${Math.floor(p[2]/cell)}`;\r\n  let total = 0;\r\n  for (const edge of edges.values()) {\r\n    if (edge.count !== 1) continue;\r\n    // Subsamples tolerate small discrepancies from separate decimation passes.\r\n    for (let i = 0; i <= 4; i++) {\r\n      const t = i / 4, p:Point = [edge.a[0] + (edge.b[0] - edge.a[0]) * t, edge.a[1] + (edge.b[1] - edge.a[1]) * t, edge.a[2] + (edge.b[2] - edge.a[2]) * t];\r\n      const k = key(p), row = grid.get(k); if (row) row.push(p); else grid.set(k, [p]); total++;\r\n    }\r\n  }\r\n  return {grid, cell, total};\r\n}\r\n\r\n/** Index the complete body surface (including closed side walls, not just cut edges). */\r\nfunction surfaceSamples(meshes: Iterable<MeshLike>, cell: number) {\r\n  const grid = new Map<string, Point[]>(), key = (p:Point) => `${Math.floor(p[0]/cell)},${Math.floor(p[1]/cell)},${Math.floor(p[2]/cell)}`;\r\n  let total = 0;\r\n  const add = (p:Point) => {const k=key(p),row=grid.get(k);if(row)row.push(p);else grid.set(k,[p]);total++;};\r\n  for (const mesh of meshes) for (const t of triangleData(mesh)) {\r\n    for (let i=0;i<3;i++) {add(t.p[i]);add(midpoint(t.p[i],t.p[(i+1)%3]));}\r\n    add(t.center);\r\n  }\r\n  return {grid,cell,total};\r\n}\r\n\r\nfunction nearSample(p: Point, index: ReturnType<typeof samples>, tolerance: number) {\r\n  const {grid, cell} = index, cx = Math.floor(p[0] / cell), cy = Math.floor(p[1] / cell), cz = Math.floor(p[2] / cell), limit = tolerance * tolerance;\r\n  for (let x = cx - 1; x <= cx + 1; x++) for (let y = cy - 1; y <= cy + 1; y++) for (let z = cz - 1; z <= cz + 1; z++) {\r\n    for (const q of grid.get(`${x},${y},${z}`) ?? []) if (distSq(p, q) <= limit) return true;\r\n  }\r\n  return false;\r\n}\r\n\r\n/**\r\n * Return triangle ids in an `arms` mesh that should be owned by the feet node.\r\n * A candidate must be below the actual feet-region top and belong to a connected\r\n * low component that contacts the actual feet surface within a small tolerance.\r\n * This keeps ordinary hanging hands and disconnected quadruped front legs in\r\n * arms, while recovering lower-leg pieces cut into arms. No triangle is dropped.\r\n *\r\n * `feetMeshes` must be the visible meshes under the assembled source `feet` group,\r\n * in the same world transform as `mesh`. Pass an empty iterable to disable rescue.\r\n */\r\nexport function armFootTriangles(mesh: MeshLike, feetBox: Box3Like, feetMeshes: Iterable<MeshLike>, options: OwnershipOptions = {}): Set<number> {\r\n  if (feetBox.isEmpty?.()) return new Set();\r\n  const height = Math.max(0, feetBox.max.y - feetBox.min.y);\r\n  const tolerance = clampTolerance(options.contactTolerance ?? Math.max(0.012, height * 0.008));\r\n  const weld = clampTolerance(options.weldTolerance ?? Math.max(1e-5, tolerance * 0.02));\r\n  const footIndex = boundarySamples(feetMeshes, tolerance, weld);\r\n  if (!footIndex.total) return new Set();\r\n\r\n  const arm = triangleData(mesh), top = feetBox.max.y + tolerance;\r\n  for (const t of arm) t.low = t.center[1] <= top;\r\n  const low = arm.filter(t => t.low);\r\n  if (!low.length) return new Set();\r\n\r\n  const seeds = new Set<number>();\r\n  for (const t of low) {\r\n    if (t.p.some(p => nearSample(p, footIndex, tolerance)) ||\r\n        nearSample(midpoint(t.p[0], t.p[1]), footIndex, tolerance) ||\r\n        nearSample(midpoint(t.p[1], t.p[2]), footIndex, tolerance) ||\r\n        nearSample(midpoint(t.p[2], t.p[0]), footIndex, tolerance) ||\r\n        nearSample(t.center, footIndex, tolerance)) seeds.add(t.id);\r\n  }\r\n  if (!seeds.size) return new Set();\r\n\r\n  const selected = new Set<number>();\r\n  // Decide ownership from the complete source component. Building connectivity\r\n  // only from low faces can peel a claw/forearm off an otherwise continuous arm\r\n  // when the low section happens to touch a foot cut at the wrist.\r\n  for (const group of components(arm, weld)) {\r\n    const reachesBodyCut = options.bodyLowerY !== undefined && group.some(t => t.p.some(p => p[1] >= options.bodyLowerY! - tolerance));\r\n    // A complete grounded leg can end at the pelvis cut, too. Ground contact\r\n    // distinguishes it from a hanging claw whose top happens to meet that cut.\r\n    const grounded = group.some(t => t.p.some(p => p[1] <= feetBox.min.y + height * .1));\r\n    if ((!reachesBodyCut || grounded) && group.some(t => seeds.has(t.id)) && group.every(t => t.p.every(p => p[1] <= top)))\r\n      for (const t of group) selected.add(t.id);\r\n  }\r\n  return selected;\r\n}\r\n\r\n/**\r\n * Return small, complete lower-torso components in an arm cut that approach the\r\n * body's full surface, including closed side walls. The lower-body band and\r\n * component-size cap keep hands and continuous arms animated as arms; this is\r\n * for detached pelvis/torso shards that the cut-edge-only check can miss.\r\n */\r\nexport function armBodyTriangles(mesh: MeshLike, bodyBox: Box3Like, bodyMeshes: Iterable<MeshLike>, options: OwnershipOptions = {}): Set<number> {\r\n  if (bodyBox.isEmpty?.()) return new Set();\r\n  const height = Math.max(0, bodyBox.max.y - bodyBox.min.y);\r\n  if (!height) return new Set();\r\n  const tolerance = clampTolerance(options.contactTolerance ?? Math.max(0.018, height * 0.014));\r\n  const weld = clampTolerance(options.weldTolerance ?? Math.max(1e-5, tolerance * 0.02));\r\n  const bodyIndex = surfaceSamples(bodyMeshes, tolerance);\r\n  if (!bodyIndex.total) return new Set();\r\n  const triangles = triangleData(mesh), lowerTop = bodyBox.min.y + height * (options.bodyUpperFraction ?? 0.4);\r\n  if (!triangles.length) return new Set();\r\n  const maximum = Math.min(300, options.bodyComponentLimit ?? Math.max(200, Math.floor(triangles.length * 0.06)));\r\n  const selected = new Set<number>();\r\n  // Keep connected pieces intact. Lower arm-cut scraps are body owned when they\r\n  // sit in the pelvis band and approach any body surface; checking only open\r\n  // cut edges misses pieces against a closed body side wall.\r\n  for (const group of components(triangles, weld)) {\r\n    if (group.length > maximum) continue;\r\n    let minY=Infinity,maxY=-Infinity,nearBody=false;\r\n    for(const t of group) for(const p of t.p){minY=Math.min(minY,p[1]);maxY=Math.max(maxY,p[1]);if(!nearBody&&nearSample(p,bodyIndex,tolerance))nearBody=true;}\r\n    if(nearBody&&minY>=bodyBox.min.y-height*.03&&maxY<=lowerTop)for(const t of group)selected.add(t.id);\r\n  }\r\n  return selected;\r\n}\r\n\r\n/**\r\n * Select only torso-side faces in a narrow hip band when they are welded into a\r\n * larger animated arm component. This keeps the actual arm connected and moving\r\n * while assigning the small faces that overlap the body cut to BodyMotion.\r\n */\r\nexport function armBodyBandTriangles(mesh: MeshLike, bodyBox: Box3Like, bodyMeshes: Iterable<MeshLike>, options: OwnershipOptions = {}): Set<number> {\r\n  if (bodyBox.isEmpty?.()) return new Set();\r\n  const height = Math.max(0, bodyBox.max.y - bodyBox.min.y);\r\n  if (!height) return new Set();\r\n  const tolerance = clampTolerance(options.contactTolerance ?? Math.max(0.018, height * 0.014));\r\n  const bodyIndex = surfaceSamples(bodyMeshes, tolerance);\r\n  if (!bodyIndex.total) return new Set();\r\n  const bottom = bodyBox.min.y - height * 0.03;\r\n  const top = bodyBox.min.y + height * (options.bodyUpperFraction ?? 0.45);\r\n  const selected = new Set<number>();\r\n  for (const triangle of triangleData(mesh)) {\r\n    const points = [...triangle.p, midpoint(triangle.p[0], triangle.p[1]), midpoint(triangle.p[1], triangle.p[2]), midpoint(triangle.p[2], triangle.p[0]), triangle.center];\r\n    const onBody=options.allVerticesOnBody?triangle.p.every(point=>nearSample(point,bodyIndex,tolerance)):points.some(point=>nearSample(point,bodyIndex,tolerance));\r\n    if (triangle.center[1] >= bottom && triangle.center[1] <= top && onBody) selected.add(triangle.id);\r\n  }\r\n  return selected;\r\n}\r\n\r\n/** Arm-cut faces whose centers fall just below a source body's bottom cut; intended for continuous tail shells. */\r\nexport function trianglesBelowBodyCut(mesh: MeshLike, bodyCutY: number, cutTolerance = 0): Set<number> {\r\n  const selected = new Set<number>();\r\n  for (const triangle of triangleData(mesh)) if (triangle.center[1] <= bodyCutY + Math.max(0, cutTolerance)) selected.add(triangle.id);\r\n  return selected;\r\n}\r\n\r\n/** Move only complete, floor-grounded source components below a continuous-tail body cut. */\r\nexport function groundedComponentsBelowBodyCut(mesh: MeshLike, bodyCutY: number, feetBox: Box3Like, cutTolerance = 0): Set<number> {\r\n  const selected = new Set<number>(), triangles = triangleData(mesh), height = feetBox.max.y - feetBox.min.y;\r\n  if (!(height > 0)) return selected;\r\n  for (const component of connectedTriangleComponents(mesh)) {\r\n    let minY = Infinity, maxY = -Infinity;\r\n    for (const id of component) for (const point of triangles[id].p) { minY = Math.min(minY, point[1]); maxY = Math.max(maxY, point[1]); }\r\n    if (minY <= feetBox.min.y + height * .1 && maxY <= bodyCutY + Math.max(0, cutTolerance)) for (const id of component) selected.add(id);\r\n  }\r\n  return selected;\r\n}\r\n\r\n/** Select whole detached foot-cut components that are really side hands. */\r\nexport function detachedHandTriangles(\r\n  mesh: MeshLike,\r\n  feetBox: Box3Like,\r\n  feetMeshes: Iterable<MeshLike>,\r\n  armsBox: Box3Like,\r\n  armsMeshes: Iterable<MeshLike>,\r\n  bodyBox: Box3Like,\r\n  bodyMeshes: Iterable<MeshLike>,\r\n  lowerBodyBox: Box3Like,\r\n  options: {maxComponentTriangles?: number} = {},\r\n): Set<number> {\r\n  if (feetBox.isEmpty?.() || armsBox.isEmpty?.() || bodyBox.isEmpty?.() || lowerBodyBox.isEmpty?.()) return new Set();\r\n  const floor = feetBox.min.y, footHeight = feetBox.max.y - floor;\r\n  if (!(footHeight > 0) || !(bodyBox.max.y > bodyBox.min.y)) return new Set();\r\n  const armContact = armFootTriangles(mesh, armsBox, armsMeshes);\r\n  if (!armContact.size) return new Set();\r\n  const bodyContact = armFootTriangles(mesh, bodyBox, bodyMeshes);\r\n  const triangles = triangleData(mesh), weld = clampTolerance(Math.max(1e-5, footHeight * 0.00016));\r\n  const selected = new Set<number>();\r\n  for (const group of components(triangles, weld)) {\r\n    if (group.length > (options.maxComponentTriangles ?? 600) || !group.some(t => armContact.has(t.id)) || group.some(t => bodyContact.has(t.id))) continue;\r\n    let minY = Infinity, centerX = 0, count = 0;\r\n    for (const triangle of group) for (const p of triangle.p) { minY = Math.min(minY, p[1]); centerX += p[0]; count++; }\r\n    centerX /= count;\r\n    const ungrounded = minY > floor + footHeight * 0.1;\r\n    const outsideLowerBody = centerX < lowerBodyBox.min.x || centerX > lowerBodyBox.max.x;\r\n    if (ungrounded && outsideLowerBody) for (const triangle of group) selected.add(triangle.id);\r\n  }\r\n  return selected;\r\n}\r\n\r\n/**\r\n * Assign complete connected components to left (-1), right (+1), or neutral (0).\r\n * Neutral means the component crosses the centerline or is too close to call.\r\n * The caller must resolve neutral ownership for that source; a valid fused limb\r\n * component can remain animated with a centroid-side fallback when appropriate.\r\n */\r\nexport function connectedComponentSides(mesh: MeshLike, centerX = 0, options: OwnershipOptions = {}): Int8Array {\r\n  const triangles = triangleData(mesh), result = new Int8Array(triangles.length);\r\n  if (!triangles.length) return result;\r\n  const xs = triangles.flatMap(t => t.p.map(p => p[0]));\r\n  const width = Math.max(...xs) - Math.min(...xs);\r\n  const weld = clampTolerance(options.weldTolerance ?? Math.max(1e-5, width * 1e-5));\r\n  const deadband = Math.max(1e-5, width * 0.015);\r\n  for (const group of components(triangles, weld)) {\r\n    let sum = 0, min = Infinity, max = -Infinity, count = 0;\r\n    for (const t of group) for (const p of t.p) { sum += p[0]; min = Math.min(min, p[0]); max = Math.max(max, p[0]); count++; }\r\n    const center = sum / count - centerX;\r\n    const crossesCenter = min < centerX - deadband && max > centerX + deadband;\r\n    let side = crossesCenter || Math.abs(center) <= deadband ? 0 : Math.sign(center);\r\n    if (!side && !crossesCenter && min >= centerX - weld) side = 1;\r\n    else if (!side && !crossesCenter && max <= centerX + weld) side = -1;\r\n    // A fused component spanning the center remains whole and neutral.\r\n    for (const t of group) result[t.id] = side;\r\n  }\r\n  return result;\r\n}\r\nimport * as THREE from 'three';\r\n","creature/source/motion.ts":"import * as T from 'three';\r\nimport type {CreatureRig} from './rig';\r\nexport const GESTURES={\r\n idle:{label:'At ease',duration:7,loop:true},listening:{label:'Listening',duration:4,loop:true},thinking:{label:'Thinking',duration:5,loop:true},speaking:{label:'Speaking',duration:3.6,loop:true},\r\n greet:{label:'Hello',duration:2.6,loop:false},agree:{label:'Yes / understood',duration:1.9,loop:false},correct:{label:'Gentle correction',duration:2.4,loop:false},encourage:{label:'Encouragement',duration:2.8,loop:false},celebrate:{label:'Celebrate',duration:3.2,loop:false},rest:{label:'Take a breath',duration:5,loop:true},laugh:{label:'Giant laugh',duration:3.4,loop:false},swipe:{label:'Platform sweep',duration:1.8,loop:false}\r\n ,awaken:{label:'Pod awakening',duration:4.8,loop:false},ready:{label:'Ready to train',duration:3.3,loop:false},victory:{label:'Effort earned',duration:3.8,loop:false},walk:{label:'Walking',duration:.9,loop:true},wiggle:{label:'Wiggle',duration:.6,loop:true}\r\n} as const;\r\nexport type Gesture=keyof typeof GESTURES;\r\nexport function gestureForCue(key:string){return ({count:'agree',complete:'celebrate',ready:'greet',tracking:'correct',setup:'listening',time:'encourage'} as Record<string,Gesture>)[key]||'speaking';}\r\nexport function samplePose(id:Gesture,t:number){\r\n const d=GESTURES[id].duration,u=t/d,s=Math.sin(u*Math.PI*2),envelope=Math.sin(Math.PI*u)**2;\r\n const p={headX:0,headY:0,headZ:0,bodyX:0,bodyZ:0,bodyY:0,leftX:0,leftZ:0,rightX:0,rightZ:0,breath:0,footLX:0,footRX:0,footLY:0,footRY:0,footLZ:0,footRZ:0};\r\n if(id==='idle'){p.headY=.045*s;p.headZ=.018*Math.sin(u*Math.PI*4);p.breath=.009*s;p.leftX=.02*s;p.rightX=-.015*s;}\r\n if(id==='listening'){p.headZ=-.085*(.5-.5*Math.cos(u*Math.PI*2));p.headX=.03*s;}\r\n if(id==='thinking'){p.headY=.10*s;p.headZ=.055*(1-Math.cos(u*Math.PI*2));p.rightX=-.06*s;}\r\n if(id==='speaking'){p.headX=.035*s;p.headZ=.02*Math.sin(u*Math.PI*4);p.rightX=.13*s;p.rightZ=.07*(1-Math.cos(u*Math.PI*2));p.leftX=-.06*s;}\r\n if(id==='greet'){p.rightZ=.27*envelope;p.rightX=.2*Math.sin(u*Math.PI*8)*envelope;p.headZ=-.06*envelope;}\r\n if(id==='agree'){p.headX=.15*Math.sin(u*Math.PI*4)*envelope;p.rightZ=.05*envelope;}\r\n if(id==='correct'){p.headY=.16*Math.sin(u*Math.PI*4)*envelope;p.rightZ=.12*envelope;}\r\n if(id==='encourage'){p.headX=.10*Math.sin(u*Math.PI*4)*envelope;p.leftZ=-.15*envelope;p.rightZ=.18*envelope;p.bodyZ=.02*s*envelope;}\r\n if(id==='celebrate'){p.leftZ=-.45*envelope;p.rightZ=.33*envelope;p.headZ=.06*s*envelope;p.bodyY=.08*envelope*(.5+.5*Math.sin(u*Math.PI*6));}\r\n if(id==='rest'){p.breath=.015*s;p.headX=.025*s;p.leftX=.025*s;}\r\n if(id==='laugh'){const chuckle=Math.sin(u*Math.PI*14)*envelope;p.headX=-.2*envelope+.12*chuckle;p.headZ=.08*chuckle;p.bodyX=-.05*envelope;p.bodyY=.055*chuckle;p.leftZ=-.18*envelope;p.rightZ=.2*envelope;p.breath=.045*Math.abs(chuckle);}\r\n if(id==='swipe'){const sweep=Math.sin(u*Math.PI)*Math.sin(u*Math.PI);p.bodyZ=-.12*sweep;p.headY=.22*Math.sin(u*Math.PI*2)*sweep;p.rightZ=1.15*Math.sin(u*Math.PI*2)*sweep;p.rightX=-.65*sweep;p.leftZ=-.16*sweep;p.bodyY=-.06*sweep;}\r\n if(id==='awaken'){p.headX=.24*(1-u)*envelope;p.headY=-.14*Math.sin(u*Math.PI*2)*envelope;p.bodyY=.08*envelope;p.leftZ=-.17*envelope;p.rightZ=.27*envelope;p.breath=.028*envelope;}\r\n if(id==='ready'){p.headX=.16*Math.sin(u*Math.PI*2)*envelope;p.leftZ=-.36*envelope;p.rightZ=.42*envelope;p.leftX=-.24*envelope;p.rightX=-.32*envelope;p.bodyY=-.045*envelope;p.breath=.018*envelope;}\r\n if(id==='victory'){p.leftZ=-.65*envelope;p.rightZ=.68*envelope;p.headX=-.12*envelope;p.headZ=.08*Math.sin(u*Math.PI*2)*envelope;p.bodyY=.09*envelope;p.breath=.026*envelope;}\r\n // One stride per foot: feet swing and lift in turn, the body waddles over the planted foot, arms swing opposite.\r\n if(id==='walk'){p.footLX=-.55*s;p.footRX=.55*s;p.footLZ=.18*s;p.footRZ=-.18*s;p.footLY=.16*Math.max(0,s);p.footRY=.16*Math.max(0,-s);p.bodyY=.05*Math.abs(s);p.bodyZ=.09*s;p.headZ=-.05*s;p.leftX=.45*s;p.rightX=-.45*s;p.leftZ=-.08;p.rightZ=.08;}\r\n // Dangling by the head: arms and feet swing fast in opposite directions with a small body twist.\r\n if(id==='wiggle'){const w=Math.sin(u*Math.PI*4);p.leftZ=-.35*w;p.rightZ=.35*w;p.footLZ=.22*w;p.footRZ=-.22*w;p.bodyZ=.08*w;p.headZ=-.04*w;}\r\n return p;\r\n}\r\nexport function createClips(rig:CreatureRig){\r\n return Object.entries(GESTURES).map(([name,meta])=>{\r\n  const count=Math.ceil(meta.duration*24),times=Array.from({length:count+1},(_,i)=>meta.duration*i/count);\r\n  const pose=times.map(t=>samplePose(name as Gesture,t)),tracks:T.KeyframeTrack[]=[];\r\n  const rotations:Record<string,(p:ReturnType<typeof samplePose>)=>number[]>={HeadMotion:p=>[p.headX,p.headY,p.headZ],BodyMotion:p=>[p.bodyX,0,p.bodyZ],ArmLeft:p=>[p.leftX,0,p.leftZ],ArmRight:p=>[p.rightX,0,p.rightZ]};\r\n  for(const [node,get] of Object.entries(rotations)){tracks.push(new T.QuaternionKeyframeTrack(node+'.quaternion',times,pose.flatMap(p=>{const [x,y,z]=get(p);return new T.Quaternion().setFromEuler(new T.Euler(x,y,z)).toArray();})));}\r\n  tracks.push(new T.VectorKeyframeTrack('BodyMotion.position',times,pose.flatMap(p=>[0,rig.rest.BodyMotion.position.y+p.bodyY,0])));\r\n  for(const [node,x,y,z] of [['FootLeft','footLX','footLY','footLZ'],['FootRight','footRX','footRY','footRZ']] as const){const rest=rig.rest[node].position;tracks.push(new T.QuaternionKeyframeTrack(node+'.quaternion',times,pose.flatMap(p=>new T.Quaternion().setFromEuler(new T.Euler(p[x],0,0)).toArray())));tracks.push(new T.VectorKeyframeTrack(node+'.position',times,pose.flatMap(p=>[rest.x,rest.y+p[y],rest.z+p[z]])));}\r\n  tracks.push(new T.VectorKeyframeTrack('BodyMotion.scale',times,pose.flatMap(p=>[1+p.breath*.3,1+p.breath,1+p.breath*.3])));\r\n  for(const node of Object.keys(rig.nodes).filter(n=>n.startsWith('EyeBlink'))){const mid=meta.duration*.55;tracks.push(new T.VectorKeyframeTrack(node+'.scale',[0,mid,mid+.10,mid+.23,meta.duration],[1,1,1,1,1,1,1,.06,1,1,1,1,1,1,1]));}\r\n  return new T.AnimationClip(name,meta.duration,tracks);\r\n });\r\n}\r\nexport class MotionController {\r\n rig:CreatureRig;mixer:T.AnimationMixer;clips:T.AnimationClip[];current:Gesture='idle';action:T.AnimationAction;ambient=true;reduced=false;paused=false;amount=1.5;clock=0;nextBlink=3.4;blinkStart=-100;\r\n actions=new Map<Gesture,T.AnimationAction>();\r\n private rawPose=new Map<string,{position:T.Vector3;quaternion:T.Quaternion;scale:T.Vector3}>();\r\n // #149 meditation: asleep = eyes held shut, no gesture or ambient motion, just a slow 4 s breathing bob (none under reduced motion).\r\n sleeping=false;\r\n constructor(rig:CreatureRig){this.rig=rig;this.clips=createClips(rig);this.mixer=new T.AnimationMixer(rig.root);for(const clip of this.clips){const action=this.mixer.clipAction(clip);const id=clip.name as Gesture;action.setLoop(GESTURES[id].loop?T.LoopRepeat:T.LoopOnce,GESTURES[id].loop?Infinity:1);action.clampWhenFinished=!GESTURES[id].loop;this.actions.set(id,action);}this.action=this.actions.get('idle')!;this.action.play();this.mixer.addEventListener('finished',()=>this.play('idle'));}\r\n play(id:Gesture){if(!Object.hasOwn(GESTURES,id))return;if(this.current===id&&GESTURES[id].loop)return;const next=this.actions.get(id)!;for(const action of this.actions.values())if(action!==this.action&&action!==next)action.stop();if(next===this.action)next.reset().play();else{this.action.fadeOut(.22);next.reset().setEffectiveTimeScale(1).setEffectiveWeight(1).fadeIn(.22).play();}this.action=next;this.current=id;}\r\n update(dt:number){\r\n  if(this.paused)return;dt=Math.min(.05,Math.max(0,dt));this.clock+=dt;\r\n  // AnimationMixer may skip writes when a sampled track value has not changed. Since the pose below\r\n  // is weighted in place, feeding that weighted pose into the next sample can accumulate drift.\r\n  // Restore the last unweighted mixed pose before updating: this preserves constant non-rest\r\n  // plateaus while ensuring motion strength is applied once, even at the supported 1.5x setting.\r\n  for(const [name,node] of Object.entries(this.rig.nodes)){if(name.startsWith('EyeBlink'))continue;const pose=this.rawPose.get(name),rest=this.rig.rest[name];node.position.copy(pose?.position??rest.position);node.quaternion.copy(pose?.quaternion??rest.quaternion);node.scale.copy(pose?.scale??rest.scale);}\r\n  this.mixer.update(dt);\r\n  for(const [name,node] of Object.entries(this.rig.nodes)){if(name.startsWith('EyeBlink'))continue;let pose=this.rawPose.get(name);if(!pose){pose={position:new T.Vector3(),quaternion:new T.Quaternion(),scale:new T.Vector3()};this.rawPose.set(name,pose);}pose.position.copy(node.position);pose.quaternion.copy(node.quaternion);pose.scale.copy(node.scale);}\r\n  // Scale the finished mixed pose from rest, so editor changes never accumulate.\r\n  const strength=this.reduced||this.sleeping?0:(this.current==='idle'&&!this.ambient?0:this.amount);\r\n  for(const [name,node] of Object.entries(this.rig.nodes)){const rest=this.rig.rest[name];if(name.startsWith('EyeBlink'))continue;const position=node.position.clone(),scale=node.scale.clone();node.quaternion.slerpQuaternions(rest.quaternion,node.quaternion.clone(),strength);node.position.copy(rest.position).lerp(position,strength);node.scale.copy(rest.scale).lerp(scale,strength);}\r\n  if(this.clock>=this.nextBlink){this.blinkStart=this.clock;this.nextBlink=this.clock+3.8+Math.random()*2.5;}\r\n  const phase=(this.clock-this.blinkStart)/.23,blink=!this.reduced&&this.ambient&&phase>=0&&phase<=1?Math.sin(phase*Math.PI)**2:0;\r\n  for(const [name,node] of Object.entries(this.rig.nodes))if(name.startsWith('EyeBlink'))node.scale.y=1-.94*(this.sleeping?1:blink);\r\n  if(this.sleeping&&!this.reduced){const b=Math.sin(this.clock*Math.PI/2),body=this.rig.nodes.BodyMotion,rest=this.rig.rest.BodyMotion;if(body){body.position.y=rest.position.y+.03*b;body.scale.set(rest.scale.x*(1+.006*b),rest.scale.y*(1+.02*b),rest.scale.z*(1+.006*b));}}\r\n }\r\n neutral(){this.mixer.stopAllAction();for(const [name,node] of Object.entries(this.rig.nodes)){const r=this.rig.rest[name];node.position.copy(r.position);node.scale.copy(r.scale);node.quaternion.copy(r.quaternion);if(!name.startsWith('EyeBlink')){let pose=this.rawPose.get(name);if(!pose){pose={position:new T.Vector3(),quaternion:new T.Quaternion(),scale:new T.Vector3()};this.rawPose.set(name,pose);}pose.position.copy(r.position);pose.quaternion.copy(r.quaternion);pose.scale.copy(r.scale);}}}\r\n dispose(){this.mixer.stopAllAction();this.mixer.uncacheRoot(this.rig.root);}\r\n}\r\n","creature/source/petal-wisp-ownership.ts":"import * as THREE from 'three';\r\nimport {connectedTriangleComponents, triangleSubset} from './limb-ownership';\r\n\r\nconst IYENG_ARC = 'roster/10-petal-wisp--stylized_creature_3d_model';\r\n\r\n/** Restore Iyeng-Arc's complete opposite fin/arm after the broad foot-cut repair. */\r\nexport function correctPetalWispArmOwnership(source: THREE.Group, sourceId: string): number {\r\n  if (sourceId !== IYENG_ARC) return 0;\r\n  source.updateWorldMatrix(true, true);\r\n  const arms = source.getObjectByName('arms'), feet = source.getObjectByName('feet');\r\n  if (!arms || !feet) return 0;\r\n  let armMaterial: THREE.Material | undefined;\r\n  arms.traverse(o => { if (!armMaterial && o instanceof THREE.Mesh && o.visible && !Array.isArray(o.material)) armMaterial = o.material; });\r\n  if (!armMaterial) return 0;\r\n  const toArms = arms.matrixWorld.clone().invert();\r\n  let recovered = 0;\r\n  const meshes: THREE.Mesh[] = [];\r\n  feet.traverse(o => { if (o instanceof THREE.Mesh && o.visible && !Array.isArray(o.material)) meshes.push(o); });\r\n  for (const mesh of meshes) {\r\n    const position = mesh.geometry.getAttribute('position'), index = mesh.geometry.index, selected = new Set<number>();\r\n    for (const component of connectedTriangleComponents(mesh)) {\r\n      if (component.length !== 581 && component.length !== 732) continue;\r\n      const bounds = new THREE.Box3();\r\n      for (const face of component) for (let k = 0; k < 3; k++) {\r\n        const vertex = index ? index.getX(face * 3 + k) : face * 3 + k;\r\n        bounds.expandByPoint(new THREE.Vector3().fromBufferAttribute(position, vertex).applyMatrix4(mesh.matrixWorld));\r\n      }\r\n      const isArmSection=component.length===581&&bounds.min.x>.59&&bounds.min.x<.62&&bounds.max.x>.88&&bounds.max.x<.92&&bounds.min.y>.67&&bounds.min.y<.70&&bounds.max.y>1.27&&bounds.max.y<1.33;\r\n      const isAttachedFin=component.length===732&&bounds.min.x>.28&&bounds.min.x<.31&&bounds.max.x>.59&&bounds.max.x<.62&&bounds.min.y>.75&&bounds.min.y<.78&&bounds.max.y>1.46&&bounds.max.y<1.48;\r\n      if (isArmSection||isAttachedFin) component.forEach(face => selected.add(face));\r\n    }\r\n    if (!selected.size) continue;\r\n    const original = mesh.geometry, armPart = triangleSubset(original, face => selected.has(face)), remainder = triangleSubset(original, face => !selected.has(face));\r\n    if (!armPart) continue;\r\n    armPart.applyMatrix4(toArms.clone().multiply(mesh.matrixWorld));\r\n    recovered += selected.size;\r\n    if (remainder) { mesh.geometry = remainder; original.dispose(); }\r\n    else { mesh.removeFromParent(); original.dispose(); }\r\n    const recoveredArm = new THREE.Mesh(armPart, armMaterial);\r\n    recoveredArm.name = 'Iyeng-Arc recovered arm section';\r\n    recoveredArm.userData.region = 'arms';\r\n    recoveredArm.userData.petalWispRecoveredArmTriangles = selected.size;\r\n    arms.add(recoveredArm);\r\n    const prior = Number(mesh.userData.recoveredArmFootTriangles) || 0;\r\n    mesh.userData.recoveredArmFootTriangles = Math.max(0, prior - selected.size);\r\n  }\r\n  source.updateWorldMatrix(true, true);\r\n  source.userData.petalWispRecoveredArmTriangles = recovered;\r\n  return recovered;\r\n}\r\n","creature/source/phone-motion.ts":"import {subscribePhoneMotion as subscribe} from '../../character-phone-sensor.mjs';\r\n\r\nexport type PhoneMotionSample={gx:number;gy:number;shake:number;angularSpeed:number;timeSeconds:number};\r\n\r\n/** Keep the sensor connection scoped to the customizer viewer's visible lifetime. */\r\nexport function subscribePhoneMotion(callback:(sample:PhoneMotionSample)=>void){\r\n return subscribe(callback);\r\n}\r\n","creature/source/phone.ts":"import {CreatureViewer} from './viewer';\r\nimport {GESTURES,gestureForCue,type Gesture} from './motion';\r\nimport {loadRecipe,RECIPE_KEY,MOTION_KEY,motionSettings,importCreature,REGIONS} from './profile';\r\nimport type {Cinematic} from './cinematic-shots';\r\nimport {IdleCycle} from './idle-cycle';\r\nimport {createInstalledCreatureSkinSource} from '../../modules/materials/installed-creature-skins.mjs';\r\nexport {importCreature};\r\nconst base=new URL('../',import.meta.url).href;\r\nconst view=document.getElementById('view');\r\nif(view){\r\n const card=document.createElement('aside');card.className='myr5-companion-card';card.setAttribute('aria-label','Your MYR5 coach');\r\n const stage=document.createElement('div');stage.className='myr5-companion-stage';\r\n const edit=document.createElement('a');edit.href=new URL('index.html',base).href;edit.textContent='Customize MYR5';edit.className='myr5-customize';\r\n const status=document.createElement('span');status.className='myr5-companion-status';status.textContent='Waking up…';status.setAttribute('role','status');\r\n const hide=document.createElement('button');hide.className='myr5-hide';hide.textContent='Hide creature';hide.setAttribute('aria-expanded','true');\r\n card.append(stage,status,edit,hide);view.append(card);\r\n let viewer:CreatureViewer|null=null,previewing:string|null=null,sleeping=false,lastCaption='',lastCueAt=0,holdUntil=0,epoch=0,closed=false,shown=true,voiceActive=false,walking=false,skinSource:ReturnType<typeof createInstalledCreatureSkinSource>|null=null,pendingSkinSource:ReturnType<typeof createInstalledCreatureSkinSource>|null=null,skinOwner:string|null=null,skinNotice:string|null=null,skinEpoch=0;\r\n let yielded=false;\r\n const gpuBlocked=()=>[...((globalThis as any).__myr5Graphics?.claims||[])].some((c:any)=>!c.keep?.includes('coach'));\r\n const tour=new IdleCycle((Object.keys(GESTURES) as Gesture[]).filter(g=>g!=='walk'&&g!=='wiggle'));\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n function settings(){let s=motionSettings(null);try{s=motionSettings(localStorage.getItem(MOTION_KEY));}catch{}viewer?.setSettings({...s,reduced:s.reduced||reduced.matches});}\r\n async function updateRecipe(raw?:string){const run=++epoch;card.dataset.ready='false';status.textContent=skinNotice||'Loading coach…';try{if(!viewer){if(gpuBlocked()){yielded=true;return false;}viewer=new CreatureViewer(stage,base,false);settings();}const recipe=raw?importCreature(raw):previewing?importCreature(previewing):loadRecipe(localStorage),active=window.myr5AuthenticatedAccount,owner=typeof active==='string'?active:active?.user?.id;let choices:Record<string,string>={};try{choices=owner?JSON.parse(localStorage.getItem('myr5-editor-skins-v1/account/'+owner)||'{}'):{};}catch{}for(const region of REGIONS){const choice=recipe.materials?.[region];if(choice?.textureId.startsWith('creature-'))choice.textureId='clay';const id=choices?.[region];if(typeof id==='string'&&id.startsWith('creature-'))recipe.materials={...recipe.materials,[region]:{textureId:id,colorId:choice?.colorId??'#7f7d78',sparkle:choice?.sparkle??0,metallic:choice?.metallic??0}};}const loaded=await viewer.setRecipe(recipe);if(!loaded||run!==epoch||closed)return;if(viewer.motion)viewer.motion.sleeping=sleeping;card.dataset.ready='true';status.textContent=skinNotice||'MYR5';const giant=document.body.dataset.screen==='rest';viewer.setStage(viewer.stage==='overlay'?'overlay':giant?'encounter':'pod');viewer.play(giant?'laugh':'greet');holdUntil=performance.now()+(giant?3700:2800);return true;}catch(error){if(run===epoch&&!closed){status.textContent=skinNotice||(error as Error).message;return false;}}}\r\n async function refreshInstalledSkins(account=window.myr5AuthenticatedAccount){const run=++skinEpoch,owner=typeof account==='string'?account:typeof account?.user?.id==='string'?account.user.id:null,ownerChanged=owner!==skinOwner;skinOwner=owner;if(ownerChanged){skinNotice=null;skinSource?.dispose();skinSource=null;pendingSkinSource?.dispose();pendingSkinSource=null;viewer?.clearSkinState();viewer?.setSkinResolver(undefined);void updateRecipe();}if(!owner){pendingSkinSource?.dispose();pendingSkinSource=null;return;}pendingSkinSource?.dispose();const source=createInstalledCreatureSkinSource({account});pendingSkinSource=source;let rows;try{rows=await source.list();}catch{const active=window.myr5AuthenticatedAccount,activeOwner=typeof active==='string'?active:active?.user?.id;if(closed||run!==skinEpoch||activeOwner!==owner||skinOwner!==owner){source.dispose();if(pendingSkinSource===source)pendingSkinSource=null;return;}if(pendingSkinSource===source)pendingSkinSource=null;source.dispose();skinSource?.dispose();skinSource=null;viewer?.clearSkinState();viewer?.setSkinResolver(undefined);skinNotice='Could not verify installed skins. Check your extra packs and try again.';void updateRecipe();return;}const active=window.myr5AuthenticatedAccount,activeOwner=typeof active==='string'?active:active?.user?.id;if(closed||run!==skinEpoch||activeOwner!==owner||skinOwner!==owner){source.dispose();if(pendingSkinSource===source)pendingSkinSource=null;return;}if(pendingSkinSource===source)pendingSkinSource=null;if(!rows.length){source.dispose();skinSource?.dispose();skinSource=null;viewer?.clearSkinState();viewer?.setSkinResolver(undefined);skinNotice='No verified installed skins. Check your extra packs and try again.';void updateRecipe();return;}const previous=skinSource;skinSource=source;previous?.dispose();skinNotice=null;viewer?.setSkinResolver(source.resolve);void updateRecipe();}\r\n function play(id:Gesture,duration=GESTURES[id]?.duration*1000+300){if(walking&&id!=='walk')return;if(!shown||viewer?.cinematicKind||!Object.hasOwn(GESTURES,id))return;viewer?.play(id);holdUntil=performance.now()+duration;}\r\n // Live cue keys are explicit; user-authored text never becomes executable data.\r\n const cue=(event:Event)=>{const d=(event as CustomEvent).detail;if(!d||typeof d.key!=='string')return;lastCueAt=performance.now();play(gestureForCue(d.key));};\r\n window.addEventListener('myr5:cue',cue);\r\n const response=(event:Event)=>{const detail=(event as CustomEvent).detail,state=detail?.state;const map:Record<string,Gesture>={listening:'listening',thinking:'thinking',speaking:'speaking',idle:'idle'};if(!Object.hasOwn(map,state))return;voiceActive=state==='speaking';if(state==='speaking'&&performance.now()<holdUntil&&viewer?.motion?.current!=='speaking')return;if(state==='idle'&&viewer?.motion?.current!=='speaking'&&performance.now()<holdUntil)return;play(map[state],state==='idle'?0:15000);};\r\n window.addEventListener('myr5:response',response);\r\n // Captions from existing controls also prompt a speaking pose. The explicit\r\n // cue takes precedence, and repeated caption text does not restart gestures.\r\n const caption=document.getElementById('coachCaption');const observer=new MutationObserver(()=>{const text=caption?.textContent||'';if(text&&text!==lastCaption){lastCaption=text;if(performance.now()-lastCueAt>120&&performance.now()>holdUntil)play('speaking',Math.min(14000,1200+text.length*80));}});if(caption)observer.observe(caption,{childList:true,characterData:true,subtree:true});\r\n const timer=setInterval(()=>{const now=performance.now(),busy=closed||!viewer?.motion||card.dataset.ready!=='true'||!shown||document.hidden||!!document.querySelector('dialog[open]')||!!viewer?.cinematicKind||now<holdUntil||voiceActive||document.body.dataset.tracking==='true'||reduced.matches;viewer?.setHomeMotion(!busy);const next=tour.next(now,!busy);if(closed||!viewer?.motion||card.dataset.ready!=='true'||!shown||document.hidden)return;if(next)viewer.play(next);else if(now>holdUntil&&!viewer.cinematicKind&&(voiceActive||document.body.dataset.tracking==='true')){const cue=walking?'walk':voiceActive?'speaking':'listening';if(viewer.motion.current!==cue)viewer.play(cue);}const label=GESTURES[viewer.motion.current].label;if(status.textContent!==(skinNotice||label))status.textContent=skinNotice||label;},200);\r\n const storage=(event:StorageEvent)=>{if(event.key===MOTION_KEY)settings();if(event.key===RECIPE_KEY)void updateRecipe(event.newValue||undefined);if(event.key?.startsWith('myr5-battle-pass-ledger-v1/account/')||event.key==='myr5-battle-pass-ledger-v1')void refreshInstalledSkins();};window.addEventListener('storage',storage);reduced.addEventListener('change',settings);\r\n const accountReady=(event:Event)=>void refreshInstalledSkins((event as CustomEvent).detail);const accountCleared=()=>void refreshInstalledSkins(null),battlePass=()=>void refreshInstalledSkins();const installedSections=(event:Event)=>{const detail=(event as CustomEvent).detail;if(!detail||typeof detail!=='object'||typeof detail.ownerId!=='string'||!Array.isArray(detail.sections)||!detail.sections.every((section:unknown)=>typeof section==='string'))return;const active=window.myr5AuthenticatedAccount,owner=typeof active==='string'?active:active?.user?.id;if(owner&&detail.ownerId===owner&&detail.sections.some((section:string)=>section.startsWith('track-')))void refreshInstalledSkins(active);};window.addEventListener('myr5:account-ready',accountReady);window.addEventListener('myr5:account-cleared',accountCleared);window.addEventListener('myr5:battle-pass',battlePass);window.addEventListener('myr5:sections-installed',installedSections);\r\n const recipeChanged=(event:Event)=>void updateRecipe(JSON.stringify((event as CustomEvent).detail));window.addEventListener('myr5:recipe',recipeChanged);\r\n // The Vault claims the GPU (modules/graphics-lifecycle.mjs): give this context back for real (dispose alone keeps it on iOS)\r\n // and rebuild the coach when the claim ends. myr5Creature calls are null-safe meanwhile.\r\n const graphicsClaim=(event:Event)=>{const held=viewer;if(!held||(event as CustomEvent).detail?.keep?.includes('coach'))return;viewer=null;yielded=true;epoch++;card.dataset.ready='false';const canvas=held.renderer.domElement;(event as CustomEvent).detail?.wait?.(new Promise<void>(done=>{canvas.addEventListener('webglcontextlost',()=>done(),{once:true});setTimeout(done,250);held.dispose();try{held.renderer.forceContextLoss();}catch{}}));};\r\n const graphicsFree=()=>{if(yielded&&!closed&&!gpuBlocked()){yielded=false;void updateRecipe();}};\r\n window.addEventListener('myr5:graphics-claim',graphicsClaim);window.addEventListener('myr5:graphics-free',graphicsFree);\r\n hide.onclick=()=>{shown=!shown;stage.hidden=!shown;status.hidden=!shown;viewer?.setPaused(!shown);hide.textContent=shown?'Hide creature':'Show creature';hide.setAttribute('aria-expanded',String(shown));};\r\n document.getElementById('start')?.addEventListener('click',()=>play('greet'));document.getElementById('stop')?.addEventListener('click',()=>play('rest',5000));\r\n window.addEventListener('pagehide',()=>{closed=true;epoch++;skinEpoch++;clearInterval(timer);observer.disconnect();skinSource?.dispose();pendingSkinSource?.dispose();skinSource=null;pendingSkinSource=null;viewer?.dispose();window.removeEventListener('myr5:cue',cue);window.removeEventListener('myr5:response',response);window.removeEventListener('storage',storage);window.removeEventListener('myr5:recipe',recipeChanged);window.removeEventListener('myr5:graphics-claim',graphicsClaim);window.removeEventListener('myr5:graphics-free',graphicsFree);window.removeEventListener('myr5:account-ready',accountReady);window.removeEventListener('myr5:account-cleared',accountCleared);window.removeEventListener('myr5:battle-pass',battlePass);window.removeEventListener('myr5:sections-installed',installedSections);reduced.removeEventListener('change',settings);},{once:true});\r\n // Workout overlay: legs walk while the coach moves across the room; cue gestures wait until it stops.\r\n (window as any).myr5Creature={play,walk:(on:boolean)=>{if(on===walking)return;walking=on;if(on){holdUntil=0;viewer?.play('walk');}else if(viewer?.motion?.current==='walk')viewer.play('idle');},face:(yaw:number)=>viewer?.face(yaw),stage:(value:'pod'|'encounter'|'overlay')=>{viewer?.setAwake(true);viewer?.setStage(value);if(value!=='overlay'){walking=false;viewer?.face(0);if(viewer?.motion?.current==='walk')viewer.play('idle');}},park:()=>viewer?.setAwake(false),cinematic:(kind:Cinematic|null,elapsed=0)=>{viewer?.cinematic(kind,elapsed);holdUntil=performance.now()+(kind?10000:500);},setMaxFps:(fps:number|null)=>viewer?.setMaxFps(fps),stats:()=>({...viewer?.stats(),stage:viewer?.stage,cinematic:viewer?.cinematicKind,handsVersion:2})};void updateRecipe();void refreshInstalledSkins();\r\n // #149 meditation. preview: render the saved recipe with these parts swapped in (e.g. the meditation boss body) without\r\n // saving it; null returns to the saved recipe. Resolves false and falls back to the saved coach when that model can't load\r\n // (an optional roster body that isn't on the phone, offline). sleep: eyes shut, still, a slow breathing bob.\r\n async function preview(parts:object|null){previewing=parts?JSON.stringify({...loadRecipe(localStorage),...parts}):null;const loaded=await updateRecipe();if(loaded===false&&previewing){previewing=null;void updateRecipe();}return loaded!==false;}\r\n Object.assign((window as any).myr5Creature,{preview,sleep:(on:boolean)=>{sleeping=on;if(viewer?.motion)viewer.motion.sleeping=on;}});\r\n window.addEventListener('pageshow',event=>{if(event.persisted)location.reload();});\r\n}\r\n","creature/source/pod-camera.ts":"import * as T from 'three';\r\nimport {regionFrame} from './creator/camera-focus';\r\n\r\n// Eight seconds out, eight seconds back. The cosine eases to a stop at\r\n// each end instead of snapping between the face and the wider coach view.\r\nexport function podCameraFrame(camera:T.PerspectiveCamera,head:T.Box3,body:T.Box3,seconds:number){\r\n const close=regionFrame(camera,head),wide=regionFrame(camera,body);\r\n if(!close||!wide)return null;\r\n const amount=(1-Math.cos(Math.PI*Math.max(0,seconds)/8))/2;\r\n return {target:close.target.lerp(wide.target,amount),position:close.position.lerp(wide.position,amount),maxDistance:Math.max(14,wide.distance*2)};\r\n}\r\n","creature/source/preview-idle.ts":"// Activity is local to the coach window; scrolling the customizer does not cover it again.\r\nexport function mountPreviewIdle(bay:HTMLElement,delay=3000){\r\n let timer:ReturnType<typeof setTimeout>|undefined;\r\n const pointers=new Set<number>(),events=new AbortController();\r\n const schedule=()=>{clearTimeout(timer);if(!pointers.size)timer=setTimeout(()=>bay.dataset.idle='true',delay);};\r\n const show=()=>{bay.dataset.idle='false';schedule();};\r\n bay.addEventListener('pointerdown',event=>{pointers.add(event.pointerId);show();},{signal:events.signal});\r\n bay.addEventListener('pointermove',show,{signal:events.signal});\r\n const release=(event:PointerEvent)=>{if(pointers.delete(event.pointerId))show();};\r\n window.addEventListener('pointerup',release,{signal:events.signal});\r\n window.addEventListener('pointercancel',release,{signal:events.signal});\r\n for(const type of ['wheel','focusin','keydown','input'])bay.addEventListener(type,show,{signal:events.signal});\r\n show();\r\n return ()=>{clearTimeout(timer);events.abort();};\r\n}\r\n","creature/source/profile.ts":"import {fresh,parseRecipe} from './creator/design';\r\nexport {fresh,REGIONS,LABELS,STYLES,PICKER_STYLES,BODIES,PICKER_BODIES} from './creator/design';\r\nexport {EYE_LAYOUTS} from './creator/eye-layouts';\r\nexport {PUPILS} from './creator/pupils';\r\nexport {COACHES} from './creator/coaching';\r\nexport const RECIPE_KEY='myr5-recipe-v1';\r\nexport const MOTION_KEY='myr5-motion-v1';\r\nexport const MAX_IMPORT_BYTES=64*1024;\r\nexport function importCreature(raw:string){\r\n if(typeof raw!=='string'||new TextEncoder().encode(raw).length>MAX_IMPORT_BYTES)throw Error('Choose a MYR5 recipe smaller than 64 KB.');\r\n try {\r\n  const data=JSON.parse(raw);\r\n  if(!data||typeof data!=='object'||Array.isArray(data))throw Error();\r\n  if(data.format!==undefined&&data.format!=='myr5-companion')throw Error();\r\n  if(data.format==='myr5-companion'&&data.version!==1)throw Error();\r\n  return parseRecipe(JSON.stringify(data.format==='myr5-companion'?data.recipe:data));\r\n } catch {throw Error('This is not a supported MYR5 recipe. Export “Save editable recipe · JSON” from the creature creator.');}\r\n}\r\nexport function loadRecipe(storage:Storage){const raw=storage.getItem(RECIPE_KEY);return raw?importCreature(raw):fresh();}\r\nexport function exportCompanion(recipe:unknown){return JSON.stringify({format:'myr5-companion',version:1,rigVersion:1,recipe:importCreature(JSON.stringify(recipe))},null,2);}\r\nexport function motionSettings(raw:string|null){\r\n try {const d=JSON.parse(raw||'{}');return {amount:1.5,reduced:typeof d?.reduced==='boolean'?d.reduced:false,ambient:d?.ambient!==false};}\r\n catch{return {amount:1.5,reduced:false,ambient:true};}\r\n}\r\n","creature/source/quadruped-ownership.ts":"import * as T from 'three';\r\nimport { connectedTriangleComponents } from './limb-ownership';\r\n\r\n/**\r\n * Re-home the lower, source-authored faces of the nine Four-legged coaches into\r\n * four unambiguous animation groups. Roster `arms`/`feet` are usually fore/hind\r\n * pairs, not bilateral humanoid limbs; some of their cut faces also land in\r\n * `body` or `head`. This pass uses the four spatial foot clusters as ownership\r\n * seeds and never drops or duplicates a source triangle.\r\n *\r\n * Call after GLTF load and before region fitting/style wrapping. A consumer can\r\n * route the cloned meshes by `mesh.userData.quadrupedLimbNode` and use the joint\r\n * hints stored on `source.userData.quadrupedLimbHints`.\r\n */\r\n\r\nexport type QuadrupedLimbNode = 'ArmLeft' | 'ArmRight' | 'FootLeft' | 'FootRight';\r\nexport type QuadrupedJointHint = { position: [number, number, number]; side: -1 | 1; fore: boolean };\r\n\r\ntype Point = { x: number; y: number; z: number };\r\ntype Triangle = { mesh: T.Mesh; region: string; id: number; points: [Point, Point, Point]; center: Point };\r\ntype Cluster = { center: Point; samples: number; radius: number; node?: QuadrupedLimbNode; fore?: boolean; side?: -1 | 1 };\r\n\r\nconst REGIONS = ['head', 'body', 'arms', 'feet'] as const;\r\nconst QUADRUPED_IDS = new Set([\r\n  'roster/18-quad-all--dragon_creature_3d_model',\r\n  'roster/18-quad-all--fantasy_creature_3d_model1',\r\n  'roster/18-quad-all--fantasy_creature_3d_model3',\r\n  'roster/18-quad-all--four-legged_robot_3d_model',\r\n  'roster/18-quad-all--quadruped_robot_3d_model1',\r\n  'roster/18-quad-all--quadruped_robot_3d_model',\r\n  'roster/18-quad-all--robotic_dog_3d_model',\r\n  'roster/18-quad-all--stylized_quadruped_3d_model',\r\n  'roster/18-quad-all--wooden_four-legged_robot_3d_model',\r\n  'roster/23-blob-texture-bodies--blob_creature_3d_model',\r\n]);\r\nconst REPAIR_IDS = new Set([\r\n  'roster/18-quad-all--fantasy_creature_3d_model1',\r\n  'roster/18-quad-all--fantasy_creature_3d_model3',\r\n  'roster/18-quad-all--four-legged_robot_3d_model',\r\n  'roster/18-quad-all--quadruped_robot_3d_model',\r\n  'roster/18-quad-all--quadruped_robot_3d_model1',\r\n  'roster/18-quad-all--robotic_dog_3d_model',\r\n  'roster/18-quad-all--wooden_four-legged_robot_3d_model',\r\n  'roster/23-blob-texture-bodies--blob_creature_3d_model',\r\n]);\r\nconst BODY_FRAGMENT_ONLY_IDS = new Set([\r\n  'roster/18-quad-all--quadruped_robot_3d_model',\r\n  'roster/18-quad-all--stylized_quadruped_3d_model',\r\n]);\r\nconst STYLIZED_QUAD_ID = 'roster/18-quad-all--stylized_quadruped_3d_model';\r\nconst WERNER_APRON_ID = 'roster/18-quad-all--quadruped_robot_3d_model1';\r\n\r\nconst sq = (v: number) => v * v;\r\nconst dist2XZ = (a: Point, b: Point) => sq(a.x - b.x) + sq(a.z - b.z);\r\nconst add = (a: Point, b: Point): Point => ({ x: a.x + b.x, y: a.y + b.y, z: a.z + b.z });\r\nconst scale = (a: Point, n: number): Point => ({ x: a.x * n, y: a.y * n, z: a.z * n });\r\n\r\nfunction closestSurfacePoint(meshes: T.Mesh[], point: T.Vector3) {\r\n  const triangle = new T.Triangle(), closest = new T.Vector3(), a = new T.Vector3(), b = new T.Vector3(), c = new T.Vector3();\r\n  let distance = Infinity, result: T.Vector3 | undefined, normal: T.Vector3 | undefined;\r\n  for (const mesh of meshes) {\r\n    const geometry = mesh.geometry, position = geometry.getAttribute('position'), index = geometry.index;\r\n    const count = (index?.count ?? position.count) / 3;\r\n    for (let face = 0; face < count; face++) {\r\n      a.fromBufferAttribute(position, index ? index.getX(face * 3) : face * 3).applyMatrix4(mesh.matrixWorld);\r\n      b.fromBufferAttribute(position, index ? index.getX(face * 3 + 1) : face * 3 + 1).applyMatrix4(mesh.matrixWorld);\r\n      c.fromBufferAttribute(position, index ? index.getX(face * 3 + 2) : face * 3 + 2).applyMatrix4(mesh.matrixWorld);\r\n      triangle.set(a, b, c).closestPointToPoint(point, closest);\r\n      const nextDistance = closest.distanceToSquared(point);\r\n      if (nextDistance < distance) {\r\n        distance = nextDistance; result = closest.clone(); normal = triangle.getNormal(new T.Vector3());\r\n      }\r\n    }\r\n  }\r\n  return result && normal ? { point: result, normal, distance: Math.sqrt(distance) } : undefined;\r\n}\r\n\r\nfunction makeTriangle(mesh: T.Mesh, region: string, id: number): Triangle {\r\n  const g = mesh.geometry, p = g.getAttribute('position'), ix = g.index, at = (i: number) => {\r\n    const n = ix ? ix.getX(i) : i;\r\n    const v = new T.Vector3().fromBufferAttribute(p, n).applyMatrix4(mesh.matrixWorld);\r\n    return { x: v.x, y: v.y, z: v.z };\r\n  };\r\n  const points = [at(id * 3), at(id * 3 + 1), at(id * 3 + 2)] as [Point, Point, Point];\r\n  return { mesh, region, id, points, center: scale(add(add(points[0], points[1]), points[2]), 1 / 3) };\r\n}\r\n\r\nfunction pointKey(p: Point, tolerance: number) {\r\n  return `${Math.round(p.x / tolerance)},${Math.round(p.y / tolerance)},${Math.round(p.z / tolerance)}`;\r\n}\r\nfunction edgeKey(a: Point, b: Point, tolerance: number) {\r\n  const ka = pointKey(a, tolerance), kb = pointKey(b, tolerance);\r\n  return ka < kb ? `${ka}|${kb}` : `${kb}|${ka}`;\r\n}\r\n\r\nfunction lowComponents(triangles: Triangle[], tolerance: number) {\r\n  const edges = new Map<string, number[]>();\r\n  triangles.forEach((tri, i) => { for (let k = 0; k < 3; k++) { const key = edgeKey(tri.points[k], tri.points[(k + 1) % 3], tolerance); const row = edges.get(key); if (row) row.push(i); else edges.set(key, [i]); } });\r\n  const adjacency = triangles.map(() => [] as number[]);\r\n  for (const ids of edges.values()) if (ids.length > 1) for (const a of ids) for (const b of ids) if (a !== b) adjacency[a].push(b);\r\n  const component = new Int32Array(triangles.length).fill(-1), groups: number[][] = [];\r\n  for (let i = 0; i < triangles.length; i++) {\r\n    if (component[i] >= 0) continue;\r\n    const id = groups.length, queue = [i], members: number[] = []; component[i] = id;\r\n    for (let q = 0; q < queue.length; q++) { const at = queue[q]; members.push(at); for (const next of adjacency[at]) if (component[next] < 0) { component[next] = id; queue.push(next); } }\r\n    groups.push(members);\r\n  }\r\n  return { component, groups };\r\n}\r\n\r\nfunction farthestSeeds(points: Point[], k: number): Point[] {\r\n  const mean = points.reduce((sum, p) => add(sum, p), { x: 0, y: 0, z: 0 });\r\n  const origin = scale(mean, 1 / points.length);\r\n  const seeds = [points.reduce((best, p) => dist2XZ(p, origin) > dist2XZ(best, origin) ? p : best, points[0])];\r\n  while (seeds.length < k) {\r\n    const next = points.reduce((best, p) => {\r\n      const d = Math.min(...seeds.map(seed => dist2XZ(p, seed)));\r\n      const bestD = Math.min(...seeds.map(seed => dist2XZ(best, seed)));\r\n      return d > bestD ? p : best;\r\n    }, points[0]);\r\n    seeds.push(next);\r\n  }\r\n  return seeds.map(p => ({ ...p }));\r\n}\r\n\r\nfunction clusterFour(points: Point[]): Cluster[] | null {\r\n  if (points.length < 80) return null;\r\n  const centers = farthestSeeds(points, 4);\r\n  let assignments = new Int8Array(points.length);\r\n  for (let pass = 0; pass < 32; pass++) {\r\n    let changed = false;\r\n    const sums = centers.map(() => ({ x: 0, y: 0, z: 0 })), counts = centers.map(() => 0);\r\n    points.forEach((p, i) => {\r\n      let best = 0, distance = Infinity;\r\n      for (let c = 0; c < centers.length; c++) { const d = dist2XZ(p, centers[c]); if (d < distance) { distance = d; best = c; } }\r\n      if (assignments[i] !== best) changed = true;\r\n      assignments[i] = best; sums[best] = add(sums[best], p); counts[best]++;\r\n    });\r\n    for (let c = 0; c < centers.length; c++) if (counts[c]) centers[c] = scale(sums[c], 1 / counts[c]);\r\n    if (!changed) break;\r\n  }\r\n  const clusters = centers.map((center, c) => {\r\n    let samples = 0, radius = 0;\r\n    points.forEach((p, i) => { if (assignments[i] === c) { samples++; radius = Math.max(radius, Math.sqrt(dist2XZ(p, center))); } });\r\n    return { center, samples, radius };\r\n  });\r\n  const separation = Math.min(...clusters.flatMap((a, i) => clusters.slice(i + 1).map(b => Math.sqrt(dist2XZ(a.center, b.center)))));\r\n  if (clusters.some(c => c.samples < 20) || separation < 0.06) return null;\r\n  return clusters;\r\n}\r\n\r\nfunction triangleSubset(source: T.BufferGeometry, ids: readonly number[]): T.BufferGeometry | null {\r\n  if (!ids.length) return null;\r\n  const position = source.getAttribute('position'), index = source.index, remap = new Map<number, number>(), sourceVertices: number[] = [], outIndex: number[] = [];\r\n  const count = index?.count ?? position.count;\r\n  for (const triangle of ids) {\r\n    const start = triangle * 3;\r\n    if (start + 2 >= count) continue;\r\n    for (let j = 0; j < 3; j++) {\r\n      const old = index ? index.getX(start + j) : start + j;\r\n      let next = remap.get(old);\r\n      if (next === undefined) { next = sourceVertices.length; remap.set(old, next); sourceVertices.push(old); }\r\n      outIndex.push(next);\r\n    }\r\n  }\r\n  if (!outIndex.length) return null;\r\n  const out = new T.BufferGeometry();\r\n  for (const [name, attribute] of Object.entries(source.attributes)) {\r\n    const a = attribute as T.BufferAttribute, values = new (a.array.constructor as any)(sourceVertices.length * a.itemSize);\r\n    for (let i = 0; i < sourceVertices.length; i++) for (let c = 0; c < a.itemSize; c++) values[i * a.itemSize + c] = a.array[sourceVertices[i] * a.itemSize + c];\r\n    out.setAttribute(name, new T.BufferAttribute(values, a.itemSize, a.normalized));\r\n  }\r\n  for (const [name, attributes] of Object.entries(source.morphAttributes)) {\r\n    out.morphAttributes[name] = attributes.map(attribute => {\r\n      const a = attribute as T.BufferAttribute, values = new (a.array.constructor as any)(sourceVertices.length * a.itemSize);\r\n      for (let i = 0; i < sourceVertices.length; i++) for (let c = 0; c < a.itemSize; c++) values[i * a.itemSize + c] = a.array[sourceVertices[i] * a.itemSize + c];\r\n      return new T.BufferAttribute(values, a.itemSize, a.normalized);\r\n    });\r\n  }\r\n  out.morphTargetsRelative = source.morphTargetsRelative;\r\n  out.setIndex(outIndex);\r\n  out.computeBoundingBox(); out.computeBoundingSphere();\r\n  return out;\r\n}\r\n\r\n/** Quadzilla's source has three legs: one left foreleg split across arms/feet, one right foreleg, and one rear-right leg. */\r\nfunction correctStylizedQuadOwnership(source: T.Group, regions: Map<string, T.Mesh[]>): boolean {\r\n  source.updateWorldMatrix(true, true);\r\n  const body = source.getObjectByName('body');\r\n  const head = source.getObjectByName('head');\r\n  const feet = source.getObjectByName('feet');\r\n  const bodyMeshes = regions.get('body') ?? [];\r\n  if (!body || !head || !feet || !bodyMeshes.length) return false;\r\n  const bodyBox = new T.Box3().setFromObject(body), headBox = new T.Box3().setFromObject(head), feetBox = new T.Box3().setFromObject(feet);\r\n  const footHeight = feetBox.max.y - feetBox.min.y;\r\n  // Head reaches the torso cut but is far above the ground; reject if it ever contains a foot-height island.\r\n  if (!(footHeight > 0) || headBox.min.y <= feetBox.min.y + footHeight * .15) return false;\r\n  const bodyMaterial = bodyMeshes.find(mesh => !Array.isArray(mesh.material))?.material;\r\n  if (!bodyMaterial || Array.isArray(bodyMaterial)) return false;\r\n  const specs = [\r\n    { region: 'arms', triangles: 154, center: [ .0982, .9973, .2414], owner: 'body' as const },\r\n    { region: 'arms', triangles: 1461, center: [-.8023, .4035, .2243], owner: 'ArmLeft' as const },\r\n    { region: 'arms', triangles: 2014, center: [ .8086, .4974, .3690], owner: 'ArmRight' as const },\r\n    { region: 'feet', triangles: 467, center: [-.8390, .2011,-.0571], owner: 'ArmLeft' as const },\r\n    { region: 'feet', triangles: 102, center: [-.1132,1.0031,-.1474], owner: 'body' as const },\r\n    { region: 'feet', triangles: 1391, center: [ .2609, .3803,-.5842], owner: 'FootRight' as const },\r\n  ];\r\n  const found = new Set<string>(), targets = new Map<T.Mesh, Map<typeof specs[number]['owner'], number[]>>();\r\n  for (const region of ['arms', 'feet']) for (const mesh of regions.get(region) ?? []) {\r\n    const position = mesh.geometry.getAttribute('position'), index = mesh.geometry.index;\r\n    for (const component of connectedTriangleComponents(mesh)) {\r\n      const box = new T.Box3(), center = new T.Vector3();\r\n      for (const face of component) for (let corner = 0; corner < 3; corner++) {\r\n        const vertex = index ? index.getX(face * 3 + corner) : face * 3 + corner;\r\n        const point = new T.Vector3().fromBufferAttribute(position, vertex).applyMatrix4(mesh.matrixWorld);\r\n        box.expandByPoint(point); center.add(point);\r\n      }\r\n      center.divideScalar(component.length * 3);\r\n      const specIndex = specs.findIndex(spec => spec.region === region && spec.triangles === component.length &&\r\n        Math.abs(center.x - spec.center[0]) < .025 && Math.abs(center.y - spec.center[1]) < .025 && Math.abs(center.z - spec.center[2]) < .025);\r\n      if (specIndex < 0) continue;\r\n      const key = `${region}:${specIndex}`;\r\n      if (found.has(key)) return false;\r\n      found.add(key);\r\n      const owner = specs[specIndex].owner;\r\n      let byOwner = targets.get(mesh); if (!byOwner) targets.set(mesh, byOwner = new Map());\r\n      let ids = byOwner.get(owner); if (!ids) byOwner.set(owner, ids = []); ids.push(...component);\r\n    }\r\n  }\r\n  if (found.size !== specs.length) return false;\r\n  let moved = 0, bodyMoved = 0;\r\n  for (const [mesh, byOwner] of targets) {\r\n    const selected = new Set([...byOwner.values()].flat());\r\n    const count = (mesh.geometry.index?.count ?? mesh.geometry.getAttribute('position').count) / 3;\r\n    const remaining: number[] = []; for (let id = 0; id < count; id++) if (!selected.has(id)) remaining.push(id);\r\n    const old = mesh.geometry, kept = triangleSubset(old, remaining), parent = mesh.parent;\r\n    if (kept) mesh.geometry = kept; else mesh.removeFromParent();\r\n    for (const [owner, ids] of byOwner) {\r\n      const geometry = triangleSubset(old, ids); if (!geometry) continue;\r\n      const part = mesh.clone(false); part.geometry = geometry;\r\n      if (owner === 'body') {\r\n        const relative = body.matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n        relative.decompose(part.position, part.quaternion, part.scale);\r\n        part.name = `${mesh.name || 'Quadzilla seam'} body-owned pelvis`;\r\n        part.material = bodyMaterial;\r\n        part.userData = { ...mesh.userData, quadrupedBodyOwnedTriangles: ids.length };\r\n        body.add(part); bodyMoved += ids.length;\r\n      } else {\r\n        part.name = `${mesh.name || 'Quadzilla leg'} ${owner}`;\r\n        part.userData = { ...mesh.userData, quadrupedLimbNode: owner, rigNodeName: owner };\r\n        parent?.add(part);\r\n      }\r\n      moved += ids.length;\r\n    }\r\n    old.dispose();\r\n  }\r\n  if (moved !== 5589 || bodyMoved !== 256) return false;\r\n  source.updateWorldMatrix(true, true);\r\n  source.userData.quadrupedOwnershipVersion = 1;\r\n  source.userData.quadrupedOwnershipTriangles = moved;\r\n  source.userData.quadrupedOwnershipBodyTriangles = bodyMoved;\r\n  source.userData.quadrupedOwnershipBodyTransferredTriangles = bodyMoved;\r\n  source.userData.quadrupedOwnershipBodyTransferredFromFeet = 102;\r\n  source.userData.quadrupedLimbHints = {\r\n    ArmLeft: { position: [-.8023, 1.05, .2243], side: -1, fore: true },\r\n    ArmRight: { position: [.8086, 1.05, .3690], side: 1, fore: true },\r\n    FootRight: { position: [.2609, 1.05, -.5842], side: 1, fore: false },\r\n  };\r\n  source.userData.quadrupedOwnershipLimbTriangles = { ArmLeft: 1928, ArmRight: 2014, FootLeft: 0, FootRight: 1391 };\r\n  storeMeshJointHints(source, source.userData.quadrupedLimbHints);\r\n  return true;\r\n}\r\n\r\nfunction inferFront(source: T.Group, bodyBox: T.Box3, headBox: T.Box3): { x: number; z: number } {\r\n  const body = bodyBox.getCenter(new T.Vector3()), head = headBox.getCenter(new T.Vector3());\r\n  const anchor = source.getObjectByName('eye_anchor');\r\n  const point = anchor ? anchor.getWorldPosition(new T.Vector3()) : head;\r\n  let x = point.x - body.x, z = point.z - body.z;\r\n  if (Math.hypot(x, z) < 1e-4) { x = head.x - body.x; z = head.z - body.z; }\r\n  if (Math.hypot(x, z) < 1e-4) { x = 0; z = 1; }\r\n  const length = Math.hypot(x, z);\r\n  return { x: x / length, z: z / length };\r\n}\r\n\r\nfunction storeMeshJointHints(source: T.Group, hints: Partial<Record<QuadrupedLimbNode, QuadrupedJointHint>>): void {\r\n  source.updateWorldMatrix(true, true);\r\n  source.traverse(object => {\r\n    if (!(object instanceof T.Mesh)) return;\r\n    const node = object.userData.rigNodeName as QuadrupedLimbNode | undefined;\r\n    const hint = node ? hints[node] : undefined;\r\n    if (!hint) return;\r\n    const local = object.worldToLocal(new T.Vector3(...hint.position));\r\n    object.userData.rigJointLocal = local.toArray();\r\n  });\r\n}\r\n\r\n/** Return false without changing source when four distinct lower-leg clusters cannot be supported. */\r\nexport function correctQuadrupedOwnership(source: T.Group, sourceId: string): boolean {\r\n  if (!QUADRUPED_IDS.has(sourceId) || (!REPAIR_IDS.has(sourceId) && !BODY_FRAGMENT_ONLY_IDS.has(sourceId)) || source.userData.quadrupedOwnershipVersion === 1) return false;\r\n  source.updateWorldMatrix(true, true);\r\n  const regionMeshes = new Map<string, T.Mesh[]>();\r\n  const boxes = new Map<string, T.Box3>();\r\n  for (const name of REGIONS) {\r\n    const region = source.getObjectByName(name), meshes: T.Mesh[] = [], box = new T.Box3();\r\n    region?.traverse(o => { if (o instanceof T.Mesh && o.visible && !Array.isArray(o.material)) { meshes.push(o); box.expandByObject(o); } });\r\n    regionMeshes.set(name, meshes); boxes.set(name, box);\r\n  }\r\n  const feetBox = boxes.get('feet')!, bodyBox = boxes.get('body')!, headBox = boxes.get('head')!;\r\n  if (feetBox.isEmpty() || bodyBox.isEmpty() || headBox.isEmpty()) return false;\r\n  if (sourceId === STYLIZED_QUAD_ID) return correctStylizedQuadOwnership(source, regionMeshes);\r\n  const cutoff = feetBox.max.y + Math.max(0.003, feetBox.getSize(new T.Vector3()).y * 0.003);\r\n  const blobBodyPrepared = sourceId === 'roster/23-blob-texture-bodies--blob_creature_3d_model';\r\n  const allLow: Triangle[] = [];\r\n  for (const [region, meshes] of regionMeshes) {\r\n    // The source assembler first returns Blob64's torso side panels and central\r\n    // pelvis to BODY. Only the four original grounded paw components are animated.\r\n    if (blobBodyPrepared && region !== 'feet') continue;\r\n    for (const mesh of meshes) {\r\n    const g = mesh.geometry, count = (g.index?.count ?? g.getAttribute('position').count) / 3;\r\n    for (let id = 0; id < count; id++) {\r\n      const triangle = makeTriangle(mesh, region, id);\r\n      if (triangle.center.y >= cutoff) continue;\r\n      allLow.push(triangle);\r\n    }\r\n    }\r\n  }\r\n  if (allLow.length < 100) return false;\r\n  const allBox = new T.Box3(); for (const tri of allLow) for (const p of tri.points) allBox.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n  const weld = Math.max(0.001, allBox.getSize(new T.Vector3()).length() * 0.0005), topology = lowComponents(allLow, weld);\r\n  const bodySize = bodyBox.getSize(new T.Vector3()), heldComponents = new Set<number>();\r\n  const bodyAttachmentComponents = new Set<number>(), bodyAttachmentOffsets = new Map<number, T.Vector3>(), bodyAttachmentContacts = new Map<number, T.Vector3>();\r\n  if (sourceId === 'roster/18-quad-all--fantasy_creature_3d_model3'\r\n    || sourceId === 'roster/18-quad-all--quadruped_robot_3d_model') {\r\n    const bodyRegion = source.getObjectByName('body'), bodyMaterial = bodyRegion\r\n      ? regionMeshes.get('body')!.find(mesh => !Array.isArray(mesh.material))?.material : undefined;\r\n    if (!bodyRegion || !bodyMaterial || Array.isArray(bodyMaterial)) return false;\r\n\r\n    const bodyOwned = new Set<Triangle>();\r\n    if (sourceId === 'roster/18-quad-all--fantasy_creature_3d_model3') {\r\n      // Shiva's separate, 75-face undershell sits centrally at the pelvis seam.\r\n      // It is not one of the four grounded paws and follows the torso.\r\n      const feetTriangles = allLow.filter(tri => tri.region === 'feet');\r\n      const feetTopology = lowComponents(feetTriangles, weld), candidates: Triangle[][] = [];\r\n      feetTopology.groups.forEach(members => {\r\n        if (members.length < 50 || members.length > 100) return;\r\n        const box = new T.Box3();\r\n        for (const index of members) for (const p of feetTriangles[index].points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n        const center = box.getCenter(new T.Vector3()), size = box.getSize(new T.Vector3());\r\n        if (Math.abs(center.x - bodyBox.getCenter(new T.Vector3()).x) < 0.15\r\n          && center.y > feetBox.min.y + (feetBox.max.y - feetBox.min.y) * 0.8\r\n          && box.max.y >= feetBox.max.y - (feetBox.max.y - feetBox.min.y) * 0.02\r\n          && size.x < bodySize.x * 0.6 && size.z < bodySize.z * 0.4) {\r\n          candidates.push(members.map(index => feetTriangles[index]));\r\n        }\r\n      });\r\n      if (candidates.length !== 1 || candidates[0].length !== 75) return false;\r\n      for (const tri of candidates[0]) bodyOwned.add(tri);\r\n    } else {\r\n      // Yee's source has a single head-owned triangle crossing the pelvis cut.\r\n      const candidates: Triangle[] = [];\r\n      topology.groups.forEach(members => {\r\n        if (members.length !== 1) return;\r\n        const tri = allLow[members[0]], sizeX = Math.max(...tri.points.map(p => p.x)) - Math.min(...tri.points.map(p => p.x));\r\n        const sizeZ = Math.max(...tri.points.map(p => p.z)) - Math.min(...tri.points.map(p => p.z));\r\n        if (tri.region === 'head' && tri.center.x > 0.15 && Math.abs(tri.center.y - cutoff) < 0.005\r\n          && sizeX < 0.06 && sizeZ < 0.03) candidates.push(tri);\r\n      });\r\n      if (candidates.length !== 1) return false;\r\n      bodyOwned.add(candidates[0]);\r\n    }\r\n\r\n    const feetHeight = feetBox.max.y - feetBox.min.y;\r\n    const groundSeeds = allLow.filter(tri => (tri.region === 'arms' || tri.region === 'feet')\r\n      && !bodyOwned.has(tri) && tri.center.y <= feetBox.min.y + feetHeight * 0.1).map(tri => tri.center);\r\n    const clusters = clusterFour(groundSeeds);\r\n    if (!clusters) return false;\r\n    const bodyCenter = bodyBox.getCenter(new T.Vector3()), front = inferFront(source, bodyBox, headBox);\r\n    const ranked = clusters.map(c => ({ c, foreScore: (c.center.x - bodyCenter.x) * front.x + (c.center.z - bodyCenter.z) * front.z }));\r\n    const fore = [...ranked].sort((a, b) => b.foreScore - a.foreScore);\r\n    const setPair = (pair: typeof ranked, foreleg: boolean) => {\r\n      const [left, right] = [...pair].sort((a, b) => a.c.center.x - b.c.center.x);\r\n      for (const row of [left, right]) {\r\n        row.c.fore = foreleg; row.c.side = row === left ? -1 : 1;\r\n        row.c.node = foreleg ? (row.c.side < 0 ? 'ArmLeft' : 'ArmRight') : (row.c.side < 0 ? 'FootLeft' : 'FootRight');\r\n      }\r\n    };\r\n    setPair(fore.slice(0, 2), true); setPair(fore.slice(2), false);\r\n    const nearestCluster = (p: Point) => clusters.map((c, i) => ({ i, d: dist2XZ(p, c.center) })).sort((a, b) => a.d - b.d)[0].i;\r\n    const targets = new Map<T.Mesh, Map<QuadrupedLimbNode | 'body', number[]>>();\r\n    const assigned: { tri: Triangle; node: QuadrupedLimbNode | 'body' }[] = [];\r\n    const addTarget = (tri: Triangle, node: QuadrupedLimbNode | 'body') => {\r\n      let map = targets.get(tri.mesh); if (!map) targets.set(tri.mesh, map = new Map());\r\n      let ids = map.get(node); if (!ids) map.set(node, ids = []); ids.push(tri.id);\r\n      assigned.push({ tri, node });\r\n    };\r\n    for (const tri of allLow) {\r\n      if (bodyOwned.has(tri)) addTarget(tri, 'body');\r\n      else if (tri.region === 'arms' || tri.region === 'feet') {\r\n        const node = clusters[nearestCluster(tri.center)].node;\r\n        if (!node) return false;\r\n        addTarget(tri, node);\r\n      }\r\n    }\r\n    let moved = 0, bodyTransferred = 0;\r\n    for (const [mesh, byNode] of targets) {\r\n      const selected = new Set([...byNode.values()].flat()), count = (mesh.geometry.index?.count ?? mesh.geometry.getAttribute('position').count) / 3;\r\n      const remaining: number[] = [];\r\n      for (let id = 0; id < count; id++) if (!selected.has(id)) remaining.push(id);\r\n      const old = mesh.geometry, kept = triangleSubset(old, remaining), parent = mesh.parent;\r\n      if (kept) mesh.geometry = kept; else mesh.removeFromParent();\r\n      for (const [node, ids] of byNode) {\r\n        const geometry = triangleSubset(old, ids); if (!geometry) continue;\r\n        const part = mesh.clone(false); part.geometry = geometry;\r\n        if (node === 'body') {\r\n          const relative = bodyRegion.matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n          relative.decompose(part.position, part.quaternion, part.scale);\r\n          part.name = `${mesh.name || 'Quadruped'} body-owned pelvis`; part.material = bodyMaterial;\r\n          part.userData = { ...mesh.userData, quadrupedBodyOwnedTriangles: ids.length };\r\n          bodyRegion.add(part); bodyTransferred += ids.length;\r\n        } else {\r\n          part.name = `${mesh.name || 'Quadruped limb'} ${node}`;\r\n          part.userData = { ...mesh.userData, quadrupedLimbNode: node, rigNodeName: node };\r\n          parent?.add(part);\r\n        }\r\n        moved += ids.length;\r\n      }\r\n      old.dispose();\r\n    }\r\n    if (moved < (sourceId === 'roster/18-quad-all--fantasy_creature_3d_model3' ? 6500 : 5500)\r\n      || bodyTransferred !== (sourceId === 'roster/18-quad-all--fantasy_creature_3d_model3' ? 75 : 1)) return false;\r\n    source.updateWorldMatrix(true, true);\r\n    const hints = {} as Record<QuadrupedLimbNode, QuadrupedJointHint>;\r\n    for (const c of clusters) {\r\n      const points = assigned.filter(row => row.node === c.node && row.tri.region !== 'body' && row.tri.region !== 'head'\r\n        && Math.sqrt(dist2XZ(row.tri.center, c.center)) < Math.max(c.radius * 0.7, 0.08)\r\n        && row.tri.center.y >= cutoff - Math.max(0.08, (cutoff - feetBox.min.y) * 0.18)).map(row => row.tri.center);\r\n      const joint = points.length ? points.reduce((sum, p) => add(sum, p), { x: 0, y: 0, z: 0 }) : { ...c.center, y: cutoff };\r\n      const p = points.length ? scale(joint, 1 / points.length) : joint;\r\n      hints[c.node!] = { position: [p.x, p.y, p.z], side: c.side!, fore: c.fore! };\r\n    }\r\n    source.userData.quadrupedLimbHints = hints; storeMeshJointHints(source, hints);\r\n    source.userData.quadrupedOwnershipVersion = 1;\r\n    source.userData.quadrupedOwnershipTriangles = moved;\r\n    source.userData.quadrupedOwnershipBodyTriangles = bodyTransferred;\r\n    source.userData.quadrupedOwnershipBodyTransferredTriangles = bodyTransferred;\r\n    return true;\r\n  }\r\n  if (BODY_FRAGMENT_ONLY_IDS.has(sourceId)) {\r\n    const candidates: number[] = [];\r\n    topology.groups.forEach((members, id) => {\r\n      const counts: Record<string, number> = {}, box = new T.Box3();\r\n      for (const index of members) {\r\n        const tri = allLow[index]; counts[tri.region] = (counts[tri.region] || 0) + 1;\r\n        for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n      }\r\n      const center = box.getCenter(new T.Vector3()), size = box.getSize(new T.Vector3());\r\n      if (sourceId === 'roster/18-quad-all--quadruped_robot_3d_model'\r\n        && members.length === 1 && counts.head === 1 && center.x > 0.15\r\n        && Math.abs(center.y - cutoff) < 0.005 && size.x < 0.06 && size.z < 0.03) candidates.push(id);\r\n      if (sourceId === 'roster/18-quad-all--stylized_quadruped_3d_model') {\r\n        const bodySideIsland = Math.abs(center.x - bodyBox.getCenter(new T.Vector3()).x) < 0.15\r\n          && Math.abs(center.y - cutoff) < feetBox.getSize(new T.Vector3()).y * 0.08\r\n          && size.x < bodySize.x * 0.55 && size.z < bodySize.z * 0.4;\r\n        if (bodySideIsland && ((members.length === 102 && counts.feet === 102)\r\n          || (members.length === 154 && counts.arms === 154))) candidates.push(id);\r\n      }\r\n    });\r\n    const expected = sourceId === 'roster/18-quad-all--quadruped_robot_3d_model' ? 1 : 2;\r\n    if (candidates.length !== expected) return false;\r\n    const bodyRegion = source.getObjectByName('body'), bodyMaterial = bodyRegion\r\n      ? regionMeshes.get('body')!.find(mesh => !Array.isArray(mesh.material))?.material : undefined;\r\n    if (!bodyRegion || !bodyMaterial || Array.isArray(bodyMaterial)) return false;\r\n    const byMesh = new Map<T.Mesh, number[]>();\r\n    for (const id of candidates) for (const index of topology.groups[id]) {\r\n      const tri = allLow[index], ids = byMesh.get(tri.mesh);\r\n      if (ids) ids.push(tri.id); else byMesh.set(tri.mesh, [tri.id]);\r\n    }\r\n    let moved = 0;\r\n    for (const [mesh, ids] of byMesh) {\r\n      if (!mesh.parent) continue;\r\n      const count = (mesh.geometry.index?.count ?? mesh.geometry.getAttribute('position').count) / 3;\r\n      const selected = new Set(ids), remaining: number[] = [];\r\n      for (let id = 0; id < count; id++) if (!selected.has(id)) remaining.push(id);\r\n      const old = mesh.geometry, parent = mesh.parent, bodyPart = triangleSubset(old, ids), kept = triangleSubset(old, remaining);\r\n      if (!bodyPart) continue;\r\n      const part = mesh.clone(false); part.geometry = bodyPart;\r\n      const relative = bodyRegion.matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n      relative.decompose(part.position, part.quaternion, part.scale);\r\n      part.name = `${mesh.name || 'Quadruped seam'} body-owned lower seam`;\r\n      part.material = bodyMaterial;\r\n      part.userData = { ...mesh.userData, quadrupedBodyOwnedTriangles: ids.length };\r\n      if (kept) mesh.geometry = kept; else mesh.removeFromParent();\r\n      bodyRegion.add(part); old.dispose(); moved += ids.length;\r\n    }\r\n    if (!moved) return false;\r\n    source.userData.quadrupedOwnershipVersion = 1;\r\n    source.userData.quadrupedOwnershipBodyTriangles = moved;\r\n    source.userData.quadrupedOwnershipBodyTransferredTriangles = moved;\r\n    source.userData.quadrupedOwnershipBodyTransferredFromFeet = sourceId === 'roster/18-quad-all--stylized_quadruped_3d_model' ? 102 : 0;\r\n    return true;\r\n  }\r\n  if (sourceId === 'roster/18-quad-all--four-legged_robot_3d_model') {\r\n    const bodyCenter = bodyBox.getCenter(new T.Vector3()), feetHeight = feetBox.max.y - feetBox.min.y;\r\n    const bodyRegion = source.getObjectByName('body'), bodyMaterial = bodyRegion\r\n      ? regionMeshes.get('body')!.find(mesh => !Array.isArray(mesh.material))?.material : undefined;\r\n    if (!bodyRegion || !bodyMaterial || Array.isArray(bodyMaterial) || !(feetHeight > 0)) return false;\r\n    const centralPelvis: number[] = [], limbIsland: number[] = [];\r\n    topology.groups.forEach((members, id) => {\r\n      const counts: Record<string, number> = {}, box = new T.Box3();\r\n      for (const index of members) {\r\n        const tri = allLow[index]; counts[tri.region] = (counts[tri.region] || 0) + 1;\r\n        for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n      }\r\n      const center = box.getCenter(new T.Vector3()), size = box.getSize(new T.Vector3());\r\n        // Tara's isolated, non-grounded 500-face underside is split into two\r\n        // source-region islands at the z seam. Together they span the torso\r\n        // width; neither island reaches a grounded leg, so both belong to body.\r\n        if (members.length >= 200 && members.length <= 280\r\n          && ((counts.feet || 0) === members.length || (counts.arms || 0) === members.length)\r\n          && Math.abs(center.x - bodyCenter.x) < 0.1\r\n          && center.y > feetBox.min.y + feetHeight * 0.8\r\n          && size.x > bodySize.x * 0.8 && size.z > bodySize.z * 0.35) centralPelvis.push(id);\r\n        if (members.length >= 7500 && (counts.feet || 0) >= 5000 && (counts.arms || 0) >= 2500) limbIsland.push(id);\r\n      });\r\n    if (centralPelvis.length !== 2 || limbIsland.length !== 1) return false;\r\n    // The source arm mesh also contains a broad center-front facade that reaches\r\n    // the ground. Its 2,190 connected faces meet the head seam directly, but it\r\n    // is not a fifth leg. Exclude it from paw clustering and keep it with the\r\n    // head shell; body ownership opened a visible seam through the front cone.\r\n    const armTriangles = allLow.filter(tri => tri.region === 'arms');\r\n    const armTopology = lowComponents(armTriangles, weld), centralFrontPanels: Triangle[][] = [];\r\n    armTopology.groups.forEach(members => {\r\n      const box = new T.Box3(), groundNearCenter: Triangle[] = [];\r\n      for (const index of members) {\r\n        const tri = armTriangles[index];\r\n        for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n        if (tri.center.y <= feetBox.min.y + feetHeight * 0.1\r\n          && Math.abs(tri.center.x - bodyCenter.x) < 0.25\r\n          && tri.center.z > bodyCenter.z + bodySize.z * 0.6) groundNearCenter.push(tri);\r\n      }\r\n      const size = box.getSize(new T.Vector3()), center = box.getCenter(new T.Vector3());\r\n      if (members.length >= 2000 && members.length <= 2300 && groundNearCenter.length >= 100\r\n        && Math.abs(center.x - bodyCenter.x) < 0.1 && center.z > bodyCenter.z + bodySize.z * 0.5\r\n        && size.x > bodySize.x * 0.8 && size.z > bodySize.z * 0.8\r\n        && box.min.y <= feetBox.min.y + feetHeight * 0.1 && box.max.y >= cutoff - feetHeight * 0.02) {\r\n        centralFrontPanels.push(members.map(index => armTriangles[index]));\r\n      }\r\n    });\r\n    if (centralFrontPanels.length !== 1) return false;\r\n    const centralFrontTriangles = new Set(centralFrontPanels[0]);\r\n    const groundSeeds: Point[] = [];\r\n    for (let i = 0; i < allLow.length; i++) {\r\n      const tri = allLow[i];\r\n      if (topology.component[i] === limbIsland[0] && (tri.region === 'arms' || tri.region === 'feet')\r\n        && !centralFrontTriangles.has(tri)\r\n        && tri.center.y <= feetBox.min.y + feetHeight * 0.1) groundSeeds.push(tri.center);\r\n    }\r\n    const clusters = clusterFour(groundSeeds);\r\n    if (!clusters) return false;\r\n    const front = inferFront(source, bodyBox, headBox), ranked = clusters.map(c => ({\r\n      c, foreScore: (c.center.x - bodyCenter.x) * front.x + (c.center.z - bodyCenter.z) * front.z,\r\n      sideScore: c.center.x - bodyCenter.x,\r\n    }));\r\n    const fore = [...ranked].sort((a, b) => b.foreScore - a.foreScore);\r\n    const setPair = (pair: typeof ranked, foreleg: boolean) => {\r\n      const [left, right] = [...pair].sort((a, b) => a.sideScore - b.sideScore);\r\n      for (const row of [left, right]) {\r\n        row.c.fore = foreleg; row.c.side = row === left ? -1 : 1;\r\n        row.c.node = foreleg ? (row.c.side < 0 ? 'ArmLeft' : 'ArmRight') : (row.c.side < 0 ? 'FootLeft' : 'FootRight');\r\n      }\r\n    };\r\n    setPair(fore.slice(0, 2), true); setPair(fore.slice(2), false);\r\n    const nearestCluster = (p: Point) => clusters.map((c, i) => ({ i, d: dist2XZ(p, c.center) })).sort((a, b) => a.d - b.d)[0].i;\r\n    const targets = new Map<T.Mesh, Map<QuadrupedLimbNode | 'body' | 'head', number[]>>();\r\n    const addTarget = (tri: Triangle, node: QuadrupedLimbNode | 'body' | 'head') => {\r\n      let meshTargets = targets.get(tri.mesh); if (!meshTargets) targets.set(tri.mesh, meshTargets = new Map());\r\n      let ids = meshTargets.get(node); if (!ids) meshTargets.set(node, ids = []); ids.push(tri.id);\r\n    };\r\n    const centralIds = new Set(centralPelvis);\r\n    for (let i = 0; i < allLow.length; i++) {\r\n      const tri = allLow[i], component = topology.component[i];\r\n      if ((centralIds.has(component) || centralFrontTriangles.has(tri)) && (tri.region === 'arms' || tri.region === 'feet')) {\r\n        addTarget(tri, centralFrontTriangles.has(tri) ? 'head' : 'body');\r\n      }\r\n      else if (component === limbIsland[0] && (tri.region === 'arms' || tri.region === 'feet')) {\r\n        const node = clusters[nearestCluster(tri.center)].node;\r\n        if (!node) return false;\r\n        addTarget(tri, node);\r\n      }\r\n    }\r\n    const headRegion = source.getObjectByName('head'), headMaterial = headRegion\r\n      ? regionMeshes.get('head')!.find(mesh => !Array.isArray(mesh.material))?.material : undefined;\r\n    if (!headRegion || !headMaterial || Array.isArray(headMaterial)) return false;\r\n    let moved = 0, bodyTransferred = 0, headTransferred = 0;\r\n    for (const [mesh, byNode] of targets) {\r\n      const selected = new Set([...byNode.values()].flat()), count = (mesh.geometry.index?.count ?? mesh.geometry.getAttribute('position').count) / 3;\r\n      const remaining: number[] = [];\r\n      for (let id = 0; id < count; id++) if (!selected.has(id)) remaining.push(id);\r\n      const old = mesh.geometry, kept = triangleSubset(old, remaining), parent = mesh.parent;\r\n      if (kept) mesh.geometry = kept; else mesh.removeFromParent();\r\n      for (const [node, ids] of byNode) {\r\n        const geometry = triangleSubset(old, ids); if (!geometry) continue;\r\n        const part = mesh.clone(false); part.geometry = geometry;\r\n        if (node === 'body' || node === 'head') {\r\n          const ownerRegion = node === 'body' ? bodyRegion : headRegion;\r\n          const relative = ownerRegion.matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n          relative.decompose(part.position, part.quaternion, part.scale);\r\n          part.name = `${mesh.name || 'Tara shell'} ${node}-owned central shell`;\r\n          part.material = node === 'body' ? bodyMaterial : headMaterial;\r\n          part.userData = { ...mesh.userData, [node === 'body' ? 'quadrupedBodyOwnedTriangles' : 'quadrupedHeadOwnedTriangles']: ids.length };\r\n          ownerRegion.add(part);\r\n          if (node === 'body') bodyTransferred += ids.length; else headTransferred += ids.length;\r\n        } else {\r\n          part.name = `${mesh.name || 'Tara leg'} ${node}`;\r\n          part.userData = { ...mesh.userData, quadrupedLimbNode: node, rigNodeName: node };\r\n          parent?.add(part);\r\n        }\r\n        moved += ids.length;\r\n      }\r\n      old.dispose();\r\n    }\r\n    if (bodyTransferred < 450 || headTransferred !== 2190 || moved < 7000) return false;\r\n    source.updateWorldMatrix(true, true);\r\n    const hints = {} as Record<QuadrupedLimbNode, QuadrupedJointHint>;\r\n    for (const cluster of clusters) hints[cluster.node!] = {\r\n      position: [cluster.center.x, cutoff, cluster.center.z], side: cluster.side!, fore: cluster.fore!,\r\n    };\r\n    source.userData.quadrupedLimbHints = hints;\r\n    storeMeshJointHints(source, hints);\r\n    source.userData.quadrupedOwnershipVersion = 1;\r\n    source.userData.quadrupedOwnershipTriangles = moved;\r\n    source.userData.quadrupedOwnershipBodyTriangles = bodyTransferred;\r\n    source.userData.quadrupedOwnershipBodyTransferredTriangles = bodyTransferred;\r\n    source.userData.quadrupedOwnershipHeadTriangles = headTransferred;\r\n    source.userData.quadrupedOwnershipHeadTransferredTriangles = headTransferred;\r\n    return true;\r\n  }\r\n  if (sourceId === 'roster/18-quad-all--wooden_four-legged_robot_3d_model') {\r\n    topology.groups.forEach((members, id) => {\r\n      let bodyFaces = 0, armFaces = 0, footFaces = 0; const box = new T.Box3();\r\n      for (const index of members) { const tri = allLow[index]; if (tri.region === 'body') bodyFaces++; if (tri.region === 'arms') armFaces++; if (tri.region === 'feet') footFaces++; for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x,p.y,p.z)); }\r\n      const size = box.getSize(new T.Vector3());\r\n      // The verified wooden model has one continuous rear underside bridging both\r\n      // sides. Preserve it as body-owned instead of cleaving it between hind feet.\r\n      if (bodyFaces > 0 && armFaces > 0 && footFaces > 0 && size.x > bodySize.x * 0.4 && size.z > bodySize.z * 0.7) heldComponents.add(id);\r\n    });\r\n  }\r\n  if (sourceId === 'roster/18-quad-all--robotic_dog_3d_model') {\r\n    const bodyCenter = bodyBox.getCenter(new T.Vector3());\r\n    const front = inferFront(source, bodyBox, headBox);\r\n    topology.groups.forEach((members, id) => {\r\n      let armFaces = 0, otherFaces = 0; const box = new T.Box3();\r\n      for (const index of members) {\r\n        const tri = allLow[index];\r\n        if (tri.region === 'arms') armFaces++; else otherFaces++;\r\n        for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n      }\r\n      const size = box.getSize(new T.Vector3()), center = box.getCenter(new T.Vector3());\r\n      const foreDepth = (center.x - bodyCenter.x) * front.x + (center.z - bodyCenter.z) * front.z;\r\n      // Two source ARM flecks sit inside the chest, immediately below its front\r\n      // edge. They are not appendages: routing them to either foreleg makes them\r\n      // swing visibly under the abdomen. Keep only these small, central components\r\n      // body-owned; the four full limb components remain independently animated.\r\n      if (otherFaces === 0 && armFaces >= 70 && armFaces <= 95\r\n        && Math.abs(center.x - bodyCenter.x) < bodySize.x * 0.3\r\n        && foreDepth > bodySize.z * 0.3\r\n        && center.y > cutoff - feetBox.getSize(new T.Vector3()).y * 0.45\r\n        && size.x < bodySize.x * 0.35 && size.y < bodySize.y * 0.4 && size.z < bodySize.z * 0.4) {\r\n        heldComponents.add(id);\r\n      }\r\n    });\r\n  }\r\n  if (sourceId === 'roster/18-quad-all--quadruped_robot_3d_model1') {\r\n    const bodyCenter = bodyBox.getCenter(new T.Vector3()), front = inferFront(source, bodyBox, headBox);\r\n    topology.groups.forEach((members, id) => {\r\n      const counts: Record<string, number> = {}, box = new T.Box3();\r\n      for (const index of members) {\r\n        const tri = allLow[index]; counts[tri.region] = (counts[tri.region] || 0) + 1;\r\n        for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n      }\r\n      const center = box.getCenter(new T.Vector3()), size = box.getSize(new T.Vector3());\r\n      const frontOffset = (center.x - bodyCenter.x) * front.x + (center.z - bodyCenter.z) * front.z;\r\n      // Werner's isolated 548-face central apron is authored in ARMS, but it is\r\n      // below the torso and has no contact with any of the four grounded limbs.\r\n      // Keep the whole centerline component with BodyMotion instead of letting\r\n      // nearest-paw voting make it swing as a detached fifth appendage.\r\n      if (members.length === 548 && counts.arms === 548\r\n        && Math.abs(center.x - bodyCenter.x) < bodySize.x * 0.08\r\n        && center.y < cutoff * 0.4 && frontOffset > bodySize.z * 0.25\r\n        && size.x < bodySize.x * 0.1 && size.y < feetBox.getSize(new T.Vector3()).y * 0.3\r\n        && size.z < bodySize.z * 0.12) {\r\n        const bodyMeshes = regionMeshes.get('body') ?? [];\r\n        const nearestBody = closestSurfacePoint(bodyMeshes, center);\r\n        if (!nearestBody) return;\r\n        const outward = nearestBody.normal;\r\n        if (outward.dot(center.clone().sub(nearestBody.point)) < 0) outward.negate();\r\n        const half = size.clone().multiplyScalar(0.5);\r\n        const radius = Math.sqrt(sq(outward.x * half.x) + sq(outward.y * half.y) + sq(outward.z * half.z));\r\n        if (!(radius > 0) || nearestBody.distance <= radius * 0.5) return;\r\n        // Keep the orphan orb as a visible belly detail: its center sits at 82% of\r\n        // its directional support radius beyond the measured torso surface, so it\r\n        // intersects slightly without disappearing into the body.\r\n        const contactPoint = nearestBody.point.clone();\r\n        const targetCenter = contactPoint.clone().addScaledVector(outward, radius * 0.82);\r\n        heldComponents.add(id); bodyAttachmentComponents.add(id);\r\n        bodyAttachmentOffsets.set(id, targetCenter.sub(center));\r\n        bodyAttachmentContacts.set(id, contactPoint);\r\n      }\r\n    });\r\n  }\r\n  const seedTriangles: Triangle[] = [];\r\n  for (let i = 0; i < allLow.length; i++) {\r\n    const tri = allLow[i];\r\n    if (!heldComponents.has(topology.component[i]) && (tri.region === 'arms' || tri.region === 'feet') && tri.center.y <= feetBox.min.y + (feetBox.max.y - feetBox.min.y) * 0.68) seedTriangles.push(tri);\r\n  }\r\n  if (allLow.length < 100 || seedTriangles.length < 80) return false;\r\n  const clusters = clusterFour(seedTriangles.map(t => t.center));\r\n  if (!clusters) return false;\r\n\r\n  const centerX = bodyBox.getCenter(new T.Vector3()).x;\r\n  const centerZ = bodyBox.getCenter(new T.Vector3()).z;\r\n  const front = inferFront(source, bodyBox, headBox);\r\n  const ranked = clusters.map(c => ({ c, foreScore: (c.center.x - centerX) * front.x + (c.center.z - centerZ) * front.z, sideScore: c.center.x - centerX }));\r\n  const fore = [...ranked].sort((a, b) => b.foreScore - a.foreScore), rear = fore.slice(2);\r\n  const setPair = (pair: typeof ranked, foreleg: boolean) => {\r\n    const [left, right] = [...pair].sort((a, b) => a.sideScore - b.sideScore);\r\n    for (const row of [left, right]) {\r\n      row.c.fore = foreleg; row.c.side = row === left ? -1 : 1;\r\n      row.c.node = foreleg ? (row.c.side < 0 ? 'ArmLeft' : 'ArmRight') : (row.c.side < 0 ? 'FootLeft' : 'FootRight');\r\n    }\r\n  };\r\n  setPair(fore.slice(0, 2), true); setPair(rear, false);\r\n\r\n  const center = { x: centerX, y: 0, z: centerZ };\r\n  const nearest = (p: Point) => clusters.map((c, i) => ({ i, d: dist2XZ(p, c.center) })).sort((a, b) => a.d - b.d)[0];\r\n  const clusterRadius = Math.max(...clusters.map(c => c.radius));\r\n  const maxAttach = Math.max(0.14, clusterRadius * 1.8);\r\n  const assigned = new Map<Triangle, QuadrupedLimbNode>();\r\n  for (let componentId = 0; componentId < topology.groups.length; componentId++) {\r\n    const memberIndexes = topology.groups[componentId];\r\n    if (heldComponents.has(componentId)) continue;\r\n    const members = memberIndexes.map(i => allLow[i]);\r\n    const sourceLimbFaces = members.filter(tri => tri.region === 'arms' || tri.region === 'feet').length;\r\n    const box = new T.Box3();\r\n    const votes = new Int32Array(clusters.length);\r\n    for (const tri of members) {\r\n      for (const p of tri.points) box.expandByPoint(new T.Vector3(p.x, p.y, p.z));\r\n      votes[nearest(tri.center).i]++;\r\n    }\r\n    const size = box.getSize(new T.Vector3());\r\n    const compactLimb = sourceLimbFaces > 0 && size.x <= bodySize.x * 1.05 && size.z <= bodySize.z * 1.05;\r\n    if (compactLimb) {\r\n      // A physical appendage is one connected source component. Give every one of its\r\n      // triangles the same joint owner; per-face nearest-cluster routing shears long toes\r\n      // and curved limbs at Voronoi boundaries when they pass close to another leg.\r\n      let winner = 0;\r\n      for (let i = 1; i < votes.length; i++) if (votes[i] > votes[winner]) winner = i;\r\n      const node = clusters[winner].node;\r\n      if (!node) return false;\r\n      for (const tri of members) assigned.set(tri, node);\r\n      continue;\r\n    }\r\n    // Fused, broad low shells retain their whole-body ownership where possible. For\r\n    // remaining broad geometry, keep the established contact-aware triangle fallback.\r\n    for (const tri of members) {\r\n      const { i, d } = nearest(tri.center), candidate = clusters[i];\r\n      if (!candidate.node) return false;\r\n      const bodyOwned = tri.region === 'body' || tri.region === 'head';\r\n      if (bodyOwned && Math.sqrt(d) > maxAttach) continue;\r\n      const sideDistance = Math.sqrt(dist2XZ(candidate.center, center));\r\n      if (bodyOwned && sideDistance < 0.08) continue;\r\n      assigned.set(tri, candidate.node);\r\n    }\r\n  }\r\n  const bodyRegion = source.getObjectByName('body');\r\n  const bodyMaterial = bodyRegion ? regionMeshes.get('body')!.find(mesh => !Array.isArray(mesh.material))?.material : undefined;\r\n  const byMesh = new Map<T.Mesh, Map<QuadrupedLimbNode | 'body' | 'bodyAttachment', number[]>>();\r\n  let bodyOwnedTriangles = 0;\r\n  let bodyTransferredTriangles = 0;\r\n  let bodyTransferredFromFeet = 0;\r\n  const addTarget = (tri: Triangle, node: QuadrupedLimbNode | 'body' | 'bodyAttachment') => {\r\n    let targets = byMesh.get(tri.mesh); if (!targets) byMesh.set(tri.mesh, targets = new Map());\r\n    let ids = targets.get(node); if (!ids) targets.set(node, ids = []); ids.push(tri.id);\r\n  };\r\n  for (let i = 0; i < allLow.length; i++) if (heldComponents.has(topology.component[i])) {\r\n    const tri = allLow[i];\r\n    addTarget(tri, bodyAttachmentComponents.has(topology.component[i]) ? 'bodyAttachment' : 'body'); bodyOwnedTriangles++;\r\n    if (tri.region !== 'body') bodyTransferredTriangles++;\r\n    if (tri.region === 'feet') bodyTransferredFromFeet++;\r\n  }\r\n  for (const [tri, node] of assigned) {\r\n    addTarget(tri, node);\r\n  }\r\n  let moved = 0;\r\n  for (const [mesh, targets] of byMesh) {\r\n    const movedIds = new Set([...targets.values()].flat());\r\n    if (!movedIds.size || !mesh.parent) continue;\r\n    const count = (mesh.geometry.index?.count ?? mesh.geometry.getAttribute('position').count) / 3;\r\n    const remaining: number[] = [];\r\n    for (let id = 0; id < count; id++) if (!movedIds.has(id)) remaining.push(id);\r\n    const kept = triangleSubset(mesh.geometry, remaining);\r\n    const old = mesh.geometry, parent = mesh.parent;\r\n    const parts: Array<{ node: QuadrupedLimbNode | 'body'; geometry: T.BufferGeometry }> = [];\r\n    for (const [node, ids] of targets) {\r\n      const geometry = triangleSubset(old, ids);\r\n      if (geometry) parts.push({ node, geometry });\r\n    }\r\n    if (kept) mesh.geometry = kept; else mesh.removeFromParent();\r\n    for (const { node, geometry } of parts) {\r\n      const part = mesh.clone(false); part.geometry = geometry;\r\n      const count = (geometry.index?.count ?? geometry.getAttribute('position').count) / 3;\r\n      if (node === 'body' || node === 'bodyAttachment') {\r\n        if (!bodyRegion || !bodyMaterial) { geometry.dispose(); continue; }\r\n        const isAttachment = node === 'bodyAttachment';\r\n        part.name = isAttachment ? `${mesh.name || 'Quadruped detail'} attached belly detail` : `${mesh.name || 'Quadruped underside'} body-owned underside`;\r\n        part.userData = { ...mesh.userData, quadrupedBodyOwnedTriangles: count };\r\n        source.updateWorldMatrix(true, true); bodyRegion.updateWorldMatrix(true, false);\r\n        const relative = bodyRegion.matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n        relative.decompose(part.position, part.quaternion, part.scale);\r\n        if (isAttachment) {\r\n          const worldOffset = sourceId === WERNER_APRON_ID && count === 548\r\n            ? bodyAttachmentOffsets.values().next().value as T.Vector3 | undefined : undefined;\r\n          const contactPoint = sourceId === WERNER_APRON_ID && count === 548\r\n            ? bodyAttachmentContacts.values().next().value as T.Vector3 | undefined : undefined;\r\n          if (!worldOffset || !contactPoint) { geometry.dispose(); continue; }\r\n          const localOffset = worldOffset.clone().applyMatrix3(new T.Matrix3().setFromMatrix4(bodyRegion.matrixWorld.clone().invert()));\r\n          part.position.add(localOffset);\r\n          part.userData.ownershipAttachmentWorldOffset = worldOffset.toArray();\r\n          part.userData.ownershipAttachmentBodyContactWorldPoint = contactPoint.toArray();\r\n          part.userData.ownershipAttachment = 'body-belly-detail';\r\n          part.material = mesh.material;\r\n        } else part.material = bodyMaterial;\r\n        bodyRegion.add(part);\r\n      } else {\r\n        part.name = `${mesh.name || 'Quadruped limb'} ${node}`;\r\n        part.userData = { ...mesh.userData, quadrupedLimbNode: node, rigNodeName: node };\r\n        parent?.add(part);\r\n      }\r\n      moved += count;\r\n    }\r\n    old.dispose();\r\n  }\r\n  if (!moved) return false;\r\n\r\n  const hints = {} as Record<QuadrupedLimbNode, QuadrupedJointHint>;\r\n  for (const c of clusters) {\r\n    const triangles = assigned;\r\n    const points: Point[] = [];\r\n    for (const [tri, node] of triangles) if (node === c.node && Math.sqrt(dist2XZ(tri.center, c.center)) <= maxAttach && tri.center.y >= cutoff - Math.max(0.08, (cutoff - feetBox.min.y) * 0.18)) points.push(tri.center);\r\n    const joint = points.length ? points.reduce((sum, p) => add(sum, p), { x: 0, y: 0, z: 0 }) : { ...c.center, y: cutoff };\r\n    const p = points.length ? scale(joint, 1 / points.length) : joint;\r\n    hints[c.node!] = { position: [p.x, p.y, p.z], side: c.side!, fore: c.fore! };\r\n  }\r\n  source.userData.quadrupedLimbHints = hints;\r\n  storeMeshJointHints(source, hints);\r\n  source.userData.quadrupedOwnershipVersion = 1;\r\n  source.userData.quadrupedOwnershipTriangles = moved;\r\n  source.userData.quadrupedOwnershipBodyTriangles = bodyOwnedTriangles;\r\n  source.userData.quadrupedOwnershipBodyTransferredTriangles = bodyTransferredTriangles;\r\n  source.userData.quadrupedOwnershipBodyTransferredFromFeet = bodyTransferredFromFeet;\r\n  return true;\r\n}\r\n","creature/source/reward-preview.ts":"import {CreatureViewer} from './viewer';\r\nimport {fresh,REGIONS} from './creator/design';\r\nimport {findTexture,textureDefaultMetalness,findColor,findPalette} from './creator/materials-registry';\r\nimport {isGranted} from './creator/unlock-store';\r\n\r\n// Reuse the real coach and material renderer. This recipe never reaches storage,\r\n// the equipped coach, or the editor's locked-item preview path.\r\nexport function mountOriginalRewardPreview(host:HTMLElement,reward:{kind:'texture'|'color'|'palette';id:string}) {\r\n if(!isGranted(reward.kind,reward.id,'myr5'))throw Error('This cosmetic has not been earned.');\r\n const texture=reward.kind==='texture'?findTexture(reward.id):findTexture('clay');\r\n if(!texture||reward.kind==='palette'&&!findPalette(reward.id)||reward.kind==='color'&&!/^#[0-9a-f]{6}$/i.test(reward.id)&&!findColor(reward.id))throw Error('This cosmetic is unavailable.');\r\n const recipe=fresh(),colorId=reward.kind==='texture'?texture.defaultColorId:reward.id;\r\n recipe.golden=false;\r\n recipe.materials=Object.fromEntries(REGIONS.filter(region=>region!=='eye').map(region=>[region,{textureId:texture.id,colorId,sparkle:0,metallic:textureDefaultMetalness(texture.id)??0}]));\r\n const viewer=new CreatureViewer(host,new URL('../',import.meta.url).href,false);\r\n viewer.renderer.domElement.setAttribute('aria-label',`Original MYR5 coach wearing the earned ${reward.kind}`);\r\n viewer.setSettings({...viewer.settings,reduced:true,amount:0});viewer.setMaxFps(12);viewer.setPaused(true);viewer.setStage('overlay');\r\n const resize=new ResizeObserver(()=>{if(!viewer.disposed&&viewer.rig)viewer.warm();});resize.observe(host);\r\n const ready=viewer.setRecipe(recipe).then(loaded=>{\r\n  if(!loaded||viewer.disposed)return false;\r\n  host.dataset.ready='true';host.dataset.body=recipe.body;host.dataset.kind=reward.kind;host.dataset.rewardId=reward.id;\r\n  viewer.warm();viewer.setAwake(false);return true;\r\n });\r\n return {ready,dispose:()=>{resize.disconnect();viewer.dispose();}};\r\n}\r\n\r\nexport function cosmeticRewardName(kind:string,id:string) {\r\n return (kind==='texture'?findTexture(id):kind==='color'?findColor(id):findPalette(id))?.displayName||id;\r\n}\r\n","creature/source/rig.ts":"import * as T from 'three';\r\nimport {mergeGeometries} from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\nimport {EYE_LAYOUTS} from './creator/eye-layouts';\r\nimport {eyePosition} from './creator/anatomy';\r\nimport type {Design} from './creator/design';\r\nimport {connectedComponentSides,connectedTriangleComponents} from './limb-ownership';\r\n\r\nconst ROUS_SIDE_PLANE_SOURCE='roster/09-monolith-tanka--robot_3d_model2';\r\n\r\n/** Infer the bilateral split from the two largest grounded connected components under a source feet group. */\r\nexport function inferGroundedSidePlaneX(footRegion:T.Object3D){\r\n footRegion.updateWorldMatrix(true,true);const footMeshes:T.Mesh[]=[];footRegion.traverse(o=>{if(o instanceof T.Mesh&&o.visible)footMeshes.push(o);});const footBox=new T.Box3();for(const mesh of footMeshes)footBox.expandByObject(mesh);const height=footBox.max.y-footBox.min.y;if(!Number.isFinite(height)||height<=0)return 0;\r\n const grounded:{triangles:number;centerX:number}[]=[];\r\n for(const mesh of footMeshes)for(const ids of connectedTriangleComponents(mesh)){\r\n  const p=mesh.geometry.getAttribute('position'),index=mesh.geometry.index;let minY=Infinity,minX=Infinity,maxX=-Infinity;\r\n  for(const triangle of ids)for(let k=0;k<3;k++){const v=new T.Vector3().fromBufferAttribute(p,index?index.getX(triangle*3+k):triangle*3+k).applyMatrix4(mesh.matrixWorld);minY=Math.min(minY,v.y);minX=Math.min(minX,v.x);maxX=Math.max(maxX,v.x);}\r\n  if(minY>footBox.min.y+height*.1)continue;grounded.push({triangles:ids.length,centerX:(minX+maxX)/2});\r\n }\r\n grounded.sort((a,b)=>b.triangles-a.triangles);return grounded.length>=2?(grounded[0].centerX+grounded[1].centerX)/2:0;\r\n}\r\n\r\nexport function disposeObject(root:T.Object3D){const geometries=new Set<T.BufferGeometry>(),materials=new Set<T.Material>();root.traverse(o=>{if(o instanceof T.SkinnedMesh)o.skeleton.dispose();if(o instanceof T.Mesh){geometries.add(o.geometry);for(const m of Array.isArray(o.material)?o.material:[o.material])materials.add(m);}});geometries.forEach(g=>g.dispose());materials.forEach(m=>m.dispose());}\r\n\r\n// The source arms and feet contain both sides in one mesh. Partition complete\r\n// triangles at the empty center gap, preserving the creator's world coordinates.\r\nfunction bake(mesh:T.Mesh,side=0,pick?:(triangle:number)=>boolean,componentSides?:Int8Array,sidePlaneX=0){\r\n const input=mesh.geometry.clone();input.applyMatrix4(mesh.matrixWorld);\r\n if(!input.getAttribute('normal'))input.computeVertexNormals();\r\n // A flipX mirror (negative-scale ancestor, e.g. assemble.ts's facing correction) reverses handedness:\r\n // applyMatrix4 above already re-orients the normal attribute correctly, but triangle winding order is\r\n // a vertex-index property it can't touch, so front/back-face culling would go inside-out unless the\r\n // winding is reversed here too (swap the last two vertices of every triangle).\r\n const mirrored=mesh.matrixWorld.determinant()<0;\r\n const pos=input.getAttribute('position'),normal=input.getAttribute('normal'),color=input.getAttribute('color'),uv=input.getAttribute('uv');\r\n const p:number[]=[],n:number[]=[],c:number[]=[],tex:number[]=[],indices:number[]=[],remap=new Map<number,number>();\r\n const count=input.index?.count??pos.count,vertex=(i:number)=>input.index?input.index.getX(i):i;\r\n for(let i=0;i<count;i+=3){const triangleId=i/3;if(pick&&!pick(triangleId))continue;const triangle=[vertex(i),vertex(i+1),vertex(i+2)],x=triangle.reduce((sum,j)=>sum+pos.getX(j),0)/3,componentSide=componentSides?.[triangleId]??0,chosenSide=componentSide|| (x<sidePlaneX?-1:1);if(side&&chosenSide!==side)continue;\r\n  if(mirrored)[triangle[1],triangle[2]]=[triangle[2],triangle[1]];\r\n  for(const j of triangle){if(!remap.has(j)){remap.set(j,p.length/3);p.push(pos.getX(j),pos.getY(j),pos.getZ(j));n.push(normal.getX(j),normal.getY(j),normal.getZ(j));c.push(color?color.getX(j):1,color?color.getY(j):1,color?color.getZ(j):1);tex.push(uv?uv.getX(j):0,uv?uv.getY(j):0);}indices.push(remap.get(j)!);}\r\n }\r\n input.dispose();if(!p.length)return null;\r\n const geometry=new T.BufferGeometry();geometry.setAttribute('position',new T.Float32BufferAttribute(p,3));geometry.setAttribute('normal',new T.Float32BufferAttribute(n,3));geometry.setAttribute('color',new T.Float32BufferAttribute(c,3));geometry.setAttribute('uv',new T.Float32BufferAttribute(tex,2));geometry.setIndex(indices);return geometry;\r\n}\r\n\r\nexport function createRig(source:T.Group,recipe:Design){\r\n const root=new T.Group();root.name='MYR5';root.userData={rigVersion:1,recipe:JSON.parse(JSON.stringify(recipe))};\r\n const nodes:Record<string,T.Group>={};\r\n function pivot(name:string,position:number[],parent=root){const node=new T.Group();node.name=name;node.position.fromArray(position);parent.add(node);nodes[name]=node;return node;}\r\n const fitted=source.userData.pivots as {body:number[];head:number[];arm:number[];foot:number[]}|null|undefined;\r\n const P=fitted??{body:[0,.8,0],head:[0,.75,0],arm:[.55,.48,0],foot:[.35,.35,0]};\r\n const body=pivot('BodyMotion',P.body);\r\n const head=pivot('HeadMotion',P.head,body);\r\n pivot('ArmLeft',[-P.arm[0],P.arm[1],P.arm[2]],body);pivot('ArmRight',P.arm,body);\r\n pivot('FootLeft',[-P.foot[0],P.foot[1],P.foot[2]]);pivot('FootRight',P.foot);\r\n const eyes=EYE_LAYOUTS[recipe.eyeLayout].eyes;\r\n const eyeOffset=(source.userData.eyeOffset as T.Vector3|undefined)??new T.Vector3();\r\n const eyeScale=(source.userData.eyeScale as number|undefined)??1,headY=P.body[1]+P.head[1];\r\n eyes.forEach((eye,i)=>{const [x,y,z]=eyePosition(eye,eyeOffset,eyeScale,source.userData.eyeSurfaceZ as number|undefined);pivot('EyeBlink'+i,[x,y-headY,z],head);});\r\n root.updateMatrixWorld(true);source.updateMatrixWorld(true);\r\n // Assemblies preserve a plane fitted from the matching roster source. A direct source-model rig can\r\n // infer it from its own feet; never borrow another coach's feet for a mixed-source recipe.\r\n const fittedSidePlanes=source.userData.limbSidePlanes as Partial<Record<'arms'|'feet',number>>|undefined;\r\n const directFeetSidePlane=recipe.feetFrom===ROUS_SIDE_PLANE_SOURCE?inferGroundedSidePlaneX(source.getObjectByName('feet')??source):0;\r\n const sidePlaneX=(region:'arms'|'feet')=>Number.isFinite(fittedSidePlanes?.[region])?fittedSidePlanes![region]!:region==='feet'?directFeetSidePlane:recipe.feetFrom===ROUS_SIDE_PLANE_SOURCE?directFeetSidePlane:0;\r\n const buckets=new Map<string,{node:T.Group;material:T.MeshStandardMaterial;geometries:T.BufferGeometry[]}>();\r\n function add(mesh:T.Mesh,node:T.Group,side=0,pick?:(triangle:number)=>boolean,componentSides?:Int8Array,sidePlaneX=0){\r\n  if(Array.isArray(mesh.material))throw Error('This MYR5 mesh uses an unsupported material layout.');\r\n  const geometry=bake(mesh,side,pick,componentSides,sidePlaneX);if(!geometry)return;\r\n  geometry.applyMatrix4(node.matrixWorld.clone().invert());\r\n  const mat=mesh.material as T.MeshStandardMaterial;\r\n  const physical=mat as T.MeshPhysicalMaterial;\r\n  const key=node.name+JSON.stringify([mat.type,mat.color.getHex(),mat.emissive.getHex(),mat.emissiveIntensity,mat.roughness,mat.metalness,mat.opacity,mat.side,mat.map?.uuid,mat.normalMap?.uuid,mat.bumpMap?.uuid,mat.roughnessMap?.uuid,mat.emissiveMap?.uuid,mat.bumpScale,physical.transmission,physical.thickness,physical.ior,physical.clearcoat,physical.sheen,mat.userData.installedSkinId?mat.uuid:null]);\r\n  if(!buckets.has(key)){const material=mat.clone();material.vertexColors=true;material.userData={};if(mat.userData.installedSkinId){material.onBeforeCompile=mat.onBeforeCompile;material.customProgramCacheKey=mat.customProgramCacheKey;material.userData.installedSkinId=mat.userData.installedSkinId;material.userData.normalConvention=mat.userData.normalConvention;}buckets.set(key,{node,material,geometries:[]});}\r\n  buckets.get(key)!.geometries.push(geometry);\r\n }\r\n function visit(obj:T.Object3D,region:string,eyeIndex=0,sourceLimb=false){\r\n  if(!obj.visible)return;\r\n  if(/^Eye [1-8]$/.test(obj.name))eyeIndex=Number(obj.name.split(' ')[1])-1;\r\n  if(obj instanceof T.Mesh){\r\n   const explicitNode=sourceLimb&&typeof obj.userData.rigNodeName==='string'?nodes[obj.userData.rigNodeName]:undefined;\r\n   if(explicitNode){\r\n    explicitNode.userData.explicitSourceLimb=true;\r\n    const localJoint=obj.userData.rigJointLocal;\r\n    if(!explicitNode.userData.explicitJointSet&&Array.isArray(localJoint)&&localJoint.length===3&&localJoint.every(Number.isFinite)){\r\n     const previousWorld=explicitNode.matrixWorld.clone();\r\n     const joint=new T.Vector3().fromArray(localJoint).applyMatrix4(obj.matrixWorld);\r\n     explicitNode.position.copy(explicitNode.parent!.worldToLocal(joint));explicitNode.updateWorldMatrix(true,true);explicitNode.userData.explicitJointSet=true;\r\n     // A mixed recipe may have already supplied geometry to this motion node.\r\n     // Changing its pivot must preserve those surfaces in their rest positions.\r\n     const correction=explicitNode.matrixWorld.clone().invert().multiply(previousWorld);\r\n     for(const bucket of buckets.values())if(bucket.node===explicitNode)for(const geometry of bucket.geometries)geometry.applyMatrix4(correction);\r\n    }\r\n    add(obj,explicitNode);\r\n   }\r\n   else if(region==='arms'){\r\n    const sidePlane=recipe.armsFrom===ROUS_SIDE_PLANE_SOURCE?sidePlaneX('arms'):0,componentSides=recipe.armsFrom!=='myr5'&&sourceLimb?connectedComponentSides(obj,sidePlane):undefined;\r\n    // Keep a fused center-crossing component animated: complete one-sided components\r\n    // retain their component owner, while neutral triangles fall back to their own\r\n    // centroid side inside bake (each face stays intact and no triangles are lost).\r\n    if(componentSides){add(obj,nodes.ArmLeft,-1,i=>componentSides[i]===-1||componentSides[i]===0,componentSides,sidePlane);add(obj,nodes.ArmRight,1,i=>componentSides[i]===1||componentSides[i]===0,componentSides,sidePlane);}\r\n    else{add(obj,nodes.ArmLeft,-1);add(obj,nodes.ArmRight,1);}\r\n   }\r\n   else if(region==='feet'){\r\n    const sidePlane=recipe.feetFrom===ROUS_SIDE_PLANE_SOURCE?sidePlaneX('feet'):0,componentSides=recipe.feetFrom!=='myr5'&&sourceLimb?connectedComponentSides(obj,sidePlane):undefined;\r\n    if(componentSides){add(obj,nodes.FootLeft,-1,i=>componentSides[i]===-1||componentSides[i]===0,componentSides,sidePlane);add(obj,nodes.FootRight,1,i=>componentSides[i]===1||componentSides[i]===0,componentSides,sidePlane);}\r\n    else{add(obj,nodes.FootLeft,-1);add(obj,nodes.FootRight,1);}\r\n   }\r\n   else add(obj,region==='eye'?nodes['EyeBlink'+eyeIndex]:region==='head'?head:body);\r\n  }\r\n  for(const child of obj.children)visit(child,region,eyeIndex,sourceLimb);\r\n }\r\n for(const part of source.children){if(part.name==='Style ornaments'){for(const detail of part.children)visit(detail,detail.userData.region);}else visit(part,part.name,0,part.name==='arms'||part.name==='feet');}\r\n for(const {node,material,geometries} of buckets.values()){\r\n  const combined=mergeGeometries(geometries,false);geometries.forEach(g=>g.dispose());if(!combined)throw Error('Could not assemble this creature.');\r\n  combined.computeBoundingSphere();const mesh=new T.Mesh(combined,material);mesh.name=node.name+'Surface';node.add(mesh);\r\n }\r\n // Rigid parts opened a gap wherever they met the body (neck, ankles) as soon as they turned. The head and\r\n // feet are skinned to BodyMotion instead: a vertex's share of its own part grows with its distance from the\r\n // body's surface, so the seam stays welded to the body and the joint bends rather than separating.\r\n root.updateMatrixWorld(true);\r\n const meshes=(node:T.Object3D)=>node.children.filter((o):o is T.Mesh=>o instanceof T.Mesh);\r\n const boxOf=(node:T.Object3D)=>{const b=new T.Box3();for(const m of meshes(node))b.expandByObject(m);return b;};\r\n // Distance to the body's surface on a voxel grid around `near` (two-pass chamfer transform), Infinity outside it.\r\n function surfaceDistance(anchor:T.Object3D,near:T.Box3,touch:number,reach:number){\r\n  const zone=near.clone().expandByScalar(reach),size=zone.getSize(new T.Vector3()),voxel=Math.max(touch/2,Math.cbrt(size.x*size.y*size.z/4e5)),o=zone.min.clone().subScalar(voxel);\r\n  // One empty voxel of padding on every side lets the sweeps skip bounds checks.\r\n  const nx=Math.ceil(size.x/voxel)+3,ny=Math.ceil(size.y/voxel)+3,nz=Math.ceil(size.z/voxel)+3,field=new Float32Array(nx*ny*nz).fill(Infinity),at=(x:number,y:number,z:number)=>(x*ny+y)*nz+z;\r\n  const t=new T.Box3(),c=[new T.Vector3(),new T.Vector3(),new T.Vector3()],q=new T.Vector3();\r\n  for(const mesh of meshes(anchor)){const p=mesh.geometry.getAttribute('position'),index=mesh.geometry.index,n=index?index.count:p.count;\r\n   for(let i=0;i<n;i+=3){for(let j=0;j<3;j++)c[j].fromBufferAttribute(p,index?index.getX(i+j):i+j).applyMatrix4(mesh.matrixWorld);if(!t.setFromPoints(c).intersectsBox(zone))continue;\r\n    const k=Math.ceil(Math.max(c[0].distanceTo(c[1]),c[1].distanceTo(c[2]),c[2].distanceTo(c[0]))/voxel);\r\n    for(let u=0;u<=k;u++)for(let w=0;u+w<=k;w++){q.copy(c[0]).multiplyScalar(1-(u+w)/k).addScaledVector(c[1],u/k).addScaledVector(c[2],w/k).sub(o).divideScalar(voxel).round();if(q.x>0&&q.y>0&&q.z>0&&q.x<nx-1&&q.y<ny-1&&q.z<nz-1)field[at(q.x,q.y,q.z)]=0;}}}\r\n  const step:number[]=[],cost:number[]=[];for(let x=-1;x<=1;x++)for(let y=-1;y<=1;y++)for(let z=-1;z<=1;z++)if(x<0||(x===0&&(y<0||(y===0&&z<0)))){step.push(at(x,y,z)-at(0,0,0));cost.push(Math.hypot(x,y,z));}\r\n  for(const s of [1,-1])for(let x=s>0?1:nx-2;x>0&&x<nx-1;x+=s)for(let y=s>0?1:ny-2;y>0&&y<ny-1;y+=s)for(let z=s>0?1:nz-2;z>0&&z<nz-1;z+=s){const i=at(x,y,z);let best=field[i];\r\n   for(let k=0;k<13;k++){const d=field[i+s*step[k]]+cost[k];if(d<best)best=d;}field[i]=best;}\r\n  const lookup=(v:T.Vector3)=>{q.copy(v).sub(o).divideScalar(voxel).round();return q.x>=0&&q.y>=0&&q.z>=0&&q.x<nx&&q.y<ny&&q.z<nz?field[at(q.x,q.y,q.z)]*voxel:Infinity;};\r\n  return {lookup,voxel};\r\n }\r\n // Weld `node` to the body: within `touch` of the body a vertex follows BodyMotion, by `touch+band` it\r\n // follows its own pivot. With movePivot the pivot moves onto the seam (the true joint). Parts that don't\r\n // meet the body stay rigid.\r\n function closestAnchor(node:T.Group,touch:number,band:number){\r\n  const near=boxOf(node);let selected:T.Group=body,bestContacts=-1,bestDistance=Infinity;\r\n  if(near.isEmpty())return body;\r\n  for(const candidate of [body,head]){if(boxOf(candidate).isEmpty())continue;const {lookup}=surfaceDistance(candidate,near,touch,touch+band),v=new T.Vector3();let contacts=0,minDistance=Infinity;\r\n   for(const mesh of meshes(node)){const p=mesh.geometry.getAttribute('position');for(let i=0;i<p.count;i++){v.fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld);const d=lookup(v);if(d<touch)contacts++;if(d<minDistance)minDistance=d;}}\r\n   if(contacts>bestContacts||(contacts===bestContacts&&minDistance<bestDistance)){selected=candidate;bestContacts=contacts;bestDistance=minDistance;}\r\n  }\r\n  return selected;\r\n }\r\n function glue(node:T.Group,touch:number,band:number,movePivot=false,anchor:T.Object3D=body){\r\n  const box=boxOf(node),parts=meshes(node);if(box.isEmpty())return;\r\n  const limb=/^(Arm|Foot)/.test(node.name)&&((node.name.startsWith('Arm')?recipe.armsFrom:recipe.feetFrom)!=='myr5'),size=box.getSize(new T.Vector3()),limbExtent=Math.max(size.x,size.y,size.z);\r\n  const {lookup:distance,voxel}=surfaceDistance(anchor,box,touch,touch+band),v=new T.Vector3(),seam=new T.Vector3();let count=0;\r\n  // A coarse grid (very large parts) widens the welded band so voxel rounding never loosens the seam.\r\n  touch=Math.max(touch,2*voxel);const reach=touch+band;\r\n  let highestContact=-Infinity;\r\n  const distances=parts.map(mesh=>{const p=mesh.geometry.getAttribute('position'),d=new Float32Array(p.count);for(let i=0;i<p.count;i++){v.fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld);d[i]=distance(v);if(d[i]<touch)highestContact=Math.max(highestContact,v.y);}return d;});\r\n  parts.forEach((mesh,j)=>{const p=mesh.geometry.getAttribute('position');for(let i=0;i<p.count;i++){v.fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld);if(distances[j][i]<touch&&(!limb||v.y>=highestContact-limbExtent*.15)){seam.add(v);count++;}}});\r\n  if(!count)return;\r\n  const joint=seam.divideScalar(count);\r\n  const weldSize=Math.max(1e-5,limbExtent*1e-4),anchorVertices=new Map<string,T.Vector3[]>(),weldKey=(x:number,y:number,z:number)=>`${x},${y},${z}`;\r\n  if(limb)for(const mesh of meshes(anchor)){const p=mesh.geometry.getAttribute('position');for(let i=0;i<p.count;i++){const point=new T.Vector3().fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld),key=weldKey(Math.round(point.x/weldSize),Math.round(point.y/weldSize),Math.round(point.z/weldSize));const list=anchorVertices.get(key)||[];list.push(point);anchorVertices.set(key,list);}}\r\n  const isCutSeam=(point:T.Vector3)=>{const x=Math.round(point.x/weldSize),y=Math.round(point.y/weldSize),z=Math.round(point.z/weldSize);for(let dx=-1;dx<=1;dx++)for(let dy=-1;dy<=1;dy++)for(let dz=-1;dz<=1;dz++)for(const other of anchorVertices.get(weldKey(x+dx,y+dy,z+dz))||[])if(point.distanceToSquared(other)<=weldSize*weldSize)return true;return false;};\r\n  if(movePivot){const shift=joint.clone().sub(node.getWorldPosition(v));node.position.add(shift);for(const child of node.children)if(child instanceof T.Mesh)child.geometry.translate(-shift.x,-shift.y,-shift.z);else child.position.sub(shift);root.updateMatrixWorld(true);}\r\n  parts.forEach((mesh,j)=>{const g=mesh.geometry,d=distances[j],index=new Uint16Array(d.length*4),w=new Float32Array(d.length*4);\r\n   const connectedToAnchor=new Uint8Array(d.length);\r\n   if(limb)for(const faces of connectedTriangleComponents(mesh)){\r\n    const vertices=new Set<number>();for(const face of faces)for(let k=0;k<3;k++)vertices.add(g.index?g.index.getX(face*3+k):face*3+k);\r\n    if([...vertices].some(i=>d[i]<touch))for(const i of vertices)connectedToAnchor[i]=1;\r\n   }\r\n   // Separate armor, hands and toes follow the limb rigidly. Only components\r\n   // that actually meet the anchor need a blended shoulder/hip seam.\r\n   for(let i=0;i<d.length;i++){v.fromBufferAttribute(g.getAttribute('position'),i).applyMatrix4(mesh.matrixWorld);const distal=limb?T.MathUtils.smoothstep(v.distanceTo(joint),limbExtent*.15,limbExtent*.5):0,own=limb&&!connectedToAnchor[i]?1:limb&&v.distanceTo(joint)<=limbExtent*.35&&isCutSeam(v)?0:Math.max(distal,T.MathUtils.smoothstep(d[i],touch,reach));index[i*4+1]=1;w[i*4]=1-own;w[i*4+1]=own;}\r\n   g.setAttribute('skinIndex',new T.Uint16BufferAttribute(index,4));g.setAttribute('skinWeight',new T.Float32BufferAttribute(w,4));g.computeBoundingSphere();\r\n   const skinned=new T.SkinnedMesh(g,mesh.material);skinned.name=mesh.name;node.remove(mesh);node.add(skinned);skinned.bind(new T.Skeleton([anchor,node] as unknown as T.Bone[]));});\r\n }\r\n const headBox=boxOf(head),headH=headBox.max.y-headBox.min.y,eyeY=Math.min(...Object.keys(nodes).filter(n=>n.startsWith('EyeBlink')).map(n=>nodes[n].getWorldPosition(new T.Vector3()).y));\r\n // The neck blends in below the eyes (they ride the head rigidly), over at most 30% of the head.\r\n glue(head,.06*Math.max(headH,headBox.max.x-headBox.min.x),T.MathUtils.clamp(.6*(eyeY-headBox.min.y),.12*headH,.3*headH),true);\r\n // Roster arms share a narrow, body-weighted shoulder seam; the source MYR5 arms keep their existing pivots.\r\n if(recipe.armsFrom!=='myr5'){\r\n  const arms=[nodes.ArmLeft,nodes.ArmRight],largest=Math.max(...arms.map(arm=>{const size=boxOf(arm).getSize(new T.Vector3());return Math.max(size.x,size.y,size.z);}));\r\n  if(largest>0)for(const arm of arms){const touch=.04*largest,band=.15*largest,anchor=closestAnchor(arm,touch,band);glue(arm,touch,band,true,anchor);}\r\n }\r\n // A foot's scale is its largest side: a leg's length, a flat foot's length.\r\n for(const foot of [nodes.FootLeft,nodes.FootRight]){const size=boxOf(foot).getSize(new T.Vector3()),h=Math.max(size.x,size.y,size.z),touch=.15*h,band=.5*h,anchor=recipe.feetFrom!=='myr5'?closestAnchor(foot,touch,band):body;glue(foot,touch,band,recipe.feetFrom!=='myr5',anchor);}\r\n const rest=Object.fromEntries(Object.entries(nodes).map(([name,node])=>[name,{position:node.position.clone(),scale:node.scale.clone(),quaternion:node.quaternion.clone()}]));\r\n return {root,nodes,rest,recipe};\r\n}\r\nexport type CreatureRig=ReturnType<typeof createRig>;\r\n","creature/source/rous-ownership.ts":"import * as THREE from 'three';\r\nimport {connectedTriangleComponents, triangleSubset} from './limb-ownership';\r\n\r\nconst ROUS = 'roster/09-monolith-tanka--robot_3d_model2';\r\n\r\n/** Recover the exact left arm pieces placed in the body and feet cuts of Rous. */\r\nexport function correctRousArmOwnership(source: THREE.Group, sourceId: string) {\r\n  if (sourceId !== ROUS) return 0;\r\n  source.updateWorldMatrix(true, true);\r\n  const arms = source.getObjectByName('arms'), body = source.getObjectByName('body'), feet = source.getObjectByName('feet');\r\n  if (!arms || !body || !feet) return 0;\r\n  const intoArms = arms.matrixWorld.clone().invert();\r\n  let recovered = 0;\r\n  const extracted: Record<'body' | 'feet', number> = {body: 0, feet: 0};\r\n  const recover = (group: THREE.Object3D, sourceRegion: 'body' | 'feet') => {\r\n    const meshes: THREE.Mesh[] = [];\r\n    group.traverse(o => { if (o instanceof THREE.Mesh && o.visible && !Array.isArray(o.material)) meshes.push(o); });\r\n    for (const mesh of meshes) {\r\n      const position = mesh.geometry.getAttribute('position'), index = mesh.geometry.index;\r\n      const chosen = new Set<number>();\r\n      for (const component of connectedTriangleComponents(mesh)) {\r\n        if (component.length < (sourceRegion === 'body' ? 100 : 500)) continue;\r\n        const bounds = new THREE.Box3(); let centerX = 0, centerY = 0, count = 0;\r\n        for (const face of component) for (let k = 0; k < 3; k++) {\r\n          const vertex = index ? index.getX(face * 3 + k) : face * 3 + k;\r\n          const point = new THREE.Vector3().fromBufferAttribute(position, vertex).applyMatrix4(mesh.matrixWorld);\r\n          bounds.expandByPoint(point); centerX += point.x; centerY += point.y; count++;\r\n        }\r\n        centerX /= count; centerY /= count;\r\n        // The left shoulder and forearm sit wholly outside the source body midpoint.\r\n        // The feet-cut glove is the sole large negative-X component reaching above the floor.\r\n        const isLeftShoulder = sourceRegion === 'body' && centerX < 0 && bounds.max.x < .24 && bounds.min.y > 1.05 && bounds.max.y < 1.9;\r\n        const isLeftGlove = sourceRegion === 'feet' && centerX < 0 && centerY > .5 && bounds.max.y <= 1.081;\r\n        if (isLeftShoulder || isLeftGlove) component.forEach(face => chosen.add(face));\r\n      }\r\n      if (!chosen.size) continue;\r\n      const original = mesh.geometry, movedGeometry = triangleSubset(original, face => chosen.has(face));\r\n      const remaining = triangleSubset(original, face => !chosen.has(face));\r\n      if (!movedGeometry) continue;\r\n      const transform = intoArms.clone().multiply(mesh.matrixWorld);\r\n      movedGeometry.applyMatrix4(transform);\r\n      recovered += chosen.size;\r\n      if (remaining) { mesh.geometry = remaining; original.dispose(); }\r\n      else { mesh.removeFromParent(); original.dispose(); }\r\n      const recoveredMesh = new THREE.Mesh(movedGeometry, mesh.material as THREE.Material);\r\n      recoveredMesh.name = `Rous recovered left arm from ${sourceRegion}`;\r\n      recoveredMesh.userData.region = 'arms';\r\n      recoveredMesh.userData.rousRecoveredArmSource = sourceRegion;\r\n      recoveredMesh.userData.rousRecoveredArmTriangles = chosen.size;\r\n      arms.add(recoveredMesh);\r\n    }\r\n  };\r\n  recover(body, 'body'); recover(feet, 'feet');\r\n  source.updateWorldMatrix(true, true);\r\n  const meshMaterial = (group: THREE.Object3D) => { let result: THREE.Material | undefined; group.traverse(o => { if (!result && o instanceof THREE.Mesh && o.visible && !Array.isArray(o.material)) result = o.material; }); return result; };\r\n  const targets = {body, feet};\r\n  const materials = {body: meshMaterial(body), feet: meshMaterial(feet)};\r\n  const moveArmFragments = (target: 'body' | 'feet') => {\r\n    const targetMaterial = materials[target]; if (!targetMaterial) return;\r\n    const meshes: THREE.Mesh[] = [];\r\n    arms.traverse(o => { if (o instanceof THREE.Mesh && o.visible && !Array.isArray(o.material)) meshes.push(o); });\r\n    for (const mesh of meshes) {\r\n      const position = mesh.geometry.getAttribute('position'), index = mesh.geometry.index, selected = new Set<number>();\r\n      for (const component of connectedTriangleComponents(mesh)) {\r\n        let x = 0, y = 0, count = 0; const bounds = new THREE.Box3();\r\n        for (const face of component) for (let k = 0; k < 3; k++) {\r\n          const vertex = index ? index.getX(face * 3 + k) : face * 3 + k;\r\n          const point = new THREE.Vector3().fromBufferAttribute(position, vertex).applyMatrix4(mesh.matrixWorld);\r\n          x += point.x; y += point.y; count++; bounds.expandByPoint(point);\r\n        }\r\n        x /= count; y /= count;\r\n        const footShard = target === 'feet' && component.length >= 150 && x > 1.5 && x < 1.7 && y < .22 && bounds.max.y < .4;\r\n        const pelvisShard = target === 'body' && component.length >= 20 && component.length <= 50 && x > 1.14 && x < 1.4 && y > 1.08 && y < 1.12 && bounds.max.y < 1.15;\r\n        if (footShard || pelvisShard) component.forEach(face => selected.add(face));\r\n      }\r\n      if (!selected.size) continue;\r\n      const original = mesh.geometry, movedGeometry = triangleSubset(original, face => selected.has(face)), remaining = triangleSubset(original, face => !selected.has(face));\r\n      if (!movedGeometry) continue;\r\n      const transform = targets[target].matrixWorld.clone().invert().multiply(mesh.matrixWorld);\r\n      movedGeometry.applyMatrix4(transform); extracted[target] += selected.size;\r\n      if (remaining) { mesh.geometry = remaining; original.dispose(); } else { mesh.removeFromParent(); original.dispose(); }\r\n      const fragment = new THREE.Mesh(movedGeometry, targetMaterial); fragment.name = `Rous recovered ${target} fragment from arms`;\r\n      fragment.userData.region = target; fragment.userData.rousRecoveredFromArms = target; fragment.userData.rousRecoveredArmTriangles = selected.size;\r\n      targets[target].add(fragment);\r\n    }\r\n  };\r\n  moveArmFragments('body'); moveArmFragments('feet');\r\n  source.updateWorldMatrix(true, true);\r\n  source.userData.rousRecoveredArmTriangles = recovered;\r\n  source.userData.rousExtractedFromArms = extracted;\r\n  return recovered;\r\n}\r\n","creature/source/save-look.ts":"// #1 / #102 trust boundary: the customizer's only writer of the coach recipe. Whatever reaches it\r\n// (a preview, devtools, an imported file) leaves with no locked texture, colour, palette or body,\r\n// so the account sync that reads storage never sees one either. Nothing here grants anything.\r\nimport type {Design,Region,MaterialChoice} from './creator/design';\r\nimport {isLocked as idLocked} from './creator/materials-registry';\r\nimport {bodyLockSection} from './creator/track-placements';\r\nimport {loadProgress,selectedTracks} from '../../battle-pass.mjs';\r\nimport {ownedShipIds} from '../../modules/ships/ship-access.mjs';\r\nimport {RECIPE_KEY} from './profile';\r\nimport {normalizeStyleId,normalizeTextureId} from './creator/texture-policy.mjs';\r\n\r\nconst ownedChoice=(c:MaterialChoice|undefined,coachId:string):c is MaterialChoice=>!!c&&!idLocked(c.textureId,coachId)&&!idLocked(c.colorId,coachId,'color');\r\nexport const BODY_KEYS=['body','headFrom','armsFrom','feetFrom'] as const;\r\n/** An earned body must not inherit another coach's exclusive material grants. */\r\nexport function selectOwnedBody(design:Design,id:Design['body']):Design{\r\n if(bodyLockSection(id,loadProgress()))throw Error('This coach is locked.');\r\n return keepOwned({...design,body:id,headFrom:id,armsFrom:id,feetFrom:id},design);\r\n}\r\n\r\n/** Locked material regions fall back to the last earned choice or original style. Body sources\r\n * must pass the live performance access gate, including bodies present in an older saved recipe.\r\n * The legacy grandfathered argument is accepted only to keep existing editor callers compatible. */\r\nexport function keepOwned(d:Design,lastOwned?:Design,_grandfathered:ReadonlySet<string>=new Set(),progress:Record<string,number>=loadProgress(),tracks:Iterable<string>=selectedTracks()):Design{\r\n const bodyOk=(id?:string):id is string=>!!id&&!bodyLockSection(id,progress,tracks);\r\n let next=d;\r\n const retired=Object.values(d.styles).some(style=>normalizeStyleId(style)!==style)||Object.values(d.materials??{}).some(choice=>choice&&normalizeTextureId(choice.textureId)!==choice.textureId);\r\n if(retired)next={...d,styles:Object.fromEntries(Object.entries(d.styles).map(([region,style])=>[region,normalizeStyleId(style)])) as Design['styles'],materials:d.materials&&Object.fromEntries(Object.entries(d.materials).map(([region,choice])=>[region,choice&&{...choice,textureId:normalizeTextureId(choice.textureId)}])) as Design['materials']};\r\n for(const key of BODY_KEYS)if(!bodyOk(next[key])){const fallback=lastOwned?.[key];next={...next,[key]:bodyOk(fallback)?fallback:'myr5'};}\r\n const ownedShips=new Set(ownedShipIds());\r\n const shipOk=(id:Design['shipId']):id is NonNullable<Design['shipId']>=>!!id&&(id==='supportive'||ownedShips.has(id));\r\n const chosenShip=next.shipId??next.coach;\r\n if(!shipOk(chosenShip)){\r\n  const fallback=lastOwned?.shipId??lastOwned?.coach;\r\n  next={...next,shipId:shipOk(fallback)?fallback:'supportive'};\r\n }\r\n if(next.materials&&!Object.values(next.materials).every(choice=>ownedChoice(choice,next.body))){\r\n  const materials:Design['materials']={};\r\n  for(const [region,choice] of Object.entries(next.materials) as [Region,MaterialChoice][]){const keep=ownedChoice(choice,next.body)?choice:lastOwned?.materials?.[region];if(ownedChoice(keep,next.body))materials[region]=keep;}\r\n  next={...next,materials:Object.keys(materials).length?materials:undefined};\r\n }\r\n return next;\r\n}\r\n\r\nexport function saveRecipe(storage:Storage,next:Design,lastOwned?:Design,_grandfathered?:ReadonlySet<string>){\r\n const owned=keepOwned(next,lastOwned);storage.setItem(RECIPE_KEY,JSON.stringify(owned));return owned;\r\n}\r\n","creature/source/sculpt-hands.py":"\"\"\"Rebuild the five MYR5 finger-count variants in the existing anatomy GLB.\"\"\"\r\nimport bpy, math, sys\r\nfrom pathlib import Path\r\nfrom mathutils import Vector\r\n\r\nroot=Path(__file__).parent/'coach-app'/'creature'/'models'\r\nbpy.ops.object.select_all(action='SELECT');bpy.ops.object.delete(use_global=False)\r\nbpy.ops.import_scene.gltf(filepath=str(root/'anatomy.glb'))\r\nskin=bpy.data.materials.new('MYR5 sculpted skin');skin.diffuse_color=(.20,.048,.32,1);skin.use_nodes=True\r\nbsdf=skin.node_tree.nodes.get('Principled BSDF');bsdf.inputs['Base Color'].default_value=(.20,.048,.32,1);bsdf.inputs['Roughness'].default_value=.48\r\nbsdf.inputs['Subsurface Weight'].default_value=.065\r\n\r\ndef finish(o,parts):\r\n    o.data.materials.clear();o.data.materials.append(skin);parts.append(o)\r\n    return o\r\n\r\ndef ellipsoid(name,center,scale,parts):\r\n    bpy.ops.mesh.primitive_uv_sphere_add(segments=24,ring_count=16,location=center)\r\n    o=bpy.context.object;o.name=name;o.scale=scale\r\n    bpy.ops.object.transform_apply(location=False,rotation=False,scale=True)\r\n    return finish(o,parts)\r\n\r\ndef tube(name,points,radii,parts):\r\n    # Round, smoothly tapered sections along the centerline. Dense enough to\r\n    # preserve finger gaps when the palm and knuckles are fused below.\r\n    curve=bpy.data.curves.new(name,'CURVE');curve.dimensions='3D';curve.resolution_u=10\r\n    curve.bevel_depth=1;curve.bevel_resolution=4;curve.use_fill_caps=True\r\n    spline=curve.splines.new('BEZIER');spline.bezier_points.add(len(points)-1)\r\n    for p,co,r in zip(spline.bezier_points,points,radii):\r\n        p.co=co;p.radius=r;p.handle_left_type='AUTO';p.handle_right_type='AUTO'\r\n    o=bpy.data.objects.new(name,curve);bpy.context.collection.objects.link(o)\r\n    bpy.ops.object.select_all(action='DESELECT');o.select_set(True);bpy.context.view_layer.objects.active=o\r\n    bpy.ops.object.convert(target='MESH');finish(bpy.context.object,parts)\r\n    ellipsoid(name+' pad',points[-1],(radii[-1],)*3,parts)\r\n\r\ndef build(count):\r\n    prior=bpy.data.objects.get('arms_'+str(count))\r\n    if prior:\r\n        for child in list(prior.children_recursive):bpy.data.objects.remove(child,do_unlink=True)\r\n        bpy.data.objects.remove(prior,do_unlink=True)\r\n    parts=[]\r\n    # Both shoulders still meet the original body and animation pivots.\r\n    tube('Left forearm',[(-.58,-.03,1.508),(-.78,-.02,1.28),(-.92,-.14,1.02),(-.94,-.22,.90)],[.155,.13,.108,.095],parts)\r\n    tube('Right forearm',[(.59,-.04,1.518),(.81,-.12,1.35),(.98,-.33,1.44),(1.05,-.48,1.58)],[.16,.14,.112,.10],parts)\r\n    for side in [-1,1]:\r\n        center=Vector((-.94,-.24,.79) if side<0 else (1.065,-.52,1.72))\r\n        direction=-1 if side<0 else 1\r\n        def at(x,z,depth=0):return center+Vector((x,-depth,direction*z))\r\n        # Palm has a rounded heel, dorsal arch and thumb mound, instead of a ball.\r\n        ellipsoid('Palm arch',center,(.174,.090,.160),parts)\r\n        ellipsoid('Palm heel',at(0,-.09,-.004),(.123,.081,.116),parts)\r\n        ellipsoid('Thumb mound',at(-side*.111,-.025,.035),(.093,.076,.115),parts)\r\n        fingers=count-1\r\n        spacing=.275/max(1,fingers-1)\r\n        radius=min(.053,spacing*.35)\r\n        for i in range(fingers):\r\n            fraction=i/max(1,fingers-1)\r\n            x=(fraction-.5)*.275 if fingers>1 else 0\r\n            length=.225+.065*math.sin(fraction*math.pi)\r\n            # Separate rounded knuckles, staggered lengths and a gentle resting curl.\r\n            spread=x*.20\r\n            pts=[at(x,.086),at(x+spread*.25,.17,.008),at(x+spread*.65,.17+length*.48,.035),at(x+spread,.17+length*.85,.076)]\r\n            tube('Finger '+str(i+1),pts,[radius*1.16,radius,radius*.84,radius*.67],parts)\r\n            ellipsoid('Knuckle',at(x,.149,-.018),(radius*1.13,radius*.83,radius*1.15),parts)\r\n            # Short web at the roots leaves clearly open spaces along each shaft.\r\n            if i:\r\n                ellipsoid('Finger web',at(x-spacing*.5,.082), (spacing*.64,.065,.057),parts)\r\n        thumb=[at(-side*.113,-.035,.026),at(-side*.211,.006,.055),at(-side*.253,.083,.102),at(-side*.223,.157,.141)]\r\n        tube('Opposed thumb',thumb,[.076,.065,.052,.040],parts)\r\n    bpy.ops.object.select_all(action='DESELECT')\r\n    for o in parts:o.select_set(True)\r\n    bpy.context.view_layer.objects.active=parts[0];bpy.ops.object.join();mesh=bpy.context.object\r\n    mesh.name='Sculpted palms and tapered fingers'\r\n    def apply(mod):bpy.ops.object.modifier_apply(modifier=mod.name)\r\n    rem=mesh.modifiers.new('Continuous wrist and palm','REMESH');rem.mode='VOXEL';rem.voxel_size=.007;apply(rem)\r\n    smooth=mesh.modifiers.new('Soften anatomy','SMOOTH');smooth.factor=.45;smooth.iterations=4;apply(smooth)\r\n    dec=mesh.modifiers.new('Phone mesh','DECIMATE');dec.ratio=.4;apply(dec)\r\n    for p in mesh.data.polygons:p.use_smooth=True\r\n    parent=bpy.data.objects.new('arms_'+str(count),None);bpy.context.collection.objects.link(parent);mesh.parent=parent\r\n    mesh['anatomyVersion']=2;mesh['digitsPerHand']=count\r\n    print('SCULPTED',count,len(mesh.data.polygons),flush=True)\r\n\r\nfor count in range(2,7):build(count)\r\nbpy.ops.object.select_all(action='DESELECT')\r\nfor o in bpy.context.scene.objects:\r\n    if o.name.startswith('arms_'):\r\n        o.select_set(True)\r\n        for child in o.children_recursive:child.select_set(True)\r\nbpy.ops.export_scene.gltf(filepath=str(root/'hands-v2.glb'),export_format='GLB',use_selection=True,export_yup=True)\r\nprint('HANDS_READY',flush=True)\r\n","creature/source/ship-preview.ts":"// Ship tab preview: the chosen owned ship, turning slowly in its tint. Models come only from the verified local\r\n// bridge (signed, owned, already-downloaded \"Ships and worlds\" bytes as blob: URLs); nothing here downloads.\r\n// Its own small renderer draws only while the panel is on screen.\r\nimport * as T from 'three';\r\nimport {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport {SHIP_FACING,applyShipTint} from '../../modules/ships/ship-scene-domain.mjs';\r\nimport {shipDetails} from '../../modules/ships/ship-catalog.mjs';\r\n\r\nexport type ShipBridge={ownedShipIds():string[];getShipUrl(id:string):string;dispose?():void};\r\n\r\nfunction disposeModel(root:T.Object3D){root.traverse(node=>{const mesh=node as T.Mesh;mesh.geometry?.dispose();for(const m of ([] as T.Material[]).concat(mesh.material||[])){for(const value of Object.values(m))if((value as T.Texture)?.isTexture)(value as T.Texture).dispose();m.dispose();}});}\r\n\r\nexport function mountShipPreview(host:HTMLElement,bridge:ShipBridge){\r\n const canvas=document.createElement('canvas');canvas.className='ship-preview';canvas.style.cssText='position:absolute;inset:0;width:100%;height:100%';canvas.setAttribute('role','img');host.prepend(canvas);\r\n let renderer:T.WebGLRenderer;\r\n try{renderer=new T.WebGLRenderer({canvas,alpha:true,antialias:true});}catch(error){canvas.remove();bridge.dispose?.();throw error;}\r\n renderer.outputColorSpace=T.SRGBColorSpace;renderer.toneMapping=T.ACESFilmicToneMapping;renderer.toneMappingExposure=1.15;renderer.setPixelRatio(Math.min(devicePixelRatio,2));\r\n const scene=new T.Scene(),camera=new T.PerspectiveCamera(34,1,.1,100),turn=new T.Group();\r\n camera.position.set(0,1.4,7);camera.lookAt(0,0,0);scene.add(turn,new T.HemisphereLight(0xe9d9ff,0x23162d,2.5));\r\n const key=new T.DirectionalLight(0xffefca,4.2);key.position.set(-3,5,4);const rim=new T.DirectionalLight(0xb58cff,3.2);rim.position.set(4,2,-3);scene.add(key,rim);\r\n const loader=new GLTFLoader(),models=new Map<string,Promise<T.Object3D>>();\r\n let shown:T.Object3D|null=null,epoch=0,raf=0,disposed=false;\r\n // Same normalization as the arrival scene: centred, longest side 2.25, stern to the viewer then a quarter turn.\r\n function load(id:string){\r\n  let model=models.get(id);\r\n  if(!model){model=loader.loadAsync(bridge.getShipUrl(id)).then(gltf=>{\r\n   const box=new T.Box3().setFromObject(gltf.scene),size=box.getSize(new T.Vector3());gltf.scene.position.sub(box.getCenter(new T.Vector3()));\r\n   const root=new T.Group();root.add(gltf.scene);root.rotation.y=SHIP_FACING;root.scale.setScalar(2.25/(Math.max(size.x,size.y,size.z)||1));\r\n   if(disposed)disposeModel(root);return root;\r\n  });model.catch(()=>models.delete(id));models.set(id,model);}\r\n  return model;\r\n }\r\n function tint(color:string){if(shown)applyShipTint(shown,color==='#ffffff'?null:color);}\r\n const reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n function tick(now:number){\r\n  raf=0;if(disposed||document.hidden)return;\r\n  const w=canvas.clientWidth,h=canvas.clientHeight;\r\n  if(w&&h&&shown){\r\n   if(canvas.width!==Math.round(w*renderer.getPixelRatio())||canvas.height!==Math.round(h*renderer.getPixelRatio())){renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();}\r\n   turn.rotation.y=reduced()?-.32:now/2400;renderer.render(scene,camera);\r\n  }\r\n  raf=requestAnimationFrame(tick);\r\n }\r\n const resume=()=>{if(document.hidden){cancelAnimationFrame(raf);raf=0;return;}if(!disposed&&!raf)raf=requestAnimationFrame(tick);};\r\n document.addEventListener('visibilitychange',resume);resume();\r\n return {\r\n  /** Resolves true once `id` is on screen; false if a later show() or dispose() overtook it. Throws if its bytes fail. */\r\n  async show(id:string,color='#ffffff'){\r\n   const run=++epoch,model=await load(id);if(disposed||run!==epoch)return false;\r\n   if(shown)turn.remove(shown);shown=model;turn.add(model);tint(/^#[0-9a-f]{6}$/i.test(color)?color:'#ffffff');canvas.dataset.ship=id;canvas.setAttribute('aria-label',`${shipDetails(id).name}: ${shipDetails(id).description}`);return true;\r\n  },\r\n  tint:(color:string)=>tint(/^#[0-9a-f]{6}$/i.test(color)?color:'#ffffff'),\r\n  ids:()=>bridge.ownedShipIds(),\r\n  dispose(){if(disposed)return;disposed=true;++epoch;document.removeEventListener('visibilitychange',resume);cancelAnimationFrame(raf);for(const model of models.values())model.then(disposeModel,()=>{});models.clear();renderer.dispose();renderer.forceContextLoss();canvas.remove();bridge.dispose?.();},\r\n };\r\n}\r\n","creature/source/torso-panel-ownership.ts":"import * as T from 'three';\r\nimport {connectedTriangleComponents,triangleSubset} from './limb-ownership';\r\n\r\nconst CASK='roster/11-anvil-cask--clay-style_robot_3d_model';\r\nconst ALIEN='roster/22-curve--stylized_alien_3d_model';\r\nconst HONEYCOMB='roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model';\r\nconst GHOST='roster/10-petal-wisp--ghost_character_3d_model';\r\nconst SPIRIT='roster/10-petal-wisp--fantasy_creature_3d_model4';\r\n\r\n/** Restore torso surfaces removed by the roster's vertical arm cuts and horizontal hip cut. */\r\nexport function correctTorsoPanelOwnership(source:T.Group,id:string){\r\n if(![CASK,ALIEN,HONEYCOMB,GHOST,SPIRIT].includes(id))return 0;\r\n source.updateWorldMatrix(true,true);const body=source.getObjectByName('body'),region=source.getObjectByName(id===CASK?'feet':'arms');if(!body||!region)return 0;\r\n const bodyMeshes:T.Mesh[]=[],meshes:T.Mesh[]=[];body.traverse(o=>{if(o instanceof T.Mesh&&!Array.isArray(o.material))bodyMeshes.push(o);});region.traverse(o=>{if(o instanceof T.Mesh&&!Array.isArray(o.material))meshes.push(o);});if(!bodyMeshes.length)return 0;\r\n const samples:T.Vector3[]=[];for(const m of bodyMeshes){if(m.userData.restoredTorsoPanelTriangles)continue;const p=m.geometry.getAttribute('position');for(let i=0;i<p.count;i++)samples.push(new T.Vector3().fromBufferAttribute(p,i).applyMatrix4(m.matrixWorld));}\r\n const box=new T.Box3().setFromPoints(samples);\r\n // Honeycomb's arm cut goes through the torso at x=±.325. Its actual\r\n // shoulder necks are at x=±.85; retain the complete inner torso wall.\r\n let moved=0;\r\n for(const m of meshes){const g=m.geometry,p=g.getAttribute('position'),idx=g.index,selected=new Set<number>();\r\n  if(id===CASK){for(const component of connectedTriangleComponents(m)){const b=new T.Box3();for(const f of component)for(let k=0;k<3;k++)b.expandByPoint(new T.Vector3().fromBufferAttribute(p,idx?idx.getX(f*3+k):f*3+k).applyMatrix4(m.matrixWorld));if(component.length===379&&b.min.x<-.6&&b.max.x>.6&&b.min.y>.63)for(const f of component)selected.add(f);}}\r\n  else{for(let f=0;f<(idx?.count??p.count)/3;f++){const v=new T.Vector3();for(let k=0;k<3;k++)v.add(new T.Vector3().fromBufferAttribute(p,idx?idx.getX(f*3+k):f*3+k).applyMatrix4(m.matrixWorld));v.divideScalar(3);\r\n   if(id===ALIEN){if(Math.abs(v.x)<.435&&v.y>=.929&&v.y<=1.64)selected.add(f);}\r\n   else if(id===GHOST){if(Math.abs(v.x)<.60&&v.y>=.929&&v.y<1.5)selected.add(f);}\r\n   else if(id===SPIRIT){if(Math.abs(v.x)<.36&&v.y>=.929&&v.y<1.8)selected.add(f);}\r\n   else if(v.y>=box.min.y-.012&&v.y<=box.max.y+.005&&Math.abs(v.x)<.85)selected.add(f);\r\n  }}\r\n  if(!selected.size)continue;const restored=triangleSubset(g,f=>selected.has(f)),remaining=triangleSubset(g,f=>!selected.has(f));if(!restored)continue;\r\n  restored.applyMatrix4(body.matrixWorld.clone().invert().multiply(m.matrixWorld));if(remaining)m.geometry=remaining;else m.removeFromParent();g.dispose();const part=new T.Mesh(restored,bodyMeshes[0].material);part.name='Restored torso panel';part.userData.restoredTorsoPanelTriangles=selected.size;body.add(part);moved+=selected.size;\r\n }\r\n source.updateWorldMatrix(true,true);return moved;\r\n}\r\n","creature/source/viewer.ts":"import * as T from 'three';\r\nimport {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';\r\nimport {RoomEnvironment} from 'three/examples/jsm/environments/RoomEnvironment.js';\r\nimport {GLTFExporter} from 'three/examples/jsm/exporters/GLTFExporter.js';\r\nimport {clone as cloneSkinned} from 'three/examples/jsm/utils/SkeletonUtils.js';\r\nimport {assembleCreature,type InstalledSkinResolver} from './creator/assemble';\r\nimport {createRig,disposeObject,type CreatureRig} from './rig';\r\nimport {MotionController,type Gesture} from './motion';\r\nimport {importCreature,motionSettings} from './profile';\r\nimport {sampleShot,SHOTS,type Cinematic} from './cinematic-shots';\r\nimport {regionBounds,frameRegion,regionFrame} from './creator/camera-focus';\r\nimport {REGIONS,type Region,type Design} from './creator/design';\r\nimport {podCameraFrame} from './pod-camera';\r\nimport {createCoachPreviewSpace} from '../../coach-preview-space.mjs';\r\nimport {createCharacterPhysics} from '../../character-phone-physics.mjs';\r\nimport {subscribePhoneMotion} from './phone-motion';\r\nimport {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport {SHIP_FACING,applyShipTint} from '../../modules/ships/ship-scene-domain.mjs';\r\nimport {localVerifiedBridge} from '../../modules/ships/verified-ship-assets.mjs';\r\nimport {ownedShipIds,SHIP_IDS} from '../../modules/ships/ship-access.mjs';\r\nimport {projectAvatarPowerAnchors} from '../power-anchors.mjs';\r\n\r\nexport const ZOOM_MIN=0,ZOOM_MAX=1;\r\nexport class CreatureViewer {\r\n regionBoxes=new Map<Region,T.Box3>();focused:Region|null=null;\r\n // #9: 'body' frames the whole creature (every region) plus a little headroom for raised arms and hops;\r\n // side 1 is the front view, -1 the back (kept for later part focus so Back stays Back).\r\n  side=1;zoom=0;\r\n  applyZoom(){if(!this.bodyBounds||this.bodyBounds.isEmpty())return;const bb=this.bodyBounds.clone();bb.max.y+=(bb.max.y-bb.min.y)*.08;const full=regionFrame(this.camera,bb,1.15,this.side);if(!full)return;let box:T.Box3|undefined;for(const b of[this.regionBoxes.get('head'),this.regionBoxes.get('eye')])if(b&&!b.isEmpty())box=box?box.union(b):b.clone();const h=box?regionFrame(this.camera,box,1.45,this.side):null,head=h??full,t=this.zoom,target=full.target.clone().lerp(head.target,t),distance=full.distance+(head.distance*.9-full.distance)*t,dir=this.camera.position.clone().sub(this.orbit.target);dir.length()<1e-6?dir.set(0,0,this.side):dir.normalize();this.orbit.minDistance=Math.min(.7,head.distance*.5);this.orbit.maxDistance=Math.max(14,full.distance*2);this.orbit.target.copy(target);this.camera.position.copy(target).addScaledVector(dir,distance);this.orbit.update();}\r\n  setZoom(z:number){this.zoom=Math.min(ZOOM_MAX,Math.max(ZOOM_MIN,Number.isFinite(z)?z:1));this.applyZoom();return this.zoom;}\r\n  focusRegion(region:Region){this.focused=region;if(region==='body'){const ok=!!this.bodyBounds&&!this.bodyBounds.isEmpty();if(ok){this.camera.position.copy(this.orbit.target).add(new T.Vector3(0,0,this.side));this.applyZoom();}return ok;}const box=this.regionBoxes.get(region);if(!box)return false;return frameRegion(this.camera,this.orbit,box,1.2,this.side);}\r\n homeElapsed=0;homeMoving=false;bodyBounds=new T.Box3();\r\n setHomeMotion(moving:boolean){this.homeMoving=moving;}\r\n homeView(){\r\n  if(this.interactive||this.stage!=='pod')return;\r\n  const head=this.regionBoxes.get('head');if(!head)return;\r\n  const frame=podCameraFrame(this.camera,head,this.bodyBounds,this.homeElapsed);if(!frame)return;\r\n  this.orbit.minDistance=.3;this.orbit.maxDistance=frame.maxDistance;this.orbit.target.copy(frame.target);this.camera.position.copy(frame.position);this.orbit.update();\r\n }\r\n cinematicKind:Cinematic|null=null;\r\n cinematic(kind:Cinematic|null,elapsed=0){\r\n  if(!kind){if(!this.cinematicKind)return;this.cinematicKind=null;this.resetStageView();this.play('idle');return;}\r\n  if(!Object.hasOwn(SHOTS,kind)||this.settings.reduced)return;\r\n  if(this.cinematicKind!==kind){this.cinematicKind=kind;this.play(SHOTS[kind].gesture);}\r\n  const [x,y,z,target]=sampleShot(kind,elapsed);this.camera.position.set(x,y,z);this.orbit.target.set(0,target,0);this.camera.fov=36;this.camera.updateProjectionMatrix();this.orbit.update();\r\n }\r\n scene=new T.Scene();camera=new T.PerspectiveCamera(36,1,.1,50);renderer:T.WebGLRenderer;orbit:OrbitControls;rig:CreatureRig|null=null;motion:MotionController|null=null;generation=0;disposed=false;frame=0;last=0;visible=true;settings=motionSettings(null);resizeObserver:ResizeObserver;visibilityObserver:IntersectionObserver;gesture:Gesture='idle';paused=false;tick:FrameRequestCallback=()=>{};stage:'pod'|'encounter'|'overlay'='pod';floorObjects:T.Object3D[]=[];previewSpaceDispose:(()=>void)|null=null;skinResolver?:InstalledSkinResolver;skinTextures=new Set<T.Texture>();maxFps:number|null=null;renders=0;\r\n powerSoles:{index:number;node:T.Object3D;local:T.Vector3}[]=[];powerAnchors:{index:number;x:number;y:number;visible:boolean}[]=[];powerProjectionWorld=new T.Vector3();powerProjectionNdc=new T.Vector3();\r\n phonePhysics=createCharacterPhysics({width:1,height:1,bodyWidth:1,bodyHeight:1,buffer:0,contain:true,tiltExit:true,ship:false});phoneMotionDispose:(()=>void)|null=null;phoneElapsed=0;phonePose='idle';phoneTransientHoldFrames=0;\r\n phoneFloorContact=0;phoneWallBlend=0;phoneWaveLookBlend=0;phoneWalkBlend=0;\r\n phoneShipEpoch=0;phoneShipLoadId:string|null=null;phoneShipUnavailableId:string|null=null;phoneShipBaseScale=1;phoneShipSelectedId:string|null=null;phoneShipTint='#ffffff';phoneShipBridge:{ownedShipIds():string[];getShipUrl(id:string):string;dispose?():void}|null=null;phoneShipRoot:T.Group|null=null;phoneShipModel:T.Object3D|null=null;phoneShipLoader=new GLTFLoader();phoneProjectionCorners=Array.from({length:8},()=>new T.Vector3());\r\n phoneCameraChange=()=>this.phoneScreenSize();\r\n phoneAccountChange=()=>{if(!this.interactive||!this.rig)return;this.resetPhonePhysics();this.disposePhoneShip();this.selectPhoneShip(this.rig.recipe);this.phoneScreenSize();};\r\n constructor(public mount:HTMLElement,public assetBase:string,public interactive=true,skinResolver?:InstalledSkinResolver){this.skinResolver=skinResolver;\r\n  this.renderer=new T.WebGLRenderer({antialias:true,alpha:true,preserveDrawingBuffer:true,powerPreference:'low-power'});\r\n  this.renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));this.renderer.outputColorSpace=T.SRGBColorSpace;this.renderer.toneMapping=T.ACESFilmicToneMapping;\r\n  const environment=new RoomEnvironment(),pmrem=new T.PMREMGenerator(this.renderer);this.scene.environment=pmrem.fromScene(environment,.04).texture;environment.dispose();pmrem.dispose();\r\n  this.renderer.domElement.setAttribute('aria-label','Your animated MYR5 creature');this.renderer.domElement.setAttribute('role','img');mount.append(this.renderer.domElement);\r\n  this.camera.position.set(0,2.65,8.9);this.orbit=new OrbitControls(this.camera,this.renderer.domElement);this.orbit.target.set(0,1.95,0);this.orbit.enableDamping=true;this.orbit.enablePan=false;this.orbit.enableZoom=false;this.orbit.minDistance=6;this.orbit.maxDistance=13;this.orbit.enabled=interactive;this.orbit.maxPolarAngle=Math.PI*.85;this.orbit.addEventListener('change',this.phoneCameraChange);\r\n  this.scene.add(new T.HemisphereLight(0xe5d5ff,0x23152e,interactive?1.65:2));\r\n  const key=new T.DirectionalLight(0xffeedc,interactive?2.8:3);key.position.set(-3,5,5);this.scene.add(key);\r\n  const rim=new T.DirectionalLight(0xb997ff,interactive?1.5:2);rim.position.set(3,4,-3);this.scene.add(rim);\r\n  if(interactive){\r\n   const space=createCoachPreviewSpace(T,{pixelRatio:this.renderer.getPixelRatio()});\r\n   this.scene.add(space.group);this.scene.background=space.background;this.scene.fog=space.fog;\r\n   this.scene.add(this.camera);\r\n   this.previewSpaceDispose=()=>{if(this.scene.background===space.background)this.scene.background=null;if(this.scene.fog===space.fog)this.scene.fog=null;space.dispose();};\r\n   this.camera.far=400;this.camera.updateProjectionMatrix();\r\n   // Fill the side hidden from the key and add a restrained cool edge. Neither casts shadows.\r\n   const fill=new T.DirectionalLight(0xffc78f,1.05);fill.position.set(4,2,4);this.scene.add(fill);\r\n   const edge=new T.DirectionalLight(0x9ac9ec,.75);edge.position.set(-4,3,-4);this.scene.add(edge);\r\n  }\r\n  const floor=new T.Mesh(new T.CylinderGeometry(1.45,1.55,.08,64),new T.MeshStandardMaterial({color:0x241e31,roughness:.5,metalness:.4}));floor.position.y=-.05;this.scene.add(floor);\r\n  const ring=new T.Mesh(new T.TorusGeometry(1.4,.014,6,64),new T.MeshBasicMaterial({color:0xd3b86d}));ring.rotation.x=Math.PI/2;ring.position.y=.005;this.scene.add(ring);\r\n  this.floorObjects=[floor,ring];\r\n  this.resizeObserver=new ResizeObserver(()=>this.resize());this.resizeObserver.observe(mount);this.resize();\r\n  this.visibilityObserver=new IntersectionObserver(entries=>{this.visible=entries[0].isIntersecting;});this.visibilityObserver.observe(mount);\r\n  if(interactive){this.startPhoneMotion();window.addEventListener('myr5:account-ready',this.phoneAccountChange);window.addEventListener('myr5:account-cleared',this.phoneAccountChange);}\r\n  // D43.5: coach-overlay can cap this below the native ~31fps (setMaxFps) while a counted set is\r\n  // tracking slowly, so this WebGL render competes less with MediaPipe on the main thread. Ongoing\r\n  // falls/climbs use the real frame gap; the brief flip and look-down beats advance per rendered frame\r\n  // so a busy renderer still shows both poses before continuing the fall.\r\n  const tick=(now:number)=>{if(this.disposed)return;this.frame=requestAnimationFrame(tick);const gate=this.maxFps?1000/this.maxFps:32,frameGap=Math.max(0,(now-this.last)/1000);if(now-this.last<gate)return;this.last=now;if(!this.visible||document.hidden)return;const motionDt=Math.min(this.maxFps?gate/1000:.05,frameGap);this.motion?.update(motionDt);this.updatePhonePhysics(Math.min(.5,frameGap));if(!this.interactive&&this.stage==='pod'&&!this.cinematicKind&&!this.paused&&!this.settings.reduced&&this.settings.amount>0&&this.homeMoving){this.homeElapsed+=motionDt;this.homeView();}this.orbit.update();this.renderer.render(this.scene,this.camera);this.refreshPowerAnchors();this.renders++;};this.tick=tick;this.frame=requestAnimationFrame(this.tick);\r\n }\r\n // Layout size, not getBoundingClientRect(): a portal destination arrives scaled from the wormhole's core (2N), and a\r\n // resize read mid-arrival would keep a thumbnail-sized canvas once it lands (the meditation room's borrowed coach).\r\n resize(){const width=this.mount.clientWidth,height=this.mount.clientHeight;if(width&&height){this.renderer.setSize(width,height,false);this.camera.aspect=width/height;this.camera.updateProjectionMatrix();if(!this.cinematicKind){if(this.stage==='overlay')this.fitBody();else if(this.focused&&this.interactive)this.focusRegion(this.focused);else this.homeView();}this.phoneScreenSize();}}\r\n private resetPhonePhysics(){if(!this.interactive)return;this.phonePhysics.reset();this.phoneElapsed=0;this.phonePose='idle';this.phoneTransientHoldFrames=0;this.phoneFloorContact=0;this.phoneWallBlend=0;this.phoneWaveLookBlend=0;this.phoneWalkBlend=0;this.renderer.domElement.dataset.phonePhase='idle';this.mount.dataset.phoneMotionPhase='idle';this.motion?.play(this.gesture);if(this.rig){this.rig.root.position.set(0,0,0);this.rig.root.quaternion.identity();this.rig.root.visible=true;}if(this.phoneShipRoot)this.phoneShipRoot.visible=false;this.renderer.domElement.dataset.phoneShipReady='false';}\r\n private cachePowerSoles(rig:CreatureRig){return(['FootLeft','FootRight'] as const).flatMap((name,side)=>{const node=rig.nodes[name],bounds=new T.Box3();node.updateMatrix();for(const child of node.children){if(!(child instanceof T.Mesh))continue;const geometry=child.geometry;if(!geometry.boundingBox)geometry.computeBoundingBox();if(geometry.boundingBox){child.updateMatrix();bounds.union(geometry.boundingBox.clone().applyMatrix4(child.matrix));}}if(bounds.isEmpty())return[];return[{index:side===0?27:28,node,local:new T.Vector3((bounds.min.x+bounds.max.x)/2,bounds.min.y,(bounds.min.z+bounds.max.z)/2)}];});}\r\n private refreshPowerAnchors(){this.powerAnchors=projectAvatarPowerAnchors(this.powerSoles,this.camera,!!this.rig?.root.visible,this.powerProjectionWorld,this.powerProjectionNdc);}\r\n private selectPhoneShip(recipe:Design){\r\n  const account=(globalThis as any).myr5AuthenticatedAccount,owner=typeof account==='string'?account:account?.user?.id;\r\n  let saved:{ship?:string;tint?:string}|null=null;\r\n  if(owner)try{saved=JSON.parse(localStorage.getItem(`myr5-ship-customization-v1/${owner}`)||'null');}catch{}\r\n  const available=ownedShipIds(),valid=(id:unknown):id is string=>typeof id==='string'&&SHIP_IDS.includes(id)&&(id==='supportive'||available.includes(id));\r\n  const id=valid(saved?.ship)?saved!.ship:valid(recipe.shipId)?recipe.shipId:valid(recipe.coach)?recipe.coach:null;\r\n  const tint=id&&saved?.ship===id&&/^#[0-9a-f]{6}$/i.test(saved.tint||'')?saved.tint!:id&&recipe.shipId===id&&/^#[0-9a-f]{6}$/i.test(recipe.shipColor||'')?recipe.shipColor!:'#ffffff';\r\n  this.phoneShipSelectedId=id;this.phoneShipTint=tint;\r\n  const width=this.mount.clientWidth||1,height=this.mount.clientHeight||1;\r\n  this.phonePhysics=createCharacterPhysics({width,height,bodyWidth:1,bodyHeight:1,buffer:0,contain:true,tiltExit:true,ship:false});\r\n  this.renderer.domElement.dataset.phoneShip=id||'';this.renderer.domElement.dataset.phoneShipReady='false';\r\n  return id;\r\n }\r\n private phonePhysicsAllowed(){return this.interactive&&this.stage==='pod'&&this.visible&&!document.hidden&&!this.paused&&!this.settings.reduced&&this.settings.amount>0;}\r\n private phoneScreenSize(){\r\n  if(!this.rig)return;\r\n  const width=this.mount.clientWidth,height=this.mount.clientHeight;if(!width||!height)return;\r\n  this.camera.updateMatrixWorld(true);\r\n  const min=this.bodyBounds.min,max=this.bodyBounds.max;let left=Infinity,right=-Infinity,top=Infinity,bottom=-Infinity;\r\n  for(let i=0;i<8;i++){const point=this.phoneProjectionCorners[i]!.set(i&1?max.x:min.x,i&2?max.y:min.y,i&4?max.z:min.z).project(this.camera);const x=(point.x*.5+.5)*width,y=(-point.y*.5+.5)*height;left=Math.min(left,x);right=Math.max(right,x);top=Math.min(top,y);bottom=Math.max(bottom,y);}\r\n  this.phonePhysics.resize(width,height,Math.max(1,right-left),Math.max(1,bottom-top));(this.phonePhysics as any).setRestCenter?.((left+right)/2,(top+bottom)/2);\r\n }\r\n private updatePhonePhysics(dt:number){\r\n  if(!this.interactive||!this.rig||!this.motion)return;\r\n  const active=this.phonePhysicsAllowed();\r\n  this.renderer.domElement.dataset.phonePhase=active?(this.phonePhysics.state.phase||'idle'):'idle';this.mount.dataset.phoneMotionPhase=this.renderer.domElement.dataset.phonePhase;\r\n  if(!active){\r\n   if(this.phonePose!=='idle'||this.phonePhysics.state.phase!=='idle'){this.resetPhonePhysics();}\r\n   this.rig.root.position.set(0,0,0);this.rig.root.quaternion.identity();return;\r\n  }\r\n  const transient=['air-run','look-down'].includes(this.phonePhysics.state.phase);\r\n  const phaseDt=transient?Math.min(.05,dt):dt;\r\n  const holdTransientFrame=transient&&this.phoneTransientHoldFrames>0;\r\n  if(holdTransientFrame)this.phoneTransientHoldFrames--;else this.phonePhysics.step(phaseDt);\r\n  this.phoneElapsed+=holdTransientFrame?0:phaseDt;\r\n  const state=this.phonePhysics.state;\r\n  this.renderer.domElement.dataset.phonePhase=state.phase;this.mount.dataset.phoneMotionPhase=state.phase;\r\n  const contactTarget=['slide','climb','wave','climb-out','recover'].includes(state.phase)?1:0;if(state.phase==='recover')this.phoneFloorContact=1;else this.phoneFloorContact+=(contactTarget-this.phoneFloorContact)*Math.min(1,Math.min(.05,dt)*5);\r\n  if(['climb','wave','climb-out','ship','gone'].includes(state.phase))void this.loadPhoneShip();\r\n  const pose=String(state.pose);\r\n  if(pose!==this.phonePose){\r\n   this.phonePose=pose;const gesture:Gesture=['wiggle','air-run','bounce'].includes(pose)?'wiggle':['walk','slide','recover','climb','ship'].includes(pose)?'walk':['greet','wave'].includes(pose)?'greet':'idle';this.motion.play(gesture);this.motion.update(.05);if(state.phase==='slide')this.motion.action.setEffectiveTimeScale(.55);\r\n  }\r\n  const viewDirection=this.camera.getWorldDirection(new T.Vector3()),right=new T.Vector3(1,0,0).applyQuaternion(this.camera.quaternion),up=new T.Vector3(0,1,0).applyQuaternion(this.camera.quaternion);\r\n  const pivot=this.bodyBounds.getCenter(new T.Vector3()),cameraPosition=this.camera.getWorldPosition(new T.Vector3()),depth=pivot.clone().sub(cameraPosition).dot(viewDirection),unitsPerPixel=2*depth*Math.tan(T.MathUtils.degToRad(this.camera.fov/2))/Math.max(1,this.mount.clientHeight);\r\n  let actorX=state.x,actorY=state.y;\r\n  if(state.phase==='ship'&&state.shipProgress<.36){const t=state.shipProgress/.36;actorX*=1-t;actorY*=1-t;}\r\n  const offset=right.clone().multiplyScalar(actorX*unitsPerPixel).addScaledVector(up,-actorY*unitsPerPixel),rotation=new T.Quaternion().setFromAxisAngle(viewDirection.negate(),state.angle);\r\n  const wallTarget=['climb','wave','climb-out'].includes(state.phase)?1:0,wallEase=1-Math.exp(-Math.min(.05,dt)*5);if(state.phase==='recover')this.phoneWallBlend=0;else this.phoneWallBlend+=(wallTarget-this.phoneWallBlend)*wallEase;\r\n  const waveTarget=state.phase==='wave'?1:0;this.phoneWaveLookBlend+=(waveTarget-this.phoneWaveLookBlend)*wallEase;\r\n  if(this.phoneWallBlend>.001){const platform=this.floorObjects[0]?.getWorldPosition(new T.Vector3())??new T.Vector3(0,-.05,0),towardWall=platform.sub(pivot).normalize(),wallFacing=new T.Quaternion().setFromUnitVectors(new T.Vector3(0,0,1),towardWall),wallRoll=wallFacing.clone().multiply(new T.Quaternion().setFromAxisAngle(new T.Vector3(0,0,1),state.angle));rotation.slerp(wallRoll,this.phoneWallBlend);}\r\n  const walkDistance=Math.abs(state.x),walkTarget=state.phase==='recover'?T.MathUtils.smoothstep(walkDistance,0,Math.max(32,this.bodyBounds.getSize(new T.Vector3()).x*.45)):0;this.phoneWalkBlend+=(walkTarget-this.phoneWalkBlend)*wallEase;\r\n  if(this.phoneWalkBlend>.001){const walkDirection=right.clone().multiplyScalar(state.x>0?-1:1);walkDirection.y=0;if(walkDirection.lengthSq()>.001){walkDirection.normalize();const walkFacing=new T.Quaternion().setFromAxisAngle(new T.Vector3(0,1,0),Math.atan2(walkDirection.x,walkDirection.z));rotation.slerp(walkFacing,this.phoneWalkBlend);}}\r\n  const pivotShift=pivot.clone().sub(pivot.clone().applyQuaternion(rotation));this.rig.root.position.copy(offset).add(pivotShift);this.rig.root.quaternion.copy(rotation);this.rig.root.updateMatrixWorld(true);\r\n  if(this.phoneFloorContact>.001){let lowest=Infinity;for(let i=0;i<8;i++){const point=this.phoneProjectionCorners[i]!.set(i&1?this.bodyBounds.max.x:this.bodyBounds.min.x,i&2?this.bodyBounds.max.y:this.bodyBounds.min.y,i&4?this.bodyBounds.max.z:this.bodyBounds.min.z).applyMatrix4(this.rig.root.matrixWorld);lowest=Math.min(lowest,point.y);}const floor=this.floorObjects[0] as T.Mesh|undefined,floorY=floor?floor.position.y+.04:-.01;this.rig.root.position.y+=(floorY-lowest)*this.phoneFloorContact;this.rig.root.updateMatrixWorld(true);}\r\n  this.rig.root.visible=state.phase!=='gone'&&!(state.phase==='ship'&&state.shipProgress>=.36);\r\n  this.updatePhoneShip(state.phase,state.shipProgress,state,pivot,right,up,unitsPerPixel);\r\n  if(pose==='climb'){\r\n   // Turn toward the floor-wall. Braced forelimbs and alternating pulls keep the quadruped climbing.\r\n   const phase=this.phoneElapsed*8,armL=this.rig.nodes.ArmLeft,armR=this.rig.nodes.ArmRight,footL=this.rig.nodes.FootLeft,footR=this.rig.nodes.FootRight;\r\n   this.rig.nodes.BodyMotion?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.2,0,.035*Math.sin(phase))));\r\n   if(this.rig.nodes.BodyMotion)this.rig.nodes.BodyMotion.position.y-=.055;\r\n   this.rig.nodes.HeadMotion?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.09,0,0)));\r\n   armL?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.52-.12*Math.sin(phase),0,-.18)));\r\n   armR?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.52+.12*Math.sin(phase),0,.18)));\r\n   footL?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.22,0,-.1)));\r\n   footR?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.22,0,.1)));\r\n  }else if(pose==='look-down'){\r\n   this.rig.nodes.HeadMotion?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.38,0,0)));\r\n   for(const node of Object.keys(this.rig.nodes).filter(name=>name.startsWith('EyeBlink')))this.rig.nodes[node]!.scale.y=.06;\r\n  }else if(pose==='fall'){\r\n   const roll=.14*Math.sin(this.phoneElapsed*5);this.rig.nodes.BodyMotion?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.12,0,roll)));\r\n   this.rig.nodes.ArmLeft?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.22,0,-.62)));\r\n   this.rig.nodes.ArmRight?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.22,0,.62)));\r\n   this.rig.nodes.FootLeft?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(.4,0,-.18)));\r\n   this.rig.nodes.FootRight?.quaternion.multiply(new T.Quaternion().setFromEuler(new T.Euler(-.28,0,.18)));\r\n  }\r\n  if(this.phoneWaveLookBlend>.001){const head=this.rig.nodes.HeadMotion;if(head?.parent){this.rig.root.updateMatrixWorld(true);const parentWorld=head.parent.getWorldQuaternion(new T.Quaternion()).invert(),towardCamera=this.camera.getWorldPosition(new T.Vector3()).sub(head.getWorldPosition(new T.Vector3())).normalize().applyQuaternion(parentWorld),lookAtCamera=new T.Quaternion().setFromUnitVectors(new T.Vector3(0,0,1),towardCamera);head.quaternion.slerp(lookAtCamera,this.phoneWaveLookBlend);}}\r\n }\r\n private startPhoneMotion(){if(!this.interactive||this.phoneMotionDispose)return;this.phoneMotionDispose=subscribePhoneMotion(sample=>{if(!this.phonePhysicsAllowed())return;const before=this.phonePhysics.state.phase;this.phonePhysics.sample(sample,sample.timeSeconds);const after=this.phonePhysics.state.phase;if(['air-run','look-down'].includes(after)&&!['air-run','look-down'].includes(before))this.phoneTransientHoldFrames=1;});}\r\n private disposePhoneShip(){++this.phoneShipEpoch;this.phoneShipLoadId=null;this.phoneShipUnavailableId=null;this.phonePhysics.setShipAvailable(false);if(this.phoneShipRoot){this.scene.remove(this.phoneShipRoot);this.disposeShipTree(this.phoneShipRoot);}this.phoneShipRoot=null;this.phoneShipModel=null;this.phoneShipBridge?.dispose?.();this.phoneShipBridge=null;this.renderer.domElement.dataset.phoneShipReady='false';}\r\n private disposeShipTree(root:T.Object3D){const geometries=new Set<T.BufferGeometry>(),materials=new Set<T.Material>(),textures=new Set<T.Texture>();root.traverse(node=>{const mesh=node as T.Mesh;if(mesh.geometry)geometries.add(mesh.geometry);for(const material of(Array.isArray(mesh.material)?mesh.material:[mesh.material]))if(material){materials.add(material);for(const value of Object.values(material))if((value as T.Texture)?.isTexture)textures.add(value as T.Texture);}});textures.forEach(texture=>texture.dispose());materials.forEach(material=>material.dispose());geometries.forEach(geometry=>geometry.dispose());}\r\n private async loadPhoneShip(){\r\n  const ship=this.phoneShipSelectedId;if(!ship||this.phoneShipLoadId===ship||this.phoneShipUnavailableId===ship||this.phoneShipModel)return;\r\n  if(ship!=='supportive'&&!ownedShipIds().includes(ship))return;\r\n  const epoch=++this.phoneShipEpoch;this.phoneShipLoadId=ship;\r\n  let bridge:{ownedShipIds():string[];getShipUrl(id:string):string;dispose?():void}|null=null;\r\n  try{\r\n   bridge=ship==='supportive'?null:await localVerifiedBridge();\r\n   if(this.disposed||epoch!==this.phoneShipEpoch){bridge?.dispose?.();return;}\r\n   if(ship!=='supportive'&&(!bridge||!bridge.ownedShipIds().includes(ship))){bridge?.dispose?.();this.phoneShipLoadId=null;this.phoneShipUnavailableId=ship;return;}\r\n   const url=bridge?bridge.getShipUrl(ship):new URL('/pod/worlds/starter/supportive.glb',location.href).href;\r\n   const gltf=await this.phoneShipLoader.loadAsync(url);\r\n   if(this.disposed||epoch!==this.phoneShipEpoch){this.disposeShipTree(gltf.scene);bridge?.dispose?.();return;}\r\n   if(ship!=='supportive'&&!ownedShipIds().includes(ship)){this.disposeShipTree(gltf.scene);bridge?.dispose?.();this.phoneShipLoadId=null;this.phoneShipUnavailableId=ship;this.phonePhysics.setShipAvailable(false);return;}\r\n   const box=new T.Box3().setFromObject(gltf.scene),size=box.getSize(new T.Vector3()),max=Math.max(size.x,size.y,size.z)||1;\r\n   gltf.scene.position.sub(box.getCenter(new T.Vector3()));\r\n   const root=new T.Group();root.name='verified-phone-coach-ship';root.add(gltf.scene);root.rotation.y=SHIP_FACING;\r\n   const body=this.bodyBounds.getSize(new T.Vector3());this.phoneShipBaseScale=Math.max(.7,body.y*1.5)/max;root.scale.setScalar(this.phoneShipBaseScale);\r\n   if(this.phoneShipTint!=='#ffffff')applyShipTint(root,this.phoneShipTint);\r\n   this.phoneShipBridge=bridge;this.phoneShipModel=gltf.scene;this.phoneShipRoot=root;this.scene.add(root);this.phonePhysics.setShipAvailable(true);\r\n  }catch{if(epoch!==this.phoneShipEpoch){bridge?.dispose?.();return;}this.phoneShipLoadId=null;this.phoneShipUnavailableId=ship;bridge?.dispose?.();this.phoneShipBridge?.dispose?.();this.phoneShipBridge=null;}\r\n }\r\n private updatePhoneShip(phase:string,progress:number,state:{x:number;y:number;angle:number},pivot:T.Vector3,right:T.Vector3,up:T.Vector3,unitsPerPixel:number){\r\n  const selected=this.phoneShipSelectedId;if(selected&&selected!=='supportive'&&!ownedShipIds().includes(selected)){if(this.phoneShipRoot)this.disposePhoneShip();return;}\r\n  const root=this.phoneShipRoot,id=selected;this.renderer.domElement.dataset.phoneShip=id||'';const visible=phase==='ship';this.renderer.domElement.dataset.phoneShipReady=String(!!root&&visible);if(!root)return;root.visible=visible;if(!visible)return;\r\n  const start=this.bodyBounds.getCenter(new T.Vector3()).applyMatrix4(this.rig!.root.matrixWorld),finish=pivot.clone();\r\n  const p=T.MathUtils.clamp(Number.isFinite(progress)?progress:0,0,1),approach=T.MathUtils.clamp(p/.36,0,1),outbound=T.MathUtils.clamp((p-.36)/.64,0,1);\r\n  const gravityX=Math.sin(state.angle),gravityY=Math.cos(state.angle),width=this.mount.clientWidth,height=this.mount.clientHeight;\r\n  const departure=finish.clone().addScaledVector(right,-gravityX*(width*.65)*unitsPerPixel).addScaledVector(up,gravityY*(height*.65)*unitsPerPixel);\r\n  if(p<.36)root.position.copy(start).lerp(finish,approach);else root.position.copy(finish).lerp(departure,outbound);\r\n  const scale=Math.max(.12,1-outbound*.78);root.scale.setScalar(this.phoneShipBaseScale*scale);\r\n  root.rotation.y=SHIP_FACING+Math.sin(outbound*Math.PI)*.28;\r\n }\r\n async setRecipe(raw:unknown,preview=false){\r\n  this.powerSoles=[];this.powerAnchors=[];\r\n  this.resetPhonePhysics();\r\n  this.disposePhoneShip();\r\n  const recipe=importCreature(JSON.stringify(raw)),generation=++this.generation;\r\n  const assembly=await assembleCreature(recipe,this.assetBase,this.skinResolver,preview);let rig:CreatureRig|undefined;\r\n  try{if(this.disposed||generation!==this.generation){assembly.skinTextures.forEach(texture=>texture.dispose());return false;}this.regionBoxes=new Map(REGIONS.map(region=>[region,regionBounds(assembly.root,region)]));if(this.regionBoxes.get('eye')!.isEmpty())this.regionBoxes.set('eye',this.regionBoxes.get('head')!.clone());this.bodyBounds.makeEmpty();for(const box of this.regionBoxes.values())this.bodyBounds.union(box);rig=createRig(assembly.root,recipe);}catch(error){assembly.skinTextures.forEach(texture=>texture.dispose());throw error;}finally{assembly.dispose();}\r\n  if(this.disposed||generation!==this.generation){assembly.skinTextures.forEach(texture=>texture.dispose());return false;}\r\n  if(this.rig){this.motion?.dispose();this.scene.remove(this.rig.root);disposeObject(this.rig.root);}\r\n  this.skinTextures.forEach(texture=>texture.dispose());this.skinTextures=assembly.skinTextures;\r\n  this.rig=rig!;this.powerSoles=this.cachePowerSoles(rig!);this.powerAnchors=[];this.motion=new MotionController(rig!);Object.assign(this.motion,this.settings,{paused:this.paused});this.scene.add(rig!.root);this.motion.play(this.gesture);this.selectPhoneShip(recipe);this.phoneScreenSize();if(!this.cinematicKind){if(this.stage==='overlay')this.fitBody();else if(this.interactive&&this.focused)this.focusRegion(this.focused);else this.homeView();}return true;\r\n }\r\n setSkinResolver(resolver?:InstalledSkinResolver){this.skinResolver=resolver;}\r\n clearSkinState(){this.generation++;this.powerSoles=[];this.powerAnchors=[];this.resetPhonePhysics();if(this.rig){this.motion?.dispose();this.scene.remove(this.rig.root);disposeObject(this.rig.root);this.rig=null;this.motion=null;}this.skinTextures.forEach(texture=>texture.dispose());this.skinTextures.clear();this.regionBoxes.clear();this.bodyBounds.makeEmpty();}\r\n play(id:Gesture){this.gesture=id;this.motion?.play(id);}\r\n // Workout overlay: turn to face where the coach walks (0 = the camera, π/2 = screen right).\r\n face(yaw:number){if(this.rig)this.rig.root.rotation.y=yaw;}\r\n setSettings(settings:ReturnType<typeof motionSettings>){this.settings=settings;if(this.motion)Object.assign(this.motion,settings);if(settings.reduced||settings.amount===0){this.resetPhonePhysics();this.homeElapsed=0;if(!this.cinematicKind)this.homeView();}}\r\n setPaused(paused:boolean){this.paused=paused;if(this.motion)this.motion.paused=paused;if(paused)this.resetPhonePhysics();}\r\n // D43.5: null/0 restores the native ~31fps gate (see tick()).\r\n setMaxFps(fps:number|null){this.maxFps=fps&&fps>0?fps:null;}\r\n // W2-2Q: asleep, no frame is scheduled at all (the ship view puts the parked app capsule to sleep once it closes).\r\n setAwake(awake:boolean){if(this.disposed||awake===!!this.frame)return;if(awake)this.frame=requestAnimationFrame(this.tick);else{cancelAnimationFrame(this.frame);this.frame=0;}}\r\n resetStageView(){if(this.stage==='overlay'){this.fitBody();return;}const giant=this.stage==='encounter';this.orbit.minDistance=giant?4:6;this.orbit.maxDistance=14;this.camera.fov=giant?32:36;this.camera.position.set(0,giant?2.1:2.65,giant?5.8:8.9);this.orbit.target.set(0,giant?2.25:1.95,0);this.camera.updateProjectionMatrix();this.orbit.update();this.homeView();}\r\n // Workout overlay: the whole body fills the canvas with the feet on its bottom edge (the user's knee line).\r\n fitBody(){const box=this.bodyBounds;if(box.isEmpty())return;const size=box.getSize(new T.Vector3()),center=box.getCenter(new T.Vector3()),half=T.MathUtils.degToRad(this.camera.fov/2),distance=Math.max(size.y/2/Math.tan(half),size.x/2/(Math.tan(half)*this.camera.aspect))+size.z/2;this.orbit.minDistance=.1;this.orbit.maxDistance=distance*2;this.orbit.target.copy(center);this.camera.position.set(center.x,center.y,center.z+distance);this.orbit.update();}\r\n setStage(stage:'pod'|'encounter'|'overlay'){if(stage!=='pod')this.resetPhonePhysics();this.stage=stage;this.focused=null;this.homeElapsed=0;this.floorObjects.forEach(o=>o.visible=stage==='pod');if(!this.cinematicKind)this.resetStageView();this.resize();if(stage==='overlay')this.warm();}\r\n // The workout coach waits offstage (display:none, so tick() skips it) until the first rep counts. Its first real frame\r\n // compiled every shader and uploaded every texture and buffer right then, a 1.3-3.4 s main-thread stall in the middle\r\n // of the set that cost the next rep (tests/camera-counting). Draw one hidden frame as soon as it is staged and loaded\r\n // (phone.ts re-stages it after every load), while the set is still starting, so the walk-in only draws.\r\n warm(){if(!this.rig||this.disposed)return;this.renderer.compile(this.scene,this.camera);this.renderer.render(this.scene,this.camera);}\r\n resetView(side=1){this.side=side;return this.focusRegion('body');}\r\n async exportGLB(){\r\n  if(!this.rig||!this.motion)throw Error('Wait for your creature to load.');\r\n  // Export a clean neutral clone and the same reusable clips used in the app.\r\n  const clone=cloneSkinned(this.rig.root);if(this.interactive){clone.position.set(0,0,0);clone.quaternion.identity();}for(const [name,rest] of Object.entries(this.rig.rest)){const node=clone.getObjectByName(name)!;node.position.copy(rest.position);node.quaternion.copy(rest.quaternion);node.scale.copy(rest.scale);}clone.updateMatrixWorld(true);\r\n  const result=await new GLTFExporter().parseAsync(clone,{binary:true,animations:this.motion.clips});return new Blob([result as ArrayBuffer],{type:'model/gltf-binary'});\r\n }\r\n // renders is a cumulative count of actual renderer.render() calls (D43.5's setMaxFps skips both the render\r\n // and this increment) — tests diff two readings over a real wall-clock window to get an actual renders/s.\r\n stats(){return {awake:!!this.frame,gesture:this.motion?.current,phonePhase:this.phonePhysics.state.phase,phoneMotionPhase:this.phonePhysics.state.phase,phoneShip:this.renderer.domElement.dataset.phoneShip,phoneShipReady:this.renderer.domElement.dataset.phoneShipReady==='true',drawCalls:this.renderer.info.render.calls,triangles:this.renderer.info.render.triangles,visible:this.visible,paused:this.paused,renders:this.renders,maxFps:this.maxFps,programs:this.renderer.info.programs?.length??0,contextLost:this.renderer.getContext().isContextLost(),canvas:{width:this.renderer.domElement.width,height:this.renderer.domElement.height},powerAnchors:this.powerAnchors,rigVersion:1,recipe:this.rig?.recipe};}\r\n dispose(){if(this.disposed)return;this.disposed=true;this.generation++;this.powerSoles=[];this.powerAnchors=[];this.phoneMotionDispose?.();this.phoneMotionDispose=null;window.removeEventListener('myr5:account-ready',this.phoneAccountChange);window.removeEventListener('myr5:account-cleared',this.phoneAccountChange);this.disposePhoneShip();cancelAnimationFrame(this.frame);this.resizeObserver.disconnect();this.visibilityObserver.disconnect();this.orbit.removeEventListener('change',this.phoneCameraChange);this.orbit.dispose();this.motion?.dispose();this.skinTextures.forEach(texture=>texture.dispose());this.skinTextures.clear();this.previewSpaceDispose?.();this.previewSpaceDispose=null;disposeObject(this.scene);if(this.scene.background instanceof T.Texture)this.scene.background.dispose();this.scene.environment?.dispose();this.renderer.dispose();this.renderer.domElement.remove();delete this.mount.dataset.phoneMotionPhase;}\r\n}\r\n","creature/source/war-room-coaches.ts":"import {COACHES,pathIntroCoachIds} from '../../performance-catalog.mjs';\r\nimport {goldenCoach,performanceOwner,readPerformanceProgress} from '../../performance-progress.mjs';\r\nimport {parseRecipe,fresh} from './creator/design';\r\nimport {bodyLockSection} from './creator/track-placements';\r\nimport {resolveRegionMaterial,regionChoice} from './creator/materials-registry';\r\n\r\nconst KEY='myr5-war-room-coaches-v2';\r\nconst selectionKey=()=>`${KEY}/${encodeURIComponent(performanceOwner())}`;\r\ntype Sprite={id:string;family:string;kind:'body'|'pet';sheet:string;frame:number[]};\r\ntype Selection={body:string|null;pet:string|null;goldenBody:boolean};\r\nexport async function loadCoachSpritePreviews(doc:Document){\r\n const response=await fetch('/pod/gala-coaches/manifest.json');if(!response.ok)throw Error('Coach sprites are unavailable.');\r\n const manifest=await response.json(),sprites:Sprite[]=manifest.sprites.filter((sprite:Sprite)=>COACHES.some((coach:any)=>coach.id===sprite.id));\r\n const sheets=new Map<string,{image:HTMLImageElement;mask:HTMLImageElement}>();\r\n const image=async(name:string)=>{const img=new Image();img.src='/pod/gala-coaches/'+name;await img.decode();return img;};\r\n await Promise.all(Object.entries(manifest.sheets).map(async([id,s]:[string,any])=>{const [art,mask]=await Promise.all([image(s.image),image(s.mask)]);sheets.set(id,{image:art,mask});}));\r\n const recipe=()=>{try{return parseRecipe(localStorage.getItem('myr5-recipe-v1')||'null');}catch{return fresh();}};\r\n const cache=new Map<string,HTMLCanvasElement>();\r\n function art(sprite:Sprite,silhouette=false,look?:any,golden=false){\r\n  const r=recipe(),skin=look&&(globalThis as any).GalaAvatar?.skinColor?.(look),colours=golden&&goldenCoach(sprite.id)?['#e8bc4d','#ffe4a1','#6b4214']:skin?[skin,skin,'#fff9df']:['body','head','eye'].map(region=>resolveRegionMaterial(r.styles[region],regionChoice(r.materials,region),true,sprite.id).primary);\r\n  const key=JSON.stringify([sprite.id,silhouette,colours]);if(cache.has(key))return cache.get(key)!;\r\n  const [x,y,w,h]=sprite.frame,canvas=doc.createElement('canvas');canvas.width=w;canvas.height=h;\r\n  const ctx=canvas.getContext('2d',{willReadFrequently:true})!,mask=doc.createElement('canvas');mask.width=w;mask.height=h;\r\n  const sheet=sheets.get(sprite.sheet)!;ctx.drawImage(sheet.image,x,y,w,h,0,0,w,h);const pixels=ctx.getImageData(0,0,w,h);\r\n  const mc=mask.getContext('2d',{willReadFrequently:true})!;mc.drawImage(sheet.mask,x,y,w,h,0,0,w,h);const regions=mc.getImageData(0,0,w,h).data;\r\n  const rgb=(hex:string)=>{const n=parseInt(hex.slice(1),16);return [n>>16,n>>8&255,n&255];};\r\n  for(let i=0;i<pixels.data.length;i+=4){if(!pixels.data[i+3])continue;const region=regions[i],tone=region===0?[33,23,46]:rgb(colours[Math.min(2,Math.round(region/64)-1)]);\r\n   const shade=pixels.data[i]/184;for(let c=0;c<3;c++)pixels.data[i+c]=silhouette?35:region===0?tone[c]:Math.min(255,Math.round(tone[c]*shade));}\r\n  ctx.putImageData(pixels,0,0);cache.set(key,canvas);return canvas;\r\n }\r\n return {sprites,art};\r\n}\r\nexport async function loadWarRoomCoaches(doc:Document){\r\n const {sprites,art}=await loadCoachSpritePreviews(doc);\r\n const lock=(id:string)=>bodyLockSection(id,{});\r\n let selection:Selection={body:null,pet:null,goldenBody:false},selectionOwner='';\r\n // Keyed by owner and stored value: the pod reuses this across War Room visits (another page writes the choice).\r\n function readSelection(){const owner=selectionKey();let raw:string|null=null;try{raw=localStorage.getItem(owner);}catch{}if(owner+' '+raw===selectionOwner)return;selectionOwner=owner+' '+raw;selection={body:null,pet:null,goldenBody:false};\r\n  try{const saved=JSON.parse(raw||'null');for(const kind of ['body','pet'] as const)if(sprites.some(s=>s.id===saved?.[kind]&&(kind==='body'||s.kind===kind))&&!lock(saved[kind]))selection[kind]=saved[kind];selection.goldenBody=saved?.goldenBody===true&&!!selection.body&&goldenCoach(selection.body);}catch{}\r\n }\r\n readSelection();\r\n function picker(kind:'body'|'pet',changed:()=>void){\r\n  readSelection();\r\n  const group=doc.createElement('fieldset'),legend=doc.createElement('legend');legend.textContent=kind==='body'?'Coach body':'Coach pets';group.append(legend);group.className='gala-coach-choices';\r\n  const note=doc.createElement('p');note.className='help';note.textContent=kind==='body'?'Choose a coach character, then change its colour in the mirror. Choose Gala body to show your Gala wardrobe.':'Coach pets unlock with their coach bodies.';group.append(note);\r\n  const choose=(id:string|null,golden=false)=>{if(id&&lock(id))return;const next={...selection,[kind]:id,...(kind==='body'?{goldenBody:golden}: {})};try{localStorage.setItem(selectionKey(),JSON.stringify(next));selection=next;changed();}catch{group.setAttribute('aria-label','This choice could not be saved. Storage is unavailable.');}};\r\n  const standard=doc.createElement('button');standard.type='button';standard.textContent=kind==='body'?'Gala body':'Gala pet';standard.setAttribute('aria-pressed',String(!selection[kind]));standard.onclick=()=>choose(null);group.append(standard);\r\n  const introductory=new Set(pathIntroCoachIds(readPerformanceProgress().paths));\r\n  const ordered=[...sprites.filter(s=>kind==='body'||s.kind===kind)].sort((a,b)=>Number(!!lock(a.id))-Number(!!lock(b.id))||Number(introductory.has(b.id))-Number(introductory.has(a.id)));\r\n  for(const sprite of ordered){\r\n   const locked=lock(sprite.id),button=doc.createElement('button'),name=COACHES.find(c=>c.id===sprite.id)?.label||sprite.family;\r\n   button.type='button';button.dataset.coachSprite=sprite.id;button.setAttribute('aria-label',name);button.setAttribute('aria-pressed',String(selection[kind]===sprite.id&&(kind!=='body'||!selection.goldenBody)));\r\n   const source=art(sprite),preview=doc.createElement('canvas');preview.width=source.width;preview.height=source.height;preview.getContext('2d')!.drawImage(source,0,0);\r\n   const label=doc.createElement('span');label.textContent=name;button.append(preview,label);button.onclick=()=>{if(locked){note.textContent=`Preview only · How to unlock ${name}: ${locked}.`;return;}choose(sprite.id);};group.append(button);\r\n   if(kind==='body'&&goldenCoach(sprite.id)&&!locked){const gold=doc.createElement('button');gold.type='button';gold.dataset.coachSprite=sprite.id;gold.dataset.goldenCoach='true';gold.setAttribute('aria-label','Golden '+name);gold.setAttribute('aria-pressed',String(selection.body===sprite.id&&selection.goldenBody));const artPreview=art(sprite,false,undefined,true),goldCanvas=doc.createElement('canvas');goldCanvas.width=artPreview.width;goldCanvas.height=artPreview.height;goldCanvas.getContext('2d')!.drawImage(artPreview,0,0);const text=doc.createElement('span');text.textContent='Golden '+name;gold.append(goldCanvas,text);gold.onclick=()=>choose(sprite.id,true);group.append(gold);}\r\n  }return group;\r\n }\r\n function draw(avatarDraw:any,canvas:HTMLCanvasElement,look:any,options:any={}){\r\n  readSelection();\r\n  const id=options.petOnly?selection.pet:selection.body,sprite=sprites.find(s=>s.id===id);\r\n  if(!sprite||lock(sprite.id)){avatarDraw(canvas,look,options);return;}\r\n  canvas.width=64;canvas.height=96;const ctx=canvas.getContext('2d')!;ctx.imageSmoothingEnabled=false;\r\n  if(options.petOnly)ctx.drawImage(art(sprite,false,look,!options.petOnly&&selection.goldenBody),0,0,48,36,0,60,48,36);else if(sprite.kind==='pet')ctx.drawImage(art(sprite,false,look,!options.petOnly&&selection.goldenBody),0,0,48,36,0,48,64,48);else ctx.drawImage(art(sprite,false,look,!options.petOnly&&selection.goldenBody),0,0);\r\n }\r\n return {picker,draw,get hasBody(){readSelection();return !!selection.body&&!lock(selection.body);},get hasPet(){readSelection();return !!selection.pet&&!lock(selection.pet);}};\r\n}\r\n","creature/source/war-room-gala.ts":"// The War Room's 3D character bay: the player's own 64-bit Gala character (the saved mominc-avatar-v1 look,\r\n// drawn by the shared Gala renderer and performer) stands on the cage room's pedestal. Coach sprites share\r\n// the saved coach's colours and body ownership; no coach models or customizer are loaded. The room's bays open the Gala menus: the weapon\r\n// rack picks the weapon, the animal cages the pet, the mirror the alien features, the centre station the clothes.\r\n// Choices save to this device like every other Gala look change; tiers stay behind the training that earned them.\r\nimport * as T from 'three';\r\nimport {OrbitControls} from 'three/examples/jsm/controls/OrbitControls.js';\r\nimport {RoomEnvironment} from 'three/examples/jsm/environments/RoomEnvironment.js';\r\nimport {mountCage,cagePacketReady,cageStyle,SECTIONS,type CageSection,type CageViewer} from './cage';\r\nimport {GALA_KEY,loadGala} from '../../pod/identity.mjs';\r\nimport {PERFORMANCE_KEY} from '../../performance-progress.mjs';\r\nimport {loadWarRoomCoaches} from './war-room-coaches';\r\nimport {createGalaEditor} from '../../war-room/gala-editor.js';\r\n// The war-room page never loads the vault store (it needs the app bundle): queue for the app to drain (the store's drainPending).\r\nconst vaultQueue=(counter:string,key?:string)=>{try{const k='myr5-vault-pending',q=JSON.parse(localStorage.getItem(k)||'[]');q.push([counter,1,key]);localStorage.setItem(k,JSON.stringify(q.slice(-50)));}catch{}};\r\n\r\ntype Look={schema:string;version:number;name:string;dye:number;parts:Record<string,number>;weapon?:{type:string;tier:number}};\r\ntype Section={id:string;label:string;note:string;names:string[];choices:number[]};\r\ntype Bay=Exclude<CageSection,'overview'>;\r\nconst G=globalThis as any;\r\nexport const MIRROR=['body','skin','face','hair','facial'];\r\nexport const CLOTHES=['headwear','neck','torso','shoulders','arms','hands','legs','feet','held','back'];\r\nexport const IDLE_WALK_MS=10000;\r\nexport const LABELS:Record<CageSection,{label:string;name:string}>={ pets:{label:'Pets',name:'Animal cages: pet'}, weapons:{label:'Weapons',name:'Weapon rack: weapon'}, mirror:{label:'Mirror',name:'Mirror: alien features'}, clothing:{label:'Clothes',name:'Centre station: clothes'}, overview:{label:'Room',name:'Whole War Room'}, pedestal:{label:'Gala',name:'Your Gala character: face'}};\r\n// Which performer scene plays: idle loops, a face tap zooms in once, and ten idle seconds send the character walking off and back.\r\nexport function sceneClock(mode:{name:'idle'|'face'|'walk';since:number},now:number,idleSince:number,scenes:{name:string;duration:number}[]){\r\n const start=(name:string)=>{let t=0;for(const s of scenes){if(s.name===name)return {t,duration:s.duration};t+=s.duration;}return null;};\r\n const idle=scenes[0].duration;\r\n if(mode.name!=='idle'){const s=start(mode.name)!,elapsed=now-mode.since;if(elapsed<s.duration)return {mode,time:s.t+elapsed};if(mode.name==='walk')idleSince=now;mode={name:'idle',since:now};}\r\n if(now-idleSince>=IDLE_WALK_MS){mode={name:'walk',since:now};return {mode,time:start('walk')!.t,idleSince:now};}\r\n return {mode,time:(now-mode.since)%idle,idleSince};\r\n}\r\n\r\nclass GalaStage implements CageViewer{\r\n scene=new T.Scene();camera=new T.PerspectiveCamera(36,1,.1,80);renderer:T.WebGLRenderer;orbit:OrbitControls;bodyBounds=new T.Box3();floorObjects:T.Object3D[]=[];focused=null;\r\n settings={amount:1,ambient:true,reduced:false};\r\n constructor(public mount:HTMLElement){\r\n  this.renderer=new T.WebGLRenderer({antialias:true,alpha:true,powerPreference:'low-power'});\r\n  this.renderer.setPixelRatio(Math.min(devicePixelRatio,1.5));this.renderer.outputColorSpace=T.SRGBColorSpace;this.renderer.toneMapping=T.ACESFilmicToneMapping;\r\n  const environment=new RoomEnvironment(),pmrem=new T.PMREMGenerator(this.renderer);this.scene.environment=pmrem.fromScene(environment,.04).texture;environment.dispose();pmrem.dispose();\r\n  this.renderer.domElement.setAttribute('role','img');mount.append(this.renderer.domElement);\r\n  this.camera.position.set(0,2.65,8.9);this.orbit=new OrbitControls(this.camera,this.renderer.domElement);this.orbit.target.set(0,1.95,0);this.orbit.enableDamping=true;this.orbit.enablePan=false;this.orbit.enableZoom=false;this.orbit.maxPolarAngle=Math.PI*.85;\r\n  this.scene.add(new T.HemisphereLight(0xe5d5ff,0x23152e,2));const key=new T.DirectionalLight(0xffeedc,3);key.position.set(-3,5,5);this.scene.add(key);\r\n  const floor=new T.Mesh(new T.CylinderGeometry(1.45,1.55,.08,64),new T.MeshStandardMaterial({color:0x241e31,roughness:.5,metalness:.4}));floor.position.y=-.05;this.scene.add(floor);this.floorObjects=[floor];\r\n }\r\n resize(){const width=this.mount.clientWidth,height=this.mount.clientHeight;if(width&&height){this.renderer.setSize(width,height,false);this.camera.aspect=width/height;this.camera.updateProjectionMatrix();}}\r\n}\r\n\r\nexport function mountGalaBay(host:HTMLElement,{tell}:{tell:(text:string)=>void}){\r\n const A=G.GalaAvatar,W=G.GalaWeapons,P=G.GalaPerformance;\r\n if(!A||!W||!P)throw Error('The Gala character renderer is missing.');\r\n cageStyle();\r\n const doc=host.ownerDocument,el=<K extends keyof HTMLElementTagNameMap>(tag:K,text='',cls='')=>{const e=doc.createElement(tag);if(text)e.textContent=text;if(cls)e.className=cls;return e;};\r\n const stageEl=el('div','','gala-bay-stage'),panel=el('section','','gala-bay-panel'),heading=el('h3'),body=el('div');\r\n panel.hidden=true;panel.append(heading,body);host.append(stageEl,panel);\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n const stage=new GalaStage(stageEl);stage.settings.reduced=reduced.matches;\r\n // The character: the performer's 160×168 canvas on a billboard, feet on the pedestal top (y 0).\r\n const canvas=doc.createElement('canvas'),texture=new T.CanvasTexture(canvas);canvas.width=160;canvas.height=168;\r\n texture.magFilter=texture.minFilter=T.NearestFilter;texture.generateMipmaps=false;texture.colorSpace=T.SRGBColorSpace;\r\n const H=4.2,Wd=H*160/168,sprite=new T.Mesh(new T.PlaneGeometry(Wd,H),new T.MeshBasicMaterial({map:texture,transparent:true,alphaTest:.1,side:T.DoubleSide}));\r\n sprite.position.y=H/2-H*11/168;sprite.name='gala-character';stage.scene.add(sprite);\r\n stage.bodyBounds.set(new T.Vector3(-Wd*.3,0,-.3),new T.Vector3(Wd*.3,H*144/168,.3));\r\n let saved:Look,look:Look,performer:any,mode:{name:'idle'|'face'|'walk';since:number}={name:'idle',since:performance.now()},idleSince=performance.now(),frame=0,last=0,disposed=false,open:Bay|null=null;\r\n let coaches:Awaited<ReturnType<typeof loadWarRoomCoaches>>|null=null;\r\n void loadWarRoomCoaches(doc).then(value=>{if(!disposed){coaches=value;load();}}).catch(()=>{if(!disposed)tell('Coach sprites could not load. Reopen the War Room to retry.');});\r\n function load(){\r\n  let storage:Storage|undefined;try{storage=localStorage;}catch{}\r\n  saved=loadGala(storage,A).look;look=structuredClone(saved);\r\n  const chosen=look.weapon||{type:'rapier',tier:0};look.weapon=W.unlocked(chosen)?chosen:{type:chosen.type,tier:0};\r\n  performer=P.create(look,coaches?{draw:(canvas:any,value:any,options:any)=>coaches!.draw(A.draw,canvas,value,options),hasPet:coaches.hasPet}:{});stage.renderer.domElement.setAttribute('aria-label',`${look.name||'Your Gala character'} with ${W.name(look.weapon)} in the War Room`);\r\n  stage.mount.querySelectorAll<HTMLElement>('[data-cage-section=clothing]').forEach(control=>{control.hidden=!!coaches?.hasBody;});\r\n  if(open)showBay(open);\r\n }\r\n const touch=()=>{idleSince=performance.now();if(mode.name==='walk')mode={name:'idle',since:idleSince};};\r\n function save(next:Look,message:string){\r\n  try{localStorage.setItem(GALA_KEY,JSON.stringify(A.normalize(next)));dispatchEvent(new Event('mominc-avatar-change'));tell(message+' Saved on this device.');}\r\n  catch{tell('This choice could not be saved. Storage is unavailable on this device.');}\r\n }\r\n function picker(section:Section){\r\n  const label=el('label',section.label),select=el('select'),current=saved.parts[section.id];\r\n  const values=section.choices.includes(current)?section.choices:[current,...section.choices];\r\n  for(const value of values){const option=el('option',section.names[value]);option.value=String(value);select.append(option);}\r\n  select.value=String(current);select.dataset.galaPart=section.id;\r\n  select.onchange=()=>{touch();save({...saved,parts:{...saved.parts,[section.id]:Number(select.value)}},`${section.label}: ${section.names[Number(select.value)]}.`);};\r\n  label.append(select);return label;\r\n }\r\n const sections=(ids:string[])=>ids.map(id=>(A.sections as Section[]).find(s=>s.id===id)!).filter(Boolean).map(picker);\r\n function weaponForm(){\r\n  const form=el('div','','gala-weapon'),type=el('select'),tier=el('select'),selected=saved.weapon||{type:'rapier',tier:0};\r\n  type.setAttribute('aria-label','Gala weapon');tier.setAttribute('aria-label','Weapon upgrade');type.dataset.galaWeapon='type';tier.dataset.galaWeapon='tier';\r\n  for(const item of W.types){const option=el('option',item.name);option.value=item.id;type.append(option);}\r\n  type.value=selected.type;\r\n  for(let i=0;i<W.tiers.length;i++){const item={type:selected.type,tier:i},option=el('option');option.value=String(i);option.disabled=!W.unlocked(item);option.textContent=W.tiers[i];tier.append(option);}\r\n  tier.value=String(selected.tier);\r\n  // The weapon already saved is kept as it is (an earned tier survives a guest or offline visit); anything else must be earned.\r\n  const equip=(next:{type:string;tier:number})=>{touch();const kept=next.type===selected.type&&next.tier===selected.tier;if(!kept&&!W.unlocked(next))next={type:next.type,tier:0};save({...saved,weapon:next},W.name(next)+'.');};\r\n  type.onchange=()=>equip({type:type.value,tier:type.value===selected.type?selected.tier:0});tier.onchange=()=>equip({type:type.value,tier:Number(tier.value)});\r\n  const typeLabel=el('label','Weapon'),tierLabel=el('label','Upgrade');typeLabel.append(type);tierLabel.append(tier);\r\n  form.append(typeLabel,tierLabel,el('p','Workout performance earns weapon upgrades.','help'));\r\n  return form;\r\n }\r\n function showBay(section:Bay){\r\n  touch();\r\n  if(section==='pedestal'){if(!reduced.matches)mode={name:'face',since:performance.now()};closeBay();return;}\r\n  // A save re-renders the open menu; keep the control the player was using focused.\r\n  const active=doc.activeElement as HTMLElement|null,keep=panel.contains(active)?active!.dataset:null;\r\n  open=section;panel.hidden=false;panel.dataset.galaBay=section;\r\n  const title={pets:'Animal cages · Pet',weapons:'Weapon rack · Weapon',mirror:'Mirror · Alien features',clothing:'Centre station · Clothes'}[section];\r\n  heading.textContent=title;\r\n  const editor=createGalaEditor({document:doc,avatar:A,weapons:W,look:saved,\r\n   previewDraw:coaches?.hasBody?(canvas:HTMLCanvasElement,previewLook:Look,options:any)=>coaches!.draw(A.draw,canvas,previewLook,options):A.draw,\r\n   onPart:(id:string,value:number,label:string)=>{touch();vaultQueue('gala-part');vaultQueue('gala-slot',id);save({...saved,parts:{...saved.parts,[id]:value}},`${(A.sections as Section[]).find(item=>item.id===id)?.label||label}: ${label}.`);},\r\n   onDye:(value:number)=>{touch();vaultQueue('gala-slot','dye');save({...saved,dye:value},`Silk ${value+1}.`);},\r\n   onWeapon:(value:{type:string;tier:number})=>{touch();vaultQueue('gala-slot','weapon');const previous=saved.weapon||{type:'rapier',tier:0};if((value.type!==previous.type||value.tier!==previous.tier)&&!W.unlocked(value))value={type:value.type,tier:0};save({...saved,weapon:value},W.name(value)+'.');},\r\n   locked:(value:{type:string;tier:number})=>!W.unlocked(value)\r\n  });\r\n  if(section==='pets')body.replaceChildren(...editor.parts(['pet']),...(coaches?[coaches.picker('pet',load)]:[]));\r\n  else if(section==='weapons')body.replaceChildren(editor.weapons());\r\n  else if(section==='mirror')body.replaceChildren(...editor.parts(coaches?.hasBody?['skin']:MIRROR),...(coaches?[coaches.picker('body',load)]:[]));\r\n  else if(coaches?.hasBody){\r\n   body.replaceChildren(el('p','Coach characters do not wear Gala clothes. Change their colour at the mirror.','help'));\r\n  }\r\n  else{\r\n   body.replaceChildren(...editor.parts(CLOTHES),editor.dye());\r\n  }\r\n  if(keep?.galaPart)(body.querySelector(`[data-gala-part=\"${keep.galaPart}\"]`) as HTMLElement|null)?.focus();\r\n  if(keep?.galaWeapon)(body.querySelector(`[data-gala-weapon=\"${keep.galaWeapon}\"]`) as HTMLElement|null)?.focus();\r\n }\r\n function closeBay(){open=null;panel.hidden=true;body.replaceChildren();}\r\n // Without the downloaded room (or if it fails), the same menus sit under the character on the plain floor disc.\r\n let cage:ReturnType<typeof mountCage>|null=null;\r\n function flatBays(){\r\n  const row=el('div','','cage-bays');row.setAttribute('role','group');row.setAttribute('aria-label','War Room sections');\r\n  for(const s of SECTIONS){if(s.id==='overview'||s.id==='pedestal')continue;const b=el('button',LABELS[s.id].label);b.type='button';b.setAttribute('aria-label',LABELS[s.id].name);b.dataset.cageSection=s.id;b.classList.add('bay-terminal-line');b.onclick=()=>{for(const x of row.children)x.setAttribute('aria-pressed',String(x===b));if(s.id==='overview')closeBay();else showBay(s.id);};row.append(b);}\r\n  stageEl.append(row);row.querySelectorAll<HTMLElement>('[data-cage-section=clothing]').forEach(control=>{control.hidden=!!coaches?.hasBody;});\r\n }\r\n void cagePacketReady().then(have=>{\r\n  if(disposed)return;\r\n  if(!have){flatBays();tell('Download the 3D cage: Install → Downloads.');return;}\r\n  cage=mountCage(stage,{openTab:()=>false,showBay:()=>{},closeBay,tell,bay:showBay,labels:LABELS,volumes:{pedestal:[[.02,.64,-.01,.22,.20,.24,0]],clothing:[[.06,.3,-.31,.18,.12,.1,0]]}});\r\n  stage.mount.querySelectorAll('[data-cage-section=overview],[data-cage-section=pedestal]').forEach(el=>el.remove());\r\n  void cage.ready.then(ok=>{if(!disposed){if(!ok)flatBays();load();}});\r\n });\r\n const tick=(now:number)=>{\r\n  if(disposed)return;frame=requestAnimationFrame(tick);if(now-last<32||doc.hidden)return;last=now;\r\n  sprite.rotation.y=Math.atan2(stage.camera.position.x-sprite.position.x,stage.camera.position.z-sprite.position.z);\r\n  if(reduced.matches)performer.paint(canvas,0,true);\r\n  else{const clock=sceneClock(mode,now,idleSince,performer.scenes);mode=clock.mode;idleSince=clock.idleSince??idleSince;performer.paint(canvas,clock.time,false);}\r\n  texture.needsUpdate=true;stage.orbit.update();stage.renderer.render(stage.scene,stage.camera);\r\n };\r\n const resize=new ResizeObserver(()=>stage.resize());resize.observe(stageEl);stage.resize();\r\n const onStorage=(event:StorageEvent)=>{if(event.key===GALA_KEY)load();else if(event.key?.startsWith(PERFORMANCE_KEY+'/')&&open)showBay(open);},onReduced=()=>{stage.settings.reduced=reduced.matches;};\r\n const onCoachProgress=()=>{if(open)showBay(open);};\r\n stage.renderer.domElement.addEventListener('pointerdown',touch);\r\n addEventListener('mominc-avatar-change',load);addEventListener('storage',onStorage);addEventListener('myr5:performance-progress',onCoachProgress);reduced.addEventListener('change',onReduced);\r\n load();frame=requestAnimationFrame(tick);\r\n return {stage,get cage(){return cage;},get mode(){return mode.name;},showBay,closeBay,\r\n  dispose(){if(disposed)return;disposed=true;cancelAnimationFrame(frame);cage?.dispose();resize.disconnect();removeEventListener('mominc-avatar-change',load);removeEventListener('storage',onStorage);removeEventListener('myr5:performance-progress',onCoachProgress);reduced.removeEventListener('change',onReduced);\r\n   texture.dispose();sprite.geometry.dispose();(sprite.material as T.Material).dispose();stage.orbit.dispose();stage.scene.environment?.dispose();stage.renderer.dispose();host.replaceChildren();}};\r\n}\r\n","creature/source/weapon-wall.mjs":"import {authFetch} from '../../auth-client.mjs';\r\nimport {authTransitions} from '../../auth-transition.mjs';\r\nimport {createWarRoomApi} from '../../war-room/account-api.mjs';\r\n\r\nexport const GALA_WEAPONS=Object.freeze([\r\n ['rapier','Rapier'],['greatsword','Greatsword'],['dagger','Dagger'],['sabre','Sabre'],['axe','Axe'],\r\n ['hammer','Hammer'],['mace','Mace'],['flail','Flail'],['spear','Spear'],['trident','Trident'],\r\n ['halberd','Halberd'],['scythe','Scythe'],['bow','Bow'],['crossbow','Crossbow'],['chakram','Chakram'],\r\n ['gauntlets','Gauntlets'],['staff','Staff'],['wand','Wand'],['tome','Tome'],['cannon','Cannon']\r\n]);\r\nconst TYPES=new Set(GALA_WEAPONS.map(([type])=>type));\r\nconst ownerOf=account=>typeof account==='string'?account:account?.user?.id;\r\nconst validState=state=>state&&Number.isSafeInteger(state.revision)&&state.revision>=0&&\r\n TYPES.has(state.loadout?.type)&&Number.isInteger(state.loadout?.tier)&&\r\n state.loadout.tier>=0&&state.loadout.tier<=20;\r\n\r\nexport function createWeaponWallController({\r\n request=authFetch,transitions=authTransitions(),\r\n getAccount=()=>globalThis.window?.myr5AuthenticatedAccount\r\n}={}){\r\n const client=createWarRoomApi({request,transitions}),listeners=new Set();\r\n let generation=0,disposed=false,pending=false,owner=null;\r\n let snapshot={mode:'locked',message:'Sign in to view your War Room loadout.',loadout:null,revision:null};\r\n const set=next=>{snapshot={...snapshot,...next};for(const listener of listeners)listener({...snapshot});};\r\n const reset=()=>{generation++;pending=false;owner=null;client.clear();set({mode:'locked',message:'Account changed. Refresh the weapon wall.',loadout:null,revision:null});};\r\n const unsubscribe=transitions.subscribe(reset);\r\n const current=(run,ticket,expectedOwner)=>{\r\n  if(disposed||run!==generation||ownerOf(getAccount())!==expectedOwner)return false;\r\n  try{transitions.assertCurrent(ticket);return true;}catch{return false;}\r\n };\r\n async function refresh(message){\r\n  if(disposed)return;\r\n  const run=++generation,expectedOwner=ownerOf(getAccount());\r\n  pending=false;owner=null;client.clear();\r\n  if(!expectedOwner){set({mode:'locked',message:'Sign in to view your War Room loadout.',loadout:null,revision:null});return;}\r\n  let ticket;\r\n  try{ticket=transitions.capture();}catch{set({mode:'unavailable',message:'Account sync is unavailable. Refresh to retry.',loadout:null,revision:null});return;}\r\n  set({mode:'loading',message:'Checking War Room access…',loadout:null,revision:null});\r\n  try{\r\n   const room=await client.api('/api/war-room');\r\n   if(!current(run,ticket,expectedOwner))return;\r\n   if(room.targetAccountId!==expectedOwner||!validState(room.state))throw Error('War Room returned an invalid account loadout.');\r\n   owner=expectedOwner;\r\n   set({mode:'ready',message:message||'Saved Gala loadout for this account.',loadout:{...room.state.loadout},revision:room.state.revision});\r\n  }catch(error){\r\n   if(!current(run,ticket,expectedOwner))return;\r\n   const unauthenticated=error.status===401;\r\n   set({mode:unauthenticated?'locked':'unavailable',\r\n    message:unauthenticated?'Sign in to view your War Room loadout.':error.message||'War Room unavailable. Refresh to retry.',\r\n    loadout:null,revision:null});\r\n  }\r\n }\r\n async function save(type,tier){\r\n  if(disposed||pending||snapshot.mode!=='ready'||!owner||ownerOf(getAccount())!==owner)return false;\r\n  if(!TYPES.has(type)||!Number.isInteger(tier)||tier<0||tier>20){\r\n   set({message:'Choose a valid Gala weapon and tier from 0 to 20.'});return false;\r\n  }\r\n  const run=generation,expectedOwner=owner,revision=snapshot.revision;\r\n  let ticket;\r\n  try{ticket=transitions.capture();}catch{reset();return false;}\r\n  pending=true;set({mode:'saving',message:'Saving Gala loadout…'});\r\n  try{\r\n   const reply=await client.api('/api/war-room/loadout',{method:'PUT',headers:{'Content-Type':'application/json'},\r\n    body:JSON.stringify({revision,loadout:{type,tier}})});\r\n   if(!current(run,ticket,expectedOwner))return false;\r\n   if(!validState(reply.state))throw Error('War Room returned an invalid loadout.');\r\n   set({mode:'ready',message:'Gala loadout saved.',loadout:{...reply.state.loadout},revision:reply.state.revision});\r\n   return true;\r\n  }catch(error){\r\n   if(!current(run,ticket,expectedOwner))return false;\r\n   if(error.status===409){await refresh('War Room changed on another device. Review the refreshed loadout before saving.');return false;}\r\n   owner=null;client.clear();\r\n   set({mode:error.status===401?'locked':'unavailable',\r\n    message:error.message||'Could not save. Refresh to retry.',loadout:null,revision:null});\r\n   return false;\r\n  }finally{if(run===generation)pending=false;}\r\n }\r\n return {\r\n  getState:()=>({...snapshot,loadout:snapshot.loadout&&{...snapshot.loadout}}),\r\n  subscribe(listener){listeners.add(listener);listener({...snapshot});return()=>listeners.delete(listener);},\r\n  refresh,save,\r\n  dispose(){if(disposed)return;disposed=true;generation++;listeners.clear();unsubscribe?.();client.dispose();}\r\n };\r\n}\r\n\r\n// The cage mounts this after its own scene admission; the server still requires the signed-in owner.\r\nexport function mountWeaponWall({host,request,transitions,getAccount,eventTarget=globalThis.window}){\r\n if(!host?.ownerDocument)throw Error('Weapon wall needs a host element.');\r\n const doc=host.ownerDocument,controller=createWeaponWallController({request,transitions,getAccount});\r\n const root=doc.createElement('section'),heading=doc.createElement('h2'),status=doc.createElement('p');\r\n const type=doc.createElement('select'),tier=doc.createElement('input'),save=doc.createElement('button');\r\n const refresh=doc.createElement('button'),link=doc.createElement('a');\r\n root.className='cage-weapon-wall';heading.textContent='Weapon wall';status.setAttribute('role','status');\r\n type.setAttribute('aria-label','Gala weapon');\r\n for(const [id,label] of GALA_WEAPONS){const option=doc.createElement('option');option.value=id;option.textContent=label;type.append(option);}\r\n tier.type='number';tier.min='0';tier.max='20';tier.step='1';tier.setAttribute('aria-label','Saved tier');\r\n save.type='button';save.textContent='Save loadout';refresh.type='button';refresh.textContent='Refresh';\r\n link.href='/war-room/';link.textContent='Open War Room';\r\n root.append(heading,status,type,tier,save,refresh,link);host.append(root);\r\n const unsubscribe=controller.subscribe(state=>{\r\n  status.textContent=state.message;const editable=state.mode==='ready';\r\n  type.disabled=tier.disabled=save.disabled=!editable;\r\n  refresh.disabled=state.mode==='loading'||state.mode==='saving';\r\n  if(state.loadout){type.value=state.loadout.type;tier.value=String(state.loadout.tier);}\r\n });\r\n const onSave=()=>void controller.save(type.value,tier.value?Number(tier.value):NaN);\r\n const onRefresh=()=>void controller.refresh();\r\n save.addEventListener('click',onSave);refresh.addEventListener('click',onRefresh);\r\n eventTarget?.addEventListener('myr5:account-ready',onRefresh);\r\n eventTarget?.addEventListener('myr5:account-cleared',onRefresh);\r\n void controller.refresh();\r\n return {controller,dispose(){\r\n  unsubscribe();controller.dispose();\r\n  save.removeEventListener('click',onSave);refresh.removeEventListener('click',onRefresh);\r\n  eventTarget?.removeEventListener('myr5:account-ready',onRefresh);\r\n  eventTarget?.removeEventListener('myr5:account-cleared',onRefresh);root.remove();\r\n }};\r\n}\r\n","daily-guide.mjs":"// How to Play opens by itself once per local calendar day, the first time the app opens that day,\r\n// separately for each signed-in account and for the guest on this device.\r\nexport const DAILY_GUIDE_KEY='myr5-how-to-play-day-v1';\r\nexport const localDay=(date=new Date())=>`${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`;\r\nexport const guideOwner=(account=globalThis.myr5AuthenticatedAccount)=>{const id=account?.user?.id;return typeof id==='string'&&id?'account:'+id:'guest';};\r\nconst keyFor=owner=>`${DAILY_GUIDE_KEY}/${owner}`;\r\nexport function dailyGuideDue({owner=guideOwner(),date=new Date(),storage=globalThis.localStorage}={}){\r\n try{return storage.getItem(keyFor(owner))!==localDay(date);}catch{return false;}\r\n}\r\nexport function markDailyGuide({owner=guideOwner(),date=new Date(),storage=globalThis.localStorage}={}){\r\n try{storage.setItem(keyFor(owner),localDay(date));return true;}catch{return false;}\r\n}\r\n","db/schema.ts":"import {sql} from 'drizzle-orm';\r\nimport {sqliteTable,text,integer,real,index,uniqueIndex,primaryKey,check} from 'drizzle-orm/sqlite-core';\r\nexport const profiles=sqliteTable('profiles',{userId:text('user_id').primaryKey(),data:text('data').notNull().default('{}'),revision:integer('revision').notNull().default(0),updatedAt:integer('updated_at').notNull()});\r\nexport const workouts=sqliteTable('workouts',{\r\n id:text('id').primaryKey(),userId:text('user_id').notNull(),mode:text('mode').notNull(),goal:real('goal').notNull(),startedAt:integer('started_at').notNull(),completedAt:integer('completed_at'),value:real('value'),active:real('active'),\r\n source:text('source').notNull().default('server'),clientWorkoutId:text('client_workout_id'),competitiveStatus:text('competitive_status'),\r\n},t=>[\r\n index('workouts_user_completed').on(t.userId,t.completedAt),\r\n uniqueIndex('ux_workouts_acct_cwid').on(t.userId,t.clientWorkoutId).where(sql`${t.clientWorkoutId} IS NOT NULL`),\r\n index('ix_workouts_authority').on(t.userId,t.source,t.completedAt),\r\n index('ix_workouts_rank').on(t.userId,t.competitiveStatus,t.mode,t.completedAt),\r\n check('workouts_source',sql`${t.source} IN ('server','guest_import')`),\r\n check('workouts_competitive_status',sql`${t.competitiveStatus} IS NULL OR ${t.competitiveStatus} IN ('accepted','pending','not_eligible')`),\r\n]);\r\nexport const meals=sqliteTable('meals',{id:text('id').primaryKey(),userId:text('user_id').notNull(),name:text('name').notNull(),portion:text('portion').notNull(),calories:real('calories'),protein:real('protein'),carbs:real('carbs'),fat:real('fat'),micros:text('micros').notNull().default('{}'),nutritionSource:text('nutrition_source'),eatenAt:text('eaten_at').notNull(),createdAt:integer('created_at').notNull()},t=>[index('meals_user_date').on(t.userId,t.eatenAt)]);\r\nexport const reminders=sqliteTable('reminders',{id:text('id').primaryKey(),userId:text('user_id').notNull(),kind:text('kind').notNull(),time:text('time').notNull(),timezone:text('timezone').notNull(),enabled:integer('enabled').notNull().default(1),quietStart:text('quiet_start').notNull().default('22:00'),quietEnd:text('quiet_end').notNull().default('07:00'),tone:text('tone').notNull().default('direct'),daysPerWeek:integer('days_per_week').notNull().default(7)},t=>[index('reminders_user').on(t.userId)]);\r\nexport const subscriptions=sqliteTable('subscriptions',{endpoint:text('endpoint').primaryKey(),userId:text('user_id').notNull(),data:text('data').notNull(),createdAt:integer('created_at').notNull()},t=>[index('subscriptions_user').on(t.userId)]);\r\nexport const releasePushDeliveries=sqliteTable('release_push_deliveries',{endpoint:text('endpoint').notNull().references(()=>subscriptions.endpoint,{onDelete:'cascade'}),releaseId:text('release_id').notNull(),status:text('status').notNull(),updatedAt:integer('updated_at').notNull()},t=>[primaryKey({columns:[t.endpoint,t.releaseId]})]);\r\nexport const deliveries=sqliteTable('deliveries',{reminderId:text('reminder_id').notNull(),day:text('day').notNull(),endpoint:text('endpoint').notNull(),status:text('status').notNull(),updatedAt:integer('updated_at').notNull()},t=>[primaryKey({columns:[t.reminderId,t.day,t.endpoint]})]);\r\nexport const armieLetterDeliveries=sqliteTable('armie_letter_deliveries',{userId:text('user_id').notNull(),day:text('day').notNull(),letterId:text('letter_id').notNull(),sentAt:integer('sent_at').notNull()},t=>[primaryKey({columns:[t.userId,t.day,t.letterId]})]);\r\nexport const system=sqliteTable('system',{key:text('key').primaryKey(),value:text('value').notNull()});\r\nexport const loginDays=sqliteTable('login_days',{userId:text('user_id').notNull(),day:integer('day').notNull(),loggedAt:integer('logged_at').notNull()},t=>[primaryKey({columns:[t.userId,t.day]})]);\r\nexport const breathingSessions=sqliteTable('breathing_sessions',{id:text('id').primaryKey(),userId:text('user_id').notNull(),startedAt:integer('started_at').notNull(),completedAt:integer('completed_at')},t=>[index('breathing_user_started').on(t.userId,t.startedAt),index('breathing_user_completed').on(t.userId,t.completedAt)]);\r\nexport const scoreboardInvites=sqliteTable('scoreboard_invites',{ownerId:text('owner_id').primaryKey(),tokenHash:text('token_hash').notNull().unique(),createdAt:integer('created_at').notNull(),expiresAt:integer('expires_at').notNull()});\r\nexport const scoreboardLinks=sqliteTable('scoreboard_links',{id:text('id').primaryKey(),userA:text('user_a').notNull(),userB:text('user_b').notNull(),createdAt:integer('created_at').notNull()},t=>[index('scoreboard_links_a').on(t.userA),index('scoreboard_links_b').on(t.userB),uniqueIndex('scoreboard_links_pair').on(t.userA,t.userB)]);\r\nexport const onboarding=sqliteTable('onboarding',{userId:text('user_id').primaryKey(),data:text('data').notNull(),startDay:text('start_day').notNull(),completedAt:integer('completed_at').notNull(),updatedAt:integer('updated_at').notNull(),revision:integer('revision').notNull().default(1),writeToken:text('write_token').notNull()});\r\n\r\nexport const installDrafts=sqliteTable('install_drafts',{tokenHash:text('token_hash').primaryKey(),data:text('data').notNull(),creator:text('creator').notNull(),expiresAt:integer('expires_at').notNull()},t=>[index('install_drafts_expiry').on(t.expiresAt),index('install_drafts_creator').on(t.creator)]);\r\n\r\nexport const accountIdentities=sqliteTable('account_identities',{clerkId:text('clerk_id').primaryKey(),ownerId:text('owner_id').notNull().unique(),createdAt:integer('created_at').notNull()});\r\n\r\nexport const releaseSubscribers=sqliteTable('release_subscribers',{userId:text('user_id').primaryKey(),email:text('email').notNull(),enabled:integer('enabled').notNull().default(0),confirmHash:text('confirm_hash'),expiresAt:integer('expires_at'),unsubscribeToken:text('unsubscribe_token').notNull().unique(),updatedAt:integer('updated_at').notNull(),confirmedAt:integer('confirmed_at'),lastRelease:text('last_release')},t=>[index('release_subscribers_confirmation').on(t.confirmHash)]);\r\nexport const releaseDeliveries=sqliteTable('release_deliveries',{userId:text('user_id').notNull(),releaseId:text('release_id').notNull(),status:text('status').notNull(),updatedAt:integer('updated_at').notNull()},t=>[primaryKey({columns:[t.userId,t.releaseId]})]);\r\nexport const galaRuns=sqliteTable('gala_runs',{id:text('id').primaryKey(),tokenHash:text('token_hash').notNull(),creator:text('creator').notNull(),startedAt:integer('started_at').notNull(),djName:text('dj_name'),moniker:text('moniker'),djAt:integer('dj_at'),galaAt:integer('gala_at'),lilAt:integer('lil_at'),corgiAt:integer('corgi_at'),handAt:integer('hand_at'),armieAt:integer('armie_at'),completedAt:integer('completed_at'),durationMs:integer('duration_ms'),installedAt:integer('installed_at'),joinedAt:integer('joined_at'),publicName:text('public_name').unique()},t=>[index('gala_runs_creator_started').on(t.creator,t.startedAt),index('gala_runs_leaderboard').on(t.joinedAt,t.durationMs)]);\r\nexport const coachArmyCompletions=sqliteTable('coach_army_completions',{dataEpoch:integer('data_epoch').notNull().default(1),eventId:text('event_id').primaryKey(),userId:text('user_id').notNull(),completedAt:integer('completed_at').notNull(),receivedAt:integer('received_at').notNull()},t=>[index('coach_army_completions_user').on(t.userId)]);\r\nexport const accountEntitlements=sqliteTable('account_entitlements',{dataEpoch:integer('data_epoch').notNull().default(1),userId:text('user_id').primaryKey(),coachArmyStatus:text('coach_army_status').notNull().default('locked'),coachArmyCompletedAt:integer('coach_army_completed_at'),coachArmyEventId:text('coach_army_event_id'),updatedAt:integer('updated_at').notNull()});\r\nexport const accountPackEntitlements=sqliteTable('account_pack_entitlements',{userId:text('user_id').notNull(),packId:text('pack_id').notNull(),status:text('status').notNull(),grantedAt:integer('granted_at').notNull()},t=>[primaryKey({columns:[t.userId,t.packId]}),index('account_pack_entitlements_user').on(t.userId)]);\r\nexport const coachArmyRuns=sqliteTable('coach_army_runs',{dataEpoch:integer('data_epoch').notNull().default(1),id:text('id').primaryKey(),accountId:text('account_id').notNull(),startedAt:integer('started_at').notNull(),completedAt:integer('completed_at'),completionEventId:text('completion_event_id'),updatedAt:integer('updated_at').notNull()},t=>[index('coach_army_runs_account').on(t.accountId,t.startedAt)]);\r\nexport const coachArmyRunEvents=sqliteTable('coach_army_run_events',{dataEpoch:integer('data_epoch').notNull().default(1),eventId:text('event_id').primaryKey(),runId:text('run_id').notNull(),accountId:text('account_id').notNull(),sequence:integer('sequence').notNull(),stage:text('stage').notNull(),source:text('source').notNull(),receivedAt:integer('received_at').notNull()},t=>[index('coach_army_run_events_run').on(t.runId,t.sequence),uniqueIndex('coach_army_run_sequence').on(t.runId,t.sequence)]);\r\nexport const coachArmyCompletionOutbox=sqliteTable('coach_army_completion_outbox',{dataEpoch:integer('data_epoch').notNull().default(1),eventId:text('event_id').primaryKey(),runId:text('run_id').notNull(),accountId:text('account_id').notNull(),completedAt:integer('completed_at').notNull(),status:text('status').notNull().default('pending'),attempts:integer('attempts').notNull().default(0),lastError:text('last_error'),deliveredAt:integer('delivered_at'),updatedAt:integer('updated_at').notNull()},t=>[index('coach_army_completion_outbox_pending').on(t.status,t.updatedAt)]);\r\nexport const coachArmyDjscratchChallenges=sqliteTable('coach_army_djscratch_challenges',{dataEpoch:integer('data_epoch').notNull().default(1),id:text('id').primaryKey(),runId:text('run_id').notNull(),accountId:text('account_id').notNull(),expiresAt:integer('expires_at').notNull(),nextStep:integer('next_step').notNull().default(0),status:text('status').notNull().default('active'),createdAt:integer('created_at').notNull(),completedAt:integer('completed_at'),updatedAt:integer('updated_at').notNull()},t=>[index('coach_army_djscratch_challenges_run').on(t.runId,t.accountId,t.status)]);\r\nexport const goals=sqliteTable('goals',{id:text('id').primaryKey(),userId:text('user_id').notNull(),title:text('title').notNull(),note:text('note').notNull().default(''),status:text('status').notNull().default('active'),createdAt:integer('created_at').notNull(),updatedAt:integer('updated_at').notNull()},t=>[index('goals_user_updated').on(t.userId,t.updatedAt)]);\r\nexport const warRoomArsenals=sqliteTable('war_room_arsenals',{userId:text('user_id').primaryKey(),loadout:text('loadout').notNull(),recipes:text('recipes').notNull().default('[]'),revision:integer('revision').notNull().default(0),updatedAt:integer('updated_at').notNull()});\r\n\r\n// Retained account generation and deletion receipts fence delayed requests.\r\nexport const accountDataEpochs=sqliteTable('account_data_epochs',{\r\n ownerId:text('owner_id').primaryKey().notNull(),\r\n epoch:integer('epoch').notNull().default(1),\r\n updatedAt:integer('updated_at').notNull(),\r\n},t=>[check('account_data_epochs_epoch',sql`typeof(${t.epoch}) = 'integer' AND ${t.epoch} BETWEEN 1 AND 9007199254740991`),check('account_data_epochs_updated',sql`typeof(${t.updatedAt}) = 'integer' AND ${t.updatedAt} >= 0`)]);\r\nexport const accountDataDeletions=sqliteTable('account_data_deletions',{\r\n ownerId:text('owner_id').notNull().references(()=>accountDataEpochs.ownerId),\r\n deletedEpoch:integer('deleted_epoch').notNull(),\r\n deletedAt:integer('deleted_at').notNull(),\r\n},t=>[primaryKey({columns:[t.ownerId,t.deletedEpoch]}),check('account_data_deletions_epoch',sql`typeof(${t.deletedEpoch}) = 'integer' AND ${t.deletedEpoch} BETWEEN 1 AND 9007199254740990`),check('account_data_deletions_time',sql`typeof(${t.deletedAt}) = 'integer' AND ${t.deletedAt} >= 0`)]);\r\n\r\nexport const workoutImports=sqliteTable('workout_imports',{\r\n workoutId:text('workout_id').primaryKey().notNull().references(()=>workouts.id,{onDelete:'cascade'}),\r\n idempotencyKey:text('idempotency_key').notNull(),fingerprint:text('fingerprint').notNull(),digestVersion:integer('digest_version').notNull(),accountDataEpoch:integer('account_data_epoch').notNull(),createdAt:integer('created_at').notNull(),\r\n},t=>[\r\n check('workout_imports_key',sql`length(${t.idempotencyKey})=64 AND ${t.idempotencyKey} NOT GLOB '*[^0-9a-f]*'`),\r\n check('workout_imports_fingerprint',sql`length(${t.fingerprint})=64 AND ${t.fingerprint} NOT GLOB '*[^0-9a-f]*'`),\r\n check('workout_imports_version',sql`typeof(${t.digestVersion})='integer' AND ${t.digestVersion} BETWEEN 1 AND 9007199254740991`),\r\n check('workout_imports_epoch',sql`typeof(${t.accountDataEpoch})='integer' AND ${t.accountDataEpoch} BETWEEN 1 AND 9007199254740991`),\r\n check('workout_imports_created',sql`typeof(${t.createdAt})='integer' AND ${t.createdAt} BETWEEN 0 AND 9007199254740991`),\r\n]);\r\nexport const competitiveDecisions=sqliteTable('competitive_decisions',{\r\n workoutId:text('workout_id').notNull().references(()=>workouts.id,{onDelete:'cascade'}),seq:integer('seq').notNull(),status:text('status').notNull(),reason:text('reason').notNull(),createdAt:integer('created_at').notNull(),\r\n},t=>[\r\n primaryKey({columns:[t.workoutId,t.seq]}),\r\n check('competitive_decisions_seq',sql`typeof(${t.seq})='integer' AND ${t.seq} BETWEEN 1 AND 9007199254740991`),\r\n check('competitive_decisions_status',sql`${t.status} IN ('accepted','pending','not_eligible')`),\r\n check('competitive_decisions_reason',sql`length(${t.reason}) BETWEEN 1 AND 128`),\r\n check('competitive_decisions_created',sql`typeof(${t.createdAt})='integer' AND ${t.createdAt} BETWEEN 0 AND 9007199254740991`),\r\n]);\r\n\r\nexport const coachArmyBindings=sqliteTable('coach_army_bindings',{dataEpoch:integer('data_epoch').notNull().default(1),bindingId:text('binding_id').primaryKey().notNull(),runId:text('run_id').notNull(),accountId:text('account_id').notNull(),eventId:text('event_id').notNull().unique(),claimHash:text('claim_hash').notNull().unique(),completedAt:integer('completed_at').notNull(),expiresAt:integer('expires_at').notNull(),claimedAt:integer('claimed_at'),createdAt:integer('created_at').notNull()},t=>[index('coach_army_bindings_account').on(t.accountId,t.expiresAt)]);\r\n","demo-poses.mjs":"// Small procedural teaching figures. Coordinates are metres, y points up.\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {applyExerciseDemo} from './exercise-demo.mjs';\r\nexport function demoPose(mode,t=0){\r\n const p={head:[0,.85,0],neck:[0,.65,0],ls:[-.23,.57,0],rs:[.23,.57,0],le:[-.31,.18,0],re:[.31,.18,0],lw:[-.3,-.13,0],rw:[.3,-.13,0],lh:[-.15,0,0],rh:[.15,0,0],lk:[-.17,-.46,0],rk:[.17,-.46,0],la:[-.17,-.95,0],ra:[.17,-.95,0]};\r\n const wave=Math.sin(t*4),rise=Math.max(0,Math.sin(t*3.6));\r\n if(mode==='tree'){p.lk=[-.52,-.2,0];p.la=[.12,-.38,0];p.le=[-.3,.32,0];p.re=[.3,.32,0];p.lw=[-.025,.48,.08];p.rw=[.025,.48,.08];}\r\n if(mode==='warrior'){p.lk=[-.65,-.4,0];p.la=[-.65,-.95,0];p.rk=[.46,-.43,0];p.ra=[.82,-.95,0];p.le=[-.58,.57,0];p.re=[.58,.57,0];p.lw=[-.94,.57,0];p.rw=[.94,.57,0];}\r\n if(mode==='horse'){p.lk=[-.53,-.25,0];p.rk=[.53,-.25,0];p.la=[-.53,-.79,0];p.ra=[.53,-.79,0];p.le=[-.3,.24,.05];p.re=[.3,.24,.05];p.lw=[-.03,.42,.15];p.rw=[.03,.42,.15];for(const v of Object.values(p))v[1]-=.15;}\r\n if(mode==='boxing'){for(const [side,sign,phase] of [['l',-1,wave],['r',1,-wave]]){const punch=Math.max(0,phase);p[side+'e']=[sign*.28,.37+punch*.16,.2+punch*.22];p[side+'w']=[sign*.2,.55,.25+punch*.65];}p.la=[-.32,-.95,.1];p.ra=[.32,-.95,-.17];}\r\n if(mode==='jogging'){for(const [side,sign,phase] of [['l',-1,wave],['r',1,-wave]]){const lift=Math.max(0,phase);p[side+'k']=[sign*.17,-.46+lift*.4,lift*.36];p[side+'a']=[sign*.17,-.95+lift*.42,.06];p[side+'e']=[sign*.32,.22,-phase*.18];p[side+'w']=[sign*.27,.42,-phase*.32];}for(const v of Object.values(p))v[1]+=.035*Math.abs(wave);}\r\n if(mode==='jumping'){for(const v of Object.values(p))v[1]+=.3*rise;p.le[0]-=.1*rise;p.re[0]+=.1*rise;p.lw[1]+=.45*rise;p.rw[1]+=.45*rise;}\r\n return EXERCISES[mode]?applyExerciseDemo(p,EXERCISES[mode],t):p;\r\n}\r\nexport const DEMO_BONES=[['head','neck'],['ls','rs'],['neck','lh'],['neck','rh'],['lh','rh'],['ls','le'],['le','lw'],['rs','re'],['re','rw'],['lh','lk'],['lk','la'],['rh','rk'],['rk','ra']];\r\n","device-notifications.mjs":"// A browser subscription alone does not prove it belongs to the signed-in account.\r\nexport function notificationBinding(api){\r\n let binding=null,checkedAt=0;\r\n return {\r\n  ready(user){return !!user&&binding?.user===user&&Date.now()-checkedAt<90000;},\r\n  forget(){binding=null;checkedAt=0;},\r\n  async verify(account,subscription){\r\n   if(!account?.onboarding||!subscription){this.forget();return false;}\r\n   const user=account.user.id,endpoint=subscription.endpoint;\r\n   if(binding?.user===user&&binding.endpoint===endpoint&&Date.now()-checkedAt<60000)return true;\r\n   this.forget();await api('/api/push/subscribe','POST',subscription.toJSON());binding={user,endpoint};checkedAt=Date.now();return true;\r\n  }\r\n };\r\n}\r\n","drizzle.config.ts":"import {defineConfig} from 'drizzle-kit';\r\nexport default defineConfig({schema:'./db/schema.ts',out:'./drizzle',dialect:'sqlite'});\r\n","drizzle/0000_new_cammi.sql":"CREATE TABLE `deliveries` (\r\n\t`reminder_id` text NOT NULL,\r\n\t`day` text NOT NULL,\r\n\t`endpoint` text NOT NULL,\r\n\t`status` text NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\tPRIMARY KEY(`reminder_id`, `day`, `endpoint`)\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `meals` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`user_id` text NOT NULL,\r\n\t`name` text NOT NULL,\r\n\t`portion` text NOT NULL,\r\n\t`calories` real,\r\n\t`protein` real,\r\n\t`carbs` real,\r\n\t`fat` real,\r\n\t`eaten_at` text NOT NULL,\r\n\t`created_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `meals_user_date` ON `meals` (`user_id`,`eaten_at`);--> statement-breakpoint\r\nCREATE TABLE `profiles` (\r\n\t`user_id` text PRIMARY KEY NOT NULL,\r\n\t`data` text DEFAULT '{}' NOT NULL,\r\n\t`revision` integer DEFAULT 0 NOT NULL,\r\n\t`updated_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `reminders` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`user_id` text NOT NULL,\r\n\t`kind` text NOT NULL,\r\n\t`time` text NOT NULL,\r\n\t`timezone` text NOT NULL,\r\n\t`enabled` integer DEFAULT 1 NOT NULL,\r\n\t`quiet_start` text DEFAULT '22:00' NOT NULL,\r\n\t`quiet_end` text DEFAULT '07:00' NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `reminders_user` ON `reminders` (`user_id`);--> statement-breakpoint\r\nCREATE TABLE `subscriptions` (\r\n\t`endpoint` text PRIMARY KEY NOT NULL,\r\n\t`user_id` text NOT NULL,\r\n\t`data` text NOT NULL,\r\n\t`created_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `subscriptions_user` ON `subscriptions` (`user_id`);--> statement-breakpoint\r\nCREATE TABLE `system` (\r\n\t`key` text PRIMARY KEY NOT NULL,\r\n\t`value` text NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `workouts` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`user_id` text NOT NULL,\r\n\t`mode` text NOT NULL,\r\n\t`goal` real NOT NULL,\r\n\t`started_at` integer NOT NULL,\r\n\t`completed_at` integer,\r\n\t`value` real,\r\n\t`active` real\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `workouts_user_completed` ON `workouts` (`user_id`,`completed_at`);","drizzle/0001_careful_impossible_man.sql":"ALTER TABLE `reminders` ADD `tone` text DEFAULT 'direct' NOT NULL;--> statement-breakpoint\r\nALTER TABLE `reminders` ADD `days_per_week` integer DEFAULT 7 NOT NULL;","drizzle/0002_peaceful_living_lightning.sql":"CREATE TABLE `onboarding` (\r\n\t`user_id` text PRIMARY KEY NOT NULL,\r\n\t`data` text NOT NULL,\r\n\t`start_day` text NOT NULL,\r\n\t`completed_at` integer NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\t`revision` integer DEFAULT 1 NOT NULL,\r\n\t`write_token` text NOT NULL\r\n);\r\n","drizzle/0003_dashing_meltdown.sql":"CREATE TABLE `install_drafts` (\r\n\t`token_hash` text PRIMARY KEY NOT NULL,\r\n\t`data` text NOT NULL,\r\n\t`creator` text NOT NULL,\r\n\t`expires_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `install_drafts_expiry` ON `install_drafts` (`expires_at`);--> statement-breakpoint\r\nCREATE INDEX `install_drafts_creator` ON `install_drafts` (`creator`);","drizzle/0004_burly_boomerang.sql":"ALTER TABLE `meals` ADD `micros` text DEFAULT '{}' NOT NULL;--> statement-breakpoint\r\nALTER TABLE `meals` ADD `nutrition_source` text;","drizzle/0005_nice_the_enforcers.sql":"CREATE TABLE `account_identities` (\r\n\t`clerk_id` text PRIMARY KEY NOT NULL,\r\n\t`owner_id` text NOT NULL,\r\n\t`created_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE UNIQUE INDEX `account_identities_owner_id_unique` ON `account_identities` (`owner_id`);","drizzle/0006_flawless_slayback.sql":"CREATE TABLE `release_deliveries` (\r\n\t`user_id` text NOT NULL,\r\n\t`release_id` text NOT NULL,\r\n\t`status` text NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\tPRIMARY KEY(`user_id`, `release_id`)\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `release_subscribers` (\r\n\t`user_id` text PRIMARY KEY NOT NULL,\r\n\t`email` text NOT NULL,\r\n\t`enabled` integer DEFAULT 0 NOT NULL,\r\n\t`confirm_hash` text,\r\n\t`expires_at` integer,\r\n\t`unsubscribe_token` text NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\t`confirmed_at` integer,\r\n\t`last_release` text\r\n);\r\n--> statement-breakpoint\r\nCREATE UNIQUE INDEX `release_subscribers_unsubscribe_token_unique` ON `release_subscribers` (`unsubscribe_token`);--> statement-breakpoint\r\nCREATE INDEX `release_subscribers_confirmation` ON `release_subscribers` (`confirm_hash`);","drizzle/0007_tan_mesmero.sql":"CREATE TABLE `gala_runs` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`token_hash` text NOT NULL,\r\n\t`creator` text NOT NULL,\r\n\t`started_at` integer NOT NULL,\r\n\t`dj_name` text,\r\n\t`moniker` text,\r\n\t`dj_at` integer,\r\n\t`gala_at` integer,\r\n\t`lil_at` integer,\r\n\t`corgi_at` integer,\r\n\t`hand_at` integer,\r\n\t`armie_at` integer,\r\n\t`completed_at` integer,\r\n\t`duration_ms` integer,\r\n\t`installed_at` integer,\r\n\t`joined_at` integer,\r\n\t`public_name` text\r\n);\r\n--> statement-breakpoint\r\nCREATE UNIQUE INDEX `gala_runs_public_name_unique` ON `gala_runs` (`public_name`);--> statement-breakpoint\r\nCREATE INDEX `gala_runs_creator_started` ON `gala_runs` (`creator`,`started_at`);--> statement-breakpoint\r\nCREATE INDEX `gala_runs_leaderboard` ON `gala_runs` (`joined_at`,`duration_ms`);","drizzle/0008_giant_charles_xavier.sql":"CREATE TABLE `scoreboard_invites` (\r\n\t`owner_id` text PRIMARY KEY NOT NULL,\r\n\t`token_hash` text NOT NULL,\r\n\t`created_at` integer NOT NULL,\r\n\t`expires_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE UNIQUE INDEX `scoreboard_invites_token_hash_unique` ON `scoreboard_invites` (`token_hash`);--> statement-breakpoint\r\nCREATE TABLE `scoreboard_links` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`user_a` text NOT NULL,\r\n\t`user_b` text NOT NULL,\r\n\t`created_at` integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `scoreboard_links_a` ON `scoreboard_links` (`user_a`);--> statement-breakpoint\r\nCREATE INDEX `scoreboard_links_b` ON `scoreboard_links` (`user_b`);--> statement-breakpoint\r\nCREATE UNIQUE INDEX `scoreboard_links_pair` ON `scoreboard_links` (`user_a`,`user_b`);","drizzle/0009_uneven_rhino.sql":"CREATE TABLE `breathing_sessions` (\r\n\t`id` text PRIMARY KEY NOT NULL,\r\n\t`user_id` text NOT NULL,\r\n\t`started_at` integer NOT NULL,\r\n\t`completed_at` integer\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX `breathing_user_started` ON `breathing_sessions` (`user_id`,`started_at`);--> statement-breakpoint\r\nCREATE INDEX `breathing_user_completed` ON `breathing_sessions` (`user_id`,`completed_at`);--> statement-breakpoint\r\nCREATE TABLE `login_days` (\r\n\t`user_id` text NOT NULL,\r\n\t`day` integer NOT NULL,\r\n\t`logged_at` integer NOT NULL,\r\n\tPRIMARY KEY(`user_id`, `day`)\r\n);\r\n","drizzle/0010_fixed_wrecker.sql":"CREATE TABLE `release_push_deliveries` (\r\n\t`endpoint` text NOT NULL,\r\n\t`release_id` text NOT NULL,\r\n\t`status` text NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\tPRIMARY KEY(`endpoint`, `release_id`),\r\n\tFOREIGN KEY (`endpoint`) REFERENCES `subscriptions`(`endpoint`) ON UPDATE no action ON DELETE cascade\r\n);\r\n","drizzle/0011_coach_army_entitlements.sql":"CREATE TABLE `coach_army_completions` (`event_id` text PRIMARY KEY NOT NULL, `user_id` text NOT NULL, `completed_at` integer NOT NULL, `received_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_completions_user` ON `coach_army_completions` (`user_id`);\r\n--> statement-breakpoint\r\nCREATE TABLE `account_entitlements` (`user_id` text PRIMARY KEY NOT NULL, `coach_army_status` text NOT NULL DEFAULT 'locked', `coach_army_completed_at` integer, `coach_army_event_id` text, `updated_at` integer NOT NULL);\r\n","drizzle/0012_coach_army_bindings.sql":"CREATE TABLE `coach_army_bindings` (`binding_id` text PRIMARY KEY NOT NULL, `run_id` text NOT NULL, `account_id` text NOT NULL, `event_id` text NOT NULL UNIQUE, `claim_hash` text NOT NULL UNIQUE, `completed_at` integer NOT NULL, `expires_at` integer NOT NULL, `claimed_at` integer, `created_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_bindings_account` ON `coach_army_bindings` (`account_id`, `expires_at`);\r\n","drizzle/0013_account_pack_entitlements.sql":"CREATE TABLE `account_pack_entitlements` (`user_id` text NOT NULL, `pack_id` text NOT NULL, `status` text NOT NULL, `granted_at` integer NOT NULL, PRIMARY KEY(`user_id`, `pack_id`));\r\n--> statement-breakpoint\r\nCREATE INDEX `account_pack_entitlements_user` ON `account_pack_entitlements` (`user_id`);\r\n","drizzle/0014_coach_army_authenticated_runs.sql":"CREATE TABLE `coach_army_runs` (`id` text PRIMARY KEY NOT NULL, `account_id` text NOT NULL, `started_at` integer NOT NULL, `completed_at` integer, `completion_event_id` text, `updated_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_runs_account` ON `coach_army_runs` (`account_id`, `started_at`);\r\n--> statement-breakpoint\r\nCREATE TABLE `coach_army_run_events` (`event_id` text PRIMARY KEY NOT NULL, `run_id` text NOT NULL, `account_id` text NOT NULL, `sequence` integer NOT NULL, `stage` text NOT NULL, `source` text NOT NULL, `received_at` integer NOT NULL, UNIQUE(`run_id`, `sequence`));\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_run_events_run` ON `coach_army_run_events` (`run_id`, `sequence`);\r\n--> statement-breakpoint\r\nCREATE TABLE `coach_army_completion_outbox` (`event_id` text PRIMARY KEY NOT NULL, `run_id` text NOT NULL, `account_id` text NOT NULL, `completed_at` integer NOT NULL, `status` text NOT NULL DEFAULT 'pending', `attempts` integer NOT NULL DEFAULT 0, `last_error` text, `delivered_at` integer, `updated_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_completion_outbox_pending` ON `coach_army_completion_outbox` (`status`, `updated_at`);\r\n","drizzle/0015_goals.sql":"CREATE TABLE `goals` (`id` text PRIMARY KEY NOT NULL, `user_id` text NOT NULL, `title` text NOT NULL, `note` text NOT NULL DEFAULT '', `status` text NOT NULL DEFAULT 'active', `created_at` integer NOT NULL, `updated_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `goals_user_updated` ON `goals` (`user_id`,`updated_at`);\r\n","drizzle/0016_war_room_arsenal.sql":"CREATE TABLE `war_room_arsenals` (`user_id` text PRIMARY KEY NOT NULL, `loadout` text NOT NULL, `recipes` text NOT NULL DEFAULT '[]', `revision` integer NOT NULL DEFAULT 0, `updated_at` integer NOT NULL);\r\n","drizzle/0017_coach_army_djscratch_verifier.sql":"CREATE TABLE `coach_army_djscratch_challenges` (`id` text PRIMARY KEY NOT NULL, `run_id` text NOT NULL, `account_id` text NOT NULL, `expires_at` integer NOT NULL, `next_step` integer NOT NULL DEFAULT 0, `status` text NOT NULL DEFAULT 'active', `created_at` integer NOT NULL, `completed_at` integer, `updated_at` integer NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX `coach_army_djscratch_challenges_run` ON `coach_army_djscratch_challenges` (`run_id`, `account_id`, `status`);\r\n","drizzle/0018_account_data_epochs.sql":"CREATE TABLE `account_data_epochs` (\r\n\t`owner_id` text PRIMARY KEY NOT NULL,\r\n\t`epoch` integer DEFAULT 1 NOT NULL,\r\n\t`updated_at` integer NOT NULL,\r\n\tCONSTRAINT \"account_data_epochs_epoch\" CHECK(typeof(\"account_data_epochs\".\"epoch\") = 'integer' AND \"account_data_epochs\".\"epoch\" BETWEEN 1 AND 9007199254740991),\r\n\tCONSTRAINT \"account_data_epochs_updated\" CHECK(typeof(\"account_data_epochs\".\"updated_at\") = 'integer' AND \"account_data_epochs\".\"updated_at\" >= 0)\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `account_data_deletions` (\r\n\t`owner_id` text NOT NULL,\r\n\t`deleted_epoch` integer NOT NULL,\r\n\t`deleted_at` integer NOT NULL,\r\n\tPRIMARY KEY(`owner_id`, `deleted_epoch`),\r\n\tFOREIGN KEY (`owner_id`) REFERENCES `account_data_epochs`(`owner_id`) ON UPDATE no action ON DELETE no action,\r\n\tCONSTRAINT \"account_data_deletions_epoch\" CHECK(typeof(\"account_data_deletions\".\"deleted_epoch\") = 'integer' AND \"account_data_deletions\".\"deleted_epoch\" BETWEEN 1 AND 9007199254740990),\r\n\tCONSTRAINT \"account_data_deletions_time\" CHECK(typeof(\"account_data_deletions\".\"deleted_at\") = 'integer' AND \"account_data_deletions\".\"deleted_at\" >= 0)\r\n);\r\n","drizzle/0019_workout_import_trust.sql":"CREATE TABLE `competitive_decisions` (\r\n\t`workout_id` text NOT NULL,\r\n\t`seq` integer NOT NULL,\r\n\t`status` text NOT NULL,\r\n\t`reason` text NOT NULL,\r\n\t`created_at` integer NOT NULL,\r\n\tPRIMARY KEY(`workout_id`, `seq`),\r\n\tFOREIGN KEY (`workout_id`) REFERENCES `workouts`(`id`) ON UPDATE no action ON DELETE cascade,\r\n\tCONSTRAINT \"competitive_decisions_seq\" CHECK(typeof(\"competitive_decisions\".\"seq\")='integer' AND \"competitive_decisions\".\"seq\" BETWEEN 1 AND 9007199254740991),\r\n\tCONSTRAINT \"competitive_decisions_status\" CHECK(\"competitive_decisions\".\"status\" IN ('accepted','pending','not_eligible')),\r\n\tCONSTRAINT \"competitive_decisions_reason\" CHECK(length(\"competitive_decisions\".\"reason\") BETWEEN 1 AND 128),\r\n\tCONSTRAINT \"competitive_decisions_created\" CHECK(typeof(\"competitive_decisions\".\"created_at\")='integer' AND \"competitive_decisions\".\"created_at\" BETWEEN 0 AND 9007199254740991)\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE `workout_imports` (\r\n\t`workout_id` text PRIMARY KEY NOT NULL,\r\n\t`idempotency_key` text NOT NULL,\r\n\t`fingerprint` text NOT NULL,\r\n\t`digest_version` integer NOT NULL,\r\n\t`account_data_epoch` integer NOT NULL,\r\n\t`created_at` integer NOT NULL,\r\n\tFOREIGN KEY (`workout_id`) REFERENCES `workouts`(`id`) ON UPDATE no action ON DELETE cascade,\r\n\tCONSTRAINT \"workout_imports_key\" CHECK(length(\"workout_imports\".\"idempotency_key\")=64 AND \"workout_imports\".\"idempotency_key\" NOT GLOB '*[^0-9a-f]*'),\r\n\tCONSTRAINT \"workout_imports_fingerprint\" CHECK(length(\"workout_imports\".\"fingerprint\")=64 AND \"workout_imports\".\"fingerprint\" NOT GLOB '*[^0-9a-f]*'),\r\n\tCONSTRAINT \"workout_imports_version\" CHECK(typeof(\"workout_imports\".\"digest_version\")='integer' AND \"workout_imports\".\"digest_version\" BETWEEN 1 AND 9007199254740991),\r\n\tCONSTRAINT \"workout_imports_epoch\" CHECK(typeof(\"workout_imports\".\"account_data_epoch\")='integer' AND \"workout_imports\".\"account_data_epoch\" BETWEEN 1 AND 9007199254740991),\r\n\tCONSTRAINT \"workout_imports_created\" CHECK(typeof(\"workout_imports\".\"created_at\")='integer' AND \"workout_imports\".\"created_at\" BETWEEN 0 AND 9007199254740991)\r\n);\r\n--> statement-breakpoint\r\nALTER TABLE workouts ADD COLUMN source TEXT NOT NULL DEFAULT 'server' CONSTRAINT workouts_source CHECK(source IN ('server','guest_import'));\r\n--> statement-breakpoint\r\nALTER TABLE workouts ADD COLUMN client_workout_id TEXT;\r\n--> statement-breakpoint\r\nALTER TABLE workouts ADD COLUMN competitive_status TEXT CONSTRAINT workouts_competitive_status CHECK(competitive_status IS NULL OR competitive_status IN ('accepted','pending','not_eligible'));\r\n--> statement-breakpoint\r\nCREATE UNIQUE INDEX `ux_workouts_acct_cwid` ON `workouts` (`user_id`,`client_workout_id`) WHERE \"workouts\".\"client_workout_id\" IS NOT NULL;--> statement-breakpoint\r\nCREATE INDEX `ix_workouts_authority` ON `workouts` (`user_id`,`source`,`completed_at`);--> statement-breakpoint\r\nCREATE INDEX `ix_workouts_rank` ON `workouts` (`user_id`,`competitive_status`,`mode`,`completed_at`);\r\n--> statement-breakpoint\r\nCREATE TRIGGER workouts_status_insert_guard BEFORE INSERT ON workouts\r\nWHEN NEW.competitive_status IS NOT NULL OR EXISTS(SELECT 1 FROM workouts WHERE id=NEW.id)\r\nBEGIN SELECT RAISE(ABORT,'workout_insert_authority'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workouts_source_insert_guard BEFORE INSERT ON workouts\r\nWHEN (NEW.source='server' AND NEW.client_workout_id IS NOT NULL)\r\n OR (NEW.source='guest_import' AND (NEW.client_workout_id IS NULL OR length(NEW.client_workout_id)=0 OR NEW.completed_at IS NULL))\r\nBEGIN SELECT RAISE(ABORT,'workout_source_shape'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workouts_authority_immutable BEFORE UPDATE ON workouts\r\nWHEN NEW.source IS NOT OLD.source OR NEW.client_workout_id IS NOT OLD.client_workout_id\r\n OR NEW.id IS NOT OLD.id OR NEW.user_id IS NOT OLD.user_id\r\nBEGIN SELECT RAISE(ABORT,'workout_authority_immutable'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workouts_completion_immutable BEFORE UPDATE ON workouts\r\nWHEN OLD.completed_at IS NOT NULL AND (NEW.completed_at IS NOT OLD.completed_at OR NEW.mode IS NOT OLD.mode\r\n OR NEW.goal IS NOT OLD.goal OR NEW.started_at IS NOT OLD.started_at OR NEW.value IS NOT OLD.value OR NEW.active IS NOT OLD.active)\r\nBEGIN SELECT RAISE(ABORT,'workout_completion_immutable'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER cd_no_update BEFORE UPDATE ON competitive_decisions\r\nBEGIN SELECT RAISE(ABORT,'append_only'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER cd_no_delete BEFORE DELETE ON competitive_decisions\r\nWHEN EXISTS(SELECT 1 FROM workouts WHERE id=OLD.workout_id)\r\nBEGIN SELECT RAISE(ABORT,'append_only'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER cd_insert_guard BEFORE INSERT ON competitive_decisions\r\nWHEN NOT EXISTS(SELECT 1 FROM workouts WHERE id=NEW.workout_id AND completed_at IS NOT NULL)\r\n OR NEW.seq != COALESCE((SELECT MAX(seq)+1 FROM competitive_decisions WHERE workout_id=NEW.workout_id),1)\r\n OR EXISTS(SELECT 1 FROM competitive_decisions WHERE workout_id=NEW.workout_id AND status='not_eligible')\r\n OR (EXISTS(SELECT 1 FROM workouts WHERE id=NEW.workout_id AND source='guest_import') AND NEW.status!='not_eligible')\r\nBEGIN SELECT RAISE(ABORT,'invalid_competitive_decision'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER w_status_guard BEFORE UPDATE OF competitive_status ON workouts\r\nWHEN NEW.competitive_status IS NOT (SELECT status FROM competitive_decisions WHERE workout_id=NEW.id ORDER BY seq DESC LIMIT 1)\r\nBEGIN SELECT RAISE(ABORT,'competitive_cache_guard'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER cd_sync AFTER INSERT ON competitive_decisions\r\nBEGIN UPDATE workouts SET competitive_status=NEW.status WHERE id=NEW.workout_id; END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_server_completed_insert AFTER INSERT ON workouts\r\nWHEN NEW.source='server' AND NEW.completed_at IS NOT NULL\r\nBEGIN INSERT INTO competitive_decisions(workout_id,seq,status,reason,created_at) VALUES(NEW.id,1,'pending','server_completion',NEW.completed_at); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_server_completed_update AFTER UPDATE OF completed_at ON workouts\r\nWHEN OLD.completed_at IS NULL AND NEW.completed_at IS NOT NULL AND NEW.source='server'\r\nBEGIN INSERT INTO competitive_decisions(workout_id,seq,status,reason,created_at) VALUES(NEW.id,1,'pending','server_completion',NEW.completed_at); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_guest_completed_insert AFTER INSERT ON workouts\r\nWHEN NEW.source='guest_import'\r\nBEGIN INSERT INTO competitive_decisions(workout_id,seq,status,reason,created_at) VALUES(NEW.id,1,'not_eligible','guest_import',NEW.completed_at); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_imports_insert_guard BEFORE INSERT ON workout_imports\r\nWHEN NOT EXISTS(SELECT 1 FROM workouts WHERE id=NEW.workout_id AND source='guest_import' AND completed_at IS NOT NULL)\r\n OR EXISTS(SELECT 1 FROM workout_imports WHERE workout_id=NEW.workout_id)\r\n OR NEW.account_data_epoch IS NOT COALESCE((SELECT e.epoch FROM account_data_epochs e JOIN workouts w ON w.user_id=e.owner_id WHERE w.id=NEW.workout_id),1)\r\nBEGIN SELECT RAISE(ABORT,'invalid_workout_import'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_imports_no_update BEFORE UPDATE ON workout_imports\r\nBEGIN SELECT RAISE(ABORT,'immutable_import'); END;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workout_imports_no_delete BEFORE DELETE ON workout_imports\r\nWHEN EXISTS(SELECT 1 FROM workouts WHERE id=OLD.workout_id)\r\nBEGIN SELECT RAISE(ABORT,'immutable_import'); END;\r\n--> statement-breakpoint\r\nINSERT INTO competitive_decisions(workout_id,seq,status,reason,created_at)\r\nSELECT w.id,1,'pending','legacy_server_completion',CASE WHEN typeof(w.completed_at)='integer' AND w.completed_at BETWEEN 0 AND 9007199254740991 THEN w.completed_at ELSE 0 END FROM workouts w\r\nWHERE w.source='server' AND w.completed_at IS NOT NULL\r\nAND NOT EXISTS(SELECT 1 FROM competitive_decisions d WHERE d.workout_id=w.id);\r\n","drizzle/0020_coach_army_data_epochs.sql":"ALTER TABLE `account_entitlements` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_completion_outbox` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_completions` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_djscratch_challenges` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_run_events` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_runs` ADD `data_epoch` integer DEFAULT 1 NOT NULL;--> statement-breakpoint\r\nALTER TABLE `coach_army_bindings` ADD `data_epoch` integer DEFAULT 1 NOT NULL;","drizzle/0021_armie_letter_deliveries.sql":"CREATE TABLE `armie_letter_deliveries` (`user_id` text NOT NULL, `day` text NOT NULL, `letter_id` text NOT NULL, `sent_at` integer NOT NULL, PRIMARY KEY(`user_id`, `day`, `letter_id`));\r\n","drizzle/0022_performance_progression.sql":"ALTER TABLE `workouts` ADD COLUMN `performance_snapshot` text;\r\n--> statement-breakpoint\r\nCREATE TRIGGER workouts_performance_immutable BEFORE UPDATE OF performance_snapshot ON workouts\r\nWHEN OLD.completed_at IS NOT NULL AND NEW.performance_snapshot IS NOT OLD.performance_snapshot\r\nBEGIN SELECT RAISE(ABORT,'workout_performance_immutable'); END;\r\n","drizzle/0025_spotify_connection.sql":"CREATE TABLE IF NOT EXISTS spotify_connections (\r\n  user_id text PRIMARY KEY NOT NULL,\r\n  spotify_user_id text NOT NULL,\r\n  display_name text,\r\n  access_token_enc text NOT NULL,\r\n  refresh_token_enc text NOT NULL,\r\n  expires_at integer NOT NULL,\r\n  scopes text NOT NULL,\r\n  data_epoch integer NOT NULL,\r\n  updated_at integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE TABLE IF NOT EXISTS spotify_oauth_states (\r\n  state_hash text PRIMARY KEY NOT NULL,\r\n  cookie_hash text NOT NULL,\r\n  user_id text NOT NULL,\r\n  verifier_enc text NOT NULL,\r\n  data_epoch integer NOT NULL,\r\n  expires_at integer NOT NULL\r\n);\r\n--> statement-breakpoint\r\nCREATE INDEX IF NOT EXISTS spotify_oauth_states_user ON spotify_oauth_states(user_id);\r\n","drizzle/0026_workout_paths.sql":"CREATE TABLE IF NOT EXISTS workout_path_choices (\r\n  user_id text PRIMARY KEY NOT NULL,\r\n  data_epoch integer NOT NULL,\r\n  paths text NOT NULL,\r\n  created_at integer NOT NULL\r\n);\r\n","drizzle/0027_coach_world.sql":"CREATE TABLE world_assertions (id TEXT PRIMARY KEY NOT NULL, ok INTEGER NOT NULL CHECK(ok=1));\r\n--> statement-breakpoint\r\nCREATE TABLE world_bases (owner TEXT PRIMARY KEY NOT NULL, epoch INTEGER NOT NULL, public_id TEXT UNIQUE NOT NULL, revision INTEGER NOT NULL, base TEXT NOT NULL, charge INTEGER NOT NULL DEFAULT 0 CHECK(charge>=0 AND charge<=10), created_at INTEGER NOT NULL);\r\n--> statement-breakpoint\r\nCREATE TABLE world_requests (owner TEXT NOT NULL, epoch INTEGER NOT NULL, id TEXT NOT NULL, hash TEXT NOT NULL, response TEXT NOT NULL, PRIMARY KEY(owner,epoch,id));\r\n--> statement-breakpoint\r\nCREATE TABLE world_sources (owner TEXT NOT NULL, epoch INTEGER NOT NULL, source_id TEXT NOT NULL, decision TEXT NOT NULL, day TEXT NOT NULL, track TEXT, PRIMARY KEY(owner,epoch,source_id));\r\n--> statement-breakpoint\r\nCREATE TABLE world_grants (owner TEXT NOT NULL, epoch INTEGER NOT NULL, day TEXT NOT NULL, track TEXT NOT NULL, PRIMARY KEY(owner,epoch,day,track));\r\n--> statement-breakpoint\r\nCREATE TABLE world_friends (a TEXT NOT NULL,b TEXT NOT NULL, location INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(a,b));\r\n--> statement-breakpoint\r\nCREATE TABLE world_friend_codes (code TEXT PRIMARY KEY NOT NULL, owner TEXT NOT NULL, epoch INTEGER NOT NULL, expires_at INTEGER NOT NULL);\r\n--> statement-breakpoint\r\nCREATE TABLE world_walks (owner TEXT PRIMARY KEY NOT NULL, epoch INTEGER NOT NULL, id TEXT NOT NULL, nonce TEXT NOT NULL, seq INTEGER NOT NULL, state TEXT NOT NULL, updated_at INTEGER NOT NULL);\r\n--> statement-breakpoint\r\nCREATE TABLE world_presence (owner TEXT PRIMARY KEY NOT NULL, epoch INTEGER NOT NULL, site_id TEXT NOT NULL, seq INTEGER NOT NULL, latitude REAL NOT NULL, longitude REAL NOT NULL, accuracy REAL NOT NULL, updated_at INTEGER NOT NULL);\r\n--> statement-breakpoint\r\nCREATE TABLE world_sectors (id TEXT PRIMARY KEY NOT NULL, site_id TEXT, kind TEXT NOT NULL DEFAULT 'hub' CHECK(kind IN ('hub','territory')), latitude REAL NOT NULL, longitude REAL NOT NULL, controller TEXT, revision INTEGER NOT NULL DEFAULT 1, generation INTEGER NOT NULL DEFAULT 1, closes_at INTEGER, pause_until INTEGER, grace_until INTEGER NOT NULL DEFAULT 0, phase TEXT NOT NULL DEFAULT 'stable', changed_at INTEGER NOT NULL, conflict_at INTEGER NOT NULL, enabled INTEGER NOT NULL DEFAULT 1);\r\n--> statement-breakpoint\r\nCREATE TABLE world_influence (id TEXT PRIMARY KEY NOT NULL, owner TEXT NOT NULL, epoch INTEGER NOT NULL, day TEXT NOT NULL, sector_id TEXT NOT NULL, faction TEXT NOT NULL, kind TEXT NOT NULL, points INTEGER NOT NULL, accepted_at INTEGER NOT NULL, effective_at INTEGER, expires_at INTEGER NOT NULL, UNIQUE(owner,epoch,day,sector_id,kind));\r\n--> statement-breakpoint\r\nCREATE INDEX world_influence_sector ON world_influence(sector_id,accepted_at,expires_at);\r\n--> statement-breakpoint\r\nCREATE TABLE world_encounters (id TEXT PRIMARY KEY NOT NULL, a TEXT NOT NULL, ae INTEGER NOT NULL, b TEXT NOT NULL, be INTEGER NOT NULL, site_id TEXT NOT NULL, anchor TEXT NOT NULL, sector_id TEXT NOT NULL, generation INTEGER NOT NULL, status TEXT NOT NULL, revision INTEGER NOT NULL, a_reserved INTEGER NOT NULL, b_reserved INTEGER NOT NULL, expires_at INTEGER NOT NULL, due_at INTEGER, admitted_at INTEGER, winner TEXT, faction_a TEXT NOT NULL, faction_b TEXT NOT NULL);\r\n--> statement-breakpoint\r\nCREATE INDEX world_encounters_party ON world_encounters(a,b,status);\r\n--> statement-breakpoint\r\nCREATE TABLE world_visits (owner TEXT NOT NULL,epoch INTEGER NOT NULL,day TEXT NOT NULL,site_id TEXT NOT NULL,item_id TEXT NOT NULL,PRIMARY KEY(owner,epoch,day,site_id,item_id));\r\n\r\n--> statement-breakpoint\r\nCREATE INDEX world_sector_bounds ON world_sectors(latitude,longitude,id);\r\n\r\n--> statement-breakpoint\r\nCREATE INDEX world_sector_due ON world_sectors(closes_at,pause_until);\r\n","drizzle/0028_world_location_drops.sql":"CREATE TABLE world_drop_locations(owner TEXT NOT NULL,epoch INTEGER NOT NULL,kind TEXT NOT NULL CHECK(kind IN ('home','work','gym')),latitude REAL NOT NULL,longitude REAL NOT NULL,version TEXT NOT NULL,updated_at INTEGER NOT NULL,PRIMARY KEY(owner,epoch,kind));\r\n--> statement-breakpoint\r\nCREATE TABLE world_drop_challenges(owner TEXT NOT NULL,epoch INTEGER NOT NULL,kind TEXT NOT NULL,id TEXT NOT NULL,nonce TEXT NOT NULL,location_version TEXT NOT NULL,issued_at INTEGER NOT NULL,expires_at INTEGER NOT NULL,first_at INTEGER,first_sample INTEGER,last_sample INTEGER,seq INTEGER NOT NULL DEFAULT 0,PRIMARY KEY(owner,epoch,kind));\r\n--> statement-breakpoint\r\nCREATE TABLE world_drop_claims(owner TEXT NOT NULL,epoch INTEGER NOT NULL,id TEXT NOT NULL,kind TEXT NOT NULL,claimed_at INTEGER NOT NULL,xp REAL NOT NULL DEFAULT 0,reward TEXT NOT NULL,PRIMARY KEY(owner,epoch,id));\r\n--> statement-breakpoint\r\nCREATE INDEX world_drop_claim_cooldown ON world_drop_claims(owner,epoch,kind,claimed_at);\r\n","drizzle/meta/0000_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"889c84fc-a27b-488d-9384-b4138f9a8a5b\",\r\n  \"prevId\": \"00000000-0000-0000-0000-000000000000\",\r\n  \"tables\": {\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0001_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"7c4b3ae0-f6b2-4d4c-b074-3cc5a28f2a81\",\r\n  \"prevId\": \"889c84fc-a27b-488d-9384-b4138f9a8a5b\",\r\n  \"tables\": {\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0002_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"9bab1ce5-58cb-44cb-b884-cdc921351a09\",\r\n  \"prevId\": \"7c4b3ae0-f6b2-4d4c-b074-3cc5a28f2a81\",\r\n  \"tables\": {\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0003_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"0b745918-cb51-4786-bdbc-8e05caf060e3\",\r\n  \"prevId\": \"9bab1ce5-58cb-44cb-b884-cdc921351a09\",\r\n  \"tables\": {\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0004_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"d1d2c454-78ff-436f-bef7-b1c815eb547a\",\r\n  \"prevId\": \"0b745918-cb51-4786-bdbc-8e05caf060e3\",\r\n  \"tables\": {\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0005_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"e6a81be3-3b7e-4425-99f7-2fd41cc736a4\",\r\n  \"prevId\": \"d1d2c454-78ff-436f-bef7-b1c815eb547a\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0006_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"5a4def95-bebf-4826-ab6f-7a498b83007f\",\r\n  \"prevId\": \"e6a81be3-3b7e-4425-99f7-2fd41cc736a4\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0007_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"6d57b017-25e7-495c-8eed-4f6e6853d0ff\",\r\n  \"prevId\": \"5a4def95-bebf-4826-ab6f-7a498b83007f\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0008_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"71f0d1f2-e5b3-4367-b3ad-8e35969ac17a\",\r\n  \"prevId\": \"6d57b017-25e7-495c-8eed-4f6e6853d0ff\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0009_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"4b095e68-4966-4b8b-9b04-14b6f305c558\",\r\n  \"prevId\": \"71f0d1f2-e5b3-4367-b3ad-8e35969ac17a\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"breathing_sessions\": {\r\n      \"name\": \"breathing_sessions\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"breathing_user_started\": {\r\n          \"name\": \"breathing_user_started\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"breathing_user_completed\": {\r\n          \"name\": \"breathing_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"login_days\": {\r\n      \"name\": \"login_days\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"logged_at\": {\r\n          \"name\": \"logged_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"login_days_user_id_day_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"day\"\r\n          ],\r\n          \"name\": \"login_days_user_id_day_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0010_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"41c63ca6-f9b8-43de-b967-d7e34c593cc6\",\r\n  \"prevId\": \"4b095e68-4966-4b8b-9b04-14b6f305c558\",\r\n  \"tables\": {\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"breathing_sessions\": {\r\n      \"name\": \"breathing_sessions\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"breathing_user_started\": {\r\n          \"name\": \"breathing_user_started\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"breathing_user_completed\": {\r\n          \"name\": \"breathing_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"login_days\": {\r\n      \"name\": \"login_days\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"logged_at\": {\r\n          \"name\": \"logged_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"login_days_user_id_day_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"day\"\r\n          ],\r\n          \"name\": \"login_days_user_id_day_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_push_deliveries\": {\r\n      \"name\": \"release_push_deliveries\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\": {\r\n          \"name\": \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\",\r\n          \"tableFrom\": \"release_push_deliveries\",\r\n          \"tableTo\": \"subscriptions\",\r\n          \"columnsFrom\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"release_push_deliveries_endpoint_release_id_pk\": {\r\n          \"columns\": [\r\n            \"endpoint\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_push_deliveries_endpoint_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0018_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"84a22af4-94f5-4dd8-bdc3-e1cd2f98e51d\",\r\n  \"prevId\": \"41c63ca6-f9b8-43de-b967-d7e34c593cc6\",\r\n  \"tables\": {\r\n    \"account_data_deletions\": {\r\n      \"name\": \"account_data_deletions\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_epoch\": {\r\n          \"name\": \"deleted_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_at\": {\r\n          \"name\": \"deleted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\": {\r\n          \"name\": \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\",\r\n          \"tableFrom\": \"account_data_deletions\",\r\n          \"tableTo\": \"account_data_epochs\",\r\n          \"columnsFrom\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"onDelete\": \"no action\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"account_data_deletions_owner_id_deleted_epoch_pk\": {\r\n          \"columns\": [\r\n            \"owner_id\",\r\n            \"deleted_epoch\"\r\n          ],\r\n          \"name\": \"account_data_deletions_owner_id_deleted_epoch_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_deletions_epoch\": {\r\n          \"name\": \"account_data_deletions_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_epoch\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_epoch\\\" BETWEEN 1 AND 9007199254740990\"\r\n        },\r\n        \"account_data_deletions_time\": {\r\n          \"name\": \"account_data_deletions_time\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_at\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_data_epochs\": {\r\n      \"name\": \"account_data_epochs\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"epoch\": {\r\n          \"name\": \"epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_epochs_epoch\": {\r\n          \"name\": \"account_data_epochs_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"epoch\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"epoch\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"account_data_epochs_updated\": {\r\n          \"name\": \"account_data_epochs_updated\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"updated_at\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"updated_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_entitlements\": {\r\n      \"name\": \"account_entitlements\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_status\": {\r\n          \"name\": \"coach_army_status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'locked'\"\r\n        },\r\n        \"coach_army_completed_at\": {\r\n          \"name\": \"coach_army_completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_event_id\": {\r\n          \"name\": \"coach_army_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_pack_entitlements\": {\r\n      \"name\": \"account_pack_entitlements\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"pack_id\": {\r\n          \"name\": \"pack_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"granted_at\": {\r\n          \"name\": \"granted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_pack_entitlements_user\": {\r\n          \"name\": \"account_pack_entitlements_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"account_pack_entitlements_user_id_pack_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"pack_id\"\r\n          ],\r\n          \"name\": \"account_pack_entitlements_user_id_pack_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"breathing_sessions\": {\r\n      \"name\": \"breathing_sessions\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"breathing_user_started\": {\r\n          \"name\": \"breathing_user_started\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"breathing_user_completed\": {\r\n          \"name\": \"breathing_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completion_outbox\": {\r\n      \"name\": \"coach_army_completion_outbox\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'pending'\"\r\n        },\r\n        \"attempts\": {\r\n          \"name\": \"attempts\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"last_error\": {\r\n          \"name\": \"last_error\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"delivered_at\": {\r\n          \"name\": \"delivered_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completion_outbox_pending\": {\r\n          \"name\": \"coach_army_completion_outbox_pending\",\r\n          \"columns\": [\r\n            \"status\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completions\": {\r\n      \"name\": \"coach_army_completions\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completions_user\": {\r\n          \"name\": \"coach_army_completions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_djscratch_challenges\": {\r\n      \"name\": \"coach_army_djscratch_challenges\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"next_step\": {\r\n          \"name\": \"next_step\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_djscratch_challenges_run\": {\r\n          \"name\": \"coach_army_djscratch_challenges_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"account_id\",\r\n            \"status\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_run_events\": {\r\n      \"name\": \"coach_army_run_events\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"sequence\": {\r\n          \"name\": \"sequence\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"stage\": {\r\n          \"name\": \"stage\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"source\": {\r\n          \"name\": \"source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_run_events_run\": {\r\n          \"name\": \"coach_army_run_events_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"coach_army_run_sequence\": {\r\n          \"name\": \"coach_army_run_sequence\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_runs\": {\r\n      \"name\": \"coach_army_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completion_event_id\": {\r\n          \"name\": \"completion_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_runs_account\": {\r\n          \"name\": \"coach_army_runs_account\",\r\n          \"columns\": [\r\n            \"account_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"goals\": {\r\n      \"name\": \"goals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"title\": {\r\n          \"name\": \"title\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"note\": {\r\n          \"name\": \"note\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"''\"\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"goals_user_updated\": {\r\n          \"name\": \"goals_user_updated\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"login_days\": {\r\n      \"name\": \"login_days\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"logged_at\": {\r\n          \"name\": \"logged_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"login_days_user_id_day_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"day\"\r\n          ],\r\n          \"name\": \"login_days_user_id_day_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_push_deliveries\": {\r\n      \"name\": \"release_push_deliveries\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\": {\r\n          \"name\": \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\",\r\n          \"tableFrom\": \"release_push_deliveries\",\r\n          \"tableTo\": \"subscriptions\",\r\n          \"columnsFrom\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"release_push_deliveries_endpoint_release_id_pk\": {\r\n          \"columns\": [\r\n            \"endpoint\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_push_deliveries_endpoint_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"war_room_arsenals\": {\r\n      \"name\": \"war_room_arsenals\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"loadout\": {\r\n          \"name\": \"loadout\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"recipes\": {\r\n          \"name\": \"recipes\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'[]'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/0019_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"76552492-8c55-4843-8f66-cb2d77f687e3\",\r\n  \"prevId\": \"84a22af4-94f5-4dd8-bdc3-e1cd2f98e51d\",\r\n  \"tables\": {\r\n    \"account_data_deletions\": {\r\n      \"name\": \"account_data_deletions\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_epoch\": {\r\n          \"name\": \"deleted_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_at\": {\r\n          \"name\": \"deleted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\": {\r\n          \"name\": \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\",\r\n          \"tableFrom\": \"account_data_deletions\",\r\n          \"tableTo\": \"account_data_epochs\",\r\n          \"columnsFrom\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"onDelete\": \"no action\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"account_data_deletions_owner_id_deleted_epoch_pk\": {\r\n          \"columns\": [\r\n            \"owner_id\",\r\n            \"deleted_epoch\"\r\n          ],\r\n          \"name\": \"account_data_deletions_owner_id_deleted_epoch_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_deletions_epoch\": {\r\n          \"name\": \"account_data_deletions_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_epoch\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_epoch\\\" BETWEEN 1 AND 9007199254740990\"\r\n        },\r\n        \"account_data_deletions_time\": {\r\n          \"name\": \"account_data_deletions_time\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_at\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_data_epochs\": {\r\n      \"name\": \"account_data_epochs\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"epoch\": {\r\n          \"name\": \"epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_epochs_epoch\": {\r\n          \"name\": \"account_data_epochs_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"epoch\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"epoch\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"account_data_epochs_updated\": {\r\n          \"name\": \"account_data_epochs_updated\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"updated_at\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"updated_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_entitlements\": {\r\n      \"name\": \"account_entitlements\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_status\": {\r\n          \"name\": \"coach_army_status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'locked'\"\r\n        },\r\n        \"coach_army_completed_at\": {\r\n          \"name\": \"coach_army_completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_event_id\": {\r\n          \"name\": \"coach_army_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_pack_entitlements\": {\r\n      \"name\": \"account_pack_entitlements\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"pack_id\": {\r\n          \"name\": \"pack_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"granted_at\": {\r\n          \"name\": \"granted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_pack_entitlements_user\": {\r\n          \"name\": \"account_pack_entitlements_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"account_pack_entitlements_user_id_pack_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"pack_id\"\r\n          ],\r\n          \"name\": \"account_pack_entitlements_user_id_pack_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"breathing_sessions\": {\r\n      \"name\": \"breathing_sessions\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"breathing_user_started\": {\r\n          \"name\": \"breathing_user_started\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"breathing_user_completed\": {\r\n          \"name\": \"breathing_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completion_outbox\": {\r\n      \"name\": \"coach_army_completion_outbox\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'pending'\"\r\n        },\r\n        \"attempts\": {\r\n          \"name\": \"attempts\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"last_error\": {\r\n          \"name\": \"last_error\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"delivered_at\": {\r\n          \"name\": \"delivered_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completion_outbox_pending\": {\r\n          \"name\": \"coach_army_completion_outbox_pending\",\r\n          \"columns\": [\r\n            \"status\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completions\": {\r\n      \"name\": \"coach_army_completions\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completions_user\": {\r\n          \"name\": \"coach_army_completions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_djscratch_challenges\": {\r\n      \"name\": \"coach_army_djscratch_challenges\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"next_step\": {\r\n          \"name\": \"next_step\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_djscratch_challenges_run\": {\r\n          \"name\": \"coach_army_djscratch_challenges_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"account_id\",\r\n            \"status\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_run_events\": {\r\n      \"name\": \"coach_army_run_events\",\r\n      \"columns\": {\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"sequence\": {\r\n          \"name\": \"sequence\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"stage\": {\r\n          \"name\": \"stage\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"source\": {\r\n          \"name\": \"source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_run_events_run\": {\r\n          \"name\": \"coach_army_run_events_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"coach_army_run_sequence\": {\r\n          \"name\": \"coach_army_run_sequence\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_runs\": {\r\n      \"name\": \"coach_army_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completion_event_id\": {\r\n          \"name\": \"completion_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_runs_account\": {\r\n          \"name\": \"coach_army_runs_account\",\r\n          \"columns\": [\r\n            \"account_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"competitive_decisions\": {\r\n      \"name\": \"competitive_decisions\",\r\n      \"columns\": {\r\n        \"workout_id\": {\r\n          \"name\": \"workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"seq\": {\r\n          \"name\": \"seq\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"reason\": {\r\n          \"name\": \"reason\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"competitive_decisions_workout_id_workouts_id_fk\": {\r\n          \"name\": \"competitive_decisions_workout_id_workouts_id_fk\",\r\n          \"tableFrom\": \"competitive_decisions\",\r\n          \"tableTo\": \"workouts\",\r\n          \"columnsFrom\": [\r\n            \"workout_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"id\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"competitive_decisions_workout_id_seq_pk\": {\r\n          \"columns\": [\r\n            \"workout_id\",\r\n            \"seq\"\r\n          ],\r\n          \"name\": \"competitive_decisions_workout_id_seq_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"competitive_decisions_seq\": {\r\n          \"name\": \"competitive_decisions_seq\",\r\n          \"value\": \"typeof(\\\"competitive_decisions\\\".\\\"seq\\\")='integer' AND \\\"competitive_decisions\\\".\\\"seq\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"competitive_decisions_status\": {\r\n          \"name\": \"competitive_decisions_status\",\r\n          \"value\": \"\\\"competitive_decisions\\\".\\\"status\\\" IN ('accepted','pending','not_eligible')\"\r\n        },\r\n        \"competitive_decisions_reason\": {\r\n          \"name\": \"competitive_decisions_reason\",\r\n          \"value\": \"length(\\\"competitive_decisions\\\".\\\"reason\\\") BETWEEN 1 AND 128\"\r\n        },\r\n        \"competitive_decisions_created\": {\r\n          \"name\": \"competitive_decisions_created\",\r\n          \"value\": \"typeof(\\\"competitive_decisions\\\".\\\"created_at\\\")='integer' AND \\\"competitive_decisions\\\".\\\"created_at\\\" BETWEEN 0 AND 9007199254740991\"\r\n        }\r\n      }\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"goals\": {\r\n      \"name\": \"goals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"title\": {\r\n          \"name\": \"title\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"note\": {\r\n          \"name\": \"note\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"''\"\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"goals_user_updated\": {\r\n          \"name\": \"goals_user_updated\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"login_days\": {\r\n      \"name\": \"login_days\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"logged_at\": {\r\n          \"name\": \"logged_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"login_days_user_id_day_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"day\"\r\n          ],\r\n          \"name\": \"login_days_user_id_day_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_push_deliveries\": {\r\n      \"name\": \"release_push_deliveries\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\": {\r\n          \"name\": \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\",\r\n          \"tableFrom\": \"release_push_deliveries\",\r\n          \"tableTo\": \"subscriptions\",\r\n          \"columnsFrom\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"release_push_deliveries_endpoint_release_id_pk\": {\r\n          \"columns\": [\r\n            \"endpoint\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_push_deliveries_endpoint_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"war_room_arsenals\": {\r\n      \"name\": \"war_room_arsenals\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"loadout\": {\r\n          \"name\": \"loadout\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"recipes\": {\r\n          \"name\": \"recipes\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'[]'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workout_imports\": {\r\n      \"name\": \"workout_imports\",\r\n      \"columns\": {\r\n        \"workout_id\": {\r\n          \"name\": \"workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"idempotency_key\": {\r\n          \"name\": \"idempotency_key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fingerprint\": {\r\n          \"name\": \"fingerprint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"digest_version\": {\r\n          \"name\": \"digest_version\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_data_epoch\": {\r\n          \"name\": \"account_data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"workout_imports_workout_id_workouts_id_fk\": {\r\n          \"name\": \"workout_imports_workout_id_workouts_id_fk\",\r\n          \"tableFrom\": \"workout_imports\",\r\n          \"tableTo\": \"workouts\",\r\n          \"columnsFrom\": [\r\n            \"workout_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"id\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"workout_imports_key\": {\r\n          \"name\": \"workout_imports_key\",\r\n          \"value\": \"length(\\\"workout_imports\\\".\\\"idempotency_key\\\")=64 AND \\\"workout_imports\\\".\\\"idempotency_key\\\" NOT GLOB '*[^0-9a-f]*'\"\r\n        },\r\n        \"workout_imports_fingerprint\": {\r\n          \"name\": \"workout_imports_fingerprint\",\r\n          \"value\": \"length(\\\"workout_imports\\\".\\\"fingerprint\\\")=64 AND \\\"workout_imports\\\".\\\"fingerprint\\\" NOT GLOB '*[^0-9a-f]*'\"\r\n        },\r\n        \"workout_imports_version\": {\r\n          \"name\": \"workout_imports_version\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"digest_version\\\")='integer' AND \\\"workout_imports\\\".\\\"digest_version\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"workout_imports_epoch\": {\r\n          \"name\": \"workout_imports_epoch\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"account_data_epoch\\\")='integer' AND \\\"workout_imports\\\".\\\"account_data_epoch\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"workout_imports_created\": {\r\n          \"name\": \"workout_imports_created\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"created_at\\\")='integer' AND \\\"workout_imports\\\".\\\"created_at\\\" BETWEEN 0 AND 9007199254740991\"\r\n        }\r\n      }\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"source\": {\r\n          \"name\": \"source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'server'\"\r\n        },\r\n        \"client_workout_id\": {\r\n          \"name\": \"client_workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"competitive_status\": {\r\n          \"name\": \"competitive_status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"ux_workouts_acct_cwid\": {\r\n          \"name\": \"ux_workouts_acct_cwid\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"client_workout_id\"\r\n          ],\r\n          \"isUnique\": true,\r\n          \"where\": \"\\\"workouts\\\".\\\"client_workout_id\\\" IS NOT NULL\"\r\n        },\r\n        \"ix_workouts_authority\": {\r\n          \"name\": \"ix_workouts_authority\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"source\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"ix_workouts_rank\": {\r\n          \"name\": \"ix_workouts_rank\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"competitive_status\",\r\n            \"mode\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"workouts_source\": {\r\n          \"name\": \"workouts_source\",\r\n          \"value\": \"\\\"workouts\\\".\\\"source\\\" IN ('server','guest_import')\"\r\n        },\r\n        \"workouts_competitive_status\": {\r\n          \"name\": \"workouts_competitive_status\",\r\n          \"value\": \"\\\"workouts\\\".\\\"competitive_status\\\" IS NULL OR \\\"workouts\\\".\\\"competitive_status\\\" IN ('accepted','pending','not_eligible')\"\r\n        }\r\n      }\r\n    },\r\n    \"coach_army_bindings\": {\r\n      \"name\": \"coach_army_bindings\",\r\n      \"columns\": {\r\n        \"binding_id\": {\r\n          \"name\": \"binding_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"claim_hash\": {\r\n          \"name\": \"claim_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"claimed_at\": {\r\n          \"name\": \"claimed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_bindings_event_id_unique\": {\r\n          \"name\": \"coach_army_bindings_event_id_unique\",\r\n          \"columns\": [\r\n            \"event_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"coach_army_bindings_claim_hash_unique\": {\r\n          \"name\": \"coach_army_bindings_claim_hash_unique\",\r\n          \"columns\": [\r\n            \"claim_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"coach_army_bindings_account\": {\r\n          \"name\": \"coach_army_bindings_account\",\r\n          \"columns\": [\r\n            \"account_id\",\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}\r\n","drizzle/meta/0020_snapshot.json":"{\r\n  \"version\": \"6\",\r\n  \"dialect\": \"sqlite\",\r\n  \"id\": \"1afb8f4f-5343-403d-80d0-0ee85f492116\",\r\n  \"prevId\": \"76552492-8c55-4843-8f66-cb2d77f687e3\",\r\n  \"tables\": {\r\n    \"account_data_deletions\": {\r\n      \"name\": \"account_data_deletions\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_epoch\": {\r\n          \"name\": \"deleted_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"deleted_at\": {\r\n          \"name\": \"deleted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\": {\r\n          \"name\": \"account_data_deletions_owner_id_account_data_epochs_owner_id_fk\",\r\n          \"tableFrom\": \"account_data_deletions\",\r\n          \"tableTo\": \"account_data_epochs\",\r\n          \"columnsFrom\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"onDelete\": \"no action\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"account_data_deletions_owner_id_deleted_epoch_pk\": {\r\n          \"columns\": [\r\n            \"owner_id\",\r\n            \"deleted_epoch\"\r\n          ],\r\n          \"name\": \"account_data_deletions_owner_id_deleted_epoch_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_deletions_epoch\": {\r\n          \"name\": \"account_data_deletions_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_epoch\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_epoch\\\" BETWEEN 1 AND 9007199254740990\"\r\n        },\r\n        \"account_data_deletions_time\": {\r\n          \"name\": \"account_data_deletions_time\",\r\n          \"value\": \"typeof(\\\"account_data_deletions\\\".\\\"deleted_at\\\") = 'integer' AND \\\"account_data_deletions\\\".\\\"deleted_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_data_epochs\": {\r\n      \"name\": \"account_data_epochs\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"epoch\": {\r\n          \"name\": \"epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"account_data_epochs_epoch\": {\r\n          \"name\": \"account_data_epochs_epoch\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"epoch\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"epoch\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"account_data_epochs_updated\": {\r\n          \"name\": \"account_data_epochs_updated\",\r\n          \"value\": \"typeof(\\\"account_data_epochs\\\".\\\"updated_at\\\") = 'integer' AND \\\"account_data_epochs\\\".\\\"updated_at\\\" >= 0\"\r\n        }\r\n      }\r\n    },\r\n    \"account_entitlements\": {\r\n      \"name\": \"account_entitlements\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_status\": {\r\n          \"name\": \"coach_army_status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'locked'\"\r\n        },\r\n        \"coach_army_completed_at\": {\r\n          \"name\": \"coach_army_completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"coach_army_event_id\": {\r\n          \"name\": \"coach_army_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_identities\": {\r\n      \"name\": \"account_identities\",\r\n      \"columns\": {\r\n        \"clerk_id\": {\r\n          \"name\": \"clerk_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_identities_owner_id_unique\": {\r\n          \"name\": \"account_identities_owner_id_unique\",\r\n          \"columns\": [\r\n            \"owner_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"account_pack_entitlements\": {\r\n      \"name\": \"account_pack_entitlements\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"pack_id\": {\r\n          \"name\": \"pack_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"granted_at\": {\r\n          \"name\": \"granted_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"account_pack_entitlements_user\": {\r\n          \"name\": \"account_pack_entitlements_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"account_pack_entitlements_user_id_pack_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"pack_id\"\r\n          ],\r\n          \"name\": \"account_pack_entitlements_user_id_pack_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"breathing_sessions\": {\r\n      \"name\": \"breathing_sessions\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"breathing_user_started\": {\r\n          \"name\": \"breathing_user_started\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"breathing_user_completed\": {\r\n          \"name\": \"breathing_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_bindings\": {\r\n      \"name\": \"coach_army_bindings\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"binding_id\": {\r\n          \"name\": \"binding_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"claim_hash\": {\r\n          \"name\": \"claim_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"claimed_at\": {\r\n          \"name\": \"claimed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_bindings_event_id_unique\": {\r\n          \"name\": \"coach_army_bindings_event_id_unique\",\r\n          \"columns\": [\r\n            \"event_id\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"coach_army_bindings_claim_hash_unique\": {\r\n          \"name\": \"coach_army_bindings_claim_hash_unique\",\r\n          \"columns\": [\r\n            \"claim_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"coach_army_bindings_account\": {\r\n          \"name\": \"coach_army_bindings_account\",\r\n          \"columns\": [\r\n            \"account_id\",\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completion_outbox\": {\r\n      \"name\": \"coach_army_completion_outbox\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'pending'\"\r\n        },\r\n        \"attempts\": {\r\n          \"name\": \"attempts\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"last_error\": {\r\n          \"name\": \"last_error\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"delivered_at\": {\r\n          \"name\": \"delivered_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completion_outbox_pending\": {\r\n          \"name\": \"coach_army_completion_outbox_pending\",\r\n          \"columns\": [\r\n            \"status\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_completions\": {\r\n      \"name\": \"coach_army_completions\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_completions_user\": {\r\n          \"name\": \"coach_army_completions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_djscratch_challenges\": {\r\n      \"name\": \"coach_army_djscratch_challenges\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"next_step\": {\r\n          \"name\": \"next_step\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_djscratch_challenges_run\": {\r\n          \"name\": \"coach_army_djscratch_challenges_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"account_id\",\r\n            \"status\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_run_events\": {\r\n      \"name\": \"coach_army_run_events\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"event_id\": {\r\n          \"name\": \"event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"run_id\": {\r\n          \"name\": \"run_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"sequence\": {\r\n          \"name\": \"sequence\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"stage\": {\r\n          \"name\": \"stage\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"source\": {\r\n          \"name\": \"source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"received_at\": {\r\n          \"name\": \"received_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_run_events_run\": {\r\n          \"name\": \"coach_army_run_events_run\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"coach_army_run_sequence\": {\r\n          \"name\": \"coach_army_run_sequence\",\r\n          \"columns\": [\r\n            \"run_id\",\r\n            \"sequence\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"coach_army_runs\": {\r\n      \"name\": \"coach_army_runs\",\r\n      \"columns\": {\r\n        \"data_epoch\": {\r\n          \"name\": \"data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_id\": {\r\n          \"name\": \"account_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completion_event_id\": {\r\n          \"name\": \"completion_event_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"coach_army_runs_account\": {\r\n          \"name\": \"coach_army_runs_account\",\r\n          \"columns\": [\r\n            \"account_id\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"competitive_decisions\": {\r\n      \"name\": \"competitive_decisions\",\r\n      \"columns\": {\r\n        \"workout_id\": {\r\n          \"name\": \"workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"seq\": {\r\n          \"name\": \"seq\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"reason\": {\r\n          \"name\": \"reason\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"competitive_decisions_workout_id_workouts_id_fk\": {\r\n          \"name\": \"competitive_decisions_workout_id_workouts_id_fk\",\r\n          \"tableFrom\": \"competitive_decisions\",\r\n          \"tableTo\": \"workouts\",\r\n          \"columnsFrom\": [\r\n            \"workout_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"id\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"competitive_decisions_workout_id_seq_pk\": {\r\n          \"columns\": [\r\n            \"workout_id\",\r\n            \"seq\"\r\n          ],\r\n          \"name\": \"competitive_decisions_workout_id_seq_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"competitive_decisions_seq\": {\r\n          \"name\": \"competitive_decisions_seq\",\r\n          \"value\": \"typeof(\\\"competitive_decisions\\\".\\\"seq\\\")='integer' AND \\\"competitive_decisions\\\".\\\"seq\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"competitive_decisions_status\": {\r\n          \"name\": \"competitive_decisions_status\",\r\n          \"value\": \"\\\"competitive_decisions\\\".\\\"status\\\" IN ('accepted','pending','not_eligible')\"\r\n        },\r\n        \"competitive_decisions_reason\": {\r\n          \"name\": \"competitive_decisions_reason\",\r\n          \"value\": \"length(\\\"competitive_decisions\\\".\\\"reason\\\") BETWEEN 1 AND 128\"\r\n        },\r\n        \"competitive_decisions_created\": {\r\n          \"name\": \"competitive_decisions_created\",\r\n          \"value\": \"typeof(\\\"competitive_decisions\\\".\\\"created_at\\\")='integer' AND \\\"competitive_decisions\\\".\\\"created_at\\\" BETWEEN 0 AND 9007199254740991\"\r\n        }\r\n      }\r\n    },\r\n    \"deliveries\": {\r\n      \"name\": \"deliveries\",\r\n      \"columns\": {\r\n        \"reminder_id\": {\r\n          \"name\": \"reminder_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"deliveries_reminder_id_day_endpoint_pk\": {\r\n          \"columns\": [\r\n            \"reminder_id\",\r\n            \"day\",\r\n            \"endpoint\"\r\n          ],\r\n          \"name\": \"deliveries_reminder_id_day_endpoint_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"gala_runs\": {\r\n      \"name\": \"gala_runs\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_name\": {\r\n          \"name\": \"dj_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"moniker\": {\r\n          \"name\": \"moniker\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"dj_at\": {\r\n          \"name\": \"dj_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"gala_at\": {\r\n          \"name\": \"gala_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"lil_at\": {\r\n          \"name\": \"lil_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"corgi_at\": {\r\n          \"name\": \"corgi_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"hand_at\": {\r\n          \"name\": \"hand_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"armie_at\": {\r\n          \"name\": \"armie_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"duration_ms\": {\r\n          \"name\": \"duration_ms\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"installed_at\": {\r\n          \"name\": \"installed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"joined_at\": {\r\n          \"name\": \"joined_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"public_name\": {\r\n          \"name\": \"public_name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"gala_runs_public_name_unique\": {\r\n          \"name\": \"gala_runs_public_name_unique\",\r\n          \"columns\": [\r\n            \"public_name\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"gala_runs_creator_started\": {\r\n          \"name\": \"gala_runs_creator_started\",\r\n          \"columns\": [\r\n            \"creator\",\r\n            \"started_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"gala_runs_leaderboard\": {\r\n          \"name\": \"gala_runs_leaderboard\",\r\n          \"columns\": [\r\n            \"joined_at\",\r\n            \"duration_ms\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"goals\": {\r\n      \"name\": \"goals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"title\": {\r\n          \"name\": \"title\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"note\": {\r\n          \"name\": \"note\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"''\"\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'active'\"\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"goals_user_updated\": {\r\n          \"name\": \"goals_user_updated\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"updated_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"install_drafts\": {\r\n      \"name\": \"install_drafts\",\r\n      \"columns\": {\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"creator\": {\r\n          \"name\": \"creator\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"install_drafts_expiry\": {\r\n          \"name\": \"install_drafts_expiry\",\r\n          \"columns\": [\r\n            \"expires_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"install_drafts_creator\": {\r\n          \"name\": \"install_drafts_creator\",\r\n          \"columns\": [\r\n            \"creator\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"login_days\": {\r\n      \"name\": \"login_days\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"day\": {\r\n          \"name\": \"day\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"logged_at\": {\r\n          \"name\": \"logged_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"login_days_user_id_day_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"day\"\r\n          ],\r\n          \"name\": \"login_days_user_id_day_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"meals\": {\r\n      \"name\": \"meals\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"name\": {\r\n          \"name\": \"name\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"portion\": {\r\n          \"name\": \"portion\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"calories\": {\r\n          \"name\": \"calories\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"protein\": {\r\n          \"name\": \"protein\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"carbs\": {\r\n          \"name\": \"carbs\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fat\": {\r\n          \"name\": \"fat\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"micros\": {\r\n          \"name\": \"micros\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"nutrition_source\": {\r\n          \"name\": \"nutrition_source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"eaten_at\": {\r\n          \"name\": \"eaten_at\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"meals_user_date\": {\r\n          \"name\": \"meals_user_date\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"eaten_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"onboarding\": {\r\n      \"name\": \"onboarding\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"start_day\": {\r\n          \"name\": \"start_day\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"write_token\": {\r\n          \"name\": \"write_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"profiles\": {\r\n      \"name\": \"profiles\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'{}'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_deliveries\": {\r\n      \"name\": \"release_deliveries\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {\r\n        \"release_deliveries_user_id_release_id_pk\": {\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_deliveries_user_id_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_push_deliveries\": {\r\n      \"name\": \"release_push_deliveries\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"release_id\": {\r\n          \"name\": \"release_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"status\": {\r\n          \"name\": \"status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\": {\r\n          \"name\": \"release_push_deliveries_endpoint_subscriptions_endpoint_fk\",\r\n          \"tableFrom\": \"release_push_deliveries\",\r\n          \"tableTo\": \"subscriptions\",\r\n          \"columnsFrom\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"endpoint\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {\r\n        \"release_push_deliveries_endpoint_release_id_pk\": {\r\n          \"columns\": [\r\n            \"endpoint\",\r\n            \"release_id\"\r\n          ],\r\n          \"name\": \"release_push_deliveries_endpoint_release_id_pk\"\r\n        }\r\n      },\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"release_subscribers\": {\r\n      \"name\": \"release_subscribers\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"email\": {\r\n          \"name\": \"email\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"confirm_hash\": {\r\n          \"name\": \"confirm_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"unsubscribe_token\": {\r\n          \"name\": \"unsubscribe_token\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"confirmed_at\": {\r\n          \"name\": \"confirmed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"last_release\": {\r\n          \"name\": \"last_release\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"release_subscribers_unsubscribe_token_unique\": {\r\n          \"name\": \"release_subscribers_unsubscribe_token_unique\",\r\n          \"columns\": [\r\n            \"unsubscribe_token\"\r\n          ],\r\n          \"isUnique\": true\r\n        },\r\n        \"release_subscribers_confirmation\": {\r\n          \"name\": \"release_subscribers_confirmation\",\r\n          \"columns\": [\r\n            \"confirm_hash\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"reminders\": {\r\n      \"name\": \"reminders\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"kind\": {\r\n          \"name\": \"kind\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"time\": {\r\n          \"name\": \"time\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"timezone\": {\r\n          \"name\": \"timezone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"enabled\": {\r\n          \"name\": \"enabled\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 1\r\n        },\r\n        \"quiet_start\": {\r\n          \"name\": \"quiet_start\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'22:00'\"\r\n        },\r\n        \"quiet_end\": {\r\n          \"name\": \"quiet_end\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'07:00'\"\r\n        },\r\n        \"tone\": {\r\n          \"name\": \"tone\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'direct'\"\r\n        },\r\n        \"days_per_week\": {\r\n          \"name\": \"days_per_week\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 7\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"reminders_user\": {\r\n          \"name\": \"reminders_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_invites\": {\r\n      \"name\": \"scoreboard_invites\",\r\n      \"columns\": {\r\n        \"owner_id\": {\r\n          \"name\": \"owner_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"token_hash\": {\r\n          \"name\": \"token_hash\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"expires_at\": {\r\n          \"name\": \"expires_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_invites_token_hash_unique\": {\r\n          \"name\": \"scoreboard_invites_token_hash_unique\",\r\n          \"columns\": [\r\n            \"token_hash\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"scoreboard_links\": {\r\n      \"name\": \"scoreboard_links\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_a\": {\r\n          \"name\": \"user_a\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_b\": {\r\n          \"name\": \"user_b\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"scoreboard_links_a\": {\r\n          \"name\": \"scoreboard_links_a\",\r\n          \"columns\": [\r\n            \"user_a\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_b\": {\r\n          \"name\": \"scoreboard_links_b\",\r\n          \"columns\": [\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"scoreboard_links_pair\": {\r\n          \"name\": \"scoreboard_links_pair\",\r\n          \"columns\": [\r\n            \"user_a\",\r\n            \"user_b\"\r\n          ],\r\n          \"isUnique\": true\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"subscriptions\": {\r\n      \"name\": \"subscriptions\",\r\n      \"columns\": {\r\n        \"endpoint\": {\r\n          \"name\": \"endpoint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"data\": {\r\n          \"name\": \"data\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"subscriptions_user\": {\r\n          \"name\": \"subscriptions_user\",\r\n          \"columns\": [\r\n            \"user_id\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"system\": {\r\n      \"name\": \"system\",\r\n      \"columns\": {\r\n        \"key\": {\r\n          \"name\": \"key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"war_room_arsenals\": {\r\n      \"name\": \"war_room_arsenals\",\r\n      \"columns\": {\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"loadout\": {\r\n          \"name\": \"loadout\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"recipes\": {\r\n          \"name\": \"recipes\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'[]'\"\r\n        },\r\n        \"revision\": {\r\n          \"name\": \"revision\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": 0\r\n        },\r\n        \"updated_at\": {\r\n          \"name\": \"updated_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {}\r\n    },\r\n    \"workout_imports\": {\r\n      \"name\": \"workout_imports\",\r\n      \"columns\": {\r\n        \"workout_id\": {\r\n          \"name\": \"workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"idempotency_key\": {\r\n          \"name\": \"idempotency_key\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"fingerprint\": {\r\n          \"name\": \"fingerprint\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"digest_version\": {\r\n          \"name\": \"digest_version\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"account_data_epoch\": {\r\n          \"name\": \"account_data_epoch\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"created_at\": {\r\n          \"name\": \"created_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {},\r\n      \"foreignKeys\": {\r\n        \"workout_imports_workout_id_workouts_id_fk\": {\r\n          \"name\": \"workout_imports_workout_id_workouts_id_fk\",\r\n          \"tableFrom\": \"workout_imports\",\r\n          \"tableTo\": \"workouts\",\r\n          \"columnsFrom\": [\r\n            \"workout_id\"\r\n          ],\r\n          \"columnsTo\": [\r\n            \"id\"\r\n          ],\r\n          \"onDelete\": \"cascade\",\r\n          \"onUpdate\": \"no action\"\r\n        }\r\n      },\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"workout_imports_key\": {\r\n          \"name\": \"workout_imports_key\",\r\n          \"value\": \"length(\\\"workout_imports\\\".\\\"idempotency_key\\\")=64 AND \\\"workout_imports\\\".\\\"idempotency_key\\\" NOT GLOB '*[^0-9a-f]*'\"\r\n        },\r\n        \"workout_imports_fingerprint\": {\r\n          \"name\": \"workout_imports_fingerprint\",\r\n          \"value\": \"length(\\\"workout_imports\\\".\\\"fingerprint\\\")=64 AND \\\"workout_imports\\\".\\\"fingerprint\\\" NOT GLOB '*[^0-9a-f]*'\"\r\n        },\r\n        \"workout_imports_version\": {\r\n          \"name\": \"workout_imports_version\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"digest_version\\\")='integer' AND \\\"workout_imports\\\".\\\"digest_version\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"workout_imports_epoch\": {\r\n          \"name\": \"workout_imports_epoch\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"account_data_epoch\\\")='integer' AND \\\"workout_imports\\\".\\\"account_data_epoch\\\" BETWEEN 1 AND 9007199254740991\"\r\n        },\r\n        \"workout_imports_created\": {\r\n          \"name\": \"workout_imports_created\",\r\n          \"value\": \"typeof(\\\"workout_imports\\\".\\\"created_at\\\")='integer' AND \\\"workout_imports\\\".\\\"created_at\\\" BETWEEN 0 AND 9007199254740991\"\r\n        }\r\n      }\r\n    },\r\n    \"workouts\": {\r\n      \"name\": \"workouts\",\r\n      \"columns\": {\r\n        \"id\": {\r\n          \"name\": \"id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": true,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"user_id\": {\r\n          \"name\": \"user_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"mode\": {\r\n          \"name\": \"mode\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"goal\": {\r\n          \"name\": \"goal\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"started_at\": {\r\n          \"name\": \"started_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false\r\n        },\r\n        \"completed_at\": {\r\n          \"name\": \"completed_at\",\r\n          \"type\": \"integer\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"value\": {\r\n          \"name\": \"value\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"active\": {\r\n          \"name\": \"active\",\r\n          \"type\": \"real\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"source\": {\r\n          \"name\": \"source\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": true,\r\n          \"autoincrement\": false,\r\n          \"default\": \"'server'\"\r\n        },\r\n        \"client_workout_id\": {\r\n          \"name\": \"client_workout_id\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        },\r\n        \"competitive_status\": {\r\n          \"name\": \"competitive_status\",\r\n          \"type\": \"text\",\r\n          \"primaryKey\": false,\r\n          \"notNull\": false,\r\n          \"autoincrement\": false\r\n        }\r\n      },\r\n      \"indexes\": {\r\n        \"workouts_user_completed\": {\r\n          \"name\": \"workouts_user_completed\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"ux_workouts_acct_cwid\": {\r\n          \"name\": \"ux_workouts_acct_cwid\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"client_workout_id\"\r\n          ],\r\n          \"isUnique\": true,\r\n          \"where\": \"\\\"workouts\\\".\\\"client_workout_id\\\" IS NOT NULL\"\r\n        },\r\n        \"ix_workouts_authority\": {\r\n          \"name\": \"ix_workouts_authority\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"source\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        },\r\n        \"ix_workouts_rank\": {\r\n          \"name\": \"ix_workouts_rank\",\r\n          \"columns\": [\r\n            \"user_id\",\r\n            \"competitive_status\",\r\n            \"mode\",\r\n            \"completed_at\"\r\n          ],\r\n          \"isUnique\": false\r\n        }\r\n      },\r\n      \"foreignKeys\": {},\r\n      \"compositePrimaryKeys\": {},\r\n      \"uniqueConstraints\": {},\r\n      \"checkConstraints\": {\r\n        \"workouts_source\": {\r\n          \"name\": \"workouts_source\",\r\n          \"value\": \"\\\"workouts\\\".\\\"source\\\" IN ('server','guest_import')\"\r\n        },\r\n        \"workouts_competitive_status\": {\r\n          \"name\": \"workouts_competitive_status\",\r\n          \"value\": \"\\\"workouts\\\".\\\"competitive_status\\\" IS NULL OR \\\"workouts\\\".\\\"competitive_status\\\" IN ('accepted','pending','not_eligible')\"\r\n        }\r\n      }\r\n    }\r\n  },\r\n  \"views\": {},\r\n  \"enums\": {},\r\n  \"_meta\": {\r\n    \"schemas\": {},\r\n    \"tables\": {},\r\n    \"columns\": {}\r\n  },\r\n  \"internal\": {\r\n    \"indexes\": {}\r\n  }\r\n}","drizzle/meta/_journal.json":"{\r\n  \"version\": \"7\",\r\n  \"dialect\": \"sqlite\",\r\n  \"entries\": [\r\n    {\r\n      \"idx\": 0,\r\n      \"version\": \"6\",\r\n      \"when\": 1788977299750,\r\n      \"tag\": \"0000_new_cammi\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 1,\r\n      \"version\": \"6\",\r\n      \"when\": 1788987027951,\r\n      \"tag\": \"0001_careful_impossible_man\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 2,\r\n      \"version\": \"6\",\r\n      \"when\": 1788988831094,\r\n      \"tag\": \"0002_peaceful_living_lightning\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 3,\r\n      \"version\": \"6\",\r\n      \"when\": 1788997926956,\r\n      \"tag\": \"0003_dashing_meltdown\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 4,\r\n      \"version\": \"6\",\r\n      \"when\": 1789000724491,\r\n      \"tag\": \"0004_burly_boomerang\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 5,\r\n      \"version\": \"6\",\r\n      \"when\": 1789004382220,\r\n      \"tag\": \"0005_nice_the_enforcers\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 6,\r\n      \"version\": \"6\",\r\n      \"when\": 1789014708507,\r\n      \"tag\": \"0006_flawless_slayback\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 7,\r\n      \"version\": \"6\",\r\n      \"when\": 1789015990548,\r\n      \"tag\": \"0007_tan_mesmero\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 8,\r\n      \"version\": \"6\",\r\n      \"when\": 1789017138908,\r\n      \"tag\": \"0008_giant_charles_xavier\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 9,\r\n      \"version\": \"6\",\r\n      \"when\": 1789026398058,\r\n      \"tag\": \"0009_uneven_rhino\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 10,\r\n      \"version\": \"6\",\r\n      \"when\": 1789057331946,\r\n      \"tag\": \"0010_fixed_wrecker\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 11,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060000000,\r\n      \"tag\": \"0011_coach_army_entitlements\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 12,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060100000,\r\n      \"tag\": \"0012_coach_army_bindings\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 13,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060200000,\r\n      \"tag\": \"0013_account_pack_entitlements\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 14,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060300000,\r\n      \"tag\": \"0014_coach_army_authenticated_runs\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 15,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060400000,\r\n      \"tag\": \"0015_goals\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 16,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060500000,\r\n      \"tag\": \"0016_war_room_arsenal\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 17,\r\n      \"version\": \"6\",\r\n      \"when\": 1789060600000,\r\n      \"tag\": \"0017_coach_army_djscratch_verifier\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 18,\r\n      \"version\": \"6\",\r\n      \"when\": 1790031159443,\r\n      \"tag\": \"0018_account_data_epochs\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 19,\r\n      \"version\": \"6\",\r\n      \"when\": 1790035909178,\r\n      \"tag\": \"0019_workout_import_trust\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 20,\r\n      \"version\": \"6\",\r\n      \"when\": 1790039380366,\r\n      \"tag\": \"0020_coach_army_data_epochs\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 21,\r\n      \"version\": \"6\",\r\n      \"when\": 1790700000000,\r\n      \"tag\": \"0021_armie_letter_deliveries\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 22,\r\n      \"version\": \"6\",\r\n      \"when\": 1790700000001,\r\n      \"tag\": \"0022_performance_progression\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 23,\r\n      \"version\": \"6\",\r\n      \"when\": 1791244800000,\r\n      \"tag\": \"0025_spotify_connection\",\r\n      \"breakpoints\": true\r\n    },\r\n    {\r\n      \"idx\": 24,\r\n      \"version\": \"6\",\r\n      \"when\": 1791244800001,\r\n      \"tag\": \"0026_workout_paths\",\r\n      \"breakpoints\": true\r\n    }\r\n  ]\r\n}\r\n","drop-pod-opening.mjs":"﻿// Drop-pod pack opening: a full-screen space drop in the style of FPS pack openings (Siege Alpha Packs, Apex).\r\n// sky -> drop -> landed (steaming in a dirt mound) -> tap the pod -> opened (lid pops, beam) -> reveal card.\r\n// Served unbundled (external in scripts/build.mjs and scripts/dev.mjs) so three.js is only fetched when a pack\r\n// is opened (same pattern as food/pyramid-scanner.mjs). pods/drop-pod-<tier>.glb drop in with no code change;\r\n// until they exist the procedural canister below is the pod.\r\nexport const PHASES=Object.freeze(['sky','drop','landed','opened','reveal']);\r\nexport const startPhase=({reduced=false}={})=>reduced?'landed':'sky';\r\nconst EDGES={sky:{fall:'drop',land:'landed'},drop:{land:'landed'},landed:{tap:'opened'},opened:{revealed:'reveal',fail:'landed'}};\r\n// Pure state machine (unit-tested in node). skip jumps straight to the reveal; restart is \"Open another\".\r\nexport function advance(phase,event){\r\n if(event==='skip')return 'reveal';\r\n if(event==='restart')return phase==='reveal'?'sky':phase;\r\n return EDGES[phase]?.[event]??phase;\r\n}\r\n// Seconds: the sky, the fall, then the impact settling before the \"Tap the pod\" prompt appears.\r\nexport const TIERS=Object.freeze({\r\n uncommon:{color:'#76e356',sky:1.0,fall:2.1,settle:1.3,shake:.34,dust:1,sparks:1,rocks:10,rumble:0},\r\n rare:{color:'#4bafff',sky:1.0,fall:2.4,settle:1.5,shake:.52,dust:1.3,sparks:1.4,rocks:14,rumble:.03},\r\n legendary:{color:'#ff9c36',sky:1.8,fall:3.0,settle:1.5,shake:.85,dust:1.8,sparks:2.4,rocks:22,rumble:.07,gold:true,big:true,aftershock:.45},\r\n // Secret (from secret achievements): the longest build-up and biggest hit, a holographic kettlebell pod and holo sparks.\r\n secret:{color:'#b388ff',sky:2.4,fall:3.4,settle:1.7,shake:1,dust:2,sparks:3,rocks:26,rumble:.1,holo:true,big:true,aftershock:.55}\r\n});\r\nexport const promptAt=tier=>{const c=TIERS[tier]||TIERS.uncommon;return c.sky+c.fall+c.settle;};\r\n\r\nconst CSS=`\r\ndialog.drop-pod:focus{outline:none}\r\ndialog.drop-pod{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;background:#02030a;color:#fff7df;font:500 16px/1.4 system-ui;overflow:hidden;touch-action:none;user-select:none;-webkit-user-select:none}\r\ndialog.drop-pod::backdrop{background:#02030a}\r\n.drop-pod canvas{position:absolute;inset:0;width:100%;height:100%;display:block}\r\n.drop-pod-flash{position:absolute;inset:0;background:radial-gradient(circle at 50% 64%,#fff 0,color-mix(in srgb,var(--pack) 65%,#fff) 14%,color-mix(in srgb,var(--pack) 50%,transparent) 34%,transparent 62%);opacity:0;pointer-events:none}\r\n.drop-pod-flash.go{animation:dp-flash .4s ease-out;--k:.9}.drop-pod-flash.pop{animation:dp-flash .3s ease-out;--k:.5}\r\n@keyframes dp-flash{0%{opacity:var(--k,1)}100%{opacity:0}}\r\n.drop-pod-caption{position:absolute;left:0;right:0;top:calc(14% + env(safe-area-inset-top,0px));text-align:center;font:900 13px system-ui;letter-spacing:.42em;text-transform:uppercase;color:var(--pack);text-shadow:0 0 14px var(--pack);opacity:0;transition:opacity .4s;pointer-events:none}\r\n.drop-pod[data-phase=sky] .drop-pod-caption,.drop-pod[data-phase=drop] .drop-pod-caption{opacity:.95;animation:dp-blink .5s steps(2) infinite}\r\n.drop-pod[data-phase=drop] .drop-pod-caption{opacity:.7}\r\n@keyframes dp-blink{50%{opacity:.35}}\r\n.drop-pod-skip{position:absolute;top:calc(12px + env(safe-area-inset-top,0px));right:12px;min-height:44px;min-width:64px;border:1px solid #fff7df80;border-radius:22px;background:#0008;color:#fff7df;font:800 13px system-ui;letter-spacing:.1em;text-transform:uppercase;padding:0 16px;cursor:pointer;z-index:3}\r\n.drop-pod[data-phase=reveal] .drop-pod-skip{display:none}\r\n.drop-pod-hit{position:absolute;left:50%;top:60%;width:200px;height:260px;transform:translate(-50%,-50%);border:0;border-radius:50%;background:transparent;cursor:pointer;display:none;z-index:2;-webkit-tap-highlight-color:transparent}\r\n.drop-pod.ready .drop-pod-hit{display:block}\r\n.drop-pod-hit::after{content:\"\";position:absolute;inset:6%;border:3px solid var(--pack);border-radius:50%;box-shadow:0 0 22px var(--pack),inset 0 0 22px color-mix(in srgb,var(--pack) 45%,transparent);animation:dp-ring 1.1s ease-in-out infinite}\r\n@keyframes dp-ring{0%,100%{transform:scale(.92);opacity:.5}50%{transform:scale(1.04);opacity:1}}\r\n.drop-pod-prompt{position:absolute;left:0;right:0;bottom:calc(6% + env(safe-area-inset-bottom,0px));text-align:center;font:900 22px system-ui;letter-spacing:.2em;text-transform:uppercase;color:#fff7df;text-shadow:0 0 18px var(--pack),0 2px 0 #000;opacity:0;pointer-events:none;transition:opacity .25s}\r\n.drop-pod.ready .drop-pod-prompt{opacity:1;animation:dp-pulse 1s ease-in-out infinite}\r\n.drop-pod-prompt small{display:block;margin-top:6px;font:700 12px system-ui;letter-spacing:.12em;color:#ffb4a8;text-shadow:none;min-height:1em}\r\n@keyframes dp-pulse{50%{transform:scale(1.06)}}\r\n.drop-pod-card{position:absolute;left:50%;top:9%;width:min(calc(100vw - 36px),340px);max-height:44%;overflow:auto;box-sizing:border-box;transform:translate(-50%,46vh) scale(.5);opacity:0;pointer-events:none;text-align:center;border:2px solid var(--pack);border-radius:20px;background:radial-gradient(circle at 50% 20%,color-mix(in srgb,var(--pack) 30%,#21152e),#100d1b 75%);box-shadow:0 0 50px color-mix(in srgb,var(--pack) 55%,transparent),0 18px 40px #000b;padding:16px 16px 18px;transition:transform .9s cubic-bezier(.2,1.25,.3,1),opacity .35s}\r\n.drop-pod[data-phase=reveal] .drop-pod-card{transform:translate(-50%,0) scale(1);opacity:1;pointer-events:auto}\r\n.drop-pod-card .eyebrow{margin:0;color:var(--pack);font:800 12px system-ui;letter-spacing:.24em;text-transform:uppercase}\r\n.drop-pod-card strong{display:block;margin-top:6px;font:900 24px/1.15 system-ui;color:#fff7df;text-shadow:0 0 18px var(--pack)}\r\n.drop-pod-card small{display:block;opacity:.85;text-transform:uppercase;letter-spacing:.12em;font-size:12px;margin-top:4px}\r\n.drop-pod-item+.drop-pod-item{margin-top:12px;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--pack) 40%,transparent)}\r\n.drop-pod-swatches{display:flex;justify-content:center;gap:6px;margin-top:10px}.drop-pod-swatches i{width:30px;height:30px;border:2px solid #fff7df;border-radius:5px}\r\n.drop-pod[data-reward-type=texture]:not([data-tier=secret]) .drop-pod-card::before{content:\"\";position:absolute;inset:-60%;z-index:-1;background:conic-gradient(from 0deg,transparent 0 10%,#ffd36a55 12%,transparent 16% 35%,#ffd36a44 37%,transparent 41% 60%,#ffd36a55 62%,transparent 66% 85%,#ffd36a44 87%,transparent 91%);animation:dp-spin 9s linear infinite}\r\n.drop-pod[data-reward-type=texture]:not([data-tier=secret]) .drop-pod-card{overflow:visible;isolation:isolate}\r\n.drop-pod[data-reward-type=texture]:not([data-tier=secret]) .drop-pod-card strong{background:linear-gradient(100deg,#fff7df 20%,#ffd36a 45%,#fff 50%,#ffd36a 55%,#fff7df 80%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:none;animation:dp-shimmer 2.6s linear infinite}\r\n@keyframes dp-spin{to{transform:rotate(1turn)}}@keyframes dp-shimmer{to{background-position:-250% 0}}\r\n.drop-pod[data-tier=secret] .drop-pod-card{border-color:transparent;background:radial-gradient(circle at 50% 20%,#3a2160,#0d0b1c 75%) padding-box,linear-gradient(120deg,#3ff5ff,#b388ff,#ff4bd8,#ffd36a,#3ff5ff) border-box;background-size:auto,300% 100%;animation:dp-iri 4s linear infinite;box-shadow:0 0 50px #b388ff88,0 0 90px #3ff5ff33,0 18px 40px #000b}\r\n.drop-pod[data-tier=secret] .drop-pod-card .eyebrow{font:900 30px/1 system-ui;letter-spacing:.32em;margin:2px 0 4px;background:linear-gradient(100deg,#3ff5ff,#b388ff 30%,#ff4bd8 55%,#ffd36a 80%,#3ff5ff);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:dp-shimmer 3s linear infinite;filter:drop-shadow(0 0 10px #b388ffaa)}\r\n.drop-pod[data-tier=secret] .drop-pod-caption{background:linear-gradient(90deg,#3ff5ff,#ff4bd8,#ffd36a,#3ff5ff);background-size:200% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;text-shadow:none;filter:drop-shadow(0 0 8px #b388ff)}\r\n@keyframes dp-iri{to{background-position:0 0,-300% 0}}\r\n.drop-pod-actions{position:absolute;left:0;right:0;bottom:calc(5% + env(safe-area-inset-bottom,0px));display:flex;gap:10px;justify-content:center;opacity:0;pointer-events:none;transition:opacity .4s .5s}\r\n.drop-pod[data-phase=reveal] .drop-pod-actions{opacity:1;pointer-events:auto}\r\n.drop-pod-actions button{min-height:48px;min-width:120px;border:2px solid var(--pack);border-radius:14px;background:var(--pack);color:#15101c;font:800 15px system-ui;padding:8px 20px;cursor:pointer}\r\n.drop-pod-actions button.secondary{background:#0009;color:#fff7df}\r\n.drop-pod button:focus-visible{outline:3px solid #fff;outline-offset:3px}.drop-pod .drop-pod-hit:focus-visible{outline:none}\r\n.drop-pod-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}\r\n@media(prefers-reduced-motion:reduce){.drop-pod-flash.go,.drop-pod-flash.pop{animation-duration:.15s}.drop-pod-card{transition:opacity .2s;transform:translate(-50%,0) scale(1)}.drop-pod[data-reward-type=texture]:not([data-tier=secret]) .drop-pod-card::before,.drop-pod[data-reward-type=texture]:not([data-tier=secret]) .drop-pod-card strong,.drop-pod[data-tier=secret] .drop-pod-card,.drop-pod[data-tier=secret] .drop-pod-card .eyebrow{animation:none}.drop-pod-hit::after,.drop-pod.ready .drop-pod-prompt{animation:none}}\r\n`;\r\n\r\nconst clamp=(v,a=0,b=1)=>Math.min(b,Math.max(a,v)),lerp=(a,b,k)=>a+(b-a)*k,smooth=k=>k*k*(3-2*k);\r\nconst easeOutBack=k=>{const c=1.9;return 1+(c+1)*Math.pow(k-1,3)+c*Math.pow(k-1,2);};\r\nconst rnd=(a=0,b=1)=>a+Math.random()*(b-a);\r\nconst hash=(x,y)=>{const s=Math.sin(x*127.1+y*311.7)*43758.5453;return s-Math.floor(s);};\r\nconst vnoise=(x,y)=>{const ix=Math.floor(x),iy=Math.floor(y),fx=smooth(x-ix),fy=smooth(y-iy);return lerp(lerp(hash(ix,iy),hash(ix+1,iy),fx),lerp(hash(ix,iy+1),hash(ix+1,iy+1),fx),fy);};\r\nconst MOUND_R=3.7;\r\n// Height of the dirt mound the pod lands in (also where thrown rocks and steam vents sit).\r\nconst moundHeight=(r,theta)=>{\r\n const s=clamp((r-.62)/(MOUND_R-.62)),base=(r<.62?1:1.05*Math.pow(1-s,1.4))+.3*Math.exp(-Math.pow((r-1.5)/.55,2));\r\n return Math.max(0,base*(.72+.5*vnoise(theta*2.2+r*1.3,r*2.1))+.1*(vnoise(theta*6,r*5)-.5)*(1-s));\r\n};\r\n\r\nconst VERT=`attribute float aSize;attribute float aAlpha;attribute vec3 aColor;uniform float uScale;varying float vA;varying vec3 vC;\r\nvoid main(){vec4 mv=modelViewMatrix*vec4(position,1.);gl_Position=projectionMatrix*mv;gl_PointSize=max(.0,aSize*uScale/max(.1,-mv.z));vA=aAlpha;vC=aColor;}`;\r\nconst FRAG=`uniform sampler2D uTex;varying float vA;varying vec3 vC;\r\nvoid main(){float a=texture2D(uTex,gl_PointCoord).a*vA;if(a<.004)discard;gl_FragColor=vec4(vC,a);\r\n#include <colorspace_fragment>\r\n}`;\r\nconst BEAM_VERT=`varying vec2 vUv;varying float vE;void main(){vUv=uv;vec4 mv=modelViewMatrix*vec4(position,1.);vE=abs(dot(normalize(normalMatrix*normal),normalize(-mv.xyz)));gl_Position=projectionMatrix*mv;}`;\r\nconst BEAM_FRAG=`uniform vec3 uColor;uniform float uOpacity;uniform float uPow;varying vec2 vUv;varying float vE;\r\nvoid main(){float fade=pow(clamp(1.-vUv.y,0.,1.),uPow);float edge=pow(clamp(vE,0.,1.),1.4);float a=fade*edge*uOpacity;gl_FragColor=vec4(mix(vec3(1.),uColor,clamp(vUv.y*1.2,0.,1.))*1.15,a);\r\n#include <colorspace_fragment>\r\n}`;\r\n\r\nexport function glowTexture(THREE,inner='255,255,255',stops=[[0,1],[.25,.55],[.6,.14],[1,0]]){\r\n const c=document.createElement('canvas');c.width=c.height=128;const x=c.getContext('2d'),g=x.createRadialGradient(64,64,0,64,64,64);\r\n for(const [k,a] of stops)g.addColorStop(k,`rgba(${inner},${a})`);x.fillStyle=g;x.fillRect(0,0,128,128);\r\n const t=new THREE.CanvasTexture(c);t.colorSpace=THREE.SRGBColorSpace;return t;\r\n}\r\n// A lumpy puff: several soft blobs so steam and dust do not read as perfect discs.\r\nfunction puffTexture(THREE){\r\n const c=document.createElement('canvas');c.width=c.height=128;const x=c.getContext('2d');\r\n for(let i=0;i<9;i++){const px=64+rnd(-20,20),py=64+rnd(-20,20),r=rnd(26,44),g=x.createRadialGradient(px,py,0,px,py,r);g.addColorStop(0,'rgba(255,255,255,.55)');g.addColorStop(.6,'rgba(255,255,255,.18)');g.addColorStop(1,'rgba(255,255,255,0)');x.fillStyle=g;x.fillRect(0,0,128,128);}\r\n const t=new THREE.CanvasTexture(c);t.colorSpace=THREE.SRGBColorSpace;return t;\r\n}\r\n\r\nclass Pool{\r\n constructor(THREE,n,{additive=false,tex,uniforms}){\r\n  this.n=n;this.i=0;this.THREE=THREE;this.gravity=0;this.drag=0;this.wobble=0;\r\n  this.pos=new Float32Array(n*3);this.vel=new Float32Array(n*3);this.size=new Float32Array(n);this.alpha=new Float32Array(n);this.col=new Float32Array(n*3);\r\n  this.age=new Float32Array(n).fill(9);this.life=new Float32Array(n).fill(1);this.s0=new Float32Array(n);this.s1=new Float32Array(n);this.a0=new Float32Array(n);this.ph=new Float32Array(n);\r\n  const geo=this.geo=new THREE.BufferGeometry();\r\n  for(const [name,arr,k] of [['position',this.pos,3],['aSize',this.size,1],['aAlpha',this.alpha,1],['aColor',this.col,3]])geo.setAttribute(name,new THREE.BufferAttribute(arr,k).setUsage(THREE.DynamicDrawUsage));\r\n  this.mat=new THREE.ShaderMaterial({vertexShader:VERT,fragmentShader:FRAG,uniforms:{uTex:{value:tex},uScale:uniforms.uScale},transparent:true,depthWrite:false,blending:additive?THREE.AdditiveBlending:THREE.NormalBlending});\r\n  this.points=new THREE.Points(geo,this.mat);this.points.frustumCulled=false;\r\n }\r\n emit(x,y,z,vx,vy,vz,life,s0,s1,color,alpha){\r\n  const i=this.i;this.i=(i+1)%this.n;const p=i*3;\r\n  this.pos[p]=x;this.pos[p+1]=y;this.pos[p+2]=z;this.vel[p]=vx;this.vel[p+1]=vy;this.vel[p+2]=vz;\r\n  this.life[i]=life;this.age[i]=0;this.s0[i]=s0;this.s1[i]=s1;this.a0[i]=alpha;this.ph[i]=Math.random()*6.28;\r\n  this.col[p]=color.r;this.col[p+1]=color.g;this.col[p+2]=color.b;\r\n }\r\n update(dt){\r\n  const {pos,vel,age,life,size,alpha,s0,s1,a0,ph}=this,dr=Math.exp(-this.drag*dt);\r\n  for(let i=0;i<this.n;i++){\r\n   if(age[i]>=life[i]){alpha[i]=0;size[i]=0;continue;}\r\n   age[i]+=dt;const k=Math.min(1,age[i]/life[i]),p=i*3;\r\n   vel[p+1]+=this.gravity*dt;vel[p]*=dr;vel[p+1]*=dr;vel[p+2]*=dr;\r\n   if(this.wobble)vel[p]+=Math.sin(age[i]*2.1+ph[i])*this.wobble*dt;\r\n   pos[p]+=vel[p]*dt;pos[p+1]+=vel[p+1]*dt;pos[p+2]+=vel[p+2]*dt;\r\n   size[i]=lerp(s0[i],s1[i],k);alpha[i]=a0[i]*Math.min(1,k*9)*Math.pow(1-k,1.25);\r\n  }\r\n  for(const name of ['position','aSize','aAlpha','aColor'])this.geo.getAttribute(name).needsUpdate=true;\r\n }\r\n}\r\n\r\n// The GLBs are untextured, so the pod's look is set here: dark metal in the tier colour with a glowing fresnel rim so it\r\n// reads at night (Legendary gold); Secret is a hologram (iridescent rim, rising scanlines, ~75% opacity, flicker).\r\nfunction tierMaterial(THREE,name){\r\n const c=new THREE.Color(TIERS[name]?.color||TIERS.uncommon.color),gold=name==='legendary';\r\n const m=new THREE.MeshStandardMaterial({color:gold?new THREE.Color(0xb07818):c.clone().multiplyScalar(.13),metalness:gold?.85:.7,roughness:gold?.3:.35,emissive:c,emissiveIntensity:.02});\r\n m.onBeforeCompile=sh=>{sh.uniforms.uRim={value:c.clone().multiplyScalar(gold?.9:.6)};\r\n  sh.fragmentShader='uniform vec3 uRim;\\n'+sh.fragmentShader.replace('#include <emissivemap_fragment>','#include <emissivemap_fragment>\\ntotalEmissiveRadiance+=uRim*pow(1.-abs(dot(normalize(vNormal),normalize(vViewPosition))),2.2);');};\r\n return m;\r\n}\r\nconst HOLO_VERT=`uniform float uTime;varying vec3 vN;varying vec3 vV;varying float vY;\r\nvoid main(){vec3 p=position;float g=step(.93,fract(sin(floor(uTime*9.)*91.7)*4375.5));p.x+=g*.03*sin(position.y*60.+uTime*80.);\r\nvec4 mv=modelViewMatrix*vec4(p,1.);vN=normalize(normalMatrix*normal);vV=normalize(-mv.xyz);vY=(modelMatrix*vec4(p,1.)).y;gl_Position=projectionMatrix*mv;}`;\r\nconst HOLO_FRAG=`uniform float uTime;uniform float uOpacity;uniform float uRimOnly;varying vec3 vN;varying vec3 vV;varying float vY;\r\nvec3 iri(float h){h=fract(h)*3.;vec3 a=vec3(.25,.95,1.),b=vec3(1.,.3,.85),c=vec3(1.,.82,.35);return h<1.?mix(a,b,h):h<2.?mix(b,c,h-1.):mix(c,a,h-2.);}\r\nvoid main(){float f=1.-abs(dot(normalize(vN),normalize(vV)));float rim=pow(f,1.6);\r\nvec3 hue=iri(f*1.3+vY*.25+uTime*.12);\r\nfloat scan=smoothstep(.55,1.,sin((vY*22.-uTime*3.)*3.1416)*.5+.5);\r\nfloat fine=.85+.15*sin((vY*140.-uTime*9.)*3.1416);\r\nfloat flick=.9+.06*sin(uTime*31.)+.04*sin(uTime*17.3);float g=step(.95,fract(sin(floor(uTime*9.)*91.7)*4375.5));flick*=1.-.35*g;\r\nvec3 col=(mix(vec3(.16,.05,.4),hue,.45+.55*rim)*(.7+.8*rim)+hue*scan*.55)*fine*flick;\r\nfloat a=uRimOnly>.5?rim*flick:uOpacity*(.85+.15*rim+.15*scan)*flick;\r\ngl_FragColor=vec4(col,a);\r\n#include <colorspace_fragment>\r\n}`;\r\nfunction holoMaterials(THREE,uTime){\r\n const mk=(rimOnly,extra)=>new THREE.ShaderMaterial({vertexShader:HOLO_VERT,fragmentShader:HOLO_FRAG,uniforms:{uTime,uOpacity:{value:.75},uRimOnly:{value:rimOnly}},transparent:true,...extra});\r\n return {body:mk(0,{depthWrite:true}),glow:mk(1,{depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.BackSide})};\r\n}\r\nfunction loadGlb(THREE,tier){\r\n return (async()=>{\r\n  try{\r\n   const {GLTFLoader}=await import('three/addons/loaders/GLTFLoader.js');\r\n   const gltf=await Promise.race([new GLTFLoader().loadAsync(new URL(`./pods/drop-pod-${tier}.glb`,import.meta.url).href),new Promise((_,no)=>setTimeout(no,7000))]);\r\n   const model=gltf.scene,box=new THREE.Box3().setFromObject(model),size=box.getSize(new THREE.Vector3()),mid=box.getCenter(new THREE.Vector3());\r\n   const big=Math.max(size.x,size.y,size.z);if(!(big>0))return null;\r\n   // Normalise by the largest side so a pod modelled lying down keeps its pose; base sits on y=0.\r\n   const k=2.4/big;model.scale.setScalar(k);model.position.set(-mid.x*k,-box.min.y*k,-mid.z*k);\r\n   const holder=new THREE.Group();holder.add(model);holder.userData={top:size.y*k,radius:Math.min(size.x,size.z)*k*.5};return holder;\r\n  }catch{return null;}\r\n })();\r\n}\r\n\r\n// The procedural pod: chunky canister, swept fins, tier-colour paint and glowing seams, hinged lid. Origin at its base, 2.4 tall.\r\nfunction buildFallbackPod(THREE,tier){\r\n const color=new THREE.Color(tier.color),group=new THREE.Group(),parts={};\r\n const hull=new THREE.MeshStandardMaterial({vertexColors:true,metalness:.82,roughness:.42});\r\n const dark=new THREE.MeshStandardMaterial({color:0x1b2029,metalness:.85,roughness:.5});\r\n const paint=new THREE.MeshStandardMaterial({color,metalness:.55,roughness:.38,emissive:color,emissiveIntensity:.07});\r\n const glow=parts.glow=new THREE.MeshStandardMaterial({color:0x111111,emissive:color,emissiveIntensity:1.6,metalness:0,roughness:.6});\r\n const profile=[[0,0],[.34,0],[.46,.07],[.55,.3],[.61,.7],[.63,1.15],[.61,1.6],[.56,1.92],[.5,2.1],[.46,2.14]].map(([r,y])=>new THREE.Vector2(r,y));\r\n const body=new THREE.LatheGeometry(profile,40),pos=body.attributes.position,cols=new Float32Array(pos.count*3),metal=new THREE.Color(0x56627a),char=new THREE.Color(0x120d0c),scorch=new THREE.Color();\r\n for(let i=0;i<pos.count;i++){const y=pos.getY(i),k=clamp((y-.15)/1.1)+.12*(vnoise(pos.getX(i)*6,y*5+pos.getZ(i)*4)-.5);scorch.copy(char).lerp(metal,clamp(k));cols[i*3]=scorch.r;cols[i*3+1]=scorch.g;cols[i*3+2]=scorch.b;}\r\n body.setAttribute('color',new THREE.BufferAttribute(cols,3));\r\n group.add(new THREE.Mesh(body,hull));\r\n // engine bell, bands, seams\r\n const bell=new THREE.Mesh(new THREE.CylinderGeometry(.3,.2,.28,24,1,true),dark);bell.position.y=-.06;group.add(bell);\r\n const nozzle=parts.nozzle=new THREE.Mesh(new THREE.CircleGeometry(.22,24),new THREE.MeshBasicMaterial({color:0xffb060}));nozzle.rotation.x=Math.PI/2;nozzle.position.y=-.2;group.add(nozzle);\r\n for(const [y,r,tube,m] of [[.2,.55,.06,dark],[1.85,.59,.07,dark],[.62,.625,.028,glow],[1.42,.625,.028,glow],[1.08,.64,.05,paint]]){const t=new THREE.Mesh(new THREE.TorusGeometry(r,tube,10,48),m);t.rotation.x=Math.PI/2;t.position.y=y;group.add(t);}\r\n for(let i=0;i<8;i++){const a=i/8*Math.PI*2+.2,s=new THREE.Mesh(new THREE.BoxGeometry(.035,.74,.03),glow);s.position.set(Math.cos(a)*.625,1.02,Math.sin(a)*.625);s.rotation.y=-a;group.add(s);}\r\n for(let i=0;i<6;i++){const a=i/6*Math.PI*2,p=new THREE.Mesh(new THREE.BoxGeometry(.28,.5,.05),dark);p.position.set(Math.cos(a)*.625,.75+(i%2)*.55,Math.sin(a)*.625);p.rotation.y=-a;group.add(p);}\r\n // porthole\r\n const win=new THREE.Mesh(new THREE.CircleGeometry(.14,20),new THREE.MeshBasicMaterial({color}));win.position.set(0,1.22,.658);group.add(win);\r\n const rim=new THREE.Mesh(new THREE.TorusGeometry(.16,.03,8,24),dark);rim.position.copy(win.position);group.add(rim);\r\n // fins\r\n const fs=new THREE.Shape();fs.moveTo(.5,.18);fs.lineTo(1.12,-.2);fs.lineTo(1.18,.04);fs.lineTo(.68,1.02);fs.lineTo(.56,1.02);fs.closePath();\r\n const fin=new THREE.ExtrudeGeometry(fs,{depth:.07,bevelEnabled:true,bevelSize:.02,bevelThickness:.02,bevelSegments:1});fin.translate(0,0,-.035);\r\n for(let i=0;i<4;i++){const f=new THREE.Mesh(fin,paint),tip=new THREE.Mesh(new THREE.BoxGeometry(.05,.05,.1),glow);tip.position.set(1.15,-.08,0);const h=new THREE.Group();h.add(f,tip);h.rotation.y=i/4*Math.PI*2+Math.PI/4;group.add(h);}\r\n // hatch core (the light inside) and hinged lid\r\n const core=parts.core=new THREE.Mesh(new THREE.CircleGeometry(.42,28),new THREE.MeshBasicMaterial({color:new THREE.Color(1,1,1).lerp(color,.35)}));core.rotation.x=-Math.PI/2;core.position.y=2.1;group.add(core);\r\n const hinge=parts.hinge=new THREE.Group();hinge.position.set(-.46,2.13,0);group.add(hinge);\r\n const lidProfile=[[0,.0],[.46,.0],[.47,.06],[.43,.14],[.3,.24],[.15,.31],[0,.34]].map(([r,y])=>new THREE.Vector2(r,y));\r\n const lid=new THREE.Mesh(new THREE.LatheGeometry(lidProfile,36),paint);lid.position.x=.46;hinge.add(lid);\r\n const lidRing=new THREE.Mesh(new THREE.TorusGeometry(.4,.025,8,32),glow);lidRing.rotation.x=Math.PI/2;lidRing.position.set(.46,.04,0);hinge.add(lidRing);\r\n const hook=new THREE.Mesh(new THREE.BoxGeometry(.12,.1,.2),dark);hook.position.set(-.02,.02,0);hinge.add(hook);\r\n const handle=new THREE.Mesh(new THREE.TorusGeometry(.09,.025,8,16,Math.PI),dark);handle.position.set(.46,.33,0);hinge.add(handle);\r\n group.userData=parts;return group;\r\n}\r\n\r\nexport function buildTerrain(THREE,tier){\r\n const g=new THREE.Group(),color=new THREE.Color(tier.color);\r\n const size=170,seg=70,geo=new THREE.PlaneGeometry(size,size,seg,seg);geo.rotateX(-Math.PI/2);\r\n const p=geo.attributes.position,cols=new Float32Array(p.count*3),c=new THREE.Color();\r\n for(let i=0;i<p.count;i++){const x=p.getX(i),z=p.getZ(i),r=Math.hypot(x,z),h=(vnoise(x*.09,z*.09)-.5)*1.4*clamp((r-5)/12)+(vnoise(x*.4,z*.4)-.5)*.12*clamp((r-4)/6);p.setY(i,h);c.set(0x2c2430).lerp(new THREE.Color(0x3a2e33),vnoise(x*.2+7,z*.2));c.multiplyScalar(.85+.3*vnoise(x*1.3,z*1.3));cols[i*3]=c.r;cols[i*3+1]=c.g;cols[i*3+2]=c.b;}\r\n geo.setAttribute('color',new THREE.BufferAttribute(cols,3));geo.computeVertexNormals();\r\n g.add(new THREE.Mesh(geo,new THREE.MeshStandardMaterial({vertexColors:true,roughness:.96,metalness:0})));\r\n // mound\r\n const rings=26,segs=72,pts=[],idx=[],mc=[];\r\n for(let ri=0;ri<=rings;ri++){const r=ri===0?0:Math.pow(ri/rings,.85)*MOUND_R;for(let si=0;si<segs;si++){const th=si/segs*Math.PI*2,rr=r*(1+.08*(vnoise(th*3,r)-.5)),h=ri===rings?0:moundHeight(rr,th)+(ri===rings?0:0);pts.push(Math.cos(th)*rr,h,Math.sin(th)*rr);const k=clamp(h/1.2);const cc=new THREE.Color(0x4a3426).lerp(new THREE.Color(0x9c7a58),k*.7+.3*vnoise(th*9,r*7));mc.push(cc.r,cc.g,cc.b);}}\r\n for(let ri=0;ri<rings;ri++)for(let si=0;si<segs;si++){const a=ri*segs+si,b=ri*segs+(si+1)%segs,c2=(ri+1)*segs+si,d=(ri+1)*segs+(si+1)%segs;idx.push(a,c2,b,b,c2,d);}\r\n const mg=new THREE.BufferGeometry();mg.setAttribute('position',new THREE.Float32BufferAttribute(pts,3));mg.setAttribute('color',new THREE.Float32BufferAttribute(mc,3));mg.setIndex(idx);mg.computeVertexNormals();\r\n const mound=new THREE.Mesh(mg,new THREE.MeshStandardMaterial({vertexColors:true,roughness:1,flatShading:true}));mound.position.y=.02;mound.scale.y=.001;mound.visible=false;g.add(mound);\r\n // scorch under the impact\r\n const sc=document.createElement('canvas');sc.width=sc.height=128;const sx=sc.getContext('2d'),sg=sx.createRadialGradient(64,64,6,64,64,64);sg.addColorStop(0,'rgba(0,0,0,.95)');sg.addColorStop(.5,'rgba(10,6,4,.75)');sg.addColorStop(1,'rgba(0,0,0,0)');sx.fillStyle=sg;sx.fillRect(0,0,128,128);\r\n const scorch=new THREE.Mesh(new THREE.PlaneGeometry(10,10),new THREE.MeshBasicMaterial({map:new THREE.CanvasTexture(sc),transparent:true,depthWrite:false,opacity:0}));scorch.rotation.x=-Math.PI/2;scorch.position.y=.03;g.add(scorch);\r\n // far ridge so the horizon has depth\r\n const ridge=new THREE.CylinderGeometry(70,70,9,96,1,true),rp=ridge.attributes.position;\r\n for(let i=0;i<rp.count;i++)if(rp.getY(i)>0){const a=Math.atan2(rp.getZ(i),rp.getX(i));rp.setY(i,3+vnoise(a*5,1)*9+vnoise(a*17,3)*3);}\r\n const rm=new THREE.Mesh(ridge,new THREE.MeshBasicMaterial({color:0x0b0f24,side:THREE.BackSide,fog:true}));rm.position.y=-3.5;g.add(rm);\r\n const rim=new THREE.Mesh(new THREE.CylinderGeometry(52,52,5,80,1,true),new THREE.MeshBasicMaterial({color:0x0f1330,side:THREE.BackSide}));\r\n const rp2=rim.geometry.attributes.position;for(let i=0;i<rp2.count;i++)if(rp2.getY(i)>0){const a=Math.atan2(rp2.getZ(i),rp2.getX(i));rp2.setY(i,1.5+vnoise(a*8,9)*5);}\r\n rim.position.y=-2.4;g.add(rim);\r\n return {group:g,mound,scorch};\r\n}\r\n\r\nexport function makeSky(THREE,tier){\r\n const c=document.createElement('canvas');c.width=4;c.height=512;const x=c.getContext('2d'),g=x.createLinearGradient(0,0,0,512),tc=new THREE.Color(tier.color);\r\n const tint=(k,base)=>'#'+new THREE.Color(base).lerp(tc,k).getHexString();\r\n g.addColorStop(0,'#01020a');g.addColorStop(.45,'#070b24');g.addColorStop(.72,tint(.14,0x141a4a));g.addColorStop(.86,tint(.28,0x2a2150));g.addColorStop(1,'#1a1228');x.fillStyle=g;x.fillRect(0,0,4,512);\r\n const t=new THREE.CanvasTexture(c);t.colorSpace=THREE.SRGBColorSpace;return t;\r\n}\r\n\r\nexport function makeStars(THREE,uniforms){\r\n const layers=[];\r\n for(const [n,R,size,tw] of [[800,95,1.5,.3],[360,70,2.3,.5],[120,45,3.6,.8]]){\r\n  const pos=new Float32Array(n*3),sz=new Float32Array(n),ph=new Float32Array(n),col=new Float32Array(n*3),cc=new THREE.Color();\r\n  for(let i=0;i<n;i++){const u=Math.random(),th=Math.random()*Math.PI*2,y=Math.pow(u,.8)*.97+.03,r=Math.sqrt(1-y*y);pos[i*3]=Math.cos(th)*r*R;pos[i*3+1]=y*R*.75;pos[i*3+2]=-Math.abs(Math.sin(th))*r*R*.9-R*.12;sz[i]=size*rnd(.5,1.2);ph[i]=Math.random()*6.28;cc.setHSL(rnd(.55,.68)*(Math.random()<.2?.13:1),.5,rnd(.8,.95));col.set([cc.r,cc.g,cc.b],i*3);}\r\n  const geo=new THREE.BufferGeometry();geo.setAttribute('position',new THREE.BufferAttribute(pos,3));geo.setAttribute('aSize',new THREE.BufferAttribute(sz,1));geo.setAttribute('aPh',new THREE.BufferAttribute(ph,1));geo.setAttribute('aColor',new THREE.BufferAttribute(col,3));\r\n  const mat=new THREE.ShaderMaterial({uniforms:{uTime:uniforms.uTime,uDpr:uniforms.uDpr,uTw:{value:tw}},transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,\r\n   vertexShader:`attribute float aSize;attribute float aPh;attribute vec3 aColor;uniform float uTime;uniform float uDpr;uniform float uTw;varying vec3 vC;varying float vT;void main(){vT=.65+.35*sin(uTime*(1.5+aPh*.4)+aPh*9.)*uTw/.5*.5+(1.-uTw)*.1;vC=aColor;gl_PointSize=aSize*uDpr*(.85+.3*vT);gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`,\r\n   fragmentShader:`varying vec3 vC;varying float vT;void main(){float d=length(gl_PointCoord-.5)*2.;float a=smoothstep(1.,0.,d);a*=a;gl_FragColor=vec4(vC*(.8+.5*vT),a);\r\n#include <colorspace_fragment>\r\n}`});\r\n  const pts=new THREE.Points(geo,mat);pts.frustumCulled=false;pts.renderOrder=-3;layers.push({pts,depth:R});\r\n }\r\n return layers;\r\n}\r\n\r\nfunction createWorld(THREE,renderer,tierName,{reduced,onEvent}){\r\n const tier=TIERS[tierName]||TIERS.uncommon,color=new THREE.Color(tier.color),gold=new THREE.Color(0xffd36a),white=new THREE.Color(0xfff1c8),hot=new THREE.Color(0xff8a3a);\r\n // Spark colour: gold flecks for Legendary, holographic cyan/violet/magenta/gold for Secret, else white-to-tier.\r\n const holoHues=[0x3ff5ff,0xb388ff,0xff4bd8,0xffd36a].map(h=>new THREE.Color(h));\r\n const sparkCol=(mix=.9)=>tier.holo?holoHues[(Math.random()*4)|0]:tier.gold&&Math.random()<.6?gold:white.clone().lerp(color,Math.random()*mix);\r\n const scene=new THREE.Scene(),aspect0=Math.max(.3,innerWidth/innerHeight);\r\n const camera=new THREE.PerspectiveCamera(50,aspect0,.1,400);\r\n const uniforms={uScale:{value:1},uTime:{value:0},uDpr:{value:renderer.getPixelRatio()}};\r\n const owned=[];const own=o=>(owned.push(o),o);\r\n scene.background=own(makeSky(THREE,tier));\r\n scene.fog=new THREE.Fog(0x1a1228,28,95);\r\n // lighting: cool moon rim from behind-left, tier rim from behind-right, tier point light on the pod, warm impact light\r\n scene.add(new THREE.HemisphereLight(0x4a5aa0,0x2a1a1c,.75));\r\n const moon=new THREE.DirectionalLight(0xa9c2ff,2.2);moon.position.set(-9,11,-9);scene.add(moon);\r\n const rimR=new THREE.DirectionalLight(color.clone().lerp(white,.35),.45);rimR.position.set(9,5,-7);scene.add(rimR);\r\n const front=new THREE.DirectionalLight(0x6a7ab8,.55);front.position.set(2,3,10);scene.add(front);\r\n const podLight=new THREE.PointLight(color.clone().lerp(white,.4),0,16,1.6);podLight.position.set(0,2.2,2.6);scene.add(podLight);\r\n const impactLight=new THREE.PointLight(0xff8a3a,0,14,1.8);impactLight.position.set(0,.6,1.6);scene.add(impactLight);\r\n const hatchLight=new THREE.PointLight(color,0,12,1.4);scene.add(hatchLight);\r\n // environment reflections so the metal reads: dark sky, a tier-coloured strip and a cool softbox\r\n {const env=new THREE.Scene(),sky=new THREE.Mesh(new THREE.SphereGeometry(20,24,12),new THREE.MeshBasicMaterial({color:0x10142c,side:THREE.BackSide}));env.add(sky);\r\n  for(const [x,y,z,w,h,c] of [[-8,8,-6,10,3,0xa9c2ff],[9,3,-5,2.5,10,color.getHex()],[0,12,4,14,2,0x5566aa],[0,2,10,12,3,0x333a60]]){const b=new THREE.Mesh(new THREE.PlaneGeometry(w,h),new THREE.MeshBasicMaterial({color:c,side:THREE.DoubleSide}));b.position.set(x,y,z);b.lookAt(0,0,0);env.add(b);}\r\n  const pm=new THREE.PMREMGenerator(renderer);scene.environment=own(pm.fromScene(env,.03).texture);scene.environmentIntensity=.9;pm.dispose();env.traverse(o=>{o.geometry?.dispose();o.material?.dispose();});}\r\n // sky dressing\r\n const stars=makeStars(THREE,uniforms),starGroup=new THREE.Group();for(const l of stars)starGroup.add(l.pts);scene.add(starGroup);\r\n const nebTex=own(glowTexture(THREE,'255,255,255',[[0,.55],[.35,.28],[.7,.08],[1,0]]));\r\n const nebula=(tier.holo?[[-24,24,-85,135,color,.75],[30,44,-95,120,new THREE.Color(0x2fe0ff),.55],[2,62,-80,140,new THREE.Color(0xff4bd8),.32],[-40,52,-90,90,new THREE.Color(0x3ff5ff),.3]]:[[-22,26,-85,110,color,.5],[30,48,-95,95,new THREE.Color(0x5a3cff),.38],[0,60,-80,120,new THREE.Color(0x2fd0c0),.18]]).map(([x,y,z,s,col,o])=>{const sp=new THREE.Sprite(new THREE.SpriteMaterial({map:nebTex,color:col,transparent:true,opacity:o,depthWrite:false,blending:THREE.AdditiveBlending,fog:false}));sp.position.set(x,y,z);sp.scale.set(s,s*.7,1);sp.renderOrder=-2;scene.add(sp);return {sp,o};});\r\n const moonTex=own(glowTexture(THREE,'200,220,255',[[0,1],[.18,.95],[.22,.35],[.6,.08],[1,0]]));\r\n const moonSp=new THREE.Sprite(new THREE.SpriteMaterial({map:moonTex,transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,fog:false}));moonSp.position.set(-30,34,-85);moonSp.scale.setScalar(30);scene.add(moonSp);\r\n const terrain=buildTerrain(THREE,tier);scene.add(terrain.group);\r\n // particles\r\n const glow=own(glowTexture(THREE)),puff=own(puffTexture(THREE));\r\n const fire=new Pool(THREE,700,{additive:true,tex:glow,uniforms}),sparks=new Pool(THREE,500,{additive:true,tex:glow,uniforms}),smoke=new Pool(THREE,500,{tex:puff,uniforms}),dust=new Pool(THREE,420,{tex:puff,uniforms}),steam=new Pool(THREE,520,{tex:puff,uniforms}),embers=new Pool(THREE,300,{additive:true,tex:glow,uniforms});\r\n sparks.gravity=-9;sparks.drag=.35;dust.drag=1.4;dust.gravity=-.2;steam.wobble=.5;steam.drag=.25;smoke.drag=.6;fire.drag=1.2;embers.drag=.15;embers.wobble=1;\r\n for(const [pool,order] of [[smoke,1],[dust,2],[steam,3],[fire,4],[sparks,5],[embers,6]]){pool.points.renderOrder=order;scene.add(pool.points);}\r\n // pod\r\n const podRoot=new THREE.Group(),podVisual=new THREE.Group();podRoot.add(podVisual);scene.add(podRoot);\r\n let parts=null,glbMode=false,hatchY=2.1,coreScale=1;\r\n const fallback=buildFallbackPod(THREE,tier);podVisual.add(fallback);parts=fallback.userData;\r\n const hatchGlow=new THREE.Sprite(new THREE.SpriteMaterial({map:glow,color:new THREE.Color(1,1,1).lerp(color,.4),transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,opacity:0}));hatchGlow.scale.setScalar(2.4);scene.add(hatchGlow);\r\n const heat=new THREE.Sprite(new THREE.SpriteMaterial({map:glow,color:hot.clone().lerp(color,.25),transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,opacity:0}));scene.add(heat);\r\n const trailMat=new THREE.ShaderMaterial({vertexShader:BEAM_VERT,fragmentShader:BEAM_FRAG,uniforms:{uColor:{value:color.clone()},uOpacity:{value:0},uPow:{value:1.4}},transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.DoubleSide});\r\n const cone=new THREE.ConeGeometry(.6,1,20,1,true);cone.translate(0,.5,0);const trail=new THREE.Mesh(cone,trailMat);trail.visible=false;scene.add(trail);\r\n const beamMat=new THREE.ShaderMaterial({vertexShader:BEAM_VERT,fragmentShader:BEAM_FRAG,uniforms:{uColor:{value:color.clone()},uOpacity:{value:0},uPow:{value:.8}},transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.DoubleSide});\r\n const cyl=new THREE.CylinderGeometry(.85,.5,1,28,1,true);cyl.translate(0,.5,0);const beam=new THREE.Mesh(cyl,beamMat);beam.visible=false;scene.add(beam);\r\n const beamMat2=beamMat.clone();beamMat2.uniforms={uColor:{value:white.clone().lerp(color,.3)},uOpacity:{value:0},uPow:{value:.6}};const cyl2=new THREE.CylinderGeometry(.34,.18,1,20,1,true);cyl2.translate(0,.5,0);const beam2=new THREE.Mesh(cyl2,beamMat2);beam2.visible=false;scene.add(beam2);\r\n const ringMat=new THREE.MeshBasicMaterial({color:white.clone().lerp(color,.4),transparent:true,opacity:0,depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.DoubleSide});\r\n const ringGeo=new THREE.RingGeometry(.9,1,72),shock=[0,1].map(()=>{const m=new THREE.Mesh(ringGeo,ringMat.clone());m.rotation.x=-Math.PI/2;m.position.y=.12;m.visible=false;scene.add(m);return {m,t0:0};});\r\n // rocks\r\n const rockGeo=new THREE.DodecahedronGeometry(1,0),rockMat=new THREE.MeshStandardMaterial({color:0x4a3828,roughness:1,flatShading:true}),rocks=[];\r\n for(let i=0;i<tier.rocks;i++){const m=new THREE.Mesh(rockGeo,rockMat),s=rnd(.07,.2)*(tier.big?1.3:1);m.scale.set(s,s*rnd(.6,1),s*rnd(.8,1.1));m.visible=false;scene.add(m);rocks.push({m,v:new THREE.Vector3(),s,bounce:0});}\r\n\r\n // timeline\r\n const T_FALL=tier.sky,T_LAND=tier.sky+tier.fall,T_PROMPT=T_LAND+tier.settle;\r\n const START=new THREE.Vector3(1.8,11.5,-2.5),END=new THREE.Vector3(0,-1.02,.1),dirFall=END.clone().sub(START).normalize();\r\n const qFall=new THREE.Quaternion(),qLand=new THREE.Quaternion().setFromEuler(new THREE.Euler(.06,0,-.15)),qSpin=new THREE.Quaternion(),Y=new THREE.Vector3(0,1,0),down=new THREE.Vector3(0,-1,0);\r\n qFall.setFromUnitVectors(down,dirFall);\r\n let t=0,last=performance.now(),tapT=null,gate=false,popped=false,landed=false,silent=false,done=false,failed=false,prevPos=START.clone(),pop0=0,landT=0,revealed=false;\r\n const shakes=[];const addShake=(at,amp,decay=4.4)=>{if(!reduced)shakes.push({at,amp,decay});};\r\n const lookY=new THREE.Vector3(),camBase=new THREE.Vector3(),tmp=new THREE.Vector3(),hatchPos=new THREE.Vector3();\r\n const fit=()=>Math.max(1,.46/Math.max(.2,camera.aspect));\r\n const sh=(tt,s)=>Math.sin(tt*41+s)*.6+Math.sin(tt*27.3+s*2.3)*.4;\r\n const hatchWorld=out=>parts?.core?podRoot.localToWorld(out.set(0,hatchY,0).applyMatrix4(podVisual.matrix)):out.set(0,2.1,0);\r\n podRoot.position.copy(START);podRoot.visible=false;\r\n\r\n function setUniformsSize(){uniforms.uScale.value=innerHeight*renderer.getPixelRatio()/(2*Math.tan(THREE.MathUtils.degToRad(camera.fov/2)));uniforms.uDpr.value=renderer.getPixelRatio();}\r\n function resize(){const w=innerWidth,h=innerHeight;renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();setUniformsSize();}\r\n\r\n function impact(){\r\n  landed=true;landT=t;podRoot.visible=true;podRoot.position.copy(END);\r\n  terrain.mound.visible=true;\r\n  if(!silent){\r\n   onEvent('impact');addShake(t,tier.shake,4.2);if(tier.aftershock)addShake(t+.5,tier.aftershock,5);\r\n   impactLight.intensity=140;\r\n   shock[0].m.visible=true;shock[0].t0=t;shock[1].m.visible=!!tier.big;shock[1].t0=t+.16;\r\n   const nd=Math.round(95*tier.dust);\r\n   for(let i=0;i<nd;i++){const a=Math.random()*6.28,sp=rnd(2,6.5)*(tier.big?1.2:1);dust.emit(Math.cos(a)*.8,.25,Math.sin(a)*.8,Math.cos(a)*sp,rnd(.4,2.6),Math.sin(a)*sp,rnd(1.6,2.8),rnd(.7,1.2),rnd(2.4,4)*(tier.big?1.25:1),new THREE.Color().setRGB(.47,.37,.3).lerp(color,.05).multiplyScalar(rnd(.8,1.15)),.62);}\r\n   for(let i=0;i<40*tier.dust;i++){dust.emit(rnd(-.5,.5),.3,rnd(-.5,.5),rnd(-.8,.8),rnd(3,7.5),rnd(-.8,.8),rnd(1.4,2.4),rnd(.7,1),rnd(2,3.4),new THREE.Color().setRGB(.5,.4,.33).multiplyScalar(rnd(.8,1.1)),.55);}\r\n   const ns=Math.round(70*tier.sparks);\r\n   for(let i=0;i<ns;i++){const a=Math.random()*6.28,sp=rnd(4,12),c=sparkCol();sparks.emit(Math.cos(a)*.5,.4,Math.sin(a)*.5,Math.cos(a)*sp,rnd(3,10),Math.sin(a)*sp,rnd(.6,1.5),rnd(.1,.2),.02,c,1);}\r\n   for(const r of rocks){r.m.visible=true;const a=Math.random()*6.28,sp=rnd(4.5,10);r.m.position.set(Math.cos(a)*1.5,.4,Math.sin(a)*1.5);r.v.set(Math.cos(a)*sp,rnd(4,9),Math.sin(a)*sp);r.bounce=0;}\r\n  }else for(const r of rocks){const a=Math.random()*6.28,d=rnd(MOUND_R*.9,MOUND_R+3.5);r.m.visible=true;r.m.position.set(Math.cos(a)*d,r.s*.5,Math.sin(a)*d);r.bounce=9;}\r\n  terrain.mound.userData.t0=t;\r\n  silent=false;\r\n }\r\n\r\n function pop(){\r\n  popped=true;pop0=t;onEvent('pop');const quiet=silent;silent=false;\r\n  hatchWorld(hatchPos);\r\n  if(!quiet){\r\n   addShake(t,tier.big?.4:.26,6);\r\n   for(let i=0;i<80;i++){const a=Math.random()*6.28,sp=rnd(.3,2.2);steam.emit(hatchPos.x+Math.cos(a)*.3,hatchPos.y,hatchPos.z+Math.sin(a)*.3,Math.cos(a)*sp,rnd(3.5,8),Math.sin(a)*sp,rnd(1.6,3),rnd(.6,1),rnd(2.5,4.5),new THREE.Color(.9,.93,1),.55);}\r\n   const ns=Math.round(60*tier.sparks);for(let i=0;i<ns;i++){const a=Math.random()*6.28,sp=rnd(1,5);sparks.emit(hatchPos.x,hatchPos.y,hatchPos.z,Math.cos(a)*sp,rnd(4,11),Math.sin(a)*sp,rnd(.8,1.8),rnd(.08,.16),.02,sparkCol(.8),1);}\r\n  }\r\n }\r\n\r\n function emitTrail(a,b,speedK){\r\n  const dist=a.distanceTo(b),n=Math.min(40,Math.ceil(dist/.14)+2);\r\n  for(let i=0;i<n;i++){\r\n   const k=i/n,x=lerp(a.x,b.x,k)-dirFall.x*1.1,y=lerp(a.y,b.y,k)-dirFall.y*1.1,z=lerp(a.z,b.z,k)-dirFall.z*1.1,c=Math.random()<.45?white.clone().lerp(hot,Math.random()*.6):color.clone().lerp(white,Math.random()*.4);\r\n   fire.emit(x,y,z,-dirFall.x*rnd(.5,3)+rnd(-.4,.4),-dirFall.y*rnd(.5,3)+rnd(-.4,.4),-dirFall.z*rnd(.5,3)+rnd(-.4,.4),rnd(.45,.95),rnd(.5,.85)*(1+speedK*.4),.08,c,.95);\r\n   if(Math.random()<.5)smoke.emit(x,y,z,rnd(-.4,.4),rnd(-.2,.5),rnd(-.4,.4),rnd(1.2,1.9),rnd(.5,.8),rnd(1.4,2.2),new THREE.Color(.2,.18,.24).lerp(color,.12),.3);\r\n   if(Math.random()<.18)sparks.emit(x,y,z,rnd(-2,2)-dirFall.x*3,rnd(-2,2)-dirFall.y*3,rnd(-2,2)-dirFall.z*3,rnd(.3,.8),rnd(.09,.15),.02,tier.holo?sparkCol():tier.gold?gold:white,1);\r\n  }\r\n }\r\n\r\n let steamAcc=0,emberAcc=0;\r\n const ventPts=[[-1.15,.42],[1.25,.28],[.35,1.15],[-.55,-.95],[.9,-.7]].map(([x,z])=>{const r=Math.hypot(x,z),th=Math.atan2(z,x);return [x,moundHeight(r,th)+.06,z];});\r\n function steamTick(dt,rate){\r\n  steamAcc+=dt*rate;\r\n  while(steamAcc>1){steamAcc--;\r\n   let x,y,z;if(Math.random()<.55){const v=ventPts[(Math.random()*ventPts.length)|0];x=v[0]+rnd(-.15,.15);y=v[1];z=v[2]+rnd(-.15,.15);}else{const a=Math.random()*6.28,r=rnd(.6,1.9);x=Math.cos(a)*r;z=Math.sin(a)*r;y=moundHeight(r,a)+.06;}\r\n   steam.emit(x,y,z,rnd(-.15,.15),rnd(.8,1.7),rnd(-.1,.2),rnd(2.2,3.6),rnd(.6,1),rnd(2.2,3.6),new THREE.Color(.8,.84,.93).lerp(color,.12),.4);\r\n  }\r\n }\r\n\r\n function update(){\r\n  const now=performance.now(),dt=Math.min(.05,(now-last)/1000);last=now;\r\n  t=(t0real===null?(t0real=now,0):(now-t0real)/1000)+skipOffset;\r\n  uniforms.uTime.value=t;\r\n  // ---- events\r\n  if(!landed&&t>=T_LAND)impact();\r\n  const u=tapT===null?-1:t-tapT;\r\n  if(tapT!==null&&!popped&&gate&&u>=.5){pop();if(fast){pop0=t-2;fast=false;}}\r\n  const pu=popped?t-pop0:-1;\r\n  if(popped&&!revealed&&pu>=1.25){revealed=true;onEvent('revealed');}\r\n  // ---- pod\r\n  const s=clamp((t-T_FALL)/tier.fall),p=Math.pow(s,1.85);\r\n  if(!landed){\r\n   podRoot.visible=t>=T_FALL;\r\n   podRoot.position.lerpVectors(START,END,p);\r\n   qSpin.setFromAxisAngle(Y,(1-p)*Math.PI*4);podRoot.quaternion.copy(qFall).multiply(qSpin);\r\n   if(podRoot.visible){\r\n    const speedK=p;emitTrail(prevPos,podRoot.position,speedK);\r\n    trail.visible=true;trail.position.copy(podRoot.position).addScaledVector(dirFall,-.9);\r\n    tmp.copy(dirFall).negate();trail.quaternion.setFromUnitVectors(Y,tmp);const len=1.5+7*Math.min(1,p*1.4);trail.scale.set(.4+.8*p,len,.4+.8*p);\r\n    trailMat.uniforms.uOpacity.value=.55+.35*p;\r\n    heat.visible=true;heat.position.copy(podRoot.position).addScaledVector(dirFall,.1);heat.material.opacity=.7+.3*Math.sin(t*40);heat.scale.setScalar(2.2+3.4*p);\r\n   }\r\n   prevPos.copy(podRoot.position);\r\n   // the engine glows hot during re-entry, panels tinted by heat\r\n   if(parts?.glow)parts.glow.emissiveIntensity=2+2*p;\r\n  }else{\r\n   const lt=t-landT;podRoot.position.copy(END);\r\n   podRoot.quaternion.slerp(qLand,clamp(dt*14));\r\n   if(trail.visible){trailMat.uniforms.uOpacity.value=Math.max(0,.9-lt*3.5);if(lt>.3)trail.visible=false;}\r\n   if(heat.visible){heat.material.opacity=Math.max(0,1-lt*4);heat.scale.setScalar(4+lt*10);if(lt>.25)heat.visible=false;}\r\n   // settle: seams cool from white-hot to tier glow and pulse\r\n   if(parts?.glow&&u<.5)parts.glow.emissiveIntensity=lerp(5,1.3,clamp(lt/1.6))+.4*Math.sin(t*3.2)*clamp(lt-1);\r\n   if(parts?.nozzle)parts.nozzle.material.color.lerp(new THREE.Color(0x201510),clamp(dt*1.2));\r\n  }\r\n  // mound grows on impact\r\n  if(landed){const mk=clamp((t-landT)/.4);terrain.mound.scale.y=Math.max(.001,silent?1:easeOutBack(mk));terrain.scorch.material.opacity=clamp((t-landT)/.5)*.9;}\r\n  // shockwaves\r\n  for(const sw of shock){if(!sw.m.visible)continue;const k=clamp((t-sw.t0)/.75);if(t<sw.t0){sw.m.scale.setScalar(.001);continue;}sw.m.scale.setScalar(.8+k*8);sw.m.material.opacity=(1-k)*(1-k)*.8;if(k>=1)sw.m.visible=false;}\r\n  // rocks\r\n  for(const r of rocks){if(!r.m.visible||r.bounce>=3)continue;r.v.y-=14*dt;r.m.position.addScaledVector(r.v,dt);r.m.rotation.x+=r.v.x*dt;r.m.rotation.z+=r.v.z*dt;\r\n   const rr=Math.hypot(r.m.position.x,r.m.position.z),gy=(rr<MOUND_R?moundHeight(rr,Math.atan2(r.m.position.z,r.m.position.x))*terrain.mound.scale.y:0)+r.s*.4;\r\n   if(r.m.position.y<gy){if(rr<1.5){const a=Math.atan2(r.m.position.z,r.m.position.x);r.m.position.x=Math.cos(a)*1.6;r.m.position.z=Math.sin(a)*1.6;}r.m.position.y=gy;r.v.y*=-.35;r.v.x*=.5;r.v.z*=.5;r.bounce++;}}\r\n  // impact + pod lights\r\n  impactLight.intensity=Math.max(0,impactLight.intensity*Math.exp(-dt*5.5));\r\n  const pulse=.5+.5*Math.sin(t*3.4);\r\n  podLight.intensity=!landed?(podRoot.visible?18+16*p:0):lerp(18,26,clamp((t-landT)/1.2))+6*pulse+(u>=0?20*clamp(u):0);\r\n  podLight.position.set(0,2.4,3);\r\n  if(!landed&&podRoot.visible)podLight.position.copy(podRoot.position).add(tmp.set(0,0,3));\r\n  // rattle, lid, beam\r\n  podVisual.position.set(0,0,0);podVisual.rotation.set(0,0,0);\r\n  if(tapT!==null&&u>=0&&!popped&&!reduced){const k=Math.min(1,u/.5),a=.016+.03*k;podVisual.position.set(rnd(-a,a),0,rnd(-a,a));podVisual.rotation.z=rnd(-a,a)*.5;if(parts?.glow)parts.glow.emissiveIntensity=lerp(1.4,6,k);steamTick(dt,50);if(Math.random()<.6)sparks.emit(rnd(-.5,.5),1.2+rnd(0,.8),rnd(-.1,.5)+.5,rnd(-1,1),rnd(1,3),rnd(0,2),rnd(.3,.7),.08,.02,white,1);}\r\n  podVisual.updateMatrix();\r\n  hatchWorld(hatchPos);\r\n  if(parts?.hinge){parts.hinge.rotation.z=popped?2.05*(1-Math.exp(-9*pu)*Math.cos(15*pu)):0;}\r\n  if(parts?.core)parts.core.visible=glbMode?popped:true;\r\n  if(glbMode&&parts?.core)parts.core.scale.setScalar(popped?clamp(pu*4)*coreScale:.001);\r\n  if(popped){\r\n   const k=clamp(pu/.5),grow=1-Math.pow(1-k,3);\r\n   beam.visible=beam2.visible=true;beam.position.copy(hatchPos);beam2.position.copy(hatchPos);\r\n   const flick=.92+.08*Math.sin(t*23)+.05*Math.sin(t*9.7);\r\n   beam.scale.set(1,18*grow,1);beam2.scale.set(1,18*grow,1);\r\n   beamMat.uniforms.uOpacity.value=.5*grow*flick;beamMat2.uniforms.uOpacity.value=.6*grow*flick;\r\n   hatchLight.position.copy(hatchPos).add(tmp.set(0,.6,.8));hatchLight.intensity=(55+25*flick)*grow;\r\n   hatchGlow.position.copy(hatchPos);hatchGlow.material.opacity=.9*grow*flick;hatchGlow.scale.setScalar(2.4+.4*Math.sin(t*14)+(1-grow)*1.5);\r\n   emberAcc+=dt*(tier.big?90:55);\r\n   while(emberAcc>1){emberAcc--;const a=Math.random()*6.28,r=rnd(0,.4);embers.emit(hatchPos.x+Math.cos(a)*r,hatchPos.y+.1,hatchPos.z+Math.sin(a)*r,rnd(-.3,.3),rnd(2.2,5.5),rnd(-.3,.3),rnd(1.4,2.6),rnd(.08,.18),.02,tier.holo||tier.gold?sparkCol(.7):white.clone().lerp(color,.7),1);}\r\n  }\r\n  // steam: continuous, loops forever once landed\r\n  if(landed&&!(tapT!==null&&!popped))steamTick(dt,(popped?44:30)*clamp((t-landT)/.9)*(silent?1:1));\r\n  // ---- camera\r\n  const asp=Math.max(.2,camera.aspect),f=fit(),lt2=clamp(t/T_LAND);\r\n  let camY=2.4,camZ=8.6*f,lk=lerp(6,1.5,smooth(lt2));\r\n  if(landed){lk=1.5;camBase.x=Math.sin(t*.28)*.22*(1-clamp(pu/1));}else camBase.x=0;\r\n  if(popped){const k=smooth(clamp(pu/1.5));camZ=lerp(8.6,8,k)*f;camY=lerp(2.4,2.5,k);lk=lerp(1.5,2.1,k);}\r\n  camera.position.set(camBase.x,camY,camZ);lookY.set(0,lk,0);\r\n  // tier rumble builds while the pod is incoming (Rare and Legendary)\r\n  let amp=0,fov=50;\r\n  if(!landed&&tier.rumble&&!reduced)amp+=tier.rumble*smooth(clamp(t/T_LAND))*(t>=T_FALL?1.6:.5);\r\n  for(let i=shakes.length-1;i>=0;i--){const sk=shakes[i],age=t-sk.at;if(age<0)continue;const a=sk.amp*Math.exp(-age*sk.decay);if(a<.004&&age>.2)shakes.splice(i,1);else{amp+=a;}}\r\n  camera.position.x+=sh(t,1)*amp*.8;camera.position.y+=sh(t,7)*amp*.8;camera.position.z+=sh(t,13)*amp*.4;\r\n  camera.lookAt(lookY);camera.rotateZ(sh(t,19)*amp*.07);\r\n  fov=50-amp*5;if(Math.abs(fov-camera.fov)>.01){camera.fov=fov;camera.updateProjectionMatrix();setUniformsSize();}\r\n  // sky motion: stars drift, layers parallax against the camera's pan\r\n  starGroup.rotation.y=t*.006;for(const [i,l] of stars.entries()){l.pts.position.y=(lk-1.5)*(i+1)*.6;l.pts.rotation.y=t*.004*(i+1);}\r\n  for(const n of nebula){n.sp.material.opacity=n.o*(1+(tier.big?.35:.12)*Math.sin(t*.6+n.o*9))*(1+(!landed?.0:0));}\r\n  if(tier.big&&!landed&&t>T_FALL){nebula[0].sp.material.opacity=nebula[0].o*(1.4+.4*Math.sin(t*9));}\r\n  // ---- particles\r\n  for(const pool of [fire,sparks,smoke,dust,steam,embers])pool.update(dt);\r\n  renderer.render(scene,camera);\r\n }\r\n let t0real=null,skipOffset=0,fast=false;\r\n resize();\r\n const world={\r\n  update,resize,tier,pools:{fire,sparks,smoke,dust,steam,embers},\r\n  get t(){return t;},get landed(){return landed;},get promptReady(){return landed&&t>=T_PROMPT&&tapT===null;},get tapped(){return tapT!==null;},\r\n  tap(){if(tapT===null){tapT=t;gate=false;}},\r\n  release(){gate=true;},\r\n  setRevealColor(hex){const c=new THREE.Color(hex);beamMat.uniforms.uColor.value.copy(c);beamMat2.uniforms.uColor.value.copy(white.clone().lerp(c,.3));hatchLight.color.copy(c);},\r\n  cancelTap(){tapT=null;gate=false;},\r\n  skipToPrompt(){silent=true;if(t<T_PROMPT)skipOffset+=T_PROMPT-t+.001;},\r\n  skipToOpen(){fast=true;if(!popped)silent=true;if(popped){pop0=Math.min(pop0,t-2);fast=false;}},\r\n  get popped(){return popped;},\r\n  // Where the pod is on screen in CSS px (for the tap target): centre and pixels per world unit.\r\n  podScreen(){tmp.set(0,(hatchY-END.y)/2,0).add(podRoot.position).project(camera);const d=camera.position.distanceTo(podRoot.position);return {x:(tmp.x*.5+.5)*innerWidth,y:(-tmp.y*.5+.5)*innerHeight,k:innerHeight/(2*Math.tan(THREE.MathUtils.degToRad(camera.fov/2)))/d};},\r\n  get silent(){return silent;},\r\n  useModel(model){\r\n   if(tapT!==null||glbMode||!parts)return;\r\n   if(tier.holo){const h=holoMaterials(THREE,uniforms.uTime),shells=[];model.traverse(o=>{if(o.isMesh){o.material=h.body;o.renderOrder=7;const s=new THREE.Mesh(o.geometry,h.glow);s.scale.setScalar(1.025);s.renderOrder=8;shells.push([o,s]);}});for(const [o,s] of shells)o.add(s);}\r\n   else{const m=tierMaterial(THREE,tierName);model.traverse(o=>{if(o.isMesh)o.material=m;});}\r\n   const core=parts.core;glbMode=true;podVisual.remove(fallback);podVisual.add(model);\r\n   // Faked hatch: a small glowing disc sunk into the top (the light, beam and sprite sell the opening).\r\n   const c=core.clone();c.material=core.material.clone();model.add(c);hatchY=model.userData.top*.96;coreScale=clamp(model.userData.radius*.45/.42,.25,.8);c.position.y=hatchY;c.rotation.x=-Math.PI/2;\r\n   parts={core:c,glow:null,nozzle:null,hinge:null};\r\n   // A mesh/node named \"lid\" or \"hatch\" is the real lid: hinge it on its lower -x edge; otherwise the glowing disc fakes the opening.\r\n   let lid=null;model.traverse(o=>{if(!lid&&/^(lid|hatch)/i.test(o.name))lid=o;});\r\n   if(lid){\r\n    podRoot.updateMatrixWorld(true);const box=new THREE.Box3().setFromObject(lid).applyMatrix4(podVisual.matrixWorld.clone().invert());\r\n    if(!box.isEmpty()){const hinge=new THREE.Group();hinge.position.set(box.min.x,box.min.y,(box.min.z+box.max.z)/2);podVisual.add(hinge);hinge.updateMatrixWorld(true);hinge.attach(lid);parts.hinge=hinge;c.position.set((box.min.x+box.max.x)/2,box.min.y,(box.min.z+box.max.z)/2);}\r\n   }\r\n  },\r\n  dispose(){\r\n   scene.traverse(o=>{o.geometry?.dispose();const m=o.material;if(m)for(const x of Array.isArray(m)?m:[m]){x.map?.dispose();x.dispose();}});\r\n   for(const o of owned)o.dispose?.();for(const l of stars)l.pts.geometry.dispose();\r\n   scene.environment=null;scene.background=null;\r\n  }\r\n };\r\n return world;\r\n}\r\n\r\n// Plays one pack's sequence full screen. open() runs the pack at the moment the pod is tapped and resolves to the\r\n// reveal items [{title,detail,colors}] (or null when it could not be saved: the pod stays closed, tap to retry).\r\n// hasNext is a boolean or a function; onNext() may return the next {tier,open,hasNext,onNext}; the sequence restarts from the sky with it.\r\nexport async function playDropPod(config){\r\n let {tier,open,hasNext,onNext}=config;let getRevealType=config.revealType,getRevealColor=config.revealColor;const onExit=config.onExit;\r\n const reduced=globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches===true;\r\n const style=document.createElement('style');style.textContent=CSS;document.head.append(style);\r\n const dlg=document.createElement('dialog');dlg.className='drop-pod';dlg.setAttribute('aria-label','Opening reward pack');\r\n dlg.innerHTML=`<canvas aria-hidden=\"true\"></canvas><div class=\"drop-pod-flash\"></div><p class=\"drop-pod-caption\" aria-hidden=\"true\">Incoming drop pod</p>\r\n<button type=\"button\" class=\"drop-pod-skip\" data-skip>Skip</button>\r\n<button type=\"button\" class=\"drop-pod-hit\" data-hit aria-label=\"Open the drop pod\"></button>\r\n<p class=\"drop-pod-prompt\" aria-hidden=\"true\">Tap the pod<small data-error></small></p>\r\n<section class=\"drop-pod-card\" aria-live=\"polite\" aria-atomic=\"true\"><p class=\"eyebrow\" data-eyebrow></p><div data-items></div></section>\r\n<div class=\"drop-pod-actions\"><button type=\"button\" class=\"secondary\" data-exit>Exit</button><button type=\"button\" data-next>Open another</button></div>`;\r\n document.body.append(dlg);\r\n const $=sel=>dlg.querySelector(sel),flash=$('.drop-pod-flash');\r\n let phase=startPhase({reduced}),world=null,renderer=null,releaseGpu=null,raf=0,disposed=false,gen=0,fullscreenTried=false,items=null,pending=null,THREE=null;\r\n const go=event=>{phase=advance(phase,event);dlg.dataset.phase=phase;};\r\n const setTier=name=>{const t=TIERS[name]?name:'uncommon';dlg.dataset.tier=t;dlg.style.setProperty('--pack',TIERS[t].color);$('.drop-pod-caption').textContent=t==='secret'?'Secret transmission':'Incoming drop pod';};\r\n const applyRewardPresentation=targetWorld=>{\r\n  if(typeof getRevealType!=='function')return;\r\n  dlg.dataset.rewardType=getRevealType();const color=typeof getRevealColor==='function'?getRevealColor():null;\r\n  if(color){dlg.style.setProperty('--pack',color);targetWorld?.setRevealColor(color);}\r\n };\r\n setTier(tier);dlg.dataset.phase=phase;\r\n dlg.tabIndex=-1;dlg.showModal();dlg.focus({preventScroll:true});\r\n // Fullscreen where allowed (not iOS Safari); the fixed 100vw x 100dvh dialog is the fallback.\r\n if(!fullscreenTried){fullscreenTried=true;try{dlg.requestFullscreen?.({navigationUI:'hide'})?.catch?.(()=>{});}catch{}}\r\n const leaveFullscreen=()=>{try{if(document.fullscreenElement)document.exitFullscreen().catch(()=>{});}catch{}};\r\n\r\n function exit(){\r\n  if(disposed)return;disposed=true;cancelAnimationFrame(raf);removeEventListener('resize',onResize);\r\n  world?.dispose();renderer?.dispose();renderer?.forceContextLoss?.();releaseGpu?.(renderer?.domElement);releaseGpu=null;leaveFullscreen();dlg.close();dlg.remove();style.remove();\r\n  try{onExit?.();}catch(error){console.error(error);}\r\n }\r\n const onResize=()=>world?.resize();addEventListener('resize',onResize);\r\n dlg.addEventListener('cancel',event=>{event.preventDefault();exit();});\r\n\r\n function showItems(list){\r\n  const wrap=$('[data-items]');wrap.replaceChildren();$('[data-eyebrow]').textContent=dlg.dataset.tier==='secret'?'SECRET':({texture:'Texture reward','multiple-colors':'Multiple colors','single-color':'Color reward'}[dlg.dataset.rewardType]||'Cosmetic rewards');\r\n  if(!list.length){const s=document.createElement('strong');s.textContent='Collection complete';const d=document.createElement('small');d.textContent='All cosmetics for your unlocked coaches are collected.';const item=document.createElement('div');item.className='drop-pod-item';item.append(s,d);wrap.append(item);}\r\n  for(const entry of list){\r\n   const item=document.createElement('div');item.className='drop-pod-item';const s=document.createElement('strong');s.textContent=`${entry.title} unlocked!`;const d=document.createElement('small');d.textContent=entry.detail||'';item.append(s,d);\r\n   if(entry.colors?.length){const sw=document.createElement('div');sw.className='drop-pod-swatches';for(const c of entry.colors){const i=document.createElement('i');i.style.background=c;sw.append(i);}item.append(sw);}\r\n   wrap.append(item);\r\n  }\r\n }\r\n function afterReveal(){\r\n  if(disposed||phase!=='reveal')return;\r\n  const next=$('[data-next]'),more=typeof hasNext==='function'?hasNext():!!hasNext;next.hidden=!more;\r\n  setTimeout(()=>{if(!disposed)(more?next:$('[data-exit]')).focus();},900);\r\n }\r\n\r\n async function tap(){\r\n  if(phase!=='landed'||!world||world.tapped)return;\r\n  const mine=gen;go('tap');dlg.classList.remove('ready');$('[data-error]').textContent='';world.tap();\r\n  let result=null;try{result=await open();}catch(error){console.error(error);}\r\n  if(disposed||mine!==gen)return;\r\n  if(!result){go('fail');world.cancelTap();dlg.classList.add('ready');$('[data-error]').textContent='Could not save this pack. Tap the pod to try again.';$('[data-hit]').focus();return;}\r\n  // The reward is now durably saved and granted. Color the reveal from that\r\n  // result while leaving the pod's already-played flight at its pack tier.\r\n  applyRewardPresentation(world);\r\n  items=result;world.release();\r\n }\r\n $('[data-hit]').onclick=tap;\r\n $('[data-exit]').onclick=exit;\r\n $('[data-next]').onclick=async()=>{\r\n  const nextConfig=await onNext?.();if(!nextConfig||disposed)return;\r\n  ({tier,open,hasNext,onNext}=nextConfig);getRevealType=nextConfig.revealType;getRevealColor=nextConfig.revealColor;go('restart');await begin();\r\n };\r\n // Skip: straight to the reveal. The pack still opens (once) through open().\r\n $('[data-skip]').onclick=async()=>{\r\n  if(!world||phase==='reveal')return;\r\n  if(phase==='opened'){world.skipToOpen();return;}\r\n  world.skipToPrompt();flash.classList.remove('go');\r\n  if(phase==='sky'||phase==='drop'){go('land');}\r\n  dlg.classList.remove('ready');await tap();\r\n  if(world&&!world.tapped)return;\r\n  world?.skipToOpen();\r\n };\r\n\r\n function frame(){\r\n  if(disposed)return;raf=requestAnimationFrame(frame);\r\n  world.update();\r\n  {const ps=world.podScreen(),hit=$('[data-hit]');hit.style.left=ps.x+'px';hit.style.top=ps.y+'px';hit.style.width=Math.min(innerWidth*.8,2.5*ps.k)+'px';hit.style.height=Math.min(innerHeight*.5,2.6*ps.k)+'px';}\r\n  if(phase==='sky'&&world.t>=world.tier.sky)go('fall');\r\n  if(world.landed&&(phase==='sky'||phase==='drop'))go('land');\r\n  if(phase==='landed'&&world.promptReady&&!dlg.classList.contains('ready')){dlg.classList.add('ready');$('[data-hit]').focus({preventScroll:true});}\r\n  if(phase==='opened'&&items&&worldRevealed){\r\n   showItems(items);items=null;go('revealed');afterReveal();\r\n  }\r\n }\r\n let worldRevealed=false;\r\n\r\n async function begin(){\r\n  const mine=++gen;dlg.classList.remove('ready');worldRevealed=false;items=null;setTier(tier);delete dlg.dataset.rewardType;dlg.dataset.phase=phase;$('[data-error]').textContent='';\r\n  world?.dispose();world=null;\r\n  if(!THREE){\r\n   try{THREE=await import('three');}catch(error){console.error(error);}\r\n   if(disposed)return;\r\n  }\r\n  if(mine!==gen)return;\r\n  if(!THREE){await fallbackReveal();return;}\r\n  if(!renderer){\r\n   // Full-screen: every other app renderer (3D coach, portal board) gives its context back until the pod closes.\r\n   if(!releaseGpu){releaseGpu=(await import('./modules/graphics-lifecycle.mjs')).claimGraphics('drop-pod');await releaseGpu.ready;if(disposed||mine!==gen)return;}\r\n   try{renderer=new THREE.WebGLRenderer({canvas:$('canvas'),antialias:true,alpha:false,powerPreference:'high-performance'});}catch(error){console.error(error);renderer=null;}\r\n   if(!renderer){await fallbackReveal();return;}\r\n   renderer.setPixelRatio(Math.min(devicePixelRatio||1,2));renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=1.15;\r\n  }\r\n  world=createWorld(THREE,renderer,tier,{reduced,onEvent:event=>{\r\n   if(event==='impact'&&!reduced){flash.classList.remove('go','pop');void flash.offsetWidth;flash.classList.add('go');}\r\n   if(event==='pop'&&!reduced&&!world.silent){flash.classList.remove('go','pop');void flash.offsetWidth;flash.classList.add('pop');}\r\n   if(event==='revealed')worldRevealed=true;\r\n  }});\r\n  if(reduced){world.skipToPrompt();}\r\n  loadGlb(THREE,TIERS[tier]?tier:'uncommon').then(model=>{if(model&&!disposed&&mine===gen&&world)world.useModel(model);});\r\n  cancelAnimationFrame(raf);raf=requestAnimationFrame(frame);\r\n }\r\n // No WebGL: skip the 3D and still open the pack, so a pack is never stuck.\r\n async function fallbackReveal(){\r\n  dlg.dataset.phase='landed';phase='landed';let result=null;try{result=await open();}catch(error){console.error(error);}\r\n  if(disposed)return;if(result)applyRewardPresentation(null);showItems(result||[]);phase='opened';go('revealed');afterReveal();\r\n }\r\n await begin();\r\n return {exit,state:()=>phase,get world(){return world;}};\r\n}\r\n","exercise-demo.mjs":"// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Schematic movement previews, with the selected supports/arm positions shown.\r\nexport function applyExerciseDemo(p,m,t){\r\n const slow=m.minCycle||m.dwell?1.1:2.1,q=(1-Math.cos(t*slow))/2;\r\n const armsUp=()=>{p.le=[-.29,.96,0];p.re=[.29,.96,0];p.lw=[-.23,1.37,0];p.rw=[.23,1.37,0];};\r\n const d=m.detector;\r\n if(d==='pushup'||d==='plank'){\r\n  const bend=d==='plank'?0:q,inc=m.incline?.45:0,lower=m.support==='knees';\r\n  for(const [side,z] of [['l',-.12],['r',.12]]){\r\n   p[side+'s']=[-.56,.04-bend*.27+inc,z];p[side+'h']=[.25,-.04+inc*.4,z];\r\n   p[side+'k']=[.58,lower?-.48:-.12,z];p[side+'a']=[.91,m.decline?.15:lower?-.38:-.28,z];\r\n   p[side+'w']=[-.58,-.51+inc,m.narrow?z*.2:m.wide?z*2.5:z];\r\n   p[side+'e']=m.forearm?[-.57,-.5,z]:[-.57+bend*.18,-.25-bend*.04+inc,z];\r\n  }\r\n  p.head=[-.85,.1-q*.27*(d==='pushup')+inc,0];p.neck=[-.68,.04-q*.27*(d==='pushup')+inc,0];\r\n }else if(d==='squat'||d==='split'){\r\n  const drop=(m.travel?.22:.4)*q;\r\n  for(const key of ['head','neck','ls','rs','le','re','lw','rw','lh','rh'])p[key][1]-=drop;\r\n  if(d==='split'){\r\n   const lead=m.side==='right'?'r':'l',back=lead==='l'?'r':'l';p[lead+'k']=[-.6,-.43-drop*.4,.04];p[lead+'a']=[-.6,-.95,.04];p[back+'k']=[.45,-.47-drop*.5,-.05];p[back+'a']=[.8,-.95,-.05];\r\n  }else{const width=m.wide?.34:.18;p.lk=[-width-.13*q,-.46-drop*.5,.25*q];p.rk=[width+.13*q,-.46-drop*.5,.25*q];p.la=[-width,-.95,0];p.ra=[width,-.95,0];}\r\n  p.le=[-.3,.24-drop,.25];p.re=[.3,.24-drop,.25];p.lw=[-.15,.36-drop,.4];p.rw=[.15,.36-drop,.4];\r\n }else if(d==='hinge'){\r\n  const bend=q*(m.bend?.45:.9),cos=Math.cos(bend),sin=Math.sin(bend);\r\n  for(const key of ['head','neck','ls','rs','le','re','lw','rw']){const y=p[key][1];p[key][1]=y*cos;p[key][2]=y*sin;}\r\n  if(m.arms==='chest'){p.lw=[.1,.37*cos,.37*sin+.1];p.rw=[-.1,.37*cos,.37*sin+.1];}\r\n }else if(d==='bridge'){\r\n  for(const [side,z] of [['l',-.14],['r',.14]]){p[side+'s']=[-.67,-.53,z];p[side+'h']=[0,-.5+q*.37,z];p[side+'k']=[.38,.02,z];p[side+'a']=[.66,-.53,z];p[side+'e']=[-.4,-.54,z*1.4];p[side+'w']=[-.1,-.54,z*1.7];}p.head=[-.93,-.47,0];p.neck=[-.78,-.5,0];\r\n }else if(d==='sideplank'){\r\n  const lower=m.side==='left'?'l':'r',upper=lower==='l'?'r':'l';\r\n  p[lower+'s']=[-.5,-.03,0];p[upper+'s']=[-.5,.32,0];p[lower+'h']=[.2,-.18,0];p[upper+'h']=[.2,.08,0];\r\n  p[lower+'e']=[-.5,-.3,0];p[lower+'w']=[-.48,-.55,0];p[upper+'e']=[-.5,.64,0];p[upper+'w']=[-.5,.96,0];\r\n  for(const side of [lower,upper]){p[side+'k']=[.57,-.31,side===lower?0:.08];p[side+'a']=[m.support==='knees'?.25:.94,-.53,side===lower?0:.08];}\r\n  p.neck=[-.65,.18,0];p.head=[-.87,.21,0];\r\n }else if(d==='raise'){\r\n  const a=q*(m.overhead?Math.PI:Math.PI/2);\r\n  for(const [side,sign] of [['l',-1],['r',1]])for(const [joint,length] of [['e',.36],['w',.73]])p[side+joint]=[sign*(.23+(m.plane==='front'?0:Math.sin(a)*length)),.57-Math.cos(a)*length,m.plane==='front'?Math.sin(a)*length:0];\r\n }else if(d==='press'){\r\n  for(const [side,sign] of [['l',-1],['r',1]]){p[side+'e']=[sign*(.56-.28*q),.53+.4*q,0];p[side+'w']=[sign*(.56-.31*q),.89+.43*q,0];}\r\n }else if(d==='balance'){\r\n  const lift=m.low?.15:.4;p.lk=[-.17-(m.kneeLift?0:.3),-.46+lift,m.kneeLift?.45:0];p.la=m.kneeLift?[-.17,-.63,.48]:[.12,m.low?-.78:-.4,0];\r\n  p.lw=[-.02,.45,.16];p.rw=[.02,.45,.16];p.le=[-.32,.22,.07];p.re=[.32,.22,.07];if(m.overhead)armsUp();\r\n }else if(d==='yoga'||d==='stance'){\r\n  const pose=m.pose??'horse';\r\n  if(pose==='salute')armsUp();\r\n  if(pose==='chair'){for(const key of ['head','neck','ls','rs','le','re','lw','rw','lh','rh'])p[key][1]-=.28;p.lk=[-.17,-.55,.3];p.rk=[.17,-.55,.3];armsUp();for(const key of ['le','re','lw','rw'])p[key][1]-=.28;}\r\n  if(pose==='wall-sit'){for(const key of ['head','neck','ls','rs','le','re','lw','rw','lh','rh'])p[key][1]-=.45;p.lk=[-.17,-.55,.45];p.rk=[.17,-.55,.45];}\r\n  if(['warrior','warrior-one'].includes(pose)||m.side){const lead=m.side==='right'?'r':'l',back=lead==='l'?'r':'l',sign=lead==='l'?-1:1;p[lead+'k']=[sign*.66,-.33,0];p[lead+'a']=[sign*.66,-.85,0];p[back+'k']=[-sign*.46,-.43,0];p[back+'a']=[-sign*.82,-.88,0];if(pose==='warrior'){p.le=[-.6,.57,0];p.re=[.6,.57,0];p.lw=[-.98,.57,0];p.rw=[.98,.57,0];}else if(pose==='warrior-one')armsUp();}\r\n  else if(pose==='horse'||pose==='goddess'){\r\n   const deep=m.high?.06:m.low?.35:.23;p.lk=[-.56,-.44+deep,0];p.rk=[.56,-.44+deep,0];p.la=[-.56,-.94+deep,0];p.ra=[.56,-.94+deep,0];\r\n   for(const v of Object.values(p))v[1]-=deep;\r\n   if(pose==='goddess'){p.le=[-.58,.48-deep,0];p.re=[.58,.48-deep,0];p.lw=[-.58,.84-deep,0];p.rw=[.58,.84-deep,0];}\r\n   else{p.lw=[-.06,.42-deep,.1];p.rw=[.06,.42-deep,.1];p.le=[-.34,.22-deep,0];p.re=[.34,.22-deep,0];}\r\n  }\r\n }else if(d==='boxing'){\r\n  for(const [side,sign,phase] of [['l',-1,Math.sin(t*(m.double?5:2.5))],['r',1,-Math.sin(t*2.5)]]){const punch=m.side&&m.side!==({l:'left',r:'right'}[side])?0:Math.max(0,phase);p[side+'e']=[sign*.28,.37+punch*.16,.2+punch*.22];p[side+'w']=[sign*.2,.55,.25+punch*.65];}p.la=[-.32,-.95,.1];p.ra=[.32,-.95,-.17];\r\n }else if(d==='march'){\r\n  for(const [side,sign,phase] of [['l',-1,Math.sin(t*(m.id==='jogging'?4:2))],['r',1,-Math.sin(t*(m.id==='jogging'?4:2))]]){const lift=Math.max(0,phase)*(m.lift?.48:m.id==='march'?.2:.32);p[side+'k']=[sign*.17,-.46+lift,lift];p[side+'a']=[sign*.17,-.95+lift,.06];p[side+'e']=[sign*.32,.22,-phase*.18];p[side+'w']=[sign*.27,.42,-phase*.32];}\r\n }else if(d==='jack'){\r\n  const swing=m.step?(1-Math.cos(t*2))/2:q;for(const [side,sign] of [['l',-1],['r',1]]){const a=swing*2.8;p[side+'e']=[sign*(.23+Math.sin(a)*.36),.57-Math.cos(a)*.36,0];p[side+'w']=[sign*(.23+Math.sin(a)*.73),.57-Math.cos(a)*.73,0];const step=!m.step||((Math.floor(t/Math.PI)%2===0)===(side==='l'));p[side+'a']=[sign*(.17+(step?.48*swing:0)),-.95,0];p[side+'k']=[sign*(.17+(step?.24*swing:0)),-.46,0];}\r\n }\r\n return p;\r\n}\r\n","exercise-gestures.mjs":"// Gesture proposals are separate from workout counting. Feet are never used.\r\nconst distance=(a,b)=>Math.hypot(a.x-b.x,a.y-b.y);\r\nexport function handShape(raw,aspect=1){\r\n if(!raw||raw.length<21||raw.some(p=>!Number.isFinite(p.x)||!Number.isFinite(p.y)||p.x<0||p.x>1||p.y<0||p.y>1))return null;\r\n const p=raw.map(v=>({x:v.x*aspect,y:v.y})),scale=distance(p[0],p[9]);if(scale<.025)return null;\r\n const extended=[8,12,16,20].map(tip=>distance(p[tip],p[0])>distance(p[tip-2],p[0])*1.25);\r\n const curled=[8,12,16,20].map(tip=>distance(p[tip],p[0])<distance(p[tip-2],p[0])*1.12);\r\n return {wrist:p[0],tip:p[8],base:p[6],fist:curled.every(Boolean),point:extended[0]&&curled.slice(1).every(Boolean),thumb:curled.every(Boolean)&&p[4].y<p[3].y-scale*.2&&p[4].y<p[5].y-scale*.35&&distance(p[4],p[0])>scale*1.15};\r\n}\r\nexport class ExerciseRecognizer {\r\n constructor(){this.pumpSide=0;this.pumps=[];this.last=0;}\r\n update(raw,hands,t,aspect=1){\r\n  const shapes=hands.map(h=>handShape(h,aspect)).filter(Boolean),thumb=shapes.some(h=>h.thumb);\r\n  if(t-this.last>850){this.pumps=[];this.pumpSide=0;}this.last=t;\r\n  if(!raw||raw.length<25)return {mode:null,thumb};\r\n  const p=raw.map(v=>({...v,x:v.x*aspect})),valid=ids=>ids.every(i=>p[i]&&p[i].visibility>=.5&&raw[i].x>=0&&raw[i].x<=1&&raw[i].y>=0&&raw[i].y<=1);\r\n  if(!valid([11,12,13,14,15,16,23,24]))return {mode:null,thumb};\r\n  const scale=(distance(p[11],p[23])+distance(p[12],p[24]))/2;if(scale<.06)return {mode:null,thumb};\r\n  const close=(a,b,n)=>distance(a,b)<scale*n;\r\n  for(const [s,e,w,otherW] of [[11,13,15,16],[12,14,16,15]]){\r\n   const target={x:(p[s].x+p[e].x)/2,y:(p[s].y+p[e].y)/2};\r\n   if(p[e].y<p[s].y+.12*scale&&p[w].y<p[s].y-.25*scale&&shapes.some(h=>h.point&&close(h.wrist,p[otherW],.65)&&close(h.tip,target,.75)&&distance(h.tip,target)<distance(h.base,target)))return {mode:'pushup',thumb};\r\n  }\r\n  const above=p[15].y<p[11].y-.45*scale&&p[16].y<p[12].y-.45*scale;\r\n  let mode=null;\r\n  if(above)mode=close(p[15],p[16],.5)?'tree':'jumping';\r\n  else if(close(p[15],p[23],.42)&&close(p[16],p[24],.42))mode='squat';\r\n  else if(Math.abs(p[15].y-p[11].y)<.25*scale&&Math.abs(p[16].y-p[12].y)<.25*scale&&Math.abs(p[15].x-p[16].x)>2.3*scale)mode='warrior';\r\n  else if(close(p[15],p[16],.35)&&p[15].y>Math.min(p[11].y,p[12].y)&&p[15].y<(p[11].y+p[23].y)/2)mode='horse';\r\n  else if(shapes.filter(h=>h.fist&&!h.thumb).length>=2&&close(p[15],p[11],.8)&&close(p[16],p[12],.8))mode='boxing';\r\n  const delta=(p[15].y-p[16].y)/scale,side=delta>.45?1:delta<-.45?-1:0;\r\n  if(side&&side!==this.pumpSide){this.pumpSide=side;this.pumps.push(t);}this.pumps=this.pumps.filter(n=>t-n<3000);\r\n  if(!mode&&this.pumps.length>=4)mode='jogging';\r\n  return {mode,thumb};\r\n }\r\n}\r\nexport class GestureConfirmation {\r\n constructor(){this.reset();}\r\n reset(){this.candidate=null;this.since=0;this.pending=null;this.expires=0;this.thumbSince=null;this.last=null;this.blocked=null;}\r\n update({mode=null,thumb=false},t){\r\n  const gap=this.last!==null&&t-this.last>850;this.last=t;\r\n  if(gap){this.candidate=null;this.thumbSince=null;}\r\n  if(!mode)this.blocked=null;\r\n  if(this.pending){\r\n   if(t>=this.expires){this.blocked=this.pending;this.pending=null;this.thumbSince=null;return {event:'expired',progress:0};}\r\n   if(thumb){this.thumbSince??=t;const progress=Math.min(1,(t-this.thumbSince)/1400);if(progress===1){const id=this.pending;this.reset();this.blocked=id;return {event:'confirmed',mode:id,progress:1};}return {event:'holding',mode:this.pending,progress};}\r\n   this.thumbSince=null;return {event:'pending',mode:this.pending,progress:0};\r\n  }\r\n  if(!mode||thumb||mode===this.blocked){this.candidate=null;return {event:'idle',progress:0};}\r\n  if(mode!==this.candidate){this.candidate=mode;this.since=t;}\r\n  if(t-this.since>=650){this.pending=mode;this.expires=t+12000;this.candidate=null;return {event:'proposed',mode,progress:0};}\r\n  return {event:'recognizing',mode,progress:0};\r\n }\r\n}\r\n","exercise-library.mjs":"// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Original movement recipes on MediaPipe landmarks. See movement-research.md.\r\n// Difficulty is a suggested progression, never a personal ability assessment.\r\nexport const FOCUS_GROUPS = [\r\n  {id:'chest',name:'Chest',description:'Push-up progressions'},\r\n  {id:'legs',name:'Legs',description:'Squats and split squats'},\r\n  {id:'hips',name:'Hips & glutes',description:'Hinges and bridges'},\r\n  {id:'core',name:'Core',description:'Plank holds'},\r\n  {id:'shoulders',name:'Shoulders',description:'Controlled arm movement'},\r\n  {id:'balance',name:'Balance',description:'Single-leg yoga holds'},\r\n  {id:'yoga',name:'Yoga',description:'Standing poses'},\r\n  {id:'stances',name:'Martial stances',description:'Controlled stance holds'},\r\n  {id:'boxing',name:'Boxing',description:'Slow shadowboxing'},\r\n  {id:'cardio',name:'Cardio',description:'Marches and jacks'}\r\n];\r\nconst rows=[];\r\nfunction add(group,id,name,detector,options={}){\r\n  const kind=options.kind??(['plank','sideplank','balance','yoga','stance'].includes(detector)?'hold':detector==='boxing'?'pace':detector==='march'?'steps':'reps');\r\n  const view=options.view??(['pushup','hinge','bridge','plank','split'].includes(detector)?'side':'front');\r\n  const measurement=kind==='hold'?'Pose hold':kind==='pace'?'Active hand time':kind==='steps'?'Knee lifts':'Repetitions';\r\n  const limits=options.limits??'Counts the visible movement; does not grade technique.';\r\n  const camera=view==='side'?'Camera beside you.':view==='angle'?'Camera at a slight angle.':'Face the camera.';\r\n  rows.push({id,group,name,detector,kind,view,measurement,limits,difficulty:rows.filter(r=>r.group===group).length+1,defaultGoal:kind==='hold'||kind==='pace'?15:5,evidence:'rule-based; camera validation pending',source:'mediapipe',...options,hint:`${camera} ${options.cue??'Keep the joints used for this movement visible.'}`});\r\n}\r\nconst pushLimits='Counts elbow bend and return. Hand shape, support stability and chest depth are not verified.';\r\nfor(const [id,name,extra] of [\r\n ['knee-pushup','Knee push-up',{support:'knees',cue:'Knees down; show shoulder, elbow, wrist and hip.'}],\r\n ['high-incline-pushup','High incline push-up',{incline:true,cue:'Hands on a stable high surface; show your full arm and torso.'}],\r\n ['low-incline-pushup','Low incline push-up',{incline:true,cue:'Hands on a stable lower surface; show your full arm and torso.'}],\r\n ['pushup','Regular push-up',{}],\r\n ['wide-pushup','Wide push-up',{wide:true}],\r\n ['slow-pushup','Slow push-up',{minCycle:1.2}],\r\n ['diamond-pushup','Diamond push-up',{narrow:true}],\r\n ['decline-pushup','Feet-elevated push-up',{decline:true,cue:'Feet on a stable low surface; show your full arm and torso.'}]\r\n])add('chest',id,name,'pushup',{cue:'Show shoulder, elbow, wrist and hip. Start with your arm extended.',limits:pushLimits,...extra});\r\nfor(const [id,name,extra] of [\r\n ['shallow-squat','Shallow squat',{travel:.18}],['squat','Bodyweight squat',{}],['wide-squat','Wide squat',{wide:true}],\r\n ['pause-squat','Pause squat',{dwell:.8}],['slow-squat','Slow squat',{minCycle:1.2}],\r\n ['split-left','Split squat · left',{detector:'split',side:'left'}],['split-right','Split squat · right',{detector:'split',side:'right'}],\r\n ['wall-sit','Wall sit',{detector:'yoga',pose:'wall-sit',kind:'hold',view:'side',cue:'Back on a wall, thighs level. Show shoulder, hip and knee.',limits:'Times the hip angle and thigh level. Wall contact and knee position are not tracked.'}]\r\n])add('legs',id,name,extra.detector??'squat',{cue:extra.side?'Show the front leg from hip to knee. Start tall.':'Show shoulders and hips. Start standing tall.',...extra});\r\nfor(const [id,name,detector,extra] of [\r\n ['small-hinge','Small hip hinge','hinge',{bend:25}],['hip-hinge','Hip hinge','hinge',{}],['good-morning','Bodyweight good morning','hinge',{arms:'chest'}],\r\n ['glute-bridge','Glute bridge','bridge',{}],['pause-bridge','Pause glute bridge','bridge',{dwell:.8}]\r\n])add('hips',id,name,detector,{cue:detector==='bridge'?'Lie on your back, knees bent. Show shoulder, hip and knee. Start with hips down.':'Show shoulder, hip and knee. Start upright; hinge slowly.',limits:'Tracks hip movement. Back curvature and muscle engagement are not verified.',...extra});\r\nfor(const [id,name,extra] of [\r\n ['knee-plank','Knee plank',{support:'knees'}],['high-plank','High plank',{}],['forearm-plank','Forearm plank',{forearm:true}],\r\n ['side-knee-left','Side knee plank · left',{side:'left',support:'knees'}],['side-knee-right','Side knee plank · right',{side:'right',support:'knees'}],\r\n ['side-plank-left','Side plank · left',{side:'left'}],['side-plank-right','Side plank · right',{side:'right'}]\r\n])add('core',id,name,extra.side?'sideplank':'plank',{view:extra.side?'front':'side',cue:extra.side?'Show both shoulders, hips and the supporting knee. Stack your shoulders.':'Show shoulder, elbow, wrist, hip and supporting knee.',limits:'Times the shoulder–hip–knee line. Feet, floor contact and loading are not tracked.',...extra});\r\nfor(const [id,name,detector,extra] of [\r\n ['front-raise','Front arm raise','raise',{view:'side',plane:'front'}],['lateral-raise','Lateral arm raise','raise',{}],\r\n ['overhead-reach','Overhead reach','raise',{overhead:true}],['standing-press','Standing arm press','press',{}],['slow-press','Slow arm press','press',{minCycle:1.2}]\r\n])add('shoulders',id,name,detector,{cue:'Keep both shoulders, elbows, wrists and hips visible. Use controlled, unloaded movement.',...extra});\r\nfor(const [id,name,extra] of [\r\n ['knee-balance','Knee-lift balance',{kneeLift:true}],['low-tree','Low tree pose',{low:true}],['tree','Tree pose',{}],['overhead-tree','Tree · arms overhead',{overhead:true}]\r\n])add('balance',id,name,'balance',{cue:'Show both hips and knees. Either leg works; keep a support nearby if needed.',limits:'Times the visible leg shape. Balance, foot pressure and support use are not verified.',...extra});\r\nfor(const [id,name,pose] of [['mountain','Mountain','mountain'],['salute','Upward salute','salute'],['chair','Chair pose','chair'],['warrior-one','Warrior I','warrior-one'],['warrior','Warrior II','warrior'],['goddess','Goddess pose','goddess']])\r\n add('yoga',id,name,'yoga',{pose,view:['chair','warrior-one'].includes(pose)?'side':'front',cue:'Show arms, hips and knees. Hold only a comfortable position.',limits:'Times broad pose shape. Foot rotation and joint alignment are not graded.'});\r\nfor(const [id,name,extra] of [['high-horse','High horse stance',{high:true}],['horse','Horse stance',{}],['low-horse','Lower horse stance',{low:true}],['front-stance-left','Front stance · left',{side:'left'}],['front-stance-right','Front stance · right',{side:'right'}]])\r\n add('stances',id,name,'stance',{view:extra.side?'side':'front',cue:'Keep hips and knees visible. Move slowly into a comfortable stance.',limits:'Times stance shape only. This is not martial-arts technique instruction.',...extra});\r\nfor(const [id,name,extra] of [['jab-left','Left straight practice',{side:'left'}],['jab-right','Right straight practice',{side:'right'}],['boxing','Alternating straights',{}],['double-jab','Double-jab practice',{double:true}]])\r\n add('boxing',id,name,'boxing',{view:'angle',cue:'Show shoulders, elbows, wrists and hips. Practice slow, controlled punches into empty space.',limits:'Tracks active hand time and relative pace. Punch type, power, accuracy and guard are not verified.',...extra});\r\nfor(const [id,name,detector,extra] of [['march','Easy march','march',{}],['high-march','High-knee march','march',{lift:.4}],['jogging','Cool Cardio','march',{lift:.08,runner:true,endless:true,cue:'Treadmill or in place: show your head, shoulders and arms. Run to move, both arms up to jump, crouch to slide, lean to switch lanes. Stop for 10 seconds and Coach catches you.'}],['step-jack','Step jack','jack',{step:true}],['jumping-jack','Jumping jack','jack',{}]])\r\n add('cardio',id,name,detector,{cue:detector==='jack'?'Show your upper body and knees. Start with arms down and knees close together.':'Show shoulders, hips and both knees. Start standing tall.',limits:detector==='jack'?'Counts arm-and-knee opening cycles. Feet, airtime and landings are not tracked.':'Counts knee lifts. Footfalls and impact are not verified.',...extra});\r\nexport const EXERCISES=Object.freeze(Object.fromEntries(rows.map(r=>[r.id,Object.freeze(r)])));\r\nexport const GROUP_EXERCISES=Object.freeze(Object.fromEntries(FOCUS_GROUPS.map(g=>[g.id,Object.freeze(rows.filter(r=>r.group===g.id))])));\r\nexport const EXERCISE_COUNT=rows.length;\r\nexport function focusFor(id){return EXERCISES[id]?.group??'cardio';}\r\nexport function exerciseAt(group,index){const choices=GROUP_EXERCISES[group]??GROUP_EXERCISES.chest;return choices[Math.max(0,Math.min(choices.length-1,Math.round(Number(index)||0)))];}\r\n","eye-styles.mjs":"// Eye styles (\"Expression\" in the Face tab). Plain JS so the recipe validator on the server shares it.\r\n// Every style is a free starter choice: expressions have never been part of the unlock catalogue.\r\nexport const EYE_STYLES=Object.freeze([\r\n ['open','Curious'],['sleepy','Unimpressed'],['wide','Wide awake'],\r\n ['anime','Anime'],['squinty','Squinty'],['bloodshot','Bloodshot'],['blind','Blind'],\r\n]);\r\nexport const EYE_STYLE_IDS=Object.freeze(EYE_STYLES.map(([id])=>id));\r\n","flight-score.mjs":"// Flight points belong to this arcade run, independently of workout XP and unlocks.\r\nexport function createFlightScore(){\r\n let hits=0,score=0,multiplier=1;\r\n const read=()=>({hits,score,multiplier});\r\n return {read,hit(){hits++;score+=multiplier;multiplier++;return read();},miss(){multiplier=1;return read();},reset(){hits=0;score=0;multiplier=1;return read();}};\r\n}\r\n","flight-scroll.mjs":"// Negative above the center, positive below it; quadratic acceleration at the edges.\r\nexport function flightScrollSpeed(clientY,top,height){\r\n if(!Number.isFinite(clientY)||!(height>0))return 0;\r\n const offset=Math.max(-1,Math.min(1,2*(clientY-top)/height-1));\r\n return Math.sign(offset)*offset*offset*1600;\r\n}\r\n\r\nexport function mountFlightScroll(viewport,{requestFrame=requestAnimationFrame,cancelFrame=cancelAnimationFrame,now=()=>performance.now()}={}){\r\n let pointerY=null,frame=0,last=0;\r\n const tick=time=>{\r\n  if(pointerY===null)return;\r\n  const rect=viewport.getBoundingClientRect(),dt=Math.min(50,Math.max(0,time-last));last=time;\r\n  viewport.scrollTop+=flightScrollSpeed(pointerY,rect.top,rect.height)*dt/1000;\r\n  frame=requestFrame(tick);\r\n };\r\n return {\r\n  aim(clientY){pointerY=clientY;if(!frame){last=now();frame=requestFrame(tick);}},\r\n  stop(){pointerY=null;if(frame)cancelFrame(frame);frame=0;},\r\n };\r\n}\r\n\r\n// R-1017 one achievements page: tuning knobs for real phones.\r\nexport const FLIGHT_TUNING={\r\n hyperMinMs:650,      // shortest hyper-speed jump\r\n hyperMaxMs:1700,     // longest jump (the whole 250-level route)\r\n hyperPxPerMs:28,     // cruise speed before the min/max clamp\r\n coachLine:.6,        // on open the golden coach's feet sit at this share of the screen; the ship rests just under them\r\n landLine:.5,         // a jumped-to section lands with its marker at this share of the screen\r\n};\r\n// Section menu: 0..chapters-1 are the flight systems (system 1 at the bottom of the page), the last one is the coaches.\r\nexport function flightSections(chapters){\r\n return [...Array.from({length:chapters},(_,chapter)=>({id:`system-${chapter+1}`,chapter})),{id:'coaches',chapter:null}];\r\n}\r\n// scrollTop that puts a point `y` px down the scroller's content at `line` of its height, clamped to the scroll range.\r\nexport function sectionScrollTop(y,viewportHeight,scrollHeight,line=FLIGHT_TUNING.landLine){\r\n return Math.round(Math.max(0,Math.min(scrollHeight-viewportHeight,y-viewportHeight*line)));\r\n}\r\nexport function hyperDuration(distance,t=FLIGHT_TUNING){\r\n return Math.round(Math.max(t.hyperMinMs,Math.min(t.hyperMaxMs,Math.abs(distance)/t.hyperPxPerMs)));\r\n}\r\n// Ease in-out (cubic): a punch out of the start, full warp in the middle, a brake into the section.\r\nexport const hyperEase=u=>u<.5?4*u*u*u:1-(-2*u+2)**3/2;\r\n","flip-display.css":".flip-display{--tile-width:48px;--tile-height:68px;--digit-size:51px;display:inline-flex;align-items:center;gap:5px;font:750 var(--digit-size)/1 ui-monospace,monospace;font-variant-numeric:tabular-nums;letter-spacing:-2px;color:#ffe4a6;vertical-align:middle}\r\n.flip-tile{position:relative;display:block;width:var(--tile-width);height:var(--tile-height);perspective:340px;border:1px solid #7d6584;border-radius:7px;background:#201529;box-shadow:0 4px 0 #130c1a,0 6px 9px #0b061970,inset 0 1px #fff2}\r\n.flip-tile:after{content:\"\";position:absolute;z-index:5;left:-2px;right:-2px;top:calc(50% - 1px);height:2px;background:#130c1a;box-shadow:-1px 0 #b4979c,1px 0 #b4979c;pointer-events:none}\r\n.flip-half{position:absolute;left:0;width:100%;height:50%;overflow:hidden;backface-visibility:hidden;transform-style:preserve-3d}\r\n.flip-half>span{position:absolute;left:0;display:flex;align-items:center;justify-content:center;width:100%;height:var(--tile-height)}\r\n.flip-top,.flip-falling{top:0;border-radius:6px 6px 0 0;background:linear-gradient(#45334c,#2c2034);transform-origin:50% 100%}\r\n.flip-bottom,.flip-landing{bottom:0;border-radius:0 0 6px 6px;background:linear-gradient(#39283f,#4a354c);transform-origin:50% 0}\r\n.flip-bottom>span,.flip-landing>span{bottom:0}\r\n.flip-falling,.flip-landing{display:none;z-index:3}\r\n.is-flipping .flip-falling{display:block;animation:flap-fall 180ms ease-in forwards}\r\n.is-flipping .flip-landing{display:block;animation:flap-land 200ms 180ms cubic-bezier(.15,.65,.25,1.15) both}\r\n.flip-colon{width:13px;text-align:center;color:#ae8faf;letter-spacing:0;font-size:32px;padding-bottom:6px}\r\n@keyframes flap-fall{to{transform:rotateX(-90deg);filter:brightness(.45)}}\r\n@keyframes flap-land{from{transform:rotateX(90deg);filter:brightness(.5)}to{transform:rotateX(0);filter:brightness(1)}}\r\n.simple-counter{gap:18px;flex-wrap:wrap;padding-top:12px}\r\n.simple-counter .counter-readout{min-width:0}\r\n.simple-counter #setNumber{font-size:11px;letter-spacing:1.8px;margin-bottom:9px}\r\n.simple-counter #primary{font-size:var(--digit-size);letter-spacing:-2px;color:#ffe4a6}\r\n.counter-target{display:flex;align-items:baseline;gap:7px;margin-top:11px;color:#bca5c8;font-size:13px}\r\n.counter-target #primaryLabel{font-size:14px;color:#e9d7eb}\r\n.counter-target #goalValue{font-size:14px;font-weight:600;letter-spacing:0;color:#e9d7eb}\r\n.counter-target .target-divider{width:1px;height:11px;background:#816389;margin:0 3px}\r\n.set-actions{flex:1;min-width:115px}.set-actions #stop{font-size:13px;min-height:40px}\r\n.rest-clock #restTime{--tile-width:32px;--tile-height:47px;--digit-size:32px;display:inline-flex;font:750 var(--digit-size)/1 ui-monospace,monospace;letter-spacing:-1px;margin-top:8px;gap:3px}\r\n.rest-clock .flip-colon{font-size:25px;width:8px}.rest-clock small{font-size:11px}\r\n.rest-bottom{flex-wrap:wrap}.rest-bottom>div:last-child{flex:1}\r\n@media(max-width:480px){.simple-counter .set-actions{flex-basis:100%;flex-direction:row;gap:10px}.set-actions .primary-action{flex:1}.set-actions #stop{min-width:70px}.flip-display{--tile-width:43px;--tile-height:61px;--digit-size:46px}.rest-bottom>div:last-child{min-width:125px}}\r\n@media(max-width:350px){.flip-display{--tile-width:39px;--tile-height:57px;--digit-size:42px}.rest-clock #restTime{--tile-width:29px;--tile-height:43px;--digit-size:29px}.rest-bottom{gap:12px}}\r\n@media(prefers-reduced-motion:reduce){.is-flipping .flip-falling{display:none}.is-flipping .flip-landing{display:block;transform:none}}\r\n","flip-display.mjs":"const displays=new WeakMap();\r\nconst whole=value=>Number.isFinite(Number(value))?Math.max(0,Math.floor(Number(value))):0;\r\nexport const countDigits=value=>String(whole(value)).padStart(2,'0');\r\nexport const clockDigits=value=>`${String(Math.floor(whole(value)/60)).padStart(2,'0')}:${String(whole(value)%60).padStart(2,'0')}`;\r\n\r\nfunction tile(character){\r\n const cell=document.createElement('span');\r\n cell.className=character===':'?'flip-colon':'flip-tile';\r\n if(character===':'){cell.textContent=character;return cell;}\r\n for(const name of ['top','bottom','falling','landing']){\r\n  const half=document.createElement('span'),ink=document.createElement('span');\r\n  half.className=`flip-half flip-${name}`;ink.textContent=character;half.append(ink);cell.append(half);\r\n }\r\n cell.value=character;\r\n return cell;\r\n}\r\nfunction settle(cell){\r\n clearTimeout(cell.timer);cell.classList.remove('is-flipping');\r\n for(const half of cell.children)half.firstChild.textContent=cell.value;\r\n}\r\nfunction turn(cell,next,animate){\r\n if(cell.value===next)return;\r\n settle(cell);const previous=cell.value;cell.value=next;\r\n if(!animate){settle(cell);return;}\r\n const [top,bottom,falling,landing]=cell.children;\r\n top.firstChild.textContent=landing.firstChild.textContent=next;\r\n bottom.firstChild.textContent=falling.firstChild.textContent=previous;\r\n // Restart only a changing digit; pose updates never restart the same second.\r\n void cell.offsetWidth;cell.classList.add('is-flipping');\r\n cell.timer=setTimeout(()=>settle(cell),420);\r\n}\r\nexport function setFlipValue(element,value,label=''){\r\n const text=String(value),format=text.includes(':')?'clock':'count';\r\n let state=displays.get(element);\r\n if(state?.text===text&&state.label===label)return;\r\n element.classList.add('flip-display');element.setAttribute('role','img');element.setAttribute('aria-label',`${text} ${label}`.trim());\r\n const animate=!globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches&&!document.hidden;\r\n if(!state||state.format!==format||state.text.length!==text.length){\r\n  const previous=state?.format===format&&format==='count'&&state.text.length<=text.length?state.text.padStart(text.length,'0'):text;\r\n  for(const cell of state?.cells||[])clearTimeout(cell.timer);\r\n  const cells=[...previous].map(tile);for(const cell of cells)cell.setAttribute('aria-hidden','true');\r\n  element.replaceChildren(...cells);state={cells,format};\r\n }\r\n [...text].forEach((character,index)=>{if(character!==':')turn(state.cells[index],character,animate);});\r\n state.text=text;state.label=label;displays.set(element,state);\r\n}\r\n","focus-library.css":"/* Movement library and hologram. The workout selector board lives in pod/control-board.css. */\r\n.workout-console .set-actions .primary-action{min-height:66px;justify-content:center}.set-actions .primary-action strong{font-size:18px}\r\n.library-filter{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:14px}\r\n.library-filter select{font:16px Arial,sans-serif;max-width:65%;padding:12px;color:#eefcf9;background:#21332f;border:1px solid #9ac7b9;border-radius:8px}\r\n#library [hidden]{display:none!important}\r\n#library[data-preview=true] .library-header,#library[data-preview=true] .library-filter,#library[data-preview=true] #libraryCount,#library[data-preview=true] .library-footer,#library[data-preview=true] .holo-tools,#library[data-preview=true] #hologramPanel>.library-caption{display:none}\r\n#library[data-preview=true] .glass-shell{min-height:100dvh;padding:16px;gap:0}\r\n#library[data-preview=true] #hologramPanel{min-height:calc(100dvh - 32px);gap:12px;position:relative}\r\n#library[data-preview=true] .holo-heading{position:relative;z-index:3;gap:14px}\r\n#library[data-preview=true] .holo-heading h2{margin:0;font:700 22px/1.3 Arial,sans-serif;color:#f2fff8}\r\n#library[data-preview=true] #backLibrary{min-width:44px;min-height:44px;padding:6px 12px;background:#112922d9}\r\n#library[data-preview=true] #holoStage{min-height:240px;max-height:340px;flex:1 0 240px;border-radius:18px}\r\n#library[data-preview=true] #useHologram{min-height:62px;font-size:20px;flex:none}\r\n.holo-setup{background:#fff0c9;color:#2c2533;border:2px solid #e0b778;border-radius:12px;padding:18px;font:16px/1.45 Arial,sans-serif;box-shadow:0 4px 0 #55384e}\r\n.holo-setup-block+.holo-setup-block{margin-top:18px;padding-top:16px;border-top:1px solid #a9916d}\r\n#library .holo-setup h3{font:700 13px/1.4 Arial,sans-serif;text-transform:uppercase;letter-spacing:1px;color:#61475c;margin:0 0 8px}\r\n#library .holo-setup p{margin:6px 0;color:#352a36}\r\n#library .holo-setup .holo-position{font-size:22px;line-height:1.25;font-weight:700}\r\n.holo-joints{display:flex;gap:7px;flex-wrap:wrap;padding:0;margin:10px 0;list-style:none}\r\n.holo-joints li{background:#412f4d;color:#fff2d8;border-radius:5px;padding:7px 10px;font-size:17px;font-weight:700}\r\n#library .holo-setup .holo-no-feet{border-top:1px solid #a9916d;padding-top:12px;margin-top:16px;font-weight:700;color:#31644d}\r\n@media(min-width:720px){#library[data-preview=true] #hologramPanel{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);grid-template-rows:auto 1fr auto;gap:18px;align-content:center}.holo-heading{grid-column:1/-1}#library[data-preview=true] #holoStage{grid-column:1;grid-row:2/4;min-height:420px;max-height:none}#library[data-preview=true] .holo-setup{grid-column:2;grid-row:2;align-self:center}#library[data-preview=true] #useHologram{grid-column:2;grid-row:3}}\r\n#library .card-kind,#library .card-number,#library .holo-link,#libraryCount{font-size:13px!important}\r\n#library .movement-cards{align-content:start}\r\n#library .movement-cards{flex:none;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px}\r\n#library .movement-card{padding:0;overflow:visible;border:0;background:none;box-shadow:none;backdrop-filter:none}\r\n#library .card-select{display:block;position:relative;padding:0!important;aspect-ratio:1;border:1px solid #aaf8e94d!important;border-radius:16px;overflow:hidden;background:radial-gradient(ellipse at 50% 85%,#69f9dd20,transparent 65%),#0c1720!important}\r\n#library .card-select img{display:block;width:100%;height:100%;object-fit:contain}\r\n#library .card-select[aria-pressed=true]{border-color:#9fffe8!important;box-shadow:inset 0 0 0 2px #9fffe8!important}\r\n#library .card-select:focus-visible{outline:3px solid #aaffef;outline-offset:3px}\r\n#library .library-header h1{margin:0}\r\n#library #gestureArea>summary{min-height:44px;display:flex;align-items:center;gap:8px;cursor:pointer;font:14px/1.4 Arial,sans-serif}\r\n#library #gestureArea>summary::before{content:'+';font-size:20px}\r\n#library #gestureArea[open]>summary::before{content:'−'}\r\n#library .holo-setup{padding:14px;font-size:14px}\r\n#library .holo-setup-block+.holo-setup-block{margin-top:12px;padding-top:12px}\r\n#library .holo-setup .holo-position{font-size:20px}\r\n#library .holo-joints li{font-size:14px;padding:6px 8px}\r\n#library .holo-no-feet{font-size:14px}\r\n.workout-console #status:empty,.launch-panel p:empty,.setup-shell p:empty,.install-card p:empty,.rest-feedback:empty{display:none}\r\n\r\n.app-update-banner,.reminders-moved{position:fixed;bottom:max(12px,env(safe-area-inset-bottom));left:12px;right:12px;z-index:9999;display:flex;gap:10px;flex-wrap:wrap;align-items:center;padding:16px;background:#163e34;color:#eefff5;border:2px solid #a6d4bb;border-radius:12px;box-shadow:0 8px 30px #0009;font:16px/1.4 Arial,sans-serif}.app-update-banner[hidden],.reminders-moved[hidden]{display:none}.app-update-banner button,.reminders-moved button{font:14px Arial,sans-serif;min-height:44px;padding:10px}.release-settings{margin-top:20px;border-top:1px solid #917885;padding-top:8px;font:16px/1.5 Arial,sans-serif}.release-settings li{margin:8px 0}.release-settings input{width:100%;padding:12px;font-size:16px}.release-settings button{min-height:44px;margin:8px 8px 8px 0}\r\n/* The reminders-moved notice (launch.mjs): one compact row at the top, above the pod's update banner (pod.css, top:128px). */\r\n.reminders-moved{top:max(12px,env(safe-area-inset-top));bottom:auto;flex-wrap:nowrap;padding:10px}.reminders-moved [data-on]{flex:1;text-align:left}\r\n.training-rewards{padding:10px 12px;margin:8px 0 12px;border:1px solid #729b9a;background:#14282dcc;color:#e5fff6}.training-rewards p{margin:0;font-size:1rem}.training-reward-weapons{display:flex;gap:20px;flex-wrap:wrap}.training-reward-weapons>div{display:flex;align-items:center;gap:8px;min-width:130px;font-size:.875rem}.training-reward-weapons canvas{width:30px;height:54px;image-rendering:pixelated}.training-rewards small{font-size:.875rem;color:#bcd7d3}\r\n.library-kind{display:flex;gap:12px;align-items:center;margin:12px 0}.library-kind select{min-height:44px;max-width:100%;font:inherit}.movement-card .card-select{height:auto;display:flex;flex-direction:column}.movement-level{display:block;padding:8px 10px;color:#fff;font-size:14px}#libraryEmpty{padding:18px;line-height:1.5}\r\n#library .movement-card .card-select{display:flex;flex-direction:column;aspect-ratio:auto;height:auto}#library .card-select img{height:auto;aspect-ratio:1}#library[data-preview=true] .library-kind{display:none}.library-kind select{padding:12px;color:#eefcf9;background:#21332f;border:1px solid #9ac7b9;border-radius:8px}\r\n\r\n/* Full-height hologram terminal: guidance is etched on the glass, below the figure. */\r\n#library[data-preview=true]{overflow:hidden}\r\n#library[data-preview=true] .glass-shell{height:100dvh;min-height:0;overflow:hidden;box-sizing:border-box;padding:10px 12px}\r\n#library[data-preview=true] #hologramPanel{display:flex;flex-direction:column;min-height:0;height:100%;gap:6px}\r\n#library[data-preview=true] .holo-heading{flex:none;min-height:44px;gap:8px}\r\n#library[data-preview=true] .holo-heading h2{font-size:clamp(15px,4vw,19px);line-height:1.2}\r\n#library[data-preview=true] #holoStage{position:relative;flex:1 1 auto;min-height:0;max-height:none;width:100%;border-radius:14px}\r\n#library[data-preview=true] #holoStage canvas{z-index:1}\r\n#library[data-preview=true] #holoStage .holo-setup{position:absolute;z-index:3;left:8px;right:8px;bottom:8px;display:grid;grid-template-columns:1fr 1fr;gap:5px 10px;padding:8px 10px;background:linear-gradient(90deg,#081e29ef,#0b2931e8);border:1px solid #7beed57d;border-radius:5px;box-shadow:0 0 16px #2bdac229;color:#bfffe9;font:11px/1.25 ui-monospace,SFMono-Regular,Consolas,monospace;pointer-events:none}\r\n#library[data-preview=true] #holoStage .holo-setup-block+.holo-setup-block{margin:0;padding:0;border:0}\r\n#library[data-preview=true] #holoStage .holo-setup h3{margin:0 0 3px;color:#58eac9;font:700 10px/1.2 ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:.08em}\r\n#library[data-preview=true] #holoStage .holo-setup p{margin:2px 0;color:#c9f8ef}\r\n#library[data-preview=true] #holoStage .holo-setup .holo-position{font-size:11px;line-height:1.25;color:#f0fff7}\r\n#library[data-preview=true] #holoStage .holo-joints{gap:3px;margin:2px 0 3px;padding:0}\r\n#library[data-preview=true] #holoStage .holo-joints li{padding:2px 4px;border:1px solid #73eac288;border-radius:2px;background:#07372e;color:#e0fff2;font:10px/1.15 ui-monospace,SFMono-Regular,Consolas,monospace}\r\n#library[data-preview=true] #holoStage .holo-no-feet{grid-column:1/-1;margin:0;padding:2px 0 0;border-top:1px solid #5ab8a966;font-size:10px;color:#91ebd1}\r\n#library[data-preview=true] #useHologram{flex:none;min-height:52px;font-size:18px}\r\n@media(min-width:720px){#library[data-preview=true] #hologramPanel{display:flex}#library[data-preview=true] #holoStage{grid-column:auto;grid-row:auto;min-height:0;max-height:none}#library[data-preview=true] #useHologram{grid-column:auto;grid-row:auto}}\r\n@media(max-height:700px){#library[data-preview=true] .glass-shell{padding:6px 10px}#library[data-preview=true] #hologramPanel{gap:4px}#library[data-preview=true] #useHologram{min-height:48px}#library[data-preview=true] #holoStage .holo-setup{padding:5px 7px;bottom:6px}#library[data-preview=true] #holoStage .holo-no-feet{display:none}}\r\n/* The shared portal housing stops above its hardware dock. Keep the terminal inside\r\n   that face and let only the movement card grid scroll on short phones. */\r\n#library[data-route]{overflow:hidden}\r\n#library[data-route] .glass-shell{box-sizing:border-box;height:100%;min-height:0}\r\n#library[data-route][data-preview=false] .movement-cards{flex:1 1 auto;min-height:0;overflow:auto;overscroll-behavior:contain}\r\n#library[data-route][data-preview=true] .glass-shell{height:100%;min-height:0}\r\n#library[data-route][data-preview=true] #hologramPanel{height:100%;min-height:0}\r\n\r\n/* Shared metal terminals leave room for Back and Begin on phone holograms. */\r\n#library.portal-framed.has-pod-chrome .glass-shell{padding-top:54px!important;padding-bottom:38px!important}\r\n","food-live.css":".food-panel .food-camera{display:flex;width:100%;gap:12px;min-height:72px;font-size:18px}\r\n.food-panel h3{margin:10px 0;font-size:18px}.food-panel form{gap:18px}.food-panel .macro-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}.food-panel .nutrient{min-width:0}.food-panel .macro-grid .nutrient{padding:14px 10px;border:1px solid #987d8b;border-radius:6px;background:#231d2b}.food-panel .nutrient span{display:block;font-size:14px;color:#e4d1df}.food-panel .nutrient output{display:block;font:700 20px/1.6 var(--pixel-font);color:#ffdaad;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.food-panel .micro-grid{display:grid;grid-template-columns:1fr 1fr;gap:0 22px}.food-panel .micro-grid .nutrient{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:9px 0;border-bottom:1px solid #96788666}.food-panel .micro-grid output{font-size:16px;text-align:right}.food-panel .nutrient-note,.food-panel .food-source{font-size:14px}.food-panel #mealConfirmation{display:grid;gap:12px}.food-panel summary{min-height:44px;align-content:center;cursor:pointer;font-size:14px}.food-panel #mealSaveControls>.main-action{width:100%;margin:14px 0 6px}.food-panel .manual-nutrition{grid-template-columns:1fr 1fr}.food-panel .scan-actions:has(>[hidden]):not(:has(>:not([hidden]))){display:none}.food-panel #mealStatus:empty{display:none}.food-panel #foodSuggestions button{font-size:14px}.food-panel .food-source{overflow-wrap:anywhere}.food-panel .saved-nutrients{display:grid;gap:8px;margin-top:10px}.food-panel .saved-nutrients p{font-size:14px;margin:0}.launch-panel .reminder-live{color:#d5edce;font-size:16px;font-variant-numeric:tabular-nums}.launch-panel .reminder-live[data-state=waiting]{color:#f1d1a6}.launch-panel .reminder-next{font-size:14px;color:#e7d49f}.launch-panel .reminder-tuning label{font-size:14px}.launch-panel .message-preview small{font-size:12px}\r\n@media(max-width:520px){.food-panel .macro-grid{grid-template-columns:1fr 1fr}.food-panel .micro-grid{gap:0 16px}.food-panel .micro-grid .nutrient{display:block}.food-panel .micro-grid output{text-align:left}.food-panel .macro-grid .nutrient{padding:10px}.food-panel .fields{grid-template-columns:minmax(0,1fr) 100px}}\r\n@media(max-width:340px){.food-panel .fields,.food-panel .manual-nutrition{grid-template-columns:1fr}.food-panel .micro-grid{column-gap:8px}}\r\n.food-panel .food-sheet{display:contents}.food-panel #cancelMeal{width:100%;margin:0 0 6px}.food-panel #foodDial{display:grid;gap:6px}.food-panel #foodDial:focus{outline:none}.food-panel .food-dial-head{display:flex;justify-content:space-between;align-items:center;gap:12px}.food-panel .food-dial-head h3{margin:0}.food-panel #foodDial p{margin:0}.food-panel .food-dial-big{font:700 26px/1.3 var(--pixel-font);color:#ffcd87;font-variant-numeric:tabular-nums}.food-panel .food-dial-list{margin:4px 0 0;padding:0;list-style:none;display:grid;gap:6px;font-size:15px}.food-panel .food-dial-list li{padding:8px 0;border-bottom:1px solid #59416680}\r\n/* #3 (W3-3A): the floating pyramid IS the Food menu. launch.mjs adds .pyramid-mode while the 3D scanner is up; the room\r\n   and pyramid fill the screen, and the photo flow, meal form and dial cards ride in a bottom sheet over the room. */\r\n#mealsPanel.pyramid-mode{position:fixed;inset:0;width:100%;height:100vh;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;border-radius:0;overflow:hidden;background:#bba16e}\r\n#mealsPanel.pyramid-mode>header{position:absolute;top:0;left:0;right:0;z-index:4;margin:0;padding:max(12px,env(safe-area-inset-top)) 16px 14px;background:linear-gradient(#21172ff0 62%,#21172f00)}\r\n#mealsPanel.pyramid-mode #pyramidScanner{position:absolute;inset:0;width:auto;height:auto;margin:0;border-radius:0}\r\n#mealsPanel.pyramid-mode #foodCamera,#mealsPanel.pyramid-mode #coachNutritionTargets,#mealsPanel.pyramid-mode:not([data-dial=today]) .recent-meals,#mealsPanel.pyramid-mode .food-sheet>:is(#foodStatus,#mealStatus):empty{display:none}\r\n#mealsPanel.pyramid-mode .food-sheet{position:absolute;left:0;right:0;bottom:0;z-index:3;display:flex;flex-direction:column;gap:8px;max-height:58%;overflow:auto;overscroll-behavior:contain;padding:0 12px max(12px,env(safe-area-inset-bottom));box-sizing:border-box;pointer-events:none}\r\n#mealsPanel.pyramid-mode .food-sheet>*{position:relative;z-index:1;margin:0;pointer-events:auto}\r\n#mealsPanel.pyramid-mode .food-sheet>:is(#foodDial,#foodStatus,#mealStatus,.recent-meals),#mealsPanel.pyramid-mode #mealForm:has(#mealConfirmation:not([hidden])){padding:12px 14px;border:1px solid #8b679c;border-radius:14px;background:#21172ff2;box-shadow:0 6px 24px #0007}\r\n#mealsPanel.pyramid-mode .food-sheet>:is(#foodStatus,#mealStatus){padding:8px 14px;color:#f4e7fb}\r\n#mealsPanel.pyramid-mode #mealForm{gap:10px}\r\n/* The Macros/Micros lists stay as the screen-reader copy of the numbers on the pyramid's screens. */\r\n#mealsPanel.pyramid-mode #mealForm>section{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\r\n/* #31: the lens opens the existing photo flow full screen, under the header and the sheet's controls. */\r\n#mealsPanel.pyramid-mode #mealScanStage{position:fixed;inset:0;z-index:0;margin:0;border:0;border-radius:0}\r\n#mealsPanel.pyramid-mode #mealScanStage .meal-preview{height:100%;max-height:none;min-height:0;margin:0;object-fit:cover}\r\n/* The scan read-out must show without the optional pocket-hardware.css skin (it only loads for unlocked accounts). */\r\n#mealsPanel.pyramid-mode .meal-scan-overlay{position:absolute;inset:0;pointer-events:none;color:#c3ffec;font:12px/1.5 var(--pixel-font,ui-monospace),monospace;text-shadow:0 1px 3px #000}\r\n#mealsPanel.pyramid-mode .scan-heading{position:absolute;left:12px;right:12px;top:calc(max(12px,env(safe-area-inset-top)) + 62px);display:flex;justify-content:space-between;gap:8px;letter-spacing:1px}\r\n#mealsPanel.pyramid-mode .scan-readout{position:absolute;left:12px;right:12px;top:calc(max(12px,env(safe-area-inset-top)) + 90px);bottom:auto;padding:8px 10px;border-left:2px solid #9dffe1;background:#001b21d9}\r\n#mealsPanel.pyramid-mode .scan-readout>span{display:block}\r\n#mealsPanel.pyramid-mode .scan-actions{justify-content:center}\r\n#mealsPanel.pyramid-mode #mealConfirmation{gap:8px}#mealsPanel.pyramid-mode #mealConfirmation .fields{gap:10px}#mealsPanel.pyramid-mode #mealForm input,#mealsPanel.pyramid-mode #mealForm select{padding:9px 11px}#mealsPanel.pyramid-mode #nutritionBasis{margin:0}\r\n#mealsPanel.pyramid-mode #mealSaveControls:not([hidden]){display:grid;grid-template-columns:1fr 1fr;gap:8px}#mealsPanel.pyramid-mode #mealSaveControls>:not(button){grid-column:1/-1}#mealsPanel.pyramid-mode #mealSaveControls>button{width:100%;margin:0}#mealsPanel.pyramid-mode .food-source{margin:0;font-size:12px}\r\n/* Release 5: as a route Food stops at the bottom bar's top edge (routes.mjs keeps the bar inside the open route); opened\r\n   from the portal it fits the metal frame's window (portal.css .portal-framed sets the box and --face-*), and so does the\r\n   full-screen photo flow. */\r\n#mealsPanel.pyramid-mode[data-route]{height:calc(100vh - var(--myr5-bar));height:calc(100dvh - var(--myr5-bar))}\r\n#mealsPanel.pyramid-mode[data-route] #mealScanStage{bottom:var(--myr5-bar)}\r\n#mealsPanel.pyramid-mode.portal-framed #mealScanStage{inset:auto;left:var(--face-left);top:var(--face-top);width:var(--face-width);height:var(--face-height)}\r\n","food-worker.mjs":"let classifier;\r\nconst MODEL='onnx-community/swin-finetuned-food101-ONNX',REVISION='e5e50bfc6425aa546f3b4421ca8bd79d0dd610b8';\r\nself.onmessage=async({data})=>{\r\n try{\r\n  if(!classifier){\r\n   postMessage({type:'progress',stage:'loading',text:'Loading the recognition model on your device…'});\r\n   // transformers.min.js is the self-contained browser build (onnxruntime bundled). transformers.web.js imports the\r\n   // bare specifiers \"onnxruntime-common\"/\"onnxruntime-web\" (a bundler input), which a browser worker cannot resolve.\r\n   const {pipeline,env}=await import('https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.8.1/dist/transformers.min.js');\r\n   env.allowLocalModels=false;env.backends.onnx.wasm.numThreads=1;\r\n   classifier=await pipeline('image-classification',MODEL,{revision:REVISION,device:'wasm',dtype:'q8',progress_callback:p=>{if(p.status==='progress'&&Number.isFinite(p.progress))postMessage({type:'progress',stage:'loading',progress:p.progress,text:`Model file download · ${Math.round(p.progress)}%`});}});\r\n  }\r\n  postMessage({type:'progress',stage:'analyzing',text:'Calculating image features and comparing food matches…'});\r\n  const ranked=await classifier(data.image,{top_k:4});\r\n  const uncertain=ranked[0].score<.5||ranked[0].score<2*ranked[1].score;\r\n  postMessage({type:'result',items:ranked[0].score<.2?[]:ranked.map(r=>({...r,label:r.label.replaceAll('_',' ')})),uncertain});\r\n }catch(error){console.warn('Food recognition failed',error);classifier=null;postMessage({type:'error',text:'Photo recognition could not finish. Try again on Wi-Fi or type the food name.'});}\r\n};\r\n","food/nutrition-fdc.json":"{\r\n \"apple pie\": {\r\n  \"fdcId\": 2707995,\r\n  \"description\": \"Pie, apple\",\r\n  \"servingName\": \"1 regular slice\",\r\n  \"servingG\": 150,\r\n  \"kcal\": 444,\r\n  \"proteinG\": 4.1,\r\n  \"fatG\": 22.9,\r\n  \"carbsG\": 56.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 43.5,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 60,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"baby back ribs\": {\r\n  \"fdcId\": 2705894,\r\n  \"description\": \"Pork, ribs\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 343,\r\n  \"proteinG\": 21.9,\r\n  \"fatG\": 20.4,\r\n  \"carbsG\": 16.4,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.69,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 1.08,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"baklava\": {\r\n  \"fdcId\": 2708044,\r\n  \"description\": \"Baklava\",\r\n  \"servingName\": \"1 piece\",\r\n  \"servingG\": 80,\r\n  \"kcal\": 352,\r\n  \"proteinG\": 5.3,\r\n  \"fatG\": 23.5,\r\n  \"carbsG\": 30,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 125.6,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.49,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"beef carpaccio\": {\r\n  \"fdcId\": 2705822,\r\n  \"description\": \"Beef, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 312,\r\n  \"proteinG\": 36.6,\r\n  \"fatG\": 17.6,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 3.08,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 9.45,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"beef tartare\": {\r\n  \"fdcId\": 2706394,\r\n  \"description\": \"Steak tartare\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 225,\r\n  \"kcal\": 486,\r\n  \"proteinG\": 39.3,\r\n  \"fatG\": 35.1,\r\n  \"carbsG\": 0.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 4.57,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 47.25,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"beet salad\": {\r\n  \"fdcId\": 2709875,\r\n  \"description\": \"Beets, fresh, cooked, fat added\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 175,\r\n  \"kcal\": 117,\r\n  \"proteinG\": 2.9,\r\n  \"fatG\": 4.9,\r\n  \"carbsG\": 16.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 162.75,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 7.35,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"beignets\": {\r\n  \"fdcId\": 2708071,\r\n  \"description\": \"Beignet\",\r\n  \"servingName\": \"3 beignets\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 563,\r\n  \"proteinG\": 7.4,\r\n  \"fatG\": 27.2,\r\n  \"carbsG\": 72.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 129.6,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.71,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"bibimbap\": {\r\n  \"fdcId\": 2708950,\r\n  \"description\": \"Bibimbap, Korean\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 162,\r\n  \"kcal\": 123,\r\n  \"proteinG\": 8.9,\r\n  \"fatG\": 4,\r\n  \"carbsG\": 13.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 183.06,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 17.01,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"bread pudding\": {\r\n  \"fdcId\": 2705680,\r\n  \"description\": \"Pudding, bread\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 200,\r\n  \"kcal\": 312,\r\n  \"proteinG\": 11.2,\r\n  \"fatG\": 9.7,\r\n  \"carbsG\": 47.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.44,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 154,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"breakfast burrito\": {\r\n  \"fdcId\": 170787,\r\n  \"description\": \"Fast foods, breakfast burrito, with egg, cheese, and sausage\",\r\n  \"servingName\": \"1 burrito\",\r\n  \"servingG\": 109,\r\n  \"kcal\": 302,\r\n  \"proteinG\": 12.1,\r\n  \"fatG\": 17,\r\n  \"carbsG\": 25,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.81,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 68.67,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"bruschetta\": {\r\n  \"fdcId\": 2707652,\r\n  \"description\": \"Bruschetta\",\r\n  \"servingName\": \"3 slices\",\r\n  \"servingG\": 129,\r\n  \"kcal\": 221,\r\n  \"proteinG\": 5.5,\r\n  \"fatG\": 9.8,\r\n  \"carbsG\": 27.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.27,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 58.05,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"caesar salad\": {\r\n  \"fdcId\": 2709591,\r\n  \"description\": \"Caesar salad, with romaine, no dressing\",\r\n  \"servingName\": \"1 Wendy's side salad\",\r\n  \"servingG\": 113,\r\n  \"kcal\": 87,\r\n  \"proteinG\": 4.5,\r\n  \"fatG\": 3.9,\r\n  \"carbsG\": 8.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 449.74,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 55.37,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"cannoli\": {\r\n  \"fdcId\": 2708029,\r\n  \"description\": \"Cream puff, eclair, custard or cream filled, NS as to icing\",\r\n  \"servingName\": \"1 cream puff (3-1/2\\\" x 2\\\")\",\r\n  \"servingG\": 112,\r\n  \"kcal\": 314,\r\n  \"proteinG\": 4.7,\r\n  \"fatG\": 27.3,\r\n  \"carbsG\": 12.4,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 266.56,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 31.36,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"caprese salad\": {\r\n  \"fdcId\": 2705818,\r\n  \"description\": \"Mozzarella cheese, tomato, and basil, with oil and vinegar dressing\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 222,\r\n  \"proteinG\": 11.5,\r\n  \"fatG\": 17.4,\r\n  \"carbsG\": 6.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.74,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 142.4,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"carrot cake\": {\r\n  \"fdcId\": 2707859,\r\n  \"description\": \"Cake or cupcake, carrot\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 120,\r\n  \"kcal\": 449,\r\n  \"proteinG\": 3,\r\n  \"fatG\": 21,\r\n  \"carbsG\": 62.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.25,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 120,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"ceviche\": {\r\n  \"fdcId\": 2706463,\r\n  \"description\": \"Ceviche\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 250,\r\n  \"kcal\": 158,\r\n  \"proteinG\": 26.3,\r\n  \"fatG\": 1.9,\r\n  \"carbsG\": 9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 3.75,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 12.75,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"cheesecake\": {\r\n  \"fdcId\": 2707861,\r\n  \"description\": \"Cheesecake, plain\",\r\n  \"servingName\": \"1 piece/slice, any size\",\r\n  \"servingG\": 175,\r\n  \"kcal\": 698,\r\n  \"proteinG\": 9.3,\r\n  \"fatG\": 46.4,\r\n  \"carbsG\": 60.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 386.75,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 36.75,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"cheese plate\": {\r\n  \"fdcId\": 2705709,\r\n  \"description\": \"Cheese, Cheddar\",\r\n  \"servingName\": \"1 cup, diced\",\r\n  \"servingG\": 132,\r\n  \"kcal\": 540,\r\n  \"proteinG\": 30.8,\r\n  \"fatG\": 44.9,\r\n  \"carbsG\": 3.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.4,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 417.12,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"chicken curry\": {\r\n  \"fdcId\": 2706437,\r\n  \"description\": \"Chicken curry\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 240,\r\n  \"kcal\": 257,\r\n  \"proteinG\": 15.6,\r\n  \"fatG\": 15.6,\r\n  \"carbsG\": 15.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 21.36,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.46,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"chicken quesadilla\": {\r\n  \"fdcId\": 2708593,\r\n  \"description\": \"Quesadilla, chicken\",\r\n  \"servingName\": \"1 full circle\",\r\n  \"servingG\": 140,\r\n  \"kcal\": 402,\r\n  \"proteinG\": 20.2,\r\n  \"fatG\": 18.2,\r\n  \"carbsG\": 38.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 75.6,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.35,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"chicken wings\": {\r\n  \"fdcId\": 2706060,\r\n  \"description\": \"Chicken wing, rotisserie\",\r\n  \"servingName\": \"4 pieces\",\r\n  \"servingG\": 140,\r\n  \"kcal\": 360,\r\n  \"proteinG\": 32.8,\r\n  \"fatG\": 25.3,\r\n  \"carbsG\": 0.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.63,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 36.4,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"chocolate cake\": {\r\n  \"fdcId\": 2707871,\r\n  \"description\": \"Cake, chocolate, flourless\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 120,\r\n  \"kcal\": 492,\r\n  \"proteinG\": 5.8,\r\n  \"fatG\": 35.3,\r\n  \"carbsG\": 45.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 214.8,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.24,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"chocolate mousse\": {\r\n  \"fdcId\": 168777,\r\n  \"description\": \"Desserts, mousse, chocolate, prepared-from-recipe\",\r\n  \"servingName\": \"0.5 cup\",\r\n  \"servingG\": 202,\r\n  \"kcal\": 455,\r\n  \"proteinG\": 8.4,\r\n  \"fatG\": 32.3,\r\n  \"carbsG\": 32.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.95,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 282.8,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"churros\": {\r\n  \"fdcId\": 2708070,\r\n  \"description\": \"Churros\",\r\n  \"servingName\": \"3 regulars\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 566,\r\n  \"proteinG\": 8.2,\r\n  \"fatG\": 30,\r\n  \"carbsG\": 66,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 143.1,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.92,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"clam chowder\": {\r\n  \"fdcId\": 2707138,\r\n  \"description\": \"Soup, Manhattan clam chowder\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 86,\r\n  \"proteinG\": 6.1,\r\n  \"fatG\": 1.2,\r\n  \"carbsG\": 12.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 3.09,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 11.27,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"club sandwich\": {\r\n  \"fdcId\": 2706993,\r\n  \"description\": \"Club sandwich on white\",\r\n  \"servingName\": \"1 sandwich, any size\",\r\n  \"servingG\": 130,\r\n  \"kcal\": 289,\r\n  \"proteinG\": 19.6,\r\n  \"fatG\": 9.7,\r\n  \"carbsG\": 30,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 66.3,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.38,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"crab cakes\": {\r\n  \"fdcId\": 2706549,\r\n  \"description\": \"Crab, cake\",\r\n  \"servingName\": \"1 cake or patty\",\r\n  \"servingG\": 85,\r\n  \"kcal\": 182,\r\n  \"proteinG\": 12.2,\r\n  \"fatG\": 12.7,\r\n  \"carbsG\": 3.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.03,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.31,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"creme brulee\": {\r\n  \"fdcId\": 2705684,\r\n  \"description\": \"Creme brulee\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 260,\r\n  \"kcal\": 294,\r\n  \"proteinG\": 10.6,\r\n  \"fatG\": 7.4,\r\n  \"carbsG\": 46.4,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.88,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 174.2,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"croque madame\": {\r\n  \"fdcId\": 2707335,\r\n  \"description\": \"Egg white sandwich, with cheese\",\r\n  \"servingName\": \"1 regular\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 265,\r\n  \"proteinG\": 15,\r\n  \"fatG\": 10.1,\r\n  \"carbsG\": 28.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 60.75,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.36,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"cup cakes\": {\r\n  \"fdcId\": 2707853,\r\n  \"description\": \"Cake or cupcake, NFS\",\r\n  \"servingName\": \"1 piece/slice, any size\",\r\n  \"servingG\": 175,\r\n  \"kcal\": 616,\r\n  \"proteinG\": 5,\r\n  \"fatG\": 25.8,\r\n  \"carbsG\": 93.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.52,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 38.5,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"deviled eggs\": {\r\n  \"fdcId\": 2707181,\r\n  \"description\": \"Egg, deviled\",\r\n  \"servingName\": \"5 eggs\",\r\n  \"servingG\": 150,\r\n  \"kcal\": 297,\r\n  \"proteinG\": 17.3,\r\n  \"fatG\": 23.9,\r\n  \"carbsG\": 1.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.53,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 205.5,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"donuts\": {\r\n  \"fdcId\": 2708062,\r\n  \"description\": \"Doughnut, NFS\",\r\n  \"servingName\": \"1 doughnut\",\r\n  \"servingG\": 75,\r\n  \"kcal\": 320,\r\n  \"proteinG\": 4.1,\r\n  \"fatG\": 17.1,\r\n  \"carbsG\": 37.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 72,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.22,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"dumplings\": {\r\n  \"fdcId\": 2706543,\r\n  \"description\": \"Chicken or turkey with dumplings\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 244,\r\n  \"kcal\": 351,\r\n  \"proteinG\": 38.3,\r\n  \"fatG\": 13.5,\r\n  \"carbsG\": 19.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.56,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 39.04,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"edamame\": {\r\n  \"fdcId\": 2707436,\r\n  \"description\": \"Edamame, cooked\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 224,\r\n  \"proteinG\": 18.5,\r\n  \"fatG\": 12.1,\r\n  \"carbsG\": 13.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 457.6,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.66,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"eggs benedict\": {\r\n  \"fdcId\": 2707180,\r\n  \"description\": \"Egg, Benedict\",\r\n  \"servingName\": \"1 egg\",\r\n  \"servingG\": 155,\r\n  \"kcal\": 446,\r\n  \"proteinG\": 21.4,\r\n  \"fatG\": 34.3,\r\n  \"carbsG\": 13.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 359.6,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.76,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"escargots\": {\r\n  \"fdcId\": 167744,\r\n  \"description\": \"Mollusks, snail, raw\",\r\n  \"servingName\": \"3 oz\",\r\n  \"servingG\": 85,\r\n  \"kcal\": 77,\r\n  \"proteinG\": 13.7,\r\n  \"fatG\": 1.2,\r\n  \"carbsG\": 1.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 4.25,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.43,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"falafel\": {\r\n  \"fdcId\": 2707408,\r\n  \"description\": \"Falafel\",\r\n  \"servingName\": \"9 patties\",\r\n  \"servingG\": 153,\r\n  \"kcal\": 786,\r\n  \"proteinG\": 12.7,\r\n  \"fatG\": 63,\r\n  \"carbsG\": 44.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 11.84,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 120.87,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"filet mignon\": {\r\n  \"fdcId\": 2705829,\r\n  \"description\": \"Beef, steak, ribeye, lean and fat eaten\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 390,\r\n  \"proteinG\": 31.7,\r\n  \"fatG\": 29.2,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.81,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 8.1,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"fish and chips\": {\r\n  \"fdcId\": 2706244,\r\n  \"description\": \"Fish, cod, fried\",\r\n  \"servingName\": \"1 small/regular fillet\",\r\n  \"servingG\": 140,\r\n  \"kcal\": 304,\r\n  \"proteinG\": 18.9,\r\n  \"fatG\": 17.5,\r\n  \"carbsG\": 16.4,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.93,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.72,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"foie gras\": {\r\n  \"fdcId\": 172929,\r\n  \"description\": \"Pate, goose liver, smoked, canned\",\r\n  \"servingName\": \"5 oz\",\r\n  \"servingG\": 142,\r\n  \"kcal\": 656,\r\n  \"proteinG\": 16.2,\r\n  \"fatG\": 62.3,\r\n  \"carbsG\": 6.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 13.35,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 1421.42,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"french fries\": {\r\n  \"fdcId\": 2709456,\r\n  \"description\": \"Potato, french fries, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 60,\r\n  \"kcal\": 135,\r\n  \"proteinG\": 1.5,\r\n  \"fatG\": 8.4,\r\n  \"carbsG\": 13.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.25,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 4.68,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"french onion soup\": {\r\n  \"fdcId\": 2710108,\r\n  \"description\": \"Soup, French onion\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 265,\r\n  \"proteinG\": 13.4,\r\n  \"fatG\": 11,\r\n  \"carbsG\": 29,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.47,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 61.25,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"french toast\": {\r\n  \"fdcId\": 2708331,\r\n  \"description\": \"French toast, NFS\",\r\n  \"servingName\": \"1 slice, any size\",\r\n  \"servingG\": 65,\r\n  \"kcal\": 177,\r\n  \"proteinG\": 6.7,\r\n  \"fatG\": 7.4,\r\n  \"carbsG\": 21,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 45.5,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.27,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"fried calamari\": {\r\n  \"fdcId\": 171982,\r\n  \"description\": \"Mollusks, squid, mixed species, cooked, fried\",\r\n  \"servingName\": \"3 oz\",\r\n  \"servingG\": 85,\r\n  \"kcal\": 149,\r\n  \"proteinG\": 15.2,\r\n  \"fatG\": 6.4,\r\n  \"carbsG\": 6.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.05,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 3.57,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"fried rice\": {\r\n  \"fdcId\": 2708951,\r\n  \"description\": \"Rice, fried, meatless\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 166,\r\n  \"kcal\": 289,\r\n  \"proteinG\": 6.4,\r\n  \"fatG\": 5.3,\r\n  \"carbsG\": 54,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 6.31,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 36.52,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"frozen yogurt\": {\r\n  \"fdcId\": 2705451,\r\n  \"description\": \"Frozen yogurt, NFS\",\r\n  \"servingName\": \"1 scoop\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 203,\r\n  \"proteinG\": 4.8,\r\n  \"fatG\": 5.8,\r\n  \"carbsG\": 34.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 78.4,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.11,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"garlic bread\": {\r\n  \"fdcId\": 2707626,\r\n  \"description\": \"Garlic bread, NFS\",\r\n  \"servingName\": \"1 mini baguette (about 9\\\" long)\",\r\n  \"servingG\": 185,\r\n  \"kcal\": 646,\r\n  \"proteinG\": 15.4,\r\n  \"fatG\": 30.7,\r\n  \"carbsG\": 77,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 308.95,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.18,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"gnocchi\": {\r\n  \"fdcId\": 2708721,\r\n  \"description\": \"Gnocchi, cheese\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 70,\r\n  \"kcal\": 125,\r\n  \"proteinG\": 6,\r\n  \"fatG\": 8.4,\r\n  \"carbsG\": 6.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 92.4,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.22,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"greek salad\": {\r\n  \"fdcId\": 2709830,\r\n  \"description\": \"Greek Salad, no dressing\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 105,\r\n  \"kcal\": 50,\r\n  \"proteinG\": 2.9,\r\n  \"fatG\": 2.4,\r\n  \"carbsG\": 4.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 252,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 37.8,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"grilled cheese sandwich\": {\r\n  \"fdcId\": 2705794,\r\n  \"description\": \"Cheese sandwich, NFS\",\r\n  \"servingName\": \"1 sandwich\",\r\n  \"servingG\": 102,\r\n  \"kcal\": 303,\r\n  \"proteinG\": 12.7,\r\n  \"fatG\": 13.6,\r\n  \"carbsG\": 32.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.62,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 72.42,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"grilled salmon\": {\r\n  \"fdcId\": 2706284,\r\n  \"description\": \"Fish, salmon, raw\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 254,\r\n  \"proteinG\": 27.6,\r\n  \"fatG\": 15.1,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 4.67,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 14.85,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"guacamole\": {\r\n  \"fdcId\": 2709307,\r\n  \"description\": \"Guacamole, NFS\",\r\n  \"servingName\": \"2 tablespoon\",\r\n  \"servingG\": 30,\r\n  \"kcal\": 47,\r\n  \"proteinG\": 0.6,\r\n  \"fatG\": 4.3,\r\n  \"carbsG\": 2.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 23.7,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 0.6,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"gyoza\": {\r\n  \"fdcId\": 2708705,\r\n  \"description\": \"Wonton, dumpling or pot sticker, fried\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 75,\r\n  \"kcal\": 144,\r\n  \"proteinG\": 6.6,\r\n  \"fatG\": 8.3,\r\n  \"carbsG\": 10.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.21,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 6.6,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"hamburger\": {\r\n  \"fdcId\": 2706920,\r\n  \"description\": \"Hamburger, NFS\",\r\n  \"servingName\": \"1 hamburger\",\r\n  \"servingG\": 145,\r\n  \"kcal\": 418,\r\n  \"proteinG\": 25.4,\r\n  \"fatG\": 20.9,\r\n  \"carbsG\": 30,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.36,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 73.95,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"hot and sour soup\": {\r\n  \"fdcId\": 2707136,\r\n  \"description\": \"Soup, hot and sour\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 96,\r\n  \"proteinG\": 6.3,\r\n  \"fatG\": 3,\r\n  \"carbsG\": 10.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.25,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 0.96,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"hot dog\": {\r\n  \"fdcId\": 2706757,\r\n  \"description\": \"Frankfurters or hot dogs and sauerkraut\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 147,\r\n  \"kcal\": 291,\r\n  \"proteinG\": 11.1,\r\n  \"fatG\": 25.4,\r\n  \"carbsG\": 5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.75,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 7.5,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"huevos rancheros\": {\r\n  \"fdcId\": 2707191,\r\n  \"description\": \"Huevos rancheros\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 163,\r\n  \"proteinG\": 9,\r\n  \"fatG\": 9,\r\n  \"carbsG\": 11.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.5,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.05,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"hummus\": {\r\n  \"fdcId\": 2707402,\r\n  \"description\": \"Hummus, plain\",\r\n  \"servingName\": \"2 tablespoon\",\r\n  \"servingG\": 30,\r\n  \"kcal\": 73,\r\n  \"proteinG\": 2.2,\r\n  \"fatG\": 5.1,\r\n  \"carbsG\": 4.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 0.52,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 10.8,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"ice cream\": {\r\n  \"fdcId\": 2705629,\r\n  \"description\": \"Ice cream, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 298,\r\n  \"proteinG\": 4.8,\r\n  \"fatG\": 15.3,\r\n  \"carbsG\": 35.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.51,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 151.2,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"lasagna\": {\r\n  \"fdcId\": 2708750,\r\n  \"description\": \"Lasagna with meat\",\r\n  \"servingName\": \"1 piece (1/6 of 8\\\" square, approx 2-1/2\\\" x 4\\\")\",\r\n  \"servingG\": 206,\r\n  \"kcal\": 286,\r\n  \"proteinG\": 15.3,\r\n  \"fatG\": 10.2,\r\n  \"carbsG\": 33.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.71,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.02,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"lobster bisque\": {\r\n  \"fdcId\": 2707140,\r\n  \"description\": \"Soup, bisque\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 255,\r\n  \"kcal\": 191,\r\n  \"proteinG\": 5.8,\r\n  \"fatG\": 12.3,\r\n  \"carbsG\": 15,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.38,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 255,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"lobster roll sandwich\": {\r\n  \"fdcId\": 2706825,\r\n  \"description\": \"Lobster salad\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 182,\r\n  \"kcal\": 340,\r\n  \"proteinG\": 18.7,\r\n  \"fatG\": 28,\r\n  \"carbsG\": 2.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.4,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.28,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"macaroni and cheese\": {\r\n  \"fdcId\": 2708811,\r\n  \"description\": \"Macaroni or noodles with cheese\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 230,\r\n  \"kcal\": 513,\r\n  \"proteinG\": 20,\r\n  \"fatG\": 24.2,\r\n  \"carbsG\": 53.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 243.8,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.62,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"macarons\": {\r\n  \"fdcId\": 2707941,\r\n  \"description\": \"Cookie, meringue\",\r\n  \"servingName\": \"12 cookies\",\r\n  \"servingG\": 60,\r\n  \"kcal\": 210,\r\n  \"proteinG\": 3.4,\r\n  \"fatG\": 0.2,\r\n  \"carbsG\": 48.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.02,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 1.2,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"miso soup\": {\r\n  \"fdcId\": 2707455,\r\n  \"description\": \"Soup, miso or tofu\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 59,\r\n  \"proteinG\": 5.4,\r\n  \"fatG\": 2.1,\r\n  \"carbsG\": 5.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 29.4,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 4.66,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"mussels\": {\r\n  \"fdcId\": 2706350,\r\n  \"description\": \"Mussels\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 147,\r\n  \"proteinG\": 20.3,\r\n  \"fatG\": 3.8,\r\n  \"carbsG\": 6.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 17.43,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 54,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"nachos\": {\r\n  \"fdcId\": 2708576,\r\n  \"description\": \"Nachos, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 358,\r\n  \"proteinG\": 10.3,\r\n  \"fatG\": 21.4,\r\n  \"carbsG\": 32.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.57,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.92,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"omelette\": {\r\n  \"fdcId\": 2707198,\r\n  \"description\": \"Egg omelet or scrambled egg, NS as to fat\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 250,\r\n  \"proteinG\": 15.6,\r\n  \"fatG\": 20.3,\r\n  \"carbsG\": 1.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.03,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 260.55,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"onion rings\": {\r\n  \"fdcId\": 2708245,\r\n  \"description\": \"Onion flavored rings\",\r\n  \"servingName\": \"1 large single serving bag\",\r\n  \"servingG\": 85,\r\n  \"kcal\": 424,\r\n  \"proteinG\": 6.5,\r\n  \"fatG\": 19.2,\r\n  \"carbsG\": 55.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 93.5,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.29,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"oysters\": {\r\n  \"fdcId\": 2706351,\r\n  \"description\": \"Oysters, raw\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 225,\r\n  \"kcal\": 115,\r\n  \"proteinG\": 12.8,\r\n  \"fatG\": 3.8,\r\n  \"carbsG\": 6.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 19.69,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.91,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"pad thai\": {\r\n  \"fdcId\": 2708804,\r\n  \"description\": \"Pad Thai, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 200,\r\n  \"kcal\": 308,\r\n  \"proteinG\": 16.3,\r\n  \"fatG\": 15,\r\n  \"carbsG\": 28.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.26,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 48,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"paella\": {\r\n  \"fdcId\": 2706711,\r\n  \"description\": \"Paella with seafood\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 240,\r\n  \"kcal\": 343,\r\n  \"proteinG\": 19.3,\r\n  \"fatG\": 11.4,\r\n  \"carbsG\": 39.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.98,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 25.44,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"pancakes\": {\r\n  \"fdcId\": 2708294,\r\n  \"description\": \"Pancakes, NFS\",\r\n  \"servingName\": \"1 extra large pancake\",\r\n  \"servingG\": 150,\r\n  \"kcal\": 423,\r\n  \"proteinG\": 11.1,\r\n  \"fatG\": 18.1,\r\n  \"carbsG\": 53,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.57,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.72,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"panna cotta\": {\r\n  \"fdcId\": 2705682,\r\n  \"description\": \"Custard\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 260,\r\n  \"kcal\": 252,\r\n  \"proteinG\": 13.2,\r\n  \"fatG\": 9.5,\r\n  \"carbsG\": 28.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.07,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 213.2,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n },\r\n \"peking duck\": {\r\n  \"fdcId\": 2706141,\r\n  \"description\": \"Duck, Peking\",\r\n  \"servingName\": \"1 cup, diced, cooked\",\r\n  \"servingG\": 140,\r\n  \"kcal\": 216,\r\n  \"proteinG\": 7.4,\r\n  \"fatG\": 16.5,\r\n  \"carbsG\": 9.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 17.08,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.29,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"pho\": {\r\n  \"fdcId\": 2707124,\r\n  \"description\": \"Soup, pho, with meat\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 189,\r\n  \"proteinG\": 14.2,\r\n  \"fatG\": 8.2,\r\n  \"carbsG\": 13.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.25,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 14.7,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"pizza\": {\r\n  \"fdcId\": 2708614,\r\n  \"description\": \"Pizza, cheese, from restaurant or fast food, NS as to type of crust\",\r\n  \"servingName\": \"1 personal size pizza (5-7\\\" diameter)\",\r\n  \"servingG\": 175,\r\n  \"kcal\": 466,\r\n  \"proteinG\": 19.9,\r\n  \"fatG\": 17,\r\n  \"carbsG\": 58.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 162.75,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.74,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"pork chop\": {\r\n  \"fdcId\": 2705866,\r\n  \"description\": \"Pork, chop, NS as to fat eaten\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 247,\r\n  \"proteinG\": 37.1,\r\n  \"fatG\": 10.2,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.82,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 0.81,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"poutine\": {\r\n  \"fdcId\": 2709456,\r\n  \"description\": \"Potato, french fries, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 60,\r\n  \"kcal\": 135,\r\n  \"proteinG\": 1.5,\r\n  \"fatG\": 8.4,\r\n  \"carbsG\": 13.9,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.25,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 4.68,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"prime rib\": {\r\n  \"fdcId\": 168679,\r\n  \"description\": \"Beef, rib, whole (ribs 6-12), separable lean and fat, trimmed to 1/8\\\" fat, prime, cooked, roasted\",\r\n  \"servingName\": \"3 oz\",\r\n  \"servingG\": 85,\r\n  \"kcal\": 340,\r\n  \"proteinG\": 19.2,\r\n  \"fatG\": 28.6,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.18,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 5.95,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"pulled pork sandwich\": {\r\n  \"fdcId\": 173344,\r\n  \"description\": \"Pulled pork in barbecue sauce\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 249,\r\n  \"kcal\": 418,\r\n  \"proteinG\": 32.8,\r\n  \"fatG\": 11,\r\n  \"carbsG\": 46.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.02,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.22,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"ramen\": {\r\n  \"fdcId\": 2709153,\r\n  \"description\": \"Ramen bowl, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 245,\r\n  \"kcal\": 311,\r\n  \"proteinG\": 17.5,\r\n  \"fatG\": 11.2,\r\n  \"carbsG\": 34.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.78,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 112.7,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"ravioli\": {\r\n  \"fdcId\": 2708760,\r\n  \"description\": \"Ravioli, NS as to filling, no sauce\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 296,\r\n  \"proteinG\": 16.5,\r\n  \"fatG\": 11.2,\r\n  \"carbsG\": 31.8,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.02,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 60.8,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"red velvet cake\": {\r\n  \"fdcId\": 2707884,\r\n  \"description\": \"Cake or cupcake, red velvet\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 120,\r\n  \"kcal\": 426,\r\n  \"proteinG\": 3.3,\r\n  \"fatG\": 17.5,\r\n  \"carbsG\": 65.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.39,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 27.6,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"risotto\": {\r\n  \"fdcId\": 2708403,\r\n  \"description\": \"Rice, white, cooked, NS as to fat\",\r\n  \"servingName\": \"1 cup, cooked\",\r\n  \"servingG\": 163,\r\n  \"kcal\": 210,\r\n  \"proteinG\": 4.4,\r\n  \"fatG\": 0.5,\r\n  \"carbsG\": 45.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 94.54,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 0.07,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"samosa\": {\r\n  \"fdcId\": 2708730,\r\n  \"description\": \"Samosa\",\r\n  \"servingName\": \"1 regular/large\",\r\n  \"servingG\": 100,\r\n  \"kcal\": 310,\r\n  \"proteinG\": 5.1,\r\n  \"fatG\": 17.5,\r\n  \"carbsG\": 33.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 2.38,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 44,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"sashimi\": {\r\n  \"fdcId\": 2706223,\r\n  \"description\": \"Fish, raw\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 127,\r\n  \"proteinG\": 23.2,\r\n  \"fatG\": 3.2,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.94,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 1.76,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"scallops\": {\r\n  \"fdcId\": 2706357,\r\n  \"description\": \"Scallops, grilled\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 146,\r\n  \"proteinG\": 20.7,\r\n  \"fatG\": 3.9,\r\n  \"carbsG\": 5.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.05,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 20.25,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"seaweed salad\": {\r\n  \"fdcId\": 2710100,\r\n  \"description\": \"Seaweed, pickled\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 100,\r\n  \"kcal\": 54,\r\n  \"proteinG\": 2.9,\r\n  \"fatG\": 0.4,\r\n  \"carbsG\": 11.4,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 108,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 8.7,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"shrimp and grits\": {\r\n  \"fdcId\": 2706360,\r\n  \"description\": \"Shrimp, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 197,\r\n  \"proteinG\": 20.9,\r\n  \"fatG\": 9,\r\n  \"carbsG\": 6.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.39,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.25,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"spaghetti bolognese\": {\r\n  \"fdcId\": 2706470,\r\n  \"description\": \"Spaghetti sauce with meat\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 260,\r\n  \"kcal\": 234,\r\n  \"proteinG\": 15.4,\r\n  \"fatG\": 11.3,\r\n  \"carbsG\": 17,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 1.33,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 5.12,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"spaghetti carbonara\": {\r\n  \"fdcId\": 2708861,\r\n  \"description\": \"Pasta with cream sauce and meat, restaurant\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 250,\r\n  \"kcal\": 533,\r\n  \"proteinG\": 14.2,\r\n  \"fatG\": 35.3,\r\n  \"carbsG\": 38.5,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.63,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 3.63,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"spring rolls\": {\r\n  \"fdcId\": 2708700,\r\n  \"description\": \"Egg roll, meatless\",\r\n  \"servingName\": \"1 egg roll\",\r\n  \"servingG\": 64,\r\n  \"kcal\": 173,\r\n  \"proteinG\": 3.6,\r\n  \"fatG\": 9,\r\n  \"carbsG\": 19.2,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 42.88,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.37,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"steak\": {\r\n  \"fdcId\": 2705824,\r\n  \"description\": \"Beef, steak, NFS\",\r\n  \"servingName\": \"1 regular\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 366,\r\n  \"proteinG\": 43.2,\r\n  \"fatG\": 20.6,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 3.26,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 0.42,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"strawberry shortcake\": {\r\n  \"fdcId\": 2707896,\r\n  \"description\": \"Cake, strawberry shortcake\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 150,\r\n  \"kcal\": 321,\r\n  \"proteinG\": 5,\r\n  \"fatG\": 7.1,\r\n  \"carbsG\": 60.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin C\",\r\n    \"amount\": 18.6,\r\n    \"unit\": \"mg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 43.5,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"sushi\": {\r\n  \"fdcId\": 2708959,\r\n  \"description\": \"Sushi, NFS\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 150,\r\n  \"kcal\": 141,\r\n  \"proteinG\": 4.4,\r\n  \"fatG\": 1,\r\n  \"carbsG\": 27.6,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.15,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Folate\",\r\n    \"amount\": 7.5,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"tacos\": {\r\n  \"fdcId\": 2708514,\r\n  \"description\": \"Taco, NFS\",\r\n  \"servingName\": \"1 large\",\r\n  \"servingG\": 160,\r\n  \"kcal\": 394,\r\n  \"proteinG\": 24.5,\r\n  \"fatG\": 21.7,\r\n  \"carbsG\": 25,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.03,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 1.49,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"takoyaki\": {\r\n  \"fdcId\": 2706331,\r\n  \"description\": \"Octopus\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 305,\r\n  \"proteinG\": 17.9,\r\n  \"fatG\": 17.5,\r\n  \"carbsG\": 18.1,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 17.48,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin E\",\r\n    \"amount\": 4.27,\r\n    \"unit\": \"mg\"\r\n   }\r\n  ]\r\n },\r\n \"tiramisu\": {\r\n  \"fdcId\": 2705702,\r\n  \"description\": \"Tiramisu\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 145,\r\n  \"kcal\": 512,\r\n  \"proteinG\": 8.2,\r\n  \"fatG\": 34.6,\r\n  \"carbsG\": 42.7,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 268.25,\r\n    \"unit\": \"µg RAE\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 0.29,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"tuna tartare\": {\r\n  \"fdcId\": 2706308,\r\n  \"description\": \"Fish, tuna, raw\",\r\n  \"servingName\": \"1 cup\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 147,\r\n  \"proteinG\": 32.9,\r\n  \"fatG\": 0.7,\r\n  \"carbsG\": 0,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.81,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin D\",\r\n    \"amount\": 2.3,\r\n    \"unit\": \"µg\"\r\n   }\r\n  ]\r\n },\r\n \"waffles\": {\r\n  \"fdcId\": 2708312,\r\n  \"description\": \"Waffle, NFS\",\r\n  \"servingName\": \"1 thick / Belgian waffle\",\r\n  \"servingG\": 135,\r\n  \"kcal\": 417,\r\n  \"proteinG\": 10,\r\n  \"fatG\": 12.8,\r\n  \"carbsG\": 65.3,\r\n  \"vitamins\": [\r\n   {\r\n    \"name\": \"Vitamin B12\",\r\n    \"amount\": 2.19,\r\n    \"unit\": \"µg\"\r\n   },\r\n   {\r\n    \"name\": \"Vitamin A\",\r\n    \"amount\": 591.3,\r\n    \"unit\": \"µg RAE\"\r\n   }\r\n  ]\r\n }\r\n}\r\n","food/pyramid-scanner.mjs":"// Food pyramid 3D scanner. #3: the floating pyramid IS the Food menu — this lazy three.js scene fills the\r\n// Food dialog (launch.mjs puts it in .pyramid-mode; a WebGL or model failure falls back to the plain panel).\r\n// The lens is the camera (#31); tap a screen to zoom it (#32, #13); the dials are Log by hand / Water / Today\r\n// (D36); a half-turn spin or a clear swipe flips the screens between the last meal and today's totals (#35).\r\n// Three.js is imported only when the panel opens (same pattern as hologram.mjs); the GLB is fetched then too.\r\n// Served unbundled (external in scripts/build.mjs): no .ts imports and no build-time defines here.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/addons/libs/meshopt_decoder.module.js';\r\nimport {pyramidTiles,mealNutrients,todayTiles,foodPhotoToday} from './pyramid-tiles.mjs';\r\nimport {claimGraphics} from '../modules/graphics-lifecycle.mjs';\r\nimport {offAxis} from '../modules/portal/peer.mjs'; // #135: tilt looks round the pyramid through the portal window\r\nexport {pyramidTiles} from './pyramid-tiles.mjs';\r\n\r\n// Reuse the lightweight striped wall + paper notices from\r\n// C:/Users/ianmy/Documents/Codex/2026-09-22/co/work/mominc-girlfriend-fix/tv/channels/girlfriend.html.\r\n// These are the original game's CSS/DOM treatment; no raster art or external request is needed.\r\n// #38: the poster and note sit in the top corners, sized to stay whole at 375x812 beside the pyramid's tip.\r\nconst ROOM_STYLE_ID='pyramidScannerRoomStyle';\r\nconst ROOM_CSS=`\r\n#pyramidScanner{position:relative;width:100%;height:230px;border-radius:10px;overflow:hidden;margin-bottom:12px;touch-action:none;isolation:isolate;background:#bba16e!important}\r\n#pyramidScanner [hidden]{display:none!important}\r\n#pyramidScanner .pyramid-room{position:absolute;inset:0;z-index:0;overflow:hidden;pointer-events:none}\r\n#pyramidScanner .dg-paper-wall{position:absolute;inset:0;background:repeating-linear-gradient(90deg,transparent 0 139px,#604c4133 140px 142px),repeating-linear-gradient(0deg,#b8a477 0 79px,#c3b181 80px 82px);border:14px solid #665044}\r\n#pyramidScanner .dg-paper-wall:after{content:'';position:absolute;inset:0;opacity:.22;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.7' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Cpath fill='%23fff' filter='url(%23p)' opacity='.7' d='M0 0h180v180H0z'/%3E%3C/svg%3E\")}\r\n#pyramidScanner .dg-pyramid-walker{position:absolute;bottom:0;left:0;height:100%;width:auto;max-width:none;z-index:1;animation:dg-pyramid-cross 11s linear infinite;filter:drop-shadow(2px 4px 2px #30251977)}\r\n@keyframes dg-pyramid-cross{0%,50%{left:0;transform:translateX(-110%) rotate(-2deg)}61%{left:25%;transform:translateX(-50%) rotate(2deg)}78%{left:75%;transform:translateX(-50%) rotate(-2deg)}95%,100%{left:100%;transform:translateX(10%) rotate(2deg)}}\r\n@media(prefers-reduced-motion:reduce){#pyramidScanner .dg-pyramid-walker{animation:none;transform:translateX(-110%)}}\r\n#pyramidScanner .paper-poster{position:absolute;z-index:1;top:clamp(74px,10%,120px);left:5%;width:min(33%,220px);box-sizing:border-box;padding:13px 9px;background:#e5d4a2;border:2px solid #ad9769;box-shadow:5px 5px #76614955;text-align:center;transform:rotate(-3deg);color:#4c3255;font:700 clamp(12px,3.3vw,20px)/1.25 Georgia,serif}\r\n#pyramidScanner .paper-poster:before{content:'';position:absolute;width:45%;height:15px;left:27%;top:-9px;background:#e2c388bb;transform:rotate(3deg)}\r\n#pyramidScanner .paper-poster small{display:block;font:9px monospace;letter-spacing:.1em;margin-top:10px}\r\n#pyramidScanner .paper-note{position:absolute;z-index:1;right:5%;top:calc(clamp(74px,10%,120px) + 14px);max-width:34%;box-sizing:border-box;background:#dbc68a;color:#463149;border-left:5px solid #79558a;padding:10px;font:11px/1.45 monospace;transform:rotate(3deg)}\r\n#pyramidScanner .pyramid-loading{position:absolute;inset:0;z-index:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;color:#463149cc;font:700 12px/1.3 monospace;text-align:center;opacity:1;transition:opacity .35s;pointer-events:none}\r\n#pyramidScanner .pyramid-loading[data-out]{opacity:0}\r\n#pyramidScanner .pyramid-loading svg{width:88px;height:88px;opacity:.6}\r\n#pyramidScanner canvas{position:absolute;inset:0;z-index:2}\r\n#pyramidScanner .pyramid-ui{position:absolute;inset:0;z-index:3;pointer-events:none;overflow:hidden}\r\n#pyramidScanner :where(.pyramid-ui>button,.pyramid-ui>.pyramid-question){position:absolute;left:0;top:0;margin:0;pointer-events:auto;cursor:pointer;font:700 13px/1 system-ui,-apple-system,sans-serif;letter-spacing:.04em}\r\n#pyramidScanner .pyramid-tag{min-height:44px;padding:0 13px;border:1px solid #fff9;border-radius:999px;background:#1d1428e0;color:#fff4dc;white-space:nowrap;box-shadow:0 2px 8px #0006}\r\n#pyramidScanner .pyramid-tag[data-on]{background:#7fe6ff;color:#10121a;border-color:#dff9ff}\r\n#pyramidScanner .pyramid-tag[data-away]:not(:focus-visible){opacity:0;pointer-events:none}\r\n#pyramidScanner .pyramid-tag[data-pulse]{animation:pyramidPulseTag 2.1s ease-in-out infinite}\r\n@keyframes pyramidPulseTag{0%,100%{box-shadow:0 2px 8px #0006}50%{box-shadow:0 2px 8px #0006,0 0 16px 4px #7fe6ffcc}}\r\n#pyramidScanner .pyramid-question{white-space:normal;max-width:min(84vw,300px);text-align:center;line-height:1.3;pointer-events:none}\r\n/* #3/#37: while the pyramid is asking, the correction sheet stays logically open (meal-nutrition.mjs still\r\n   searches and computes nutrients for the guess, so the numbers fly in and the eventual Food match is\r\n   prefilled) but visually closed, so the pyramid — not this sheet — is the whole Food menu until resolved. */\r\n#mealsPanel.pyramid-mode[data-asking] #mealConfirmation,#mealsPanel.pyramid-mode[data-asking] #mealSaveControls{display:none!important}\r\n/* Release 6: while asking, the wall's poster and note step down below the question's Yes/Type it/Fix row (reframe() sets --ask-clear). */\r\n#mealsPanel[data-asking] #pyramidScanner .paper-poster{top:var(--ask-clear,120px)}#mealsPanel[data-asking] #pyramidScanner .paper-note{top:calc(var(--ask-clear,120px) + 14px)}\r\n#pyramidScanner .pyramid-screen-key{min-height:0;padding:0;border:0;border-radius:6px;background:none;opacity:0;pointer-events:none!important}\r\n#pyramidScanner .pyramid-screen-key:focus-visible{opacity:1;outline:3px solid #ffb24d;outline-offset:2px}\r\n#pyramidScanner .pyramid-flip{left:50%;top:auto;bottom:14px;translate:-50% 0;display:flex;white-space:nowrap;align-items:center;gap:9px;min-height:40px;padding:0 15px;border:1px solid #fff8;border-radius:999px;background:#1d1428e0;color:#b9a9c6;box-shadow:0 2px 8px #0006}\r\n#pyramidScanner .pyramid-flip span[data-on]{color:#fff4dc}\r\n#pyramidScanner .pyramid-flip i{position:relative;width:30px;height:14px;border-radius:7px;background:#ffffff38}\r\n#pyramidScanner .pyramid-flip i:after{content:'';position:absolute;top:2px;left:2px;width:10px;height:10px;border-radius:50%;background:#7fe6ff;transition:transform .25s}\r\n#pyramidScanner .pyramid-flip[data-mode=today] i:after{transform:translateX(16px)}\r\n#pyramidScanner .pyramid-zoom{left:12px;right:12px;top:var(--zoom-y,50%);translate:0 -50%;display:grid;justify-items:center;gap:10px;padding:26px 14px;border:3px solid #2a2320;border-radius:22px;color:#2a2320;text-align:center;box-shadow:0 14px 44px #000b}\r\n#pyramidScanner .pyramid-zoom small{font:800 clamp(18px,5.5vw,28px)/1 system-ui,-apple-system,sans-serif;letter-spacing:.14em}\r\n#pyramidScanner .pyramid-zoom strong{max-width:100%;font:900 clamp(46px,16vw,110px)/1.05 system-ui,-apple-system,sans-serif;overflow-wrap:anywhere}\r\n#pyramidScanner .pyramid-zoom[data-key=name] strong{font-size:clamp(30px,10vw,64px)}\r\n#pyramidScanner .pyramid-zoom em{font:600 13px/1 system-ui,-apple-system,sans-serif;font-style:normal;opacity:.7}\r\n#pyramidScanner .pyramid-fly{position:absolute;left:0;top:0;padding:5px 9px;border:2px solid #2a2320;border-radius:9px;color:#2a2320;font:800 15px/1 system-ui,-apple-system,sans-serif;white-space:nowrap;pointer-events:none;box-shadow:0 3px 12px #0006}\r\n@media (prefers-reduced-motion:reduce){\r\n #pyramidScanner .pyramid-flip i:after{transition:none}\r\n #pyramidScanner .pyramid-loading{transition:none}\r\n #pyramidScanner .pyramid-tag[data-pulse]{animation:none;box-shadow:0 2px 8px #0006,0 0 16px 4px #7fe6ffcc}\r\n}\r\n`;\r\nlet roomStyle=null,roomStyleUsers=0;\r\nfunction acquireRoomStyle(){\r\n if(!roomStyle){roomStyle=document.getElementById(ROOM_STYLE_ID)||document.createElement('style');roomStyle.id=ROOM_STYLE_ID;roomStyle.textContent=ROOM_CSS;if(!roomStyle.isConnected)document.head.append(roomStyle);}\r\n roomStyleUsers++;\r\n return ()=>{roomStyleUsers=Math.max(0,roomStyleUsers-1);if(!roomStyleUsers){roomStyle?.remove();roomStyle=null;}};\r\n}\r\n\r\nconst TILES=[ // [mesh name, tileState key, small label, tile background]\r\n ['screen_name','name','FOOD','#7fcf5a'],\r\n ['screen_calories','calories','CALORIES','#f4d35e'],\r\n ['screen_protein','protein','PROTEIN','#4fd1c5'],\r\n ['screen_fat','fat','FAT','#f4978e'],\r\n ['screen_carbs','carbs','CARBS','#7fcf5a'],\r\n ['screen_vitamins','vitamins','VITAMINS','#c9a7eb'],\r\n];\r\nconst DIALS=['Log by hand','Water','Today']; // D36: knob_0..2\r\nconst TAU=Math.PI*2,FOV=35,TAN=Math.tan(FOV*Math.PI/360);\r\nconst FLIP_SPACE=64; // px kept under the pyramid for the meal/today indicator\r\nconst INERTIA=0.94;  // per-frame spin decay after release\r\nconst FOCUS=0.7;     // top share of the model holding the lens, screens and dials (the base may hang behind the sheet)\r\nconst FLY_MS=700;    // one number's flight from the lens to its screen\r\n\r\nfunction roundedRectPath(ctx,w,h,r){\r\n if(ctx.roundRect){ctx.beginPath();ctx.roundRect(0,0,w,h,r);return;}\r\n ctx.beginPath();ctx.moveTo(r,0);ctx.arcTo(w,0,w,h,r);ctx.arcTo(w,h,0,h,r);ctx.arcTo(0,h,0,0,r);ctx.arcTo(0,0,w,0,r);ctx.closePath();\r\n}\r\nfunction paintTile(canvas,bg,label,value){\r\n const ctx=canvas.getContext('2d'),w=canvas.width,h=canvas.height;\r\n ctx.clearRect(0,0,w,h);ctx.fillStyle=bg;roundedRectPath(ctx,w,h,Math.min(w,h)*0.16);ctx.fill();\r\n ctx.fillStyle='#2a2320';ctx.textAlign='center';ctx.textBaseline='middle';\r\n ctx.font=`700 ${Math.round(h*0.15)}px system-ui,-apple-system,sans-serif`;ctx.fillText(label,w/2,h*0.24);\r\n let size=h*0.33;\r\n for(;;){ctx.font=`800 ${Math.round(size)}px system-ui,-apple-system,sans-serif`;if(ctx.measureText(value).width<=w*0.86||size<=h*0.13)break;size-=2;}\r\n ctx.fillText(value,w/2,h*0.65);\r\n}\r\n// UV (0,0)=bottom-left, (1,1)=top-right per the asset contract: find corners by UV,\r\n// not by buffer index order, since glTF export may reindex/triangulate the quad.\r\nfunction quadCorners(mesh){\r\n const pos=mesh.geometry.attributes.position,uv=mesh.geometry.attributes.uv;\r\n const pick=(ux,uy)=>{let best=0,bestD=Infinity;for(let i=0;i<uv.count;i++){const d=(uv.getX(i)-ux)**2+(uv.getY(i)-uy)**2;if(d<bestD){bestD=d;best=i;}}return new THREE.Vector3().fromBufferAttribute(pos,best);};\r\n return {bl:pick(0,0),br:pick(1,0),tl:pick(0,1),tr:pick(1,1)};\r\n}\r\nfunction softDotTexture(tint=1){\r\n const c=document.createElement('canvas');c.width=c.height=64;const ctx=c.getContext('2d');\r\n const g=ctx.createRadialGradient(32,32,0,32,32,32);g.addColorStop(0,`rgba(255,255,255,${tint})`);g.addColorStop(1,'rgba(255,255,255,0)');\r\n ctx.fillStyle=g;ctx.fillRect(0,0,64,64);return new THREE.CanvasTexture(c);\r\n}\r\n\r\n// anchor: an element already in the (core, always-loaded) food panel markup that this lazy-loaded scanner\r\n// mounts itself just before. Building the host, its overlay controls and their styling here, instead of\r\n// shipping them in launch-shell.mjs/food-live.css, keeps three.js and its container out of the core bundle.\r\n// getMeals: the saved /api/meals rows (newest first) or null; onDial(index,on): a dial was pressed;\r\n// frame(): {top,bottom} px of the host the pyramid should fit between (the Food header and bottom sheet).\r\nexport async function mountPyramidScanner(anchor,{getNutrition=()=>({name:null,nutrients:null}),getMeals=()=>null,onDial=()=>{},frame=null,signal}={}){\r\n const cancelled=()=>new DOMException('Pyramid scanner closed.','AbortError');\r\n if(signal?.aborted)throw cancelled();\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n let disposed=false,raf=0,observer,timer,pet=null,petAsked=false,ready=false;\r\n let meal=pyramidTiles(null,null),today=todayTiles(null),mode=0,dial=-1,typing=false,uncertain=false,guessName='';\r\n let zoomKey=null,zoomReturn=null,flyArmed=false,flyTimer=0,spin=null;\r\n const flights=[]; // numbers flying from the lens to the screens\r\n const pending=new Set(); // tile keys blank while their number is flying in\r\n const download=new AbortController();\r\n const releaseRoomStyle=acquireRoomStyle();\r\n const host=document.createElement('div');host.id='pyramidScanner';host.dataset.loading='';\r\n // #39: a ghosted wireframe stand-in fills the model's spot while the GLB downloads, with a rising percent when\r\n // the response carries a Content-Length; it fades out (instantly under reduced motion) once the model is ready.\r\n host.innerHTML='<div class=\"pyramid-room\" aria-hidden=\"true\"><div class=\"dg-paper-wall\"></div><img class=\"dg-pyramid-walker\" src=\"/food/drgf-paper-character.png\" alt=\"\" draggable=\"false\"><div class=\"paper-poster\">CARED FOR.<br>CORRECTED.<br>PROVIDED FOR.<small>A MOM INC. WORKPLACE</small></div><div class=\"paper-note\">READ THE SOURCE.<br>KEEP THE LABEL.</div><div class=\"pyramid-loading\"><svg viewBox=\"0 0 100 90\" aria-hidden=\"true\"><polygon points=\"50,6 92,82 8,82\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"4\"/><polyline points=\"8,82 50,40 92,82\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"4 4\"/><line x1=\"50\" y1=\"6\" x2=\"50\" y2=\"40\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"4 4\"/></svg><span class=\"pyramid-loading-text\">Loading the pyramid</span></div></div><div class=\"pyramid-ui\" hidden></div>';\r\n const ui=host.querySelector('.pyramid-ui');\r\n const loading=host.querySelector('.pyramid-loading'),loadingText=host.querySelector('.pyramid-loading-text');\r\n const control=(className,text)=>{const b=document.createElement('button');b.type='button';b.className=className;if(text)b.textContent=text;ui.append(b);return b;};\r\n // Labels ride the lens and dials (projected every frame) and are their keyboard/touch targets too.\r\n const lensTag=control('pyramid-tag','Scan food');lensTag.setAttribute('aria-label','Scan food: take a food photo');\r\n const dialTags=DIALS.map(text=>control('pyramid-tag',text));\r\n for(const tag of dialTags.slice(1))tag.setAttribute('aria-pressed','false');\r\n // #37: an unsure result asks above a clean Yes/Type it/Fix row near the lens (a flat 2D banner, not baked into\r\n // the FOOD screen's 3D texture, so its layout never fights the model's geometry). #36: Type it is the\r\n // always-available manual-entry fallback.\r\n const questionTag=document.createElement('div');questionTag.className='pyramid-tag pyramid-question';questionTag.setAttribute('role','status');questionTag.hidden=true;ui.append(questionTag);\r\n const yesTag=control('pyramid-tag','Yes');yesTag.hidden=true;\r\n const fixTag=control('pyramid-tag','Fix');fixTag.hidden=true;\r\n const typeItTag=control('pyramid-tag','Type it');typeItTag.hidden=true;\r\n // Invisible keys over the six screens so a keyboard can zoom them too (pointer taps use the raycast).\r\n const screenKeys=Object.fromEntries(TILES.map(([meshName])=>[meshName,control('pyramid-screen-key')]));\r\n const flip=control('pyramid-flip');flip.innerHTML='<span>LAST MEAL</span><i></i><span>TODAY</span>';\r\n const zoom=control('pyramid-zoom');zoom.hidden=true;\r\n anchor.before(host);\r\n const scene=new THREE.Scene(),stage=new THREE.Group(),pivot=new THREE.Group();\r\n scene.add(stage);stage.add(pivot);\r\n scene.add(new THREE.AmbientLight(0xffffff,0.95));\r\n const key=new THREE.DirectionalLight(0xffffff,0.75);key.position.set(0.6,1.4,1.2);scene.add(key);\r\n let renderer;\r\n // The hidden 3D coach gives its context back first (the portal round Food keeps its board); it returns when Food closes.\r\n const releaseGpu=claimGraphics('pyramid',{keep:['portal']});await releaseGpu.ready;\r\n if(signal?.aborted){releaseGpu();host.remove();releaseRoomStyle();throw cancelled();}\r\n try{renderer=new THREE.WebGLRenderer({alpha:true,antialias:true,powerPreference:'low-power'});}\r\n catch(error){releaseGpu();host.remove();releaseRoomStyle();throw error;}\r\n renderer.setPixelRatio(Math.min(window.devicePixelRatio||1,1.5));renderer.setClearColor(0x000000,0);\r\n renderer.domElement.style.cssText='display:block;width:100%;height:100%;touch-action:none';renderer.domElement.setAttribute('aria-hidden','true');host.append(renderer.domElement);\r\n // Looks straight down -z; reframe() slides it back and down/up so the pyramid fills the free space.\r\n const camera=new THREE.PerspectiveCamera(FOV,1,0.01,40);camera.position.set(0,0.05,2.2);scene.add(camera);\r\n const raycaster=new THREE.Raycaster();\r\n const dialogEl=host.closest('dialog');\r\n\r\n const screens={},knobs=[];let lens=null,lensHalo=null,lensFlashT=-10,lensRadius=0.03,body=null,modelSize=null;\r\n const steamTex=softDotTexture(0.9);\r\n const steamPool=Array.from({length:24},()=>({sprite:new THREE.Sprite(new THREE.SpriteMaterial({map:steamTex,transparent:true,opacity:0,depthWrite:false,color:0xf3ece8})),age:0,life:0,vel:new THREE.Vector3(),pos:new THREE.Vector3()}));\r\n for(const p of steamPool){p.sprite.visible=false;p.sprite.scale.setScalar(0.012);}\r\n\r\n function disposeMat(mat){for(const m of [mat].flat())if(m){for(const v of Object.values(m))if(v?.isTexture)v.dispose();m.dispose();}}\r\n function disposeTree(root){root.traverse(node=>{node.geometry?.dispose();if(node.material)disposeMat(node.material);});}\r\n function dispose(){\r\n  if(disposed)return;disposed=true;cancelAnimationFrame(raf);observer?.disconnect();\r\n  releaseRoomStyle();delete dialogEl?.dataset.asking;pet?.dispose?.();window.removeEventListener('myr5:food-photo-ready',wakePet);\r\n  signal?.removeEventListener('abort',dispose);download.abort();clearTimeout(timer);clearTimeout(flyTimer);\r\n  window.removeEventListener('myr5:meal-nutrition',onNutrition);window.removeEventListener('myr5:food-selected',onSelected);window.removeEventListener('myr5:food-reset',onReset);\r\n  dialogEl?.removeEventListener('cancel',onCancel);\r\n  const dom=renderer.domElement;dom.removeEventListener('pointerdown',onDown);dom.removeEventListener('pointermove',onMove);dom.removeEventListener('pointerup',onUp);dom.removeEventListener('pointercancel',onUp);dom.removeEventListener('click',onClick);\r\n  disposeTree(scene);\r\n  for(const p of steamPool)if(!p.sprite.parent)p.sprite.material.dispose();\r\n  steamTex.dispose();renderer.dispose();renderer.forceContextLoss();host.remove();releaseGpu(renderer.domElement);\r\n }\r\n\r\n // ---- Screens: \"last meal\" face (the meal being logged, else the newest saved one) or today's totals.\r\n function faces(){\r\n  const current=getNutrition(),items=getMeals(),last=items?.[0];\r\n  meal=current?.name!=null?pyramidTiles(current.name===''&&typing?'TYPE YOUR FOOD':current.name,current.nutrients)\r\n   :last?pyramidTiles(last.name,mealNutrients(last)):pyramidTiles(null,null);\r\n  today=todayTiles(items);\r\n }\r\n const tileText=key=>mode?today[key]:pending.has(key)?'':meal[key];\r\n function paint([meshName,key,label,bg]){\r\n  const s=screens[meshName],value=tileText(key);\r\n  screenKeys[meshName].setAttribute('aria-label',`${label}: ${value||'arriving'}. Zoom in`);\r\n  if(!s)return;paintTile(s.canvas,bg,label,value);s.tex.needsUpdate=true;\r\n }\r\n function repaint(){for(const tile of TILES)paint(tile);if(zoomKey)fillZoom();}\r\n // #37: question + Yes/Type it/Fix travel together; a resolved or abandoned guess clears all four at once\r\n // and lets the (already-computed) correction sheet show again.\r\n function hideAsk(){questionTag.hidden=yesTag.hidden=fixTag.hidden=typeItTag.hidden=true;lensTag.hidden=!lens;delete dialogEl?.dataset.asking;}\r\n function onNutrition(){\r\n  if(disposed)return;\r\n  if(dial===0&&getNutrition()?.name==null)setDial(-1);\r\n  if(getNutrition()?.name==null){uncertain=false;hideAsk();} // #36/#37: a saved/cleared meal drops the ask\r\n  faces();if(!flyArmed)repaint();else if(meal.calories!=='—')fly();\r\n }\r\n // #31: a scan result (or a picked suggestion) blanks the screens, then its numbers fly out of the lens onto them.\r\n // #36/#37: no name (a scan error, a cancel or \"no clear food match\") offers Type it instead; an unsure result\r\n // asks first, with the question and Yes/Type it/Fix all near the lens (#3: the pyramid stays the whole menu —\r\n // the correction sheet itself opens only once Yes, Fix or Type it resolves the guess).\r\n function onSelected(e){\r\n  if(disposed)return;\r\n  const name=e?.detail?.name;\r\n  if(!name){uncertain=false;hideAsk();lensTag.hidden=true;typeItTag.hidden=false;return;} // error/cancel/no-match: the old guess is void, Type it remains (in the lens label's freed slot)\r\n  uncertain=!!e.detail.uncertain;\r\n  if(uncertain){guessName=name;questionTag.textContent=`Looks like… ${name}?`;dialogEl?.setAttribute('data-asking','');}\r\n  else delete dialogEl?.dataset.asking;\r\n  questionTag.hidden=yesTag.hidden=fixTag.hidden=typeItTag.hidden=!uncertain;\r\n  lensTag.hidden=uncertain; // frees its slot for the question/row, which take over the lens's job of triggering a rescan\r\n  typing=false;flyArmed=true;clearFlights();for(const [,k] of TILES)pending.add(k);\r\n  if(mode){spin=null;velocity=0;setRotation(pivot.rotation.y+TAU);} // same pose, other face: the result lands on \"last meal\"\r\n  faces();repaint();clearTimeout(flyTimer);flyTimer=setTimeout(fly,2500); // no nutrition match: fly the name anyway\r\n }\r\n function onReset(){\r\n  if(disposed)return;\r\n  typing=false;flyArmed=false;uncertain=false;hideAsk();\r\n  clearFlights();clearTimeout(flyTimer);pending.clear();faces();repaint();\r\n }\r\n window.addEventListener('myr5:meal-nutrition',onNutrition);window.addEventListener('myr5:food-selected',onSelected);window.addEventListener('myr5:food-reset',onReset);\r\n\r\n const tmp=new THREE.Vector3(),tmp2=new THREE.Vector3(),toCam=new THREE.Vector3();\r\n let W=1,H=1;\r\n function toScreen(world){tmp.copy(world).project(camera);return {x:(tmp.x+1)/2*W,y:(1-tmp.y)/2*H};}\r\n function screenRect(meshName){\r\n  const s=screens[meshName];if(!s)return null;\r\n  let x0=Infinity,y0=Infinity,x1=-Infinity,y1=-Infinity;\r\n  for(const c of s.corners){const p=toScreen(tmp2.copy(c).applyMatrix4(s.mesh.matrixWorld));x0=Math.min(x0,p.x);y0=Math.min(y0,p.y);x1=Math.max(x1,p.x);y1=Math.max(y1,p.y);}\r\n  return {x:x0,y:y0,w:x1-x0,h:y1-y0};\r\n }\r\n\r\n function fly(){\r\n  if(disposed||!flyArmed)return;flyArmed=false;clearTimeout(flyTimer);\r\n  if(reduced||!lens){pending.clear();repaint();return;}\r\n  clearFlights();const now=performance.now();\r\n  TILES.forEach((tile,i)=>{\r\n   const chip=document.createElement('span');chip.className='pyramid-fly';chip.textContent=meal[tile[1]];chip.style.background=tile[3];chip.style.opacity='0';chip.setAttribute('aria-hidden','true');ui.append(chip);\r\n   flights.push({chip,tile,start:now+i*110});\r\n  });\r\n }\r\n // Each frame: chips arc from the lens to their screen's current spot (the pyramid may be reframing), then land.\r\n function moveFlights(now){\r\n  if(!flights.length)return;\r\n  const from=lens&&toScreen(lens.getWorldPosition(tmp2));\r\n  for(let i=flights.length-1;i>=0;i--){\r\n   const f=flights[i],t=(now-f.start)/FLY_MS;if(t<0)continue;\r\n   const to=screenRect(f.tile[0]);\r\n   if(t>=1||!to||!from){f.chip.remove();flights.splice(i,1);pending.delete(f.tile[1]);paint(f.tile);continue;}\r\n   const e=t<.5?2*t*t:1-(-2*t+2)**2/2,x=from.x+(to.x+to.w/2-from.x)*e,y=from.y+(to.y+to.h/2-from.y)*e-Math.sin(t*Math.PI)*70;\r\n   f.chip.style.opacity=String(Math.min(1,t*6));f.chip.style.transform=`translate(${Math.round(x)}px,${Math.round(y)}px) translate(-50%,-50%) scale(${(1.15-.55*e).toFixed(3)})`;\r\n  }\r\n }\r\n function clearFlights(){for(const f of flights)f.chip.remove();flights.length=0;}\r\n\r\n // ---- #32/#13: tap a screen to zoom it across the width; tap again (or Escape) to return.\r\n function fillZoom(){\r\n  const [,key,label,bg]=TILES.find(t=>t[0]===zoomKey),small=document.createElement('small'),strong=document.createElement('strong'),hint=document.createElement('em');\r\n  small.textContent=label;strong.textContent=tileText(key)||'…';hint.textContent='Tap to return';\r\n  zoom.dataset.key=key;zoom.style.background=bg;zoom.replaceChildren(small,strong,hint);\r\n }\r\n function openZoom(meshName){\r\n  const from=screenRect(meshName);zoomKey=meshName;fillZoom();zoom.hidden=false;\r\n  zoomReturn=ui.contains(document.activeElement)?document.activeElement:null;zoom.focus({preventScroll:true});\r\n  if(reduced||!from)return;\r\n  const z=zoom.getBoundingClientRect(),h=host.getBoundingClientRect(),dx=h.left+from.x+from.w/2-(z.left+z.width/2),dy=h.top+from.y+from.h/2-(z.top+z.height/2);\r\n  zoom.animate([{transform:`translate(${dx}px,${dy}px) scale(${Math.max(.05,from.w/z.width)})`,opacity:.6},{transform:'none',opacity:1}],{duration:280,easing:'cubic-bezier(.2,0,.2,1)'});\r\n }\r\n function closeZoom(){if(!zoomKey)return;zoomKey=null;zoom.hidden=true;zoomReturn?.focus({preventScroll:true});zoomReturn=null;}\r\n function onCancel(e){if(zoomKey){e.preventDefault();closeZoom();}}\r\n dialogEl?.addEventListener('cancel',onCancel);\r\n zoom.onclick=closeZoom;\r\n for(const [meshName] of TILES)screenKeys[meshName].onclick=()=>openZoom(meshName);\r\n\r\n // ---- #35: the pose picks the face. Each half-turn past the back flips it (the swap happens out of sight),\r\n // so a full spin shows the other face; a spin that crosses the back or a clear swipe glides on to the front.\r\n function syncMode(){\r\n  const m=Math.round(pivot.rotation.y/TAU)&1;if(m===mode)return;\r\n  mode=m;repaint();flip.dataset.mode=mode?'today':'meal';\r\n  const [a,b]=flip.querySelectorAll('span');a.toggleAttribute('data-on',!mode);b.toggleAttribute('data-on',!!mode);\r\n  flip.setAttribute('aria-label',mode?'Screens show today’s totals. Switch to the last meal':'Screens show the last meal. Switch to today’s totals');\r\n }\r\n function setRotation(y){pivot.rotation.y=y;syncMode();}\r\n function spinTo(to){velocity=0;if(reduced){spin=null;setRotation(to);return;}const from=pivot.rotation.y;spin={from,to,t0:performance.now(),ms:Math.min(1100,380+Math.abs(to-from)*110)};}\r\n flip.onclick=()=>spinTo(Math.round(pivot.rotation.y/TAU)*TAU+TAU);\r\n mode=1;syncMode(); // initialise the indicator's labels (mode 0 = last meal)\r\n\r\n // ---- Photo days: Dr. Girlfriend's pocket holds a paper friend (arcade/pyramid-jump, lazy and never core).\r\n const apex=()=>toScreen(tmp2.set(0,modelSize.y/2,0).applyMatrix4(stage.matrixWorld));\r\n function wakePet(){\r\n  if(disposed||petAsked||!ready||!foodPhotoToday())return;petAsked=true;\r\n  import('../arcade/pyramid-jump/pet.mjs').then(m=>{if(!disposed)pet=m.mountPet({host,walker:host.querySelector('.dg-pyramid-walker'),playAt:flip,apex,getMeals,dialog:dialogEl});}).catch(()=>{petAsked=false;});\r\n }\r\n\r\n // ---- Knobs: glow, wiggle and steam feedback (unchanged), now each with a job (D36).\r\n function spawnSteam(k){\r\n  if(reduced)return;\r\n  for(let n=0;n<5;n++){\r\n   const p=steamPool.shift();steamPool.push(p);\r\n   p.pos.copy(k.basePos).addScaledVector(k.axis,0.01);\r\n   p.vel.copy(k.axis).multiplyScalar(0.055).add(new THREE.Vector3((Math.random()-0.5)*0.018,(Math.random()-0.5)*0.018,(Math.random()-0.5)*0.018));\r\n   p.age=0;p.life=0.85+Math.random()*0.3;p.sprite.visible=true;p.sprite.scale.setScalar(0.012);p.sprite.material.opacity=0.55;p.sprite.position.copy(p.pos);\r\n  }\r\n }\r\n function updateSteam(dt){\r\n  for(const p of steamPool){\r\n   if(!p.sprite.visible)continue;\r\n   p.age+=dt;if(p.age>p.life){p.sprite.visible=false;continue;}\r\n   p.vel.y+=dt*0.05;p.pos.addScaledVector(p.vel,dt);p.sprite.position.copy(p.pos);\r\n   const f=p.age/p.life;p.sprite.material.opacity=0.55*(1-f);p.sprite.scale.setScalar(0.012+f*0.02);\r\n  }\r\n }\r\n // One dial lit at a time (launch.mjs also calls this when a dial's panel closes).\r\n function setDial(i){dial=i;for(const k of knobs)k.on=k.index===i;dialTags.forEach((tag,n)=>{tag.toggleAttribute('data-on',n===i);if(n)tag.setAttribute('aria-pressed',String(n===i));});}\r\n function pressDial(i){\r\n  // Log by hand always opens; Water and Today toggle their cards.\r\n  const on=i===0||dial!==i,k=knobs.find(k=>k.index===i);setDial(on?i:-1);\r\n  if(k){k.tapT=performance.now();spawnSteam(k);}\r\n  if(i===0&&on){typing=true;uncertain=false;hideAsk();} // typing in by hand settles any \"unsure\" question\r\n  onDial(i,on);\r\n }\r\n dialTags.forEach((tag,i)=>tag.onclick=()=>pressDial(i));\r\n // #37: Yes/Fix both settle the guess through the normal food-selected path (same as a confident result), which\r\n // opens the correction sheet with that name searched and re-hides the question/tags via onSelected above.\r\n // Fix additionally surfaces the alternates, retry and status text the worker already prepared but held back.\r\n const confirmGuess=()=>window.dispatchEvent(new CustomEvent('myr5:food-selected',{detail:{name:guessName,uncertain:false}}));\r\n yesTag.onclick=confirmGuess; // #37: keep the guess, drop the \"?\"\r\n fixTag.onclick=()=>{\r\n  const suggestions=document.getElementById('foodSuggestions'),retry=document.getElementById('recognizeFood'),status=document.getElementById('foodStatus');\r\n  if(suggestions)suggestions.hidden=false;\r\n  if(retry)retry.hidden=false;\r\n  if(status)status.textContent='Check the match & portion';\r\n  confirmGuess();\r\n };\r\n typeItTag.onclick=()=>{\r\n  // #36/#37: blank the guess first — launch.mjs's Log by hand only resets the name when the sheet was still\r\n  // closed, which an unsure result's (visually hidden, logically open) sheet no longer is.\r\n  window.dispatchEvent(new CustomEvent('myr5:food-selected',{detail:{name:''}}));\r\n  pressDial(0); // opens Log by hand, which focuses #mealName\r\n };\r\n function scan(){lensFlashT=performance.now();document.getElementById('foodCamera')?.click();}\r\n lensTag.onclick=scan;\r\n function animateKnob(k,now){\r\n  const dt=(now-k.tapT)/1000;\r\n  if(!reduced&&k.tapT>0&&dt<1.1){const decay=Math.exp(-dt*4),ang=decay*Math.sin(dt*26)*0.5,pop=decay*Math.sin(dt*26)*0.002;\r\n   k.mesh.quaternion.setFromAxisAngle(k.axis,ang);k.mesh.position.copy(k.basePos).addScaledVector(k.axis,pop);\r\n  }else{k.mesh.quaternion.identity();k.mesh.position.copy(k.basePos);}\r\n }\r\n function pulseGlow(now){\r\n  const t=now/1000;\r\n  for(const k of knobs){\r\n   const mat=k.mesh.material;if(!mat.emissive)continue;\r\n   const idle=(k.on?0.32:0.12)+(reduced?0:Math.sin(t*2+k.mesh.id)*0.08),flashDt=(now-k.tapT)/1000,flash=!reduced&&flashDt>=0&&flashDt<0.3?(1-flashDt/0.3)*1.6:0;\r\n   mat.emissive.set(k.on?0x7fe6ff:0x3fb6d8);mat.emissiveIntensity=Math.max(0.05,idle)+flash;\r\n  }\r\n  // #34: nothing logged and no scan running (the meal face reads \"—\") pulses the lens harder, inviting a scan.\r\n  const empty=meal.calories==='—';\r\n  lensTag.toggleAttribute('data-pulse',empty);\r\n  if(lensHalo){\r\n   const amp=empty?0.35:0.12,idle=reduced?0.3+(empty?amp:0):0.3+Math.sin(t*2.4)*amp;\r\n   const flashDt=(now-lensFlashT)/1000,flash=!reduced&&flashDt>=0&&flashDt<0.3?(1-flashDt/0.3)*0.9:0;\r\n   lensHalo.material.opacity=Math.max(0,Math.min(1,idle+flash));\r\n  }\r\n }\r\n\r\n // ---- Pointer: drag spins (as before), a tap hits the lens, a screen or a dial.\r\n let dragging=false,downX=0,downY=0,downT=0,downRot=0,lastX=0,lastT=0,speed=0,moved=false,velocity=0,tapAt=null;\r\n function onDown(e){renderer.domElement.setPointerCapture?.(e.pointerId);dragging=true;tapAt=null;moved=false;spin=null;downX=lastX=e.clientX;downY=e.clientY;downT=lastT=performance.now();downRot=pivot.rotation.y;velocity=0;speed=0;}\r\n function onMove(e){\r\n  if(!dragging)return;\r\n  const now=performance.now(),dx=e.clientX-lastX;speed=dx/Math.max(1,now-lastT);lastX=e.clientX;lastT=now;\r\n  if(Math.abs(e.clientX-downX)>6||Math.abs(e.clientY-downY)>6)moved=true;\r\n  if(moved){setRotation(pivot.rotation.y+dx*0.009);velocity=reduced?0:dx*0.009;}\r\n }\r\n function lensWorldSphere(){const p=new THREE.Vector3();lens.getWorldPosition(p);const s=new THREE.Vector3();lens.getWorldScale(s);return new THREE.Sphere(p,lensRadius*s.x);}\r\n function handleTap(cx,cy){\r\n  if(zoomKey){closeZoom();return;}\r\n  const rect=renderer.domElement.getBoundingClientRect();\r\n  const ndc=new THREE.Vector2(((cx-rect.left)/rect.width)*2-1,-((cy-rect.top)/rect.height)*2+1);\r\n  camera.updateMatrixWorld();raycaster.setFromCamera(ndc,camera);\r\n  if(lens&&raycaster.ray.intersectSphere(lensWorldSphere(),new THREE.Vector3())){scan();return;}\r\n  // The body only blocks what is clearly behind it (a dial or screen on the far side), not a knob set into its skin.\r\n  const hits=raycaster.intersectObjects([body,...knobs.map(k=>k.mesh),...Object.values(screens).map(s=>s.mesh)].filter(Boolean),false),near=hits.find(h=>h.object!==body);\r\n  if(!near||hits[0].object===body&&near.distance-hits[0].distance>0.06)return;\r\n  const hit=near.object;\r\n  const knob=knobs.find(k=>k.mesh===hit);if(knob){pressDial(knob.index);return;}\r\n  const screen=Object.keys(screens).find(n=>screens[n].mesh===hit);if(screen)openZoom(screen);\r\n }\r\n function onUp(e){\r\n  if(!dragging)return;dragging=false;\r\n  const dt=performance.now()-downT,dx=e.clientX-downX,dist=Math.hypot(dx,e.clientY-downY);\r\n  // A tap acts on the click that follows: acting on pointerup would let a touch's click land on what the tap opened\r\n  // (the zoom card under the finger would close at once).\r\n  if(!moved&&dist<6&&dt<400&&e.type==='pointerup'){tapAt={x:e.clientX,y:e.clientY};return;}\r\n  if(!moved)return;\r\n  const swipe=Math.abs(dx)>50&&Math.abs(dx)>2*Math.abs(e.clientY-downY)&&Math.abs(speed)>0.5&&performance.now()-lastT<80;\r\n  const coast=pivot.rotation.y+velocity/(1-INERTIA),crossed=Math.round(coast/TAU)!==Math.round(downRot/TAU);\r\n  if(!swipe&&!crossed)return;\r\n  const dir=Math.sign(swipe?dx:coast-downRot)||1,turns=pivot.rotation.y/TAU;\r\n  spinTo((dir>0?Math.ceil(turns+1e-6):Math.floor(turns-1e-6))*TAU);\r\n }\r\n const dom=renderer.domElement;\r\n function onClick(){if(!tapAt)return;const {x,y}=tapAt;tapAt=null;handleTap(x,y);}\r\n dom.addEventListener('pointerdown',onDown);dom.addEventListener('pointermove',onMove);dom.addEventListener('pointerup',onUp);dom.addEventListener('pointercancel',onUp);dom.addEventListener('click',onClick);\r\n\r\n // ---- Framing: fit the pyramid between the Food header and its bottom sheet (portrait phones included).\r\n let fitGoal=null,fitNow=null,frameTop=6;\r\n function reframe(){\r\n  if(disposed)return;\r\n  W=Math.max(host.clientWidth,1);H=Math.max(host.clientHeight,1); // layout size: the portal's arrival scale must not shrink the canvas\r\n  renderer.setSize(W,H,false);camera.aspect=W/H;camera.updateProjectionMatrix();\r\n  for(const tag of [lensTag,questionTag,yesTag,fixTag,typeItTag,...dialTags])tag.labelWidth=tag.offsetWidth;\r\n  const f=frame?.()||{top:0,bottom:H},top=frameTop=Math.max(0,f.top)+6,base=Math.min(H,f.bottom),bottom=base-FLIP_SPACE,middle=(top+bottom)/2;\r\n  flip.style.bottom=`${Math.max(8,H-base+12)}px`;host.style.setProperty('--ask-clear',`${top+108}px`); // under the ask row (placeUI: frameTop+56, 44px tall)\r\n  zoom.style.setProperty('--zoom-y',`${Math.max(top,middle)}px`);\r\n  if(!modelSize)return;\r\n  // px per world unit: the whole model at full width when it fits; when the sheet is up, keep the lens, screens\r\n  // and dials whole at that size and let the base hang behind the sheet.\r\n  const space=Math.max(60,bottom-top),ppuW=W/(modelSize.x*1.3);let ppu=Math.min(ppuW,space/(modelSize.y*1.08)),aim=0;\r\n  if(ppu<ppuW&&base<H-32){ppu=Math.min(ppuW,space/(modelSize.y*FOCUS*1.08));aim=modelSize.y*(0.5-FOCUS/2);}\r\n  fitGoal={dist:H/(2*TAN*ppu),y:aim+(middle-H/2)/ppu};\r\n  if(reduced||!fitNow)fitNow={...fitGoal};\r\n }\r\n // Labels follow the lens and knobs; a knob turned to the back hides its label (focus still shows it).\r\n function place(tag,x,y){const w=tag.labelWidth||0;tag.style.transform=`translate(${Math.round(Math.min(Math.max(x-w/2,6),W-w-6))}px,${Math.round(Math.max(frameTop,Math.min(y,H-46)))}px)`;}\r\n function placeUI(){\r\n  // #37: the question and its row anchor to the top of the safe area (not the lens) — the lens's own screen\r\n  // position swings with the model's fit (how much room the correction sheet leaves it), so anything hung off\r\n  // it risks landing on top of itself; frameTop is stable, and stays clear of the header by construction.\r\n  const askX=lens?toScreen(lens.getWorldPosition(tmp2)).x:W/2;\r\n  if(uncertain){\r\n   place(questionTag,askX,frameTop+2);\r\n   place(yesTag,askX-104,frameTop+56);place(typeItTag,askX,frameTop+56);place(fixTag,askX+104,frameTop+56);\r\n  }else if(!typeItTag.hidden)place(typeItTag,askX,frameTop+2); // #36: a plain error/no-match offers just Type it\r\n  if(lens){\r\n   const p=toScreen(lens.getWorldPosition(tmp2));\r\n   if(!lensTag.hidden)place(lensTag,p.x,p.y-58);\r\n  }\r\n  for(const k of knobs){\r\n   k.mesh.getWorldPosition(tmp2);const p=toScreen(tmp2);\r\n   const axis=toCam.copy(k.axis).transformDirection(k.mesh.parent.matrixWorld),facing=axis.dot(tmp.copy(camera.position).sub(tmp2).normalize());\r\n   dialTags[k.index].toggleAttribute('data-away',facing<-0.1);place(dialTags[k.index],p.x,p.y+14);\r\n  }\r\n  for(const [meshName] of TILES){const r=screenRect(meshName),keyEl=screenKeys[meshName];if(!r){keyEl.hidden=true;continue;}keyEl.style.transform=`translate(${Math.round(r.x)}px,${Math.round(r.y)}px)`;keyEl.style.width=`${Math.round(r.w)}px`;keyEl.style.height=`${Math.round(r.h)}px`;}\r\n }\r\n\r\n signal?.addEventListener('abort',dispose,{once:true});\r\n try{\r\n  timer=setTimeout(()=>download.abort(),20000);let bytes;\r\n  try{\r\n   const response=await fetch('/food/pyramid-scanner.glb',{signal:download.signal});if(!response.ok)throw new Error('Pyramid model unavailable.');\r\n   // #39: read the stream by hand for a percent readout; a response with no Content-Length just skips the number.\r\n   const total=Number(response.headers.get('Content-Length'))||0,reader=response.body?.getReader();\r\n   if(reader){\r\n    const chunks=[];let received=0;\r\n    for(;;){\r\n     const {done,value}=await reader.read();if(done)break;\r\n     chunks.push(value);received+=value.length;\r\n     if(total&&loadingText)loadingText.textContent=`Loading the pyramid · ${Math.round(received/total*100)}%`;\r\n    }\r\n    bytes=await new Blob(chunks).arrayBuffer();\r\n   }else bytes=await response.arrayBuffer();\r\n  }finally{clearTimeout(timer);}\r\n  if(disposed)throw cancelled();\r\n  const loader=new GLTFLoader();loader.setMeshoptDecoder(MeshoptDecoder);\r\n  const gltf=await loader.parseAsync(bytes,'');const model=gltf.scene;\r\n  // GLTF texture decoding cannot be aborted. Discard a late result without\r\n  // mounting anything or reviving the closed renderer/listeners.\r\n  if(disposed){disposeTree(model);throw cancelled();}\r\n  const box=new THREE.Box3().setFromObject(model),size=box.getSize(new THREE.Vector3()),center=box.getCenter(new THREE.Vector3()),scale=1.6/Math.max(size.x,size.y,size.z);\r\n  const offset=new THREE.Group();offset.position.copy(center).multiplyScalar(-1);offset.add(model);\r\n  const normalized=new THREE.Group();normalized.scale.setScalar(scale);normalized.add(offset);pivot.add(normalized);\r\n  modelSize=size.multiplyScalar(scale);\r\n  // Knob coordinates and their steam share the model's local coordinate space.\r\n  // Add effects only after measuring the actual model for its camera framing.\r\n  for(const p of steamPool)model.add(p.sprite);\r\n  body=model.getObjectByName('body')||null;\r\n\r\n  for(const [meshName] of TILES){\r\n   const mesh=model.getObjectByName(meshName);if(!mesh)continue;\r\n   const {bl,br,tl,tr}=quadCorners(mesh),w=bl.distanceTo(br)||1,h=bl.distanceTo(tl)||1,targetH=220;\r\n   const canvas=document.createElement('canvas');canvas.height=targetH;canvas.width=Math.max(64,Math.round(targetH*(w/h)));\r\n   // glTF UVs start at the image's top-left (GLTFLoader never flips), so the canvas must not be flipped either.\r\n   const tex=new THREE.CanvasTexture(canvas);tex.colorSpace=THREE.SRGBColorSpace;tex.flipY=false;\r\n   // polygonOffset: the screen quad sits flush against the body mesh (both in the original GLB) and z-fights\r\n   // it without this — negative factor/units pull the screen a hair closer to the camera for clean edges.\r\n   mesh.material=new THREE.MeshBasicMaterial({map:tex,side:THREE.FrontSide,polygonOffset:true,polygonOffsetFactor:-4,polygonOffsetUnits:-4});\r\n   screens[meshName]={canvas,tex,mesh,corners:[bl,br,tl,tr]};\r\n  }\r\n\r\n  for(let i=0;i<3;i++){\r\n   const knob=model.getObjectByName(`knob_${i}`);if(!knob){dialTags[i].dataset.away='';continue;}\r\n   knob.material=Array.isArray(knob.material)?knob.material.map(m=>m.clone()):knob.material.clone();\r\n   const axis=new THREE.Vector3(...(knob.userData.axis||[0,0,1])).normalize();\r\n   knobs.push({index:i,mesh:knob,axis,basePos:knob.position.clone(),tapT:-10,on:false});\r\n  }\r\n\r\n  lens=model.getObjectByName('lens');\r\n  if(lens){\r\n   lensRadius=lens.userData.radius||0.03;\r\n   lensHalo=new THREE.Sprite(new THREE.SpriteMaterial({map:steamTex,color:0x8ef2ff,blending:THREE.AdditiveBlending,depthWrite:false,transparent:true,opacity:0.3}));\r\n   lensHalo.scale.setScalar(lensRadius*2.6);lens.add(lensHalo);\r\n  }else lensTag.hidden=true;\r\n\r\n  faces();repaint();\r\n  delete host.dataset.loading;ui.hidden=false;ready=true;wakePet();window.addEventListener('myr5:food-photo-ready',wakePet);\r\n  if(loading){if(reduced)loading.remove();else{loading.dataset.out='';loading.addEventListener('transitionend',()=>loading.remove(),{once:true});}}\r\n  observer=new ResizeObserver(reframe);observer.observe(host);reframe();\r\n  let last=performance.now();\r\n  function animate(now){\r\n   if(disposed)return;\r\n   // The opaque full-screen photo/scan stage covers the pyramid while a scan runs: no render or label writes under it\r\n   // (numbers still flying out of the lens keep moving).\r\n   const scanStage=document.getElementById('mealScanStage');\r\n   if(scanStage&&!scanStage.hidden&&!flights.length){last=now;raf=requestAnimationFrame(animate);return;}\r\n   const dt=Math.min((now-last)/1000,0.05);last=now;\r\n   if(spin){const t=Math.min(1,(now-spin.t0)/spin.ms);setRotation(spin.from+(spin.to-spin.from)*(1-(1-t)**3));if(t>=1)spin=null;}\r\n   else if(!dragging&&velocity){setRotation(pivot.rotation.y+velocity);velocity*=INERTIA;if(Math.abs(velocity)<1e-4)velocity=0;}\r\n   if(!reduced){const t=now/1000;stage.position.y=Math.sin(t*1.1)*0.035;stage.rotation.z=Math.sin(t*0.7)*0.035;stage.rotation.x=Math.sin(t*0.5)*0.02;}\r\n   if(fitNow){const ease=reduced?1:0.2;fitNow.dist+=(fitGoal.dist-fitNow.dist)*ease;fitNow.y+=(fitGoal.y-fitNow.y)*ease;camera.position.set(0,fitNow.y,fitNow.dist);offAxis(camera,fitNow.dist);}\r\n   for(const k of knobs)animateKnob(k,now);\r\n   updateSteam(dt);pulseGlow(now);\r\n   renderer.render(scene,camera);placeUI();moveFlights(now);raf=requestAnimationFrame(animate);\r\n  }\r\n  raf=requestAnimationFrame(animate);\r\n  return {dispose,reframe,setDial,refresh(){if(!disposed){faces();repaint();}}};\r\n }catch(error){dispose();throw error;}\r\n}\r\n","food/pyramid-tiles.mjs":"// Pure scan-result formatting, kept independent of WebGL for unit tests.\r\nconst VITAMIN_DV={vitaminA:900,vitaminC:90,vitaminD:20,vitaminE:15,vitaminB12:2.4,folate:400};\r\nconst VITAMIN_LABEL={vitaminA:'A',vitaminC:'C',vitaminD:'D',vitaminE:'E',vitaminB12:'B12',folate:'B9'};\r\nconst DASH='—';\r\nconst has=v=>typeof v==='number'&&Number.isFinite(v);\r\n\r\nexport function pyramidTiles(scan,nutrients){\r\n if(scan==null)return {name:'SCAN A MEAL',calories:DASH,protein:DASH,fat:DASH,carbs:DASH,vitamins:DASH};\r\n const round=(v,d=0)=>{const m=10**d;return Math.round(v*m)/m;};\r\n const amount=k=>has(nutrients?.[k])?`${round(nutrients[k],k==='calories'?0:1)} ${k==='calories'?'kcal':'g'}`:DASH;\r\n const top=Object.entries(VITAMIN_DV)\r\n  .map(([k,dv])=>[VITAMIN_LABEL[k],has(nutrients?.[k])?nutrients[k]/dv:-1])\r\n  .filter(([,pct])=>pct>0).sort((a,b)=>b[1]-a[1]).slice(0,2).map(([label])=>label);\r\n return {name:scan||'Try again',calories:amount('calories'),protein:amount('protein'),fat:amount('fat'),carbs:amount('carbs'),vitamins:top.length?top.join(' '):DASH};\r\n}\r\n\r\n// A saved /api/meals row -> the flat nutrient object pyramidTiles reads (D1 returns micros as JSON text).\r\nexport function mealNutrients(item){\r\n let micros=item?.micros;\r\n if(typeof micros==='string'){try{micros=JSON.parse(micros);}catch{micros=null;}}\r\n return {...(micros||{}),calories:item?.calories,protein:item?.protein,fat:item?.fat,carbs:item?.carbs};\r\n}\r\n\r\n// Meals eaten on `now`'s local calendar day; null when the list isn't available (signed out, offline).\r\nexport function mealsOn(items,now=new Date()){\r\n if(!Array.isArray(items))return null;\r\n const day=now.toDateString();\r\n return items.filter(item=>new Date(item.eaten_at).toDateString()===day);\r\n}\r\n\r\n// #35: the screens' \"today\" face — summed macros (0 when nothing is logged yet) and the top two vitamins.\r\nexport function todayTiles(items,now=new Date()){\r\n const meals=mealsOn(items,now);\r\n if(!meals)return pyramidTiles('TODAY',null);\r\n const total={calories:0,protein:0,fat:0,carbs:0};\r\n for(const item of meals)for(const [k,v] of Object.entries(mealNutrients(item)))if(has(v))total[k]=(total[k]||0)+v;\r\n return pyramidTiles(meals.length?`TODAY · ${meals.length} MEAL${meals.length===1?'':'S'}`:'TODAY',total);\r\n}\r\n\r\n// Pocket pet (arcade/pyramid-jump): only on days the user took a food photo. meal-scanner sets the flag on\r\n// 'myr5:food-photo-ready'; the vault's own days['food-scan'] counts too (same local-day string).\r\nconst FOOD_PHOTO_KEY='myr5-food-photo-day',localDay=(d=new Date())=>`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;\r\nexport function markFoodPhotoToday(store=globalThis.localStorage,now=new Date()){try{store.setItem(FOOD_PHOTO_KEY,localDay(now));}catch{/* private mode: the pet just stays away */}}\r\nexport function foodPhotoToday(store=globalThis.localStorage,now=new Date()){\r\n try{const day=localDay(now);return store.getItem(FOOD_PHOTO_KEY)===day||JSON.parse(store.getItem('myr5-vault-v1')||'{}').days?.['food-scan']===day;}catch{return false;}\r\n}\r\n","full-workout-ui.mjs":"// FULL WORKOUT dropdown + runner. The circuit logic is in full-workout.mjs; every exercise runs through\r\n// the normal camera workout (app.mjs start()), so reps/holds, XP, locks and rest rewards are unchanged.\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {FULL_WORKOUT,circuitStyles,buildFullWorkout,styleLadder,maxLevel,tapLevel,sectionPicks} from './full-workout.mjs';\r\nimport {ROPE,makeRope,stepRope,rotate,ropePath} from './rope.mjs';\r\nimport {subscribePhoneMotion,requestPhoneMotion} from './character-phone-sensor.mjs';\r\n\r\nconst esc=s=>String(s).replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]));\r\nconst clock=s=>`${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`;\r\nconst wait=ms=>new Promise(r=>setTimeout(r,ms));\r\n\r\n/** deps: canUse(id)->bool, reason(id)->string, select(id,goal), start(), leaveRest(), voice, storage */\r\nexport function mountFullWorkout({canUse,reason,select,start,leaveRest,voice,storage=globalThis.localStorage}){\r\n const details=document.createElement('details');details.id='podFullWorkout';details.className='pod-goals';\r\n details.innerHTML='<summary aria-label=\"Full workout circuit\">FULL <span data-fw-status></span></summary><div class=\"pod-goals-menu fw-menu\"></div>';\r\n document.getElementById('podGoals').after(details);\r\n const menu=details.querySelector('.fw-menu'),status=details.querySelector('[data-fw-status]');\r\n const hud=document.createElement('section');hud.id='fullWorkoutHud';hud.hidden=true;hud.setAttribute('aria-live','polite');document.body.append(hud);\r\n // Camera-only mode hides every other body child, so the HUD rides inside the camera stage while it is up.\r\n new MutationObserver(()=>{const stage=document.getElementById('cameraWorkout'),target=document.body.dataset.cameraWorkout&&stage?stage:document.body;if(hud.parentNode!==target)target.append(hud);hud.inert=false;}).observe(document.body,{attributes:true,attributeFilter:['data-camera-workout']});\r\n\r\n // Persistence: which sections are plugged in, and each section's engaged ladder level (switches 1..level are on).\r\n const load=()=>{try{const v=JSON.parse(storage.getItem(FULL_WORKOUT.storageKey));if(v&&!Array.isArray(v))return {powered:new Set(v.powered||[]),levels:v.levels||{}};}catch{}return {powered:new Set(),levels:{}};};\r\n const st=load();\r\n const save=()=>{try{storage.setItem(FULL_WORKOUT.storageKey,JSON.stringify({powered:[...st.powered],levels:st.levels}));}catch{}};\r\n const styles=circuitStyles();\r\n const cap=id=>maxLevel(id,canUse);\r\n const lvl=id=>Math.min(st.levels[id]??0,cap(id));\r\n const picks=()=>sectionPicks({powered:st.powered,levels:st.levels,canUse});\r\n const selection=picks;\r\n const detent=kind=>{window.dispatchEvent(new CustomEvent('myr5:hardware-detent',{detail:{kind}}));try{navigator.vibrate?.(kind==='lever'?14:8);}catch{}};\r\n const reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const connected=new Set(); // plugs that have clicked home (lamps only light then)\r\n\r\n function paintHead(){\r\n  const n=picks().length;status.textContent=`${n} section${n===1?'':'s'}`;\r\n  const c=menu.querySelector('.fw-count');if(c)c.textContent=`${n} section${n===1?'':'s'} in the circuit`;\r\n  const s=menu.querySelector('[data-fw-start]');if(s){s.disabled=!n;s.textContent='START FULL WORKOUT'+(n?` · ${n}`:'');}\r\n  menu.querySelector('.fw-hub')?.setAttribute('data-lit',String(connected.size>0));\r\n }\r\n function paintLadder(id,k=0){\r\n  const sec=menu.querySelector(`.fw-style[data-style=\"${id}\"]`);if(!sec)return;const lv=lvl(id),l=styleLadder(id);\r\n  sec.querySelectorAll('.fw-row input').forEach((input,i)=>{input.checked=i<lv;input.closest('.fw-row').style.setProperty('--d',Math.abs(i+1-k));});\r\n  sec.querySelector('.fw-pick').textContent=!st.powered.has(id)?(cap(id)?'OFF':'LOCKED'):lv?l[lv-1].name:'NO SWITCH';\r\n  paintHead();\r\n }\r\n function render(){\r\n  const open=[...menu.querySelectorAll('.fw-style[open]')].map(d=>d.dataset.style),top=menu.scrollTop;\r\n  menu.innerHTML=`<div class=\"fw-body\"><svg class=\"fw-wires\" aria-hidden=\"true\">${styles.map(s=>`<g class=\"fw-cord\" data-w=\"${s.id}\"><path class=\"fw-c-sh\"/><path class=\"fw-c-jk\"/><path class=\"fw-c-hl\"/><path class=\"fw-c-pl\"/></g>`).join('')}</svg>\r\n   <div class=\"fw-power\"><i class=\"fw-screw l\"></i><div class=\"fw-pw-l\"><span class=\"fw-plate\">Power source</span><p class=\"fw-count\"></p></div><button type=\"button\" class=\"fw-hub\" data-hub aria-label=\"Power all sections\" data-lit=\"false\"><span aria-hidden=\"true\">⏻</span></button><i class=\"fw-screw r\"></i></div>\r\n   <div class=\"fw-bay\" aria-hidden=\"true\"></div>\r\n   ${styles.map(style=>{\r\n    const ids=style.exercises.map(e=>e.id),max=cap(style.id),on=st.powered.has(style.id),lv=lvl(style.id),capped=max===0,hint=capped?(reason(ids[0])||'Locked'):'';\r\n    return `<details class=\"fw-style\" data-style=\"${style.id}\" data-power=\"${on&&connected.has(style.id)?'on':'off'}\"${capped?' data-capped':''}><summary><span class=\"fw-plate\">${esc(style.name)}</span><span class=\"fw-pick\"></span><i class=\"fw-socket\" data-socket=\"${style.id}\"></i></summary>\r\n     ${capped?`<p class=\"fw-hint\">${esc(hint)}</p>`:''}\r\n     ${style.exercises.map((e,i)=>{const ok=canUse(e.id);return `<label class=\"fw-row${ok?'':' fw-locked'}${on?'':' fw-dead'}\" style=\"--r:${i}\"><input type=\"checkbox\" value=\"${e.id}\" data-k=\"${i+1}\"${i<lv?' checked':''}${on&&i<max?'':' disabled'}><i class=\"fw-lamp\" aria-hidden=\"true\"></i><span class=\"fw-name\"><b class=\"fw-lv\">${i+1}</b> ${esc(e.name)}</span><i class=\"fw-tog\" aria-hidden=\"true\">${ok?'':'<b class=\"fw-guard\">LOCK</b>'}</i>${ok?'':`<small>${esc(reason(e.id)||'Locked')}</small>`}</label>`;}).join('')}\r\n    </details>`;}).join('')}\r\n   <button type=\"button\" class=\"fw-start\" data-fw-start>START FULL WORKOUT</button>\r\n   ${styles.map(s=>{const capped=cap(s.id)===0;return `<button type=\"button\" class=\"fw-plug${capped?' fw-capped':''}\" data-plug=\"${s.id}\" aria-pressed=\"${st.powered.has(s.id)}\" aria-label=\"Power ${esc(s.name)}\"${capped?' aria-disabled=\"true\"':''} title=\"${capped?esc(reason(s.exercises[0].id)||'Locked'):'Power '+esc(s.name)}\"><i aria-hidden=\"true\"></i></button>`;}).join('')}\r\n  </div>`;\r\n  for(const d of menu.querySelectorAll('.fw-style'))if(open.includes(d.dataset.style))d.open=true;\r\n  for(const s of styles)paintLadder(s.id);\r\n  menu.scrollTop=top;rig.rebind();\r\n }\r\n\r\n // ---- power cables: one hub, one verlet rope per section, gravity from the app's tilt source ----\r\n const rig=(()=>{\r\n  const R={};let body,pos,raf=0,unsub=null,tilt=null,tiltAt=-1e9,grav={gx:0,gy:1},last=0,plugs={},paths={};\r\n  const dist=(a,b)=>Math.hypot(a.x-b.x,a.y-b.y);\r\n  const measure=()=>{\r\n   body=menu.querySelector('.fw-body');if(!body)return false;const b=body.getBoundingClientRect(),c=e=>{const r=e.getBoundingClientRect();return {x:r.left+r.width/2-b.left,y:r.top+r.height/2-b.top};};\r\n   const hub=c(body.querySelector('.fw-hub'));pos={hub:{x:hub.x,y:hub.y+24},sock:{},b,bayBottom:body.querySelector('.fw-bay').getBoundingClientRect().bottom-b.top-6};\r\n   for(const s of styles){const e=body.querySelector(`[data-socket=\"${s.id}\"]`);pos.sock[s.id]=e&&e.offsetParent?c(e):null;}return true;};\r\n  const rebind=()=>{plugs={};paths={};for(const s of styles){plugs[s.id]=menu.querySelector(`[data-plug=\"${s.id}\"]`);paths[s.id]=menu.querySelector(`[data-w=\"${s.id}\"]`);}\r\n   if(details.open){if(!measure())return;if(reduced())settle();else if(!raf)loop();}};\r\n  const slackOf=i=>ROPE.plugSlack+(i%5)*ROPE.slackSpread;\r\n  const state=(s,i)=>R[s.id]??=(()=>{const hub=pos.hub,looseLen=ROPE.looseLength+(i%2)*ROPE.looseStagger,sock=pos.sock[s.id],on=st.powered.has(s.id)&&sock;\r\n   const c={i,looseLen,len:looseLen,rope:makeRope(hub.x,hub.y,looseLen),pin:null,drag:null};\r\n   if(on){c.pin={...sock};c.len=dist(hub,sock)*slackOf(i);c.rope=makeRope(hub.x,hub.y,c.len);c.rope.pts.forEach((p,j,a)=>{const f=j/(a.length-1);p.x=p.px=hub.x+(sock.x-hub.x)*f;p.y=p.py=hub.y+(sock.y-hub.y)*f;});connected.add(s.id);paintPower(s.id);}\r\n   return c;})();\r\n  function tick(dt,t,instant){\r\n   const target=tilt&&t-tiltAt<1500?tilt:{gx:Math.sin(t/1000*Math.PI*2*ROPE.swayHz)*ROPE.sway,gy:1};\r\n   const k=instant?1:Math.min(1,dt*10);grav={gx:grav.gx+(target.gx-grav.gx)*k,gy:grav.gy+(target.gy-grav.gy)*k};\r\n   styles.forEach((s,i)=>{\r\n    const c=state(s,i),sock=pos.sock[s.id],hub=pos.hub,powered=st.powered.has(s.id)&&sock;let end=null,len=c.looseLen;\r\n    if(c.drag){end={x:c.drag.cx-pos.b.left,y:c.drag.cy-pos.b.top};len=Math.max(c.looseLen,dist(hub,end)*1.03+8);c.pin=null;}\r\n    else if(powered){\r\n     c.pin??={...c.rope.pts.at(-1)};const f=instant?1:Math.min(1,dt*14);c.pin.x+=(sock.x-c.pin.x)*f;c.pin.y+=(sock.y-c.pin.y)*f;\r\n     if(dist(c.pin,sock)<1.5){c.pin={...sock};if(!connected.has(s.id)){connected.add(s.id);home(s.id);}}\r\n     end=c.pin;len=Math.max(dist(hub,end)*slackOf(i),dist(hub,end)+6);\r\n    }else{c.pin=null;if(connected.delete(s.id))paintPower(s.id);}\r\n    c.len+=(len-c.len)*(instant?1:Math.min(1,dt*10));if(end)c.len=Math.max(c.len,dist(hub,end)+2);\r\n    const g=powered&&!c.drag?grav:rotate(grav,((i>>1)*2+(i&1))*ROPE.fanDeg);\r\n    stepRope(c.rope,dt,g,{anchor:hub,end,length:c.len});\r\n    // The cord channel: plugged cords stay in the right gutter, loose ones inside the board above the rows. Physics still runs inside.\r\n    const W=pos.b.width,pts=c.rope.pts,plugged=end&&!c.drag,lo=plugged?W-ROPE.gutter+6:26,hi=W-(plugged?6:26);\r\n    for(let j=1;j<pts.length;j++){const q=pts[j];if(q.x<lo||q.x>hi){q.x=Math.min(hi,Math.max(lo,q.x));q.px=q.x;}if(!end&&!c.drag){const y=Math.min(pos.bayBottom,Math.max(hub.y+26,q.y));if(y!==q.y){q.y=y;q.py=y;}}}\r\n   });\r\n  }\r\n  function draw(){\r\n   styles.forEach(s=>{const c=R[s.id];if(!c)return;const pts=c.rope.pts,e=pts.at(-1),q=pts.at(-2),a=Math.atan2(e.y-q.y,e.x-q.x)*180/Math.PI-90,d=ropePath(pts),g=paths[s.id];\r\n    g?.querySelectorAll('path').forEach(pa=>pa.setAttribute('d',d));g?.classList.toggle('on',connected.has(s.id));\r\n    const p=plugs[s.id];if(p)p.style.transform=`translate(${(e.x-22).toFixed(1)}px,${(e.y-22).toFixed(1)}px) rotate(${a.toFixed(1)}deg)`;});\r\n  }\r\n  function frame(now){raf=0;if(!details.open||!body?.isConnected)return;const dt=Math.min(1/30,(now-(last||now))/1000||1/60);last=now;\r\n   if(!measure())return;edgeScroll();tick(dt,now,false);draw();raf=requestAnimationFrame(frame);}\r\n  function loop(){last=0;raf=requestAnimationFrame(frame);}\r\n  function settle(){if(!measure())return;grav={gx:0,gy:1};for(let i=0;i<ROPE.settleSteps;i++)tick(1/60,0,true);draw();}\r\n  const edgeScroll=()=>{const d=styles.map(s=>R[s.id]?.drag).find(Boolean);if(!d)return;const r=menu.getBoundingClientRect();if(d.cy<r.top+40)menu.scrollTop-=10;else if(d.cy>r.bottom-40)menu.scrollTop+=10;};\r\n  function home(id){ // the plug clicked in: spark, click sound, lamps power up in sequence\r\n   detent('lever');const sec=menu.querySelector(`.fw-style[data-style=\"${id}\"]`),sock=menu.querySelector(`[data-socket=\"${id}\"]`);\r\n   paintPower(id);sec?.classList.add('fw-pulse');sock?.classList.add('fw-spark');setTimeout(()=>{sec?.classList.remove('fw-pulse');sock?.classList.remove('fw-spark');},1300);}\r\n  return {R,rebind,\r\n   open(){if(unsub)return;measure();unsub=subscribePhoneMotion(g=>{tilt={gx:g.gx,gy:g.gy};tiltAt=performance.now();});if(reduced())settle();else if(!raf)loop();},\r\n   close(){unsub?.();unsub=null;tilt=null;cancelAnimationFrame(raf);raf=0;},\r\n   resettle(){if(details.open&&reduced())settle();},\r\n   dragStart(id,e){const c=R[id];if(!c)return;c.drag={cx:e.clientX,cy:e.clientY,sx:e.clientX,sy:e.clientY,moved:false};},\r\n   dragMove(id,e){const d=R[id]?.drag;if(!d)return;d.cx=e.clientX;d.cy=e.clientY;if(Math.hypot(d.cx-d.sx,d.cy-d.sy)>6)d.moved=true;},\r\n   dragEnd(id){const c=R[id],d=c?.drag;if(!d)return null;measure();const end={x:d.cx-pos.b.left,y:d.cy-pos.b.top},sock=pos.sock[id];c.drag=null;c.pin={...end};return {moved:d.moved,near:!!sock&&dist(end,sock)<64};}};\r\n })();\r\n const paintPower=id=>{const sec=menu.querySelector(`.fw-style[data-style=\"${id}\"]`);if(sec)sec.dataset.power=st.powered.has(id)&&connected.has(id)?'on':'off';paintHead();};\r\n function setPower(id,on){\r\n  if(cap(id)===0||on===st.powered.has(id))return;\r\n  on?st.powered.add(id):st.powered.delete(id);save();detent(on?'switch':'lever');\r\n  const sec=menu.querySelector(`.fw-style[data-style=\"${id}\"]`),max=cap(id);\r\n  sec?.querySelectorAll('.fw-row').forEach((row,i)=>{row.classList.toggle('fw-dead',!on);row.querySelector('input').disabled=!on||i>=max;});\r\n  menu.querySelector(`[data-plug=\"${id}\"]`)?.setAttribute('aria-pressed',String(on));\r\n  if(!on)connected.delete(id);paintPower(id);paintLadder(id);rig.resettle();\r\n  if(on&&reduced()){connected.add(id);paintPower(id);}\r\n }\r\n menu.addEventListener('click',event=>{\r\n  const b=event.target.closest('button');if(!b)return;\r\n  if(b.matches('[data-fw-start]'))begin();\r\n  else if(b.matches('[data-hub]')){const open=styles.filter(s=>cap(s.id)>0),all=open.every(s=>st.powered.has(s.id));open.forEach(s=>setPower(s.id,!all));}\r\n  else if(b.matches('.fw-plug')){if(b.classList.contains('fw-capped'))menu.querySelector(`.fw-style[data-style=\"${b.dataset.plug}\"]`).open=true;else if(event.detail===0)setPower(b.dataset.plug,!st.powered.has(b.dataset.plug));}\r\n });\r\n menu.addEventListener('pointerdown',event=>{const b=event.target.closest('.fw-plug');if(!b||b.classList.contains('fw-capped'))return;event.preventDefault();b.setPointerCapture?.(event.pointerId);rig.dragStart(b.dataset.plug,event);});\r\n menu.addEventListener('pointermove',event=>{const b=event.target.closest('.fw-plug');if(b)rig.dragMove(b.dataset.plug,event);});\r\n const release=event=>{const b=event.target.closest?.('.fw-plug');if(!b)return;const id=b.dataset.plug,r=rig.dragEnd(id);if(!r)return;setPower(id,r.moved?r.near:!st.powered.has(id));};\r\n menu.addEventListener('pointerup',release);menu.addEventListener('pointercancel',release);\r\n menu.addEventListener('change',event=>{\r\n  const i=event.target.closest('input[type=checkbox]');if(!i)return;const id=i.closest('.fw-style').dataset.style,k=Number(i.dataset.k);\r\n  st.levels[id]=tapLevel(lvl(id),k,cap(id));save();detent('switch');paintLadder(id,k);\r\n });\r\n menu.addEventListener('toggle',()=>rig.resettle(),true);\r\n details.addEventListener('keydown',event=>{if(event.key==='Escape'&&details.open){details.open=false;details.querySelector('summary').focus();}});\r\n document.addEventListener('pointerdown',event=>{if(details.open&&!details.contains(event.target))details.open=false;});\r\n const goals=document.getElementById('podGoals');\r\n details.addEventListener('toggle',()=>{if(details.open){goals.open=false;rig.open();}else rig.close();});goals.addEventListener('toggle',()=>{if(goals.open)details.open=false;});\r\n details.querySelector('summary').addEventListener('click',()=>{try{if(!localStorage.getItem('myr5.tiltPermission'))void requestPhoneMotion();}catch{}});\r\n\r\n // ---- runner ----\r\n let run=null;\r\n const nameOf=id=>EXERCISES[id]?.name??id;\r\n const paint=html=>{hud.innerHTML=html;hud.hidden=false;};\r\n const bar=()=>{const exTotal=run.steps.filter(s=>s.type==='exercise').length,n=run.done.length+1;paint(`<div class=\"fw-top\"><b>FULL WORKOUT ${n}/${exTotal}</b><span>${esc(nameOf(run.steps[run.i].id))}</span><button type=\"button\" data-fw-end>END</button></div>`);hud.dataset.mode='exercise';};\r\n function finish(reasonText){\r\n  if(!run)return;const r=run;run=null;\r\n  const xp=r.done.reduce((t,d)=>t+(d.xp||0),0),secs=Math.round((Date.now()-r.t0)/1000);\r\n  hud.dataset.mode='summary';\r\n  paint(`<div class=\"fw-panel\"><h2>${reasonText==='ended'?'Workout ended':'Full workout done'}</h2>\r\n   <p class=\"fw-big\">${r.done.length} of ${r.steps.filter(s=>s.type==='exercise').length} exercises · ${clock(secs)}${xp?` · +${xp} XP`:''}</p>\r\n   <ol>${r.done.map(d=>`<li>${esc(nameOf(d.id))} <span>${Math.round(d.value)}${d.unit}</span></li>`).join('')||'<li>No sets finished.</li>'}</ol>\r\n   <button type=\"button\" data-fw-close>Done</button></div>`);\r\n  if(reasonText!=='ended')voice?.say('Full workout complete. Great work.',{interrupt:true});\r\n }\r\n hud.addEventListener('click',event=>{\r\n  const b=event.target.closest('button');if(!b)return;\r\n  if('fwEnd' in b.dataset){const r=run;document.getElementById('stop')?.click();if(run===r)finish('ended');}\r\n  if('fwClose' in b.dataset){hud.hidden=true;hud.innerHTML='';if(document.body.dataset.screen==='rest')void leaveRest?.();}\r\n  if('fwSkip' in b.dataset&&run)run.skip=true;\r\n });\r\n const unitOf=id=>{const k=EXERCISES[id]?.kind;return k==='hold'||k==='pace'?'s':k==='steps'?' steps':' reps';};\r\n\r\n async function playBreak(r,step){\r\n  const end=Date.now()+step.seconds*1000;r.skip=false;hud.dataset.mode='break';\r\n  voice?.say(`${step.between==='styles'?'Style change. ':''}Rest. Next up, ${nameOf(step.next.id)}.`,{interrupt:true});\r\n  while(run===r&&!r.skip&&Date.now()<end){\r\n   const left=Math.ceil((end-Date.now())/1000),style=circuitStyles().find(s=>s.id===step.next.style)?.name;\r\n   paint(`<div class=\"fw-panel\"><p class=\"fw-eyebrow\">${step.between==='styles'?'STYLE BREAK':'BREATHER'}</p><div class=\"fw-clock\" role=\"timer\">${clock(left)}</div>\r\n    <p>Next up</p><p class=\"fw-big\">${esc(nameOf(step.next.id))}</p><p class=\"fw-sub\">${esc(style||'')} · ${r.steps.find(s=>s.id===step.next.id).goal}${unitOf(step.next.id)}</p>\r\n    <button type=\"button\" data-fw-skip>Skip rest</button> <button type=\"button\" data-fw-end>End workout</button></div>`);\r\n   await wait(250);\r\n  }\r\n }\r\n async function play(r){\r\n  while(run===r&&r.i<r.steps.length){\r\n   const step=r.steps[r.i];\r\n   if(step.type==='break'){await playBreak(r,step);if(run!==r)return;await leaveRest?.();for(let t=0;t<40&&document.body.dataset.screen==='rest';t++)await wait(150);r.i++;continue;}\r\n   bar();select(step.id,step.goal);\r\n   const completed=new Promise(res=>{r.onSet=res;}),aborted=new Promise(res=>{r.onAbort=()=>res(null);}),result=await Promise.race([Promise.resolve(start()).then(()=>completed),aborted]);\r\n   if(run!==r)return;\r\n   if(!result){finish('ended');return;}\r\n   r.done.push({id:step.id,value:result.value,xp:result.xp,unit:unitOf(step.id)});r.i++;\r\n  }\r\n  if(run===r)finish('done');\r\n }\r\n function begin(){\r\n  if(run||document.body.dataset.tracking==='true'||!selection().length)return;\r\n  const steps=buildFullWorkout(selection(),{seed:Date.now()});\r\n  details.open=false;run={steps,i:0,done:[],t0:Date.now()};void play(run);\r\n }\r\n window.addEventListener('myr5:set-complete',event=>{if(run&&event.detail?.mode===run.steps[run.i]?.id)run.onSet?.(event.detail);});\r\n window.addEventListener('myr5:workout-stopped',()=>{if(run&&run.steps[run.i]?.type==='exercise')run.onAbort?.();});\r\n for(const name of ['myr5:performance-progress','myr5:account-ready'])window.addEventListener(name,render);\r\n render();\r\n return {render,selection,get running(){return !!run;}};\r\n}\r\n","full-workout.mjs":"// FULL WORKOUT (circuit) mode: pure logic only (no DOM) so it is unit tested directly.\r\n// One of each checked exercise, grouped into style blocks (a style = a focus group: boxing, legs, ...),\r\n// shuffled, with a long rest between style blocks and a short one between exercises in a block.\r\nimport {EXERCISES,FOCUS_GROUPS} from './exercise-library.mjs';\r\n\r\n// TUNING KNOBS -- real phones need tuning; change only here.\r\nexport const FULL_WORKOUT={\r\n restBetweenExercisesSeconds:15, // short breather inside a style block\r\n restBetweenStylesSeconds:60,    // long break when the style changes\r\n goalByKind:{reps:5,hold:20,pace:20,steps:12,jumps:10}, // reps / seconds per exercise\r\n shuffleStyles:true,             // false = keep the library's style order\r\n storageKey:'myr5-full-workout-v1',\r\n};\r\n\r\n/** Every exercise a circuit may use. Endless runner modes (Cool Cardio) are not a counted set. */\r\nexport const circuitExercises=()=>Object.values(EXERCISES).filter(e=>!e.endless);\r\nexport const circuitStyles=()=>FOCUS_GROUPS.map(g=>({id:g.id,name:g.name,exercises:circuitExercises().filter(e=>e.group===g.id)})).filter(g=>g.exercises.length);\r\nexport const goalFor=id=>FULL_WORKOUT.goalByKind[EXERCISES[id]?.kind]??5;\r\n\r\n/** Small seeded PRNG (mulberry32): same seed, same circuit. */\r\nexport function seededRandom(seed){let a=(Number(seed)||0)>>>0;return()=>{a=a+0x6D2B79F5>>>0;let t=a;t=Math.imul(t^t>>>15,t|1);t^=t+Math.imul(t^t>>>7,t|61);return((t^t>>>14)>>>0)/4294967296;};}\r\nexport function shuffle(list,random=Math.random){const a=[...list];for(let i=a.length-1;i>0;i--){const j=Math.floor(random()*(i+1));[a[i],a[j]]=[a[j],a[i]];}return a;}\r\n\r\n/** Steps: {type:'exercise',id,style,goal} and {type:'break',seconds,between:'styles'|'exercises',next:{id,style}}. */\r\nexport function buildFullWorkout(ids,{seed=Date.now(),knobs=FULL_WORKOUT}={}){\r\n const random=seededRandom(seed),chosen=[...new Set(ids)].filter(id=>EXERCISES[id]&&!EXERCISES[id].endless);\r\n const byStyle=new Map();\r\n for(const id of chosen){const style=EXERCISES[id].group;if(!byStyle.has(style))byStyle.set(style,[]);byStyle.get(style).push(id);}\r\n let styles=[...byStyle.keys()];\r\n if(knobs.shuffleStyles)styles=shuffle(styles,random);\r\n const flat=[];\r\n for(const style of styles)for(const id of shuffle(byStyle.get(style),random))flat.push({type:'exercise',id,style,goal:goalFor(id)});\r\n const steps=[];\r\n flat.forEach((step,i)=>{\r\n  if(i){const styleChange=flat[i-1].style!==step.style;steps.push({type:'break',between:styleChange?'styles':'exercises',seconds:styleChange?knobs.restBetweenStylesSeconds:knobs.restBetweenExercisesSeconds,next:{id:step.id,style:step.style}});}\r\n  steps.push(step);\r\n });\r\n return steps;\r\n}\r\n\r\n// ---- power + level ladder ----\r\n// A style (focus group) is powered by its plug. Inside a powered style the exercises are a level ladder, easiest first\r\n// (library order). Level L means switches 1..L are engaged; the circuit uses the exercise at switch L, one per style.\r\nexport const styleLadder=style=>circuitExercises().filter(e=>e.group===style);\r\n/** Highest level reachable: the leading run of unlocked exercises (a locked rung kills every rung above it). */\r\nexport function maxLevel(style,canUse){const l=styleLadder(style);let n=0;while(n<l.length&&canUse(l[n].id))n++;return n;}\r\n/** Tap switch k (1-based): an off switch engages 1..k; an engaged switch drops the ladder to k-1. Dead switches (above max) do nothing. */\r\nexport function tapLevel(level,k,max=Infinity){if(k>max||k<1)return level;return k<=level?k-1:k;}\r\n/** One exercise per powered style at its engaged level; unpowered or level-0 styles contribute none. */\r\nexport function sectionPicks({powered,levels,canUse}){\r\n const out=[];\r\n for(const style of powered){const l=styleLadder(style),lv=Math.min(levels[style]??0,maxLevel(style,canUse));if(lv>=1)out.push(l[lv-1].id);}\r\n return out;\r\n}\r\n","gala-handoff.mjs":"import {isInstalled} from './install-context.mjs';\r\nconst KEY='myr5-gala-run-v1';\r\nconst valid=data=>data?.version===1&&/^[0-9a-f-]{36}$/.test(data.id)&&/^[a-f0-9]{64}$/.test(data.token);\r\nexport function decodeGala(raw){if(typeof raw!=='string'||raw.length>18000)throw Error('This Gala invitation is invalid.');let data;try{data=JSON.parse(decodeURIComponent(escape(atob(raw))));}catch{throw Error('This Gala invitation is unreadable.');}if(!valid(data))throw Error('This Gala invitation is invalid.');return data;}\r\nfunction importIdentity(data){if(window.MBS_DJ?.valid(data.dj))localStorage.setItem('mbs-dj-identity-v1',JSON.stringify(data.dj));if(data.avatar&&window.GalaAvatar){try{localStorage.setItem('mominc-avatar-v1',JSON.stringify(window.GalaAvatar.normalize(data.avatar)));window.dispatchEvent(new Event('mominc-avatar-change'));}catch{}}}\r\nexport function captureGala(){const params=new URLSearchParams(location.hash.slice(1)),raw=params.get('gala');if(raw){params.delete('gala');history.replaceState(null,'',location.pathname+location.search+(params.size?'#'+params:''));const data=decodeGala(raw);localStorage.setItem(KEY,JSON.stringify(data));importIdentity(data);return data;}try{const data=JSON.parse(localStorage.getItem(KEY));return valid(data)?data:null;}catch{return null;}}\r\nasync function request(path,data,token){const r=await fetch('/api/gala/'+path,{method:data?'POST':'GET',credentials:'same-origin',cache:'no-store',headers:{...(data?{'Content-Type':'application/json'}:{}),...(token?{Authorization:'Bearer '+token}:{})},body:data?JSON.stringify(data):undefined,signal:AbortSignal.timeout(15000)});const value=await r.json();if(!r.ok)throw Error(value.error||'Your Gala run could not connect. Retry while connected.');return value;}\r\nexport async function prepareGalaInstall(){const data=captureGala();if(data)await request('install-draft',{id:data.id,token:data.token});return data;}\r\nasync function restoreGala(){let data=captureGala();if(!data){data=(await request('install-draft')).data;if(valid(data))localStorage.setItem(KEY,JSON.stringify(data));else data=null;}if(data)importIdentity(data);return data;}\r\nexport async function saveInstalledRun(){if(!isInstalled())return null;const data=await restoreGala();if(!data)return null;const value=await request('runs/'+data.id+'/install',{installed:true},data.token);if(value.djName&&!window.MBS_DJ?.read()){const base=value.djName.split(' · ')[0],dj={version:1,base,moniker:value.moniker,parts:base.split(' ').slice(0,3),chosenAt:value.startedAt,completedAt:value.startedAt};while(dj.parts.length<3)dj.parts.push('DJ');if(window.MBS_DJ?.valid(dj)){localStorage.setItem('mbs-dj-identity-v1',JSON.stringify(dj));window.dispatchEvent(new Event('mominc-avatar-change'));}}return value;}\r\nexport async function mountGalaReturn(){let data,error='';try{data=isInstalled()?await restoreGala():captureGala();}catch(e){error=e.message;}if(!data&&!error)return;let panel=document.getElementById('galaReturn');if(panel)return;panel=document.createElement('aside');panel.id='galaReturn';panel.style.cssText='padding:14px;margin:12px 0;background:#111d28;color:#acffe0;border:2px outset #648d99;font:14px/1.5 monospace';panel.innerHTML='<strong>GOON GALA · RUN ARCHIVE</strong><p role=\"status\"></p><a href=\"https://mominc.online/gala/terminal/\" style=\"color:#befaff\">Return to the Gala terminal →</a><button type=\"button\" style=\"margin-left:10px;min-height:40px\">Retry saving</button>';(document.querySelector('.install-card')||document.getElementById('accountContent')||document.body).append(panel);const message=panel.querySelector('p'),retry=panel.querySelector('button');async function save(){try{retry.disabled=true;await prepareGalaInstall();const run=await saveInstalledRun();message.textContent=run?(run.completedAt?'App received. Your run is saved. Join the rankings at the Gala terminal.':'App received. Finish your remaining run clearances at the Gala terminal.'):'Install and open MYR5 from its app icon to save this run.';retry.hidden=!!run;}catch(e){message.textContent=e.message;retry.hidden=false;}finally{retry.disabled=false;}}retry.onclick=save;window.addEventListener('online',save);if(error)message.textContent=error;else save();}\r\n","gesture-controls.mjs":"import {ExerciseRecognizer,GestureConfirmation} from './exercise-gestures.mjs';\r\nimport {openCamera,cameraFacing,widestZoom} from './camera.mjs';\r\n// The workout's pinned tracker, same-origin (scripts/mediapipe.mjs). A template keeps esbuild from resolving it.\r\nconst MEDIAPIPE='/vendor/mediapipe/0.10.14';\r\nconst timeout=(promise,ms,message)=>{let t;return Promise.race([promise,new Promise((_,reject)=>{t=setTimeout(()=>reject(new Error(message)),ms);})]).finally(()=>clearTimeout(t));};\r\nexport class HandControl {\r\n constructor(options){Object.assign(this,options);this.recognizer=new ExerciseRecognizer();this.confirmation=new GestureConfirmation();this.running=false;this.models=[];this.frame=0;this.lastVideo=-1;this.lastInference=-Infinity;}\r\n async start(){\r\n  this.running=true;\r\n  try{\r\n   const stream=await openCamera(this.camera,20);if(!this.running){stream.getTracks().forEach(t=>t.stop());return;}this.stream=stream;this.video.srcObject=stream;\r\n   await timeout(this.video.play(),10000,'No camera frames. Try the other camera.');if(!this.running)return;\r\n   await widestZoom(stream.getVideoTracks()[0]);if(!this.running)return;\r\n   this.video.style.transform=cameraFacing(stream.getVideoTracks()[0],this.camera)==='user'?'scaleX(-1)':'none';this.video.hidden=false;\r\n   this.message('Loading gesture recognition…');\r\n   const api=await timeout(import(`${MEDIAPIPE}/vision_bundle.mjs`),20000,'Gesture library download timed out.');if(!this.running)return;\r\n   const files=await timeout(api.FilesetResolver.forVisionTasks(MEDIAPIPE+'/wasm'),20000,'Gesture runtime download timed out.');if(!this.running)return;\r\n   const create=async(Type,modelAssetPath,options)=>{let expired=false;const loading=Type.createFromOptions(files,{baseOptions:{modelAssetPath,delegate:'CPU'},runningMode:'VIDEO',...options});loading.then(model=>{if(!this.running||expired)model.close();},()=>{});try{const model=await timeout(loading,60000,'Gesture model loading timed out.');if(this.running)this.models.push(model);return model;}catch(error){expired=true;throw error;}};\r\n   this.pose=await create(api.PoseLandmarker,MEDIAPIPE+'/pose_landmarker_lite.task',{numPoses:1});if(!this.running)return;\r\n   this.hand=await create(api.HandLandmarker,'https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task',{numHands:2,minHandDetectionConfidence:.6,minTrackingConfidence:.6});if(!this.running)return;\r\n   this.message('Make an exercise gesture, then hold thumbs up to confirm.');this.loop();\r\n  }catch(error){this.stop();throw error;}\r\n }\r\n stop(){this.running=false;cancelAnimationFrame(this.frame);this.models.splice(0).forEach(m=>{try{m.close();}catch{}});this.stream?.getTracks().forEach(t=>t.stop());this.stream=null;this.video.pause();this.video.srcObject=null;this.video.hidden=true;this.confirmation.reset();}\r\n loop(){\r\n  if(!this.running)return;\r\n  try{\r\n   const now=performance.now();\r\n   // Two small trackers run only in this optional menu, at most eight passes/s.\r\n   if(now-this.lastInference>=125&&this.video.readyState>=2&&this.video.currentTime!==this.lastVideo){\r\n    this.lastInference=now;this.lastVideo=this.video.currentTime;\r\n    const pose=this.pose.detectForVideo(this.video,now),hands=this.hand.detectForVideo(this.video,now);\r\n    const input=this.recognizer.update(pose.landmarks[0],hands.landmarks,now,this.video.videoWidth/this.video.videoHeight);\r\n    this.onGesture(this.confirmation.update(input,now));\r\n   }\r\n   if(this.running)this.frame=requestAnimationFrame(()=>this.loop());\r\n  }catch(error){this.stop();this.onError('Gesture tracking stopped. '+error.message);}\r\n }\r\n}\r\n","guest-history-choice.mjs":"import {IMPORT_UPLOAD_MANIFEST} from './local-coach/import-upload-manifest.mjs';\r\n\r\n// Opening/dismissing history records no choice and starts no upload. The user\r\n// selects concrete workouts and a destination shown by this render.\r\nexport function mountGuestHistoryChoice({host,adapter,getAccount,transitions,onChange=()=>{}}){\r\n let generation=0;\r\n const clear=()=>{generation++;host.replaceChildren();adapter.stop();};\r\n const unsubscribe=transitions.subscribe(clear);\r\n const element=(tag,text)=>{const node=document.createElement(tag);if(text!==undefined)node.textContent=text;return node;};\r\n async function render(){\r\n  const run=++generation,displayed=getAccount(),rows=await adapter.history();if(run!==generation)return;\r\n  host.replaceChildren();if(!rows.length)return;\r\n  host.append(element('h3','Choose how to keep device history'));\r\n  host.append(element('p','Signing in does not upload these workouts. Imported history stays outside rankings and rewards.'));\r\n  const status=element('p');status.setAttribute('role','status');\r\n  const options=element('div'),selected=new Set(),buttons=[];\r\n  for(const row of rows){\r\n   const line=element('label'),checkbox=element('input');checkbox.type='checkbox';checkbox.disabled=!row.selectable;\r\n   checkbox.addEventListener('change',()=>{if(checkbox.checked)selected.add(row.workout.clientWorkoutId);else selected.delete(row.workout.clientWorkoutId);});\r\n   const label=`${row.workout.metadata?.name||row.workout.mode} · ${new Date(row.workout.completedAt).toLocaleString()} · ${row.status.replaceAll('_',' ')}`;\r\n   line.append(checkbox,document.createTextNode(label));options.append(line,element('br'));\r\n  }\r\n  host.append(options,status);\r\n  async function act(work){\r\n   if(run!==generation)return;buttons.forEach(button=>button.disabled=true);\r\n   try{await work();if(run!==generation)return;await render();onChange();}\r\n   catch(error){if(run===generation)status.textContent=error.message;}\r\n   finally{if(run===generation)buttons.forEach(button=>button.disabled=false);}\r\n  }\r\n  const button=(label,work)=>{const node=element('button',label);node.type='button';node.addEventListener('click',()=>void act(work));buttons.push(node);host.append(node);return node;};\r\n  const choice=kind=>{if(selected.size<1||selected.size>100)throw Error('Select between one and 100 workouts.');return adapter.choose(kind,[...selected],displayed);};\r\n  button('Keep selected workouts local',()=>choice('keep_local'));\r\n  if(displayed?.user?.id){\r\n   host.append(element('p',`Import destination: ${displayed.user.email||displayed.user.id}`));\r\n   button('Save import choice for selected workouts',()=>choice('import'));\r\n   button('Check for account deletion',()=>adapter.reconcileDeletedTarget(displayed));\r\n   if(IMPORT_UPLOAD_MANIFEST.uploadsEnabled===true){\r\n    button('Import saved choices',()=>adapter.upload(displayed));\r\n    const parked=rows.filter(row=>row.status==='parked'&&row.item?.targetAccountId===displayed.user.id&&row.item.targetDataEpoch===displayed.dataEpoch).map(row=>row.item.claimId);\r\n    if(parked.length)button('Resume paused imports',()=>adapter.upload(displayed,{resumeParkedClaimIds:parked}));\r\n   }else host.append(element('p','Uploads are disabled in this build. Your choice is saved only on this device.'));\r\n  }else host.append(element('p','Sign in to choose an import destination.'));\r\n }\r\n return {render,close(){clear();unsubscribe();}};\r\n}\r\n","hand-companion.css":".avatar-dialog{width:min(94vw,560px)}.avatar-dialog h2{font-size:1.2rem}.avatar-dialog p,.avatar-dialog a,.avatar-dialog summary,.avatar-dialog button{font-size:1rem}.gala-import{margin:12px 0;padding:12px;border:1px solid #b08bc4;border-radius:12px}.gala-import a{display:block;margin-top:12px}.hand-subsection{display:grid;grid-template-columns:96px minmax(0,1fr);gap:16px;align-items:center;margin-top:24px;padding-top:20px;border-top:1px solid #a57aad66}.hand-subsection img{width:96px;height:120px;object-fit:contain;background:#1c1229;border-radius:14px}.hand-subsection small{font-size:.875rem;color:#dbb1ea}.hand-subsection h3{font-size:1.3rem;margin:4px 0}.hand-subsection p{line-height:1.4;margin:6px 0 12px}.hand-subsection button{width:100%}\r\n.avatar-dialog.hand-editing{width:min(1200px,100vw);max-width:100vw;height:96dvh;max-height:100dvh;padding:12px;overflow:hidden}.hand-editing>header{height:44px;margin:0}.hand-editing #handEditorPanel{height:calc(100% - 44px);display:grid;grid-template-rows:44px minmax(0,1fr)}.hand-editor-bar{display:flex;align-items:center;justify-content:space-between;gap:12px}.hand-editor-bar span{font-size:.875rem;color:#d8c1e3}#handEditorFrame{display:block;width:100%;height:100%;min-height:0;border:0;border-radius:14px;background:#6427a5}.hand-editing #identitySummary{display:none}\r\n.rest-hand{position:absolute;left:calc(50% + 36px);bottom:15%;width:clamp(95px,29vw,165px);height:clamp(115px,34vw,190px);z-index:8;pointer-events:none}#restHandMount,#restHandMount canvas{width:100%;height:100%;display:block}#restHandFallback{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}#restHandFallback[hidden]{display:none}.hand-team{display:grid;grid-template-columns:1fr auto;align-items:center;gap:7px 12px;padding:12px 0 0;font-size:.875rem;color:#e6c8ee}.hand-team progress{width:100%;height:9px;accent-color:#d99bff}.hand-team small{font-size:.875rem;color:#e6c8ee}.hand-team button{font-size:.875rem}.rest-feedback{min-height:2.8em}#identitySummary[hidden],#handEditorPanel[hidden]{display:none}\r\n@media(max-width:600px){.avatar-dialog.hand-editing{margin:0;width:100vw;height:100dvh;border-radius:0;padding:8px}.hand-editing>header{height:42px}.hand-editing #handEditorPanel{height:calc(100% - 42px);grid-template-rows:42px minmax(0,1fr)}.hand-editor-bar span{display:none}.hand-subsection{grid-template-columns:75px minmax(0,1fr);gap:12px}.hand-subsection img{width:75px}}\r\n","hand-companion.mjs":"const HAND_KEY='handborne-recipe-v4';\r\nexport function initHandCompanion(){\r\n const $=id=>document.getElementById(id);let companion=null,loading=null,inRest=false,disposed=false;\r\n function preview(){let family=11;try{const design=JSON.parse(localStorage.getItem(HAND_KEY));if(Number.isInteger(design?.sections?.palm)&&design.sections.palm>=0&&design.sections.palm<23)family=design.sections.palm;}catch{}\r\n  for(const id of ['identityHandPreview','restHandFallback'])$(id).src='/handborne/previews/family-'+String(family).padStart(2,'0')+'.png?v=5';\r\n }\r\n function status(text){$('handTeamStatus').textContent=text;const failed=/could not|unavailable/i.test(text);$('retryHand').hidden=!failed;$('restHandFallback').hidden=!failed;}\r\n async function load(){if(companion){companion.setActive(inRest);return;}if(loading)return loading;\r\n  loading=(async()=>{try{const {createHandCompanion}=await import('/handborne/companion.mjs');if(disposed||!inRest)return;companion=createHandCompanion($('restHandMount'),{onStatus:status});companion.setActive(inRest);}catch{status('3D hand unavailable. Your hand can still help with team strikes.');}finally{loading=null;}})();return loading;\r\n }\r\n function edit(){$('identitySummary').hidden=true;$('handEditorPanel').hidden=false;$('identity').classList.add('hand-editing');$('handEditorFrame').src='/handborne/index.html?embed=1';$('backToAvatar').focus();}\r\n function back(){ $('handEditorFrame').removeAttribute('src');$('handEditorPanel').hidden=true;$('identitySummary').hidden=false;$('identity').classList.remove('hand-editing');preview();if(inRest)companion?.refresh(); }\r\n $('customizeHand').addEventListener('click',edit);$('backToAvatar').addEventListener('click',()=>{back();$('customizeHand').focus();});$('identity').addEventListener('close',back);\r\n $('retryHand').addEventListener('click',()=>companion?companion.refresh():load());\r\n const changed=event=>{if(event.key===HAND_KEY||event.key===null)preview();};\r\n const message=event=>{if(event.origin!==location.origin||event.source!==$('handEditorFrame').contentWindow||event.data?.type!=='handborne:changed')return;preview();};\r\n window.addEventListener('storage',changed);window.addEventListener('message',message);preview();\r\n return {edit,enter(){inRest=true;preview();$('handCharge').value=0;$('handChargeLabel').textContent='Team strike in 3 taps';void load();},leave(){inRest=false;companion?.setActive(false);},hit(hit){companion?.gesture(hit.assisted?'fist-bump':hit.blocked?'high-five':'point-at-you');$('handCharge').value=hit.charge;$('handChargeLabel').textContent=hit.assisted?'Team strike!':`Team strike in ${3-hit.charge} ${hit.charge===2?'tap':'taps'}`;$('handTeamStatus').textContent=hit.assisted?(hit.blocked?'Helping Hand strikes. Coach blocks!':'Helping Hand doubles your strike!'):'Helping Hand is charging up.';},dispose(){disposed=true;companion?.dispose();window.removeEventListener('storage',changed);window.removeEventListener('message',message);}};\r\n}\r\n","hand-controls.mjs":"import {PinchGesture,cursorPoint} from './hand-gesture.mjs';\r\nimport {openCamera,cameraFacing,widestZoom} from './camera.mjs';\r\nconst timeout=(promise,ms,message)=>{let t;return Promise.race([promise,new Promise((_,reject)=>{t=setTimeout(()=>reject(new Error(message)),ms);})]).finally(()=>clearTimeout(t));};\r\nexport class HandControl {\r\n  constructor(options){Object.assign(this,options);this.gesture=new PinchGesture();this.running=false;this.tracker=null;this.stream=null;this.frame=0;this.hover=null;this.held=null;this.lastVideo=-1;this.lastInference=0;}\r\n  async start(){\r\n    this.running=true;\r\n    try{\r\n      if(!navigator.mediaDevices?.getUserMedia)throw new Error('Open the forwarded localhost page to use the camera.');\r\n      const stream=await openCamera(this.camera,24);\r\n      if(!this.running){stream.getTracks().forEach(t=>t.stop());return;}this.stream=stream;this.video.srcObject=stream;\r\n      await timeout(this.video.play(),10000,'No camera frames. Try the other camera in the workout controls.');if(!this.running)return;\r\n      await widestZoom(stream.getVideoTracks()[0]);if(!this.running)return;\r\n      this.mirrored=cameraFacing(stream.getVideoTracks()[0],this.camera)==='user';this.video.style.transform=this.mirrored?'scaleX(-1)':'none';this.video.hidden=false;\r\n      this.message('Loading hand tracker…');\r\n      const api=await timeout(import('/vendor/mediapipe/0.10.14/vision_bundle.mjs'),20000,'Hand tracker download failed. Check your connection.');if(!this.running)return;\r\n      const files=await timeout(api.FilesetResolver.forVisionTasks('/vendor/mediapipe/0.10.14/wasm'),20000,'Hand runtime download timed out.');if(!this.running)return;\r\n      let expired=false;const loading=api.HandLandmarker.createFromOptions(files,{baseOptions:{modelAssetPath:'https://storage.googleapis.com/mediapipe-models/hand_landmarker/hand_landmarker/float16/1/hand_landmarker.task',delegate:'CPU'},runningMode:'VIDEO',numHands:1,minHandDetectionConfidence:.65,minHandPresenceConfidence:.6,minTrackingConfidence:.6});\r\n      loading.then(tracker=>{if(!this.running||expired)tracker.close();},()=>{});\r\n      try{this.tracker=await timeout(loading,45000,'Hand model loading timed out.');}catch(error){expired=true;throw error;}\r\n      if(!this.running){this.tracker=null;return;}\r\n      this.message('Show an open hand, then point and pinch.');this.loop();\r\n    }catch(error){this.stop();throw error;}\r\n  }\r\n  clearAim(){this.hover?.classList.remove('hand-hover');this.held?.classList?.remove('hand-down');this.hover=null;this.held=null;this.dragging=false;this.cursor.hidden=true;}\r\n  stop(){this.running=false;cancelAnimationFrame(this.frame);try{this.tracker?.close();}catch{}this.tracker=null;this.stream?.getTracks().forEach(t=>t.stop());this.stream=null;this.video.pause();this.video.srcObject=null;this.video.hidden=true;this.gesture.reset();this.clearAim();}\r\n  loop(){\r\n    if(!this.running||!this.tracker)return;\r\n    try{\r\n      const now=performance.now();\r\n      // Hand menus only need ~15 updates/s; no pose tracker runs at the same time.\r\n      if(now-this.lastInference>=65&&this.video.readyState>=2&&this.video.currentTime!==this.lastVideo){\r\n        this.lastInference=now;this.lastVideo=this.video.currentTime;\r\n        const result=this.tracker.detectForVideo(this.video,now),p=this.gesture.update(result.landmarks[0],now,this.video.videoWidth/this.video.videoHeight);\r\n        if(!p){this.clearAim();this.message('Show an open hand to regain control.');}\r\n        else{\r\n          const r=this.root.getBoundingClientRect(),clip={left:r.left,top:r.top,width:r.width,height:r.height};\r\n          const point=cursorPoint(p,clip,this.mirrored),hit=document.elementFromPoint(point.x,point.y);\r\n          const button=hit?.closest('button[data-hand]:not(:disabled)'),target=button&&this.root.contains(button)?button:null;\r\n          this.cursor.hidden=false;this.cursor.style.left=point.x+'px';this.cursor.style.top=point.y+'px';this.cursor.classList.toggle('pinched',p.pinched);\r\n          if(target!==this.hover){this.hover?.classList.remove('hand-hover');this.hover=target;target?.classList.add('hand-hover');this.hoverSince=now;}\r\n          if(p.down){\r\n            this.downAt=now;this.held=target&&now-this.hoverSince>=100?target:null;this.held?.classList.add('hand-down');\r\n            this.dragging=!target&&!!hit?.closest('#holoStage');\r\n          }\r\n          if(p.pinched&&this.dragging&&this.previous){this.rotate((point.x-this.previous.x)*.008,(point.y-this.previous.y)*.006);}\r\n          if(p.up){const chosen=this.held;const activate=chosen&&chosen===target&&now-this.downAt>=80;this.held?.classList.remove('hand-down');this.held=null;this.dragging=false;if(activate)chosen.click();}\r\n          if(p.canceled){this.held?.classList.remove('hand-down');this.held=null;this.dragging=false;}\r\n          this.previous=point;if(this.running)this.message(!p.armed?'Open your hand to begin.':this.dragging?'Move your pinched hand to rotate the hologram.':p.pinched?'Release to select.':'Point at a button, pinch, then release.');\r\n        }\r\n      }\r\n      if(this.running)this.frame=requestAnimationFrame(()=>this.loop());\r\n    }catch(error){this.stop();this.onError('Hand tracking stopped. '+error.message);}\r\n  }\r\n}\r\n","hand-gesture.mjs":"// Pinch signature adapted from Ian's Barehands cockpit, originally by Jared\r\n// Rhodenizer. AGPL-3.0-or-later. Menu gestures intentionally omit board throws.\r\nconst clamp=(x,a,b)=>Math.max(a,Math.min(b,x));\r\nexport class PinchGesture {\r\n  constructor(){this.reset();}\r\n  reset(){this.pinched=false;this.armed=false;this.okPrev=false;this.okEma=0;this.bad=0;this.last=0;this.point=null;}\r\n  update(raw,now,aspect=1){\r\n    if(!raw||raw.length!==21||raw.some(p=>!Number.isFinite(p.x)||!Number.isFinite(p.y))){this.reset();return null;}\r\n    if(this.last&&now-this.last>250)this.reset();\r\n    const dt=this.last?Math.min(100,now-this.last):50;this.last=now;\r\n    const p=raw.map(q=>({x:q.x*aspect,y:q.y})),d=(a,b)=>Math.hypot(p[a].x-p[b].x,p[a].y-p[b].y);\r\n    const span=d(0,9),width=d(5,17);if(span<.025||width<.002||span/width>12){this.reset();return null;}\r\n    const finger=(tip,mcp)=>d(tip,0)/Math.max(d(mcp,0),.001);\r\n    const f8=finger(8,5),back=(finger(12,9)+finger(16,13)+finger(20,17))/3;\r\n    const palmAspect=span/width,ratio=d(4,8)/span,thumb=d(4,13)/span;\r\n    const signature=(back-f8>.18&&back>1.3)||(palmAspect<2&&thumb>.95)||(back>1.6&&f8>1.6);\r\n    this.okEma=.7*this.okEma+.3*Number(signature);\r\n    const was=this.pinched;let canceled=false;\r\n    if(ratio>=.55){this.armed=true;this.pinched=false;}\r\n    else if(!was&&this.armed&&ratio<(palmAspect<2?.38:.32)&&((signature&&this.okPrev)||this.okEma>.55)){this.pinched=true;this.started=now;this.bad=0;}\r\n    if(was&&now-this.started<400){this.bad=signature?0:this.bad+1;if(this.bad>=4){this.pinched=false;this.armed=false;canceled=true;}}\r\n    this.okPrev=signature;\r\n    const point={x:(raw[4].x+raw[8].x)/2,y:(raw[4].y+raw[8].y)/2};\r\n    const alpha=1-Math.exp(-dt/55);this.point=this.point?{x:this.point.x+(point.x-this.point.x)*alpha,y:this.point.y+(point.y-this.point.y)*alpha}:point;\r\n    return {...this.point,pinched:this.pinched,down:!was&&this.pinched,up:was&&!this.pinched&&!canceled,canceled,armed:this.armed};\r\n  }\r\n}\r\n// Map a comfortable central camera region across the control surface.\r\nexport function cursorPoint(p,rect,mirrored=false){return {x:rect.left+clamp(((mirrored?1-p.x:p.x)-.12)/.76,0,1)*rect.width,y:rect.top+clamp((p.y-.08)/.84,0,1)*rect.height};}\r\n","handborne/index.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><meta name=\"theme-color\" content=\"#6427a5\"><title>Helping Hand · Customizer</title><meta name=\"description\" content=\"Customize your Helping Hand with a live preview, creature styles, nails, scales and gestures.\">  <script type=\"module\" src=\"/audio/standalone-sound.mjs\"></script>  <script src=\"/public-entry.mjs\" data-entry=\"/handborne\" data-module=\"/handborne/assets/hand-entry-DiWC2DxB.js\"></script>\r\n  <link rel=\"stylesheet\" crossorigin href=\"/handborne/assets/hand-entry-BUSUnr2n.css\">\r\n<link rel=\"stylesheet\" href=\"/shader-effects.css\"><script type=\"module\" src=\"/shader-entry.mjs\"></script></head><body><div id=\"root\"></div></body></html>\r\n","handborne/source/app/anatomy-comparison.tsx":"'use client';\r\nimport { HandViewer } from './hand-viewer';\r\nimport { useState } from 'react';\r\nimport { Switch } from '@/components/ui/switch';\r\nimport { REGIONS } from './catalog';\r\nimport type { Selection } from './recipe';\r\nexport const ANATOMY_STUDIES=[\r\n  {id:7,name:'Skeletal',description:'Open metacarpals, joint heads and slender bone shafts.'},\r\n  {id:18,name:'Mechanical',description:'Segment housings, hinge pins and a palm chassis.'},\r\n  {id:13,name:'Stone',description:'Broad palm slabs, faceted fingers and heavy knuckles.'},\r\n];\r\nexport const SOFT_STUDIES=[\r\n  {id:20,name:'Fluffy',description:'Curved fur strands, a soft undercoat and small round nails.'},\r\n  {id:21,name:'Jelly',description:'Glossy lime jelly with a translucent body and trapped bubbles.'},\r\n  {id:22,name:'Baby',description:'A smaller hand with short, plump fingers and soft wrist rolls.'},\r\n];\r\nexport function AnatomyComparison({variant='anatomy'}:{variant?:'anatomy'|'soft'}){\r\n  const soft=variant==='soft',studies=soft?SOFT_STUDIES:ANATOMY_STUDIES;\r\n  const [gray,setGray]=useState(!soft);\r\n  return <main className=\"anatomy-comparison\">\r\n    <header className=\"comparison-heading\"><div><p>HELPING HAND / {soft?'SOFT FORMS':'ANATOMY STUDIES'}</p><h1>{soft?'Fluffy. Jelly. Little.':'Three different structures.'}</h1></div><a href=\"/handborne/\">Back to customizer</a></header>\r\n    <div className=\"comparison-options\"><p className=\"comparison-note\">Same camera and lighting. Drag to inspect{soft?' — the baby hand is smaller in real scale':''}.</p><label className=\"gray-control\">Plain gray<Switch aria-label=\"Show all hands without colors or translucency\" checked={gray} onCheckedChange={setGray} /></label></div>\r\n    <div className=\"comparison-grid\">{studies.map(study=><section className=\"comparison-card\" key={study.id}>\r\n      <div className=\"comparison-canvas\"><HandViewer selection={Object.fromEntries(REGIONS.map(r=>[r.id,study.id])) as Selection} poseId=\"relaxed\" nailShape=\"family\" animate={false} gray={gray} selectedRegion=\"fingers\" exploded={false} onSelectRegion={()=>{}} /></div>\r\n      <div className=\"comparison-caption\"><h2>{study.name}</h2><p>{study.description}</p><a href={'/handborne/?anatomy='+study.id}>Customize this hand →</a></div>\r\n    </section>)}</div><a className=\"comparison-other\" href={'/handborne/?compare='+(soft?'anatomy':'soft')}>{soft?'Compare skeletal, mechanical & stone':'Compare fluffy, jelly & baby'} →</a>\r\n  </main>;\r\n}\r\n","handborne/source/app/browser-entry.tsx":"import {createRoot} from 'react-dom/client';\r\nimport Home from './page';\r\nimport './globals.css';\r\nimport './design-studio.css';\r\ncreateRoot(document.getElementById('root')!).render(<Home />);\r\n","handborne/source/app/catalog.ts":"import {BUILTIN_SURFACE_PROFILES,SPECIAL_SURFACE_PROFILES,builtinSurfaceProfile} from './material-patterns';\r\nimport palettes from './palettes.json';\r\nexport const REGIONS = [\r\n  { id: 'nails', label: 'Nails', short: 'Nails', description: 'Five claw and nail forms' },\r\n  { id: 'fingertips', label: 'Finger tips', short: 'Tips', description: 'Distal pads and final phalanges' },\r\n  { id: 'fingers', label: 'Fingers & knuckles', short: 'Fingers', description: 'Joined finger shafts, bases and knuckles' },\r\n  { id: 'palm', label: 'Palm', short: 'Palm', description: 'The inner hand surface' },\r\n  { id: 'back_of_hand', label: 'Back of hand', short: 'Back', description: 'The dorsal hand surface' },\r\n  { id: 'wrist', label: 'Wrist', short: 'Wrist', description: 'Stump, cuff and transition' },\r\n] as const;\r\n\r\nexport type RegionId = (typeof REGIONS)[number]['id'];\r\n\r\nexport type StyleFamily = {\r\n  id: number;\r\n  name: string;\r\n  realm: string;\r\n  primary: string;\r\n  secondary: string;\r\n  accent: string;\r\n  emissive: string;\r\n  roughness: number;\r\n  metalness: number;\r\n  paletteId?:string;\r\n  detail: string | 'clean' | 'vine' | 'caps' | 'plates' | 'scales' | 'spines' | 'coral' | 'bone' | 'mist' | 'flame' | 'halo' | 'void' | 'eyes' | 'rock' | 'crystal' | 'magma' | 'ice' | 'storm' | 'gears' | 'neon' | 'fur' | 'jelly' | 'baby';\r\n};\r\n\r\nconst LEGACY_STYLES: StyleFamily[] = [\r\n  { id: 0, name: 'Mortal', realm: 'Baseline · Earth', primary: '#b9856f', secondary: '#714c42', accent: '#f0c0a3', emissive: '#000000', roughness: 0.72, metalness: 0.02, detail: 'clean' },\r\n  { id: 1, name: 'Verdant', realm: 'Wildroot · Dimension 12', primary: '#3f7448', secondary: '#1e3b2b', accent: '#b8dd6e', emissive: '#172d13', roughness: 0.88, metalness: 0, detail: 'vine' },\r\n  { id: 2, name: 'Mycelial', realm: 'Sporesea · Dimension 09', primary: '#d5c7ae', secondary: '#776b82', accent: '#f59ec4', emissive: '#6d234a', roughness: 0.92, metalness: 0, detail: 'caps' },\r\n  { id: 3, name: 'Chitin', realm: 'Carapace · Dimension 31', primary: '#4f263d', secondary: '#180f20', accent: '#d17663', emissive: '#240716', roughness: 0.3, metalness: 0.28, detail: 'plates' },\r\n  { id: 4, name: 'Reptilian', realm: 'Scalehold · Dimension 04', primary: '#5f7a3f', secondary: '#283621', accent: '#cfb85c', emissive: '#101c08', roughness: 0.76, metalness: 0.04, detail: 'scales' },\r\n  { id: 5, name: 'Abyssal', realm: 'Deep Trench · Dimension 88', primary: '#132a42', secondary: '#06111f', accent: '#4edfd3', emissive: '#0b756f', roughness: 0.34, metalness: 0.12, detail: 'spines' },\r\n  { id: 6, name: 'Coral', realm: 'Living Reef · Dimension 22', primary: '#e46867', secondary: '#70344c', accent: '#ffd27a', emissive: '#8b2438', roughness: 0.83, metalness: 0, detail: 'coral' },\r\n  { id: 7, name: 'Skeletal', realm: 'Ossuary · Dimension 00', primary: '#d8d0af', secondary: '#80785f', accent: '#fff7d1', emissive: '#17160e', roughness: 0.9, metalness: 0, detail: 'bone' },\r\n  { id: 8, name: 'Spectral', realm: 'Veil · Dimension 13', primary: '#8ed9cd', secondary: '#294c58', accent: '#d5fff8', emissive: '#248e86', roughness: 0.18, metalness: 0.04, detail: 'mist' },\r\n  { id: 9, name: 'Infernal', realm: 'Cinder Court · Dimension 66', primary: '#7b211e', secondary: '#260b0a', accent: '#ff8a2a', emissive: '#d33812', roughness: 0.58, metalness: 0.1, detail: 'flame' },\r\n  { id: 10, name: 'Celestial', realm: 'High Orbit · Dimension 07', primary: '#e6dca4', secondary: '#786da7', accent: '#fffbd7', emissive: '#8d74d6', roughness: 0.24, metalness: 0.5, detail: 'halo' },\r\n  { id: 11, name: 'Voidborn', realm: 'Null Expanse · Dimension ∅', primary: '#16101f', secondary: '#060409', accent: '#9f64ff', emissive: '#482285', roughness: 0.16, metalness: 0.36, detail: 'void' },\r\n  { id: 12, name: 'Eldritch', realm: 'Watcher Fold · Dimension 47', primary: '#6b426c', secondary: '#252038', accent: '#b6ef63', emissive: '#4e7628', roughness: 0.64, metalness: 0.04, detail: 'eyes' },\r\n  { id: 13, name: 'Stone Golem', realm: 'Deep Strata · Dimension 19', primary: '#6f7068', secondary: '#393b37', accent: '#b7a37d', emissive: '#171811', roughness: 0.98, metalness: 0, detail: 'rock' },\r\n  { id: 14, name: 'Crystal', realm: 'Prism Vault · Dimension 52', primary: '#896bc2', secondary: '#302e66', accent: '#e0c8ff', emissive: '#5a3da8', roughness: 0.12, metalness: 0.3, detail: 'crystal' },\r\n  { id: 15, name: 'Magma', realm: 'Mantle · Dimension 03', primary: '#4a1713', secondary: '#140706', accent: '#ffb22f', emissive: '#e44712', roughness: 0.78, metalness: 0.06, detail: 'magma' },\r\n  { id: 16, name: 'Glacial', realm: 'White Silence · Dimension 71', primary: '#93c9df', secondary: '#315a76', accent: '#ebfdff', emissive: '#3c93bb', roughness: 0.2, metalness: 0.14, detail: 'ice' },\r\n  { id: 17, name: 'Stormcharged', realm: 'Tempest Ring · Dimension 28', primary: '#48536e', secondary: '#1a2236', accent: '#c3f7ff', emissive: '#3ebde0', roughness: 0.4, metalness: 0.32, detail: 'storm' },\r\n  { id: 18, name: 'Clockwork Robot', realm: 'Brass Meridian · Dimension 14', primary: '#9a6a37', secondary: '#33251d', accent: '#efd08c', emissive: '#5b2c12', roughness: 0.32, metalness: 0.82, detail: 'gears' },\r\n  { id: 19, name: 'Neon Synth', realm: 'Aftergrid · Dimension 20', primary: '#251d54', secondary: '#0b0921', accent: '#ff5bd7', emissive: '#b519ac', roughness: 0.22, metalness: 0.55, detail: 'neon' },\r\n  { id: 20, name: 'Fluffy', realm: 'Cloudburrow · Soft forms', primary: '#d6a987', secondary: '#bb8969', accent: '#ffe4c3', emissive: '#000000', roughness: .88, metalness: 0, detail: 'fur' },\r\n  { id: 21, name: 'Jelly', realm: 'Lime Lagoon · Soft forms', primary: '#a7ec69', secondary: '#f1ffd4', accent: '#c9ff90', emissive: '#000000', roughness: .13, metalness: 0, detail: 'jelly' },\r\n  { id: 22, name: 'Baby', realm: 'Little One · Soft forms', primary: '#efb398', secondary: '#d68e7c', accent: '#ffe2d5', emissive: '#000000', roughness: .52, metalness: 0, detail: 'baby' },\r\n];\r\n\r\nconst specialPaletteIds=[\"opal-jelly\", \"bubble-glass\", \"prism-crystal\", \"holo-foil\", \"glitter-resin\", \"galaxy-geode\",\"caustic-slime\",\"blister-hide\",\"rotten-rind\",\"parasite-nest\",\"exposed-sinew\",\"abyssal-maw\",\"circuit-alloy\",\"servo-armor\",\"chrome-rib\",\"carbon-mech\",\"hazard-panel\",\"reactor-glass\"];\r\nexport const STYLES:StyleFamily[]=[...LEGACY_STYLES,\r\n ...[{id:30,name:'Flat',roughness:.55,metalness:0},{id:31,name:'Clay',roughness:.92,metalness:0},...BUILTIN_SURFACE_PROFILES,builtinSurfaceProfile(56)!,...SPECIAL_SURFACE_PROFILES].map(p=>{\r\n  const palette=palettes.find(row=>row.id===specialPaletteIds[p.id-57]);\r\n  const [primary,secondary,accent]=palette?.colors??['#8b8f9a','#4a4d55','#e7e9ee'];\r\n  return{id:p.id,name:p.name,realm:'Surface finish',primary,secondary,accent,emissive:'#000000',roughness:p.roughness,metalness:p.metalness,detail:p.name.toLowerCase(),paletteId:palette?.id};\r\n })];\r\nexport const styleFor=(id:number)=>STYLES.find(style=>style.id===id)!;\r\nexport const hasStyle=(id:number)=>STYLES.some(style=>style.id===id);\r\nexport const DEFAULT_SELECTION: Record<RegionId, number> = {\r\n  nails: 14,\r\n  fingertips: 5,\r\n  fingers: 12,\r\n  palm: 3,\r\n  back_of_hand: 17,\r\n  wrist: 18,\r\n};\r\n\r\nexport const PURE_PRESETS = STYLES.filter(style=>![8,11].includes(style.id)).map((style) => ({\r\n  name: style.name,\r\n  description: `A pure ${style.name.toLowerCase()} hand`,\r\n  values: Object.fromEntries(REGIONS.map((region) => [region.id, style.id])) as Record<RegionId, number>,\r\n}));\r\n\r\n\r\n// Legacy IDs stay importable; retired looks are excluded from new picks.\r\nexport const PICKER_STYLES=STYLES.filter(style=>![8,11].includes(style.id)).sort((a,b)=>Number(b.id>=63)-Number(a.id>=63)||Number(b.id>=57)-Number(a.id>=57));\r\n","handborne/source/app/companion.ts":"import * as THREE from 'three';\r\nimport {RoomEnvironment} from 'three/examples/jsm/environments/RoomEnvironment.js';\r\nimport {assemble} from './hand-model';\r\nimport {bindHand,applyHandPose,type HandRig} from './pose-rig';\r\nimport {getPose,mixPoses} from './poses';\r\nimport {parseDesign,type HandDesign} from './recipe';\r\nimport {DEFAULT_SELECTION} from './catalog';\r\nimport {DEFAULT_NAIL_SHAPE} from './nails';\r\nexport {parseDesign};\r\nexport const HAND_KEY='handborne-recipe-v4';\r\nexport function readHand(storage:Pick<Storage,'getItem'>):HandDesign {\r\n  try{const value=storage.getItem(HAND_KEY);if(value)return parseDesign(value);}catch{}\r\n  return {sections:{...DEFAULT_SELECTION},pose:'relaxed',nailShape:DEFAULT_NAIL_SHAPE};\r\n}\r\nexport function createHandCompanion(host:HTMLDivElement,{storage=localStorage,onStatus=(_text:string)=>{},cropWrist=false}={}){\r\n  let disposed=false,revision=0,frame=0,rig:HandRig|null=null,hand:THREE.Group|null=null;\r\n  let currentPose=getPose('relaxed'),transition:{from:ReturnType<typeof getPose>;to:ReturnType<typeof getPose>;start:number}|null=null;\r\n  let gestureUntil=0,lastFrame=0,active=true;\r\n  const reduced=window.matchMedia('(prefers-reduced-motion: reduce)');\r\n  const renderer=new THREE.WebGLRenderer({alpha:true,antialias:true});renderer.setPixelRatio(Math.min(devicePixelRatio,1.35));renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=1.4;\r\n  renderer.domElement.setAttribute('role','img');renderer.domElement.setAttribute('aria-label','Your customized Helping Hand beside your Gala avatar');host.appendChild(renderer.domElement);\r\n  const scene=new THREE.Scene(),root=new THREE.Group();scene.add(root);\r\n  const environment=new RoomEnvironment(),pmrem=new THREE.PMREMGenerator(renderer);scene.environment=pmrem.fromScene(environment,.04).texture;environment.dispose();pmrem.dispose();\r\n  const camera=new THREE.PerspectiveCamera(34,1,.005,3);camera.position.set(.045,.08,.39);camera.lookAt(0,.035,0);\r\n  if(cropWrist){camera.position.set(.035,.10,.25);camera.lookAt(0,.085,0);renderer.domElement.setAttribute('aria-label','Your customized DJ hand');}\r\n  scene.add(new THREE.HemisphereLight('#fff4e0','#655179',2));\r\n  const key=new THREE.DirectionalLight('#fff2ce',3.6);key.position.set(.3,.3,.4);scene.add(key);\r\n  const rim=new THREE.DirectionalLight('#d899ff',2.5);rim.position.set(-.3,.15,-.2);scene.add(rim);\r\n  const resize=()=>{const w=Math.max(host.clientWidth,1),h=Math.max(host.clientHeight,1);renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();};\r\n  const observer=new ResizeObserver(resize);observer.observe(host);resize();\r\n  function release(){if(hand)hand.removeFromParent();rig?.dispose();rig=null;hand=null;}\r\n  async function refresh(){\r\n    const run=++revision;onStatus('Your hand is arriving…');\r\n    try{const design=readHand(storage),next=await assemble(design.sections,design.nailShape,design.scalePattern);\r\n      if(disposed||run!==revision){next.traverse(o=>{if(o instanceof THREE.Mesh&&o.userData.ownedGeometry)o.geometry.dispose();});return;}\r\n      release();hand=next;rig=bindHand(next);root.add(next);currentPose=getPose('relaxed');transition=null;applyHandPose(rig,currentPose);onStatus('Helping Hand ready');\r\n    }catch{if(!disposed&&run===revision)onStatus('Hand could not load. Tap Retry hand.');}\r\n  }\r\n  function gesture(id:string){if(disposed)return;transition={from:currentPose,to:getPose(id),start:performance.now()};gestureUntil=performance.now()+1500;}\r\n  function tick(now:number){if(disposed)return;frame=requestAnimationFrame(tick);if(!active||document.hidden||now-lastFrame<40)return;lastFrame=now;\r\n    if(transition&&rig){const t=reduced.matches?1:Math.min(1,(now-transition.start)/220);currentPose=mixPoses(transition.from,transition.to,t);applyHandPose(rig,currentPose);if(t===1)transition=null;}\r\n    if(gestureUntil&&now>gestureUntil){gestureUntil=0;transition={from:currentPose,to:getPose('relaxed'),start:now};}\r\n    root.position.y=reduced.matches?0:Math.sin(now/850)*.003;root.rotation.y=reduced.matches?0:Math.sin(now/1400)*.08;\r\n    renderer.render(scene,camera);\r\n  }\r\n  const changed=(event:StorageEvent)=>{if(event.key===HAND_KEY||event.key===null)void refresh();};window.addEventListener('storage',changed);\r\n  frame=requestAnimationFrame(tick);void refresh();\r\n  return {refresh,gesture,setActive(value:boolean){active=value;},dispose(){if(disposed)return;disposed=true;revision++;cancelAnimationFrame(frame);observer.disconnect();window.removeEventListener('storage',changed);release();scene.environment?.dispose();renderer.dispose();renderer.domElement.remove();}};\r\n}\r\n","handborne/source/app/design-studio.css":".design-studio{height:100dvh;min-height:0;display:grid;grid-template-rows:auto minmax(0,1fr);overflow:hidden;padding:12px;background:linear-gradient(150deg,#b784df,#6427a5 65%,#351055);gap:12px}\r\n.design-studio .topbar{min-height:64px;padding:8px 14px;background:#fff3d6;border:2px solid #2a0a44;border-radius:14px;box-shadow:0 4px 0 #2a0a44;gap:12px;flex-wrap:nowrap}\r\n.design-studio .brand-copy h1{font-size:clamp(1rem,2.3vw,1.65rem);margin-top:4px}.design-studio .brand-copy p{font-size:.875rem}\r\n.design-studio .creator-grid{height:100%;min-height:0;display:grid;grid-template-columns:minmax(0,1fr) minmax(310px,370px);gap:14px;padding:0}\r\n.design-studio .viewport-panel{height:100%;min-height:0;grid-column:auto;grid-row:auto;order:0;border-radius:20px;box-shadow:0 5px 0 #250b3c}\r\n.design-studio .viewport-chrome{top:18px;left:18px}.design-studio .orbit-hint{top:50px;left:18px;font-size:.875rem;letter-spacing:0;text-transform:none}.design-studio .view-tools{bottom:18px;left:14px;right:14px;justify-content:center;gap:8px}\r\n.design-controls{min-height:0;min-width:0;border:2px solid #2a0a44;border-radius:16px;overflow:hidden;background:#fff6e3;box-shadow:0 5px 0 #250b3c}\r\n.design-tabs{height:100%;gap:0}.design-tabs [data-slot=tabs-list]{width:100%;height:52px;min-height:52px;padding:5px;border-radius:0;background:#efdae9;border-bottom:2px solid #c5a2d6;gap:2px}.design-tabs [data-slot=tabs-trigger]{font-size:1rem;padding:8px 7px;color:#4a1a86}.design-tabs [data-slot=tabs-trigger][data-active]{background:#4a1a86;color:#fff6e3;border-radius:9px}\r\n.control-scroll{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:16px;scrollbar-width:thin}.design-heading h2{font-family:var(--font-display);font-size:1.35rem;margin:0 0 4px}.design-heading p{font-size:1rem;line-height:1.25;color:#654773;margin:0 0 14px}\r\n.scope-switch{display:flex;gap:8px;margin-bottom:12px}.scope-switch>*{flex:1}.scope-switch [aria-pressed=true]{background:#4a1a86;color:#fff6e3}.part-target{display:flex;align-items:end;gap:8px;margin-bottom:12px}.part-target label{flex:1;font-size:1rem}.part-target [data-slot=native-select-wrapper]{width:100%}\r\n.design-studio .style-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:0}.design-studio .style-grid button{position:relative;border:2px solid #d5bbdf;border-radius:10px;background:#21142b;padding:0;overflow:hidden;min-height:110px}.design-studio .style-grid button.is-active{border-color:#4a1a86;box-shadow:0 0 0 2px #ffd36e}.design-studio .style-grid img{display:block;width:100%;height:95px;object-fit:contain}.design-studio .tile-label{display:block;position:static;padding:5px 2px;background:#fff3d6;color:#351055;font-size:.875rem;line-height:1.1;text-align:center;white-space:normal}\r\n.design-studio .hand-shape-buttons,.pose-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin-top:14px}.pose-grid button{white-space:normal;height:auto;min-height:46px}.design-studio [aria-pressed=true]{border-color:#4a1a86}.pose-grid [aria-pressed=true],.design-studio .nail-shapes [aria-pressed=true]{background:#4a1a86;color:#fff6e3}.design-studio .nail-shop{margin-bottom:20px}.file-actions{display:grid;gap:12px}.control-note{font-size:1rem;line-height:1.3}.control-note button{text-decoration:underline}.save-indicator{font-size:.875rem;white-space:nowrap;color:#4a1a86}.design-studio .gray-control{margin:14px 0}\r\n@media(max-width:760px){.design-studio{padding:8px;gap:8px}.design-studio .topbar{min-height:62px;padding:6px 10px}.design-studio .top-actions{gap:4px;flex-wrap:nowrap}.design-studio .top-actions button{width:36px;min-width:36px;padding:6px}.design-studio .top-actions button span{display:none}.save-indicator{display:none}.design-studio .creator-grid{grid-template-columns:minmax(0,1fr);grid-template-rows:minmax(190px,43%) minmax(0,1fr);gap:9px}.design-studio .viewport-panel{height:100%;min-height:0}.design-studio .view-tools{bottom:9px}.design-studio .viewport-chrome{top:10px;left:12px}.design-studio .orbit-hint{top:37px;left:12px;font-size:.875rem}.control-scroll{padding:12px}.design-heading p{margin-bottom:10px}.design-studio .style-grid{grid-template-columns:repeat(4,minmax(0,1fr))}.design-studio .style-grid img{height:74px}.design-studio .style-grid button{min-height:100px}.design-studio .tile-label{font-size:.875rem}.design-tabs [data-slot=tabs-list]{height:48px;min-height:48px}.design-tabs [data-slot=tabs-trigger]{padding:7px 5px}}\r\n@media(max-width:350px){.design-studio .style-grid{grid-template-columns:repeat(3,minmax(0,1fr))}.design-studio .brand-copy p{font-size:.75rem}.design-studio .topbar{padding-inline:6px}}\r\n@media(max-height:550px) and (min-width:600px){.design-studio .creator-grid{grid-template-columns:minmax(0,1fr) minmax(290px,42%);grid-template-rows:minmax(0,1fr)}.design-studio .topbar{min-height:48px}.design-studio .brand-copy p{display:none}}\r\n","handborne/source/app/globals.css":"@import 'tailwindcss';\r\n@import 'tw-animate-css';\r\n@import 'shadcn/tailwind.css';\r\n@custom-variant dark (&:is(.dark *));\r\n@font-face{font-family:'Barlow Condensed';src:url('/handborne/fonts/barlow-400.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}\r\n@font-face{font-family:'Barlow Condensed';src:url('/handborne/fonts/barlow-500.ttf') format('truetype');font-weight:500;font-style:normal;font-display:swap}\r\n@font-face{font-family:'Barlow Condensed';src:url('/handborne/fonts/barlow-600.ttf') format('truetype');font-weight:600;font-style:normal;font-display:swap}\r\n@font-face{font-family:'Barlow Condensed';src:url('/handborne/fonts/barlow-700.ttf') format('truetype');font-weight:700;font-style:normal;font-display:swap}\r\n@font-face{font-family:'Bowlby One SC';src:url('/handborne/fonts/bowlby.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}\r\n@font-face{font-family:'Anton';src:url('/handborne/fonts/anton.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}\r\n@font-face{font-family:'VT323';src:url('/handborne/fonts/vt323.ttf') format('truetype');font-weight:400;font-style:normal;font-display:swap}\r\n@theme inline {\r\n  --color-background:var(--background);--color-foreground:var(--foreground);\r\n  --font-sans:var(--font-geist-sans);--font-mono:var(--font-geist-mono);\r\n  --color-primary:var(--primary);--color-primary-foreground:var(--primary-foreground);\r\n  --color-secondary:var(--secondary);--color-secondary-foreground:var(--secondary-foreground);\r\n  --color-muted:var(--muted);--color-muted-foreground:var(--muted-foreground);\r\n  --color-accent:var(--accent);--color-accent-foreground:var(--accent-foreground);\r\n  --color-card:var(--card);--color-card-foreground:var(--foreground);\r\n  --color-popover:var(--popover);--color-popover-foreground:var(--foreground);\r\n  --color-border:var(--border);--color-input:var(--input);--color-ring:var(--ring);\r\n  --color-destructive:var(--destructive);--radius-lg:.7rem;--radius-md:.5rem;--radius-sm:.35rem;--radius-xl:1rem;\r\n}\r\n:root {\r\n  --font-geist-sans:'Barlow Condensed';--font-geist-mono:'VT323';--font-headline:'Bowlby One SC';--font-display:'Anton';\r\n  --background:#fdf6e3;--foreground:#2a0a44;--card:#fff9ec;--popover:#fff9ec;\r\n  --primary:#7a2fc4;--primary-foreground:#fff9ec;--secondary:#ffd36e;--secondary-foreground:#2a0a44;\r\n  --muted:#edddec;--muted-foreground:#654773;--accent:#ffd36e;--accent-foreground:#2a0a44;\r\n  --destructive:#b91c51;--border:#4a1a86;--input:#7a2fc4;--ring:#ff2f7a;\r\n  --pur:#7a2fc4;--pur-d:#4a1a86;--pur-dd:#2a0a44;--gold:#ffd36e;--cream:#fdf6e3;--hot:#ff2f7a;--sig:#39ff9a;\r\n}\r\n*{box-sizing:border-box}\r\nhtml,body{min-height:100%;margin:0}\r\nbody{background:var(--background);color:var(--foreground);font-family:var(--font-geist-sans),Arial,sans-serif;font-size:1.125rem}\r\nbutton,input,textarea,select{font:inherit}button{cursor:pointer}button:disabled{cursor:default;opacity:.45}\r\nbutton:focus-visible,a:focus-visible{outline:3px solid var(--hot);outline-offset:3px}\r\n[data-slot=button]{min-height:2.65rem;font-size:1rem;border-radius:8px}\r\n.creator-shell{min-height:100vh;background:radial-gradient(120% 100% at 50% -15%,#fff7e6 0%,#ffe6b8 30%,#e9b6f0 65%,#b06fe0 100%)}\r\n.mom-ribbon{min-height:28px;padding:4px 18px;background:repeating-linear-gradient(45deg,var(--pur) 0 16px,var(--pur-d) 16px 32px);color:var(--gold);font:400 .875rem/1.4 var(--font-display),Impact,sans-serif;letter-spacing:.12em;text-align:center}\r\n.mom-ribbon span{margin-left:30px}\r\n.topbar{min-height:96px;display:flex;align-items:center;gap:24px;padding:12px 24px 16px;position:relative;z-index:5}\r\n.brand-copy p,.panel-kicker{margin:0;color:var(--pur-d);font:400 .875rem/1.4 var(--font-display),Impact,sans-serif;letter-spacing:.10em}\r\n.brand-copy p{color:#b91958}\r\n.brand-copy h1{margin:6px 0 0;font:400 clamp(1.4rem,2.6vw,2rem)/1.05 var(--font-headline),'Arial Black',sans-serif;letter-spacing:-.025em;text-shadow:2px 2px 0 var(--gold),4px 4px 0 #ae70d4}\r\n.brand-copy sup{font-family:Arial,sans-serif;font-size:.4em;vertical-align:super;text-shadow:none;margin-left:3px}\r\n.five-finger-badge{color:var(--pur-dd);background:var(--gold);border:2px solid var(--pur-dd);padding:7px 10px;transform:rotate(-3deg);white-space:nowrap;font-family:var(--font-display),Impact,sans-serif;font-size:.875rem;box-shadow:3px 3px 0 var(--pur)}\r\n.top-actions{margin-left:auto;display:flex;gap:8px;align-items:center}\r\n.top-actions [data-slot=button]{border:2px solid var(--pur-dd);box-shadow:0 3px 0 var(--pur-dd);font-weight:600}\r\n.top-actions [data-slot=button]:active{transform:translateY(2px);box-shadow:0 1px 0 var(--pur-dd)}\r\n.creator-grid{height:calc(100dvh - 124px);min-height:660px;display:grid;grid-template-columns:274px minmax(320px,1fr) 336px;gap:18px;padding:0 18px 20px}\r\n.region-panel,.style-panel{padding:20px 16px;background:var(--cream);overflow-y:auto;scrollbar-width:thin;scrollbar-color:#a66ad0 #f3e3eb;border:3px solid var(--pur-dd);border-radius:14px;box-shadow:5px 5px 0 var(--pur-dd)}\r\n.region-panel h2{font:400 1.45rem/1.2 var(--font-headline),'Arial Black',sans-serif;margin:10px 0 8px;letter-spacing:-.035em}\r\n.panel-intro{font-size:1rem;line-height:1.3;margin:0 0 20px;color:#654773}\r\n.region-list{display:grid;gap:10px}\r\n.region-card{border:2px solid #d4bde0;border-radius:9px;padding:2px 6px 2px 10px;background:#fffaf1;transition:background .15s}\r\n.region-card.is-active{border-color:var(--pur-dd);background:var(--gold);box-shadow:3px 3px 0 var(--pur)}\r\n.region-card-heading{display:flex;align-items:center;gap:4px}\r\n.region-pick{display:flex;gap:10px;align-items:center;flex:1;text-align:left;min-height:62px;background:none;border:0;padding:3px 0;color:inherit}\r\n.region-index{font:400 1rem var(--font-display),Impact,sans-serif;color:var(--pur);align-self:flex-start;padding-top:8px}\r\n.region-name{display:flex;flex-direction:column;gap:1px}.region-name strong{font-size:1rem;font-weight:700;line-height:1.12}.region-name small{font-size:.875rem;color:#654773}\r\n.region-card-heading [data-slot=button]{color:#796086;min-width:32px;width:32px}.region-card-heading .is-locked{color:var(--pur-dd)}\r\n.recipe-actions{display:flex;gap:8px;margin-top:20px}.recipe-actions>*{flex:1}\r\n.viewport-panel{position:relative;isolation:isolate;overflow:hidden;min-width:0;border:3px solid var(--pur-dd);border-radius:28px;background:radial-gradient(ellipse at 50% 35%,#32243e 0,#17101f 45%,#090610 80%);box-shadow:5px 5px 0 var(--pur-dd),inset 0 0 80px #000a}\r\n.hand-viewer-wrap,.hand-canvas{width:100%;height:100%;min-height:0;position:relative}\r\n.hand-canvas{cursor:grab}.hand-canvas:active{cursor:grabbing}.hand-canvas canvas{width:100%;height:100%;display:block;touch-action:none}\r\n.protective-glass{position:absolute;inset:7px;z-index:1;pointer-events:none;border:8px solid #2b1b33;border-radius:22px;background:linear-gradient(112deg,#fff0b30a,transparent 34%,transparent 72%,#9e6ed007);box-shadow:0 0 0 1px #a0783f,0 0 0 4px #0a0610,inset 1px 2px 2px #fff1b563,inset -2px -2px 3px #080613,inset 0 0 48px #ae7fc01c;overflow:hidden}\r\n.glass-edge{position:absolute;inset:5px;border:1px solid #e5c29638;border-radius:11px;box-shadow:inset 0 0 0 2px #16092175,inset 0 0 24px #ecd8ff0a}\r\n.glass-reflection{position:absolute;inset:-20%;transform:rotate(-24deg);background:linear-gradient(90deg,transparent 13%,#f3e1ff04 14%,#fff8e00d 19%,#fff8e006 25%,transparent 26%,transparent 29%,#fff9ee0a 29.4%,transparent 30%)}\r\n.reflection-secondary{transform:rotate(-24deg) translateX(76%);opacity:.45}\r\n.glass-fastener{position:absolute;width:8px;height:8px;border-radius:50%;background:linear-gradient(130deg,#e4bc72,#302136 55%,#a17948);box-shadow:0 0 0 2px #100a15,inset 0 1px #fff0b666}\r\n.fastener-tl{top:2px;left:2px}.fastener-tr{top:2px;right:2px}.fastener-bl{bottom:2px;left:2px}.fastener-br{bottom:2px;right:2px}\r\n.glass-seal{position:absolute;right:15px;top:20px;font:400 .75rem var(--font-display),Impact,sans-serif;letter-spacing:.1em;color:#d8bc88}\r\n.viewport-chrome{position:absolute;left:30px;top:31px;z-index:2;pointer-events:none}\r\n.live-badge{background:#0b0f0a;color:var(--sig);border:2px solid #000;height:30px;padding:4px 10px;letter-spacing:.08em;font:400 1.05rem var(--font-geist-mono),monospace;box-shadow:inset 0 1px 4px #000}\r\n.live-dot{height:6px;width:6px;border-radius:50%;background:var(--sig);margin-right:4px;box-shadow:0 0 9px #39ff9a66}\r\n.view-tools{position:absolute;left:20px;right:20px;bottom:94px;z-index:2;display:flex;justify-content:center;gap:8px;align-items:center}\r\n.view-tools [data-slot=button],.explode-control{color:var(--cream);background:linear-gradient(#34273e,#18111e);border:2px solid #07040a;box-shadow:inset 0 1px 0 #ffffff26,0 3px 0 #08040c}\r\n.view-tools [data-slot=button]{border-radius:50%}\r\n.explode-control{display:flex;align-items:center;gap:8px;padding:9px 11px;border-radius:8px;font-size:.875rem;line-height:1.2}\r\n.explode-control>svg{height:16px;width:16px}\r\n.explode-control [data-slot=switch][data-checked]{background:var(--sig)}\r\n.explode-control [data-slot=switch-thumb]{background:#fff9ec}\r\n.specimen-label{position:absolute;left:30px;right:30px;bottom:30px;z-index:2;pointer-events:none;text-align:center}\r\n.specimen-label span{display:flex;flex-direction:column;gap:5px}\r\n.specimen-label small{font:400 .75rem var(--font-display),Impact,sans-serif;color:#d9bfeb;letter-spacing:.09em}\r\n.specimen-label strong{font:400 clamp(1rem,1.6vw,1.25rem) var(--font-headline),'Arial Black',sans-serif;color:var(--gold);text-shadow:2px 2px 0 #4a1a86}\r\n.orbit-hint{position:absolute;left:30px;top:63px;color:#bba5c8;font-size:.875rem;pointer-events:none;z-index:2}\r\n.model-status{position:absolute;z-index:3;left:50%;top:50%;transform:translate(-50%,-50%);width:min(85%,380px);padding:16px;background:#100a1af2;color:var(--cream);border:2px solid #8553b0;border-radius:10px;font-size:1rem;text-align:center}\r\n.model-status.is-error{border-color:var(--hot)}.model-status button{display:block;margin:12px auto 0;padding:8px 20px;border-radius:6px;background:var(--gold);color:var(--pur-dd)}\r\n.style-heading h2{margin:9px 0 7px;font:400 1.55rem/1.15 var(--font-headline),'Arial Black',sans-serif;letter-spacing:-.04em;text-shadow:2px 2px 0 var(--gold)}\r\n.style-heading p{color:#654773;font-size:1rem;margin:0}\r\n.slider-block{padding-top:16px}.slider-actions{display:grid;grid-template-columns:38px 1fr 38px;gap:10px;align-items:center;text-align:center}\r\n.slider-actions [data-slot=button]{width:38px;min-height:38px;height:38px;border:2px solid var(--pur-dd);background:#fffaf1}\r\n.selected-style-label{font-size:1rem;font-weight:700;color:var(--pur)}\r\n.style-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;padding:16px 0 20px}\r\n.style-grid button{overflow:hidden;min-width:0;border-radius:7px;background:#f9ebf3;border:2px solid #baa0ce;padding:0;color:var(--pur-dd);text-align:left;transition:transform .15s}\r\n.style-grid button:hover{border-color:var(--pur);transform:translateY(-2px)}.style-grid button.is-active{border-color:var(--pur-dd);background:var(--gold);box-shadow:3px 3px 0 var(--pur)}\r\n.style-grid img{width:100%;height:80px;object-fit:cover;display:block;background:#120c1a}\r\n.tile-label{display:block;padding:5px 3px;font-size:.875rem;font-weight:600;line-height:1.1;overflow-wrap:anywhere;min-height:40px}\r\n.nail-shop{margin:18px 0 0;padding:12px 10px 10px;border:2px solid var(--pur-dd);border-radius:9px;background:#f5e4ee;min-width:0}\r\n.nail-shop legend{font:400 1rem var(--font-display),Impact,sans-serif;padding:0 5px;color:var(--pur)}\r\n.nail-shapes{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}\r\n.nail-shapes button{font-size:.875rem;font-weight:600;line-height:1.1;min-height:38px;padding:6px 3px;border:1px solid #9d79b5;border-radius:5px;background:#fffaf1}\r\n.nail-shapes button.is-active{background:var(--pur);color:var(--cream);border-color:var(--pur-dd);box-shadow:0 2px 0 var(--pur-dd)}\r\n.hand-shape-shop{margin:0 0 22px;padding:12px 10px;border:2px solid var(--pur-dd);border-radius:9px;background:#f5e4ee;min-width:0}\r\n.hand-shape-shop legend{font:400 1rem var(--font-display),Impact,sans-serif;padding:0 5px;color:var(--pur)}\r\n.shape-target{display:flex;align-items:center;gap:8px;margin-bottom:12px;font-size:.875rem;font-weight:600}.shape-target>span{flex-shrink:0}.shape-target>div{flex:1;min-width:0}.shape-target select{width:100%;min-width:0;height:38px;font-size:.875rem;background:#fffaf1;border-color:#9d79b5}\r\n.hand-shape-buttons{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.hand-shape-buttons [data-slot=button]{min-width:0;min-height:42px;height:auto;padding:7px 3px;font-size:.875rem;font-weight:600;line-height:1.2;white-space:normal;overflow-wrap:anywhere;border:1px solid #9d79b5;border-radius:5px;background:#fffaf1;color:var(--pur-dd)}\r\n.hand-shape-buttons [aria-pressed=true]{background:var(--pur);color:var(--cream);border-color:var(--pur-dd);box-shadow:0 2px 0 var(--pur-dd)}.hand-shape-shop p{margin:10px 0 0;font-size:.875rem;line-height:1.35;color:#654773}\r\n.scale-shop{margin:0 0 22px;padding:12px 10px;border:2px solid var(--pur-dd);border-radius:9px;background:#fff0c7;min-width:0}\r\n.scale-shop legend{font:400 1rem var(--font-display),Impact,sans-serif;padding:0 5px;color:var(--pur)}\r\n.scale-buttons{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}.scale-buttons [data-slot=button]{flex-direction:column;gap:5px;min-width:0;min-height:62px;height:auto;padding:8px 3px;font-size:.875rem;border:1px solid #9d79b5;border-radius:5px;background:#fffaf1;color:var(--pur-dd)}\r\n.scale-buttons [aria-pressed=true]{background:var(--pur);color:var(--cream);border-color:var(--pur-dd);box-shadow:0 2px 0 var(--pur-dd)}.scale-shop p{margin:10px 0 0;font-size:.875rem;line-height:1.35;color:#654773}\r\n.scale-icon{display:block;width:20px;height:20px;background:currentColor;opacity:.9}.scale-none{border:2px solid currentColor;background:linear-gradient(135deg,transparent 46%,currentColor 47% 54%,transparent 55%);border-radius:50%}.scale-round{border-radius:50%}.scale-diamond{clip-path:polygon(50% 0,92% 50%,50% 100%,8% 50%)}.scale-hex{clip-path:polygon(25% 7%,75% 7%,100% 50%,75% 93%,25% 93%,0 50%)}.scale-shield{clip-path:polygon(12% 0,88% 0,100% 45%,50% 100%,0 45%)}\r\n.apply-all{width:100%;font:400 1rem var(--font-display),Impact,sans-serif!important;white-space:normal!important;height:auto!important;line-height:1.35;padding:11px!important;background:var(--gold)!important;border:2px solid var(--pur-dd)!important;box-shadow:0 3px 0 var(--pur-dd)}\r\n.preset-label{display:block;font-size:1rem;margin:20px 0 7px;font-weight:600}.preset-select{width:100%!important}.preset-select select{height:44px;background:#fffaf1;font-size:1rem;color:var(--pur-dd);border:2px solid var(--pur)}\r\n.creator-dialog{background:var(--cream)!important;max-width:min(94vw,520px)!important;max-height:90dvh;overflow:auto;border:3px solid var(--pur-dd)!important;padding:24px!important;box-shadow:7px 7px 0 var(--pur);color:var(--pur-dd)!important}\r\n.creator-dialog [data-slot=dialog-title]{font:400 1.3rem/1.3 var(--font-headline),'Arial Black',sans-serif}.creator-dialog [data-slot=dialog-description]{font-size:1rem;line-height:1.4;color:#654773}\r\n.export-options,.recipe-editor{display:grid;gap:12px}.export-options [data-slot=button],.recipe-editor [data-slot=button]{height:46px;white-space:normal}\r\n.library-download{padding:12px;text-align:center;border:2px solid var(--pur);border-radius:8px;color:var(--pur);font-size:1rem;font-weight:600}\r\n.export-note{font-size:.875rem;line-height:1.4;color:#654773;margin:0}\r\n.recipe-editor label{font-size:1rem}.recipe-editor textarea{font-family:monospace;font-size:.875rem;line-height:1.5;background:#fffaf1}\r\n.feedback-toast{position:fixed;bottom:20px;left:50%;transform:translateX(-50%);z-index:100;background:var(--pur-dd);color:var(--gold);padding:14px 20px;border:2px solid var(--gold);border-radius:10px;box-shadow:0 8px 40px #0005;max-width:90vw;font-size:1rem}\r\n@media(max-width:1200px){.creator-grid{grid-template-columns:240px minmax(280px,1fr) 294px;gap:12px;padding:0 12px 16px}.region-panel,.style-panel{padding:18px 12px}.five-finger-badge{display:none}.topbar{gap:12px}.style-grid{gap:6px}.style-grid img{height:72px}.glass-seal{top:59px;right:14px;letter-spacing:.02em}.orbit-hint{top:75px}.explode-control>svg{display:none}}\r\n@media(max-width:980px){\r\n  .topbar{min-height:88px;padding:12px 16px 16px;gap:12px;flex-wrap:wrap}.brand-copy h1{font-size:1.55rem}\r\n  .top-actions{gap:6px}.top-actions button{min-width:38px}.top-actions button span{display:none}.top-actions button svg{width:17px}\r\n  .creator-grid{height:auto;min-height:0;grid-template-columns:1fr 1fr}\r\n  .viewport-panel{grid-column:1/-1;grid-row:1;height:62dvh;min-height:440px}.region-panel,.style-panel{overflow:visible}\r\n  .style-grid img{height:100px}.glass-seal{top:21px;right:16px}.orbit-hint{top:63px}.specimen-label strong{font-size:1.25rem}\r\n}\r\n@media(max-width:600px){\r\n  .mom-ribbon{font-size:.75rem;letter-spacing:.06em}.mom-ribbon span{margin-left:12px}\r\n  .topbar{gap:8px;min-height:96px}.brand-copy{flex:1}.brand-copy h1{font-size:1.3rem}.brand-copy p{font-size:.75rem}\r\n  .top-actions{margin-left:0}.top-actions [data-slot=button]{width:34px;min-width:34px;min-height:36px;height:36px;padding:7px}\r\n  .creator-grid{display:flex;flex-direction:column;padding:0 10px 16px;gap:16px}.viewport-panel{order:0;height:54dvh;min-height:400px}.region-panel{order:1}.style-panel{order:2}\r\n  .region-list{grid-template-columns:1fr 1fr;gap:9px}.region-index{display:none}.region-card{padding:3px 6px 3px 8px}.region-pick{min-height:62px}.region-name strong{font-size:1rem}\r\n  .style-grid{grid-template-columns:repeat(5,minmax(0,1fr))}.style-grid img{height:96px}\r\n  .protective-glass{inset:5px;border-width:6px;border-radius:19px}.viewport-chrome{top:26px;left:24px}.glass-seal{top:18px;right:12px;font-size:.75rem}\r\n  .orbit-hint{top:59px;left:24px}.specimen-label{left:20px;right:20px;bottom:27px}.specimen-label strong{font-size:1.05rem}.specimen-label small{font-size:.75rem;letter-spacing:.025em}.view-tools{bottom:90px}\r\n}\r\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important}}\r\n.anatomy-link{display:block;padding:11px 12px;margin:0 0 20px;background:#2a0a44;color:#ffd36e;border-radius:8px;font-weight:600;font-size:1rem;line-height:1.3}\r\n.gray-control{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding:10px 12px;border:1px solid #a581bb;border-radius:8px;font-size:1rem}\r\n.size-note{font-size:1rem;line-height:1.4;padding:12px;background:#fff1ca;color:#412c15;border-radius:8px;margin-top:12px}\r\n.anatomy-comparison{min-height:100vh;background:#f2efe8;padding:28px clamp(16px,3vw,44px);color:#26252a}\r\n.comparison-heading{display:flex;align-items:center;justify-content:space-between;gap:20px}.comparison-heading p{margin:0 0 8px;font:400 .875rem var(--font-display);letter-spacing:.08em;color:#655378}.comparison-heading h1{font:400 clamp(1.5rem,3vw,2.3rem)/1.2 var(--font-headline);margin:0}.comparison-heading>a{color:#4a1a86;text-decoration:underline;white-space:nowrap;font-size:1rem}\r\n.comparison-note{font-size:1.125rem;color:#65616c;margin:16px 0 24px}\r\n.comparison-options{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:20px}.comparison-options .comparison-note{margin:0}.comparison-options .gray-control{margin:0;gap:20px}.comparison-other{display:inline-block;color:#4a1a86;text-decoration:underline;margin-top:24px;font-size:1rem}\r\n.comparison-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}\r\n.comparison-card{overflow:hidden;background:#fff;border:1px solid #d0cbd4;border-radius:14px}\r\n.comparison-canvas{height:60dvh;min-height:420px;max-height:680px;background:radial-gradient(ellipse at 50% 40%,#303236,#15171b 75%)}\r\n.comparison-caption{padding:18px 20px 22px}.comparison-caption h2{font:400 1.35rem var(--font-headline);margin:0 0 7px}.comparison-caption p{font-size:1rem;line-height:1.4;color:#625d68;margin:0 0 16px;min-height:2.8em}.comparison-caption a{display:block;padding:10px 14px;background:#4a1a86;color:#fff;border-radius:7px;text-align:center;font-size:1rem;font-weight:600}\r\n@media(max-width:880px){.comparison-grid{grid-template-columns:1fr}.comparison-canvas{height:60dvh;min-height:430px}.comparison-heading{align-items:flex-start;flex-direction:column}.comparison-caption p{min-height:0}}\r\n","handborne/source/app/hand-model.ts":"import * as THREE from 'three';\r\nimport {GLTFLoader,type GLTF} from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/examples/jsm/libs/meshopt_decoder.module.js';\r\nimport {REGIONS,STYLES,styleFor} from './catalog';\r\nimport {recipeCode,type Selection} from './recipe';\r\nimport {replaceNailShape} from './nails';\r\nimport {addHandScales} from './scales';\r\nimport {sculptMaterial,growMaterial} from './material-language';\r\nconst files=new Map<number,Promise<GLTF>>();\r\nfunction family(id:number) {\r\n  id=id>=30?(id===57||id===58||id===61||id===63||id===74?21:id===59||id===62?14:0):id;\r\n  if(!files.has(id)) files.set(id,new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).loadAsync('/handborne/models/family-'+String(id).padStart(2,'0')+'.glb?v=5').catch(error=>{files.delete(id);throw error;}));\r\n  return files.get(id)!;\r\n}\r\nexport async function assemble(selection:Selection,nailShape:string,scalePattern='none') {\r\n  const group=new THREE.Group();group.name='Handborne_Creature';\r\n  group.userData={recipe:recipeCode(selection),units:'metres',fingers:5};\r\n  const parts=await Promise.all(REGIONS.map(async r=>{\r\n    const gltf=await family(selection[r.id]);\r\n    const source=gltf.scene.getObjectByName(r.id);\r\n    if(!source)throw new Error('Missing '+r.label+' module');\r\n    const part=source.clone(true);part.name=r.id;\r\n    if(r.id==='nails')replaceNailShape(part,nailShape,selection.nails);\r\n    part.userData={...part.userData,region:r.id,style:styleFor(selection[r.id]).name,style_id:selection[r.id]};\r\n    part.updateMatrixWorld(true);\r\n    part.traverse(obj=>{if(obj instanceof THREE.Mesh){obj.userData.region=r.id;obj.castShadow=true;obj.receiveShadow=true;\r\n      if(selection[r.id]===20){const old=obj.material as THREE.MeshStandardMaterial,m=new THREE.MeshPhysicalMaterial();THREE.MeshStandardMaterial.prototype.copy.call(m,old);m.sheen=1;m.sheenRoughness=.9;m.sheenColor.set('#ffe5c9');obj.material=m;obj.userData.ownedMaterial=true;}\r\n      else sculptMaterial(obj,styleFor(selection[r.id]),.075);\r\n    }});\r\n    part.add(growMaterial(part as THREE.Group,styleFor(selection[r.id]),r.id,.075,1,true));\r\n    return part;\r\n  }));\r\n  group.add(...parts);addHandScales(group,scalePattern);return group;\r\n}\r\n","handborne/source/app/hand-shapes.ts":"import { REGIONS, type RegionId } from './catalog.ts';\r\nimport type { Selection } from './recipe.ts';\r\n\r\nexport const HAND_SHAPES = [\r\n  { id: 'original', name: 'Original', styleId: 0 },\r\n  { id: 'skeletal', name: 'Skeletal', styleId: 7 },\r\n  { id: 'mechanical', name: 'Mechanical', styleId: 18 },\r\n  { id: 'stone', name: 'Stone', styleId: 13 },\r\n  { id: 'fluffy', name: 'Fluffy', styleId: 20 },\r\n  { id: 'jelly', name: 'Jelly', styleId: 21 },\r\n  { id: 'baby', name: 'Baby', styleId: 22 },\r\n] as const;\r\nexport type ShapeScope = 'hand' | 'section';\r\n\r\nexport function selectHandShape(selection: Selection, shapeId: string, scope: ShapeScope, region: RegionId, locks: readonly RegionId[]): Selection {\r\n  const shape = HAND_SHAPES.find(item => item.id === shapeId);\r\n  if (!shape) throw new Error('Choose a valid hand shape.');\r\n  if (scope !== 'hand' && scope !== 'section') throw new Error('Choose a valid shape target.');\r\n  if (!REGIONS.some(item => item.id === region)) throw new Error('Choose a valid section.');\r\n  return Object.fromEntries(REGIONS.map(item => [\r\n    item.id,\r\n    (scope === 'hand' || item.id === region) && !locks.includes(item.id) ? shape.styleId : selection[item.id],\r\n  ])) as Selection;\r\n}\r\n\r\nexport function activeHandShape(selection: Selection, scope: ShapeScope, region: RegionId): string | null {\r\n  const values = scope === 'hand' ? Object.values(selection) : [selection[region]];\r\n  return HAND_SHAPES.find(shape => values.every(id => id === shape.styleId))?.id ?? null;\r\n}\r\n","handborne/source/app/hand-viewer.tsx":"'use client';\r\n\r\nimport { assemble } from './hand-model';\r\nimport { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';\r\nimport * as THREE from 'three';\r\nimport { GLTFLoader, type GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';\r\nimport { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';\r\nimport { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';\r\nimport { REGIONS, STYLES, styleFor, type RegionId } from './catalog';\r\nimport { recipeCode, designCode, type Selection } from './recipe';\r\nimport { getPose, mixPoses, type Pose } from './poses';\r\nimport { bindHand, applyHandPose, type HandRig } from './pose-rig';\r\nimport { replaceNailShape } from './nails';\r\nimport { specimenMotion } from './motion';\r\nimport { addHandScales } from './scales';\r\n\r\nexport type HandViewerHandle = { exportFile:(format:'glb'|'obj'|'png')=>Promise<void>; resetView:()=>void; flipView:()=>void; };\r\ntype Props = {selection:Selection;poseId:string;nailShape:string;scalePattern?:string;animate:boolean;gray?:boolean;selectedRegion:RegionId;exploded:boolean;onSelectRegion:(r:RegionId)=>void;onReady?:(code:string)=>void;};\r\nfunction download(blob:Blob,name:string) {\r\n  const url=URL.createObjectURL(blob); const a=document.createElement('a');\r\n  a.href=url;a.download=name;document.body.appendChild(a);a.click();a.remove();\r\n  window.setTimeout(()=>URL.revokeObjectURL(url),3000);\r\n}\r\nfunction disposeDisplay(group:THREE.Group) {\r\n  group.traverse(obj=>{if(obj instanceof THREE.Mesh && obj.userData.displayMaterial) {\r\n    const mats=Array.isArray(obj.material)?obj.material:[obj.material];mats.forEach(m=>m.dispose());\r\n  }});\r\n}\r\n\r\nexport const HandViewer=forwardRef<HandViewerHandle,Props>(function HandViewer({selection,poseId,nailShape,scalePattern='none',animate,gray=false,selectedRegion,exploded,onSelectRegion,onReady},ref) {\r\n  const host=useRef<HTMLDivElement>(null);\r\n  const sceneRef=useRef<THREE.Scene|null>(null),handRef=useRef<THREE.Group|null>(null);\r\n  const floatingRoot=useRef<THREE.Group|null>(null);\r\n  const cameraRef=useRef<THREE.PerspectiveCamera|null>(null),rendererRef=useRef<THREE.WebGLRenderer|null>(null),controlsRef=useRef<OrbitControls|null>(null);\r\n  const current=useRef({selection,poseId,nailShape,scalePattern,animate,gray,selectedRegion,exploded,onSelectRegion,onReady});current.current={selection,poseId,nailShape,scalePattern,animate,gray,selectedRegion,exploded,onSelectRegion,onReady};\r\n  const rigRef=useRef<HandRig|null>(null),loadedStyle=useRef(''),displayedPose=useRef(getPose(poseId));\r\n  const transition=useRef<{from:Pose;to:Pose;start:number;duration:number;last:number}|null>(null);\r\n  const [status,setStatus]=useState('Loading hand…'),[error,setError]=useState(false),[retry,setRetry]=useState(0);\r\n  const selectionKey=recipeCode(selection)+'/'+nailShape+'/'+scalePattern;\r\n\r\n  function decorate() {\r\n    sceneRef.current?.traverse(obj=>{\r\n      if(obj instanceof THREE.Light){obj.userData.originalColor??=obj.color.clone();obj.color.copy(current.current.gray?new THREE.Color('#ffffff'):obj.userData.originalColor);}\r\n      if(obj instanceof THREE.HemisphereLight){obj.userData.originalGroundColor??=obj.groundColor.clone();obj.groundColor.copy(current.current.gray?new THREE.Color('#202020'):obj.userData.originalGroundColor);}\r\n    });\r\n    const hand=handRef.current;if(!hand)return;\r\n    for(const part of hand.children) {\r\n      const region=part.userData.region as RegionId;\r\n      const offsets:Record<RegionId,[number,number,number]>={nails:[0,.018,.014],fingertips:[0,.012,0],fingers:[0,.005,0],palm:[0,0,-.020],back_of_hand:[0,0,.020],wrist:[0,-.020,0]};\r\n      part.position.fromArray(current.current.exploded?offsets[region]:[0,0,0]);\r\n      part.traverse(obj=>{\r\n        if(!(obj instanceof THREE.Mesh))return;\r\n        if(!obj.userData.displayMaterial) {\r\n          obj.userData.sourceMaterials=Array.isArray(obj.material)?obj.material:[obj.material];\r\n          obj.material=Array.isArray(obj.material)?obj.material.map(m=>m.clone()):obj.material.clone();\r\n          obj.userData.displayMaterial=true;\r\n          const m=Array.isArray(obj.material)?obj.material[0]:obj.material;\r\n          if(m instanceof THREE.MeshStandardMaterial)obj.userData.originalEmissive=m.emissive.clone();\r\n        }\r\n        const mats=Array.isArray(obj.material)?obj.material:[obj.material];\r\n        for(const [i,m]of mats.entries())if(m instanceof THREE.MeshStandardMaterial) {\r\n          const source=obj.userData.sourceMaterials[i];m.copy(source);m.onBeforeCompile=source.onBeforeCompile;m.customProgramCacheKey=source.customProgramCacheKey;\r\n          if(current.current.gray){m.color.set('#92979c');m.emissive.set(0);m.map=null;m.normalMap=null;m.roughnessMap=null;m.metalnessMap=null;m.roughness=.66;m.metalness=0;}\r\n          if(current.current.gray&&m instanceof THREE.MeshPhysicalMaterial){m.transmission=0;m.thickness=0;m.clearcoat=0;m.sheen=0;m.iridescence=0;}\r\n          if(!current.current.gray&&region===current.current.selectedRegion)m.emissive.add(new THREE.Color('#081b14'));\r\n          m.needsUpdate=true;\r\n        }\r\n      });\r\n    }\r\n  }\r\n  useEffect(()=>{decorate();},[selectedRegion,exploded,gray]);\r\n  useEffect(()=>{\r\n    if(!rigRef.current)return;\r\n    transition.current={from:displayedPose.current,to:getPose(poseId),start:performance.now(),duration:window.matchMedia('(prefers-reduced-motion: reduce)').matches?0:1100,last:0};\r\n  },[poseId]);\r\n  useEffect(()=>{\r\n    let cancelled=false;setStatus('Loading selected forms…');setError(false);\r\n    assemble(selection,nailShape,scalePattern).then(hand=>{\r\n      if(cancelled||!floatingRoot.current){hand.traverse(o=>{if(o instanceof THREE.Mesh&&o.userData.ownedGeometry)o.geometry.dispose();});return;}\r\n      if(handRef.current){handRef.current.removeFromParent();disposeDisplay(handRef.current);rigRef.current?.dispose();}\r\n      // Bind in rest-space before attaching the independent, moving display parent.\r\n      handRef.current=hand;rigRef.current=bindHand(hand);floatingRoot.current.add(hand);loadedStyle.current=selectionKey;\r\n      displayedPose.current=getPose(current.current.poseId);transition.current=null;applyHandPose(rigRef.current,displayedPose.current);\r\n      decorate();setStatus('');current.current.onReady?.(designCode({sections:selection,pose:current.current.poseId,nailShape,scalePattern}));\r\n    }).catch(()=>{if(!cancelled){setError(true);setStatus('Could not load this hand. Check your connection and retry.');}});\r\n    return ()=>{cancelled=true;};\r\n  },[selectionKey,retry]);\r\n\r\n  useImperativeHandle(ref,()=>({\r\n    async exportFile(format) {\r\n      if(format==='png') {\r\n        const renderer=rendererRef.current,scene=sceneRef.current,camera=cameraRef.current;\r\n        if(!renderer||!scene||!camera)throw new Error('The preview is still loading.');\r\n        renderer.render(scene,camera);\r\n        const blob=await new Promise<Blob|null>(resolve=>renderer.domElement.toBlob(resolve,'image/png'));\r\n        if(!blob)throw new Error('Could not capture the preview.');\r\n        download(blob,'handborne-preview.png');return;\r\n      }\r\n      const chosen={sections:current.current.selection,pose:current.current.poseId,nailShape:current.current.nailShape,scalePattern:current.current.scalePattern};\r\n      const hand=await assemble(chosen.sections,chosen.nailShape,chosen.scalePattern),exportRig=bindHand(hand);applyHandPose(exportRig,getPose(chosen.pose));hand.userData.recipe=designCode(chosen);hand.userData.nail_shape=chosen.nailShape;hand.updateMatrixWorld(true);\r\n      try{\r\n      if(format==='glb') {\r\n        const {GLTFExporter}=await import('three/examples/jsm/exporters/GLTFExporter.js');\r\n        const result=await new GLTFExporter().parseAsync(hand,{binary:true,onlyVisible:true});\r\n        if(!(result instanceof ArrayBuffer))throw new Error('GLB export failed.');\r\n        download(new Blob([result],{type:'model/gltf-binary'}),'handborne-'+chosen.pose+'.glb');\r\n      } else {\r\n        const {OBJExporter}=await import('three/examples/jsm/exporters/OBJExporter.js');\r\n        const {zipSync,strToU8}=await import('three/examples/jsm/libs/fflate.module.js');\r\n        let mtl='# Handborne material library\\n';const seen=new Set<string>();\r\n        hand.traverse(obj=>{\r\n          if(!(obj instanceof THREE.Mesh))return;\r\n          for(const m of (Array.isArray(obj.material)?obj.material:[obj.material]))if(m instanceof THREE.MeshStandardMaterial&&!seen.has(m.name)){\r\n            seen.add(m.name);\r\n            const style=styleFor(m.userData.materialStyle)||STYLES.find(s=>m.name.startsWith(s.name.toLowerCase().replace(/[^a-z0-9]+/g,'-')+'_'));\r\n            const c=m.map&&style?new THREE.Color(style.primary):m.color;\r\n            mtl+='newmtl '+m.name+'\\nKd '+[c.r,c.g,c.b].join(' ')+'\\nKs 0.25 0.25 0.25\\nNs '+Math.round((1-m.roughness)*200)+'\\nd 1\\n\\n';\r\n          }\r\n        });\r\n        const obj='mtllib handborne.mtl\\n'+new OBJExporter().parse(hand);\r\n        const archive=zipSync({'handborne.obj':strToU8(obj),'handborne.mtl':strToU8(mtl),'recipe.json':strToU8(JSON.stringify({version:4,...chosen},null,2)),'README.txt':strToU8('OBJ preserves the selected pose, nail shape, raised scale pattern, anatomical mesh, physical relief and base material colors. Use GLB for embedded albedo and microrelief normal maps. This is a baked static pose, not an animation skeleton. Curved module interfaces remain open; not print-ready.')});\r\n        download(new Blob([archive as unknown as BlobPart],{type:'application/zip'}),'handborne-'+chosen.pose+'-obj.zip');\r\n      }\r\n      }finally{exportRig.dispose();}\r\n    },\r\n    resetView(){const camera=cameraRef.current;if(camera){const fit=Math.max(1,.62/camera.aspect);camera.position.set(.055*fit,.035+.06*fit,.36*fit);}controlsRef.current?.target.set(0,.035,0);controlsRef.current?.update();},\r\n    flipView(){const camera=cameraRef.current;if(camera){camera.position.x*=-1;camera.position.z*=-1;controlsRef.current?.update();}},\r\n  }),[]);\r\n\r\n  useEffect(()=>{\r\n    const mount=host.current;if(!mount)return;\r\n    let renderer:THREE.WebGLRenderer;\r\n    try{renderer=new THREE.WebGLRenderer({antialias:true,alpha:true,preserveDrawingBuffer:true});}\r\n    catch {setError(true);setStatus('3D graphics are unavailable. Try a browser with hardware acceleration.');return;}\r\n    renderer.setPixelRatio(Math.min(window.devicePixelRatio,1.75));renderer.outputColorSpace=THREE.SRGBColorSpace;\r\n    renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=1.12;\r\n    renderer.shadowMap.enabled=true;renderer.shadowMap.type=THREE.PCFSoftShadowMap;\r\n    mount.appendChild(renderer.domElement);rendererRef.current=renderer;\r\n    const scene=new THREE.Scene();sceneRef.current=scene;\r\n    const floatGroup=new THREE.Group();floatGroup.name='Specimen motion';scene.add(floatGroup);floatingRoot.current=floatGroup;\r\n    const camera=new THREE.PerspectiveCamera(34,1,.005,5);camera.position.set(.055,.095,.36);cameraRef.current=camera;\r\n    const controls=new OrbitControls(camera,renderer.domElement);controls.target.set(0,.035,0);controls.enableDamping=true;\r\n    controls.enablePan=false;controls.minDistance=.20;controls.maxDistance=.95;controlsRef.current=controls;\r\n    const pmrem=new THREE.PMREMGenerator(renderer);const room=new RoomEnvironment();const env=pmrem.fromScene(room,.04);scene.environment=env.texture;\r\n    scene.environmentIntensity=.55;\r\n    scene.add(new THREE.HemisphereLight('#c6e8ef','#15212b',.65));\r\n    const key=new THREE.DirectionalLight('#ffead6',3.2);key.position.set(.22,.25,.30);key.castShadow=true;\r\n    key.shadow.mapSize.set(1024,1024);key.shadow.camera.left=-.18;key.shadow.camera.right=.18;key.shadow.camera.top=.25;key.shadow.camera.bottom=-.16;key.shadow.camera.near=.01;key.shadow.camera.far=1;key.shadow.bias=-.00005;key.shadow.normalBias=.0006;key.shadow.radius=3;scene.add(key);\r\n    const rim=new THREE.DirectionalLight('#9adeee',2.1);rim.position.set(-.28,.16,-.16);scene.add(rim);\r\n    const fill=new THREE.DirectionalLight('#abc3e9',.65);fill.position.set(-.3,.03,.2);scene.add(fill);\r\n    const chamber=new THREE.Group();chamber.name='Observation chamber';scene.add(chamber);\r\n    const platform=new THREE.Mesh(new THREE.CylinderGeometry(.105,.11,.012,80),new THREE.MeshStandardMaterial({color:'#17242d',metalness:.75,roughness:.28}));\r\n    platform.position.y=-.083;platform.receiveShadow=true;chamber.add(platform);\r\n    const ring=new THREE.Mesh(new THREE.TorusGeometry(.101,.00065,8,100),new THREE.MeshBasicMaterial({color:'#ffd36e'}));\r\n    ring.rotation.x=Math.PI/2;ring.position.y=-.076;chamber.add(ring);\r\n    const floor=new THREE.Mesh(new THREE.PlaneGeometry(.9,.9),new THREE.MeshStandardMaterial({color:'#09151c',roughness:.54,metalness:.25}));\r\n    floor.rotation.x=-Math.PI/2;floor.position.y=-.09;floor.receiveShadow=true;chamber.add(floor);\r\n    let start=[0,0];const down=(e:PointerEvent)=>{start=[e.clientX,e.clientY];};\r\n    const up=(e:PointerEvent)=>{\r\n      if(!handRef.current||Math.hypot(e.clientX-start[0],e.clientY-start[1])>6)return;\r\n      const rect=renderer.domElement.getBoundingClientRect();const point=new THREE.Vector2((e.clientX-rect.left)/rect.width*2-1,-(e.clientY-rect.top)/rect.height*2+1);\r\n      const ray=new THREE.Raycaster();ray.setFromCamera(point,camera);\r\n      const hit=ray.intersectObject(handRef.current,true)[0];if(hit?.object.userData.region)current.current.onSelectRegion(hit.object.userData.region);\r\n    };\r\n    renderer.domElement.addEventListener('pointerdown',down);renderer.domElement.addEventListener('pointerup',up);\r\n    let firstSize=true;\r\n    const resize=()=>{const w=mount.clientWidth,h=mount.clientHeight;renderer.setSize(w,h,false);camera.aspect=w/Math.max(h,1);camera.updateProjectionMatrix();if(firstSize&&w>0&&h>0){const fit=Math.max(1,.62/camera.aspect);camera.position.set(.055*fit,.035+.06*fit,.36*fit);firstSize=false;}};\r\n    const observer=new ResizeObserver(resize);observer.observe(mount);resize();\r\n    let frame=0,motionTime=0,lastTime=performance.now();const tick=()=>{\r\n      const change=transition.current,now=performance.now();\r\n      if(current.current.animate&&!document.hidden)motionTime+=Math.min((now-lastTime)/1000,.05);lastTime=now;\r\n      const motion=specimenMotion(motionTime);floatGroup.position.fromArray(motion.position);floatGroup.rotation.set(...motion.rotation);\r\n      if(change&&rigRef.current&&(now-change.last>28||change.duration===0)){\r\n        const t=change.duration===0?1:Math.min(1,(now-change.start)/change.duration);change.last=now;\r\n        displayedPose.current=mixPoses(change.from,change.to,t*t*(3-2*t));applyHandPose(rigRef.current,displayedPose.current);\r\n        if(t===1){transition.current=null;if(loadedStyle.current===recipeCode(current.current.selection)+'/'+current.current.nailShape+'/'+current.current.scalePattern)current.current.onReady?.(designCode({sections:current.current.selection,pose:change.to.id,nailShape:current.current.nailShape,scalePattern:current.current.scalePattern}));}\r\n      }\r\n      controls.update();renderer.render(scene,camera);frame=requestAnimationFrame(tick);\r\n    };tick();\r\n    return ()=>{\r\n      cancelAnimationFrame(frame);observer.disconnect();controls.dispose();env.dispose();pmrem.dispose();room.dispose();\r\n      chamber.traverse(obj=>{if(obj instanceof THREE.Mesh){obj.geometry.dispose();for(const material of(Array.isArray(obj.material)?obj.material:[obj.material]))material.dispose();}});key.shadow.dispose();if(handRef.current)disposeDisplay(handRef.current);rigRef.current?.dispose();rigRef.current=null;\r\n      renderer.dispose();if(renderer.domElement.parentElement===mount)mount.removeChild(renderer.domElement);\r\n      sceneRef.current=null;rendererRef.current=null;floatingRoot.current=null;\r\n    };\r\n  },[]);\r\n  return <div className=\"hand-viewer-wrap\"><div ref={host} className=\"hand-canvas\" role=\"img\" aria-label=\"Five-finger 3D hand. Drag to rotate, scroll to zoom, or tap a section.\" />\r\n    {status&&<div className={'model-status '+(error?'is-error':'')} role=\"status\">{status}{error&&<button onClick={()=>setRetry(v=>v+1)}>Retry</button>}</div>}\r\n  </div>;\r\n});\r\n","handborne/source/app/layout.tsx":"import type { Metadata } from 'next';\r\nimport './globals.css';\r\n\r\nexport const metadata: Metadata = {\r\n  title: 'Helping Hand — The Custom Shop',\r\n  description:\r\n    'Customize your Helping Hand with twenty-three creature styles, six joined sections and eight nail shapes. Your hand. Your way.',\r\n};\r\n\r\nexport default function RootLayout({\r\n  children,\r\n}: Readonly<{\r\n  children: React.ReactNode;\r\n}>) {\r\n  return (\r\n    <html lang=\"en\">\r\n      <body\r\n        className=\"antialiased\"\r\n      >\r\n        {children}\r\n      </body>\r\n    </html>\r\n  );\r\n}\r\n","handborne/source/app/material-access.ts":"import {DEFAULT_SELECTION,type RegionId,styleFor} from './catalog';\r\nimport type {Selection} from './recipe';\r\nconst owned=new Set<number>();\r\nexport const isHandStyleUnlocked=(id:number)=>id<57||owned.has(id);\r\nexport const assertHandStylesUnlocked=(sections:Selection)=>{for(const id of Object.values(sections))if(!isHandStyleUnlocked(id))throw Error(styleFor(id).name+' is locked. Earn its texture and color in Coach packs.');};\r\nexport const availableHandSections=(sections:Selection):Selection=>Object.fromEntries(Object.entries(sections).map(([region,id])=>[region,isHandStyleUnlocked(id)?id:DEFAULT_SELECTION[region as RegionId]])) as Selection;\r\nexport function subscribeHandUnlocks(changed:()=>void){\r\n const origin='https://myr5.mominc.online',frame=document.createElement('iframe');\r\n frame.src=origin+'/handborne/unlocks.html';frame.hidden=true;frame.title='Coach material ownership';\r\n const request=()=>frame.contentWindow?.postMessage({type:'handborne:unlock-request'},origin);\r\n const receive=(event:MessageEvent)=>{if(event.origin!==origin||event.source!==frame.contentWindow||event.data?.type!=='handborne:unlock-state'||!Array.isArray(event.data.styles))return;\r\n  owned.clear();for(const id of event.data.styles)if(Number.isInteger(id)&&id>=57&&id<=74)owned.add(id);changed();};\r\n frame.addEventListener('load',request);window.addEventListener('message',receive);window.addEventListener('focus',request);document.body.appendChild(frame);\r\n return()=>{window.removeEventListener('message',receive);window.removeEventListener('focus',request);frame.remove();owned.clear();};\r\n}\r\n","handborne/source/app/material-fixture.ts":"export * as THREE from 'three';\r\nexport {assemble} from './hand-model';\r\nexport {REGIONS,STYLES} from './catalog';\r\nexport {bindHand,applyHandPose} from './pose-rig';\r\nexport {getPose} from './poses';\r\nexport {DEFAULT_NAIL_SHAPE} from './nails';\r\n","handborne/source/app/material-language.ts":"import * as T from 'three';\r\nimport {mergeGeometries} from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\nimport {builtinSurfaceProfile,sampleBuiltinSurface} from './material-patterns';\r\nimport {refineCoachGeometry,type CoachReliefBudget} from './material-refinement';\r\nimport {samplePaletteTint,applyPaletteFinish} from './palette-finishes';\r\n\r\n// This material language is shared verbatim by Coach and Helping Hand. Maps are\r\n// ordinary glTF-compatible PBR textures, so the appearance also survives export.\r\nexport const MATERIAL_REVISION='material-horror-robot-2026-10-05-r1';\r\nexport const MATERIAL_NOTES=[\r\n 'Fine pores, palm folds and soft satin skin.',\r\n 'Twisted roots, bark fissures and fresh leaf growth.',\r\n 'Soft mushroom caps, radial gills and a branching mycelium web.',\r\n 'Overlapping lacquered carapace plates with dark flexible seams.',\r\n 'Raised overlapping scales, belly scutes and a serrated ridge.',\r\n 'Deep ocean hide, swept fins and luminous sensory pearls.',\r\n 'Porous reef limestone, branching antlers and hollow polyps.',\r\n 'Weathered ivory, joint ends and hollow skeletal anatomy.',\r\n 'Translucent mist glass with flowing veils and a pale inner glow.',\r\n 'Charred hide, swept horns and ember-lit fractures.',\r\n 'Pearlescent ceramic, engraved gold and orbiting halo segments.',\r\n 'Obsidian shells with violet fracture edges and star-like inclusions.',\r\n 'Folded flesh, coiled tendrils and luminous sensory nodules.',\r\n 'Angular stone slabs, chipped strata and deep mineral seams.',\r\n 'Faceted amethyst clusters with reflective faces and mineral inclusions.',\r\n 'Black basalt crust over glowing orange lava fissures.',\r\n 'Translucent blue ice, frost veins and sharp icicle clusters.',\r\n 'Storm-dark armor with branching electric channels and conductor fins.',\r\n 'Rigid brass armor, steel hinge joints, rivets and exposed toothed gears.',\r\n 'Machined violet panels, recessed circuits and pink illuminated rails.',\r\n 'Dense tapered fur tufts, a soft undercoat and contrasting guard hairs.',\r\n 'Translucent gelatin, a wet clear coat and bubbles suspended inside.',\r\n 'Plump soft forms, warm blush and delicate skin folds.'\r\n] as const;\r\ntype Style={id:number;primary:string;secondary:string;accent:string;emissive:string;roughness:number;metalness:number;detail:string;paletteId?:string};\r\nconst clamp=T.MathUtils.clamp,fract=(x:number)=>x-Math.floor(x);\r\nconst hash=(x:number,y:number)=>fract(Math.sin(x*127.1+y*311.7)*43758.5453);\r\nfunction cells(x:number,y:number){\r\n const ix=Math.floor(x),iy=Math.floor(y);let a=10,b=10;\r\n for(let j=-1;j<=1;j++)for(let i=-1;i<=1;i++){\r\n  const px=ix+i+.2+.6*hash(ix+i,iy+j),py=iy+j+.2+.6*hash(iy+j,ix+i+19);\r\n  const d=Math.hypot(x-px,y-py);if(d<a){b=a;a=d;}else if(d<b)b=d;\r\n }\r\n return {pit:a,seam:b-a};\r\n}\r\nexport function surfaceSample(id:number,x:number,y:number){\r\n const builtIn=sampleBuiltinSurface(id,x,y);if(builtIn)return builtIn;\r\n const c=cells(x*5,y*5),grain=hash(Math.floor(x*180),Math.floor(y*180));\r\n const wave=Math.sin(x*18+Math.sin(y*9)*2),vein=Math.pow(1-Math.abs(Math.sin(x*12+Math.sin(y*7)*2)),9);\r\n const seam=1-T.MathUtils.smoothstep(c.seam,.025,.12),spot=1-T.MathUtils.smoothstep(c.pit,.06,.19);\r\n const sx=fract(x*10+(Math.floor(y*12)%2)*.5)-.5,sy=fract(y*12)-.5;\r\n const scale=clamp(1-Math.pow(Math.abs(sx)*1.9,3)-Math.pow(Math.abs(sy)*1.9,4),0,1);\r\n let h=.5,t=.5,glow=0,rough=.7;\r\n switch(id){\r\n  case 0:h=.42+grain*.12+wave*.015;t=.54+grain*.07;rough=.61+grain*.2;break;\r\n  case 1:h=.4+wave*.19+vein*.25;t=.28+vein*.42+grain*.13;rough=.91;break;\r\n  case 2:h=.6-spot*.3+Math.sin(Math.atan2(sy,sx)*24)*.04;t=.7-spot*.4;glow=spot*.16;rough=.87;break;\r\n  case 3:h=scale*.75;t=.22+scale*.65;rough=.18+(.9-scale)*.4;break;\r\n  case 4:h=scale*.6+grain*.12;t=.22+scale*.52+wave*.08;rough=.56+grain*.2;break;\r\n  case 5:h=.55+wave*.12-spot*.23;t=.15+spot*.8;glow=spot;rough=.32;break;\r\n  case 6:h=.75-spot*.65-grain*.12;t=.44+spot*.4+grain*.1;rough=.93;break;\r\n  case 7:h=.55+Math.sin(y*35)*.09-grain*.12-seam*.06;t=.75-grain*.2-seam*.35;rough=.83;break;\r\n  case 8:h=.5+wave*.035;t=.7+wave*.12;glow=vein*.35;rough=.12;break;\r\n  case 9:h=.48+wave*.14+grain*.12;t=.15+grain*.13+vein*.3;glow=vein*.4;rough=.83;break;\r\n  case 10:h=.55+vein*.08;t=.74+vein*.23;glow=vein*.22;rough=.18+grain*.07;break;\r\n  case 11:h=.55-seam*.3;t=.03+seam*.48;glow=seam*.8;rough=.14;break;\r\n  case 12:h=.5+wave*.19+spot*.18;t=.25+spot*.65;glow=spot*.4;rough=.39;break;\r\n  case 13:h=.62-seam*.52+Math.floor(grain*4)*.035;t=.32+grain*.2-seam*.26;rough=.98;break;\r\n  case 14:h=.45+Math.floor(c.pit*8)*.05;t=.32+c.pit*.45;rough=.09;break;\r\n  case 15:{const lava=cells(x*2+Math.sin(y*5)*.3,y*2+Math.sin(x*4)*.3),crack=1-T.MathUtils.smoothstep(lava.seam,.015,.065);h=.72-crack*.65+grain*.1;t=.015+crack*.88;glow=crack;rough=.95-crack*.7;break;}\r\n  case 16:h=.5+seam*.14;t=.72+seam*.22;rough=.13+seam*.48;break;\r\n  case 17:{const bolt=Math.pow(1-Math.abs(Math.sin(x*7+Math.sin(y*22)*.25+Math.sin(y*9))),24);h=.54-bolt*.2;t=.13+bolt*.82;glow=bolt;rough=.38;break;}\r\n  case 18:{const cut=Math.min(fract(x*5),fract(y*5));h=cut<.06?.12:.68+grain*.03;t=cut<.06?.05:.43+grain*.16;rough=.24+grain*.25;break;}\r\n  case 19:{const a=fract(x*6),b=fract(y*6),switcher=hash(Math.floor(x*6),Math.floor(y*6));const rail=(Math.abs(a-.5)<.025&&b>.2&&switcher>.35)||(Math.abs(b-.5)<.025&&a<.6&&switcher<.65)?1:0;h=.5-rail*.2;t=.08+rail*.9;glow=rail;rough=.25;break;}\r\n  case 20:h=.5+Math.sin(x*160+Math.sin(y*25))* .2;t=.58+grain*.2;rough=.98;break;\r\n  case 21:h=.5+wave*.018;t=.7+wave*.07;rough=.07;break;\r\n  case 22:h=.5+grain*.035+wave*.01;t=.67+wave*.02;rough=.51;break;\r\n  // Rank 4 additions: Flat (no mask - literally constant) and Clay (soft procedural noise,\r\n  // PLAN §6.1) so the runtime tint system has an always-unlocked, no-download starting pair.\r\n  case 30:h=.5;t=.5;rough=.55;break;\r\n  case 31:h=.5+grain*.05+wave*.008;t=.5+grain*.03;rough=.92;break;\r\n }\r\n return {height:h,tint:clamp(t,0,1),glow,rough};\r\n}\r\nconst maps=new Map<string,{map:T.DataTexture;bump:T.DataTexture;rough:T.DataTexture;glow:T.DataTexture}>();\r\nfunction materialMaps(style:Style){\r\n const key=[MATERIAL_REVISION,style.id,style.primary,style.secondary,style.accent,style.paletteId??''].join('|');if(maps.has(key))return maps.get(key)!;\r\n const size=192,buffers=Array.from({length:4},()=>new Uint8Array(size*size*4));\r\n const dark=new T.Color(style.secondary),base=new T.Color(style.primary),light=new T.Color(style.accent),color=new T.Color(),profile=builtinSurfaceProfile(style.id);\r\n for(let y=0;y<size;y++)for(let x=0;x<size;x++){\r\n  const s=surfaceSample(style.id,x/size,y/size),i=(y*size+x)*4;\r\n  const tint=samplePaletteTint(style.paletteId,s.tint,x/size,y/size,style.id===30); // Palette stops follow the existing texture tones; watercolor/marbled add a spatial finish tint.\r\n  color.copy(tint<.5?dark:base).lerp(tint<.5?base:light,tint<.5?tint*2:(tint-.5)*2);\r\n  const roughnessMap=profile?clamp(.9+(s.rough-profile.roughness)*.75,0,1):s.rough;\r\n  for(let k=0;k<3;k++){buffers[0][i+k]=Math.round([color.r,color.g,color.b][k]*255);buffers[1][i+k]=s.height*255;buffers[2][i+k]=roughnessMap*255;buffers[3][i+k]=s.glow*255;}\r\n  for(const b of buffers)b[i+3]=255;\r\n }\r\n const textures=buffers.map(bytes=>{const tex=new T.DataTexture(bytes,size,size,T.RGBAFormat);tex.wrapS=tex.wrapT=T.RepeatWrapping;tex.magFilter=T.LinearFilter;tex.minFilter=T.LinearMipmapLinearFilter;tex.generateMipmaps=true;tex.needsUpdate=true;return tex;});\r\n const result={map:textures[0],bump:textures[1],rough:textures[2],glow:textures[3]};maps.set(key,result);return result;\r\n}\r\n/** Colour-only path for irises and other parts whose geometry must stay intact. */\r\nexport function applyPaletteSurface(material:T.MeshStandardMaterial,palette:{primary:string;secondary:string;accent:string;paletteId?:string;id?:number}){\r\n if(!palette.paletteId)return;\r\n material.map=materialMaps({...palette,id:palette.id??30,emissive:'#000000',roughness:.55,metalness:0,detail:'palette'}).map;\r\n material.color.set('white');material.needsUpdate=true;\r\n applyPaletteFinish(material as T.MeshPhysicalMaterial,palette.paletteId,palette);\r\n}\r\nexport function materialFor(style:Style,unit:number,original?:T.MeshStandardMaterial){\r\n const tex=materialMaps(style),id=style.id;\r\n const profile=builtinSurfaceProfile(id);\r\n const mat=new T.MeshPhysicalMaterial({name:style.detail+' · '+MATERIAL_REVISION,color:'white',map:tex.map,bumpMap:tex.bump,bumpScale:unit*(profile?.bump??([8,21,22].includes(id)?.0005:.007)),roughnessMap:tex.rough,roughness:profile?.roughness??1,metalness:style.metalness,vertexColors:true,envMapIntensity:[18,19,14].includes(id)?1.3:1});\r\n if(original){mat.side=original.side;mat.polygonOffset=original.polygonOffset;mat.polygonOffsetFactor=original.polygonOffsetFactor;}\r\n if([3,4,10,11,14,18,19,21].includes(id)){mat.clearcoat=id===21?1:.6;mat.clearcoatRoughness=id===21?.055:.19;}\r\n if([8,14,16,21].includes(id)){\r\n  mat.transmission=id===21?.8:id===8?.62:id===16?.54:.28;mat.thickness=unit*(id===21?.36:.16);mat.ior=id===21?1.36:id===16?1.31:1.46;\r\n  mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*(id===21?1.4:2);mat.metalness=0;mat.roughnessMap=null;mat.roughness=id===21?.075:id===16?.16:.12;\r\n }\r\n if([5,8,9,10,11,12,15,17,19].includes(id)){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=id===15?2.1:id===17?1.5:.85;}\r\n if(id===20){mat.sheen=1;mat.sheenRoughness=.96;mat.sheenColor.set(style.accent);mat.metalness=0;}\r\n if(id===0||id===22){mat.sheen=.22;mat.sheenColor.set('#ffc9b1');}\r\n if(profile){mat.sheen=profile.sheen;mat.sheenRoughness=profile.sheenRoughness;mat.sheenColor.set(style.accent);mat.clearcoat=Math.max(mat.clearcoat,profile.clearcoat);mat.clearcoatRoughness=profile.clearcoatRoughness;}\r\n if(id>=57&&id<=62){\r\n  mat.envMapIntensity=1.65;mat.iridescence=id===60?1:id===57?.85:.3;\r\n  mat.iridescenceThicknessRange=id===60?[100,750]:[140,480];\r\n  if([57,58,59,61].includes(id)){\r\n   mat.transmission=id===58?.97:id===59?.84:.88;mat.thickness=unit*(id===59?.32:.48);\r\n   mat.ior=id===59?1.8:id===58?1.46:1.38;mat.metalness=0;\r\n   mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*3.5;\r\n   mat.roughnessMap=null;mat.roughness=profile!.roughness;\r\n   mat.dispersion=id===59?.75:.2;\r\n  }\r\n  if(id===62){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=.65;}\r\n }\r\n if(id===63||id===74){mat.transmission=id===63?.48:.82;mat.thickness=unit*.32;mat.ior=id===63?1.33:1.52;mat.metalness=0;mat.attenuationColor.set(style.primary);mat.attenuationDistance=unit*2.4;mat.roughnessMap=null;mat.roughness=profile!.roughness;}\r\n if([69,70,74].includes(id)){mat.emissive.set(style.accent);mat.emissiveMap=tex.glow;mat.emissiveIntensity=id===74?1.1:.75;}\r\n mat.flatShading=[13,14,59].includes(id);mat.userData.materialStyle=id;\r\n const optics={transmission:mat.transmission,thickness:mat.thickness,ior:mat.ior,roughness:mat.roughness,metalness:mat.metalness,iridescence:mat.iridescence,iridescenceThicknessRange:mat.iridescenceThicknessRange};\r\n applyPaletteFinish(mat,style.paletteId,style);\r\n // Color finishes coat a clear volume; they must not erase the chosen jelly/glass texture.\r\n if(style.paletteId&&optics.transmission>0){Object.assign(mat,optics);mat.clearcoat=1;mat.clearcoatRoughness=.035;}\r\n if(id===60){mat.metalness=.88;mat.iridescence=1;mat.iridescenceThicknessRange=[100,750];mat.roughness=.16;}\r\n if(id===61||id===62)applySparkle(mat,.85);\r\n return mat;\r\n}\r\n\r\n// Sparkle flakes stay attached to the UV surface and flash as the viewing angle changes.\r\nexport function applySparkle(mat:T.MeshPhysicalMaterial,sparkle:number){\r\n const amount=clamp(sparkle,0,1);if(amount<=0||mat.userData.myr5FinishGlitter)return;\r\n if(mat.userData.myr5Sparkle)return;mat.userData.myr5Sparkle=amount;\r\n const previous=mat.onBeforeCompile;(mat as T.MeshPhysicalMaterial & {defines?:Record<string,string>}).defines={...(mat as T.MeshPhysicalMaterial & {defines?:Record<string,string>}).defines,USE_UV:''};\r\n mat.onBeforeCompile=(shader,renderer)=>{\r\n  previous?.call(mat,shader,renderer);\r\n  shader.uniforms.uSparkle={value:amount};\r\n  shader.vertexShader=shader.vertexShader.replace('#include <common>','#include <common>\\nvarying vec2 vMyr5SparkleUv;').replace('#include <uv_vertex>','#include <uv_vertex>\\nvMyr5SparkleUv=uv;');\r\n  shader.fragmentShader=shader.fragmentShader\r\n   .replace('#include <common>','uniform float uSparkle;\\nvarying vec2 vMyr5SparkleUv;\\n#include <common>')\r\n   .replace('#include <dithering_fragment>','float mySparkleGrain=fract(sin(dot(floor(vMyr5SparkleUv*83.0),vec2(12.9898,78.233)))*43758.5453);\\nvec3 myFlakeNormal=normalize(normal+vec3(sin(mySparkleGrain*91.0),cos(mySparkleGrain*73.0),0.0)*.55);\\nfloat myGlint=pow(max(dot(myFlakeNormal,normalize(vViewPosition)),0.0),42.0);\\ngl_FragColor.rgb+=step(0.94,mySparkleGrain)*myGlint*uSparkle*2.2;\\n#include <dithering_fragment>');\r\n };\r\n const priorKey=mat.customProgramCacheKey.bind(mat);mat.customProgramCacheKey=()=>priorKey()+'|myr5-sparkle-v3|'+amount.toFixed(3);\r\n mat.needsUpdate=true;\r\n}\r\n\r\nfunction meshWorldSpan(g:T.BufferGeometry,matrix:T.Matrix4){\r\n if(!g.boundingBox)g.computeBoundingBox();\r\n const size=g.boundingBox!.clone().applyMatrix4(matrix).getSize(new T.Vector3());\r\n return Math.max(size.x,size.y,size.z,1e-6);\r\n}\r\n\r\nexport function authoredUvScale(g:T.BufferGeometry,matrix:T.Matrix4){\r\n const uv=g.attributes.uv,p=g.attributes.position,idx=g.index;if(!uv||uv.itemSize<2)return 1.8;\r\n let worldArea=0,uvArea=0;const a=new T.Vector3(),b=new T.Vector3(),c=new T.Vector3(),ab=new T.Vector3(),ac=new T.Vector3();\r\n const count=idx?.count??p.count;\r\n for(let j=0;j+2<count;j+=3){const ia=idx?idx.getX(j):j,ib=idx?idx.getX(j+1):j+1,ic=idx?idx.getX(j+2):j+2;\r\n  a.fromBufferAttribute(p,ia).applyMatrix4(matrix);b.fromBufferAttribute(p,ib).applyMatrix4(matrix);c.fromBufferAttribute(p,ic).applyMatrix4(matrix);\r\n  ab.subVectors(b,a);ac.subVectors(c,a);worldArea+=ab.cross(ac).length()*.5;\r\n  const ux=uv.getX(ib)-uv.getX(ia),uy=uv.getY(ib)-uv.getY(ia),vx=uv.getX(ic)-uv.getX(ia),vy=uv.getY(ic)-uv.getY(ia);uvArea+=Math.abs(ux*vy-uy*vx)*.5;\r\n }\r\n if(!Number.isFinite(worldArea)||!Number.isFinite(uvArea)||worldArea<=1e-10||uvArea<=1e-10)return 1.8;\r\n // Divide physical UV density by the mesh span. A ten-times larger imported\r\n // sculpt should show the same sized pattern, not 10x more tiles that mipmap away.\r\n const span=meshWorldSpan(g,matrix);\r\n return T.MathUtils.clamp(Math.sqrt(worldArea/uvArea)*1.8/Math.max(1,span/2),.5,6);\r\n}\r\n\r\n// R25: a vertex can only carry relief that is coarser than the mesh. Point-sampling a finer pattern\r\n// (Fine Stripe has 40 strands per tile) at sparse roster vertices aliased into lumpy patches, so the\r\n// displacement fades out between a quarter and half of the pattern's finest wavelength; the bump and\r\n// colour maps still draw the full detail. Wavelength = finest axis, Schmitt-triggered against noise.\r\nconst reliefWavelengths=new Map<number,number>();\r\nfunction reliefWavelength(id:number){\r\n let w=reliefWavelengths.get(id);if(w!==undefined)return w;w=Infinity;const n=2048;\r\n for(const axis of [0,1]){const h=new Float32Array(n);let lo=1,hi=0;for(let i=0;i<n;i++){h[i]=surfaceSample(id,axis?.37:i/n,axis?i/n:.37).height;lo=Math.min(lo,h[i]);hi=Math.max(hi,h[i]);}\r\n  const mid=(lo+hi)/2,band=(hi-lo)*.2;let side=0,crossings=0;for(const value of h){const next=value>mid+band?1:value<mid-band?-1:side;if(side&&next!==side)crossings++;side=next;}\r\n  if(crossings)w=Math.min(w,2/crossings);}\r\n reliefWavelengths.set(id,w);return w;\r\n}\r\nfunction meanEdge(g:T.BufferGeometry,matrix:T.Matrix4){\r\n const p=g.attributes.position,idx=g.index,count=idx?.count??p.count,stride=Math.max(1,Math.floor(count/3/4000))*3,a=new T.Vector3(),b=new T.Vector3();let sum=0,edges=0;\r\n for(let j=0;j+2<count;j+=stride)for(let k=0;k<3;k++){a.fromBufferAttribute(p,idx?idx.getX(j+k):j+k).applyMatrix4(matrix);b.fromBufferAttribute(p,idx?idx.getX(j+(k+1)%3):j+(k+1)%3).applyMatrix4(matrix);sum+=a.distanceTo(b);edges++;}\r\n return edges?sum/edges:0;\r\n}\r\nexport function reliefResolve(id:number,uvEdge:number){const w=reliefWavelength(id);return 1-T.MathUtils.smoothstep(uvEdge,w/4,w/2);}\r\n\r\nexport function sculptMaterial(mesh:T.Mesh,style:Style,unit=1,amount=1,coachRelief?:CoachReliefBudget){\r\n if(Array.isArray(mesh.material)||!mesh.geometry.attributes.position)return;\r\n // The higher-density authored-UV path is deliberately limited to known static meshes.\r\n // Keep animated, morph-target, interleaved and unsupported Float16 geometry on the\r\n // established path until their attributes can be refined without changing semantics.\r\n if(coachRelief&&((mesh as T.SkinnedMesh).isSkinnedMesh||mesh.geometry.attributes.skinIndex||mesh.geometry.attributes.skinWeight||Object.values(mesh.geometry.morphAttributes).some(attributes=>attributes.length)||Object.values(mesh.geometry.attributes).some(attribute=>(attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||(attribute as T.BufferAttribute & {isFloat16BufferAttribute?:boolean}).isFloat16BufferAttribute||((globalThis as any).Float16Array&&attribute.array instanceof (globalThis as any).Float16Array))))coachRelief=undefined;\r\n const old=mesh.geometry;\r\n // Keep Original MYR5's established single-pass geometry, UVs and JS-double displacement path exact.\r\n if(!coachRelief){\r\n  const g=old.clone();if(!g.attributes.normal)g.computeVertexNormals();\r\n  const p=g.attributes.position,n=g.attributes.normal,uv=new Float32Array(p.count*2),colors=new Float32Array(p.count*3);\r\n  mesh.updateWorldMatrix(true,false);const normalMatrix=new T.Matrix3().getNormalMatrix(mesh.matrixWorld),inv=mesh.matrixWorld.clone().invert(),point=new T.Vector3(),normal=new T.Vector3();\r\n  const id=style.id,relief=unit*(builtinSurfaceProfile(id)?.relief??([0,8,20,21,22].includes(id)?.0018:id===13?.037:id===18?.018:.019));\r\n  for(let i=0;i<p.count;i++){\r\n   point.fromBufferAttribute(p,i).applyMatrix4(mesh.matrixWorld);normal.fromBufferAttribute(n,i).applyMatrix3(normalMatrix).normalize();\r\n   const x=point.x/unit,y=point.y/unit,z=point.z/unit;\r\n   const u=(Math.abs(normal.z)>.45?x:z)*1.8+.5,v=y*1.8+.5,s=surfaceSample(id,u,v);uv[i*2]=u;uv[i*2+1]=v;\r\n   let edge=1;for(const [sx,sy,sz,r]of mesh.userData.eyeSockets??[])edge*=T.MathUtils.smoothstep(Math.hypot(point.x-sx,point.y-sy,point.z-sz),r*1.04,r*1.35);\r\n   point.addScaledVector(normal,(s.height-.5)*relief*amount*edge).applyMatrix4(inv);p.setXYZ(i,point.x,point.y,point.z);\r\n   const shade=.91+.09*Math.sin(x*3+y*4+z*2);colors.set([shade,shade,shade],i*3);\r\n  }\r\n  g.setAttribute('uv',new T.BufferAttribute(uv,2));g.setAttribute('color',new T.BufferAttribute(colors,3));g.computeVertexNormals();g.computeBoundingBox();g.computeBoundingSphere();\r\n  const oldMat=mesh.material as T.MeshStandardMaterial;mesh.material=materialFor(style,unit,oldMat);mesh.geometry=g;\r\n  if(mesh.userData.ownedGeometry)old.dispose();mesh.userData.ownedGeometry=true;mesh.userData.ownedMaterial=true;return;\r\n }\r\n mesh.updateWorldMatrix(true,false);const worldScale=mesh.matrixWorld.getMaxScaleOnAxis(),refined=refineCoachGeometry(old,coachRelief,worldScale),g=refined?.geometry??old.clone();if(!g.attributes.normal)g.computeVertexNormals();\r\n // Keep imported smoothing while adding only the geometric normal change caused by relief.\r\n // This avoids faceting the source coach while making shallow height fields catch light.\r\n const authoredNormals=new Float32Array(g.attributes.normal.array as ArrayLike<number>);g.computeVertexNormals();const geometricBefore=new Float32Array(g.attributes.normal.array as ArrayLike<number>);g.attributes.normal.array.set(authoredNormals);g.attributes.normal.needsUpdate=true;\r\n const p=g.attributes.position,n=g.attributes.normal,uv=new Float32Array(p.count*2),colors=new Float32Array(p.count*3),worldPositions=new Float32Array(p.count*3),worldOffsets=new Float32Array(p.count*3);\r\n const vertexKeys=coachRelief?new Array<string>(p.count):undefined;\r\n const coordinateUnit=Math.max(unit,meshWorldSpan(g,mesh.matrixWorld)/2);\r\n const resolvable=reliefResolve(style.id,meanEdge(g,mesh.matrixWorld)*1.8/coordinateUnit);\r\n const normalMatrix=new T.Matrix3().getNormalMatrix(mesh.matrixWorld),inv=mesh.matrixWorld.clone().invert(),point=new T.Vector3(),normal=new T.Vector3();\r\n const id=style.id,relief=Math.min(unit*(builtinSurfaceProfile(id)?.relief??([0,8,20,21,22].includes(id)?.0018:id===13?.037:id===18?.018:.019)),meshWorldSpan(g,mesh.matrixWorld)*.015);\r\n const seamOffsets=coachRelief?new Map<string,{x:number;y:number;z:number;count:number}>():undefined,seamKey=(x:number,y:number,z:number)=>`${Math.round(x*1e5)},${Math.round(y*1e5)},${Math.round(z*1e5)}`;\r\n for(let i=0;i<p.count;i++){\r\n  const localX=p.getX(i),localY=p.getY(i),localZ=p.getZ(i);point.set(localX,localY,localZ).applyMatrix4(mesh.matrixWorld);normal.fromBufferAttribute(n,i).applyMatrix3(normalMatrix).normalize();\r\n  const x=point.x/coordinateUnit,y=point.y/coordinateUnit,z=point.z/coordinateUnit;\r\n  // R25: every species uses Original MYR5's object projection. Authored (Tripo atlas) UVs are cut into\r\n  // islands with their own rotation and density, so directional patterns such as Fine Stripe turned\r\n  // into a patchwork across the belly. The projection is fixed on the mesh and periodic for the surfaces.\r\n  const u=(Math.abs(normal.z)>.45?x:z)*1.8+.5,v=y*1.8+.5,s=surfaceSample(id,u,v);\r\n  uv[i*2]=u;uv[i*2+1]=v;worldPositions[i*3]=point.x;worldPositions[i*3+1]=point.y;worldPositions[i*3+2]=point.z;\r\n  let edge=1;for(const [sx,sy,sz,r]of mesh.userData.eyeSockets??[])edge*=T.MathUtils.smoothstep(Math.hypot(point.x-sx,point.y-sy,point.z-sz),r*1.04,r*1.35);\r\n  const offset=(s.height-.5)*relief*amount*edge*resolvable,dx=normal.x*offset,dy=normal.y*offset,dz=normal.z*offset;worldOffsets[i*3]=dx;worldOffsets[i*3+1]=dy;worldOffsets[i*3+2]=dz;\r\n  if(seamOffsets){const key=seamKey(localX,localY,localZ);vertexKeys![i]=key;const group=seamOffsets.get(key)??{x:0,y:0,z:0,count:0};group.x+=dx;group.y+=dy;group.z+=dz;group.count++;seamOffsets.set(key,group);}\r\n  const shade=.91+.09*Math.sin(x*3+y*4+z*2);colors.set([shade,shade,shade],i*3);\r\n }\r\n for(let i=0;i<p.count;i++){\r\n  const x=worldPositions[i*3],y=worldPositions[i*3+1],z=worldPositions[i*3+2];let dx=worldOffsets[i*3],dy=worldOffsets[i*3+1],dz=worldOffsets[i*3+2];\r\n  if(seamOffsets){const group=seamOffsets.get(vertexKeys![i]);if(group&&group.count>1){dx=group.x/group.count;dy=group.y/group.count;dz=group.z/group.count;}}\r\n  point.set(x+dx,y+dy,z+dz).applyMatrix4(inv);p.setXYZ(i,point.x,point.y,point.z);\r\n }\r\n g.computeVertexNormals();const geometricAfter=g.attributes.normal;\r\n for(let i=0;i<p.count;i++){const j=i*3,x=authoredNormals[j]+geometricAfter.array[j]-geometricBefore[j],y=authoredNormals[j+1]+geometricAfter.array[j+1]-geometricBefore[j+1],z=authoredNormals[j+2]+geometricAfter.array[j+2]-geometricBefore[j+2],length=Math.hypot(x,y,z)||1;geometricAfter.setXYZ(i,x/length,y/length,z/length);}\r\n g.setAttribute('uv',new T.BufferAttribute(uv,2));g.setAttribute('color',new T.BufferAttribute(colors,3));g.computeBoundingBox();g.computeBoundingSphere();\r\n const oldMat=mesh.material as T.MeshStandardMaterial;mesh.material=materialFor(style,unit,oldMat);mesh.geometry=g;\r\n if(mesh.userData.ownedGeometry)old.dispose();mesh.userData.ownedGeometry=true;mesh.userData.ownedMaterial=true;\r\n}\r\n\r\ntype Triangle={a:T.Vector3;b:T.Vector3;c:T.Vector3;normal:T.Vector3;total:number};\r\nfunction surfaceTriangles(group:T.Group){\r\n group.updateWorldMatrix(true,true);const inv=group.matrixWorld.clone().invert(),triangles:Triangle[]=[],bounds=new T.Box3();let total=0;\r\n group.traverseVisible(obj=>{if(!(obj instanceof T.Mesh)||obj.userData.materialDetail)return;const g=obj.geometry,p=g.attributes.position,ix=g.index;if(!p)return;\r\n  const matrix=inv.clone().multiply(obj.matrixWorld),normalMatrix=new T.Matrix3().getNormalMatrix(matrix),authored=g.attributes.normal,count=ix?.count??p.count;\r\n  // Surface sampling needs area coverage, not every triangle of the dense fur assets.\r\n  const stride=Math.max(1,Math.ceil(count/24000))*3;\r\n  for(let j=0;j+2<count;j+=stride){const ids=[0,1,2].map(k=>ix?ix.getX(j+k):j+k),[a,b,c]=ids.map(i=>new T.Vector3().fromBufferAttribute(p,i).applyMatrix4(matrix));const cross=b.clone().sub(a).cross(c.clone().sub(a)),area=cross.length()*.5;if(area<1e-10)continue;const normal=authored?ids.reduce((sum,i)=>sum.add(new T.Vector3().fromBufferAttribute(authored,i).applyMatrix3(normalMatrix)),new T.Vector3()).normalize():cross.normalize();if(normal.lengthSq()<1e-8)normal.copy(cross).normalize();total+=area;bounds.expandByPoint(a);bounds.expandByPoint(b);bounds.expandByPoint(c);triangles.push({a,b,c,normal,total});}\r\n });return {triangles,total,bounds};\r\n}\r\nexport function growMaterial(group:T.Group,style:Style,region:string,unit=1,amount=1,hand=false){\r\n const result=new T.Group();result.name='Material sculpture '+style.detail;result.userData.region=region;\r\n if(region==='eye'||region==='nails'||[0,7,22].includes(style.id))return result;\r\n const {triangles,total,bounds}=surfaceTriangles(group);if(!triangles.length)return result;\r\n let seed=style.id*9173+region.length*419;const rand=()=>{seed=(Math.imul(seed,1664525)+1013904223)>>>0;return seed/4294967296;};\r\n const id=style.id;if(hand&&id===20)return result;\r\n const baseCount=id===20?2100:[3,4].includes(id)?110:id===21?32:42;\r\n const count=Math.round((id>=63?(id===66?60:id===68?22:id===72?12:38):id>=57&&id<=62?(id===61?180:id===58?55:36):baseCount)*(region==='head'||region==='palm'||region==='back_of_hand'?1:region==='body'?.8:.5));\r\n const batches:T.BufferGeometry[][]=[[],[],[]],normal=new T.Vector3(),point=new T.Vector3(),up=new T.Vector3(0,1,0);\r\n const span=bounds.getSize(new T.Vector3()),featureUnit=unit*T.MathUtils.clamp(Math.cbrt(Math.max(1e-6,span.x*span.y*span.z))/2.2,1,2.2);\r\n function add(g:T.BufferGeometry,pos:T.Vector3,q:T.Quaternion,scale:T.Vector3,material=0){g.applyMatrix4(new T.Matrix4().compose(pos,q,scale));if(!g.attributes.uv)g.setAttribute('uv',new T.Float32BufferAttribute(new Float32Array(g.attributes.position.count*2),2));if(g.index){const expanded=g.toNonIndexed();g.dispose();g=expanded;}batches[material].push(g);}\r\n const color=[style.primary,style.accent,style.secondary];\r\n for(let k=0;k<count;k++){\r\n  const pick=rand()*total;let lo=0,hi=triangles.length-1;while(lo<hi){const m=(lo+hi)>>1;if(triangles[m].total<pick)lo=m+1;else hi=m;}\r\n  const {a,b,c}=triangles[lo],u=Math.sqrt(rand()),v=rand();point.copy(a).multiplyScalar(1-u).addScaledVector(b,u*(1-v)).addScaledVector(c,u*v);normal.copy(triangles[lo].normal);\r\n  let socket=false;group.traverse(o=>{for(const [x,y,z,r]of o.userData.eyeSockets??[])if(point.distanceTo(new T.Vector3(x,y,z))<r*1.48)socket=true;});\r\n  if(socket||(!hand&&region==='feet'&&normal.y<-.2))continue;\r\n  const larger=[2,3,9,13,14,16].includes(id)?1.7:1;\r\n  const q=new T.Quaternion().setFromUnitVectors(up,normal),s=featureUnit*amount*(.055+rand()*.075)*larger,center=point.clone(),size=new T.Vector3(s,s,s);\r\n  const geometry=(g:T.BufferGeometry,offset=0,scale=size,mat=0)=>add(g,center.clone().addScaledVector(normal,offset+s*.12),q,scale,mat);\r\n  switch(id){\r\n   case 63:geometry(new T.SphereGeometry(.8,10,7),-s*.3,new T.Vector3(s,s*.6,s),k%3);break;\r\n   case 64:geometry(new T.SphereGeometry(.7,10,7),-s*.12,new T.Vector3(s*.8,s*.65,s*.8),k%3);if(k%3===0)geometry(new T.TorusGeometry(.45,.13,5,10).rotateX(Math.PI/2),s*.05,size,0);break;\r\n   case 65:geometry(new T.DodecahedronGeometry(.6,0),0,new T.Vector3(s,s*.45,s),k%3);geometry(new T.SphereGeometry(.22,6,4),s*.4,size,2);break;\r\n   case 66:{const curve=new T.CatmullRomCurve3([new T.Vector3(-.7,0,0),new T.Vector3(-.25,.35,.25),new T.Vector3(.3,.2,-.15),new T.Vector3(.65,.55,.1)]);geometry(new T.TubeGeometry(curve,7,.15,5,false),s*.06,new T.Vector3(s,s,s),k%3);break;}\r\n   case 67:{const curve=new T.CatmullRomCurve3([new T.Vector3(-.6,0,0),new T.Vector3(-.15,.3,.15),new T.Vector3(.5,.55,-.1)]);geometry(new T.TubeGeometry(curve,6,.12,5,false),s*.1,new T.Vector3(s*.75,s*1.4,s),k%3);break;}\r\n   case 68:{geometry(new T.CylinderGeometry(.48,.38,.045,12),s*.12,size,1);geometry(new T.TorusGeometry(.53,.13,6,12).rotateX(Math.PI/2),s*.17,size,0);for(let t=0;t<6;t++){const a=t*Math.PI/3,offset=new T.Vector3(Math.cos(a)*s*.34,s*.32,Math.sin(a)*s*.34).applyQuaternion(q);add(new T.ConeGeometry(.08,.34,5),center.clone().add(offset),q,size,2);}break;}\r\n   case 69:geometry(new T.BoxGeometry(.65,.13,.85),s*.04,size,0);geometry(new T.BoxGeometry(.08,.05,1.15),s*.14,size,2);geometry(new T.CylinderGeometry(.12,.12,.1,8),s*.18,size,2);break;\r\n   case 70:geometry(new T.BoxGeometry(1.25,.18,.85),s*.1,size,0);geometry(new T.CylinderGeometry(.17,.17,.19,8),s*.27,size,1);geometry(new T.BoxGeometry(.9,.05,.12),s*.25,size,2);break;\r\n   case 71:geometry(new T.CylinderGeometry(.15,.15,1.7,8).rotateZ(Math.PI/2),s*.13,size,0);geometry(new T.BoxGeometry(.2,.11,1.05),s*.12,size,1);break;\r\n   case 72:geometry(new T.BoxGeometry(.8,.1,.5),s*.07,size,1);geometry(new T.CylinderGeometry(.1,.1,.12,6),s*.16,size,0);break;\r\n   case 73:geometry(new T.BoxGeometry(1,.15,1),s*.1,size,0);geometry(new T.BoxGeometry(.08,.025,1.1).rotateY(Math.PI/4),s*.2,size,1);break;\r\n   case 74:geometry(new T.SphereGeometry(.32,8,6),-s*.05,size,2);geometry(new T.TorusGeometry(.45,.07,5,12).rotateX(Math.PI/2),s*.07,size,0);break;\r\n   case 57:geometry(new T.OctahedronGeometry(.55,1),-s*.3,new T.Vector3(s*.6,s*.2,s*.6),k%3);break;\r\n   case 58:geometry(new T.SphereGeometry(.55,10,7),-s*.4,new T.Vector3(s*.45,s*.65,s*.45),k%3);break;\r\n   case 59:case 62:geometry(new T.CylinderGeometry(0,.32,1.7,6),s*.42,size,k%3);break;\r\n   case 61:geometry(new T.OctahedronGeometry(.22),-s*.2,new T.Vector3(s,s*.18,s),k%3);break;\r\n   case 1:{ // Roots and leaves have separate silhouettes, not generic spikes.\r\n    const path=new T.CatmullRomCurve3([new T.Vector3(0,-.1,0),new T.Vector3(.18,.5,0),new T.Vector3(-.15,1.3,.1),new T.Vector3(.35,2,.1)]);\r\n    geometry(new T.TubeGeometry(path,8,.14,5,false),0,size,2);geometry(new T.SphereGeometry(1,8,5),s*1.1,new T.Vector3(s*.55,s*.9,s*.12),1);break;}\r\n   case 2:geometry(new T.CylinderGeometry(.13,.19,1,6),s*.25,new T.Vector3(s,s,s),2);geometry(new T.SphereGeometry(1,12,8,0,Math.PI*2,0,Math.PI/2),s*.8,new T.Vector3(s*.8,s*.38,s*.8),k%3===0?1:0);geometry(new T.ConeGeometry(.73,.12,16),s*.77,size,2);break;\r\n   case 3:geometry(new T.SphereGeometry(1,6,4),s*.08,new T.Vector3(s*.86,s*.26,s*1.3),0);geometry(new T.ConeGeometry(.19,.8,5),s*.34,size,1);break;\r\n   case 4:geometry(new T.SphereGeometry(1,5,3),s*.015,new T.Vector3(s*.68,s*.17,s),k%6===0?1:0);break;\r\n   case 5:geometry(new T.ConeGeometry(.18,2.5,4),s*.6,new T.Vector3(s,s,s*.5),2);geometry(new T.SphereGeometry(.22,8,5),s*1.7,size,1);break;\r\n   case 6:{geometry(new T.CylinderGeometry(.19,.32,1.9,7),s*.55,size,0);for(const sign of [-1,1]){const branchQ=q.clone().multiply(new T.Quaternion().setFromAxisAngle(new T.Vector3(0,0,1),sign*.62));add(new T.CylinderGeometry(.12,.2,1.2,6),center.clone().addScaledVector(normal,s),branchQ,size,1);}geometry(new T.TorusGeometry(.2,.08,5,9),s*1.5,size,2);break;}\r\n   case 8:geometry(new T.SphereGeometry(1,9,6),s*.3,new T.Vector3(s*.3,s*1.9,s*.13),1);break;\r\n   case 9:{const curve=new T.CatmullRomCurve3([new T.Vector3(0,-.15,0),new T.Vector3(.1,.7,0),new T.Vector3(.6,1.5,0)]);const g=new T.TubeGeometry(curve,9,.24,7,false),p=g.attributes.position;for(let j=0;j<p.count;j++){const t=Math.floor(j/8)/9,at=curve.getPointAt(t),v=new T.Vector3().fromBufferAttribute(p,j).sub(at).multiplyScalar(1-t*.97).add(at);p.setXYZ(j,v.x,v.y,v.z);}g.computeVertexNormals();geometry(g,0,size,2);break;}\r\n   case 10:geometry(new T.TorusGeometry(.65,.075,5,18,Math.PI*1.55),s*.3,size,1);geometry(new T.OctahedronGeometry(.35),s*.4,size,0);break;\r\n   case 11:geometry(new T.OctahedronGeometry(1),s*.02,new T.Vector3(s*.7,s*.28,s*.85),2);geometry(new T.OctahedronGeometry(.11),s*.5,size,1);break;\r\n   case 12:geometry(new T.TorusGeometry(.65,.18,7,13,Math.PI*1.8),s*.25,size,0);geometry(new T.SphereGeometry(.28,8,6),s*.4,size,1);break;\r\n   case 13:geometry(new T.DodecahedronGeometry(1,0),s*.05,new T.Vector3(s*1.3,s*.38,s*.9),k%4===0?1:0);break;\r\n   case 14:case 16:geometry(new T.CylinderGeometry(0,.36,2.3,id===14?6:5),s*.72,new T.Vector3(s,s,s),k%3===0?1:0);geometry(new T.CylinderGeometry(.28,.34,.65,6),s*.14,size,2);break;\r\n   case 15:geometry(new T.DodecahedronGeometry(1,0),s*.025,new T.Vector3(s*1.25,s*.22,s),2);break;\r\n   case 17:geometry(new T.BoxGeometry(.12,1.7,.9),s*.45,size,2);geometry(new T.CylinderGeometry(.08,.08,1.4,5),s*.4,size,1);break;\r\n   case 18:{geometry(new T.CylinderGeometry(.76,.88,.18,8),s*.12,size,0);geometry(new T.TorusGeometry(.38,.1,5,14),s*.26,size,2);for(let r=0;r<6;r++){const angle=r*Math.PI/3,offset=new T.Vector3(Math.cos(angle)*s*.63,s*.29,Math.sin(angle)*s*.63).applyQuaternion(q);add(new T.CylinderGeometry(.08,.08,.12,6),center.clone().add(offset),q,size,1);}if(k%3===0)geometry(new T.CylinderGeometry(.46,.46,.23,12),s*.32,size,2);break;}\r\n   case 19:geometry(new T.BoxGeometry(1.1,.19,1.65),s*.06,size,2);geometry(new T.BoxGeometry(.075,.035,1.35),s*.18,size,1);break;\r\n   case 20:{const lean=.3+rand()*.6,curve=new T.CatmullRomCurve3([new T.Vector3(0,-.1,0),new T.Vector3(.15,.6,.1),new T.Vector3(lean,1.3,.25),new T.Vector3(lean*1.4,1.65,.3)]);const g=new T.TubeGeometry(curve,5,.035,3,false),p=g.attributes.position;for(let j=0;j<p.count;j++){const t=Math.floor(j/4)/5,at=curve.getPointAt(t),v=new T.Vector3().fromBufferAttribute(p,j).sub(at).multiplyScalar(1-t*.96).add(at);p.setXYZ(j,v.x,v.y,v.z);}g.computeVertexNormals();geometry(g,0,size,k%4===0?1:k%5===0?2:0);break;}\r\n   case 21:geometry(new T.SphereGeometry(1,10,7),-s*.72,new T.Vector3(s*.3,s*.43,s*.3),k%4===0?1:2);break;\r\n  }\r\n }\r\n batches.forEach((geos,index)=>{if(!geos.length)return;const g=mergeGeometries(geos,false);geos.forEach(g=>g.dispose());if(!g)return;\r\n  const mat=new T.MeshPhysicalMaterial({color:color[index],roughness:[14,16,21].includes(id)?.12:id===20?.95:style.roughness,metalness:style.metalness,clearcoat:[3,18,19,21].includes(id)?.7:0});\r\n  if(index===1&&[5,8,9,11,12,15,17,19].includes(id)){mat.emissive.set(style.accent);mat.emissiveIntensity=1.2;}\r\n  if([8,14,16].includes(id)){mat.transmission=.45;mat.thickness=unit*.15;mat.ior=1.35;mat.metalness=0;}\r\n  if(id>=57&&id<=62){mat.clearcoat=1;mat.clearcoatRoughness=.035;mat.roughness=.08;mat.iridescence=.9;mat.iridescenceThicknessRange=[100,650];\r\n   if(id===58){mat.transmission=.75;mat.thickness=unit*.04;mat.metalness=0;mat.ior=1.1;}\r\n   if(id===57||id===59){mat.transmission=.5;mat.thickness=unit*.08;mat.metalness=0;mat.ior=1.6;}\r\n   if(id===61){mat.metalness=.9;applySparkle(mat,1);}\r\n   if(id===62&&index===1){mat.emissive.set(style.accent);mat.emissiveIntensity=.5;}\r\n  }\r\n  if(id>=63&&id<=68){mat.metalness=0;mat.clearcoat=id===65?0:1;mat.clearcoatRoughness=.055;mat.roughness=id===65?.98:.16;\r\n   if(id===63){mat.transmission=.55;mat.thickness=unit*.08;mat.ior=1.33;}\r\n   if(id===64&&index===2){mat.transmission=.25;mat.thickness=unit*.06;}\r\n  }\r\n  if(id>=69&&id<=74){mat.metalness=id===74?0:style.metalness;mat.clearcoat=.8;mat.clearcoatRoughness=.06;\r\n   if(index===2&&[69,70,74].includes(id)){mat.emissive.set(style.accent);mat.emissiveIntensity=1.3;}\r\n   if(id===74&&index===0){mat.transmission=.75;mat.thickness=unit*.04;mat.roughness=.045;}\r\n  }\r\n  if(id===20){mat.sheen=1;mat.sheenColor.set(style.accent);}\r\n  if(id===21){mat.color.set(index===1?style.accent:'#edffd3');mat.roughness=.12;mat.metalness=0;}\r\n  if(id===18){mat.metalness=.87;mat.color.set(index===2?'#333d48':color[index]);}\r\n  const mesh=new T.Mesh(g,mat);mesh.name=style.detail+' structural details';mesh.userData={materialDetail:true,ownedGeometry:true,ownedMaterial:true,region};result.add(mesh);\r\n });return result;\r\n}\r\n","handborne/source/app/material-patterns.ts":"/** Built-in procedural surface families. These are local math, so previews work offline. */\r\nexport type SurfaceSample={height:number;tint:number;glow:number;rough:number};\r\nexport type SurfaceProfile={id:number;name:string;roughness:number;metalness:number;relief:number;bump:number;sheen:number;sheenRoughness:number;clearcoat:number;clearcoatRoughness:number};\r\n\r\n// Stable ids 32-55 correspond to the Battle Pass catalogue order in materials-registry.ts.\r\nexport const BUILTIN_SURFACE_PROFILES:readonly SurfaceProfile[]=[\r\n {id:32,name:'Plate Steel',roughness:.34,metalness:.82,relief:.024,bump:.012,sheen:0,sheenRoughness:.7,clearcoat:.35,clearcoatRoughness:.24},\r\n {id:33,name:'Rubber Grip',roughness:.95,metalness:0,relief:.055,bump:.022,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:34,name:'Chain Mail',roughness:.41,metalness:.78,relief:.034,bump:.014,sheen:0,sheenRoughness:.7,clearcoat:.3,clearcoatRoughness:.25},\r\n {id:35,name:'Track Rubber',roughness:.94,metalness:0,relief:.038,bump:.016,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:36,name:'Denim',roughness:.86,metalness:0,relief:.012,bump:.011,sheen:.22,sheenRoughness:.96,clearcoat:0,clearcoatRoughness:.5},\r\n {id:37,name:'Hex Tread',roughness:.82,metalness:.04,relief:.052,bump:.014,sheen:0,sheenRoughness:.9,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:38,name:'Sweatshirt Fleece',roughness:.99,metalness:0,relief:.05,bump:.032,sheen:.74,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n {id:39,name:'Quilted',roughness:.89,metalness:0,relief:.07,bump:.012,sheen:.14,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:40,name:'Speckled',roughness:.96,metalness:0,relief:.03,bump:.028,sheen:.34,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n {id:41,name:'Hammered Bronze',roughness:.39,metalness:.78,relief:.025,bump:.025,sheen:0,sheenRoughness:.7,clearcoat:.28,clearcoatRoughness:.22},\r\n {id:42,name:'Fine Stripe',roughness:.91,metalness:0,relief:.042,bump:.012,sheen:.08,sheenRoughness:.92,clearcoat:0,clearcoatRoughness:.5},\r\n {id:43,name:'Snake Skin',roughness:.68,metalness:.02,relief:.019,bump:.023,sheen:.1,sheenRoughness:.76,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:44,name:'Holey',roughness:.96,metalness:0,relief:.039,bump:.025,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},\r\n {id:45,name:'Woven Mat',roughness:.9,metalness:0,relief:.014,bump:.014,sheen:.08,sheenRoughness:.94,clearcoat:0,clearcoatRoughness:.5},\r\n {id:46,name:'Petal',roughness:.51,metalness:0,relief:.025,bump:.009,sheen:.52,sheenRoughness:.72,clearcoat:.12,clearcoatRoughness:.3},\r\n {id:47,name:'Graph Paper',roughness:.93,metalness:0,relief:.012,bump:.017,sheen:.16,sheenRoughness:.97,clearcoat:0,clearcoatRoughness:.5},\r\n {id:48,name:'Bamboo',roughness:.57,metalness:0,relief:.027,bump:.008,sheen:.18,sheenRoughness:.62,clearcoat:.12,clearcoatRoughness:.28},\r\n {id:49,name:'Dragon Scale',roughness:.31,metalness:.16,relief:.043,bump:.01,sheen:.24,sheenRoughness:.42,clearcoat:.72,clearcoatRoughness:.16},\r\n {id:50,name:'Cool Graph Paper',roughness:.56,metalness:.23,relief:.021,bump:.008,sheen:0,sheenRoughness:.8,clearcoat:.12,clearcoatRoughness:.3},\r\n {id:51,name:'Terry Cloth',roughness:.98,metalness:0,relief:.014,bump:.026,sheen:.62,sheenRoughness:.99,clearcoat:0,clearcoatRoughness:.5},\r\n {id:52,name:'Pebble Path',roughness:.77,metalness:0,relief:.038,bump:.018,sheen:0,sheenRoughness:.8,clearcoat:.08,clearcoatRoughness:.4},\r\n {id:53,name:'Wiggles',roughness:.99,metalness:0,relief:.016,bump:.016,sheen:0,sheenRoughness:.95,clearcoat:0,clearcoatRoughness:.5},\r\n {id:54,name:'River Stone',roughness:.72,metalness:.01,relief:.031,bump:.019,sheen:.04,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.32},\r\n {id:55,name:'Moss',roughness:.99,metalness:0,relief:.022,bump:.023,sheen:.38,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},\r\n];\r\nconst pixelProfile:SurfaceProfile={id:56,name:'64-bit Skin',roughness:.58,metalness:.12,relief:.018,bump:.01,sheen:0,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.4};\r\n// Extra finishes use stable additive IDs; existing reward IDs retain their meaning.\r\nexport const SPECIAL_SURFACE_PROFILES:readonly SurfaceProfile[]=[\r\n {id:57,name:'Opal Jelly',roughness:.06,metalness:0,relief:.004,bump:.001,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.035},\r\n {id:58,name:'Bubble Glass',roughness:.035,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},\r\n {id:59,name:'Prism Crystal',roughness:.045,metalness:0,relief:.052,bump:.008,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.03},\r\n {id:60,name:'Holographic Foil',roughness:.18,metalness:.88,relief:.022,bump:.013,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.045},\r\n {id:61,name:'Glitter Resin',roughness:.075,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},\r\n {id:62,name:'Galaxy Geode',roughness:.22,metalness:.25,relief:.065,bump:.014,sheen:0,sheenRoughness:.3,clearcoat:.8,clearcoatRoughness:.06},\r\n {id:63,name:'Caustic Slime',roughness:0.055,metalness:0,relief:0.035,bump:0.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:64,name:'Blister Hide',roughness:0.18,metalness:0,relief:0.065,bump:0.023,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:65,name:'Rotten Rind',roughness:0.94,metalness:0,relief:0.05,bump:0.025,sheen:0,sheenRoughness:.6,clearcoat:0,clearcoatRoughness:.07},\r\n {id:66,name:'Parasite Nest',roughness:0.31,metalness:0,relief:0.07,bump:0.027,sheen:0,sheenRoughness:.6,clearcoat:0.6,clearcoatRoughness:.07},\r\n {id:67,name:'Exposed Sinew',roughness:0.2,metalness:0,relief:0.045,bump:0.017,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:68,name:'Abyssal Maw',roughness:0.26,metalness:0,relief:0.065,bump:0.023,sheen:0,sheenRoughness:.6,clearcoat:0.8,clearcoatRoughness:.07},\r\n {id:69,name:'Circuit Alloy',roughness:0.19,metalness:0.83,relief:0.027,bump:0.01,sheen:0,sheenRoughness:.6,clearcoat:0.6,clearcoatRoughness:.07},\r\n {id:70,name:'Servo Armor',roughness:0.34,metalness:0.82,relief:0.055,bump:0.013,sheen:0,sheenRoughness:.6,clearcoat:0.4,clearcoatRoughness:.07},\r\n {id:71,name:'Chrome Rib',roughness:0.09,metalness:0.96,relief:0.05,bump:0.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n {id:72,name:'Carbon Mech',roughness:0.64,metalness:0.18,relief:0.018,bump:0.013,sheen:0,sheenRoughness:.6,clearcoat:0.25,clearcoatRoughness:.07},\r\n {id:73,name:'Hazard Panel',roughness:0.46,metalness:0.55,relief:0.032,bump:0.014,sheen:0,sheenRoughness:.6,clearcoat:0.4,clearcoatRoughness:.07},\r\n {id:74,name:'Reactor Glass',roughness:0.045,metalness:0,relief:0.018,bump:0.004,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},\r\n];\r\nconst profiles=new Map([...BUILTIN_SURFACE_PROFILES,pixelProfile,...SPECIAL_SURFACE_PROFILES].map(p=>[p.id,p]));\r\nexport const builtinSurfaceProfile=(id:number)=>profiles.get(id);\r\nconst fract=(x:number)=>x-Math.floor(x),clamp=(x:number)=>Math.max(0,Math.min(1,x));\r\nconst hash=(x:number,y:number)=>fract(Math.sin(x*127.1+y*311.7)*43758.5453);\r\nconst smooth=(a:number,b:number,x:number)=>{const t=clamp((x-a)/(b-a));return t*t*(3-2*t);};\r\nconst triangle=(x:number)=>1-Math.abs(fract(x)*2-1);\r\nconst voronoi=(x:number,y:number)=>{const ix=Math.floor(x),iy=Math.floor(y);let near=9,next=9;for(let j=-1;j<=1;j++)for(let i=-1;i<=1;i++){const px=ix+i+.18+.64*hash(ix+i,iy+j),py=iy+j+.18+.64*hash(iy+j,ix+i+19),d=Math.hypot(x-px,y-py);if(d<near){next=near;near=d;}else if(d<next)next=d;}return{near,gap:next-near};};\r\n\r\n/** High-contrast structural masks are paired with their actual material height and roughness maps. */\r\nexport function sampleBuiltinSurface(id:number,x:number,y:number):SurfaceSample|undefined{\r\n if(!profiles.has(id))return undefined;\r\n x=fract(x);y=fract(y); // Geometry relief and RepeatWrapping must sample the same tiled domain.\r\n const g=Math.sin(x*167.3+Math.sin(y*43)*1.7)*Math.sin(y*151.7+Math.sin(x*37))*0.5+0.5;\r\n const line=(v:number,n:number,w:number)=>1-smooth(w,w*2,Math.abs(fract(v*n)-.5));\r\n let h=.5,t=.5,glow=0,rough=.8;\r\n switch(id){\r\n  case 63:{const c=voronoi(x*7,y*7),sac=1-smooth(.04,.44,c.near),ooze=.5+.5*Math.sin(x*20+Math.sin(y*14)*3);h=.32+sac*.49;t=.13+sac*.67+ooze*.12;rough=.055+sac*.045;break;}\r\n  case 64:{const c=voronoi(x*10,y*9),pustule=1-smooth(.08,.36,c.near),rim=1-smooth(.02,.08,Math.abs(c.near-.33));h=.34+pustule*.56-rim*.08;t=.1+pustule*.8;rough=.13+.24*rim;break;}\r\n  case 65:{const c=voronoi(x*11,y*11),rot=1-smooth(.02,.14,c.gap),mould=hash(Math.floor(x*57),Math.floor(y*57))>.7?1:0;h=.56-rot*.4+mould*.12;t=.12+mould*.49+(1-rot)*.22;rough=.86+mould*.13;break;}\r\n  case 66:{const c=voronoi(x*9,y*9),hole=1-smooth(.1,.22,c.near),lip=1-smooth(.045,.1,Math.abs(c.near-.25));h=.53-hole*.42+lip*.18;t=.47-hole*.45+lip*.42;rough=.22+hole*.52;break;}\r\n  case 67:{const strand=.5+.5*Math.sin(x*95+Math.sin(y*13)*5),cleft=Math.pow(1-strand,8);h=.3+strand*.43-cleft*.15;t=.15+strand*.68;rough=.13+cleft*.35;break;}\r\n  case 68:{const c=voronoi(x*6,y*6),mouth=1-smooth(.06,.26,c.near),rim=1-smooth(.02,.07,Math.abs(c.near-.28)),tooth=hash(Math.floor(x*49),Math.floor(y*49))>.76?rim:0;h=.51-mouth*.47+rim*.26;t=.3-mouth*.28+tooth*.67;rough=.16+mouth*.64;break;}\r\n  case 69:{const wire=Math.max(line(x,12,.028),line(y,12,.025)),junction=1-smooth(.025,.065,Math.hypot(fract(x*6)-.5,fract(y*6)-.5));h=.49+wire*.17+junction*.2;t=.12+wire*.68+junction*.17;glow=wire*.8+junction;rough=.22-wire*.1;break;}\r\n  case 70:{const u=fract(x*4),v=fract(y*5),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.07,edge),bolt=1-smooth(.028,.07,Math.hypot(u-.14,v-.14));h=.68-seam*.45+bolt*.25;t=.56-seam*.5+bolt*.4;rough=.32+seam*.42;break;}\r\n  case 71:{const rib=triangle(x*13),groove=1-smooth(.07,.18,rib);h=.32+.57*rib;t=.17+.78*rib;rough=.09+groove*.3;break;}\r\n  case 72:{const u=fract(x*18),v=fract(y*18),over=(Math.floor(x*18)+Math.floor(y*18))%2,thread=over?Math.sin(u*Math.PI):Math.sin(v*Math.PI);h=.44+thread*.14;t=.12+thread*.69;rough=.64+.12*(1-thread);break;}\r\n  case 73:{const stripe=fract((x+y)*7)<.5?1:0,u=fract(x*3),v=fract(y*3),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.07,edge);h=.58-seam*.34;t=.07+stripe*.74-seam*.07;rough=.41+seam*.32;break;}\r\n  case 74:{const cell=voronoi(x*7,y*7),seam=1-smooth(.02,.07,cell.gap),core=1-smooth(.04,.16,cell.near);h=.52-seam*.12;t=.23+seam*.53+core*.23;glow=seam*.7+core;rough=.04+seam*.07;break;}\r\n\r\n  case 57:{const cloud=.5+.5*Math.sin(x*12+Math.sin(y*9)*2)*Math.cos(y*11);h=.48+cloud*.07;t=.48+cloud*.4;rough=.045+cloud*.025;break;}\r\n  case 58:{const c=voronoi(x*9,y*9),bubble=1-smooth(.1,.24,c.near);h=.49+bubble*.13;t=.7+bubble*.28;rough=.025+bubble*.035;break;}\r\n  case 59:{const c=voronoi(x*8,y*8),facet=Math.floor(c.near*7)/7,crack=1-smooth(.012,.06,c.gap);h=.35+facet*.65-crack*.12;t=.3+facet*.65;rough=.035+crack*.16;break;}\r\n  case 60:{const fold=Math.sin(x*31+Math.sin(y*23)*2)*Math.cos(y*27),ribs=triangle((x+y*.4)*38);h=.5+fold*.27+ribs*.06;t=.1+.8*(.5+.5*fold);rough=.12+ribs*.13;break;}\r\n  case 61:{const fleck=hash(Math.floor(x*83),Math.floor(y*83))>.91?1:0;h=.49+fleck*.035;t=.58+fleck*.4;rough=.075-fleck*.045;break;}\r\n  case 62:{const c=voronoi(x*6,y*6),seam=1-smooth(.025,.1,c.gap),star=hash(Math.floor(x*93),Math.floor(y*93))>.989?1:0;h=.65-seam*.43;t=.06+seam*.73+star*.2;glow=seam*.55+star*.4;rough=.32-seam*.2;break;}\r\n\r\n  case 56:{const ix=Math.floor(x*16),iy=Math.floor(y*16),pixel=Math.floor(hash(ix,iy)*4)/3;h=.35+.3*pixel;t=.1+.8*pixel;rough=.5+.15*(1-pixel);break;}\r\n  case 32:{const u=fract(x*3),v=fract(y*3),edge=Math.min(u,1-u,v,1-v),seam=1-smooth(.025,.065,edge),rivet=Math.hypot(u-.5,v-.5),dot=(1-smooth(.035,.075,rivet))*((Math.floor(x*3)+Math.floor(y*3))%2===0?1:.35);h=.69-.34*seam+.28*dot;t=.69-.49*seam+.18*dot;rough=.3+.45*seam;break;}\r\n  case 33:{const d=Math.abs(fract((x+y)*6)-.5),a=Math.abs(fract((x-y)*6)-.5),ridge=Math.max(1-smooth(.045,.12,d),1-smooth(.045,.12,a)),trough=smooth(.16,.34,Math.min(d,a));h=.25+.64*ridge-.1*trough;t=.09+.82*ridge-.08*trough;rough=.99-.16*ridge;break;}\r\n  case 34:{const u=fract(x*7),v=fract(y*7),cx=Math.floor(x*7)+(Math.floor(y*7)%2)*.5+.5,cy=Math.floor(y*7)+.5,r=Math.hypot((x*7-cx)*.72,y*7-cy),ring=1-smooth(.055,.13,Math.abs(r-.31)),hole=1-smooth(.16,.25,r);h=.42+.39*ring-.15*hole;t=.3+.58*ring;rough=.58-.23*ring;void u;void v;break;}\r\n  case 35:{const chevron=triangle((x+y*.48)*9),ridge=1-smooth(.18,.31,Math.abs(chevron-.5));h=.31+.51*ridge;t=.18+.67*ridge;rough=.97-.11*ridge;break;}\r\n  case 36:{const twill=triangle((x+y)*26),cross=triangle((x-y*.12)*5);h=.46+.09*twill+.025*cross;t=.25+.56*twill;rough=.82+g*.12;break;}\r\n  case 37:{const u=fract(x*8),v=fract(y*8),hex=Math.max(Math.abs(u-.5)*.866+Math.abs(v-.5)*.5,Math.abs(v-.5)),ridge=1-smooth(.31,.43,hex);h=.28+.62*ridge;t=.14+.73*ridge;rough=.9-.17*ridge;break;}\r\n  case 38:{const c=voronoi(x*14,y*13),pile=1-smooth(.1,.54,c.near),valley=smooth(.06,.22,c.gap),fiber=Math.sin(x*83+Math.sin(y*41)*1.7)*Math.sin(y*77+Math.sin(x*37))*0.5+0.5;h=.2+.53*pile-.14*valley+.025*fiber;t=.1+.78*pile-.1*valley+.035*fiber;rough=.99;break;}\r\n  case 39:{const u=fract(x*4),v=fract(y*4),diamond=Math.abs(u-.5)+Math.abs(v-.5),seam=smooth(.39,.48,diamond),pad=1-smooth(.08,.43,diamond);h=.28+.62*pad-.21*seam;t=.14+.72*pad-.1*seam;rough=.93-.08*pad;break;}\r\n  case 40:{const d=voronoi(x*19,y*17),dimple=1-smooth(.06,.24,d.near),nap=smooth(.16,.39,d.near),fiber=Math.sin(x*91+Math.sin(y*48))*Math.sin(y*79+Math.sin(x*43));h=.46+.035*g-.14*dimple+.06*nap+.012*fiber;t=.54+.04*g-.27*dimple+.13*nap+.025*fiber;rough=.97-.025*nap;break;}\r\n  case 41:{const c=voronoi(x*11,y*11),pit=1-smooth(.03,.22,c.near),lip=1-smooth(.04,.2,c.gap);h=.55-.29*pit+.15*lip;t=.45-.31*pit+.18*lip;rough=.47-.16*lip+.28*pit;break;}\r\n  case 42:{const strand=triangle((x*8+y*1.7)*5),twist=triangle((x*8-y*1.7)*2);h=.27+.47*strand+.13*twist;t=.16+.74*strand;rough=.91-.08*strand;break;}\r\n  case 43:{const c=voronoi(x*15,y*15),crease=1-smooth(.025,.11,c.gap),grain=Math.sin(x*81+Math.sin(y*43))*Math.sin(y*75);h=.5-.16*crease+grain*.045;t=.38+.16*grain-.22*crease;rough=.72+.19*crease;break;}\r\n  case 44:{const c=voronoi(x*12,y*12),cell=smooth(.06,.37,c.near),chip=(hash(Math.floor(x*12),Math.floor(y*12))>.74?1:0)*cell;h=.34+.4*cell-.24*chip;t=.19+.62*cell-.18*chip;rough=.97;break;}\r\n  case 45:{const a=line(x+y*.12,12,.34),b=line(y-x*.08,12,.34),over=fract(x*12+y*12)<.5?a:b;h=.36+.27*a+.22*b+.12*over;t=.18+.37*a+.42*b;rough=.92-.12*over;break;}\r\n  case 46:{const u=fract(x*5)-.5,v=fract(y*5)-.5,angle=Math.atan2(v,u),r=Math.hypot(u,v),lobe=(1-smooth(.28,.49,r))*(.65+.35*Math.cos(angle*6)),vein=1-smooth(.012,.035,Math.abs(v-Math.sin(u*6)*.035));h=.33+.31*lobe+.12*vein;t=.19+.48*lobe+.22*vein;rough=.6-.17*lobe;break;}\r\n  case 47:{const vertical=line(x,22,.31),horizontal=line(y,22,.31),crossing=vertical*horizontal;h=.41+.12*vertical+.12*horizontal+.13*crossing;t=.26+.27*vertical+.27*horizontal;rough=.95-.08*crossing;break;}\r\n  case 48:{const rib=triangle(x*8),node=1-smooth(.015,.07,Math.abs(fract(y*2)-.5));h=.27+.53*(1-smooth(.28,.48,rib))+.14*node;t=.17+.67*(1-smooth(.3,.47,rib))+.12*node;rough=.68-.15*node;break;}\r\n  case 49:{const u=fract(x*6+(Math.floor(y*7)%2)*.5),v=fract(y*7),scale=Math.hypot((u-.5)*.86,v-.5),rim=1-smooth(.36,.48,scale),seam=1-smooth(.025,.09,Math.abs(v-.5));h=.28+.46*rim-.08*seam;t=.12+.74*rim-.12*seam;rough=.52-.24*rim;break;}\r\n  case 50:{const u=fract(x*14),v=fract(y*14),bar=Math.min(u,1-u,v,1-v),wire=1-smooth(.035,.105,bar),hole=1-wire;h=.26+.56*wire;t=.08+.76*wire;rough=.58-.2*wire;break;}\r\n  case 51:{const u=fract(x*18),v=fract(y*18),stagger=(Math.floor(y*18)%2)*.5,cx=fract(x*18+stagger)-.5,cy=v-.5,r=Math.hypot(cx,cy),loop=1-smooth(.035,.105,Math.abs(r-.27)),center=1-smooth(.01,.08,r);h=.44+.2*loop+.06*center;t=.34+.28*loop;rough=.99;break;}\r\n  case 52:{const c=voronoi(x*7,y*7),stone=1-smooth(.2,.52,c.near),edge=1-smooth(.035,.1,c.gap);h=.26+.49*stone-.1*edge;t=.1+.76*stone-.14*edge;rough=.87-.2*stone;break;}\r\n  case 53:{const q=y*7+Math.sin(x*17+y*4)*.35+Math.sin(x*6-y*13)*.16,ridge=1-smooth(.16,.34,Math.abs(fract(q)-.5));h=.39+.31*ridge+.025*g;t=.3+.38*ridge;rough=.99;break;}\r\n  case 54:{const c=voronoi(x*4,y*4),stone=1-smooth(.31,.75,c.near),seam=1-smooth(.045,.13,c.gap);h=.31+.43*stone-.16*seam;t=.15+.67*stone-.19*seam;rough=.79-.14*stone+.1*seam;break;}\r\n  case 55:{const c=voronoi(x*31,y*31),tuft=1-smooth(.08,.38,c.near),spore=hash(Math.floor(x*31),Math.floor(y*31))>.84?1:0;h=.37+.2*tuft+.07*spore;t=.2+.61*tuft+.12*spore;rough=.99;break;}\r\n }\r\n return{height:h,tint:clamp(t),glow,rough};\r\n}\r\n","handborne/source/app/material-refinement.ts":"import * as T from 'three';\r\nimport {mergeVertices} from 'three/examples/jsm/utils/BufferGeometryUtils.js';\r\n\r\nexport type CoachReliefBudget={remainingTriangles:number;usedTriangles:number;perMeshAddedTriangles:number;perMeshVertices:number};\r\n// Budgets count added triangles per coach, and total final positions per mesh.\r\nexport const createCoachReliefBudget=(limit=240_000,perMeshAddedTriangles=64_000,perMeshVertices=32_000):CoachReliefBudget=>({remainingTriangles:limit,usedTriangles:0,perMeshAddedTriangles,perMeshVertices});\r\nconst isFloat16=(a:{array:ArrayLike<number>;isFloat16BufferAttribute?:boolean})=>!!a.isFloat16BufferAttribute||(()=>{const Float16=(globalThis as any).Float16Array;return !!Float16&&a.array instanceof Float16;})();\r\n\r\nfunction component(a:T.BufferAttribute|T.InterleavedBufferAttribute,i:number,c:number){\r\n if(c===0)return a.getX(i);if(c===1)return a.getY(i);if(c===2)return a.getZ(i);if(c===3)return a.getW(i);\r\n return a.array[i*a.itemSize+c];\r\n}\r\nfunction write(a:T.BufferAttribute,i:number,c:number,v:number){\r\n if(c===0)a.setX(i,v);else if(c===1)a.setY(i,v);else if(c===2)a.setZ(i,v);else if(c===3)a.setW(i,v);else a.array[i*a.itemSize+c]=v;\r\n}\r\nfunction normalizeAttribute(a:T.BufferAttribute,i:number){\r\n if(a.itemSize<3)return;\r\n const x=a.getX(i),y=a.getY(i),z=a.getZ(i),length=Math.hypot(x,y,z);if(length<1e-12)return;\r\n a.setXYZ(i,x/length,y/length,z/length);\r\n}\r\n\r\n/** One linear triangle split. It preserves silhouette, UVs, authored normals and vertex attributes. */\r\nfunction split(source:T.BufferGeometry,maxVertices:number):T.BufferGeometry|undefined{\r\n const index=source.index;if(!index||index.count%3)return undefined;\r\n const edgeIds=new Map<string,number>(),edges:Array<[number,number]>=[],indices:number[]=[];\r\n const midpoint=(a:number,b:number)=>{\r\n  const lo=Math.min(a,b),hi=Math.max(a,b),key=lo+':'+hi,old=edgeIds.get(key);if(old!==undefined)return old;\r\n  const id=source.attributes.position.count+edges.length;edgeIds.set(key,id);edges.push([lo,hi]);return id;\r\n };\r\n const groups=source.groups.length?source.groups:[{start:0,count:index.count,materialIndex:0}],nextGroups:{start:number;count:number;materialIndex:number}[]=[];\r\n for(const group of groups){\r\n  const start=indices.length,end=Math.min(index.count,group.start+group.count);\r\n  for(let j=group.start;j+2<end;j+=3){const a=index.getX(j),b=index.getX(j+1),c=index.getX(j+2),ab=midpoint(a,b),bc=midpoint(b,c),ca=midpoint(c,a);\r\n   indices.push(a,ab,ca,ab,b,bc,ca,bc,c,ab,bc,ca);\r\n  }\r\n  if(indices.length>start)nextGroups.push({start,count:indices.length-start,materialIndex:group.materialIndex??0});\r\n }\r\n if(!edges.length||source.attributes.position.count+edges.length>maxVertices)return undefined;\r\n const out=source.clone();\r\n for(const [name,attribute]of Object.entries(source.attributes)){\r\n  if((attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||isFloat16(attribute))return undefined;\r\n  const count=attribute.count+edges.length,array=new (attribute.array.constructor as any)(count*attribute.itemSize);array.set(attribute.array);\r\n  const target=new T.BufferAttribute(array,attribute.itemSize,attribute.normalized);target.name=attribute.name;target.setUsage((attribute as T.BufferAttribute).usage);target.gpuType=(attribute as T.BufferAttribute).gpuType;\r\n  for(let e=0;e<edges.length;e++){const [a,b]=edges[e],dst=attribute.count+e;\r\n   for(let c=0;c<attribute.itemSize;c++)write(target,dst,c,(component(attribute,a,c)+component(attribute,b,c))*.5);\r\n   if(name==='normal'||name==='tangent')normalizeAttribute(target,dst);\r\n  }\r\n  out.setAttribute(name,target);\r\n }\r\n out.setIndex(indices);out.clearGroups();for(const group of nextGroups)out.addGroup(group.start,group.count,group.materialIndex);\r\n out.morphAttributes=source.morphAttributes;out.morphTargetsRelative=source.morphTargetsRelative;out.userData={...source.userData};\r\n return out;\r\n}\r\n\r\n/** Refine only bounded static roster geometry; unknown animated/morph geometry safely stays untouched. */\r\nexport function refineCoachGeometry(source:T.BufferGeometry,budget:CoachReliefBudget,worldScale=1):{geometry:T.BufferGeometry;addedTriangles:number;addedVertices:number;levels:number}|undefined{\r\n if(!budget||budget.remainingTriangles<=0||Object.values(source.morphAttributes).some(attributes=>attributes.length)||source.attributes.skinIndex||source.attributes.skinWeight)return undefined;\r\n if(source.drawRange.start!==0||(source.index&&source.drawRange.count<source.index.count))return undefined;\r\n for(const attribute of Object.values(source.attributes))if((attribute as T.InterleavedBufferAttribute).isInterleavedBufferAttribute||isFloat16(attribute))return undefined;\r\n let working=source.clone();\r\n if(!working.index){const merged=mergeVertices(working);working.dispose();working=merged;}\r\n if(!working.index||working.index.count%3){working.dispose();return undefined;}\r\n if(!working.attributes.normal)working.computeVertexNormals();\r\n const triangles=working.index.count/3;\r\n // Estimate a 90th-percentile edge so tiny existing triangles stay untouched while broad facets\r\n // receive enough linear splits to reach roughly .025 world units. The total remains tightly capped.\r\n if(triangles>10_000){working.dispose();return undefined;}\r\n const positions=working.attributes.position,edges:number[]=[];for(let j=0;j<working.index.count;j+=3){const a=working.index.getX(j),b=working.index.getX(j+1),c=working.index.getX(j+2);for(const [u,v]of [[a,b],[b,c],[c,a]])edges.push(Math.hypot(positions.getX(u)-positions.getX(v),positions.getY(u)-positions.getY(v),positions.getZ(u)-positions.getZ(v))*worldScale);}\r\n edges.sort((a,b)=>a-b);const p90=edges[Math.floor((edges.length-1)*.9)]??0,desired=Math.min(5,Math.max(0,Math.ceil(Math.log2(p90/.025))));\r\n if(!desired){working.dispose();return undefined;}\r\n const initial=working.attributes.position.count,initialTriangles=triangles;let levels=0;\r\n for(let level=0;level<desired;level++){\r\n  const currentTriangles=working.index!.count/3,nextTriangles=currentTriangles*4,cumulativeAdded=nextTriangles-initialTriangles;\r\n  if(cumulativeAdded>budget.remainingTriangles||cumulativeAdded>budget.perMeshAddedTriangles||nextTriangles>64_000)break;\r\n  const next=split(working,budget.perMeshVertices);if(!next)break;\r\n  working.dispose();working=next;levels++;\r\n }\r\n const addedTriangles=working.index!.count/3-initialTriangles,addedVertices=working.attributes.position.count-initial;\r\n if(!levels){working.dispose();return undefined;}\r\n budget.remainingTriangles-=addedTriangles;budget.usedTriangles+=addedTriangles;\r\n working.userData={...working.userData,coachRelief:{addedTriangles,addedVertices,levels,originalVertices:initial}};\r\n return {geometry:working,addedTriangles,addedVertices,levels};\r\n}\r\n\r\n/** Optional alternate-coach quality path for the original imported material (no recolouring). */\r\nexport function refineCoachMesh(mesh:T.Mesh,budget:CoachReliefBudget){\r\n if(Array.isArray(mesh.material)||(mesh as T.SkinnedMesh).isSkinnedMesh||mesh.geometry.attributes.skinIndex||mesh.geometry.attributes.skinWeight||Object.values(mesh.geometry.morphAttributes).some(attributes=>attributes.length))return undefined;\r\n mesh.updateWorldMatrix(true,false);const result=refineCoachGeometry(mesh.geometry,budget,mesh.matrixWorld.getMaxScaleOnAxis());if(!result)return undefined;\r\n const previous=mesh.geometry;mesh.geometry=result.geometry;if(mesh.userData.ownedGeometry)previous.dispose();mesh.userData.ownedGeometry=true;\r\n return {addedTriangles:result.addedTriangles,addedVertices:result.addedVertices,levels:result.levels};\r\n}\r\n","handborne/source/app/motion.ts":"import { POSES } from './poses.ts';\r\nexport const POSE_INTERVAL_MS=15_000;\r\nexport const nextPoseId=(id:string)=>POSES[(POSES.findIndex(p=>p.id===id)+1)%POSES.length].id;\r\nexport function specimenMotion(seconds:number){\r\n  return {position:[.0018*Math.sin(seconds*.57),.0028*Math.sin(seconds*.79),.0012*Math.sin(seconds*.43)] as [number,number,number],rotation:[.018*Math.sin(seconds*.41),.035*Math.sin(seconds*.32),.014*Math.sin(seconds*.53)] as [number,number,number]};\r\n}\r\nexport function schedulePoseCycle(advance:()=>void,schedule=globalThis.setTimeout,cancel=globalThis.clearTimeout){\r\n  let stopped=false,timer:ReturnType<typeof setTimeout>;\r\n  const tick=()=>{if(stopped)return;advance();if(!stopped)timer=schedule(tick,POSE_INTERVAL_MS);};\r\n  timer=schedule(tick,POSE_INTERVAL_MS);\r\n  return()=>{stopped=true;cancel(timer);};\r\n}\r\n","handborne/source/app/nail-shapes.json":"[\r\n  {\"id\":\"short\",\"name\":\"Short round\",\"extension\":0,\"tip\":0.73,\"taper\":1.8,\"curve\":0,\"width\":1},\r\n  {\"id\":\"square\",\"name\":\"Square\",\"extension\":0.004,\"tip\":0.98,\"taper\":3,\"curve\":0,\"width\":1.04},\r\n  {\"id\":\"almond\",\"name\":\"Almond\",\"extension\":0.006,\"tip\":0.12,\"taper\":1.65,\"curve\":0,\"width\":1},\r\n  {\"id\":\"coffin\",\"name\":\"Coffin\",\"extension\":0.01,\"tip\":0.52,\"taper\":1.4,\"curve\":0,\"width\":1.05},\r\n  {\"id\":\"stiletto\",\"name\":\"Stiletto\",\"extension\":0.014,\"tip\":0.025,\"taper\":1.15,\"curve\":0.0008,\"width\":0.95},\r\n  {\"id\":\"talon\",\"name\":\"Talon\",\"extension\":0.014,\"tip\":0.025,\"taper\":1.4,\"curve\":0.007,\"width\":1.05},\r\n  {\"id\":\"hook\",\"name\":\"Hooked claw\",\"extension\":0.01,\"tip\":0.025,\"taper\":1.6,\"curve\":0.014,\"width\":1.12},\r\n  {\"id\":\"spade\",\"name\":\"Spade\",\"extension\":0.006,\"tip\":0.06,\"taper\":3.4,\"curve\":0.001,\"width\":1.3}\r\n]\r\n","handborne/source/app/nails.ts":"import * as THREE from 'three';\r\nimport shapes from './nail-shapes.json' with {type:'json'};\r\nimport { DIGITS, type Digit } from './poses.ts';\r\nimport { REST_SOURCE, DIGIT_RADII, BABY_RIG_SCALE } from './pose-rig.ts';\r\nexport const NAIL_SHAPES=shapes;\r\nexport const DEFAULT_NAIL_SHAPE='family';\r\nexport function validateNailShape(value:unknown):string {\r\n  if(value===DEFAULT_NAIL_SHAPE||shapes.some(s=>s.id===value))return value as string;\r\n  throw new Error('Choose a valid nail shape.');\r\n}\r\nfunction curve(digit:Digit,t:number){\r\n  const points=REST_SOURCE[digit].map(([x,y,z])=>new THREE.Vector3(x,z,-y));\r\n  const u=Math.min(t*3,3-1e-8),i=Math.floor(u),a=u-i;\r\n  const p0=points[Math.max(0,i-1)],p1=points[i],p2=points[i+1],p3=points[Math.min(3,i+2)];\r\n  return p1.clone().multiplyScalar(2).addScaledVector(p0,-a+2*a*a-a*a*a).addScaledVector(p1,-5*a*a+3*a*a*a).addScaledVector(p2,a+4*a*a-3*a*a*a).addScaledVector(p3,-a*a+a*a*a).multiplyScalar(.5);\r\n}\r\nexport function nailGeometry(digit:Digit,shapeId:string,styleId:number){\r\n  const shape=shapes.find(s=>s.id===shapeId);if(!shape)throw new Error('Unknown nail shape');\r\n  const positions:number[]=[],uv:number[]=[],indices:number[]=[],rings=24,sides=20,row=sides+1,layer=(rings+1)*row;\r\n  const radius=DIGIT_RADII[DIGITS.indexOf(digit)];\r\n  for(let bottom=0;bottom<2;bottom++)for(let j=0;j<=rings;j++){\r\n    const u=j/rings,t=.78+u*.195,p=curve(digit,t),tangent=curve(digit,t+.002).sub(curve(digit,t-.002)).normalize();\r\n    const dorsal=new THREE.Vector3(0,0,1);dorsal.addScaledVector(tangent,-dorsal.dot(tangent)).normalize();\r\n    const side=tangent.clone().cross(dorsal).normalize();\r\n    const growth=Math.max(0,(u-.32)/.68),width=radius*.72*shape.width*(.8+.2*Math.sin(Math.PI*u))*(1-(1-shape.tip)*Math.pow(u,shape.taper));\r\n    p.addScaledVector(tangent,shape.extension*growth*growth).addScaledVector(dorsal,-shape.curve*Math.pow(growth,3));\r\n    for(let k=0;k<=sides;k++){\r\n      const v=k/sides*2-1;\r\n      const ridge=styleId===0?0:.00022*Math.sin(v*Math.PI*(3+styleId%5))*Math.sin(Math.PI*u);\r\n      const point=p.clone().addScaledVector(side,width*v).addScaledVector(dorsal,radius*(1-.31*t)*(.87-.18*v*v)+.00055-bottom*.0007+ridge);\r\n      positions.push(point.x,point.y,point.z);uv.push(k/sides,u);\r\n    }\r\n  }\r\n  const quad=(a:number,b:number,c:number,d:number)=>indices.push(a,b,c,a,c,d);\r\n  for(let j=0;j<rings;j++)for(let k=0;k<sides;k++){\r\n    const a=j*row+k;quad(a,a+1,a+row+1,a+row);quad(a+layer,a+row+layer,a+row+1+layer,a+1+layer);\r\n  }\r\n  for(let j=0;j<rings;j++){\r\n    const a=j*row,b=a+sides;quad(a,a+row,a+row+layer,a+layer);quad(b,b+layer,b+row+layer,b+row);\r\n  }\r\n  for(let k=0;k<sides;k++){quad(k,k+layer,k+1+layer,k+1);const a=rings*row+k;quad(a,a+1,a+1+layer,a+layer);}\r\n  const geometry=new THREE.BufferGeometry();geometry.setAttribute('position',new THREE.Float32BufferAttribute(positions,3));geometry.setAttribute('uv',new THREE.Float32BufferAttribute(uv,2));geometry.setIndex(indices);geometry.computeVertexNormals();\r\n  if(styleId===22)geometry.scale(BABY_RIG_SCALE.x,BABY_RIG_SCALE.y,BABY_RIG_SCALE.z);\r\n  return geometry;\r\n}\r\nexport function replaceNailShape(part:THREE.Object3D,shapeId:string,styleId:number){\r\n  validateNailShape(shapeId);if(shapeId===DEFAULT_NAIL_SHAPE)return;\r\n  const materials=new Map<Digit,THREE.Material|THREE.Material[]>();\r\n  part.traverse(obj=>{if(obj instanceof THREE.Mesh&&obj.userData.digit&&obj.userData.source_part?.endsWith('_claw'))materials.set(obj.userData.digit,obj.material);});\r\n  part.clear();\r\n  for(const digit of DIGITS){\r\n    const material=materials.get(digit);if(!material)throw new Error('Missing nail material for '+digit);\r\n    const mesh=new THREE.Mesh(nailGeometry(digit,shapeId,styleId),material);\r\n    mesh.name=digit+'_'+shapeId;mesh.userData={region:'nails',digit,source_part:digit+'_claw',nail_shape:shapeId,ownedGeometry:true,...(styleId===22?{rig_profile:'baby'}:{})};mesh.castShadow=true;mesh.receiveShadow=true;part.add(mesh);\r\n  }\r\n}\r\n","handborne/source/app/page.tsx":"'use client';\r\n\r\nimport { useCallback, useEffect, useRef, useState } from 'react';\r\nimport { ChevronLeft, ChevronRight, Dices, Download, RotateCcw, Undo2, Redo2, Lock, Unlock, Save, Layers3, Focus, Rotate3D, Play, Pause } from 'lucide-react';\r\nimport { Button } from '@/components/ui/button';\r\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from '@/components/ui/tabs';\r\nimport { Badge } from '@/components/ui/badge';\r\nimport { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from '@/components/ui/dialog';\r\nimport { Switch } from '@/components/ui/switch';\r\nimport { NativeSelect, NativeSelectOption } from '@/components/ui/native-select';\r\nimport { Textarea } from '@/components/ui/textarea';\r\nimport { DEFAULT_SELECTION, REGIONS, STYLES, styleFor, PICKER_STYLES, type RegionId } from './catalog';\r\nimport { parseDesign, designCode, randomize, type Selection, type HandDesign } from './recipe';\r\nimport { DEFAULT_POSE, POSES } from './poses';\r\nimport { DEFAULT_NAIL_SHAPE, NAIL_SHAPES } from './nails';\r\nimport { nextPoseId, schedulePoseCycle } from './motion';\r\nimport { registerHandTools } from './web-tools';\r\nimport { HandViewer, type HandViewerHandle } from './hand-viewer';\r\nimport {MATERIAL_NOTES} from './material-language';\r\nimport {isHandStyleUnlocked,assertHandStylesUnlocked,availableHandSections,subscribeHandUnlocks} from './material-access';\r\nimport {surfaceSwatch} from './swatches';\r\nimport { AnatomyComparison, ANATOMY_STUDIES, SOFT_STUDIES } from './anatomy-comparison';\r\nimport { HAND_SHAPES, activeHandShape, selectHandShape, type ShapeScope } from './hand-shapes';\r\nimport { SCALE_PATTERNS } from './scale-patterns';\r\n\r\ntype History = {past:HandDesign[];present:HandDesign;future:HandDesign[]};\r\nconst number = (n:number) => String(n+1).padStart(2,'0');\r\nexport default function Home() {\r\n  const [selectedRegion,setSelectedRegion]=useState<RegionId>('palm');\r\n  const [tab,setTab]=useState('look'),[scope,setScope]=useState<'hand'|'part'>('hand');\r\n  const [,setOwnershipRevision]=useState(0);\r\n  const [saved,setSaved]=useState(false),[embedded,setEmbedded]=useState(false);\r\n  const chooseRegion=(region:RegionId)=>{setSelectedRegion(region);setScope('part');setTab('look');};\r\n  const [shapeScope,setShapeScope]=useState<ShapeScope>('hand');\r\n  const [history,setHistory]=useState<History>({past:[],present:{sections:{...DEFAULT_SELECTION},pose:DEFAULT_POSE,nailShape:DEFAULT_NAIL_SHAPE},future:[]});\r\n  const [animate,setAnimate]=useState(false),[visible,setVisible]=useState(true),[cycleRevision,setCycleRevision]=useState(0);\r\n  const [locks,setLocks]=useState<RegionId[]>([]);\r\n  const [exploded,setExploded]=useState(false);\r\n  const [dialog,setDialog]=useState<'export'|'recipe'|null>(null);\r\n  const [recipeInput,setRecipeInput]=useState('');\r\n  const [message,setMessage]=useState('');\r\n  const [busy,setBusy]=useState(false);\r\n  const [restored,setRestored]=useState(false);\r\n  const [readyCode,setReadyCode]=useState('');\r\n  const [comparison,setComparison]=useState<'anatomy'|'soft'|null>(null),[gray,setGray]=useState(false);\r\n  const viewer=useRef<HandViewerHandle>(null);\r\n  const design=history.present,selection=design.sections;\r\n  const code=designCode(design);\r\n  const style=styleFor(selection[selectedRegion]);\r\n  const selectedShape=activeHandShape(selection,shapeScope,selectedRegion);\r\n  const shapeLocked=shapeScope==='hand'?locks.length===REGIONS.length:locks.includes(selectedRegion);\r\n  const current=useRef(design);current.current=design;\r\n  const restoreAfterOwnership=useRef<HandDesign|null>(null);\r\n  const pending=useRef<{code:string;resolve:()=>void;reject:(e:Error)=>void;timer:ReturnType<typeof setTimeout>}|null>(null);\r\n  const commit=useCallback((sections:Selection,nextPose?:string,nextNailShape?:string,nextScalePattern?:string)=>{\r\n    assertHandStylesUnlocked(sections);restoreAfterOwnership.current=null;\r\n    if(nextPose)setCycleRevision(v=>v+1);\r\n    setHistory(h=>{const pattern=nextScalePattern??h.present.scalePattern??'none';const next={sections,pose:nextPose??h.present.pose,nailShape:nextNailShape??h.present.nailShape,...(pattern==='none'?{}:{scalePattern:pattern})};return designCode(h.present)===designCode(next)?h:{past:[...h.past,h.present].slice(-80),present:next,future:[]};});\r\n  },[]);\r\n  const setStyle=(region:RegionId,value:number)=>commit({...selection,[region]:styleFor(value).id});\r\n  const applyAll=(id:number)=>commit(Object.fromEntries(REGIONS.map(r=>[r.id,locks.includes(r.id)?selection[r.id]:id])) as Selection);\r\n  const applyShape=(shapeId:string)=>{\r\n    const next=selectHandShape(selection,shapeId,shapeScope,selectedRegion,locks);\r\n    commit(next);setGray(false);\r\n    if(locks.length&&shapeScope==='hand')setMessage('Shape applied. Locked sections were kept.');\r\n  };\r\n  const undo=()=>setHistory(h=>h.past.length?{past:h.past.slice(0,-1),present:h.past[h.past.length-1],future:[h.present,...h.future]}:h);\r\n  const redo=()=>setHistory(h=>h.future.length?{past:[...h.past,h.present],present:h.future[0],future:h.future.slice(1)}:h);\r\n  const roll=()=>{commit(randomize(selection,locks,crypto.getRandomValues(new Uint32Array(1))[0]));setMessage(locks.length===REGIONS.length?'Unlock a section to remix.':'A fresh mix. All yours.');};\r\n  const onReady=useCallback((value:string)=>{\r\n    setReadyCode(value);\r\n    if(pending.current?.code===value){clearTimeout(pending.current.timer);pending.current.resolve();pending.current=null;}\r\n  },[]);\r\n  useEffect(()=>{\r\n    let previous=current.current;\r\n    try{const saved=localStorage.getItem('handborne-recipe-v4')??localStorage.getItem('handborne-recipe-v3')??localStorage.getItem('handborne-recipe-v2')??localStorage.getItem('handborne-recipe-v1');if(saved){previous=parseDesign(saved);restoreAfterOwnership.current=previous;previous={...previous,sections:availableHandSections(previous.sections)};setHistory({past:[],present:previous,future:[]});}}catch{}\r\n    const query=new URLSearchParams(window.location.search),study=Number(query.get('anatomy'));\r\n    const compare=query.get('compare');setComparison(compare==='anatomy'||compare==='soft'?compare:null);\r\n    if(query.has('anatomy')&&[...ANATOMY_STUDIES,...SOFT_STUDIES].some(s=>s.id===study)){\r\n      setHistory({past:[previous],present:{sections:Object.fromEntries(REGIONS.map(r=>[r.id,study])) as Selection,pose:DEFAULT_POSE,nailShape:DEFAULT_NAIL_SHAPE},future:[]});setGray(ANATOMY_STUDIES.some(s=>s.id===study));\r\n    }\r\n    setEmbedded(window.parent!==window);\r\n    const preference=window.matchMedia('(prefers-reduced-motion: reduce)');setAnimate(false);\r\n    const reduce=()=>{if(preference.matches)setAnimate(false);};preference.addEventListener('change',reduce);\r\n    const visibility=()=>setVisible(!document.hidden);visibility();document.addEventListener('visibilitychange',visibility);\r\n    setRestored(true);\r\n    return()=>{preference.removeEventListener('change',reduce);document.removeEventListener('visibilitychange',visibility);};\r\n  },[]);\r\n  useEffect(()=>subscribeHandUnlocks(()=>{setOwnershipRevision(n=>n+1);setHistory(h=>{const saved=restoreAfterOwnership.current;restoreAfterOwnership.current=null;const design=saved??h.present;return {...h,present:{...design,sections:availableHandSections(design.sections)}};});}),[]);\r\n  useEffect(()=>{if(!restored)return;try{localStorage.setItem('handborne-recipe-v4',JSON.stringify({version:4,...design}));setSaved(true);window.parent.postMessage({type:'handborne:changed'},window.location.origin);}catch{setSaved(false);setMessage('Device storage is full. Save a recipe to keep this hand.');}},[design,restored]);\r\n  useEffect(()=>{const update=(event:StorageEvent)=>{if(event.key==='handborne-recipe-v4'&&event.newValue)try{const next=parseDesign(event.newValue);next.sections=availableHandSections(next.sections);setHistory(h=>({...h,present:next}));}catch{}};window.addEventListener('storage',update);return()=>window.removeEventListener('storage',update);},[]);\r\n  useEffect(()=>{\r\n    if(!animate||!restored||!visible||dialog||busy||comparison)return;\r\n    return schedulePoseCycle(()=>{if(!pending.current)setHistory(h=>({...h,present:{...h.present,pose:nextPoseId(h.present.pose)}}));});\r\n  },[animate,restored,visible,dialog,busy,cycleRevision,comparison]);\r\n  useEffect(()=>{if(!message)return;const timer=setTimeout(()=>setMessage(''),5500);return()=>clearTimeout(timer);},[message]);\r\n  useEffect(()=>{if(comparison)return;return registerHandTools(()=>current.current,async next=>{\r\n    assertHandStylesUnlocked(next.sections);\r\n    if(designCode(current.current)===designCode(next))return;\r\n    if(pending.current){clearTimeout(pending.current.timer);pending.current.reject(new Error('Superseded by another recipe.'));}\r\n    await new Promise<void>((resolve,reject)=>{\r\n      const timer=setTimeout(()=>{pending.current=null;reject(new Error('Hand loading timed out.'));},30000);\r\n      pending.current={code:designCode(next),resolve,reject,timer};commit(next.sections,next.pose,next.nailShape,next.scalePattern??'none');\r\n    });\r\n  });},[commit,comparison]);\r\n  async function exportFile(format:'glb'|'obj'|'png') {\r\n    if(!viewer.current)return;setBusy(true);\r\n    try{await viewer.current.exportFile(format);setMessage('Download ready.');}catch(error){setMessage(error instanceof Error?error.message:'Export failed.');}finally{setBusy(false);}\r\n  }\r\n  function saveRecipe(){\r\n    const blob=new Blob([JSON.stringify({version:4,...design},null,2)],{type:'application/json'});\r\n    const url=URL.createObjectURL(blob);const a=document.createElement('a');a.href=url;a.download='handborne-recipe.json';a.click();setTimeout(()=>URL.revokeObjectURL(url),2000);\r\n    setMessage('Recipe saved.');\r\n  }\r\n  function loadRecipe(){try{const next=parseDesign(recipeInput);commit(next.sections,next.pose,next.nailShape,next.scalePattern??'none');setDialog(null);setMessage('Your hand is back.');}catch(error){setMessage(error instanceof Error?error.message:'Invalid recipe.');}}\r\n\r\n  if(comparison)return <AnatomyComparison variant={comparison} />;\r\n  return <main className={'creator-shell design-studio'+(embedded?' embedded':'')}>\r\n    <header className=\"topbar\">\r\n      <div className=\"brand-copy\"><p>{embedded?'YOUR GALA AVATAR':'MOM INC. CUSTOM SHOP'}</p><h1>HELPING HAND<sup>™</sup></h1></div>\r\n      <div className=\"top-actions\">\r\n        <Button variant=\"ghost\" size=\"icon\" aria-label=\"Undo\" disabled={!history.past.length} onClick={undo}><Undo2 /></Button>\r\n        <Button variant=\"ghost\" size=\"icon\" aria-label=\"Redo\" disabled={!history.future.length} onClick={redo}><Redo2 /></Button>\r\n        <Button variant=\"outline\" onClick={roll}><Dices /><span>Remix</span></Button>\r\n        <span className=\"save-indicator\" role=\"status\">{saved?'Saved on device':'Not saved yet'}</span>\r\n      </div>\r\n    </header>\r\n    <section className=\"creator-grid\">\r\n      <section className=\"viewport-panel\" aria-label=\"Live 3D hand preview\">\r\n        <div className=\"viewport-chrome\"><Badge className=\"live-badge\"><span className=\"live-dot\" />{readyCode===code?'LIVE PREVIEW':'UPDATING…'}</Badge></div>\r\n        <HandViewer ref={viewer} selection={selection} poseId={design.pose} nailShape={design.nailShape} scalePattern={design.scalePattern} animate={animate&&visible&&!dialog&&!busy} gray={gray} selectedRegion={selectedRegion} exploded={exploded} onSelectRegion={chooseRegion} onReady={onReady} />\r\n        <div className=\"view-tools\">\r\n          <Button variant=\"outline\" aria-label={animate?'Pause animation':'Play animation'} title={animate?'Pause animation':'Play animation'} size=\"icon\" onClick={()=>setAnimate(v=>!v)}>{animate?<Pause />:<Play />}</Button>\r\n          <Button variant=\"outline\" aria-label=\"Reset camera\" title=\"Reset camera\" size=\"icon\" onClick={()=>viewer.current?.resetView()}><Focus /></Button>\r\n          <Button variant=\"outline\" aria-label=\"View other side\" title=\"View other side\" size=\"icon\" onClick={()=>viewer.current?.flipView()}><Rotate3D /></Button>\r\n          <label className=\"explode-control\">Parts<Switch aria-label=\"Separate hand parts\" checked={exploded} onCheckedChange={setExploded} /></label>\r\n        </div>\r\n        <p className=\"orbit-hint\">Drag to turn · Tap a part to edit</p>\r\n      </section>\r\n      <aside className=\"design-controls\" aria-label=\"Hand design controls\">\r\n        <Tabs value={tab} onValueChange={value=>setTab(String(value))} className=\"design-tabs\">\r\n          <TabsList aria-label=\"Customize your hand\">{[['look','Look'],['shape','Shape'],['details','Details'],['motion','Motion'],['files','Save']].map(([id,label])=><TabsTrigger key={id} value={id}>{label}</TabsTrigger>)}</TabsList>\r\n          <div className=\"control-scroll\">\r\n            <TabsContent value=\"look\">\r\n              <div className=\"design-heading\"><h2>Choose a look</h2><p>{MATERIAL_NOTES[style.id]??style.name}</p></div>\r\n              <div className=\"scope-switch\"><Button variant=\"outline\" aria-pressed={scope==='hand'} onClick={()=>setScope('hand')}>Whole hand</Button><Button variant=\"outline\" aria-pressed={scope==='part'} onClick={()=>setScope('part')}>One part</Button></div>\r\n              {scope==='part'&&<div className=\"part-target\"><label htmlFor=\"part-target\">Part<NativeSelect id=\"part-target\" value={selectedRegion} onChange={e=>setSelectedRegion(e.target.value as RegionId)}>{REGIONS.map(r=><NativeSelectOption key={r.id} value={r.id}>{r.label}</NativeSelectOption>)}</NativeSelect></label><Button variant=\"outline\" size=\"icon\" aria-label={(locks.includes(selectedRegion)?'Unlock ':'Lock ')+REGIONS.find(r=>r.id===selectedRegion)?.label} aria-pressed={locks.includes(selectedRegion)} onClick={()=>setLocks(list=>list.includes(selectedRegion)?list.filter(id=>id!==selectedRegion):[...list,selectedRegion])}>{locks.includes(selectedRegion)?<Lock />:<Unlock />}</Button></div>}\r\n              <div className=\"style-grid\" aria-label=\"Creature families\">{PICKER_STYLES.map(item=><button key={item.id} aria-label={item.name+(isHandStyleUnlocked(item.id)?'':' - Locked')} title={isHandStyleUnlocked(item.id)?item.name:'Earn this texture and color in Coach packs'} disabled={!isHandStyleUnlocked(item.id)||(scope==='part'?locks.includes(selectedRegion):locks.length===REGIONS.length)} aria-pressed={scope==='hand'?Object.values(selection).every(id=>id===item.id):style.id===item.id} className={(scope==='hand'?Object.values(selection).every(id=>id===item.id):style.id===item.id)?'is-active':''} onClick={()=>scope==='hand'?applyAll(item.id):setStyle(selectedRegion,item.id)}><img src={surfaceSwatch(item.id,item.primary,item.secondary,item.accent)} alt=\"\" loading=\"lazy\" /><span className=\"tile-label\">{!isHandStyleUnlocked(item.id)&&<Lock size={12} aria-hidden=\"true\" />}{item.name}</span></button>)}</div>\r\n              <p className=\"control-note\">New horror and robotic looks unlock through texture and color packs in <a href=\"https://myr5.mominc.online\" target=\"_blank\" rel=\"noopener\">Coach</a>. Return here after earning both.</p>\r\n              {!!locks.length&&<p className=\"control-note\">{locks.length} locked {locks.length===1?'part stays':'parts stay'} when you remix or change the whole hand. <button onClick={()=>setLocks([])}>Unlock all</button></p>}\r\n            </TabsContent>\r\n            <TabsContent value=\"shape\">\r\n              <div className=\"design-heading\"><h2>Hand shape</h2><p>Shape presets include their creature look.</p></div>\r\n              <label className=\"shape-target\" htmlFor=\"shape-target\">Apply to<NativeSelect id=\"shape-target\" value={shapeScope} onChange={e=>setShapeScope(e.target.value as ShapeScope)}><NativeSelectOption value=\"hand\">Whole hand</NativeSelectOption><NativeSelectOption value=\"section\">{REGIONS.find(r=>r.id===selectedRegion)?.label}</NativeSelectOption></NativeSelect></label>\r\n              <div className=\"hand-shape-buttons\">{HAND_SHAPES.map(shape=><Button key={shape.id} variant=\"outline\" aria-pressed={selectedShape===shape.id} disabled={shapeLocked} onClick={()=>applyShape(shape.id)}>{shape.name}</Button>)}</div>\r\n              <label className=\"gray-control\">Plain gray preview<Switch checked={gray} onCheckedChange={setGray} aria-label=\"Show shape without textures\" /></label>\r\n            </TabsContent>\r\n            <TabsContent value=\"details\">\r\n              <div className=\"design-heading\"><h2>Nails & scales</h2><p>Change the small details of your hand.</p></div>\r\n              <fieldset className=\"nail-shop\"><legend>Nail shape</legend><div className=\"nail-shapes\">{[{id:DEFAULT_NAIL_SHAPE,name:'Creature default'},...NAIL_SHAPES].map(shape=><button key={shape.id} aria-pressed={design.nailShape===shape.id} onClick={()=>commit(selection,undefined,shape.id)}>{shape.name}</button>)}</div></fieldset>\r\n              <fieldset className=\"scale-shop\"><legend>Raised scales</legend><div className=\"scale-buttons\">{SCALE_PATTERNS.map(pattern=><Button key={pattern.id} variant=\"outline\" aria-pressed={(design.scalePattern??'none')===pattern.id} onClick={()=>commit(selection,undefined,undefined,pattern.id)}><span className={'scale-icon scale-'+pattern.id} aria-hidden=\"true\" />{pattern.name}</Button>)}</div></fieldset>\r\n            </TabsContent>\r\n            <TabsContent value=\"motion\">\r\n              <div className=\"design-heading\"><h2>Try a gesture</h2><p>Hold a pose while you edit, or play the collection.</p></div>\r\n              <label className=\"gray-control\">Play gestures<Switch checked={animate} onCheckedChange={setAnimate} aria-label=\"Play gestures\" /></label>\r\n              <div className=\"pose-grid\">{POSES.map(pose=><Button key={pose.id} variant=\"outline\" aria-pressed={design.pose===pose.id} onClick={()=>{setAnimate(false);commit(selection,pose.id);}}>{pose.name}</Button>)}</div>\r\n            </TabsContent>\r\n            <TabsContent value=\"files\">\r\n              <div className=\"design-heading\"><h2>Keep your hand</h2><p>Edits save on this device. Take a recipe to another device.</p></div>\r\n              <div className=\"file-actions\"><Button onClick={()=>{setRecipeInput(code);setDialog('recipe');}}><Save />Save or load recipe</Button><Button variant=\"outline\" onClick={()=>setDialog('export')}><Download />Export hand</Button><Button variant=\"outline\" onClick={()=>{commit({...DEFAULT_SELECTION},DEFAULT_POSE,DEFAULT_NAIL_SHAPE,'none');setLocks([]);setExploded(false);setMessage('Starter hand restored. Undo brings your design back.');}}><RotateCcw />Reset hand</Button></div>\r\n            </TabsContent>\r\n          </div>\r\n        </Tabs>\r\n      </aside>\r\n    </section>\r\n\r\n    <Dialog open={dialog!==null} onOpenChange={open=>{if(!open)setDialog(null);}}>\r\n      <DialogContent className=\"creator-dialog\">\r\n        <DialogHeader><DialogTitle>{dialog==='export'?'Export your creature':'Save or load a recipe'}</DialogTitle>\r\n          <DialogDescription>{dialog==='export'?'Take home this hand, just as it is. Or collect the complete creature library.':'Your recipe keeps all six parts, nail shape, scale texture and hand position. Saved on this device; older recipes still work.'}</DialogDescription></DialogHeader>\r\n        {dialog==='export'?<div className=\"export-options\">\r\n          <Button disabled={busy||readyCode!==code} onClick={()=>exportFile('glb')}><Download /> Download hand · GLB</Button>\r\n          <Button variant=\"outline\" disabled={busy||readyCode!==code} onClick={()=>exportFile('obj')}><Download /> Download hand · OBJ + MTL</Button>\r\n          <Button variant=\"outline\" disabled={busy||readyCode!==code} onClick={()=>exportFile('png')}>Save preview · PNG</Button>\r\n          <a className=\"library-download\" href=\"https://mominc.online/handborne/downloads/handborne-sections.zip\" download>Download original sections · OBJ + MTL</a>\r\n          <a className=\"library-download\" href=\"https://mominc.online/handborne/downloads/handborne-complete-hands.zip\" download>Download original complete hands · GLB</a>\r\n          <p className=\"export-note\">Download hand includes your chosen scales and nails. The complete library contains the original base families. GLB includes detailed textures. GLB and OBJ bake the selected pose into the mesh; they do not include an animation skeleton. Curved section joins remain open surfaces, not a print-ready union.</p>\r\n        </div>:<div className=\"recipe-editor\">\r\n          <label htmlFor=\"recipe-text\">Recipe code or JSON</label>\r\n          <Textarea id=\"recipe-text\" value={recipeInput} onChange={e=>setRecipeInput(e.target.value)} rows={4} />\r\n          <Button onClick={loadRecipe}>Load recipe</Button>\r\n          <Button variant=\"outline\" onClick={saveRecipe}>Download current recipe</Button>\r\n          <Button variant=\"ghost\" onClick={async()=>{try{await navigator.clipboard.writeText(code);setMessage('Recipe code copied.');}catch{setRecipeInput(code);setMessage('Select and copy the code from the field.');}}}>Copy current code</Button>\r\n        </div>}\r\n      </DialogContent>\r\n    </Dialog>\r\n    {message&&<div className=\"feedback-toast\" role=\"status\">{message}</div>}\r\n  </main>;\r\n}\r\n","handborne/source/app/palette-finishes.ts":"import * as THREE from 'three';\r\nimport palettesData from './palettes.json';\r\n\r\nexport type FinishKind =\r\n  | 'matte' | 'brushed-metal' | 'polished-metal' | 'glitter'\r\n  | 'pearl' | 'watercolor' | 'marbled' | 'glaze';\r\n\r\nexport const FINISH_ID: Record<FinishKind, number> = {\r\n  matte: 0,\r\n  'brushed-metal': 1,\r\n  'polished-metal': 2,\r\n  glitter: 3,\r\n  pearl: 4,\r\n  watercolor: 6,\r\n  marbled: 7,\r\n  glaze: 8,\r\n};\r\n\r\nconst KINDS = new Set<string>(Object.keys(FINISH_ID));\r\ntype PaletteMeta = { id: string; finish?: unknown; colors: string[] };\r\nconst CATALOG = new Map<string, PaletteMeta>(palettesData.map(p => [p.id,p]));\r\n\r\nfunction meta(id?: string): (PaletteMeta & { finish: FinishKind }) | undefined {\r\n  if (!id) return undefined;\r\n  const p = CATALOG.get(id);\r\n  return p && typeof p.finish === 'string' && KINDS.has(p.finish) ? p as PaletteMeta & {finish: FinishKind} : undefined;\r\n}\r\n\r\nexport function paletteFinish(paletteId?: string): FinishKind | undefined {\r\n  return meta(paletteId)?.finish;\r\n}\r\nexport function isCatalogPalette(paletteId?: string): boolean {\r\n  return !!meta(paletteId);\r\n}\r\n\r\nexport const FINISH_LABELS: Record<FinishKind, string> = {\r\n  matte: 'Matte', 'brushed-metal': 'Brushed metal', 'polished-metal': 'Polished metal',\r\n  glitter: 'Glitter', pearl: 'Pearl', watercolor: 'Watercolor', marbled: 'Marbled', glaze: 'Glaze',\r\n};\r\nexport function finishLabel(id?: string): string {\r\n  const f = paletteFinish(id);\r\n  return f ? FINISH_LABELS[f] : '';\r\n}\r\n\r\nexport function finishSwatchCSS(id?: string): string {\r\n  const p = meta(id); if (!p) return '';\r\n  const [a,b,c] = p.colors;\r\n  switch (p.finish) {\r\n    case 'matte': return '';\r\n    case 'brushed-metal': return `repeating-linear-gradient(100deg,${a} 0 2px,${b} 2px 3px,${c} 3px 5px)`;\r\n    case 'polished-metal': return `linear-gradient(115deg,${a},${c} 38%,#fff 50%,${b} 64%,${a})`;\r\n    case 'glitter': return `radial-gradient(circle at 22% 28%,#fff 0 2%,transparent 3%),radial-gradient(circle at 68% 62%,${c} 0 2%,transparent 3%),linear-gradient(135deg,${a},${b})`;\r\n    case 'pearl': return `linear-gradient(120deg,${a},#fff 36%,${b} 58%,${c})`;\r\n    case 'watercolor': return `radial-gradient(circle at 28% 34%,${a} 0 28%,transparent 55%),radial-gradient(circle at 72% 66%,${c} 0 24%,transparent 58%),linear-gradient(${b},${b})`;\r\n    case 'marbled': return `repeating-linear-gradient(128deg,${a} 0 9px,${b} 10px 17px,${c} 18px 23px)`;\r\n    case 'glaze': return `linear-gradient(160deg,rgba(255,255,255,.72),transparent 34%),linear-gradient(135deg,${a},${b},${c})`;\r\n  }\r\n}\r\n\r\nconst TAU = Math.PI * 2;\r\nconst wrap = (x: number) => x - Math.floor(x);\r\nfunction flatField(u: number, v: number): number {\r\n  u = wrap(u); v = wrap(v);\r\n  const s = 0.5 + 0.5 * Math.sin(TAU * u + 0.9 * Math.sin(TAU * v))\r\n    * Math.cos(TAU * v - 0.7 * Math.sin(TAU * u));\r\n  return wrap(s + 0.22 * Math.sin(TAU * (u - v)));\r\n}\r\nexport function samplePaletteTint(paletteId: string | undefined, tint: number, u: number, v: number, flat = false): number {\r\n  const f = paletteFinish(paletteId);\r\n  if (!f) return tint;\r\n  let t = THREE.MathUtils.clamp(tint, 0, 1);\r\n  u = wrap(u); v = wrap(v);\r\n  if (flat && f !== 'watercolor' && f !== 'marbled') return THREE.MathUtils.clamp(0.72 * flatField(u, v) + 0.28 * t, 0, 1);\r\n  if (f === 'watercolor') {\r\n    const bloom = 0.5 + 0.32 * Math.sin(TAU * u + 1.7 * Math.sin(TAU * v)) + 0.18 * Math.sin(TAU * (2 * u + v) + 0.6);\r\n    const grain = 0.03 * Math.sin(TAU * (9 * u + 5 * v));\r\n    return THREE.MathUtils.clamp(0.84 * bloom + 0.16 * t + grain, 0, 1);\r\n  }\r\n  if (f === 'marbled') {\r\n    const swirl = 0.5 + 0.48 * Math.sin(TAU * (u + 0.35 * Math.sin(TAU * (v + 0.5 * u))) + TAU * v);\r\n    return THREE.MathUtils.clamp(0.86 * swirl + 0.14 * t, 0, 1);\r\n  }\r\n  return t;\r\n}\r\n\r\nexport const FINISH_TINT_GLSL = `\r\nfloat myr5FlatPaletteTint(vec2 uv) {\r\n  uv = fract(uv);\r\n  float s = 0.5 + 0.5 * sin(6.2831853 * uv.x + 0.9 * sin(6.2831853 * uv.y))\r\n    * cos(6.2831853 * uv.y - 0.7 * sin(6.2831853 * uv.x));\r\n  return clamp(0.72 * fract(s + 0.22 * sin(6.2831853 * (uv.x - uv.y))) + 0.14, 0.0, 1.0);\r\n}\r\nfloat myr5FinishTint(float finish, float t, vec2 uv) {\r\n  t = clamp(t, 0.0, 1.0); uv = fract(uv);\r\n  if (finish == 6.0) {\r\n    float bloom = 0.5 + 0.32 * sin(6.2831853 * uv.x + 1.7 * sin(6.2831853 * uv.y))\r\n      + 0.18 * sin(6.2831853 * (2.0 * uv.x + uv.y) + 0.6);\r\n    float grain = 0.03 * sin(6.2831853 * (9.0 * uv.x + 5.0 * uv.y));\r\n    return clamp(0.84 * bloom + 0.16 * t + grain, 0.0, 1.0);\r\n  }\r\n  if (finish == 7.0) {\r\n    float swirl = 0.5 + 0.48 * sin(6.2831853 * (uv.x + 0.35 * sin(6.2831853 * (uv.y + 0.5 * uv.x))) + 6.2831853 * uv.y);\r\n    return clamp(0.86 * swirl + 0.14 * t, 0.0, 1.0);\r\n  }\r\n  return t;\r\n}\r\n`;\r\n\r\ntype Hooked = MeshPhysicalMaterialWithHooks;\r\ntype MeshPhysicalMaterialWithHooks = THREE.MeshPhysicalMaterial & {\r\n  userData: Record<string, any>;\r\n  defines?: Record<string,string>;\r\n};\r\n\r\nfunction addHook(mat: Hooked, kind: 'glitter' | 'brushed-metal'): void {\r\n  mat.userData.__myr5FinishHooks ||= {};\r\n  const hooks = mat.userData.__myr5FinishHooks as Record<string, boolean>;\r\n  if (hooks[kind]) return;\r\n  hooks[kind] = true;\r\n  if (kind === 'glitter') mat.userData.myr5FinishGlitter = true;\r\n  mat.defines={...mat.defines,USE_UV:''};\r\n  const prev = mat.onBeforeCompile?.bind(mat);\r\n  const vary = kind === 'glitter' ? 'vMyr5GlitterUv' : 'vMyr5BrushedUv';\r\n  mat.onBeforeCompile = (shader, renderer) => {\r\n    prev?.(shader, renderer);\r\n    shader.vertexShader = shader.vertexShader\r\n      .replace('#include <common>', `#include <common>\\nvarying vec2 ${vary};`)\r\n      .replace('#include <uv_vertex>', `#include <uv_vertex>\\n${vary} = uv;`);\r\n    shader.fragmentShader = shader.fragmentShader.replace(\r\n      '#include <common>',\r\n      `#include <common>\\nvarying vec2 ${vary};`\r\n    );\r\n    if (kind === 'glitter') {\r\n      shader.fragmentShader = shader.fragmentShader.replace(\r\n        '#include <roughnessmap_fragment>',\r\n        `#include <roughnessmap_fragment>\r\n        {\r\n          vec2 gu = fract(${vary} * 83.0);\r\n          float g = fract(sin(dot(floor(${vary} * 83.0), vec2(12.9898, 78.233))) * 43758.5453);\r\n          float speck = step(0.92, g) * step(0.5, smoothstep(0.0, 0.08, min(gu.x, gu.y)));\r\n          roughnessFactor = mix(roughnessFactor,0.055,speck);\r\n        }`\r\n      );\r\n      shader.fragmentShader = shader.fragmentShader.replace('#include <dithering_fragment>', `{\r\n        float grain=fract(sin(dot(floor(vMyr5GlitterUv*83.0),vec2(12.9898,78.233)))*43758.5453);\r\n        vec3 flakeNormal=normalize(normal+vec3(sin(grain*91.0),cos(grain*73.0),0.0)*0.55);\r\n        float glint=step(0.92,grain)*pow(max(dot(flakeNormal,normalize(vViewPosition)),0.0),42.0);\r\n        gl_FragColor.rgb+=glint*1.8;\r\n      }\\n#include <dithering_fragment>`);\r\n    } else {\r\n      shader.fragmentShader = shader.fragmentShader.replace(\r\n        '#include <roughnessmap_fragment>',\r\n        `#include <roughnessmap_fragment>\r\n        roughnessFactor = clamp(roughnessFactor + 0.055 * sin(6.2831853 * (fract(${vary}.y) * 90.0 + 0.15 * sin(6.2831853 * ${vary}.x))), 0.05, 1.0);`\r\n      );\r\n    }\r\n  };\r\n  const prevKey = mat.customProgramCacheKey?.bind(mat);\r\n  mat.customProgramCacheKey = function () {\r\n    return `${prevKey ? prevKey.call(this) : ''}|myr5-${kind}`;\r\n  };\r\n  mat.needsUpdate = true;\r\n}\r\n\r\nexport function applyPaletteFinish(\r\n  mat: THREE.MeshPhysicalMaterial,\r\n  paletteId?: string,\r\n  palette?: { primary: string; secondary: string; accent: string },\r\n): void {\r\n  const p = meta(paletteId);\r\n  if (!p) return;\r\n  const f = p.finish;\r\n  mat.roughnessMap = null;\r\n  mat.clearcoat = 0; mat.clearcoatRoughness = 0;\r\n  mat.sheen = 0; (mat as any).sheenRoughness = 1; (mat as any).sheenColor?.set?.(0x000000);\r\n  mat.iridescence = 0; mat.iridescenceIOR = 1.3; mat.iridescenceThicknessRange = [100, 400];\r\n  (mat as any).anisotropy = 0;\r\n  mat.transmission = 0; mat.thickness = 0; mat.ior = 1.5;\r\n  switch (f) {\r\n    case 'matte': mat.roughness = 0.92; mat.metalness = 0; break;\r\n    case 'brushed-metal': mat.roughness = 0.44; mat.metalness = 0.82; (mat as any).anisotropy = 0.65; break;\r\n    case 'polished-metal': mat.roughness = 0.16; mat.metalness = 0.92; break;\r\n    case 'glitter': mat.roughness = 0.24; mat.metalness = 0.35; mat.clearcoat=1; mat.clearcoatRoughness=.035; mat.envMapIntensity=1.5; break;\r\n    case 'pearl':\r\n      mat.roughness = 0.3; mat.metalness = 0.08; mat.iridescence = 1;\r\n      mat.iridescenceIOR = 1.35; mat.iridescenceThicknessRange = [120, 420]; break;\r\n    case 'watercolor': mat.roughness = 0.96; mat.metalness = 0; break;\r\n    case 'marbled': mat.roughness = 0.35; mat.metalness = 0.05; break;\r\n    case 'glaze': mat.roughness = 0.24; mat.metalness = 0; mat.clearcoat = 1; mat.clearcoatRoughness = 0.08; break;\r\n  }\r\n  if (f === 'glitter') addHook(mat as Hooked, 'glitter');\r\n  if (f === 'brushed-metal') addHook(mat as Hooked, 'brushed-metal');\r\n  mat.needsUpdate = true;\r\n}\r\n","handborne/source/app/palettes.json":"[\r\n  {\r\n    \"id\": \"pal-01\",\r\n    \"name\": \"Acid Forge\",\r\n    \"tagline\": \"Lime bites oxblood and chrome\",\r\n    \"colors\": [\r\n      \"#C6FF00\",\r\n      \"#4A0E17\",\r\n      \"#C0C7CE\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 5,\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-02\",\r\n    \"name\": \"Neon Afterburn Haze\",\r\n    \"tagline\": \"Orange aqua contrails with violet flare\",\r\n    \"colors\": [\r\n      \"#FF6D00\",\r\n      \"#00E0B0\",\r\n      \"#C800FF\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 10,\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-03\",\r\n    \"name\": \"Petrel Copper\",\r\n    \"tagline\": \"Petrol depths meet intense violet\",\r\n    \"colors\": [\r\n      \"#0E5A61\",\r\n      \"#B87333\",\r\n      \"#6913E7\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 15,\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-04\",\r\n    \"name\": \"Vinaigrette Rust\",\r\n    \"tagline\": \"Oil pigment rust swirl\",\r\n    \"colors\": [\r\n      \"#8A3B12\",\r\n      \"#556B2F\",\r\n      \"#E7A213\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 20,\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-05\",\r\n    \"name\": \"Neon Relic\",\r\n    \"tagline\": \"Hot magenta neon amber on bone\",\r\n    \"colors\": [\r\n      \"#FF009F\",\r\n      \"#FFB500\",\r\n      \"#F2EFE6\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 25,\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-06\",\r\n    \"name\": \"Glacier Ember\",\r\n    \"tagline\": \"Ice teal over ember red\",\r\n    \"colors\": [\r\n      \"#13E7D1\",\r\n      \"#D9381E\",\r\n      \"#2B2530\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 30,\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-07\",\r\n    \"name\": \"Chartreuse Storm\",\r\n    \"tagline\": \"Sludge green meets slate violet\",\r\n    \"colors\": [\r\n      \"#B5C700\",\r\n      \"#3D3654\",\r\n      \"#E85D75\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 35,\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-08\",\r\n    \"name\": \"Saffron Voltage\",\r\n    \"tagline\": \"Saffron arcs on ink blue\",\r\n    \"colors\": [\r\n      \"#FFB000\",\r\n      \"#101D42\",\r\n      \"#00FAA6\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 40,\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-09\",\r\n    \"name\": \"Neon Venom Signal\",\r\n    \"tagline\": \"Poison lime warning under arterial red\",\r\n    \"colors\": [\r\n      \"#A6FF00\",\r\n      \"#FF2442\",\r\n      \"#101828\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 45,\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-10\",\r\n    \"name\": \"Mercury Moss\",\r\n    \"tagline\": \"Silver moss over saturated gold\",\r\n    \"colors\": [\r\n      \"#AEB6BC\",\r\n      \"#5C6B3C\",\r\n      \"#E7A913\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 50,\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-11\",\r\n    \"name\": \"Ultraviolet Tar\",\r\n    \"tagline\": \"Violet glow on tar black\",\r\n    \"colors\": [\r\n      \"#7B2FF7\",\r\n      \"#141414\",\r\n      \"#FFC93C\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 55,\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-12\",\r\n    \"name\": \"Salmon Circuit\",\r\n    \"tagline\": \"Salmon pink on circuit green\",\r\n    \"colors\": [\r\n      \"#FA2200\",\r\n      \"#00A86B\",\r\n      \"#2E2A5C\"\r\n    ],\r\n    \"unlockRule\": \"aura-milestone\",\r\n    \"unlockAtDay\": 60,\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-13\",\r\n    \"name\": \"Muddy Pop\",\r\n    \"tagline\": \"Ochre mud sparks cerulean\",\r\n    \"colors\": [\r\n      \"#8C6A2F\",\r\n      \"#0081C8\",\r\n      \"#E71362\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-14\",\r\n    \"name\": \"Neon Vapor Crown\",\r\n    \"tagline\": \"Laser pink blue over dark purple\",\r\n    \"colors\": [\r\n      \"#FF00AA\",\r\n      \"#00D0FF\",\r\n      \"#1B0033\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-15\",\r\n    \"name\": \"Brick Vein\",\r\n    \"tagline\": \"Brick red veined in steel\",\r\n    \"colors\": [\r\n      \"#A0342B\",\r\n      \"#8C9BA5\",\r\n      \"#D7E713\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-2:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-16\",\r\n    \"name\": \"Peacock Static\",\r\n    \"tagline\": \"Peacock green hums gold\",\r\n    \"colors\": [\r\n      \"#046A5B\",\r\n      \"#FAAF00\",\r\n      \"#5B1E4B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-17\",\r\n    \"name\": \"Foghorn Flame\",\r\n    \"tagline\": \"Fog gray with fire-orange siren\",\r\n    \"colors\": [\r\n      \"#B8C0C2\",\r\n      \"#FA3F00\",\r\n      \"#123C69\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-18\",\r\n    \"name\": \"Toxic Honey\",\r\n    \"tagline\": \"Honey drips on toxic lime\",\r\n    \"colors\": [\r\n      \"#D9A404\",\r\n      \"#9BF00B\",\r\n      \"#4A154B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-3:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-19\",\r\n    \"name\": \"Neon Crimson Mirage\",\r\n    \"tagline\": \"Scarlet toxic lime over deep jade\",\r\n    \"colors\": [\r\n      \"#FF1744\",\r\n      \"#76FF03\",\r\n      \"#005E3C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-20\",\r\n    \"name\": \"Opal Drain\",\r\n    \"tagline\": \"Opal sheen on drainpipe green\",\r\n    \"colors\": [\r\n      \"#13E7B9\",\r\n      \"#3E5641\",\r\n      \"#D1495B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-21\",\r\n    \"name\": \"Rust Halo\",\r\n    \"tagline\": \"Rust ringed by mint flash\",\r\n    \"colors\": [\r\n      \"#9C4221\",\r\n      \"#12E898\",\r\n      \"#2C2C54\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-22\",\r\n    \"name\": \"Volt Quartz\",\r\n    \"tagline\": \"Electric yellow on rose quartz\",\r\n    \"colors\": [\r\n      \"#F5E900\",\r\n      \"#E71363\",\r\n      \"#264653\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-23\",\r\n    \"name\": \"Neon Flare Garden\",\r\n    \"tagline\": \"Laser lime pink on teal steel\",\r\n    \"colors\": [\r\n      \"#8CFF00\",\r\n      \"#FF006E\",\r\n      \"#00B8A9\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-24\",\r\n    \"name\": \"Crimson Tidebreak\",\r\n    \"tagline\": \"Crimson breaks on seafoam\",\r\n    \"colors\": [\r\n      \"#B91338\",\r\n      \"#13E7B5\",\r\n      \"#2A1E5C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-5:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-25\",\r\n    \"name\": \"Brass Mirage\",\r\n    \"tagline\": \"Brass shimmer dusky plum\",\r\n    \"colors\": [\r\n      \"#C59B42\",\r\n      \"#5A2A52\",\r\n      \"#0D94ED\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-26\",\r\n    \"name\": \"Neon Infrared Bloom\",\r\n    \"tagline\": \"Red heat sliced by frozen cyan\",\r\n    \"colors\": [\r\n      \"#FF0000\",\r\n      \"#00F5FF\",\r\n      \"#5B00B5\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-27\",\r\n    \"name\": \"Ice Magma\",\r\n    \"tagline\": \"Pigmented ice over magma orange\",\r\n    \"colors\": [\r\n      \"#D6F0F0\",\r\n      \"#F45B0F\",\r\n      \"#3D2C8D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"strider-6:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-28\",\r\n    \"name\": \"Fern Radio\",\r\n    \"tagline\": \"Fern green static magenta\",\r\n    \"colors\": [\r\n      \"#3F7A3A\",\r\n      \"#E4007C\",\r\n      \"#E7BE13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-29\",\r\n    \"name\": \"Porcelain Fuel\",\r\n    \"tagline\": \"Porcelain white fuel orange\",\r\n    \"colors\": [\r\n      \"#F2F2F0\",\r\n      \"#FF7A1A\",\r\n      \"#14507A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-30\",\r\n    \"name\": \"Neon Photon Alley\",\r\n    \"tagline\": \"Yellow signage aqua and violet glass\",\r\n    \"colors\": [\r\n      \"#FFD300\",\r\n      \"#00FFCC\",\r\n      \"#7A00FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-2:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-31\",\r\n    \"name\": \"Neon Solar Flare\",\r\n    \"tagline\": \"Hot yellow ember in plum space\",\r\n    \"colors\": [\r\n      \"#FFEA00\",\r\n      \"#FF3D00\",\r\n      \"#26142B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-32\",\r\n    \"name\": \"Wet Cement Rose\",\r\n    \"tagline\": \"Cement gray wild rose\",\r\n    \"colors\": [\r\n      \"#8D9096\",\r\n      \"#D84A87\",\r\n      \"#F0E130\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-33\",\r\n    \"name\": \"Neon Laser Tropics\",\r\n    \"tagline\": \"Chartreuse beams with scorched orange shadows\",\r\n    \"colors\": [\r\n      \"#C6FF00\",\r\n      \"#FF4D00\",\r\n      \"#001219\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-3:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-34\",\r\n    \"name\": \"Copper Fog\",\r\n    \"tagline\": \"Copper glows through fog\",\r\n    \"colors\": [\r\n      \"#B46A30\",\r\n      \"#C4CBCE\",\r\n      \"#B600F5\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L1\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-35\",\r\n    \"name\": \"Laser Moss\",\r\n    \"tagline\": \"Laser cyan on moss\",\r\n    \"colors\": [\r\n      \"#00E5FF\",\r\n      \"#546B2F\",\r\n      \"#FF4FA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L3\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-36\",\r\n    \"name\": \"Bone Ember\",\r\n    \"tagline\": \"Bone white ember orange\",\r\n    \"colors\": [\r\n      \"#EDE8DC\",\r\n      \"#E4572E\",\r\n      \"#BA00FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-4:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-37\",\r\n    \"name\": \"Plum Static\",\r\n    \"tagline\": \"Plum noise with electric lime\",\r\n    \"colors\": [\r\n      \"#4A1E4F\",\r\n      \"#B8F000\",\r\n      \"#33B5C7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-38\",\r\n    \"name\": \"Neon Lime Vortex\",\r\n    \"tagline\": \"Acid green swirling through electric blue\",\r\n    \"colors\": [\r\n      \"#BFFF00\",\r\n      \"#00E5FF\",\r\n      \"#12100F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-39\",\r\n    \"name\": \"Clay Command\",\r\n    \"tagline\": \"Terracotta clay cobalt order\",\r\n    \"colors\": [\r\n      \"#C06B55\",\r\n      \"#2E4BC6\",\r\n      \"#EDE6D6\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"ringer-5:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-40\",\r\n    \"name\": \"Static Cream\",\r\n    \"tagline\": \"Cream noise shock green\",\r\n    \"colors\": [\r\n      \"#F4EDDE\",\r\n      \"#39FF14\",\r\n      \"#4A306D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-41\",\r\n    \"name\": \"Midnight Papaya\",\r\n    \"tagline\": \"Midnight blue papaya burst\",\r\n    \"colors\": [\r\n      \"#191970\",\r\n      \"#FF9E42\",\r\n      \"#13E796\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-42\",\r\n    \"name\": \"Dusty Laser\",\r\n    \"tagline\": \"Dusty mauve laser green\",\r\n    \"colors\": [\r\n      \"#A27E8E\",\r\n      \"#7CFC00\",\r\n      \"#1B3B6F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-43\",\r\n    \"name\": \"Neon Atomic Sunset\",\r\n    \"tagline\": \"Amber fallout glowing beside ultraviolet pink\",\r\n    \"colors\": [\r\n      \"#FF9100\",\r\n      \"#FF00F5\",\r\n      \"#062A2A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-44\",\r\n    \"name\": \"Fern Flame\",\r\n    \"tagline\": \"Cool fern fierce flame\",\r\n    \"colors\": [\r\n      \"#4F7942\",\r\n      \"#FF3D2E\",\r\n      \"#E75A13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-45\",\r\n    \"name\": \"Violet Quarry\",\r\n    \"tagline\": \"Quarry gray violet eruption\",\r\n    \"colors\": [\r\n      \"#7D7F87\",\r\n      \"#8B3DFF\",\r\n      \"#DCE35B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-46\",\r\n    \"name\": \"Cadmium Deep\",\r\n    \"tagline\": \"Cadmium red deep lagoon\",\r\n    \"colors\": [\r\n      \"#D32E12\",\r\n      \"#046E8F\",\r\n      \"#E79E13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-47\",\r\n    \"name\": \"Pigment Riot\",\r\n    \"tagline\": \"Intense blue maroon and hot orange\",\r\n    \"colors\": [\r\n      \"#139FE7\",\r\n      \"#6E1423\",\r\n      \"#FF7300\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-48\",\r\n    \"name\": \"Neon Prism Riot\",\r\n    \"tagline\": \"Sea-glass cyan, magenta bite, lemon flash\",\r\n    \"colors\": [\r\n      \"#00FFC6\",\r\n      \"#FF00B8\",\r\n      \"#F5FF00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-4:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-49\",\r\n    \"name\": \"Neon Tropic Surge\",\r\n    \"tagline\": \"Aqua tide, citrus flare, violet thunder\",\r\n    \"colors\": [\r\n      \"#00FF9D\",\r\n      \"#FFB000\",\r\n      \"#D000FF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-50\",\r\n    \"name\": \"Ash Honey\",\r\n    \"tagline\": \"Ash gray golden honey\",\r\n    \"colors\": [\r\n      \"#9BA0A6\",\r\n      \"#E0A100\",\r\n      \"#2F6690\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-51\",\r\n    \"name\": \"Cherry Motor\",\r\n    \"tagline\": \"Cherry motor oil with electric blue\",\r\n    \"colors\": [\r\n      \"#B22234\",\r\n      \"#3B2F2F\",\r\n      \"#005CFF\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"manyarm-5:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-52\",\r\n    \"name\": \"Glacier Punch\",\r\n    \"tagline\": \"Glacier pigmented hot punch\",\r\n    \"colors\": [\r\n      \"#13A6E7\",\r\n      \"#F52549\",\r\n      \"#3D405B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-53\",\r\n    \"name\": \"Tarnish Bloom\",\r\n    \"tagline\": \"Tarnished teal floral orange\",\r\n    \"colors\": [\r\n      \"#3A7D7B\",\r\n      \"#F4852B\",\r\n      \"#E9D6EC\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L3\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-54\",\r\n    \"name\": \"Umber Signal\",\r\n    \"tagline\": \"Umber earth neon signal\",\r\n    \"colors\": [\r\n      \"#635147\",\r\n      \"#D0FF4B\",\r\n      \"#7A28C0\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-55\",\r\n    \"name\": \"Rose Quartz Coil\",\r\n    \"tagline\": \"Soft rose coil of teal\",\r\n    \"colors\": [\r\n      \"#E7134B\",\r\n      \"#0FA3A3\",\r\n      \"#2B2118\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-56\",\r\n    \"name\": \"Sulfur Deck\",\r\n    \"tagline\": \"Sulfur yellow blue and hot orange\",\r\n    \"colors\": [\r\n      \"#E3D200\",\r\n      \"#274C77\",\r\n      \"#FF4A00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-57\",\r\n    \"name\": \"Neon Ember Static\",\r\n    \"tagline\": \"Orange yellow buzzing with royal voltage\",\r\n    \"colors\": [\r\n      \"#FF5E00\",\r\n      \"#FFE600\",\r\n      \"#3A0CA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-3:L4\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-58\",\r\n    \"name\": \"Mango Ash\",\r\n    \"tagline\": \"Mango bright volcanic ash\",\r\n    \"colors\": [\r\n      \"#FFA12B\",\r\n      \"#59595E\",\r\n      \"#64DDBB\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-59\",\r\n    \"name\": \"Steel Petal\",\r\n    \"tagline\": \"Steel gray crushed petals\",\r\n    \"colors\": [\r\n      \"#8A8F98\",\r\n      \"#E71813\",\r\n      \"#D8E26E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-60\",\r\n    \"name\": \"Ninja Cream\",\r\n    \"tagline\": \"Hidden navy cream coral\",\r\n    \"colors\": [\r\n      \"#1E2A4A\",\r\n      \"#F0EBE0\",\r\n      \"#7EEC00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-4:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-61\",\r\n    \"name\": \"Tangerine Static\",\r\n    \"tagline\": \"Tangerine buzz grape shadow\",\r\n    \"colors\": [\r\n      \"#F28500\",\r\n      \"#3D2159\",\r\n      \"#202020\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L1\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-62\",\r\n    \"name\": \"Sage Pistol\",\r\n    \"tagline\": \"Muted sage pistol pink\",\r\n    \"colors\": [\r\n      \"#9AB5A1\",\r\n      \"#E45C98\",\r\n      \"#33272A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-63\",\r\n    \"name\": \"Lagoon Battery\",\r\n    \"tagline\": \"Lagoon green charged yellow\",\r\n    \"colors\": [\r\n      \"#1D8A7A\",\r\n      \"#FAE000\",\r\n      \"#76305B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"wedge-5:L4\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-64\",\r\n    \"name\": \"Wine Cooling\",\r\n    \"tagline\": \"Warm wine cooled by mint\",\r\n    \"colors\": [\r\n      \"#701F3C\",\r\n      \"#13E78C\",\r\n      \"#E8D44D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-65\",\r\n    \"name\": \"Charcoal Tulip\",\r\n    \"tagline\": \"Charcoal tulip flame combo\",\r\n    \"colors\": [\r\n      \"#2E3033\",\r\n      \"#FF4E50\",\r\n      \"#CA00C7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-66\",\r\n    \"name\": \"Neon Acid Harbor\",\r\n    \"tagline\": \"Lime light cutting across magenta docks\",\r\n    \"colors\": [\r\n      \"#39FF14\",\r\n      \"#FF007F\",\r\n      \"#001B2E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"warden-1:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-67\",\r\n    \"name\": \"Rustic Neon\",\r\n    \"tagline\": \"Barn red barn lime buzz\",\r\n    \"colors\": [\r\n      \"#8A3324\",\r\n      \"#C1FF33\",\r\n      \"#2D4A6B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L1\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-68\",\r\n    \"name\": \"Alice Warning\",\r\n    \"tagline\": \"Alice blue caution orange\",\r\n    \"colors\": [\r\n      \"#1399E7\",\r\n      \"#FF7E1F\",\r\n      \"#EEF700\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-69\",\r\n    \"name\": \"Smog Candy\",\r\n    \"tagline\": \"Smog beige candy teal\",\r\n    \"colors\": [\r\n      \"#E79813\",\r\n      \"#00C2A8\",\r\n      \"#D8395B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-2:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-70\",\r\n    \"name\": \"Violet Furnace\",\r\n    \"tagline\": \"Furnace violet cooled sky\",\r\n    \"colors\": [\r\n      \"#6A2D9E\",\r\n      \"#F57C3B\",\r\n      \"#302012\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-71\",\r\n    \"name\": \"Khaki Storm\",\r\n    \"tagline\": \"Khaki field storm magenta\",\r\n    \"colors\": [\r\n      \"#A89B6E\",\r\n      \"#E0218A\",\r\n      \"#2A6F97\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-72\",\r\n    \"name\": \"Neon Circuit Surge\",\r\n    \"tagline\": \"Turquoise sparks over midnight violet\",\r\n    \"colors\": [\r\n      \"#00F5D4\",\r\n      \"#F72585\",\r\n      \"#0B0321\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-3:L4\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-73\",\r\n    \"name\": \"Cedar Ultraviolet\",\r\n    \"tagline\": \"Cedar wood ultraviolet light\",\r\n    \"colors\": [\r\n      \"#7A4532\",\r\n      \"#8246FF\",\r\n      \"#E9E4D8\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-74\",\r\n    \"name\": \"Frosted Chili\",\r\n    \"tagline\": \"Frost blue chili red\",\r\n    \"colors\": [\r\n      \"#13AAE7\",\r\n      \"#C13A2F\",\r\n      \"#4C5B2C\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-75\",\r\n    \"name\": \"Moss Rocket\",\r\n    \"tagline\": \"Moss green rocket pink\",\r\n    \"colors\": [\r\n      \"#5B7042\",\r\n      \"#FA0057\",\r\n      \"#061F5B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"blob-4:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-76\",\r\n    \"name\": \"Pewter Punch\",\r\n    \"tagline\": \"Pewter softened hot punch\",\r\n    \"colors\": [\r\n      \"#99A0A8\",\r\n      \"#FF3D7F\",\r\n      \"#164D37\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L1\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-77\",\r\n    \"name\": \"Neon Glacier Riot\",\r\n    \"tagline\": \"Cyan hot pink and radioactive lime\",\r\n    \"colors\": [\r\n      \"#00F0FF\",\r\n      \"#FF00E5\",\r\n      \"#CCFF00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L3\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-78\",\r\n    \"name\": \"Cola Lightning\",\r\n    \"tagline\": \"Cola brown lightning yellow\",\r\n    \"colors\": [\r\n      \"#3A2618\",\r\n      \"#F7FF00\",\r\n      \"#FA005E\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-2:L4\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-79\",\r\n    \"name\": \"Periwinkle Fuel\",\r\n    \"tagline\": \"Soft periwinkle diesel orange\",\r\n    \"colors\": [\r\n      \"#1325E7\",\r\n      \"#E0641E\",\r\n      \"#2F4730\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-80\",\r\n    \"name\": \"Jade Alarm\",\r\n    \"tagline\": \"Jade calm siren red\",\r\n    \"colors\": [\r\n      \"#57A78A\",\r\n      \"#D91E36\",\r\n      \"#E7AF13\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L3\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-81\",\r\n    \"name\": \"Neon Ultraviolet Pulse\",\r\n    \"tagline\": \"Violet beams with mint-charged current\",\r\n    \"colors\": [\r\n      \"#8C00FF\",\r\n      \"#00FFB2\",\r\n      \"#160021\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"cap-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-82\",\r\n    \"name\": \"Neon Nightcaller\",\r\n    \"tagline\": \"Cyan violet flame in black-green fog\",\r\n    \"colors\": [\r\n      \"#00FFFF\",\r\n      \"#9400FF\",\r\n      \"#131A00\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L1\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-83\",\r\n    \"name\": \"Ivory Shock\",\r\n    \"tagline\": \"Ivory calm violet shock\",\r\n    \"colors\": [\r\n      \"#F0EEE4\",\r\n      \"#7C1FD3\",\r\n      \"#FFB200\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-84\",\r\n    \"name\": \"Neon Ruby Arc\",\r\n    \"tagline\": \"Red-hot signal over green afterglow\",\r\n    \"colors\": [\r\n      \"#FF073A\",\r\n      \"#00FF87\",\r\n      \"#080F1B\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-2:L4\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-85\",\r\n    \"name\": \"Maroon Cloud\",\r\n    \"tagline\": \"Maroon heavy cloud blue\",\r\n    \"colors\": [\r\n      \"#6D1E2E\",\r\n      \"#1381E7\",\r\n      \"#E5D352\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L1\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-86\",\r\n    \"name\": \"Chrome Berry\",\r\n    \"tagline\": \"Chrome band over berry\",\r\n    \"colors\": [\r\n      \"#C3C9D1\",\r\n      \"#8E2A5C\",\r\n      \"#FFB347\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-87\",\r\n    \"name\": \"Lentil Neon\",\r\n    \"tagline\": \"Lentil tan electric aqua\",\r\n    \"colors\": [\r\n      \"#B09A6E\",\r\n      \"#00FFF0\",\r\n      \"#5F1B63\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-3:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-88\",\r\n    \"name\": \"Neon Cobalt Fuse\",\r\n    \"tagline\": \"Blue ignition wired to blazing yellow\",\r\n    \"colors\": [\r\n      \"#004DFF\",\r\n      \"#FFEE00\",\r\n      \"#0D0221\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-89\",\r\n    \"name\": \"Spruce Bonfire\",\r\n    \"tagline\": \"Dark spruce bonfire orange\",\r\n    \"colors\": [\r\n      \"#23493C\",\r\n      \"#FF7A3D\",\r\n      \"#0C1735\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-90\",\r\n    \"name\": \"Lilac Foundry\",\r\n    \"tagline\": \"Lilac meets foundry steel\",\r\n    \"colors\": [\r\n      \"#9813E7\",\r\n      \"#7B8894\",\r\n      \"#D4522A\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"stalk-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-91\",\r\n    \"name\": \"Topaz Battle\",\r\n    \"tagline\": \"Topaz gold navy clash\",\r\n    \"colors\": [\r\n      \"#F0B429\",\r\n      \"#182952\",\r\n      \"#FA007D\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L1\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-92\",\r\n    \"name\": \"Dusk Celery\",\r\n    \"tagline\": \"Dusky purple celery snap\",\r\n    \"colors\": [\r\n      \"#574B6B\",\r\n      \"#C8D86A\",\r\n      \"#FA2100\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L3\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-93\",\r\n    \"name\": \"Tide Copperfuse\",\r\n    \"tagline\": \"Tidal teal copperfuse glow\",\r\n    \"colors\": [\r\n      \"#0F7B7B\",\r\n      \"#C07840\",\r\n      \"#C2F000\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-2:L4\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-94\",\r\n    \"name\": \"Punch Driftwood\",\r\n    \"tagline\": \"Fruit punch on driftwood\",\r\n    \"colors\": [\r\n      \"#E63362\",\r\n      \"#6E5B4A\",\r\n      \"#1648EA\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L1\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"pal-95\",\r\n    \"name\": \"Ink Lime\",\r\n    \"tagline\": \"Ink smudge streaked lime\",\r\n    \"colors\": [\r\n      \"#23232A\",\r\n      \"#A8E10C\",\r\n      \"#7E10EA\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L3\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-96\",\r\n    \"name\": \"Porcelain Prism\",\r\n    \"tagline\": \"Porcelain violet over tidal blue\",\r\n    \"colors\": [\r\n      \"#F5F1E8\",\r\n      \"#BD05DA\",\r\n      \"#005F73\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-3:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-97\",\r\n    \"name\": \"Wasabi Cloud\",\r\n    \"tagline\": \"Wasabi heat cloud gray\",\r\n    \"colors\": [\r\n      \"#9FBF3B\",\r\n      \"#8E94A0\",\r\n      \"#E71363\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L1\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-98\",\r\n    \"name\": \"Eggplant Flare\",\r\n    \"tagline\": \"Eggplant deep flare yellow\",\r\n    \"colors\": [\r\n      \"#41284E\",\r\n      \"#FFD23F\",\r\n      \"#5BC0BE\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L3\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-99\",\r\n    \"name\": \"Stone Rose\",\r\n    \"tagline\": \"Stone gray antique rose\",\r\n    \"colors\": [\r\n      \"#8F8A82\",\r\n      \"#C46E8E\",\r\n      \"#2F6DA3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"tanka-4:L4\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-100\",\r\n    \"name\": \"Neon Quasar Pop\",\r\n    \"tagline\": \"Yellow green comet over indigo gravity\",\r\n    \"colors\": [\r\n      \"#FFEF00\",\r\n      \"#00FF3C\",\r\n      \"#2D02B8\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L1\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"pal-101\",\r\n    \"name\": \"Arctic Rust\",\r\n    \"tagline\": \"Arctic white rusted orange\",\r\n    \"colors\": [\r\n      \"#E9F2F5\",\r\n      \"#9E4A1D\",\r\n      \"#3E3F8F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L3\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-102\",\r\n    \"name\": \"Magenta Selvage\",\r\n    \"tagline\": \"Magenta edge denim blue\",\r\n    \"colors\": [\r\n      \"#D8117E\",\r\n      \"#3B5B8C\",\r\n      \"#E7D313\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"lume-1:L4\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"pal-103\",\r\n    \"name\": \"Haze Saffron\",\r\n    \"tagline\": \"Purple haze saffron spark\",\r\n    \"colors\": [\r\n      \"#8467B8\",\r\n      \"#F4A81D\",\r\n      \"#1D4E50\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L1\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"pal-104\",\r\n    \"name\": \"Neon Cyber Reed\",\r\n    \"tagline\": \"Green circuitry humming beside lemon static\",\r\n    \"colors\": [\r\n      \"#00FF66\",\r\n      \"#FFEA00\",\r\n      \"#4B0082\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L2\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"pal-105\",\r\n    \"name\": \"Neon Magma Bloom\",\r\n    \"tagline\": \"Molten orange meeting synthetic magenta\",\r\n    \"colors\": [\r\n      \"#FF2E00\",\r\n      \"#F000FF\",\r\n      \"#0A0A0F\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L3\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"pal-106\",\r\n    \"name\": \"Dune Violet\",\r\n    \"tagline\": \"Warm dune electric violet\",\r\n    \"colors\": [\r\n      \"#C9AE7E\",\r\n      \"#7D2BF0\",\r\n      \"#13E7E3\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L4\",\r\n    \"finish\": \"marbled\"\r\n  },\r\n  {\r\n    \"id\": \"pal-107\",\r\n    \"name\": \"Ember Nightshade\",\r\n    \"tagline\": \"Violet shadows ember teal\",\r\n    \"colors\": [\r\n      \"#523090\",\r\n      \"#EF4E23\",\r\n      \"#0C5D68\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"reward\": \"food:L5\",\r\n    \"finish\": \"watercolor\"\r\n  },\r\n  {\r\n    \"id\": \"opal-jelly\",\r\n    \"name\": \"Opal Jelly\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#b3fff0\",\r\n      \"#9767ff\",\r\n      \"#fff1ff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"bubble-glass\",\r\n    \"name\": \"Bubble Glass\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#58eaff\",\r\n      \"#b8fff8\",\r\n      \"#ffffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"prism-crystal\",\r\n    \"name\": \"Prism Crystal\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#b18aff\",\r\n      \"#447bff\",\r\n      \"#fff2ff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"holo-foil\",\r\n    \"name\": \"Holographic Foil\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#ff54de\",\r\n      \"#39e5ff\",\r\n      \"#fff56b\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"pearl\"\r\n  },\r\n  {\r\n    \"id\": \"glitter-resin\",\r\n    \"name\": \"Glitter Resin\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#ff319c\",\r\n      \"#7025ff\",\r\n      \"#fff6db\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"galaxy-geode\",\r\n    \"name\": \"Galaxy Geode\",\r\n    \"tagline\": \"Shifting highlights and luminous color\",\r\n    \"colors\": [\r\n      \"#21134e\",\r\n      \"#7b39e8\",\r\n      \"#63ffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glitter\"\r\n  },\r\n  {\r\n    \"id\": \"caustic-slime\",\r\n    \"name\": \"Caustic Slime\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#8aa52b\",\r\n      \"#20300b\",\r\n      \"#dcff57\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"blister-hide\",\r\n    \"name\": \"Blister Hide\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#9e435f\",\r\n      \"#2d1727\",\r\n      \"#e7bb72\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"rotten-rind\",\r\n    \"name\": \"Rotten Rind\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#626124\",\r\n      \"#211916\",\r\n      \"#a2b16b\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"matte\"\r\n  },\r\n  {\r\n    \"id\": \"parasite-nest\",\r\n    \"name\": \"Parasite Nest\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#786541\",\r\n      \"#151c14\",\r\n      \"#ece2b0\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"exposed-sinew\",\r\n    \"name\": \"Exposed Sinew\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#b72945\",\r\n      \"#300b24\",\r\n      \"#efb5a1\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"abyssal-maw\",\r\n    \"name\": \"Abyssal Maw\",\r\n    \"tagline\": \"Organic horror surface\",\r\n    \"colors\": [\r\n      \"#522045\",\r\n      \"#100d19\",\r\n      \"#d9e6a7\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  },\r\n  {\r\n    \"id\": \"circuit-alloy\",\r\n    \"name\": \"Circuit Alloy\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#273f50\",\r\n      \"#0a111c\",\r\n      \"#4effdc\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"servo-armor\",\r\n    \"name\": \"Servo Armor\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#617080\",\r\n      \"#141b25\",\r\n      \"#ff6739\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"brushed-metal\"\r\n  },\r\n  {\r\n    \"id\": \"chrome-rib\",\r\n    \"name\": \"Chrome Rib\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#bfcde1\",\r\n      \"#202f46\",\r\n      \"#ffffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"polished-metal\"\r\n  },\r\n  {\r\n    \"id\": \"carbon-mech\",\r\n    \"name\": \"Carbon Mech\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#323d46\",\r\n      \"#080d15\",\r\n      \"#95bac9\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\"\r\n  },\r\n  {\r\n    \"id\": \"hazard-panel\",\r\n    \"name\": \"Hazard Panel\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#edb932\",\r\n      \"#131a20\",\r\n      \"#ffe9a2\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\"\r\n  },\r\n  {\r\n    \"id\": \"reactor-glass\",\r\n    \"name\": \"Reactor Glass\",\r\n    \"tagline\": \"Machine surface\",\r\n    \"colors\": [\r\n      \"#48e8ff\",\r\n      \"#063a55\",\r\n      \"#d4ffff\"\r\n    ],\r\n    \"unlockRule\": \"battle-pass\",\r\n    \"finish\": \"glaze\"\r\n  }\r\n]\r\n","handborne/source/app/pose-rig.ts":"import * as THREE from 'three';\r\nimport { DIGITS, type Digit, type Pose } from './poses.ts';\r\n\r\n// Rest centerlines are shared with the anatomical sculpt (converted to Y-up).\r\nexport const REST_SOURCE:Record<Digit,number[][]>={\r\n index:[[-.028,0,.048],[-.032,.003,.086],[-.033,.010,.112],[-.032,.018,.132]],\r\n middle:[[-.008,-.001,.054],[-.009,.002,.097],[-.009,.011,.126],[-.008,.021,.148]],\r\n ring:[[.013,0,.050],[.015,.004,.090],[.017,.014,.115],[.018,.025,.135]],\r\n pinky:[[.031,.002,.039],[.038,.006,.069],[.042,.015,.089],[.043,.026,.105]],\r\n thumb:[[-.028,.010,-.021],[-.049,.016,.003],[-.067,.020,.023],[-.077,.028,.044]],\r\n};\r\nexport const DIGIT_RADII=[.0092,.0098,.0089,.0073,.0108];\r\nconst radii=DIGIT_RADII;\r\nconst axisX=new THREE.Vector3(1,0,0),axisY=new THREE.Vector3(0,1,0),axisZ=new THREE.Vector3(0,0,1);\r\nconst rest=DIGITS.map(d=>REST_SOURCE[d].map(([x,y,z])=>new THREE.Vector3(x,z,-y)));\r\nexport const BABY_RIG_SCALE=new THREE.Vector3(.78,.40,.95);\r\ntype RigProfile='standard'|'baby';\r\nconst makeBones=(landmarks:THREE.Vector3[][])=>landmarks.map(points=>points.slice(0,3).map((p,i)=>{\r\n  const dir=points[i+1].clone().sub(p),length=dir.length();dir.normalize();\r\n  const side=dir.clone().cross(axisZ).normalize(),back=side.clone().cross(dir).normalize();\r\n  const quaternion=new THREE.Quaternion().setFromRotationMatrix(new THREE.Matrix4().makeBasis(side,dir,back));\r\n  const inverse=new THREE.Matrix4().compose(p,quaternion,new THREE.Vector3(1,1,1)).invert();\r\n  return {p,dir,length,quaternion,inverse};\r\n}));\r\nconst profileBones={standard:makeBones(rest),baby:makeBones(rest.map(points=>points.map(p=>p.clone().multiply(BABY_RIG_SCALE))))};\r\nconst smooth=(x:number)=>{x=Math.max(0,Math.min(1,x));return x*x*(3-2*x);};\r\nexport function poseMatrices(pose:Pose,profile:RigProfile='standard'):THREE.Matrix4[] {\r\n  const bones=profileBones[profile];\r\n  const matrices=[new THREE.Matrix4()],rad=Math.PI/180;\r\n  for(let d=0;d<5;d++){\r\n    const angles=pose.fingers[DIGITS[d]];let previousQ=new THREE.Quaternion(),previousP=new THREE.Vector3();\r\n    for(let i=0;i<3;i++){\r\n      const bone=bones[d][i];let q:THREE.Quaternion,p:THREE.Vector3;\r\n      if(i===0){\r\n        q=new THREE.Quaternion().setFromAxisAngle(axisZ,angles[3]*rad);\r\n        if(d===4)q.multiply(new THREE.Quaternion().setFromAxisAngle(axisY,-pose.opposition*rad));\r\n        q.multiply(bone.quaternion);p=bone.p.clone();\r\n      }else{\r\n        q=previousQ.clone().multiply(bones[d][i-1].quaternion.clone().invert().multiply(bone.quaternion));\r\n        p=previousP.clone().add(new THREE.Vector3(0,bones[d][i-1].length,0).applyQuaternion(previousQ));\r\n      }\r\n      q.multiply(new THREE.Quaternion().setFromAxisAngle(axisX,-angles[i]*rad));\r\n      matrices.push(new THREE.Matrix4().compose(p,q,new THREE.Vector3(1,1,1)).multiply(bone.inverse));\r\n      previousQ=q;previousP=p;\r\n    }\r\n  }\r\n  const rotation=new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(...pose.rotation.map(v=>v*rad) as [number,number,number]));\r\n  return matrices.map(m=>rotation.clone().multiply(m));\r\n}\r\nexport function fingerTip(pose:Pose,digit:Digit):THREE.Vector3 {\r\n  const index=DIGITS.indexOf(digit);return rest[index][3].clone().applyMatrix4(poseMatrices(pose)[index*3+3]);\r\n}\r\n\r\nfunction influences(x:number,y:number,z:number,profile:RigProfile='standard'):[number,number][] {\r\n  const bones=profileBones[profile],size=profile==='baby'?.46:1;\r\n  const radii=DIGIT_RADII.map(r=>r*(profile==='baby'?.86:1));\r\n  if(y<-.033*(profile==='baby'?BABY_RIG_SCALE.y:1))return [[0,1]];\r\n  const candidates:{score:number;gain:number;d:number;i:number;t:number}[]=[];\r\n  for(let d=0;d<5;d++){\r\n    let min=Infinity,segment=0,t=0;\r\n    for(let i=0;i<3;i++){\r\n      const b=bones[d][i],dx=x-b.p.x,dy=y-b.p.y,dz=z-b.p.z;\r\n      const u=Math.max(0,Math.min(1,(dx*b.dir.x+dy*b.dir.y+dz*b.dir.z)/b.length));\r\n      const ex=dx-b.dir.x*u*b.length,ey=dy-b.dir.y*u*b.length,ez=dz-b.dir.z*u*b.length;\r\n      const dist=ex*ex+ey*ey+ez*ez;if(dist<min){min=dist;segment=i;t=u;}\r\n    }\r\n    const base=bones[d][0],along=(x-base.p.x)*base.dir.x+(y-base.p.y)*base.dir.y+(z-base.p.z)*base.dir.z;\r\n    const gain=smooth((along+.007*size)/(.020*size))*(1-smooth((Math.sqrt(min)/radii[d]-1.45)/1.1));\r\n    candidates.push({score:1/Math.pow(.08+min/(radii[d]*radii[d]),4),gain,d,i:segment,t});\r\n  }\r\n  candidates.sort((a,b)=>b.score-a.score);\r\n  const chosen=candidates.slice(0,2),total=chosen.reduce((s,c)=>s+c.score,0),weights=new Map<number,number>();\r\n  const add=(id:number,w:number)=>weights.set(id,(weights.get(id)??0)+w);\r\n  for(const c of chosen){\r\n    const fraction=c.score/total,active=fraction*c.gain,id=c.d*3+c.i+1;add(0,fraction-active);\r\n    const previous=c.i>0?.5*(1-smooth(c.t/.20)):0,next=c.i<2?.5*smooth((c.t-.80)/.20):0;\r\n    add(id,active*(1-previous-next));if(previous)add(id-1,active*previous);if(next)add(id+1,active*next);\r\n  }\r\n  const result=[...weights].sort((a,b)=>b[1]-a[1]).slice(0,4),sum=result.reduce((s,[,w])=>s+w,0);\r\n  return result.map(([id,w])=>[id,w/sum]);\r\n}\r\ntype BoundMesh={mesh:THREE.Mesh;profile:RigProfile;positions:Float32Array;normals:Float32Array;ids:Uint8Array;weights:Float32Array;inverse:THREE.Matrix4;inverseNormal:THREE.Matrix3};\r\nexport type HandRig={group:THREE.Group;meshes:BoundMesh[];dispose:()=>void};\r\nexport function bindHand(group:THREE.Group):HandRig {\r\n  group.updateMatrixWorld(true);const bound:BoundMesh[]=[];\r\n  group.traverse(obj=>{\r\n    if(!(obj instanceof THREE.Mesh))return;\r\n    const original=obj.geometry;obj.geometry=original.clone();if(obj.userData.ownedGeometry)original.dispose();obj.userData.posedGeometry=true;\r\n    const pos=obj.geometry.getAttribute('position'),normal=obj.geometry.getAttribute('normal');\r\n    const positions=new Float32Array(pos.count*3),normals=new Float32Array(pos.count*3),ids=new Uint8Array(pos.count*4),weights=new Float32Array(pos.count*4);\r\n    const worldNormal=new THREE.Matrix3().getNormalMatrix(obj.matrixWorld),p=new THREE.Vector3(),n=new THREE.Vector3();\r\n    const profile:RigProfile=obj.userData.rig_profile==='baby'?'baby':'standard';\r\n    // Every strand or scale shares its attachment weights, so fingers cannot tear it apart.\r\n    const furRoots=obj.geometry.getAttribute('_fur_root')??obj.geometry.getAttribute('_surface_root');\r\n    let rootX=NaN,rootY=NaN,rootZ=NaN,rootWeights:[number,number][]=[];\r\n    for(let i=0;i<pos.count;i++){\r\n      p.fromBufferAttribute(pos,i).applyMatrix4(obj.matrixWorld);n.fromBufferAttribute(normal,i).applyNormalMatrix(worldNormal);\r\n      p.toArray(positions,i*3);n.toArray(normals,i*3);\r\n      const nailDigit=obj.userData.region==='nails'?DIGITS.indexOf(obj.userData.digit):-1;\r\n      const explicitBone=obj.userData.rig_bone;\r\n      if(furRoots){\r\n        const x=furRoots.getX(i),y=furRoots.getY(i),z=furRoots.getZ(i);\r\n        if(x!==rootX||y!==rootY||z!==rootZ){rootX=x;rootY=y;rootZ=z;rootWeights=influences(x,y,z,profile);}\r\n      }\r\n      const vertexWeights=Number.isInteger(explicitBone)&&explicitBone>=0&&explicitBone<=15?[[explicitBone,1]]:nailDigit>=0?[[nailDigit*3+3,1]]:furRoots?rootWeights:influences(p.x,p.y,p.z,profile);\r\n      for(const[j,[id,w]]of vertexWeights.entries()){ids[i*4+j]=id;weights[i*4+j]=w;}\r\n    }\r\n    bound.push({mesh:obj,profile,positions,normals,ids,weights,inverse:obj.matrixWorld.clone().invert(),inverseNormal:worldNormal.clone().invert()});\r\n  });\r\n  return {group,meshes:bound,dispose(){const materials=new Set<THREE.Material>();for(const item of bound){item.mesh.geometry.dispose();if(item.mesh.userData.ownedMaterial){for(const m of Array.isArray(item.mesh.material)?item.mesh.material:[item.mesh.material])materials.add(m);for(const m of item.mesh.userData.sourceMaterials??[])materials.add(m);}}materials.forEach(m=>m.dispose());}};\r\n}\r\nexport function applyHandPose(rig:HandRig,pose:Pose) {\r\n  const profileMatrices={standard:poseMatrices(pose).map(m=>m.elements),baby:poseMatrices(pose,'baby').map(m=>m.elements)},min=new THREE.Vector3(Infinity,Infinity,Infinity),max=new THREE.Vector3(-Infinity,-Infinity,-Infinity);\r\n  const p=new THREE.Vector3(),n=new THREE.Vector3();\r\n  for(const bound of rig.meshes){\r\n    const {mesh,positions,normals,ids,weights}=bound,pos=mesh.geometry.getAttribute('position'),normal=mesh.geometry.getAttribute('normal');\r\n    const matrices=profileMatrices[bound.profile];\r\n    for(let i=0;i<pos.count;i++){\r\n      const k=i*3,x=positions[k],y=positions[k+1],z=positions[k+2],nx=normals[k],ny=normals[k+1],nz=normals[k+2];\r\n      let px=0,py=0,pz=0,ox=0,oy=0,oz=0;\r\n      for(let j=0;j<4;j++){\r\n        const w=weights[i*4+j];if(!w)continue;const m=matrices[ids[i*4+j]];\r\n        px+=w*(m[0]*x+m[4]*y+m[8]*z+m[12]);py+=w*(m[1]*x+m[5]*y+m[9]*z+m[13]);pz+=w*(m[2]*x+m[6]*y+m[10]*z+m[14]);\r\n        ox+=w*(m[0]*nx+m[4]*ny+m[8]*nz);oy+=w*(m[1]*nx+m[5]*ny+m[9]*nz);oz+=w*(m[2]*nx+m[6]*ny+m[10]*nz);\r\n      }\r\n      p.set(px,py,pz);min.min(p);max.max(p);p.applyMatrix4(bound.inverse);pos.setXYZ(i,p.x,p.y,p.z);\r\n      n.set(ox,oy,oz).applyMatrix3(bound.inverseNormal).normalize();normal.setXYZ(i,n.x,n.y,n.z);\r\n    }\r\n    pos.needsUpdate=true;normal.needsUpdate=true;mesh.geometry.computeBoundingBox();mesh.geometry.computeBoundingSphere();\r\n    // Exporters regenerate tangents from the posed normals and preserved UVs.\r\n    mesh.geometry.deleteAttribute('tangent');\r\n  }\r\n  const center=min.add(max).multiplyScalar(.5);rig.group.position.set(-center.x,.035-center.y,-center.z);\r\n  rig.group.userData.pose=pose.id;rig.group.userData.pose_name=pose.name;rig.group.updateMatrixWorld(true);\r\n}\r\n","handborne/source/app/poses.ts":"export const DIGITS = ['index','middle','ring','pinky','thumb'] as const;\r\nexport type Digit = typeof DIGITS[number];\r\nexport type FingerPose = [number,number,number,number]; // MCP, PIP, DIP flexion; spread, degrees\r\nexport type Pose = { id:string; name:string; description:string; fingers:Record<Digit,FingerPose>; opposition:number; rotation:[number,number,number] };\r\nconst relaxed:FingerPose=[0,0,0,0],straight:FingerPose=[-3,-8,-7,0],fold:FingerPose=[72,88,42,0];\r\nconst thumbIn:FingerPose=[0,6,8,-60];\r\nfunction pose(id:string,name:string,description:string,fingers:Partial<Record<Digit,FingerPose>>={},opposition=0,rotation:[number,number,number]=[0,0,0]):Pose {\r\n  return {id,name,description,fingers:{index:[...relaxed],middle:[...relaxed],ring:[...relaxed],pinky:[...relaxed],thumb:[...relaxed],...fingers},opposition,rotation};\r\n}\r\nconst fist={index:fold,middle:fold,ring:fold,pinky:fold,thumb:thumbIn};\r\nexport const POSES:Pose[]=[\r\n  pose('relaxed','Relaxed','The original relaxed, open hand.'),\r\n  pose('high-five','High Five','An open palm with all five fingers spread.',{index:[-3,-8,-7,8],middle:straight,ring:[-3,-8,-7,-7],pinky:[-3,-8,-7,-13],thumb:[-6,-6,-5,12]},0,[0,180,0]),\r\n  pose('fist-bump','Fist Bump','Closed fingers, with the knuckles leading.',fist,10,[58,0,-12]),\r\n  pose('peace','Peace / Victory','Index and middle fingers form a V.',{...fist,index:[-3,-8,-7,12],middle:[-3,-8,-7,-7]},10),\r\n  pose('rock-on','Rock On','Index and pinky up, thumb over the folded fingers.',{...fist,index:[-3,-8,-7,6],pinky:[-3,-8,-7,-10]},10),\r\n  pose('i-love-you','I Love You','Thumb, index and pinky extended.',{index:straight,middle:fold,ring:fold,pinky:straight,thumb:[-4,-5,-6,8]}),\r\n  pose('web-shooter','Web Shooter','Middle and ring fingers press toward the palm.',{index:[-3,-8,-7,5],middle:[65,80,58,0],ring:[65,80,58,0],pinky:[-3,-8,-7,-8],thumb:[-8,-6,-7,15]},0,[-8,180,-18]),\r\n  pose('vulcan','Vulcan Salute','Two paired fingers, separated down the middle.',{index:[-3,-8,-7,6],middle:[-3,-8,-7,12],ring:[-3,-8,-7,-11],pinky:[-3,-8,-7,-5],thumb:[-4,-4,-4,10]}),\r\n  pose('thumbs-up','Thumbs Up','A closed fist with the thumb held up.',{...fist,thumb:[-5,-8,-7,0]},0,[0,0,-51]),\r\n  pose('thumbs-down','Thumbs Down','A closed fist with the thumb pointing down.',{...fist,thumb:[-5,-8,-7,0]},0,[0,0,129]),\r\n  pose('finger-gun','Finger Gun','Index forward, thumb raised, other fingers curled.',{...fist,index:straight,thumb:[-8,-7,-5,13]},0,[0,0,-70]),\r\n  pose('point-up','Point Up','One index finger raised.',{...fist,index:straight},10),\r\n  pose('point-at-you','Point at You','An index finger aimed through the glass.',{...fist,index:straight},10,[72,-12,0]),\r\n  pose('ok','OK Sign','Thumb and index form a circle.',{index:[35,72,46,4],middle:[-2,-6,-4,-1],ring:[3,0,0,-5],pinky:[6,3,0,-12],thumb:[-14.5,26.4,36.8,-38]},10.9,[0,55,0]),\r\n  pose('pinch','Pinch','Thumb and index meet in a small precision pinch.',{index:[40,62,40,2],middle:[45,52,28,0],ring:[53,60,30,0],pinky:[60,65,32,0],thumb:[-.7,10.1,31.6,-35.3]},14.9,[0,55,0]),\r\n  pose('crossed-fingers','Fingers Crossed','Index and middle crossed for good luck.',{...fist,index:[-9,-3,-5,-11],middle:[8,0,-3,17]},10),\r\n  pose('pinky-promise','Pinky Promise','A single pinky extended from a loose fist.',{...fist,pinky:[-3,-8,-7,-7]},10),\r\n  pose('hang-loose','Hang Loose / Shaka','Thumb and pinky out; the middle three fingers curled.',{...fist,pinky:[-3,-8,-7,-10],thumb:[-7,-8,-6,12]},0,[0,0,-25]),\r\n  pose('scout-salute','Three-finger Salute','Index, middle and ring raised together.',{...fist,index:[-3,-8,-7,-2],middle:straight,ring:[-3,-8,-7,2]},10),\r\n  pose('force-grip','Force Grip','A natural, open grasp with all fingers curved.',{index:[26,32,17,9],middle:[32,35,19,2],ring:[38,39,21,-5],pinky:[43,42,24,-12],thumb:[8,13,10,5]},20,[-10,-20,8]),\r\n];\r\nexport const DEFAULT_POSE='relaxed';\r\nexport function getPose(id:string):Pose { const found=POSES.find(p=>p.id===id);if(!found)throw new Error('Unknown hand pose.');return found; }\r\nexport function validatePose(value:unknown):string {if(typeof value!=='string')throw new Error('Choose a valid hand pose.');getPose(value);return value;}\r\nexport function mixPoses(a:Pose,b:Pose,t:number):Pose {\r\n  if(t>=1)return b;\r\n  const lerp=(x:number,y:number)=>x+(y-x)*t;\r\n  return {...b,fingers:Object.fromEntries(DIGITS.map(d=>[d,a.fingers[d].map((v,i)=>lerp(v,b.fingers[d][i]))])) as Record<Digit,FingerPose>,opposition:lerp(a.opposition,b.opposition),rotation:a.rotation.map((v,i)=>v+((b.rotation[i]-v+540)%360-180)*t) as Pose['rotation']};\r\n}\r\n","handborne/source/app/recipe.ts":"import {isHandStyleUnlocked} from './material-access';\r\nimport { DEFAULT_SELECTION, REGIONS, STYLES, hasStyle, PICKER_STYLES, type RegionId } from './catalog.ts';\r\nimport { DEFAULT_POSE, POSES, validatePose } from './poses.ts';\r\nimport { DEFAULT_NAIL_SHAPE, NAIL_SHAPES, validateNailShape } from './nails.ts';\r\nimport { SCALE_PATTERNS, validateScalePattern } from './scale-patterns.ts';\r\n\r\nexport type Selection = Record<RegionId, number>;\r\nexport type HandDesign = {sections:Selection;pose:string;nailShape:string;scalePattern?:string};\r\nconst legacyRegions=['nails','fingertips','middle_sections','knuckles','palm','back_of_hand','wrist'];\r\nconst nailIds=[DEFAULT_NAIL_SHAPE,...NAIL_SHAPES.map(s=>s.id)];\r\nconst two=(n:number)=>String(n).padStart(2,'0');\r\nexport const recipeCode=(sections:Selection)=>'HB3-'+REGIONS.map(r=>two(sections[r.id]+1)).join('-')+'-01-01';\r\nexport function designCode(design:HandDesign){\r\n  const core=recipeCode(design.sections).split('-').slice(0,7).join('-')+'-'+two(POSES.findIndex(p=>p.id===validatePose(design.pose))+1)+'-'+two(nailIds.indexOf(validateNailShape(design.nailShape))+1);\r\n  const pattern=validateScalePattern(design.scalePattern??'none');\r\n  return pattern==='none'?core:core.replace('HB3-','HB4-')+'-'+two(SCALE_PATTERNS.findIndex(s=>s.id===pattern)+1);\r\n}\r\nexport function validateSelection(value: unknown): Selection {\r\n  if (!value || typeof value !== 'object') throw new Error('A recipe must contain all six sections.');\r\n  const source = value as Record<string, unknown>;\r\n  if (Object.keys(source).length !== 6) throw new Error('A recipe needs exactly six sections.');\r\n  const result = {} as Selection;\r\n  for (const { id } of REGIONS) {\r\n    if (typeof source[id] !== 'number' || !Number.isInteger(source[id]) || source[id] < 0 || !hasStyle(source[id] as number)) throw new Error(`Invalid style for ${id}. Choose 1–${STYLES.length}.`);\r\n    result[id] = source[id] as number;\r\n  }\r\n  return result;\r\n}\r\nfunction migrateLegacy(value:unknown):Selection {\r\n  if(!value||typeof value!=='object'||Object.keys(value).length!==7)throw new Error('Older recipes need seven original sections.');\r\n  const v=value as Record<string,unknown>;\r\n  for(const id of legacyRegions)if(typeof v[id]!=='number'||!Number.isInteger(v[id])||(v[id] as number)<0||(v[id] as number)>19)throw new Error('Invalid legacy style.');\r\n  // The old finger-shaft choice now styles the joined finger/knuckle surface.\r\n  return validateSelection({nails:v.nails,fingertips:v.fingertips,fingers:v.middle_sections,palm:v.palm,back_of_hand:v.back_of_hand,wrist:v.wrist});\r\n}\r\nexport function parseDesign(text:string):HandDesign {\r\n  const input=text.trim();\r\n  if(input.startsWith('HB3-')||input.startsWith('HB4-')){\r\n    const scales=input.startsWith('HB4-');\r\n    if(!(scales?/^HB4(?:-\\d{2}){9}$/:/^HB3(?:-\\d{2}){8}$/).test(input))throw new Error('Invalid recipe: six styles, a pose, nails and (HB4) scales are required.');\r\n    const v=input.split('-').slice(1).map(Number);\r\n    if(!POSES[v[6]-1]||!nailIds[v[7]-1])throw new Error('Invalid pose or nail shape in recipe.');\r\n    const pattern=scales?validateScalePattern(SCALE_PATTERNS[v[8]-1]?.id):'none';\r\n    return {sections:validateSelection(Object.fromEntries(REGIONS.map((r,i)=>[r.id,v[i]-1]))),pose:POSES[v[6]-1].id,nailShape:nailIds[v[7]-1],...(pattern==='none'?{}:{scalePattern:pattern})};\r\n  }\r\n  if(input.startsWith('HB1-')||input.startsWith('HB2-')){\r\n    const v=input.split('-'),version=v.shift();\r\n    if(v.length!==(version==='HB1'?7:8)||v.some(n=>!/^(0[1-9]|1[0-9]|20)$/.test(n)))throw new Error('Invalid older recipe code.');\r\n    return {sections:migrateLegacy(Object.fromEntries(legacyRegions.map((r,i)=>[r,Number(v[i])-1]))),pose:version==='HB1'?DEFAULT_POSE:POSES[Number(v[7])-1].id,nailShape:DEFAULT_NAIL_SHAPE};\r\n  }\r\n  let parsed:{version:number;sections:unknown;pose?:unknown;nailShape?:unknown;scalePattern?:unknown};\r\n  try{parsed=JSON.parse(input);}catch{throw new Error('Paste a Handborne recipe code or recipe JSON.');}\r\n  if(!parsed||![1,2,3,4].includes(parsed.version))throw new Error('Unsupported recipe version.');\r\n  const pattern=parsed.version===4?validateScalePattern(parsed.scalePattern??'none'):'none';\r\n  return {sections:parsed.version>=3?validateSelection(parsed.sections):migrateLegacy(parsed.sections),pose:parsed.version===1?DEFAULT_POSE:validatePose(parsed.pose),nailShape:parsed.version>=3?validateNailShape(parsed.nailShape):DEFAULT_NAIL_SHAPE,...(pattern==='none'?{}:{scalePattern:pattern})};\r\n}\r\nexport function parseRecipe(text:string):Selection{return parseDesign(text).sections;}\r\nexport function randomize(sections: Selection, locks: RegionId[], seed: number): Selection {\r\n  let state = seed >>> 0;\r\n  const next = { ...sections };\r\n  for (const { id } of REGIONS) {\r\n    state = (Math.imul(state, 1664525) + 1013904223) >>> 0;\r\n    if (!locks.includes(id)) {const choices=PICKER_STYLES.filter(style=>style.id!==sections[id]&&isHandStyleUnlocked(style.id));next[id]=choices[state%choices.length].id;}\r\n  }\r\n  return next;\r\n}\r\nexport const emptyLocks: RegionId[] = [];\r\nexport const initialSelection: Selection = { ...DEFAULT_SELECTION };\r\n","handborne/source/app/scale-patterns.ts":"export const SCALE_PATTERNS = [\r\n  {id:'none',name:'Off'},\r\n  {id:'round',name:'Round'},\r\n  {id:'diamond',name:'Diamond'},\r\n  {id:'hex',name:'Hex'},\r\n  {id:'shield',name:'Shield'},\r\n] as const;\r\nexport type ScalePattern = typeof SCALE_PATTERNS[number]['id'];\r\nexport function validateScalePattern(value:unknown):ScalePattern {\r\n  if(typeof value!=='string'||!SCALE_PATTERNS.some(s=>s.id===value))throw new Error('Choose Off, Round, Diamond, Hex or Shield scales.');\r\n  return value as ScalePattern;\r\n}\r\n","handborne/source/app/scales.ts":"import * as THREE from 'three';\r\nimport { validateScalePattern, type ScalePattern } from './scale-patterns.ts';\r\n\r\ntype Point = [number,number];\r\nconst outlines:Record<Exclude<ScalePattern,'none'>,Point[]>={\r\n  round:Array.from({length:12},(_,i)=>[Math.cos(i*Math.PI/6),Math.sin(i*Math.PI/6)*1.08]),\r\n  diamond:[[0,1.25],[-.87,0],[0,-1.25],[.87,0]],\r\n  hex:Array.from({length:6},(_,i)=>[Math.cos(i*Math.PI/3),Math.sin(i*Math.PI/3)]),\r\n  shield:[[0,1.35],[-.88,.30],[-.88,-.65],[-.55,-.95],[.55,-.95],[.88,-.65],[.88,.30]],\r\n};\r\n\r\n/** Sample a staggered lattice on each surface, then add real, separately rooted plates.\r\n * Source meshes and their shared geometry/materials are never modified.\r\n * The same routine is used for the live hand and its GLB/OBJ exports. */\r\nexport function addHandScales(group:THREE.Group,value:string='none') {\r\n  const pattern=validateScalePattern(value);group.userData.scale_pattern=pattern;\r\n  if(pattern==='none')return;\r\n  group.updateMatrixWorld(true);\r\n  const sources:THREE.Mesh[]=[];\r\n  group.traverse(o=>{\r\n    if(!(o instanceof THREE.Mesh)||o.userData.region==='nails'||o.userData.trapped_bubble||o.geometry.hasAttribute('_fur_root')||o.userData.surface_pattern)return;\r\n    if(String(o.userData.source_part??'').endsWith('_sculpt')||o.userData.structure_piece)sources.push(o);\r\n  });\r\n  // One spatial hash across module boundaries avoids double-stamping their seams.\r\n  const occupied=new Map<string,THREE.Vector3[]>(),cell=.0024;\r\n  const accept=(p:THREE.Vector3,distance:number)=>{\r\n    const x=Math.floor(p.x/cell),y=Math.floor(p.y/cell),z=Math.floor(p.z/cell),range=Math.ceil(distance/cell);\r\n    for(let dx=-range;dx<=range;dx++)for(let dy=-range;dy<=range;dy++)for(let dz=-range;dz<=range;dz++){\r\n      const near=occupied.get(`${x+dx},${y+dy},${z+dz}`);\r\n      if(near?.some(other=>other.distanceToSquared(p)<distance*distance))return false;\r\n    }\r\n    const key=`${x},${y},${z}`;if(!occupied.has(key))occupied.set(key,[]);occupied.get(key)!.push(p.clone());return true;\r\n  };\r\n  for(const source of sources){\r\n    if(!source.parent)continue;\r\n    const geometry=source.geometry,position=geometry.getAttribute('position'),normal=geometry.getAttribute('normal'),uv=geometry.getAttribute('uv'),index=geometry.index;\r\n    if(!position||!normal)continue;\r\n    const small=source.userData.rig_profile==='baby',spacing=small?.0031:.0056,rowHeight=spacing*.87;\r\n    const radius=spacing*.49,height=spacing*(pattern==='round'?.15:pattern==='hex'?.20:pattern==='diamond'?.24:.28);\r\n    const inverse=source.parent.matrixWorld.clone().invert(),worldNormal=new THREE.Matrix3().getNormalMatrix(source.matrixWorld);\r\n    const vertices: number[]=[],roots:number[]=[],uvs:number[]=[],indices:number[]=[];\r\n    const a=new THREE.Vector3(),b=new THREE.Vector3(),c=new THREE.Vector3(),face=new THREE.Vector3(),edge=new THREE.Vector3();\r\n    const point=new THREE.Vector3(),n=new THREE.Vector3(),na=new THREE.Vector3(),nb=new THREE.Vector3(),nc=new THREE.Vector3();\r\n    const forward=new THREE.Vector3(),side=new THREE.Vector3(),v=new THREE.Vector3(),outline=outlines[pattern];\r\n    let count=0;\r\n    const stamp=(u:number,w:number)=>{\r\n      // Project the finger-length direction onto the surface; fall back at end caps.\r\n      forward.set(0,1,0).addScaledVector(n,-n.y);\r\n      if(forward.lengthSq()<.05)forward.set(0,0,1).addScaledVector(n,-n.z);\r\n      forward.normalize();side.crossVectors(forward,n).normalize();\r\n      const base=vertices.length/3,size=outline.length;\r\n      const vertex=(x:number,y:number,z:number)=>{\r\n        v.copy(point).addScaledVector(side,x*radius).addScaledVector(forward,y*radius).addScaledVector(n,z).applyMatrix4(inverse);\r\n        vertices.push(v.x,v.y,v.z);roots.push(point.x,point.y,point.z);uvs.push(u+x*.012,w+y*.012);\r\n      };\r\n      for(const [x,y]of outline)vertex(x,y,-height*.12);\r\n      const inset=pattern==='round'?.60:pattern==='hex'?.78:pattern==='diamond'?.26:.64;\r\n      for(const [x,y]of outline)vertex(x*inset,y*inset,height*(pattern==='shield'?(.60+.23*y):.78));\r\n      vertex(0,pattern==='shield'?.18:0,height*(pattern==='hex'?.78:1));\r\n      for(let j=0;j<size;j++){\r\n        const k=(j+1)%size;\r\n        indices.push(base+j,base+k,base+size+k,base+j,base+size+k,base+size+j,base+size+j,base+size+k,base+size*2);\r\n      }\r\n      count++;\r\n    };\r\n    const total=index?index.count:position.count;\r\n    for(let triangle=0;triangle<total;triangle+=3){\r\n      const ia=index?index.getX(triangle):triangle,ib=index?index.getX(triangle+1):triangle+1,ic=index?index.getX(triangle+2):triangle+2;\r\n      a.fromBufferAttribute(position,ia).applyMatrix4(source.matrixWorld);b.fromBufferAttribute(position,ib).applyMatrix4(source.matrixWorld);c.fromBufferAttribute(position,ic).applyMatrix4(source.matrixWorld);\r\n      face.subVectors(b,a).cross(edge.subVectors(c,a));\r\n      const abs=[Math.abs(face.x),Math.abs(face.y),Math.abs(face.z)],axis=abs.indexOf(Math.max(...abs));\r\n      // Y is the row coordinate for side faces, keeping plates aligned along fingers.\r\n      const h=axis===0?2:0,k=axis===1?2:1;\r\n      const ax=a.getComponent(h),ay=a.getComponent(k),bx=b.getComponent(h),by=b.getComponent(k),cx=c.getComponent(h),cy=c.getComponent(k);\r\n      const denominator=(by-cy)*(ax-cx)+(cx-bx)*(ay-cy);if(Math.abs(denominator)<1e-15)continue;\r\n      const y0=Math.ceil(Math.min(ay,by,cy)/rowHeight),y1=Math.floor(Math.max(ay,by,cy)/rowHeight);\r\n      for(let row=y0;row<=y1;row++){\r\n        const y=row*rowHeight,offset=(Math.abs(row)%2)*.5;\r\n        const x0=Math.ceil(Math.min(ax,bx,cx)/spacing-offset),x1=Math.floor(Math.max(ax,bx,cx)/spacing-offset);\r\n        for(let col=x0;col<=x1;col++){\r\n          const x=(col+offset)*spacing,wa=((by-cy)*(x-cx)+(cx-bx)*(y-cy))/denominator,wb=((cy-ay)*(x-cx)+(ax-cx)*(y-cy))/denominator,wc=1-wa-wb;\r\n          if(wa<-.00001||wb<-.00001||wc<-.00001)continue;\r\n          point.copy(a).multiplyScalar(wa).addScaledVector(b,wb).addScaledVector(c,wc);\r\n          if(!accept(point,spacing*.55))continue;\r\n          na.fromBufferAttribute(normal,ia);nb.fromBufferAttribute(normal,ib);nc.fromBufferAttribute(normal,ic);\r\n          n.copy(na).multiplyScalar(wa).addScaledVector(nb,wb).addScaledVector(nc,wc).applyNormalMatrix(worldNormal);\r\n          stamp(uv?uv.getX(ia)*wa+uv.getX(ib)*wb+uv.getX(ic)*wc:0,uv?uv.getY(ia)*wa+uv.getY(ib)*wb+uv.getY(ic)*wc:0);\r\n        }\r\n      }\r\n    }\r\n    if(!count)continue;\r\n    const relief=new THREE.BufferGeometry();relief.setAttribute('position',new THREE.Float32BufferAttribute(vertices,3));relief.setAttribute('_surface_root',new THREE.Float32BufferAttribute(roots,3));relief.setAttribute('uv',new THREE.Float32BufferAttribute(uvs,2));relief.setIndex(indices);relief.computeVertexNormals();\r\n    // Flat facets on the angular patterns; rounded scales keep a soft dome.\r\n    let finalGeometry=relief;\r\n    if(pattern!=='round'){finalGeometry=relief.toNonIndexed();finalGeometry.computeVertexNormals();relief.dispose();}\r\n    const mesh=new THREE.Mesh(finalGeometry,Array.isArray(source.material)?source.material[0]:source.material);\r\n    mesh.name=source.name+'_'+pattern+'_scales';mesh.castShadow=true;mesh.receiveShadow=true;\r\n    mesh.userData={region:source.userData.region,rig_profile:source.userData.rig_profile,rig_bone:source.userData.rig_bone,surface_pattern:pattern,scale_count:count,ownedGeometry:true};\r\n    source.parent.add(mesh);\r\n  }\r\n}\r\n","handborne/source/app/style-slider.tsx":"'use client';\r\nimport { Field } from '@base-ui/react/field';\r\nimport { Slider } from '@/components/ui/slider';\r\nimport { STYLES, styleFor,PICKER_STYLES } from './catalog';\r\n\r\nexport function StyleSlider({label,value,onChange,className}:{label:string;value:number;onChange:(value:number)=>void;className?:string}) {\r\n  return <Field.Root>\r\n    <Field.Label className=\"sr-only\">{label} — {styleFor(value).name}</Field.Label>\r\n    <Slider min={1} max={PICKER_STYLES.length} step={1} largeStep={5} value={[Math.max(0,PICKER_STYLES.findIndex(s=>s.id===value))+1]} onValueChange={v=>onChange(PICKER_STYLES[Number(Array.isArray(v)?v[0]:v)-1].id)} className={className} />\r\n  </Field.Root>;\r\n}\r\n","handborne/source/app/swatches.ts":"// Runtime swatch generation (Rank 4): texture pattern previews are small canvases rendered\r\n// from the same procedural surfaceSample() the 3D material uses, cached by family id, never\r\n// shipped as image files. Colour swatches need no canvas at all — a CSS background is enough.\r\nimport {surfaceSample} from './material-language';\r\nimport * as T from 'three';\r\n\r\nconst colored=new Map<string,string>();\r\nexport function surfaceSwatch(id:number,primary:string,secondary:string,accent:string):string{\r\n const key=[id,primary,secondary,accent].join('|');if(colored.has(key))return colored.get(key)!;\r\n const canvas=document.createElement('canvas');canvas.width=canvas.height=80;\r\n const ctx=canvas.getContext('2d');if(!ctx)return '';\r\n const image=ctx.createImageData(80,80),a=new T.Color(secondary),b=new T.Color(primary),c=new T.Color(accent),color=new T.Color();\r\n for(let y=0;y<80;y++)for(let x=0;x<80;x++){\r\n  const sample=surfaceSample(id,x/80,y/80),t=sample.tint;\r\n  color.copy(t<.5?a:b).lerp(t<.5?b:c,t<.5?t*2:(t-.5)*2).convertLinearToSRGB();\r\n  const i=(y*80+x)*4;image.data.set([color.r*255,color.g*255,color.b*255,255],i);\r\n }\r\n ctx.putImageData(image,0,0);const url=canvas.toDataURL();colored.set(key,url);return url;\r\n}\r\n\r\nconst cache = new Map<number, string>();\r\nexport function texturePreviewDataURL(familyId: number, size = 40): string {\r\n const cached = cache.get(familyId); if (cached) return cached;\r\n const canvas = document.createElement('canvas'); canvas.width = canvas.height = size;\r\n const ctx = canvas.getContext('2d'); if (!ctx) return '';\r\n const img = ctx.createImageData(size, size);\r\n for (let y = 0; y < size; y++) for (let x = 0; x < size; x++) {\r\n  const s = surfaceSample(familyId, x / size, y / size), v = Math.round(Math.max(0, Math.min(1, s.height)) * 255), i = (y * size + x) * 4;\r\n  img.data[i] = img.data[i + 1] = img.data[i + 2] = v; img.data[i + 3] = 255;\r\n }\r\n ctx.putImageData(img, 0, 0);\r\n const url = canvas.toDataURL('image/png'); cache.set(familyId, url); return url;\r\n}\r\n","handborne/source/app/unlock-bridge.ts":"import {authFetch,loadLogin} from '../../../auth-client.mjs';\r\nimport {isGranted,currentCosmeticCoach} from '../../../creature/source/creator/unlock-store';\r\nimport {STYLES} from './catalog';\r\nconst allowed=new Set(['https://mominc.online','https://www.mominc.online','https://myr5.mominc.online']);\r\nlet pending=false;\r\nwindow.addEventListener('message',async event=>{\r\n if(event.source!==window.parent||!allowed.has(event.origin)||event.data?.type!=='handborne:unlock-request'||pending)return;\r\n pending=true;\r\n try{\r\n  let account=null;try{if(localStorage.getItem('myr5-login-provider')==='clerk')await loadLogin();const res=await authFetch('/api/account',{guestSkip:true});if(res.ok)account=await res.json();}catch{}\r\n  (globalThis as any).myr5AuthenticatedAccount=account;\r\n  const coach=currentCosmeticCoach(),styles=STYLES.filter(s=>s.id>=57&&s.paletteId&&isGranted('texture',s.paletteId,coach)&&isGranted('palette',s.paletteId,coach)).map(s=>s.id);\r\n  window.parent.postMessage({type:'handborne:unlock-state',styles},event.origin);\r\n }finally{pending=false;}\r\n});\r\n","handborne/source/app/web-tools.ts":"import { REGIONS, STYLES, type RegionId } from './catalog';\r\nimport { validateSelection, designCode, type HandDesign } from './recipe';\r\nimport { POSES, validatePose } from './poses';\r\nimport { DEFAULT_NAIL_SHAPE, NAIL_SHAPES, validateNailShape } from './nails';\r\nimport { SCALE_PATTERNS, validateScalePattern } from './scale-patterns';\r\ntype Tool = {name:string;title:string;description:string;inputSchema:object;annotations:{readOnlyHint:boolean};execute:(input:unknown)=>unknown};\r\nexport function registerHandTools(read:()=>HandDesign, apply:(s:HandDesign)=>Promise<void>) {\r\n  const context=(document as Document & {modelContext?:{registerTool:(tool:Tool,options:{signal:AbortSignal})=>unknown}}).modelContext;\r\n  if(!context?.registerTool) return () => {};\r\n  const lifecycle=new AbortController();\r\n  const tools:Tool[]=[\r\n    {name:'read_hand_recipe',title:'Read hand recipe',description:'Read the six sections, nail shape, raised scales, current pose and restorable recipe.',inputSchema:{type:'object',properties:{},additionalProperties:false},annotations:{readOnlyHint:true},execute:()=>({...read(),code:designCode(read()),styles:STYLES.map(s=>({id:s.id,name:s.name})),poses:POSES.map(p=>({id:p.id,name:p.name})),nailShapes:[{id:DEFAULT_NAIL_SHAPE,name:'Creature default'},...NAIL_SHAPES.map(s=>({id:s.id,name:s.name}))],scalePatterns:SCALE_PATTERNS,regions:REGIONS})},\r\n    {name:'configure_hand_sections',title:'Configure hand sections',description:`Apply all six section styles, preserving the nail shape and current pose. Style IDs are zero-based, 0 through ${Math.max(...STYLES.map(s=>s.id))}.`,inputSchema:{type:'object',properties:{sections:{type:'object',properties:Object.fromEntries(REGIONS.map(r=>[r.id,{type:'integer',minimum:0,maximum:Math.max(...STYLES.map(s=>s.id))}])),required:REGIONS.map(r=>r.id),additionalProperties:false}},required:['sections'],additionalProperties:false},annotations:{readOnlyHint:false},async execute(input){if(!input||typeof input!=='object'||Object.keys(input).some(k=>k!=='sections'))throw new Error('Expected sections.');const sections=validateSelection((input as {sections:Record<RegionId,number>}).sections),next={...read(),sections};await apply(next);return {...next,code:designCode(next)};}},\r\n    {name:'configure_hand_pose',title:'Change hand pose',description:'Pose the visible hand while preserving styles and nails. Automatic posing resumes after 15 seconds if playback is enabled.',inputSchema:{type:'object',properties:{pose:{type:'string',enum:POSES.map(p=>p.id)}},required:['pose'],additionalProperties:false},annotations:{readOnlyHint:false},async execute(input){if(!input||typeof input!=='object'||Object.keys(input).some(k=>k!=='pose'))throw new Error('Expected a pose ID.');const pose=validatePose((input as {pose:unknown}).pose),next={...read(),pose};await apply(next);return {...next,code:designCode(next)};}},\r\n    {name:'configure_nail_shape',title:'Change nail shape',description:'Change the five physical nails while preserving the creature materials and pose.',inputSchema:{type:'object',properties:{nailShape:{type:'string',enum:[DEFAULT_NAIL_SHAPE,...NAIL_SHAPES.map(s=>s.id)]}},required:['nailShape'],additionalProperties:false},annotations:{readOnlyHint:false},async execute(input){if(!input||typeof input!=='object'||Object.keys(input).some(k=>k!=='nailShape'))throw new Error('Expected a nail shape.');const nailShape=validateNailShape((input as {nailShape:unknown}).nailShape),next={...read(),nailShape};await apply(next);return {...next,code:designCode(next)};}},\r\n  ];\r\n  tools.push({name:'configure_scale_pattern',title:'Change raised scales',description:'Add round, diamond, hexagonal or shield-shaped scale geometry across the hand, or turn it off. Keeps hand shape, materials, nails and pose.',inputSchema:{type:'object',properties:{scalePattern:{type:'string',enum:SCALE_PATTERNS.map(s=>s.id)}},required:['scalePattern'],additionalProperties:false},annotations:{readOnlyHint:false},async execute(input){if(!input||typeof input!=='object'||Object.keys(input).some(k=>k!=='scalePattern'))throw new Error('Expected a scale pattern.');const scalePattern=validateScalePattern((input as {scalePattern:unknown}).scalePattern),next={...read(),scalePattern};await apply(next);return {...next,code:designCode(next)};}});\r\n  for(const tool of tools) {try{Promise.resolve(context.registerTool(tool,{signal:lifecycle.signal})).catch(()=>{});}catch{}}\r\n  return ()=>lifecycle.abort();\r\n}\r\n","handborne/source/components/ui/accordion.tsx":"import { Accordion as AccordionPrimitive } from '@base-ui/react/accordion';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronDownIcon, ChevronUpIcon } from 'lucide-react';\r\n\r\nfunction Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {\r\n  return (\r\n    <AccordionPrimitive.Root\r\n      data-slot=\"accordion\"\r\n      className={cn('flex w-full flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {\r\n  return (\r\n    <AccordionPrimitive.Item\r\n      data-slot=\"accordion-item\"\r\n      className={cn('not-last:border-b', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AccordionTrigger({\r\n  className,\r\n  children,\r\n  ...props\r\n}: AccordionPrimitive.Trigger.Props) {\r\n  return (\r\n    <AccordionPrimitive.Header className=\"flex\">\r\n      <AccordionPrimitive.Trigger\r\n        data-slot=\"accordion-trigger\"\r\n        className={cn(\r\n          'focus-visible:ring-ring/50 focus-visible:border-ring focus-visible:after:border-ring **:data-[slot=accordion-trigger-icon]:text-muted-foreground rounded-lg py-2.5 text-left text-sm font-medium hover:underline focus-visible:ring-3 **:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 group/accordion-trigger relative flex flex-1 items-start justify-between border border-transparent transition-all outline-none aria-disabled:pointer-events-none aria-disabled:opacity-50',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n        <ChevronDownIcon\r\n          data-slot=\"accordion-trigger-icon\"\r\n          className=\"pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden\"\r\n        />\r\n        <ChevronUpIcon\r\n          data-slot=\"accordion-trigger-icon\"\r\n          className=\"pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline\"\r\n        />\r\n      </AccordionPrimitive.Trigger>\r\n    </AccordionPrimitive.Header>\r\n  );\r\n}\r\n\r\nfunction AccordionContent({\r\n  className,\r\n  children,\r\n  ...props\r\n}: AccordionPrimitive.Panel.Props) {\r\n  return (\r\n    <AccordionPrimitive.Panel\r\n      data-slot=\"accordion-content\"\r\n      className=\"data-open:animate-accordion-down data-closed:animate-accordion-up text-sm overflow-hidden\"\r\n      {...props}\r\n    >\r\n      <div\r\n        className={cn(\r\n          'pt-0 pb-2.5 h-(--accordion-panel-height) data-ending-style:h-0 data-starting-style:h-0 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4',\r\n          className,\r\n        )}\r\n      >\r\n        {children}\r\n      </div>\r\n    </AccordionPrimitive.Panel>\r\n  );\r\n}\r\n\r\nexport { Accordion, AccordionItem, AccordionTrigger, AccordionContent };\r\n","handborne/source/components/ui/alert-dialog.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { AlertDialog as AlertDialogPrimitive } from '@base-ui/react/alert-dialog';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\n\r\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\r\n  return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />;\r\n}\r\n\r\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\r\n  return (\r\n    <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\r\n  );\r\n}\r\n\r\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\r\n  return (\r\n    <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\r\n  );\r\n}\r\n\r\nfunction AlertDialogOverlay({\r\n  className,\r\n  ...props\r\n}: AlertDialogPrimitive.Backdrop.Props) {\r\n  return (\r\n    <AlertDialogPrimitive.Backdrop\r\n      data-slot=\"alert-dialog-overlay\"\r\n      className={cn(\r\n        'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 isolate z-50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogContent({\r\n  className,\r\n  size = 'default',\r\n  ...props\r\n}: AlertDialogPrimitive.Popup.Props & {\r\n  size?: 'default' | 'sm';\r\n}) {\r\n  return (\r\n    <AlertDialogPortal>\r\n      <AlertDialogOverlay />\r\n      <AlertDialogPrimitive.Popup\r\n        data-slot=\"alert-dialog-content\"\r\n        data-size={size}\r\n        className={cn(\r\n          'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 bg-popover text-popover-foreground ring-foreground/10 gap-4 rounded-xl p-4 ring-1 duration-100 data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-sm group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 outline-none',\r\n          className,\r\n        )}\r\n        {...props}\r\n      />\r\n    </AlertDialogPortal>\r\n  );\r\n}\r\n\r\nfunction AlertDialogHeader({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-dialog-header\"\r\n      className={cn(\r\n        'grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-4 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogFooter({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-dialog-footer\"\r\n      className={cn(\r\n        'bg-muted/50 -mx-4 -mb-4 rounded-b-xl border-t p-4 flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogMedia({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-dialog-media\"\r\n      className={cn(\r\n        \"bg-muted mb-2 inline-flex size-10 items-center justify-center rounded-md sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-6\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogTitle({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\r\n  return (\r\n    <AlertDialogPrimitive.Title\r\n      data-slot=\"alert-dialog-title\"\r\n      className={cn(\r\n        'text-base font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2 cn-font-heading',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogDescription({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\r\n  return (\r\n    <AlertDialogPrimitive.Description\r\n      data-slot=\"alert-dialog-description\"\r\n      className={cn(\r\n        'text-muted-foreground *:[a]:hover:text-foreground text-sm text-balance md:text-pretty *:[a]:underline *:[a]:underline-offset-3',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogAction({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  return (\r\n    <Button\r\n      data-slot=\"alert-dialog-action\"\r\n      className={cn(className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDialogCancel({\r\n  className,\r\n  variant = 'outline',\r\n  size = 'default',\r\n  ...props\r\n}: AlertDialogPrimitive.Close.Props &\r\n  Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>) {\r\n  return (\r\n    <AlertDialogPrimitive.Close\r\n      data-slot=\"alert-dialog-cancel\"\r\n      className={cn(className)}\r\n      render={<Button variant={variant} size={size} />}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  AlertDialog,\r\n  AlertDialogAction,\r\n  AlertDialogCancel,\r\n  AlertDialogContent,\r\n  AlertDialogDescription,\r\n  AlertDialogFooter,\r\n  AlertDialogHeader,\r\n  AlertDialogMedia,\r\n  AlertDialogOverlay,\r\n  AlertDialogPortal,\r\n  AlertDialogTitle,\r\n  AlertDialogTrigger,\r\n};\r\n","handborne/source/components/ui/alert.tsx":"import * as React from 'react';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nconst alertVariants = cva(\r\n  \"group/alert relative grid w-full gap-0.5 rounded-lg border px-2.5 py-2 text-left text-sm has-data-[slot=alert-action]:relative has-data-[slot=alert-action]:pr-18 has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:row-span-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4\",\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-card text-card-foreground',\r\n        destructive:\r\n          'bg-card text-destructive *:data-[slot=alert-description]:text-destructive/90 *:[svg]:text-current',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Alert({\r\n  className,\r\n  variant,\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof alertVariants>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert\"\r\n      role=\"alert\"\r\n      className={cn(alertVariants({ variant }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertTitle({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-title\"\r\n      className={cn(\r\n        'font-medium group-has-[>svg]/alert:col-start-2 [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertDescription({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-description\"\r\n      className={cn(\r\n        'text-sm text-balance text-muted-foreground md:text-pretty [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AlertAction({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"alert-action\"\r\n      className={cn('absolute top-2 right-2', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Alert, AlertTitle, AlertDescription, AlertAction };\r\n","handborne/source/components/ui/aspect-ratio.tsx":"import { cn } from '@/lib/utils';\r\n\r\nfunction AspectRatio({\r\n  ratio,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'> & { ratio: number }) {\r\n  return (\r\n    <div\r\n      data-slot=\"aspect-ratio\"\r\n      style={\r\n        {\r\n          '--ratio': ratio,\r\n        } as React.CSSProperties\r\n      }\r\n      className={cn('relative aspect-(--ratio)', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { AspectRatio };\r\n","handborne/source/components/ui/attachment.tsx":"import * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\n\r\nconst attachmentVariants = cva(\r\n  'rounded-xl w-fit focus-within:ring-1 focus-within:ring-ring/50 group/attachment relative flex max-w-full min-w-0 shrink-0 flex-wrap border bg-card text-card-foreground transition-colors has-[>a,>button]:hover:bg-muted/50 data-[state=error]:border-destructive/30 data-[state=idle]:border-dashed',\r\n  {\r\n    variants: {\r\n      size: {\r\n        default:\r\n          'gap-2 has-data-[slot=attachment-content]:px-2.5 has-data-[slot=attachment-content]:py-2 has-data-[slot=attachment-media]:p-2 text-sm',\r\n        sm: 'gap-2.5 has-data-[slot=attachment-content]:px-2 has-data-[slot=attachment-content]:py-1.5 has-data-[slot=attachment-media]:p-1.5 text-xs',\r\n        xs: 'gap-1.5 has-data-[slot=attachment-content]:px-1.5 has-data-[slot=attachment-content]:py-1 has-data-[slot=attachment-media]:p-1 text-xs rounded-lg',\r\n      },\r\n      orientation: {\r\n        horizontal: 'min-w-40 items-center',\r\n        vertical: 'w-24 has-data-[slot=attachment-content]:w-30 flex-col',\r\n      },\r\n    },\r\n  },\r\n);\r\n\r\nfunction Attachment({\r\n  className,\r\n  state = 'done',\r\n  size = 'default',\r\n  orientation = 'horizontal',\r\n  ...props\r\n}: React.ComponentProps<'div'> &\r\n  VariantProps<typeof attachmentVariants> & {\r\n    state?: 'idle' | 'uploading' | 'processing' | 'error' | 'done';\r\n  }) {\r\n  return (\r\n    <div\r\n      data-slot=\"attachment\"\r\n      data-state={state}\r\n      data-size={size}\r\n      data-orientation={orientation}\r\n      className={cn(attachmentVariants({ size, orientation }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst attachmentMediaVariants = cva(\r\n  \"bg-muted text-foreground w-10 rounded-lg group-data-[size=sm]/attachment:w-8 group-data-[size=xs]/attachment:w-7 group-data-[size=xs]/attachment:rounded-md [&_svg:not([class*='size-'])]:size-4 group-data-[size=xs]/attachment:[&_svg:not([class*='size-'])]:size-3.5 group-data-[orientation=vertical]/attachment:w-full group-data-[orientation=vertical]/attachment:[&_svg:not([class*='size-'])]:size-6 group-data-[orientation=vertical]/attachment:*:data-[slot=spinner]:size-6! relative flex aspect-square shrink-0 items-center justify-center overflow-hidden group-data-[state=error]/attachment:bg-destructive/10 group-data-[state=error]/attachment:text-destructive [&_svg]:pointer-events-none\",\r\n  {\r\n    variants: {\r\n      variant: {\r\n        icon: '',\r\n        image:\r\n          'opacity-60 group-data-[state=idle]/attachment:opacity-100 group-data-[state=done]/attachment:opacity-100 *:[img]:aspect-square *:[img]:w-full *:[img]:object-cover',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'icon',\r\n    },\r\n  },\r\n);\r\n\r\nfunction AttachmentMedia({\r\n  className,\r\n  variant = 'icon',\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof attachmentMediaVariants>) {\r\n  return (\r\n    <div\r\n      data-slot=\"attachment-media\"\r\n      data-variant={variant}\r\n      className={cn(attachmentMediaVariants({ variant }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"attachment-content\"\r\n      className={cn(\r\n        'leading-tight group-data-[orientation=vertical]/attachment:px-1 max-w-full min-w-0 flex-1',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentTitle({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"attachment-title\"\r\n      className={cn(\r\n        'font-medium block max-w-full min-w-0 truncate group-data-[state=processing]/attachment:shimmer group-data-[state=uploading]/attachment:shimmer',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentDescription({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"attachment-description\"\r\n      className={cn(\r\n        'mt-0.5 text-xs block min-w-0 truncate text-muted-foreground group-data-[state=error]/attachment:text-destructive/80',\r\n        'max-w-full',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentActions({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"attachment-actions\"\r\n      className={cn(\r\n        'group-data-[orientation=vertical]/attachment:absolute group-data-[orientation=vertical]/attachment:top-3 group-data-[orientation=vertical]/attachment:right-3 relative z-20 group-data-[orientation=vertical]/attachment:gap-1 flex shrink-0 items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentAction({\r\n  className,\r\n  variant,\r\n  size = 'icon-xs',\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  return (\r\n    <Button\r\n      data-slot=\"attachment-action\"\r\n      variant={variant ?? 'ghost'}\r\n      size={size}\r\n      className={cn(className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AttachmentTrigger({\r\n  className,\r\n  render,\r\n  type,\r\n  ...props\r\n}: useRender.ComponentProps<'button'>) {\r\n  return useRender({\r\n    defaultTagName: 'button',\r\n    props: mergeProps<'button'>(\r\n      {\r\n        type: render ? type : (type ?? 'button'),\r\n        className: cn('absolute inset-0 z-10 outline-none', className),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'attachment-trigger',\r\n    },\r\n  });\r\n}\r\n\r\nfunction AttachmentGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"attachment-group\"\r\n      className={cn(\r\n        'gap-3 scroll-px-1 py-1 flex min-w-0 scroll-fade-x snap-x snap-mandatory scrollbar-none overflow-x-auto overscroll-x-contain *:data-[slot=attachment]:flex-none *:data-[slot=attachment]:snap-start',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Attachment,\r\n  AttachmentGroup,\r\n  AttachmentMedia,\r\n  AttachmentContent,\r\n  AttachmentTitle,\r\n  AttachmentDescription,\r\n  AttachmentActions,\r\n  AttachmentAction,\r\n  AttachmentTrigger,\r\n};\r\n","handborne/source/components/ui/avatar.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Avatar as AvatarPrimitive } from '@base-ui/react/avatar';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Avatar({\r\n  className,\r\n  size = 'default',\r\n  ...props\r\n}: AvatarPrimitive.Root.Props & {\r\n  size?: 'default' | 'sm' | 'lg';\r\n}) {\r\n  return (\r\n    <AvatarPrimitive.Root\r\n      data-slot=\"avatar\"\r\n      data-size={size}\r\n      className={cn(\r\n        'size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {\r\n  return (\r\n    <AvatarPrimitive.Image\r\n      data-slot=\"avatar-image\"\r\n      className={cn(\r\n        'rounded-full aspect-square size-full object-cover',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AvatarFallback({\r\n  className,\r\n  ...props\r\n}: AvatarPrimitive.Fallback.Props) {\r\n  return (\r\n    <AvatarPrimitive.Fallback\r\n      data-slot=\"avatar-fallback\"\r\n      className={cn(\r\n        'bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AvatarBadge({ className, ...props }: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"avatar-badge\"\r\n      className={cn(\r\n        'bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none',\r\n        'group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden',\r\n        'group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2',\r\n        'group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AvatarGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"avatar-group\"\r\n      className={cn(\r\n        'group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction AvatarGroupCount({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"avatar-group-count\"\r\n      className={cn(\r\n        'bg-muted text-muted-foreground size-8 rounded-full text-sm group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 relative flex shrink-0 items-center justify-center ring-2 ring-background',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Avatar,\r\n  AvatarImage,\r\n  AvatarFallback,\r\n  AvatarGroup,\r\n  AvatarGroupCount,\r\n  AvatarBadge,\r\n};\r\n","handborne/source/components/ui/badge.tsx":"import { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nconst badgeVariants = cva(\r\n  'group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-primary text-primary-foreground [a]:hover:bg-primary/80',\r\n        secondary:\r\n          'bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80',\r\n        destructive:\r\n          'bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20',\r\n        outline:\r\n          'border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground',\r\n        ghost:\r\n          'hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50',\r\n        link: 'text-primary underline-offset-4 hover:underline',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Badge({\r\n  className,\r\n  variant = 'default',\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'span'> & VariantProps<typeof badgeVariants>) {\r\n  return useRender({\r\n    defaultTagName: 'span',\r\n    props: mergeProps<'span'>(\r\n      {\r\n        className: cn(badgeVariants({ variant }), className),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'badge',\r\n      variant,\r\n    },\r\n  });\r\n}\r\n\r\nexport { Badge, badgeVariants };\r\n","handborne/source/components/ui/breadcrumb.tsx":"import * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronRightIcon, MoreHorizontalIcon } from 'lucide-react';\r\n\r\nfunction Breadcrumb({ className, ...props }: React.ComponentProps<'nav'>) {\r\n  return (\r\n    <nav\r\n      aria-label=\"breadcrumb\"\r\n      data-slot=\"breadcrumb\"\r\n      className={cn(className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction BreadcrumbList({ className, ...props }: React.ComponentProps<'ol'>) {\r\n  return (\r\n    <ol\r\n      data-slot=\"breadcrumb-list\"\r\n      className={cn(\r\n        'text-muted-foreground gap-1.5 text-sm flex flex-wrap items-center wrap-break-word',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction BreadcrumbItem({ className, ...props }: React.ComponentProps<'li'>) {\r\n  return (\r\n    <li\r\n      data-slot=\"breadcrumb-item\"\r\n      className={cn('gap-1 inline-flex items-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction BreadcrumbLink({\r\n  className,\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'a'>) {\r\n  return useRender({\r\n    defaultTagName: 'a',\r\n    props: mergeProps<'a'>(\r\n      {\r\n        className: cn('hover:text-foreground transition-colors', className),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'breadcrumb-link',\r\n    },\r\n  });\r\n}\r\n\r\nfunction BreadcrumbPage({ className, ...props }: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"breadcrumb-page\"\r\n      role=\"link\"\r\n      aria-disabled=\"true\"\r\n      aria-current=\"page\"\r\n      className={cn('text-foreground font-normal', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction BreadcrumbSeparator({\r\n  children,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'li'>) {\r\n  return (\r\n    <li\r\n      data-slot=\"breadcrumb-separator\"\r\n      role=\"presentation\"\r\n      aria-hidden=\"true\"\r\n      className={cn('[&>svg]:size-3.5', className)}\r\n      {...props}\r\n    >\r\n      {children ?? <ChevronRightIcon className=\"cn-rtl-flip\" />}\r\n    </li>\r\n  );\r\n}\r\n\r\nfunction BreadcrumbEllipsis({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"breadcrumb-ellipsis\"\r\n      role=\"presentation\"\r\n      aria-hidden=\"true\"\r\n      className={cn(\r\n        'size-5 [&>svg]:size-4 flex items-center justify-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <MoreHorizontalIcon />\r\n      <span className=\"sr-only\">More</span>\r\n    </span>\r\n  );\r\n}\r\n\r\nexport {\r\n  Breadcrumb,\r\n  BreadcrumbList,\r\n  BreadcrumbItem,\r\n  BreadcrumbLink,\r\n  BreadcrumbPage,\r\n  BreadcrumbSeparator,\r\n  BreadcrumbEllipsis,\r\n};\r\n","handborne/source/components/ui/bubble.tsx":"import * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction BubbleGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"bubble-group\"\r\n      className={cn('gap-2 flex min-w-0 flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst bubbleVariants = cva(\r\n  'gap-1 data-[align=end]:self-end max-w-[80%] data-[variant=ghost]:max-w-full group-data-[align=end]/message:self-end group/bubble relative flex w-fit min-w-0 flex-col',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default:\r\n          '*:data-[slot=bubble-content]:bg-primary *:data-[slot=bubble-content]:text-primary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-primary/80',\r\n        secondary:\r\n          '*:data-[slot=bubble-content]:bg-secondary *:data-[slot=bubble-content]:text-secondary-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)]',\r\n        muted:\r\n          '*:data-[slot=bubble-content]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[color-mix(in_oklch,var(--muted),var(--foreground)_5%)]',\r\n        tinted:\r\n          '*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.93_calc(c*0.4)_h)] dark:*:data-[slot=bubble-content]:bg-[oklch(from_var(--primary)_0.3_calc(c*0.4)_h)] *:data-[slot=bubble-content]:text-foreground [&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.88_calc(c*0.5)_h)] dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-[oklch(from_var(--primary)_0.35_calc(c*0.5)_h)]',\r\n        outline:\r\n          '*:data-[slot=bubble-content]:bg-background *:data-[slot=bubble-content]:border-border [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-input/30',\r\n        ghost:\r\n          '*:data-[slot=bubble-content]:rounded-none *:data-[slot=bubble-content]:bg-transparent *:data-[slot=bubble-content]:p-0 [&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted [&>[data-slot=bubble-content]:is(button,a):hover]:text-foreground dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-muted/50 border-none',\r\n        destructive:\r\n          '*:data-[slot=bubble-content]:bg-destructive/10 dark:*:data-[slot=bubble-content]:bg-destructive/20 *:data-[slot=bubble-content]:text-destructive [&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/20 dark:[&>[data-slot=bubble-content]:is(button,a):hover]:bg-destructive/30',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Bubble({\r\n  variant = 'default',\r\n  align = 'start',\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'> &\r\n  VariantProps<typeof bubbleVariants> & {\r\n    align?: 'start' | 'end';\r\n  }) {\r\n  return (\r\n    <div\r\n      data-slot=\"bubble\"\r\n      data-variant={variant}\r\n      data-align={align}\r\n      className={cn(bubbleVariants({ variant }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction BubbleContent({\r\n  className,\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'div'>) {\r\n  return useRender({\r\n    defaultTagName: 'div',\r\n    props: mergeProps<'div'>(\r\n      {\r\n        className: cn(\r\n          'rounded-xl border border-transparent px-3 py-2 text-sm leading-relaxed [button,a]:outline-none [button,a]:focus-visible:border-ring [button,a]:focus-visible:ring-3 [button,a]:focus-visible:ring-ring/50 group-data-[align=end]/bubble:self-end w-fit max-w-full min-w-0 overflow-hidden wrap-break-word [button]:text-left [button,a]:transition-colors',\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'bubble-content',\r\n    },\r\n  });\r\n}\r\n\r\nconst bubbleReactionsVariants = cva(\r\n  'rounded-full ring-3 ring-card bg-muted shrink-0 gap-1 px-1.5 py-0.5 has-[button]:p-0 text-sm absolute z-10 flex w-fit items-center justify-center',\r\n  {\r\n    variants: {\r\n      side: {\r\n        top: 'top-0 -translate-y-3/4',\r\n        bottom: 'bottom-0 translate-y-3/4',\r\n      },\r\n      align: {\r\n        start: 'left-3',\r\n        end: 'right-3',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      side: 'bottom',\r\n      align: 'end',\r\n    },\r\n  },\r\n);\r\n\r\nfunction BubbleReactions({\r\n  side = 'bottom',\r\n  align = 'end',\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  align?: 'start' | 'end';\r\n  side?: 'top' | 'bottom';\r\n}) {\r\n  return (\r\n    <div\r\n      data-slot=\"bubble-reactions\"\r\n      data-align={align}\r\n      data-side={side}\r\n      className={cn(bubbleReactionsVariants({ side, align }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { BubbleGroup, Bubble, BubbleContent, BubbleReactions };\r\n","handborne/source/components/ui/button-group.tsx":"import { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Separator } from '@/components/ui/separator';\r\n\r\nconst buttonGroupVariants = cva(\r\n  \"has-[>[data-slot=button-group]]:gap-2 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-lg flex w-fit items-stretch *:focus-visible:relative *:focus-visible:z-10 [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1\",\r\n  {\r\n    variants: {\r\n      orientation: {\r\n        horizontal:\r\n          '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-r-lg! *:data-slot:rounded-r-none [&>[data-slot]~[data-slot]]:rounded-l-none [&>[data-slot]~[data-slot]]:border-l-0',\r\n        vertical:\r\n          '[&>[data-slot]:not(:has(~[data-slot]))]:rounded-b-lg! flex-col *:data-slot:rounded-b-none [&>[data-slot]~[data-slot]]:rounded-t-none [&>[data-slot]~[data-slot]]:border-t-0',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      orientation: 'horizontal',\r\n    },\r\n  },\r\n);\r\n\r\nfunction ButtonGroup({\r\n  className,\r\n  orientation,\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof buttonGroupVariants>) {\r\n  return (\r\n    <div\r\n      role=\"group\"\r\n      data-slot=\"button-group\"\r\n      data-orientation={orientation}\r\n      className={cn(buttonGroupVariants({ orientation }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ButtonGroupText({\r\n  className,\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'div'>) {\r\n  return useRender({\r\n    defaultTagName: 'div',\r\n    props: mergeProps<'div'>(\r\n      {\r\n        className: cn(\r\n          \"bg-muted gap-2 rounded-lg border px-2.5 text-sm font-medium [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none\",\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'button-group-text',\r\n    },\r\n  });\r\n}\r\n\r\nfunction ButtonGroupSeparator({\r\n  className,\r\n  orientation = 'vertical',\r\n  ...props\r\n}: React.ComponentProps<typeof Separator>) {\r\n  return (\r\n    <Separator\r\n      data-slot=\"button-group-separator\"\r\n      orientation={orientation}\r\n      className={cn(\r\n        'bg-input relative self-stretch data-horizontal:mx-px data-horizontal:w-auto data-vertical:my-px data-vertical:h-auto',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  ButtonGroup,\r\n  ButtonGroupSeparator,\r\n  ButtonGroupText,\r\n  buttonGroupVariants,\r\n};\r\n","handborne/source/components/ui/button.tsx":"import { Button as ButtonPrimitive } from '@base-ui/react/button';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nconst buttonVariants = cva(\r\n  \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-primary text-primary-foreground hover:bg-primary/80',\r\n        outline:\r\n          'border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50',\r\n        secondary:\r\n          'bg-secondary text-secondary-foreground hover:bg-[color-mix(in_oklch,var(--secondary),var(--foreground)_5%)] aria-expanded:bg-secondary aria-expanded:text-secondary-foreground',\r\n        ghost:\r\n          'hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50',\r\n        destructive:\r\n          'bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40',\r\n        link: 'text-primary underline-offset-4 hover:underline',\r\n      },\r\n      size: {\r\n        default:\r\n          'h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\r\n        xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\r\n        sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\r\n        lg: 'h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\r\n        icon: 'size-8',\r\n        'icon-xs':\r\n          \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\r\n        'icon-sm':\r\n          'size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg',\r\n        'icon-lg': 'size-9',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n      size: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Button({\r\n  className,\r\n  variant = 'default',\r\n  size = 'default',\r\n  ...props\r\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\r\n  return (\r\n    <ButtonPrimitive\r\n      data-slot=\"button\"\r\n      className={cn(buttonVariants({ variant, size, className }))}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Button, buttonVariants };\r\n","handborne/source/components/ui/calendar.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport {\r\n  DayPicker,\r\n  getDefaultClassNames,\r\n  type DayButton,\r\n  type Locale,\r\n} from 'react-day-picker';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button, buttonVariants } from '@/components/ui/button';\r\nimport {\r\n  ChevronLeftIcon,\r\n  ChevronRightIcon,\r\n  ChevronDownIcon,\r\n} from 'lucide-react';\r\n\r\nfunction Calendar({\r\n  className,\r\n  classNames,\r\n  showOutsideDays = true,\r\n  captionLayout = 'label',\r\n  buttonVariant = 'ghost',\r\n  locale,\r\n  formatters,\r\n  components,\r\n  ...props\r\n}: React.ComponentProps<typeof DayPicker> & {\r\n  buttonVariant?: React.ComponentProps<typeof Button>['variant'];\r\n}) {\r\n  const defaultClassNames = getDefaultClassNames();\r\n\r\n  return (\r\n    <DayPicker\r\n      showOutsideDays={showOutsideDays}\r\n      className={cn(\r\n        'p-2 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(7)] group/calendar bg-background in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent',\r\n        String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\r\n        String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\r\n        className,\r\n      )}\r\n      captionLayout={captionLayout}\r\n      locale={locale}\r\n      formatters={{\r\n        formatMonthDropdown: (date) =>\r\n          date.toLocaleString(locale?.code, { month: 'short' }),\r\n        ...formatters,\r\n      }}\r\n      classNames={{\r\n        root: cn('w-fit', defaultClassNames.root),\r\n        months: cn(\r\n          'relative flex flex-col gap-4 md:flex-row',\r\n          defaultClassNames.months,\r\n        ),\r\n        month: cn('flex w-full flex-col gap-4', defaultClassNames.month),\r\n        nav: cn(\r\n          'absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1',\r\n          defaultClassNames.nav,\r\n        ),\r\n        button_previous: cn(\r\n          buttonVariants({ variant: buttonVariant }),\r\n          'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',\r\n          defaultClassNames.button_previous,\r\n        ),\r\n        button_next: cn(\r\n          buttonVariants({ variant: buttonVariant }),\r\n          'size-(--cell-size) p-0 select-none aria-disabled:opacity-50',\r\n          defaultClassNames.button_next,\r\n        ),\r\n        month_caption: cn(\r\n          'flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)',\r\n          defaultClassNames.month_caption,\r\n        ),\r\n        dropdowns: cn(\r\n          'flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium',\r\n          defaultClassNames.dropdowns,\r\n        ),\r\n        dropdown_root: cn(\r\n          'cn-calendar-dropdown-root relative rounded-(--cell-radius)',\r\n          defaultClassNames.dropdown_root,\r\n        ),\r\n        dropdown: cn(\r\n          'absolute inset-0 bg-popover opacity-0',\r\n          defaultClassNames.dropdown,\r\n        ),\r\n        caption_label: cn(\r\n          'font-medium select-none',\r\n          captionLayout === 'label'\r\n            ? 'cn-calendar-caption text-sm'\r\n            : 'cn-calendar-caption-label flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground',\r\n          defaultClassNames.caption_label,\r\n        ),\r\n        month_grid: cn('w-full border-collapse', defaultClassNames.month_grid),\r\n        weekdays: cn('flex', defaultClassNames.weekdays),\r\n        weekday: cn(\r\n          'flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none',\r\n          defaultClassNames.weekday,\r\n        ),\r\n        week: cn('mt-2 flex w-full', defaultClassNames.week),\r\n        week_number_header: cn(\r\n          'w-(--cell-size) select-none',\r\n          defaultClassNames.week_number_header,\r\n        ),\r\n        week_number: cn(\r\n          'text-[0.8rem] text-muted-foreground select-none',\r\n          defaultClassNames.week_number,\r\n        ),\r\n        day: cn(\r\n          'group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)',\r\n          props.showWeekNumber\r\n            ? '[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)'\r\n            : '[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)',\r\n          defaultClassNames.day,\r\n        ),\r\n        range_start: cn(\r\n          'relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted',\r\n          defaultClassNames.range_start,\r\n        ),\r\n        range_middle: cn('rounded-none', defaultClassNames.range_middle),\r\n        range_end: cn(\r\n          'relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted',\r\n          defaultClassNames.range_end,\r\n        ),\r\n        today: cn(\r\n          'rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none',\r\n          defaultClassNames.today,\r\n        ),\r\n        outside: cn(\r\n          'text-muted-foreground aria-selected:text-muted-foreground',\r\n          defaultClassNames.outside,\r\n        ),\r\n        disabled: cn(\r\n          'text-muted-foreground opacity-50',\r\n          defaultClassNames.disabled,\r\n        ),\r\n        hidden: cn('invisible', defaultClassNames.hidden),\r\n        ...classNames,\r\n      }}\r\n      components={{\r\n        Root: ({ className, rootRef, ...props }) => {\r\n          return (\r\n            <div\r\n              data-slot=\"calendar\"\r\n              ref={rootRef}\r\n              className={cn(className)}\r\n              {...props}\r\n            />\r\n          );\r\n        },\r\n        Chevron: ({ className, orientation, ...props }) => {\r\n          if (orientation === 'left') {\r\n            return (\r\n              <ChevronLeftIcon\r\n                className={cn('cn-rtl-flip size-4', className)}\r\n                {...props}\r\n              />\r\n            );\r\n          }\r\n\r\n          if (orientation === 'right') {\r\n            return (\r\n              <ChevronRightIcon\r\n                className={cn('cn-rtl-flip size-4', className)}\r\n                {...props}\r\n              />\r\n            );\r\n          }\r\n\r\n          return (\r\n            <ChevronDownIcon className={cn('size-4', className)} {...props} />\r\n          );\r\n        },\r\n        DayButton: ({ ...props }) => (\r\n          <CalendarDayButton locale={locale} {...props} />\r\n        ),\r\n        WeekNumber: ({ children, ...props }) => {\r\n          return (\r\n            <td {...props}>\r\n              <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\r\n                {children}\r\n              </div>\r\n            </td>\r\n          );\r\n        },\r\n        ...components,\r\n      }}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CalendarDayButton({\r\n  className,\r\n  day,\r\n  modifiers,\r\n  locale,\r\n  ...props\r\n}: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {\r\n  const defaultClassNames = getDefaultClassNames();\r\n\r\n  const ref = React.useRef<HTMLButtonElement>(null);\r\n  React.useEffect(() => {\r\n    if (modifiers.focused) ref.current?.focus();\r\n  }, [modifiers.focused]);\r\n\r\n  return (\r\n    <Button\r\n      variant=\"ghost\"\r\n      size=\"icon\"\r\n      data-day={day.date.toLocaleDateString(locale?.code)}\r\n      data-selected-single={\r\n        modifiers.selected &&\r\n        !modifiers.range_start &&\r\n        !modifiers.range_end &&\r\n        !modifiers.range_middle\r\n      }\r\n      data-range-start={modifiers.range_start}\r\n      data-range-end={modifiers.range_end}\r\n      data-range-middle={modifiers.range_middle}\r\n      className={cn(\r\n        'relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70',\r\n        defaultClassNames.day,\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Calendar, CalendarDayButton };\r\n","handborne/source/components/ui/card.tsx":"import * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Card({\r\n  className,\r\n  size = 'default',\r\n  ...props\r\n}: React.ComponentProps<'div'> & { size?: 'default' | 'sm' }) {\r\n  return (\r\n    <div\r\n      data-slot=\"card\"\r\n      data-size={size}\r\n      className={cn(\r\n        'group/card flex flex-col gap-(--card-spacing) overflow-hidden rounded-xl bg-card py-(--card-spacing) text-sm text-card-foreground ring-1 ring-foreground/10 [--card-spacing:--spacing(4)] has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:[--card-spacing:--spacing(3)] data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-header\"\r\n      className={cn(\r\n        'group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-(--card-spacing) has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-(--card-spacing)',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-title\"\r\n      className={cn(\r\n        'font-heading text-base leading-snug font-medium group-data-[size=sm]/card:text-sm',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-description\"\r\n      className={cn('text-sm text-muted-foreground', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardAction({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-action\"\r\n      className={cn(\r\n        'col-start-2 row-span-2 row-start-1 self-start justify-self-end',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-content\"\r\n      className={cn('px-(--card-spacing)', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"card-footer\"\r\n      className={cn(\r\n        'flex items-center rounded-b-xl border-t bg-muted/50 p-(--card-spacing)',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Card,\r\n  CardHeader,\r\n  CardFooter,\r\n  CardTitle,\r\n  CardAction,\r\n  CardDescription,\r\n  CardContent,\r\n};\r\n","handborne/source/components/ui/carousel.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport useEmblaCarousel, {\r\n  type UseEmblaCarouselType,\r\n} from 'embla-carousel-react';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { ChevronLeftIcon, ChevronRightIcon } from 'lucide-react';\r\n\r\ntype CarouselApi = UseEmblaCarouselType[1];\r\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\r\ntype CarouselOptions = UseCarouselParameters[0];\r\ntype CarouselPlugin = UseCarouselParameters[1];\r\n\r\ntype CarouselProps = {\r\n  opts?: CarouselOptions;\r\n  plugins?: CarouselPlugin;\r\n  orientation?: 'horizontal' | 'vertical';\r\n  setApi?: (api: CarouselApi) => void;\r\n};\r\n\r\ntype CarouselContextProps = {\r\n  carouselRef: ReturnType<typeof useEmblaCarousel>[0];\r\n  api: ReturnType<typeof useEmblaCarousel>[1];\r\n  scrollPrev: () => void;\r\n  scrollNext: () => void;\r\n  canScrollPrev: boolean;\r\n  canScrollNext: boolean;\r\n} & CarouselProps;\r\n\r\nconst CarouselContext = React.createContext<CarouselContextProps | null>(null);\r\n\r\nfunction useCarousel() {\r\n  const context = React.useContext(CarouselContext);\r\n\r\n  if (!context) {\r\n    throw new Error('useCarousel must be used within a <Carousel />');\r\n  }\r\n\r\n  return context;\r\n}\r\n\r\nfunction Carousel({\r\n  orientation = 'horizontal',\r\n  opts,\r\n  setApi,\r\n  plugins,\r\n  className,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<'div'> & CarouselProps) {\r\n  const [carouselRef, api] = useEmblaCarousel(\r\n    {\r\n      ...opts,\r\n      axis: orientation === 'horizontal' ? 'x' : 'y',\r\n    },\r\n    plugins,\r\n  );\r\n  const [canScrollPrev, setCanScrollPrev] = React.useState(false);\r\n  const [canScrollNext, setCanScrollNext] = React.useState(false);\r\n\r\n  const onSelect = React.useCallback((api: CarouselApi) => {\r\n    if (!api) return;\r\n    setCanScrollPrev(api.canScrollPrev());\r\n    setCanScrollNext(api.canScrollNext());\r\n  }, []);\r\n\r\n  const scrollPrev = React.useCallback(() => {\r\n    api?.scrollPrev();\r\n  }, [api]);\r\n\r\n  const scrollNext = React.useCallback(() => {\r\n    api?.scrollNext();\r\n  }, [api]);\r\n\r\n  const handleKeyDown = React.useCallback(\r\n    (event: React.KeyboardEvent<HTMLDivElement>) => {\r\n      if (event.key === 'ArrowLeft') {\r\n        event.preventDefault();\r\n        scrollPrev();\r\n      } else if (event.key === 'ArrowRight') {\r\n        event.preventDefault();\r\n        scrollNext();\r\n      }\r\n    },\r\n    [scrollPrev, scrollNext],\r\n  );\r\n\r\n  React.useEffect(() => {\r\n    if (!api || !setApi) return;\r\n    setApi(api);\r\n  }, [api, setApi]);\r\n\r\n  React.useEffect(() => {\r\n    if (!api) return;\r\n    onSelect(api);\r\n    api.on('reInit', onSelect);\r\n    api.on('select', onSelect);\r\n\r\n    return () => {\r\n      api?.off('select', onSelect);\r\n    };\r\n  }, [api, onSelect]);\r\n\r\n  return (\r\n    <CarouselContext.Provider\r\n      value={{\r\n        carouselRef,\r\n        api: api,\r\n        opts,\r\n        orientation:\r\n          orientation || (opts?.axis === 'y' ? 'vertical' : 'horizontal'),\r\n        scrollPrev,\r\n        scrollNext,\r\n        canScrollPrev,\r\n        canScrollNext,\r\n      }}\r\n    >\r\n      <div\r\n        onKeyDownCapture={handleKeyDown}\r\n        className={cn('relative', className)}\r\n        role=\"region\"\r\n        aria-roledescription=\"carousel\"\r\n        data-slot=\"carousel\"\r\n        {...props}\r\n      >\r\n        {children}\r\n      </div>\r\n    </CarouselContext.Provider>\r\n  );\r\n}\r\n\r\nfunction CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  const { carouselRef, orientation } = useCarousel();\r\n\r\n  return (\r\n    <div\r\n      ref={carouselRef}\r\n      className=\"overflow-hidden\"\r\n      data-slot=\"carousel-content\"\r\n    >\r\n      <div\r\n        className={cn(\r\n          'flex',\r\n          orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',\r\n          className,\r\n        )}\r\n        {...props}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {\r\n  const { orientation } = useCarousel();\r\n\r\n  return (\r\n    <div\r\n      role=\"group\"\r\n      aria-roledescription=\"slide\"\r\n      data-slot=\"carousel-item\"\r\n      className={cn(\r\n        'min-w-0 shrink-0 grow-0 basis-full',\r\n        orientation === 'horizontal' ? 'pl-4' : 'pt-4',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CarouselPrevious({\r\n  className,\r\n  variant = 'outline',\r\n  size = 'icon-sm',\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  const { orientation, scrollPrev, canScrollPrev } = useCarousel();\r\n\r\n  return (\r\n    <Button\r\n      data-slot=\"carousel-previous\"\r\n      variant={variant}\r\n      size={size}\r\n      className={cn(\r\n        'rounded-full absolute touch-manipulation',\r\n        orientation === 'horizontal'\r\n          ? 'inset-y-0 -left-12 my-auto'\r\n          : '-top-12 left-1/2 -translate-x-1/2 rotate-90',\r\n        className,\r\n      )}\r\n      disabled={!canScrollPrev}\r\n      onClick={scrollPrev}\r\n      {...props}\r\n    >\r\n      <ChevronLeftIcon className=\"cn-rtl-flip\" />\r\n      <span className=\"sr-only\">Previous slide</span>\r\n    </Button>\r\n  );\r\n}\r\n\r\nfunction CarouselNext({\r\n  className,\r\n  variant = 'outline',\r\n  size = 'icon-sm',\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  const { orientation, scrollNext, canScrollNext } = useCarousel();\r\n\r\n  return (\r\n    <Button\r\n      data-slot=\"carousel-next\"\r\n      variant={variant}\r\n      size={size}\r\n      className={cn(\r\n        'rounded-full absolute touch-manipulation',\r\n        orientation === 'horizontal'\r\n          ? 'inset-y-0 -right-12 my-auto'\r\n          : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',\r\n        className,\r\n      )}\r\n      disabled={!canScrollNext}\r\n      onClick={scrollNext}\r\n      {...props}\r\n    >\r\n      <ChevronRightIcon className=\"cn-rtl-flip\" />\r\n      <span className=\"sr-only\">Next slide</span>\r\n    </Button>\r\n  );\r\n}\r\n\r\nexport {\r\n  type CarouselApi,\r\n  Carousel,\r\n  CarouselContent,\r\n  CarouselItem,\r\n  CarouselPrevious,\r\n  CarouselNext,\r\n  useCarousel,\r\n};\r\n","handborne/source/components/ui/chart.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport * as RechartsPrimitive from 'recharts';\r\nimport type { TooltipValueType } from 'recharts';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\n// Format: { THEME_NAME: CSS_SELECTOR }\r\nconst THEMES = { light: '', dark: '.dark' } as const;\r\n\r\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const;\r\ntype TooltipNameType = number | string;\r\n\r\nexport type ChartConfig = Record<\r\n  string,\r\n  {\r\n    label?: React.ReactNode;\r\n    icon?: React.ComponentType;\r\n  } & (\r\n    | { color?: string; theme?: never }\r\n    | { color?: never; theme: Record<keyof typeof THEMES, string> }\r\n  )\r\n>;\r\n\r\ntype ChartContextProps = {\r\n  config: ChartConfig;\r\n};\r\n\r\nconst ChartContext = React.createContext<ChartContextProps | null>(null);\r\n\r\nfunction useChart() {\r\n  const context = React.useContext(ChartContext);\r\n\r\n  if (!context) {\r\n    throw new Error('useChart must be used within a <ChartContainer />');\r\n  }\r\n\r\n  return context;\r\n}\r\n\r\nfunction ChartContainer({\r\n  id,\r\n  className,\r\n  children,\r\n  config,\r\n  initialDimension = INITIAL_DIMENSION,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  config: ChartConfig;\r\n  children: React.ComponentProps<\r\n    typeof RechartsPrimitive.ResponsiveContainer\r\n  >['children'];\r\n  initialDimension?: {\r\n    width: number;\r\n    height: number;\r\n  };\r\n}) {\r\n  const uniqueId = React.useId();\r\n  const chartId = `chart-${id ?? uniqueId.replace(/:/g, '')}`;\r\n\r\n  return (\r\n    <ChartContext.Provider value={{ config }}>\r\n      <div\r\n        data-slot=\"chart\"\r\n        data-chart={chartId}\r\n        className={cn(\r\n          \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        <ChartStyle id={chartId} config={config} />\r\n        <RechartsPrimitive.ResponsiveContainer\r\n          initialDimension={initialDimension}\r\n        >\r\n          {children}\r\n        </RechartsPrimitive.ResponsiveContainer>\r\n      </div>\r\n    </ChartContext.Provider>\r\n  );\r\n}\r\n\r\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\r\n  const colorConfig = Object.entries(config).filter(\r\n    ([, config]) => config.theme ?? config.color,\r\n  );\r\n\r\n  if (!colorConfig.length) {\r\n    return null;\r\n  }\r\n\r\n  return (\r\n    <style\r\n      dangerouslySetInnerHTML={{\r\n        __html: Object.entries(THEMES)\r\n          .map(\r\n            ([theme, prefix]) => `\r\n${prefix} [data-chart=${id}] {\r\n${colorConfig\r\n  .map(([key, itemConfig]) => {\r\n    const color =\r\n      itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\r\n      itemConfig.color;\r\n    return color ? `  --color-${key}: ${color};` : null;\r\n  })\r\n  .join('\\n')}\r\n}\r\n`,\r\n          )\r\n          .join('\\n'),\r\n      }}\r\n    />\r\n  );\r\n};\r\n\r\nconst ChartTooltip = RechartsPrimitive.Tooltip;\r\n\r\nfunction ChartTooltipContent({\r\n  active,\r\n  payload,\r\n  className,\r\n  indicator = 'dot',\r\n  hideLabel = false,\r\n  hideIndicator = false,\r\n  label,\r\n  labelFormatter,\r\n  labelClassName,\r\n  formatter,\r\n  color,\r\n  nameKey,\r\n  labelKey,\r\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\r\n  React.ComponentProps<'div'> & {\r\n    hideLabel?: boolean;\r\n    hideIndicator?: boolean;\r\n    indicator?: 'line' | 'dot' | 'dashed';\r\n    nameKey?: string;\r\n    labelKey?: string;\r\n  } & Omit<\r\n    RechartsPrimitive.DefaultTooltipContentProps<\r\n      TooltipValueType,\r\n      TooltipNameType\r\n    >,\r\n    'accessibilityLayer'\r\n  >) {\r\n  const { config } = useChart();\r\n\r\n  const tooltipLabel = React.useMemo(() => {\r\n    if (hideLabel || !payload?.length) {\r\n      return null;\r\n    }\r\n\r\n    const [item] = payload;\r\n    const key = `${labelKey ?? item?.dataKey ?? item?.name ?? 'value'}`;\r\n    const itemConfig = getPayloadConfigFromPayload(config, item, key);\r\n    const value =\r\n      !labelKey && typeof label === 'string'\r\n        ? (config[label]?.label ?? label)\r\n        : itemConfig?.label;\r\n\r\n    if (labelFormatter) {\r\n      return (\r\n        <div className={cn('font-medium', labelClassName)}>\r\n          {labelFormatter(value, payload)}\r\n        </div>\r\n      );\r\n    }\r\n\r\n    if (!value) {\r\n      return null;\r\n    }\r\n\r\n    return <div className={cn('font-medium', labelClassName)}>{value}</div>;\r\n  }, [\r\n    label,\r\n    labelFormatter,\r\n    payload,\r\n    hideLabel,\r\n    labelClassName,\r\n    config,\r\n    labelKey,\r\n  ]);\r\n\r\n  if (!active || !payload?.length) {\r\n    return null;\r\n  }\r\n\r\n  const nestLabel = payload.length === 1 && indicator !== 'dot';\r\n\r\n  return (\r\n    <div\r\n      className={cn(\r\n        'border-border/50 bg-background gap-1.5 rounded-lg border px-2.5 py-1.5 text-xs shadow-xl grid min-w-32 items-start',\r\n        className,\r\n      )}\r\n    >\r\n      {!nestLabel ? tooltipLabel : null}\r\n      <div className=\"grid gap-1.5\">\r\n        {payload\r\n          .filter((item) => item.type !== 'none')\r\n          .map((item, index) => {\r\n            const key = `${nameKey ?? item.name ?? item.dataKey ?? 'value'}`;\r\n            const itemConfig = getPayloadConfigFromPayload(config, item, key);\r\n            const indicatorColor = color ?? item.payload?.fill ?? item.color;\r\n\r\n            return (\r\n              <div\r\n                key={index}\r\n                className={cn(\r\n                  'flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground',\r\n                  indicator === 'dot' && 'items-center',\r\n                )}\r\n              >\r\n                {formatter && item?.value !== undefined && item.name ? (\r\n                  formatter(item.value, item.name, item, index, item.payload)\r\n                ) : (\r\n                  <>\r\n                    {itemConfig?.icon ? (\r\n                      <itemConfig.icon />\r\n                    ) : (\r\n                      !hideIndicator && (\r\n                        <div\r\n                          className={cn(\r\n                            'shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)',\r\n                            {\r\n                              'h-2.5 w-2.5': indicator === 'dot',\r\n                              'w-1': indicator === 'line',\r\n                              'w-0 border-[1.5px] border-dashed bg-transparent':\r\n                                indicator === 'dashed',\r\n                              'my-0.5': nestLabel && indicator === 'dashed',\r\n                            },\r\n                          )}\r\n                          style={\r\n                            {\r\n                              '--color-bg': indicatorColor,\r\n                              '--color-border': indicatorColor,\r\n                            } as React.CSSProperties\r\n                          }\r\n                        />\r\n                      )\r\n                    )}\r\n                    <div\r\n                      className={cn(\r\n                        'flex flex-1 justify-between leading-none',\r\n                        nestLabel ? 'items-end' : 'items-center',\r\n                      )}\r\n                    >\r\n                      <div className=\"grid gap-1.5\">\r\n                        {nestLabel ? tooltipLabel : null}\r\n                        <span className=\"text-muted-foreground\">\r\n                          {itemConfig?.label ?? item.name}\r\n                        </span>\r\n                      </div>\r\n                      {item.value != null && (\r\n                        <span className=\"font-mono font-medium text-foreground tabular-nums\">\r\n                          {typeof item.value === 'number'\r\n                            ? item.value.toLocaleString()\r\n                            : String(item.value)}\r\n                        </span>\r\n                      )}\r\n                    </div>\r\n                  </>\r\n                )}\r\n              </div>\r\n            );\r\n          })}\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n\r\nconst ChartLegend = RechartsPrimitive.Legend;\r\n\r\nfunction ChartLegendContent({\r\n  className,\r\n  hideIcon = false,\r\n  payload,\r\n  verticalAlign = 'bottom',\r\n  nameKey,\r\n}: React.ComponentProps<'div'> & {\r\n  hideIcon?: boolean;\r\n  nameKey?: string;\r\n} & RechartsPrimitive.DefaultLegendContentProps) {\r\n  const { config } = useChart();\r\n\r\n  if (!payload?.length) {\r\n    return null;\r\n  }\r\n\r\n  return (\r\n    <div\r\n      className={cn(\r\n        'flex items-center justify-center gap-4',\r\n        verticalAlign === 'top' ? 'pb-3' : 'pt-3',\r\n        className,\r\n      )}\r\n    >\r\n      {payload\r\n        .filter((item) => item.type !== 'none')\r\n        .map((item, index) => {\r\n          const key = `${nameKey ?? item.dataKey ?? 'value'}`;\r\n          const itemConfig = getPayloadConfigFromPayload(config, item, key);\r\n\r\n          return (\r\n            <div\r\n              key={index}\r\n              className={cn(\r\n                'flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground',\r\n              )}\r\n            >\r\n              {itemConfig?.icon && !hideIcon ? (\r\n                <itemConfig.icon />\r\n              ) : (\r\n                <div\r\n                  className=\"h-2 w-2 shrink-0 rounded-[2px]\"\r\n                  style={{\r\n                    backgroundColor: item.color,\r\n                  }}\r\n                />\r\n              )}\r\n              {itemConfig?.label}\r\n            </div>\r\n          );\r\n        })}\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction getPayloadConfigFromPayload(\r\n  config: ChartConfig,\r\n  payload: unknown,\r\n  key: string,\r\n) {\r\n  if (typeof payload !== 'object' || payload === null) {\r\n    return undefined;\r\n  }\r\n\r\n  const payloadPayload =\r\n    'payload' in payload &&\r\n    typeof payload.payload === 'object' &&\r\n    payload.payload !== null\r\n      ? payload.payload\r\n      : undefined;\r\n\r\n  let configLabelKey: string = key;\r\n\r\n  if (\r\n    key in payload &&\r\n    typeof payload[key as keyof typeof payload] === 'string'\r\n  ) {\r\n    configLabelKey = payload[key as keyof typeof payload] as string;\r\n  } else if (\r\n    payloadPayload &&\r\n    key in payloadPayload &&\r\n    typeof payloadPayload[key as keyof typeof payloadPayload] === 'string'\r\n  ) {\r\n    configLabelKey = payloadPayload[\r\n      key as keyof typeof payloadPayload\r\n    ] as string;\r\n  }\r\n\r\n  return configLabelKey in config ? config[configLabelKey] : config[key];\r\n}\r\n\r\nexport {\r\n  ChartContainer,\r\n  ChartTooltip,\r\n  ChartTooltipContent,\r\n  ChartLegend,\r\n  ChartLegendContent,\r\n  ChartStyle,\r\n};\r\n","handborne/source/components/ui/checkbox.tsx":"'use client';\r\n\r\nimport { Checkbox as CheckboxPrimitive } from '@base-ui/react/checkbox';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { CheckIcon } from 'lucide-react';\r\n\r\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\r\n  return (\r\n    <CheckboxPrimitive.Root\r\n      data-slot=\"checkbox\"\r\n      className={cn(\r\n        'peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground group-has-[:focus-visible]/field-label:data-checked:border-primary dark:data-checked:bg-primary',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <CheckboxPrimitive.Indicator\r\n        data-slot=\"checkbox-indicator\"\r\n        className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\r\n      >\r\n        <CheckIcon />\r\n      </CheckboxPrimitive.Indicator>\r\n    </CheckboxPrimitive.Root>\r\n  );\r\n}\r\n\r\nexport { Checkbox };\r\n","handborne/source/components/ui/collapsible.tsx":"'use client';\r\n\r\nimport { Collapsible as CollapsiblePrimitive } from '@base-ui/react/collapsible';\r\n\r\nfunction Collapsible({ ...props }: CollapsiblePrimitive.Root.Props) {\r\n  return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\r\n}\r\n\r\nfunction CollapsibleTrigger({ ...props }: CollapsiblePrimitive.Trigger.Props) {\r\n  return (\r\n    <CollapsiblePrimitive.Trigger data-slot=\"collapsible-trigger\" {...props} />\r\n  );\r\n}\r\n\r\nfunction CollapsibleContent({ ...props }: CollapsiblePrimitive.Panel.Props) {\r\n  return (\r\n    <CollapsiblePrimitive.Panel data-slot=\"collapsible-content\" {...props} />\r\n  );\r\n}\r\n\r\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\r\n","handborne/source/components/ui/combobox.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Combobox as ComboboxPrimitive } from '@base-ui/react';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport {\r\n  InputGroup,\r\n  InputGroupAddon,\r\n  InputGroupButton,\r\n  InputGroupInput,\r\n} from '@/components/ui/input-group';\r\nimport { ChevronDownIcon, XIcon, CheckIcon } from 'lucide-react';\r\n\r\nconst Combobox = ComboboxPrimitive.Root;\r\n\r\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\r\n  return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />;\r\n}\r\n\r\nfunction ComboboxTrigger({\r\n  className,\r\n  children,\r\n  ...props\r\n}: ComboboxPrimitive.Trigger.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Trigger\r\n      data-slot=\"combobox-trigger\"\r\n      className={cn(\"[&_svg:not([class*='size-'])]:size-4\", className)}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <ChevronDownIcon className=\"text-muted-foreground size-4 pointer-events-none\" />\r\n    </ComboboxPrimitive.Trigger>\r\n  );\r\n}\r\n\r\nfunction ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Clear\r\n      data-slot=\"combobox-clear\"\r\n      render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\r\n      className={cn(className)}\r\n      {...props}\r\n    >\r\n      <XIcon className=\"pointer-events-none\" />\r\n    </ComboboxPrimitive.Clear>\r\n  );\r\n}\r\n\r\nfunction ComboboxInput({\r\n  className,\r\n  children,\r\n  disabled = false,\r\n  showTrigger = true,\r\n  showClear = false,\r\n  ...props\r\n}: ComboboxPrimitive.Input.Props & {\r\n  showTrigger?: boolean;\r\n  showClear?: boolean;\r\n}) {\r\n  return (\r\n    <InputGroup className={cn('w-auto', className)}>\r\n      <ComboboxPrimitive.Input\r\n        render={<InputGroupInput disabled={disabled} />}\r\n        {...props}\r\n      />\r\n      <InputGroupAddon align=\"inline-end\">\r\n        {showTrigger && (\r\n          <InputGroupButton\r\n            size=\"icon-xs\"\r\n            variant=\"ghost\"\r\n            render={<ComboboxTrigger />}\r\n            data-slot=\"input-group-button\"\r\n            className=\"group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent\"\r\n            disabled={disabled}\r\n          />\r\n        )}\r\n        {showClear && <ComboboxClear disabled={disabled} />}\r\n      </InputGroupAddon>\r\n      {children}\r\n    </InputGroup>\r\n  );\r\n}\r\n\r\nfunction ComboboxContent({\r\n  className,\r\n  side = 'bottom',\r\n  sideOffset = 6,\r\n  align = 'start',\r\n  alignOffset = 0,\r\n  anchor,\r\n  ...props\r\n}: ComboboxPrimitive.Popup.Props &\r\n  Pick<\r\n    ComboboxPrimitive.Positioner.Props,\r\n    'side' | 'align' | 'sideOffset' | 'alignOffset' | 'anchor'\r\n  >) {\r\n  return (\r\n    <ComboboxPrimitive.Portal>\r\n      <ComboboxPrimitive.Positioner\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        anchor={anchor}\r\n        className=\"isolate z-50\"\r\n      >\r\n        <ComboboxPrimitive.Popup\r\n          data-slot=\"combobox-content\"\r\n          data-chips={!!anchor}\r\n          className={cn(\r\n            'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 overflow-hidden rounded-lg shadow-md ring-1 duration-100 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 cn-menu-target cn-menu-translucent group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) data-[chips=true]:min-w-(--anchor-width)',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n      </ComboboxPrimitive.Positioner>\r\n    </ComboboxPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\r\n  return (\r\n    <ComboboxPrimitive.List\r\n      data-slot=\"combobox-list\"\r\n      className={cn(\r\n        'no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 p-1 data-empty:p-0 overflow-y-auto overscroll-contain',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxItem({\r\n  className,\r\n  children,\r\n  ...props\r\n}: ComboboxPrimitive.Item.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Item\r\n      data-slot=\"combobox-item\"\r\n      className={cn(\r\n        \"data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground gap-2 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <ComboboxPrimitive.ItemIndicator\r\n        render={\r\n          <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\r\n        }\r\n      >\r\n        <CheckIcon className=\"pointer-events-none\" />\r\n      </ComboboxPrimitive.ItemIndicator>\r\n    </ComboboxPrimitive.Item>\r\n  );\r\n}\r\n\r\nfunction ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Group\r\n      data-slot=\"combobox-group\"\r\n      className={cn(className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxLabel({\r\n  className,\r\n  ...props\r\n}: ComboboxPrimitive.GroupLabel.Props) {\r\n  return (\r\n    <ComboboxPrimitive.GroupLabel\r\n      data-slot=\"combobox-label\"\r\n      className={cn('text-muted-foreground px-2 py-1.5 text-xs', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\r\n  );\r\n}\r\n\r\nfunction ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Empty\r\n      data-slot=\"combobox-empty\"\r\n      className={cn(\r\n        'text-muted-foreground hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxSeparator({\r\n  className,\r\n  ...props\r\n}: ComboboxPrimitive.Separator.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Separator\r\n      data-slot=\"combobox-separator\"\r\n      className={cn('bg-border -mx-1 my-1 h-px', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxChips({\r\n  className,\r\n  ...props\r\n}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> &\r\n  ComboboxPrimitive.Chips.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Chips\r\n      data-slot=\"combobox-chips\"\r\n      className={cn(\r\n        'dark:bg-input/30 border-input focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-8 flex-wrap items-center gap-1 rounded-lg border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ComboboxChip({\r\n  className,\r\n  children,\r\n  showRemove = true,\r\n  ...props\r\n}: ComboboxPrimitive.Chip.Props & {\r\n  showRemove?: boolean;\r\n}) {\r\n  return (\r\n    <ComboboxPrimitive.Chip\r\n      data-slot=\"combobox-chip\"\r\n      className={cn(\r\n        'bg-muted text-foreground flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm px-1.5 text-xs font-medium whitespace-nowrap has-data-[slot=combobox-chip-remove]:pr-0 has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      {showRemove && (\r\n        <ComboboxPrimitive.ChipRemove\r\n          render={<Button variant=\"ghost\" size=\"icon-xs\" />}\r\n          className=\"-ml-1 opacity-50 hover:opacity-100\"\r\n          data-slot=\"combobox-chip-remove\"\r\n        >\r\n          <XIcon className=\"pointer-events-none\" />\r\n        </ComboboxPrimitive.ChipRemove>\r\n      )}\r\n    </ComboboxPrimitive.Chip>\r\n  );\r\n}\r\n\r\nfunction ComboboxChipsInput({\r\n  className,\r\n  ...props\r\n}: ComboboxPrimitive.Input.Props) {\r\n  return (\r\n    <ComboboxPrimitive.Input\r\n      data-slot=\"combobox-chip-input\"\r\n      className={cn('min-w-16 flex-1 outline-none', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction useComboboxAnchor() {\r\n  return React.useRef<HTMLDivElement | null>(null);\r\n}\r\n\r\nexport {\r\n  Combobox,\r\n  ComboboxInput,\r\n  ComboboxContent,\r\n  ComboboxList,\r\n  ComboboxItem,\r\n  ComboboxGroup,\r\n  ComboboxLabel,\r\n  ComboboxCollection,\r\n  ComboboxEmpty,\r\n  ComboboxSeparator,\r\n  ComboboxChips,\r\n  ComboboxChip,\r\n  ComboboxChipsInput,\r\n  ComboboxTrigger,\r\n  ComboboxValue,\r\n  useComboboxAnchor,\r\n};\r\n","handborne/source/components/ui/command.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Command as CommandPrimitive } from 'cmdk';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n  Dialog,\r\n  DialogContent,\r\n  DialogDescription,\r\n  DialogHeader,\r\n  DialogTitle,\r\n} from '@/components/ui/dialog';\r\nimport { InputGroup, InputGroupAddon } from '@/components/ui/input-group';\r\nimport { SearchIcon, CheckIcon } from 'lucide-react';\r\n\r\nfunction Command({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive>) {\r\n  return (\r\n    <CommandPrimitive\r\n      data-slot=\"command\"\r\n      className={cn(\r\n        'bg-popover text-popover-foreground rounded-xl! p-1 flex size-full flex-col overflow-hidden',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CommandDialog({\r\n  title = 'Command Palette',\r\n  description = 'Search for a command to run...',\r\n  children,\r\n  className,\r\n  showCloseButton = false,\r\n  ...props\r\n}: Omit<React.ComponentProps<typeof Dialog>, 'children'> & {\r\n  title?: string;\r\n  description?: string;\r\n  className?: string;\r\n  showCloseButton?: boolean;\r\n  children: React.ReactNode;\r\n}) {\r\n  return (\r\n    <Dialog {...props}>\r\n      <DialogHeader className=\"sr-only\">\r\n        <DialogTitle>{title}</DialogTitle>\r\n        <DialogDescription>{description}</DialogDescription>\r\n      </DialogHeader>\r\n      <DialogContent\r\n        className={cn(\r\n          'rounded-xl! top-1/3 translate-y-0 overflow-hidden p-0',\r\n          className,\r\n        )}\r\n        showCloseButton={showCloseButton}\r\n      >\r\n        {children}\r\n      </DialogContent>\r\n    </Dialog>\r\n  );\r\n}\r\n\r\nfunction CommandInput({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\r\n  return (\r\n    <div data-slot=\"command-input-wrapper\" className=\"p-1 pb-0\">\r\n      <InputGroup className=\"bg-input/30 border-input/30 h-8! rounded-lg! shadow-none! *:data-[slot=input-group-addon]:pl-2!\">\r\n        <CommandPrimitive.Input\r\n          data-slot=\"command-input\"\r\n          className={cn(\r\n            'w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n        <InputGroupAddon>\r\n          <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\r\n        </InputGroupAddon>\r\n      </InputGroup>\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction CommandList({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\r\n  return (\r\n    <CommandPrimitive.List\r\n      data-slot=\"command-list\"\r\n      className={cn(\r\n        'no-scrollbar max-h-72 scroll-py-1 outline-none overflow-x-hidden overflow-y-auto',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CommandEmpty({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\r\n  return (\r\n    <CommandPrimitive.Empty\r\n      data-slot=\"command-empty\"\r\n      className={cn('py-6 text-center text-sm', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CommandGroup({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\r\n  return (\r\n    <CommandPrimitive.Group\r\n      data-slot=\"command-group\"\r\n      className={cn(\r\n        'text-foreground **:[[cmdk-group-heading]]:text-muted-foreground overflow-hidden p-1 **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CommandSeparator({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\r\n  return (\r\n    <CommandPrimitive.Separator\r\n      data-slot=\"command-separator\"\r\n      className={cn('bg-border -mx-1 h-px', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction CommandItem({\r\n  className,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\r\n  return (\r\n    <CommandPrimitive.Item\r\n      data-slot=\"command-item\"\r\n      className={cn(\r\n        \"data-selected:bg-muted data-selected:text-foreground data-selected:*:[svg]:text-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! [&_svg:not([class*='size-'])]:size-4 group/command-item data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <CheckIcon className=\"ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100\" />\r\n    </CommandPrimitive.Item>\r\n  );\r\n}\r\n\r\nfunction CommandShortcut({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"command-shortcut\"\r\n      className={cn(\r\n        'text-muted-foreground group-data-selected/command-item:text-foreground ml-auto text-xs tracking-widest',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Command,\r\n  CommandDialog,\r\n  CommandInput,\r\n  CommandList,\r\n  CommandEmpty,\r\n  CommandGroup,\r\n  CommandItem,\r\n  CommandShortcut,\r\n  CommandSeparator,\r\n};\r\n","handborne/source/components/ui/context-menu.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { ContextMenu as ContextMenuPrimitive } from '@base-ui/react/context-menu';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronRightIcon, CheckIcon } from 'lucide-react';\r\n\r\nfunction ContextMenu({ ...props }: ContextMenuPrimitive.Root.Props) {\r\n  return <ContextMenuPrimitive.Root data-slot=\"context-menu\" {...props} />;\r\n}\r\n\r\nfunction ContextMenuPortal({ ...props }: ContextMenuPrimitive.Portal.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.Portal data-slot=\"context-menu-portal\" {...props} />\r\n  );\r\n}\r\n\r\nfunction ContextMenuTrigger({\r\n  className,\r\n  ...props\r\n}: ContextMenuPrimitive.Trigger.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.Trigger\r\n      data-slot=\"context-menu-trigger\"\r\n      className={cn('select-none', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuContent({\r\n  className,\r\n  align = 'start',\r\n  alignOffset = 4,\r\n  side = 'right',\r\n  sideOffset = 0,\r\n  ...props\r\n}: ContextMenuPrimitive.Popup.Props &\r\n  Pick<\r\n    ContextMenuPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset'\r\n  >) {\r\n  return (\r\n    <ContextMenuPrimitive.Portal>\r\n      <ContextMenuPrimitive.Positioner\r\n        className=\"isolate z-50 outline-none\"\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n      >\r\n        <ContextMenuPrimitive.Popup\r\n          data-slot=\"context-menu-content\"\r\n          className={cn(\r\n            'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground min-w-36 rounded-lg p-1 shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 cn-menu-target cn-menu-translucent z-50 max-h-(--available-height) origin-(--transform-origin) overflow-x-hidden overflow-y-auto outline-none',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n      </ContextMenuPrimitive.Positioner>\r\n    </ContextMenuPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction ContextMenuGroup({ ...props }: ContextMenuPrimitive.Group.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.Group data-slot=\"context-menu-group\" {...props} />\r\n  );\r\n}\r\n\r\nfunction ContextMenuLabel({\r\n  className,\r\n  inset,\r\n  ...props\r\n}: ContextMenuPrimitive.GroupLabel.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <ContextMenuPrimitive.GroupLabel\r\n      data-slot=\"context-menu-label\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        'text-muted-foreground px-1.5 py-1 text-xs font-medium data-inset:pl-7',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuItem({\r\n  className,\r\n  inset,\r\n  variant = 'default',\r\n  ...props\r\n}: ContextMenuPrimitive.Item.Props & {\r\n  inset?: boolean;\r\n  variant?: 'default' | 'destructive';\r\n}) {\r\n  return (\r\n    <ContextMenuPrimitive.Item\r\n      data-slot=\"context-menu-item\"\r\n      data-inset={inset}\r\n      data-variant={variant}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive focus:*:[svg]:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 group/context-menu-item relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuSub({ ...props }: ContextMenuPrimitive.SubmenuRoot.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.SubmenuRoot data-slot=\"context-menu-sub\" {...props} />\r\n  );\r\n}\r\n\r\nfunction ContextMenuSubTrigger({\r\n  className,\r\n  inset,\r\n  children,\r\n  ...props\r\n}: ContextMenuPrimitive.SubmenuTrigger.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <ContextMenuPrimitive.SubmenuTrigger\r\n      data-slot=\"context-menu-sub-trigger\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 flex cursor-default items-center outline-hidden select-none [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <ChevronRightIcon className=\"cn-rtl-flip ml-auto\" />\r\n    </ContextMenuPrimitive.SubmenuTrigger>\r\n  );\r\n}\r\n\r\nfunction ContextMenuSubContent({\r\n  ...props\r\n}: React.ComponentProps<typeof ContextMenuContent>) {\r\n  return (\r\n    <ContextMenuContent\r\n      data-slot=\"context-menu-sub-content\"\r\n      className=\"shadow-lg cn-menu-target cn-menu-translucent\"\r\n      side=\"right\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuCheckboxItem({\r\n  className,\r\n  children,\r\n  checked,\r\n  inset,\r\n  ...props\r\n}: ContextMenuPrimitive.CheckboxItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <ContextMenuPrimitive.CheckboxItem\r\n      data-slot=\"context-menu-checkbox-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      checked={checked}\r\n      {...props}\r\n    >\r\n      <span className=\"absolute right-2 pointer-events-none\">\r\n        <ContextMenuPrimitive.CheckboxItemIndicator>\r\n          <CheckIcon />\r\n        </ContextMenuPrimitive.CheckboxItemIndicator>\r\n      </span>\r\n      {children}\r\n    </ContextMenuPrimitive.CheckboxItem>\r\n  );\r\n}\r\n\r\nfunction ContextMenuRadioGroup({\r\n  ...props\r\n}: ContextMenuPrimitive.RadioGroup.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.RadioGroup\r\n      data-slot=\"context-menu-radio-group\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuRadioItem({\r\n  className,\r\n  children,\r\n  inset,\r\n  ...props\r\n}: ContextMenuPrimitive.RadioItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <ContextMenuPrimitive.RadioItem\r\n      data-slot=\"context-menu-radio-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <span className=\"absolute right-2 pointer-events-none\">\r\n        <ContextMenuPrimitive.RadioItemIndicator>\r\n          <CheckIcon />\r\n        </ContextMenuPrimitive.RadioItemIndicator>\r\n      </span>\r\n      {children}\r\n    </ContextMenuPrimitive.RadioItem>\r\n  );\r\n}\r\n\r\nfunction ContextMenuSeparator({\r\n  className,\r\n  ...props\r\n}: ContextMenuPrimitive.Separator.Props) {\r\n  return (\r\n    <ContextMenuPrimitive.Separator\r\n      data-slot=\"context-menu-separator\"\r\n      className={cn('bg-border -mx-1 my-1 h-px', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ContextMenuShortcut({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"context-menu-shortcut\"\r\n      className={cn(\r\n        'text-muted-foreground group-focus/context-menu-item:text-accent-foreground ml-auto text-xs tracking-widest',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  ContextMenu,\r\n  ContextMenuTrigger,\r\n  ContextMenuContent,\r\n  ContextMenuItem,\r\n  ContextMenuCheckboxItem,\r\n  ContextMenuRadioItem,\r\n  ContextMenuLabel,\r\n  ContextMenuSeparator,\r\n  ContextMenuShortcut,\r\n  ContextMenuGroup,\r\n  ContextMenuPortal,\r\n  ContextMenuSub,\r\n  ContextMenuSubContent,\r\n  ContextMenuSubTrigger,\r\n  ContextMenuRadioGroup,\r\n};\r\n","handborne/source/components/ui/dialog.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Dialog as DialogPrimitive } from '@base-ui/react/dialog';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { XIcon } from 'lucide-react';\r\n\r\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\r\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />;\r\n}\r\n\r\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\r\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />;\r\n}\r\n\r\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\r\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />;\r\n}\r\n\r\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\r\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />;\r\n}\r\n\r\nfunction DialogOverlay({\r\n  className,\r\n  ...props\r\n}: DialogPrimitive.Backdrop.Props) {\r\n  return (\r\n    <DialogPrimitive.Backdrop\r\n      data-slot=\"dialog-overlay\"\r\n      className={cn(\r\n        'fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DialogContent({\r\n  className,\r\n  children,\r\n  showCloseButton = true,\r\n  ...props\r\n}: DialogPrimitive.Popup.Props & {\r\n  showCloseButton?: boolean;\r\n}) {\r\n  return (\r\n    <DialogPortal>\r\n      <DialogOverlay />\r\n      <DialogPrimitive.Popup\r\n        data-slot=\"dialog-content\"\r\n        className={cn(\r\n          'fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-4 rounded-xl bg-popover p-4 text-sm text-popover-foreground ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n        {showCloseButton && (\r\n          <DialogPrimitive.Close\r\n            data-slot=\"dialog-close\"\r\n            render={\r\n              <Button\r\n                variant=\"ghost\"\r\n                className=\"absolute top-2 right-2\"\r\n                size=\"icon-sm\"\r\n              />\r\n            }\r\n          >\r\n            <XIcon />\r\n            <span className=\"sr-only\">Close</span>\r\n          </DialogPrimitive.Close>\r\n        )}\r\n      </DialogPrimitive.Popup>\r\n    </DialogPortal>\r\n  );\r\n}\r\n\r\nfunction DialogHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"dialog-header\"\r\n      className={cn('flex flex-col gap-2', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DialogFooter({\r\n  className,\r\n  showCloseButton = false,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  showCloseButton?: boolean;\r\n}) {\r\n  return (\r\n    <div\r\n      data-slot=\"dialog-footer\"\r\n      className={cn(\r\n        '-mx-4 -mb-4 flex flex-col-reverse gap-2 rounded-b-xl border-t bg-muted/50 p-4 sm:flex-row sm:justify-end',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      {showCloseButton && (\r\n        <DialogPrimitive.Close render={<Button variant=\"outline\" />}>\r\n          Close\r\n        </DialogPrimitive.Close>\r\n      )}\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\r\n  return (\r\n    <DialogPrimitive.Title\r\n      data-slot=\"dialog-title\"\r\n      className={cn(\r\n        'font-heading text-base leading-none font-medium',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DialogDescription({\r\n  className,\r\n  ...props\r\n}: DialogPrimitive.Description.Props) {\r\n  return (\r\n    <DialogPrimitive.Description\r\n      data-slot=\"dialog-description\"\r\n      className={cn(\r\n        'text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Dialog,\r\n  DialogClose,\r\n  DialogContent,\r\n  DialogDescription,\r\n  DialogFooter,\r\n  DialogHeader,\r\n  DialogOverlay,\r\n  DialogPortal,\r\n  DialogTitle,\r\n  DialogTrigger,\r\n};\r\n","handborne/source/components/ui/direction.tsx":"'use client';\r\n\r\nexport {\r\n  DirectionProvider,\r\n  useDirection,\r\n} from '@base-ui/react/direction-provider';\r\n","handborne/source/components/ui/drawer.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Drawer as DrawerPrimitive } from '@base-ui/react/drawer';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\ntype DrawerContextProps = {\r\n  hasSnapPoints: boolean;\r\n  modal: DrawerPrimitive.Root.Props['modal'];\r\n  showSwipeHandle: boolean;\r\n  swipeDirection: NonNullable<DrawerPrimitive.Root.Props['swipeDirection']>;\r\n};\r\n\r\nconst DrawerContext = React.createContext<DrawerContextProps | null>(null);\r\n\r\nfunction useDrawer() {\r\n  const context = React.useContext(DrawerContext);\r\n\r\n  if (!context) {\r\n    throw new Error('useDrawer must be used within a Drawer.');\r\n  }\r\n\r\n  return context;\r\n}\r\n\r\nfunction Drawer({\r\n  modal = true,\r\n  showSwipeHandle = false,\r\n  snapPoints,\r\n  swipeDirection = 'down',\r\n  ...props\r\n}: DrawerPrimitive.Root.Props & {\r\n  showSwipeHandle?: boolean;\r\n}) {\r\n  const hasSnapPoints = snapPoints != null && snapPoints.length > 0;\r\n  const contextValue = React.useMemo(\r\n    () => ({ hasSnapPoints, modal, showSwipeHandle, swipeDirection }),\r\n    [hasSnapPoints, modal, showSwipeHandle, swipeDirection],\r\n  );\r\n\r\n  return (\r\n    <DrawerContext.Provider value={contextValue}>\r\n      <DrawerPrimitive.Root\r\n        data-slot=\"drawer\"\r\n        modal={modal}\r\n        snapPoints={snapPoints}\r\n        swipeDirection={swipeDirection}\r\n        {...props}\r\n      />\r\n    </DrawerContext.Provider>\r\n  );\r\n}\r\n\r\nfunction DrawerTrigger({ ...props }: DrawerPrimitive.Trigger.Props) {\r\n  return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />;\r\n}\r\n\r\nfunction DrawerPortal({ ...props }: DrawerPrimitive.Portal.Props) {\r\n  return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />;\r\n}\r\n\r\nfunction DrawerClose({ ...props }: DrawerPrimitive.Close.Props) {\r\n  return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />;\r\n}\r\n\r\nfunction DrawerOverlay({\r\n  className,\r\n  ...props\r\n}: DrawerPrimitive.Backdrop.Props) {\r\n  return (\r\n    <DrawerPrimitive.Backdrop\r\n      data-slot=\"drawer-overlay\"\r\n      className={cn(\r\n        'bg-black/10 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50 min-h-dvh opacity-[max(var(--drawer-overlay-min-opacity,0),calc(1-var(--drawer-swipe-progress)))] transition-opacity duration-450 ease-[cubic-bezier(0.32,0.72,0,1)] select-none data-ending-style:pointer-events-none data-ending-style:opacity-0 data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-snap-points:[--drawer-overlay-min-opacity:0.5] data-starting-style:opacity-0 data-swiping:duration-0 supports-[-webkit-touch-callout:none]:absolute',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DrawerSwipeHandle({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"drawer-swipe-handle\"\r\n      aria-hidden=\"true\"\r\n      className={cn(\r\n        'after:block after:shrink-0 after:rounded-full after:bg-muted group-data-[swipe-axis=y]/drawer-popup:h-3 group-data-[swipe-axis=y]/drawer-popup:w-full group-data-[swipe-axis=y]/drawer-popup:justify-center group-data-[swipe-axis=y]/drawer-popup:after:h-1 group-data-[swipe-axis=y]/drawer-popup:after:w-24 group-data-[swipe-direction=down]/drawer-popup:items-end group-data-[swipe-direction=up]/drawer-popup:items-start group-data-[swipe-axis=x]/drawer-popup:h-full group-data-[swipe-axis=x]/drawer-popup:w-3 group-data-[swipe-axis=x]/drawer-popup:items-center group-data-[swipe-axis=x]/drawer-popup:after:h-24 group-data-[swipe-axis=x]/drawer-popup:after:w-1 group-data-[swipe-direction=left]/drawer-popup:justify-start group-data-[swipe-direction=right]/drawer-popup:justify-end relative z-10 flex shrink-0 cursor-grab transition-opacity duration-200 group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-[swipe-direction=left]/drawer-popup:order-last group-data-[swipe-direction=up]/drawer-popup:order-last active:cursor-grabbing',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DrawerContent({\r\n  className,\r\n  children,\r\n  ...props\r\n}: DrawerPrimitive.Popup.Props) {\r\n  const { hasSnapPoints, modal, showSwipeHandle, swipeDirection } = useDrawer();\r\n  const swipeAxis =\r\n    swipeDirection === 'down' || swipeDirection === 'up' ? 'y' : 'x';\r\n\r\n  return (\r\n    <DrawerPortal data-slot=\"drawer-portal\">\r\n      {modal === true && (\r\n        <DrawerOverlay data-snap-points={hasSnapPoints ? '' : undefined} />\r\n      )}\r\n      <DrawerPrimitive.Viewport\r\n        data-slot=\"drawer-viewport\"\r\n        data-modal={modal}\r\n        className=\"pointer-events-none fixed inset-0 z-50 select-none data-[modal=true]:pointer-events-auto\"\r\n      >\r\n        <DrawerPrimitive.Popup\r\n          data-slot=\"drawer-popup\"\r\n          data-swipe-axis={swipeAxis}\r\n          data-snap-points={hasSnapPoints ? '' : undefined}\r\n          className={cn(\r\n            // Base.\r\n            'bg-popover text-popover-foreground text-sm data-[swipe-direction=down]:rounded-t-xl data-[swipe-direction=down]:border-t data-[swipe-direction=left]:rounded-r-xl data-[swipe-direction=left]:border-r data-[swipe-direction=right]:rounded-l-xl data-[swipe-direction=right]:border-l data-[swipe-direction=up]:rounded-b-xl data-[swipe-direction=up]:border-b group/drawer-popup pointer-events-auto fixed z-50 m-(--drawer-inset,0px) flex h-(--drawer-content-height) max-h-(--drawer-content-max-height,none) min-h-0 w-(--drawer-content-width,auto) transform-[translate3d(var(--translate-x,0px),var(--translate-y,0px),0)_scale(var(--stack-scale))] flex-col transition-[transform,height,opacity,filter] duration-450 ease-[cubic-bezier(0.22,1,0.36,1)] will-change-transform outline-none select-none [interpolate-size:allow-keywords]',\r\n            // Nested.\r\n            'data-nested-drawer-open:overflow-hidden data-nested-drawer-open:brightness-95',\r\n            // Bleed.\r\n            'after:pointer-events-none after:absolute after:bg-(--drawer-bleed-background,var(--color-popover)) data-[swipe-axis=x]:after:inset-y-0 data-[swipe-axis=x]:after:w-(--bleed) data-[swipe-axis=y]:after:inset-x-0 data-[swipe-axis=y]:after:h-(--bleed) data-[swipe-direction=down]:after:top-full data-[swipe-direction=left]:after:right-full data-[swipe-direction=right]:after:left-full data-[swipe-direction=up]:after:bottom-full',\r\n            // Sizing.\r\n            '[--drawer-content-height:var(--drawer-height,auto)] data-[swipe-axis=x]:[--drawer-content-width:75%] data-[swipe-axis=y]:[--drawer-content-max-height:calc(100dvh-6rem)] data-[swipe-axis=y]:data-snap-points:[--drawer-content-height:100dvh] data-[swipe-axis=x]:sm:[--drawer-content-width:24rem]',\r\n            // Stack.\r\n            '[--bleed:3rem] [--peek:1rem] [--stack-height:var(--drawer-frontmost-height,var(--drawer-height,0px))] [--stack-peek-offset:max(0px,calc((var(--nested-drawers)-var(--stack-progress))*var(--peek)))] [--stack-progress:clamp(0,var(--drawer-swipe-progress),1)] [--stack-scale-base:max(0,calc(1-(var(--nested-drawers)*var(--stack-step))))] [--stack-scale:clamp(0,calc(var(--stack-scale-base)+(var(--stack-step)*var(--stack-progress))),1)] [--stack-shrink:calc(1-var(--stack-scale))] [--stack-step:0.05]',\r\n            // Transitions.\r\n            'data-ending-style:transform-(--closed-transform) data-ending-style:opacity-[0.9999] data-ending-style:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-nested-drawer-swiping:duration-0 data-ending-style:data-nested-drawer-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)] data-starting-style:transform-(--closed-transform) data-swiping:duration-0 data-ending-style:data-swiping:duration-[calc(var(--drawer-swipe-strength)*400ms)]',\r\n            // Axis: y.\r\n            'data-[swipe-axis=y]:inset-x-0 data-[swipe-axis=y]:data-nested-drawer-open:h-(--stack-height)',\r\n            // Axis: x.\r\n            'data-[swipe-axis=x]:inset-y-0 data-[swipe-axis=x]:flex-row',\r\n            // Direction: down.\r\n            'data-[swipe-direction=down]:bottom-0 data-[swipe-direction=down]:origin-bottom data-[swipe-direction=down]:[--closed-transform:translate3d(0,calc(100%+var(--drawer-inset,0px)+2px),0)] data-[swipe-direction=down]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)-var(--stack-peek-offset)-(var(--stack-shrink)*var(--stack-height)))]',\r\n            // Direction: up.\r\n            'data-[swipe-direction=up]:top-0 data-[swipe-direction=up]:origin-top data-[swipe-direction=up]:[--closed-transform:translate3d(0,calc(-100%-var(--drawer-inset,0px)-2px),0)] data-[swipe-direction=up]:[--translate-y:calc(var(--drawer-snap-point-offset,0px)+var(--drawer-swipe-movement-y)+var(--stack-peek-offset)+(var(--stack-shrink)*var(--stack-height)))]',\r\n            // Direction: left.\r\n            'data-[swipe-direction=left]:left-0 data-[swipe-direction=left]:origin-left data-[swipe-direction=left]:[--closed-transform:translate3d(calc(-100%-var(--drawer-inset,0px)-2px),0,0)] data-[swipe-direction=left]:[--translate-x:calc(var(--drawer-swipe-movement-x)+var(--stack-peek-offset)+(var(--stack-shrink)*100%))]',\r\n            // Direction: right.\r\n            'data-[swipe-direction=right]:right-0 data-[swipe-direction=right]:origin-right data-[swipe-direction=right]:[--closed-transform:translate3d(calc(100%+var(--drawer-inset,0px)+2px),0,0)] data-[swipe-direction=right]:[--translate-x:calc(var(--drawer-swipe-movement-x)-var(--stack-peek-offset)-(var(--stack-shrink)*100%))]',\r\n            className,\r\n          )}\r\n          {...props}\r\n        >\r\n          {showSwipeHandle && <DrawerSwipeHandle />}\r\n          <DrawerPrimitive.Content\r\n            data-slot=\"drawer-content\"\r\n            className={cn(\r\n              'flex min-h-0 flex-1 flex-col overflow-hidden overscroll-contain rounded-[inherit] transition-opacity duration-300 ease-[cubic-bezier(0.45,1.005,0,1.005)] select-text group-data-nested-drawer-open/drawer-popup:opacity-0 group-data-nested-drawer-swiping/drawer-popup:opacity-100 group-data-swiping/drawer-popup:select-none',\r\n            )}\r\n          >\r\n            {children}\r\n          </DrawerPrimitive.Content>\r\n        </DrawerPrimitive.Popup>\r\n      </DrawerPrimitive.Viewport>\r\n    </DrawerPortal>\r\n  );\r\n}\r\n\r\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"drawer-header\"\r\n      className={cn(\r\n        'gap-0.5 p-4 pb-0 md:gap-0.5 md:text-left flex shrink-0 flex-col group-data-[swipe-axis=y]/drawer-popup:text-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"drawer-footer\"\r\n      className={cn('gap-2 p-4 pt-0 mt-auto flex shrink-0 flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DrawerTitle({ className, ...props }: DrawerPrimitive.Title.Props) {\r\n  return (\r\n    <DrawerPrimitive.Title\r\n      data-slot=\"drawer-title\"\r\n      className={cn(\r\n        'text-foreground text-base font-medium cn-font-heading',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DrawerDescription({\r\n  className,\r\n  ...props\r\n}: DrawerPrimitive.Description.Props) {\r\n  return (\r\n    <DrawerPrimitive.Description\r\n      data-slot=\"drawer-description\"\r\n      className={cn('text-muted-foreground text-sm text-balance', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Drawer,\r\n  DrawerPortal,\r\n  DrawerOverlay,\r\n  DrawerSwipeHandle,\r\n  DrawerTrigger,\r\n  DrawerClose,\r\n  DrawerContent,\r\n  DrawerHeader,\r\n  DrawerFooter,\r\n  DrawerTitle,\r\n  DrawerDescription,\r\n};\r\n","handborne/source/components/ui/dropdown-menu.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Menu as MenuPrimitive } from '@base-ui/react/menu';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronRightIcon, CheckIcon } from 'lucide-react';\r\n\r\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\r\n  return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />;\r\n}\r\n\r\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\r\n  return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />;\r\n}\r\n\r\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\r\n  return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />;\r\n}\r\n\r\nfunction DropdownMenuContent({\r\n  align = 'start',\r\n  alignOffset = 0,\r\n  side = 'bottom',\r\n  sideOffset = 4,\r\n  className,\r\n  ...props\r\n}: MenuPrimitive.Popup.Props &\r\n  Pick<\r\n    MenuPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset'\r\n  >) {\r\n  return (\r\n    <MenuPrimitive.Portal>\r\n      <MenuPrimitive.Positioner\r\n        className=\"isolate z-50 outline-none\"\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n      >\r\n        <MenuPrimitive.Popup\r\n          data-slot=\"dropdown-menu-content\"\r\n          className={cn(\r\n            'z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n      </MenuPrimitive.Positioner>\r\n    </MenuPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\r\n  return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />;\r\n}\r\n\r\nfunction DropdownMenuLabel({\r\n  className,\r\n  inset,\r\n  ...props\r\n}: MenuPrimitive.GroupLabel.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.GroupLabel\r\n      data-slot=\"dropdown-menu-label\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        'px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DropdownMenuItem({\r\n  className,\r\n  inset,\r\n  variant = 'default',\r\n  ...props\r\n}: MenuPrimitive.Item.Props & {\r\n  inset?: boolean;\r\n  variant?: 'default' | 'destructive';\r\n}) {\r\n  return (\r\n    <MenuPrimitive.Item\r\n      data-slot=\"dropdown-menu-item\"\r\n      data-inset={inset}\r\n      data-variant={variant}\r\n      className={cn(\r\n        \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\r\n  return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />;\r\n}\r\n\r\nfunction DropdownMenuSubTrigger({\r\n  className,\r\n  inset,\r\n  children,\r\n  ...props\r\n}: MenuPrimitive.SubmenuTrigger.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.SubmenuTrigger\r\n      data-slot=\"dropdown-menu-sub-trigger\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <ChevronRightIcon className=\"ml-auto\" />\r\n    </MenuPrimitive.SubmenuTrigger>\r\n  );\r\n}\r\n\r\nfunction DropdownMenuSubContent({\r\n  align = 'start',\r\n  alignOffset = -3,\r\n  side = 'right',\r\n  sideOffset = 0,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuContent>) {\r\n  return (\r\n    <DropdownMenuContent\r\n      data-slot=\"dropdown-menu-sub-content\"\r\n      className={cn(\r\n        'w-auto min-w-[96px] rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\r\n        className,\r\n      )}\r\n      align={align}\r\n      alignOffset={alignOffset}\r\n      side={side}\r\n      sideOffset={sideOffset}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DropdownMenuCheckboxItem({\r\n  className,\r\n  children,\r\n  checked,\r\n  inset,\r\n  ...props\r\n}: MenuPrimitive.CheckboxItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.CheckboxItem\r\n      data-slot=\"dropdown-menu-checkbox-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      checked={checked}\r\n      {...props}\r\n    >\r\n      <span\r\n        className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\r\n        data-slot=\"dropdown-menu-checkbox-item-indicator\"\r\n      >\r\n        <MenuPrimitive.CheckboxItemIndicator>\r\n          <CheckIcon />\r\n        </MenuPrimitive.CheckboxItemIndicator>\r\n      </span>\r\n      {children}\r\n    </MenuPrimitive.CheckboxItem>\r\n  );\r\n}\r\n\r\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\r\n  return (\r\n    <MenuPrimitive.RadioGroup\r\n      data-slot=\"dropdown-menu-radio-group\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DropdownMenuRadioItem({\r\n  className,\r\n  children,\r\n  inset,\r\n  ...props\r\n}: MenuPrimitive.RadioItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.RadioItem\r\n      data-slot=\"dropdown-menu-radio-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <span\r\n        className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\r\n        data-slot=\"dropdown-menu-radio-item-indicator\"\r\n      >\r\n        <MenuPrimitive.RadioItemIndicator>\r\n          <CheckIcon />\r\n        </MenuPrimitive.RadioItemIndicator>\r\n      </span>\r\n      {children}\r\n    </MenuPrimitive.RadioItem>\r\n  );\r\n}\r\n\r\nfunction DropdownMenuSeparator({\r\n  className,\r\n  ...props\r\n}: MenuPrimitive.Separator.Props) {\r\n  return (\r\n    <MenuPrimitive.Separator\r\n      data-slot=\"dropdown-menu-separator\"\r\n      className={cn('-mx-1 my-1 h-px bg-border', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction DropdownMenuShortcut({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"dropdown-menu-shortcut\"\r\n      className={cn(\r\n        'ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  DropdownMenu,\r\n  DropdownMenuPortal,\r\n  DropdownMenuTrigger,\r\n  DropdownMenuContent,\r\n  DropdownMenuGroup,\r\n  DropdownMenuLabel,\r\n  DropdownMenuItem,\r\n  DropdownMenuCheckboxItem,\r\n  DropdownMenuRadioGroup,\r\n  DropdownMenuRadioItem,\r\n  DropdownMenuSeparator,\r\n  DropdownMenuShortcut,\r\n  DropdownMenuSub,\r\n  DropdownMenuSubTrigger,\r\n  DropdownMenuSubContent,\r\n};\r\n","handborne/source/components/ui/empty.tsx":"import { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Empty({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty\"\r\n      className={cn(\r\n        'gap-4 rounded-xl border-dashed p-6 flex w-full min-w-0 flex-1 flex-col items-center justify-center text-center text-balance',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty-header\"\r\n      className={cn('gap-2 flex max-w-sm flex-col items-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst emptyMediaVariants = cva(\r\n  'mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-transparent',\r\n        icon: \"bg-muted text-foreground flex size-8 shrink-0 items-center justify-center rounded-lg [&_svg:not([class*='size-'])]:size-4\",\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction EmptyMedia({\r\n  className,\r\n  variant = 'default',\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof emptyMediaVariants>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty-icon\"\r\n      data-variant={variant}\r\n      className={cn(emptyMediaVariants({ variant, className }))}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty-title\"\r\n      className={cn(\r\n        'text-sm font-medium tracking-tight cn-font-heading',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<'p'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty-description\"\r\n      className={cn(\r\n        'text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction EmptyContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"empty-content\"\r\n      className={cn(\r\n        'gap-2.5 text-sm flex w-full max-w-sm min-w-0 flex-col items-center text-balance',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Empty,\r\n  EmptyHeader,\r\n  EmptyTitle,\r\n  EmptyDescription,\r\n  EmptyContent,\r\n  EmptyMedia,\r\n};\r\n","handborne/source/components/ui/field.tsx":"'use client';\r\n\r\nimport { useMemo } from 'react';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Label } from '@/components/ui/label';\r\nimport { Separator } from '@/components/ui/separator';\r\n\r\nfunction FieldSet({ className, ...props }: React.ComponentProps<'fieldset'>) {\r\n  return (\r\n    <fieldset\r\n      data-slot=\"field-set\"\r\n      className={cn(\r\n        'gap-4 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3 flex flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldLegend({\r\n  className,\r\n  variant = 'legend',\r\n  ...props\r\n}: React.ComponentProps<'legend'> & { variant?: 'legend' | 'label' }) {\r\n  return (\r\n    <legend\r\n      data-slot=\"field-legend\"\r\n      data-variant={variant}\r\n      className={cn(\r\n        'mb-1.5 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"field-group\"\r\n      className={cn(\r\n        'gap-5 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4 group/field-group @container/field-group flex w-full flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst fieldVariants = cva(\r\n  'data-[invalid=true]:text-destructive gap-2 group/field flex w-full',\r\n  {\r\n    variants: {\r\n      orientation: {\r\n        vertical: 'flex-col *:w-full [&>.sr-only]:w-auto',\r\n        horizontal:\r\n          'flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\r\n        responsive:\r\n          'flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      orientation: 'vertical',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Field({\r\n  className,\r\n  orientation = 'vertical',\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof fieldVariants>) {\r\n  return (\r\n    <div\r\n      role=\"group\"\r\n      data-slot=\"field\"\r\n      data-orientation={orientation}\r\n      className={cn(fieldVariants({ orientation }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"field-content\"\r\n      className={cn(\r\n        'gap-0.5 group/field-content flex flex-1 flex-col leading-snug',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldLabel({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Label>) {\r\n  return (\r\n    <Label\r\n      data-slot=\"field-label\"\r\n      className={cn(\r\n        'has-data-checked:bg-primary/5 has-data-checked:border-primary/30 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10 gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-[>[data-slot=field]]:rounded-lg has-[>[data-slot=field]]:border has-[>[data-slot=field]]:not-has-[:disabled,[data-disabled]]:hover:bg-muted/50 has-[>[data-slot=field]]:has-[:focus-visible]:border-ring has-[>[data-slot=field]]:has-[:focus-visible]:ring-ring/50 has-[>[data-slot=field]]:has-[:focus-visible]:ring-3 *:data-[slot=field]:p-2.5 group/field-label peer/field-label flex w-fit',\r\n        'has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldTitle({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"field-label\"\r\n      className={cn(\r\n        'gap-2 text-sm font-medium group-data-[disabled=true]/field:opacity-50 flex w-fit items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldDescription({ className, ...props }: React.ComponentProps<'p'>) {\r\n  return (\r\n    <p\r\n      data-slot=\"field-description\"\r\n      className={cn(\r\n        'text-muted-foreground text-left text-sm [[data-variant=legend]+&]:-mt-1.5 leading-normal font-normal group-has-data-horizontal/field:text-balance',\r\n        'last:mt-0 nth-last-2:-mt-1',\r\n        '[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction FieldSeparator({\r\n  children,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  children?: React.ReactNode;\r\n}) {\r\n  return (\r\n    <div\r\n      data-slot=\"field-separator\"\r\n      data-content={!!children}\r\n      className={cn(\r\n        '-my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2 relative',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <Separator className=\"absolute inset-0 top-1/2\" />\r\n      {children && (\r\n        <span\r\n          className=\"text-muted-foreground px-2 relative mx-auto block w-fit bg-background\"\r\n          data-slot=\"field-separator-content\"\r\n        >\r\n          {children}\r\n        </span>\r\n      )}\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction FieldError({\r\n  className,\r\n  children,\r\n  errors,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  errors?: Array<{ message?: string } | undefined>;\r\n}) {\r\n  const content = useMemo(() => {\r\n    if (children) {\r\n      return children;\r\n    }\r\n\r\n    if (!errors?.length) {\r\n      return null;\r\n    }\r\n\r\n    const uniqueErrors = [\r\n      ...new Map(errors.map((error) => [error?.message, error])).values(),\r\n    ];\r\n\r\n    if (uniqueErrors?.length == 1) {\r\n      return uniqueErrors[0]?.message;\r\n    }\r\n\r\n    return (\r\n      <ul className=\"ml-4 flex list-disc flex-col gap-1\">\r\n        {uniqueErrors.map(\r\n          (error, index) =>\r\n            error?.message && <li key={index}>{error.message}</li>,\r\n        )}\r\n      </ul>\r\n    );\r\n  }, [children, errors]);\r\n\r\n  if (!content) {\r\n    return null;\r\n  }\r\n\r\n  return (\r\n    <div\r\n      role=\"alert\"\r\n      data-slot=\"field-error\"\r\n      className={cn('text-destructive text-sm font-normal', className)}\r\n      {...props}\r\n    >\r\n      {content}\r\n    </div>\r\n  );\r\n}\r\n\r\nexport {\r\n  Field,\r\n  FieldLabel,\r\n  FieldDescription,\r\n  FieldError,\r\n  FieldGroup,\r\n  FieldLegend,\r\n  FieldSeparator,\r\n  FieldSet,\r\n  FieldContent,\r\n  FieldTitle,\r\n};\r\n","handborne/source/components/ui/hover-card.tsx":"'use client';\r\n\r\nimport { PreviewCard as PreviewCardPrimitive } from '@base-ui/react/preview-card';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction HoverCard({ ...props }: PreviewCardPrimitive.Root.Props) {\r\n  return <PreviewCardPrimitive.Root data-slot=\"hover-card\" {...props} />;\r\n}\r\n\r\nfunction HoverCardTrigger({ ...props }: PreviewCardPrimitive.Trigger.Props) {\r\n  return (\r\n    <PreviewCardPrimitive.Trigger data-slot=\"hover-card-trigger\" {...props} />\r\n  );\r\n}\r\n\r\nfunction HoverCardContent({\r\n  className,\r\n  side = 'bottom',\r\n  sideOffset = 4,\r\n  align = 'center',\r\n  alignOffset = 4,\r\n  ...props\r\n}: PreviewCardPrimitive.Popup.Props &\r\n  Pick<\r\n    PreviewCardPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset'\r\n  >) {\r\n  return (\r\n    <PreviewCardPrimitive.Portal data-slot=\"hover-card-portal\">\r\n      <PreviewCardPrimitive.Positioner\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        className=\"isolate z-50\"\r\n      >\r\n        <PreviewCardPrimitive.Popup\r\n          data-slot=\"hover-card-content\"\r\n          className={cn(\r\n            'data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 bg-popover text-popover-foreground w-64 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 origin-(--transform-origin) outline-hidden',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n      </PreviewCardPrimitive.Positioner>\r\n    </PreviewCardPrimitive.Portal>\r\n  );\r\n}\r\n\r\nexport { HoverCard, HoverCardTrigger, HoverCardContent };\r\n","handborne/source/components/ui/input-group.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { Input } from '@/components/ui/input';\r\nimport { Textarea } from '@/components/ui/textarea';\r\n\r\nfunction InputGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"input-group\"\r\n      role=\"group\"\r\n      className={cn(\r\n        'border-input dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-input/50 dark:has-disabled:bg-input/80 h-8 rounded-lg border transition-colors in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5 group/input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst inputGroupAddonVariants = cva(\r\n  \"text-muted-foreground h-auto gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4 flex cursor-text items-center justify-center select-none\",\r\n  {\r\n    variants: {\r\n      align: {\r\n        'inline-start':\r\n          'pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem] order-first',\r\n        'inline-end':\r\n          'pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem] order-last',\r\n        'block-start':\r\n          'px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2 order-first w-full justify-start',\r\n        'block-end':\r\n          'px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2 order-last w-full justify-start',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      align: 'inline-start',\r\n    },\r\n  },\r\n);\r\n\r\nfunction InputGroupAddon({\r\n  className,\r\n  align = 'inline-start',\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof inputGroupAddonVariants>) {\r\n  return (\r\n    <div\r\n      role=\"group\"\r\n      data-slot=\"input-group-addon\"\r\n      data-align={align}\r\n      className={cn(inputGroupAddonVariants({ align }), className)}\r\n      onClick={(e) => {\r\n        if ((e.target as HTMLElement).closest('button')) {\r\n          return;\r\n        }\r\n        e.currentTarget.parentElement?.querySelector('input')?.focus();\r\n      }}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst inputGroupButtonVariants = cva(\r\n  'gap-2 text-sm flex items-center shadow-none',\r\n  {\r\n    variants: {\r\n      size: {\r\n        xs: \"h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\r\n        sm: '',\r\n        'icon-xs':\r\n          'size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0',\r\n        'icon-sm': 'size-8 p-0 has-[>svg]:p-0',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      size: 'xs',\r\n    },\r\n  },\r\n);\r\n\r\nfunction InputGroupButton({\r\n  className,\r\n  type = 'button',\r\n  variant = 'ghost',\r\n  size = 'xs',\r\n  ...props\r\n}: Omit<React.ComponentProps<typeof Button>, 'size' | 'type'> &\r\n  VariantProps<typeof inputGroupButtonVariants> & {\r\n    type?: 'button' | 'submit' | 'reset';\r\n  }) {\r\n  return (\r\n    <Button\r\n      type={type}\r\n      data-size={size}\r\n      variant={variant}\r\n      className={cn(inputGroupButtonVariants({ size }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction InputGroupText({ className, ...props }: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      className={cn(\r\n        \"text-muted-foreground gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction InputGroupInput({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'input'>) {\r\n  return (\r\n    <Input\r\n      data-slot=\"input-group-control\"\r\n      className={cn(\r\n        'rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent flex-1',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction InputGroupTextarea({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'textarea'>) {\r\n  return (\r\n    <Textarea\r\n      data-slot=\"input-group-control\"\r\n      className={cn(\r\n        'rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent flex-1 resize-none',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  InputGroup,\r\n  InputGroupAddon,\r\n  InputGroupButton,\r\n  InputGroupText,\r\n  InputGroupInput,\r\n  InputGroupTextarea,\r\n};\r\n","handborne/source/components/ui/input-otp.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { OTPInput, OTPInputContext } from 'input-otp';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { MinusIcon } from 'lucide-react';\r\n\r\nfunction InputOTP({\r\n  className,\r\n  containerClassName,\r\n  ...props\r\n}: React.ComponentProps<typeof OTPInput> & {\r\n  containerClassName?: string;\r\n}) {\r\n  return (\r\n    <OTPInput\r\n      data-slot=\"input-otp\"\r\n      containerClassName={cn(\r\n        'cn-input-otp flex items-center has-disabled:opacity-50',\r\n        containerClassName,\r\n      )}\r\n      spellCheck={false}\r\n      className={cn('disabled:cursor-not-allowed', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"input-otp-group\"\r\n      className={cn(\r\n        'has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive rounded-lg has-aria-invalid:ring-3 flex items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction InputOTPSlot({\r\n  index,\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  index: number;\r\n}) {\r\n  const inputOTPContext = React.useContext(OTPInputContext);\r\n  const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};\r\n\r\n  return (\r\n    <div\r\n      data-slot=\"input-otp-slot\"\r\n      data-active={isActive}\r\n      className={cn(\r\n        'dark:bg-input/30 border-input data-[active=true]:border-ring data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:ring-destructive/20 dark:data-[active=true]:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[active=true]:aria-invalid:border-destructive size-8 border-y border-r text-sm transition-all outline-none first:rounded-l-lg first:border-l last:rounded-r-lg data-[active=true]:ring-3 relative flex items-center justify-center data-[active=true]:z-10',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {char}\r\n      {hasFakeCaret && (\r\n        <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\r\n          <div className=\"animate-caret-blink bg-foreground h-4 w-px duration-1000\" />\r\n        </div>\r\n      )}\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"input-otp-separator\"\r\n      className=\"[&_svg:not([class*='size-'])]:size-4 flex items-center\"\r\n      role=\"separator\"\r\n      {...props}\r\n    >\r\n      <MinusIcon />\r\n    </div>\r\n  );\r\n}\r\n\r\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator };\r\n","handborne/source/components/ui/input.tsx":"import * as React from 'react';\r\nimport { Input as InputPrimitive } from '@base-ui/react/input';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Input({ className, type, ...props }: React.ComponentProps<'input'>) {\r\n  return (\r\n    <InputPrimitive\r\n      type={type}\r\n      data-slot=\"input\"\r\n      className={cn(\r\n        'h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Input };\r\n","handborne/source/components/ui/item.tsx":"import * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Separator } from '@/components/ui/separator';\r\n\r\nfunction ItemGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      role=\"list\"\r\n      data-slot=\"item-group\"\r\n      className={cn(\r\n        'gap-4 has-data-[size=sm]:gap-2.5 has-data-[size=xs]:gap-2 group/item-group flex w-full flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemSeparator({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Separator>) {\r\n  return (\r\n    <Separator\r\n      data-slot=\"item-separator\"\r\n      orientation=\"horizontal\"\r\n      className={cn('my-2', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst itemVariants = cva(\r\n  '[a]:hover:bg-muted rounded-lg border text-sm group/item flex w-full flex-wrap items-center transition-colors duration-100 outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 [a]:transition-colors',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'border-transparent',\r\n        outline: 'border-border',\r\n        muted: 'bg-muted/50 border-transparent',\r\n      },\r\n      size: {\r\n        default: 'gap-2.5 px-3 py-2.5',\r\n        sm: 'gap-2.5 px-3 py-2.5',\r\n        xs: 'gap-2 px-2.5 py-2 in-data-[slot=dropdown-menu-content]:p-0',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n      size: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Item({\r\n  className,\r\n  variant = 'default',\r\n  size = 'default',\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'div'> & VariantProps<typeof itemVariants>) {\r\n  return useRender({\r\n    defaultTagName: 'div',\r\n    props: mergeProps<'div'>(\r\n      {\r\n        className: cn(itemVariants({ variant, size, className })),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'item',\r\n      variant,\r\n      size,\r\n    },\r\n  });\r\n}\r\n\r\nconst itemMediaVariants = cva(\r\n  'gap-2 group-has-data-[slot=item-description]/item:translate-y-0.5 group-has-data-[slot=item-description]/item:self-start flex shrink-0 items-center justify-center [&_svg]:pointer-events-none',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-transparent',\r\n        icon: \"[&_svg:not([class*='size-'])]:size-4\",\r\n        image:\r\n          'size-10 overflow-hidden rounded-sm group-data-[size=sm]/item:size-8 group-data-[size=xs]/item:size-6 [&_img]:size-full [&_img]:object-cover',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction ItemMedia({\r\n  className,\r\n  variant = 'default',\r\n  ...props\r\n}: React.ComponentProps<'div'> & VariantProps<typeof itemMediaVariants>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-media\"\r\n      data-variant={variant}\r\n      className={cn(itemMediaVariants({ variant, className }))}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-content\"\r\n      className={cn(\r\n        'gap-1 group-data-[size=xs]/item:gap-0 flex flex-1 flex-col [&+[data-slot=item-content]]:flex-none',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemTitle({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-title\"\r\n      className={cn(\r\n        'gap-2 text-sm leading-snug font-medium underline-offset-4 line-clamp-1 flex w-fit items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemDescription({ className, ...props }: React.ComponentProps<'p'>) {\r\n  return (\r\n    <p\r\n      data-slot=\"item-description\"\r\n      className={cn(\r\n        'text-muted-foreground text-left text-sm leading-normal group-data-[size=xs]/item:text-xs line-clamp-2 font-normal [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemActions({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-actions\"\r\n      className={cn('gap-2 flex items-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-header\"\r\n      className={cn(\r\n        'gap-2 flex basis-full items-center justify-between',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ItemFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"item-footer\"\r\n      className={cn(\r\n        'gap-2 flex basis-full items-center justify-between',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Item,\r\n  ItemMedia,\r\n  ItemContent,\r\n  ItemActions,\r\n  ItemGroup,\r\n  ItemSeparator,\r\n  ItemTitle,\r\n  ItemDescription,\r\n  ItemHeader,\r\n  ItemFooter,\r\n};\r\n","handborne/source/components/ui/kbd.tsx":"import { cn } from '@/lib/utils';\r\n\r\nfunction Kbd({ className, ...props }: React.ComponentProps<'kbd'>) {\r\n  return (\r\n    <kbd\r\n      data-slot=\"kbd\"\r\n      className={cn(\r\n        \"bg-muted text-muted-foreground in-data-[slot=tooltip-content]:bg-background/20 in-data-[slot=tooltip-content]:text-background dark:in-data-[slot=tooltip-content]:bg-background/10 h-5 w-fit min-w-5 gap-1 rounded-sm px-1 font-sans text-xs font-medium [&_svg:not([class*='size-'])]:size-3 pointer-events-none inline-flex items-center justify-center select-none\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction KbdGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <kbd\r\n      data-slot=\"kbd-group\"\r\n      className={cn('gap-1 inline-flex items-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Kbd, KbdGroup };\r\n","handborne/source/components/ui/label.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Label({ className, ...props }: React.ComponentProps<'label'>) {\r\n  return (\r\n    <label\r\n      data-slot=\"label\"\r\n      className={cn(\r\n        'flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Label };\r\n","handborne/source/components/ui/marker.tsx":"import * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nconst markerVariants = cva(\r\n  \"gap-2 text-sm text-muted-foreground [a]:hover:text-foreground [a]:underline-offset-3 [a]:underline [&_svg:not([class*='size-'])]:size-4 min-h-4 text-left group/marker relative flex w-full items-center\",\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: '',\r\n        separator:\r\n          'before:h-px before:min-w-0 before:flex-1 before:bg-border after:h-px after:min-w-0 after:flex-1 after:bg-border before:mr-1 after:ml-1',\r\n        border: 'border-b border-border pb-2',\r\n      },\r\n    },\r\n  },\r\n);\r\n\r\nfunction Marker({\r\n  className,\r\n  variant = 'default',\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'div'> & VariantProps<typeof markerVariants>) {\r\n  return useRender({\r\n    defaultTagName: 'div',\r\n    props: mergeProps<'div'>(\r\n      {\r\n        className: cn(markerVariants({ variant, className })),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'marker',\r\n      variant,\r\n    },\r\n  });\r\n}\r\n\r\nfunction MarkerIcon({ className, ...props }: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"marker-icon\"\r\n      aria-hidden=\"true\"\r\n      className={cn(\r\n        \"size-4 [&_svg:not([class*='size-'])]:size-4 shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MarkerContent({ className, ...props }: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      data-slot=\"marker-content\"\r\n      className={cn(\r\n        'group-data-[variant=separator]/marker:flex-none group-data-[variant=separator]/marker:text-center *:[a]:hover:text-foreground *:[a]:underline *:[a]:underline-offset-3 min-w-0 wrap-break-word',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Marker, MarkerIcon, MarkerContent, markerVariants };\r\n","handborne/source/components/ui/menubar.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Menu as MenuPrimitive } from '@base-ui/react/menu';\r\nimport { Menubar as MenubarPrimitive } from '@base-ui/react/menubar';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport {\r\n  DropdownMenu,\r\n  DropdownMenuContent,\r\n  DropdownMenuGroup,\r\n  DropdownMenuItem,\r\n  DropdownMenuLabel,\r\n  DropdownMenuPortal,\r\n  DropdownMenuRadioGroup,\r\n  DropdownMenuSeparator,\r\n  DropdownMenuShortcut,\r\n  DropdownMenuSub,\r\n  DropdownMenuSubContent,\r\n  DropdownMenuSubTrigger,\r\n  DropdownMenuTrigger,\r\n} from '@/components/ui/dropdown-menu';\r\nimport { CheckIcon } from 'lucide-react';\r\n\r\nfunction Menubar({ className, ...props }: MenubarPrimitive.Props) {\r\n  return (\r\n    <MenubarPrimitive\r\n      data-slot=\"menubar\"\r\n      className={cn(\r\n        'h-8 gap-0.5 rounded-lg border p-[3px] flex items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarMenu({ ...props }: React.ComponentProps<typeof DropdownMenu>) {\r\n  return <DropdownMenu data-slot=\"menubar-menu\" {...props} />;\r\n}\r\n\r\nfunction MenubarGroup({\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuGroup>) {\r\n  return <DropdownMenuGroup data-slot=\"menubar-group\" {...props} />;\r\n}\r\n\r\nfunction MenubarPortal({\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuPortal>) {\r\n  return <DropdownMenuPortal data-slot=\"menubar-portal\" {...props} />;\r\n}\r\n\r\nfunction MenubarTrigger({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuTrigger>) {\r\n  return (\r\n    <DropdownMenuTrigger\r\n      data-slot=\"menubar-trigger\"\r\n      className={cn(\r\n        'hover:bg-muted aria-expanded:bg-muted rounded-sm px-1.5 py-[2px] text-sm font-medium flex items-center outline-hidden select-none',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarContent({\r\n  className,\r\n  align = 'start',\r\n  alignOffset = -4,\r\n  sideOffset = 8,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuContent>) {\r\n  return (\r\n    <DropdownMenuContent\r\n      data-slot=\"menubar-content\"\r\n      align={align}\r\n      alignOffset={alignOffset}\r\n      sideOffset={sideOffset}\r\n      className={cn(\r\n        'bg-popover text-popover-foreground data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-36 rounded-lg p-1 shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 cn-menu-target cn-menu-translucent',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarItem({\r\n  className,\r\n  inset,\r\n  variant = 'default',\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuItem>) {\r\n  return (\r\n    <DropdownMenuItem\r\n      data-slot=\"menubar-item\"\r\n      data-inset={inset}\r\n      data-variant={variant}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 dark:data-[variant=destructive]:focus:bg-destructive/20 data-[variant=destructive]:focus:text-destructive data-[variant=destructive]:*:[svg]:text-destructive! not-data-[variant=destructive]:focus:**:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-disabled:opacity-50 data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 group/menubar-item\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarCheckboxItem({\r\n  className,\r\n  children,\r\n  checked,\r\n  inset,\r\n  ...props\r\n}: MenuPrimitive.CheckboxItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.CheckboxItem\r\n      data-slot=\"menubar-checkbox-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        'focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm data-inset:pl-7 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0',\r\n        className,\r\n      )}\r\n      checked={checked}\r\n      {...props}\r\n    >\r\n      <span className=\"left-1.5 size-4 [&_svg:not([class*='size-'])]:size-4 pointer-events-none absolute flex items-center justify-center\">\r\n        <MenuPrimitive.CheckboxItemIndicator>\r\n          <CheckIcon />\r\n        </MenuPrimitive.CheckboxItemIndicator>\r\n      </span>\r\n      {children}\r\n    </MenuPrimitive.CheckboxItem>\r\n  );\r\n}\r\n\r\nfunction MenubarRadioGroup({\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuRadioGroup>) {\r\n  return <DropdownMenuRadioGroup data-slot=\"menubar-radio-group\" {...props} />;\r\n}\r\n\r\nfunction MenubarRadioItem({\r\n  className,\r\n  children,\r\n  inset,\r\n  ...props\r\n}: MenuPrimitive.RadioItem.Props & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <MenuPrimitive.RadioItem\r\n      data-slot=\"menubar-radio-item\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground gap-1.5 rounded-md py-1 pr-1.5 pl-7 text-sm data-disabled:opacity-50 data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4 relative flex cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <span className=\"left-1.5 size-4 [&_svg:not([class*='size-'])]:size-4 pointer-events-none absolute flex items-center justify-center\">\r\n        <MenuPrimitive.RadioItemIndicator>\r\n          <CheckIcon />\r\n        </MenuPrimitive.RadioItemIndicator>\r\n      </span>\r\n      {children}\r\n    </MenuPrimitive.RadioItem>\r\n  );\r\n}\r\n\r\nfunction MenubarLabel({\r\n  className,\r\n  inset,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuLabel> & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <DropdownMenuLabel\r\n      data-slot=\"menubar-label\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        'px-1.5 py-1 text-sm font-medium data-inset:pl-7',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarSeparator({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuSeparator>) {\r\n  return (\r\n    <DropdownMenuSeparator\r\n      data-slot=\"menubar-separator\"\r\n      className={cn('bg-border -mx-1 my-1 h-px', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarShortcut({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuShortcut>) {\r\n  return (\r\n    <DropdownMenuShortcut\r\n      data-slot=\"menubar-shortcut\"\r\n      className={cn(\r\n        'text-muted-foreground group-focus/menubar-item:text-accent-foreground text-xs tracking-widest ml-auto',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarSub({\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuSub>) {\r\n  return <DropdownMenuSub data-slot=\"menubar-sub\" {...props} />;\r\n}\r\n\r\nfunction MenubarSubTrigger({\r\n  className,\r\n  inset,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuSubTrigger> & {\r\n  inset?: boolean;\r\n}) {\r\n  return (\r\n    <DropdownMenuSubTrigger\r\n      data-slot=\"menubar-sub-trigger\"\r\n      data-inset={inset}\r\n      className={cn(\r\n        \"focus:bg-accent focus:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground gap-1.5 rounded-md px-1.5 py-1 text-sm data-inset:pl-7 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MenubarSubContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof DropdownMenuSubContent>) {\r\n  return (\r\n    <DropdownMenuSubContent\r\n      data-slot=\"menubar-sub-content\"\r\n      className={cn(\r\n        'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 min-w-32 rounded-lg p-1 shadow-lg ring-1 duration-100 cn-menu-target cn-menu-translucent',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Menubar,\r\n  MenubarPortal,\r\n  MenubarMenu,\r\n  MenubarTrigger,\r\n  MenubarContent,\r\n  MenubarGroup,\r\n  MenubarSeparator,\r\n  MenubarLabel,\r\n  MenubarItem,\r\n  MenubarShortcut,\r\n  MenubarCheckboxItem,\r\n  MenubarRadioGroup,\r\n  MenubarRadioItem,\r\n  MenubarSub,\r\n  MenubarSubTrigger,\r\n  MenubarSubContent,\r\n};\r\n","handborne/source/components/ui/message-scroller.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport {\r\n  MessageScroller as MessageScrollerPrimitive,\r\n  useMessageScroller,\r\n  useMessageScrollerScrollable,\r\n  useMessageScrollerVisibility,\r\n} from '@shadcn/react/message-scroller';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { ArrowDownIcon } from 'lucide-react';\r\n\r\nfunction MessageScrollerProvider(\r\n  props: React.ComponentProps<typeof MessageScrollerPrimitive.Provider>,\r\n) {\r\n  return <MessageScrollerPrimitive.Provider {...props} />;\r\n}\r\n\r\nfunction MessageScroller({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Root>) {\r\n  return (\r\n    <MessageScrollerPrimitive.Root\r\n      data-slot=\"message-scroller\"\r\n      className={cn(\r\n        'group/message-scroller relative flex size-full min-h-0 flex-col overflow-hidden',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageScrollerViewport({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Viewport>) {\r\n  return (\r\n    <MessageScrollerPrimitive.Viewport\r\n      data-slot=\"message-scroller-viewport\"\r\n      className={cn(\r\n        'size-full min-h-0 min-w-0 scroll-fade-b scrollbar-thin scrollbar-gutter-stable overflow-y-auto overscroll-contain contain-content data-autoscrolling:scrollbar-thumb-transparent data-autoscrolling:scrollbar-track-transparent',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageScrollerContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Content>) {\r\n  return (\r\n    <MessageScrollerPrimitive.Content\r\n      data-slot=\"message-scroller-content\"\r\n      className={cn('gap-6 flex h-max min-h-full flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageScrollerItem({\r\n  className,\r\n  scrollAnchor = false,\r\n  ...props\r\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Item>) {\r\n  return (\r\n    <MessageScrollerPrimitive.Item\r\n      data-slot=\"message-scroller-item\"\r\n      scrollAnchor={scrollAnchor}\r\n      className={cn(\r\n        'min-w-0 shrink-0 [contain-intrinsic-size:auto_10rem] [content-visibility:auto]',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageScrollerButton({\r\n  direction = 'end',\r\n  className,\r\n  children,\r\n  render,\r\n  variant = 'secondary',\r\n  size = 'icon-sm',\r\n  ...props\r\n}: React.ComponentProps<typeof MessageScrollerPrimitive.Button> &\r\n  Pick<React.ComponentProps<typeof Button>, 'variant' | 'size'>) {\r\n  return (\r\n    <MessageScrollerPrimitive.Button\r\n      data-slot=\"message-scroller-button\"\r\n      data-direction={direction}\r\n      data-variant={variant}\r\n      data-size={size}\r\n      direction={direction}\r\n      className={cn(\r\n        'absolute inset-s-1/2 -translate-x-1/2 border-border bg-background text-foreground transition-[translate,scale,opacity] duration-200 hover:bg-muted hover:text-foreground data-[active=false]:pointer-events-none data-[active=false]:scale-95 data-[active=false]:opacity-0 data-[active=false]:duration-400 data-[active=false]:ease-[cubic-bezier(0.7,0,0.84,0)] data-[active=true]:translate-y-0 data-[active=true]:scale-100 data-[active=true]:opacity-100 data-[active=true]:ease-[cubic-bezier(0.23,1,0.32,1)] data-[direction=end]:bottom-4 data-[direction=end]:data-[active=false]:translate-y-full data-[direction=start]:top-4 data-[direction=start]:data-[active=false]:-translate-y-full rtl:translate-x-1/2 data-[direction=start]:[&_svg]:rotate-180',\r\n        className,\r\n      )}\r\n      render={render ?? <Button variant={variant} size={size} />}\r\n      {...props}\r\n    >\r\n      {children ?? (\r\n        <>\r\n          <ArrowDownIcon />\r\n          <span className=\"sr-only\">\r\n            {direction === 'end' ? 'Scroll to end' : 'Scroll to start'}\r\n          </span>\r\n        </>\r\n      )}\r\n    </MessageScrollerPrimitive.Button>\r\n  );\r\n}\r\n\r\nexport {\r\n  MessageScrollerProvider,\r\n  MessageScroller,\r\n  MessageScrollerViewport,\r\n  MessageScrollerContent,\r\n  MessageScrollerItem,\r\n  MessageScrollerButton,\r\n  useMessageScroller,\r\n  useMessageScrollerScrollable,\r\n  useMessageScrollerVisibility,\r\n};\r\n","handborne/source/components/ui/message.tsx":"import * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction MessageGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"message-group\"\r\n      className={cn('gap-2 flex min-w-0 flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction Message({\r\n  className,\r\n  align = 'start',\r\n  ...props\r\n}: React.ComponentProps<'div'> & { align?: 'start' | 'end' }) {\r\n  return (\r\n    <div\r\n      data-slot=\"message\"\r\n      data-align={align}\r\n      className={cn(\r\n        'text-sm gap-2 group/message relative flex w-full min-w-0 data-[align=end]:flex-row-reverse',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageAvatar({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"message-avatar\"\r\n      className={cn(\r\n        'min-w-8 group-has-data-[slot=message-footer]/message:-translate-y-8 flex w-fit shrink-0 items-center justify-center self-end overflow-hidden rounded-full bg-muted',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"message-content\"\r\n      className={cn(\r\n        'gap-2.5 group-data-[align=end]/message:*:data-slot:self-end flex w-full min-w-0 flex-col wrap-break-word',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"message-header\"\r\n      className={cn(\r\n        'text-xs font-medium text-muted-foreground px-3 group-has-data-[variant=ghost]/message:px-0 flex max-w-full min-w-0 items-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction MessageFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"message-footer\"\r\n      className={cn(\r\n        'text-xs font-medium text-muted-foreground px-3 group-has-data-[variant=ghost]/message:px-0 flex max-w-full min-w-0 items-center group-data-[align=end]/message:justify-end',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  MessageGroup,\r\n  Message,\r\n  MessageAvatar,\r\n  MessageContent,\r\n  MessageFooter,\r\n  MessageHeader,\r\n};\r\n","handborne/source/components/ui/native-select.tsx":"import * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronDownIcon } from 'lucide-react';\r\n\r\ntype NativeSelectProps = Omit<React.ComponentProps<'select'>, 'size'> & {\r\n  size?: 'sm' | 'default';\r\n};\r\n\r\nfunction NativeSelect({\r\n  className,\r\n  size = 'default',\r\n  ...props\r\n}: NativeSelectProps) {\r\n  return (\r\n    <div\r\n      className={cn(\r\n        'group/native-select relative w-fit has-[select:disabled]:opacity-50',\r\n        className,\r\n      )}\r\n      data-slot=\"native-select-wrapper\"\r\n      data-size={size}\r\n    >\r\n      <select\r\n        data-slot=\"native-select\"\r\n        data-size={size}\r\n        className=\"border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 h-8 w-full min-w-0 appearance-none rounded-lg border bg-transparent py-1 pr-8 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] data-[size=sm]:py-0.5 outline-none disabled:pointer-events-none disabled:cursor-not-allowed\"\r\n        {...props}\r\n      />\r\n      <ChevronDownIcon\r\n        className=\"text-muted-foreground top-1/2 right-2.5 size-4 -translate-y-1/2 pointer-events-none absolute select-none\"\r\n        aria-hidden=\"true\"\r\n        data-slot=\"native-select-icon\"\r\n      />\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction NativeSelectOption({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'option'>) {\r\n  return (\r\n    <option\r\n      data-slot=\"native-select-option\"\r\n      className={cn('bg-[Canvas] text-[CanvasText]', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NativeSelectOptGroup({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'optgroup'>) {\r\n  return (\r\n    <optgroup\r\n      data-slot=\"native-select-optgroup\"\r\n      className={cn('bg-[Canvas] text-[CanvasText]', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { NativeSelect, NativeSelectOptGroup, NativeSelectOption };\r\n","handborne/source/components/ui/navigation-menu.tsx":"import { NavigationMenu as NavigationMenuPrimitive } from '@base-ui/react/navigation-menu';\r\nimport { cva } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronDownIcon } from 'lucide-react';\r\n\r\nfunction NavigationMenu({\r\n  align = 'start',\r\n  className,\r\n  children,\r\n  ...props\r\n}: NavigationMenuPrimitive.Root.Props &\r\n  Pick<NavigationMenuPrimitive.Positioner.Props, 'align'>) {\r\n  return (\r\n    <NavigationMenuPrimitive.Root\r\n      data-slot=\"navigation-menu\"\r\n      className={cn(\r\n        'group/navigation-menu relative flex max-w-max flex-1 items-center justify-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <NavigationMenuPositioner align={align} />\r\n    </NavigationMenuPrimitive.Root>\r\n  );\r\n}\r\n\r\nfunction NavigationMenuList({\r\n  className,\r\n  ...props\r\n}: React.ComponentPropsWithRef<typeof NavigationMenuPrimitive.List>) {\r\n  return (\r\n    <NavigationMenuPrimitive.List\r\n      data-slot=\"navigation-menu-list\"\r\n      className={cn(\r\n        'gap-0 group flex flex-1 list-none items-center justify-center',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NavigationMenuItem({\r\n  className,\r\n  ...props\r\n}: React.ComponentPropsWithRef<typeof NavigationMenuPrimitive.Item>) {\r\n  return (\r\n    <NavigationMenuPrimitive.Item\r\n      data-slot=\"navigation-menu-item\"\r\n      className={cn('relative', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst navigationMenuTriggerStyle = cva(\r\n  'hover:bg-muted focus:bg-muted data-open:hover:bg-muted data-open:focus:bg-muted data-open:bg-muted/50 focus-visible:ring-ring/50 data-popup-open:bg-muted/50 data-popup-open:hover:bg-muted rounded-lg px-2.5 py-1.5 text-sm font-medium transition-all focus-visible:ring-3 focus-visible:outline-1 disabled:opacity-50 group/navigation-menu-trigger inline-flex h-9 w-max items-center justify-center outline-none disabled:pointer-events-none',\r\n);\r\n\r\nfunction NavigationMenuTrigger({\r\n  className,\r\n  children,\r\n  ...props\r\n}: NavigationMenuPrimitive.Trigger.Props) {\r\n  return (\r\n    <NavigationMenuPrimitive.Trigger\r\n      data-slot=\"navigation-menu-trigger\"\r\n      className={cn(navigationMenuTriggerStyle(), 'group', className)}\r\n      {...props}\r\n    >\r\n      {children}{' '}\r\n      <ChevronDownIcon\r\n        className=\"relative top-px ml-1 size-3 transition duration-300 group-data-open/navigation-menu-trigger:rotate-180 group-data-popup-open/navigation-menu-trigger:rotate-180\"\r\n        aria-hidden=\"true\"\r\n      />\r\n    </NavigationMenuPrimitive.Trigger>\r\n  );\r\n}\r\n\r\nfunction NavigationMenuContent({\r\n  className,\r\n  ...props\r\n}: NavigationMenuPrimitive.Content.Props) {\r\n  return (\r\n    <NavigationMenuPrimitive.Content\r\n      data-slot=\"navigation-menu-content\"\r\n      className={cn(\r\n        'data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 group-data-[viewport=false]/navigation-menu:bg-popover group-data-[viewport=false]/navigation-menu:text-popover-foreground group-data-[viewport=false]/navigation-menu:data-open:animate-in group-data-[viewport=false]/navigation-menu:data-closed:animate-out group-data-[viewport=false]/navigation-menu:data-closed:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-open:zoom-in-95 group-data-[viewport=false]/navigation-menu:data-open:fade-in-0 group-data-[viewport=false]/navigation-menu:data-closed:fade-out-0 group-data-[viewport=false]/navigation-menu:ring-foreground/10 p-1 ease-[cubic-bezier(0.22,1,0.36,1)] group-data-[viewport=false]/navigation-menu:rounded-lg group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:ring-1 group-data-[viewport=false]/navigation-menu:duration-300 data-ending-style:data-activation-direction=left:translate-x-[50%] data-ending-style:data-activation-direction=right:translate-x-[-50%] data-starting-style:data-activation-direction=left:translate-x-[-50%] data-starting-style:data-activation-direction=right:translate-x-[50%] h-full w-auto transition-[opacity,transform,translate] duration-[0.35s] data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NavigationMenuPositioner({\r\n  className,\r\n  side = 'bottom',\r\n  sideOffset = 8,\r\n  align = 'start',\r\n  alignOffset = 0,\r\n  ...props\r\n}: NavigationMenuPrimitive.Positioner.Props) {\r\n  return (\r\n    <NavigationMenuPrimitive.Portal>\r\n      <NavigationMenuPrimitive.Positioner\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        className={cn(\r\n          'ease-[cubic-bezier(0.22,1,0.36,1)] data-[side=bottom]:before:top-[-10px] data-[side=bottom]:before:right-0 data-[side=bottom]:before:left-0 isolate z-50 h-(--positioner-height) w-(--positioner-width) max-w-(--available-width) transition-[top,left,right,bottom] duration-[0.35s] data-instant:transition-none',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        <NavigationMenuPrimitive.Popup className=\"bg-popover text-popover-foreground ring-foreground/10 rounded-lg shadow ring-1 outline-none data-ending-style:scale-90 data-ending-style:opacity-0 data-ending-style:duration-150 data-starting-style:scale-90 data-starting-style:opacity-0 data-[ending-style]:easing-[ease] xs:w-(--popup-width) relative h-(--popup-height) w-(--popup-width) origin-(--transform-origin) transition-[opacity,transform,width,height,scale,translate] duration-[0.35s] ease-[cubic-bezier(0.22,1,0.36,1)]\">\r\n          <NavigationMenuPrimitive.Viewport className=\"relative size-full overflow-hidden\" />\r\n        </NavigationMenuPrimitive.Popup>\r\n      </NavigationMenuPrimitive.Positioner>\r\n    </NavigationMenuPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction NavigationMenuLink({\r\n  className,\r\n  ...props\r\n}: NavigationMenuPrimitive.Link.Props) {\r\n  return (\r\n    <NavigationMenuPrimitive.Link\r\n      data-slot=\"navigation-menu-link\"\r\n      className={cn(\r\n        \"data-active:focus:bg-muted data-active:hover:bg-muted data-active:bg-muted/50 focus-visible:ring-ring/50 hover:bg-muted focus:bg-muted flex items-center gap-2 rounded-lg p-2 text-sm transition-all outline-none focus-visible:ring-3 focus-visible:outline-1 in-data-[slot=navigation-menu-content]:rounded-md [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction NavigationMenuIndicator({\r\n  className,\r\n  ...props\r\n}: React.ComponentPropsWithRef<typeof NavigationMenuPrimitive.Icon>) {\r\n  return (\r\n    <NavigationMenuPrimitive.Icon\r\n      data-slot=\"navigation-menu-indicator\"\r\n      className={cn(\r\n        'data-[state=visible]:animate-in data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-1 flex h-1.5 items-end justify-center overflow-hidden',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <div className=\"bg-border rounded-tl-sm shadow-md relative top-[60%] h-2 w-2 rotate-45\" />\r\n    </NavigationMenuPrimitive.Icon>\r\n  );\r\n}\r\n\r\nexport {\r\n  NavigationMenu,\r\n  NavigationMenuContent,\r\n  NavigationMenuIndicator,\r\n  NavigationMenuItem,\r\n  NavigationMenuLink,\r\n  NavigationMenuList,\r\n  NavigationMenuTrigger,\r\n  navigationMenuTriggerStyle,\r\n  NavigationMenuPositioner,\r\n};\r\n","handborne/source/components/ui/pagination.tsx":"import * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport {\r\n  ChevronLeftIcon,\r\n  ChevronRightIcon,\r\n  MoreHorizontalIcon,\r\n} from 'lucide-react';\r\n\r\nfunction Pagination({ className, ...props }: React.ComponentProps<'nav'>) {\r\n  return (\r\n    <nav\r\n      role=\"navigation\"\r\n      aria-label=\"pagination\"\r\n      data-slot=\"pagination\"\r\n      className={cn('mx-auto flex w-full justify-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction PaginationContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'ul'>) {\r\n  return (\r\n    <ul\r\n      data-slot=\"pagination-content\"\r\n      className={cn('gap-0.5 flex items-center', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction PaginationItem({ ...props }: React.ComponentProps<'li'>) {\r\n  return <li data-slot=\"pagination-item\" {...props} />;\r\n}\r\n\r\ntype PaginationLinkProps = {\r\n  isActive?: boolean;\r\n} & Pick<React.ComponentProps<typeof Button>, 'size'> &\r\n  React.ComponentProps<'a'>;\r\n\r\nfunction PaginationLink({\r\n  className,\r\n  isActive,\r\n  size = 'icon',\r\n  ...props\r\n}: PaginationLinkProps) {\r\n  return (\r\n    <Button\r\n      variant={isActive ? 'outline' : 'ghost'}\r\n      size={size}\r\n      className={cn(className)}\r\n      nativeButton={false}\r\n      render={\r\n        <a\r\n          aria-current={isActive ? 'page' : undefined}\r\n          data-slot=\"pagination-link\"\r\n          data-active={isActive}\r\n          {...props}\r\n        />\r\n      }\r\n    />\r\n  );\r\n}\r\n\r\nfunction PaginationPrevious({\r\n  className,\r\n  text = 'Previous',\r\n  ...props\r\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\r\n  return (\r\n    <PaginationLink\r\n      aria-label=\"Go to previous page\"\r\n      size=\"default\"\r\n      className={cn('pl-1.5!', className)}\r\n      {...props}\r\n    >\r\n      <ChevronLeftIcon data-icon=\"inline-start\" className=\"cn-rtl-flip\" />\r\n      <span className=\"hidden sm:block\">{text}</span>\r\n    </PaginationLink>\r\n  );\r\n}\r\n\r\nfunction PaginationNext({\r\n  className,\r\n  text = 'Next',\r\n  ...props\r\n}: React.ComponentProps<typeof PaginationLink> & { text?: string }) {\r\n  return (\r\n    <PaginationLink\r\n      aria-label=\"Go to next page\"\r\n      size=\"default\"\r\n      className={cn('pr-1.5!', className)}\r\n      {...props}\r\n    >\r\n      <span className=\"hidden sm:block\">{text}</span>\r\n      <ChevronRightIcon data-icon=\"inline-end\" className=\"cn-rtl-flip\" />\r\n    </PaginationLink>\r\n  );\r\n}\r\n\r\nfunction PaginationEllipsis({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'span'>) {\r\n  return (\r\n    <span\r\n      aria-hidden\r\n      data-slot=\"pagination-ellipsis\"\r\n      className={cn(\r\n        \"size-8 [&_svg:not([class*='size-'])]:size-4 flex items-center justify-center\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <MoreHorizontalIcon />\r\n      <span className=\"sr-only\">More pages</span>\r\n    </span>\r\n  );\r\n}\r\n\r\nexport {\r\n  Pagination,\r\n  PaginationContent,\r\n  PaginationEllipsis,\r\n  PaginationItem,\r\n  PaginationLink,\r\n  PaginationNext,\r\n  PaginationPrevious,\r\n};\r\n","handborne/source/components/ui/popover.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Popover as PopoverPrimitive } from '@base-ui/react/popover';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\r\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />;\r\n}\r\n\r\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\r\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />;\r\n}\r\n\r\nfunction PopoverContent({\r\n  className,\r\n  align = 'center',\r\n  alignOffset = 0,\r\n  side = 'bottom',\r\n  sideOffset = 4,\r\n  ...props\r\n}: PopoverPrimitive.Popup.Props &\r\n  Pick<\r\n    PopoverPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset'\r\n  >) {\r\n  return (\r\n    <PopoverPrimitive.Portal>\r\n      <PopoverPrimitive.Positioner\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        className=\"isolate z-50\"\r\n      >\r\n        <PopoverPrimitive.Popup\r\n          data-slot=\"popover-content\"\r\n          className={cn(\r\n            'bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 flex flex-col gap-2.5 rounded-lg p-2.5 text-sm shadow-md ring-1 duration-100 data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 z-50 w-72 origin-(--transform-origin) outline-hidden',\r\n            className,\r\n          )}\r\n          {...props}\r\n        />\r\n      </PopoverPrimitive.Positioner>\r\n    </PopoverPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"popover-header\"\r\n      className={cn('flex flex-col gap-0.5 text-sm', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\r\n  return (\r\n    <PopoverPrimitive.Title\r\n      data-slot=\"popover-title\"\r\n      className={cn('font-medium', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction PopoverDescription({\r\n  className,\r\n  ...props\r\n}: PopoverPrimitive.Description.Props) {\r\n  return (\r\n    <PopoverPrimitive.Description\r\n      data-slot=\"popover-description\"\r\n      className={cn('text-muted-foreground', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Popover,\r\n  PopoverContent,\r\n  PopoverDescription,\r\n  PopoverHeader,\r\n  PopoverTitle,\r\n  PopoverTrigger,\r\n};\r\n","handborne/source/components/ui/progress.tsx":"'use client';\r\n\r\nimport { Progress as ProgressPrimitive } from '@base-ui/react/progress';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Progress({\r\n  className,\r\n  children,\r\n  value,\r\n  ...props\r\n}: ProgressPrimitive.Root.Props) {\r\n  return (\r\n    <ProgressPrimitive.Root\r\n      value={value}\r\n      data-slot=\"progress\"\r\n      className={cn('flex flex-wrap gap-3', className)}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <ProgressTrack>\r\n        <ProgressIndicator />\r\n      </ProgressTrack>\r\n    </ProgressPrimitive.Root>\r\n  );\r\n}\r\n\r\nfunction ProgressTrack({ className, ...props }: ProgressPrimitive.Track.Props) {\r\n  return (\r\n    <ProgressPrimitive.Track\r\n      className={cn(\r\n        'bg-muted h-1 rounded-full relative flex w-full items-center overflow-x-hidden',\r\n        className,\r\n      )}\r\n      data-slot=\"progress-track\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ProgressIndicator({\r\n  className,\r\n  ...props\r\n}: ProgressPrimitive.Indicator.Props) {\r\n  return (\r\n    <ProgressPrimitive.Indicator\r\n      data-slot=\"progress-indicator\"\r\n      className={cn('bg-primary h-full transition-all', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ProgressLabel({ className, ...props }: ProgressPrimitive.Label.Props) {\r\n  return (\r\n    <ProgressPrimitive.Label\r\n      className={cn('text-sm font-medium', className)}\r\n      data-slot=\"progress-label\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ProgressValue({ className, ...props }: ProgressPrimitive.Value.Props) {\r\n  return (\r\n    <ProgressPrimitive.Value\r\n      className={cn(\r\n        'text-muted-foreground ml-auto text-sm tabular-nums',\r\n        className,\r\n      )}\r\n      data-slot=\"progress-value\"\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Progress,\r\n  ProgressTrack,\r\n  ProgressIndicator,\r\n  ProgressLabel,\r\n  ProgressValue,\r\n};\r\n","handborne/source/components/ui/radio-group.tsx":"'use client';\r\n\r\nimport { Radio as RadioPrimitive } from '@base-ui/react/radio';\r\nimport { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {\r\n  return (\r\n    <RadioGroupPrimitive\r\n      data-slot=\"radio-group\"\r\n      className={cn('grid gap-2 w-full', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {\r\n  return (\r\n    <RadioPrimitive.Root\r\n      data-slot=\"radio-group-item\"\r\n      className={cn(\r\n        'border-input dark:bg-input/30 data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary data-checked:border-primary aria-invalid:aria-checked:border-primary aria-invalid:border-destructive focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 dark:aria-invalid:border-destructive/50 flex size-4 rounded-full focus-visible:ring-3 aria-invalid:ring-3 group-has-[:focus-visible]/field-label:ring-0 group-has-[:focus-visible]/field-label:not-data-checked:border-input group-has-[:focus-visible]/field-label:data-checked:border-primary group/radio-group-item peer relative aspect-square shrink-0 border outline-none after:absolute after:-inset-x-3 after:-inset-y-2 disabled:cursor-not-allowed disabled:opacity-50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <RadioPrimitive.Indicator\r\n        data-slot=\"radio-group-indicator\"\r\n        className=\"flex size-4 items-center justify-center\"\r\n      >\r\n        <span className=\"bg-primary-foreground absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full\" />\r\n      </RadioPrimitive.Indicator>\r\n    </RadioPrimitive.Root>\r\n  );\r\n}\r\n\r\nexport { RadioGroup, RadioGroupItem };\r\n","handborne/source/components/ui/resizable.tsx":"'use client';\r\n\r\nimport * as ResizablePrimitive from 'react-resizable-panels';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction ResizablePanelGroup({\r\n  className,\r\n  ...props\r\n}: ResizablePrimitive.GroupProps) {\r\n  return (\r\n    <ResizablePrimitive.Group\r\n      data-slot=\"resizable-panel-group\"\r\n      className={cn(\r\n        'flex h-full w-full aria-[orientation=vertical]:flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ResizablePanel({ ...props }: ResizablePrimitive.PanelProps) {\r\n  return <ResizablePrimitive.Panel data-slot=\"resizable-panel\" {...props} />;\r\n}\r\n\r\nfunction ResizableHandle({\r\n  withHandle,\r\n  className,\r\n  ...props\r\n}: ResizablePrimitive.SeparatorProps & {\r\n  withHandle?: boolean;\r\n}) {\r\n  return (\r\n    <ResizablePrimitive.Separator\r\n      data-slot=\"resizable-handle\"\r\n      className={cn(\r\n        'relative flex w-px items-center justify-center bg-border ring-offset-background after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:ring-1 focus-visible:ring-ring focus-visible:outline-hidden aria-[orientation=horizontal]:h-px aria-[orientation=horizontal]:w-full aria-[orientation=horizontal]:after:left-0 aria-[orientation=horizontal]:after:h-1 aria-[orientation=horizontal]:after:w-full aria-[orientation=horizontal]:after:translate-x-0 aria-[orientation=horizontal]:after:-translate-y-1/2 [&[aria-orientation=horizontal]>div]:rotate-90',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {withHandle && (\r\n        <div className=\"bg-border h-6 w-1 rounded-lg z-10 flex shrink-0\" />\r\n      )}\r\n    </ResizablePrimitive.Separator>\r\n  );\r\n}\r\n\r\nexport { ResizableHandle, ResizablePanel, ResizablePanelGroup };\r\n","handborne/source/components/ui/scroll-area.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { ScrollArea as ScrollAreaPrimitive } from '@base-ui/react/scroll-area';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction ScrollArea({\r\n  className,\r\n  children,\r\n  ...props\r\n}: ScrollAreaPrimitive.Root.Props) {\r\n  return (\r\n    <ScrollAreaPrimitive.Root\r\n      data-slot=\"scroll-area\"\r\n      className={cn('relative', className)}\r\n      {...props}\r\n    >\r\n      <ScrollAreaPrimitive.Viewport\r\n        data-slot=\"scroll-area-viewport\"\r\n        className=\"size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1\"\r\n      >\r\n        {children}\r\n      </ScrollAreaPrimitive.Viewport>\r\n      <ScrollBar />\r\n      <ScrollAreaPrimitive.Corner />\r\n    </ScrollAreaPrimitive.Root>\r\n  );\r\n}\r\n\r\nfunction ScrollBar({\r\n  className,\r\n  orientation = 'vertical',\r\n  ...props\r\n}: ScrollAreaPrimitive.Scrollbar.Props) {\r\n  return (\r\n    <ScrollAreaPrimitive.Scrollbar\r\n      data-slot=\"scroll-area-scrollbar\"\r\n      data-orientation={orientation}\r\n      orientation={orientation}\r\n      className={cn(\r\n        'data-horizontal:h-2.5 data-horizontal:flex-col data-horizontal:border-t data-horizontal:border-t-transparent data-vertical:h-full data-vertical:w-2.5 data-vertical:border-l data-vertical:border-l-transparent flex touch-none p-px transition-colors select-none',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <ScrollAreaPrimitive.Thumb\r\n        data-slot=\"scroll-area-thumb\"\r\n        className=\"rounded-full relative flex-1 bg-border\"\r\n      />\r\n    </ScrollAreaPrimitive.Scrollbar>\r\n  );\r\n}\r\n\r\nexport { ScrollArea, ScrollBar };\r\n","handborne/source/components/ui/select.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Select as SelectPrimitive } from '@base-ui/react/select';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { ChevronDownIcon, CheckIcon, ChevronUpIcon } from 'lucide-react';\r\n\r\nconst Select = SelectPrimitive.Root;\r\n\r\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\r\n  return (\r\n    <SelectPrimitive.Group\r\n      data-slot=\"select-group\"\r\n      className={cn('scroll-my-1 p-1', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\r\n  return (\r\n    <SelectPrimitive.Value\r\n      data-slot=\"select-value\"\r\n      className={cn('flex flex-1 text-left', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SelectTrigger({\r\n  className,\r\n  size = 'default',\r\n  children,\r\n  ...props\r\n}: SelectPrimitive.Trigger.Props & {\r\n  size?: 'sm' | 'default';\r\n}) {\r\n  return (\r\n    <SelectPrimitive.Trigger\r\n      data-slot=\"select-trigger\"\r\n      data-size={size}\r\n      className={cn(\r\n        \"flex w-fit items-center justify-between gap-1.5 rounded-lg border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap transition-colors outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n      <SelectPrimitive.Icon\r\n        render={\r\n          <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\r\n        }\r\n      />\r\n    </SelectPrimitive.Trigger>\r\n  );\r\n}\r\n\r\nfunction SelectContent({\r\n  className,\r\n  children,\r\n  side = 'bottom',\r\n  sideOffset = 4,\r\n  align = 'center',\r\n  alignOffset = 0,\r\n  alignItemWithTrigger = true,\r\n  ...props\r\n}: SelectPrimitive.Popup.Props &\r\n  Pick<\r\n    SelectPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset' | 'alignItemWithTrigger'\r\n  >) {\r\n  return (\r\n    <SelectPrimitive.Portal>\r\n      <SelectPrimitive.Positioner\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        alignItemWithTrigger={alignItemWithTrigger}\r\n        className=\"isolate z-50\"\r\n      >\r\n        <SelectPrimitive.Popup\r\n          data-slot=\"select-content\"\r\n          data-align-trigger={alignItemWithTrigger}\r\n          className={cn(\r\n            'relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\r\n            className,\r\n          )}\r\n          {...props}\r\n        >\r\n          <SelectScrollUpButton />\r\n          <SelectPrimitive.List>{children}</SelectPrimitive.List>\r\n          <SelectScrollDownButton />\r\n        </SelectPrimitive.Popup>\r\n      </SelectPrimitive.Positioner>\r\n    </SelectPrimitive.Portal>\r\n  );\r\n}\r\n\r\nfunction SelectLabel({\r\n  className,\r\n  ...props\r\n}: SelectPrimitive.GroupLabel.Props) {\r\n  return (\r\n    <SelectPrimitive.GroupLabel\r\n      data-slot=\"select-label\"\r\n      className={cn('px-1.5 py-1 text-xs text-muted-foreground', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SelectItem({\r\n  className,\r\n  children,\r\n  ...props\r\n}: SelectPrimitive.Item.Props) {\r\n  return (\r\n    <SelectPrimitive.Item\r\n      data-slot=\"select-item\"\r\n      className={cn(\r\n        \"relative flex w-full cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\r\n        {children}\r\n      </SelectPrimitive.ItemText>\r\n      <SelectPrimitive.ItemIndicator\r\n        render={\r\n          <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\r\n        }\r\n      >\r\n        <CheckIcon className=\"pointer-events-none\" />\r\n      </SelectPrimitive.ItemIndicator>\r\n    </SelectPrimitive.Item>\r\n  );\r\n}\r\n\r\nfunction SelectSeparator({\r\n  className,\r\n  ...props\r\n}: SelectPrimitive.Separator.Props) {\r\n  return (\r\n    <SelectPrimitive.Separator\r\n      data-slot=\"select-separator\"\r\n      className={cn('pointer-events-none -mx-1 my-1 h-px bg-border', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SelectScrollUpButton({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\r\n  return (\r\n    <SelectPrimitive.ScrollUpArrow\r\n      data-slot=\"select-scroll-up-button\"\r\n      className={cn(\r\n        \"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <ChevronUpIcon />\r\n    </SelectPrimitive.ScrollUpArrow>\r\n  );\r\n}\r\n\r\nfunction SelectScrollDownButton({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\r\n  return (\r\n    <SelectPrimitive.ScrollDownArrow\r\n      data-slot=\"select-scroll-down-button\"\r\n      className={cn(\r\n        \"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <ChevronDownIcon />\r\n    </SelectPrimitive.ScrollDownArrow>\r\n  );\r\n}\r\n\r\nexport {\r\n  Select,\r\n  SelectContent,\r\n  SelectGroup,\r\n  SelectItem,\r\n  SelectLabel,\r\n  SelectScrollDownButton,\r\n  SelectScrollUpButton,\r\n  SelectSeparator,\r\n  SelectTrigger,\r\n  SelectValue,\r\n};\r\n","handborne/source/components/ui/separator.tsx":"'use client';\r\n\r\nimport { Separator as SeparatorPrimitive } from '@base-ui/react/separator';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Separator({\r\n  className,\r\n  orientation = 'horizontal',\r\n  ...props\r\n}: SeparatorPrimitive.Props) {\r\n  return (\r\n    <SeparatorPrimitive\r\n      data-slot=\"separator\"\r\n      orientation={orientation}\r\n      className={cn(\r\n        'shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Separator };\r\n","handborne/source/components/ui/sheet.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Dialog as SheetPrimitive } from '@base-ui/react/dialog';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { XIcon } from 'lucide-react';\r\n\r\nfunction Sheet({ ...props }: SheetPrimitive.Root.Props) {\r\n  return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\r\n}\r\n\r\nfunction SheetTrigger({ ...props }: SheetPrimitive.Trigger.Props) {\r\n  return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\r\n}\r\n\r\nfunction SheetClose({ ...props }: SheetPrimitive.Close.Props) {\r\n  return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\r\n}\r\n\r\nfunction SheetPortal({ ...props }: SheetPrimitive.Portal.Props) {\r\n  return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />;\r\n}\r\n\r\nfunction SheetOverlay({ className, ...props }: SheetPrimitive.Backdrop.Props) {\r\n  return (\r\n    <SheetPrimitive.Backdrop\r\n      data-slot=\"sheet-overlay\"\r\n      className={cn(\r\n        'bg-black/10 supports-backdrop-filter:backdrop-blur-xs fixed inset-0 z-50 transition-opacity duration-150 data-ending-style:opacity-0 data-starting-style:opacity-0',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SheetContent({\r\n  className,\r\n  children,\r\n  side = 'right',\r\n  showCloseButton = true,\r\n  ...props\r\n}: SheetPrimitive.Popup.Props & {\r\n  side?: 'top' | 'right' | 'bottom' | 'left';\r\n  showCloseButton?: boolean;\r\n}) {\r\n  return (\r\n    <SheetPortal>\r\n      <SheetOverlay />\r\n      <SheetPrimitive.Popup\r\n        data-slot=\"sheet-content\"\r\n        data-side={side}\r\n        className={cn(\r\n          'bg-popover text-popover-foreground fixed z-50 flex flex-col gap-4 bg-clip-padding text-sm shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-ending-style:opacity-0 data-starting-style:opacity-0 data-[side=bottom]:data-ending-style:translate-y-[2.5rem] data-[side=bottom]:data-starting-style:translate-y-[2.5rem] data-[side=left]:data-ending-style:translate-x-[-2.5rem] data-[side=left]:data-starting-style:translate-x-[-2.5rem] data-[side=right]:data-ending-style:translate-x-[2.5rem] data-[side=right]:data-starting-style:translate-x-[2.5rem] data-[side=top]:data-ending-style:translate-y-[-2.5rem] data-[side=top]:data-starting-style:translate-y-[-2.5rem]',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n        {showCloseButton && (\r\n          <SheetPrimitive.Close\r\n            data-slot=\"sheet-close\"\r\n            render={\r\n              <Button\r\n                variant=\"ghost\"\r\n                className=\"absolute top-3 right-3\"\r\n                size=\"icon-sm\"\r\n              />\r\n            }\r\n          >\r\n            <XIcon />\r\n            <span className=\"sr-only\">Close</span>\r\n          </SheetPrimitive.Close>\r\n        )}\r\n      </SheetPrimitive.Popup>\r\n    </SheetPortal>\r\n  );\r\n}\r\n\r\nfunction SheetHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sheet-header\"\r\n      className={cn('gap-0.5 p-4 flex flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SheetFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sheet-footer\"\r\n      className={cn('gap-2 p-4 mt-auto flex flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SheetTitle({ className, ...props }: SheetPrimitive.Title.Props) {\r\n  return (\r\n    <SheetPrimitive.Title\r\n      data-slot=\"sheet-title\"\r\n      className={cn(\r\n        'text-foreground text-base font-medium cn-font-heading',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SheetDescription({\r\n  className,\r\n  ...props\r\n}: SheetPrimitive.Description.Props) {\r\n  return (\r\n    <SheetPrimitive.Description\r\n      data-slot=\"sheet-description\"\r\n      className={cn('text-muted-foreground text-sm', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Sheet,\r\n  SheetTrigger,\r\n  SheetClose,\r\n  SheetContent,\r\n  SheetHeader,\r\n  SheetFooter,\r\n  SheetTitle,\r\n  SheetDescription,\r\n};\r\n","handborne/source/components/ui/sidebar.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { mergeProps } from '@base-ui/react/merge-props';\r\nimport { useRender } from '@base-ui/react/use-render';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { useIsMobile } from '@/hooks/use-mobile';\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport { Input } from '@/components/ui/input';\r\nimport { Separator } from '@/components/ui/separator';\r\nimport {\r\n  Sheet,\r\n  SheetContent,\r\n  SheetDescription,\r\n  SheetHeader,\r\n  SheetTitle,\r\n} from '@/components/ui/sheet';\r\nimport { Skeleton } from '@/components/ui/skeleton';\r\nimport {\r\n  Tooltip,\r\n  TooltipContent,\r\n  TooltipTrigger,\r\n} from '@/components/ui/tooltip';\r\nimport { PanelLeftIcon } from 'lucide-react';\r\n\r\nconst SIDEBAR_COOKIE_NAME = 'sidebar_state';\r\nconst SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7;\r\nconst SIDEBAR_WIDTH = '16rem';\r\nconst SIDEBAR_WIDTH_MOBILE = '18rem';\r\nconst SIDEBAR_WIDTH_ICON = '3rem';\r\nconst SIDEBAR_KEYBOARD_SHORTCUT = 'b';\r\n\r\ntype SidebarContextProps = {\r\n  state: 'expanded' | 'collapsed';\r\n  open: boolean;\r\n  setOpen: (open: boolean) => void;\r\n  openMobile: boolean;\r\n  setOpenMobile: (open: boolean) => void;\r\n  isMobile: boolean;\r\n  toggleSidebar: () => void;\r\n};\r\n\r\nconst SidebarContext = React.createContext<SidebarContextProps | null>(null);\r\n\r\nfunction useSidebar() {\r\n  const context = React.useContext(SidebarContext);\r\n  if (!context) {\r\n    throw new Error('useSidebar must be used within a SidebarProvider.');\r\n  }\r\n\r\n  return context;\r\n}\r\n\r\nfunction SidebarProvider({\r\n  defaultOpen = true,\r\n  open: openProp,\r\n  onOpenChange: setOpenProp,\r\n  className,\r\n  style,\r\n  children,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  defaultOpen?: boolean;\r\n  open?: boolean;\r\n  onOpenChange?: (open: boolean) => void;\r\n}) {\r\n  const isMobile = useIsMobile();\r\n  const [openMobile, setOpenMobile] = React.useState(false);\r\n\r\n  // This is the internal state of the sidebar.\r\n  // We use openProp and setOpenProp for control from outside the component.\r\n  const [_open, _setOpen] = React.useState(defaultOpen);\r\n  const open = openProp ?? _open;\r\n  const setOpen = React.useCallback(\r\n    (value: boolean | ((value: boolean) => boolean)) => {\r\n      const openState = typeof value === 'function' ? value(open) : value;\r\n      if (setOpenProp) {\r\n        setOpenProp(openState);\r\n      } else {\r\n        _setOpen(openState);\r\n      }\r\n\r\n      // This sets the cookie to keep the sidebar state.\r\n      document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;\r\n    },\r\n    [setOpenProp, open],\r\n  );\r\n\r\n  // Helper to toggle the sidebar.\r\n  const toggleSidebar = React.useCallback(() => {\r\n    return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open);\r\n  }, [isMobile, setOpen, setOpenMobile]);\r\n\r\n  // Adds a keyboard shortcut to toggle the sidebar.\r\n  React.useEffect(() => {\r\n    const handleKeyDown = (event: KeyboardEvent) => {\r\n      if (\r\n        event.key === SIDEBAR_KEYBOARD_SHORTCUT &&\r\n        (event.metaKey || event.ctrlKey)\r\n      ) {\r\n        event.preventDefault();\r\n        toggleSidebar();\r\n      }\r\n    };\r\n\r\n    window.addEventListener('keydown', handleKeyDown);\r\n    return () => window.removeEventListener('keydown', handleKeyDown);\r\n  }, [toggleSidebar]);\r\n\r\n  // We add a state so that we can do data-state=\"expanded\" or \"collapsed\".\r\n  // This makes it easier to style the sidebar with Tailwind classes.\r\n  const state = open ? 'expanded' : 'collapsed';\r\n\r\n  const contextValue = React.useMemo<SidebarContextProps>(\r\n    () => ({\r\n      state,\r\n      open,\r\n      setOpen,\r\n      isMobile,\r\n      openMobile,\r\n      setOpenMobile,\r\n      toggleSidebar,\r\n    }),\r\n    [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar],\r\n  );\r\n\r\n  return (\r\n    <SidebarContext.Provider value={contextValue}>\r\n      <div\r\n        data-slot=\"sidebar-wrapper\"\r\n        style={\r\n          {\r\n            '--sidebar-width': SIDEBAR_WIDTH,\r\n            '--sidebar-width-icon': SIDEBAR_WIDTH_ICON,\r\n            ...style,\r\n          } as React.CSSProperties\r\n        }\r\n        className={cn(\r\n          'group/sidebar-wrapper flex min-h-svh w-full has-data-[variant=inset]:bg-sidebar',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n      </div>\r\n    </SidebarContext.Provider>\r\n  );\r\n}\r\n\r\nfunction Sidebar({\r\n  side = 'left',\r\n  variant = 'sidebar',\r\n  collapsible = 'offcanvas',\r\n  className,\r\n  children,\r\n  dir,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  side?: 'left' | 'right';\r\n  variant?: 'sidebar' | 'floating' | 'inset';\r\n  collapsible?: 'offcanvas' | 'icon' | 'none';\r\n}) {\r\n  const { isMobile, state, openMobile, setOpenMobile } = useSidebar();\r\n\r\n  if (collapsible === 'none') {\r\n    return (\r\n      <div\r\n        data-slot=\"sidebar\"\r\n        className={cn(\r\n          'flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        {children}\r\n      </div>\r\n    );\r\n  }\r\n\r\n  if (isMobile) {\r\n    return (\r\n      <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>\r\n        <SheetContent\r\n          dir={dir}\r\n          data-sidebar=\"sidebar\"\r\n          data-slot=\"sidebar\"\r\n          data-mobile=\"true\"\r\n          className=\"w-(--sidebar-width) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden\"\r\n          style={\r\n            {\r\n              '--sidebar-width': SIDEBAR_WIDTH_MOBILE,\r\n            } as React.CSSProperties\r\n          }\r\n          side={side}\r\n        >\r\n          <SheetHeader className=\"sr-only\">\r\n            <SheetTitle>Sidebar</SheetTitle>\r\n            <SheetDescription>Displays the mobile sidebar.</SheetDescription>\r\n          </SheetHeader>\r\n          <div className=\"flex h-full w-full flex-col\">{children}</div>\r\n        </SheetContent>\r\n      </Sheet>\r\n    );\r\n  }\r\n\r\n  return (\r\n    <div\r\n      className=\"group peer hidden text-sidebar-foreground md:block\"\r\n      data-state={state}\r\n      data-collapsible={state === 'collapsed' ? collapsible : ''}\r\n      data-variant={variant}\r\n      data-side={side}\r\n      data-slot=\"sidebar\"\r\n    >\r\n      {/* This is what handles the sidebar gap on desktop */}\r\n      <div\r\n        data-slot=\"sidebar-gap\"\r\n        className={cn(\r\n          'transition-[width] duration-200 ease-linear relative w-(--sidebar-width) bg-transparent',\r\n          'group-data-[collapsible=offcanvas]:w-0',\r\n          'group-data-[side=right]:rotate-180',\r\n          variant === 'floating' || variant === 'inset'\r\n            ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'\r\n            : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',\r\n        )}\r\n      />\r\n      <div\r\n        data-slot=\"sidebar-container\"\r\n        data-side={side}\r\n        className={cn(\r\n          'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear data-[side=left]:left-0 data-[side=left]:group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)] data-[side=right]:right-0 data-[side=right]:group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)] md:flex',\r\n          // Adjust the padding for floating and inset variants.\r\n          variant === 'floating' || variant === 'inset'\r\n            ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'\r\n            : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',\r\n          className,\r\n        )}\r\n        {...props}\r\n      >\r\n        <div\r\n          data-sidebar=\"sidebar\"\r\n          data-slot=\"sidebar-inner\"\r\n          className=\"bg-sidebar group-data-[variant=floating]:ring-sidebar-border group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:shadow-sm group-data-[variant=floating]:ring-1 flex size-full flex-col\"\r\n        >\r\n          {children}\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction SidebarTrigger({\r\n  className,\r\n  onClick,\r\n  ...props\r\n}: React.ComponentProps<typeof Button>) {\r\n  const { toggleSidebar } = useSidebar();\r\n\r\n  return (\r\n    <Button\r\n      data-sidebar=\"trigger\"\r\n      data-slot=\"sidebar-trigger\"\r\n      variant=\"ghost\"\r\n      size=\"icon-sm\"\r\n      className={cn(className)}\r\n      onClick={(event) => {\r\n        onClick?.(event);\r\n        toggleSidebar();\r\n      }}\r\n      {...props}\r\n    >\r\n      <PanelLeftIcon className=\"cn-rtl-flip\" />\r\n      <span className=\"sr-only\">Toggle Sidebar</span>\r\n    </Button>\r\n  );\r\n}\r\n\r\nfunction SidebarRail({ className, ...props }: React.ComponentProps<'button'>) {\r\n  const { toggleSidebar } = useSidebar();\r\n\r\n  return (\r\n    <button\r\n      data-sidebar=\"rail\"\r\n      data-slot=\"sidebar-rail\"\r\n      aria-label=\"Toggle Sidebar\"\r\n      tabIndex={-1}\r\n      onClick={toggleSidebar}\r\n      title=\"Toggle Sidebar\"\r\n      className={cn(\r\n        'hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:start-1/2 after:w-[2px] sm:flex ltr:-translate-x-1/2 rtl:-translate-x-1/2',\r\n        'in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize',\r\n        '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',\r\n        'group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full hover:group-data-[collapsible=offcanvas]:bg-sidebar',\r\n        '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2',\r\n        '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarInset({ className, ...props }: React.ComponentProps<'main'>) {\r\n  return (\r\n    <main\r\n      data-slot=\"sidebar-inset\"\r\n      className={cn(\r\n        'bg-background md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2 relative flex w-full flex-1 flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarInput({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Input>) {\r\n  return (\r\n    <Input\r\n      data-slot=\"sidebar-input\"\r\n      data-sidebar=\"input\"\r\n      className={cn('bg-background h-8 w-full shadow-none', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarHeader({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-header\"\r\n      data-sidebar=\"header\"\r\n      className={cn('gap-2 p-2 flex flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarFooter({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-footer\"\r\n      data-sidebar=\"footer\"\r\n      className={cn('gap-2 p-2 flex flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarSeparator({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<typeof Separator>) {\r\n  return (\r\n    <Separator\r\n      data-slot=\"sidebar-separator\"\r\n      data-sidebar=\"separator\"\r\n      className={cn('bg-sidebar-border mx-2 w-auto', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarContent({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-content\"\r\n      data-sidebar=\"content\"\r\n      className={cn(\r\n        'no-scrollbar gap-0 flex min-h-0 flex-1 flex-col overflow-auto group-data-[collapsible=icon]:overflow-hidden',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarGroup({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-group\"\r\n      data-sidebar=\"group\"\r\n      className={cn('p-2 relative flex w-full min-w-0 flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarGroupLabel({\r\n  className,\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'div'> & React.ComponentProps<'div'>) {\r\n  return useRender({\r\n    defaultTagName: 'div',\r\n    props: mergeProps<'div'>(\r\n      {\r\n        className: cn(\r\n          'text-sidebar-foreground/70 ring-sidebar-ring h-8 rounded-md px-2 text-xs font-medium transition-[margin,opacity] duration-200 ease-linear group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0 focus-visible:ring-2 [&>svg]:size-4 flex shrink-0 items-center outline-hidden [&>svg]:shrink-0',\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'sidebar-group-label',\r\n      sidebar: 'group-label',\r\n    },\r\n  });\r\n}\r\n\r\nfunction SidebarGroupAction({\r\n  className,\r\n  render,\r\n  ...props\r\n}: useRender.ComponentProps<'button'> & React.ComponentProps<'button'>) {\r\n  return useRender({\r\n    defaultTagName: 'button',\r\n    props: mergeProps<'button'>(\r\n      {\r\n        className: cn(\r\n          'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 w-5 rounded-md p-0 focus-visible:ring-2 [&>svg]:size-4 flex aspect-square items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0',\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'sidebar-group-action',\r\n      sidebar: 'group-action',\r\n    },\r\n  });\r\n}\r\n\r\nfunction SidebarGroupContent({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-group-content\"\r\n      data-sidebar=\"group-content\"\r\n      className={cn('text-sm w-full', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarMenu({ className, ...props }: React.ComponentProps<'ul'>) {\r\n  return (\r\n    <ul\r\n      data-slot=\"sidebar-menu\"\r\n      data-sidebar=\"menu\"\r\n      className={cn('gap-0 flex w-full min-w-0 flex-col', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarMenuItem({ className, ...props }: React.ComponentProps<'li'>) {\r\n  return (\r\n    <li\r\n      data-slot=\"sidebar-menu-item\"\r\n      data-sidebar=\"menu-item\"\r\n      className={cn('group/menu-item relative', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst sidebarMenuButtonVariants = cva(\r\n  'ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground data-open:hover:bg-sidebar-accent data-open:hover:text-sidebar-accent-foreground gap-2 rounded-md p-2 text-left text-sm transition-[width,height,padding] group-has-data-[sidebar=menu-action]/menu-item:pr-8 group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! focus-visible:ring-2 data-active:font-medium peer/menu-button group/menu-button flex w-full items-center overflow-hidden outline-hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:size-4 [&_svg]:shrink-0 [&>span:last-child]:truncate',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',\r\n        outline:\r\n          'bg-background hover:bg-sidebar-accent hover:text-sidebar-accent-foreground shadow-[0_0_0_1px_var(--sidebar-border)] hover:shadow-[0_0_0_1px_var(--sidebar-accent)]',\r\n      },\r\n      size: {\r\n        default: 'h-8 text-sm',\r\n        sm: 'h-7 text-xs',\r\n        lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n      size: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction SidebarMenuButton({\r\n  render,\r\n  isActive = false,\r\n  variant = 'default',\r\n  size = 'default',\r\n  tooltip,\r\n  className,\r\n  ...props\r\n}: useRender.ComponentProps<'button'> &\r\n  React.ComponentProps<'button'> & {\r\n    isActive?: boolean;\r\n    tooltip?: string | React.ComponentProps<typeof TooltipContent>;\r\n  } & VariantProps<typeof sidebarMenuButtonVariants>) {\r\n  const { isMobile, state } = useSidebar();\r\n  const comp = useRender({\r\n    defaultTagName: 'button',\r\n    props: mergeProps<'button'>(\r\n      {\r\n        className: cn(sidebarMenuButtonVariants({ variant, size }), className),\r\n      },\r\n      props,\r\n    ),\r\n    render: !tooltip ? render : <TooltipTrigger render={render} />,\r\n    state: {\r\n      slot: 'sidebar-menu-button',\r\n      sidebar: 'menu-button',\r\n      size,\r\n      active: isActive,\r\n    },\r\n  });\r\n\r\n  if (!tooltip) {\r\n    return comp;\r\n  }\r\n\r\n  if (typeof tooltip === 'string') {\r\n    tooltip = {\r\n      children: tooltip,\r\n    };\r\n  }\r\n\r\n  return (\r\n    <Tooltip>\r\n      {comp}\r\n      <TooltipContent\r\n        side=\"right\"\r\n        align=\"center\"\r\n        hidden={state !== 'collapsed' || isMobile}\r\n        {...tooltip}\r\n      />\r\n    </Tooltip>\r\n  );\r\n}\r\n\r\nfunction SidebarMenuAction({\r\n  className,\r\n  render,\r\n  showOnHover = false,\r\n  ...props\r\n}: useRender.ComponentProps<'button'> &\r\n  React.ComponentProps<'button'> & {\r\n    showOnHover?: boolean;\r\n  }) {\r\n  return useRender({\r\n    defaultTagName: 'button',\r\n    props: mergeProps<'button'>(\r\n      {\r\n        className: cn(\r\n          'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 aspect-square w-5 rounded-md p-0 peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 focus-visible:ring-2 [&>svg]:size-4 flex items-center justify-center outline-hidden transition-transform group-data-[collapsible=icon]:hidden after:absolute after:-inset-2 md:after:hidden [&>svg]:shrink-0',\r\n          showOnHover &&\r\n            'group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 peer-data-active/menu-button:text-sidebar-accent-foreground aria-expanded:opacity-100 md:opacity-0',\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'sidebar-menu-action',\r\n      sidebar: 'menu-action',\r\n    },\r\n  });\r\n}\r\n\r\nfunction SidebarMenuBadge({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-menu-badge\"\r\n      data-sidebar=\"menu-badge\"\r\n      className={cn(\r\n        'text-sidebar-foreground peer-hover/menu-button:text-sidebar-accent-foreground peer-data-active/menu-button:text-sidebar-accent-foreground pointer-events-none absolute right-1 h-5 min-w-5 rounded-md px-1 text-xs font-medium peer-data-[size=default]/menu-button:top-1.5 peer-data-[size=lg]/menu-button:top-2.5 peer-data-[size=sm]/menu-button:top-1 flex items-center justify-center tabular-nums select-none group-data-[collapsible=icon]:hidden',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarMenuSkeleton({\r\n  className,\r\n  showIcon = false,\r\n  ...props\r\n}: React.ComponentProps<'div'> & {\r\n  showIcon?: boolean;\r\n}) {\r\n  // Random width between 50 to 90%.\r\n  const [width] = React.useState(() => {\r\n    return `${Math.floor(Math.random() * 40) + 50}%`;\r\n  });\r\n\r\n  return (\r\n    <div\r\n      data-slot=\"sidebar-menu-skeleton\"\r\n      data-sidebar=\"menu-skeleton\"\r\n      className={cn('h-8 gap-2 rounded-md px-2 flex items-center', className)}\r\n      {...props}\r\n    >\r\n      {showIcon && (\r\n        <Skeleton\r\n          className=\"size-4 rounded-md\"\r\n          data-sidebar=\"menu-skeleton-icon\"\r\n        />\r\n      )}\r\n      <Skeleton\r\n        className=\"h-4 max-w-(--skeleton-width) flex-1\"\r\n        data-sidebar=\"menu-skeleton-text\"\r\n        style={\r\n          {\r\n            '--skeleton-width': width,\r\n          } as React.CSSProperties\r\n        }\r\n      />\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction SidebarMenuSub({ className, ...props }: React.ComponentProps<'ul'>) {\r\n  return (\r\n    <ul\r\n      data-slot=\"sidebar-menu-sub\"\r\n      data-sidebar=\"menu-sub\"\r\n      className={cn(\r\n        'border-sidebar-border mx-3.5 translate-x-px gap-1 border-l px-2.5 py-0.5 group-data-[collapsible=icon]:hidden flex min-w-0 flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarMenuSubItem({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'li'>) {\r\n  return (\r\n    <li\r\n      data-slot=\"sidebar-menu-sub-item\"\r\n      data-sidebar=\"menu-sub-item\"\r\n      className={cn('group/menu-sub-item relative', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction SidebarMenuSubButton({\r\n  render,\r\n  size = 'md',\r\n  isActive = false,\r\n  className,\r\n  ...props\r\n}: useRender.ComponentProps<'a'> &\r\n  React.ComponentProps<'a'> & {\r\n    size?: 'sm' | 'md';\r\n    isActive?: boolean;\r\n  }) {\r\n  return useRender({\r\n    defaultTagName: 'a',\r\n    props: mergeProps<'a'>(\r\n      {\r\n        className: cn(\r\n          'text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground data-active:bg-sidebar-accent data-active:text-sidebar-accent-foreground h-7 gap-2 rounded-md px-2 focus-visible:ring-2 data-[size=md]:text-sm data-[size=sm]:text-xs [&>svg]:size-4 flex min-w-0 -translate-x-px items-center overflow-hidden outline-hidden group-data-[collapsible=icon]:hidden disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:shrink-0',\r\n          className,\r\n        ),\r\n      },\r\n      props,\r\n    ),\r\n    render,\r\n    state: {\r\n      slot: 'sidebar-menu-sub-button',\r\n      sidebar: 'menu-sub-button',\r\n      size,\r\n      active: isActive,\r\n    },\r\n  });\r\n}\r\n\r\nexport {\r\n  Sidebar,\r\n  SidebarContent,\r\n  SidebarFooter,\r\n  SidebarGroup,\r\n  SidebarGroupAction,\r\n  SidebarGroupContent,\r\n  SidebarGroupLabel,\r\n  SidebarHeader,\r\n  SidebarInput,\r\n  SidebarInset,\r\n  SidebarMenu,\r\n  SidebarMenuAction,\r\n  SidebarMenuBadge,\r\n  SidebarMenuButton,\r\n  SidebarMenuItem,\r\n  SidebarMenuSkeleton,\r\n  SidebarMenuSub,\r\n  SidebarMenuSubButton,\r\n  SidebarMenuSubItem,\r\n  SidebarProvider,\r\n  SidebarRail,\r\n  SidebarSeparator,\r\n  SidebarTrigger,\r\n  useSidebar,\r\n};\r\n","handborne/source/components/ui/skeleton.tsx":"import { cn } from '@/lib/utils';\r\n\r\nfunction Skeleton({ className, ...props }: React.ComponentProps<'div'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"skeleton\"\r\n      className={cn('animate-pulse rounded-md bg-muted', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Skeleton };\r\n","handborne/source/components/ui/slider.tsx":"import { Slider as SliderPrimitive } from '@base-ui/react/slider';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Slider({\r\n  className,\r\n  defaultValue,\r\n  value,\r\n  min = 0,\r\n  max = 100,\r\n  ...props\r\n}: SliderPrimitive.Root.Props) {\r\n  const _values = Array.isArray(value)\r\n    ? value\r\n    : Array.isArray(defaultValue)\r\n      ? defaultValue\r\n      : [min, max];\r\n\r\n  return (\r\n    <SliderPrimitive.Root\r\n      className={cn('data-horizontal:w-full data-vertical:h-full', className)}\r\n      data-slot=\"slider\"\r\n      defaultValue={defaultValue}\r\n      value={value}\r\n      min={min}\r\n      max={max}\r\n      thumbAlignment=\"edge\"\r\n      {...props}\r\n    >\r\n      <SliderPrimitive.Control className=\"data-vertical:min-h-40 relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:w-auto data-vertical:flex-col\">\r\n        <SliderPrimitive.Track\r\n          data-slot=\"slider-track\"\r\n          className=\"bg-muted rounded-full data-horizontal:h-1 data-horizontal:w-full data-vertical:h-full data-vertical:w-1 relative grow overflow-hidden select-none\"\r\n        >\r\n          <SliderPrimitive.Indicator\r\n            data-slot=\"slider-range\"\r\n            className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\r\n          />\r\n        </SliderPrimitive.Track>\r\n        {Array.from({ length: _values.length }, (_, index) => (\r\n          <SliderPrimitive.Thumb\r\n            data-slot=\"slider-thumb\"\r\n            key={index}\r\n            className=\"border-ring ring-ring/50 relative size-3 rounded-full border bg-white transition-[color,box-shadow] after:absolute after:-inset-2 hover:ring-3 focus-visible:ring-3 focus-visible:outline-hidden active:ring-3 block shrink-0 select-none disabled:pointer-events-none disabled:opacity-50\"\r\n          />\r\n        ))}\r\n      </SliderPrimitive.Control>\r\n    </SliderPrimitive.Root>\r\n  );\r\n}\r\n\r\nexport { Slider };\r\n","handborne/source/components/ui/spinner.tsx":"import { cn } from '@/lib/utils';\r\nimport { Loader2Icon } from 'lucide-react';\r\n\r\nfunction Spinner({ className, ...props }: React.ComponentProps<'svg'>) {\r\n  return (\r\n    <Loader2Icon\r\n      data-slot=\"spinner\"\r\n      role=\"status\"\r\n      aria-label=\"Loading\"\r\n      className={cn('size-4 animate-spin', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Spinner };\r\n","handborne/source/components/ui/switch.tsx":"'use client';\r\n\r\nimport { Switch as SwitchPrimitive } from '@base-ui/react/switch';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Switch({\r\n  className,\r\n  size = 'default',\r\n  ...props\r\n}: SwitchPrimitive.Root.Props & {\r\n  size?: 'sm' | 'default';\r\n}) {\r\n  return (\r\n    <SwitchPrimitive.Root\r\n      data-slot=\"switch\"\r\n      data-size={size}\r\n      className={cn(\r\n        'peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent transition-all outline-none group-has-[:focus-visible]/field-label:border-transparent group-has-[:focus-visible]/field-label:ring-0 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <SwitchPrimitive.Thumb\r\n        data-slot=\"switch-thumb\"\r\n        className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\r\n      />\r\n    </SwitchPrimitive.Root>\r\n  );\r\n}\r\n\r\nexport { Switch };\r\n","handborne/source/components/ui/table.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Table({ className, ...props }: React.ComponentProps<'table'>) {\r\n  return (\r\n    <div\r\n      data-slot=\"table-container\"\r\n      className=\"relative w-full overflow-x-auto\"\r\n    >\r\n      <table\r\n        data-slot=\"table\"\r\n        className={cn('w-full caption-bottom text-sm', className)}\r\n        {...props}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n\r\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\r\n  return (\r\n    <thead\r\n      data-slot=\"table-header\"\r\n      className={cn('[&_tr]:border-b', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\r\n  return (\r\n    <tbody\r\n      data-slot=\"table-body\"\r\n      className={cn('[&_tr:last-child]:border-0', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\r\n  return (\r\n    <tfoot\r\n      data-slot=\"table-footer\"\r\n      className={cn(\r\n        'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\r\n  return (\r\n    <tr\r\n      data-slot=\"table-row\"\r\n      className={cn(\r\n        'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors has-aria-expanded:bg-muted/50',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableHead({ className, ...props }: React.ComponentProps<'th'>) {\r\n  return (\r\n    <th\r\n      data-slot=\"table-head\"\r\n      className={cn(\r\n        'text-foreground h-10 px-2 text-left align-middle font-medium whitespace-nowrap [&:has([role=checkbox])]:pr-0',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\r\n  return (\r\n    <td\r\n      data-slot=\"table-cell\"\r\n      className={cn(\r\n        'p-2 align-middle whitespace-nowrap [&:has([role=checkbox])]:pr-0',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TableCaption({\r\n  className,\r\n  ...props\r\n}: React.ComponentProps<'caption'>) {\r\n  return (\r\n    <caption\r\n      data-slot=\"table-caption\"\r\n      className={cn('text-muted-foreground mt-4 text-sm', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport {\r\n  Table,\r\n  TableHeader,\r\n  TableBody,\r\n  TableFooter,\r\n  TableHead,\r\n  TableRow,\r\n  TableCell,\r\n  TableCaption,\r\n};\r\n","handborne/source/components/ui/tabs.tsx":"'use client';\r\n\r\nimport { Tabs as TabsPrimitive } from '@base-ui/react/tabs';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Tabs({\r\n  className,\r\n  orientation = 'horizontal',\r\n  ...props\r\n}: TabsPrimitive.Root.Props) {\r\n  return (\r\n    <TabsPrimitive.Root\r\n      data-slot=\"tabs\"\r\n      data-orientation={orientation}\r\n      className={cn(\r\n        'group/tabs flex gap-2 data-horizontal:flex-col',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nconst tabsListVariants = cva(\r\n  'group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-8 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none',\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-muted',\r\n        line: 'gap-1 bg-transparent',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction TabsList({\r\n  className,\r\n  variant = 'default',\r\n  ...props\r\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\r\n  return (\r\n    <TabsPrimitive.List\r\n      data-slot=\"tabs-list\"\r\n      data-variant={variant}\r\n      className={cn(tabsListVariants({ variant }), className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\r\n  return (\r\n    <TabsPrimitive.Tab\r\n      data-slot=\"tabs-trigger\"\r\n      className={cn(\r\n        \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-1.5 py-0.5 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 has-data-[icon=inline-end]:pr-1 has-data-[icon=inline-start]:pl-1 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\r\n        'group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent',\r\n        'data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground',\r\n        'after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\r\n  return (\r\n    <TabsPrimitive.Panel\r\n      data-slot=\"tabs-content\"\r\n      className={cn('flex-1 text-sm outline-none', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants };\r\n","handborne/source/components/ui/textarea.tsx":"import * as React from 'react';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {\r\n  return (\r\n    <textarea\r\n      data-slot=\"textarea\"\r\n      className={cn(\r\n        'flex field-sizing-content min-h-16 w-full rounded-lg border border-input bg-transparent px-2.5 py-2 text-base transition-colors outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Textarea };\r\n","handborne/source/components/ui/toast.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Toast as ToastPrimitive } from '@base-ui/react/toast';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { Button } from '@/components/ui/button';\r\nimport {\r\n  XIcon,\r\n  CircleCheckIcon,\r\n  InfoIcon,\r\n  TriangleAlertIcon,\r\n  OctagonXIcon,\r\n  Loader2Icon,\r\n} from 'lucide-react';\r\n\r\nconst toast = ToastPrimitive.createToastManager();\r\n\r\nfunction ToastProvider({ ...props }: ToastPrimitive.Provider.Props) {\r\n  return <ToastPrimitive.Provider {...props} />;\r\n}\r\n\r\nfunction ToastPortal({ ...props }: ToastPrimitive.Portal.Props) {\r\n  return <ToastPrimitive.Portal data-slot=\"toast-portal\" {...props} />;\r\n}\r\n\r\nfunction ToastViewport({ className, ...props }: ToastPrimitive.Viewport.Props) {\r\n  return (\r\n    <ToastPrimitive.Viewport\r\n      data-slot=\"toast-viewport\"\r\n      className={cn(\r\n        'pointer-events-none fixed inset-x-4 bottom-4 z-50 mx-auto w-auto max-w-sm outline-none sm:right-4 sm:left-auto sm:mx-0 sm:w-full',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction Toast({ className, ...props }: ToastPrimitive.Root.Props) {\r\n  return (\r\n    <ToastPrimitive.Root\r\n      data-slot=\"toast\"\r\n      className={cn(\r\n        'rounded-2xl group/toast pointer-events-auto absolute right-0 bottom-0 z-[calc(1000-var(--toast-index))] w-full origin-bottom border bg-popover text-popover-foreground shadow-lg will-change-transform outline-none select-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50',\r\n        '[--gap:0.75rem] [--height:var(--toast-frontmost-height,var(--toast-height))] [--offset-y:calc(var(--toast-offset-y)*-1+calc(var(--toast-index)*var(--gap)*-1)+var(--toast-swipe-movement-y))] [--peek:0.75rem] [--scale:calc(max(0,1-(var(--toast-index)*0.1)))] [--shrink:calc(1-var(--scale))]',\r\n        'h-(--height) [transform:translateX(var(--toast-swipe-movement-x))_translateY(calc(var(--toast-swipe-movement-y)-(var(--toast-index)*var(--peek))-(var(--shrink)*var(--height))))_scale(var(--scale))] [transition:transform_500ms_cubic-bezier(0.22,1,0.36,1),opacity_500ms,height_150ms]',\r\n        \"after:absolute after:top-full after:left-0 after:h-[calc(var(--gap)+1px)] after:w-full after:content-['']\",\r\n        'data-expanded:h-(--toast-height) data-expanded:[transform:translateX(var(--toast-swipe-movement-x))_translateY(var(--offset-y))]',\r\n        'data-limited:opacity-0 data-starting-style:[transform:translateY(150%)]',\r\n        '[&[data-ending-style]:not([data-limited]):not([data-swipe-direction])]:[transform:translateY(150%)]',\r\n        'data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]',\r\n        'data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]',\r\n        'data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]',\r\n        'data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]',\r\n        'data-expanded:data-ending-style:data-[swipe-direction=down]:[transform:translateY(calc(var(--toast-swipe-movement-y)+150%))]',\r\n        'data-expanded:data-ending-style:data-[swipe-direction=left]:[transform:translateX(calc(var(--toast-swipe-movement-x)-150%))_translateY(var(--offset-y))]',\r\n        'data-expanded:data-ending-style:data-[swipe-direction=right]:[transform:translateX(calc(var(--toast-swipe-movement-x)+150%))_translateY(var(--offset-y))]',\r\n        'data-expanded:data-ending-style:data-[swipe-direction=up]:[transform:translateY(calc(var(--toast-swipe-movement-y)-150%))]',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ToastContent({ className, ...props }: ToastPrimitive.Content.Props) {\r\n  return (\r\n    <ToastPrimitive.Content\r\n      data-slot=\"toast-content\"\r\n      className={cn(\r\n        'flex h-full items-center gap-3 overflow-hidden p-4 transition-opacity duration-250 ease-[cubic-bezier(0.22,1,0.36,1)] data-behind:opacity-0 data-expanded:opacity-100',\r\n        className,\r\n      )}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ToastTitle({ className, ...props }: ToastPrimitive.Title.Props) {\r\n  return (\r\n    <ToastPrimitive.Title\r\n      data-slot=\"toast-title\"\r\n      className={cn('text-sm font-medium', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ToastDescription({\r\n  className,\r\n  ...props\r\n}: ToastPrimitive.Description.Props) {\r\n  return (\r\n    <ToastPrimitive.Description\r\n      data-slot=\"toast-description\"\r\n      className={cn('text-sm text-muted-foreground', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ToastAction({\r\n  className,\r\n  render = <Button variant=\"outline\" size=\"sm\" />,\r\n  ...props\r\n}: ToastPrimitive.Action.Props) {\r\n  return (\r\n    <ToastPrimitive.Action\r\n      data-slot=\"toast-action\"\r\n      render={render}\r\n      className={cn('shrink-0', className)}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction ToastClose({\r\n  className,\r\n  children,\r\n  render = <Button variant=\"ghost\" size=\"icon-sm\" />,\r\n  ...props\r\n}: ToastPrimitive.Close.Props) {\r\n  return (\r\n    <ToastPrimitive.Close\r\n      data-slot=\"toast-close\"\r\n      aria-label=\"Close toast\"\r\n      render={render}\r\n      className={cn(\r\n        \"relative shrink-0 text-muted-foreground after:absolute after:-inset-2 after:content-[''] hover:text-foreground\",\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children ?? <XIcon aria-hidden=\"true\" />}\r\n    </ToastPrimitive.Close>\r\n  );\r\n}\r\n\r\nfunction ToastIcon({ type }: { type: string | undefined }) {\r\n  let icon: React.ReactNode = null;\r\n\r\n  if (type === 'success') {\r\n    icon = <CircleCheckIcon aria-hidden=\"true\" />;\r\n  }\r\n\r\n  if (type === 'info') {\r\n    icon = <InfoIcon aria-hidden=\"true\" />;\r\n  }\r\n\r\n  if (type === 'warning') {\r\n    icon = <TriangleAlertIcon aria-hidden=\"true\" />;\r\n  }\r\n\r\n  if (type === 'error') {\r\n    icon = <OctagonXIcon className=\"text-destructive\" aria-hidden=\"true\" />;\r\n  }\r\n\r\n  if (type === 'loading') {\r\n    icon = <Loader2Icon className=\"animate-spin\" aria-hidden=\"true\" />;\r\n  }\r\n\r\n  if (!icon) {\r\n    return null;\r\n  }\r\n\r\n  return (\r\n    <span\r\n      data-slot=\"toast-icon\"\r\n      className=\"shrink-0 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\"\r\n    >\r\n      {icon}\r\n    </span>\r\n  );\r\n}\r\n\r\nfunction ToastList() {\r\n  const { toasts } = ToastPrimitive.useToastManager();\r\n\r\n  return toasts.map((toastItem) => (\r\n    <Toast key={toastItem.id} toast={toastItem}>\r\n      <ToastContent>\r\n        <ToastIcon type={toastItem.type} />\r\n        <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\r\n          <ToastTitle />\r\n          <ToastDescription />\r\n        </div>\r\n        <ToastAction />\r\n        <ToastClose />\r\n      </ToastContent>\r\n    </Toast>\r\n  ));\r\n}\r\n\r\nfunction Toaster({\r\n  children,\r\n  toastManager = toast,\r\n  ...props\r\n}: ToastPrimitive.Provider.Props) {\r\n  return (\r\n    <ToastProvider toastManager={toastManager} {...props}>\r\n      {children}\r\n      <ToastPortal>\r\n        <ToastViewport>\r\n          <ToastList />\r\n        </ToastViewport>\r\n      </ToastPortal>\r\n    </ToastProvider>\r\n  );\r\n}\r\n\r\nconst createToastManager = ToastPrimitive.createToastManager;\r\nconst useToastManager = ToastPrimitive.useToastManager;\r\n\r\nexport {\r\n  Toaster,\r\n  Toast,\r\n  ToastAction,\r\n  ToastClose,\r\n  ToastContent,\r\n  ToastDescription,\r\n  ToastPortal,\r\n  ToastProvider,\r\n  ToastTitle,\r\n  ToastViewport,\r\n  createToastManager,\r\n  toast,\r\n  useToastManager,\r\n};\r\n","handborne/source/components/ui/toggle-group.tsx":"'use client';\r\n\r\nimport * as React from 'react';\r\nimport { Toggle as TogglePrimitive } from '@base-ui/react/toggle';\r\nimport { ToggleGroup as ToggleGroupPrimitive } from '@base-ui/react/toggle-group';\r\nimport { type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\nimport { toggleVariants } from '@/components/ui/toggle';\r\n\r\nconst ToggleGroupContext = React.createContext<\r\n  VariantProps<typeof toggleVariants> & {\r\n    spacing?: number;\r\n    orientation?: 'horizontal' | 'vertical';\r\n  }\r\n>({\r\n  size: 'default',\r\n  variant: 'default',\r\n  spacing: 2,\r\n  orientation: 'horizontal',\r\n});\r\n\r\nfunction ToggleGroup({\r\n  className,\r\n  variant,\r\n  size,\r\n  spacing = 2,\r\n  orientation = 'horizontal',\r\n  children,\r\n  ...props\r\n}: ToggleGroupPrimitive.Props &\r\n  VariantProps<typeof toggleVariants> & {\r\n    spacing?: number;\r\n    orientation?: 'horizontal' | 'vertical';\r\n  }) {\r\n  return (\r\n    <ToggleGroupPrimitive\r\n      data-slot=\"toggle-group\"\r\n      data-variant={variant}\r\n      data-size={size}\r\n      data-spacing={spacing}\r\n      data-orientation={orientation}\r\n      style={{ '--gap': spacing } as React.CSSProperties}\r\n      className={cn(\r\n        'rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-vertical:flex-col data-vertical:items-stretch',\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      <ToggleGroupContext.Provider\r\n        value={{ variant, size, spacing, orientation }}\r\n      >\r\n        {children}\r\n      </ToggleGroupContext.Provider>\r\n    </ToggleGroupPrimitive>\r\n  );\r\n}\r\n\r\nfunction ToggleGroupItem({\r\n  className,\r\n  children,\r\n  variant = 'default',\r\n  size = 'default',\r\n  ...props\r\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\r\n  const context = React.useContext(ToggleGroupContext);\r\n\r\n  return (\r\n    <TogglePrimitive\r\n      data-slot=\"toggle-group-item\"\r\n      data-variant={context.variant || variant}\r\n      data-size={context.size || size}\r\n      data-spacing={context.spacing}\r\n      className={cn(\r\n        'group-data-[spacing=0]/toggle-group:rounded-none group-data-[spacing=0]/toggle-group:px-2 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-end]:pr-1.5 group-data-[spacing=0]/toggle-group:has-data-[icon=inline-start]:pl-1.5 group-data-horizontal/toggle-group:data-[spacing=0]:first:rounded-l-lg group-data-vertical/toggle-group:data-[spacing=0]:first:rounded-t-lg group-data-horizontal/toggle-group:data-[spacing=0]:last:rounded-r-lg group-data-vertical/toggle-group:data-[spacing=0]:last:rounded-b-lg shrink-0 focus:z-10 focus-visible:z-10 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:border-l-0 group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:border-t-0 group-data-horizontal/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-l group-data-vertical/toggle-group:data-[spacing=0]:data-[variant=outline]:first:border-t',\r\n        toggleVariants({\r\n          variant: context.variant || variant,\r\n          size: context.size || size,\r\n        }),\r\n        className,\r\n      )}\r\n      {...props}\r\n    >\r\n      {children}\r\n    </TogglePrimitive>\r\n  );\r\n}\r\n\r\nexport { ToggleGroup, ToggleGroupItem };\r\n","handborne/source/components/ui/toggle.tsx":"'use client';\r\n\r\nimport { Toggle as TogglePrimitive } from '@base-ui/react/toggle';\r\nimport { cva, type VariantProps } from 'class-variance-authority';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nconst toggleVariants = cva(\r\n  \"hover:text-foreground aria-pressed:bg-muted focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive data-[state=on]:bg-muted gap-1 rounded-lg text-sm font-medium transition-all [&_svg:not([class*='size-'])]:size-4 group/toggle inline-flex items-center justify-center whitespace-nowrap outline-none hover:bg-muted focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\r\n  {\r\n    variants: {\r\n      variant: {\r\n        default: 'bg-transparent',\r\n        outline: 'border-input hover:bg-muted border bg-transparent',\r\n      },\r\n      size: {\r\n        default:\r\n          'h-8 min-w-8 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\r\n        sm: \"h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\r\n        lg: 'h-9 min-w-9 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2',\r\n      },\r\n    },\r\n    defaultVariants: {\r\n      variant: 'default',\r\n      size: 'default',\r\n    },\r\n  },\r\n);\r\n\r\nfunction Toggle({\r\n  className,\r\n  variant = 'default',\r\n  size = 'default',\r\n  ...props\r\n}: TogglePrimitive.Props & VariantProps<typeof toggleVariants>) {\r\n  return (\r\n    <TogglePrimitive\r\n      data-slot=\"toggle\"\r\n      className={cn(toggleVariants({ variant, size, className }))}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nexport { Toggle, toggleVariants };\r\n","handborne/source/components/ui/tooltip.tsx":"'use client';\r\n\r\nimport { Tooltip as TooltipPrimitive } from '@base-ui/react/tooltip';\r\n\r\nimport { cn } from '@/lib/utils';\r\n\r\nfunction TooltipProvider({\r\n  delay = 0,\r\n  ...props\r\n}: TooltipPrimitive.Provider.Props) {\r\n  return (\r\n    <TooltipPrimitive.Provider\r\n      data-slot=\"tooltip-provider\"\r\n      delay={delay}\r\n      {...props}\r\n    />\r\n  );\r\n}\r\n\r\nfunction Tooltip({ ...props }: TooltipPrimitive.Root.Props) {\r\n  return <TooltipPrimitive.Root data-slot=\"tooltip\" {...props} />;\r\n}\r\n\r\nfunction TooltipTrigger({ ...props }: TooltipPrimitive.Trigger.Props) {\r\n  return <TooltipPrimitive.Trigger data-slot=\"tooltip-trigger\" {...props} />;\r\n}\r\n\r\nfunction TooltipContent({\r\n  className,\r\n  side = 'top',\r\n  sideOffset = 4,\r\n  align = 'center',\r\n  alignOffset = 0,\r\n  children,\r\n  ...props\r\n}: TooltipPrimitive.Popup.Props &\r\n  Pick<\r\n    TooltipPrimitive.Positioner.Props,\r\n    'align' | 'alignOffset' | 'side' | 'sideOffset'\r\n  >) {\r\n  return (\r\n    <TooltipPrimitive.Portal>\r\n      <TooltipPrimitive.Positioner\r\n        align={align}\r\n        alignOffset={alignOffset}\r\n        side={side}\r\n        sideOffset={sideOffset}\r\n        className=\"isolate z-50\"\r\n      >\r\n        <TooltipPrimitive.Popup\r\n          data-slot=\"tooltip-content\"\r\n          className={cn(\r\n            'z-50 inline-flex w-fit max-w-xs origin-(--transform-origin) items-center gap-1.5 rounded-md bg-foreground px-3 py-1.5 text-xs text-background has-data-[slot=kbd]:pr-1.5 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 **:data-[slot=kbd]:relative **:data-[slot=kbd]:isolate **:data-[slot=kbd]:z-50 **:data-[slot=kbd]:rounded-sm data-[state=delayed-open]:animate-in data-[state=delayed-open]:fade-in-0 data-[state=delayed-open]:zoom-in-95 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95',\r\n            className,\r\n          )}\r\n          {...props}\r\n        >\r\n          {children}\r\n          <TooltipPrimitive.Arrow className=\"z-50 size-2.5 translate-y-[calc(-50%-2px)] rotate-45 rounded-[2px] bg-foreground fill-foreground data-[side=bottom]:top-1 data-[side=inline-end]:top-1/2! data-[side=inline-end]:-left-1 data-[side=inline-end]:-translate-y-1/2 data-[side=inline-start]:top-1/2! data-[side=inline-start]:-right-1 data-[side=inline-start]:-translate-y-1/2 data-[side=left]:top-1/2! data-[side=left]:-right-1 data-[side=left]:-translate-y-1/2 data-[side=right]:top-1/2! data-[side=right]:-left-1 data-[side=right]:-translate-y-1/2 data-[side=top]:-bottom-2.5\" />\r\n        </TooltipPrimitive.Popup>\r\n      </TooltipPrimitive.Positioner>\r\n    </TooltipPrimitive.Portal>\r\n  );\r\n}\r\n\r\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };\r\n","handborne/source/hand-entry.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><meta name=\"theme-color\" content=\"#6427a5\"><title>Helping Hand · Customizer</title><meta name=\"description\" content=\"Customize your Helping Hand with a live preview, creature styles, nails, scales and gestures.\"></head><body><div id=\"root\"></div><script type=\"module\" src=\"/app/browser-entry.tsx\"></script></body></html>\r\n","handborne/source/hooks/use-mobile.ts":"import * as React from 'react';\r\n\r\nconst MOBILE_BREAKPOINT = 768;\r\n\r\nexport function useIsMobile() {\r\n  const [isMobile, setIsMobile] = React.useState<boolean | undefined>(\r\n    undefined,\r\n  );\r\n\r\n  React.useEffect(() => {\r\n    const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);\r\n    const onChange = () => {\r\n      setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\r\n    };\r\n    mql.addEventListener('change', onChange);\r\n    setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);\r\n    return () => mql.removeEventListener('change', onChange);\r\n  }, []);\r\n\r\n  return !!isMobile;\r\n}\r\n","handborne/source/lib/utils.ts":"import { clsx, type ClassValue } from 'clsx';\r\nimport { twMerge } from 'tailwind-merge';\r\n\r\nexport function cn(...inputs: ClassValue[]) {\r\n  return twMerge(clsx(inputs));\r\n}\r\n","handborne/source/next-env.d.ts":"import \"vinext/types\";\r\nimport \"./.next/types/routes.d.ts\";\r\n\r\n// NOTE: This file should not be edited\r\n// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.\r\n","handborne/source/package-lock.json":"{\r\n  \"name\": \"sites-project\",\r\n  \"version\": \"0.1.0\",\r\n  \"lockfileVersion\": 3,\r\n  \"requires\": true,\r\n  \"packages\": {\r\n    \"\": {\r\n      \"name\": \"sites-project\",\r\n      \"version\": \"0.1.0\",\r\n      \"dependencies\": {\r\n        \"@base-ui/react\": \"1.7.0\",\r\n        \"@shadcn/react\": \"0.3.0\",\r\n        \"class-variance-authority\": \"0.7.1\",\r\n        \"clsx\": \"2.1.1\",\r\n        \"cmdk\": \"1.1.1\",\r\n        \"date-fns\": \"4.1.0\",\r\n        \"embla-carousel-react\": \"8.5.2\",\r\n        \"input-otp\": \"1.4.2\",\r\n        \"lucide-react\": \"1.31.0\",\r\n        \"react\": \"19.2.6\",\r\n        \"react-day-picker\": \"9.8.1\",\r\n        \"react-dom\": \"19.2.6\",\r\n        \"react-resizable-panels\": \"4.5.8\",\r\n        \"react-server-dom-webpack\": \"19.2.6\",\r\n        \"recharts\": \"3.8.0\",\r\n        \"shadcn\": \"4.18.0\",\r\n        \"tailwind-merge\": \"3.6.0\",\r\n        \"three\": \"^0.180.0\",\r\n        \"tw-animate-css\": \"1.4.0\",\r\n        \"vinext\": \"1.0.0-beta.5\"\r\n      },\r\n      \"devDependencies\": {\r\n        \"@cloudflare/vite-plugin\": \"1.37.1\",\r\n        \"@cloudflare/workers-types\": \"4.20260515.1\",\r\n        \"@openai/sites-vite-plugin\": \"0.2.0\",\r\n        \"@tailwindcss/postcss\": \"4.2.1\",\r\n        \"@types/node\": \"22.19.19\",\r\n        \"@types/react\": \"19.2.14\",\r\n        \"@types/react-dom\": \"19.2.3\",\r\n        \"@types/three\": \"^0.180.0\",\r\n        \"@vitejs/plugin-react\": \"6.0.2\",\r\n        \"@vitejs/plugin-rsc\": \"0.5.26\",\r\n        \"oxfmt\": \"0.61.0\",\r\n        \"oxlint\": \"1.76.0\",\r\n        \"oxlint-tsgolint\": \"7.0.2001\",\r\n        \"tailwindcss\": \"4.2.1\",\r\n        \"typescript\": \"5.9.3\",\r\n        \"vite\": \"8.0.13\",\r\n        \"wrangler\": \"4.92.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.13.0\"\r\n      }\r\n    },\r\n    \"node_modules/@alloc/quick-lru\": {\r\n      \"version\": \"5.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.3.0.tgz\",\r\n      \"integrity\": \"sha512-U4+70Pc5ZS9osnCBCE5Jha/ciHM+Yp+CNMNC/7HvYbNRk1Ldd+f7qO65W5qfhu/TCv+/ozljlXXe9Nj8419DMA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/code-frame\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-validator-identifier\": \"^7.29.7\",\r\n        \"js-tokens\": \"^4.0.0\",\r\n        \"picocolors\": \"^1.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/compat-data\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/core\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/code-frame\": \"^7.29.7\",\r\n        \"@babel/generator\": \"^7.29.7\",\r\n        \"@babel/helper-compilation-targets\": \"^7.29.7\",\r\n        \"@babel/helper-module-transforms\": \"^7.29.7\",\r\n        \"@babel/helpers\": \"^7.29.7\",\r\n        \"@babel/parser\": \"^7.29.7\",\r\n        \"@babel/template\": \"^7.29.7\",\r\n        \"@babel/traverse\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\",\r\n        \"@jridgewell/remapping\": \"^2.3.5\",\r\n        \"convert-source-map\": \"^2.0.0\",\r\n        \"debug\": \"^4.1.0\",\r\n        \"gensync\": \"^1.0.0-beta.2\",\r\n        \"json5\": \"^2.2.3\",\r\n        \"semver\": \"^6.3.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/babel\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/generator\": {\r\n      \"version\": \"7.29.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz\",\r\n      \"integrity\": \"sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/parser\": \"^7.29.8\",\r\n        \"@babel/types\": \"^7.29.8\",\r\n        \"@jridgewell/gen-mapping\": \"^0.3.12\",\r\n        \"@jridgewell/trace-mapping\": \"^0.3.28\",\r\n        \"jsesc\": \"^3.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-annotate-as-pure\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-compilation-targets\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/compat-data\": \"^7.29.7\",\r\n        \"@babel/helper-validator-option\": \"^7.29.7\",\r\n        \"browserslist\": \"^4.24.0\",\r\n        \"lru-cache\": \"^5.1.1\",\r\n        \"semver\": \"^6.3.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-create-class-features-plugin\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-annotate-as-pure\": \"^7.29.7\",\r\n        \"@babel/helper-member-expression-to-functions\": \"^7.29.7\",\r\n        \"@babel/helper-optimise-call-expression\": \"^7.29.7\",\r\n        \"@babel/helper-replace-supers\": \"^7.29.7\",\r\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.29.7\",\r\n        \"@babel/traverse\": \"^7.29.7\",\r\n        \"semver\": \"^6.3.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-globals\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-member-expression-to-functions\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/traverse\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-module-imports\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/traverse\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-module-transforms\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-module-imports\": \"^7.29.7\",\r\n        \"@babel/helper-validator-identifier\": \"^7.29.7\",\r\n        \"@babel/traverse\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-optimise-call-expression\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-plugin-utils\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-replace-supers\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-member-expression-to-functions\": \"^7.29.7\",\r\n        \"@babel/helper-optimise-call-expression\": \"^7.29.7\",\r\n        \"@babel/traverse\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-skip-transparent-expression-wrappers\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/traverse\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-string-parser\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-validator-identifier\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helper-validator-option\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/helpers\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/template\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/parser\": {\r\n      \"version\": \"7.29.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz\",\r\n      \"integrity\": \"sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/types\": \"^7.29.8\"\r\n      },\r\n      \"bin\": {\r\n        \"parser\": \"bin/babel-parser.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/plugin-syntax-jsx\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-TSu8+mHCoEaaCDEZ0I3+6mvTBYR4PCxQwf2z9/r5Tbztv6NaLR3B9thGTTxX2WGuGHJqRiAbKPeGTJ5XWXVg6A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-plugin-utils\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0-0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/plugin-syntax-typescript\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-plugin-utils\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0-0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/plugin-transform-modules-commonjs\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-j0vCldybPC5b5dwCQOJ21uKtHzt7hxLygJTg9eF1ScfaikEDNfzn94XoW5Fi+seBR0nCyL23xaBFFkq7dTM8XQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-module-transforms\": \"^7.29.7\",\r\n        \"@babel/helper-plugin-utils\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0-0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/plugin-transform-typescript\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-annotate-as-pure\": \"^7.29.7\",\r\n        \"@babel/helper-create-class-features-plugin\": \"^7.29.7\",\r\n        \"@babel/helper-plugin-utils\": \"^7.29.7\",\r\n        \"@babel/helper-skip-transparent-expression-wrappers\": \"^7.29.7\",\r\n        \"@babel/plugin-syntax-typescript\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0-0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/preset-typescript\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-/Foi8vKY2EVbed/1eZx0gJEEwHAIxogrySI7rULcRIvhZzbvoE/b5qG5Ghc0WKAFKOHA9SD1x7RsFlOYdutIiQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-plugin-utils\": \"^7.29.7\",\r\n        \"@babel/helper-validator-option\": \"^7.29.7\",\r\n        \"@babel/plugin-syntax-jsx\": \"^7.29.7\",\r\n        \"@babel/plugin-transform-modules-commonjs\": \"^7.29.7\",\r\n        \"@babel/plugin-transform-typescript\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@babel/core\": \"^7.0.0-0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/runtime\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/template\": {\r\n      \"version\": \"7.29.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz\",\r\n      \"integrity\": \"sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/code-frame\": \"^7.29.7\",\r\n        \"@babel/parser\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/traverse\": {\r\n      \"version\": \"7.29.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz\",\r\n      \"integrity\": \"sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/code-frame\": \"^7.29.7\",\r\n        \"@babel/generator\": \"^7.29.8\",\r\n        \"@babel/helper-globals\": \"^7.29.7\",\r\n        \"@babel/parser\": \"^7.29.8\",\r\n        \"@babel/template\": \"^7.29.7\",\r\n        \"@babel/types\": \"^7.29.8\",\r\n        \"debug\": \"^4.3.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@babel/types\": {\r\n      \"version\": \"7.29.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz\",\r\n      \"integrity\": \"sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/helper-string-parser\": \"^7.29.7\",\r\n        \"@babel/helper-validator-identifier\": \"^7.29.7\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@base-ui/react\": {\r\n      \"version\": \"1.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@base-ui/react/-/react-1.7.0.tgz\",\r\n      \"integrity\": \"sha512-j+8QjX44C32jrXD/qyEAGpFr70FRpGL2CY61mQd9nBPWN737CK0xxD1ceJ055rW4RtdvFDT1e7otzdlfxvsYug==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/runtime\": \"^7.29.2\",\r\n        \"@base-ui/utils\": \"0.3.2\",\r\n        \"@floating-ui/react-dom\": \"^2.1.9\",\r\n        \"@floating-ui/utils\": \"^0.2.12\",\r\n        \"use-sync-external-store\": \"^1.6.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/mui-org\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@date-fns/tz\": \"^1.2.0\",\r\n        \"@types/react\": \"^17 || ^18 || ^19\",\r\n        \"date-fns\": \"^4.0.0\",\r\n        \"react\": \"^17 || ^18 || ^19\",\r\n        \"react-dom\": \"^17 || ^18 || ^19\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@date-fns/tz\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"date-fns\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@base-ui/utils\": {\r\n      \"version\": \"0.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@base-ui/utils/-/utils-0.3.2.tgz\",\r\n      \"integrity\": \"sha512-oWy1aq/I2GmYjpl4PhEAhzflF8VPGKgZeq0xAWTbfD5KBWyxcN0ZP2+WHSUm/5Z6lVMBDLReLcoXwSYoRc/zNQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/runtime\": \"^7.29.2\",\r\n        \"@floating-ui/utils\": \"^0.2.12\",\r\n        \"reselect\": \"^5.2.0\",\r\n        \"use-sync-external-store\": \"^1.6.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"^17 || ^18 || ^19\",\r\n        \"react\": \"^17 || ^18 || ^19\",\r\n        \"react-dom\": \"^17 || ^18 || ^19\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/kv-asset-handler\": {\r\n      \"version\": \"0.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz\",\r\n      \"integrity\": \"sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/unenv-preset\": {\r\n      \"version\": \"2.16.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz\",\r\n      \"integrity\": \"sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"peerDependencies\": {\r\n        \"unenv\": \"2.0.0-rc.24\",\r\n        \"workerd\": \">1.20260305.0 <2.0.0-0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"workerd\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/vite-plugin\": {\r\n      \"version\": \"1.37.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/vite-plugin/-/vite-plugin-1.37.1.tgz\",\r\n      \"integrity\": \"sha512-FldhsmkXyLsX3yI+p0aJDo/kGyY69pDdynz2JjcuH3eCiQ+G9XaY3CrN+UYEfCbWv8CiR2wL95lNg0fT/HfwWA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@cloudflare/unenv-preset\": \"2.16.1\",\r\n        \"miniflare\": \"4.20260515.0\",\r\n        \"unenv\": \"2.0.0-rc.24\",\r\n        \"wrangler\": \"4.92.0\",\r\n        \"ws\": \"8.18.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"vite\": \"^6.1.0 || ^7.0.0 || ^8.0.0\",\r\n        \"wrangler\": \"^4.92.0\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-darwin-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-Wtw44el2pNbzixvTkWdfeBDTrQwQbJRz7/JUvPKV27I0pQWXbhNJPpM8cstq/pbrU5AGcA/HjFH6yPMRTIRKig==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-darwin-arm64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-X8EqkZej6FfmhF9AVAQ3FhyQRr9acS4RcDunMU2YiuxKHF1IU8zzH3vY30/POaG+rUu9vGDp/VgUl49VPenHJQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-linux-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-CDC89QxQ7Y7t7RG1Jd9vj/qolE1sQRkI2OSEuV5BMJi0vW/gV4OVG6xjpdK3b1OYnSWDzF7NpvlR5Yg86q7k4g==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-linux-arm64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-WxbW/PToYES4fvHXzsr/5qOiETQs/Z9iZ0mjSZAiEwq5cMLZemzGN0COx+uFb9OvQwzh6Pg159qPFnw3+i9FuA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-windows-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-WmV/iv+MHjYsvkcMVzpM2B5/mf06UUkdpVhZrtMfV9graWjBGPYFvE/eab8748RPVGKh1Xe1vXofLzDSwc08lA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workers-types\": {\r\n      \"version\": \"4.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-ruz+9tcG2iIKq5mXU2F00lL6KF5d4QfbAk7fNgvvqf5BelxDXaieyZmSnvA4sQBuemUstt4AEDN9CmJKmfCsDw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\"\r\n    },\r\n    \"node_modules/@cspotcode/source-map-support\": {\r\n      \"version\": \"0.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\r\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping\": {\r\n      \"version\": \"0.3.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\r\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\r\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\r\n      }\r\n    },\r\n    \"node_modules/@date-fns/tz\": {\r\n      \"version\": \"1.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@date-fns/tz/-/tz-1.5.0.tgz\",\r\n      \"integrity\": \"sha512-lwYN/vDPeNRULcepoE/LO2Pgx+7/RV+S9ARfbc9lr2DtGkOD7pAiruHvbR1RX3Qyf6ja47EWJDMsNK5vK08DJg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@dimforge/rapier3d-compat\": {\r\n      \"version\": \"0.12.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz\",\r\n      \"integrity\": \"sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx\": {\r\n      \"version\": \"1.75.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@dotenvx/dotenvx/-/dotenvx-1.75.1.tgz\",\r\n      \"integrity\": \"sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"@dotenvx/primitives\": \"^0.8.0\",\r\n        \"commander\": \"^11.1.0\",\r\n        \"conf\": \"^10.2.0\",\r\n        \"dotenv\": \"^17.2.1\",\r\n        \"enquirer\": \"^2.4.1\",\r\n        \"env-paths\": \"^2.2.1\",\r\n        \"execa\": \"^5.1.1\",\r\n        \"fdir\": \"^6.2.0\",\r\n        \"ignore\": \"^5.3.0\",\r\n        \"object-treeify\": \"1.1.33\",\r\n        \"open\": \"^8.4.2\",\r\n        \"picomatch\": \"^4.0.4\",\r\n        \"systeminformation\": \"^5.22.11\",\r\n        \"undici\": \"^7.11.0\",\r\n        \"which\": \"^4.0.0\",\r\n        \"yocto-spinner\": \"^1.1.0\"\r\n      },\r\n      \"bin\": {\r\n        \"dotenvx\": \"src/cli/dotenvx.js\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://dotenvx.com\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/commander\": {\r\n      \"version\": \"11.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-11.1.0.tgz\",\r\n      \"integrity\": \"sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/define-lazy-prop\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/execa\": {\r\n      \"version\": \"5.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/execa/-/execa-5.1.1.tgz\",\r\n      \"integrity\": \"sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"cross-spawn\": \"^7.0.3\",\r\n        \"get-stream\": \"^6.0.0\",\r\n        \"human-signals\": \"^2.1.0\",\r\n        \"is-stream\": \"^2.0.0\",\r\n        \"merge-stream\": \"^2.0.0\",\r\n        \"npm-run-path\": \"^4.0.1\",\r\n        \"onetime\": \"^5.1.2\",\r\n        \"signal-exit\": \"^3.0.3\",\r\n        \"strip-final-newline\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sindresorhus/execa?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/get-stream\": {\r\n      \"version\": \"6.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz\",\r\n      \"integrity\": \"sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/human-signals\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=10.17.0\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/is-docker\": {\r\n      \"version\": \"2.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz\",\r\n      \"integrity\": \"sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"is-docker\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/is-stream\": {\r\n      \"version\": \"2.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz\",\r\n      \"integrity\": \"sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/is-wsl\": {\r\n      \"version\": \"2.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz\",\r\n      \"integrity\": \"sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-docker\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/npm-run-path\": {\r\n      \"version\": \"4.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz\",\r\n      \"integrity\": \"sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"path-key\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/open\": {\r\n      \"version\": \"8.4.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/open/-/open-8.4.2.tgz\",\r\n      \"integrity\": \"sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"define-lazy-prop\": \"^2.0.0\",\r\n        \"is-docker\": \"^2.1.1\",\r\n        \"is-wsl\": \"^2.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/signal-exit\": {\r\n      \"version\": \"3.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz\",\r\n      \"integrity\": \"sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/@dotenvx/dotenvx/node_modules/strip-final-newline\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/@dotenvx/primitives\": {\r\n      \"version\": \"0.8.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@dotenvx/primitives/-/primitives-0.8.0.tgz\",\r\n      \"integrity\": \"sha512-VYJy0uhFm9zTJ1TxBaW/pA8bjbOM/OttaNMwZ1RHG4JKyRG7DhSdiqD1ipQoAyoD22olUtxbP78W9xY3Wd11bg==\",\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@emnapi/core\": {\r\n      \"version\": \"1.10.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz\",\r\n      \"integrity\": \"sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/wasi-threads\": \"1.2.1\",\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@emnapi/runtime\": {\r\n      \"version\": \"1.11.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz\",\r\n      \"integrity\": \"sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@emnapi/wasi-threads\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/aix-ppc64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"aix\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-arm\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/darwin-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/darwin-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/freebsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/freebsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-arm\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-ia32\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-loong64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==\",\r\n      \"cpu\": [\r\n        \"loong64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-mips64el\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==\",\r\n      \"cpu\": [\r\n        \"mips64el\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-ppc64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-riscv64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-s390x\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/netbsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/netbsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openbsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openbsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openharmony-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/sunos-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"sunos\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-ia32\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@floating-ui/core\": {\r\n      \"version\": \"1.8.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz\",\r\n      \"integrity\": \"sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@floating-ui/utils\": \"^0.2.12\"\r\n      }\r\n    },\r\n    \"node_modules/@floating-ui/dom\": {\r\n      \"version\": \"1.8.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz\",\r\n      \"integrity\": \"sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@floating-ui/core\": \"^1.8.0\",\r\n        \"@floating-ui/utils\": \"^0.2.12\"\r\n      }\r\n    },\r\n    \"node_modules/@floating-ui/react-dom\": {\r\n      \"version\": \"2.1.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz\",\r\n      \"integrity\": \"sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@floating-ui/dom\": \"^1.8.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \">=16.8.0\",\r\n        \"react-dom\": \">=16.8.0\"\r\n      }\r\n    },\r\n    \"node_modules/@floating-ui/utils\": {\r\n      \"version\": \"0.2.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz\",\r\n      \"integrity\": \"sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@hono/node-server\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-ELuehkj5VCBdgEw9zs+ivkKwyzzUCSQuE96YmiPvn1ECBoZCczbFXJLeEGMTYjphP6gydh4pHMqEYPVMYUVgQg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"hono\": \"^4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/colour\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-darwin-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-darwin-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-darwin-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-darwin-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-darwin-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-darwin-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-arm\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-ppc64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-riscv64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-s390x\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linuxmusl-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linuxmusl-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-arm\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-arm\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-ppc64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-ppc64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-riscv64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-riscv64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-s390x\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-s390x\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linuxmusl-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linuxmusl-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linuxmusl-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linuxmusl-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-wasm32\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==\",\r\n      \"cpu\": [\r\n        \"wasm32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later AND MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/runtime\": \"^1.7.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-ia32\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/gen-mapping\": {\r\n      \"version\": \"0.3.13\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz\",\r\n      \"integrity\": \"sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/sourcemap-codec\": \"^1.5.0\",\r\n        \"@jridgewell/trace-mapping\": \"^0.3.24\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/remapping\": {\r\n      \"version\": \"2.3.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz\",\r\n      \"integrity\": \"sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/gen-mapping\": \"^0.3.5\",\r\n        \"@jridgewell/trace-mapping\": \"^0.3.24\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/resolve-uri\": {\r\n      \"version\": \"3.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz\",\r\n      \"integrity\": \"sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/source-map\": {\r\n      \"version\": \"0.3.11\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz\",\r\n      \"integrity\": \"sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@jridgewell/gen-mapping\": \"^0.3.5\",\r\n        \"@jridgewell/trace-mapping\": \"^0.3.25\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/sourcemap-codec\": {\r\n      \"version\": \"1.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz\",\r\n      \"integrity\": \"sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@jridgewell/trace-mapping\": {\r\n      \"version\": \"0.3.31\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz\",\r\n      \"integrity\": \"sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/resolve-uri\": \"^3.1.0\",\r\n        \"@jridgewell/sourcemap-codec\": \"^1.4.14\"\r\n      }\r\n    },\r\n    \"node_modules/@modelcontextprotocol/sdk\": {\r\n      \"version\": \"1.30.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz\",\r\n      \"integrity\": \"sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@hono/node-server\": \"^1.19.9 || ^2.0.5\",\r\n        \"ajv\": \"^8.17.1\",\r\n        \"ajv-formats\": \"^3.0.1\",\r\n        \"content-type\": \"^1.0.5\",\r\n        \"cors\": \"^2.8.5\",\r\n        \"cross-spawn\": \"^7.0.5\",\r\n        \"eventsource\": \"^3.0.2\",\r\n        \"eventsource-parser\": \"^3.0.0\",\r\n        \"express\": \"^5.2.1\",\r\n        \"express-rate-limit\": \"^8.2.1\",\r\n        \"hono\": \"^4.11.4\",\r\n        \"jose\": \"^6.1.3\",\r\n        \"json-schema-typed\": \"^8.0.2\",\r\n        \"pkce-challenge\": \"^5.0.0\",\r\n        \"raw-body\": \"^3.0.0\",\r\n        \"zod\": \"^3.25 || ^4.0\",\r\n        \"zod-to-json-schema\": \"^3.25.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@cfworker/json-schema\": \"^4.1.1\",\r\n        \"zod\": \"^3.25 || ^4.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@cfworker/json-schema\": {\r\n          \"optional\": true\r\n        },\r\n        \"zod\": {\r\n          \"optional\": false\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@napi-rs/wasm-runtime\": {\r\n      \"version\": \"1.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz\",\r\n      \"integrity\": \"sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@tybys/wasm-util\": \"^0.10.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || ^22.13.0 || >=23.5.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/Brooooooklyn\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@emnapi/core\": \"^1.7.1 || ^2.0.0-alpha.4\",\r\n        \"@emnapi/runtime\": \"^1.7.1 || ^2.0.0-alpha.4\"\r\n      }\r\n    },\r\n    \"node_modules/@nodelib/fs.scandir\": {\r\n      \"version\": \"2.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz\",\r\n      \"integrity\": \"sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@nodelib/fs.stat\": \"2.0.5\",\r\n        \"run-parallel\": \"^1.1.9\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/@nodelib/fs.stat\": {\r\n      \"version\": \"2.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz\",\r\n      \"integrity\": \"sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/@nodelib/fs.walk\": {\r\n      \"version\": \"1.2.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz\",\r\n      \"integrity\": \"sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@nodelib/fs.scandir\": \"2.1.5\",\r\n        \"fastq\": \"^1.6.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/@openai/sites-vite-plugin\": {\r\n      \"version\": \"0.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@openai/sites-vite-plugin/-/sites-vite-plugin-0.2.0.tgz\",\r\n      \"integrity\": \"sha512-4ThLMW9eaf2gd+SqBwHmqBONKBAbQ2BuOFev7mHq7Y2W5mm/rfVJOSjcgQIsY2PqdXxXNZ4Yd0+s0DlSUYehag==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=22.13.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"vite\": \"^8.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxc-project/types\": {\r\n      \"version\": \"0.130.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz\",\r\n      \"integrity\": \"sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/Boshen\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-android-arm-eabi\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-BaS+1OVvg9sr+Xav0+KdWedQRcAzrdoEcwMZeqoc2F6ieC1s/t5eM35YQoRPQ7vAqkZ+p3tbQb1r9I9mrV5oGA==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-android-arm64\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-of8atAV0M1egGcVOMbgZCvc10sFOP3ayQBNQV5h5G3fNq8gACdEswfFk9bzGrdbM23rtg0Coxi7np7oPLcueNw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-darwin-arm64\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-7l8+5ov4BGwtAcmpzvEik/TG3bciwyw/S3e6j5GKH7pcQqcgCVxD3AuJeP6upto+SOTBKQ4wrrdbMt0gq8fHSQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-darwin-x64\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-Fnz4dDDXBb7udk+DmwelNjxbD6yptyxwCqwCH2ebo4RVLxVsRfFsn/AHJC49KIltPrVokamGv4SSOsiV50DTxQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-freebsd-x64\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-mddOebKNCP+AucmzfNsk3jgbr681qAUvgMqi865GW5gWLJ/AnzXbvjQRrny0e++NAN8aphav/aRSrfFxNsNjpA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-arm-gnueabihf\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-svx59iYL+DbaZGZUIoice4W0CjRXGExnbz7Re+awIb60rVxBS2KrU7Hnlx+nZYanLGLpjneUEgo/VFEKkSZAyQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-arm-musleabihf\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-BYK9MPJPCf6d+fLKMTruThmEyCtHzQ1zLcsrTlUVkmnoXIaHAbfpeLYQwX1tkjs7W11dyzoi6HFvKcdnvX1zNg==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-arm64-gnu\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-QUaCNLq2/EC6G5ljOuFanl9Lgw6ZWp4co7rs4+KOMUzbGfA4Lq58FHRjjF9sVIG+93XSbo343MxFATrOU1qctA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-arm64-musl\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-S6uvJ6MXnRXl+zTs0CARNDvkE+cymj0EVWEKKsyKnlLlqTyQJBjw5s4D2pSIOZc+S46cy4STefzcr/sm0VzVPA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-ppc64-gnu\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-6VDlRcytvZG6UlSIdAFKDLbppo9tvPxrWzle6vHldYFMeuDPQEfMKrkwezp7FaBq1wik9ra554ZZeRPsyIkFpg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-riscv64-gnu\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-KkBTYbzExpbmn15XjKPLu2fRV2PVlq+KWt+brad5rwIa03vdYoaDRWiS7raHII/dCTR6Ro4UpYUCH4t6lif4WQ==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-riscv64-musl\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-69tzIq7sJLVB9dxYYtvMzcSSsnZHSO+U2U19O2RqDqgj6+Q4O7HjSXdaszbcgqzhsUwzSH7z5kWvk8nmf6BHTg==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-s390x-gnu\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-Oqi/N0OvtOVXsPKAOOhKgGH3msRYF8BLJaNBbWiupRiKoKVyc8JRKPCfarkQJC+RgP9U8raUKLe+bNwd0HUMiA==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-x64-gnu\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-3TKwv/ed4uwJSemAA8P9XcoqETpjQI4waquF9UilhA9Mn/dhr1PdUEXWlL74mtc6ZNfmKPA9+NEJm01nRF8CVA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-linux-x64-musl\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-uFso4u4nLkVSlMCpgjyvWV60Gt7GvDQHnk1mmRxHIkZTMB0ljpUKwCD9FYGgN9H97x2wYl0UwEjgRZaPIuhEhw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-openharmony-arm64\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-keGLkzeOvkMpNmPp4hffXWpfoSsY6e1K8++KXD4mSSfxdvM8q9QUDsYY689TB1k6Co832DZn1MnaaVx6cIBMWQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-win32-arm64-msvc\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-VzsAISkFxmNhJ5LBDEL9VuH6tJsVJMtqYit2LyIUf/HLnsCe4Pg9SMOjjVQzGWt0bnpyfJ94CrqTqcpNZzK+ug==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-win32-ia32-msvc\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-xv4t7yzwJoYaLB6Zv28B3W+j7brEjsyv50rLTAQgmxJzddce9fAMCxed8dSAkbWES0zz2J29nYK5FaTuD2YBHg==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxfmt/binding-win32-x64-msvc\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-6EZXFkqOwxdDYjIn3TSNnPk3ST5E5GiYd4FiM6UF/mCL/LZSfr6D6UygTfW3R1PCQP2quCKpCEGRlij8E3VYbg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/darwin-arm64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/darwin-arm64/-/darwin-arm64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-CUJEdbSZ54+Xy9OXqOhWLTKZKV0BBiV7C2i/ygyVmXtkUNXx5YCzN8DpSSshTAKktoL7S+tnQ/ftFG/i7X896w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/darwin-x64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/darwin-x64/-/darwin-x64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-pXfBb5BqONCcgrXQNUZWXgiYmRSWJzd97S8i41VVOh6ut0tyo+cJ5FKFpczDHxiVNfj/3e7c9B4MtztNdpIVCw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/linux-arm64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/linux-arm64/-/linux-arm64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-roP7zujb/QDPzDwEKsFFpzNHHy91/Y7oX9vQXk78ekyZtcQj1QXDIMH33gjDdHBfRl4K9pZ36xhRgrP4Zr+R8A==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/linux-x64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/linux-x64/-/linux-x64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-UDezNqdECVmngu2TPnjaS1YoAmcTaBoI5lV9vk3VahBxoi+I5r9k3iJTT7qZoYWOXTD/7T7bNcwRgrocR6BscQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/win32-arm64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/win32-arm64/-/win32-arm64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-uJZhqB6pdXLuN+AD1F5082byyQti/NPmJA77GtcFlmT2HzRelqbNls3SaIqxpjdFgvSBF9g0yOKGBkGFg7kX8Q==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint-tsgolint/win32-x64\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint-tsgolint/win32-x64/-/win32-x64-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-FkDRm8hx9OwzGQqyWG1tO5QrTLRApff9DzSgpz9QZau37BR8d1VYKOxMLGf6shPZntJFoTwIIJYT68VndYDCog==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ]\r\n    },\r\n    \"node_modules/@oxlint/binding-android-arm-eabi\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-android-arm-eabi/-/binding-android-arm-eabi-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-ZHIE5Zt9AsPDcY4nOlofXt0YfneEeo+QrKMPcPzLf2Z6Q8VtV2W73d7SFJ920WUwyik783u/doKCs3KXdwG+7w==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-android-arm64\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-android-arm64/-/binding-android-arm64-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-shm/ngQilHK6bs+ElJWa4oHfNj5vL1Gl/iVEJldTQjpr0/67oSgr0KUpbmcnLig5Fo0v/l6j2567A7TOL89ONA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-darwin-arm64\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-darwin-arm64/-/binding-darwin-arm64-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-rvJmrAPKSQ9aWJ6wIS6CK2tJjwzfW0ApQH9qokq6sfDvmHwoyIHxHFMq7z7i7GiV6fdE6s8qvBqWKPTu8RmT6Q==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-darwin-x64\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-darwin-x64/-/binding-darwin-x64-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-U/zYdb7VYKGY6pA9Vd2rYl9O/HlCylcOlb5PGPvVLtg+oLGsk6H3XGKEMHKyqD3nmmtmlmwb/8SwU2vfSAtvMw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-freebsd-x64\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-freebsd-x64/-/binding-freebsd-x64-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-WvKG9CAriuo0XNiFzpXjDngUZcRGFNpaK2kLyMUsnJlShxkT96u+BpJQ3KqdQwGOrvI14L6V8bAwXwAYNNY6Jg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-qJ5+RH99TqFRq3UCDxkW0zJJu9c+OAHFY72vGlxZLEpuO+MpKo3POgqb8sYipL9KYm8XY6ofb0HsOuvY6hQNqQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-arm-musleabihf\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-PvPCVptkgVARsucgIqFQQcSmJ6xc6GtnVB5bRBekRahTc9eObMtjHfMjy5M+C2tHt5UCMttWM9RuSk/H9NqYeg==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-arm64-gnu\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-3KeFDx8Bu4HPAXbuHZOr/oHvN+QT+JQhMw/NYPz7Z071xLSsG27Jfh9PIQVEY7hk1I+jr43ExqRIeJ6VKk2yLw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-arm64-musl\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-oPFkkKTgl0K/EIg9fQ8oA3IGcI05/Mq1en04iFa41mmNPT+6KEiByVazTOZZJiHMBBrbsns1YJ2e1Scqwzesjw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-ppc64-gnu\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-gN7yZ0eqflA5Fhf1wvHxGUltIV3FsvmB1zhNMDEK9vSHhc7E6qg9CuPeBgPZab66Tjzq6w6kHAtNEvnTHf4cyw==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-riscv64-gnu\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-S/HqMbn22mQrjtErUxEoS/a55u8kIeXvreIxiJu5G7Le3UecEd6SQZxrDIpuhtgaFnsY/nVra3ytP+pRljDilA==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-riscv64-musl\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-ZIga3097VJZolGZk6SrIAUokIGfRkxRlhiHDUznZptGBfwrhD7pNfD1rzEzsCwvk/1DX0A1bLz+liuNh5QKIVQ==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-s390x-gnu\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-ZGiiA7pFzMJSyMWYZTVlPgbTsx+Vl8ihLGMIujPwaslUF7kIPPWAbVmAlTc+9lWDV+DCiB8Ikixu+lSHeOIIWQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-x64-gnu\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-JLiy5WuvEBFTT6ErIFV35SLzi0R7Iri6MKU6dZbTxfIx8pndbbPs3Mj780nMipBFcPkti+okAPOJ9POKkHFEgg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-linux-x64-musl\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-linux-x64-musl/-/binding-linux-x64-musl-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-z7lgKQtbo/I1NIe8G5NHLesxJDv0tRSUWTpXKb9Pm3E9nKFKfO4IOSDtFroKgXtOYb0jQbcdH+0wzTyMXVes+A==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-openharmony-arm64\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-openharmony-arm64/-/binding-openharmony-arm64-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-JOjKymIpb9QcYfEhZsN6h4V9Ivd474W38cNIBRv6bg2TbIvogbMTH0Mg6YWW9TiRDqfcX+/Hyfsbo5vcSE5guQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-win32-arm64-msvc\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-pqDWZiwcmByWUEm1NFUBNiT6aentCcaoMWJv0HbXEmuYermJ4sg8ppVrshubYP2MZ6SHccJJcpr6x469PuDFIw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-win32-ia32-msvc\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-Ba0O659kgMv6pwO3z9PdO+K3aMxQRaw9HnG+e6AtOfgwcKFvYilciQYBoUBmxfQvOCKZe1SwjMkuB542NkuDMQ==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxlint/binding-win32-x64-msvc\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxlint/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-5qcirPHO8nKfkoowEVWtpAoVTcYDy6g0UT0NGic450Qv8J2NrOqg4uQ8QppRP4MDTC7Xx47lbZnmadTH03CGGA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/colors\": {\r\n      \"version\": \"4.1.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz\",\r\n      \"integrity\": \"sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"kleur\": \"^4.1.5\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/dumper\": {\r\n      \"version\": \"0.6.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz\",\r\n      \"integrity\": \"sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/colors\": \"^4.1.5\",\r\n        \"@sindresorhus/is\": \"^7.0.2\",\r\n        \"supports-color\": \"^10.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/dumper/node_modules/supports-color\": {\r\n      \"version\": \"10.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz\",\r\n      \"integrity\": \"sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/supports-color?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/exception\": {\r\n      \"version\": \"1.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz\",\r\n      \"integrity\": \"sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@radix-ui/primitive\": {\r\n      \"version\": \"1.1.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.7.tgz\",\r\n      \"integrity\": \"sha512-rqWnm76nYT8HoNNqEjpgJ7Pw/DrBj5iBTrmEPo6HTX5+VJyBNOqTdv4g89G63HuR5g0AaENoAcH7Is5fF2kZ8Q==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@radix-ui/react-compose-refs\": {\r\n      \"version\": \"1.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz\",\r\n      \"integrity\": \"sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-context\": {\r\n      \"version\": \"1.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.2.2.tgz\",\r\n      \"integrity\": \"sha512-RHCUGwKHDr0hDGg4X7ma4JG4/+12qxw8rkh5QKdDldlCvtja6nUx1Ef/8HVrJze81lEsgLQlqjzjGNHantgnQA==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-dialog\": {\r\n      \"version\": \"1.1.23\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.1.23.tgz\",\r\n      \"integrity\": \"sha512-Ksw4WeROkO4rC9k/onilX/Ao2Cr1ku1unMNH+XSCcP4jSXYu7HDsg9n4ojMjVb22XpYjAQ9qfrFlVbru1vXDUA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/primitive\": \"1.1.7\",\r\n        \"@radix-ui/react-compose-refs\": \"1.1.5\",\r\n        \"@radix-ui/react-context\": \"1.2.2\",\r\n        \"@radix-ui/react-dismissable-layer\": \"1.1.19\",\r\n        \"@radix-ui/react-focus-guards\": \"1.1.6\",\r\n        \"@radix-ui/react-focus-scope\": \"1.1.16\",\r\n        \"@radix-ui/react-id\": \"1.1.4\",\r\n        \"@radix-ui/react-portal\": \"1.1.17\",\r\n        \"@radix-ui/react-presence\": \"1.1.10\",\r\n        \"@radix-ui/react-primitive\": \"2.1.10\",\r\n        \"@radix-ui/react-slot\": \"1.3.3\",\r\n        \"@radix-ui/react-use-controllable-state\": \"1.2.6\",\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\",\r\n        \"aria-hidden\": \"^1.2.4\",\r\n        \"react-remove-scroll\": \"^2.7.2\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-dismissable-layer\": {\r\n      \"version\": \"1.1.19\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.19.tgz\",\r\n      \"integrity\": \"sha512-8g4pfOL9HoKKLWGiypT+dphVqjFfmcXO5GBnhsG6zI+lxAx/8feQpr+1LSN8Re3hiZ+XkLNS4O9ztK11/LzQ6w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/primitive\": \"1.1.7\",\r\n        \"@radix-ui/react-compose-refs\": \"1.1.5\",\r\n        \"@radix-ui/react-primitive\": \"2.1.10\",\r\n        \"@radix-ui/react-use-callback-ref\": \"1.1.4\",\r\n        \"@radix-ui/react-use-effect-event\": \"0.0.5\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-focus-guards\": {\r\n      \"version\": \"1.1.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.6.tgz\",\r\n      \"integrity\": \"sha512-RNOJjfZMTyBM6xYmV3IVGXkPjIhcBAuv48POevAXwrGJhkWZ9p1rFoIS1JFooPuT193AZmRsCPhpoVJxx6OPoQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-focus-scope\": {\r\n      \"version\": \"1.1.16\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.16.tgz\",\r\n      \"integrity\": \"sha512-wmRZ2WWLvmt6KHy2rNPOdPUjwq5xOHY02+m+udwJTn0aNIox/rkskAvJTyTLGhPK6KgrUjlJUJpgmx/+wFiFIQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-compose-refs\": \"1.1.5\",\r\n        \"@radix-ui/react-primitive\": \"2.1.10\",\r\n        \"@radix-ui/react-use-callback-ref\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-id\": {\r\n      \"version\": \"1.1.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz\",\r\n      \"integrity\": \"sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-portal\": {\r\n      \"version\": \"1.1.17\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.17.tgz\",\r\n      \"integrity\": \"sha512-vKQLcWypUnwZVvfV7UkGahH2g6ySe8M8R+zYBwPrv5byZ9QAW6cQVvNKo7GgmD+p8aYb6D9JBuvy8/WhOno2wQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-primitive\": \"2.1.10\",\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-presence\": {\r\n      \"version\": \"1.1.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.10.tgz\",\r\n      \"integrity\": \"sha512-3wyzCQ6+ubRA+D4uv9m95JYLXxmOHp05qjrkjeA7uKHHtjpPggQzc6DAb0URl7j67oR0K2foO4ip27TiX037Bw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-primitive\": {\r\n      \"version\": \"2.1.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.10.tgz\",\r\n      \"integrity\": \"sha512-MucOnzh6hR5mid6VpkbglRAMYMjKLqRnGBbjXkzjK52fuQDd1qbkx78a5P40mkcnVXJdEVxm26E9OPAiUq7nBg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-slot\": \"1.3.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"@types/react-dom\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-slot\": {\r\n      \"version\": \"1.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.3.3.tgz\",\r\n      \"integrity\": \"sha512-qx7oqnYbxnK9kYI9m317qmFmEgo6ywqWvbTogdj7cL9p3/yx4M48p7Rnw5z3H890cL/ow/EeWJsuTykeZVXP5Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-compose-refs\": \"1.1.5\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-use-callback-ref\": {\r\n      \"version\": \"1.1.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.4.tgz\",\r\n      \"integrity\": \"sha512-R6OUY2e2fA6Yn6s+VSx5KBV6Nx8LQEhu+cz7LCej18rQ1HLyg9PSC9jP/ZNx0o6FAIK9c0F1kHylzSxKsdlkrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-use-controllable-state\": {\r\n      \"version\": \"1.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.6.tgz\",\r\n      \"integrity\": \"sha512-uEQJGT97ZA/TgP/Hydw47lHu+/vQj6z/0jA+WeTbK1o9Rx45GImjpD0tc3W5ad3D6XTSR6e1yEO0FvGq6WQfVQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/primitive\": \"1.1.7\",\r\n        \"@radix-ui/react-use-effect-event\": \"0.0.5\",\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-use-effect-event\": {\r\n      \"version\": \"0.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz\",\r\n      \"integrity\": \"sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-use-layout-effect\": \"1.1.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@radix-ui/react-use-layout-effect\": {\r\n      \"version\": \"1.1.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz\",\r\n      \"integrity\": \"sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@reduxjs/toolkit\": {\r\n      \"version\": \"2.12.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.12.0.tgz\",\r\n      \"integrity\": \"sha512-KiT+RzZbp6mQET+Mg+h2c97+9j1sNflUxQkIHI7Yuzf6Peu+OYpmkn6nbHWmLLWj+1ZODUJFwGZ7gx3L9R9EOw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@standard-schema/spec\": \"^1.0.0\",\r\n        \"@standard-schema/utils\": \"^0.3.0\",\r\n        \"immer\": \"^11.0.0\",\r\n        \"redux\": \"^5.0.1\",\r\n        \"redux-thunk\": \"^3.1.0\",\r\n        \"reselect\": \"^5.1.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.9.0 || ^17.0.0 || ^18 || ^19\",\r\n        \"react-redux\": \"^7.2.1 || ^8.1.3 || ^9.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"react\": {\r\n          \"optional\": true\r\n        },\r\n        \"react-redux\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@reduxjs/toolkit/node_modules/immer\": {\r\n      \"version\": \"11.1.18\",\r\n      \"resolved\": \"https://registry.npmjs.org/immer/-/immer-11.1.18.tgz\",\r\n      \"integrity\": \"sha512-EQyQtLiYW029lyoczMl/Hh4Xu7cDecSc58JRYpHyL4tIAu3eqd1yJzQX04d2BZHDkzFFvm6qJEJWOtfDSWAXbQ==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/immer\"\r\n      }\r\n    },\r\n    \"node_modules/@resvg/resvg-wasm\": {\r\n      \"version\": \"2.4.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@resvg/resvg-wasm/-/resvg-wasm-2.4.0.tgz\",\r\n      \"integrity\": \"sha512-C7c51Nn4yTxXFKvgh2txJFNweaVcfUPQxwEUFw4aWsCmfiBDJsTSwviIF8EcwjQ6k8bPyMWCl1vw4BdxE569Cg==\",\r\n      \"license\": \"MPL-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">= 10\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-android-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-darwin-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-darwin-x64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-freebsd-x64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm64-musl\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-ppc64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-s390x-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-x64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-x64-musl\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-openharmony-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-wasm32-wasi\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==\",\r\n      \"cpu\": [\r\n        \"wasm32\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/core\": \"1.10.0\",\r\n        \"@emnapi/runtime\": \"1.10.0\",\r\n        \"@napi-rs/wasm-runtime\": \"^1.1.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime\": {\r\n      \"version\": \"1.10.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz\",\r\n      \"integrity\": \"sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-win32-arm64-msvc\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-win32-x64-msvc\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/pluginutils\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@sec-ant/readable-stream\": {\r\n      \"version\": \"0.4.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz\",\r\n      \"integrity\": \"sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@shadcn/react\": {\r\n      \"version\": \"0.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@shadcn/react/-/react-0.3.0.tgz\",\r\n      \"integrity\": \"sha512-iKN0NuYe850VDHlxEfvppFrpa7CMV3zArTHusXlaSmeFeQhohGbIqclv6WwPTs/44I8EkXQpcuRt6sXEVKkWqQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \">=19\",\r\n        \"react\": \">=19\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@shuding/opentype.js\": {\r\n      \"version\": \"1.4.0-beta.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz\",\r\n      \"integrity\": \"sha512-3NgmNyH3l/Hv6EvsWJbsvpcpUba6R8IREQ83nH83cyakCw7uM1arZKNfHwv1Wz6jgqrF/j4x5ELvR6PnK9nTcA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fflate\": \"^0.7.3\",\r\n        \"string.prototype.codepointat\": \"^0.2.1\"\r\n      },\r\n      \"bin\": {\r\n        \"ot\": \"bin/ot\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 8.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@sindresorhus/is\": {\r\n      \"version\": \"7.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz\",\r\n      \"integrity\": \"sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sindresorhus/is?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/@sindresorhus/merge-streams\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/@speed-highlight/core\": {\r\n      \"version\": \"1.2.24\",\r\n      \"resolved\": \"https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.24.tgz\",\r\n      \"integrity\": \"sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==\",\r\n      \"dev\": true,\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    \"node_modules/@standard-schema/spec\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@standard-schema/utils\": {\r\n      \"version\": \"0.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz\",\r\n      \"integrity\": \"sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@tailwindcss/node\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/node/-/node-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-jlx6sLk4EOwO6hHe1oCGm1Q4AN/s0rSrTTPBGPM0/RQ6Uylwq17FuU8IeJJKEjtc6K6O07zsvP+gDO6MMWo7pg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/remapping\": \"^2.3.5\",\r\n        \"enhanced-resolve\": \"^5.19.0\",\r\n        \"jiti\": \"^2.6.1\",\r\n        \"lightningcss\": \"1.31.1\",\r\n        \"magic-string\": \"^0.30.21\",\r\n        \"source-map-js\": \"^1.2.1\",\r\n        \"tailwindcss\": \"4.2.1\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide/-/oxide-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-yv9jeEFWnjKCI6/T3Oq50yQEOqmpmpfzG1hcZsAOaXFQPfzWprWrlHSdGPEF3WQTi8zu8ohC9Mh9J470nT5pUw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@tailwindcss/oxide-android-arm64\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-darwin-arm64\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-darwin-x64\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-freebsd-x64\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-linux-arm-gnueabihf\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-linux-arm64-gnu\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-linux-arm64-musl\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-linux-x64-gnu\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-linux-x64-musl\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-wasm32-wasi\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-win32-arm64-msvc\": \"4.2.1\",\r\n        \"@tailwindcss/oxide-win32-x64-msvc\": \"4.2.1\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-android-arm64\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-android-arm64/-/oxide-android-arm64-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-eZ7G1Zm5EC8OOKaesIKuw77jw++QJ2lL9N+dDpdQiAB/c/B2wDh0QPFHbkBVrXnwNugvrbJFk1gK2SsVjwWReg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-darwin-arm64\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-darwin-arm64/-/oxide-darwin-arm64-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-q/LHkOstoJ7pI1J0q6djesLzRvQSIfEto148ppAd+BVQK0JYjQIFSK3JgYZJa+Yzi0DDa52ZsQx2rqytBnf8Hw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-darwin-x64\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-darwin-x64/-/oxide-darwin-x64-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-/f/ozlaXGY6QLbpvd/kFTro2l18f7dHKpB+ieXz+Cijl4Mt9AI2rTrpq7V+t04nK+j9XBQHnSMdeQRhbGyt6fw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-freebsd-x64\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-freebsd-x64/-/oxide-freebsd-x64-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-5e/AkgYJT/cpbkys/OU2Ei2jdETCLlifwm7ogMC7/hksI2fC3iiq6OcXwjibcIjPung0kRtR3TxEITkqgn0TcA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-linux-arm-gnueabihf\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm-gnueabihf/-/oxide-linux-arm-gnueabihf-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-Uny1EcVTTmerCKt/1ZuKTkb0x8ZaiuYucg2/kImO5A5Y/kBz41/+j0gxUZl+hTF3xkWpDmHX+TaWhOtba2Fyuw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-linux-arm64-gnu\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-gnu/-/oxide-linux-arm64-gnu-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-CTrwomI+c7n6aSSQlsPL0roRiNMDQ/YzMD9EjcR+H4f0I1SQ8QqIuPnsVp7QgMkC1Qi8rtkekLkOFjo7OlEFRQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-linux-arm64-musl\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-linux-arm64-musl/-/oxide-linux-arm64-musl-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-WZA0CHRL/SP1TRbA5mp9htsppSEkWuQ4KsSUumYQnyl8ZdT39ntwqmz4IUHGN6p4XdSlYfJwM4rRzZLShHsGAQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-linux-x64-gnu\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-gnu/-/oxide-linux-x64-gnu-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-qMFzxI2YlBOLW5PhblzuSWlWfwLHaneBE0xHzLrBgNtqN6mWfs+qYbhryGSXQjFYB1Dzf5w+LN5qbUTPhW7Y5g==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-linux-x64-musl\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-linux-x64-musl/-/oxide-linux-x64-musl-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-5r1X2FKnCMUPlXTWRYpHdPYUY6a1Ar/t7P24OuiEdEOmms5lyqjDRvVY1yy9Rmioh+AunQ0rWiOTPE8F9A3v5g==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-wasm32-wasi\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-wasm32-wasi/-/oxide-wasm32-wasi-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-MGFB5cVPvshR85MTJkEvqDUnuNoysrsRxd6vnk1Lf2tbiqNlXpHYZqkqOQalydienEWOHHFyyuTSYRsLfxFJ2Q==\",\r\n      \"bundleDependencies\": [\r\n        \"@napi-rs/wasm-runtime\",\r\n        \"@emnapi/core\",\r\n        \"@emnapi/runtime\",\r\n        \"@tybys/wasm-util\",\r\n        \"@emnapi/wasi-threads\",\r\n        \"tslib\"\r\n      ],\r\n      \"cpu\": [\r\n        \"wasm32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/core\": \"^1.8.1\",\r\n        \"@emnapi/runtime\": \"^1.8.1\",\r\n        \"@emnapi/wasi-threads\": \"^1.1.0\",\r\n        \"@napi-rs/wasm-runtime\": \"^1.1.1\",\r\n        \"@tybys/wasm-util\": \"^0.10.1\",\r\n        \"tslib\": \"^2.8.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-win32-arm64-msvc\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-YlUEHRHBGnCMh4Nj4GnqQyBtsshUPdiNroZj8VPkvTZSoHsilRCwXcVKnG9kyi0ZFAS/3u+qKHBdDc81SADTRA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/oxide-win32-x64-msvc\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/oxide-win32-x64-msvc/-/oxide-win32-x64-msvc-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-rbO34G5sMWWyrN/idLeVxAZgAKWrn5LiR3/I90Q9MkA67s6T1oB0xtTe+0heoBvHSpbU9Mk7i6uwJnpo4u21XQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 20\"\r\n      }\r\n    },\r\n    \"node_modules/@tailwindcss/postcss\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tailwindcss/postcss/-/postcss-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-OEwGIBnXnj7zJeonOh6ZG9woofIjGrd2BORfvE5p9USYKDCZoQmfqLcfNiRWoJlRWLdNPn2IgVZuWAOM4iTYMw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@alloc/quick-lru\": \"^5.2.0\",\r\n        \"@tailwindcss/node\": \"4.2.1\",\r\n        \"@tailwindcss/oxide\": \"4.2.1\",\r\n        \"postcss\": \"^8.5.6\",\r\n        \"tailwindcss\": \"4.2.1\"\r\n      }\r\n    },\r\n    \"node_modules/@ts-morph/common\": {\r\n      \"version\": \"0.27.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@ts-morph/common/-/common-0.27.0.tgz\",\r\n      \"integrity\": \"sha512-Wf29UqxWDpc+i61k3oIOzcUfQt79PIT9y/MWfAGlrkjg6lBC1hwDECLXPVJAhWjiGbfBCxZd65F/LIZF3+jeJQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fast-glob\": \"^3.3.3\",\r\n        \"minimatch\": \"^10.0.1\",\r\n        \"path-browserify\": \"^1.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/@tweenjs/tween.js\": {\r\n      \"version\": \"23.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz\",\r\n      \"integrity\": \"sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@tybys/wasm-util\": {\r\n      \"version\": \"0.10.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz\",\r\n      \"integrity\": \"sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==\",\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@types/d3-array\": {\r\n      \"version\": \"3.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz\",\r\n      \"integrity\": \"sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/d3-color\": {\r\n      \"version\": \"3.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz\",\r\n      \"integrity\": \"sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/d3-ease\": {\r\n      \"version\": \"3.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz\",\r\n      \"integrity\": \"sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/d3-interpolate\": {\r\n      \"version\": \"3.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz\",\r\n      \"integrity\": \"sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@types/d3-color\": \"*\"\r\n      }\r\n    },\r\n    \"node_modules/@types/d3-path\": {\r\n      \"version\": \"3.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz\",\r\n      \"integrity\": \"sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/d3-scale\": {\r\n      \"version\": \"4.0.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz\",\r\n      \"integrity\": \"sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@types/d3-time\": \"*\"\r\n      }\r\n    },\r\n    \"node_modules/@types/d3-shape\": {\r\n      \"version\": \"3.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.2.0.tgz\",\r\n      \"integrity\": \"sha512-kVd74ta9eof3eJOvbNd1vGKS/XERRyQbT26Og63hIsvDO84cjD5gEOhsXf26w3FSoNlPVz84DOFcKv/oou+fMw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@types/d3-path\": \"*\"\r\n      }\r\n    },\r\n    \"node_modules/@types/d3-time\": {\r\n      \"version\": \"3.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz\",\r\n      \"integrity\": \"sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/d3-timer\": {\r\n      \"version\": \"3.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz\",\r\n      \"integrity\": \"sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/estree\": {\r\n      \"version\": \"1.0.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz\",\r\n      \"integrity\": \"sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/json-schema\": {\r\n      \"version\": \"7.0.15\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz\",\r\n      \"integrity\": \"sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@types/node\": {\r\n      \"version\": \"22.19.19\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.19.19.tgz\",\r\n      \"integrity\": \"sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"undici-types\": \"~6.21.0\"\r\n      }\r\n    },\r\n    \"node_modules/@types/react\": {\r\n      \"version\": \"19.2.14\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz\",\r\n      \"integrity\": \"sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"csstype\": \"^3.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/@types/react-dom\": {\r\n      \"version\": \"19.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.3.tgz\",\r\n      \"integrity\": \"sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"^19.2.0\"\r\n      }\r\n    },\r\n    \"node_modules/@types/stats.js\": {\r\n      \"version\": \"0.17.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz\",\r\n      \"integrity\": \"sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/three\": {\r\n      \"version\": \"0.180.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/three/-/three-0.180.0.tgz\",\r\n      \"integrity\": \"sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@dimforge/rapier3d-compat\": \"~0.12.0\",\r\n        \"@tweenjs/tween.js\": \"~23.1.3\",\r\n        \"@types/stats.js\": \"*\",\r\n        \"@types/webxr\": \"*\",\r\n        \"@webgpu/types\": \"*\",\r\n        \"fflate\": \"~0.8.2\",\r\n        \"meshoptimizer\": \"~0.22.0\"\r\n      }\r\n    },\r\n    \"node_modules/@types/three/node_modules/fflate\": {\r\n      \"version\": \"0.8.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz\",\r\n      \"integrity\": \"sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/use-sync-external-store\": {\r\n      \"version\": \"0.0.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz\",\r\n      \"integrity\": \"sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/validate-npm-package-name\": {\r\n      \"version\": \"4.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/validate-npm-package-name/-/validate-npm-package-name-4.0.2.tgz\",\r\n      \"integrity\": \"sha512-lrpDziQipxCEeK5kWxvljWYhUvOiB2A9izZd9B2AFarYAkqZshb4lPbRs7zKEic6eGtH8V/2qJW+dPp9OtF6bw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@types/webxr\": {\r\n      \"version\": \"0.5.24\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz\",\r\n      \"integrity\": \"sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@unpic/core\": {\r\n      \"version\": \"1.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@unpic/core/-/core-1.0.3.tgz\",\r\n      \"integrity\": \"sha512-aum9YNVUGso7MjGLD0Rp/08kywCGLqZ03/q6VQBFFakDBOXWEc8D4kPGcZ8v5wEnGRex3lE+++bOuucBp3KJ/w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"unpic\": \"^4.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/@unpic/react\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@unpic/react/-/react-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-5RmRfELwTF8w+4zjtQGqjpvX+RU2VLvis3xDCS1O2uWk0PZN2cvatL+3/KAR3mshAuRrkFGTX1XwyAezSXaoCA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@unpic/core\": \"^1.0.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"next\": \"^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0\",\r\n        \"react\": \"^17.0.0 || ^18.0.0 || ^19.0.0\",\r\n        \"react-dom\": \"^17.0.0 || ^18.0.0 || ^19.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"next\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@vercel/og\": {\r\n      \"version\": \"0.8.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@vercel/og/-/og-0.8.6.tgz\",\r\n      \"integrity\": \"sha512-hBcWIOppZV14bi+eAmCZj8Elj8hVSUZJTpf1lgGBhVD85pervzQ1poM/qYfFUlPraYSZYP+ASg6To5BwYmUSGQ==\",\r\n      \"license\": \"MPL-2.0\",\r\n      \"dependencies\": {\r\n        \"@resvg/resvg-wasm\": \"2.4.0\",\r\n        \"satori\": \"0.16.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@vinext/types\": {\r\n      \"version\": \"1.0.0-beta.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@vinext/types/-/types-1.0.0-beta.2.tgz\",\r\n      \"integrity\": \"sha512-kbKY/H1RWlf7yox4G6Vwk1JeM6x0Tv1EAv28f3tDYkK3brq+89vp5eZHbdw3L/pZMbAhG4oFyhT9C976y+jkhQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=22\"\r\n      }\r\n    },\r\n    \"node_modules/@vitejs/plugin-react\": {\r\n      \"version\": \"6.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-6.0.2.tgz\",\r\n      \"integrity\": \"sha512-DlSMqo4WhThw4vB8Mpn0Woe9J+Jfq1geJ61AKW0QEgLzGMNwtIMdxbDUzLxcun8W7NbJO0e2Jg/Nxm3cCSVzzg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@rolldown/pluginutils\": \"^1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@rolldown/plugin-babel\": \"^0.1.7 || ^0.2.0\",\r\n        \"babel-plugin-react-compiler\": \"^1.0.0\",\r\n        \"vite\": \"^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@rolldown/plugin-babel\": {\r\n          \"optional\": true\r\n        },\r\n        \"babel-plugin-react-compiler\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@vitejs/plugin-rsc\": {\r\n      \"version\": \"0.5.26\",\r\n      \"resolved\": \"https://registry.npmjs.org/@vitejs/plugin-rsc/-/plugin-rsc-0.5.26.tgz\",\r\n      \"integrity\": \"sha512-T8W8ODEutblw9qXQB512LDPyv1tAbJRD/Gf0QEGsAoydl4nxEtIrghnhoI9oLY9R+7aw+cLk1ZEltxWHWf4aHw==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@rolldown/pluginutils\": \"1.0.0-rc.18\",\r\n        \"es-module-lexer\": \"^2.1.0\",\r\n        \"estree-walker\": \"^3.0.3\",\r\n        \"magic-string\": \"^0.30.21\",\r\n        \"srvx\": \"^0.11.15\",\r\n        \"strip-literal\": \"^3.1.0\",\r\n        \"turbo-stream\": \"^3.2.0\",\r\n        \"vitefu\": \"^1.1.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"*\",\r\n        \"react-dom\": \"*\",\r\n        \"react-server-dom-webpack\": \"*\",\r\n        \"vite\": \"*\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"react-server-dom-webpack\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@vitejs/plugin-rsc/node_modules/@rolldown/pluginutils\": {\r\n      \"version\": \"1.0.0-rc.18\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.18.tgz\",\r\n      \"integrity\": \"sha512-CUY5Mnhe64xQBGZEEXQ5WyZwsc1JU3vAZLIxtrsBt3LO6UOb+C8GunVKqe9sT8NeWb4lqSaoJtp2xo6GxT1MNw==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@webassemblyjs/ast\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/helper-numbers\": \"1.13.2\",\r\n        \"@webassemblyjs/helper-wasm-bytecode\": \"1.13.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/floating-point-hex-parser\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@webassemblyjs/helper-api-error\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@webassemblyjs/helper-buffer\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@webassemblyjs/helper-numbers\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/floating-point-hex-parser\": \"1.13.2\",\r\n        \"@webassemblyjs/helper-api-error\": \"1.13.2\",\r\n        \"@xtuc/long\": \"4.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/helper-wasm-bytecode\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@webassemblyjs/helper-wasm-section\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-buffer\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-wasm-bytecode\": \"1.13.2\",\r\n        \"@webassemblyjs/wasm-gen\": \"1.14.1\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/ieee754\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@xtuc/ieee754\": \"^1.2.0\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/leb128\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@xtuc/long\": \"4.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/utf8\": {\r\n      \"version\": \"1.13.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz\",\r\n      \"integrity\": \"sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@webassemblyjs/wasm-edit\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-buffer\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-wasm-bytecode\": \"1.13.2\",\r\n        \"@webassemblyjs/helper-wasm-section\": \"1.14.1\",\r\n        \"@webassemblyjs/wasm-gen\": \"1.14.1\",\r\n        \"@webassemblyjs/wasm-opt\": \"1.14.1\",\r\n        \"@webassemblyjs/wasm-parser\": \"1.14.1\",\r\n        \"@webassemblyjs/wast-printer\": \"1.14.1\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/wasm-gen\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-wasm-bytecode\": \"1.13.2\",\r\n        \"@webassemblyjs/ieee754\": \"1.13.2\",\r\n        \"@webassemblyjs/leb128\": \"1.13.2\",\r\n        \"@webassemblyjs/utf8\": \"1.13.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/wasm-opt\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-buffer\": \"1.14.1\",\r\n        \"@webassemblyjs/wasm-gen\": \"1.14.1\",\r\n        \"@webassemblyjs/wasm-parser\": \"1.14.1\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/wasm-parser\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@webassemblyjs/helper-api-error\": \"1.13.2\",\r\n        \"@webassemblyjs/helper-wasm-bytecode\": \"1.13.2\",\r\n        \"@webassemblyjs/ieee754\": \"1.13.2\",\r\n        \"@webassemblyjs/leb128\": \"1.13.2\",\r\n        \"@webassemblyjs/utf8\": \"1.13.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webassemblyjs/wast-printer\": {\r\n      \"version\": \"1.14.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz\",\r\n      \"integrity\": \"sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@webassemblyjs/ast\": \"1.14.1\",\r\n        \"@xtuc/long\": \"4.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/@webgpu/types\": {\r\n      \"version\": \"0.1.72\",\r\n      \"resolved\": \"https://registry.npmjs.org/@webgpu/types/-/types-0.1.72.tgz\",\r\n      \"integrity\": \"sha512-0cF7RFM2edNoiIS1ODJp0/Gzv4/xSXhwoR0YCza+OWpJWtn4wmo9DvK91aLlH9+uUnwIriP7ZiC3WitmyhuzBw==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@xtuc/ieee754\": {\r\n      \"version\": \"1.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz\",\r\n      \"integrity\": \"sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/@xtuc/long\": {\r\n      \"version\": \"4.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz\",\r\n      \"integrity\": \"sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/accepts\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"mime-types\": \"^3.0.0\",\r\n        \"negotiator\": \"^1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/acorn\": {\r\n      \"version\": \"8.18.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz\",\r\n      \"integrity\": \"sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"acorn\": \"bin/acorn\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/acorn-loose\": {\r\n      \"version\": \"8.5.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/acorn-loose/-/acorn-loose-8.5.2.tgz\",\r\n      \"integrity\": \"sha512-PPvV6g8UGMGgjrMu+n/f9E/tCSkNQ2Y97eFvuVdJfG11+xdIeDcLyNdC8SHcrHbRqkfwLASdplyR6B6sKM1U4A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"acorn\": \"^8.15.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/ajv\": {\r\n      \"version\": \"8.20.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz\",\r\n      \"integrity\": \"sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fast-deep-equal\": \"^3.1.3\",\r\n        \"fast-uri\": \"^3.0.1\",\r\n        \"json-schema-traverse\": \"^1.0.0\",\r\n        \"require-from-string\": \"^2.0.2\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/epoberezkin\"\r\n      }\r\n    },\r\n    \"node_modules/ajv-formats\": {\r\n      \"version\": \"3.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz\",\r\n      \"integrity\": \"sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"ajv\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/ajv-keywords\": {\r\n      \"version\": \"5.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz\",\r\n      \"integrity\": \"sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"fast-deep-equal\": \"^3.1.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"ajv\": \"^8.8.2\"\r\n      }\r\n    },\r\n    \"node_modules/ansi-colors\": {\r\n      \"version\": \"4.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz\",\r\n      \"integrity\": \"sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/ansi-regex\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/argparse\": {\r\n      \"version\": \"2.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz\",\r\n      \"integrity\": \"sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==\",\r\n      \"license\": \"Python-2.0\"\r\n    },\r\n    \"node_modules/aria-hidden\": {\r\n      \"version\": \"1.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.6.tgz\",\r\n      \"integrity\": \"sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/ast-types\": {\r\n      \"version\": \"0.16.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/ast-types/-/ast-types-0.16.3.tgz\",\r\n      \"integrity\": \"sha512-FvWoWYfSCM6kRxCSH+MGLHIKKGRL6A6AW7Zek2O32REPQRdg131428uRTKMBYAeRd3XXAaHDS60Wpri7CdKDrA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/atomically\": {\r\n      \"version\": \"1.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz\",\r\n      \"integrity\": \"sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/balanced-match\": {\r\n      \"version\": \"4.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz\",\r\n      \"integrity\": \"sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \"18 || 20 || >=22\"\r\n      }\r\n    },\r\n    \"node_modules/base64-js\": {\r\n      \"version\": \"0.0.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz\",\r\n      \"integrity\": \"sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/baseline-browser-mapping\": {\r\n      \"version\": \"2.11.21\",\r\n      \"resolved\": \"https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.21.tgz\",\r\n      \"integrity\": \"sha512-uh8vpY/1/YyFkunIDFH/12p7/7VdPKA1hejMVEbdkEaWnUz0Hesvx5EbiU6XxjyHZIOju+ZMbQJkRh+es3/spQ==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"bin\": {\r\n        \"baseline-browser-mapping\": \"dist/cli.cjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/blake3-wasm\": {\r\n      \"version\": \"2.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz\",\r\n      \"integrity\": \"sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/body-parser\": {\r\n      \"version\": \"2.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz\",\r\n      \"integrity\": \"sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"bytes\": \"^3.1.2\",\r\n        \"content-type\": \"^2.0.0\",\r\n        \"debug\": \"^4.4.3\",\r\n        \"http-errors\": \"^2.0.1\",\r\n        \"iconv-lite\": \"^0.7.2\",\r\n        \"on-finished\": \"^2.4.1\",\r\n        \"qs\": \"^6.15.2\",\r\n        \"raw-body\": \"^3.0.2\",\r\n        \"type-is\": \"^2.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/body-parser/node_modules/content-type\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/brace-expansion\": {\r\n      \"version\": \"5.0.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz\",\r\n      \"integrity\": \"sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"balanced-match\": \"^4.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"20 || >=22\"\r\n      }\r\n    },\r\n    \"node_modules/braces\": {\r\n      \"version\": \"3.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/braces/-/braces-3.0.3.tgz\",\r\n      \"integrity\": \"sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fill-range\": \"^7.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/browserslist\": {\r\n      \"version\": \"4.28.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/browserslist/-/browserslist-4.28.9.tgz\",\r\n      \"integrity\": \"sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/browserslist\"\r\n        },\r\n        {\r\n          \"type\": \"tidelift\",\r\n          \"url\": \"https://tidelift.com/funding/github/npm/browserslist\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"baseline-browser-mapping\": \"^2.11.20\",\r\n        \"caniuse-lite\": \"^1.0.30001810\",\r\n        \"electron-to-chromium\": \"^1.5.420\",\r\n        \"node-releases\": \"^2.0.54\",\r\n        \"update-browserslist-db\": \"^1.3.2\"\r\n      },\r\n      \"bin\": {\r\n        \"browserslist\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7\"\r\n      }\r\n    },\r\n    \"node_modules/buffer-from\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/bundle-name\": {\r\n      \"version\": \"4.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz\",\r\n      \"integrity\": \"sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"run-applescript\": \"^7.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/bytes\": {\r\n      \"version\": \"3.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz\",\r\n      \"integrity\": \"sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/call-bind-apply-helpers\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"function-bind\": \"^1.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/call-bound\": {\r\n      \"version\": \"1.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz\",\r\n      \"integrity\": \"sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"call-bind-apply-helpers\": \"^1.0.2\",\r\n        \"get-intrinsic\": \"^1.3.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/callsites\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/camelize\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/caniuse-lite\": {\r\n      \"version\": \"1.0.30001810\",\r\n      \"resolved\": \"https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz\",\r\n      \"integrity\": \"sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/browserslist\"\r\n        },\r\n        {\r\n          \"type\": \"tidelift\",\r\n          \"url\": \"https://tidelift.com/funding/github/npm/caniuse-lite\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"CC-BY-4.0\"\r\n    },\r\n    \"node_modules/chalk\": {\r\n      \"version\": \"5.6.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz\",\r\n      \"integrity\": \"sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \"^12.17.0 || ^14.13 || >=16.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/chalk?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/chrome-trace-event\": {\r\n      \"version\": \"1.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz\",\r\n      \"integrity\": \"sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"engines\": {\r\n        \"node\": \">=6.0\"\r\n      }\r\n    },\r\n    \"node_modules/class-variance-authority\": {\r\n      \"version\": \"0.7.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.1.tgz\",\r\n      \"integrity\": \"sha512-Ka+9Trutv7G8M6WT6SeiRWz792K5qEqIGEGzXKhAE6xOWAY6pPH8U+9IY3oCMv6kqTmLsv7Xh/2w2RigkePMsg==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"clsx\": \"^2.1.1\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://polar.sh/cva\"\r\n      }\r\n    },\r\n    \"node_modules/cli-cursor\": {\r\n      \"version\": \"5.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz\",\r\n      \"integrity\": \"sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"restore-cursor\": \"^5.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/cli-spinners\": {\r\n      \"version\": \"2.9.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz\",\r\n      \"integrity\": \"sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/clsx\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/cmdk\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/cmdk/-/cmdk-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-Vsv7kFaXm+ptHDMZ7izaRsP70GgrW9NBNGswt9OZaVBLlE0SNpDq8eu/VGXyF9r7M0azK3Wy7OlYXsuyYLFzHg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@radix-ui/react-compose-refs\": \"^1.1.1\",\r\n        \"@radix-ui/react-dialog\": \"^1.1.6\",\r\n        \"@radix-ui/react-id\": \"^1.1.0\",\r\n        \"@radix-ui/react-primitive\": \"^2.0.2\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^18 || ^19 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^18 || ^19 || ^19.0.0-rc\"\r\n      }\r\n    },\r\n    \"node_modules/code-block-writer\": {\r\n      \"version\": \"13.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.3.tgz\",\r\n      \"integrity\": \"sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/color-name\": {\r\n      \"version\": \"1.1.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz\",\r\n      \"integrity\": \"sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/commander\": {\r\n      \"version\": \"14.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-14.0.3.tgz\",\r\n      \"integrity\": \"sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      }\r\n    },\r\n    \"node_modules/conf\": {\r\n      \"version\": \"10.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/conf/-/conf-10.2.0.tgz\",\r\n      \"integrity\": \"sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ajv\": \"^8.6.3\",\r\n        \"ajv-formats\": \"^2.1.1\",\r\n        \"atomically\": \"^1.7.0\",\r\n        \"debounce-fn\": \"^4.0.0\",\r\n        \"dot-prop\": \"^6.0.1\",\r\n        \"env-paths\": \"^2.2.1\",\r\n        \"json-schema-typed\": \"^7.0.3\",\r\n        \"onetime\": \"^5.1.2\",\r\n        \"pkg-up\": \"^3.1.0\",\r\n        \"semver\": \"^7.3.5\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/conf/node_modules/ajv-formats\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"ajv\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/conf/node_modules/json-schema-typed\": {\r\n      \"version\": \"7.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz\",\r\n      \"integrity\": \"sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==\",\r\n      \"license\": \"BSD-2-Clause\"\r\n    },\r\n    \"node_modules/conf/node_modules/semver\": {\r\n      \"version\": \"7.8.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-7.8.5.tgz\",\r\n      \"integrity\": \"sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==\",\r\n      \"license\": \"ISC\",\r\n      \"bin\": {\r\n        \"semver\": \"bin/semver.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/content-disposition\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/content-type\": {\r\n      \"version\": \"1.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz\",\r\n      \"integrity\": \"sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/convert-source-map\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/cookie\": {\r\n      \"version\": \"0.7.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz\",\r\n      \"integrity\": \"sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/cookie-signature\": {\r\n      \"version\": \"1.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz\",\r\n      \"integrity\": \"sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.6.0\"\r\n      }\r\n    },\r\n    \"node_modules/cors\": {\r\n      \"version\": \"2.8.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/cors/-/cors-2.8.6.tgz\",\r\n      \"integrity\": \"sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"object-assign\": \"^4\",\r\n        \"vary\": \"^1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.10\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/cosmiconfig\": {\r\n      \"version\": \"9.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.2.tgz\",\r\n      \"integrity\": \"sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"env-paths\": \"^2.2.1\",\r\n        \"import-fresh\": \"^3.3.0\",\r\n        \"js-yaml\": \"^4.1.0\",\r\n        \"parse-json\": \"^5.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/d-fischer\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"typescript\": \">=4.9.5\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"typescript\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/cross-spawn\": {\r\n      \"version\": \"7.0.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz\",\r\n      \"integrity\": \"sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"path-key\": \"^3.1.0\",\r\n        \"shebang-command\": \"^2.0.0\",\r\n        \"which\": \"^2.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/cross-spawn/node_modules/isexe\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/cross-spawn/node_modules/which\": {\r\n      \"version\": \"2.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-2.0.2.tgz\",\r\n      \"integrity\": \"sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"isexe\": \"^2.0.0\"\r\n      },\r\n      \"bin\": {\r\n        \"node-which\": \"bin/node-which\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/css-background-parser\": {\r\n      \"version\": \"0.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/css-background-parser/-/css-background-parser-0.1.0.tgz\",\r\n      \"integrity\": \"sha512-2EZLisiZQ+7m4wwur/qiYJRniHX4K5Tc9w93MT3AS0WS1u5kaZ4FKXlOTBhOjc+CgEgPiGY+fX1yWD8UwpEqUA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/css-box-shadow\": {\r\n      \"version\": \"1.0.0-3\",\r\n      \"resolved\": \"https://registry.npmjs.org/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz\",\r\n      \"integrity\": \"sha512-9jaqR6e7Ohds+aWwmhe6wILJ99xYQbfmK9QQB9CcMjDbTxPZjwEmUQpU91OG05Xgm8BahT5fW+svbsQGjS/zPg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/css-color-keywords\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/css-gradient-parser\": {\r\n      \"version\": \"0.0.16\",\r\n      \"resolved\": \"https://registry.npmjs.org/css-gradient-parser/-/css-gradient-parser-0.0.16.tgz\",\r\n      \"integrity\": \"sha512-3O5QdqgFRUbXvK1x5INf1YkBz1UKSWqrd63vWsum8MNHDBYD5urm3QtxZbKU259OrEXNM26lP/MPY3d1IGkBgA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/css-to-react-native\": {\r\n      \"version\": \"3.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz\",\r\n      \"integrity\": \"sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"camelize\": \"^1.0.0\",\r\n        \"css-color-keywords\": \"^1.0.0\",\r\n        \"postcss-value-parser\": \"^4.0.2\"\r\n      }\r\n    },\r\n    \"node_modules/cssesc\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"cssesc\": \"bin/cssesc\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/csstype\": {\r\n      \"version\": \"3.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz\",\r\n      \"integrity\": \"sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/d3-array\": {\r\n      \"version\": \"3.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz\",\r\n      \"integrity\": \"sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"internmap\": \"1 - 2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-color\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-ease\": {\r\n      \"version\": \"3.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz\",\r\n      \"integrity\": \"sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-format\": {\r\n      \"version\": \"3.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz\",\r\n      \"integrity\": \"sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-interpolate\": {\r\n      \"version\": \"3.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz\",\r\n      \"integrity\": \"sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"d3-color\": \"1 - 3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-path\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-scale\": {\r\n      \"version\": \"4.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz\",\r\n      \"integrity\": \"sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"d3-array\": \"2.10.0 - 3\",\r\n        \"d3-format\": \"1 - 3\",\r\n        \"d3-interpolate\": \"1.2.0 - 3\",\r\n        \"d3-time\": \"2.1.1 - 3\",\r\n        \"d3-time-format\": \"2 - 4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-shape\": {\r\n      \"version\": \"3.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz\",\r\n      \"integrity\": \"sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"d3-path\": \"^3.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-time\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"d3-array\": \"2 - 3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-time-format\": {\r\n      \"version\": \"4.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz\",\r\n      \"integrity\": \"sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"d3-time\": \"1 - 3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/d3-timer\": {\r\n      \"version\": \"3.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz\",\r\n      \"integrity\": \"sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/date-fns\": {\r\n      \"version\": \"4.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz\",\r\n      \"integrity\": \"sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/kossnocorp\"\r\n      }\r\n    },\r\n    \"node_modules/date-fns-jalali\": {\r\n      \"version\": \"4.1.0-0\",\r\n      \"resolved\": \"https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz\",\r\n      \"integrity\": \"sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/debounce-fn\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"mimic-fn\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/debug\": {\r\n      \"version\": \"4.4.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz\",\r\n      \"integrity\": \"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ms\": \"^2.1.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"supports-color\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/decimal.js-light\": {\r\n      \"version\": \"2.5.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz\",\r\n      \"integrity\": \"sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/dedent\": {\r\n      \"version\": \"1.7.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz\",\r\n      \"integrity\": \"sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"babel-plugin-macros\": \"^3.1.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"babel-plugin-macros\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/deepmerge\": {\r\n      \"version\": \"4.3.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz\",\r\n      \"integrity\": \"sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/default-browser\": {\r\n      \"version\": \"5.5.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/default-browser/-/default-browser-5.5.1.tgz\",\r\n      \"integrity\": \"sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"bundle-name\": \"^4.1.0\",\r\n        \"default-browser-id\": \"^5.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/default-browser-id\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/define-lazy-prop\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/depd\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/depd/-/depd-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/detect-libc\": {\r\n      \"version\": \"2.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz\",\r\n      \"integrity\": \"sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/detect-node-es\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/diff\": {\r\n      \"version\": \"8.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/diff/-/diff-8.0.4.tgz\",\r\n      \"integrity\": \"sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=0.3.1\"\r\n      }\r\n    },\r\n    \"node_modules/dot-prop\": {\r\n      \"version\": \"6.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz\",\r\n      \"integrity\": \"sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-obj\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/dotenv\": {\r\n      \"version\": \"17.4.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz\",\r\n      \"integrity\": \"sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==\",\r\n      \"license\": \"BSD-2-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://dotenvx.com\"\r\n      }\r\n    },\r\n    \"node_modules/dunder-proto\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"call-bind-apply-helpers\": \"^1.0.1\",\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"gopd\": \"^1.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/ee-first\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/electron-to-chromium\": {\r\n      \"version\": \"1.5.422\",\r\n      \"resolved\": \"https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.422.tgz\",\r\n      \"integrity\": \"sha512-UvA/32XqrLDdZSn7Jllo1AYNcWji/G0d5M0GTViE7KoGBiMunw3a34Sb2KO4ZZyrSEhqsxFoVhWWJshdyfKqJA==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/embla-carousel\": {\r\n      \"version\": \"8.5.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.5.2.tgz\",\r\n      \"integrity\": \"sha512-xQ9oVLrun/eCG/7ru3R+I5bJ7shsD8fFwLEY7yPe27/+fDHCNj0OT5EoG5ZbFyOxOcG6yTwW8oTz/dWyFnyGpg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/embla-carousel-react\": {\r\n      \"version\": \"8.5.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/embla-carousel-react/-/embla-carousel-react-8.5.2.tgz\",\r\n      \"integrity\": \"sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"embla-carousel\": \"8.5.2\",\r\n        \"embla-carousel-reactive-utils\": \"8.5.2\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.8.0 || ^17.0.1 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      }\r\n    },\r\n    \"node_modules/embla-carousel-reactive-utils\": {\r\n      \"version\": \"8.5.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/embla-carousel-reactive-utils/-/embla-carousel-reactive-utils-8.5.2.tgz\",\r\n      \"integrity\": \"sha512-QC8/hYSK/pEmqEdU1IO5O+XNc/Ptmmq7uCB44vKplgLKhB/l0+yvYx0+Cv0sF6Ena8Srld5vUErZkT+yTahtDg==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"embla-carousel\": \"8.5.2\"\r\n      }\r\n    },\r\n    \"node_modules/emoji-regex\": {\r\n      \"version\": \"10.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz\",\r\n      \"integrity\": \"sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/emoji-regex-xs\": {\r\n      \"version\": \"2.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz\",\r\n      \"integrity\": \"sha512-1QFuh8l7LqUcKe24LsPUNzjrzJQ7pgRwp1QMcZ5MX6mFplk2zQ08NVCM84++1cveaUUYtcCYHmeFEuNg16sU4g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/encodeurl\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/enhanced-resolve\": {\r\n      \"version\": \"5.24.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz\",\r\n      \"integrity\": \"sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"graceful-fs\": \"^4.2.4\",\r\n        \"tapable\": \"^2.3.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10.13.0\"\r\n      }\r\n    },\r\n    \"node_modules/enquirer\": {\r\n      \"version\": \"2.4.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz\",\r\n      \"integrity\": \"sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ansi-colors\": \"^4.1.1\",\r\n        \"strip-ansi\": \"^6.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8.6\"\r\n      }\r\n    },\r\n    \"node_modules/env-paths\": {\r\n      \"version\": \"2.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz\",\r\n      \"integrity\": \"sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/error-ex\": {\r\n      \"version\": \"1.3.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz\",\r\n      \"integrity\": \"sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-arrayish\": \"^0.2.1\"\r\n      }\r\n    },\r\n    \"node_modules/error-stack-parser-es\": {\r\n      \"version\": \"1.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz\",\r\n      \"integrity\": \"sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/antfu\"\r\n      }\r\n    },\r\n    \"node_modules/es-define-property\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/es-errors\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/es-module-lexer\": {\r\n      \"version\": \"2.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz\",\r\n      \"integrity\": \"sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/es-object-atoms\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-errors\": \"^1.3.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/es-toolkit\": {\r\n      \"version\": \"1.52.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-toolkit/-/es-toolkit-1.52.0.tgz\",\r\n      \"integrity\": \"sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==\",\r\n      \"license\": \"MIT\",\r\n      \"workspaces\": [\r\n        \"docs\",\r\n        \"benchmarks\",\r\n        \"tests/types\",\r\n        \"tests/browser-compat\"\r\n      ]\r\n    },\r\n    \"node_modules/esbuild\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==\",\r\n      \"devOptional\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"esbuild\": \"bin/esbuild\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@esbuild/aix-ppc64\": \"0.27.3\",\r\n        \"@esbuild/android-arm\": \"0.27.3\",\r\n        \"@esbuild/android-arm64\": \"0.27.3\",\r\n        \"@esbuild/android-x64\": \"0.27.3\",\r\n        \"@esbuild/darwin-arm64\": \"0.27.3\",\r\n        \"@esbuild/darwin-x64\": \"0.27.3\",\r\n        \"@esbuild/freebsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/freebsd-x64\": \"0.27.3\",\r\n        \"@esbuild/linux-arm\": \"0.27.3\",\r\n        \"@esbuild/linux-arm64\": \"0.27.3\",\r\n        \"@esbuild/linux-ia32\": \"0.27.3\",\r\n        \"@esbuild/linux-loong64\": \"0.27.3\",\r\n        \"@esbuild/linux-mips64el\": \"0.27.3\",\r\n        \"@esbuild/linux-ppc64\": \"0.27.3\",\r\n        \"@esbuild/linux-riscv64\": \"0.27.3\",\r\n        \"@esbuild/linux-s390x\": \"0.27.3\",\r\n        \"@esbuild/linux-x64\": \"0.27.3\",\r\n        \"@esbuild/netbsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/netbsd-x64\": \"0.27.3\",\r\n        \"@esbuild/openbsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/openbsd-x64\": \"0.27.3\",\r\n        \"@esbuild/openharmony-arm64\": \"0.27.3\",\r\n        \"@esbuild/sunos-x64\": \"0.27.3\",\r\n        \"@esbuild/win32-arm64\": \"0.27.3\",\r\n        \"@esbuild/win32-ia32\": \"0.27.3\",\r\n        \"@esbuild/win32-x64\": \"0.27.3\"\r\n      }\r\n    },\r\n    \"node_modules/escalade\": {\r\n      \"version\": \"3.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz\",\r\n      \"integrity\": \"sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/escape-html\": {\r\n      \"version\": \"1.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz\",\r\n      \"integrity\": \"sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/esprima\": {\r\n      \"version\": \"4.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz\",\r\n      \"integrity\": \"sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==\",\r\n      \"license\": \"BSD-2-Clause\",\r\n      \"bin\": {\r\n        \"esparse\": \"bin/esparse.js\",\r\n        \"esvalidate\": \"bin/esvalidate.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/estree-walker\": {\r\n      \"version\": \"3.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz\",\r\n      \"integrity\": \"sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@types/estree\": \"^1.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/etag\": {\r\n      \"version\": \"1.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/etag/-/etag-1.8.1.tgz\",\r\n      \"integrity\": \"sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/eventemitter3\": {\r\n      \"version\": \"5.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz\",\r\n      \"integrity\": \"sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/events\": {\r\n      \"version\": \"3.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/events/-/events-3.3.0.tgz\",\r\n      \"integrity\": \"sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"engines\": {\r\n        \"node\": \">=0.8.x\"\r\n      }\r\n    },\r\n    \"node_modules/eventsource\": {\r\n      \"version\": \"3.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz\",\r\n      \"integrity\": \"sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"eventsource-parser\": \"^3.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/eventsource-parser\": {\r\n      \"version\": \"3.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.1.1.tgz\",\r\n      \"integrity\": \"sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/execa\": {\r\n      \"version\": \"9.6.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/execa/-/execa-9.6.1.tgz\",\r\n      \"integrity\": \"sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@sindresorhus/merge-streams\": \"^4.0.0\",\r\n        \"cross-spawn\": \"^7.0.6\",\r\n        \"figures\": \"^6.1.0\",\r\n        \"get-stream\": \"^9.0.0\",\r\n        \"human-signals\": \"^8.0.1\",\r\n        \"is-plain-obj\": \"^4.1.0\",\r\n        \"is-stream\": \"^4.0.1\",\r\n        \"npm-run-path\": \"^6.0.0\",\r\n        \"pretty-ms\": \"^9.2.0\",\r\n        \"signal-exit\": \"^4.1.0\",\r\n        \"strip-final-newline\": \"^4.0.0\",\r\n        \"yoctocolors\": \"^2.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^18.19.0 || >=20.5.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sindresorhus/execa?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/express\": {\r\n      \"version\": \"5.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/express/-/express-5.2.1.tgz\",\r\n      \"integrity\": \"sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"accepts\": \"^2.0.0\",\r\n        \"body-parser\": \"^2.2.1\",\r\n        \"content-disposition\": \"^1.0.0\",\r\n        \"content-type\": \"^1.0.5\",\r\n        \"cookie\": \"^0.7.1\",\r\n        \"cookie-signature\": \"^1.2.1\",\r\n        \"debug\": \"^4.4.0\",\r\n        \"depd\": \"^2.0.0\",\r\n        \"encodeurl\": \"^2.0.0\",\r\n        \"escape-html\": \"^1.0.3\",\r\n        \"etag\": \"^1.8.1\",\r\n        \"finalhandler\": \"^2.1.0\",\r\n        \"fresh\": \"^2.0.0\",\r\n        \"http-errors\": \"^2.0.0\",\r\n        \"merge-descriptors\": \"^2.0.0\",\r\n        \"mime-types\": \"^3.0.0\",\r\n        \"on-finished\": \"^2.4.1\",\r\n        \"once\": \"^1.4.0\",\r\n        \"parseurl\": \"^1.3.3\",\r\n        \"proxy-addr\": \"^2.0.7\",\r\n        \"qs\": \"^6.14.0\",\r\n        \"range-parser\": \"^1.2.1\",\r\n        \"router\": \"^2.2.0\",\r\n        \"send\": \"^1.1.0\",\r\n        \"serve-static\": \"^2.2.0\",\r\n        \"statuses\": \"^2.0.1\",\r\n        \"type-is\": \"^2.0.1\",\r\n        \"vary\": \"^1.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/express-rate-limit\": {\r\n      \"version\": \"8.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.0.tgz\",\r\n      \"integrity\": \"sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"debug\": \"^4.4.3\",\r\n        \"ip-address\": \"^10.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 16\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/express-rate-limit\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"express\": \">= 4.11\"\r\n      }\r\n    },\r\n    \"node_modules/fast-deep-equal\": {\r\n      \"version\": \"3.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz\",\r\n      \"integrity\": \"sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/fast-glob\": {\r\n      \"version\": \"3.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz\",\r\n      \"integrity\": \"sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@nodelib/fs.stat\": \"^2.0.2\",\r\n        \"@nodelib/fs.walk\": \"^1.2.3\",\r\n        \"glob-parent\": \"^5.1.2\",\r\n        \"merge2\": \"^1.3.0\",\r\n        \"micromatch\": \"^4.0.8\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8.6.0\"\r\n      }\r\n    },\r\n    \"node_modules/fast-uri\": {\r\n      \"version\": \"3.1.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz\",\r\n      \"integrity\": \"sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/fastify\"\r\n        },\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/fastify\"\r\n        }\r\n      ],\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/fastq\": {\r\n      \"version\": \"1.20.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz\",\r\n      \"integrity\": \"sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"reusify\": \"^1.0.4\"\r\n      }\r\n    },\r\n    \"node_modules/fdir\": {\r\n      \"version\": \"6.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz\",\r\n      \"integrity\": \"sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"picomatch\": \"^3 || ^4\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"picomatch\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/fflate\": {\r\n      \"version\": \"0.7.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/fflate/-/fflate-0.7.5.tgz\",\r\n      \"integrity\": \"sha512-QieYf//cis6ywHNi5qW1+PXPQ4bC+XVJAtS4AXIML8P76GroEiOxm/oQtn1f02UkJY1+KsXMJcC+R2v/Eg4G3g==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/figures\": {\r\n      \"version\": \"6.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/figures/-/figures-6.1.0.tgz\",\r\n      \"integrity\": \"sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-unicode-supported\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/fill-range\": {\r\n      \"version\": \"7.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz\",\r\n      \"integrity\": \"sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"to-regex-range\": \"^5.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/finalhandler\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"debug\": \"^4.4.0\",\r\n        \"encodeurl\": \"^2.0.0\",\r\n        \"escape-html\": \"^1.0.3\",\r\n        \"on-finished\": \"^2.4.1\",\r\n        \"parseurl\": \"^1.3.3\",\r\n        \"statuses\": \"^2.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/find-up\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"locate-path\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/forwarded\": {\r\n      \"version\": \"0.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz\",\r\n      \"integrity\": \"sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/fresh\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/fs-extra\": {\r\n      \"version\": \"11.4.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz\",\r\n      \"integrity\": \"sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"graceful-fs\": \"^4.2.0\",\r\n        \"jsonfile\": \"^6.0.1\",\r\n        \"universalify\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.14\"\r\n      }\r\n    },\r\n    \"node_modules/fsevents\": {\r\n      \"version\": \"2.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz\",\r\n      \"integrity\": \"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==\",\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/function-bind\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/fuzzysort\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fuzzysort/-/fuzzysort-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-sR9BNCjBg6LNgwvxlBd0sBABvQitkLzoVY9MYYROQVX/FvfJ4Mai9LsGhDgd8qYdds0bY77VzYd5iuB+v5rwQQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/gensync\": {\r\n      \"version\": \"1.0.0-beta.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz\",\r\n      \"integrity\": \"sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/get-east-asian-width\": {\r\n      \"version\": \"1.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz\",\r\n      \"integrity\": \"sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/get-intrinsic\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"call-bind-apply-helpers\": \"^1.0.2\",\r\n        \"es-define-property\": \"^1.0.1\",\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"es-object-atoms\": \"^1.1.1\",\r\n        \"function-bind\": \"^1.1.2\",\r\n        \"get-proto\": \"^1.0.1\",\r\n        \"gopd\": \"^1.2.0\",\r\n        \"has-symbols\": \"^1.1.0\",\r\n        \"hasown\": \"^2.0.2\",\r\n        \"math-intrinsics\": \"^1.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/get-nonce\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/get-own-enumerable-keys\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-own-enumerable-keys/-/get-own-enumerable-keys-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-PKsK2FSrQCyxcGHsGrLDcK0lx+0Ke+6e8KFFozA9/fIQLhQzPaRvJFdcz7+Axg3jUH/Mq+NI4xa5u/UT2tQskA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=14.16\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/get-proto\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"dunder-proto\": \"^1.0.1\",\r\n        \"es-object-atoms\": \"^1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/get-stream\": {\r\n      \"version\": \"9.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz\",\r\n      \"integrity\": \"sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@sec-ant/readable-stream\": \"^0.4.1\",\r\n        \"is-stream\": \"^4.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/glob-parent\": {\r\n      \"version\": \"5.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz\",\r\n      \"integrity\": \"sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"is-glob\": \"^4.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 6\"\r\n      }\r\n    },\r\n    \"node_modules/gopd\": {\r\n      \"version\": \"1.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz\",\r\n      \"integrity\": \"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/graceful-fs\": {\r\n      \"version\": \"4.2.11\",\r\n      \"resolved\": \"https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz\",\r\n      \"integrity\": \"sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/has-flag\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/has-symbols\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/hasown\": {\r\n      \"version\": \"2.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz\",\r\n      \"integrity\": \"sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"function-bind\": \"^1.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/hex-rgb\": {\r\n      \"version\": \"4.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/hex-rgb/-/hex-rgb-4.3.0.tgz\",\r\n      \"integrity\": \"sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/hono\": {\r\n      \"version\": \"4.13.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/hono/-/hono-4.13.7.tgz\",\r\n      \"integrity\": \"sha512-c8/gF9ac8Y78/agExVocyLevgR+JlpNB444Py0FSX8pJoPdYUfUzRcXtYEYGwt6l19qIlVZPN5Mfsw9jFShmQQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=16.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/http-errors\": {\r\n      \"version\": \"2.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz\",\r\n      \"integrity\": \"sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"depd\": \"~2.0.0\",\r\n        \"inherits\": \"~2.0.4\",\r\n        \"setprototypeof\": \"~1.2.0\",\r\n        \"statuses\": \"~2.0.2\",\r\n        \"toidentifier\": \"~1.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/human-signals\": {\r\n      \"version\": \"8.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz\",\r\n      \"integrity\": \"sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==\",\r\n      \"license\": \"Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=18.18.0\"\r\n      }\r\n    },\r\n    \"node_modules/iconv-lite\": {\r\n      \"version\": \"0.7.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz\",\r\n      \"integrity\": \"sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"safer-buffer\": \">= 2.1.2 < 3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/ignore\": {\r\n      \"version\": \"5.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz\",\r\n      \"integrity\": \"sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 4\"\r\n      }\r\n    },\r\n    \"node_modules/image-size\": {\r\n      \"version\": \"2.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/image-size/-/image-size-2.0.2.tgz\",\r\n      \"integrity\": \"sha512-IRqXKlaXwgSMAMtpNzZa1ZAe8m+Sa1770Dhk8VkSsP9LS+iHD62Zd8FQKs8fbPiagBE7BzoFX23cxFnwshpV6w==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"image-size\": \"bin/image-size.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16.x\"\r\n      }\r\n    },\r\n    \"node_modules/immer\": {\r\n      \"version\": \"10.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/immer/-/immer-10.2.0.tgz\",\r\n      \"integrity\": \"sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/immer\"\r\n      }\r\n    },\r\n    \"node_modules/import-fresh\": {\r\n      \"version\": \"3.3.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz\",\r\n      \"integrity\": \"sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"parent-module\": \"^1.0.0\",\r\n        \"resolve-from\": \"^4.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/inherits\": {\r\n      \"version\": \"2.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz\",\r\n      \"integrity\": \"sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/input-otp\": {\r\n      \"version\": \"1.4.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz\",\r\n      \"integrity\": \"sha512-l3jWwYNvrEa6NTCt7BECfCm48GvwuZzkoeG3gBL2w4CHeOXW3eKFmf9UNYkNfYc3mxMrthMnxjIE07MT0zLBQA==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc\",\r\n        \"react-dom\": \"^16.8 || ^17.0 || ^18.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      }\r\n    },\r\n    \"node_modules/internmap\": {\r\n      \"version\": \"2.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz\",\r\n      \"integrity\": \"sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/ip-address\": {\r\n      \"version\": \"10.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz\",\r\n      \"integrity\": \"sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 12\"\r\n      }\r\n    },\r\n    \"node_modules/ipaddr.js\": {\r\n      \"version\": \"1.9.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz\",\r\n      \"integrity\": \"sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.10\"\r\n      }\r\n    },\r\n    \"node_modules/is-arrayish\": {\r\n      \"version\": \"0.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz\",\r\n      \"integrity\": \"sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/is-docker\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"is-docker\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^12.20.0 || ^14.13.1 || >=16.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-extglob\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/is-glob\": {\r\n      \"version\": \"4.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz\",\r\n      \"integrity\": \"sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-extglob\": \"^2.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/is-in-ssh\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-in-ssh/-/is-in-ssh-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-inside-container\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-docker\": \"^3.0.0\"\r\n      },\r\n      \"bin\": {\r\n        \"is-inside-container\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.16\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-interactive\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-number\": {\r\n      \"version\": \"7.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz\",\r\n      \"integrity\": \"sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/is-obj\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/is-plain-obj\": {\r\n      \"version\": \"4.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz\",\r\n      \"integrity\": \"sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-promise\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/is-regexp\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-stream\": {\r\n      \"version\": \"4.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz\",\r\n      \"integrity\": \"sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-unicode-supported\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/is-wsl\": {\r\n      \"version\": \"3.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz\",\r\n      \"integrity\": \"sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-inside-container\": \"^1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/isexe\": {\r\n      \"version\": \"3.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/isexe/-/isexe-3.1.5.tgz\",\r\n      \"integrity\": \"sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w==\",\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/jest-worker\": {\r\n      \"version\": \"27.5.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz\",\r\n      \"integrity\": \"sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@types/node\": \"*\",\r\n        \"merge-stream\": \"^2.0.0\",\r\n        \"supports-color\": \"^8.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 10.13.0\"\r\n      }\r\n    },\r\n    \"node_modules/jiti\": {\r\n      \"version\": \"2.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz\",\r\n      \"integrity\": \"sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"jiti\": \"lib/jiti-cli.mjs\"\r\n      }\r\n    },\r\n    \"node_modules/jose\": {\r\n      \"version\": \"6.2.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/jose/-/jose-6.2.12.tgz\",\r\n      \"integrity\": \"sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/panva\"\r\n      }\r\n    },\r\n    \"node_modules/js-tokens\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/js-yaml\": {\r\n      \"version\": \"4.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz\",\r\n      \"integrity\": \"sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/puzrin\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/nodeca\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"argparse\": \"^2.0.1\"\r\n      },\r\n      \"bin\": {\r\n        \"js-yaml\": \"bin/js-yaml.js\"\r\n      }\r\n    },\r\n    \"node_modules/jsesc\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"jsesc\": \"bin/jsesc\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/json-parse-even-better-errors\": {\r\n      \"version\": \"2.3.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz\",\r\n      \"integrity\": \"sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/json-schema-traverse\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/json-schema-typed\": {\r\n      \"version\": \"8.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz\",\r\n      \"integrity\": \"sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==\",\r\n      \"license\": \"BSD-2-Clause\"\r\n    },\r\n    \"node_modules/json5\": {\r\n      \"version\": \"2.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/json5/-/json5-2.2.3.tgz\",\r\n      \"integrity\": \"sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==\",\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"json5\": \"lib/cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/jsonfile\": {\r\n      \"version\": \"6.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz\",\r\n      \"integrity\": \"sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"universalify\": \"^2.0.0\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"graceful-fs\": \"^4.1.6\"\r\n      }\r\n    },\r\n    \"node_modules/kleur\": {\r\n      \"version\": \"4.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz\",\r\n      \"integrity\": \"sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss/-/lightningcss-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"dependencies\": {\r\n        \"detect-libc\": \"^2.0.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"lightningcss-android-arm64\": \"1.31.1\",\r\n        \"lightningcss-darwin-arm64\": \"1.31.1\",\r\n        \"lightningcss-darwin-x64\": \"1.31.1\",\r\n        \"lightningcss-freebsd-x64\": \"1.31.1\",\r\n        \"lightningcss-linux-arm-gnueabihf\": \"1.31.1\",\r\n        \"lightningcss-linux-arm64-gnu\": \"1.31.1\",\r\n        \"lightningcss-linux-arm64-musl\": \"1.31.1\",\r\n        \"lightningcss-linux-x64-gnu\": \"1.31.1\",\r\n        \"lightningcss-linux-x64-musl\": \"1.31.1\",\r\n        \"lightningcss-win32-arm64-msvc\": \"1.31.1\",\r\n        \"lightningcss-win32-x64-msvc\": \"1.31.1\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-android-arm64\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-darwin-arm64\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-darwin-x64\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-freebsd-x64\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm64-gnu\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm64-musl\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-x64-gnu\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-x64-musl\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-win32-arm64-msvc\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-win32-x64-msvc\": {\r\n      \"version\": \"1.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.31.1.tgz\",\r\n      \"integrity\": \"sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/linebreak\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/linebreak/-/linebreak-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"base64-js\": \"0.0.8\",\r\n        \"unicode-trie\": \"^2.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/lines-and-columns\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/locate-path\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"p-locate\": \"^3.0.0\",\r\n        \"path-exists\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/log-symbols\": {\r\n      \"version\": \"6.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz\",\r\n      \"integrity\": \"sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"chalk\": \"^5.3.0\",\r\n        \"is-unicode-supported\": \"^1.3.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/log-symbols/node_modules/is-unicode-supported\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/lru-cache\": {\r\n      \"version\": \"5.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz\",\r\n      \"integrity\": \"sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"yallist\": \"^3.0.2\"\r\n      }\r\n    },\r\n    \"node_modules/lucide-react\": {\r\n      \"version\": \"1.31.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lucide-react/-/lucide-react-1.31.0.tgz\",\r\n      \"integrity\": \"sha512-G8u2eEtoHUnUa9f8lbvqDhCiORMnYLdUEo06EEG9MQvHQrInKcX3Pa2TH39MM5qyzRcWETxB0+aOwAPI1g1kEg==\",\r\n      \"license\": \"ISC\",\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/magic-string\": {\r\n      \"version\": \"0.30.21\",\r\n      \"resolved\": \"https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz\",\r\n      \"integrity\": \"sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/sourcemap-codec\": \"^1.5.5\"\r\n      }\r\n    },\r\n    \"node_modules/math-intrinsics\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/media-typer\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/merge-descriptors\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/merge-stream\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/merge2\": {\r\n      \"version\": \"1.4.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz\",\r\n      \"integrity\": \"sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 8\"\r\n      }\r\n    },\r\n    \"node_modules/meshoptimizer\": {\r\n      \"version\": \"0.22.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz\",\r\n      \"integrity\": \"sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/micromatch\": {\r\n      \"version\": \"4.0.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz\",\r\n      \"integrity\": \"sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"braces\": \"^3.0.3\",\r\n        \"picomatch\": \"^2.3.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8.6\"\r\n      }\r\n    },\r\n    \"node_modules/micromatch/node_modules/picomatch\": {\r\n      \"version\": \"2.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz\",\r\n      \"integrity\": \"sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8.6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/jonschlinkert\"\r\n      }\r\n    },\r\n    \"node_modules/mime-db\": {\r\n      \"version\": \"1.54.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz\",\r\n      \"integrity\": \"sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      }\r\n    },\r\n    \"node_modules/mime-types\": {\r\n      \"version\": \"3.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz\",\r\n      \"integrity\": \"sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"mime-db\": \"^1.54.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/mimic-fn\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/mimic-function\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/miniflare\": {\r\n      \"version\": \"4.20260515.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/miniflare/-/miniflare-4.20260515.0.tgz\",\r\n      \"integrity\": \"sha512-2j0oQWizk1Eu4Cm8tDX7Z+Nsjd0nebIj1TQcQ+Oy1QKeo0Ay9+bdn8wfLAtOj9znDCybDCUlnS1+nYvKXEdfNg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@cspotcode/source-map-support\": \"0.8.1\",\r\n        \"sharp\": \"^0.34.5\",\r\n        \"undici\": \"7.24.8\",\r\n        \"workerd\": \"1.20260515.1\",\r\n        \"ws\": \"8.18.0\",\r\n        \"youch\": \"4.1.0-beta.10\"\r\n      },\r\n      \"bin\": {\r\n        \"miniflare\": \"bootstrap.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/minimatch\": {\r\n      \"version\": \"10.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz\",\r\n      \"integrity\": \"sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==\",\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"dependencies\": {\r\n        \"brace-expansion\": \"^5.0.8\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"18 || 20 || >=22\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/isaacs\"\r\n      }\r\n    },\r\n    \"node_modules/minimist\": {\r\n      \"version\": \"1.2.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz\",\r\n      \"integrity\": \"sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/minimizer-webpack-plugin\": {\r\n      \"version\": \"5.9.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.9.0.tgz\",\r\n      \"integrity\": \"sha512-OASqv+dewv8vjkOBjqMOHvxUaXhtGBLZAXq7JbmYE8TSzBvOswiGq5JcBdc8ypuLL/8YUT1OEyupga6/iqdyTA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@jridgewell/trace-mapping\": \"^0.3.31\",\r\n        \"jest-worker\": \"^27.4.5\",\r\n        \"schema-utils\": \"^4.3.3\",\r\n        \"terser\": \"^5.51.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 10.13.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/webpack\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"webpack\": \"^5.1.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@minify-html/node\": {\r\n          \"optional\": true\r\n        },\r\n        \"@napi-rs/image\": {\r\n          \"optional\": true\r\n        },\r\n        \"@swc/core\": {\r\n          \"optional\": true\r\n        },\r\n        \"@swc/css\": {\r\n          \"optional\": true\r\n        },\r\n        \"@swc/html\": {\r\n          \"optional\": true\r\n        },\r\n        \"clean-css\": {\r\n          \"optional\": true\r\n        },\r\n        \"cssnano\": {\r\n          \"optional\": true\r\n        },\r\n        \"csso\": {\r\n          \"optional\": true\r\n        },\r\n        \"esbuild\": {\r\n          \"optional\": true\r\n        },\r\n        \"html-minifier-terser\": {\r\n          \"optional\": true\r\n        },\r\n        \"imagemin\": {\r\n          \"optional\": true\r\n        },\r\n        \"lightningcss\": {\r\n          \"optional\": true\r\n        },\r\n        \"postcss\": {\r\n          \"optional\": true\r\n        },\r\n        \"sharp\": {\r\n          \"optional\": true\r\n        },\r\n        \"svgo\": {\r\n          \"optional\": true\r\n        },\r\n        \"uglify-js\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/ms\": {\r\n      \"version\": \"2.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\r\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/nanoid\": {\r\n      \"version\": \"3.3.18\",\r\n      \"resolved\": \"https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz\",\r\n      \"integrity\": \"sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"nanoid\": \"bin/nanoid.cjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^10 || ^12 || ^13.7 || ^14 || >=15.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/negotiator\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/negotiator/-/negotiator-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"content-type\": \"^2.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/negotiator/node_modules/content-type\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/neo-async\": {\r\n      \"version\": \"2.6.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz\",\r\n      \"integrity\": \"sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/node-releases\": {\r\n      \"version\": \"2.0.54\",\r\n      \"resolved\": \"https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz\",\r\n      \"integrity\": \"sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/npm-run-path\": {\r\n      \"version\": \"6.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz\",\r\n      \"integrity\": \"sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"path-key\": \"^4.0.0\",\r\n        \"unicorn-magic\": \"^0.3.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/npm-run-path/node_modules/path-key\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/object-assign\": {\r\n      \"version\": \"4.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz\",\r\n      \"integrity\": \"sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/object-inspect\": {\r\n      \"version\": \"1.13.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz\",\r\n      \"integrity\": \"sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/object-treeify\": {\r\n      \"version\": \"1.1.33\",\r\n      \"resolved\": \"https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz\",\r\n      \"integrity\": \"sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 10\"\r\n      }\r\n    },\r\n    \"node_modules/on-finished\": {\r\n      \"version\": \"2.4.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz\",\r\n      \"integrity\": \"sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ee-first\": \"1.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/once\": {\r\n      \"version\": \"1.4.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/once/-/once-1.4.0.tgz\",\r\n      \"integrity\": \"sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"wrappy\": \"1\"\r\n      }\r\n    },\r\n    \"node_modules/onetime\": {\r\n      \"version\": \"5.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz\",\r\n      \"integrity\": \"sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"mimic-fn\": \"^2.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/onetime/node_modules/mimic-fn\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/open\": {\r\n      \"version\": \"11.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/open/-/open-11.0.2.tgz\",\r\n      \"integrity\": \"sha512-RWqF+pBSkqecEvCKOn8QYhaNdRMJDZRIrlS/7rTDdLHaPcfXGCZ/h8zb413NfvdeAV0MR7T1yJcA34/q+CSm1Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"default-browser\": \"^5.5.1\",\r\n        \"define-lazy-prop\": \"^3.0.0\",\r\n        \"is-in-ssh\": \"^1.0.0\",\r\n        \"is-inside-container\": \"^1.0.0\",\r\n        \"powershell-utils\": \"^0.2.1\",\r\n        \"wsl-utils\": \"^1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/ora\": {\r\n      \"version\": \"8.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ora/-/ora-8.2.0.tgz\",\r\n      \"integrity\": \"sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"chalk\": \"^5.3.0\",\r\n        \"cli-cursor\": \"^5.0.0\",\r\n        \"cli-spinners\": \"^2.9.2\",\r\n        \"is-interactive\": \"^2.0.0\",\r\n        \"is-unicode-supported\": \"^2.0.0\",\r\n        \"log-symbols\": \"^6.0.0\",\r\n        \"stdin-discarder\": \"^0.2.2\",\r\n        \"string-width\": \"^7.2.0\",\r\n        \"strip-ansi\": \"^7.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/ora/node_modules/ansi-regex\": {\r\n      \"version\": \"6.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz\",\r\n      \"integrity\": \"sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/ansi-regex?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/ora/node_modules/strip-ansi\": {\r\n      \"version\": \"7.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz\",\r\n      \"integrity\": \"sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ansi-regex\": \"^6.2.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/strip-ansi?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/oxfmt\": {\r\n      \"version\": \"0.61.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/oxfmt/-/oxfmt-0.61.0.tgz\",\r\n      \"integrity\": \"sha512-DxdHBEMYpcEnHoUHjjOigUqV2TYKsvxLwUPXnVYBjgFdqrcQ/91OtwubtZ2PUodCs3sStI8R5Qw3fKNGK4e8wQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"tinypool\": \"2.1.0\"\r\n      },\r\n      \"bin\": {\r\n        \"oxfmt\": \"bin/oxfmt\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/Boshen\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@oxfmt/binding-android-arm-eabi\": \"0.61.0\",\r\n        \"@oxfmt/binding-android-arm64\": \"0.61.0\",\r\n        \"@oxfmt/binding-darwin-arm64\": \"0.61.0\",\r\n        \"@oxfmt/binding-darwin-x64\": \"0.61.0\",\r\n        \"@oxfmt/binding-freebsd-x64\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-arm-gnueabihf\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-arm-musleabihf\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-arm64-gnu\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-arm64-musl\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-ppc64-gnu\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-riscv64-gnu\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-riscv64-musl\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-s390x-gnu\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-x64-gnu\": \"0.61.0\",\r\n        \"@oxfmt/binding-linux-x64-musl\": \"0.61.0\",\r\n        \"@oxfmt/binding-openharmony-arm64\": \"0.61.0\",\r\n        \"@oxfmt/binding-win32-arm64-msvc\": \"0.61.0\",\r\n        \"@oxfmt/binding-win32-ia32-msvc\": \"0.61.0\",\r\n        \"@oxfmt/binding-win32-x64-msvc\": \"0.61.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"svelte\": \"^5.0.0\",\r\n        \"vite-plus\": \"*\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"svelte\": {\r\n          \"optional\": true\r\n        },\r\n        \"vite-plus\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/oxlint\": {\r\n      \"version\": \"1.76.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/oxlint/-/oxlint-1.76.0.tgz\",\r\n      \"integrity\": \"sha512-6QoFioEU4fNdiUx/2Eo6TRd6NG7H7njnRCz8rhB66cZmMHDTqcm1Rjvl8Wry+ZTQMBAmyb4Mlf62Mk5X+eHSOw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"oxlint\": \"bin/oxlint\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/Boshen\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@oxlint/binding-android-arm-eabi\": \"1.76.0\",\r\n        \"@oxlint/binding-android-arm64\": \"1.76.0\",\r\n        \"@oxlint/binding-darwin-arm64\": \"1.76.0\",\r\n        \"@oxlint/binding-darwin-x64\": \"1.76.0\",\r\n        \"@oxlint/binding-freebsd-x64\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-arm-gnueabihf\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-arm-musleabihf\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-arm64-gnu\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-arm64-musl\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-ppc64-gnu\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-riscv64-gnu\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-riscv64-musl\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-s390x-gnu\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-x64-gnu\": \"1.76.0\",\r\n        \"@oxlint/binding-linux-x64-musl\": \"1.76.0\",\r\n        \"@oxlint/binding-openharmony-arm64\": \"1.76.0\",\r\n        \"@oxlint/binding-win32-arm64-msvc\": \"1.76.0\",\r\n        \"@oxlint/binding-win32-ia32-msvc\": \"1.76.0\",\r\n        \"@oxlint/binding-win32-x64-msvc\": \"1.76.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"oxlint-tsgolint\": \">=7.0.2001\",\r\n        \"vite-plus\": \"*\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"oxlint-tsgolint\": {\r\n          \"optional\": true\r\n        },\r\n        \"vite-plus\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/oxlint-tsgolint\": {\r\n      \"version\": \"7.0.2001\",\r\n      \"resolved\": \"https://registry.npmjs.org/oxlint-tsgolint/-/oxlint-tsgolint-7.0.2001.tgz\",\r\n      \"integrity\": \"sha512-KjK/XLcXr1DSyonKhsuFqJRiuKqcyG9j3LJ8nkOsrLzGvodBPqzHOKauy10asLMDI0sUpvb+1sxlzff3udZvfg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"tsgolint\": \"bin/tsgolint.js\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@oxlint-tsgolint/darwin-arm64\": \"7.0.2001\",\r\n        \"@oxlint-tsgolint/darwin-x64\": \"7.0.2001\",\r\n        \"@oxlint-tsgolint/linux-arm64\": \"7.0.2001\",\r\n        \"@oxlint-tsgolint/linux-x64\": \"7.0.2001\",\r\n        \"@oxlint-tsgolint/win32-arm64\": \"7.0.2001\",\r\n        \"@oxlint-tsgolint/win32-x64\": \"7.0.2001\"\r\n      }\r\n    },\r\n    \"node_modules/p-limit\": {\r\n      \"version\": \"2.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz\",\r\n      \"integrity\": \"sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"p-try\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/p-locate\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"p-limit\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/p-try\": {\r\n      \"version\": \"2.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz\",\r\n      \"integrity\": \"sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/pako\": {\r\n      \"version\": \"0.2.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/pako/-/pako-0.2.9.tgz\",\r\n      \"integrity\": \"sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/parent-module\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"callsites\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/parse-css-color\": {\r\n      \"version\": \"0.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/parse-css-color/-/parse-css-color-0.2.1.tgz\",\r\n      \"integrity\": \"sha512-bwS/GGIFV3b6KS4uwpzCFj4w297Yl3uqnSgIPsoQkx7GMLROXfMnWvxfNkL0oh8HVhZA4hvJoEoEIqonfJ3BWg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"color-name\": \"^1.1.4\",\r\n        \"hex-rgb\": \"^4.1.0\"\r\n      }\r\n    },\r\n    \"node_modules/parse-json\": {\r\n      \"version\": \"5.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz\",\r\n      \"integrity\": \"sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/code-frame\": \"^7.0.0\",\r\n        \"error-ex\": \"^1.3.1\",\r\n        \"json-parse-even-better-errors\": \"^2.3.0\",\r\n        \"lines-and-columns\": \"^1.1.6\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/parse-ms\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/parseurl\": {\r\n      \"version\": \"1.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz\",\r\n      \"integrity\": \"sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/path-browserify\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/path-exists\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/path-key\": {\r\n      \"version\": \"3.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz\",\r\n      \"integrity\": \"sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/path-to-regexp\": {\r\n      \"version\": \"8.4.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz\",\r\n      \"integrity\": \"sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/pathe\": {\r\n      \"version\": \"2.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz\",\r\n      \"integrity\": \"sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/picocolors\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/picomatch\": {\r\n      \"version\": \"4.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz\",\r\n      \"integrity\": \"sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/jonschlinkert\"\r\n      }\r\n    },\r\n    \"node_modules/pkce-challenge\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=16.20.0\"\r\n      }\r\n    },\r\n    \"node_modules/pkg-up\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"find-up\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/postcss\": {\r\n      \"version\": \"8.5.28\",\r\n      \"resolved\": \"https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz\",\r\n      \"integrity\": \"sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/postcss/\"\r\n        },\r\n        {\r\n          \"type\": \"tidelift\",\r\n          \"url\": \"https://tidelift.com/funding/github/npm/postcss\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"nanoid\": \"^3.3.18\",\r\n        \"picocolors\": \"^1.1.1\",\r\n        \"source-map-js\": \"^1.2.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^10 || ^12 || >=14\"\r\n      }\r\n    },\r\n    \"node_modules/postcss-selector-parser\": {\r\n      \"version\": \"7.1.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.6.tgz\",\r\n      \"integrity\": \"sha512-7qASPzhKF2l2KLboRZux8CCTRMdGiV08vWmyKzPz22qZ7ZjQBOeY7rNzNoCLSUiftJ7HUq0GERHmxw/t0dCdMw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"cssesc\": \"^3.0.0\",\r\n        \"util-deprecate\": \"^1.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/postcss-value-parser\": {\r\n      \"version\": \"4.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz\",\r\n      \"integrity\": \"sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/powershell-utils\": {\r\n      \"version\": \"0.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.2.1.tgz\",\r\n      \"integrity\": \"sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/pretty-ms\": {\r\n      \"version\": \"9.3.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.3.1.tgz\",\r\n      \"integrity\": \"sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"parse-ms\": \"^4.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/prompts\": {\r\n      \"version\": \"2.4.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz\",\r\n      \"integrity\": \"sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"kleur\": \"^3.0.3\",\r\n        \"sisteransi\": \"^1.0.5\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 6\"\r\n      }\r\n    },\r\n    \"node_modules/prompts/node_modules/kleur\": {\r\n      \"version\": \"3.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz\",\r\n      \"integrity\": \"sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/proxy-addr\": {\r\n      \"version\": \"2.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz\",\r\n      \"integrity\": \"sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"forwarded\": \"0.2.0\",\r\n        \"ipaddr.js\": \"1.9.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.10\"\r\n      }\r\n    },\r\n    \"node_modules/qs\": {\r\n      \"version\": \"6.16.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/qs/-/qs-6.16.0.tgz\",\r\n      \"integrity\": \"sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"es-define-property\": \"^1.0.1\",\r\n        \"side-channel\": \"^1.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.6\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/queue-microtask\": {\r\n      \"version\": \"1.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz\",\r\n      \"integrity\": \"sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/feross\"\r\n        },\r\n        {\r\n          \"type\": \"patreon\",\r\n          \"url\": \"https://www.patreon.com/feross\"\r\n        },\r\n        {\r\n          \"type\": \"consulting\",\r\n          \"url\": \"https://feross.org/support\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/range-parser\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.6\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/raw-body\": {\r\n      \"version\": \"3.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz\",\r\n      \"integrity\": \"sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"bytes\": \"~3.1.2\",\r\n        \"http-errors\": \"~2.0.1\",\r\n        \"iconv-lite\": \"~0.7.0\",\r\n        \"unpipe\": \"~1.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.10\"\r\n      }\r\n    },\r\n    \"node_modules/react\": {\r\n      \"version\": \"19.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/react/-/react-19.2.6.tgz\",\r\n      \"integrity\": \"sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/react-day-picker\": {\r\n      \"version\": \"9.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.8.1.tgz\",\r\n      \"integrity\": \"sha512-kMcLrp3PfN/asVJayVv82IjF3iLOOxuH5TNFWezX6lS/T8iVRFPTETpHl3TUSTH99IDMZLubdNPJr++rQctkEw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@date-fns/tz\": \"^1.2.0\",\r\n        \"date-fns\": \"^4.1.0\",\r\n        \"date-fns-jalali\": \"^4.1.0-0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"individual\",\r\n        \"url\": \"https://github.com/sponsors/gpbl\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \">=16.8.0\"\r\n      }\r\n    },\r\n    \"node_modules/react-dom\": {\r\n      \"version\": \"19.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-dom/-/react-dom-19.2.6.tgz\",\r\n      \"integrity\": \"sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"scheduler\": \"^0.27.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^19.2.6\"\r\n      }\r\n    },\r\n    \"node_modules/react-is\": {\r\n      \"version\": \"19.2.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-is/-/react-is-19.2.8.tgz\",\r\n      \"integrity\": \"sha512-s5un28nYxKJw5gvUHyW5PCC28CvBqLu9r3cWgzHT4Vo/5fqqkFcdRYsGcKf50WMPpjjFZS5d76fn3YCo2njKwQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/react-redux\": {\r\n      \"version\": \"9.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-redux/-/react-redux-9.3.0.tgz\",\r\n      \"integrity\": \"sha512-KQopgqFo/p/fgmAs5qz6p5RWaNAzq40WAu7fJIXnQpYxFPbJYtsJPWvGeF2rOBaY/kEuV77AVsX8TsQzKm+A/g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@types/use-sync-external-store\": \"^0.0.6\",\r\n        \"use-sync-external-store\": \"^1.4.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"^18.2.25 || ^19\",\r\n        \"react\": \"^18.0 || ^19\",\r\n        \"redux\": \"^5.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        },\r\n        \"redux\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/react-remove-scroll\": {\r\n      \"version\": \"2.7.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz\",\r\n      \"integrity\": \"sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"react-remove-scroll-bar\": \"^2.3.7\",\r\n        \"react-style-singleton\": \"^2.2.3\",\r\n        \"tslib\": \"^2.1.0\",\r\n        \"use-callback-ref\": \"^1.3.3\",\r\n        \"use-sidecar\": \"^1.1.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/react-remove-scroll-bar\": {\r\n      \"version\": \"2.3.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.8.tgz\",\r\n      \"integrity\": \"sha512-9r+yi9+mgU33AKcj6IbT9oRCO78WriSj6t/cF8DWBZJ9aOGPOTEDvdUDz1FwKim7QXWwmHqtdHnRJfhAxEG46Q==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"react-style-singleton\": \"^2.2.2\",\r\n        \"tslib\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/react-resizable-panels\": {\r\n      \"version\": \"4.5.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-resizable-panels/-/react-resizable-panels-4.5.8.tgz\",\r\n      \"integrity\": \"sha512-X2S5YoYWbjd7Ove6e6T/kzOrjiUD6ccz55a+XW0H3JXbrPb+Gmz7YRAJy4ysOkua/U5jSOG9SoySbebMBjtQJQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"react\": \"^18.0.0 || ^19.0.0\",\r\n        \"react-dom\": \"^18.0.0 || ^19.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/react-server-dom-webpack\": {\r\n      \"version\": \"19.2.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-server-dom-webpack/-/react-server-dom-webpack-19.2.6.tgz\",\r\n      \"integrity\": \"sha512-762YXjBPc6hw2V16k4x1sdnw0mxghcSPzoiOhefGYjiTguJLCImGBUz6EjznPIfqKhWgLtpaQMlBhp66N8dKrw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"acorn-loose\": \"^8.3.0\",\r\n        \"neo-async\": \"^2.6.1\",\r\n        \"webpack-sources\": \"^3.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^19.2.6\",\r\n        \"react-dom\": \"^19.2.6\",\r\n        \"webpack\": \"^5.59.0\"\r\n      }\r\n    },\r\n    \"node_modules/react-style-singleton\": {\r\n      \"version\": \"2.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.3.tgz\",\r\n      \"integrity\": \"sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"get-nonce\": \"^1.0.0\",\r\n        \"tslib\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/recast\": {\r\n      \"version\": \"0.23.21\",\r\n      \"resolved\": \"https://registry.npmjs.org/recast/-/recast-0.23.21.tgz\",\r\n      \"integrity\": \"sha512-mFAyJq9vUbSTARLZUvAEf1z3YxlvAwswbmxMx2mPA/MSm4KmpwvwvhsH/NIrZhyOuwD60Lzyw2qh83uCbgTPYw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ast-types\": \"^0.16.1\",\r\n        \"esprima\": \"~4.0.0\",\r\n        \"source-map\": \"~0.6.1\",\r\n        \"tiny-invariant\": \"^1.3.3\",\r\n        \"tslib\": \"^2.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 4\"\r\n      }\r\n    },\r\n    \"node_modules/recharts\": {\r\n      \"version\": \"3.8.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/recharts/-/recharts-3.8.0.tgz\",\r\n      \"integrity\": \"sha512-Z/m38DX3L73ExO4Tpc9/iZWHmHnlzWG4njQbxsF5aSjwqmHNDDIm0rdEBArkwsBvR8U6EirlEHiQNYWCVh9sGQ==\",\r\n      \"license\": \"MIT\",\r\n      \"workspaces\": [\r\n        \"www\"\r\n      ],\r\n      \"dependencies\": {\r\n        \"@reduxjs/toolkit\": \"^1.9.0 || 2.x.x\",\r\n        \"clsx\": \"^2.1.1\",\r\n        \"decimal.js-light\": \"^2.5.1\",\r\n        \"es-toolkit\": \"^1.39.3\",\r\n        \"eventemitter3\": \"^5.0.1\",\r\n        \"immer\": \"^10.1.1\",\r\n        \"react-redux\": \"8.x.x || 9.x.x\",\r\n        \"reselect\": \"5.1.1\",\r\n        \"tiny-invariant\": \"^1.3.3\",\r\n        \"use-sync-external-store\": \"^1.2.2\",\r\n        \"victory-vendor\": \"^37.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\",\r\n        \"react-dom\": \"^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\",\r\n        \"react-is\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/recharts/node_modules/reselect\": {\r\n      \"version\": \"5.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz\",\r\n      \"integrity\": \"sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/redux\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/redux/-/redux-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/redux-thunk\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"redux\": \"^5.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/require-from-string\": {\r\n      \"version\": \"2.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz\",\r\n      \"integrity\": \"sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/reselect\": {\r\n      \"version\": \"5.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/reselect/-/reselect-5.3.0.tgz\",\r\n      \"integrity\": \"sha512-XGoLeRAVzUTcJ1qkxPQhDJyIZ5d6zzZD9nT7AEZOaaU9UbWclhycElmhO+VD5bFeLuzhPBaOV2oXC8uG35ZSpg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/resolve-from\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/restore-cursor\": {\r\n      \"version\": \"5.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz\",\r\n      \"integrity\": \"sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"onetime\": \"^7.0.0\",\r\n        \"signal-exit\": \"^4.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/restore-cursor/node_modules/onetime\": {\r\n      \"version\": \"7.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz\",\r\n      \"integrity\": \"sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"mimic-function\": \"^5.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/reusify\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"iojs\": \">=1.0.0\",\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/rolldown\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@oxc-project/types\": \"=0.130.0\",\r\n        \"@rolldown/pluginutils\": \"^1.0.0\"\r\n      },\r\n      \"bin\": {\r\n        \"rolldown\": \"bin/cli.mjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@rolldown/binding-android-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-darwin-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-darwin-x64\": \"1.0.1\",\r\n        \"@rolldown/binding-freebsd-x64\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm-gnueabihf\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm64-musl\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-ppc64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-s390x-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-x64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-x64-musl\": \"1.0.1\",\r\n        \"@rolldown/binding-openharmony-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-wasm32-wasi\": \"1.0.1\",\r\n        \"@rolldown/binding-win32-arm64-msvc\": \"1.0.1\",\r\n        \"@rolldown/binding-win32-x64-msvc\": \"1.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/router\": {\r\n      \"version\": \"2.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/router/-/router-2.2.0.tgz\",\r\n      \"integrity\": \"sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"debug\": \"^4.4.0\",\r\n        \"depd\": \"^2.0.0\",\r\n        \"is-promise\": \"^4.0.0\",\r\n        \"parseurl\": \"^1.3.3\",\r\n        \"path-to-regexp\": \"^8.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      }\r\n    },\r\n    \"node_modules/run-applescript\": {\r\n      \"version\": \"7.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz\",\r\n      \"integrity\": \"sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/run-parallel\": {\r\n      \"version\": \"1.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz\",\r\n      \"integrity\": \"sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/feross\"\r\n        },\r\n        {\r\n          \"type\": \"patreon\",\r\n          \"url\": \"https://www.patreon.com/feross\"\r\n        },\r\n        {\r\n          \"type\": \"consulting\",\r\n          \"url\": \"https://feross.org/support\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"queue-microtask\": \"^1.2.2\"\r\n      }\r\n    },\r\n    \"node_modules/safer-buffer\": {\r\n      \"version\": \"2.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz\",\r\n      \"integrity\": \"sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/satori\": {\r\n      \"version\": \"0.16.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/satori/-/satori-0.16.0.tgz\",\r\n      \"integrity\": \"sha512-ZvHN3ygzZ8FuxjSNB+mKBiF/NIoqHzlBGbD0MJiT+MvSsFOvotnWOhdTjxKzhHRT2wPC1QbhLzx2q/Y83VhfYQ==\",\r\n      \"license\": \"MPL-2.0\",\r\n      \"dependencies\": {\r\n        \"@shuding/opentype.js\": \"1.4.0-beta.0\",\r\n        \"css-background-parser\": \"^0.1.0\",\r\n        \"css-box-shadow\": \"1.0.0-3\",\r\n        \"css-gradient-parser\": \"^0.0.16\",\r\n        \"css-to-react-native\": \"^3.0.0\",\r\n        \"emoji-regex-xs\": \"^2.0.1\",\r\n        \"escape-html\": \"^1.0.3\",\r\n        \"linebreak\": \"^1.1.0\",\r\n        \"parse-css-color\": \"^0.2.1\",\r\n        \"postcss-value-parser\": \"^4.2.0\",\r\n        \"yoga-layout\": \"^3.2.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/scheduler\": {\r\n      \"version\": \"0.27.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz\",\r\n      \"integrity\": \"sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/schema-utils\": {\r\n      \"version\": \"4.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz\",\r\n      \"integrity\": \"sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@types/json-schema\": \"^7.0.9\",\r\n        \"ajv\": \"^8.9.0\",\r\n        \"ajv-formats\": \"^2.1.1\",\r\n        \"ajv-keywords\": \"^5.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 10.13.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/webpack\"\r\n      }\r\n    },\r\n    \"node_modules/schema-utils/node_modules/ajv-formats\": {\r\n      \"version\": \"2.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz\",\r\n      \"integrity\": \"sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"ajv\": \"^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"ajv\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/semver\": {\r\n      \"version\": \"6.3.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-6.3.1.tgz\",\r\n      \"integrity\": \"sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==\",\r\n      \"license\": \"ISC\",\r\n      \"bin\": {\r\n        \"semver\": \"bin/semver.js\"\r\n      }\r\n    },\r\n    \"node_modules/send\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/send/-/send-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"debug\": \"^4.4.3\",\r\n        \"encodeurl\": \"^2.0.0\",\r\n        \"escape-html\": \"^1.0.3\",\r\n        \"etag\": \"^1.8.1\",\r\n        \"fresh\": \"^2.0.0\",\r\n        \"http-errors\": \"^2.0.1\",\r\n        \"mime-types\": \"^3.0.2\",\r\n        \"ms\": \"^2.1.3\",\r\n        \"on-finished\": \"^2.4.1\",\r\n        \"range-parser\": \"^1.2.1\",\r\n        \"statuses\": \"^2.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/serve-static\": {\r\n      \"version\": \"2.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz\",\r\n      \"integrity\": \"sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"encodeurl\": \"^2.0.0\",\r\n        \"escape-html\": \"^1.0.3\",\r\n        \"parseurl\": \"^1.3.3\",\r\n        \"send\": \"^1.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/setprototypeof\": {\r\n      \"version\": \"1.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz\",\r\n      \"integrity\": \"sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/shadcn\": {\r\n      \"version\": \"4.18.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/shadcn/-/shadcn-4.18.0.tgz\",\r\n      \"integrity\": \"sha512-tUFZgkYmfVNQVm3xX7lhSzOvDsp+O14ac5dwgXIr5mIsr79ISueb/Mu+ZtWMz0DH6v77u4eYyvbQ9TTMpSn3aw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@babel/core\": \"^7.28.0\",\r\n        \"@babel/parser\": \"^7.28.0\",\r\n        \"@babel/plugin-transform-typescript\": \"^7.28.0\",\r\n        \"@babel/preset-typescript\": \"^7.27.1\",\r\n        \"@dotenvx/dotenvx\": \"^1.48.4\",\r\n        \"@modelcontextprotocol/sdk\": \"^1.26.0\",\r\n        \"@types/validate-npm-package-name\": \"^4.0.2\",\r\n        \"browserslist\": \"^4.26.2\",\r\n        \"commander\": \"^14.0.0\",\r\n        \"cosmiconfig\": \"^9.0.0\",\r\n        \"dedent\": \"^1.6.0\",\r\n        \"deepmerge\": \"^4.3.1\",\r\n        \"diff\": \"^8.0.2\",\r\n        \"execa\": \"^9.6.0\",\r\n        \"fast-glob\": \"^3.3.3\",\r\n        \"fs-extra\": \"^11.3.1\",\r\n        \"fuzzysort\": \"^3.1.0\",\r\n        \"kleur\": \"^4.1.5\",\r\n        \"open\": \"^11.0.0\",\r\n        \"ora\": \"^8.2.0\",\r\n        \"postcss\": \"^8.5.6\",\r\n        \"postcss-selector-parser\": \"^7.1.0\",\r\n        \"prompts\": \"^2.4.2\",\r\n        \"recast\": \"^0.23.11\",\r\n        \"socks\": \"^2.8.8\",\r\n        \"stringify-object\": \"^5.0.0\",\r\n        \"tailwind-merge\": \"^3.0.1\",\r\n        \"ts-morph\": \"^26.0.0\",\r\n        \"tsconfig-paths\": \"^4.2.0\",\r\n        \"undici\": \"^7.27.2\",\r\n        \"validate-npm-package-name\": \"^7.0.1\",\r\n        \"zod\": \"^3.24.1\",\r\n        \"zod-to-json-schema\": \"^3.24.6\"\r\n      },\r\n      \"bin\": {\r\n        \"shadcn\": \"dist/index.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20.18.1\"\r\n      }\r\n    },\r\n    \"node_modules/shadcn/node_modules/undici\": {\r\n      \"version\": \"7.29.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/undici/-/undici-7.29.1.tgz\",\r\n      \"integrity\": \"sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20.18.1\"\r\n      }\r\n    },\r\n    \"node_modules/sharp\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"@img/colour\": \"^1.0.0\",\r\n        \"detect-libc\": \"^2.1.2\",\r\n        \"semver\": \"^7.7.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-darwin-arm64\": \"0.34.5\",\r\n        \"@img/sharp-darwin-x64\": \"0.34.5\",\r\n        \"@img/sharp-libvips-darwin-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-darwin-x64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-arm\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-ppc64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-riscv64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-s390x\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-x64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linuxmusl-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linuxmusl-x64\": \"1.2.4\",\r\n        \"@img/sharp-linux-arm\": \"0.34.5\",\r\n        \"@img/sharp-linux-arm64\": \"0.34.5\",\r\n        \"@img/sharp-linux-ppc64\": \"0.34.5\",\r\n        \"@img/sharp-linux-riscv64\": \"0.34.5\",\r\n        \"@img/sharp-linux-s390x\": \"0.34.5\",\r\n        \"@img/sharp-linux-x64\": \"0.34.5\",\r\n        \"@img/sharp-linuxmusl-arm64\": \"0.34.5\",\r\n        \"@img/sharp-linuxmusl-x64\": \"0.34.5\",\r\n        \"@img/sharp-wasm32\": \"0.34.5\",\r\n        \"@img/sharp-win32-arm64\": \"0.34.5\",\r\n        \"@img/sharp-win32-ia32\": \"0.34.5\",\r\n        \"@img/sharp-win32-x64\": \"0.34.5\"\r\n      }\r\n    },\r\n    \"node_modules/sharp/node_modules/semver\": {\r\n      \"version\": \"7.8.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-7.8.5.tgz\",\r\n      \"integrity\": \"sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\",\r\n      \"bin\": {\r\n        \"semver\": \"bin/semver.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/shebang-command\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"shebang-regex\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/shebang-regex\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/side-channel\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"object-inspect\": \"^1.13.4\",\r\n        \"side-channel-list\": \"^1.0.1\",\r\n        \"side-channel-map\": \"^1.0.1\",\r\n        \"side-channel-weakmap\": \"^1.0.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/side-channel-list\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"object-inspect\": \"^1.13.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/side-channel-map\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"call-bound\": \"^1.0.2\",\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"get-intrinsic\": \"^1.2.5\",\r\n        \"object-inspect\": \"^1.13.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/side-channel-weakmap\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"call-bound\": \"^1.0.2\",\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"get-intrinsic\": \"^1.2.5\",\r\n        \"object-inspect\": \"^1.13.3\",\r\n        \"side-channel-map\": \"^1.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/signal-exit\": {\r\n      \"version\": \"4.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz\",\r\n      \"integrity\": \"sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \">=14\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/isaacs\"\r\n      }\r\n    },\r\n    \"node_modules/sisteransi\": {\r\n      \"version\": \"1.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz\",\r\n      \"integrity\": \"sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/smart-buffer\": {\r\n      \"version\": \"4.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz\",\r\n      \"integrity\": \"sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 6.0.0\",\r\n        \"npm\": \">= 3.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/socks\": {\r\n      \"version\": \"2.8.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/socks/-/socks-2.8.10.tgz\",\r\n      \"integrity\": \"sha512-e0VyvkVTwVYViNovRkZ9aodhxVlyoMn7eJhVUPxZ+eK9P/7CBkxvvsBOHqFPEH416726W8tLXXXjKwqgTErrCQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ip-address\": \"^10.1.1\",\r\n        \"smart-buffer\": \"^4.2.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 10.0.0\",\r\n        \"npm\": \">= 3.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/source-map\": {\r\n      \"version\": \"0.6.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz\",\r\n      \"integrity\": \"sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/source-map-js\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==\",\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/source-map-support\": {\r\n      \"version\": \"0.5.21\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz\",\r\n      \"integrity\": \"sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"buffer-from\": \"^1.0.0\",\r\n        \"source-map\": \"^0.6.0\"\r\n      }\r\n    },\r\n    \"node_modules/srvx\": {\r\n      \"version\": \"0.11.22\",\r\n      \"resolved\": \"https://registry.npmjs.org/srvx/-/srvx-0.11.22.tgz\",\r\n      \"integrity\": \"sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"srvx\": \"bin/srvx.mjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20.16.0\"\r\n      }\r\n    },\r\n    \"node_modules/statuses\": {\r\n      \"version\": \"2.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz\",\r\n      \"integrity\": \"sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/stdin-discarder\": {\r\n      \"version\": \"0.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz\",\r\n      \"integrity\": \"sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/string-width\": {\r\n      \"version\": \"7.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz\",\r\n      \"integrity\": \"sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"emoji-regex\": \"^10.3.0\",\r\n        \"get-east-asian-width\": \"^1.0.0\",\r\n        \"strip-ansi\": \"^7.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/string-width/node_modules/ansi-regex\": {\r\n      \"version\": \"6.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz\",\r\n      \"integrity\": \"sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/ansi-regex?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/string-width/node_modules/strip-ansi\": {\r\n      \"version\": \"7.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz\",\r\n      \"integrity\": \"sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ansi-regex\": \"^6.2.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/strip-ansi?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/string.prototype.codepointat\": {\r\n      \"version\": \"0.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz\",\r\n      \"integrity\": \"sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/stringify-object\": {\r\n      \"version\": \"5.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/stringify-object/-/stringify-object-5.0.0.tgz\",\r\n      \"integrity\": \"sha512-zaJYxz2FtcMb4f+g60KsRNFOpVMUyuJgA51Zi5Z1DOTC3S59+OQiVOzE9GZt0x72uBGWKsQIuBKeF9iusmKFsg==\",\r\n      \"license\": \"BSD-2-Clause\",\r\n      \"dependencies\": {\r\n        \"get-own-enumerable-keys\": \"^1.0.0\",\r\n        \"is-obj\": \"^3.0.0\",\r\n        \"is-regexp\": \"^3.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.16\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/yeoman/stringify-object?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/stringify-object/node_modules/is-obj\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/is-obj/-/is-obj-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-IlsXEHOjtKhpN8r/tRFj2nDyTmHvcfNeu/nrRIcXE17ROeatXchkojffa1SpdqW4cr/Fj6QkEf/Gn4zf6KKvEQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/strip-ansi\": {\r\n      \"version\": \"6.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz\",\r\n      \"integrity\": \"sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ansi-regex\": \"^5.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/strip-bom\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=4\"\r\n      }\r\n    },\r\n    \"node_modules/strip-final-newline\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/strip-literal\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"js-tokens\": \"^9.0.1\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/antfu\"\r\n      }\r\n    },\r\n    \"node_modules/strip-literal/node_modules/js-tokens\": {\r\n      \"version\": \"9.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz\",\r\n      \"integrity\": \"sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/supports-color\": {\r\n      \"version\": \"8.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz\",\r\n      \"integrity\": \"sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"has-flag\": \"^4.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/supports-color?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/systeminformation\": {\r\n      \"version\": \"5.33.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/systeminformation/-/systeminformation-5.33.8.tgz\",\r\n      \"integrity\": \"sha512-v4F6OGYGh7wDvV68YmjOmZwGixV9A/GQ7d2b84t0UF4CaOy9jipNWIJDkHqYDYiTPuiojqlwVQd0hfUKOUN7tQ==\",\r\n      \"license\": \"MIT\",\r\n      \"os\": [\r\n        \"darwin\",\r\n        \"linux\",\r\n        \"win32\",\r\n        \"freebsd\",\r\n        \"openbsd\",\r\n        \"netbsd\",\r\n        \"sunos\",\r\n        \"android\"\r\n      ],\r\n      \"bin\": {\r\n        \"systeminformation\": \"lib/cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"Buy me a coffee\",\r\n        \"url\": \"https://www.buymeacoffee.com/systeminfo\"\r\n      }\r\n    },\r\n    \"node_modules/tailwind-merge\": {\r\n      \"version\": \"3.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.6.0.tgz\",\r\n      \"integrity\": \"sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/dcastil\"\r\n      }\r\n    },\r\n    \"node_modules/tailwindcss\": {\r\n      \"version\": \"4.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.2.1.tgz\",\r\n      \"integrity\": \"sha512-/tBrSQ36vCleJkAOsy9kbNTgaxvGbyOamC30PRePTQe/o1MFwEKHQk4Cn7BNGaPtjp+PuUrByJehM1hgxfq4sw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tapable\": {\r\n      \"version\": \"2.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz\",\r\n      \"integrity\": \"sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/webpack\"\r\n      }\r\n    },\r\n    \"node_modules/terser\": {\r\n      \"version\": \"5.51.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/terser/-/terser-5.51.2.tgz\",\r\n      \"integrity\": \"sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==\",\r\n      \"license\": \"BSD-2-Clause\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@jridgewell/source-map\": \"^0.3.3\",\r\n        \"acorn\": \"^8.15.0\",\r\n        \"commander\": \"^2.20.0\",\r\n        \"source-map-support\": \"~0.5.20\"\r\n      },\r\n      \"bin\": {\r\n        \"terser\": \"bin/terser\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/terser/node_modules/commander\": {\r\n      \"version\": \"2.20.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/commander/-/commander-2.20.3.tgz\",\r\n      \"integrity\": \"sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true\r\n    },\r\n    \"node_modules/three\": {\r\n      \"version\": \"0.180.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/three/-/three-0.180.0.tgz\",\r\n      \"integrity\": \"sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tiny-inflate\": {\r\n      \"version\": \"1.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz\",\r\n      \"integrity\": \"sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tiny-invariant\": {\r\n      \"version\": \"1.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz\",\r\n      \"integrity\": \"sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tinyglobby\": {\r\n      \"version\": \"0.2.17\",\r\n      \"resolved\": \"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz\",\r\n      \"integrity\": \"sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fdir\": \"^6.5.0\",\r\n        \"picomatch\": \"^4.0.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/SuperchupuDev\"\r\n      }\r\n    },\r\n    \"node_modules/tinypool\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \"^20.0.0 || >=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/to-regex-range\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-number\": \"^7.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8.0\"\r\n      }\r\n    },\r\n    \"node_modules/toidentifier\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=0.6\"\r\n      }\r\n    },\r\n    \"node_modules/ts-morph\": {\r\n      \"version\": \"26.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ts-morph/-/ts-morph-26.0.0.tgz\",\r\n      \"integrity\": \"sha512-ztMO++owQnz8c/gIENcM9XfCEzgoGphTv+nKpYNM1bgsdOVC/jRZuEBf6N+mLLDNg68Kl+GgUZfOySaRiG1/Ug==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@ts-morph/common\": \"~0.27.0\",\r\n        \"code-block-writer\": \"^13.0.3\"\r\n      }\r\n    },\r\n    \"node_modules/tsconfig-paths\": {\r\n      \"version\": \"4.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz\",\r\n      \"integrity\": \"sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"json5\": \"^2.2.2\",\r\n        \"minimist\": \"^1.2.6\",\r\n        \"strip-bom\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/tslib\": {\r\n      \"version\": \"2.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz\",\r\n      \"integrity\": \"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==\",\r\n      \"license\": \"0BSD\"\r\n    },\r\n    \"node_modules/turbo-stream\": {\r\n      \"version\": \"3.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/turbo-stream/-/turbo-stream-3.2.1.tgz\",\r\n      \"integrity\": \"sha512-BaX0eWz3IrypOVDFqPv3VGD6uZZW8y3oFAOJqZQ+oopmOyQ8/xNm7IMwAJFvxax2DBa8zSk+/AeqA6D6b1PXGg==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tw-animate-css\": {\r\n      \"version\": \"1.4.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/tw-animate-css/-/tw-animate-css-1.4.0.tgz\",\r\n      \"integrity\": \"sha512-7bziOlRqH0hJx80h/3mbicLW7o8qLsH5+RaLR2t+OHM3D0JlWGODQKQ4cxbK7WlvmUxpcj6Kgu6EKqjrGFe3QQ==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/Wombosvideo\"\r\n      }\r\n    },\r\n    \"node_modules/type-is\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"content-type\": \"^2.0.0\",\r\n        \"media-typer\": \"^1.1.0\",\r\n        \"mime-types\": \"^3.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/type-is/node_modules/content-type\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/typescript\": {\r\n      \"version\": \"5.9.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz\",\r\n      \"integrity\": \"sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"bin\": {\r\n        \"tsc\": \"bin/tsc\",\r\n        \"tsserver\": \"bin/tsserver\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=14.17\"\r\n      }\r\n    },\r\n    \"node_modules/undici\": {\r\n      \"version\": \"7.24.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/undici/-/undici-7.24.8.tgz\",\r\n      \"integrity\": \"sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20.18.1\"\r\n      }\r\n    },\r\n    \"node_modules/undici-types\": {\r\n      \"version\": \"6.21.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\r\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/unenv\": {\r\n      \"version\": \"2.0.0-rc.24\",\r\n      \"resolved\": \"https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz\",\r\n      \"integrity\": \"sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"pathe\": \"^2.0.3\"\r\n      }\r\n    },\r\n    \"node_modules/unicode-trie\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/unicode-trie/-/unicode-trie-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"pako\": \"^0.2.5\",\r\n        \"tiny-inflate\": \"^1.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/unicorn-magic\": {\r\n      \"version\": \"0.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz\",\r\n      \"integrity\": \"sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/universalify\": {\r\n      \"version\": \"2.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz\",\r\n      \"integrity\": \"sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 10.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/unpic\": {\r\n      \"version\": \"4.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/unpic/-/unpic-4.2.2.tgz\",\r\n      \"integrity\": \"sha512-z6T2ScMgRV2y2H8MwwhY5xHZWXhUx/YxtOCGJwfURSl7ypVy4HpLIMWoIZKnnxQa/RKzM0kg8hUh0paIrpLfvw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/unpipe\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/update-browserslist-db\": {\r\n      \"version\": \"1.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz\",\r\n      \"integrity\": \"sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==\",\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/browserslist\"\r\n        },\r\n        {\r\n          \"type\": \"tidelift\",\r\n          \"url\": \"https://tidelift.com/funding/github/npm/browserslist\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"escalade\": \"^3.2.0\",\r\n        \"picocolors\": \"^1.1.1\"\r\n      },\r\n      \"bin\": {\r\n        \"update-browserslist-db\": \"cli.js\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"browserslist\": \">= 4.21.0\"\r\n      }\r\n    },\r\n    \"node_modules/use-callback-ref\": {\r\n      \"version\": \"1.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.3.tgz\",\r\n      \"integrity\": \"sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/use-sidecar\": {\r\n      \"version\": \"1.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz\",\r\n      \"integrity\": \"sha512-Fedw0aZvkhynoPYlA5WXrMCAMm+nSWdZt6lzJQ7Ok8S6Q+VsHmHpRWndVRJ8Be0ZbkfPc5LRYH+5XrzXcEeLRQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"detect-node-es\": \"^1.1.0\",\r\n        \"tslib\": \"^2.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/react\": \"*\",\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/react\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/use-sync-external-store\": {\r\n      \"version\": \"1.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz\",\r\n      \"integrity\": \"sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==\",\r\n      \"license\": \"MIT\",\r\n      \"peerDependencies\": {\r\n        \"react\": \"^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/util-deprecate\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/validate-npm-package-name\": {\r\n      \"version\": \"7.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz\",\r\n      \"integrity\": \"sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==\",\r\n      \"license\": \"ISC\",\r\n      \"engines\": {\r\n        \"node\": \"^20.17.0 || >=22.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/vary\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/vary/-/vary-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.8\"\r\n      }\r\n    },\r\n    \"node_modules/victory-vendor\": {\r\n      \"version\": \"37.3.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/victory-vendor/-/victory-vendor-37.3.6.tgz\",\r\n      \"integrity\": \"sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==\",\r\n      \"license\": \"MIT AND ISC\",\r\n      \"dependencies\": {\r\n        \"@types/d3-array\": \"^3.0.3\",\r\n        \"@types/d3-ease\": \"^3.0.0\",\r\n        \"@types/d3-interpolate\": \"^3.0.1\",\r\n        \"@types/d3-scale\": \"^4.0.2\",\r\n        \"@types/d3-shape\": \"^3.1.0\",\r\n        \"@types/d3-time\": \"^3.0.0\",\r\n        \"@types/d3-timer\": \"^3.0.0\",\r\n        \"d3-array\": \"^3.1.6\",\r\n        \"d3-ease\": \"^3.0.1\",\r\n        \"d3-interpolate\": \"^3.0.1\",\r\n        \"d3-scale\": \"^4.0.2\",\r\n        \"d3-shape\": \"^3.1.0\",\r\n        \"d3-time\": \"^3.0.0\",\r\n        \"d3-timer\": \"^3.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/vinext\": {\r\n      \"version\": \"1.0.0-beta.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/vinext/-/vinext-1.0.0-beta.5.tgz\",\r\n      \"integrity\": \"sha512-c0I1UB70/pGwD9y4/iXWrGfz/LnowSbkQpUw+lK9t08tes5WHX7Vl0sZAY4MIzGaVCyvrD4/xZo7HWpMje6SwA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@unpic/react\": \"^1.0.2\",\r\n        \"@vercel/og\": \"^0.8.6\",\r\n        \"@vinext/types\": \"^1.0.0-beta.2\",\r\n        \"image-size\": \"2.0.2\",\r\n        \"ipaddr.js\": \"^2.1.0\",\r\n        \"magic-string\": \"^0.30.21\",\r\n        \"vite-plugin-commonjs\": \"^0.10.4\",\r\n        \"web-vitals\": \"^4.2.4\"\r\n      },\r\n      \"bin\": {\r\n        \"vinext\": \"dist/cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@mdx-js/rollup\": \"^3.0.0\",\r\n        \"@vitejs/plugin-react\": \"^5.1.4 || ^6.0.0\",\r\n        \"@vitejs/plugin-rsc\": \"^0.5.26\",\r\n        \"react\": \"^19.2.6\",\r\n        \"react-dom\": \"^19.2.6\",\r\n        \"react-server-dom-webpack\": \"^19.2.6\",\r\n        \"vite\": \"^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@mdx-js/rollup\": {\r\n          \"optional\": true\r\n        },\r\n        \"@vitejs/plugin-rsc\": {\r\n          \"optional\": true\r\n        },\r\n        \"react-server-dom-webpack\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/vinext/node_modules/ipaddr.js\": {\r\n      \"version\": \"2.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.5.0.tgz\",\r\n      \"integrity\": \"sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 10\"\r\n      }\r\n    },\r\n    \"node_modules/vite\": {\r\n      \"version\": \"8.0.13\",\r\n      \"resolved\": \"https://registry.npmjs.org/vite/-/vite-8.0.13.tgz\",\r\n      \"integrity\": \"sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"lightningcss\": \"^1.32.0\",\r\n        \"picomatch\": \"^4.0.4\",\r\n        \"postcss\": \"^8.5.14\",\r\n        \"rolldown\": \"1.0.1\",\r\n        \"tinyglobby\": \"^0.2.16\"\r\n      },\r\n      \"bin\": {\r\n        \"vite\": \"bin/vite.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/vitejs/vite?sponsor=1\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"fsevents\": \"~2.3.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/node\": \"^20.19.0 || >=22.12.0\",\r\n        \"@vitejs/devtools\": \"^0.1.18\",\r\n        \"esbuild\": \"^0.27.0 || ^0.28.0\",\r\n        \"jiti\": \">=1.21.0\",\r\n        \"less\": \"^4.0.0\",\r\n        \"sass\": \"^1.70.0\",\r\n        \"sass-embedded\": \"^1.70.0\",\r\n        \"stylus\": \">=0.54.8\",\r\n        \"sugarss\": \"^5.0.0\",\r\n        \"terser\": \"^5.16.0\",\r\n        \"tsx\": \"^4.8.1\",\r\n        \"yaml\": \"^2.4.2\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/node\": {\r\n          \"optional\": true\r\n        },\r\n        \"@vitejs/devtools\": {\r\n          \"optional\": true\r\n        },\r\n        \"esbuild\": {\r\n          \"optional\": true\r\n        },\r\n        \"jiti\": {\r\n          \"optional\": true\r\n        },\r\n        \"less\": {\r\n          \"optional\": true\r\n        },\r\n        \"sass\": {\r\n          \"optional\": true\r\n        },\r\n        \"sass-embedded\": {\r\n          \"optional\": true\r\n        },\r\n        \"stylus\": {\r\n          \"optional\": true\r\n        },\r\n        \"sugarss\": {\r\n          \"optional\": true\r\n        },\r\n        \"terser\": {\r\n          \"optional\": true\r\n        },\r\n        \"tsx\": {\r\n          \"optional\": true\r\n        },\r\n        \"yaml\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/vite-plugin-commonjs\": {\r\n      \"version\": \"0.10.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/vite-plugin-commonjs/-/vite-plugin-commonjs-0.10.4.tgz\",\r\n      \"integrity\": \"sha512-eWQuvQKCcx0QYB5e5xfxBNjQKyrjEWZIR9UOkOV6JAgxVhtbZvCOF+FNC2ZijBJ3U3Px04ZMMyyMyFBVWIJ5+g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"acorn\": \"^8.12.1\",\r\n        \"magic-string\": \"^0.30.11\",\r\n        \"vite-plugin-dynamic-import\": \"^1.6.0\"\r\n      }\r\n    },\r\n    \"node_modules/vite-plugin-dynamic-import\": {\r\n      \"version\": \"1.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/vite-plugin-dynamic-import/-/vite-plugin-dynamic-import-1.6.0.tgz\",\r\n      \"integrity\": \"sha512-TM0sz70wfzTIo9YCxVFwS8OA9lNREsh+0vMHGSkWDTZ7bgd1Yjs5RV8EgB634l/91IsXJReg0xtmuQqP0mf+rg==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"acorn\": \"^8.12.1\",\r\n        \"es-module-lexer\": \"^1.5.4\",\r\n        \"fast-glob\": \"^3.3.2\",\r\n        \"magic-string\": \"^0.30.11\"\r\n      }\r\n    },\r\n    \"node_modules/vite-plugin-dynamic-import/node_modules/es-module-lexer\": {\r\n      \"version\": \"1.7.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz\",\r\n      \"integrity\": \"sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==\",\r\n      \"license\": \"MPL-2.0\",\r\n      \"dependencies\": {\r\n        \"detect-libc\": \"^2.0.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"lightningcss-android-arm64\": \"1.33.0\",\r\n        \"lightningcss-darwin-arm64\": \"1.33.0\",\r\n        \"lightningcss-darwin-x64\": \"1.33.0\",\r\n        \"lightningcss-freebsd-x64\": \"1.33.0\",\r\n        \"lightningcss-linux-arm-gnueabihf\": \"1.33.0\",\r\n        \"lightningcss-linux-arm64-gnu\": \"1.33.0\",\r\n        \"lightningcss-linux-arm64-musl\": \"1.33.0\",\r\n        \"lightningcss-linux-x64-gnu\": \"1.33.0\",\r\n        \"lightningcss-linux-x64-musl\": \"1.33.0\",\r\n        \"lightningcss-win32-arm64-msvc\": \"1.33.0\",\r\n        \"lightningcss-win32-x64-msvc\": \"1.33.0\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-android-arm64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-darwin-arm64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-darwin-x64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-freebsd-x64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-linux-arm64-gnu\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-linux-arm64-musl\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-linux-x64-gnu\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-linux-x64-musl\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-win32-arm64-msvc\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vite/node_modules/lightningcss-win32-x64-msvc\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/vitefu\": {\r\n      \"version\": \"1.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz\",\r\n      \"integrity\": \"sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==\",\r\n      \"devOptional\": true,\r\n      \"license\": \"MIT\",\r\n      \"workspaces\": [\r\n        \"tests/deps/*\",\r\n        \"tests/projects/*\",\r\n        \"tests/projects/workspace/packages/*\"\r\n      ],\r\n      \"peerDependencies\": {\r\n        \"vite\": \"^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"vite\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/watchpack\": {\r\n      \"version\": \"2.5.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz\",\r\n      \"integrity\": \"sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"graceful-fs\": \"^4.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10.13.0\"\r\n      }\r\n    },\r\n    \"node_modules/web-vitals\": {\r\n      \"version\": \"4.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/web-vitals/-/web-vitals-4.2.4.tgz\",\r\n      \"integrity\": \"sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==\",\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/webpack\": {\r\n      \"version\": \"5.110.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/webpack/-/webpack-5.110.3.tgz\",\r\n      \"integrity\": \"sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==\",\r\n      \"license\": \"MIT\",\r\n      \"peer\": true,\r\n      \"dependencies\": {\r\n        \"@types/estree\": \"^1.0.8\",\r\n        \"@types/json-schema\": \"^7.0.15\",\r\n        \"@webassemblyjs/ast\": \"^1.14.1\",\r\n        \"@webassemblyjs/wasm-edit\": \"^1.14.1\",\r\n        \"@webassemblyjs/wasm-parser\": \"^1.14.1\",\r\n        \"acorn\": \"^8.16.0\",\r\n        \"browserslist\": \"^4.28.1\",\r\n        \"chrome-trace-event\": \"^1.0.2\",\r\n        \"enhanced-resolve\": \"^5.24.4\",\r\n        \"es-module-lexer\": \"^2.1.0\",\r\n        \"events\": \"^3.2.0\",\r\n        \"graceful-fs\": \"^4.2.11\",\r\n        \"mime-db\": \"^1.54.0\",\r\n        \"minimizer-webpack-plugin\": \"^5.7.0\",\r\n        \"neo-async\": \"^2.6.2\",\r\n        \"schema-utils\": \"^4.3.3\",\r\n        \"tapable\": \"^2.3.0\",\r\n        \"watchpack\": \"^2.5.2\",\r\n        \"webpack-sources\": \"^3.5.1\"\r\n      },\r\n      \"bin\": {\r\n        \"webpack\": \"bin/webpack.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10.13.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/webpack\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"webpack-cli\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/webpack-sources\": {\r\n      \"version\": \"3.5.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz\",\r\n      \"integrity\": \"sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10.13.0\"\r\n      }\r\n    },\r\n    \"node_modules/which\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/which/-/which-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==\",\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"isexe\": \"^3.1.1\"\r\n      },\r\n      \"bin\": {\r\n        \"node-which\": \"bin/which.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^16.13.0 || >=18.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/workerd\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/workerd/-/workerd-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-MjKOJLcvU45xXedQowvuiHtJTxu4WTHYQeIlF7YmjuqhiI6dImTFxWCEoRQHiskztxuVSNEmdO7/0UfDu6OMnQ==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"bin\": {\r\n        \"workerd\": \"bin/workerd\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@cloudflare/workerd-darwin-64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-darwin-arm64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-linux-64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-linux-arm64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-windows-64\": \"1.20260515.1\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler\": {\r\n      \"version\": \"4.92.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/wrangler/-/wrangler-4.92.0.tgz\",\r\n      \"integrity\": \"sha512-/DKpQHPxkuZbQsO9dFW2700VTD/4DSZMHjy92fO/frNoDRi/zQsFCAd2ONCV6TGqcUoXcP3D8Bo2gj/L4M0qQQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"@cloudflare/kv-asset-handler\": \"0.5.0\",\r\n        \"@cloudflare/unenv-preset\": \"2.16.1\",\r\n        \"blake3-wasm\": \"2.1.5\",\r\n        \"esbuild\": \"0.27.3\",\r\n        \"miniflare\": \"4.20260515.0\",\r\n        \"path-to-regexp\": \"6.3.0\",\r\n        \"unenv\": \"2.0.0-rc.24\",\r\n        \"workerd\": \"1.20260515.1\"\r\n      },\r\n      \"bin\": {\r\n        \"wrangler\": \"bin/wrangler.js\",\r\n        \"wrangler2\": \"bin/wrangler.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"fsevents\": \"~2.3.2\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@cloudflare/workers-types\": \"^4.20260515.1\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@cloudflare/workers-types\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/path-to-regexp\": {\r\n      \"version\": \"6.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz\",\r\n      \"integrity\": \"sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/wrappy\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/ws\": {\r\n      \"version\": \"8.18.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ws/-/ws-8.18.0.tgz\",\r\n      \"integrity\": \"sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"bufferutil\": \"^4.0.1\",\r\n        \"utf-8-validate\": \">=5.0.2\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"bufferutil\": {\r\n          \"optional\": true\r\n        },\r\n        \"utf-8-validate\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/wsl-utils\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/wsl-utils/-/wsl-utils-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-Hl0ZOAs672vg+06kfujwRhoS6/jehvULrlFkuF2dRu6pHgA8U06h3xqNIqNNU1LTXPcedxByAR4GS6pwQK0mgA==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"is-wsl\": \"^3.1.0\",\r\n        \"powershell-utils\": \"^0.1.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/wsl-utils/node_modules/powershell-utils\": {\r\n      \"version\": \"0.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz\",\r\n      \"integrity\": \"sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/yallist\": {\r\n      \"version\": \"3.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz\",\r\n      \"integrity\": \"sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==\",\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/yocto-spinner\": {\r\n      \"version\": \"1.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/yocto-spinner/-/yocto-spinner-1.2.2.tgz\",\r\n      \"integrity\": \"sha512-DODGl1wJjA/s5pnJFKau9lIYHT81lnhob1i3e1TjxZRxEhWRKl74nTbWE6H5KlkViQQTo/Z29YFdxzTZAMY3ng==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"yoctocolors\": \"^2.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18.19\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/yoctocolors\": {\r\n      \"version\": \"2.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.2.0.tgz\",\r\n      \"integrity\": \"sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/yoga-layout\": {\r\n      \"version\": \"3.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/yoga-layout/-/yoga-layout-3.2.1.tgz\",\r\n      \"integrity\": \"sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/youch\": {\r\n      \"version\": \"4.1.0-beta.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz\",\r\n      \"integrity\": \"sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/colors\": \"^4.1.5\",\r\n        \"@poppinss/dumper\": \"^0.6.4\",\r\n        \"@speed-highlight/core\": \"^1.2.7\",\r\n        \"cookie\": \"^1.0.2\",\r\n        \"youch-core\": \"^0.3.3\"\r\n      }\r\n    },\r\n    \"node_modules/youch-core\": {\r\n      \"version\": \"0.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz\",\r\n      \"integrity\": \"sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/exception\": \"^1.2.2\",\r\n        \"error-stack-parser-es\": \"^1.0.5\"\r\n      }\r\n    },\r\n    \"node_modules/youch/node_modules/cookie\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/zod\": {\r\n      \"version\": \"3.25.76\",\r\n      \"resolved\": \"https://registry.npmjs.org/zod/-/zod-3.25.76.tgz\",\r\n      \"integrity\": \"sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/colinhacks\"\r\n      }\r\n    },\r\n    \"node_modules/zod-to-json-schema\": {\r\n      \"version\": \"3.25.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.2.tgz\",\r\n      \"integrity\": \"sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==\",\r\n      \"license\": \"ISC\",\r\n      \"peerDependencies\": {\r\n        \"zod\": \"^3.25.28 || ^4\"\r\n      }\r\n    }\r\n  }\r\n}\r\n","handborne/source/package.json":"{\r\n  \"name\": \"sites-project\",\r\n  \"version\": \"0.1.0\",\r\n  \"private\": true,\r\n  \"engines\": {\r\n    \"node\": \">=22.13.0\"\r\n  },\r\n  \"scripts\": {\r\n    \"predev\": \"node scripts/build-downloads.mjs\",\r\n    \"dev\": \"vinext dev\",\r\n    \"build\": \"node scripts/build.mjs\",\r\n    \"start\": \"node scripts/serve.mjs\",\r\n    \"lint\": \"oxlint\",\r\n    \"format\": \"oxfmt\"\r\n  },\r\n  \"dependencies\": {\r\n    \"@base-ui/react\": \"1.7.0\",\r\n    \"@shadcn/react\": \"0.3.0\",\r\n    \"class-variance-authority\": \"0.7.1\",\r\n    \"clsx\": \"2.1.1\",\r\n    \"cmdk\": \"1.1.1\",\r\n    \"date-fns\": \"4.1.0\",\r\n    \"embla-carousel-react\": \"8.5.2\",\r\n    \"input-otp\": \"1.4.2\",\r\n    \"lucide-react\": \"1.31.0\",\r\n    \"react\": \"19.2.6\",\r\n    \"react-day-picker\": \"9.8.1\",\r\n    \"react-dom\": \"19.2.6\",\r\n    \"react-resizable-panels\": \"4.5.8\",\r\n    \"react-server-dom-webpack\": \"19.2.6\",\r\n    \"recharts\": \"3.8.0\",\r\n    \"shadcn\": \"4.18.0\",\r\n    \"tailwind-merge\": \"3.6.0\",\r\n    \"three\": \"^0.180.0\",\r\n    \"tw-animate-css\": \"1.4.0\",\r\n    \"vinext\": \"1.0.0-beta.5\"\r\n  },\r\n  \"devDependencies\": {\r\n    \"@cloudflare/vite-plugin\": \"1.37.1\",\r\n    \"@cloudflare/workers-types\": \"4.20260515.1\",\r\n    \"@openai/sites-vite-plugin\": \"0.2.0\",\r\n    \"@tailwindcss/postcss\": \"4.2.1\",\r\n    \"@types/node\": \"22.19.19\",\r\n    \"@types/react\": \"19.2.14\",\r\n    \"@types/react-dom\": \"19.2.3\",\r\n    \"@types/three\": \"^0.180.0\",\r\n    \"@vitejs/plugin-react\": \"6.0.2\",\r\n    \"@vitejs/plugin-rsc\": \"0.5.26\",\r\n    \"oxfmt\": \"0.61.0\",\r\n    \"oxlint\": \"1.76.0\",\r\n    \"oxlint-tsgolint\": \"7.0.2001\",\r\n    \"tailwindcss\": \"4.2.1\",\r\n    \"typescript\": \"5.9.3\",\r\n    \"vite\": \"8.0.13\",\r\n    \"wrangler\": \"4.92.0\"\r\n  },\r\n  \"type\": \"module\"\r\n}\r\n","handborne/source/scripts/build-embedded.mjs":"import {build} from 'vite';\r\nimport tailwindcss from '@tailwindcss/postcss';\r\nimport react from '@vitejs/plugin-react';\r\nimport {rename,readFile,writeFile,cp,mkdir,readdir} from 'node:fs/promises';\r\nimport {fileURLToPath} from 'node:url';\r\nawait build({configFile:false,base:'/handborne/',resolve:{alias:{'@':fileURLToPath(new URL('../',import.meta.url))}},css:{postcss:{plugins:[tailwindcss()]}},plugins:[react()],build:{copyPublicDir:false,outDir:'dist/embedded',rollupOptions:{input:'hand-entry.html'}}});\r\nawait rename('dist/embedded/hand-entry.html','dist/embedded/index.html');\r\nconst {build:bundle}=await import('esbuild');\r\nawait bundle({entryPoints:['app/companion.ts'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'dist/embedded/companion.mjs'});\r\nawait bundle({entryPoints:['app/unlock-bridge.ts'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'dist/embedded/unlock-bridge.mjs'});\r\n// Assets are already published beside the recovered authoring source.\r\nfor(const dir of ['fonts','previews'])await cp('../'+dir,'dist/embedded/'+dir,{recursive:true});\r\nawait mkdir('dist/embedded/models',{recursive:true});\r\nfor(const name of await readdir('../models'))if(/^family-\\d+\\.glb$/.test(name))await cp('../models/'+name,'dist/embedded/models/'+name);\r\nconsole.log('Hand editor and companion ready.');\r\n","handborne/source/tsconfig.json":"{\r\n  \"compilerOptions\": {\r\n    \"target\": \"ES2017\",\r\n    \"lib\": [\"dom\", \"dom.iterable\", \"esnext\"],\r\n    \"allowJs\": true,\r\n    \"allowImportingTsExtensions\": true,\r\n    \"skipLibCheck\": true,\r\n    \"strict\": true,\r\n    \"noEmit\": true,\r\n    \"esModuleInterop\": true,\r\n    \"module\": \"esnext\",\r\n    \"moduleResolution\": \"bundler\",\r\n    \"types\": [\"node\", \"@cloudflare/workers-types\", \"vinext/types\"],\r\n    \"resolveJsonModule\": true,\r\n    \"isolatedModules\": true,\r\n    \"jsx\": \"react-jsx\",\r\n    \"incremental\": true,\r\n    \"paths\": {\r\n      \"@/*\": [\"./*\"]\r\n    }\r\n  },\r\n  \"include\": [\r\n    \"next-env.d.ts\",\r\n    \"**/*.ts\",\r\n    \"**/*.tsx\",\r\n    \".next/types/**/*.ts\",\r\n    \".next/dev/types/**/*.ts\",\r\n    \"**/*.mts\"\r\n  ],\r\n  \"exclude\": [\"node_modules\"]\r\n}\r\n","handborne/unlock-bridge.mjs":"var g=\"myr5-auth-transition-v1\",ye=\"myr5-login-provider\",E=e=>typeof e==\"string\"&&/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(e),_=class extends Error{constructor(r=\"auth_transition\"){super(r===\"auth_unavailable\"?\"Account synchronization is unavailable. Reload to retry.\":\"Account changed. Refresh to continue.\"),this.name=\"AuthTransitionError\",this.code=r}};function ke({storage:e,events:r,channelFactory:a,randomUUID:o}){let t,i=0,l=0,u=new AbortController,d,s,c=!1,m,k=new Set,O=()=>{for(let n of k)try{n()}catch{}},R=()=>{i++,l++,u.abort(),d?.abort(),u=new AbortController,O()},b=()=>{throw c||(c=!0,R()),new _(\"auth_unavailable\")},ge=()=>{try{let n=e.getItem(g);return E(n)?n:b()}catch{return b()}},C=()=>{if(c)throw new _(\"auth_unavailable\");let n=ge();return n!==t&&(t=n,R()),n},D=()=>{if(c)throw new _(\"auth_unavailable\");R();try{let n=o();return!E(n)||(e.setItem(g,n),e.getItem(g)!==n)?b():(t=n,s.postMessage({type:\"transition\",token:n}),n)}catch{return b()}},X=n=>{try{n.key===g||n.key===null?C():n.key===ye&&D()}catch{}},fe=()=>{try{C()}catch{}};try{if(!e||!r?.addEventListener||typeof a!=\"function\"||typeof o!=\"function\")throw Error();if(t=e.getItem(g),t===null){if(t=o(),!E(t))throw Error();e.setItem(g,t),t=e.getItem(g)}if(!E(t)||(s=a(\"myr5-auth-transition-v1\"),!s?.addEventListener||!s?.postMessage))throw Error();s.addEventListener(\"message\",fe),s.addEventListener(\"messageerror\",()=>{try{b()}catch{}}),r.addEventListener(\"storage\",X)}catch{c=!0,u.abort()}let $=()=>{let n=C();return Object.freeze({token:n,revision:i,signal:u.signal})},J=n=>{try{return!!n&&C()===n.token&&n.revision===i&&!n.signal.aborted&&(n.refreshGeneration===void 0||n.refreshGeneration===l)}catch{return!1}};return Object.freeze({capture:$,isCurrent:J,invalidate:D,assertCurrent(n){if(!J(n))throw new _(c?\"auth_unavailable\":\"auth_transition\")},beginRefresh(){let n=$();return d?.abort(),d=new AbortController,Object.freeze({...n,refreshGeneration:++l,signal:d.signal})},observeIdentity(n,be,_e){let x=JSON.stringify([n,be??null,_e??null]);if(m===void 0){m=x;return}m!==x&&(m=x,D())},subscribe(n){return k.add(n),()=>k.delete(n)},close(){c||(c=!0,R()),r?.removeEventListener?.(\"storage\",X),s?.close?.()}})}var B;function F(){if(!B){let e;try{e=globalThis.localStorage}catch{}B=ke({storage:e,events:globalThis.window,channelFactory:typeof globalThis.BroadcastChannel==\"function\"?r=>new BroadcastChannel(r):void 0,randomUUID:()=>globalThis.crypto.randomUUID()})}return B}var w,A=0,p=null,f=0,v=null,Y=!1;function Q({force:e=!1}={}){e&&(A++,w=null);let r=A;return w??=(async()=>{let a=await fetch(`/api/auth/config?t=${Date.now()}`,{credentials:\"same-origin\",cache:\"no-store\",signal:AbortSignal.timeout(5e3)});if(!a.ok)throw Object.assign(Error(\"Login could not connect. Please retry.\"),{status:a.status,code:\"auth-config\"});return a.json()})().then(a=>(A===r&&(a.enabled?w=a:w=null),a)).catch(a=>{throw A===r&&(w=null),a})}function V(e,r){return new Promise((a,o)=>{let t=document.createElement(\"script\");t.src=e,t.crossOrigin=\"anonymous\",r&&(t.dataset.clerkPublishableKey=r),t.onload=()=>{a()},t.onerror=()=>o(Error(\"Login could not load. Check your connection and retry.\")),document.head.append(t)})}function I(){if(p)return p;let e=++f,r=null,a=()=>{r&&(clearTimeout(r),r=null)},o=new Promise((t,i)=>{let l=Object.assign(new Error(\"Account timed out\"),{code:\"account_timeout\"}),u=(async()=>{try{let d;try{if(d=await Q(),f!==e)throw l}catch(O){throw a(),O}if(!d.enabled)return a(),null;let s=new URL(d.frontend).origin;if(await V(s+\"/npm/@clerk/ui@1/dist/ui.browser.js\"),f!==e||(await V(s+\"/npm/@clerk/clerk-js@6/dist/clerk.browser.js\",d.publishableKey),f!==e))throw l;let c=window.Clerk;if(await c.load({ui:{ClerkUI:window.__internal_ClerkUICtor}}),f!==e)throw l;let m=c;F().observeIdentity(\"clerk\",m.session?.id,m.user?.id),v&&(v(),v=null);let k=()=>{f===e&&F().observeIdentity(\"clerk\",m.session?.id,m.user?.id)};v=m.addListener(k),Y||(window.dispatchEvent(new Event(\"myr5:login-ready\")),Y=!0),t(m)}catch(d){a(),i(d)}})();r=setTimeout(()=>{p===o&&(f++,a(),i(l))},2e4),u.then(t,i).finally(a)});return p=o,p.then(t=>{a(),t===null&&p===o&&(p=null)},()=>{a(),p===o&&(p=null)}),o}function P(e,r,a=5e3){return new Promise((o,t)=>{let i=!1,l=(s,c)=>{i||(i=!0,clearTimeout(d),r.removeEventListener(\"abort\",u),s(c))},u=()=>l(t,Object.assign(Error(\"Account changed. Refresh to continue.\"),{code:\"auth_transition\"})),d=setTimeout(()=>l(t,Object.assign(Error(\"Account service timed out. Please retry.\"),{status:503,code:\"account_timeout\"})),a);r.addEventListener(\"abort\",u,{once:!0}),r.aborted&&u(),Promise.resolve(e).then(s=>l(o,s),s=>l(t,s))})}async function Z(e,r={}){let a=F(),o=a.capture(),t=new Headers(r.headers),i=await P(Q(),o.signal);a.assertCurrent(o);let l=localStorage.getItem(\"myr5-login-provider\");if(r.guestSkip&&l!==\"clerk\")return new Response(JSON.stringify({error:\"Sign in to save your progress.\"}),{status:401,headers:{\"Content-Type\":\"application/json\"}});if(i.enabled&&l===\"clerk\"){let s=await P(I(),o.signal,2e4);a.assertCurrent(o),a.observeIdentity(\"clerk\",s?.session?.id,s?.user?.id),a.assertCurrent(o);let c=await P(s?.session?.getToken(),o.signal);if(a.observeIdentity(\"clerk\",s?.session?.id,s?.user?.id),a.assertCurrent(o),!c)throw Object.assign(Error(\"Sign in to Coach again.\"),{status:401});t.set(\"Authorization\",\"Bearer \"+c)}a.assertCurrent(o);let u=AbortSignal.any([o.signal,...r.signal?[r.signal]:[],AbortSignal.timeout(8e3)]),d=await fetch(e,{...r,signal:u,headers:t,credentials:\"same-origin\",cache:\"no-store\"});return a.assertCurrent(o),d}var we=[{id:\"chest\",name:\"Chest\",description:\"Push-up progressions\"},{id:\"legs\",name:\"Legs\",description:\"Squats and split squats\"},{id:\"hips\",name:\"Hips & glutes\",description:\"Hinges and bridges\"},{id:\"core\",name:\"Core\",description:\"Plank holds\"},{id:\"shoulders\",name:\"Shoulders\",description:\"Controlled arm movement\"},{id:\"balance\",name:\"Balance\",description:\"Single-leg yoga holds\"},{id:\"yoga\",name:\"Yoga\",description:\"Standing poses\"},{id:\"stances\",name:\"Martial stances\",description:\"Controlled stance holds\"},{id:\"boxing\",name:\"Boxing\",description:\"Slow shadowboxing\"},{id:\"cardio\",name:\"Cardio\",description:\"Marches and jacks\"}],S=[];function h(e,r,a,o,t={}){let i=t.kind??([\"plank\",\"sideplank\",\"balance\",\"yoga\",\"stance\"].includes(o)?\"hold\":o===\"boxing\"?\"pace\":o===\"march\"?\"steps\":\"reps\"),l=t.view??([\"pushup\",\"hinge\",\"bridge\",\"plank\",\"split\"].includes(o)?\"side\":\"front\"),u=i===\"hold\"?\"Pose hold\":i===\"pace\"?\"Active hand time\":i===\"steps\"?\"Knee lifts\":\"Repetitions\",d=t.limits??\"Counts the visible movement; does not grade technique.\",s=l===\"side\"?\"Camera beside you.\":l===\"angle\"?\"Camera at a slight angle.\":\"Face the camera.\";S.push({id:r,group:e,name:a,detector:o,kind:i,view:l,measurement:u,limits:d,difficulty:S.filter(c=>c.group===e).length+1,defaultGoal:i===\"hold\"||i===\"pace\"?15:5,evidence:\"rule-based; camera validation pending\",source:\"mediapipe\",...t,hint:`${s} ${t.cue??\"Keep the joints used for this movement visible.\"}`})}var Se=\"Counts elbow bend and return. Hand shape, support stability and chest depth are not verified.\";for(let[e,r,a]of[[\"knee-pushup\",\"Knee push-up\",{support:\"knees\",cue:\"Knees down; show shoulder, elbow, wrist and hip.\"}],[\"high-incline-pushup\",\"High incline push-up\",{incline:!0,cue:\"Hands on a stable high surface; show your full arm and torso.\"}],[\"low-incline-pushup\",\"Low incline push-up\",{incline:!0,cue:\"Hands on a stable lower surface; show your full arm and torso.\"}],[\"pushup\",\"Regular push-up\",{}],[\"wide-pushup\",\"Wide push-up\",{wide:!0}],[\"slow-pushup\",\"Slow push-up\",{minCycle:1.2}],[\"diamond-pushup\",\"Diamond push-up\",{narrow:!0}],[\"decline-pushup\",\"Feet-elevated push-up\",{decline:!0,cue:\"Feet on a stable low surface; show your full arm and torso.\"}]])h(\"chest\",e,r,\"pushup\",{cue:\"Show shoulder, elbow, wrist and hip. Start with your arm extended.\",limits:Se,...a});for(let[e,r,a]of[[\"shallow-squat\",\"Shallow squat\",{travel:.18}],[\"squat\",\"Bodyweight squat\",{}],[\"wide-squat\",\"Wide squat\",{wide:!0}],[\"pause-squat\",\"Pause squat\",{dwell:.8}],[\"slow-squat\",\"Slow squat\",{minCycle:1.2}],[\"split-left\",\"Split squat \\xB7 left\",{detector:\"split\",side:\"left\"}],[\"split-right\",\"Split squat \\xB7 right\",{detector:\"split\",side:\"right\"}],[\"wall-sit\",\"Wall sit\",{detector:\"yoga\",pose:\"wall-sit\",kind:\"hold\",view:\"side\",cue:\"Back on a wall, thighs level. Show shoulder, hip and knee.\",limits:\"Times the hip angle and thigh level. Wall contact and knee position are not tracked.\"}]])h(\"legs\",e,r,a.detector??\"squat\",{cue:a.side?\"Show the front leg from hip to knee. Start tall.\":\"Show shoulders and hips. Start standing tall.\",...a});for(let[e,r,a,o]of[[\"small-hinge\",\"Small hip hinge\",\"hinge\",{bend:25}],[\"hip-hinge\",\"Hip hinge\",\"hinge\",{}],[\"good-morning\",\"Bodyweight good morning\",\"hinge\",{arms:\"chest\"}],[\"glute-bridge\",\"Glute bridge\",\"bridge\",{}],[\"pause-bridge\",\"Pause glute bridge\",\"bridge\",{dwell:.8}]])h(\"hips\",e,r,a,{cue:a===\"bridge\"?\"Lie on your back, knees bent. Show shoulder, hip and knee. Start with hips down.\":\"Show shoulder, hip and knee. Start upright; hinge slowly.\",limits:\"Tracks hip movement. Back curvature and muscle engagement are not verified.\",...o});for(let[e,r,a]of[[\"knee-plank\",\"Knee plank\",{support:\"knees\"}],[\"high-plank\",\"High plank\",{}],[\"forearm-plank\",\"Forearm plank\",{forearm:!0}],[\"side-knee-left\",\"Side knee plank \\xB7 left\",{side:\"left\",support:\"knees\"}],[\"side-knee-right\",\"Side knee plank \\xB7 right\",{side:\"right\",support:\"knees\"}],[\"side-plank-left\",\"Side plank \\xB7 left\",{side:\"left\"}],[\"side-plank-right\",\"Side plank \\xB7 right\",{side:\"right\"}]])h(\"core\",e,r,a.side?\"sideplank\":\"plank\",{view:a.side?\"front\":\"side\",cue:a.side?\"Show both shoulders, hips and the supporting knee. Stack your shoulders.\":\"Show shoulder, elbow, wrist, hip and supporting knee.\",limits:\"Times the shoulder\\u2013hip\\u2013knee line. Feet, floor contact and loading are not tracked.\",...a});for(let[e,r,a,o]of[[\"front-raise\",\"Front arm raise\",\"raise\",{view:\"side\",plane:\"front\"}],[\"lateral-raise\",\"Lateral arm raise\",\"raise\",{}],[\"overhead-reach\",\"Overhead reach\",\"raise\",{overhead:!0}],[\"standing-press\",\"Standing arm press\",\"press\",{}],[\"slow-press\",\"Slow arm press\",\"press\",{minCycle:1.2}]])h(\"shoulders\",e,r,a,{cue:\"Keep both shoulders, elbows, wrists and hips visible. Use controlled, unloaded movement.\",...o});for(let[e,r,a]of[[\"knee-balance\",\"Knee-lift balance\",{kneeLift:!0}],[\"low-tree\",\"Low tree pose\",{low:!0}],[\"tree\",\"Tree pose\",{}],[\"overhead-tree\",\"Tree \\xB7 arms overhead\",{overhead:!0}]])h(\"balance\",e,r,\"balance\",{cue:\"Show both hips and knees. Either leg works; keep a support nearby if needed.\",limits:\"Times the visible leg shape. Balance, foot pressure and support use are not verified.\",...a});for(let[e,r,a]of[[\"mountain\",\"Mountain\",\"mountain\"],[\"salute\",\"Upward salute\",\"salute\"],[\"chair\",\"Chair pose\",\"chair\"],[\"warrior-one\",\"Warrior I\",\"warrior-one\"],[\"warrior\",\"Warrior II\",\"warrior\"],[\"goddess\",\"Goddess pose\",\"goddess\"]])h(\"yoga\",e,r,\"yoga\",{pose:a,view:[\"chair\",\"warrior-one\"].includes(a)?\"side\":\"front\",cue:\"Show arms, hips and knees. Hold only a comfortable position.\",limits:\"Times broad pose shape. Foot rotation and joint alignment are not graded.\"});for(let[e,r,a]of[[\"high-horse\",\"High horse stance\",{high:!0}],[\"horse\",\"Horse stance\",{}],[\"low-horse\",\"Lower horse stance\",{low:!0}],[\"front-stance-left\",\"Front stance \\xB7 left\",{side:\"left\"}],[\"front-stance-right\",\"Front stance \\xB7 right\",{side:\"right\"}]])h(\"stances\",e,r,\"stance\",{view:a.side?\"side\":\"front\",cue:\"Keep hips and knees visible. Move slowly into a comfortable stance.\",limits:\"Times stance shape only. This is not martial-arts technique instruction.\",...a});for(let[e,r,a]of[[\"jab-left\",\"Left straight practice\",{side:\"left\"}],[\"jab-right\",\"Right straight practice\",{side:\"right\"}],[\"boxing\",\"Alternating straights\",{}],[\"double-jab\",\"Double-jab practice\",{double:!0}]])h(\"boxing\",e,r,\"boxing\",{view:\"angle\",cue:\"Show shoulders, elbows, wrists and hips. Practice slow, controlled punches into empty space.\",limits:\"Tracks active hand time and relative pace. Punch type, power, accuracy and guard are not verified.\",...a});for(let[e,r,a,o]of[[\"march\",\"Easy march\",\"march\",{}],[\"high-march\",\"High-knee march\",\"march\",{lift:.4}],[\"jogging\",\"Cool Cardio\",\"march\",{lift:.08,runner:!0,endless:!0,cue:\"Treadmill or in place: show your head, shoulders and arms. Run to move, both arms up to jump, crouch to slide, lean to switch lanes. Stop for 10 seconds and Coach catches you.\"}],[\"step-jack\",\"Step jack\",\"jack\",{step:!0}],[\"jumping-jack\",\"Jumping jack\",\"jack\",{}]])h(\"cardio\",e,r,a,{cue:a===\"jack\"?\"Show your upper body and knees. Start with arms down and knees close together.\":\"Show shoulders, hips and both knees. Start standing tall.\",limits:a===\"jack\"?\"Counts arm-and-knee opening cycles. Feet, airtime and landings are not tracked.\":\"Counts knee lifts. Footfalls and impact are not verified.\",...o});var ee=Object.freeze(Object.fromEntries(S.map(e=>[e.id,Object.freeze(e)]))),Re=Object.freeze(Object.fromEntries(we.map(e=>[e.id,Object.freeze(S.filter(r=>r.group===e.id))]))),or=S.length;var re=Object.freeze([\"roster/21-flyer--winged_humanoid_3d_model\",\"roster/18-quad-all--wooden_robot_3d_model\"]),Ce=[[\"myr5\",\"original\",[\"MYR5 Jacked LaLAN\",\"Jack LaLanne\",\"jacked strength\",\"local area network\"],[\"MYR5 AT-Lift Prime\",\"Charles Atlas\",\"lift\",\"model designation\"]],[\"02-taper-tallstalk--humanoid_robot_3d_model1\",\"arms\",[\"Arnoid Press\",\"Arnold Schwarzenegger\",\"Arnold press\",\"android\"],[\"ScotTorque Curl\",\"Larry Scott\",\"curl\",\"motor torque\"]],[\"19-genie-multi--multi-armed_humanoid_3d_model1\",\"arms\",[\"Ferri-Delt L0U\",\"Lou Ferrigno\",\"delt\",\"robot designation\"],[\"R0N Curlman\",\"Ronnie Coleman\",\"curl\",\"engine manifold\"]],[\"19-genie-multi--multi-armed_humanoid_3d_model\",\"arms\",[\"Frank Delt-Zan3\",\"Frank Zane\",\"delt\",\"magnetic coil\"],[\"Cutlerator Curl\",\"Jay Cutler\",\"curl\",\"accelerator\"]],[\"17-shellcap-manyarm--mushroom_creature_3d_model\",\"arms\",[\"KAI-nematic Raise\",\"Kai Greene\",\"raise\",\"kinematic mechanism\"],[\"Philament Heave Press\",\"Phil Heath\",\"press\",\"electrical filament\"]],[\"17-shellcap-manyarm--mushroom_robot_3d_model\",\"arms\",[\"Wheel-er Servo-Shrug\",\"Flex Wheeler\",\"shrug\",\"servo wheel\"]],[\"23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"arms\",[\"Ree-volts Raise\",\"Steve Reeves\",\"raise\",\"voltage\"]],[\"08-shard-asym--robot_3d_model4\",\"arms\",[\"S3RG Oliv-Armature\",\"Sergio Oliva\",\"arm\",\"motor armature\"]],[\"17-shellcap-manyarm--3d_character_figurine\",\"arms\",[\"Delt-alinn Bailey\",\"Dana Linn Bailey\",\"delt\",\"Delta designation\"]],[\"06-ridge-triad--geometric_robot_3d_model1\",\"chest\",[\"Oliva-C Pec\",\"Sergio Oliva\",\"pec\",\"vacuum drive\"]],[\"08-shard-asym--geometric_robot_3d_model\",\"chest\",[\"Pec-n0ld Reactor\",\"Arnold Schwarzenegger\",\"pec\",\"reactor\"]],[\"16-spade-arch--pyramid_head_figure_3d_model\",\"chest\",[\"Franx Pec-Zane\",\"Frank Zane\",\"pec\",\"motor drive\"],[\"Y4TES Yoke\",\"Dorian Yates\",\"press\",\"powered yoke\"]],[\"04-crest-wedge--robot_creature_3d_model\",\"chest\",[\"L0U Ferri-pecctor\",\"Lou Ferrigno\",\"pec\",\"reactor\"],[\"Wheeler Wheel-Bench\",\"Flex Wheeler\",\"bench\",\"drive wheel\"]],[\"16-spade-arch--stylized_humanoid_3d_model\",\"chest\",[\"Cutlerator Press\",\"Jay Cutler\",\"press\",\"accelerator\"]],[\"04-crest-wedge--stylized_3d_character\",\"chest\",[\"Gr33ne Grid-Press\",\"Kai Greene\",\"press\",\"power grid designation\"]],[\"09-monolith-tanka--3d_robot_model\",\"chest\",[\"chris BenchSTEAD\",\"Chris Bumstead\",\"bench\",\"robot\"]],[\"09-monolith-tanka--white_horned_robot_3d_model\",\"chest\",[\"Cavalier-EX Chest\",\"Jeff Cavaliere\",\"chest\",\"exercise model EX\"]],[\"15-orbital-coili--robot_character_3d_model\",\"quads\",[\"t-OHM Platzma\",\"Tom Platz\",\"squat\",\"plasma\"]],[\"13-fan-split--stylized_3d_character2\",\"quads\",[\"Quad-Cutler LEGS THO\",\"Jay Cutler\",\"quad\",\"circuit\"],[\"BumSTEADy Squat\",\"Chris Bumstead\",\"squat\",\"steady-state control\"]],[\"22-curve--stylized_cartoon_figure_3d_model\",\"quads\",[\"Kai Gr33ne Lunge\",\"Kai Greene\",\"lunge\",\"gear designation\"]],[\"02-taper-tallstalk--3d_humanoid_figure\",\"quads\",[\"Hane-Yoke Lunge\",\"Lee Haney\",\"lunge\",\"powered yoke\"],[\"Stern-on Squat\",\"Erin Stern\",\"squat\",\"power-on switch\"]],[\"02-taper-tallstalk--white_humanoid_doll_3d_model\",\"quads\",[\"Oli-Volt Lunge\",\"Sergio Oliva\",\"lunge\",\"voltage\"],[\"Y4TES Yoke-Squat\",\"Dorian Yates\",\"squat\",\"robot designation\"]],[\"18-quad-all--wooden_four-legged_robot_3d_model\",\"quads\",[\"Priest-L33 Squat\",\"Lee Priest\",\"squat\",\"piston\"]],[\"18-quad-all--stylized_quadruped_3d_model\",\"quads\",[\"Quadzilla Platz\",\"Tom Platz\",\"quads\",\"kaiju creature\"],[\"SternShift Squat\",\"Erin Stern\",\"squat\",\"gear shift\"]],[\"23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"glutes\",[\"Con-Thrust-Era\",\"Bret Contreras\",\"hip thrust\",\"thruster\"]],[\"23-blob-texture-bodies--sand_creature_3d_model\",\"glutes\",[\"Tingularity Thrust\",\"Chloe Ting\",\"hip thrust\",\"singularity\"]],[\"03-pearl-orb-ring--stylized_3d_character1\",\"glutes\",[\"Gyrvanium Glute-Drive\",\"Caroline Girvan\",\"glute\",\"futuristic alloy\"],[\"Jill-iON Hinge-Flex\",\"Jillian Michaels\",\"hip hinge\",\"ion drive\"]],[\"03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"glutes\",[\"Trac-ION Hip-Thrust\",\"Tracy Anderson\",\"hip thrust\",\"ion drive\"],[\"Simmonics Bridge-Servo\",\"Whitney Simmons\",\"bridge\",\"electronics servo\"]],[\"03-pearl-orb-ring--abstract_humanoid_3d_model\",\"glutes\",[\"Robo-ertson Bridge\",\"Heather Robertson\",\"bridge\",\"robot\"],[\"Hearn-ess ExoHinge\",\"Katy Hearn\",\"hinge\",\"exosuit harness\"]],[\"03-pearl-orb-ring--circle_center\",\"glutes\",[\"Con-Terra Coil-Bridge\",\"Bret Contreras\",\"bridge\",\"planetary coil\"],[\"Cyb-Ho Holo-Bridge\",\"Cassey Ho\",\"bridge\",\"cyborg hologram\"]],[\"23-blob-texture-bodies--cute_blob_creature_3d_model\",\"glutes\",[\"Chlo-Turbo Thrust\",\"Chloe Ting\",\"thrust\",\"turbine\"]],[\"10-petal-wisp--fantasy_creature_3d_model4\",\"yoga\",[\"Adriene A-Sana Mk II\",\"Adriene Mishler\",\"asana\",\"model revision\"]],[\"19-genie-multi--fantasy_creature_3d_model\",\"yoga\",[\"Mat-Gregor Matrix\",\"Kino MacGregor\",\"mat\",\"simulation matrix\"]],[\"10-petal-wisp--ghost_character_3d_model\",\"yoga\",[\"Warri0r-ner Drive\",\"Dylan Werner\",\"warrior pose\",\"motor designation\"],[\"Kathryn Bend-1g\",\"Kathryn Budig\",\"bend\",\"robot\"]],[\"08-shard-asym--stylized_action_figure_3d_model\",\"yoga\",[\"Yee-lastic Flow\",\"Rodney Yee\",\"yoga flow\",\"elastic mechanics\"]],[\"22-curve--stylized_alien_3d_model\",\"yoga\",[\"Strom Flex Current\",\"Max Strom\",\"stretch\",\"electric current\"]],[\"10-petal-wisp--stylized_creature_3d_model\",\"yoga\",[\"Iyeng-Arc Inversion\",\"B. K. S. Iyengar\",\"inversion\",\"powered arc\"]],[\"19-genie-multi--stylized_octopus_3d_model\",\"yoga\",[\"Yee Gyro-Yogi\",\"Rodney Yee\",\"yoga\",\"gyroscope\"]],[\"01-seed-pearo--cute_alien_figure_3d_model\",\"yoga\",[\"Wern-Axis Flow\",\"Dylan Werner\",\"flow\",\"robotic axis\"],[\"Mat-Gregor Drive\",\"Kino MacGregor\",\"mat practice\",\"motor drive\"]],[\"01-seed-pearo--white_3d_character_model\",\"yoga\",[\"Budig-ital Balance\",\"Kathryn Budig\",\"balance\",\"digital\"],[\"Corn Kernel Cobra\",\"Seane Corn\",\"cobra pose\",\"computing kernel\"]],[\"09-monolith-tanka--boxy_humanoid_3d_model\",\"martial-arts\",[\"Bruce L3300\",\"Bruce Lee\",\"kick\",\"alphanumeric call sign\"],[\"GSP-Drive\",\"Georges St-Pierre\",\"spar\",\"motor drive\"]],[\"11-anvil-cask--clay-style_robot_3d_model\",\"martial-arts\",[\"Anderson Sil-VOLT\",\"Anderson Silva\",\"strike\",\"voltage\"],[\"r0nda Rous-Bot\",\"Ronda Rousey\",\"armbar\",\"robot\"]],[\"05-slope-bobble--clay_humanoid_figure_3d_model\",\"martial-arts\",[\"C0N0R McG-Gear\",\"Conor McGregor\",\"kick\",\"gear transmission\"],[\"Nor-Rotor Punch\",\"Chuck Norris\",\"punch\",\"rotor\"]],[\"14-chisel-spire--cone_head_3d_model\",\"martial-arts\",[\"LiDAR Jett-Jab\",\"Jet Li\",\"jab\",\"laser ranging\"],[\"Jaa-Bot Jab\",\"Tony Jaa\",\"jab\",\"robot\"]],[\"08-shard-asym--fantasy_creature_3d_model2\",\"martial-arts\",[\"Waters0nic\",\"Michelle Waterson\",\"kick\",\"sonic drive\"],[\"Amanda Nu-NEURAL\",\"Amanda Nunes\",\"strike\",\"neural implant\"]],[\"09-monolith-tanka--mini_robot_3d_model\",\"martial-arts\",[\"Machi-Droid-a\",\"Lyoto Machida\",\"chop\",\"android\"],[\"Bas Rut-TORque\",\"Bas Rutten\",\"kick\",\"motor torque\"]],[\"09-monolith-tanka--robot_3d_model3\",\"martial-arts\",[\"Israel Ade-SYNC-ya\",\"Israel Adesanya\",\"strike\",\"synchronization\"],[\"Shev-Servo Sweep\",\"Valentina Shevchenko\",\"sweep\",\"servo\"]],[\"13-fan-split--stylized_toy_3d_model\",\"martial-arts\",[\"BlankSaber Kick\",\"Billy Blanks\",\"kick\",\"energy saber\"],[\"Wilsonic Kick\",\"Don Wilson\",\"kick\",\"sonic drive\"]],[\"09-monolith-tanka--robot_3d_model2\",\"martial-arts\",[\"Rous-Torque Throw\",\"Ronda Rousey\",\"throw\",\"motor torque\"],[\"Jackie Chain-Kick\",\"Jackie Chan\",\"kick\",\"chain drive\"]],[\"07-bulb-sphereling--humanoid_robot_3d_model\",\"cardio\",[\"B0LT Sprint-Drive\",\"Usain Bolt\",\"sprint\",\"electrical bolt drive\"]],[\"03-pearl-orb-ring--ringed_humanoid_3d_model\",\"cardio\",[\"Fon-Dynamo Footwork\",\"Jane Fonda\",\"footwork\",\"dynamo\"],[\"Simmonics Sweatstream\",\"Richard Simmons\",\"aerobic sweat\",\"electronics stream\"]],[\"06-ridge-triad--robot_3d_model1\",\"cardio\",[\"M0 Farah Fastlane\",\"Mo Farah\",\"fast run\",\"electric capacitance\"]],[\"03-pearl-orb-ring--robot_3d_model\",\"cardio\",[\"Feli-X Footdrive\",\"Allyson Felix\",\"footwork\",\"X-model drive\"],[\"Rad-Clutch Run\",\"Paula Radcliffe\",\"run\",\"motor clutch\"]],[\"20-lume--robotic_figure_3d_model\",\"cardio\",[\"Pre-Font-AI-ne Pace\",\"Steve Prefontaine\",\"pace\",\"AI running model\"],[\"Ohm-wens Run\",\"Jesse Owens\",\"run\",\"electrical resistance\"]],[\"07-bulb-sphereling--cute_robot_3d_model\",\"cardio\",[\"Billy Blanx Beam\",\"Billy Blanks\",\"boot camp\",\"waveform\"],[\"GebreShell Runloop\",\"Haile Gebrselassie\",\"run\",\"software shell loop\"]],[\"01-seed-pearo--blank_toy_figure_3d_model\",\"cardio\",[\"Phelpeller Pulse\",\"Michael Phelps\",\"cardio pulse\",\"propeller\"],[\"Fon-Droid Footwork\",\"Jane Fonda\",\"footwork\",\"android\"]],[\"18-quad-all--dragon_creature_3d_model\",\"meditation\",[\"H0F-Lung\",\"Wim Hof\",\"breathing\",\"oxygen-code lung\"]],[\"18-quad-all--fantasy_creature_3d_model1\",\"meditation\",[\"Max Ohm-Strom Breath\",\"Max Strom\",\"breathing\",\"electrical resistance\"],[\"Yee-uro Zen\",\"Rodney Yee\",\"mindful movement\",\"neural interface\"]],[\"18-quad-all--fantasy_creature_3d_model3\",\"meditation\",[\"Shiva Rea-spatory\",\"Shiva Rea\",\"respiration\",\"airlock\"]],[\"18-quad-all--four-legged_robot_3d_model\",\"meditation\",[\"Tara-5tile5-Standby\",\"Tara Stiles\",\"breathing\",\"computer standby\"]],[\"18-quad-all--quadruped_robot_3d_model1\",\"meditation\",[\"Werner Wind0wn\",\"Dylan Werner\",\"wind-down practice\",\"alphanumeric standby mode\"]],[\"18-quad-all--quadruped_robot_3d_model\",\"meditation\",[\"Yee Holo-Om\",\"Rodney Yee\",\"mindful movement\",\"hologram\"]],[\"18-quad-all--robotic_dog_3d_model\",\"meditation\",[\"Budig-ital Breath\",\"Kathryn Budig\",\"breathing\",\"digital\"]],[\"12-seedpod-snailslug--stylized_slug_3d_model\",\"meditation\",[\"H0F Hold-Circuit\",\"Wim Hof\",\"breath hold\",\"circuit and model code\"],[\"Ohm-Strom Still\",\"Max Strom\",\"stillness\",\"electrical resistance\"]],[\"12-seedpod-snailslug--stylized_worm_3d_model\",\"meditation\",[\"Pilat-OS Calm-Circuit\",\"Joseph Pilates\",\"mindful breathing\",\"operating system circuit\"]],[\"14-chisel-spire--low_poly_robot_3d_model\",\"meditation\",[\"Rea-Spire Relay\",\"Shiva Rea\",\"respiration\",\"air relay\"]],[\"01-seed-pearo--3d_character_model\",\"meditation\",[\"McKe-O2 Nose-Cone\",\"Patrick McKeown\",\"nasal breathing\",\"rocket nose cone\"],[\"Vertu-al Vent\",\"Shona Vertue\",\"ventilation\",\"virtual reality\"]],[\"23-blob-texture-bodies--blob_creature_3d_model\",\"meditation\",[\"Blob 1 \\xB7 H0F Hold-Drive\",\"Wim Hof\",\"breath hold\",\"air drive and model code\"]],[\"01-seed-pearo--blank_humanoid_figure_3d_model\",\"meditation\",[\"Corn Kernel Om\",\"Seane Corn\",\"meditation\",\"computing kernel\"],[\"Kino-Kinetic Breath\",\"Kino MacGregor\",\"breathing\",\"kinematics\"]]],ae=Object.freeze(Object.fromEntries(Ce.map(([e,r,...a])=>[e===\"myr5\"?e:`roster/${e}`,Object.freeze({track:r,names:Object.freeze(a.map(([o,t,i,l])=>Object.freeze({name:o,person:t,workout:i,scifi:l})))})])));var sr=Object.freeze(Object.fromEntries(Object.entries(ae).map(([e,r])=>[e,Object.freeze(r.names.map(a=>a.name))])));function Ee(e){let r=ae[e];if(!r)throw RangeError(`No coach name for ${e}.`);return r}var T=(e,r=!1)=>{let a=Ee(e).names;return a[r?1:0]?.name??a[0].name};var L=Object.freeze({sprintRounds:5,gentleActiveSeconds:300,paceActiveSeconds:300,meditationDays:Object.freeze([3,6,9,12])}),Fe=[{id:\"myr5\",sourceLabel:\"Original MYR5\"},{id:\"roster/01-seed-pearo--3d_character_model\",sourceLabel:\"Seed \\xB7 Pearo 1\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--cute_alien_figure_3d_model\",sourceLabel:\"Seed \\xB7 Pearo 2\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--blank_toy_figure_3d_model\",sourceLabel:\"Seed \\xB7 Pearo 5\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/02-taper-tallstalk--3d_humanoid_figure\",sourceLabel:\"Taper \\xB7 Tallstalk 1\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",sourceLabel:\"Taper \\xB7 Tallstalk 2\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",sourceLabel:\"Taper \\xB7 Tallstalk 3\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 1\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--circle_center\",sourceLabel:\"Pearl \\xB7 Orb 2\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 3\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--robot_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 4\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_3d_character1\",sourceLabel:\"Pearl \\xB7 Orb 5\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 6\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/04-crest-wedge--robot_creature_3d_model\",sourceLabel:\"Crest \\xB7 Wedge 1\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/04-crest-wedge--stylized_3d_character\",sourceLabel:\"Crest \\xB7 Wedge 2\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",sourceLabel:\"Slope \\xB7 Bobble 1\",group:\"Slope \\xB7 Bobble\"},{id:\"roster/06-ridge-triad--geometric_robot_3d_model1\",sourceLabel:\"Ridge \\xB7 Triad 1\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/06-ridge-triad--robot_3d_model1\",sourceLabel:\"Ridge \\xB7 Triad 2\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/07-bulb-sphereling--cute_robot_3d_model\",sourceLabel:\"Bulb \\xB7 Sphereling 1\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",sourceLabel:\"Bulb \\xB7 Sphereling 2\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/08-shard-asym--geometric_robot_3d_model\",sourceLabel:\"Shard \\xB7 Asym 1\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--robot_3d_model4\",sourceLabel:\"Shard \\xB7 Asym 2\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--fantasy_creature_3d_model2\",sourceLabel:\"Shard \\xB7 Asym 3\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--stylized_action_figure_3d_model\",sourceLabel:\"Shard \\xB7 Asym 4\",group:\"Shard \\xB7 Asym\"},{id:\"roster/09-monolith-tanka--3d_robot_model\",sourceLabel:\"Monolith \\xB7 Tanka 1\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 2\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--mini_robot_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 3\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--robot_3d_model3\",sourceLabel:\"Monolith \\xB7 Tanka 5\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--white_horned_robot_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 6\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/10-petal-wisp--stylized_creature_3d_model\",sourceLabel:\"Petal \\xB7 Wisp 1\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--ghost_character_3d_model\",sourceLabel:\"Petal \\xB7 Wisp 2\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--fantasy_creature_3d_model4\",sourceLabel:\"Petal \\xB7 Wisp 3\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/11-anvil-cask--clay-style_robot_3d_model\",sourceLabel:\"Anvil \\xB7 Cask 1\",group:\"Anvil \\xB7 Cask\"},{id:\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",sourceLabel:\"Seedpod \\xB7 Snailslug 1\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",sourceLabel:\"Seedpod \\xB7 Snailslug 2\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/13-fan-split--stylized_3d_character2\",sourceLabel:\"Fan \\xB7 Split 1\",group:\"Fan \\xB7 Split\"},{id:\"roster/13-fan-split--stylized_toy_3d_model\",sourceLabel:\"Fan \\xB7 Split 2\",group:\"Fan \\xB7 Split\"},{id:\"roster/14-chisel-spire--cone_head_3d_model\",sourceLabel:\"Chisel \\xB7 Spire 1\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/14-chisel-spire--low_poly_robot_3d_model\",sourceLabel:\"Chisel \\xB7 Spire 2\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/15-orbital-coili--robot_character_3d_model\",sourceLabel:\"Orbital \\xB7 Coili 1\",group:\"Orbital \\xB7 Coili\"},{id:\"roster/16-spade-arch--pyramid_head_figure_3d_model\",sourceLabel:\"Spade \\xB7 Arch 1\",group:\"Spade \\xB7 Arch\"},{id:\"roster/16-spade-arch--stylized_humanoid_3d_model\",sourceLabel:\"Spade \\xB7 Arch 2\",group:\"Spade \\xB7 Arch\"},{id:\"roster/17-shellcap-manyarm--3d_character_figurine\",sourceLabel:\"Shellcap \\xB7 Manyarm 1\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",sourceLabel:\"Shellcap \\xB7 Manyarm 2\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",sourceLabel:\"Shellcap \\xB7 Manyarm 3\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/18-quad-all--dragon_creature_3d_model\",sourceLabel:\"Four-legged 1\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model1\",sourceLabel:\"Four-legged 2\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model3\",sourceLabel:\"Four-legged 3\",group:\"Four-legged\"},{id:\"roster/18-quad-all--four-legged_robot_3d_model\",sourceLabel:\"Four-legged 4\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model1\",sourceLabel:\"Four-legged 5\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model\",sourceLabel:\"Four-legged 6\",group:\"Four-legged\"},{id:\"roster/18-quad-all--robotic_dog_3d_model\",sourceLabel:\"Four-legged 7\",group:\"Four-legged\"},{id:\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",sourceLabel:\"Four-legged 9\",group:\"Four-legged\"},{id:\"roster/19-genie-multi--fantasy_creature_3d_model\",sourceLabel:\"Genie \\xB7 Multi 1\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",sourceLabel:\"Genie \\xB7 Multi 2\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",sourceLabel:\"Genie \\xB7 Multi 3\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--stylized_octopus_3d_model\",sourceLabel:\"Genie \\xB7 Multi 4\",group:\"Genie \\xB7 Multi\"},{id:\"roster/20-lume--robotic_figure_3d_model\",sourceLabel:\"Lume 1\",group:\"Lume\"},{id:\"roster/22-curve--stylized_alien_3d_model\",sourceLabel:\"Curve 1\",group:\"Curve\"},{id:\"roster/22-curve--stylized_cartoon_figure_3d_model\",sourceLabel:\"Curve 2\",group:\"Curve\"},{id:\"roster/23-blob-texture-bodies--blob_creature_3d_model\",sourceLabel:\"Blob 1\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",sourceLabel:\"Blob 2\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",sourceLabel:\"Blob 3\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",sourceLabel:\"Blob 4\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--sand_creature_3d_model\",sourceLabel:\"Blob 5\",group:\"Blob\"}],Ae=Fe.map(e=>({...e,label:T(e.id)})),ve=[{id:\"roster/23-blob-texture-bodies--blob_creature_3d_model\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--dragon_creature_3d_model\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model1\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model3\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--four-legged_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model1\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/18-quad-all--robotic_dog_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",tracks:[\"meditation\"],difficulty:\"expert\"},{id:\"roster/14-chisel-spire--low_poly_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"expert\"},{id:\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",tracks:[\"cardio\"],difficulty:\"easy\"},{id:\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",tracks:[\"cardio\"],difficulty:\"easy\"},{id:\"roster/06-ridge-triad--robot_3d_model1\",tracks:[\"cardio\"],difficulty:\"medium\"},{id:\"roster/03-pearl-orb-ring--robot_3d_model\",tracks:[\"cardio\"],difficulty:\"hard\"},{id:\"roster/20-lume--robotic_figure_3d_model\",tracks:[\"cardio\"],difficulty:\"expert\"},{id:\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",tracks:[\"arms\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",tracks:[\"arms\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",tracks:[\"arms\"],difficulty:\"medium\"},{id:\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",tracks:[\"arms\"],difficulty:\"medium\"},{id:\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",tracks:[\"arms\"],difficulty:\"hard\"},{id:\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",tracks:[\"arms\"],difficulty:\"hard\"},{id:\"roster/08-shard-asym--robot_3d_model4\",tracks:[\"arms\"],difficulty:\"expert\"},{id:\"roster/06-ridge-triad--geometric_robot_3d_model1\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/08-shard-asym--geometric_robot_3d_model\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/16-spade-arch--pyramid_head_figure_3d_model\",tracks:[\"chest\",\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/04-crest-wedge--robot_creature_3d_model\",tracks:[\"chest\"],difficulty:\"hard\"},{id:\"roster/16-spade-arch--stylized_humanoid_3d_model\",tracks:[\"chest\"],difficulty:\"expert\"},{id:\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",tracks:[\"glutes\"],difficulty:\"easy\"},{id:\"roster/23-blob-texture-bodies--sand_creature_3d_model\",tracks:[\"glutes\"],difficulty:\"medium\"},{id:\"roster/03-pearl-orb-ring--stylized_3d_character1\",tracks:[\"glutes\"],difficulty:\"hard\"},{id:\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",tracks:[\"glutes\"],difficulty:\"expert\"},{id:\"roster/15-orbital-coili--robot_character_3d_model\",tracks:[\"quads\"],difficulty:\"easy\"},{id:\"roster/13-fan-split--stylized_3d_character2\",tracks:[\"quads\"],difficulty:\"medium\"},{id:\"roster/22-curve--stylized_cartoon_figure_3d_model\",tracks:[\"quads\"],difficulty:\"hard\"},{id:\"roster/10-petal-wisp--fantasy_creature_3d_model4\",tracks:[\"yoga\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--fantasy_creature_3d_model\",tracks:[\"yoga\"],difficulty:\"easy\"},{id:\"roster/10-petal-wisp--ghost_character_3d_model\",tracks:[\"yoga\"],difficulty:\"medium\"},{id:\"roster/08-shard-asym--stylized_action_figure_3d_model\",tracks:[\"yoga\"],difficulty:\"medium\"},{id:\"roster/22-curve--stylized_alien_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/10-petal-wisp--stylized_creature_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/19-genie-multi--stylized_octopus_3d_model\",tracks:[\"yoga\"],difficulty:\"expert\"},{id:\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",tracks:[\"martial-arts\"],difficulty:\"easy\"},{id:\"roster/11-anvil-cask--clay-style_robot_3d_model\",tracks:[\"martial-arts\"],difficulty:\"easy\"},{id:\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",tracks:[\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/14-chisel-spire--cone_head_3d_model\",tracks:[\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/08-shard-asym--fantasy_creature_3d_model2\",tracks:[\"martial-arts\"],difficulty:\"hard\"},{id:\"roster/09-monolith-tanka--mini_robot_3d_model\",tracks:[\"martial-arts\"],difficulty:\"hard\"},{id:\"roster/09-monolith-tanka--robot_3d_model3\",tracks:[\"martial-arts\"],difficulty:\"expert\"},{id:\"roster/13-fan-split--stylized_toy_3d_model\",tracks:[\"martial-arts\"],difficulty:\"expert\"},{id:\"roster/01-seed-pearo--3d_character_model\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/01-seed-pearo--cute_alien_figure_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/01-seed-pearo--blank_toy_figure_3d_model\",tracks:[\"cardio\"],difficulty:\"hard\"},{id:\"roster/02-taper-tallstalk--3d_humanoid_figure\",tracks:[\"quads\"],difficulty:\"hard\"},{id:\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",tracks:[\"quads\"],difficulty:\"expert\"},{id:\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",tracks:[\"glutes\"],difficulty:\"easy\"},{id:\"roster/03-pearl-orb-ring--circle_center\",tracks:[\"glutes\"],difficulty:\"medium\"},{id:\"roster/04-crest-wedge--stylized_3d_character\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/07-bulb-sphereling--cute_robot_3d_model\",tracks:[\"cardio\"],difficulty:\"medium\"},{id:\"roster/09-monolith-tanka--3d_robot_model\",tracks:[\"chest\"],difficulty:\"medium\"},{id:\"roster/09-monolith-tanka--white_horned_robot_3d_model\",tracks:[\"chest\"],difficulty:\"hard\"},{id:\"roster/17-shellcap-manyarm--3d_character_figurine\",tracks:[\"arms\"],difficulty:\"expert\"},{id:\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",tracks:[\"quads\"],difficulty:\"medium\"},{id:\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",tracks:[\"glutes\"],difficulty:\"hard\"}],Le={chest:[\"chest\"],quads:[\"legs\"],glutes:[\"hips\"],arms:[\"shoulders\"],yoga:[\"core\",\"balance\",\"yoga\"],\"martial-arts\":[\"stances\",\"boxing\"],cardio:[\"cardio\"],meditation:[\"meditation\"]},te=Object.freeze([\"chest\",\"quads\",\"glutes\",\"arms-shoulders\",\"yoga\",\"martial-arts\",\"cardio\"]),dr=Object.freeze({arms:\"arms-shoulders\"}),Me=e=>e===\"arms-shoulders\"?\"arms\":e;var oe=Object.freeze([\"myr5\",\"roster/23-blob-texture-bodies--blob_creature_3d_model\"]);var ne=ve.filter(e=>!oe.includes(e.id)).map(e=>({...e,name:T(e.id),groups:e.tracks.flatMap(r=>Le[r])})),Oe=Object.freeze(Object.fromEntries(te.map(e=>[e,ne.find(r=>r.tracks[0]===Me(e)&&r.difficulty===\"easy\").id])));var De=Object.freeze([\"easy\",\"medium\",\"hard\",\"expert\"]),ie=e=>Object.freeze(e.map(r=>Object.freeze(r.map(a=>a*10)))),mr=ie([[4,8,16],[8,12,20],[12,16,24],[16,20,28]]),hr=ie([[1,2,4],[2,3,5],[3,4,6],[4,5,7]]);var xe=15;var pr=Object.freeze({uncommon:1,rare:2,legendary:3,secret:3}),gr=Object.freeze({uncommon:Object.freeze({color:90,\"64-bit\":7,texture:3}),rare:Object.freeze({color:80,\"64-bit\":15,texture:5}),legendary:Object.freeze({color:70,\"64-bit\":20,texture:10}),secret:Object.freeze({color:60,\"64-bit\":20,texture:20})}),Be=2,le=500*10,y=Object.freeze({sessions:120,activeMinutes:30,expertXpPerMinute:280,meditationMultiplier:Be,trioBonus:le}),Pe=y.sessions*(y.activeMinutes*y.expertXpPerMinute*y.meditationMultiplier+y.trioBonus),fr=y.expertXpPerMinute*xe/60;var ce=250,N=ce-1,se=40,Ie=Pe/10,br=Object.freeze(Array.from({length:ce},(e,r)=>10*(se*r+Math.floor((Ie-se*N)*r*(r-1)/(N*(N-1))))));function z(e=globalThis.localStorage,r=globalThis.myr5AuthenticatedAccount){let a=r?.user?.id;if(a)return`account:${a}${r.dataEpoch!=null?`:${r.dataEpoch}`:\"\"}`;if(!e)return\"guest:unavailable\";let o=\"myr5-local-guest-owner-v1\";try{let t=e.getItem(o);return t||(t=globalThis.crypto?.randomUUID?.()||`guest-${Date.now()}-${Math.random()}`,e.setItem(o,t)),`guest:${t}`}catch{return\"guest:unavailable\"}}var Br={sprint:L.sprintRounds,gentle:L.gentleActiveSeconds,pace:L.paceActiveSeconds};var Te=Object.freeze([\"creature-skin\",\"ship\",\"reward-pack\"]),Tr=new Set([...Te,\"texture\",\"color\",\"palette\",\"boss-skin\"]);var zr=Object.freeze([\"clay\",\"martial-arts-canvas-gi\",\"arms-rope\",\"yoga-cork\",\"glutes-peach\"]),j=Object.freeze({\"legacy-0\":\"clay\",\"legacy-21\":\"opal-jelly\",\"bubble-glass\":\"glitter-resin\"}),jr=Object.freeze([\"flat\",\"legacy-22\",...Object.keys(j)]),de=e=>Object.hasOwn(j,e)?j[e]:e;var Ne=\"myr5-unlocks-v2\",ze=()=>({texture:[],color:[],palette:[]}),je=(e,r)=>`coach:${encodeURIComponent(e)}:${r}`,q=(e,r)=>e===\"texture\"?de(r):r,qe=(e,r)=>{let a=/^(coach:[^:]*:)(.*)$/.exec(r);return a?a[1]+q(e,a[2]):r};function U(){try{return JSON.parse(localStorage.getItem(\"myr5-recipe-v1\")||\"{}\").body||\"myr5\"}catch{return\"myr5\"}}var Ue=()=>`${Ne}/${encodeURIComponent(z())}`;function ue(){try{let e=JSON.parse(localStorage.getItem(Ue())||\"{}\");return Object.fromEntries([\"texture\",\"color\",\"palette\"].map(r=>[r,Array.isArray(e[r])?[...new Set(e[r].filter(a=>typeof a==\"string\").map(a=>qe(r,a)))]:[]]))}catch{return ze()}}var me=(e,r,a)=>ue()[e]?.includes(je(a,q(e,r)))??!1;function He(e,r){let a=q(e,r);return(ue()[e]||[]).some(o=>{let t=/^coach:([^:]+):(.*)$/.exec(o);if(!t||t[2]!==a)return!1;try{return decodeURIComponent(t[1])!==\"myr5\"}catch{return!1}})}var Ge=(e,r)=>me(e,r,\"myr5\")||He(e,r),H=(e,r,a=U())=>a===\"myr5\"?Ge(e,r):me(e,r,a);var G=[{id:32,name:\"Plate Steel\",roughness:.34,metalness:.82,relief:.024,bump:.012,sheen:0,sheenRoughness:.7,clearcoat:.35,clearcoatRoughness:.24},{id:33,name:\"Rubber Grip\",roughness:.95,metalness:0,relief:.055,bump:.022,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:34,name:\"Chain Mail\",roughness:.41,metalness:.78,relief:.034,bump:.014,sheen:0,sheenRoughness:.7,clearcoat:.3,clearcoatRoughness:.25},{id:35,name:\"Track Rubber\",roughness:.94,metalness:0,relief:.038,bump:.016,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:36,name:\"Denim\",roughness:.86,metalness:0,relief:.012,bump:.011,sheen:.22,sheenRoughness:.96,clearcoat:0,clearcoatRoughness:.5},{id:37,name:\"Hex Tread\",roughness:.82,metalness:.04,relief:.052,bump:.014,sheen:0,sheenRoughness:.9,clearcoat:.08,clearcoatRoughness:.4},{id:38,name:\"Sweatshirt Fleece\",roughness:.99,metalness:0,relief:.05,bump:.032,sheen:.74,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},{id:39,name:\"Quilted\",roughness:.89,metalness:0,relief:.07,bump:.012,sheen:.14,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:40,name:\"Speckled\",roughness:.96,metalness:0,relief:.03,bump:.028,sheen:.34,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},{id:41,name:\"Hammered Bronze\",roughness:.39,metalness:.78,relief:.025,bump:.025,sheen:0,sheenRoughness:.7,clearcoat:.28,clearcoatRoughness:.22},{id:42,name:\"Fine Stripe\",roughness:.91,metalness:0,relief:.042,bump:.012,sheen:.08,sheenRoughness:.92,clearcoat:0,clearcoatRoughness:.5},{id:43,name:\"Snake Skin\",roughness:.68,metalness:.02,relief:.019,bump:.023,sheen:.1,sheenRoughness:.76,clearcoat:.08,clearcoatRoughness:.4},{id:44,name:\"Holey\",roughness:.96,metalness:0,relief:.039,bump:.025,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:45,name:\"Woven Mat\",roughness:.9,metalness:0,relief:.014,bump:.014,sheen:.08,sheenRoughness:.94,clearcoat:0,clearcoatRoughness:.5},{id:46,name:\"Petal\",roughness:.51,metalness:0,relief:.025,bump:.009,sheen:.52,sheenRoughness:.72,clearcoat:.12,clearcoatRoughness:.3},{id:47,name:\"Graph Paper\",roughness:.93,metalness:0,relief:.012,bump:.017,sheen:.16,sheenRoughness:.97,clearcoat:0,clearcoatRoughness:.5},{id:48,name:\"Bamboo\",roughness:.57,metalness:0,relief:.027,bump:.008,sheen:.18,sheenRoughness:.62,clearcoat:.12,clearcoatRoughness:.28},{id:49,name:\"Dragon Scale\",roughness:.31,metalness:.16,relief:.043,bump:.01,sheen:.24,sheenRoughness:.42,clearcoat:.72,clearcoatRoughness:.16},{id:50,name:\"Cool Graph Paper\",roughness:.56,metalness:.23,relief:.021,bump:.008,sheen:0,sheenRoughness:.8,clearcoat:.12,clearcoatRoughness:.3},{id:51,name:\"Terry Cloth\",roughness:.98,metalness:0,relief:.014,bump:.026,sheen:.62,sheenRoughness:.99,clearcoat:0,clearcoatRoughness:.5},{id:52,name:\"Pebble Path\",roughness:.77,metalness:0,relief:.038,bump:.018,sheen:0,sheenRoughness:.8,clearcoat:.08,clearcoatRoughness:.4},{id:53,name:\"Wiggles\",roughness:.99,metalness:0,relief:.016,bump:.016,sheen:0,sheenRoughness:.95,clearcoat:0,clearcoatRoughness:.5},{id:54,name:\"River Stone\",roughness:.72,metalness:.01,relief:.031,bump:.019,sheen:.04,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.32},{id:55,name:\"Moss\",roughness:.99,metalness:0,relief:.022,bump:.023,sheen:.38,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5}],Ke={id:56,name:\"64-bit Skin\",roughness:.58,metalness:.12,relief:.018,bump:.01,sheen:0,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.4},K=[{id:57,name:\"Opal Jelly\",roughness:.06,metalness:0,relief:.004,bump:.001,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.035},{id:58,name:\"Bubble Glass\",roughness:.035,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},{id:59,name:\"Prism Crystal\",roughness:.045,metalness:0,relief:.052,bump:.008,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.03},{id:60,name:\"Holographic Foil\",roughness:.18,metalness:.88,relief:.022,bump:.013,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.045},{id:61,name:\"Glitter Resin\",roughness:.075,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},{id:62,name:\"Galaxy Geode\",roughness:.22,metalness:.25,relief:.065,bump:.014,sheen:0,sheenRoughness:.3,clearcoat:.8,clearcoatRoughness:.06},{id:63,name:\"Caustic Slime\",roughness:.055,metalness:0,relief:.035,bump:.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:64,name:\"Blister Hide\",roughness:.18,metalness:0,relief:.065,bump:.023,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:65,name:\"Rotten Rind\",roughness:.94,metalness:0,relief:.05,bump:.025,sheen:0,sheenRoughness:.6,clearcoat:0,clearcoatRoughness:.07},{id:66,name:\"Parasite Nest\",roughness:.31,metalness:0,relief:.07,bump:.027,sheen:0,sheenRoughness:.6,clearcoat:.6,clearcoatRoughness:.07},{id:67,name:\"Exposed Sinew\",roughness:.2,metalness:0,relief:.045,bump:.017,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:68,name:\"Abyssal Maw\",roughness:.26,metalness:0,relief:.065,bump:.023,sheen:0,sheenRoughness:.6,clearcoat:.8,clearcoatRoughness:.07},{id:69,name:\"Circuit Alloy\",roughness:.19,metalness:.83,relief:.027,bump:.01,sheen:0,sheenRoughness:.6,clearcoat:.6,clearcoatRoughness:.07},{id:70,name:\"Servo Armor\",roughness:.34,metalness:.82,relief:.055,bump:.013,sheen:0,sheenRoughness:.6,clearcoat:.4,clearcoatRoughness:.07},{id:71,name:\"Chrome Rib\",roughness:.09,metalness:.96,relief:.05,bump:.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:72,name:\"Carbon Mech\",roughness:.64,metalness:.18,relief:.018,bump:.013,sheen:0,sheenRoughness:.6,clearcoat:.25,clearcoatRoughness:.07},{id:73,name:\"Hazard Panel\",roughness:.46,metalness:.55,relief:.032,bump:.014,sheen:0,sheenRoughness:.6,clearcoat:.4,clearcoatRoughness:.07},{id:74,name:\"Reactor Glass\",roughness:.045,metalness:0,relief:.018,bump:.004,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07}],We=new Map([...G,Ke,...K].map(e=>[e.id,e])),he=e=>We.get(e);var pe=[{id:\"pal-01\",name:\"Acid Forge\",tagline:\"Lime bites oxblood and chrome\",colors:[\"#C6FF00\",\"#4A0E17\",\"#C0C7CE\"],unlockRule:\"aura-milestone\",unlockAtDay:5,finish:\"glitter\"},{id:\"pal-02\",name:\"Neon Afterburn Haze\",tagline:\"Orange aqua contrails with violet flare\",colors:[\"#FF6D00\",\"#00E0B0\",\"#C800FF\"],unlockRule:\"aura-milestone\",unlockAtDay:10,finish:\"brushed-metal\"},{id:\"pal-03\",name:\"Petrel Copper\",tagline:\"Petrol depths meet intense violet\",colors:[\"#0E5A61\",\"#B87333\",\"#6913E7\"],unlockRule:\"aura-milestone\",unlockAtDay:15,finish:\"polished-metal\"},{id:\"pal-04\",name:\"Vinaigrette Rust\",tagline:\"Oil pigment rust swirl\",colors:[\"#8A3B12\",\"#556B2F\",\"#E7A213\"],unlockRule:\"aura-milestone\",unlockAtDay:20,finish:\"marbled\"},{id:\"pal-05\",name:\"Neon Relic\",tagline:\"Hot magenta neon amber on bone\",colors:[\"#FF009F\",\"#FFB500\",\"#F2EFE6\"],unlockRule:\"aura-milestone\",unlockAtDay:25,finish:\"glitter\"},{id:\"pal-06\",name:\"Glacier Ember\",tagline:\"Ice teal over ember red\",colors:[\"#13E7D1\",\"#D9381E\",\"#2B2530\"],unlockRule:\"aura-milestone\",unlockAtDay:30,finish:\"pearl\"},{id:\"pal-07\",name:\"Chartreuse Storm\",tagline:\"Sludge green meets slate violet\",colors:[\"#B5C700\",\"#3D3654\",\"#E85D75\"],unlockRule:\"aura-milestone\",unlockAtDay:35,finish:\"matte\"},{id:\"pal-08\",name:\"Saffron Voltage\",tagline:\"Saffron arcs on ink blue\",colors:[\"#FFB000\",\"#101D42\",\"#00FAA6\"],unlockRule:\"aura-milestone\",unlockAtDay:40,finish:\"polished-metal\"},{id:\"pal-09\",name:\"Neon Venom Signal\",tagline:\"Poison lime warning under arterial red\",colors:[\"#A6FF00\",\"#FF2442\",\"#101828\"],unlockRule:\"aura-milestone\",unlockAtDay:45,finish:\"watercolor\"},{id:\"pal-10\",name:\"Mercury Moss\",tagline:\"Silver moss over saturated gold\",colors:[\"#AEB6BC\",\"#5C6B3C\",\"#E7A913\"],unlockRule:\"aura-milestone\",unlockAtDay:50,finish:\"brushed-metal\"},{id:\"pal-11\",name:\"Ultraviolet Tar\",tagline:\"Violet glow on tar black\",colors:[\"#7B2FF7\",\"#141414\",\"#FFC93C\"],unlockRule:\"aura-milestone\",unlockAtDay:55,finish:\"glaze\"},{id:\"pal-12\",name:\"Salmon Circuit\",tagline:\"Salmon pink on circuit green\",colors:[\"#FA2200\",\"#00A86B\",\"#2E2A5C\"],unlockRule:\"aura-milestone\",unlockAtDay:60,finish:\"pearl\"},{id:\"pal-13\",name:\"Muddy Pop\",tagline:\"Ochre mud sparks cerulean\",colors:[\"#8C6A2F\",\"#0081C8\",\"#E71362\"],unlockRule:\"battle-pass\",reward:\"strider-2:L1\",finish:\"matte\"},{id:\"pal-14\",name:\"Neon Vapor Crown\",tagline:\"Laser pink blue over dark purple\",colors:[\"#FF00AA\",\"#00D0FF\",\"#1B0033\"],unlockRule:\"battle-pass\",reward:\"strider-2:L3\",finish:\"watercolor\"},{id:\"pal-15\",name:\"Brick Vein\",tagline:\"Brick red veined in steel\",colors:[\"#A0342B\",\"#8C9BA5\",\"#D7E713\"],unlockRule:\"battle-pass\",reward:\"strider-2:L4\",finish:\"marbled\"},{id:\"pal-16\",name:\"Peacock Static\",tagline:\"Peacock green hums gold\",colors:[\"#046A5B\",\"#FAAF00\",\"#5B1E4B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L1\",finish:\"polished-metal\"},{id:\"pal-17\",name:\"Foghorn Flame\",tagline:\"Fog gray with fire-orange siren\",colors:[\"#B8C0C2\",\"#FA3F00\",\"#123C69\"],unlockRule:\"battle-pass\",reward:\"strider-3:L3\",finish:\"brushed-metal\"},{id:\"pal-18\",name:\"Toxic Honey\",tagline:\"Honey drips on toxic lime\",colors:[\"#D9A404\",\"#9BF00B\",\"#4A154B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L4\",finish:\"glaze\"},{id:\"pal-19\",name:\"Neon Crimson Mirage\",tagline:\"Scarlet toxic lime over deep jade\",colors:[\"#FF1744\",\"#76FF03\",\"#005E3C\"],unlockRule:\"battle-pass\",reward:\"strider-4:L1\",finish:\"matte\"},{id:\"pal-20\",name:\"Opal Drain\",tagline:\"Opal sheen on drainpipe green\",colors:[\"#13E7B9\",\"#3E5641\",\"#D1495B\"],unlockRule:\"battle-pass\",reward:\"strider-4:L3\",finish:\"pearl\"},{id:\"pal-21\",name:\"Rust Halo\",tagline:\"Rust ringed by mint flash\",colors:[\"#9C4221\",\"#12E898\",\"#2C2C54\"],unlockRule:\"battle-pass\",reward:\"strider-4:L4\",finish:\"brushed-metal\"},{id:\"pal-22\",name:\"Volt Quartz\",tagline:\"Electric yellow on rose quartz\",colors:[\"#F5E900\",\"#E71363\",\"#264653\"],unlockRule:\"battle-pass\",reward:\"strider-5:L1\",finish:\"glitter\"},{id:\"pal-23\",name:\"Neon Flare Garden\",tagline:\"Laser lime pink on teal steel\",colors:[\"#8CFF00\",\"#FF006E\",\"#00B8A9\"],unlockRule:\"battle-pass\",reward:\"strider-5:L3\",finish:\"matte\"},{id:\"pal-24\",name:\"Crimson Tidebreak\",tagline:\"Crimson breaks on seafoam\",colors:[\"#B91338\",\"#13E7B5\",\"#2A1E5C\"],unlockRule:\"battle-pass\",reward:\"strider-5:L4\",finish:\"watercolor\"},{id:\"pal-25\",name:\"Brass Mirage\",tagline:\"Brass shimmer dusky plum\",colors:[\"#C59B42\",\"#5A2A52\",\"#0D94ED\"],unlockRule:\"battle-pass\",reward:\"strider-6:L1\",finish:\"polished-metal\"},{id:\"pal-26\",name:\"Neon Infrared Bloom\",tagline:\"Red heat sliced by frozen cyan\",colors:[\"#FF0000\",\"#00F5FF\",\"#5B00B5\"],unlockRule:\"battle-pass\",reward:\"strider-6:L3\",finish:\"glaze\"},{id:\"pal-27\",name:\"Ice Magma\",tagline:\"Pigmented ice over magma orange\",colors:[\"#D6F0F0\",\"#F45B0F\",\"#3D2C8D\"],unlockRule:\"battle-pass\",reward:\"strider-6:L4\",finish:\"marbled\"},{id:\"pal-28\",name:\"Fern Radio\",tagline:\"Fern green static magenta\",colors:[\"#3F7A3A\",\"#E4007C\",\"#E7BE13\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L1\",finish:\"matte\"},{id:\"pal-29\",name:\"Porcelain Fuel\",tagline:\"Porcelain white fuel orange\",colors:[\"#F2F2F0\",\"#FF7A1A\",\"#14507A\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L3\",finish:\"glaze\"},{id:\"pal-30\",name:\"Neon Photon Alley\",tagline:\"Yellow signage aqua and violet glass\",colors:[\"#FFD300\",\"#00FFCC\",\"#7A00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L4\",finish:\"brushed-metal\"},{id:\"pal-31\",name:\"Neon Solar Flare\",tagline:\"Hot yellow ember in plum space\",colors:[\"#FFEA00\",\"#FF3D00\",\"#26142B\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L1\",finish:\"polished-metal\"},{id:\"pal-32\",name:\"Wet Cement Rose\",tagline:\"Cement gray wild rose\",colors:[\"#8D9096\",\"#D84A87\",\"#F0E130\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L3\",finish:\"matte\"},{id:\"pal-33\",name:\"Neon Laser Tropics\",tagline:\"Chartreuse beams with scorched orange shadows\",colors:[\"#C6FF00\",\"#FF4D00\",\"#001219\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L4\",finish:\"watercolor\"},{id:\"pal-34\",name:\"Copper Fog\",tagline:\"Copper glows through fog\",colors:[\"#B46A30\",\"#C4CBCE\",\"#B600F5\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L1\",finish:\"brushed-metal\"},{id:\"pal-35\",name:\"Laser Moss\",tagline:\"Laser cyan on moss\",colors:[\"#00E5FF\",\"#546B2F\",\"#FF4FA3\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L3\",finish:\"glitter\"},{id:\"pal-36\",name:\"Bone Ember\",tagline:\"Bone white ember orange\",colors:[\"#EDE8DC\",\"#E4572E\",\"#BA00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L4\",finish:\"matte\"},{id:\"pal-37\",name:\"Plum Static\",tagline:\"Plum noise with electric lime\",colors:[\"#4A1E4F\",\"#B8F000\",\"#33B5C7\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L1\",finish:\"glaze\"},{id:\"pal-38\",name:\"Neon Lime Vortex\",tagline:\"Acid green swirling through electric blue\",colors:[\"#BFFF00\",\"#00E5FF\",\"#12100F\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L3\",finish:\"pearl\"},{id:\"pal-39\",name:\"Clay Command\",tagline:\"Terracotta clay cobalt order\",colors:[\"#C06B55\",\"#2E4BC6\",\"#EDE6D6\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L4\",finish:\"marbled\"},{id:\"pal-40\",name:\"Static Cream\",tagline:\"Cream noise shock green\",colors:[\"#F4EDDE\",\"#39FF14\",\"#4A306D\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L1\",finish:\"glitter\"},{id:\"pal-41\",name:\"Midnight Papaya\",tagline:\"Midnight blue papaya burst\",colors:[\"#191970\",\"#FF9E42\",\"#13E796\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L3\",finish:\"polished-metal\"},{id:\"pal-42\",name:\"Dusty Laser\",tagline:\"Dusty mauve laser green\",colors:[\"#A27E8E\",\"#7CFC00\",\"#1B3B6F\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L4\",finish:\"matte\"},{id:\"pal-43\",name:\"Neon Atomic Sunset\",tagline:\"Amber fallout glowing beside ultraviolet pink\",colors:[\"#FF9100\",\"#FF00F5\",\"#062A2A\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L1\",finish:\"glaze\"},{id:\"pal-44\",name:\"Fern Flame\",tagline:\"Cool fern fierce flame\",colors:[\"#4F7942\",\"#FF3D2E\",\"#E75A13\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L3\",finish:\"brushed-metal\"},{id:\"pal-45\",name:\"Violet Quarry\",tagline:\"Quarry gray violet eruption\",colors:[\"#7D7F87\",\"#8B3DFF\",\"#DCE35B\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L4\",finish:\"matte\"},{id:\"pal-46\",name:\"Cadmium Deep\",tagline:\"Cadmium red deep lagoon\",colors:[\"#D32E12\",\"#046E8F\",\"#E79E13\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L1\",finish:\"polished-metal\"},{id:\"pal-47\",name:\"Pigment Riot\",tagline:\"Intense blue maroon and hot orange\",colors:[\"#139FE7\",\"#6E1423\",\"#FF7300\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L3\",finish:\"watercolor\"},{id:\"pal-48\",name:\"Neon Prism Riot\",tagline:\"Sea-glass cyan, magenta bite, lemon flash\",colors:[\"#00FFC6\",\"#FF00B8\",\"#F5FF00\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L4\",finish:\"pearl\"},{id:\"pal-49\",name:\"Neon Tropic Surge\",tagline:\"Aqua tide, citrus flare, violet thunder\",colors:[\"#00FF9D\",\"#FFB000\",\"#D000FF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L1\",finish:\"glitter\"},{id:\"pal-50\",name:\"Ash Honey\",tagline:\"Ash gray golden honey\",colors:[\"#9BA0A6\",\"#E0A100\",\"#2F6690\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L3\",finish:\"matte\"},{id:\"pal-51\",name:\"Cherry Motor\",tagline:\"Cherry motor oil with electric blue\",colors:[\"#B22234\",\"#3B2F2F\",\"#005CFF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L4\",finish:\"brushed-metal\"},{id:\"pal-52\",name:\"Glacier Punch\",tagline:\"Glacier pigmented hot punch\",colors:[\"#13A6E7\",\"#F52549\",\"#3D405B\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L1\",finish:\"glaze\"},{id:\"pal-53\",name:\"Tarnish Bloom\",tagline:\"Tarnished teal floral orange\",colors:[\"#3A7D7B\",\"#F4852B\",\"#E9D6EC\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L3\",finish:\"marbled\"},{id:\"pal-54\",name:\"Umber Signal\",tagline:\"Umber earth neon signal\",colors:[\"#635147\",\"#D0FF4B\",\"#7A28C0\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L4\",finish:\"matte\"},{id:\"pal-55\",name:\"Rose Quartz Coil\",tagline:\"Soft rose coil of teal\",colors:[\"#E7134B\",\"#0FA3A3\",\"#2B2118\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L1\",finish:\"pearl\"},{id:\"pal-56\",name:\"Sulfur Deck\",tagline:\"Sulfur yellow blue and hot orange\",colors:[\"#E3D200\",\"#274C77\",\"#FF4A00\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L3\",finish:\"polished-metal\"},{id:\"pal-57\",name:\"Neon Ember Static\",tagline:\"Orange yellow buzzing with royal voltage\",colors:[\"#FF5E00\",\"#FFE600\",\"#3A0CA3\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L4\",finish:\"watercolor\"},{id:\"pal-58\",name:\"Mango Ash\",tagline:\"Mango bright volcanic ash\",colors:[\"#FFA12B\",\"#59595E\",\"#64DDBB\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L1\",finish:\"matte\"},{id:\"pal-59\",name:\"Steel Petal\",tagline:\"Steel gray crushed petals\",colors:[\"#8A8F98\",\"#E71813\",\"#D8E26E\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L3\",finish:\"brushed-metal\"},{id:\"pal-60\",name:\"Ninja Cream\",tagline:\"Hidden navy cream coral\",colors:[\"#1E2A4A\",\"#F0EBE0\",\"#7EEC00\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L4\",finish:\"glaze\"},{id:\"pal-61\",name:\"Tangerine Static\",tagline:\"Tangerine buzz grape shadow\",colors:[\"#F28500\",\"#3D2159\",\"#202020\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L1\",finish:\"glitter\"},{id:\"pal-62\",name:\"Sage Pistol\",tagline:\"Muted sage pistol pink\",colors:[\"#9AB5A1\",\"#E45C98\",\"#33272A\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L3\",finish:\"matte\"},{id:\"pal-63\",name:\"Lagoon Battery\",tagline:\"Lagoon green charged yellow\",colors:[\"#1D8A7A\",\"#FAE000\",\"#76305B\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L4\",finish:\"polished-metal\"},{id:\"pal-64\",name:\"Wine Cooling\",tagline:\"Warm wine cooled by mint\",colors:[\"#701F3C\",\"#13E78C\",\"#E8D44D\"],unlockRule:\"battle-pass\",reward:\"warden-1:L1\",finish:\"pearl\"},{id:\"pal-65\",name:\"Charcoal Tulip\",tagline:\"Charcoal tulip flame combo\",colors:[\"#2E3033\",\"#FF4E50\",\"#CA00C7\"],unlockRule:\"battle-pass\",reward:\"warden-1:L3\",finish:\"matte\"},{id:\"pal-66\",name:\"Neon Acid Harbor\",tagline:\"Lime light cutting across magenta docks\",colors:[\"#39FF14\",\"#FF007F\",\"#001B2E\"],unlockRule:\"battle-pass\",reward:\"warden-1:L4\",finish:\"pearl\"},{id:\"pal-67\",name:\"Rustic Neon\",tagline:\"Barn red barn lime buzz\",colors:[\"#8A3324\",\"#C1FF33\",\"#2D4A6B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L1\",finish:\"marbled\"},{id:\"pal-68\",name:\"Alice Warning\",tagline:\"Alice blue caution orange\",colors:[\"#1399E7\",\"#FF7E1F\",\"#EEF700\"],unlockRule:\"battle-pass\",reward:\"blob-2:L3\",finish:\"watercolor\"},{id:\"pal-69\",name:\"Smog Candy\",tagline:\"Smog beige candy teal\",colors:[\"#E79813\",\"#00C2A8\",\"#D8395B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L4\",finish:\"matte\"},{id:\"pal-70\",name:\"Violet Furnace\",tagline:\"Furnace violet cooled sky\",colors:[\"#6A2D9E\",\"#F57C3B\",\"#302012\"],unlockRule:\"battle-pass\",reward:\"blob-3:L1\",finish:\"glaze\"},{id:\"pal-71\",name:\"Khaki Storm\",tagline:\"Khaki field storm magenta\",colors:[\"#A89B6E\",\"#E0218A\",\"#2A6F97\"],unlockRule:\"battle-pass\",reward:\"blob-3:L3\",finish:\"brushed-metal\"},{id:\"pal-72\",name:\"Neon Circuit Surge\",tagline:\"Turquoise sparks over midnight violet\",colors:[\"#00F5D4\",\"#F72585\",\"#0B0321\"],unlockRule:\"battle-pass\",reward:\"blob-3:L4\",finish:\"glitter\"},{id:\"pal-73\",name:\"Cedar Ultraviolet\",tagline:\"Cedar wood ultraviolet light\",colors:[\"#7A4532\",\"#8246FF\",\"#E9E4D8\"],unlockRule:\"battle-pass\",reward:\"blob-4:L1\",finish:\"matte\"},{id:\"pal-74\",name:\"Frosted Chili\",tagline:\"Frost blue chili red\",colors:[\"#13AAE7\",\"#C13A2F\",\"#4C5B2C\"],unlockRule:\"battle-pass\",reward:\"blob-4:L3\",finish:\"polished-metal\"},{id:\"pal-75\",name:\"Moss Rocket\",tagline:\"Moss green rocket pink\",colors:[\"#5B7042\",\"#FA0057\",\"#061F5B\"],unlockRule:\"battle-pass\",reward:\"blob-4:L4\",finish:\"matte\"},{id:\"pal-76\",name:\"Pewter Punch\",tagline:\"Pewter softened hot punch\",colors:[\"#99A0A8\",\"#FF3D7F\",\"#164D37\"],unlockRule:\"battle-pass\",reward:\"cap-2:L1\",finish:\"brushed-metal\"},{id:\"pal-77\",name:\"Neon Glacier Riot\",tagline:\"Cyan hot pink and radioactive lime\",colors:[\"#00F0FF\",\"#FF00E5\",\"#CCFF00\"],unlockRule:\"battle-pass\",reward:\"cap-2:L3\",finish:\"watercolor\"},{id:\"pal-78\",name:\"Cola Lightning\",tagline:\"Cola brown lightning yellow\",colors:[\"#3A2618\",\"#F7FF00\",\"#FA005E\"],unlockRule:\"battle-pass\",reward:\"cap-2:L4\",finish:\"glaze\"},{id:\"pal-79\",name:\"Periwinkle Fuel\",tagline:\"Soft periwinkle diesel orange\",colors:[\"#1325E7\",\"#E0641E\",\"#2F4730\"],unlockRule:\"battle-pass\",reward:\"cap-3:L1\",finish:\"matte\"},{id:\"pal-80\",name:\"Jade Alarm\",tagline:\"Jade calm siren red\",colors:[\"#57A78A\",\"#D91E36\",\"#E7AF13\"],unlockRule:\"battle-pass\",reward:\"cap-3:L3\",finish:\"pearl\"},{id:\"pal-81\",name:\"Neon Ultraviolet Pulse\",tagline:\"Violet beams with mint-charged current\",colors:[\"#8C00FF\",\"#00FFB2\",\"#160021\"],unlockRule:\"battle-pass\",reward:\"cap-3:L4\",finish:\"matte\"},{id:\"pal-82\",name:\"Neon Nightcaller\",tagline:\"Cyan violet flame in black-green fog\",colors:[\"#00FFFF\",\"#9400FF\",\"#131A00\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L1\",finish:\"marbled\"},{id:\"pal-83\",name:\"Ivory Shock\",tagline:\"Ivory calm violet shock\",colors:[\"#F0EEE4\",\"#7C1FD3\",\"#FFB200\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L3\",finish:\"glaze\"},{id:\"pal-84\",name:\"Neon Ruby Arc\",tagline:\"Red-hot signal over green afterglow\",colors:[\"#FF073A\",\"#00FF87\",\"#080F1B\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L4\",finish:\"glitter\"},{id:\"pal-85\",name:\"Maroon Cloud\",tagline:\"Maroon heavy cloud blue\",colors:[\"#6D1E2E\",\"#1381E7\",\"#E5D352\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L1\",finish:\"watercolor\"},{id:\"pal-86\",name:\"Chrome Berry\",tagline:\"Chrome band over berry\",colors:[\"#C3C9D1\",\"#8E2A5C\",\"#FFB347\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L3\",finish:\"polished-metal\"},{id:\"pal-87\",name:\"Lentil Neon\",tagline:\"Lentil tan electric aqua\",colors:[\"#B09A6E\",\"#00FFF0\",\"#5F1B63\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L4\",finish:\"matte\"},{id:\"pal-88\",name:\"Neon Cobalt Fuse\",tagline:\"Blue ignition wired to blazing yellow\",colors:[\"#004DFF\",\"#FFEE00\",\"#0D0221\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L1\",finish:\"glaze\"},{id:\"pal-89\",name:\"Spruce Bonfire\",tagline:\"Dark spruce bonfire orange\",colors:[\"#23493C\",\"#FF7A3D\",\"#0C1735\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L3\",finish:\"matte\"},{id:\"pal-90\",name:\"Lilac Foundry\",tagline:\"Lilac meets foundry steel\",colors:[\"#9813E7\",\"#7B8894\",\"#D4522A\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L4\",finish:\"brushed-metal\"},{id:\"pal-91\",name:\"Topaz Battle\",tagline:\"Topaz gold navy clash\",colors:[\"#F0B429\",\"#182952\",\"#FA007D\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L1\",finish:\"polished-metal\"},{id:\"pal-92\",name:\"Dusk Celery\",tagline:\"Dusky purple celery snap\",colors:[\"#574B6B\",\"#C8D86A\",\"#FA2100\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L3\",finish:\"matte\"},{id:\"pal-93\",name:\"Tide Copperfuse\",tagline:\"Tidal teal copperfuse glow\",colors:[\"#0F7B7B\",\"#C07840\",\"#C2F000\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L4\",finish:\"pearl\"},{id:\"pal-94\",name:\"Punch Driftwood\",tagline:\"Fruit punch on driftwood\",colors:[\"#E63362\",\"#6E5B4A\",\"#1648EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L1\",finish:\"watercolor\"},{id:\"pal-95\",name:\"Ink Lime\",tagline:\"Ink smudge streaked lime\",colors:[\"#23232A\",\"#A8E10C\",\"#7E10EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L3\",finish:\"glaze\"},{id:\"pal-96\",name:\"Porcelain Prism\",tagline:\"Porcelain violet over tidal blue\",colors:[\"#F5F1E8\",\"#BD05DA\",\"#005F73\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L4\",finish:\"marbled\"},{id:\"pal-97\",name:\"Wasabi Cloud\",tagline:\"Wasabi heat cloud gray\",colors:[\"#9FBF3B\",\"#8E94A0\",\"#E71363\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L1\",finish:\"matte\"},{id:\"pal-98\",name:\"Eggplant Flare\",tagline:\"Eggplant deep flare yellow\",colors:[\"#41284E\",\"#FFD23F\",\"#5BC0BE\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L3\",finish:\"glitter\"},{id:\"pal-99\",name:\"Stone Rose\",tagline:\"Stone gray antique rose\",colors:[\"#8F8A82\",\"#C46E8E\",\"#2F6DA3\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L4\",finish:\"brushed-metal\"},{id:\"pal-100\",name:\"Neon Quasar Pop\",tagline:\"Yellow green comet over indigo gravity\",colors:[\"#FFEF00\",\"#00FF3C\",\"#2D02B8\"],unlockRule:\"battle-pass\",reward:\"lume-1:L1\",finish:\"glaze\"},{id:\"pal-101\",name:\"Arctic Rust\",tagline:\"Arctic white rusted orange\",colors:[\"#E9F2F5\",\"#9E4A1D\",\"#3E3F8F\"],unlockRule:\"battle-pass\",reward:\"lume-1:L3\",finish:\"brushed-metal\"},{id:\"pal-102\",name:\"Magenta Selvage\",tagline:\"Magenta edge denim blue\",colors:[\"#D8117E\",\"#3B5B8C\",\"#E7D313\"],unlockRule:\"battle-pass\",reward:\"lume-1:L4\",finish:\"matte\"},{id:\"pal-103\",name:\"Haze Saffron\",tagline:\"Purple haze saffron spark\",colors:[\"#8467B8\",\"#F4A81D\",\"#1D4E50\"],unlockRule:\"battle-pass\",reward:\"food:L1\",finish:\"pearl\"},{id:\"pal-104\",name:\"Neon Cyber Reed\",tagline:\"Green circuitry humming beside lemon static\",colors:[\"#00FF66\",\"#FFEA00\",\"#4B0082\"],unlockRule:\"battle-pass\",reward:\"food:L2\",finish:\"glitter\"},{id:\"pal-105\",name:\"Neon Magma Bloom\",tagline:\"Molten orange meeting synthetic magenta\",colors:[\"#FF2E00\",\"#F000FF\",\"#0A0A0F\"],unlockRule:\"battle-pass\",reward:\"food:L3\",finish:\"polished-metal\"},{id:\"pal-106\",name:\"Dune Violet\",tagline:\"Warm dune electric violet\",colors:[\"#C9AE7E\",\"#7D2BF0\",\"#13E7E3\"],unlockRule:\"battle-pass\",reward:\"food:L4\",finish:\"marbled\"},{id:\"pal-107\",name:\"Ember Nightshade\",tagline:\"Violet shadows ember teal\",colors:[\"#523090\",\"#EF4E23\",\"#0C5D68\"],unlockRule:\"battle-pass\",reward:\"food:L5\",finish:\"watercolor\"},{id:\"opal-jelly\",name:\"Opal Jelly\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b3fff0\",\"#9767ff\",\"#fff1ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"bubble-glass\",name:\"Bubble Glass\",tagline:\"Shifting highlights and luminous color\",colors:[\"#58eaff\",\"#b8fff8\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"prism-crystal\",name:\"Prism Crystal\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b18aff\",\"#447bff\",\"#fff2ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"holo-foil\",name:\"Holographic Foil\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff54de\",\"#39e5ff\",\"#fff56b\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"glitter-resin\",name:\"Glitter Resin\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff319c\",\"#7025ff\",\"#fff6db\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"galaxy-geode\",name:\"Galaxy Geode\",tagline:\"Shifting highlights and luminous color\",colors:[\"#21134e\",\"#7b39e8\",\"#63ffff\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"caustic-slime\",name:\"Caustic Slime\",tagline:\"Organic horror surface\",colors:[\"#8aa52b\",\"#20300b\",\"#dcff57\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"blister-hide\",name:\"Blister Hide\",tagline:\"Organic horror surface\",colors:[\"#9e435f\",\"#2d1727\",\"#e7bb72\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"rotten-rind\",name:\"Rotten Rind\",tagline:\"Organic horror surface\",colors:[\"#626124\",\"#211916\",\"#a2b16b\"],unlockRule:\"battle-pass\",finish:\"matte\"},{id:\"parasite-nest\",name:\"Parasite Nest\",tagline:\"Organic horror surface\",colors:[\"#786541\",\"#151c14\",\"#ece2b0\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"exposed-sinew\",name:\"Exposed Sinew\",tagline:\"Organic horror surface\",colors:[\"#b72945\",\"#300b24\",\"#efb5a1\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"abyssal-maw\",name:\"Abyssal Maw\",tagline:\"Organic horror surface\",colors:[\"#522045\",\"#100d19\",\"#d9e6a7\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"circuit-alloy\",name:\"Circuit Alloy\",tagline:\"Machine surface\",colors:[\"#273f50\",\"#0a111c\",\"#4effdc\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"servo-armor\",name:\"Servo Armor\",tagline:\"Machine surface\",colors:[\"#617080\",\"#141b25\",\"#ff6739\"],unlockRule:\"battle-pass\",finish:\"brushed-metal\"},{id:\"chrome-rib\",name:\"Chrome Rib\",tagline:\"Machine surface\",colors:[\"#bfcde1\",\"#202f46\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"carbon-mech\",name:\"Carbon Mech\",tagline:\"Machine surface\",colors:[\"#323d46\",\"#080d15\",\"#95bac9\"],unlockRule:\"battle-pass\"},{id:\"hazard-panel\",name:\"Hazard Panel\",tagline:\"Machine surface\",colors:[\"#edb932\",\"#131a20\",\"#ffe9a2\"],unlockRule:\"battle-pass\"},{id:\"reactor-glass\",name:\"Reactor Glass\",tagline:\"Machine surface\",colors:[\"#48e8ff\",\"#063a55\",\"#d4ffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"}];var $e=[{id:\"nails\",label:\"Nails\",short:\"Nails\",description:\"Five claw and nail forms\"},{id:\"fingertips\",label:\"Finger tips\",short:\"Tips\",description:\"Distal pads and final phalanges\"},{id:\"fingers\",label:\"Fingers & knuckles\",short:\"Fingers\",description:\"Joined finger shafts, bases and knuckles\"},{id:\"palm\",label:\"Palm\",short:\"Palm\",description:\"The inner hand surface\"},{id:\"back_of_hand\",label:\"Back of hand\",short:\"Back\",description:\"The dorsal hand surface\"},{id:\"wrist\",label:\"Wrist\",short:\"Wrist\",description:\"Stump, cuff and transition\"}],Je=[{id:0,name:\"Mortal\",realm:\"Baseline \\xB7 Earth\",primary:\"#b9856f\",secondary:\"#714c42\",accent:\"#f0c0a3\",emissive:\"#000000\",roughness:.72,metalness:.02,detail:\"clean\"},{id:1,name:\"Verdant\",realm:\"Wildroot \\xB7 Dimension 12\",primary:\"#3f7448\",secondary:\"#1e3b2b\",accent:\"#b8dd6e\",emissive:\"#172d13\",roughness:.88,metalness:0,detail:\"vine\"},{id:2,name:\"Mycelial\",realm:\"Sporesea \\xB7 Dimension 09\",primary:\"#d5c7ae\",secondary:\"#776b82\",accent:\"#f59ec4\",emissive:\"#6d234a\",roughness:.92,metalness:0,detail:\"caps\"},{id:3,name:\"Chitin\",realm:\"Carapace \\xB7 Dimension 31\",primary:\"#4f263d\",secondary:\"#180f20\",accent:\"#d17663\",emissive:\"#240716\",roughness:.3,metalness:.28,detail:\"plates\"},{id:4,name:\"Reptilian\",realm:\"Scalehold \\xB7 Dimension 04\",primary:\"#5f7a3f\",secondary:\"#283621\",accent:\"#cfb85c\",emissive:\"#101c08\",roughness:.76,metalness:.04,detail:\"scales\"},{id:5,name:\"Abyssal\",realm:\"Deep Trench \\xB7 Dimension 88\",primary:\"#132a42\",secondary:\"#06111f\",accent:\"#4edfd3\",emissive:\"#0b756f\",roughness:.34,metalness:.12,detail:\"spines\"},{id:6,name:\"Coral\",realm:\"Living Reef \\xB7 Dimension 22\",primary:\"#e46867\",secondary:\"#70344c\",accent:\"#ffd27a\",emissive:\"#8b2438\",roughness:.83,metalness:0,detail:\"coral\"},{id:7,name:\"Skeletal\",realm:\"Ossuary \\xB7 Dimension 00\",primary:\"#d8d0af\",secondary:\"#80785f\",accent:\"#fff7d1\",emissive:\"#17160e\",roughness:.9,metalness:0,detail:\"bone\"},{id:8,name:\"Spectral\",realm:\"Veil \\xB7 Dimension 13\",primary:\"#8ed9cd\",secondary:\"#294c58\",accent:\"#d5fff8\",emissive:\"#248e86\",roughness:.18,metalness:.04,detail:\"mist\"},{id:9,name:\"Infernal\",realm:\"Cinder Court \\xB7 Dimension 66\",primary:\"#7b211e\",secondary:\"#260b0a\",accent:\"#ff8a2a\",emissive:\"#d33812\",roughness:.58,metalness:.1,detail:\"flame\"},{id:10,name:\"Celestial\",realm:\"High Orbit \\xB7 Dimension 07\",primary:\"#e6dca4\",secondary:\"#786da7\",accent:\"#fffbd7\",emissive:\"#8d74d6\",roughness:.24,metalness:.5,detail:\"halo\"},{id:11,name:\"Voidborn\",realm:\"Null Expanse \\xB7 Dimension \\u2205\",primary:\"#16101f\",secondary:\"#060409\",accent:\"#9f64ff\",emissive:\"#482285\",roughness:.16,metalness:.36,detail:\"void\"},{id:12,name:\"Eldritch\",realm:\"Watcher Fold \\xB7 Dimension 47\",primary:\"#6b426c\",secondary:\"#252038\",accent:\"#b6ef63\",emissive:\"#4e7628\",roughness:.64,metalness:.04,detail:\"eyes\"},{id:13,name:\"Stone Golem\",realm:\"Deep Strata \\xB7 Dimension 19\",primary:\"#6f7068\",secondary:\"#393b37\",accent:\"#b7a37d\",emissive:\"#171811\",roughness:.98,metalness:0,detail:\"rock\"},{id:14,name:\"Crystal\",realm:\"Prism Vault \\xB7 Dimension 52\",primary:\"#896bc2\",secondary:\"#302e66\",accent:\"#e0c8ff\",emissive:\"#5a3da8\",roughness:.12,metalness:.3,detail:\"crystal\"},{id:15,name:\"Magma\",realm:\"Mantle \\xB7 Dimension 03\",primary:\"#4a1713\",secondary:\"#140706\",accent:\"#ffb22f\",emissive:\"#e44712\",roughness:.78,metalness:.06,detail:\"magma\"},{id:16,name:\"Glacial\",realm:\"White Silence \\xB7 Dimension 71\",primary:\"#93c9df\",secondary:\"#315a76\",accent:\"#ebfdff\",emissive:\"#3c93bb\",roughness:.2,metalness:.14,detail:\"ice\"},{id:17,name:\"Stormcharged\",realm:\"Tempest Ring \\xB7 Dimension 28\",primary:\"#48536e\",secondary:\"#1a2236\",accent:\"#c3f7ff\",emissive:\"#3ebde0\",roughness:.4,metalness:.32,detail:\"storm\"},{id:18,name:\"Clockwork Robot\",realm:\"Brass Meridian \\xB7 Dimension 14\",primary:\"#9a6a37\",secondary:\"#33251d\",accent:\"#efd08c\",emissive:\"#5b2c12\",roughness:.32,metalness:.82,detail:\"gears\"},{id:19,name:\"Neon Synth\",realm:\"Aftergrid \\xB7 Dimension 20\",primary:\"#251d54\",secondary:\"#0b0921\",accent:\"#ff5bd7\",emissive:\"#b519ac\",roughness:.22,metalness:.55,detail:\"neon\"},{id:20,name:\"Fluffy\",realm:\"Cloudburrow \\xB7 Soft forms\",primary:\"#d6a987\",secondary:\"#bb8969\",accent:\"#ffe4c3\",emissive:\"#000000\",roughness:.88,metalness:0,detail:\"fur\"},{id:21,name:\"Jelly\",realm:\"Lime Lagoon \\xB7 Soft forms\",primary:\"#a7ec69\",secondary:\"#f1ffd4\",accent:\"#c9ff90\",emissive:\"#000000\",roughness:.13,metalness:0,detail:\"jelly\"},{id:22,name:\"Baby\",realm:\"Little One \\xB7 Soft forms\",primary:\"#efb398\",secondary:\"#d68e7c\",accent:\"#ffe2d5\",emissive:\"#000000\",roughness:.52,metalness:0,detail:\"baby\"}],Ye=[\"opal-jelly\",\"bubble-glass\",\"prism-crystal\",\"holo-foil\",\"glitter-resin\",\"galaxy-geode\",\"caustic-slime\",\"blister-hide\",\"rotten-rind\",\"parasite-nest\",\"exposed-sinew\",\"abyssal-maw\",\"circuit-alloy\",\"servo-armor\",\"chrome-rib\",\"carbon-mech\",\"hazard-panel\",\"reactor-glass\"],M=[...Je,...[{id:30,name:\"Flat\",roughness:.55,metalness:0},{id:31,name:\"Clay\",roughness:.92,metalness:0},...G,he(56),...K].map(e=>{let r=pe.find(i=>i.id===Ye[e.id-57]),[a,o,t]=r?.colors??[\"#8b8f9a\",\"#4a4d55\",\"#e7e9ee\"];return{id:e.id,name:e.name,realm:\"Surface finish\",primary:a,secondary:o,accent:t,emissive:\"#000000\",roughness:e.roughness,metalness:e.metalness,detail:e.name.toLowerCase(),paletteId:r?.id}})];var Qr=M.filter(e=>![8,11].includes(e.id)).map(e=>({name:e.name,description:`A pure ${e.name.toLowerCase()} hand`,values:Object.fromEntries($e.map(r=>[r.id,e.id]))})),Zr=M.filter(e=>![8,11].includes(e.id)).sort((e,r)=>+(r.id>=63)-+(e.id>=63)||+(r.id>=57)-+(e.id>=57));var Ve=new Set([\"https://mominc.online\",\"https://www.mominc.online\",\"https://myr5.mominc.online\"]),W=!1;window.addEventListener(\"message\",async e=>{if(!(e.source!==window.parent||!Ve.has(e.origin)||e.data?.type!==\"handborne:unlock-request\"||W)){W=!0;try{let r=null;try{localStorage.getItem(\"myr5-login-provider\")===\"clerk\"&&await I();let t=await Z(\"/api/account\",{guestSkip:!0});t.ok&&(r=await t.json())}catch{}globalThis.myr5AuthenticatedAccount=r;let a=U(),o=M.filter(t=>t.id>=57&&t.paletteId&&H(\"texture\",t.paletteId,a)&&H(\"palette\",t.paletteId,a)).map(t=>t.id);window.parent.postMessage({type:\"handborne:unlock-state\",styles:o},e.origin)}finally{W=!1}}});\n","handborne/unlocks.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><title>Coach material ownership</title></head><body><script type=\"module\" src=\"/handborne/unlock-bridge.mjs\"></script></body></html>\r\n","hardware-launch.css":":root{--pixel-font:ui-monospace,'Cascadia Mono',monospace}\r\n.panel-heading>span,.calibration-grid label,.goal-control label{font-size:11px}.panel-heading>small,.signal-control>small,.manual-button,.slider-scale{font-size:12px}.goal-control output{font-size:16px}.calibration-grid{align-items:center}.dial-controls button{min-width:36px;min-height:44px}.exercise-control{padding-right:8px}.exercise-control>strong{font-size:17px}.rocker-switch{min-width:64px;min-height:72px}.signal-control>small{max-width:140px;margin:auto;line-height:1.5}.coach-line #coachCaption{font-size:14px}\r\n.workout-console #hud{justify-content:center;text-align:center;padding:14px 8px;margin:0 0 16px;background:#1c1820!important;border:2px solid #211a26;border-radius:5px;box-shadow:inset 2px 3px 8px #0009,0 1px #aa899e}.counter-target{justify-content:center}.workout-console #primary{--tile-width:43px;--tile-height:60px;--digit-size:45px}.workout-console #status{font-size:13px}.workout-console .set-actions{flex-basis:auto}.set-actions .primary-action small{font-size:11px}.set-actions .primary-action span{font-size:10px}.workout-console #stop{font-size:13px}\r\n/* W2-2A: the bar's hardware skin; its layout lives in launch.css. */\r\n#coachDock.coach-dock{border-top:3px solid #a38e9a;background:repeating-linear-gradient(0deg,#d9c5d604 0 1px,transparent 1px 3px),linear-gradient(125deg,#564754,#322938 60%,#635163);box-shadow:inset 0 2px #d7bdcf66,0 -5px 14px #08060c66}\r\n#coachDock.coach-dock button:not(.dock-portal){position:relative;flex-direction:column;gap:5px;font:700 10px var(--pixel-font);letter-spacing:0;border:2px solid #a89e98;border-top-color:#e8dfc5;border-left-color:#d1c5b3;border-radius:6px;color:#2b303c;background:linear-gradient(135deg,#eee9d7,#c7c9ba 70%,#a5afa4);box-shadow:inset 0 2px #fff9,inset -2px -3px #72817a66,0 3px #475050,0 4px #13111a;transition:transform .08s,box-shadow .08s}\r\n#coachDock.coach-dock button:not(.dock-portal):before{content:'';width:18px;height:6px;border:1px solid #27232d;background:#574a4b;border-radius:2px;box-shadow:inset 0 1px 2px #0008}\r\n#coachDock.coach-dock button[data-panel=meals]{background:linear-gradient(135deg,#e7bd7f,#bc8c55);border-color:#edc796;color:#32232a}#coachDock.coach-dock button[data-panel=reminders]{background:linear-gradient(135deg,#85b5aa,#4f847e);border-color:#a9c7b7;color:#172f30}#coachDock.coach-dock button[data-panel=install]{background:linear-gradient(135deg,#ae9bab,#74677f);border-color:#b7a6b8;color:#fff2d5}\r\n#coachDock.coach-dock button:not(.dock-portal):is(:active,[aria-current=page]){transform:translateY(3px);box-shadow:inset 1px 3px 5px #39444366,0 1px #475050,0 1px #13111a}#coachDock.coach-dock button[aria-current=page]:before{background:#eab56d;box-shadow:0 0 7px #ffc875aa}\r\n.launch-panel{border:3px solid #9c8394;border-top-color:#c6aeba;border-bottom-color:#4d3c51;border-radius:9px;background:repeating-linear-gradient(0deg,#e9cfdf05 0 1px,transparent 1px 3px),linear-gradient(125deg,#574354,#33293d 56%,#46384b);box-shadow:inset 0 2px #e7cedb66,0 6px #1e1725,8px 15px 50px #000a;padding:24px}.launch-panel header{padding-bottom:16px;border-bottom:2px solid #231b2a;box-shadow:0 1px #a58b9866}.launch-panel h2{font:750 24px var(--pixel-font);color:#f6dfb7}.launch-panel h3{font:700 18px var(--pixel-font);color:#f6dfb7}.launch-panel label{color:#e6d2dd}\r\n.launch-panel button,.launch-panel .action-link{border:2px solid #b297a8;border-top-color:#d1bccc;border-bottom-color:#71596f;border-radius:5px;background:linear-gradient(135deg,#93798d,#5f4c64);box-shadow:inset 0 2px #efd7e355,inset -2px -3px #34253566,0 4px #251b2d,0 6px #17111d;color:#fff0d7;font:650 14px var(--pixel-font);min-height:48px;transition:transform .08s,box-shadow .08s}\r\n.launch-panel button:active:not(:disabled),.launch-panel .action-link:active{transform:translateY(3px);box-shadow:inset 1px 3px 6px #24182d88,0 1px #251b2d}.launch-panel .main-action{border-color:#e9c18c;background:linear-gradient(#e6bc7c,#ba814b);color:#2e222a;box-shadow:inset 0 2px #fff0c5,inset -2px -3px #76503166,0 4px #583c30,0 6px #1c1420}.launch-panel header button{min-height:44px;font-size:12px}\r\n.launch-panel input,.launch-panel select{background:#201b27;border:2px solid #201728;border-bottom-color:#997d90;box-shadow:inset 2px 3px 5px #0007;border-radius:4px;color:#f7e8d0}.launch-panel input:focus-visible,.launch-panel select:focus-visible{outline:3px solid #f1c482;outline-offset:3px}.launch-panel input[type=file]{padding:8px}.launch-panel input::file-selector-button{margin-right:10px;border:2px solid #c1bba4;border-radius:4px;background:linear-gradient(#ede9d6,#b7bdad);box-shadow:0 3px #687467;color:#273b39;padding:10px;cursor:pointer}\r\n.launch-panel .status{border:2px solid #23192a;border-bottom-color:#957788;background:#221c29;color:#e9d7ba;box-shadow:inset 1px 2px 4px #0006;border-radius:4px;font-size:14px}.launch-panel .hint{color:#d2bccb}.launch-panel .entry{border-color:#8d728466;align-items:center}.launch-panel .entry small{color:#cdb7ca}.launch-panel .nutrition{margin:14px 0}.launch-panel form>.main-action{margin-top:7px}\r\n.switch-plate{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px;border:2px solid #977c8a;border-radius:6px;background:linear-gradient(130deg,#71586b,#3d3045);box-shadow:inset 0 1px #d5b9c966,0 3px #201625;margin:15px 0}.switch-plate>div{flex:1}.switch-plate strong{display:block;font:700 14px var(--pixel-font);color:#f0dabb}.switch-plate small{display:block;font-size:12px;color:#ceb8cb;margin-top:5px}.switch-plate .actions{margin-top:12px}\r\n.launch-panel .hardware-toggle{display:inline-flex;align-items:center;justify-content:space-between;gap:10px;min-width:102px;min-height:48px;padding:7px 10px 7px 7px;background:linear-gradient(#332738,#211927);border:2px solid #a48a99;box-shadow:inset 2px 3px 6px #000b,0 2px #b298a766;color:#d3bdcf;border-radius:6px;font-size:12px;flex-shrink:0}\r\n.hardware-toggle:before{content:'';width:32px;height:30px;border:2px solid #c8b7ae;border-radius:4px;background:repeating-linear-gradient(90deg,#b4a4a6 0 4px,#8d7d88 4px 5px);box-shadow:inset 0 2px #e5d7ca,2px 3px 3px #0009;transition:transform .12s}.launch-panel .hardware-toggle[aria-checked=true]{flex-direction:row-reverse;color:#fee1a0;background:linear-gradient(#6e573d,#423126)}.hardware-toggle[aria-checked=true]:before{background:repeating-linear-gradient(90deg,#e2b775 0 4px,#b58d59 4px 5px);border-color:#f1cf94}\r\n.launch-panel .switch-label{display:flex;align-items:center;justify-content:space-between;gap:15px;padding:12px 0;font:650 14px var(--pixel-font)}.launch-panel input[type=checkbox][role=switch]{appearance:none;position:relative;flex-shrink:0;width:76px;height:40px;margin:0;border:3px solid #211827;border-radius:5px;background:linear-gradient(#2e2536,#19151e);box-shadow:0 0 0 1px #a08796,inset 2px 2px 5px #0007;cursor:pointer;padding:0}.launch-panel input[type=checkbox][role=switch]:before{content:'';position:absolute;inset:3px auto 3px 3px;width:28px;background:repeating-linear-gradient(90deg,#b1a0a8 0 4px,#8e7f8c 4px 5px);border:1px solid #d4c5c4;box-shadow:1px 2px 3px #0009;border-radius:2px;transition:transform .12s}.launch-panel input[type=checkbox][role=switch]:checked{background:#6c4e30}.launch-panel input[type=checkbox][role=switch]:checked:before{transform:translateX(34px);background:repeating-linear-gradient(90deg,#e7bd7c 0 4px,#bf905f 4px 5px);border-color:#f6d899}\r\n.nutrition-switch summary{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:50px;font-size:14px;cursor:pointer;list-style:none}.nutrition-switch summary:after{content:'OFF';display:flex;align-items:center;justify-content:center;width:65px;height:34px;background:linear-gradient(#8a7485,#58465d);border:3px solid #25192c;border-radius:4px;box-shadow:inset 0 2px #bca3b4,0 2px #ad93a755;font:700 12px var(--pixel-font);color:#eddae6}.nutrition-switch[open] summary:after{content:'ON';background:linear-gradient(#a98454,#705034);color:#ffe9b8;box-shadow:inset 0 -2px #dcb27b,0 2px #ad93a755}.reminder-entry{flex-wrap:wrap}.reminder-entry>.entry-copy{flex:1;min-width:160px}.reminder-controls{display:flex;gap:9px;align-items:center}.reminder-controls>button:last-child{min-width:44px;padding:8px;font-size:12px}.reminder-entry[data-enabled=false] .entry-copy{opacity:.65}\r\n@media(min-width:900px) and (pointer:fine){body{max-width:940px}.pod-page{padding:0 38px 25px}.containment-bay .containment-pod{height:420px}.calibration-grid{padding:24px}.exercise-dial{width:112px;height:112px}.panel-heading>strong{font-size:25px}.exercise-control>strong{font-size:21px}.rocker-switch{width:78px;min-height:82px}.coach-line #coachCaption{font-size:18px}.workout-console #primary{--tile-width:50px;--tile-height:70px;--digit-size:53px}}\r\n@media(max-width:420px){.launch-panel{padding:18px 14px}.switch-plate{padding:11px;gap:8px}.switch-plate strong{font-size:13px}.launch-panel .hardware-toggle{min-width:91px;gap:7px}.launch-panel .entry{gap:10px}.panel-heading>strong{font-size:17px}.calibration-grid label{font-size:10px}.exercise-dial{width:76px;height:76px}.dial-controls{gap:6px}.dial-controls button{min-width:30px}}\r\n","hologram.mjs":"// Three.js is imported only on opening a model. AGPL-3.0-or-later app wrapper.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {OrbitControls} from 'three/addons/controls/OrbitControls.js';\r\nimport {demoPose,DEMO_BONES} from './demo-poses.mjs';\r\nimport {coachFetch} from './coach-net.mjs';\r\nimport {claimGraphics} from './modules/graphics-lifecycle.mjs';\r\nexport async function createHologram(host,name,{still=false}={}){\r\n  let renderer,releaseGpu=null,controls,frame=0,observer,mixer,model,animateDemo=null,demoTime=0,disposed=false,playing=true;\r\n  const scene=new THREE.Scene(),pivot=new THREE.Group();scene.add(pivot);\r\n  function disposeObject(object){object.traverse(node=>{node.geometry?.dispose();if(node.material)for(const mat of [node.material].flat()){for(const value of Object.values(mat))if(value?.isTexture)value.dispose();mat.dispose();}});}\r\n  function dispose(){if(disposed)return;disposed=true;cancelAnimationFrame(frame);observer?.disconnect();controls?.dispose();mixer?.stopAllAction();if(model)mixer?.uncacheRoot(model);disposeObject(scene);renderer?.dispose();renderer?.forceContextLoss();renderer?.domElement.remove();releaseGpu?.(renderer?.domElement);releaseGpu=null;}\r\n  // The hidden portal board yields (the 3D coach stays beside the demo); it rebuilds once this closes.\r\n  releaseGpu=claimGraphics('hologram',{keep:['coach']});await releaseGpu.ready;\r\n  try{\r\n    renderer=new THREE.WebGLRenderer({alpha:true,antialias:true,powerPreference:'low-power'});renderer.setPixelRatio(Math.min(window.devicePixelRatio||1,1.5));renderer.setClearColor(0x000000,0);host.append(renderer.domElement);\r\n    const camera=new THREE.PerspectiveCamera(38,1,.01,100);controls=new OrbitControls(camera,renderer.domElement);controls.enablePan=false;controls.enableZoom=false;controls.enableDamping=true;controls.minDistance=1.5;controls.maxDistance=12;controls.minPolarAngle=.15;controls.maxPolarAngle=Math.PI-.15;\r\n    // Offline or slow: the procedural wireframe figure below stands in for the downloaded model.\r\n    const got=['squat','pushup'].includes(name)?await coachFetch('/models/'+name+'.glb',{},{timeoutMs:20000,parse:'arrayBuffer',local:true}):null;\r\n    if(got?.ok){\r\n    const bytes=got.data;\r\n    const gltf=await new GLTFLoader().parseAsync(bytes,'');model=gltf.scene;\r\n    // Fit using the first animation pose, not the rig's rest pose.\r\n    mixer=new THREE.AnimationMixer(model);gltf.animations.forEach(clip=>mixer.clipAction(clip).play());mixer.update(0);model.updateMatrixWorld(true);\r\n    const box=new THREE.Box3().setFromObject(model),size=box.getSize(new THREE.Vector3()),center=box.getCenter(new THREE.Vector3()),scale=2/Math.max(size.x,size.y,size.z);\r\n    const offset=new THREE.Group();offset.position.copy(center).multiplyScalar(-1);offset.add(model);const normalized=new THREE.Group();normalized.scale.setScalar(scale);normalized.add(offset);pivot.add(normalized);\r\n    model.traverse(node=>{if(node.isMesh){const old=[node.material].flat();node.material=new THREE.MeshBasicMaterial({color:0x9afae4,wireframe:true,transparent:true,opacity:.72});for(const mat of old){for(const value of Object.values(mat))if(value?.isTexture)value.dispose();mat.dispose();}node.frustumCulled=false;}});\r\n    }else{\r\n      model=new THREE.Group();pivot.add(model);\r\n      const material=new THREE.MeshBasicMaterial({color:0x9afae4,wireframe:true,transparent:true,opacity:.8});\r\n      const joints=Object.fromEntries(Object.keys(demoPose(name)).map(key=>{const joint=new THREE.Mesh(new THREE.SphereGeometry(key==='head'?.13:.047,12,8),material);model.add(joint);return [key,joint];}));\r\n      const bones=DEMO_BONES.map(()=>{const mesh=new THREE.Mesh(new THREE.CylinderGeometry(.035,.045,1,8,4),material);model.add(mesh);return mesh;});\r\n      const up=new THREE.Vector3(0,1,0),a=new THREE.Vector3(),b=new THREE.Vector3(),direction=new THREE.Vector3();\r\n      animateDemo=t=>{const points=demoPose(name,t);for(const [key,joint] of Object.entries(joints))joint.position.fromArray(points[key]);DEMO_BONES.forEach(([from,to],i)=>{a.fromArray(points[from]);b.fromArray(points[to]);const mesh=bones[i];direction.subVectors(b,a);mesh.position.copy(a).add(b).multiplyScalar(.5);mesh.scale.y=direction.length();mesh.quaternion.setFromUnitVectors(up,direction.normalize());});};animateDemo(0);\r\n    }\r\n    const ring=new THREE.Mesh(new THREE.RingGeometry(1.02,1.035,64),new THREE.MeshBasicMaterial({color:0x8cf6e0,transparent:true,opacity:.35,side:THREE.DoubleSide}));ring.rotation.x=-Math.PI/2;ring.position.y=-1.05;scene.add(ring);\r\n    function reset(){pivot.rotation.set(0,['boxing','jogging'].includes(name)?-.45:0,0);camera.position.set(0,.15,Math.max(4.8,3.6/(host.clientWidth/Math.max(host.clientHeight,1))));controls.target.set(0,0,0);controls.update();}\r\n    function resize(){const r=host.getBoundingClientRect();renderer.setSize(Math.max(r.width,1),Math.max(r.height,1),false);camera.aspect=r.width/Math.max(r.height,1);camera.updateProjectionMatrix();}\r\n    observer=new ResizeObserver(resize);observer.observe(host);reset();resize();let last=performance.now();\r\n    function draw(now){if(disposed)return;const dt=Math.min((now-last)/1000,.06);last=now;if(playing){mixer?.update(dt);demoTime+=dt;animateDemo?.(demoTime);}controls.update();renderer.render(scene,camera);frame=requestAnimationFrame(draw);}if(!still)frame=requestAnimationFrame(draw);\r\n    return {dispose,reset,capturePose:async time=>{mixer?.setTime(time);animateDemo?.(time);controls.update();renderer.render(scene,camera);return new Promise(resolve=>renderer.domElement.toBlob(resolve,'image/png'));},toggle:()=>playing=!playing,rotate:(x,y)=>{pivot.rotation.y+=x;pivot.rotation.x=THREE.MathUtils.clamp(pivot.rotation.x+y,-1.2,1.2);}};\r\n  }catch(error){dispose();throw error;}\r\n}\r\n","install-context.mjs":"export function isInstalled(win=window){return win.matchMedia('(display-mode: standalone)').matches||win.navigator.standalone===true;}\r\nexport function setupAllowed(win=window){\r\n if(isInstalled(win)){try{win.sessionStorage.setItem('myr5-in-app-setup','1');}catch{}return true;}\r\n // Keep an in-app sign-in return usable if the identity provider changes its window context.\r\n try{return win.sessionStorage.getItem('myr5-in-app-setup')==='1';}catch{return false;}\r\n}\r\n","install-transfer.mjs":"import {readIncomingCoach,saveIncomingCoach} from './pending-coach.mjs';\r\nexport async function prepareInstall(data,fetcher=fetch){\r\n const response=await fetcher('/api/install-draft',{method:'POST',credentials:'same-origin',headers:{'Content-Type':'application/json'},body:JSON.stringify({data})});\r\n if(!response.ok)throw Error('Your coach could not be prepared for installation. Please retry.');\r\n}\r\nexport async function restoreInstall(fetcher=fetch,session=sessionStorage,local=localStorage,{signal}={}){\r\n const response=await fetcher('/api/install-draft',{credentials:'same-origin',cache:'no-store',signal});\r\n if(!response.ok)throw Object.assign(Error('Could not bring your coach into the app. Check your connection and retry.'),{status:response.status});\r\n const {data}=await response.json();signal?.throwIfAborted();\r\n if(data){saveIncomingCoach(data,session,local);await fetcher('/api/install-draft',{method:'DELETE',credentials:'same-origin',signal});return data;}\r\n return readIncomingCoach(session,local);\r\n}\r\n","install.css":":root{color-scheme:dark;font-family:Arial,sans-serif;color:#f5e4ba;background:#21172f}*{box-sizing:border-box}body{margin:0;min-height:100dvh;display:grid;place-items:center;padding:max(24px,env(safe-area-inset-top)) 20px max(24px,env(safe-area-inset-bottom));background:radial-gradient(ellipse at top,#54335d,#21172f 65%)}.install-card{width:min(100%,440px);text-align:center;padding:28px 24px;background:#2b2036;border:2px solid #ae9060;border-radius:24px;box-shadow:0 14px 50px #0b061770}.brand{font-size:.875rem;font-weight:700;letter-spacing:.2em;color:#d6b77d;margin-bottom:22px}.app-icon{border-radius:22px;display:block;margin:0 auto 22px}h1{font-size:2rem;line-height:1.1;margin:0 0 18px}p{font-size:1rem;line-height:1.5}button,.continue{width:100%;min-height:52px;border-radius:12px;font:700 1rem Arial;display:grid;place-content:center;text-decoration:none;padding:14px 18px}button{margin-top:24px;background:#e7c988;color:#21172f;border:2px solid #ffebb7;cursor:pointer}.continue{color:#b8e9cf;margin-top:10px;border:1px solid #65756e}button:focus-visible,a:focus-visible{outline:3px solid #b8e9cf;outline-offset:4px}.status,.note{font-size:.875rem;color:#d5c6b7}.note{border-top:1px solid #76614b;padding-top:16px;margin-bottom:0}#installGuide{text-align:left;border-radius:12px;background:#17101f;padding:18px;margin-top:18px}#installGuide[hidden]{display:none}h2{font-size:1.125rem;margin:0 0 12px}ol{padding-left:22px;margin:0}li{line-height:1.5;margin:8px 0}#installHelp{display:block;color:#b8e9cf;font-size:.875rem;margin-top:14px}#installHelp[hidden]{display:none}\r\n\r\n[hidden]{display:none!important}button:disabled{opacity:.6;cursor:wait}\r\n","install.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\"><meta name=\"referrer\" content=\"no-referrer\"><meta name=\"theme-color\" content=\"#21172f\"><meta name=\"apple-mobile-web-app-capable\" content=\"yes\"><title>Install your Coach · MOM INC</title><link rel=\"manifest\" href=\"/manifest.webmanifest?v=myr5-alien-v1\"><link rel=\"icon\" type=\"image/png\" href=\"/icons/myr5-alien-192.png\"><link rel=\"apple-touch-icon\" href=\"/icons/myr5-alien-apple.png\"><link rel=\"stylesheet\" href=\"/install.css\"></head><body><main class=\"install-card\"><div class=\"brand\">MOM INC</div><img class=\"app-icon\" src=\"/icons/myr5-alien-192.png\" alt=\"Original purple MYR5 alien\" width=\"96\" height=\"96\"><h1>Install Coach</h1><p class=\"status\">Install MYR5, then open it from your home screen.</p><p id=\"coachSaved\" role=\"status\"></p><button id=\"installCoach\" type=\"button\" disabled>Loading…</button><p id=\"installStatus\" class=\"status\" role=\"status\"></p><section id=\"installGuide\" hidden aria-labelledby=\"guideTitle\"><h2 id=\"guideTitle\">Add to your home screen</h2><ol id=\"installSteps\"></ol><a id=\"installHelp\" href=\"https://support.apple.com/guide/iphone/open-as-web-app-iphea86e5236/ios\" target=\"_blank\" rel=\"noopener noreferrer\" hidden>Apple’s home-screen guide</a></section><noscript>Enable JavaScript to bring your coach into the app.</noscript></main><script type=\"module\" src=\"/install.mjs?v=quick-install-v3\"></script></body></html>\r\n","install.mjs":"import {decodeHandoff} from './onboarding-domain.mjs';\r\nimport {captureGala,mountGalaReturn,saveInstalledRun,prepareGalaInstall} from './gala-handoff.mjs';\r\ntry{captureGala();mountGalaReturn();}catch{}\r\nimport {readIncomingCoach,saveIncomingCoach} from './pending-coach.mjs';\r\nimport {isInstalled,setupAllowed} from './install-context.mjs';\r\nimport {prepareInstall} from './install-transfer.mjs';\r\nimport {prepareOfflineApp} from './offline-install.mjs';\r\nconst button=document.getElementById('installCoach'),status=document.getElementById('installStatus'),saved=document.getElementById('coachSaved');\r\nconst ios=/iPad|iPhone|iPod/.test(navigator.userAgent)||(navigator.platform==='MacIntel'&&navigator.maxTouchPoints>1),android=/Android/i.test(navigator.userAgent);\r\nlet prompt=null,ready=false;\r\nfunction guide(){\r\n const steps=ios?['Tap Share, then Add to Home Screen.','Leave Open as Web App on if shown, then tap Add.','Open the MYR5 icon on your home screen.']:android?['Open the ⋮ menu and tap Install app or Add to Home screen.','Confirm, then open MYR5 from your home screen.']:['Use your browser’s install icon beside the address bar, or its Install app menu item.','Open MYR5 from your apps.'];\r\n const list=document.getElementById('installSteps');list.replaceChildren(...steps.map(text=>{const li=document.createElement('li');li.textContent=text;return li;}));\r\n document.getElementById('installHelp').hidden=!ios;document.getElementById('installGuide').hidden=false;\r\n status.textContent=ios?'Add Coach, then open its home-screen icon.':'Install Coach, then open it from your apps. If installation is unavailable, use Chrome or Edge.';\r\n}\r\nfunction installed(){prompt=null;button.hidden=true;document.getElementById('installGuide').hidden=true;status.textContent='Installed. Open MYR5 to start.';}\r\nwindow.addEventListener('beforeinstallprompt',event=>{event.preventDefault();prompt=event;if(ready){button.textContent='Install Coach';status.textContent='Ready to install';}});\r\nwindow.addEventListener('appinstalled',installed);\r\nbutton.onclick=async()=>{if(!ready){await prepare();return;}if(!prompt){guide();return;}const current=prompt;prompt=null;try{await current.prompt();const choice=await current.userChoice;if(choice.outcome==='accepted')installed();else{status.textContent='Install cancelled';}}catch{guide();}};\r\nasync function prepare(){\r\n button.disabled=true;\r\n try{\r\n  status.textContent='Saving Coach on this device…';\r\n  try{await prepareGalaInstall();}catch{mountGalaReturn();}\r\n  const raw=new URLSearchParams(location.hash.slice(1)).get('coach'),incoming=raw?saveIncomingCoach(decodeHandoff(raw)):readIncomingCoach();\r\n  if(incoming){await prepareInstall(incoming);saved.textContent='Coach saved';}\r\n  if(raw)history.replaceState(null,'',location.pathname+location.search);\r\n  await prepareOfflineApp();\r\n  ready=true;button.disabled=false;button.textContent=ios?'Add Coach to Home Screen':'Install Coach';status.textContent='';\r\n  if(ios)guide();else setTimeout(()=>{if(!prompt)guide();},2500); // no install prompt (desktop/unsupported browser): show the steps instead of a dead button\r\n }catch(error){status.textContent=error.message;button.textContent='Retry';button.disabled=false;}\r\n}\r\nif(isInstalled()){await saveInstalledRun().catch(()=>{});setupAllowed();location.replace('/onboarding.html?from=install'+location.hash);}else await prepare();\r\n","launch-bootstrap.mjs":"export function showStartupFailure(document,error){\r\n const setup=document.getElementById('coachSetupGate');if(setup?.open)setup.close();\r\n let gate=document.getElementById('coachStartupRecovery');\r\n if(!gate){gate=document.createElement('dialog');gate.id='coachStartupRecovery';document.body.append(gate);}\r\n gate.setAttribute('aria-label','Reconnect Coach');\r\n gate.style.cssText='position:fixed;inset:0;margin:0;width:100vw;height:100dvh;max-width:none;max-height:none;border:0;z-index:2147483646;background:#17111ef5;display:grid;place-content:center;padding:28px;color:#f5e4ba;font:18px/1.6 Arial;text-align:center';\r\n gate.replaceChildren();\r\n const heading=document.createElement('h1'),message=document.createElement('p'),retry=document.createElement('a');\r\n heading.textContent='Reconnect Coach';message.textContent='Your saved coach is safe. Reload the app to reconnect.';\r\n retry.textContent='Reload Coach';retry.href='/pose.html?reconnect='+Date.now();retry.style.cssText='color:#b8e9cf;padding:14px;min-height:48px';\r\n gate.append(heading,message,retry);gate.hidden=false;if(!gate.open)gate.showModal();\r\n console.error('Coach startup failed',error);\r\n}\r\nexport async function bootCoach({load,document,timeout=30000}){\r\n const timer=setTimeout(()=>showStartupFailure(document,new Error('Startup timed out.')),timeout);\r\n try{await load();const recovery=document.getElementById('coachStartupRecovery');if(recovery){recovery.close();recovery.hidden=true;}return true;}catch(error){showStartupFailure(document,error);return false;}finally{clearTimeout(timer);}\r\n}\r\nif(typeof document!=='undefined'){\r\n const runtime=new URL('./launch-runtime.mjs',import.meta.url);runtime.search=new URL(import.meta.url).search;\r\n void bootCoach({document,load:()=>import(/* @vite-ignore */ runtime.href)});\r\n}\r\n","launch-shell.mjs":"export function mountLaunch(){document.body.insertAdjacentHTML('beforeend',`\r\n<span id=\"syncBadge\" class=\"sync-badge\" role=\"status\">Connecting…</span>\r\n<nav id=\"coachDock\" class=\"coach-dock ship-control-deck\" aria-label=\"Coach tools\"><button type=\"button\" class=\"dock-continue\" hidden></button><button type=\"button\" class=\"dock-control dock-settings\" data-route=\"customizeCoach\" aria-label=\"Customize coach\" title=\"Customize coach\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><circle cx=\"12\" cy=\"12\" r=\"6.5\"/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9 7 7M17 17l2.1 2.1M4.9 19.1 7 17M17 7l2.1-2.1\"/></svg></span></button><button type=\"button\" class=\"dock-control dock-food\" data-panel=\"meals\" data-route=\"food\" aria-label=\"Food\" title=\"Food\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 8h4l2-3h6l2 3h4v11H3z\"/><circle cx=\"12\" cy=\"13\" r=\"3.5\"/></svg></span></button><button type=\"button\" class=\"dock-portal\" data-route=\"portal\" aria-label=\"Portal or workout pod\" title=\"Portal or workout pod\"><svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 11.5 12 4l9 7.5M5.5 10v10h13V10M10 20v-6h4v6\"/></svg><span aria-hidden=\"true\">PORTAL</span></button><button type=\"button\" class=\"dock-control dock-scoreboard\" data-panel=\"account\" data-route=\"scoreboard\" aria-label=\"Classroom leaderboard\" title=\"Classroom leaderboard\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"9\" cy=\"8\" r=\"3\"/><circle cx=\"17\" cy=\"9\" r=\"2.5\"/><path d=\"M3 20c0-4 3-6 6-6s6 2 6 6M15 14c3 0 6 1.5 6 5\"/></svg></span></button><button type=\"button\" class=\"dock-control dock-achievements\" data-route=\"achievements\" aria-label=\"Achievements\" title=\"Achievements\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7 4h10v5a5 5 0 0 1-10 0zM7 6H3c0 3 1 4 4 4M17 6h4c0 3-1 4-4 4M12 14v4M8 21h8\"/></svg></span></button><button type=\"button\" class=\"dock-control dock-pod\" data-panel=\"reminders\" data-route=\"reminders\" aria-label=\"Reminders computer\" title=\"Reminders computer\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z\"/></svg></span></button><span class=\"dock-live\" role=\"status\" aria-live=\"polite\"></span></nav>\r\n<dialog id=\"historyPanel\" class=\"launch-panel\" aria-labelledby=\"historyTitle\"><header><h2 id=\"historyTitle\">History</h2><button data-close>Close</button></header><p class=\"hint\">Completed workouts saved on this device.</p><p id=\"localHistoryStatus\" role=\"status\"></p><div id=\"localHistoryList\"></div></dialog>\r\n<dialog id=\"mealsPanel\" class=\"launch-panel food-panel\" aria-labelledby=\"mealsTitle\"><header><h2 id=\"mealsTitle\">Food</h2><button data-close>Close</button></header>\r\n<button id=\"foodCamera\" class=\"main-action food-camera\" aria-label=\"Take a food photo\"><svg viewBox=\"0 0 24 24\" width=\"30\" height=\"30\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.8\" aria-hidden=\"true\"><path d=\"M8 5l2-2h4l2 2h4a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"4\"/></svg><span>Camera</span></button>\r\n<input id=\"foodPhoto\" type=\"file\" accept=\"image/jpeg,image/png,image/webp\" capture=\"environment\" hidden>\r\n<div class=\"food-sheet\"><section id=\"foodDial\" class=\"food-dial\" tabindex=\"-1\" aria-labelledby=\"foodDialTitle\" hidden><div class=\"food-dial-head\"><h3 id=\"foodDialTitle\"></h3><button type=\"button\" id=\"foodDialBack\">Back</button></div><div id=\"foodDialBody\"></div></section>\r\n<p id=\"foodStatus\" class=\"hint\" role=\"status\"></p>\r\n<div id=\"mealScanStage\" class=\"meal-scan-stage\" hidden><img id=\"foodPreview\" class=\"meal-preview\" alt=\"Your selected meal\"><div id=\"mealScanOverlay\" class=\"meal-scan-overlay\" data-state=\"ready\"><div class=\"scan-grid\" aria-hidden=\"true\"></div><div class=\"scan-reticle\" aria-hidden=\"true\"></div><div class=\"scan-beam\" aria-hidden=\"true\"></div><div class=\"scan-heading\"><span id=\"scanPhase\">FOOD SCANNER</span><time id=\"scanElapsed\" aria-label=\"Elapsed scan time\">00:00</time></div><div class=\"scan-readout\"><span id=\"scanDetail\"></span><progress id=\"scanProgress\" max=\"100\" aria-label=\"Current model file download\" hidden></progress></div></div></div>\r\n<div class=\"actions scan-actions\"><button id=\"recognizeFood\" hidden>Retry scan</button><button id=\"cancelFoodScan\" hidden>Stop scan</button></div>\r\n<div id=\"foodSuggestions\" class=\"actions\" hidden></div>\r\n<form id=\"mealForm\">\r\n <div id=\"mealConfirmation\" hidden><div class=\"fields\"><label>Food<input name=\"name\" id=\"mealName\" required maxlength=\"160\" autocomplete=\"off\"></label><label>Portion (g)<input id=\"mealGrams\" type=\"number\" min=\"1\" max=\"2000\" step=\"1\" value=\"100\" required></label></div><label id=\"foodReferenceLabel\">Food match<select id=\"foodReference\"></select></label><p id=\"nutritionBasis\" class=\"hint\" role=\"status\">Check food & portion</p></div>\r\n <section aria-labelledby=\"macroTitle\"><h3 id=\"macroTitle\">Macros</h3><div class=\"macro-grid\"><div class=\"nutrient\"><span>Calories</span><output id=\"nutrient-calories\">—</output></div><div class=\"nutrient\"><span>Protein</span><output id=\"nutrient-protein\">—</output></div><div class=\"nutrient\"><span>Carbs</span><output id=\"nutrient-carbs\">—</output></div><div class=\"nutrient\"><span>Fat</span><output id=\"nutrient-fat\">—</output></div></div></section>\r\n <section aria-labelledby=\"microTitle\"><h3 id=\"microTitle\">Micros</h3><div class=\"micro-grid\"><div class=\"nutrient\"><span>Calcium</span><output id=\"nutrient-calcium\">—</output></div><div class=\"nutrient\"><span>Iron</span><output id=\"nutrient-iron\">—</output></div><div class=\"nutrient\"><span>Magnesium</span><output id=\"nutrient-magnesium\">—</output></div><div class=\"nutrient\"><span>Potassium</span><output id=\"nutrient-potassium\">—</output></div><div class=\"nutrient\"><span>Sodium</span><output id=\"nutrient-sodium\">—</output></div><div class=\"nutrient\"><span>Zinc</span><output id=\"nutrient-zinc\">—</output></div><div class=\"nutrient\"><span>Vitamin A</span><output id=\"nutrient-vitaminA\">—</output></div><div class=\"nutrient\"><span>Vitamin C</span><output id=\"nutrient-vitaminC\">—</output></div><div class=\"nutrient\"><span>Vitamin D</span><output id=\"nutrient-vitaminD\">—</output></div><div class=\"nutrient\"><span>Vitamin E</span><output id=\"nutrient-vitaminE\">—</output></div><div class=\"nutrient\"><span>Vitamin B12</span><output id=\"nutrient-vitaminB12\">—</output></div><div class=\"nutrient\"><span>Folate</span><output id=\"nutrient-folate\">—</output></div></div><p class=\"hint nutrient-note\">— unavailable</p></section>\r\n <div id=\"mealSaveControls\" hidden><details id=\"nutritionAdjust\"><summary>Edit nutrition & time</summary><label>Eaten at<input name=\"eatenAt\" type=\"datetime-local\" required></label><div class=\"nutrition manual-nutrition\"><label>Calories (kcal)<input name=\"calories\" type=\"number\" min=\"0\" max=\"20000\" step=\"any\"></label><label>Protein (g)<input name=\"protein\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Carbs (g)<input name=\"carbs\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Fat (g)<input name=\"fat\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Calcium (mg)<input name=\"calcium\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Iron (mg)<input name=\"iron\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Magnesium (mg)<input name=\"magnesium\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Potassium (mg)<input name=\"potassium\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Sodium (mg)<input name=\"sodium\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Zinc (mg)<input name=\"zinc\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Vitamin A (µg RAE)<input name=\"vitaminA\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Vitamin C (mg)<input name=\"vitaminC\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Vitamin D (µg)<input name=\"vitaminD\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Vitamin E (mg)<input name=\"vitaminE\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Vitamin B12 (µg)<input name=\"vitaminB12\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label><label>Folate (µg)<input name=\"folate\" type=\"number\" min=\"0\" max=\"2000000\" step=\"any\"></label></div></details><input name=\"portion\" type=\"hidden\" value=\"100 g\"><button type=\"submit\" id=\"saveMeal\" class=\"main-action\">Save meal</button><button type=\"button\" id=\"cancelMeal\">Cancel</button><p class=\"hint food-source\">Nutrition: <a href=\"https://fdc.nal.usda.gov/\" target=\"_blank\" rel=\"noreferrer\">USDA FoodData Central</a> (public domain) for recognized dishes, <a href=\"https://www.ars.usda.gov/northeast-area/beltsville-md-bhnrc/beltsville-human-nutrition-research-center/methods-and-application-of-food-composition-laboratory/mafcl-site-pages/sr11-sr28/\" target=\"_blank\" rel=\"noreferrer\">USDA SR28</a> estimates otherwise. Photos stay on this device.</p></div>\r\n</form><p id=\"mealStatus\" role=\"status\"></p><details class=\"recent-meals\"><summary>Recent meals</summary><div id=\"mealList\"></div></details></div></dialog>\r\n<dialog id=\"remindersPanel\" class=\"launch-panel\" aria-labelledby=\"remindersTitle\"><header><h2 id=\"remindersTitle\">Reminders</h2><button data-close>Close</button></header><p id=\"pushStatus\" class=\"status\" role=\"status\">Connecting…</p><p id=\"reminderLiveStatus\" class=\"reminder-live\" role=\"status\"></p><div class=\"switch-plate\"><div><strong>THIS DEVICE</strong></div><button id=\"notificationSwitch\" class=\"hardware-toggle\" role=\"switch\" aria-checked=\"false\" aria-label=\"Reminders and app updates on this device\" disabled>OFF</button></div><div class=\"actions\"><button id=\"testPush\">Send a test</button></div><details><summary>Notification help</summary><p>Get reminders and a download notification for each app update, even when Coach is closed. iPhone: install Coach first, then allow notifications.</p></details><form id=\"reminderForm\"><div class=\"fields\"><label>Reminder<select name=\"kind\"><option value=\"workout\">Workout</option><option value=\"meal\">Meal logging</option><option value=\"water\">Water</option><option value=\"motivation\">Encouragement</option></select></label><label>At<input name=\"time\" type=\"time\" required value=\"17:00\"></label></div><section class=\"reminder-tuning\" aria-label=\"MOM reminder controls\"><div class=\"tone-control\"><label id=\"toneDialLabel\">TONE</label><div class=\"tone-dial-row\"><button type=\"button\" id=\"gentlerTone\" aria-label=\"Gentler wording\">−</button><div id=\"toneDial\" class=\"tone-dial\" role=\"slider\" tabindex=\"0\" aria-labelledby=\"toneDialLabel\" aria-valuemin=\"0\" aria-valuemax=\"2\" aria-valuenow=\"1\" aria-valuetext=\"direct\"><i aria-hidden=\"true\"></i></div><button type=\"button\" id=\"cheekierTone\" aria-label=\"Cheekier wording\">+</button></div><output id=\"toneValue\">Direct</output><div class=\"tone-scale\" aria-hidden=\"true\">GENTLE · DIRECT · CHEEKY</div><input type=\"hidden\" name=\"tone\" value=\"direct\"></div><div class=\"consistency-control\"><label for=\"consistencySlider\">FREQUENCY</label><output id=\"consistencyValue\" for=\"consistencySlider\">Every day</output><input id=\"consistencySlider\" type=\"range\" min=\"0\" max=\"3\" step=\"1\" value=\"3\" aria-valuetext=\"Every day\"><div class=\"cadence-scale\" aria-hidden=\"true\"><span>1 / WK</span><span>3 / WK</span><span>5 / WK</span><span>DAILY</span></div><input type=\"hidden\" name=\"daysPerWeek\" value=\"7\"></div><div class=\"message-preview\"><small>MOM WILL SAY</small><p id=\"reminderPreview\"></p></div></section><label>Time zone<input name=\"timezone\" required></label><div class=\"fields\"><label>Quiet hours begin<input name=\"quietStart\" type=\"time\" required value=\"22:00\"></label><label>Quiet hours end<input name=\"quietEnd\" type=\"time\" required value=\"07:00\"></label></div><label class=\"switch-label\">Reminder on<input name=\"enabled\" type=\"checkbox\" role=\"switch\" checked></label><button type=\"submit\" id=\"saveReminder\" class=\"main-action\">Save reminder</button><button type=\"button\" id=\"cancelReminderEdit\" hidden>Cancel edit</button></form><p id=\"reminderStatus\" role=\"status\"></p><div id=\"reminderList\"></div></dialog>\r\n<dialog id=\"accountPanel\" class=\"launch-panel accomplishments-panel\" aria-labelledby=\"accountTitle\">\r\n <header><div><h2 id=\"accountTitle\">Crew scoreboard</h2></div><button data-close>Done</button></header>\r\n <a id=\"signIn\" class=\"action-link main-action\" href=\"/signin.html?return_to=%2Fpose.html\" target=\"_top\">Sign in to Coach</a>\r\n <div id=\"accountContent\" hidden>\r\n  <section class=\"crew-invites\" aria-labelledby=\"crewInviteTitle\"><h3 id=\"crewInviteTitle\">Invite friends</h3><div id=\"scoreboardCrew\" class=\"scoreboard-crew\"></div>\r\n   <details id=\"crewInviteControls\"><summary>Add friends</summary><p>Shares your name, Gala look and best sets. Disconnect any time.</p><button type=\"button\" id=\"createCrewInvite\">Create invite code</button><button type=\"button\" id=\"revokeCrewInvite\" hidden>Cancel invite</button>\r\n    <div id=\"crewInviteOutput\" hidden><label>One-use code<input id=\"crewInviteCode\" readonly autocomplete=\"off\" spellcheck=\"false\"></label><button type=\"button\" id=\"copyCrewInvite\">Copy code</button></div>\r\n    <form id=\"crewJoinForm\"><label>Have a friend’s code?<input id=\"crewJoinCode\" autocomplete=\"off\" spellcheck=\"false\" placeholder=\"Paste their invite code\" maxlength=\"40\" required></label><button type=\"submit\" id=\"crewJoin\">Connect & share best sets</button></form>\r\n   </details><p id=\"crewStatus\" role=\"status\"></p>\r\n  </section>\r\n  <div class=\"progress-summary\"><div><output id=\"accountLevel\">Level 1</output><span id=\"accountSets\">0 completed sets</span></div><button id=\"refreshAccount\" aria-label=\"Refresh your records\">↻ Refresh</button></div>\r\n  <div class=\"scoreboard-heading\"><div><h3 id=\"scoreboardGroup\">Chest</h3><p id=\"scoreboardSubtitle\">Push-up progressions</p></div><div class=\"medal-key\" aria-label=\"Rank colors\"><span data-medal=\"gold\">1 Gold</span><span data-medal=\"silver\">2 Silver</span><span data-medal=\"bronze\">3 Bronze</span></div></div>\r\n  <p id=\"recordsStatus\" class=\"hint\" role=\"status\">Loading your records…</p><div id=\"boardCanvas\"><div id=\"workoutList\"></div><div id=\"boardMovingPen\" aria-hidden=\"true\" hidden><i class=\"marker-eraser\"></i><i class=\"marker-tip\"></i></div></div>\r\n  <section class=\"unlock-board\" aria-labelledby=\"unlockTitle\"><h3 id=\"unlockTitle\">Game unlocks</h3><ul id=\"rewardList\"></ul></section>\r\n </div>\r\n <details class=\"account-settings\"><summary>Account & appearance</summary><p id=\"accountName\"></p><p id=\"accountStatus\" class=\"hint\" role=\"status\"></p>\r\n  <div id=\"accountSettingsContent\" hidden><div class=\"actions\"><button id=\"saveProfile\">Save appearance</button><button id=\"restoreProfile\">Restore appearance</button></div>\r\n   <h3>Your data</h3><div class=\"actions\"><button id=\"exportData\">Download my data</button><a id=\"signOut\" class=\"action-link\" href=\"/pose.html\" target=\"_top\">Sign out</a></div>\r\n   <details><summary>Delete Coach data</summary><p>This deletes your Coach progress, meals, reminders and saved appearance from this account.</p><label>Type DELETE<input id=\"deleteConfirm\" autocomplete=\"off\"></label><button id=\"deleteAccount\" class=\"danger\">Delete Coach data</button></details>\r\n  </div><p class=\"hint\"><a href=\"/privacy.html\">Privacy</a> · <a href=\"/source.json.gz\" download>App source (.json.gz)</a> · <a href=\"/LICENSE\">License</a></p>\r\n </details>\r\n <nav id=\"scoreboardMarkers\" class=\"marker-tray\" aria-label=\"Exercise focus markers\"></nav>\r\n</dialog>\r\n<dialog id=\"installPanel\" class=\"launch-panel\" aria-labelledby=\"installTitle\"><header><h2 id=\"installTitle\">Install Coach</h2><button data-close>Close</button></header><p id=\"installStatus\" class=\"status\" role=\"status\"></p><button id=\"installApp\" class=\"main-action\" hidden>Add to home screen</button><details><summary>Install steps</summary><p>iPhone: Safari → Share → Add to Home Screen.</p><p>Android: browser menu → Install app.</p></details><h3>Coach voice</h3><p>Deep robot voice</p><p class=\"hint\">Download for offline voice.</p><button id=\"downloadVoice\">Download voice</button><p id=\"downloadStatus\" role=\"status\"></p><button id=\"applyUpdate\" hidden>Install ready update</button></dialog>\r\n`);{const sound=document.getElementById('toggleVoice')?.closest('.cb-part');if(sound){sound.classList.add('dock-sound');sound.querySelector('button').classList.add('dock-control');document.getElementById('coachDock').append(sound);}}for(const close of document.querySelectorAll('[data-close]'))close.onclick=()=>close.closest('dialog').close();for(const button of document.querySelectorAll('[data-panel]')){const panel=document.getElementById(button.dataset.panel+'Panel');button.setAttribute('aria-haspopup','dialog');button.setAttribute('aria-expanded','false');panel.addEventListener('close',()=>button.setAttribute('aria-expanded','false'));button.onclick=(event)=>{if(panel.open){event.stopPropagation();panel.close();button.setAttribute('aria-expanded','false');return;}document.getElementById('stop')?.click();panel.showModal();button.setAttribute('aria-expanded','true');};}}\r\n","launch.css":"/* W2-2A (#5): one bottom bar on every route (routes.mjs). Fixed to the bottom; inside a route's dialog while it is\r\n   open (a modal makes everything outside it inert), so it is styled by id + all:unset to shrug off dialog button rules\r\n   (and !important where a dialog forces one, e.g. the Settings terminal's square corners). */\r\n:root{--myr5-bar:calc(88px + env(safe-area-inset-bottom))} /* R20: one dock console height for every page (portal.css draws it); 64px on landscape phones, below */\r\n@media(orientation:landscape) and (max-height:500px){:root{--myr5-bar:calc(64px + env(safe-area-inset-bottom))}} /* R20: a lower console on landscape phones, every page alike */\r\n#coachDock.coach-dock{position:fixed;inset:auto 0 0;z-index:40;box-sizing:border-box;width:auto;height:var(--myr5-bar);margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr)) 58px repeat(3,minmax(0,1fr));align-items:center;gap:3px;padding:0 6px env(safe-area-inset-bottom);border:0;border-top:1px solid #685077;border-radius:0;background:#171123f2;box-shadow:0 -6px 18px #08050f99;font:600 12px/1.1 system-ui,sans-serif}@media(max-width:400px){#coachDock.coach-dock{font-size:11px}}\r\n#coachDock.coach-dock button{all:unset;box-sizing:border-box;display:flex;align-items:center;justify-content:center;min-width:0;height:46px;padding:0 1px;border:1px solid #70547c;border-radius:9px!important;background:#30223e;color:#f2deab;font:inherit;text-align:center;hyphens:auto;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent;transition:box-shadow .15s,background-color .15s}\r\n#coachDock.coach-dock button:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n#coachDock.coach-dock button[aria-current=page]{color:#fff7e0;border-color:#ffb24d;background:#4d305f;box-shadow:0 0 0 1px #ffb24d,0 0 14px #ffb24d80}\r\n#coachDock.coach-dock .dock-portal{justify-self:center;width:56px;height:56px;padding:0;border:0;border-radius:50%!important;color:#fff;letter-spacing:.3px;background:radial-gradient(circle,#1c1428 0 60%,transparent 62%),conic-gradient(#ff5f1f,#ffff33,#39ff14,#1f51ff,#b026ff,#ff10f0,#ff5f1f);box-shadow:0 0 12px #b026ff80}\r\n#coachDock.coach-dock .dock-portal[aria-current=page]{background:radial-gradient(circle,#2c1d3d 0 60%,transparent 62%),conic-gradient(#ff5f1f,#ffff33,#39ff14,#1f51ff,#b026ff,#ff10f0,#ff5f1f);box-shadow:0 0 0 2px #fff,0 0 18px #ff10f0,0 0 30px #1f51ffaa}\r\n#coachDock .dock-live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\r\n#coachDock.coach-dock[data-hint]:before{content:attr(data-hint);position:absolute;left:50%;bottom:calc(100% + 10px);transform:translateX(-50%);padding:8px 14px;border-radius:999px;background:#1c1428f2;border:1px solid #ffffff44;color:#f5eaff;white-space:nowrap;font-size:13px;box-shadow:0 4px 16px #0008}\r\n/* #19: a Continue chip above the bar, same pill look as the [data-hint] hint above. It sits higher than that\r\n   hint (+40px, not +10px): on the quilt the metal frame leaves only ~16px clear above the bar including its\r\n   rail, not enough for a real button, so the chip floats over the framed glass clear of the frame and rail. */\r\n#coachDock.coach-dock .dock-continue{position:absolute;left:50%;bottom:calc(100% + 40px);transform:translateX(-50%);padding:8px 14px;border-radius:999px;background:#1c1428f2;border:1px solid #ffffff44;color:#f5eaff;white-space:nowrap;font-size:13px;font-weight:600;box-shadow:0 4px 16px #0008;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}\r\n#coachDock.coach-dock .dock-continue:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n#coachDock.coach-dock .dock-continue[hidden]{display:none}\r\nbody[data-tracking=true] #coachDock.coach-dock,body[data-screen=rest] #coachDock.coach-dock{display:none}\r\nbody:has(#coachDock){padding-bottom:calc(var(--myr5-bar) + 12px)}\r\nbody:has(#coachDock) .armie-inbox-launcher,body:has(#coachDock) .app-update-banner{bottom:calc(var(--myr5-bar) + 10px)}\r\n/* A route's dialog is sized to leave the bar showing (full-screen scenes stop at its top edge). */\r\ndialog[data-route][open]{bottom:var(--myr5-bar);max-height:calc(100dvh - var(--myr5-bar) - 16px)}\r\ndialog[data-route][open]:is(.ach-board,.meditation-panel,.ship-view,#library){height:calc(100dvh - var(--myr5-bar));max-height:none}\r\n.launch-panel button:focus-visible{outline:3px solid #ffb24d;outline-offset:3px}\r\n.launch-panel{color:#f7eefc;background:#21172f;border:1px solid #8b679c;border-radius:16px;width:min(620px,calc(100% - 24px));max-height:85dvh;padding:22px;box-sizing:border-box;font:16px/1.5 system-ui}.launch-panel::backdrop{background:#08050fc9}.launch-panel header{display:flex;justify-content:space-between;align-items:center;gap:16px;margin-bottom:20px}.launch-panel h2{font-size:24px;margin:0;color:#f4d49b}.launch-panel h3{font-size:18px;margin:24px 0 10px}.launch-panel p{color:#d8c9e0;margin:10px 0}.launch-panel button,.launch-panel .action-link{font:inherit;min-height:44px;border:1px solid #886797;border-radius:8px;background:#382548;color:#fcecd0;padding:9px 14px;cursor:pointer;text-decoration:none;display:inline-flex;align-items:center;justify-content:center}.launch-panel button:disabled{opacity:.5;cursor:wait}.launch-panel .main-action{background:#eea954;color:#231429;border-color:#ffc779;font-weight:650}.launch-panel form{display:grid;gap:14px}.launch-panel label{display:grid;gap:6px;color:#e7d7ed;font-size:14px}.launch-panel input,.launch-panel select{font:inherit;font-size:16px;box-sizing:border-box;max-width:100%;width:100%;border:1px solid #77568a;border-radius:7px;background:#140d20;color:#fff3e1;padding:11px}.launch-panel .fields{display:grid;grid-template-columns:1fr 1fr;gap:12px}.launch-panel .actions{display:flex;gap:8px;flex-wrap:wrap}.launch-panel .hint{font-size:14px;color:#beaccb}.launch-panel .status{padding:10px 12px;border-left:3px solid #efa952;background:#31223e;min-height:22px}.launch-panel .entry{padding:14px 0;border-bottom:1px solid #594166;display:flex;justify-content:space-between;gap:16px;align-items:center}.launch-panel .entry small{display:block;color:#c9b5d3;font-size:14px}.launch-panel img.meal-preview{display:block;width:100%;height:180px;object-fit:contain;background:#120b1b;border-radius:8px;margin:12px 0}.launch-panel [hidden]{display:none!important}.launch-panel .nutrition{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.launch-panel a{color:#ffd59d}.launch-panel output{font-size:22px;font-weight:700;color:#ffcd87}.sync-badge{font:12px system-ui;color:#d6b6e3;display:block;text-align:center;padding:4px}.launch-panel progress{width:100%;accent-color:#eea954}.launch-panel .reward{padding:14px;border:1px solid #72527c;border-radius:10px;margin:10px 0;background:#2c1e3c}.launch-panel .reward[data-unlocked=true]{border-color:#dfa858}.launch-panel .danger{border-color:#c88489;color:#ffd5d8}\r\n@media(max-width:420px){.launch-panel{padding:16px}.launch-panel .nutrition{grid-template-columns:1fr 1fr}.launch-panel .fields{grid-template-columns:1fr}}\r\n.progress-eyebrow{display:block;font:11px ui-monospace,monospace;letter-spacing:2px;color:#bba3c6;margin-bottom:5px}\r\n.accomplishments-panel header{margin-bottom:18px;gap:10px}.accomplishments-panel h2{font-size:clamp(21px,6vw,27px);letter-spacing:-.6px}\r\n.progress-summary{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:16px;border-bottom:1px solid #644774}\r\n.progress-summary output,.progress-summary #accountSets{display:block}.progress-summary #accountSets{font-size:13px;color:#c7b0d2;margin-top:3px}.progress-summary button{font-size:13px}\r\n.accomplishments-panel .record-intro{margin:16px 0 5px}.accomplishments-panel #recordsStatus{font-size:13px}.accomplishments-panel #recordsStatus:empty{display:none}\r\n.record-board{margin-top:22px}.record-heading{display:flex;justify-content:space-between;align-items:baseline;gap:12px;border-bottom:2px solid #80618c;padding-bottom:8px}\r\n.record-heading h3{margin:0;font-size:17px;color:#f5d49e}.record-heading>span{font-size:12px;color:#c1aaca;text-align:right;font-variant-numeric:tabular-nums}\r\n.record-board table{width:100%;border-collapse:collapse;table-layout:fixed;font-variant-numeric:tabular-nums;font-size:14px}\r\n.record-board thead th{font-size:10px;text-transform:uppercase;letter-spacing:.7px;font-weight:500;color:#b59bc2;padding:9px 4px 5px;text-align:right}\r\n.record-board thead th:first-child{font-size:0;width:27px}.record-board thead th:nth-child(2){text-align:left;width:41%}.record-board thead th:last-child{width:35px}\r\n.record-board td,.record-board tbody th{padding:12px 4px;border-bottom:1px solid #52395e;text-align:right}.record-board tbody th{text-align:left;font-weight:500;overflow-wrap:anywhere}\r\n.record-board .record-rank{text-align:left;font:12px ui-monospace,monospace;color:#b39bbb}.record-board .record-best{font-size:19px;font-weight:700;letter-spacing:-.6px;color:#ffdb9a}\r\n.record-board tbody td:last-child{font-size:13px;color:#c9b3d4}.record-board tr[data-record=false]{color:#b39bbb}.record-board tr[data-record=false] .record-best{color:#967e9f}\r\n.unlock-board{margin-top:26px}.unlock-board h3{font-size:17px;margin:0 0 6px;color:#f5d49e}.unlock-board ul{padding:0;list-style:none;margin:0}\r\n.unlock-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:11px 0;border-bottom:1px solid #52395e;font-size:14px}.unlock-row>span:last-child{font-size:12px;color:#bda6c9}.unlock-row[data-unlocked=true]>span:last-child{color:#f5cf87}\r\n.account-settings{margin-top:25px;padding-top:8px;border-top:1px solid #6c4b7b}.account-settings summary{cursor:pointer;min-height:44px;align-content:center;font-size:14px;color:#cebad9}.account-settings p{overflow-wrap:anywhere}.account-settings .actions{margin:12px 0}.account-settings .hint{font-size:13px}\r\n/* D34 post-download package: the Downloads menu (its own full-screen page), progress strip, Install section and body note; see post-download.mjs. */\r\n.downloads-menu{position:fixed;inset:0;margin:0;width:100vw;height:100dvh;max-width:none;max-height:none;box-sizing:border-box;padding:0;border:0;background:#163e34;color:#eefff5;font:16px/1.45 Arial,sans-serif;flex-direction:column}\r\n.downloads-menu[open]{display:flex}.downloads-menu::backdrop{background:#163e34}\r\n.downloads-page{flex:1;min-height:0;overflow-y:auto;width:min(620px,100%);margin:0 auto;padding:max(20px,env(safe-area-inset-top)) 16px 12px;box-sizing:border-box}\r\n.downloads-menu h2{margin:0 0 8px;font-size:26px;line-height:1.2}.downloads-menu p{margin:0 0 12px}.downloads-menu .hint{color:#cfe9dc}\r\n.downloads-menu fieldset{border:0;margin:0;padding:0;min-width:0}.downloads-menu legend{padding:0;margin-bottom:4px;font:700 13px Arial,sans-serif;letter-spacing:1px;text-transform:uppercase;color:#cfe9dc}\r\n.download-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:12px;min-height:56px;padding:10px 0;border-bottom:1px solid #2f6b5a;cursor:pointer}\r\n.download-row strong{font-size:17px}.download-row small{display:block;font-size:14px;line-height:1.35;color:#cfe9dc}.download-row b{font-size:14px;white-space:nowrap;font-variant-numeric:tabular-nums}.download-row[data-saved=true] b{color:#b8f0cf}\r\n.download-row em{display:inline-block;margin-left:8px;padding:1px 8px;border-radius:99px;background:#b8f0cf;color:#10281f;font:700 12px/1.5 Arial,sans-serif;font-style:normal;vertical-align:2px}.download-row em[data-lock]{background:transparent;color:#f2deab;border:1px solid #f2deab}.download-row em[hidden]{display:none}\r\n.download-row input{appearance:none;flex:none;position:relative;width:48px;height:28px;margin:0;border:2px solid #a6d4bb;border-radius:99px;background:#0f2a23;cursor:pointer}\r\n.download-row input::before{content:'';position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#a6d4bb;transition:transform .15s}\r\n.download-row input:checked{background:#b8f0cf;border-color:#b8f0cf}.download-row input:checked::before{transform:translateX(20px);background:#10281f}.download-row input:indeterminate{border-color:#b8f0cf}.download-row input:indeterminate::before{transform:translateX(10px);background:#b8f0cf}\r\n.download-row input:disabled{opacity:.6;cursor:default}.download-row input:focus-visible,.downloads-menu button:focus-visible,.downloads-menu summary:focus-visible{outline:3px solid #fff;outline-offset:3px}\r\n.download-bodies details{margin-left:20px}.download-bodies summary{min-height:44px;align-content:center;cursor:pointer;color:#cfe9dc}.download-bodies details .download-row{min-height:48px}.download-bodies details strong{font-size:16px}\r\n.downloads-footer{padding:12px 16px max(16px,env(safe-area-inset-bottom));border-top:2px solid #a6d4bb;background:#10302a}.downloads-footer>*{max-width:588px;margin-left:auto;margin-right:auto}\r\n.downloads-footer [data-total]{margin-bottom:10px;font-weight:700}.downloads-footer .actions{display:flex;gap:10px}\r\n.downloads-footer .actions button{min-height:48px;padding:10px 18px;border-radius:10px;font:700 16px Arial,sans-serif}\r\n.downloads-footer [data-download]{flex:1 1 60%;background:#b8f0cf;color:#10281f;border:0}.downloads-footer [data-download]:disabled{opacity:.55}.downloads-footer [data-download][hidden]{display:none}.downloads-footer [data-later]{flex:1 1 30%;background:transparent;color:#eefff5;border:2px solid #a6d4bb}\r\n.downloads-status{margin-bottom:10px}.downloads-status[hidden]{display:none}.downloads-status p{margin:0 0 6px}.downloads-status span{display:block;font-size:14px}\r\n.downloads-status button{min-height:44px;margin-top:6px;padding:8px 14px;border:2px solid #a6d4bb;border-radius:9px;background:transparent;color:#eefff5;font:700 14px Arial,sans-serif}.downloads-status button[hidden]{display:none}\r\n@media (prefers-reduced-motion:reduce){.download-row input::before{transition:none}}\r\n.full-download-bar button:focus-visible{outline:3px solid #fff;outline-offset:3px}\r\n.full-download-bar{position:fixed;top:max(8px,env(safe-area-inset-top));left:12px;right:12px;z-index:9998;display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px;padding:10px 12px;background:#163e34;color:#eefff5;border:2px solid #a6d4bb;border-radius:12px;box-shadow:0 8px 30px #0009;font:14px/1.3 Arial,sans-serif}\r\n/* Not over the quilt either: the portal makes the page behind it inert, so its Pause would look tappable and not be. Settings > Downloads shows the same progress. */\r\n.full-download-bar[hidden],body[data-tracking=true] .full-download-bar,body[data-screen=rest] .full-download-bar,body:has(#portalHome:not([hidden])) .full-download-bar{display:none}\r\n.full-download-bar p{margin:0;flex:1 1 100%}.full-download-bar span{flex:1}.full-download-bar button{min-height:44px;padding:8px 12px;font:14px Arial,sans-serif}\r\n.full-download-bar progress,.full-download-settings progress,.downloads-status progress{display:block;width:100%;height:10px;accent-color:#b8f0cf}.full-download-bar progress[hidden],.full-download-settings progress[hidden],.downloads-status progress[hidden]{display:none}\r\n.full-download-settings{margin-top:20px;border-top:1px solid #917885;padding-top:8px;font:16px/1.5 Arial,sans-serif}.full-download-settings span{display:block;font-size:14px}\r\n.post-download-sections{margin-top:18px;padding-top:14px;border-top:1px solid #917885}.post-download-sections[hidden]{display:none}.post-download-sections h3{margin:0 0 6px}.post-download-sections p{margin:0 0 8px}.post-download-sections [data-actions]{display:flex;flex-wrap:wrap;gap:8px}.post-download-sections button{min-height:44px;padding:8px 12px;border:1px solid #a6d4bb;border-radius:9px;background:#244f43;color:#eefff5;font:700 14px Arial,sans-serif}.post-download-sections button:focus-visible{outline:3px solid #fff;outline-offset:3px}.post-download-sections progress{display:block;width:100%;height:10px;accent-color:#b8f0cf}.post-download-sections progress[hidden]{display:none}\r\n.full-download-settings [data-open]{display:block;min-height:44px;margin:4px 0 8px}.full-download-settings [data-toggle][hidden]{display:none}\r\n.body-download-note{position:fixed;left:50%;top:max(12px,env(safe-area-inset-top));transform:translateX(-50%);z-index:9999;pointer-events:none;width:max-content;max-width:calc(100vw - 32px);box-sizing:border-box;margin:0;padding:10px 16px;border:2px solid #a6d4bb;border-radius:18px;background:#163e34;color:#eefff5;font:14px/1.3 Arial,sans-serif;text-align:center}.body-download-note[hidden]{display:none}\r\n","launch.mjs":"import {initSpotifyTerminal} from './spotify-terminal.mjs';\r\nimport {mountCoachPathPicker} from './coach-path-picker.mjs';\r\nimport {recordDailyActivity,readPerformanceProgress,localDay,mergeVerifiedPerformance} from './performance-progress.mjs';\r\nimport {createPerformanceAccountSync} from './performance-account-sync.mjs';\r\nimport {cosmeticLevel} from './progression-rules.mjs';\r\nimport {createAccountReadinessRefresh} from './account-readiness-client.mjs';\r\nimport {createImportAccountAdapter} from './local-coach/import-account-adapter.mjs';\r\nimport {mountGuestHistoryChoice} from './guest-history-choice.mjs';\r\nimport {authTransitions} from './auth-transition.mjs';\r\nimport {createAccountWorkoutSync,accountPendingKey,validateAccountDeletionReceipt} from './account-workout-sync.mjs';\r\nimport {VOICE_MANIFEST,VOICE_CACHE} from './robot-audio.mjs';\r\nimport {initAppUpdates} from './app-updates.mjs';\r\nimport {mountPostDownload} from './post-download.mjs';\r\nimport {mountCoachHub,mountSatcomFrame} from './coach-hub.mjs';\r\nimport {authFetch,signOut} from './auth-client.mjs';\r\nimport {mountCreatureSkinRewardReveal} from './creature-skin-reward-reveal.mjs';\r\nimport {mountRewardPacks} from './reward-pack-ui.mjs';\r\nimport {mountCosmeticRewardReveal} from './cosmetic-reward-reveal.mjs';\r\n\r\nimport {mountGalaReturn} from './gala-handoff.mjs';\r\nimport {mountMeditation} from './meditation.mjs';\r\nimport {applyCoachAccount,applyLocalCoach,clearCoachAccount} from './coach-profile.mjs';\r\nimport {openLocalCoach} from './local-coach-runtime.mjs';\r\nimport {mountLaunch} from './launch-shell.mjs?v=quick-install-v1';\r\nimport {mountRemindersComputer} from './modules/rooms/reminders-computer.mjs';\r\nimport {mountScoreboard} from './scoreboard.mjs';\r\nimport {mountMealNutrition} from './meal-nutrition.mjs';\r\nimport {MACROS,MICROS,displayNutrient} from './nutrition.mjs';\r\nimport {mealsOn,todayTiles} from './food/pyramid-tiles.mjs';\r\nimport {mountLiveReminders} from './reminder-live.mjs';\r\nimport {notificationBinding} from './device-notifications.mjs';\r\nimport {mountMealScanner} from './meal-scanner.mjs';\r\nimport {mountReminderControls} from './reminder-controls.mjs';\r\nimport {CADENCE_LABELS} from './reminder-settings.mjs';\r\nimport {hasPackGrant} from './packs/pack-entitlements.mjs';\r\nimport {createPackGrantCache} from './packs/pack-grant-cache.mjs';\r\nimport {subscribePush,staleSubscription} from './push-subscribe.mjs';\r\nconst accountTransitions=authTransitions();\r\nmountLaunch();\r\ninitSpotifyTerminal({request:authFetch,getAccount:()=>account});\r\nmountRemindersComputer();\r\nmountCreatureSkinRewardReveal();\r\nmountCosmeticRewardReveal();\r\nmountRewardPacks();\r\nmountCoachHub({api});\r\nmountGalaReturn();\r\nmountMeditation({api,onComplete:refresh,getAccount:()=>account});\r\nmountMealScanner();\r\nconst mealNutrition=mountMealNutrition();\r\nconst reminderControls=mountReminderControls();\r\nwindow.addEventListener('myr5:reminder-defaults',e=>reminderControls.load(e.detail.tone,e.detail.days));\r\nlet editingReminder=null;\r\nconst $=id=>document.getElementById(id),keys=['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1','myr5-pod-power-v1','handborne-recipe-v4','mbs-dj-identity-v1'];\r\nlet account=null,revision=0,registration=null,installPrompt=null,reminderSnapshot=null,deviceBusy=false,packGrantCache=null;\r\nwindow.addEventListener('myr5:login-ready',()=>{queueMicrotask(()=>{if(account===null && !accountTransitionBusy){void refresh().catch(()=>{});} });});\r\nlet localHistoryRepository=null,guestHistoryChoice=null,accountTransitionBusy=false;\r\nmountCoachPathPicker({getAccount:()=>account,savePaths:async(paths,expected)=>{\r\n if(accountTransitionBusy||account?.user?.id!==expected.user.id||account?.dataEpoch!==expected.dataEpoch)throw Error('Account changed. Refresh and try again.');\r\n return api('/api/performance/paths','POST',{paths},{'X-Target-Account':expected.user.id,'X-Expected-Data-Epoch':String(expected.dataEpoch)});\r\n},onChosen:()=>{void refresh();}});\r\nlet expansionMounted=false;\r\nasync function mountVerifiedExpansion(value){\r\n if(expansionMounted||!hasPackGrant(value,'mom-paper-tear')||!window.myr5WorkoutOwner)return;\r\n expansionMounted=true;\r\n try{\r\n  const {mountExpansion}=await import('./modules/new/expansion-entry.mjs');\r\n  const result=mountExpansion({account:value,workoutOwner:window.myr5WorkoutOwner});\r\n  if(!result)expansionMounted=false;\r\n }catch(error){expansionMounted=false;console.warn('Optional expansion unavailable',error);}\r\n}\r\nwindow.addEventListener('myr5:account-ready',event=>{void mountVerifiedExpansion(event.detail);});\r\nwindow.addEventListener('myr5:workout-owner-ready',()=>{const owner=account||packGrantCache?.active();if(owner)void mountVerifiedExpansion(owner);});\r\nconst scoreboard=mountScoreboard({api,getAccount:()=>account});\r\nconst deviceBinding=notificationBinding(api);\r\nconst liveReminders=mountLiveReminders({refresh,read:reminders,getAccount:()=>account,deviceReady:()=>deviceBinding.ready(account?.user.id)});\r\nconst set=(id,text)=>$(id).textContent=text;\r\nexport async function api(path,method='GET',data,headers={}){const ticket=accountTransitions.capture(),assertions={...headers};if(!['GET','HEAD'].includes(method)&&(/^\\/api\\/(?:reminders(?:\\/|$)|push\\/|profile$|goals(?:\\/|$)|meals(?:\\/|$)|onboarding$|breathing\\/|scoreboard(?:\\/|$))/.test(path)||path==='/api/updates/subscription')){const captured=account;const has=name=>Object.keys(assertions).some(key=>key.toLowerCase()===name.toLowerCase());if((!has('X-Target-Account')||!has('X-Expected-Data-Epoch'))&&(!captured?.user?.id||!Number.isSafeInteger(captured.dataEpoch)||captured.dataEpoch<1))throw Error('Refresh your account before saving.');if(!has('X-Target-Account'))assertions['X-Target-Account']=captured.user.id;if(!has('X-Expected-Data-Epoch'))assertions['X-Expected-Data-Epoch']=String(captured.dataEpoch);}const response=await authFetch(path,{method,guestSkip:method==='GET'&&/^\\/api\\/(?:account\\?core=1|updates\\/subscription|reminders(?:\\/plan)?|meals)$/.test(path),signal:ticket.signal,credentials:'same-origin',headers:{...(data?{'Content-Type':'application/json'}:{}),...assertions},body:data?JSON.stringify(data):undefined,cache:'no-store'});accountTransitions.assertCurrent(ticket);if(response.redirected||!response.headers.get('content-type')?.includes('application/json'))throw Error('Sign in to Coach again to reconnect.');const value=await response.json();accountTransitions.assertCurrent(ticket);if(!response.ok)throw Object.assign(Error(value.error||'Please try again.'),{status:response.status,code:value.code});return value;}\r\nconst button=(text,fn)=>{const b=document.createElement('button');b.type='button';b.textContent=text;b.onclick=fn;return b;};\r\nfunction download(data,name,type='application/json'){const a=document.createElement('a'),url=URL.createObjectURL(new Blob([data],{type}));a.href=url;a.download=name;a.click();setTimeout(()=>URL.revokeObjectURL(url),10000);}\r\nfunction publishProgress(p){\r\n if(account)mergeVerifiedPerformance({...account,progress:p});\r\n window.coachProgress=p;if(account)account.progress=p;window.dispatchEvent(new CustomEvent('myr5:account-progress',{detail:p}));\r\n const earned=readPerformanceProgress();set('accountLevel',`Level ${cosmeticLevel(earned.totalXp).level}`);set('accountSets',`${p.completedSets} completed sets`);$('rewardList').replaceChildren();\r\n for(const [label,count] of [['Coaches',earned.coaches.length],['Golden coaches',earned.goldenCoaches.length],['Weapon families',Object.keys(earned.weapons).length],['Ships',earned.ships.length]]){const row=document.createElement('li');row.className='unlock-row';const name=document.createElement('span'),value=document.createElement('span');name.textContent=label;value.textContent=String(count);row.append(name,value);$('rewardList').append(row);}\r\n}\r\nconst optionalReadiness=createAccountReadinessRefresh({api,transitions:accountTransitions,getAccount:()=>account,apply:observation=>{if(!account)return;Object.assign(account,observation);const push=account.push;set('pushStatus',push.environment==='preview'?'Local preview · open the live app to connect notifications.':push.schedulerActive&&(!push.status||['ready','available'].includes(push.status))?'Online reminder sender is running. Enable notifications on each device.':'The reminder sender is connecting or temporarily unavailable. Try again shortly.');liveReminders.render();}});\r\nasync function refresh(){if(accountTransitionBusy)return null;let ticket;try{ticket=accountTransitions.beginRefresh();const value=await api('/api/account?core=1');if(!accountTransitions.isCurrent(ticket))return null;if(account&&(account.user.id!==value.user.id||account.dataEpoch!==value.dataEpoch)){accountTransitions.invalidate();return refresh();}account=value;revision=value.revision;packGrantCache?.confirm(value);mergeVerifiedPerformance(value);applyCoachAccount(value);$('signIn').hidden=true;$('accountContent').hidden=false;$('accountSettingsContent').hidden=false;set('accountName',value.user.provider==='clerk'?(window.Clerk?.user?.primaryEmailAddress?.emailAddress||value.user.email):value.user.email);publishProgress(value.progress);set('accountStatus','Progress synced');set('syncBadge','Synced');set('pushStatus',value.push.environment==='preview'?'Local preview · open the live app to connect notifications.':value.push.schedulerActive&&(!value.push.status||['ready','available'].includes(value.push.status))?'Online reminder sender is running. Enable notifications on each device.':'The reminder sender is connecting or temporarily unavailable. Try again shortly.');void optionalReadiness.refresh();await syncDeviceSwitch();if(!accountTransitions.isCurrent(ticket))return null;await flushSets();if(!accountTransitions.isCurrent(ticket))return null;return value;}catch(e){if(!ticket||!accountTransitions.isCurrent(ticket))return null;if(e.status===401){account=null;packGrantCache?.deactivate();scoreboard.clear();clearCoachAccount();$('signIn').hidden=false;$('accountContent').hidden=true;$('accountSettingsContent').hidden=true;$('workoutList').replaceChildren();$('mealList').replaceChildren();$('reminderList').replaceChildren();reminderSnapshot=null;liveReminders.update([]);await syncDeviceSwitch();if(!accountTransitions.isCurrent(ticket))return null;set('accountName','Sign in to sync');set('syncBadge','Sign in to save progress');}else {if(account)account.push={...account.push,schedulerActive:false};liveReminders.render();set('syncBadge',navigator.onLine?e.message:'Offline · reconnect to sync');if(account)account={...account,stale:true};else {const cached=packGrantCache?.active();if(cached)void mountVerifiedExpansion(cached);}}return null;}}\r\nlet accountStorage;try{accountStorage=localStorage;}catch{}\r\npackGrantCache=createPackGrantCache({storage:accountStorage});\r\nconst accountWorkoutSync=createAccountWorkoutSync({storage:accountStorage,api,transitions:accountTransitions,getAccount:()=>account,publishProgress});\r\nconst performanceAccountSync=createPerformanceAccountSync({storage:accountStorage,api,transitions:accountTransitions,getAccount:()=>account,maxUploads:120,getRows:async()=>{localHistoryRepository??=await openLocalCoach();return localHistoryRepository.forOwner(localHistoryRepository.guestOwnerId).listWorkouts();},onAccount:value=>publishProgress(value.progress)});\r\nwindow.addEventListener('myr5:local-history-refresh',()=>void flushSets());\r\nconst pendingKey=accountPendingKey;\r\nconst pending=user=>accountWorkoutSync.pending(user);\r\nasync function flushSets(){if(accountTransitionBusy||!account)return;let ticket;try{ticket=accountTransitions.capture();const result=await performanceAccountSync.flush();accountTransitions.assertCurrent(ticket);await accountWorkoutSync.flush();if(result?.failed?.length)set('syncBadge','Workout saved on this device · account sync will retry.');}catch(error){if(!ticket||!accountTransitions.isCurrent(ticket))return;if(error.code!=='auth_transition'&&error.code!=='account_scope_changed')set('syncBadge',error.message);}}\r\nwindow.coachAccount={refresh,async start(mode,goal){if(accountTransitionBusy)throw Error('Account is changing.');const ticket=accountTransitions.capture(),ready=account||await refresh();accountTransitions.assertCurrent(ticket);if(ready!==account)throw Error('Account changed. Refresh to continue.');if(!ready)throw Error('Sign in from Progress before starting a saved workout.');if(!ready.onboarding)throw Error('Complete your coach setup first.');return accountWorkoutSync.start(mode,goal);},async complete(data){if(accountTransitionBusy)throw Error('Account is changing.');return accountWorkoutSync.complete(data);}};\r\naccountTransitions.subscribe(()=>{account=null;scoreboard.clear();clearCoachAccount();$('signIn').hidden=false;$('accountContent').hidden=true;$('accountSettingsContent').hidden=true;$('workoutList').replaceChildren();$('mealList').replaceChildren();mealItems=null;$('reminderList').replaceChildren();reminderSnapshot=null;liveReminders.update([]);});\r\nconst localDate=()=>{const d=new Date();return new Date(d.getTime()-d.getTimezoneOffset()*60000).toISOString().slice(0,16);};\r\n$('mealForm').elements.eatenAt.value=localDate();$('reminderForm').elements.timezone.value=Intl.DateTimeFormat().resolvedOptions().timeZone;\r\nconst GUEST_MEALS='myr5-guest-meals-v1';const guestMeals={list(){try{return JSON.parse(localStorage.getItem(GUEST_MEALS)||'[]')}catch{return[]}},save(items){localStorage.setItem(GUEST_MEALS,JSON.stringify(items.slice(0,100)))}};\r\nasync function meals(){try{const items=account?(await api('/api/meals')).items:guestMeals.list();mealItems=items;$('mealList').replaceChildren();if(!items.length)set('mealList','No meals logged yet.');for(const item of items){\r\n const row=document.createElement('div');row.className='entry';const text=document.createElement('details'),name=document.createElement('summary');name.textContent=item.name;text.append(name);\r\n const detail=document.createElement('small');detail.textContent=item.portion+' · '+new Date(item.eaten_at).toLocaleString();text.append(detail);\r\n const breakdown=document.createElement('div');breakdown.className='saved-nutrients';const micros=typeof item.micros==='string'?JSON.parse(item.micros):item.micros||{};\r\n for(const [label,keys,values] of [['Macros',MACROS,item],['Micros',MICROS,micros]]){const p=document.createElement('p');p.textContent=label+': '+keys.map(([k,title,unit])=>title+' '+displayNutrient(values[k],unit)).join(' · ');breakdown.append(p);}text.append(breakdown);\r\n row.append(text,button('Remove',async()=>{try{if(account)await api('/api/meals/'+item.id,'DELETE');else guestMeals.save(mealItems.filter(m=>m.id!==item.id));await meals();}catch(e){set('mealStatus',e.message);}}));$('mealList').append(row);}}catch(e){mealItems=null;set('mealList',e.message);}finally{pyramidScanner?.refresh();if($('mealsPanel').dataset.dial)renderFoodDial();}}\r\n$('mealForm').onsubmit=async e=>{e.preventDefault();const form=e.target,submit=form.querySelector('[type=submit]');submit.disabled=true;$('foodCamera').disabled=true;const d={...Object.fromEntries(new FormData(form)),...mealNutrition.data()};try{d.id=crypto.randomUUID();d.eatenAt=new Date(d.eatenAt).toISOString();const rewardAccount=account,rewardDay=localDay(Date.parse(d.eatenAt));if(account){await api('/api/meals','POST',d);set('mealStatus','Meal saved');}else{guestMeals.save([{id:d.id,name:d.name,portion:d.portion,eaten_at:d.eatenAt,calories:d.calories,protein:d.protein,carbs:d.carbs,fat:d.fat,micros:Object.fromEntries(MICROS.map(([k])=>[k,d[k]]))},...guestMeals.list()]);set('mealStatus','Meal saved on this phone. Sign in to sync it.');}recordDailyActivity('food',{id:d.id,day:rewardDay},{account:rewardAccount});mealNutrition.reset();form.elements.eatenAt.value=localDate();$('foodStatus').textContent='';await meals();if(account)void refresh();}catch(err){set('mealStatus',err.message);}finally{$('mealStatus').scrollIntoView?.({block:'nearest'});submit.disabled=false;$('foodCamera').disabled=false;}};\r\nasync function reminders(){try{\r\n const {items}=await api('/api/reminders');const snapshot=JSON.stringify(items);if(snapshot===reminderSnapshot){liveReminders.update(items);return;}reminderSnapshot=snapshot;$('reminderList').replaceChildren();if(!items.length)set('reminderList','No reminders saved yet.');\r\n for(const r of items){\r\n  const row=document.createElement('div');row.className='entry reminder-entry';row.dataset.enabled=String(!!r.enabled);\r\n  const text=document.createElement('div');text.className='entry-copy';text.textContent=r.kind[0].toUpperCase()+r.kind.slice(1)+' · '+r.time;\r\n  const hint=document.createElement('small');hint.textContent=(CADENCE_LABELS[r.days_per_week??7])+' · '+(r.tone||'direct')+' · '+r.timezone+' · Quiet '+r.quiet_start+'–'+r.quiet_end;text.append(hint);\r\n  const next=document.createElement('small');next.id='reminder-next-'+r.id;next.className='reminder-next';text.append(next);\r\n  const controls=document.createElement('div');controls.className='reminder-controls';\r\n  const toggle=button(r.enabled?'ON':'OFF',async()=>{toggle.disabled=true;try{await api('/api/reminders/'+r.id,'PATCH',{enabled:!r.enabled});r.enabled=r.enabled?0:1;toggle.textContent=r.enabled?'ON':'OFF';toggle.setAttribute('aria-checked',String(!!r.enabled));row.dataset.enabled=String(!!r.enabled);set('reminderStatus',r.enabled?'Reminder resumed.':'Reminder paused.');liveReminders.update(items);}catch(e){set('reminderStatus',e.message);}finally{toggle.disabled=false;}});\r\n  toggle.className='hardware-toggle';toggle.setAttribute('role','switch');toggle.setAttribute('aria-label',r.kind+' reminder at '+r.time);toggle.setAttribute('aria-checked',String(!!r.enabled));\r\n  controls.append(toggle,button('Edit',()=>{editingReminder=r.id;const form=$('reminderForm');for(const name of ['kind','time','timezone'])form.elements[name].value=r[name];form.elements.quietStart.value=r.quiet_start;form.elements.quietEnd.value=r.quiet_end;form.elements.enabled.checked=!!r.enabled;reminderControls.load(r.tone,r.days_per_week);set('saveReminder','Save changes');$('cancelReminderEdit').hidden=false;set('reminderStatus','Editing reminder');form.scrollIntoView({block:'start'});$('toneDial').focus({preventScroll:true});}),button('Remove',async()=>{try{await api('/api/reminders/'+r.id,'DELETE');if(editingReminder===r.id)resetReminderEdit();await reminders();}catch(e){set('reminderStatus',e.message);}}));row.append(text,controls);$('reminderList').append(row);\r\n }\r\nliveReminders.update(items);\r\n}catch(e){reminderSnapshot=null;set('reminderList',e.message);liveReminders.update([]);}}\r\nfunction resetReminderEdit(){editingReminder=null;set('saveReminder','Save reminder');$('cancelReminderEdit').hidden=true;$('reminderForm').reset();$('reminderForm').elements.timezone.value=Intl.DateTimeFormat().resolvedOptions().timeZone;reminderControls.load();}\r\n$('cancelReminderEdit').onclick=()=>{resetReminderEdit();set('reminderStatus','Ready for a new reminder.');};\r\n$('reminderForm').onsubmit=async e=>{e.preventDefault();const form=e.target,b=form.querySelector('[type=submit]');b.disabled=true;$('cancelReminderEdit').disabled=true;try{const data=Object.fromEntries(new FormData(form));data.daysPerWeek=Number(data.daysPerWeek);data.enabled=form.elements.enabled.checked;data.id=editingReminder||crypto.randomUUID();await api(editingReminder?'/api/reminders/'+editingReminder:'/api/reminders',editingReminder?'PUT':'POST',data);void import('./modules/vault/vault-store.mjs').then(m=>m.bump('reminder-set')).catch(()=>{});set('reminderStatus',account?.push.schedulerActive?'Reminder saved.':'Reminder saved; delivery starts once the online sender is connected.');resetReminderEdit();await reminders();}catch(err){set('reminderStatus',err.message);}finally{b.disabled=false;$('cancelReminderEdit').disabled=false;}};\r\n// R8: a phone that turned reminders on before the Cloudflare move still holds a subscription under the old VAPID key.\r\nconst movedNotice=document.createElement('aside'),MOVED_SEEN='myr5-reminders-moved-v1';movedNotice.className='reminders-moved';movedNotice.setAttribute('role','status');movedNotice.hidden=true;\r\nmovedNotice.innerHTML='<button type=\"button\" data-on>Reminders moved to a new server. Tap to turn them back on.</button><button type=\"button\" data-later aria-label=\"Dismiss reminders notice\">Later</button>';document.body.append(movedNotice);\r\nconst movedSeen=()=>{try{return accountStorage?.getItem(MOVED_SEEN)==='1';}catch{return false;}},dismissMoved=()=>{movedNotice.hidden=true;try{accountStorage?.setItem(MOVED_SEEN,'1');}catch{}};\r\nmovedNotice.querySelector('[data-later]').onclick=dismissMoved;\r\nmovedNotice.querySelector('[data-on]').onclick=()=>{dismissMoved();$('notificationSwitch').click();if(!$('remindersPanel').open)$('remindersPanel').showModal();};\r\nasync function syncDeviceSwitch(){\r\n if(deviceBusy)return;\r\n let ticket;try{\r\n  ticket=accountTransitions.capture();\r\n  const supported='Notification'in window&&'PushManager'in window&&'serviceWorker'in navigator;\r\n  const reg=registration||await navigator.serviceWorker?.getRegistration(),sub=await reg?.pushManager?.getSubscription(),stale=supported&&!!account&&staleSubscription(sub,account.push.publicKey),on=supported&&!!sub&&!stale&&Notification.permission==='granted';\r\n  if(!accountTransitions.isCurrent(ticket))return;\r\n  movedNotice.hidden=!(stale&&Notification.permission!=='denied'&&!movedSeen());\r\n  $('notificationSwitch').setAttribute('aria-checked',String(on));set('notificationSwitch',on?'ON':'OFF');\r\n  $('notificationSwitch').disabled=!account||!supported||(!on&&!account.push.configured);$('testPush').disabled=!on;\r\n  if(on&&account?.push.configured)await deviceBinding.verify(account,sub);else deviceBinding.forget();\r\n  if(!accountTransitions.isCurrent(ticket))return;\r\n  set('pushStatus',!supported?'Install Coach to enable notifications.':!account?'Sign in to enable reminders.':Notification.permission==='denied'?'Allow notifications for Coach in your browser or phone settings.':!account.push.configured?'Notification service is reconnecting.':!account.push.schedulerActive?'Reconnecting… Reminders saved.':on?'Reminders and app update notifications on':'Turn on reminders and app updates for this device.');\r\n  liveReminders.render();\r\n }catch{if(ticket&&!accountTransitions.isCurrent(ticket))return;deviceBinding.forget();$('testPush').disabled=true;set('pushStatus','Reconnecting…');liveReminders.render();}\r\n}\r\n$('notificationSwitch').onclick=async()=>{\r\n const toggle=$('notificationSwitch'),turnOff=toggle.getAttribute('aria-checked')==='true';deviceBusy=true;deviceBinding.forget();toggle.disabled=true;\r\n try{\r\n  if(!('Notification'in window)||!('PushManager'in window))throw Error('Install Coach on your home screen and use a browser that supports notifications.');\r\n  if(turnOff){const reg=registration||await navigator.serviceWorker.ready,sub=await reg.pushManager.getSubscription();if(sub){await api('/api/push/unsubscribe','POST',{endpoint:sub.endpoint});await sub.unsubscribe();}set('pushStatus','Reminders are off on this device.');}\r\n  else{\r\n   if(account?.push.environment==='preview')throw Error('Notifications connect in the live app: myr5.mominc.online.');if(!account?.push.configured)throw Error('The notification sender could not connect. Retry while online.');\r\n   if(await Notification.requestPermission()!=='granted')throw Error('Notifications were not allowed. Enable them in your phone settings.');\r\n   const reg=registration||await navigator.serviceWorker.ready,{subscription:sub,fresh}=await subscribePush(reg,account.push.publicKey);\r\n   try{await api('/api/push/subscribe','POST',sub.toJSON());}catch(e){if(fresh)await sub.unsubscribe();throw e;}\r\n   set('pushStatus','This device is connected. Send a test to check delivery.');\r\n  }\r\n }catch(e){deviceBusy=false;await syncDeviceSwitch();set('pushStatus',e.message);return;}finally{deviceBusy=false;}await syncDeviceSwitch();\r\n};\r\n$('testPush').onclick=async()=>{try{const reg=registration||await navigator.serviceWorker?.getRegistration(),sub=await reg?.pushManager?.getSubscription();if(!sub)throw Error('Turn reminders on for this device first.');await api('/api/push/test','POST',{endpoint:sub.endpoint});set('pushStatus','The notification service accepted the test. Check your phone.');}catch(e){set('pushStatus',e.message);}};\r\nasync function workouts(){return scoreboard.refresh();}\r\nasync function localHistory(){try{localHistoryRepository??=await openLocalCoach();const scope=localHistoryRepository.forOwner(localHistoryRepository.guestOwnerId),items=(await scope.listWorkouts()).filter(item=>item.status==='completed').sort((a,b)=>(b.completedAt??0)-(a.completedAt??0)),list=$('localHistoryList');list.replaceChildren();set('localHistoryStatus',items.length?`${items.length} completed workout${items.length===1?'':'s'} on this device.`:'No completed workouts on this device yet.');for(const item of items){const row=document.createElement('article'),title=document.createElement('strong'),detail=document.createElement('p');row.className='entry';title.textContent=item.metadata?.name||item.mode;detail.textContent=`${item.completion?.value??0} · ${new Date(item.completedAt).toLocaleString()}`;row.append(title,detail);list.append(row);}if(!guestHistoryChoice){const host=document.createElement('section');$('historyPanel').append(host);const adapter=createImportAccountAdapter({repository:scope,request:authFetch,transitions:accountTransitions,getAccount:()=>account});guestHistoryChoice=mountGuestHistoryChoice({host,adapter,getAccount:()=>account,transitions:accountTransitions});}await guestHistoryChoice.render();}catch(error){set('localHistoryStatus',error.message);}}\r\n$('saveProfile').onclick = async () => {\r\n  try {\r\n    const ticket = accountTransitions.capture();\r\n    if (!account) throw new Error('No account');\r\n    const owner = account.user.id;\r\n    const dataEpoch = account.dataEpoch;\r\n    const data = Object.fromEntries(keys.map(k => [k, localStorage.getItem(k)]).filter(([, v]) => v != null));\r\n    const result = await api('/api/profile', 'PUT', { revision: revision, data });\r\n    // Update global revision before any further checks\r\n\r\n    accountTransitions.assertCurrent(ticket);\r\n    if (!account || account.user.id !== owner || account.dataEpoch !== dataEpoch) {\r\n      throw new Error('Account changed');\r\n    }\r\n    revision = result.revision;\r\n    const baseline = JSON.stringify(data);\r\n    if (localStorage.getItem('myr5-coach-owner') === owner) {\r\n      localStorage.setItem('myr5-synced-appearance', baseline);\r\n    }\r\n    await refresh();\r\n    set('accountStatus', 'Appearance saved to your account.');\r\n  } catch (e) {\r\n    set('accountStatus', e.message);\r\n  }\r\n};\r\n$('restoreProfile').onclick=async()=>{try{const ticket=accountTransitions.capture();const originalOwner=account?.user?.id;const originalEpoch=account?.dataEpoch;if(!originalOwner||originalEpoch===undefined){throw new Error('No account');}const value = await refresh();if (!value) return;if(account==null){throw new Error('Account missing after refresh');}accountTransitions.assertCurrent(ticket); if(account?.user?.id !== originalOwner || account?.dataEpoch !== originalEpoch) { throw new Error(\"Account changed\"); } if(value.user.id!==originalOwner||value.dataEpoch!==originalEpoch){throw new Error(\"Stale account\");}const profile=value.profile;if(!profile){throw new Error('Profile missing');}for(const key of keys){const raw=profile[key];if(raw!=null){localStorage.setItem(key,raw);window.dispatchEvent(new StorageEvent('storage',{key,newValue:raw}));}else{localStorage.removeItem(key);window.dispatchEvent(new StorageEvent('storage',{key,newValue:null}));}}localStorage.setItem('myr5-coach-owner',value.user.id);const snapshot=Object.fromEntries(keys.map(k=>[k,localStorage.getItem(k)]).filter(([,v])=>v!=null));localStorage.setItem('myr5-synced-appearance',JSON.stringify(snapshot));window.dispatchEvent(new Event('mominc-avatar-change'));set('accountStatus','Saved appearance restored.');}catch(e){set('accountStatus',e.message);}}\r\n$('refreshAccount').onclick=async()=>{await refresh();await workouts();};\r\n$('exportData').onclick=async()=>{try{download(JSON.stringify(await api('/api/export'),null,2),'myr5-data.json');}catch(e){set('accountStatus',e.message);}};\r\n$('signOut').onclick=async e=>{e.preventDefault();const target=account;accountTransitionBusy=true;try{try{accountTransitions.invalidate();}catch{}packGrantCache?.deactivate();void (async()=>{try{const sub=await registration?.pushManager.getSubscription();if(sub&&target){try{await api('/api/push/unsubscribe','POST',{endpoint:sub.endpoint},{'X-Target-Account':target.user.id,'X-Expected-Data-Epoch':String(target.dataEpoch)});}catch{}try{await sub.unsubscribe();}catch{}}}catch{}})();for(const k of [...keys,'myr5-workout-progress-v1','myr5-coach-owner','myr5-synced-appearance'])try{localStorage.removeItem(k);}catch{}try{clearCoachAccount();}catch{}await signOut();}catch(err){set('accountStatus',err.message);}finally{accountTransitionBusy=false;}};\r\n$('deleteAccount').onclick=async()=>{const captured=account;accountTransitionBusy=true;try{accountTransitions.invalidate();const target=captured&&Number.isSafeInteger(captured.dataEpoch)?captured:await api('/api/account?core=1');const receipt=await api('/api/account','DELETE',{confirm:$('deleteConfirm').value,expectedDataEpoch:target.dataEpoch},{'X-Target-Account':target.user.id});const through=validateAccountDeletionReceipt(receipt,target.user.id,target.dataEpoch);packGrantCache?.remove(target.user.id);accountWorkoutSync.forgetDeletedAccount(target.user.id,through);if(!receipt.alreadyDeleted)for(const k of [...keys,'myr5-workout-progress-v1','myr5-coach-owner','myr5-synced-appearance'])localStorage.removeItem(k);clearCoachAccount();location.reload();}catch(e){set('accountStatus',e.message);}finally{accountTransitionBusy=false;}};\r\nwindow.addEventListener('beforeinstallprompt',e=>{e.preventDefault();installPrompt=e;$('installApp').hidden=false;set('installStatus','Coach is ready to install on your home screen.');});window.addEventListener('appinstalled',()=>{set('installStatus','Coach is installed.');$('installApp').hidden=true;});\r\nset('installStatus',matchMedia('(display-mode: standalone)').matches?'Coach is running as an installed app.':'Install Coach for a full-screen training pod.');\r\n$('installApp').onclick=async()=>{if(installPrompt){await installPrompt.prompt();await installPrompt.userChoice;installPrompt=null;$('installApp').hidden=true;}};\r\ntry{localStorage.setItem('myr5-voice-style','robot');}catch{}\r\n$('downloadVoice').onclick=async()=>{const b=$('downloadVoice');b.disabled=true;try{const manifest=await(await fetch(VOICE_MANIFEST)).json(),urls=Object.values(manifest.phrases),cache=await caches.open(VOICE_CACHE);let i=0;await cache.add(VOICE_MANIFEST);for(const url of urls){if(!await cache.match(url)){const response=await fetch(url);if(!response.ok)throw Error('Download interrupted. Tap again to resume.');await cache.put(url,response);}set('downloadStatus',`Downloaded ${++i} of ${urls.length} voice clips.`);}set('downloadStatus','Robot voice pack is available offline on this device.');}catch(e){set('downloadStatus',e.message);}finally{b.disabled=false;}};\r\ninitAppUpdates({api,applyButton:$('applyUpdate'),onRegistration:reg=>{registration=reg;syncDeviceSwitch();},onBeforeUpdate:async()=>{await flushSets();if(account&&pending(account.user.id).length)throw Error('Your set is still syncing. Reconnect before updating.');}});\r\nmountPostDownload({host:$('installPanel')});\r\n// #120: the same military-satcom frame as Settings, generalised (mountSatcomFrame in coach-hub.mjs).\r\n// The Downloads menu only exists once mountPostDownload has built it (skipped if service workers\r\n// or caches aren't available, e.g. some test harnesses).\r\nmountSatcomFrame($('installPanel'),{title:'DOWNLOAD LINK'});\r\nconst downloadsMenu=$('downloadsMenu');if(downloadsMenu)mountSatcomFrame(downloadsMenu,{title:'DOWNLOAD LINK'});\r\nlet pyramidScanner=null,pyramidRequest=null,pyramidGen=0,pyramidBroken=false,mealItems=null;\r\n// #3 (W3-3A): Food opens as one full-screen pyramid scene (.pyramid-mode). A WebGL or model failure drops the class,\r\n// leaving the plain panel with its Camera button and Macros/Micros lists.\r\nasync function mountPyramid(){\r\n if(pyramidScanner||pyramidRequest)return;\r\n const run=++pyramidGen,request=new AbortController();pyramidRequest=request;\r\n try{\r\n  const {mountPyramidScanner}=await import('./food/pyramid-scanner.mjs');if(run!==pyramidGen||!$('mealsPanel').open)return;\r\n  const instance=await mountPyramidScanner($('foodCamera'),{getNutrition:mealNutrition.snapshot,getMeals:()=>mealItems,onDial:foodDial,frame:foodFrame,signal:request.signal});if(run!==pyramidGen||!$('mealsPanel').open){instance.dispose();return;}\r\n  pyramidScanner=instance;pyramidBroken=false;$('mealsPanel').classList.add('pyramid-mode');$('pyramidStarter')?.remove();\r\n }catch(error){if(!request.signal.aborted){pyramidBroken=true;$('mealsPanel').classList.remove('pyramid-mode');console.warn('Pyramid scanner unavailable',error);void offerPyramidStarter();}}\r\n finally{if(pyramidRequest===request)pyramidRequest=null;}\r\n}\r\n// W2-2O: the pyramid model is Starter-pack art. When it isn't on this phone (offline, never downloaded; not a WebGL\r\n// failure), the plain Food panel (Camera, Macros/Micros) offers the pack; online, the service worker fetches it on demand.\r\nasync function offerPyramidStarter(){\r\n if(navigator.onLine||await globalThis.caches?.match('/food/pyramid-scanner.glb').catch(()=>null)||$('pyramidStarter'))return;\r\n const offer=document.createElement('p');offer.id='pyramidStarter';offer.className='hint';\r\n offer.append('The Food pyramid comes with the Starter pack. ',button('Download the Starter pack',()=>window.myr5Packs?.open('starter')));\r\n $('foodCamera').after(offer);\r\n}\r\nfunction releasePyramid(){pyramidGen++;pyramidRequest?.abort();pyramidRequest=null;pyramidScanner?.dispose();pyramidScanner=null;}\r\n// The pyramid fits between the Food header and whatever the bottom sheet is showing.\r\nfunction foodFrame(){const panel=$('mealsPanel'),dock=document.getElementById('coachDock');let bottom=panel.querySelector('.food-sheet').offsetTop;\r\n // Framed fullscreen Food carries the dock inside the dialog: end the pyramid's frame (and the flip switch) above it.\r\n if(dock?.offsetHeight){const p=panel.getBoundingClientRect(),d=dock.getBoundingClientRect();if(d.top>p.top&&d.top<p.bottom)bottom=Math.min(bottom,(d.top-p.top)*panel.offsetHeight/(p.height||1));}\r\n return {top:panel.querySelector('header').offsetHeight,bottom};} // layout px: unaffected by the portal's arrival scale\r\nnew ResizeObserver(()=>pyramidScanner?.reframe()).observe($('mealsPanel').querySelector('.food-sheet'));\r\n// D36: the pyramid's dials. knob_0 opens the existing manual entry; knob_1/knob_2 toggle the Water and Today cards.\r\nlet foodDialReturn=null;\r\nfunction foodDial(index,on){\r\n if(index===0){setFoodDial(null);if($('mealConfirmation').hidden)window.dispatchEvent(new CustomEvent('myr5:food-selected',{detail:{name:''}}));$('mealName').focus();return;}\r\n setFoodDial(on?['log','water','today'][index]:null);\r\n}\r\nfunction setFoodDial(name){\r\n const panel=$('mealsPanel');\r\n if(name&&!panel.dataset.dial)foodDialReturn=document.activeElement;\r\n if(name)panel.dataset.dial=name;else delete panel.dataset.dial;\r\n $('foodDial').hidden=!name;\r\n if(name){renderFoodDial();$('foodDial').focus({preventScroll:true});return;}\r\n if(foodDialReturn?.isConnected&&panel.open)foodDialReturn.focus({preventScroll:true});foodDialReturn=null;\r\n}\r\nfunction renderFoodDial(){\r\n const name=$('mealsPanel').dataset.dial,targets=window.coachPlan?.targets,line=(text,className)=>{const p=document.createElement('p');p.textContent=text;if(className)p.className=className;return p;};\r\n if(name==='water'){\r\n  // No water log exists yet (no /api/logs): the existing water UI is the daily target and a water reminder.\r\n  set('foodDialTitle','Water');\r\n  $('foodDialBody').replaceChildren(line(targets?.waterOz?`${targets.waterOz} oz`:'—','food-dial-big'),line(targets?.waterOz?'Your water target for today.':'Finish Coach setup to get a daily water target.','hint'),button('Set a water reminder',()=>{$('reminderForm').elements.kind.value='water';document.querySelector('[data-panel=\"reminders\"]')?.click();}));\r\n }else if(name==='today'){\r\n  set('foodDialTitle','Today');\r\n  const eaten=mealsOn(mealItems);\r\n  const t=todayTiles(mealItems),list=document.createElement('ul');list.className='food-dial-list';\r\n  for(const item of eaten){const li=document.createElement('li');li.textContent=`${item.name} · ${new Date(item.eaten_at).toLocaleTimeString([],{hour:'numeric',minute:'2-digit'})} · ${displayNutrient(item.calories,'kcal')}`;list.append(li);}\r\n  $('foodDialBody').replaceChildren(line(t.calories,'food-dial-big'),line(`Protein ${t.protein} · Carbs ${t.carbs} · Fat ${t.fat}${targets?.proteinGrams?` · target ${targets.proteinGrams} g protein`:''}`),eaten.length?list:line('No meals logged today yet. Tap the lens to scan one.','hint'));\r\n }\r\n}\r\n$('foodDialBack').onclick=()=>{pyramidScanner?.setDial(-1);setFoodDial(null);};\r\n// Clears the meal in progress (and any scan left on screen) so the pyramid is back to its idle face.\r\n$('cancelMeal').onclick=()=>{if(!$('cancelFoodScan').hidden)$('cancelFoodScan').click();window.dispatchEvent(new Event('myr5:food-reset'));for(const id of ['mealScanStage','foodSuggestions','recognizeFood'])$(id).hidden=true;set('foodStatus','');};\r\n$('mealsPanel').addEventListener('close',()=>{releasePyramid();setFoodDial(null);});window.addEventListener('pagehide',releasePyramid);\r\n// Router/portal hook (same contract as myr5Menus.ship): opens Food and returns its <dialog>.\r\nwindow.myr5Menus={...window.myr5Menus,food:()=>{\r\n if(document.body.dataset.cameraWorkout==='true'||document.body.dataset.tracking==='true')return null; // #40: no meals over a workout\r\n if(!$('mealsPanel').open)document.querySelector('[data-panel=\"meals\"]')?.click();return $('mealsPanel');\r\n}};\r\n for(const button of document.querySelectorAll('[data-panel]'))button.addEventListener('click',async()=>{if(button.dataset.panel==='history')await localHistory();if(button.dataset.panel==='meals'){$('mealsPanel').classList.toggle('pyramid-mode',!pyramidBroken);void mountPyramid();await meals();}if(button.dataset.panel==='reminders')await liveReminders.sync();if(button.dataset.panel==='account'){await refresh();await workouts();}});\r\n window.addEventListener('myr5:local-history-refresh',localHistory);window.addEventListener('pagehide',()=>{guestHistoryChoice?.close();localHistoryRepository?.close();},{once:true});\r\nconst coachDayTimer=setInterval(()=>{if(!document.hidden)refresh();},60000);window.addEventListener('pagehide',()=>clearInterval(coachDayTimer));\r\nwindow.addEventListener('online',refresh);document.addEventListener('visibilitychange',()=>{if(!document.hidden)refresh();});\r\n await applyLocalCoach();{const cached=packGrantCache?.active();if(cached)void mountVerifiedExpansion(cached);}void refresh();const panel=new URLSearchParams(location.search).get('panel');window.myr5Routes.boot(panel);\r\n","level-map-domain.mjs":"// Presentation rules only. XP thresholds and rewards stay owned by progression-rules and battle-pass.\r\nexport const CHAPTER_SIZE=10;\r\nexport const CHAPTER_COUNT=25;\r\nconst WORLDS=[\r\n ['The first signal','Faint moon'],['Dustwake','Broken satellites'],['Pale orbit','Ice rings'],['Ion garden','Blue aurora'],['Beacon belt','Twin moons'],\r\n ['Amber crossing','Gas halo'],['The outer reach','Meteor river'],['Violet frontier','Crystal world'],['Aster passage','Silver rings'],['Solar forge','Young star'],\r\n ['Helios rise','Gold corona'],['The wide expanse','Planet chain'],['Cinder sea','Ash world'],['Neon divide','Artificial orbit'],['The crimson arc','Red giant'],\r\n ['Eventide','Shadow planet'],['The iron constellation','Orbital foundry'],['Hyperion','Binary suns'],['Last daylight','Supergiant'],['The dark current','Gravity tide'],\r\n ['Blackglass gate','Mirror world'],['The fracture','Dimensional seam'],['Singularity rim','Accretion disc'],['Beyond the veil','Star rift'],['The final horizon','Cosmic dawn']\r\n];\r\nexport function chapterForLevel(level){return Math.max(0,Math.min(CHAPTER_COUNT-1,Math.floor((level-1)/CHAPTER_SIZE)));}\r\nexport function chapterLevels(chapter,thresholds){\r\n const page=Math.max(0,Math.min(CHAPTER_COUNT-1,chapter));\r\n return thresholds.slice(page*CHAPTER_SIZE,(page+1)*CHAPTER_SIZE).map((xp,index)=>({level:page*CHAPTER_SIZE+index+1,xp,tier:(index+1)%10===0?'Legendary':(index+1)%5===0?'Rare':'Uncommon'}));\r\n}\r\nexport function chapterWorld(chapter){const page=Math.max(0,Math.min(CHAPTER_COUNT-1,chapter));return {name:WORLDS[page][0],body:WORLDS[page][1],intensity:page/(CHAPTER_COUNT-1),page};}\r\n// Coordinates are percentages of one flight sector, ordered from its highest level down.\r\n// Every sector meets the next at x=50 so the 250 rewards form one continuous route.\r\nexport function chapterConstellation(chapter){\r\n const page=Math.max(0,Math.min(CHAPTER_COUNT-1,chapter));\r\n const pattern=[27,56,78,47,19,51,79,42,24,66];\r\n const nodes=pattern.map((base,index)=>({x:Math.max(16,Math.min(84,(page%2?100-base:base)+((page*7+index*3)%9)-4)),y:8+index*9.3}));\r\n const main=`M 50 0 ${nodes.map(({x,y})=>`L ${x} ${y.toFixed(1)}`).join(' ')} L 50 100`;\r\n const branchIndex=4,anchor=nodes[branchIndex],coach={x:anchor.x<50?83:17,y:49};\r\n const branch=`M ${anchor.x} ${anchor.y.toFixed(1)} L ${coach.x} ${coach.y}`;\r\n return {nodes,main,branch,coach};\r\n}\r\nexport function chapterCoach(chapter,requirements){\r\n if(!requirements.length)return null;\r\n return requirements[Math.min(requirements.length-1,Math.round(chapter*(requirements.length-1)/(CHAPTER_COUNT-1)))];\r\n}\r\n","level-map-scene.mjs":"// A small arcade canvas with run-local points; it never writes workout XP or unlocks.\r\nimport {createFlightScore} from './flight-score.mjs';\r\nimport {asteroid,rock} from './space-rocks.mjs';\r\nconst SHIPS=['supportive','direct','analytical','playful','calm','mom'];\r\nconst clamp=(v,min,max)=>Math.max(min,Math.min(max,v));\r\nconst sprite=[\r\n '.......11.......','......1221......','......1221......','.....123321.....',\r\n '....12344321....','...1234554321...','..123456654321..','1123456776543211',\r\n '1123456776543211','..123456654321..','...1234554321...','....12344321....',\r\n '.....123321.....','......1881......','.....8.88.8.....','....8..88..8....'\r\n];\r\nconst colors={supportive:['#142b40','#70b4db','#b9edff','#f4e6b2','#f37f42','#ffe4a0','#fff8de','#e66638'],direct:['#302644','#b59ce8','#e6caff','#ffdfad','#d95f51','#ff9c65','#fff4db','#e65d39'],analytical:['#183a40','#60d3cc','#b8fff0','#e1e8ff','#6b8fea','#afd3ff','#fff8de','#e66638'],playful:['#3d2445','#fa9ccf','#ffd7ec','#ffecae','#fc7d87','#ffc484','#fff8de','#e66638'],calm:['#173a36','#7dbea7','#c6f5d7','#f8e8be','#8ecbc6','#d7fff0','#fff8de','#e66638'],mom:['#402824','#dba579','#f7d5ad','#fff0c9','#d86d50','#ffbc7f','#fff8de','#e66638']};\r\nfunction drawShip(ctx,x,y,style,t){\r\n const palette=colors[SHIPS.includes(style)?style:'supportive'],pixel=3;\r\n ctx.save();ctx.translate(Math.round(x-24),Math.round(y-24));\r\n // Each selected catalog hull has its own readable silhouette at this small resolution.\r\n ctx.fillStyle=palette[1];\r\n if(style==='supportive'){for(const px of [1,37]){ctx.fillRect(px,19,10,12);ctx.fillRect(px+2,31,6,9);}}\r\n if(style==='direct'){ctx.fillRect(0,28,15,5);ctx.fillRect(33,28,15,5);ctx.fillRect(3,23,10,6);ctx.fillRect(35,23,10,6);}\r\n if(style==='analytical'){ctx.fillRect(4,32,40,4);ctx.fillRect(4,25,4,11);ctx.fillRect(40,25,4,11);ctx.fillRect(12,36,24,5);}\r\n if(style==='playful'){ctx.fillRect(4,3,5,26);ctx.fillRect(39,3,5,26);ctx.fillRect(0,30,11,10);ctx.fillRect(37,30,11,10);}\r\n if(style==='calm'){ctx.fillRect(9,12,30,28);ctx.fillRect(13,7,22,5);ctx.fillRect(13,40,22,5);}\r\n if(style==='mom'){ctx.fillRect(2,18,44,22);ctx.fillRect(17,6,14,15);ctx.fillRect(4,10,9,13);ctx.fillRect(35,10,9,13);}\r\n for(let row=0;row<16;row++)for(let col=0;col<16;col++){\r\n  const code=Number(sprite[row][col]);if(!code)continue;\r\n  ctx.fillStyle=palette[code-1]||palette[0];ctx.fillRect(col*pixel,row*pixel,pixel,pixel);\r\n }\r\n ctx.fillStyle=t%360<180?'#f58b40':'#ffe5a0';ctx.fillRect(19,48,4,8);ctx.fillRect(27,48,4,8);ctx.restore();\r\n}\r\nexport function mountLevelMapScene(canvas,{ship='supportive',reducedMotion=false,onScore=()=>{}}={}){\r\n const points=createFlightScore();\r\n const publish=()=>onScore(points.read());publish();\r\n const ctx=canvas.getContext('2d');if(!ctx)return {start(){},stop(){},startFiring(){},stopFiring(){},fire(){},aim(){},setShip(){},resize(){},setWarp(){}};\r\n let running=false,raf=0,w=1,h=1,last=0,time=0,style=ship,aimX=.5,aimY=.72,x=.5,y=.72,firing=false,shotClock=0;\r\n const clampX=(xVal)=>{if(w<100)return xVal;const maxR=9,minX=(maxR/w)+0.08,maxX=1-minX;return Math.max(minX,Math.min(maxX,xVal));};\r\n const asteroids=Array.from({length:9},(_,i)=>({x:.12+.76*((i*37+19)%97)/100,y:((i*29+8)%103)/100,r:3+i%4*2,s:.000035+i%5*.000016,hit:0}));\r\n // R-1017: the constellation page's dark lit-rim rocks join the flight as bigger, slower targets (both pages' asteroids, one game).\r\n for(let i=0;i<4;i++)asteroids.push({x:.18+.64*((i*41+7)%89)/89,y:((i*31+50)%101)/100,s:.00002+i%3*.00001,hit:0,...asteroid(8,13),poly:true});\r\n // Hyper-speed: warp streaks while the page jumps to a section; warp is the scroll speed in px/ms (+ = flying up).\r\n let warp=0;const streaks=Array.from({length:42},(_,i)=>({x:((i*53+11)%97)/97,y:((i*71+5)%89)/89,l:.4+(i*37%10)/10}));\r\n const lasers=[];const blasts=[];\r\n // Kenney Space Shooter Remastered, CC0: https://kenney.nl/assets/space-shooter-remastered\r\n const meteors=['/pod/worlds/kenney-meteor-grey-tiny1.png','/pod/worlds/kenney-meteor-brown-tiny1.png'].map(src=>{const img=new Image();img.src=src;img.onload=()=>{if(!running)draw();};return img;});\r\n const resize=()=>{const rect=canvas.getBoundingClientRect(),dpr=Math.min(devicePixelRatio||1,2);w=Math.max(1,rect.width);h=Math.max(1,rect.height);canvas.width=Math.round(w*dpr);canvas.height=Math.round(h*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);draw();};\r\n function draw(){ctx.clearRect(0,0,w,h);const now=time;\r\n  for(let index=0;index<asteroids.length;index++){const a=asteroids[index];if(a.hit>0)continue;const px=a.x*w,py=a.y*h,img=meteors[index%meteors.length];if(a.poly){rock(ctx,px,py,a.r,a.rot+a.vr*now/1000,a.verts,.9);continue;}if(img.complete&&img.naturalWidth){ctx.drawImage(img,px-a.r,py-a.r,a.r*2,a.r*2);}else{ctx.fillStyle='#aabcca';ctx.fillRect(px-a.r,py-a.r,a.r*2,a.r*2);}}\r\n  for(const l of lasers){ctx.strokeStyle='#b9faff';ctx.lineWidth=2;ctx.shadowBlur=12;ctx.shadowColor='#60e6ff';ctx.beginPath();ctx.moveTo(l.x*w,l.y*h);ctx.lineTo(l.x*w,(l.y-.08)*h);ctx.stroke();ctx.shadowBlur=0;}\r\n  for(const b of blasts){ctx.strokeStyle=`rgba(255,190,105,${Math.max(0,1-b.age/380)})`;ctx.lineWidth=3;ctx.beginPath();ctx.arc(b.x*w,b.y*h,3+b.age/24,0,Math.PI*2);ctx.stroke();}\r\n  if(warp){const k=Math.min(1,Math.abs(warp)/40);ctx.strokeStyle='#cfefff';ctx.lineWidth=1.5;ctx.globalAlpha=.25+.6*k;ctx.beginPath();\r\n   for(const s of streaks){const sx=s.x*w,sy=s.y*h,len=(30+h*.5*k)*s.l;ctx.moveTo(sx,sy);ctx.lineTo(sx,sy-Math.sign(warp)*len);}\r\n   ctx.stroke();ctx.globalAlpha=1;}\r\n  drawShip(ctx,x*w,y*h,style,now);\r\n  if(warp){ctx.fillStyle='#ffb25a';ctx.globalAlpha=.85;const flame=10+Math.min(60,Math.abs(warp)*1.5);ctx.fillRect(x*w-7,y*h+(warp>0?24:-24-flame),14,flame);ctx.globalAlpha=1;}\r\n }\r\n function frame(now){if(!running)return;const dt=Math.min(40,Math.max(0,now-last));last=now;time+=dt;\r\n  // Streaks rush past opposite the jump; asteroids are left behind (they recycle off the edge without breaking the multiplier).\r\n  if(warp){for(const s of streaks){s.y=((s.y+warp*dt/h*1.6)%1+1)%1;}for(const a of asteroids){if(a.hit<=0){a.y+=warp*dt/h;if(a.y>1.04||a.y<-.1){a.y=a.y>1?-.08:1;a.x=clampX((a.x+.37)%1);}}}}\r\n  x+=(aimX-x)*Math.min(1,dt*.04);y+=(aimY-y)*Math.min(1,dt*.04);\r\n  if(firing){shotClock+=dt;while(shotClock>=125){lasers.push({x,y:y-.04});shotClock-=125;}}\r\n  for(const a of asteroids){if(a.hit>0){a.hit-=dt;continue;}if(!reducedMotion){a.y+=a.s*dt;if(a.y>1.05){a.y=-.08;a.x=clampX((a.x+.37)%1);points.miss();publish();}}}\r\n  for(let i=lasers.length-1;i>=0;i--){const l=lasers[i];l.y-=dt*.0016;if(l.y<-.1){lasers.splice(i,1);continue;}const hit=asteroids.find(a=>a.hit<=0&&Math.abs(a.x-l.x)*w<a.r+5&&Math.abs(a.y-l.y)*h<a.r+10);if(hit){hit.hit=700;blasts.push({x:hit.x,y:hit.y,age:0});hit.y=-.08;hit.x=clampX((hit.x+.37)%1);lasers.splice(i,1);points.hit();publish();}}\r\n  for(let i=blasts.length-1;i>=0;i--){blasts[i].age+=dt;if(blasts[i].age>380)blasts.splice(i,1);}\r\n  draw();raf=requestAnimationFrame(frame);\r\n }\r\n function start(){resize();if(running||document.hidden)return;running=true;last=performance.now();raf=requestAnimationFrame(frame);}\r\n function stopFiring(){firing=false;shotClock=0;}\r\n function stop(){stopFiring();running=false;if(raf)cancelAnimationFrame(raf);raf=0;}\r\n function fire(){if(document.hidden)return;lasers.push({x,y:y-.04});if(!running)draw();}\r\n return {start,stop,stopFiring,resetScore(){points.reset();publish();},startFiring(){if(document.hidden)return;firing=true;shotClock=0;fire();},resize,setWarp(value){warp=reducedMotion?0:value;},aim(clientX,clientY){const r=canvas.getBoundingClientRect();aimX=clamp((clientX-r.left)/r.width,.1,.9);aimY=clamp((clientY-r.top)/r.height,.14,.88);x=aimX;y=aimY;draw();},fire,setShip(value){style=value;draw();}};\r\n}\r\n","local-coach/browser-runtime.mjs":"import {openLocalCoach,LocalCoachStorageError} from './repository.mjs';\r\n\r\nexport {openLocalCoach,LocalCoachStorageError};\r\n\r\nexport function accountProbeFallsBackToLocal(error){\r\n if(error instanceof LocalCoachStorageError)return false;\r\n const status=Number(error?.status);if(status>=400&&status<500)return false;\r\n return error instanceof TypeError||error?.name==='TimeoutError'||error?.code==='optional_probe_timeout'||status>=500&&status<=599;\r\n}\r\nasync function boundedOptionalProbe(load,{timeoutMs=4000,setTimeoutFn=setTimeout,clearTimeoutFn=clearTimeout}={}){\r\n if(!Number.isFinite(timeoutMs)||timeoutMs<=0)throw RangeError('Invalid optional probe deadline.');\r\n const controller=new AbortController();let timer;\r\n try{return await Promise.race([\r\n  Promise.resolve().then(()=>load({signal:controller.signal})),\r\n  new Promise((_,reject)=>{timer=setTimeoutFn(()=>{const error=Object.assign(Error('Optional account service timed out.'),{code:'optional_probe_timeout',status:503});controller.abort(error);reject(error);},timeoutMs);}),\r\n ]);}finally{clearTimeoutFn(timer);}\r\n}\r\nexport async function probeOptionalAccount(load,options){try{return await boundedOptionalProbe(load,options);}catch(error){if(error?.status===401&&error?.code!=='auth-config'||accountProbeFallsBackToLocal(error))return null;throw error;}}\r\nexport async function probeOptionalTransfer(load,options){try{return await boundedOptionalProbe(load,options);}catch(error){if(accountProbeFallsBackToLocal(error))return null;throw error;}}\r\n\r\nconst HEARTBEAT_MS=20_000,STALE_MS=60_000,CHANNEL='myr5-local-workout-lease-v1';\r\nconst defaultChannel=name=>typeof BroadcastChannel==='function'?new BroadcastChannel(name):null;\r\nconst delay=ms=>new Promise(resolve=>setTimeout(resolve,ms));\r\nconst json=value=>{try{return JSON.parse(value||'null');}catch{return null;}};\r\n\r\nexport async function openGuestWorkoutAdapter({\r\n exerciseKeys,\r\n open=openLocalCoach,\r\n storage=globalThis.localStorage,\r\n channelFactory=defaultChannel,\r\n now=()=>Date.now(),\r\n setIntervalFn=globalThis.setInterval?.bind(globalThis),\r\n clearIntervalFn=globalThis.clearInterval?.bind(globalThis),\r\n wait=delay,\r\n heartbeatMs=HEARTBEAT_MS,\r\n staleMs=STALE_MS,\r\n tabId=globalThis.crypto?.randomUUID?.(),\r\n}={}){\r\n if(!tabId)throw new LocalCoachStorageError('missing-randomness','Secure tab identifiers are unavailable.',{recoverable:false});\r\n const repository=await open({exerciseKeys}),scope=repository.forOwner(repository.guestOwnerId);\r\n const key=`myr5-local-workout-heartbeat:${scope.ownerId}:${scope.deviceId}`,channel=channelFactory?.(CHANNEL);\r\n const peers=new Map();let timer=0,disposed=false,held=false,active=null,leaseToken=null,fence=0;\r\n const current=value=>value&&Number.isFinite(value.at)&&value.at>now()-staleMs;\r\n const fresh=value=>current(value)&&value.tabId!==tabId;\r\n const readHeartbeat=()=>{try{return json(storage?.getItem(key));}catch{return null;}};\r\n const foreignHeartbeat=()=>{const stored=readHeartbeat();return fresh(stored)&&stored.type==='heartbeat'||[...peers.values()].some(value=>fresh(value)&&value.type==='heartbeat');};\r\n const foreign=()=>fresh(readHeartbeat())||[...peers.values()].some(fresh);\r\n const removeHeartbeat=token=>{try{const value=readHeartbeat();if(value?.tabId===tabId&&(!token||value.token===token))storage?.removeItem(key);}catch{}};\r\n const loseLease=()=>{if(timer)clearIntervalFn?.(timer);timer=0;held=false;const token=leaseToken;leaseToken=null;removeHeartbeat(token);};\r\n const writeHeartbeat=()=>{if(!held||disposed||!leaseToken)return false;const stored=readHeartbeat();if(fresh(stored)||[...peers.values()].some(value=>fresh(value)&&value.type==='heartbeat')){loseLease();return false;}const value={type:'heartbeat',tabId,token:leaseToken,at:now(),ownerId:scope.ownerId,deviceId:scope.deviceId};try{storage?.setItem(key,JSON.stringify(value));}catch{loseLease();return false;}if(readHeartbeat()?.token!==leaseToken){loseLease();return false;}channel?.postMessage?.(value);return true;};\r\n const receive=event=>{const value=event?.data;if(value?.ownerId!==scope.ownerId||value?.deviceId!==scope.deviceId||value.tabId===tabId)return;if(value.type==='release'){if(!value.token||peers.get(value.tabId)?.token===value.token)peers.delete(value.tabId);}else if(value.type==='heartbeat'||value.type==='claim'||value.type==='probe'){peers.set(value.tabId,value);if(value.type==='probe'&&held)writeHeartbeat();}};\r\n channel?.addEventListener?.('message',receive);\r\n const acquire=async()=>{\r\n  if(disposed)throw Error('Local workout storage is closed.');if(held){try{assertLease();return true;}catch{return false;}}\r\n  channel?.postMessage?.({type:'probe',tabId,at:now(),ownerId:scope.ownerId,deviceId:scope.deviceId});await wait(25);\r\n  if(foreignHeartbeat())return false;\r\n  const token=`${tabId}:${now()}:${++fence}`,claim={type:'claim',tabId,token,at:now(),ownerId:scope.ownerId,deviceId:scope.deviceId};\r\n  const beforeClaim=readHeartbeat();if(fresh(beforeClaim)&&beforeClaim.type==='heartbeat')return false;\r\n  try{storage?.setItem(key,JSON.stringify(claim));}catch{return false;}channel?.postMessage?.(claim);await wait(25);\r\n  if(foreignHeartbeat()){removeHeartbeat(token);return false;}\r\n  const stored=readHeartbeat(),contenders=[claim,...[...peers.values()].filter(value=>fresh(value)&&value.type==='claim'),...(fresh(stored)&&stored.type==='claim'?[stored]:[])];\r\n  contenders.sort((a,b)=>String(a.tabId).localeCompare(String(b.tabId))||String(a.token).localeCompare(String(b.token)));\r\n  if(contenders[0]?.token!==token){removeHeartbeat(token);return false;}\r\n  const value={...claim,type:'heartbeat',at:now()};try{storage?.setItem(key,JSON.stringify(value));}catch{return false;}channel?.postMessage?.(value);await wait(25);\r\n  const owner=readHeartbeat();if(owner?.type!=='heartbeat'||owner.tabId!==tabId||owner.token!==token||foreignHeartbeat()){removeHeartbeat(token);return false;}\r\n  try{await scope.claimWorkoutLease(token);}catch(error){removeHeartbeat(token);throw error;}\r\n  const confirmed=readHeartbeat();if(confirmed?.type!=='heartbeat'||confirmed.tabId!==tabId||confirmed.token!==token||foreignHeartbeat()){removeHeartbeat(token);return false;}\r\n  leaseToken=token;held=true;timer=setIntervalFn?.(writeHeartbeat,heartbeatMs)??0;return true;\r\n };\r\n const assertLease=()=>{const owner=readHeartbeat(),blocked=disposed||!held||owner?.type!=='heartbeat'||owner.tabId!==tabId||owner.token!==leaseToken||!current(owner)||[...peers.values()].some(value=>fresh(value)&&value.type==='heartbeat');if(blocked){loseLease();throw new LocalCoachStorageError('lease','This workout is active in another tab.',{recoverable:true});}return leaseToken;};\r\n const release=()=>{const token=leaseToken;loseLease();channel?.postMessage?.({type:'release',tabId,token,at:now(),ownerId:scope.ownerId,deviceId:scope.deviceId});};\r\n try{const bootForeign=foreign();if(!bootForeign&&await acquire()){try{await scope.interruptActiveWorkouts({leaseToken:assertLease()});}finally{release();}}}\r\n catch(error){release();channel?.removeEventListener?.('message',receive);channel?.close?.();repository.close();throw error;}\r\n async function resumable(mode){const rows=await scope.listWorkouts();return rows.filter(row=>row.status==='paused'&&(mode===undefined||row.mode===mode)&&row.metadata?.control==='manual').at(-1)??null;}\r\n // #19: the newest paused/interrupted row started today (any control). Only a manual row truly resumes its\r\n // progress -- through paused()/resumable() above, gated by beginSet's pausedLocal check -- a paused or\r\n // interrupted camera row just restarts the same movement from zero; the Continue chip still surfaces it so\r\n // the cut-short set is not forgotten.\r\n async function unfinishedToday(){\r\n  const rows=await scope.listWorkouts(),today=new Date(now());\r\n  const sameDay=t=>{const d=new Date(t);return d.getFullYear()===today.getFullYear()&&d.getMonth()===today.getMonth()&&d.getDate()===today.getDate();};\r\n  return rows.filter(row=>(row.status==='paused'||row.status==='interrupted')&&sameDay(row.startedAt)).at(-1)??null;\r\n }\r\n return Object.freeze({\r\n  ownerId:scope.ownerId,deviceId:scope.deviceId,\r\n  hasForeignLease:foreign,\r\n  async paused(mode){return resumable(mode);},\r\n  async unfinished(){return unfinishedToday();},\r\n  async start({mode,goal,restSeconds,progress={},metadata={},control='camera'}){\r\n   if(!await acquire())throw new LocalCoachStorageError('lease','This workout is active in another tab.',{recoverable:true});const token=assertLease();\r\n   try{if(control==='manual'){const paused=await resumable(mode);if(paused){await scope.resumeWorkout(paused.id,{leaseToken:token});active={id:paused.id,control};return {...paused,status:'active',resumed:true};}}const workout=await scope.startWorkout({mode,goal,restSeconds,progress,metadata:{...metadata,control}},{leaseToken:token});active={id:workout.id,control};return workout;}catch(error){release();throw error;}\r\n  },\r\n  async update(id,progress){const token=assertLease();return scope.updateWorkout(id,{progress},{leaseToken:token});},\r\n  async pause(id,progress){const token=assertLease();if(progress)await scope.updateWorkout(id,{progress},{leaseToken:token});const workout=await scope.pauseWorkout(id,{leaseToken:token});active={id,control:'manual'};return workout;},\r\n  async resume(id){const token=assertLease(),workout=await scope.resumeWorkout(id,{leaseToken:token});active={id,control:'manual'};return workout;},\r\n  async complete(id,completion){const token=assertLease(),result=await scope.completeWorkout(id,completion,{leaseToken:token});active=null;release();return {local:true,queued:!!result.outbox,workout:result.workout,duplicate:result.duplicate};},\r\n  async interrupt(id,progress){const token=assertLease();if(progress)await scope.updateWorkout(id,{progress},{leaseToken:token});const workout=await scope.interruptWorkout(id,{leaseToken:token});active=null;release();return workout;},\r\n  async history(){return (await scope.listWorkouts()).filter(row=>row.status==='completed').sort((a,b)=>(b.completedAt??0)-(a.completedAt??0)||b.id.localeCompare(a.id));},\r\n  async listPerformanceWorkouts(){return (await scope.listWorkouts()).filter(row=>row.status==='completed'&&row.progress?.performance).sort((a,b)=>(a.completedAt??0)-(b.completedAt??0)||a.id.localeCompare(b.id));},\r\n  snapshot(){return {held,active,foreign:foreign()};},\r\n  close(){if(disposed)return;disposed=true;release();channel?.removeEventListener?.('message',receive);channel?.close?.();repository.close();},\r\n });\r\n}\r\n","local-coach/import-account-adapter.mjs":"import {createImportDrain} from './import-sync.mjs';\r\nimport {assignmentStatus} from './import-assignment.mjs';\r\nimport {IMPORT_UPLOAD_MANIFEST} from './import-upload-manifest.mjs';\r\n\r\nconst fail=code=>{throw Object.assign(Error('Refresh the selected account before continuing.'),{code});};\r\nconst target=account=>{\r\n if(typeof account?.user?.id!=='string'||!account.user.id||!Number.isSafeInteger(account.dataEpoch)||account.dataEpoch<1)fail('account_scope_unavailable');\r\n return {owner:account.user.id,epoch:account.dataEpoch};\r\n};\r\n// This is the sole browser adapter that turns an authenticated core response\r\n// into local deletion evidence. It accepts no caller-supplied deletion proof.\r\nexport function createImportAccountAdapter({repository,request,transitions,getAccount,manifest=IMPORT_UPLOAD_MANIFEST,now=()=>Date.now(),randomUUID=()=>crypto.randomUUID()}){\r\n async function loadAccount({signal}={}){\r\n  const response=await request('/api/account?core=1',{method:'GET',signal,cache:'no-store',credentials:'same-origin'});\r\n  if(response.redirected||!response.headers.get('content-type')?.includes('application/json'))fail('invalid_account_response');\r\n  const value=await response.json();\r\n  if(!response.ok)throw Object.assign(Error('Account could not be checked.'),{status:response.status});\r\n  target(value);return value;\r\n }\r\n const current=(ticket,expected)=>{\r\n  transitions.assertCurrent(ticket);const selected=target(getAccount());\r\n  if(selected.owner!==expected.owner||selected.epoch!==expected.epoch)fail('account_scope_changed');\r\n };\r\n async function fresh(ticket,expected){\r\n  current(ticket,expected);const value=await loadAccount({signal:ticket.signal});current(ticket,expected);\r\n  const live=target(value);if(live.owner!==expected.owner||live.epoch!==expected.epoch)fail('account_scope_changed');return value;\r\n }\r\n const drain=createImportDrain({repository,transition:transitions,manifest,now,loadAccount,postImport:async input=>{\r\n  const response=await request(input.path,{method:'POST',headers:input.headers,body:input.body,signal:input.signal,cache:'no-store',credentials:'same-origin'});\r\n  let body=null;if(!response.redirected&&response.headers.get('content-type')?.includes('application/json'))try{body=await response.json();}catch{}\r\n  return {status:response.status,body,retryAfter:response.headers.get('Retry-After')};\r\n }});\r\n return Object.freeze({\r\n  stop:()=>drain.stop(),\r\n  async history(){\r\n   const [workouts,state]=await Promise.all([repository.listWorkouts(),repository.listImportAssignments()]);\r\n   const observedAt=now();\r\n   return workouts.filter(row=>row.status==='completed').map(workout=>{\r\n    const head=state.heads.find(row=>row.clientWorkoutId===workout.clientWorkoutId),item=head&&state.items.find(row=>row.claimId===head.claimId);\r\n    return {workout,selectable:!head||head.status==='released',item,status:item?assignmentStatus(state,item.claimId,observedAt):'unassigned'};\r\n   });\r\n  },\r\n  async choose(kind,clientWorkoutIds,displayedAccount){\r\n   if(!['import','keep_local'].includes(kind)||!Array.isArray(clientWorkoutIds)||clientWorkoutIds.length<1||clientWorkoutIds.length>100||new Set(clientWorkoutIds).size!==clientWorkoutIds.length)fail('invalid_choice');\r\n   const selectedIds=[...clientWorkoutIds],expected=kind==='import'?target(displayedAccount):null,ticket=expected?transitions.capture():null;\r\n   if(expected)await fresh(ticket,expected);\r\n   const input={decisionId:randomUUID(),kind,selections:selectedIds.map(clientWorkoutId=>({clientWorkoutId,claimId:randomUUID(),itemId:randomUUID()})),...(expected?{targetAccountId:expected.owner,targetDataEpoch:expected.epoch}:{})};\r\n   const prepared=await repository.prepareImportDecision(input);if(expected)current(ticket,expected);\r\n   const result=await repository.commitImportDecision(prepared);if(expected)current(ticket,expected);\r\n   return result;\r\n  },\r\n  async reconcileDeletedTarget(displayedAccount){\r\n   const expected=target(displayedAccount),ticket=transitions.capture(),account=await fresh(ticket,expected),proof=account.deletionEvidence;\r\n   if(!proof||proof.ownerId!==expected.owner||proof.currentDataEpoch!==expected.epoch||!Number.isSafeInteger(proof.deletedThroughEpoch)||proof.deletedThroughEpoch!==expected.epoch-1)fail('invalid_deletion_evidence');\r\n   if(proof.deletedThroughEpoch===0)return 0;\r\n   const state=await repository.listImportAssignments();current(ticket,expected);let count=0;\r\n   for(const item of state.items){\r\n    if(item.kind!=='import'||item.targetAccountId!==expected.owner||item.targetDataEpoch>proof.deletedThroughEpoch)continue;\r\n    current(ticket,expected);\r\n    const result=await repository.releaseImportAssignment({claimId:item.claimId,generation:item.generation,ownerId:proof.ownerId,currentDataEpoch:proof.currentDataEpoch,deletedThroughEpoch:proof.deletedThroughEpoch});\r\n    if(!result.duplicate)count++;\r\n   }\r\n   current(ticket,expected);return count;\r\n  },\r\n  async upload(displayedAccount,{resumeParkedClaimIds=[]}={}){\r\n   // Fail closed before auth, IndexedDB or transport when the build is disabled.\r\n   if(manifest.uploadsEnabled!==true)return {stopped:'disabled',posted:0,imported:0};\r\n   const expected=target(displayedAccount),ticket=transitions.capture();await fresh(ticket,expected);\r\n   const result=await drain.run({targetAccountId:expected.owner,resumeParkedClaimIds});current(ticket,expected);return result;\r\n  },\r\n });\r\n}\r\n","local-coach/import-assignment.mjs":"import {isAttemptEvent,validateAttemptEvents,projectImportAttempts} from './import-attempts.mjs';\r\n// Pure policy for a single owner's guest-import history. The caller must load\r\n// validated source workouts and commit returned changes in one transaction.\r\n// Epochs/proofs come from an authenticated adapter: shape checks are NOT auth.\r\nexport class ImportAssignmentError extends Error {\r\n  constructor(code, message = code) { super(message); this.name = 'ImportAssignmentError'; this.code = code; }\r\n}\r\nconst policyFailures = new WeakSet();\r\nconst fail = (code, message) => { const error = new ImportAssignmentError(code, message); policyFailures.add(error); throw error; };\r\nconst own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);\r\nconst opaque = (value, name) => {\r\n  if (typeof value !== 'string' || !value || value.length > 512 || value.trim() !== value) fail('invalid-record', name + ' must be a canonical opaque id');\r\n  return value;\r\n};\r\nconst positive = (value, name) => {\r\n  if (!Number.isSafeInteger(value) || value < 1) fail('invalid-record', name + ' must be a positive safe integer');\r\n  return value;\r\n};\r\nconst owned = new WeakSet();\r\nconst freeze = value => {\r\n  if (value && typeof value === 'object' && !Object.isFrozen(value)) {\r\n    for (const key of Object.getOwnPropertyNames(value)) freeze(value[key]);\r\n    Object.freeze(value);\r\n    owned.add(value);\r\n  }\r\n  return value;\r\n};\r\nconst canonicalJSON = value => {\r\n  try {\r\n  const ancestors = new Set();\r\n  let remaining = 131072;\r\n  const count = text => {\r\n    remaining -= text.length;\r\n    if (remaining < 0) fail('invalid-record', 'canonical record including its envelope exceeds the local record limit');\r\n    return text;\r\n  };\r\n  const visit = (input, depth = 0) => {\r\n    if (depth > 64) fail('invalid-record', 'snapshot is too deep');\r\n    if (input === null || typeof input === 'string' || typeof input === 'boolean') return count(JSON.stringify(input));\r\n    if (typeof input === 'number' && Number.isFinite(input)) return count(JSON.stringify(input));\r\n    if (!input || typeof input !== 'object' || ancestors.has(input)) fail('invalid-record', 'snapshot must be JSON');\r\n    const array = Array.isArray(input);\r\n    const descriptors = Object.getOwnPropertyDescriptors(input);\r\n    if (Object.getOwnPropertySymbols(descriptors).length) fail('invalid-record');\r\n    const keys = Object.keys(descriptors).filter(key => descriptors[key].enumerable);\r\n    const length = array ? descriptors.length?.value : 0;\r\n    if (array) {\r\n      if (Object.getPrototypeOf(input) !== Array.prototype) fail('invalid-record', 'snapshot arrays must be plain arrays');\r\n      if (!Number.isSafeInteger(length) || length > remaining || keys.length !== length || keys.some((key, index) => key !== String(index))) fail('invalid-record', 'snapshot arrays must be dense and bounded');\r\n    } else if (![Object.prototype, null].includes(Object.getPrototypeOf(input))) fail('invalid-record', 'snapshot must contain plain objects');\r\n    if (Object.keys(descriptors).length !== keys.length + (array ? 1 : 0) || keys.some(key => !own(descriptors[key], 'value'))) fail('invalid-record', 'snapshot must contain data properties');\r\n    count(array ? '[]' : '{}');\r\n    remaining -= Math.max(0, keys.length - 1);\r\n    if (remaining < 0) fail('invalid-record', 'snapshot exceeds the local record limit');\r\n    ancestors.add(input);\r\n    const parts = [];\r\n    for (const key of array ? keys : keys.sort()) {\r\n      parts.push((array ? '' : count(JSON.stringify(key) + ':')) + visit(descriptors[key].value, depth + 1));\r\n    }\r\n    const result = (array ? '[' : '{') + parts.join(',') + (array ? ']' : '}');\r\n    ancestors.delete(input);\r\n    return result;\r\n  };\r\n  const result = visit(value);\r\n  if (result.length > 131072) fail('invalid-record', 'canonical record including its envelope exceeds the local record limit');\r\n  return result;\r\n  } catch (error) {\r\n    if (policyFailures.has(error)) throw error;\r\n    fail('invalid-record');\r\n  }\r\n};\r\n// Capture own data descriptors without invoking input accessors. Validate the\r\n// detached record only; callers cannot change a discriminator between reads.\r\nconst dataRecord = raw => {\r\n  try {\r\n    if (!raw || typeof raw !== 'object' || Array.isArray(raw) ||\r\n        ![Object.prototype, null].includes(Object.getPrototypeOf(raw))) fail('invalid-record');\r\n    const descriptors = Object.getOwnPropertyDescriptors(raw), copy = Object.create(null);\r\n    if (Object.getOwnPropertySymbols(descriptors).length) fail('invalid-record');\r\n    for (const [key, descriptor] of Object.entries(descriptors)) {\r\n      if (!own(descriptor, 'value') || !descriptor.enumerable) fail('invalid-record');\r\n      copy[key] = descriptor.value;\r\n    }\r\n    return copy;\r\n  } catch (error) {\r\n    if (policyFailures.has(error)) throw error;\r\n    fail('invalid-record');\r\n  }\r\n};\r\nconst itemKey = item => JSON.stringify([item.sourceOwnerId, item.clientWorkoutId]);\r\nconst stateOf = state => {\r\n  try {\r\n    if (!owned.has(state)) state = structuredClone(state);\r\n    if (!state || !Array.isArray(state.heads) || !Array.isArray(state.items) || !Array.isArray(state.events)) fail('invalid-state');\r\n    const ids = new Set(), headKeys = new Set();\r\n    for (const item of state.items) {\r\n      opaque(item.itemId, 'itemId'); opaque(item.claimId, 'claimId'); positive(item.generation, 'generation');\r\n      if (ids.has(item.itemId) || ids.has(item.claimId) || item.itemId === item.claimId) fail('invalid-state');\r\n      ids.add(item.itemId); ids.add(item.claimId);\r\n    }\r\n    for (const head of state.heads) {\r\n      const key = itemKey(head), item = state.items.find(candidate => candidate.claimId === head.claimId);\r\n      if (headKeys.has(key) || !['active', 'released', 'keep_local'].includes(head.status) || !item ||\r\n          item.generation !== head.generation || itemKey(item) !== key || item.itemId !== head.itemId) fail('invalid-state');\r\n      headKeys.add(key);\r\n    }\r\n    for (const event of state.events) {\r\n      const item = state.items.find(candidate => candidate.claimId === event.claimId);\r\n      if (!item || item.kind !== 'import' || (!['imported', 'retry', 'target_deleted', 'deletion_evidence'].includes(event.type) && !isAttemptEvent(event)) || event.generation !== item.generation) fail('invalid-state');\r\n      if (['target_deleted', 'deletion_evidence'].includes(event.type)) {\r\n        opaque(event.targetAccountId, 'targetAccountId');\r\n        positive(event.deletedThroughEpoch, 'deletedThroughEpoch');\r\n        positive(event.currentDataEpoch, 'currentDataEpoch');\r\n        if (event.targetAccountId !== item.targetAccountId ||\r\n            !(item.targetDataEpoch <= event.deletedThroughEpoch && event.deletedThroughEpoch < event.currentDataEpoch)) fail('invalid-state');\r\n      }\r\n    }\r\n    validateAttemptEvents(state.events);\r\n    return state;\r\n  } catch { fail('invalid-state'); }\r\n};\r\nconst deletionWatermark = (state, targetAccountId) => state.events\r\n  .filter(event => ['target_deleted', 'deletion_evidence'].includes(event.type) && event.targetAccountId === targetAccountId)\r\n  .reduce((maximum, event) => Math.max(maximum, event.deletedThroughEpoch), 0);\r\nexport const emptyImportAssignmentState = () => freeze({heads: [], items: [], events: []});\r\nconst readClaim = raw => {\r\n  raw = dataRecord(raw);\r\n  if (!raw || typeof raw !== 'object' || Array.isArray(raw) || raw.completed !== true || !['import', 'keep_local'].includes(raw.kind)) fail('invalid-record');\r\n  const fields = ['decisionId','sourceOwnerId','sourceDeviceId','clientWorkoutId','claimId','itemId','kind','completed'];\r\n  if (raw.kind === 'import') fields.push('targetAccountId','targetDataEpoch','fingerprint','snapshot');\r\n  const prepared = raw.kind === 'import' && (own(raw,'digestVersion') || own(raw,'idempotencyKey'));\r\n  if (prepared) {\r\n    fields.push('digestVersion','idempotencyKey');\r\n    if (![1,2].includes(raw.digestVersion) || typeof raw.idempotencyKey !== 'string' || !/^[0-9a-f]{64}$/.test(raw.idempotencyKey)) fail('invalid-record');\r\n  }\r\n  if (Object.keys(raw).some(key => !fields.includes(key))) fail('invalid-record', 'unexpected claim field');\r\n  const base = Object.fromEntries(fields.filter(key => !['completed','targetDataEpoch','fingerprint','snapshot','digestVersion','idempotencyKey'].includes(key)).map(key => [key, opaque(raw[key], key)]));\r\n  if (!/^guest:\\S+$/.test(base.sourceOwnerId) || base.claimId === base.itemId) fail('invalid-record');\r\n  if (raw.kind === 'keep_local') return {...base, decision: canonicalJSON(base)};\r\n  if (typeof raw.fingerprint !== 'string' || !/^[0-9a-f]{64}$/.test(raw.fingerprint) || !own(raw, 'snapshot')) fail('invalid-record');\r\n  const normalized = {...base, targetDataEpoch: positive(raw.targetDataEpoch, 'targetDataEpoch'),\r\n    fingerprint: raw.fingerprint, snapshot: JSON.parse(canonicalJSON(raw.snapshot)),\r\n    ...(prepared ? {digestVersion:raw.digestVersion,idempotencyKey:raw.idempotencyKey} : {})};\r\n  return {...normalized, decision: canonicalJSON(normalized)};\r\n};\r\nexport const claimAssignment = (state, input) => {\r\n  state = stateOf(state);\r\n  const claim = readClaim(input), prior = state.items.find(item => item.sourceOwnerId === claim.sourceOwnerId && item.decisionId === claim.decisionId && item.clientWorkoutId === claim.clientWorkoutId);\r\n  if (prior) {\r\n    if (prior.decision !== claim.decision) fail('decision-conflict');\r\n    return freeze({state, item: prior, duplicate: true});\r\n  }\r\n  if (state.items.some(item => [item.itemId, item.claimId].includes(claim.itemId) || [item.itemId, item.claimId].includes(claim.claimId))) fail('id-conflict');\r\n  const key = itemKey(claim), previous = state.heads.find(head => itemKey(head) === key);\r\n  if (previous && previous.status !== 'released') fail('covered');\r\n  if (claim.kind === 'import') {\r\n    const watermark = deletionWatermark(state, claim.targetAccountId);\r\n    if (claim.targetDataEpoch <= watermark) fail('deleted-target-epoch');\r\n  }\r\n  const generation = state.items.filter(item => itemKey(item) === key).reduce((maximum, item) => Math.max(maximum, item.generation), 0) + 1;\r\n  positive(generation, 'generation');\r\n  const item = freeze({...claim, generation});\r\n  const head = freeze({sourceOwnerId: claim.sourceOwnerId, sourceDeviceId: claim.sourceDeviceId, clientWorkoutId: claim.clientWorkoutId,\r\n    claimId: claim.claimId, itemId: claim.itemId, generation, status: claim.kind === 'keep_local' ? 'keep_local' : 'active'});\r\n  return freeze({state: {\r\n    heads: previous ? state.heads.map(candidate => itemKey(candidate) === key ? head : candidate) : [...state.heads, head],\r\n    items: [...state.items, item], events: state.events,\r\n  }, item, duplicate: false});\r\n};\r\nexport const assignmentStatus = (state, claimId, now) => {\r\n  state = stateOf(state);\r\n  const item = state.items.find(candidate => candidate.claimId === claimId);\r\n  if (!item) fail('not-found');\r\n  if (item.kind === 'keep_local') return 'keep_local';\r\n  if (item.targetDataEpoch <= deletionWatermark(state, item.targetAccountId)) return 'target_deleted';\r\n  if (state.events.some(event=>event.claimId===claimId&&event.type==='target_deleted')) return 'target_deleted';\r\n  return projectImportAttempts(state.events.filter(event=>event.claimId===claimId),now).status;\r\n};\r\nexport const recordImportOutcome = (state, callback) => {\r\n  state = stateOf(state);\r\n  callback = dataRecord(callback);\r\n  if (!callback || !['imported','retry'].includes(callback.type)) fail('invalid-record');\r\n  const item = state.items.find(candidate => candidate.claimId === callback.claimId);\r\n  if (!item || item.kind !== 'import' || item.generation !== callback.generation ||\r\n      item.sourceOwnerId !== callback.sourceOwnerId || item.sourceDeviceId !== callback.sourceDeviceId ||\r\n      item.clientWorkoutId !== callback.clientWorkoutId) fail('not-found');\r\n  const status = assignmentStatus(state, item.claimId);\r\n  if (status === 'target_deleted' || status === 'imported' || ['conflict','rejected'].includes(status) || status === callback.type) return freeze({state, item, duplicate: true});\r\n  if (own(item,'digestVersion')) fail('invalid-record', 'Prepared import outcomes require a committed attempt.');\r\n  const event = freeze({type: callback.type, claimId: item.claimId, generation: item.generation});\r\n  return freeze({state: {...state, events: [...state.events, event]}, item, duplicate: false});\r\n};\r\nexport const recordImported = (state, callback) => recordImportOutcome(state, {...dataRecord(callback), type: 'imported'});\r\nexport const releaseAssignment = (state, proof) => {\r\n  state = stateOf(state);\r\n  proof = dataRecord(proof);\r\n  if (!proof || typeof proof !== 'object') fail('invalid-record');\r\n  const item = state.items.find(candidate => candidate.claimId === proof.claimId);\r\n  const generation = positive(proof.generation, 'generation'), ownerId = opaque(proof.ownerId, 'ownerId');\r\n  const currentDataEpoch = positive(proof.currentDataEpoch, 'currentDataEpoch'), deletedThroughEpoch = positive(proof.deletedThroughEpoch, 'deletedThroughEpoch');\r\n  if (!item || item.kind !== 'import' || item.generation !== generation || item.targetAccountId !== ownerId ||\r\n      !(item.targetDataEpoch <= deletedThroughEpoch && deletedThroughEpoch < currentDataEpoch)) fail('invalid-deletion-proof');\r\n  const old = state.events.find(event => event.type === 'target_deleted' && event.claimId === item.claimId);\r\n  const maximum = state.events.filter(event => event.claimId === item.claimId && ['target_deleted','deletion_evidence'].includes(event.type))\r\n    .reduce((value, event) => Math.max(value, event.deletedThroughEpoch), 0);\r\n  if (old && maximum >= deletedThroughEpoch) return freeze({state, item, duplicate: true});\r\n  const event = freeze({type: old ? 'deletion_evidence' : 'target_deleted', claimId: item.claimId, generation,\r\n    targetAccountId: ownerId, currentDataEpoch, deletedThroughEpoch});\r\n  const key = itemKey(item), heads = state.heads.map(head => itemKey(head) === key && head.claimId === item.claimId && head.generation === generation\r\n    ? freeze({...head, status: 'released'}) : head);\r\n  return freeze({state: {...state, heads, events: [...state.events, event]}, item, duplicate: false});\r\n};\r\n","local-coach/import-attempts.mjs":"import {validateImportSnapshot,canonicalImportKey} from '../workout-import-codec.mjs';\r\nexport const IMPORT_ATTEMPT_STALE_MS=30000;\r\nconst own=(value,key)=>Object.prototype.hasOwnProperty.call(value,key);\r\nconst invalid=()=>{throw Error('Invalid import attempt record.');};\r\nconst id=value=>{if(typeof value!=='string'||!value||value.length>512||value.trim()!==value)invalid();};\r\nconst integer=(value,min=0)=>{if(!Number.isSafeInteger(value)||value<min)invalid();};\r\nfunction data(raw){\r\n if(!raw||typeof raw!=='object'||Array.isArray(raw)||![null,Object.prototype].includes(Object.getPrototypeOf(raw)))invalid();\r\n const descriptors=Object.getOwnPropertyDescriptors(raw),out={};\r\n if(Reflect.ownKeys(descriptors).some(key=>typeof key!=='string'||!own(descriptors[key],'value')||!descriptors[key].enumerable))invalid();\r\n for(const [key,descriptor]of Object.entries(descriptors))Object.defineProperty(out,key,{value:descriptor.value,enumerable:true});\r\n return out;\r\n}\r\nconst exact=(record,keys)=>{if(Object.keys(record).length!==keys.length||keys.some(key=>!own(record,key)))invalid();};\r\nconst resultTypes=['imported','retryable_failure','parked','conflict','rejected'];\r\nexport function isAttemptEvent(event){return ['retry_budget_resumed','submission_started','retryable_failure','parked','conflict','rejected'].includes(event.type)||event.type==='imported'&&own(event,'attemptId');}\r\nfunction captureBegin(raw){\r\n const v=data(raw);exact(v,['claimId','generation','attemptId','startedAt']);\r\n id(v.claimId);id(v.attemptId);integer(v.generation,1);integer(v.startedAt);\r\n integer(v.startedAt+IMPORT_ATTEMPT_STALE_MS);\r\n return {type:'submission_started',claimId:v.claimId,generation:v.generation,attemptId:v.attemptId,startedAt:v.startedAt,expiresAt:v.startedAt+IMPORT_ATTEMPT_STALE_MS};\r\n}\r\nfunction captureResult(raw){\r\n const v=data(raw);id(v.claimId);id(v.attemptId);integer(v.generation,1);integer(v.at);\r\n if(!resultTypes.includes(v.type))invalid();\r\n const keys=['claimId','generation','attemptId','type','at'];\r\n if(v.type==='imported'){\r\n  keys.push('serverWorkoutId','httpStatus');id(v.serverWorkoutId);if(![200,201].includes(v.httpStatus))invalid();\r\n }else{\r\n  keys.push('category');\r\n  const categories={retryable_failure:['offline','timeout','rate_limited','server_unavailable','unknown_response'],parked:['signed_out','target_mismatch','feature_disabled','retry_exhausted','epoch_mismatch'],conflict:['fingerprint_conflict'],rejected:['invalid_payload','policy_rejected']};\r\n  if(!categories[v.type].includes(v.category))invalid();\r\n  if(own(v,'httpStatus')){keys.push('httpStatus');integer(v.httpStatus,100);if(v.httpStatus>599)invalid();}\r\n  if(v.type==='retryable_failure'){keys.push('retryAt');integer(v.retryAt,v.at);if(v.retryAt-v.at>86400000)invalid();}\r\n }\r\n exact(v,keys);return Object.fromEntries(keys.map(key=>[key,v[key]]));\r\n}\r\nconst same=(a,b)=>JSON.stringify(a)===JSON.stringify(b);\r\n// Relational validation makes persisted malformed/orphan results fail closed.\r\nexport function validateAttemptEvents(events){\r\n const starts=new Map(),results=new Set();\r\n for(const event of events){\r\n  if(!isAttemptEvent(event))continue;\r\n  if(event.type==='retry_budget_resumed'){\r\n   exact(event,['type','claimId','generation','resumeId','at']);id(event.claimId);id(event.resumeId);integer(event.generation,1);integer(event.at);\r\n   const index=events.indexOf(event),next=events[index+1];\r\n   if(!next||next.type!=='submission_started'||next.attemptId!==event.resumeId||next.claimId!==event.claimId||next.generation!==event.generation||next.startedAt!==event.at||projectImportAttempts(events.slice(0,index).filter(e=>e.claimId===event.claimId),event.at).status!=='parked')invalid();\r\n  }else if(event.type==='submission_started'){\r\n   const {type,expiresAt,attemptLimit,...input}=event,normalized=captureBegin(input);\r\n   if(attemptLimit!==undefined){integer(attemptLimit,1);if(attemptLimit>5)invalid();normalized.attemptLimit=attemptLimit;}\r\n   if(!same(event,normalized)||starts.has(event.attemptId))invalid();starts.set(event.attemptId,event);\r\n  }else{\r\n   const normalized=captureResult(event),start=starts.get(event.attemptId);\r\n   // Property order is not semantic for caller/re-hydrated result records.\r\n   if(Object.keys(event).length!==Object.keys(normalized).length||!start||results.has(event.attemptId)||start.claimId!==event.claimId||start.generation!==event.generation||event.at<start.startedAt)invalid();\r\n   results.add(event.attemptId);\r\n  }\r\n }\r\n}\r\nfunction projectWithoutBudget(events,now){\r\n if(events.some(e=>e.type==='imported'))return {status:'imported'};\r\n const terminal=events.find(e=>e.type==='conflict'||e.type==='rejected');if(terminal)return {status:terminal.type};\r\n const latest=events.filter(e=>e.type==='submission_started').at(-1);\r\n if(!latest)return {status:events.some(e=>e.type==='retry')?'retry':'pending'};\r\n const result=events.find(e=>e.attemptId===latest.attemptId&&e.type!=='submission_started');\r\n if(!result)return {status:now!==undefined&&now>=latest.expiresAt?'retryable':'in_flight',attemptId:latest.attemptId,retryAt:latest.expiresAt};\r\n return {status:result.type==='retryable_failure'?'retryable':result.type,attemptId:latest.attemptId,...(result.type==='retryable_failure'?{retryAt:result.retryAt}:{})};\r\n}\r\nexport function importRetryBudget(events){\r\n const boundary=events.findLastIndex(e=>e.type==='retry_budget_resumed');\r\n const starts=events.slice(boundary+1).filter(e=>e.type==='submission_started');\r\n return {attemptNumber:starts.length,attemptLimit:starts[0]?.attemptLimit??3};\r\n}\r\nexport function projectImportAttempts(events,now){\r\n const projection=projectWithoutBudget(events,now),budget=importRetryBudget(events);\r\n if(projection.status==='retryable'&&budget.attemptNumber>=budget.attemptLimit)return {...budget,status:'parked',category:'retry_exhausted'};\r\n return {...projection,...budget};\r\n}\r\nfunction preparedItem(state,claimId,ownerId,deviceId){\r\n const item=state.items.find(i=>i.claimId===claimId);\r\n if(!ownerId.startsWith('guest:')||!item||item.kind!=='import'||item.sourceOwnerId!==ownerId||item.sourceDeviceId!==deviceId)invalid();\r\n const header=state.decisions.find(d=>d.decisionId===item.decisionId);\r\n if(!header||header.preparationVersion!==1||header.kind!=='import'||header.sourceOwnerId!==ownerId||header.sourceDeviceId!==deviceId||!Array.isArray(header.selections)||header.selections.length<1||header.selections.length>100)invalid();\r\n exact(header,['sourceOwnerId','decisionId','sourceDeviceId','kind','targetAccountId','targetDataEpoch','preparationVersion','selections']);\r\n const rows=state.items.filter(i=>i.decisionId===header.decisionId),selected=new Set(),identities=new Set();\r\n if(rows.length!==header.selections.length)invalid();\r\n for(const s of header.selections){\r\n  exact(s,['clientWorkoutId','claimId','itemId']);id(s.clientWorkoutId);id(s.claimId);id(s.itemId);\r\n  if(selected.has(s.clientWorkoutId)||identities.has(s.claimId)||identities.has(s.itemId)||s.claimId===s.itemId)invalid();\r\n  selected.add(s.clientWorkoutId);identities.add(s.claimId);identities.add(s.itemId);\r\n  const row=rows.find(i=>i.clientWorkoutId===s.clientWorkoutId&&i.claimId===s.claimId&&i.itemId===s.itemId);\r\n  if(!row||row.kind!=='import'||row.sourceOwnerId!==ownerId||row.sourceDeviceId!==deviceId||row.targetAccountId!==header.targetAccountId||row.targetDataEpoch!==header.targetDataEpoch||![1,2].includes(row.digestVersion)||typeof row.idempotencyKey!=='string'||!(/^[a-f0-9]{64}$/).test(row.idempotencyKey))invalid();\r\n  validateImportSnapshot(row.snapshot);if(row.snapshot.clientWorkoutId!==row.clientWorkoutId)invalid();\r\n  canonicalImportKey({digestVersion:row.digestVersion,targetAccountId:row.targetAccountId,targetDataEpoch:row.targetDataEpoch,clientWorkoutId:row.clientWorkoutId,fingerprint:row.fingerprint});\r\n }\r\n return item;\r\n}\r\nexport function createImportAttempts({db,ownerId,deviceId,tables,read,persist,transact,readOperation,status,invalid:storageInvalid}){\r\n const guard=fn=>{try{return fn();}catch{storageInvalid('Invalid import attempt or incomplete prepared decision.');}};\r\n const inspect=(state,item,now)=>{\r\n  const authoritative=status(state,item.claimId);\r\n  if(['target_deleted','keep_local','imported','conflict','rejected'].includes(authoritative))return {status:authoritative};\r\n  return projectImportAttempts(state.events.filter(e=>e.claimId===item.claimId),now);\r\n };\r\n return Object.freeze({\r\n  async beginImportAttempt(input,{resumeParked=false,attemptLimit=3}={}){\r\n   guard(()=>{integer(attemptLimit,1);if(attemptLimit>5)invalid();});\r\n   const event=guard(()=>captureBegin(input));\r\n   return transact('Import attempt start',tables,async()=>{\r\n    const state=await read(),item=guard(()=>preparedItem(state,event.claimId,ownerId,deviceId));\r\n    if(item.generation!==event.generation)storageInvalid('Import attempt generation mismatch.');\r\n    // Exact retry may observe a terminal outcome; it never authorizes another POST.\r\n    const prior=state.events.find(e=>e.type==='submission_started'&&e.attemptId===event.attemptId);\r\n    if(prior){const {attemptLimit:_limit,...identity}=prior;if(!same(identity,event))storageInvalid('Attempt identity cannot change.');return {duplicate:true,item,...inspect(state,item,event.startedAt)};}\r\n    const lastTime=state.events.reduce((latest,e)=>e.claimId===item.claimId?Math.max(latest,e.at??e.startedAt??0):latest,0);\r\n    if(event.startedAt<lastTime)storageInvalid('Attempt time cannot precede prior observations.');\r\n    const current=inspect(state,item,event.startedAt),head=state.heads.find(h=>h.claimId===item.claimId&&h.generation===item.generation&&h.clientWorkoutId===item.clientWorkoutId);\r\n    if(!head||head.status!=='active'||current.status==='parked'&&resumeParked!==true||['target_deleted','imported','conflict','rejected','in_flight'].includes(current.status)||current.retryAt>event.startedAt)storageInvalid('Import attempt is not eligible.');\r\n    const events=state.events.filter(e=>e.claimId===item.claimId),budget=importRetryBudget(events);\r\n    const resuming=current.status==='parked'&&resumeParked===true;\r\n    const limit=resuming||budget.attemptNumber===0?attemptLimit:budget.attemptLimit;\r\n    if(!resuming&&budget.attemptNumber>=limit)storageInvalid('Import retry budget is exhausted.');\r\n    const resume=resuming?[{type:'retry_budget_resumed',claimId:item.claimId,generation:item.generation,resumeId:event.attemptId,at:event.startedAt}]:[];\r\n    const after={...state,events:[...state.events,...resume,{...event,attemptLimit:limit}]};guard(()=>validateAttemptEvents(after.events));await persist(state,after);\r\n    return {duplicate:false,item,...inspect(after,item,event.startedAt)};\r\n   });\r\n  },\r\n  async recordImportAttemptResult(input){\r\n   const event=guard(()=>captureResult(input));\r\n   return transact('Import attempt result',tables,async()=>{\r\n    const state=await read(),item=guard(()=>preparedItem(state,event.claimId,ownerId,deviceId));\r\n    if(item.generation!==event.generation)storageInvalid('Import attempt generation mismatch.');\r\n    // Validate existing state even if a duplicate will be returned.\r\n    guard(()=>validateAttemptEvents(state.events));status(state,item.claimId);\r\n    const start=state.events.find(e=>e.type==='submission_started'&&e.attemptId===event.attemptId);\r\n    if(!start||start.claimId!==event.claimId||start.generation!==event.generation||event.at<start.startedAt)storageInvalid('Result must match a committed attempt.');\r\n    const prior=state.events.find(e=>e.attemptId===event.attemptId&&e.type!=='submission_started');\r\n    if(prior){if(!same(captureResult(prior),event))storageInvalid('An attempt result cannot change.');return {duplicate:true,item,...inspect(state,item,event.at)};}\r\n    const after={...state,events:[...state.events,event]};guard(()=>validateAttemptEvents(after.events));await persist(state,after);\r\n    return {duplicate:false,item,...inspect(after,item,event.at)};\r\n   });\r\n  },\r\n  async importAttemptState(claimId,now){\r\n   guard(()=>{id(claimId);integer(now);});\r\n   return readOperation('Import attempt status',()=>db.transaction('r',...tables,async()=>{const state=await read(),item=guard(()=>preparedItem(state,claimId,ownerId,deviceId));return {item,...inspect(state,item,now)};}));\r\n  },\r\n });\r\n}\r\n","local-coach/import-ledger.mjs":"import {createImportAttempts} from './import-attempts.mjs';\r\nimport {createImportPreparation} from './import-preparation.mjs';\r\nimport {ImportAssignmentError,claimAssignment,recordImportOutcome,releaseAssignment,assignmentStatus} from './import-assignment.mjs';\r\n\r\n// Layout version is independent of the unchanged v1 workout row schema.\r\nexport const IMPORT_LEDGER_STORES=Object.freeze({\r\n guestHistoryDecisions:'[sourceOwnerId+decisionId],sourceOwnerId',\r\n guestHistoryItems:'&itemId,&claimId,&[sourceOwnerId+decisionId+clientWorkoutId],&[sourceOwnerId+clientWorkoutId+generation],sourceOwnerId',\r\n guestHistoryEvents:'++sequence,sourceOwnerId,claimId',\r\n guestHistoryAssignmentHeads:'[sourceOwnerId+clientWorkoutId],sourceOwnerId',\r\n});\r\nexport const importLedgerTables=db=>Object.keys(IMPORT_LEDGER_STORES).map(name=>db.table(name));\r\nexport async function readImportLedger(db,sourceOwnerId,StorageError){\r\n const read=async name=>(await db.table(name).where('sourceOwnerId').equals(sourceOwnerId).toArray()).map(row=>{if(row.schemaVersion!==1)throw new StorageError('invalid-record','Unsupported import ledger row schema.',{recoverable:true});const {schemaVersion,...value}=row;return value;});\r\n const [decisions,items,eventRows,heads]=await Promise.all(Object.keys(IMPORT_LEDGER_STORES).map(read));\r\n const compare=(a,b)=>a<b?-1:a>b?1:0;\r\n decisions.sort((a,b)=>compare(a.sourceOwnerId,b.sourceOwnerId)||compare(a.decisionId,b.decisionId));\r\n heads.sort((a,b)=>compare(a.sourceOwnerId,b.sourceOwnerId)||compare(a.clientWorkoutId,b.clientWorkoutId));\r\n items.sort((a,b)=>compare(a.sourceOwnerId,b.sourceOwnerId)||compare(a.clientWorkoutId,b.clientWorkoutId)||a.generation-b.generation);\r\n return {decisions,heads,items,events:eventRows.sort((a,b)=>a.sequence-b.sequence).map(({sequence,sourceOwnerId,...event})=>event)};\r\n}\r\nexport async function deleteImportLedger(db,sourceOwnerId){\r\n const counts={};\r\n for(const name of Object.keys(IMPORT_LEDGER_STORES))counts[name]=await db.table(name).where('sourceOwnerId').equals(sourceOwnerId).delete();\r\n return counts;\r\n}\r\nexport function createImportLedger({db,ownerId,deviceId,getWorkout,transact,StorageError,classifyError}){\r\n const tables=importLedgerTables(db);\r\n const policy=fn=>{try{return fn();}catch(error){if(error instanceof ImportAssignmentError)throw new StorageError(error.code,error.message,{cause:error,recoverable:true});throw error;}};\r\n const invalid=message=>{throw new StorageError('invalid-record',message,{recoverable:true});};\r\n // getWorkout must only read the workouts table and open no nested write\r\n // transaction. Repository supplies its internal owner-scoped validator.\r\n const readOperation=async(label,fn)=>{try{return await fn();}catch(error){throw classifyError(error,label);}};\r\n const source=async clientWorkoutId=>{\r\n  const workout=await getWorkout(clientWorkoutId);\r\n  if(!ownerId.startsWith('guest:')||!workout||workout.status!=='completed'||workout.id!==clientWorkoutId||workout.id!==workout.clientWorkoutId||workout.ownerId!==ownerId||workout.deviceId!==deviceId)invalid('Import source must be a completed workout owned by this guest and device.');\r\n  return workout;\r\n };\r\n const persist=async(before,after)=>{\r\n  // Assert append-only policy output before any writes, including all head keys.\r\n  const same=(a,b)=>JSON.stringify(a)===JSON.stringify(b),headKey=head=>JSON.stringify([head.sourceOwnerId,head.clientWorkoutId]);\r\n  for(const key of ['items','events'])if(after[key].length<before[key].length||before[key].some((entry,index)=>!same(entry,after[key][index])))invalid('Import policy attempted to change immutable history.');\r\n  const nextKeys=after.heads.map(headKey);\r\n  if(after.heads.length<before.heads.length||new Set(nextKeys).size!==nextKeys.length||before.heads.some(head=>!nextKeys.includes(headKey(head))))invalid('Import policy attempted to remove an assignment head.');\r\n  if(after.items.slice(before.items.length).some(item=>item.sourceOwnerId!==ownerId)||after.heads.some(head=>head.sourceOwnerId!==ownerId))invalid('Import policy output has a mismatched source owner.');\r\n  // Immutable rows are appended only; head replacement is the sole mutation.\r\n  for(const item of after.items.slice(before.items.length))await db.guestHistoryItems.add({...item,schemaVersion:1});\r\n  for(const event of after.events.slice(before.events.length))await db.guestHistoryEvents.add({...event,sourceOwnerId:ownerId,schemaVersion:1});\r\n  for(const head of after.heads){\r\n   const old=before.heads.find(candidate=>candidate.sourceOwnerId===head.sourceOwnerId&&candidate.clientWorkoutId===head.clientWorkoutId);\r\n   if(JSON.stringify(old)!==JSON.stringify(head))await db.guestHistoryAssignmentHeads.put({...head,schemaVersion:1});\r\n  }\r\n };\r\n const transition=(label,fn)=>transact(label,tables,async()=>{\r\n  const before=await readImportLedger(db,ownerId,StorageError),result=policy(()=>fn(before));\r\n  await persist(before,result.state);\r\n  return {item:result.item,duplicate:result.duplicate,status:assignmentStatus(result.state,result.item.claimId)};\r\n });\r\n return Object.freeze({\r\n  ...createImportAttempts({db,ownerId,deviceId,tables,read:()=>readImportLedger(db,ownerId,StorageError),persist,transact,readOperation,status:assignmentStatus,invalid}),\r\n  ...createImportPreparation({db,ownerId,deviceId,tables,source,persist,transact,read:()=>readImportLedger(db,ownerId,StorageError),policy,invalid,readOperation,StorageError}),\r\n  // Call before any asynchronous hashing. The revision is rechecked inside the\r\n  // claim transaction. This legacy API cannot create prepared upload metadata;\r\n  // callers must use prepareImportDecision for codec-bound decisions.\r\n  async prepareImportAssignment(clientWorkoutId){\r\n   return readOperation('Import assignment preparation',()=>db.transaction('r',db.workouts,async()=>{const workout=await source(clientWorkoutId);return {workout,sourceRevision:JSON.stringify(workout)};}));\r\n  },\r\n  async claimImportAssignment(input,{sourceRevision}={}){\r\n   // First capture/validate input through policy, without reading raw accessors.\r\n   const {generation,decision,...captured}=policy(()=>claimAssignment({heads:[],items:[],events:[]},input)).item;\r\n   if(Object.hasOwn(captured,'digestVersion')||Object.hasOwn(captured,'idempotencyKey'))invalid('Prepared import metadata requires prepareImportDecision.');\r\n   const claim={...captured,completed:true};\r\n   if(claim.sourceOwnerId!==ownerId||claim.sourceDeviceId!==deviceId)invalid('Import source scope does not match.');\r\n   return transact('Import assignment claim',[db.workouts,...tables],async()=>{\r\n    const before=await readImportLedger(db,ownerId,StorageError),result=policy(()=>claimAssignment(before,claim));\r\n    // Exact historical retries return the original item even if its source has\r\n    // since changed. The policy rejects any altered retry before this return.\r\n    if(result.duplicate)return {item:result.item,duplicate:true,status:assignmentStatus(result.state,result.item.claimId)};\r\n    if(typeof sourceRevision!=='string')invalid('A prepared source revision is required.');\r\n    const workout=await source(claim.clientWorkoutId);\r\n    if(JSON.stringify(workout)!==sourceRevision)invalid('Import source changed after preparation.');\r\n    const header={sourceOwnerId:ownerId,decisionId:claim.decisionId,sourceDeviceId:deviceId,kind:claim.kind,...(claim.kind==='import'?{targetAccountId:claim.targetAccountId,targetDataEpoch:claim.targetDataEpoch}:{})};\r\n    const stored=await db.guestHistoryDecisions.get([ownerId,claim.decisionId]);\r\n    const prior=stored?(({schemaVersion,...header})=>header)(stored):null;\r\n    if(prior&&JSON.stringify(prior)!==JSON.stringify(header))invalid('Decision identity cannot change its target or choice.');\r\n    if(!prior)await db.guestHistoryDecisions.add({...header,schemaVersion:1});\r\n    await persist(before,result.state);\r\n    return {item:result.item,duplicate:result.duplicate,status:assignmentStatus(result.state,result.item.claimId)};\r\n   });\r\n  },\r\n  // Only a future authenticated adapter may supply deletion evidence. Shape\r\n  // validation and IndexedDB transactions do not authenticate a server response.\r\n  async releaseImportAssignment(proof){return transition('Import assignment release',state=>releaseAssignment(state,proof));},\r\n  async recordImportAssignmentOutcome(callback){return transition('Import assignment outcome',state=>recordImportOutcome(state,callback));},\r\n  async listImportAssignments(){return readOperation('Import assignment history',()=>db.transaction('r',...tables,async()=>readImportLedger(db,ownerId,StorageError)));},\r\n });\r\n}\r\n","local-coach/import-preparation.mjs":"import {WorkoutImportCodecError,snapshotFromCompletedWorkout,prepareWorkoutImport} from '../workout-import-codec.mjs';\r\nimport {claimAssignment,assignmentStatus} from './import-assignment.mjs';\r\n\r\n// No network and no asynchronous crypto within an IndexedDB transaction.\r\n// Tokens are process-local capabilities, not serialized caller-supplied claims.\r\nexport function createImportPreparation({db,ownerId,deviceId,tables,source,persist,transact,read,policy,invalid,readOperation,StorageError}) {\r\n const tokens=new WeakMap(),same=(a,b)=>JSON.stringify(a)===JSON.stringify(b);\r\n const own=(v,k)=>Object.prototype.hasOwnProperty.call(v,k);\r\n const record=(raw,keys)=>{\r\n  if(!raw||typeof raw!=='object'||Array.isArray(raw)||![null,Object.prototype].includes(Object.getPrototypeOf(raw)))invalid('Expected own data fields.');\r\n  const descriptors=Object.getOwnPropertyDescriptors(raw);\r\n  if(Reflect.ownKeys(descriptors).length!==keys.length||keys.some(key=>!own(descriptors,key)||!own(descriptors[key],'value')||!descriptors[key].enumerable))invalid('Unexpected or accessor choice field.');\r\n  return Object.fromEntries(keys.map(key=>[key,descriptors[key].value]));\r\n };\r\n const id=value=>{if(typeof value!=='string'||!value||value.length>512||value.trim()!==value)invalid('Invalid choice identifier.');return value;};\r\n const captureUnsafe=raw=>{\r\n  // Inspect kind as data before selecting the exact supported input shape.\r\n  const d=raw&&Object.getOwnPropertyDescriptor(raw,'kind');\r\n  if(!d||!own(d,'value')||!['import','keep_local'].includes(d.value))invalid('Choose import or keep_local.');\r\n  const input=record(raw,['decisionId','kind','selections',...(d.value==='import'?['targetAccountId','targetDataEpoch']:[])]);\r\n  id(input.decisionId);\r\n  if(!Array.isArray(input.selections)||Object.getPrototypeOf(input.selections)!==Array.prototype||input.selections.length<1||input.selections.length>100)invalid('Select between one and 100 workouts.');\r\n  const descriptors=Object.getOwnPropertyDescriptors(input.selections),length=input.selections.length;\r\n  if(Reflect.ownKeys(descriptors).length!==length+1)invalid('Selections must be dense data.');\r\n  const selections=[];\r\n  for(let i=0;i<length;i++){\r\n   const descriptor=descriptors[i];if(!descriptor||!own(descriptor,'value'))invalid('Selections must be dense data.');\r\n   const entry=record(descriptor.value,['clientWorkoutId','claimId','itemId']);\r\n   for(const key of Object.keys(entry))id(entry[key]);\r\n   selections.push(entry);\r\n  }\r\n  selections.sort((a,b)=>a.clientWorkoutId<b.clientWorkoutId?-1:a.clientWorkoutId>b.clientWorkoutId?1:0);\r\n  if(new Set(selections.map(s=>s.clientWorkoutId)).size!==length||new Set(selections.flatMap(s=>[s.claimId,s.itemId])).size!==length*2)invalid('Choice selections and identities must be unique.');\r\n  if(input.kind==='import'){\r\n   id(input.targetAccountId);\r\n   if(!Number.isSafeInteger(input.targetDataEpoch)||input.targetDataEpoch<1)invalid('Invalid target epoch.');\r\n  }\r\n  return {sourceOwnerId:ownerId,decisionId:input.decisionId,sourceDeviceId:deviceId,kind:input.kind,\r\n   ...(input.kind==='import'?{targetAccountId:input.targetAccountId,targetDataEpoch:input.targetDataEpoch}:{}),preparationVersion:1,selections};\r\n };\r\n const capture=raw=>{try{return captureUnsafe(raw);}catch{invalid('Invalid explicit import choice.');}};\r\n const matching=(before,header)=>{\r\n  const existing=before.decisions.find(row=>row.decisionId===header.decisionId);\r\n  if(!existing)return null;\r\n  if(!same(existing,header))invalid('Decision identity cannot change its selection, target or choice.');\r\n  const items=before.items.filter(row=>row.decisionId===header.decisionId);\r\n  if(items.length!==header.selections.length||header.selections.some(s=>!items.some(item=>item.clientWorkoutId===s.clientWorkoutId&&item.claimId===s.claimId&&item.itemId===s.itemId&&item.kind===header.kind)))invalid('Stored decision is incomplete.');\r\n  return items;\r\n };\r\n const output=(state,items,duplicate)=>({items:items.map(item=>({item,status:assignmentStatus(state,item.claimId)})),duplicate});\r\n return Object.freeze({\r\n  async prepareImportDecision(input){\r\n   return readOperation('Import decision preparation',async()=>{\r\n   try{\r\n   const header=capture(input);\r\n   if(!ownerId.startsWith('guest:'))invalid('Only guest history can be selected.');\r\n   const prepared=await db.transaction('r',db.workouts,...tables,async()=>{\r\n    const before=await read(),prior=matching(before,header);\r\n    if(prior)return {header,retry:true};\r\n    const rows=[];\r\n    for(const selection of header.selections){\r\n     const workout=await source(selection.clientWorkoutId);\r\n     const head=before.heads.find(h=>h.clientWorkoutId===selection.clientWorkoutId)??null;\r\n     if(head&&head.status!=='released')invalid('Selected workout is already covered.');\r\n     rows.push({selection,workout,sourceRevision:JSON.stringify(workout),headRevision:JSON.stringify(head)});\r\n    }\r\n    return {header,rows};\r\n   });\r\n   if(!prepared.retry){\r\n    prepared.claims=[];\r\n    for(const row of prepared.rows){\r\n     const {selections,preparationVersion,...choice}=header;\r\n     const derived=header.kind==='import'?await prepareWorkoutImport(snapshotFromCompletedWorkout(row.workout),{targetAccountId:header.targetAccountId,targetDataEpoch:header.targetDataEpoch}):{};\r\n     prepared.claims.push({...choice,...row.selection,completed:true,...derived});\r\n    }\r\n   }\r\n   const token=Object.freeze({decisionId:header.decisionId,count:header.selections.length,kind:header.kind});\r\n   tokens.set(token,prepared);return token;\r\n   }catch(error){\r\n    if(error instanceof WorkoutImportCodecError)throw new StorageError(error.code,error.message,{cause:error,recoverable:true});\r\n    throw error;\r\n   }\r\n   });\r\n  },\r\n  async commitImportDecision(token){\r\n   const prepared=tokens.get(token);if(!prepared)invalid('Use a preparation token from this owner scope.');\r\n   return transact('Import decision',[db.workouts,...tables],async()=>{\r\n    const before=await read(),prior=matching(before,prepared.header);\r\n    if(prior)return output(before,prior,true);\r\n    if(prepared.retry)invalid('The prepared historical decision no longer exists.');\r\n    let state=before;const items=[];\r\n    for(let i=0;i<prepared.rows.length;i++){\r\n     const row=prepared.rows[i],workout=await source(row.selection.clientWorkoutId);\r\n     const head=before.heads.find(h=>h.clientWorkoutId===row.selection.clientWorkoutId)??null;\r\n     if(JSON.stringify(workout)!==row.sourceRevision||JSON.stringify(head)!==row.headRevision)invalid('Source or assignment changed after preparation.');\r\n     const result=policy(()=>claimAssignment(state,prepared.claims[i]));\r\n     if(result.duplicate)invalid('Decision has incomplete historical claims.');\r\n     state=result.state;items.push(result.item);\r\n    }\r\n    await db.guestHistoryDecisions.add({...prepared.header,schemaVersion:1});\r\n    await persist(before,state);\r\n    return output(state,items,false);\r\n   });\r\n  },\r\n });\r\n}\r\n","local-coach/import-sync.mjs":"import {IMPORT_UPLOAD_MANIFEST} from './import-upload-manifest.mjs';\r\nconst terminal=new Set(['imported','target_deleted','conflict','rejected','keep_local']);\r\nconst own=(v,k)=>Object.prototype.hasOwnProperty.call(v,k);\r\nconst safeRecord=value=>{\r\n if(!value||typeof value!=='object'||Array.isArray(value))throw Error('Invalid response');\r\n const descriptors=Object.getOwnPropertyDescriptors(value),out={};\r\n for(const key of Reflect.ownKeys(descriptors)){const d=descriptors[key];if(typeof key!=='string'||!own(d,'value')||!d.enumerable)throw Error('Invalid response');Object.defineProperty(out,key,{value:d.value,enumerable:true});}\r\n return out;\r\n};\r\nfunction success(reply,item){\r\n try{\r\n  if(![200,201].includes(reply.status))return false;\r\n  const body=safeRecord(reply.body),receipt=safeRecord(body.receipt),workout=safeRecord(body.workout);\r\n  const keys=['targetAccountId','targetDataEpoch','digestVersion','fingerprint','idempotencyKey'];\r\n  if(Object.keys(receipt).length!==keys.length||keys.some(key=>receipt[key]!==item[key]))return false;\r\n  if(typeof workout.id!=='string'||!workout.id||workout.id.length>512||workout.user_id!==item.targetAccountId||workout.client_workout_id!==item.clientWorkoutId||workout.source!=='guest_import'||workout.competitive_status!=='not_eligible')return false;\r\n  const fields={mode:'mode',goal:'goal',started_at:'startedAt',completed_at:'completedAt',value:'value',active:'activeSeconds'};\r\n  return Object.entries(fields).every(([key,source])=>workout[key]===item.snapshot[source])?workout.id:null;\r\n }catch{return false;}\r\n}\r\nconst abortError=()=>Object.assign(Error('Import run interrupted.'),{code:'interrupted'});\r\nconst sleep=(ms,signal)=>new Promise((resolve,reject)=>{\r\n if(signal.aborted){reject(abortError());return;}\r\n const end=()=>{clearTimeout(timer);signal.removeEventListener('abort',abort);resolve();};\r\n const abort=()=>{clearTimeout(timer);signal.removeEventListener('abort',abort);reject(abortError());};\r\n const timer=setTimeout(end,ms);signal.addEventListener('abort',abort,{once:true});\r\n});\r\n// loadAccount must authenticate and bypass caches; postImport is an injected\r\n// transport, not global fetch. Both must honor signal, but a deadline also races\r\n// their full promise so hung auth acquisition cannot hold this run indefinitely.\r\nexport function createImportDrain({repository,loadAccount,postImport,transition,\r\n manifest=IMPORT_UPLOAD_MANIFEST,now=()=>Date.now(),randomUUID=()=>crypto.randomUUID(),\r\n wait=sleep,random=Math.random,requestTimeoutMs=8000,maxAttemptsPerItem=3,maxItems=100,maxInlineDelayMs=1000}={}){\r\n if(!Number.isSafeInteger(requestTimeoutMs)||requestTimeoutMs<1||requestTimeoutMs>10000||!Number.isSafeInteger(maxAttemptsPerItem)||maxAttemptsPerItem<1||maxAttemptsPerItem>5||!Number.isSafeInteger(maxItems)||maxItems<1||maxItems>100||!Number.isSafeInteger(maxInlineDelayMs)||maxInlineDelayMs<0||maxInlineDelayMs>5000)throw Error('Invalid import run limits.');\r\n let running=false,active=null;\r\n const enabled=()=>manifest?.version===1&&manifest?.uploadsEnabled===true;\r\n async function bounded(fn,signal){\r\n  const controller=new AbortController();let timer,onAbort;\r\n  const stopped=new Promise((_,reject)=>{\r\n   onAbort=()=>{controller.abort();reject(abortError());};\r\n   if(signal.aborted){onAbort();return;}\r\n   signal.addEventListener('abort',onAbort,{once:true});\r\n   timer=setTimeout(()=>{controller.abort();reject(Object.assign(Error('Import request timed out.'),{code:'timeout'}));},requestTimeoutMs);\r\n  });\r\n  try{return await Promise.race([Promise.resolve().then(()=>{if(signal.aborted)throw abortError();return fn(controller.signal);}),stopped]);}\r\n  finally{clearTimeout(timer);signal.removeEventListener('abort',onAbort);}\r\n }\r\n const retryDelay=(reply,attempt)=>{\r\n  let seconds;try{const raw=reply?.retryAfter;if(typeof raw==='string'){if(/^\\d+(?:\\.\\d+)?$/.test(raw))seconds=Number(raw);else{const deadline=Date.parse(raw);if(Number.isFinite(deadline))seconds=Math.max(0,(deadline-now())/1000);}}}catch{}\r\n  if(Number.isFinite(seconds))return Math.min(86400000,Math.max(0,Math.ceil(seconds*1000)));\r\n  return Math.min(30000,Math.ceil(250*2**attempt*(1+Math.min(1,Math.max(0,random())))));\r\n };\r\n return Object.freeze({\r\n  stop(){active?.abort();},\r\n  async run({targetAccountId,resumeParkedClaimIds=[]}={}){\r\n   if(!enabled())return {stopped:'disabled',posted:0,imported:0};\r\n   if(running)return {stopped:'busy',posted:0,imported:0};\r\n   if(typeof targetAccountId!=='string'||!targetAccountId||!Array.isArray(resumeParkedClaimIds)||resumeParkedClaimIds.some(id=>typeof id!=='string'))throw Error('Choose an immutable target and explicit resume claims.');\r\n   running=true;const controller=new AbortController();active=controller;\r\n   const summary={posted:0,imported:0,parked:0,retryAt:null,stopped:'complete'};\r\n   let unsubscribe=()=>{},runTicket;\r\n   const current=ticket=>!controller.signal.aborted&&enabled()&&transition.isCurrent(runTicket)&&transition.isCurrent(ticket);\r\n   try{\r\n    try{runTicket=transition.capture();unsubscribe=transition.subscribe(()=>controller.abort());if(!transition.isCurrent(runTicket))throw abortError();}catch{summary.stopped='identity_unavailable';return summary;}\r\n    const ledger=await repository.listImportAssignments();\r\n    const candidates=ledger.items.filter(item=>item.kind==='import'&&item.targetAccountId===targetAccountId&&[1,2].includes(item.digestVersion)&&typeof item.idempotencyKey==='string');\r\n    const resume=new Set(resumeParkedClaimIds);let processedItems=0;\r\n    for(const selected of candidates){\r\n     if(!current(runTicket)){summary.stopped='identity_changed';break;}\r\n     let projection=await repository.importAttemptState(selected.claimId,now());\r\n     if(terminal.has(projection.status)||projection.status==='in_flight'||projection.retryAt>now()||projection.status==='parked'&&!resume.has(selected.claimId))continue;\r\n     if(processedItems++>=maxItems)break;\r\n     for(let count=0;count<maxAttemptsPerItem;count++){\r\n      if(!current(runTicket)){summary.stopped='identity_changed';return summary;}\r\n      projection=await repository.importAttemptState(selected.claimId,now());\r\n      if(terminal.has(projection.status)||projection.status==='in_flight'||projection.retryAt>now()||projection.status==='parked'&&(count>0||!resume.has(selected.claimId)))break;\r\n      let ticket;try{ticket=transition.capture();}catch{summary.stopped='identity_unavailable';return summary;}\r\n      let account,preflightCategory,preflightFailure;\r\n      try{account=await bounded(signal=>loadAccount({signal,cache:'no-store'}),controller.signal);}\r\n      catch(error){if(!current(ticket)){summary.stopped='identity_changed';return summary;}if(error?.status===401)preflightCategory='signed_out';else preflightFailure=error?.code==='timeout'?'timeout':'offline';}\r\n      if(!current(ticket)){summary.stopped='identity_changed';return summary;}\r\n      if(!preflightCategory&&!preflightFailure){\r\n       try{const value=safeRecord(account),user=safeRecord(value.user);if(user.id!==selected.targetAccountId)preflightCategory='target_mismatch';else if(!Number.isSafeInteger(value.dataEpoch)||value.dataEpoch<1)preflightFailure='unknown_response';else if(value.dataEpoch!==selected.targetDataEpoch)preflightCategory='epoch_mismatch';}\r\n       catch{preflightFailure='unknown_response';}\r\n      }\r\n      const startedAt=now(),attemptId=randomUUID();let attempt;\r\n      try{attempt=await repository.beginImportAttempt({claimId:selected.claimId,generation:selected.generation,attemptId,startedAt},{resumeParked:count===0&&resume.has(selected.claimId),attemptLimit:maxAttemptsPerItem});}\r\n      catch{summary.stopped='storage_or_contention';return summary;}\r\n      if(attempt.duplicate||attempt.status!=='in_flight')break;\r\n      const item=attempt.item;\r\n      const observe=details=>repository.recordImportAttemptResult({claimId:item.claimId,generation:item.generation,attemptId,at:Math.max(startedAt,now()),...details});\r\n      if(!current(ticket)){await observe({type:'parked',category:'target_mismatch'});summary.parked++;summary.stopped='identity_changed';return summary;}\r\n      if(preflightCategory){await observe({type:'parked',category:preflightCategory});summary.parked++;summary.stopped=preflightCategory;return summary;}\r\n      let reply,errorCategory=preflightFailure;\r\n      if(!preflightFailure){\r\n       // Nothing after this equality check can choose a different target/body.\r\n       const request=Object.freeze({path:'/api/workouts/import',method:'POST',cache:'no-store',headers:Object.freeze({'Content-Type':'application/json','X-Target-Account':item.targetAccountId,'Idempotency-Key':item.idempotencyKey}),body:JSON.stringify({digestVersion:item.digestVersion,targetDataEpoch:item.targetDataEpoch,snapshot:item.snapshot,fingerprint:item.fingerprint})});\r\n       try{summary.posted++;reply=safeRecord(await bounded(signal=>postImport({...request,signal}),controller.signal));}\r\n       catch(error){errorCategory=error?.code==='timeout'?'timeout':'offline';}\r\n      }\r\n      if(!current(ticket)){await observe({type:'parked',category:'target_mismatch'});summary.parked++;summary.stopped='identity_changed';return summary;}\r\n      const serverWorkoutId=success(reply??{},item);\r\n      if(serverWorkoutId){await observe({type:'imported',httpStatus:reply.status,serverWorkoutId});summary.imported++;break;}\r\n      let status=reply?.status,code;try{code=safeRecord(reply.body).code;}catch{}\r\n      if(!Number.isInteger(status)||status<100||status>599)status=undefined;\r\n      const withStatus=status===undefined?{}:{httpStatus:status};\r\n      const park=status===401?'signed_out':status===404?'feature_disabled':status===409&&['target_mismatch','target_account_mismatch'].includes(code)?'target_mismatch':status===409&&code==='target_epoch_mismatch'?'epoch_mismatch':null;\r\n      if(park){await observe({type:'parked',category:park,...withStatus});summary.parked++;summary.stopped=park;return summary;}\r\n      if(status===409&&code==='fingerprint_conflict'){await observe({type:'conflict',category:'fingerprint_conflict',...withStatus});break;}\r\n      const rejectionCodes=['invalid_workout_import','invalid_snapshot','invalid_key_input','invalid_idempotency_key','invalid_fingerprint','unsupported_digest_version'];\r\n      if([403,422].includes(status)&&code==='policy_rejected'){await observe({type:'rejected',category:'policy_rejected',...withStatus});break;}\r\n      if([400,422].includes(status)&&rejectionCodes.includes(code)){await observe({type:'rejected',category:'invalid_payload',...withStatus});break;}\r\n      if(attempt.attemptNumber>=attempt.attemptLimit){await observe({type:'parked',category:'retry_exhausted',...withStatus});summary.parked++;break;}\r\n      const delay=retryDelay(reply,attempt.attemptNumber-1),retryAt=Math.max(startedAt,now())+delay;\r\n      await observe({type:'retryable_failure',category:errorCategory??(status===429?'rate_limited':status>=500?'server_unavailable':'unknown_response'),retryAt,...withStatus});\r\n      summary.retryAt=summary.retryAt===null?retryAt:Math.min(summary.retryAt,retryAt);\r\n      if(delay>maxInlineDelayMs)break;\r\n      try{await wait(delay,controller.signal);}catch{summary.stopped='identity_changed';return summary;}\r\n     }\r\n    }\r\n    return summary;\r\n   }finally{unsubscribe();if(active===controller)active=null;running=false;}\r\n  },\r\n });\r\n}\r\n","local-coach/import-upload-manifest.mjs":"// No production caller enables uploads. Synthetic tests may inject an explicit\r\n// version-1 manifest; activation requires a separate reviewed integration.\r\nexport const IMPORT_UPLOAD_MANIFEST=Object.freeze({version:1,uploadsEnabled:false});\r\n","local-coach/manual-clock.mjs":"export class ManualActiveClock{\r\n constructor({now=()=>performance.now(),visible=()=>!document.hidden}={}){this.now=now;this.visible=visible;this.elapsed=0;this.last=null;this.running=false;}\r\n start(elapsed=0){this.elapsed=Math.max(0,Number(elapsed)||0);this.last=this.now();this.running=true;return this.elapsed;}\r\n sample(){const current=this.now();if(this.running&&this.visible()&&this.last!==null)this.elapsed+=Math.max(0,(current-this.last)/1000);this.last=current;return this.elapsed;}\r\n pause(){this.sample();this.running=false;return this.elapsed;}\r\n resume(){this.last=this.now();this.running=true;return this.elapsed;}\r\n}\r\n\r\nexport class ManualStartGate{\r\n constructor(){this.pending=Promise.resolve();this.pausePending=null;}\r\n run(task){this.pausePending=null;this.pending=Promise.resolve().then(task);return this.pending;}\r\n pause(task){this.pausePending??=this.pending.then(task);return this.pausePending;}\r\n}\r\n","local-coach/repository.mjs":"import Dexie from 'dexie';\r\nimport {z} from 'zod';\r\nimport {IMPORT_LEDGER_STORES,importLedgerTables,readImportLedger,deleteImportLedger,createImportLedger} from './import-ledger.mjs';\r\nimport {EXERCISES,validateOnboarding} from '../onboarding-domain.mjs';\r\n\r\n// Tuning knob: slow first launches (cold IndexedDB, throttled CPU, parallel tabs) need well over 3 s to open. Real failures (VersionError, blocked upgrade, quota) still reject immediately or at this deadline.\r\nexport const LOCAL_COACH_OPEN_TIMEOUT_MS=15000;\r\nexport const LOCAL_COACH_SCHEMA_VERSION=1;\r\nexport const LOCAL_COACH_LAYOUT_VERSION=2;\r\nexport const LOCAL_COACH_EXPORT_VERSION=1;\r\nexport const DEFAULT_LOCAL_COACH_DB='myr5-local-coach';\r\n\r\nconst TimestampSchema=z.number().int().nonnegative();\r\nconst OwnerIdSchema=z.string().min(1).max(512).regex(/^(guest|account):\\S+$/,'Owner must have a non-empty guest or account scope.');\r\nconst DeviceIdSchema=z.string().min(1).max(128);\r\nconst IdentifierSchema=z.string().min(1).max(128);\r\nconst LeaseTokenSchema=z.string().min(1).max(512);\r\nconst JsonValueSchema=z.lazy(()=>z.union([z.string(),z.number().finite(),z.boolean(),z.null(),z.array(JsonValueSchema),z.record(z.string(),JsonValueSchema)]));\r\nconst JsonObjectSchema=z.record(z.string(),JsonValueSchema).refine(value=>JSON.stringify(value).length<=131072,'JSON object exceeds the 128 KiB local-record limit.');\r\nconst IntakeSchema=z.unknown().transform((value,context)=>{\r\n try{return validateOnboarding(value);}catch(error){context.addIssue({code:'custom',message:error instanceof Error?error.message:'Invalid coach setup.'});return z.NEVER;}\r\n});\r\nconst SettingsSchema=JsonObjectSchema;\r\nconst StartDaySchema=z.string().regex(/^\\d{4}-\\d{2}-\\d{2}$/,'Start day must be a local calendar date.');\r\nconst WorkoutStatusSchema=z.enum(['active','paused','completed','interrupted']);\r\nconst ModeSchema=z.string().min(1).max(80);\r\nconst WorkoutStartSchema=z.object({\r\n clientWorkoutId:IdentifierSchema.optional(),\r\n mode:ModeSchema,\r\n goal:z.number().int().min(1).max(100000),\r\n restSeconds:z.number().int().min(15).max(180).default(60),\r\n progress:JsonObjectSchema.default({}),\r\n metadata:JsonObjectSchema.default({}),\r\n});\r\nconst WorkoutPatchSchema=z.object({\r\n progress:JsonObjectSchema.optional(),\r\n metadata:JsonObjectSchema.optional(),\r\n});\r\nconst CompletionSchema=z.object({\r\n value:z.number().finite().min(0).max(100000),\r\n activeSeconds:z.number().finite().min(0).max(7200).optional(),\r\n elapsedSeconds:z.number().finite().min(0).max(7200).optional(),\r\n earned:z.boolean().optional(),\r\n progress:JsonObjectSchema.optional(),\r\n metadata:JsonObjectSchema.optional(),\r\n});\r\n\r\nconst MetaRecordSchema=z.object({key:z.string(),ownerId:OwnerIdSchema.optional(),value:JsonValueSchema,updatedAt:TimestampSchema,schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION)});\r\nconst IntakeRecordSchema=z.object({ownerId:OwnerIdSchema,deviceId:DeviceIdSchema,value:IntakeSchema,updatedAt:TimestampSchema,schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION)});\r\nconst SettingsRecordSchema=z.object({ownerId:OwnerIdSchema,deviceId:DeviceIdSchema,value:SettingsSchema,updatedAt:TimestampSchema,schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION)});\r\nconst WorkoutRecordSchema=z.object({\r\n id:IdentifierSchema,\r\n clientWorkoutId:IdentifierSchema,\r\n ownerId:OwnerIdSchema,\r\n deviceId:DeviceIdSchema,\r\n mode:ModeSchema,\r\n goal:z.number().int().min(1).max(100000),\r\n restSeconds:z.number().int().min(15).max(180),\r\n status:WorkoutStatusSchema,\r\n progress:JsonObjectSchema,\r\n metadata:JsonObjectSchema,\r\n completion:CompletionSchema.optional(),\r\n startedAt:TimestampSchema,\r\n updatedAt:TimestampSchema,\r\n completedAt:TimestampSchema.optional(),\r\n interruptedAt:TimestampSchema.optional(),\r\n schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION),\r\n});\r\nconst EventRecordSchema=z.object({id:IdentifierSchema,workoutId:IdentifierSchema,ownerId:OwnerIdSchema,deviceId:DeviceIdSchema,sequence:z.number().int().positive(),type:z.enum(['started','updated','paused','resumed','completed','interrupted']),payload:JsonObjectSchema,createdAt:TimestampSchema,schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION)});\r\nconst OutboxRecordSchema=z.object({id:IdentifierSchema,workoutId:IdentifierSchema,clientWorkoutId:IdentifierSchema,ownerId:OwnerIdSchema,deviceId:DeviceIdSchema,type:z.literal('workout.completed'),state:z.enum(['pending','sent','rejected']),payload:JsonObjectSchema,createdAt:TimestampSchema,updatedAt:TimestampSchema,schemaVersion:z.literal(LOCAL_COACH_SCHEMA_VERSION)});\r\nconst LegacyPendingSetSchema=z.object({id:z.union([z.string(),z.number()]),value:z.number().finite().min(0).max(100000),active:z.number().finite().min(0).max(7200).optional()}).passthrough();\r\nconst LegacyMigrationSchema=z.object({sourceKey:z.string().min(1).max(512),intake:z.unknown().optional(),settings:SettingsSchema.optional(),pendingSets:z.array(LegacyPendingSetSchema).max(10000).optional()});\r\n\r\nconst parse=(schema,value,label)=>{\r\n const result=schema.safeParse(value);\r\n if(result.success)return result.data;\r\n throw new LocalCoachStorageError('invalid-record',`${label} failed validation.`,{cause:result.error,recoverable:true});\r\n};\r\n\r\nexport class LocalCoachStorageError extends Error{\r\n constructor(code,message,{cause,recoverable=false}={}){super(message,{cause});this.name='LocalCoachStorageError';this.code=code;this.recoverable=recoverable;}\r\n}\r\n\r\nexport function classifyLocalCoachError(error,operation='Local coach storage'){\r\n if(error instanceof LocalCoachStorageError)return error;\r\n const name=String(error?.name??'');\r\n if(name==='QuotaExceededError')return new LocalCoachStorageError('quota',`${operation} could not be saved because device storage is full.`,{cause:error,recoverable:true});\r\n if(name==='VersionError'||name==='UpgradeError')return new LocalCoachStorageError('migration',`${operation} could not open the local coach database.`,{cause:error,recoverable:true});\r\n if(name==='AbortError'||name==='TransactionInactiveError')return new LocalCoachStorageError('interrupted-write',`${operation} was interrupted and was not committed.`,{cause:error,recoverable:true});\r\n return new LocalCoachStorageError('storage',`${operation} failed.`,{cause:error,recoverable:true});\r\n}\r\n\r\nfunction createId(cryptoObject){\r\n if(typeof cryptoObject?.randomUUID==='function')return cryptoObject.randomUUID();\r\n throw new LocalCoachStorageError('missing-randomness','Secure local identifiers are unavailable.',{recoverable:false});\r\n}\r\n\r\nexport async function openLocalCoach({\r\n name=DEFAULT_LOCAL_COACH_DB,\r\n openTimeoutMs=LOCAL_COACH_OPEN_TIMEOUT_MS,\r\n indexedDB=globalThis.indexedDB,\r\n IDBKeyRange=globalThis.IDBKeyRange,\r\n cryptoObject=globalThis.crypto,\r\n now=()=>Date.now(),\r\n exerciseKeys=Object.keys(EXERCISES),\r\n}={}){\r\n if(!Number.isSafeInteger(openTimeoutMs)||openTimeoutMs<1||openTimeoutMs>60000)throw new LocalCoachStorageError('invalid-record','Local storage open timeout must be between 1 and 60000 milliseconds.',{recoverable:true});\r\n if(!indexedDB||!IDBKeyRange)throw new LocalCoachStorageError('unavailable','Durable local storage is unavailable in this browser.',{recoverable:true});\r\n const modes=new Set(exerciseKeys);\r\n const db=new Dexie(name,{indexedDB,IDBKeyRange});\r\n db.version(1).stores({\r\n  meta:'&key,ownerId,updatedAt',\r\n  intake:'&ownerId,deviceId,updatedAt',\r\n  settings:'&ownerId,deviceId,updatedAt',\r\n  workouts:'&id,&clientWorkoutId,ownerId,[ownerId+status],[ownerId+startedAt],status,updatedAt',\r\n  workoutEvents:'&id,workoutId,[ownerId+workoutId],[workoutId+sequence],ownerId,createdAt',\r\n  outbox:'&id,&workoutId,ownerId,[ownerId+state],state,updatedAt',\r\n });\r\n db.version(LOCAL_COACH_LAYOUT_VERSION).stores(IMPORT_LEDGER_STORES);\r\n let openExpired=false,openTimer;\r\n const openDeadlineError=new LocalCoachStorageError('migration','Local storage is taking longer than expected. Retry; close other app tabs if upgrade is blocked.',{recoverable:true});\r\n try{\r\n  await Promise.race([\r\n   db.open().then(()=>{if(openExpired){db.close({disableAutoOpen:true});throw openDeadlineError;}}),\r\n   new Promise((resolve,reject)=>{openTimer=setTimeout(()=>{openExpired=true;reject(openDeadlineError);db.close({disableAutoOpen:true});},openTimeoutMs);}),\r\n  ]);\r\n }catch(error){db.close({disableAutoOpen:true});throw classifyLocalCoachError(error,'Local coach database');}\r\n finally{clearTimeout(openTimer);}\r\n\r\n const readMeta=async key=>{\r\n  const row=await db.meta.get(key);\r\n  return row?parse(MetaRecordSchema,row,'Local metadata'):null;\r\n };\r\n const ensureIdentity=async()=>{\r\n  try{return await db.transaction('rw',db.meta,async()=>{\r\n   const existingDevice=await readMeta('device-id');\r\n   const existingGuest=await readMeta('guest-owner-id');\r\n   const timestamp=now();\r\n   const deviceId=existingDevice?.value??createId(cryptoObject);\r\n   const guestOwnerId=existingGuest?.value??`guest:${createId(cryptoObject)}`;\r\n   parse(DeviceIdSchema,deviceId,'Device identifier');parse(OwnerIdSchema,guestOwnerId,'Guest owner identifier');\r\n   if(!existingDevice)await db.meta.add(parse(MetaRecordSchema,{key:'device-id',value:deviceId,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Device metadata'));\r\n   if(!existingGuest)await db.meta.add(parse(MetaRecordSchema,{key:'guest-owner-id',ownerId:guestOwnerId,value:guestOwnerId,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Guest metadata'));\r\n   return {deviceId,guestOwnerId};\r\n  });}catch(error){throw classifyLocalCoachError(error,'Local coach identity');}\r\n };\r\n const identity=await ensureIdentity();\r\n\r\n const appendEvent=async(workout,type,payload={})=>{\r\n  const sequence=await db.workoutEvents.where('workoutId').equals(workout.id).count()+1;\r\n  const event=parse(EventRecordSchema,{id:createId(cryptoObject),workoutId:workout.id,ownerId:workout.ownerId,deviceId:workout.deviceId,sequence,type,payload,createdAt:now(),schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Workout event');\r\n  await db.workoutEvents.add(event);return event;\r\n };\r\n\r\n const forOwner=ownerValue=>{\r\n  const ownerId=parse(OwnerIdSchema,ownerValue,'Owner identifier');\r\n  const leaseKey=`workout-lease:${JSON.stringify([ownerId,identity.deviceId])}`;\r\n  const getWorkout=async id=>{\r\n   const row=await db.workouts.get(parse(IdentifierSchema,id,'Workout identifier'));\r\n   if(!row||row.ownerId!==ownerId)return null;\r\n   return parse(WorkoutRecordSchema,row,'Workout');\r\n  };\r\n  const transact=async(operation,tables,fn)=>{\r\n   try{return await db.transaction('rw',...tables,fn);}catch(error){throw classifyLocalCoachError(error,operation);}\r\n  };\r\n  const assertWorkoutLease=async token=>{if(token===undefined)return;const expected=parse(LeaseTokenSchema,token,'Workout lease token'),row=await db.meta.get(leaseKey),lease=row?parse(MetaRecordSchema,row,'Workout lease record').value:null;if(!lease||lease.token!==expected)throw new LocalCoachStorageError('lease','This workout is active in another tab.',{recoverable:true});};\r\n  return Object.freeze({\r\n   ...createImportLedger({db,ownerId,deviceId:identity.deviceId,getWorkout,transact,StorageError:LocalCoachStorageError,classifyError:classifyLocalCoachError}),\r\n   ownerId,\r\n   deviceId:identity.deviceId,\r\n   async claimWorkoutLease(token){const value={token:parse(LeaseTokenSchema,token,'Workout lease token')};return transact('Workout lease claim',[db.meta],async()=>{const row=parse(MetaRecordSchema,{key:leaseKey,ownerId,value,updatedAt:now(),schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Workout lease record');await db.meta.put(row);return value;});},\r\n   async saveIntake(value){\r\n    const intake=parse(IntakeSchema,value,'Coach intake'),timestamp=now();\r\n    const row=parse(IntakeRecordSchema,{ownerId,deviceId:identity.deviceId,value:intake,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach intake record');\r\n    try{await db.intake.put(row);return row.value;}catch(error){throw classifyLocalCoachError(error,'Coach intake');}\r\n   },\r\n   async getIntake(){try{const row=await db.intake.get(ownerId);return row?parse(IntakeRecordSchema,row,'Coach intake record').value:null;}catch(error){throw classifyLocalCoachError(error,'Coach intake');}},\r\n   async saveSettings(value){\r\n    const settings=parse(SettingsSchema,value,'Coach settings'),timestamp=now();\r\n    const row=parse(SettingsRecordSchema,{ownerId,deviceId:identity.deviceId,value:settings,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach settings record');\r\n    try{await db.settings.put(row);return row.value;}catch(error){throw classifyLocalCoachError(error,'Coach settings');}\r\n   },\r\n    async getSettings(){try{const row=await db.settings.get(ownerId);return row?parse(SettingsRecordSchema,row,'Coach settings record').value:null;}catch(error){throw classifyLocalCoachError(error,'Coach settings');}},\r\n    async saveSetup(value,{startDay}={}){\r\n     const intake=parse(IntakeSchema,value,'Coach intake'),requestedDay=parse(StartDaySchema,startDay,'Coach start day');\r\n     return transact('Coach setup',[db.intake,db.settings],async()=>{\r\n      const timestamp=now(),existing=await db.settings.get(ownerId),prior=existing?parse(SettingsRecordSchema,existing,'Coach settings record').value:{};\r\n      const settings=parse(SettingsSchema,{...prior,startDay:prior.startDay??requestedDay},'Coach settings');\r\n      const intakeRow=parse(IntakeRecordSchema,{ownerId,deviceId:identity.deviceId,value:intake,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach intake record');\r\n      const settingsRow=parse(SettingsRecordSchema,{ownerId,deviceId:identity.deviceId,value:settings,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach settings record');\r\n      await db.intake.put(intakeRow);await db.settings.put(settingsRow);return {intake:intakeRow.value,settings:settingsRow.value};\r\n     });\r\n    },\r\n   async startWorkout(input,{leaseToken}={}){\r\n    const parsed=parse(WorkoutStartSchema,input,'Workout start');\r\n    if(!modes.has(parsed.mode))throw new LocalCoachStorageError('invalid-record','Workout mode is not supported.',{recoverable:true});\r\n    // The client identifier is the durable local primary key by design. The\r\n    // server receives this same immutable value for idempotent reconciliation.\r\n    const timestamp=now(),id=parsed.clientWorkoutId??createId(cryptoObject);\r\n    const row=parse(WorkoutRecordSchema,{id,clientWorkoutId:id,ownerId,deviceId:identity.deviceId,mode:parsed.mode,goal:parsed.goal,restSeconds:parsed.restSeconds,status:'active',progress:parsed.progress,metadata:parsed.metadata,startedAt:timestamp,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Workout');\r\n    return transact('Workout start',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);await db.workouts.add(row);await appendEvent(row,'started',{mode:row.mode,goal:row.goal,restSeconds:row.restSeconds});return row;});\r\n   },\r\n   async updateWorkout(id,patch,{leaseToken}={}){\r\n    const parsed=parse(WorkoutPatchSchema,patch,'Workout update');\r\n    return transact('Workout update',[db.meta,db.workouts,db.workoutEvents],async()=>{\r\n     await assertWorkoutLease(leaseToken);\r\n     const current=await getWorkout(id);if(!current)throw new LocalCoachStorageError('not-found','Workout was not found for this owner.',{recoverable:true});\r\n     if(current.status==='completed')throw new LocalCoachStorageError('already-completed','Completed workouts cannot be changed.',{recoverable:true});\r\n     const updated=parse(WorkoutRecordSchema,{...current,...parsed,updatedAt:now()},'Workout');\r\n     await db.workouts.put(updated);await appendEvent(updated,'updated',parsed);return updated;\r\n    });\r\n   },\r\n   async pauseWorkout(id,{leaseToken}={}){return transact('Workout pause',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);const current=await getWorkout(id);if(!current)throw new LocalCoachStorageError('not-found','Workout was not found for this owner.',{recoverable:true});if(current.status!=='active')return current;const updated=parse(WorkoutRecordSchema,{...current,status:'paused',updatedAt:now()},'Workout');await db.workouts.put(updated);await appendEvent(updated,'paused');return updated;});},\r\n   async resumeWorkout(id,{leaseToken}={}){return transact('Workout resume',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);const current=await getWorkout(id);if(!current)throw new LocalCoachStorageError('not-found','Workout was not found for this owner.',{recoverable:true});if(!['paused','interrupted'].includes(current.status))return current;const {interruptedAt:_interruptedAt,...resumable}=current;const updated=parse(WorkoutRecordSchema,{...resumable,status:'active',updatedAt:now()},'Workout');await db.workouts.put(updated);await appendEvent(updated,'resumed');return updated;});},\r\n   async completeWorkout(id,completion,{queueForSync=true,leaseToken}={}){\r\n    const parsed=parse(CompletionSchema,completion,'Workout completion');\r\n    return transact('Workout completion',[db.meta,db.workouts,db.workoutEvents,db.outbox],async()=>{\r\n     await assertWorkoutLease(leaseToken);\r\n     const current=await getWorkout(id);if(!current)throw new LocalCoachStorageError('not-found','Workout was not found for this owner.',{recoverable:true});\r\n     if(current.status==='completed'){const existing=await db.outbox.where('workoutId').equals(current.id).first();return {workout:current,outbox:existing?parse(OutboxRecordSchema,existing,'Sync outbox record'):null,duplicate:true};}\r\n     const timestamp=now();\r\n     const updated=parse(WorkoutRecordSchema,{...current,status:'completed',completion:parsed,progress:parsed.progress??current.progress,metadata:parsed.metadata??current.metadata,completedAt:timestamp,updatedAt:timestamp},'Workout');\r\n     await db.workouts.put(updated);await appendEvent(updated,'completed',{value:parsed.value,activeSeconds:parsed.activeSeconds??null,elapsedSeconds:parsed.elapsedSeconds??null,earned:parsed.earned??null});\r\n     let outbox=null;\r\n     if(queueForSync){outbox=parse(OutboxRecordSchema,{id:createId(cryptoObject),workoutId:updated.id,clientWorkoutId:updated.clientWorkoutId,ownerId,deviceId:identity.deviceId,type:'workout.completed',state:'pending',payload:{workout:updated},createdAt:timestamp,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Sync outbox record');await db.outbox.add(outbox);}\r\n     return {workout:updated,outbox,duplicate:false};\r\n    });\r\n   },\r\n    async recoverInterruptedWorkouts({leaseToken}={}){return transact('Workout recovery',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);const rows=await db.workouts.where('[ownerId+status]').anyOf([[ownerId,'active'],[ownerId,'paused']]).toArray();const recovered=[];for(const raw of rows){const current=parse(WorkoutRecordSchema,raw,'Workout'),timestamp=now(),updated=parse(WorkoutRecordSchema,{...current,status:'interrupted',interruptedAt:timestamp,updatedAt:timestamp},'Workout');await db.workouts.put(updated);await appendEvent(updated,'interrupted',{previousStatus:current.status});recovered.push(updated);}return recovered;});},\r\n    async interruptActiveWorkouts({leaseToken}={}){return transact('Active workout recovery',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);const rows=await db.workouts.where('[ownerId+status]').equals([ownerId,'active']).toArray(),recovered=[];for(const raw of rows){const current=parse(WorkoutRecordSchema,raw,'Workout'),timestamp=now(),updated=parse(WorkoutRecordSchema,{...current,status:'interrupted',interruptedAt:timestamp,updatedAt:timestamp},'Workout');await db.workouts.put(updated);await appendEvent(updated,'interrupted',{previousStatus:current.status});recovered.push(updated);}return recovered;});},\r\n    async interruptWorkout(id,{leaseToken}={}){return transact('Workout interruption',[db.meta,db.workouts,db.workoutEvents],async()=>{await assertWorkoutLease(leaseToken);const current=await getWorkout(id);if(!current)throw new LocalCoachStorageError('not-found','Workout was not found for this owner.',{recoverable:true});if(current.status!=='active')return current;const timestamp=now(),updated=parse(WorkoutRecordSchema,{...current,status:'interrupted',interruptedAt:timestamp,updatedAt:timestamp},'Workout');await db.workouts.put(updated);await appendEvent(updated,'interrupted',{previousStatus:current.status});return updated;});},\r\n   async getWorkout(id){try{return await getWorkout(id);}catch(error){throw classifyLocalCoachError(error,'Workout read');}},\r\n   async listWorkouts(){try{return (await db.workouts.where('ownerId').equals(ownerId).sortBy('startedAt')).map(row=>parse(WorkoutRecordSchema,row,'Workout'));}catch(error){throw classifyLocalCoachError(error,'Workout history');}},\r\n   async listEvents(workoutId){try{return (await db.workoutEvents.where('[ownerId+workoutId]').equals([ownerId,workoutId]).sortBy('sequence')).map(row=>parse(EventRecordSchema,row,'Workout event'));}catch(error){throw classifyLocalCoachError(error,'Workout events');}},\r\n   async listOutbox({state}={}){try{const rows=state?await db.outbox.where('[ownerId+state]').equals([ownerId,state]).toArray():await db.outbox.where('ownerId').equals(ownerId).toArray();return rows.map(row=>parse(OutboxRecordSchema,row,'Sync outbox record')).sort((a,b)=>a.createdAt-b.createdAt||a.id.localeCompare(b.id));}catch(error){throw classifyLocalCoachError(error,'Sync outbox');}},\r\n   async markOutbox(id,state){\r\n    const next=parse(z.enum(['sent','rejected']),state,'Outbox state');\r\n    return transact('Sync outbox update',[db.outbox],async()=>{const row=await db.outbox.get(id);if(!row||row.ownerId!==ownerId)throw new LocalCoachStorageError('not-found','Sync record was not found for this owner.',{recoverable:true});const updated=parse(OutboxRecordSchema,{...row,state:next,updatedAt:now()},'Sync outbox record');await db.outbox.put(updated);return updated;});\r\n   },\r\n   async exportLocalData(){\r\n    try{return await db.transaction('r',db.intake,db.settings,db.workouts,db.workoutEvents,db.outbox,...importLedgerTables(db),async()=>{\r\n     const intake=await db.intake.get(ownerId),settings=await db.settings.get(ownerId),workouts=await db.workouts.where('ownerId').equals(ownerId).toArray(),events=await db.workoutEvents.where('ownerId').equals(ownerId).toArray(),outbox=await db.outbox.where('ownerId').equals(ownerId).toArray();\r\n     return {importAssignments:await readImportLedger(db,ownerId,LocalCoachStorageError),exportVersion:LOCAL_COACH_EXPORT_VERSION,schemaVersion:LOCAL_COACH_SCHEMA_VERSION,ownerId,deviceId:identity.deviceId,exportedAt:now(),intake:intake?parse(IntakeRecordSchema,intake,'Coach intake record'):null,settings:settings?parse(SettingsRecordSchema,settings,'Coach settings record'):null,workouts:workouts.map(row=>parse(WorkoutRecordSchema,row,'Workout')).sort((a,b)=>a.startedAt-b.startedAt||a.id.localeCompare(b.id)),events:events.map(row=>parse(EventRecordSchema,row,'Workout event')).sort((a,b)=>a.createdAt-b.createdAt||a.id.localeCompare(b.id)),outbox:outbox.map(row=>parse(OutboxRecordSchema,row,'Sync outbox record')).sort((a,b)=>a.createdAt-b.createdAt||a.id.localeCompare(b.id))};\r\n    });}catch(error){throw classifyLocalCoachError(error,'Local coach export');}\r\n   },\r\n   async deleteLocalData(){return transact('Local coach deletion',[db.meta,db.intake,db.settings,db.workouts,db.workoutEvents,db.outbox,...importLedgerTables(db)],async()=>{const metadataKeys=(await db.meta.where('ownerId').equals(ownerId).primaryKeys()).filter(key=>key!=='guest-owner-id');const counts={importAssignments:await deleteImportLedger(db,ownerId),intake:await db.intake.where('ownerId').equals(ownerId).delete(),settings:await db.settings.where('ownerId').equals(ownerId).delete(),workouts:await db.workouts.where('ownerId').equals(ownerId).delete(),events:await db.workoutEvents.where('ownerId').equals(ownerId).delete(),outbox:await db.outbox.where('ownerId').equals(ownerId).delete(),metadata:metadataKeys.length};if(metadataKeys.length)await db.meta.bulkDelete(metadataKeys);return counts;});},\r\n   async importLegacyLocalState(input){\r\n    const legacy=parse(LegacyMigrationSchema,input,'Legacy local state'),markerKey=`legacy:${JSON.stringify([ownerId,legacy.sourceKey])}`;\r\n    return transact('Legacy local migration',[db.meta,db.intake,db.settings,db.outbox],async()=>{\r\n     if(await db.meta.get(markerKey))return {imported:false,reason:'already-imported'};\r\n     const timestamp=now();\r\n     if(legacy.intake!==undefined){const value=parse(IntakeSchema,legacy.intake,'Legacy coach intake');await db.intake.put(parse(IntakeRecordSchema,{ownerId,deviceId:identity.deviceId,value,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach intake record'));}\r\n     if(legacy.settings!==undefined)await db.settings.put(parse(SettingsRecordSchema,{ownerId,deviceId:identity.deviceId,value:legacy.settings,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Coach settings record'));\r\n     let pending=0;\r\n     for(const item of legacy.pendingSets??[]){const workoutId=createId(cryptoObject),id=createId(cryptoObject);const row=parse(OutboxRecordSchema,{id,workoutId,clientWorkoutId:workoutId,ownerId,deviceId:identity.deviceId,type:'workout.completed',state:'pending',payload:{legacy:true,legacyId:String(item.id),value:item.value,activeSeconds:item.active??null},createdAt:timestamp,updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Legacy sync outbox record');await db.outbox.put(row);pending++;}\r\n     await db.meta.put(parse(MetaRecordSchema,{key:markerKey,ownerId,value:{sourceKey:legacy.sourceKey,importedAt:timestamp,pending},updatedAt:timestamp,schemaVersion:LOCAL_COACH_SCHEMA_VERSION},'Migration metadata'));\r\n     return {imported:true,pending};\r\n    });\r\n   },\r\n  });\r\n };\r\n\r\n return Object.freeze({\r\n  schemaVersion:LOCAL_COACH_SCHEMA_VERSION,\r\n  layoutVersion:LOCAL_COACH_LAYOUT_VERSION,\r\n  deviceId:identity.deviceId,\r\n  guestOwnerId:identity.guestOwnerId,\r\n  forOwner,\r\n  close(){db.close({disableAutoOpen:true});},\r\n });\r\n}\r\n","locked-public.css":"/* Public intake state: quiet, paper-like, and deliberately free of optional game surfaces. */\r\nhtml[data-public-state=\"locked\"]{color-scheme:light;background:#e8dfcf}\r\nhtml[data-public-state=\"locked\"] body{--wall:#e8dfcf;--purple:#315c72;--gold:#b8653c;--cream:#24313a;--muted:#5d6b6d;max-width:760px;background:#e8dfcf;color:#24313a;box-shadow:none;font-family:system-ui,-apple-system,\"Segoe UI\",sans-serif}\r\nhtml[data-public-state=\"locked\"] .device-bezel{display:none}\r\nhtml[data-public-state=\"locked\"] .ship-header{height:auto;min-height:70px;padding:calc(12px + env(safe-area-inset-top)) 20px 12px;background:#f7f1e5;border-bottom:2px solid #c6b9a4;box-shadow:0 2px 0 #fff9;gap:12px}\r\nhtml[data-public-state=\"locked\"] .mom-brand{color:#24313a;font-size:16px;letter-spacing:-.3px}\r\nhtml[data-public-state=\"locked\"] .mom-brand img{width:30px;height:30px}\r\nhtml[data-public-state=\"locked\"] .mom-brand>span>span{font-size:9px;letter-spacing:3px;margin-top:3px}\r\nhtml[data-public-state=\"locked\"] .ship-location{color:#5d6b6d;font-size:10px;letter-spacing:.08em}\r\nhtml[data-public-state=\"locked\"] .ship-header .deck-readout{color:#5d6b6d;font-size:10px;letter-spacing:.08em}\r\nhtml[data-public-state=\"locked\"] .ship-header .status-light{background:#6b9b72;box-shadow:none}\r\nhtml[data-public-state=\"locked\"] .ship-header .icon-button{color:#24313a;background:#e4eee8;border:1px solid #9bb9a7;border-radius:6px}\r\nhtml[data-public-state=\"locked\"] .pod-page{padding:14px 18px max(104px,env(safe-area-inset-bottom))}\r\nhtml[data-public-state=\"locked\"] .containment-bay{margin:0}\r\nhtml[data-public-state=\"locked\"] .containment-pod{height:clamp(240px,38dvh,390px);border:2px solid #a9b9ae;border-radius:10px;background:#dcebe2;box-shadow:0 3px 0 #b3a995;overflow:hidden}\r\nhtml[data-public-state=\"locked\"] .containment-pod:before,html[data-public-state=\"locked\"] .containment-pod:after,html[data-public-state=\"locked\"] .pod-rim,html[data-public-state=\"locked\"] .pod-floor,html[data-public-state=\"locked\"] .pod-inscription,html[data-public-state=\"locked\"] .frame-bolt,html[data-public-state=\"locked\"] .pod-top-vent{display:none}\r\nhtml[data-public-state=\"locked\"] #homeCharacter,html[data-public-state=\"locked\"] .coach-mount canvas,html[data-public-state=\"locked\"] .coach-mount video{display:none!important}\r\nhtml[data-public-state=\"locked\"] .coach-mount{inset:18px 16px 42px;background:#f7f1e5;border:1px solid #b7a994;border-radius:6px;box-shadow:inset 0 0 0 5px #f0e7d7}\r\nhtml[data-public-state=\"locked\"] .coach-mount>*{visibility:hidden}\r\nhtml[data-public-state=\"locked\"] .coach-mount:after{content:\"MOM INC. COACH\\A Ready for your next comfortable set.\";white-space:pre;visibility:visible;position:absolute;inset:0;display:grid;place-content:center;text-align:center;color:#315c72;font-weight:700;line-height:1.55;letter-spacing:.02em}\r\nhtml[data-public-state=\"locked\"] .pod-nameplate{left:16px;right:16px;height:34px;padding:0 10px;background:#c7ddcf;border:1px solid #94ab9b;border-radius:5px 5px 0 0;color:#315c72;font-size:9px}\r\nhtml[data-public-state=\"locked\"] .pod-nameplate a{display:none}\r\nhtml[data-public-state=\"locked\"] .workout-console{padding:14px;background:#f7f1e5;border:2px solid #b7a994;border-radius:10px;box-shadow:0 3px 0 #b3a995;color:#24313a}\r\n/* Locked intake stays in normal document flow.  The legacy sticky action\r\n   treatment is useful for the full coach, but it obscures the public focus\r\n   controls on short mobile viewports. */\r\nhtml[data-public-state=\"locked\"] .workout-console .calibration-grid{grid-template-columns:minmax(0,1fr) minmax(72px,88px);gap:10px;align-items:center}\r\nhtml[data-public-state=\"locked\"] .workout-console .dial-controls{flex-wrap:nowrap;gap:6px;margin:10px 0 7px}\r\nhtml[data-public-state=\"locked\"] .workout-console .dial-controls button{width:40px;min-width:40px;min-height:44px;padding:6px;background:#e4eee8;color:#24313a;border:1px solid #91aa9d;box-shadow:none}\r\nhtml[data-public-state=\"locked\"] .workout-console .exercise-dial{width:68px;height:68px;background:repeating-conic-gradient(from 0deg,#9ab7aa 0deg 3deg,#dcebe2 3deg 10deg);box-shadow:0 0 0 3px #f7f1e5,0 0 0 5px #91aa9d}\r\nhtml[data-public-state=\"locked\"] .workout-console .exercise-dial:before{background:radial-gradient(circle at 30% 25%,#f7f1e5,#dcebe2 60%,#b7cfc2 90%);box-shadow:inset 1px 2px #fff9,inset -2px -3px #91aa9d}\r\nhtml[data-public-state=\"locked\"] .workout-console .exercise-dial i:after{background:#d77c52;border-color:#7d422f;box-shadow:none}\r\nhtml[data-public-state=\"locked\"] .workout-console .signal-control .rocker-switch{min-width:58px;width:58px;min-height:58px;padding:8px;background:#e4eee8;color:#24313a;border:1px solid #91aa9d;box-shadow:none;transform:none}\r\nhtml[data-public-state=\"locked\"] .workout-console label,html[data-public-state=\"locked\"] .workout-console small,html[data-public-state=\"locked\"] #status,html[data-public-state=\"locked\"] .simple-counter small{color:#5d6b6d}\r\nhtml[data-public-state=\"locked\"] .workout-console button,html[data-public-state=\"locked\"] .workout-console select{color:#24313a;background:#e4eee8;border:1px solid #91aa9d;border-radius:6px;box-shadow:none}\r\nhtml[data-public-state=\"locked\"] .workout-console .manual-button,html[data-public-state=\"locked\"] .workout-console .movement-scope{color:#24313a;background:#fffaf2;border-color:#b7a994}\r\nhtml[data-public-state=\"locked\"] .workout-console .primary-action{background:#d77c52;color:#fffaf2;border-color:#a85335;box-shadow:0 2px 0 #91472e}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-actions{position:static;display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px;min-width:0;margin:12px 0 0;padding:0;background:none}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-actions .set-summary{display:block;grid-column:1/-1;grid-row:1;margin:0;text-align:center;color:#315c72;font:600 12px/1.4 ui-monospace,monospace}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-actions #start,html[data-public-state=\"locked\"] .workout-console .set-actions #stop{grid-row:2;min-height:52px}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-actions #start{grid-column:1}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-actions #stop{grid-column:2;min-width:72px;padding:8px 12px;color:#24313a;background:#e4eee8;border:1px solid #91aa9d;border-radius:6px;font-size:12px}\r\nhtml[data-public-state=\"locked\"] .workout-console .goal-control{border-top:1px solid #c6b9a4}\r\nhtml[data-public-state=\"locked\"] .workout-console .goal-control #variationName{color:#315c72}\r\nhtml[data-public-state=\"locked\"] .workout-console .movement-scope summary,html[data-public-state=\"locked\"] .workout-console #variationHint,html[data-public-state=\"locked\"] .workout-console #trackingScope{color:#24313a}\r\nhtml[data-public-state=\"locked\"] .workout-console .set-track{background:#d8d0c2}\r\nhtml[data-public-state=\"locked\"] .coach-line #coachCaption{color:#315c72}\r\nhtml[data-public-state=\"locked\"] #primary,html[data-public-state=\"locked\"] #goalValue{color:#315c72}\r\nhtml[data-public-state=\"locked\"] .set-track{background:#d8d0c2}html[data-public-state=\"locked\"] #activity{background:#d77c52;transition:none}\r\nhtml[data-public-state=\"locked\"] .coach-line{min-height:48px;color:#24313a}html[data-public-state=\"locked\"] .coach-line p{color:#315c72}\r\nhtml[data-public-state=\"locked\"] .coach-mission{margin:0 0 12px;padding:12px;background:#f7f1e5;border:2px solid #b7a994;box-shadow:0 3px 0 #b3a995;color:#24313a;border-radius:8px}\r\nhtml[data-public-state=\"locked\"] .coach-mission .mission-strip{color:#315c72;background:#e4eee8;border:1px solid #91aa9d;box-shadow:none;border-radius:6px}\r\nhtml[data-public-state=\"locked\"] .coach-mission .mission-tag,html[data-public-state=\"locked\"] .coach-mission .mission-readouts,html[data-public-state=\"locked\"] .coach-mission .mission-streak,html[data-public-state=\"locked\"] .coach-mission .mission-head p{color:#4e5e61}\r\nhtml[data-public-state=\"locked\"] .meditation-entry{display:none}\r\nhtml[data-public-state=\"locked\"] .crew-footer{display:none}\r\nhtml[data-public-state=\"locked\"] #coachDock.coach-dock{background:#f7f1e5;border-top:2px solid #c6b9a4;backdrop-filter:none}\r\nhtml[data-public-state=\"locked\"] #coachDock.coach-dock button:not(.dock-portal){color:#24313a;background:#e4eee8;border:1px solid #91aa9d;border-radius:6px}\r\nhtml[data-public-state=\"locked\"] .launch-panel{color:#24313a;background:#f7f1e5;border:2px solid #b7a994;border-radius:10px;box-shadow:0 5px 0 #b3a995}\r\nhtml[data-public-state=\"locked\"] .launch-panel h2,html[data-public-state=\"locked\"] .launch-panel h3{color:#315c72}\r\nhtml[data-public-state=\"locked\"] .launch-panel button,html[data-public-state=\"locked\"] .launch-panel input,html[data-public-state=\"locked\"] .launch-panel select{color:#24313a;background:#e4eee8;border-color:#91aa9d;border-radius:6px}\r\nhtml[data-public-state=\"locked\"] .launch-panel .main-action{color:#fffaf2;background:#d77c52;border-color:#a85335}\r\nhtml[data-public-state=\"locked\"] .goals-board{margin:16px 0;padding:14px;background:#f7f1e5;border:2px solid #b7a994;border-radius:8px;box-shadow:0 3px 0 #b3a995}\r\nhtml[data-public-state=\"locked\"] .goals-board h3{margin:0 0 5px;color:#315c72}\r\nhtml[data-public-state=\"locked\"] .goals-board form{display:grid;gap:9px}\r\nhtml[data-public-state=\"locked\"] .goals-board label{display:grid;gap:4px}\r\nhtml[data-public-state=\"locked\"] .goals-board textarea{resize:vertical;font:inherit;padding:9px}\r\nhtml[data-public-state=\"locked\"] .goal-entry{margin-top:10px;padding:10px;background:#fffaf2;border:1px solid #b7a994;border-left:5px solid #d77c52}\r\nhtml[data-public-state=\"locked\"] .goal-entry h4,html[data-public-state=\"locked\"] .goal-entry p{margin:0 0 5px}\r\nhtml[data-public-state=\"locked\"] .goal-entry[data-status=\"completed\"]{border-left-color:#6b9b72;opacity:.85}\r\nhtml[data-public-state=\"locked\"] .goal-entry[data-status=\"archived\"]{opacity:.6}\r\n/* The account marker rail overlays the dialog footer. Keep enough scroll room\r\n   for Goals controls to rise above it on compact desktop and phone screens. */\r\nhtml[data-public-state=\"locked\"] #accountContent{padding-bottom:104px}\r\nhtml[data-public-state=\"locked\"] .coach-mission .mission-arm{background:#e4eee8;color:#315c72;border-color:#91aa9d;box-shadow:none}\r\nhtml[data-public-state=\"locked\"] .workout-console .slider-scale{display:flex;justify-content:space-between;gap:14px;white-space:nowrap}\r\nhtml[data-public-state=\"locked\"] .workout-console .slider-scale span{display:block}\r\nhtml[data-public-state=\"locked\"] .workout-console .panel-heading{background:#f7f1e5;color:#315c72}\r\nhtml[data-public-state=\"locked\"] .launch-panel p,html[data-public-state=\"locked\"] .launch-panel label,html[data-public-state=\"locked\"] .launch-panel .hint{color:#4e5e61}\r\nhtml[data-public-state=\"locked\"] *{animation:none!important;transition:none!important}\r\n@media(max-width:520px){html[data-public-state=\"locked\"] .ship-location{display:none}html[data-public-state=\"locked\"] .ship-header .deck-readout{margin-left:auto}html[data-public-state=\"locked\"] .pod-page{padding-inline:12px}html[data-public-state=\"locked\"] .workout-console{padding:12px}html[data-public-state=\"locked\"] .workout-console .calibration-grid{grid-template-columns:minmax(0,1fr) 72px;gap:8px}html[data-public-state=\"locked\"] .workout-console .dial-controls{gap:4px}html[data-public-state=\"locked\"] .workout-console .dial-controls button{width:34px;min-width:34px;padding-inline:4px}html[data-public-state=\"locked\"] .workout-console .exercise-dial{width:60px;height:60px}}\r\n","manifest.webmanifest":"{\"id\":\"/pose.html\",\"name\":\"MYR5 Coach\",\"short_name\":\"MYR5\",\"description\":\"Your MYR5 training pod, meals and progress.\",\"start_url\":\"/pose\",\"scope\":\"/\",\"display\":\"standalone\",\"orientation\":\"portrait-primary\",\"background_color\":\"#21172f\",\"theme_color\":\"#21172f\",\"icons\":[{\"src\":\"/icons/myr5-alien-192.png\",\"sizes\":\"192x192\",\"type\":\"image/png\",\"purpose\":\"any\"},{\"src\":\"/icons/myr5-alien-512.png\",\"sizes\":\"512x512\",\"type\":\"image/png\",\"purpose\":\"any\"},{\"src\":\"/icons/myr5-alien-maskable.png\",\"sizes\":\"512x512\",\"type\":\"image/png\",\"purpose\":\"maskable\"}]}\r\n","meal-nutrition.mjs":"import {NUTRIENTS,findFoods,portionNutrition,displayNutrient} from './nutrition.mjs';\r\nimport FDC from './food/nutrition-fdc.json' with {type:'json'};\r\n// #R9-FOOD: the Food-101 scanner labels (and typed text that exactly matches one) skip the SR28 fuzzy\r\n// search below and use this USDA FoodData Central table instead -- one real \"as eaten\" match per label\r\n// rather than a guessed word-match. Reshaped into portionNutrition()'s per-100g \"food\" shape so the same\r\n// grams scaler/renderer this file already has handles it; only the two vitamins FDC gave us are filled in.\r\nconst VITAMIN_KEY={'Vitamin A':'vitaminA','Vitamin C':'vitaminC','Vitamin D':'vitaminD','Vitamin E':'vitaminE','Vitamin B12':'vitaminB12',Folate:'folate'};\r\nfunction fdcFood(entry){\r\n const per100=v=>v==null?null:v*100/entry.servingG;\r\n const food={id:`fdc:${entry.fdcId}`,name:entry.description,calories:per100(entry.kcal),protein:per100(entry.proteinG),carbs:per100(entry.carbsG),fat:per100(entry.fatG)};\r\n for(const v of entry.vitamins)food[VITAMIN_KEY[v.name]]=per100(v.amount);\r\n return food;\r\n}\r\nexport function mountMealNutrition(){\r\n const $=id=>document.getElementById(id),form=$('mealForm');let foods=null,reference=null,generation=0,mode='estimate',queryTimer;\r\n const data=()=>{const nutrients=Object.fromEntries(NUTRIENTS.map(([k])=>[k,form.elements[k].value===''?null:Number(form.elements[k].value)]));const source=reference?.id?.startsWith('fdc:')?`USDA FDC ${reference.id.slice(4)}`:`USDA SR28 ${reference?.id}`;return {...nutrients,micros:Object.fromEntries(NUTRIENTS.slice(4).map(([k])=>[k,nutrients[k]])),nutritionSource:mode==='estimate'&&reference?source:'User entered'};};\r\n const snapshot=()=>({name:$('mealConfirmation').hidden?null:$('mealName').value,nutrients:data()});\r\n function render(){const values=data();for(const [k,,unit]of NUTRIENTS)$('nutrient-'+k).textContent=displayNutrient(values[k],unit);window.dispatchEvent(new CustomEvent('myr5:meal-nutrition',{detail:snapshot()}));}\r\n function calculate(){mode='estimate';const grams=Number($('mealGrams').value),values=portionNutrition(reference,grams);for(const [k]of NUTRIENTS)form.elements[k].value=values[k]??'';form.elements.portion.value=`${grams} g`;$('nutritionBasis').textContent=reference?(reference.id?.startsWith('fdc:')?`USDA FDC · ${grams} g`:`Estimate · ${grams} g`):'No match. Enter the food or label values.';render();}\r\n async function search(query){\r\n  const run=++generation,exact=FDC[query.trim().toLowerCase()];\r\n  reference=null;$('foodReference').replaceChildren();\r\n  if(exact){reference=fdcFood(exact);$('mealGrams').value=exact.servingG;$('foodReferenceLabel').hidden=true;calculate();return;}\r\n  calculate();\r\n  try{foods??=(await import('./nutrition-data.mjs')).default;if(run!==generation)return;const matches=findFoods(foods,query);for(const f of matches){const o=document.createElement('option');o.value=f.id;o.textContent=f.name;$('foodReference').append(o);}reference=matches[0]||null;$('foodReferenceLabel').hidden=!matches.length;calculate();}catch{if(run===generation)$('nutritionBasis').textContent='Food reference could not load. Reconnect or enter nutrition from its label.';}\r\n }\r\n function open(name=''){clearTimeout(queryTimer);$('mealConfirmation').hidden=false;$('mealSaveControls').hidden=false;$('mealName').value=name;$('mealGrams').value=100;$('nutritionAdjust').open=false;search(name);}\r\n function reset(){generation++;clearTimeout(queryTimer);reference=null;form.reset();const now=new Date();form.elements.eatenAt.value=new Date(now.getTime()-now.getTimezoneOffset()*60000).toISOString().slice(0,16);$('mealConfirmation').hidden=true;$('mealSaveControls').hidden=true;for(const [k]of NUTRIENTS)form.elements[k].value='';render();}\r\n $('foodReference').onchange=()=>{reference=foods?.find(f=>f.id===$('foodReference').value)||null;calculate();};\r\n $('mealGrams').oninput=calculate;\r\n $('mealName').oninput=()=>{clearTimeout(queryTimer);generation++;reference=null;calculate();queryTimer=setTimeout(()=>search($('mealName').value),250);};\r\n for(const [k]of NUTRIENTS)form.elements[k].oninput=()=>{mode='manual';$('nutritionBasis').textContent='Your label values';render();};\r\n window.addEventListener('myr5:food-selected',e=>open(e.detail?.name||''));\r\n window.addEventListener('myr5:food-reset',reset);\r\n window.addEventListener('pagehide',()=>{generation++;clearTimeout(queryTimer);});\r\n return {data,reset,snapshot};\r\n}\r\n","meal-scanner.mjs":"import {markFoodPhotoToday} from './food/pyramid-tiles.mjs';\r\nexport function mountMealScanner(){\r\n const $=id=>document.getElementById(id),stage=$('mealScanStage'),overlay=$('mealScanOverlay'),preview=$('foodPreview'),trigger=$('recognizeFood');\r\n let worker=null,photoUrl=null,selected=null,generation=0,timer=null,started=0;\r\n const status=text=>$('foodStatus').textContent=text;\r\n function stopClock(){clearInterval(timer);timer=null;trigger.disabled=false;$('cancelFoodScan').hidden=true;stage.removeAttribute('aria-busy');}\r\n function cancel(message){generation++;worker?.terminate();worker=null;stopClock();overlay.dataset.state='ready';$('scanProgress').hidden=true;if(message){$('scanPhase').textContent='SCAN PAUSED';status(message);}}\r\n function phase(state,title,detail){overlay.hidden=false;overlay.dataset.state=state;$('scanPhase').textContent=title;$('scanDetail').textContent=detail;}\r\n const notify=(type,detail)=>window.dispatchEvent(new CustomEvent(type,{detail}));\r\n function error(text){stopClock();phase('error','SCAN INTERRUPTED',text);stage.hidden=true;$('scanProgress').hidden=true;trigger.hidden=false;status(text);worker?.terminate();worker=null;notify('myr5:food-selected',{name:''});}\r\n $('foodCamera').onclick=()=>$('foodPhoto').click();\r\n $('foodPhoto').onchange=()=>{\r\n  if(!$('foodPhoto').files[0])return;\r\n  cancel();notify('myr5:food-reset');trigger.hidden=true;if(photoUrl)URL.revokeObjectURL(photoUrl);photoUrl=null;selected=null;preview.removeAttribute('src');stage.hidden=true;$('foodSuggestions').replaceChildren();$('foodSuggestions').hidden=true;\r\n  const file=$('foodPhoto').files[0];if(!file){status('Choose a photo to begin.');return;}\r\n  if(file.size>15*1024*1024){status('Choose a photo smaller than 15 MB.');return;}\r\n  if(!['image/jpeg','image/png','image/webp'].includes(file.type)){status('Choose a JPEG, PNG or WebP photo.');return;}\r\n  selected=file;photoUrl=URL.createObjectURL(file);preview.src=photoUrl;preview.hidden=false;stage.hidden=false;$('scanElapsed').textContent='00:00';\r\n  phase('ready','FOOD SCANNER','Reading your photo');return trigger.onclick();\r\n };\r\n $('cancelFoodScan').onclick=()=>{cancel('Scan stopped. Retry or confirm the food below.');trigger.hidden=false;notify('myr5:food-selected',{name:''});};\r\n $('mealsPanel').addEventListener('close',()=>{if(timer){cancel('Scan paused. Tap Retry scan to continue.');trigger.hidden=false;}});\r\n trigger.onclick=async()=>{\r\n  if(!selected){status('Choose a meal photo first.');return;}\r\n  const run=++generation;clearInterval(timer);trigger.hidden=true;trigger.disabled=true;stage.setAttribute('aria-busy','true');$('cancelFoodScan').hidden=false;$('foodSuggestions').replaceChildren();started=performance.now();\r\n  const tick=()=>{const s=Math.floor((performance.now()-started)/1000);$('scanElapsed').textContent=`${String(Math.floor(s/60)).padStart(2,'0')}:${String(s%60).padStart(2,'0')}`;};tick();timer=setInterval(tick,1000);\r\n  phase('preparing','PREPARING PHOTO','Reading image on this device');status('Preparing your photo…');\r\n  try{\r\n   const bitmap=await createImageBitmap(selected);if(run!==generation){bitmap.close();return;}\r\n   const canvas=document.createElement('canvas'),ratio=Math.min(1,768/Math.max(bitmap.width,bitmap.height));canvas.width=Math.max(1,Math.round(bitmap.width*ratio));canvas.height=Math.max(1,Math.round(bitmap.height*ratio));canvas.getContext('2d').drawImage(bitmap,0,0,canvas.width,canvas.height);bitmap.close();\r\n   markFoodPhotoToday();notify('myr5:food-photo-ready'); // accepted, decoded photo: step out of the portal before recognition\r\n   worker??=new Worker('/food-worker.mjs',{type:'module'});\r\n   worker.onerror=()=>{if(run===generation)error('Recognition is unavailable in this browser. Type the meal name below.');};\r\n   worker.onmessage=({data})=>{\r\n    if(run!==generation)return;\r\n    if(data.type==='progress'){\r\n     phase(data.stage||'analyzing',data.stage==='loading'?'LOADING FOOD MODEL':'ANALYZING FOOD',data.text);status(data.text);\r\n     const p=$('scanProgress');p.hidden=!(data.stage==='loading'&&Number.isFinite(data.progress));if(!p.hidden)p.value=data.progress;\r\n    }else if(data.type==='error')error(data.text);\r\n    else if(data.type==='result'){\r\n     stopClock();$('scanProgress').hidden=true;\r\n     const best=data.items[0],unsure=!!(best&&data.uncertain);if(best)void import('./modules/vault/vault-store.mjs').then(m=>m.bump('food-scan')).catch(()=>{});\r\n     phase('result',data.uncertain?'CHECK THE MATCHES':'SCAN COMPLETE',best?`${best.label} · ${(best.score*100).toFixed(1)}% match score`:'No clear food match');\r\n     stage.hidden=true;\r\n     // #3/#37: a real guess with a question mark keeps the pyramid full size — the sheet, retry and candidates\r\n     // below stay closed until the pyramid's Fix or Type it opens them. No guess at all (empty items) shows them\r\n     // at once, same as before.\r\n     trigger.hidden=unsure||!data.uncertain;status(unsure?'':data.uncertain?'Check the match & portion':'Check food & portion');\r\n     notify('myr5:food-selected',{name:best?.label||'',uncertain:unsure,score:best?.score});\r\n     $('foodSuggestions').hidden=unsure||!data.uncertain;\r\n     $('foodSuggestions').replaceChildren(...data.items.map(item=>{const b=document.createElement('button');b.type='button';b.textContent=`${item.label} · ${(item.score*100).toFixed(1)}%`;b.setAttribute('aria-label',`${item.label}, ${(item.score*100).toFixed(1)} percent model match score`);b.onclick=()=>{notify('myr5:food-selected',{name:item.label,uncertain:false,score:item.score});};return b;}));\r\n    }\r\n   };\r\n   worker.postMessage({image:canvas.toDataURL('image/jpeg',.85)});\r\n  }catch{if(run===generation)error('Could not read that photo. Try a JPEG or PNG, or enter the meal below.');}\r\n };\r\n window.addEventListener('pagehide',()=>{cancel();if(photoUrl)URL.revokeObjectURL(photoUrl);photoUrl=null;});\r\n}\r\n","meditation-backgrounds.mjs":"// D28: meditation backgrounds are the \"wonders\" pack entries in plan/asset-manifest.json\r\n// (pack \"wonders\", files backgrounds/clean/<id>.webp). The full 48 ship through the signed pack host,\r\n// never core. Six starters ship on the site (pod/worlds/starter/) in the optional Starter download (W2-2O),\r\n// fetched on demand when missing: todaysBackground() asks a caller-supplied lookup for today's pack copy and\r\n// falls back to today's starter. This module fetches nothing itself.\r\n// ponytail: no default pack-store lookup yet (no live pack host); wire one when packs ship.\r\nexport const WONDERS_PACK = 'wonders';\r\n// Stems of every pack:\"wonders\" entry in plan/asset-manifest.json (48, checked 2026-09-22).\r\nexport const WONDER_BACKGROUNDS = Object.freeze(`angkor-wat-a angkor-wat-b big-ben-a big-ben-b bora-bora chichen-itza-a chichen-itza-b\r\nchrist-the-redeemer-a christ-the-redeemer-b colosseum-a colosseum-b colossus-of-rhodes dead-sea eiffel-tower-a eiffel-tower-b\r\ngalapagos-islands grand-canyon great-pyramid-of-giza-a great-pyramid-of-giza-b great-wall-of-china-a great-wall-of-china-b\r\nhanging-gardens-of-babylon kyoto lighthouse-of-alexandria machu-picchu-a machu-picchu-b maldives mausoleum-at-halicarnassus\r\nmount-fuji-a mount-fuji-b new-york-a new-york-b niagara-falls-a niagara-falls-b northern-lights petra santorini-a santorini-b\r\nstatue-of-zeus-at-olympia sydney-opera-house-a sydney-opera-house-b taj-mahal-a taj-mahal-b temple-of-artemis-at-ephesus tokyo\r\ntropical-island venice-a venice-b`.split(/\\s+/));\r\nexport const wonderAssetPath = id => `backgrounds/clean/${id}.webp`;\r\nexport const STARTER_WONDERS = Object.freeze(['great-wall-of-china-a', 'great-pyramid-of-giza-a', 'machu-picchu-a', 'taj-mahal-a', 'colosseum-a', 'mount-fuji-a']);\r\nexport const starterWonderUrl = id => `/pod/worlds/starter/${id}.webp`;\r\n\r\nexport function backgroundForDay(ids = WONDER_BACKGROUNDS, day = Math.floor(Date.now() / 86400000)) {\r\n return ids?.length ? ids[((Math.floor(day) % ids.length) + ids.length) % ids.length] : null;\r\n}\r\n\r\n// lookup: optional async ({pack, path, id}) => local URL string | null.\r\nexport async function resolveBackground(id, lookup) {\r\n if (!id || !lookup) return null;\r\n try {\r\n  const url = await lookup({pack: WONDERS_PACK, path: wonderAssetPath(id), id});\r\n  return typeof url === 'string' && url ? url : null;\r\n } catch {\r\n  return null;\r\n }\r\n}\r\n\r\n// Today's wonder: the downloaded pack copy (any of the 48) when the lookup has it, else today's starter.\r\nexport async function todaysBackground(lookup, day = Math.floor(Date.now() / 86400000)) {\r\n const id = backgroundForDay(WONDER_BACKGROUNDS, day), url = await resolveBackground(id, lookup);\r\n if (url) return {id, url};\r\n const starter = backgroundForDay(STARTER_WONDERS, day);\r\n return {id: starter, url: starterWonderUrl(starter)};\r\n}\r\n\r\n// Mean colour of the image's bottom pixel row, so the page below the landmark continues it.\r\nexport function averageRgb(data) {\r\n const sum = [0, 0, 0];\r\n for (let i = 0; i < data.length; i += 4) for (let c = 0; c < 3; c++) sum[c] += data[i + c];\r\n const n = Math.max(1, data.length / 4);\r\n return `rgb(${sum.map(v => Math.round(v / n)).join(',')})`;\r\n}\r\n","meditation.css":".meditation-entry{display:grid;grid-template-columns:40px 1fr;text-align:left;gap:3px 12px;width:100%;min-height:78px;padding:16px;margin:14px 0;border:2px outset #b7cdc4;border-radius:12px;background:linear-gradient(120deg,#4e7772,#2e444d);color:#f2ebd3;cursor:pointer}.meditation-entry>span{grid-row:span 2;font-size:35px;align-self:center}.meditation-entry strong{font:20px Georgia,serif}.meditation-entry small{font-size:12px}.meditation-panel{overflow:auto;background:linear-gradient(#173338,#101b29)!important;color:#def4e8!important;max-width:560px}.meditation-panel header{color:#e1eed7}.meditation-eyebrow{font:10px monospace;letter-spacing:.12em;color:#92b9ad;text-align:center}.meditation-stage{height:min(40dvh,300px);position:relative;display:grid;place-items:center;isolation:isolate}.meditation-character{border:0!important;background:none!important;box-shadow:none!important;position:relative;z-index:2;width:150px;height:210px;cursor:pointer}.meditation-character canvas{height:100%;max-width:100%;image-rendering:pixelated}.breathing-ring{position:absolute;width:220px;height:220px;border:1px solid #9edece;border-radius:50%;box-shadow:0 0 50px #7ff7cc20,inset 0 0 25px #8cefd411;animation:meditation-breathe 8s ease-in-out infinite}.meditation-speech{text-align:center;min-height:50px;font:20px/1.4 Georgia,serif}.meditation-hint{text-align:center;font-size:12px;color:#8eafa8}.breathing-paused .breathing-ring{animation-play-state:paused}.meditation-stage[data-annoyed=\"2\"] .meditation-character{rotate:-3deg}.meditation-stage[data-annoyed=\"3\"] .meditation-character{rotate:4deg;filter:sepia(.2)}.meditation-stage[data-annoyed=\"4\"] .meditation-character{rotate:-5deg;filter:sepia(.5) saturate(1.7)}.meditation-can{position:absolute;z-index:3;width:42px;height:58px;top:67%;left:64%;background:linear-gradient(90deg,#a2aaad,#f3f4e6,#a7b3b3);border-radius:4px 4px 10px 10px;border-top:7px solid #c5ff4b;display:grid;place-content:center;opacity:0;color:#47235f;font:12px monospace}.meditation-can i{position:absolute;left:3px;right:3px;top:-5px;height:4px;background:#dfffbc}.meditation-powder{position:absolute;z-index:4;color:#d9ffc1;font:30px monospace;top:30%;left:55%;opacity:0}.snorting .meditation-can{animation:meditation-can 1.8s ease-in-out forwards}.snorting .meditation-character{animation:meditation-snort 1.8s ease-in-out forwards}.snorting .meditation-powder{animation:meditation-powder 1.8s ease-in-out forwards}.meditation-blackout{position:fixed;inset:0;pointer-events:none;z-index:100;display:none;background:transparent}.blacking-out .meditation-blackout{display:block;animation:meditation-blackout 1.2s linear forwards}.meditation-blackout i{position:absolute;left:0;right:0;top:calc(var(--strip)*12.5%);height:13%;background:#000;transform:translateX(-100%);animation:meditation-shutter .8s calc(var(--strip)*.045s) forwards}.meditation-blackout i:nth-child(even){transform:translateX(100%)}\r\n@keyframes meditation-breathe{0%,100%{transform:scale(.75);opacity:.45}50%{transform:scale(1.08);opacity:1}}@keyframes meditation-can{0%{opacity:0;transform:translateY(60px)}25%{opacity:1;transform:translateY(0)}65%,100%{opacity:1;transform:translate(-44px,-90px) rotate(-65deg)}}@keyframes meditation-snort{0%,45%{transform:none}70%{transform:translate(12px,-4px) rotate(13deg)}100%{transform:translate(0,5px) rotate(-7deg)}}@keyframes meditation-powder{0%,45%,100%{opacity:0}65%{opacity:1;transform:translate(0,5px)}85%{opacity:.2;transform:translate(-30px,-15px) scale(.3)}}@keyframes meditation-shutter{to{transform:translateX(0)}}@keyframes meditation-blackout{0%{background:#ecfff060}35%{background:transparent}80%,100%{background:black}}@media(prefers-reduced-motion:reduce){.breathing-ring,.snorting .meditation-character,.snorting .meditation-can,.snorting .meditation-powder{animation:none}.snorting .meditation-can{opacity:1}.blacking-out .meditation-blackout{animation:none;background:black}.meditation-blackout i{animation:none;transform:none}}\r\n.breathing-session{display:grid;gap:8px;padding:12px}.breathing-session button{min-height:44px;font-size:1rem}.breathing-session progress{width:100%;accent-color:#9cffcb}.breathing-session p{margin:0;font-size:.875rem;color:#cdf1df}\r\n.breath-modes,.breath-run{display:grid;gap:10px}.breath-mode-card{display:grid!important;gap:4px;justify-content:start!important;justify-items:start;text-align:left;padding:12px!important;border:1px solid #4e7772!important;border-radius:10px;background:#132b2ee6!important;color:#def4e8!important}.breath-mode-card strong{font-size:1rem}.breath-mode-card small{color:#a9d2c6;font-size:.8rem}.breath-seated-notice{color:#ffd699!important;font-weight:650}.breath-phase{min-height:1.3em;font-weight:650;font-size:1rem!important;color:#eafff2!important}.breath-actions{display:flex;gap:8px}.breath-actions button{flex:1}.breath-exit{background:#5a2530!important;border-color:#d27a86!important;font-weight:650}.breath-stance-link{justify-self:start;background:none!important;font-size:.875rem!important}.breath-note{color:#9cbdb4!important;font-size:.75rem!important}\r\n.meditation-panel:has([data-breath-run][data-phase=\"hold\"]) .breathing-ring{animation-play-state:paused}\r\n/* D28 default layout: a full-height room. The day's wonder (~0.86:1 tile) sits uncropped across\r\n   the top and fades into a colour sampled from its own bottom edge, where the breathing UI lives.\r\n   No downloaded art: the original neutral gradient is the placeholder. The header stays pinned so\r\n   Close is always reachable (Esc also closes). */\r\n.meditation-panel{width:min(560px,100%);max-width:none;height:100dvh;max-height:none;margin:0 auto;padding:0 0 24px;border:0;border-radius:0}\r\n.meditation-panel header{position:sticky;top:0;z-index:5;height:0;margin:0;padding:0 12px;align-items:flex-start}.meditation-panel header>*{margin-top:12px!important}.meditation-panel header h2{text-shadow:0 1px 3px #000}.meditation-panel header button{background:#101b29d9}\r\n.meditation-panel [data-meditation-scene]>:not(.meditation-stage){margin-inline:16px}.meditation-panel .breathing-session{padding-inline:0}.meditation-panel:not(.has-wonder-art) .meditation-stage{margin-top:64px}\r\n.meditation-panel.has-wonder-art{background:var(--wonder-grey,var(--wonder-base,#101b29))!important;transition:background-color 2.5s ease}.meditation-panel.has-wonder-art.meditation-colour{background:var(--wonder-base,#101b29)!important}\r\n.meditation-panel.has-wonder-art .meditation-stage{height:clamp(300px,52dvh,520px);background:none}.meditation-panel.has-wonder-art .meditation-near{place-items:end center;padding-bottom:8px}\r\n.meditation-panel.has-wonder-art .meditation-far{background:linear-gradient(transparent 72%,var(--wonder-base,#101b29)),var(--wonder-url) center bottom/cover no-repeat;image-rendering:pixelated}\r\n.meditation-panel.has-wonder-art .meditation-character{height:170px}.meditation-panel.has-wonder-art .breathing-ring{width:180px;height:180px}.meditation-panel.has-wonder-art .meditation-speech{text-shadow:0 1px 3px #000}\r\n/* #149 (D46): the black-and-white room. Three peering layers slide by depth while dragged (meditation.mjs sets --peer-x/y):\r\n   far = the day's wonder, mid = the big sleeping coach, near = your seated character, the ring and the caption.\r\n   A full session fades the colour back in; stopping early lets the coach leap out through the water. */\r\n.meditation-stage{overflow:hidden;touch-action:pan-y}.meditation-layer{position:absolute;inset:0;--depth:1;translate:calc(var(--peer-x,0px)*var(--depth)) calc(var(--peer-y,0px)*var(--depth));transition:translate .5s ease-out}\r\n.meditation-far{--depth:.3;scale:1.05}.meditation-mid{--depth:.6;z-index:1}.meditation-near{z-index:2;display:grid;place-items:center}\r\n.meditation-panel:not(.has-wonder-art) .meditation-far{background:inherit;image-rendering:pixelated}\r\n.meditation-coach{position:absolute;left:-12%;right:-12%;bottom:14%;height:72%;transform-origin:50% 100%;transition:scale .3s ease-in,translate 3s linear}.coach-wander .meditation-coach{translate:135% 0}\r\n.meditation-coach .myr5-companion-card{position:absolute!important;inset:0!important;width:auto!important;height:auto!important;border:0!important;background:none!important;backdrop-filter:none!important;box-shadow:none!important;overflow:visible!important;pointer-events:none}.meditation-coach .myr5-companion-card>:not(.myr5-companion-stage){display:none!important}.meditation-coach .myr5-companion-stage{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;background:none!important}.meditation-coach canvas{width:100%!important;height:100%!important}\r\n.meditation-character canvas{transform-origin:50% 100%;animation:meditation-sit 8s ease-in-out infinite}.breathing-paused .meditation-character canvas{animation-play-state:paused}\r\n.meditation-panel .meditation-near .meditation-speech{position:absolute;left:12px;right:12px;bottom:1%;z-index:4;min-height:0;margin:0;text-shadow:0 1px 3px #000}\r\n@keyframes meditation-sit{50%{scale:1.03}}@keyframes meditation-smack{0%,100%{transform:none}20%{transform:translate(-10px,5px) rotate(-1.2deg)}40%{transform:translate(9px,-6px) rotate(1deg)}60%{transform:translate(-6px,3px)}80%{transform:translate(4px,-2px)}}@keyframes meditation-flash{from{opacity:.85}to{opacity:0}}\r\n@media(prefers-reduced-motion:reduce){.meditation-layer{translate:none}.meditation-character canvas{animation:none}}\r\n/* W2-2O: offered when today's starter wonder isn't on this phone (the Starter pack). */\r\n.meditation-starter{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;margin:0 16px 14px;font-size:14px;text-align:center}\r\n.meditation-starter[hidden]{display:none}\r\n.meditation-starter button{min-height:44px}\r\n/* The still room occupies the entire viewport. Wonder art returns only after a completed session. */\r\n.meditation-panel,.meditation-panel.has-wonder-art{position:fixed;inset:0;box-sizing:border-box;width:100vw;max-width:none;height:100dvh;max-height:none;margin:0;padding:0;overflow:hidden;background:#000!important;color:#fff!important}\r\n.meditation-panel::backdrop{background:#000}\r\n.meditation-panel.meditation-colour.has-wonder-art{background:var(--wonder-base,#000)!important}\r\n.meditation-panel header{position:absolute;top:0;left:0;right:0;height:auto;z-index:8;padding:max(10px,env(safe-area-inset-top)) 14px 0;box-sizing:border-box}\r\n.meditation-panel header>*{margin-top:0!important}\r\n.meditation-panel header h2{font:700 15px/1.2 ui-monospace,monospace;letter-spacing:.08em;text-transform:uppercase;color:#fff}\r\n.meditation-panel header button{border:2px solid #fff;border-radius:0;background:#000;color:#fff}\r\n.meditation-panel [data-meditation-scene]{position:relative;width:100%;height:100%;min-height:0;background:#000}\r\n.meditation-panel .meditation-stage,.meditation-panel.has-wonder-art .meditation-stage,.meditation-panel:not(.has-wonder-art) .meditation-stage{width:100%;height:100%;margin:0;background:#000}\r\n.meditation-panel .meditation-far,.meditation-panel.has-wonder-art .meditation-far{background:#000!important}\r\n.meditation-panel.meditation-colour.has-wonder-art .meditation-far{background:linear-gradient(transparent 72%,var(--wonder-base,#000)),var(--wonder-url) center bottom/cover no-repeat!important}\r\n.meditation-panel .meditation-near,.meditation-panel.has-wonder-art .meditation-near{place-items:center;padding:0}\r\n.meditation-panel .meditation-character,.meditation-panel.has-wonder-art .meditation-character{width:clamp(115px,34vw,170px);height:210px}\r\n.meditation-panel .breathing-ring,.meditation-panel.has-wonder-art .breathing-ring{width:180px;height:180px;border-color:#fff;box-shadow:0 0 0 2px #000,0 0 0 3px #fff}\r\n.meditation-panel .meditation-coach{bottom:26%;height:52%}\r\n.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{bottom:22%;padding:0 12px;color:#fff;font:700 17px/1.35 ui-monospace,monospace;text-shadow:2px 2px #000}\r\n.meditation-panel .breathing-session{position:absolute;z-index:6;left:0;right:0;bottom:max(10px,env(safe-area-inset-bottom));box-sizing:border-box;width:min(560px,100%);margin:auto;padding:0 16px;color:#fff}\r\n.meditation-panel .breathing-session p,.meditation-panel .breath-note,.meditation-panel .breath-phase,.meditation-panel .breath-seated-notice{color:#fff!important}\r\n.meditation-panel .breath-run{padding:10px;border:2px solid #fff;background:#000e}\r\n.meditation-panel .breath-actions button,.meditation-panel .breath-stance-link,.meditation-panel [data-breath-pause]{border:2px solid #fff;border-radius:0;background:#000;color:#fff}\r\n.meditation-panel .breathing-session progress{accent-color:#fff}\r\n.meditation-panel [data-breath-pause]{position:absolute;z-index:7;right:16px;bottom:160px}\r\n.meditation-panel .meditation-starter{position:absolute;z-index:6;left:12px;right:12px;bottom:110px;margin:0;padding:6px;border:1px solid #fff;background:#000;color:#fff;font:12px ui-monospace,monospace}\r\n.meditation-panel .meditation-starter button{border:1px solid #fff;border-radius:0;background:#000;color:#fff}\r\n/* Two square pixel thought bubbles flank the character. They remain real focusable buttons. */\r\n.meditation-panel .breath-modes{position:absolute;z-index:5;inset:0;display:block;pointer-events:none}\r\n.meditation-panel .breath-modes[hidden]{display:none}\r\n.meditation-panel .breath-mode-card{position:absolute;top:37%;width:clamp(110px,30vw,166px);min-height:130px;box-sizing:border-box;padding:9px!important;border:3px solid #fff!important;border-radius:0!important;background:#000!important;color:#fff!important;box-shadow:5px 5px 0 #777!important;image-rendering:pixelated;pointer-events:auto;font:11px/1.25 ui-monospace,monospace!important;overflow-wrap:anywhere}\r\n.meditation-panel .breath-mode-card:first-child{left:2%}\r\n.meditation-panel .breath-mode-card:last-child{right:2%}\r\n.meditation-panel .breath-mode-card::after{content:'';position:absolute;top:67%;width:10px;height:10px;background:#000;border:3px solid #fff;box-shadow:5px 5px 0 #777}\r\n.meditation-panel .breath-mode-card:first-child::after{left:calc(100% + 6px)}\r\n.meditation-panel .breath-mode-card:last-child::after{right:calc(100% + 6px)}\r\n.meditation-panel .breath-mode-card strong{font:700 13px/1.2 ui-monospace,monospace}\r\n.meditation-panel .breath-mode-card small{color:#fff;font:10px/1.25 ui-monospace,monospace}\r\n.meditation-panel .breath-mode-card:focus-visible{outline:3px solid #fff;outline-offset:5px}\r\n.meditation-panel.meditation-colour .breath-mode-card{border-color:#fff!important}\r\n@media(max-height:650px){.meditation-panel .breath-mode-card{top:28%;min-height:110px}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{bottom:28%}}\r\n\r\n/* Keep the active track time readable near the top third of the still room. */\r\n.meditation-panel .breath-run:not([hidden]) [data-status]{position:fixed;top:33dvh;left:12px;right:12px;z-index:7;margin:0;text-align:center;pointer-events:none}\r\n\r\n/* Pixel room: landmarks, a low platform, the sleeping four-legged coach and the selected 2D pose. */\r\n.meditation-panel .meditation-far{background:#000!important}\r\n.meditation-panel .room-art{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated}\r\n.meditation-panel .meditation-mid{z-index:1}\r\n.meditation-panel .meditation-platform{position:absolute;left:8%;right:8%;bottom:10%;height:22%;z-index:0}\r\n.meditation-panel .meditation-platform svg{width:100%;height:100%;overflow:visible;image-rendering:pixelated}\r\n.meditation-panel .meditation-coach{z-index:1;left:3%;right:3%;bottom:23%;height:48%;opacity:.6;filter:grayscale(1)}\r\n.meditation-panel .coach-pixel{position:absolute;z-index:1;left:-10%;right:-10%;bottom:18%;width:120%;height:58%;opacity:.82;filter:grayscale(1);image-rendering:pixelated}\r\n.meditation-panel .meditation-coach .myr5-companion-card{opacity:.14;mix-blend-mode:screen}\r\n.meditation-panel .meditation-near{z-index:2}\r\n.meditation-panel .breathing-orbit{position:absolute;left:50%;top:43%;width:min(68vw,380px);aspect-ratio:1;transform:translate(-50%,-50%);display:grid;place-items:center;z-index:1;pointer-events:none}\r\n.meditation-panel .breathing-ring{position:absolute;inset:0;width:auto;height:auto;box-sizing:border-box;border:4px solid #fff;border-radius:50%;box-shadow:0 0 0 5px #000,0 0 0 8px #fff;animation:none;transform:scale(calc(.72 + var(--breath-progress,.5)*.38));transition:transform .22s linear,opacity .22s linear;opacity:.92}\r\n.meditation-panel .breath-count{position:relative;z-index:2;font:900 clamp(72px,20vw,148px)/.9 ui-monospace,monospace;letter-spacing:-.08em;color:#fff;text-shadow:5px 5px #000,-2px -2px #000;transform:translateY(-8%)}\r\n.meditation-panel [data-session-clock]{position:absolute;z-index:3;bottom:17%;padding:5px 13px;border:3px solid #fff;background:#000;color:#fff;font:700 clamp(18px,5vw,28px)/1 ui-monospace,monospace;letter-spacing:.05em;box-shadow:4px 4px #777}\r\n.meditation-panel .meditation-character{position:absolute;z-index:3;left:50%;bottom:8%;transform:translateX(-50%);width:clamp(145px,42vw,220px);height:clamp(200px,34vh,270px);padding:0!important;image-rendering:pixelated}\r\n.meditation-panel .meditation-character canvas{display:none}\r\n.meditation-panel .meditation-character .pose{display:none;position:absolute;inset:0}\r\n.meditation-panel .meditation-character .pose svg{width:100%;height:100%;image-rendering:pixelated;filter:drop-shadow(5px 5px 0 #000)}\r\n.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{bottom:21%;z-index:5;max-width:700px;margin:0 auto;padding:7px 16px;border:2px solid #fff;background:#000;color:#fff;font:700 clamp(14px,4vw,21px)/1.35 ui-monospace,monospace;text-align:center;text-shadow:none;box-shadow:4px 4px #777}\r\n.meditation-panel .breathing-session{bottom:max(12px,env(safe-area-inset-bottom));padding-inline:12px}\r\n.meditation-panel .breath-run:not([hidden]) [data-status]{top:calc(50% - min(34vw,190px) - 42px);font:700 16px ui-monospace,monospace;text-shadow:2px 2px #000}\r\n.meditation-panel .breath-mode-card[data-mode=\"gentle-guided\"]{left:50%;right:auto;top:55%;width:min(72vw,290px);min-height:126px;transform:translateX(-50%)}\r\n.meditation-panel .breath-mode-card[data-mode=\"gentle-guided\"]::after{display:none}\r\n.meditation-panel.breathing-paused .breathing-ring{transition:none}\r\n@media(max-height:650px){.meditation-panel .breathing-orbit{top:40%;width:min(54vh,280px)}.meditation-panel .meditation-character{bottom:5%;height:clamp(150px,29vh,200px)}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{bottom:19%}.meditation-panel .breath-mode-card{top:29%}.meditation-panel .breath-mode-card[data-mode=\"gentle-guided\"]{top:52%}}\r\n@media(prefers-reduced-motion:reduce){.meditation-panel .breathing-ring{transform:scale(.9);transition:none}}\r\n\r\n/* Final room composition: scenery at the back, the coach above a platform, and all choices below. */\r\n.meditation-panel .room-art{z-index:0;filter:grayscale(1);opacity:.9}\r\n.meditation-panel .room-pixels{position:absolute;inset:0;width:100%;height:100%;image-rendering:pixelated;filter:grayscale(1) contrast(1.65);opacity:.34;mix-blend-mode:screen}.meditation-panel:not(.meditation-colour) .room-pixels{display:none}\r\n.meditation-panel .coach-pixel{left:-7%;bottom:18%;width:114%;height:59%;opacity:.9;z-index:1;filter:grayscale(1) contrast(1.1)}\r\n.meditation-panel .meditation-coach{z-index:2;left:-17%;right:-17%;bottom:8%;height:82%;opacity:.34}\r\n.meditation-panel .meditation-coach .myr5-companion-card{opacity:1;mix-blend-mode:normal}\r\n.meditation-panel .breathing-orbit{top:37%;width:min(76vw,410px);z-index:3}\r\n.meditation-panel .breathing-ring{position:absolute;inset:0;width:auto!important;height:auto!important;display:block;transform:scale(calc(.72 + var(--breath-progress,.5)*.38));transform-origin:center;}\r\n.meditation-panel .breath-count{position:absolute;left:0;right:0;top:calc(50% - 82px);display:grid;place-items:center;transform:none;font-size:clamp(72px,20vw,142px);line-height:.8;z-index:3}\r\n.meditation-panel [data-session-clock]{left:50%;right:auto;top:50%;bottom:auto;transform:translate(-50%,-50%);font-size:clamp(18px,5vw,26px);z-index:4;white-space:nowrap}\r\n.meditation-panel .breath-direction{position:absolute;left:calc(50% + 58px);top:50%;transform:translateY(-50%);z-index:4;color:#fff;font:900 11px/1 ui-monospace,monospace;font-style:normal;letter-spacing:.08em;white-space:nowrap;text-shadow:2px 2px #000}\r\n.meditation-panel .meditation-character{left:50%;bottom:36%;height:clamp(174px,25vh,215px);width:clamp(138px,36vw,195px);z-index:4;transform:translateX(-50%)}\r\n.meditation-panel .meditation-character[data-expression=\"focused\"]{filter:brightness(.8)}\r\n.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:64%;bottom:auto;z-index:5;max-width:min(700px,90vw);font-size:clamp(12px,3.7vw,19px)}\r\n.meditation-panel .breathing-session{position:absolute;left:0;right:0;bottom:max(8px,env(safe-area-inset-bottom));z-index:7;width:100%;max-width:760px;padding:0 12px;margin:auto;display:grid;gap:5px;box-sizing:border-box;pointer-events:none}\r\n.meditation-panel .breath-run:not([hidden]){display:grid;grid-template-columns:1fr;gap:5px;padding:7px 9px;border:2px solid #fff;background:#000e;pointer-events:auto}\r\n.meditation-panel .breath-run:not([hidden]) .breath-phase{min-height:1em;max-height:1.3em;overflow:hidden;font:700 12px/1.25 ui-monospace,monospace!important;text-align:center}\r\n.meditation-panel .breathing-session progress{height:8px}\r\n.meditation-panel .breath-actions{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}\r\n.meditation-panel .breath-actions button{min-height:42px!important;padding:4px 8px!important;font:700 13px ui-monospace,monospace!important}\r\n.meditation-panel .breath-actions [data-breath-pause]{position:static;right:auto;bottom:auto;z-index:auto;min-height:42px!important}\r\n.meditation-panel .breath-exit{background:#000!important;border:2px solid #fff!important;border-radius:0!important;color:#fff!important}\r\n.meditation-panel .breath-actions [data-skip-hold]:not([hidden]){grid-column:1/-1}\r\n.meditation-panel .breath-actions [data-retry]:not([hidden]){grid-column:1/-1}\r\n.meditation-panel .breath-modes{position:static;inset:auto;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;width:100%;margin:auto;pointer-events:auto;z-index:6}\r\n.meditation-panel .breath-modes[hidden]{display:none}\r\n.meditation-panel .breath-mode-card{position:relative;inset:auto;transform:none;width:auto;min-height:85px;padding:8px!important;border:3px solid #fff!important;background:#000e!important;box-shadow:4px 4px #777!important;pointer-events:auto}\r\n.meditation-panel [data-meditation-scene]>.breathing-session{margin-inline:0!important;width:100%;max-width:760px}\r\n.meditation-panel .breath-mode-card,.meditation-panel .breath-actions button{box-sizing:border-box;min-width:0!important;width:100%!important}\r\n.meditation-panel .breath-mode-card:first-child,.meditation-panel .breath-mode-card:last-child{left:auto;right:auto}\r\n.meditation-panel .breath-mode-card::after{display:none}\r\n.meditation-panel .breath-mode-card strong{font-size:clamp(12px,3.2vw,16px)}\r\n.meditation-panel .breath-mode-card small{font-size:clamp(9px,2.5vw,12px)}\r\n.meditation-panel .breath-seated-notice{font-size:9px!important;line-height:1.15}\r\n.meditation-panel .breathing-session [data-status]{position:static;top:auto;left:auto;right:auto;z-index:auto;margin:0;text-align:center;font:10px ui-monospace,monospace;pointer-events:none}\r\n.meditation-panel .breath-note{display:block;max-width:760px;margin:0 auto!important;padding:2px 5px;font:10px/1.2 ui-monospace,monospace!important;text-align:center;pointer-events:none;text-shadow:1px 1px #000}\r\n@media(max-height:700px){.meditation-panel .breathing-orbit{top:29%;width:min(48vh,240px)}.meditation-panel .breath-count{top:calc(50% - 65px);font-size:clamp(58px,18vw,100px)}.meditation-panel [data-session-clock]{font-size:17px;padding:4px 8px}.meditation-panel .breath-direction{left:calc(50% + 48px);top:50%;font-size:9px}.meditation-panel .meditation-character{bottom:31%;height:min(20vh,140px)}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:64%}.meditation-panel .breath-mode-card{min-height:65px;padding:5px!important}.meditation-panel .breath-note{font-size:8px!important}}\r\n@media (orientation:portrait) and (min-height:701px) and (max-height:780px){.meditation-panel .meditation-character{bottom:39%}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:61%}}\r\n@media(max-width:340px){.meditation-panel .breath-modes{width:100%;gap:5px}.meditation-panel .breath-mode-card{padding:5px!important}.meditation-panel .breath-mode-card small{font-size:8px}}\r\n@media(orientation:landscape) and (max-height:600px){\r\n .meditation-panel [data-meditation-scene]>.breathing-session{left:52%;right:2%;bottom:3%;width:46%;max-width:none;margin-inline:0!important;padding:0;gap:4px}\r\n .meditation-panel .breathing-orbit{left:27%;top:33%;width:min(42vh,220px)}\r\n .meditation-panel .breath-count{top:calc(50% - 56px);font-size:clamp(54px,13vh,78px)}\r\n .meditation-panel [data-session-clock]{font-size:16px;padding:4px 8px}\r\n .meditation-panel .breath-direction{left:calc(50% + 43px);top:50%;font-size:8px}\r\n .meditation-panel .meditation-character{left:27%;bottom:3%;height:min(40vh,145px);width:min(26vw,165px)}\r\n .meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:20%;left:52%;right:3%;width:45%;max-width:none;padding:5px 8px;font-size:12px;line-height:1.2}\r\n .meditation-panel .breathing-session{left:52%;right:2%;bottom:3%;width:46%;max-width:none;padding:0;gap:4px}\r\n .meditation-panel .breath-run:not([hidden]){gap:4px;padding:5px 7px}\r\n .meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:10px!important}\r\n .meditation-panel .breathing-session progress{height:6px}\r\n .meditation-panel .breath-actions{gap:4px}\r\n .meditation-panel .breath-actions button{min-height:38px!important;padding:3px 5px!important;font-size:11px!important}\r\n .meditation-panel .breath-modes{gap:5px}\r\n .meditation-panel .breath-mode-card{min-height:66px;padding:5px!important}\r\n .meditation-panel .breath-mode-card small{font-size:9px}\r\n .meditation-panel .breath-seated-notice{font-size:7px!important}\r\n .meditation-panel .breathing-session [data-status]{font-size:8px}\r\n .meditation-panel .breath-note{font-size:8px!important;line-height:1.05}\r\n}\r\n@media(prefers-reduced-motion:reduce){.meditation-panel .breathing-ring{transform:scale(.9)!important;transition:none!important}}\r\n\r\n/* User-directed scene update: own Gala sprite, forest silhouette and a genuinely phase-driven stop ring. */\r\n.meditation-panel [data-meditation-scene]{container-type:size;container-name:meditation-scene}\r\n.meditation-panel .meditation-character{left:25%;bottom:44%;height:clamp(118px,20vh,150px);width:auto;min-width:90px;transform:translateX(-50%);z-index:6}\r\n.meditation-panel .meditation-character canvas{display:block;width:auto;height:100%;max-width:none;image-rendering:pixelated;filter:drop-shadow(4px 4px #000)}\r\n.meditation-panel .meditation-character .pose{display:none!important}\r\n.meditation-panel .forest-canopy{position:absolute;left:-3%;right:-3%;bottom:19%;height:24%;z-index:1;pointer-events:none;filter:grayscale(1);image-rendering:pixelated}\r\n.meditation-panel .forest-canopy svg{display:block;width:100%;height:100%;image-rendering:pixelated;filter:drop-shadow(0 -3px #fff)}\r\n.meditation-panel .meditation-coach{left:-21%;right:-21%;bottom:4%;height:94%;opacity:.42;filter:grayscale(1) contrast(1.22)}\r\n.meditation-panel .meditation-coach .myr5-companion-card{opacity:1;mix-blend-mode:screen}\r\n.meditation-panel .coach-pixel{left:-12%;right:-12%;bottom:7%;width:124%;height:76%;opacity:.82;z-index:1;filter:grayscale(1) contrast(1.3)}\r\n.meditation-panel .breathing-orbit{top:36%;width:min(70vw,370px);z-index:5}\r\n.meditation-panel .breathing-ring{transform:scale(var(--breath-scale,.91))!important;transition:transform .06s linear,opacity .06s linear!important;will-change:transform}\r\n.meditation-panel .breathing-ring-stop{position:absolute;inset:0;z-index:2;border:0!important;border-radius:50%!important;background:transparent!important;box-shadow:none!important;padding:0!important;transform:scale(var(--breath-scale,.91));transform-origin:center;cursor:pointer;pointer-events:auto}\r\n.meditation-panel .breathing-ring-stop[hidden]{display:none}\r\n.meditation-panel .breathing-ring-stop:focus-visible{outline:4px solid #fff!important;outline-offset:8px!important}\r\n.meditation-panel .breath-count,.meditation-panel [data-session-clock],.meditation-panel .breath-direction{pointer-events:none}\r\n.meditation-panel .breath-count{z-index:4}\r\n.meditation-panel [data-session-clock]{z-index:5}\r\n.meditation-panel .breath-direction{z-index:5}\r\n.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{font-size:clamp(28px,7vw,38px)!important;line-height:1.13!important;max-width:min(94vw,900px);padding:10px 13px;z-index:6}\r\n.meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:clamp(20px,5vw,26px)!important;line-height:1.14;max-height:none;overflow:visible}\r\n.meditation-panel .breath-modes{grid-template-columns:repeat(2,minmax(0,1fr));align-items:stretch}\r\n.meditation-panel .breath-mode-card{min-height:76px}\r\n.meditation-panel .breath-mode-card strong{font-size:clamp(14px,3.8vw,19px)}\r\n.meditation-panel .breath-mode-card small{font-size:clamp(11px,3vw,15px)}\r\n.meditation-panel .breath-note{font-size:12px!important;line-height:1.2}\r\n.meditation-panel .breath-run:not([hidden]) .breath-seated-notice{font-size:13px!important;line-height:1.15}\r\n.meditation-panel .breath-actions button{font-size:14px!important}\r\n.meditation-panel .meditation-coach{transform-origin:50% 95%}\r\n@media(prefers-reduced-motion:reduce){.meditation-panel .breathing-ring{transition:transform .06s linear,opacity .06s linear!important;animation:none!important}}\r\n@container meditation-scene (orientation: portrait) and (max-height: 780px){\r\n .meditation-panel .breathing-orbit{top:29%;width:min(62vw,230px)}\r\n .meditation-panel .breath-count{top:calc(50% - 60px);font-size:clamp(52px,16vw,82px)}\r\n .meditation-panel [data-session-clock]{font-size:17px;padding:4px 8px}\r\n .meditation-panel .meditation-character{left:22%;bottom:44%;height:min(18cqh,134px);min-width:84px}\r\n .meditation-panel .forest-canopy{bottom:20%;height:42%}\r\n .meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:52%;bottom:auto;left:36%;right:3%;width:auto;box-sizing:border-box;font-size:clamp(27.75px,7.4vw,34px)!important;line-height:1.07!important}\r\n .meditation-panel .breathing-session{bottom:max(5px,env(safe-area-inset-bottom));gap:3px;padding-inline:8px}\r\n .meditation-panel .breath-modes{gap:5px}\r\n .meditation-panel .breath-mode-card{min-height:62px;padding:5px!important}\r\n .meditation-panel .breath-mode-card strong{font-size:14px}\r\n .meditation-panel .breath-mode-card small{font-size:11px}\r\n .meditation-panel .breath-run:not([hidden]){gap:3px;padding:5px 7px}\r\n .meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:24px!important}\r\n .meditation-panel .breath-actions button{min-height:36px!important;font-size:12px!important}\r\n .meditation-panel .breath-note{font-size:10px!important}\r\n}\r\n@container meditation-scene (orientation: portrait) and (max-height: 660px){\r\n .meditation-panel .breathing-orbit{top:25%;width:min(56vw,175px)}\r\n .meditation-panel .breath-count{top:calc(50% - 48px);font-size:clamp(42px,14vw,68px)}\r\n .meditation-panel .breath-direction{left:calc(50% + 40px);font-size:8px}\r\n .meditation-panel .meditation-character{left:22%;bottom:44%;height:min(16cqh,102px);min-width:70px}\r\n .meditation-panel .forest-canopy{bottom:20%;height:30%}\r\n .meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:43%;left:36%;right:3%;width:auto;box-sizing:border-box;font-size:clamp(27.75px,7.4vw,30px)!important;max-height:none;overflow:visible}\r\n .meditation-panel .breath-mode-card{min-height:50px;padding:3px!important}\r\n .meditation-panel .breath-mode-card small,.meditation-panel .breath-note{font-size:9px!important}\r\n .meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:24px!important}\r\n .meditation-panel .breath-actions button{min-height:32px!important;font-size:11px!important}\r\n}\r\n@container meditation-scene (orientation: landscape) and (max-height: 600px){\r\n .meditation-panel .breathing-orbit{top:34%;width:min(40cqh,205px)}\r\n .meditation-panel .meditation-character{left:27%;bottom:3%;height:min(38cqh,130px);width:auto}\r\n .meditation-panel .forest-canopy{left:0;right:48%;bottom:4%;height:25%}\r\n .meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:18%;left:52%;right:3%;width:auto;box-sizing:border-box;font-size:clamp(24px,5vh,31px)!important;line-height:1.05!important}\r\n .meditation-panel [data-meditation-scene]>.breathing-session{left:52%;right:2%;bottom:2%;width:46%;max-width:none;padding:0;gap:3px}\r\n .meditation-panel .breath-modes{gap:4px}\r\n .meditation-panel .breath-mode-card{min-height:46px;padding:3px!important}\r\n .meditation-panel .breath-mode-card small{font-size:10px}\r\n .meditation-panel .breath-phase{font-size:20px!important}\r\n .meditation-panel .breath-note{font-size:9px!important}\r\n}\r\n\r\n/* Pause holds the exact painted breath phase; tapping the ring remains a small, smooth target. */\r\n.meditation-panel.breathing-paused .breathing-ring,.meditation-panel.breathing-paused .breathing-ring-stop{transition:none!important}\r\n@container meditation-scene (orientation: portrait) and (min-height: 781px){.meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:24px!important}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{font-size:clamp(28px,7.4vw,38px)!important;box-sizing:border-box}}\r\n@container meditation-scene (orientation: landscape) and (max-height: 600px){.meditation-panel .meditation-character{left:12%}.meditation-panel .breath-run:not([hidden]) .breath-phase{font-size:20px!important}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{width:auto;box-sizing:border-box}}\r\n\r\n@container meditation-scene (orientation: portrait){.meditation-panel .meditation-character{left:21%}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{left:39%;font-family:system-ui,sans-serif!important}}\r\n@container meditation-scene (orientation: landscape) and (max-height: 600px){.meditation-panel .breathing-orbit{width:min(52cqh,245px)}.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{font-family:system-ui,sans-serif!important}}\r\n\r\n@container meditation-scene (orientation: portrait) and (min-height: 781px){.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:49%}}\r\n@container meditation-scene (orientation: portrait) and (min-height: 661px) and (max-height: 780px){.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:47%}}\r\n@container meditation-scene (orientation: landscape) and (max-height: 600px){.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:22%}}\r\n\r\n@container meditation-scene (orientation: landscape) and (max-height: 600px){.meditation-panel .meditation-speech,.meditation-panel .meditation-near .meditation-speech{top:58px;padding-block:0;line-height:1.2!important}}\r\n\r\n.meditation-panel .room-pixels{display:none!important}.meditation-panel.meditation-colour.has-wonder-art .meditation-far{background:#000!important}\r\n.meditation-panel .room-art{display:none!important}\r\n.meditation-panel .forest-canopy{display:none!important}\r\n.meditation-panel .meditation-far{background:url('/pod/worlds/meditation-waterfall.png') center bottom / cover no-repeat!important;image-rendering:pixelated!important}\r\n.meditation-panel.meditation-colour.has-wonder-art .meditation-far{background:url('/pod/worlds/meditation-waterfall.png') center bottom / cover no-repeat!important;image-rendering:pixelated!important}\r\n.meditation-panel.has-wonder-art .meditation-far{background:url('/pod/worlds/meditation-waterfall.png') center bottom / cover no-repeat!important;image-rendering:pixelated!important}\r\n.meditation-panel .meditation-mid{opacity:.75!important}\r\n.meditation-panel .breath-hud{position:absolute;left:0;right:0;bottom:12%;display:grid;place-items:center;z-index:5;pointer-events:none}\r\n.meditation-panel .breath-hud .breath-count{font-size:clamp(48px,14vw,84px);top:auto!important;bottom:auto!important;position:static!important}\r\n.meditation-panel .breath-hud .breathing-ring-stop{position:static;width:44px;height:44px;pointer-events:auto;background:none;border:0;padding:0;margin:0}\r\n.meditation-panel .meditation-character{left:25%;bottom:6% !important;height:20vh!important}\r\n.meditation-panel .meditation-coach{z-index:1!important}\r\n/* R18 A3: grey veil over the whole stage (a sibling, so nothing inherits a filter); a hole centred on the character grows with each completed breath. */\r\n@property --reveal-r{syntax:'<length>';inherits:false;initial-value:0px}\r\n.meditation-grey{position:absolute;inset:0;z-index:3;pointer-events:none;--cx:50%;--cy:60%;--reveal-r:0px;-webkit-backdrop-filter:grayscale(1);backdrop-filter:grayscale(1);-webkit-mask-image:radial-gradient(circle at var(--cx) var(--cy),transparent calc(var(--reveal-r) - 28px),#000 var(--reveal-r));mask-image:radial-gradient(circle at var(--cx) var(--cy),transparent calc(var(--reveal-r) - 28px),#000 var(--reveal-r));transition:--reveal-r 1.2s ease-out,opacity 2.5s ease}\r\n.meditation-colour .meditation-grey{opacity:0}\r\n/* R18 A4: seated warning, full-scene, fades out on Accept */\r\n.breath-seated-overlay{position:absolute;inset:0;z-index:20;display:grid;place-items:center;padding:24px;background:#050a12f2;transition:opacity .6s ease}.breath-seated-overlay[hidden]{display:none}.breath-seated-overlay.fading{opacity:0;pointer-events:none}\r\n.breath-seated-overlay>div{display:grid;gap:20px;max-width:360px;justify-items:center;text-align:center}.meditation-panel .breath-seated-overlay .breath-seated-notice{font-size:17px!important;line-height:1.45}.breath-seated-overlay button{min-height:48px;padding:0 36px;border:2px solid #fff;border-radius:10px;background:#0b1c26;color:#fff;font:700 17px Georgia,serif;cursor:pointer}\r\n/* R18 A5: speech bubbles fade in (.5 s), stay 4 s, fade out (.5 s) */\r\n.meditation-panel .meditation-speech{opacity:0}.meditation-panel .meditation-speech.bubble{animation:bubble 5s ease forwards}@keyframes bubble{0%{opacity:0}10%,90%{opacity:1}100%{opacity:0}}\r\n/* R18 A6: the four-legged coach behind the waterfall leaps out through the water at the viewer (700 ms), then the dialog closes */\r\n.meditation-panel.coach-leap .meditation-mid{z-index:4;opacity:1!important}.meditation-panel.coach-leap .meditation-coach{animation:coach-leap .7s cubic-bezier(.4,0,.8,.6) forwards}.meditation-panel.coach-leap .meditation-far{animation:coach-splash .7s ease-out}\r\n@keyframes coach-leap{0%{transform:translateY(0) scale(1);opacity:.45}35%{transform:translateY(-8%) scale(1.9);opacity:.85}70%{transform:translateY(4%) scale(3.6);opacity:.95}100%{transform:translateY(14%) scale(6);opacity:0}}@keyframes coach-splash{40%{filter:brightness(1.7) saturate(1.3)}}\r\n/* R18 A3: while a session runs the controls sit at the top, so the seated character (the centre of the colour circle) and the counter stay visible. */\r\n@media(orientation:portrait){.meditation-panel:has([data-breath-run]:not([hidden])) .breathing-session{top:56px;bottom:auto}}\r\n/* R18 polish: a clear scene. No platform diamond; the coach is a solid dark shadow; the counter is a small chip; the top panel fades after Accept. */\r\n.meditation-panel .meditation-platform{display:none}\r\n.meditation-panel .meditation-coach{left:14%;right:14%;bottom:34%;height:36%;filter:brightness(0);opacity:.45}\r\n.meditation-panel .meditation-coach .coach-pixel{filter:brightness(0)}\r\n.meditation-panel .breath-hud{left:auto;right:5%;width:auto;bottom:3%;display:flex;gap:8px;align-items:center;justify-content:flex-end;pointer-events:none}\r\n.meditation-panel .breath-hud .breath-count{position:static!important;transform:none!important;font:700 14px/1 ui-monospace,monospace!important;letter-spacing:0;text-shadow:1px 1px #000;order:2}\r\n.meditation-panel .breath-hud [data-session-clock]{position:static!important;transform:none!important;font-size:14px!important;padding:3px 8px;box-shadow:none;order:1}\r\n.meditation-panel .breath-hud .breath-direction{position:static!important;transform:none!important;font-size:11px!important;order:3}\r\n.meditation-panel .breath-hud .breathing-ring-stop{order:4;width:auto;height:auto;padding:3px 8px;border:2px solid #fff;background:#000;color:#fff;font:700 12px ui-monospace,monospace;transform:none!important}.meditation-panel .breath-hud .breathing-ring-stop::before{content:\"Exit\"}\r\n.meditation-panel .breathing-session{transition:opacity .6s ease}.meditation-panel.hud-calm .breathing-session{opacity:.07;pointer-events:none}\r\n/* leap splash: a burst of water drops from the middle of the falls */\r\n.meditation-panel.coach-leap .meditation-stage::before{content:'';position:absolute;left:50%;top:48%;width:10px;height:10px;margin:-5px;border-radius:50%;z-index:6;pointer-events:none;background:#e9fbff;box-shadow:-60px -30px #bff3ff,60px -30px #e9fbff,-90px 10px #7fe3f5,90px 10px #bff3ff,-40px 50px #e9fbff,40px 50px #7fe3f5,0 -70px #bff3ff,-20px 80px #bff3ff,25px -55px #e9fbff,-75px -65px #7fe3f5,80px -60px #bff3ff;animation:coach-drops .7s ease-out forwards}\r\n@keyframes coach-drops{from{transform:scale(.2);opacity:1}to{transform:scale(3.2);opacity:0}}\r\n.meditation-panel.coach-leap .breathing-session{opacity:0;pointer-events:none}\r\n/* in the routed room the dock sits inside the panel: lift the chip and the character above it */\r\n/* R20: the room now ends at the 88px console's top edge (R19's 64px bar overlapped its last 24px): lift by 40px to\r\n   keep the chip and character where they stood on screen. */\r\n.meditation-panel:has(>#coachDock) .breath-hud{bottom:calc(40px + env(safe-area-inset-bottom) + 6px)}.meditation-panel:has(>#coachDock) .meditation-character{bottom:calc(6% + 40px + env(safe-area-inset-bottom))!important}\r\n@media(orientation:landscape){.meditation-panel .breath-hud{left:30%;right:auto}}.meditation-panel .breath-hud .breathing-ring-stop{min-width:44px;min-height:32px}\r\n\r\n/* R20 meditation: one Begin button, a settle countdown, the steady in/out cue, and a per-tick colour pulse. */\r\n.meditation-grey{transition:--reveal-r 60ms linear,opacity 2.5s ease}\r\n/* Begin sits bottom-right, above the chip, clear of the seated character at bottom-left */\r\n.meditation-panel .breathing-session .breath-modes{display:grid;grid-template-columns:1fr;justify-items:end}\r\n.meditation-panel .breathing-session .breath-modes[hidden]{display:none}\r\n.meditation-panel .breath-begin{min-height:56px;width:min(46vw,190px)!important;padding:0 20px;border:3px solid #fff;border-radius:0;background:#000;color:#fff;box-shadow:4px 4px #777;font:700 22px ui-monospace,monospace;letter-spacing:.12em;pointer-events:auto;cursor:pointer}\r\n.meditation-panel .breath-begin:focus-visible{outline:3px solid #fff;outline-offset:5px}\r\n.meditation-panel .breath-settle,.meditation-panel .breath-cue{position:absolute;left:50%;right:auto;width:max-content;transform:translateX(-50%);top:30%;z-index:5;margin:0;pointer-events:none;color:#fff;text-align:center;text-shadow:3px 3px #000}\r\n.meditation-panel .breath-settle{display:flex;justify-content:center;align-items:baseline;gap:12px}\r\n.meditation-panel .breath-settle[hidden],.meditation-panel .breath-cue[hidden]{display:none}\r\n.meditation-panel .breath-settle small{font:700 16px ui-monospace,monospace;letter-spacing:.2em;text-transform:uppercase}\r\n.meditation-panel .breath-settle b{font:900 min(72px,18vw,11vh)/1 ui-monospace,monospace}\r\n.meditation-panel .breath-cue{font:700 min(42px,8.5vw,8vh)/1 ui-monospace,monospace;opacity:1;animation:none}\r\n@media(max-height:700px){.meditation-panel .breath-settle,.meditation-panel .breath-cue{top:22%}}\r\n@media(orientation:landscape){.meditation-panel .breath-settle,.meditation-panel .breath-cue{left:27%;top:30%}}\r\n.meditation-panel:has([data-breath-modes]:not([hidden])) .breath-hud{visibility:hidden} /* start screen: the idle 3:30 chip sat under the safety note */\r\n/* R20: the portal's \"Tilt to look around\" tab sits on the dock's top edge, left; lift the counter chip and Begin clear of it */\r\n/* R20 frame: portrait only; in landscape the HUD and Begin sit right of the tab (left:30%+) and the shorter room has no 36px to spare. */\r\n@media(orientation:portrait){.meditation-panel:has(>.portal-peer-ui>.portal-tilt-chip) .breath-hud{translate:0 -36px}.meditation-panel:has(>.portal-peer-ui>.portal-tilt-chip) .breathing-session .breath-modes{translate:0 -44px}}\r\n","meditation.mjs":"import {mountTubFlight} from './arcade/tub-flight/game.mjs';\r\nimport {mountBreathing,bubble} from './breathing.mjs';\r\nimport {todaysBackground,averageRgb} from './meditation-backgrounds.mjs';\r\n// #149 (D46): the meditation track's starting boss and only mount, Four-legged 7, sleeps big behind you.\r\nexport const MEDITATION_COACH='roster/18-quad-all--robotic_dog_3d_model';\r\nconst SLEEP_YAW=-.9; // resting three-quarters on, head toward screen left, behind your character\r\nexport function mountMeditation({api,onComplete,getAccount,backgroundLookup}={}){\r\n const open=document.createElement('button');open.type='button';open.className='meditation-entry';open.innerHTML='<span>◌</span><strong>Meditation</strong><small aria-hidden=\"true\">→</small>';document.querySelector('.crew-footer').after(open);\r\n // #149: the room is three peering layers (data-peer-depth): far = the day's wonder, mid = the big sleeping coach,\r\n // near = your seated character, the ring and the caption. All black and white until a full session brings the colour back.\r\n const dialog=document.createElement('dialog');dialog.className='launch-panel meditation-panel';dialog.setAttribute('aria-labelledby','meditation-title');dialog.innerHTML='<header><h2 id=\"meditation-title\">The still room</h2><button data-meditation-close>Close</button></header><section data-meditation-scene><div class=\"meditation-stage\"><div class=\"meditation-layer meditation-far\" data-peer-depth=\"far\" aria-hidden=\"true\"></div><div class=\"meditation-layer meditation-mid\" data-peer-depth=\"mid\" aria-hidden=\"true\"><div class=\"meditation-platform\"></div><div class=\"meditation-coach\"></div></div><div class=\"meditation-layer meditation-near\" data-peer-depth=\"near\"><button class=\"meditation-character\" aria-label=\"Tap your Gala character\"><canvas width=\"64\" height=\"96\"></canvas></button><div class=\"forest-canopy\" aria-hidden=\"true\"></div><div class=\"meditation-can\" aria-hidden=\"true\"><b>FUEL</b><i></i></div><div class=\"meditation-powder\" aria-hidden=\"true\">· · · · ·</div><p class=\"meditation-speech\" role=\"status\">Breathe in. Breathe out.</p><p class=\"breath-cue\" data-breath-cue aria-hidden=\"true\" hidden></p><div class=\"breath-settle\" data-settle-countdown aria-hidden=\"true\" hidden><small>Settle</small><b></b></div></div><div class=\"meditation-grey\" aria-hidden=\"true\"></div></div><button data-breath-pause type=\"button\">Pause</button></section><section data-meditation-arcade hidden></section><div class=\"meditation-blackout\" aria-hidden=\"true\">'+Array.from({length:8},(_,i)=>'<i style=\"--strip:'+i+'\"></i>').join('')+'</div>';document.body.append(dialog);\r\n const scene=dialog.querySelector('[data-meditation-scene]'),stage=dialog.querySelector('.meditation-stage'),coachBox=dialog.querySelector('.meditation-coach'),character=dialog.querySelector('.meditation-character'),speech=dialog.querySelector('.meditation-speech'),arcade=dialog.querySelector('[data-meditation-arcade]'),breathPause=dialog.querySelector('[data-breath-pause]');let taps=0,game=null,timers=[],transitioning=false,epoch=0,borrowed=null,drag=null;\r\n // The room art is deliberately drawn from simple SVG shapes so it remains bundled, crisp, and offline.\r\n const far=dialog.querySelector('.meditation-far');far.innerHTML='<svg class=\"room-art\" viewBox=\"0 0 800 900\" preserveAspectRatio=\"xMidYMid slice\" aria-hidden=\"true\"><g fill=\"#050505\" stroke=\"#fff\" stroke-width=\"5\" stroke-linejoin=\"miter\"><path d=\"M0 650h800v250H0z\"/><path d=\"M36 612h36v-32h22v-36h22v-39h23v-37h26v37h22v39h22v36h34v32h22v288H36zM229 612h32v-35h20v-37h21v-43h24v-41h27v41h23v43h21v37h19v35h29v288H229zM419 612h35v-33h21v-38h22v-45h24v-42h27v42h23v45h22v38h21v33h32v288H419zM617 612h31v-34h19v-36h22v-42h24v-39h25v39h22v42h20v36h24v34h24v288H617z\"/></g><path d=\"M0 650h800M0 735h800M0 820h800\" stroke=\"#fff\" stroke-width=\"4\" stroke-dasharray=\"5 21\"/><g fill=\"#fff\"><path d=\"M95 140h28v28H95zM240 225h18v18h-18zM655 112h28v28h-28zM530 310h16v16h-16zM378 95h20v20h-20z\"/></g><circle cx=\"680\" cy=\"220\" r=\"58\" fill=\"none\" stroke=\"#fff\" stroke-width=\"5\"/></svg>';\r\n const platform=dialog.querySelector('.meditation-platform');platform.innerHTML='<svg viewBox=\"0 0 800 230\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><path d=\"M28 118 400 12l372 106-372 100z\" fill=\"#050505\" stroke=\"#fff\" stroke-width=\"8\"/><path d=\"M130 118 400 45l270 73-270 75z\" fill=\"none\" stroke=\"#777\" stroke-width=\"5\" stroke-dasharray=\"12 9\"/></svg>';\r\n const coachArt=document.createElementNS('http://www.w3.org/2000/svg','svg');coachArt.setAttribute('viewBox','0 0 800 500');coachArt.setAttribute('aria-hidden','true');coachArt.classList.add('coach-pixel');coachArt.innerHTML='<g fill=\"#050505\" stroke=\"#fff\" stroke-width=\"14\" stroke-linejoin=\"round\"><path d=\"M188 178 270 120 542 112 632 168 682 270 612 326 244 328 158 273z\"/><path d=\"m232 292-25 148h70l56-134M330 305l8 142h70l26-137M530 304l-2 143h68l37-143M615 293l62 139h67l-73-195\"/><path d=\"m173 194-86-70-55 22 91 132\"/><path d=\"m600 176 92-85 62 24-110 129\"/><path d=\"m608 176 35-78 68-10 46 43-35 75z\"/></g><g fill=\"#fff\"><path d=\"M682 139h25v25h-25zM731 139h25v25h-25z\"/></g>';\r\n coachBox.prepend(coachArt);character.innerHTML='<canvas width=\"64\" height=\"96\"></canvas>';\r\n const canopy=dialog.querySelector('.forest-canopy');canopy.innerHTML='<svg viewBox=\"0 0 800 180\" preserveAspectRatio=\"none\" aria-hidden=\"true\"><path d=\"M0 126h800v54H0z\" fill=\"#000\"/><g fill=\"#000\" stroke=\"#fff\" stroke-width=\"6\" stroke-linejoin=\"miter\"><path d=\"M46 151h28v-24h20v-21h18V83h18V59h17v24h18v23h20v21h27v29zM237 151h24v-25h19v-22h18V79h18V53h18v26h18v25h19v22h25v25zM430 151h28v-24h19v-23h17V74h20V47h18v27h20v30h17v23h25v24zM622 151h24v-23h18v-22h17V79h20V57h17v22h18v27h19v22h29v23z\"/></g><path d=\"M157 119v54m171-53v54m214-55v55m157-52v52\" stroke=\"#fff\" stroke-width=\"7\"/><path d=\"M157 139 135 122m22 10 20-18m151 43-22-18m22 4 21-18m192 42-22-20m22 5 23-19m134 34-21-18m21 4 21-18\" stroke=\"#fff\" stroke-width=\"5\"/><path d=\"M0 165h800\" stroke=\"#fff\" stroke-width=\"4\" stroke-dasharray=\"8 18\"/></svg>';\r\n const stopCircle=document.createElement('button'),count=document.createElement('b'),sessionClock=document.createElement('small'),direction=document.createElement('i');count.className='breath-count';count.dataset.breathCount='';count.textContent='—';sessionClock.dataset.sessionClock='';sessionClock.textContent='3:30';direction.className='breath-direction';direction.dataset.breathDirection='';direction.textContent='SETTLE';stopCircle.type='button';stopCircle.className='breathing-ring-stop';stopCircle.dataset.breathingStop='';stopCircle.dataset.breathExit='';stopCircle.setAttribute('aria-label','Stop the breathing session and leave the room');stopCircle.hidden=true;const hud=document.createElement('div');hud.className='breath-hud';hud.append(count,sessionClock,direction,stopCircle);dialog.querySelector('.meditation-near').append(hud);\r\n const reducedMotion=matchMedia('(prefers-reduced-motion: reduce)');\r\n const later=(fn,ms)=>{const id=setTimeout(fn,ms);timers.push(id);};\r\n // Cancelled with the room: reset() clears the timer, so the awaiting sequence simply never resumes.\r\n const wait=ms=>new Promise(resolve=>later(resolve,ms));\r\n const say=line=>bubble(speech,line);\r\n function portrait(){character.dataset.expression=taps>=3?'focused':'calm';try{const avatar=window.GalaAvatar,canvas=character.querySelector('canvas');let look=avatar.defaultLook;try{look=avatar.normalize(JSON.parse(localStorage.getItem('mominc-avatar-v1')));}catch{}avatar.draw(canvas,look,{base:false,weapon:false,prop:false,blink:false,pose:{meditate:true}});}catch{}}\r\n\r\n function reset(){epoch++;timers.forEach(clearTimeout);timers=[];game?.dispose();game=null;taps=0;transitioning=false;scene.hidden=false;arcade.hidden=true;dialog.classList.remove('snorting','blacking-out','meditation-colour','coach-leap','coach-wander');peer(0,0);stage.dataset.annoyed='0';character.disabled=false;dialog.classList.remove('breathing-paused');breathPause.textContent='Pause';say('Breathe in. Breathe out.');portrait();}\r\n // D28: the day's \"wonders\" pack background when a caller-supplied lookup has it downloaded,\r\n // otherwise today's bundled starter wonder; the neutral gradient only shows if the image fails.\r\n async function applyBackground(){\r\n  const requestEpoch=epoch,{id,url}=await todaysBackground(backgroundLookup);let art=null;\r\n  if(url)try{const img=new Image();img.src=url;await img.decode();if(requestEpoch!==epoch||!dialog.open)return;const base=bottomColour(img);art={url:`url(\"${url}\")`,base,grey:base&&grey(base)};pixelateWonder(img);}catch{}\r\n  if(requestEpoch!==epoch||!dialog.open)return;\r\n   dialog.dataset.wonder=art?id:'';dialog.classList.toggle('has-wonder-art',!!art);starter.hidden=!!art;\r\n  for(const key of ['url','base','grey'])art?.[key]?dialog.style.setProperty('--wonder-'+key,art[key]):dialog.style.removeProperty('--wonder-'+key);\r\n }\r\n function pixelateWonder(img){try{const canvas=document.createElement('canvas');canvas.className='room-pixels';canvas.width=56;canvas.height=64;const ctx=canvas.getContext('2d',{willReadFrequently:true});ctx.imageSmoothingEnabled=false;ctx.drawImage(img,0,0,canvas.width,canvas.height);const pixels=ctx.getImageData(0,0,canvas.width,canvas.height);for(let i=0;i<pixels.data.length;i+=4){const y=Math.round(.2126*pixels.data[i]+.7152*pixels.data[i+1]+.0722*pixels.data[i+2]);const v=y<70?0:y<135?88:y<200?176:255;pixels.data[i]=pixels.data[i+1]=pixels.data[i+2]=v;}ctx.putImageData(pixels,0,0);far.prepend(canvas);}catch{}}\r\n // W2-2O: the starter wonders are Starter-pack art; without today's (offline, not downloaded) the plain room shows and the pack is offered.\r\n const starter=document.createElement('p'),get=document.createElement('button');starter.className='meditation-starter';starter.hidden=true;\r\n get.type='button';get.textContent='Download the Starter pack';get.onclick=()=>window.myr5Packs?.open('starter');\r\n starter.append('Backgrounds come with the Starter pack. ',get);stage.after(starter); // below the room: the caption now sits inside its near layer (#149)\r\n function bottomColour(img){try{const c=document.createElement('canvas');c.width=img.naturalWidth;c.height=1;const g=c.getContext('2d');g.drawImage(img,0,img.naturalHeight-1,img.naturalWidth,1,0,0,img.naturalWidth,1);return averageRgb(g.getImageData(0,0,c.width,1).data);}catch{return null;}}\r\n // The panel below the stage continues the wonder's bottom edge; while the room is black and white, in grey (grayscale() weights).\r\n function grey(rgb){const [r,g,b]=rgb.match(/\\d+/g).map(Number),y=Math.round(.2126*r+.7152*g+.0722*b);return `rgb(${y},${y},${y})`;}\r\n // The big sleeping coach: borrow the live companion card (creature/assets/phone.js, loaded here if the pod hasn't yet) into\r\n // the mid layer and show the meditation boss built on the user's own recipe, asleep. pod.mjs re-homes the card on any #view\r\n // change unless body.dataset.shipView is set, so the room holds that flag while it has the card, as the ship view does.\r\n async function borrowCoach(run){\r\n  let card=document.querySelector('.myr5-companion-card');\r\n  if(!card&&document.getElementById('view')){\r\n   if(!document.querySelector('link[href=\"/creature/phone.css\"]')){const link=document.createElement('link');link.rel='stylesheet';link.href='/creature/phone.css';document.head.append(link);}\r\n   try{await import('/creature/assets/phone.js');}catch{}card=document.querySelector('.myr5-companion-card');\r\n  }\r\n  const creature=window.myr5Creature;if(run!==epoch||!dialog.open||!card||!creature?.preview)return;\r\n  borrowed={card,home:card.parentElement,stage:creature.stats?.().stage,flag:document.body.dataset.shipView??''};\r\n  document.body.dataset.shipView='true';coachBox.append(card);card.hidden=true;coachArt.style.display='';creature.stage('overlay');creature.sleep(true);\r\n  let shown=false;try{shown=await creature.preview({body:MEDITATION_COACH,headFrom:MEDITATION_COACH,armsFrom:MEDITATION_COACH,feetFrom:MEDITATION_COACH});}catch{}\r\n  if(run===epoch&&dialog.open){if(shown){coachArt.style.display='none';card.hidden=false;creature.walk?.(false);creature.sleep?.(true);creature.face?.(SLEEP_YAW);creature.stage?.('overlay');creature.walk?.(false);creature.sleep?.(true);creature.face?.(SLEEP_YAW);}else{coachArt.style.display='';card.hidden=true;}}\r\n  // If the model is offline, the drawn four-legged room figure remains visible; never substitute the user's coach.\r\n }\r\n function releaseCoach(){\r\n  if(!borrowed)return;const {card,home,stage:was,flag}=borrowed,creature=window.myr5Creature;borrowed=null;card.hidden=false;\r\n  creature?.walk?.(false);creature?.face?.(0);creature?.sleep?.(false);void creature?.preview?.(null)?.catch?.(()=>{});\r\n  document.body.dataset.shipView=flag;(home?.isConnected?home:document.getElementById('coachMount')||document.getElementById('view')||document.body).append(card);\r\n  if(was)creature?.stage?.(was);\r\n }\r\n // A full session: colour fades back into every layer (CSS, ~2.5 s), then the coach wakes and wanders off screen right.\r\n async function wake(){\r\n  dialog.classList.add('meditation-colour');say('The colour comes back.');await wait(2500);\r\n  const creature=borrowed&&window.myr5Creature;creature?.sleep?.(false);creature?.face?.(Math.PI/2);creature?.walk?.(true);\r\n  dialog.classList.add('coach-wander');say('Your coach wakes up and wanders off. Well breathed.');await wait(3000);creature?.walk?.(false);\r\n }\r\n // D46 \"should still have the peering effect, even if slight\": drag and the layers slide by depth (far .3, mid .6, near 1, in CSS).\r\n // ponytail: drag only; tilt can drive the same --peer-x/--peer-y on the stage (2N's wrapper) when it lands.\r\n function peer(x,y){stage.style.setProperty('--peer-x',x+'px');stage.style.setProperty('--peer-y',y+'px');}\r\n const clamp=v=>Math.max(-24,Math.min(24,v*.25));\r\n stage.addEventListener('pointerdown',event=>{if(reducedMotion.matches)return;drag={x:event.clientX,y:event.clientY};stage.classList.add('peering');});\r\n stage.addEventListener('pointermove',event=>{if(drag)peer(clamp(event.clientX-drag.x),clamp(event.clientY-drag.y));});\r\n for(const type of ['pointerup','pointercancel','pointerleave'])stage.addEventListener(type,()=>{if(!drag)return;drag=null;stage.classList.remove('peering');peer(0,0);});\r\n open.onclick=()=>{document.getElementById('stop')?.click();reset();void applyBackground();dialog.showModal();void borrowCoach(epoch);};\r\n dialog.querySelector('[data-meditation-close]').onclick=()=>dialog.close();dialog.addEventListener('close',()=>{reset();releaseCoach();open.focus();});\r\n breathPause.onclick=()=>{const paused=dialog.classList.toggle('breathing-paused');breathPause.textContent=paused?'Resume':'Pause';};\r\n character.onclick=()=>{if(transitioning)return;taps++;stage.dataset.annoyed=String(Math.min(taps,5));portrait();const lines=['I am concentrating.','That is not part of the meditation.','You. Again.','One more poke. See what happens.','Fine. Emergency fuel.'];bubble(speech,lines[Math.min(taps-1,4)]);if(taps<5)return;transitioning=true;character.disabled=true;dialog.classList.add('snorting');later(()=>dialog.classList.add('blacking-out'),1800);later(()=>{scene.hidden=true;arcade.hidden=false;game=mountTubFlight(arcade,{title:'TUB FLIGHT',onComplete:()=>{const link=document.createElement('a');link.className='primary-action';link.href='https://mominc.online/games/fuel/#fuelFlight=myr5-eight-pipes';link.target='_blank';link.rel='noopener';link.textContent='Your tub is full. Open Goon Fuel →';arcade.append(link);}});dialog.classList.remove('snorting','blacking-out');transitioning=false;arcade.querySelector('canvas').focus();},3000);};\r\n mountBreathing({dialog,scene,pause:breathPause,api,getAccount,onComplete,onSessionComplete:()=>{if(dialog.open)void wake();},onEarlyExit:async({isCurrent=()=>true}={})=>{const run=epoch;dialog.classList.add('coach-leap');await wait(700);if(run!==epoch||!dialog.open)return;dialog.classList.remove('coach-leap');if(isCurrent())dialog.close();}});\r\n window.addEventListener('pagehide',()=>{epoch++;timers.forEach(clearTimeout);timers=[];game?.dispose();game=null;if(dialog.open)dialog.close();else releaseCoach();});\r\n}\r\n","menu-lifecycle.mjs":"// Shared menu lifetime boundary. Route code calls enter() after adoption and leave() on finish.\r\n// Native close, hidden panels, and pagehide are covered as fallbacks for legacy openers.\r\nconst isElement=value=>!!value&&typeof value==='object'&&typeof value.querySelectorAll==='function';\r\n\r\nexport function mountMenuLifecycle({doc=globalThis.document,win=globalThis.window,routes=win?.myr5Routes?.ROUTES}={}){\r\n if(!doc||!win)throw new Error('Menu lifecycle needs a document and window.');\r\n const routeEntries=Object.entries(routes||{}).filter(([,route])=>route?.dialog);\r\n const resources=new Map(),states=new Map(),frames=new Map();\r\n let disposed=false;\r\n const dialogs=()=>[...doc.querySelectorAll('dialog')];\r\n function key(owner){\r\n  if(typeof owner==='string')return owner;\r\n  if(!owner)return '';\r\n  if(owner.dataset?.route)return owner.dataset.route;\r\n  const match=routeEntries.find(([,route])=>owner.matches?.(route.dialog));\r\n  return match?.[0]||owner.id||owner;\r\n }\r\n function element(owner){\r\n  if(isElement(owner))return owner;\r\n  const route=routes?.[owner];\r\n  if(route?.dialog)return doc.querySelector(route.dialog);\r\n  return typeof owner==='string'?doc.getElementById?.(owner):null;\r\n }\r\n function state(owner){\r\n  const id=key(owner);\r\n  if(!states.has(id)){\r\n   const root=element(owner);\r\n   states.set(id,{active:root?.tagName==='DIALOG'?!!root.open:root?root.hidden!==true:true});\r\n  }\r\n  return states.get(id);\r\n }\r\n function items(root,selector){return [...(root?.matches?.(selector)?[root]:[]),...(root?.querySelectorAll?.(selector)||[])];}\r\n function pauseMedia(root){for(const media of items(root,'audio,video'))try{media.pause?.();}catch{}}\r\n function suspendFrame(frame){\r\n  if(frames.has(frame)){\r\n   const saved=frames.get(frame),src=frame.getAttribute?.('src'),srcdoc=frame.getAttribute?.('srcdoc');\r\n   if(src==null&&srcdoc==null){frames.delete(frame);return;}\r\n   if(srcdoc!=null){saved.srcdoc=srcdoc;frame.removeAttribute('srcdoc');}\r\n   if(src!=null&&src!=='about:blank'){saved.src=src;frame.setAttribute('src','about:blank');}\r\n   return;\r\n  }\r\n  const src=frame.getAttribute?.('src'),srcdoc=frame.getAttribute?.('srcdoc');\r\n  if(src==null&&srcdoc==null)return;\r\n  frames.set(frame,{src,srcdoc});\r\n  frame.removeAttribute('srcdoc');\r\n  frame.setAttribute('src','about:blank');\r\n }\r\n function restoreFrames(root){\r\n  for(const frame of items(root,'iframe')){\r\n   if(hidden(frame))continue;\r\n   const saved=frames.get(frame);if(!saved)continue;\r\n   frames.delete(frame);\r\n   frame.removeAttribute('src');\r\n   if(saved.srcdoc!=null)frame.setAttribute('srcdoc',saved.srcdoc);\r\n   if(saved.src!=null)frame.setAttribute('src',saved.src);\r\n  }\r\n }\r\n function suspend(root){pauseMedia(root);for(const frame of items(root,'iframe'))suspendFrame(frame);}\r\n function hidden(frame){\r\n  if(doc.hidden||frame.closest?.('[hidden]'))return true;\r\n  const dialog=frame.closest?.('dialog');\r\n  return !!dialog&&!dialog.open||!!frame.getClientRects&&!frame.getClientRects().length;\r\n }\r\n function scanHidden(){for(const frame of doc.querySelectorAll('iframe'))if(hidden(frame))suspendFrame(frame);}\r\n function event(owner,reason){\r\n  const detail={owner:key(owner),reason,element:element(owner)};\r\n  const EventType=win.CustomEvent||globalThis.CustomEvent;\r\n  if(EventType)win.dispatchEvent(new EventType('myr5:menu-leave',{detail}));\r\n }\r\n function leave(owner,reason='route-leave'){\r\n  if(disposed)return;\r\n  const id=key(owner),entry=state(id);if(!entry.active)return;\r\n  entry.active=false;\r\n  const root=element(owner);if(root)suspend(root);\r\n  for(const resource of resources.get(id)||[])if(resource.active){resource.active=false;try{resource.dispose?.(reason);}catch(error){win.console?.error?.('Menu resource disposal failed',error);}}\r\n  event(owner,reason);\r\n }\r\n function enter(owner){\r\n  if(disposed)return;\r\n  if(doc.hidden){const root=element(owner);if(root?.open)root.close();return;}\r\n  const id=key(owner),entry=state(id);entry.active=true;\r\n  const root=element(owner);if(root)restoreFrames(root);\r\n  for(const resource of resources.get(id)||[])if(!resource.active){resource.active=true;try{resource.reopen?.();}catch(error){win.console?.error?.('Menu resource reopen failed',error);}}\r\n }\r\n function closeInactive(current){\r\n  if(disposed)return;\r\n  const active=element(current);\r\n  for(const dialog of dialogs())if(dialog.open&&dialog!==active){leave(dialog,'route-switch');dialog.close();}\r\n  scanHidden();\r\n }\r\n function stopAll(reason='page-hidden'){\r\n  if(disposed)return;\r\n  for(const dialog of dialogs())if(dialog.open){leave(dialog,reason);dialog.close();}\r\n  for(const [id,entry] of states)if(entry.active)leave(id,reason);\r\n  for(const media of doc.querySelectorAll('audio,video'))try{media.pause?.();}catch{}\r\n  for(const frame of doc.querySelectorAll('iframe'))suspendFrame(frame);\r\n }\r\n function registerMenuResource(owner,{dispose,reopen}={}){\r\n  const id=key(owner),record={dispose,reopen,active:state(id).active};\r\n  if(!resources.has(id))resources.set(id,new Set());\r\n  resources.get(id).add(record);\r\n  if(!record.active)try{dispose?.('registered-inactive');}catch(error){win.console?.error?.('Menu resource disposal failed',error);}\r\n  return ()=>resources.get(id)?.delete(record);\r\n }\r\n const onClose=e=>{if(e.target?.tagName==='DIALOG'&&!e.target.open)leave(e.target,'dialog-close');};\r\n const onVisibility=()=>{if(doc.hidden)stopAll('page-hidden');};\r\n const onPageHide=()=>stopAll('pagehide');\r\n doc.addEventListener('close',onClose,true);\r\n doc.addEventListener('visibilitychange',onVisibility);\r\n win.addEventListener('pagehide',onPageHide);\r\n const Observer=win.MutationObserver||globalThis.MutationObserver;\r\n const observer=Observer?new Observer(records=>{\r\n  for(const record of records){\r\n   if(record.type==='attributes'&&record.target?.tagName==='DIALOG'&&record.attributeName==='open'&&record.target.open)enter(record.target);\r\n  }\r\n  scanHidden();\r\n }):null;\r\n observer?.observe(doc.documentElement||doc,{subtree:true,childList:true,attributes:true,attributeFilter:['open','hidden','src','srcdoc']});\r\n scanHidden();\r\n const api={enter,leave,closeInactive,stopAll,registerMenuResource,scanHidden,dispose(){if(disposed)return;stopAll('lifecycle-dispose');disposed=true;observer?.disconnect();doc.removeEventListener('close',onClose,true);doc.removeEventListener('visibilitychange',onVisibility);win.removeEventListener('pagehide',onPageHide);resources.clear();states.clear();frames.clear();}};\r\n return api;\r\n}\r\n","menu.css":"/* Fixed glass panels: depth belongs to the surface; rotation belongs to models. */\r\n.voice-row{display:flex;align-items:center;gap:10px;margin:6px 0}.voice-row button{background:#24443d;color:#d8fff0;padding:7px 12px;min-height:40px}.voice-row span{font-size:10px;color:#c1d6d2}#coachCaption{font-size:12px;color:#afffe6;margin:4px 0;line-height:1.35}#confirmProgress{width:100%;height:6px;accent-color:#9affdf;margin-top:10px}.intro-cue{padding:12px;border:1px solid #aaffdd44;border-radius:12px;background:#193c35b0;color:#e1fff5;font-size:13px;line-height:1.5}#holoStage{max-height:420px}#handHelp summary{font-size:12px;color:#c8efe6;padding:6px 0}\r\n.library-launch{width:100%;display:flex;justify-content:space-between;align-items:center;gap:8px;margin-bottom:8px;background:#31253e;color:#f3e8ff;text-align:left}\r\n.library-launch span{font-size:10px;font-weight:400;color:#d8c6e9}\r\n#library{padding:0;border:0;width:min(900px,100vw);max-width:100vw;height:100dvh;max-height:100dvh;margin:auto;background:radial-gradient(ellipse at 15% 0%,#34404d99,transparent 55%),radial-gradient(ellipse at 90% 90%,#52316199,transparent 50%),#10141cf2;color:#f5faff;overflow:auto}\r\n#library::backdrop{background:#080b14bd;backdrop-filter:blur(8px)}\r\n#handVideo{position:fixed;inset:0;width:100%;height:100%;object-fit:cover;opacity:.32;pointer-events:none}\r\n.glass-shell{position:relative;z-index:1;padding:20px;max-width:900px;margin:auto;min-height:100%;display:flex;flex-direction:column;gap:16px}\r\n.library-header{display:flex;align-items:center;justify-content:space-between;gap:14px;flex:none}.library-header small{color:#8cebe2;font-size:10px;letter-spacing:2px}.library-header h1{font-size:24px;letter-spacing:-.8px;margin:5px 0 0;font-weight:650}\r\n#library button{min-height:52px;border:1px solid #bae9f14d;background:linear-gradient(135deg,#d2eaf91e,#b6bdd909),#172131b5;color:#f5faff;border-radius:14px;font-size:14px;box-shadow:inset 0 1px #f2ffff14,0 8px 24px #0002;backdrop-filter:blur(14px);cursor:pointer;touch-action:manipulation}\r\n#library button:focus-visible{outline:3px solid #aaffef;outline-offset:3px}#library button:hover{border-color:#b4f8ecb3}#library button.hand-hover{border-color:#b4f8ec;box-shadow:0 0 0 3px #aaffef33,inset 0 1px #fff3}#library button.hand-down{background:#3c736ac9;color:#fff}\r\n#closeLibrary{min-width:66px}.movement-cards{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;flex:1;align-content:center}\r\n.movement-card{padding:15px 14px;border:1px solid #bde7f638;border-radius:19px;background:linear-gradient(145deg,#d7e9ff13,#a3c2e804),#142031a1;box-shadow:inset 0 1px #fff1,0 12px 24px #0002;backdrop-filter:blur(16px);min-width:0}\r\n.movement-card .card-select{width:100%;text-align:left;min-height:65px!important;background:transparent!important;border:none!important;box-shadow:none!important;padding:0 5px!important;backdrop-filter:none!important}.card-number{display:block;font-size:10px;color:#88c6c6;font-weight:400;letter-spacing:1px;margin-bottom:9px}.card-title{display:block;font-size:18px;line-height:1.15}.card-kind{font-size:11px;font-weight:400;color:#c4d4e7;display:block;margin-top:7px}\r\n.movement-card .holo-link{width:100%;font-size:12px!important;margin-top:10px;min-height:48px!important;color:#aaf7ed!important}\r\n.library-footer{flex:none;border-top:1px solid #c1e2ff22;padding-top:13px}.hand-row{display:flex;gap:12px;align-items:center;flex-wrap:wrap}.hand-row button{padding:10px 15px}#handState{font-size:12px;color:#a2e9dd;max-width:40ch}.library-footer p,.library-caption{font-size:12px;line-height:1.5;color:#bccddd;margin:9px 0 0}\r\n.library-pages{display:flex;align-items:center;gap:18px;justify-content:space-between}.library-pages button{min-width:100px}.library-pages span{color:#b9d6dc;font-size:12px}\r\n#startFromLibrary{margin-bottom:12px}.card-select[aria-pressed=true] .card-title{color:#9fffe8}.card-select[aria-pressed=true] .card-kind::before{content:'Selected · ';color:#9fffe8}\r\n#handCursor{position:fixed;width:28px;height:28px;z-index:100;pointer-events:none;border:2px solid #b3fff1;border-radius:50%;transform:translate(-50%,-50%);background:#aaffef30;box-shadow:0 0 20px #aaffef55}#handCursor.pinched{width:18px;height:18px;background:#b3fff1}\r\n#hologramPanel{flex:1;display:flex;flex-direction:column;gap:10px}.holo-heading{display:flex;align-items:center;gap:16px}.holo-heading button{min-width:70px}.holo-heading h2{font-size:18px;font-weight:600}\r\n#holoStage{position:relative;flex:1;min-height:230px;overflow:hidden;border:1px solid #b9ecfa33;border-radius:24px;touch-action:none;background:radial-gradient(ellipse at 50% 85%,#69f9dd1a,transparent 55%),linear-gradient(#b4e9ff0c 1px,transparent 1px),linear-gradient(90deg,#b4e9ff0c 1px,transparent 1px),#0c17207d;background-size:auto,32px 32px,32px 32px,auto;cursor:grab}\r\n#holoStage canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:auto}#holoStatus{position:absolute;inset:16px;z-index:2;font-size:13px;color:#c5ebe9;pointer-events:none}.holo-tools{display:flex;gap:8px;flex-wrap:wrap}.holo-tools button{flex:1;padding:8px;min-width:52px}#holoPlay,#holoReset{flex:2}.use-movement{width:100%;background:#426f6588!important;border-color:#aaffef88!important}\r\n@media(max-width:480px){.glass-shell{padding:16px;gap:13px}.library-header h1{font-size:22px}.movement-cards{gap:9px}.movement-card{padding:10px}.card-title{font-size:16px}.card-kind{font-size:11px}#handState{font-size:11px}.library-launch span{max-width:135px;text-align:right}}\r\n@media(orientation:landscape) and (min-width:700px){.movement-cards{grid-template-columns:repeat(4,minmax(0,1fr))}.glass-shell{padding:18px 24px}#holoStage{min-height:280px}}\r\n@media(prefers-reduced-transparency:reduce){#library button,.movement-card{background:#182636;backdrop-filter:none}#handVideo{opacity:.1}}\r\n","menu.mjs":"// Fixed glass library with spoken proposals and a hologram before every start.\r\nimport {EXERCISES,FOCUS_GROUPS,GROUP_EXERCISES,focusFor} from './exercise-library.mjs';\r\nimport {movementSetup} from './movement-setup.mjs';\r\nimport {WORKOUT_KINDS,workoutKind,workoutChoices,workoutLevel} from './workout-levels.mjs';\r\nconst $=id=>document.getElementById(id);\r\nexport function initLibrary({movements,onOpen,onSelect,onStart,camera,movement,voice,canUse=()=>true,onLocked}){\r\n const dialog=$('library');let hands=null,viewer=null,viewerGeneration=0,handGeneration=0,introGeneration=0,introTimer=null,resolveWait=null,introducing=false,selected='squat',page=0,filter='legs',kind='reps';\r\n const kindLabel=document.createElement('label');kindLabel.className='library-kind';kindLabel.textContent='Training type';const kindSelect=document.createElement('select');kindSelect.id='libraryKind';for(const item of WORKOUT_KINDS){const o=document.createElement('option');o.value=item.id;o.textContent=item.name;kindSelect.append(o);}kindLabel.append(kindSelect);$('libraryFocus').closest('label').before(kindLabel);kindSelect.value=kind;kindSelect.onchange=()=>{kind=kindSelect.value;page=0;paginate();};\r\n // The setup is terminal text on the hologram glass, never a separate panel.\r\n const setupPanel=$('hologramPanel').querySelector('.holo-setup');$('holoStage').append(setupPanel);\r\n for(const g of FOCUS_GROUPS){const o=document.createElement('option');o.value=g.id;o.textContent=g.name;$('libraryFocus').append(o);}\r\n $('libraryFocus').addEventListener('change',()=>{filter=$('libraryFocus').value;page=0;paginate();});\r\n const speak=(text,options={})=>voice.say(text,options);\r\n function cancelIntro(){introGeneration++;introducing=false;clearTimeout(introTimer);resolveWait?.();resolveWait=null;voice.cancel();$('introCue').hidden=true;}\r\n function releaseViewer(){viewerGeneration++;viewer?.dispose();viewer=null;}\r\n function stopHands(message='Touch controls ready'){handGeneration++;hands?.stop();hands=null;$('toggleHands').disabled=false;$('toggleHands').textContent='Enable exercise gestures';$('toggleHands').setAttribute('aria-pressed','false');$('handState').textContent=message;$('confirmProgress').value=0;}\r\n function selection(id){if(id==='jumping')id='jumping-jack';selected=id;$('startFromLibrary').textContent='Start '+movements[id].name;for(const button of $('movementCards').querySelectorAll('[data-movement]'))button.setAttribute('aria-pressed',String(button.dataset.movement===id));}\r\n function refreshAccess(){for(const option of $('libraryFocus').options){const first=GROUP_EXERCISES[option.value]?.[0];const allowed=!!first&&canUse(first.id);option.disabled=!allowed;option.textContent=FOCUS_GROUPS.find(group=>group.id===option.value)?.name+(allowed?'':' · locked');}for(const button of $('movementCards').querySelectorAll('[data-movement]')){const allowed=canUse(button.dataset.movement);button.disabled=!allowed;button.setAttribute('aria-disabled',String(!allowed));}if(!GROUP_EXERCISES[filter]?.some(exercise=>canUse(exercise.id))){const first=FOCUS_GROUPS.find(group=>GROUP_EXERCISES[group.id]?.some(exercise=>canUse(exercise.id)));if(first){filter=first.id;$('libraryFocus').value=filter;page=0;}}paginate();}\r\n function home(){delete dialog.dataset.workoutBegin;dialog.dataset.preview='false';filter=focusFor(selected);kind=workoutKind(selected);kindSelect.value=kind;$('libraryFocus').value=filter;page=Math.max(0,Math.floor(workoutChoices(filter,kind).findIndex(m=>m.id===selected)/4));paginate();cancelIntro();releaseViewer();$('movementCards').hidden=false;$('startFromLibrary').hidden=true;$('hologramPanel').hidden=true;$('gestureArea').hidden=false;dialog.scrollTop=0;if(dialog.open)$('movementCards').querySelector(`[data-movement=\"${selected}\"]`)?.focus();}\r\n for(const [id,m] of Object.entries(EXERCISES)){\r\n  const card=document.createElement('article');card.className='movement-card';card.dataset.group=focusFor(id);card.dataset.kind=workoutKind(id);const level=workoutLevel(id);card.dataset.difficulty=level.difficulty;\r\n  const button=document.createElement('button');button.className='card-select';button.dataset.movement=id;button.setAttribute('aria-pressed','false');\r\n  button.setAttribute('aria-label',`${level.label} ${m.name}, ${level.kind}`);button.title=m.name;\r\n  const poster=document.createElement('img');poster.src=`/models/previews/${id}.png`;poster.alt='';poster.width=512;poster.height=512;poster.loading='lazy';poster.decoding='async';button.append(poster);\r\n  const title=document.createElement('strong');title.className='movement-level';title.textContent=`${level.label} \\u00b7 ${m.name}`;button.append(title);button.addEventListener('click',()=>{cancelIntro();showModel(id);});card.append(button);$('movementCards').append(card);\r\n }\r\n function paginate(){const cards=[...$('movementCards').children].filter(c=>c.dataset.group===filter&&c.dataset.kind===kind&&canUse(c.querySelector('[data-movement]').dataset.movement));const pages=Math.max(1,Math.ceil(cards.length/4));page=Math.max(0,Math.min(page,pages-1));for(const card of $('movementCards').children)card.hidden=true;cards.slice(page*4,page*4+4).forEach(c=>c.hidden=false);$('pageNumber').textContent=(page+1)+' / '+pages;$('previousPage').disabled=page===0;$('nextPage').disabled=page===pages-1;$('libraryPages').hidden=pages===1;let empty=document.getElementById('libraryEmpty');if(!empty){empty=document.createElement('p');empty.id='libraryEmpty';empty.setAttribute('role','status');$('movementCards').after(empty);}empty.textContent=`No available ${WORKOUT_KINDS.find(k=>k.id===kind).name.toLowerCase()} in this focus. Choose another focus or unlock this path.`;empty.hidden=cards.length>0;}\r\n $('previousPage').addEventListener('click',()=>{page--;paginate();});$('nextPage').addEventListener('click',()=>{page++;paginate();});\r\n $('libraryFocus').value=filter;paginate();\r\n async function showModel(id){\r\n  if(id==='jumping')id='jumping-jack';\r\n  if(!canUse(id))return false;\r\n  const setup=movementSetup(EXERCISES[id]);\r\n  $('holoCameraPosition').textContent=setup.position;$('holoCameraPlacement').textContent=setup.placement;\r\n  $('holoFrameNote').textContent=setup.framing;\r\n  $('holoVisibleJoints').replaceChildren(...setup.joints.map(name=>{const li=document.createElement('li');li.textContent=name;return li;}));\r\n  $('holoStage').setAttribute('aria-label',`${movements[id].name} example. Camera: ${setup.position}. ${setup.placement}. Keep ${setup.joints.join(', ')} visible. ${setup.framing}. Drag to rotate.`);\r\n  dialog.dataset.preview='true';stopHands();releaseViewer();const run=viewerGeneration;selection(id);onSelect(id);$('movementCards').hidden=true;$('libraryPages').hidden=true;$('startFromLibrary').hidden=true;$('gestureArea').hidden=true;$('hologramPanel').hidden=false;$('holoName').textContent=`${workoutLevel(id).label} \\u00b7 ${movements[id].name}`;$('holoStatus').hidden=false;$('holoStatus').textContent='Loading hologram…';$('holoPlay').textContent='Pause animation';$('useHologram').disabled=false;$('useHologram').textContent='Begin';dialog.scrollTop=0;\r\n  $('backLibrary').focus();\r\n  try{const {createHologram}=await import('./hologram.mjs');if(run!==viewerGeneration||!dialog.open)return false;\r\n   const instance=await createHologram($('holoStage'),id);if(run!==viewerGeneration||!dialog.open){instance.dispose();return false;}viewer=instance;$('holoStatus').hidden=true;$('useHologram').disabled=false;return true;\r\n  }catch(error){if(run===viewerGeneration){$('holoStatus').textContent='Hologram could not load. '+error.message;$('useHologram').textContent='Begin';$('useHologram').disabled=false;}return false;}\r\n }\r\n function begin(){if(!canUse(selected))return;cancelIntro();stopHands();releaseViewer();dialog.dataset.workoutBegin='true';dialog.close();onStart();}\r\n async function introduce(id=movement()){\r\n  if(id==='jumping')id='jumping-jack';\r\n  if(!canUse(id))return false;\r\n  void import('./modules/vault/vault-store.mjs').then(m=>m.bump('library-open',1,{key:id})).catch(()=>{});onOpen();cancelIntro();stopHands();selection(id);onSelect(id);if(!dialog.open)dialog.showModal();introducing=true;\r\n  await showModel(id);\r\n }\r\n function gesture(event){\r\n  $('confirmProgress').value=event.progress;\r\n  if(event.mode&&['proposed','holding','pending','confirmed'].includes(event.event)&&!canUse(event.mode)){\r\n   const message='That workout path is locked. Choose one of your available paths.';\r\n   if(event.event==='confirmed')stopHands(message);else $('handState').textContent=message;\r\n   return;\r\n  }\r\n  if(event.event==='proposed'){selection(event.mode);$('handState').textContent=movements[event.mode].name+'? Hold thumbs up to confirm.';}\r\n  else if(event.event==='holding')$('handState').textContent=`Hold thumbs up… ${Math.round(event.progress*100)}%`;\r\n  else if(event.event==='pending')$('handState').textContent=movements[event.mode].name+'? Hold thumbs up for a moment.';\r\n  else if(event.event==='confirmed'){stopHands();introduce(event.mode);}\r\n  else if(event.event==='expired'){$('handState').textContent='Selection expired. Make another gesture.';speak('Selection cancelled. Make another gesture.',{interrupt:true});}\r\n  else if(event.event==='idle')$('handState').textContent='Make an exercise gesture.';\r\n }\r\n $('toggleHands').addEventListener('click',async()=>{\r\n  if(hands){stopHands();speak('Exercise gestures off.',{interrupt:true});return;}\r\n  const run=++handGeneration;$('toggleHands').disabled=true;$('handState').textContent='Opening exercise gestures…';speak('Exercise gestures. Show your gesture, then hold thumbs up to confirm.',{interrupt:true});\r\n  try{const {HandControl}=await import('./gesture-controls.mjs');if(run!==handGeneration||!dialog.open)return;\r\n   const control=new HandControl({video:$('handVideo'),camera:camera(),message:text=>$('handState').textContent=text,onGesture:gesture,onError:text=>stopHands(text)});hands=control;await control.start();\r\n   if(run!==handGeneration||!dialog.open){control.stop();return;}$('toggleHands').disabled=false;$('toggleHands').textContent='Disable exercise gestures';$('toggleHands').setAttribute('aria-pressed','true');\r\n  }catch(error){if(run===handGeneration){stopHands(error.message);speak('Gesture tracking unavailable. Touch controls are ready.',{interrupt:true});}}\r\n });\r\n $('openLibrary').addEventListener('click',()=>{onOpen();const current=movement(),first=Object.keys(EXERCISES).find(id=>canUse(id));if(!first){onLocked?.();return;}selection(canUse(current)?current:first);home();refreshAccess();dialog.showModal();speak('Choose your movement.',{interrupt:true});});\r\n $('startFromLibrary').addEventListener('click',()=>introduce(selected));\r\n $('closeLibrary').addEventListener('click',()=>{cancelIntro();dialog.close();speak('Library closed.',{interrupt:true});});\r\n $('backLibrary').addEventListener('click',()=>{home();speak('Movement library.',{interrupt:true});});\r\n $('useHologram').addEventListener('click',()=>begin());\r\n $('holoReset').addEventListener('click',()=>{viewer?.reset();if(!introducing)speak('View reset.');}); $('holoPlay').addEventListener('click',()=>{if(viewer){if(introducing)cancelIntro();const playing=viewer.toggle();$('holoPlay').textContent=playing?'Pause animation':'Play animation';$('useHologram').textContent='Begin';speak(playing?'Example playing.':'Example paused.');}});\r\n dialog.addEventListener('cancel',cancelIntro);\r\n dialog.addEventListener('close',()=>{stopHands();releaseViewer();$('openLibrary').focus();});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden&&dialog.open){cancelIntro();stopHands('Gestures paused');releaseViewer();home();}});\r\n window.addEventListener('pagehide',()=>{cancelIntro();stopHands();releaseViewer();});\r\n window.addEventListener('myr5:performance-progress',refreshAccess);window.addEventListener('myr5:account-ready',refreshAccess);refreshAccess();\r\n return {introduce,refreshAccess};\r\n}\r\n","modules/coach-world/art/manifest.json":"{\n  \"version\": 1,\n  \"size\": 64,\n  \"kinds\": [\n    \"hq\",\n    \"hall\",\n    \"building\",\n    \"ship\",\n    \"resource\",\n    \"shop\",\n    \"node\",\n    \"rubble\",\n    \"crew\",\n    \"production\",\n    \"expedition\",\n    \"foundation\",\n    \"drop\"\n  ],\n  \"variants\": 5,\n  \"factions\": {\n    \"chest\": {\n      \"motif\": \"Faceted wedge crowns\",\n      \"shape\": \"wedge\",\n      \"material\": \"beveled ceramic armor\",\n      \"rule\": \"Crest and diamond planes over broad shoulders and a narrow waist.\",\n      \"png\": \"chest.png\",\n      \"source\": \"chest.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"quads\": {\n      \"motif\": \"Stacked oval pylons\",\n      \"shape\": \"pylon\",\n      \"material\": \"segmented load-bearing stone\",\n      \"rule\": \"Egg-shaped drums taper upward from paired broad foundations.\",\n      \"png\": \"quads.png\",\n      \"source\": \"quads.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"glutes\": {\n      \"motif\": \"Pearl pod vaults\",\n      \"shape\": \"pod\",\n      \"material\": \"rounded living pearl\",\n      \"rule\": \"Stacked positive-volume spheres, bubble joints and a heavy lower core.\",\n      \"png\": \"glutes.png\",\n      \"source\": \"glutes.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"arms-shoulders\": {\n      \"motif\": \"Branching canopy foundries\",\n      \"shape\": \"canopy\",\n      \"material\": \"ribbed shell and mechanical branches\",\n      \"rule\": \"One shoulder canopy carries paired radial arms.\",\n      \"png\": \"arms-shoulders.png\",\n      \"source\": \"arms-shoulders.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"yoga\": {\n      \"motif\": \"Suspended curl sanctuaries\",\n      \"shape\": \"curl\",\n      \"material\": \"flowing translucent ceramic\",\n      \"rule\": \"Unplanted S stems and hooked ribbon tips float above their foundations.\",\n      \"png\": \"yoga.png\",\n      \"source\": \"yoga.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"martial-arts\": {\n      \"motif\": \"Folded plate bastions\",\n      \"shape\": \"fan\",\n      \"material\": \"creased armored plates\",\n      \"rule\": \"Blunt monoliths unfold into ribbed fan helmets on compact braced feet.\",\n      \"png\": \"martial-arts.png\",\n      \"source\": \"martial-arts.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    },\n    \"cardio\": {\n      \"motif\": \"Open-core relay towers\",\n      \"shape\": \"ring\",\n      \"material\": \"light skeletal alloy\",\n      \"rule\": \"Negative-space rings, suspended discs and lean open struts.\",\n      \"png\": \"cardio.png\",\n      \"source\": \"cardio.piskel\",\n      \"frames\": [\n        {\n          \"kind\": \"hq\",\n          \"variant\": 0,\n          \"frame\": [\n            0,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 0,\n          \"frame\": [\n            64,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 0,\n          \"frame\": [\n            128,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 0,\n          \"frame\": [\n            192,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 0,\n          \"frame\": [\n            256,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 0,\n          \"frame\": [\n            320,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 0,\n          \"frame\": [\n            384,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 0,\n          \"frame\": [\n            448,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 0,\n          \"frame\": [\n            512,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 0,\n          \"frame\": [\n            576,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 0,\n          \"frame\": [\n            640,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 0,\n          \"frame\": [\n            704,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 0,\n          \"frame\": [\n            768,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 1,\n          \"frame\": [\n            832,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 1,\n          \"frame\": [\n            896,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 1,\n          \"frame\": [\n            960,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 1,\n          \"frame\": [\n            1024,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 1,\n          \"frame\": [\n            1088,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 1,\n          \"frame\": [\n            1152,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 1,\n          \"frame\": [\n            1216,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 1,\n          \"frame\": [\n            1280,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 1,\n          \"frame\": [\n            1344,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 1,\n          \"frame\": [\n            1408,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 1,\n          \"frame\": [\n            1472,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 1,\n          \"frame\": [\n            1536,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 1,\n          \"frame\": [\n            1600,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 2,\n          \"frame\": [\n            1664,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 2,\n          \"frame\": [\n            1728,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 2,\n          \"frame\": [\n            1792,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 2,\n          \"frame\": [\n            1856,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 2,\n          \"frame\": [\n            1920,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 2,\n          \"frame\": [\n            1984,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 2,\n          \"frame\": [\n            2048,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 2,\n          \"frame\": [\n            2112,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 2,\n          \"frame\": [\n            2176,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 2,\n          \"frame\": [\n            2240,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 2,\n          \"frame\": [\n            2304,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 2,\n          \"frame\": [\n            2368,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 2,\n          \"frame\": [\n            2432,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 3,\n          \"frame\": [\n            2496,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 3,\n          \"frame\": [\n            2560,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 3,\n          \"frame\": [\n            2624,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 3,\n          \"frame\": [\n            2688,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 3,\n          \"frame\": [\n            2752,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 3,\n          \"frame\": [\n            2816,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 3,\n          \"frame\": [\n            2880,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 3,\n          \"frame\": [\n            2944,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 3,\n          \"frame\": [\n            3008,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 3,\n          \"frame\": [\n            3072,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 3,\n          \"frame\": [\n            3136,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 3,\n          \"frame\": [\n            3200,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 3,\n          \"frame\": [\n            3264,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hq\",\n          \"variant\": 4,\n          \"frame\": [\n            3328,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"hall\",\n          \"variant\": 4,\n          \"frame\": [\n            3392,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"building\",\n          \"variant\": 4,\n          \"frame\": [\n            3456,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"ship\",\n          \"variant\": 4,\n          \"frame\": [\n            3520,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"resource\",\n          \"variant\": 4,\n          \"frame\": [\n            3584,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"shop\",\n          \"variant\": 4,\n          \"frame\": [\n            3648,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"node\",\n          \"variant\": 4,\n          \"frame\": [\n            3712,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"rubble\",\n          \"variant\": 4,\n          \"frame\": [\n            3776,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"crew\",\n          \"variant\": 4,\n          \"frame\": [\n            3840,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"production\",\n          \"variant\": 4,\n          \"frame\": [\n            3904,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"expedition\",\n          \"variant\": 4,\n          \"frame\": [\n            3968,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"foundation\",\n          \"variant\": 4,\n          \"frame\": [\n            4032,\n            0,\n            64,\n            64\n          ]\n        },\n        {\n          \"kind\": \"drop\",\n          \"variant\": 4,\n          \"frame\": [\n            4096,\n            0,\n            64,\n            64\n          ]\n        }\n      ]\n    }\n  }\n}\n","modules/coach-world/authorized-friends.mjs":"// Ephemeral permission-scoped rendering input. No storage or public-map cache.\nimport {distanceMeters,validCoordinate} from './geo.mjs';\nimport {localOffset} from './public-geography.mjs';\nimport {FACTION_BY_ID} from './catalog.mjs';\nexport function authorizedFriendLandmarks(friends,anchor){\n if(!anchor||!validCoordinate(anchor.latitude,anchor.longitude))return [];\n const result=[];for(const friend of Array.isArray(friends)?friends:[]){const h=friend?.home;if(!h||h.consent!==true||!validCoordinate(h.latitude,h.longitude)||typeof friend.publicId!=='string'||!friend.base||!Object.hasOwn(FACTION_BY_ID,friend.base.faction)||distanceMeters(anchor,h)>2000)continue;const levels=Object.values(friend.base.buildings||{}).map(b=>b?.level).filter(l=>Number.isInteger(l)&&l>=1&&l<=10);result.push({...localOffset(anchor,h.longitude,h.latitude),faction:friend.base.faction,level:Math.max(1,...levels)});if(result.length===8)break;}return result;\n}\n","modules/coach-world/camera-view.mjs":"import {BUILDINGS,FACTIONS,FACTION_BY_ID} from './catalog.mjs';\r\nimport {claimGraphics,releaseGraphics} from '../graphics-lifecycle.mjs';\r\nimport {captureWorldPhoto,showPhotoPreview} from './photo.mjs';\r\nimport {readPublicGeography,cityMasses,localOffset} from './public-geography.mjs';\r\nimport {createTerrain,drawTerrain} from './terrain.mjs';\r\nimport {distanceMeters} from './geo.mjs';\r\nimport {authorizedFriendLandmarks} from './authorized-friends.mjs';\r\nimport {createPixelBillboards,disposePixelObject,fitPixelRenderer} from './sprite-billboards.mjs';\r\n\r\nexport function mountCameraView(host,{getBase,signal,loadFriends=async()=>({friends:[]})}){\r\n const local=new AbortController();let disposed=false,renderer,scene,camera,claim,raf=0,stream,spin=0,three,photoDispose,cityMode=false,cityGroup=null,cityVersion=null,baseObjects=[],friendLayer=null,friendGeneration=0,friendTimer=0;\r\n host.innerHTML='<div class=\"cw-camera-stage\"><video muted playsinline></video><canvas aria-label=\"Virtual alien base\"></canvas><span class=\"cw-camera-label\">Virtual base · manual orbit</span></div><p class=\"cw-note\">Your permanent base as layered pixel sprites in 3D space. Camera overlay is approximate; this view is not a mapped city or a shared geographic anchor.</p><div class=\"cw-actions\"><button data-camera>Enable rear camera</button><button data-recenter>Recenter</button><button data-photo disabled>Take photo</button></div><p data-status role=\"status\">Loading virtual base…</p>';\r\n const modeNote=host.querySelector('.cw-note');const video=host.querySelector('video'),canvas=host.querySelector('canvas'),status=host.querySelector('[data-status]'),label=host.querySelector('.cw-camera-label');const alive=()=>!disposed&&!signal?.aborted;\r\n const friendStatus=document.createElement('p');friendStatus.className='cw-note';friendStatus.dataset.authorizedLandmarks='0';host.append(friendStatus);\r\n function clearFriends(){friendGeneration++;if(friendLayer){scene?.remove(friendLayer);disposePixelObject(friendLayer);friendLayer=null;}friendStatus.dataset.authorizedLandmarks='0';friendStatus.textContent='';}\r\n function stopFriends(){clearInterval(friendTimer);friendTimer=0;clearFriends();}\r\n async function refreshFriends(){clearFriends();const generation=friendGeneration;if(!alive()||!cityMode||!renderer||document.hidden)return;try{const origin=readPublicGeography()?.anchor;const snapshot=await loadFriends(origin);if(!alive()||!cityMode||generation!==friendGeneration||document.hidden)return;const geography=readPublicGeography();if(!geography)return;const landmarks=authorizedFriendLandmarks(snapshot.friends,geography.anchor),T=three,layer=createPixelBillboards(T),group=layer.group,skyHeight=Math.max(60,...geography.buildings.map(b=>b.height));group.name='authorized-friend-landmarks';for(const landmark of landmarks){const height=Math.min(260,skyHeight+35+landmark.level*3),variant=Math.max(0,Math.min(4,landmark.level-1));layer.add({faction:landmark.faction,kind:'hq',variant,x:landmark.x,z:landmark.z,height});for(const side of [-1,1])layer.add({faction:landmark.faction,kind:'hall',variant,x:landmark.x+side*height*.3,z:landmark.z+3,height:height*.55});}friendLayer=group;scene.add(group);friendStatus.dataset.authorizedLandmarks=String(landmarks.length);friendStatus.textContent=landmarks.length?`${landmarks.length} nearby friend landmarks above the fog. Only explicitly shared home locations are rendered; permissions refresh every 15 seconds.`:'No nearby friends with explicit home-location sharing. Appearance-only connections stay in the fog.';}catch(e){if(alive()&&cityMode&&generation===friendGeneration)friendStatus.textContent='Friend landmarks hidden until permissions can be checked again.';}}\r\n function startFriends(){clearInterval(friendTimer);void refreshFriends();friendTimer=setInterval(()=>void refreshFriends(),15000);}\r\n const modes=document.createElement('div');modes.className='cw-actions';const virtual=document.createElement('button');virtual.textContent='Virtual base';const mapped=document.createElement('button');mapped.textContent='Mapped city skyline';mapped.disabled=!readPublicGeography();modes.append(virtual,mapped);host.prepend(modes);\r\n virtual.onclick=()=>{cityMode=false;modeNote.textContent='Your permanent base as layered pixel sprites in 3D space. Camera overlay placement is approximate, with manual orbit and recenter.';stopFriends();cityGroup&&(cityGroup.visible=false);baseObjects.forEach(o=>o.visible=true);if(scene)scene.fog=new three.FogExp2(0x25333c,.022);label.textContent=stream?'Camera overlay · approximate placement':'Virtual base · manual orbit';};\r\n mapped.onclick=()=>{if(!renderer)return;const geography=readPublicGeography();if(!geography){status.textContent='Open Sectors and prepare actual mapped building geometry first.';return;}const T=three;\r\n  if(cityGroup&&cityVersion!==geography.captureId){disposePixelObject(cityGroup);cityGroup=null;}\r\n  if(!cityGroup){cityVersion=geography.captureId;const layer=createPixelBillboards(T),masses=cityMasses(geography);cityGroup=layer.group;cityGroup.name='public-pixel-skyline';\r\n   let index=0;for(const b of [...masses.near].sort((a,c)=>a.distance-c.distance).slice(0,100)){const x=b.points.reduce((n,p)=>n+p.x,0)/b.points.length,z=b.points.reduce((n,p)=>n+p.z,0)/b.points.length,height=Math.max(45,Math.min(220,b.height*2+30)),faction=FACTION_BY_ID[b.faction]?b.faction:'chest',variant=Math.min(3,Math.floor(b.height/35)),damaged=b.phase!=='stable';layer.add({faction,kind:'building',variant,x,z,height,tint:damaged?b.phase==='healing'?0xd9d2bd:0xaaa19c:0xffffff});if(damaged)layer.add({faction,kind:'rubble',variant:0,x:x+height*.25,z:z+2,height:height*.4});else if(index%8===0)layer.add({faction,kind:'resource',variant:0,x:x+height*.35,z:z+2,height:Math.max(5,height*.25)});index++;}\r\n   for(const mass of masses.far.slice(0,48))layer.add({faction:FACTION_BY_ID[mass.faction]?mass.faction:'chest',kind:'building',variant:0,x:mass.x,z:mass.z,height:Math.max(70,mass.height*2+30),opacity:.72,tint:0x9aa8a4});\r\n   let publicProps=0;for(const node of geography.nodes||[]){const latitude=node.latitude??node.lat,longitude=node.longitude??node.lng;if(!Number.isFinite(latitude)||!Number.isFinite(longitude)||distanceMeters(geography.anchor,{latitude,longitude})>2000)continue;const {x,z}=localOffset(geography.anchor,longitude,latitude),kind=node.type==='public-hub'?'shop':node.type==='public-node'?'node':'resource';layer.add({faction:kind==='resource'&&node.faction==='neutral'?'neutral':FACTION_BY_ID[node.faction]?node.faction:'chest',kind,variant:0,x,z,height:kind==='shop'?38:kind==='node'?24:12,tint:node.phase==='stable'?0xffffff:0xc0b8a7});if(++publicProps>=40)break;}\r\n   for(const y of [1,4,8]){const fog=new T.Mesh(new T.PlaneGeometry(4200,4200),new T.MeshBasicMaterial({color:0xa2b3b0,transparent:true,opacity:.1,depthWrite:false,side:T.DoubleSide}));fog.rotation.x=-Math.PI/2;fog.position.y=y;cityGroup.add(fog);}scene.add(cityGroup);\r\n  }cityMode=true;modeNote.textContent='Existing mapped city positions and heights restyled with workout pixel sprites. Camera placement is approximate and manually aligned; this is not shared geographic tracking.';startFriends();cityGroup.visible=true;baseObjects.forEach(o=>o.visible=false);scene.fog=new T.FogExp2(0x8b9c9c,.0007);label.textContent='Mapped skyline / approximate manual view';status.textContent=`${geography.buildings.length} existing mapped building footprints. ${geography.attribution}. ${geography.preview?'Seeded initial territory preview.':'Architecture follows the latest public territory snapshot.'} Background buildings follow their nearest public sector; this art does not claim private land. War-torn ground heals gradually. Anonymous masses merge beyond 914 m. Camera placement is manual, not VPS.`;};\r\n const stopCamera=()=>{stream?.getTracks().forEach(t=>t.stop());stream=null;video.srcObject=null;};\r\n async function init(){try{claim=claimGraphics('coach-world');await claim.ready;if(!alive()){claim();return;}three=await import('/vendor/three/three.module.js');if(!alive()){claim();return;}\r\n  const T=three;renderer=new T.WebGLRenderer({canvas,alpha:true,antialias:false,preserveDrawingBuffer:true});renderer.setPixelRatio(1);scene=new T.Scene();scene.fog=new T.FogExp2(0x25333c,.022);camera=new T.PerspectiveCamera(45,1,.1,7000);\r\n  const base=getBase(),layer=createPixelBillboards(T),terrainCanvas=document.createElement('canvas');terrainCanvas.width=terrainCanvas.height=768;drawTerrain(terrainCanvas.getContext('2d'),createTerrain(base),{unit:32,ox:0,oy:0});const terrainTexture=new T.CanvasTexture(terrainCanvas);terrainTexture.magFilter=terrainTexture.minFilter=T.NearestFilter;terrainTexture.generateMipmaps=false;terrainTexture.colorSpace=T.SRGBColorSpace;const ground=new T.Mesh(new T.PlaneGeometry(24,24),new T.MeshBasicMaterial({map:terrainTexture,toneMapped:false}));ground.rotation.x=-Math.PI/2;ground.position.set(2,-.1,2);scene.add(ground);\r\n  for(const def of BUILDINGS){const b={...def,...base.buildings[def.id]},faction=FACTION_BY_ID[b.track]?b.track:base.faction,x=b.x-10,z=b.y-10,height=b.level===0?1.6:3+b.level*.25;layer.add({faction,kind:b.level===0?'foundation':['hq','hall','production','expedition'].includes(def.kind)?def.kind:'building',variant:Math.max(0,Math.min(4,(b.level??1)-1)),x,z,height});if(b.job)layer.add({faction,kind:'resource',variant:0,x:x+1.2,z:z+.3,height:1.2});}\r\n  for(let i=0;i<5;i++)layer.add({faction:base.faction,kind:'crew',variant:0,x:-7+i*3,z:1+(i%2),height:1.15});const hull=base.ships?.[base.selectedShip]||{tier:0};layer.add({faction:base.faction,kind:'ship',variant:Math.min(4,hull.tier||0),x:4,y:5,z:3,height:1.6+(hull.tier||0)*.6});layer.add({faction:base.faction,kind:'resource',variant:0,x:-6,z:4,height:1.4});scene.add(layer.group);\r\n  const fog=new T.Mesh(new T.PlaneGeometry(34,34),new T.MeshBasicMaterial({color:0x91a6ac,transparent:true,opacity:.13,depthWrite:false,side:T.DoubleSide}));fog.rotation.x=-Math.PI/2;fog.position.y=.2;scene.add(fog);\r\n  baseObjects=[...scene.children];const resize=()=>{if(alive()&&renderer)return fitPixelRenderer(renderer,camera,canvas.parentElement,2);},observer=new ResizeObserver(resize);observer.observe(canvas.parentElement);local.signal.addEventListener('abort',()=>observer.disconnect(),{once:true});resize();\r\n  let lastFrame=0;const frame=t=>{if(!alive())return;raf=requestAnimationFrame(frame);if(document.hidden||t-lastFrame<33)return;lastFrame=t;const distance=cityMode?350:26;camera.position.set(Math.sin(spin)*distance,cityMode?160:22,Math.cos(spin)*distance);camera.lookAt(0,cityMode?25:0,0);renderer.render(scene,camera);};frame(0);status.textContent=readPublicGeography()?'Virtual base ready. Mapped city geometry is also available above.':'Virtual base ready. Prepare actual mapped buildings in Sectors to unlock Mapped city skyline.';host.querySelector('[data-photo]').disabled=false;\r\n }catch(e){console.warn('Coach World 3D unavailable:',e);if(alive()){status.textContent='3D could not start on this device. Your complete pixel base is available in Base.';}await disposeGraphics();}}\r\n let dragging=null;canvas.addEventListener('pointerdown',e=>{dragging=e.clientX;canvas.setPointerCapture(e.pointerId);},{signal:local.signal});canvas.addEventListener('pointermove',e=>{if(dragging==null)return;spin+=(e.clientX-dragging)*.01;dragging=e.clientX;},{signal:local.signal});canvas.addEventListener('pointerup',()=>dragging=null,{signal:local.signal});canvas.addEventListener('pointercancel',()=>dragging=null,{signal:local.signal});\r\n host.querySelector('[data-recenter]').onclick=()=>{spin=0;};\r\n host.querySelector('[data-camera]').onclick=async()=>{stopCamera();if(!navigator.mediaDevices?.getUserMedia){status.textContent='Camera unavailable. Continue with the virtual base.';return;}status.textContent='Waiting for camera permission…';try{const next=await navigator.mediaDevices.getUserMedia({audio:false,video:{facingMode:{ideal:'environment'}}});if(!alive()){next.getTracks().forEach(t=>t.stop());return;}stream=next;video.srcObject=stream;await video.play();if(!alive()){stopCamera();return;}label.textContent='Camera overlay · approximate placement';status.textContent='Camera active. Manual orbit and Recenter control placement.';}catch(e){stopCamera();if(alive())status.textContent='Camera permission denied or camera busy. Virtual base remains available.';}};\r\n host.querySelector('[data-photo]').onclick=async()=>{try{const blob=await captureWorldPhoto({video,overlay:canvas,alive});if(alive()){photoDispose?.();photoDispose=showPhotoPreview(blob,host,{signal:local.signal});}}catch(e){if(alive())status.textContent=e.message;}};\r\n async function disposeGraphics(){cancelAnimationFrame(raf);if(renderer){const r=renderer;renderer=null;disposePixelObject(scene);await releaseGraphics(canvas,r.getContext(),()=>{r.dispose();r.forceContextLoss();});}claim?.();claim=null;}\r\n function dispose(){if(disposed)return;disposed=true;stopFriends();stopCamera();photoDispose?.();local.abort();void disposeGraphics();}signal?.addEventListener('abort',dispose,{once:true});globalThis.addEventListener('pagehide',dispose,{signal:local.signal});document.addEventListener('visibilitychange',()=>{if(document.hidden){stopFriends();stopCamera();label.textContent=cityMode?'Mapped skyline / camera paused':'Virtual base / camera paused';status.textContent='Camera paused while the app was hidden. Enable rear camera to resume.';}},{signal:local.signal});void init();return {dispose};\r\n}\r\n","modules/coach-world/canvas-scene.mjs":"import {BUILDINGS,FACTIONS,FACTION_BY_ID,MAX_LEVEL} from './catalog.mjs';\r\nimport {createWanderers,stepWanderers,occupancy,findPath} from './navigation.mjs';\r\nimport {BASIC_WORKER,SECTION_COMPANIONS,UNIT_BY_ID} from './unit-catalog.mjs';\r\nimport {unitRoster} from './expedition-catalog.mjs';\r\nimport {getSpriteCanvas} from './pixel-art.mjs';\r\nimport {createTerrain,drawTerrain} from './terrain.mjs';\r\nimport {createTouchGesture,unitsInRectangle,rallyUnits,stepRalliedUnits} from './touchselection.mjs';\r\nconst clamp=(v,a,b)=>Math.min(b,Math.max(a,v));\r\nexport function drawBuilding(ctx,b,f,x,y,size,{selected=false}={}){\r\n const level=Number.isInteger(b.level)?b.level:1,w=size*(b.w||3),h=size*(b.h||3),pixels=w<48?32:64*Math.max(1,Math.round(w/64)),left=Math.round(x+w/2-pixels/2),top=Math.round(y+h-pixels),kind=level===0?'foundation':['hq','hall','production','expedition'].includes(b.kind)?b.kind:b.kind==='care'?'shop':'building';\r\n ctx.imageSmoothingEnabled=false;ctx.drawImage(getSpriteCanvas(f.id,kind,Math.max(0,Math.min(4,level-1))),left,top,pixels,pixels);\r\n if(b.job){ctx.fillStyle='#eab46f';for(let i=0;i<5;i++)ctx.fillRect(left+3+i*(pixels-6)/5,top+pixels-4,3,2);}\r\n if(selected){ctx.strokeStyle='#fff4b8';ctx.lineWidth=1;ctx.strokeRect(left-2,top-2,pixels+4,pixels+4);}\r\n ctx.font='bold 8px monospace';const label=level===0?'SITE':`${level}/${MAX_LEVEL}`,width=ctx.measureText(label).width+6;ctx.fillStyle='#09171ee8';ctx.fillRect(Math.round(x+w/2-width/2),Math.round(y+h-3),width,11);ctx.fillStyle=level===0?'#b7c8c5':f.accent;ctx.textAlign='center';ctx.fillText(label,Math.round(x+w/2),Math.round(y+h+5));ctx.textAlign='start';\r\n}\r\nexport function constructionCountdown(dueAt,now=Date.now()){if(!Number.isFinite(dueAt)||!Number.isFinite(now))return '';const seconds=Math.max(0,Math.ceil((dueAt-now)/1000));if(!seconds)return 'Ready to finish';return `${Math.floor(seconds/60)}m ${String(seconds%60).padStart(2,'0')}s`;}\r\nexport function sceneUnitDefinitions(input={}){const base=input.buildings?input:{coachAccess:input.coaches||[],buildings:Object.fromEntries(FACTIONS.map(f=>[`hall-${f.id}`,{level:5}]))},basics=FACTIONS.map(f=>({...BASIC_WORKER,section:f.id})),companions=FACTIONS.flatMap(f=>SECTION_COMPANIONS[f.id]||[]),coaches=unitRoster(base).filter(u=>u.owned&&['grunt','boss'].includes(u.role)).map(u=>UNIT_BY_ID[u.visualId]).filter(Boolean);return [...basics,...companions,...coaches];}\r\nexport function isSceneUnitAway(unit,base){const m=base.expedition;if(!m||!['launched','returning'].includes(m.status))return false;if(unit.role==='worker')return unit.section===m.factionId&&m.unitIds.includes('myr5-worker');const id=unit.role==='scout'?`companion-${unit.section}-scout`:unit.role==='carrier'?`companion-${unit.section}-hauler`:['boss','grunt'].includes(unit.role)?`${unit.role}-${unit.section}`:null;return !!id&&m.unitIds.includes(id);}\r\nexport function mountBaseScene(canvas,{getBase,onSelect=()=>{},onEnterWarRoom=()=>{},onSelectionChange=()=>{},onRally=()=>{},getServerTime=()=>Date.now()}){\r\n const ctx=canvas.getContext('2d'),pointers=new Map(),abort=new AbortController(),definitions=sceneUnitDefinitions(getBase()||{}),crew=createWanderers(definitions.length),selectedUnits=new Set(),atlases=new Map(),images=[];\r\n let raf=0,disposed=false,last=0,scale=1,pan={x:0,y:0},pinch=0,selected='hq',transition=null,entryFinished=false,terrain=null,terrainKey='',initialized=false,selectionArmed=false;\r\n const notify=()=>onSelectionChange({count:selectedUnits.size,ids:[...selectedUnits],units:crew.filter(u=>!u.away&&selectedUnits.has(u.id)).map(u=>({...u.definition,instanceId:u.id})),selectionMode:selectionArmed});\r\n const gesture=createTouchGesture({onHold:()=>{try{navigator.vibrate?.(12);}catch{}canvas.dataset.troopGesture='select';}});\r\n for(const path of new Set(definitions.map(u=>u.atlasPath))){const image=new Image();images.push(image);image.onload=()=>{if(!disposed)atlases.set(path,image);};image.src=path;}\r\n const box=()=>canvas.getBoundingClientRect();\r\n function transform(){const r=box(),unit=Math.min(r.width/26,r.height/25)*scale,normal={unit,ox:r.width/2-12*unit+pan.x,oy:r.height/2-11*unit+pan.y};if(!transition)return normal;const progress=clamp((performance.now()-transition.started)/450,0,1),ease=1-(1-progress)**3,targetUnit=transition.from.unit*3,hq=getBase()?.buildings?.hq||{x:10,y:9},target={unit:targetUnit,ox:r.width/2-(hq.x+2)*targetUnit,oy:r.height/2-(hq.y+2)*targetUnit};return Object.fromEntries(Object.keys(normal).map(k=>[k,transition.from[k]+(target[k]-transition.from[k])*ease]));}\r\n const localPoint=e=>{const r=box();return {x:e.clientX-r.left,y:e.clientY-r.top};};\r\n function terrainFor(base){const key=`${base.seed}:${base.faction}:`+Object.values(base.buildings).map(b=>`${b.id}:${b.x}:${b.y}:${b.level}:${!!b.job}`).join('|');if(key!==terrainKey){terrain=createTerrain(base);terrainKey=key;for(const unit of crew){unit.path=[];unit.index=0;unit.rally=false;unit.hasOrder=false;}}return terrain;}\r\n function nearestFree(base,point){const blocked=occupancy(base);for(const key of terrain.blocked)blocked.add(key);let best=null,distance=Infinity;for(let y=0;y<24;y++)for(let x=0;x<24;x++)if(!blocked.has(y*24+x)){const d=Math.hypot(x-point.x,y-point.y);if(d<distance){distance=d;best={x,y};}}return best||{x:0,y:0};}\r\n function initialize(base){if(initialized)return;initialized=true;for(let i=0;i<crew.length;i++){const definition=definitions[i],hall=base.buildings[`hall-${definition.section}`],def=BUILDINGS.find(d=>d.id===`hall-${definition.section}`),point=nearestFree(base,{x:(hall?.x||2)+(def?.w||3)/2,y:(hall?.y||2)+(def?.h||3)+1});Object.assign(crew[i],point,{definition,sectionAnchor:point,role:definition.role,rally:definition.role!=='worker',hasOrder:false});}}\r\n function enterWarRoom(){if(disposed||transition||entryFinished||!getBase())return false;gesture.cancel();selected='hq';if(matchMedia('(prefers-reduced-motion: reduce)').matches){entryFinished=true;onEnterWarRoom();return true;}transition={started:performance.now(),from:transform()};canvas.dataset.enteringWarRoom='true';canvas.setAttribute('aria-busy','true');return true;}\r\n function rally(target){const base=getBase();if(!base||base.rest||!terrain||!selectedUnits.size)return 0;const count=rallyUnits(crew,selectedUnits,target,base,terrain.blocked);for(const unit of crew)if(selectedUnits.has(unit.id)&&unit.rally)unit.hasOrder=true;selectionArmed=false;notify();onRally({count,target});return count;}\r\n function patrol(base,t){for(const unit of crew){if(unit.away||unit.role==='worker'||unit.hasOrder||base.rest)continue;if(unit.path?.[unit.index])continue;if(unit.patrolWait==null){unit.patrolWait=t+1100+unit.id*37;continue;}if(t<unit.patrolWait)continue;unit.patrolWait=null;const a=unit.sectionAnchor,offset=(unit.cycle++%5)-2,target=nearestFree(base,{x:a.x+offset,y:a.y+(unit.cycle%3)-1});rallyUnits([unit],new Set([unit.id]),target,base,terrain.blocked);}}\r\n function screenUnit(unit,tr){return {id:unit.id,x:tr.ox+(unit.x+.5)*tr.unit,y:tr.oy+(unit.y+.5)*tr.unit-terrain.heightAt(unit.x,unit.y)*2};}\r\n function drawUnit(unit,tr,t,base){const point=screenUnit(unit,tr),definition=unit.definition,atlas=atlases.get(definition.atlasPath),pet=definition.sheet==='pets',height=pet?(definition.role==='carrier'?16:13):definition.role==='boss'?34:definition.role==='worker'?20:24,width=Math.round(height*definition.frame[2]/definition.frame[3]),bob=base.rest?0:Math.sin(unit.phase)*1.2,f=FACTION_BY_ID[definition.section]||FACTIONS[0];\r\n  ctx.fillStyle='#08121688';ctx.fillRect(Math.round(point.x-width/2),Math.round(point.y),width,3);ctx.strokeStyle=selectedUnits.has(unit.id)?'#fff0a6':f.color;ctx.lineWidth=selectedUnits.has(unit.id)?2:1;ctx.beginPath();ctx.ellipse(point.x,point.y+1,Math.max(5,width*.42),3,0,0,Math.PI*2);ctx.stroke();if(atlas){ctx.save();ctx.translate(Math.round(point.x),Math.round(point.y-height+bob));if(unit.facing==='left')ctx.scale(-1,1);ctx.drawImage(atlas,...definition.frame,-Math.round(width/2),0,width,height);ctx.restore();}else ctx.drawImage(getSpriteCanvas(f.id,'crew'),Math.round(point.x-height/2),Math.round(point.y-height),height,height);\r\n  if(unit.state==='building'){ctx.fillStyle='#ffd88b';ctx.fillRect(point.x+width/2,point.y-height+3,3,3);}if(base.rest){ctx.fillStyle='#c7d7bb';ctx.font='9px monospace';ctx.fillText('z',point.x+4,point.y-height);}if(unit.hasOrder&&unit.rallyTarget){ctx.fillStyle='#e9d58c';ctx.fillRect(tr.ox+(unit.rallyTarget.x+.5)*tr.unit-1,tr.oy+(unit.rallyTarget.y+.5)*tr.unit-1,3,3);}\r\n }\r\n function draw(t){if(disposed)return;raf=requestAnimationFrame(draw);if(t-last<33||document.hidden)return;const dt=Math.min(.1,(t-last)/1000);last=t;const r=box();if(!r.width||!r.height)return;const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;if(reduced)t=0;const dpr=Math.min(devicePixelRatio||1,2);if(canvas.width!==Math.round(r.width*dpr)||canvas.height!==Math.round(r.height*dpr)){canvas.width=Math.round(r.width*dpr);canvas.height=Math.round(r.height*dpr);}ctx.setTransform(dpr,0,0,dpr,0,0);ctx.imageSmoothingEnabled=false;ctx.fillStyle='#0d1924';ctx.fillRect(0,0,r.width,r.height);const base=getBase();if(!base)return;terrainFor(base);initialize(base);let selectionChanged=false;for(const unit of crew){unit.away=isSceneUnitAway(unit.definition,base);if(unit.away&&selectedUnits.delete(unit.id))selectionChanged=true;}if(selectionChanged)notify();const tr=transform(),{unit:u,ox,oy}=tr;drawTerrain(ctx,terrain,tr);\r\n  const blocked=occupancy(base);for(const key of terrain.blocked)blocked.add(key);for(const unit of crew)if(blocked.has(Math.floor(unit.y)*24+Math.floor(unit.x))){Object.assign(unit,nearestFree(base,unit));unit.path=[];unit.index=0;unit.hasOrder=false;unit.rally=false;}\r\n  for(const unit of crew)if(unit.role==='worker'&&Object.values(base.buildings).some(b=>b.job?.policy==='occupied-worker'&&b.job.builderId===`crew-${unit.id+1}`)&&unit.hasOrder){unit.hasOrder=false;unit.rally=false;unit.path=[];unit.version=null;}const builders=crew.filter(unit=>!unit.away&&unit.role==='worker'&&!unit.hasOrder);stepWanderers(builders,base,reduced?0:dt,t,{extraBlocked:terrain.blocked});patrol(base,t);stepRalliedUnits(crew.filter(u=>!u.away),reduced?0:dt,base.rest);\r\n  const rows=[...BUILDINGS.map(def=>({type:'building',value:{...def,...base.buildings[def.id]},depth:(base.buildings[def.id]?.y??def.y)+def.h})),...crew.filter(unit=>!unit.away).map(unit=>({type:'unit',value:unit,depth:unit.y+.5}))].sort((a,b)=>a.depth-b.depth);\r\n  for(const row of rows){if(row.type==='unit'){drawUnit(row.value,tr,t,base);continue;}const b=row.value,f=FACTION_BY_ID[b.track]||FACTION_BY_ID[base.faction]||FACTIONS[0];drawBuilding(ctx,b,f,ox+b.x*u,oy+b.y*u-terrain.heightAt(b.x,b.y)*2,u,{selected:b.id===selected});if(b.job){const text=constructionCountdown(b.job.dueAt,getServerTime());ctx.font='bold 10px monospace';ctx.textAlign='center';const x=ox+(b.x+b.w/2)*u,y=oy+(b.y+b.h)*u+13,width=ctx.measureText(text).width+10;ctx.fillStyle='#101923ee';ctx.fillRect(x-width/2,y-11,width,15);ctx.fillStyle='#ffe3a0';ctx.fillText(text,x,y);ctx.textAlign='start';}}\r\n  const f=FACTION_BY_ID[base.faction]||FACTIONS[0];for(const [x,y] of [[1.4,4],[21.8,7],[2,18],[21,20]])ctx.drawImage(getSpriteCanvas(f.id,'resource'),Math.round(ox+x*u-16),Math.round(oy+y*u-25),32,32);const hull=base.ships?.[base.selectedShip]||{tier:0},tier=Math.min(4,hull.tier||0),pixels=32*(tier>=3?2:1),a=t/6500;ctx.drawImage(getSpriteCanvas(f.id,'ship',tier),Math.round(ox+(12+Math.cos(a)*8)*u-pixels/2),Math.round(oy+(9+Math.sin(a)*5)*u-pixels/2),pixels,pixels);\r\n  const g=gesture.state;if(g?.mode==='select'){ctx.fillStyle='#d5dfa61a';ctx.strokeStyle='#fff0a6';ctx.lineWidth=1;const x=Math.min(g.start.x,g.point.x),y=Math.min(g.start.y,g.point.y),w=Math.max(12,Math.abs(g.start.x-g.point.x)),h=Math.max(12,Math.abs(g.start.y-g.point.y));ctx.fillRect(x,y,w,h);ctx.strokeRect(Math.round(x),Math.round(y),Math.round(w),Math.round(h));}\r\n  if(transition&&performance.now()-transition.started>=450){entryFinished=true;transition=null;delete canvas.dataset.enteringWarRoom;canvas.removeAttribute('aria-busy');onEnterWarRoom();}\r\n }\r\n canvas.addEventListener('contextmenu',e=>e.preventDefault(),{signal:abort.signal});canvas.tabIndex=0;\r\n canvas.addEventListener('pointerdown',e=>{if(transition||entryFinished)return;canvas.setPointerCapture(e.pointerId);const p=localPoint(e);pointers.set(e.pointerId,p);if(pointers.size===1)gesture.down(p,{select:selectionArmed});else{gesture.pinch();const points=[...pointers.values()];pinch=Math.hypot(points[0].x-points[1].x,points[0].y-points[1].y);}},{signal:abort.signal});\r\n canvas.addEventListener('pointermove',e=>{if(!pointers.has(e.pointerId))return;const point=localPoint(e);pointers.set(e.pointerId,point);if(pointers.size>=2){gesture.pinch();const points=[...pointers.values()],distance=Math.hypot(points[0].x-points[1].x,points[0].y-points[1].y);if(pinch)scale=clamp(scale*distance/pinch,.65,2.6);pinch=distance;return;}const move=gesture.move(point);if(move?.mode==='pan'){pan.x=clamp(pan.x+move.dx,-450,450);pan.y=clamp(pan.y+move.dy,-450,450);}},{signal:abort.signal});\r\n const end=e=>{const count=pointers.size;pointers.delete(e.pointerId);if(e.type==='pointercancel'){gesture.cancel();pinch=0;delete canvas.dataset.troopGesture;return;}if(count!==1){gesture.pinch();pinch=0;return;}const g=gesture.up();delete canvas.dataset.troopGesture;if(!g)return;if(g.mode==='select'){selectedUnits.clear();const tr=transform();for(const id of unitsInRectangle(crew.filter(unit=>!unit.away).map(unit=>screenUnit(unit,tr)),g.start,g.point,g.moved?5:18))selectedUnits.add(id);selectionArmed=false;notify();return;}if(g.mode!=='pending'||g.moved)return;const tr=transform(),point=localPoint(e),x=(point.x-tr.ox)/tr.unit,y=(point.y-tr.oy)/tr.unit,base=getBase(),building=[...BUILDINGS].reverse().find(d=>{const b={...d,...base?.buildings[d.id]};return x>=b.x&&x<=b.x+b.w&&y>=b.y-1&&y<=b.y+b.h;});if(building){selected=building.id;onSelect(building.id);if(building.id==='hq')enterWarRoom();}else if(selectedUnits.size)rally({x:Math.floor(x),y:Math.floor(y)});};canvas.addEventListener('pointerup',end,{signal:abort.signal});canvas.addEventListener('pointercancel',end,{signal:abort.signal});\r\n canvas.addEventListener('keydown',e=>{if(e.key==='Escape'&&selectedUnits.size){e.preventDefault();e.stopPropagation();selectedUnits.clear();selectionArmed=false;notify();}else if(['ArrowLeft','ArrowRight','ArrowUp','ArrowDown'].includes(e.key)){e.preventDefault();pan.x+=e.key==='ArrowLeft'?20:e.key==='ArrowRight'?-20:0;pan.y+=e.key==='ArrowUp'?20:e.key==='ArrowDown'?-20:0;}},{signal:abort.signal});\r\n raf=requestAnimationFrame(draw);return {enterWarRoom,select(id){selected=id;},selectTroops(){if(!initialized){const base=getBase();if(base){terrainFor(base);initialize(base);}}selectedUnits.clear();for(const unit of crew)if(!isSceneUnitAway(unit.definition,getBase()))selectedUnits.add(unit.id);selectionArmed=true;notify();},clearSelection(){selectedUnits.clear();selectionArmed=false;gesture.cancel();notify();},rallyAtHQ(){const hq=getBase()?.buildings?.hq;if(hq)return rally({x:hq.x+2,y:hq.y+4});return 0;},getSelectedUnits(){return crew.filter(unit=>!unit.away&&selectedUnits.has(unit.id)).map(unit=>({...unit.definition,instanceId:unit.id}));},recenter(){scale=1;pan={x:0,y:0};},dispose(){disposed=true;transition=null;gesture.dispose();delete canvas.dataset.enteringWarRoom;delete canvas.dataset.troopGesture;canvas.removeAttribute('aria-busy');for(const image of images)image.onload=null;atlases.clear();abort.abort();cancelAnimationFrame(raf);pointers.clear();}};\r\n}\r\n","modules/coach-world/catalog.mjs":"// Original MYR5 civilizations. Existing workout IDs remain canonical.\r\nexport const MAX_LEVEL=5;\nexport const hangarShipTier=level=>Math.max(1,Math.min(4,Math.ceil(level*4/MAX_LEVEL)));\nexport const SKYLINE_LOD_METERS=914.4;\r\nexport const RULES=Object.freeze({version:2,materialPerDay:10,maxTracksPerDay:3,dayGates:[1,3,6,10],buildMinuteMs:300000,launchCapacity:10,walkDwellMs:90000,walkSamples:6,walkDailyCap:12,walkHourlyCap:4,captureWindowMs:1800000,conversionMs:21600000,healingMs:86400000,graceMs:21600000});\nexport const FACTIONS=Object.freeze([\r\n {id:'chest',label:'Chest',name:'Pressforge',policy:'occupied-worker',color:'#ed7855',dark:'#643c46',accent:'#ffe2aa',groups:['chest'],description:'Crested wedge armor and diamond crowns echo the chest coaches angular heads and broad tapered shoulders.'},\r\n {id:'quads',label:'Quads',name:'Stride Citadel',policy:'occupied-worker',color:'#d8b85e',dark:'#4d4e59',accent:'#fff0ae',groups:['legs'],description:'Stacked oval drums and tapered pylons stand on broad paired foundations, echoing the quads coaches.'},\r\n {id:'glutes',label:'Glutes',name:'Thrustroot',policy:'consumed-seed',color:'#c579b6',dark:'#53365f',accent:'#a1e5bc',groups:['hips'],description:'Stacked pearl pods, bubble joints and heavy rounded vaults inherit the glutes coaches spherical bodies.'},\r\n {id:'arms-shoulders',label:'Arms & shoulders',name:'Orbit Arsenal',policy:'occupied-worker',color:'#6b9ee8',dark:'#293f6a',accent:'#ffcf82',groups:['shoulders'],description:'Wide shoulder canopies carry paired branching arms, echoing the arms and shoulders coaches.'},\r\n {id:'yoga',label:'Yoga & balance',name:'Stillwave',policy:'seeded-warp',color:'#88c6ae',dark:'#394f68',accent:'#f3e4b9',groups:['core','balance','yoga'],description:'Floating S-stems, hooked crowns and curling ribbons inherit the yoga coaches suspended wisp bodies.'},\r\n {id:'martial-arts',label:'Martial arts',name:'Moltguard',policy:'consumed-seed',color:'#d96564',dark:'#463b4b',accent:'#c0e2b1',groups:['stances','boxing'],description:'Compact braced bastions unfold from blunt monolith plates into ribbed fan helmets.'},\r\n {id:'cardio',label:'Cardio',name:'Pulseway',policy:'seeded-warp',color:'#5fcdd1',dark:'#294d62',accent:'#eb99df',groups:['cardio'],description:'Open-core rings, suspended saucers and thin skeletal struts echo the cardio coaches airy silhouettes.'},\r\n].map(f=>Object.freeze({...f,groups:Object.freeze(f.groups)})));\r\nexport const FACTION_BY_ID=Object.freeze(Object.fromEntries(FACTIONS.map(f=>[f.id,f])));\r\nexport const GROUP_TO_FACTION=Object.freeze(Object.fromEntries(FACTIONS.flatMap(f=>f.groups.map(g=>[g,f.id]))));\r\nexport const BUILDINGS=Object.freeze([\r\n {id:'hq',kind:'hq',track:null,x:10,y:9,w:4,h:4,label:'Command habitat'},\r\n ...FACTIONS.map((f,i)=>({id:`hall-${f.id}`,kind:'hall',track:f.id,x:[3,10,17,3,17,5,15][i],y:[3,2,3,10,10,17,17][i],w:3,h:3,label:f.name})),\r\n {id:'care',kind:'care',track:null,x:3,y:6,w:2,h:2,label:'Fuel kitchen'},\r\n {id:'observatory',kind:'observatory',track:null,x:18,y:6,w:2,h:2,label:'Breath observatory'},\r\n {id:'habitat',kind:'habitat',track:null,x:9,y:15,w:2,h:2,label:'Crew habitat'},\r\n {id:'hangar',kind:'hangar',track:null,x:12,y:15,w:3,h:2,label:'Ship hangar'},\n ...FACTIONS.flatMap((f,i)=>[\n  {id:`production-${f.id}`,kind:'production',track:f.id,x:[1,4,7,16,19,22,0][i],y:i===6?22:0,w:2,h:2,label:`${f.name} production`,startsUnbuilt:true,prerequisites:[{buildingId:'hq',level:1},{buildingId:`hall-${f.id}`,level:1}]},\n  {id:`expedition-${f.id}`,kind:'expedition',track:f.id,x:[3,6,9,12,15,18,21][i],y:22,w:2,h:2,label:`${f.name} launch post`,startsUnbuilt:true,prerequisites:[{buildingId:'hq',level:2},{buildingId:`production-${f.id}`,level:1}]},\n ]),\n].map(Object.freeze));\r\nexport const BUILDING_BY_ID=Object.freeze(Object.fromEntries(BUILDINGS.map(b=>[b.id,b])));\r\nexport const SHIP_IDS=Object.freeze(['supportive','direct','analytical','playful','calm','mom']);\r\nexport const NPC_ITEMS=Object.freeze([{id:'repair-flag',label:'Repair pennant',cost:10},{id:'garden-lamp',label:'Biome lantern',cost:15},{id:'landing-ring',label:'Landing ring',cost:25}]);\r\n","modules/coach-world/client.mjs":"import {authFetch} from '../../auth-client.mjs';\r\nimport {authTransitions} from '../../auth-transition.mjs';\r\nimport {performanceOwner,readPerformanceProgress,mergeVerifiedPerformance} from '../../performance-progress.mjs';\r\nimport {grantUnlock} from '../../unlock-ledger.mjs';\r\nimport {newBase,advanceBase,applyBaseAction,creditPersonalProgress,assertBase,normalizeBase} from './state.mjs';\r\n\r\nexport function createWorldClient({signal,onInvalidate=()=>{}}={}){\r\n const owner=performanceOwner(),account=globalThis.myr5AuthenticatedAccount;\r\n const user=account?.user?.id,epoch=account?.dataEpoch,key=`myr5-coach-world-v1/${encodeURIComponent(owner)}`;\r\n let snapshot=null,disposed=false,queue=Promise.resolve();const transitions=authTransitions(),ticket=transitions.capture();\r\n const current=()=>{if(disposed||signal?.aborted||performanceOwner()!==owner||!transitions.isCurrent(ticket))throw new DOMException('World closed or account changed.','AbortError');};\r\n const invalidate=()=>{if(performanceOwner()!==owner){disposed=true;snapshot=null;onInvalidate();}};\r\n globalThis.addEventListener('myr5:account-ready',invalidate);globalThis.addEventListener('myr5:auth-transition',invalidate);\r\n const unsubscribe=transitions.subscribe(()=>{disposed=true;snapshot=null;onInvalidate();});\r\n const save=base=>{current();try{localStorage.setItem(key,JSON.stringify(base));}catch{throw Error('Base could not be saved on this device. Free storage and retry.');}return base;};\r\n async function request(path,body){\r\n  current();if(!user)throw Error('Sign in to use shared sectors, shops and nearby battles.');\r\n  if(epoch==null)throw Error('Your account is still loading. Close World and retry.');\r\n  const headers={'X-Target-Account':user,'X-Expected-Data-Epoch':String(epoch)};\r\n  if(body){headers['Content-Type']='application/json';headers['Idempotency-Key']=body.id;}\r\n  const response=await authFetch(path,{signal,headers,method:body?'POST':'GET',body:body?JSON.stringify(body):undefined});current();\r\n  let data;try{data=await response.json();}catch{throw Error('World returned an unreadable response. Retry shortly.');}\r\n  if(!response.ok)throw Object.assign(Error(response.status===401?'Sign in again to use shared World features.':data.message||data.error||`World request failed (${response.status}).`),{status:response.status,code:data.code||data.error});\r\n  if(data.targetAccountId&&data.targetAccountId!==user||data.dataEpoch!=null&&Number(data.dataEpoch)!==Number(epoch))throw Error('Account changed. Reopen World.');\r\n  return data;\r\n }\r\n async function execute(action){\r\n  async function post(body){try{return await request('/api/world',body);}catch(e){current();if(e instanceof TypeError||e.name==='TimeoutError')return request('/api/world',body);throw e;}}\r\n  const make=()=>({...action,id:crypto.randomUUID(),revision:snapshot.revision});\r\n  try{snapshot=await post(make());}catch(e){if(!['world_revision_conflict','world_state_conflict'].includes(e.code))throw e;snapshot=await request('/api/world');snapshot=await post(make());}\r\n  if(action.type==='tick')snapshot=await request('/api/world');snapshot={...snapshot,base:normalizeBase(snapshot.base)};return snapshot;\r\n }\r\n return {owner,authenticated:!!user,get snapshot(){return snapshot;},\r\n  async load(){current();if(user){snapshot=await request('/api/world');await execute({type:'reconcile'});}else{\r\n   let base;try{base=normalizeBase(JSON.parse(localStorage.getItem(key)));assertBase(base);}catch{base=newBase(owner);}\r\n   base=advanceBase(base);base=creditPersonalProgress(base,readPerformanceProgress({owner}));save(base);snapshot={base,revision:0,publicId:null,serverTime:Date.now()};\r\n  }current();return snapshot;},\r\n  command(action){const run=queue.then(async()=>{current();if(!snapshot)throw Error('Your base is still loading.');\r\n   if(user){await execute(action);}\r\n   else {if(!['build','upgrade','cancel','move','care','rest','faction','select-ship','train-unit','cancel-training','prepare-expedition','launch-expedition','return-expedition','cancel-expedition'].includes(action.type))throw Error('Sign in to use shared world features.');const base=applyBaseAction(advanceBase(snapshot.base),action,{now:Date.now()});save(base);snapshot={...snapshot,base};}\r\n   current();return snapshot;\r\n  });queue=run.catch(()=>{});return run;},\r\n  async map({latitude,longitude,radius=5000}={}){if(user){const query=Number.isFinite(latitude)&&Number.isFinite(longitude)?`?latitude=${encodeURIComponent(latitude)}&longitude=${encodeURIComponent(longitude)}&radius=${Math.max(100,Math.min(5000,radius))}`:'';return request('/api/world/map'+query);}current();const {WORLD_SITES,WORLD_SECTORS}=await import('./sites.mjs');current();return {serverTime:Date.now(),preview:true,sites:WORLD_SITES.map(s=>({...s})),sectors:WORLD_SECTORS.map(s=>({id:s.id,siteId:s.siteId,initialPatchId:s.initialPatchId,controller:s.initialFaction,phase:'stable',conversionProgress:1,polygonGeoJSON:{type:'Polygon',coordinates:[[...s.polygon,s.polygon[0]]]}})),friends:[],geometryEpoch:1};},encounter:id=>request(`/api/world/encounters/${encodeURIComponent(id)}`),\r\n  async drops(){const data=await request('/api/world/drops');current();for(const claim of data.claims||[])for(const id of claim.packs||[])grantUnlock('reward-pack',id,{account});return data;},\r\n  dropsCommand(action){const run=queue.then(async()=>{current();const body={...action,id:crypto.randomUUID()};let response;try{response=await request('/api/world/drops',body);}catch(e){if(e instanceof TypeError||e.name==='TimeoutError')response=await request('/api/world/drops',body);else throw e;}current();if(response.result?.claimed){for(const id of response.result.claim.packs)grantUnlock('reward-pack',id,{account});try{const verified=await request('/api/account');current();mergeVerifiedPerformance(verified);}catch{current();response.progressRefreshPending=true;}globalThis.dispatchEvent(new CustomEvent('myr5:battle-pass',{detail:{granted:response.result.claim.packs.map(id=>({kind:'reward-pack',id}))}}));}globalThis.dispatchEvent(new CustomEvent('myr5:world-drops-updated'));return response;});queue=run.catch(()=>{});return run;},\r\n  dispose(){disposed=true;snapshot=null;unsubscribe();globalThis.removeEventListener('myr5:account-ready',invalidate);globalThis.removeEventListener('myr5:auth-transition',invalidate);}\r\n };\r\n}\r\n","modules/coach-world/entry.mjs":"// One visible door; the shared router owns opening/back/close behavior.\r\nexport function mountWorldEntry(){\r\n let disposed=false;const add=()=>{const settings=document.getElementById('settings');if(settings&&!settings.querySelector('[data-world-entry]')){const a=document.createElement('a');a.href='#world';a.dataset.worldEntry='';a.textContent='Open your War Room base';a.className='button';a.addEventListener('click',()=>settings.close());settings.append(a);}\r\n  const header=document.querySelector('body > .ship-header');if(header&&!header.querySelector('[data-world-entry]')){const a=document.createElement('a');a.href='#world';a.dataset.worldEntry='';a.textContent='BASE';a.setAttribute('aria-label','Open War Room base');a.style.cssText='color:#d9efbc;font:700 11px monospace;letter-spacing:.12em;text-decoration:none;padding:12px 9px;border:1px solid #77937f66;border-radius:8px;margin-left:auto;margin-right:10px;background:#132a2cdd;';header.insertBefore(a,document.getElementById('openSettings'));}\r\n };const observe=new MutationObserver(()=>{if(!disposed)add();});observe.observe(document.body,{childList:true,subtree:true});add();return ()=>{disposed=true;observe.disconnect();};\r\n}\r\nif(typeof document!=='undefined'){if(document.readyState==='loading')document.addEventListener('DOMContentLoaded',()=>mountWorldEntry(),{once:true});else mountWorldEntry();}\r\n","modules/coach-world/expedition-catalog.mjs":"import {FACTIONS,SHIP_IDS} from './catalog.mjs';\r\nimport {COACH_REQUIREMENTS,STARTER_COACH_IDS} from '../../performance-catalog.mjs';\r\nexport const UNIT_CATALOG=Object.freeze([\r\n {id:'myr5-worker',label:'MYR5 builder',role:'worker',faction:null,buildingId:'hq',requiredLevel:1,supply:1,trainable:false,description:'Builds, repairs and carries expedition supplies. Never consumed.'},\r\n ...FACTIONS.flatMap(f=>[\r\n  {id:`grunt-${f.id}`,label:`${f.label} coach grunt`,role:'grunt',faction:f.id,buildingId:`hall-${f.id}`,requiredLevel:1,supply:1,trainable:false,description:'An available coach guards the group and escorts supplies.'},\r\n  {id:`boss-${f.id}`,label:`${f.label} coach boss`,role:'boss',faction:f.id,buildingId:`hall-${f.id}`,requiredLevel:3,supply:3,trainable:false,description:'The senior coach leads the expedition; permanent coach progress is protected.'},\r\n  {id:`companion-${f.id}-scout`,label:`${f.name} pathfinder`,role:'scout',faction:f.id,buildingId:`production-${f.id}`,requiredLevel:1,supply:1,trainable:true,materialCost:8,trainingMs:120000,description:'A four-legged companion scouts virtual terrain and guides the group.'},\r\n  {id:`companion-${f.id}-hauler`,label:`${f.name} pack companion`,role:'hauler',faction:f.id,buildingId:`production-${f.id}`,requiredLevel:3,supply:2,trainable:true,materialCost:15,trainingMs:240000,description:'A four-legged companion carries supplies and recovery gear.'},\r\n ]),\r\n].map(Object.freeze));\r\nexport const UNIT_BY_ID=Object.freeze(Object.fromEntries(UNIT_CATALOG.map(v=>[v.id,v])));\r\nexport const SHIP_ROLES=Object.freeze(Object.fromEntries(SHIP_IDS.map(id=>[id,Object.freeze({id,role:id==='supportive'?'supply-scout':'carrier',description:id==='supportive'?'Smallest starter supply shuttle.':'Larger carrier; capacity grows with earned hull and hangar tiers.'})])));\r\nexport function unitRoster(base){const reserved=new Set(['launched','returning'].includes(base.expedition?.status)?base.expedition.unitIds:[]),earned=new Set(base.coachAccess??STARTER_COACH_IDS);return UNIT_CATALOG.map(unit=>{const buildingLevel=base.buildings?.[unit.buildingId]?.level??0,coach=['grunt','boss'].includes(unit.role)?COACH_REQUIREMENTS.filter(c=>c.tracks.includes(unit.faction==='arms-shoulders'?'arms':unit.faction)&&earned.has(c.id)&&(unit.role==='boss'?c.difficulty==='expert':c.difficulty!=='expert')).sort((a,b)=>['easy','medium','hard','expert'].indexOf(a.difficulty)-['easy','medium','hard','expert'].indexOf(b.difficulty)||a.id.localeCompare(b.id))[0]:null,owned=unit.trainable?(base.units?.[unit.id]??0)>0:buildingLevel>=unit.requiredLevel&&(unit.role==='worker'||!!coach),sourceCoachId=unit.role==='worker'?'myr5':coach?.id??null,visualId=unit.role==='worker'?'worker:myr5':unit.trainable?`companion:${unit.faction}:${unit.role==='hauler'?'carrier':'scout'}`:sourceCoachId?`coach:${sourceCoachId}`:null;return {...unit,owned,available:owned&&!reserved.has(unit.id),reserved:reserved.has(unit.id),buildingLevel,unlocked:buildingLevel>=unit.requiredLevel,training:base.training?.[unit.id]??null,sourceCoachId,visualId};});}\r\nexport function expeditionQuote(base,plan){\r\n const fail=reason=>({allowed:false,reason});if(!plan||!FACTIONS.some(f=>f.id===plan.factionId))return fail('Choose an expedition civilization.');\r\n const facility=base.buildings?.[`expedition-${plan.factionId}`];if(!facility||facility.level<1||facility.job)return fail('Build an idle launch post for this civilization first.');\r\n if(!Object.hasOwn(base.ships??{},plan.shipId))return fail('Choose an earned ship.');if(!Array.isArray(plan.unitIds)||!plan.unitIds.length||plan.unitIds.length>8||new Set(plan.unitIds).size!==plan.unitIds.length)return fail('Choose one to eight distinct available units.');\r\n const roster=unitRoster({...base,expedition:null}),units=plan.unitIds.map(id=>roster.find(u=>u.id===id));if(units.some(u=>!u||!u.owned||u.faction&&u.faction!==plan.factionId))return fail('Selected units must be earned and belong to this civilization.');\r\n // Roles come from the owned roster, never from client-supplied quote fields.\n // Each benefit applies once per role; companions are permanent, not consumables.\n const roles=new Set(units.map(u=>u.role)),supply=units.reduce((n,u)=>n+u.supply,0),\n capacity=(plan.shipId==='supportive'?4:4+2*(base.ships[plan.shipId].tier||1))+(roles.has('hauler')?2:0),\n materialCost=Math.max(1,10+supply*2-(roles.has('worker')?2:0)),\n fuelCost=Math.max(1,10+supply*2-(roles.has('grunt')?2:0)),\n durationMs=Math.max(30000,Math.ceil((6-facility.level)*60000*(roles.has('scout')?.75:1)*(roles.has('boss')?.85:1))),\n returnDurationMs=roles.has('hauler')?45000:60000,\n roleEffects=[\n  ...(roles.has('worker')?['Builder: 2 fewer launch materials.']:[]),\n  ...(roles.has('grunt')?['Escort: 2 less launch fuel.']:[]),\n  ...(roles.has('scout')?['Scout: 25% shorter outbound journey.']:[]),\n  ...(roles.has('boss')?['Leader: 15% shorter outbound journey.']:[]),\n  ...(roles.has('hauler')?['Pack companion: +2 ship capacity and 25% faster return.']:[]),\n ];\n const result={factionId:plan.factionId,shipId:plan.shipId,unitIds:[...plan.unitIds],supply,capacity,materialCost,fuelCost,durationMs,returnDurationMs,roleEffects};\n if(supply>capacity)return {...result,...fail(`This ship carries ${capacity} supply; selected units use ${supply}.`)};\r\n if((base.materials?.[plan.factionId]??0)<materialCost)return {...result,...fail(`Need ${materialCost} matching materials to launch.`)};if(base.fuel<fuelCost)return {...result,...fail(`Need ${fuelCost} station fuel to launch.`)};\r\n return {...result,allowed:true,reason:null};\r\n}\r\n","modules/coach-world/geo.mjs":"// H3 indexes conquest sectors; spherical nearest-anchor influence is a separate layer.\nimport {latLngToCell,cellToBoundary,cellToLatLng,gridDisk,polygonToCells} from './vendor/h3.mjs';\nexport {latLngToCell,cellToBoundary,cellToLatLng,gridDisk,polygonToCells};\nexport const EARTH_METERS=6371008.8;\nexport function validCoordinate(lat,lng){return typeof lat==='number'&&typeof lng==='number'&&Number.isFinite(lat)&&Number.isFinite(lng)&&Math.abs(lat)<=90&&Math.abs(lng)<=180;}\nexport function distanceMeters(a,b,c,d){let lat1,lng1,lat2,lng2;if(typeof a==='number'){[lat1,lng1,lat2,lng2]=[a,b,c,d];}else{lat1=a.latitude??a.lat;lng1=a.longitude??a.lng;lat2=b.latitude??b.lat;lng2=b.longitude??b.lng;}if(!validCoordinate(lat1,lng1)||!validCoordinate(lat2,lng2))return Infinity;const rad=Math.PI/180,p=lat1*rad,q=lat2*rad,dl=(lng2-lng1)*rad;const h=Math.sin((q-p)/2)**2+Math.cos(p)*Math.cos(q)*Math.sin(dl/2)**2;return 2*EARTH_METERS*Math.atan2(Math.sqrt(Math.min(1,h)),Math.sqrt(Math.max(0,1-h)));}\nexport function unitVector(lat,lng){if(!validCoordinate(lat,lng))throw RangeError('Invalid geographic coordinate.');const p=lat*Math.PI/180,l=lng*Math.PI/180;return [Math.cos(p)*Math.cos(l),Math.cos(p)*Math.sin(l),Math.sin(p)];}\nexport function nearestAnchor(point,anchors){const u=unitVector(point.latitude??point.lat,point.longitude??point.lng);let best=null,score=-Infinity;for(const a of anchors){const v=unitVector(a.latitude??a.lat,a.longitude??a.lng),s=u[0]*v[0]+u[1]*v[1]+u[2]*v[2];if(s>score+1e-14||(Math.abs(s-score)<=1e-14&&String(a.id)<String(best?.id))){best=a;score=s;}}return best;}\nfunction inRing(x,y,ring){let inside=false;for(let i=0,j=ring.length-1;i<ring.length;j=i++){const [xi,yi]=ring[i],[xj,yj]=ring[j];if((yi>y)!==(yj>y)&&x<(xj-xi)*(y-yi)/(yj-yi)+xi)inside=!inside;}return inside;}\nexport function containsPoint(geometry,latitude,longitude){if(!validCoordinate(latitude,longitude)||!geometry)return false;const polys=geometry.type==='MultiPolygon'?geometry.coordinates:geometry.type==='Polygon'?[geometry.coordinates]:[];return polys.some(p=>inRing(longitude,latitude,p[0])&&!p.slice(1).some(r=>inRing(longitude,latitude,r)));}\nexport const sectorAt=(lat,lng)=>validCoordinate(lat,lng)?latLngToCell(lat,lng,10):null;\nexport function neighbors(id){try{return gridDisk(id,1).filter(v=>v!==id);}catch{return [];}}\nexport function conservativeNearby(a,b,max=100){if(!a||!b||!Number.isFinite(a.accuracy)||!Number.isFinite(b.accuracy)||a.accuracy<0||b.accuracy<0)return false;return distanceMeters(a,b)+a.accuracy+b.accuracy<=max;}\n","modules/coach-world/location-drop-rules.mjs":"import {EXERCISES,GROUP_EXERCISES} from '../../exercise-library.mjs';\nimport {GROUP_TO_FACTION} from './catalog.mjs';\nexport const DROP_KINDS=Object.freeze(['home','work','gym']);\nexport const DROP_RULES=Object.freeze({cooldownMs:86400000,challengeMs:120000,dwellMs:10000,radiusMeters:60,maxAccuracy:25,rounds:10,gymPacks:3});\n// Bonus XP only: never manufacture workout sessions, coach milestones or battle charge.\nexport function gymCircuitReward(performance={}){\n const selected=new Set(performance.paths||[]),best=new Map();\n for(const session of Object.values(performance.sessions||{})){\n  const exercise=EXERCISES[session.mode],faction=GROUP_TO_FACTION[exercise?.group];if(!exercise||!faction||selected.size&&!selected.has(faction)||!Number.isFinite(session.xp)||session.xp<=0)continue;\n  const level=(GROUP_EXERCISES[exercise.group]||[]).findIndex(e=>e.id===exercise.id)+1,prior=best.get(exercise.group);\n  if(!prior||level>prior.level||level===prior.level&&session.xp>prior.xpPerRound)best.set(exercise.group,{mode:exercise.id,name:exercise.name,group:exercise.group,faction,level,xpPerRound:session.xp});\n }\n const exercises=[...best.values()].sort((a,b)=>a.group.localeCompare(b.group)),xp=Math.round(exercises.reduce((sum,e)=>sum+e.xpPerRound*DROP_RULES.rounds,0)*1000)/1000;\n return {rounds:DROP_RULES.rounds,exercises,xp,secretPacks:DROP_RULES.gymPacks,eligible:exercises.length>0,basis:'highest-completed-mode-per-active-workout-family'};\n}\nexport function dropDistance(a,b){const r=Math.PI/180,p=(b.latitude-a.latitude)*r,q=(b.longitude-a.longitude)*r;return 12742000*Math.asin(Math.min(1,Math.sqrt(Math.sin(p/2)**2+Math.cos(a.latitude*r)*Math.cos(b.latitude*r)*Math.sin(q/2)**2)));}\n","modules/coach-world/location-drops-view.mjs":"import {DROP_KINDS,DROP_RULES} from './location-drop-rules.mjs';\nconst labels={home:'Home',work:'Work',gym:'Gym'},human=e=>({drop_move_closer:'Move closer to your saved drop spot.',drop_cache_recharging:'This cache is recharging. Check its timer.',drop_complete_a_phone_workout_first:'Complete a phone workout to establish your gym circuit reward.',drop_location_change_cooldown:'This location was just saved. You can move it after one hour.',drop_fresh_accurate_gps_required:'Wait for a fresh GPS fix with accuracy of 25 m or better.',drop_challenge_expired:'That pickup expired. Start a fresh pickup.',drop_state_changed:'The cache changed. Refresh and try again.'}[e.code]||e.message);\nexport function mountLocationDrops(host,{client,signal}={}){\n const abort=new AbortController();let disposed=false,data=null,busy=false,active=null,poll=0,timer=0,generation=0;\n const alive=()=>!disposed&&!signal?.aborted,stop=()=>{generation++;clearInterval(poll);poll=0;active=null;};\n host.classList.add('cw-card');host.innerHTML='<span class=\"cw-eyebrow\">PRIVATE SUPPLY CACHES</span><h3>A reason to get there.</h3><p class=\"cw-note\">Home, optional work, and gym drops recharge 24 hours after collection. Your saved spots are visible only to you.</p><label class=\"cw-check\"><input type=\"checkbox\" data-drop-consent> This is an accessible spot I may use, and I want to save it privately.</label><div data-drop-cards></div><p data-drop-status class=\"cw-note\" role=\"status\"></p><button data-stop-drop hidden>Cancel pickup</button>';\n const status=host.querySelector('[data-drop-status]'),cards=host.querySelector('[data-drop-cards]'),consent=host.querySelector('[data-drop-consent]'),cancel=host.querySelector('[data-stop-drop]');\n const getFix=()=>new Promise((resolve,reject)=>{if(!navigator.geolocation)return reject(Error('GPS is unavailable in this browser.'));navigator.geolocation.getCurrentPosition(p=>resolve({latitude:p.coords.latitude,longitude:p.coords.longitude,accuracy:p.coords.accuracy,sampledAt:p.timestamp}),()=>reject(Error('Allow location access to use this private supply cache.')),{enableHighAccuracy:true,maximumAge:0,timeout:15000});});\n function countdown(){if(!alive()||!data)return;const now=Date.now()+(data.serverTime-data.receivedAt);for(const n of host.querySelectorAll('[data-drop-available]')){const seconds=Math.max(0,Math.ceil((Number(n.dataset.dropAvailable)-now)/1000));n.textContent=seconds?`Recharging / ${Math.floor(seconds/3600)}h ${Math.floor(seconds%3600/60)}m`:'Ready to collect nearby';}}\n function render(){if(!alive())return;cards.replaceChildren();for(const kind of DROP_KINDS){const location=data?.locations?.find(l=>l.kind===kind),card=document.createElement('article');card.className='cw-drop-card';const title=document.createElement('h4');title.textContent=`${labels[kind]} drop${kind==='work'?' / optional':''}`;card.append(title);const reward=document.createElement('p');reward.className='cw-note';reward.textContent=kind==='gym'?data?.gymReward?.eligible?`${data.gymReward.xp.toLocaleString()} bonus XP + 3 secret packs. Ten rounds of each highest completed exercise in your active workout families.`:'3 secret packs + full circuit bonus XP once you have a completed phone workout.':'1 uncommon cosmetic pack.';card.append(reward);\n   if(kind==='gym'&&data?.gymReward?.eligible){const basis=document.createElement('small');basis.textContent=data.gymReward.exercises.map(e=>`${e.name} / level ${e.level}`).join(' · ');card.append(basis);}\n   const row=document.createElement('div');row.className='cw-actions';const save=document.createElement('button');save.textContent=location?'Move drop to this spot':'Save this spot';save.disabled=!client.authenticated;save.onclick=()=>saveLocation(kind);row.append(save);\n   if(location){const collect=document.createElement('button');collect.textContent='Collect nearby';collect.className='cw-primary';collect.onclick=()=>start(kind);row.append(collect);const remove=document.createElement('button');remove.textContent='Remove';remove.onclick=()=>run(async()=>{stop();await client.dropsCommand({type:'remove-location',kind});await refresh();status.textContent=`${labels[kind]} spot removed.`;});row.append(remove);const recharge=document.createElement('p');recharge.className='cw-note';recharge.dataset.dropAvailable=String(location.availableAt);card.append(recharge);}card.append(row);cards.append(card);\n  }countdown();}\n async function refresh(){const next=await client.drops();if(alive()){data={...next,receivedAt:Date.now()};render();}}\n async function run(fn){if(busy||!alive())return;busy=true;try{await fn();}catch(e){stop();if(alive())status.textContent=human(e);}finally{busy=false;if(alive())cancel.hidden=!active;}}\n const saveLocation=kind=>run(async()=>{if(!consent.checked)throw Error('Confirm this is an accessible spot you want to save privately.');stop();status.textContent='Waiting for an accurate location fix...';const fix=await getFix();if(!alive())return;await client.dropsCommand({type:'set-location',kind,confirmPrivateLocation:true,confirmAccessible:true,...fix});await refresh();if(alive())status.textContent=`${labels[kind]} drop saved privately. Its marker is on your Sectors map.`;});\n const start=kind=>run(async()=>{stop();status.textContent='Finding your saved cache...';const fix=await getFix();if(!alive())return;const response=await client.dropsCommand({type:'start-claim',kind,...fix});if(!alive())return;const ticket=++generation;active={kind,...response.result.challenge,seq:0};cancel.hidden=false;status.textContent='Stay near the cache while GPS confirms your pickup / about 15 seconds.';\n  poll=setInterval(()=>{if(!alive()||ticket!==generation||!active||busy)return;void run(async()=>{if(Date.now()>active.expiresAt){stop();throw Error('Pickup expired. Start again.');}const fix=await getFix();if(!alive()||ticket!==generation)return;const response=await client.dropsCommand({type:'sample-claim',kind,challengeId:active.id,nonce:active.nonce,seq:++active.seq,...fix});if(!alive()||ticket!==generation)return;if(response.result.claimed){const claim=response.result.claim;stop();await refresh();status.textContent=`Collected ${claim.packs.length} ${kind==='gym'?'secret':'uncommon'} pack${claim.packs.length===1?'':'s'}${claim.xp?` and ${claim.xp.toLocaleString()} bonus XP`:''}. Open your packs from the pack button.`;}else status.textContent=`GPS pickup in progress / ${Math.floor(response.result.dwellMs/1000)} seconds confirmed.`;});},3000);\n });\n cancel.onclick=()=>{stop();cancel.hidden=true;status.textContent='Pickup cancelled. The cache is still there.';};timer=setInterval(countdown,1000);\n if(client.authenticated)void refresh().catch(e=>{if(alive())status.textContent=human(e);});else{render();consent.disabled=true;status.textContent='Sign in to save private cache locations and collect rewards.';}\n const dispose=()=>{if(disposed)return;disposed=true;stop();clearInterval(timer);abort.abort();};signal?.addEventListener('abort',dispose,{once:true});document.addEventListener('visibilitychange',()=>{if(document.hidden){stop();cancel.hidden=true;if(alive())status.textContent='Pickup paused while the app was hidden.';}},{signal:abort.signal});return {dispose};\n}\n","modules/coach-world/map-view.mjs":"import {FACTION_BY_ID,NPC_ITEMS} from './catalog.mjs';\r\nimport {rememberPublicGeography,updatePublicTerritory,publicThemeAt} from './public-geography.mjs';\r\nimport {drawBuilding} from './canvas-scene.mjs';\r\nimport {getSpriteCanvas} from './pixel-art.mjs';\r\nimport {buildWorldNodes} from './world-nodes.mjs';\r\nimport {mountPrivateDropPins} from './private-drop-pins.mjs';\r\nimport {claimGraphics,releaseGraphics} from '../graphics-lifecycle.mjs';\r\nlet mapLibrary;\r\nfunction loadMapLibrary(){\r\n if(globalThis.maplibregl)return Promise.resolve(globalThis.maplibregl);\r\n if(!mapLibrary)mapLibrary=new Promise((resolve,reject)=>{const css=document.createElement('link');css.rel='stylesheet';css.href='/modules/coach-world/vendor/maplibre-gl.css';document.head.append(css);const script=document.createElement('script');script.src='/modules/coach-world/vendor/maplibre-gl.js';script.onload=()=>globalThis.maplibregl?resolve(globalThis.maplibregl):reject(Error('Map renderer unavailable.'));script.onerror=()=>reject(Error('Map renderer could not load.'));document.head.append(script);}).catch(e=>{mapLibrary=null;throw e;});return mapLibrary;\r\n}\r\nconst text=(tag,value,className)=>{const e=document.createElement(tag);e.textContent=value;if(className)e.className=className;return e;};\r\nexport function mountSectors(host,{client,signal,onSnapshot=()=>{}}){\r\n let disposed=false,watch=null,walk=null,seq=0,sending=false,generation=0,geographicMap=null,mapClaim=null,lastFix=null,latestData=null,viewportTimer=0,privateDropPins=null;const abort=new AbortController();\r\n host.innerHTML='<div class=\"cw-sector-intro\"><span class=\"cw-eyebrow\">THE FRONTIER</span><h3>Earn your ground.</h3><p>Small territory patches. A few public hubs. Contested ground stays scarred while control spreads, then heals after sustained peace.</p></div><label class=\"cw-check\"><input type=\"checkbox\" data-lawful-walk> I am walking somewhere I am allowed to be; virtual territory is not permission to enter property.</label><div class=\"cw-actions\"><button data-walk>Begin a sector walk</button><button data-refresh>Refresh sectors</button><button data-skyline>Prepare mapped skyline here</button></div><p data-walk-status role=\"status\">GPS is off. Walking requires your explicit permission.</p><div data-map></div><div data-sites></div><section class=\"cw-card\"><h3>Connect at a public hub</h3><p data-public></p><div class=\"cw-actions\"><button data-friend>Create friend code</button><input data-friend-code placeholder=\"Friend invite code\" aria-label=\"Friend invite code\"><button data-accept-friend>Accept friend</button></div><p data-invite></p><div class=\"cw-actions\"><input data-target placeholder=\"Player public ID\" aria-label=\"Player public ID\"><select data-site aria-label=\"Battle meetup hub\"></select><button data-battle>Invite to battle</button></div><label class=\"cw-check\"><input type=\"checkbox\" data-public-path> I am on an ordinary open public path and choose my current spot for this battle.</label><div class=\"cw-actions\"><input data-encounter placeholder=\"Encounter ID\" aria-label=\"Encounter ID\"><button data-accept-battle>Accept battle</button><button data-cancel-battle>Cancel battle</button><button data-check-battle>Check battle</button></div><p class=\"cw-note\">Both players must be nearby at the same eligible public hub. Battles reveal a temporary defense view, never a home address. Friendship does not automatically share home location.</p></section><p data-error role=\"status\"></p>';\r\n const q=s=>host.querySelector(s),status=q('[data-walk-status]'),error=q('[data-error]');q('[data-public]').textContent=client.snapshot?.publicId?`Your public ID: ${client.snapshot.publicId}`:'Sign in to visit shops, share friend codes and battle nearby.';\r\n const alive=()=>!disposed&&!signal?.aborted;\r\n const report=e=>{if(alive())error.textContent=e.name==='AbortError'?'':e.message;};\r\n const cmd=async action=>{error.textContent='';const s=await client.command(action);if(alive()){onSnapshot(s);return s;}throw new DOMException('Closed','AbortError');};\r\n async function refresh(){const g=++generation;q('[data-refresh]').disabled=true;try{const center=geographicMap?.getCenter(),data=await client.map(center?{latitude:center.lat,longitude:center.lng,radius:5000}:{});if(!alive()||g!==generation)return;render(data);}catch(e){report(e);}finally{if(alive()&&g===generation)q('[data-refresh]').disabled=false;}}\r\n function releaseMap(){privateDropPins?.dispose();privateDropPins=null;const map=geographicMap,claim=mapClaim;geographicMap=null;mapClaim=null;if(!map){claim?.();return;}const canvas=map.getCanvas(),gl=canvas.getContext('webgl2')||canvas.getContext('webgl');void releaseGraphics(canvas,gl,()=>{map.remove();gl?.getExtension('WEBGL_lose_context')?.loseContext();}).then(()=>claim?.());}\r\n function syncNodeSprites(map,data){\r\n  const nodes=buildWorldNodes(data.sectors||[],data.sites||[]),features=[];\r\n  for(const n of nodes){const kind=n.type==='public-hub'?'shop':n.type==='public-node'?'node':'resource',key=`cw-${n.faction}-${kind}`;if(!map.hasImage?.(key)){const source=getSpriteCanvas(n.faction,kind),image=source.getContext('2d').getImageData(0,0,64,64);map.addImage(key,image,{pixelRatio:2});}features.push({type:'Feature',id:n.id,geometry:{type:'Point',coordinates:[n.lng,n.lat]},properties:{sprite:key,label:n.label,type:n.type}});}\r\n  const value={type:'FeatureCollection',features},source=map.getSource('cw-world-node-sprites');if(source)source.setData(value);else{map.addSource('cw-world-node-sprites',{type:'geojson',data:value});map.addLayer({id:'cw-world-node-sprites',type:'symbol',source:'cw-world-node-sprites',minzoom:12,layout:{'icon-image':['get','sprite'],'icon-anchor':'bottom','icon-allow-overlap':false,'icon-padding':4,'icon-pitch-alignment':'viewport','icon-rotation-alignment':'viewport'}});}\r\n }\r\n async function mountGeographicMap(node,data,g){let ownClaim;try{const lib=await loadMapLibrary();if(!alive()||generation!==g||!node.isConnected)return;ownClaim=claimGraphics('coach-world-map');await ownClaim.ready;if(!alive()||generation!==g||!node.isConnected){ownClaim();return;}mapClaim=ownClaim;const sites=data.sites||[],first=sites.find(s=>Number.isFinite(s.longitude??s.lng)&&Number.isFinite(s.latitude??s.lat));const lng=data.query?.longitude??first?.longitude??first?.lng??-115.1398,lat=data.query?.latitude??first?.latitude??first?.lat??36.1699;\r\n  geographicMap=new lib.Map({container:node,style:'https://tiles.openfreemap.org/styles/liberty',center:[lng,lat],zoom:11,pitch:35,attributionControl:true});geographicMap.addControl(new lib.NavigationControl({showCompass:false}),'top-right');geographicMap.on('moveend',()=>{if(!alive())return;clearTimeout(viewportTimer);viewportTimer=setTimeout(()=>{if(alive()&&geographicMap)void refresh();},450);});\r\n  geographicMap.on('error',()=>{if(alive())node.setAttribute('aria-label','Map tiles may be unavailable. Public sites and sectors remain listed below.');});\r\n  const activeMap=geographicMap;activeMap.on('load',()=>{if(!alive()||geographicMap!==activeMap)return;data=latestData||data;const map=activeMap,style=map.getStyle(),buildingLayer=style.layers?.find(l=>l['source-layer']==='building');if(buildingLayer){try{map.addLayer({id:'cw-alien-building-masses',type:'fill',source:buildingLayer.source,'source-layer':'building',minzoom:13,paint:{'fill-color':'#526b69','fill-opacity':.5}});}catch{}}\r\n   syncNodeSprites(map,data);privateDropPins=mountPrivateDropPins(map,client,{signal:abort.signal});\r\n   const features=[];for(const s of sites){const x=s.longitude??s.lng,y=s.latitude??s.lat;if(Number.isFinite(x)&&Number.isFinite(y))features.push({type:'Feature',geometry:{type:'Point',coordinates:[x,y]},properties:{label:s.label||s.name||s.id}});}map.addSource('cw-public-hubs',{type:'geojson',data:{type:'FeatureCollection',features}});map.addLayer({id:'cw-public-hubs',type:'circle',source:'cw-public-hubs',paint:{'circle-radius':8,'circle-color':'#d5d9a5','circle-stroke-color':'#142c32','circle-stroke-width':3}});\r\n   const patches=(data.sectors||[]).map(s=>({...s,geometry:s.geometry||s.polygonGeoJSON||(Array.isArray(s.polygon)?{type:'Polygon',coordinates:[[...s.polygon,s.polygon[0]]]}:null)})).filter(s=>s.geometry?.type==='Polygon').map(s=>({type:'Feature',geometry:s.geometry,properties:{color:FACTION_BY_ID[s.controller||s.faction]?.color||'#8a9795',phase:s.phase||'neutral'}}));{map.addSource('cw-public-territory',{type:'geojson',data:{type:'FeatureCollection',features:patches}});map.addLayer({id:'cw-public-territory',type:'fill',source:'cw-public-territory',paint:{'fill-color':['get','color'],'fill-opacity':.24}});map.addLayer({id:'cw-public-territory-borders',type:'line',source:'cw-public-territory',paint:{'line-color':['get','color'],'line-width':2}});}\r\n   const friends=(data.friends||[]).filter(f=>f.home?.consent===true&&Number.isFinite(f.home.latitude)&&Number.isFinite(f.home.longitude)).map(f=>({type:'Feature',geometry:{type:'Point',coordinates:[f.home.longitude,f.home.latitude]},properties:{label:f.publicId}}));{map.addSource('cw-shared-friend-landmarks',{type:'geojson',data:{type:'FeatureCollection',features:friends}});map.addLayer({id:'cw-shared-friend-landmarks',type:'circle',source:'cw-shared-friend-landmarks',paint:{'circle-radius':15,'circle-color':'#e8e7b0','circle-stroke-width':5,'circle-stroke-color':'#5c8978'}});map.addLayer({id:'cw-shared-friend-names',type:'symbol',source:'cw-shared-friend-landmarks',layout:{'text-field':['get','label'],'text-offset':[0,-2],'text-size':12},paint:{'text-color':'#f5efd4','text-halo-color':'#152631','text-halo-width':2}});}\r\n  });\r\n }catch{releaseMap();ownClaim?.();if(alive()&&node.isConnected)node.replaceWith(text('p','Geographic tiles are unavailable. Use the public hub list and official access links below.','cw-note'));}}\r\n function render(data){latestData=data;updatePublicTerritory(data);if(data.preview)error.textContent='Read-only world preview. Sign in for live territory control.';const sites=q('[data-sites]'),map=q('[data-map]'),select=q('[data-site]'),retained=geographicMap?map.querySelector('.cw-map'):null;if(!retained)releaseMap();sites.replaceChildren();map.replaceChildren();select.replaceChildren();const sectors=data.sectors||[];\r\n  const geographic=retained||document.createElement('div');geographic.className='cw-map';geographic.setAttribute('aria-label','Existing geographic map with anonymous building masses and public meetup hubs');map.append(geographic,text('p','Map: OpenFreeMap / OpenStreetMap contributors. Building masses are existing map geometry, not player homes. Ground fog never grants access to private bases.','cw-note'));if(!retained)void mountGeographicMap(geographic,data,generation);else{const friends=(data.friends||[]).filter(f=>f.home?.consent===true&&Number.isFinite(f.home.latitude)&&Number.isFinite(f.home.longitude)).map(f=>({type:'Feature',geometry:{type:'Point',coordinates:[f.home.longitude,f.home.latitude]},properties:{label:f.publicId}}));geographicMap.getSource('cw-shared-friend-landmarks')?.setData({type:'FeatureCollection',features:friends});const patches=sectors.map(s=>({...s,geometry:s.geometry||s.polygonGeoJSON||(Array.isArray(s.polygon)?{type:'Polygon',coordinates:[[...s.polygon,s.polygon[0]]]}:null)})).filter(s=>s.geometry?.type==='Polygon').map(s=>({type:'Feature',geometry:s.geometry,properties:{color:FACTION_BY_ID[s.controller||s.faction]?.color||'#8a9795',phase:s.phase||'neutral'}}));geographicMap.getSource('cw-public-territory')?.setData({type:'FeatureCollection',features:patches});syncNodeSprites(geographicMap,data);geographicMap.resize();}\r\n  const nodes=buildWorldNodes(sectors,data.sites||[]);map.append(text('p',`${nodes.filter(n=>n.type==='resource').length} resource formations / ${nodes.filter(n=>n.type==='public-node').length} public relays. Scenery uses public territory data; resource harvesting is not enabled.`,'cw-note'));\r\n  const patchCount=new Set(sectors.map(s=>s.initialPatchId).filter(Boolean)).size;map.append(text('h3',patchCount?`${patchCount} biome patches / ${sectors.length} territory cells`:`${sectors.length} territory cells`),text('p','Homes stay under fog. Territory shown here comes from public sector anchors, never houses.','cw-note'));\r\n  const tiles=document.createElement('div');tiles.className='cw-sector-grid';\r\n  for(const s of sectors.slice(0,84)){const f=FACTION_BY_ID[s.controller||s.faction||s.controllerFaction],phase=s.phase||s.state||'neutral',tile=document.createElement('article');tile.className=`cw-sector-tile ${['warzone','contested','converting','healing'].includes(phase)?'is-scarred':''}`;tile.style.setProperty('--sector-color',f?.color||'#768793');tile.append(text('strong',s.label||f?.name||'Unclaimed frontier'),text('span',`Sector ${String(s.id).slice(-9,-3).toUpperCase()}`),text('b',phase.toUpperCase()));const progress=Number(s.conversionProgress??s.progress);if(Number.isFinite(progress))tile.append(text('small',`Conversion ${Math.round(progress<=1?progress*100:progress)}%`));tiles.append(tile);}\r\n  map.append(tiles);if(data.query?.truncated||data.truncated)map.append(text('p','This public map response is bounded. Pan or zoom and refresh to inspect another area.','cw-note'));if(!sectors.length)map.append(text('p','No public sectors are available here yet. No private home geometry is shown.'));\r\n  for(const site of data.sites||[]){const card=document.createElement('article');card.className='cw-card';const territory=publicThemeAt(data.sectors||[],site.latitude,site.longitude),f=FACTION_BY_ID[territory.faction]||FACTION_BY_ID[site.faction||site.biome];card.dataset.phase=territory.phase;card.append(text('span',site.kind==='battle'?'BATTLE SECTOR':'PUBLIC HUB','cw-eyebrow'),text('h3',site.label||site.name||site.id),text('p',`${f?.name||'Public alien outpost'} · ${site.hours||'Check official access hours before visiting.'}`));const source=typeof site.source==='string'?site.source:site.source?.officialPage||site.url;if(source){const a=document.createElement('a');a.href=source;a.target='_blank';a.rel='noopener noreferrer';a.textContent='Official place / access information';card.append(a);}if(site.accessNote)card.append(text('p',site.accessNote,'cw-note'));const row=document.createElement('div');row.className='cw-actions';const visit=document.createElement('button');visit.textContent='Visit this hub';visit.onclick=()=>cmd({type:'visit',siteId:site.id}).then(s=>{if(alive())error.textContent=s.result?.message||'Visit recorded.';}).catch(report);row.append(visit);card.append(row);\r\n   if(f){const art=document.createElement('canvas');art.width=140;art.height=90;art.className='cw-hub-art';art.setAttribute('aria-label',`${f.name} public outpost`);drawBuilding(art.getContext('2d'),{level:3,w:3,h:2,job:territory.phase==='stable'?null:{}},f,45,45,16);if(territory.phase!=='stable'){const c=art.getContext('2d');c.fillStyle='#111a21';for(let i=0;i<8;i++)c.fillRect(25+i*11,73+(i%2)*5,8,5);}card.prepend(art);card.append(text('p',`${data.preview?'Seeded initial theme':'Territory theme'}: ${f.name} / ${territory.phase}`,'cw-note'));}\r\n   card.append(text('p','NPC cosmetic shop · purchases require a fresh visit at this hub. Player-made marketplace comes later.','cw-note'));\r\n   visit.disabled=!client.authenticated;\r\n   for(const item of site.items||site.shop?.items||NPC_ITEMS){const button=document.createElement('button');button.textContent=`${item.label||item.name||item.id} · ${item.cost??item.price??'see price'}`;button.disabled=!client.authenticated;button.onclick=()=>cmd({type:'purchase',siteId:site.id,itemId:item.id}).then(()=>{if(alive())error.textContent='Purchase saved.';}).catch(report);row.append(button);}\r\n   sites.append(card);const option=document.createElement('option');option.value=site.id;option.textContent=site.label||site.name||site.id;select.append(option);\r\n  }\r\n  if(sectors.length>84)map.append(text('p',`Showing 84 of ${sectors.length} public cells in the list. Geographic territory includes all available cells.`,'cw-note'));\r\n  for(const friend of data.friends||[]){const id=friend.publicId||friend.public_id;if(!id)continue;const card=document.createElement('section');card.className='cw-card';card.append(text('h3',`Connected: ${id}`),text('p','Home coordinates remain private unless separately shared.','cw-note'));const revoke=document.createElement('button');revoke.textContent='Revoke connection';revoke.onclick=()=>cmd({type:'friend-revoke',publicId:id}).then(()=>refresh()).catch(report);const share=document.createElement('button');share.textContent='Share my exact home with this friend';share.onclick=()=>cmd({type:'friend-location',publicId:id,shareLocation:true}).then(()=>{if(alive())error.textContent='Your exact home is now shared with this friend.';}).catch(report);const stopShare=document.createElement('button');stopShare.textContent='Stop sharing my home';stopShare.onclick=()=>cmd({type:'friend-location',publicId:id,shareLocation:false}).then(()=>{if(alive())error.textContent='Your exact home is private from this friend.';}).catch(report);const row=document.createElement('div');row.className='cw-actions';row.append(share,stopShare,revoke);card.append(row);sites.append(card);}\r\n }\r\n function stopWatch(){if(watch!=null)navigator.geolocation?.clearWatch(watch);watch=null;}\r\n async function stopWalk(){const active=walk;walk=null;stopWatch();q('[data-walk]').textContent='Begin a sector walk';status.textContent='GPS is off. Walk ended.';if(active)try{await cmd({type:'walk-stop',sessionId:active.id||active.sessionId,nonce:active.nonce});}catch(e){report(e);}}\r\n q('[data-walk]').onclick=async()=>{if(walk)return stopWalk();if(!q('[data-lawful-walk]').checked){status.textContent='Confirm that you are walking somewhere you are allowed to be.';return;}if(!navigator.geolocation){status.textContent='Location is unavailable on this browser.';return;}q('[data-walk]').disabled=true;try{const snapshot=await cmd({type:'walk-start',confirmLawfulWalking:true});if(!alive())return;walk=snapshot.result?.session||snapshot.result?.walk||snapshot.walkSession||snapshot.result;if(!(walk?.id||walk?.sessionId)||!walk?.nonce)throw Error('Walk session was not returned. Retry.');seq=0;status.textContent='Waiting for GPS permission and an accurate fix…';q('[data-walk]').textContent='End sector walk';\r\n   watch=navigator.geolocation.watchPosition(async p=>{if(!alive()||!walk||sending)return;const active=walk;lastFix={latitude:p.coords.latitude,longitude:p.coords.longitude,accuracy:p.coords.accuracy,sampledAt:p.timestamp};status.textContent=`GPS accuracy ±${Math.round(p.coords.accuracy)} m · walking session active`;sending=true;try{const s=await cmd({type:'walk-sample',sessionId:active.id||active.sessionId,nonce:active.nonce,seq:++seq,latitude:p.coords.latitude,longitude:p.coords.longitude,accuracy:p.coords.accuracy,sampledAt:p.timestamp});if(alive()&&walk===active)status.textContent=s.result?.message||(s.result?.credited?'Influence accepted. Expansion remains war-torn while the control window resolves.':s.result?.status==='tracking'?`Tracking public sector / ${Math.floor((s.result.dwellMs||0)/1000)} s dwell / ${Math.round(s.result.movement||0)} m accepted movement`:`GPS checked: ${s.result?.status||'waiting'}. Only eligible open public ground earns influence.`);}catch(e){report(e);stopWatch();if(alive())status.textContent='Walk paused after a rejected sample. End this walk and start again.';}finally{sending=false;}},e=>{status.textContent=e.code===1?'GPS permission denied. No location samples sent.':'GPS fix unavailable. Move to open public ground or end the walk.';stopWatch();},{enableHighAccuracy:true,maximumAge:0,timeout:20000});\r\n  }catch(e){report(e);walk=null;stopWatch();}finally{if(alive())q('[data-walk]').disabled=false;}};\r\n q('[data-refresh]').onclick=refresh;\r\n q('[data-skyline]').onclick=()=>{if(!geographicMap){error.textContent='Wait for the geographic map to load.';return;}const map=geographicMap;error.textContent='Loading actual building footprints around the map center?';const capture=()=>{if(!alive()||geographicMap!==map)return;try{const data=rememberPublicGeography(map,latestData||{});error.textContent=`${data.buildings.length} existing mapped buildings prepared. Open Camera ? Mapped city skyline. OpenStreetMap attribution retained.`;}catch(e){report(e);}};if(map.getZoom()<15){map.once('idle',capture);map.easeTo({zoom:15,duration:500});}else if(map.isStyleLoaded())capture();else map.once('idle',capture);};\r\n q('[data-friend]').onclick=()=>cmd({type:'friend-invite'}).then(s=>{if(alive())q('[data-invite]').textContent=`Friend invite: ${s.result?.code||s.result?.invite?.code||'Created. Refresh to check status.'}`;}).catch(report);\r\n q('[data-accept-friend]').onclick=()=>cmd({type:'friend-accept',code:q('[data-friend-code]').value.trim()}).then(()=>{if(alive())q('[data-invite]').textContent='Friend connection saved.';}).catch(report);\r\n q('[data-battle]').onclick=()=>{if(!q('[data-public-path]').checked){error.textContent='Confirm your current spot is an ordinary open public path.';return;}if(!lastFix||Date.now()-lastFix.sampledAt>15000){error.textContent='Begin a sector walk and wait for a fresh GPS fix before inviting.';return;}cmd({type:'encounter-invite',targetPublicId:q('[data-target]').value.trim(),siteId:q('[data-site]').value,meetingAnchor:{latitude:lastFix.latitude,longitude:lastFix.longitude},confirmPublicPath:true}).then(s=>{if(alive()){const id=s.result?.encounterId||s.result?.encounter?.id||s.result?.id;q('[data-encounter]').value=id||'';error.textContent=id?`Battle invite ${id}`:'Invite sent.';}}).catch(report);};\r\n for(const action of ['accept','cancel'])q(`[data-${action}-battle]`).onclick=()=>cmd({type:`encounter-${action}`,encounterId:q('[data-encounter]').value.trim()}).then(s=>{if(alive())error.textContent=s.result?.status||`Battle ${action} saved.`;}).catch(report);\r\n q('[data-check-battle]').onclick=()=>client.encounter(q('[data-encounter]').value.trim()).then(s=>{if(alive())error.textContent=`Encounter: ${s.status||s.encounter?.status||'checked'}`;}).catch(report);\r\n const refreshTimer=setInterval(()=>{if(alive()&&client.authenticated&&!document.hidden)void refresh();},15000);\r\n if(!client.authenticated){for(const el of host.querySelectorAll('button,input,select'))el.disabled=true;q('[data-refresh]').disabled=false;q('[data-skyline]').disabled=false;error.textContent='Read-only world preview. Sign in for live territory control.';}void refresh();\r\n function dispose(){if(disposed)return;disposed=true;generation++;clearInterval(refreshTimer);clearTimeout(viewportTimer);stopWatch();walk=null;releaseMap();abort.abort();}signal?.addEventListener('abort',dispose,{once:true});globalThis.addEventListener('pagehide',dispose,{signal:abort.signal});return {dispose};\r\n}\r\n","modules/coach-world/navigation.mjs":"/* Grid BFS and waypoint walking adapted from StarNet worldmodel.js:2102–2127\n * and world.js:1861–1896 at 7ee93ceac14c6bcb500ab263e92186e3a2d8b5d7.\n * Copyright (c) 2026 Andrew Sims. MIT; full notice in STARNET-LICENSE.txt.\n * MYR5 changes: standalone ES module, bounded open grid, own building footprints,\n * deterministic decorative crew states. No StarNet artwork or service runtime.\n */\nimport {BUILDING_BY_ID} from './catalog.mjs';\nexport function findPath(cols,rows,blocked,start,target){\n const valid=p=>Number.isInteger(p.x)&&Number.isInteger(p.y)&&p.x>=0&&p.y>=0&&p.x<cols&&p.y<rows&&!blocked.has(p.y*cols+p.x);\n if(!valid(start)||!valid(target))return null;if(start.x===target.x&&start.y===target.y)return [];\n const from=start.y*cols+start.x,to=target.y*cols+target.x,prev=new Int32Array(cols*rows).fill(-1),queue=[from];prev[from]=from;\n for(let head=0;head<queue.length;head++){const at=queue[head];if(at===to)break;const x=at%cols,y=Math.floor(at/cols);for(const [nx,ny] of [[x+1,y],[x-1,y],[x,y+1],[x,y-1]]){if(!valid({x:nx,y:ny}))continue;const next=ny*cols+nx;if(prev[next]!==-1)continue;prev[next]=at;queue.push(next);}}\n if(prev[to]===-1)return null;const path=[];for(let at=to;at!==from;at=prev[at])path.push({x:at%cols,y:Math.floor(at/cols)});return path.reverse();\n}\nexport function occupancy(base){const blocked=new Set();for(const b of Object.values(base.buildings)){const d=BUILDING_BY_ID[b.id];if(!d||((b.level??1)<=0&&!b.job))continue;for(let y=b.y;y<b.y+d.h;y++)for(let x=b.x;x<b.x+d.w;x++)blocked.add(y*24+x);}return blocked;}\nfunction entrance(b,blocked,from){const d=BUILDING_BY_ID[b.id],points=[];for(let x=b.x;x<b.x+d.w;x++){points.push({x,y:b.y-1},{x,y:b.y+d.h});}for(let y=b.y;y<b.y+d.h;y++){points.push({x:b.x-1,y},{x:b.x+d.w,y});}return points.filter(p=>p.x>=0&&p.x<24&&p.y>=0&&p.y<24&&!blocked.has(p.y*24+p.x)).sort((a,c)=>Math.hypot(a.x-from.x,a.y-from.y)-Math.hypot(c.x-from.x,c.y-from.y))[0];}\nexport function createWanderers(count=9){return Array.from({length:Math.min(64,count)},(_,i)=>({id:i,x:1+i%3,y:1+Math.floor(i/3),path:[],index:0,phase:i,state:'idle',target:null,cycle:0,waitUntil:0}));}\nexport function stepWanderers(crew,base,dt,now,{extraBlocked=new Set()}={}){\n const blocked=occupancy(base);for(const key of extraBlocked)blocked.add(key);const free=[];for(let y=0;y<24;y++)for(let x=0;x<24;x++)if(!blocked.has(y*24+x))free.push({x,y});const version=Object.values(base.buildings).map(b=>`${b.id}:${b.x}:${b.y}:${b.level}:${b.job?.builderId||''}:${b.job?.policy||''}`).join('|')+':'+[...extraBlocked].join(',');\n for(const w of crew){w.phase+=Math.max(0,Math.min(.1,dt))*7;if(base.rest){w.state='rest';continue;}if(blocked.has(Math.floor(w.y)*24+Math.floor(w.x))){const p=free[Math.min(w.id,free.length-1)];Object.assign(w,{x:p.x,y:p.y,path:[],index:0});}\n  const job=Object.values(base.buildings).find(b=>b.job?.policy==='occupied-worker'&&b.job.builderId===`crew-${w.id+1}`),target=job?entrance(job,blocked,w):null;\n  if(w.version!==version||(target&&w.target!==job.id)){w.path=[];w.index=0;w.version=version;w.target=job?.id??null;}\n  if(!w.path.length&&now>=w.waitUntil){const destination=target||free[(w.id*67+w.cycle++*47)%free.length],p=findPath(24,24,blocked,{x:Math.floor(w.x),y:Math.floor(w.y)},destination);w.path=p||[];w.index=0;if(!w.path.length){w.state=job?'building':'idle';w.waitUntil=now+(job?500:900+w.id*110);}}\n  const p=w.path[w.index];if(!p)continue;const dx=p.x-w.x,dy=p.y-w.y,d=Math.hypot(dx,dy),step=Math.min(.1,Math.max(0,dt))*1.7;if(d<=step){w.x=p.x;w.y=p.y;w.index++;if(w.index>=w.path.length){w.path=[];w.index=0;w.state=job?'building':'idle';w.waitUntil=now+700;}}else{w.x+=dx/d*step;w.y+=dy/d*step;w.state='walking';w.facing=dx<0?'left':'right';}\n }return crew;\n}\n","modules/coach-world/photo.mjs":"export function coverCrop(sw,sh,dw,dh){if(![sw,sh,dw,dh].every(v=>Number.isFinite(v)&&v>0))throw Error('Camera frame is not ready.');const s=Math.max(dw/sw,dh/sh),w=dw/s,h=dh/s;return [(sw-w)/2,(sh-h)/2,w,h];}\nexport async function captureWorldPhoto({video,overlay,alive=()=>true}){\n if(!alive())throw new DOMException('Camera closed.','AbortError');const canvas=document.createElement('canvas');canvas.width=overlay.width;canvas.height=overlay.height;const c=canvas.getContext('2d');\n if(video?.srcObject){if(video.readyState<2)throw Error('Wait for the camera image before taking a photo.');c.drawImage(video,...coverCrop(video.videoWidth,video.videoHeight,canvas.width,canvas.height),0,0,canvas.width,canvas.height);}else{c.fillStyle='#111f32';c.fillRect(0,0,canvas.width,canvas.height);}\n c.drawImage(overlay,0,0);const blob=await new Promise((resolve,reject)=>{try{canvas.toBlob(b=>b?resolve(b):reject(Error('Photo export failed.')),'image/png');}catch(e){reject(e);}});if(!alive())throw new DOMException('Camera closed.','AbortError');return blob;\n}\nexport function showPhotoPreview(blob,host,{signal}={}){\n const url=URL.createObjectURL(blob),card=document.createElement('section');card.className='cw-photo';const image=document.createElement('img');image.src=url;image.alt='Your captured Coach World scene';const close=document.createElement('button');close.textContent='Close photo';const download=document.createElement('a');download.href=url;download.download='myr5-world.png';download.textContent='Save PNG';download.className='cw-button';const share=document.createElement('button');share.textContent='Share';const status=document.createElement('p');status.setAttribute('role','status');\n const file=new File([blob],'myr5-world.png',{type:'image/png'});share.hidden=!navigator.canShare?.({files:[file]});share.onclick=async()=>{try{await navigator.share({files:[file]});}catch(e){if(e.name!=='AbortError')status.textContent='Sharing unavailable. Use Save PNG.';}};\n let released=false;const dispose=()=>{if(released)return;released=true;URL.revokeObjectURL(url);card.remove();};close.onclick=dispose;signal?.addEventListener('abort',dispose,{once:true});card.append(image,download,share,close,status);host.append(card);return dispose;\n}\n","modules/coach-world/pixel-art.mjs":"// Original MYR5 pixel architecture. Integer raster cells, no vector antialiasing.\n// Editable PNG/Piskel exports: scripts/export-world-sprites.mjs.\nimport {FACTION_BY_ID} from './catalog.mjs';\nimport {SPRITE_OVERRIDES} from './pixel-overrides.mjs';\nexport const SPRITE_SIZE=64;\nexport const ART_KINDS=Object.freeze(['hq','hall','building','ship','resource','shop','node','rubble','crew','production','expedition','foundation','drop']);\nexport const ART_DIRECTION=Object.freeze({\n chest:{motif:'Faceted wedge crowns',shape:'wedge',material:'beveled ceramic armor',rule:'Crest and diamond planes over broad shoulders and a narrow waist.'},\n quads:{motif:'Stacked oval pylons',shape:'pylon',material:'segmented load-bearing stone',rule:'Egg-shaped drums taper upward from paired broad foundations.'},\n glutes:{motif:'Pearl pod vaults',shape:'pod',material:'rounded living pearl',rule:'Stacked positive-volume spheres, bubble joints and a heavy lower core.'},\n 'arms-shoulders':{motif:'Branching canopy foundries',shape:'canopy',material:'ribbed shell and mechanical branches',rule:'One shoulder canopy carries paired radial arms.'},\n yoga:{motif:'Suspended curl sanctuaries',shape:'curl',material:'flowing translucent ceramic',rule:'Unplanted S stems and hooked ribbon tips float above their foundations.'},\n 'martial-arts':{motif:'Folded plate bastions',shape:'fan',material:'creased armored plates',rule:'Blunt monoliths unfold into ribbed fan helmets on compact braced feet.'},\n cardio:{motif:'Open-core relay towers',shape:'ring',material:'light skeletal alloy',rule:'Negative-space rings, suspended discs and lean open struts.'}\n});\nconst rasters=new Map(),canvases=new Map();\nconst hex=c=>[parseInt(c.slice(1,3),16),parseInt(c.slice(3,5),16),parseInt(c.slice(5,7),16)];\nconst mix=(a,b,t)=>'#'+hex(a).map((n,i)=>Math.round(n+(hex(b)[i]-n)*t).toString(16).padStart(2,'0')).join('');\nexport function spritePalette(faction){if(faction==='neutral')return ['#00000000','#141b20','#293136','#3d464b','#576269','#748087','#9ca6ab','#c4cccf','#e3e7e5','#11191e','#81969b','#b3c1c4'];const f=FACTION_BY_ID[faction]||FACTION_BY_ID.chest;return ['#00000000','#101c29','#243342',f.dark,mix(f.dark,f.color,.48),f.color,mix(f.color,f.accent,.42),f.accent,'#eef0ce','#111b25','#75cbc1','#b5eee0'];}\nfunction raster(){\n const cells=new Uint8Array(4096),p=(x,y,c)=>{x=Math.round(x);y=Math.round(y);if(x>=0&&x<64&&y>=0&&y<64)cells[y*64+x]=c;};\n const rect=(x,y,w,h,c)=>{for(let j=Math.round(y);j<Math.round(y+h);j++)for(let i=Math.round(x);i<Math.round(x+w);i++)p(i,j,c);};\n const line=(x0,y0,x1,y1,c,width=1)=>{x0=Math.round(x0);y0=Math.round(y0);x1=Math.round(x1);y1=Math.round(y1);const dx=Math.abs(x1-x0),sx=x0<x1?1:-1,dy=-Math.abs(y1-y0),sy=y0<y1?1:-1;let e=dx+dy;for(;;){rect(x0,y0,width,width,c);if(x0===x1&&y0===y1)break;const e2=2*e;if(e2>=dy){e+=dy;x0+=sx;}if(e2<=dx){e+=dx;y0+=sy;}}};\n const poly=(pts,c)=>{const min=Math.max(0,Math.floor(Math.min(...pts.map(v=>v[1])))),max=Math.min(63,Math.ceil(Math.max(...pts.map(v=>v[1]))));for(let y=min;y<=max;y++)for(let x=0;x<64;x++){let inside=false;for(let i=0,j=pts.length-1;i<pts.length;j=i++){const a=pts[i],b=pts[j];if((a[1]>y)!==(b[1]>y)&&x<(b[0]-a[0])*(y-a[1])/(b[1]-a[1])+a[0])inside=!inside;}if(inside)p(x,y,c);}};\n const ellipse=(cx,cy,rx,ry,c)=>{for(let y=Math.floor(cy-ry);y<=cy+ry;y++)for(let x=Math.floor(cx-rx);x<=cx+rx;x++)if(((x-cx)/rx)**2+((y-cy)/ry)**2<=1)p(x,y,c);};\n const bevel=(pts,c=5)=>{poly(pts,1);const cx=pts.reduce((n,a)=>n+a[0],0)/pts.length,cy=pts.reduce((n,a)=>n+a[1],0)/pts.length;poly(pts.map(([x,y])=>[x+(cx-x)*.12,y+(cy-y)*.12]),c);for(let i=0;i<pts.length-1;i++)if(pts[i+1][0]>=pts[i][0])line(pts[i][0]+1,pts[i][1]+1,pts[i+1][0]-1,pts[i+1][1]+1,6);};\n const orb=(cx,cy,rx,ry)=>{ellipse(cx,cy,rx+1,ry+1,1);ellipse(cx,cy,rx,ry,3);ellipse(cx-1,cy-2,rx-1,ry-2,5);ellipse(cx-2,cy-3,Math.max(1,rx-3),Math.max(1,ry-4),6);rect(cx-rx+3,cy-ry+3,3,2,7);};\n return {cells,p,rect,line,poly,ellipse,bevel,orb};\n}\nfunction emblem(r,shape,cx,cy,size=8){const {line,ellipse,rect,poly}=r;\n if(shape==='wedge')poly([[cx,cy-size],[cx+size,cy],[cx,cy+size*.6],[cx-size,cy]],7);\n if(shape==='pylon'){ellipse(cx,cy,size*.65,size,7);line(cx-size*.65,cy,cx+size*.65,cy,4);}\n if(shape==='pod'){ellipse(cx,cy,size,size,7);ellipse(cx,cy,size*.55,size*.55,5);}\n if(shape==='canopy'){poly([[cx-size,cy],[cx-size*.6,cy-size*.6],[cx,cy-size],[cx+size*.6,cy-size*.6],[cx+size,cy]],7);for(const side of [-1,1])line(cx,cy,cx+side*size,cy+size*.6,6,2);}\n if(shape==='curl'){line(cx-size*.4,cy+size,cx+size*.4,cy,7,2);line(cx+size*.4,cy,cx-size*.4,cy-size*.5,7,2);line(cx-size*.4,cy-size*.5,cx,cy-size,7,2);}\n if(shape==='fan'){for(let i=-2;i<=2;i++)line(cx,cy+size*.5,cx+i*size*.4,cy-size+Math.abs(i),7);}\n if(shape==='ring'){ellipse(cx,cy,size,size*.7,7);ellipse(cx,cy,size-2,size*.7-2,3);}\n}\nexport function rasterSprite(factionId,kind='hq',variant=0){\n const id=factionId==='neutral'&&kind==='resource'?'neutral':Object.hasOwn(ART_DIRECTION,factionId)?factionId:'chest';kind=ART_KINDS.includes(kind)?kind:'building';variant=Math.max(0,Math.min(4,Math.floor(Number(variant)||0)));const key=`${id}/${kind}/${variant}`;if(rasters.has(key))return rasters.get(key);\n if(SPRITE_OVERRIDES[key]){const edited=SPRITE_OVERRIDES[key],result=Object.freeze({width:64,height:64,pixels:Uint8Array.from(edited.pixels),palette:Object.freeze(edited.palette),faction:id,kind,variant});rasters.set(key,result);return result;}\n const r=raster(),{rect,line,poly,ellipse,bevel,orb}=r,shape=id==='neutral'?'mineral':ART_DIRECTION[id].shape;\n // Every sprite has the same light from upper-left, dark one-cell contour and no half pixels.\n if(kind==='drop'){\n  ellipse(32,55,21,5,1);bevel([[13,29],[31,23],[51,30],[51,49],[32,56],[13,48]],4);poly([[32,26],[49,31],[49,47],[32,53]],3);bevel([[12,27],[31,20],[53,27],[53,33],[32,40],[12,33]],5);line(31,22,31,38,7,3);line(32,40,32,53,7,2);rect(25,36,12,8,1);rect(27,37,8,5,10);line(27,13,32,17,7,2);line(32,17,37,12,7,2);rect(30,8,3,3,8);\n }else if(kind==='foundation'){\n  poly([[32,37],[59,45],[59,51],[32,60],[5,51],[5,45]],1);poly([[32,39],[55,46],[32,54],[9,46]],3);line(10,47,31,40,6);line(32,55,54,47,4);for(const [x,y] of [[11,45],[32,39],[52,45],[32,52]]){rect(x-1,y-5,3,7,5);rect(x,y-7,2,2,7);}emblem(r,shape,32,46,5);\n }else if(kind==='rubble'){\n  ellipse(32,54,25,6,1);for(let i=0;i<9;i++){const x=11+(i*17)%43,y=43+(i*7)%12;bevel([[x,y-5],[x+6,y-2],[x+4,y+4],[x-4,y+2]],i%2?3:4);}line(19,48,28,41,2,2);rect(28,40,4,7,9);emblem(r,shape,45,43,5);\n }else if(kind==='resource'){\n  ellipse(32,56,23,5,1);ellipse(32,54,20,4,3);\n  if(shape==='pod'){orb(23,45,9,9);orb(38,39,11,13);orb(45,50,6,6);}\n  else if(shape==='curl'){for(let i=0;i<3;i++){const x=20+i*12;line(x,51,x+5,35-i*6,5,3);line(x+5,35-i*6,x,28-i*4,7,2);line(x,28-i*4,x+4,23-i*3,6,2);}}\n  else if(shape==='ring'){for(let i=0;i<2;i++){ellipse(24+i*18,39-i*8,9,12,1);ellipse(24+i*18,39-i*8,7,10,6);ellipse(24+i*18,39-i*8,4,7,0);}line(17,53,20,47,4,3);line(43,53,41,42,4,3);}\n  else if(shape==='wedge'){\n   bevel([[17,49],[21,29],[32,16],[45,31],[48,49],[33,56]],5);poly([[33,19],[43,32],[45,47],[33,52]],3);line(32,20,32,49,7,2);bevel([[8,50],[10,40],[17,32],[22,44],[22,52],[15,55]],4);bevel([[44,52],[48,37],[57,44],[55,53]],4);\n  }else if(shape==='pylon'){\n   for(const [x,y,h]of [[19,43,12],[42,37,20]]){ellipse(x,y+h-1,10,4,1);rect(x-9,y,18,h,3);ellipse(x,y,10,5,1);ellipse(x,y-1,8,3,6);for(let step=5;step<h;step+=5){ellipse(x,y+step,9,3,4);line(x-7,y+step,x+7,y+step,7);}line(x-7,y+2,x-7,y+h-2,5,2);}orb(42,25,7,9);\n  }else if(shape==='canopy'){\n   line(32,53,32,29,1,7);line(32,52,32,28,5,4);for(const side of [-1,1]){line(32,35,32+side*15,27,1,5);line(32,35,32+side*15,27,4,3);line(32+side*15,27,32+side*19,39,6,3);rect(32+side*19-4,38,8,9,1);rect(32+side*19-3,39,6,6,10);line(32,45,32+side*10,48,5,3);rect(32+side*10-3,48,6,7,3);}bevel([[8,23],[18,14],[32,10],[46,14],[56,23],[48,28],[16,28]],5);line(15,24,49,24,7);\n  }else if(shape==='fan'){\n   bevel([[11,47],[14,30],[22,18],[32,13],[44,20],[53,35],[52,49],[32,56]],4);for(const [x,y]of [[16,31],[23,21],[32,16],[42,23],[49,36]]){poly([[31,53],[x-2,y],[x+3,y-1],[35,51]],5);line(32,51,x,y,7);}bevel([[7,53],[10,44],[20,48],[18,56]],3);bevel([[43,54],[47,44],[57,48],[56,56]],3);\n  }else {for(let i=0;i<3;i++){const x=15+i*14,y=39-(i%2)*11;bevel([[x,y+14],[x-4,y+3],[x+3,y-5],[x+9,y+2],[x+8,y+15]],5);line(x+3,y-1,x+3,y+11,7);}}\n }else if(kind==='ship'){\n  ellipse(32,53,19+variant*2,3,2);\n  if(shape==='wedge'){bevel([[32,7],[42,25],[58,40],[52,46],[38,39],[32,47],[26,39],[12,46],[6,40],[22,25]],4);poly([[32,10],[38,32],[32,40],[26,32]],6);line(32,12,32,29,7);}\n  if(shape==='pylon'){for(const x of [19,45]){orb(x,36,8,12);line(x-6,37,x+6,37,3,2);}orb(32,24,13,18);line(20,22,44,22,3,2);line(20,29,44,29,3,2);ellipse(32,16,17,3,7);ellipse(32,16,10,1,4);}\n  if(shape==='pod'){orb(18,37,12,12);orb(46,37,12,12);orb(32,28,15,19);orb(32,16,9,9);orb(32,39,8,8);rect(29,35,5,5,10);}\n  if(shape==='canopy'){bevel([[5,26],[13,15],[27,10],[40,12],[53,18],[59,28],[44,35],[20,35]],5);for(const side of [-1,1])for(let i=0;i<3;i++){line(32+side*9,28+i*3,32+side*(20+i*2),38+i*4,3,4);line(32+side*9,28+i*3,32+side*(20+i*2),38+i*4,6);}bevel([[25,31],[39,31],[43,44],[32,49],[21,44]],4);line(12,27,52,28,7);}\n  if(shape==='curl'){for(const side of [-1,1]){const pts=[[32,45],[32+side*10,37],[32+side*18,28],[32+side*16,17],[32+side*8,13],[32+side*5,18]];for(let i=1;i<pts.length;i++)line(...pts[i-1],...pts[i],1,7);for(let i=1;i<pts.length;i++)line(...pts[i-1],...pts[i],5,5);for(let i=1;i<pts.length;i++)line(...pts[i-1],...pts[i],7);}orb(32,30,6,11);}\n  if(shape==='fan'){bevel([[7,28],[12,16],[22,10],[32,8],[44,12],[54,20],[58,30],[32,45]],5);for(const [x,y] of [[12,19],[21,13],[31,11],[42,15],[51,22],[54,29]]){line(32,41,x,y,3,2);line(33,40,x+1,y,6);}bevel([[21,42],[32,34],[43,42],[39,49],[25,49]],3);}\n  if(shape==='ring'){ellipse(32,28,25,17,1);ellipse(32,27,23,15,5);ellipse(32,27,16,10,0);line(12,20,22,15,7,2);bevel([[32,8],[38,17],[36,24],[28,24],[26,17]],6);rect(29,33,6,13,4);line(15,36,24,46,6,2);line(48,36,40,46,4,2);}\n  rect(21,44,4,5,10);rect(39,44,4,5,10);rect(22,49,2,3,11);rect(40,49,2,3,11);\n }else if(kind==='crew'){\n  ellipse(32,57,12,3,1);\n  if(shape==='curl'){line(31,49,36,40,1,6);line(31,49,36,40,5,4);line(36,40,29,28,6,4);line(30,28,35,19,6,3);line(35,19,31,14,7,2);line(29,34,20,41,5,2);line(35,33,43,39,5,2);orb(32,27,5,7);}\n  else{if(shape==='pod'){orb(32,39,11,12);orb(32,22,10,10);orb(20,43,5,6);orb(44,43,5,6);}else{bevel([[25,33],[39,33],[40,45],[34,48],[25,45]],5);line(24,36,19,47,4,4);line(39,36,45,47,4,4);}\n   if(shape==='wedge')bevel([[24,19],[34,10],[42,19],[33,29],[25,26]],6);\n   if(shape==='pylon'){orb(32,23,8,11);line(21,22,43,22,7);line(26,36,38,36,3,2);}\n   if(shape==='canopy'){bevel([[18,23],[22,16],[32,12],[40,15],[47,24],[40,29],[22,28]],5);for(const side of [-1,1]){line(32+side*7,35,32+side*16,42,5,3);line(32+side*7,40,32+side*14,49,6,3);}}\n   if(shape==='fan'){bevel([[22,19],[27,13],[34,11],[42,17],[44,24],[32,30]],5);for(let i=0;i<5;i++)line(32,28,24+i*4,16,7);}\n   if(shape==='ring'){ellipse(32,38,10,12,6);ellipse(32,38,7,9,0);bevel([[20,21],[32,16],[44,21],[32,27]],5);}\n   rect(25,47,5,10,4);rect(35,47,5,10,4);rect(24,55,7,3,6);rect(34,55,7,3,6);}\n }else {\n  // Three-quarter ground plinth anchors every tier to a shared world scale.\n  poly([[32,42],[61,49],[59,56],[32,63],[3,55],[3,49]],1);poly([[32,43],[58,49],[32,57],[6,49]],4);poly([[6,50],[32,57],[32,60],[6,53]],3);poly([[33,57],[58,50],[58,54],[33,61]],2);line(10,49,30,44,6);line(33,58,53,52,5);\n  if(variant>=1){for(const x of [6,58]){line(x,49,x,29-variant*4,3,3);emblem(r,shape,x,28-variant*4,4);rect(x-2,47,5,6,4);}}\n  if(variant>=2){for(const x of [12,51]){bevel([[x-5,37],[x,29],[x+5,37],[x+4,49],[x-4,51]],4);emblem(r,shape,x,37,3);}}\n  if(variant>=3){line(32,8,32,1,7,2);for(const x of [3,60]){rect(x-1,18,3,7,3);rect(x,18,1,4,10);}line(5,26,12,31,6);line(59,26,51,31,6);}\n  if(variant>=4){for(const x of [6,57]){orb(x,35,5,8);emblem(r,shape,x,25,4);line(x,26,x,36,7);}line(5,43,13,45,10,2);line(51,45,59,43,10,2);}\n  if(shape==='wedge'){\n   bevel([[11,31],[31,21],[52,29],[51,48],[31,56],[11,48]],4);poly([[31,23],[51,30],[50,46],[31,53]],3);bevel([[8,29],[27,10],[39,9],[56,28],[32,38]],5);poly([[29,12],[34,12],[36,32],[31,35]],7);poly([[36,12],[52,27],[38,32]],4);line(13,30,28,36,6);bevel([[16,34],[25,38],[25,48],[16,45]],5);bevel([[38,38],[46,34],[46,44],[38,48]],3);rect(28,39,7,12,1);line(29,40,29,49,10);line(34,40,34,49,5);\n  }else if(shape==='pylon'){\n   for(const x of [17,45]){bevel([[x-7,43],[x+5,40],[x+8,51],[x-4,55]],4);orb(x,32,8,16);line(x-6,32,x+6,34,3);line(x-6,37,x+6,39,3);}\n   orb(31,26,13,18);ellipse(31,20,14,5,1);ellipse(31,19,13,4,6);line(18,28,43,29,3,2);line(20,36,42,37,3,2);rect(27,39,8,13,1);rect(29,40,3,10,10);orb(31,12,6,9);\n  }else if(shape==='pod'){\n   orb(17,43,10,11);orb(47,43,10,11);orb(32,37,18,18);orb(32,18,13,12);orb(31,14,9,8);ellipse(32,40,9,10,1);ellipse(32,39,7,8,3);ellipse(31,37,5,6,10);ellipse(29,35,2,2,11);line(18,47,23,52,6,2);line(43,49,47,46,5,2);orb(13,51,5,5);orb(51,51,5,5);\n  }else if(shape==='canopy'){\n   for(const side of [-1,1])for(let i=0;i<3;i++){const x=32+side*(15+i*3),y=28+i*8;line(32+side*6,25+i*7,x,y,1,5);line(32+side*6,25+i*7,x,y,4,3);line(x,y,x+side*3,y+6,6,3);rect(x+side*3-2,y+5,6,4,3);rect(x+side*3-1,y+5,3,2,7);}\n   bevel([[26,24],[38,24],[42,49],[33,55],[23,49]],5);bevel([[4,24],[13,12],[28,6],[39,7],[53,16],[59,25],[49,31],[16,31]],5);poly([[32,8],[52,17],[56,25],[32,26]],4);line(9,25,53,26,7);for(let i=0;i<6;i++)line(15+i*6,27,16+i*6,30,3);rect(28,37,8,13,1);rect(30,38,3,10,10);\n  }else if(shape==='curl'){\n   ellipse(32,50,18,5,3);ellipse(32,47,16,3,6);ellipse(32,47,11,1,1);\n   const paths=[[[31,44],[40,35],[35,27],[25,23],[24,16],[33,11],[39,13]],[[23,41],[15,34],[16,27],[21,25]],[[42,40],[50,33],[49,25],[45,23]]];\n   for(const pts of paths){for(let i=1;i<pts.length;i++)line(...pts[i-1],...pts[i],1,6);for(let i=1;i<pts.length;i++)line(...pts[i-1],...pts[i],5,4);for(let i=1;i<pts.length;i++)line(pts[i-1][0],pts[i-1][1],pts[i][0],pts[i][1],7);}\n   orb(32,28,7,7);rect(30,27,4,3,11);for(const [x,y] of [[22,13],[44,18],[16,43]]){rect(x,y,2,2,7);}\n  }else if(shape==='fan'){\n   bevel([[13,38],[26,32],[38,32],[51,38],[47,52],[32,57],[17,52]],4);bevel([[7,25],[13,14],[22,7],[32,5],[43,9],[53,17],[58,27],[33,39]],5);poly([[33,7],[43,10],[54,25],[33,35]],4);for(const [x,y] of [[13,17],[21,10],[30,7],[40,10],[49,17],[54,25]]){line(32,35,x,y,3);line(33,34,x+1,y,6);}rect(24,38,17,6,3);rect(27,39,4,2,7);rect(34,39,4,2,7);bevel([[21,45],[28,45],[26,55],[16,54]],5);bevel([[38,45],[45,45],[48,53],[38,56]],3);rect(29,46,7,10,1);line(30,47,30,54,10);\n  }else if(shape==='ring'){\n   for(const x of [18,45]){line(x,49,x+(x<32?7:-7),28,1,5);line(x,49,x+(x<32?7:-7),28,5,3);bevel([[x-5,49],[x+5,48],[x+7,53],[x-4,56]],4);}\n   ellipse(32,30,17,17,1);ellipse(32,29,15,16,5);ellipse(32,29,10,11,0);line(21,18,26,14,7,2);line(17,29,17,34,6,2);bevel([[8,13],[30,5],[53,12],[55,17],[33,24],[9,19]],5);poly([[33,7],[52,13],[52,17],[33,21]],3);line(12,14,29,8,7);rect(29,43,7,8,3);rect(31,44,2,6,10);\n  }\n  // Common authored service details; tier bits change infrastructure, never faction identity.\n  for(let i=0;i<variant+1;i++){rect(8+i*5,53+i%2,3,2,7);rect(48-i*4,53,2,2,10);}\n  if(kind==='shop'||kind==='node'){bevel([[14,38],[32,34],[50,38],[48,44],[16,44]],4);for(let i=0;i<7;i++)rect(16+i*4,39,2,4,i%2?6:3);rect(24,45,16,7,1);rect(26,46,12,3,10);}\n  if(kind==='hall')emblem(r,shape,32,29,6);\n  if(kind==='building'){rect(7,44,7,7,3);rect(8,45,5,2,6);line(8,49,12,49,1);}\n  if(kind==='production'){for(const x of [8,53]){bevel([[x-5,38],[x+5,36],[x+7,50],[x,54],[x-6,50]],4);rect(x-3,41,6,7,1);rect(x-2,42,4,3,10);emblem(r,shape,x,33,5);}bevel([[18,47],[32,43],[46,48],[43,57],[21,57]],3);for(let i=0;i<4;i++)line(23+i*5,49,23+i*5,54,6);}\n  if(kind==='expedition'){bevel([[6,46],[31,39],[59,46],[56,55],[31,63],[7,55]],3);ellipse(32,49,19,6,7);ellipse(32,49,16,4,3);line(14,49,49,49,7);line(31,44,31,54,7);for(const x of [7,56]){rect(x,24,2,25,4);poly([[x+1,24],[x+(x<32?9:-8),27],[x+1,31]],7);}emblem(r,shape,32,49,4);}\n }\n const result=Object.freeze({width:64,height:64,pixels:r.cells,palette:Object.freeze(spritePalette(id)),faction:id,kind,variant});rasters.set(key,result);return result;\n}\nexport function getSpriteCanvas(factionId,kind='hq',variant=0){const sprite=rasterSprite(factionId,kind,variant),key=`${sprite.faction}/${sprite.kind}/${sprite.variant}`;if(canvases.has(key))return canvases.get(key);const canvas=document.createElement('canvas');canvas.width=64;canvas.height=64;const ctx=canvas.getContext('2d'),image=ctx.createImageData(64,64),colors=sprite.palette.map((c,i)=>i?hex(c):[0,0,0]);for(let i=0;i<4096;i++){const color=sprite.pixels[i],offset=i*4;image.data[offset]=colors[color][0];image.data[offset+1]=colors[color][1];image.data[offset+2]=colors[color][2];image.data[offset+3]=color?255:0;}ctx.putImageData(image,0,0);canvases.set(key,canvas);return canvas;}\n","modules/coach-world/pixel-overrides.mjs":"// Pixel-editor imports live here. Run scripts/import-world-sprite.py after editing an exported PNG.\nexport const SPRITE_OVERRIDES=Object.freeze({});\n","modules/coach-world/private-drop-pins.mjs":"import {getSpriteCanvas} from './pixel-art.mjs';\n// Owner-only transient overlay. Never pass these features into public geography.\nexport function mountPrivateDropPins(map,client,{signal}={}){\n if(!client.authenticated)return {dispose(){}};let disposed=false,generation=0;const source='cw-private-drop-pins',layer=source,alive=()=>!disposed&&!signal?.aborted;\n const clear=()=>{try{map.getSource(source)?.setData({type:'FeatureCollection',features:[]});}catch{}};\n async function refresh(){clear();const ticket=++generation;try{const data=await client.drops();if(!alive()||ticket!==generation)return;const features=data.locations.map(location=>({type:'Feature',geometry:{type:'Point',coordinates:[location.longitude,location.latitude]},properties:{kind:location.kind}})),value={type:'FeatureCollection',features};if(map.getSource(source))map.getSource(source).setData(value);else{const canvas=getSpriteCanvas(client.snapshot?.base?.faction,'drop');map.addImage('cw-private-drop-image',canvas.getContext('2d').getImageData(0,0,64,64),{pixelRatio:2});map.addSource(source,{type:'geojson',data:value});map.addLayer({id:layer,type:'symbol',source,layout:{'icon-image':'cw-private-drop-image','icon-anchor':'bottom','icon-allow-overlap':true,'icon-pitch-alignment':'viewport','icon-rotation-alignment':'viewport'}});}}catch{clear();}}\n const dispose=()=>{if(disposed)return;disposed=true;generation++;globalThis.removeEventListener('myr5:world-drops-updated',refresh);document.removeEventListener('visibilitychange',visibility);clear();try{if(map.getLayer?.(layer))map.removeLayer(layer);if(map.getSource(source))map.removeSource(source);if(map.hasImage?.('cw-private-drop-image'))map.removeImage('cw-private-drop-image');}catch{}};\n const visibility=()=>{if(document.hidden){generation++;clear();}else if(alive())void refresh();};globalThis.addEventListener('myr5:world-drops-updated',refresh);document.addEventListener('visibilitychange',visibility);signal?.addEventListener('abort',dispose,{once:true});void refresh();return {dispose};\n}\n","modules/coach-world/public-geography.mjs":"// Public OpenStreetMap geometry only. Never put account/base/presence data here.\r\nimport {distanceMeters,containsPoint,cellToLatLng} from './geo.mjs';\r\nimport {buildWorldNodes} from './world-nodes.mjs';\r\nlet cached=null,sequence=0;\r\nexport function publicThemeAt(sectors,latitude,longitude){\r\n let best=null,nearest=Infinity;for(const s of sectors){const geometry=s.geometry||s.polygonGeoJSON||(s.polygon?{type:'Polygon',coordinates:[s.polygon]}:null);let center;if(geometry){const ring=geometry.coordinates?.[0];if(ring?.length)center={latitude:ring.reduce((n,p)=>n+p[1],0)/ring.length,longitude:ring.reduce((n,p)=>n+p[0],0)/ring.length};if(containsPoint(geometry,latitude,longitude)){best=s;break;}}if(!center){try{const p=cellToLatLng(s.id);center={latitude:p[0],longitude:p[1]};}catch{continue;}}const d=distanceMeters({latitude,longitude},center);if(d<nearest){nearest=d;best=s;}}\r\n return {faction:best?.controller||best?.initialFaction||best?.faction||null,phase:best?.phase||'stable',revision:best?.revision||0,conversionProgress:best?.conversionProgress??1,sectorId:best?.id||null};\r\n}\r\nconst signature=sectors=>sectors.map(s=>`${s.id}:${s.controller||s.initialFaction||s.faction}:${s.phase}:${s.revision||0}:${s.conversionProgress??1}`).join('|');\r\nexport function updatePublicTerritory({sectors=[],sites=[],preview=false}={}){if(!cached)return;const next=signature(sectors),nodes=buildWorldNodes(sectors,sites),nodeSignature=JSON.stringify(nodes);if(cached.territorySignature===next&&cached.preview===preview&&cached.nodeSignature===nodeSignature)return;for(const b of cached.buildings)Object.assign(b,publicThemeAt(sectors,b.latitude,b.longitude));cached={...cached,nodes,nodeSignature,preview,territorySignature:next,captureId:++sequence};}\r\nexport function rememberPublicGeography(map,{sectors=[],sites=[],preview=false}={}){\r\n if(!map?.isStyleLoaded())throw Error('Map tiles are still loading. Wait and retry.');const center=map.getCenter(),anchor={latitude:center.lat,longitude:center.lng},layers=map.getStyle().layers.filter(l=>l['source-layer']==='building').map(l=>l.id);if(!layers.length)throw Error('This map has no building footprints.');\r\n const seen=new Set(),buildings=[];for(const feature of map.queryRenderedFeatures({layers})){const polygons=feature.geometry.type==='Polygon'?[feature.geometry.coordinates]:feature.geometry.type==='MultiPolygon'?feature.geometry.coordinates:[];for(const polygon of polygons){const ring=polygon[0];if(!ring||ring.length<4)continue;const bounded=ring.slice(0,120).filter(p=>p.length>=2&&p.slice(0,2).every(Number.isFinite));if(bounded.length<4)continue;const key=bounded.map(p=>p.map(v=>v.toFixed(6)).join(',')).join(';');if(seen.has(key))continue;seen.add(key);const longitude=bounded.reduce((n,p)=>n+p[0],0)/bounded.length,latitude=bounded.reduce((n,p)=>n+p[1],0)/bounded.length,distance=distanceMeters(anchor,{latitude,longitude});if(distance>2000)continue;const raw=Number(feature.properties?.render_height??feature.properties?.height),height=Number.isFinite(raw)?Math.min(180,Math.max(3,raw)):8;buildings.push({ring:bounded.map(p=>p.slice(0,2)),latitude,longitude,height,distance});if(buildings.length>=3000)break;}if(buildings.length>=3000)break;}\r\n buildings.sort((a,b)=>a.distance-b.distance);buildings.splice(160);for(const b of buildings)Object.assign(b,publicThemeAt(sectors,b.latitude,b.longitude));\r\n if(!buildings.length)throw Error('No mapped building footprints are visible. Zoom into nearby city streets and retry.');const nodes=buildWorldNodes(sectors,sites);cached={anchor,buildings,nodes,nodeSignature:JSON.stringify(nodes),captureId:++sequence,territorySignature:signature(sectors),preview,capturedAt:Date.now(),attribution:'OpenFreeMap / © OpenStreetMap contributors',source:'https://tiles.openfreemap.org/styles/liberty'};return cached;\r\n}\r\nexport function readPublicGeography(){return cached&&Date.now()-cached.capturedAt<3600000?cached:null;}\r\nexport function localOffset(anchor,longitude,latitude){return {x:(longitude-anchor.longitude)*111320*Math.cos(anchor.latitude*Math.PI/180),z:-(latitude-anchor.latitude)*110540};}\r\nexport function cityMasses(geography,lod=914.4){const near=[],far=new Map();for(const b of geography.buildings){const points=b.ring.map(p=>localOffset(geography.anchor,p[0],p[1]));if(b.distance<lod){near.push({...b,points});continue;}const x=points.reduce((n,p)=>n+p.x,0)/points.length,z=points.reduce((n,p)=>n+p.z,0)/points.length,key=`${Math.floor(x/100)}:${Math.floor(z/100)}:${b.faction}:${b.phase}`,mass=far.get(key)||{x:Math.floor(x/100)*100+50,z:Math.floor(z/100)*100+50,height:0,faction:b.faction,phase:b.phase,conversionProgress:b.conversionProgress};mass.height=Math.max(mass.height,b.height);far.set(key,mass);}return {near,far:[...far.values()]};}\r\n","modules/coach-world/sites-data.mjs":"// Official Clark County recreation GIS; source URLs retained per site.\r\nexport const SITE_DATA=[{\"id\":\"vegas-chest-1\",\"name\":\"Lorenzi Park\",\"track\":\"chest\",\"faction\":\"chest\",\"latitude\":36.1792022,\"longitude\":-115.1860033,\"referenceCoordinate\":{\"latitude\":36.1792022,\"longitude\":-115.1860033,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.183435,36.181077],[-115.187862,36.181157],[-115.18788,36.181143],[-115.18789,36.181119],[-115.187923,36.177448],[-115.185554,36.177415],[-115.184234,36.177397],[-115.184228,36.178605],[-115.184198,36.179049],[-115.183977,36.179392],[-115.183702,36.179635],[-115.183342,36.179958],[-115.18325,36.18004],[-115.183226,36.180115],[-115.183234,36.180211],[-115.183301,36.180422],[-115.183366,36.180589],[-115.183425,36.180768],[-115.183456,36.180946],[-115.183435,36.181077]]],[[[-115.183242,36.180197],[-115.183245,36.180038],[-115.183323,36.179968],[-115.183438,36.179865],[-115.183637,36.179687],[-115.183826,36.179518],[-115.184,36.179356],[-115.184206,36.179035],[-115.184215,36.178901],[-115.184233,36.178625],[-115.184242,36.177383],[-115.181345,36.177392],[-115.181344,36.181027],[-115.183443,36.181063],[-115.183464,36.180932],[-115.183433,36.180754],[-115.183374,36.180575],[-115.183309,36.180408],[-115.183242,36.180197]]]]},\"hours\":\"07:00-23:00\",\"openingHours\":[7,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/5\",\"gisObjectIdField\":\"OBJECTID_1\",\"gisObjectIds\":[73,74],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/5/query?objectIds=73,74&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-5.json\",\"rawFeatureIds\":[73,74],\"rawPropertiesObjectIds\":[73,74],\"rawStatusCodes\":[1,1],\"officialPage\":\"https://www.lasvegasnevada.gov/Residents/Parks-Facilities/Lorenzi-Park\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-quads-1\",\"name\":\"Centennial Hills Park\",\"track\":\"quads\",\"faction\":\"quads\",\"latitude\":36.2854174,\"longitude\":-115.2627944,\"referenceCoordinate\":{\"latitude\":36.2854174,\"longitude\":-115.2627944,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.261461,36.287552],[-115.261492,36.287672],[-115.261603,36.287677],[-115.261849,36.287752],[-115.262442,36.287759],[-115.262646,36.28777],[-115.262818,36.28778],[-115.262942,36.28769],[-115.263132,36.287602],[-115.263178,36.28758],[-115.263356,36.287528],[-115.264966,36.287562],[-115.26504,36.284325],[-115.264855,36.284304],[-115.264646,36.284274],[-115.264285,36.284176],[-115.263966,36.28398],[-115.263792,36.283861],[-115.263707,36.283768],[-115.263605,36.283653],[-115.263534,36.28356],[-115.263427,36.283443],[-115.263231,36.283292],[-115.263129,36.283231],[-115.262945,36.283135],[-115.262747,36.283036],[-115.262533,36.282941],[-115.262433,36.282889],[-115.262316,36.282808],[-115.262208,36.28271],[-115.262068,36.282542],[-115.261965,36.2824],[-115.261867,36.282234],[-115.261796,36.282135],[-115.261696,36.281985],[-115.26151,36.2818],[-115.261289,36.281945],[-115.260806,36.282512],[-115.260684,36.282998],[-115.260642,36.283387],[-115.260537,36.28651],[-115.261403,36.286547],[-115.261397,36.286911],[-115.261307,36.287179],[-115.26092,36.28724],[-115.260784,36.287215],[-115.26071,36.287175],[-115.260618,36.287095],[-115.260581,36.287089],[-115.26055,36.287154],[-115.260543,36.287224],[-115.26053,36.287414],[-115.261227,36.287416],[-115.261382,36.287461],[-115.261461,36.287552]]],[[[-115.261502,36.288076],[-115.26157,36.288231],[-115.261546,36.289575],[-115.261452,36.28976],[-115.261366,36.289865],[-115.261285,36.289969],[-115.261143,36.290044],[-115.261118,36.290074],[-115.261142,36.290109],[-115.261278,36.290199],[-115.261302,36.290314],[-115.261431,36.29054],[-115.262613,36.290634],[-115.262638,36.289518],[-115.262633,36.28779],[-115.261837,36.287777],[-115.261621,36.287707],[-115.261516,36.287702],[-115.261502,36.288076]]]]},\"hours\":\"07:00-23:00\",\"openingHours\":[7,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/5\",\"gisObjectIdField\":\"OBJECTID_1\",\"gisObjectIds\":[65],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/5/query?objectIds=65&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-5.json\",\"rawFeatureIds\":[65],\"rawPropertiesObjectIds\":[65],\"rawStatusCodes\":[1],\"officialPage\":\"https://www.lasvegasnevada.gov/Residents/Parks-Facilities/Centennial-Hills-Park\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-glutes-2\",\"name\":\"Craig Ranch Regional Park\",\"track\":\"glutes\",\"faction\":\"glutes\",\"latitude\":36.2432799,\"longitude\":-115.1491227,\"referenceCoordinate\":{\"latitude\":36.2432799,\"longitude\":-115.1491227,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.146822,36.246436],[-115.146877,36.246466],[-115.146913,36.246485],[-115.146949,36.246503],[-115.146986,36.24652],[-115.147079,36.246564],[-115.147119,36.246583],[-115.147158,36.246603],[-115.147197,36.246623],[-115.147235,36.246644],[-115.147273,36.246666],[-115.14731,36.246688],[-115.147347,36.24671],[-115.147383,36.246733],[-115.147419,36.246757],[-115.147455,36.246781],[-115.147489,36.246806],[-115.147513,36.246822],[-115.147522,36.246828],[-115.147541,36.246839],[-115.147561,36.24685],[-115.14757,36.246856],[-115.147591,36.246866],[-115.147611,36.246875],[-115.147632,36.246884],[-115.147643,36.246889],[-115.147664,36.246897],[-115.147675,36.246901],[-115.147697,36.246908],[-115.147708,36.246911],[-115.14773,36.246917],[-115.147742,36.24692],[-115.147764,36.246926],[-115.147776,36.246928],[-115.147799,36.246932],[-115.147822,36.246936],[-115.147846,36.246939],[-115.147869,36.246941],[-115.147881,36.246942],[-115.147904,36.246943],[-115.147928,36.246944],[-115.14794,36.246944],[-115.152821,36.246941],[-115.153103,36.246941],[-115.154531,36.246921],[-115.154488,36.243158],[-115.154448,36.239561],[-115.153623,36.239559],[-115.153606,36.239567],[-115.153606,36.239559],[-115.15302,36.239558],[-115.148844,36.239606],[-115.148904,36.242955],[-115.145882,36.243039],[-115.143766,36.243098],[-115.14376,36.243185],[-115.143757,36.243235],[-115.143755,36.243325],[-115.143756,36.243375],[-115.143757,36.243426],[-115.143768,36.243683],[-115.143802,36.243682],[-115.143811,36.243892],[-115.143864,36.243973],[-115.143969,36.243924],[-115.143953,36.24367],[-115.14403,36.24368],[-115.144057,36.243689],[-115.144081,36.243698],[-115.144105,36.243706],[-115.144129,36.243714],[-115.144153,36.243721],[-115.144179,36.243728],[-115.144206,36.243735],[-115.144233,36.243741],[-115.14431,36.243755],[-115.144348,36.243762],[-115.144366,36.243765],[-115.144386,36.243767],[-115.144399,36.243768],[-115.14443,36.243769],[-115.144448,36.243769],[-115.144482,36.24377],[-115.14454,36.243768],[-115.144576,36.244615],[-115.144661,36.244554],[-115.14497,36.244564],[-115.145063,36.244706],[-115.145892,36.245467],[-115.146888,36.24636],[-115.146822,36.246436]]]]},\"hours\":\"06:00-23:00; source says seasonal changes possible\",\"openingHours\":[6,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/10\",\"gisObjectIdField\":\"OBJECTID_1\",\"gisObjectIds\":[11],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/10/query?objectIds=11&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-10.json\",\"rawFeatureIds\":[11],\"rawPropertiesObjectIds\":[12],\"rawStatusCodes\":[1],\"officialPage\":\"https://www.cityofnorthlasvegas.com/home/showpublisheddocument/5643/638169045960900000\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-arms-shoulders-1\",\"name\":\"Desert Breeze Park\",\"track\":\"arms-shoulders\",\"faction\":\"arms-shoulders\",\"latitude\":36.1258471,\"longitude\":-115.2759792,\"referenceCoordinate\":{\"latitude\":36.1258471,\"longitude\":-115.2759792,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.274399,36.129463],[-115.278954,36.129564],[-115.278968,36.12591],[-115.278981,36.122239],[-115.270005,36.122076],[-115.269992,36.123989],[-115.269981,36.125717],[-115.272992,36.125785],[-115.272955,36.127448],[-115.274316,36.127452],[-115.274399,36.129463]]]]},\"hours\":\"06:00-23:00 general county rule; posted exceptions/closures override\",\"openingHours\":[6,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6\",\"gisObjectIdField\":\"OBJECTID_12\",\"gisObjectIds\":[109],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6/query?objectIds=109&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-6.json\",\"rawFeatureIds\":[109],\"rawPropertiesObjectIds\":[109],\"rawStatusCodes\":[1],\"officialPage\":\"https://parkslocator.clarkcountynv.gov/Search/ParkDetail?parkId=3\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-chest-2\",\"name\":\"Sunset Park\",\"track\":\"chest\",\"faction\":\"chest\",\"latitude\":36.065258,\"longitude\":-115.1122018,\"referenceCoordinate\":{\"latitude\":36.065258,\"longitude\":-115.1122018,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.106059,36.069979],[-115.10606,36.070319],[-115.10606,36.070662],[-115.10606,36.070684],[-115.106061,36.071433],[-115.106984,36.071429],[-115.107753,36.071426],[-115.108616,36.071422],[-115.108601,36.070898],[-115.108568,36.069747],[-115.109143,36.069749],[-115.10969,36.06975],[-115.110182,36.069754],[-115.1108,36.069758],[-115.11082,36.070402],[-115.11084,36.071042],[-115.110852,36.07142],[-115.118298,36.071448],[-115.118334,36.071444],[-115.118367,36.071435],[-115.11841,36.071416],[-115.118447,36.071388],[-115.118467,36.071365],[-115.118484,36.071338],[-115.118493,36.07131],[-115.118497,36.071273],[-115.118327,36.064392],[-115.118327,36.064392],[-115.118217,36.059831],[-115.113819,36.0579],[-115.1139,36.060643],[-115.109398,36.060669],[-115.109419,36.061613],[-115.109517,36.064359],[-115.106053,36.064358],[-115.106058,36.066124],[-115.106058,36.067886],[-115.106058,36.067972],[-115.106061,36.069639],[-115.106059,36.069979]]],[[[-115.113806,36.057058],[-115.113789,36.057588],[-115.118196,36.059519],[-115.118196,36.059516],[-115.118133,36.057077],[-115.118122,36.057044],[-115.1181,36.057022],[-115.118066,36.057008],[-115.118002,36.057007],[-115.113806,36.057058]]]]},\"hours\":\"06:00-23:00 general county rule; posted exceptions/closures override\",\"openingHours\":[6,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6\",\"gisObjectIdField\":\"OBJECTID_12\",\"gisObjectIds\":[62],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6/query?objectIds=62&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-6.json\",\"rawFeatureIds\":[62],\"rawPropertiesObjectIds\":[62],\"rawStatusCodes\":[1],\"officialPage\":\"https://www.clarkcountynv.gov/government/departments/parks___recreation/services/area_reservations/sunset-park-webpage\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-quads-2\",\"name\":\"Cornerstone Park\",\"track\":\"quads\",\"faction\":\"quads\",\"latitude\":36.0361899,\"longitude\":-115.0533469,\"referenceCoordinate\":{\"latitude\":36.0361899,\"longitude\":-115.0533469,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.050198,36.038553],[-115.050232,36.038554],[-115.050233,36.038588],[-115.050237,36.038623],[-115.050245,36.038656],[-115.050255,36.038691],[-115.05027,36.038725],[-115.050286,36.038756],[-115.050305,36.038787],[-115.050327,36.038816],[-115.050353,36.038845],[-115.05038,36.038871],[-115.05041,36.038896],[-115.050442,36.038919],[-115.050477,36.03894],[-115.050512,36.038959],[-115.050549,36.038975],[-115.050588,36.038989],[-115.050996,36.039125],[-115.051019,36.039134],[-115.051041,36.039143],[-115.051062,36.039154],[-115.051083,36.039166],[-115.051102,36.03918],[-115.051121,36.039194],[-115.051138,36.039209],[-115.051152,36.039224],[-115.051185,36.03926],[-115.051233,36.038064],[-115.052812,36.038043],[-115.055603,36.038006],[-115.055604,36.037999],[-115.055605,36.037947],[-115.055611,36.037856],[-115.055613,36.037854],[-115.055617,36.037821],[-115.055622,36.037772],[-115.055638,36.037696],[-115.055638,36.037692],[-115.055674,36.037543],[-115.055699,36.037439],[-115.055718,36.037389],[-115.055772,36.037234],[-115.055837,36.037083],[-115.055867,36.037011],[-115.05591,36.036936],[-115.055921,36.036912],[-115.055983,36.0368],[-115.055991,36.036787],[-115.056034,36.036718],[-115.056085,36.036645],[-115.056141,36.036563],[-115.056184,36.036511],[-115.056217,36.03647],[-115.056294,36.036377],[-115.056305,36.036369],[-115.056376,36.036295],[-115.056396,36.036274],[-115.05642,36.03625],[-115.056538,36.03613],[-115.056643,36.036007],[-115.056643,36.036005],[-115.056713,36.035918],[-115.05674,36.03588],[-115.056767,36.035845],[-115.056829,36.03575],[-115.056901,36.035631],[-115.056909,36.035616],[-115.056947,36.035552],[-115.056971,36.035505],[-115.05698,36.035489],[-115.056985,36.03548],[-115.057009,36.035431],[-115.057047,36.035338],[-115.057091,36.035223],[-115.057101,36.035197],[-115.057134,36.035096],[-115.057145,36.035051],[-115.057183,36.034919],[-115.057183,36.034901],[-115.057205,36.034811],[-115.057219,36.034709],[-115.057233,36.034555],[-115.057239,36.034493],[-115.057122,36.034494],[-115.056943,36.034488],[-115.056764,36.034475],[-115.056585,36.034455],[-115.056409,36.034428],[-115.056234,36.034395],[-115.055779,36.0344],[-115.055785,36.03429],[-115.055785,36.034275],[-115.055658,36.034231],[-115.055538,36.034186],[-115.05542,36.034138],[-115.055305,36.034086],[-115.055247,36.034059],[-115.055135,36.034002],[-115.055025,36.033942],[-115.054918,36.033879],[-115.054814,36.033813],[-115.054548,36.033639],[-115.054467,36.033588],[-115.054418,36.033558],[-115.054318,36.0335],[-115.054266,36.033473],[-115.054163,36.03342],[-115.05411,36.033394],[-115.054003,36.033346],[-115.053949,36.03332],[-115.053894,36.033298],[-115.053783,36.033255],[-115.053671,36.033216],[-115.053556,36.033179],[-115.05344,36.033146],[-115.053323,36.033117],[-115.053205,36.03309],[-115.053085,36.033067],[-115.052965,36.033048],[-115.052844,36.033032],[-115.052722,36.033019],[-115.0526,36.03301],[-115.052477,36.033004],[-115.052354,36.033002],[-115.052232,36.033003],[-115.052109,36.033008],[-115.051987,36.033016],[-115.051865,36.033027],[-115.051743,36.033042],[-115.051623,36.033061],[-115.051503,36.033083],[-115.051443,36.033095],[-115.051325,36.033122],[-115.051208,36.033152],[-115.051093,36.033186],[-115.050979,36.033223],[-115.050866,36.033263],[-115.050755,36.033306],[-115.050647,36.033352],[-115.05054,36.033402],[-115.050436,36.033454],[-115.050333,36.033509],[-115.050232,36.033569],[-115.050226,36.034462],[-115.050201,36.038077],[-115.050198,36.038553]]]]},\"hours\":\"06:00-22:00\",\"openingHours\":[6,22],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/7\",\"gisObjectIdField\":\"OBJECTID_1\",\"gisObjectIds\":[50],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/7/query?objectIds=50&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-7.json\",\"rawFeatureIds\":[50],\"rawPropertiesObjectIds\":[138],\"rawStatusCodes\":[1],\"officialPage\":\"https://www.cityofhenderson.com/Home/Components/FacilityDirectory/FacilityDirectory/218/752?npage=1\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1},{\"id\":\"vegas-glutes-1\",\"name\":\"Mountains Edge Park\",\"track\":\"glutes\",\"faction\":\"glutes\",\"latitude\":36.004247,\"longitude\":-115.2700208,\"referenceCoordinate\":{\"latitude\":36.004247,\"longitude\":-115.2700208,\"method\":\"Shapely representative_point of union of same-name cached PKSTATUS=1 GIS polygons in EPSG:4326\",\"purpose\":\"Discovery reference ONLY; not a navigation target, meeting anchor or battle presence anchor\"},\"geometry\":{\"type\":\"MultiPolygon\",\"coordinates\":[[[[-115.270719,36.002378],[-115.270735,36.005036],[-115.270735,36.005047],[-115.272281,36.005016],[-115.272338,36.005015],[-115.273238,36.005006],[-115.273728,36.004995],[-115.273728,36.004992],[-115.273728,36.004991],[-115.273728,36.00499],[-115.273656,36.002351],[-115.273643,36.002351],[-115.273629,36.002351],[-115.273608,36.002351],[-115.272893,36.002358],[-115.272717,36.002359],[-115.272559,36.002361],[-115.270719,36.002378]]],[[[-115.26631,36.002431],[-115.266326,36.003504],[-115.266344,36.005195],[-115.268655,36.005117],[-115.268673,36.005117],[-115.270735,36.005047],[-115.270735,36.005036],[-115.270719,36.002378],[-115.26631,36.002431]]]]},\"hours\":\"06:00-23:00 general county rule; posted exceptions/closures override\",\"openingHours\":[6,23],\"timezone\":\"America/Los_Angeles\",\"enabled\":true,\"discoverable\":true,\"source\":{\"gisLayer\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6\",\"gisObjectIdField\":\"OBJECTID_12\",\"gisObjectIds\":[156,170],\"coordinateQuery\":\"https://maps.clarkcountynv.gov/arcgis/rest/services/OpenData/Recreation/MapServer/6/query?objectIds=156,170&outFields=*&outSR=4326&f=geojson\",\"rawSnapshot\":\"vegas-gis-layer-6.json\",\"rawFeatureIds\":[156,170],\"rawPropertiesObjectIds\":[169,183],\"rawStatusCodes\":[1,1],\"officialPage\":\"https://parkslocator.clarkcountynv.gov/Search/ParkDetail?parkId=104\",\"retrieved\":\"2026-10-16\"},\"referenceOnly\":true,\"meetingAnchor\":null,\"accessNote\":\"Choose an ordinary open public path; park reference is not a navigation or meeting point. Avoid water, roads, play equipment and restricted areas.\",\"inventoryVersion\":1}];\r\n","modules/coach-world/sites.mjs":"import {SITE_DATA} from './sites-data.mjs';\nimport {FACTIONS} from './catalog.mjs';\nimport {polygonToCells,cellToBoundary,cellToLatLng,latLngToCell,containsPoint,distanceMeters,neighbors} from './geo.mjs';\nexport const WORLD_SITES=Object.freeze(SITE_DATA.map(s=>Object.freeze({...s})));\nexport function isSiteOpen(site,now=Date.now()){if(!site?.enabled||!Number.isFinite(now))return false;const h=Number(new Intl.DateTimeFormat('en-US',{hour:'numeric',hourCycle:'h23',timeZone:site.timezone||'America/Los_Angeles'}).format(new Date(now)));const [a,b]=site.openingHours||[0,24];return a<=b?h>=a&&h<b:h>=a||h<b;}\n// Existing public-park polygons provide access candidates, not surveyed walking routes.\n// Six starting patches per hub are distinct from the seven maintained meetup/shop hubs.\nconst sectors=[],known=new Set();\nWORLD_SITES.forEach((site,siteIndex)=>{\n const cells=new Set();for(const poly of site.geometry.coordinates){try{for(const id of polygonToCells(poly,10,true))cells.add(id);}catch{}}\n const rows=[...cells].map(id=>{const [latitude,longitude]=cellToLatLng(id);return {id,latitude,longitude};}).filter(c=>containsPoint(site.geometry,c.latitude,c.longitude));\n rows.sort((a,b)=>distanceMeters(a,site)-distanceMeters(b,site)||a.id.localeCompare(b.id));\n const seeds=[];if(rows.length)seeds.push(rows[0]);while(seeds.length<Math.min(6,rows.length)){const next=rows.filter(c=>!seeds.includes(c)).sort((a,b)=>Math.min(...seeds.map(s=>distanceMeters(b,s)))-Math.min(...seeds.map(s=>distanceMeters(a,s)))||a.id.localeCompare(b.id))[0];seeds.push(next);}\n for(const row of rows){if(known.has(row.id))continue;known.add(row.id);let i=0,best=Infinity;seeds.forEach((s,j)=>{const d=distanceMeters(s,row);if(d<best){best=d;i=j;}});const faction=FACTIONS[(siteIndex*6+i)%7].id;\n  sectors.push(Object.freeze({...row,siteId:site.id,faction,initialFaction:faction,initialPatchId:`${site.id}-patch-${i}`,neighbors:neighbors(row.id),polygon:cellToBoundary(row.id,true),outpostFactions:seeds.some(s=>s.id===row.id)?FACTIONS.map(f=>f.id):[],enabled:true}));\n }\n});\nexport const WORLD_SECTORS=Object.freeze(sectors);\nexport const SECTOR_BY_ID=Object.freeze(Object.fromEntries(WORLD_SECTORS.map(s=>[s.id,s])));\nexport function locatePublicSector(latitude,longitude,accuracy=0,now=Date.now()){\n if(typeof accuracy!=='number'||!Number.isFinite(accuracy)||accuracy<0||accuracy>100)return {status:'ambiguous',sectorId:null,siteId:null};\n let cell;try{cell=latLngToCell(latitude,longitude,10);}catch{return {status:'outside',sectorId:null,siteId:null};}\n const sector=SECTOR_BY_ID[cell];if(!sector)return {status:'outside',sectorId:null,siteId:null};\n const site=WORLD_SITES.find(s=>s.id===sector.siteId);if(!site||!containsPoint(site.geometry,latitude,longitude))return {status:'outside',sectorId:cell,siteId:sector.siteId};\n if(!isSiteOpen(site,now))return {status:'closed',sectorId:cell,siteId:site.id};\n // Do not demand a GPS uncertainty disk fit a narrow sidewalk. Poor fixes stay ambiguous.\n let boundaryAmbiguous=false;if(accuracy>0){const latRadius=accuracy/111320,lngRadius=latRadius/Math.max(.05,Math.cos(latitude*Math.PI/180));for(let i=0;i<8;i++){const a=i*Math.PI/4;if(!containsPoint(site.geometry,latitude+Math.sin(a)*latRadius,longitude+Math.cos(a)*lngRadius)){boundaryAmbiguous=true;break;}}}\n return {status:accuracy>25||boundaryAmbiguous?'ambiguous':'inside',sectorId:cell,siteId:site.id,sector,site};\n}\nexport const COVERAGE=Object.freeze({metro:'Las Vegas valley',publicHubCount:WORLD_SITES.length,initialPatchCount:new Set(WORLD_SECTORS.map(s=>s.initialPatchId)).size,sectorCount:WORLD_SECTORS.length,physicalAnchorsVerified:0,referenceOnly:true});\n","modules/coach-world/sprite-billboards.mjs":"import {getSpriteCanvas} from './pixel-art.mjs';\r\n\r\nexport function createPixelBillboards(T,{getCanvas=getSpriteCanvas}={}){\r\n const group=new T.Group(),textures=new Map(),materials=new Set();let disposed=false;group.name='pixel-billboard-layer';\r\n return {group,add({faction='chest',kind='hq',variant=0,x=0,y=0,z=0,height=4,opacity=1,tint=0xffffff}={}){\r\n  if(disposed)throw Error('Pixel layer is disposed.');variant=Math.max(0,Math.min(4,Math.floor(variant)||0));const key=`${faction}:${kind}:${variant}`;let texture=textures.get(key);\r\n  if(!texture){const canvas=getCanvas(faction,kind,variant);texture=new T.CanvasTexture(canvas);texture.magFilter=texture.minFilter=T.NearestFilter;texture.generateMipmaps=false;texture.colorSpace=T.SRGBColorSpace;textures.set(key,texture);}\r\n  const material=new T.SpriteMaterial({map:texture,color:tint,transparent:true,opacity,alphaTest:.06,depthWrite:true,toneMapped:false});materials.add(material);const sprite=new T.Sprite(material),canvas=texture.image;sprite.center.set(.5,0);sprite.position.set(x,y,z);sprite.scale.set(height*(canvas.width/canvas.height),height,1);sprite.name=`pixel-${kind}`;group.add(sprite);return sprite;\r\n },dispose(){if(disposed)return;disposed=true;group.removeFromParent();materials.forEach(m=>m.dispose());textures.forEach(t=>t.dispose());materials.clear();textures.clear();group.clear();}};\r\n}\r\n\r\n// THREE.Sprite instances share library-owned geometry. Dispose our materials and\r\n// textures, while leaving that geometry available to the other active layers.\r\nexport function disposePixelObject(root){if(!root)return;root.removeFromParent?.();const materials=new Set(),textures=new Set(),geometry=new Set();root.traverse(o=>{if(o.geometry&&!o.isSprite)geometry.add(o.geometry);for(const m of Array.isArray(o.material)?o.material:o.material?[o.material]:[]){materials.add(m);if(m.map)textures.add(m.map);}});textures.forEach(t=>t.dispose());materials.forEach(m=>m.dispose());geometry.forEach(g=>g.dispose());root.clear?.();}\r\n\r\nexport function pixelViewport(width,height,scale=2){scale=Math.max(1,Math.floor(scale));const rasterWidth=Math.max(1,Math.floor(width/scale)),rasterHeight=Math.max(1,Math.floor(height/scale));return {width:rasterWidth,height:rasterHeight,scale,displayWidth:rasterWidth*scale,displayHeight:rasterHeight*scale};}\r\nexport function fitPixelRenderer(renderer,camera,container,scale=2){const r=container.getBoundingClientRect(),size=pixelViewport(Math.max(1,r.width),Math.max(1,r.height),scale);renderer.setPixelRatio(1);renderer.setSize(size.width,size.height,false);const canvas=renderer.domElement;Object.assign(canvas.style,{width:`${size.displayWidth}px`,height:`${size.displayHeight}px`,left:'50%',top:'50%',right:'auto',bottom:'auto',transform:'translate(-50%,-50%)',imageRendering:'pixelated'});camera.aspect=size.width/size.height;camera.updateProjectionMatrix();return size;}\r\n","modules/coach-world/state.mjs":"import {FACTIONS,FACTION_BY_ID,GROUP_TO_FACTION,BUILDINGS,BUILDING_BY_ID,MAX_LEVEL,RULES,SHIP_IDS,hangarShipTier} from './catalog.mjs';\nimport {COACHES,STARTER_COACH_IDS} from '../../performance-catalog.mjs';\r\nimport {UNIT_BY_ID,UNIT_CATALOG,expeditionQuote,unitRoster} from './expedition-catalog.mjs';\r\nconst own=(v,k)=>Object.hasOwn(v,k),bad=new Set(['__proto__','constructor','prototype']);\r\nconst integer=(v,min=0,max=Number.MAX_SAFE_INTEGER)=>Number.isSafeInteger(v)&&v>=min&&v<=max;\r\nconst object=v=>v&&typeof v==='object'&&!Array.isArray(v);\r\nconst dayOf=now=>new Date(now).toISOString().slice(0,10);\r\nconst validDay=s=>typeof s==='string'&&/^\\d{4}-\\d{2}-\\d{2}$/.test(s)&&Number.isFinite(Date.parse(s+'T12:00:00Z'))&&new Date(s+'T12:00:00Z').toISOString().slice(0,10)===s;\r\nfunction safe(v,depth=0){if(depth>15)throw RangeError('Station data is too deeply nested.');if(typeof v==='number'&&!Number.isFinite(v))throw RangeError('Invalid station number.');if(v&&typeof v==='object')for(const k of Object.keys(v)){if(bad.has(k))throw RangeError('Unsafe station key.');safe(v[k],depth+1);}}\r\nconst clone=v=>{safe(v);return structuredClone(v);};\r\nconst fail=message=>{throw RangeError(message);};\r\nexport function newBase(seed='guest',now=Date.now()){\r\n if(typeof seed!=='string'||seed.length>160)fail('Invalid station owner.');\r\n return {version:2,seed,faction:'chest',buildings:Object.fromEntries(BUILDINGS.map(b=>[b.id,{id:b.id,track:b.track,level:b.startsUnbuilt?0:1,x:b.x,y:b.y,job:null}])),materials:Object.fromEntries(FACTIONS.map(f=>[f.id,20])),fuel:60,calm:60,launchCharge:0,rest:false,ships:{supportive:{tier:0,variant:0}},selectedShip:'supportive',rewardDays:{},sourceKeys:{},careDays:{},factionChangedAt:0,home:null,publicSiteId:null,inventory:{},rations:0,calmTokens:0,seedWorkers:3,workers:4,coachAccess:[...STARTER_COACH_IDS],units:{},training:{},expedition:null,expeditionSerial:0,expeditionHistory:[]};\r\n}\r\nfunction overlap(a,b){const x=BUILDING_BY_ID[a.id],y=BUILDING_BY_ID[b.id];return a.x<b.x+y.w&&a.x+x.w>b.x&&a.y<b.y+y.h&&a.y+x.h>b.y;}\r\nfunction layoutValid(buildings){const rows=Object.values(buildings).filter(b=>b.level>0||b.job);for(let i=0;i<rows.length;i++){const b=rows[i],d=BUILDING_BY_ID[b.id];if(!d||!integer(b.x,0,24-d.w)||!integer(b.y,0,24-d.h))return false;for(let j=0;j<i;j++)if(overlap(b,rows[j]))return false;}return true;}\r\nfunction assertV2(b){\r\n safe(b);if(!object(b)||b.version!==2||typeof b.seed!=='string'||b.seed.length>160||!own(FACTION_BY_ID,b.faction)||!object(b.buildings)||Object.keys(b.buildings).length!==BUILDINGS.length||!object(b.materials))fail('Invalid saved station.');\r\n for(const f of FACTIONS)if(!integer(b.materials[f.id]))fail('Invalid station material.');\r\n for(const d of BUILDINGS){const x=b.buildings[d.id];if(!object(x)||x.id!==d.id||x.track!==d.track||!integer(x.level,d.startsUnbuilt?0:1,MAX_LEVEL)||!integer(x.x,0,24-d.w)||!integer(x.y,0,24-d.h))fail('Invalid station building.');const j=x.job;if(j!=null&&(!object(j)||!integer(j.targetLevel,1,MAX_LEVEL)||j.targetLevel!==x.level+1||!integer(j.startedAt)||!integer(j.dueAt,j.startedAt)||!integer(j.cost)||!own(FACTION_BY_ID,j.track)||!['occupied-worker','seeded-warp','consumed-seed'].includes(j.policy)))fail('Invalid construction job.');}\r\n if(!layoutValid(b.buildings)||!integer(b.fuel,0,100)||!integer(b.calm,0,100)||!integer(b.launchCharge,0,10)||typeof b.rest!=='boolean'||!integer(b.rations)||!integer(b.calmTokens)||!integer(b.seedWorkers,0,3)||!integer(b.workers,1,8)||!integer(b.factionChangedAt))fail('Invalid station state.');\r\n for(const k of ['rewardDays','sourceKeys','careDays','inventory','ships'])if(!object(b[k]))fail('Invalid station ledger.');\r\n if(!own(b.ships,'supportive')||!own(b.ships,b.selectedShip))fail('Invalid selected ship.');\r\n for(const [id,s] of Object.entries(b.ships))if(!SHIP_IDS.includes(id)||!object(s)||!integer(s.tier,0,4)||!integer(s.variant,0,3)||(id==='supportive'&&s.tier!==0))fail('Invalid station ship.');\r\n for(const [day,tracks] of Object.entries(b.rewardDays))if(!validDay(day)||!Array.isArray(tracks)||tracks.length>3||new Set(tracks).size!==tracks.length||tracks.some(t=>!own(FACTION_BY_ID,t)))fail('Invalid reward day.');\r\n if(b.home!==null&&(!object(b.home)||!Number.isFinite(b.home.latitude)||Math.abs(b.home.latitude)>90||!Number.isFinite(b.home.longitude)||Math.abs(b.home.longitude)>180||b.home.consent!==true))fail('Invalid private home.');\r\n if(!Array.isArray(b.coachAccess)||new Set(b.coachAccess).size!==b.coachAccess.length||b.coachAccess.some(id=>!COACHES.some(c=>c.id===id)))fail('Invalid earned coach access.');\r\n if(!object(b.units)||!object(b.training)||!integer(b.expeditionSerial)||!Array.isArray(b.expeditionHistory)||b.expeditionHistory.length>12)fail('Invalid expedition ledger.');\r\n for(const [id,count]of Object.entries(b.units))if(!own(UNIT_BY_ID,id)||!UNIT_BY_ID[id].trainable||!integer(count,0,1))fail('Invalid trained unit.');\r\n for(const [id,j]of Object.entries(b.training))if(!own(UNIT_BY_ID,id)||!UNIT_BY_ID[id].trainable||!object(j)||j.unitId!==id||j.faction!==UNIT_BY_ID[id].faction||!integer(j.startedAt)||!integer(j.dueAt,j.startedAt)||!integer(j.cost))fail('Invalid training job.');\r\n if(b.expedition!==null){const e=b.expedition;if(!object(e)||typeof e.id!=='string'||!/^expedition-[1-9][0-9]*$/.test(e.id)||!['prepared','launched','returning','returned'].includes(e.status)||!own(FACTION_BY_ID,e.factionId)||!own(b.ships,e.shipId)||!Array.isArray(e.unitIds)||e.unitIds.length<1||e.unitIds.length>8||new Set(e.unitIds).size!==e.unitIds.length||e.unitIds.some(id=>!own(UNIT_BY_ID,id))||typeof e.shared!=='boolean'||!integer(e.preparedAt)||!integer(e.materialCost)||!integer(e.fuelCost)||!integer(e.durationMs,1)||!integer(e.returnDurationMs,1))fail('Invalid expedition plan.');if(e.shared&&(typeof e.siteId!=='string'||!/^[A-Za-z0-9_-]{1,100}$/.test(e.siteId)))fail('Choose a public mission hub.');if(e.status!=='prepared'&&(!integer(e.launchedAt)||!integer(e.dueAt,e.launchedAt)))fail('Invalid expedition journey.');if(['returning','returned'].includes(e.status)&&!integer(e.returnDueAt,e.launchedAt))fail('Invalid expedition return.');}\r\n if(b.publicSiteId!==null&&(typeof b.publicSiteId!=='string'||!/^[a-zA-Z0-9_-]{1,100}$/.test(b.publicSiteId)))fail('Invalid public hub.');return b;\r\n}\r\nexport function normalizeBase(base){\r\n safe(base);if(!object(base)||![1,2].includes(base.version))fail('Invalid saved station.');const b=clone(base);if(b.version===2){b.coachAccess??=[...STARTER_COACH_IDS];return assertV2(b);}\r\n const original=BUILDINGS.filter(d=>!d.startsUnbuilt);if(!object(b.buildings)||Object.keys(b.buildings).length!==original.length||!object(b.materials))fail('Invalid legacy station.');b.legacyTiers={};b.migration={from:1,to:2,refundedJobs:[]};\r\n for(const d of original){const x=b.buildings[d.id];if(!object(x)||x.id!==d.id||x.track!==d.track||!integer(x.level,1,10))fail('Invalid legacy building.');const oldLevel=x.level;b.legacyTiers[d.id]=oldLevel;x.level=Math.ceil(oldLevel/2);if(x.job){const j=x.job;if(!integer(j.targetLevel,2,10)||j.targetLevel!==oldLevel+1||!integer(j.cost)||!own(FACTION_BY_ID,j.track)||!integer(j.startedAt)||!integer(j.dueAt,j.startedAt)||!['occupied-worker','seeded-warp','consumed-seed'].includes(j.policy))fail('Invalid legacy construction.');const target=Math.ceil(j.targetLevel/2);if(target<=x.level||x.level>=MAX_LEVEL){b.materials[j.track]+=j.cost;b.fuel=Math.min(100,b.fuel+5);if(j.policy==='consumed-seed')b.seedWorkers=Math.min(3,b.seedWorkers+1);x.job=null;b.migration.refundedJobs.push(d.id);}else j.targetLevel=target;}}\r\n const occupied=()=>Object.values(b.buildings);for(const d of BUILDINGS.filter(v=>v.startsUnbuilt)){let position={x:d.x,y:d.y};const clear=p=>!occupied().some(x=>{const def=BUILDING_BY_ID[x.id];return p.x<x.x+def.w&&p.x+d.w>x.x&&p.y<x.y+def.h&&p.y+d.h>x.y;});if(!clear(position)){let found=false;for(let y=0;y<=24-d.h&&!found;y++)for(let x=0;x<=24-d.w;x++)if(clear({x,y})){position={x,y};found=true;break;}}b.buildings[d.id]={id:d.id,track:d.track,level:0,...position,job:null};}\r\n b.version=2;b.coachAccess=[...STARTER_COACH_IDS];b.units={};b.training={};b.expedition=null;b.expeditionSerial=0;b.expeditionHistory=[];return assertV2(b);\r\n}\r\nexport function assertBase(base){return normalizeBase(base);}\r\nexport function advanceBase(base,now=Date.now()){\r\n if(!integer(now))fail('Invalid station clock.');const b=normalizeBase(base);\r\n for(const x of Object.values(b.buildings)){const j=x.job;if(j&&j.dueAt<=now){x.level=j.targetLevel;x.job=null;if(j.policy==='consumed-seed')b.seedWorkers=Math.min(3,b.seedWorkers+1);}}\r\n for(const [id,j]of Object.entries(b.training))if(j.dueAt<=now){b.units[id]=1;delete b.training[id];}\r\n const e=b.expedition;if(e?.status==='launched'&&e.dueAt<=now){e.status='returning';e.returnDueAt=e.dueAt+e.returnDurationMs;}if(e?.status==='returning'&&e.returnDueAt<=now){e.status='returned';e.returnedAt=e.returnDueAt;if(!b.expeditionHistory.some(v=>v.id===e.id))b.expeditionHistory.push({id:e.id,factionId:e.factionId,shipId:e.shipId,unitIds:[...e.unitIds],shared:e.shared,status:'returned',returnedAt:e.returnedAt});b.expeditionHistory=b.expeditionHistory.slice(-12);}\r\n return assertV2(b);\r\n}\r\nexport function qualifyingDays(base,track){return Object.values(base.rewardDays).filter(v=>Array.isArray(v)&&v.includes(track)).length;}\r\nfunction reachableEntrances(buildings){const blocked=new Set();for(const b of Object.values(buildings).filter(b=>b.level>0||b.job)){const d=BUILDING_BY_ID[b.id];for(let y=b.y;y<b.y+d.h;y++)for(let x=b.x;x<b.x+d.w;x++)blocked.add(y*24+x);}const q=[0],seen=new Set(q);for(let i=0;i<q.length;i++){const n=q[i],x=n%24,y=Math.floor(n/24);for(const [a,c] of [[x-1,y],[x+1,y],[x,y-1],[x,y+1]]){const k=c*24+a;if(a>=0&&a<24&&c>=0&&c<24&&!blocked.has(k)&&!seen.has(k)){seen.add(k);q.push(k);}}}return Object.values(buildings).filter(b=>b.level>0||b.job).every(b=>{const d=BUILDING_BY_ID[b.id];for(let x=b.x;x<b.x+d.w;x++)if(seen.has((b.y-1)*24+x)||seen.has((b.y+d.h)*24+x))return true;for(let y=b.y;y<b.y+d.h;y++)if(seen.has(y*24+b.x-1)||seen.has(y*24+b.x+d.w))return true;return false;});}\r\nexport function constructionQuote(base,buildingId,requestedTrack){\r\n const b=normalizeBase(base),d=own(BUILDING_BY_ID,buildingId)?BUILDING_BY_ID[buildingId]:null,x=own(b.buildings,buildingId)?b.buildings[buildingId]:null;if(!d||!x)return {allowed:false,reason:'Choose a building.'};const track=d.track??requestedTrack??b.faction;if(!own(FACTION_BY_ID,track))return {allowed:false,reason:'Choose a workout material.'};const next=x.level+1,build=x.level===0,daysRequired=build?(d.kind==='expedition'?3:1):(RULES.dayGates[next-2]??0),days=qualifyingDays(b,track),support=['care','observatory','habitat','hangar'].reduce((n,id)=>n+b.buildings[id].level,0)/4,softCapMultiplier=d.id==='hq'?1+Math.max(0,next-1-Math.floor(support))*.25:1;\r\n let prerequisites=build?(d.prerequisites??[]):d.id==='hq'?[]:[{buildingId:'hq',level:Math.min(MAX_LEVEL,Math.max(1,next-(d.kind==='expedition'?-1:1)))}];if(!build&&d.kind==='production')prerequisites.push({buildingId:`hall-${d.track}`,level:Math.min(3,next)});if(!build&&d.kind==='expedition')prerequisites.push({buildingId:`production-${d.track}`,level:Math.min(3,next)});prerequisites=prerequisites.map(p=>({...p,met:(b.buildings[p.buildingId]?.level??0)>=p.level}));\r\n const cost=Math.ceil((build?(d.kind==='expedition'?40:30):20*next)*softCapMultiplier),durationMs=Math.ceil(RULES.buildMinuteMs*(build?1:next-1)*softCapMultiplier),q={targetLevel:next,cost,fuelCost:5,durationMs,daysRequired,qualifyingDays:days,prerequisites,softCapMultiplier,track,allowed:true,reason:null};\r\n const fail=reason=>({...q,allowed:false,reason});if(x.job)return fail('This building is busy.');if(next>MAX_LEVEL)return fail('Maximum level reached.');const missing=prerequisites.find(p=>!p.met);if(missing)return fail(`Need ${BUILDING_BY_ID[missing.buildingId].label} level ${missing.level}.`);if(days<daysRequired)return fail(`Earn ${daysRequired} qualifying ${FACTION_BY_ID[track].label} days first.`);if(b.materials[track]<cost)return fail(`Need ${cost} ${FACTION_BY_ID[track].label} material.`);if(b.fuel<5)return fail('Fuel the station before construction.');return q;\r\n}\r\nexport function applyBaseAction(base,action,{now=Date.now(),sharedMissionAuthorized=false}={}){\r\n if(!object(action)||typeof action.type!=='string')fail('Choose a station action.');safe(action);const b=advanceBase(base,now),x=own(b.buildings,action.buildingId)?b.buildings[action.buildingId]:null,d=own(BUILDING_BY_ID,action.buildingId)?BUILDING_BY_ID[action.buildingId]:null;\r\n switch(action.type){\r\n case 'build':case 'upgrade':{if(!x)fail('Choose a building.');if(action.type==='build'&&x.level!==0)fail('This building is already built.');if(action.type==='upgrade'&&x.level===0)fail('Build this structure first.');const quote=constructionQuote(b,d.id,action.track);if(!quote.allowed)fail(quote.reason);const {track,cost,targetLevel:next,durationMs,softCapMultiplier}=quote,policy=FACTION_BY_ID[track].policy,used=Object.values(b.buildings).filter(v=>v.job?.policy==='occupied-worker').length;if(policy==='occupied-worker'&&used>=b.workers)fail('All builder crews are busy.');if(policy==='consumed-seed'&&b.seedWorkers<1)fail('A root worker is regrowing.');b.materials[track]-=cost;b.fuel-=5;if(policy==='consumed-seed')b.seedWorkers--;x.job={targetLevel:next,startedAt:now,dueAt:now+durationMs,cost,track,policy,softCapMultiplier,builderId:policy==='occupied-worker'?Array.from({length:b.workers},(_,i)=>`crew-${i+1}`).find(id=>!Object.values(b.buildings).some(v=>v.job?.builderId===id)):null};if(!layoutValid(b.buildings)||!reachableEntrances(b.buildings))fail('Choose a clear plot with a reachable entrance.');break;}\r\n case 'cancel':{if(!x?.job)fail('No construction to cancel.');const j=x.job;b.materials[j.track]+=Math.floor(j.cost*.9);if(j.policy==='consumed-seed')b.seedWorkers=Math.min(3,b.seedWorkers+1);x.job=null;break;}\r\n case 'move':{if(!x||x.job)fail('Choose an idle building.');if(!integer(action.x,0,23)||!integer(action.y,0,23))fail('Choose a valid plot.');x.x=action.x;x.y=action.y;if(!layoutValid(b.buildings)||!reachableEntrances(b.buildings))fail('Leave every building a reachable entrance.');break;}\r\n case 'train-unit':{const unit=own(UNIT_BY_ID,action.unitId)?UNIT_BY_ID[action.unitId]:null;if(!unit?.trainable)fail('This unit is unlocked by its coach hall.');if((b.buildings[unit.buildingId]?.level??0)<unit.requiredLevel||b.buildings[unit.buildingId].job)fail(`Need an idle ${BUILDING_BY_ID[unit.buildingId].label} level ${unit.requiredLevel}.`);if(b.units[unit.id]||b.training[unit.id])fail('This companion is already owned or training.');if(Object.keys(b.training).some(id=>UNIT_BY_ID[id].buildingId===unit.buildingId))fail('This production facility is training a companion.');if(b.materials[unit.faction]<unit.materialCost)fail('Need more matching materials to train this companion.');b.materials[unit.faction]-=unit.materialCost;b.training[unit.id]={unitId:unit.id,faction:unit.faction,startedAt:now,dueAt:now+unit.trainingMs,cost:unit.materialCost};break;}\r\n case 'cancel-training':{const j=b.training[action.unitId];if(!j)fail('No companion training to cancel.');b.materials[j.faction]+=Math.floor(j.cost*.9);delete b.training[action.unitId];break;}\r\n case 'prepare-expedition':{if(['launched','returning'].includes(b.expedition?.status))fail('Wait for the current expedition to return.');const plan={factionId:action.factionId??b.faction,shipId:action.shipId??b.selectedShip,unitIds:action.unitIds,shared:action.shared===true,siteId:action.shared===true?action.siteId:null};if(plan.shared&&(typeof plan.siteId!=='string'||!/^[A-Za-z0-9_-]{1,100}$/.test(plan.siteId)))fail('Choose a public mission hub.');const q=expeditionQuote(b,plan);if(!q.allowed)fail(q.reason);b.expeditionSerial++;b.expedition={...plan,...q,id:`expedition-${b.expeditionSerial}`,status:'prepared',preparedAt:now,rewardAuthority:'server-only'};delete b.expedition.allowed;delete b.expedition.reason;break;}\r\n case 'launch-expedition':{const e=b.expedition;if(e?.status!=='prepared')fail('Prepare an expedition first.');if(e.shared&&!sharedMissionAuthorized)fail('Shared missions require fresh presence at the selected public hub.');const q=expeditionQuote(b,e);if(!q.allowed)fail(q.reason);b.materials[e.factionId]-=q.materialCost;b.fuel-=q.fuelCost;Object.assign(e,q,{status:'launched',launchedAt:now,dueAt:now+q.durationMs});delete e.allowed;delete e.reason;break;}\r\n case 'return-expedition':{const e=b.expedition;if(e?.status==='returned')break;if(e?.status!=='launched')fail('This expedition is already returning or has not launched.');e.status='returning';e.returnDueAt=now+e.returnDurationMs;break;}\r\n case 'cancel-expedition':if(b.expedition?.status!=='prepared')fail('Only an unlaunched plan can be cancelled.');b.expedition=null;break;\r\n case 'care':{const day=dayOf(now),flags=b.careDays[day]??={};if(action.kind==='greet'){if(flags.greet)fail('Your crew has been greeted today.');flags.greet=true;b.calm=Math.min(100,b.calm+10);}else if(action.kind==='fuel'){if(b.rations<1)fail('Log food to earn a station ration.');if(b.fuel>=100)fail('Fuel is full.');b.rations--;b.fuel=Math.min(100,b.fuel+25);}else if(action.kind==='meditate'){if(b.calmTokens<1)fail('Complete meditation to earn calm.');if(b.calm>=100)fail('Calm is full.');b.calmTokens--;b.calm=Math.min(100,b.calm+25);}else fail('Unknown care action.');break;}\r\n case 'rest':if(typeof action.value!=='boolean')fail('Choose rest on or off.');b.rest=action.value;break;\r\n case 'faction':if(!own(FACTION_BY_ID,action.factionId))fail('Choose a workout faction.');if(action.factionId===b.faction)break;if(b.factionChangedAt&&now-b.factionChangedAt<7*86400000)fail('Faction changes unlock after seven days.');b.faction=action.factionId;b.factionChangedAt=now;break;\r\n case 'home':if(action.consent!==true||typeof action.latitude!=='number'||typeof action.longitude!=='number'||!Number.isFinite(action.latitude)||!Number.isFinite(action.longitude)||Math.abs(action.latitude)>90||Math.abs(action.longitude)>180)fail('Confirm a valid private home location.');b.home={latitude:action.latitude,longitude:action.longitude,consent:true};break;\r\n case 'public-site':if(typeof action.siteId!=='string'||!/^[a-zA-Z0-9_-]{1,100}$/.test(action.siteId))fail('Choose a public hub.');b.publicSiteId=action.siteId;break;\r\n case 'select-ship':if(!own(b.ships,action.shipId))fail('Earn this ship first.');b.selectedShip=action.shipId;break;\r\n default:fail('Unknown station action.');}\r\n return assertBase(b);\r\n}\r\nexport function creditPersonalProgress(base,performance,{now=Date.now()}={}){\r\n const b=advanceBase(base,now);if(!object(performance))return b;if(Array.isArray(performance.coaches))b.coachAccess=[...new Set([...b.coachAccess,...performance.coaches.filter(id=>COACHES.some(c=>c.id===id))])];\r\n const sessions=object(performance.sessions)?Object.entries(performance.sessions):[];sessions.sort((a,c)=>String(a[1]?.day).localeCompare(String(c[1]?.day))||a[0].localeCompare(c[0]));\r\n for(const [id,s] of sessions){if(bad.has(id)||id.length>250||!object(s)||!validDay(s.day)||s.day>dayOf(now))continue;const key='workout:'+id,track=GROUP_TO_FACTION[s.group];if(own(b.sourceKeys,key)||!track||!(typeof s.xp==='number'&&s.xp>0))continue;const value=typeof s.value==='number'?s.value:0,active=typeof s.activeSeconds==='number'?s.activeSeconds:0,continuous=typeof s.continuous==='number'?s.continuous:0;const qualified=s.kind==='reps'?value>=5:s.kind==='hold'?continuous>=60||active>=60:value>=60||active>=60;if(!qualified)continue;const tracks=b.rewardDays[s.day]??=[];if(!tracks.includes(track)&&tracks.length<3){tracks.push(track);b.materials[track]+=10;}b.sourceKeys[key]=true;}\r\n const creditCare=(kind,day)=>{if(!validDay(day)||day>dayOf(now))return;const flags=b.careDays[day]??={};if(kind==='food'&&!flags.food){flags.food=true;b.rations++;}if(kind==='meditation'&&!flags.meditation){flags.meditation=true;b.calmTokens++;}};\r\n if(object(performance.activities))for(const a of Object.values(performance.activities))if(object(a))creditCare(a.kind,a.day);\r\n if(object(performance.days))for(const [day,a] of Object.entries(performance.days))if(object(a)){if(a.food)creditCare('food',day);if(a.meditation)creditCare('meditation',day);}\r\n let hash=0;for(const c of b.seed)hash=(Math.imul(hash,31)+c.charCodeAt(0))>>>0;for(const id of Array.isArray(performance.ships)?performance.ships:[])if(SHIP_IDS.includes(id)&&id!=='supportive'){const tier=hangarShipTier(b.buildings.hangar.level);if(own(b.ships,id))b.ships[id].tier=Math.max(b.ships[id].tier,tier);else b.ships[id]={tier,variant:(hash+SHIP_IDS.indexOf(id))%4};}\n // Guest-personal reconciliation NEVER grants expedition charge.\r\n return assertBase(b);\r\n}\r\n","modules/coach-world/terrain.mjs":"import {BUILDINGS,FACTIONS,FACTION_BY_ID} from './catalog.mjs';\r\nimport {occupancy,findPath} from './navigation.mjs';\r\nexport const TERRAIN_SIZE=24,TILE_PIXELS=32;\r\nconst composites=new WeakMap(),cache=new Map(),clamp=(v,a,b)=>Math.max(a,Math.min(b,v));\r\nfunction hash(x,y,seed=0){let n=Math.imul(x+seed,374761393)^Math.imul(y+17,668265263);n=Math.imul(n^(n>>>13),1274126177);return (n^(n>>>16))>>>0;}\r\nfunction seedOf(text){let n=0;for(const c of String(text))n=(Math.imul(n,31)+c.charCodeAt(0))>>>0;return n;}\r\nfunction tint(a,b,weight){const channels=[1,3,5].map(i=>Math.round(parseInt(a.slice(i,i+2),16)*(1-weight)+parseInt(b.slice(i,i+2),16)*weight));return '#'+channels.map(n=>n.toString(16).padStart(2,'0')).join('');}\r\nexport function terrainRaster(faction='chest',kind='soil',variant=0){\r\n const f=FACTION_BY_ID[faction]||FACTIONS[0],index=FACTIONS.indexOf(f),pixels=new Uint8Array(32*32),soil=tint('#202b2d',f.dark,.42),palette=[tint(soil,'#858782',.09),soil,tint(soil,f.color,.18),tint(soil,f.color,.23),'#162e3a','#203c48','#35515a',tint(soil,'#0c181e',.25)];\r\n for(let y=0;y<32;y++)for(let x=0;x<32;x++){const n=hash(x,y,variant+index*19);let color=1;\r\n  if(kind==='water'){color=4;if((x+Math.floor(y/4)*5+variant*3)%23<8&&y%7<2)color=5;if((x+y*3+variant)%43===0)color=6;}\r\n  else if(kind==='path'||kind==='bridge'){color=kind==='bridge'?2:0;if(x%16===0||y%16===0)color=7;if((x+y+variant)%29===0)color=1;if(kind==='bridge'&&(x<3||x>28))color=3;}\r\n  else{if(n%83===0)color=0;const cluster=(x-(8+variant*4))**2+(y-(10+variant*3))**2<48;if(cluster&&index===0&&((x+y)%15===0||(x-y+32)%23===0))color=2;if(cluster&&index===1&&(((x-16)**2/2+(y-16)**2)%89<8))color=2;if(cluster&&index===2&&((x*3+y+variant)%23<2||((x-8)**2+(y-23)**2)%101<5))color=2;if(cluster&&index===3&&((y%12===0&&x%16<9)||(x%16===8&&y%12<8)))color=2;if(cluster&&index===4&&Math.abs(Math.hypot(x-16,y-16)%9)<.8)color=2;if(cluster&&index===5&&((x+Math.abs(y-16))%18<2))color=2;if(cluster&&index===6&&((x%16<2)||(y%16<2&&x%16<9)))color=2;if(cluster&&n%83===0)color=3;}\r\n  pixels[y*32+x]=color;\r\n }return {width:32,height:32,pixels,palette};\r\n}\r\nexport function terrainTileCanvas(faction,kind,variant){const key=`${faction}/${kind}/${variant}`;if(cache.has(key))return cache.get(key);const raster=terrainRaster(faction,kind,variant),canvas=document.createElement('canvas');canvas.width=canvas.height=32;const ctx=canvas.getContext('2d'),image=ctx.createImageData(32,32),colors=raster.palette.map(c=>[1,3,5].map(i=>parseInt(c.slice(i,i+2),16)));for(let i=0;i<1024;i++){image.data.set([...colors[raster.pixels[i]],255],i*4);}ctx.putImageData(image,0,0);cache.set(key,canvas);return canvas;}\r\nexport function createTerrain(base){\r\n const definitions=BUILDINGS.map(d=>({...d,...base.buildings?.[d.id]})),halls=definitions.filter(d=>d.kind==='hall'),seed=seedOf(base.seed),cells=[],blocked=new Set(),occupied=occupancy(base),roads=new Set();\r\n for(let y=0;y<24;y++)for(let x=0;x<24;x++){let nearest=halls[0],distance=Infinity;for(const hall of halls){const d=(x-hall.x-hall.w/2)**2+(y-hall.y-hall.h/2)**2;if(d<distance){distance=d;nearest=hall;}}const faction=nearest?.track||base.faction||'chest',water=(x<3&&y>17)||(x>20&&y<5),height=water?0:hash(Math.floor(x/4),Math.floor(y/4),seed)%3;cells.push({x,y,faction,kind:water?'water':'soil',height,variant:hash(x,y,seed)%4});}\r\n const hq=definitions.find(d=>d.id==='hq')||{x:10,y:9,w:4,h:4},origin={x:clamp(Math.floor(hq.x+hq.w/2),0,23),y:clamp(hq.y+hq.h,0,23)};\r\n for(const d of definitions){const entrances=[];for(let x=d.x;x<d.x+d.w;x++)entrances.push({x,y:d.y-1},{x,y:d.y+d.h});for(let y=d.y;y<d.y+d.h;y++)entrances.push({x:d.x-1,y},{x:d.x+d.w,y});const target=entrances.filter(p=>p.x>=0&&p.y>=0&&p.x<24&&p.y<24&&!occupied.has(p.y*24+p.x)).sort((a,b)=>Math.hypot(a.x-origin.x,a.y-origin.y)-Math.hypot(b.x-origin.x,b.y-origin.y))[0];if(target){const path=findPath(24,24,occupied,origin,target);for(const p of path||[])roads.add(p.y*24+p.x);}}\r\n for(const d of definitions)for(let y=Math.max(0,d.y-1);y<Math.min(24,d.y+d.h+1);y++)for(let x=Math.max(0,d.x-1);x<Math.min(24,d.x+d.w+1);x++){const cell=cells[y*24+x];cell.height=0;if(cell.kind==='water')cell.kind='soil';if(d.track)cell.faction=d.track;}\r\n for(const cell of cells){if(roads.has(cell.y*24+cell.x)){cell.kind=cell.kind==='water'?'bridge':'path';cell.height=0;}if(cell.kind==='water')blocked.add(cell.y*24+cell.x);}\r\n return {cells,blocked,roads,signature:`${base.seed}:${base.faction}:`+definitions.map(d=>`${d.id}:${d.x}:${d.y}:${d.level}`).join('|'),heightAt(x,y){return cells[clamp(Math.floor(y),0,23)*24+clamp(Math.floor(x),0,23)]?.height||0;}};\r\n}\r\nexport function terrainComposite(terrain,unit=32){const previous=composites.get(terrain);if(previous?.unit===unit)return previous.canvas;const canvas=document.createElement('canvas');canvas.width=Math.ceil(24*unit);canvas.height=Math.ceil(24*unit)+8;const ctx=canvas.getContext('2d');ctx.imageSmoothingEnabled=false;for(const cell of terrain.cells){const x=Math.round(cell.x*unit),y=Math.round(cell.y*unit-cell.height*2)+4,size=Math.ceil(unit);if(cell.height){ctx.fillStyle='#122025';ctx.fillRect(x,y+size,size,cell.height*2+1);}ctx.drawImage(terrainTileCanvas(cell.faction,cell.kind,cell.variant),x,y,size,size);}composites.set(terrain,{unit,canvas});return canvas;}\r\nexport function drawTerrain(ctx,terrain,{unit,ox,oy}){ctx.imageSmoothingEnabled=false;ctx.drawImage(terrainComposite(terrain,unit),Math.round(ox),Math.round(oy)-4);}\r\n","modules/coach-world/touchselection.mjs":"import {findPath,occupancy} from './navigation.mjs';\r\nexport function unitsInRectangle(units,a,b,pad=8){const left=Math.min(a.x,b.x)-pad,right=Math.max(a.x,b.x)+pad,top=Math.min(a.y,b.y)-pad,bottom=Math.max(a.y,b.y)+pad;return units.filter(u=>u.x>=left&&u.x<=right&&u.y>=top&&u.y<=bottom).map(u=>u.id);}\r\nexport function createTouchGesture({holdMs=430,threshold=7,setTimer=setTimeout,clearTimer=clearTimeout,onHold=()=>{}}={}){\r\n let state=null,timer=null;const stop=()=>{if(timer!=null)clearTimer(timer);timer=null;};\r\n return {get state(){return state;},down(point,{select=false}={}){stop();state={start:{...point},point:{...point},mode:select?'select':'pending',moved:false};if(!select)timer=setTimer(()=>{if(state?.mode==='pending'){state.mode='select';onHold();}},holdMs);return state;},move(point){if(!state)return null;const previous=state.point;state.point={...point};if(Math.hypot(point.x-state.start.x,point.y-state.start.y)>threshold){state.moved=true;if(state.mode==='pending'){state.mode='pan';stop();}}return {mode:state.mode,dx:point.x-previous.x,dy:point.y-previous.y};},pinch(){stop();if(state)state.mode='pinch';},up(){stop();const result=state;state=null;return result;},cancel(){stop();state=null;},dispose(){stop();state=null;}};\r\n}\r\nexport function rallyUnits(units,ids,target,base,extraBlocked=new Set()){\r\n const blocked=occupancy(base);for(const key of extraBlocked)blocked.add(key);const candidates=[];for(let radius=0;radius<5;radius++)for(let y=target.y-radius;y<=target.y+radius;y++)for(let x=target.x-radius;x<=target.x+radius;x++)if(x>=0&&x<24&&y>=0&&y<24&&!blocked.has(y*24+x)&&!candidates.some(p=>p.x===x&&p.y===y))candidates.push({x,y});let assigned=0;\r\n for(const unit of units){if(unit.away||!ids.has(unit.id)||unit.state==='building'||Object.values(base.buildings).some(b=>b.job?.policy==='occupied-worker'&&b.job.builderId===`crew-${unit.id+1}`))continue;const origin={x:Math.floor(unit.x),y:Math.floor(unit.y)};for(let i=0;i<candidates.length;i++){const path=findPath(24,24,blocked,origin,candidates[i]);if(path){unit.path=path;unit.index=0;unit.rallyTarget=candidates[i];unit.state=path.length?'rally':'holding';unit.rally=true;candidates.splice(i,1);assigned++;break;}}}return assigned;\r\n}\r\nexport function stepRalliedUnits(units,dt,rest=false){for(const unit of units){if(!unit.rally||rest)continue;const p=unit.path?.[unit.index||0];if(!p){unit.state='holding';continue;}const dx=p.x-unit.x,dy=p.y-unit.y,d=Math.hypot(dx,dy),step=Math.min(.1,Math.max(0,dt))*1.7;if(d<=step){unit.x=p.x;unit.y=p.y;unit.index=(unit.index||0)+1;}else{unit.x+=dx/d*step;unit.y+=dy/d*step;unit.state='rally';unit.facing=dx<0?'left':'right';}unit.phase=(unit.phase||0)+step*7;}}\r\n","modules/coach-world/unit-catalog.mjs":"// Verified actual atlas crops. Eight active quadruped appearances supply fourteen\n// World role definitions through explicit appearance reuse + faction dye. This\n// catalog grants no coach/cosmetic ownership and does not enforce production gates.\nconst freeze=value=>{if(value&&typeof value==='object'){for(const v of Object.values(value))freeze(v);Object.freeze(value);}return value;};\nexport const UNIT_SECTIONS=freeze(['chest','quads','glutes','arms-shoulders','yoga','martial-arts','cardio']);\nexport const FOUR_LEGGED_SOURCES=freeze([{\"sourceCoachId\":\"roster/18-quad-all--dragon_creature_3d_model\",\"sourceLabel\":\"H0F-Lung\",\"sheet\":\"pets\",\"frame\":[0,0,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--fantasy_creature_3d_model1\",\"sourceLabel\":\"Max Ohm-Strom Breath\",\"sheet\":\"pets\",\"frame\":[48,0,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--fantasy_creature_3d_model3\",\"sourceLabel\":\"Shiva Rea-spatory\",\"sheet\":\"pets\",\"frame\":[96,0,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--four-legged_robot_3d_model\",\"sourceLabel\":\"Tara-5tile5-Standby\",\"sheet\":\"pets\",\"frame\":[144,0,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--quadruped_robot_3d_model1\",\"sourceLabel\":\"Werner Wind0wn\",\"sheet\":\"pets\",\"frame\":[192,0,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--quadruped_robot_3d_model\",\"sourceLabel\":\"Yee Holo-Om\",\"sheet\":\"pets\",\"frame\":[0,36,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--robotic_dog_3d_model\",\"sourceLabel\":\"Budig-ital Breath\",\"sheet\":\"pets\",\"frame\":[48,36,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"},{\"sourceCoachId\":\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",\"sourceLabel\":\"Priest-L33 Squat\",\"sheet\":\"pets\",\"frame\":[96,36,48,36],\"atlasPath\":\"/pod/gala-coaches/pets.png\",\"family\":\"Four-legged\"}]);\nexport const BASIC_WORKER=freeze({id:'worker:myr5',label:'MYR5 basic worker',role:'worker',section:null,variant:0,unlockPolicy:'baseline',productionPath:['hq'],...{\"sourceCoachId\":\"myr5\",\"sourceLabel\":\"MYR5 Jacked LaLAN\",\"sheet\":\"bodies\",\"frame\":[0,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"MYR5\"}});\nconst roleLabels={chest:['Crest scout','Plate carrier'],quads:['Trail scout','Load carrier'],glutes:['Pod scout','Pearl carrier'],'arms-shoulders':['Relay scout','Joint carrier'],yoga:['Wisp scout','Calm carrier'],'martial-arts':['Border scout','Shield carrier'],cardio:['Pace scout','Cell carrier']};\nexport const SECTION_COMPANIONS=freeze(Object.fromEntries(UNIT_SECTIONS.map((section,index)=>[section,['scout','carrier'].map((role,variant)=>{const source=FOUR_LEGGED_SOURCES[(index*2+variant)%FOUR_LEGGED_SOURCES.length];return {...source,id:'companion:'+section+':'+role,label:roleLabels[section][variant],role,section,variant,dyeFaction:section,appearanceReused:true,unlockPolicy:'world-baseline-role',productionPath:['hall-'+section,'production','expedition']};})])));\nexport const COACH_UNITS=freeze([{\"sourceCoachId\":\"roster/01-seed-pearo--3d_character_model\",\"sourceLabel\":\"McKe-O2 Nose-Cone\",\"sheet\":\"bodies\",\"frame\":[64,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Seed · Pearo\",\"section\":null,\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/01-seed-pearo--cute_alien_figure_3d_model\",\"sourceLabel\":\"Wern-Axis Flow\",\"sheet\":\"bodies\",\"frame\":[128,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Seed · Pearo\",\"section\":\"yoga\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/01-seed-pearo--blank_toy_figure_3d_model\",\"sourceLabel\":\"Phelpeller Pulse\",\"sheet\":\"bodies\",\"frame\":[192,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Seed · Pearo\",\"section\":\"cardio\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/02-taper-tallstalk--3d_humanoid_figure\",\"sourceLabel\":\"Hane-Yoke Lunge\",\"sheet\":\"bodies\",\"frame\":[256,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Taper · Tallstalk\",\"section\":\"quads\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\"sourceLabel\":\"Arnoid Press\",\"sheet\":\"bodies\",\"frame\":[320,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Taper · Tallstalk\",\"section\":\"arms-shoulders\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",\"sourceLabel\":\"Oli-Volt Lunge\",\"sheet\":\"bodies\",\"frame\":[384,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Taper · Tallstalk\",\"section\":\"quads\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",\"sourceLabel\":\"Robo-ertson Bridge\",\"sheet\":\"bodies\",\"frame\":[448,0,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"glutes\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--circle_center\",\"sourceLabel\":\"Con-Terra Coil-Bridge\",\"sheet\":\"bodies\",\"frame\":[0,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"glutes\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\"sourceLabel\":\"Fon-Dynamo Footwork\",\"sheet\":\"bodies\",\"frame\":[64,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"cardio\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--robot_3d_model\",\"sourceLabel\":\"Feli-X Footdrive\",\"sheet\":\"bodies\",\"frame\":[128,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"cardio\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--stylized_3d_character1\",\"sourceLabel\":\"Gyrvanium Glute-Drive\",\"sheet\":\"bodies\",\"frame\":[192,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"glutes\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"sourceLabel\":\"Trac-ION Hip-Thrust\",\"sheet\":\"bodies\",\"frame\":[256,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Pearl · Orb\",\"section\":\"glutes\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/04-crest-wedge--robot_creature_3d_model\",\"sourceLabel\":\"L0U Ferri-pecctor\",\"sheet\":\"bodies\",\"frame\":[320,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Crest · Wedge\",\"section\":\"chest\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/04-crest-wedge--stylized_3d_character\",\"sourceLabel\":\"Gr33ne Grid-Press\",\"sheet\":\"bodies\",\"frame\":[384,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Crest · Wedge\",\"section\":\"chest\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\"sourceLabel\":\"C0N0R McG-Gear\",\"sheet\":\"bodies\",\"frame\":[448,96,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Slope · Bobble\",\"section\":\"martial-arts\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/06-ridge-triad--geometric_robot_3d_model1\",\"sourceLabel\":\"Oliva-C Pec\",\"sheet\":\"bodies\",\"frame\":[0,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Ridge · Triad\",\"section\":\"chest\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/06-ridge-triad--robot_3d_model1\",\"sourceLabel\":\"M0 Farah Fastlane\",\"sheet\":\"bodies\",\"frame\":[64,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Ridge · Triad\",\"section\":\"cardio\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/07-bulb-sphereling--cute_robot_3d_model\",\"sourceLabel\":\"Billy Blanx Beam\",\"sheet\":\"bodies\",\"frame\":[128,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Bulb · Sphereling\",\"section\":\"cardio\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\"sourceLabel\":\"B0LT Sprint-Drive\",\"sheet\":\"bodies\",\"frame\":[192,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Bulb · Sphereling\",\"section\":\"cardio\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/08-shard-asym--geometric_robot_3d_model\",\"sourceLabel\":\"Pec-n0ld Reactor\",\"sheet\":\"bodies\",\"frame\":[256,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shard · Asym\",\"section\":\"chest\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/08-shard-asym--robot_3d_model4\",\"sourceLabel\":\"S3RG Oliv-Armature\",\"sheet\":\"bodies\",\"frame\":[320,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shard · Asym\",\"section\":\"arms-shoulders\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/08-shard-asym--fantasy_creature_3d_model2\",\"sourceLabel\":\"Waters0nic\",\"sheet\":\"bodies\",\"frame\":[384,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shard · Asym\",\"section\":\"martial-arts\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/08-shard-asym--stylized_action_figure_3d_model\",\"sourceLabel\":\"Yee-lastic Flow\",\"sheet\":\"bodies\",\"frame\":[448,192,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shard · Asym\",\"section\":\"yoga\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/09-monolith-tanka--3d_robot_model\",\"sourceLabel\":\"chris BenchSTEAD\",\"sheet\":\"bodies\",\"frame\":[0,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Monolith · Tanka\",\"section\":\"chest\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\"sourceLabel\":\"Bruce L3300\",\"sheet\":\"bodies\",\"frame\":[64,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Monolith · Tanka\",\"section\":\"martial-arts\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/09-monolith-tanka--mini_robot_3d_model\",\"sourceLabel\":\"Machi-Droid-a\",\"sheet\":\"bodies\",\"frame\":[128,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Monolith · Tanka\",\"section\":\"martial-arts\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/09-monolith-tanka--robot_3d_model3\",\"sourceLabel\":\"Israel Ade-SYNC-ya\",\"sheet\":\"bodies\",\"frame\":[192,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Monolith · Tanka\",\"section\":\"martial-arts\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/09-monolith-tanka--white_horned_robot_3d_model\",\"sourceLabel\":\"Cavalier-EX Chest\",\"sheet\":\"bodies\",\"frame\":[256,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Monolith · Tanka\",\"section\":\"chest\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/10-petal-wisp--stylized_creature_3d_model\",\"sourceLabel\":\"Iyeng-Arc Inversion\",\"sheet\":\"bodies\",\"frame\":[320,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Petal · Wisp\",\"section\":\"yoga\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/10-petal-wisp--ghost_character_3d_model\",\"sourceLabel\":\"Warri0r-ner Drive\",\"sheet\":\"bodies\",\"frame\":[384,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Petal · Wisp\",\"section\":\"yoga\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/10-petal-wisp--fantasy_creature_3d_model4\",\"sourceLabel\":\"Adriene A-Sana Mk II\",\"sheet\":\"bodies\",\"frame\":[448,288,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Petal · Wisp\",\"section\":\"yoga\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/11-anvil-cask--clay-style_robot_3d_model\",\"sourceLabel\":\"Anderson Sil-VOLT\",\"sheet\":\"bodies\",\"frame\":[0,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Anvil · Cask\",\"section\":\"martial-arts\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\"sourceLabel\":\"H0F Hold-Circuit\",\"sheet\":\"bodies\",\"frame\":[64,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Seedpod · Snailslug\",\"section\":null,\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\"sourceLabel\":\"Pilat-OS Calm-Circuit\",\"sheet\":\"bodies\",\"frame\":[128,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Seedpod · Snailslug\",\"section\":null,\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/13-fan-split--stylized_3d_character2\",\"sourceLabel\":\"Quad-Cutler LEGS THO\",\"sheet\":\"bodies\",\"frame\":[192,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Fan · Split\",\"section\":\"quads\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/13-fan-split--stylized_toy_3d_model\",\"sourceLabel\":\"BlankSaber Kick\",\"sheet\":\"bodies\",\"frame\":[256,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Fan · Split\",\"section\":\"martial-arts\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/14-chisel-spire--cone_head_3d_model\",\"sourceLabel\":\"LiDAR Jett-Jab\",\"sheet\":\"bodies\",\"frame\":[320,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Chisel · Spire\",\"section\":\"martial-arts\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/14-chisel-spire--low_poly_robot_3d_model\",\"sourceLabel\":\"Rea-Spire Relay\",\"sheet\":\"bodies\",\"frame\":[384,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Chisel · Spire\",\"section\":null,\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/15-orbital-coili--robot_character_3d_model\",\"sourceLabel\":\"t-OHM Platzma\",\"sheet\":\"bodies\",\"frame\":[448,384,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Orbital · Coili\",\"section\":\"quads\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/16-spade-arch--pyramid_head_figure_3d_model\",\"sourceLabel\":\"Franx Pec-Zane\",\"sheet\":\"bodies\",\"frame\":[0,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Spade · Arch\",\"section\":\"chest\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/16-spade-arch--stylized_humanoid_3d_model\",\"sourceLabel\":\"Cutlerator Press\",\"sheet\":\"bodies\",\"frame\":[64,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Spade · Arch\",\"section\":\"chest\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/17-shellcap-manyarm--3d_character_figurine\",\"sourceLabel\":\"Delt-alinn Bailey\",\"sheet\":\"bodies\",\"frame\":[128,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shellcap · Manyarm\",\"section\":\"arms-shoulders\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\"sourceLabel\":\"KAI-nematic Raise\",\"sheet\":\"bodies\",\"frame\":[192,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shellcap · Manyarm\",\"section\":\"arms-shoulders\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\"sourceLabel\":\"Wheel-er Servo-Shrug\",\"sheet\":\"bodies\",\"frame\":[256,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Shellcap · Manyarm\",\"section\":\"arms-shoulders\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/19-genie-multi--fantasy_creature_3d_model\",\"sourceLabel\":\"Mat-Gregor Matrix\",\"sheet\":\"bodies\",\"frame\":[320,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Genie · Multi\",\"section\":\"yoga\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\"sourceLabel\":\"Ferri-Delt L0U\",\"sheet\":\"bodies\",\"frame\":[384,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Genie · Multi\",\"section\":\"arms-shoulders\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\"sourceLabel\":\"Frank Delt-Zan3\",\"sheet\":\"bodies\",\"frame\":[448,480,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Genie · Multi\",\"section\":\"arms-shoulders\",\"difficulty\":\"medium\"},{\"sourceCoachId\":\"roster/19-genie-multi--stylized_octopus_3d_model\",\"sourceLabel\":\"Yee Gyro-Yogi\",\"sheet\":\"bodies\",\"frame\":[0,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Genie · Multi\",\"section\":\"yoga\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/20-lume--robotic_figure_3d_model\",\"sourceLabel\":\"Pre-Font-AI-ne Pace\",\"sheet\":\"bodies\",\"frame\":[64,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Lume\",\"section\":\"cardio\",\"difficulty\":\"expert\"},{\"sourceCoachId\":\"roster/22-curve--stylized_alien_3d_model\",\"sourceLabel\":\"Strom Flex Current\",\"sheet\":\"bodies\",\"frame\":[192,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Curve\",\"section\":\"yoga\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/22-curve--stylized_cartoon_figure_3d_model\",\"sourceLabel\":\"Kai Gr33ne Lunge\",\"sheet\":\"bodies\",\"frame\":[256,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Curve\",\"section\":\"quads\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/23-blob-texture-bodies--blob_creature_3d_model\",\"sourceLabel\":\"Blob 1 · H0F Hold-Drive\",\"sheet\":\"bodies\",\"frame\":[320,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Blob\",\"section\":null,\"difficulty\":\"starter\"},{\"sourceCoachId\":\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",\"sourceLabel\":\"Chlo-Turbo Thrust\",\"sheet\":\"bodies\",\"frame\":[384,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Blob\",\"section\":\"glutes\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"sourceLabel\":\"Con-Thrust-Era\",\"sheet\":\"bodies\",\"frame\":[448,576,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Blob\",\"section\":\"glutes\",\"difficulty\":\"easy\"},{\"sourceCoachId\":\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"sourceLabel\":\"Ree-volts Raise\",\"sheet\":\"bodies\",\"frame\":[0,672,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Blob\",\"section\":\"arms-shoulders\",\"difficulty\":\"hard\"},{\"sourceCoachId\":\"roster/23-blob-texture-bodies--sand_creature_3d_model\",\"sourceLabel\":\"Tingularity Thrust\",\"sheet\":\"bodies\",\"frame\":[64,672,64,96],\"atlasPath\":\"/pod/gala-coaches/bodies.png\",\"family\":\"Blob\",\"section\":\"glutes\",\"difficulty\":\"medium\"}].map(source=>({...source,id:'coach:'+source.sourceCoachId,label:source.sourceLabel,role:source.difficulty==='expert'?'boss':'grunt',variant:0,unlockPolicy:'earned-coach',productionPath:source.section?['hall-'+source.section,'production','expedition']:['production','expedition']})));\nexport const UNIT_CATALOG=freeze([BASIC_WORKER,...UNIT_SECTIONS.flatMap(section=>SECTION_COMPANIONS[section]),...COACH_UNITS]);\nexport const UNIT_BY_ID=freeze(Object.fromEntries(UNIT_CATALOG.map(unit=>[unit.id,unit])));\nexport function unitDefinition(id){return typeof id==='string'&&Object.hasOwn(UNIT_BY_ID,id)?UNIT_BY_ID[id]:null;}\nexport function initialWorldUnits(section='chest'){const chosen=UNIT_SECTIONS.includes(section)?section:'chest';return [BASIC_WORKER,...SECTION_COMPANIONS[chosen]];}\nexport function unitsForSection(section){return UNIT_SECTIONS.includes(section)?UNIT_CATALOG.filter(unit=>unit.section===section||unit.id===BASIC_WORKER.id):[];}\nexport function isWorldUnitAvailable(unitOrId,earnedCoachIds=[]){const unit=typeof unitOrId==='string'?unitDefinition(unitOrId):unitDefinition(unitOrId?.id);if(!unit)return false;return unit.unlockPolicy!=='earned-coach'||new Set(earnedCoachIds).has(unit.sourceCoachId);}\n","modules/coach-world/vendor/h3.mjs":"// @ts-nocheck\r\n\r\nvar libh3 = function (libh3) {\r\n  libh3 = libh3 || {};\r\n  var Module = typeof libh3 !== \"undefined\" ? libh3 : {};\r\n  var moduleOverrides = {};\r\n  var key;\r\n  for (key in Module) {\r\n    if (Module.hasOwnProperty(key)) {\r\n      moduleOverrides[key] = Module[key];\r\n    }\r\n  }\r\n  var arguments_ = [];\r\n  var thisProgram = \"./this.program\";\r\n  var ENVIRONMENT_IS_WEB = false;\r\n  var ENVIRONMENT_IS_WORKER = false;\r\n  var ENVIRONMENT_IS_NODE = false;\r\n  var ENVIRONMENT_HAS_NODE = false;\r\n  var ENVIRONMENT_IS_SHELL = false;\r\n  ENVIRONMENT_IS_WEB = typeof window === \"object\";\r\n  ENVIRONMENT_IS_WORKER = typeof importScripts === \"function\";\r\n  // MYR5: this self-contained asm.js build embeds its memory image. Avoid the\r\n  // obsolete CommonJS __dirname/require branch in ESM and Workers nodejs_compat.\r\n  ENVIRONMENT_HAS_NODE = false;\r\n  ENVIRONMENT_IS_NODE = ENVIRONMENT_HAS_NODE && !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_WORKER;\r\n  ENVIRONMENT_IS_SHELL = !ENVIRONMENT_IS_WEB && !ENVIRONMENT_IS_NODE && !ENVIRONMENT_IS_WORKER;\r\n  var scriptDirectory = \"\";\r\n  function locateFile(path) {\r\n    if (Module[\"locateFile\"]) {\r\n      return Module[\"locateFile\"](path, scriptDirectory);\r\n    }\r\n    return scriptDirectory + path;\r\n  }\r\n  var read_, readAsync, readBinary;\r\n  // MYR5: removed unreachable Node filesystem loader; see vendor/provenance.json.\r\n  if (ENVIRONMENT_IS_SHELL) {\r\n    if (typeof read != \"undefined\") {\r\n      read_ = function shell_read(f) {\r\n        var data = tryParseAsDataURI(f);\r\n        if (data) {\r\n          return intArrayToString(data);\r\n        }\r\n        return read(f);\r\n      };\r\n    }\r\n    readBinary = function readBinary(f) {\r\n      var data;\r\n      data = tryParseAsDataURI(f);\r\n      if (data) {\r\n        return data;\r\n      }\r\n      if (typeof readbuffer === \"function\") {\r\n        return new Uint8Array(readbuffer(f));\r\n      }\r\n      data = read(f, \"binary\");\r\n      assert(typeof data === \"object\");\r\n      return data;\r\n    };\r\n    if (typeof scriptArgs != \"undefined\") {\r\n      arguments_ = scriptArgs;\r\n    } else if (typeof arguments != \"undefined\") {\r\n      arguments_ = arguments;\r\n    }\r\n    if (typeof print !== \"undefined\") {\r\n      if (typeof console === \"undefined\") { console = {}; }\r\n      console.log = print;\r\n      console.warn = console.error = typeof printErr !== \"undefined\" ? printErr : print;\r\n    }\r\n  } else if (ENVIRONMENT_IS_WEB || ENVIRONMENT_IS_WORKER) {\r\n    if (ENVIRONMENT_IS_WORKER) {\r\n      scriptDirectory = self.location.href;\r\n    } else if (typeof document !== \"undefined\" && document.currentScript) {\r\n      scriptDirectory = document.currentScript.src;\r\n    }\r\n    if (scriptDirectory.indexOf(\"blob:\") !== 0) {\r\n      scriptDirectory = scriptDirectory.substr(0, scriptDirectory.lastIndexOf(\"/\") + 1);\r\n    } else {\r\n      scriptDirectory = \"\";\r\n    }\r\n    read_ = function shell_read(url) {\r\n      try {\r\n        var xhr = new XMLHttpRequest();\r\n        xhr.open(\"GET\", url, false);\r\n        xhr.send(null);\r\n        return xhr.responseText;\r\n      } catch (err) {\r\n        var data = tryParseAsDataURI(url);\r\n        if (data) {\r\n          return intArrayToString(data);\r\n        }\r\n        throw err;\r\n      }\r\n    };\r\n    if (ENVIRONMENT_IS_WORKER) {\r\n      readBinary = function readBinary(url) {\r\n        try {\r\n          var xhr = new XMLHttpRequest();\r\n          xhr.open(\"GET\", url, false);\r\n          xhr.responseType = \"arraybuffer\";\r\n          xhr.send(null);\r\n          return new Uint8Array(xhr.response);\r\n        } catch (err) {\r\n          var data = tryParseAsDataURI(url);\r\n          if (data) {\r\n            return data;\r\n          }\r\n          throw err;\r\n        }\r\n      };\r\n    }\r\n    readAsync = function readAsync(url, onload, onerror) {\r\n      var xhr = new XMLHttpRequest();\r\n      xhr.open(\"GET\", url, true);\r\n      xhr.responseType = \"arraybuffer\";\r\n      xhr.onload = function xhr_onload() {\r\n        if (xhr.status == 200 || xhr.status == 0 && xhr.response) {\r\n          onload(xhr.response);\r\n          return;\r\n        }\r\n        var data = tryParseAsDataURI(url);\r\n        if (data) {\r\n          onload(data.buffer);\r\n          return;\r\n        }\r\n        onerror();\r\n      };\r\n      xhr.onerror = onerror;\r\n      xhr.send(null);\r\n    };\r\n  }\r\n  var out = Module[\"print\"] || console.log.bind(console);\r\n  var err = Module[\"printErr\"] || console.warn.bind(console);\r\n  for (key in moduleOverrides) {\r\n    if (moduleOverrides.hasOwnProperty(key)) {\r\n      Module[key] = moduleOverrides[key];\r\n    }\r\n  }\r\n  moduleOverrides = null;\r\n  if (Module[\"arguments\"]) { arguments_ = Module[\"arguments\"]; }\r\n  if (Module[\"thisProgram\"]) { thisProgram = Module[\"thisProgram\"]; }\r\n  var tempRet0 = 0;\r\n  var setTempRet0 = function (value) {\r\n    tempRet0 = value;\r\n  };\r\n  var getTempRet0 = function () {\r\n    return tempRet0;\r\n  };\r\n  var GLOBAL_BASE = 8;\r\n  function setValue(ptr, value, type, noSafe) {\r\n    type = type || \"i8\";\r\n    if (type.charAt(type.length - 1) === \"*\") { type = \"i32\"; }\r\n    switch (type) {\r\n      case \"i1\":\r\n        HEAP8[ptr >> 0] = value;\r\n        break;\r\n      case \"i8\":\r\n        HEAP8[ptr >> 0] = value;\r\n        break;\r\n      case \"i16\":\r\n        HEAP16[ptr >> 1] = value;\r\n        break;\r\n      case \"i32\":\r\n        HEAP32[ptr >> 2] = value;\r\n        break;\r\n      case \"i64\":\r\n        tempI64 = [value >>> 0, (tempDouble = value, +Math_abs(tempDouble) >= +1 ? tempDouble > +0 ? (Math_min(+Math_floor(tempDouble / +4294967296), +4294967295) | 0) >>> 0 : ~~+Math_ceil((tempDouble - +(~~tempDouble >>> 0)) / +4294967296) >>> 0 : 0)], HEAP32[ptr >> 2] = tempI64[0], HEAP32[ptr + 4 >> 2] = tempI64[1];\r\n        break;\r\n      case \"float\":\r\n        HEAPF32[ptr >> 2] = value;\r\n        break;\r\n      case \"double\":\r\n        HEAPF64[ptr >> 3] = value;\r\n        break;\r\n      default:\r\n        abort(\"invalid type for setValue: \" + type);\r\n    }\r\n  }\r\n  function getValue(ptr, type, noSafe) {\r\n    type = type || \"i8\";\r\n    if (type.charAt(type.length - 1) === \"*\") { type = \"i32\"; }\r\n    switch (type) {\r\n      case \"i1\":\r\n        return HEAP8[ptr >> 0];\r\n      case \"i8\":\r\n        return HEAP8[ptr >> 0];\r\n      case \"i16\":\r\n        return HEAP16[ptr >> 1];\r\n      case \"i32\":\r\n        return HEAP32[ptr >> 2];\r\n      case \"i64\":\r\n        return HEAP32[ptr >> 2];\r\n      case \"float\":\r\n        return HEAPF32[ptr >> 2];\r\n      case \"double\":\r\n        return HEAPF64[ptr >> 3];\r\n      default:\r\n        abort(\"invalid type for getValue: \" + type);\r\n    }\r\n    return null;\r\n  }\r\n  var ABORT = false;\r\n  function assert(condition, text) {\r\n    if (!condition) {\r\n      abort(\"Assertion failed: \" + text);\r\n    }\r\n  }\r\n  function getCFunc(ident) {\r\n    var func = Module[\"_\" + ident];\r\n    assert(func, \"Cannot call unknown function \" + ident + \", make sure it is exported\");\r\n    return func;\r\n  }\r\n  function ccall(ident, returnType, argTypes, args, opts) {\r\n    var toC = {\r\n      \"string\": function (str) {\r\n        var ret = 0;\r\n        if (str !== null && str !== undefined && str !== 0) {\r\n          var len = (str.length << 2) + 1;\r\n          ret = stackAlloc(len);\r\n          stringToUTF8(str, ret, len);\r\n        }\r\n        return ret;\r\n      },\r\n      \"array\": function (arr) {\r\n        var ret = stackAlloc(arr.length);\r\n        writeArrayToMemory(arr, ret);\r\n        return ret;\r\n      }\r\n    };\r\n    function convertReturnValue(ret) {\r\n      if (returnType === \"string\") { return UTF8ToString(ret); }\r\n      if (returnType === \"boolean\") { return Boolean(ret); }\r\n      return ret;\r\n    }\r\n    var func = getCFunc(ident);\r\n    var cArgs = [];\r\n    var stack = 0;\r\n    if (args) {\r\n      for (var i = 0; i < args.length; i++) {\r\n        var converter = toC[argTypes[i]];\r\n        if (converter) {\r\n          if (stack === 0) { stack = stackSave(); }\r\n          cArgs[i] = converter(args[i]);\r\n        } else {\r\n          cArgs[i] = args[i];\r\n        }\r\n      }\r\n    }\r\n    var ret = func.apply(null, cArgs);\r\n    ret = convertReturnValue(ret);\r\n    if (stack !== 0) { stackRestore(stack); }\r\n    return ret;\r\n  }\r\n  function cwrap(ident, returnType, argTypes, opts) {\r\n    argTypes = argTypes || [];\r\n    var numericArgs = argTypes.every(function (type) {\r\n      return type === \"number\";\r\n    });\r\n    var numericRet = returnType !== \"string\";\r\n    if (numericRet && numericArgs && !opts) {\r\n      return getCFunc(ident);\r\n    }\r\n    return function () {\r\n      return ccall(ident, returnType, argTypes, arguments, opts);\r\n    };\r\n  }\r\n  var UTF8Decoder = typeof TextDecoder !== \"undefined\" ? new TextDecoder(\"utf8\") : undefined;\r\n  function UTF8ArrayToString(u8Array, idx, maxBytesToRead) {\r\n    var endIdx = idx + maxBytesToRead;\r\n    var endPtr = idx;\r\n    while (u8Array[endPtr] && !(endPtr >= endIdx)) { ++endPtr; }\r\n    if (endPtr - idx > 16 && u8Array.subarray && UTF8Decoder) {\r\n      return UTF8Decoder.decode(u8Array.subarray(idx, endPtr));\r\n    } else {\r\n      var str = \"\";\r\n      while (idx < endPtr) {\r\n        var u0 = u8Array[idx++];\r\n        if (!(u0 & 128)) {\r\n          str += String.fromCharCode(u0);\r\n          continue;\r\n        }\r\n        var u1 = u8Array[idx++] & 63;\r\n        if ((u0 & 224) == 192) {\r\n          str += String.fromCharCode((u0 & 31) << 6 | u1);\r\n          continue;\r\n        }\r\n        var u2 = u8Array[idx++] & 63;\r\n        if ((u0 & 240) == 224) {\r\n          u0 = (u0 & 15) << 12 | u1 << 6 | u2;\r\n        } else {\r\n          u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | u8Array[idx++] & 63;\r\n        }\r\n        if (u0 < 65536) {\r\n          str += String.fromCharCode(u0);\r\n        } else {\r\n          var ch = u0 - 65536;\r\n          str += String.fromCharCode(55296 | ch >> 10, 56320 | ch & 1023);\r\n        }\r\n      }\r\n    }\r\n    return str;\r\n  }\r\n  function UTF8ToString(ptr, maxBytesToRead) {\r\n    return ptr ? UTF8ArrayToString(HEAPU8, ptr, maxBytesToRead) : \"\";\r\n  }\r\n  function stringToUTF8Array(str, outU8Array, outIdx, maxBytesToWrite) {\r\n    if (!(maxBytesToWrite > 0)) { return 0; }\r\n    var startIdx = outIdx;\r\n    var endIdx = outIdx + maxBytesToWrite - 1;\r\n    for (var i = 0; i < str.length; ++i) {\r\n      var u = str.charCodeAt(i);\r\n      if (u >= 55296 && u <= 57343) {\r\n        var u1 = str.charCodeAt(++i);\r\n        u = 65536 + ((u & 1023) << 10) | u1 & 1023;\r\n      }\r\n      if (u <= 127) {\r\n        if (outIdx >= endIdx) { break; }\r\n        outU8Array[outIdx++] = u;\r\n      } else if (u <= 2047) {\r\n        if (outIdx + 1 >= endIdx) { break; }\r\n        outU8Array[outIdx++] = 192 | u >> 6;\r\n        outU8Array[outIdx++] = 128 | u & 63;\r\n      } else if (u <= 65535) {\r\n        if (outIdx + 2 >= endIdx) { break; }\r\n        outU8Array[outIdx++] = 224 | u >> 12;\r\n        outU8Array[outIdx++] = 128 | u >> 6 & 63;\r\n        outU8Array[outIdx++] = 128 | u & 63;\r\n      } else {\r\n        if (outIdx + 3 >= endIdx) { break; }\r\n        outU8Array[outIdx++] = 240 | u >> 18;\r\n        outU8Array[outIdx++] = 128 | u >> 12 & 63;\r\n        outU8Array[outIdx++] = 128 | u >> 6 & 63;\r\n        outU8Array[outIdx++] = 128 | u & 63;\r\n      }\r\n    }\r\n    outU8Array[outIdx] = 0;\r\n    return outIdx - startIdx;\r\n  }\r\n  function stringToUTF8(str, outPtr, maxBytesToWrite) {\r\n    return stringToUTF8Array(str, HEAPU8, outPtr, maxBytesToWrite);\r\n  }\r\n  var UTF16Decoder = typeof TextDecoder !== \"undefined\" ? new TextDecoder(\"utf-16le\") : undefined;\r\n  function writeArrayToMemory(array, buffer) {\r\n    HEAP8.set(array, buffer);\r\n  }\r\n  function alignUp(x, multiple) {\r\n    if (x % multiple > 0) {\r\n      x += multiple - x % multiple;\r\n    }\r\n    return x;\r\n  }\r\n  var buffer, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64;\r\n  function updateGlobalBufferAndViews(buf) {\r\n    buffer = buf;\r\n    Module[\"HEAP8\"] = HEAP8 = new Int8Array(buf);\r\n    Module[\"HEAP16\"] = HEAP16 = new Int16Array(buf);\r\n    Module[\"HEAP32\"] = HEAP32 = new Int32Array(buf);\r\n    Module[\"HEAPU8\"] = HEAPU8 = new Uint8Array(buf);\r\n    Module[\"HEAPU16\"] = HEAPU16 = new Uint16Array(buf);\r\n    Module[\"HEAPU32\"] = HEAPU32 = new Uint32Array(buf);\r\n    Module[\"HEAPF32\"] = HEAPF32 = new Float32Array(buf);\r\n    Module[\"HEAPF64\"] = HEAPF64 = new Float64Array(buf);\r\n  }\r\n  var DYNAMIC_BASE = 5271520,\r\n    DYNAMICTOP_PTR = 28608;\r\n  var INITIAL_TOTAL_MEMORY = Module[\"TOTAL_MEMORY\"] || 33554432;\r\n  if (Module[\"buffer\"]) {\r\n    buffer = Module[\"buffer\"];\r\n  } else {\r\n    buffer = new ArrayBuffer(INITIAL_TOTAL_MEMORY);\r\n  }\r\n  INITIAL_TOTAL_MEMORY = buffer.byteLength;\r\n  updateGlobalBufferAndViews(buffer);\r\n  HEAP32[DYNAMICTOP_PTR >> 2] = DYNAMIC_BASE;\r\n  function callRuntimeCallbacks(callbacks) {\r\n    while (callbacks.length > 0) {\r\n      var callback = callbacks.shift();\r\n      if (typeof callback == \"function\") {\r\n        callback();\r\n        continue;\r\n      }\r\n      var func = callback.func;\r\n      if (typeof func === \"number\") {\r\n        if (callback.arg === undefined) {\r\n          Module[\"dynCall_v\"](func);\r\n        } else {\r\n          Module[\"dynCall_vi\"](func, callback.arg);\r\n        }\r\n      } else {\r\n        func(callback.arg === undefined ? null : callback.arg);\r\n      }\r\n    }\r\n  }\r\n  var __ATPRERUN__ = [];\r\n  var __ATINIT__ = [];\r\n  var __ATMAIN__ = [];\r\n  var __ATPOSTRUN__ = [];\r\n  function preRun() {\r\n    if (Module[\"preRun\"]) {\r\n      if (typeof Module[\"preRun\"] == \"function\") { Module[\"preRun\"] = [Module[\"preRun\"]]; }\r\n      while (Module[\"preRun\"].length) {\r\n        addOnPreRun(Module[\"preRun\"].shift());\r\n      }\r\n    }\r\n    callRuntimeCallbacks(__ATPRERUN__);\r\n  }\r\n  function initRuntime() {\r\n    callRuntimeCallbacks(__ATINIT__);\r\n  }\r\n  function preMain() {\r\n    callRuntimeCallbacks(__ATMAIN__);\r\n  }\r\n  function postRun() {\r\n    if (Module[\"postRun\"]) {\r\n      if (typeof Module[\"postRun\"] == \"function\") { Module[\"postRun\"] = [Module[\"postRun\"]]; }\r\n      while (Module[\"postRun\"].length) {\r\n        addOnPostRun(Module[\"postRun\"].shift());\r\n      }\r\n    }\r\n    callRuntimeCallbacks(__ATPOSTRUN__);\r\n  }\r\n  function addOnPreRun(cb) {\r\n    __ATPRERUN__.unshift(cb);\r\n  }\r\n  function addOnPostRun(cb) {\r\n    __ATPOSTRUN__.unshift(cb);\r\n  }\r\n  var Math_abs = Math.abs;\r\n  var Math_ceil = Math.ceil;\r\n  var Math_floor = Math.floor;\r\n  var Math_min = Math.min;\r\n  var runDependencies = 0;\r\n  var runDependencyWatcher = null;\r\n  var dependenciesFulfilled = null;\r\n  function addRunDependency(id) {\r\n    runDependencies++;\r\n    if (Module[\"monitorRunDependencies\"]) {\r\n      Module[\"monitorRunDependencies\"](runDependencies);\r\n    }\r\n  }\r\n  function removeRunDependency(id) {\r\n    runDependencies--;\r\n    if (Module[\"monitorRunDependencies\"]) {\r\n      Module[\"monitorRunDependencies\"](runDependencies);\r\n    }\r\n    if (runDependencies == 0) {\r\n      if (runDependencyWatcher !== null) {\r\n        clearInterval(runDependencyWatcher);\r\n        runDependencyWatcher = null;\r\n      }\r\n      if (dependenciesFulfilled) {\r\n        var callback = dependenciesFulfilled;\r\n        dependenciesFulfilled = null;\r\n        callback();\r\n      }\r\n    }\r\n  }\r\n  Module[\"preloadedImages\"] = {};\r\n  Module[\"preloadedAudios\"] = {};\r\n  var memoryInitializer = null;\r\n  var dataURIPrefix = \"data:application/octet-stream;base64,\";\r\n  function isDataURI(filename) {\r\n    return String.prototype.startsWith ? filename.startsWith(dataURIPrefix) : filename.indexOf(dataURIPrefix) === 0;\r\n  }\r\n  var tempDouble;\r\n  var tempI64;\r\n  memoryInitializer = \"data:application/octet-stream;base64,AAAAAAAAAAAAAAAAAQAAAAIAAAADAAAABAAAAAUAAAAGAAAAAQAAAAQAAAADAAAABgAAAAUAAAACAAAAAAAAAAIAAAADAAAAAQAAAAQAAAAGAAAAAAAAAAUAAAADAAAABgAAAAQAAAAFAAAAAAAAAAEAAAACAAAABAAAAAUAAAAGAAAAAAAAAAIAAAADAAAAAQAAAAUAAAACAAAAAAAAAAEAAAADAAAABgAAAAQAAAAGAAAAAAAAAAUAAAACAAAAAQAAAAQAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAIAAAADAAAAAAAAAAAAAAACAAAAAAAAAAEAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAYAAAAAAAAABQAAAAAAAAAAAAAABAAAAAUAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAYAAAAAAAAABgAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAABAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAAAAAAAgAAAAMAAAAEAAAABQAAAAYAAAAAAAAAAQAAAAMAAAAEAAAABQAAAAYAAAAAAAAAAQAAAAIAAAAEAAAABQAAAAYAAAAAAAAAAQAAAAIAAAADAAAABQAAAAYAAAAAAAAAAQAAAAIAAAADAAAABAAAAAYAAAAAAAAAAQAAAAIAAAADAAAABAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAYAAAAAAAAAAwAAAAIAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAFAAAABAAAAAAAAAABAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAYAAAAAAAAABAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAFAAAAAgAAAAQAAAADAAAACAAAAAEAAAAHAAAABgAAAAkAAAAAAAAAAwAAAAIAAAACAAAABgAAAAoAAAALAAAAAAAAAAEAAAAFAAAAAwAAAA0AAAABAAAABwAAAAQAAAAMAAAAAAAAAAQAAAB/AAAADwAAAAgAAAADAAAAAAAAAAwAAAAFAAAAAgAAABIAAAAKAAAACAAAAAAAAAAQAAAABgAAAA4AAAALAAAAEQAAAAEAAAAJAAAAAgAAAAcAAAAVAAAACQAAABMAAAADAAAADQAAAAEAAAAIAAAABQAAABYAAAAQAAAABAAAAAAAAAAPAAAACQAAABMAAAAOAAAAFAAAAAEAAAAHAAAABgAAAAoAAAALAAAAGAAAABcAAAAFAAAAAgAAABIAAAALAAAAEQAAABcAAAAZAAAAAgAAAAYAAAAKAAAADAAAABwAAAANAAAAGgAAAAQAAAAPAAAAAwAAAA0AAAAaAAAAFQAAAB0AAAADAAAADAAAAAcAAAAOAAAAfwAAABEAAAAbAAAACQAAABQAAAAGAAAADwAAABYAAAAcAAAAHwAAAAQAAAAIAAAADAAAABAAAAASAAAAIQAAAB4AAAAIAAAABQAAABYAAAARAAAACwAAAA4AAAAGAAAAIwAAABkAAAAbAAAAEgAAABgAAAAeAAAAIAAAAAUAAAAKAAAAEAAAABMAAAAiAAAAFAAAACQAAAAHAAAAFQAAAAkAAAAUAAAADgAAABMAAAAJAAAAKAAAABsAAAAkAAAAFQAAACYAAAATAAAAIgAAAA0AAAAdAAAABwAAABYAAAAQAAAAKQAAACEAAAAPAAAACAAAAB8AAAAXAAAAGAAAAAsAAAAKAAAAJwAAACUAAAAZAAAAGAAAAH8AAAAgAAAAJQAAAAoAAAAXAAAAEgAAABkAAAAXAAAAEQAAAAsAAAAtAAAAJwAAACMAAAAaAAAAKgAAAB0AAAArAAAADAAAABwAAAANAAAAGwAAACgAAAAjAAAALgAAAA4AAAAUAAAAEQAAABwAAAAfAAAAKgAAACwAAAAMAAAADwAAABoAAAAdAAAAKwAAACYAAAAvAAAADQAAABoAAAAVAAAAHgAAACAAAAAwAAAAMgAAABAAAAASAAAAIQAAAB8AAAApAAAALAAAADUAAAAPAAAAFgAAABwAAAAgAAAAHgAAABgAAAASAAAANAAAADIAAAAlAAAAIQAAAB4AAAAxAAAAMAAAABYAAAAQAAAAKQAAACIAAAATAAAAJgAAABUAAAA2AAAAJAAAADMAAAAjAAAALgAAAC0AAAA4AAAAEQAAABsAAAAZAAAAJAAAABQAAAAiAAAAEwAAADcAAAAoAAAANgAAACUAAAAnAAAANAAAADkAAAAYAAAAFwAAACAAAAAmAAAAfwAAACIAAAAzAAAAHQAAAC8AAAAVAAAAJwAAACUAAAAZAAAAFwAAADsAAAA5AAAALQAAACgAAAAbAAAAJAAAABQAAAA8AAAALgAAADcAAAApAAAAMQAAADUAAAA9AAAAFgAAACEAAAAfAAAAKgAAADoAAAArAAAAPgAAABwAAAAsAAAAGgAAACsAAAA+AAAALwAAAEAAAAAaAAAAKgAAAB0AAAAsAAAANQAAADoAAABBAAAAHAAAAB8AAAAqAAAALQAAACcAAAAjAAAAGQAAAD8AAAA7AAAAOAAAAC4AAAA8AAAAOAAAAEQAAAAbAAAAKAAAACMAAAAvAAAAJgAAACsAAAAdAAAARQAAADMAAABAAAAAMAAAADEAAAAeAAAAIQAAAEMAAABCAAAAMgAAADEAAAB/AAAAPQAAAEIAAAAhAAAAMAAAACkAAAAyAAAAMAAAACAAAAAeAAAARgAAAEMAAAA0AAAAMwAAAEUAAAA2AAAARwAAACYAAAAvAAAAIgAAADQAAAA5AAAARgAAAEoAAAAgAAAAJQAAADIAAAA1AAAAPQAAAEEAAABLAAAAHwAAACkAAAAsAAAANgAAAEcAAAA3AAAASQAAACIAAAAzAAAAJAAAADcAAAAoAAAANgAAACQAAABIAAAAPAAAAEkAAAA4AAAARAAAAD8AAABNAAAAIwAAAC4AAAAtAAAAOQAAADsAAABKAAAATgAAACUAAAAnAAAANAAAADoAAAB/AAAAPgAAAEwAAAAsAAAAQQAAACoAAAA7AAAAPwAAAE4AAABPAAAAJwAAAC0AAAA5AAAAPAAAAEgAAABEAAAAUAAAACgAAAA3AAAALgAAAD0AAAA1AAAAMQAAACkAAABRAAAASwAAAEIAAAA+AAAAKwAAADoAAAAqAAAAUgAAAEAAAABMAAAAPwAAAH8AAAA4AAAALQAAAE8AAAA7AAAATQAAAEAAAAAvAAAAPgAAACsAAABUAAAARQAAAFIAAABBAAAAOgAAADUAAAAsAAAAVgAAAEwAAABLAAAAQgAAAEMAAABRAAAAVQAAADEAAAAwAAAAPQAAAEMAAABCAAAAMgAAADAAAABXAAAAVQAAAEYAAABEAAAAOAAAADwAAAAuAAAAWgAAAE0AAABQAAAARQAAADMAAABAAAAALwAAAFkAAABHAAAAVAAAAEYAAABDAAAANAAAADIAAABTAAAAVwAAAEoAAABHAAAAWQAAAEkAAABbAAAAMwAAAEUAAAA2AAAASAAAAH8AAABJAAAANwAAAFAAAAA8AAAAWAAAAEkAAABbAAAASAAAAFgAAAA2AAAARwAAADcAAABKAAAATgAAAFMAAABcAAAANAAAADkAAABGAAAASwAAAEEAAAA9AAAANQAAAF4AAABWAAAAUQAAAEwAAABWAAAAUgAAAGAAAAA6AAAAQQAAAD4AAABNAAAAPwAAAEQAAAA4AAAAXQAAAE8AAABaAAAATgAAAEoAAAA7AAAAOQAAAF8AAABcAAAATwAAAE8AAABOAAAAPwAAADsAAABdAAAAXwAAAE0AAABQAAAARAAAAEgAAAA8AAAAYwAAAFoAAABYAAAAUQAAAFUAAABeAAAAZQAAAD0AAABCAAAASwAAAFIAAABgAAAAVAAAAGIAAAA+AAAATAAAAEAAAABTAAAAfwAAAEoAAABGAAAAZAAAAFcAAABcAAAAVAAAAEUAAABSAAAAQAAAAGEAAABZAAAAYgAAAFUAAABXAAAAZQAAAGYAAABCAAAAQwAAAFEAAABWAAAATAAAAEsAAABBAAAAaAAAAGAAAABeAAAAVwAAAFMAAABmAAAAZAAAAEMAAABGAAAAVQAAAFgAAABIAAAAWwAAAEkAAABjAAAAUAAAAGkAAABZAAAAYQAAAFsAAABnAAAARQAAAFQAAABHAAAAWgAAAE0AAABQAAAARAAAAGoAAABdAAAAYwAAAFsAAABJAAAAWQAAAEcAAABpAAAAWAAAAGcAAABcAAAAUwAAAE4AAABKAAAAbAAAAGQAAABfAAAAXQAAAE8AAABaAAAATQAAAG0AAABfAAAAagAAAF4AAABWAAAAUQAAAEsAAABrAAAAaAAAAGUAAABfAAAAXAAAAE8AAABOAAAAbQAAAGwAAABdAAAAYAAAAGgAAABiAAAAbgAAAEwAAABWAAAAUgAAAGEAAAB/AAAAYgAAAFQAAABnAAAAWQAAAG8AAABiAAAAbgAAAGEAAABvAAAAUgAAAGAAAABUAAAAYwAAAFAAAABpAAAAWAAAAGoAAABaAAAAcQAAAGQAAABmAAAAUwAAAFcAAABsAAAAcgAAAFwAAABlAAAAZgAAAGsAAABwAAAAUQAAAFUAAABeAAAAZgAAAGUAAABXAAAAVQAAAHIAAABwAAAAZAAAAGcAAABbAAAAYQAAAFkAAAB0AAAAaQAAAG8AAABoAAAAawAAAG4AAABzAAAAVgAAAF4AAABgAAAAaQAAAFgAAABnAAAAWwAAAHEAAABjAAAAdAAAAGoAAABdAAAAYwAAAFoAAAB1AAAAbQAAAHEAAABrAAAAfwAAAGUAAABeAAAAcwAAAGgAAABwAAAAbAAAAGQAAABfAAAAXAAAAHYAAAByAAAAbQAAAG0AAABsAAAAXQAAAF8AAAB1AAAAdgAAAGoAAABuAAAAYgAAAGgAAABgAAAAdwAAAG8AAABzAAAAbwAAAGEAAABuAAAAYgAAAHQAAABnAAAAdwAAAHAAAABrAAAAZgAAAGUAAAB4AAAAcwAAAHIAAABxAAAAYwAAAHQAAABpAAAAdQAAAGoAAAB5AAAAcgAAAHAAAABkAAAAZgAAAHYAAAB4AAAAbAAAAHMAAABuAAAAawAAAGgAAAB4AAAAdwAAAHAAAAB0AAAAZwAAAHcAAABvAAAAcQAAAGkAAAB5AAAAdQAAAH8AAABtAAAAdgAAAHEAAAB5AAAAagAAAHYAAAB4AAAAbAAAAHIAAAB1AAAAeQAAAG0AAAB3AAAAbwAAAHMAAABuAAAAeQAAAHQAAAB4AAAAeAAAAHMAAAByAAAAcAAAAHkAAAB3AAAAdgAAAHkAAAB0AAAAeAAAAHcAAAB1AAAAcQAAAHYAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAABAAAABQAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAACAAAABQAAAAEAAAAAAAAA/////wEAAAAAAAAAAwAAAAQAAAACAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAAQAAAAAAAAAAAAAAAQAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAADAAAAAAAAAAAAAAABAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAADAAAABQAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAP////8DAAAAAAAAAAUAAAACAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAEAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAFAAAABQAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAAAAAD/////AwAAAAAAAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAABAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAQAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAAAAAP////8DAAAAAAAAAAUAAAACAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAUAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAFAAAABQAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAAAAAADAAAAAwAAAAMAAAAAAAAAAwAAAAAAAAAAAAAA/////wMAAAAAAAAABQAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAADAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAA/////wMAAAAAAAAABQAAAAIAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAMAAAADAAAAAwAAAAMAAAAAAAAAAwAAAAAAAAD/////AwAAAAAAAAAFAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAAAAAMAAAADAAAAAwAAAAAAAAADAAAAAAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAADAAAAAAAAAAAAAAD/////AwAAAAAAAAAFAAAAAgAAAAAAAAAAAAAAAwAAAAMAAAADAAAAAAAAAAAAAAADAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAFAAAAAAAAAAAAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAQAAAAAAAAABAAAAAAAAAAAAAAABAAAAAwAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAwAAAAAAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAADAAAAAAAAAP////8DAAAAAAAAAAUAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAAAAAAAAAAADAAAAAwAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAUAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAFAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAwAAAAAAAAAAAAAA/////wMAAAAAAAAABQAAAAIAAAAAAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAAFAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAQAAAAAAAAABAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAwAAAAAAAAADAAAAAwAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAQAAAAAAAAABAAAAAAAAAAMAAAADAAAAAwAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAAUAAAABAAAAAAAAAP////8DAAAAAAAAAAUAAAACAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAABAAAAAUAAAABAAAAAAAAAAMAAAADAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAFAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAADAAAAAQAAAAAAAAABAAAAAAAAAAUAAAAAAAAAAAAAAAUAAAAFAAAAAAAAAAAAAAD/////AQAAAAAAAAADAAAABAAAAAIAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAUAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAFAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAUAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAEAAAD//////////wEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAACAAAAAAAAAAAAAAABAAAAAgAAAAYAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAYAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAKAAAAAgAAAAAAAAAAAAAAAQAAAAEAAAAFAAAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAACAAAAAAAAAAAAAAABAAAAAwAAAAcAAAAGAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAABwAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAADAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAADgAAAAIAAAAAAAAAAAAAAAEAAAAAAAAACQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAMAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAABwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAAIAAAAAAAAAAAAAAAEAAAAEAAAACAAAAAoAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAALAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAACQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAgAAAAAAAAAAAAAAAQAAAAsAAAAPAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAOAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAIAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAABQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHAAAAAgAAAAAAAAAAAAAAAQAAAAwAAAAQAAAADAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAoAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAPAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAADwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAOAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAADQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAACAAAAAAAAAAAAAAABAAAACgAAABMAAAAIAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAOAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAwAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAQAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAACQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAIAAAAAAAAAAAAAAAEAAAANAAAAEQAAAA0AAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAARAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAEwAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAATAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAEQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAA0AAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAACAAAAAAAAAAAAAAABAAAADgAAABIAAAAPAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAADwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAASAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAEwAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAABEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABIAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAATAAAAAgAAAAAAAAAAAAAAAQAAAP//////////EwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAEgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAASAAAAAAAAABgAAAAAAAAAIQAAAAAAAAAeAAAAAAAAACAAAAADAAAAMQAAAAEAAAAwAAAAAwAAADIAAAADAAAACAAAAAAAAAAFAAAABQAAAAoAAAAFAAAAFgAAAAAAAAAQAAAAAAAAABIAAAAAAAAAKQAAAAEAAAAhAAAAAAAAAB4AAAAAAAAABAAAAAAAAAAAAAAABQAAAAIAAAAFAAAADwAAAAEAAAAIAAAAAAAAAAUAAAAFAAAAHwAAAAEAAAAWAAAAAAAAABAAAAAAAAAAAgAAAAAAAAAGAAAAAAAAAA4AAAAAAAAACgAAAAAAAAALAAAAAAAAABEAAAADAAAAGAAAAAEAAAAXAAAAAwAAABkAAAADAAAAAAAAAAAAAAABAAAABQAAAAkAAAAFAAAABQAAAAAAAAACAAAAAAAAAAYAAAAAAAAAEgAAAAEAAAAKAAAAAAAAAAsAAAAAAAAABAAAAAEAAAADAAAABQAAAAcAAAAFAAAACAAAAAEAAAAAAAAAAAAAAAEAAAAFAAAAEAAAAAEAAAAFAAAAAAAAAAIAAAAAAAAABwAAAAAAAAAVAAAAAAAAACYAAAAAAAAACQAAAAAAAAATAAAAAAAAACIAAAADAAAADgAAAAEAAAAUAAAAAwAAACQAAAADAAAAAwAAAAAAAAANAAAABQAAAB0AAAAFAAAAAQAAAAAAAAAHAAAAAAAAABUAAAAAAAAABgAAAAEAAAAJAAAAAAAAABMAAAAAAAAABAAAAAIAAAAMAAAABQAAABoAAAAFAAAAAAAAAAEAAAADAAAAAAAAAA0AAAAFAAAAAgAAAAEAAAABAAAAAAAAAAcAAAAAAAAAGgAAAAAAAAAqAAAAAAAAADoAAAAAAAAAHQAAAAAAAAArAAAAAAAAAD4AAAADAAAAJgAAAAEAAAAvAAAAAwAAAEAAAAADAAAADAAAAAAAAAAcAAAABQAAACwAAAAFAAAADQAAAAAAAAAaAAAAAAAAACoAAAAAAAAAFQAAAAEAAAAdAAAAAAAAACsAAAAAAAAABAAAAAMAAAAPAAAABQAAAB8AAAAFAAAAAwAAAAEAAAAMAAAAAAAAABwAAAAFAAAABwAAAAEAAAANAAAAAAAAABoAAAAAAAAAHwAAAAAAAAApAAAAAAAAADEAAAAAAAAALAAAAAAAAAA1AAAAAAAAAD0AAAADAAAAOgAAAAEAAABBAAAAAwAAAEsAAAADAAAADwAAAAAAAAAWAAAABQAAACEAAAAFAAAAHAAAAAAAAAAfAAAAAAAAACkAAAAAAAAAKgAAAAEAAAAsAAAAAAAAADUAAAAAAAAABAAAAAQAAAAIAAAABQAAABAAAAAFAAAADAAAAAEAAAAPAAAAAAAAABYAAAAFAAAAGgAAAAEAAAAcAAAAAAAAAB8AAAAAAAAAMgAAAAAAAAAwAAAAAAAAADEAAAADAAAAIAAAAAAAAAAeAAAAAwAAACEAAAADAAAAGAAAAAMAAAASAAAAAwAAABAAAAADAAAARgAAAAAAAABDAAAAAAAAAEIAAAADAAAANAAAAAMAAAAyAAAAAAAAADAAAAAAAAAAJQAAAAMAAAAgAAAAAAAAAB4AAAADAAAAUwAAAAAAAABXAAAAAwAAAFUAAAADAAAASgAAAAMAAABGAAAAAAAAAEMAAAAAAAAAOQAAAAEAAAA0AAAAAwAAADIAAAAAAAAAGQAAAAAAAAAXAAAAAAAAABgAAAADAAAAEQAAAAAAAAALAAAAAwAAAAoAAAADAAAADgAAAAMAAAAGAAAAAwAAAAIAAAADAAAALQAAAAAAAAAnAAAAAAAAACUAAAADAAAAIwAAAAMAAAAZAAAAAAAAABcAAAAAAAAAGwAAAAMAAAARAAAAAAAAAAsAAAADAAAAPwAAAAAAAAA7AAAAAwAAADkAAAADAAAAOAAAAAMAAAAtAAAAAAAAACcAAAAAAAAALgAAAAMAAAAjAAAAAwAAABkAAAAAAAAAJAAAAAAAAAAUAAAAAAAAAA4AAAADAAAAIgAAAAAAAAATAAAAAwAAAAkAAAADAAAAJgAAAAMAAAAVAAAAAwAAAAcAAAADAAAANwAAAAAAAAAoAAAAAAAAABsAAAADAAAANgAAAAMAAAAkAAAAAAAAABQAAAAAAAAAMwAAAAMAAAAiAAAAAAAAABMAAAADAAAASAAAAAAAAAA8AAAAAwAAAC4AAAADAAAASQAAAAMAAAA3AAAAAAAAACgAAAAAAAAARwAAAAMAAAA2AAAAAwAAACQAAAAAAAAAQAAAAAAAAAAvAAAAAAAAACYAAAADAAAAPgAAAAAAAAArAAAAAwAAAB0AAAADAAAAOgAAAAMAAAAqAAAAAwAAABoAAAADAAAAVAAAAAAAAABFAAAAAAAAADMAAAADAAAAUgAAAAMAAABAAAAAAAAAAC8AAAAAAAAATAAAAAMAAAA+AAAAAAAAACsAAAADAAAAYQAAAAAAAABZAAAAAwAAAEcAAAADAAAAYgAAAAMAAABUAAAAAAAAAEUAAAAAAAAAYAAAAAMAAABSAAAAAwAAAEAAAAAAAAAASwAAAAAAAABBAAAAAAAAADoAAAADAAAAPQAAAAAAAAA1AAAAAwAAACwAAAADAAAAMQAAAAMAAAApAAAAAwAAAB8AAAADAAAAXgAAAAAAAABWAAAAAAAAAEwAAAADAAAAUQAAAAMAAABLAAAAAAAAAEEAAAAAAAAAQgAAAAMAAAA9AAAAAAAAADUAAAADAAAAawAAAAAAAABoAAAAAwAAAGAAAAADAAAAZQAAAAMAAABeAAAAAAAAAFYAAAAAAAAAVQAAAAMAAABRAAAAAwAAAEsAAAAAAAAAOQAAAAAAAAA7AAAAAAAAAD8AAAADAAAASgAAAAAAAABOAAAAAwAAAE8AAAADAAAAUwAAAAMAAABcAAAAAwAAAF8AAAADAAAAJQAAAAAAAAAnAAAAAwAAAC0AAAADAAAANAAAAAAAAAA5AAAAAAAAADsAAAAAAAAARgAAAAMAAABKAAAAAAAAAE4AAAADAAAAGAAAAAAAAAAXAAAAAwAAABkAAAADAAAAIAAAAAMAAAAlAAAAAAAAACcAAAADAAAAMgAAAAMAAAA0AAAAAAAAADkAAAAAAAAALgAAAAAAAAA8AAAAAAAAAEgAAAADAAAAOAAAAAAAAABEAAAAAwAAAFAAAAADAAAAPwAAAAMAAABNAAAAAwAAAFoAAAADAAAAGwAAAAAAAAAoAAAAAwAAADcAAAADAAAAIwAAAAAAAAAuAAAAAAAAADwAAAAAAAAALQAAAAMAAAA4AAAAAAAAAEQAAAADAAAADgAAAAAAAAAUAAAAAwAAACQAAAADAAAAEQAAAAMAAAAbAAAAAAAAACgAAAADAAAAGQAAAAMAAAAjAAAAAAAAAC4AAAAAAAAARwAAAAAAAABZAAAAAAAAAGEAAAADAAAASQAAAAAAAABbAAAAAwAAAGcAAAADAAAASAAAAAMAAABYAAAAAwAAAGkAAAADAAAAMwAAAAAAAABFAAAAAwAAAFQAAAADAAAANgAAAAAAAABHAAAAAAAAAFkAAAAAAAAANwAAAAMAAABJAAAAAAAAAFsAAAADAAAAJgAAAAAAAAAvAAAAAwAAAEAAAAADAAAAIgAAAAMAAAAzAAAAAAAAAEUAAAADAAAAJAAAAAMAAAA2AAAAAAAAAEcAAAAAAAAAYAAAAAAAAABoAAAAAAAAAGsAAAADAAAAYgAAAAAAAABuAAAAAwAAAHMAAAADAAAAYQAAAAMAAABvAAAAAwAAAHcAAAADAAAATAAAAAAAAABWAAAAAwAAAF4AAAADAAAAUgAAAAAAAABgAAAAAAAAAGgAAAAAAAAAVAAAAAMAAABiAAAAAAAAAG4AAAADAAAAOgAAAAAAAABBAAAAAwAAAEsAAAADAAAAPgAAAAMAAABMAAAAAAAAAFYAAAADAAAAQAAAAAMAAABSAAAAAAAAAGAAAAAAAAAAVQAAAAAAAABXAAAAAAAAAFMAAAADAAAAZQAAAAAAAABmAAAAAwAAAGQAAAADAAAAawAAAAMAAABwAAAAAwAAAHIAAAADAAAAQgAAAAAAAABDAAAAAwAAAEYAAAADAAAAUQAAAAAAAABVAAAAAAAAAFcAAAAAAAAAXgAAAAMAAABlAAAAAAAAAGYAAAADAAAAMQAAAAAAAAAwAAAAAwAAADIAAAADAAAAPQAAAAMAAABCAAAAAAAAAEMAAAADAAAASwAAAAMAAABRAAAAAAAAAFUAAAAAAAAAXwAAAAAAAABcAAAAAAAAAFMAAAAAAAAATwAAAAAAAABOAAAAAAAAAEoAAAADAAAAPwAAAAEAAAA7AAAAAwAAADkAAAADAAAAbQAAAAAAAABsAAAAAAAAAGQAAAAFAAAAXQAAAAEAAABfAAAAAAAAAFwAAAAAAAAATQAAAAEAAABPAAAAAAAAAE4AAAAAAAAAdQAAAAQAAAB2AAAABQAAAHIAAAAFAAAAagAAAAEAAABtAAAAAAAAAGwAAAAAAAAAWgAAAAEAAABdAAAAAQAAAF8AAAAAAAAAWgAAAAAAAABNAAAAAAAAAD8AAAAAAAAAUAAAAAAAAABEAAAAAAAAADgAAAADAAAASAAAAAEAAAA8AAAAAwAAAC4AAAADAAAAagAAAAAAAABdAAAAAAAAAE8AAAAFAAAAYwAAAAEAAABaAAAAAAAAAE0AAAAAAAAAWAAAAAEAAABQAAAAAAAAAEQAAAAAAAAAdQAAAAMAAABtAAAABQAAAF8AAAAFAAAAcQAAAAEAAABqAAAAAAAAAF0AAAAAAAAAaQAAAAEAAABjAAAAAQAAAFoAAAAAAAAAaQAAAAAAAABYAAAAAAAAAEgAAAAAAAAAZwAAAAAAAABbAAAAAAAAAEkAAAADAAAAYQAAAAEAAABZAAAAAwAAAEcAAAADAAAAcQAAAAAAAABjAAAAAAAAAFAAAAAFAAAAdAAAAAEAAABpAAAAAAAAAFgAAAAAAAAAbwAAAAEAAABnAAAAAAAAAFsAAAAAAAAAdQAAAAIAAABqAAAABQAAAFoAAAAFAAAAeQAAAAEAAABxAAAAAAAAAGMAAAAAAAAAdwAAAAEAAAB0AAAAAQAAAGkAAAAAAAAAdwAAAAAAAABvAAAAAAAAAGEAAAAAAAAAcwAAAAAAAABuAAAAAAAAAGIAAAADAAAAawAAAAEAAABoAAAAAwAAAGAAAAADAAAAeQAAAAAAAAB0AAAAAAAAAGcAAAAFAAAAeAAAAAEAAAB3AAAAAAAAAG8AAAAAAAAAcAAAAAEAAABzAAAAAAAAAG4AAAAAAAAAdQAAAAEAAABxAAAABQAAAGkAAAAFAAAAdgAAAAEAAAB5AAAAAAAAAHQAAAAAAAAAcgAAAAEAAAB4AAAAAQAAAHcAAAAAAAAAcgAAAAAAAABwAAAAAAAAAGsAAAAAAAAAZAAAAAAAAABmAAAAAAAAAGUAAAADAAAAUwAAAAEAAABXAAAAAwAAAFUAAAADAAAAdgAAAAAAAAB4AAAAAAAAAHMAAAAFAAAAbAAAAAEAAAByAAAAAAAAAHAAAAAAAAAAXAAAAAEAAABkAAAAAAAAAGYAAAAAAAAAdQAAAAAAAAB5AAAABQAAAHcAAAAFAAAAbQAAAAEAAAB2AAAAAAAAAHgAAAAAAAAAXwAAAAEAAABsAAAAAQAAAHIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAGAAAAAgAAAAUAAAABAAAABAAAAAAAAAAAAAAABQAAAAMAAAABAAAABgAAAAQAAAACAAAAAAAAAH6iBfbytuk/Gq6akm/58z/Xrm0Liez0P5doSdOpSwRAWs602ULg8D/dT7Rcbo/1v1N1RQHFNOM/g9Snx7HW3L8HWsP8Q3jfP6VwOLosutk/9rjk1YQcxj+gnmKMsNn6P/HDeuPFY+M/YHwDjqKhB0Ci19/fCVrbP4UxKkDWOP6/pvljWa09tL9wi7wrQXjnv/Z6yLImkM2/3yTlOzY14D+m+WNZrT20PzwKVQnrQwNA9nrIsiaQzT/g40rFrRQFwPa45NWEHMa/kbslHEZq97/xw3rjxWPjv4cLC2SMBci/otff3wla27+rKF5oIAv0P1N1RQHFNOO/iDJPGyWHBUAHWsP8Q3jfvwQf/by16gXAfqIF9vK26b8XrO0Vh0r+v9eubQuJ7PS/BxLrA0ZZ479azrTZQuDwv1MK1EuItPw/yscgV9Z6FkAwHBR2WjQMQJNRzXsQ5vY/GlUHVJYKF0DONuFv2lMNQNCGZ28QJfk/0WUwoIL36D8ggDOMQuATQNqMOeAy/wZAWFYOYM+M2z/LWC4uH3oSQDE+LyTsMgRAkJzhRGWFGEDd4soovCQQQKqk0DJMEP8/rGmNdwOLBUAW2X/9xCbjP4hu3dcqJhNAzuYItRvdB0CgzW3zJW/sPxotm/Y2TxRAQAk9XmdDDEC1Kx9MKgT3P1M+NctcghZAFVqcLlb0C0Bgzd3sB2b2P77mZDPUWhZAFROHJpUGCEDAfma5CxXtPz1DWq/zYxRAmhYY5824F0DOuQKWSbAOQNCMqrvu3fs/L6DR22K2wT9nAAxPBU8RQGiN6mW43AFAZhu25b633D8c1YgmzowSQNM25BRKWARArGS08/lNxD+LFssHwmMRQLC5aNcxBgJABL9HT0WRF0CjCmJmOGEOQHsuaVzMP/s/TWJCaGGwBUCeu1PAPLzjP9nqN9DZOBNAKE4JcydbCkCGtbd1qjPzP8dgm9U8jhVAtPeKTkVwDkCeCLss5l37P401XMPLmBdAFd29VMVQDUBg0yA55h75Pz6odcYLCRdApBM4rBrkAkDyAVWgQxbRP4XDMnK20hFAymLlF7EmzD8GUgo9XBHlP3lbK7T9COc/k+OhPthhy7+YGEpnrOvCPzBFhLs15u4/epbqB6H4uz9IuuLF5svev6lzLKY31es/CaQ0envF5z8ZY0xlUADXv7zaz7HYEuI/CfbK1sn16T8uAQfWwxLWPzKn/YuFN94/5KdbC1AFu793fyCSnlfvPzK2y4doAMY/NRg5t1/X6b/shq4QJaHDP5yNIAKPOeI/vpn7BSE30r/X4YQrO6nrv78Ziv/Thto/DqJ1Y6+y5z9l51NaxFrlv8QlA65HOLS/86dxiEc96z+Hj0+LFjneP6LzBZ8LTc2/DaJ1Y6+y579l51NaxFrlP8QlA65HOLQ/8qdxiEc967+Jj0+LFjnev6LzBZ8LTc0/1qdbC1AFuz93fyCSnlfvvzK2y4doAMa/NRg5t1/X6T/vhq4QJaHDv5yNIAKPOeK/wJn7BSE30j/W4YQrO6nrP78Ziv/Thtq/CaQ0envF578XY0xlUADXP7zaz7HYEuK/CvbK1sn16b8rAQfWwxLWvzKn/YuFN96/zWLlF7EmzL8GUgo9XBHlv3lbK7T9COe/kOOhPthhyz+cGEpnrOvCvzBFhLs15u6/c5bqB6H4u79IuuLF5sveP6lzLKY31eu/AQAAAP////8HAAAA/////zEAAAD/////VwEAAP////9hCQAA/////6dBAAD/////kcsBAP/////3kAwA/////8H2VwAAAAAAAAAAAAAAAAACAAAA/////w4AAAD/////YgAAAP////+uAgAA/////8ISAAD/////ToMAAP////8ilwMA/////+4hGQD/////gu2vAAAAAAAAAAAAAAAAAAAAAAACAAAA//////////8BAAAAAwAAAP//////////////////////////////////////////////////////////////////////////AQAAAAAAAAACAAAA////////////////AwAAAP//////////////////////////////////////////////////////////////////////////AQAAAAAAAAACAAAA////////////////AwAAAP//////////////////////////////////////////////////////////////////////////AQAAAAAAAAACAAAA////////////////AwAAAP//////////////////////////////////////////////////////////AgAAAP//////////AQAAAAAAAAD/////////////////////AwAAAP////////////////////////////////////////////////////8DAAAA/////////////////////wAAAAD/////////////////////AQAAAP///////////////wIAAAD///////////////////////////////8DAAAA/////////////////////wAAAAD///////////////8CAAAAAQAAAP////////////////////////////////////////////////////8DAAAA/////////////////////wAAAAD///////////////8CAAAAAQAAAP////////////////////////////////////////////////////8DAAAA/////////////////////wAAAAD///////////////8CAAAAAQAAAP////////////////////////////////////////////////////8DAAAA/////////////////////wAAAAD///////////////8CAAAAAQAAAP////////////////////////////////////////////////////8BAAAAAgAAAP///////////////wAAAAD/////////////////////AwAAAP////////////////////////////////////////////////////8BAAAAAgAAAP///////////////wAAAAD/////////////////////AwAAAP////////////////////////////////////////////////////8BAAAAAgAAAP///////////////wAAAAD/////////////////////AwAAAP////////////////////////////////////////////////////8BAAAAAgAAAP///////////////wAAAAD/////////////////////AwAAAP///////////////////////////////wIAAAD///////////////8BAAAA/////////////////////wAAAAD/////////////////////AwAAAP////////////////////////////////////////////////////8DAAAA/////////////////////wAAAAABAAAA//////////8CAAAA//////////////////////////////////////////////////////////8DAAAA////////////////AgAAAAAAAAABAAAA//////////////////////////////////////////////////////////////////////////8DAAAA////////////////AgAAAAAAAAABAAAA//////////////////////////////////////////////////////////////////////////8DAAAA////////////////AgAAAAAAAAABAAAA//////////////////////////////////////////////////////////////////////////8DAAAAAQAAAP//////////AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAACAAAAAAAAAAIAAAABAAAAAQAAAAIAAAACAAAAAAAAAAUAAAAFAAAAAAAAAAIAAAACAAAAAwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAgAAAAEAAAACAAAAAgAAAAIAAAAAAAAABQAAAAYAAAAAAAAAAgAAAAIAAAADAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAACAAAAAQAAAAMAAAACAAAAAgAAAAAAAAAFAAAABwAAAAAAAAACAAAAAgAAAAMAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAACAAAAAAAAAAIAAAABAAAABAAAAAIAAAACAAAAAAAAAAUAAAAIAAAAAAAAAAIAAAACAAAAAwAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAIAAAAAAAAAAgAAAAEAAAAAAAAAAgAAAAIAAAAAAAAABQAAAAkAAAAAAAAAAgAAAAIAAAADAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAKAAAAAgAAAAIAAAAAAAAAAwAAAA4AAAACAAAAAAAAAAIAAAADAAAAAAAAAAAAAAACAAAAAgAAAAMAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAACAAAAAgAAAAAAAAADAAAACgAAAAIAAAAAAAAAAgAAAAMAAAABAAAAAAAAAAIAAAACAAAAAwAAAAcAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAIAAAACAAAAAAAAAAMAAAALAAAAAgAAAAAAAAACAAAAAwAAAAIAAAAAAAAAAgAAAAIAAAADAAAACAAAAAAAAAAAAAAAAAAAAAAAAAANAAAAAgAAAAIAAAAAAAAAAwAAAAwAAAACAAAAAAAAAAIAAAADAAAAAwAAAAAAAAACAAAAAgAAAAMAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAA4AAAACAAAAAgAAAAAAAAADAAAADQAAAAIAAAAAAAAAAgAAAAMAAAAEAAAAAAAAAAIAAAACAAAAAwAAAAoAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAIAAAACAAAAAAAAAAMAAAAGAAAAAgAAAAAAAAACAAAAAwAAAA8AAAAAAAAAAgAAAAIAAAADAAAACwAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAgAAAAIAAAAAAAAAAwAAAAcAAAACAAAAAAAAAAIAAAADAAAAEAAAAAAAAAACAAAAAgAAAAMAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAACAAAAAgAAAAAAAAADAAAACAAAAAIAAAAAAAAAAgAAAAMAAAARAAAAAAAAAAIAAAACAAAAAwAAAA0AAAAAAAAAAAAAAAAAAAAAAAAACAAAAAIAAAACAAAAAAAAAAMAAAAJAAAAAgAAAAAAAAACAAAAAwAAABIAAAAAAAAAAgAAAAIAAAADAAAADgAAAAAAAAAAAAAAAAAAAAAAAAAJAAAAAgAAAAIAAAAAAAAAAwAAAAUAAAACAAAAAAAAAAIAAAADAAAAEwAAAAAAAAACAAAAAgAAAAMAAAAPAAAAAAAAAAAAAAAAAAAAAAAAABAAAAACAAAAAAAAAAIAAAABAAAAEwAAAAIAAAACAAAAAAAAAAUAAAAKAAAAAAAAAAIAAAACAAAAAwAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAAAIAAAAAAAAAAgAAAAEAAAAPAAAAAgAAAAIAAAAAAAAABQAAAAsAAAAAAAAAAgAAAAIAAAADAAAAEQAAAAAAAAAAAAAAAAAAAAAAAAASAAAAAgAAAAAAAAACAAAAAQAAABAAAAACAAAAAgAAAAAAAAAFAAAADAAAAAAAAAACAAAAAgAAAAMAAAASAAAAAAAAAAAAAAAAAAAAAAAAABMAAAACAAAAAAAAAAIAAAABAAAAEQAAAAIAAAACAAAAAAAAAAUAAAANAAAAAAAAAAIAAAACAAAAAwAAABMAAAAAAAAAAAAAAAAAAAAAAAAADwAAAAIAAAAAAAAAAgAAAAEAAAASAAAAAgAAAAIAAAAAAAAABQAAAA4AAAAAAAAAAgAAAAIAAAADAAAAAgAAAAEAAAAAAAAAAQAAAAIAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAEAAAACAAAAAQAAAAAAAAACAAAAAAAAAAUAAAAEAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAFAAAABAAAAAAAAAABAAAABQAAAAQAAAAAAAAABQAAAAAAAAACAAAAAQAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAgAAAAEAAAAAAAAAAQAAAAIAAAABAAAAAAAAAAIAAAACAAAAAAAAAAEAAAAAAAAAAAAAAAUAAAAEAAAAAAAAAAEAAAAFAAAAAAAAAAAAAAAFAAAABAAAAAAAAAABAAAABQAAAAQAAAAAAAAABQAAAAUAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAEAAAAAAQAAAAAAAAAAAQAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAAAAQAAAAAAAAAAAAA6B6FaUp9QQTPXMuL4myJBraiDfBwx9UBYJseitzTIQOL5if9jqZtAnXX+Z+ycb0C3pucbhRBCQG8wJBYqpRRAlWbDCzCY5z/eFWBUEve6P/+qo4Q50Y4/D9YM3iCcYT8fcA2QJSA0P4ADxu0qAAc/BNcGolVJ2j5d9FACqwquPh9z7MthtI9CSUSYJke/YUJQ/64OyjU0Qpi0+HCmFQdCm3GfIVdh2kHsJ11kAyauQYC3UDFJOoFBSJsFV1OwU0FK5fcxX4AmQWhy/zZIt/lACqaCPsBjzUDbdUNIScugQMYQlVJ4MXNANiuq8GTvRUDxTXnulxEZQFZ8QX5kpuw/qmG/JwYFlEAluh3Q6DB+QKn4vyNq0GZAKOXekas+UUB8xabXXhI6QG63C2pLtSNAdDBtyNfLDUDyOcu67ID2P0rCMvRXAeE/Ki2TSVyzyT9Dk+8Sz2uzP5J+w5ARWp0/NQAoOiMuhj9YnP+RyMJwPxgW7TvQVFk/KgsLYF0kQz9g5dAC6IwzQcgHPVvDex1B1XjppodHBkHJq3OMM9fwQNvcmJ7wddlAInGPpQs/w0BRobq5EBmtQJZ2ai7n+ZVAtv2G5E+bgECG+gIfKBlpQK5f8jdI91JAL39sL/WpPEB8rGxhDqklQK6yUf43XhBAxL9y/tK8+D86XyZpgrHiPwAAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////AAAAAP////8AAAAAAAAAAAAAAAABAAAAAAAAAAAAAAD/////AAAAAAAAAAABAAAAAQAAAAAAAAAAAAAA/////wAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAP////8FAAAABQAAAAAAAAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////////////////////wAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP////////////////////////////////////8AAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAFAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////////////////////////////AAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAEAAAAAAAAABQAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQAAAAAAAQABAAABAQAAAAAAAQAAAAEAAAABAAEAAAAAAAAAAAAAAAAAAAAAquJYWJZl+D9jaeZNtj/zPwwdI9KqaeO/qGefXwdHdz+q4lhYlmX4P+OrlPMN3PI/DB0j0qpp47+7SQLV4VIEQKriWFiWZfg/r2kma3tz8T82eQmLqNIGwMRIWXMqSvo/fcCszPux9j+jara6ozTwP6hnn18HR3c/MSoKLequ8r+SabgA2nj0P7jBLbDOHO8/1Ym/ICfH4T+6lxjvlFXHv73m373LRPU/0vXyDVxo7T+ToKRHJXMAQF/33578aPE/pAyy64tD9T8+U/hCvyruPwxv8Y7YYwLAuXYr8NAiCEB4+LDK0Sn0P1Qeuy4j+eo/OMx50n7K7L+TrGB/nyf8v5ehC2fbYPM/aXMKexiT6z8mFRIMjg/zP7yUVwGGBNw/E6opHERf8z/z0wR2g9DqPw4pBpcOhvu/NbA29uWAA8DMaTExyXzyP02biiQ+Ruk/S8jz2/FKBEB1pzZnpbb9P7pQU4wLfPI//7ZcQXeG6D9CqEQvAYoIwDB2VB6sSgRAVyv8H5We8T+EHWF8XNPmPzB2wT8Nrrg/SEi+cX+w4L8of+GtdSDxP1sjk5AdouU/6ZjOVru13r8K0obqI6bxvwVbdNXyhfA/w5GG024n5z+rwmtMzP8BwLw9pSX49QXABe/2uQxP8D+b6wCzCvXkP7uGT87fK+Q/pz/JWw4coj+qoBf2J0nwP/yE3PUo0+I/vFJeHcaC+D96luSIqvntP/bf8sHUYu8/gZNN41mL4z9bhOqVOF4FwO6lmAh1hQhAbCVxbdhk7z+1C8NdDcfiPwG36x/0OQBAx0WJ76c2+D9nlSHXANfuP2HlfZ3gqOE/EwnVlVPg9r96+oHzEH//v5bXzdT1Auw/DM3GwLsA4D9p/8uoKcr+v+U9x5DQVAPAehjSdghb7D9sc1IetODgP8MVwwB1pu6/azPk6OGe978W8t/TUc3rP+0QMvYfP+A/RsG/QpSE8D+l3uwScxzgPwQaifgujuw/k1Vti1I43z8MAwLnSh0GQH5nYnwwZgJAiGUzWC5s6j8WyyI/BbLgPw4iUapGeQJAB3W+imnp/j9BLWR4ssrpP2t+gG5Pstk/cpBsfm6DCMCOpU9dOZsFQEv8nFypHeo/ehJ6i+6S2D9jqlGEmarLv7STC5TRiOa/bC+x8WZD6D9H3yUkWpDZP8gZvmCMuQLAreY19/eRBsCoPOc8UzzpP6KI/QV+y9g/t/MoboyWzT+Hv5q3Zu3Mvy2xROCT4uY/9gQitMMg1T9abAqhWMDkv1oLTavoUfG/PMUJP9CD5j+fHRX3t6fSPz7W2gk6bvs/WRnuHwqN9D8YFturGCTmP1EZczv0b9I/5t4exabB5D/1ESLh5fTEP9X2z6SYweQ/6lv3I2zT0D9zkRGNUNMAQKoSvc4EIfs/Xggt8wQI5T+mJHHg/w/SP4lhT/9t8vQ/DrZ/DbwH7D+XlhbYZrjkP34LIpFt6c4/lwfp8fLX9L+j96CTTf76v3WdNhEv9uM/d8c3o4lV0D/vFdCHVcsFwAHeDq0F1QhApbYqcZiN5D9KoilqByXLPwX0/diA0vq/0fo0GxnxAMBbaTkvlCzjP/RrFrWXrMs/UYTrky7jA0DB9f4FiZYAQEGAk/3QzeE/r/TeqE8t0D/OqjlsnPbvvz8RKU8JOfW/smSEbK/O4T8MzuyPm3DDP/rFtctq9gZAfb1EVEaSA0Dts5dVInnhP18SFMc79MM/7y34cw6LAMDFrRJsZO0DwC2KLvLSYuA/hx5wcUHewz+49SnK/4ruPyeS0PX9a+E/ZxaaLvvZ3z8WPu5T2QS8Pygo4RIvMqa/BJ0Kqsd0279cKW4ay8jdP3b05bmZ364/10/qtdxk2r+Bcz6CDMvpv54qOw+Amdw/qLV71pW7sT/YKc80nIPUP8OfIaBJ77G/LyTuD1un2z+diYu8efWzP1wU7ACkfwjAZroyPL1yBkAmv3lKJJbbPysKSE4W+p0/dIgqY79TA8ATLTOQ3tsGwJ2zweD/Xdg/XO/jXeFUaL8VW2qLFKfov1cA9Aa6XfK/tIa7YGgI2T+f3hu/sxqPv2nXdPpf3Pc/jkw8Jbda8j+tT/z8tGPVP1yBHpJd35k/KYvYOy1s8j/yz+kCQjPrP9+agH7x59g/PZfJ9aBhpr/rDKzvYBb+PwtkiaGCt/c/vb1mVr+f1T/JIHwHc8Govw7aeF6+9vG/Xv7kD6fp979isYioQYHVP7AIQZuSFrG/3z1AdUTnAUDN3XY9O7f9P0AdQ9ljYNQ/dJANJPTOrb8kLECUiiPlP4yF7UgmStA/9xGmXxCG1T9qZzix4W2zv2SGJRJVrPe/Fh9a2M/B/b8IexzFCoPSP9y1QFD2bLe/Q86cWLJe/b+mOOfYm78BwOTjkPAGE9E/8aPCUKu/ub9pPZyLCiUGwBA7Mev/BQlALOmrlRi+0j+AMJ/dKULBv7iLtL6a6QRAEMDV/yajAUDa62dE3crJP1P70RgBUbq/38hVnR6esT/s1tG10Z/Ov/zLwalHPss/dTS9NKTXx78nMcRzCIEHQAabxDsAmQRA0tyLK3gSyT+Aui7nOhDGv5Gs58z3WgHATN3forJuBMCAui7nOhDGP9Lciyt4Esm/WAJyHQ4c7z8UP5HFIs3iP3U0vTSk18c//MvBqUc+y7+cvv8HLg/Kvy1I/mHsI+K/U/vRGAFRuj/a62dE3crJv8p+WV8KlQjAuQ/nOP43B0CAMJ/dKULBPyzpq5UYvtK/ZoU+VoLh4L9etLlRUfvtv/GjwlCrv7k/5OOQ8AYT0b9DfT9FhufXPwUX8hJp+4u/3LVAUPZstz8IexzFCoPSv9+L609E5fQ/q9Fz7X2J7T9qZzix4W2zP/cRpl8QhtW/vtNilqGX+j8MOy7QJoL0P3SQDST0zq0/QB1D2WNg1L8IIjSvGNkDwGB8Jou2GAfAsAhBm5IWsT9isYioQYHVvyS9D3zb6uy/gnwRa7uM9L/JIHwHc8GoP729Zla/n9W/CsAHJZwmAEDEW6OYT1r6Pz2XyfWgYaY/35qAfvHn2L83Tdy4lS30vxf2/gZ0jPq/XIEekl3fmb+tT/z8tGPVvybPr2zJ1/+/K7mJ0ypVAsCf3hu/sxqPPwCGu2BoCNm/5oITrpZn+r+UDUyDP+n/v1zv413hVGg/nbPB4P9d2L9MlmkxNvgCQMtZlKE85v8/KwpIThb6nb8mv3lKJJbbv8+SZsTvOOc/pQCIIOYw0j+diYu8efWzvy8k7g9bp9u/kxYDa+pKtD9XlYvA8HnVv6i1e9aVu7G/nio7D4CZ3L/WR6rNh5EGwCkgQweBkghAdvTluZnfrr9cKW4ay8jdvxbjhr1f1QVAR5C0MzivAkAWPu5T2QS8v2cWmi772d+/cKj4lzLJCEBx2QJfYrMFQIcecHFB3sO/LYou8tJi4L+jr7lhO38BwIcI0Nb7xgTAXxIUxzv0w7/ts5dVInnhv0T+l8DZLfE/MP3FoFvS5D8MzuyPm3DDv7JkhGyvzuG/tzhzRIRc0b9Ovv3/0z7mv6/03qhPLdC/m4CT/dDN4b9dwjU5VCQBQBBJX1ntCv0/9GsWtZesy79baTkvlCzjv1mjYgEz++S/oW6KnOQW8b9KoilqByXLv6W2KnGYjeS/SmaKz3Vx9z+BZB5yxGHwP3fHN6OJVdC/dZ02ES/2478PuaBjLrXaP4/JU81pPaO/fgsikW3pzr+XlhbYZrjkv4tSn7YDbP0/f2LnFKlF9z+mJHHg/w/Sv14ILfMECOW/mfg4qYhR/b+OP+RQDCACwOpb9yNs09C/1fbPpJjB5L9pN2WOVZ3wv3hHy9nxIve/URlzO/Rv0r8YFturGCTmv1d1/KKR8QPA8gsy9qzSB8CfHRX3t6fSvzzFCT/Qg+a/EYStnrzV9r/2QJqI7Lb9v/YEIrTDINW/LbFE4JPi5r/7kQEs5fEDQHunnf4GeQBAooj9BX7L2L+oPOc8Uzzpv+ydYY2SSAfAL4HK6CRTB0BH3yUkWpDZv2wvsfFmQ+i/Ik0Yzruh6T8fM3LoGoDUP3oSeovukti/S/ycXKkd6r9rEv+7UWcHQCRIQe/GfwNAa36Abk+y2b9BLWR4ssrpv9KT87qa0bM/FTyktw823L8WyyI/BbLgv4hlM1gubOq/DizMp9Ki6r8b5ckdjVrzv5NVbYtSON+/BBqJ+C6O7L/dUBFqgyXYv00Wh18r7+q/7RAy9h8/4L8W8t/TUc3rv4RM5DKx3wDAfvWIj94aBcBsc1IetODgv3oY0nYIW+y/oGcTFF54AUDkJqS/FKX6PwzNxsC7AOC/ltfN1PUC7L+5Wrz/zHnzP6688w2rNOc/YeV9neCo4b9nlSHXANfuvw9RsxKjY/s/1V8GteXE8j+1C8NdDcfiv2wlcW3YZO+/IOywaA7Q8b9bFP+4Tg36v4GTTeNZi+O/9t/ywdRi77+tRc3yFR7eP2bkcHXJkLO//ITc9SjT4r+qoBf2J0nwv2YHKoswwfm/iQcLspCjAcCb6wCzCvXkvwXv9rkMT/C/YkuwYAMXBMApCNUai9kIwMORhtNuJ+e/BVt01fKF8L+ZqWEfvIjsP6h693QZYNk/WyOTkB2i5b8of+GtdSDxvwpaaulDSwVADMQAX+lOAECEHWF8XNPmv1cr/B+VnvG/XyFG6opcCMD/mtR32/UEQP+2XEF3hui/ulBTjAt88r/imfCfRP+yP9zbvtc8XeO/TZuKJD5G6b/MaTExyXzyvxiTQeElXOO/rbJRQVGN9L/z0wR2g9DqvxOqKRxEX/O/FDGCEei99j9x8zV4VYTmP2lzCnsYk+u/l6ELZ9tg878pRXacaDT/v3k6GZRqoQXAVB67LiP56r94+LDK0Sn0vwO6pZ9b7wFAvK0nKVcc9j8+U/hCvyruv6QMsuuLQ/W/FPhKFYv46j8MyxaDTOW/v9L18g1caO2/vebfvctE9b/7GD8ZrF3xv3gx1AR9bQDAuMEtsM4c77+SabgA2nj0v5xKFIwxsATArKNSBaKsB0Cjara6ozTwv33ArMz7sfa/dF2U0FcWCcDxL357DJX/P69pJmt7c/G/quJYWJZl+L/YntVJlnrSP4sRLzXM+fe/46uU8w3c8r+q4lhYlmX4v85lu5+QRwRAsI0H/WU8479jaeZNtj/zv6riWFiWZfi/sI0H/WU847/OZbufkEcEQHAoPUBrnss/9exKzDtFtT88wM8kax+gP9OqeKeAYog/MW0ItiZvcj+ph+smvt5bP2lCaV5dEUU/StaUmQDaLz+kK9y22BMYP0O3whZuMwI/IIbgZGWE6z7UkjYaEM3UPuezxwa9cr8+LybxRMnFpz6E1N8DbPiRPsYjySMvK3s+//////8fAAj//////zMQCP////9/MiAI/////28yMAj/////YzJACP///z9iMlAI////N2IyYAj///8zYjJwCP//vzNiMoAI//+rM2IykAj/f6szYjKgCP8PqzNiMrAI/wOrM2IywAi/A6szYjLQCJ8DqzNiMuAImQOrM2Iy8Aj//////z8PCP//////Kx8I/////38pLwj/////Pyk/CP////85KU8I////PzgpXwj///8POClvCP///w44KX8I//8fDjgpjwj//w8OOCmfCP9/DQ44Ka8I/w8NDjgpvwj/DQ0OOCnPCP8MDQ44Kd8IxwwNDjgp7wjEDA0OOCn/CAcAAAAHAAAAAQAAAAIAAAAEAAAAAwAAAAAAAAAAAAAABwAAAAMAAAABAAAAAgAAAAUAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAACAAAAAQAAAAMAAAAOAAAABgAAAAsAAAACAAAABwAAAAEAAAAYAAAABQAAAAoAAAABAAAABgAAAAAAAAAmAAAABwAAAAwAAAADAAAACAAAAAIAAAAxAAAACQAAAA4AAAAAAAAABQAAAAQAAAA6AAAACAAAAA0AAAAEAAAACQAAAAMAAAA/AAAACwAAAAYAAAAPAAAACgAAABAAAABIAAAADAAAAAcAAAAQAAAACwAAABEAAABTAAAACgAAAAUAAAATAAAADgAAAA8AAABhAAAADQAAAAgAAAARAAAADAAAABIAAABrAAAADgAAAAkAAAASAAAADQAAABMAAAB1AAAADwAAABMAAAARAAAAEgAAABAAAAAGAAAAAgAAAAMAAAAFAAAABAAAAAAAAAAAAAAAAAAAAAYAAAACAAAAAwAAAAEAAAAFAAAABAAAAAAAAAAAAAAABwAAAAUAAAADAAAABAAAAAEAAAAAAAAAAgAAAAAAAAACAAAAAwAAAAEAAAAFAAAABAAAAAYAAAAAAAAAAAAAABgtRFT7Ifk/GC1EVPsh+b8YLURU+yEJQBgtRFT7IQnAYWxnb3MuYwBoM05laWdoYm9yUm90YXRpb25zAGNvb3JkaWprLmMAX3VwQXA3Q2hlY2tlZABfdXBBcDdyQ2hlY2tlZABkaXJlY3RlZEVkZ2UuYwBkaXJlY3RlZEVkZ2VUb0JvdW5kYXJ5AGFkamFjZW50RmFjZURpclt0bXBGaWprLmZhY2VdW2ZpamsuZmFjZV0gPT0gS0kAZmFjZWlqay5jAF9mYWNlSWprUGVudFRvQ2VsbEJvdW5kYXJ5AGFkamFjZW50RmFjZURpcltjZW50ZXJJSksuZmFjZV1bZmFjZTJdID09IEtJAF9mYWNlSWprVG9DZWxsQm91bmRhcnkAaDNJbmRleC5jAGNvbXBhY3RDZWxscwBsYXRMbmdUb0NlbGwAY2VsbFRvQ2hpbGRQb3MAdmFsaWRhdGVDaGlsZFBvcwBsYXRMbmcuYwBjZWxsQXJlYVJhZHMyAHBvbHlnb24tPm5leHQgPT0gTlVMTABsaW5rZWRHZW8uYwBhZGROZXdMaW5rZWRQb2x5Z29uAG5leHQgIT0gTlVMTABsb29wICE9IE5VTEwAYWRkTmV3TGlua2VkTG9vcABwb2x5Z29uLT5maXJzdCA9PSBOVUxMAGFkZExpbmtlZExvb3AAY29vcmQgIT0gTlVMTABhZGRMaW5rZWRDb29yZABsb29wLT5maXJzdCA9PSBOVUxMAGlubmVyTG9vcHMgIT0gTlVMTABub3JtYWxpemVNdWx0aVBvbHlnb24AYmJveGVzICE9IE5VTEwAY2FuZGlkYXRlcyAhPSBOVUxMAGZpbmRQb2x5Z29uRm9ySG9sZQBjYW5kaWRhdGVCQm94ZXMgIT0gTlVMTAByZXZEaXIgIT0gSU5WQUxJRF9ESUdJVABsb2NhbGlqLmMAY2VsbFRvTG9jYWxJamsAYmFzZUNlbGwgIT0gb3JpZ2luQmFzZUNlbGwAIShvcmlnaW5PblBlbnQgJiYgaW5kZXhPblBlbnQpAGJhc2VDZWxsID09IG9yaWdpbkJhc2VDZWxsAGJhc2VDZWxsICE9IElOVkFMSURfQkFTRV9DRUxMAGxvY2FsSWprVG9DZWxsACFfaXNCYXNlQ2VsbFBlbnRhZ29uKGJhc2VDZWxsKQBiYXNlQ2VsbFJvdGF0aW9ucyA+PSAwAGdyaWRQYXRoQ2VsbHMAcG9seWZpbGwuYwBpdGVyU3RlcFBvbHlnb25Db21wYWN0ADAAdmVydGV4LmMAY2VsbFRvVmVydGV4AGdyYXBoLT5idWNrZXRzICE9IE5VTEwAdmVydGV4R3JhcGguYwBpbml0VmVydGV4R3JhcGgAbm9kZSAhPSBOVUxMAGFkZFZlcnRleE5vZGU=\";\r\n  var tempDoublePtr = 28624;\r\n  function demangle(func) {\r\n    return func;\r\n  }\r\n  function demangleAll(text) {\r\n    var regex = /\\b__Z[\\w\\d_]+/g;\r\n    return text.replace(regex, function (x) {\r\n      var y = demangle(x);\r\n      return x === y ? x : y + \" [\" + x + \"]\";\r\n    });\r\n  }\r\n  function jsStackTrace() {\r\n    var err = new Error();\r\n    if (!err.stack) {\r\n      try {\r\n        throw new Error(0);\r\n      } catch (e) {\r\n        err = e;\r\n      }\r\n      if (!err.stack) {\r\n        return \"(no stack trace available)\";\r\n      }\r\n    }\r\n    return err.stack.toString();\r\n  }\r\n  function stackTrace() {\r\n    var js = jsStackTrace();\r\n    if (Module[\"extraStackTrace\"]) { js += \"\\n\" + Module[\"extraStackTrace\"](); }\r\n    return demangleAll(js);\r\n  }\r\n  function ___assert_fail(condition, filename, line, func) {\r\n    abort(\"Assertion failed: \" + UTF8ToString(condition) + \", at: \" + [filename ? UTF8ToString(filename) : \"unknown filename\", line, func ? UTF8ToString(func) : \"unknown function\"]);\r\n  }\r\n  function _emscripten_get_heap_size() {\r\n    return HEAP8.length;\r\n  }\r\n  function _emscripten_memcpy_big(dest, src, num) {\r\n    HEAPU8.set(HEAPU8.subarray(src, src + num), dest);\r\n  }\r\n  function ___setErrNo(value) {\r\n    if (Module[\"___errno_location\"]) { HEAP32[Module[\"___errno_location\"]() >> 2] = value; }\r\n    return value;\r\n  }\r\n  function abortOnCannotGrowMemory(requestedSize) {\r\n    abort(\"OOM\");\r\n  }\r\n  function emscripten_realloc_buffer(size) {\r\n    try {\r\n      var newBuffer = new ArrayBuffer(size);\r\n      if (newBuffer.byteLength != size) { return; }\r\n      new Int8Array(newBuffer).set(HEAP8);\r\n      _emscripten_replace_memory(newBuffer);\r\n      updateGlobalBufferAndViews(newBuffer);\r\n      return 1;\r\n    } catch (e) {}\r\n  }\r\n  function _emscripten_resize_heap(requestedSize) {\r\n    var oldSize = _emscripten_get_heap_size();\r\n    var PAGE_MULTIPLE = 16777216;\r\n    var LIMIT = 2147483648 - PAGE_MULTIPLE;\r\n    if (requestedSize > LIMIT) {\r\n      return false;\r\n    }\r\n    var MIN_TOTAL_MEMORY = 16777216;\r\n    var newSize = Math.max(oldSize, MIN_TOTAL_MEMORY);\r\n    while (newSize < requestedSize) {\r\n      if (newSize <= 536870912) {\r\n        newSize = alignUp(2 * newSize, PAGE_MULTIPLE);\r\n      } else {\r\n        newSize = Math.min(alignUp((3 * newSize + 2147483648) / 4, PAGE_MULTIPLE), LIMIT);\r\n      }\r\n    }\r\n    var replacement = emscripten_realloc_buffer(newSize);\r\n    if (!replacement) {\r\n      return false;\r\n    }\r\n    return true;\r\n  }\r\n  function intArrayToString(array) {\r\n    var ret = [];\r\n    for (var i = 0; i < array.length; i++) {\r\n      var chr = array[i];\r\n      if (chr > 255) {\r\n        chr &= 255;\r\n      }\r\n      ret.push(String.fromCharCode(chr));\r\n    }\r\n    return ret.join(\"\");\r\n  }\r\n  var decodeBase64 = typeof atob === \"function\" ? atob : function (input) {\r\n    var keyStr = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\";\r\n    var output = \"\";\r\n    var chr1, chr2, chr3;\r\n    var enc1, enc2, enc3, enc4;\r\n    var i = 0;\r\n    input = input.replace(/[^A-Za-z0-9\\+\\/\\=]/g, \"\");\r\n    do {\r\n      enc1 = keyStr.indexOf(input.charAt(i++));\r\n      enc2 = keyStr.indexOf(input.charAt(i++));\r\n      enc3 = keyStr.indexOf(input.charAt(i++));\r\n      enc4 = keyStr.indexOf(input.charAt(i++));\r\n      chr1 = enc1 << 2 | enc2 >> 4;\r\n      chr2 = (enc2 & 15) << 4 | enc3 >> 2;\r\n      chr3 = (enc3 & 3) << 6 | enc4;\r\n      output = output + String.fromCharCode(chr1);\r\n      if (enc3 !== 64) {\r\n        output = output + String.fromCharCode(chr2);\r\n      }\r\n      if (enc4 !== 64) {\r\n        output = output + String.fromCharCode(chr3);\r\n      }\r\n    } while (i < input.length);\r\n    return output;\r\n  };\r\n  function intArrayFromBase64(s) {\r\n    if (typeof ENVIRONMENT_IS_NODE === \"boolean\" && ENVIRONMENT_IS_NODE) {\r\n      var buf;\r\n      try {\r\n        buf = Buffer.from(s, \"base64\");\r\n      } catch (_) {\r\n        buf = new Buffer(s, \"base64\");\r\n      }\r\n      return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\r\n    }\r\n    try {\r\n      var decoded = decodeBase64(s);\r\n      var bytes = new Uint8Array(decoded.length);\r\n      for (var i = 0; i < decoded.length; ++i) {\r\n        bytes[i] = decoded.charCodeAt(i);\r\n      }\r\n      return bytes;\r\n    } catch (_) {\r\n      throw new Error(\"Converting base64 string to bytes failed.\");\r\n    }\r\n  }\r\n  function tryParseAsDataURI(filename) {\r\n    if (!isDataURI(filename)) {\r\n      return;\r\n    }\r\n    return intArrayFromBase64(filename.slice(dataURIPrefix.length));\r\n  }\r\n  var asmGlobalArg = {\r\n    \"Math\": Math,\r\n    \"Int8Array\": Int8Array,\r\n    \"Int32Array\": Int32Array,\r\n    \"Uint8Array\": Uint8Array,\r\n    \"Float32Array\": Float32Array,\r\n    \"Float64Array\": Float64Array\r\n  };\r\n  var asmLibraryArg = {\r\n    \"a\": abort,\r\n    \"b\": setTempRet0,\r\n    \"c\": getTempRet0,\r\n    \"d\": ___assert_fail,\r\n    \"e\": ___setErrNo,\r\n    \"f\": _emscripten_get_heap_size,\r\n    \"g\": _emscripten_memcpy_big,\r\n    \"h\": _emscripten_resize_heap,\r\n    \"i\": abortOnCannotGrowMemory,\r\n    \"j\": demangle,\r\n    \"k\": demangleAll,\r\n    \"l\": emscripten_realloc_buffer,\r\n    \"m\": jsStackTrace,\r\n    \"n\": stackTrace,\r\n    \"o\": tempDoublePtr,\r\n    \"p\": DYNAMICTOP_PTR\r\n  }; // EMSCRIPTEN_START_ASM\r\n  var asm = (/** @suppress {uselessCode} */function (global, env, buffer) {\r\n    \"almost asm\";\r\n\r\n    var a = new global.Int8Array(buffer),\r\n      b = new global.Int32Array(buffer),\r\n      c = new global.Uint8Array(buffer),\r\n      d = new global.Float32Array(buffer),\r\n      e = new global.Float64Array(buffer),\r\n      f = env.o | 0,\r\n      g = env.p | 0,\r\n      p = global.Math.floor,\r\n      q = global.Math.abs,\r\n      r = global.Math.sqrt,\r\n      s = global.Math.pow,\r\n      t = global.Math.cos,\r\n      u = global.Math.sin,\r\n      v = global.Math.tan,\r\n      w = global.Math.acos,\r\n      x = global.Math.asin,\r\n      y = global.Math.atan,\r\n      z = global.Math.atan2,\r\n      A = global.Math.ceil,\r\n      B = global.Math.imul,\r\n      C = global.Math.min,\r\n      D = global.Math.max,\r\n      E = global.Math.clz32,\r\n      G = env.b,\r\n      H = env.c,\r\n      I = env.d,\r\n      J = env.e,\r\n      K = env.f,\r\n      L = env.g,\r\n      M = env.h,\r\n      N = env.i,\r\n      T = 28640;\r\n    function W(newBuffer) {\r\n      a = new Int8Array(newBuffer);\r\n      c = new Uint8Array(newBuffer);\r\n      b = new Int32Array(newBuffer);\r\n      d = new Float32Array(newBuffer);\r\n      e = new Float64Array(newBuffer);\r\n      buffer = newBuffer;\r\n      return true;\r\n    }\r\n    // EMSCRIPTEN_START_FUNCS\r\n    function X(a) {\r\n      a = a | 0;\r\n      var b = 0;\r\n      b = T;\r\n      T = T + a | 0;\r\n      T = T + 15 & -16;\r\n      return b | 0;\r\n    }\r\n    function Y() {\r\n      return T | 0;\r\n    }\r\n    function Z(a) {\r\n      a = a | 0;\r\n      T = a;\r\n    }\r\n    function _(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      T = a;\r\n    }\r\n    function $(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0;\r\n      if ((a | 0) < 0) {\r\n        c = 2;\r\n        return c | 0;\r\n      }\r\n      if ((a | 0) > 13780509) {\r\n        c = uc(15, c) | 0;\r\n        return c | 0;\r\n      } else {\r\n        d = ((a | 0) < 0) << 31 >> 31;\r\n        f = Md(a | 0, d | 0, 3, 0) | 0;\r\n        e = H() | 0;\r\n        d = Gd(a | 0, d | 0, 1, 0) | 0;\r\n        d = Md(f | 0, e | 0, d | 0, H() | 0) | 0;\r\n        d = Gd(d | 0, H() | 0, 1, 0) | 0;\r\n        a = H() | 0;\r\n        b[c >> 2] = d;\r\n        b[c + 4 >> 2] = a;\r\n        c = 0;\r\n        return c | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function aa(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      return ba(a, b, c, d, 0) | 0;\r\n    }\r\n    function ba(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      j = T;\r\n      T = T + 16 | 0;\r\n      h = j;\r\n      if (!(ca(a, c, d, e, f) | 0)) {\r\n        e = 0;\r\n        T = j;\r\n        return e | 0;\r\n      }\r\n      do { if ((d | 0) >= 0) {\r\n        if ((d | 0) > 13780509) {\r\n          g = uc(15, h) | 0;\r\n          if (g | 0) { break; }\r\n          i = h;\r\n          h = b[i >> 2] | 0;\r\n          i = b[i + 4 >> 2] | 0;\r\n        } else {\r\n          g = ((d | 0) < 0) << 31 >> 31;\r\n          k = Md(d | 0, g | 0, 3, 0) | 0;\r\n          i = H() | 0;\r\n          g = Gd(d | 0, g | 0, 1, 0) | 0;\r\n          g = Md(k | 0, i | 0, g | 0, H() | 0) | 0;\r\n          g = Gd(g | 0, H() | 0, 1, 0) | 0;\r\n          i = H() | 0;\r\n          b[h >> 2] = g;\r\n          b[h + 4 >> 2] = i;\r\n          h = g;\r\n        }\r\n        Xd(e | 0, 0, h << 3 | 0) | 0;\r\n        if (f | 0) {\r\n          Xd(f | 0, 0, h << 2 | 0) | 0;\r\n          g = da(a, c, d, e, f, h, i, 0) | 0;\r\n          break;\r\n        }\r\n        g = Fd(h, 4) | 0;\r\n        if (!g) { g = 13; }else {\r\n          k = da(a, c, d, e, g, h, i, 0) | 0;\r\n          Ed(g);\r\n          g = k;\r\n        }\r\n      } else { g = 2; } } while (0);\r\n      k = g;\r\n      T = j;\r\n      return k | 0;\r\n    }\r\n    function ca(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0;\r\n      q = T;\r\n      T = T + 16 | 0;\r\n      o = q;\r\n      p = q + 8 | 0;\r\n      n = o;\r\n      b[n >> 2] = a;\r\n      b[n + 4 >> 2] = c;\r\n      if ((d | 0) < 0) {\r\n        p = 2;\r\n        T = q;\r\n        return p | 0;\r\n      }\r\n      g = e;\r\n      b[g >> 2] = a;\r\n      b[g + 4 >> 2] = c;\r\n      g = (f | 0) != 0;\r\n      if (g) { b[f >> 2] = 0; }\r\n      if (Hb(a, c) | 0) {\r\n        p = 9;\r\n        T = q;\r\n        return p | 0;\r\n      }\r\n      b[p >> 2] = 0;\r\n      a: do { if ((d | 0) >= 1) {\r\n        if (g) {\r\n          l = 1;\r\n          k = 0;\r\n          m = 0;\r\n          n = 1;\r\n          g = a;\r\n          while (1) {\r\n            if (!(k | m)) {\r\n              g = ea(g, c, 4, p, o) | 0;\r\n              if (g | 0) { break a; }\r\n              c = o;\r\n              g = b[c >> 2] | 0;\r\n              c = b[c + 4 >> 2] | 0;\r\n              if (Hb(g, c) | 0) {\r\n                g = 9;\r\n                break a;\r\n              }\r\n            }\r\n            g = ea(g, c, b[26800 + (m << 2) >> 2] | 0, p, o) | 0;\r\n            if (g | 0) { break a; }\r\n            c = o;\r\n            g = b[c >> 2] | 0;\r\n            c = b[c + 4 >> 2] | 0;\r\n            a = e + (l << 3) | 0;\r\n            b[a >> 2] = g;\r\n            b[a + 4 >> 2] = c;\r\n            b[f + (l << 2) >> 2] = n;\r\n            a = k + 1 | 0;\r\n            h = (a | 0) == (n | 0);\r\n            i = m + 1 | 0;\r\n            j = (i | 0) == 6;\r\n            if (Hb(g, c) | 0) {\r\n              g = 9;\r\n              break a;\r\n            }\r\n            n = n + (j & h & 1) | 0;\r\n            if ((n | 0) > (d | 0)) {\r\n              g = 0;\r\n              break;\r\n            } else {\r\n              l = l + 1 | 0;\r\n              k = h ? 0 : a;\r\n              m = h ? j ? 0 : i : m;\r\n            }\r\n          }\r\n        } else {\r\n          l = 1;\r\n          k = 0;\r\n          m = 0;\r\n          n = 1;\r\n          g = a;\r\n          while (1) {\r\n            if (!(k | m)) {\r\n              g = ea(g, c, 4, p, o) | 0;\r\n              if (g | 0) { break a; }\r\n              c = o;\r\n              g = b[c >> 2] | 0;\r\n              c = b[c + 4 >> 2] | 0;\r\n              if (Hb(g, c) | 0) {\r\n                g = 9;\r\n                break a;\r\n              }\r\n            }\r\n            g = ea(g, c, b[26800 + (m << 2) >> 2] | 0, p, o) | 0;\r\n            if (g | 0) { break a; }\r\n            c = o;\r\n            g = b[c >> 2] | 0;\r\n            c = b[c + 4 >> 2] | 0;\r\n            a = e + (l << 3) | 0;\r\n            b[a >> 2] = g;\r\n            b[a + 4 >> 2] = c;\r\n            a = k + 1 | 0;\r\n            h = (a | 0) == (n | 0);\r\n            i = m + 1 | 0;\r\n            j = (i | 0) == 6;\r\n            if (Hb(g, c) | 0) {\r\n              g = 9;\r\n              break a;\r\n            }\r\n            n = n + (j & h & 1) | 0;\r\n            if ((n | 0) > (d | 0)) {\r\n              g = 0;\r\n              break;\r\n            } else {\r\n              l = l + 1 | 0;\r\n              k = h ? 0 : a;\r\n              m = h ? j ? 0 : i : m;\r\n            }\r\n          }\r\n        }\r\n      } else { g = 0; } } while (0);\r\n      p = g;\r\n      T = q;\r\n      return p | 0;\r\n    }\r\n    function da(a, c, d, e, f, g, h, i) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      h = h | 0;\r\n      i = i | 0;\r\n      var j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0;\r\n      q = T;\r\n      T = T + 16 | 0;\r\n      o = q + 8 | 0;\r\n      p = q;\r\n      j = Od(a | 0, c | 0, g | 0, h | 0) | 0;\r\n      l = H() | 0;\r\n      m = e + (j << 3) | 0;\r\n      r = m;\r\n      s = b[r >> 2] | 0;\r\n      r = b[r + 4 >> 2] | 0;\r\n      k = (s | 0) == (a | 0) & (r | 0) == (c | 0);\r\n      if (!((s | 0) == 0 & (r | 0) == 0 | k)) { do {\r\n        j = Gd(j | 0, l | 0, 1, 0) | 0;\r\n        j = Nd(j | 0, H() | 0, g | 0, h | 0) | 0;\r\n        l = H() | 0;\r\n        m = e + (j << 3) | 0;\r\n        s = m;\r\n        r = b[s >> 2] | 0;\r\n        s = b[s + 4 >> 2] | 0;\r\n        k = (r | 0) == (a | 0) & (s | 0) == (c | 0);\r\n      } while (!((r | 0) == 0 & (s | 0) == 0 | k)); }\r\n      j = f + (j << 2) | 0;\r\n      if (k ? (b[j >> 2] | 0) <= (i | 0) : 0) {\r\n        s = 0;\r\n        T = q;\r\n        return s | 0;\r\n      }\r\n      s = m;\r\n      b[s >> 2] = a;\r\n      b[s + 4 >> 2] = c;\r\n      b[j >> 2] = i;\r\n      if ((i | 0) >= (d | 0)) {\r\n        s = 0;\r\n        T = q;\r\n        return s | 0;\r\n      }\r\n      k = i + 1 | 0;\r\n      b[o >> 2] = 0;\r\n      j = ea(a, c, 2, o, p) | 0;\r\n      switch (j | 0) {\r\n        case 9:\r\n          {\r\n            n = 9;\r\n            break;\r\n          }\r\n        case 0:\r\n          {\r\n            j = p;\r\n            j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n            if (!j) { n = 9; }\r\n            break;\r\n          }\r\n        default:\r\n\r\n      }\r\n      a: do { if ((n | 0) == 9) {\r\n        b[o >> 2] = 0;\r\n        j = ea(a, c, 3, o, p) | 0;\r\n        switch (j | 0) {\r\n          case 9:\r\n            break;\r\n          case 0:\r\n            {\r\n              j = p;\r\n              j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n              if (j | 0) { break a; }\r\n              break;\r\n            }\r\n          default:\r\n            break a;\r\n        }\r\n        b[o >> 2] = 0;\r\n        j = ea(a, c, 1, o, p) | 0;\r\n        switch (j | 0) {\r\n          case 9:\r\n            break;\r\n          case 0:\r\n            {\r\n              j = p;\r\n              j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n              if (j | 0) { break a; }\r\n              break;\r\n            }\r\n          default:\r\n            break a;\r\n        }\r\n        b[o >> 2] = 0;\r\n        j = ea(a, c, 5, o, p) | 0;\r\n        switch (j | 0) {\r\n          case 9:\r\n            break;\r\n          case 0:\r\n            {\r\n              j = p;\r\n              j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n              if (j | 0) { break a; }\r\n              break;\r\n            }\r\n          default:\r\n            break a;\r\n        }\r\n        b[o >> 2] = 0;\r\n        j = ea(a, c, 4, o, p) | 0;\r\n        switch (j | 0) {\r\n          case 9:\r\n            break;\r\n          case 0:\r\n            {\r\n              j = p;\r\n              j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n              if (j | 0) { break a; }\r\n              break;\r\n            }\r\n          default:\r\n            break a;\r\n        }\r\n        b[o >> 2] = 0;\r\n        j = ea(a, c, 6, o, p) | 0;\r\n        switch (j | 0) {\r\n          case 9:\r\n            break;\r\n          case 0:\r\n            {\r\n              j = p;\r\n              j = da(b[j >> 2] | 0, b[j + 4 >> 2] | 0, d, e, f, g, h, k) | 0;\r\n              if (j | 0) { break a; }\r\n              break;\r\n            }\r\n          default:\r\n            break a;\r\n        }\r\n        s = 0;\r\n        T = q;\r\n        return s | 0;\r\n      } } while (0);\r\n      s = j;\r\n      T = q;\r\n      return s | 0;\r\n    }\r\n    function ea(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0;\r\n      if (d >>> 0 > 6) {\r\n        f = 1;\r\n        return f | 0;\r\n      }\r\n      m = (b[e >> 2] | 0) % 6 | 0;\r\n      b[e >> 2] = m;\r\n      if ((m | 0) > 0) {\r\n        g = 0;\r\n        do {\r\n          d = $a(d) | 0;\r\n          g = g + 1 | 0;\r\n        } while ((g | 0) < (b[e >> 2] | 0));\r\n      }\r\n      m = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      l = m & 127;\r\n      if (l >>> 0 > 121) {\r\n        f = 5;\r\n        return f | 0;\r\n      }\r\n      j = Pb(a, c) | 0;\r\n      g = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      g = g & 15;\r\n      a: do { if (!g) { k = 8; }else {\r\n        while (1) {\r\n          h = (15 - g | 0) * 3 | 0;\r\n          i = Qd(a | 0, c | 0, h | 0) | 0;\r\n          H() | 0;\r\n          i = i & 7;\r\n          if ((i | 0) == 7) {\r\n            c = 5;\r\n            break;\r\n          }\r\n          p = (Vb(g) | 0) == 0;\r\n          g = g + -1 | 0;\r\n          n = Rd(7, 0, h | 0) | 0;\r\n          c = c & ~(H() | 0);\r\n          o = Rd(b[(p ? 432 : 16) + (i * 28 | 0) + (d << 2) >> 2] | 0, 0, h | 0) | 0;\r\n          h = H() | 0;\r\n          d = b[(p ? 640 : 224) + (i * 28 | 0) + (d << 2) >> 2] | 0;\r\n          a = o | a & ~n;\r\n          c = h | c;\r\n          if (!d) {\r\n            d = 0;\r\n            break a;\r\n          }\r\n          if (!g) {\r\n            k = 8;\r\n            break a;\r\n          }\r\n        }\r\n        return c | 0;\r\n      } } while (0);\r\n      if ((k | 0) == 8) {\r\n        p = b[848 + (l * 28 | 0) + (d << 2) >> 2] | 0;\r\n        o = Rd(p | 0, 0, 45) | 0;\r\n        a = o | a;\r\n        c = H() | 0 | c & -1040385;\r\n        d = b[4272 + (l * 28 | 0) + (d << 2) >> 2] | 0;\r\n        if ((p & 127 | 0) == 127) {\r\n          p = Rd(b[848 + (l * 28 | 0) + 20 >> 2] | 0, 0, 45) | 0;\r\n          c = H() | 0 | c & -1040385;\r\n          d = b[4272 + (l * 28 | 0) + 20 >> 2] | 0;\r\n          a = Rb(p | a, c) | 0;\r\n          c = H() | 0;\r\n          b[e >> 2] = (b[e >> 2] | 0) + 1;\r\n        }\r\n      }\r\n      i = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      i = i & 127;\r\n      b: do { if (!(oa(i) | 0)) {\r\n        if ((d | 0) > 0) {\r\n          g = 0;\r\n          do {\r\n            a = Rb(a, c) | 0;\r\n            c = H() | 0;\r\n            g = g + 1 | 0;\r\n          } while ((g | 0) != (d | 0));\r\n        }\r\n      } else {\r\n        c: do { if ((Pb(a, c) | 0) == 1) {\r\n          if ((l | 0) != (i | 0)) { if (ua(i, b[7696 + (l * 28 | 0) >> 2] | 0) | 0) {\r\n            a = Tb(a, c) | 0;\r\n            h = 1;\r\n            c = H() | 0;\r\n            break;\r\n          } else { I(27795, 26864, 533, 26872); } }\r\n          switch (j | 0) {\r\n            case 3:\r\n              {\r\n                a = Rb(a, c) | 0;\r\n                c = H() | 0;\r\n                b[e >> 2] = (b[e >> 2] | 0) + 1;\r\n                h = 0;\r\n                break c;\r\n              }\r\n            case 5:\r\n              {\r\n                a = Tb(a, c) | 0;\r\n                c = H() | 0;\r\n                b[e >> 2] = (b[e >> 2] | 0) + 5;\r\n                h = 0;\r\n                break c;\r\n              }\r\n            case 0:\r\n              {\r\n                p = 9;\r\n                return p | 0;\r\n              }\r\n            default:\r\n              {\r\n                p = 1;\r\n                return p | 0;\r\n              }\r\n          }\r\n        } else { h = 0; } } while (0);\r\n        if ((d | 0) > 0) {\r\n          g = 0;\r\n          do {\r\n            a = Qb(a, c) | 0;\r\n            c = H() | 0;\r\n            g = g + 1 | 0;\r\n          } while ((g | 0) != (d | 0));\r\n        }\r\n        if ((l | 0) != (i | 0)) {\r\n          if (!(pa(i) | 0)) {\r\n            if ((h | 0) != 0 | (Pb(a, c) | 0) != 5) { break; }\r\n            b[e >> 2] = (b[e >> 2] | 0) + 1;\r\n            break;\r\n          }\r\n          switch (m & 127) {\r\n            case 8:\r\n            case 118:\r\n              break b;\r\n            default:\r\n\r\n          }\r\n          if ((Pb(a, c) | 0) != 3) { b[e >> 2] = (b[e >> 2] | 0) + 1; }\r\n        }\r\n      } } while (0);\r\n      b[e >> 2] = ((b[e >> 2] | 0) + d | 0) % 6 | 0;\r\n      p = f;\r\n      b[p >> 2] = a;\r\n      b[p + 4 >> 2] = c;\r\n      p = 0;\r\n      return p | 0;\r\n    }\r\n    function fa(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      if (!(ga(a, b, c, d) | 0)) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      Xd(d | 0, 0, c * 48 | 0) | 0;\r\n      d = ha(a, b, c, d) | 0;\r\n      return d | 0;\r\n    }\r\n    function ga(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0;\r\n      p = T;\r\n      T = T + 16 | 0;\r\n      n = p;\r\n      o = p + 8 | 0;\r\n      m = n;\r\n      b[m >> 2] = a;\r\n      b[m + 4 >> 2] = c;\r\n      if ((d | 0) < 0) {\r\n        o = 2;\r\n        T = p;\r\n        return o | 0;\r\n      }\r\n      if (!d) {\r\n        o = e;\r\n        b[o >> 2] = a;\r\n        b[o + 4 >> 2] = c;\r\n        o = 0;\r\n        T = p;\r\n        return o | 0;\r\n      }\r\n      b[o >> 2] = 0;\r\n      a: do { if (!(Hb(a, c) | 0)) {\r\n        f = 0;\r\n        m = a;\r\n        do {\r\n          a = ea(m, c, 4, o, n) | 0;\r\n          if (a | 0) { break a; }\r\n          c = n;\r\n          m = b[c >> 2] | 0;\r\n          c = b[c + 4 >> 2] | 0;\r\n          f = f + 1 | 0;\r\n          if (Hb(m, c) | 0) {\r\n            a = 9;\r\n            break a;\r\n          }\r\n        } while ((f | 0) < (d | 0));\r\n        l = e;\r\n        b[l >> 2] = m;\r\n        b[l + 4 >> 2] = c;\r\n        l = d + -1 | 0;\r\n        k = 0;\r\n        a = 1;\r\n        do {\r\n          f = 26800 + (k << 2) | 0;\r\n          if ((k | 0) == 5) {\r\n            h = b[f >> 2] | 0;\r\n            g = 0;\r\n            f = a;\r\n            while (1) {\r\n              a = n;\r\n              a = ea(b[a >> 2] | 0, b[a + 4 >> 2] | 0, h, o, n) | 0;\r\n              if (a | 0) { break a; }\r\n              if ((g | 0) != (l | 0)) {\r\n                j = n;\r\n                i = b[j >> 2] | 0;\r\n                j = b[j + 4 >> 2] | 0;\r\n                a = e + (f << 3) | 0;\r\n                b[a >> 2] = i;\r\n                b[a + 4 >> 2] = j;\r\n                if (!(Hb(i, j) | 0)) { a = f + 1 | 0; }else {\r\n                  a = 9;\r\n                  break a;\r\n                }\r\n              } else { a = f; }\r\n              g = g + 1 | 0;\r\n              if ((g | 0) >= (d | 0)) { break; }else { f = a; }\r\n            }\r\n          } else {\r\n            h = n;\r\n            j = b[f >> 2] | 0;\r\n            i = 0;\r\n            f = a;\r\n            g = b[h >> 2] | 0;\r\n            h = b[h + 4 >> 2] | 0;\r\n            while (1) {\r\n              a = ea(g, h, j, o, n) | 0;\r\n              if (a | 0) { break a; }\r\n              h = n;\r\n              g = b[h >> 2] | 0;\r\n              h = b[h + 4 >> 2] | 0;\r\n              a = e + (f << 3) | 0;\r\n              b[a >> 2] = g;\r\n              b[a + 4 >> 2] = h;\r\n              a = f + 1 | 0;\r\n              if (Hb(g, h) | 0) {\r\n                a = 9;\r\n                break a;\r\n              }\r\n              i = i + 1 | 0;\r\n              if ((i | 0) >= (d | 0)) { break; }else { f = a; }\r\n            }\r\n          }\r\n          k = k + 1 | 0;\r\n        } while (k >>> 0 < 6);\r\n        a = n;\r\n        a = ((m | 0) == (b[a >> 2] | 0) ? (c | 0) == (b[a + 4 >> 2] | 0) : 0) ? 0 : 9;\r\n      } else { a = 9; } } while (0);\r\n      o = a;\r\n      T = p;\r\n      return o | 0;\r\n    }\r\n    function ha(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0;\r\n      m = T;\r\n      T = T + 16 | 0;\r\n      h = m;\r\n      if (!d) {\r\n        b[e >> 2] = a;\r\n        b[e + 4 >> 2] = c;\r\n        e = 0;\r\n        T = m;\r\n        return e | 0;\r\n      }\r\n      do { if ((d | 0) >= 0) {\r\n        if ((d | 0) > 13780509) {\r\n          f = uc(15, h) | 0;\r\n          if (f | 0) { break; }\r\n          g = h;\r\n          f = b[g >> 2] | 0;\r\n          g = b[g + 4 >> 2] | 0;\r\n        } else {\r\n          f = ((d | 0) < 0) << 31 >> 31;\r\n          l = Md(d | 0, f | 0, 3, 0) | 0;\r\n          g = H() | 0;\r\n          f = Gd(d | 0, f | 0, 1, 0) | 0;\r\n          f = Md(l | 0, g | 0, f | 0, H() | 0) | 0;\r\n          f = Gd(f | 0, H() | 0, 1, 0) | 0;\r\n          g = H() | 0;\r\n          l = h;\r\n          b[l >> 2] = f;\r\n          b[l + 4 >> 2] = g;\r\n        }\r\n        k = Fd(f, 8) | 0;\r\n        if (!k) { f = 13; }else {\r\n          l = Fd(f, 4) | 0;\r\n          if (!l) {\r\n            Ed(k);\r\n            f = 13;\r\n            break;\r\n          }\r\n          f = da(a, c, d, k, l, f, g, 0) | 0;\r\n          if (f | 0) {\r\n            Ed(k);\r\n            Ed(l);\r\n            break;\r\n          }\r\n          c = b[h >> 2] | 0;\r\n          h = b[h + 4 >> 2] | 0;\r\n          if ((h | 0) > 0 | (h | 0) == 0 & c >>> 0 > 0) {\r\n            f = 0;\r\n            i = 0;\r\n            j = 0;\r\n            do {\r\n              a = k + (i << 3) | 0;\r\n              g = b[a >> 2] | 0;\r\n              a = b[a + 4 >> 2] | 0;\r\n              if (!((g | 0) == 0 & (a | 0) == 0) ? (b[l + (i << 2) >> 2] | 0) == (d | 0) : 0) {\r\n                n = e + (f << 3) | 0;\r\n                b[n >> 2] = g;\r\n                b[n + 4 >> 2] = a;\r\n                f = f + 1 | 0;\r\n              }\r\n              i = Gd(i | 0, j | 0, 1, 0) | 0;\r\n              j = H() | 0;\r\n            } while ((j | 0) < (h | 0) | (j | 0) == (h | 0) & i >>> 0 < c >>> 0);\r\n          }\r\n          Ed(k);\r\n          Ed(l);\r\n          f = 0;\r\n        }\r\n      } else { f = 2; } } while (0);\r\n      n = f;\r\n      T = m;\r\n      return n | 0;\r\n    }\r\n    function ia(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      i = T;\r\n      T = T + 16 | 0;\r\n      g = i;\r\n      h = i + 8 | 0;\r\n      f = (Hb(a, c) | 0) == 0;\r\n      f = f ? 1 : 2;\r\n      while (1) {\r\n        b[h >> 2] = 0;\r\n        k = (ea(a, c, f, h, g) | 0) == 0;\r\n        j = g;\r\n        if (k & ((b[j >> 2] | 0) == (d | 0) ? (b[j + 4 >> 2] | 0) == (e | 0) : 0)) {\r\n          a = 4;\r\n          break;\r\n        }\r\n        f = f + 1 | 0;\r\n        if (f >>> 0 >= 7) {\r\n          f = 7;\r\n          a = 4;\r\n          break;\r\n        }\r\n      }\r\n      if ((a | 0) == 4) {\r\n        T = i;\r\n        return f | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function ja(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      i = T;\r\n      T = T + 48 | 0;\r\n      f = i + 16 | 0;\r\n      g = i + 8 | 0;\r\n      h = i;\r\n      d = Xc(d) | 0;\r\n      if (d | 0) {\r\n        h = d;\r\n        T = i;\r\n        return h | 0;\r\n      }\r\n      k = a;\r\n      j = b[k + 4 >> 2] | 0;\r\n      d = g;\r\n      b[d >> 2] = b[k >> 2];\r\n      b[d + 4 >> 2] = j;\r\n      Wc(g, f);\r\n      d = Ha(f, c, h) | 0;\r\n      if (!d) {\r\n        c = b[g >> 2] | 0;\r\n        g = b[a + 8 >> 2] | 0;\r\n        if ((g | 0) > 0) {\r\n          f = b[a + 12 >> 2] | 0;\r\n          d = 0;\r\n          do {\r\n            c = (b[f + (d << 3) >> 2] | 0) + c | 0;\r\n            d = d + 1 | 0;\r\n          } while ((d | 0) < (g | 0));\r\n        }\r\n        d = h;\r\n        f = b[d >> 2] | 0;\r\n        d = b[d + 4 >> 2] | 0;\r\n        g = ((c | 0) < 0) << 31 >> 31;\r\n        if ((d | 0) < (g | 0) | (d | 0) == (g | 0) & f >>> 0 < c >>> 0) {\r\n          d = h;\r\n          b[d >> 2] = c;\r\n          b[d + 4 >> 2] = g;\r\n          d = g;\r\n        } else { c = f; }\r\n        j = Gd(c | 0, d | 0, 12, 0) | 0;\r\n        k = H() | 0;\r\n        d = h;\r\n        b[d >> 2] = j;\r\n        b[d + 4 >> 2] = k;\r\n        d = e;\r\n        b[d >> 2] = j;\r\n        b[d + 4 >> 2] = k;\r\n        d = 0;\r\n      }\r\n      k = d;\r\n      T = i;\r\n      return k | 0;\r\n    }\r\n    function ka(a, c, d, f, g, h, i) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      h = h | 0;\r\n      i = i | 0;\r\n      var j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0,\r\n        D = 0,\r\n        E = 0,\r\n        F = 0,\r\n        G = 0,\r\n        I = 0,\r\n        J = 0.0,\r\n        K = 0.0,\r\n        L = 0.0,\r\n        M = 0.0;\r\n      I = T;\r\n      T = T + 64 | 0;\r\n      D = I + 48 | 0;\r\n      E = I + 32 | 0;\r\n      F = I + 24 | 0;\r\n      x = I + 8 | 0;\r\n      y = I;\r\n      k = b[a >> 2] | 0;\r\n      if ((k | 0) <= 0) {\r\n        G = 0;\r\n        T = I;\r\n        return G | 0;\r\n      }\r\n      z = a + 4 | 0;\r\n      A = D + 8 | 0;\r\n      B = E + 8 | 0;\r\n      C = x + 8 | 0;\r\n      j = 0;\r\n      v = 0;\r\n      while (1) {\r\n        l = b[z >> 2] | 0;\r\n        u = l + (v << 4) | 0;\r\n        b[D >> 2] = b[u >> 2];\r\n        b[D + 4 >> 2] = b[u + 4 >> 2];\r\n        b[D + 8 >> 2] = b[u + 8 >> 2];\r\n        b[D + 12 >> 2] = b[u + 12 >> 2];\r\n        if ((v | 0) == (k + -1 | 0)) {\r\n          b[E >> 2] = b[l >> 2];\r\n          b[E + 4 >> 2] = b[l + 4 >> 2];\r\n          b[E + 8 >> 2] = b[l + 8 >> 2];\r\n          b[E + 12 >> 2] = b[l + 12 >> 2];\r\n        } else {\r\n          u = l + (v + 1 << 4) | 0;\r\n          b[E >> 2] = b[u >> 2];\r\n          b[E + 4 >> 2] = b[u + 4 >> 2];\r\n          b[E + 8 >> 2] = b[u + 8 >> 2];\r\n          b[E + 12 >> 2] = b[u + 12 >> 2];\r\n        }\r\n        k = Ia(D, E, f, F) | 0;\r\n        a: do { if (!k) {\r\n          k = F;\r\n          l = b[k >> 2] | 0;\r\n          k = b[k + 4 >> 2] | 0;\r\n          if ((k | 0) > 0 | (k | 0) == 0 & l >>> 0 > 0) {\r\n            t = 0;\r\n            u = 0;\r\n            b: while (1) {\r\n              K = 1.0 / (+(l >>> 0) + 4294967296.0 * +(k | 0));\r\n              M = +e[D >> 3];\r\n              k = Hd(l | 0, k | 0, t | 0, u | 0) | 0;\r\n              L = +(k >>> 0) + 4294967296.0 * +(H() | 0);\r\n              J = +(t >>> 0) + 4294967296.0 * +(u | 0);\r\n              e[x >> 3] = K * (M * L) + K * (+e[E >> 3] * J);\r\n              e[C >> 3] = K * (+e[A >> 3] * L) + K * (+e[B >> 3] * J);\r\n              k = Wb(x, f, y) | 0;\r\n              if (k | 0) {\r\n                j = k;\r\n                break;\r\n              }\r\n              s = y;\r\n              r = b[s >> 2] | 0;\r\n              s = b[s + 4 >> 2] | 0;\r\n              o = Od(r | 0, s | 0, c | 0, d | 0) | 0;\r\n              m = H() | 0;\r\n              k = i + (o << 3) | 0;\r\n              n = k;\r\n              l = b[n >> 2] | 0;\r\n              n = b[n + 4 >> 2] | 0;\r\n              c: do { if ((l | 0) == 0 & (n | 0) == 0) {\r\n                w = k;\r\n                G = 16;\r\n              } else {\r\n                p = 0;\r\n                q = 0;\r\n                while (1) {\r\n                  if ((p | 0) > (d | 0) | (p | 0) == (d | 0) & q >>> 0 > c >>> 0) {\r\n                    j = 1;\r\n                    break b;\r\n                  }\r\n                  if ((l | 0) == (r | 0) & (n | 0) == (s | 0)) { break c; }\r\n                  k = Gd(o | 0, m | 0, 1, 0) | 0;\r\n                  o = Nd(k | 0, H() | 0, c | 0, d | 0) | 0;\r\n                  m = H() | 0;\r\n                  q = Gd(q | 0, p | 0, 1, 0) | 0;\r\n                  p = H() | 0;\r\n                  k = i + (o << 3) | 0;\r\n                  n = k;\r\n                  l = b[n >> 2] | 0;\r\n                  n = b[n + 4 >> 2] | 0;\r\n                  if ((l | 0) == 0 & (n | 0) == 0) {\r\n                    w = k;\r\n                    G = 16;\r\n                    break;\r\n                  }\r\n                }\r\n              } } while (0);\r\n              if ((G | 0) == 16 ? (G = 0, !((r | 0) == 0 & (s | 0) == 0)) : 0) {\r\n                q = w;\r\n                b[q >> 2] = r;\r\n                b[q + 4 >> 2] = s;\r\n                q = h + (b[g >> 2] << 3) | 0;\r\n                b[q >> 2] = r;\r\n                b[q + 4 >> 2] = s;\r\n                q = g;\r\n                q = Gd(b[q >> 2] | 0, b[q + 4 >> 2] | 0, 1, 0) | 0;\r\n                r = H() | 0;\r\n                s = g;\r\n                b[s >> 2] = q;\r\n                b[s + 4 >> 2] = r;\r\n              }\r\n              t = Gd(t | 0, u | 0, 1, 0) | 0;\r\n              u = H() | 0;\r\n              k = F;\r\n              l = b[k >> 2] | 0;\r\n              k = b[k + 4 >> 2] | 0;\r\n              if (!((k | 0) > (u | 0) | (k | 0) == (u | 0) & l >>> 0 > t >>> 0)) {\r\n                l = 1;\r\n                break a;\r\n              }\r\n            }\r\n            l = 0;\r\n          } else { l = 1; }\r\n        } else {\r\n          l = 0;\r\n          j = k;\r\n        } } while (0);\r\n        v = v + 1 | 0;\r\n        if (!l) {\r\n          G = 21;\r\n          break;\r\n        }\r\n        k = b[a >> 2] | 0;\r\n        if ((v | 0) >= (k | 0)) {\r\n          j = 0;\r\n          G = 21;\r\n          break;\r\n        }\r\n      }\r\n      if ((G | 0) == 21) {\r\n        T = I;\r\n        return j | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function la(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0,\r\n        D = 0,\r\n        E = 0,\r\n        F = 0,\r\n        G = 0,\r\n        I = 0,\r\n        J = 0,\r\n        K = 0;\r\n      K = T;\r\n      T = T + 112 | 0;\r\n      F = K + 80 | 0;\r\n      j = K + 72 | 0;\r\n      G = K;\r\n      I = K + 56 | 0;\r\n      f = Xc(d) | 0;\r\n      if (f | 0) {\r\n        J = f;\r\n        T = K;\r\n        return J | 0;\r\n      }\r\n      k = a + 8 | 0;\r\n      J = Dd((b[k >> 2] << 5) + 32 | 0) | 0;\r\n      if (!J) {\r\n        J = 13;\r\n        T = K;\r\n        return J | 0;\r\n      }\r\n      Yc(a, J);\r\n      f = Xc(d) | 0;\r\n      if (!f) {\r\n        D = a;\r\n        E = b[D + 4 >> 2] | 0;\r\n        f = j;\r\n        b[f >> 2] = b[D >> 2];\r\n        b[f + 4 >> 2] = E;\r\n        Wc(j, F);\r\n        f = Ha(F, c, G) | 0;\r\n        if (!f) {\r\n          f = b[j >> 2] | 0;\r\n          g = b[k >> 2] | 0;\r\n          if ((g | 0) > 0) {\r\n            h = b[a + 12 >> 2] | 0;\r\n            d = 0;\r\n            do {\r\n              f = (b[h + (d << 3) >> 2] | 0) + f | 0;\r\n              d = d + 1 | 0;\r\n            } while ((d | 0) != (g | 0));\r\n            d = f;\r\n          } else { d = f; }\r\n          f = G;\r\n          g = b[f >> 2] | 0;\r\n          f = b[f + 4 >> 2] | 0;\r\n          h = ((d | 0) < 0) << 31 >> 31;\r\n          if ((f | 0) < (h | 0) | (f | 0) == (h | 0) & g >>> 0 < d >>> 0) {\r\n            f = G;\r\n            b[f >> 2] = d;\r\n            b[f + 4 >> 2] = h;\r\n            f = h;\r\n          } else { d = g; }\r\n          D = Gd(d | 0, f | 0, 12, 0) | 0;\r\n          E = H() | 0;\r\n          f = G;\r\n          b[f >> 2] = D;\r\n          b[f + 4 >> 2] = E;\r\n          f = 0;\r\n        } else {\r\n          D = 0;\r\n          E = 0;\r\n        }\r\n        if (!f) {\r\n          d = Fd(D, 8) | 0;\r\n          if (!d) {\r\n            Ed(J);\r\n            J = 13;\r\n            T = K;\r\n            return J | 0;\r\n          }\r\n          i = Fd(D, 8) | 0;\r\n          if (!i) {\r\n            Ed(J);\r\n            Ed(d);\r\n            J = 13;\r\n            T = K;\r\n            return J | 0;\r\n          }\r\n          B = F;\r\n          b[B >> 2] = 0;\r\n          b[B + 4 >> 2] = 0;\r\n          B = a;\r\n          C = b[B + 4 >> 2] | 0;\r\n          f = j;\r\n          b[f >> 2] = b[B >> 2];\r\n          b[f + 4 >> 2] = C;\r\n          f = ka(j, D, E, c, F, d, i) | 0;\r\n          a: do { if (!f) {\r\n            b: do { if ((b[k >> 2] | 0) > 0) {\r\n              h = a + 12 | 0;\r\n              g = 0;\r\n              while (1) {\r\n                f = ka((b[h >> 2] | 0) + (g << 3) | 0, D, E, c, F, d, i) | 0;\r\n                g = g + 1 | 0;\r\n                if (f | 0) { break; }\r\n                if ((g | 0) >= (b[k >> 2] | 0)) { break b; }\r\n              }\r\n              Ed(d);\r\n              Ed(i);\r\n              Ed(J);\r\n              break a;\r\n            } } while (0);\r\n            if ((E | 0) > 0 | (E | 0) == 0 & D >>> 0 > 0) { Xd(i | 0, 0, D << 3 | 0) | 0; }\r\n            C = F;\r\n            B = b[C + 4 >> 2] | 0;\r\n            c: do { if ((B | 0) > 0 | (B | 0) == 0 & (b[C >> 2] | 0) >>> 0 > 0) {\r\n              y = d;\r\n              z = i;\r\n              A = d;\r\n              B = i;\r\n              C = d;\r\n              f = d;\r\n              v = d;\r\n              w = i;\r\n              x = i;\r\n              d = i;\r\n              d: while (1) {\r\n                r = 0;\r\n                s = 0;\r\n                t = 0;\r\n                u = 0;\r\n                g = 0;\r\n                h = 0;\r\n                while (1) {\r\n                  i = G;\r\n                  j = i + 56 | 0;\r\n                  do {\r\n                    b[i >> 2] = 0;\r\n                    i = i + 4 | 0;\r\n                  } while ((i | 0) < (j | 0));\r\n                  c = y + (r << 3) | 0;\r\n                  k = b[c >> 2] | 0;\r\n                  c = b[c + 4 >> 2] | 0;\r\n                  if (ca(k, c, 1, G, 0) | 0) {\r\n                    i = G;\r\n                    j = i + 56 | 0;\r\n                    do {\r\n                      b[i >> 2] = 0;\r\n                      i = i + 4 | 0;\r\n                    } while ((i | 0) < (j | 0));\r\n                    i = Fd(7, 4) | 0;\r\n                    if (i | 0) {\r\n                      da(k, c, 1, G, i, 7, 0, 0) | 0;\r\n                      Ed(i);\r\n                    }\r\n                  }\r\n                  q = 0;\r\n                  while (1) {\r\n                    p = G + (q << 3) | 0;\r\n                    o = b[p >> 2] | 0;\r\n                    p = b[p + 4 >> 2] | 0;\r\n                    e: do { if ((o | 0) == 0 & (p | 0) == 0) {\r\n                      i = g;\r\n                      j = h;\r\n                    } else {\r\n                      l = Od(o | 0, p | 0, D | 0, E | 0) | 0;\r\n                      k = H() | 0;\r\n                      i = e + (l << 3) | 0;\r\n                      c = i;\r\n                      j = b[c >> 2] | 0;\r\n                      c = b[c + 4 >> 2] | 0;\r\n                      if (!((j | 0) == 0 & (c | 0) == 0)) {\r\n                        m = 0;\r\n                        n = 0;\r\n                        do {\r\n                          if ((m | 0) > (E | 0) | (m | 0) == (E | 0) & n >>> 0 > D >>> 0) { break d; }\r\n                          if ((j | 0) == (o | 0) & (c | 0) == (p | 0)) {\r\n                            i = g;\r\n                            j = h;\r\n                            break e;\r\n                          }\r\n                          i = Gd(l | 0, k | 0, 1, 0) | 0;\r\n                          l = Nd(i | 0, H() | 0, D | 0, E | 0) | 0;\r\n                          k = H() | 0;\r\n                          n = Gd(n | 0, m | 0, 1, 0) | 0;\r\n                          m = H() | 0;\r\n                          i = e + (l << 3) | 0;\r\n                          c = i;\r\n                          j = b[c >> 2] | 0;\r\n                          c = b[c + 4 >> 2] | 0;\r\n                        } while (!((j | 0) == 0 & (c | 0) == 0));\r\n                      }\r\n                      if ((o | 0) == 0 & (p | 0) == 0) {\r\n                        i = g;\r\n                        j = h;\r\n                        break;\r\n                      }\r\n                      Zb(o, p, I) | 0;\r\n                      if (Zc(a, J, I) | 0) {\r\n                        n = Gd(g | 0, h | 0, 1, 0) | 0;\r\n                        h = H() | 0;\r\n                        m = i;\r\n                        b[m >> 2] = o;\r\n                        b[m + 4 >> 2] = p;\r\n                        g = z + (g << 3) | 0;\r\n                        b[g >> 2] = o;\r\n                        b[g + 4 >> 2] = p;\r\n                        g = n;\r\n                      }\r\n                      i = g;\r\n                      j = h;\r\n                    } } while (0);\r\n                    q = q + 1 | 0;\r\n                    if (q >>> 0 >= 7) { break; }else {\r\n                      g = i;\r\n                      h = j;\r\n                    }\r\n                  }\r\n                  r = Gd(r | 0, s | 0, 1, 0) | 0;\r\n                  s = H() | 0;\r\n                  t = Gd(t | 0, u | 0, 1, 0) | 0;\r\n                  u = H() | 0;\r\n                  h = F;\r\n                  g = b[h >> 2] | 0;\r\n                  h = b[h + 4 >> 2] | 0;\r\n                  if (!((u | 0) < (h | 0) | (u | 0) == (h | 0) & t >>> 0 < g >>> 0)) { break; }else {\r\n                    g = i;\r\n                    h = j;\r\n                  }\r\n                }\r\n                if ((h | 0) > 0 | (h | 0) == 0 & g >>> 0 > 0) {\r\n                  g = 0;\r\n                  h = 0;\r\n                  do {\r\n                    u = y + (g << 3) | 0;\r\n                    b[u >> 2] = 0;\r\n                    b[u + 4 >> 2] = 0;\r\n                    g = Gd(g | 0, h | 0, 1, 0) | 0;\r\n                    h = H() | 0;\r\n                    u = F;\r\n                    t = b[u + 4 >> 2] | 0;\r\n                  } while ((h | 0) < (t | 0) | ((h | 0) == (t | 0) ? g >>> 0 < (b[u >> 2] | 0) >>> 0 : 0));\r\n                }\r\n                u = F;\r\n                b[u >> 2] = i;\r\n                b[u + 4 >> 2] = j;\r\n                if ((j | 0) > 0 | (j | 0) == 0 & i >>> 0 > 0) {\r\n                  q = d;\r\n                  r = x;\r\n                  s = C;\r\n                  t = w;\r\n                  u = z;\r\n                  d = v;\r\n                  x = f;\r\n                  w = A;\r\n                  v = q;\r\n                  f = r;\r\n                  C = B;\r\n                  B = s;\r\n                  A = t;\r\n                  z = y;\r\n                  y = u;\r\n                } else { break c; }\r\n              }\r\n              Ed(A);\r\n              Ed(B);\r\n              Ed(J);\r\n              f = 1;\r\n              break a;\r\n            } else { f = i; } } while (0);\r\n            Ed(J);\r\n            Ed(d);\r\n            Ed(f);\r\n            f = 0;\r\n          } else {\r\n            Ed(d);\r\n            Ed(i);\r\n            Ed(J);\r\n          } } while (0);\r\n          J = f;\r\n          T = K;\r\n          return J | 0;\r\n        }\r\n      }\r\n      Ed(J);\r\n      J = f;\r\n      T = K;\r\n      return J | 0;\r\n    }\r\n    function ma(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0;\r\n      l = T;\r\n      T = T + 176 | 0;\r\n      j = l;\r\n      if ((c | 0) < 1) {\r\n        ud(d, 0, 0);\r\n        k = 0;\r\n        T = l;\r\n        return k | 0;\r\n      }\r\n      i = a;\r\n      i = Qd(b[i >> 2] | 0, b[i + 4 >> 2] | 0, 52) | 0;\r\n      H() | 0;\r\n      ud(d, (c | 0) > 6 ? c : 6, i & 15);\r\n      i = 0;\r\n      while (1) {\r\n        e = a + (i << 3) | 0;\r\n        e = _b(b[e >> 2] | 0, b[e + 4 >> 2] | 0, j) | 0;\r\n        if (e | 0) { break; }\r\n        e = b[j >> 2] | 0;\r\n        if ((e | 0) > 0) {\r\n          h = 0;\r\n          do {\r\n            g = j + 8 + (h << 4) | 0;\r\n            h = h + 1 | 0;\r\n            e = j + 8 + (((h | 0) % (e | 0) | 0) << 4) | 0;\r\n            f = zd(d, e, g) | 0;\r\n            if (!f) { yd(d, g, e) | 0; }else { xd(d, f) | 0; }\r\n            e = b[j >> 2] | 0;\r\n          } while ((h | 0) < (e | 0));\r\n        }\r\n        i = i + 1 | 0;\r\n        if ((i | 0) >= (c | 0)) {\r\n          e = 0;\r\n          k = 13;\r\n          break;\r\n        }\r\n      }\r\n      if ((k | 0) == 13) {\r\n        T = l;\r\n        return e | 0;\r\n      }\r\n      vd(d);\r\n      k = e;\r\n      T = l;\r\n      return k | 0;\r\n    }\r\n    function na(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      g = T;\r\n      T = T + 32 | 0;\r\n      e = g;\r\n      f = g + 16 | 0;\r\n      a = ma(a, c, f) | 0;\r\n      if (a | 0) {\r\n        d = a;\r\n        T = g;\r\n        return d | 0;\r\n      }\r\n      b[d >> 2] = 0;\r\n      b[d + 4 >> 2] = 0;\r\n      b[d + 8 >> 2] = 0;\r\n      a = wd(f) | 0;\r\n      if (a | 0) { do {\r\n        c = Cc(d) | 0;\r\n        do {\r\n          Dc(c, a) | 0;\r\n          h = a + 16 | 0;\r\n          b[e >> 2] = b[h >> 2];\r\n          b[e + 4 >> 2] = b[h + 4 >> 2];\r\n          b[e + 8 >> 2] = b[h + 8 >> 2];\r\n          b[e + 12 >> 2] = b[h + 12 >> 2];\r\n          xd(f, a) | 0;\r\n          a = Ad(f, e) | 0;\r\n        } while ((a | 0) != 0);\r\n        a = wd(f) | 0;\r\n      } while ((a | 0) != 0); }\r\n      vd(f);\r\n      a = Fc(d) | 0;\r\n      if (!a) {\r\n        h = 0;\r\n        T = g;\r\n        return h | 0;\r\n      }\r\n      Ec(d);\r\n      h = a;\r\n      T = g;\r\n      return h | 0;\r\n    }\r\n    function oa(a) {\r\n      a = a | 0;\r\n      if (a >>> 0 > 121) {\r\n        a = 0;\r\n        return a | 0;\r\n      }\r\n      a = b[7696 + (a * 28 | 0) + 16 >> 2] | 0;\r\n      return a | 0;\r\n    }\r\n    function pa(a) {\r\n      a = a | 0;\r\n      return (a | 0) == 4 | (a | 0) == 117 | 0;\r\n    }\r\n    function qa(a) {\r\n      a = a | 0;\r\n      return b[11120 + ((b[a >> 2] | 0) * 216 | 0) + ((b[a + 4 >> 2] | 0) * 72 | 0) + ((b[a + 8 >> 2] | 0) * 24 | 0) + (b[a + 12 >> 2] << 3) >> 2] | 0;\r\n    }\r\n    function ra(a) {\r\n      a = a | 0;\r\n      return b[11120 + ((b[a >> 2] | 0) * 216 | 0) + ((b[a + 4 >> 2] | 0) * 72 | 0) + ((b[a + 8 >> 2] | 0) * 24 | 0) + (b[a + 12 >> 2] << 3) + 4 >> 2] | 0;\r\n    }\r\n    function sa(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      a = 7696 + (a * 28 | 0) | 0;\r\n      b[c >> 2] = b[a >> 2];\r\n      b[c + 4 >> 2] = b[a + 4 >> 2];\r\n      b[c + 8 >> 2] = b[a + 8 >> 2];\r\n      b[c + 12 >> 2] = b[a + 12 >> 2];\r\n      return;\r\n    }\r\n    function ta(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0;\r\n      if (c >>> 0 > 20) {\r\n        c = -1;\r\n        return c | 0;\r\n      }\r\n      do { if ((b[11120 + (c * 216 | 0) >> 2] | 0) != (a | 0)) {\r\n        if ((b[11120 + (c * 216 | 0) + 8 >> 2] | 0) != (a | 0)) {\r\n          if ((b[11120 + (c * 216 | 0) + 16 >> 2] | 0) != (a | 0)) {\r\n            if ((b[11120 + (c * 216 | 0) + 24 >> 2] | 0) != (a | 0)) {\r\n              if ((b[11120 + (c * 216 | 0) + 32 >> 2] | 0) != (a | 0)) {\r\n                if ((b[11120 + (c * 216 | 0) + 40 >> 2] | 0) != (a | 0)) {\r\n                  if ((b[11120 + (c * 216 | 0) + 48 >> 2] | 0) != (a | 0)) {\r\n                    if ((b[11120 + (c * 216 | 0) + 56 >> 2] | 0) != (a | 0)) {\r\n                      if ((b[11120 + (c * 216 | 0) + 64 >> 2] | 0) != (a | 0)) {\r\n                        if ((b[11120 + (c * 216 | 0) + 72 >> 2] | 0) != (a | 0)) {\r\n                          if ((b[11120 + (c * 216 | 0) + 80 >> 2] | 0) != (a | 0)) {\r\n                            if ((b[11120 + (c * 216 | 0) + 88 >> 2] | 0) != (a | 0)) {\r\n                              if ((b[11120 + (c * 216 | 0) + 96 >> 2] | 0) != (a | 0)) {\r\n                                if ((b[11120 + (c * 216 | 0) + 104 >> 2] | 0) != (a | 0)) {\r\n                                  if ((b[11120 + (c * 216 | 0) + 112 >> 2] | 0) != (a | 0)) {\r\n                                    if ((b[11120 + (c * 216 | 0) + 120 >> 2] | 0) != (a | 0)) {\r\n                                      if ((b[11120 + (c * 216 | 0) + 128 >> 2] | 0) != (a | 0)) {\r\n                                        if ((b[11120 + (c * 216 | 0) + 136 >> 2] | 0) == (a | 0)) {\r\n                                          a = 2;\r\n                                          d = 1;\r\n                                          e = 2;\r\n                                        } else {\r\n                                          if ((b[11120 + (c * 216 | 0) + 144 >> 2] | 0) == (a | 0)) {\r\n                                            a = 0;\r\n                                            d = 2;\r\n                                            e = 0;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 152 >> 2] | 0) == (a | 0)) {\r\n                                            a = 0;\r\n                                            d = 2;\r\n                                            e = 1;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 160 >> 2] | 0) == (a | 0)) {\r\n                                            a = 0;\r\n                                            d = 2;\r\n                                            e = 2;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 168 >> 2] | 0) == (a | 0)) {\r\n                                            a = 1;\r\n                                            d = 2;\r\n                                            e = 0;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 176 >> 2] | 0) == (a | 0)) {\r\n                                            a = 1;\r\n                                            d = 2;\r\n                                            e = 1;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 184 >> 2] | 0) == (a | 0)) {\r\n                                            a = 1;\r\n                                            d = 2;\r\n                                            e = 2;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 192 >> 2] | 0) == (a | 0)) {\r\n                                            a = 2;\r\n                                            d = 2;\r\n                                            e = 0;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 200 >> 2] | 0) == (a | 0)) {\r\n                                            a = 2;\r\n                                            d = 2;\r\n                                            e = 1;\r\n                                            break;\r\n                                          }\r\n                                          if ((b[11120 + (c * 216 | 0) + 208 >> 2] | 0) == (a | 0)) {\r\n                                            a = 2;\r\n                                            d = 2;\r\n                                            e = 2;\r\n                                            break;\r\n                                          } else { a = -1; }\r\n                                          return a | 0;\r\n                                        }\r\n                                      } else {\r\n                                        a = 2;\r\n                                        d = 1;\r\n                                        e = 1;\r\n                                      }\r\n                                    } else {\r\n                                      a = 2;\r\n                                      d = 1;\r\n                                      e = 0;\r\n                                    }\r\n                                  } else {\r\n                                    a = 1;\r\n                                    d = 1;\r\n                                    e = 2;\r\n                                  }\r\n                                } else {\r\n                                  a = 1;\r\n                                  d = 1;\r\n                                  e = 1;\r\n                                }\r\n                              } else {\r\n                                a = 1;\r\n                                d = 1;\r\n                                e = 0;\r\n                              }\r\n                            } else {\r\n                              a = 0;\r\n                              d = 1;\r\n                              e = 2;\r\n                            }\r\n                          } else {\r\n                            a = 0;\r\n                            d = 1;\r\n                            e = 1;\r\n                          }\r\n                        } else {\r\n                          a = 0;\r\n                          d = 1;\r\n                          e = 0;\r\n                        }\r\n                      } else {\r\n                        a = 2;\r\n                        d = 0;\r\n                        e = 2;\r\n                      }\r\n                    } else {\r\n                      a = 2;\r\n                      d = 0;\r\n                      e = 1;\r\n                    }\r\n                  } else {\r\n                    a = 2;\r\n                    d = 0;\r\n                    e = 0;\r\n                  }\r\n                } else {\r\n                  a = 1;\r\n                  d = 0;\r\n                  e = 2;\r\n                }\r\n              } else {\r\n                a = 1;\r\n                d = 0;\r\n                e = 1;\r\n              }\r\n            } else {\r\n              a = 1;\r\n              d = 0;\r\n              e = 0;\r\n            }\r\n          } else {\r\n            a = 0;\r\n            d = 0;\r\n            e = 2;\r\n          }\r\n        } else {\r\n          a = 0;\r\n          d = 0;\r\n          e = 1;\r\n        }\r\n      } else {\r\n        a = 0;\r\n        d = 0;\r\n        e = 0;\r\n      } } while (0);\r\n      c = b[11120 + (c * 216 | 0) + (d * 72 | 0) + (a * 24 | 0) + (e << 3) + 4 >> 2] | 0;\r\n      return c | 0;\r\n    }\r\n    function ua(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      if ((b[7696 + (a * 28 | 0) + 20 >> 2] | 0) == (c | 0)) {\r\n        c = 1;\r\n        return c | 0;\r\n      }\r\n      c = (b[7696 + (a * 28 | 0) + 24 >> 2] | 0) == (c | 0);\r\n      return c | 0;\r\n    }\r\n    function va(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      return b[848 + (a * 28 | 0) + (c << 2) >> 2] | 0;\r\n    }\r\n    function wa(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      if ((b[848 + (a * 28 | 0) >> 2] | 0) == (c | 0)) {\r\n        c = 0;\r\n        return c | 0;\r\n      }\r\n      if ((b[848 + (a * 28 | 0) + 4 >> 2] | 0) == (c | 0)) {\r\n        c = 1;\r\n        return c | 0;\r\n      }\r\n      if ((b[848 + (a * 28 | 0) + 8 >> 2] | 0) == (c | 0)) {\r\n        c = 2;\r\n        return c | 0;\r\n      }\r\n      if ((b[848 + (a * 28 | 0) + 12 >> 2] | 0) == (c | 0)) {\r\n        c = 3;\r\n        return c | 0;\r\n      }\r\n      if ((b[848 + (a * 28 | 0) + 16 >> 2] | 0) == (c | 0)) {\r\n        c = 4;\r\n        return c | 0;\r\n      }\r\n      if ((b[848 + (a * 28 | 0) + 20 >> 2] | 0) == (c | 0)) {\r\n        c = 5;\r\n        return c | 0;\r\n      } else { return ((b[848 + (a * 28 | 0) + 24 >> 2] | 0) == (c | 0) ? 6 : 7) | 0; }\r\n      return 0;\r\n    }\r\n    function xa() {\r\n      return 122;\r\n    }\r\n    function ya(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      c = 0;\r\n      do {\r\n        Rd(c | 0, 0, 45) | 0;\r\n        e = H() | 0 | 134225919;\r\n        d = a + (c << 3) | 0;\r\n        b[d >> 2] = -1;\r\n        b[d + 4 >> 2] = e;\r\n        c = c + 1 | 0;\r\n      } while ((c | 0) != 122);\r\n      return 0;\r\n    }\r\n    function za(a) {\r\n      a = a | 0;\r\n      var b = 0.0,\r\n        c = 0.0,\r\n        d = 0.0;\r\n      d = +e[a + 16 >> 3];\r\n      c = +e[a + 24 >> 3];\r\n      b = d - c;\r\n      return +(d < c ? b + 6.283185307179586 : b);\r\n    }\r\n    function Aa(a) {\r\n      a = a | 0;\r\n      return +e[a + 16 >> 3] < +e[a + 24 >> 3] | 0;\r\n    }\r\n    function Ba(a) {\r\n      a = a | 0;\r\n      return +(+e[a >> 3] - +e[a + 8 >> 3]);\r\n    }\r\n    function Ca(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0;\r\n      c = +e[b >> 3];\r\n      if (!(c >= +e[a + 8 >> 3])) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      if (!(c <= +e[a >> 3])) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      d = +e[a + 16 >> 3];\r\n      c = +e[a + 24 >> 3];\r\n      f = +e[b + 8 >> 3];\r\n      b = f >= c;\r\n      a = f <= d & 1;\r\n      if (d < c) {\r\n        if (b) { a = 1; }\r\n      } else if (!b) { a = 0; }\r\n      b = (a | 0) != 0;\r\n      return b | 0;\r\n    }\r\n    function Da(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        f = 0,\r\n        g = 0.0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0;\r\n      if (+e[a >> 3] < +e[b + 8 >> 3]) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      if (+e[a + 8 >> 3] > +e[b >> 3]) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      g = +e[a + 16 >> 3];\r\n      c = a + 24 | 0;\r\n      l = +e[c >> 3];\r\n      h = g < l;\r\n      d = b + 16 | 0;\r\n      k = +e[d >> 3];\r\n      f = b + 24 | 0;\r\n      j = +e[f >> 3];\r\n      i = k < j;\r\n      b = l - k < j - g;\r\n      a = h ? i | b ? 1 : 2 : 0;\r\n      b = i ? h ? 1 : b ? 2 : 1 : 0;\r\n      g = +kc(g, a);\r\n      if (g < +kc(+e[f >> 3], b)) {\r\n        i = 0;\r\n        return i | 0;\r\n      }\r\n      l = +kc(+e[c >> 3], a);\r\n      if (l > +kc(+e[d >> 3], b)) {\r\n        i = 0;\r\n        return i | 0;\r\n      }\r\n      i = 1;\r\n      return i | 0;\r\n    }\r\n    function Ea(a, c, d, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0;\r\n      h = +e[a + 16 >> 3];\r\n      k = +e[a + 24 >> 3];\r\n      a = h < k;\r\n      j = +e[c + 16 >> 3];\r\n      i = +e[c + 24 >> 3];\r\n      g = j < i;\r\n      c = k - j < i - h;\r\n      b[d >> 2] = a ? g | c ? 1 : 2 : 0;\r\n      b[f >> 2] = g ? a ? 1 : c ? 2 : 1 : 0;\r\n      return;\r\n    }\r\n    function Fa(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        f = 0,\r\n        g = 0.0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0;\r\n      if (+e[a >> 3] < +e[b >> 3]) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      if (+e[a + 8 >> 3] > +e[b + 8 >> 3]) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      d = a + 16 | 0;\r\n      j = +e[d >> 3];\r\n      g = +e[a + 24 >> 3];\r\n      h = j < g;\r\n      c = b + 16 | 0;\r\n      l = +e[c >> 3];\r\n      f = b + 24 | 0;\r\n      k = +e[f >> 3];\r\n      i = l < k;\r\n      b = g - l < k - j;\r\n      a = h ? i | b ? 1 : 2 : 0;\r\n      b = i ? h ? 1 : b ? 2 : 1 : 0;\r\n      g = +kc(g, a);\r\n      if (!(g <= +kc(+e[f >> 3], b))) {\r\n        i = 0;\r\n        return i | 0;\r\n      }\r\n      l = +kc(+e[d >> 3], a);\r\n      i = l >= +kc(+e[c >> 3], b);\r\n      return i | 0;\r\n    }\r\n    function Ga(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0;\r\n      g = T;\r\n      T = T + 176 | 0;\r\n      f = g;\r\n      b[f >> 2] = 4;\r\n      j = +e[c >> 3];\r\n      e[f + 8 >> 3] = j;\r\n      h = +e[c + 16 >> 3];\r\n      e[f + 16 >> 3] = h;\r\n      e[f + 24 >> 3] = j;\r\n      j = +e[c + 24 >> 3];\r\n      e[f + 32 >> 3] = j;\r\n      i = +e[c + 8 >> 3];\r\n      e[f + 40 >> 3] = i;\r\n      e[f + 48 >> 3] = j;\r\n      e[f + 56 >> 3] = i;\r\n      e[f + 64 >> 3] = h;\r\n      c = f + 72 | 0;\r\n      d = c + 96 | 0;\r\n      do {\r\n        b[c >> 2] = 0;\r\n        c = c + 4 | 0;\r\n      } while ((c | 0) < (d | 0));\r\n      Wd(a | 0, f | 0, 168) | 0;\r\n      T = g;\r\n      return;\r\n    }\r\n    function Ha(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0.0,\r\n        v = 0.0;\r\n      t = T;\r\n      T = T + 288 | 0;\r\n      n = t + 264 | 0;\r\n      o = t + 96 | 0;\r\n      m = t;\r\n      k = m;\r\n      l = k + 96 | 0;\r\n      do {\r\n        b[k >> 2] = 0;\r\n        k = k + 4 | 0;\r\n      } while ((k | 0) < (l | 0));\r\n      c = cc(c, m) | 0;\r\n      if (c | 0) {\r\n        s = c;\r\n        T = t;\r\n        return s | 0;\r\n      }\r\n      l = m;\r\n      m = b[l >> 2] | 0;\r\n      l = b[l + 4 >> 2] | 0;\r\n      Zb(m, l, n) | 0;\r\n      _b(m, l, o) | 0;\r\n      j = +mc(n, o + 8 | 0);\r\n      e[n >> 3] = +e[a >> 3];\r\n      l = n + 8 | 0;\r\n      e[l >> 3] = +e[a + 16 >> 3];\r\n      e[o >> 3] = +e[a + 8 >> 3];\r\n      m = o + 8 | 0;\r\n      e[m >> 3] = +e[a + 24 >> 3];\r\n      h = +mc(n, o);\r\n      v = +e[l >> 3] - +e[m >> 3];\r\n      i = +q(+v);\r\n      u = +e[n >> 3] - +e[o >> 3];\r\n      g = +q(+u);\r\n      if (!(v == 0.0 | u == 0.0) ? (v = +Td(+i, +g), v = +A(+(h * h / +Ud(+(v / +Ud(+i, +g)), 3.0) / (j * (j * 2.59807621135) * .8))), e[f >> 3] = v, r = ~~v >>> 0, s = +q(v) >= 1.0 ? v > 0.0 ? ~~+C(+p(v / 4294967296.0), 4294967295.0) >>> 0 : ~~+A((v - +(~~v >>> 0)) / 4294967296.0) >>> 0 : 0, !((b[f + 4 >> 2] & 2146435072 | 0) == 2146435072)) : 0) {\r\n        o = (r | 0) == 0 & (s | 0) == 0;\r\n        c = d;\r\n        b[c >> 2] = o ? 1 : r;\r\n        b[c + 4 >> 2] = o ? 0 : s;\r\n        c = 0;\r\n      } else { c = 1; }\r\n      s = c;\r\n      T = t;\r\n      return s | 0;\r\n    }\r\n    function Ia(a, c, d, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0.0;\r\n      m = T;\r\n      T = T + 288 | 0;\r\n      j = m + 264 | 0;\r\n      k = m + 96 | 0;\r\n      l = m;\r\n      h = l;\r\n      i = h + 96 | 0;\r\n      do {\r\n        b[h >> 2] = 0;\r\n        h = h + 4 | 0;\r\n      } while ((h | 0) < (i | 0));\r\n      d = cc(d, l) | 0;\r\n      if (d | 0) {\r\n        g = d;\r\n        T = m;\r\n        return g | 0;\r\n      }\r\n      d = l;\r\n      h = b[d >> 2] | 0;\r\n      d = b[d + 4 >> 2] | 0;\r\n      Zb(h, d, j) | 0;\r\n      _b(h, d, k) | 0;\r\n      n = +mc(j, k + 8 | 0);\r\n      n = +A(+(+mc(a, c) / (n * 2.0)));\r\n      e[f >> 3] = n;\r\n      d = ~~n >>> 0;\r\n      h = +q(n) >= 1.0 ? n > 0.0 ? ~~+C(+p(n / 4294967296.0), 4294967295.0) >>> 0 : ~~+A((n - +(~~n >>> 0)) / 4294967296.0) >>> 0 : 0;\r\n      if ((b[f + 4 >> 2] & 2146435072 | 0) == 2146435072) {\r\n        g = 1;\r\n        T = m;\r\n        return g | 0;\r\n      }\r\n      l = (d | 0) == 0 & (h | 0) == 0;\r\n      b[g >> 2] = l ? 1 : d;\r\n      b[g + 4 >> 2] = l ? 0 : h;\r\n      g = 0;\r\n      T = m;\r\n      return g | 0;\r\n    }\r\n    function Ja(a, b) {\r\n      a = a | 0;\r\n      b = +b;\r\n      var c = 0,\r\n        d = 0.0,\r\n        f = 0.0,\r\n        g = 0,\r\n        h = 0.0,\r\n        i = 0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0;\r\n      g = a + 16 | 0;\r\n      h = +e[g >> 3];\r\n      c = a + 24 | 0;\r\n      f = +e[c >> 3];\r\n      d = h - f;\r\n      d = h < f ? d + 6.283185307179586 : d;\r\n      k = +e[a >> 3];\r\n      i = a + 8 | 0;\r\n      j = +e[i >> 3];\r\n      l = k - j;\r\n      d = (d * b - d) * .5;\r\n      b = (l * b - l) * .5;\r\n      k = k + b;\r\n      e[a >> 3] = k > 1.5707963267948966 ? 1.5707963267948966 : k;\r\n      b = j - b;\r\n      e[i >> 3] = b < -1.5707963267948966 ? -1.5707963267948966 : b;\r\n      b = h + d;\r\n      b = b > 3.141592653589793 ? b + -6.283185307179586 : b;\r\n      e[g >> 3] = b < -3.141592653589793 ? b + 6.283185307179586 : b;\r\n      b = f - d;\r\n      b = b > 3.141592653589793 ? b + -6.283185307179586 : b;\r\n      e[c >> 3] = b < -3.141592653589793 ? b + 6.283185307179586 : b;\r\n      return;\r\n    }\r\n    function Ka(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      b[a >> 2] = c;\r\n      b[a + 4 >> 2] = d;\r\n      b[a + 8 >> 2] = e;\r\n      return;\r\n    }\r\n    function La(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0.0;\r\n      n = c + 8 | 0;\r\n      b[n >> 2] = 0;\r\n      k = +e[a >> 3];\r\n      i = +q(+k);\r\n      l = +e[a + 8 >> 3];\r\n      j = +q(+l) * 1.1547005383792515;\r\n      i = i + j * .5;\r\n      d = ~~i;\r\n      a = ~~j;\r\n      i = i - +(d | 0);\r\n      j = j - +(a | 0);\r\n      do { if (i < .5) {\r\n        if (i < .3333333333333333) {\r\n          b[c >> 2] = d;\r\n          if (j < (i + 1.0) * .5) {\r\n            b[c + 4 >> 2] = a;\r\n            break;\r\n          } else {\r\n            a = a + 1 | 0;\r\n            b[c + 4 >> 2] = a;\r\n            break;\r\n          }\r\n        } else {\r\n          o = 1.0 - i;\r\n          a = (!(j < o) & 1) + a | 0;\r\n          b[c + 4 >> 2] = a;\r\n          if (o <= j & j < i * 2.0) {\r\n            d = d + 1 | 0;\r\n            b[c >> 2] = d;\r\n            break;\r\n          } else {\r\n            b[c >> 2] = d;\r\n            break;\r\n          }\r\n        }\r\n      } else {\r\n        if (!(i < .6666666666666666)) {\r\n          d = d + 1 | 0;\r\n          b[c >> 2] = d;\r\n          if (j < i * .5) {\r\n            b[c + 4 >> 2] = a;\r\n            break;\r\n          } else {\r\n            a = a + 1 | 0;\r\n            b[c + 4 >> 2] = a;\r\n            break;\r\n          }\r\n        }\r\n        if (j < 1.0 - i) {\r\n          b[c + 4 >> 2] = a;\r\n          if (i * 2.0 + -1.0 < j) {\r\n            b[c >> 2] = d;\r\n            break;\r\n          }\r\n        } else {\r\n          a = a + 1 | 0;\r\n          b[c + 4 >> 2] = a;\r\n        }\r\n        d = d + 1 | 0;\r\n        b[c >> 2] = d;\r\n      } } while (0);\r\n      do { if (k < 0.0) { if (!(a & 1)) {\r\n        m = (a | 0) / 2 | 0;\r\n        m = Hd(d | 0, ((d | 0) < 0) << 31 >> 31 | 0, m | 0, ((m | 0) < 0) << 31 >> 31 | 0) | 0;\r\n        d = ~~(+(d | 0) - (+(m >>> 0) + 4294967296.0 * +(H() | 0)) * 2.0);\r\n        b[c >> 2] = d;\r\n        break;\r\n      } else {\r\n        m = (a + 1 | 0) / 2 | 0;\r\n        m = Hd(d | 0, ((d | 0) < 0) << 31 >> 31 | 0, m | 0, ((m | 0) < 0) << 31 >> 31 | 0) | 0;\r\n        d = ~~(+(d | 0) - ((+(m >>> 0) + 4294967296.0 * +(H() | 0)) * 2.0 + 1.0));\r\n        b[c >> 2] = d;\r\n        break;\r\n      } } } while (0);\r\n      m = c + 4 | 0;\r\n      if (l < 0.0) {\r\n        d = d - ((a << 1 | 1 | 0) / 2 | 0) | 0;\r\n        b[c >> 2] = d;\r\n        a = 0 - a | 0;\r\n        b[m >> 2] = a;\r\n      }\r\n      f = a - d | 0;\r\n      if ((d | 0) < 0) {\r\n        g = 0 - d | 0;\r\n        b[m >> 2] = f;\r\n        b[n >> 2] = g;\r\n        b[c >> 2] = 0;\r\n        a = f;\r\n        d = 0;\r\n      } else { g = 0; }\r\n      if ((a | 0) < 0) {\r\n        d = d - a | 0;\r\n        b[c >> 2] = d;\r\n        g = g - a | 0;\r\n        b[n >> 2] = g;\r\n        b[m >> 2] = 0;\r\n        a = 0;\r\n      }\r\n      h = d - g | 0;\r\n      f = a - g | 0;\r\n      if ((g | 0) < 0) {\r\n        b[c >> 2] = h;\r\n        b[m >> 2] = f;\r\n        b[n >> 2] = 0;\r\n        a = f;\r\n        d = h;\r\n        g = 0;\r\n      }\r\n      f = (a | 0) < (d | 0) ? a : d;\r\n      f = (g | 0) < (f | 0) ? g : f;\r\n      if ((f | 0) <= 0) { return; }\r\n      b[c >> 2] = d - f;\r\n      b[m >> 2] = a - f;\r\n      b[n >> 2] = g - f;\r\n      return;\r\n    }\r\n    function Ma(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      c = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      d = b[h >> 2] | 0;\r\n      if ((c | 0) < 0) {\r\n        d = d - c | 0;\r\n        b[h >> 2] = d;\r\n        g = a + 8 | 0;\r\n        b[g >> 2] = (b[g >> 2] | 0) - c;\r\n        b[a >> 2] = 0;\r\n        c = 0;\r\n      }\r\n      if ((d | 0) < 0) {\r\n        c = c - d | 0;\r\n        b[a >> 2] = c;\r\n        g = a + 8 | 0;\r\n        f = (b[g >> 2] | 0) - d | 0;\r\n        b[g >> 2] = f;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      } else {\r\n        f = a + 8 | 0;\r\n        g = f;\r\n        f = b[f >> 2] | 0;\r\n      }\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[a >> 2] = c;\r\n        d = d - f | 0;\r\n        b[h >> 2] = d;\r\n        b[g >> 2] = 0;\r\n        f = 0;\r\n      }\r\n      e = (d | 0) < (c | 0) ? d : c;\r\n      e = (f | 0) < (e | 0) ? f : e;\r\n      if ((e | 0) <= 0) { return; }\r\n      b[a >> 2] = c - e;\r\n      b[h >> 2] = d - e;\r\n      b[g >> 2] = f - e;\r\n      return;\r\n    }\r\n    function Na(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0.0,\r\n        f = 0;\r\n      f = b[a + 8 >> 2] | 0;\r\n      d = +((b[a + 4 >> 2] | 0) - f | 0);\r\n      e[c >> 3] = +((b[a >> 2] | 0) - f | 0) - d * .5;\r\n      e[c + 8 >> 3] = d * .8660254037844386;\r\n      return;\r\n    }\r\n    function Oa(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      b[d >> 2] = (b[c >> 2] | 0) + (b[a >> 2] | 0);\r\n      b[d + 4 >> 2] = (b[c + 4 >> 2] | 0) + (b[a + 4 >> 2] | 0);\r\n      b[d + 8 >> 2] = (b[c + 8 >> 2] | 0) + (b[a + 8 >> 2] | 0);\r\n      return;\r\n    }\r\n    function Pa(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      b[d >> 2] = (b[a >> 2] | 0) - (b[c >> 2] | 0);\r\n      b[d + 4 >> 2] = (b[a + 4 >> 2] | 0) - (b[c + 4 >> 2] | 0);\r\n      b[d + 8 >> 2] = (b[a + 8 >> 2] | 0) - (b[c + 8 >> 2] | 0);\r\n      return;\r\n    }\r\n    function Qa(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0;\r\n      d = B(b[a >> 2] | 0, c) | 0;\r\n      b[a >> 2] = d;\r\n      d = a + 4 | 0;\r\n      e = B(b[d >> 2] | 0, c) | 0;\r\n      b[d >> 2] = e;\r\n      a = a + 8 | 0;\r\n      c = B(b[a >> 2] | 0, c) | 0;\r\n      b[a >> 2] = c;\r\n      return;\r\n    }\r\n    function Ra(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = b[a >> 2] | 0;\r\n      i = (h | 0) < 0;\r\n      e = (b[a + 4 >> 2] | 0) - (i ? h : 0) | 0;\r\n      g = (e | 0) < 0;\r\n      f = (g ? 0 - e | 0 : 0) + ((b[a + 8 >> 2] | 0) - (i ? h : 0)) | 0;\r\n      d = (f | 0) < 0;\r\n      a = d ? 0 : f;\r\n      c = (g ? 0 : e) - (d ? f : 0) | 0;\r\n      f = (i ? 0 : h) - (g ? e : 0) - (d ? f : 0) | 0;\r\n      d = (c | 0) < (f | 0) ? c : f;\r\n      d = (a | 0) < (d | 0) ? a : d;\r\n      e = (d | 0) > 0;\r\n      a = a - (e ? d : 0) | 0;\r\n      c = c - (e ? d : 0) | 0;\r\n      a: do { switch (f - (e ? d : 0) | 0) {\r\n        case 0:\r\n          switch (c | 0) {\r\n            case 0:\r\n              {\r\n                i = (a | 0) == 0 ? 0 : (a | 0) == 1 ? 1 : 7;\r\n                return i | 0;\r\n              }\r\n            case 1:\r\n              {\r\n                i = (a | 0) == 0 ? 2 : (a | 0) == 1 ? 3 : 7;\r\n                return i | 0;\r\n              }\r\n            default:\r\n              break a;\r\n          }\r\n        case 1:\r\n          switch (c | 0) {\r\n            case 0:\r\n              {\r\n                i = (a | 0) == 0 ? 4 : (a | 0) == 1 ? 5 : 7;\r\n                return i | 0;\r\n              }\r\n            case 1:\r\n              {\r\n                if (!a) { a = 6; }else { break a; }\r\n                return a | 0;\r\n              }\r\n            default:\r\n              break a;\r\n          }\r\n        default:\r\n\r\n      } } while (0);\r\n      i = 7;\r\n      return i | 0;\r\n    }\r\n    function Sa(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      j = a + 8 | 0;\r\n      h = b[j >> 2] | 0;\r\n      i = (b[a >> 2] | 0) - h | 0;\r\n      k = a + 4 | 0;\r\n      h = (b[k >> 2] | 0) - h | 0;\r\n      if (i >>> 0 > 715827881 | h >>> 0 > 715827881) {\r\n        e = (i | 0) > 0;\r\n        f = 2147483647 - i | 0;\r\n        g = -2147483648 - i | 0;\r\n        if (e ? (f | 0) < (i | 0) : (g | 0) > (i | 0)) {\r\n          k = 1;\r\n          return k | 0;\r\n        }\r\n        d = i << 1;\r\n        if (e ? (2147483647 - d | 0) < (i | 0) : (-2147483648 - d | 0) > (i | 0)) {\r\n          k = 1;\r\n          return k | 0;\r\n        }\r\n        if ((h | 0) > 0 ? (2147483647 - h | 0) < (h | 0) : (-2147483648 - h | 0) > (h | 0)) {\r\n          k = 1;\r\n          return k | 0;\r\n        }\r\n        c = i * 3 | 0;\r\n        d = h << 1;\r\n        if ((e ? (f | 0) < (d | 0) : (g | 0) > (d | 0)) ? 1 : (i | 0) > -1 ? (c | -2147483648 | 0) >= (h | 0) : (c ^ -2147483648 | 0) < (h | 0)) {\r\n          k = 1;\r\n          return k | 0;\r\n        }\r\n      } else {\r\n        d = h << 1;\r\n        c = i * 3 | 0;\r\n      }\r\n      e = Cd(+(c - h | 0) * .14285714285714285) | 0;\r\n      b[a >> 2] = e;\r\n      f = Cd(+(d + i | 0) * .14285714285714285) | 0;\r\n      b[k >> 2] = f;\r\n      b[j >> 2] = 0;\r\n      d = (f | 0) < (e | 0);\r\n      c = d ? e : f;\r\n      d = d ? f : e;\r\n      if ((d | 0) < 0) {\r\n        if ((d | 0) == -2147483648 ? 1 : (c | 0) > 0 ? (2147483647 - c | 0) < (d | 0) : (-2147483648 - c | 0) > (d | 0)) { I(27795, 26892, 354, 26903); }\r\n        if ((c | 0) > -1 ? (c | -2147483648 | 0) >= (d | 0) : (c ^ -2147483648 | 0) < (d | 0)) { I(27795, 26892, 354, 26903); }\r\n      }\r\n      c = f - e | 0;\r\n      if ((e | 0) < 0) {\r\n        d = 0 - e | 0;\r\n        b[k >> 2] = c;\r\n        b[j >> 2] = d;\r\n        b[a >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        c = f;\r\n        d = 0;\r\n      }\r\n      if ((c | 0) < 0) {\r\n        e = e - c | 0;\r\n        b[a >> 2] = e;\r\n        d = d - c | 0;\r\n        b[j >> 2] = d;\r\n        b[k >> 2] = 0;\r\n        c = 0;\r\n      }\r\n      g = e - d | 0;\r\n      f = c - d | 0;\r\n      if ((d | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[k >> 2] = f;\r\n        b[j >> 2] = 0;\r\n        c = f;\r\n        f = g;\r\n        d = 0;\r\n      } else { f = e; }\r\n      e = (c | 0) < (f | 0) ? c : f;\r\n      e = (d | 0) < (e | 0) ? d : e;\r\n      if ((e | 0) <= 0) {\r\n        k = 0;\r\n        return k | 0;\r\n      }\r\n      b[a >> 2] = f - e;\r\n      b[k >> 2] = c - e;\r\n      b[j >> 2] = d - e;\r\n      k = 0;\r\n      return k | 0;\r\n    }\r\n    function Ta(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      h = a + 8 | 0;\r\n      f = b[h >> 2] | 0;\r\n      g = (b[a >> 2] | 0) - f | 0;\r\n      i = a + 4 | 0;\r\n      f = (b[i >> 2] | 0) - f | 0;\r\n      if (g >>> 0 > 715827881 | f >>> 0 > 715827881) {\r\n        d = (g | 0) > 0;\r\n        if (d ? (2147483647 - g | 0) < (g | 0) : (-2147483648 - g | 0) > (g | 0)) {\r\n          i = 1;\r\n          return i | 0;\r\n        }\r\n        c = g << 1;\r\n        e = (f | 0) > 0;\r\n        if (e ? (2147483647 - f | 0) < (f | 0) : (-2147483648 - f | 0) > (f | 0)) {\r\n          i = 1;\r\n          return i | 0;\r\n        }\r\n        j = f << 1;\r\n        if (e ? (2147483647 - j | 0) < (f | 0) : (-2147483648 - j | 0) > (f | 0)) {\r\n          j = 1;\r\n          return j | 0;\r\n        }\r\n        if (d ? (2147483647 - c | 0) < (f | 0) : (-2147483648 - c | 0) > (f | 0)) {\r\n          j = 1;\r\n          return j | 0;\r\n        }\r\n        d = f * 3 | 0;\r\n        if ((f | 0) > -1 ? (d | -2147483648 | 0) >= (g | 0) : (d ^ -2147483648 | 0) < (g | 0)) {\r\n          j = 1;\r\n          return j | 0;\r\n        }\r\n      } else {\r\n        d = f * 3 | 0;\r\n        c = g << 1;\r\n      }\r\n      e = Cd(+(c + f | 0) * .14285714285714285) | 0;\r\n      b[a >> 2] = e;\r\n      f = Cd(+(d - g | 0) * .14285714285714285) | 0;\r\n      b[i >> 2] = f;\r\n      b[h >> 2] = 0;\r\n      d = (f | 0) < (e | 0);\r\n      c = d ? e : f;\r\n      d = d ? f : e;\r\n      if ((d | 0) < 0) {\r\n        if ((d | 0) == -2147483648 ? 1 : (c | 0) > 0 ? (2147483647 - c | 0) < (d | 0) : (-2147483648 - c | 0) > (d | 0)) { I(27795, 26892, 402, 26917); }\r\n        if ((c | 0) > -1 ? (c | -2147483648 | 0) >= (d | 0) : (c ^ -2147483648 | 0) < (d | 0)) { I(27795, 26892, 402, 26917); }\r\n      }\r\n      c = f - e | 0;\r\n      if ((e | 0) < 0) {\r\n        d = 0 - e | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = d;\r\n        b[a >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        c = f;\r\n        d = 0;\r\n      }\r\n      if ((c | 0) < 0) {\r\n        e = e - c | 0;\r\n        b[a >> 2] = e;\r\n        d = d - c | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = 0;\r\n        c = 0;\r\n      }\r\n      g = e - d | 0;\r\n      f = c - d | 0;\r\n      if ((d | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[i >> 2] = f;\r\n        b[h >> 2] = 0;\r\n        c = f;\r\n        f = g;\r\n        d = 0;\r\n      } else { f = e; }\r\n      e = (c | 0) < (f | 0) ? c : f;\r\n      e = (d | 0) < (e | 0) ? d : e;\r\n      if ((e | 0) <= 0) {\r\n        j = 0;\r\n        return j | 0;\r\n      }\r\n      b[a >> 2] = f - e;\r\n      b[i >> 2] = c - e;\r\n      b[h >> 2] = d - e;\r\n      j = 0;\r\n      return j | 0;\r\n    }\r\n    function Ua(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = a + 8 | 0;\r\n      d = b[h >> 2] | 0;\r\n      c = (b[a >> 2] | 0) - d | 0;\r\n      i = a + 4 | 0;\r\n      d = (b[i >> 2] | 0) - d | 0;\r\n      e = Cd(+((c * 3 | 0) - d | 0) * .14285714285714285) | 0;\r\n      b[a >> 2] = e;\r\n      c = Cd(+((d << 1) + c | 0) * .14285714285714285) | 0;\r\n      b[i >> 2] = c;\r\n      b[h >> 2] = 0;\r\n      d = c - e | 0;\r\n      if ((e | 0) < 0) {\r\n        g = 0 - e | 0;\r\n        b[i >> 2] = d;\r\n        b[h >> 2] = g;\r\n        b[a >> 2] = 0;\r\n        c = d;\r\n        e = 0;\r\n        d = g;\r\n      } else { d = 0; }\r\n      if ((c | 0) < 0) {\r\n        e = e - c | 0;\r\n        b[a >> 2] = e;\r\n        d = d - c | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = 0;\r\n        c = 0;\r\n      }\r\n      g = e - d | 0;\r\n      f = c - d | 0;\r\n      if ((d | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[i >> 2] = f;\r\n        b[h >> 2] = 0;\r\n        c = f;\r\n        f = g;\r\n        d = 0;\r\n      } else { f = e; }\r\n      e = (c | 0) < (f | 0) ? c : f;\r\n      e = (d | 0) < (e | 0) ? d : e;\r\n      if ((e | 0) <= 0) { return; }\r\n      b[a >> 2] = f - e;\r\n      b[i >> 2] = c - e;\r\n      b[h >> 2] = d - e;\r\n      return;\r\n    }\r\n    function Va(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = a + 8 | 0;\r\n      d = b[h >> 2] | 0;\r\n      c = (b[a >> 2] | 0) - d | 0;\r\n      i = a + 4 | 0;\r\n      d = (b[i >> 2] | 0) - d | 0;\r\n      e = Cd(+((c << 1) + d | 0) * .14285714285714285) | 0;\r\n      b[a >> 2] = e;\r\n      c = Cd(+((d * 3 | 0) - c | 0) * .14285714285714285) | 0;\r\n      b[i >> 2] = c;\r\n      b[h >> 2] = 0;\r\n      d = c - e | 0;\r\n      if ((e | 0) < 0) {\r\n        g = 0 - e | 0;\r\n        b[i >> 2] = d;\r\n        b[h >> 2] = g;\r\n        b[a >> 2] = 0;\r\n        c = d;\r\n        e = 0;\r\n        d = g;\r\n      } else { d = 0; }\r\n      if ((c | 0) < 0) {\r\n        e = e - c | 0;\r\n        b[a >> 2] = e;\r\n        d = d - c | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = 0;\r\n        c = 0;\r\n      }\r\n      g = e - d | 0;\r\n      f = c - d | 0;\r\n      if ((d | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[i >> 2] = f;\r\n        b[h >> 2] = 0;\r\n        c = f;\r\n        f = g;\r\n        d = 0;\r\n      } else { f = e; }\r\n      e = (c | 0) < (f | 0) ? c : f;\r\n      e = (d | 0) < (e | 0) ? d : e;\r\n      if ((e | 0) <= 0) { return; }\r\n      b[a >> 2] = f - e;\r\n      b[i >> 2] = c - e;\r\n      b[h >> 2] = d - e;\r\n      return;\r\n    }\r\n    function Wa(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      c = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      d = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      e = b[i >> 2] | 0;\r\n      f = d + (c * 3 | 0) | 0;\r\n      b[a >> 2] = f;\r\n      d = e + (d * 3 | 0) | 0;\r\n      b[h >> 2] = d;\r\n      c = (e * 3 | 0) + c | 0;\r\n      b[i >> 2] = c;\r\n      e = d - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = e;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        d = e;\r\n        e = 0;\r\n      } else { e = f; }\r\n      if ((d | 0) < 0) {\r\n        e = e - d | 0;\r\n        b[a >> 2] = e;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = e - c | 0;\r\n      f = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = f;\r\n        b[i >> 2] = 0;\r\n        e = g;\r\n        c = 0;\r\n      } else { f = d; }\r\n      d = (f | 0) < (e | 0) ? f : e;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = e - d;\r\n      b[h >> 2] = f - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function Xa(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      f = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      c = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      d = b[i >> 2] | 0;\r\n      e = (c * 3 | 0) + f | 0;\r\n      f = d + (f * 3 | 0) | 0;\r\n      b[a >> 2] = f;\r\n      b[h >> 2] = e;\r\n      c = (d * 3 | 0) + c | 0;\r\n      b[i >> 2] = c;\r\n      d = e - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        f = 0;\r\n      } else { d = e; }\r\n      if ((d | 0) < 0) {\r\n        f = f - d | 0;\r\n        b[a >> 2] = f;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = f - c | 0;\r\n      e = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = e;\r\n        b[i >> 2] = 0;\r\n        f = g;\r\n        c = 0;\r\n      } else { e = d; }\r\n      d = (e | 0) < (f | 0) ? e : f;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = f - d;\r\n      b[h >> 2] = e - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function Ya(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      if ((c + -1 | 0) >>> 0 >= 6) { return; }\r\n      f = (b[15440 + (c * 12 | 0) >> 2] | 0) + (b[a >> 2] | 0) | 0;\r\n      b[a >> 2] = f;\r\n      i = a + 4 | 0;\r\n      e = (b[15440 + (c * 12 | 0) + 4 >> 2] | 0) + (b[i >> 2] | 0) | 0;\r\n      b[i >> 2] = e;\r\n      h = a + 8 | 0;\r\n      c = (b[15440 + (c * 12 | 0) + 8 >> 2] | 0) + (b[h >> 2] | 0) | 0;\r\n      b[h >> 2] = c;\r\n      d = e - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[i >> 2] = d;\r\n        b[h >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        d = e;\r\n        e = f;\r\n      }\r\n      if ((d | 0) < 0) {\r\n        e = e - d | 0;\r\n        b[a >> 2] = e;\r\n        c = c - d | 0;\r\n        b[h >> 2] = c;\r\n        b[i >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = e - c | 0;\r\n      f = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[i >> 2] = f;\r\n        b[h >> 2] = 0;\r\n        e = g;\r\n        c = 0;\r\n      } else { f = d; }\r\n      d = (f | 0) < (e | 0) ? f : e;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = e - d;\r\n      b[i >> 2] = f - d;\r\n      b[h >> 2] = c - d;\r\n      return;\r\n    }\r\n    function Za(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      f = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      c = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      d = b[i >> 2] | 0;\r\n      e = c + f | 0;\r\n      f = d + f | 0;\r\n      b[a >> 2] = f;\r\n      b[h >> 2] = e;\r\n      c = d + c | 0;\r\n      b[i >> 2] = c;\r\n      d = e - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        d = e;\r\n        e = f;\r\n      }\r\n      if ((d | 0) < 0) {\r\n        e = e - d | 0;\r\n        b[a >> 2] = e;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = e - c | 0;\r\n      f = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = f;\r\n        b[i >> 2] = 0;\r\n        e = g;\r\n        c = 0;\r\n      } else { f = d; }\r\n      d = (f | 0) < (e | 0) ? f : e;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = e - d;\r\n      b[h >> 2] = f - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function _a(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      c = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      e = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      d = b[i >> 2] | 0;\r\n      f = e + c | 0;\r\n      b[a >> 2] = f;\r\n      e = d + e | 0;\r\n      b[h >> 2] = e;\r\n      c = d + c | 0;\r\n      b[i >> 2] = c;\r\n      d = e - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        d = e;\r\n        e = f;\r\n      }\r\n      if ((d | 0) < 0) {\r\n        e = e - d | 0;\r\n        b[a >> 2] = e;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = e - c | 0;\r\n      f = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = f;\r\n        b[i >> 2] = 0;\r\n        e = g;\r\n        c = 0;\r\n      } else { f = d; }\r\n      d = (f | 0) < (e | 0) ? f : e;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = e - d;\r\n      b[h >> 2] = f - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function $a(a) {\r\n      a = a | 0;\r\n      switch (a | 0) {\r\n        case 1:\r\n          {\r\n            a = 5;\r\n            break;\r\n          }\r\n        case 5:\r\n          {\r\n            a = 4;\r\n            break;\r\n          }\r\n        case 4:\r\n          {\r\n            a = 6;\r\n            break;\r\n          }\r\n        case 6:\r\n          {\r\n            a = 2;\r\n            break;\r\n          }\r\n        case 2:\r\n          {\r\n            a = 3;\r\n            break;\r\n          }\r\n        case 3:\r\n          {\r\n            a = 1;\r\n            break;\r\n          }\r\n        default:\r\n\r\n      }\r\n      return a | 0;\r\n    }\r\n    function ab(a) {\r\n      a = a | 0;\r\n      switch (a | 0) {\r\n        case 1:\r\n          {\r\n            a = 3;\r\n            break;\r\n          }\r\n        case 3:\r\n          {\r\n            a = 2;\r\n            break;\r\n          }\r\n        case 2:\r\n          {\r\n            a = 6;\r\n            break;\r\n          }\r\n        case 6:\r\n          {\r\n            a = 4;\r\n            break;\r\n          }\r\n        case 4:\r\n          {\r\n            a = 5;\r\n            break;\r\n          }\r\n        case 5:\r\n          {\r\n            a = 1;\r\n            break;\r\n          }\r\n        default:\r\n\r\n      }\r\n      return a | 0;\r\n    }\r\n    function bb(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      c = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      d = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      e = b[i >> 2] | 0;\r\n      f = d + (c << 1) | 0;\r\n      b[a >> 2] = f;\r\n      d = e + (d << 1) | 0;\r\n      b[h >> 2] = d;\r\n      c = (e << 1) + c | 0;\r\n      b[i >> 2] = c;\r\n      e = d - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = e;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        d = e;\r\n        e = 0;\r\n      } else { e = f; }\r\n      if ((d | 0) < 0) {\r\n        e = e - d | 0;\r\n        b[a >> 2] = e;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = e - c | 0;\r\n      f = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = f;\r\n        b[i >> 2] = 0;\r\n        e = g;\r\n        c = 0;\r\n      } else { f = d; }\r\n      d = (f | 0) < (e | 0) ? f : e;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = e - d;\r\n      b[h >> 2] = f - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function cb(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      f = b[a >> 2] | 0;\r\n      h = a + 4 | 0;\r\n      c = b[h >> 2] | 0;\r\n      i = a + 8 | 0;\r\n      d = b[i >> 2] | 0;\r\n      e = (c << 1) + f | 0;\r\n      f = d + (f << 1) | 0;\r\n      b[a >> 2] = f;\r\n      b[h >> 2] = e;\r\n      c = (d << 1) + c | 0;\r\n      b[i >> 2] = c;\r\n      d = e - f | 0;\r\n      if ((f | 0) < 0) {\r\n        c = c - f | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = c;\r\n        b[a >> 2] = 0;\r\n        f = 0;\r\n      } else { d = e; }\r\n      if ((d | 0) < 0) {\r\n        f = f - d | 0;\r\n        b[a >> 2] = f;\r\n        c = c - d | 0;\r\n        b[i >> 2] = c;\r\n        b[h >> 2] = 0;\r\n        d = 0;\r\n      }\r\n      g = f - c | 0;\r\n      e = d - c | 0;\r\n      if ((c | 0) < 0) {\r\n        b[a >> 2] = g;\r\n        b[h >> 2] = e;\r\n        b[i >> 2] = 0;\r\n        f = g;\r\n        c = 0;\r\n      } else { e = d; }\r\n      d = (e | 0) < (f | 0) ? e : f;\r\n      d = (c | 0) < (d | 0) ? c : d;\r\n      if ((d | 0) <= 0) { return; }\r\n      b[a >> 2] = f - d;\r\n      b[h >> 2] = e - d;\r\n      b[i >> 2] = c - d;\r\n      return;\r\n    }\r\n    function db(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = (b[a >> 2] | 0) - (b[c >> 2] | 0) | 0;\r\n      i = (h | 0) < 0;\r\n      e = (b[a + 4 >> 2] | 0) - (b[c + 4 >> 2] | 0) - (i ? h : 0) | 0;\r\n      g = (e | 0) < 0;\r\n      f = (i ? 0 - h | 0 : 0) + (b[a + 8 >> 2] | 0) - (b[c + 8 >> 2] | 0) + (g ? 0 - e | 0 : 0) | 0;\r\n      a = (f | 0) < 0;\r\n      c = a ? 0 : f;\r\n      d = (g ? 0 : e) - (a ? f : 0) | 0;\r\n      f = (i ? 0 : h) - (g ? e : 0) - (a ? f : 0) | 0;\r\n      a = (d | 0) < (f | 0) ? d : f;\r\n      a = (c | 0) < (a | 0) ? c : a;\r\n      e = (a | 0) > 0;\r\n      c = c - (e ? a : 0) | 0;\r\n      d = d - (e ? a : 0) | 0;\r\n      a = f - (e ? a : 0) | 0;\r\n      a = (a | 0) > -1 ? a : 0 - a | 0;\r\n      d = (d | 0) > -1 ? d : 0 - d | 0;\r\n      c = (c | 0) > -1 ? c : 0 - c | 0;\r\n      c = (d | 0) > (c | 0) ? d : c;\r\n      return ((a | 0) > (c | 0) ? a : c) | 0;\r\n    }\r\n    function eb(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0;\r\n      d = b[a + 8 >> 2] | 0;\r\n      b[c >> 2] = (b[a >> 2] | 0) - d;\r\n      b[c + 4 >> 2] = (b[a + 4 >> 2] | 0) - d;\r\n      return;\r\n    }\r\n    function fb(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      e = b[a >> 2] | 0;\r\n      b[c >> 2] = e;\r\n      f = b[a + 4 >> 2] | 0;\r\n      h = c + 4 | 0;\r\n      b[h >> 2] = f;\r\n      i = c + 8 | 0;\r\n      b[i >> 2] = 0;\r\n      d = (f | 0) < (e | 0);\r\n      a = d ? e : f;\r\n      d = d ? f : e;\r\n      if ((d | 0) < 0) {\r\n        if ((d | 0) == -2147483648 ? 1 : (a | 0) > 0 ? (2147483647 - a | 0) < (d | 0) : (-2147483648 - a | 0) > (d | 0)) {\r\n          c = 1;\r\n          return c | 0;\r\n        }\r\n        if ((a | 0) > -1 ? (a | -2147483648 | 0) >= (d | 0) : (a ^ -2147483648 | 0) < (d | 0)) {\r\n          c = 1;\r\n          return c | 0;\r\n        }\r\n      }\r\n      a = f - e | 0;\r\n      if ((e | 0) < 0) {\r\n        d = 0 - e | 0;\r\n        b[h >> 2] = a;\r\n        b[i >> 2] = d;\r\n        b[c >> 2] = 0;\r\n        e = 0;\r\n      } else {\r\n        a = f;\r\n        d = 0;\r\n      }\r\n      if ((a | 0) < 0) {\r\n        e = e - a | 0;\r\n        b[c >> 2] = e;\r\n        d = d - a | 0;\r\n        b[i >> 2] = d;\r\n        b[h >> 2] = 0;\r\n        a = 0;\r\n      }\r\n      g = e - d | 0;\r\n      f = a - d | 0;\r\n      if ((d | 0) < 0) {\r\n        b[c >> 2] = g;\r\n        b[h >> 2] = f;\r\n        b[i >> 2] = 0;\r\n        a = f;\r\n        f = g;\r\n        d = 0;\r\n      } else { f = e; }\r\n      e = (a | 0) < (f | 0) ? a : f;\r\n      e = (d | 0) < (e | 0) ? d : e;\r\n      if ((e | 0) <= 0) {\r\n        c = 0;\r\n        return c | 0;\r\n      }\r\n      b[c >> 2] = f - e;\r\n      b[h >> 2] = a - e;\r\n      b[i >> 2] = d - e;\r\n      c = 0;\r\n      return c | 0;\r\n    }\r\n    function gb(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0;\r\n      c = a + 8 | 0;\r\n      f = b[c >> 2] | 0;\r\n      d = f - (b[a >> 2] | 0) | 0;\r\n      b[a >> 2] = d;\r\n      e = a + 4 | 0;\r\n      a = (b[e >> 2] | 0) - f | 0;\r\n      b[e >> 2] = a;\r\n      b[c >> 2] = 0 - (a + d);\r\n      return;\r\n    }\r\n    function hb(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      d = b[a >> 2] | 0;\r\n      c = 0 - d | 0;\r\n      b[a >> 2] = c;\r\n      h = a + 8 | 0;\r\n      b[h >> 2] = 0;\r\n      i = a + 4 | 0;\r\n      e = b[i >> 2] | 0;\r\n      f = e + d | 0;\r\n      if ((d | 0) > 0) {\r\n        b[i >> 2] = f;\r\n        b[h >> 2] = d;\r\n        b[a >> 2] = 0;\r\n        c = 0;\r\n        e = f;\r\n      } else { d = 0; }\r\n      if ((e | 0) < 0) {\r\n        g = c - e | 0;\r\n        b[a >> 2] = g;\r\n        d = d - e | 0;\r\n        b[h >> 2] = d;\r\n        b[i >> 2] = 0;\r\n        f = g - d | 0;\r\n        c = 0 - d | 0;\r\n        if ((d | 0) < 0) {\r\n          b[a >> 2] = f;\r\n          b[i >> 2] = c;\r\n          b[h >> 2] = 0;\r\n          e = c;\r\n          d = 0;\r\n        } else {\r\n          e = 0;\r\n          f = g;\r\n        }\r\n      } else { f = c; }\r\n      c = (e | 0) < (f | 0) ? e : f;\r\n      c = (d | 0) < (c | 0) ? d : c;\r\n      if ((c | 0) <= 0) { return; }\r\n      b[a >> 2] = f - c;\r\n      b[i >> 2] = e - c;\r\n      b[h >> 2] = d - c;\r\n      return;\r\n    }\r\n    function ib(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0;\r\n      m = T;\r\n      T = T + 64 | 0;\r\n      l = m;\r\n      i = m + 56 | 0;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 134217728 & (0 == 0 & (e & 2013265920 | 0) == 134217728))) {\r\n        f = 5;\r\n        T = m;\r\n        return f | 0;\r\n      }\r\n      if ((a | 0) == (d | 0) & (c | 0) == (e | 0)) {\r\n        b[f >> 2] = 0;\r\n        f = 0;\r\n        T = m;\r\n        return f | 0;\r\n      }\r\n      h = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      h = h & 15;\r\n      k = Qd(d | 0, e | 0, 52) | 0;\r\n      H() | 0;\r\n      if ((h | 0) != (k & 15 | 0)) {\r\n        f = 12;\r\n        T = m;\r\n        return f | 0;\r\n      }\r\n      g = h + -1 | 0;\r\n      if (h >>> 0 > 1) {\r\n        Fb(a, c, g, l) | 0;\r\n        Fb(d, e, g, i) | 0;\r\n        k = l;\r\n        j = b[k >> 2] | 0;\r\n        k = b[k + 4 >> 2] | 0;\r\n        a: do { if ((j | 0) == (b[i >> 2] | 0) ? (k | 0) == (b[i + 4 >> 2] | 0) : 0) {\r\n          h = (h ^ 15) * 3 | 0;\r\n          g = Qd(a | 0, c | 0, h | 0) | 0;\r\n          H() | 0;\r\n          g = g & 7;\r\n          h = Qd(d | 0, e | 0, h | 0) | 0;\r\n          H() | 0;\r\n          h = h & 7;\r\n          do { if (!((g | 0) == 0 | (h | 0) == 0)) {\r\n            if ((g | 0) == 7) { g = 5; }else {\r\n              if ((g | 0) == 1 | (h | 0) == 1 ? Hb(j, k) | 0 : 0) {\r\n                g = 5;\r\n                break;\r\n              }\r\n              if ((b[15536 + (g << 2) >> 2] | 0) != (h | 0) ? (b[15568 + (g << 2) >> 2] | 0) != (h | 0) : 0) { break a; }\r\n              b[f >> 2] = 1;\r\n              g = 0;\r\n            }\r\n          } else {\r\n            b[f >> 2] = 1;\r\n            g = 0;\r\n          } } while (0);\r\n          f = g;\r\n          T = m;\r\n          return f | 0;\r\n        } } while (0);\r\n      }\r\n      g = l;\r\n      h = g + 56 | 0;\r\n      do {\r\n        b[g >> 2] = 0;\r\n        g = g + 4 | 0;\r\n      } while ((g | 0) < (h | 0));\r\n      aa(a, c, 1, l) | 0;\r\n      c = l;\r\n      if (((((!((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0) ? (c = l + 8 | 0, !((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0)) : 0) ? (c = l + 16 | 0, !((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0)) : 0) ? (c = l + 24 | 0, !((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0)) : 0) ? (c = l + 32 | 0, !((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0)) : 0) ? (c = l + 40 | 0, !((b[c >> 2] | 0) == (d | 0) ? (b[c + 4 >> 2] | 0) == (e | 0) : 0)) : 0) {\r\n        g = l + 48 | 0;\r\n        g = ((b[g >> 2] | 0) == (d | 0) ? (b[g + 4 >> 2] | 0) == (e | 0) : 0) & 1;\r\n      } else { g = 1; }\r\n      b[f >> 2] = g;\r\n      f = 0;\r\n      T = m;\r\n      return f | 0;\r\n    }\r\n    function jb(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      d = ia(a, c, d, e) | 0;\r\n      if ((d | 0) == 7) {\r\n        f = 11;\r\n        return f | 0;\r\n      }\r\n      e = Rd(d | 0, 0, 56) | 0;\r\n      c = c & -2130706433 | (H() | 0) | 268435456;\r\n      b[f >> 2] = a | e;\r\n      b[f + 4 >> 2] = c;\r\n      f = 0;\r\n      return f | 0;\r\n    }\r\n    function kb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 268435456)) {\r\n        d = 6;\r\n        return d | 0;\r\n      }\r\n      b[d >> 2] = a;\r\n      b[d + 4 >> 2] = c & -2130706433 | 134217728;\r\n      d = 0;\r\n      return d | 0;\r\n    }\r\n    function lb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      e = f;\r\n      b[e >> 2] = 0;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 268435456)) {\r\n        e = 6;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      g = Qd(a | 0, c | 0, 56) | 0;\r\n      H() | 0;\r\n      e = ea(a, c & -2130706433 | 134217728, g & 7, e, d) | 0;\r\n      T = f;\r\n      return e | 0;\r\n    }\r\n    function mb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0;\r\n      c = Qd(a | 0, b | 0, 56) | 0;\r\n      H() | 0;\r\n      switch (c & 7) {\r\n        case 0:\r\n        case 7:\r\n          {\r\n            c = 0;\r\n            return c | 0;\r\n          }\r\n        default:\r\n\r\n      }\r\n      c = b & -2130706433 | 134217728;\r\n      if (!(0 == 0 & (b & 2013265920 | 0) == 268435456)) {\r\n        c = 0;\r\n        return c | 0;\r\n      }\r\n      if (0 == 0 & (b & 117440512 | 0) == 16777216 & (Hb(a, c) | 0) != 0) {\r\n        c = 0;\r\n        return c | 0;\r\n      }\r\n      c = Db(a, c) | 0;\r\n      return c | 0;\r\n    }\r\n    function nb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      e = f;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 268435456)) {\r\n        e = 6;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      g = c & -2130706433 | 134217728;\r\n      h = d;\r\n      b[h >> 2] = a;\r\n      b[h + 4 >> 2] = g;\r\n      b[e >> 2] = 0;\r\n      c = Qd(a | 0, c | 0, 56) | 0;\r\n      H() | 0;\r\n      e = ea(a, g, c & 7, e, d + 8 | 0) | 0;\r\n      T = f;\r\n      return e | 0;\r\n    }\r\n    function ob(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0;\r\n      f = (Hb(a, c) | 0) == 0;\r\n      c = c & -2130706433;\r\n      e = d;\r\n      b[e >> 2] = f ? a : 0;\r\n      b[e + 4 >> 2] = f ? c | 285212672 : 0;\r\n      e = d + 8 | 0;\r\n      b[e >> 2] = a;\r\n      b[e + 4 >> 2] = c | 301989888;\r\n      e = d + 16 | 0;\r\n      b[e >> 2] = a;\r\n      b[e + 4 >> 2] = c | 318767104;\r\n      e = d + 24 | 0;\r\n      b[e >> 2] = a;\r\n      b[e + 4 >> 2] = c | 335544320;\r\n      e = d + 32 | 0;\r\n      b[e >> 2] = a;\r\n      b[e + 4 >> 2] = c | 352321536;\r\n      d = d + 40 | 0;\r\n      b[d >> 2] = a;\r\n      b[d + 4 >> 2] = c | 369098752;\r\n      return 0;\r\n    }\r\n    function pb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      h = T;\r\n      T = T + 16 | 0;\r\n      f = h;\r\n      g = c & -2130706433 | 134217728;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 268435456)) {\r\n        g = 6;\r\n        T = h;\r\n        return g | 0;\r\n      }\r\n      e = Qd(a | 0, c | 0, 56) | 0;\r\n      H() | 0;\r\n      e = od(a, g, e & 7) | 0;\r\n      if ((e | 0) == -1) {\r\n        b[d >> 2] = 0;\r\n        g = 6;\r\n        T = h;\r\n        return g | 0;\r\n      }\r\n      if (Yb(a, g, f) | 0) { I(27795, 26932, 282, 26947); }\r\n      c = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      c = c & 15;\r\n      if (!(Hb(a, g) | 0)) { zb(f, c, e, 2, d); }else { vb(f, c, e, 2, d); }\r\n      g = 0;\r\n      T = h;\r\n      return g | 0;\r\n    }\r\n    function qb(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0;\r\n      d = T;\r\n      T = T + 16 | 0;\r\n      e = d;\r\n      rb(a, b, c, e);\r\n      La(e, c + 4 | 0);\r\n      T = d;\r\n      return;\r\n    }\r\n    function rb(a, c, d, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      var g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0,\r\n        k = 0;\r\n      j = T;\r\n      T = T + 16 | 0;\r\n      k = j;\r\n      sb(a, d, k);\r\n      h = +w(+(1.0 - +e[k >> 3] * .5));\r\n      if (h < 1.0e-16) {\r\n        b[f >> 2] = 0;\r\n        b[f + 4 >> 2] = 0;\r\n        b[f + 8 >> 2] = 0;\r\n        b[f + 12 >> 2] = 0;\r\n        T = j;\r\n        return;\r\n      }\r\n      k = b[d >> 2] | 0;\r\n      g = +e[15920 + (k * 24 | 0) >> 3];\r\n      g = +ic(g - +ic(+oc(15600 + (k << 4) | 0, a)));\r\n      if (!(Vb(c) | 0)) { i = g; }else { i = +ic(g + -.3334731722518321); }\r\n      g = +v(+h) * 2.618033988749896;\r\n      if ((c | 0) > 0) {\r\n        a = 0;\r\n        do {\r\n          g = g * 2.6457513110645907;\r\n          a = a + 1 | 0;\r\n        } while ((a | 0) != (c | 0));\r\n      }\r\n      h = +t(+i) * g;\r\n      e[f >> 3] = h;\r\n      i = +u(+i) * g;\r\n      e[f + 8 >> 3] = i;\r\n      T = j;\r\n      return;\r\n    }\r\n    function sb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0,\r\n        h = 0;\r\n      h = T;\r\n      T = T + 32 | 0;\r\n      g = h;\r\n      nd(a, g);\r\n      b[c >> 2] = 0;\r\n      e[d >> 3] = 5.0;\r\n      f = +md(16400, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 0;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16424, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 1;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16448, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 2;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16472, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 3;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16496, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 4;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16520, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 5;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16544, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 6;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16568, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 7;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16592, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 8;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16616, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 9;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16640, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 10;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16664, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 11;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16688, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 12;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16712, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 13;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16736, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 14;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16760, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 15;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16784, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 16;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16808, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 17;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16832, g);\r\n      if (f < +e[d >> 3]) {\r\n        b[c >> 2] = 18;\r\n        e[d >> 3] = f;\r\n      }\r\n      f = +md(16856, g);\r\n      if (!(f < +e[d >> 3])) {\r\n        T = h;\r\n        return;\r\n      }\r\n      b[c >> 2] = 19;\r\n      e[d >> 3] = f;\r\n      T = h;\r\n      return;\r\n    }\r\n    function tb(a, c, d, f, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0;\r\n      h = +jd(a);\r\n      if (h < 1.0e-16) {\r\n        c = 15600 + (c << 4) | 0;\r\n        b[g >> 2] = b[c >> 2];\r\n        b[g + 4 >> 2] = b[c + 4 >> 2];\r\n        b[g + 8 >> 2] = b[c + 8 >> 2];\r\n        b[g + 12 >> 2] = b[c + 12 >> 2];\r\n        return;\r\n      }\r\n      i = +z(+ +e[a + 8 >> 3], + +e[a >> 3]);\r\n      if ((d | 0) > 0) {\r\n        a = 0;\r\n        do {\r\n          h = h * .37796447300922725;\r\n          a = a + 1 | 0;\r\n        } while ((a | 0) != (d | 0));\r\n      }\r\n      j = h * .3333333333333333;\r\n      if (!f) {\r\n        h = +y(+(h * .381966011250105));\r\n        if (Vb(d) | 0) { i = +ic(i + .3334731722518321); }\r\n      } else {\r\n        d = (Vb(d) | 0) == 0;\r\n        h = +y(+((d ? j : j * .37796447300922725) * .381966011250105));\r\n      }\r\n      pc(15600 + (c << 4) | 0, +ic(+e[15920 + (c * 24 | 0) >> 3] - i), h, g);\r\n      return;\r\n    }\r\n    function ub(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0;\r\n      e = T;\r\n      T = T + 16 | 0;\r\n      f = e;\r\n      Na(a + 4 | 0, f);\r\n      tb(f, b[a >> 2] | 0, c, 0, d);\r\n      T = e;\r\n      return;\r\n    }\r\n    function vb(a, c, d, f, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0,\r\n        D = 0,\r\n        E = 0,\r\n        F = 0,\r\n        G = 0,\r\n        H = 0.0,\r\n        J = 0.0;\r\n      G = T;\r\n      T = T + 272 | 0;\r\n      h = G + 256 | 0;\r\n      u = G + 240 | 0;\r\n      D = G;\r\n      E = G + 224 | 0;\r\n      F = G + 208 | 0;\r\n      v = G + 176 | 0;\r\n      w = G + 160 | 0;\r\n      x = G + 192 | 0;\r\n      y = G + 144 | 0;\r\n      z = G + 128 | 0;\r\n      A = G + 112 | 0;\r\n      B = G + 96 | 0;\r\n      C = G + 80 | 0;\r\n      b[h >> 2] = c;\r\n      b[u >> 2] = b[a >> 2];\r\n      b[u + 4 >> 2] = b[a + 4 >> 2];\r\n      b[u + 8 >> 2] = b[a + 8 >> 2];\r\n      b[u + 12 >> 2] = b[a + 12 >> 2];\r\n      wb(u, h, D);\r\n      b[g >> 2] = 0;\r\n      u = f + d + ((f | 0) == 5 & 1) | 0;\r\n      if ((u | 0) <= (d | 0)) {\r\n        T = G;\r\n        return;\r\n      }\r\n      k = b[h >> 2] | 0;\r\n      l = E + 4 | 0;\r\n      m = v + 4 | 0;\r\n      n = d + 5 | 0;\r\n      o = 16880 + (k << 2) | 0;\r\n      p = 16960 + (k << 2) | 0;\r\n      q = z + 8 | 0;\r\n      r = A + 8 | 0;\r\n      s = B + 8 | 0;\r\n      t = F + 4 | 0;\r\n      j = d;\r\n      a: while (1) {\r\n        i = D + (((j | 0) % 5 | 0) << 4) | 0;\r\n        b[F >> 2] = b[i >> 2];\r\n        b[F + 4 >> 2] = b[i + 4 >> 2];\r\n        b[F + 8 >> 2] = b[i + 8 >> 2];\r\n        b[F + 12 >> 2] = b[i + 12 >> 2];\r\n        do {} while ((xb(F, k, 0, 1) | 0) == 2);\r\n        if ((j | 0) > (d | 0) & (Vb(c) | 0) != 0) {\r\n          b[v >> 2] = b[F >> 2];\r\n          b[v + 4 >> 2] = b[F + 4 >> 2];\r\n          b[v + 8 >> 2] = b[F + 8 >> 2];\r\n          b[v + 12 >> 2] = b[F + 12 >> 2];\r\n          Na(l, w);\r\n          f = b[v >> 2] | 0;\r\n          h = b[17040 + (f * 80 | 0) + (b[E >> 2] << 2) >> 2] | 0;\r\n          b[v >> 2] = b[18640 + (f * 80 | 0) + (h * 20 | 0) >> 2];\r\n          i = b[18640 + (f * 80 | 0) + (h * 20 | 0) + 16 >> 2] | 0;\r\n          if ((i | 0) > 0) {\r\n            a = 0;\r\n            do {\r\n              Za(m);\r\n              a = a + 1 | 0;\r\n            } while ((a | 0) < (i | 0));\r\n          }\r\n          i = 18640 + (f * 80 | 0) + (h * 20 | 0) + 4 | 0;\r\n          b[x >> 2] = b[i >> 2];\r\n          b[x + 4 >> 2] = b[i + 4 >> 2];\r\n          b[x + 8 >> 2] = b[i + 8 >> 2];\r\n          Qa(x, (b[o >> 2] | 0) * 3 | 0);\r\n          Oa(m, x, m);\r\n          Ma(m);\r\n          Na(m, y);\r\n          H = +(b[p >> 2] | 0);\r\n          e[z >> 3] = H * 3.0;\r\n          e[q >> 3] = 0.0;\r\n          J = H * -1.5;\r\n          e[A >> 3] = J;\r\n          e[r >> 3] = H * 2.598076211353316;\r\n          e[B >> 3] = J;\r\n          e[s >> 3] = H * -2.598076211353316;\r\n          switch (b[17040 + ((b[v >> 2] | 0) * 80 | 0) + (b[F >> 2] << 2) >> 2] | 0) {\r\n            case 1:\r\n              {\r\n                a = A;\r\n                f = z;\r\n                break;\r\n              }\r\n            case 3:\r\n              {\r\n                a = B;\r\n                f = A;\r\n                break;\r\n              }\r\n            case 2:\r\n              {\r\n                a = z;\r\n                f = B;\r\n                break;\r\n              }\r\n            default:\r\n              {\r\n                a = 12;\r\n                break a;\r\n              }\r\n          }\r\n          kd(w, y, f, a, C);\r\n          tb(C, b[v >> 2] | 0, k, 1, g + 8 + (b[g >> 2] << 4) | 0);\r\n          b[g >> 2] = (b[g >> 2] | 0) + 1;\r\n        }\r\n        if ((j | 0) < (n | 0)) {\r\n          Na(t, v);\r\n          tb(v, b[F >> 2] | 0, k, 1, g + 8 + (b[g >> 2] << 4) | 0);\r\n          b[g >> 2] = (b[g >> 2] | 0) + 1;\r\n        }\r\n        b[E >> 2] = b[F >> 2];\r\n        b[E + 4 >> 2] = b[F + 4 >> 2];\r\n        b[E + 8 >> 2] = b[F + 8 >> 2];\r\n        b[E + 12 >> 2] = b[F + 12 >> 2];\r\n        j = j + 1 | 0;\r\n        if ((j | 0) >= (u | 0)) {\r\n          a = 3;\r\n          break;\r\n        }\r\n      }\r\n      if ((a | 0) == 3) {\r\n        T = G;\r\n        return;\r\n      } else if ((a | 0) == 12) { I(26970, 27017, 572, 27027); }\r\n    }\r\n    function wb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 128 | 0;\r\n      e = j + 64 | 0;\r\n      f = j;\r\n      g = e;\r\n      h = 20240;\r\n      i = g + 60 | 0;\r\n      do {\r\n        b[g >> 2] = b[h >> 2];\r\n        g = g + 4 | 0;\r\n        h = h + 4 | 0;\r\n      } while ((g | 0) < (i | 0));\r\n      g = f;\r\n      h = 20304;\r\n      i = g + 60 | 0;\r\n      do {\r\n        b[g >> 2] = b[h >> 2];\r\n        g = g + 4 | 0;\r\n        h = h + 4 | 0;\r\n      } while ((g | 0) < (i | 0));\r\n      i = (Vb(b[c >> 2] | 0) | 0) == 0;\r\n      e = i ? e : f;\r\n      f = a + 4 | 0;\r\n      bb(f);\r\n      cb(f);\r\n      if (Vb(b[c >> 2] | 0) | 0) {\r\n        Xa(f);\r\n        b[c >> 2] = (b[c >> 2] | 0) + 1;\r\n      }\r\n      b[d >> 2] = b[a >> 2];\r\n      c = d + 4 | 0;\r\n      Oa(f, e, c);\r\n      Ma(c);\r\n      b[d + 16 >> 2] = b[a >> 2];\r\n      c = d + 20 | 0;\r\n      Oa(f, e + 12 | 0, c);\r\n      Ma(c);\r\n      b[d + 32 >> 2] = b[a >> 2];\r\n      c = d + 36 | 0;\r\n      Oa(f, e + 24 | 0, c);\r\n      Ma(c);\r\n      b[d + 48 >> 2] = b[a >> 2];\r\n      c = d + 52 | 0;\r\n      Oa(f, e + 36 | 0, c);\r\n      Ma(c);\r\n      b[d + 64 >> 2] = b[a >> 2];\r\n      d = d + 68 | 0;\r\n      Oa(f, e + 48 | 0, d);\r\n      Ma(d);\r\n      T = j;\r\n      return;\r\n    }\r\n    function xb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0;\r\n      p = T;\r\n      T = T + 32 | 0;\r\n      n = p + 12 | 0;\r\n      i = p;\r\n      o = a + 4 | 0;\r\n      m = b[16960 + (c << 2) >> 2] | 0;\r\n      l = (e | 0) != 0;\r\n      m = l ? m * 3 | 0 : m;\r\n      f = b[o >> 2] | 0;\r\n      k = a + 8 | 0;\r\n      h = b[k >> 2] | 0;\r\n      if (l) {\r\n        g = a + 12 | 0;\r\n        e = b[g >> 2] | 0;\r\n        f = h + f + e | 0;\r\n        if ((f | 0) == (m | 0)) {\r\n          o = 1;\r\n          T = p;\r\n          return o | 0;\r\n        } else { j = g; }\r\n      } else {\r\n        j = a + 12 | 0;\r\n        e = b[j >> 2] | 0;\r\n        f = h + f + e | 0;\r\n      }\r\n      if ((f | 0) <= (m | 0)) {\r\n        o = 0;\r\n        T = p;\r\n        return o | 0;\r\n      }\r\n      do { if ((e | 0) > 0) {\r\n        e = b[a >> 2] | 0;\r\n        if ((h | 0) > 0) {\r\n          g = 18640 + (e * 80 | 0) + 60 | 0;\r\n          e = a;\r\n          break;\r\n        }\r\n        e = 18640 + (e * 80 | 0) + 40 | 0;\r\n        if (!d) {\r\n          g = e;\r\n          e = a;\r\n        } else {\r\n          Ka(n, m, 0, 0);\r\n          Pa(o, n, i);\r\n          _a(i);\r\n          Oa(i, n, o);\r\n          g = e;\r\n          e = a;\r\n        }\r\n      } else {\r\n        g = 18640 + ((b[a >> 2] | 0) * 80 | 0) + 20 | 0;\r\n        e = a;\r\n      } } while (0);\r\n      b[e >> 2] = b[g >> 2];\r\n      f = g + 16 | 0;\r\n      if ((b[f >> 2] | 0) > 0) {\r\n        e = 0;\r\n        do {\r\n          Za(o);\r\n          e = e + 1 | 0;\r\n        } while ((e | 0) < (b[f >> 2] | 0));\r\n      }\r\n      a = g + 4 | 0;\r\n      b[n >> 2] = b[a >> 2];\r\n      b[n + 4 >> 2] = b[a + 4 >> 2];\r\n      b[n + 8 >> 2] = b[a + 8 >> 2];\r\n      c = b[16880 + (c << 2) >> 2] | 0;\r\n      Qa(n, l ? c * 3 | 0 : c);\r\n      Oa(o, n, o);\r\n      Ma(o);\r\n      if (l) { e = ((b[k >> 2] | 0) + (b[o >> 2] | 0) + (b[j >> 2] | 0) | 0) == (m | 0) ? 1 : 2; }else { e = 2; }\r\n      o = e;\r\n      T = p;\r\n      return o | 0;\r\n    }\r\n    function yb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0;\r\n      do { c = xb(a, b, 0, 1) | 0; } while ((c | 0) == 2);\r\n      return c | 0;\r\n    }\r\n    function zb(a, c, d, f, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0.0,\r\n        D = 0.0;\r\n      B = T;\r\n      T = T + 240 | 0;\r\n      h = B + 224 | 0;\r\n      x = B + 208 | 0;\r\n      y = B;\r\n      z = B + 192 | 0;\r\n      A = B + 176 | 0;\r\n      s = B + 160 | 0;\r\n      t = B + 144 | 0;\r\n      u = B + 128 | 0;\r\n      v = B + 112 | 0;\r\n      w = B + 96 | 0;\r\n      b[h >> 2] = c;\r\n      b[x >> 2] = b[a >> 2];\r\n      b[x + 4 >> 2] = b[a + 4 >> 2];\r\n      b[x + 8 >> 2] = b[a + 8 >> 2];\r\n      b[x + 12 >> 2] = b[a + 12 >> 2];\r\n      Ab(x, h, y);\r\n      b[g >> 2] = 0;\r\n      r = f + d + ((f | 0) == 6 & 1) | 0;\r\n      if ((r | 0) <= (d | 0)) {\r\n        T = B;\r\n        return;\r\n      }\r\n      k = b[h >> 2] | 0;\r\n      l = d + 6 | 0;\r\n      m = 16960 + (k << 2) | 0;\r\n      n = t + 8 | 0;\r\n      o = u + 8 | 0;\r\n      p = v + 8 | 0;\r\n      q = z + 4 | 0;\r\n      i = 0;\r\n      j = d;\r\n      f = -1;\r\n      a: while (1) {\r\n        h = (j | 0) % 6 | 0;\r\n        a = y + (h << 4) | 0;\r\n        b[z >> 2] = b[a >> 2];\r\n        b[z + 4 >> 2] = b[a + 4 >> 2];\r\n        b[z + 8 >> 2] = b[a + 8 >> 2];\r\n        b[z + 12 >> 2] = b[a + 12 >> 2];\r\n        a = i;\r\n        i = xb(z, k, 0, 1) | 0;\r\n        if ((j | 0) > (d | 0) & (Vb(c) | 0) != 0 ? (a | 0) != 1 ? (b[z >> 2] | 0) != (f | 0) : 0 : 0) {\r\n          Na(y + (((h + 5 | 0) % 6 | 0) << 4) + 4 | 0, A);\r\n          Na(y + (h << 4) + 4 | 0, s);\r\n          C = +(b[m >> 2] | 0);\r\n          e[t >> 3] = C * 3.0;\r\n          e[n >> 3] = 0.0;\r\n          D = C * -1.5;\r\n          e[u >> 3] = D;\r\n          e[o >> 3] = C * 2.598076211353316;\r\n          e[v >> 3] = D;\r\n          e[p >> 3] = C * -2.598076211353316;\r\n          h = b[x >> 2] | 0;\r\n          switch (b[17040 + (h * 80 | 0) + (((f | 0) == (h | 0) ? b[z >> 2] | 0 : f) << 2) >> 2] | 0) {\r\n            case 1:\r\n              {\r\n                a = u;\r\n                f = t;\r\n                break;\r\n              }\r\n            case 3:\r\n              {\r\n                a = v;\r\n                f = u;\r\n                break;\r\n              }\r\n            case 2:\r\n              {\r\n                a = t;\r\n                f = v;\r\n                break;\r\n              }\r\n            default:\r\n              {\r\n                a = 8;\r\n                break a;\r\n              }\r\n          }\r\n          kd(A, s, f, a, w);\r\n          if (!(ld(A, w) | 0) ? !(ld(s, w) | 0) : 0) {\r\n            tb(w, b[x >> 2] | 0, k, 1, g + 8 + (b[g >> 2] << 4) | 0);\r\n            b[g >> 2] = (b[g >> 2] | 0) + 1;\r\n          }\r\n        }\r\n        if ((j | 0) < (l | 0)) {\r\n          Na(q, A);\r\n          tb(A, b[z >> 2] | 0, k, 1, g + 8 + (b[g >> 2] << 4) | 0);\r\n          b[g >> 2] = (b[g >> 2] | 0) + 1;\r\n        }\r\n        j = j + 1 | 0;\r\n        if ((j | 0) >= (r | 0)) {\r\n          a = 3;\r\n          break;\r\n        } else { f = b[z >> 2] | 0; }\r\n      }\r\n      if ((a | 0) == 3) {\r\n        T = B;\r\n        return;\r\n      } else if ((a | 0) == 8) { I(27054, 27017, 737, 27099); }\r\n    }\r\n    function Ab(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 160 | 0;\r\n      e = j + 80 | 0;\r\n      f = j;\r\n      g = e;\r\n      h = 20368;\r\n      i = g + 72 | 0;\r\n      do {\r\n        b[g >> 2] = b[h >> 2];\r\n        g = g + 4 | 0;\r\n        h = h + 4 | 0;\r\n      } while ((g | 0) < (i | 0));\r\n      g = f;\r\n      h = 20448;\r\n      i = g + 72 | 0;\r\n      do {\r\n        b[g >> 2] = b[h >> 2];\r\n        g = g + 4 | 0;\r\n        h = h + 4 | 0;\r\n      } while ((g | 0) < (i | 0));\r\n      i = (Vb(b[c >> 2] | 0) | 0) == 0;\r\n      e = i ? e : f;\r\n      f = a + 4 | 0;\r\n      bb(f);\r\n      cb(f);\r\n      if (Vb(b[c >> 2] | 0) | 0) {\r\n        Xa(f);\r\n        b[c >> 2] = (b[c >> 2] | 0) + 1;\r\n      }\r\n      b[d >> 2] = b[a >> 2];\r\n      c = d + 4 | 0;\r\n      Oa(f, e, c);\r\n      Ma(c);\r\n      b[d + 16 >> 2] = b[a >> 2];\r\n      c = d + 20 | 0;\r\n      Oa(f, e + 12 | 0, c);\r\n      Ma(c);\r\n      b[d + 32 >> 2] = b[a >> 2];\r\n      c = d + 36 | 0;\r\n      Oa(f, e + 24 | 0, c);\r\n      Ma(c);\r\n      b[d + 48 >> 2] = b[a >> 2];\r\n      c = d + 52 | 0;\r\n      Oa(f, e + 36 | 0, c);\r\n      Ma(c);\r\n      b[d + 64 >> 2] = b[a >> 2];\r\n      c = d + 68 | 0;\r\n      Oa(f, e + 48 | 0, c);\r\n      Ma(c);\r\n      b[d + 80 >> 2] = b[a >> 2];\r\n      d = d + 84 | 0;\r\n      Oa(f, e + 60 | 0, d);\r\n      Ma(d);\r\n      T = j;\r\n      return;\r\n    }\r\n    function Bb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      b = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      return b & 15 | 0;\r\n    }\r\n    function Cb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      b = Qd(a | 0, b | 0, 45) | 0;\r\n      H() | 0;\r\n      return b & 127 | 0;\r\n    }\r\n    function Db(b, c) {\r\n      b = b | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      if (!(0 == 0 & (c & -16777216 | 0) == 134217728)) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      e = Qd(b | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      d = Qd(b | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      d = d & 127;\r\n      if (d >>> 0 > 121) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      h = (e ^ 15) * 3 | 0;\r\n      f = Qd(b | 0, c | 0, h | 0) | 0;\r\n      h = Rd(f | 0, H() | 0, h | 0) | 0;\r\n      f = H() | 0;\r\n      g = Hd(-1227133514, -1171, h | 0, f | 0) | 0;\r\n      if (!((h & 613566756 & g | 0) == 0 & (f & 4681 & (H() | 0) | 0) == 0)) {\r\n        h = 0;\r\n        return h | 0;\r\n      }\r\n      h = (e * 3 | 0) + 19 | 0;\r\n      g = Rd(~b | 0, ~c | 0, h | 0) | 0;\r\n      h = Qd(g | 0, H() | 0, h | 0) | 0;\r\n      if (!((e | 0) == 15 | (h | 0) == 0 & (H() | 0) == 0)) {\r\n        h = 0;\r\n        return h | 0;\r\n      }\r\n      if (!(a[20528 + d >> 0] | 0)) {\r\n        h = 1;\r\n        return h | 0;\r\n      }\r\n      c = c & 8191;\r\n      if ((b | 0) == 0 & (c | 0) == 0) {\r\n        h = 1;\r\n        return h | 0;\r\n      } else {\r\n        h = Sd(b | 0, c | 0, 0) | 0;\r\n        H() | 0;\r\n        return ((63 - h | 0) % 3 | 0 | 0) != 0 | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function Eb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      f = Rd(c | 0, 0, 52) | 0;\r\n      g = H() | 0;\r\n      d = Rd(d | 0, 0, 45) | 0;\r\n      d = g | (H() | 0) | 134225919;\r\n      if ((c | 0) < 1) {\r\n        g = -1;\r\n        e = d;\r\n        c = a;\r\n        b[c >> 2] = g;\r\n        a = a + 4 | 0;\r\n        b[a >> 2] = e;\r\n        return;\r\n      }\r\n      g = 1;\r\n      f = -1;\r\n      while (1) {\r\n        h = (15 - g | 0) * 3 | 0;\r\n        i = Rd(7, 0, h | 0) | 0;\r\n        d = d & ~(H() | 0);\r\n        h = Rd(e | 0, 0, h | 0) | 0;\r\n        f = f & ~i | h;\r\n        d = d | (H() | 0);\r\n        if ((g | 0) == (c | 0)) { break; }else { g = g + 1 | 0; }\r\n      }\r\n      i = a;\r\n      h = i;\r\n      b[h >> 2] = f;\r\n      i = i + 4 | 0;\r\n      b[i >> 2] = d;\r\n      return;\r\n    }\r\n    function Fb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0;\r\n      g = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      g = g & 15;\r\n      if (d >>> 0 > 15) {\r\n        e = 4;\r\n        return e | 0;\r\n      }\r\n      if ((g | 0) < (d | 0)) {\r\n        e = 12;\r\n        return e | 0;\r\n      }\r\n      if ((g | 0) == (d | 0)) {\r\n        b[e >> 2] = a;\r\n        b[e + 4 >> 2] = c;\r\n        e = 0;\r\n        return e | 0;\r\n      }\r\n      f = Rd(d | 0, 0, 52) | 0;\r\n      f = f | a;\r\n      a = H() | 0 | c & -15728641;\r\n      if ((g | 0) > (d | 0)) { do {\r\n        c = Rd(7, 0, (14 - d | 0) * 3 | 0) | 0;\r\n        d = d + 1 | 0;\r\n        f = c | f;\r\n        a = H() | 0 | a;\r\n      } while ((d | 0) < (g | 0)); }\r\n      b[e >> 2] = f;\r\n      b[e + 4 >> 2] = a;\r\n      e = 0;\r\n      return e | 0;\r\n    }\r\n    function Gb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      g = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      g = g & 15;\r\n      if (!((d | 0) < 16 & (g | 0) <= (d | 0))) {\r\n        e = 4;\r\n        return e | 0;\r\n      }\r\n      f = d - g | 0;\r\n      d = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      a: do { if (!(oa(d & 127) | 0)) {\r\n        d = Oc(7, 0, f, ((f | 0) < 0) << 31 >> 31) | 0;\r\n        f = H() | 0;\r\n      } else {\r\n        b: do { if (g | 0) {\r\n          d = 1;\r\n          while (1) {\r\n            h = Rd(7, 0, (15 - d | 0) * 3 | 0) | 0;\r\n            if (!((h & a | 0) == 0 & ((H() | 0) & c | 0) == 0)) { break; }\r\n            if (d >>> 0 < g >>> 0) { d = d + 1 | 0; }else { break b; }\r\n          }\r\n          d = Oc(7, 0, f, ((f | 0) < 0) << 31 >> 31) | 0;\r\n          f = H() | 0;\r\n          break a;\r\n        } } while (0);\r\n        d = Oc(7, 0, f, ((f | 0) < 0) << 31 >> 31) | 0;\r\n        d = Md(d | 0, H() | 0, 5, 0) | 0;\r\n        d = Gd(d | 0, H() | 0, -5, -1) | 0;\r\n        d = Kd(d | 0, H() | 0, 6, 0) | 0;\r\n        d = Gd(d | 0, H() | 0, 1, 0) | 0;\r\n        f = H() | 0;\r\n      } } while (0);\r\n      h = e;\r\n      b[h >> 2] = d;\r\n      b[h + 4 >> 2] = f;\r\n      h = 0;\r\n      return h | 0;\r\n    }\r\n    function Hb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      e = Qd(a | 0, b | 0, 45) | 0;\r\n      H() | 0;\r\n      if (!(oa(e & 127) | 0)) {\r\n        e = 0;\r\n        return e | 0;\r\n      }\r\n      e = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      a: do { if (!e) { c = 0; }else {\r\n        d = 1;\r\n        while (1) {\r\n          c = Qd(a | 0, b | 0, (15 - d | 0) * 3 | 0) | 0;\r\n          H() | 0;\r\n          c = c & 7;\r\n          if (c | 0) { break a; }\r\n          if (d >>> 0 < e >>> 0) { d = d + 1 | 0; }else {\r\n            c = 0;\r\n            break;\r\n          }\r\n        }\r\n      } } while (0);\r\n      e = (c | 0) == 0 & 1;\r\n      return e | 0;\r\n    }\r\n    function Ib(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = T;\r\n      T = T + 16 | 0;\r\n      g = h;\r\n      fc(g, a, c, d);\r\n      c = g;\r\n      a = b[c >> 2] | 0;\r\n      c = b[c + 4 >> 2] | 0;\r\n      if ((a | 0) == 0 & (c | 0) == 0) {\r\n        T = h;\r\n        return 0;\r\n      }\r\n      f = 0;\r\n      d = 0;\r\n      do {\r\n        i = e + (f << 3) | 0;\r\n        b[i >> 2] = a;\r\n        b[i + 4 >> 2] = c;\r\n        f = Gd(f | 0, d | 0, 1, 0) | 0;\r\n        d = H() | 0;\r\n        hc(g);\r\n        i = g;\r\n        a = b[i >> 2] | 0;\r\n        c = b[i + 4 >> 2] | 0;\r\n      } while (!((a | 0) == 0 & (c | 0) == 0));\r\n      T = h;\r\n      return 0;\r\n    }\r\n    function Jb(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      if ((d | 0) < (c | 0)) {\r\n        c = b;\r\n        d = a;\r\n        G(c | 0);\r\n        return d | 0;\r\n      }\r\n      c = Rd(-1, -1, ((d - c | 0) * 3 | 0) + 3 | 0) | 0;\r\n      d = Rd(~c | 0, ~(H() | 0) | 0, (15 - d | 0) * 3 | 0) | 0;\r\n      c = ~(H() | 0) & b;\r\n      d = ~d & a;\r\n      G(c | 0);\r\n      return d | 0;\r\n    }\r\n    function Kb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0;\r\n      f = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      f = f & 15;\r\n      if (!((d | 0) < 16 & (f | 0) <= (d | 0))) {\r\n        e = 4;\r\n        return e | 0;\r\n      }\r\n      if ((f | 0) < (d | 0)) {\r\n        f = Rd(-1, -1, ((d + -1 - f | 0) * 3 | 0) + 3 | 0) | 0;\r\n        f = Rd(~f | 0, ~(H() | 0) | 0, (15 - d | 0) * 3 | 0) | 0;\r\n        c = ~(H() | 0) & c;\r\n        a = ~f & a;\r\n      }\r\n      f = Rd(d | 0, 0, 52) | 0;\r\n      d = c & -15728641 | (H() | 0);\r\n      b[e >> 2] = a | f;\r\n      b[e + 4 >> 2] = d;\r\n      e = 0;\r\n      return e | 0;\r\n    }\r\n    function Lb(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0,\r\n        D = 0,\r\n        E = 0;\r\n      if ((d | 0) == 0 & (e | 0) == 0) {\r\n        E = 0;\r\n        return E | 0;\r\n      }\r\n      f = a;\r\n      g = b[f >> 2] | 0;\r\n      f = b[f + 4 >> 2] | 0;\r\n      if (0 == 0 & (f & 15728640 | 0) == 0) {\r\n        if (!((e | 0) > 0 | (e | 0) == 0 & d >>> 0 > 0)) {\r\n          E = 0;\r\n          return E | 0;\r\n        }\r\n        E = c;\r\n        b[E >> 2] = g;\r\n        b[E + 4 >> 2] = f;\r\n        if ((d | 0) == 1 & (e | 0) == 0) {\r\n          E = 0;\r\n          return E | 0;\r\n        }\r\n        f = 1;\r\n        g = 0;\r\n        do {\r\n          C = a + (f << 3) | 0;\r\n          D = b[C + 4 >> 2] | 0;\r\n          E = c + (f << 3) | 0;\r\n          b[E >> 2] = b[C >> 2];\r\n          b[E + 4 >> 2] = D;\r\n          f = Gd(f | 0, g | 0, 1, 0) | 0;\r\n          g = H() | 0;\r\n        } while ((g | 0) < (e | 0) | (g | 0) == (e | 0) & f >>> 0 < d >>> 0);\r\n        f = 0;\r\n        return f | 0;\r\n      }\r\n      B = d << 3;\r\n      D = Dd(B) | 0;\r\n      if (!D) {\r\n        E = 13;\r\n        return E | 0;\r\n      }\r\n      Wd(D | 0, a | 0, B | 0) | 0;\r\n      C = Fd(d, 8) | 0;\r\n      if (!C) {\r\n        Ed(D);\r\n        E = 13;\r\n        return E | 0;\r\n      }\r\n      a: while (1) {\r\n        f = D;\r\n        k = b[f >> 2] | 0;\r\n        f = b[f + 4 >> 2] | 0;\r\n        z = Qd(k | 0, f | 0, 52) | 0;\r\n        H() | 0;\r\n        z = z & 15;\r\n        A = z + -1 | 0;\r\n        y = (z | 0) != 0;\r\n        x = (e | 0) > 0 | (e | 0) == 0 & d >>> 0 > 0;\r\n        b: do { if (y & x) {\r\n          t = Rd(A | 0, 0, 52) | 0;\r\n          u = H() | 0;\r\n          if (A >>> 0 > 15) {\r\n            if (!((k | 0) == 0 & (f | 0) == 0)) {\r\n              E = 16;\r\n              break a;\r\n            }\r\n            g = 0;\r\n            a = 0;\r\n            while (1) {\r\n              g = Gd(g | 0, a | 0, 1, 0) | 0;\r\n              a = H() | 0;\r\n              if (!((a | 0) < (e | 0) | (a | 0) == (e | 0) & g >>> 0 < d >>> 0)) { break b; }\r\n              h = D + (g << 3) | 0;\r\n              w = b[h >> 2] | 0;\r\n              h = b[h + 4 >> 2] | 0;\r\n              if (!((w | 0) == 0 & (h | 0) == 0)) {\r\n                f = h;\r\n                E = 16;\r\n                break a;\r\n              }\r\n            }\r\n          }\r\n          i = k;\r\n          a = f;\r\n          g = 0;\r\n          h = 0;\r\n          while (1) {\r\n            if (!((i | 0) == 0 & (a | 0) == 0)) {\r\n              if (!(0 == 0 & (a & 117440512 | 0) == 0)) {\r\n                E = 21;\r\n                break a;\r\n              }\r\n              l = Qd(i | 0, a | 0, 52) | 0;\r\n              H() | 0;\r\n              l = l & 15;\r\n              if ((l | 0) < (A | 0)) {\r\n                f = 12;\r\n                E = 27;\r\n                break a;\r\n              }\r\n              if ((l | 0) != (A | 0)) {\r\n                i = i | t;\r\n                a = a & -15728641 | u;\r\n                if (l >>> 0 >= z >>> 0) {\r\n                  j = A;\r\n                  do {\r\n                    w = Rd(7, 0, (14 - j | 0) * 3 | 0) | 0;\r\n                    j = j + 1 | 0;\r\n                    i = w | i;\r\n                    a = H() | 0 | a;\r\n                  } while (j >>> 0 < l >>> 0);\r\n                }\r\n              }\r\n              n = Od(i | 0, a | 0, d | 0, e | 0) | 0;\r\n              o = H() | 0;\r\n              j = C + (n << 3) | 0;\r\n              l = j;\r\n              m = b[l >> 2] | 0;\r\n              l = b[l + 4 >> 2] | 0;\r\n              if (!((m | 0) == 0 & (l | 0) == 0)) {\r\n                r = 0;\r\n                s = 0;\r\n                do {\r\n                  if ((r | 0) > (e | 0) | (r | 0) == (e | 0) & s >>> 0 > d >>> 0) {\r\n                    E = 31;\r\n                    break a;\r\n                  }\r\n                  if ((m | 0) == (i | 0) & (l & -117440513 | 0) == (a | 0)) {\r\n                    p = Qd(m | 0, l | 0, 56) | 0;\r\n                    H() | 0;\r\n                    p = p & 7;\r\n                    q = p + 1 | 0;\r\n                    w = Qd(m | 0, l | 0, 45) | 0;\r\n                    H() | 0;\r\n                    c: do { if (!(oa(w & 127) | 0)) { l = 7; }else {\r\n                      m = Qd(m | 0, l | 0, 52) | 0;\r\n                      H() | 0;\r\n                      m = m & 15;\r\n                      if (!m) {\r\n                        l = 6;\r\n                        break;\r\n                      }\r\n                      l = 1;\r\n                      while (1) {\r\n                        w = Rd(7, 0, (15 - l | 0) * 3 | 0) | 0;\r\n                        if (!((w & i | 0) == 0 & ((H() | 0) & a | 0) == 0)) {\r\n                          l = 7;\r\n                          break c;\r\n                        }\r\n                        if (l >>> 0 < m >>> 0) { l = l + 1 | 0; }else {\r\n                          l = 6;\r\n                          break;\r\n                        }\r\n                      }\r\n                    } } while (0);\r\n                    if ((p + 2 | 0) >>> 0 > l >>> 0) {\r\n                      E = 41;\r\n                      break a;\r\n                    }\r\n                    w = Rd(q | 0, 0, 56) | 0;\r\n                    a = H() | 0 | a & -117440513;\r\n                    v = j;\r\n                    b[v >> 2] = 0;\r\n                    b[v + 4 >> 2] = 0;\r\n                    i = w | i;\r\n                  } else {\r\n                    n = Gd(n | 0, o | 0, 1, 0) | 0;\r\n                    n = Nd(n | 0, H() | 0, d | 0, e | 0) | 0;\r\n                    o = H() | 0;\r\n                  }\r\n                  s = Gd(s | 0, r | 0, 1, 0) | 0;\r\n                  r = H() | 0;\r\n                  j = C + (n << 3) | 0;\r\n                  l = j;\r\n                  m = b[l >> 2] | 0;\r\n                  l = b[l + 4 >> 2] | 0;\r\n                } while (!((m | 0) == 0 & (l | 0) == 0));\r\n              }\r\n              w = j;\r\n              b[w >> 2] = i;\r\n              b[w + 4 >> 2] = a;\r\n            }\r\n            g = Gd(g | 0, h | 0, 1, 0) | 0;\r\n            h = H() | 0;\r\n            if (!((h | 0) < (e | 0) | (h | 0) == (e | 0) & g >>> 0 < d >>> 0)) { break b; }\r\n            a = D + (g << 3) | 0;\r\n            i = b[a >> 2] | 0;\r\n            a = b[a + 4 >> 2] | 0;\r\n          }\r\n        } } while (0);\r\n        w = Gd(d | 0, e | 0, 5, 0) | 0;\r\n        v = H() | 0;\r\n        if (v >>> 0 < 0 | (v | 0) == 0 & w >>> 0 < 11) {\r\n          E = 85;\r\n          break;\r\n        }\r\n        w = Kd(d | 0, e | 0, 6, 0) | 0;\r\n        H() | 0;\r\n        w = Fd(w, 8) | 0;\r\n        if (!w) {\r\n          E = 48;\r\n          break;\r\n        }\r\n        do { if (x) {\r\n          q = 0;\r\n          a = 0;\r\n          p = 0;\r\n          r = 0;\r\n          while (1) {\r\n            l = C + (q << 3) | 0;\r\n            h = l;\r\n            g = b[h >> 2] | 0;\r\n            h = b[h + 4 >> 2] | 0;\r\n            if (!((g | 0) == 0 & (h | 0) == 0)) {\r\n              m = Qd(g | 0, h | 0, 56) | 0;\r\n              H() | 0;\r\n              m = m & 7;\r\n              i = m + 1 | 0;\r\n              n = h & -117440513;\r\n              v = Qd(g | 0, h | 0, 45) | 0;\r\n              H() | 0;\r\n              d: do { if (oa(v & 127) | 0) {\r\n                o = Qd(g | 0, h | 0, 52) | 0;\r\n                H() | 0;\r\n                o = o & 15;\r\n                if (o | 0) {\r\n                  j = 1;\r\n                  while (1) {\r\n                    v = Rd(7, 0, (15 - j | 0) * 3 | 0) | 0;\r\n                    if (!((g & v | 0) == 0 & (n & (H() | 0) | 0) == 0)) { break d; }\r\n                    if (j >>> 0 < o >>> 0) { j = j + 1 | 0; }else { break; }\r\n                  }\r\n                }\r\n                h = Rd(i | 0, 0, 56) | 0;\r\n                g = h | g;\r\n                h = H() | 0 | n;\r\n                i = l;\r\n                b[i >> 2] = g;\r\n                b[i + 4 >> 2] = h;\r\n                i = m + 2 | 0;\r\n              } } while (0);\r\n              if ((i | 0) == 7) {\r\n                v = w + (a << 3) | 0;\r\n                b[v >> 2] = g;\r\n                b[v + 4 >> 2] = h & -117440513;\r\n                a = Gd(a | 0, p | 0, 1, 0) | 0;\r\n                v = H() | 0;\r\n              } else { v = p; }\r\n            } else { v = p; }\r\n            q = Gd(q | 0, r | 0, 1, 0) | 0;\r\n            r = H() | 0;\r\n            if (!((r | 0) < (e | 0) | (r | 0) == (e | 0) & q >>> 0 < d >>> 0)) { break; }else { p = v; }\r\n          }\r\n          if (x) {\r\n            s = A >>> 0 > 15;\r\n            t = Rd(A | 0, 0, 52) | 0;\r\n            u = H() | 0;\r\n            if (!y) {\r\n              g = 0;\r\n              j = 0;\r\n              i = 0;\r\n              h = 0;\r\n              while (1) {\r\n                if (!((k | 0) == 0 & (f | 0) == 0)) {\r\n                  A = c + (g << 3) | 0;\r\n                  b[A >> 2] = k;\r\n                  b[A + 4 >> 2] = f;\r\n                  g = Gd(g | 0, j | 0, 1, 0) | 0;\r\n                  j = H() | 0;\r\n                }\r\n                i = Gd(i | 0, h | 0, 1, 0) | 0;\r\n                h = H() | 0;\r\n                if (!((h | 0) < (e | 0) | (h | 0) == (e | 0) & i >>> 0 < d >>> 0)) { break; }\r\n                f = D + (i << 3) | 0;\r\n                k = b[f >> 2] | 0;\r\n                f = b[f + 4 >> 2] | 0;\r\n              }\r\n              f = v;\r\n              break;\r\n            }\r\n            g = 0;\r\n            j = 0;\r\n            h = 0;\r\n            i = 0;\r\n            while (1) {\r\n              do { if (!((k | 0) == 0 & (f | 0) == 0)) {\r\n                o = Qd(k | 0, f | 0, 52) | 0;\r\n                H() | 0;\r\n                o = o & 15;\r\n                if (s | (o | 0) < (A | 0)) {\r\n                  E = 80;\r\n                  break a;\r\n                }\r\n                if ((o | 0) != (A | 0)) {\r\n                  l = k | t;\r\n                  m = f & -15728641 | u;\r\n                  if (o >>> 0 >= z >>> 0) {\r\n                    n = A;\r\n                    do {\r\n                      y = Rd(7, 0, (14 - n | 0) * 3 | 0) | 0;\r\n                      n = n + 1 | 0;\r\n                      l = y | l;\r\n                      m = H() | 0 | m;\r\n                    } while (n >>> 0 < o >>> 0);\r\n                  }\r\n                } else {\r\n                  l = k;\r\n                  m = f;\r\n                }\r\n                p = Od(l | 0, m | 0, d | 0, e | 0) | 0;\r\n                n = 0;\r\n                o = 0;\r\n                r = H() | 0;\r\n                do {\r\n                  if ((n | 0) > (e | 0) | (n | 0) == (e | 0) & o >>> 0 > d >>> 0) {\r\n                    E = 81;\r\n                    break a;\r\n                  }\r\n                  y = C + (p << 3) | 0;\r\n                  q = b[y + 4 >> 2] | 0;\r\n                  if ((q & -117440513 | 0) == (m | 0) ? (b[y >> 2] | 0) == (l | 0) : 0) {\r\n                    E = 65;\r\n                    break;\r\n                  }\r\n                  y = Gd(p | 0, r | 0, 1, 0) | 0;\r\n                  p = Nd(y | 0, H() | 0, d | 0, e | 0) | 0;\r\n                  r = H() | 0;\r\n                  o = Gd(o | 0, n | 0, 1, 0) | 0;\r\n                  n = H() | 0;\r\n                  y = C + (p << 3) | 0;\r\n                } while (!((b[y >> 2] | 0) == (l | 0) ? (b[y + 4 >> 2] | 0) == (m | 0) : 0));\r\n                if ((E | 0) == 65 ? (E = 0, 0 == 0 & (q & 117440512 | 0) == 100663296) : 0) { break; }\r\n                y = c + (g << 3) | 0;\r\n                b[y >> 2] = k;\r\n                b[y + 4 >> 2] = f;\r\n                g = Gd(g | 0, j | 0, 1, 0) | 0;\r\n                j = H() | 0;\r\n              } } while (0);\r\n              h = Gd(h | 0, i | 0, 1, 0) | 0;\r\n              i = H() | 0;\r\n              if (!((i | 0) < (e | 0) | (i | 0) == (e | 0) & h >>> 0 < d >>> 0)) { break; }\r\n              f = D + (h << 3) | 0;\r\n              k = b[f >> 2] | 0;\r\n              f = b[f + 4 >> 2] | 0;\r\n            }\r\n            f = v;\r\n          } else {\r\n            g = 0;\r\n            f = v;\r\n          }\r\n        } else {\r\n          g = 0;\r\n          a = 0;\r\n          f = 0;\r\n        } } while (0);\r\n        Xd(C | 0, 0, B | 0) | 0;\r\n        Wd(D | 0, w | 0, a << 3 | 0) | 0;\r\n        Ed(w);\r\n        if ((a | 0) == 0 & (f | 0) == 0) {\r\n          E = 89;\r\n          break;\r\n        } else {\r\n          c = c + (g << 3) | 0;\r\n          e = f;\r\n          d = a;\r\n        }\r\n      }\r\n      if ((E | 0) == 16) {\r\n        if (0 == 0 & (f & 117440512 | 0) == 0) {\r\n          f = 4;\r\n          E = 27;\r\n        } else { E = 21; }\r\n      } else if ((E | 0) == 31) { I(27795, 27122, 529, 27132); }else if ((E | 0) == 41) {\r\n        Ed(D);\r\n        Ed(C);\r\n        E = 10;\r\n        return E | 0;\r\n      } else if ((E | 0) == 48) {\r\n        Ed(D);\r\n        Ed(C);\r\n        E = 13;\r\n        return E | 0;\r\n      } else if ((E | 0) == 80) { I(27795, 27122, 620, 27132); }else if ((E | 0) == 81) { I(27795, 27122, 632, 27132); }else if ((E | 0) == 85) {\r\n        Wd(c | 0, D | 0, d << 3 | 0) | 0;\r\n        E = 89;\r\n      }\r\n      if ((E | 0) == 21) {\r\n        Ed(D);\r\n        Ed(C);\r\n        E = 5;\r\n        return E | 0;\r\n      } else if ((E | 0) == 27) {\r\n        Ed(D);\r\n        Ed(C);\r\n        E = f;\r\n        return E | 0;\r\n      } else if ((E | 0) == 89) {\r\n        Ed(D);\r\n        Ed(C);\r\n        E = 0;\r\n        return E | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function Mb(a, c, d, e, f, g, h) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      h = h | 0;\r\n      var i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0;\r\n      q = T;\r\n      T = T + 16 | 0;\r\n      p = q;\r\n      if (!((d | 0) > 0 | (d | 0) == 0 & c >>> 0 > 0)) {\r\n        p = 0;\r\n        T = q;\r\n        return p | 0;\r\n      }\r\n      if ((h | 0) >= 16) {\r\n        p = 12;\r\n        T = q;\r\n        return p | 0;\r\n      }\r\n      n = 0;\r\n      o = 0;\r\n      m = 0;\r\n      i = 0;\r\n      a: while (1) {\r\n        k = a + (n << 3) | 0;\r\n        j = b[k >> 2] | 0;\r\n        k = b[k + 4 >> 2] | 0;\r\n        l = Qd(j | 0, k | 0, 52) | 0;\r\n        H() | 0;\r\n        if ((l & 15 | 0) > (h | 0)) {\r\n          i = 12;\r\n          j = 11;\r\n          break;\r\n        }\r\n        fc(p, j, k, h);\r\n        l = p;\r\n        k = b[l >> 2] | 0;\r\n        l = b[l + 4 >> 2] | 0;\r\n        if ((k | 0) == 0 & (l | 0) == 0) { j = m; }else {\r\n          j = m;\r\n          do {\r\n            if (!((i | 0) < (g | 0) | (i | 0) == (g | 0) & j >>> 0 < f >>> 0)) {\r\n              j = 10;\r\n              break a;\r\n            }\r\n            m = e + (j << 3) | 0;\r\n            b[m >> 2] = k;\r\n            b[m + 4 >> 2] = l;\r\n            j = Gd(j | 0, i | 0, 1, 0) | 0;\r\n            i = H() | 0;\r\n            hc(p);\r\n            m = p;\r\n            k = b[m >> 2] | 0;\r\n            l = b[m + 4 >> 2] | 0;\r\n          } while (!((k | 0) == 0 & (l | 0) == 0));\r\n        }\r\n        n = Gd(n | 0, o | 0, 1, 0) | 0;\r\n        o = H() | 0;\r\n        if (!((o | 0) < (d | 0) | (o | 0) == (d | 0) & n >>> 0 < c >>> 0)) {\r\n          i = 0;\r\n          j = 11;\r\n          break;\r\n        } else { m = j; }\r\n      }\r\n      if ((j | 0) == 10) {\r\n        p = 14;\r\n        T = q;\r\n        return p | 0;\r\n      } else if ((j | 0) == 11) {\r\n        T = q;\r\n        return i | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function Nb(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0;\r\n      n = T;\r\n      T = T + 16 | 0;\r\n      m = n;\r\n      a: do { if ((d | 0) > 0 | (d | 0) == 0 & c >>> 0 > 0) {\r\n        k = 0;\r\n        h = 0;\r\n        g = 0;\r\n        l = 0;\r\n        while (1) {\r\n          j = a + (k << 3) | 0;\r\n          i = b[j >> 2] | 0;\r\n          j = b[j + 4 >> 2] | 0;\r\n          if (!((i | 0) == 0 & (j | 0) == 0)) {\r\n            j = (Gb(i, j, e, m) | 0) == 0;\r\n            i = m;\r\n            h = Gd(b[i >> 2] | 0, b[i + 4 >> 2] | 0, h | 0, g | 0) | 0;\r\n            g = H() | 0;\r\n            if (!j) {\r\n              g = 12;\r\n              break;\r\n            }\r\n          }\r\n          k = Gd(k | 0, l | 0, 1, 0) | 0;\r\n          l = H() | 0;\r\n          if (!((l | 0) < (d | 0) | (l | 0) == (d | 0) & k >>> 0 < c >>> 0)) { break a; }\r\n        }\r\n        T = n;\r\n        return g | 0;\r\n      } else {\r\n        h = 0;\r\n        g = 0;\r\n      } } while (0);\r\n      b[f >> 2] = h;\r\n      b[f + 4 >> 2] = g;\r\n      f = 0;\r\n      T = n;\r\n      return f | 0;\r\n    }\r\n    function Ob(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      b = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      return b & 1 | 0;\r\n    }\r\n    function Pb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      e = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      if (!e) {\r\n        e = 0;\r\n        return e | 0;\r\n      }\r\n      d = 1;\r\n      while (1) {\r\n        c = Qd(a | 0, b | 0, (15 - d | 0) * 3 | 0) | 0;\r\n        H() | 0;\r\n        c = c & 7;\r\n        if (c | 0) {\r\n          d = 5;\r\n          break;\r\n        }\r\n        if (d >>> 0 < e >>> 0) { d = d + 1 | 0; }else {\r\n          c = 0;\r\n          d = 5;\r\n          break;\r\n        }\r\n      }\r\n      if ((d | 0) == 5) { return c | 0; }\r\n      return 0;\r\n    }\r\n    function Qb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      i = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      i = i & 15;\r\n      if (!i) {\r\n        h = b;\r\n        i = a;\r\n        G(h | 0);\r\n        return i | 0;\r\n      }\r\n      h = 1;\r\n      c = 0;\r\n      while (1) {\r\n        f = (15 - h | 0) * 3 | 0;\r\n        d = Rd(7, 0, f | 0) | 0;\r\n        e = H() | 0;\r\n        g = Qd(a | 0, b | 0, f | 0) | 0;\r\n        H() | 0;\r\n        f = Rd($a(g & 7) | 0, 0, f | 0) | 0;\r\n        g = H() | 0;\r\n        a = f | a & ~d;\r\n        b = g | b & ~e;\r\n        a: do { if (!c) { if (!((f & d | 0) == 0 & (g & e | 0) == 0)) {\r\n          d = Qd(a | 0, b | 0, 52) | 0;\r\n          H() | 0;\r\n          d = d & 15;\r\n          if (!d) { c = 1; }else {\r\n            c = 1;\r\n            b: while (1) {\r\n              g = Qd(a | 0, b | 0, (15 - c | 0) * 3 | 0) | 0;\r\n              H() | 0;\r\n              switch (g & 7) {\r\n                case 1:\r\n                  break b;\r\n                case 0:\r\n                  break;\r\n                default:\r\n                  {\r\n                    c = 1;\r\n                    break a;\r\n                  }\r\n              }\r\n              if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else {\r\n                c = 1;\r\n                break a;\r\n              }\r\n            }\r\n            c = 1;\r\n            while (1) {\r\n              g = (15 - c | 0) * 3 | 0;\r\n              e = Qd(a | 0, b | 0, g | 0) | 0;\r\n              H() | 0;\r\n              f = Rd(7, 0, g | 0) | 0;\r\n              b = b & ~(H() | 0);\r\n              g = Rd($a(e & 7) | 0, 0, g | 0) | 0;\r\n              a = a & ~f | g;\r\n              b = b | (H() | 0);\r\n              if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else {\r\n                c = 1;\r\n                break;\r\n              }\r\n            }\r\n          }\r\n        } else { c = 0; } } } while (0);\r\n        if (h >>> 0 < i >>> 0) { h = h + 1 | 0; }else { break; }\r\n      }\r\n      G(b | 0);\r\n      return a | 0;\r\n    }\r\n    function Rb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      d = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      d = d & 15;\r\n      if (!d) {\r\n        c = b;\r\n        d = a;\r\n        G(c | 0);\r\n        return d | 0;\r\n      }\r\n      c = 1;\r\n      while (1) {\r\n        f = (15 - c | 0) * 3 | 0;\r\n        g = Qd(a | 0, b | 0, f | 0) | 0;\r\n        H() | 0;\r\n        e = Rd(7, 0, f | 0) | 0;\r\n        b = b & ~(H() | 0);\r\n        f = Rd($a(g & 7) | 0, 0, f | 0) | 0;\r\n        a = f | a & ~e;\r\n        b = H() | 0 | b;\r\n        if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else { break; }\r\n      }\r\n      G(b | 0);\r\n      return a | 0;\r\n    }\r\n    function Sb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      i = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      i = i & 15;\r\n      if (!i) {\r\n        h = b;\r\n        i = a;\r\n        G(h | 0);\r\n        return i | 0;\r\n      }\r\n      h = 1;\r\n      c = 0;\r\n      while (1) {\r\n        f = (15 - h | 0) * 3 | 0;\r\n        d = Rd(7, 0, f | 0) | 0;\r\n        e = H() | 0;\r\n        g = Qd(a | 0, b | 0, f | 0) | 0;\r\n        H() | 0;\r\n        f = Rd(ab(g & 7) | 0, 0, f | 0) | 0;\r\n        g = H() | 0;\r\n        a = f | a & ~d;\r\n        b = g | b & ~e;\r\n        a: do { if (!c) { if (!((f & d | 0) == 0 & (g & e | 0) == 0)) {\r\n          d = Qd(a | 0, b | 0, 52) | 0;\r\n          H() | 0;\r\n          d = d & 15;\r\n          if (!d) { c = 1; }else {\r\n            c = 1;\r\n            b: while (1) {\r\n              g = Qd(a | 0, b | 0, (15 - c | 0) * 3 | 0) | 0;\r\n              H() | 0;\r\n              switch (g & 7) {\r\n                case 1:\r\n                  break b;\r\n                case 0:\r\n                  break;\r\n                default:\r\n                  {\r\n                    c = 1;\r\n                    break a;\r\n                  }\r\n              }\r\n              if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else {\r\n                c = 1;\r\n                break a;\r\n              }\r\n            }\r\n            c = 1;\r\n            while (1) {\r\n              e = (15 - c | 0) * 3 | 0;\r\n              f = Rd(7, 0, e | 0) | 0;\r\n              g = b & ~(H() | 0);\r\n              b = Qd(a | 0, b | 0, e | 0) | 0;\r\n              H() | 0;\r\n              b = Rd(ab(b & 7) | 0, 0, e | 0) | 0;\r\n              a = a & ~f | b;\r\n              b = g | (H() | 0);\r\n              if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else {\r\n                c = 1;\r\n                break;\r\n              }\r\n            }\r\n          }\r\n        } else { c = 0; } } } while (0);\r\n        if (h >>> 0 < i >>> 0) { h = h + 1 | 0; }else { break; }\r\n      }\r\n      G(b | 0);\r\n      return a | 0;\r\n    }\r\n    function Tb(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      d = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      d = d & 15;\r\n      if (!d) {\r\n        c = b;\r\n        d = a;\r\n        G(c | 0);\r\n        return d | 0;\r\n      }\r\n      c = 1;\r\n      while (1) {\r\n        g = (15 - c | 0) * 3 | 0;\r\n        f = Rd(7, 0, g | 0) | 0;\r\n        e = b & ~(H() | 0);\r\n        b = Qd(a | 0, b | 0, g | 0) | 0;\r\n        H() | 0;\r\n        b = Rd(ab(b & 7) | 0, 0, g | 0) | 0;\r\n        a = b | a & ~f;\r\n        b = H() | 0 | e;\r\n        if (c >>> 0 < d >>> 0) { c = c + 1 | 0; }else { break; }\r\n      }\r\n      G(b | 0);\r\n      return a | 0;\r\n    }\r\n    function Ub(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0;\r\n      j = T;\r\n      T = T + 64 | 0;\r\n      i = j + 40 | 0;\r\n      e = j + 24 | 0;\r\n      f = j + 12 | 0;\r\n      g = j;\r\n      Rd(c | 0, 0, 52) | 0;\r\n      d = H() | 0 | 134225919;\r\n      if (!c) {\r\n        if ((b[a + 4 >> 2] | 0) > 2) {\r\n          h = 0;\r\n          i = 0;\r\n          G(h | 0);\r\n          T = j;\r\n          return i | 0;\r\n        }\r\n        if ((b[a + 8 >> 2] | 0) > 2) {\r\n          h = 0;\r\n          i = 0;\r\n          G(h | 0);\r\n          T = j;\r\n          return i | 0;\r\n        }\r\n        if ((b[a + 12 >> 2] | 0) > 2) {\r\n          h = 0;\r\n          i = 0;\r\n          G(h | 0);\r\n          T = j;\r\n          return i | 0;\r\n        }\r\n        Rd(qa(a) | 0, 0, 45) | 0;\r\n        h = H() | 0 | d;\r\n        i = -1;\r\n        G(h | 0);\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      b[i >> 2] = b[a >> 2];\r\n      b[i + 4 >> 2] = b[a + 4 >> 2];\r\n      b[i + 8 >> 2] = b[a + 8 >> 2];\r\n      b[i + 12 >> 2] = b[a + 12 >> 2];\r\n      h = i + 4 | 0;\r\n      if ((c | 0) > 0) {\r\n        a = -1;\r\n        while (1) {\r\n          b[e >> 2] = b[h >> 2];\r\n          b[e + 4 >> 2] = b[h + 4 >> 2];\r\n          b[e + 8 >> 2] = b[h + 8 >> 2];\r\n          if (!(c & 1)) {\r\n            Va(h);\r\n            b[f >> 2] = b[h >> 2];\r\n            b[f + 4 >> 2] = b[h + 4 >> 2];\r\n            b[f + 8 >> 2] = b[h + 8 >> 2];\r\n            Xa(f);\r\n          } else {\r\n            Ua(h);\r\n            b[f >> 2] = b[h >> 2];\r\n            b[f + 4 >> 2] = b[h + 4 >> 2];\r\n            b[f + 8 >> 2] = b[h + 8 >> 2];\r\n            Wa(f);\r\n          }\r\n          Pa(e, f, g);\r\n          Ma(g);\r\n          l = (15 - c | 0) * 3 | 0;\r\n          k = Rd(7, 0, l | 0) | 0;\r\n          d = d & ~(H() | 0);\r\n          l = Rd(Ra(g) | 0, 0, l | 0) | 0;\r\n          a = l | a & ~k;\r\n          d = H() | 0 | d;\r\n          if ((c | 0) > 1) { c = c + -1 | 0; }else { break; }\r\n        }\r\n      } else { a = -1; }\r\n      a: do { if (((b[h >> 2] | 0) <= 2 ? (b[i + 8 >> 2] | 0) <= 2 : 0) ? (b[i + 12 >> 2] | 0) <= 2 : 0) {\r\n        e = qa(i) | 0;\r\n        c = Rd(e | 0, 0, 45) | 0;\r\n        c = c | a;\r\n        a = H() | 0 | d & -1040385;\r\n        g = ra(i) | 0;\r\n        if (!(oa(e) | 0)) {\r\n          if ((g | 0) <= 0) { break; }\r\n          f = 0;\r\n          while (1) {\r\n            e = Qd(c | 0, a | 0, 52) | 0;\r\n            H() | 0;\r\n            e = e & 15;\r\n            if (e) {\r\n              d = 1;\r\n              while (1) {\r\n                l = (15 - d | 0) * 3 | 0;\r\n                i = Qd(c | 0, a | 0, l | 0) | 0;\r\n                H() | 0;\r\n                k = Rd(7, 0, l | 0) | 0;\r\n                a = a & ~(H() | 0);\r\n                l = Rd($a(i & 7) | 0, 0, l | 0) | 0;\r\n                c = c & ~k | l;\r\n                a = a | (H() | 0);\r\n                if (d >>> 0 < e >>> 0) { d = d + 1 | 0; }else { break; }\r\n              }\r\n            }\r\n            f = f + 1 | 0;\r\n            if ((f | 0) == (g | 0)) { break a; }\r\n          }\r\n        }\r\n        f = Qd(c | 0, a | 0, 52) | 0;\r\n        H() | 0;\r\n        f = f & 15;\r\n        b: do { if (f) {\r\n          d = 1;\r\n          c: while (1) {\r\n            l = Qd(c | 0, a | 0, (15 - d | 0) * 3 | 0) | 0;\r\n            H() | 0;\r\n            switch (l & 7) {\r\n              case 1:\r\n                break c;\r\n              case 0:\r\n                break;\r\n              default:\r\n                break b;\r\n            }\r\n            if (d >>> 0 < f >>> 0) { d = d + 1 | 0; }else { break b; }\r\n          }\r\n          if (ua(e, b[i >> 2] | 0) | 0) {\r\n            d = 1;\r\n            while (1) {\r\n              i = (15 - d | 0) * 3 | 0;\r\n              k = Rd(7, 0, i | 0) | 0;\r\n              l = a & ~(H() | 0);\r\n              a = Qd(c | 0, a | 0, i | 0) | 0;\r\n              H() | 0;\r\n              a = Rd(ab(a & 7) | 0, 0, i | 0) | 0;\r\n              c = c & ~k | a;\r\n              a = l | (H() | 0);\r\n              if (d >>> 0 < f >>> 0) { d = d + 1 | 0; }else { break; }\r\n            }\r\n          } else {\r\n            d = 1;\r\n            while (1) {\r\n              l = (15 - d | 0) * 3 | 0;\r\n              i = Qd(c | 0, a | 0, l | 0) | 0;\r\n              H() | 0;\r\n              k = Rd(7, 0, l | 0) | 0;\r\n              a = a & ~(H() | 0);\r\n              l = Rd($a(i & 7) | 0, 0, l | 0) | 0;\r\n              c = c & ~k | l;\r\n              a = a | (H() | 0);\r\n              if (d >>> 0 < f >>> 0) { d = d + 1 | 0; }else { break; }\r\n            }\r\n          }\r\n        } } while (0);\r\n        if ((g | 0) > 0) {\r\n          d = 0;\r\n          do {\r\n            c = Qb(c, a) | 0;\r\n            a = H() | 0;\r\n            d = d + 1 | 0;\r\n          } while ((d | 0) != (g | 0));\r\n        }\r\n      } else {\r\n        c = 0;\r\n        a = 0;\r\n      } } while (0);\r\n      k = a;\r\n      l = c;\r\n      G(k | 0);\r\n      T = j;\r\n      return l | 0;\r\n    }\r\n    function Vb(a) {\r\n      a = a | 0;\r\n      return (a | 0) % 2 | 0 | 0;\r\n    }\r\n    function Wb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      e = f;\r\n      if (c >>> 0 > 15) {\r\n        e = 4;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      if ((b[a + 4 >> 2] & 2146435072 | 0) == 2146435072) {\r\n        e = 3;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      if ((b[a + 8 + 4 >> 2] & 2146435072 | 0) == 2146435072) {\r\n        e = 3;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      qb(a, c, e);\r\n      c = Ub(e, c) | 0;\r\n      e = H() | 0;\r\n      b[d >> 2] = c;\r\n      b[d + 4 >> 2] = e;\r\n      if ((c | 0) == 0 & (e | 0) == 0) { I(27795, 27122, 959, 27145); }\r\n      e = 0;\r\n      T = f;\r\n      return e | 0;\r\n    }\r\n    function Xb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      f = d + 4 | 0;\r\n      g = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      g = g & 15;\r\n      h = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      e = (g | 0) == 0;\r\n      if (!(oa(h & 127) | 0)) {\r\n        if (e) {\r\n          h = 0;\r\n          return h | 0;\r\n        }\r\n        if ((b[f >> 2] | 0) == 0 ? (b[d + 8 >> 2] | 0) == 0 : 0) { e = (b[d + 12 >> 2] | 0) != 0 & 1; }else { e = 1; }\r\n      } else if (e) {\r\n        h = 1;\r\n        return h | 0;\r\n      } else { e = 1; }\r\n      d = 1;\r\n      while (1) {\r\n        if (!(d & 1)) { Xa(f); }else { Wa(f); }\r\n        h = Qd(a | 0, c | 0, (15 - d | 0) * 3 | 0) | 0;\r\n        H() | 0;\r\n        Ya(f, h & 7);\r\n        if (d >>> 0 < g >>> 0) { d = d + 1 | 0; }else { break; }\r\n      }\r\n      return e | 0;\r\n    }\r\n    function Yb(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0;\r\n      l = T;\r\n      T = T + 16 | 0;\r\n      j = l;\r\n      k = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      k = k & 127;\r\n      if (k >>> 0 > 121) {\r\n        b[d >> 2] = 0;\r\n        b[d + 4 >> 2] = 0;\r\n        b[d + 8 >> 2] = 0;\r\n        b[d + 12 >> 2] = 0;\r\n        k = 5;\r\n        T = l;\r\n        return k | 0;\r\n      }\r\n      a: do { if ((oa(k) | 0) != 0 ? (g = Qd(a | 0, c | 0, 52) | 0, H() | 0, g = g & 15, (g | 0) != 0) : 0) {\r\n        e = 1;\r\n        b: while (1) {\r\n          i = Qd(a | 0, c | 0, (15 - e | 0) * 3 | 0) | 0;\r\n          H() | 0;\r\n          switch (i & 7) {\r\n            case 5:\r\n              break b;\r\n            case 0:\r\n              break;\r\n            default:\r\n              {\r\n                e = c;\r\n                break a;\r\n              }\r\n          }\r\n          if (e >>> 0 < g >>> 0) { e = e + 1 | 0; }else {\r\n            e = c;\r\n            break a;\r\n          }\r\n        }\r\n        f = 1;\r\n        e = c;\r\n        while (1) {\r\n          c = (15 - f | 0) * 3 | 0;\r\n          h = Rd(7, 0, c | 0) | 0;\r\n          i = e & ~(H() | 0);\r\n          e = Qd(a | 0, e | 0, c | 0) | 0;\r\n          H() | 0;\r\n          e = Rd(ab(e & 7) | 0, 0, c | 0) | 0;\r\n          a = a & ~h | e;\r\n          e = i | (H() | 0);\r\n          if (f >>> 0 < g >>> 0) { f = f + 1 | 0; }else { break; }\r\n        }\r\n      } else { e = c; } } while (0);\r\n      i = 7696 + (k * 28 | 0) | 0;\r\n      b[d >> 2] = b[i >> 2];\r\n      b[d + 4 >> 2] = b[i + 4 >> 2];\r\n      b[d + 8 >> 2] = b[i + 8 >> 2];\r\n      b[d + 12 >> 2] = b[i + 12 >> 2];\r\n      if (!(Xb(a, e, d) | 0)) {\r\n        k = 0;\r\n        T = l;\r\n        return k | 0;\r\n      }\r\n      h = d + 4 | 0;\r\n      b[j >> 2] = b[h >> 2];\r\n      b[j + 4 >> 2] = b[h + 4 >> 2];\r\n      b[j + 8 >> 2] = b[h + 8 >> 2];\r\n      g = Qd(a | 0, e | 0, 52) | 0;\r\n      H() | 0;\r\n      i = g & 15;\r\n      if (!(g & 1)) { g = i; }else {\r\n        Xa(h);\r\n        g = i + 1 | 0;\r\n      }\r\n      if (!(oa(k) | 0)) { e = 0; }else {\r\n        c: do { if (!i) { e = 0; }else {\r\n          c = 1;\r\n          while (1) {\r\n            f = Qd(a | 0, e | 0, (15 - c | 0) * 3 | 0) | 0;\r\n            H() | 0;\r\n            f = f & 7;\r\n            if (f | 0) {\r\n              e = f;\r\n              break c;\r\n            }\r\n            if (c >>> 0 < i >>> 0) { c = c + 1 | 0; }else {\r\n              e = 0;\r\n              break;\r\n            }\r\n          }\r\n        } } while (0);\r\n        e = (e | 0) == 4 & 1;\r\n      }\r\n      if (!(xb(d, g, e, 0) | 0)) {\r\n        if ((g | 0) != (i | 0)) {\r\n          b[h >> 2] = b[j >> 2];\r\n          b[h + 4 >> 2] = b[j + 4 >> 2];\r\n          b[h + 8 >> 2] = b[j + 8 >> 2];\r\n        }\r\n      } else {\r\n        if (oa(k) | 0) { do {} while ((xb(d, g, 0, 0) | 0) != 0); }\r\n        if ((g | 0) != (i | 0)) { Va(h); }\r\n      }\r\n      k = 0;\r\n      T = l;\r\n      return k | 0;\r\n    }\r\n    function Zb(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      d = f;\r\n      e = Yb(a, b, d) | 0;\r\n      if (e | 0) {\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      e = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      ub(d, e & 15, c);\r\n      e = 0;\r\n      T = f;\r\n      return e | 0;\r\n    }\r\n    function _b(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      g = T;\r\n      T = T + 16 | 0;\r\n      f = g;\r\n      d = Yb(a, b, f) | 0;\r\n      if (d | 0) {\r\n        f = d;\r\n        T = g;\r\n        return f | 0;\r\n      }\r\n      d = Qd(a | 0, b | 0, 45) | 0;\r\n      H() | 0;\r\n      d = (oa(d & 127) | 0) == 0;\r\n      e = Qd(a | 0, b | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      a: do { if (!d) {\r\n        if (e | 0) {\r\n          d = 1;\r\n          while (1) {\r\n            h = Rd(7, 0, (15 - d | 0) * 3 | 0) | 0;\r\n            if (!((h & a | 0) == 0 & ((H() | 0) & b | 0) == 0)) { break a; }\r\n            if (d >>> 0 < e >>> 0) { d = d + 1 | 0; }else { break; }\r\n          }\r\n        }\r\n        vb(f, e, 0, 5, c);\r\n        h = 0;\r\n        T = g;\r\n        return h | 0;\r\n      } } while (0);\r\n      zb(f, e, 0, 6, c);\r\n      h = 0;\r\n      T = g;\r\n      return h | 0;\r\n    }\r\n    function $b(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      f = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      if (!(oa(f & 127) | 0)) {\r\n        f = 2;\r\n        b[d >> 2] = f;\r\n        return 0;\r\n      }\r\n      f = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      f = f & 15;\r\n      if (!f) {\r\n        f = 5;\r\n        b[d >> 2] = f;\r\n        return 0;\r\n      }\r\n      e = 1;\r\n      while (1) {\r\n        g = Rd(7, 0, (15 - e | 0) * 3 | 0) | 0;\r\n        if (!((g & a | 0) == 0 & ((H() | 0) & c | 0) == 0)) {\r\n          e = 2;\r\n          a = 6;\r\n          break;\r\n        }\r\n        if (e >>> 0 < f >>> 0) { e = e + 1 | 0; }else {\r\n          e = 5;\r\n          a = 6;\r\n          break;\r\n        }\r\n      }\r\n      if ((a | 0) == 6) {\r\n        b[d >> 2] = e;\r\n        return 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function ac(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0;\r\n      m = T;\r\n      T = T + 128 | 0;\r\n      k = m + 112 | 0;\r\n      g = m + 96 | 0;\r\n      l = m;\r\n      f = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      i = f & 15;\r\n      b[k >> 2] = i;\r\n      h = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      h = h & 127;\r\n      a: do { if (oa(h) | 0) {\r\n        if (i | 0) {\r\n          e = 1;\r\n          while (1) {\r\n            j = Rd(7, 0, (15 - e | 0) * 3 | 0) | 0;\r\n            if (!((j & a | 0) == 0 & ((H() | 0) & c | 0) == 0)) {\r\n              f = 0;\r\n              break a;\r\n            }\r\n            if (e >>> 0 < i >>> 0) { e = e + 1 | 0; }else { break; }\r\n          }\r\n        }\r\n        if (!(f & 1)) {\r\n          j = Rd(i + 1 | 0, 0, 52) | 0;\r\n          l = H() | 0 | c & -15728641;\r\n          k = Rd(7, 0, (14 - i | 0) * 3 | 0) | 0;\r\n          l = ac((j | a) & ~k, l & ~(H() | 0), d) | 0;\r\n          T = m;\r\n          return l | 0;\r\n        } else { f = 1; }\r\n      } else { f = 0; } } while (0);\r\n      e = Yb(a, c, g) | 0;\r\n      if (!e) {\r\n        if (f) {\r\n          wb(g, k, l);\r\n          j = 5;\r\n        } else {\r\n          Ab(g, k, l);\r\n          j = 6;\r\n        }\r\n        b: do { if (oa(h) | 0) {\r\n          if (!i) { a = 5; }else {\r\n            e = 1;\r\n            while (1) {\r\n              h = Rd(7, 0, (15 - e | 0) * 3 | 0) | 0;\r\n              if (!((h & a | 0) == 0 & ((H() | 0) & c | 0) == 0)) {\r\n                a = 2;\r\n                break b;\r\n              }\r\n              if (e >>> 0 < i >>> 0) { e = e + 1 | 0; }else {\r\n                a = 5;\r\n                break;\r\n              }\r\n            }\r\n          }\r\n        } else { a = 2; } } while (0);\r\n        Xd(d | 0, -1, a << 2 | 0) | 0;\r\n        c: do { if (f) {\r\n          g = 0;\r\n          while (1) {\r\n            h = l + (g << 4) | 0;\r\n            yb(h, b[k >> 2] | 0) | 0;\r\n            h = b[h >> 2] | 0;\r\n            i = b[d >> 2] | 0;\r\n            if ((i | 0) == -1 | (i | 0) == (h | 0)) { e = d; }else {\r\n              f = 0;\r\n              do {\r\n                f = f + 1 | 0;\r\n                if (f >>> 0 >= a >>> 0) {\r\n                  e = 1;\r\n                  break c;\r\n                }\r\n                e = d + (f << 2) | 0;\r\n                i = b[e >> 2] | 0;\r\n              } while (!((i | 0) == -1 | (i | 0) == (h | 0)));\r\n            }\r\n            b[e >> 2] = h;\r\n            g = g + 1 | 0;\r\n            if (g >>> 0 >= j >>> 0) {\r\n              e = 0;\r\n              break;\r\n            }\r\n          }\r\n        } else {\r\n          g = 0;\r\n          while (1) {\r\n            h = l + (g << 4) | 0;\r\n            xb(h, b[k >> 2] | 0, 0, 1) | 0;\r\n            h = b[h >> 2] | 0;\r\n            i = b[d >> 2] | 0;\r\n            if ((i | 0) == -1 | (i | 0) == (h | 0)) { e = d; }else {\r\n              f = 0;\r\n              do {\r\n                f = f + 1 | 0;\r\n                if (f >>> 0 >= a >>> 0) {\r\n                  e = 1;\r\n                  break c;\r\n                }\r\n                e = d + (f << 2) | 0;\r\n                i = b[e >> 2] | 0;\r\n              } while (!((i | 0) == -1 | (i | 0) == (h | 0)));\r\n            }\r\n            b[e >> 2] = h;\r\n            g = g + 1 | 0;\r\n            if (g >>> 0 >= j >>> 0) {\r\n              e = 0;\r\n              break;\r\n            }\r\n          }\r\n        } } while (0);\r\n      }\r\n      l = e;\r\n      T = m;\r\n      return l | 0;\r\n    }\r\n    function bc() {\r\n      return 12;\r\n    }\r\n    function cc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      if (a >>> 0 > 15) {\r\n        i = 4;\r\n        return i | 0;\r\n      }\r\n      Rd(a | 0, 0, 52) | 0;\r\n      i = H() | 0 | 134225919;\r\n      if (!a) {\r\n        d = 0;\r\n        e = 0;\r\n        do {\r\n          if (oa(e) | 0) {\r\n            Rd(e | 0, 0, 45) | 0;\r\n            h = i | (H() | 0);\r\n            a = c + (d << 3) | 0;\r\n            b[a >> 2] = -1;\r\n            b[a + 4 >> 2] = h;\r\n            d = d + 1 | 0;\r\n          }\r\n          e = e + 1 | 0;\r\n        } while ((e | 0) != 122);\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      d = 0;\r\n      h = 0;\r\n      do {\r\n        if (oa(h) | 0) {\r\n          Rd(h | 0, 0, 45) | 0;\r\n          e = 1;\r\n          f = -1;\r\n          g = i | (H() | 0);\r\n          while (1) {\r\n            j = Rd(7, 0, (15 - e | 0) * 3 | 0) | 0;\r\n            f = f & ~j;\r\n            g = g & ~(H() | 0);\r\n            if ((e | 0) == (a | 0)) { break; }else { e = e + 1 | 0; }\r\n          }\r\n          j = c + (d << 3) | 0;\r\n          b[j >> 2] = f;\r\n          b[j + 4 >> 2] = g;\r\n          d = d + 1 | 0;\r\n        }\r\n        h = h + 1 | 0;\r\n      } while ((h | 0) != 122);\r\n      d = 0;\r\n      return d | 0;\r\n    }\r\n    function dc(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0;\r\n      t = T;\r\n      T = T + 16 | 0;\r\n      r = t;\r\n      s = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      s = s & 15;\r\n      if (d >>> 0 > 15) {\r\n        s = 4;\r\n        T = t;\r\n        return s | 0;\r\n      }\r\n      if ((s | 0) < (d | 0)) {\r\n        s = 12;\r\n        T = t;\r\n        return s | 0;\r\n      }\r\n      if ((s | 0) != (d | 0)) {\r\n        g = Rd(d | 0, 0, 52) | 0;\r\n        g = g | a;\r\n        i = H() | 0 | c & -15728641;\r\n        if ((s | 0) > (d | 0)) {\r\n          j = d;\r\n          do {\r\n            q = Rd(7, 0, (14 - j | 0) * 3 | 0) | 0;\r\n            j = j + 1 | 0;\r\n            g = q | g;\r\n            i = H() | 0 | i;\r\n          } while ((j | 0) < (s | 0));\r\n          q = g;\r\n        } else { q = g; }\r\n      } else {\r\n        q = a;\r\n        i = c;\r\n      }\r\n      p = Qd(q | 0, i | 0, 45) | 0;\r\n      H() | 0;\r\n      a: do { if (oa(p & 127) | 0) {\r\n        j = Qd(q | 0, i | 0, 52) | 0;\r\n        H() | 0;\r\n        j = j & 15;\r\n        if (j | 0) {\r\n          g = 1;\r\n          while (1) {\r\n            p = Rd(7, 0, (15 - g | 0) * 3 | 0) | 0;\r\n            if (!((p & q | 0) == 0 & ((H() | 0) & i | 0) == 0)) {\r\n              k = 33;\r\n              break a;\r\n            }\r\n            if (g >>> 0 < j >>> 0) { g = g + 1 | 0; }else { break; }\r\n          }\r\n        }\r\n        p = e;\r\n        b[p >> 2] = 0;\r\n        b[p + 4 >> 2] = 0;\r\n        if ((s | 0) > (d | 0)) {\r\n          p = c & -15728641;\r\n          o = s;\r\n          while (1) {\r\n            n = o;\r\n            o = o + -1 | 0;\r\n            if (o >>> 0 > 15 | (s | 0) < (o | 0)) {\r\n              k = 19;\r\n              break;\r\n            }\r\n            if ((s | 0) != (o | 0)) {\r\n              g = Rd(o | 0, 0, 52) | 0;\r\n              g = g | a;\r\n              j = H() | 0 | p;\r\n              if ((s | 0) < (n | 0)) { m = g; }else {\r\n                k = o;\r\n                do {\r\n                  m = Rd(7, 0, (14 - k | 0) * 3 | 0) | 0;\r\n                  k = k + 1 | 0;\r\n                  g = m | g;\r\n                  j = H() | 0 | j;\r\n                } while ((k | 0) < (s | 0));\r\n                m = g;\r\n              }\r\n            } else {\r\n              m = a;\r\n              j = c;\r\n            }\r\n            l = Qd(m | 0, j | 0, 45) | 0;\r\n            H() | 0;\r\n            if (!(oa(l & 127) | 0)) { g = 0; }else {\r\n              l = Qd(m | 0, j | 0, 52) | 0;\r\n              H() | 0;\r\n              l = l & 15;\r\n              b: do { if (!l) { g = 0; }else {\r\n                k = 1;\r\n                while (1) {\r\n                  g = Qd(m | 0, j | 0, (15 - k | 0) * 3 | 0) | 0;\r\n                  H() | 0;\r\n                  g = g & 7;\r\n                  if (g | 0) { break b; }\r\n                  if (k >>> 0 < l >>> 0) { k = k + 1 | 0; }else {\r\n                    g = 0;\r\n                    break;\r\n                  }\r\n                }\r\n              } } while (0);\r\n              g = (g | 0) == 0 & 1;\r\n            }\r\n            j = Qd(a | 0, c | 0, (15 - n | 0) * 3 | 0) | 0;\r\n            H() | 0;\r\n            j = j & 7;\r\n            if ((j | 0) == 7) {\r\n              f = 5;\r\n              k = 42;\r\n              break;\r\n            }\r\n            g = (g | 0) != 0;\r\n            if ((j | 0) == 1 & g) {\r\n              f = 5;\r\n              k = 42;\r\n              break;\r\n            }\r\n            m = j + (((j | 0) != 0 & g) << 31 >> 31) | 0;\r\n            if (m | 0) {\r\n              k = s - n | 0;\r\n              k = Oc(7, 0, k, ((k | 0) < 0) << 31 >> 31) | 0;\r\n              l = H() | 0;\r\n              if (g) {\r\n                g = Md(k | 0, l | 0, 5, 0) | 0;\r\n                g = Gd(g | 0, H() | 0, -5, -1) | 0;\r\n                g = Kd(g | 0, H() | 0, 6, 0) | 0;\r\n                g = Gd(g | 0, H() | 0, 1, 0) | 0;\r\n                j = H() | 0;\r\n              } else {\r\n                g = k;\r\n                j = l;\r\n              }\r\n              n = m + -1 | 0;\r\n              n = Md(k | 0, l | 0, n | 0, ((n | 0) < 0) << 31 >> 31 | 0) | 0;\r\n              n = Gd(g | 0, j | 0, n | 0, H() | 0) | 0;\r\n              m = H() | 0;\r\n              l = e;\r\n              l = Gd(n | 0, m | 0, b[l >> 2] | 0, b[l + 4 >> 2] | 0) | 0;\r\n              m = H() | 0;\r\n              n = e;\r\n              b[n >> 2] = l;\r\n              b[n + 4 >> 2] = m;\r\n            }\r\n            if ((o | 0) <= (d | 0)) {\r\n              k = 37;\r\n              break;\r\n            }\r\n          }\r\n          if ((k | 0) == 19) { I(27795, 27122, 1276, 27158); }else if ((k | 0) == 37) {\r\n            h = e;\r\n            f = b[h + 4 >> 2] | 0;\r\n            h = b[h >> 2] | 0;\r\n            break;\r\n          } else if ((k | 0) == 42) {\r\n            T = t;\r\n            return f | 0;\r\n          }\r\n        } else {\r\n          f = 0;\r\n          h = 0;\r\n        }\r\n      } else { k = 33; } } while (0);\r\n      c: do { if ((k | 0) == 33) {\r\n        p = e;\r\n        b[p >> 2] = 0;\r\n        b[p + 4 >> 2] = 0;\r\n        if ((s | 0) > (d | 0)) {\r\n          g = s;\r\n          while (1) {\r\n            f = Qd(a | 0, c | 0, (15 - g | 0) * 3 | 0) | 0;\r\n            H() | 0;\r\n            f = f & 7;\r\n            if ((f | 0) == 7) {\r\n              f = 5;\r\n              break;\r\n            }\r\n            h = s - g | 0;\r\n            h = Oc(7, 0, h, ((h | 0) < 0) << 31 >> 31) | 0;\r\n            f = Md(h | 0, H() | 0, f | 0, 0) | 0;\r\n            h = H() | 0;\r\n            p = e;\r\n            h = Gd(b[p >> 2] | 0, b[p + 4 >> 2] | 0, f | 0, h | 0) | 0;\r\n            f = H() | 0;\r\n            p = e;\r\n            b[p >> 2] = h;\r\n            b[p + 4 >> 2] = f;\r\n            g = g + -1 | 0;\r\n            if ((g | 0) <= (d | 0)) { break c; }\r\n          }\r\n          T = t;\r\n          return f | 0;\r\n        } else {\r\n          f = 0;\r\n          h = 0;\r\n        }\r\n      } } while (0);\r\n      if (Gb(q, i, s, r) | 0) { I(27795, 27122, 1236, 27173); }\r\n      s = r;\r\n      r = b[s + 4 >> 2] | 0;\r\n      if (((f | 0) > -1 | (f | 0) == -1 & h >>> 0 > 4294967295) & ((r | 0) > (f | 0) | ((r | 0) == (f | 0) ? (b[s >> 2] | 0) >>> 0 > h >>> 0 : 0))) {\r\n        s = 0;\r\n        T = t;\r\n        return s | 0;\r\n      } else { I(27795, 27122, 1316, 27158); }\r\n      return 0;\r\n    }\r\n    function ec(a, c, d, e, f, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0;\r\n      m = T;\r\n      T = T + 16 | 0;\r\n      h = m;\r\n      if (f >>> 0 > 15) {\r\n        g = 4;\r\n        T = m;\r\n        return g | 0;\r\n      }\r\n      i = Qd(d | 0, e | 0, 52) | 0;\r\n      H() | 0;\r\n      i = i & 15;\r\n      if ((i | 0) > (f | 0)) {\r\n        g = 12;\r\n        T = m;\r\n        return g | 0;\r\n      }\r\n      if (Gb(d, e, f, h) | 0) { I(27795, 27122, 1236, 27173); }\r\n      l = h;\r\n      k = b[l + 4 >> 2] | 0;\r\n      if (!(((c | 0) > -1 | (c | 0) == -1 & a >>> 0 > 4294967295) & ((k | 0) > (c | 0) | ((k | 0) == (c | 0) ? (b[l >> 2] | 0) >>> 0 > a >>> 0 : 0)))) {\r\n        g = 2;\r\n        T = m;\r\n        return g | 0;\r\n      }\r\n      l = f - i | 0;\r\n      f = Rd(f | 0, 0, 52) | 0;\r\n      j = H() | 0 | e & -15728641;\r\n      k = g;\r\n      b[k >> 2] = f | d;\r\n      b[k + 4 >> 2] = j;\r\n      k = Qd(d | 0, e | 0, 45) | 0;\r\n      H() | 0;\r\n      a: do { if (oa(k & 127) | 0) {\r\n        if (i | 0) {\r\n          h = 1;\r\n          while (1) {\r\n            k = Rd(7, 0, (15 - h | 0) * 3 | 0) | 0;\r\n            if (!((k & d | 0) == 0 & ((H() | 0) & e | 0) == 0)) { break a; }\r\n            if (h >>> 0 < i >>> 0) { h = h + 1 | 0; }else { break; }\r\n          }\r\n        }\r\n        if ((l | 0) < 1) {\r\n          g = 0;\r\n          T = m;\r\n          return g | 0;\r\n        }\r\n        k = i ^ 15;\r\n        e = -1;\r\n        j = 1;\r\n        h = 1;\r\n        while (1) {\r\n          i = l - j | 0;\r\n          i = Oc(7, 0, i, ((i | 0) < 0) << 31 >> 31) | 0;\r\n          d = H() | 0;\r\n          do { if (h) {\r\n            h = Md(i | 0, d | 0, 5, 0) | 0;\r\n            h = Gd(h | 0, H() | 0, -5, -1) | 0;\r\n            h = Kd(h | 0, H() | 0, 6, 0) | 0;\r\n            f = H() | 0;\r\n            if ((c | 0) > (f | 0) | (c | 0) == (f | 0) & a >>> 0 > h >>> 0) {\r\n              c = Gd(a | 0, c | 0, -1, -1) | 0;\r\n              c = Hd(c | 0, H() | 0, h | 0, f | 0) | 0;\r\n              h = H() | 0;\r\n              n = g;\r\n              p = b[n >> 2] | 0;\r\n              n = b[n + 4 >> 2] | 0;\r\n              q = (k + e | 0) * 3 | 0;\r\n              o = Rd(7, 0, q | 0) | 0;\r\n              n = n & ~(H() | 0);\r\n              e = Kd(c | 0, h | 0, i | 0, d | 0) | 0;\r\n              a = H() | 0;\r\n              f = Gd(e | 0, a | 0, 2, 0) | 0;\r\n              q = Rd(f | 0, H() | 0, q | 0) | 0;\r\n              n = H() | 0 | n;\r\n              f = g;\r\n              b[f >> 2] = q | p & ~o;\r\n              b[f + 4 >> 2] = n;\r\n              a = Md(e | 0, a | 0, i | 0, d | 0) | 0;\r\n              a = Hd(c | 0, h | 0, a | 0, H() | 0) | 0;\r\n              h = 0;\r\n              c = H() | 0;\r\n              break;\r\n            } else {\r\n              q = g;\r\n              o = b[q >> 2] | 0;\r\n              q = b[q + 4 >> 2] | 0;\r\n              p = Rd(7, 0, (k + e | 0) * 3 | 0) | 0;\r\n              q = q & ~(H() | 0);\r\n              h = g;\r\n              b[h >> 2] = o & ~p;\r\n              b[h + 4 >> 2] = q;\r\n              h = 1;\r\n              break;\r\n            }\r\n          } else {\r\n            o = g;\r\n            f = b[o >> 2] | 0;\r\n            o = b[o + 4 >> 2] | 0;\r\n            e = (k + e | 0) * 3 | 0;\r\n            n = Rd(7, 0, e | 0) | 0;\r\n            o = o & ~(H() | 0);\r\n            q = Kd(a | 0, c | 0, i | 0, d | 0) | 0;\r\n            h = H() | 0;\r\n            e = Rd(q | 0, h | 0, e | 0) | 0;\r\n            o = H() | 0 | o;\r\n            p = g;\r\n            b[p >> 2] = e | f & ~n;\r\n            b[p + 4 >> 2] = o;\r\n            h = Md(q | 0, h | 0, i | 0, d | 0) | 0;\r\n            a = Hd(a | 0, c | 0, h | 0, H() | 0) | 0;\r\n            h = 0;\r\n            c = H() | 0;\r\n          } } while (0);\r\n          if ((l | 0) > (j | 0)) {\r\n            e = ~j;\r\n            j = j + 1 | 0;\r\n          } else {\r\n            c = 0;\r\n            break;\r\n          }\r\n        }\r\n        T = m;\r\n        return c | 0;\r\n      } } while (0);\r\n      if ((l | 0) < 1) {\r\n        q = 0;\r\n        T = m;\r\n        return q | 0;\r\n      }\r\n      f = i ^ 15;\r\n      h = 1;\r\n      while (1) {\r\n        p = l - h | 0;\r\n        p = Oc(7, 0, p, ((p | 0) < 0) << 31 >> 31) | 0;\r\n        q = H() | 0;\r\n        j = g;\r\n        d = b[j >> 2] | 0;\r\n        j = b[j + 4 >> 2] | 0;\r\n        i = (f - h | 0) * 3 | 0;\r\n        e = Rd(7, 0, i | 0) | 0;\r\n        j = j & ~(H() | 0);\r\n        n = Kd(a | 0, c | 0, p | 0, q | 0) | 0;\r\n        o = H() | 0;\r\n        i = Rd(n | 0, o | 0, i | 0) | 0;\r\n        j = H() | 0 | j;\r\n        k = g;\r\n        b[k >> 2] = i | d & ~e;\r\n        b[k + 4 >> 2] = j;\r\n        q = Md(n | 0, o | 0, p | 0, q | 0) | 0;\r\n        a = Hd(a | 0, c | 0, q | 0, H() | 0) | 0;\r\n        c = H() | 0;\r\n        if ((l | 0) <= (h | 0)) {\r\n          c = 0;\r\n          break;\r\n        } else { h = h + 1 | 0; }\r\n      }\r\n      T = m;\r\n      return c | 0;\r\n    }\r\n    function fc(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      f = Qd(c | 0, d | 0, 52) | 0;\r\n      H() | 0;\r\n      f = f & 15;\r\n      if ((c | 0) == 0 & (d | 0) == 0 | ((e | 0) > 15 | (f | 0) > (e | 0))) {\r\n        g = -1;\r\n        c = -1;\r\n        d = 0;\r\n        f = 0;\r\n      } else {\r\n        c = Jb(c, d, f + 1 | 0, e) | 0;\r\n        h = (H() | 0) & -15728641;\r\n        d = Rd(e | 0, 0, 52) | 0;\r\n        d = c | d;\r\n        h = h | (H() | 0);\r\n        c = (Hb(d, h) | 0) == 0;\r\n        g = f;\r\n        c = c ? -1 : e;\r\n        f = h;\r\n      }\r\n      h = a;\r\n      b[h >> 2] = d;\r\n      b[h + 4 >> 2] = f;\r\n      b[a + 8 >> 2] = g;\r\n      b[a + 12 >> 2] = c;\r\n      return;\r\n    }\r\n    function gc(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0;\r\n      f = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      f = f & 15;\r\n      g = e + 8 | 0;\r\n      b[g >> 2] = f;\r\n      if ((a | 0) == 0 & (c | 0) == 0 | ((d | 0) > 15 | (f | 0) > (d | 0))) {\r\n        d = e;\r\n        b[d >> 2] = 0;\r\n        b[d + 4 >> 2] = 0;\r\n        b[g >> 2] = -1;\r\n        b[e + 12 >> 2] = -1;\r\n        return;\r\n      }\r\n      a = Jb(a, c, f + 1 | 0, d) | 0;\r\n      g = (H() | 0) & -15728641;\r\n      f = Rd(d | 0, 0, 52) | 0;\r\n      f = a | f;\r\n      g = g | (H() | 0);\r\n      a = e;\r\n      b[a >> 2] = f;\r\n      b[a + 4 >> 2] = g;\r\n      a = e + 12 | 0;\r\n      if (!(Hb(f, g) | 0)) {\r\n        b[a >> 2] = -1;\r\n        return;\r\n      } else {\r\n        b[a >> 2] = d;\r\n        return;\r\n      }\r\n    }\r\n    function hc(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      d = a;\r\n      c = b[d >> 2] | 0;\r\n      d = b[d + 4 >> 2] | 0;\r\n      if ((c | 0) == 0 & (d | 0) == 0) { return; }\r\n      e = Qd(c | 0, d | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      i = Rd(1, 0, (e ^ 15) * 3 | 0) | 0;\r\n      c = Gd(i | 0, H() | 0, c | 0, d | 0) | 0;\r\n      d = H() | 0;\r\n      i = a;\r\n      b[i >> 2] = c;\r\n      b[i + 4 >> 2] = d;\r\n      i = a + 8 | 0;\r\n      h = b[i >> 2] | 0;\r\n      if ((e | 0) < (h | 0)) { return; }\r\n      j = a + 12 | 0;\r\n      g = e;\r\n      while (1) {\r\n        if ((g | 0) == (h | 0)) {\r\n          e = 5;\r\n          break;\r\n        }\r\n        k = (g | 0) == (b[j >> 2] | 0);\r\n        f = (15 - g | 0) * 3 | 0;\r\n        e = Qd(c | 0, d | 0, f | 0) | 0;\r\n        H() | 0;\r\n        e = e & 7;\r\n        if (k & ((e | 0) == 1 & 0 == 0)) {\r\n          e = 7;\r\n          break;\r\n        }\r\n        if (!((e | 0) == 7 & 0 == 0)) {\r\n          e = 10;\r\n          break;\r\n        }\r\n        k = Rd(1, 0, f | 0) | 0;\r\n        c = Gd(c | 0, d | 0, k | 0, H() | 0) | 0;\r\n        d = H() | 0;\r\n        k = a;\r\n        b[k >> 2] = c;\r\n        b[k + 4 >> 2] = d;\r\n        if ((g | 0) > (h | 0)) { g = g + -1 | 0; }else {\r\n          e = 10;\r\n          break;\r\n        }\r\n      }\r\n      if ((e | 0) == 5) {\r\n        k = a;\r\n        b[k >> 2] = 0;\r\n        b[k + 4 >> 2] = 0;\r\n        b[i >> 2] = -1;\r\n        b[j >> 2] = -1;\r\n        return;\r\n      } else if ((e | 0) == 7) {\r\n        h = Rd(1, 0, f | 0) | 0;\r\n        h = Gd(c | 0, d | 0, h | 0, H() | 0) | 0;\r\n        i = H() | 0;\r\n        k = a;\r\n        b[k >> 2] = h;\r\n        b[k + 4 >> 2] = i;\r\n        b[j >> 2] = g + -1;\r\n        return;\r\n      } else if ((e | 0) == 10) { return; }\r\n    }\r\n    function ic(a) {\r\n      a = +a;\r\n      var b = 0.0;\r\n      b = a < 0.0 ? a + 6.283185307179586 : a;\r\n      return +(!(a >= 6.283185307179586) ? b : b + -6.283185307179586);\r\n    }\r\n    function jc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (!(+q(+(+e[a >> 3] - +e[b >> 3])) < 1.7453292519943298e-11)) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      b = +q(+(+e[a + 8 >> 3] - +e[b + 8 >> 3])) < 1.7453292519943298e-11;\r\n      return b | 0;\r\n    }\r\n    function kc(a, b) {\r\n      a = +a;\r\n      b = b | 0;\r\n      switch (b | 0) {\r\n        case 1:\r\n          {\r\n            a = a < 0.0 ? a + 6.283185307179586 : a;\r\n            break;\r\n          }\r\n        case 2:\r\n          {\r\n            a = a > 0.0 ? a + -6.283185307179586 : a;\r\n            break;\r\n          }\r\n        default:\r\n\r\n      }\r\n      return +a;\r\n    }\r\n    function lc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0;\r\n      f = +e[b >> 3];\r\n      d = +e[a >> 3];\r\n      g = +u(+((f - d) * .5));\r\n      c = +u(+((+e[b + 8 >> 3] - +e[a + 8 >> 3]) * .5));\r\n      c = g * g + c * (+t(+f) * +t(+d) * c);\r\n      return +(+z(+ +r(+c), + +r(+(1.0 - c))) * 2.0);\r\n    }\r\n    function mc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0;\r\n      f = +e[b >> 3];\r\n      d = +e[a >> 3];\r\n      g = +u(+((f - d) * .5));\r\n      c = +u(+((+e[b + 8 >> 3] - +e[a + 8 >> 3]) * .5));\r\n      c = g * g + c * (+t(+f) * +t(+d) * c);\r\n      return +(+z(+ +r(+c), + +r(+(1.0 - c))) * 2.0 * 6371.007180918475);\r\n    }\r\n    function nc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0;\r\n      f = +e[b >> 3];\r\n      d = +e[a >> 3];\r\n      g = +u(+((f - d) * .5));\r\n      c = +u(+((+e[b + 8 >> 3] - +e[a + 8 >> 3]) * .5));\r\n      c = g * g + c * (+t(+f) * +t(+d) * c);\r\n      return +(+z(+ +r(+c), + +r(+(1.0 - c))) * 2.0 * 6371.007180918475 * 1.0e3);\r\n    }\r\n    function oc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0;\r\n      g = +e[b >> 3];\r\n      d = +t(+g);\r\n      f = +e[b + 8 >> 3] - +e[a + 8 >> 3];\r\n      h = d * +u(+f);\r\n      c = +e[a >> 3];\r\n      return + +z(+h, +(+u(+g) * +t(+c) - +t(+f) * (d * +u(+c))));\r\n    }\r\n    function pc(a, c, d, f) {\r\n      a = a | 0;\r\n      c = +c;\r\n      d = +d;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0;\r\n      if (d < 1.0e-16) {\r\n        b[f >> 2] = b[a >> 2];\r\n        b[f + 4 >> 2] = b[a + 4 >> 2];\r\n        b[f + 8 >> 2] = b[a + 8 >> 2];\r\n        b[f + 12 >> 2] = b[a + 12 >> 2];\r\n        return;\r\n      }\r\n      h = c < 0.0 ? c + 6.283185307179586 : c;\r\n      h = !(c >= 6.283185307179586) ? h : h + -6.283185307179586;\r\n      do { if (h < 1.0e-16) {\r\n        c = +e[a >> 3] + d;\r\n        e[f >> 3] = c;\r\n        g = f;\r\n      } else {\r\n        g = +q(+(h + -3.141592653589793)) < 1.0e-16;\r\n        c = +e[a >> 3];\r\n        if (g) {\r\n          c = c - d;\r\n          e[f >> 3] = c;\r\n          g = f;\r\n          break;\r\n        }\r\n        i = +t(+d);\r\n        d = +u(+d);\r\n        c = i * +u(+c) + +t(+h) * (d * +t(+c));\r\n        c = c > 1.0 ? 1.0 : c;\r\n        c = +x(+(c < -1.0 ? -1.0 : c));\r\n        e[f >> 3] = c;\r\n        if (+q(+(c + -1.5707963267948966)) < 1.0e-16) {\r\n          e[f >> 3] = 1.5707963267948966;\r\n          e[f + 8 >> 3] = 0.0;\r\n          return;\r\n        }\r\n        if (+q(+(c + 1.5707963267948966)) < 1.0e-16) {\r\n          e[f >> 3] = -1.5707963267948966;\r\n          e[f + 8 >> 3] = 0.0;\r\n          return;\r\n        }\r\n        j = 1.0 / +t(+c);\r\n        h = d * +u(+h) * j;\r\n        d = +e[a >> 3];\r\n        c = j * ((i - +u(+c) * +u(+d)) / +t(+d));\r\n        i = h > 1.0 ? 1.0 : h;\r\n        c = c > 1.0 ? 1.0 : c;\r\n        c = +e[a + 8 >> 3] + +z(+(i < -1.0 ? -1.0 : i), +(c < -1.0 ? -1.0 : c));\r\n        if (c > 3.141592653589793) { do { c = c + -6.283185307179586; } while (c > 3.141592653589793); }\r\n        if (c < -3.141592653589793) { do { c = c + 6.283185307179586; } while (c < -3.141592653589793); }\r\n        e[f + 8 >> 3] = c;\r\n        return;\r\n      } } while (0);\r\n      if (+q(+(c + -1.5707963267948966)) < 1.0e-16) {\r\n        e[g >> 3] = 1.5707963267948966;\r\n        e[f + 8 >> 3] = 0.0;\r\n        return;\r\n      }\r\n      if (+q(+(c + 1.5707963267948966)) < 1.0e-16) {\r\n        e[g >> 3] = -1.5707963267948966;\r\n        e[f + 8 >> 3] = 0.0;\r\n        return;\r\n      }\r\n      c = +e[a + 8 >> 3];\r\n      if (c > 3.141592653589793) { do { c = c + -6.283185307179586; } while (c > 3.141592653589793); }\r\n      if (c < -3.141592653589793) { do { c = c + 6.283185307179586; } while (c < -3.141592653589793); }\r\n      e[f + 8 >> 3] = c;\r\n      return;\r\n    }\r\n    function qc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (a >>> 0 > 15) {\r\n        b = 4;\r\n        return b | 0;\r\n      }\r\n      e[b >> 3] = +e[20656 + (a << 3) >> 3];\r\n      b = 0;\r\n      return b | 0;\r\n    }\r\n    function rc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (a >>> 0 > 15) {\r\n        b = 4;\r\n        return b | 0;\r\n      }\r\n      e[b >> 3] = +e[20784 + (a << 3) >> 3];\r\n      b = 0;\r\n      return b | 0;\r\n    }\r\n    function sc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (a >>> 0 > 15) {\r\n        b = 4;\r\n        return b | 0;\r\n      }\r\n      e[b >> 3] = +e[20912 + (a << 3) >> 3];\r\n      b = 0;\r\n      return b | 0;\r\n    }\r\n    function tc(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (a >>> 0 > 15) {\r\n        b = 4;\r\n        return b | 0;\r\n      }\r\n      e[b >> 3] = +e[21040 + (a << 3) >> 3];\r\n      b = 0;\r\n      return b | 0;\r\n    }\r\n    function uc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0;\r\n      if (a >>> 0 > 15) {\r\n        c = 4;\r\n        return c | 0;\r\n      }\r\n      d = Oc(7, 0, a, ((a | 0) < 0) << 31 >> 31) | 0;\r\n      d = Md(d | 0, H() | 0, 120, 0) | 0;\r\n      a = H() | 0;\r\n      b[c >> 2] = d | 2;\r\n      b[c + 4 >> 2] = a;\r\n      c = 0;\r\n      return c | 0;\r\n    }\r\n    function vc(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      var d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0,\r\n        n = 0.0;\r\n      n = +e[b >> 3];\r\n      l = +e[a >> 3];\r\n      j = +u(+((n - l) * .5));\r\n      g = +e[b + 8 >> 3];\r\n      k = +e[a + 8 >> 3];\r\n      h = +u(+((g - k) * .5));\r\n      i = +t(+l);\r\n      m = +t(+n);\r\n      h = j * j + h * (m * i * h);\r\n      h = +z(+ +r(+h), + +r(+(1.0 - h))) * 2.0;\r\n      j = +e[c >> 3];\r\n      n = +u(+((j - n) * .5));\r\n      d = +e[c + 8 >> 3];\r\n      g = +u(+((d - g) * .5));\r\n      f = +t(+j);\r\n      g = n * n + g * (m * f * g);\r\n      g = +z(+ +r(+g), + +r(+(1.0 - g))) * 2.0;\r\n      j = +u(+((l - j) * .5));\r\n      d = +u(+((k - d) * .5));\r\n      d = j * j + d * (i * f * d);\r\n      d = +z(+ +r(+d), + +r(+(1.0 - d))) * 2.0;\r\n      f = (h + g + d) * .5;\r\n      return +(+y(+ +r(+(+v(+(f * .5)) * +v(+((f - h) * .5)) * +v(+((f - g) * .5)) * +v(+((f - d) * .5))))) * 4.0);\r\n    }\r\n    function wc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 192 | 0;\r\n      h = j + 168 | 0;\r\n      i = j;\r\n      g = Zb(a, c, h) | 0;\r\n      if (g | 0) {\r\n        d = g;\r\n        T = j;\r\n        return d | 0;\r\n      }\r\n      if (_b(a, c, i) | 0) { I(27795, 27190, 415, 27199); }\r\n      c = b[i >> 2] | 0;\r\n      if ((c | 0) > 0) {\r\n        f = +vc(i + 8 | 0, i + 8 + (((c | 0) != 1 & 1) << 4) | 0, h) + 0.0;\r\n        if ((c | 0) != 1) {\r\n          a = 1;\r\n          do {\r\n            g = a;\r\n            a = a + 1 | 0;\r\n            f = f + +vc(i + 8 + (g << 4) | 0, i + 8 + (((a | 0) % (c | 0) | 0) << 4) | 0, h);\r\n          } while ((a | 0) < (c | 0));\r\n        }\r\n      } else { f = 0.0; }\r\n      e[d >> 3] = f;\r\n      d = 0;\r\n      T = j;\r\n      return d | 0;\r\n    }\r\n    function xc(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      a = wc(a, b, c) | 0;\r\n      if (a | 0) { return a | 0; }\r\n      e[c >> 3] = +e[c >> 3] * 6371.007180918475 * 6371.007180918475;\r\n      return a | 0;\r\n    }\r\n    function yc(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      a = wc(a, b, c) | 0;\r\n      if (a | 0) { return a | 0; }\r\n      e[c >> 3] = +e[c >> 3] * 6371.007180918475 * 6371.007180918475 * 1.0e3 * 1.0e3;\r\n      return a | 0;\r\n    }\r\n    function zc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0;\r\n      j = T;\r\n      T = T + 176 | 0;\r\n      i = j;\r\n      a = pb(a, c, i) | 0;\r\n      if (a | 0) {\r\n        i = a;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      e[d >> 3] = 0.0;\r\n      a = b[i >> 2] | 0;\r\n      if ((a | 0) <= 1) {\r\n        i = 0;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      c = a + -1 | 0;\r\n      a = 0;\r\n      f = +e[i + 8 >> 3];\r\n      g = +e[i + 16 >> 3];\r\n      h = 0.0;\r\n      do {\r\n        a = a + 1 | 0;\r\n        l = f;\r\n        f = +e[i + 8 + (a << 4) >> 3];\r\n        m = +u(+((f - l) * .5));\r\n        k = g;\r\n        g = +e[i + 8 + (a << 4) + 8 >> 3];\r\n        k = +u(+((g - k) * .5));\r\n        k = m * m + k * (+t(+f) * +t(+l) * k);\r\n        h = h + +z(+ +r(+k), + +r(+(1.0 - k))) * 2.0;\r\n      } while ((a | 0) < (c | 0));\r\n      e[d >> 3] = h;\r\n      i = 0;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Ac(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0;\r\n      j = T;\r\n      T = T + 176 | 0;\r\n      i = j;\r\n      a = pb(a, c, i) | 0;\r\n      if (a | 0) {\r\n        i = a;\r\n        h = +e[d >> 3];\r\n        h = h * 6371.007180918475;\r\n        e[d >> 3] = h;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      e[d >> 3] = 0.0;\r\n      a = b[i >> 2] | 0;\r\n      if ((a | 0) <= 1) {\r\n        i = 0;\r\n        h = 0.0;\r\n        h = h * 6371.007180918475;\r\n        e[d >> 3] = h;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      c = a + -1 | 0;\r\n      a = 0;\r\n      f = +e[i + 8 >> 3];\r\n      g = +e[i + 16 >> 3];\r\n      h = 0.0;\r\n      do {\r\n        a = a + 1 | 0;\r\n        l = f;\r\n        f = +e[i + 8 + (a << 4) >> 3];\r\n        m = +u(+((f - l) * .5));\r\n        k = g;\r\n        g = +e[i + 8 + (a << 4) + 8 >> 3];\r\n        k = +u(+((g - k) * .5));\r\n        k = m * m + k * (+t(+l) * +t(+f) * k);\r\n        h = h + +z(+ +r(+k), + +r(+(1.0 - k))) * 2.0;\r\n      } while ((a | 0) != (c | 0));\r\n      e[d >> 3] = h;\r\n      i = 0;\r\n      m = h;\r\n      m = m * 6371.007180918475;\r\n      e[d >> 3] = m;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Bc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0;\r\n      j = T;\r\n      T = T + 176 | 0;\r\n      i = j;\r\n      a = pb(a, c, i) | 0;\r\n      if (a | 0) {\r\n        i = a;\r\n        h = +e[d >> 3];\r\n        h = h * 6371.007180918475;\r\n        h = h * 1.0e3;\r\n        e[d >> 3] = h;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      e[d >> 3] = 0.0;\r\n      a = b[i >> 2] | 0;\r\n      if ((a | 0) <= 1) {\r\n        i = 0;\r\n        h = 0.0;\r\n        h = h * 6371.007180918475;\r\n        h = h * 1.0e3;\r\n        e[d >> 3] = h;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      c = a + -1 | 0;\r\n      a = 0;\r\n      f = +e[i + 8 >> 3];\r\n      g = +e[i + 16 >> 3];\r\n      h = 0.0;\r\n      do {\r\n        a = a + 1 | 0;\r\n        l = f;\r\n        f = +e[i + 8 + (a << 4) >> 3];\r\n        m = +u(+((f - l) * .5));\r\n        k = g;\r\n        g = +e[i + 8 + (a << 4) + 8 >> 3];\r\n        k = +u(+((g - k) * .5));\r\n        k = m * m + k * (+t(+l) * +t(+f) * k);\r\n        h = h + +z(+ +r(+k), + +r(+(1.0 - k))) * 2.0;\r\n      } while ((a | 0) != (c | 0));\r\n      e[d >> 3] = h;\r\n      i = 0;\r\n      m = h;\r\n      m = m * 6371.007180918475;\r\n      m = m * 1.0e3;\r\n      e[d >> 3] = m;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Cc(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      c = Fd(1, 12) | 0;\r\n      if (!c) { I(27280, 27235, 49, 27293); }\r\n      d = a + 4 | 0;\r\n      e = b[d >> 2] | 0;\r\n      if (e | 0) {\r\n        e = e + 8 | 0;\r\n        b[e >> 2] = c;\r\n        b[d >> 2] = c;\r\n        return c | 0;\r\n      }\r\n      if (b[a >> 2] | 0) { I(27310, 27235, 61, 27333); }\r\n      e = a;\r\n      b[e >> 2] = c;\r\n      b[d >> 2] = c;\r\n      return c | 0;\r\n    }\r\n    function Dc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0;\r\n      e = Dd(24) | 0;\r\n      if (!e) { I(27347, 27235, 78, 27361); }\r\n      b[e >> 2] = b[c >> 2];\r\n      b[e + 4 >> 2] = b[c + 4 >> 2];\r\n      b[e + 8 >> 2] = b[c + 8 >> 2];\r\n      b[e + 12 >> 2] = b[c + 12 >> 2];\r\n      b[e + 16 >> 2] = 0;\r\n      c = a + 4 | 0;\r\n      d = b[c >> 2] | 0;\r\n      if (d | 0) {\r\n        b[d + 16 >> 2] = e;\r\n        b[c >> 2] = e;\r\n        return e | 0;\r\n      }\r\n      if (b[a >> 2] | 0) { I(27376, 27235, 82, 27361); }\r\n      b[a >> 2] = e;\r\n      b[c >> 2] = e;\r\n      return e | 0;\r\n    }\r\n    function Ec(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0;\r\n      if (!a) { return; }\r\n      e = 1;\r\n      while (1) {\r\n        c = b[a >> 2] | 0;\r\n        if (c | 0) { do {\r\n          d = b[c >> 2] | 0;\r\n          if (d | 0) { do {\r\n            f = d;\r\n            d = b[d + 16 >> 2] | 0;\r\n            Ed(f);\r\n          } while ((d | 0) != 0); }\r\n          f = c;\r\n          c = b[c + 8 >> 2] | 0;\r\n          Ed(f);\r\n        } while ((c | 0) != 0); }\r\n        c = a;\r\n        a = b[a + 8 >> 2] | 0;\r\n        if (!e) { Ed(c); }\r\n        if (!a) { break; }else { e = 0; }\r\n      }\r\n      return;\r\n    }\r\n    function Fc(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0.0,\r\n        i = 0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        r = 0,\r\n        s = 0.0,\r\n        t = 0.0,\r\n        u = 0.0,\r\n        v = 0.0,\r\n        w = 0.0,\r\n        x = 0.0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0,\r\n        B = 0,\r\n        C = 0,\r\n        D = 0,\r\n        E = 0,\r\n        F = 0,\r\n        G = 0,\r\n        H = 0,\r\n        J = 0,\r\n        K = 0;\r\n      g = a + 8 | 0;\r\n      if (b[g >> 2] | 0) {\r\n        K = 1;\r\n        return K | 0;\r\n      }\r\n      f = b[a >> 2] | 0;\r\n      if (!f) {\r\n        K = 0;\r\n        return K | 0;\r\n      }\r\n      c = f;\r\n      d = 0;\r\n      do {\r\n        d = d + 1 | 0;\r\n        c = b[c + 8 >> 2] | 0;\r\n      } while ((c | 0) != 0);\r\n      if (d >>> 0 < 2) {\r\n        K = 0;\r\n        return K | 0;\r\n      }\r\n      H = Dd(d << 2) | 0;\r\n      if (!H) { I(27396, 27235, 317, 27415); }\r\n      G = Dd(d << 5) | 0;\r\n      if (!G) { I(27437, 27235, 321, 27415); }\r\n      b[a >> 2] = 0;\r\n      z = a + 4 | 0;\r\n      b[z >> 2] = 0;\r\n      b[g >> 2] = 0;\r\n      d = 0;\r\n      F = 0;\r\n      y = 0;\r\n      n = 0;\r\n      a: while (1) {\r\n        m = b[f >> 2] | 0;\r\n        if (m) {\r\n          h = 0.0;\r\n          i = m;\r\n          do {\r\n            k = +e[i + 8 >> 3];\r\n            c = i;\r\n            i = b[i + 16 >> 2] | 0;\r\n            l = (i | 0) == 0;\r\n            g = l ? m : i;\r\n            j = +e[g + 8 >> 3];\r\n            if (+q(+(k - j)) > 3.141592653589793) {\r\n              K = 14;\r\n              break;\r\n            }\r\n            h = h + (j - k) * (+e[c >> 3] + +e[g >> 3]);\r\n          } while (!l);\r\n          if ((K | 0) == 14) {\r\n            K = 0;\r\n            h = 0.0;\r\n            c = m;\r\n            do {\r\n              x = +e[c + 8 >> 3];\r\n              E = c + 16 | 0;\r\n              D = b[E >> 2] | 0;\r\n              D = (D | 0) == 0 ? m : D;\r\n              w = +e[D + 8 >> 3];\r\n              h = h + (+e[c >> 3] + +e[D >> 3]) * ((w < 0.0 ? w + 6.283185307179586 : w) - (x < 0.0 ? x + 6.283185307179586 : x));\r\n              c = b[((c | 0) == 0 ? f : E) >> 2] | 0;\r\n            } while ((c | 0) != 0);\r\n          }\r\n          if (h > 0.0) {\r\n            b[H + (F << 2) >> 2] = f;\r\n            F = F + 1 | 0;\r\n            g = y;\r\n            c = n;\r\n          } else { K = 19; }\r\n        } else { K = 19; }\r\n        if ((K | 0) == 19) {\r\n          K = 0;\r\n          do { if (!d) {\r\n            if (!n) {\r\n              if (!(b[a >> 2] | 0)) {\r\n                g = z;\r\n                i = a;\r\n                c = f;\r\n                d = a;\r\n                break;\r\n              } else {\r\n                K = 27;\r\n                break a;\r\n              }\r\n            } else {\r\n              g = z;\r\n              i = n + 8 | 0;\r\n              c = f;\r\n              d = a;\r\n              break;\r\n            }\r\n          } else {\r\n            c = d + 8 | 0;\r\n            if (b[c >> 2] | 0) {\r\n              K = 21;\r\n              break a;\r\n            }\r\n            d = Fd(1, 12) | 0;\r\n            if (!d) {\r\n              K = 23;\r\n              break a;\r\n            }\r\n            b[c >> 2] = d;\r\n            g = d + 4 | 0;\r\n            i = d;\r\n            c = n;\r\n          } } while (0);\r\n          b[i >> 2] = f;\r\n          b[g >> 2] = f;\r\n          i = G + (y << 5) | 0;\r\n          l = b[f >> 2] | 0;\r\n          if (l) {\r\n            m = G + (y << 5) + 8 | 0;\r\n            e[m >> 3] = 1797693134862315708145274.0e284;\r\n            n = G + (y << 5) + 24 | 0;\r\n            e[n >> 3] = 1797693134862315708145274.0e284;\r\n            e[i >> 3] = -1797693134862315708145274.0e284;\r\n            o = G + (y << 5) + 16 | 0;\r\n            e[o >> 3] = -1797693134862315708145274.0e284;\r\n            u = 1797693134862315708145274.0e284;\r\n            v = -1797693134862315708145274.0e284;\r\n            g = 0;\r\n            p = l;\r\n            k = 1797693134862315708145274.0e284;\r\n            s = 1797693134862315708145274.0e284;\r\n            t = -1797693134862315708145274.0e284;\r\n            j = -1797693134862315708145274.0e284;\r\n            while (1) {\r\n              h = +e[p >> 3];\r\n              x = +e[p + 8 >> 3];\r\n              p = b[p + 16 >> 2] | 0;\r\n              r = (p | 0) == 0;\r\n              w = +e[(r ? l : p) + 8 >> 3];\r\n              if (h < k) {\r\n                e[m >> 3] = h;\r\n                k = h;\r\n              }\r\n              if (x < s) {\r\n                e[n >> 3] = x;\r\n                s = x;\r\n              }\r\n              if (h > t) { e[i >> 3] = h; }else { h = t; }\r\n              if (x > j) {\r\n                e[o >> 3] = x;\r\n                j = x;\r\n              }\r\n              u = x > 0.0 & x < u ? x : u;\r\n              v = x < 0.0 & x > v ? x : v;\r\n              g = g | +q(+(x - w)) > 3.141592653589793;\r\n              if (r) { break; }else { t = h; }\r\n            }\r\n            if (g) {\r\n              e[o >> 3] = v;\r\n              e[n >> 3] = u;\r\n            }\r\n          } else {\r\n            b[i >> 2] = 0;\r\n            b[i + 4 >> 2] = 0;\r\n            b[i + 8 >> 2] = 0;\r\n            b[i + 12 >> 2] = 0;\r\n            b[i + 16 >> 2] = 0;\r\n            b[i + 20 >> 2] = 0;\r\n            b[i + 24 >> 2] = 0;\r\n            b[i + 28 >> 2] = 0;\r\n          }\r\n          g = y + 1 | 0;\r\n        }\r\n        E = f + 8 | 0;\r\n        f = b[E >> 2] | 0;\r\n        b[E >> 2] = 0;\r\n        if (!f) {\r\n          K = 45;\r\n          break;\r\n        } else {\r\n          y = g;\r\n          n = c;\r\n        }\r\n      }\r\n      if ((K | 0) == 21) { I(27213, 27235, 35, 27247); }else if ((K | 0) == 23) { I(27267, 27235, 37, 27247); }else if ((K | 0) == 27) { I(27310, 27235, 61, 27333); }else if ((K | 0) == 45) {\r\n        b: do { if ((F | 0) > 0) {\r\n          E = (g | 0) == 0;\r\n          C = g << 2;\r\n          D = (a | 0) == 0;\r\n          B = 0;\r\n          c = 0;\r\n          while (1) {\r\n            A = b[H + (B << 2) >> 2] | 0;\r\n            if (!E) {\r\n              y = Dd(C) | 0;\r\n              if (!y) {\r\n                K = 50;\r\n                break;\r\n              }\r\n              z = Dd(C) | 0;\r\n              if (!z) {\r\n                K = 52;\r\n                break;\r\n              }\r\n              c: do { if (!D) {\r\n                g = 0;\r\n                d = 0;\r\n                i = a;\r\n                while (1) {\r\n                  f = G + (g << 5) | 0;\r\n                  if (Gc(b[i >> 2] | 0, f, b[A >> 2] | 0) | 0) {\r\n                    b[y + (d << 2) >> 2] = i;\r\n                    b[z + (d << 2) >> 2] = f;\r\n                    r = d + 1 | 0;\r\n                  } else { r = d; }\r\n                  i = b[i + 8 >> 2] | 0;\r\n                  if (!i) { break; }else {\r\n                    g = g + 1 | 0;\r\n                    d = r;\r\n                  }\r\n                }\r\n                if ((r | 0) > 0) {\r\n                  f = b[y >> 2] | 0;\r\n                  if ((r | 0) == 1) { d = f; }else {\r\n                    o = 0;\r\n                    p = -1;\r\n                    d = f;\r\n                    n = f;\r\n                    while (1) {\r\n                      l = b[n >> 2] | 0;\r\n                      f = 0;\r\n                      i = 0;\r\n                      while (1) {\r\n                        g = b[b[y + (i << 2) >> 2] >> 2] | 0;\r\n                        if ((g | 0) == (l | 0)) { m = f; }else { m = f + ((Gc(g, b[z + (i << 2) >> 2] | 0, b[l >> 2] | 0) | 0) & 1) | 0; }\r\n                        i = i + 1 | 0;\r\n                        if ((i | 0) == (r | 0)) { break; }else { f = m; }\r\n                      }\r\n                      g = (m | 0) > (p | 0);\r\n                      d = g ? n : d;\r\n                      f = o + 1 | 0;\r\n                      if ((f | 0) == (r | 0)) { break c; }\r\n                      o = f;\r\n                      p = g ? m : p;\r\n                      n = b[y + (f << 2) >> 2] | 0;\r\n                    }\r\n                  }\r\n                } else { d = 0; }\r\n              } else { d = 0; } } while (0);\r\n              Ed(y);\r\n              Ed(z);\r\n              if (d) {\r\n                g = d + 4 | 0;\r\n                f = b[g >> 2] | 0;\r\n                if (!f) {\r\n                  if (b[d >> 2] | 0) {\r\n                    K = 70;\r\n                    break;\r\n                  }\r\n                } else { d = f + 8 | 0; }\r\n                b[d >> 2] = A;\r\n                b[g >> 2] = A;\r\n              } else { K = 73; }\r\n            } else { K = 73; }\r\n            if ((K | 0) == 73) {\r\n              K = 0;\r\n              c = b[A >> 2] | 0;\r\n              if (c | 0) { do {\r\n                z = c;\r\n                c = b[c + 16 >> 2] | 0;\r\n                Ed(z);\r\n              } while ((c | 0) != 0); }\r\n              Ed(A);\r\n              c = 1;\r\n            }\r\n            B = B + 1 | 0;\r\n            if ((B | 0) >= (F | 0)) {\r\n              J = c;\r\n              break b;\r\n            }\r\n          }\r\n          if ((K | 0) == 50) { I(27452, 27235, 249, 27471); }else if ((K | 0) == 52) { I(27490, 27235, 252, 27471); }else if ((K | 0) == 70) { I(27310, 27235, 61, 27333); }\r\n        } else { J = 0; } } while (0);\r\n        Ed(H);\r\n        Ed(G);\r\n        K = J;\r\n        return K | 0;\r\n      }\r\n      return 0;\r\n    }\r\n    function Gc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0;\r\n      if (!(Ca(c, d) | 0)) {\r\n        a = 0;\r\n        return a | 0;\r\n      }\r\n      c = Aa(c) | 0;\r\n      f = +e[d >> 3];\r\n      g = +e[d + 8 >> 3];\r\n      g = c & g < 0.0 ? g + 6.283185307179586 : g;\r\n      a = b[a >> 2] | 0;\r\n      if (!a) {\r\n        a = 0;\r\n        return a | 0;\r\n      }\r\n      if (c) {\r\n        c = 0;\r\n        l = g;\r\n        d = a;\r\n        a: while (1) {\r\n          while (1) {\r\n            i = +e[d >> 3];\r\n            g = +e[d + 8 >> 3];\r\n            d = d + 16 | 0;\r\n            m = b[d >> 2] | 0;\r\n            m = (m | 0) == 0 ? a : m;\r\n            h = +e[m >> 3];\r\n            j = +e[m + 8 >> 3];\r\n            if (i > h) {\r\n              k = i;\r\n              i = j;\r\n            } else {\r\n              k = h;\r\n              h = i;\r\n              i = g;\r\n              g = j;\r\n            }\r\n            f = f == h | f == k ? f + 2.220446049250313e-16 : f;\r\n            if (!(f < h | f > k)) { break; }\r\n            d = b[d >> 2] | 0;\r\n            if (!d) {\r\n              d = 22;\r\n              break a;\r\n            }\r\n          }\r\n          j = i < 0.0 ? i + 6.283185307179586 : i;\r\n          i = g < 0.0 ? g + 6.283185307179586 : g;\r\n          l = j == l | i == l ? l + -2.220446049250313e-16 : l;\r\n          k = j + (i - j) * ((f - h) / (k - h));\r\n          if ((k < 0.0 ? k + 6.283185307179586 : k) > l) { c = c ^ 1; }\r\n          d = b[d >> 2] | 0;\r\n          if (!d) {\r\n            d = 22;\r\n            break;\r\n          }\r\n        }\r\n        if ((d | 0) == 22) { return c | 0; }\r\n      } else {\r\n        c = 0;\r\n        l = g;\r\n        d = a;\r\n        b: while (1) {\r\n          while (1) {\r\n            i = +e[d >> 3];\r\n            g = +e[d + 8 >> 3];\r\n            d = d + 16 | 0;\r\n            m = b[d >> 2] | 0;\r\n            m = (m | 0) == 0 ? a : m;\r\n            h = +e[m >> 3];\r\n            j = +e[m + 8 >> 3];\r\n            if (i > h) {\r\n              k = i;\r\n              i = j;\r\n            } else {\r\n              k = h;\r\n              h = i;\r\n              i = g;\r\n              g = j;\r\n            }\r\n            f = f == h | f == k ? f + 2.220446049250313e-16 : f;\r\n            if (!(f < h | f > k)) { break; }\r\n            d = b[d >> 2] | 0;\r\n            if (!d) {\r\n              d = 22;\r\n              break b;\r\n            }\r\n          }\r\n          l = i == l | g == l ? l + -2.220446049250313e-16 : l;\r\n          if (i + (g - i) * ((f - h) / (k - h)) > l) { c = c ^ 1; }\r\n          d = b[d >> 2] | 0;\r\n          if (!d) {\r\n            d = 22;\r\n            break;\r\n          }\r\n        }\r\n        if ((d | 0) == 22) { return c | 0; }\r\n      }\r\n      return 0;\r\n    }\r\n    function Hc(c, d, e, f, g) {\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0;\r\n      u = T;\r\n      T = T + 32 | 0;\r\n      t = u + 16 | 0;\r\n      s = u;\r\n      h = Qd(c | 0, d | 0, 52) | 0;\r\n      H() | 0;\r\n      h = h & 15;\r\n      p = Qd(e | 0, f | 0, 52) | 0;\r\n      H() | 0;\r\n      if ((h | 0) != (p & 15 | 0)) {\r\n        t = 12;\r\n        T = u;\r\n        return t | 0;\r\n      }\r\n      l = Qd(c | 0, d | 0, 45) | 0;\r\n      H() | 0;\r\n      l = l & 127;\r\n      m = Qd(e | 0, f | 0, 45) | 0;\r\n      H() | 0;\r\n      m = m & 127;\r\n      if (l >>> 0 > 121 | m >>> 0 > 121) {\r\n        t = 5;\r\n        T = u;\r\n        return t | 0;\r\n      }\r\n      p = (l | 0) != (m | 0);\r\n      if (p) {\r\n        j = wa(l, m) | 0;\r\n        if ((j | 0) == 7) {\r\n          t = 1;\r\n          T = u;\r\n          return t | 0;\r\n        }\r\n        k = wa(m, l) | 0;\r\n        if ((k | 0) == 7) { I(27514, 27538, 161, 27548); }else {\r\n          q = j;\r\n          i = k;\r\n        }\r\n      } else {\r\n        q = 0;\r\n        i = 0;\r\n      }\r\n      n = oa(l) | 0;\r\n      o = oa(m) | 0;\r\n      b[t >> 2] = 0;\r\n      b[t + 4 >> 2] = 0;\r\n      b[t + 8 >> 2] = 0;\r\n      b[t + 12 >> 2] = 0;\r\n      do { if (!q) {\r\n        Xb(e, f, t) | 0;\r\n        if ((n | 0) != 0 & (o | 0) != 0) {\r\n          if ((m | 0) != (l | 0)) { I(27621, 27538, 261, 27548); }\r\n          i = Pb(c, d) | 0;\r\n          h = Pb(e, f) | 0;\r\n          if (!((i | 0) == 7 | (h | 0) == 7)) {\r\n            if (!(a[22e3 + (i * 7 | 0) + h >> 0] | 0)) {\r\n              i = b[21168 + (i * 28 | 0) + (h << 2) >> 2] | 0;\r\n              if ((i | 0) > 0) {\r\n                j = t + 4 | 0;\r\n                h = 0;\r\n                do {\r\n                  _a(j);\r\n                  h = h + 1 | 0;\r\n                } while ((h | 0) != (i | 0));\r\n                r = 51;\r\n              } else { r = 51; }\r\n            } else { h = 1; }\r\n          } else { h = 5; }\r\n        } else { r = 51; }\r\n      } else {\r\n        m = b[4272 + (l * 28 | 0) + (q << 2) >> 2] | 0;\r\n        j = (m | 0) > 0;\r\n        if (!o) {\r\n          if (j) {\r\n            l = 0;\r\n            k = e;\r\n            j = f;\r\n            do {\r\n              k = Tb(k, j) | 0;\r\n              j = H() | 0;\r\n              i = ab(i) | 0;\r\n              l = l + 1 | 0;\r\n            } while ((l | 0) != (m | 0));\r\n            m = i;\r\n            l = k;\r\n            k = j;\r\n          } else {\r\n            m = i;\r\n            l = e;\r\n            k = f;\r\n          }\r\n        } else if (j) {\r\n          l = 0;\r\n          k = e;\r\n          j = f;\r\n          do {\r\n            k = Sb(k, j) | 0;\r\n            j = H() | 0;\r\n            i = ab(i) | 0;\r\n            if ((i | 0) == 1) { i = ab(1) | 0; }\r\n            l = l + 1 | 0;\r\n          } while ((l | 0) != (m | 0));\r\n          m = i;\r\n          l = k;\r\n          k = j;\r\n        } else {\r\n          m = i;\r\n          l = e;\r\n          k = f;\r\n        }\r\n        Xb(l, k, t) | 0;\r\n        if (!p) { I(27563, 27538, 191, 27548); }\r\n        j = (n | 0) != 0;\r\n        i = (o | 0) != 0;\r\n        if (j & i) { I(27590, 27538, 192, 27548); }\r\n        if (!j) {\r\n          if (i) {\r\n            i = Pb(l, k) | 0;\r\n            if ((i | 0) == 7) {\r\n              h = 5;\r\n              break;\r\n            }\r\n            if (a[22e3 + (i * 7 | 0) + m >> 0] | 0) {\r\n              h = 1;\r\n              break;\r\n            }\r\n            l = 0;\r\n            k = b[21168 + (m * 28 | 0) + (i << 2) >> 2] | 0;\r\n          } else {\r\n            l = 0;\r\n            k = 0;\r\n          }\r\n        } else {\r\n          i = Pb(c, d) | 0;\r\n          if ((i | 0) == 7) {\r\n            h = 5;\r\n            break;\r\n          }\r\n          if (a[22e3 + (i * 7 | 0) + q >> 0] | 0) {\r\n            h = 1;\r\n            break;\r\n          }\r\n          k = b[21168 + (i * 28 | 0) + (q << 2) >> 2] | 0;\r\n          l = k;\r\n        }\r\n        if ((l | k | 0) < 0) { h = 5; }else {\r\n          if ((k | 0) > 0) {\r\n            j = t + 4 | 0;\r\n            i = 0;\r\n            do {\r\n              _a(j);\r\n              i = i + 1 | 0;\r\n            } while ((i | 0) != (k | 0));\r\n          }\r\n          b[s >> 2] = 0;\r\n          b[s + 4 >> 2] = 0;\r\n          b[s + 8 >> 2] = 0;\r\n          Ya(s, q);\r\n          if (h | 0) { while (1) {\r\n            if (!(Vb(h) | 0)) { Xa(s); }else { Wa(s); }\r\n            if ((h | 0) > 1) { h = h + -1 | 0; }else { break; }\r\n          } }\r\n          if ((l | 0) > 0) {\r\n            h = 0;\r\n            do {\r\n              _a(s);\r\n              h = h + 1 | 0;\r\n            } while ((h | 0) != (l | 0));\r\n          }\r\n          r = t + 4 | 0;\r\n          Oa(r, s, r);\r\n          Ma(r);\r\n          r = 51;\r\n        }\r\n      } } while (0);\r\n      if ((r | 0) == 51) {\r\n        h = t + 4 | 0;\r\n        b[g >> 2] = b[h >> 2];\r\n        b[g + 4 >> 2] = b[h + 4 >> 2];\r\n        b[g + 8 >> 2] = b[h + 8 >> 2];\r\n        h = 0;\r\n      }\r\n      t = h;\r\n      T = u;\r\n      return t | 0;\r\n    }\r\n    function Ic(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0;\r\n      q = T;\r\n      T = T + 48 | 0;\r\n      k = q + 36 | 0;\r\n      h = q + 24 | 0;\r\n      i = q + 12 | 0;\r\n      j = q;\r\n      f = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      f = f & 15;\r\n      n = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      n = n & 127;\r\n      if (n >>> 0 > 121) {\r\n        e = 5;\r\n        T = q;\r\n        return e | 0;\r\n      }\r\n      l = oa(n) | 0;\r\n      Rd(f | 0, 0, 52) | 0;\r\n      r = H() | 0 | 134225919;\r\n      g = e;\r\n      b[g >> 2] = -1;\r\n      b[g + 4 >> 2] = r;\r\n      if (!f) {\r\n        f = Ra(d) | 0;\r\n        if ((f | 0) == 7) {\r\n          r = 1;\r\n          T = q;\r\n          return r | 0;\r\n        }\r\n        f = va(n, f) | 0;\r\n        if ((f | 0) == 127) {\r\n          r = 1;\r\n          T = q;\r\n          return r | 0;\r\n        }\r\n        o = Rd(f | 0, 0, 45) | 0;\r\n        p = H() | 0;\r\n        n = e;\r\n        p = b[n + 4 >> 2] & -1040385 | p;\r\n        r = e;\r\n        b[r >> 2] = b[n >> 2] | o;\r\n        b[r + 4 >> 2] = p;\r\n        r = 0;\r\n        T = q;\r\n        return r | 0;\r\n      }\r\n      b[k >> 2] = b[d >> 2];\r\n      b[k + 4 >> 2] = b[d + 4 >> 2];\r\n      b[k + 8 >> 2] = b[d + 8 >> 2];\r\n      d = f;\r\n      while (1) {\r\n        g = d;\r\n        d = d + -1 | 0;\r\n        b[h >> 2] = b[k >> 2];\r\n        b[h + 4 >> 2] = b[k + 4 >> 2];\r\n        b[h + 8 >> 2] = b[k + 8 >> 2];\r\n        if (!(Vb(g) | 0)) {\r\n          f = Ta(k) | 0;\r\n          if (f | 0) {\r\n            d = 13;\r\n            break;\r\n          }\r\n          b[i >> 2] = b[k >> 2];\r\n          b[i + 4 >> 2] = b[k + 4 >> 2];\r\n          b[i + 8 >> 2] = b[k + 8 >> 2];\r\n          Xa(i);\r\n        } else {\r\n          f = Sa(k) | 0;\r\n          if (f | 0) {\r\n            d = 13;\r\n            break;\r\n          }\r\n          b[i >> 2] = b[k >> 2];\r\n          b[i + 4 >> 2] = b[k + 4 >> 2];\r\n          b[i + 8 >> 2] = b[k + 8 >> 2];\r\n          Wa(i);\r\n        }\r\n        Pa(h, i, j);\r\n        Ma(j);\r\n        f = e;\r\n        t = b[f >> 2] | 0;\r\n        f = b[f + 4 >> 2] | 0;\r\n        u = (15 - g | 0) * 3 | 0;\r\n        s = Rd(7, 0, u | 0) | 0;\r\n        f = f & ~(H() | 0);\r\n        u = Rd(Ra(j) | 0, 0, u | 0) | 0;\r\n        f = H() | 0 | f;\r\n        r = e;\r\n        b[r >> 2] = u | t & ~s;\r\n        b[r + 4 >> 2] = f;\r\n        if ((g | 0) <= 1) {\r\n          d = 14;\r\n          break;\r\n        }\r\n      }\r\n      a: do { if ((d | 0) != 13) { if ((d | 0) == 14) { if (((b[k >> 2] | 0) <= 1 ? (b[k + 4 >> 2] | 0) <= 1 : 0) ? (b[k + 8 >> 2] | 0) <= 1 : 0) {\r\n        d = Ra(k) | 0;\r\n        f = va(n, d) | 0;\r\n        if ((f | 0) == 127) { j = 0; }else { j = oa(f) | 0; }\r\n        b: do { if (!d) {\r\n          if ((l | 0) != 0 & (j | 0) != 0) {\r\n            d = Pb(a, c) | 0;\r\n            g = e;\r\n            g = Pb(b[g >> 2] | 0, b[g + 4 >> 2] | 0) | 0;\r\n            if ((d | 0) == 7 | (g | 0) == 7) {\r\n              f = 5;\r\n              break a;\r\n            }\r\n            g = b[21376 + (d * 28 | 0) + (g << 2) >> 2] | 0;\r\n            if ((g | 0) < 0) {\r\n              f = 5;\r\n              break a;\r\n            }\r\n            if (!g) { d = 59; }else {\r\n              i = e;\r\n              d = 0;\r\n              h = b[i >> 2] | 0;\r\n              i = b[i + 4 >> 2] | 0;\r\n              do {\r\n                h = Rb(h, i) | 0;\r\n                i = H() | 0;\r\n                u = e;\r\n                b[u >> 2] = h;\r\n                b[u + 4 >> 2] = i;\r\n                d = d + 1 | 0;\r\n              } while ((d | 0) < (g | 0));\r\n              d = 58;\r\n            }\r\n          } else { d = 58; }\r\n        } else {\r\n          if (l) {\r\n            f = Pb(a, c) | 0;\r\n            if ((f | 0) == 7) {\r\n              f = 5;\r\n              break a;\r\n            }\r\n            g = b[21376 + (f * 28 | 0) + (d << 2) >> 2] | 0;\r\n            if ((g | 0) > 0) {\r\n              f = d;\r\n              d = 0;\r\n              do {\r\n                f = $a(f) | 0;\r\n                d = d + 1 | 0;\r\n              } while ((d | 0) != (g | 0));\r\n            } else { f = d; }\r\n            if ((f | 0) == 1) {\r\n              f = 9;\r\n              break a;\r\n            }\r\n            d = va(n, f) | 0;\r\n            if ((d | 0) == 127) { I(27648, 27538, 411, 27678); }\r\n            if (!(oa(d) | 0)) {\r\n              p = d;\r\n              o = g;\r\n              m = f;\r\n            } else { I(27693, 27538, 412, 27678); }\r\n          } else {\r\n            p = f;\r\n            o = 0;\r\n            m = d;\r\n          }\r\n          i = b[4272 + (n * 28 | 0) + (m << 2) >> 2] | 0;\r\n          if ((i | 0) <= -1) { I(27724, 27538, 419, 27678); }\r\n          if (!j) {\r\n            if ((o | 0) < 0) {\r\n              f = 5;\r\n              break a;\r\n            }\r\n            if (o | 0) {\r\n              g = e;\r\n              f = 0;\r\n              d = b[g >> 2] | 0;\r\n              g = b[g + 4 >> 2] | 0;\r\n              do {\r\n                d = Rb(d, g) | 0;\r\n                g = H() | 0;\r\n                u = e;\r\n                b[u >> 2] = d;\r\n                b[u + 4 >> 2] = g;\r\n                f = f + 1 | 0;\r\n              } while ((f | 0) < (o | 0));\r\n            }\r\n            if ((i | 0) <= 0) {\r\n              f = p;\r\n              d = 58;\r\n              break;\r\n            }\r\n            g = e;\r\n            f = 0;\r\n            d = b[g >> 2] | 0;\r\n            g = b[g + 4 >> 2] | 0;\r\n            while (1) {\r\n              d = Rb(d, g) | 0;\r\n              g = H() | 0;\r\n              u = e;\r\n              b[u >> 2] = d;\r\n              b[u + 4 >> 2] = g;\r\n              f = f + 1 | 0;\r\n              if ((f | 0) == (i | 0)) {\r\n                f = p;\r\n                d = 58;\r\n                break b;\r\n              }\r\n            }\r\n          }\r\n          h = wa(p, n) | 0;\r\n          if ((h | 0) == 7) { I(27514, 27538, 428, 27678); }\r\n          f = e;\r\n          d = b[f >> 2] | 0;\r\n          f = b[f + 4 >> 2] | 0;\r\n          if ((i | 0) > 0) {\r\n            g = 0;\r\n            do {\r\n              d = Rb(d, f) | 0;\r\n              f = H() | 0;\r\n              u = e;\r\n              b[u >> 2] = d;\r\n              b[u + 4 >> 2] = f;\r\n              g = g + 1 | 0;\r\n            } while ((g | 0) != (i | 0));\r\n          }\r\n          f = Pb(d, f) | 0;\r\n          if ((f | 0) == 7) { I(27795, 27538, 440, 27678); }\r\n          d = pa(p) | 0;\r\n          d = b[(d ? 21792 : 21584) + (h * 28 | 0) + (f << 2) >> 2] | 0;\r\n          if ((d | 0) < 0) { I(27795, 27538, 454, 27678); }\r\n          if (!d) {\r\n            f = p;\r\n            d = 58;\r\n          } else {\r\n            h = e;\r\n            f = 0;\r\n            g = b[h >> 2] | 0;\r\n            h = b[h + 4 >> 2] | 0;\r\n            do {\r\n              g = Qb(g, h) | 0;\r\n              h = H() | 0;\r\n              u = e;\r\n              b[u >> 2] = g;\r\n              b[u + 4 >> 2] = h;\r\n              f = f + 1 | 0;\r\n            } while ((f | 0) < (d | 0));\r\n            f = p;\r\n            d = 58;\r\n          }\r\n        } } while (0);\r\n        if ((d | 0) == 58) { if (j) { d = 59; } }\r\n        if ((d | 0) == 59) {\r\n          u = e;\r\n          if ((Pb(b[u >> 2] | 0, b[u + 4 >> 2] | 0) | 0) == 1) {\r\n            f = 9;\r\n            break;\r\n          }\r\n        }\r\n        u = e;\r\n        s = b[u >> 2] | 0;\r\n        u = b[u + 4 >> 2] & -1040385;\r\n        t = Rd(f | 0, 0, 45) | 0;\r\n        u = u | (H() | 0);\r\n        f = e;\r\n        b[f >> 2] = s | t;\r\n        b[f + 4 >> 2] = u;\r\n        f = 0;\r\n      } else { f = 1; } } } } while (0);\r\n      u = f;\r\n      T = q;\r\n      return u | 0;\r\n    }\r\n    function Jc(a, b, c, d, e, f) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0;\r\n      h = T;\r\n      T = T + 16 | 0;\r\n      g = h;\r\n      if (!e) {\r\n        a = Hc(a, b, c, d, g) | 0;\r\n        if (!a) {\r\n          eb(g, f);\r\n          a = 0;\r\n        }\r\n      } else { a = 15; }\r\n      T = h;\r\n      return a | 0;\r\n    }\r\n    function Kc(a, b, c, d, e) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0;\r\n      g = T;\r\n      T = T + 16 | 0;\r\n      f = g;\r\n      if (!d) {\r\n        c = fb(c, f) | 0;\r\n        if (!c) { c = Ic(a, b, f, e) | 0; }\r\n      } else { c = 15; }\r\n      T = g;\r\n      return c | 0;\r\n    }\r\n    function Lc(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 32 | 0;\r\n      h = j + 12 | 0;\r\n      i = j;\r\n      g = Hc(a, c, a, c, h) | 0;\r\n      if (g | 0) {\r\n        i = g;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      a = Hc(a, c, d, e, i) | 0;\r\n      if (a | 0) {\r\n        i = a;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      h = db(h, i) | 0;\r\n      i = f;\r\n      b[i >> 2] = h;\r\n      b[i + 4 >> 2] = ((h | 0) < 0) << 31 >> 31;\r\n      i = 0;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Mc(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 32 | 0;\r\n      h = j + 12 | 0;\r\n      i = j;\r\n      g = Hc(a, c, a, c, h) | 0;\r\n      if (!g) {\r\n        g = Hc(a, c, d, e, i) | 0;\r\n        if (!g) {\r\n          e = db(h, i) | 0;\r\n          e = Gd(e | 0, ((e | 0) < 0) << 31 >> 31 | 0, 1, 0) | 0;\r\n          h = H() | 0;\r\n          i = f;\r\n          b[i >> 2] = e;\r\n          b[i + 4 >> 2] = h;\r\n          i = 0;\r\n          T = j;\r\n          return i | 0;\r\n        }\r\n      }\r\n      i = g;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Nc(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0,\r\n        l = 0.0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        r = 0.0,\r\n        s = 0,\r\n        t = 0.0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0.0;\r\n      z = T;\r\n      T = T + 48 | 0;\r\n      x = z + 24 | 0;\r\n      h = z + 12 | 0;\r\n      y = z;\r\n      g = Hc(a, c, a, c, x) | 0;\r\n      if (!g) {\r\n        g = Hc(a, c, d, e, h) | 0;\r\n        if (!g) {\r\n          v = db(x, h) | 0;\r\n          w = ((v | 0) < 0) << 31 >> 31;\r\n          b[x >> 2] = 0;\r\n          b[x + 4 >> 2] = 0;\r\n          b[x + 8 >> 2] = 0;\r\n          b[h >> 2] = 0;\r\n          b[h + 4 >> 2] = 0;\r\n          b[h + 8 >> 2] = 0;\r\n          if (Hc(a, c, a, c, x) | 0) { I(27795, 27538, 692, 27747); }\r\n          if (Hc(a, c, d, e, h) | 0) { I(27795, 27538, 697, 27747); }\r\n          gb(x);\r\n          gb(h);\r\n          l = (v | 0) == 0 ? 0.0 : 1.0 / +(v | 0);\r\n          d = b[x >> 2] | 0;\r\n          r = l * +((b[h >> 2] | 0) - d | 0);\r\n          s = x + 4 | 0;\r\n          e = b[s >> 2] | 0;\r\n          t = l * +((b[h + 4 >> 2] | 0) - e | 0);\r\n          u = x + 8 | 0;\r\n          g = b[u >> 2] | 0;\r\n          l = l * +((b[h + 8 >> 2] | 0) - g | 0);\r\n          b[y >> 2] = d;\r\n          m = y + 4 | 0;\r\n          b[m >> 2] = e;\r\n          n = y + 8 | 0;\r\n          b[n >> 2] = g;\r\n          a: do { if ((v | 0) < 0) { g = 0; }else {\r\n            o = 0;\r\n            p = 0;\r\n            while (1) {\r\n              j = +(p >>> 0) + 4294967296.0 * +(o | 0);\r\n              A = r * j + +(d | 0);\r\n              i = t * j + +(e | 0);\r\n              j = l * j + +(g | 0);\r\n              d = ~~+Vd(+A);\r\n              h = ~~+Vd(+i);\r\n              g = ~~+Vd(+j);\r\n              A = +q(+(+(d | 0) - A));\r\n              i = +q(+(+(h | 0) - i));\r\n              j = +q(+(+(g | 0) - j));\r\n              do { if (!(A > i & A > j)) {\r\n                k = 0 - d | 0;\r\n                if (i > j) {\r\n                  e = k - g | 0;\r\n                  break;\r\n                } else {\r\n                  e = h;\r\n                  g = k - h | 0;\r\n                  break;\r\n                }\r\n              } else {\r\n                d = 0 - (h + g) | 0;\r\n                e = h;\r\n              } } while (0);\r\n              b[y >> 2] = d;\r\n              b[m >> 2] = e;\r\n              b[n >> 2] = g;\r\n              hb(y);\r\n              g = Ic(a, c, y, f + (p << 3) | 0) | 0;\r\n              if (g | 0) { break a; }\r\n              if (!((o | 0) < (w | 0) | (o | 0) == (w | 0) & p >>> 0 < v >>> 0)) {\r\n                g = 0;\r\n                break a;\r\n              }\r\n              d = Gd(p | 0, o | 0, 1, 0) | 0;\r\n              e = H() | 0;\r\n              o = e;\r\n              p = d;\r\n              d = b[x >> 2] | 0;\r\n              e = b[s >> 2] | 0;\r\n              g = b[u >> 2] | 0;\r\n            }\r\n          } } while (0);\r\n          y = g;\r\n          T = z;\r\n          return y | 0;\r\n        }\r\n      }\r\n      y = g;\r\n      T = z;\r\n      return y | 0;\r\n    }\r\n    function Oc(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      if ((c | 0) == 0 & (d | 0) == 0) {\r\n        e = 0;\r\n        f = 1;\r\n        G(e | 0);\r\n        return f | 0;\r\n      }\r\n      f = a;\r\n      e = b;\r\n      a = 1;\r\n      b = 0;\r\n      do {\r\n        g = (c & 1 | 0) == 0 & 0 == 0;\r\n        a = Md((g ? 1 : f) | 0, (g ? 0 : e) | 0, a | 0, b | 0) | 0;\r\n        b = H() | 0;\r\n        c = Pd(c | 0, d | 0, 1) | 0;\r\n        d = H() | 0;\r\n        f = Md(f | 0, e | 0, f | 0, e | 0) | 0;\r\n        e = H() | 0;\r\n      } while (!((c | 0) == 0 & (d | 0) == 0));\r\n      G(b | 0);\r\n      return a | 0;\r\n    }\r\n    function Pc(a, c, d, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0;\r\n      j = T;\r\n      T = T + 16 | 0;\r\n      h = j;\r\n      i = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      i = i & 15;\r\n      do { if (!i) {\r\n        g = Qd(a | 0, c | 0, 45) | 0;\r\n        H() | 0;\r\n        g = g & 127;\r\n        if (g >>> 0 > 121) {\r\n          i = 5;\r\n          T = j;\r\n          return i | 0;\r\n        } else {\r\n          h = 22064 + (g << 5) | 0;\r\n          b[d >> 2] = b[h >> 2];\r\n          b[d + 4 >> 2] = b[h + 4 >> 2];\r\n          b[d + 8 >> 2] = b[h + 8 >> 2];\r\n          b[d + 12 >> 2] = b[h + 12 >> 2];\r\n          b[d + 16 >> 2] = b[h + 16 >> 2];\r\n          b[d + 20 >> 2] = b[h + 20 >> 2];\r\n          b[d + 24 >> 2] = b[h + 24 >> 2];\r\n          b[d + 28 >> 2] = b[h + 28 >> 2];\r\n          break;\r\n        }\r\n      } else {\r\n        g = Zb(a, c, h) | 0;\r\n        if (!g) {\r\n          l = +e[h >> 3];\r\n          k = 1.0 / +t(+l);\r\n          m = +e[25968 + (i << 3) >> 3];\r\n          e[d >> 3] = l + m;\r\n          e[d + 8 >> 3] = l - m;\r\n          l = +e[h + 8 >> 3];\r\n          k = m * k;\r\n          e[d + 16 >> 3] = k + l;\r\n          e[d + 24 >> 3] = l - k;\r\n          break;\r\n        }\r\n        i = g;\r\n        T = j;\r\n        return i | 0;\r\n      } } while (0);\r\n      Ja(d, f ? 1.4 : 1.1);\r\n      f = 26096 + (i << 3) | 0;\r\n      if ((b[f >> 2] | 0) == (a | 0) ? (b[f + 4 >> 2] | 0) == (c | 0) : 0) { e[d >> 3] = 1.5707963267948966; }\r\n      i = 26224 + (i << 3) | 0;\r\n      if ((b[i >> 2] | 0) == (a | 0) ? (b[i + 4 >> 2] | 0) == (c | 0) : 0) { e[d + 8 >> 3] = -1.5707963267948966; }\r\n      if (!(+e[d >> 3] == 1.5707963267948966) ? !(+e[d + 8 >> 3] == -1.5707963267948966) : 0) {\r\n        i = 0;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      e[d + 16 >> 3] = 3.141592653589793;\r\n      e[d + 24 >> 3] = -3.141592653589793;\r\n      i = 0;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function Qc(c, d, e, f) {\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0;\r\n      l = T;\r\n      T = T + 48 | 0;\r\n      i = l + 32 | 0;\r\n      h = l + 40 | 0;\r\n      j = l;\r\n      Eb(i, 0, 0, 0);\r\n      k = b[i >> 2] | 0;\r\n      i = b[i + 4 >> 2] | 0;\r\n      do { if (e >>> 0 <= 15) {\r\n        g = Xc(f) | 0;\r\n        if (g | 0) {\r\n          f = j;\r\n          b[f >> 2] = 0;\r\n          b[f + 4 >> 2] = 0;\r\n          b[j + 8 >> 2] = g;\r\n          b[j + 12 >> 2] = -1;\r\n          f = j + 16 | 0;\r\n          k = j + 29 | 0;\r\n          b[f >> 2] = 0;\r\n          b[f + 4 >> 2] = 0;\r\n          b[f + 8 >> 2] = 0;\r\n          a[f + 12 >> 0] = 0;\r\n          a[k >> 0] = a[h >> 0] | 0;\r\n          a[k + 1 >> 0] = a[h + 1 >> 0] | 0;\r\n          a[k + 2 >> 0] = a[h + 2 >> 0] | 0;\r\n          break;\r\n        }\r\n        g = Fd((b[d + 8 >> 2] | 0) + 1 | 0, 32) | 0;\r\n        if (!g) {\r\n          f = j;\r\n          b[f >> 2] = 0;\r\n          b[f + 4 >> 2] = 0;\r\n          b[j + 8 >> 2] = 13;\r\n          b[j + 12 >> 2] = -1;\r\n          f = j + 16 | 0;\r\n          k = j + 29 | 0;\r\n          b[f >> 2] = 0;\r\n          b[f + 4 >> 2] = 0;\r\n          b[f + 8 >> 2] = 0;\r\n          a[f + 12 >> 0] = 0;\r\n          a[k >> 0] = a[h >> 0] | 0;\r\n          a[k + 1 >> 0] = a[h + 1 >> 0] | 0;\r\n          a[k + 2 >> 0] = a[h + 2 >> 0] | 0;\r\n          break;\r\n        } else {\r\n          Yc(d, g);\r\n          m = j;\r\n          b[m >> 2] = k;\r\n          b[m + 4 >> 2] = i;\r\n          b[j + 8 >> 2] = 0;\r\n          b[j + 12 >> 2] = e;\r\n          b[j + 16 >> 2] = f;\r\n          b[j + 20 >> 2] = d;\r\n          b[j + 24 >> 2] = g;\r\n          a[j + 28 >> 0] = 0;\r\n          k = j + 29 | 0;\r\n          a[k >> 0] = a[h >> 0] | 0;\r\n          a[k + 1 >> 0] = a[h + 1 >> 0] | 0;\r\n          a[k + 2 >> 0] = a[h + 2 >> 0] | 0;\r\n          break;\r\n        }\r\n      } else {\r\n        k = j;\r\n        b[k >> 2] = 0;\r\n        b[k + 4 >> 2] = 0;\r\n        b[j + 8 >> 2] = 4;\r\n        b[j + 12 >> 2] = -1;\r\n        k = j + 16 | 0;\r\n        m = j + 29 | 0;\r\n        b[k >> 2] = 0;\r\n        b[k + 4 >> 2] = 0;\r\n        b[k + 8 >> 2] = 0;\r\n        a[k + 12 >> 0] = 0;\r\n        a[m >> 0] = a[h >> 0] | 0;\r\n        a[m + 1 >> 0] = a[h + 1 >> 0] | 0;\r\n        a[m + 2 >> 0] = a[h + 2 >> 0] | 0;\r\n      } } while (0);\r\n      Rc(j);\r\n      b[c >> 2] = b[j >> 2];\r\n      b[c + 4 >> 2] = b[j + 4 >> 2];\r\n      b[c + 8 >> 2] = b[j + 8 >> 2];\r\n      b[c + 12 >> 2] = b[j + 12 >> 2];\r\n      b[c + 16 >> 2] = b[j + 16 >> 2];\r\n      b[c + 20 >> 2] = b[j + 20 >> 2];\r\n      b[c + 24 >> 2] = b[j + 24 >> 2];\r\n      b[c + 28 >> 2] = b[j + 28 >> 2];\r\n      T = l;\r\n      return;\r\n    }\r\n    function Rc(c) {\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0;\r\n      w = T;\r\n      T = T + 336 | 0;\r\n      p = w + 168 | 0;\r\n      q = w;\r\n      f = c;\r\n      e = b[f >> 2] | 0;\r\n      f = b[f + 4 >> 2] | 0;\r\n      if ((e | 0) == 0 & (f | 0) == 0) {\r\n        T = w;\r\n        return;\r\n      }\r\n      d = c + 28 | 0;\r\n      if (!(a[d >> 0] | 0)) { a[d >> 0] = 1; }else {\r\n        e = Sc(e, f) | 0;\r\n        f = H() | 0;\r\n      }\r\n      v = c + 20 | 0;\r\n      if (!(b[b[v >> 2] >> 2] | 0)) {\r\n        d = c + 24 | 0;\r\n        e = b[d >> 2] | 0;\r\n        if (e | 0) { Ed(e); }\r\n        u = c;\r\n        b[u >> 2] = 0;\r\n        b[u + 4 >> 2] = 0;\r\n        b[c + 8 >> 2] = 0;\r\n        b[v >> 2] = 0;\r\n        b[c + 12 >> 2] = -1;\r\n        b[c + 16 >> 2] = 0;\r\n        b[d >> 2] = 0;\r\n        T = w;\r\n        return;\r\n      }\r\n      u = c + 16 | 0;\r\n      d = b[u >> 2] | 0;\r\n      g = d & 15;\r\n      a: do { if (!((e | 0) == 0 & (f | 0) == 0)) {\r\n        r = c + 12 | 0;\r\n        n = (g | 0) == 3;\r\n        m = d & 255;\r\n        k = (g | 1 | 0) == 3;\r\n        o = c + 24 | 0;\r\n        l = (g + -1 | 0) >>> 0 < 3;\r\n        i = (g | 2 | 0) == 3;\r\n        j = q + 8 | 0;\r\n        b: while (1) {\r\n          h = Qd(e | 0, f | 0, 52) | 0;\r\n          H() | 0;\r\n          h = h & 15;\r\n          if ((h | 0) == (b[r >> 2] | 0)) {\r\n            switch (m & 15) {\r\n              case 0:\r\n              case 2:\r\n              case 3:\r\n                {\r\n                  g = Zb(e, f, p) | 0;\r\n                  if (g | 0) {\r\n                    s = 15;\r\n                    break b;\r\n                  }\r\n                  if (Zc(b[v >> 2] | 0, b[o >> 2] | 0, p) | 0) {\r\n                    s = 19;\r\n                    break b;\r\n                  }\r\n                  break;\r\n                }\r\n              default:\r\n\r\n            }\r\n            if (k ? (g = b[(b[v >> 2] | 0) + 4 >> 2] | 0, b[p >> 2] = b[g >> 2], b[p + 4 >> 2] = b[g + 4 >> 2], b[p + 8 >> 2] = b[g + 8 >> 2], b[p + 12 >> 2] = b[g + 12 >> 2], Ca(26832, p) | 0) : 0) {\r\n              if (Wb(b[(b[v >> 2] | 0) + 4 >> 2] | 0, h, q) | 0) {\r\n                s = 25;\r\n                break;\r\n              }\r\n              g = q;\r\n              if ((b[g >> 2] | 0) == (e | 0) ? (b[g + 4 >> 2] | 0) == (f | 0) : 0) {\r\n                s = 29;\r\n                break;\r\n              }\r\n            }\r\n            if (l) {\r\n              g = _b(e, f, p) | 0;\r\n              if (g | 0) {\r\n                s = 32;\r\n                break;\r\n              }\r\n              if (Pc(e, f, q, 0) | 0) {\r\n                s = 36;\r\n                break;\r\n              }\r\n              if (i ? _c(b[v >> 2] | 0, b[o >> 2] | 0, p, q) | 0 : 0) {\r\n                s = 42;\r\n                break;\r\n              }\r\n              if (k ? ad(b[v >> 2] | 0, b[o >> 2] | 0, p, q) | 0 : 0) {\r\n                s = 42;\r\n                break;\r\n              }\r\n            }\r\n            if (n) {\r\n              d = Pc(e, f, p, 1) | 0;\r\n              g = b[o >> 2] | 0;\r\n              if (d | 0) {\r\n                s = 45;\r\n                break;\r\n              }\r\n              if (Da(g, p) | 0) {\r\n                Ga(q, p);\r\n                if (Fa(p, b[o >> 2] | 0) | 0) {\r\n                  s = 53;\r\n                  break;\r\n                }\r\n                if (Zc(b[v >> 2] | 0, b[o >> 2] | 0, j) | 0) {\r\n                  s = 53;\r\n                  break;\r\n                }\r\n                if (ad(b[v >> 2] | 0, b[o >> 2] | 0, q, p) | 0) {\r\n                  s = 53;\r\n                  break;\r\n                }\r\n              }\r\n            }\r\n          }\r\n          do { if ((h | 0) < (b[r >> 2] | 0)) {\r\n            d = Pc(e, f, p, 1) | 0;\r\n            g = b[o >> 2] | 0;\r\n            if (d | 0) {\r\n              s = 58;\r\n              break b;\r\n            }\r\n            if (!(Da(g, p) | 0)) {\r\n              s = 73;\r\n              break;\r\n            }\r\n            if (Fa(b[o >> 2] | 0, p) | 0 ? (Ga(q, p), _c(b[v >> 2] | 0, b[o >> 2] | 0, q, p) | 0) : 0) {\r\n              s = 65;\r\n              break b;\r\n            }\r\n            e = Kb(e, f, h + 1 | 0, q) | 0;\r\n            if (e | 0) {\r\n              s = 67;\r\n              break b;\r\n            }\r\n            f = q;\r\n            e = b[f >> 2] | 0;\r\n            f = b[f + 4 >> 2] | 0;\r\n          } else { s = 73; } } while (0);\r\n          if ((s | 0) == 73) {\r\n            s = 0;\r\n            e = Sc(e, f) | 0;\r\n            f = H() | 0;\r\n          }\r\n          if ((e | 0) == 0 & (f | 0) == 0) {\r\n            t = o;\r\n            break a;\r\n          }\r\n        }\r\n        switch (s | 0) {\r\n          case 15:\r\n            {\r\n              d = b[o >> 2] | 0;\r\n              if (d | 0) { Ed(d); }\r\n              s = c;\r\n              b[s >> 2] = 0;\r\n              b[s + 4 >> 2] = 0;\r\n              b[v >> 2] = 0;\r\n              b[r >> 2] = -1;\r\n              b[u >> 2] = 0;\r\n              b[o >> 2] = 0;\r\n              b[c + 8 >> 2] = g;\r\n              s = 20;\r\n              break;\r\n            }\r\n          case 19:\r\n            {\r\n              b[c >> 2] = e;\r\n              b[c + 4 >> 2] = f;\r\n              s = 20;\r\n              break;\r\n            }\r\n          case 25:\r\n            {\r\n              I(27795, 27761, 470, 27772);\r\n              break;\r\n            }\r\n          case 29:\r\n            {\r\n              b[c >> 2] = e;\r\n              b[c + 4 >> 2] = f;\r\n              T = w;\r\n              return;\r\n            }\r\n          case 32:\r\n            {\r\n              d = b[o >> 2] | 0;\r\n              if (d | 0) { Ed(d); }\r\n              t = c;\r\n              b[t >> 2] = 0;\r\n              b[t + 4 >> 2] = 0;\r\n              b[v >> 2] = 0;\r\n              b[r >> 2] = -1;\r\n              b[u >> 2] = 0;\r\n              b[o >> 2] = 0;\r\n              b[c + 8 >> 2] = g;\r\n              T = w;\r\n              return;\r\n            }\r\n          case 36:\r\n            {\r\n              I(27795, 27761, 493, 27772);\r\n              break;\r\n            }\r\n          case 42:\r\n            {\r\n              b[c >> 2] = e;\r\n              b[c + 4 >> 2] = f;\r\n              T = w;\r\n              return;\r\n            }\r\n          case 45:\r\n            {\r\n              if (g | 0) { Ed(g); }\r\n              s = c;\r\n              b[s >> 2] = 0;\r\n              b[s + 4 >> 2] = 0;\r\n              b[v >> 2] = 0;\r\n              b[r >> 2] = -1;\r\n              b[u >> 2] = 0;\r\n              b[o >> 2] = 0;\r\n              b[c + 8 >> 2] = d;\r\n              s = 55;\r\n              break;\r\n            }\r\n          case 53:\r\n            {\r\n              b[c >> 2] = e;\r\n              b[c + 4 >> 2] = f;\r\n              s = 55;\r\n              break;\r\n            }\r\n          case 58:\r\n            {\r\n              if (g | 0) { Ed(g); }\r\n              s = c;\r\n              b[s >> 2] = 0;\r\n              b[s + 4 >> 2] = 0;\r\n              b[v >> 2] = 0;\r\n              b[r >> 2] = -1;\r\n              b[u >> 2] = 0;\r\n              b[o >> 2] = 0;\r\n              b[c + 8 >> 2] = d;\r\n              s = 71;\r\n              break;\r\n            }\r\n          case 65:\r\n            {\r\n              b[c >> 2] = e;\r\n              b[c + 4 >> 2] = f;\r\n              s = 71;\r\n              break;\r\n            }\r\n          case 67:\r\n            {\r\n              d = b[o >> 2] | 0;\r\n              if (d | 0) { Ed(d); }\r\n              t = c;\r\n              b[t >> 2] = 0;\r\n              b[t + 4 >> 2] = 0;\r\n              b[v >> 2] = 0;\r\n              b[r >> 2] = -1;\r\n              b[u >> 2] = 0;\r\n              b[o >> 2] = 0;\r\n              b[c + 8 >> 2] = e;\r\n              T = w;\r\n              return;\r\n            }\r\n        }\r\n        if ((s | 0) == 20) {\r\n          T = w;\r\n          return;\r\n        } else if ((s | 0) == 55) {\r\n          T = w;\r\n          return;\r\n        } else if ((s | 0) == 71) {\r\n          T = w;\r\n          return;\r\n        }\r\n      } else { t = c + 24 | 0; } } while (0);\r\n      d = b[t >> 2] | 0;\r\n      if (d | 0) { Ed(d); }\r\n      s = c;\r\n      b[s >> 2] = 0;\r\n      b[s + 4 >> 2] = 0;\r\n      b[c + 8 >> 2] = 0;\r\n      b[v >> 2] = 0;\r\n      b[c + 12 >> 2] = -1;\r\n      b[u >> 2] = 0;\r\n      b[t >> 2] = 0;\r\n      T = w;\r\n      return;\r\n    }\r\n    function Sc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0;\r\n      m = T;\r\n      T = T + 16 | 0;\r\n      l = m;\r\n      e = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      e = e & 15;\r\n      d = Qd(a | 0, c | 0, 45) | 0;\r\n      H() | 0;\r\n      do { if (e) {\r\n        while (1) {\r\n          d = Rd(e + 4095 | 0, 0, 52) | 0;\r\n          f = H() | 0 | c & -15728641;\r\n          g = (15 - e | 0) * 3 | 0;\r\n          h = Rd(7, 0, g | 0) | 0;\r\n          i = H() | 0;\r\n          d = d | a | h;\r\n          f = f | i;\r\n          j = Qd(a | 0, c | 0, g | 0) | 0;\r\n          H() | 0;\r\n          j = j & 7;\r\n          e = e + -1 | 0;\r\n          if (j >>> 0 < 6) { break; }\r\n          if (!e) {\r\n            k = 4;\r\n            break;\r\n          } else {\r\n            c = f;\r\n            a = d;\r\n          }\r\n        }\r\n        if ((k | 0) == 4) {\r\n          d = Qd(d | 0, f | 0, 45) | 0;\r\n          H() | 0;\r\n          break;\r\n        }\r\n        l = (j | 0) == 0 & (Hb(d, f) | 0) != 0;\r\n        l = Rd((l ? 2 : 1) + j | 0, 0, g | 0) | 0;\r\n        k = H() | 0 | c & ~i;\r\n        l = l | a & ~h;\r\n        G(k | 0);\r\n        T = m;\r\n        return l | 0;\r\n      } } while (0);\r\n      d = d & 127;\r\n      if (d >>> 0 > 120) {\r\n        k = 0;\r\n        l = 0;\r\n        G(k | 0);\r\n        T = m;\r\n        return l | 0;\r\n      }\r\n      Eb(l, 0, d + 1 | 0, 0);\r\n      k = b[l + 4 >> 2] | 0;\r\n      l = b[l >> 2] | 0;\r\n      G(k | 0);\r\n      T = m;\r\n      return l | 0;\r\n    }\r\n    function Tc(a, c, d, e, f, g) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0;\r\n      r = T;\r\n      T = T + 160 | 0;\r\n      m = r + 80 | 0;\r\n      i = r + 64 | 0;\r\n      n = r + 112 | 0;\r\n      q = r;\r\n      Qc(m, a, c, d);\r\n      k = m;\r\n      fc(i, b[k >> 2] | 0, b[k + 4 >> 2] | 0, c);\r\n      k = i;\r\n      j = b[k >> 2] | 0;\r\n      k = b[k + 4 >> 2] | 0;\r\n      h = b[m + 8 >> 2] | 0;\r\n      o = n + 4 | 0;\r\n      b[o >> 2] = b[m >> 2];\r\n      b[o + 4 >> 2] = b[m + 4 >> 2];\r\n      b[o + 8 >> 2] = b[m + 8 >> 2];\r\n      b[o + 12 >> 2] = b[m + 12 >> 2];\r\n      b[o + 16 >> 2] = b[m + 16 >> 2];\r\n      b[o + 20 >> 2] = b[m + 20 >> 2];\r\n      b[o + 24 >> 2] = b[m + 24 >> 2];\r\n      b[o + 28 >> 2] = b[m + 28 >> 2];\r\n      o = q;\r\n      b[o >> 2] = j;\r\n      b[o + 4 >> 2] = k;\r\n      o = q + 8 | 0;\r\n      b[o >> 2] = h;\r\n      a = q + 12 | 0;\r\n      c = n;\r\n      d = a + 36 | 0;\r\n      do {\r\n        b[a >> 2] = b[c >> 2];\r\n        a = a + 4 | 0;\r\n        c = c + 4 | 0;\r\n      } while ((a | 0) < (d | 0));\r\n      n = q + 48 | 0;\r\n      b[n >> 2] = b[i >> 2];\r\n      b[n + 4 >> 2] = b[i + 4 >> 2];\r\n      b[n + 8 >> 2] = b[i + 8 >> 2];\r\n      b[n + 12 >> 2] = b[i + 12 >> 2];\r\n      if ((j | 0) == 0 & (k | 0) == 0) {\r\n        q = h;\r\n        T = r;\r\n        return q | 0;\r\n      }\r\n      d = q + 16 | 0;\r\n      l = q + 24 | 0;\r\n      m = q + 28 | 0;\r\n      h = 0;\r\n      i = 0;\r\n      c = j;\r\n      a = k;\r\n      do {\r\n        if (!((h | 0) < (f | 0) | (h | 0) == (f | 0) & i >>> 0 < e >>> 0)) {\r\n          p = 4;\r\n          break;\r\n        }\r\n        k = i;\r\n        i = Gd(i | 0, h | 0, 1, 0) | 0;\r\n        h = H() | 0;\r\n        k = g + (k << 3) | 0;\r\n        b[k >> 2] = c;\r\n        b[k + 4 >> 2] = a;\r\n        hc(n);\r\n        a = n;\r\n        c = b[a >> 2] | 0;\r\n        a = b[a + 4 >> 2] | 0;\r\n        if ((c | 0) == 0 & (a | 0) == 0) {\r\n          Rc(d);\r\n          c = d;\r\n          a = b[c >> 2] | 0;\r\n          c = b[c + 4 >> 2] | 0;\r\n          if ((a | 0) == 0 & (c | 0) == 0) {\r\n            p = 10;\r\n            break;\r\n          }\r\n          gc(a, c, b[m >> 2] | 0, n);\r\n          a = n;\r\n          c = b[a >> 2] | 0;\r\n          a = b[a + 4 >> 2] | 0;\r\n        }\r\n        k = q;\r\n        b[k >> 2] = c;\r\n        b[k + 4 >> 2] = a;\r\n      } while (!((c | 0) == 0 & (a | 0) == 0));\r\n      if ((p | 0) == 4) {\r\n        a = q + 40 | 0;\r\n        c = b[a >> 2] | 0;\r\n        if (c | 0) { Ed(c); }\r\n        p = q + 16 | 0;\r\n        b[p >> 2] = 0;\r\n        b[p + 4 >> 2] = 0;\r\n        b[l >> 2] = 0;\r\n        b[q + 36 >> 2] = 0;\r\n        b[m >> 2] = -1;\r\n        b[q + 32 >> 2] = 0;\r\n        b[a >> 2] = 0;\r\n        gc(0, 0, 0, n);\r\n        b[q >> 2] = 0;\r\n        b[q + 4 >> 2] = 0;\r\n        b[o >> 2] = 0;\r\n        q = 14;\r\n        T = r;\r\n        return q | 0;\r\n      } else if ((p | 0) == 10) {\r\n        b[q >> 2] = 0;\r\n        b[q + 4 >> 2] = 0;\r\n        b[o >> 2] = b[l >> 2];\r\n      }\r\n      q = b[o >> 2] | 0;\r\n      T = r;\r\n      return q | 0;\r\n    }\r\n    function Uc(c, d, f, g) {\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      g = g | 0;\r\n      var h = 0,\r\n        i = 0.0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0.0,\r\n        r = 0;\r\n      o = T;\r\n      T = T + 48 | 0;\r\n      l = o + 32 | 0;\r\n      k = o + 40 | 0;\r\n      m = o;\r\n      if (!(b[c >> 2] | 0)) {\r\n        n = g;\r\n        b[n >> 2] = 0;\r\n        b[n + 4 >> 2] = 0;\r\n        n = 0;\r\n        T = o;\r\n        return n | 0;\r\n      }\r\n      Eb(l, 0, 0, 0);\r\n      j = l;\r\n      h = b[j >> 2] | 0;\r\n      j = b[j + 4 >> 2] | 0;\r\n      do { if (d >>> 0 > 15) {\r\n        n = m;\r\n        b[n >> 2] = 0;\r\n        b[n + 4 >> 2] = 0;\r\n        b[m + 8 >> 2] = 4;\r\n        b[m + 12 >> 2] = -1;\r\n        n = m + 16 | 0;\r\n        f = m + 29 | 0;\r\n        b[n >> 2] = 0;\r\n        b[n + 4 >> 2] = 0;\r\n        b[n + 8 >> 2] = 0;\r\n        a[n + 12 >> 0] = 0;\r\n        a[f >> 0] = a[k >> 0] | 0;\r\n        a[f + 1 >> 0] = a[k + 1 >> 0] | 0;\r\n        a[f + 2 >> 0] = a[k + 2 >> 0] | 0;\r\n        f = 4;\r\n        n = 9;\r\n      } else {\r\n        f = Xc(f) | 0;\r\n        if (f | 0) {\r\n          l = m;\r\n          b[l >> 2] = 0;\r\n          b[l + 4 >> 2] = 0;\r\n          b[m + 8 >> 2] = f;\r\n          b[m + 12 >> 2] = -1;\r\n          l = m + 16 | 0;\r\n          n = m + 29 | 0;\r\n          b[l >> 2] = 0;\r\n          b[l + 4 >> 2] = 0;\r\n          b[l + 8 >> 2] = 0;\r\n          a[l + 12 >> 0] = 0;\r\n          a[n >> 0] = a[k >> 0] | 0;\r\n          a[n + 1 >> 0] = a[k + 1 >> 0] | 0;\r\n          a[n + 2 >> 0] = a[k + 2 >> 0] | 0;\r\n          n = 9;\r\n          break;\r\n        }\r\n        f = Fd((b[c + 8 >> 2] | 0) + 1 | 0, 32) | 0;\r\n        if (!f) {\r\n          n = m;\r\n          b[n >> 2] = 0;\r\n          b[n + 4 >> 2] = 0;\r\n          b[m + 8 >> 2] = 13;\r\n          b[m + 12 >> 2] = -1;\r\n          n = m + 16 | 0;\r\n          f = m + 29 | 0;\r\n          b[n >> 2] = 0;\r\n          b[n + 4 >> 2] = 0;\r\n          b[n + 8 >> 2] = 0;\r\n          a[n + 12 >> 0] = 0;\r\n          a[f >> 0] = a[k >> 0] | 0;\r\n          a[f + 1 >> 0] = a[k + 1 >> 0] | 0;\r\n          a[f + 2 >> 0] = a[k + 2 >> 0] | 0;\r\n          f = 13;\r\n          n = 9;\r\n          break;\r\n        }\r\n        Yc(c, f);\r\n        r = m;\r\n        b[r >> 2] = h;\r\n        b[r + 4 >> 2] = j;\r\n        j = m + 8 | 0;\r\n        b[j >> 2] = 0;\r\n        b[m + 12 >> 2] = d;\r\n        b[m + 20 >> 2] = c;\r\n        b[m + 24 >> 2] = f;\r\n        a[m + 28 >> 0] = 0;\r\n        h = m + 29 | 0;\r\n        a[h >> 0] = a[k >> 0] | 0;\r\n        a[h + 1 >> 0] = a[k + 1 >> 0] | 0;\r\n        a[h + 2 >> 0] = a[k + 2 >> 0] | 0;\r\n        b[m + 16 >> 2] = 3;\r\n        p = +Ba(f);\r\n        p = p * +za(f);\r\n        i = +q(+ +e[f >> 3]);\r\n        i = p / +t(+ +Ud(+i, + +q(+ +e[f + 8 >> 3]))) * 6371.007180918475 * 6371.007180918475;\r\n        h = m + 12 | 0;\r\n        f = b[h >> 2] | 0;\r\n        a: do { if ((f | 0) > 0) { do {\r\n          qc(f + -1 | 0, l) | 0;\r\n          if (!(i / +e[l >> 3] > 10.0)) { break a; }\r\n          r = b[h >> 2] | 0;\r\n          f = r + -1 | 0;\r\n          b[h >> 2] = f;\r\n        } while ((r | 0) > 1); } } while (0);\r\n        Rc(m);\r\n        h = g;\r\n        b[h >> 2] = 0;\r\n        b[h + 4 >> 2] = 0;\r\n        h = m;\r\n        f = b[h >> 2] | 0;\r\n        h = b[h + 4 >> 2] | 0;\r\n        if (!((f | 0) == 0 & (h | 0) == 0)) { do {\r\n          Gb(f, h, d, l) | 0;\r\n          k = l;\r\n          c = g;\r\n          k = Gd(b[c >> 2] | 0, b[c + 4 >> 2] | 0, b[k >> 2] | 0, b[k + 4 >> 2] | 0) | 0;\r\n          c = H() | 0;\r\n          r = g;\r\n          b[r >> 2] = k;\r\n          b[r + 4 >> 2] = c;\r\n          Rc(m);\r\n          r = m;\r\n          f = b[r >> 2] | 0;\r\n          h = b[r + 4 >> 2] | 0;\r\n        } while (!((f | 0) == 0 & (h | 0) == 0)); }\r\n        f = b[j >> 2] | 0;\r\n      } } while (0);\r\n      r = f;\r\n      T = o;\r\n      return r | 0;\r\n    }\r\n    function Vc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0,\r\n        m = 0.0,\r\n        n = 0,\r\n        o = 0;\r\n      if (!(Ca(c, d) | 0)) {\r\n        o = 0;\r\n        return o | 0;\r\n      }\r\n      c = Aa(c) | 0;\r\n      f = +e[d >> 3];\r\n      g = +e[d + 8 >> 3];\r\n      g = c & g < 0.0 ? g + 6.283185307179586 : g;\r\n      o = b[a >> 2] | 0;\r\n      if ((o | 0) <= 0) {\r\n        o = 0;\r\n        return o | 0;\r\n      }\r\n      n = b[a + 4 >> 2] | 0;\r\n      if (c) {\r\n        c = 0;\r\n        m = g;\r\n        d = -1;\r\n        a = 0;\r\n        a: while (1) {\r\n          l = a;\r\n          while (1) {\r\n            i = +e[n + (l << 4) >> 3];\r\n            g = +e[n + (l << 4) + 8 >> 3];\r\n            a = (d + 2 | 0) % (o | 0) | 0;\r\n            h = +e[n + (a << 4) >> 3];\r\n            j = +e[n + (a << 4) + 8 >> 3];\r\n            if (i > h) {\r\n              k = i;\r\n              i = j;\r\n            } else {\r\n              k = h;\r\n              h = i;\r\n              i = g;\r\n              g = j;\r\n            }\r\n            f = f == h | f == k ? f + 2.220446049250313e-16 : f;\r\n            if (!(f < h | f > k)) { break; }\r\n            d = l + 1 | 0;\r\n            if ((d | 0) >= (o | 0)) {\r\n              d = 22;\r\n              break a;\r\n            } else {\r\n              a = l;\r\n              l = d;\r\n              d = a;\r\n            }\r\n          }\r\n          j = i < 0.0 ? i + 6.283185307179586 : i;\r\n          i = g < 0.0 ? g + 6.283185307179586 : g;\r\n          m = j == m | i == m ? m + -2.220446049250313e-16 : m;\r\n          k = j + (i - j) * ((f - h) / (k - h));\r\n          if ((k < 0.0 ? k + 6.283185307179586 : k) > m) { c = c ^ 1; }\r\n          a = l + 1 | 0;\r\n          if ((a | 0) >= (o | 0)) {\r\n            d = 22;\r\n            break;\r\n          } else { d = l; }\r\n        }\r\n        if ((d | 0) == 22) { return c | 0; }\r\n      } else {\r\n        c = 0;\r\n        m = g;\r\n        d = -1;\r\n        a = 0;\r\n        b: while (1) {\r\n          l = a;\r\n          while (1) {\r\n            i = +e[n + (l << 4) >> 3];\r\n            g = +e[n + (l << 4) + 8 >> 3];\r\n            a = (d + 2 | 0) % (o | 0) | 0;\r\n            h = +e[n + (a << 4) >> 3];\r\n            j = +e[n + (a << 4) + 8 >> 3];\r\n            if (i > h) {\r\n              k = i;\r\n              i = j;\r\n            } else {\r\n              k = h;\r\n              h = i;\r\n              i = g;\r\n              g = j;\r\n            }\r\n            f = f == h | f == k ? f + 2.220446049250313e-16 : f;\r\n            if (!(f < h | f > k)) { break; }\r\n            d = l + 1 | 0;\r\n            if ((d | 0) >= (o | 0)) {\r\n              d = 22;\r\n              break b;\r\n            } else {\r\n              a = l;\r\n              l = d;\r\n              d = a;\r\n            }\r\n          }\r\n          m = i == m | g == m ? m + -2.220446049250313e-16 : m;\r\n          if (i + (g - i) * ((f - h) / (k - h)) > m) { c = c ^ 1; }\r\n          a = l + 1 | 0;\r\n          if ((a | 0) >= (o | 0)) {\r\n            d = 22;\r\n            break;\r\n          } else { d = l; }\r\n        }\r\n        if ((d | 0) == 22) { return c | 0; }\r\n      }\r\n      return 0;\r\n    }\r\n    function Wc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0.0,\r\n        f = 0.0,\r\n        g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0;\r\n      r = b[a >> 2] | 0;\r\n      if (!r) {\r\n        b[c >> 2] = 0;\r\n        b[c + 4 >> 2] = 0;\r\n        b[c + 8 >> 2] = 0;\r\n        b[c + 12 >> 2] = 0;\r\n        b[c + 16 >> 2] = 0;\r\n        b[c + 20 >> 2] = 0;\r\n        b[c + 24 >> 2] = 0;\r\n        b[c + 28 >> 2] = 0;\r\n        return;\r\n      }\r\n      s = c + 8 | 0;\r\n      e[s >> 3] = 1797693134862315708145274.0e284;\r\n      t = c + 24 | 0;\r\n      e[t >> 3] = 1797693134862315708145274.0e284;\r\n      e[c >> 3] = -1797693134862315708145274.0e284;\r\n      u = c + 16 | 0;\r\n      e[u >> 3] = -1797693134862315708145274.0e284;\r\n      if ((r | 0) <= 0) { return; }\r\n      o = b[a + 4 >> 2] | 0;\r\n      l = 1797693134862315708145274.0e284;\r\n      m = -1797693134862315708145274.0e284;\r\n      n = 0;\r\n      a = -1;\r\n      h = 1797693134862315708145274.0e284;\r\n      i = 1797693134862315708145274.0e284;\r\n      k = -1797693134862315708145274.0e284;\r\n      f = -1797693134862315708145274.0e284;\r\n      p = 0;\r\n      while (1) {\r\n        d = +e[o + (p << 4) >> 3];\r\n        j = +e[o + (p << 4) + 8 >> 3];\r\n        a = a + 2 | 0;\r\n        g = +e[o + (((a | 0) == (r | 0) ? 0 : a) << 4) + 8 >> 3];\r\n        if (d < h) {\r\n          e[s >> 3] = d;\r\n          h = d;\r\n        }\r\n        if (j < i) {\r\n          e[t >> 3] = j;\r\n          i = j;\r\n        }\r\n        if (d > k) { e[c >> 3] = d; }else { d = k; }\r\n        if (j > f) {\r\n          e[u >> 3] = j;\r\n          f = j;\r\n        }\r\n        l = j > 0.0 & j < l ? j : l;\r\n        m = j < 0.0 & j > m ? j : m;\r\n        n = n | +q(+(j - g)) > 3.141592653589793;\r\n        a = p + 1 | 0;\r\n        if ((a | 0) == (r | 0)) { break; }else {\r\n          v = p;\r\n          k = d;\r\n          p = a;\r\n          a = v;\r\n        }\r\n      }\r\n      if (!n) { return; }\r\n      e[u >> 3] = m;\r\n      e[t >> 3] = l;\r\n      return;\r\n    }\r\n    function Xc(a) {\r\n      a = a | 0;\r\n      return (a >>> 0 < 4 ? 0 : 15) | 0;\r\n    }\r\n    function Yc(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0,\r\n        n = 0.0,\r\n        o = 0.0,\r\n        p = 0.0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0,\r\n        x = 0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0;\r\n      r = b[a >> 2] | 0;\r\n      if (r) {\r\n        s = c + 8 | 0;\r\n        e[s >> 3] = 1797693134862315708145274.0e284;\r\n        t = c + 24 | 0;\r\n        e[t >> 3] = 1797693134862315708145274.0e284;\r\n        e[c >> 3] = -1797693134862315708145274.0e284;\r\n        u = c + 16 | 0;\r\n        e[u >> 3] = -1797693134862315708145274.0e284;\r\n        if ((r | 0) > 0) {\r\n          g = b[a + 4 >> 2] | 0;\r\n          o = 1797693134862315708145274.0e284;\r\n          p = -1797693134862315708145274.0e284;\r\n          f = 0;\r\n          d = -1;\r\n          k = 1797693134862315708145274.0e284;\r\n          l = 1797693134862315708145274.0e284;\r\n          n = -1797693134862315708145274.0e284;\r\n          i = -1797693134862315708145274.0e284;\r\n          v = 0;\r\n          while (1) {\r\n            h = +e[g + (v << 4) >> 3];\r\n            m = +e[g + (v << 4) + 8 >> 3];\r\n            z = d + 2 | 0;\r\n            j = +e[g + (((z | 0) == (r | 0) ? 0 : z) << 4) + 8 >> 3];\r\n            if (h < k) {\r\n              e[s >> 3] = h;\r\n              k = h;\r\n            }\r\n            if (m < l) {\r\n              e[t >> 3] = m;\r\n              l = m;\r\n            }\r\n            if (h > n) { e[c >> 3] = h; }else { h = n; }\r\n            if (m > i) {\r\n              e[u >> 3] = m;\r\n              i = m;\r\n            }\r\n            o = m > 0.0 & m < o ? m : o;\r\n            p = m < 0.0 & m > p ? m : p;\r\n            f = f | +q(+(m - j)) > 3.141592653589793;\r\n            d = v + 1 | 0;\r\n            if ((d | 0) == (r | 0)) { break; }else {\r\n              z = v;\r\n              n = h;\r\n              v = d;\r\n              d = z;\r\n            }\r\n          }\r\n          if (f) {\r\n            e[u >> 3] = p;\r\n            e[t >> 3] = o;\r\n          }\r\n        }\r\n      } else {\r\n        b[c >> 2] = 0;\r\n        b[c + 4 >> 2] = 0;\r\n        b[c + 8 >> 2] = 0;\r\n        b[c + 12 >> 2] = 0;\r\n        b[c + 16 >> 2] = 0;\r\n        b[c + 20 >> 2] = 0;\r\n        b[c + 24 >> 2] = 0;\r\n        b[c + 28 >> 2] = 0;\r\n      }\r\n      z = a + 8 | 0;\r\n      d = b[z >> 2] | 0;\r\n      if ((d | 0) <= 0) { return; }\r\n      y = a + 12 | 0;\r\n      x = 0;\r\n      do {\r\n        g = b[y >> 2] | 0;\r\n        f = x;\r\n        x = x + 1 | 0;\r\n        t = c + (x << 5) | 0;\r\n        u = b[g + (f << 3) >> 2] | 0;\r\n        if (u) {\r\n          v = c + (x << 5) + 8 | 0;\r\n          e[v >> 3] = 1797693134862315708145274.0e284;\r\n          a = c + (x << 5) + 24 | 0;\r\n          e[a >> 3] = 1797693134862315708145274.0e284;\r\n          e[t >> 3] = -1797693134862315708145274.0e284;\r\n          w = c + (x << 5) + 16 | 0;\r\n          e[w >> 3] = -1797693134862315708145274.0e284;\r\n          if ((u | 0) > 0) {\r\n            r = b[g + (f << 3) + 4 >> 2] | 0;\r\n            o = 1797693134862315708145274.0e284;\r\n            p = -1797693134862315708145274.0e284;\r\n            g = 0;\r\n            f = -1;\r\n            s = 0;\r\n            k = 1797693134862315708145274.0e284;\r\n            l = 1797693134862315708145274.0e284;\r\n            m = -1797693134862315708145274.0e284;\r\n            i = -1797693134862315708145274.0e284;\r\n            while (1) {\r\n              h = +e[r + (s << 4) >> 3];\r\n              n = +e[r + (s << 4) + 8 >> 3];\r\n              f = f + 2 | 0;\r\n              j = +e[r + (((f | 0) == (u | 0) ? 0 : f) << 4) + 8 >> 3];\r\n              if (h < k) {\r\n                e[v >> 3] = h;\r\n                k = h;\r\n              }\r\n              if (n < l) {\r\n                e[a >> 3] = n;\r\n                l = n;\r\n              }\r\n              if (h > m) { e[t >> 3] = h; }else { h = m; }\r\n              if (n > i) {\r\n                e[w >> 3] = n;\r\n                i = n;\r\n              }\r\n              o = n > 0.0 & n < o ? n : o;\r\n              p = n < 0.0 & n > p ? n : p;\r\n              g = g | +q(+(n - j)) > 3.141592653589793;\r\n              f = s + 1 | 0;\r\n              if ((f | 0) == (u | 0)) { break; }else {\r\n                A = s;\r\n                s = f;\r\n                m = h;\r\n                f = A;\r\n              }\r\n            }\r\n            if (g) {\r\n              e[w >> 3] = p;\r\n              e[a >> 3] = o;\r\n            }\r\n          }\r\n        } else {\r\n          b[t >> 2] = 0;\r\n          b[t + 4 >> 2] = 0;\r\n          b[t + 8 >> 2] = 0;\r\n          b[t + 12 >> 2] = 0;\r\n          b[t + 16 >> 2] = 0;\r\n          b[t + 20 >> 2] = 0;\r\n          b[t + 24 >> 2] = 0;\r\n          b[t + 28 >> 2] = 0;\r\n          d = b[z >> 2] | 0;\r\n        }\r\n      } while ((x | 0) < (d | 0));\r\n      return;\r\n    }\r\n    function Zc(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      if (!(Vc(a, c, d) | 0)) {\r\n        f = 0;\r\n        return f | 0;\r\n      }\r\n      f = a + 8 | 0;\r\n      if ((b[f >> 2] | 0) <= 0) {\r\n        f = 1;\r\n        return f | 0;\r\n      }\r\n      e = a + 12 | 0;\r\n      a = 0;\r\n      while (1) {\r\n        g = a;\r\n        a = a + 1 | 0;\r\n        if (Vc((b[e >> 2] | 0) + (g << 3) | 0, c + (a << 5) | 0, d) | 0) {\r\n          a = 0;\r\n          e = 6;\r\n          break;\r\n        }\r\n        if ((a | 0) >= (b[f >> 2] | 0)) {\r\n          a = 1;\r\n          e = 6;\r\n          break;\r\n        }\r\n      }\r\n      if ((e | 0) == 6) { return a | 0; }\r\n      return 0;\r\n    }\r\n    function _c(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0;\r\n      k = T;\r\n      T = T + 16 | 0;\r\n      i = k;\r\n      h = d + 8 | 0;\r\n      if (!(Vc(a, c, h) | 0)) {\r\n        j = 0;\r\n        T = k;\r\n        return j | 0;\r\n      }\r\n      j = a + 8 | 0;\r\n      a: do { if ((b[j >> 2] | 0) > 0) {\r\n        g = a + 12 | 0;\r\n        f = 0;\r\n        while (1) {\r\n          l = f;\r\n          f = f + 1 | 0;\r\n          if (Vc((b[g >> 2] | 0) + (l << 3) | 0, c + (f << 5) | 0, h) | 0) {\r\n            f = 0;\r\n            break;\r\n          }\r\n          if ((f | 0) >= (b[j >> 2] | 0)) { break a; }\r\n        }\r\n        T = k;\r\n        return f | 0;\r\n      } } while (0);\r\n      if ($c(a, c, d, e) | 0) {\r\n        l = 0;\r\n        T = k;\r\n        return l | 0;\r\n      }\r\n      b[i >> 2] = b[d >> 2];\r\n      b[i + 4 >> 2] = h;\r\n      f = b[j >> 2] | 0;\r\n      b: do { if ((f | 0) > 0) {\r\n        a = a + 12 | 0;\r\n        h = 0;\r\n        g = f;\r\n        while (1) {\r\n          f = b[a >> 2] | 0;\r\n          if ((b[f + (h << 3) >> 2] | 0) > 0) {\r\n            if (Vc(i, e, b[f + (h << 3) + 4 >> 2] | 0) | 0) {\r\n              f = 0;\r\n              break b;\r\n            }\r\n            f = h + 1 | 0;\r\n            if ($c((b[a >> 2] | 0) + (h << 3) | 0, c + (f << 5) | 0, d, e) | 0) {\r\n              f = 0;\r\n              break b;\r\n            }\r\n            g = b[j >> 2] | 0;\r\n          } else { f = h + 1 | 0; }\r\n          if ((f | 0) < (g | 0)) { h = f; }else {\r\n            f = 1;\r\n            break;\r\n          }\r\n        }\r\n      } else { f = 1; } } while (0);\r\n      l = f;\r\n      T = k;\r\n      return l | 0;\r\n    }\r\n    function $c(a, c, d, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0,\r\n        n = 0.0,\r\n        o = 0.0,\r\n        p = 0.0,\r\n        q = 0.0,\r\n        r = 0.0,\r\n        s = 0.0,\r\n        t = 0.0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0.0,\r\n        x = 0.0,\r\n        y = 0,\r\n        z = 0,\r\n        A = 0;\r\n      y = T;\r\n      T = T + 176 | 0;\r\n      u = y + 172 | 0;\r\n      g = y + 168 | 0;\r\n      v = y;\r\n      if (!(Da(c, f) | 0)) {\r\n        a = 0;\r\n        T = y;\r\n        return a | 0;\r\n      }\r\n      Ea(c, f, u, g);\r\n      Wd(v | 0, d | 0, 168) | 0;\r\n      if ((b[d >> 2] | 0) > 0) {\r\n        c = 0;\r\n        do {\r\n          z = v + 8 + (c << 4) + 8 | 0;\r\n          t = +kc(+e[z >> 3], b[g >> 2] | 0);\r\n          e[z >> 3] = t;\r\n          c = c + 1 | 0;\r\n        } while ((c | 0) < (b[d >> 2] | 0));\r\n      }\r\n      r = +e[f >> 3];\r\n      s = +e[f + 8 >> 3];\r\n      t = +kc(+e[f + 16 >> 3], b[g >> 2] | 0);\r\n      p = +kc(+e[f + 24 >> 3], b[g >> 2] | 0);\r\n      a: do { if ((b[a >> 2] | 0) > 0) {\r\n        f = a + 4 | 0;\r\n        g = b[v >> 2] | 0;\r\n        if ((g | 0) <= 0) {\r\n          c = 0;\r\n          while (1) {\r\n            c = c + 1 | 0;\r\n            if ((c | 0) >= (b[a >> 2] | 0)) {\r\n              c = 0;\r\n              break a;\r\n            }\r\n          }\r\n        }\r\n        d = 0;\r\n        while (1) {\r\n          c = b[f >> 2] | 0;\r\n          o = +e[c + (d << 4) >> 3];\r\n          q = +kc(+e[c + (d << 4) + 8 >> 3], b[u >> 2] | 0);\r\n          c = b[f >> 2] | 0;\r\n          d = d + 1 | 0;\r\n          z = (d | 0) % (b[a >> 2] | 0) | 0;\r\n          h = +e[c + (z << 4) >> 3];\r\n          i = +kc(+e[c + (z << 4) + 8 >> 3], b[u >> 2] | 0);\r\n          if (((!(o >= r) | !(h >= r) ? !(o <= s) | !(h <= s) : 0) ? !(q <= p) | !(i <= p) : 0) ? !(q >= t) | !(i >= t) : 0) {\r\n            n = h - o;\r\n            l = i - q;\r\n            c = 0;\r\n            do {\r\n              A = c;\r\n              c = c + 1 | 0;\r\n              z = (c | 0) == (g | 0) ? 0 : c;\r\n              h = +e[v + 8 + (A << 4) + 8 >> 3];\r\n              i = +e[v + 8 + (z << 4) + 8 >> 3] - h;\r\n              j = +e[v + 8 + (A << 4) >> 3];\r\n              k = +e[v + 8 + (z << 4) >> 3] - j;\r\n              m = n * i - l * k;\r\n              if ((m != 0.0 ? (w = q - h, x = o - j, k = (w * k - i * x) / m, !(k < 0.0 | k > 1.0)) : 0) ? (m = (n * w - l * x) / m, m >= 0.0 & m <= 1.0) : 0) {\r\n                c = 1;\r\n                break a;\r\n              }\r\n            } while ((c | 0) < (g | 0));\r\n          }\r\n          if ((d | 0) >= (b[a >> 2] | 0)) {\r\n            c = 0;\r\n            break;\r\n          }\r\n        }\r\n      } else { c = 0; } } while (0);\r\n      A = c;\r\n      T = y;\r\n      return A | 0;\r\n    }\r\n    function ad(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      if ($c(a, c, d, e) | 0) {\r\n        g = 1;\r\n        return g | 0;\r\n      }\r\n      g = a + 8 | 0;\r\n      if ((b[g >> 2] | 0) <= 0) {\r\n        g = 0;\r\n        return g | 0;\r\n      }\r\n      f = a + 12 | 0;\r\n      a = 0;\r\n      while (1) {\r\n        h = a;\r\n        a = a + 1 | 0;\r\n        if ($c((b[f >> 2] | 0) + (h << 3) | 0, c + (a << 5) | 0, d, e) | 0) {\r\n          a = 1;\r\n          f = 6;\r\n          break;\r\n        }\r\n        if ((a | 0) >= (b[g >> 2] | 0)) {\r\n          a = 0;\r\n          f = 6;\r\n          break;\r\n        }\r\n      }\r\n      if ((f | 0) == 6) { return a | 0; }\r\n      return 0;\r\n    }\r\n    function bd() {\r\n      return 8;\r\n    }\r\n    function cd() {\r\n      return 16;\r\n    }\r\n    function dd() {\r\n      return 168;\r\n    }\r\n    function ed() {\r\n      return 8;\r\n    }\r\n    function fd() {\r\n      return 16;\r\n    }\r\n    function gd() {\r\n      return 12;\r\n    }\r\n    function hd() {\r\n      return 8;\r\n    }\r\n    function id(a) {\r\n      a = a | 0;\r\n      return +(+((b[a >> 2] | 0) >>> 0) + 4294967296.0 * +(b[a + 4 >> 2] | 0));\r\n    }\r\n    function jd(a) {\r\n      a = a | 0;\r\n      var b = 0.0,\r\n        c = 0.0;\r\n      c = +e[a >> 3];\r\n      b = +e[a + 8 >> 3];\r\n      return + +r(+(c * c + b * b));\r\n    }\r\n    function kd(a, b, c, d, f) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      f = f | 0;\r\n      var g = 0.0,\r\n        h = 0.0,\r\n        i = 0.0,\r\n        j = 0.0,\r\n        k = 0.0,\r\n        l = 0.0,\r\n        m = 0.0,\r\n        n = 0.0;\r\n      k = +e[a >> 3];\r\n      j = +e[b >> 3] - k;\r\n      i = +e[a + 8 >> 3];\r\n      h = +e[b + 8 >> 3] - i;\r\n      m = +e[c >> 3];\r\n      g = +e[d >> 3] - m;\r\n      n = +e[c + 8 >> 3];\r\n      l = +e[d + 8 >> 3] - n;\r\n      g = (g * (i - n) - (k - m) * l) / (j * l - h * g);\r\n      e[f >> 3] = k + j * g;\r\n      e[f + 8 >> 3] = i + h * g;\r\n      return;\r\n    }\r\n    function ld(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      if (!(+q(+(+e[a >> 3] - +e[b >> 3])) < 1.1920928955078125e-07)) {\r\n        b = 0;\r\n        return b | 0;\r\n      }\r\n      b = +q(+(+e[a + 8 >> 3] - +e[b + 8 >> 3])) < 1.1920928955078125e-07;\r\n      return b | 0;\r\n    }\r\n    function md(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0;\r\n      f = +e[a >> 3] - +e[b >> 3];\r\n      d = +e[a + 8 >> 3] - +e[b + 8 >> 3];\r\n      c = +e[a + 16 >> 3] - +e[b + 16 >> 3];\r\n      return +(f * f + d * d + c * c);\r\n    }\r\n    function nd(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0.0,\r\n        d = 0.0,\r\n        f = 0.0;\r\n      c = +e[a >> 3];\r\n      d = +t(+c);\r\n      c = +u(+c);\r\n      e[b + 16 >> 3] = c;\r\n      c = +e[a + 8 >> 3];\r\n      f = d * +t(+c);\r\n      e[b >> 3] = f;\r\n      c = d * +u(+c);\r\n      e[b + 8 >> 3] = c;\r\n      return;\r\n    }\r\n    function od(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      g = T;\r\n      T = T + 16 | 0;\r\n      f = g;\r\n      e = Hb(a, c) | 0;\r\n      if ((d + -1 | 0) >>> 0 > 5) {\r\n        f = -1;\r\n        T = g;\r\n        return f | 0;\r\n      }\r\n      e = (e | 0) != 0;\r\n      if ((d | 0) == 1 & e) {\r\n        f = -1;\r\n        T = g;\r\n        return f | 0;\r\n      }\r\n      do { if (!(pd(a, c, f) | 0)) {\r\n        if (e) {\r\n          e = ((b[26352 + (d << 2) >> 2] | 0) + 5 - (b[f >> 2] | 0) | 0) % 5 | 0;\r\n          break;\r\n        } else {\r\n          e = ((b[26384 + (d << 2) >> 2] | 0) + 6 - (b[f >> 2] | 0) | 0) % 6 | 0;\r\n          break;\r\n        }\r\n      } else { e = -1; } } while (0);\r\n      f = e;\r\n      T = g;\r\n      return f | 0;\r\n    }\r\n    function pd(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      k = T;\r\n      T = T + 32 | 0;\r\n      h = k + 16 | 0;\r\n      i = k;\r\n      e = Yb(a, c, h) | 0;\r\n      if (e | 0) {\r\n        d = e;\r\n        T = k;\r\n        return d | 0;\r\n      }\r\n      g = Cb(a, c) | 0;\r\n      j = Pb(a, c) | 0;\r\n      sa(g, i);\r\n      e = ta(g, b[h >> 2] | 0) | 0;\r\n      a: do { if (oa(g) | 0) {\r\n        do { switch (g | 0) {\r\n          case 4:\r\n            {\r\n              a = 0;\r\n              break;\r\n            }\r\n          case 14:\r\n            {\r\n              a = 1;\r\n              break;\r\n            }\r\n          case 24:\r\n            {\r\n              a = 2;\r\n              break;\r\n            }\r\n          case 38:\r\n            {\r\n              a = 3;\r\n              break;\r\n            }\r\n          case 49:\r\n            {\r\n              a = 4;\r\n              break;\r\n            }\r\n          case 58:\r\n            {\r\n              a = 5;\r\n              break;\r\n            }\r\n          case 63:\r\n            {\r\n              a = 6;\r\n              break;\r\n            }\r\n          case 72:\r\n            {\r\n              a = 7;\r\n              break;\r\n            }\r\n          case 83:\r\n            {\r\n              a = 8;\r\n              break;\r\n            }\r\n          case 97:\r\n            {\r\n              a = 9;\r\n              break;\r\n            }\r\n          case 107:\r\n            {\r\n              a = 10;\r\n              break;\r\n            }\r\n          case 117:\r\n            {\r\n              a = 11;\r\n              break;\r\n            }\r\n          default:\r\n            {\r\n              e = 1;\r\n              break a;\r\n            }\r\n        } } while (0);\r\n        f = b[26416 + (a * 24 | 0) + 8 >> 2] | 0;\r\n        c = b[26416 + (a * 24 | 0) + 16 >> 2] | 0;\r\n        a = b[h >> 2] | 0;\r\n        if ((a | 0) != (b[i >> 2] | 0)) {\r\n          i = pa(g) | 0;\r\n          a = b[h >> 2] | 0;\r\n          if (i | (a | 0) == (c | 0)) { e = (e + 1 | 0) % 6 | 0; }\r\n        }\r\n        if ((j | 0) == 3 & (a | 0) == (c | 0)) {\r\n          e = (e + 5 | 0) % 6 | 0;\r\n          f = 22;\r\n          break;\r\n        }\r\n        if ((j | 0) == 5 & (a | 0) == (f | 0)) {\r\n          e = (e + 1 | 0) % 6 | 0;\r\n          f = 22;\r\n        } else { f = 22; }\r\n      } else { f = 22; } } while (0);\r\n      if ((f | 0) == 22) {\r\n        b[d >> 2] = e;\r\n        e = 0;\r\n      }\r\n      d = e;\r\n      T = k;\r\n      return d | 0;\r\n    }\r\n    function qd(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0;\r\n      u = T;\r\n      T = T + 32 | 0;\r\n      t = u + 24 | 0;\r\n      r = u + 20 | 0;\r\n      p = u + 8 | 0;\r\n      o = u + 16 | 0;\r\n      n = u;\r\n      j = (Hb(a, c) | 0) == 0;\r\n      j = j ? 6 : 5;\r\n      l = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      l = l & 15;\r\n      if (j >>> 0 <= d >>> 0) {\r\n        e = 2;\r\n        T = u;\r\n        return e | 0;\r\n      }\r\n      m = (l | 0) == 0;\r\n      if (!m ? (q = Rd(7, 0, (l ^ 15) * 3 | 0) | 0, (q & a | 0) == 0 & ((H() | 0) & c | 0) == 0) : 0) { f = d; }else { g = 4; }\r\n      a: do { if ((g | 0) == 4) {\r\n        f = (Hb(a, c) | 0) != 0;\r\n        if (((f ? 4 : 5) | 0) < (d | 0)) {\r\n          e = 1;\r\n          T = u;\r\n          return e | 0;\r\n        }\r\n        if (pd(a, c, t) | 0) {\r\n          e = 1;\r\n          T = u;\r\n          return e | 0;\r\n        }\r\n        g = (b[t >> 2] | 0) + d | 0;\r\n        if (f) { f = 26704 + (((g | 0) % 5 | 0) << 2) | 0; }else { f = 26736 + (((g | 0) % 6 | 0) << 2) | 0; }\r\n        q = b[f >> 2] | 0;\r\n        if ((q | 0) == 7) {\r\n          e = 1;\r\n          T = u;\r\n          return e | 0;\r\n        }\r\n        b[r >> 2] = 0;\r\n        f = ea(a, c, q, r, p) | 0;\r\n        do { if (!f) {\r\n          i = p;\r\n          k = b[i >> 2] | 0;\r\n          i = b[i + 4 >> 2] | 0;\r\n          h = i >>> 0 < c >>> 0 | (i | 0) == (c | 0) & k >>> 0 < a >>> 0;\r\n          g = h ? k : a;\r\n          h = h ? i : c;\r\n          if (!m ? (m = Rd(7, 0, (l ^ 15) * 3 | 0) | 0, (k & m | 0) == 0 & (i & (H() | 0) | 0) == 0) : 0) { f = d; }else {\r\n            i = (d + -1 + j | 0) % (j | 0) | 0;\r\n            f = Hb(a, c) | 0;\r\n            if ((i | 0) < 0) { I(27795, 27797, 246, 27806); }\r\n            j = (f | 0) != 0;\r\n            if (((j ? 4 : 5) | 0) < (i | 0)) { I(27795, 27797, 246, 27806); }\r\n            if (pd(a, c, t) | 0) { I(27795, 27797, 246, 27806); }\r\n            f = (b[t >> 2] | 0) + i | 0;\r\n            if (j) { f = 26704 + (((f | 0) % 5 | 0) << 2) | 0; }else { f = 26736 + (((f | 0) % 6 | 0) << 2) | 0; }\r\n            i = b[f >> 2] | 0;\r\n            if ((i | 0) == 7) { I(27795, 27797, 246, 27806); }\r\n            b[o >> 2] = 0;\r\n            f = ea(a, c, i, o, n) | 0;\r\n            if (f | 0) { break; }\r\n            k = n;\r\n            j = b[k >> 2] | 0;\r\n            k = b[k + 4 >> 2] | 0;\r\n            do { if (k >>> 0 < h >>> 0 | (k | 0) == (h | 0) & j >>> 0 < g >>> 0) {\r\n              if (!(Hb(j, k) | 0)) { g = b[26800 + ((((b[o >> 2] | 0) + (b[26768 + (i << 2) >> 2] | 0) | 0) % 6 | 0) << 2) >> 2] | 0; }else { g = ia(j, k, a, c) | 0; }\r\n              f = Hb(j, k) | 0;\r\n              if ((g + -1 | 0) >>> 0 > 5) {\r\n                f = -1;\r\n                g = j;\r\n                h = k;\r\n                break;\r\n              }\r\n              f = (f | 0) != 0;\r\n              if ((g | 0) == 1 & f) {\r\n                f = -1;\r\n                g = j;\r\n                h = k;\r\n                break;\r\n              }\r\n              do { if (!(pd(j, k, t) | 0)) {\r\n                if (f) {\r\n                  f = ((b[26352 + (g << 2) >> 2] | 0) + 5 - (b[t >> 2] | 0) | 0) % 5 | 0;\r\n                  break;\r\n                } else {\r\n                  f = ((b[26384 + (g << 2) >> 2] | 0) + 6 - (b[t >> 2] | 0) | 0) % 6 | 0;\r\n                  break;\r\n                }\r\n              } else { f = -1; } } while (0);\r\n              g = j;\r\n              h = k;\r\n            } else { f = d; } } while (0);\r\n            i = p;\r\n            k = b[i >> 2] | 0;\r\n            i = b[i + 4 >> 2] | 0;\r\n          }\r\n          if ((g | 0) == (k | 0) & (h | 0) == (i | 0)) {\r\n            j = (Hb(k, i) | 0) != 0;\r\n            if (j) { a = ia(k, i, a, c) | 0; }else { a = b[26800 + ((((b[r >> 2] | 0) + (b[26768 + (q << 2) >> 2] | 0) | 0) % 6 | 0) << 2) >> 2] | 0; }\r\n            f = Hb(k, i) | 0;\r\n            if ((a + -1 | 0) >>> 0 <= 5 ? (s = (f | 0) != 0, !((a | 0) == 1 & s)) : 0) {\r\n              do { if (!(pd(k, i, t) | 0)) {\r\n                if (s) {\r\n                  f = ((b[26352 + (a << 2) >> 2] | 0) + 5 - (b[t >> 2] | 0) | 0) % 5 | 0;\r\n                  break;\r\n                } else {\r\n                  f = ((b[26384 + (a << 2) >> 2] | 0) + 6 - (b[t >> 2] | 0) | 0) % 6 | 0;\r\n                  break;\r\n                }\r\n              } else { f = -1; } } while (0);\r\n            } else { f = -1; }\r\n            f = f + 1 | 0;\r\n            f = (f | 0) == 6 | j & (f | 0) == 5 ? 0 : f;\r\n          }\r\n          c = h;\r\n          a = g;\r\n          break a;\r\n        } } while (0);\r\n        e = f;\r\n        T = u;\r\n        return e | 0;\r\n      } } while (0);\r\n      s = Rd(f | 0, 0, 56) | 0;\r\n      t = H() | 0 | c & -2130706433 | 536870912;\r\n      b[e >> 2] = s | a;\r\n      b[e + 4 >> 2] = t;\r\n      e = 0;\r\n      T = u;\r\n      return e | 0;\r\n    }\r\n    function rd(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      g = (Hb(a, c) | 0) == 0;\r\n      e = qd(a, c, 0, d) | 0;\r\n      f = (e | 0) == 0;\r\n      if (g) {\r\n        if (!f) {\r\n          g = e;\r\n          return g | 0;\r\n        }\r\n        e = qd(a, c, 1, d + 8 | 0) | 0;\r\n        if (e | 0) {\r\n          g = e;\r\n          return g | 0;\r\n        }\r\n        e = qd(a, c, 2, d + 16 | 0) | 0;\r\n        if (e | 0) {\r\n          g = e;\r\n          return g | 0;\r\n        }\r\n        e = qd(a, c, 3, d + 24 | 0) | 0;\r\n        if (e | 0) {\r\n          g = e;\r\n          return g | 0;\r\n        }\r\n        e = qd(a, c, 4, d + 32 | 0) | 0;\r\n        if (!e) { return qd(a, c, 5, d + 40 | 0) | 0; }else {\r\n          g = e;\r\n          return g | 0;\r\n        }\r\n      }\r\n      if (!f) {\r\n        g = e;\r\n        return g | 0;\r\n      }\r\n      e = qd(a, c, 1, d + 8 | 0) | 0;\r\n      if (e | 0) {\r\n        g = e;\r\n        return g | 0;\r\n      }\r\n      e = qd(a, c, 2, d + 16 | 0) | 0;\r\n      if (e | 0) {\r\n        g = e;\r\n        return g | 0;\r\n      }\r\n      e = qd(a, c, 3, d + 24 | 0) | 0;\r\n      if (e | 0) {\r\n        g = e;\r\n        return g | 0;\r\n      }\r\n      e = qd(a, c, 4, d + 32 | 0) | 0;\r\n      if (e | 0) {\r\n        g = e;\r\n        return g | 0;\r\n      }\r\n      g = d + 40 | 0;\r\n      b[g >> 2] = 0;\r\n      b[g + 4 >> 2] = 0;\r\n      g = 0;\r\n      return g | 0;\r\n    }\r\n    function sd(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = T;\r\n      T = T + 192 | 0;\r\n      f = j;\r\n      g = j + 168 | 0;\r\n      h = Qd(a | 0, c | 0, 56) | 0;\r\n      H() | 0;\r\n      h = h & 7;\r\n      i = c & -2130706433 | 134217728;\r\n      e = Yb(a, i, g) | 0;\r\n      if (e | 0) {\r\n        i = e;\r\n        T = j;\r\n        return i | 0;\r\n      }\r\n      c = Qd(a | 0, c | 0, 52) | 0;\r\n      H() | 0;\r\n      c = c & 15;\r\n      if (!(Hb(a, i) | 0)) { zb(g, c, h, 1, f); }else { vb(g, c, h, 1, f); }\r\n      i = f + 8 | 0;\r\n      b[d >> 2] = b[i >> 2];\r\n      b[d + 4 >> 2] = b[i + 4 >> 2];\r\n      b[d + 8 >> 2] = b[i + 8 >> 2];\r\n      b[d + 12 >> 2] = b[i + 12 >> 2];\r\n      i = 0;\r\n      T = j;\r\n      return i | 0;\r\n    }\r\n    function td(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      d = f;\r\n      if (!(0 == 0 & (c & 2013265920 | 0) == 536870912)) {\r\n        e = 0;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      e = c & -2130706433 | 134217728;\r\n      if (!(Db(a, e) | 0)) {\r\n        e = 0;\r\n        T = f;\r\n        return e | 0;\r\n      }\r\n      g = Qd(a | 0, c | 0, 56) | 0;\r\n      H() | 0;\r\n      g = (qd(a, e, g & 7, d) | 0) == 0;\r\n      e = d;\r\n      e = g & ((b[e >> 2] | 0) == (a | 0) ? (b[e + 4 >> 2] | 0) == (c | 0) : 0) & 1;\r\n      T = f;\r\n      return e | 0;\r\n    }\r\n    function ud(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0;\r\n      if ((c | 0) > 0) {\r\n        e = Fd(c, 4) | 0;\r\n        b[a >> 2] = e;\r\n        if (!e) { I(27819, 27842, 40, 27856); }\r\n      } else { b[a >> 2] = 0; }\r\n      b[a + 4 >> 2] = c;\r\n      b[a + 8 >> 2] = 0;\r\n      b[a + 12 >> 2] = d;\r\n      return;\r\n    }\r\n    function vd(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      g = a + 4 | 0;\r\n      h = a + 12 | 0;\r\n      i = a + 8 | 0;\r\n      a: while (1) {\r\n        d = b[g >> 2] | 0;\r\n        c = 0;\r\n        while (1) {\r\n          if ((c | 0) >= (d | 0)) { break a; }\r\n          f = b[a >> 2] | 0;\r\n          j = b[f + (c << 2) >> 2] | 0;\r\n          if (!j) { c = c + 1 | 0; }else { break; }\r\n        }\r\n        c = f + (~~(+q(+(+s(10.0, + +(15 - (b[h >> 2] | 0) | 0)) * (+e[j >> 3] + +e[j + 8 >> 3]))) % +(d | 0)) >>> 0 << 2) | 0;\r\n        d = b[c >> 2] | 0;\r\n        b: do { if (d | 0) {\r\n          f = j + 32 | 0;\r\n          if ((d | 0) == (j | 0)) { b[c >> 2] = b[f >> 2]; }else {\r\n            d = d + 32 | 0;\r\n            c = b[d >> 2] | 0;\r\n            if (!c) { break; }\r\n            while (1) {\r\n              if ((c | 0) == (j | 0)) { break; }\r\n              d = c + 32 | 0;\r\n              c = b[d >> 2] | 0;\r\n              if (!c) { break b; }\r\n            }\r\n            b[d >> 2] = b[f >> 2];\r\n          }\r\n          Ed(j);\r\n          b[i >> 2] = (b[i >> 2] | 0) + -1;\r\n        } } while (0);\r\n      }\r\n      Ed(b[a >> 2] | 0);\r\n      return;\r\n    }\r\n    function wd(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      e = b[a + 4 >> 2] | 0;\r\n      d = 0;\r\n      while (1) {\r\n        if ((d | 0) >= (e | 0)) {\r\n          c = 0;\r\n          d = 4;\r\n          break;\r\n        }\r\n        c = b[(b[a >> 2] | 0) + (d << 2) >> 2] | 0;\r\n        if (!c) { d = d + 1 | 0; }else {\r\n          d = 4;\r\n          break;\r\n        }\r\n      }\r\n      if ((d | 0) == 4) { return c | 0; }\r\n      return 0;\r\n    }\r\n    function xd(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      d = ~~(+q(+(+s(10.0, + +(15 - (b[a + 12 >> 2] | 0) | 0)) * (+e[c >> 3] + +e[c + 8 >> 3]))) % +(b[a + 4 >> 2] | 0)) >>> 0;\r\n      d = (b[a >> 2] | 0) + (d << 2) | 0;\r\n      f = b[d >> 2] | 0;\r\n      if (!f) {\r\n        h = 1;\r\n        return h | 0;\r\n      }\r\n      h = c + 32 | 0;\r\n      do { if ((f | 0) != (c | 0)) {\r\n        d = b[f + 32 >> 2] | 0;\r\n        if (!d) {\r\n          h = 1;\r\n          return h | 0;\r\n        }\r\n        g = d;\r\n        while (1) {\r\n          if ((g | 0) == (c | 0)) {\r\n            g = 8;\r\n            break;\r\n          }\r\n          d = b[g + 32 >> 2] | 0;\r\n          if (!d) {\r\n            d = 1;\r\n            g = 10;\r\n            break;\r\n          } else {\r\n            f = g;\r\n            g = d;\r\n          }\r\n        }\r\n        if ((g | 0) == 8) {\r\n          b[f + 32 >> 2] = b[h >> 2];\r\n          break;\r\n        } else if ((g | 0) == 10) { return d | 0; }\r\n      } else { b[d >> 2] = b[h >> 2]; } } while (0);\r\n      Ed(c);\r\n      h = a + 8 | 0;\r\n      b[h >> 2] = (b[h >> 2] | 0) + -1;\r\n      h = 0;\r\n      return h | 0;\r\n    }\r\n    function yd(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = Dd(40) | 0;\r\n      if (!h) { I(27872, 27842, 98, 27885); }\r\n      b[h >> 2] = b[c >> 2];\r\n      b[h + 4 >> 2] = b[c + 4 >> 2];\r\n      b[h + 8 >> 2] = b[c + 8 >> 2];\r\n      b[h + 12 >> 2] = b[c + 12 >> 2];\r\n      g = h + 16 | 0;\r\n      b[g >> 2] = b[d >> 2];\r\n      b[g + 4 >> 2] = b[d + 4 >> 2];\r\n      b[g + 8 >> 2] = b[d + 8 >> 2];\r\n      b[g + 12 >> 2] = b[d + 12 >> 2];\r\n      b[h + 32 >> 2] = 0;\r\n      g = ~~(+q(+(+s(10.0, + +(15 - (b[a + 12 >> 2] | 0) | 0)) * (+e[c >> 3] + +e[c + 8 >> 3]))) % +(b[a + 4 >> 2] | 0)) >>> 0;\r\n      g = (b[a >> 2] | 0) + (g << 2) | 0;\r\n      f = b[g >> 2] | 0;\r\n      do { if (!f) { b[g >> 2] = h; }else {\r\n        while (1) {\r\n          if (jc(f, c) | 0 ? jc(f + 16 | 0, d) | 0 : 0) { break; }\r\n          g = b[f + 32 >> 2] | 0;\r\n          f = (g | 0) == 0 ? f : g;\r\n          if (!(b[f + 32 >> 2] | 0)) {\r\n            i = 10;\r\n            break;\r\n          }\r\n        }\r\n        if ((i | 0) == 10) {\r\n          b[f + 32 >> 2] = h;\r\n          break;\r\n        }\r\n        Ed(h);\r\n        i = f;\r\n        return i | 0;\r\n      } } while (0);\r\n      i = a + 8 | 0;\r\n      b[i >> 2] = (b[i >> 2] | 0) + 1;\r\n      i = h;\r\n      return i | 0;\r\n    }\r\n    function zd(a, c, d) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var f = 0,\r\n        g = 0;\r\n      g = ~~(+q(+(+s(10.0, + +(15 - (b[a + 12 >> 2] | 0) | 0)) * (+e[c >> 3] + +e[c + 8 >> 3]))) % +(b[a + 4 >> 2] | 0)) >>> 0;\r\n      g = b[(b[a >> 2] | 0) + (g << 2) >> 2] | 0;\r\n      if (!g) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      if (!d) {\r\n        a = g;\r\n        while (1) {\r\n          if (jc(a, c) | 0) {\r\n            f = 10;\r\n            break;\r\n          }\r\n          a = b[a + 32 >> 2] | 0;\r\n          if (!a) {\r\n            a = 0;\r\n            f = 10;\r\n            break;\r\n          }\r\n        }\r\n        if ((f | 0) == 10) { return a | 0; }\r\n      }\r\n      a = g;\r\n      while (1) {\r\n        if (jc(a, c) | 0 ? jc(a + 16 | 0, d) | 0 : 0) {\r\n          f = 10;\r\n          break;\r\n        }\r\n        a = b[a + 32 >> 2] | 0;\r\n        if (!a) {\r\n          a = 0;\r\n          f = 10;\r\n          break;\r\n        }\r\n      }\r\n      if ((f | 0) == 10) { return a | 0; }\r\n      return 0;\r\n    }\r\n    function Ad(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0;\r\n      d = ~~(+q(+(+s(10.0, + +(15 - (b[a + 12 >> 2] | 0) | 0)) * (+e[c >> 3] + +e[c + 8 >> 3]))) % +(b[a + 4 >> 2] | 0)) >>> 0;\r\n      a = b[(b[a >> 2] | 0) + (d << 2) >> 2] | 0;\r\n      if (!a) {\r\n        d = 0;\r\n        return d | 0;\r\n      }\r\n      while (1) {\r\n        if (jc(a, c) | 0) {\r\n          c = 5;\r\n          break;\r\n        }\r\n        a = b[a + 32 >> 2] | 0;\r\n        if (!a) {\r\n          a = 0;\r\n          c = 5;\r\n          break;\r\n        }\r\n      }\r\n      if ((c | 0) == 5) { return a | 0; }\r\n      return 0;\r\n    }\r\n    function Bd() {\r\n      return 27904;\r\n    }\r\n    function Cd(a) {\r\n      a = +a;\r\n      return ~~+Yd(+a) | 0;\r\n    }\r\n    function Dd(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0,\r\n        q = 0,\r\n        r = 0,\r\n        s = 0,\r\n        t = 0,\r\n        u = 0,\r\n        v = 0,\r\n        w = 0;\r\n      w = T;\r\n      T = T + 16 | 0;\r\n      n = w;\r\n      do { if (a >>> 0 < 245) {\r\n        k = a >>> 0 < 11 ? 16 : a + 11 & -8;\r\n        a = k >>> 3;\r\n        m = b[6977] | 0;\r\n        d = m >>> a;\r\n        if (d & 3 | 0) {\r\n          c = (d & 1 ^ 1) + a | 0;\r\n          a = 27948 + (c << 1 << 2) | 0;\r\n          d = a + 8 | 0;\r\n          e = b[d >> 2] | 0;\r\n          f = e + 8 | 0;\r\n          g = b[f >> 2] | 0;\r\n          if ((g | 0) == (a | 0)) { b[6977] = m & ~(1 << c); }else {\r\n            b[g + 12 >> 2] = a;\r\n            b[d >> 2] = g;\r\n          }\r\n          v = c << 3;\r\n          b[e + 4 >> 2] = v | 3;\r\n          v = e + v + 4 | 0;\r\n          b[v >> 2] = b[v >> 2] | 1;\r\n          v = f;\r\n          T = w;\r\n          return v | 0;\r\n        }\r\n        l = b[6979] | 0;\r\n        if (k >>> 0 > l >>> 0) {\r\n          if (d | 0) {\r\n            c = 2 << a;\r\n            c = d << a & (c | 0 - c);\r\n            c = (c & 0 - c) + -1 | 0;\r\n            i = c >>> 12 & 16;\r\n            c = c >>> i;\r\n            d = c >>> 5 & 8;\r\n            c = c >>> d;\r\n            g = c >>> 2 & 4;\r\n            c = c >>> g;\r\n            a = c >>> 1 & 2;\r\n            c = c >>> a;\r\n            e = c >>> 1 & 1;\r\n            e = (d | i | g | a | e) + (c >>> e) | 0;\r\n            c = 27948 + (e << 1 << 2) | 0;\r\n            a = c + 8 | 0;\r\n            g = b[a >> 2] | 0;\r\n            i = g + 8 | 0;\r\n            d = b[i >> 2] | 0;\r\n            if ((d | 0) == (c | 0)) {\r\n              a = m & ~(1 << e);\r\n              b[6977] = a;\r\n            } else {\r\n              b[d + 12 >> 2] = c;\r\n              b[a >> 2] = d;\r\n              a = m;\r\n            }\r\n            v = e << 3;\r\n            h = v - k | 0;\r\n            b[g + 4 >> 2] = k | 3;\r\n            f = g + k | 0;\r\n            b[f + 4 >> 2] = h | 1;\r\n            b[g + v >> 2] = h;\r\n            if (l | 0) {\r\n              e = b[6982] | 0;\r\n              c = l >>> 3;\r\n              d = 27948 + (c << 1 << 2) | 0;\r\n              c = 1 << c;\r\n              if (!(a & c)) {\r\n                b[6977] = a | c;\r\n                c = d;\r\n                a = d + 8 | 0;\r\n              } else {\r\n                a = d + 8 | 0;\r\n                c = b[a >> 2] | 0;\r\n              }\r\n              b[a >> 2] = e;\r\n              b[c + 12 >> 2] = e;\r\n              b[e + 8 >> 2] = c;\r\n              b[e + 12 >> 2] = d;\r\n            }\r\n            b[6979] = h;\r\n            b[6982] = f;\r\n            v = i;\r\n            T = w;\r\n            return v | 0;\r\n          }\r\n          g = b[6978] | 0;\r\n          if (g) {\r\n            d = (g & 0 - g) + -1 | 0;\r\n            f = d >>> 12 & 16;\r\n            d = d >>> f;\r\n            e = d >>> 5 & 8;\r\n            d = d >>> e;\r\n            h = d >>> 2 & 4;\r\n            d = d >>> h;\r\n            i = d >>> 1 & 2;\r\n            d = d >>> i;\r\n            j = d >>> 1 & 1;\r\n            j = b[28212 + ((e | f | h | i | j) + (d >>> j) << 2) >> 2] | 0;\r\n            d = j;\r\n            i = j;\r\n            j = (b[j + 4 >> 2] & -8) - k | 0;\r\n            while (1) {\r\n              a = b[d + 16 >> 2] | 0;\r\n              if (!a) {\r\n                a = b[d + 20 >> 2] | 0;\r\n                if (!a) { break; }\r\n              }\r\n              h = (b[a + 4 >> 2] & -8) - k | 0;\r\n              f = h >>> 0 < j >>> 0;\r\n              d = a;\r\n              i = f ? a : i;\r\n              j = f ? h : j;\r\n            }\r\n            h = i + k | 0;\r\n            if (h >>> 0 > i >>> 0) {\r\n              f = b[i + 24 >> 2] | 0;\r\n              c = b[i + 12 >> 2] | 0;\r\n              do { if ((c | 0) == (i | 0)) {\r\n                a = i + 20 | 0;\r\n                c = b[a >> 2] | 0;\r\n                if (!c) {\r\n                  a = i + 16 | 0;\r\n                  c = b[a >> 2] | 0;\r\n                  if (!c) {\r\n                    d = 0;\r\n                    break;\r\n                  }\r\n                }\r\n                while (1) {\r\n                  e = c + 20 | 0;\r\n                  d = b[e >> 2] | 0;\r\n                  if (!d) {\r\n                    e = c + 16 | 0;\r\n                    d = b[e >> 2] | 0;\r\n                    if (!d) { break; }else {\r\n                      c = d;\r\n                      a = e;\r\n                    }\r\n                  } else {\r\n                    c = d;\r\n                    a = e;\r\n                  }\r\n                }\r\n                b[a >> 2] = 0;\r\n                d = c;\r\n              } else {\r\n                d = b[i + 8 >> 2] | 0;\r\n                b[d + 12 >> 2] = c;\r\n                b[c + 8 >> 2] = d;\r\n                d = c;\r\n              } } while (0);\r\n              do { if (f | 0) {\r\n                c = b[i + 28 >> 2] | 0;\r\n                a = 28212 + (c << 2) | 0;\r\n                if ((i | 0) == (b[a >> 2] | 0)) {\r\n                  b[a >> 2] = d;\r\n                  if (!d) {\r\n                    b[6978] = g & ~(1 << c);\r\n                    break;\r\n                  }\r\n                } else {\r\n                  v = f + 16 | 0;\r\n                  b[((b[v >> 2] | 0) == (i | 0) ? v : f + 20 | 0) >> 2] = d;\r\n                  if (!d) { break; }\r\n                }\r\n                b[d + 24 >> 2] = f;\r\n                c = b[i + 16 >> 2] | 0;\r\n                if (c | 0) {\r\n                  b[d + 16 >> 2] = c;\r\n                  b[c + 24 >> 2] = d;\r\n                }\r\n                c = b[i + 20 >> 2] | 0;\r\n                if (c | 0) {\r\n                  b[d + 20 >> 2] = c;\r\n                  b[c + 24 >> 2] = d;\r\n                }\r\n              } } while (0);\r\n              if (j >>> 0 < 16) {\r\n                v = j + k | 0;\r\n                b[i + 4 >> 2] = v | 3;\r\n                v = i + v + 4 | 0;\r\n                b[v >> 2] = b[v >> 2] | 1;\r\n              } else {\r\n                b[i + 4 >> 2] = k | 3;\r\n                b[h + 4 >> 2] = j | 1;\r\n                b[h + j >> 2] = j;\r\n                if (l | 0) {\r\n                  e = b[6982] | 0;\r\n                  c = l >>> 3;\r\n                  d = 27948 + (c << 1 << 2) | 0;\r\n                  c = 1 << c;\r\n                  if (!(c & m)) {\r\n                    b[6977] = c | m;\r\n                    c = d;\r\n                    a = d + 8 | 0;\r\n                  } else {\r\n                    a = d + 8 | 0;\r\n                    c = b[a >> 2] | 0;\r\n                  }\r\n                  b[a >> 2] = e;\r\n                  b[c + 12 >> 2] = e;\r\n                  b[e + 8 >> 2] = c;\r\n                  b[e + 12 >> 2] = d;\r\n                }\r\n                b[6979] = j;\r\n                b[6982] = h;\r\n              }\r\n              v = i + 8 | 0;\r\n              T = w;\r\n              return v | 0;\r\n            } else { m = k; }\r\n          } else { m = k; }\r\n        } else { m = k; }\r\n      } else if (a >>> 0 <= 4294967231) {\r\n        a = a + 11 | 0;\r\n        k = a & -8;\r\n        e = b[6978] | 0;\r\n        if (e) {\r\n          f = 0 - k | 0;\r\n          a = a >>> 8;\r\n          if (a) {\r\n            if (k >>> 0 > 16777215) { j = 31; }else {\r\n              m = (a + 1048320 | 0) >>> 16 & 8;\r\n              q = a << m;\r\n              i = (q + 520192 | 0) >>> 16 & 4;\r\n              q = q << i;\r\n              j = (q + 245760 | 0) >>> 16 & 2;\r\n              j = 14 - (i | m | j) + (q << j >>> 15) | 0;\r\n              j = k >>> (j + 7 | 0) & 1 | j << 1;\r\n            }\r\n          } else { j = 0; }\r\n          d = b[28212 + (j << 2) >> 2] | 0;\r\n          a: do { if (!d) {\r\n            d = 0;\r\n            a = 0;\r\n            q = 61;\r\n          } else {\r\n            a = 0;\r\n            i = k << ((j | 0) == 31 ? 0 : 25 - (j >>> 1) | 0);\r\n            g = 0;\r\n            while (1) {\r\n              h = (b[d + 4 >> 2] & -8) - k | 0;\r\n              if (h >>> 0 < f >>> 0) { if (!h) {\r\n                a = d;\r\n                f = 0;\r\n                q = 65;\r\n                break a;\r\n              } else {\r\n                a = d;\r\n                f = h;\r\n              } }\r\n              q = b[d + 20 >> 2] | 0;\r\n              d = b[d + 16 + (i >>> 31 << 2) >> 2] | 0;\r\n              g = (q | 0) == 0 | (q | 0) == (d | 0) ? g : q;\r\n              if (!d) {\r\n                d = g;\r\n                q = 61;\r\n                break;\r\n              } else { i = i << 1; }\r\n            }\r\n          } } while (0);\r\n          if ((q | 0) == 61) {\r\n            if ((d | 0) == 0 & (a | 0) == 0) {\r\n              a = 2 << j;\r\n              a = (a | 0 - a) & e;\r\n              if (!a) {\r\n                m = k;\r\n                break;\r\n              }\r\n              m = (a & 0 - a) + -1 | 0;\r\n              h = m >>> 12 & 16;\r\n              m = m >>> h;\r\n              g = m >>> 5 & 8;\r\n              m = m >>> g;\r\n              i = m >>> 2 & 4;\r\n              m = m >>> i;\r\n              j = m >>> 1 & 2;\r\n              m = m >>> j;\r\n              d = m >>> 1 & 1;\r\n              a = 0;\r\n              d = b[28212 + ((g | h | i | j | d) + (m >>> d) << 2) >> 2] | 0;\r\n            }\r\n            if (!d) {\r\n              i = a;\r\n              h = f;\r\n            } else { q = 65; }\r\n          }\r\n          if ((q | 0) == 65) {\r\n            g = d;\r\n            while (1) {\r\n              m = (b[g + 4 >> 2] & -8) - k | 0;\r\n              d = m >>> 0 < f >>> 0;\r\n              f = d ? m : f;\r\n              a = d ? g : a;\r\n              d = b[g + 16 >> 2] | 0;\r\n              if (!d) { d = b[g + 20 >> 2] | 0; }\r\n              if (!d) {\r\n                i = a;\r\n                h = f;\r\n                break;\r\n              } else { g = d; }\r\n            }\r\n          }\r\n          if (((i | 0) != 0 ? h >>> 0 < ((b[6979] | 0) - k | 0) >>> 0 : 0) ? (l = i + k | 0, l >>> 0 > i >>> 0) : 0) {\r\n            g = b[i + 24 >> 2] | 0;\r\n            c = b[i + 12 >> 2] | 0;\r\n            do { if ((c | 0) == (i | 0)) {\r\n              a = i + 20 | 0;\r\n              c = b[a >> 2] | 0;\r\n              if (!c) {\r\n                a = i + 16 | 0;\r\n                c = b[a >> 2] | 0;\r\n                if (!c) {\r\n                  c = 0;\r\n                  break;\r\n                }\r\n              }\r\n              while (1) {\r\n                f = c + 20 | 0;\r\n                d = b[f >> 2] | 0;\r\n                if (!d) {\r\n                  f = c + 16 | 0;\r\n                  d = b[f >> 2] | 0;\r\n                  if (!d) { break; }else {\r\n                    c = d;\r\n                    a = f;\r\n                  }\r\n                } else {\r\n                  c = d;\r\n                  a = f;\r\n                }\r\n              }\r\n              b[a >> 2] = 0;\r\n            } else {\r\n              v = b[i + 8 >> 2] | 0;\r\n              b[v + 12 >> 2] = c;\r\n              b[c + 8 >> 2] = v;\r\n            } } while (0);\r\n            do { if (g) {\r\n              a = b[i + 28 >> 2] | 0;\r\n              d = 28212 + (a << 2) | 0;\r\n              if ((i | 0) == (b[d >> 2] | 0)) {\r\n                b[d >> 2] = c;\r\n                if (!c) {\r\n                  e = e & ~(1 << a);\r\n                  b[6978] = e;\r\n                  break;\r\n                }\r\n              } else {\r\n                v = g + 16 | 0;\r\n                b[((b[v >> 2] | 0) == (i | 0) ? v : g + 20 | 0) >> 2] = c;\r\n                if (!c) { break; }\r\n              }\r\n              b[c + 24 >> 2] = g;\r\n              a = b[i + 16 >> 2] | 0;\r\n              if (a | 0) {\r\n                b[c + 16 >> 2] = a;\r\n                b[a + 24 >> 2] = c;\r\n              }\r\n              a = b[i + 20 >> 2] | 0;\r\n              if (a) {\r\n                b[c + 20 >> 2] = a;\r\n                b[a + 24 >> 2] = c;\r\n              }\r\n            } } while (0);\r\n            b: do { if (h >>> 0 < 16) {\r\n              v = h + k | 0;\r\n              b[i + 4 >> 2] = v | 3;\r\n              v = i + v + 4 | 0;\r\n              b[v >> 2] = b[v >> 2] | 1;\r\n            } else {\r\n              b[i + 4 >> 2] = k | 3;\r\n              b[l + 4 >> 2] = h | 1;\r\n              b[l + h >> 2] = h;\r\n              c = h >>> 3;\r\n              if (h >>> 0 < 256) {\r\n                d = 27948 + (c << 1 << 2) | 0;\r\n                a = b[6977] | 0;\r\n                c = 1 << c;\r\n                if (!(a & c)) {\r\n                  b[6977] = a | c;\r\n                  c = d;\r\n                  a = d + 8 | 0;\r\n                } else {\r\n                  a = d + 8 | 0;\r\n                  c = b[a >> 2] | 0;\r\n                }\r\n                b[a >> 2] = l;\r\n                b[c + 12 >> 2] = l;\r\n                b[l + 8 >> 2] = c;\r\n                b[l + 12 >> 2] = d;\r\n                break;\r\n              }\r\n              c = h >>> 8;\r\n              if (c) {\r\n                if (h >>> 0 > 16777215) { d = 31; }else {\r\n                  u = (c + 1048320 | 0) >>> 16 & 8;\r\n                  v = c << u;\r\n                  t = (v + 520192 | 0) >>> 16 & 4;\r\n                  v = v << t;\r\n                  d = (v + 245760 | 0) >>> 16 & 2;\r\n                  d = 14 - (t | u | d) + (v << d >>> 15) | 0;\r\n                  d = h >>> (d + 7 | 0) & 1 | d << 1;\r\n                }\r\n              } else { d = 0; }\r\n              c = 28212 + (d << 2) | 0;\r\n              b[l + 28 >> 2] = d;\r\n              a = l + 16 | 0;\r\n              b[a + 4 >> 2] = 0;\r\n              b[a >> 2] = 0;\r\n              a = 1 << d;\r\n              if (!(e & a)) {\r\n                b[6978] = e | a;\r\n                b[c >> 2] = l;\r\n                b[l + 24 >> 2] = c;\r\n                b[l + 12 >> 2] = l;\r\n                b[l + 8 >> 2] = l;\r\n                break;\r\n              }\r\n              c = b[c >> 2] | 0;\r\n              c: do { if ((b[c + 4 >> 2] & -8 | 0) != (h | 0)) {\r\n                e = h << ((d | 0) == 31 ? 0 : 25 - (d >>> 1) | 0);\r\n                while (1) {\r\n                  d = c + 16 + (e >>> 31 << 2) | 0;\r\n                  a = b[d >> 2] | 0;\r\n                  if (!a) { break; }\r\n                  if ((b[a + 4 >> 2] & -8 | 0) == (h | 0)) {\r\n                    c = a;\r\n                    break c;\r\n                  } else {\r\n                    e = e << 1;\r\n                    c = a;\r\n                  }\r\n                }\r\n                b[d >> 2] = l;\r\n                b[l + 24 >> 2] = c;\r\n                b[l + 12 >> 2] = l;\r\n                b[l + 8 >> 2] = l;\r\n                break b;\r\n              } } while (0);\r\n              u = c + 8 | 0;\r\n              v = b[u >> 2] | 0;\r\n              b[v + 12 >> 2] = l;\r\n              b[u >> 2] = l;\r\n              b[l + 8 >> 2] = v;\r\n              b[l + 12 >> 2] = c;\r\n              b[l + 24 >> 2] = 0;\r\n            } } while (0);\r\n            v = i + 8 | 0;\r\n            T = w;\r\n            return v | 0;\r\n          } else { m = k; }\r\n        } else { m = k; }\r\n      } else { m = -1; } } while (0);\r\n      d = b[6979] | 0;\r\n      if (d >>> 0 >= m >>> 0) {\r\n        c = d - m | 0;\r\n        a = b[6982] | 0;\r\n        if (c >>> 0 > 15) {\r\n          v = a + m | 0;\r\n          b[6982] = v;\r\n          b[6979] = c;\r\n          b[v + 4 >> 2] = c | 1;\r\n          b[a + d >> 2] = c;\r\n          b[a + 4 >> 2] = m | 3;\r\n        } else {\r\n          b[6979] = 0;\r\n          b[6982] = 0;\r\n          b[a + 4 >> 2] = d | 3;\r\n          v = a + d + 4 | 0;\r\n          b[v >> 2] = b[v >> 2] | 1;\r\n        }\r\n        v = a + 8 | 0;\r\n        T = w;\r\n        return v | 0;\r\n      }\r\n      h = b[6980] | 0;\r\n      if (h >>> 0 > m >>> 0) {\r\n        t = h - m | 0;\r\n        b[6980] = t;\r\n        v = b[6983] | 0;\r\n        u = v + m | 0;\r\n        b[6983] = u;\r\n        b[u + 4 >> 2] = t | 1;\r\n        b[v + 4 >> 2] = m | 3;\r\n        v = v + 8 | 0;\r\n        T = w;\r\n        return v | 0;\r\n      }\r\n      if (!(b[7095] | 0)) {\r\n        b[7097] = 4096;\r\n        b[7096] = 4096;\r\n        b[7098] = -1;\r\n        b[7099] = -1;\r\n        b[7100] = 0;\r\n        b[7088] = 0;\r\n        b[7095] = n & -16 ^ 1431655768;\r\n        a = 4096;\r\n      } else { a = b[7097] | 0; }\r\n      i = m + 48 | 0;\r\n      j = m + 47 | 0;\r\n      g = a + j | 0;\r\n      f = 0 - a | 0;\r\n      k = g & f;\r\n      if (k >>> 0 <= m >>> 0) {\r\n        v = 0;\r\n        T = w;\r\n        return v | 0;\r\n      }\r\n      a = b[7087] | 0;\r\n      if (a | 0 ? (l = b[7085] | 0, n = l + k | 0, n >>> 0 <= l >>> 0 | n >>> 0 > a >>> 0) : 0) {\r\n        v = 0;\r\n        T = w;\r\n        return v | 0;\r\n      }\r\n      d: do { if (!(b[7088] & 4)) {\r\n        d = b[6983] | 0;\r\n        e: do { if (d) {\r\n          e = 28356;\r\n          while (1) {\r\n            n = b[e >> 2] | 0;\r\n            if (n >>> 0 <= d >>> 0 ? (n + (b[e + 4 >> 2] | 0) | 0) >>> 0 > d >>> 0 : 0) { break; }\r\n            a = b[e + 8 >> 2] | 0;\r\n            if (!a) {\r\n              q = 128;\r\n              break e;\r\n            } else { e = a; }\r\n          }\r\n          c = g - h & f;\r\n          if (c >>> 0 < 2147483647) {\r\n            a = Zd(c | 0) | 0;\r\n            if ((a | 0) == ((b[e >> 2] | 0) + (b[e + 4 >> 2] | 0) | 0)) {\r\n              if ((a | 0) != (-1 | 0)) {\r\n                h = c;\r\n                g = a;\r\n                q = 145;\r\n                break d;\r\n              }\r\n            } else {\r\n              e = a;\r\n              q = 136;\r\n            }\r\n          } else { c = 0; }\r\n        } else { q = 128; } } while (0);\r\n        do { if ((q | 0) == 128) {\r\n          d = Zd(0) | 0;\r\n          if ((d | 0) != (-1 | 0) ? (c = d, o = b[7096] | 0, p = o + -1 | 0, c = ((p & c | 0) == 0 ? 0 : (p + c & 0 - o) - c | 0) + k | 0, o = b[7085] | 0, p = c + o | 0, c >>> 0 > m >>> 0 & c >>> 0 < 2147483647) : 0) {\r\n            n = b[7087] | 0;\r\n            if (n | 0 ? p >>> 0 <= o >>> 0 | p >>> 0 > n >>> 0 : 0) {\r\n              c = 0;\r\n              break;\r\n            }\r\n            a = Zd(c | 0) | 0;\r\n            if ((a | 0) == (d | 0)) {\r\n              h = c;\r\n              g = d;\r\n              q = 145;\r\n              break d;\r\n            } else {\r\n              e = a;\r\n              q = 136;\r\n            }\r\n          } else { c = 0; }\r\n        } } while (0);\r\n        do { if ((q | 0) == 136) {\r\n          d = 0 - c | 0;\r\n          if (!(i >>> 0 > c >>> 0 & (c >>> 0 < 2147483647 & (e | 0) != (-1 | 0)))) { if ((e | 0) == (-1 | 0)) {\r\n            c = 0;\r\n            break;\r\n          } else {\r\n            h = c;\r\n            g = e;\r\n            q = 145;\r\n            break d;\r\n          } }\r\n          a = b[7097] | 0;\r\n          a = j - c + a & 0 - a;\r\n          if (a >>> 0 >= 2147483647) {\r\n            h = c;\r\n            g = e;\r\n            q = 145;\r\n            break d;\r\n          }\r\n          if ((Zd(a | 0) | 0) == (-1 | 0)) {\r\n            Zd(d | 0) | 0;\r\n            c = 0;\r\n            break;\r\n          } else {\r\n            h = a + c | 0;\r\n            g = e;\r\n            q = 145;\r\n            break d;\r\n          }\r\n        } } while (0);\r\n        b[7088] = b[7088] | 4;\r\n        q = 143;\r\n      } else {\r\n        c = 0;\r\n        q = 143;\r\n      } } while (0);\r\n      if (((q | 0) == 143 ? k >>> 0 < 2147483647 : 0) ? (t = Zd(k | 0) | 0, p = Zd(0) | 0, r = p - t | 0, s = r >>> 0 > (m + 40 | 0) >>> 0, !((t | 0) == (-1 | 0) | s ^ 1 | t >>> 0 < p >>> 0 & ((t | 0) != (-1 | 0) & (p | 0) != (-1 | 0)) ^ 1)) : 0) {\r\n        h = s ? r : c;\r\n        g = t;\r\n        q = 145;\r\n      }\r\n      if ((q | 0) == 145) {\r\n        c = (b[7085] | 0) + h | 0;\r\n        b[7085] = c;\r\n        if (c >>> 0 > (b[7086] | 0) >>> 0) { b[7086] = c; }\r\n        j = b[6983] | 0;\r\n        f: do { if (j) {\r\n          c = 28356;\r\n          while (1) {\r\n            a = b[c >> 2] | 0;\r\n            d = b[c + 4 >> 2] | 0;\r\n            if ((g | 0) == (a + d | 0)) {\r\n              q = 154;\r\n              break;\r\n            }\r\n            e = b[c + 8 >> 2] | 0;\r\n            if (!e) { break; }else { c = e; }\r\n          }\r\n          if (((q | 0) == 154 ? (u = c + 4 | 0, (b[c + 12 >> 2] & 8 | 0) == 0) : 0) ? g >>> 0 > j >>> 0 & a >>> 0 <= j >>> 0 : 0) {\r\n            b[u >> 2] = d + h;\r\n            v = (b[6980] | 0) + h | 0;\r\n            t = j + 8 | 0;\r\n            t = (t & 7 | 0) == 0 ? 0 : 0 - t & 7;\r\n            u = j + t | 0;\r\n            t = v - t | 0;\r\n            b[6983] = u;\r\n            b[6980] = t;\r\n            b[u + 4 >> 2] = t | 1;\r\n            b[j + v + 4 >> 2] = 40;\r\n            b[6984] = b[7099];\r\n            break;\r\n          }\r\n          if (g >>> 0 < (b[6981] | 0) >>> 0) { b[6981] = g; }\r\n          d = g + h | 0;\r\n          c = 28356;\r\n          while (1) {\r\n            if ((b[c >> 2] | 0) == (d | 0)) {\r\n              q = 162;\r\n              break;\r\n            }\r\n            a = b[c + 8 >> 2] | 0;\r\n            if (!a) { break; }else { c = a; }\r\n          }\r\n          if ((q | 0) == 162 ? (b[c + 12 >> 2] & 8 | 0) == 0 : 0) {\r\n            b[c >> 2] = g;\r\n            l = c + 4 | 0;\r\n            b[l >> 2] = (b[l >> 2] | 0) + h;\r\n            l = g + 8 | 0;\r\n            l = g + ((l & 7 | 0) == 0 ? 0 : 0 - l & 7) | 0;\r\n            c = d + 8 | 0;\r\n            c = d + ((c & 7 | 0) == 0 ? 0 : 0 - c & 7) | 0;\r\n            k = l + m | 0;\r\n            i = c - l - m | 0;\r\n            b[l + 4 >> 2] = m | 3;\r\n            g: do { if ((j | 0) == (c | 0)) {\r\n              v = (b[6980] | 0) + i | 0;\r\n              b[6980] = v;\r\n              b[6983] = k;\r\n              b[k + 4 >> 2] = v | 1;\r\n            } else {\r\n              if ((b[6982] | 0) == (c | 0)) {\r\n                v = (b[6979] | 0) + i | 0;\r\n                b[6979] = v;\r\n                b[6982] = k;\r\n                b[k + 4 >> 2] = v | 1;\r\n                b[k + v >> 2] = v;\r\n                break;\r\n              }\r\n              a = b[c + 4 >> 2] | 0;\r\n              if ((a & 3 | 0) == 1) {\r\n                h = a & -8;\r\n                e = a >>> 3;\r\n                h: do { if (a >>> 0 < 256) {\r\n                  a = b[c + 8 >> 2] | 0;\r\n                  d = b[c + 12 >> 2] | 0;\r\n                  if ((d | 0) == (a | 0)) {\r\n                    b[6977] = b[6977] & ~(1 << e);\r\n                    break;\r\n                  } else {\r\n                    b[a + 12 >> 2] = d;\r\n                    b[d + 8 >> 2] = a;\r\n                    break;\r\n                  }\r\n                } else {\r\n                  g = b[c + 24 >> 2] | 0;\r\n                  a = b[c + 12 >> 2] | 0;\r\n                  do { if ((a | 0) == (c | 0)) {\r\n                    d = c + 16 | 0;\r\n                    e = d + 4 | 0;\r\n                    a = b[e >> 2] | 0;\r\n                    if (!a) {\r\n                      a = b[d >> 2] | 0;\r\n                      if (!a) {\r\n                        a = 0;\r\n                        break;\r\n                      }\r\n                    } else { d = e; }\r\n                    while (1) {\r\n                      f = a + 20 | 0;\r\n                      e = b[f >> 2] | 0;\r\n                      if (!e) {\r\n                        f = a + 16 | 0;\r\n                        e = b[f >> 2] | 0;\r\n                        if (!e) { break; }else {\r\n                          a = e;\r\n                          d = f;\r\n                        }\r\n                      } else {\r\n                        a = e;\r\n                        d = f;\r\n                      }\r\n                    }\r\n                    b[d >> 2] = 0;\r\n                  } else {\r\n                    v = b[c + 8 >> 2] | 0;\r\n                    b[v + 12 >> 2] = a;\r\n                    b[a + 8 >> 2] = v;\r\n                  } } while (0);\r\n                  if (!g) { break; }\r\n                  d = b[c + 28 >> 2] | 0;\r\n                  e = 28212 + (d << 2) | 0;\r\n                  do { if ((b[e >> 2] | 0) != (c | 0)) {\r\n                    v = g + 16 | 0;\r\n                    b[((b[v >> 2] | 0) == (c | 0) ? v : g + 20 | 0) >> 2] = a;\r\n                    if (!a) { break h; }\r\n                  } else {\r\n                    b[e >> 2] = a;\r\n                    if (a | 0) { break; }\r\n                    b[6978] = b[6978] & ~(1 << d);\r\n                    break h;\r\n                  } } while (0);\r\n                  b[a + 24 >> 2] = g;\r\n                  d = c + 16 | 0;\r\n                  e = b[d >> 2] | 0;\r\n                  if (e | 0) {\r\n                    b[a + 16 >> 2] = e;\r\n                    b[e + 24 >> 2] = a;\r\n                  }\r\n                  d = b[d + 4 >> 2] | 0;\r\n                  if (!d) { break; }\r\n                  b[a + 20 >> 2] = d;\r\n                  b[d + 24 >> 2] = a;\r\n                } } while (0);\r\n                c = c + h | 0;\r\n                f = h + i | 0;\r\n              } else { f = i; }\r\n              c = c + 4 | 0;\r\n              b[c >> 2] = b[c >> 2] & -2;\r\n              b[k + 4 >> 2] = f | 1;\r\n              b[k + f >> 2] = f;\r\n              c = f >>> 3;\r\n              if (f >>> 0 < 256) {\r\n                d = 27948 + (c << 1 << 2) | 0;\r\n                a = b[6977] | 0;\r\n                c = 1 << c;\r\n                if (!(a & c)) {\r\n                  b[6977] = a | c;\r\n                  c = d;\r\n                  a = d + 8 | 0;\r\n                } else {\r\n                  a = d + 8 | 0;\r\n                  c = b[a >> 2] | 0;\r\n                }\r\n                b[a >> 2] = k;\r\n                b[c + 12 >> 2] = k;\r\n                b[k + 8 >> 2] = c;\r\n                b[k + 12 >> 2] = d;\r\n                break;\r\n              }\r\n              c = f >>> 8;\r\n              do { if (!c) { e = 0; }else {\r\n                if (f >>> 0 > 16777215) {\r\n                  e = 31;\r\n                  break;\r\n                }\r\n                u = (c + 1048320 | 0) >>> 16 & 8;\r\n                v = c << u;\r\n                t = (v + 520192 | 0) >>> 16 & 4;\r\n                v = v << t;\r\n                e = (v + 245760 | 0) >>> 16 & 2;\r\n                e = 14 - (t | u | e) + (v << e >>> 15) | 0;\r\n                e = f >>> (e + 7 | 0) & 1 | e << 1;\r\n              } } while (0);\r\n              c = 28212 + (e << 2) | 0;\r\n              b[k + 28 >> 2] = e;\r\n              a = k + 16 | 0;\r\n              b[a + 4 >> 2] = 0;\r\n              b[a >> 2] = 0;\r\n              a = b[6978] | 0;\r\n              d = 1 << e;\r\n              if (!(a & d)) {\r\n                b[6978] = a | d;\r\n                b[c >> 2] = k;\r\n                b[k + 24 >> 2] = c;\r\n                b[k + 12 >> 2] = k;\r\n                b[k + 8 >> 2] = k;\r\n                break;\r\n              }\r\n              c = b[c >> 2] | 0;\r\n              i: do { if ((b[c + 4 >> 2] & -8 | 0) != (f | 0)) {\r\n                e = f << ((e | 0) == 31 ? 0 : 25 - (e >>> 1) | 0);\r\n                while (1) {\r\n                  d = c + 16 + (e >>> 31 << 2) | 0;\r\n                  a = b[d >> 2] | 0;\r\n                  if (!a) { break; }\r\n                  if ((b[a + 4 >> 2] & -8 | 0) == (f | 0)) {\r\n                    c = a;\r\n                    break i;\r\n                  } else {\r\n                    e = e << 1;\r\n                    c = a;\r\n                  }\r\n                }\r\n                b[d >> 2] = k;\r\n                b[k + 24 >> 2] = c;\r\n                b[k + 12 >> 2] = k;\r\n                b[k + 8 >> 2] = k;\r\n                break g;\r\n              } } while (0);\r\n              u = c + 8 | 0;\r\n              v = b[u >> 2] | 0;\r\n              b[v + 12 >> 2] = k;\r\n              b[u >> 2] = k;\r\n              b[k + 8 >> 2] = v;\r\n              b[k + 12 >> 2] = c;\r\n              b[k + 24 >> 2] = 0;\r\n            } } while (0);\r\n            v = l + 8 | 0;\r\n            T = w;\r\n            return v | 0;\r\n          }\r\n          c = 28356;\r\n          while (1) {\r\n            a = b[c >> 2] | 0;\r\n            if (a >>> 0 <= j >>> 0 ? (v = a + (b[c + 4 >> 2] | 0) | 0, v >>> 0 > j >>> 0) : 0) { break; }\r\n            c = b[c + 8 >> 2] | 0;\r\n          }\r\n          f = v + -47 | 0;\r\n          a = f + 8 | 0;\r\n          a = f + ((a & 7 | 0) == 0 ? 0 : 0 - a & 7) | 0;\r\n          f = j + 16 | 0;\r\n          a = a >>> 0 < f >>> 0 ? j : a;\r\n          c = a + 8 | 0;\r\n          d = h + -40 | 0;\r\n          t = g + 8 | 0;\r\n          t = (t & 7 | 0) == 0 ? 0 : 0 - t & 7;\r\n          u = g + t | 0;\r\n          t = d - t | 0;\r\n          b[6983] = u;\r\n          b[6980] = t;\r\n          b[u + 4 >> 2] = t | 1;\r\n          b[g + d + 4 >> 2] = 40;\r\n          b[6984] = b[7099];\r\n          d = a + 4 | 0;\r\n          b[d >> 2] = 27;\r\n          b[c >> 2] = b[7089];\r\n          b[c + 4 >> 2] = b[7090];\r\n          b[c + 8 >> 2] = b[7091];\r\n          b[c + 12 >> 2] = b[7092];\r\n          b[7089] = g;\r\n          b[7090] = h;\r\n          b[7092] = 0;\r\n          b[7091] = c;\r\n          c = a + 24 | 0;\r\n          do {\r\n            u = c;\r\n            c = c + 4 | 0;\r\n            b[c >> 2] = 7;\r\n          } while ((u + 8 | 0) >>> 0 < v >>> 0);\r\n          if ((a | 0) != (j | 0)) {\r\n            g = a - j | 0;\r\n            b[d >> 2] = b[d >> 2] & -2;\r\n            b[j + 4 >> 2] = g | 1;\r\n            b[a >> 2] = g;\r\n            c = g >>> 3;\r\n            if (g >>> 0 < 256) {\r\n              d = 27948 + (c << 1 << 2) | 0;\r\n              a = b[6977] | 0;\r\n              c = 1 << c;\r\n              if (!(a & c)) {\r\n                b[6977] = a | c;\r\n                c = d;\r\n                a = d + 8 | 0;\r\n              } else {\r\n                a = d + 8 | 0;\r\n                c = b[a >> 2] | 0;\r\n              }\r\n              b[a >> 2] = j;\r\n              b[c + 12 >> 2] = j;\r\n              b[j + 8 >> 2] = c;\r\n              b[j + 12 >> 2] = d;\r\n              break;\r\n            }\r\n            c = g >>> 8;\r\n            if (c) {\r\n              if (g >>> 0 > 16777215) { e = 31; }else {\r\n                u = (c + 1048320 | 0) >>> 16 & 8;\r\n                v = c << u;\r\n                t = (v + 520192 | 0) >>> 16 & 4;\r\n                v = v << t;\r\n                e = (v + 245760 | 0) >>> 16 & 2;\r\n                e = 14 - (t | u | e) + (v << e >>> 15) | 0;\r\n                e = g >>> (e + 7 | 0) & 1 | e << 1;\r\n              }\r\n            } else { e = 0; }\r\n            d = 28212 + (e << 2) | 0;\r\n            b[j + 28 >> 2] = e;\r\n            b[j + 20 >> 2] = 0;\r\n            b[f >> 2] = 0;\r\n            c = b[6978] | 0;\r\n            a = 1 << e;\r\n            if (!(c & a)) {\r\n              b[6978] = c | a;\r\n              b[d >> 2] = j;\r\n              b[j + 24 >> 2] = d;\r\n              b[j + 12 >> 2] = j;\r\n              b[j + 8 >> 2] = j;\r\n              break;\r\n            }\r\n            c = b[d >> 2] | 0;\r\n            j: do { if ((b[c + 4 >> 2] & -8 | 0) != (g | 0)) {\r\n              e = g << ((e | 0) == 31 ? 0 : 25 - (e >>> 1) | 0);\r\n              while (1) {\r\n                d = c + 16 + (e >>> 31 << 2) | 0;\r\n                a = b[d >> 2] | 0;\r\n                if (!a) { break; }\r\n                if ((b[a + 4 >> 2] & -8 | 0) == (g | 0)) {\r\n                  c = a;\r\n                  break j;\r\n                } else {\r\n                  e = e << 1;\r\n                  c = a;\r\n                }\r\n              }\r\n              b[d >> 2] = j;\r\n              b[j + 24 >> 2] = c;\r\n              b[j + 12 >> 2] = j;\r\n              b[j + 8 >> 2] = j;\r\n              break f;\r\n            } } while (0);\r\n            u = c + 8 | 0;\r\n            v = b[u >> 2] | 0;\r\n            b[v + 12 >> 2] = j;\r\n            b[u >> 2] = j;\r\n            b[j + 8 >> 2] = v;\r\n            b[j + 12 >> 2] = c;\r\n            b[j + 24 >> 2] = 0;\r\n          }\r\n        } else {\r\n          v = b[6981] | 0;\r\n          if ((v | 0) == 0 | g >>> 0 < v >>> 0) { b[6981] = g; }\r\n          b[7089] = g;\r\n          b[7090] = h;\r\n          b[7092] = 0;\r\n          b[6986] = b[7095];\r\n          b[6985] = -1;\r\n          b[6990] = 27948;\r\n          b[6989] = 27948;\r\n          b[6992] = 27956;\r\n          b[6991] = 27956;\r\n          b[6994] = 27964;\r\n          b[6993] = 27964;\r\n          b[6996] = 27972;\r\n          b[6995] = 27972;\r\n          b[6998] = 27980;\r\n          b[6997] = 27980;\r\n          b[7e3] = 27988;\r\n          b[6999] = 27988;\r\n          b[7002] = 27996;\r\n          b[7001] = 27996;\r\n          b[7004] = 28004;\r\n          b[7003] = 28004;\r\n          b[7006] = 28012;\r\n          b[7005] = 28012;\r\n          b[7008] = 28020;\r\n          b[7007] = 28020;\r\n          b[7010] = 28028;\r\n          b[7009] = 28028;\r\n          b[7012] = 28036;\r\n          b[7011] = 28036;\r\n          b[7014] = 28044;\r\n          b[7013] = 28044;\r\n          b[7016] = 28052;\r\n          b[7015] = 28052;\r\n          b[7018] = 28060;\r\n          b[7017] = 28060;\r\n          b[7020] = 28068;\r\n          b[7019] = 28068;\r\n          b[7022] = 28076;\r\n          b[7021] = 28076;\r\n          b[7024] = 28084;\r\n          b[7023] = 28084;\r\n          b[7026] = 28092;\r\n          b[7025] = 28092;\r\n          b[7028] = 28100;\r\n          b[7027] = 28100;\r\n          b[7030] = 28108;\r\n          b[7029] = 28108;\r\n          b[7032] = 28116;\r\n          b[7031] = 28116;\r\n          b[7034] = 28124;\r\n          b[7033] = 28124;\r\n          b[7036] = 28132;\r\n          b[7035] = 28132;\r\n          b[7038] = 28140;\r\n          b[7037] = 28140;\r\n          b[7040] = 28148;\r\n          b[7039] = 28148;\r\n          b[7042] = 28156;\r\n          b[7041] = 28156;\r\n          b[7044] = 28164;\r\n          b[7043] = 28164;\r\n          b[7046] = 28172;\r\n          b[7045] = 28172;\r\n          b[7048] = 28180;\r\n          b[7047] = 28180;\r\n          b[7050] = 28188;\r\n          b[7049] = 28188;\r\n          b[7052] = 28196;\r\n          b[7051] = 28196;\r\n          v = h + -40 | 0;\r\n          t = g + 8 | 0;\r\n          t = (t & 7 | 0) == 0 ? 0 : 0 - t & 7;\r\n          u = g + t | 0;\r\n          t = v - t | 0;\r\n          b[6983] = u;\r\n          b[6980] = t;\r\n          b[u + 4 >> 2] = t | 1;\r\n          b[g + v + 4 >> 2] = 40;\r\n          b[6984] = b[7099];\r\n        } } while (0);\r\n        c = b[6980] | 0;\r\n        if (c >>> 0 > m >>> 0) {\r\n          t = c - m | 0;\r\n          b[6980] = t;\r\n          v = b[6983] | 0;\r\n          u = v + m | 0;\r\n          b[6983] = u;\r\n          b[u + 4 >> 2] = t | 1;\r\n          b[v + 4 >> 2] = m | 3;\r\n          v = v + 8 | 0;\r\n          T = w;\r\n          return v | 0;\r\n        }\r\n      }\r\n      v = Bd() | 0;\r\n      b[v >> 2] = 12;\r\n      v = 0;\r\n      T = w;\r\n      return v | 0;\r\n    }\r\n    function Ed(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      if (!a) { return; }\r\n      d = a + -8 | 0;\r\n      f = b[6981] | 0;\r\n      a = b[a + -4 >> 2] | 0;\r\n      c = a & -8;\r\n      j = d + c | 0;\r\n      do { if (!(a & 1)) {\r\n        e = b[d >> 2] | 0;\r\n        if (!(a & 3)) { return; }\r\n        h = d + (0 - e) | 0;\r\n        g = e + c | 0;\r\n        if (h >>> 0 < f >>> 0) { return; }\r\n        if ((b[6982] | 0) == (h | 0)) {\r\n          a = j + 4 | 0;\r\n          c = b[a >> 2] | 0;\r\n          if ((c & 3 | 0) != 3) {\r\n            i = h;\r\n            c = g;\r\n            break;\r\n          }\r\n          b[6979] = g;\r\n          b[a >> 2] = c & -2;\r\n          b[h + 4 >> 2] = g | 1;\r\n          b[h + g >> 2] = g;\r\n          return;\r\n        }\r\n        d = e >>> 3;\r\n        if (e >>> 0 < 256) {\r\n          a = b[h + 8 >> 2] | 0;\r\n          c = b[h + 12 >> 2] | 0;\r\n          if ((c | 0) == (a | 0)) {\r\n            b[6977] = b[6977] & ~(1 << d);\r\n            i = h;\r\n            c = g;\r\n            break;\r\n          } else {\r\n            b[a + 12 >> 2] = c;\r\n            b[c + 8 >> 2] = a;\r\n            i = h;\r\n            c = g;\r\n            break;\r\n          }\r\n        }\r\n        f = b[h + 24 >> 2] | 0;\r\n        a = b[h + 12 >> 2] | 0;\r\n        do { if ((a | 0) == (h | 0)) {\r\n          c = h + 16 | 0;\r\n          d = c + 4 | 0;\r\n          a = b[d >> 2] | 0;\r\n          if (!a) {\r\n            a = b[c >> 2] | 0;\r\n            if (!a) {\r\n              a = 0;\r\n              break;\r\n            }\r\n          } else { c = d; }\r\n          while (1) {\r\n            e = a + 20 | 0;\r\n            d = b[e >> 2] | 0;\r\n            if (!d) {\r\n              e = a + 16 | 0;\r\n              d = b[e >> 2] | 0;\r\n              if (!d) { break; }else {\r\n                a = d;\r\n                c = e;\r\n              }\r\n            } else {\r\n              a = d;\r\n              c = e;\r\n            }\r\n          }\r\n          b[c >> 2] = 0;\r\n        } else {\r\n          i = b[h + 8 >> 2] | 0;\r\n          b[i + 12 >> 2] = a;\r\n          b[a + 8 >> 2] = i;\r\n        } } while (0);\r\n        if (f) {\r\n          c = b[h + 28 >> 2] | 0;\r\n          d = 28212 + (c << 2) | 0;\r\n          if ((b[d >> 2] | 0) == (h | 0)) {\r\n            b[d >> 2] = a;\r\n            if (!a) {\r\n              b[6978] = b[6978] & ~(1 << c);\r\n              i = h;\r\n              c = g;\r\n              break;\r\n            }\r\n          } else {\r\n            i = f + 16 | 0;\r\n            b[((b[i >> 2] | 0) == (h | 0) ? i : f + 20 | 0) >> 2] = a;\r\n            if (!a) {\r\n              i = h;\r\n              c = g;\r\n              break;\r\n            }\r\n          }\r\n          b[a + 24 >> 2] = f;\r\n          c = h + 16 | 0;\r\n          d = b[c >> 2] | 0;\r\n          if (d | 0) {\r\n            b[a + 16 >> 2] = d;\r\n            b[d + 24 >> 2] = a;\r\n          }\r\n          c = b[c + 4 >> 2] | 0;\r\n          if (c) {\r\n            b[a + 20 >> 2] = c;\r\n            b[c + 24 >> 2] = a;\r\n            i = h;\r\n            c = g;\r\n          } else {\r\n            i = h;\r\n            c = g;\r\n          }\r\n        } else {\r\n          i = h;\r\n          c = g;\r\n        }\r\n      } else {\r\n        i = d;\r\n        h = d;\r\n      } } while (0);\r\n      if (h >>> 0 >= j >>> 0) { return; }\r\n      a = j + 4 | 0;\r\n      e = b[a >> 2] | 0;\r\n      if (!(e & 1)) { return; }\r\n      if (!(e & 2)) {\r\n        if ((b[6983] | 0) == (j | 0)) {\r\n          j = (b[6980] | 0) + c | 0;\r\n          b[6980] = j;\r\n          b[6983] = i;\r\n          b[i + 4 >> 2] = j | 1;\r\n          if ((i | 0) != (b[6982] | 0)) { return; }\r\n          b[6982] = 0;\r\n          b[6979] = 0;\r\n          return;\r\n        }\r\n        if ((b[6982] | 0) == (j | 0)) {\r\n          j = (b[6979] | 0) + c | 0;\r\n          b[6979] = j;\r\n          b[6982] = h;\r\n          b[i + 4 >> 2] = j | 1;\r\n          b[h + j >> 2] = j;\r\n          return;\r\n        }\r\n        f = (e & -8) + c | 0;\r\n        d = e >>> 3;\r\n        do { if (e >>> 0 < 256) {\r\n          c = b[j + 8 >> 2] | 0;\r\n          a = b[j + 12 >> 2] | 0;\r\n          if ((a | 0) == (c | 0)) {\r\n            b[6977] = b[6977] & ~(1 << d);\r\n            break;\r\n          } else {\r\n            b[c + 12 >> 2] = a;\r\n            b[a + 8 >> 2] = c;\r\n            break;\r\n          }\r\n        } else {\r\n          g = b[j + 24 >> 2] | 0;\r\n          a = b[j + 12 >> 2] | 0;\r\n          do { if ((a | 0) == (j | 0)) {\r\n            c = j + 16 | 0;\r\n            d = c + 4 | 0;\r\n            a = b[d >> 2] | 0;\r\n            if (!a) {\r\n              a = b[c >> 2] | 0;\r\n              if (!a) {\r\n                d = 0;\r\n                break;\r\n              }\r\n            } else { c = d; }\r\n            while (1) {\r\n              e = a + 20 | 0;\r\n              d = b[e >> 2] | 0;\r\n              if (!d) {\r\n                e = a + 16 | 0;\r\n                d = b[e >> 2] | 0;\r\n                if (!d) { break; }else {\r\n                  a = d;\r\n                  c = e;\r\n                }\r\n              } else {\r\n                a = d;\r\n                c = e;\r\n              }\r\n            }\r\n            b[c >> 2] = 0;\r\n            d = a;\r\n          } else {\r\n            d = b[j + 8 >> 2] | 0;\r\n            b[d + 12 >> 2] = a;\r\n            b[a + 8 >> 2] = d;\r\n            d = a;\r\n          } } while (0);\r\n          if (g | 0) {\r\n            a = b[j + 28 >> 2] | 0;\r\n            c = 28212 + (a << 2) | 0;\r\n            if ((b[c >> 2] | 0) == (j | 0)) {\r\n              b[c >> 2] = d;\r\n              if (!d) {\r\n                b[6978] = b[6978] & ~(1 << a);\r\n                break;\r\n              }\r\n            } else {\r\n              e = g + 16 | 0;\r\n              b[((b[e >> 2] | 0) == (j | 0) ? e : g + 20 | 0) >> 2] = d;\r\n              if (!d) { break; }\r\n            }\r\n            b[d + 24 >> 2] = g;\r\n            a = j + 16 | 0;\r\n            c = b[a >> 2] | 0;\r\n            if (c | 0) {\r\n              b[d + 16 >> 2] = c;\r\n              b[c + 24 >> 2] = d;\r\n            }\r\n            a = b[a + 4 >> 2] | 0;\r\n            if (a | 0) {\r\n              b[d + 20 >> 2] = a;\r\n              b[a + 24 >> 2] = d;\r\n            }\r\n          }\r\n        } } while (0);\r\n        b[i + 4 >> 2] = f | 1;\r\n        b[h + f >> 2] = f;\r\n        if ((i | 0) == (b[6982] | 0)) {\r\n          b[6979] = f;\r\n          return;\r\n        }\r\n      } else {\r\n        b[a >> 2] = e & -2;\r\n        b[i + 4 >> 2] = c | 1;\r\n        b[h + c >> 2] = c;\r\n        f = c;\r\n      }\r\n      a = f >>> 3;\r\n      if (f >>> 0 < 256) {\r\n        d = 27948 + (a << 1 << 2) | 0;\r\n        c = b[6977] | 0;\r\n        a = 1 << a;\r\n        if (!(c & a)) {\r\n          b[6977] = c | a;\r\n          a = d;\r\n          c = d + 8 | 0;\r\n        } else {\r\n          c = d + 8 | 0;\r\n          a = b[c >> 2] | 0;\r\n        }\r\n        b[c >> 2] = i;\r\n        b[a + 12 >> 2] = i;\r\n        b[i + 8 >> 2] = a;\r\n        b[i + 12 >> 2] = d;\r\n        return;\r\n      }\r\n      a = f >>> 8;\r\n      if (a) {\r\n        if (f >>> 0 > 16777215) { e = 31; }else {\r\n          h = (a + 1048320 | 0) >>> 16 & 8;\r\n          j = a << h;\r\n          g = (j + 520192 | 0) >>> 16 & 4;\r\n          j = j << g;\r\n          e = (j + 245760 | 0) >>> 16 & 2;\r\n          e = 14 - (g | h | e) + (j << e >>> 15) | 0;\r\n          e = f >>> (e + 7 | 0) & 1 | e << 1;\r\n        }\r\n      } else { e = 0; }\r\n      a = 28212 + (e << 2) | 0;\r\n      b[i + 28 >> 2] = e;\r\n      b[i + 20 >> 2] = 0;\r\n      b[i + 16 >> 2] = 0;\r\n      c = b[6978] | 0;\r\n      d = 1 << e;\r\n      a: do { if (!(c & d)) {\r\n        b[6978] = c | d;\r\n        b[a >> 2] = i;\r\n        b[i + 24 >> 2] = a;\r\n        b[i + 12 >> 2] = i;\r\n        b[i + 8 >> 2] = i;\r\n      } else {\r\n        a = b[a >> 2] | 0;\r\n        b: do { if ((b[a + 4 >> 2] & -8 | 0) != (f | 0)) {\r\n          e = f << ((e | 0) == 31 ? 0 : 25 - (e >>> 1) | 0);\r\n          while (1) {\r\n            d = a + 16 + (e >>> 31 << 2) | 0;\r\n            c = b[d >> 2] | 0;\r\n            if (!c) { break; }\r\n            if ((b[c + 4 >> 2] & -8 | 0) == (f | 0)) {\r\n              a = c;\r\n              break b;\r\n            } else {\r\n              e = e << 1;\r\n              a = c;\r\n            }\r\n          }\r\n          b[d >> 2] = i;\r\n          b[i + 24 >> 2] = a;\r\n          b[i + 12 >> 2] = i;\r\n          b[i + 8 >> 2] = i;\r\n          break a;\r\n        } } while (0);\r\n        h = a + 8 | 0;\r\n        j = b[h >> 2] | 0;\r\n        b[j + 12 >> 2] = i;\r\n        b[h >> 2] = i;\r\n        b[i + 8 >> 2] = j;\r\n        b[i + 12 >> 2] = a;\r\n        b[i + 24 >> 2] = 0;\r\n      } } while (0);\r\n      j = (b[6985] | 0) + -1 | 0;\r\n      b[6985] = j;\r\n      if (j | 0) { return; }\r\n      a = 28364;\r\n      while (1) {\r\n        a = b[a >> 2] | 0;\r\n        if (!a) { break; }else { a = a + 8 | 0; }\r\n      }\r\n      b[6985] = -1;\r\n      return;\r\n    }\r\n    function Fd(a, c) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      var d = 0;\r\n      if (a) {\r\n        d = B(c, a) | 0;\r\n        if ((c | a) >>> 0 > 65535) { d = ((d >>> 0) / (a >>> 0) | 0 | 0) == (c | 0) ? d : -1; }\r\n      } else { d = 0; }\r\n      a = Dd(d) | 0;\r\n      if (!a) { return a | 0; }\r\n      if (!(b[a + -4 >> 2] & 3)) { return a | 0; }\r\n      Xd(a | 0, 0, d | 0) | 0;\r\n      return a | 0;\r\n    }\r\n    function Gd(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      c = a + c >>> 0;\r\n      return (G(b + d + (c >>> 0 < a >>> 0 | 0) >>> 0 | 0), c | 0) | 0;\r\n    }\r\n    function Hd(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      d = b - d - (c >>> 0 > a >>> 0 | 0) >>> 0;\r\n      return (G(d | 0), a - c >>> 0 | 0) | 0;\r\n    }\r\n    function Id(a) {\r\n      a = a | 0;\r\n      return (a ? 31 - (E(a ^ a - 1) | 0) | 0 : 32) | 0;\r\n    }\r\n    function Jd(a, c, d, e, f) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      f = f | 0;\r\n      var g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0,\r\n        l = 0,\r\n        m = 0,\r\n        n = 0,\r\n        o = 0,\r\n        p = 0;\r\n      l = a;\r\n      j = c;\r\n      k = j;\r\n      h = d;\r\n      n = e;\r\n      i = n;\r\n      if (!k) {\r\n        g = (f | 0) != 0;\r\n        if (!i) {\r\n          if (g) {\r\n            b[f >> 2] = (l >>> 0) % (h >>> 0);\r\n            b[f + 4 >> 2] = 0;\r\n          }\r\n          n = 0;\r\n          f = (l >>> 0) / (h >>> 0) >>> 0;\r\n          return (G(n | 0), f) | 0;\r\n        } else {\r\n          if (!g) {\r\n            n = 0;\r\n            f = 0;\r\n            return (G(n | 0), f) | 0;\r\n          }\r\n          b[f >> 2] = a | 0;\r\n          b[f + 4 >> 2] = c & 0;\r\n          n = 0;\r\n          f = 0;\r\n          return (G(n | 0), f) | 0;\r\n        }\r\n      }\r\n      g = (i | 0) == 0;\r\n      do { if (h) {\r\n        if (!g) {\r\n          g = (E(i | 0) | 0) - (E(k | 0) | 0) | 0;\r\n          if (g >>> 0 <= 31) {\r\n            m = g + 1 | 0;\r\n            i = 31 - g | 0;\r\n            c = g - 31 >> 31;\r\n            h = m;\r\n            a = l >>> (m >>> 0) & c | k << i;\r\n            c = k >>> (m >>> 0) & c;\r\n            g = 0;\r\n            i = l << i;\r\n            break;\r\n          }\r\n          if (!f) {\r\n            n = 0;\r\n            f = 0;\r\n            return (G(n | 0), f) | 0;\r\n          }\r\n          b[f >> 2] = a | 0;\r\n          b[f + 4 >> 2] = j | c & 0;\r\n          n = 0;\r\n          f = 0;\r\n          return (G(n | 0), f) | 0;\r\n        }\r\n        g = h - 1 | 0;\r\n        if (g & h | 0) {\r\n          i = (E(h | 0) | 0) + 33 - (E(k | 0) | 0) | 0;\r\n          p = 64 - i | 0;\r\n          m = 32 - i | 0;\r\n          j = m >> 31;\r\n          o = i - 32 | 0;\r\n          c = o >> 31;\r\n          h = i;\r\n          a = m - 1 >> 31 & k >>> (o >>> 0) | (k << m | l >>> (i >>> 0)) & c;\r\n          c = c & k >>> (i >>> 0);\r\n          g = l << p & j;\r\n          i = (k << p | l >>> (o >>> 0)) & j | l << m & i - 33 >> 31;\r\n          break;\r\n        }\r\n        if (f | 0) {\r\n          b[f >> 2] = g & l;\r\n          b[f + 4 >> 2] = 0;\r\n        }\r\n        if ((h | 0) == 1) {\r\n          o = j | c & 0;\r\n          p = a | 0 | 0;\r\n          return (G(o | 0), p) | 0;\r\n        } else {\r\n          p = Id(h | 0) | 0;\r\n          o = k >>> (p >>> 0) | 0;\r\n          p = k << 32 - p | l >>> (p >>> 0) | 0;\r\n          return (G(o | 0), p) | 0;\r\n        }\r\n      } else {\r\n        if (g) {\r\n          if (f | 0) {\r\n            b[f >> 2] = (k >>> 0) % (h >>> 0);\r\n            b[f + 4 >> 2] = 0;\r\n          }\r\n          o = 0;\r\n          p = (k >>> 0) / (h >>> 0) >>> 0;\r\n          return (G(o | 0), p) | 0;\r\n        }\r\n        if (!l) {\r\n          if (f | 0) {\r\n            b[f >> 2] = 0;\r\n            b[f + 4 >> 2] = (k >>> 0) % (i >>> 0);\r\n          }\r\n          o = 0;\r\n          p = (k >>> 0) / (i >>> 0) >>> 0;\r\n          return (G(o | 0), p) | 0;\r\n        }\r\n        g = i - 1 | 0;\r\n        if (!(g & i)) {\r\n          if (f | 0) {\r\n            b[f >> 2] = a | 0;\r\n            b[f + 4 >> 2] = g & k | c & 0;\r\n          }\r\n          o = 0;\r\n          p = k >>> ((Id(i | 0) | 0) >>> 0);\r\n          return (G(o | 0), p) | 0;\r\n        }\r\n        g = (E(i | 0) | 0) - (E(k | 0) | 0) | 0;\r\n        if (g >>> 0 <= 30) {\r\n          c = g + 1 | 0;\r\n          i = 31 - g | 0;\r\n          h = c;\r\n          a = k << i | l >>> (c >>> 0);\r\n          c = k >>> (c >>> 0);\r\n          g = 0;\r\n          i = l << i;\r\n          break;\r\n        }\r\n        if (!f) {\r\n          o = 0;\r\n          p = 0;\r\n          return (G(o | 0), p) | 0;\r\n        }\r\n        b[f >> 2] = a | 0;\r\n        b[f + 4 >> 2] = j | c & 0;\r\n        o = 0;\r\n        p = 0;\r\n        return (G(o | 0), p) | 0;\r\n      } } while (0);\r\n      if (!h) {\r\n        k = i;\r\n        j = 0;\r\n        i = 0;\r\n      } else {\r\n        m = d | 0 | 0;\r\n        l = n | e & 0;\r\n        k = Gd(m | 0, l | 0, -1, -1) | 0;\r\n        d = H() | 0;\r\n        j = i;\r\n        i = 0;\r\n        do {\r\n          e = j;\r\n          j = g >>> 31 | j << 1;\r\n          g = i | g << 1;\r\n          e = a << 1 | e >>> 31 | 0;\r\n          n = a >>> 31 | c << 1 | 0;\r\n          Hd(k | 0, d | 0, e | 0, n | 0) | 0;\r\n          p = H() | 0;\r\n          o = p >> 31 | ((p | 0) < 0 ? -1 : 0) << 1;\r\n          i = o & 1;\r\n          a = Hd(e | 0, n | 0, o & m | 0, (((p | 0) < 0 ? -1 : 0) >> 31 | ((p | 0) < 0 ? -1 : 0) << 1) & l | 0) | 0;\r\n          c = H() | 0;\r\n          h = h - 1 | 0;\r\n        } while ((h | 0) != 0);\r\n        k = j;\r\n        j = 0;\r\n      }\r\n      h = 0;\r\n      if (f | 0) {\r\n        b[f >> 2] = a;\r\n        b[f + 4 >> 2] = c;\r\n      }\r\n      o = (g | 0) >>> 31 | (k | h) << 1 | (h << 1 | g >>> 31) & 0 | j;\r\n      p = (g << 1 | 0 >>> 31) & -2 | i;\r\n      return (G(o | 0), p) | 0;\r\n    }\r\n    function Kd(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0;\r\n      j = b >> 31 | ((b | 0) < 0 ? -1 : 0) << 1;\r\n      i = ((b | 0) < 0 ? -1 : 0) >> 31 | ((b | 0) < 0 ? -1 : 0) << 1;\r\n      f = d >> 31 | ((d | 0) < 0 ? -1 : 0) << 1;\r\n      e = ((d | 0) < 0 ? -1 : 0) >> 31 | ((d | 0) < 0 ? -1 : 0) << 1;\r\n      h = Hd(j ^ a | 0, i ^ b | 0, j | 0, i | 0) | 0;\r\n      g = H() | 0;\r\n      a = f ^ j;\r\n      b = e ^ i;\r\n      return Hd((Jd(h, g, Hd(f ^ c | 0, e ^ d | 0, f | 0, e | 0) | 0, H() | 0, 0) | 0) ^ a | 0, (H() | 0) ^ b | 0, a | 0, b | 0) | 0;\r\n    }\r\n    function Ld(a, b) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0,\r\n        f = 0;\r\n      f = a & 65535;\r\n      e = b & 65535;\r\n      c = B(e, f) | 0;\r\n      d = a >>> 16;\r\n      a = (c >>> 16) + (B(e, d) | 0) | 0;\r\n      e = b >>> 16;\r\n      b = B(e, f) | 0;\r\n      return (G((a >>> 16) + (B(e, d) | 0) + (((a & 65535) + b | 0) >>> 16) | 0), a + b << 16 | c & 65535 | 0) | 0;\r\n    }\r\n    function Md(a, b, c, d) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      var e = 0,\r\n        f = 0;\r\n      e = a;\r\n      f = c;\r\n      c = Ld(e, f) | 0;\r\n      a = H() | 0;\r\n      return (G((B(b, f) | 0) + (B(d, e) | 0) + a | a & 0 | 0), c | 0 | 0) | 0;\r\n    }\r\n    function Nd(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0,\r\n        j = 0,\r\n        k = 0;\r\n      f = T;\r\n      T = T + 16 | 0;\r\n      i = f | 0;\r\n      h = c >> 31 | ((c | 0) < 0 ? -1 : 0) << 1;\r\n      g = ((c | 0) < 0 ? -1 : 0) >> 31 | ((c | 0) < 0 ? -1 : 0) << 1;\r\n      k = e >> 31 | ((e | 0) < 0 ? -1 : 0) << 1;\r\n      j = ((e | 0) < 0 ? -1 : 0) >> 31 | ((e | 0) < 0 ? -1 : 0) << 1;\r\n      a = Hd(h ^ a | 0, g ^ c | 0, h | 0, g | 0) | 0;\r\n      c = H() | 0;\r\n      Jd(a, c, Hd(k ^ d | 0, j ^ e | 0, k | 0, j | 0) | 0, H() | 0, i) | 0;\r\n      e = Hd(b[i >> 2] ^ h | 0, b[i + 4 >> 2] ^ g | 0, h | 0, g | 0) | 0;\r\n      d = H() | 0;\r\n      T = f;\r\n      return (G(d | 0), e) | 0;\r\n    }\r\n    function Od(a, c, d, e) {\r\n      a = a | 0;\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0;\r\n      g = T;\r\n      T = T + 16 | 0;\r\n      f = g | 0;\r\n      Jd(a, c, d, e, f) | 0;\r\n      T = g;\r\n      return (G(b[f + 4 >> 2] | 0), b[f >> 2] | 0) | 0;\r\n    }\r\n    function Pd(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      if ((c | 0) < 32) {\r\n        G(b >> c | 0);\r\n        return a >>> c | (b & (1 << c) - 1) << 32 - c;\r\n      }\r\n      G(((b | 0) < 0 ? -1 : 0) | 0);\r\n      return b >> c - 32 | 0;\r\n    }\r\n    function Qd(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      if ((c | 0) < 32) {\r\n        G(b >>> c | 0);\r\n        return a >>> c | (b & (1 << c) - 1) << 32 - c;\r\n      }\r\n      G(0);\r\n      return b >>> c - 32 | 0;\r\n    }\r\n    function Rd(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      if ((c | 0) < 32) {\r\n        G(b << c | (a & (1 << c) - 1 << 32 - c) >>> 32 - c | 0);\r\n        return a << c;\r\n      }\r\n      G(a << c - 32 | 0);\r\n      return 0;\r\n    }\r\n    function Sd(a, b, c) {\r\n      a = a | 0;\r\n      b = b | 0;\r\n      c = c | 0;\r\n      b = E(b) | 0;\r\n      if ((b | 0) == 32) { b = b + (E(a) | 0) | 0; }\r\n      G(0);\r\n      return b | 0;\r\n    }\r\n    function Td(a, b) {\r\n      a = +a;\r\n      b = +b;\r\n      if (a != a) { return +b; }\r\n      if (b != b) { return +a; }\r\n      return +D(+a, +b);\r\n    }\r\n    function Ud(a, b) {\r\n      a = +a;\r\n      b = +b;\r\n      if (a != a) { return +b; }\r\n      if (b != b) { return +a; }\r\n      return +C(+a, +b);\r\n    }\r\n    function Vd(a) {\r\n      a = +a;\r\n      return a >= 0.0 ? +p(a + .5) : +A(a - .5);\r\n    }\r\n    function Wd(c, d, e) {\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0;\r\n      if ((e | 0) >= 8192) {\r\n        L(c | 0, d | 0, e | 0) | 0;\r\n        return c | 0;\r\n      }\r\n      h = c | 0;\r\n      g = c + e | 0;\r\n      if ((c & 3) == (d & 3)) {\r\n        while (c & 3) {\r\n          if (!e) { return h | 0; }\r\n          a[c >> 0] = a[d >> 0] | 0;\r\n          c = c + 1 | 0;\r\n          d = d + 1 | 0;\r\n          e = e - 1 | 0;\r\n        }\r\n        e = g & -4 | 0;\r\n        f = e - 64 | 0;\r\n        while ((c | 0) <= (f | 0)) {\r\n          b[c >> 2] = b[d >> 2];\r\n          b[c + 4 >> 2] = b[d + 4 >> 2];\r\n          b[c + 8 >> 2] = b[d + 8 >> 2];\r\n          b[c + 12 >> 2] = b[d + 12 >> 2];\r\n          b[c + 16 >> 2] = b[d + 16 >> 2];\r\n          b[c + 20 >> 2] = b[d + 20 >> 2];\r\n          b[c + 24 >> 2] = b[d + 24 >> 2];\r\n          b[c + 28 >> 2] = b[d + 28 >> 2];\r\n          b[c + 32 >> 2] = b[d + 32 >> 2];\r\n          b[c + 36 >> 2] = b[d + 36 >> 2];\r\n          b[c + 40 >> 2] = b[d + 40 >> 2];\r\n          b[c + 44 >> 2] = b[d + 44 >> 2];\r\n          b[c + 48 >> 2] = b[d + 48 >> 2];\r\n          b[c + 52 >> 2] = b[d + 52 >> 2];\r\n          b[c + 56 >> 2] = b[d + 56 >> 2];\r\n          b[c + 60 >> 2] = b[d + 60 >> 2];\r\n          c = c + 64 | 0;\r\n          d = d + 64 | 0;\r\n        }\r\n        while ((c | 0) < (e | 0)) {\r\n          b[c >> 2] = b[d >> 2];\r\n          c = c + 4 | 0;\r\n          d = d + 4 | 0;\r\n        }\r\n      } else {\r\n        e = g - 4 | 0;\r\n        while ((c | 0) < (e | 0)) {\r\n          a[c >> 0] = a[d >> 0] | 0;\r\n          a[c + 1 >> 0] = a[d + 1 >> 0] | 0;\r\n          a[c + 2 >> 0] = a[d + 2 >> 0] | 0;\r\n          a[c + 3 >> 0] = a[d + 3 >> 0] | 0;\r\n          c = c + 4 | 0;\r\n          d = d + 4 | 0;\r\n        }\r\n      }\r\n      while ((c | 0) < (g | 0)) {\r\n        a[c >> 0] = a[d >> 0] | 0;\r\n        c = c + 1 | 0;\r\n        d = d + 1 | 0;\r\n      }\r\n      return h | 0;\r\n    }\r\n    function Xd(c, d, e) {\r\n      c = c | 0;\r\n      d = d | 0;\r\n      e = e | 0;\r\n      var f = 0,\r\n        g = 0,\r\n        h = 0,\r\n        i = 0;\r\n      h = c + e | 0;\r\n      d = d & 255;\r\n      if ((e | 0) >= 67) {\r\n        while (c & 3) {\r\n          a[c >> 0] = d;\r\n          c = c + 1 | 0;\r\n        }\r\n        f = h & -4 | 0;\r\n        i = d | d << 8 | d << 16 | d << 24;\r\n        g = f - 64 | 0;\r\n        while ((c | 0) <= (g | 0)) {\r\n          b[c >> 2] = i;\r\n          b[c + 4 >> 2] = i;\r\n          b[c + 8 >> 2] = i;\r\n          b[c + 12 >> 2] = i;\r\n          b[c + 16 >> 2] = i;\r\n          b[c + 20 >> 2] = i;\r\n          b[c + 24 >> 2] = i;\r\n          b[c + 28 >> 2] = i;\r\n          b[c + 32 >> 2] = i;\r\n          b[c + 36 >> 2] = i;\r\n          b[c + 40 >> 2] = i;\r\n          b[c + 44 >> 2] = i;\r\n          b[c + 48 >> 2] = i;\r\n          b[c + 52 >> 2] = i;\r\n          b[c + 56 >> 2] = i;\r\n          b[c + 60 >> 2] = i;\r\n          c = c + 64 | 0;\r\n        }\r\n        while ((c | 0) < (f | 0)) {\r\n          b[c >> 2] = i;\r\n          c = c + 4 | 0;\r\n        }\r\n      }\r\n      while ((c | 0) < (h | 0)) {\r\n        a[c >> 0] = d;\r\n        c = c + 1 | 0;\r\n      }\r\n      return h - e | 0;\r\n    }\r\n    function Yd(a) {\r\n      a = +a;\r\n      return a >= 0.0 ? +p(a + .5) : +A(a - .5);\r\n    }\r\n    function Zd(a) {\r\n      a = a | 0;\r\n      var c = 0,\r\n        d = 0,\r\n        e = 0;\r\n      e = K() | 0;\r\n      d = b[g >> 2] | 0;\r\n      c = d + a | 0;\r\n      if ((a | 0) > 0 & (c | 0) < (d | 0) | (c | 0) < 0) {\r\n        N(c | 0) | 0;\r\n        J(12);\r\n        return -1;\r\n      }\r\n      if ((c | 0) > (e | 0)) { if (!(M(c | 0) | 0)) {\r\n        J(12);\r\n        return -1;\r\n      } }\r\n      b[g >> 2] = c;\r\n      return d | 0;\r\n    }\r\n\r\n    // EMSCRIPTEN_END_FUNCS\r\n    return {\r\n      ___divdi3: Kd,\r\n      ___muldi3: Md,\r\n      ___remdi3: Nd,\r\n      ___uremdi3: Od,\r\n      _areNeighborCells: ib,\r\n      _bitshift64Ashr: Pd,\r\n      _bitshift64Lshr: Qd,\r\n      _bitshift64Shl: Rd,\r\n      _calloc: Fd,\r\n      _cellAreaKm2: xc,\r\n      _cellAreaM2: yc,\r\n      _cellAreaRads2: wc,\r\n      _cellToBoundary: _b,\r\n      _cellToCenterChild: Kb,\r\n      _cellToChildPos: dc,\r\n      _cellToChildren: Ib,\r\n      _cellToChildrenSize: Gb,\r\n      _cellToLatLng: Zb,\r\n      _cellToLocalIj: Jc,\r\n      _cellToParent: Fb,\r\n      _cellToVertex: qd,\r\n      _cellToVertexes: rd,\r\n      _cellsToDirectedEdge: jb,\r\n      _cellsToLinkedMultiPolygon: na,\r\n      _childPosToCell: ec,\r\n      _compactCells: Lb,\r\n      _destroyLinkedMultiPolygon: Ec,\r\n      _directedEdgeToBoundary: pb,\r\n      _directedEdgeToCells: nb,\r\n      _edgeLengthKm: Ac,\r\n      _edgeLengthM: Bc,\r\n      _edgeLengthRads: zc,\r\n      _emscripten_replace_memory: W,\r\n      _free: Ed,\r\n      _getBaseCellNumber: Cb,\r\n      _getDirectedEdgeDestination: lb,\r\n      _getDirectedEdgeOrigin: kb,\r\n      _getHexagonAreaAvgKm2: qc,\r\n      _getHexagonAreaAvgM2: rc,\r\n      _getHexagonEdgeLengthAvgKm: sc,\r\n      _getHexagonEdgeLengthAvgM: tc,\r\n      _getIcosahedronFaces: ac,\r\n      _getNumCells: uc,\r\n      _getPentagons: cc,\r\n      _getRes0Cells: ya,\r\n      _getResolution: Bb,\r\n      _greatCircleDistanceKm: mc,\r\n      _greatCircleDistanceM: nc,\r\n      _greatCircleDistanceRads: lc,\r\n      _gridDisk: aa,\r\n      _gridDiskDistances: ba,\r\n      _gridDistance: Lc,\r\n      _gridPathCells: Nc,\r\n      _gridPathCellsSize: Mc,\r\n      _gridRing: fa,\r\n      _gridRingUnsafe: ga,\r\n      _i64Add: Gd,\r\n      _i64Subtract: Hd,\r\n      _isPentagon: Hb,\r\n      _isResClassIII: Ob,\r\n      _isValidCell: Db,\r\n      _isValidDirectedEdge: mb,\r\n      _isValidVertex: td,\r\n      _latLngToCell: Wb,\r\n      _llvm_ctlz_i64: Sd,\r\n      _llvm_maxnum_f64: Td,\r\n      _llvm_minnum_f64: Ud,\r\n      _llvm_round_f64: Vd,\r\n      _localIjToCell: Kc,\r\n      _malloc: Dd,\r\n      _maxFaceCount: $b,\r\n      _maxGridDiskSize: $,\r\n      _maxPolygonToCellsSize: ja,\r\n      _maxPolygonToCellsSizeExperimental: Uc,\r\n      _memcpy: Wd,\r\n      _memset: Xd,\r\n      _originToDirectedEdges: ob,\r\n      _pentagonCount: bc,\r\n      _polygonToCells: la,\r\n      _polygonToCellsExperimental: Tc,\r\n      _readInt64AsDoubleFromPointer: id,\r\n      _res0CellCount: xa,\r\n      _round: Yd,\r\n      _sbrk: Zd,\r\n      _sizeOfCellBoundary: dd,\r\n      _sizeOfCoordIJ: hd,\r\n      _sizeOfGeoLoop: ed,\r\n      _sizeOfGeoPolygon: fd,\r\n      _sizeOfH3Index: bd,\r\n      _sizeOfLatLng: cd,\r\n      _sizeOfLinkedGeoPolygon: gd,\r\n      _uncompactCells: Mb,\r\n      _uncompactCellsSize: Nb,\r\n      _vertexToLatLng: sd,\r\n      establishStackSpace: _,\r\n      stackAlloc: X,\r\n      stackRestore: Z,\r\n      stackSave: Y\r\n    };\r\n  }\r\n\r\n  // EMSCRIPTEN_END_ASM\r\n  )(asmGlobalArg, asmLibraryArg, buffer);\r\n  var ___divdi3 = Module[\"___divdi3\"] = asm[\"___divdi3\"];\r\n  var ___muldi3 = Module[\"___muldi3\"] = asm[\"___muldi3\"];\r\n  var ___remdi3 = Module[\"___remdi3\"] = asm[\"___remdi3\"];\r\n  var ___uremdi3 = Module[\"___uremdi3\"] = asm[\"___uremdi3\"];\r\n  var _areNeighborCells = Module[\"_areNeighborCells\"] = asm[\"_areNeighborCells\"];\r\n  var _bitshift64Ashr = Module[\"_bitshift64Ashr\"] = asm[\"_bitshift64Ashr\"];\r\n  var _bitshift64Lshr = Module[\"_bitshift64Lshr\"] = asm[\"_bitshift64Lshr\"];\r\n  var _bitshift64Shl = Module[\"_bitshift64Shl\"] = asm[\"_bitshift64Shl\"];\r\n  var _calloc = Module[\"_calloc\"] = asm[\"_calloc\"];\r\n  var _cellAreaKm2 = Module[\"_cellAreaKm2\"] = asm[\"_cellAreaKm2\"];\r\n  var _cellAreaM2 = Module[\"_cellAreaM2\"] = asm[\"_cellAreaM2\"];\r\n  var _cellAreaRads2 = Module[\"_cellAreaRads2\"] = asm[\"_cellAreaRads2\"];\r\n  var _cellToBoundary = Module[\"_cellToBoundary\"] = asm[\"_cellToBoundary\"];\r\n  var _cellToCenterChild = Module[\"_cellToCenterChild\"] = asm[\"_cellToCenterChild\"];\r\n  var _cellToChildPos = Module[\"_cellToChildPos\"] = asm[\"_cellToChildPos\"];\r\n  var _cellToChildren = Module[\"_cellToChildren\"] = asm[\"_cellToChildren\"];\r\n  var _cellToChildrenSize = Module[\"_cellToChildrenSize\"] = asm[\"_cellToChildrenSize\"];\r\n  var _cellToLatLng = Module[\"_cellToLatLng\"] = asm[\"_cellToLatLng\"];\r\n  var _cellToLocalIj = Module[\"_cellToLocalIj\"] = asm[\"_cellToLocalIj\"];\r\n  var _cellToParent = Module[\"_cellToParent\"] = asm[\"_cellToParent\"];\r\n  var _cellToVertex = Module[\"_cellToVertex\"] = asm[\"_cellToVertex\"];\r\n  var _cellToVertexes = Module[\"_cellToVertexes\"] = asm[\"_cellToVertexes\"];\r\n  var _cellsToDirectedEdge = Module[\"_cellsToDirectedEdge\"] = asm[\"_cellsToDirectedEdge\"];\r\n  var _cellsToLinkedMultiPolygon = Module[\"_cellsToLinkedMultiPolygon\"] = asm[\"_cellsToLinkedMultiPolygon\"];\r\n  var _childPosToCell = Module[\"_childPosToCell\"] = asm[\"_childPosToCell\"];\r\n  var _compactCells = Module[\"_compactCells\"] = asm[\"_compactCells\"];\r\n  var _destroyLinkedMultiPolygon = Module[\"_destroyLinkedMultiPolygon\"] = asm[\"_destroyLinkedMultiPolygon\"];\r\n  var _directedEdgeToBoundary = Module[\"_directedEdgeToBoundary\"] = asm[\"_directedEdgeToBoundary\"];\r\n  var _directedEdgeToCells = Module[\"_directedEdgeToCells\"] = asm[\"_directedEdgeToCells\"];\r\n  var _edgeLengthKm = Module[\"_edgeLengthKm\"] = asm[\"_edgeLengthKm\"];\r\n  var _edgeLengthM = Module[\"_edgeLengthM\"] = asm[\"_edgeLengthM\"];\r\n  var _edgeLengthRads = Module[\"_edgeLengthRads\"] = asm[\"_edgeLengthRads\"];\r\n  var _emscripten_replace_memory = Module[\"_emscripten_replace_memory\"] = asm[\"_emscripten_replace_memory\"];\r\n  var _free = Module[\"_free\"] = asm[\"_free\"];\r\n  var _getBaseCellNumber = Module[\"_getBaseCellNumber\"] = asm[\"_getBaseCellNumber\"];\r\n  var _getDirectedEdgeDestination = Module[\"_getDirectedEdgeDestination\"] = asm[\"_getDirectedEdgeDestination\"];\r\n  var _getDirectedEdgeOrigin = Module[\"_getDirectedEdgeOrigin\"] = asm[\"_getDirectedEdgeOrigin\"];\r\n  var _getHexagonAreaAvgKm2 = Module[\"_getHexagonAreaAvgKm2\"] = asm[\"_getHexagonAreaAvgKm2\"];\r\n  var _getHexagonAreaAvgM2 = Module[\"_getHexagonAreaAvgM2\"] = asm[\"_getHexagonAreaAvgM2\"];\r\n  var _getHexagonEdgeLengthAvgKm = Module[\"_getHexagonEdgeLengthAvgKm\"] = asm[\"_getHexagonEdgeLengthAvgKm\"];\r\n  var _getHexagonEdgeLengthAvgM = Module[\"_getHexagonEdgeLengthAvgM\"] = asm[\"_getHexagonEdgeLengthAvgM\"];\r\n  var _getIcosahedronFaces = Module[\"_getIcosahedronFaces\"] = asm[\"_getIcosahedronFaces\"];\r\n  var _getNumCells = Module[\"_getNumCells\"] = asm[\"_getNumCells\"];\r\n  var _getPentagons = Module[\"_getPentagons\"] = asm[\"_getPentagons\"];\r\n  var _getRes0Cells = Module[\"_getRes0Cells\"] = asm[\"_getRes0Cells\"];\r\n  var _getResolution = Module[\"_getResolution\"] = asm[\"_getResolution\"];\r\n  var _greatCircleDistanceKm = Module[\"_greatCircleDistanceKm\"] = asm[\"_greatCircleDistanceKm\"];\r\n  var _greatCircleDistanceM = Module[\"_greatCircleDistanceM\"] = asm[\"_greatCircleDistanceM\"];\r\n  var _greatCircleDistanceRads = Module[\"_greatCircleDistanceRads\"] = asm[\"_greatCircleDistanceRads\"];\r\n  var _gridDisk = Module[\"_gridDisk\"] = asm[\"_gridDisk\"];\r\n  var _gridDiskDistances = Module[\"_gridDiskDistances\"] = asm[\"_gridDiskDistances\"];\r\n  var _gridDistance = Module[\"_gridDistance\"] = asm[\"_gridDistance\"];\r\n  var _gridPathCells = Module[\"_gridPathCells\"] = asm[\"_gridPathCells\"];\r\n  var _gridPathCellsSize = Module[\"_gridPathCellsSize\"] = asm[\"_gridPathCellsSize\"];\r\n  var _gridRing = Module[\"_gridRing\"] = asm[\"_gridRing\"];\r\n  var _gridRingUnsafe = Module[\"_gridRingUnsafe\"] = asm[\"_gridRingUnsafe\"];\r\n  var _i64Add = Module[\"_i64Add\"] = asm[\"_i64Add\"];\r\n  var _i64Subtract = Module[\"_i64Subtract\"] = asm[\"_i64Subtract\"];\r\n  var _isPentagon = Module[\"_isPentagon\"] = asm[\"_isPentagon\"];\r\n  var _isResClassIII = Module[\"_isResClassIII\"] = asm[\"_isResClassIII\"];\r\n  var _isValidCell = Module[\"_isValidCell\"] = asm[\"_isValidCell\"];\r\n  var _isValidDirectedEdge = Module[\"_isValidDirectedEdge\"] = asm[\"_isValidDirectedEdge\"];\r\n  var _isValidVertex = Module[\"_isValidVertex\"] = asm[\"_isValidVertex\"];\r\n  var _latLngToCell = Module[\"_latLngToCell\"] = asm[\"_latLngToCell\"];\r\n  var _llvm_ctlz_i64 = Module[\"_llvm_ctlz_i64\"] = asm[\"_llvm_ctlz_i64\"];\r\n  var _llvm_maxnum_f64 = Module[\"_llvm_maxnum_f64\"] = asm[\"_llvm_maxnum_f64\"];\r\n  var _llvm_minnum_f64 = Module[\"_llvm_minnum_f64\"] = asm[\"_llvm_minnum_f64\"];\r\n  var _llvm_round_f64 = Module[\"_llvm_round_f64\"] = asm[\"_llvm_round_f64\"];\r\n  var _localIjToCell = Module[\"_localIjToCell\"] = asm[\"_localIjToCell\"];\r\n  var _malloc = Module[\"_malloc\"] = asm[\"_malloc\"];\r\n  var _maxFaceCount = Module[\"_maxFaceCount\"] = asm[\"_maxFaceCount\"];\r\n  var _maxGridDiskSize = Module[\"_maxGridDiskSize\"] = asm[\"_maxGridDiskSize\"];\r\n  var _maxPolygonToCellsSize = Module[\"_maxPolygonToCellsSize\"] = asm[\"_maxPolygonToCellsSize\"];\r\n  var _maxPolygonToCellsSizeExperimental = Module[\"_maxPolygonToCellsSizeExperimental\"] = asm[\"_maxPolygonToCellsSizeExperimental\"];\r\n  var _memcpy = Module[\"_memcpy\"] = asm[\"_memcpy\"];\r\n  var _memset = Module[\"_memset\"] = asm[\"_memset\"];\r\n  var _originToDirectedEdges = Module[\"_originToDirectedEdges\"] = asm[\"_originToDirectedEdges\"];\r\n  var _pentagonCount = Module[\"_pentagonCount\"] = asm[\"_pentagonCount\"];\r\n  var _polygonToCells = Module[\"_polygonToCells\"] = asm[\"_polygonToCells\"];\r\n  var _polygonToCellsExperimental = Module[\"_polygonToCellsExperimental\"] = asm[\"_polygonToCellsExperimental\"];\r\n  var _readInt64AsDoubleFromPointer = Module[\"_readInt64AsDoubleFromPointer\"] = asm[\"_readInt64AsDoubleFromPointer\"];\r\n  var _res0CellCount = Module[\"_res0CellCount\"] = asm[\"_res0CellCount\"];\r\n  var _round = Module[\"_round\"] = asm[\"_round\"];\r\n  var _sbrk = Module[\"_sbrk\"] = asm[\"_sbrk\"];\r\n  var _sizeOfCellBoundary = Module[\"_sizeOfCellBoundary\"] = asm[\"_sizeOfCellBoundary\"];\r\n  var _sizeOfCoordIJ = Module[\"_sizeOfCoordIJ\"] = asm[\"_sizeOfCoordIJ\"];\r\n  var _sizeOfGeoLoop = Module[\"_sizeOfGeoLoop\"] = asm[\"_sizeOfGeoLoop\"];\r\n  var _sizeOfGeoPolygon = Module[\"_sizeOfGeoPolygon\"] = asm[\"_sizeOfGeoPolygon\"];\r\n  var _sizeOfH3Index = Module[\"_sizeOfH3Index\"] = asm[\"_sizeOfH3Index\"];\r\n  var _sizeOfLatLng = Module[\"_sizeOfLatLng\"] = asm[\"_sizeOfLatLng\"];\r\n  var _sizeOfLinkedGeoPolygon = Module[\"_sizeOfLinkedGeoPolygon\"] = asm[\"_sizeOfLinkedGeoPolygon\"];\r\n  var _uncompactCells = Module[\"_uncompactCells\"] = asm[\"_uncompactCells\"];\r\n  var _uncompactCellsSize = Module[\"_uncompactCellsSize\"] = asm[\"_uncompactCellsSize\"];\r\n  var _vertexToLatLng = Module[\"_vertexToLatLng\"] = asm[\"_vertexToLatLng\"];\r\n  var establishStackSpace = Module[\"establishStackSpace\"] = asm[\"establishStackSpace\"];\r\n  var stackAlloc = Module[\"stackAlloc\"] = asm[\"stackAlloc\"];\r\n  var stackRestore = Module[\"stackRestore\"] = asm[\"stackRestore\"];\r\n  var stackSave = Module[\"stackSave\"] = asm[\"stackSave\"];\r\n  Module[\"asm\"] = asm;\r\n  Module[\"cwrap\"] = cwrap;\r\n  Module[\"setValue\"] = setValue;\r\n  Module[\"getValue\"] = getValue;\r\n  if (memoryInitializer) {\r\n    if (!isDataURI(memoryInitializer)) {\r\n      memoryInitializer = locateFile(memoryInitializer);\r\n    }\r\n    if (ENVIRONMENT_IS_NODE || ENVIRONMENT_IS_SHELL) {\r\n      var data = readBinary(memoryInitializer);\r\n      HEAPU8.set(data, GLOBAL_BASE);\r\n    } else {\r\n      addRunDependency(\"memory initializer\");\r\n      var applyMemoryInitializer = function (data) {\r\n        if (data.byteLength) { data = new Uint8Array(data); }\r\n        HEAPU8.set(data, GLOBAL_BASE);\r\n        if (Module[\"memoryInitializerRequest\"]) { delete Module[\"memoryInitializerRequest\"].response; }\r\n        removeRunDependency(\"memory initializer\");\r\n      };\r\n      var doBrowserLoad = function () {\r\n        readAsync(memoryInitializer, applyMemoryInitializer, function () {\r\n          throw \"could not load memory initializer \" + memoryInitializer;\r\n        });\r\n      };\r\n      var memoryInitializerBytes = tryParseAsDataURI(memoryInitializer);\r\n      if (memoryInitializerBytes) {\r\n        applyMemoryInitializer(memoryInitializerBytes.buffer);\r\n      } else if (Module[\"memoryInitializerRequest\"]) {\r\n        var useRequest = function () {\r\n          var request = Module[\"memoryInitializerRequest\"];\r\n          var response = request.response;\r\n          if (request.status !== 200 && request.status !== 0) {\r\n            var data = tryParseAsDataURI(Module[\"memoryInitializerRequestURL\"]);\r\n            if (data) {\r\n              response = data.buffer;\r\n            } else {\r\n              console.warn(\"a problem seems to have happened with Module.memoryInitializerRequest, status: \" + request.status + \", retrying \" + memoryInitializer);\r\n              doBrowserLoad();\r\n              return;\r\n            }\r\n          }\r\n          applyMemoryInitializer(response);\r\n        };\r\n        if (Module[\"memoryInitializerRequest\"].response) {\r\n          setTimeout(useRequest, 0);\r\n        } else {\r\n          Module[\"memoryInitializerRequest\"].addEventListener(\"load\", useRequest);\r\n        }\r\n      } else {\r\n        doBrowserLoad();\r\n      }\r\n    }\r\n  }\r\n  var calledRun;\r\n  dependenciesFulfilled = function runCaller() {\r\n    if (!calledRun) { run(); }\r\n    if (!calledRun) { dependenciesFulfilled = runCaller; }\r\n  };\r\n  function run(args) {\r\n    args = args || arguments_;\r\n    if (runDependencies > 0) {\r\n      return;\r\n    }\r\n    preRun();\r\n    if (runDependencies > 0) { return; }\r\n    function doRun() {\r\n      if (calledRun) { return; }\r\n      calledRun = true;\r\n      if (ABORT) { return; }\r\n      initRuntime();\r\n      preMain();\r\n      if (Module[\"onRuntimeInitialized\"]) { Module[\"onRuntimeInitialized\"](); }\r\n      postRun();\r\n    }\r\n    if (Module[\"setStatus\"]) {\r\n      Module[\"setStatus\"](\"Running...\");\r\n      setTimeout(function () {\r\n        setTimeout(function () {\r\n          Module[\"setStatus\"](\"\");\r\n        }, 1);\r\n        doRun();\r\n      }, 1);\r\n    } else {\r\n      doRun();\r\n    }\r\n  }\r\n  Module[\"run\"] = run;\r\n  function abort(what) {\r\n    if (Module[\"onAbort\"]) {\r\n      Module[\"onAbort\"](what);\r\n    }\r\n    what += \"\";\r\n    out(what);\r\n    err(what);\r\n    ABORT = true;\r\n    throw \"abort(\" + what + \"). Build with -s ASSERTIONS=1 for more info.\";\r\n  }\r\n  Module[\"abort\"] = abort;\r\n  if (Module[\"preInit\"]) {\r\n    if (typeof Module[\"preInit\"] == \"function\") { Module[\"preInit\"] = [Module[\"preInit\"]]; }\r\n    while (Module[\"preInit\"].length > 0) {\r\n      Module[\"preInit\"].pop()();\r\n    }\r\n  }\r\n  run();\r\n  return libh3;\r\n}(typeof libh3 === 'object' ? libh3 : {});\r\n\r\n/*\r\n * Copyright 2018-2019, 2022 Uber Technologies, Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *         http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\n// Define the C bindings for the h3 library\r\n\r\n// Add some aliases to make the function definitions more intelligible\r\nvar NUMBER = 'number';\r\nvar H3_ERROR = NUMBER;\r\nvar BOOLEAN = NUMBER;\r\nvar H3_LOWER = NUMBER;\r\nvar H3_UPPER = NUMBER;\r\nvar RESOLUTION = NUMBER;\r\nvar POINTER = NUMBER;\r\n\r\n// Define the bindings to functions in the C lib. Functions are defined as\r\n// [name, return type, [arg types]]. You must run `npm run build-emscripten`\r\n// before new functions added here will be available.\r\n/** @type {([string, string] | [string, string | null, string[]])[]} */\r\nvar BINDINGS = [\r\n// The size functions are inserted via build/sizes.h\r\n['sizeOfH3Index', NUMBER], ['sizeOfLatLng', NUMBER], ['sizeOfCellBoundary', NUMBER], ['sizeOfGeoLoop', NUMBER], ['sizeOfGeoPolygon', NUMBER], ['sizeOfLinkedGeoPolygon', NUMBER], ['sizeOfCoordIJ', NUMBER], ['readInt64AsDoubleFromPointer', NUMBER],\r\n// The remaining functions are defined in the core lib in h3Api.h\r\n['isValidCell', BOOLEAN, [H3_LOWER, H3_UPPER]], ['latLngToCell', H3_ERROR, [NUMBER, NUMBER, RESOLUTION, POINTER]], ['cellToLatLng', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['cellToBoundary', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['maxGridDiskSize', H3_ERROR, [NUMBER, POINTER]], ['gridDisk', H3_ERROR, [H3_LOWER, H3_UPPER, NUMBER, POINTER]], ['gridDiskDistances', H3_ERROR, [H3_LOWER, H3_UPPER, NUMBER, POINTER, POINTER]], ['gridRing', H3_ERROR, [H3_LOWER, H3_UPPER, NUMBER, POINTER]], ['gridRingUnsafe', H3_ERROR, [H3_LOWER, H3_UPPER, NUMBER, POINTER]], ['maxPolygonToCellsSize', H3_ERROR, [POINTER, RESOLUTION, NUMBER, POINTER]], ['polygonToCells', H3_ERROR, [POINTER, RESOLUTION, NUMBER, POINTER]], ['maxPolygonToCellsSizeExperimental', H3_ERROR, [POINTER, RESOLUTION, NUMBER, POINTER]], ['polygonToCellsExperimental', H3_ERROR, [POINTER, RESOLUTION, NUMBER, NUMBER, NUMBER, POINTER]], ['cellsToLinkedMultiPolygon', H3_ERROR, [POINTER, NUMBER, POINTER]], ['destroyLinkedMultiPolygon', null, [POINTER]], ['compactCells', H3_ERROR, [POINTER, POINTER, NUMBER, NUMBER]], ['uncompactCells', H3_ERROR, [POINTER, NUMBER, NUMBER, POINTER, NUMBER, RESOLUTION]], ['uncompactCellsSize', H3_ERROR, [POINTER, NUMBER, NUMBER, RESOLUTION, POINTER]], ['isPentagon', BOOLEAN, [H3_LOWER, H3_UPPER]], ['isResClassIII', BOOLEAN, [H3_LOWER, H3_UPPER]], ['getBaseCellNumber', NUMBER, [H3_LOWER, H3_UPPER]], ['getResolution', NUMBER, [H3_LOWER, H3_UPPER]], ['maxFaceCount', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['getIcosahedronFaces', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['cellToParent', H3_ERROR, [H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['cellToChildren', H3_ERROR, [H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['cellToCenterChild', H3_ERROR, [H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['cellToChildrenSize', H3_ERROR, [H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['cellToChildPos', H3_ERROR, [H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['childPosToCell', H3_ERROR, [NUMBER, NUMBER, H3_LOWER, H3_UPPER, RESOLUTION, POINTER]], ['areNeighborCells', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, POINTER]], ['cellsToDirectedEdge', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, POINTER]], ['getDirectedEdgeOrigin', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['getDirectedEdgeDestination', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['isValidDirectedEdge', BOOLEAN, [H3_LOWER, H3_UPPER]], ['directedEdgeToCells', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['originToDirectedEdges', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['directedEdgeToBoundary', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['gridDistance', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, POINTER]], ['gridPathCells', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, POINTER]], ['gridPathCellsSize', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, POINTER]], ['cellToLocalIj', H3_ERROR, [H3_LOWER, H3_UPPER, H3_LOWER, H3_UPPER, NUMBER, POINTER]], ['localIjToCell', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER, NUMBER, POINTER]], ['getHexagonAreaAvgM2', H3_ERROR, [RESOLUTION, POINTER]], ['getHexagonAreaAvgKm2', H3_ERROR, [RESOLUTION, POINTER]], ['getHexagonEdgeLengthAvgM', H3_ERROR, [RESOLUTION, POINTER]], ['getHexagonEdgeLengthAvgKm', H3_ERROR, [RESOLUTION, POINTER]], ['greatCircleDistanceM', NUMBER, [POINTER, POINTER]], ['greatCircleDistanceKm', NUMBER, [POINTER, POINTER]], ['greatCircleDistanceRads', NUMBER, [POINTER, POINTER]], ['cellAreaM2', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['cellAreaKm2', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['cellAreaRads2', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['edgeLengthM', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['edgeLengthKm', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['edgeLengthRads', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['getNumCells', H3_ERROR, [RESOLUTION, POINTER]], ['getRes0Cells', H3_ERROR, [POINTER]], ['res0CellCount', NUMBER], ['getPentagons', H3_ERROR, [NUMBER, POINTER]], ['pentagonCount', NUMBER], ['cellToVertex', H3_ERROR, [H3_LOWER, H3_UPPER, NUMBER, POINTER]], ['cellToVertexes', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['vertexToLatLng', H3_ERROR, [H3_LOWER, H3_UPPER, POINTER]], ['isValidVertex', BOOLEAN, [H3_LOWER, H3_UPPER]]];\r\n\r\n/*\r\n * Copyright 2018-2019, 2022 Uber Technologies, Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *         http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\n// Error codes from the code library, aliased here for legibility\r\nvar E_SUCCESS = 0;\r\nvar E_FAILED = 1;\r\nvar E_DOMAIN = 2;\r\nvar E_LATLNG_DOMAIN = 3;\r\nvar E_RES_DOMAIN = 4;\r\nvar E_CELL_INVALID = 5;\r\nvar E_DIR_EDGE_INVALID = 6;\r\nvar E_UNDIR_EDGE_INVALID = 7;\r\nvar E_VERTEX_INVALID = 8;\r\nvar E_PENTAGON = 9;\r\nvar E_DUPLICATE_INPUT = 10;\r\nvar E_NOT_NEIGHBORS = 11;\r\nvar E_RES_MISMATCH = 12;\r\nvar E_MEMORY_ALLOC = 13;\r\nvar E_MEMORY_BOUNDS = 14;\r\nvar E_OPTION_INVALID = 15;\r\n\r\n/**\r\n * Error messages corresponding to the core library error codes. See\r\n * https://h3geo.org/docs/library/errors#table-of-error-codes\r\n * @private\r\n */\r\nvar H3_ERROR_MSGS = {};\r\nH3_ERROR_MSGS[E_SUCCESS] = 'Success';\r\nH3_ERROR_MSGS[E_FAILED] = 'The operation failed but a more specific error is not available';\r\nH3_ERROR_MSGS[E_DOMAIN] = 'Argument was outside of acceptable range';\r\nH3_ERROR_MSGS[E_LATLNG_DOMAIN] = 'Latitude or longitude arguments were outside of acceptable range';\r\nH3_ERROR_MSGS[E_RES_DOMAIN] = 'Resolution argument was outside of acceptable range';\r\nH3_ERROR_MSGS[E_CELL_INVALID] = 'Cell argument was not valid';\r\nH3_ERROR_MSGS[E_DIR_EDGE_INVALID] = 'Directed edge argument was not valid';\r\nH3_ERROR_MSGS[E_UNDIR_EDGE_INVALID] = 'Undirected edge argument was not valid';\r\nH3_ERROR_MSGS[E_VERTEX_INVALID] = 'Vertex argument was not valid';\r\nH3_ERROR_MSGS[E_PENTAGON] = 'Pentagon distortion was encountered';\r\nH3_ERROR_MSGS[E_DUPLICATE_INPUT] = 'Duplicate input';\r\nH3_ERROR_MSGS[E_NOT_NEIGHBORS] = 'Cell arguments were not neighbors';\r\nH3_ERROR_MSGS[E_RES_MISMATCH] = 'Cell arguments had incompatible resolutions';\r\nH3_ERROR_MSGS[E_MEMORY_ALLOC] = 'Memory allocation failed';\r\nH3_ERROR_MSGS[E_MEMORY_BOUNDS] = 'Bounds of provided memory were insufficient';\r\nH3_ERROR_MSGS[E_OPTION_INVALID] = 'Mode or flags argument was not valid';\r\n\r\n// Error codes for JS errors thrown in the bindings\r\nvar E_UNKNOWN_UNIT = 1000;\r\nvar E_ARRAY_LENGTH = 1001;\r\nvar E_NULL_INDEX = 1002;\r\n\r\n/**\r\n * Error messages for errors thrown in the binding code. These don't strictly\r\n * need error codes, but it's simpler to treat all of the errors consistently\r\n * @private\r\n */\r\nvar JS_ERROR_MESSAGES = {};\r\nJS_ERROR_MESSAGES[E_UNKNOWN_UNIT] = 'Unknown unit';\r\nJS_ERROR_MESSAGES[E_ARRAY_LENGTH] = 'Array length out of bounds';\r\nJS_ERROR_MESSAGES[E_NULL_INDEX] = 'Got unexpected null value for H3 index';\r\nvar UNKNOWN_ERROR_MSG = 'Unknown error';\r\n\r\n/**\r\n * Create an error with an attached code\r\n * @private\r\n * @param {Record<number, string>} messages  Map of code-to-messages to use\r\n * @param {number} errCode                   Numeric error code\r\n * @param {{value: unknown} | {}} [meta]     Metadata with value to associate with the error\r\n */\r\nfunction createError(messages, errCode, meta) {\r\n  // The error value may be \"undefined\", so check if the argument was provided\r\n  var hasValue = meta && 'value' in meta;\r\n  // Throw a custom error type with the code attached\r\n  var err = new Error(((messages[errCode] || UNKNOWN_ERROR_MSG) + \" (code: \" + errCode + (hasValue ? (\", value: \" + (meta.value)) : '') + \")\"));\r\n  // @ts-expect-error - TS doesn't like extending Error\r\n  err.code = errCode;\r\n  return err;\r\n}\r\n\r\n/**\r\n * Custom error for H3Error codes\r\n * @private\r\n * @param {number} errCode     Error code from the H3 library\r\n * @param {unknown} [value]    Value to associate with the error, if any\r\n * @returns {Error}\r\n */\r\nfunction H3LibraryError(errCode, value) {\r\n  // The error value may be \"undefined\", so check if the argument was provided\r\n  var meta = arguments.length === 2 ? {\r\n    value: value\r\n  } : {};\r\n  return createError(H3_ERROR_MSGS, errCode, meta);\r\n}\r\n\r\n/**\r\n * Custom errors thrown from the JS bindings.\r\n * @private\r\n * @param {number} errCode     Error code from the H3 library\r\n * @param {unknown} [value]    Value to associate with the error, if any\r\n * @returns {Error}\r\n */\r\nfunction JSBindingError(errCode, value) {\r\n  // The error value may be \"undefined\", so check if the argument was provided\r\n  var meta = arguments.length === 2 ? {\r\n    value: value\r\n  } : {};\r\n  return createError(JS_ERROR_MESSAGES, errCode, meta);\r\n}\r\n\r\n/**\r\n * Throw a JavaScript error if the C library return code is an error\r\n * @private\r\n * @param {number} errCode     Error code from the H3 library\r\n * @throws {Error} Error if err is not E_SUCCESS (0)\r\n */\r\nfunction throwIfError(errCode) {\r\n  if (errCode !== 0) {\r\n    throw H3LibraryError(errCode);\r\n  }\r\n}\r\n\r\n/*\r\n * Copyright 2018-2019, 2022 Uber Technologies, Inc.\r\n *\r\n * Licensed under the Apache License, Version 2.0 (the \"License\");\r\n * you may not use this file except in compliance with the License.\r\n * You may obtain a copy of the License at\r\n *\r\n *         http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing, software\r\n * distributed under the License is distributed on an \"AS IS\" BASIS,\r\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n * See the License for the specific language governing permissions and\r\n * limitations under the License.\r\n */\r\n\r\n/**\r\n * Map of C-defined functions\r\n * @type {any}\r\n * @private\r\n */\r\nvar H3 = {};\r\n\r\n// Create the bound functions themselves\r\nBINDINGS.forEach(function bind(def) {\r\n  H3[def[0]] = libh3.cwrap.apply(libh3, def);\r\n});\r\n\r\n// Alias the hexidecimal base for legibility\r\nvar BASE_16 = 16;\r\n\r\n// Alias unused bits for legibility\r\nvar UNUSED_UPPER_32_BITS = 0;\r\n\r\n// ----------------------------------------------------------------------------\r\n// Byte size imports\r\n\r\nvar SZ_INT = 4;\r\nvar SZ_PTR = 4;\r\nvar SZ_DBL = 8;\r\nvar SZ_INT64 = 8;\r\nvar SZ_H3INDEX = H3.sizeOfH3Index();\r\nvar SZ_LATLNG = H3.sizeOfLatLng();\r\nvar SZ_CELLBOUNDARY = H3.sizeOfCellBoundary();\r\nvar SZ_GEOPOLYGON = H3.sizeOfGeoPolygon();\r\nvar SZ_GEOLOOP = H3.sizeOfGeoLoop();\r\nvar SZ_LINKED_GEOPOLYGON = H3.sizeOfLinkedGeoPolygon();\r\nvar SZ_COORDIJ = H3.sizeOfCoordIJ();\r\n\r\n// ----------------------------------------------------------------------------\r\n// Custom types\r\n\r\n/**\r\n * 64-bit hexidecimal string representation of an H3 index\r\n * @static\r\n * @typedef {string} H3Index\r\n */\r\n\r\n/**\r\n * 64-bit hexidecimal string representation of an H3 index,\r\n * or two 32-bit integers in little endian order in an array.\r\n * @static\r\n * @typedef {string | number[]} H3IndexInput\r\n */\r\n\r\n/**\r\n * Coordinates as an `{i, j}` pair\r\n * @static\r\n * @typedef CoordIJ\r\n * @property {number} i\r\n * @property {number} j\r\n */\r\n\r\n/**\r\n * Custom JS Error instance with an attached error code. Error codes come from the\r\n * core H3 library and can be found [in the H3 docs](https://h3geo.org/docs/library/errors#table-of-error-codes).\r\n * @static\r\n * @typedef H3Error\r\n * @property {string} message\r\n * @property {number} code\r\n */\r\n\r\n/**\r\n * Pair of lat,lng coordinates (or lng,lat if GeoJSON output is specified)\r\n * @static\r\n * @typedef {number[]} CoordPair\r\n */\r\n\r\n/**\r\n * Pair of lower,upper 32-bit ints representing a 64-bit value\r\n * @static\r\n * @typedef {number[]} SplitLong\r\n */\r\n\r\n// ----------------------------------------------------------------------------\r\n// Unit constants\r\n\r\n/**\r\n * Length/Area units\r\n * @static\r\n * @property {string} m\r\n * @property {string} m2\r\n * @property {string} km\r\n * @property {string} km2\r\n * @property {string} rads\r\n * @property {string} rads2\r\n */\r\nvar UNITS = {\r\n  m: 'm',\r\n  m2: 'm2',\r\n  km: 'km',\r\n  km2: 'km2',\r\n  rads: 'rads',\r\n  rads2: 'rads2'\r\n};\r\n\r\n// ----------------------------------------------------------------------------\r\n// Flags\r\n\r\n/**\r\n * Mode flags for polygonToCells\r\n * @static\r\n * @property {string} containmentCenter\r\n * @property {string} containmentFull\r\n * @property {string} containmentOverlapping\r\n * @property {string} containmentOverlappingBbox\r\n */\r\nvar POLYGON_TO_CELLS_FLAGS = {\r\n  containmentCenter: 'containmentCenter',\r\n  containmentFull: 'containmentFull',\r\n  containmentOverlapping: 'containmentOverlapping',\r\n  containmentOverlappingBbox: 'containmentOverlappingBbox'\r\n};\r\n\r\n// ----------------------------------------------------------------------------\r\n// Utilities and helpers\r\n\r\n/**\r\n * @private\r\n * @param {string} flags Value from POLYGON_TO_CELLS_FLAGS\r\n * @returns {number} Flag value\r\n * @throws {H3Error} If invalid\r\n */\r\nfunction polygonToCellsFlagsToNumber(flags) {\r\n  switch (flags) {\r\n    case POLYGON_TO_CELLS_FLAGS.containmentCenter:\r\n      return 0;\r\n    case POLYGON_TO_CELLS_FLAGS.containmentFull:\r\n      return 1;\r\n    case POLYGON_TO_CELLS_FLAGS.containmentOverlapping:\r\n      return 2;\r\n    case POLYGON_TO_CELLS_FLAGS.containmentOverlappingBbox:\r\n      return 3;\r\n    default:\r\n      throw JSBindingError(E_OPTION_INVALID, flags);\r\n  }\r\n}\r\n\r\n/**\r\n * Validate a resolution, throwing an error if invalid\r\n * @private\r\n * @param  {unknown} res Value to validate\r\n * @return {number}      Valid res\r\n * @throws {H3Error}     If invalid\r\n */\r\nfunction validateRes(res) {\r\n  if (typeof res !== 'number' || res < 0 || res > 15 || Math.floor(res) !== res) {\r\n    throw H3LibraryError(E_RES_DOMAIN, res);\r\n  }\r\n  return res;\r\n}\r\n\r\n/**\r\n * Assert H3 index output, throwing an error if null\r\n * @private\r\n * @param {H3Index | null} h3Index    Index to validate\r\n * @return {H3Index}\r\n * @throws {H3Error}     If invalid\r\n */\r\nfunction validateH3Index(h3Index) {\r\n  if (!h3Index) { throw JSBindingError(E_NULL_INDEX); }\r\n  return h3Index;\r\n}\r\nvar MAX_JS_ARRAY_LENGTH = Math.pow(2, 32) - 1;\r\n\r\n/**\r\n * Validate an array length. JS will throw its own error if you try\r\n * to create an array larger than 2^32 - 1, but validating beforehand\r\n * allows us to exit early before we try to process large amounts\r\n * of data that won't even fit in an output array\r\n * @private\r\n * @param  {number} length  Length to validate\r\n * @return {number}         Valid array length\r\n * @throws {H3Error}        If invalid\r\n */\r\nfunction validateArrayLength(length) {\r\n  if (length > MAX_JS_ARRAY_LENGTH) {\r\n    throw JSBindingError(E_ARRAY_LENGTH, length);\r\n  }\r\n  return length;\r\n}\r\nvar INVALID_HEXIDECIMAL_CHAR = /[^0-9a-fA-F]/;\r\n\r\n/**\r\n * Convert an H3 index (64-bit hexidecimal string) into a \"split long\" - a pair of 32-bit ints\r\n * @param  {H3IndexInput} h3Index  H3 index to check\r\n * @return {SplitLong}             A two-element array with 32 lower bits and 32 upper bits\r\n */\r\nfunction h3IndexToSplitLong(h3Index) {\r\n  if (Array.isArray(h3Index) && h3Index.length === 2 && Number.isInteger(h3Index[0]) && Number.isInteger(h3Index[1])) {\r\n    return h3Index;\r\n  }\r\n  if (typeof h3Index !== 'string' || INVALID_HEXIDECIMAL_CHAR.test(h3Index)) {\r\n    return [0, 0];\r\n  }\r\n  var upper = parseInt(h3Index.substring(0, h3Index.length - 8), BASE_16);\r\n  var lower = parseInt(h3Index.substring(h3Index.length - 8), BASE_16);\r\n  return [lower, upper];\r\n}\r\n\r\n/**\r\n * Convert a 32-bit int to a hexdecimal string\r\n * @private\r\n * @param  {number} num  Integer to convert\r\n * @return {H3Index}     Hexidecimal string\r\n */\r\nfunction hexFrom32Bit(num) {\r\n  if (num >= 0) {\r\n    return num.toString(BASE_16);\r\n  }\r\n\r\n  // Handle negative numbers\r\n  num = num & 0x7fffffff;\r\n  var tempStr = zeroPad(8, num.toString(BASE_16));\r\n  var topNum = (parseInt(tempStr[0], BASE_16) + 8).toString(BASE_16);\r\n  tempStr = topNum + tempStr.substring(1);\r\n  return tempStr;\r\n}\r\n\r\n/**\r\n * Get a H3 index string from a split long (pair of 32-bit ints)\r\n * @param  {number} lower Lower 32 bits\r\n * @param  {number} upper Upper 32 bits\r\n * @return {H3Index}       H3 index\r\n */\r\nfunction splitLongToH3Index(lower, upper) {\r\n  return hexFrom32Bit(upper) + zeroPad(8, hexFrom32Bit(lower));\r\n}\r\n\r\n/**\r\n * Zero-pad a string to a given length\r\n * @private\r\n * @param  {number} fullLen Target length\r\n * @param  {string} numStr  String to zero-pad\r\n * @return {string}         Zero-padded string\r\n */\r\nfunction zeroPad(fullLen, numStr) {\r\n  var numZeroes = fullLen - numStr.length;\r\n  var outStr = '';\r\n  for (var i = 0; i < numZeroes; i++) {\r\n    outStr += '0';\r\n  }\r\n  outStr = outStr + numStr;\r\n  return outStr;\r\n}\r\n\r\n// One more than the max size of an unsigned 32-bit int.\r\n// Dividing by this number is equivalent to num >>> 32\r\nvar UPPER_BIT_DIVISOR = Math.pow(2, 32);\r\n\r\n/**\r\n * Convert a JS double-precision floating point number to a split long\r\n * @private\r\n * @param  {number} num  Number to convert\r\n * @return {SplitLong}     A two-element array with 32 lower bits and 32 upper bits\r\n */\r\nfunction numberToSplitLong(num) {\r\n  if (typeof num !== 'number') {\r\n    return [0, 0];\r\n  }\r\n  return [num | 0, num / UPPER_BIT_DIVISOR | 0];\r\n}\r\n\r\n/**\r\n * Populate a C-appropriate GeoLoop struct from a polygon array\r\n * @private\r\n * @param  {number[][]} polygonArray  Polygon, as an array of coordinate pairs\r\n * @param  {number}  geoLoop          C pointer to a GeoLoop struct\r\n * @param  {boolean} isGeoJson        Whether coordinates are in [lng, lat] order per GeoJSON spec\r\n * @return {number}                   C pointer to populated GeoLoop struct\r\n */\r\nfunction polygonArrayToGeoLoop(polygonArray, geoLoop, isGeoJson) {\r\n  var numVerts = polygonArray.length;\r\n  var geoCoordArray = libh3._calloc(numVerts, SZ_LATLNG);\r\n  // Support [lng, lat] pairs if GeoJSON is specified\r\n  var latIndex = isGeoJson ? 1 : 0;\r\n  var lngIndex = isGeoJson ? 0 : 1;\r\n  for (var i = 0; i < numVerts * 2; i += 2) {\r\n    libh3.HEAPF64.set([polygonArray[i / 2][latIndex], polygonArray[i / 2][lngIndex]].map(degsToRads), geoCoordArray / SZ_DBL + i);\r\n  }\r\n  libh3.HEAPU32.set([numVerts, geoCoordArray], geoLoop / SZ_INT);\r\n  return geoLoop;\r\n}\r\n\r\n/**\r\n * Create a C-appropriate GeoPolygon struct from an array of polygons\r\n * @private\r\n * @param  {number[][][]} coordinates Array of polygons, each an array of coordinate pairs\r\n * @param  {boolean} isGeoJson        Whether coordinates are in [lng, lat] order per GeoJSON spec\r\n * @return {number}                   C pointer to populated GeoPolygon struct\r\n */\r\nfunction coordinatesToGeoPolygon(coordinates, isGeoJson) {\r\n  // Any loops beyond the first loop are holes\r\n  var numHoles = coordinates.length - 1;\r\n  var geoPolygon = libh3._calloc(SZ_GEOPOLYGON);\r\n  // Byte positions within the struct\r\n  var geoLoopOffset = 0;\r\n  var numHolesOffset = geoLoopOffset + SZ_GEOLOOP;\r\n  var holesOffset = numHolesOffset + SZ_INT;\r\n  // geoLoop is first part of struct\r\n  polygonArrayToGeoLoop(coordinates[0], geoPolygon + geoLoopOffset, isGeoJson);\r\n  var holes;\r\n  if (numHoles > 0) {\r\n    holes = libh3._calloc(numHoles, SZ_GEOLOOP);\r\n    for (var i = 0; i < numHoles; i++) {\r\n      polygonArrayToGeoLoop(coordinates[i + 1], holes + SZ_GEOLOOP * i, isGeoJson);\r\n    }\r\n  }\r\n  libh3.setValue(geoPolygon + numHolesOffset, numHoles, 'i32');\r\n  libh3.setValue(geoPolygon + holesOffset, holes, 'i32');\r\n  return geoPolygon;\r\n}\r\n\r\n/**\r\n * Free memory allocated for a GeoPolygon struct. It is an error to access the struct\r\n * after passing it to this method.\r\n * @private\r\n * @param {number} geoPolygon     C pointer to GeoPolygon struct\r\n * @return {void}\r\n */\r\nfunction destroyGeoPolygon(geoPolygon) {\r\n  // Byte positions within the struct\r\n  var geoLoopOffset = 0;\r\n  var numHolesOffset = geoLoopOffset + SZ_GEOLOOP;\r\n  var holesOffset = numHolesOffset + SZ_INT;\r\n  // Offset of the geoLoop vertex array pointer within the GeoLoop struct\r\n  var geoLoopArrayOffset = SZ_INT;\r\n  // Free the outer vertex array\r\n  libh3._free(libh3.getValue(geoPolygon + geoLoopOffset + geoLoopArrayOffset, 'i8*'));\r\n  // Free the vertex array for the holes, if any\r\n  var numHoles = libh3.getValue(geoPolygon + numHolesOffset, 'i32');\r\n  if (numHoles > 0) {\r\n    var holes = libh3.getValue(geoPolygon + holesOffset, 'i32');\r\n    for (var i = 0; i < numHoles; i++) {\r\n      libh3._free(libh3.getValue(holes + SZ_GEOLOOP * i + geoLoopArrayOffset, 'i8*'));\r\n    }\r\n    libh3._free(holes);\r\n  }\r\n  libh3._free(geoPolygon);\r\n}\r\n\r\n/**\r\n * Read an H3 index from a pointer to C memory.\r\n * @private\r\n * @param  {number} cAddress  Pointer to allocated C memory\r\n * @param {number} offset     Offset, in number of H3 indexes, in case we're\r\n *                            reading an array\r\n * @return {H3Index | null}   H3 index, or null if index was invalid\r\n */\r\nfunction readH3IndexFromPointer(cAddress, offset) {\r\n  if ( offset === void 0 ) offset = 0;\r\n\r\n  var lower = libh3.getValue(cAddress + SZ_H3INDEX * offset, 'i32');\r\n  var upper = libh3.getValue(cAddress + SZ_H3INDEX * offset + SZ_INT, 'i32');\r\n  // The lower bits are allowed to be 0s, but if the upper bits are 0\r\n  // this represents an invalid H3 index\r\n  return upper ? splitLongToH3Index(lower, upper) : null;\r\n}\r\n\r\n/**\r\n * Read a boolean (32 bit) from a pointer to C memory.\r\n * @private\r\n * @param  {number} cAddress  Pointer to allocated C memory\r\n * @param {number} offset     Offset, in number of booleans, in case we're\r\n *                            reading an array\r\n * @return {Boolean} Boolean value\r\n */\r\nfunction readBooleanFromPointer(cAddress, offset) {\r\n  if ( offset === void 0 ) offset = 0;\r\n\r\n  var val = libh3.getValue(cAddress + SZ_INT * offset, 'i32');\r\n  return Boolean(val);\r\n}\r\n\r\n/**\r\n * Read a double from a pointer to C memory.\r\n * @private\r\n * @param  {number} cAddress  Pointer to allocated C memory\r\n * @param {number} offset     Offset, in number of doubles, in case we're\r\n *                            reading an array\r\n * @return {number} Double value\r\n */\r\nfunction readDoubleFromPointer(cAddress, offset) {\r\n  if ( offset === void 0 ) offset = 0;\r\n\r\n  return libh3.getValue(cAddress + SZ_DBL * offset, 'double');\r\n}\r\n\r\n/**\r\n * Read a 64-bit int from a pointer to C memory into a JS 64-bit float.\r\n * Note that this may lose precision if larger than MAX_SAFE_INTEGER\r\n * @private\r\n * @param  {number} cAddress  Pointer to allocated C memory\r\n * @return {number} Double value\r\n */\r\nfunction readInt64AsDoubleFromPointer(cAddress) {\r\n  return H3.readInt64AsDoubleFromPointer(cAddress);\r\n}\r\n\r\n/**\r\n * Store an H3 index in C memory. Primarily used as an efficient way to\r\n * write sets of hexagons.\r\n * @private\r\n * @param  {H3IndexInput} h3Index  H3 index to store\r\n * @param  {number} cAddress  Pointer to allocated C memory\r\n * @param {number} offset     Offset, in number of H3 indexes from beginning\r\n *                            of the current array\r\n */\r\nfunction storeH3Index(h3Index, cAddress, offset) {\r\n  // HEAPU32 is a typed array projection on the index space\r\n  // as unsigned 32-bit integers. This means the index needs\r\n  // to be divided by SZ_INT (4) to access correctly. Also,\r\n  // the H3 index is 64 bits, so we skip by twos as we're writing\r\n  // to 32-bit integers in the proper order.\r\n  libh3.HEAPU32.set(h3IndexToSplitLong(h3Index), cAddress / SZ_INT + 2 * offset);\r\n}\r\n\r\n/**\r\n * Read an array of 64-bit H3 indexes from C and convert to a JS array of\r\n * H3 index strings\r\n * @private\r\n * @param  {number} cAddress    Pointer to C ouput array\r\n * @param  {number} maxCount    Max number of hexagons in array. Hexagons with\r\n *                              the value 0 will be skipped, so this isn't\r\n *                              necessarily the length of the output array.\r\n * @return {H3Index[]}          Array of H3 indexes\r\n */\r\nfunction readArrayOfH3Indexes(cAddress, maxCount) {\r\n  var out = [];\r\n  for (var i = 0; i < maxCount; i++) {\r\n    var h3Index = readH3IndexFromPointer(cAddress, i);\r\n    if (h3Index !== null) {\r\n      out.push(h3Index);\r\n    }\r\n  }\r\n  return out;\r\n}\r\n\r\n/**\r\n * Store an array of H3 index strings as a C array of 64-bit integers.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C input array\r\n * @param  {H3IndexInput[]} hexagons H3 indexes to pass to the C lib\r\n */\r\nfunction storeArrayOfH3Indexes(cAddress, hexagons) {\r\n  // Assuming the cAddress points to an already appropriately\r\n  // allocated space\r\n  var count = hexagons.length;\r\n  for (var i = 0; i < count; i++) {\r\n    storeH3Index(hexagons[i], cAddress, i);\r\n  }\r\n}\r\n\r\n/**\r\n * Populate a C-appropriate LatLng struct from a [lat, lng] array\r\n * @private\r\n * @param {number} lat     Coordinate latitude\r\n * @param {number} lng     Coordinate longitude\r\n * @return {number}        C pointer to populated LatLng struct\r\n */\r\nfunction storeLatLng(lat, lng) {\r\n  var geoCoord = libh3._calloc(1, SZ_LATLNG);\r\n  libh3.HEAPF64.set([lat, lng].map(degsToRads), geoCoord / SZ_DBL);\r\n  return geoCoord;\r\n}\r\n\r\n/**\r\n * Read a single lat or lng value\r\n * @private\r\n * @param  {number} cAddress Pointer to C value\r\n * @return {number}\r\n */\r\nfunction readSingleCoord(cAddress) {\r\n  return radsToDegs(libh3.getValue(cAddress, 'double'));\r\n}\r\n\r\n/**\r\n * Read a LatLng from C and return a [lat, lng] pair.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C struct\r\n * @return {CoordPair}          [lat, lng] pair\r\n */\r\nfunction readLatLng(cAddress) {\r\n  return [readSingleCoord(cAddress), readSingleCoord(cAddress + SZ_DBL)];\r\n}\r\n\r\n/**\r\n * Read a LatLng from C and return a GeoJSON-style [lng, lat] pair.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C struct\r\n * @return {CoordPair}          [lng, lat] pair\r\n */\r\nfunction readLatLngGeoJson(cAddress) {\r\n  return [readSingleCoord(cAddress + SZ_DBL), readSingleCoord(cAddress)];\r\n}\r\n\r\n/**\r\n * Read the CellBoundary structure into a list of geo coordinate pairs\r\n * @private\r\n * @param {number}  cellBoundary       C pointer to CellBoundary struct\r\n * @param {boolean} [geoJsonCoords]    Whether to provide GeoJSON coordinate order: [lng, lat]\r\n * @param {boolean} [closedLoop]       Whether to close the loop\r\n * @return {CoordPair[]}               Array of geo coordinate pairs\r\n */\r\nfunction readCellBoundary(cellBoundary, geoJsonCoords, closedLoop) {\r\n  var numVerts = libh3.getValue(cellBoundary, 'i32');\r\n  // Note that though numVerts is an int, the coordinate doubles have to be\r\n  // aligned to 8 bytes, hence the 8-byte offset here\r\n  var vertsPos = cellBoundary + SZ_DBL;\r\n  var out = [];\r\n  // Support [lng, lat] pairs if GeoJSON is specified\r\n  var readCoord = geoJsonCoords ? readLatLngGeoJson : readLatLng;\r\n  for (var i = 0; i < numVerts * 2; i += 2) {\r\n    out.push(readCoord(vertsPos + SZ_DBL * i));\r\n  }\r\n  if (closedLoop) {\r\n    // Close loop if GeoJSON is specified\r\n    out.push(out[0]);\r\n  }\r\n  return out;\r\n}\r\n\r\n/**\r\n * Read the LinkedGeoPolygon structure into a nested array of MultiPolygon coordinates\r\n * @private\r\n * @param {number}  polygon           C pointer to LinkedGeoPolygon struct\r\n * @param {boolean} [formatAsGeoJson] Whether to provide GeoJSON output: [lng, lat], closed loops\r\n * @return {CoordPair[][][]}          MultiPolygon-style output.\r\n */\r\nfunction readMultiPolygon(polygon, formatAsGeoJson) {\r\n  var output = [];\r\n  var readCoord = formatAsGeoJson ? readLatLngGeoJson : readLatLng;\r\n  var loops;\r\n  var loop;\r\n  var coords;\r\n  var coord;\r\n  // Loop through the linked structure, building the output\r\n  while (polygon) {\r\n    output.push(loops = []);\r\n    // Follow ->first pointer\r\n    loop = libh3.getValue(polygon, 'i8*');\r\n    while (loop) {\r\n      loops.push(coords = []);\r\n      // Follow ->first pointer\r\n      coord = libh3.getValue(loop, 'i8*');\r\n      while (coord) {\r\n        coords.push(readCoord(coord));\r\n        // Follow ->next pointer\r\n        coord = libh3.getValue(coord + SZ_DBL * 2, 'i8*');\r\n      }\r\n      if (formatAsGeoJson) {\r\n        // Close loop if GeoJSON is requested\r\n        coords.push(coords[0]);\r\n      }\r\n      // Follow ->next pointer\r\n      loop = libh3.getValue(loop + SZ_PTR * 2, 'i8*');\r\n    }\r\n    // Follow ->next pointer\r\n    polygon = libh3.getValue(polygon + SZ_PTR * 2, 'i8*');\r\n  }\r\n  return output;\r\n}\r\n\r\n/**\r\n * Read a CoordIJ from C and return an {i, j} pair.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C struct\r\n * @return {CoordIJ}            {i, j} pair\r\n */\r\nfunction readCoordIJ(cAddress) {\r\n  return {\r\n    i: libh3.getValue(cAddress, 'i32'),\r\n    j: libh3.getValue(cAddress + SZ_INT, 'i32')\r\n  };\r\n}\r\n\r\n/**\r\n * Store an {i, j} pair to a C CoordIJ struct.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C memory\r\n * @param {CoordIJ} ij          {i,j} pair to store\r\n * @return {void}\r\n */\r\nfunction storeCoordIJ(cAddress, ref) {\r\n  var i = ref.i;\r\n  var j = ref.j;\r\n\r\n  libh3.setValue(cAddress, i, 'i32');\r\n  libh3.setValue(cAddress + SZ_INT, j, 'i32');\r\n}\r\n\r\n/**\r\n * Read an array of positive integers array from C. Negative\r\n * values are considered invalid and ignored in output.\r\n * @private\r\n * @param  {number} cAddress    Pointer to C array\r\n * @param  {number} count       Length of C array\r\n * @return {number[]}           Javascript integer array\r\n */\r\nfunction readArrayOfPositiveIntegers(cAddress, count) {\r\n  var out = [];\r\n  for (var i = 0; i < count; i++) {\r\n    var int = libh3.getValue(cAddress + SZ_INT * i, 'i32');\r\n    if (int >= 0) {\r\n      out.push(int);\r\n    }\r\n  }\r\n  return out;\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public API functions: Core\r\n\r\n/**\r\n * Whether a given string represents a valid H3 index\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to check\r\n * @return {boolean}          Whether the index is valid\r\n */\r\nfunction isValidCell(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return Boolean(H3.isValidCell(lower, upper));\r\n}\r\n\r\n/**\r\n * Whether the given H3 index is a pentagon\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to check\r\n * @return {boolean}          isPentagon\r\n */\r\nfunction isPentagon(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return Boolean(H3.isPentagon(lower, upper));\r\n}\r\n\r\n/**\r\n * Whether the given H3 index is in a Class III resolution (rotated versus\r\n * the icosahedron and subject to shape distortion adding extra points on\r\n * icosahedron edges, making them not true hexagons).\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to check\r\n * @return {boolean}          isResClassIII\r\n */\r\nfunction isResClassIII(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return Boolean(H3.isResClassIII(lower, upper));\r\n}\r\n\r\n/**\r\n * Get the number of the base cell for a given H3 index\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get the base cell for\r\n * @return {number}           Index of the base cell (0-121)\r\n */\r\nfunction getBaseCellNumber(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return H3.getBaseCellNumber(lower, upper);\r\n}\r\n\r\n/**\r\n * Get the indices of all icosahedron faces intersected by a given H3 index\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get faces for\r\n * @return {number[]}              Indices (0-19) of all intersected faces\r\n * @throws {H3Error}               If input is invalid\r\n */\r\nfunction getIcosahedronFaces(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var countPtr = libh3._malloc(SZ_INT);\r\n  try {\r\n    throwIfError(H3.maxFaceCount(lower, upper, countPtr));\r\n    var count = libh3.getValue(countPtr, 'i32');\r\n    var faces = libh3._malloc(SZ_INT * count);\r\n    try {\r\n      throwIfError(H3.getIcosahedronFaces(lower, upper, faces));\r\n      return readArrayOfPositiveIntegers(faces, count);\r\n    } finally {\r\n      libh3._free(faces);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Returns the resolution of an H3 index\r\n * @static\r\n * @param  {H3IndexInput} h3Index H3 index to get resolution\r\n * @return {number}          The number (0-15) resolution, or -1 if invalid\r\n */\r\nfunction getResolution(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  if (!H3.isValidCell(lower, upper)) {\r\n    // Compatability with stated API\r\n    return -1;\r\n  }\r\n  return H3.getResolution(lower, upper);\r\n}\r\n\r\n/**\r\n * Get the hexagon containing a lat,lon point\r\n * @static\r\n * @param  {number} lat Latitude of point\r\n * @param  {number} lng Longtitude of point\r\n * @param  {number} res Resolution of hexagons to return\r\n * @return {H3Index}    H3 index\r\n * @throws {H3Error}    If input is invalid\r\n */\r\nfunction latLngToCell(lat, lng, res) {\r\n  var latLng = libh3._malloc(SZ_LATLNG);\r\n  // Slightly more efficient way to set the memory\r\n  libh3.HEAPF64.set([lat, lng].map(degsToRads), latLng / SZ_DBL);\r\n  // Read value as a split long\r\n  var h3Index = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.latLngToCell(latLng, res, h3Index));\r\n    return validateH3Index(readH3IndexFromPointer(h3Index));\r\n  } finally {\r\n    libh3._free(h3Index);\r\n    libh3._free(latLng);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the lat,lon center of a given hexagon\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index\r\n * @return {CoordPair}             Point as a [lat, lng] pair\r\n * @throws {H3Error}               If input is invalid\r\n */\r\nfunction cellToLatLng(h3Index) {\r\n  var latLng = libh3._malloc(SZ_LATLNG);\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  try {\r\n    throwIfError(H3.cellToLatLng(lower, upper, latLng));\r\n    return readLatLng(latLng);\r\n  } finally {\r\n    libh3._free(latLng);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the vertices of a given hexagon (or pentagon), as an array of [lat, lng]\r\n * points. For pentagons and hexagons on the edge of an icosahedron face, this\r\n * function may return up to 10 vertices.\r\n * @static\r\n * @param  {H3IndexInput} h3Index          H3 index\r\n * @param {boolean} [formatAsGeoJson] Whether to provide GeoJSON output: [lng, lat], closed loops\r\n * @return {CoordPair[]}              Array of [lat, lng] pairs\r\n * @throws {H3Error}                  If input is invalid\r\n */\r\nfunction cellToBoundary(h3Index, formatAsGeoJson) {\r\n  var cellBoundary = libh3._malloc(SZ_CELLBOUNDARY);\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  try {\r\n    throwIfError(H3.cellToBoundary(lower, upper, cellBoundary));\r\n    return readCellBoundary(cellBoundary, formatAsGeoJson, formatAsGeoJson);\r\n  } finally {\r\n    libh3._free(cellBoundary);\r\n  }\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public API functions: Algorithms\r\n\r\n/**\r\n * Get the parent of the given hexagon at a particular resolution\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get parent for\r\n * @param  {number} res       Resolution of hexagon to return\r\n * @return {H3Index}          H3 index of parent, or null for invalid input\r\n * @throws {H3Error}          If input is invalid\r\n */\r\nfunction cellToParent(h3Index, res) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var parent = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellToParent(lower, upper, res, parent));\r\n    return validateH3Index(readH3IndexFromPointer(parent));\r\n  } finally {\r\n    libh3._free(parent);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the children/descendents of the given hexagon at a particular resolution\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get children for\r\n * @param  {number} res       Resolution of hexagons to return\r\n * @return {H3Index[]}        H3 indexes of children, or empty array for invalid input\r\n * @throws {H3Error}          If resolution is invalid or output is too large for JS\r\n */\r\nfunction cellToChildren(h3Index, res) {\r\n  // Bad input in this case can potentially result in high computation volume\r\n  // using the current C algorithm. Validate and return an empty array on failure.\r\n  if (!isValidCell(h3Index)) {\r\n    return [];\r\n  }\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var count = validateArrayLength(cellToChildrenSize(h3Index, res));\r\n  var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellToChildren(lower, upper, res, hexagons));\r\n    return readArrayOfH3Indexes(hexagons, count);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the number of children for a cell at a given resolution\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get child count for\r\n * @param  {number} res            Child resolution\r\n * @return {number}                Number of children at res for the given cell\r\n * @throws {H3Error}               If cell or parentRes are invalid\r\n */\r\nfunction cellToChildrenSize(h3Index, res) {\r\n  if (!isValidCell(h3Index)) {\r\n    throw H3LibraryError(E_CELL_INVALID);\r\n  }\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.cellToChildrenSize(lower, upper, res, countPtr));\r\n    return readInt64AsDoubleFromPointer(countPtr);\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the center child of the given hexagon at a particular resolution\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get center child for\r\n * @param  {number} res       Resolution of cell to return\r\n * @return {H3Index}          H3 index of child, or null for invalid input\r\n * @throws {H3Error}          If resolution is invalid\r\n */\r\nfunction cellToCenterChild(h3Index, res) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var centerChild = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellToCenterChild(lower, upper, res, centerChild));\r\n    return validateH3Index(readH3IndexFromPointer(centerChild));\r\n  } finally {\r\n    libh3._free(centerChild);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the position of the cell within an ordered list of all children of the\r\n * cell's parent at the specified resolution.\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index to get child pos for\r\n * @param  {number} parentRes      Resolution of reference parent\r\n * @return {number}                Position of child within parent at parentRes\r\n * @throws {H3Error}               If cell or parentRes are invalid\r\n */\r\nfunction cellToChildPos(h3Index, parentRes) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var childPos = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.cellToChildPos(lower, upper, parentRes, childPos));\r\n    return readInt64AsDoubleFromPointer(childPos);\r\n  } finally {\r\n    libh3._free(childPos);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the child cell at a given position within an ordered list of all children\r\n * at the specified resolution\r\n * @static\r\n * @param  {number} childPos       Position of the child cell to get\r\n * @param  {H3IndexInput} h3Index  H3 index of the parent cell\r\n * @param  {number} childRes       Resolution of child cell to return\r\n * @return {H3Index}          H3 index of child\r\n * @throws {H3Error}          If input is invalid\r\n */\r\nfunction childPosToCell(childPos, h3Index, childRes) {\r\n  var ref = numberToSplitLong(childPos);\r\n  var cpLower = ref[0];\r\n  var cpUpper = ref[1];\r\n  var ref$1 = h3IndexToSplitLong(h3Index);\r\n  var lower = ref$1[0];\r\n  var upper = ref$1[1];\r\n  var child = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.childPosToCell(cpLower, cpUpper, lower, upper, childRes, child));\r\n    return validateH3Index(readH3IndexFromPointer(child));\r\n  } finally {\r\n    libh3._free(child);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons in a k-ring around a given center. The order of the hexagons is undefined.\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index of center hexagon\r\n * @param  {number} ringSize  Radius of k-ring\r\n * @return {H3Index[]}        H3 indexes for all hexagons in ring\r\n * @throws {H3Error}          If input is invalid or output is too large for JS\r\n */\r\nfunction gridDisk(h3Index, ringSize) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.maxGridDiskSize(ringSize, countPtr));\r\n    var count = validateArrayLength(readInt64AsDoubleFromPointer(countPtr));\r\n    var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n    try {\r\n      throwIfError(H3.gridDisk(lower, upper, ringSize, hexagons));\r\n      return readArrayOfH3Indexes(hexagons, count);\r\n    } finally {\r\n      libh3._free(hexagons);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons in a k-ring around a given center, in an array of arrays\r\n * ordered by distance from the origin. The order of the hexagons within each ring is undefined.\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index of center hexagon\r\n * @param  {number} ringSize  Radius of k-ring\r\n * @return {H3Index[][]}      Array of arrays with H3 indexes for all hexagons each ring\r\n * @throws {H3Error}          If input is invalid or output is too large for JS\r\n */\r\nfunction gridDiskDistances(h3Index, ringSize) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.maxGridDiskSize(ringSize, countPtr));\r\n    var count = validateArrayLength(readInt64AsDoubleFromPointer(countPtr));\r\n    var kRings = libh3._calloc(count, SZ_H3INDEX);\r\n    var distances = libh3._calloc(count, SZ_INT);\r\n    try {\r\n      throwIfError(H3.gridDiskDistances(lower, upper, ringSize, kRings, distances));\r\n      /**\r\n       * An array of empty arrays to hold the output\r\n       * @type {string[][]}\r\n       * @private\r\n       */\r\n      var out = [];\r\n      for (var i = 0; i < ringSize + 1; i++) {\r\n        out.push([]);\r\n      }\r\n      // Read the array of hexagons, putting them into the appropriate rings\r\n      for (var i$1 = 0; i$1 < count; i$1++) {\r\n        var cell = readH3IndexFromPointer(kRings, i$1);\r\n        var index = libh3.getValue(distances + SZ_INT * i$1, 'i32');\r\n        // eslint-disable-next-line max-depth\r\n        if (cell !== null) {\r\n          out[index].push(cell);\r\n        }\r\n      }\r\n      return out;\r\n    } finally {\r\n      libh3._free(kRings);\r\n      libh3._free(distances);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons in a hollow hexagonal ring centered at origin with sides of a given length.\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index of center hexagon\r\n * @param  {number} ringSize  Radius of ring\r\n * @return {H3Index[]}        H3 indexes for all hexagons in ring\r\n * @throws {Error}            If the algorithm could not calculate the ring\r\n * @throws {H3Error}          If input is invalid\r\n */\r\nfunction gridRing(h3Index, ringSize) {\r\n  var maxCount = ringSize === 0 ? 1 : 6 * ringSize;\r\n  var hexagons = libh3._calloc(maxCount, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.gridRing.apply(H3, h3IndexToSplitLong(h3Index).concat( [ringSize], [hexagons] )));\r\n    return readArrayOfH3Indexes(hexagons, maxCount);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons in a hollow hexagonal ring centered at origin with sides of a given length.\r\n * Unlike gridDisk, this function will throw an error if there is a pentagon anywhere in the ring.\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index of center hexagon\r\n * @param  {number} ringSize  Radius of ring\r\n * @return {H3Index[]}        H3 indexes for all hexagons in ring\r\n * @throws {Error}            If the algorithm could not calculate the ring\r\n * @throws {H3Error}          If input is invalid\r\n */\r\nfunction gridRingUnsafe(h3Index, ringSize) {\r\n  var maxCount = ringSize === 0 ? 1 : 6 * ringSize;\r\n  var hexagons = libh3._calloc(maxCount, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.gridRingUnsafe.apply(H3, h3IndexToSplitLong(h3Index).concat( [ringSize], [hexagons] )));\r\n    return readArrayOfH3Indexes(hexagons, maxCount);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons with centers contained in a given polygon. The polygon\r\n * is specified with GeoJson semantics as an array of loops. Each loop is\r\n * an array of [lat, lng] pairs (or [lng, lat] if isGeoJson is specified).\r\n * The first loop is the perimeter of the polygon, and subsequent loops are\r\n * expected to be holes.\r\n * @static\r\n * @param  {number[][] | number[][][]} coordinates\r\n *                                  Array of loops, or a single loop\r\n * @param  {number} res             Resolution of hexagons to return\r\n * @param  {boolean} [isGeoJson]    Whether to expect GeoJson-style [lng, lat]\r\n *                                  pairs instead of [lat, lng]\r\n * @return {H3Index[]}              H3 indexes for all hexagons in polygon\r\n * @throws {H3Error}                If input is invalid or output is too large for JS\r\n */\r\nfunction polygonToCells(coordinates, res, isGeoJson) {\r\n  validateRes(res);\r\n  isGeoJson = Boolean(isGeoJson);\r\n  // Guard against empty input\r\n  if (coordinates.length === 0 || coordinates[0].length === 0) {\r\n    return [];\r\n  }\r\n  // Wrap to expected format if a single loop is provided\r\n  var polygon = typeof coordinates[0][0] === 'number' ? [coordinates] : coordinates;\r\n  var geoPolygon = coordinatesToGeoPolygon(\r\n  // @ts-expect-error - There's no way to convince TS that polygon is now number[][][]\r\n  polygon, isGeoJson);\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.maxPolygonToCellsSize(geoPolygon, res, 0, countPtr));\r\n    var count = validateArrayLength(readInt64AsDoubleFromPointer(countPtr));\r\n    var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n    try {\r\n      throwIfError(H3.polygonToCells(geoPolygon, res, 0, hexagons));\r\n      return readArrayOfH3Indexes(hexagons, count);\r\n    } finally {\r\n      libh3._free(hexagons);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n    destroyGeoPolygon(geoPolygon);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all hexagons with centers contained in a given polygon. The polygon\r\n * is specified with GeoJson semantics as an array of loops. Each loop is\r\n * an array of [lat, lng] pairs (or [lng, lat] if isGeoJson is specified).\r\n * The first loop is the perimeter of the polygon, and subsequent loops are\r\n * expected to be holes.\r\n * @static\r\n * @param  {number[][] | number[][][]} coordinates\r\n *                                  Array of loops, or a single loop\r\n * @param  {number} res             Resolution of hexagons to return\r\n * @param  {string} flags           Value from POLYGON_TO_CELLS_FLAGS\r\n * @param  {boolean} [isGeoJson]    Whether to expect GeoJson-style [lng, lat]\r\n *                                  pairs instead of [lat, lng]\r\n * @return {H3Index[]}              H3 indexes for all hexagons in polygon\r\n * @throws {H3Error}                If input is invalid or output is too large for JS\r\n */\r\nfunction polygonToCellsExperimental(coordinates, res, flags, isGeoJson) {\r\n  validateRes(res);\r\n  isGeoJson = Boolean(isGeoJson);\r\n  var flagsInt = polygonToCellsFlagsToNumber(flags);\r\n  // Guard against empty input\r\n  if (coordinates.length === 0 || coordinates[0].length === 0) {\r\n    return [];\r\n  }\r\n  // Wrap to expected format if a single loop is provided\r\n  var polygon = typeof coordinates[0][0] === 'number' ? [coordinates] : coordinates;\r\n  var geoPolygon = coordinatesToGeoPolygon(\r\n  // @ts-expect-error - There's no way to convince TS that polygon is now number[][][]\r\n  polygon, isGeoJson);\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.maxPolygonToCellsSizeExperimental(geoPolygon, res, flagsInt, countPtr));\r\n    var count = validateArrayLength(readInt64AsDoubleFromPointer(countPtr));\r\n    var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n    try {\r\n      throwIfError(H3.polygonToCellsExperimental(geoPolygon, res, flagsInt, count, UNUSED_UPPER_32_BITS, hexagons));\r\n      return readArrayOfH3Indexes(hexagons, count);\r\n    } finally {\r\n      libh3._free(hexagons);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n    destroyGeoPolygon(geoPolygon);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the outlines of a set of H3 hexagons, returned in GeoJSON MultiPolygon\r\n * format (an array of polygons, each with an array of loops, each an array of\r\n * coordinates). Coordinates are returned as [lat, lng] pairs unless GeoJSON\r\n * is requested.\r\n *\r\n * It is the responsibility of the caller to ensure that all hexagons in the\r\n * set have the same resolution and that the set contains no duplicates. Behavior\r\n * is undefined if duplicates or multiple resolutions are present, and the\r\n * algorithm may produce unexpected or invalid polygons.\r\n *\r\n * @static\r\n * @param {H3IndexInput[]} h3Indexes  H3 indexes to get outlines for\r\n * @param {boolean} [formatAsGeoJson] Whether to provide GeoJSON output: [lng, lat], closed loops\r\n * @return {CoordPair[][][]}          MultiPolygon-style output.\r\n * @throws {H3Error}                  If input is invalid\r\n */\r\nfunction cellsToMultiPolygon(h3Indexes, formatAsGeoJson) {\r\n  // Early exit on empty input\r\n  if (!h3Indexes || !h3Indexes.length) {\r\n    return [];\r\n  }\r\n  // Set up input set\r\n  var indexCount = h3Indexes.length;\r\n  var set = libh3._calloc(indexCount, SZ_H3INDEX);\r\n  storeArrayOfH3Indexes(set, h3Indexes);\r\n  // Allocate memory for output linked polygon\r\n  var polygon = libh3._calloc(SZ_LINKED_GEOPOLYGON);\r\n  try {\r\n    throwIfError(H3.cellsToLinkedMultiPolygon(set, indexCount, polygon));\r\n    return readMultiPolygon(polygon, formatAsGeoJson);\r\n  } finally {\r\n    // Clean up\r\n    H3.destroyLinkedMultiPolygon(polygon);\r\n    libh3._free(polygon);\r\n    libh3._free(set);\r\n  }\r\n}\r\n\r\n/**\r\n * Compact a set of hexagons of the same resolution into a set of hexagons across\r\n * multiple levels that represents the same area.\r\n * @static\r\n * @param  {H3IndexInput[]} h3Set H3 indexes to compact\r\n * @return {H3Index[]}       Compacted H3 indexes\r\n * @throws {H3Error}         If the input is invalid (e.g. duplicate hexagons)\r\n */\r\nfunction compactCells(h3Set) {\r\n  if (!h3Set || !h3Set.length) {\r\n    return [];\r\n  }\r\n  // Set up input set\r\n  var count = h3Set.length;\r\n  var set = libh3._calloc(count, SZ_H3INDEX);\r\n  storeArrayOfH3Indexes(set, h3Set);\r\n  // Allocate memory for compacted hexagons, worst-case is no compaction\r\n  var compactedSet = libh3._calloc(count, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.compactCells(set, compactedSet, count, UNUSED_UPPER_32_BITS));\r\n    return readArrayOfH3Indexes(compactedSet, count);\r\n  } finally {\r\n    libh3._free(set);\r\n    libh3._free(compactedSet);\r\n  }\r\n}\r\n\r\n/**\r\n * Uncompact a compacted set of hexagons to hexagons of the same resolution\r\n * @static\r\n * @param  {H3IndexInput[]} compactedSet H3 indexes to uncompact\r\n * @param  {number}    res          The resolution to uncompact to\r\n * @return {H3Index[]}              The uncompacted H3 indexes\r\n * @throws {H3Error}                If the input is invalid (e.g. invalid resolution)\r\n */\r\nfunction uncompactCells(compactedSet, res) {\r\n  validateRes(res);\r\n  if (!compactedSet || !compactedSet.length) {\r\n    return [];\r\n  }\r\n  // Set up input set\r\n  var count = compactedSet.length;\r\n  var set = libh3._calloc(count, SZ_H3INDEX);\r\n  storeArrayOfH3Indexes(set, compactedSet);\r\n  // Estimate how many hexagons we need (always overestimates if in error)\r\n  var uncompactCellSizePtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.uncompactCellsSize(set, count, UNUSED_UPPER_32_BITS, res, uncompactCellSizePtr));\r\n    var uncompactCellSize = validateArrayLength(readInt64AsDoubleFromPointer(uncompactCellSizePtr));\r\n    // Allocate memory for uncompacted hexagons\r\n    var uncompactedSet = libh3._calloc(uncompactCellSize, SZ_H3INDEX);\r\n    try {\r\n      throwIfError(H3.uncompactCells(set, count, UNUSED_UPPER_32_BITS, uncompactedSet, uncompactCellSize, UNUSED_UPPER_32_BITS, res));\r\n      return readArrayOfH3Indexes(uncompactedSet, uncompactCellSize);\r\n    } finally {\r\n      libh3._free(set);\r\n      libh3._free(uncompactedSet);\r\n    }\r\n  } finally {\r\n    libh3._free(uncompactCellSizePtr);\r\n  }\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public API functions: Directed edges\r\n\r\n/**\r\n * Whether two H3 indexes are neighbors (share an edge)\r\n * @static\r\n * @param  {H3IndexInput} origin      Origin hexagon index\r\n * @param  {H3IndexInput} destination Destination hexagon index\r\n * @return {boolean}             Whether the hexagons share an edge\r\n * @throws {H3Error}             If the input is invalid\r\n */\r\nfunction areNeighborCells(origin, destination) {\r\n  var ref = h3IndexToSplitLong(origin);\r\n  var oLower = ref[0];\r\n  var oUpper = ref[1];\r\n  var ref$1 = h3IndexToSplitLong(destination);\r\n  var dLower = ref$1[0];\r\n  var dUpper = ref$1[1];\r\n  var out = libh3._malloc(SZ_INT);\r\n  try {\r\n    throwIfError(H3.areNeighborCells(oLower, oUpper, dLower, dUpper, out));\r\n    return readBooleanFromPointer(out);\r\n  } finally {\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n/**\r\n * Get an H3 index representing a unidirectional edge for a given origin and destination\r\n * @static\r\n * @param  {H3IndexInput} origin      Origin hexagon index\r\n * @param  {H3IndexInput} destination Destination hexagon index\r\n * @return {H3Index}             H3 index of the edge, or null if no edge is shared\r\n * @throws {H3Error}             If the input is invalid\r\n */\r\nfunction cellsToDirectedEdge(origin, destination) {\r\n  var ref = h3IndexToSplitLong(origin);\r\n  var oLower = ref[0];\r\n  var oUpper = ref[1];\r\n  var ref$1 = h3IndexToSplitLong(destination);\r\n  var dLower = ref$1[0];\r\n  var dUpper = ref$1[1];\r\n  var h3Index = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellsToDirectedEdge(oLower, oUpper, dLower, dUpper, h3Index));\r\n    return validateH3Index(readH3IndexFromPointer(h3Index));\r\n  } finally {\r\n    libh3._free(h3Index);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the origin hexagon from an H3 index representing a unidirectional edge\r\n * @static\r\n * @param  {H3IndexInput} edgeIndex H3 index of the edge\r\n * @return {H3Index}           H3 index of the edge origin\r\n * @throws {H3Error}           If the input is invalid\r\n */\r\nfunction getDirectedEdgeOrigin(edgeIndex) {\r\n  var ref = h3IndexToSplitLong(edgeIndex);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var h3Index = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.getDirectedEdgeOrigin(lower, upper, h3Index));\r\n    return validateH3Index(readH3IndexFromPointer(h3Index));\r\n  } finally {\r\n    libh3._free(h3Index);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the destination hexagon from an H3 index representing a unidirectional edge\r\n * @static\r\n * @param  {H3IndexInput} edgeIndex H3 index of the edge\r\n * @return {H3Index}           H3 index of the edge destination\r\n * @throws {H3Error}           If the input is invalid\r\n */\r\nfunction getDirectedEdgeDestination(edgeIndex) {\r\n  var ref = h3IndexToSplitLong(edgeIndex);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var h3Index = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.getDirectedEdgeDestination(lower, upper, h3Index));\r\n    return validateH3Index(readH3IndexFromPointer(h3Index));\r\n  } finally {\r\n    libh3._free(h3Index);\r\n  }\r\n}\r\n\r\n/**\r\n * Whether the input is a valid unidirectional edge\r\n * @static\r\n * @param  {H3IndexInput} edgeIndex H3 index of the edge\r\n * @return {boolean}           Whether the index is valid\r\n */\r\nfunction isValidDirectedEdge(edgeIndex) {\r\n  var ref = h3IndexToSplitLong(edgeIndex);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return Boolean(H3.isValidDirectedEdge(lower, upper));\r\n}\r\n\r\n/**\r\n * Get the [origin, destination] pair represented by a unidirectional edge\r\n * @static\r\n * @param  {H3IndexInput} edgeIndex H3 index of the edge\r\n * @return {H3Index[]}         [origin, destination] pair as H3 indexes\r\n * @throws {H3Error}           If the input is invalid\r\n */\r\nfunction directedEdgeToCells(edgeIndex) {\r\n  var ref = h3IndexToSplitLong(edgeIndex);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var count = 2;\r\n  var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.directedEdgeToCells(lower, upper, hexagons));\r\n    return readArrayOfH3Indexes(hexagons, count);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all of the unidirectional edges with the given H3 index as the origin (i.e. an edge to\r\n * every neighbor)\r\n * @static\r\n * @param  {H3IndexInput} h3Index   H3 index of the origin hexagon\r\n * @return {H3Index[]}         List of unidirectional edges\r\n * @throws {H3Error}           If the input is invalid\r\n */\r\nfunction originToDirectedEdges(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var count = 6;\r\n  var edges = libh3._calloc(count, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.originToDirectedEdges(lower, upper, edges));\r\n    return readArrayOfH3Indexes(edges, count);\r\n  } finally {\r\n    libh3._free(edges);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the vertices of a given edge as an array of [lat, lng] points. Note that for edges that\r\n * cross the edge of an icosahedron face, this may return 3 coordinates.\r\n * @static\r\n * @param  {H3IndexInput} edgeIndex        H3 index of the edge\r\n * @param {boolean} [formatAsGeoJson] Whether to provide GeoJSON output: [lng, lat]\r\n * @return {CoordPair[]}              Array of geo coordinate pairs\r\n * @throws {H3Error}                  If the input is invalid\r\n */\r\nfunction directedEdgeToBoundary(edgeIndex, formatAsGeoJson) {\r\n  var cellBoundary = libh3._malloc(SZ_CELLBOUNDARY);\r\n  var ref = h3IndexToSplitLong(edgeIndex);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  try {\r\n    throwIfError(H3.directedEdgeToBoundary(lower, upper, cellBoundary));\r\n    return readCellBoundary(cellBoundary, formatAsGeoJson);\r\n  } finally {\r\n    libh3._free(cellBoundary);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the grid distance between two hex indexes. This function may fail\r\n * to find the distance between two indexes if they are very far apart or\r\n * on opposite sides of a pentagon.\r\n * @static\r\n * @param  {H3IndexInput} origin      Origin hexagon index\r\n * @param  {H3IndexInput} destination Destination hexagon index\r\n * @return {number}          Distance between hexagons\r\n * @throws {H3Error}         If input is invalid or the distance could not be calculated\r\n */\r\nfunction gridDistance(origin, destination) {\r\n  var ref = h3IndexToSplitLong(origin);\r\n  var oLower = ref[0];\r\n  var oUpper = ref[1];\r\n  var ref$1 = h3IndexToSplitLong(destination);\r\n  var dLower = ref$1[0];\r\n  var dUpper = ref$1[1];\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.gridDistance(oLower, oUpper, dLower, dUpper, countPtr));\r\n    return readInt64AsDoubleFromPointer(countPtr);\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Given two H3 indexes, return the line of indexes between them (inclusive).\r\n *\r\n * This function may fail to find the line between two indexes, for\r\n * example if they are very far apart. It may also fail when finding\r\n * distances for indexes on opposite sides of a pentagon.\r\n *\r\n * Notes:\r\n *\r\n *  - The specific output of this function should not be considered stable\r\n *    across library versions. The only guarantees the library provides are\r\n *    that the line length will be `h3Distance(start, end) + 1` and that\r\n *    every index in the line will be a neighbor of the preceding index.\r\n *  - Lines are drawn in grid space, and may not correspond exactly to either\r\n *    Cartesian lines or great arcs.\r\n *\r\n * @static\r\n * @param  {H3IndexInput} origin      Origin hexagon index\r\n * @param  {H3IndexInput} destination Destination hexagon index\r\n * @return {H3Index[]}           H3 indexes connecting origin and destination\r\n * @throws {H3Error}             If input is invalid or the line cannot be calculated\r\n */\r\nfunction gridPathCells(origin, destination) {\r\n  var ref = h3IndexToSplitLong(origin);\r\n  var oLower = ref[0];\r\n  var oUpper = ref[1];\r\n  var ref$1 = h3IndexToSplitLong(destination);\r\n  var dLower = ref$1[0];\r\n  var dUpper = ref$1[1];\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    throwIfError(H3.gridPathCellsSize(oLower, oUpper, dLower, dUpper, countPtr));\r\n    var count = validateArrayLength(readInt64AsDoubleFromPointer(countPtr));\r\n    var hexagons = libh3._calloc(count, SZ_H3INDEX);\r\n    try {\r\n      H3.gridPathCells(oLower, oUpper, dLower, dUpper, hexagons);\r\n      return readArrayOfH3Indexes(hexagons, count);\r\n    } finally {\r\n      libh3._free(hexagons);\r\n    }\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\nvar LOCAL_IJ_DEFAULT_MODE = 0;\r\n\r\n/**\r\n * Produces IJ coordinates for an H3 index anchored by an origin.\r\n *\r\n * - The coordinate space used by this function may have deleted\r\n * regions or warping due to pentagonal distortion.\r\n * - Coordinates are only comparable if they come from the same\r\n * origin index.\r\n * - Failure may occur if the index is too far away from the origin\r\n * or if the index is on the other side of a pentagon.\r\n * - This function is experimental, and its output is not guaranteed\r\n * to be compatible across different versions of H3.\r\n * @static\r\n * @param  {H3IndexInput} origin      Origin H3 index\r\n * @param  {H3IndexInput} destination H3 index for which to find relative coordinates\r\n * @return {CoordIJ}             Coordinates as an `{i, j}` pair\r\n * @throws {H3Error}             If the IJ coordinates cannot be calculated\r\n */\r\nfunction cellToLocalIj(origin, destination) {\r\n  var ij = libh3._malloc(SZ_COORDIJ);\r\n  try {\r\n    throwIfError(H3.cellToLocalIj.apply(H3, h3IndexToSplitLong(origin).concat( h3IndexToSplitLong(destination), [LOCAL_IJ_DEFAULT_MODE], [ij] )));\r\n    return readCoordIJ(ij);\r\n  } finally {\r\n    libh3._free(ij);\r\n  }\r\n}\r\n\r\n/**\r\n * Produces an H3 index for IJ coordinates anchored by an origin.\r\n *\r\n * - The coordinate space used by this function may have deleted\r\n * regions or warping due to pentagonal distortion.\r\n * - Coordinates are only comparable if they come from the same\r\n * origin index.\r\n * - Failure may occur if the index is too far away from the origin\r\n * or if the index is on the other side of a pentagon.\r\n * - This function is experimental, and its output is not guaranteed\r\n * to be compatible across different versions of H3.\r\n * @static\r\n * @param  {H3IndexInput} origin     Origin H3 index\r\n * @param  {CoordIJ} coords     Coordinates as an `{i, j}` pair\r\n * @return {H3Index}            H3 index at the relative coordinates\r\n * @throws {H3Error}            If the H3 index cannot be calculated\r\n */\r\nfunction localIjToCell(origin, coords) {\r\n  // Validate input coords\r\n  if (!coords || typeof coords.i !== 'number' || typeof coords.j !== 'number') {\r\n    throw new Error('Coordinates must be provided as an {i, j} object');\r\n  }\r\n  // Allocate memory for the CoordIJ struct and an H3 index to hold the return value\r\n  var ij = libh3._malloc(SZ_COORDIJ);\r\n  var out = libh3._malloc(SZ_H3INDEX);\r\n  storeCoordIJ(ij, coords);\r\n  try {\r\n    throwIfError(H3.localIjToCell.apply(H3, h3IndexToSplitLong(origin).concat( [ij], [LOCAL_IJ_DEFAULT_MODE], [out] )));\r\n    return validateH3Index(readH3IndexFromPointer(out));\r\n  } finally {\r\n    libh3._free(ij);\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public API functions: Distance/area utilities\r\n\r\n/**\r\n * Great circle distance between two geo points. This is not specific to H3,\r\n * but is implemented in the library and provided here as a convenience.\r\n * @static\r\n * @param  {number[]} latLng1 Origin coordinate as [lat, lng]\r\n * @param  {number[]} latLng2 Destination coordinate as [lat, lng]\r\n * @param  {string}   unit    Distance unit (either UNITS.m, UNITS.km, or UNITS.rads)\r\n * @return {number}           Great circle distance\r\n * @throws {H3Error}          If the unit is invalid\r\n */\r\nfunction greatCircleDistance(latLng1, latLng2, unit) {\r\n  var coord1 = storeLatLng(latLng1[0], latLng1[1]);\r\n  var coord2 = storeLatLng(latLng2[0], latLng2[1]);\r\n  var result;\r\n  switch (unit) {\r\n    case UNITS.m:\r\n      result = H3.greatCircleDistanceM(coord1, coord2);\r\n      break;\r\n    case UNITS.km:\r\n      result = H3.greatCircleDistanceKm(coord1, coord2);\r\n      break;\r\n    case UNITS.rads:\r\n      result = H3.greatCircleDistanceRads(coord1, coord2);\r\n      break;\r\n    default:\r\n      result = null;\r\n  }\r\n  libh3._free(coord1);\r\n  libh3._free(coord2);\r\n  if (result === null) {\r\n    throw JSBindingError(E_UNKNOWN_UNIT, unit);\r\n  }\r\n  return result;\r\n}\r\n\r\n/**\r\n * Exact area of a given cell\r\n * @static\r\n * @param  {H3IndexInput} h3Index  H3 index of the hexagon to measure\r\n * @param  {string}  unit     Distance unit (either UNITS.m2, UNITS.km2, or UNITS.rads2)\r\n * @return {number}           Cell area\r\n * @throws {H3Error}          If the input is invalid\r\n */\r\nfunction cellArea(h3Index, unit) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var out = libh3._malloc(SZ_DBL);\r\n  try {\r\n    switch (unit) {\r\n      case UNITS.m2:\r\n        throwIfError(H3.cellAreaM2(lower, upper, out));\r\n        break;\r\n      case UNITS.km2:\r\n        throwIfError(H3.cellAreaKm2(lower, upper, out));\r\n        break;\r\n      case UNITS.rads2:\r\n        throwIfError(H3.cellAreaRads2(lower, upper, out));\r\n        break;\r\n      default:\r\n        throw JSBindingError(E_UNKNOWN_UNIT, unit);\r\n    }\r\n    return readDoubleFromPointer(out);\r\n  } finally {\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n/**\r\n * Calculate length of a given unidirectional edge\r\n * @static\r\n * @param  {H3IndexInput} edge     H3 index of the edge to measure\r\n * @param  {string}  unit     Distance unit (either UNITS.m, UNITS.km, or UNITS.rads)\r\n * @return {number}           Cell area\r\n * @throws {H3Error}          If the input is invalid\r\n */\r\nfunction edgeLength(edge, unit) {\r\n  var ref = h3IndexToSplitLong(edge);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var out = libh3._malloc(SZ_DBL);\r\n  try {\r\n    switch (unit) {\r\n      case UNITS.m:\r\n        throwIfError(H3.edgeLengthM(lower, upper, out));\r\n        break;\r\n      case UNITS.km:\r\n        throwIfError(H3.edgeLengthKm(lower, upper, out));\r\n        break;\r\n      case UNITS.rads:\r\n        throwIfError(H3.edgeLengthRads(lower, upper, out));\r\n        break;\r\n      default:\r\n        throw JSBindingError(E_UNKNOWN_UNIT, unit);\r\n    }\r\n    return readDoubleFromPointer(out);\r\n  } finally {\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n/**\r\n * Average hexagon area at a given resolution\r\n * @static\r\n * @param  {number} res  Hexagon resolution\r\n * @param  {string} unit Area unit (either UNITS.m2, UNITS.km2, or UNITS.rads2)\r\n * @return {number}      Average area\r\n * @throws {H3Error}     If the input is invalid\r\n */\r\nfunction getHexagonAreaAvg(res, unit) {\r\n  validateRes(res);\r\n  var out = libh3._malloc(SZ_DBL);\r\n  try {\r\n    switch (unit) {\r\n      case UNITS.m2:\r\n        throwIfError(H3.getHexagonAreaAvgM2(res, out));\r\n        break;\r\n      case UNITS.km2:\r\n        throwIfError(H3.getHexagonAreaAvgKm2(res, out));\r\n        break;\r\n      default:\r\n        throw JSBindingError(E_UNKNOWN_UNIT, unit);\r\n    }\r\n    return readDoubleFromPointer(out);\r\n  } finally {\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n/**\r\n * Average hexagon edge length at a given resolution\r\n * @static\r\n * @param  {number} res  Hexagon resolution\r\n * @param  {string} unit Distance unit (either UNITS.m, UNITS.km, or UNITS.rads)\r\n * @return {number}      Average edge length\r\n * @throws {H3Error}     If the input is invalid\r\n */\r\nfunction getHexagonEdgeLengthAvg(res, unit) {\r\n  validateRes(res);\r\n  var out = libh3._malloc(SZ_DBL);\r\n  try {\r\n    switch (unit) {\r\n      case UNITS.m:\r\n        throwIfError(H3.getHexagonEdgeLengthAvgM(res, out));\r\n        break;\r\n      case UNITS.km:\r\n        throwIfError(H3.getHexagonEdgeLengthAvgKm(res, out));\r\n        break;\r\n      default:\r\n        throw JSBindingError(E_UNKNOWN_UNIT, unit);\r\n    }\r\n    return readDoubleFromPointer(out);\r\n  } finally {\r\n    libh3._free(out);\r\n  }\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public API functions: Vertex mode\r\n\r\n/**\r\n * Find the index for a vertex of a cell.\r\n * @static\r\n * @param {H3IndexInput} h3Index     Cell to find the vertex for\r\n * @param {number} vertexNum         Number (index) of the vertex to calculate\r\n * @return {H3Index}     Vertex index\r\n * @throws {H3Error}     If the input is invalid\r\n */\r\nfunction cellToVertex(h3Index, vertexNum) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var vertexIndex = libh3._malloc(SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellToVertex(lower, upper, vertexNum, vertexIndex));\r\n    return validateH3Index(readH3IndexFromPointer(vertexIndex));\r\n  } finally {\r\n    libh3._free(vertexIndex);\r\n  }\r\n}\r\n\r\n/**\r\n * Find the indexes for all vertexes of a cell.\r\n * @static\r\n * @param {H3IndexInput} h3Index     Cell to find all vertexes for\r\n * @return {H3Index[]}   All vertex indexes of this cell\r\n * @throws {H3Error}     If the input is invalid\r\n */\r\nfunction cellToVertexes(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  var maxNumVertexes = 6;\r\n  var vertexIndexes = libh3._calloc(maxNumVertexes, SZ_H3INDEX);\r\n  try {\r\n    throwIfError(H3.cellToVertexes(lower, upper, vertexIndexes));\r\n    return readArrayOfH3Indexes(vertexIndexes, maxNumVertexes);\r\n  } finally {\r\n    libh3._free(vertexIndexes);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the lat, lng of a given vertex\r\n * @static\r\n * @param {H3IndexInput} h3Index A vertex index\r\n * @returns {CoordPair}          Latitude, longitude coordinates of the vertex\r\n * @throws {H3Error}             If the input is invalid\r\n */\r\nfunction vertexToLatLng(h3Index) {\r\n  var latlng = libh3._malloc(SZ_LATLNG);\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  try {\r\n    throwIfError(H3.vertexToLatLng(lower, upper, latlng));\r\n    return readLatLng(latlng);\r\n  } finally {\r\n    libh3._free(latlng);\r\n  }\r\n}\r\n\r\n/**\r\n * Returns true if the input is a valid vertex index.\r\n * @static\r\n * @param {H3IndexInput} h3Index An index to test for being a vertex index\r\n * @returns {boolean} True if the index represents a vertex\r\n */\r\nfunction isValidVertex(h3Index) {\r\n  var ref = h3IndexToSplitLong(h3Index);\r\n  var lower = ref[0];\r\n  var upper = ref[1];\r\n  return Boolean(H3.isValidVertex(lower, upper));\r\n}\r\n\r\n// ----------------------------------------------------------------------------\r\n// Public informational utilities\r\n\r\n/**\r\n * The total count of hexagons in the world at a given resolution. Note that above\r\n * resolution 8 the exact count cannot be represented in a JavaScript 32-bit number,\r\n * so consumers should use caution when applying further operations to the output.\r\n * @static\r\n * @param  {number} res  Hexagon resolution\r\n * @return {number}      Count\r\n * @throws {H3Error}     If the resolution is invalid\r\n */\r\nfunction getNumCells(res) {\r\n  validateRes(res);\r\n  var countPtr = libh3._malloc(SZ_INT64);\r\n  try {\r\n    // Get number as a long value\r\n    throwIfError(H3.getNumCells(res, countPtr));\r\n    return readInt64AsDoubleFromPointer(countPtr);\r\n  } finally {\r\n    libh3._free(countPtr);\r\n  }\r\n}\r\n\r\n/**\r\n * Get all H3 indexes at resolution 0. As every index at every resolution > 0 is\r\n * the descendant of a res 0 index, this can be used with h3ToChildren to iterate\r\n * over H3 indexes at any resolution.\r\n * @static\r\n * @return {H3Index[]}  All H3 indexes at res 0\r\n */\r\nfunction getRes0Cells() {\r\n  var count = H3.res0CellCount();\r\n  var hexagons = libh3._malloc(SZ_H3INDEX * count);\r\n  try {\r\n    throwIfError(H3.getRes0Cells(hexagons));\r\n    return readArrayOfH3Indexes(hexagons, count);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Get the twelve pentagon indexes at a given resolution.\r\n * @static\r\n * @param  {number} res  Hexagon resolution\r\n * @return {H3Index[]}   All H3 pentagon indexes at res\r\n * @throws {H3Error}     If the resolution is invalid\r\n */\r\nfunction getPentagons(res) {\r\n  validateRes(res);\r\n  var count = H3.pentagonCount();\r\n  var hexagons = libh3._malloc(SZ_H3INDEX * count);\r\n  try {\r\n    throwIfError(H3.getPentagons(res, hexagons));\r\n    return readArrayOfH3Indexes(hexagons, count);\r\n  } finally {\r\n    libh3._free(hexagons);\r\n  }\r\n}\r\n\r\n/**\r\n * Convert degrees to radians\r\n * @static\r\n * @param  {number} deg Value in degrees\r\n * @return {number}     Value in radians\r\n */\r\nfunction degsToRads(deg) {\r\n  return deg * Math.PI / 180;\r\n}\r\n\r\n/**\r\n * Convert radians to degrees\r\n * @static\r\n * @param  {number} rad Value in radians\r\n * @return {number}     Value in degrees\r\n */\r\nfunction radsToDegs(rad) {\r\n  return rad * 180 / Math.PI;\r\n}\r\n\r\nexport { UNITS, POLYGON_TO_CELLS_FLAGS, h3IndexToSplitLong, splitLongToH3Index, isValidCell, isPentagon, isResClassIII, getBaseCellNumber, getIcosahedronFaces, getResolution, latLngToCell, cellToLatLng, cellToBoundary, cellToParent, cellToChildren, cellToChildrenSize, cellToCenterChild, cellToChildPos, childPosToCell, gridDisk, gridDiskDistances, gridRing, gridRingUnsafe, polygonToCells, polygonToCellsExperimental, cellsToMultiPolygon, compactCells, uncompactCells, areNeighborCells, cellsToDirectedEdge, getDirectedEdgeOrigin, getDirectedEdgeDestination, isValidDirectedEdge, directedEdgeToCells, originToDirectedEdges, directedEdgeToBoundary, gridDistance, gridPathCells, cellToLocalIj, localIjToCell, greatCircleDistance, cellArea, edgeLength, getHexagonAreaAvg, getHexagonEdgeLengthAvg, cellToVertex, cellToVertexes, vertexToLatLng, isValidVertex, getNumCells, getRes0Cells, getPentagons, degsToRads, radsToDegs };\r\n//# sourceMappingURL=h3-js.es.js.map\r\n","modules/coach-world/vendor/maplibre-gl.css":".maplibregl-map{font:12px/20px Helvetica Neue,Arial,Helvetica,sans-serif;overflow:hidden;position:relative;-webkit-tap-highlight-color:rgb(0 0 0/0)}.maplibregl-canvas{left:0;position:absolute;top:0}.maplibregl-map:fullscreen{height:100%;width:100%}.maplibregl-ctrl-group button.maplibregl-ctrl-compass{touch-action:none}.maplibregl-canvas-container.maplibregl-interactive,.maplibregl-ctrl-group button.maplibregl-ctrl-compass{cursor:grab;-webkit-user-select:none;-moz-user-select:none;user-select:none}.maplibregl-canvas-container.maplibregl-interactive.maplibregl-track-pointer{cursor:pointer}.maplibregl-canvas-container.maplibregl-interactive:active,.maplibregl-ctrl-group button.maplibregl-ctrl-compass:active{cursor:grabbing}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-canvas-container.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:pinch-zoom}.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan,.maplibregl-canvas-container.maplibregl-touch-zoom-rotate.maplibregl-touch-drag-pan .maplibregl-canvas{touch-action:none}.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures,.maplibregl-canvas-container.maplibregl-touch-drag-pan.maplibregl-cooperative-gestures .maplibregl-canvas{touch-action:pan-x pan-y}.maplibregl-ctrl-bottom-left,.maplibregl-ctrl-bottom-right,.maplibregl-ctrl-top-left,.maplibregl-ctrl-top-right{pointer-events:none;position:absolute;z-index:2}.maplibregl-ctrl-top-left{left:0;top:0}.maplibregl-ctrl-top-right{right:0;top:0}.maplibregl-ctrl-bottom-left{bottom:0;left:0}.maplibregl-ctrl-bottom-right{bottom:0;right:0}.maplibregl-ctrl{clear:both;pointer-events:auto;transform:translate(0)}.maplibregl-ctrl-top-left .maplibregl-ctrl{float:left;margin:10px 0 0 10px}.maplibregl-ctrl-top-right .maplibregl-ctrl{float:right;margin:10px 10px 0 0}.maplibregl-ctrl-bottom-left .maplibregl-ctrl{float:left;margin:0 0 10px 10px}.maplibregl-ctrl-bottom-right .maplibregl-ctrl{float:right;margin:0 10px 10px 0}.maplibregl-ctrl-group{background:#fff;border-radius:4px}.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px rgba(0,0,0,.1)}@media (forced-colors:active){.maplibregl-ctrl-group:not(:empty){box-shadow:0 0 0 2px ButtonText}}.maplibregl-ctrl-group button{background-color:transparent;border:0;box-sizing:border-box;cursor:pointer;display:block;height:29px;outline:none;padding:0;width:29px}.maplibregl-ctrl-group button+button{border-top:1px solid #ddd}.maplibregl-ctrl button .maplibregl-ctrl-icon{background-position:50%;background-repeat:no-repeat;display:block;height:100%;width:100%}@media (forced-colors:active){.maplibregl-ctrl-icon{background-color:transparent}.maplibregl-ctrl-group button+button{border-top:1px solid ButtonText}}.maplibregl-ctrl button::-moz-focus-inner{border:0;padding:0}.maplibregl-ctrl-attrib-button:focus,.maplibregl-ctrl-group button:focus{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl button:disabled{cursor:not-allowed}.maplibregl-ctrl button:disabled .maplibregl-ctrl-icon{opacity:.25}@media (hover:hover){.maplibregl-ctrl button:not(:disabled):hover{background-color:rgb(0 0 0/5%)}}.maplibregl-ctrl button:not(:disabled):active{background-color:rgb(0 0 0/5%)}.maplibregl-ctrl-group button:focus:focus-visible{box-shadow:0 0 2px 2px #0096ff}.maplibregl-ctrl-group button:focus:not(:focus-visible){box-shadow:none}.maplibregl-ctrl-group button:focus:first-child{border-radius:4px 4px 0 0}.maplibregl-ctrl-group button:focus:last-child{border-radius:0 0 4px 4px}.maplibregl-ctrl-group button:focus:only-child{border-radius:inherit}.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5'/%3E%3C/svg%3E\")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5'/%3E%3C/svg%3E\")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-zoom-out .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M10 13c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h9c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-zoom-in .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M14.5 8.5c-.75 0-1.5.75-1.5 1.5v3h-3c-.75 0-1.5.75-1.5 1.5S9.25 16 10 16h3v3c0 .75.75 1.5 1.5 1.5S16 19.75 16 19v-3h3c.75 0 1.5-.75 1.5-1.5S19.75 13 19 13h-3v-3c0-.75-.75-1.5-1.5-1.5'/%3E%3C/svg%3E\")}}.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1z'/%3E%3C/svg%3E\")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1z'/%3E%3C/svg%3E\")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-fullscreen .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M24 16v5.5c0 1.75-.75 2.5-2.5 2.5H16v-1l3-1.5-4-5.5 1-1 5.5 4 1.5-3zM6 16l1.5 3 5.5-4 1 1-4 5.5 3 1.5v1H7.5C5.75 24 5 23.25 5 21.5V16zm7-11v1l-3 1.5 4 5.5-1 1-5.5-4L6 13H5V7.5C5 5.75 5.75 5 7.5 5zm11 2.5c0-1.75-.75-2.5-2.5-2.5H16v1l3 1.5-4 5.5 1 1 5.5-4 1.5 3h1z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-shrink .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='M18.5 16c-1.75 0-2.5.75-2.5 2.5V24h1l1.5-3 5.5 4 1-1-4-5.5 3-1.5v-1zM13 18.5c0-1.75-.75-2.5-2.5-2.5H5v1l3 1.5L4 24l1 1 5.5-4 1.5 3h1zm3-8c0 1.75.75 2.5 2.5 2.5H24v-1l-3-1.5L25 5l-1-1-5.5 4L17 5h-1zM10.5 13c1.75 0 2.5-.75 2.5-2.5V5h-1l-1.5 3L5 4 4 5l4 5.5L5 12v1z'/%3E%3C/svg%3E\")}}.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 29 29'%3E%3Cpath d='m10.5 14 4-8 4 8z'/%3E%3Cpath fill='%23ccc' d='m10.5 16 4 8 4-8z'/%3E%3C/svg%3E\")}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 29 29'%3E%3Cpath d='m10.5 14 4-8 4 8z'/%3E%3Cpath fill='%23ccc' d='m10.5 16 4 8 4-8z'/%3E%3C/svg%3E\")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-compass .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 29 29'%3E%3Cpath d='m10.5 14 4-8 4 8z'/%3E%3Cpath fill='%23ccc' d='m10.5 16 4 8 4-8z'/%3E%3C/svg%3E\")}}.maplibregl-ctrl button.maplibregl-ctrl-globe .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' fill='none' stroke='%23333' viewBox='0 0 22 22'%3E%3Ccircle cx='11' cy='11' r='8.5'/%3E%3Cpath d='M17.5 11c0 4.819-3.02 8.5-6.5 8.5S4.5 15.819 4.5 11 7.52 2.5 11 2.5s6.5 3.681 6.5 8.5Z'/%3E%3Cpath d='M13.5 11c0 2.447-.331 4.64-.853 6.206-.262.785-.562 1.384-.872 1.777-.314.399-.58.517-.775.517s-.461-.118-.775-.517c-.31-.393-.61-.992-.872-1.777C8.831 15.64 8.5 13.446 8.5 11s.331-4.64.853-6.206c.262-.785.562-1.384.872-1.777.314-.399.58-.517.775-.517s.461.118.775.517c.31.393.61.992.872 1.777.522 1.565.853 3.76.853 6.206Z'/%3E%3Cpath d='M11 7.5c-1.909 0-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3 1.3 0 0 1-.224-.138q.07-.058.224-.138c.299-.151.763-.302 1.379-.434C7.378 5.666 9.091 5.5 11 5.5s3.622.166 4.845.428c.616.132 1.08.283 1.379.434.105.053.177.1.224.138q-.07.058-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428ZM4.486 6.436ZM11 16.5c-1.909 0-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3 1.3 0 0 1-.224-.138 1.3 1.3 0 0 1 .224-.138c.299-.151.763-.302 1.379-.434C7.378 14.666 9.091 14.5 11 14.5s3.622.166 4.845.428c.616.132 1.08.283 1.379.434.105.053.177.1.224.138a1.3 1.3 0 0 1-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm-6.514-1.064ZM11 12.5c-2.46 0-4.672-.222-6.255-.574-.796-.177-1.406-.38-1.805-.59a1.5 1.5 0 0 1-.39-.272.3.3 0 0 1-.047-.064.3.3 0 0 1 .048-.064c.066-.073.189-.167.389-.272.399-.21 1.009-.413 1.805-.59C6.328 9.722 8.54 9.5 11 9.5s4.672.222 6.256.574c.795.177 1.405.38 1.804.59.2.105.323.2.39.272a.3.3 0 0 1 .047.064.3.3 0 0 1-.048.064 1.4 1.4 0 0 1-.389.272c-.399.21-1.009.413-1.804.59-1.584.352-3.796.574-6.256.574Zm-8.501-1.51v.002zm0 .018v.002zm17.002.002v-.002zm0-.018v-.002z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-globe-enabled .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' fill='none' stroke='%2333b5e5' viewBox='0 0 22 22'%3E%3Ccircle cx='11' cy='11' r='8.5'/%3E%3Cpath d='M17.5 11c0 4.819-3.02 8.5-6.5 8.5S4.5 15.819 4.5 11 7.52 2.5 11 2.5s6.5 3.681 6.5 8.5Z'/%3E%3Cpath d='M13.5 11c0 2.447-.331 4.64-.853 6.206-.262.785-.562 1.384-.872 1.777-.314.399-.58.517-.775.517s-.461-.118-.775-.517c-.31-.393-.61-.992-.872-1.777C8.831 15.64 8.5 13.446 8.5 11s.331-4.64.853-6.206c.262-.785.562-1.384.872-1.777.314-.399.58-.517.775-.517s.461.118.775.517c.31.393.61.992.872 1.777.522 1.565.853 3.76.853 6.206Z'/%3E%3Cpath d='M11 7.5c-1.909 0-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3 1.3 0 0 1-.224-.138q.07-.058.224-.138c.299-.151.763-.302 1.379-.434C7.378 5.666 9.091 5.5 11 5.5s3.622.166 4.845.428c.616.132 1.08.283 1.379.434.105.053.177.1.224.138q-.07.058-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428ZM4.486 6.436ZM11 16.5c-1.909 0-3.622-.166-4.845-.428-.616-.132-1.08-.283-1.379-.434a1.3 1.3 0 0 1-.224-.138 1.3 1.3 0 0 1 .224-.138c.299-.151.763-.302 1.379-.434C7.378 14.666 9.091 14.5 11 14.5s3.622.166 4.845.428c.616.132 1.08.283 1.379.434.105.053.177.1.224.138a1.3 1.3 0 0 1-.224.138c-.299.151-.763.302-1.379.434-1.223.262-2.936.428-4.845.428Zm-6.514-1.064ZM11 12.5c-2.46 0-4.672-.222-6.255-.574-.796-.177-1.406-.38-1.805-.59a1.5 1.5 0 0 1-.39-.272.3.3 0 0 1-.047-.064.3.3 0 0 1 .048-.064c.066-.073.189-.167.389-.272.399-.21 1.009-.413 1.805-.59C6.328 9.722 8.54 9.5 11 9.5s4.672.222 6.256.574c.795.177 1.405.38 1.804.59.2.105.323.2.39.272a.3.3 0 0 1 .047.064.3.3 0 0 1-.048.064 1.4 1.4 0 0 1-.389.272c-.399.21-1.009.413-1.804.59-1.584.352-3.796.574-6.256.574Zm-8.501-1.51v.002zm0 .018v.002zm17.002.002v-.002zm0-.018v-.002z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-terrain .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' fill='%23333' viewBox='0 0 22 22'%3E%3Cpath d='m1.754 13.406 4.453-4.851 3.09 3.09 3.281 3.277.969-.969-3.309-3.312 3.844-4.121 6.148 6.886h1.082v-.855l-7.207-8.07-4.84 5.187L6.169 6.57l-5.48 5.965v.871ZM.688 16.844h20.625v1.375H.688Zm0 0'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-terrain-enabled .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='22' height='22' fill='%2333b5e5' viewBox='0 0 22 22'%3E%3Cpath d='m1.754 13.406 4.453-4.851 3.09 3.09 3.281 3.277.969-.969-3.309-3.312 3.844-4.121 6.148 6.886h1.082v-.855l-7.207-8.07-4.84 5.187L6.169 6.57l-5.48 5.965v.871ZM.688 16.844h20.625v1.375H.688Zm0 0'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23333' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23aaa' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3Cpath fill='red' d='m14 5 1 1-9 9-1-1z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%2333b5e5' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active-error .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23e58978' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%2333b5e5' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23e54e33' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-waiting .maplibregl-ctrl-icon{animation:maplibregl-spin 2s linear infinite}@media (forced-colors:active){.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23fff' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23999' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3Cpath fill='red' d='m14 5 1 1-9 9-1-1z'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%2333b5e5' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-active-error .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23e58978' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%2333b5e5' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate.maplibregl-ctrl-geolocate-background-error .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23e54e33' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3C/svg%3E\")}}@media (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl button.maplibregl-ctrl-geolocate .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3C/svg%3E\")}.maplibregl-ctrl button.maplibregl-ctrl-geolocate:disabled .maplibregl-ctrl-icon{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='29' height='29' fill='%23666' viewBox='0 0 20 20'%3E%3Cpath d='M10 4C9 4 9 5 9 5v.1A5 5 0 0 0 5.1 9H5s-1 0-1 1 1 1 1 1h.1A5 5 0 0 0 9 14.9v.1s0 1 1 1 1-1 1-1v-.1a5 5 0 0 0 3.9-3.9h.1s1 0 1-1-1-1-1-1h-.1A5 5 0 0 0 11 5.1V5s0-1-1-1m0 2.5a3.5 3.5 0 1 1 0 7 3.5 3.5 0 1 1 0-7'/%3E%3Ccircle cx='10' cy='10' r='2'/%3E%3Cpath fill='red' d='m14 5 1 1-9 9-1-1z'/%3E%3C/svg%3E\")}}@keyframes maplibregl-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}a.maplibregl-ctrl-logo{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='23' fill='none'%3E%3Cpath fill='%23000' fill-opacity='.4' fill-rule='evenodd' d='M17.408 16.796h-1.827l2.501-12.095h.198l3.324 6.533.988 2.19.988-2.19 3.258-6.533h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.929 5.644h-.098l-2.914-5.644-.757-1.71-.345 1.71zm1.958-3.42-.726 3.663a1.255 1.255 0 0 1-1.232 1.011h-1.827a1.255 1.255 0 0 1-1.229-1.509l2.501-12.095a1.255 1.255 0 0 1 1.23-1.001h.197a1.25 1.25 0 0 1 1.12.685l3.19 6.273 3.125-6.263a1.25 1.25 0 0 1 1.123-.695h.181a1.255 1.255 0 0 1 1.227.991l1.443 6.71a5 5 0 0 1 .314-.787l.009-.016a4.6 4.6 0 0 1 1.777-1.887c.782-.46 1.668-.667 2.611-.667a4.6 4.6 0 0 1 1.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255 1.255 0 0 1 1.212.925 1.255 1.255 0 0 1 1.212-.925h1.711c.284 0 .545.094.755.252.613-.3 1.312-.45 2.075-.45 1.356 0 2.557.445 3.482 1.4q.47.48.763 1.064V4.701a1.255 1.255 0 0 1 1.255-1.255h1.86A1.255 1.255 0 0 1 54.44 4.7v9.194h2.217c.19 0 .37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42 2.42 0 0 1-.682-1.71c0-.665.267-1.253.735-1.7a2.45 2.45 0 0 1 1.722-.674 2.43 2.43 0 0 1 1.705.675q.318.302.504.683V4.7a1.255 1.255 0 0 1 1.255-1.255h1.744A1.255 1.255 0 0 1 65.812 4.7v3.335a4.8 4.8 0 0 1 1.526-.246c.938 0 1.817.214 2.59.69a4.47 4.47 0 0 1 1.67 1.743v-.98a1.255 1.255 0 0 1 1.256-1.256h1.777c.233 0 .451.064.639.174a3.4 3.4 0 0 1 1.567-.372c.346 0 .861.02 1.285.232a1.25 1.25 0 0 1 .689 1.004 4.7 4.7 0 0 1 .853-.588c.795-.44 1.675-.647 2.61-.647 1.385 0 2.65.39 3.525 1.396.836.938 1.168 2.173 1.168 3.528q-.001.515-.056 1.051a1.255 1.255 0 0 1-.947 1.09l.408.952a1.255 1.255 0 0 1-.477 1.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06 0-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8 5.8 0 0 1-.548-2.512q0-.429.053-.843a1.3 1.3 0 0 1-.333-.086l-.166-.004c-.223 0-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255 1.255 0 0 1-1.256 1.256h-1.777a1.255 1.255 0 0 1-1.256-1.256V15.69l-.032.057a4.8 4.8 0 0 1-1.86 1.833 5.04 5.04 0 0 1-2.484.634 4.5 4.5 0 0 1-1.935-.424 1.25 1.25 0 0 1-.764.258h-1.71a1.255 1.255 0 0 1-1.256-1.255V7.687a2.4 2.4 0 0 1-.428.625c.253.23.412.561.412.93v7.553a1.255 1.255 0 0 1-1.256 1.255h-1.843a1.25 1.25 0 0 1-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255 1.255 0 0 1-1.256-1.255v-1.251l-.061.117a4.7 4.7 0 0 1-1.782 1.884 4.77 4.77 0 0 1-2.485.67 5.6 5.6 0 0 1-1.485-.188l.009 2.764a1.255 1.255 0 0 1-1.255 1.259h-1.729a1.255 1.255 0 0 1-1.255-1.255v-3.537a1.255 1.255 0 0 1-1.167.793h-1.679a1.25 1.25 0 0 1-.77-.263 4.5 4.5 0 0 1-1.945.429c-.885 0-1.724-.21-2.495-.632l-.017-.01a5 5 0 0 1-1.081-.836 1.255 1.255 0 0 1-1.254 1.312h-1.81a1.255 1.255 0 0 1-1.228-.99l-.782-3.625-2.044 3.939a1.25 1.25 0 0 1-1.115.676h-.098a1.25 1.25 0 0 1-1.116-.68l-2.061-3.994zM35.92 16.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033 1.332h1.678V9.242h-1.694l-.033 1.267q-.133-.329-.526-.658l-.032-.028a3.2 3.2 0 0 0-.668-.428l-.27-.12a3.3 3.3 0 0 0-1.235-.23q-1.136-.001-1.974.493a3.36 3.36 0 0 0-1.3 1.382q-.445.89-.444 2.074 0 1.2.51 2.107a3.8 3.8 0 0 0 1.382 1.381 3.9 3.9 0 0 0 1.893.477q.795 0 1.455-.33zm-2.789-5.38q-.576.675-.575 1.762 0 1.102.559 1.794.576.675 1.645.675a2.25 2.25 0 0 0 .934-.19 2.2 2.2 0 0 0 .468-.29l.178-.161a2.2 2.2 0 0 0 .397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2 2.2 0 0 0-.633-.709l-.13-.086-.047-.028a2.1 2.1 0 0 0-1.073-.285q-1.052 0-1.629.692zm2.316 2.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96 0 0 0-.353-.389.85.85 0 0 0-.464-.127c-.4 0-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945 0 .506.122.801.27.99.097.11.266.224.68.224.303 0 .504-.09.687-.269zm7.545 1.705a2.6 2.6 0 0 0 .331.423q.319.33.755.548l.173.074q.65.255 1.49.255 1.02 0 1.844-.493a3.45 3.45 0 0 0 1.316-1.4q.493-.904.493-2.089 0-1.909-.988-2.913-.988-1.02-2.584-1.02-.898 0-1.575.347a3 3 0 0 0-.415.262l-.199.166a3.4 3.4 0 0 0-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296 1.119.297 1.07 0 1.645-.675.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.435 0-.835.16a2 2 0 0 0-.284.136 2 2 0 0 0-.363.254 2.2 2.2 0 0 0-.46.569l-.082.162a2.6 2.6 0 0 0-.213 1.072v.115q0 .707.296 1.267l.135.211zm.964-.818a1.1 1.1 0 0 0 .367.385.94.94 0 0 0 .476.118c.423 0 .59-.117.687-.23.159-.194.28-.478.28-.95 0-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1 1 0 0 0-.503.135l-.012.007a.86.86 0 0 0-.335.343c-.073.133-.132.324-.132.614v.115a1.4 1.4 0 0 0 .14.66zm15.7-6.222q.347-.346.346-.856a1.05 1.05 0 0 0-.345-.79 1.18 1.18 0 0 0-.84-.329q-.51 0-.855.33a1.05 1.05 0 0 0-.346.79q0 .51.346.855.345.346.856.346.51 0 .839-.346zm4.337 9.314.033-1.332q.191.403.59.747l.098.081a4 4 0 0 0 .316.224l.223.122a3.2 3.2 0 0 0 1.44.322 3.8 3.8 0 0 0 1.875-.477 3.5 3.5 0 0 0 1.382-1.366q.527-.89.526-2.09 0-1.184-.444-2.073a3.24 3.24 0 0 0-1.283-1.399q-.823-.51-1.942-.51a3.5 3.5 0 0 0-1.527.344l-.086.043-.165.09a3 3 0 0 0-.33.214q-.432.315-.656.707a2 2 0 0 0-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5 2.5 0 0 0 .566.7q.117.098.245.18l.144.08a2.1 2.1 0 0 0 .975.232q1.07 0 1.645-.675.576-.69.576-1.778 0-1.102-.576-1.777-.56-.691-1.645-.692a2.2 2.2 0 0 0-1.015.235q-.22.113-.415.282l-.15.142a2.1 2.1 0 0 0-.42.594q-.223.479-.223 1.1v.115q0 .705.293 1.26zm2.616-.293c.157-.191.28-.479.28-.967 0-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87 0 0 0-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0 .285.057.499.144.669a1.1 1.1 0 0 0 .367.405c.137.082.28.123.455.123.423 0 .59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493 0 .642.099l.247-1.794q-.196-.099-.717-.099a2.3 2.3 0 0 0-.545.063 2 2 0 0 0-.411.148 2.2 2.2 0 0 0-.4.249 2.5 2.5 0 0 0-.485.499 2.7 2.7 0 0 0-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5 1.5 0 0 1 .466-.636 2.5 2.5 0 0 1 .399-.253 2 2 0 0 1 .224-.099zm9.784 2.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46 3.46 0 0 0-1.4 1.382q-.493.906-.493 2.106 0 1.07.428 1.975.428.89 1.332 1.432.906.526 2.255.526.973 0 1.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954 0-1.497-.444a1.6 1.6 0 0 1-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1 1 0 0 0-.156-.176q-.46-.428-1.316-.428-.986 0-1.494.604-.379.45-.494 1.234zm-27.053 2.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z'/%3E%3Cpath fill='%23fff' d='m19.63 11.151-.757-1.71-.345 1.71-1.12 5.644h-1.827L18.083 4.7h.197l3.325 6.533.988 2.19.988-2.19L26.839 4.7h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.93 5.644h-.098l-2.913-5.644zm14.836 5.81q-1.02 0-1.893-.478a3.8 3.8 0 0 1-1.381-1.382q-.51-.906-.51-2.106 0-1.185.444-2.074a3.36 3.36 0 0 1 1.3-1.382q.839-.494 1.974-.494a3.3 3.3 0 0 1 1.234.231 3.3 3.3 0 0 1 .97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02 1.053a3.17 3.17 0 0 1-1.662.444zm.296-1.482q.938 0 1.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2 2.2 0 0 0-.807-.872 2.1 2.1 0 0 0-1.119-.313q-1.053 0-1.629.692-.575.675-.575 1.76 0 1.103.559 1.795.577.675 1.645.675zm6.521-6.237h1.711v1.4q.906-1.597 2.83-1.597 1.596 0 2.584 1.02.988 1.005.988 2.914 0 1.185-.493 2.09a3.46 3.46 0 0 1-1.316 1.399 3.5 3.5 0 0 1-1.844.493q-.954 0-1.662-.329a2.67 2.67 0 0 1-1.086-.97l.017 5.134h-1.728zm4.048 6.22q1.07 0 1.645-.674.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.592 0-1.12.296-.51.28-.822.823-.296.527-.296 1.234v.115q0 .708.296 1.267.313.543.823.855.51.296 1.119.297z'/%3E%3Cpath fill='%23e1e3e9' d='M51.325 4.7h1.86v10.45h3.473v1.646h-5.333zm7.12 4.542h1.843v7.553h-1.843zm.905-1.415a1.16 1.16 0 0 1-.856-.346 1.17 1.17 0 0 1-.346-.856 1.05 1.05 0 0 1 .346-.79q.346-.329.856-.329.494 0 .839.33a1.05 1.05 0 0 1 .345.79 1.16 1.16 0 0 1-.345.855q-.33.346-.84.346zm7.875 9.133a3.17 3.17 0 0 1-1.662-.444q-.723-.46-1.004-1.053l-.033 1.332h-1.71V4.701h1.743v4.657l-.082 1.283q.279-.658 1.086-1.119a3.5 3.5 0 0 1 1.778-.477q1.119 0 1.942.51a3.24 3.24 0 0 1 1.283 1.4q.445.888.444 2.072 0 1.201-.526 2.09a3.5 3.5 0 0 1-1.382 1.366 3.8 3.8 0 0 1-1.876.477zm-.296-1.481q1.069 0 1.645-.675.577-.69.577-1.778 0-1.102-.577-1.776-.56-.691-1.645-.692a2.12 2.12 0 0 0-1.58.659q-.642.641-.642 1.694v.115q0 .71.296 1.267a2.4 2.4 0 0 0 .807.872 2.1 2.1 0 0 0 1.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14 2.14 0 0 1 1.349-.46q.527 0 .724.098l-.247 1.794q-.149-.099-.642-.099-.774 0-1.416.494-.626.493-.626 1.58v3.883h-1.777V9.242zm9.534 7.718q-1.35 0-2.255-.526-.904-.543-1.332-1.432a4.6 4.6 0 0 1-.428-1.975q0-1.2.493-2.106a3.46 3.46 0 0 1 1.4-1.382q.889-.495 2.007-.494 1.744 0 2.584.97.855.956.856 2.7 0 .444-.05.92h-5.43q.18 1.005.708 1.45.542.443 1.497.443.79 0 1.3-.131a4 4 0 0 0 .938-.362l.542 1.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728 0-1.991 1.86z'/%3E%3Cpath d='M5.074 15.948a.484.657 0 0 0-.486.659v1.84a.484.657 0 0 0 .486.659h4.101a.484.657 0 0 0 .486-.659v-1.84a.484.657 0 0 0-.486-.659zm3.56 1.16H5.617v.838h3.017z' style='fill:%23fff;fill-rule:evenodd;stroke-width:1.03600001'/%3E%3Cg style='stroke-width:1.12603545'%3E%3Cpath d='M-9.408-1.416c-3.833-.025-7.056 2.912-7.08 6.615-.02 3.08 1.653 4.832 3.107 6.268.903.892 1.721 1.74 2.32 2.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87 1.87 0 0 0-.362 1.121l-.011 1.877c-.003.402.104.787.347 1.125.244.338.688.653 1.23.656l4.142.028c.542.003.99-.306 1.238-.641a1.87 1.87 0 0 0 .363-1.121l.012-1.875a1.87 1.87 0 0 0-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145 1.425-1.983 2.348-2.87 1.473-1.414 3.18-3.149 3.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006 1.1v.002c3.274.02 5.92 2.532 5.9 5.6-.017 2.706-1.39 4.026-2.863 5.44-1.034.994-2.118 2.033-2.814 3.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34 0 0 1-.226.084.34.34 0 0 1-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067 2.7-5.545 5.975-5.523m-.02 2.826c-1.62-.01-2.944 1.315-2.955 2.96-.01 1.646 1.295 2.988 2.916 2.999h.002c1.621.01 2.943-1.316 2.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005 1.1c1.017.006 1.829.83 1.822 1.89s-.83 1.874-1.848 1.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874 1.848-1.868m-2.155 11.857 4.14.025c.271.002.49.305.487.676l-.013 1.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668' style='color:%23000;font-style:normal;font-variant:normal;font-weight:400;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:%23000;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:evenodd;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:%23000;solid-opacity:1;vector-effect:none;fill:%23000;fill-opacity:.4;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;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' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-9.415-.316C-12.69-.338-15.37 2.14-15.39 5.207c-.017 2.716 1.326 4.041 2.78 5.477 1.013 1 2.081 2.055 2.78 3.67l.092.076a.34.34 0 0 0 .225.086.34.34 0 0 0 .227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6 1.78-2.64 2.814-3.634 1.473-1.414 2.847-2.733 2.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057 8.784c1.621.011 2.944-1.315 2.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945 1.315-2.955 2.96s1.295 2.989 2.916 3' style='clip-rule:evenodd;fill:%23e1e3e9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-11.594 15.465c-.27-.002-.492.297-.494.668l-.012 1.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z' style='clip-rule:evenodd;fill:%23fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3C/g%3E%3C/svg%3E\");background-repeat:no-repeat;cursor:pointer;display:block;height:23px;margin:0 0 -4px -4px;overflow:hidden;width:88px}a.maplibregl-ctrl-logo.maplibregl-compact{width:14px}@media (forced-colors:active){a.maplibregl-ctrl-logo{background-color:transparent;background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='23' fill='none'%3E%3Cpath fill='%23000' fill-opacity='.4' fill-rule='evenodd' d='M17.408 16.796h-1.827l2.501-12.095h.198l3.324 6.533.988 2.19.988-2.19 3.258-6.533h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.929 5.644h-.098l-2.914-5.644-.757-1.71-.345 1.71zm1.958-3.42-.726 3.663a1.255 1.255 0 0 1-1.232 1.011h-1.827a1.255 1.255 0 0 1-1.229-1.509l2.501-12.095a1.255 1.255 0 0 1 1.23-1.001h.197a1.25 1.25 0 0 1 1.12.685l3.19 6.273 3.125-6.263a1.25 1.25 0 0 1 1.123-.695h.181a1.255 1.255 0 0 1 1.227.991l1.443 6.71a5 5 0 0 1 .314-.787l.009-.016a4.6 4.6 0 0 1 1.777-1.887c.782-.46 1.668-.667 2.611-.667a4.6 4.6 0 0 1 1.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255 1.255 0 0 1 1.212.925 1.255 1.255 0 0 1 1.212-.925h1.711c.284 0 .545.094.755.252.613-.3 1.312-.45 2.075-.45 1.356 0 2.557.445 3.482 1.4q.47.48.763 1.064V4.701a1.255 1.255 0 0 1 1.255-1.255h1.86A1.255 1.255 0 0 1 54.44 4.7v9.194h2.217c.19 0 .37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42 2.42 0 0 1-.682-1.71c0-.665.267-1.253.735-1.7a2.45 2.45 0 0 1 1.722-.674 2.43 2.43 0 0 1 1.705.675q.318.302.504.683V4.7a1.255 1.255 0 0 1 1.255-1.255h1.744A1.255 1.255 0 0 1 65.812 4.7v3.335a4.8 4.8 0 0 1 1.526-.246c.938 0 1.817.214 2.59.69a4.47 4.47 0 0 1 1.67 1.743v-.98a1.255 1.255 0 0 1 1.256-1.256h1.777c.233 0 .451.064.639.174a3.4 3.4 0 0 1 1.567-.372c.346 0 .861.02 1.285.232a1.25 1.25 0 0 1 .689 1.004 4.7 4.7 0 0 1 .853-.588c.795-.44 1.675-.647 2.61-.647 1.385 0 2.65.39 3.525 1.396.836.938 1.168 2.173 1.168 3.528q-.001.515-.056 1.051a1.255 1.255 0 0 1-.947 1.09l.408.952a1.255 1.255 0 0 1-.477 1.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06 0-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8 5.8 0 0 1-.548-2.512q0-.429.053-.843a1.3 1.3 0 0 1-.333-.086l-.166-.004c-.223 0-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255 1.255 0 0 1-1.256 1.256h-1.777a1.255 1.255 0 0 1-1.256-1.256V15.69l-.032.057a4.8 4.8 0 0 1-1.86 1.833 5.04 5.04 0 0 1-2.484.634 4.5 4.5 0 0 1-1.935-.424 1.25 1.25 0 0 1-.764.258h-1.71a1.255 1.255 0 0 1-1.256-1.255V7.687a2.4 2.4 0 0 1-.428.625c.253.23.412.561.412.93v7.553a1.255 1.255 0 0 1-1.256 1.255h-1.843a1.25 1.25 0 0 1-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255 1.255 0 0 1-1.256-1.255v-1.251l-.061.117a4.7 4.7 0 0 1-1.782 1.884 4.77 4.77 0 0 1-2.485.67 5.6 5.6 0 0 1-1.485-.188l.009 2.764a1.255 1.255 0 0 1-1.255 1.259h-1.729a1.255 1.255 0 0 1-1.255-1.255v-3.537a1.255 1.255 0 0 1-1.167.793h-1.679a1.25 1.25 0 0 1-.77-.263 4.5 4.5 0 0 1-1.945.429c-.885 0-1.724-.21-2.495-.632l-.017-.01a5 5 0 0 1-1.081-.836 1.255 1.255 0 0 1-1.254 1.312h-1.81a1.255 1.255 0 0 1-1.228-.99l-.782-3.625-2.044 3.939a1.25 1.25 0 0 1-1.115.676h-.098a1.25 1.25 0 0 1-1.116-.68l-2.061-3.994zM35.92 16.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033 1.332h1.678V9.242h-1.694l-.033 1.267q-.133-.329-.526-.658l-.032-.028a3.2 3.2 0 0 0-.668-.428l-.27-.12a3.3 3.3 0 0 0-1.235-.23q-1.136-.001-1.974.493a3.36 3.36 0 0 0-1.3 1.382q-.445.89-.444 2.074 0 1.2.51 2.107a3.8 3.8 0 0 0 1.382 1.381 3.9 3.9 0 0 0 1.893.477q.795 0 1.455-.33zm-2.789-5.38q-.576.675-.575 1.762 0 1.102.559 1.794.576.675 1.645.675a2.25 2.25 0 0 0 .934-.19 2.2 2.2 0 0 0 .468-.29l.178-.161a2.2 2.2 0 0 0 .397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2 2.2 0 0 0-.633-.709l-.13-.086-.047-.028a2.1 2.1 0 0 0-1.073-.285q-1.052 0-1.629.692zm2.316 2.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96 0 0 0-.353-.389.85.85 0 0 0-.464-.127c-.4 0-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945 0 .506.122.801.27.99.097.11.266.224.68.224.303 0 .504-.09.687-.269zm7.545 1.705a2.6 2.6 0 0 0 .331.423q.319.33.755.548l.173.074q.65.255 1.49.255 1.02 0 1.844-.493a3.45 3.45 0 0 0 1.316-1.4q.493-.904.493-2.089 0-1.909-.988-2.913-.988-1.02-2.584-1.02-.898 0-1.575.347a3 3 0 0 0-.415.262l-.199.166a3.4 3.4 0 0 0-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296 1.119.297 1.07 0 1.645-.675.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.435 0-.835.16a2 2 0 0 0-.284.136 2 2 0 0 0-.363.254 2.2 2.2 0 0 0-.46.569l-.082.162a2.6 2.6 0 0 0-.213 1.072v.115q0 .707.296 1.267l.135.211zm.964-.818a1.1 1.1 0 0 0 .367.385.94.94 0 0 0 .476.118c.423 0 .59-.117.687-.23.159-.194.28-.478.28-.95 0-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1 1 0 0 0-.503.135l-.012.007a.86.86 0 0 0-.335.343c-.073.133-.132.324-.132.614v.115a1.4 1.4 0 0 0 .14.66zm15.7-6.222q.347-.346.346-.856a1.05 1.05 0 0 0-.345-.79 1.18 1.18 0 0 0-.84-.329q-.51 0-.855.33a1.05 1.05 0 0 0-.346.79q0 .51.346.855.345.346.856.346.51 0 .839-.346zm4.337 9.314.033-1.332q.191.403.59.747l.098.081a4 4 0 0 0 .316.224l.223.122a3.2 3.2 0 0 0 1.44.322 3.8 3.8 0 0 0 1.875-.477 3.5 3.5 0 0 0 1.382-1.366q.527-.89.526-2.09 0-1.184-.444-2.073a3.24 3.24 0 0 0-1.283-1.399q-.823-.51-1.942-.51a3.5 3.5 0 0 0-1.527.344l-.086.043-.165.09a3 3 0 0 0-.33.214q-.432.315-.656.707a2 2 0 0 0-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5 2.5 0 0 0 .566.7q.117.098.245.18l.144.08a2.1 2.1 0 0 0 .975.232q1.07 0 1.645-.675.576-.69.576-1.778 0-1.102-.576-1.777-.56-.691-1.645-.692a2.2 2.2 0 0 0-1.015.235q-.22.113-.415.282l-.15.142a2.1 2.1 0 0 0-.42.594q-.223.479-.223 1.1v.115q0 .705.293 1.26zm2.616-.293c.157-.191.28-.479.28-.967 0-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87 0 0 0-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0 .285.057.499.144.669a1.1 1.1 0 0 0 .367.405c.137.082.28.123.455.123.423 0 .59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493 0 .642.099l.247-1.794q-.196-.099-.717-.099a2.3 2.3 0 0 0-.545.063 2 2 0 0 0-.411.148 2.2 2.2 0 0 0-.4.249 2.5 2.5 0 0 0-.485.499 2.7 2.7 0 0 0-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5 1.5 0 0 1 .466-.636 2.5 2.5 0 0 1 .399-.253 2 2 0 0 1 .224-.099zm9.784 2.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46 3.46 0 0 0-1.4 1.382q-.493.906-.493 2.106 0 1.07.428 1.975.428.89 1.332 1.432.906.526 2.255.526.973 0 1.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954 0-1.497-.444a1.6 1.6 0 0 1-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1 1 0 0 0-.156-.176q-.46-.428-1.316-.428-.986 0-1.494.604-.379.45-.494 1.234zm-27.053 2.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z'/%3E%3Cpath fill='%23fff' d='m19.63 11.151-.757-1.71-.345 1.71-1.12 5.644h-1.827L18.083 4.7h.197l3.325 6.533.988 2.19.988-2.19L26.839 4.7h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.93 5.644h-.098l-2.913-5.644zm14.836 5.81q-1.02 0-1.893-.478a3.8 3.8 0 0 1-1.381-1.382q-.51-.906-.51-2.106 0-1.185.444-2.074a3.36 3.36 0 0 1 1.3-1.382q.839-.494 1.974-.494a3.3 3.3 0 0 1 1.234.231 3.3 3.3 0 0 1 .97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02 1.053a3.17 3.17 0 0 1-1.662.444zm.296-1.482q.938 0 1.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2 2.2 0 0 0-.807-.872 2.1 2.1 0 0 0-1.119-.313q-1.053 0-1.629.692-.575.675-.575 1.76 0 1.103.559 1.795.577.675 1.645.675zm6.521-6.237h1.711v1.4q.906-1.597 2.83-1.597 1.596 0 2.584 1.02.988 1.005.988 2.914 0 1.185-.493 2.09a3.46 3.46 0 0 1-1.316 1.399 3.5 3.5 0 0 1-1.844.493q-.954 0-1.662-.329a2.67 2.67 0 0 1-1.086-.97l.017 5.134h-1.728zm4.048 6.22q1.07 0 1.645-.674.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.592 0-1.12.296-.51.28-.822.823-.296.527-.296 1.234v.115q0 .708.296 1.267.313.543.823.855.51.296 1.119.297z'/%3E%3Cpath fill='%23e1e3e9' d='M51.325 4.7h1.86v10.45h3.473v1.646h-5.333zm7.12 4.542h1.843v7.553h-1.843zm.905-1.415a1.16 1.16 0 0 1-.856-.346 1.17 1.17 0 0 1-.346-.856 1.05 1.05 0 0 1 .346-.79q.346-.329.856-.329.494 0 .839.33a1.05 1.05 0 0 1 .345.79 1.16 1.16 0 0 1-.345.855q-.33.346-.84.346zm7.875 9.133a3.17 3.17 0 0 1-1.662-.444q-.723-.46-1.004-1.053l-.033 1.332h-1.71V4.701h1.743v4.657l-.082 1.283q.279-.658 1.086-1.119a3.5 3.5 0 0 1 1.778-.477q1.119 0 1.942.51a3.24 3.24 0 0 1 1.283 1.4q.445.888.444 2.072 0 1.201-.526 2.09a3.5 3.5 0 0 1-1.382 1.366 3.8 3.8 0 0 1-1.876.477zm-.296-1.481q1.069 0 1.645-.675.577-.69.577-1.778 0-1.102-.577-1.776-.56-.691-1.645-.692a2.12 2.12 0 0 0-1.58.659q-.642.641-.642 1.694v.115q0 .71.296 1.267a2.4 2.4 0 0 0 .807.872 2.1 2.1 0 0 0 1.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14 2.14 0 0 1 1.349-.46q.527 0 .724.098l-.247 1.794q-.149-.099-.642-.099-.774 0-1.416.494-.626.493-.626 1.58v3.883h-1.777V9.242zm9.534 7.718q-1.35 0-2.255-.526-.904-.543-1.332-1.432a4.6 4.6 0 0 1-.428-1.975q0-1.2.493-2.106a3.46 3.46 0 0 1 1.4-1.382q.889-.495 2.007-.494 1.744 0 2.584.97.855.956.856 2.7 0 .444-.05.92h-5.43q.18 1.005.708 1.45.542.443 1.497.443.79 0 1.3-.131a4 4 0 0 0 .938-.362l.542 1.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728 0-1.991 1.86z'/%3E%3Cpath d='M5.074 15.948a.484.657 0 0 0-.486.659v1.84a.484.657 0 0 0 .486.659h4.101a.484.657 0 0 0 .486-.659v-1.84a.484.657 0 0 0-.486-.659zm3.56 1.16H5.617v.838h3.017z' style='fill:%23fff;fill-rule:evenodd;stroke-width:1.03600001'/%3E%3Cg style='stroke-width:1.12603545'%3E%3Cpath d='M-9.408-1.416c-3.833-.025-7.056 2.912-7.08 6.615-.02 3.08 1.653 4.832 3.107 6.268.903.892 1.721 1.74 2.32 2.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87 1.87 0 0 0-.362 1.121l-.011 1.877c-.003.402.104.787.347 1.125.244.338.688.653 1.23.656l4.142.028c.542.003.99-.306 1.238-.641a1.87 1.87 0 0 0 .363-1.121l.012-1.875a1.87 1.87 0 0 0-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145 1.425-1.983 2.348-2.87 1.473-1.414 3.18-3.149 3.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006 1.1v.002c3.274.02 5.92 2.532 5.9 5.6-.017 2.706-1.39 4.026-2.863 5.44-1.034.994-2.118 2.033-2.814 3.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34 0 0 1-.226.084.34.34 0 0 1-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067 2.7-5.545 5.975-5.523m-.02 2.826c-1.62-.01-2.944 1.315-2.955 2.96-.01 1.646 1.295 2.988 2.916 2.999h.002c1.621.01 2.943-1.316 2.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005 1.1c1.017.006 1.829.83 1.822 1.89s-.83 1.874-1.848 1.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874 1.848-1.868m-2.155 11.857 4.14.025c.271.002.49.305.487.676l-.013 1.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668' style='color:%23000;font-style:normal;font-variant:normal;font-weight:400;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:%23000;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:evenodd;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:%23000;solid-opacity:1;vector-effect:none;fill:%23000;fill-opacity:.4;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;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' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-9.415-.316C-12.69-.338-15.37 2.14-15.39 5.207c-.017 2.716 1.326 4.041 2.78 5.477 1.013 1 2.081 2.055 2.78 3.67l.092.076a.34.34 0 0 0 .225.086.34.34 0 0 0 .227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6 1.78-2.64 2.814-3.634 1.473-1.414 2.847-2.733 2.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057 8.784c1.621.011 2.944-1.315 2.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945 1.315-2.955 2.96s1.295 2.989 2.916 3' style='clip-rule:evenodd;fill:%23e1e3e9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-11.594 15.465c-.27-.002-.492.297-.494.668l-.012 1.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z' style='clip-rule:evenodd;fill:%23fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3C/g%3E%3C/svg%3E\")}}@media (forced-colors:active) and (prefers-color-scheme:light){a.maplibregl-ctrl-logo{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='88' height='23' fill='none'%3E%3Cpath fill='%23000' fill-opacity='.4' fill-rule='evenodd' d='M17.408 16.796h-1.827l2.501-12.095h.198l3.324 6.533.988 2.19.988-2.19 3.258-6.533h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.929 5.644h-.098l-2.914-5.644-.757-1.71-.345 1.71zm1.958-3.42-.726 3.663a1.255 1.255 0 0 1-1.232 1.011h-1.827a1.255 1.255 0 0 1-1.229-1.509l2.501-12.095a1.255 1.255 0 0 1 1.23-1.001h.197a1.25 1.25 0 0 1 1.12.685l3.19 6.273 3.125-6.263a1.25 1.25 0 0 1 1.123-.695h.181a1.255 1.255 0 0 1 1.227.991l1.443 6.71a5 5 0 0 1 .314-.787l.009-.016a4.6 4.6 0 0 1 1.777-1.887c.782-.46 1.668-.667 2.611-.667a4.6 4.6 0 0 1 1.7.32l.306.134c.21-.16.474-.256.759-.256h1.694a1.255 1.255 0 0 1 1.212.925 1.255 1.255 0 0 1 1.212-.925h1.711c.284 0 .545.094.755.252.613-.3 1.312-.45 2.075-.45 1.356 0 2.557.445 3.482 1.4q.47.48.763 1.064V4.701a1.255 1.255 0 0 1 1.255-1.255h1.86A1.255 1.255 0 0 1 54.44 4.7v9.194h2.217c.19 0 .37.043.532.118v-4.77c0-.356.147-.678.385-.906a2.42 2.42 0 0 1-.682-1.71c0-.665.267-1.253.735-1.7a2.45 2.45 0 0 1 1.722-.674 2.43 2.43 0 0 1 1.705.675q.318.302.504.683V4.7a1.255 1.255 0 0 1 1.255-1.255h1.744A1.255 1.255 0 0 1 65.812 4.7v3.335a4.8 4.8 0 0 1 1.526-.246c.938 0 1.817.214 2.59.69a4.47 4.47 0 0 1 1.67 1.743v-.98a1.255 1.255 0 0 1 1.256-1.256h1.777c.233 0 .451.064.639.174a3.4 3.4 0 0 1 1.567-.372c.346 0 .861.02 1.285.232a1.25 1.25 0 0 1 .689 1.004 4.7 4.7 0 0 1 .853-.588c.795-.44 1.675-.647 2.61-.647 1.385 0 2.65.39 3.525 1.396.836.938 1.168 2.173 1.168 3.528q-.001.515-.056 1.051a1.255 1.255 0 0 1-.947 1.09l.408.952a1.255 1.255 0 0 1-.477 1.552c-.418.268-.92.463-1.458.612-.613.171-1.304.244-2.049.244-1.06 0-2.043-.207-2.886-.698l-.015-.008c-.798-.48-1.419-1.135-1.818-1.963l-.004-.008a5.8 5.8 0 0 1-.548-2.512q0-.429.053-.843a1.3 1.3 0 0 1-.333-.086l-.166-.004c-.223 0-.426.062-.643.228-.03.024-.142.139-.142.59v3.883a1.255 1.255 0 0 1-1.256 1.256h-1.777a1.255 1.255 0 0 1-1.256-1.256V15.69l-.032.057a4.8 4.8 0 0 1-1.86 1.833 5.04 5.04 0 0 1-2.484.634 4.5 4.5 0 0 1-1.935-.424 1.25 1.25 0 0 1-.764.258h-1.71a1.255 1.255 0 0 1-1.256-1.255V7.687a2.4 2.4 0 0 1-.428.625c.253.23.412.561.412.93v7.553a1.255 1.255 0 0 1-1.256 1.255h-1.843a1.25 1.25 0 0 1-.894-.373c-.228.23-.544.373-.894.373H51.32a1.255 1.255 0 0 1-1.256-1.255v-1.251l-.061.117a4.7 4.7 0 0 1-1.782 1.884 4.77 4.77 0 0 1-2.485.67 5.6 5.6 0 0 1-1.485-.188l.009 2.764a1.255 1.255 0 0 1-1.255 1.259h-1.729a1.255 1.255 0 0 1-1.255-1.255v-3.537a1.255 1.255 0 0 1-1.167.793h-1.679a1.25 1.25 0 0 1-.77-.263 4.5 4.5 0 0 1-1.945.429c-.885 0-1.724-.21-2.495-.632l-.017-.01a5 5 0 0 1-1.081-.836 1.255 1.255 0 0 1-1.254 1.312h-1.81a1.255 1.255 0 0 1-1.228-.99l-.782-3.625-2.044 3.939a1.25 1.25 0 0 1-1.115.676h-.098a1.25 1.25 0 0 1-1.116-.68l-2.061-3.994zM35.92 16.63l.207-.114.223-.15q.493-.356.735-.785l.061-.118.033 1.332h1.678V9.242h-1.694l-.033 1.267q-.133-.329-.526-.658l-.032-.028a3.2 3.2 0 0 0-.668-.428l-.27-.12a3.3 3.3 0 0 0-1.235-.23q-1.136-.001-1.974.493a3.36 3.36 0 0 0-1.3 1.382q-.445.89-.444 2.074 0 1.2.51 2.107a3.8 3.8 0 0 0 1.382 1.381 3.9 3.9 0 0 0 1.893.477q.795 0 1.455-.33zm-2.789-5.38q-.576.675-.575 1.762 0 1.102.559 1.794.576.675 1.645.675a2.25 2.25 0 0 0 .934-.19 2.2 2.2 0 0 0 .468-.29l.178-.161a2.2 2.2 0 0 0 .397-.561q.244-.5.244-1.15v-.115q0-.708-.296-1.267l-.043-.077a2.2 2.2 0 0 0-.633-.709l-.13-.086-.047-.028a2.1 2.1 0 0 0-1.073-.285q-1.052 0-1.629.692zm2.316 2.706c.163-.17.28-.407.28-.83v-.114c0-.292-.06-.508-.15-.68a.96.96 0 0 0-.353-.389.85.85 0 0 0-.464-.127c-.4 0-.56.114-.664.239l-.01.012c-.148.174-.275.45-.275.945 0 .506.122.801.27.99.097.11.266.224.68.224.303 0 .504-.09.687-.269zm7.545 1.705a2.6 2.6 0 0 0 .331.423q.319.33.755.548l.173.074q.65.255 1.49.255 1.02 0 1.844-.493a3.45 3.45 0 0 0 1.316-1.4q.493-.904.493-2.089 0-1.909-.988-2.913-.988-1.02-2.584-1.02-.898 0-1.575.347a3 3 0 0 0-.415.262l-.199.166a3.4 3.4 0 0 0-.64.82V9.242h-1.712v11.553h1.729l-.017-5.134zm.53-1.138q.206.29.48.5l.155.11.053.034q.51.296 1.119.297 1.07 0 1.645-.675.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.435 0-.835.16a2 2 0 0 0-.284.136 2 2 0 0 0-.363.254 2.2 2.2 0 0 0-.46.569l-.082.162a2.6 2.6 0 0 0-.213 1.072v.115q0 .707.296 1.267l.135.211zm.964-.818a1.1 1.1 0 0 0 .367.385.94.94 0 0 0 .476.118c.423 0 .59-.117.687-.23.159-.194.28-.478.28-.95 0-.53-.133-.8-.266-.952l-.021-.025c-.078-.094-.231-.221-.68-.221a1 1 0 0 0-.503.135l-.012.007a.86.86 0 0 0-.335.343c-.073.133-.132.324-.132.614v.115a1.4 1.4 0 0 0 .14.66zm15.7-6.222q.347-.346.346-.856a1.05 1.05 0 0 0-.345-.79 1.18 1.18 0 0 0-.84-.329q-.51 0-.855.33a1.05 1.05 0 0 0-.346.79q0 .51.346.855.345.346.856.346.51 0 .839-.346zm4.337 9.314.033-1.332q.191.403.59.747l.098.081a4 4 0 0 0 .316.224l.223.122a3.2 3.2 0 0 0 1.44.322 3.8 3.8 0 0 0 1.875-.477 3.5 3.5 0 0 0 1.382-1.366q.527-.89.526-2.09 0-1.184-.444-2.073a3.24 3.24 0 0 0-1.283-1.399q-.823-.51-1.942-.51a3.5 3.5 0 0 0-1.527.344l-.086.043-.165.09a3 3 0 0 0-.33.214q-.432.315-.656.707a2 2 0 0 0-.099.198l.082-1.283V4.701h-1.744v12.095zm.473-2.509a2.5 2.5 0 0 0 .566.7q.117.098.245.18l.144.08a2.1 2.1 0 0 0 .975.232q1.07 0 1.645-.675.576-.69.576-1.778 0-1.102-.576-1.777-.56-.691-1.645-.692a2.2 2.2 0 0 0-1.015.235q-.22.113-.415.282l-.15.142a2.1 2.1 0 0 0-.42.594q-.223.479-.223 1.1v.115q0 .705.293 1.26zm2.616-.293c.157-.191.28-.479.28-.967 0-.51-.13-.79-.276-.961l-.021-.026c-.082-.1-.232-.225-.67-.225a.87.87 0 0 0-.681.279l-.012.011c-.154.155-.274.38-.274.807v.115c0 .285.057.499.144.669a1.1 1.1 0 0 0 .367.405c.137.082.28.123.455.123.423 0 .59-.118.686-.23zm8.266-3.013q.345-.13.724-.14l.069-.002q.493 0 .642.099l.247-1.794q-.196-.099-.717-.099a2.3 2.3 0 0 0-.545.063 2 2 0 0 0-.411.148 2.2 2.2 0 0 0-.4.249 2.5 2.5 0 0 0-.485.499 2.7 2.7 0 0 0-.32.581l-.05.137v-1.48h-1.778v7.553h1.777v-3.884q0-.546.159-.943a1.5 1.5 0 0 1 .466-.636 2.5 2.5 0 0 1 .399-.253 2 2 0 0 1 .224-.099zm9.784 2.656.05-.922q0-1.743-.856-2.698-.838-.97-2.584-.97-1.119-.001-2.007.493a3.46 3.46 0 0 0-1.4 1.382q-.493.906-.493 2.106 0 1.07.428 1.975.428.89 1.332 1.432.906.526 2.255.526.973 0 1.668-.185l.044-.012.135-.04q.613-.184.984-.421l-.542-1.267q-.3.162-.642.274l-.297.087q-.51.131-1.3.131-.954 0-1.497-.444a1.6 1.6 0 0 1-.192-.193q-.366-.44-.512-1.234l-.004-.021zm-5.427-1.256-.003.022h3.752v-.138q-.011-.727-.288-1.118a1 1 0 0 0-.156-.176q-.46-.428-1.316-.428-.986 0-1.494.604-.379.45-.494 1.234zm-27.053 2.77V4.7h-1.86v12.095h5.333V15.15zm7.103-5.908v7.553h-1.843V9.242h1.843z'/%3E%3Cpath fill='%23fff' d='m19.63 11.151-.757-1.71-.345 1.71-1.12 5.644h-1.827L18.083 4.7h.197l3.325 6.533.988 2.19.988-2.19L26.839 4.7h.181l2.6 12.095h-1.81l-1.218-5.644-.362-1.71-.658 1.71-2.93 5.644h-.098l-2.913-5.644zm14.836 5.81q-1.02 0-1.893-.478a3.8 3.8 0 0 1-1.381-1.382q-.51-.906-.51-2.106 0-1.185.444-2.074a3.36 3.36 0 0 1 1.3-1.382q.839-.494 1.974-.494a3.3 3.3 0 0 1 1.234.231 3.3 3.3 0 0 1 .97.575q.396.33.527.659l.033-1.267h1.694v7.553H37.18l-.033-1.332q-.279.593-1.02 1.053a3.17 3.17 0 0 1-1.662.444zm.296-1.482q.938 0 1.58-.642.642-.66.642-1.711v-.115q0-.708-.296-1.267a2.2 2.2 0 0 0-.807-.872 2.1 2.1 0 0 0-1.119-.313q-1.053 0-1.629.692-.575.675-.575 1.76 0 1.103.559 1.795.577.675 1.645.675zm6.521-6.237h1.711v1.4q.906-1.597 2.83-1.597 1.596 0 2.584 1.02.988 1.005.988 2.914 0 1.185-.493 2.09a3.46 3.46 0 0 1-1.316 1.399 3.5 3.5 0 0 1-1.844.493q-.954 0-1.662-.329a2.67 2.67 0 0 1-1.086-.97l.017 5.134h-1.728zm4.048 6.22q1.07 0 1.645-.674.577-.69.576-1.762 0-1.119-.576-1.777-.558-.675-1.645-.675-.592 0-1.12.296-.51.28-.822.823-.296.527-.296 1.234v.115q0 .708.296 1.267.313.543.823.855.51.296 1.119.297z'/%3E%3Cpath fill='%23e1e3e9' d='M51.325 4.7h1.86v10.45h3.473v1.646h-5.333zm7.12 4.542h1.843v7.553h-1.843zm.905-1.415a1.16 1.16 0 0 1-.856-.346 1.17 1.17 0 0 1-.346-.856 1.05 1.05 0 0 1 .346-.79q.346-.329.856-.329.494 0 .839.33a1.05 1.05 0 0 1 .345.79 1.16 1.16 0 0 1-.345.855q-.33.346-.84.346zm7.875 9.133a3.17 3.17 0 0 1-1.662-.444q-.723-.46-1.004-1.053l-.033 1.332h-1.71V4.701h1.743v4.657l-.082 1.283q.279-.658 1.086-1.119a3.5 3.5 0 0 1 1.778-.477q1.119 0 1.942.51a3.24 3.24 0 0 1 1.283 1.4q.445.888.444 2.072 0 1.201-.526 2.09a3.5 3.5 0 0 1-1.382 1.366 3.8 3.8 0 0 1-1.876.477zm-.296-1.481q1.069 0 1.645-.675.577-.69.577-1.778 0-1.102-.577-1.776-.56-.691-1.645-.692a2.12 2.12 0 0 0-1.58.659q-.642.641-.642 1.694v.115q0 .71.296 1.267a2.4 2.4 0 0 0 .807.872 2.1 2.1 0 0 0 1.119.313zm5.927-6.237h1.777v1.481q.263-.757.856-1.217a2.14 2.14 0 0 1 1.349-.46q.527 0 .724.098l-.247 1.794q-.149-.099-.642-.099-.774 0-1.416.494-.626.493-.626 1.58v3.883h-1.777V9.242zm9.534 7.718q-1.35 0-2.255-.526-.904-.543-1.332-1.432a4.6 4.6 0 0 1-.428-1.975q0-1.2.493-2.106a3.46 3.46 0 0 1 1.4-1.382q.889-.495 2.007-.494 1.744 0 2.584.97.855.956.856 2.7 0 .444-.05.92h-5.43q.18 1.005.708 1.45.542.443 1.497.443.79 0 1.3-.131a4 4 0 0 0 .938-.362l.542 1.267q-.411.263-1.119.46-.708.198-1.711.197zm1.596-4.558q.016-1.02-.444-1.432-.46-.428-1.316-.428-1.728 0-1.991 1.86z'/%3E%3Cpath d='M5.074 15.948a.484.657 0 0 0-.486.659v1.84a.484.657 0 0 0 .486.659h4.101a.484.657 0 0 0 .486-.659v-1.84a.484.657 0 0 0-.486-.659zm3.56 1.16H5.617v.838h3.017z' style='fill:%23fff;fill-rule:evenodd;stroke-width:1.03600001'/%3E%3Cg style='stroke-width:1.12603545'%3E%3Cpath d='M-9.408-1.416c-3.833-.025-7.056 2.912-7.08 6.615-.02 3.08 1.653 4.832 3.107 6.268.903.892 1.721 1.74 2.32 2.902l-.525-.004c-.543-.003-.992.304-1.24.639a1.87 1.87 0 0 0-.362 1.121l-.011 1.877c-.003.402.104.787.347 1.125.244.338.688.653 1.23.656l4.142.028c.542.003.99-.306 1.238-.641a1.87 1.87 0 0 0 .363-1.121l.012-1.875a1.87 1.87 0 0 0-.348-1.127c-.243-.338-.688-.653-1.23-.656l-.518-.004c.597-1.145 1.425-1.983 2.348-2.87 1.473-1.414 3.18-3.149 3.2-6.226-.016-3.59-2.923-6.684-6.993-6.707m-.006 1.1v.002c3.274.02 5.92 2.532 5.9 5.6-.017 2.706-1.39 4.026-2.863 5.44-1.034.994-2.118 2.033-2.814 3.633-.018.041-.052.055-.075.065q-.013.004-.02.01a.34.34 0 0 1-.226.084.34.34 0 0 1-.224-.086l-.092-.077c-.699-1.615-1.768-2.669-2.781-3.67-1.454-1.435-2.797-2.762-2.78-5.478.02-3.067 2.7-5.545 5.975-5.523m-.02 2.826c-1.62-.01-2.944 1.315-2.955 2.96-.01 1.646 1.295 2.988 2.916 2.999h.002c1.621.01 2.943-1.316 2.953-2.961.011-1.646-1.294-2.988-2.916-2.998m-.005 1.1c1.017.006 1.829.83 1.822 1.89s-.83 1.874-1.848 1.867c-1.018-.006-1.829-.83-1.822-1.89s.83-1.874 1.848-1.868m-2.155 11.857 4.14.025c.271.002.49.305.487.676l-.013 1.875c-.003.37-.224.67-.495.668l-4.14-.025c-.27-.002-.487-.306-.485-.676l.012-1.875c.003-.37.224-.67.494-.668' style='color:%23000;font-style:normal;font-variant:normal;font-weight:400;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:%23000;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:evenodd;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:%23000;solid-opacity:1;vector-effect:none;fill:%23000;fill-opacity:.4;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;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' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-9.415-.316C-12.69-.338-15.37 2.14-15.39 5.207c-.017 2.716 1.326 4.041 2.78 5.477 1.013 1 2.081 2.055 2.78 3.67l.092.076a.34.34 0 0 0 .225.086.34.34 0 0 0 .227-.083l.019-.01c.022-.009.057-.024.074-.064.697-1.6 1.78-2.64 2.814-3.634 1.473-1.414 2.847-2.733 2.864-5.44.02-3.067-2.627-5.58-5.901-5.601m-.057 8.784c1.621.011 2.944-1.315 2.955-2.96.01-1.646-1.295-2.988-2.916-2.999-1.622-.01-2.945 1.315-2.955 2.96s1.295 2.989 2.916 3' style='clip-rule:evenodd;fill:%23e1e3e9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3Cpath d='M-11.594 15.465c-.27-.002-.492.297-.494.668l-.012 1.876c-.003.371.214.673.485.675l4.14.027c.271.002.492-.298.495-.668l.012-1.877c.003-.37-.215-.672-.485-.674z' style='clip-rule:evenodd;fill:%23fff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.47727823;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:.4' transform='translate(15.553 2.85)scale(.88807)'/%3E%3C/g%3E%3C/svg%3E\")}}.maplibregl-ctrl.maplibregl-ctrl-attrib{background-color:hsla(0,0%,100%,.5);margin:0;padding:0 5px}@media screen{.maplibregl-ctrl-attrib.maplibregl-compact{background-color:#fff;border-radius:12px;box-sizing:content-box;color:#000;margin:10px;min-height:20px;padding:2px 24px 2px 0;position:relative}.maplibregl-ctrl-attrib.maplibregl-compact-show{padding:2px 28px 2px 8px;visibility:visible}.maplibregl-ctrl-bottom-left>.maplibregl-ctrl-attrib.maplibregl-compact-show,.maplibregl-ctrl-top-left>.maplibregl-ctrl-attrib.maplibregl-compact-show{border-radius:12px;padding:2px 8px 2px 28px}.maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-inner{display:none}.maplibregl-ctrl-attrib-button{background-color:hsla(0,0%,100%,.5);background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E\");border:0;border-radius:12px;box-sizing:border-box;cursor:pointer;display:none;height:24px;outline:none;position:absolute;right:0;top:0;width:24px}.maplibregl-ctrl-attrib summary.maplibregl-ctrl-attrib-button{-webkit-appearance:none;-moz-appearance:none;appearance:none;list-style:none}.maplibregl-ctrl-attrib summary.maplibregl-ctrl-attrib-button::-webkit-details-marker{display:none}.maplibregl-ctrl-bottom-left .maplibregl-ctrl-attrib-button,.maplibregl-ctrl-top-left .maplibregl-ctrl-attrib-button{left:0}.maplibregl-ctrl-attrib.maplibregl-compact .maplibregl-ctrl-attrib-button,.maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-inner{display:block}.maplibregl-ctrl-attrib.maplibregl-compact-show .maplibregl-ctrl-attrib-button{background-color:rgb(0 0 0/5%)}.maplibregl-ctrl-bottom-right>.maplibregl-ctrl-attrib.maplibregl-compact:after{bottom:0;right:0}.maplibregl-ctrl-top-right>.maplibregl-ctrl-attrib.maplibregl-compact:after{right:0;top:0}.maplibregl-ctrl-top-left>.maplibregl-ctrl-attrib.maplibregl-compact:after{left:0;top:0}.maplibregl-ctrl-bottom-left>.maplibregl-ctrl-attrib.maplibregl-compact:after{bottom:0;left:0}}@media screen and (forced-colors:active){.maplibregl-ctrl-attrib.maplibregl-compact:after{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%23fff' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E\")}}@media screen and (forced-colors:active) and (prefers-color-scheme:light){.maplibregl-ctrl-attrib.maplibregl-compact:after{background-image:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill-rule='evenodd' viewBox='0 0 20 20'%3E%3Cpath d='M4 10a6 6 0 1 0 12 0 6 6 0 1 0-12 0m5-3a1 1 0 1 0 2 0 1 1 0 1 0-2 0m0 3a1 1 0 1 1 2 0v3a1 1 0 1 1-2 0'/%3E%3C/svg%3E\")}}.maplibregl-ctrl-attrib a{color:rgba(0,0,0,.75);text-decoration:none}.maplibregl-ctrl-attrib a:hover{color:inherit;text-decoration:underline}.maplibregl-attrib-empty{display:none}.maplibregl-ctrl-scale{background-color:hsla(0,0%,100%,.75);border:2px solid #333;border-top:#333;box-sizing:border-box;color:#333;font-size:10px;padding:0 5px}.maplibregl-popup{display:flex;left:0;pointer-events:none;position:absolute;top:0;will-change:transform}.maplibregl-popup-anchor-top,.maplibregl-popup-anchor-top-left,.maplibregl-popup-anchor-top-right{flex-direction:column}.maplibregl-popup-anchor-bottom,.maplibregl-popup-anchor-bottom-left,.maplibregl-popup-anchor-bottom-right{flex-direction:column-reverse}.maplibregl-popup-anchor-left{flex-direction:row}.maplibregl-popup-anchor-right{flex-direction:row-reverse}.maplibregl-popup-tip{border:10px solid transparent;height:0;width:0;z-index:1}.maplibregl-popup-anchor-top .maplibregl-popup-tip{align-self:center;border-bottom-color:#fff;border-top:none}.maplibregl-popup-anchor-top-left .maplibregl-popup-tip{align-self:flex-start;border-bottom-color:#fff;border-left:none;border-top:none}.maplibregl-popup-anchor-top-right .maplibregl-popup-tip{align-self:flex-end;border-bottom-color:#fff;border-right:none;border-top:none}.maplibregl-popup-anchor-bottom .maplibregl-popup-tip{align-self:center;border-bottom:none;border-top-color:#fff}.maplibregl-popup-anchor-bottom-left .maplibregl-popup-tip{align-self:flex-start;border-bottom:none;border-left:none;border-top-color:#fff}.maplibregl-popup-anchor-bottom-right .maplibregl-popup-tip{align-self:flex-end;border-bottom:none;border-right:none;border-top-color:#fff}.maplibregl-popup-anchor-left .maplibregl-popup-tip{align-self:center;border-left:none;border-right-color:#fff}.maplibregl-popup-anchor-right .maplibregl-popup-tip{align-self:center;border-left-color:#fff;border-right:none}.maplibregl-popup-close-button{background-color:transparent;border:0;border-radius:0 3px 0 0;cursor:pointer;position:absolute;right:0;top:0}.maplibregl-popup-close-button:hover{background-color:rgb(0 0 0/5%)}.maplibregl-popup-content{background:#fff;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.1);padding:15px 10px;pointer-events:auto;position:relative}.maplibregl-popup-anchor-top-left .maplibregl-popup-content{border-top-left-radius:0}.maplibregl-popup-anchor-top-right .maplibregl-popup-content{border-top-right-radius:0}.maplibregl-popup-anchor-bottom-left .maplibregl-popup-content{border-bottom-left-radius:0}.maplibregl-popup-anchor-bottom-right .maplibregl-popup-content{border-bottom-right-radius:0}.maplibregl-popup-track-pointer{display:none}.maplibregl-popup-track-pointer *{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.maplibregl-map:hover .maplibregl-popup-track-pointer{display:flex}.maplibregl-map:active .maplibregl-popup-track-pointer{display:none}.maplibregl-marker{left:0;position:absolute;top:0;transition:opacity .2s;will-change:transform}.maplibregl-user-location-dot,.maplibregl-user-location-dot:before{background-color:#1da1f2;border-radius:50%;height:15px;width:15px}.maplibregl-user-location-dot:before{animation:maplibregl-user-location-dot-pulse 2s infinite;content:\"\";position:absolute}.maplibregl-user-location-dot:after{border:2px solid #fff;border-radius:50%;box-shadow:0 0 3px rgba(0,0,0,.35);box-sizing:border-box;content:\"\";height:19px;left:-2px;position:absolute;top:-2px;width:19px}@keyframes maplibregl-user-location-dot-pulse{0%{opacity:1;transform:scale(1)}70%{opacity:0;transform:scale(3)}to{opacity:0;transform:scale(1)}}.maplibregl-user-location-dot-stale{background-color:#aaa}.maplibregl-user-location-dot-stale:after{display:none}.maplibregl-user-location-accuracy-circle{background-color:#1da1f233;border-radius:100%;height:1px;width:1px}.maplibregl-crosshair,.maplibregl-crosshair .maplibregl-interactive,.maplibregl-crosshair .maplibregl-interactive:active{cursor:crosshair}.maplibregl-boxzoom{background:#fff;border:2px dotted #202020;height:0;left:0;opacity:.5;position:absolute;top:0;width:0}.maplibregl-cooperative-gesture-screen{align-items:center;background:rgba(0,0,0,.4);color:#fff;display:flex;font-size:1.4em;inset:0;justify-content:center;line-height:1.2;opacity:0;padding:1rem;pointer-events:none;position:absolute;transition:opacity 1s ease 1s;z-index:99999}.maplibregl-cooperative-gesture-screen.maplibregl-show{opacity:1;transition:opacity .05s}.maplibregl-cooperative-gesture-screen .maplibregl-mobile-message{display:none}@media (hover:none),(pointer:coarse){.maplibregl-cooperative-gesture-screen .maplibregl-desktop-message{display:none}.maplibregl-cooperative-gesture-screen .maplibregl-mobile-message{display:block}}.maplibregl-pseudo-fullscreen{height:100%!important;left:0!important;position:fixed!important;top:0!important;width:100%!important;z-index:99999}","modules/coach-world/vendor/maplibre-gl.js":"/**\n * MapLibre GL JS\n * @license 3-Clause BSD. Full text of license: https://github.com/maplibre/maplibre-gl-js/blob/v5.6.0/LICENSE.txt\n */\n(function (global, factory) {\ntypeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\ntypeof define === 'function' && define.amd ? define(factory) :\n(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.maplibregl = factory());\n})(this, (function () { 'use strict';\n\n/* eslint-disable */\n\nvar maplibregl = {};\nvar modules = {};\nfunction define(moduleName, _dependencies, moduleFactory) {\n    modules[moduleName] = moduleFactory;\n\n    // to get the list of modules see generated dist/maplibre-gl-dev.js file (look for `define(` calls)\n    if (moduleName !== 'index') {\n        return;\n    }\n\n    // we assume that when an index module is initializing then other modules are loaded already\n    var workerBundleString = 'var sharedModule = {}; (' + modules.shared + ')(sharedModule); (' + modules.worker + ')(sharedModule);'\n\n    var sharedModule = {};\n    // the order of arguments of a module factory depends on rollup (it decides who is whose dependency)\n    // to check the correct order, see dist/maplibre-gl-dev.js file (look for `define(` calls)\n    // we assume that for our 3 chunks it will generate 3 modules and their order is predefined like the following\n    modules.shared(sharedModule);\n    modules.index(maplibregl, sharedModule);\n\n    if (typeof window !== 'undefined') {\n        maplibregl.setWorkerUrl(window.URL.createObjectURL(new Blob([workerBundleString], { type: 'text/javascript' })));\n    }\n\n    return maplibregl;\n};\n\n\n\ndefine(\"shared\",[\"exports\"],(function(t){\"use strict\";function e(t,e,r,n){return new(r||(r=Promise))((function(i,s){function a(t){try{l(n.next(t));}catch(t){s(t);}}function o(t){try{l(n.throw(t));}catch(t){s(t);}}function l(t){var e;t.done?i(t.value):(e=t.value,e instanceof r?e:new r((function(t){t(e);}))).then(a,o);}l((n=n.apply(t,e||[])).next());}))}function r(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,\"default\")?t.default:t}var n,i;function s(){if(i)return n;function t(t,e){this.x=t,this.y=e;}return i=1,n=t,t.prototype={clone:function(){return new t(this.x,this.y)},add:function(t){return this.clone()._add(t)},sub:function(t){return this.clone()._sub(t)},multByPoint:function(t){return this.clone()._multByPoint(t)},divByPoint:function(t){return this.clone()._divByPoint(t)},mult:function(t){return this.clone()._mult(t)},div:function(t){return this.clone()._div(t)},rotate:function(t){return this.clone()._rotate(t)},rotateAround:function(t,e){return this.clone()._rotateAround(t,e)},matMult:function(t){return this.clone()._matMult(t)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(t){return this.x===t.x&&this.y===t.y},dist:function(t){return Math.sqrt(this.distSqr(t))},distSqr:function(t){var e=t.x-this.x,r=t.y-this.y;return e*e+r*r},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(t){return Math.atan2(this.y-t.y,this.x-t.x)},angleWith:function(t){return this.angleWithSep(t.x,t.y)},angleWithSep:function(t,e){return Math.atan2(this.x*e-this.y*t,this.x*t+this.y*e)},_matMult:function(t){var e=t[2]*this.x+t[3]*this.y;return this.x=t[0]*this.x+t[1]*this.y,this.y=e,this},_add:function(t){return this.x+=t.x,this.y+=t.y,this},_sub:function(t){return this.x-=t.x,this.y-=t.y,this},_mult:function(t){return this.x*=t,this.y*=t,this},_div:function(t){return this.x/=t,this.y/=t,this},_multByPoint:function(t){return this.x*=t.x,this.y*=t.y,this},_divByPoint:function(t){return this.x/=t.x,this.y/=t.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var t=this.y;return this.y=this.x,this.x=-t,this},_rotate:function(t){var e=Math.cos(t),r=Math.sin(t),n=r*this.x+e*this.y;return this.x=e*this.x-r*this.y,this.y=n,this},_rotateAround:function(t,e){var r=Math.cos(t),n=Math.sin(t),i=e.y+n*(this.x-e.x)+r*(this.y-e.y);return this.x=e.x+r*(this.x-e.x)-n*(this.y-e.y),this.y=i,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}},t.convert=function(e){return e instanceof t?e:Array.isArray(e)?new t(e[0],e[1]):e},n}\"function\"==typeof SuppressedError&&SuppressedError;var a,o,l=r(s()),u=function(){if(o)return a;function t(t,e,r,n){this.cx=3*t,this.bx=3*(r-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(n-e)-this.cy,this.ay=1-this.cy-this.by,this.p1x=t,this.p1y=e,this.p2x=r,this.p2y=n;}return o=1,a=t,t.prototype={sampleCurveX:function(t){return ((this.ax*t+this.bx)*t+this.cx)*t},sampleCurveY:function(t){return ((this.ay*t+this.by)*t+this.cy)*t},sampleCurveDerivativeX:function(t){return (3*this.ax*t+2*this.bx)*t+this.cx},solveCurveX:function(t,e){if(void 0===e&&(e=1e-6),t<0)return 0;if(t>1)return 1;for(var r=t,n=0;n<8;n++){var i=this.sampleCurveX(r)-t;if(Math.abs(i)<e)return r;var s=this.sampleCurveDerivativeX(r);if(Math.abs(s)<1e-6)break;r-=i/s;}var a=0,o=1;for(r=t,n=0;n<20&&(i=this.sampleCurveX(r),!(Math.abs(i-t)<e));n++)t>i?a=r:o=r,r=.5*(o-a)+a;return r},solve:function(t,e){return this.sampleCurveY(this.solveCurveX(t,e))}},a}(),c=r(u);let h,p;function f(){return null==h&&(h=\"undefined\"!=typeof OffscreenCanvas&&new OffscreenCanvas(1,1).getContext(\"2d\")&&\"function\"==typeof createImageBitmap),h}function d(){if(null==p&&(p=!1,f())){const t=5,e=new OffscreenCanvas(t,t).getContext(\"2d\",{willReadFrequently:!0});if(e){for(let r=0;r<t*t;r++){const n=4*r;e.fillStyle=`rgb(${n},${n+1},${n+2})`,e.fillRect(r%t,Math.floor(r/t),1,1);}const r=e.getImageData(0,0,t,t).data;for(let e=0;e<t*t*4;e++)if(e%4!=3&&r[e]!==e){p=!0;break}}}return p||!1}var y=1e-6,m=\"undefined\"!=typeof Float32Array?Float32Array:Array;function g(){var t=new m(9);return m!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[5]=0,t[6]=0,t[7]=0),t[0]=1,t[4]=1,t[8]=1,t}function x(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}function v(){var t=new m(3);return m!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t}function b(t){return Math.hypot(t[0],t[1],t[2])}function w(t,e,r){var n=new m(3);return n[0]=t,n[1]=e,n[2]=r,n}function _(t,e,r){return t[0]=e[0]+r[0],t[1]=e[1]+r[1],t[2]=e[2]+r[2],t}function S(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t}function A(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[0],o=r[1],l=r[2];return t[0]=i*l-s*o,t[1]=s*a-n*l,t[2]=n*o-i*a,t}Math.hypot||(Math.hypot=function(){for(var t=0,e=arguments.length;e--;)t+=arguments[e]*arguments[e];return Math.sqrt(t)});var k,M=b;function I(t,e,r){var n=e[0],i=e[1],s=e[2],a=e[3];return t[0]=r[0]*n+r[4]*i+r[8]*s+r[12]*a,t[1]=r[1]*n+r[5]*i+r[9]*s+r[13]*a,t[2]=r[2]*n+r[6]*i+r[10]*s+r[14]*a,t[3]=r[3]*n+r[7]*i+r[11]*s+r[15]*a,t}function z(){var t=new m(4);return m!=Float32Array&&(t[0]=0,t[1]=0,t[2]=0),t[3]=1,t}function P(t,e,r,n){var i=.5*Math.PI/180;e*=i,r*=i,n*=i;var s=Math.sin(e),a=Math.cos(e),o=Math.sin(r),l=Math.cos(r),u=Math.sin(n),c=Math.cos(n);return t[0]=s*l*c-a*o*u,t[1]=a*o*c+s*l*u,t[2]=a*l*u-s*o*c,t[3]=a*l*c+s*o*u,t}function C(){var t=new m(2);return m!=Float32Array&&(t[0]=0,t[1]=0),t}function B(t,e){var r=new m(2);return r[0]=t,r[1]=e,r}v(),k=new m(4),m!=Float32Array&&(k[0]=0,k[1]=0,k[2]=0,k[3]=0),v(),w(1,0,0),w(0,1,0),z(),z(),g(),C();const E=8192;function T(t,e,r){return e*(E/(t.tileSize*Math.pow(2,r-t.tileID.overscaledZ)))}function V(t,e){return (t%e+e)%e}function F(t,e,r){return t*(1-r)+e*r}function L(t){if(t<=0)return 0;if(t>=1)return 1;const e=t*t,r=e*t;return 4*(t<.5?r:3*(t-e)+r-.75)}function $(t,e,r,n){const i=new c(t,e,r,n);return t=>i.solve(t)}const D=$(.25,.1,.25,1);function O(t,e,r){return Math.min(r,Math.max(e,t))}function R(t,e,r){const n=r-e,i=((t-e)%n+n)%n+e;return i===e?r:i}function j(t,...e){for(const r of e)for(const e in r)t[e]=r[e];return t}let N=1;function U(t,e,r){const n={};for(const r in t)n[r]=e.call(this,t[r],r,t);return n}function q(t,e,r){const n={};for(const r in t)e.call(this,t[r],r,t)&&(n[r]=t[r]);return n}function G(t){return Array.isArray(t)?t.map(G):\"object\"==typeof t&&t?U(t,G):t}const X={};function Z(t){X[t]||(\"undefined\"!=typeof console&&console.warn(t),X[t]=!0);}function Y(t,e,r){return (r.y-t.y)*(e.x-t.x)>(e.y-t.y)*(r.x-t.x)}function H(t){return \"undefined\"!=typeof WorkerGlobalScope&&void 0!==t&&t instanceof WorkerGlobalScope}let K=null;function J(t){return \"undefined\"!=typeof ImageBitmap&&t instanceof ImageBitmap}const W=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=\";function Q(t,r,n,i,s){return e(this,void 0,void 0,(function*(){if(\"undefined\"==typeof VideoFrame)throw new Error(\"VideoFrame not supported\");const e=new VideoFrame(t,{timestamp:0});try{const a=null==e?void 0:e.format;if(!a||!a.startsWith(\"BGR\")&&!a.startsWith(\"RGB\"))throw new Error(`Unrecognized format ${a}`);const o=a.startsWith(\"BGR\"),l=new Uint8ClampedArray(i*s*4);if(yield e.copyTo(l,function(t,e,r,n,i){const s=4*Math.max(1,0),a=(Math.max(0,r)-r)*n*4+s,o=4*n,l=Math.max(0,e),u=Math.max(0,r);return {rect:{x:l,y:u,width:Math.min(t.width,e+n)-l,height:Math.min(t.height,r+i)-u},layout:[{offset:a,stride:o}]}}(t,r,n,i,s)),o)for(let t=0;t<l.length;t+=4){const e=l[t];l[t]=l[t+2],l[t+2]=e;}return l}finally{e.close();}}))}let tt,et;function rt(t,e,r,n){return t.addEventListener(e,r,n),{unsubscribe:()=>{t.removeEventListener(e,r,n);}}}function nt(t){return t*Math.PI/180}function it(t){return t/Math.PI*180}const st={touchstart:!0,touchmove:!0,touchmoveWindow:!0,touchend:!0,touchcancel:!0},at={dblclick:!0,click:!0,mouseover:!0,mouseout:!0,mousedown:!0,mousemove:!0,mousemoveWindow:!0,mouseup:!0,mouseupWindow:!0,contextmenu:!0,wheel:!0},ot=\"AbortError\";function lt(){return new Error(ot)}const ut={MAX_PARALLEL_IMAGE_REQUESTS:16,MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME:8,MAX_TILE_CACHE_ZOOM_LEVELS:5,REGISTERED_PROTOCOLS:{},WORKER_URL:\"\"};function ct(t){return ut.REGISTERED_PROTOCOLS[t.substring(0,t.indexOf(\"://\"))]}const ht=\"global-dispatcher\";class pt extends Error{constructor(t,e,r,n){super(`AJAXError: ${e} (${t}): ${r}`),this.status=t,this.statusText=e,this.url=r,this.body=n;}}const ft=()=>H(self)?self.worker&&self.worker.referrer:(\"blob:\"===window.location.protocol?window.parent:window).location.href,dt=function(t,r){if(/:\\/\\//.test(t.url)&&!/^https?:|^file:/.test(t.url)){const e=ct(t.url);if(e)return e(t,r);if(H(self)&&self.worker&&self.worker.actor)return self.worker.actor.sendAsync({type:\"GR\",data:t,targetMapId:ht},r)}if(!(/^file:/.test(n=t.url)||/^file:/.test(ft())&&!/^\\w+:/.test(n))){if(fetch&&Request&&AbortController&&Object.prototype.hasOwnProperty.call(Request.prototype,\"signal\"))return function(t,r){return e(this,void 0,void 0,(function*(){const e=new Request(t.url,{method:t.method||\"GET\",body:t.body,credentials:t.credentials,headers:t.headers,cache:t.cache,referrer:ft(),signal:r.signal});let n,i;\"json\"!==t.type||e.headers.has(\"Accept\")||e.headers.set(\"Accept\",\"application/json\");try{n=yield fetch(e);}catch(e){throw new pt(0,e.message,t.url,new Blob)}if(!n.ok){const e=yield n.blob();throw new pt(n.status,n.statusText,t.url,e)}i=\"arrayBuffer\"===t.type||\"image\"===t.type?n.arrayBuffer():\"json\"===t.type?n.json():n.text();const s=yield i;if(r.signal.aborted)throw lt();return {data:s,cacheControl:n.headers.get(\"Cache-Control\"),expires:n.headers.get(\"Expires\")}}))}(t,r);if(H(self)&&self.worker&&self.worker.actor)return self.worker.actor.sendAsync({type:\"GR\",data:t,mustQueue:!0,targetMapId:ht},r)}var n;return function(t,e){return new Promise(((r,n)=>{var i;const s=new XMLHttpRequest;s.open(t.method||\"GET\",t.url,!0),\"arrayBuffer\"!==t.type&&\"image\"!==t.type||(s.responseType=\"arraybuffer\");for(const e in t.headers)s.setRequestHeader(e,t.headers[e]);\"json\"===t.type&&(s.responseType=\"text\",(null===(i=t.headers)||void 0===i?void 0:i.Accept)||s.setRequestHeader(\"Accept\",\"application/json\")),s.withCredentials=\"include\"===t.credentials,s.onerror=()=>{n(new Error(s.statusText));},s.onload=()=>{if(!e.signal.aborted)if((s.status>=200&&s.status<300||0===s.status)&&null!==s.response){let e=s.response;if(\"json\"===t.type)try{e=JSON.parse(s.response);}catch(t){return void n(t)}r({data:e,cacheControl:s.getResponseHeader(\"Cache-Control\"),expires:s.getResponseHeader(\"Expires\")});}else {const e=new Blob([s.response],{type:s.getResponseHeader(\"Content-Type\")});n(new pt(s.status,s.statusText,t.url,e));}},e.signal.addEventListener(\"abort\",(()=>{s.abort(),n(lt());})),s.send(t.body);}))}(t,r)};function yt(t){if(!t||t.indexOf(\"://\")<=0||0===t.indexOf(\"data:image/\")||0===t.indexOf(\"blob:\"))return !0;const e=new URL(t),r=window.location;return e.protocol===r.protocol&&e.host===r.host}function mt(t,e,r){r[t]&&-1!==r[t].indexOf(e)||(r[t]=r[t]||[],r[t].push(e));}function gt(t,e,r){if(r&&r[t]){const n=r[t].indexOf(e);-1!==n&&r[t].splice(n,1);}}class xt{constructor(t,e={}){j(this,e),this.type=t;}}class vt extends xt{constructor(t,e={}){super(\"error\",j({error:t},e));}}class bt{on(t,e){return this._listeners=this._listeners||{},mt(t,e,this._listeners),{unsubscribe:()=>{this.off(t,e);}}}off(t,e){return gt(t,e,this._listeners),gt(t,e,this._oneTimeListeners),this}once(t,e){return e?(this._oneTimeListeners=this._oneTimeListeners||{},mt(t,e,this._oneTimeListeners),this):new Promise((e=>this.once(t,e)))}fire(t,e){\"string\"==typeof t&&(t=new xt(t,e||{}));const r=t.type;if(this.listens(r)){t.target=this;const e=this._listeners&&this._listeners[r]?this._listeners[r].slice():[];for(const r of e)r.call(this,t);const n=this._oneTimeListeners&&this._oneTimeListeners[r]?this._oneTimeListeners[r].slice():[];for(const e of n)gt(r,e,this._oneTimeListeners),e.call(this,t);const i=this._eventedParent;i&&(j(t,\"function\"==typeof this._eventedParentData?this._eventedParentData():this._eventedParentData),i.fire(t));}else t instanceof vt&&console.error(t.error);return this}listens(t){return this._listeners&&this._listeners[t]&&this._listeners[t].length>0||this._oneTimeListeners&&this._oneTimeListeners[t]&&this._oneTimeListeners[t].length>0||this._eventedParent&&this._eventedParent.listens(t)}setEventedParent(t,e){return this._eventedParent=t,this._eventedParentData=e,this}}var wt={$version:8,$root:{version:{required:!0,type:\"enum\",values:[8]},name:{type:\"string\"},metadata:{type:\"*\"},center:{type:\"array\",value:\"number\"},centerAltitude:{type:\"number\"},zoom:{type:\"number\"},bearing:{type:\"number\",default:0,period:360,units:\"degrees\"},pitch:{type:\"number\",default:0,units:\"degrees\"},roll:{type:\"number\",default:0,units:\"degrees\"},state:{type:\"state\",default:{}},light:{type:\"light\"},sky:{type:\"sky\"},projection:{type:\"projection\"},terrain:{type:\"terrain\"},sources:{required:!0,type:\"sources\"},sprite:{type:\"sprite\"},glyphs:{type:\"string\"},transition:{type:\"transition\"},layers:{required:!0,type:\"array\",value:\"layer\"}},sources:{\"*\":{type:\"source\"}},source:[\"source_vector\",\"source_raster\",\"source_raster_dem\",\"source_geojson\",\"source_video\",\"source_image\"],source_vector:{type:{required:!0,type:\"enum\",values:{vector:{}}},url:{type:\"string\"},tiles:{type:\"array\",value:\"string\"},bounds:{type:\"array\",value:\"number\",length:4,default:[-180,-85.051129,180,85.051129]},scheme:{type:\"enum\",values:{xyz:{},tms:{}},default:\"xyz\"},minzoom:{type:\"number\",default:0},maxzoom:{type:\"number\",default:22},attribution:{type:\"string\"},promoteId:{type:\"promoteId\"},volatile:{type:\"boolean\",default:!1},\"*\":{type:\"*\"}},source_raster:{type:{required:!0,type:\"enum\",values:{raster:{}}},url:{type:\"string\"},tiles:{type:\"array\",value:\"string\"},bounds:{type:\"array\",value:\"number\",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:\"number\",default:0},maxzoom:{type:\"number\",default:22},tileSize:{type:\"number\",default:512,units:\"pixels\"},scheme:{type:\"enum\",values:{xyz:{},tms:{}},default:\"xyz\"},attribution:{type:\"string\"},volatile:{type:\"boolean\",default:!1},\"*\":{type:\"*\"}},source_raster_dem:{type:{required:!0,type:\"enum\",values:{\"raster-dem\":{}}},url:{type:\"string\"},tiles:{type:\"array\",value:\"string\"},bounds:{type:\"array\",value:\"number\",length:4,default:[-180,-85.051129,180,85.051129]},minzoom:{type:\"number\",default:0},maxzoom:{type:\"number\",default:22},tileSize:{type:\"number\",default:512,units:\"pixels\"},attribution:{type:\"string\"},encoding:{type:\"enum\",values:{terrarium:{},mapbox:{},custom:{}},default:\"mapbox\"},redFactor:{type:\"number\",default:1},blueFactor:{type:\"number\",default:1},greenFactor:{type:\"number\",default:1},baseShift:{type:\"number\",default:0},volatile:{type:\"boolean\",default:!1},\"*\":{type:\"*\"}},source_geojson:{type:{required:!0,type:\"enum\",values:{geojson:{}}},data:{required:!0,type:\"*\"},maxzoom:{type:\"number\",default:18},attribution:{type:\"string\"},buffer:{type:\"number\",default:128,maximum:512,minimum:0},filter:{type:\"*\"},tolerance:{type:\"number\",default:.375},cluster:{type:\"boolean\",default:!1},clusterRadius:{type:\"number\",default:50,minimum:0},clusterMaxZoom:{type:\"number\"},clusterMinPoints:{type:\"number\"},clusterProperties:{type:\"*\"},lineMetrics:{type:\"boolean\",default:!1},generateId:{type:\"boolean\",default:!1},promoteId:{type:\"promoteId\"}},source_video:{type:{required:!0,type:\"enum\",values:{video:{}}},urls:{required:!0,type:\"array\",value:\"string\"},coordinates:{required:!0,type:\"array\",length:4,value:{type:\"array\",length:2,value:\"number\"}}},source_image:{type:{required:!0,type:\"enum\",values:{image:{}}},url:{required:!0,type:\"string\"},coordinates:{required:!0,type:\"array\",length:4,value:{type:\"array\",length:2,value:\"number\"}}},layer:{id:{type:\"string\",required:!0},type:{type:\"enum\",values:{fill:{},line:{},symbol:{},circle:{},heatmap:{},\"fill-extrusion\":{},raster:{},hillshade:{},\"color-relief\":{},background:{}},required:!0},metadata:{type:\"*\"},source:{type:\"string\"},\"source-layer\":{type:\"string\"},minzoom:{type:\"number\",minimum:0,maximum:24},maxzoom:{type:\"number\",minimum:0,maximum:24},filter:{type:\"filter\"},layout:{type:\"layout\"},paint:{type:\"paint\"}},layout:[\"layout_fill\",\"layout_line\",\"layout_circle\",\"layout_heatmap\",\"layout_fill-extrusion\",\"layout_symbol\",\"layout_raster\",\"layout_hillshade\",\"layout_color-relief\",\"layout_background\"],layout_background:{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_fill:{\"fill-sort-key\":{type:\"number\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_circle:{\"circle-sort-key\":{type:\"number\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_heatmap:{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},\"layout_fill-extrusion\":{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_line:{\"line-cap\":{type:\"enum\",values:{butt:{},round:{},square:{}},default:\"butt\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"line-join\":{type:\"enum\",values:{bevel:{},round:{},miter:{}},default:\"miter\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"line-miter-limit\":{type:\"number\",default:2,requires:[{\"line-join\":\"miter\"}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"line-round-limit\":{type:\"number\",default:1.05,requires:[{\"line-join\":\"round\"}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"line-sort-key\":{type:\"number\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_symbol:{\"symbol-placement\":{type:\"enum\",values:{point:{},line:{},\"line-center\":{}},default:\"point\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"symbol-spacing\":{type:\"number\",default:250,minimum:1,units:\"pixels\",requires:[{\"symbol-placement\":\"line\"}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"symbol-avoid-edges\":{type:\"boolean\",default:!1,expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"symbol-sort-key\":{type:\"number\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"symbol-z-order\":{type:\"enum\",values:{auto:{},\"viewport-y\":{},source:{}},default:\"auto\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-allow-overlap\":{type:\"boolean\",default:!1,requires:[\"icon-image\",{\"!\":\"icon-overlap\"}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-overlap\":{type:\"enum\",values:{never:{},always:{},cooperative:{}},requires:[\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-ignore-placement\":{type:\"boolean\",default:!1,requires:[\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-optional\":{type:\"boolean\",default:!1,requires:[\"icon-image\",\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-rotation-alignment\":{type:\"enum\",values:{map:{},viewport:{},auto:{}},default:\"auto\",requires:[\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-size\":{type:\"number\",default:1,minimum:0,units:\"factor of the original icon size\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-text-fit\":{type:\"enum\",values:{none:{},width:{},height:{},both:{}},default:\"none\",requires:[\"icon-image\",\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-text-fit-padding\":{type:\"array\",value:\"number\",length:4,default:[0,0,0,0],units:\"pixels\",requires:[\"icon-image\",\"text-field\",{\"icon-text-fit\":[\"both\",\"width\",\"height\"]}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-image\":{type:\"resolvedImage\",tokens:!0,expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-rotate\":{type:\"number\",default:0,period:360,units:\"degrees\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-padding\":{type:\"padding\",default:[2],units:\"pixels\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-keep-upright\":{type:\"boolean\",default:!1,requires:[\"icon-image\",{\"icon-rotation-alignment\":\"map\"},{\"symbol-placement\":[\"line\",\"line-center\"]}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-offset\":{type:\"array\",value:\"number\",length:2,default:[0,0],requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-anchor\":{type:\"enum\",values:{center:{},left:{},right:{},top:{},bottom:{},\"top-left\":{},\"top-right\":{},\"bottom-left\":{},\"bottom-right\":{}},default:\"center\",requires:[\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"icon-pitch-alignment\":{type:\"enum\",values:{map:{},viewport:{},auto:{}},default:\"auto\",requires:[\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-pitch-alignment\":{type:\"enum\",values:{map:{},viewport:{},auto:{}},default:\"auto\",requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-rotation-alignment\":{type:\"enum\",values:{map:{},viewport:{},\"viewport-glyph\":{},auto:{}},default:\"auto\",requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-field\":{type:\"formatted\",default:\"\",tokens:!0,expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-font\":{type:\"array\",value:\"string\",default:[\"Open Sans Regular\",\"Arial Unicode MS Regular\"],requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-size\":{type:\"number\",default:16,minimum:0,units:\"pixels\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-max-width\":{type:\"number\",default:10,minimum:0,units:\"ems\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-line-height\":{type:\"number\",default:1.2,units:\"ems\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-letter-spacing\":{type:\"number\",default:0,units:\"ems\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-justify\":{type:\"enum\",values:{auto:{},left:{},center:{},right:{}},default:\"center\",requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-radial-offset\":{type:\"number\",units:\"ems\",default:0,requires:[\"text-field\"],\"property-type\":\"data-driven\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]}},\"text-variable-anchor\":{type:\"array\",value:\"enum\",values:{center:{},left:{},right:{},top:{},bottom:{},\"top-left\":{},\"top-right\":{},\"bottom-left\":{},\"bottom-right\":{}},requires:[\"text-field\",{\"symbol-placement\":[\"point\"]}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-variable-anchor-offset\":{type:\"variableAnchorOffsetCollection\",requires:[\"text-field\",{\"symbol-placement\":[\"point\"]}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-anchor\":{type:\"enum\",values:{center:{},left:{},right:{},top:{},bottom:{},\"top-left\":{},\"top-right\":{},\"bottom-left\":{},\"bottom-right\":{}},default:\"center\",requires:[\"text-field\",{\"!\":\"text-variable-anchor\"}],expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-max-angle\":{type:\"number\",default:45,units:\"degrees\",requires:[\"text-field\",{\"symbol-placement\":[\"line\",\"line-center\"]}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-writing-mode\":{type:\"array\",value:\"enum\",values:{horizontal:{},vertical:{}},requires:[\"text-field\",{\"symbol-placement\":[\"point\"]}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-rotate\":{type:\"number\",default:0,period:360,units:\"degrees\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-padding\":{type:\"number\",default:2,minimum:0,units:\"pixels\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-keep-upright\":{type:\"boolean\",default:!0,requires:[\"text-field\",{\"text-rotation-alignment\":\"map\"},{\"symbol-placement\":[\"line\",\"line-center\"]}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-transform\":{type:\"enum\",values:{none:{},uppercase:{},lowercase:{}},default:\"none\",requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-offset\":{type:\"array\",value:\"number\",units:\"ems\",length:2,default:[0,0],requires:[\"text-field\",{\"!\":\"text-radial-offset\"}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"data-driven\"},\"text-allow-overlap\":{type:\"boolean\",default:!1,requires:[\"text-field\",{\"!\":\"text-overlap\"}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-overlap\":{type:\"enum\",values:{never:{},always:{},cooperative:{}},requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-ignore-placement\":{type:\"boolean\",default:!1,requires:[\"text-field\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-optional\":{type:\"boolean\",default:!1,requires:[\"text-field\",\"icon-image\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_raster:{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},layout_hillshade:{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},\"layout_color-relief\":{visibility:{type:\"enum\",values:{visible:{},none:{}},default:\"visible\",\"property-type\":\"constant\"}},filter:{type:\"array\",value:\"*\"},filter_operator:{type:\"enum\",values:{\"==\":{},\"!=\":{},\">\":{},\">=\":{},\"<\":{},\"<=\":{},in:{},\"!in\":{},all:{},any:{},none:{},has:{},\"!has\":{}}},geometry_type:{type:\"enum\",values:{Point:{},LineString:{},Polygon:{}}},function:{expression:{type:\"expression\"},stops:{type:\"array\",value:\"function_stop\"},base:{type:\"number\",default:1,minimum:0},property:{type:\"string\",default:\"$zoom\"},type:{type:\"enum\",values:{identity:{},exponential:{},interval:{},categorical:{}},default:\"exponential\"},colorSpace:{type:\"enum\",values:{rgb:{},lab:{},hcl:{}},default:\"rgb\"},default:{type:\"*\",required:!1}},function_stop:{type:\"array\",minimum:0,maximum:24,value:[\"number\",\"color\"],length:2},expression:{type:\"array\",value:\"*\",minimum:1},light:{anchor:{type:\"enum\",default:\"viewport\",values:{map:{},viewport:{}},\"property-type\":\"data-constant\",transition:!1,expression:{interpolated:!1,parameters:[\"zoom\"]}},position:{type:\"array\",default:[1.15,210,30],length:3,value:\"number\",\"property-type\":\"data-constant\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]}},color:{type:\"color\",\"property-type\":\"data-constant\",default:\"#ffffff\",expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},intensity:{type:\"number\",\"property-type\":\"data-constant\",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0}},sky:{\"sky-color\":{type:\"color\",\"property-type\":\"data-constant\",default:\"#88C6FC\",expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"horizon-color\":{type:\"color\",\"property-type\":\"data-constant\",default:\"#ffffff\",expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"fog-color\":{type:\"color\",\"property-type\":\"data-constant\",default:\"#ffffff\",expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"fog-ground-blend\":{type:\"number\",\"property-type\":\"data-constant\",default:.5,minimum:0,maximum:1,expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"horizon-fog-blend\":{type:\"number\",\"property-type\":\"data-constant\",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"sky-horizon-blend\":{type:\"number\",\"property-type\":\"data-constant\",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0},\"atmosphere-blend\":{type:\"number\",\"property-type\":\"data-constant\",default:.8,minimum:0,maximum:1,expression:{interpolated:!0,parameters:[\"zoom\"]},transition:!0}},terrain:{source:{type:\"string\",required:!0},exaggeration:{type:\"number\",minimum:0,default:1}},projection:{type:{type:\"projectionDefinition\",default:\"mercator\",\"property-type\":\"data-constant\",transition:!1,expression:{interpolated:!0,parameters:[\"zoom\"]}}},paint:[\"paint_fill\",\"paint_line\",\"paint_circle\",\"paint_heatmap\",\"paint_fill-extrusion\",\"paint_symbol\",\"paint_raster\",\"paint_hillshade\",\"paint_color-relief\",\"paint_background\"],paint_fill:{\"fill-antialias\":{type:\"boolean\",default:!0,expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-color\":{type:\"color\",default:\"#000000\",transition:!0,requires:[{\"!\":\"fill-pattern\"}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-outline-color\":{type:\"color\",transition:!0,requires:[{\"!\":\"fill-pattern\"},{\"fill-antialias\":!0}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"fill-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-pattern\":{type:\"resolvedImage\",transition:!0,expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"cross-faded-data-driven\"}},\"paint_fill-extrusion\":{\"fill-extrusion-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-extrusion-color\":{type:\"color\",default:\"#000000\",transition:!0,requires:[{\"!\":\"fill-extrusion-pattern\"}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-extrusion-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-extrusion-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"fill-extrusion-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"fill-extrusion-pattern\":{type:\"resolvedImage\",transition:!0,expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"cross-faded-data-driven\"},\"fill-extrusion-height\":{type:\"number\",default:0,minimum:0,units:\"meters\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-extrusion-base\":{type:\"number\",default:0,minimum:0,units:\"meters\",transition:!0,requires:[\"fill-extrusion-height\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"fill-extrusion-vertical-gradient\":{type:\"boolean\",default:!0,transition:!1,expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},paint_line:{\"line-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-color\":{type:\"color\",default:\"#000000\",transition:!0,requires:[{\"!\":\"line-pattern\"}],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"line-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"line-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"line-width\":{type:\"number\",default:1,minimum:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-gap-width\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-offset\":{type:\"number\",default:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-blur\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"line-dasharray\":{type:\"array\",value:\"number\",minimum:0,transition:!0,units:\"line widths\",requires:[{\"!\":\"line-pattern\"}],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"cross-faded\"},\"line-pattern\":{type:\"resolvedImage\",transition:!0,expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]},\"property-type\":\"cross-faded-data-driven\"},\"line-gradient\":{type:\"color\",transition:!1,requires:[{\"!\":\"line-dasharray\"},{\"!\":\"line-pattern\"},{source:\"geojson\",has:{lineMetrics:!0}}],expression:{interpolated:!0,parameters:[\"line-progress\"]},\"property-type\":\"color-ramp\"}},paint_circle:{\"circle-radius\":{type:\"number\",default:5,minimum:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-color\":{type:\"color\",default:\"#000000\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-blur\":{type:\"number\",default:0,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"circle-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"circle-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"circle-pitch-scale\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"circle-pitch-alignment\":{type:\"enum\",values:{map:{},viewport:{}},default:\"viewport\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"circle-stroke-width\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-stroke-color\":{type:\"color\",default:\"#000000\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"circle-stroke-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"}},paint_heatmap:{\"heatmap-radius\":{type:\"number\",default:30,minimum:1,transition:!0,units:\"pixels\",expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"heatmap-weight\":{type:\"number\",default:1,minimum:0,transition:!1,expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"heatmap-intensity\":{type:\"number\",default:1,minimum:0,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"heatmap-color\":{type:\"color\",default:[\"interpolate\",[\"linear\"],[\"heatmap-density\"],0,\"rgba(0, 0, 255, 0)\",.1,\"royalblue\",.3,\"cyan\",.5,\"lime\",.7,\"yellow\",1,\"red\"],transition:!1,expression:{interpolated:!0,parameters:[\"heatmap-density\"]},\"property-type\":\"color-ramp\"},\"heatmap-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},paint_symbol:{\"icon-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"icon-color\":{type:\"color\",default:\"#000000\",transition:!0,requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"icon-halo-color\":{type:\"color\",default:\"rgba(0, 0, 0, 0)\",transition:!0,requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"icon-halo-width\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"icon-halo-blur\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"icon-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",requires:[\"icon-image\"],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"icon-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"icon-image\",\"icon-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"text-color\":{type:\"color\",default:\"#000000\",transition:!0,overridable:!0,requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"text-halo-color\":{type:\"color\",default:\"rgba(0, 0, 0, 0)\",transition:!0,requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"text-halo-width\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"text-halo-blur\":{type:\"number\",default:0,minimum:0,transition:!0,units:\"pixels\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\",\"feature\",\"feature-state\"]},\"property-type\":\"data-driven\"},\"text-translate\":{type:\"array\",value:\"number\",length:2,default:[0,0],transition:!0,units:\"pixels\",requires:[\"text-field\"],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"text-translate-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"map\",requires:[\"text-field\",\"text-translate\"],expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},paint_raster:{\"raster-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-hue-rotate\":{type:\"number\",default:0,period:360,transition:!0,units:\"degrees\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-brightness-min\":{type:\"number\",default:0,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-brightness-max\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-saturation\":{type:\"number\",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-contrast\":{type:\"number\",default:0,minimum:-1,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-resampling\":{type:\"enum\",values:{linear:{},nearest:{}},default:\"linear\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"raster-fade-duration\":{type:\"number\",default:300,minimum:0,transition:!1,units:\"milliseconds\",expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},paint_hillshade:{\"hillshade-illumination-direction\":{type:\"numberArray\",default:335,minimum:0,maximum:359,transition:!1,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-illumination-altitude\":{type:\"numberArray\",default:45,minimum:0,maximum:90,transition:!1,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-illumination-anchor\":{type:\"enum\",values:{map:{},viewport:{}},default:\"viewport\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-exaggeration\":{type:\"number\",default:.5,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-shadow-color\":{type:\"colorArray\",default:\"#000000\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-highlight-color\":{type:\"colorArray\",default:\"#FFFFFF\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-accent-color\":{type:\"color\",default:\"#000000\",transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"hillshade-method\":{type:\"enum\",values:{standard:{},basic:{},combined:{},igor:{},multidirectional:{}},default:\"standard\",expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},\"paint_color-relief\":{\"color-relief-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"color-relief-color\":{type:\"color\",transition:!1,expression:{interpolated:!0,parameters:[\"elevation\"]},\"property-type\":\"color-ramp\"}},paint_background:{\"background-color\":{type:\"color\",default:\"#000000\",transition:!0,requires:[{\"!\":\"background-pattern\"}],expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"},\"background-pattern\":{type:\"resolvedImage\",transition:!0,expression:{interpolated:!1,parameters:[\"zoom\"]},\"property-type\":\"cross-faded\"},\"background-opacity\":{type:\"number\",default:1,minimum:0,maximum:1,transition:!0,expression:{interpolated:!0,parameters:[\"zoom\"]},\"property-type\":\"data-constant\"}},transition:{duration:{type:\"number\",default:300,minimum:0,units:\"milliseconds\"},delay:{type:\"number\",default:0,minimum:0,units:\"milliseconds\"}},\"property-type\":{\"data-driven\":{type:\"property-type\"},\"cross-faded\":{type:\"property-type\"},\"cross-faded-data-driven\":{type:\"property-type\"},\"color-ramp\":{type:\"property-type\"},\"data-constant\":{type:\"property-type\"},constant:{type:\"property-type\"}},promoteId:{\"*\":{type:\"string\"}}};const _t=[\"type\",\"source\",\"source-layer\",\"minzoom\",\"maxzoom\",\"filter\",\"layout\"];function St(t,e){const r={};for(const e in t)\"ref\"!==e&&(r[e]=t[e]);return _t.forEach((t=>{t in e&&(r[t]=e[t]);})),r}function At(t,e){if(Array.isArray(t)){if(!Array.isArray(e)||t.length!==e.length)return !1;for(let r=0;r<t.length;r++)if(!At(t[r],e[r]))return !1;return !0}if(\"object\"==typeof t&&null!==t&&null!==e){if(\"object\"!=typeof e)return !1;if(Object.keys(t).length!==Object.keys(e).length)return !1;for(const r in t)if(!At(t[r],e[r]))return !1;return !0}return t===e}function kt(t,e){t.push(e);}function Mt(t,e,r){kt(r,{command:\"addSource\",args:[t,e[t]]});}function It(t,e,r){kt(e,{command:\"removeSource\",args:[t]}),r[t]=!0;}function zt(t,e,r,n){It(t,r,n),Mt(t,e,r);}function Pt(t,e,r){let n;for(n in t[r])if(Object.prototype.hasOwnProperty.call(t[r],n)&&\"data\"!==n&&!At(t[r][n],e[r][n]))return !1;for(n in e[r])if(Object.prototype.hasOwnProperty.call(e[r],n)&&\"data\"!==n&&!At(t[r][n],e[r][n]))return !1;return !0}function Ct(t,e,r,n,i,s){t=t||{},e=e||{};for(const a in t)Object.prototype.hasOwnProperty.call(t,a)&&(At(t[a],e[a])||r.push({command:s,args:[n,a,e[a],i]}));for(const a in e)Object.prototype.hasOwnProperty.call(e,a)&&!Object.prototype.hasOwnProperty.call(t,a)&&(At(t[a],e[a])||r.push({command:s,args:[n,a,e[a],i]}));}function Bt(t){return t.id}function Et(t,e){return t[e.id]=e,t}class Tt{constructor(t,e,r,n){this.message=(t?`${t}: `:\"\")+r,n&&(this.identifier=n),null!=e&&e.__line__&&(this.line=e.__line__);}}function Vt(t,...e){for(const r of e)for(const e in r)t[e]=r[e];return t}class Ft extends Error{constructor(t,e){super(e),this.message=e,this.key=t;}}class Lt{constructor(t,e=[]){this.parent=t,this.bindings={};for(const[t,r]of e)this.bindings[t]=r;}concat(t){return new Lt(this,t)}get(t){if(this.bindings[t])return this.bindings[t];if(this.parent)return this.parent.get(t);throw new Error(`${t} not found in scope.`)}has(t){return !!this.bindings[t]||!!this.parent&&this.parent.has(t)}}const $t={kind:\"null\"},Dt={kind:\"number\"},Ot={kind:\"string\"},Rt={kind:\"boolean\"},jt={kind:\"color\"},Nt={kind:\"projectionDefinition\"},Ut={kind:\"object\"},qt={kind:\"value\"},Gt={kind:\"collator\"},Xt={kind:\"formatted\"},Zt={kind:\"padding\"},Yt={kind:\"colorArray\"},Ht={kind:\"numberArray\"},Kt={kind:\"resolvedImage\"},Jt={kind:\"variableAnchorOffsetCollection\"};function Wt(t,e){return {kind:\"array\",itemType:t,N:e}}function Qt(t){if(\"array\"===t.kind){const e=Qt(t.itemType);return \"number\"==typeof t.N?`array<${e}, ${t.N}>`:\"value\"===t.itemType.kind?\"array\":`array<${e}>`}return t.kind}const te=[$t,Dt,Ot,Rt,jt,Nt,Xt,Ut,Wt(qt),Zt,Ht,Yt,Kt,Jt];function ee(t,e){if(\"error\"===e.kind)return null;if(\"array\"===t.kind){if(\"array\"===e.kind&&(0===e.N&&\"value\"===e.itemType.kind||!ee(t.itemType,e.itemType))&&(\"number\"!=typeof t.N||t.N===e.N))return null}else {if(t.kind===e.kind)return null;if(\"value\"===t.kind)for(const t of te)if(!ee(t,e))return null}return `Expected ${Qt(t)} but found ${Qt(e)} instead.`}function re(t,e){return e.some((e=>e.kind===t.kind))}function ne(t,e){return e.some((e=>\"null\"===e?null===t:\"array\"===e?Array.isArray(t):\"object\"===e?t&&!Array.isArray(t)&&\"object\"==typeof t:e===typeof t))}function ie(t,e){return \"array\"===t.kind&&\"array\"===e.kind?t.itemType.kind===e.itemType.kind&&\"number\"==typeof t.N:t.kind===e.kind}const se=.96422,ae=.82521,oe=4/29,le=6/29,ue=3*le*le,ce=le*le*le,he=Math.PI/180,pe=180/Math.PI;function fe(t){return (t%=360)<0&&(t+=360),t}function de([t,e,r,n]){let i,s;const a=me((.2225045*(t=ye(t))+.7168786*(e=ye(e))+.0606169*(r=ye(r)))/1);t===e&&e===r?i=s=a:(i=me((.4360747*t+.3850649*e+.1430804*r)/se),s=me((.0139322*t+.0971045*e+.7141733*r)/ae));const o=116*a-16;return [o<0?0:o,500*(i-a),200*(a-s),n]}function ye(t){return t<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function me(t){return t>ce?Math.pow(t,1/3):t/ue+oe}function ge([t,e,r,n]){let i=(t+16)/116,s=isNaN(e)?i:i+e/500,a=isNaN(r)?i:i-r/200;return i=1*ve(i),s=se*ve(s),a=ae*ve(a),[xe(3.1338561*s-1.6168667*i-.4906146*a),xe(-.9787684*s+1.9161415*i+.033454*a),xe(.0719453*s-.2289914*i+1.4052427*a),n]}function xe(t){return (t=t<=.00304?12.92*t:1.055*Math.pow(t,1/2.4)-.055)<0?0:t>1?1:t}function ve(t){return t>le?t*t*t:ue*(t-oe)}const be=Object.hasOwn||function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};function we(t,e){return be(t,e)?t[e]:void 0}function _e(t){return parseInt(t.padEnd(2,t),16)/255}function Se(t,e){return Ae(e?t/100:t,0,1)}function Ae(t,e,r){return Math.min(Math.max(e,t),r)}function ke(t){return !t.some(Number.isNaN)}const Me={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]};function Ie(t,e,r){return t+r*(e-t)}function ze(t,e,r){return t.map(((t,n)=>Ie(t,e[n],r)))}class Pe{constructor(t,e,r,n=1,i=!0){this.r=t,this.g=e,this.b=r,this.a=n,i||(this.r*=n,this.g*=n,this.b*=n,n||this.overwriteGetter(\"rgb\",[t,e,r,n]));}static parse(t){if(t instanceof Pe)return t;if(\"string\"!=typeof t)return;const e=function(t){if(\"transparent\"===(t=t.toLowerCase().trim()))return [0,0,0,0];const e=we(Me,t);if(e){const[t,r,n]=e;return [t/255,r/255,n/255,1]}if(t.startsWith(\"#\")&&/^#(?:[0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/.test(t)){const e=t.length<6?1:2;let r=1;return [_e(t.slice(r,r+=e)),_e(t.slice(r,r+=e)),_e(t.slice(r,r+=e)),_e(t.slice(r,r+e)||\"ff\")]}if(t.startsWith(\"rgb\")){const e=t.match(/^rgba?\\(\\s*([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)(%)?(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/);if(e){const[t,r,n,i,s,a,o,l,u,c,h,p]=e,f=[i||\" \",o||\" \",c].join(\"\");if(\"  \"===f||\"  /\"===f||\",,\"===f||\",,,\"===f){const t=[n,a,u].join(\"\"),e=\"%%%\"===t?100:\"\"===t?255:0;if(e){const t=[Ae(+r/e,0,1),Ae(+s/e,0,1),Ae(+l/e,0,1),h?Se(+h,p):1];if(ke(t))return t}}return}}const r=t.match(/^hsla?\\(\\s*([\\de.+-]+)(?:deg)?(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s+|\\s*(,)\\s*)([\\de.+-]+)%(?:\\s*([,\\/])\\s*([\\de.+-]+)(%)?)?\\s*\\)$/);if(r){const[t,e,n,i,s,a,o,l,u]=r,c=[n||\" \",s||\" \",o].join(\"\");if(\"  \"===c||\"  /\"===c||\",,\"===c||\",,,\"===c){const t=[+e,Ae(+i,0,100),Ae(+a,0,100),l?Se(+l,u):1];if(ke(t))return function([t,e,r,n]){function i(n){const i=(n+t/30)%12,s=e*Math.min(r,1-r);return r-s*Math.max(-1,Math.min(i-3,9-i,1))}return t=fe(t),e/=100,r/=100,[i(0),i(8),i(4),n]}(t)}}}(t);return e?new Pe(...e,!1):void 0}get rgb(){const{r:t,g:e,b:r,a:n}=this,i=n||1/0;return this.overwriteGetter(\"rgb\",[t/i,e/i,r/i,n])}get hcl(){return this.overwriteGetter(\"hcl\",function(t){const[e,r,n,i]=de(t),s=Math.sqrt(r*r+n*n);return [Math.round(1e4*s)?fe(Math.atan2(n,r)*pe):NaN,s,e,i]}(this.rgb))}get lab(){return this.overwriteGetter(\"lab\",de(this.rgb))}overwriteGetter(t,e){return Object.defineProperty(this,t,{value:e}),e}toString(){const[t,e,r,n]=this.rgb;return `rgba(${[t,e,r].map((t=>Math.round(255*t))).join(\",\")},${n})`}static interpolate(t,e,r,n=\"rgb\"){switch(n){case \"rgb\":{const[n,i,s,a]=ze(t.rgb,e.rgb,r);return new Pe(n,i,s,a,!1)}case \"hcl\":{const[n,i,s,a]=t.hcl,[o,l,u,c]=e.hcl;let h,p;if(isNaN(n)||isNaN(o))isNaN(n)?isNaN(o)?h=NaN:(h=o,1!==s&&0!==s||(p=l)):(h=n,1!==u&&0!==u||(p=i));else {let t=o-n;o>n&&t>180?t-=360:o<n&&n-o>180&&(t+=360),h=n+r*t;}const[f,d,y,m]=function([t,e,r,n]){return t=isNaN(t)?0:t*he,ge([r,Math.cos(t)*e,Math.sin(t)*e,n])}([h,null!=p?p:Ie(i,l,r),Ie(s,u,r),Ie(a,c,r)]);return new Pe(f,d,y,m,!1)}case \"lab\":{const[n,i,s,a]=ge(ze(t.lab,e.lab,r));return new Pe(n,i,s,a,!1)}}}}Pe.black=new Pe(0,0,0,1),Pe.white=new Pe(1,1,1,1),Pe.transparent=new Pe(0,0,0,0),Pe.red=new Pe(1,0,0,1);class Ce{constructor(t,e,r){this.sensitivity=t?e?\"variant\":\"case\":e?\"accent\":\"base\",this.locale=r,this.collator=new Intl.Collator(this.locale?this.locale:[],{sensitivity:this.sensitivity,usage:\"search\"});}compare(t,e){return this.collator.compare(t,e)}resolvedLocale(){return new Intl.Collator(this.locale?this.locale:[]).resolvedOptions().locale}}const Be=[\"bottom\",\"center\",\"top\"];class Ee{constructor(t,e,r,n,i,s){this.text=t,this.image=e,this.scale=r,this.fontStack=n,this.textColor=i,this.verticalAlign=s;}}class Te{constructor(t){this.sections=t;}static fromString(t){return new Te([new Ee(t,null,null,null,null,null)])}isEmpty(){return 0===this.sections.length||!this.sections.some((t=>0!==t.text.length||t.image&&0!==t.image.name.length))}static factory(t){return t instanceof Te?t:Te.fromString(t)}toString(){return 0===this.sections.length?\"\":this.sections.map((t=>t.text)).join(\"\")}}class Ve{constructor(t){this.values=t.slice();}static parse(t){if(t instanceof Ve)return t;if(\"number\"==typeof t)return new Ve([t,t,t,t]);if(Array.isArray(t)&&!(t.length<1||t.length>4)){for(const e of t)if(\"number\"!=typeof e)return;switch(t.length){case 1:t=[t[0],t[0],t[0],t[0]];break;case 2:t=[t[0],t[1],t[0],t[1]];break;case 3:t=[t[0],t[1],t[2],t[1]];}return new Ve(t)}}toString(){return JSON.stringify(this.values)}static interpolate(t,e,r){return new Ve(ze(t.values,e.values,r))}}class Fe{constructor(t){this.values=t.slice();}static parse(t){if(t instanceof Fe)return t;if(\"number\"==typeof t)return new Fe([t]);if(Array.isArray(t)){for(const e of t)if(\"number\"!=typeof e)return;return new Fe(t)}}toString(){return JSON.stringify(this.values)}static interpolate(t,e,r){return new Fe(ze(t.values,e.values,r))}}class Le{constructor(t){this.values=t.slice();}static parse(t){if(t instanceof Le)return t;if(\"string\"==typeof t){const e=Pe.parse(t);if(!e)return;return new Le([e])}if(!Array.isArray(t))return;const e=[];for(const r of t){if(\"string\"!=typeof r)return;const t=Pe.parse(r);if(!t)return;e.push(t);}return new Le(e)}toString(){return JSON.stringify(this.values)}static interpolate(t,e,r,n=\"rgb\"){const i=[];if(t.values.length!=e.values.length)throw new Error(`colorArray: Arrays have mismatched length (${t.values.length} vs. ${e.values.length}), cannot interpolate.`);for(let s=0;s<t.values.length;s++)i.push(Pe.interpolate(t.values[s],e.values[s],r,n));return new Le(i)}}class $e extends Error{constructor(t){super(t),this.name=\"RuntimeError\";}toJSON(){return this.message}}const De=new Set([\"center\",\"left\",\"right\",\"top\",\"bottom\",\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"]);class Oe{constructor(t){this.values=t.slice();}static parse(t){if(t instanceof Oe)return t;if(Array.isArray(t)&&!(t.length<1)&&t.length%2==0){for(let e=0;e<t.length;e+=2){const r=t[e],n=t[e+1];if(\"string\"!=typeof r||!De.has(r))return;if(!Array.isArray(n)||2!==n.length||\"number\"!=typeof n[0]||\"number\"!=typeof n[1])return}return new Oe(t)}}toString(){return JSON.stringify(this.values)}static interpolate(t,e,r){const n=t.values,i=e.values;if(n.length!==i.length)throw new $e(`Cannot interpolate values of different length. from: ${t.toString()}, to: ${e.toString()}`);const s=[];for(let t=0;t<n.length;t+=2){if(n[t]!==i[t])throw new $e(`Cannot interpolate values containing mismatched anchors. from[${t}]: ${n[t]}, to[${t}]: ${i[t]}`);s.push(n[t]);const[e,a]=n[t+1],[o,l]=i[t+1];s.push([Ie(e,o,r),Ie(a,l,r)]);}return new Oe(s)}}class Re{constructor(t){this.name=t.name,this.available=t.available;}toString(){return this.name}static fromString(t){return t?new Re({name:t,available:!1}):null}}class je{constructor(t,e,r){this.from=t,this.to=e,this.transition=r;}static interpolate(t,e,r){return new je(t,e,r)}static parse(t){return t instanceof je?t:Array.isArray(t)&&3===t.length&&\"string\"==typeof t[0]&&\"string\"==typeof t[1]&&\"number\"==typeof t[2]?new je(t[0],t[1],t[2]):\"object\"==typeof t&&\"string\"==typeof t.from&&\"string\"==typeof t.to&&\"number\"==typeof t.transition?new je(t.from,t.to,t.transition):\"string\"==typeof t?new je(t,t,1):void 0}}function Ne(t,e,r,n){return \"number\"==typeof t&&t>=0&&t<=255&&\"number\"==typeof e&&e>=0&&e<=255&&\"number\"==typeof r&&r>=0&&r<=255?void 0===n||\"number\"==typeof n&&n>=0&&n<=1?null:`Invalid rgba value [${[t,e,r,n].join(\", \")}]: 'a' must be between 0 and 1.`:`Invalid rgba value [${(\"number\"==typeof n?[t,e,r,n]:[t,e,r]).join(\", \")}]: 'r', 'g', and 'b' must be between 0 and 255.`}function Ue(t){if(null===t||\"string\"==typeof t||\"boolean\"==typeof t||\"number\"==typeof t||t instanceof je||t instanceof Pe||t instanceof Ce||t instanceof Te||t instanceof Ve||t instanceof Fe||t instanceof Le||t instanceof Oe||t instanceof Re)return !0;if(Array.isArray(t)){for(const e of t)if(!Ue(e))return !1;return !0}if(\"object\"==typeof t){for(const e in t)if(!Ue(t[e]))return !1;return !0}return !1}function qe(t){if(null===t)return $t;if(\"string\"==typeof t)return Ot;if(\"boolean\"==typeof t)return Rt;if(\"number\"==typeof t)return Dt;if(t instanceof Pe)return jt;if(t instanceof je)return Nt;if(t instanceof Ce)return Gt;if(t instanceof Te)return Xt;if(t instanceof Ve)return Zt;if(t instanceof Fe)return Ht;if(t instanceof Le)return Yt;if(t instanceof Oe)return Jt;if(t instanceof Re)return Kt;if(Array.isArray(t)){const e=t.length;let r;for(const e of t){const t=qe(e);if(r){if(r===t)continue;r=qt;break}r=t;}return Wt(r||qt,e)}return Ut}function Ge(t){const e=typeof t;return null===t?\"\":\"string\"===e||\"number\"===e||\"boolean\"===e?String(t):t instanceof Pe||t instanceof je||t instanceof Te||t instanceof Ve||t instanceof Fe||t instanceof Le||t instanceof Oe||t instanceof Re?t.toString():JSON.stringify(t)}class Xe{constructor(t,e){this.type=t,this.value=e;}static parse(t,e){if(2!==t.length)return e.error(`'literal' expression requires exactly one argument, but found ${t.length-1} instead.`);if(!Ue(t[1]))return e.error(\"invalid value\");const r=t[1];let n=qe(r);const i=e.expectedType;return \"array\"!==n.kind||0!==n.N||!i||\"array\"!==i.kind||\"number\"==typeof i.N&&0!==i.N||(n=i),new Xe(n,r)}evaluate(){return this.value}eachChild(){}outputDefined(){return !0}}const Ze={string:Ot,number:Dt,boolean:Rt,object:Ut};class Ye{constructor(t,e){this.type=t,this.args=e;}static parse(t,e){if(t.length<2)return e.error(\"Expected at least one argument.\");let r,n=1;const i=t[0];if(\"array\"===i){let i,s;if(t.length>2){const r=t[1];if(\"string\"!=typeof r||!(r in Ze)||\"object\"===r)return e.error('The item type argument of \"array\" must be one of string, number, boolean',1);i=Ze[r],n++;}else i=qt;if(t.length>3){if(null!==t[2]&&(\"number\"!=typeof t[2]||t[2]<0||t[2]!==Math.floor(t[2])))return e.error('The length argument to \"array\" must be a positive integer literal',2);s=t[2],n++;}r=Wt(i,s);}else {if(!Ze[i])throw new Error(`Types doesn't contain name = ${i}`);r=Ze[i];}const s=[];for(;n<t.length;n++){const r=e.parse(t[n],n,qt);if(!r)return null;s.push(r);}return new Ye(r,s)}evaluate(t){for(let e=0;e<this.args.length;e++){const r=this.args[e].evaluate(t);if(!ee(this.type,qe(r)))return r;if(e===this.args.length-1)throw new $e(`Expected value to be of type ${Qt(this.type)}, but found ${Qt(qe(r))} instead.`)}throw new Error}eachChild(t){this.args.forEach(t);}outputDefined(){return this.args.every((t=>t.outputDefined()))}}const He={\"to-boolean\":Rt,\"to-color\":jt,\"to-number\":Dt,\"to-string\":Ot};class Ke{constructor(t,e){this.type=t,this.args=e;}static parse(t,e){if(t.length<2)return e.error(\"Expected at least one argument.\");const r=t[0];if(!He[r])throw new Error(`Can't parse ${r} as it is not part of the known types`);if((\"to-boolean\"===r||\"to-string\"===r)&&2!==t.length)return e.error(\"Expected one argument.\");const n=He[r],i=[];for(let r=1;r<t.length;r++){const n=e.parse(t[r],r,qt);if(!n)return null;i.push(n);}return new Ke(n,i)}evaluate(t){switch(this.type.kind){case \"boolean\":return Boolean(this.args[0].evaluate(t));case \"color\":{let e,r;for(const n of this.args){if(e=n.evaluate(t),r=null,e instanceof Pe)return e;if(\"string\"==typeof e){const r=t.parseColor(e);if(r)return r}else if(Array.isArray(e)&&(r=e.length<3||e.length>4?`Invalid rgba value ${JSON.stringify(e)}: expected an array containing either three or four numeric values.`:Ne(e[0],e[1],e[2],e[3]),!r))return new Pe(e[0]/255,e[1]/255,e[2]/255,e[3])}throw new $e(r||`Could not parse color from value '${\"string\"==typeof e?e:JSON.stringify(e)}'`)}case \"padding\":{let e;for(const r of this.args){e=r.evaluate(t);const n=Ve.parse(e);if(n)return n}throw new $e(`Could not parse padding from value '${\"string\"==typeof e?e:JSON.stringify(e)}'`)}case \"numberArray\":{let e;for(const r of this.args){e=r.evaluate(t);const n=Fe.parse(e);if(n)return n}throw new $e(`Could not parse numberArray from value '${\"string\"==typeof e?e:JSON.stringify(e)}'`)}case \"colorArray\":{let e;for(const r of this.args){e=r.evaluate(t);const n=Le.parse(e);if(n)return n}throw new $e(`Could not parse colorArray from value '${\"string\"==typeof e?e:JSON.stringify(e)}'`)}case \"variableAnchorOffsetCollection\":{let e;for(const r of this.args){e=r.evaluate(t);const n=Oe.parse(e);if(n)return n}throw new $e(`Could not parse variableAnchorOffsetCollection from value '${\"string\"==typeof e?e:JSON.stringify(e)}'`)}case \"number\":{let e=null;for(const r of this.args){if(e=r.evaluate(t),null===e)return 0;const n=Number(e);if(!isNaN(n))return n}throw new $e(`Could not convert ${JSON.stringify(e)} to number.`)}case \"formatted\":return Te.fromString(Ge(this.args[0].evaluate(t)));case \"resolvedImage\":return Re.fromString(Ge(this.args[0].evaluate(t)));case \"projectionDefinition\":return this.args[0].evaluate(t);default:return Ge(this.args[0].evaluate(t))}}eachChild(t){this.args.forEach(t);}outputDefined(){return this.args.every((t=>t.outputDefined()))}}const Je=[\"Unknown\",\"Point\",\"LineString\",\"Polygon\"];class We{constructor(){this.globals=null,this.feature=null,this.featureState=null,this.formattedSection=null,this._parseColorCache=new Map,this.availableImages=null,this.canonical=null;}id(){return this.feature&&\"id\"in this.feature?this.feature.id:null}geometryType(){return this.feature?\"number\"==typeof this.feature.type?Je[this.feature.type]:this.feature.type:null}geometry(){return this.feature&&\"geometry\"in this.feature?this.feature.geometry:null}canonicalID(){return this.canonical}properties(){return this.feature&&this.feature.properties||{}}parseColor(t){let e=this._parseColorCache.get(t);return e||(e=Pe.parse(t),this._parseColorCache.set(t,e)),e}}class Qe{constructor(t,e,r=[],n,i=new Lt,s=[]){this.registry=t,this.path=r,this.key=r.map((t=>`[${t}]`)).join(\"\"),this.scope=i,this.errors=s,this.expectedType=n,this._isConstant=e;}parse(t,e,r,n,i={}){return e?this.concat(e,r,n)._parse(t,i):this._parse(t,i)}_parse(t,e){function r(t,e,r){return \"assert\"===r?new Ye(e,[t]):\"coerce\"===r?new Ke(e,[t]):t}if(null!==t&&\"string\"!=typeof t&&\"boolean\"!=typeof t&&\"number\"!=typeof t||(t=[\"literal\",t]),Array.isArray(t)){if(0===t.length)return this.error('Expected an array with at least one element. If you wanted a literal array, use [\"literal\", []].');const n=t[0];if(\"string\"!=typeof n)return this.error(`Expression name must be a string, but found ${typeof n} instead. If you wanted a literal array, use [\"literal\", [...]].`,0),null;const i=this.registry[n];if(i){let n=i.parse(t,this);if(!n)return null;if(this.expectedType){const t=this.expectedType,i=n.type;if(\"string\"!==t.kind&&\"number\"!==t.kind&&\"boolean\"!==t.kind&&\"object\"!==t.kind&&\"array\"!==t.kind||\"value\"!==i.kind){if(\"projectionDefinition\"===t.kind&&[\"string\",\"array\"].includes(i.kind)||[\"color\",\"formatted\",\"resolvedImage\"].includes(t.kind)&&[\"value\",\"string\"].includes(i.kind)||[\"padding\",\"numberArray\"].includes(t.kind)&&[\"value\",\"number\",\"array\"].includes(i.kind)||\"colorArray\"===t.kind&&[\"value\",\"string\",\"array\"].includes(i.kind)||\"variableAnchorOffsetCollection\"===t.kind&&[\"value\",\"array\"].includes(i.kind))n=r(n,t,e.typeAnnotation||\"coerce\");else if(this.checkSubtype(t,i))return null}else n=r(n,t,e.typeAnnotation||\"assert\");}if(!(n instanceof Xe)&&\"resolvedImage\"!==n.type.kind&&this._isConstant(n)){const t=new We;try{n=new Xe(n.type,n.evaluate(t));}catch(t){return this.error(t.message),null}}return n}return this.error(`Unknown expression \"${n}\". If you wanted a literal array, use [\"literal\", [...]].`,0)}return this.error(void 0===t?\"'undefined' value invalid. Use null instead.\":\"object\"==typeof t?'Bare objects invalid. Use [\"literal\", {...}] instead.':`Expected an array, but found ${typeof t} instead.`)}concat(t,e,r){const n=\"number\"==typeof t?this.path.concat(t):this.path,i=r?this.scope.concat(r):this.scope;return new Qe(this.registry,this._isConstant,n,e||null,i,this.errors)}error(t,...e){const r=`${this.key}${e.map((t=>`[${t}]`)).join(\"\")}`;this.errors.push(new Ft(r,t));}checkSubtype(t,e){const r=ee(t,e);return r&&this.error(r),r}}class tr{constructor(t,e){this.type=e.type,this.bindings=[].concat(t),this.result=e;}evaluate(t){return this.result.evaluate(t)}eachChild(t){for(const e of this.bindings)t(e[1]);t(this.result);}static parse(t,e){if(t.length<4)return e.error(`Expected at least 3 arguments, but found ${t.length-1} instead.`);const r=[];for(let n=1;n<t.length-1;n+=2){const i=t[n];if(\"string\"!=typeof i)return e.error(`Expected string, but found ${typeof i} instead.`,n);if(/[^a-zA-Z0-9_]/.test(i))return e.error(\"Variable names must contain only alphanumeric characters or '_'.\",n);const s=e.parse(t[n+1],n+1);if(!s)return null;r.push([i,s]);}const n=e.parse(t[t.length-1],t.length-1,e.expectedType,r);return n?new tr(r,n):null}outputDefined(){return this.result.outputDefined()}}class er{constructor(t,e){this.type=e.type,this.name=t,this.boundExpression=e;}static parse(t,e){if(2!==t.length||\"string\"!=typeof t[1])return e.error(\"'var' expression requires exactly one string literal argument.\");const r=t[1];return e.scope.has(r)?new er(r,e.scope.get(r)):e.error(`Unknown variable \"${r}\". Make sure \"${r}\" has been bound in an enclosing \"let\" expression before using it.`,1)}evaluate(t){return this.boundExpression.evaluate(t)}eachChild(){}outputDefined(){return !1}}class rr{constructor(t,e,r){this.type=t,this.index=e,this.input=r;}static parse(t,e){if(3!==t.length)return e.error(`Expected 2 arguments, but found ${t.length-1} instead.`);const r=e.parse(t[1],1,Dt),n=e.parse(t[2],2,Wt(e.expectedType||qt));return r&&n?new rr(n.type.itemType,r,n):null}evaluate(t){const e=this.index.evaluate(t),r=this.input.evaluate(t);if(e<0)throw new $e(`Array index out of bounds: ${e} < 0.`);if(e>=r.length)throw new $e(`Array index out of bounds: ${e} > ${r.length-1}.`);if(e!==Math.floor(e))throw new $e(`Array index must be an integer, but found ${e} instead.`);return r[e]}eachChild(t){t(this.index),t(this.input);}outputDefined(){return !1}}class nr{constructor(t,e){this.type=Rt,this.needle=t,this.haystack=e;}static parse(t,e){if(3!==t.length)return e.error(`Expected 2 arguments, but found ${t.length-1} instead.`);const r=e.parse(t[1],1,qt),n=e.parse(t[2],2,qt);return r&&n?re(r.type,[Rt,Ot,Dt,$t,qt])?new nr(r,n):e.error(`Expected first argument to be of type boolean, string, number or null, but found ${Qt(r.type)} instead`):null}evaluate(t){const e=this.needle.evaluate(t),r=this.haystack.evaluate(t);if(!r)return !1;if(!ne(e,[\"boolean\",\"string\",\"number\",\"null\"]))throw new $e(`Expected first argument to be of type boolean, string, number or null, but found ${Qt(qe(e))} instead.`);if(!ne(r,[\"string\",\"array\"]))throw new $e(`Expected second argument to be of type array or string, but found ${Qt(qe(r))} instead.`);return r.indexOf(e)>=0}eachChild(t){t(this.needle),t(this.haystack);}outputDefined(){return !0}}class ir{constructor(t,e,r){this.type=Dt,this.needle=t,this.haystack=e,this.fromIndex=r;}static parse(t,e){if(t.length<=2||t.length>=5)return e.error(`Expected 3 or 4 arguments, but found ${t.length-1} instead.`);const r=e.parse(t[1],1,qt),n=e.parse(t[2],2,qt);if(!r||!n)return null;if(!re(r.type,[Rt,Ot,Dt,$t,qt]))return e.error(`Expected first argument to be of type boolean, string, number or null, but found ${Qt(r.type)} instead`);if(4===t.length){const i=e.parse(t[3],3,Dt);return i?new ir(r,n,i):null}return new ir(r,n)}evaluate(t){const e=this.needle.evaluate(t),r=this.haystack.evaluate(t);if(!ne(e,[\"boolean\",\"string\",\"number\",\"null\"]))throw new $e(`Expected first argument to be of type boolean, string, number or null, but found ${Qt(qe(e))} instead.`);let n;if(this.fromIndex&&(n=this.fromIndex.evaluate(t)),ne(r,[\"string\"])){const t=r.indexOf(e,n);return -1===t?-1:[...r.slice(0,t)].length}if(ne(r,[\"array\"]))return r.indexOf(e,n);throw new $e(`Expected second argument to be of type array or string, but found ${Qt(qe(r))} instead.`)}eachChild(t){t(this.needle),t(this.haystack),this.fromIndex&&t(this.fromIndex);}outputDefined(){return !1}}class sr{constructor(t,e,r,n,i,s){this.inputType=t,this.type=e,this.input=r,this.cases=n,this.outputs=i,this.otherwise=s;}static parse(t,e){if(t.length<5)return e.error(`Expected at least 4 arguments, but found only ${t.length-1}.`);if(t.length%2!=1)return e.error(\"Expected an even number of arguments.\");let r,n;e.expectedType&&\"value\"!==e.expectedType.kind&&(n=e.expectedType);const i={},s=[];for(let a=2;a<t.length-1;a+=2){let o=t[a];const l=t[a+1];Array.isArray(o)||(o=[o]);const u=e.concat(a);if(0===o.length)return u.error(\"Expected at least one branch label.\");for(const t of o){if(\"number\"!=typeof t&&\"string\"!=typeof t)return u.error(\"Branch labels must be numbers or strings.\");if(\"number\"==typeof t&&Math.abs(t)>Number.MAX_SAFE_INTEGER)return u.error(`Branch labels must be integers no larger than ${Number.MAX_SAFE_INTEGER}.`);if(\"number\"==typeof t&&Math.floor(t)!==t)return u.error(\"Numeric branch labels must be integer values.\");if(r){if(u.checkSubtype(r,qe(t)))return null}else r=qe(t);if(void 0!==i[String(t)])return u.error(\"Branch labels must be unique.\");i[String(t)]=s.length;}const c=e.parse(l,a,n);if(!c)return null;n=n||c.type,s.push(c);}const a=e.parse(t[1],1,qt);if(!a)return null;const o=e.parse(t[t.length-1],t.length-1,n);return o?\"value\"!==a.type.kind&&e.concat(1).checkSubtype(r,a.type)?null:new sr(r,n,a,i,s,o):null}evaluate(t){const e=this.input.evaluate(t);return (qe(e)===this.inputType&&this.outputs[this.cases[e]]||this.otherwise).evaluate(t)}eachChild(t){t(this.input),this.outputs.forEach(t),t(this.otherwise);}outputDefined(){return this.outputs.every((t=>t.outputDefined()))&&this.otherwise.outputDefined()}}class ar{constructor(t,e,r){this.type=t,this.branches=e,this.otherwise=r;}static parse(t,e){if(t.length<4)return e.error(`Expected at least 3 arguments, but found only ${t.length-1}.`);if(t.length%2!=0)return e.error(\"Expected an odd number of arguments.\");let r;e.expectedType&&\"value\"!==e.expectedType.kind&&(r=e.expectedType);const n=[];for(let i=1;i<t.length-1;i+=2){const s=e.parse(t[i],i,Rt);if(!s)return null;const a=e.parse(t[i+1],i+1,r);if(!a)return null;n.push([s,a]),r=r||a.type;}const i=e.parse(t[t.length-1],t.length-1,r);if(!i)return null;if(!r)throw new Error(\"Can't infer output type\");return new ar(r,n,i)}evaluate(t){for(const[e,r]of this.branches)if(e.evaluate(t))return r.evaluate(t);return this.otherwise.evaluate(t)}eachChild(t){for(const[e,r]of this.branches)t(e),t(r);t(this.otherwise);}outputDefined(){return this.branches.every((([t,e])=>e.outputDefined()))&&this.otherwise.outputDefined()}}class or{constructor(t,e,r,n){this.type=t,this.input=e,this.beginIndex=r,this.endIndex=n;}static parse(t,e){if(t.length<=2||t.length>=5)return e.error(`Expected 3 or 4 arguments, but found ${t.length-1} instead.`);const r=e.parse(t[1],1,qt),n=e.parse(t[2],2,Dt);if(!r||!n)return null;if(!re(r.type,[Wt(qt),Ot,qt]))return e.error(`Expected first argument to be of type array or string, but found ${Qt(r.type)} instead`);if(4===t.length){const i=e.parse(t[3],3,Dt);return i?new or(r.type,r,n,i):null}return new or(r.type,r,n)}evaluate(t){const e=this.input.evaluate(t),r=this.beginIndex.evaluate(t);let n;if(this.endIndex&&(n=this.endIndex.evaluate(t)),ne(e,[\"string\"]))return [...e].slice(r,n).join(\"\");if(ne(e,[\"array\"]))return e.slice(r,n);throw new $e(`Expected first argument to be of type array or string, but found ${Qt(qe(e))} instead.`)}eachChild(t){t(this.input),t(this.beginIndex),this.endIndex&&t(this.endIndex);}outputDefined(){return !1}}function lr(t,e){const r=t.length-1;let n,i,s=0,a=r,o=0;for(;s<=a;)if(o=Math.floor((s+a)/2),n=t[o],i=t[o+1],n<=e){if(o===r||e<i)return o;s=o+1;}else {if(!(n>e))throw new $e(\"Input is not a number.\");a=o-1;}return 0}class ur{constructor(t,e,r){this.type=t,this.input=e,this.labels=[],this.outputs=[];for(const[t,e]of r)this.labels.push(t),this.outputs.push(e);}static parse(t,e){if(t.length-1<4)return e.error(`Expected at least 4 arguments, but found only ${t.length-1}.`);if((t.length-1)%2!=0)return e.error(\"Expected an even number of arguments.\");const r=e.parse(t[1],1,Dt);if(!r)return null;const n=[];let i=null;e.expectedType&&\"value\"!==e.expectedType.kind&&(i=e.expectedType);for(let r=1;r<t.length;r+=2){const s=1===r?-1/0:t[r],a=t[r+1],o=r,l=r+1;if(\"number\"!=typeof s)return e.error('Input/output pairs for \"step\" expressions must be defined using literal numeric values (not computed expressions) for the input values.',o);if(n.length&&n[n.length-1][0]>=s)return e.error('Input/output pairs for \"step\" expressions must be arranged with input values in strictly ascending order.',o);const u=e.parse(a,l,i);if(!u)return null;i=i||u.type,n.push([s,u]);}return new ur(i,r,n)}evaluate(t){const e=this.labels,r=this.outputs;if(1===e.length)return r[0].evaluate(t);const n=this.input.evaluate(t);if(n<=e[0])return r[0].evaluate(t);const i=e.length;return n>=e[i-1]?r[i-1].evaluate(t):r[lr(e,n)].evaluate(t)}eachChild(t){t(this.input);for(const e of this.outputs)t(e);}outputDefined(){return this.outputs.every((t=>t.outputDefined()))}}function cr(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,\"default\")?t.default:t}var hr,pr,fr=function(){if(pr)return hr;function t(t,e,r,n){this.cx=3*t,this.bx=3*(r-t)-this.cx,this.ax=1-this.cx-this.bx,this.cy=3*e,this.by=3*(n-e)-this.cy,this.ay=1-this.cy-this.by,this.p1x=t,this.p1y=e,this.p2x=r,this.p2y=n;}return pr=1,hr=t,t.prototype={sampleCurveX:function(t){return ((this.ax*t+this.bx)*t+this.cx)*t},sampleCurveY:function(t){return ((this.ay*t+this.by)*t+this.cy)*t},sampleCurveDerivativeX:function(t){return (3*this.ax*t+2*this.bx)*t+this.cx},solveCurveX:function(t,e){if(void 0===e&&(e=1e-6),t<0)return 0;if(t>1)return 1;for(var r=t,n=0;n<8;n++){var i=this.sampleCurveX(r)-t;if(Math.abs(i)<e)return r;var s=this.sampleCurveDerivativeX(r);if(Math.abs(s)<1e-6)break;r-=i/s;}var a=0,o=1;for(r=t,n=0;n<20&&(i=this.sampleCurveX(r),!(Math.abs(i-t)<e));n++)t>i?a=r:o=r,r=.5*(o-a)+a;return r},solve:function(t,e){return this.sampleCurveY(this.solveCurveX(t,e))}},hr}(),dr=cr(fr);class yr{constructor(t,e,r,n,i){this.type=t,this.operator=e,this.interpolation=r,this.input=n,this.labels=[],this.outputs=[];for(const[t,e]of i)this.labels.push(t),this.outputs.push(e);}static interpolationFactor(t,e,r,n){let i=0;if(\"exponential\"===t.name)i=mr(e,t.base,r,n);else if(\"linear\"===t.name)i=mr(e,1,r,n);else if(\"cubic-bezier\"===t.name){const s=t.controlPoints;i=new dr(s[0],s[1],s[2],s[3]).solve(mr(e,1,r,n));}return i}static parse(t,e){let[r,n,i,...s]=t;if(!Array.isArray(n)||0===n.length)return e.error(\"Expected an interpolation type expression.\",1);if(\"linear\"===n[0])n={name:\"linear\"};else if(\"exponential\"===n[0]){const t=n[1];if(\"number\"!=typeof t)return e.error(\"Exponential interpolation requires a numeric base.\",1,1);n={name:\"exponential\",base:t};}else {if(\"cubic-bezier\"!==n[0])return e.error(`Unknown interpolation type ${String(n[0])}`,1,0);{const t=n.slice(1);if(4!==t.length||t.some((t=>\"number\"!=typeof t||t<0||t>1)))return e.error(\"Cubic bezier interpolation requires four numeric arguments with values between 0 and 1.\",1);n={name:\"cubic-bezier\",controlPoints:t};}}if(t.length-1<4)return e.error(`Expected at least 4 arguments, but found only ${t.length-1}.`);if((t.length-1)%2!=0)return e.error(\"Expected an even number of arguments.\");if(i=e.parse(i,2,Dt),!i)return null;const a=[];let o=null;\"interpolate-hcl\"!==r&&\"interpolate-lab\"!==r||e.expectedType==Yt?e.expectedType&&\"value\"!==e.expectedType.kind&&(o=e.expectedType):o=jt;for(let t=0;t<s.length;t+=2){const r=s[t],n=s[t+1],i=t+3,l=t+4;if(\"number\"!=typeof r)return e.error('Input/output pairs for \"interpolate\" expressions must be defined using literal numeric values (not computed expressions) for the input values.',i);if(a.length&&a[a.length-1][0]>=r)return e.error('Input/output pairs for \"interpolate\" expressions must be arranged with input values in strictly ascending order.',i);const u=e.parse(n,l,o);if(!u)return null;o=o||u.type,a.push([r,u]);}return ie(o,Dt)||ie(o,Nt)||ie(o,jt)||ie(o,Zt)||ie(o,Ht)||ie(o,Yt)||ie(o,Jt)||ie(o,Wt(Dt))?new yr(o,r,n,i,a):e.error(`Type ${Qt(o)} is not interpolatable.`)}evaluate(t){const e=this.labels,r=this.outputs;if(1===e.length)return r[0].evaluate(t);const n=this.input.evaluate(t);if(n<=e[0])return r[0].evaluate(t);const i=e.length;if(n>=e[i-1])return r[i-1].evaluate(t);const s=lr(e,n),a=yr.interpolationFactor(this.interpolation,n,e[s],e[s+1]),o=r[s].evaluate(t),l=r[s+1].evaluate(t);switch(this.operator){case \"interpolate\":switch(this.type.kind){case \"number\":return Ie(o,l,a);case \"color\":return Pe.interpolate(o,l,a);case \"padding\":return Ve.interpolate(o,l,a);case \"colorArray\":return Le.interpolate(o,l,a);case \"numberArray\":return Fe.interpolate(o,l,a);case \"variableAnchorOffsetCollection\":return Oe.interpolate(o,l,a);case \"array\":return ze(o,l,a);case \"projectionDefinition\":return je.interpolate(o,l,a)}case \"interpolate-hcl\":switch(this.type.kind){case \"color\":return Pe.interpolate(o,l,a,\"hcl\");case \"colorArray\":return Le.interpolate(o,l,a,\"hcl\")}case \"interpolate-lab\":switch(this.type.kind){case \"color\":return Pe.interpolate(o,l,a,\"lab\");case \"colorArray\":return Le.interpolate(o,l,a,\"lab\")}}}eachChild(t){t(this.input);for(const e of this.outputs)t(e);}outputDefined(){return this.outputs.every((t=>t.outputDefined()))}}function mr(t,e,r,n){const i=n-r,s=t-r;return 0===i?0:1===e?s/i:(Math.pow(e,s)-1)/(Math.pow(e,i)-1)}const gr={color:Pe.interpolate,number:Ie,padding:Ve.interpolate,numberArray:Fe.interpolate,colorArray:Le.interpolate,variableAnchorOffsetCollection:Oe.interpolate,array:ze};class xr{constructor(t,e){this.type=t,this.args=e;}static parse(t,e){if(t.length<2)return e.error(\"Expected at least one argument.\");let r=null;const n=e.expectedType;n&&\"value\"!==n.kind&&(r=n);const i=[];for(const n of t.slice(1)){const t=e.parse(n,1+i.length,r,void 0,{typeAnnotation:\"omit\"});if(!t)return null;r=r||t.type,i.push(t);}if(!r)throw new Error(\"No output type\");const s=n&&i.some((t=>ee(n,t.type)));return new xr(s?qt:r,i)}evaluate(t){let e,r=null,n=0;for(const i of this.args)if(n++,r=i.evaluate(t),r&&r instanceof Re&&!r.available&&(e||(e=r.name),r=null,n===this.args.length&&(r=e)),null!==r)break;return r}eachChild(t){this.args.forEach(t);}outputDefined(){return this.args.every((t=>t.outputDefined()))}}function vr(t,e){return \"==\"===t||\"!=\"===t?\"boolean\"===e.kind||\"string\"===e.kind||\"number\"===e.kind||\"null\"===e.kind||\"value\"===e.kind:\"string\"===e.kind||\"number\"===e.kind||\"value\"===e.kind}function br(t,e,r,n){return 0===n.compare(e,r)}function wr(t,e,r){const n=\"==\"!==t&&\"!=\"!==t;return class i{constructor(t,e,r){this.type=Rt,this.lhs=t,this.rhs=e,this.collator=r,this.hasUntypedArgument=\"value\"===t.type.kind||\"value\"===e.type.kind;}static parse(t,e){if(3!==t.length&&4!==t.length)return e.error(\"Expected two or three arguments.\");const r=t[0];let s=e.parse(t[1],1,qt);if(!s)return null;if(!vr(r,s.type))return e.concat(1).error(`\"${r}\" comparisons are not supported for type '${Qt(s.type)}'.`);let a=e.parse(t[2],2,qt);if(!a)return null;if(!vr(r,a.type))return e.concat(2).error(`\"${r}\" comparisons are not supported for type '${Qt(a.type)}'.`);if(s.type.kind!==a.type.kind&&\"value\"!==s.type.kind&&\"value\"!==a.type.kind)return e.error(`Cannot compare types '${Qt(s.type)}' and '${Qt(a.type)}'.`);n&&(\"value\"===s.type.kind&&\"value\"!==a.type.kind?s=new Ye(a.type,[s]):\"value\"!==s.type.kind&&\"value\"===a.type.kind&&(a=new Ye(s.type,[a])));let o=null;if(4===t.length){if(\"string\"!==s.type.kind&&\"string\"!==a.type.kind&&\"value\"!==s.type.kind&&\"value\"!==a.type.kind)return e.error(\"Cannot use collator to compare non-string types.\");if(o=e.parse(t[3],3,Gt),!o)return null}return new i(s,a,o)}evaluate(i){const s=this.lhs.evaluate(i),a=this.rhs.evaluate(i);if(n&&this.hasUntypedArgument){const e=qe(s),r=qe(a);if(e.kind!==r.kind||\"string\"!==e.kind&&\"number\"!==e.kind)throw new $e(`Expected arguments for \"${t}\" to be (string, string) or (number, number), but found (${e.kind}, ${r.kind}) instead.`)}if(this.collator&&!n&&this.hasUntypedArgument){const t=qe(s),r=qe(a);if(\"string\"!==t.kind||\"string\"!==r.kind)return e(i,s,a)}return this.collator?r(i,s,a,this.collator.evaluate(i)):e(i,s,a)}eachChild(t){t(this.lhs),t(this.rhs),this.collator&&t(this.collator);}outputDefined(){return !0}}}const _r=wr(\"==\",(function(t,e,r){return e===r}),br),Sr=wr(\"!=\",(function(t,e,r){return e!==r}),(function(t,e,r,n){return !br(0,e,r,n)})),Ar=wr(\"<\",(function(t,e,r){return e<r}),(function(t,e,r,n){return n.compare(e,r)<0})),kr=wr(\">\",(function(t,e,r){return e>r}),(function(t,e,r,n){return n.compare(e,r)>0})),Mr=wr(\"<=\",(function(t,e,r){return e<=r}),(function(t,e,r,n){return n.compare(e,r)<=0})),Ir=wr(\">=\",(function(t,e,r){return e>=r}),(function(t,e,r,n){return n.compare(e,r)>=0}));class zr{constructor(t,e,r){this.type=Gt,this.locale=r,this.caseSensitive=t,this.diacriticSensitive=e;}static parse(t,e){if(2!==t.length)return e.error(\"Expected one argument.\");const r=t[1];if(\"object\"!=typeof r||Array.isArray(r))return e.error(\"Collator options argument must be an object.\");const n=e.parse(void 0!==r[\"case-sensitive\"]&&r[\"case-sensitive\"],1,Rt);if(!n)return null;const i=e.parse(void 0!==r[\"diacritic-sensitive\"]&&r[\"diacritic-sensitive\"],1,Rt);if(!i)return null;let s=null;return r.locale&&(s=e.parse(r.locale,1,Ot),!s)?null:new zr(n,i,s)}evaluate(t){return new Ce(this.caseSensitive.evaluate(t),this.diacriticSensitive.evaluate(t),this.locale?this.locale.evaluate(t):null)}eachChild(t){t(this.caseSensitive),t(this.diacriticSensitive),this.locale&&t(this.locale);}outputDefined(){return !1}}class Pr{constructor(t,e,r,n,i){this.type=Ot,this.number=t,this.locale=e,this.currency=r,this.minFractionDigits=n,this.maxFractionDigits=i;}static parse(t,e){if(3!==t.length)return e.error(\"Expected two arguments.\");const r=e.parse(t[1],1,Dt);if(!r)return null;const n=t[2];if(\"object\"!=typeof n||Array.isArray(n))return e.error(\"NumberFormat options argument must be an object.\");let i=null;if(n.locale&&(i=e.parse(n.locale,1,Ot),!i))return null;let s=null;if(n.currency&&(s=e.parse(n.currency,1,Ot),!s))return null;let a=null;if(n[\"min-fraction-digits\"]&&(a=e.parse(n[\"min-fraction-digits\"],1,Dt),!a))return null;let o=null;return n[\"max-fraction-digits\"]&&(o=e.parse(n[\"max-fraction-digits\"],1,Dt),!o)?null:new Pr(r,i,s,a,o)}evaluate(t){return new Intl.NumberFormat(this.locale?this.locale.evaluate(t):[],{style:this.currency?\"currency\":\"decimal\",currency:this.currency?this.currency.evaluate(t):void 0,minimumFractionDigits:this.minFractionDigits?this.minFractionDigits.evaluate(t):void 0,maximumFractionDigits:this.maxFractionDigits?this.maxFractionDigits.evaluate(t):void 0}).format(this.number.evaluate(t))}eachChild(t){t(this.number),this.locale&&t(this.locale),this.currency&&t(this.currency),this.minFractionDigits&&t(this.minFractionDigits),this.maxFractionDigits&&t(this.maxFractionDigits);}outputDefined(){return !1}}class Cr{constructor(t){this.type=Xt,this.sections=t;}static parse(t,e){if(t.length<2)return e.error(\"Expected at least one argument.\");const r=t[1];if(!Array.isArray(r)&&\"object\"==typeof r)return e.error(\"First argument must be an image or text section.\");const n=[];let i=!1;for(let r=1;r<=t.length-1;++r){const s=t[r];if(i&&\"object\"==typeof s&&!Array.isArray(s)){i=!1;let t=null;if(s[\"font-scale\"]&&(t=e.parse(s[\"font-scale\"],1,Dt),!t))return null;let r=null;if(s[\"text-font\"]&&(r=e.parse(s[\"text-font\"],1,Wt(Ot)),!r))return null;let a=null;if(s[\"text-color\"]&&(a=e.parse(s[\"text-color\"],1,jt),!a))return null;let o=null;if(s[\"vertical-align\"]){if(\"string\"==typeof s[\"vertical-align\"]&&!Be.includes(s[\"vertical-align\"]))return e.error(`'vertical-align' must be one of: 'bottom', 'center', 'top' but found '${s[\"vertical-align\"]}' instead.`);if(o=e.parse(s[\"vertical-align\"],1,Ot),!o)return null}const l=n[n.length-1];l.scale=t,l.font=r,l.textColor=a,l.verticalAlign=o;}else {const s=e.parse(t[r],1,qt);if(!s)return null;const a=s.type.kind;if(\"string\"!==a&&\"value\"!==a&&\"null\"!==a&&\"resolvedImage\"!==a)return e.error(\"Formatted text type must be 'string', 'value', 'image' or 'null'.\");i=!0,n.push({content:s,scale:null,font:null,textColor:null,verticalAlign:null});}}return new Cr(n)}evaluate(t){return new Te(this.sections.map((e=>{const r=e.content.evaluate(t);return qe(r)===Kt?new Ee(\"\",r,null,null,null,e.verticalAlign?e.verticalAlign.evaluate(t):null):new Ee(Ge(r),null,e.scale?e.scale.evaluate(t):null,e.font?e.font.evaluate(t).join(\",\"):null,e.textColor?e.textColor.evaluate(t):null,e.verticalAlign?e.verticalAlign.evaluate(t):null)})))}eachChild(t){for(const e of this.sections)t(e.content),e.scale&&t(e.scale),e.font&&t(e.font),e.textColor&&t(e.textColor),e.verticalAlign&&t(e.verticalAlign);}outputDefined(){return !1}}class Br{constructor(t){this.type=Kt,this.input=t;}static parse(t,e){if(2!==t.length)return e.error(\"Expected two arguments.\");const r=e.parse(t[1],1,Ot);return r?new Br(r):e.error(\"No image name provided.\")}evaluate(t){const e=this.input.evaluate(t),r=Re.fromString(e);return r&&t.availableImages&&(r.available=t.availableImages.indexOf(e)>-1),r}eachChild(t){t(this.input);}outputDefined(){return !1}}class Er{constructor(t){this.type=Dt,this.input=t;}static parse(t,e){if(2!==t.length)return e.error(`Expected 1 argument, but found ${t.length-1} instead.`);const r=e.parse(t[1],1);return r?\"array\"!==r.type.kind&&\"string\"!==r.type.kind&&\"value\"!==r.type.kind?e.error(`Expected argument of type string or array, but found ${Qt(r.type)} instead.`):new Er(r):null}evaluate(t){const e=this.input.evaluate(t);if(\"string\"==typeof e)return [...e].length;if(Array.isArray(e))return e.length;throw new $e(`Expected value to be of type string or array, but found ${Qt(qe(e))} instead.`)}eachChild(t){t(this.input);}outputDefined(){return !1}}const Tr=8192;function Vr(t,e){const r=(180+t[0])/360,n=(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+t[1]*Math.PI/360)))/360,i=Math.pow(2,e.z);return [Math.round(r*i*Tr),Math.round(n*i*Tr)]}function Fr(t,e){const r=Math.pow(2,e.z);return [(i=(t[0]/Tr+e.x)/r,360*i-180),(n=(t[1]/Tr+e.y)/r,360/Math.PI*Math.atan(Math.exp((180-360*n)*Math.PI/180))-90)];var n,i;}function Lr(t,e){t[0]=Math.min(t[0],e[0]),t[1]=Math.min(t[1],e[1]),t[2]=Math.max(t[2],e[0]),t[3]=Math.max(t[3],e[1]);}function $r(t,e){return !(t[0]<=e[0]||t[2]>=e[2]||t[1]<=e[1]||t[3]>=e[3])}function Dr(t,e,r){const n=t[0]-e[0],i=t[1]-e[1],s=t[0]-r[0],a=t[1]-r[1];return n*a-s*i==0&&n*s<=0&&i*a<=0}function Or(t,e,r,n){return 0!=(i=[n[0]-r[0],n[1]-r[1]])[0]*(s=[e[0]-t[0],e[1]-t[1]])[1]-i[1]*s[0]&&!(!Gr(t,e,r,n)||!Gr(r,n,t,e));var i,s;}function Rr(t,e,r){for(const n of r)for(let r=0;r<n.length-1;++r)if(Or(t,e,n[r],n[r+1]))return !0;return !1}function jr(t,e,r=!1){let n=!1;for(const o of e)for(let e=0;e<o.length-1;e++){if(Dr(t,o[e],o[e+1]))return r;(s=o[e])[1]>(i=t)[1]!=(a=o[e+1])[1]>i[1]&&i[0]<(a[0]-s[0])*(i[1]-s[1])/(a[1]-s[1])+s[0]&&(n=!n);}var i,s,a;return n}function Nr(t,e){for(const r of e)if(jr(t,r))return !0;return !1}function Ur(t,e){for(const r of t)if(!jr(r,e))return !1;for(let r=0;r<t.length-1;++r)if(Rr(t[r],t[r+1],e))return !1;return !0}function qr(t,e){for(const r of e)if(Ur(t,r))return !0;return !1}function Gr(t,e,r,n){const i=n[0]-r[0],s=n[1]-r[1],a=(t[0]-r[0])*s-i*(t[1]-r[1]),o=(e[0]-r[0])*s-i*(e[1]-r[1]);return a>0&&o<0||a<0&&o>0}function Xr(t,e,r){const n=[];for(let i=0;i<t.length;i++){const s=[];for(let n=0;n<t[i].length;n++){const a=Vr(t[i][n],r);Lr(e,a),s.push(a);}n.push(s);}return n}function Zr(t,e,r){const n=[];for(let i=0;i<t.length;i++){const s=Xr(t[i],e,r);n.push(s);}return n}function Yr(t,e,r,n){if(t[0]<r[0]||t[0]>r[2]){const e=.5*n;let i=t[0]-r[0]>e?-n:r[0]-t[0]>e?n:0;0===i&&(i=t[0]-r[2]>e?-n:r[2]-t[0]>e?n:0),t[0]+=i;}Lr(e,t);}function Hr(t,e,r,n){const i=Math.pow(2,n.z)*Tr,s=[n.x*Tr,n.y*Tr],a=[];for(const n of t)for(const t of n){const n=[t.x+s[0],t.y+s[1]];Yr(n,e,r,i),a.push(n);}return a}function Kr(t,e,r,n){const i=Math.pow(2,n.z)*Tr,s=[n.x*Tr,n.y*Tr],a=[];for(const r of t){const t=[];for(const n of r){const r=[n.x+s[0],n.y+s[1]];Lr(e,r),t.push(r);}a.push(t);}if(e[2]-e[0]<=i/2){(o=e)[0]=o[1]=1/0,o[2]=o[3]=-1/0;for(const t of a)for(const n of t)Yr(n,e,r,i);}var o;return a}class Jr{constructor(t,e){this.type=Rt,this.geojson=t,this.geometries=e;}static parse(t,e){if(2!==t.length)return e.error(`'within' expression requires exactly one argument, but found ${t.length-1} instead.`);if(Ue(t[1])){const e=t[1];if(\"FeatureCollection\"===e.type){const t=[];for(const r of e.features){const{type:e,coordinates:n}=r.geometry;\"Polygon\"===e&&t.push(n),\"MultiPolygon\"===e&&t.push(...n);}if(t.length)return new Jr(e,{type:\"MultiPolygon\",coordinates:t})}else if(\"Feature\"===e.type){const t=e.geometry.type;if(\"Polygon\"===t||\"MultiPolygon\"===t)return new Jr(e,e.geometry)}else if(\"Polygon\"===e.type||\"MultiPolygon\"===e.type)return new Jr(e,e)}return e.error(\"'within' expression requires valid geojson object that contains polygon geometry type.\")}evaluate(t){if(null!=t.geometry()&&null!=t.canonicalID()){if(\"Point\"===t.geometryType())return function(t,e){const r=[1/0,1/0,-1/0,-1/0],n=[1/0,1/0,-1/0,-1/0],i=t.canonicalID();if(\"Polygon\"===e.type){const s=Xr(e.coordinates,n,i),a=Hr(t.geometry(),r,n,i);if(!$r(r,n))return !1;for(const t of a)if(!jr(t,s))return !1}if(\"MultiPolygon\"===e.type){const s=Zr(e.coordinates,n,i),a=Hr(t.geometry(),r,n,i);if(!$r(r,n))return !1;for(const t of a)if(!Nr(t,s))return !1}return !0}(t,this.geometries);if(\"LineString\"===t.geometryType())return function(t,e){const r=[1/0,1/0,-1/0,-1/0],n=[1/0,1/0,-1/0,-1/0],i=t.canonicalID();if(\"Polygon\"===e.type){const s=Xr(e.coordinates,n,i),a=Kr(t.geometry(),r,n,i);if(!$r(r,n))return !1;for(const t of a)if(!Ur(t,s))return !1}if(\"MultiPolygon\"===e.type){const s=Zr(e.coordinates,n,i),a=Kr(t.geometry(),r,n,i);if(!$r(r,n))return !1;for(const t of a)if(!qr(t,s))return !1}return !0}(t,this.geometries)}return !1}eachChild(){}outputDefined(){return !0}}let Wr=class{constructor(t=[],e=(t,e)=>t<e?-1:t>e?1:0){if(this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t);}push(t){this.data.push(t),this._up(this.length++);}pop(){if(0===this.length)return;const t=this.data[0],e=this.data.pop();return --this.length>0&&(this.data[0]=e,this._down(0)),t}peek(){return this.data[0]}_up(t){const{data:e,compare:r}=this,n=e[t];for(;t>0;){const i=t-1>>1,s=e[i];if(r(n,s)>=0)break;e[t]=s,t=i;}e[t]=n;}_down(t){const{data:e,compare:r}=this,n=this.length>>1,i=e[t];for(;t<n;){let n=1+(t<<1);const s=n+1;if(s<this.length&&r(e[s],e[n])<0&&(n=s),r(e[n],i)>=0)break;e[t]=e[n],t=n;}e[t]=i;}};function Qr(t,e,r=0,n=t.length-1,i=en){for(;n>r;){if(n-r>600){const s=n-r+1,a=e-r+1,o=Math.log(s),l=.5*Math.exp(2*o/3),u=.5*Math.sqrt(o*l*(s-l)/s)*(a-s/2<0?-1:1);Qr(t,e,Math.max(r,Math.floor(e-a*l/s+u)),Math.min(n,Math.floor(e+(s-a)*l/s+u)),i);}const s=t[e];let a=r,o=n;for(tn(t,r,e),i(t[n],s)>0&&tn(t,r,n);a<o;){for(tn(t,a,o),a++,o--;i(t[a],s)<0;)a++;for(;i(t[o],s)>0;)o--;}0===i(t[r],s)?tn(t,r,o):(o++,tn(t,o,n)),o<=e&&(r=o+1),e<=o&&(n=o-1);}}function tn(t,e,r){const n=t[e];t[e]=t[r],t[r]=n;}function en(t,e){return t<e?-1:t>e?1:0}function rn(t,e){if(t.length<=1)return [t];const r=[];let n,i;for(const e of t){const t=sn(e);0!==t&&(e.area=Math.abs(t),void 0===i&&(i=t<0),i===t<0?(n&&r.push(n),n=[e]):n.push(e));}if(n&&r.push(n),e>1)for(let t=0;t<r.length;t++)r[t].length<=e||(Qr(r[t],e,1,r[t].length-1,nn),r[t]=r[t].slice(0,e));return r}function nn(t,e){return e.area-t.area}function sn(t){let e=0;for(let r,n,i=0,s=t.length,a=s-1;i<s;a=i++)r=t[i],n=t[a],e+=(n.x-r.x)*(r.y+n.y);return e}const an=1/298.257223563,on=an*(2-an),ln=Math.PI/180;class un{constructor(t){const e=6378.137*ln*1e3,r=Math.cos(t*ln),n=1/(1-on*(1-r*r)),i=Math.sqrt(n);this.kx=e*i*r,this.ky=e*i*n*(1-on);}distance(t,e){const r=this.wrap(t[0]-e[0])*this.kx,n=(t[1]-e[1])*this.ky;return Math.sqrt(r*r+n*n)}pointOnLine(t,e){let r,n,i,s,a=1/0;for(let o=0;o<t.length-1;o++){let l=t[o][0],u=t[o][1],c=this.wrap(t[o+1][0]-l)*this.kx,h=(t[o+1][1]-u)*this.ky,p=0;0===c&&0===h||(p=(this.wrap(e[0]-l)*this.kx*c+(e[1]-u)*this.ky*h)/(c*c+h*h),p>1?(l=t[o+1][0],u=t[o+1][1]):p>0&&(l+=c/this.kx*p,u+=h/this.ky*p)),c=this.wrap(e[0]-l)*this.kx,h=(e[1]-u)*this.ky;const f=c*c+h*h;f<a&&(a=f,r=l,n=u,i=o,s=p);}return {point:[r,n],index:i,t:Math.max(0,Math.min(1,s))}}wrap(t){for(;t<-180;)t+=360;for(;t>180;)t-=360;return t}}function cn(t,e){return e[0]-t[0]}function hn(t){return t[1]-t[0]+1}function pn(t,e){return t[1]>=t[0]&&t[1]<e}function fn(t,e){if(t[0]>t[1])return [null,null];const r=hn(t);if(e){if(2===r)return [t,null];const e=Math.floor(r/2);return [[t[0],t[0]+e],[t[0]+e,t[1]]]}if(1===r)return [t,null];const n=Math.floor(r/2)-1;return [[t[0],t[0]+n],[t[0]+n+1,t[1]]]}function dn(t,e){if(!pn(e,t.length))return [1/0,1/0,-1/0,-1/0];const r=[1/0,1/0,-1/0,-1/0];for(let n=e[0];n<=e[1];++n)Lr(r,t[n]);return r}function yn(t){const e=[1/0,1/0,-1/0,-1/0];for(const r of t)for(const t of r)Lr(e,t);return e}function mn(t){return t[0]!==-1/0&&t[1]!==-1/0&&t[2]!==1/0&&t[3]!==1/0}function gn(t,e,r){if(!mn(t)||!mn(e))return NaN;let n=0,i=0;return t[2]<e[0]&&(n=e[0]-t[2]),t[0]>e[2]&&(n=t[0]-e[2]),t[1]>e[3]&&(i=t[1]-e[3]),t[3]<e[1]&&(i=e[1]-t[3]),r.distance([0,0],[n,i])}function xn(t,e,r){const n=r.pointOnLine(e,t);return r.distance(t,n.point)}function vn(t,e,r,n,i){const s=Math.min(xn(t,[r,n],i),xn(e,[r,n],i)),a=Math.min(xn(r,[t,e],i),xn(n,[t,e],i));return Math.min(s,a)}function bn(t,e,r,n,i){if(!pn(e,t.length)||!pn(n,r.length))return 1/0;let s=1/0;for(let a=e[0];a<e[1];++a){const e=t[a],o=t[a+1];for(let t=n[0];t<n[1];++t){const n=r[t],a=r[t+1];if(Or(e,o,n,a))return 0;s=Math.min(s,vn(e,o,n,a,i));}}return s}function wn(t,e,r,n,i){if(!pn(e,t.length)||!pn(n,r.length))return NaN;let s=1/0;for(let a=e[0];a<=e[1];++a)for(let e=n[0];e<=n[1];++e)if(s=Math.min(s,i.distance(t[a],r[e])),0===s)return s;return s}function _n(t,e,r){if(jr(t,e,!0))return 0;let n=1/0;for(const i of e){const e=i[0],s=i[i.length-1];if(e!==s&&(n=Math.min(n,xn(t,[s,e],r)),0===n))return n;const a=r.pointOnLine(i,t);if(n=Math.min(n,r.distance(t,a.point)),0===n)return n}return n}function Sn(t,e,r,n){if(!pn(e,t.length))return NaN;for(let n=e[0];n<=e[1];++n)if(jr(t[n],r,!0))return 0;let i=1/0;for(let s=e[0];s<e[1];++s){const e=t[s],a=t[s+1];for(const t of r)for(let r=0,s=t.length,o=s-1;r<s;o=r++){const s=t[o],l=t[r];if(Or(e,a,s,l))return 0;i=Math.min(i,vn(e,a,s,l,n));}}return i}function An(t,e){for(const r of t)for(const t of r)if(jr(t,e,!0))return !0;return !1}function kn(t,e,r,n=1/0){const i=yn(t),s=yn(e);if(n!==1/0&&gn(i,s,r)>=n)return n;if($r(i,s)){if(An(t,e))return 0}else if(An(e,t))return 0;let a=1/0;for(const n of t)for(let t=0,i=n.length,s=i-1;t<i;s=t++){const i=n[s],o=n[t];for(const t of e)for(let e=0,n=t.length,s=n-1;e<n;s=e++){const n=t[s],l=t[e];if(Or(i,o,n,l))return 0;a=Math.min(a,vn(i,o,n,l,r));}}return a}function Mn(t,e,r,n,i,s){if(!s)return;const a=gn(dn(n,s),i,r);a<e&&t.push([a,s,[0,0]]);}function In(t,e,r,n,i,s,a){if(!s||!a)return;const o=gn(dn(n,s),dn(i,a),r);o<e&&t.push([o,s,a]);}function zn(t,e,r,n,i=1/0){let s=Math.min(n.distance(t[0],r[0][0]),i);if(0===s)return s;const a=new Wr([[0,[0,t.length-1],[0,0]]],cn),o=yn(r);for(;a.length>0;){const i=a.pop();if(i[0]>=s)continue;const l=i[1],u=e?50:100;if(hn(l)<=u){if(!pn(l,t.length))return NaN;if(e){const e=Sn(t,l,r,n);if(isNaN(e)||0===e)return e;s=Math.min(s,e);}else for(let e=l[0];e<=l[1];++e){const i=_n(t[e],r,n);if(s=Math.min(s,i),0===s)return 0}}else {const r=fn(l,e);Mn(a,s,n,t,o,r[0]),Mn(a,s,n,t,o,r[1]);}}return s}function Pn(t,e,r,n,i,s=1/0){let a=Math.min(s,i.distance(t[0],r[0]));if(0===a)return a;const o=new Wr([[0,[0,t.length-1],[0,r.length-1]]],cn);for(;o.length>0;){const s=o.pop();if(s[0]>=a)continue;const l=s[1],u=s[2],c=e?50:100,h=n?50:100;if(hn(l)<=c&&hn(u)<=h){if(!pn(l,t.length)&&pn(u,r.length))return NaN;let s;if(e&&n)s=bn(t,l,r,u,i),a=Math.min(a,s);else if(e&&!n){const e=t.slice(l[0],l[1]+1);for(let t=u[0];t<=u[1];++t)if(s=xn(r[t],e,i),a=Math.min(a,s),0===a)return a}else if(!e&&n){const e=r.slice(u[0],u[1]+1);for(let r=l[0];r<=l[1];++r)if(s=xn(t[r],e,i),a=Math.min(a,s),0===a)return a}else s=wn(t,l,r,u,i),a=Math.min(a,s);}else {const s=fn(l,e),c=fn(u,n);In(o,a,i,t,r,s[0],c[0]),In(o,a,i,t,r,s[0],c[1]),In(o,a,i,t,r,s[1],c[0]),In(o,a,i,t,r,s[1],c[1]);}}return a}function Cn(t){return \"MultiPolygon\"===t.type?t.coordinates.map((t=>({type:\"Polygon\",coordinates:t}))):\"MultiLineString\"===t.type?t.coordinates.map((t=>({type:\"LineString\",coordinates:t}))):\"MultiPoint\"===t.type?t.coordinates.map((t=>({type:\"Point\",coordinates:t}))):[t]}class Bn{constructor(t,e){this.type=Dt,this.geojson=t,this.geometries=e;}static parse(t,e){if(2!==t.length)return e.error(`'distance' expression requires exactly one argument, but found ${t.length-1} instead.`);if(Ue(t[1])){const e=t[1];if(\"FeatureCollection\"===e.type)return new Bn(e,e.features.map((t=>Cn(t.geometry))).flat());if(\"Feature\"===e.type)return new Bn(e,Cn(e.geometry));if(\"type\"in e&&\"coordinates\"in e)return new Bn(e,Cn(e))}return e.error(\"'distance' expression requires valid geojson object that contains polygon geometry type.\")}evaluate(t){if(null!=t.geometry()&&null!=t.canonicalID()){if(\"Point\"===t.geometryType())return function(t,e){const r=t.geometry(),n=r.flat().map((e=>Fr([e.x,e.y],t.canonical)));if(0===r.length)return NaN;const i=new un(n[0][1]);let s=1/0;for(const t of e){switch(t.type){case \"Point\":s=Math.min(s,Pn(n,!1,[t.coordinates],!1,i,s));break;case \"LineString\":s=Math.min(s,Pn(n,!1,t.coordinates,!0,i,s));break;case \"Polygon\":s=Math.min(s,zn(n,!1,t.coordinates,i,s));}if(0===s)return s}return s}(t,this.geometries);if(\"LineString\"===t.geometryType())return function(t,e){const r=t.geometry(),n=r.flat().map((e=>Fr([e.x,e.y],t.canonical)));if(0===r.length)return NaN;const i=new un(n[0][1]);let s=1/0;for(const t of e){switch(t.type){case \"Point\":s=Math.min(s,Pn(n,!0,[t.coordinates],!1,i,s));break;case \"LineString\":s=Math.min(s,Pn(n,!0,t.coordinates,!0,i,s));break;case \"Polygon\":s=Math.min(s,zn(n,!0,t.coordinates,i,s));}if(0===s)return s}return s}(t,this.geometries);if(\"Polygon\"===t.geometryType())return function(t,e){const r=t.geometry();if(0===r.length||0===r[0].length)return NaN;const n=rn(r,0).map((e=>e.map((e=>e.map((e=>Fr([e.x,e.y],t.canonical))))))),i=new un(n[0][0][0][1]);let s=1/0;for(const t of e)for(const e of n){switch(t.type){case \"Point\":s=Math.min(s,zn([t.coordinates],!1,e,i,s));break;case \"LineString\":s=Math.min(s,zn(t.coordinates,!0,e,i,s));break;case \"Polygon\":s=Math.min(s,kn(e,t.coordinates,i,s));}if(0===s)return s}return s}(t,this.geometries)}return NaN}eachChild(){}outputDefined(){return !0}}class En{constructor(t){this.type=qt,this.key=t;}static parse(t,e){if(2!==t.length)return e.error(`Expected 1 argument, but found ${t.length-1} instead.`);const r=t[1];return null==r?e.error(\"Global state property must be defined.\"):\"string\"!=typeof r?e.error(`Global state property must be string, but found ${typeof t[1]} instead.`):new En(r)}evaluate(t){var e;const r=null===(e=t.globals)||void 0===e?void 0:e.globalState;return r&&0!==Object.keys(r).length?we(r,this.key):null}eachChild(){}outputDefined(){return !1}}const Tn={\"==\":_r,\"!=\":Sr,\">\":kr,\"<\":Ar,\">=\":Ir,\"<=\":Mr,array:Ye,at:rr,boolean:Ye,case:ar,coalesce:xr,collator:zr,format:Cr,image:Br,in:nr,\"index-of\":ir,interpolate:yr,\"interpolate-hcl\":yr,\"interpolate-lab\":yr,length:Er,let:tr,literal:Xe,match:sr,number:Ye,\"number-format\":Pr,object:Ye,slice:or,step:ur,string:Ye,\"to-boolean\":Ke,\"to-color\":Ke,\"to-number\":Ke,\"to-string\":Ke,var:er,within:Jr,distance:Bn,\"global-state\":En};class Vn{constructor(t,e,r,n){this.name=t,this.type=e,this._evaluate=r,this.args=n;}evaluate(t){return this._evaluate(t,this.args)}eachChild(t){this.args.forEach(t);}outputDefined(){return !1}static parse(t,e){const r=t[0],n=Vn.definitions[r];if(!n)return e.error(`Unknown expression \"${r}\". If you wanted a literal array, use [\"literal\", [...]].`,0);const i=Array.isArray(n)?n[0]:n.type,s=Array.isArray(n)?[[n[1],n[2]]]:n.overloads,a=s.filter((([e])=>!Array.isArray(e)||e.length===t.length-1));let o=null;for(const[n,s]of a){o=new Qe(e.registry,On,e.path,null,e.scope);const a=[];let l=!1;for(let e=1;e<t.length;e++){const r=t[e],i=Array.isArray(n)?n[e-1]:n.type,s=o.parse(r,1+a.length,i);if(!s){l=!0;break}a.push(s);}if(!l)if(Array.isArray(n)&&n.length!==a.length)o.error(`Expected ${n.length} arguments, but found ${a.length} instead.`);else {for(let t=0;t<a.length;t++){const e=Array.isArray(n)?n[t]:n.type,r=a[t];o.concat(t+1).checkSubtype(e,r.type);}if(0===o.errors.length)return new Vn(r,i,s,a)}}if(1===a.length)e.errors.push(...o.errors);else {const r=(a.length?a:s).map((([t])=>{return e=t,Array.isArray(e)?`(${e.map(Qt).join(\", \")})`:`(${Qt(e.type)}...)`;var e;})).join(\" | \"),n=[];for(let r=1;r<t.length;r++){const i=e.parse(t[r],1+n.length);if(!i)return null;n.push(Qt(i.type));}e.error(`Expected arguments of type ${r}, but found (${n.join(\", \")}) instead.`);}return null}static register(t,e){Vn.definitions=e;for(const r in e)t[r]=Vn;}}function Fn(t,[e,r,n,i]){e=e.evaluate(t),r=r.evaluate(t),n=n.evaluate(t);const s=i?i.evaluate(t):1,a=Ne(e,r,n,s);if(a)throw new $e(a);return new Pe(e/255,r/255,n/255,s,!1)}function Ln(t,e){return t in e}function $n(t,e){const r=e[t];return void 0===r?null:r}function Dn(t){return {type:t}}function On(t){if(t instanceof er)return On(t.boundExpression);if(t instanceof Vn&&\"error\"===t.name)return !1;if(t instanceof zr)return !1;if(t instanceof Jr)return !1;if(t instanceof Bn)return !1;if(t instanceof En)return !1;const e=t instanceof Ke||t instanceof Ye;let r=!0;return t.eachChild((t=>{r=e?r&&On(t):r&&t instanceof Xe;})),!!r&&Rn(t)&&Nn(t,[\"zoom\",\"heatmap-density\",\"elevation\",\"line-progress\",\"accumulated\",\"is-supported-script\"])}function Rn(t){if(t instanceof Vn){if(\"get\"===t.name&&1===t.args.length)return !1;if(\"feature-state\"===t.name)return !1;if(\"has\"===t.name&&1===t.args.length)return !1;if(\"properties\"===t.name||\"geometry-type\"===t.name||\"id\"===t.name)return !1;if(/^filter-/.test(t.name))return !1}if(t instanceof Jr)return !1;if(t instanceof Bn)return !1;let e=!0;return t.eachChild((t=>{e&&!Rn(t)&&(e=!1);})),e}function jn(t){if(t instanceof Vn&&\"feature-state\"===t.name)return !1;let e=!0;return t.eachChild((t=>{e&&!jn(t)&&(e=!1);})),e}function Nn(t,e){if(t instanceof Vn&&e.indexOf(t.name)>=0)return !1;let r=!0;return t.eachChild((t=>{r&&!Nn(t,e)&&(r=!1);})),r}function Un(t){return {result:\"success\",value:t}}function qn(t){return {result:\"error\",value:t}}function Gn(t){return \"data-driven\"===t[\"property-type\"]||\"cross-faded-data-driven\"===t[\"property-type\"]}function Xn(t){return !!t.expression&&t.expression.parameters.indexOf(\"zoom\")>-1}function Zn(t){return !!t.expression&&t.expression.interpolated}function Yn(t){return t instanceof Number?\"number\":t instanceof String?\"string\":t instanceof Boolean?\"boolean\":Array.isArray(t)?\"array\":null===t?\"null\":typeof t}function Hn(t){return \"object\"==typeof t&&null!==t&&!Array.isArray(t)&&qe(t)===Ut}function Kn(t){return t}function Jn(t,e){const r=t.stops&&\"object\"==typeof t.stops[0][0],n=r||!(r||void 0!==t.property),i=t.type||(Zn(e)?\"exponential\":\"interval\"),s=function(t){switch(t.type){case \"color\":return Pe.parse;case \"padding\":return Ve.parse;case \"numberArray\":return Fe.parse;case \"colorArray\":return Le.parse;default:return null}}(e);if(s&&((t=Vt({},t)).stops&&(t.stops=t.stops.map((t=>[t[0],s(t[1])]))),t.default=s(t.default?t.default:e.default)),t.colorSpace&&\"rgb\"!==(a=t.colorSpace)&&\"hcl\"!==a&&\"lab\"!==a)throw new Error(`Unknown color space: \"${t.colorSpace}\"`);var a;const o=function(t){switch(t){case \"exponential\":return ei;case \"interval\":return ti;case \"categorical\":return Qn;case \"identity\":return ri;default:throw new Error(`Unknown function type \"${t}\"`)}}(i);let l,u;if(\"categorical\"===i){l=Object.create(null);for(const e of t.stops)l[e[0]]=e[1];u=typeof t.stops[0][0];}if(r){const r={},n=[];for(let e=0;e<t.stops.length;e++){const i=t.stops[e],s=i[0].zoom;void 0===r[s]&&(r[s]={zoom:s,type:t.type,property:t.property,default:t.default,stops:[]},n.push(s)),r[s].stops.push([i[0].value,i[1]]);}const i=[];for(const t of n)i.push([r[t].zoom,Jn(r[t],e)]);const s={name:\"linear\"};return {kind:\"composite\",interpolationType:s,interpolationFactor:yr.interpolationFactor.bind(void 0,s),zoomStops:i.map((t=>t[0])),evaluate:({zoom:r},n)=>ei({stops:i,base:t.base},e,r).evaluate(r,n)}}if(n){const r=\"exponential\"===i?{name:\"exponential\",base:void 0!==t.base?t.base:1}:null;return {kind:\"camera\",interpolationType:r,interpolationFactor:yr.interpolationFactor.bind(void 0,r),zoomStops:t.stops.map((t=>t[0])),evaluate:({zoom:r})=>o(t,e,r,l,u)}}return {kind:\"source\",evaluate(r,n){const i=n&&n.properties?n.properties[t.property]:void 0;return void 0===i?Wn(t.default,e.default):o(t,e,i,l,u)}}}function Wn(t,e,r){return void 0!==t?t:void 0!==e?e:void 0!==r?r:void 0}function Qn(t,e,r,n,i){return Wn(typeof r===i?n[r]:void 0,t.default,e.default)}function ti(t,e,r){if(\"number\"!==Yn(r))return Wn(t.default,e.default);const n=t.stops.length;if(1===n)return t.stops[0][1];if(r<=t.stops[0][0])return t.stops[0][1];if(r>=t.stops[n-1][0])return t.stops[n-1][1];const i=lr(t.stops.map((t=>t[0])),r);return t.stops[i][1]}function ei(t,e,r){const n=void 0!==t.base?t.base:1;if(\"number\"!==Yn(r))return Wn(t.default,e.default);const i=t.stops.length;if(1===i)return t.stops[0][1];if(r<=t.stops[0][0])return t.stops[0][1];if(r>=t.stops[i-1][0])return t.stops[i-1][1];const s=lr(t.stops.map((t=>t[0])),r),a=function(t,e,r,n){const i=n-r,s=t-r;return 0===i?0:1===e?s/i:(Math.pow(e,s)-1)/(Math.pow(e,i)-1)}(r,n,t.stops[s][0],t.stops[s+1][0]),o=t.stops[s][1],l=t.stops[s+1][1],u=gr[e.type]||Kn;return \"function\"==typeof o.evaluate?{evaluate(...e){const r=o.evaluate.apply(void 0,e),n=l.evaluate.apply(void 0,e);if(void 0!==r&&void 0!==n)return u(r,n,a,t.colorSpace)}}:u(o,l,a,t.colorSpace)}function ri(t,e,r){switch(e.type){case \"color\":r=Pe.parse(r);break;case \"formatted\":r=Te.fromString(r.toString());break;case \"resolvedImage\":r=Re.fromString(r.toString());break;case \"padding\":r=Ve.parse(r);break;case \"colorArray\":r=Le.parse(r);break;case \"numberArray\":r=Fe.parse(r);break;default:Yn(r)===e.type||\"enum\"===e.type&&e.values[r]||(r=void 0);}return Wn(r,t.default,e.default)}Vn.register(Tn,{error:[{kind:\"error\"},[Ot],(t,[e])=>{throw new $e(e.evaluate(t))}],typeof:[Ot,[qt],(t,[e])=>Qt(qe(e.evaluate(t)))],\"to-rgba\":[Wt(Dt,4),[jt],(t,[e])=>{const[r,n,i,s]=e.evaluate(t).rgb;return [255*r,255*n,255*i,s]}],rgb:[jt,[Dt,Dt,Dt],Fn],rgba:[jt,[Dt,Dt,Dt,Dt],Fn],has:{type:Rt,overloads:[[[Ot],(t,[e])=>Ln(e.evaluate(t),t.properties())],[[Ot,Ut],(t,[e,r])=>Ln(e.evaluate(t),r.evaluate(t))]]},get:{type:qt,overloads:[[[Ot],(t,[e])=>$n(e.evaluate(t),t.properties())],[[Ot,Ut],(t,[e,r])=>$n(e.evaluate(t),r.evaluate(t))]]},\"feature-state\":[qt,[Ot],(t,[e])=>$n(e.evaluate(t),t.featureState||{})],properties:[Ut,[],t=>t.properties()],\"geometry-type\":[Ot,[],t=>t.geometryType()],id:[qt,[],t=>t.id()],zoom:[Dt,[],t=>t.globals.zoom],\"heatmap-density\":[Dt,[],t=>t.globals.heatmapDensity||0],elevation:[Dt,[],t=>t.globals.elevation||0],\"line-progress\":[Dt,[],t=>t.globals.lineProgress||0],accumulated:[qt,[],t=>void 0===t.globals.accumulated?null:t.globals.accumulated],\"+\":[Dt,Dn(Dt),(t,e)=>{let r=0;for(const n of e)r+=n.evaluate(t);return r}],\"*\":[Dt,Dn(Dt),(t,e)=>{let r=1;for(const n of e)r*=n.evaluate(t);return r}],\"-\":{type:Dt,overloads:[[[Dt,Dt],(t,[e,r])=>e.evaluate(t)-r.evaluate(t)],[[Dt],(t,[e])=>-e.evaluate(t)]]},\"/\":[Dt,[Dt,Dt],(t,[e,r])=>e.evaluate(t)/r.evaluate(t)],\"%\":[Dt,[Dt,Dt],(t,[e,r])=>e.evaluate(t)%r.evaluate(t)],ln2:[Dt,[],()=>Math.LN2],pi:[Dt,[],()=>Math.PI],e:[Dt,[],()=>Math.E],\"^\":[Dt,[Dt,Dt],(t,[e,r])=>Math.pow(e.evaluate(t),r.evaluate(t))],sqrt:[Dt,[Dt],(t,[e])=>Math.sqrt(e.evaluate(t))],log10:[Dt,[Dt],(t,[e])=>Math.log(e.evaluate(t))/Math.LN10],ln:[Dt,[Dt],(t,[e])=>Math.log(e.evaluate(t))],log2:[Dt,[Dt],(t,[e])=>Math.log(e.evaluate(t))/Math.LN2],sin:[Dt,[Dt],(t,[e])=>Math.sin(e.evaluate(t))],cos:[Dt,[Dt],(t,[e])=>Math.cos(e.evaluate(t))],tan:[Dt,[Dt],(t,[e])=>Math.tan(e.evaluate(t))],asin:[Dt,[Dt],(t,[e])=>Math.asin(e.evaluate(t))],acos:[Dt,[Dt],(t,[e])=>Math.acos(e.evaluate(t))],atan:[Dt,[Dt],(t,[e])=>Math.atan(e.evaluate(t))],min:[Dt,Dn(Dt),(t,e)=>Math.min(...e.map((e=>e.evaluate(t))))],max:[Dt,Dn(Dt),(t,e)=>Math.max(...e.map((e=>e.evaluate(t))))],abs:[Dt,[Dt],(t,[e])=>Math.abs(e.evaluate(t))],round:[Dt,[Dt],(t,[e])=>{const r=e.evaluate(t);return r<0?-Math.round(-r):Math.round(r)}],floor:[Dt,[Dt],(t,[e])=>Math.floor(e.evaluate(t))],ceil:[Dt,[Dt],(t,[e])=>Math.ceil(e.evaluate(t))],\"filter-==\":[Rt,[Ot,qt],(t,[e,r])=>t.properties()[e.value]===r.value],\"filter-id-==\":[Rt,[qt],(t,[e])=>t.id()===e.value],\"filter-type-==\":[Rt,[Ot],(t,[e])=>t.geometryType()===e.value],\"filter-<\":[Rt,[Ot,qt],(t,[e,r])=>{const n=t.properties()[e.value],i=r.value;return typeof n==typeof i&&n<i}],\"filter-id-<\":[Rt,[qt],(t,[e])=>{const r=t.id(),n=e.value;return typeof r==typeof n&&r<n}],\"filter->\":[Rt,[Ot,qt],(t,[e,r])=>{const n=t.properties()[e.value],i=r.value;return typeof n==typeof i&&n>i}],\"filter-id->\":[Rt,[qt],(t,[e])=>{const r=t.id(),n=e.value;return typeof r==typeof n&&r>n}],\"filter-<=\":[Rt,[Ot,qt],(t,[e,r])=>{const n=t.properties()[e.value],i=r.value;return typeof n==typeof i&&n<=i}],\"filter-id-<=\":[Rt,[qt],(t,[e])=>{const r=t.id(),n=e.value;return typeof r==typeof n&&r<=n}],\"filter->=\":[Rt,[Ot,qt],(t,[e,r])=>{const n=t.properties()[e.value],i=r.value;return typeof n==typeof i&&n>=i}],\"filter-id->=\":[Rt,[qt],(t,[e])=>{const r=t.id(),n=e.value;return typeof r==typeof n&&r>=n}],\"filter-has\":[Rt,[qt],(t,[e])=>e.value in t.properties()],\"filter-has-id\":[Rt,[],t=>null!==t.id()&&void 0!==t.id()],\"filter-type-in\":[Rt,[Wt(Ot)],(t,[e])=>e.value.indexOf(t.geometryType())>=0],\"filter-id-in\":[Rt,[Wt(qt)],(t,[e])=>e.value.indexOf(t.id())>=0],\"filter-in-small\":[Rt,[Ot,Wt(qt)],(t,[e,r])=>r.value.indexOf(t.properties()[e.value])>=0],\"filter-in-large\":[Rt,[Ot,Wt(qt)],(t,[e,r])=>function(t,e,r,n){for(;r<=n;){const i=r+n>>1;if(e[i]===t)return !0;e[i]>t?n=i-1:r=i+1;}return !1}(t.properties()[e.value],r.value,0,r.value.length-1)],all:{type:Rt,overloads:[[[Rt,Rt],(t,[e,r])=>e.evaluate(t)&&r.evaluate(t)],[Dn(Rt),(t,e)=>{for(const r of e)if(!r.evaluate(t))return !1;return !0}]]},any:{type:Rt,overloads:[[[Rt,Rt],(t,[e,r])=>e.evaluate(t)||r.evaluate(t)],[Dn(Rt),(t,e)=>{for(const r of e)if(r.evaluate(t))return !0;return !1}]]},\"!\":[Rt,[Rt],(t,[e])=>!e.evaluate(t)],\"is-supported-script\":[Rt,[Ot],(t,[e])=>{const r=t.globals&&t.globals.isSupportedScript;return !r||r(e.evaluate(t))}],upcase:[Ot,[Ot],(t,[e])=>e.evaluate(t).toUpperCase()],downcase:[Ot,[Ot],(t,[e])=>e.evaluate(t).toLowerCase()],concat:[Ot,Dn(qt),(t,e)=>e.map((e=>Ge(e.evaluate(t)))).join(\"\")],\"resolved-locale\":[Ot,[Gt],(t,[e])=>e.evaluate(t).resolvedLocale()]});class ni{constructor(t,e){this.expression=t,this._warningHistory={},this._evaluator=new We,this._defaultValue=e?function(t){if(\"color\"===t.type&&Hn(t.default))return new Pe(0,0,0,0);switch(t.type){case \"color\":return Pe.parse(t.default)||null;case \"padding\":return Ve.parse(t.default)||null;case \"numberArray\":return Fe.parse(t.default)||null;case \"colorArray\":return Le.parse(t.default)||null;case \"variableAnchorOffsetCollection\":return Oe.parse(t.default)||null;case \"projectionDefinition\":return je.parse(t.default)||null;default:return void 0===t.default?null:t.default}}(e):null,this._enumValues=e&&\"enum\"===e.type?e.values:null;}evaluateWithoutErrorHandling(t,e,r,n,i,s){return this._evaluator.globals=t,this._evaluator.feature=e,this._evaluator.featureState=r,this._evaluator.canonical=n,this._evaluator.availableImages=i||null,this._evaluator.formattedSection=s,this.expression.evaluate(this._evaluator)}evaluate(t,e,r,n,i,s){this._evaluator.globals=t,this._evaluator.feature=e||null,this._evaluator.featureState=r||null,this._evaluator.canonical=n,this._evaluator.availableImages=i||null,this._evaluator.formattedSection=s||null;try{const t=this.expression.evaluate(this._evaluator);if(null==t||\"number\"==typeof t&&t!=t)return this._defaultValue;if(this._enumValues&&!(t in this._enumValues))throw new $e(`Expected value to be one of ${Object.keys(this._enumValues).map((t=>JSON.stringify(t))).join(\", \")}, but found ${JSON.stringify(t)} instead.`);return t}catch(t){return this._warningHistory[t.message]||(this._warningHistory[t.message]=!0,\"undefined\"!=typeof console&&console.warn(t.message)),this._defaultValue}}}function ii(t){return Array.isArray(t)&&t.length>0&&\"string\"==typeof t[0]&&t[0]in Tn}function si(t,e){const r=new Qe(Tn,On,[],e?function(t){const e={color:jt,string:Ot,number:Dt,enum:Ot,boolean:Rt,formatted:Xt,padding:Zt,numberArray:Ht,colorArray:Yt,projectionDefinition:Nt,resolvedImage:Kt,variableAnchorOffsetCollection:Jt};return \"array\"===t.type?Wt(e[t.value]||qt,t.length):e[t.type]}(e):void 0),n=r.parse(t,void 0,void 0,void 0,e&&\"string\"===e.type?{typeAnnotation:\"coerce\"}:void 0);return n?Un(new ni(n,e)):qn(r.errors)}class ai{constructor(t,e){this.kind=t,this._styleExpression=e,this.isStateDependent=\"constant\"!==t&&!jn(e.expression),this.globalStateRefs=hi(e.expression);}evaluateWithoutErrorHandling(t,e,r,n,i,s){return this._styleExpression.evaluateWithoutErrorHandling(t,e,r,n,i,s)}evaluate(t,e,r,n,i,s){return this._styleExpression.evaluate(t,e,r,n,i,s)}}class oi{constructor(t,e,r,n){this.kind=t,this.zoomStops=r,this._styleExpression=e,this.isStateDependent=\"camera\"!==t&&!jn(e.expression),this.globalStateRefs=hi(e.expression),this.interpolationType=n;}evaluateWithoutErrorHandling(t,e,r,n,i,s){return this._styleExpression.evaluateWithoutErrorHandling(t,e,r,n,i,s)}evaluate(t,e,r,n,i,s){return this._styleExpression.evaluate(t,e,r,n,i,s)}interpolationFactor(t,e,r){return this.interpolationType?yr.interpolationFactor(this.interpolationType,t,e,r):0}}function li(t,e){const r=si(t,e);if(\"error\"===r.result)return r;const n=r.value.expression,i=Rn(n);if(!i&&!Gn(e))return qn([new Ft(\"\",\"data expressions not supported\")]);const s=Nn(n,[\"zoom\"]);if(!s&&!Xn(e))return qn([new Ft(\"\",\"zoom expressions not supported\")]);const a=ci(n);return a||s?a instanceof Ft?qn([a]):a instanceof yr&&!Zn(e)?qn([new Ft(\"\",'\"interpolate\" expressions cannot be used with this property')]):Un(a?new oi(i?\"camera\":\"composite\",r.value,a.labels,a instanceof yr?a.interpolation:void 0):new ai(i?\"constant\":\"source\",r.value)):qn([new Ft(\"\",'\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.')])}class ui{constructor(t,e){this._parameters=t,this._specification=e,Vt(this,Jn(this._parameters,this._specification));}static deserialize(t){return new ui(t._parameters,t._specification)}static serialize(t){return {_parameters:t._parameters,_specification:t._specification}}}function ci(t){let e=null;if(t instanceof tr)e=ci(t.result);else if(t instanceof xr){for(const r of t.args)if(e=ci(r),e)break}else (t instanceof ur||t instanceof yr)&&t.input instanceof Vn&&\"zoom\"===t.input.name&&(e=t);return e instanceof Ft||t.eachChild((t=>{const r=ci(t);r instanceof Ft?e=r:!e&&r?e=new Ft(\"\",'\"zoom\" expression may only be used as input to a top-level \"step\" or \"interpolate\" expression.'):e&&r&&e!==r&&(e=new Ft(\"\",'Only one zoom-based \"step\" or \"interpolate\" subexpression may be used in an expression.'));})),e}function hi(t,e=new Set){return t instanceof En&&e.add(t.key),t.eachChild((t=>{hi(t,e);})),e}function pi(t){if(!0===t||!1===t)return !0;if(!Array.isArray(t)||0===t.length)return !1;switch(t[0]){case \"has\":return t.length>=2&&\"$id\"!==t[1]&&\"$type\"!==t[1];case \"in\":return t.length>=3&&(\"string\"!=typeof t[1]||Array.isArray(t[2]));case \"!in\":case \"!has\":case \"none\":return !1;case \"==\":case \"!=\":case \">\":case \">=\":case \"<\":case \"<=\":return 3!==t.length||Array.isArray(t[1])||Array.isArray(t[2]);case \"any\":case \"all\":for(const e of t.slice(1))if(!pi(e)&&\"boolean\"!=typeof e)return !1;return !0;default:return !0}}const fi={type:\"boolean\",default:!1,transition:!1,\"property-type\":\"data-driven\",expression:{interpolated:!1,parameters:[\"zoom\",\"feature\"]}};function di(t){if(null==t)return {filter:()=>!0,needGeometry:!1,getGlobalStateRefs:()=>new Set};pi(t)||(t=gi(t));const e=si(t,fi);if(\"error\"===e.result)throw new Error(e.value.map((t=>`${t.key}: ${t.message}`)).join(\", \"));return {filter:(t,r,n)=>e.value.evaluate(t,r,{},n),needGeometry:mi(t),getGlobalStateRefs:()=>hi(e.value.expression)}}function yi(t,e){return t<e?-1:t>e?1:0}function mi(t){if(!Array.isArray(t))return !1;if(\"within\"===t[0]||\"distance\"===t[0])return !0;for(let e=1;e<t.length;e++)if(mi(t[e]))return !0;return !1}function gi(t){if(!t)return !0;const e=t[0];return t.length<=1?\"any\"!==e:\"==\"===e?xi(t[1],t[2],\"==\"):\"!=\"===e?wi(xi(t[1],t[2],\"==\")):\"<\"===e||\">\"===e||\"<=\"===e||\">=\"===e?xi(t[1],t[2],e):\"any\"===e?(r=t.slice(1),[\"any\"].concat(r.map(gi))):\"all\"===e?[\"all\"].concat(t.slice(1).map(gi)):\"none\"===e?[\"all\"].concat(t.slice(1).map(gi).map(wi)):\"in\"===e?vi(t[1],t.slice(2)):\"!in\"===e?wi(vi(t[1],t.slice(2))):\"has\"===e?bi(t[1]):\"!has\"!==e||wi(bi(t[1]));var r;}function xi(t,e,r){switch(t){case \"$type\":return [`filter-type-${r}`,e];case \"$id\":return [`filter-id-${r}`,e];default:return [`filter-${r}`,t,e]}}function vi(t,e){if(0===e.length)return !1;switch(t){case \"$type\":return [\"filter-type-in\",[\"literal\",e]];case \"$id\":return [\"filter-id-in\",[\"literal\",e]];default:return e.length>200&&!e.some((t=>typeof t!=typeof e[0]))?[\"filter-in-large\",t,[\"literal\",e.sort(yi)]]:[\"filter-in-small\",t,[\"literal\",e]]}}function bi(t){switch(t){case \"$type\":return !0;case \"$id\":return [\"filter-has-id\"];default:return [\"filter-has\",t]}}function wi(t){return [\"!\",t]}function _i(t){const e=typeof t;if(\"number\"===e||\"boolean\"===e||\"string\"===e||null==t)return JSON.stringify(t);if(Array.isArray(t)){let e=\"[\";for(const r of t)e+=`${_i(r)},`;return `${e}]`}const r=Object.keys(t).sort();let n=\"{\";for(let e=0;e<r.length;e++)n+=`${JSON.stringify(r[e])}:${_i(t[r[e]])},`;return `${n}}`}function Si(t){let e=\"\";for(const r of _t)e+=`/${_i(t[r])}`;return e}function Ai(t){const e=t.value;return e?[new Tt(t.key,e,\"constants have been deprecated as of v8\")]:[]}function ki(t){return t instanceof Number||t instanceof String||t instanceof Boolean?t.valueOf():t}function Mi(t){if(Array.isArray(t))return t.map(Mi);if(t instanceof Object&&!(t instanceof Number||t instanceof String||t instanceof Boolean)){const e={};for(const r in t)e[r]=Mi(t[r]);return e}return ki(t)}function Ii(t){const e=t.key,r=t.value,n=t.valueSpec||{},i=t.objectElementValidators||{},s=t.style,a=t.styleSpec,o=t.validateSpec;let l=[];const u=Yn(r);if(\"object\"!==u)return [new Tt(e,r,`object expected, ${u} found`)];for(const t in r){const u=t.split(\".\")[0],c=we(n,u)||n[\"*\"];let h;if(we(i,u))h=i[u];else if(we(n,u))h=o;else if(i[\"*\"])h=i[\"*\"];else {if(!n[\"*\"]){l.push(new Tt(e,r[t],`unknown property \"${t}\"`));continue}h=o;}l=l.concat(h({key:(e?`${e}.`:e)+t,value:r[t],valueSpec:c,style:s,styleSpec:a,object:r,objectKey:t,validateSpec:o},r));}for(const t in n)i[t]||n[t].required&&void 0===n[t].default&&void 0===r[t]&&l.push(new Tt(e,r,`missing required property \"${t}\"`));return l}function zi(t){const e=t.value,r=t.valueSpec,n=t.style,i=t.styleSpec,s=t.key,a=t.arrayElementValidator||t.validateSpec;if(\"array\"!==Yn(e))return [new Tt(s,e,`array expected, ${Yn(e)} found`)];if(r.length&&e.length!==r.length)return [new Tt(s,e,`array length ${r.length} expected, length ${e.length} found`)];if(r[\"min-length\"]&&e.length<r[\"min-length\"])return [new Tt(s,e,`array length at least ${r[\"min-length\"]} expected, length ${e.length} found`)];let o={type:r.value,values:r.values};i.$version<7&&(o.function=r.function),\"object\"===Yn(r.value)&&(o=r.value);let l=[];for(let r=0;r<e.length;r++)l=l.concat(a({array:e,arrayIndex:r,value:e[r],valueSpec:o,validateSpec:t.validateSpec,style:n,styleSpec:i,key:`${s}[${r}]`}));return l}function Pi(t){const e=t.key,r=t.value,n=t.valueSpec;let i=Yn(r);return \"number\"===i&&r!=r&&(i=\"NaN\"),\"number\"!==i?[new Tt(e,r,`number expected, ${i} found`)]:\"minimum\"in n&&r<n.minimum?[new Tt(e,r,`${r} is less than the minimum value ${n.minimum}`)]:\"maximum\"in n&&r>n.maximum?[new Tt(e,r,`${r} is greater than the maximum value ${n.maximum}`)]:[]}function Ci(t){const e=t.valueSpec,r=ki(t.value.type);let n,i,s,a={};const o=\"categorical\"!==r&&void 0===t.value.property,l=!o,u=\"array\"===Yn(t.value.stops)&&\"array\"===Yn(t.value.stops[0])&&\"object\"===Yn(t.value.stops[0][0]),c=Ii({key:t.key,value:t.value,valueSpec:t.styleSpec.function,validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec,objectElementValidators:{stops:function(t){if(\"identity\"===r)return [new Tt(t.key,t.value,'identity function may not have a \"stops\" property')];let e=[];const n=t.value;return e=e.concat(zi({key:t.key,value:n,valueSpec:t.valueSpec,validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec,arrayElementValidator:h})),\"array\"===Yn(n)&&0===n.length&&e.push(new Tt(t.key,n,\"array must have at least one stop\")),e},default:function(t){return t.validateSpec({key:t.key,value:t.value,valueSpec:e,validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec})}}});return \"identity\"===r&&o&&c.push(new Tt(t.key,t.value,'missing required property \"property\"')),\"identity\"===r||t.value.stops||c.push(new Tt(t.key,t.value,'missing required property \"stops\"')),\"exponential\"===r&&t.valueSpec.expression&&!Zn(t.valueSpec)&&c.push(new Tt(t.key,t.value,\"exponential functions not supported\")),t.styleSpec.$version>=8&&(l&&!Gn(t.valueSpec)?c.push(new Tt(t.key,t.value,\"property functions not supported\")):o&&!Xn(t.valueSpec)&&c.push(new Tt(t.key,t.value,\"zoom functions not supported\"))),\"categorical\"!==r&&!u||void 0!==t.value.property||c.push(new Tt(t.key,t.value,'\"property\" property is required')),c;function h(t){let r=[];const n=t.value,o=t.key;if(\"array\"!==Yn(n))return [new Tt(o,n,`array expected, ${Yn(n)} found`)];if(2!==n.length)return [new Tt(o,n,`array length 2 expected, length ${n.length} found`)];if(u){if(\"object\"!==Yn(n[0]))return [new Tt(o,n,`object expected, ${Yn(n[0])} found`)];if(void 0===n[0].zoom)return [new Tt(o,n,\"object stop key must have zoom\")];if(void 0===n[0].value)return [new Tt(o,n,\"object stop key must have value\")];if(s&&s>ki(n[0].zoom))return [new Tt(o,n[0].zoom,\"stop zoom values must appear in ascending order\")];ki(n[0].zoom)!==s&&(s=ki(n[0].zoom),i=void 0,a={}),r=r.concat(Ii({key:`${o}[0]`,value:n[0],valueSpec:{zoom:{}},validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec,objectElementValidators:{zoom:Pi,value:p}}));}else r=r.concat(p({key:`${o}[0]`,value:n[0],validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec},n));return ii(Mi(n[1]))?r.concat([new Tt(`${o}[1]`,n[1],\"expressions are not allowed in function stops.\")]):r.concat(t.validateSpec({key:`${o}[1]`,value:n[1],valueSpec:e,validateSpec:t.validateSpec,style:t.style,styleSpec:t.styleSpec}))}function p(t,s){const o=Yn(t.value),l=ki(t.value),u=null!==t.value?t.value:s;if(n){if(o!==n)return [new Tt(t.key,u,`${o} stop domain type must match previous stop domain type ${n}`)]}else n=o;if(\"number\"!==o&&\"string\"!==o&&\"boolean\"!==o)return [new Tt(t.key,u,\"stop domain value must be a number, string, or boolean\")];if(\"number\"!==o&&\"categorical\"!==r){let n=`number expected, ${o} found`;return Gn(e)&&void 0===r&&(n+='\\nIf you intended to use a categorical function, specify `\"type\": \"categorical\"`.'),[new Tt(t.key,u,n)]}return \"categorical\"!==r||\"number\"!==o||isFinite(l)&&Math.floor(l)===l?\"categorical\"!==r&&\"number\"===o&&void 0!==i&&l<i?[new Tt(t.key,u,\"stop domain values must appear in ascending order\")]:(i=l,\"categorical\"===r&&l in a?[new Tt(t.key,u,\"stop domain values must be unique\")]:(a[l]=!0,[])):[new Tt(t.key,u,`integer expected, found ${l}`)]}}function Bi(t){const e=(\"property\"===t.expressionContext?li:si)(Mi(t.value),t.valueSpec);if(\"error\"===e.result)return e.value.map((e=>new Tt(`${t.key}${e.key}`,t.value,e.message)));const r=e.value.expression||e.value._styleExpression.expression;if(\"property\"===t.expressionContext&&\"text-font\"===t.propertyKey&&!r.outputDefined())return [new Tt(t.key,t.value,`Invalid data expression for \"${t.propertyKey}\". Output values must be contained as literals within the expression.`)];if(\"property\"===t.expressionContext&&\"layout\"===t.propertyType&&!jn(r))return [new Tt(t.key,t.value,'\"feature-state\" data expressions are not supported with layout properties.')];if(\"filter\"===t.expressionContext&&!jn(r))return [new Tt(t.key,t.value,'\"feature-state\" data expressions are not supported with filters.')];if(t.expressionContext&&0===t.expressionContext.indexOf(\"cluster\")){if(!Nn(r,[\"zoom\",\"feature-state\"]))return [new Tt(t.key,t.value,'\"zoom\" and \"feature-state\" expressions are not supported with cluster properties.')];if(\"cluster-initial\"===t.expressionContext&&!Rn(r))return [new Tt(t.key,t.value,\"Feature data expressions are not supported with initial expression part of cluster properties.\")]}return []}function Ei(t){const e=t.key,r=t.value,n=Yn(r);return \"string\"!==n?[new Tt(e,r,`color expected, ${n} found`)]:Pe.parse(String(r))?[]:[new Tt(e,r,`color expected, \"${r}\" found`)]}function Ti(t){const e=t.key,r=t.value,n=t.valueSpec,i=[];return Array.isArray(n.values)?-1===n.values.indexOf(ki(r))&&i.push(new Tt(e,r,`expected one of [${n.values.join(\", \")}], ${JSON.stringify(r)} found`)):-1===Object.keys(n.values).indexOf(ki(r))&&i.push(new Tt(e,r,`expected one of [${Object.keys(n.values).join(\", \")}], ${JSON.stringify(r)} found`)),i}function Vi(t){return pi(Mi(t.value))?Bi(Vt({},t,{expressionContext:\"filter\",valueSpec:{value:\"boolean\"}})):Fi(t)}function Fi(t){const e=t.value,r=t.key;if(\"array\"!==Yn(e))return [new Tt(r,e,`array expected, ${Yn(e)} found`)];const n=t.styleSpec;let i,s=[];if(e.length<1)return [new Tt(r,e,\"filter array must have at least 1 element\")];switch(s=s.concat(Ti({key:`${r}[0]`,value:e[0],valueSpec:n.filter_operator,style:t.style,styleSpec:t.styleSpec})),ki(e[0])){case \"<\":case \"<=\":case \">\":case \">=\":e.length>=2&&\"$type\"===ki(e[1])&&s.push(new Tt(r,e,`\"$type\" cannot be use with operator \"${e[0]}\"`));case \"==\":case \"!=\":3!==e.length&&s.push(new Tt(r,e,`filter array for operator \"${e[0]}\" must have 3 elements`));case \"in\":case \"!in\":e.length>=2&&(i=Yn(e[1]),\"string\"!==i&&s.push(new Tt(`${r}[1]`,e[1],`string expected, ${i} found`)));for(let a=2;a<e.length;a++)i=Yn(e[a]),\"$type\"===ki(e[1])?s=s.concat(Ti({key:`${r}[${a}]`,value:e[a],valueSpec:n.geometry_type,style:t.style,styleSpec:t.styleSpec})):\"string\"!==i&&\"number\"!==i&&\"boolean\"!==i&&s.push(new Tt(`${r}[${a}]`,e[a],`string, number, or boolean expected, ${i} found`));break;case \"any\":case \"all\":case \"none\":for(let n=1;n<e.length;n++)s=s.concat(Fi({key:`${r}[${n}]`,value:e[n],style:t.style,styleSpec:t.styleSpec}));break;case \"has\":case \"!has\":i=Yn(e[1]),2!==e.length?s.push(new Tt(r,e,`filter array for \"${e[0]}\" operator must have 2 elements`)):\"string\"!==i&&s.push(new Tt(`${r}[1]`,e[1],`string expected, ${i} found`));}return s}function Li(t,e){const r=t.key,n=t.validateSpec,i=t.style,s=t.styleSpec,a=t.value,o=t.objectKey,l=s[`${e}_${t.layerType}`];if(!l)return [];const u=o.match(/^(.*)-transition$/);if(\"paint\"===e&&u&&l[u[1]]&&l[u[1]].transition)return n({key:r,value:a,valueSpec:s.transition,style:i,styleSpec:s});const c=t.valueSpec||l[o];if(!c)return [new Tt(r,a,`unknown property \"${o}\"`)];let h;if(\"string\"===Yn(a)&&Gn(c)&&!c.tokens&&(h=/^{([^}]+)}$/.exec(a)))return [new Tt(r,a,`\"${o}\" does not support interpolation syntax\\nUse an identity property function instead: \\`{ \"type\": \"identity\", \"property\": ${JSON.stringify(h[1])} }\\`.`)];const p=[];return \"symbol\"===t.layerType&&(\"text-field\"===o&&i&&!i.glyphs&&p.push(new Tt(r,a,'use of \"text-field\" requires a style \"glyphs\" property')),\"text-font\"===o&&Hn(Mi(a))&&\"identity\"===ki(a.type)&&p.push(new Tt(r,a,'\"text-font\" does not support identity functions'))),p.concat(n({key:t.key,value:a,valueSpec:c,style:i,styleSpec:s,expressionContext:\"property\",propertyType:e,propertyKey:o}))}function $i(t){return Li(t,\"paint\")}function Di(t){return Li(t,\"layout\")}function Oi(t){let e=[];const r=t.value,n=t.key,i=t.style,s=t.styleSpec;if(\"object\"!==Yn(r))return [new Tt(n,r,`object expected, ${Yn(r)} found`)];r.type||r.ref||e.push(new Tt(n,r,'either \"type\" or \"ref\" is required'));let a=ki(r.type);const o=ki(r.ref);if(r.id){const s=ki(r.id);for(let a=0;a<t.arrayIndex;a++){const t=i.layers[a];ki(t.id)===s&&e.push(new Tt(n,r.id,`duplicate layer id \"${r.id}\", previously used at line ${t.id.__line__}`));}}if(\"ref\"in r){let t;[\"type\",\"source\",\"source-layer\",\"filter\",\"layout\"].forEach((t=>{t in r&&e.push(new Tt(n,r[t],`\"${t}\" is prohibited for ref layers`));})),i.layers.forEach((e=>{ki(e.id)===o&&(t=e);})),t?t.ref?e.push(new Tt(n,r.ref,\"ref cannot reference another ref layer\")):a=ki(t.type):e.push(new Tt(n,r.ref,`ref layer \"${o}\" not found`));}else if(\"background\"!==a)if(r.source){const t=i.sources&&i.sources[r.source],s=t&&ki(t.type);t?\"vector\"===s&&\"raster\"===a?e.push(new Tt(n,r.source,`layer \"${r.id}\" requires a raster source`)):\"raster-dem\"!==s&&\"hillshade\"===a||\"raster-dem\"!==s&&\"color-relief\"===a?e.push(new Tt(n,r.source,`layer \"${r.id}\" requires a raster-dem source`)):\"raster\"===s&&\"raster\"!==a?e.push(new Tt(n,r.source,`layer \"${r.id}\" requires a vector source`)):\"vector\"!==s||r[\"source-layer\"]?\"raster-dem\"===s&&\"hillshade\"!==a&&\"color-relief\"!==a?e.push(new Tt(n,r.source,\"raster-dem source can only be used with layer type 'hillshade' or 'color-relief'.\")):\"line\"!==a||!r.paint||!r.paint[\"line-gradient\"]||\"geojson\"===s&&t.lineMetrics||e.push(new Tt(n,r,`layer \"${r.id}\" specifies a line-gradient, which requires a GeoJSON source with \\`lineMetrics\\` enabled.`)):e.push(new Tt(n,r,`layer \"${r.id}\" must specify a \"source-layer\"`)):e.push(new Tt(n,r.source,`source \"${r.source}\" not found`));}else e.push(new Tt(n,r,'missing required property \"source\"'));return e=e.concat(Ii({key:n,value:r,valueSpec:s.layer,style:t.style,styleSpec:t.styleSpec,validateSpec:t.validateSpec,objectElementValidators:{\"*\":()=>[],type:()=>t.validateSpec({key:`${n}.type`,value:r.type,valueSpec:s.layer.type,style:t.style,styleSpec:t.styleSpec,validateSpec:t.validateSpec,object:r,objectKey:\"type\"}),filter:Vi,layout:t=>Ii({layer:r,key:t.key,value:t.value,style:t.style,styleSpec:t.styleSpec,validateSpec:t.validateSpec,objectElementValidators:{\"*\":t=>Di(Vt({layerType:a},t))}}),paint:t=>Ii({layer:r,key:t.key,value:t.value,style:t.style,styleSpec:t.styleSpec,validateSpec:t.validateSpec,objectElementValidators:{\"*\":t=>$i(Vt({layerType:a},t))}})}})),e}function Ri(t){const e=t.value,r=t.key,n=Yn(e);return \"string\"!==n?[new Tt(r,e,`string expected, ${n} found`)]:[]}const ji={promoteId:function({key:t,value:e}){if(\"string\"===Yn(e))return Ri({key:t,value:e});{const r=[];for(const n in e)r.push(...Ri({key:`${t}.${n}`,value:e[n]}));return r}}};function Ni(t){const e=t.value,r=t.key,n=t.styleSpec,i=t.style,s=t.validateSpec;if(!e.type)return [new Tt(r,e,'\"type\" is required')];const a=ki(e.type);let o;switch(a){case \"vector\":case \"raster\":return o=Ii({key:r,value:e,valueSpec:n[`source_${a.replace(\"-\",\"_\")}`],style:t.style,styleSpec:n,objectElementValidators:ji,validateSpec:s}),o;case \"raster-dem\":return o=function(t){var e;const r=null!==(e=t.sourceName)&&void 0!==e?e:\"\",n=t.value,i=t.styleSpec,s=i.source_raster_dem,a=t.style;let o=[];const l=Yn(n);if(void 0===n)return o;if(\"object\"!==l)return o.push(new Tt(\"source_raster_dem\",n,`object expected, ${l} found`)),o;const u=\"custom\"===ki(n.encoding),c=[\"redFactor\",\"greenFactor\",\"blueFactor\",\"baseShift\"],h=t.value.encoding?`\"${t.value.encoding}\"`:\"Default\";for(const e in n)!u&&c.includes(e)?o.push(new Tt(e,n[e],`In \"${r}\": \"${e}\" is only valid when \"encoding\" is set to \"custom\". ${h} encoding found`)):s[e]?o=o.concat(t.validateSpec({key:e,value:n[e],valueSpec:s[e],validateSpec:t.validateSpec,style:a,styleSpec:i})):o.push(new Tt(e,n[e],`unknown property \"${e}\"`));return o}({sourceName:r,value:e,style:t.style,styleSpec:n,validateSpec:s}),o;case \"geojson\":if(o=Ii({key:r,value:e,valueSpec:n.source_geojson,style:i,styleSpec:n,validateSpec:s,objectElementValidators:ji}),e.cluster)for(const t in e.clusterProperties){const[n,i]=e.clusterProperties[t],s=\"string\"==typeof n?[n,[\"accumulated\"],[\"get\",t]]:n;o.push(...Bi({key:`${r}.${t}.map`,value:i,expressionContext:\"cluster-map\"})),o.push(...Bi({key:`${r}.${t}.reduce`,value:s,expressionContext:\"cluster-reduce\"}));}return o;case \"video\":return Ii({key:r,value:e,valueSpec:n.source_video,style:i,validateSpec:s,styleSpec:n});case \"image\":return Ii({key:r,value:e,valueSpec:n.source_image,style:i,validateSpec:s,styleSpec:n});case \"canvas\":return [new Tt(r,null,\"Please use runtime APIs to add canvas sources, rather than including them in stylesheets.\",\"source.canvas\")];default:return Ti({key:`${r}.type`,value:e.type,valueSpec:{values:[\"vector\",\"raster\",\"raster-dem\",\"geojson\",\"video\",\"image\"]}})}}function Ui(t){const e=t.value,r=t.styleSpec,n=r.light,i=t.style;let s=[];const a=Yn(e);if(void 0===e)return s;if(\"object\"!==a)return s=s.concat([new Tt(\"light\",e,`object expected, ${a} found`)]),s;for(const a in e){const o=a.match(/^(.*)-transition$/);s=s.concat(o&&n[o[1]]&&n[o[1]].transition?t.validateSpec({key:a,value:e[a],valueSpec:r.transition,validateSpec:t.validateSpec,style:i,styleSpec:r}):n[a]?t.validateSpec({key:a,value:e[a],valueSpec:n[a],validateSpec:t.validateSpec,style:i,styleSpec:r}):[new Tt(a,e[a],`unknown property \"${a}\"`)]);}return s}function qi(t){const e=t.value,r=t.styleSpec,n=r.sky,i=t.style,s=Yn(e);if(void 0===e)return [];if(\"object\"!==s)return [new Tt(\"sky\",e,`object expected, ${s} found`)];let a=[];for(const s in e)a=a.concat(n[s]?t.validateSpec({key:s,value:e[s],valueSpec:n[s],style:i,styleSpec:r}):[new Tt(s,e[s],`unknown property \"${s}\"`)]);return a}function Gi(t){const e=t.value,r=t.styleSpec,n=r.terrain,i=t.style;let s=[];const a=Yn(e);if(void 0===e)return s;if(\"object\"!==a)return s=s.concat([new Tt(\"terrain\",e,`object expected, ${a} found`)]),s;for(const a in e)s=s.concat(n[a]?t.validateSpec({key:a,value:e[a],valueSpec:n[a],validateSpec:t.validateSpec,style:i,styleSpec:r}):[new Tt(a,e[a],`unknown property \"${a}\"`)]);return s}function Xi(t){let e=[];const r=t.value,n=t.key;if(Array.isArray(r)){const i=[],s=[];for(const a in r)r[a].id&&i.includes(r[a].id)&&e.push(new Tt(n,r,`all the sprites' ids must be unique, but ${r[a].id} is duplicated`)),i.push(r[a].id),r[a].url&&s.includes(r[a].url)&&e.push(new Tt(n,r,`all the sprites' URLs must be unique, but ${r[a].url} is duplicated`)),s.push(r[a].url),e=e.concat(Ii({key:`${n}[${a}]`,value:r[a],valueSpec:{id:{type:\"string\",required:!0},url:{type:\"string\",required:!0}},validateSpec:t.validateSpec}));return e}return Ri({key:n,value:r})}function Zi(t){return e=t.value,Boolean(e)&&e.constructor===Object?[]:[new Tt(t.key,t.value,`object expected, ${Yn(t.value)} found`)];var e;}const Yi={\"*\":()=>[],array:zi,boolean:function(t){const e=t.value,r=t.key,n=Yn(e);return \"boolean\"!==n?[new Tt(r,e,`boolean expected, ${n} found`)]:[]},number:Pi,color:Ei,constants:Ai,enum:Ti,filter:Vi,function:Ci,layer:Oi,object:Ii,source:Ni,light:Ui,sky:qi,terrain:Gi,projection:function(t){const e=t.value,r=t.styleSpec,n=r.projection,i=t.style,s=Yn(e);if(void 0===e)return [];if(\"object\"!==s)return [new Tt(\"projection\",e,`object expected, ${s} found`)];let a=[];for(const s in e)a=a.concat(n[s]?t.validateSpec({key:s,value:e[s],valueSpec:n[s],style:i,styleSpec:r}):[new Tt(s,e[s],`unknown property \"${s}\"`)]);return a},projectionDefinition:function(t){const e=t.key;let r=t.value;r=r instanceof String?r.valueOf():r;const n=Yn(r);return \"array\"!==n||function(t){return Array.isArray(t)&&3===t.length&&\"string\"==typeof t[0]&&\"string\"==typeof t[1]&&\"number\"==typeof t[2]}(r)||function(t){return !![\"interpolate\",\"step\",\"literal\"].includes(t[0])}(r)?[\"array\",\"string\"].includes(n)?[]:[new Tt(e,r,`projection expected, invalid type \"${n}\" found`)]:[new Tt(e,r,`projection expected, invalid array ${JSON.stringify(r)} found`)]},string:Ri,formatted:function(t){return 0===Ri(t).length?[]:Bi(t)},resolvedImage:function(t){return 0===Ri(t).length?[]:Bi(t)},padding:function(t){const e=t.key,r=t.value;if(\"array\"===Yn(r)){if(r.length<1||r.length>4)return [new Tt(e,r,`padding requires 1 to 4 values; ${r.length} values found`)];const n={type:\"number\"};let i=[];for(let s=0;s<r.length;s++)i=i.concat(t.validateSpec({key:`${e}[${s}]`,value:r[s],validateSpec:t.validateSpec,valueSpec:n}));return i}return Pi({key:e,value:r,valueSpec:{}})},numberArray:function(t){const e=t.key,r=t.value;if(\"array\"===Yn(r)){const n={type:\"number\"};if(r.length<1)return [new Tt(e,r,\"array length at least 1 expected, length 0 found\")];let i=[];for(let s=0;s<r.length;s++)i=i.concat(t.validateSpec({key:`${e}[${s}]`,value:r[s],validateSpec:t.validateSpec,valueSpec:n}));return i}return Pi({key:e,value:r,valueSpec:{}})},colorArray:function(t){const e=t.key,r=t.value;if(\"array\"===Yn(r)){if(r.length<1)return [new Tt(e,r,\"array length at least 1 expected, length 0 found\")];let t=[];for(let n=0;n<r.length;n++)t=t.concat(Ei({key:`${e}[${n}]`,value:r[n]}));return t}return Ei({key:e,value:r})},variableAnchorOffsetCollection:function(t){const e=t.key,r=t.value,n=Yn(r),i=t.styleSpec;if(\"array\"!==n||r.length<1||r.length%2!=0)return [new Tt(e,r,\"variableAnchorOffsetCollection requires a non-empty array of even length\")];let s=[];for(let n=0;n<r.length;n+=2)s=s.concat(Ti({key:`${e}[${n}]`,value:r[n],valueSpec:i.layout_symbol[\"text-anchor\"]})),s=s.concat(zi({key:`${e}[${n+1}]`,value:r[n+1],valueSpec:{length:2,value:\"number\"},validateSpec:t.validateSpec,style:t.style,styleSpec:i}));return s},sprite:Xi,state:Zi};function Hi(t){const e=t.value,r=t.valueSpec,n=t.styleSpec;return t.validateSpec=Hi,r.expression&&Hn(ki(e))?Ci(t):r.expression&&ii(Mi(e))?Bi(t):r.type&&Yi[r.type]?Yi[r.type](t):Ii(Vt({},t,{valueSpec:r.type?n[r.type]:r}))}function Ki(t){const e=t.value,r=t.key,n=Ri(t);return n.length||(-1===e.indexOf(\"{fontstack}\")&&n.push(new Tt(r,e,'\"glyphs\" url must include a \"{fontstack}\" token')),-1===e.indexOf(\"{range}\")&&n.push(new Tt(r,e,'\"glyphs\" url must include a \"{range}\" token'))),n}function Ji(t,e=wt){let r=[];return r=r.concat(Hi({key:\"\",value:t,valueSpec:e.$root,styleSpec:e,style:t,validateSpec:Hi,objectElementValidators:{glyphs:Ki,\"*\":()=>[]}})),t.constants&&(r=r.concat(Ai({key:\"constants\",value:t.constants}))),Qi(r)}function Wi(t){return function(e){return t({...e,validateSpec:Hi})}}function Qi(t){return [].concat(t).sort(((t,e)=>t.line-e.line))}function ts(t){return function(...e){return Qi(t.apply(this,e))}}Ji.source=ts(Wi(Ni)),Ji.sprite=ts(Wi(Xi)),Ji.glyphs=ts(Wi(Ki)),Ji.light=ts(Wi(Ui)),Ji.sky=ts(Wi(qi)),Ji.terrain=ts(Wi(Gi)),Ji.state=ts(Wi(Zi)),Ji.layer=ts(Wi(Oi)),Ji.filter=ts(Wi(Vi)),Ji.paintProperty=ts(Wi($i)),Ji.layoutProperty=ts(Wi(Di));const es=Ji,rs=es.light,ns=es.sky,is=es.paintProperty,ss=es.layoutProperty;function as(t,e){let r=!1;if(e&&e.length)for(const n of e)t.fire(new vt(new Error(n.message))),r=!0;return r}class os{constructor(t,e,r){const n=this.cells=[];if(t instanceof ArrayBuffer){this.arrayBuffer=t;const i=new Int32Array(this.arrayBuffer);t=i[0],this.d=(e=i[1])+2*(r=i[2]);for(let t=0;t<this.d*this.d;t++){const e=i[3+t],r=i[3+t+1];n.push(e===r?null:i.subarray(e,r));}const s=i[3+n.length+1];this.keys=i.subarray(i[3+n.length],s),this.bboxes=i.subarray(s),this.insert=this._insertReadonly;}else {this.d=e+2*r;for(let t=0;t<this.d*this.d;t++)n.push([]);this.keys=[],this.bboxes=[];}this.n=e,this.extent=t,this.padding=r,this.scale=e/t,this.uid=0;const i=r/e*t;this.min=-i,this.max=t+i;}insert(t,e,r,n,i){this._forEachCell(e,r,n,i,this._insertCell,this.uid++,void 0,void 0),this.keys.push(t),this.bboxes.push(e),this.bboxes.push(r),this.bboxes.push(n),this.bboxes.push(i);}_insertReadonly(){throw new Error(\"Cannot insert into a GridIndex created from an ArrayBuffer.\")}_insertCell(t,e,r,n,i,s){this.cells[i].push(s);}query(t,e,r,n,i){const s=this.min,a=this.max;if(t<=s&&e<=s&&a<=r&&a<=n&&!i)return Array.prototype.slice.call(this.keys);{const s=[];return this._forEachCell(t,e,r,n,this._queryCell,s,{},i),s}}_queryCell(t,e,r,n,i,s,a,o){const l=this.cells[i];if(null!==l){const i=this.keys,u=this.bboxes;for(let c=0;c<l.length;c++){const h=l[c];if(void 0===a[h]){const l=4*h;(o?o(u[l+0],u[l+1],u[l+2],u[l+3]):t<=u[l+2]&&e<=u[l+3]&&r>=u[l+0]&&n>=u[l+1])?(a[h]=!0,s.push(i[h])):a[h]=!1;}}}}_forEachCell(t,e,r,n,i,s,a,o){const l=this._convertToCellCoord(t),u=this._convertToCellCoord(e),c=this._convertToCellCoord(r),h=this._convertToCellCoord(n);for(let p=l;p<=c;p++)for(let l=u;l<=h;l++){const u=this.d*l+p;if((!o||o(this._convertFromCellCoord(p),this._convertFromCellCoord(l),this._convertFromCellCoord(p+1),this._convertFromCellCoord(l+1)))&&i.call(this,t,e,r,n,u,s,a,o))return}}_convertFromCellCoord(t){return (t-this.padding)/this.scale}_convertToCellCoord(t){return Math.max(0,Math.min(this.d-1,Math.floor(t*this.scale)+this.padding))}toArrayBuffer(){if(this.arrayBuffer)return this.arrayBuffer;const t=this.cells,e=3+this.cells.length+1+1;let r=0;for(let t=0;t<this.cells.length;t++)r+=this.cells[t].length;const n=new Int32Array(e+r+this.keys.length+this.bboxes.length);n[0]=this.extent,n[1]=this.n,n[2]=this.padding;let i=e;for(let e=0;e<t.length;e++){const r=t[e];n[3+e]=i,n.set(r,i),i+=r.length;}return n[3+t.length]=i,n.set(this.keys,i),i+=this.keys.length,n[3+t.length+1]=i,n.set(this.bboxes,i),i+=this.bboxes.length,n.buffer}static serialize(t,e){const r=t.toArrayBuffer();return e&&e.push(r),{buffer:r}}static deserialize(t){return new os(t.buffer)}}const ls={};function us(t,e,r={}){if(ls[t])throw new Error(`${t} is already registered.`);Object.defineProperty(e,\"_classRegistryKey\",{value:t,writeable:!1}),ls[t]={klass:e,omit:r.omit||[],shallow:r.shallow||[]};}us(\"Object\",Object),us(\"Set\",Set),us(\"TransferableGridIndex\",os),us(\"Color\",Pe),us(\"Error\",Error),us(\"AJAXError\",pt),us(\"ResolvedImage\",Re),us(\"StylePropertyFunction\",ui),us(\"StyleExpression\",ni,{omit:[\"_evaluator\"]}),us(\"ZoomDependentExpression\",oi),us(\"ZoomConstantExpression\",ai),us(\"CompoundExpression\",Vn,{omit:[\"_evaluate\"]});for(const t in Tn)Tn[t]._classRegistryKey||us(`Expression_${t}`,Tn[t]);function cs(t){return t&&\"undefined\"!=typeof ArrayBuffer&&(t instanceof ArrayBuffer||t.constructor&&\"ArrayBuffer\"===t.constructor.name)}function hs(t){return t.$name||t.constructor._classRegistryKey}function ps(t){return !function(t){if(null===t||\"object\"!=typeof t)return !1;const e=hs(t);return !(!e||\"Object\"===e)}(t)&&(null==t||\"boolean\"==typeof t||\"number\"==typeof t||\"string\"==typeof t||t instanceof Boolean||t instanceof Number||t instanceof String||t instanceof Date||t instanceof RegExp||t instanceof Blob||t instanceof Error||cs(t)||J(t)||ArrayBuffer.isView(t)||t instanceof ImageData)}function fs(t,e){if(ps(t))return (cs(t)||J(t))&&e&&e.push(t),ArrayBuffer.isView(t)&&e&&e.push(t.buffer),t instanceof ImageData&&e&&e.push(t.data.buffer),t;if(Array.isArray(t)){const r=[];for(const n of t)r.push(fs(n,e));return r}if(\"object\"!=typeof t)throw new Error(\"can't serialize object of type \"+typeof t);const r=hs(t);if(!r)throw new Error(`can't serialize object of unregistered class ${t.constructor.name}`);if(!ls[r])throw new Error(`${r} is not registered.`);const{klass:n}=ls[r],i=n.serialize?n.serialize(t,e):{};if(n.serialize){if(e&&i===e[e.length-1])throw new Error(\"statically serialized object won't survive transfer of $name property\")}else {for(const n in t){if(!t.hasOwnProperty(n))continue;if(ls[r].omit.indexOf(n)>=0)continue;const s=t[n];i[n]=ls[r].shallow.indexOf(n)>=0?s:fs(s,e);}t instanceof Error&&(i.message=t.message);}if(i.$name)throw new Error(\"$name property is reserved for worker serialization logic.\");return \"Object\"!==r&&(i.$name=r),i}function ds(t){if(ps(t))return t;if(Array.isArray(t))return t.map(ds);if(\"object\"!=typeof t)throw new Error(\"can't deserialize object of type \"+typeof t);const e=hs(t)||\"Object\";if(!ls[e])throw new Error(`can't deserialize unregistered class ${e}`);const{klass:r}=ls[e];if(!r)throw new Error(`can't deserialize unregistered class ${e}`);if(r.deserialize)return r.deserialize(t);const n=Object.create(r.prototype);for(const r of Object.keys(t)){if(\"$name\"===r)continue;const i=t[r];n[r]=ls[e].shallow.indexOf(r)>=0?i:ds(i);}return n}class ys{constructor(){this.first=!0;}update(t,e){const r=Math.floor(t);return this.first?(this.first=!1,this.lastIntegerZoom=r,this.lastIntegerZoomTime=0,this.lastZoom=t,this.lastFloorZoom=r,!0):(this.lastFloorZoom>r?(this.lastIntegerZoom=r+1,this.lastIntegerZoomTime=e):this.lastFloorZoom<r&&(this.lastIntegerZoom=r,this.lastIntegerZoomTime=e),t!==this.lastZoom&&(this.lastZoom=t,this.lastFloorZoom=r,!0))}}const ms={\"Latin-1 Supplement\":t=>t>=128&&t<=255,\"Hangul Jamo\":t=>t>=4352&&t<=4607,Khmer:t=>t>=6016&&t<=6143,\"General Punctuation\":t=>t>=8192&&t<=8303,\"Letterlike Symbols\":t=>t>=8448&&t<=8527,\"Number Forms\":t=>t>=8528&&t<=8591,\"Miscellaneous Technical\":t=>t>=8960&&t<=9215,\"Control Pictures\":t=>t>=9216&&t<=9279,\"Optical Character Recognition\":t=>t>=9280&&t<=9311,\"Enclosed Alphanumerics\":t=>t>=9312&&t<=9471,\"Geometric Shapes\":t=>t>=9632&&t<=9727,\"Miscellaneous Symbols\":t=>t>=9728&&t<=9983,\"Miscellaneous Symbols and Arrows\":t=>t>=11008&&t<=11263,\"Ideographic Description Characters\":t=>t>=12272&&t<=12287,\"CJK Symbols and Punctuation\":t=>t>=12288&&t<=12351,Hiragana:t=>t>=12352&&t<=12447,Katakana:t=>t>=12448&&t<=12543,Kanbun:t=>t>=12688&&t<=12703,\"CJK Strokes\":t=>t>=12736&&t<=12783,\"Enclosed CJK Letters and Months\":t=>t>=12800&&t<=13055,\"CJK Compatibility\":t=>t>=13056&&t<=13311,\"Yijing Hexagram Symbols\":t=>t>=19904&&t<=19967,\"CJK Unified Ideographs\":t=>t>=19968&&t<=40959,\"Hangul Syllables\":t=>t>=44032&&t<=55215,\"Private Use Area\":t=>t>=57344&&t<=63743,\"Vertical Forms\":t=>t>=65040&&t<=65055,\"CJK Compatibility Forms\":t=>t>=65072&&t<=65103,\"Small Form Variants\":t=>t>=65104&&t<=65135,\"Halfwidth and Fullwidth Forms\":t=>t>=65280&&t<=65519};function gs(t){for(const e of t)if(Ss(e.charCodeAt(0)))return !0;return !1}function xs(t){for(const e of t)if(!ws(e.charCodeAt(0)))return !1;return !0}function vs(t){const e=t.map((t=>{try{return new RegExp(`\\\\p{sc=${t}}`,\"u\").source}catch(t){return null}})).filter((t=>t));return new RegExp(e.join(\"|\"),\"u\")}const bs=vs([\"Arab\",\"Dupl\",\"Mong\",\"Ougr\",\"Syrc\"]);function ws(t){return !bs.test(String.fromCodePoint(t))}const _s=vs([\"Bopo\",\"Hani\",\"Hira\",\"Kana\",\"Kits\",\"Nshu\",\"Tang\",\"Yiii\"]);function Ss(t){return !(746!==t&&747!==t&&(t<4352||!(ms[\"CJK Compatibility Forms\"](t)&&!(t>=65097&&t<=65103)||ms[\"CJK Compatibility\"](t)||ms[\"CJK Strokes\"](t)||!(!ms[\"CJK Symbols and Punctuation\"](t)||t>=12296&&t<=12305||t>=12308&&t<=12319||12336===t)||ms[\"Enclosed CJK Letters and Months\"](t)||ms[\"Ideographic Description Characters\"](t)||ms.Kanbun(t)||ms.Katakana(t)&&12540!==t||!(!ms[\"Halfwidth and Fullwidth Forms\"](t)||65288===t||65289===t||65293===t||t>=65306&&t<=65310||65339===t||65341===t||65343===t||t>=65371&&t<=65503||65507===t||t>=65512&&t<=65519)||!(!ms[\"Small Form Variants\"](t)||t>=65112&&t<=65118||t>=65123&&t<=65126)||ms[\"Vertical Forms\"](t)||ms[\"Yijing Hexagram Symbols\"](t)||/\\p{sc=Cans}/u.test(String.fromCodePoint(t))||/\\p{sc=Hang}/u.test(String.fromCodePoint(t))||_s.test(String.fromCodePoint(t)))))}function As(t){return !(Ss(t)||function(t){return !!(ms[\"Latin-1 Supplement\"](t)&&(167===t||169===t||174===t||177===t||188===t||189===t||190===t||215===t||247===t)||ms[\"General Punctuation\"](t)&&(8214===t||8224===t||8225===t||8240===t||8241===t||8251===t||8252===t||8258===t||8263===t||8264===t||8265===t||8273===t)||ms[\"Letterlike Symbols\"](t)||ms[\"Number Forms\"](t)||ms[\"Miscellaneous Technical\"](t)&&(t>=8960&&t<=8967||t>=8972&&t<=8991||t>=8996&&t<=9e3||9003===t||t>=9085&&t<=9114||t>=9150&&t<=9165||9167===t||t>=9169&&t<=9179||t>=9186&&t<=9215)||ms[\"Control Pictures\"](t)&&9251!==t||ms[\"Optical Character Recognition\"](t)||ms[\"Enclosed Alphanumerics\"](t)||ms[\"Geometric Shapes\"](t)||ms[\"Miscellaneous Symbols\"](t)&&!(t>=9754&&t<=9759)||ms[\"Miscellaneous Symbols and Arrows\"](t)&&(t>=11026&&t<=11055||t>=11088&&t<=11097||t>=11192&&t<=11243)||ms[\"CJK Symbols and Punctuation\"](t)||ms.Katakana(t)||ms[\"Private Use Area\"](t)||ms[\"CJK Compatibility Forms\"](t)||ms[\"Small Form Variants\"](t)||ms[\"Halfwidth and Fullwidth Forms\"](t)||8734===t||8756===t||8757===t||t>=9984&&t<=10087||t>=10102&&t<=10131||65532===t||65533===t)}(t))}const ks=vs([\"Adlm\",\"Arab\",\"Armi\",\"Avst\",\"Chrs\",\"Cprt\",\"Egyp\",\"Elym\",\"Gara\",\"Hatr\",\"Hebr\",\"Hung\",\"Khar\",\"Lydi\",\"Mand\",\"Mani\",\"Mend\",\"Merc\",\"Mero\",\"Narb\",\"Nbat\",\"Nkoo\",\"Orkh\",\"Palm\",\"Phli\",\"Phlp\",\"Phnx\",\"Prti\",\"Rohg\",\"Samr\",\"Sarb\",\"Sogo\",\"Syrc\",\"Thaa\",\"Todr\",\"Yezi\"]);function Ms(t){return ks.test(String.fromCodePoint(t))}function Is(t,e){return !(!e&&Ms(t)||t>=2304&&t<=3583||t>=3840&&t<=4255||ms.Khmer(t))}function zs(t){for(const e of t)if(Ms(e.charCodeAt(0)))return !0;return !1}const Ps=new class{constructor(){this.TIMEOUT=5e3,this.applyArabicShaping=null,this.processBidirectionalText=null,this.processStyledBidirectionalText=null,this.pluginStatus=\"unavailable\",this.pluginURL=null,this.loadScriptResolve=()=>{};}setState(t){this.pluginStatus=t.pluginStatus,this.pluginURL=t.pluginURL;}getState(){return {pluginStatus:this.pluginStatus,pluginURL:this.pluginURL}}setMethods(t){if(Ps.isParsed())throw new Error(\"RTL text plugin already registered.\");this.applyArabicShaping=t.applyArabicShaping,this.processBidirectionalText=t.processBidirectionalText,this.processStyledBidirectionalText=t.processStyledBidirectionalText,this.loadScriptResolve();}isParsed(){return null!=this.applyArabicShaping&&null!=this.processBidirectionalText&&null!=this.processStyledBidirectionalText}getRTLTextPluginStatus(){return this.pluginStatus}syncState(t,r){return e(this,void 0,void 0,(function*(){if(this.isParsed())return this.getState();if(\"loading\"!==t.pluginStatus)return this.setState(t),t;const e=t.pluginURL,n=new Promise((t=>{this.loadScriptResolve=t;}));r(e);const i=new Promise((t=>setTimeout((()=>t()),this.TIMEOUT)));if(yield Promise.race([n,i]),this.isParsed()){const t={pluginStatus:\"loaded\",pluginURL:e};return this.setState(t),t}throw this.setState({pluginStatus:\"error\",pluginURL:\"\"}),new Error(`RTL Text Plugin failed to import scripts from ${e}`)}))}};class Cs{constructor(t,e){this.zoom=t,e?(this.now=e.now||0,this.fadeDuration=e.fadeDuration||0,this.zoomHistory=e.zoomHistory||new ys,this.transition=e.transition||{},this.globalState=e.globalState||{}):(this.now=0,this.fadeDuration=0,this.zoomHistory=new ys,this.transition={},this.globalState={});}isSupportedScript(t){return function(t,e){for(const r of t)if(!Is(r.charCodeAt(0),e))return !1;return !0}(t,\"loaded\"===Ps.getRTLTextPluginStatus())}crossFadingFactor(){return 0===this.fadeDuration?1:Math.min((this.now-this.zoomHistory.lastIntegerZoomTime)/this.fadeDuration,1)}getCrossfadeParameters(){const t=this.zoom,e=t-Math.floor(t),r=this.crossFadingFactor();return t>this.zoomHistory.lastIntegerZoom?{fromScale:2,toScale:1,t:e+(1-e)*r}:{fromScale:.5,toScale:1,t:1-(1-r)*e}}}class Bs{constructor(t,e){this.property=t,this.value=e,this.expression=function(t,e){if(Hn(t))return new ui(t,e);if(ii(t)){const r=li(t,e);if(\"error\"===r.result)throw new Error(r.value.map((t=>`${t.key}: ${t.message}`)).join(\", \"));return r.value}{let r=t;return \"color\"===e.type&&\"string\"==typeof t?r=Pe.parse(t):\"padding\"!==e.type||\"number\"!=typeof t&&!Array.isArray(t)?\"numberArray\"!==e.type||\"number\"!=typeof t&&!Array.isArray(t)?\"colorArray\"!==e.type||\"string\"!=typeof t&&!Array.isArray(t)?\"variableAnchorOffsetCollection\"===e.type&&Array.isArray(t)?r=Oe.parse(t):\"projectionDefinition\"===e.type&&\"string\"==typeof t&&(r=je.parse(t)):r=Le.parse(t):r=Fe.parse(t):r=Ve.parse(t),{globalStateRefs:new Set,kind:\"constant\",evaluate:()=>r}}}(void 0===e?t.specification.default:e,t.specification);}isDataDriven(){return \"source\"===this.expression.kind||\"composite\"===this.expression.kind}getGlobalStateRefs(){return this.expression.globalStateRefs||new Set}possiblyEvaluate(t,e,r){return this.property.possiblyEvaluate(this,t,e,r)}}class Es{constructor(t){this.property=t,this.value=new Bs(t,void 0);}transitioned(t,e){return new Vs(this.property,this.value,e,j({},t.transition,this.transition),t.now)}untransitioned(){return new Vs(this.property,this.value,null,{},0)}}class Ts{constructor(t){this._properties=t,this._values=Object.create(t.defaultTransitionablePropertyValues);}getValue(t){return G(this._values[t].value.value)}setValue(t,e){Object.prototype.hasOwnProperty.call(this._values,t)||(this._values[t]=new Es(this._values[t].property)),this._values[t].value=new Bs(this._values[t].property,null===e?void 0:G(e));}getTransition(t){return G(this._values[t].transition)}setTransition(t,e){Object.prototype.hasOwnProperty.call(this._values,t)||(this._values[t]=new Es(this._values[t].property)),this._values[t].transition=G(e)||void 0;}serialize(){const t={};for(const e of Object.keys(this._values)){const r=this.getValue(e);void 0!==r&&(t[e]=r);const n=this.getTransition(e);void 0!==n&&(t[`${e}-transition`]=n);}return t}transitioned(t,e){const r=new Fs(this._properties);for(const n of Object.keys(this._values))r._values[n]=this._values[n].transitioned(t,e._values[n]);return r}untransitioned(){const t=new Fs(this._properties);for(const e of Object.keys(this._values))t._values[e]=this._values[e].untransitioned();return t}}class Vs{constructor(t,e,r,n,i){this.property=t,this.value=e,this.begin=i+n.delay||0,this.end=this.begin+n.duration||0,t.specification.transition&&(n.delay||n.duration)&&(this.prior=r);}possiblyEvaluate(t,e,r){const n=t.now||0,i=this.value.possiblyEvaluate(t,e,r),s=this.prior;if(s){if(n>this.end)return this.prior=null,i;if(this.value.isDataDriven())return this.prior=null,i;if(n<this.begin)return s.possiblyEvaluate(t,e,r);{const a=(n-this.begin)/(this.end-this.begin);return this.property.interpolate(s.possiblyEvaluate(t,e,r),i,L(a))}}return i}}class Fs{constructor(t){this._properties=t,this._values=Object.create(t.defaultTransitioningPropertyValues);}possiblyEvaluate(t,e,r){const n=new Ds(this._properties);for(const i of Object.keys(this._values))n._values[i]=this._values[i].possiblyEvaluate(t,e,r);return n}hasTransition(){for(const t of Object.keys(this._values))if(this._values[t].prior)return !0;return !1}}class Ls{constructor(t){this._properties=t,this._values=Object.create(t.defaultPropertyValues);}hasValue(t){return void 0!==this._values[t].value}getValue(t){return G(this._values[t].value)}setValue(t,e){this._values[t]=new Bs(this._values[t].property,null===e?void 0:G(e));}serialize(){const t={};for(const e of Object.keys(this._values)){const r=this.getValue(e);void 0!==r&&(t[e]=r);}return t}possiblyEvaluate(t,e,r){const n=new Ds(this._properties);for(const i of Object.keys(this._values))n._values[i]=this._values[i].possiblyEvaluate(t,e,r);return n}}class $s{constructor(t,e,r){this.property=t,this.value=e,this.parameters=r;}isConstant(){return \"constant\"===this.value.kind}constantOr(t){return \"constant\"===this.value.kind?this.value.value:t}evaluate(t,e,r,n){return this.property.evaluate(this.value,this.parameters,t,e,r,n)}}class Ds{constructor(t){this._properties=t,this._values=Object.create(t.defaultPossiblyEvaluatedValues);}get(t){return this._values[t]}}class Os{constructor(t){this.specification=t;}possiblyEvaluate(t,e){if(t.isDataDriven())throw new Error(\"Value should not be data driven\");return t.expression.evaluate(e)}interpolate(t,e,r){const n=gr[this.specification.type];return n?n(t,e,r):t}}class Rs{constructor(t,e){this.specification=t,this.overrides=e;}possiblyEvaluate(t,e,r,n){return new $s(this,\"constant\"===t.expression.kind||\"camera\"===t.expression.kind?{kind:\"constant\",value:t.expression.evaluate(e,null,{},r,n)}:t.expression,e)}interpolate(t,e,r){if(\"constant\"!==t.value.kind||\"constant\"!==e.value.kind)return t;if(void 0===t.value.value||void 0===e.value.value)return new $s(this,{kind:\"constant\",value:void 0},t.parameters);const n=gr[this.specification.type];if(n){const i=n(t.value.value,e.value.value,r);return new $s(this,{kind:\"constant\",value:i},t.parameters)}return t}evaluate(t,e,r,n,i,s){return \"constant\"===t.kind?t.value:t.evaluate(e,r,n,i,s)}}class js extends Rs{possiblyEvaluate(t,e,r,n){if(void 0===t.value)return new $s(this,{kind:\"constant\",value:void 0},e);if(\"constant\"===t.expression.kind){const i=t.expression.evaluate(e,null,{},r,n),s=\"resolvedImage\"===t.property.specification.type&&\"string\"!=typeof i?i.name:i,a=this._calculate(s,s,s,e);return new $s(this,{kind:\"constant\",value:a},e)}if(\"camera\"===t.expression.kind){const r=this._calculate(t.expression.evaluate({zoom:e.zoom-1}),t.expression.evaluate({zoom:e.zoom}),t.expression.evaluate({zoom:e.zoom+1}),e);return new $s(this,{kind:\"constant\",value:r},e)}return new $s(this,t.expression,e)}evaluate(t,e,r,n,i,s){if(\"source\"===t.kind){const a=t.evaluate(e,r,n,i,s);return this._calculate(a,a,a,e)}return \"composite\"===t.kind?this._calculate(t.evaluate({zoom:Math.floor(e.zoom)-1},r,n),t.evaluate({zoom:Math.floor(e.zoom)},r,n),t.evaluate({zoom:Math.floor(e.zoom)+1},r,n),e):t.value}_calculate(t,e,r,n){return n.zoom>n.zoomHistory.lastIntegerZoom?{from:t,to:e}:{from:r,to:e}}interpolate(t){return t}}class Ns{constructor(t){this.specification=t;}possiblyEvaluate(t,e,r,n){if(void 0!==t.value){if(\"constant\"===t.expression.kind){const i=t.expression.evaluate(e,null,{},r,n);return this._calculate(i,i,i,e)}return this._calculate(t.expression.evaluate(new Cs(Math.floor(e.zoom-1),e)),t.expression.evaluate(new Cs(Math.floor(e.zoom),e)),t.expression.evaluate(new Cs(Math.floor(e.zoom+1),e)),e)}}_calculate(t,e,r,n){return n.zoom>n.zoomHistory.lastIntegerZoom?{from:t,to:e}:{from:r,to:e}}interpolate(t){return t}}class Us{constructor(t){this.specification=t;}possiblyEvaluate(t,e,r,n){return !!t.expression.evaluate(e,null,{},r,n)}interpolate(){return !1}}class qs{constructor(t){this.properties=t,this.defaultPropertyValues={},this.defaultTransitionablePropertyValues={},this.defaultTransitioningPropertyValues={},this.defaultPossiblyEvaluatedValues={},this.overridableProperties=[];for(const e in t){const r=t[e];r.specification.overridable&&this.overridableProperties.push(e);const n=this.defaultPropertyValues[e]=new Bs(r,void 0),i=this.defaultTransitionablePropertyValues[e]=new Es(r);this.defaultTransitioningPropertyValues[e]=i.untransitioned(),this.defaultPossiblyEvaluatedValues[e]=n.possiblyEvaluate({});}}}us(\"DataDrivenProperty\",Rs),us(\"DataConstantProperty\",Os),us(\"CrossFadedDataDrivenProperty\",js),us(\"CrossFadedProperty\",Ns),us(\"ColorRampProperty\",Us);const Gs=\"-transition\";class Xs extends bt{constructor(t,e){if(super(),this.id=t.id,this.type=t.type,this._featureFilter={filter:()=>!0,needGeometry:!1,getGlobalStateRefs:()=>new Set},\"custom\"!==t.type&&(this.metadata=t.metadata,this.minzoom=t.minzoom,this.maxzoom=t.maxzoom,\"background\"!==t.type&&(this.source=t.source,this.sourceLayer=t[\"source-layer\"],this.filter=t.filter,this._featureFilter=di(t.filter)),e.layout&&(this._unevaluatedLayout=new Ls(e.layout)),e.paint)){this._transitionablePaint=new Ts(e.paint);for(const e in t.paint)this.setPaintProperty(e,t.paint[e],{validate:!1});for(const e in t.layout)this.setLayoutProperty(e,t.layout[e],{validate:!1});this._transitioningPaint=this._transitionablePaint.untransitioned(),this.paint=new Ds(e.paint);}}setFilter(t){this.filter=t,this._featureFilter=di(t);}getCrossfadeParameters(){return this._crossfadeParameters}getLayoutProperty(t){return \"visibility\"===t?this.visibility:this._unevaluatedLayout.getValue(t)}getLayoutAffectingGlobalStateRefs(){const t=new Set;if(this._unevaluatedLayout)for(const e in this._unevaluatedLayout._values){const r=this._unevaluatedLayout._values[e];for(const e of r.getGlobalStateRefs())t.add(e);}for(const e of this._featureFilter.getGlobalStateRefs())t.add(e);return t}setLayoutProperty(t,e,r={}){null!=e&&this._validate(ss,`layers.${this.id}.layout.${t}`,t,e,r)||(\"visibility\"!==t?this._unevaluatedLayout.setValue(t,e):this.visibility=e);}getPaintProperty(t){return t.endsWith(Gs)?this._transitionablePaint.getTransition(t.slice(0,-11)):this._transitionablePaint.getValue(t)}setPaintProperty(t,e,r={}){if(null!=e&&this._validate(is,`layers.${this.id}.paint.${t}`,t,e,r))return !1;if(t.endsWith(Gs))return this._transitionablePaint.setTransition(t.slice(0,-11),e||void 0),!1;{const r=this._transitionablePaint._values[t],n=\"cross-faded-data-driven\"===r.property.specification[\"property-type\"],i=r.value.isDataDriven(),s=r.value;this._transitionablePaint.setValue(t,e),this._handleSpecialPaintPropertyUpdate(t);const a=this._transitionablePaint._values[t].value;return a.isDataDriven()||i||n||this._handleOverridablePaintPropertyUpdate(t,s,a)}}_handleSpecialPaintPropertyUpdate(t){}_handleOverridablePaintPropertyUpdate(t,e,r){return !1}isHidden(t){return !!(this.minzoom&&t<this.minzoom)||!!(this.maxzoom&&t>=this.maxzoom)||\"none\"===this.visibility}updateTransitions(t){this._transitioningPaint=this._transitionablePaint.transitioned(t,this._transitioningPaint);}hasTransition(){return this._transitioningPaint.hasTransition()}recalculate(t,e){t.getCrossfadeParameters&&(this._crossfadeParameters=t.getCrossfadeParameters()),this._unevaluatedLayout&&(this.layout=this._unevaluatedLayout.possiblyEvaluate(t,void 0,e)),this.paint=this._transitioningPaint.possiblyEvaluate(t,void 0,e);}serialize(){const t={id:this.id,type:this.type,source:this.source,\"source-layer\":this.sourceLayer,metadata:this.metadata,minzoom:this.minzoom,maxzoom:this.maxzoom,filter:this.filter,layout:this._unevaluatedLayout&&this._unevaluatedLayout.serialize(),paint:this._transitionablePaint&&this._transitionablePaint.serialize()};return this.visibility&&(t.layout=t.layout||{},t.layout.visibility=this.visibility),q(t,((t,e)=>!(void 0===t||\"layout\"===e&&!Object.keys(t).length||\"paint\"===e&&!Object.keys(t).length)))}_validate(t,e,r,n,i={}){return (!i||!1!==i.validate)&&as(this,t.call(es,{key:e,layerType:this.type,objectKey:r,value:n,styleSpec:wt,style:{glyphs:!0,sprite:!0}}))}is3D(){return !1}isTileClipped(){return !1}hasOffscreenPass(){return !1}resize(){}isStateDependent(){for(const t in this.paint._values){const e=this.paint.get(t);if(e instanceof $s&&Gn(e.property.specification)&&(\"source\"===e.value.kind||\"composite\"===e.value.kind)&&e.value.isStateDependent)return !0}return !1}}const Zs={Int8:Int8Array,Uint8:Uint8Array,Int16:Int16Array,Uint16:Uint16Array,Int32:Int32Array,Uint32:Uint32Array,Float32:Float32Array};class Ys{constructor(t,e){this._structArray=t,this._pos1=e*this.size,this._pos2=this._pos1/2,this._pos4=this._pos1/4,this._pos8=this._pos1/8;}}class Hs{constructor(){this.isTransferred=!1,this.capacity=-1,this.resize(0);}static serialize(t,e){return t._trim(),e&&(t.isTransferred=!0,e.push(t.arrayBuffer)),{length:t.length,arrayBuffer:t.arrayBuffer}}static deserialize(t){const e=Object.create(this.prototype);return e.arrayBuffer=t.arrayBuffer,e.length=t.length,e.capacity=t.arrayBuffer.byteLength/e.bytesPerElement,e._refreshViews(),e}_trim(){this.length!==this.capacity&&(this.capacity=this.length,this.arrayBuffer=this.arrayBuffer.slice(0,this.length*this.bytesPerElement),this._refreshViews());}clear(){this.length=0;}resize(t){this.reserve(t),this.length=t;}reserve(t){if(t>this.capacity){this.capacity=Math.max(t,Math.floor(5*this.capacity),128),this.arrayBuffer=new ArrayBuffer(this.capacity*this.bytesPerElement);const e=this.uint8;this._refreshViews(),e&&this.uint8.set(e);}}_refreshViews(){throw new Error(\"_refreshViews() must be implemented by each concrete StructArray layout\")}}function Ks(t,e=1){let r=0,n=0;return {members:t.map((t=>{const i=Zs[t.type].BYTES_PER_ELEMENT,s=r=Js(r,Math.max(e,i)),a=t.components||1;return n=Math.max(n,i),r+=i*a,{name:t.name,type:t.type,components:a,offset:s}})),size:Js(r,Math.max(n,e)),alignment:e}}function Js(t,e){return Math.ceil(t/e)*e}class Ws extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e){const r=this.length;return this.resize(r+1),this.emplace(r,t,e)}emplace(t,e,r){const n=2*t;return this.int16[n+0]=e,this.int16[n+1]=r,t}}Ws.prototype.bytesPerElement=4,us(\"StructArrayLayout2i4\",Ws);class Qs extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r){const n=this.length;return this.resize(n+1),this.emplace(n,t,e,r)}emplace(t,e,r,n){const i=3*t;return this.int16[i+0]=e,this.int16[i+1]=r,this.int16[i+2]=n,t}}Qs.prototype.bytesPerElement=6,us(\"StructArrayLayout3i6\",Qs);class ta extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n){const i=this.length;return this.resize(i+1),this.emplace(i,t,e,r,n)}emplace(t,e,r,n,i){const s=4*t;return this.int16[s+0]=e,this.int16[s+1]=r,this.int16[s+2]=n,this.int16[s+3]=i,t}}ta.prototype.bytesPerElement=8,us(\"StructArrayLayout4i8\",ta);class ea extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s){const a=this.length;return this.resize(a+1),this.emplace(a,t,e,r,n,i,s)}emplace(t,e,r,n,i,s,a){const o=6*t;return this.int16[o+0]=e,this.int16[o+1]=r,this.int16[o+2]=n,this.int16[o+3]=i,this.int16[o+4]=s,this.int16[o+5]=a,t}}ea.prototype.bytesPerElement=12,us(\"StructArrayLayout2i4i12\",ea);class ra extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s){const a=this.length;return this.resize(a+1),this.emplace(a,t,e,r,n,i,s)}emplace(t,e,r,n,i,s,a){const o=4*t,l=8*t;return this.int16[o+0]=e,this.int16[o+1]=r,this.uint8[l+4]=n,this.uint8[l+5]=i,this.uint8[l+6]=s,this.uint8[l+7]=a,t}}ra.prototype.bytesPerElement=8,us(\"StructArrayLayout2i4ub8\",ra);class na extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e){const r=this.length;return this.resize(r+1),this.emplace(r,t,e)}emplace(t,e,r){const n=2*t;return this.float32[n+0]=e,this.float32[n+1]=r,t}}na.prototype.bytesPerElement=8,us(\"StructArrayLayout2f8\",na);class ia extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s,a,o,l,u){const c=this.length;return this.resize(c+1),this.emplace(c,t,e,r,n,i,s,a,o,l,u)}emplace(t,e,r,n,i,s,a,o,l,u,c){const h=10*t;return this.uint16[h+0]=e,this.uint16[h+1]=r,this.uint16[h+2]=n,this.uint16[h+3]=i,this.uint16[h+4]=s,this.uint16[h+5]=a,this.uint16[h+6]=o,this.uint16[h+7]=l,this.uint16[h+8]=u,this.uint16[h+9]=c,t}}ia.prototype.bytesPerElement=20,us(\"StructArrayLayout10ui20\",ia);class sa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s,a,o,l,u,c,h){const p=this.length;return this.resize(p+1),this.emplace(p,t,e,r,n,i,s,a,o,l,u,c,h)}emplace(t,e,r,n,i,s,a,o,l,u,c,h,p){const f=12*t;return this.int16[f+0]=e,this.int16[f+1]=r,this.int16[f+2]=n,this.int16[f+3]=i,this.uint16[f+4]=s,this.uint16[f+5]=a,this.uint16[f+6]=o,this.uint16[f+7]=l,this.int16[f+8]=u,this.int16[f+9]=c,this.int16[f+10]=h,this.int16[f+11]=p,t}}sa.prototype.bytesPerElement=24,us(\"StructArrayLayout4i4ui4i24\",sa);class aa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e,r){const n=this.length;return this.resize(n+1),this.emplace(n,t,e,r)}emplace(t,e,r,n){const i=3*t;return this.float32[i+0]=e,this.float32[i+1]=r,this.float32[i+2]=n,t}}aa.prototype.bytesPerElement=12,us(\"StructArrayLayout3f12\",aa);class oa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer);}emplaceBack(t){const e=this.length;return this.resize(e+1),this.emplace(e,t)}emplace(t,e){return this.uint32[1*t+0]=e,t}}oa.prototype.bytesPerElement=4,us(\"StructArrayLayout1ul4\",oa);class la extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s,a,o,l){const u=this.length;return this.resize(u+1),this.emplace(u,t,e,r,n,i,s,a,o,l)}emplace(t,e,r,n,i,s,a,o,l,u){const c=10*t,h=5*t;return this.int16[c+0]=e,this.int16[c+1]=r,this.int16[c+2]=n,this.int16[c+3]=i,this.int16[c+4]=s,this.int16[c+5]=a,this.uint32[h+3]=o,this.uint16[c+8]=l,this.uint16[c+9]=u,t}}la.prototype.bytesPerElement=20,us(\"StructArrayLayout6i1ul2ui20\",la);class ua extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s){const a=this.length;return this.resize(a+1),this.emplace(a,t,e,r,n,i,s)}emplace(t,e,r,n,i,s,a){const o=6*t;return this.int16[o+0]=e,this.int16[o+1]=r,this.int16[o+2]=n,this.int16[o+3]=i,this.int16[o+4]=s,this.int16[o+5]=a,t}}ua.prototype.bytesPerElement=12,us(\"StructArrayLayout2i2i2i12\",ua);class ca extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i){const s=this.length;return this.resize(s+1),this.emplace(s,t,e,r,n,i)}emplace(t,e,r,n,i,s){const a=4*t,o=8*t;return this.float32[a+0]=e,this.float32[a+1]=r,this.float32[a+2]=n,this.int16[o+6]=i,this.int16[o+7]=s,t}}ca.prototype.bytesPerElement=16,us(\"StructArrayLayout2f1f2i16\",ca);class ha extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s){const a=this.length;return this.resize(a+1),this.emplace(a,t,e,r,n,i,s)}emplace(t,e,r,n,i,s,a){const o=16*t,l=4*t,u=8*t;return this.uint8[o+0]=e,this.uint8[o+1]=r,this.float32[l+1]=n,this.float32[l+2]=i,this.int16[u+6]=s,this.int16[u+7]=a,t}}ha.prototype.bytesPerElement=16,us(\"StructArrayLayout2ub2f2i16\",ha);class pa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e,r){const n=this.length;return this.resize(n+1),this.emplace(n,t,e,r)}emplace(t,e,r,n){const i=3*t;return this.uint16[i+0]=e,this.uint16[i+1]=r,this.uint16[i+2]=n,t}}pa.prototype.bytesPerElement=6,us(\"StructArrayLayout3ui6\",pa);class fa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m){const g=this.length;return this.resize(g+1),this.emplace(g,t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m)}emplace(t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g){const x=24*t,v=12*t,b=48*t;return this.int16[x+0]=e,this.int16[x+1]=r,this.uint16[x+2]=n,this.uint16[x+3]=i,this.uint32[v+2]=s,this.uint32[v+3]=a,this.uint32[v+4]=o,this.uint16[x+10]=l,this.uint16[x+11]=u,this.uint16[x+12]=c,this.float32[v+7]=h,this.float32[v+8]=p,this.uint8[b+36]=f,this.uint8[b+37]=d,this.uint8[b+38]=y,this.uint32[v+10]=m,this.int16[x+22]=g,t}}fa.prototype.bytesPerElement=48,us(\"StructArrayLayout2i2ui3ul3ui2f3ub1ul1i48\",fa);class da extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.int16=new Int16Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g,x,v,b,w,_,S,A,k,M,I){const z=this.length;return this.resize(z+1),this.emplace(z,t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g,x,v,b,w,_,S,A,k,M,I)}emplace(t,e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g,x,v,b,w,_,S,A,k,M,I,z){const P=32*t,C=16*t;return this.int16[P+0]=e,this.int16[P+1]=r,this.int16[P+2]=n,this.int16[P+3]=i,this.int16[P+4]=s,this.int16[P+5]=a,this.int16[P+6]=o,this.int16[P+7]=l,this.uint16[P+8]=u,this.uint16[P+9]=c,this.uint16[P+10]=h,this.uint16[P+11]=p,this.uint16[P+12]=f,this.uint16[P+13]=d,this.uint16[P+14]=y,this.uint16[P+15]=m,this.uint16[P+16]=g,this.uint16[P+17]=x,this.uint16[P+18]=v,this.uint16[P+19]=b,this.uint16[P+20]=w,this.uint16[P+21]=_,this.uint16[P+22]=S,this.uint32[C+12]=A,this.float32[C+13]=k,this.float32[C+14]=M,this.uint16[P+30]=I,this.uint16[P+31]=z,t}}da.prototype.bytesPerElement=64,us(\"StructArrayLayout8i15ui1ul2f2ui64\",da);class ya extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t){const e=this.length;return this.resize(e+1),this.emplace(e,t)}emplace(t,e){return this.float32[1*t+0]=e,t}}ya.prototype.bytesPerElement=4,us(\"StructArrayLayout1f4\",ya);class ma extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e,r){const n=this.length;return this.resize(n+1),this.emplace(n,t,e,r)}emplace(t,e,r,n){const i=3*t;return this.uint16[6*t+0]=e,this.float32[i+1]=r,this.float32[i+2]=n,t}}ma.prototype.bytesPerElement=12,us(\"StructArrayLayout1ui2f12\",ma);class ga extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint32=new Uint32Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e,r){const n=this.length;return this.resize(n+1),this.emplace(n,t,e,r)}emplace(t,e,r,n){const i=4*t;return this.uint32[2*t+0]=e,this.uint16[i+2]=r,this.uint16[i+3]=n,t}}ga.prototype.bytesPerElement=8,us(\"StructArrayLayout1ul2ui8\",ga);class xa extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t,e){const r=this.length;return this.resize(r+1),this.emplace(r,t,e)}emplace(t,e,r){const n=2*t;return this.uint16[n+0]=e,this.uint16[n+1]=r,t}}xa.prototype.bytesPerElement=4,us(\"StructArrayLayout2ui4\",xa);class va extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.uint16=new Uint16Array(this.arrayBuffer);}emplaceBack(t){const e=this.length;return this.resize(e+1),this.emplace(e,t)}emplace(t,e){return this.uint16[1*t+0]=e,t}}va.prototype.bytesPerElement=2,us(\"StructArrayLayout1ui2\",va);class ba extends Hs{_refreshViews(){this.uint8=new Uint8Array(this.arrayBuffer),this.float32=new Float32Array(this.arrayBuffer);}emplaceBack(t,e,r,n){const i=this.length;return this.resize(i+1),this.emplace(i,t,e,r,n)}emplace(t,e,r,n,i){const s=4*t;return this.float32[s+0]=e,this.float32[s+1]=r,this.float32[s+2]=n,this.float32[s+3]=i,t}}ba.prototype.bytesPerElement=16,us(\"StructArrayLayout4f16\",ba);class wa extends Ys{get anchorPointX(){return this._structArray.int16[this._pos2+0]}get anchorPointY(){return this._structArray.int16[this._pos2+1]}get x1(){return this._structArray.int16[this._pos2+2]}get y1(){return this._structArray.int16[this._pos2+3]}get x2(){return this._structArray.int16[this._pos2+4]}get y2(){return this._structArray.int16[this._pos2+5]}get featureIndex(){return this._structArray.uint32[this._pos4+3]}get sourceLayerIndex(){return this._structArray.uint16[this._pos2+8]}get bucketIndex(){return this._structArray.uint16[this._pos2+9]}get anchorPoint(){return new l(this.anchorPointX,this.anchorPointY)}}wa.prototype.size=20;class _a extends la{get(t){return new wa(this,t)}}us(\"CollisionBoxArray\",_a);class Sa extends Ys{get anchorX(){return this._structArray.int16[this._pos2+0]}get anchorY(){return this._structArray.int16[this._pos2+1]}get glyphStartIndex(){return this._structArray.uint16[this._pos2+2]}get numGlyphs(){return this._structArray.uint16[this._pos2+3]}get vertexStartIndex(){return this._structArray.uint32[this._pos4+2]}get lineStartIndex(){return this._structArray.uint32[this._pos4+3]}get lineLength(){return this._structArray.uint32[this._pos4+4]}get segment(){return this._structArray.uint16[this._pos2+10]}get lowerSize(){return this._structArray.uint16[this._pos2+11]}get upperSize(){return this._structArray.uint16[this._pos2+12]}get lineOffsetX(){return this._structArray.float32[this._pos4+7]}get lineOffsetY(){return this._structArray.float32[this._pos4+8]}get writingMode(){return this._structArray.uint8[this._pos1+36]}get placedOrientation(){return this._structArray.uint8[this._pos1+37]}set placedOrientation(t){this._structArray.uint8[this._pos1+37]=t;}get hidden(){return this._structArray.uint8[this._pos1+38]}set hidden(t){this._structArray.uint8[this._pos1+38]=t;}get crossTileID(){return this._structArray.uint32[this._pos4+10]}set crossTileID(t){this._structArray.uint32[this._pos4+10]=t;}get associatedIconIndex(){return this._structArray.int16[this._pos2+22]}}Sa.prototype.size=48;class Aa extends fa{get(t){return new Sa(this,t)}}us(\"PlacedSymbolArray\",Aa);class ka extends Ys{get anchorX(){return this._structArray.int16[this._pos2+0]}get anchorY(){return this._structArray.int16[this._pos2+1]}get rightJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+2]}get centerJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+3]}get leftJustifiedTextSymbolIndex(){return this._structArray.int16[this._pos2+4]}get verticalPlacedTextSymbolIndex(){return this._structArray.int16[this._pos2+5]}get placedIconSymbolIndex(){return this._structArray.int16[this._pos2+6]}get verticalPlacedIconSymbolIndex(){return this._structArray.int16[this._pos2+7]}get key(){return this._structArray.uint16[this._pos2+8]}get textBoxStartIndex(){return this._structArray.uint16[this._pos2+9]}get textBoxEndIndex(){return this._structArray.uint16[this._pos2+10]}get verticalTextBoxStartIndex(){return this._structArray.uint16[this._pos2+11]}get verticalTextBoxEndIndex(){return this._structArray.uint16[this._pos2+12]}get iconBoxStartIndex(){return this._structArray.uint16[this._pos2+13]}get iconBoxEndIndex(){return this._structArray.uint16[this._pos2+14]}get verticalIconBoxStartIndex(){return this._structArray.uint16[this._pos2+15]}get verticalIconBoxEndIndex(){return this._structArray.uint16[this._pos2+16]}get featureIndex(){return this._structArray.uint16[this._pos2+17]}get numHorizontalGlyphVertices(){return this._structArray.uint16[this._pos2+18]}get numVerticalGlyphVertices(){return this._structArray.uint16[this._pos2+19]}get numIconVertices(){return this._structArray.uint16[this._pos2+20]}get numVerticalIconVertices(){return this._structArray.uint16[this._pos2+21]}get useRuntimeCollisionCircles(){return this._structArray.uint16[this._pos2+22]}get crossTileID(){return this._structArray.uint32[this._pos4+12]}set crossTileID(t){this._structArray.uint32[this._pos4+12]=t;}get textBoxScale(){return this._structArray.float32[this._pos4+13]}get collisionCircleDiameter(){return this._structArray.float32[this._pos4+14]}get textAnchorOffsetStartIndex(){return this._structArray.uint16[this._pos2+30]}get textAnchorOffsetEndIndex(){return this._structArray.uint16[this._pos2+31]}}ka.prototype.size=64;class Ma extends da{get(t){return new ka(this,t)}}us(\"SymbolInstanceArray\",Ma);class Ia extends ya{getoffsetX(t){return this.float32[1*t+0]}}us(\"GlyphOffsetArray\",Ia);class za extends Qs{getx(t){return this.int16[3*t+0]}gety(t){return this.int16[3*t+1]}gettileUnitDistanceFromAnchor(t){return this.int16[3*t+2]}}us(\"SymbolLineVertexArray\",za);class Pa extends Ys{get textAnchor(){return this._structArray.uint16[this._pos2+0]}get textOffset0(){return this._structArray.float32[this._pos4+1]}get textOffset1(){return this._structArray.float32[this._pos4+2]}}Pa.prototype.size=12;class Ca extends ma{get(t){return new Pa(this,t)}}us(\"TextAnchorOffsetArray\",Ca);class Ba extends Ys{get featureIndex(){return this._structArray.uint32[this._pos4+0]}get sourceLayerIndex(){return this._structArray.uint16[this._pos2+2]}get bucketIndex(){return this._structArray.uint16[this._pos2+3]}}Ba.prototype.size=8;class Ea extends ga{get(t){return new Ba(this,t)}}us(\"FeatureIndexArray\",Ea);class Ta extends Ws{}class Va extends Ws{}class Fa extends Ws{}class La extends ea{}class $a extends ra{}class Da extends na{}class Oa extends ia{}class Ra extends sa{}class ja extends aa{}class Na extends oa{}class Ua extends ua{}class qa extends ha{}class Ga extends pa{}class Xa extends xa{}const Za=Ks([{name:\"a_pos\",components:2,type:\"Int16\"}],4),{members:Ya}=Za;class Ha{constructor(t=[]){this._forceNewSegmentOnNextPrepare=!1,this.segments=t;}prepareSegment(t,e,r,n){const i=this.segments[this.segments.length-1];return t>Ha.MAX_VERTEX_ARRAY_LENGTH&&Z(`Max vertices per segment is ${Ha.MAX_VERTEX_ARRAY_LENGTH}: bucket requested ${t}. Consider using the \\`fillLargeMeshArrays\\` function if you require meshes with more than ${Ha.MAX_VERTEX_ARRAY_LENGTH} vertices.`),this._forceNewSegmentOnNextPrepare||!i||i.vertexLength+t>Ha.MAX_VERTEX_ARRAY_LENGTH||i.sortKey!==n?this.createNewSegment(e,r,n):i}createNewSegment(t,e,r){const n={vertexOffset:t.length,primitiveOffset:e.length,vertexLength:0,primitiveLength:0,vaos:{}};return void 0!==r&&(n.sortKey=r),this._forceNewSegmentOnNextPrepare=!1,this.segments.push(n),n}getOrCreateLatestSegment(t,e,r){return this.prepareSegment(0,t,e,r)}forceNewSegmentOnNextPrepare(){this._forceNewSegmentOnNextPrepare=!0;}get(){return this.segments}destroy(){for(const t of this.segments)for(const e in t.vaos)t.vaos[e].destroy();}static simpleSegment(t,e,r,n){return new Ha([{vertexOffset:t,primitiveOffset:e,vertexLength:r,primitiveLength:n,vaos:{},sortKey:0}])}}function Ka(t,e){return 256*(t=O(Math.floor(t),0,255))+O(Math.floor(e),0,255)}Ha.MAX_VERTEX_ARRAY_LENGTH=Math.pow(2,16)-1,us(\"SegmentVector\",Ha);const Ja=Ks([{name:\"a_pattern_from\",components:4,type:\"Uint16\"},{name:\"a_pattern_to\",components:4,type:\"Uint16\"},{name:\"a_pixel_ratio_from\",components:1,type:\"Uint16\"},{name:\"a_pixel_ratio_to\",components:1,type:\"Uint16\"}]);var Wa,Qa,to,eo={exports:{}},ro={exports:{}},no={exports:{}},io=function(){if(to)return eo.exports;to=1;var t=(Wa||(Wa=1,ro.exports=function(t,e){var r,n,i,s,a,o,l,u;for(n=t.length-(r=3&t.length),i=e,a=3432918353,o=461845907,u=0;u<n;)l=255&t.charCodeAt(u)|(255&t.charCodeAt(++u))<<8|(255&t.charCodeAt(++u))<<16|(255&t.charCodeAt(++u))<<24,++u,i=27492+(65535&(s=5*(65535&(i=(i^=l=(65535&(l=(l=(65535&l)*a+(((l>>>16)*a&65535)<<16)&4294967295)<<15|l>>>17))*o+(((l>>>16)*o&65535)<<16)&4294967295)<<13|i>>>19))+((5*(i>>>16)&65535)<<16)&4294967295))+((58964+(s>>>16)&65535)<<16);switch(l=0,r){case 3:l^=(255&t.charCodeAt(u+2))<<16;case 2:l^=(255&t.charCodeAt(u+1))<<8;case 1:i^=l=(65535&(l=(l=(65535&(l^=255&t.charCodeAt(u)))*a+(((l>>>16)*a&65535)<<16)&4294967295)<<15|l>>>17))*o+(((l>>>16)*o&65535)<<16)&4294967295;}return i^=t.length,i=2246822507*(65535&(i^=i>>>16))+((2246822507*(i>>>16)&65535)<<16)&4294967295,i=3266489909*(65535&(i^=i>>>13))+((3266489909*(i>>>16)&65535)<<16)&4294967295,(i^=i>>>16)>>>0}),ro.exports),e=(Qa||(Qa=1,no.exports=function(t,e){for(var r,n=t.length,i=e^n,s=0;n>=4;)r=1540483477*(65535&(r=255&t.charCodeAt(s)|(255&t.charCodeAt(++s))<<8|(255&t.charCodeAt(++s))<<16|(255&t.charCodeAt(++s))<<24))+((1540483477*(r>>>16)&65535)<<16),i=1540483477*(65535&i)+((1540483477*(i>>>16)&65535)<<16)^(r=1540483477*(65535&(r^=r>>>24))+((1540483477*(r>>>16)&65535)<<16)),n-=4,++s;switch(n){case 3:i^=(255&t.charCodeAt(s+2))<<16;case 2:i^=(255&t.charCodeAt(s+1))<<8;case 1:i=1540483477*(65535&(i^=255&t.charCodeAt(s)))+((1540483477*(i>>>16)&65535)<<16);}return i=1540483477*(65535&(i^=i>>>13))+((1540483477*(i>>>16)&65535)<<16),(i^=i>>>15)>>>0}),no.exports);return eo.exports=t,eo.exports.murmur3=t,eo.exports.murmur2=e,eo.exports}(),so=r(io);class ao{constructor(){this.ids=[],this.positions=[],this.indexed=!1;}add(t,e,r,n){this.ids.push(oo(t)),this.positions.push(e,r,n);}getPositions(t){if(!this.indexed)throw new Error(\"Trying to get index, but feature positions are not indexed\");const e=oo(t);let r=0,n=this.ids.length-1;for(;r<n;){const t=r+n>>1;this.ids[t]>=e?n=t:r=t+1;}const i=[];for(;this.ids[r]===e;)i.push({index:this.positions[3*r],start:this.positions[3*r+1],end:this.positions[3*r+2]}),r++;return i}static serialize(t,e){const r=new Float64Array(t.ids),n=new Uint32Array(t.positions);return lo(r,n,0,r.length-1),e&&e.push(r.buffer,n.buffer),{ids:r,positions:n}}static deserialize(t){const e=new ao;return e.ids=t.ids,e.positions=t.positions,e.indexed=!0,e}}function oo(t){const e=+t;return !isNaN(e)&&e<=Number.MAX_SAFE_INTEGER?e:so(String(t))}function lo(t,e,r,n){for(;r<n;){const i=t[r+n>>1];let s=r-1,a=n+1;for(;;){do{s++;}while(t[s]<i);do{a--;}while(t[a]>i);if(s>=a)break;uo(t,s,a),uo(e,3*s,3*a),uo(e,3*s+1,3*a+1),uo(e,3*s+2,3*a+2);}a-r<n-a?(lo(t,e,r,a),r=a+1):(lo(t,e,a+1,n),n=a);}}function uo(t,e,r){const n=t[e];t[e]=t[r],t[r]=n;}us(\"FeaturePositionMap\",ao);class co{constructor(t,e){this.gl=t.gl,this.location=e;}}class ho extends co{constructor(t,e){super(t,e),this.current=0;}set(t){this.current!==t&&(this.current=t,this.gl.uniform1f(this.location,t));}}class po extends co{constructor(t,e){super(t,e),this.current=[0,0,0,0];}set(t){t[0]===this.current[0]&&t[1]===this.current[1]&&t[2]===this.current[2]&&t[3]===this.current[3]||(this.current=t,this.gl.uniform4f(this.location,t[0],t[1],t[2],t[3]));}}class fo extends co{constructor(t,e){super(t,e),this.current=Pe.transparent;}set(t){t.r===this.current.r&&t.g===this.current.g&&t.b===this.current.b&&t.a===this.current.a||(this.current=t,this.gl.uniform4f(this.location,t.r,t.g,t.b,t.a));}}const yo=new Float32Array(16);function mo(t){return [Ka(255*t.r,255*t.g),Ka(255*t.b,255*t.a)]}class go{constructor(t,e,r){this.value=t,this.uniformNames=e.map((t=>`u_${t}`)),this.type=r;}setUniform(t,e,r){t.set(r.constantOr(this.value));}getBinding(t,e,r){return \"color\"===this.type?new fo(t,e):new ho(t,e)}}class xo{constructor(t,e){this.uniformNames=e.map((t=>`u_${t}`)),this.patternFrom=null,this.patternTo=null,this.pixelRatioFrom=1,this.pixelRatioTo=1;}setConstantPatternPositions(t,e){this.pixelRatioFrom=e.pixelRatio,this.pixelRatioTo=t.pixelRatio,this.patternFrom=e.tlbr,this.patternTo=t.tlbr;}setUniform(t,e,r,n){const i=\"u_pattern_to\"===n?this.patternTo:\"u_pattern_from\"===n?this.patternFrom:\"u_pixel_ratio_to\"===n?this.pixelRatioTo:\"u_pixel_ratio_from\"===n?this.pixelRatioFrom:null;i&&t.set(i);}getBinding(t,e,r){return \"u_pattern\"===r.substr(0,9)?new po(t,e):new ho(t,e)}}class vo{constructor(t,e,r,n){this.expression=t,this.type=r,this.maxValue=0,this.paintVertexAttributes=e.map((t=>({name:`a_${t}`,type:\"Float32\",components:\"color\"===r?2:1,offset:0}))),this.paintVertexArray=new n;}populatePaintArray(t,e,r,n,i){const s=this.paintVertexArray.length,a=this.expression.evaluate(new Cs(0),e,{},n,[],i);this.paintVertexArray.resize(t),this._setPaintValue(s,t,a);}updatePaintArray(t,e,r,n){const i=this.expression.evaluate({zoom:0},r,n);this._setPaintValue(t,e,i);}_setPaintValue(t,e,r){if(\"color\"===this.type){const n=mo(r);for(let r=t;r<e;r++)this.paintVertexArray.emplace(r,n[0],n[1]);}else {for(let n=t;n<e;n++)this.paintVertexArray.emplace(n,r);this.maxValue=Math.max(this.maxValue,Math.abs(r));}}upload(t){this.paintVertexArray&&this.paintVertexArray.arrayBuffer&&(this.paintVertexBuffer&&this.paintVertexBuffer.buffer?this.paintVertexBuffer.updateData(this.paintVertexArray):this.paintVertexBuffer=t.createVertexBuffer(this.paintVertexArray,this.paintVertexAttributes,this.expression.isStateDependent));}destroy(){this.paintVertexBuffer&&this.paintVertexBuffer.destroy();}}class bo{constructor(t,e,r,n,i,s){this.expression=t,this.uniformNames=e.map((t=>`u_${t}_t`)),this.type=r,this.useIntegerZoom=n,this.zoom=i,this.maxValue=0,this.paintVertexAttributes=e.map((t=>({name:`a_${t}`,type:\"Float32\",components:\"color\"===r?4:2,offset:0}))),this.paintVertexArray=new s;}populatePaintArray(t,e,r,n,i){const s=this.expression.evaluate(new Cs(this.zoom),e,{},n,[],i),a=this.expression.evaluate(new Cs(this.zoom+1),e,{},n,[],i),o=this.paintVertexArray.length;this.paintVertexArray.resize(t),this._setPaintValue(o,t,s,a);}updatePaintArray(t,e,r,n){const i=this.expression.evaluate({zoom:this.zoom},r,n),s=this.expression.evaluate({zoom:this.zoom+1},r,n);this._setPaintValue(t,e,i,s);}_setPaintValue(t,e,r,n){if(\"color\"===this.type){const i=mo(r),s=mo(n);for(let r=t;r<e;r++)this.paintVertexArray.emplace(r,i[0],i[1],s[0],s[1]);}else {for(let i=t;i<e;i++)this.paintVertexArray.emplace(i,r,n);this.maxValue=Math.max(this.maxValue,Math.abs(r),Math.abs(n));}}upload(t){this.paintVertexArray&&this.paintVertexArray.arrayBuffer&&(this.paintVertexBuffer&&this.paintVertexBuffer.buffer?this.paintVertexBuffer.updateData(this.paintVertexArray):this.paintVertexBuffer=t.createVertexBuffer(this.paintVertexArray,this.paintVertexAttributes,this.expression.isStateDependent));}destroy(){this.paintVertexBuffer&&this.paintVertexBuffer.destroy();}setUniform(t,e){const r=this.useIntegerZoom?Math.floor(e.zoom):e.zoom,n=O(this.expression.interpolationFactor(r,this.zoom,this.zoom+1),0,1);t.set(n);}getBinding(t,e,r){return new ho(t,e)}}class wo{constructor(t,e,r,n,i,s){this.expression=t,this.type=e,this.useIntegerZoom=r,this.zoom=n,this.layerId=s,this.zoomInPaintVertexArray=new i,this.zoomOutPaintVertexArray=new i;}populatePaintArray(t,e,r){const n=this.zoomInPaintVertexArray.length;this.zoomInPaintVertexArray.resize(t),this.zoomOutPaintVertexArray.resize(t),this._setPaintValues(n,t,e.patterns&&e.patterns[this.layerId],r);}updatePaintArray(t,e,r,n,i){this._setPaintValues(t,e,r.patterns&&r.patterns[this.layerId],i);}_setPaintValues(t,e,r,n){if(!n||!r)return;const{min:i,mid:s,max:a}=r,o=n[i],l=n[s],u=n[a];if(o&&l&&u)for(let r=t;r<e;r++)this.zoomInPaintVertexArray.emplace(r,l.tl[0],l.tl[1],l.br[0],l.br[1],o.tl[0],o.tl[1],o.br[0],o.br[1],l.pixelRatio,o.pixelRatio),this.zoomOutPaintVertexArray.emplace(r,l.tl[0],l.tl[1],l.br[0],l.br[1],u.tl[0],u.tl[1],u.br[0],u.br[1],l.pixelRatio,u.pixelRatio);}upload(t){this.zoomInPaintVertexArray&&this.zoomInPaintVertexArray.arrayBuffer&&this.zoomOutPaintVertexArray&&this.zoomOutPaintVertexArray.arrayBuffer&&(this.zoomInPaintVertexBuffer=t.createVertexBuffer(this.zoomInPaintVertexArray,Ja.members,this.expression.isStateDependent),this.zoomOutPaintVertexBuffer=t.createVertexBuffer(this.zoomOutPaintVertexArray,Ja.members,this.expression.isStateDependent));}destroy(){this.zoomOutPaintVertexBuffer&&this.zoomOutPaintVertexBuffer.destroy(),this.zoomInPaintVertexBuffer&&this.zoomInPaintVertexBuffer.destroy();}}class _o{constructor(t,e,r){this.binders={},this._buffers=[];const n=[];for(const i in t.paint._values){if(!r(i))continue;const s=t.paint.get(i);if(!(s instanceof $s&&Gn(s.property.specification)))continue;const a=Ao(i,t.type),o=s.value,l=s.property.specification.type,u=s.property.useIntegerZoom,c=s.property.specification[\"property-type\"],h=\"cross-faded\"===c||\"cross-faded-data-driven\"===c;if(\"constant\"===o.kind)this.binders[i]=h?new xo(o.value,a):new go(o.value,a,l),n.push(`/u_${i}`);else if(\"source\"===o.kind||h){const r=ko(i,l,\"source\");this.binders[i]=h?new wo(o,l,u,e,r,t.id):new vo(o,a,l,r),n.push(`/a_${i}`);}else {const t=ko(i,l,\"composite\");this.binders[i]=new bo(o,a,l,u,e,t),n.push(`/z_${i}`);}}this.cacheKey=n.sort().join(\"\");}getMaxValue(t){const e=this.binders[t];return e instanceof vo||e instanceof bo?e.maxValue:0}populatePaintArrays(t,e,r,n,i){for(const s in this.binders){const a=this.binders[s];(a instanceof vo||a instanceof bo||a instanceof wo)&&a.populatePaintArray(t,e,r,n,i);}}setConstantPatternPositions(t,e){for(const r in this.binders){const n=this.binders[r];n instanceof xo&&n.setConstantPatternPositions(t,e);}}updatePaintArrays(t,e,r,n,i){let s=!1;for(const a in t){const o=e.getPositions(a);for(const e of o){const o=r.feature(e.index);for(const r in this.binders){const l=this.binders[r];if((l instanceof vo||l instanceof bo||l instanceof wo)&&!0===l.expression.isStateDependent){const u=n.paint.get(r);l.expression=u.value,l.updatePaintArray(e.start,e.end,o,t[a],i),s=!0;}}}}return s}defines(){const t=[];for(const e in this.binders){const r=this.binders[e];(r instanceof go||r instanceof xo)&&t.push(...r.uniformNames.map((t=>`#define HAS_UNIFORM_${t}`)));}return t}getBinderAttributes(){const t=[];for(const e in this.binders){const r=this.binders[e];if(r instanceof vo||r instanceof bo)for(let e=0;e<r.paintVertexAttributes.length;e++)t.push(r.paintVertexAttributes[e].name);else if(r instanceof wo)for(let e=0;e<Ja.members.length;e++)t.push(Ja.members[e].name);}return t}getBinderUniforms(){const t=[];for(const e in this.binders){const r=this.binders[e];if(r instanceof go||r instanceof xo||r instanceof bo)for(const e of r.uniformNames)t.push(e);}return t}getPaintVertexBuffers(){return this._buffers}getUniforms(t,e){const r=[];for(const n in this.binders){const i=this.binders[n];if(i instanceof go||i instanceof xo||i instanceof bo)for(const s of i.uniformNames)if(e[s]){const a=i.getBinding(t,e[s],s);r.push({name:s,property:n,binding:a});}}return r}setUniforms(t,e,r,n){for(const{name:t,property:i,binding:s}of e)this.binders[i].setUniform(s,n,r.get(i),t);}updatePaintBuffers(t){this._buffers=[];for(const e in this.binders){const r=this.binders[e];if(t&&r instanceof wo){const e=2===t.fromScale?r.zoomInPaintVertexBuffer:r.zoomOutPaintVertexBuffer;e&&this._buffers.push(e);}else (r instanceof vo||r instanceof bo)&&r.paintVertexBuffer&&this._buffers.push(r.paintVertexBuffer);}}upload(t){for(const e in this.binders){const r=this.binders[e];(r instanceof vo||r instanceof bo||r instanceof wo)&&r.upload(t);}this.updatePaintBuffers();}destroy(){for(const t in this.binders){const e=this.binders[t];(e instanceof vo||e instanceof bo||e instanceof wo)&&e.destroy();}}}class So{constructor(t,e,r=()=>!0){this.programConfigurations={};for(const n of t)this.programConfigurations[n.id]=new _o(n,e,r);this.needsUpload=!1,this._featureMap=new ao,this._bufferOffset=0;}populatePaintArrays(t,e,r,n,i,s){for(const r in this.programConfigurations)this.programConfigurations[r].populatePaintArrays(t,e,n,i,s);void 0!==e.id&&this._featureMap.add(e.id,r,this._bufferOffset,t),this._bufferOffset=t,this.needsUpload=!0;}updatePaintArrays(t,e,r,n){for(const i of r)this.needsUpload=this.programConfigurations[i.id].updatePaintArrays(t,this._featureMap,e,i,n)||this.needsUpload;}get(t){return this.programConfigurations[t]}upload(t){if(this.needsUpload){for(const e in this.programConfigurations)this.programConfigurations[e].upload(t);this.needsUpload=!1;}}destroy(){for(const t in this.programConfigurations)this.programConfigurations[t].destroy();}}function Ao(t,e){return {\"text-opacity\":[\"opacity\"],\"icon-opacity\":[\"opacity\"],\"text-color\":[\"fill_color\"],\"icon-color\":[\"fill_color\"],\"text-halo-color\":[\"halo_color\"],\"icon-halo-color\":[\"halo_color\"],\"text-halo-blur\":[\"halo_blur\"],\"icon-halo-blur\":[\"halo_blur\"],\"text-halo-width\":[\"halo_width\"],\"icon-halo-width\":[\"halo_width\"],\"line-gap-width\":[\"gapwidth\"],\"line-pattern\":[\"pattern_to\",\"pattern_from\",\"pixel_ratio_to\",\"pixel_ratio_from\"],\"fill-pattern\":[\"pattern_to\",\"pattern_from\",\"pixel_ratio_to\",\"pixel_ratio_from\"],\"fill-extrusion-pattern\":[\"pattern_to\",\"pattern_from\",\"pixel_ratio_to\",\"pixel_ratio_from\"]}[t]||[t.replace(`${e}-`,\"\").replace(/-/g,\"_\")]}function ko(t,e,r){const n={color:{source:na,composite:ba},number:{source:ya,composite:na}},i=function(t){return {\"line-pattern\":{source:Oa,composite:Oa},\"fill-pattern\":{source:Oa,composite:Oa},\"fill-extrusion-pattern\":{source:Oa,composite:Oa}}[t]}(t);return i&&i[r]||n[e][r]}us(\"ConstantBinder\",go),us(\"CrossFadedConstantBinder\",xo),us(\"SourceExpressionBinder\",vo),us(\"CrossFadedCompositeBinder\",wo),us(\"CompositeExpressionBinder\",bo),us(\"ProgramConfiguration\",_o,{omit:[\"_buffers\"]}),us(\"ProgramConfigurationSet\",So);const Mo=Math.pow(2,14)-1,Io=-Mo-1;function zo(t){const e=E/t.extent,r=t.loadGeometry();for(let t=0;t<r.length;t++){const n=r[t];for(let t=0;t<n.length;t++){const r=n[t],i=Math.round(r.x*e),s=Math.round(r.y*e);r.x=O(i,Io,Mo),r.y=O(s,Io,Mo),(i<r.x||i>r.x+1||s<r.y||s>r.y+1)&&Z(\"Geometry exceeds allowed extent, reduce your vector tile buffer size\");}}return r}function Po(t,e){return {type:t.type,id:t.id,properties:t.properties,geometry:e?zo(t):[]}}const Co=-32768;function Bo(t,e,r,n,i){t.emplaceBack(Co+8*e+n,Co+8*r+i);}class Eo{constructor(t){this.zoom=t.zoom,this.globalState=t.globalState,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map((t=>t.id)),this.index=t.index,this.hasPattern=!1,this.layoutVertexArray=new Va,this.indexArray=new Ga,this.segments=new Ha,this.programConfigurations=new So(t.layers,t.zoom),this.stateDependentLayerIds=this.layers.filter((t=>t.isStateDependent())).map((t=>t.id));}populate(t,e,r){const n=this.layers[0],i=[];let s=null,a=!1,o=\"heatmap\"===n.type;if(\"circle\"===n.type){const t=n;s=t.layout.get(\"circle-sort-key\"),a=!s.isConstant(),o=o||\"map\"===t.paint.get(\"circle-pitch-alignment\");}const l=o?e.subdivisionGranularity.circle:1;for(const{feature:e,id:n,index:o,sourceLayerIndex:l}of t){const t=this.layers[0]._featureFilter.needGeometry,u=Po(e,t);if(!this.layers[0]._featureFilter.filter(new Cs(this.zoom,{globalState:this.globalState}),u,r))continue;const c=a?s.evaluate(u,{},r):void 0,h={id:n,properties:e.properties,type:e.type,sourceLayerIndex:l,index:o,geometry:t?u.geometry:zo(e),patterns:{},sortKey:c};i.push(h);}a&&i.sort(((t,e)=>t.sortKey-e.sortKey));for(const n of i){const{geometry:i,index:s,sourceLayerIndex:a}=n,o=t[s].feature;this.addFeature(n,i,s,r,l),e.featureIndex.insert(o,i,s,a,this.index);}}update(t,e,r){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(t,e,this.stateDependentLayers,r);}isEmpty(){return 0===this.layoutVertexArray.length}uploadPending(){return !this.uploaded||this.programConfigurations.needsUpload}upload(t){this.uploaded||(this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,Ya),this.indexBuffer=t.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(t),this.uploaded=!0;}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy());}addFeature(t,e,r,n,i=1){let s;switch(i){case 1:s=[0,7];break;case 3:s=[0,2,5,7];break;case 5:s=[0,1,3,4,6,7];break;case 7:s=[0,1,2,3,4,5,6,7];break;default:throw new Error(`Invalid circle bucket granularity: ${i}; valid values are 1, 3, 5, 7.`)}const a=s.length;for(const r of e)for(const e of r){const r=e.x,n=e.y;if(r<0||r>=E||n<0||n>=E)continue;const i=this.segments.prepareSegment(a*a,this.layoutVertexArray,this.indexArray,t.sortKey),o=i.vertexLength;for(let t=0;t<a;t++)for(let e=0;e<a;e++)Bo(this.layoutVertexArray,r,n,s[e],s[t]);for(let t=0;t<a-1;t++)for(let e=0;e<a-1;e++){const r=o+t*a+e,n=o+(t+1)*a+e;this.indexArray.emplaceBack(r,n+1,r+1),this.indexArray.emplaceBack(r,n,n+1);}i.vertexLength+=a*a,i.primitiveLength+=(a-1)*(a-1)*2;}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,t,r,{},n);}}function To(t,e){for(let r=0;r<t.length;r++)if(No(e,t[r]))return !0;for(let r=0;r<e.length;r++)if(No(t,e[r]))return !0;return !!$o(t,e)}function Vo(t,e,r){return !!No(t,e)||!!Oo(e,t,r)}function Fo(t,e){if(1===t.length)return jo(e,t[0]);for(let r=0;r<e.length;r++){const n=e[r];for(let e=0;e<n.length;e++)if(No(t,n[e]))return !0}for(let r=0;r<t.length;r++)if(jo(e,t[r]))return !0;for(let r=0;r<e.length;r++)if($o(t,e[r]))return !0;return !1}function Lo(t,e,r){if(t.length>1){if($o(t,e))return !0;for(let n=0;n<e.length;n++)if(Oo(e[n],t,r))return !0}for(let n=0;n<t.length;n++)if(Oo(t[n],e,r))return !0;return !1}function $o(t,e){if(0===t.length||0===e.length)return !1;for(let r=0;r<t.length-1;r++){const n=t[r],i=t[r+1];for(let t=0;t<e.length-1;t++)if(Do(n,i,e[t],e[t+1]))return !0}return !1}function Do(t,e,r,n){return Y(t,r,n)!==Y(e,r,n)&&Y(t,e,r)!==Y(t,e,n)}function Oo(t,e,r){const n=r*r;if(1===e.length)return t.distSqr(e[0])<n;for(let r=1;r<e.length;r++)if(Ro(t,e[r-1],e[r])<n)return !0;return !1}function Ro(t,e,r){const n=e.distSqr(r);if(0===n)return t.distSqr(e);const i=((t.x-e.x)*(r.x-e.x)+(t.y-e.y)*(r.y-e.y))/n;return t.distSqr(i<0?e:i>1?r:r.sub(e)._mult(i)._add(e))}function jo(t,e){let r,n,i,s=!1;for(let a=0;a<t.length;a++){r=t[a];for(let t=0,a=r.length-1;t<r.length;a=t++)n=r[t],i=r[a],n.y>e.y!=i.y>e.y&&e.x<(i.x-n.x)*(e.y-n.y)/(i.y-n.y)+n.x&&(s=!s);}return s}function No(t,e){let r=!1;for(let n=0,i=t.length-1;n<t.length;i=n++){const s=t[n],a=t[i];s.y>e.y!=a.y>e.y&&e.x<(a.x-s.x)*(e.y-s.y)/(a.y-s.y)+s.x&&(r=!r);}return r}function Uo(t,e,r){const n=r[0],i=r[2];if(t.x<n.x&&e.x<n.x||t.x>i.x&&e.x>i.x||t.y<n.y&&e.y<n.y||t.y>i.y&&e.y>i.y)return !1;const s=Y(t,e,r[0]);return s!==Y(t,e,r[1])||s!==Y(t,e,r[2])||s!==Y(t,e,r[3])}function qo(t,e,r){const n=e.paint.get(t).value;return \"constant\"===n.kind?n.value:r.programConfigurations.get(e.id).getMaxValue(t)}function Go(t){return Math.sqrt(t[0]*t[0]+t[1]*t[1])}function Xo(t,e,r,n,i){if(!e[0]&&!e[1])return t;const s=l.convert(e)._mult(i);\"viewport\"===r&&s._rotate(-n);const a=[];for(let e=0;e<t.length;e++)a.push(t[e].sub(s));return a}let Zo,Yo;us(\"CircleBucket\",Eo,{omit:[\"layers\"]});var Ho={get paint(){return Yo=Yo||new qs({\"circle-radius\":new Rs(wt.paint_circle[\"circle-radius\"]),\"circle-color\":new Rs(wt.paint_circle[\"circle-color\"]),\"circle-blur\":new Rs(wt.paint_circle[\"circle-blur\"]),\"circle-opacity\":new Rs(wt.paint_circle[\"circle-opacity\"]),\"circle-translate\":new Os(wt.paint_circle[\"circle-translate\"]),\"circle-translate-anchor\":new Os(wt.paint_circle[\"circle-translate-anchor\"]),\"circle-pitch-scale\":new Os(wt.paint_circle[\"circle-pitch-scale\"]),\"circle-pitch-alignment\":new Os(wt.paint_circle[\"circle-pitch-alignment\"]),\"circle-stroke-width\":new Rs(wt.paint_circle[\"circle-stroke-width\"]),\"circle-stroke-color\":new Rs(wt.paint_circle[\"circle-stroke-color\"]),\"circle-stroke-opacity\":new Rs(wt.paint_circle[\"circle-stroke-opacity\"])})},get layout(){return Zo=Zo||new qs({\"circle-sort-key\":new Rs(wt.layout_circle[\"circle-sort-key\"])})}};class Ko extends Xs{constructor(t){super(t,Ho);}createBucket(t){return new Eo(t)}queryRadius(t){const e=t;return qo(\"circle-radius\",this,e)+qo(\"circle-stroke-width\",this,e)+Go(this.paint.get(\"circle-translate\"))}queryIntersectsFeature({queryGeometry:t,feature:e,featureState:r,geometry:n,transform:i,pixelsToTileUnits:s,unwrappedTileID:a,getElevation:o}){const l=Xo(t,this.paint.get(\"circle-translate\"),this.paint.get(\"circle-translate-anchor\"),-i.bearingInRadians,s),u=this.paint.get(\"circle-radius\").evaluate(e,r)+this.paint.get(\"circle-stroke-width\").evaluate(e,r),c=\"map\"===this.paint.get(\"circle-pitch-alignment\"),h=c?l:function(t,e,r,n){return t.map((t=>Jo(t,e,r,n)))}(l,i,a,o),p=c?u*s:u;for(const t of n)for(const e of t){const t=c?e:Jo(e,i,a,o);let r=p;const n=i.projectTileCoordinates(e.x,e.y,a,o).signedDistanceFromCamera;if(\"viewport\"===this.paint.get(\"circle-pitch-scale\")&&\"map\"===this.paint.get(\"circle-pitch-alignment\")?r*=n/i.cameraToCenterDistance:\"map\"===this.paint.get(\"circle-pitch-scale\")&&\"viewport\"===this.paint.get(\"circle-pitch-alignment\")&&(r*=i.cameraToCenterDistance/n),Vo(h,t,r))return !0}return !1}}function Jo(t,e,r,n){const i=e.projectTileCoordinates(t.x,t.y,r,n).point;return new l((.5*i.x+.5)*e.width,(.5*-i.y+.5)*e.height)}class Wo extends Eo{}let Qo;us(\"HeatmapBucket\",Wo,{omit:[\"layers\"]});var tl={get paint(){return Qo=Qo||new qs({\"heatmap-radius\":new Rs(wt.paint_heatmap[\"heatmap-radius\"]),\"heatmap-weight\":new Rs(wt.paint_heatmap[\"heatmap-weight\"]),\"heatmap-intensity\":new Os(wt.paint_heatmap[\"heatmap-intensity\"]),\"heatmap-color\":new Us(wt.paint_heatmap[\"heatmap-color\"]),\"heatmap-opacity\":new Os(wt.paint_heatmap[\"heatmap-opacity\"])})}};function el(t,{width:e,height:r},n,i){if(i){if(i instanceof Uint8ClampedArray)i=new Uint8Array(i.buffer);else if(i.length!==e*r*n)throw new RangeError(`mismatched image size. expected: ${i.length} but got: ${e*r*n}`)}else i=new Uint8Array(e*r*n);return t.width=e,t.height=r,t.data=i,t}function rl(t,{width:e,height:r},n){if(e===t.width&&r===t.height)return;const i=el({},{width:e,height:r},n);nl(t,i,{x:0,y:0},{x:0,y:0},{width:Math.min(t.width,e),height:Math.min(t.height,r)},n),t.width=e,t.height=r,t.data=i.data;}function nl(t,e,r,n,i,s){if(0===i.width||0===i.height)return e;if(i.width>t.width||i.height>t.height||r.x>t.width-i.width||r.y>t.height-i.height)throw new RangeError(\"out of range source coordinates for image copy\");if(i.width>e.width||i.height>e.height||n.x>e.width-i.width||n.y>e.height-i.height)throw new RangeError(\"out of range destination coordinates for image copy\");const a=t.data,o=e.data;if(a===o)throw new Error(\"srcData equals dstData, so image is already copied\");for(let l=0;l<i.height;l++){const u=((r.y+l)*t.width+r.x)*s,c=((n.y+l)*e.width+n.x)*s;for(let t=0;t<i.width*s;t++)o[c+t]=a[u+t];}return e}class il{constructor(t,e){el(this,t,1,e);}resize(t){rl(this,t,1);}clone(){return new il({width:this.width,height:this.height},new Uint8Array(this.data))}static copy(t,e,r,n,i){nl(t,e,r,n,i,1);}}class sl{constructor(t,e){el(this,t,4,e);}resize(t){rl(this,t,4);}replace(t,e){e?this.data.set(t):this.data=t instanceof Uint8ClampedArray?new Uint8Array(t.buffer):t;}clone(){return new sl({width:this.width,height:this.height},new Uint8Array(this.data))}static copy(t,e,r,n,i){nl(t,e,r,n,i,4);}setPixel(t,e,r){const n=4*(t*this.width+e);this.data[n+0]=Math.round(255*r.r/r.a),this.data[n+1]=Math.round(255*r.g/r.a),this.data[n+2]=Math.round(255*r.b/r.a),this.data[n+3]=Math.round(255*r.a);}}function al(t){const e={},r=t.resolution||256,n=t.clips?t.clips.length:1,i=t.image||new sl({width:r,height:n});if(Math.log(r)/Math.LN2%1!=0)throw new Error(`width is not a power of 2 - ${r}`);const s=(n,s,a)=>{e[t.evaluationKey]=a;const o=t.expression.evaluate(e);i.setPixel(n/4/r,s/4,o);};if(t.clips)for(let e=0,i=0;e<n;++e,i+=4*r)for(let n=0,a=0;n<r;n++,a+=4){const o=n/(r-1),{start:l,end:u}=t.clips[e];s(i,a,l*(1-o)+u*o);}else for(let t=0,e=0;t<r;t++,e+=4)s(0,e,t/(r-1));return i}us(\"AlphaImage\",il),us(\"RGBAImage\",sl);const ol=\"big-fb\";class ll extends Xs{createBucket(t){return new Wo(t)}constructor(t){super(t,tl),this.heatmapFbos=new Map,this._updateColorRamp();}_handleSpecialPaintPropertyUpdate(t){\"heatmap-color\"===t&&this._updateColorRamp();}_updateColorRamp(){this.colorRamp=al({expression:this._transitionablePaint._values[\"heatmap-color\"].value.expression,evaluationKey:\"heatmapDensity\",image:this.colorRamp}),this.colorRampTexture=null;}resize(){this.heatmapFbos.has(ol)&&this.heatmapFbos.delete(ol);}queryRadius(){return 0}queryIntersectsFeature(){return !1}hasOffscreenPass(){return 0!==this.paint.get(\"heatmap-opacity\")&&\"none\"!==this.visibility}}let ul;var cl={get paint(){return ul=ul||new qs({\"hillshade-illumination-direction\":new Os(wt.paint_hillshade[\"hillshade-illumination-direction\"]),\"hillshade-illumination-altitude\":new Os(wt.paint_hillshade[\"hillshade-illumination-altitude\"]),\"hillshade-illumination-anchor\":new Os(wt.paint_hillshade[\"hillshade-illumination-anchor\"]),\"hillshade-exaggeration\":new Os(wt.paint_hillshade[\"hillshade-exaggeration\"]),\"hillshade-shadow-color\":new Os(wt.paint_hillshade[\"hillshade-shadow-color\"]),\"hillshade-highlight-color\":new Os(wt.paint_hillshade[\"hillshade-highlight-color\"]),\"hillshade-accent-color\":new Os(wt.paint_hillshade[\"hillshade-accent-color\"]),\"hillshade-method\":new Os(wt.paint_hillshade[\"hillshade-method\"])})}};class hl extends Xs{constructor(t){super(t,cl),this.recalculate({zoom:0,zoomHistory:{}},void 0);}getIlluminationProperties(){let t=this.paint.get(\"hillshade-illumination-direction\").values,e=this.paint.get(\"hillshade-illumination-altitude\").values,r=this.paint.get(\"hillshade-highlight-color\").values,n=this.paint.get(\"hillshade-shadow-color\").values;const i=Math.max(t.length,e.length,r.length,n.length);t=t.concat(Array(i-t.length).fill(t.at(-1))),e=e.concat(Array(i-e.length).fill(e.at(-1))),r=r.concat(Array(i-r.length).fill(r.at(-1))),n=n.concat(Array(i-n.length).fill(n.at(-1)));const s=e.map(nt);return {directionRadians:t.map(nt),altitudeRadians:s,shadowColor:n,highlightColor:r}}hasOffscreenPass(){return 0!==this.paint.get(\"hillshade-exaggeration\")&&\"none\"!==this.visibility}}let pl;var fl={get paint(){return pl=pl||new qs({\"color-relief-opacity\":new Os(wt[\"paint_color-relief\"][\"color-relief-opacity\"]),\"color-relief-color\":new Us(wt[\"paint_color-relief\"][\"color-relief-color\"])})}};class dl{constructor(t,e,r,n){this.context=t,this.format=r,this.texture=t.gl.createTexture(),this.update(e,n);}update(t,e,r){const{width:n,height:i}=t,s=!(this.size&&this.size[0]===n&&this.size[1]===i||r),{context:a}=this,{gl:o}=a;if(this.useMipmap=Boolean(e&&e.useMipmap),o.bindTexture(o.TEXTURE_2D,this.texture),a.pixelStoreUnpackFlipY.set(!1),a.pixelStoreUnpack.set(1),a.pixelStoreUnpackPremultiplyAlpha.set(this.format===o.RGBA&&(!e||!1!==e.premultiply)),s)this.size=[n,i],t instanceof HTMLImageElement||t instanceof HTMLCanvasElement||t instanceof HTMLVideoElement||t instanceof ImageData||J(t)?o.texImage2D(o.TEXTURE_2D,0,this.format,this.format,o.UNSIGNED_BYTE,t):o.texImage2D(o.TEXTURE_2D,0,this.format,n,i,0,this.format,o.UNSIGNED_BYTE,t.data);else {const{x:e,y:s}=r||{x:0,y:0};t instanceof HTMLImageElement||t instanceof HTMLCanvasElement||t instanceof HTMLVideoElement||t instanceof ImageData||J(t)?o.texSubImage2D(o.TEXTURE_2D,0,e,s,o.RGBA,o.UNSIGNED_BYTE,t):o.texSubImage2D(o.TEXTURE_2D,0,e,s,n,i,o.RGBA,o.UNSIGNED_BYTE,t.data);}this.useMipmap&&this.isSizePowerOfTwo()&&o.generateMipmap(o.TEXTURE_2D),a.pixelStoreUnpackFlipY.setDefault(),a.pixelStoreUnpack.setDefault(),a.pixelStoreUnpackPremultiplyAlpha.setDefault();}bind(t,e,r){const{context:n}=this,{gl:i}=n;i.bindTexture(i.TEXTURE_2D,this.texture),r!==i.LINEAR_MIPMAP_NEAREST||this.isSizePowerOfTwo()||(r=i.LINEAR),t!==this.filter&&(i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MAG_FILTER,t),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_MIN_FILTER,r||t),this.filter=t),e!==this.wrap&&(i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_S,e),i.texParameteri(i.TEXTURE_2D,i.TEXTURE_WRAP_T,e),this.wrap=e);}isSizePowerOfTwo(){return this.size[0]===this.size[1]&&Math.log(this.size[0])/Math.LN2%1==0}destroy(){const{gl:t}=this.context;t.deleteTexture(this.texture),this.texture=null;}}class yl{constructor(t,e,r,n=1,i=1,s=1,a=0){if(this.uid=t,e.height!==e.width)throw new RangeError(\"DEM tiles must be square\");if(r&&![\"mapbox\",\"terrarium\",\"custom\"].includes(r))return void Z(`\"${r}\" is not a valid encoding type. Valid types include \"mapbox\", \"terrarium\" and \"custom\".`);this.stride=e.height;const o=this.dim=e.height-2;switch(this.data=new Uint32Array(e.data.buffer),r){case \"terrarium\":this.redFactor=256,this.greenFactor=1,this.blueFactor=1/256,this.baseShift=32768;break;case \"custom\":this.redFactor=n,this.greenFactor=i,this.blueFactor=s,this.baseShift=a;break;default:this.redFactor=6553.6,this.greenFactor=25.6,this.blueFactor=.1,this.baseShift=1e4;}for(let t=0;t<o;t++)this.data[this._idx(-1,t)]=this.data[this._idx(0,t)],this.data[this._idx(o,t)]=this.data[this._idx(o-1,t)],this.data[this._idx(t,-1)]=this.data[this._idx(t,0)],this.data[this._idx(t,o)]=this.data[this._idx(t,o-1)];this.data[this._idx(-1,-1)]=this.data[this._idx(0,0)],this.data[this._idx(o,-1)]=this.data[this._idx(o-1,0)],this.data[this._idx(-1,o)]=this.data[this._idx(0,o-1)],this.data[this._idx(o,o)]=this.data[this._idx(o-1,o-1)],this.min=Number.MAX_SAFE_INTEGER,this.max=Number.MIN_SAFE_INTEGER;for(let t=0;t<o;t++)for(let e=0;e<o;e++){const r=this.get(t,e);r>this.max&&(this.max=r),r<this.min&&(this.min=r);}}get(t,e){const r=new Uint8Array(this.data.buffer),n=4*this._idx(t,e);return this.unpack(r[n],r[n+1],r[n+2])}getUnpackVector(){return [this.redFactor,this.greenFactor,this.blueFactor,this.baseShift]}_idx(t,e){if(t<-1||t>=this.dim+1||e<-1||e>=this.dim+1)throw new RangeError(\"out of range source coordinates for DEM data\");return (e+1)*this.stride+(t+1)}unpack(t,e,r){return t*this.redFactor+e*this.greenFactor+r*this.blueFactor-this.baseShift}pack(t){return ml(t,this.getUnpackVector())}getPixels(){return new sl({width:this.stride,height:this.stride},new Uint8Array(this.data.buffer))}backfillBorder(t,e,r){if(this.dim!==t.dim)throw new Error(\"dem dimension mismatch\");let n=e*this.dim,i=e*this.dim+this.dim,s=r*this.dim,a=r*this.dim+this.dim;switch(e){case -1:n=i-1;break;case 1:i=n+1;}switch(r){case -1:s=a-1;break;case 1:a=s+1;}const o=-e*this.dim,l=-r*this.dim;for(let e=s;e<a;e++)for(let r=n;r<i;r++)this.data[this._idx(r,e)]=t.data[this._idx(r+o,e+l)];}}function ml(t,e){const r=e[0],n=e[1],i=e[2],s=e[3],a=Math.min(r,n,i),o=Math.round((t+s)/a);return {r:Math.floor(o*a/r)%256,g:Math.floor(o*a/n)%256,b:Math.floor(o*a/i)%256}}us(\"DEMData\",yl);class gl extends Xs{constructor(t){super(t,fl);}_createColorRamp(t){const e={elevationStops:[],colorStops:[]},r=this._transitionablePaint._values[\"color-relief-color\"].value.expression;if(r instanceof ai&&r._styleExpression.expression instanceof yr){this.colorRampExpression=r;const t=r._styleExpression.expression;e.elevationStops=t.labels,e.colorStops=[];for(const r of e.elevationStops)e.colorStops.push(t.evaluate({globals:{elevation:r}}));}if(e.elevationStops.length<1&&(e.elevationStops=[0],e.colorStops=[Pe.transparent]),e.elevationStops.length<2&&(e.elevationStops.push(e.elevationStops[0]+1),e.colorStops.push(e.colorStops[0])),e.elevationStops.length<=t)return e;const n={elevationStops:[],colorStops:[]},i=(e.elevationStops.length-1)/(t-1);for(let t=0;t<e.elevationStops.length-.5;t+=i)n.elevationStops.push(e.elevationStops[Math.round(t)]),n.colorStops.push(e.colorStops[Math.round(t)]);return Z(`Too many colors in specification of ${this.id} color-relief layer, may not render properly.`),n}_colorRampChanged(){return this.colorRampExpression!=this._transitionablePaint._values[\"color-relief-color\"].value.expression}getColorRampTextures(t,e,r){if(this.colorRampTextures&&!this._colorRampChanged())return this.colorRampTextures;const n=this._createColorRamp(e),i=new sl({width:n.colorStops.length,height:1}),s=new sl({width:n.colorStops.length,height:1});for(let t=0;t<n.elevationStops.length;t++){const e=ml(n.elevationStops[t],r);s.setPixel(0,t,new Pe(e.r/255,e.g/255,e.b/255,1)),i.setPixel(0,t,n.colorStops[t]);}return this.colorRampTextures={elevationTexture:new dl(t,s,t.gl.RGBA),colorTexture:new dl(t,i,t.gl.RGBA)},this.colorRampTextures}hasOffscreenPass(){return \"none\"!==this.visibility&&!!this.colorRampTextures}}const xl=Ks([{name:\"a_pos\",components:2,type:\"Int16\"}],4),{members:vl}=xl;function bl(t,e,r){const n=r.patternDependencies;let i=!1;for(const r of e){const e=r.paint.get(`${t}-pattern`);e.isConstant()||(i=!0);const s=e.constantOr(null);s&&(i=!0,n[s.to]=!0,n[s.from]=!0);}return i}function wl(t,e,r,n,i){const s=i.patternDependencies;for(const a of e){const e=a.paint.get(`${t}-pattern`).value;if(\"constant\"!==e.kind){let t=e.evaluate({zoom:n-1},r,{},i.availableImages),o=e.evaluate({zoom:n},r,{},i.availableImages),l=e.evaluate({zoom:n+1},r,{},i.availableImages);t=t&&t.name?t.name:t,o=o&&o.name?o.name:o,l=l&&l.name?l.name:l,s[t]=!0,s[o]=!0,s[l]=!0,r.patterns[a.id]={min:t,mid:o,max:l};}}return r}function _l(t,e,r,n,i){let s;if(i===function(t,e,r,n){let i=0;for(let s=e,a=r-n;s<r;s+=n)i+=(t[a]-t[s])*(t[s+1]+t[a+1]),a=s;return i}(t,e,r,n)>0)for(let i=e;i<r;i+=n)s=ql(i/n|0,t[i],t[i+1],s);else for(let i=r-n;i>=e;i-=n)s=ql(i/n|0,t[i],t[i+1],s);return s&&Dl(s,s.next)&&(Gl(s),s=s.next),s}function Sl(t,e){if(!t)return t;e||(e=t);let r,n=t;do{if(r=!1,n.steiner||!Dl(n,n.next)&&0!==$l(n.prev,n,n.next))n=n.next;else {if(Gl(n),n=e=n.prev,n===n.next)break;r=!0;}}while(r||n!==e);return e}function Al(t,e,r,n,i,s,a){if(!t)return;!a&&s&&function(t,e,r,n){let i=t;do{0===i.z&&(i.z=El(i.x,i.y,e,r,n)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;}while(i!==t);i.prevZ.nextZ=null,i.prevZ=null,function(t){let e,r=1;do{let n,i=t;t=null;let s=null;for(e=0;i;){e++;let a=i,o=0;for(let t=0;t<r&&(o++,a=a.nextZ,a);t++);let l=r;for(;o>0||l>0&&a;)0!==o&&(0===l||!a||i.z<=a.z)?(n=i,i=i.nextZ,o--):(n=a,a=a.nextZ,l--),s?s.nextZ=n:t=n,n.prevZ=s,s=n;i=a;}s.nextZ=null,r*=2;}while(e>1)}(i);}(t,n,i,s);let o=t;for(;t.prev!==t.next;){const l=t.prev,u=t.next;if(s?Ml(t,n,i,s):kl(t))e.push(l.i,t.i,u.i),Gl(t),t=u.next,o=u.next;else if((t=u)===o){a?1===a?Al(t=Il(Sl(t),e),e,r,n,i,s,2):2===a&&zl(t,e,r,n,i,s):Al(Sl(t),e,r,n,i,s,1);break}}}function kl(t){const e=t.prev,r=t,n=t.next;if($l(e,r,n)>=0)return !1;const i=e.x,s=r.x,a=n.x,o=e.y,l=r.y,u=n.y,c=Math.min(i,s,a),h=Math.min(o,l,u),p=Math.max(i,s,a),f=Math.max(o,l,u);let d=n.next;for(;d!==e;){if(d.x>=c&&d.x<=p&&d.y>=h&&d.y<=f&&Fl(i,o,s,l,a,u,d.x,d.y)&&$l(d.prev,d,d.next)>=0)return !1;d=d.next;}return !0}function Ml(t,e,r,n){const i=t.prev,s=t,a=t.next;if($l(i,s,a)>=0)return !1;const o=i.x,l=s.x,u=a.x,c=i.y,h=s.y,p=a.y,f=Math.min(o,l,u),d=Math.min(c,h,p),y=Math.max(o,l,u),m=Math.max(c,h,p),g=El(f,d,e,r,n),x=El(y,m,e,r,n);let v=t.prevZ,b=t.nextZ;for(;v&&v.z>=g&&b&&b.z<=x;){if(v.x>=f&&v.x<=y&&v.y>=d&&v.y<=m&&v!==i&&v!==a&&Fl(o,c,l,h,u,p,v.x,v.y)&&$l(v.prev,v,v.next)>=0)return !1;if(v=v.prevZ,b.x>=f&&b.x<=y&&b.y>=d&&b.y<=m&&b!==i&&b!==a&&Fl(o,c,l,h,u,p,b.x,b.y)&&$l(b.prev,b,b.next)>=0)return !1;b=b.nextZ;}for(;v&&v.z>=g;){if(v.x>=f&&v.x<=y&&v.y>=d&&v.y<=m&&v!==i&&v!==a&&Fl(o,c,l,h,u,p,v.x,v.y)&&$l(v.prev,v,v.next)>=0)return !1;v=v.prevZ;}for(;b&&b.z<=x;){if(b.x>=f&&b.x<=y&&b.y>=d&&b.y<=m&&b!==i&&b!==a&&Fl(o,c,l,h,u,p,b.x,b.y)&&$l(b.prev,b,b.next)>=0)return !1;b=b.nextZ;}return !0}function Il(t,e){let r=t;do{const n=r.prev,i=r.next.next;!Dl(n,i)&&Ol(n,r,r.next,i)&&Nl(n,i)&&Nl(i,n)&&(e.push(n.i,r.i,i.i),Gl(r),Gl(r.next),r=t=i),r=r.next;}while(r!==t);return Sl(r)}function zl(t,e,r,n,i,s){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&Ll(a,t)){let o=Ul(a,t);return a=Sl(a,a.next),o=Sl(o,o.next),Al(a,e,r,n,i,s,0),void Al(o,e,r,n,i,s,0)}t=t.next;}a=a.next;}while(a!==t)}function Pl(t,e){let r=t.x-e.x;return 0===r&&(r=t.y-e.y,0===r)&&(r=(t.next.y-t.y)/(t.next.x-t.x)-(e.next.y-e.y)/(e.next.x-e.x)),r}function Cl(t,e){const r=function(t,e){let r=e;const n=t.x,i=t.y;let s,a=-1/0;if(Dl(t,r))return r;do{if(Dl(t,r.next))return r.next;if(i<=r.y&&i>=r.next.y&&r.next.y!==r.y){const t=r.x+(i-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(t<=n&&t>a&&(a=t,s=r.x<r.next.x?r:r.next,t===n))return s}r=r.next;}while(r!==e);if(!s)return null;const o=s,l=s.x,u=s.y;let c=1/0;r=s;do{if(n>=r.x&&r.x>=l&&n!==r.x&&Vl(i<u?n:a,i,l,u,i<u?a:n,i,r.x,r.y)){const e=Math.abs(i-r.y)/(n-r.x);Nl(r,t)&&(e<c||e===c&&(r.x>s.x||r.x===s.x&&Bl(s,r)))&&(s=r,c=e);}r=r.next;}while(r!==o);return s}(t,e);if(!r)return e;const n=Ul(r,t);return Sl(n,n.next),Sl(r,r.next)}function Bl(t,e){return $l(t.prev,t,e.prev)<0&&$l(e.next,t,t.next)<0}function El(t,e,r,n,i){return (t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-r)*i|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-n)*i|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function Tl(t){let e=t,r=t;do{(e.x<r.x||e.x===r.x&&e.y<r.y)&&(r=e),e=e.next;}while(e!==t);return r}function Vl(t,e,r,n,i,s,a,o){return (i-a)*(e-o)>=(t-a)*(s-o)&&(t-a)*(n-o)>=(r-a)*(e-o)&&(r-a)*(s-o)>=(i-a)*(n-o)}function Fl(t,e,r,n,i,s,a,o){return !(t===a&&e===o)&&Vl(t,e,r,n,i,s,a,o)}function Ll(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let r=t;do{if(r.i!==t.i&&r.next.i!==t.i&&r.i!==e.i&&r.next.i!==e.i&&Ol(r,r.next,t,e))return !0;r=r.next;}while(r!==t);return !1}(t,e)&&(Nl(t,e)&&Nl(e,t)&&function(t,e){let r=t,n=!1;const i=(t.x+e.x)/2,s=(t.y+e.y)/2;do{r.y>s!=r.next.y>s&&r.next.y!==r.y&&i<(r.next.x-r.x)*(s-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next;}while(r!==t);return n}(t,e)&&($l(t.prev,t,e.prev)||$l(t,e.prev,e))||Dl(t,e)&&$l(t.prev,t,t.next)>0&&$l(e.prev,e,e.next)>0)}function $l(t,e,r){return (e.y-t.y)*(r.x-e.x)-(e.x-t.x)*(r.y-e.y)}function Dl(t,e){return t.x===e.x&&t.y===e.y}function Ol(t,e,r,n){const i=jl($l(t,e,r)),s=jl($l(t,e,n)),a=jl($l(r,n,t)),o=jl($l(r,n,e));return i!==s&&a!==o||!(0!==i||!Rl(t,r,e))||!(0!==s||!Rl(t,n,e))||!(0!==a||!Rl(r,t,n))||!(0!==o||!Rl(r,e,n))}function Rl(t,e,r){return e.x<=Math.max(t.x,r.x)&&e.x>=Math.min(t.x,r.x)&&e.y<=Math.max(t.y,r.y)&&e.y>=Math.min(t.y,r.y)}function jl(t){return t>0?1:t<0?-1:0}function Nl(t,e){return $l(t.prev,t,t.next)<0?$l(t,e,t.next)>=0&&$l(t,t.prev,e)>=0:$l(t,e,t.prev)<0||$l(t,t.next,e)<0}function Ul(t,e){const r=Xl(t.i,t.x,t.y),n=Xl(e.i,e.x,e.y),i=t.next,s=e.prev;return t.next=e,e.prev=t,r.next=i,i.prev=r,n.next=r,r.prev=n,s.next=n,n.prev=s,n}function ql(t,e,r,n){const i=Xl(t,e,r);return n?(i.next=n.next,i.prev=n,n.next.prev=i,n.next=i):(i.prev=i,i.next=i),i}function Gl(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ);}function Xl(t,e,r){return {i:t,x:e,y:r,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}class Zl{constructor(t,e){if(e>t)throw new Error(\"Min granularity must not be greater than base granularity.\");this._baseZoomGranularity=t,this._minGranularity=e;}getGranularityForZoomLevel(t){return Math.max(Math.floor(this._baseZoomGranularity/(1<<t)),this._minGranularity,1)}}class Yl{constructor(t){this.fill=t.fill,this.line=t.line,this.tile=t.tile,this.stencil=t.stencil,this.circle=t.circle;}}Yl.noSubdivision=new Yl({fill:new Zl(0,0),line:new Zl(0,0),tile:new Zl(0,0),stencil:new Zl(0,0),circle:1}),us(\"SubdivisionGranularityExpression\",Zl),us(\"SubdivisionGranularitySetting\",Yl);const Hl=-32768,Kl=32767;class Jl{constructor(t,e){this._vertexBuffer=[],this._vertexDictionary=new Map,this._used=!1,this._granularity=t,this._granularityCellSize=E/t,this._canonical=e;}_getKey(t,e){return (t+=32768)<<16|e+32768}_vertexToIndex(t,e){if(t<-32768||e<-32768||t>32767||e>32767)throw new Error(\"Vertex coordinates are out of signed 16 bit integer range.\");const r=0|Math.round(t),n=0|Math.round(e),i=this._getKey(r,n);if(this._vertexDictionary.has(i))return this._vertexDictionary.get(i);const s=this._vertexBuffer.length/2;return this._vertexDictionary.set(i,s),this._vertexBuffer.push(r,n),s}_subdivideTrianglesScanline(t){if(this._granularity<2)return function(t,e){const r=[];for(let n=0;n<e.length;n+=3){const i=e[n],s=e[n+1],a=e[n+2],o=t[2*i],l=t[2*i+1];(t[2*s]-o)*(t[2*a+1]-l)-(t[2*s+1]-l)*(t[2*a]-o)>0?(r.push(i),r.push(a),r.push(s)):(r.push(i),r.push(s),r.push(a));}return r}(this._vertexBuffer,t);const e=[],r=t.length;for(let n=0;n<r;n+=3){const r=[t[n+0],t[n+1],t[n+2]],i=[this._vertexBuffer[2*t[n+0]+0],this._vertexBuffer[2*t[n+0]+1],this._vertexBuffer[2*t[n+1]+0],this._vertexBuffer[2*t[n+1]+1],this._vertexBuffer[2*t[n+2]+0],this._vertexBuffer[2*t[n+2]+1]];let s=1/0,a=1/0,o=-1/0,l=-1/0;for(let t=0;t<3;t++){const e=i[2*t],r=i[2*t+1];s=Math.min(s,e),o=Math.max(o,e),a=Math.min(a,r),l=Math.max(l,r);}if(s===o||a===l)continue;const u=Math.floor(s/this._granularityCellSize),c=Math.ceil(o/this._granularityCellSize),h=Math.floor(a/this._granularityCellSize),p=Math.ceil(l/this._granularityCellSize);if(u!==c||h!==p)for(let t=h;t<p;t++){const n=this._scanlineGenerateVertexRingForCellRow(t,i,r);tu(this._vertexBuffer,n,e);}else e.push(...r);}return e}_scanlineGenerateVertexRingForCellRow(t,e,r){const n=t*this._granularityCellSize,i=n+this._granularityCellSize,s=[];for(let t=0;t<3;t++){const a=e[2*t],o=e[2*t+1],l=e[2*(t+1)%6],u=e[(2*(t+1)+1)%6],c=e[2*(t+2)%6],h=e[(2*(t+2)+1)%6],p=l-a,f=u-o,d=0===p,y=0===f,m=(n-o)/f,g=(i-o)/f,x=Math.min(m,g),v=Math.max(m,g);if(!y&&(x>=1||v<=0)||y&&(o<n||o>i)){u>=n&&u<=i&&s.push(r[(t+1)%3]);continue}!y&&x>0&&s.push(this._vertexToIndex(a+p*x,o+f*x));const b=a+p*Math.max(x,0),w=a+p*Math.min(v,1);d||this._generateIntraEdgeVertices(s,a,o,l,u,b,w),!y&&v<1&&s.push(this._vertexToIndex(a+p*v,o+f*v)),(y||u>=n&&u<=i)&&s.push(r[(t+1)%3]),!y&&(u<=n||u>=i)&&this._generateInterEdgeVertices(s,a,o,l,u,c,h,w,n,i);}return s}_generateIntraEdgeVertices(t,e,r,n,i,s,a){const o=n-e,l=i-r,u=0===l,c=u?Math.min(e,n):Math.min(s,a),h=u?Math.max(e,n):Math.max(s,a),p=Math.floor(c/this._granularityCellSize)+1,f=Math.ceil(h/this._granularityCellSize)-1;if(u?e<n:s<a)for(let n=p;n<=f;n++){const i=n*this._granularityCellSize;t.push(this._vertexToIndex(i,r+l*(i-e)/o));}else for(let n=f;n>=p;n--){const i=n*this._granularityCellSize;t.push(this._vertexToIndex(i,r+l*(i-e)/o));}}_generateInterEdgeVertices(t,e,r,n,i,s,a,o,l,u){const c=i-r,h=s-n,p=a-i,f=(l-i)/p,d=(u-i)/p,y=Math.min(f,d),m=Math.max(f,d),g=n+h*y;let x=Math.floor(Math.min(g,o)/this._granularityCellSize)+1,v=Math.ceil(Math.max(g,o)/this._granularityCellSize)-1,b=o<g;const w=0===p;if(w&&(a===l||a===u))return;if(w||y>=1||m<=0){const t=r-a,n=s+(e-s)*Math.min((l-a)/t,(u-a)/t);x=Math.floor(Math.min(n,o)/this._granularityCellSize)+1,v=Math.ceil(Math.max(n,o)/this._granularityCellSize)-1,b=o<n;}const _=c>0?u:l;if(b)for(let e=x;e<=v;e++)t.push(this._vertexToIndex(e*this._granularityCellSize,_));else for(let e=v;e>=x;e--)t.push(this._vertexToIndex(e*this._granularityCellSize,_));}_generateOutline(t){const e=[];for(const r of t){const t=Ql(r,this._granularity,!0),n=this._pointArrayToIndices(t),i=[];for(let t=1;t<n.length;t++)i.push(n[t-1]),i.push(n[t]);e.push(i);}return e}_handlePoles(t){let e=!1,r=!1;this._canonical&&(0===this._canonical.y&&(e=!0),this._canonical.y===(1<<this._canonical.z)-1&&(r=!0)),(e||r)&&this._fillPoles(t,e,r);}_ensureNoPoleVertices(){const t=this._vertexBuffer;for(let e=0;e<t.length;e+=2){const r=t[e+1];r===Hl&&(t[e+1]=-32767),r===Kl&&(t[e+1]=32766);}}_generatePoleQuad(t,e,r,n,i,s){n>i!=(s===Hl)?(t.push(e),t.push(r),t.push(this._vertexToIndex(n,s)),t.push(r),t.push(this._vertexToIndex(i,s)),t.push(this._vertexToIndex(n,s))):(t.push(r),t.push(e),t.push(this._vertexToIndex(n,s)),t.push(this._vertexToIndex(i,s)),t.push(r),t.push(this._vertexToIndex(n,s)));}_fillPoles(t,e,r){const n=this._vertexBuffer,i=E,s=t.length;for(let a=2;a<s;a+=3){const s=t[a-2],o=t[a-1],l=t[a],u=n[2*s],c=n[2*s+1],h=n[2*o],p=n[2*o+1],f=n[2*l],d=n[2*l+1];e&&(0===c&&0===p&&this._generatePoleQuad(t,s,o,u,h,Hl),0===p&&0===d&&this._generatePoleQuad(t,o,l,h,f,Hl),0===d&&0===c&&this._generatePoleQuad(t,l,s,f,u,Hl)),r&&(c===i&&p===i&&this._generatePoleQuad(t,s,o,u,h,Kl),p===i&&d===i&&this._generatePoleQuad(t,o,l,h,f,Kl),d===i&&c===i&&this._generatePoleQuad(t,l,s,f,u,Kl));}}_initializeVertices(t){for(let e=0;e<t.length;e+=2)this._vertexToIndex(t[e],t[e+1]);}subdividePolygonInternal(t,e){if(this._used)throw new Error(\"Subdivision: multiple use not allowed.\");this._used=!0;const{flattened:r,holeIndices:n}=function(t){const e=[],r=[];for(const n of t)if(0!==n.length){n!==t[0]&&e.push(r.length/2);for(let t=0;t<n.length;t++)r.push(n[t].x),r.push(n[t].y);}return {flattened:r,holeIndices:e}}(t);let i;this._initializeVertices(r);try{const t=function(t,e,r=2){const n=e&&e.length,i=n?e[0]*r:t.length;let s=_l(t,0,i,r,!0);const a=[];if(!s||s.next===s.prev)return a;let o,l,u;if(n&&(s=function(t,e,r,n){const i=[];for(let r=0,s=e.length;r<s;r++){const a=_l(t,e[r]*n,r<s-1?e[r+1]*n:t.length,n,!1);a===a.next&&(a.steiner=!0),i.push(Tl(a));}i.sort(Pl);for(let t=0;t<i.length;t++)r=Cl(i[t],r);return r}(t,e,s,r)),t.length>80*r){o=1/0,l=1/0;let e=-1/0,n=-1/0;for(let s=r;s<i;s+=r){const r=t[s],i=t[s+1];r<o&&(o=r),i<l&&(l=i),r>e&&(e=r),i>n&&(n=i);}u=Math.max(e-o,n-l),u=0!==u?32767/u:0;}return Al(s,a,r,o,l,u,0),a}(r,n),e=this._convertIndices(r,t);i=this._subdivideTrianglesScanline(e);}catch(t){console.error(t);}let s=[];return e&&(s=this._generateOutline(t)),this._ensureNoPoleVertices(),this._handlePoles(i),{verticesFlattened:this._vertexBuffer,indicesTriangles:i,indicesLineList:s}}_convertIndices(t,e){const r=[];for(let n=0;n<e.length;n++)r.push(this._vertexToIndex(t[2*e[n]],t[2*e[n]+1]));return r}_pointArrayToIndices(t){const e=[];for(let r=0;r<t.length;r++){const n=t[r];e.push(this._vertexToIndex(n.x,n.y));}return e}}function Wl(t,e,r,n=!0){return new Jl(r,e).subdividePolygonInternal(t,n)}function Ql(t,e,r=!1){if(!t||t.length<1)return [];if(t.length<2)return [];const n=t[0],i=t[t.length-1],s=r&&(n.x!==i.x||n.y!==i.y);if(e<2)return s?[...t,t[0]]:[...t];const a=Math.floor(E/e),o=[];o.push(new l(t[0].x,t[0].y));const u=t.length,c=s?u:u-1;for(let e=0;e<c;e++){const r=t[e],n=e<u-1?t[e+1]:t[0],i=r.x,s=r.y,c=n.x,h=n.y,p=i!==c,f=s!==h;if(!p&&!f)continue;const d=c-i,y=h-s,m=Math.abs(d),g=Math.abs(y);let x=i,v=s;for(;;){const t=d>0?(Math.floor(x/a)+1)*a:(Math.ceil(x/a)-1)*a,e=y>0?(Math.floor(v/a)+1)*a:(Math.ceil(v/a)-1)*a,r=Math.abs(x-t),n=Math.abs(v-e),i=Math.abs(x-c),s=Math.abs(v-h),u=p?r/m:Number.POSITIVE_INFINITY,b=f?n/g:Number.POSITIVE_INFINITY;if((i<=r||!p)&&(s<=n||!f))break;if(u<b&&p||!f){x=t,v+=y*u;const e=new l(x,Math.round(v));o[o.length-1].x===e.x&&o[o.length-1].y===e.y||o.push(e);}else {x+=d*b,v=e;const t=new l(Math.round(x),v);o[o.length-1].x===t.x&&o[o.length-1].y===t.y||o.push(t);}}const b=new l(c,h);o[o.length-1].x===b.x&&o[o.length-1].y===b.y||o.push(b);}return o}function tu(t,e,r){if(0===e.length)throw new Error(\"Subdivision vertex ring is empty.\");let n=0,i=t[2*e[0]];for(let r=1;r<e.length;r++){const s=t[2*e[r]];s<i&&(i=s,n=r);}const s=e.length;let a=n,o=(a+1)%s;for(;;){const n=a-1>=0?a-1:s-1,i=(o+1)%s,l=t[2*e[n]],u=t[2*e[i]],c=t[2*e[a]],h=t[2*e[a]+1],p=t[2*e[o]+1];let f=!1;if(l<u)f=!0;else if(l>u)f=!1;else {const r=p-h,s=-(t[2*e[o]]-c),a=h<p?1:-1;((l-c)*r+(t[2*e[n]+1]-h)*s)*a>((u-c)*r+(t[2*e[i]+1]-h)*s)*a&&(f=!0);}if(f){const t=e[n],i=e[a],l=e[o];t!==i&&t!==l&&i!==l&&r.push(l,i,t),a--,a<0&&(a=s-1);}else {const t=e[i],n=e[a],l=e[o];t!==n&&t!==l&&n!==l&&r.push(l,n,t),o++,o>=s&&(o=0);}if(n===i)break}}function eu(t,e,r,n,i,s,a,o,l){const u=i.length/2,c=a&&o&&l;if(u<Ha.MAX_VERTEX_ARRAY_LENGTH){const h=e.prepareSegment(u,r,n),p=h.vertexLength;for(let t=0;t<s.length;t+=3)n.emplaceBack(p+s[t],p+s[t+1],p+s[t+2]);let f,d;h.vertexLength+=u,h.primitiveLength+=s.length/3,c&&(d=a.prepareSegment(u,r,o),f=d.vertexLength,d.vertexLength+=u);for(let e=0;e<i.length;e+=2)t(i[e],i[e+1]);if(c)for(let t=0;t<l.length;t++){const e=l[t];for(let t=1;t<e.length;t+=2)o.emplaceBack(f+e[t-1],f+e[t]);d.primitiveLength+=e.length/2;}}else !function(t,e,r,n,i,s){const a=[];for(let t=0;t<n.length/2;t++)a.push(-1);const o={count:0};let l=0,u=t.getOrCreateLatestSegment(e,r),c=u.vertexLength;for(let h=2;h<i.length;h+=3){const p=i[h-2],f=i[h-1],d=i[h];let y=a[p]<l,m=a[f]<l,g=a[d]<l;u.vertexLength+((y?1:0)+(m?1:0)+(g?1:0))>Ha.MAX_VERTEX_ARRAY_LENGTH&&(u=t.createNewSegment(e,r),l=o.count,y=!0,m=!0,g=!0,c=0);const x=ru(a,n,s,o,p,y,u),v=ru(a,n,s,o,f,m,u),b=ru(a,n,s,o,d,g,u);r.emplaceBack(c+x-l,c+v-l,c+b-l),u.primitiveLength++;}}(e,r,n,i,s,t),c&&function(t,e,r,n,i,s){const a=[];for(let t=0;t<n.length/2;t++)a.push(-1);const o={count:0};let l=0,u=t.getOrCreateLatestSegment(e,r),c=u.vertexLength;for(let h=0;h<i.length;h++){const p=i[h];for(let f=1;f<i[h].length;f+=2){const i=p[f-1],h=p[f];let d=a[i]<l,y=a[h]<l;u.vertexLength+((d?1:0)+(y?1:0))>Ha.MAX_VERTEX_ARRAY_LENGTH&&(u=t.createNewSegment(e,r),l=o.count,d=!0,y=!0,c=0);const m=ru(a,n,s,o,i,d,u),g=ru(a,n,s,o,h,y,u);r.emplaceBack(c+m-l,c+g-l),u.primitiveLength++;}}}(a,r,o,i,l,t),e.forceNewSegmentOnNextPrepare(),null==a||a.forceNewSegmentOnNextPrepare();}function ru(t,e,r,n,i,s,a){if(s){const s=n.count;return r(e[2*i],e[2*i+1]),t[i]=n.count,n.count++,a.vertexLength++,s}return t[i]}class nu{constructor(t){this.zoom=t.zoom,this.globalState=t.globalState,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map((t=>t.id)),this.index=t.index,this.hasPattern=!1,this.patternFeatures=[],this.layoutVertexArray=new Fa,this.indexArray=new Ga,this.indexArray2=new Xa,this.programConfigurations=new So(t.layers,t.zoom),this.segments=new Ha,this.segments2=new Ha,this.stateDependentLayerIds=this.layers.filter((t=>t.isStateDependent())).map((t=>t.id));}populate(t,e,r){this.hasPattern=bl(\"fill\",this.layers,e);const n=this.layers[0].layout.get(\"fill-sort-key\"),i=!n.isConstant(),s=[];for(const{feature:a,id:o,index:l,sourceLayerIndex:u}of t){const t=this.layers[0]._featureFilter.needGeometry,c=Po(a,t);if(!this.layers[0]._featureFilter.filter(new Cs(this.zoom,{globalState:this.globalState}),c,r))continue;const h=i?n.evaluate(c,{},r,e.availableImages):void 0,p={id:o,properties:a.properties,type:a.type,sourceLayerIndex:u,index:l,geometry:t?c.geometry:zo(a),patterns:{},sortKey:h};s.push(p);}i&&s.sort(((t,e)=>t.sortKey-e.sortKey));for(const n of s){const{geometry:i,index:s,sourceLayerIndex:a}=n;if(this.hasPattern){const t=wl(\"fill\",this.layers,n,this.zoom,e);this.patternFeatures.push(t);}else this.addFeature(n,i,s,r,{},e.subdivisionGranularity);e.featureIndex.insert(t[s].feature,i,s,a,this.index);}}update(t,e,r){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(t,e,this.stateDependentLayers,r);}addFeatures(t,e,r){for(const n of this.patternFeatures)this.addFeature(n,n.geometry,n.index,e,r,t.subdivisionGranularity);}isEmpty(){return 0===this.layoutVertexArray.length}uploadPending(){return !this.uploaded||this.programConfigurations.needsUpload}upload(t){this.uploaded||(this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,vl),this.indexBuffer=t.createIndexBuffer(this.indexArray),this.indexBuffer2=t.createIndexBuffer(this.indexArray2)),this.programConfigurations.upload(t),this.uploaded=!0;}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.indexBuffer2.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.segments2.destroy());}addFeature(t,e,r,n,i,s){for(const t of rn(e,500)){const e=Wl(t,n,s.fill.getGranularityForZoomLevel(n.z)),r=this.layoutVertexArray;eu(((t,e)=>{r.emplaceBack(t,e);}),this.segments,this.layoutVertexArray,this.indexArray,e.verticesFlattened,e.indicesTriangles,this.segments2,this.indexArray2,e.indicesLineList);}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,t,r,i,n);}}let iu,su;us(\"FillBucket\",nu,{omit:[\"layers\",\"patternFeatures\"]});var au={get paint(){return su=su||new qs({\"fill-antialias\":new Os(wt.paint_fill[\"fill-antialias\"]),\"fill-opacity\":new Rs(wt.paint_fill[\"fill-opacity\"]),\"fill-color\":new Rs(wt.paint_fill[\"fill-color\"]),\"fill-outline-color\":new Rs(wt.paint_fill[\"fill-outline-color\"]),\"fill-translate\":new Os(wt.paint_fill[\"fill-translate\"]),\"fill-translate-anchor\":new Os(wt.paint_fill[\"fill-translate-anchor\"]),\"fill-pattern\":new js(wt.paint_fill[\"fill-pattern\"])})},get layout(){return iu=iu||new qs({\"fill-sort-key\":new Rs(wt.layout_fill[\"fill-sort-key\"])})}};class ou extends Xs{constructor(t){super(t,au);}recalculate(t,e){super.recalculate(t,e);const r=this.paint._values[\"fill-outline-color\"];\"constant\"===r.value.kind&&void 0===r.value.value&&(this.paint._values[\"fill-outline-color\"]=this.paint._values[\"fill-color\"]);}createBucket(t){return new nu(t)}queryRadius(){return Go(this.paint.get(\"fill-translate\"))}queryIntersectsFeature({queryGeometry:t,geometry:e,transform:r,pixelsToTileUnits:n}){return Fo(Xo(t,this.paint.get(\"fill-translate\"),this.paint.get(\"fill-translate-anchor\"),-r.bearingInRadians,n),e)}isTileClipped(){return !0}}const lu=Ks([{name:\"a_pos\",components:2,type:\"Int16\"},{name:\"a_normal_ed\",components:4,type:\"Int16\"}],4),uu=Ks([{name:\"a_centroid\",components:2,type:\"Int16\"}],4),{members:cu}=lu;var hu,pu,fu,du,yu,mu,gu,xu={};function vu(){if(pu)return hu;pu=1;var t=s();function e(t,e,n,i,s){this.properties={},this.extent=n,this.type=0,this._pbf=t,this._geometry=-1,this._keys=i,this._values=s,t.readFields(r,this,e);}function r(t,e,r){1==t?e.id=r.readVarint():2==t?function(t,e){for(var r=t.readVarint()+t.pos;t.pos<r;){var n=e._keys[t.readVarint()],i=e._values[t.readVarint()];e.properties[n]=i;}}(r,e):3==t?e.type=r.readVarint():4==t&&(e._geometry=r.pos);}function n(t){for(var e,r,n=0,i=0,s=t.length,a=s-1;i<s;a=i++)n+=((r=t[a]).x-(e=t[i]).x)*(e.y+r.y);return n}return hu=e,e.types=[\"Unknown\",\"Point\",\"LineString\",\"Polygon\"],e.prototype.loadGeometry=function(){var e=this._pbf;e.pos=this._geometry;for(var r,n=e.readVarint()+e.pos,i=1,s=0,a=0,o=0,l=[];e.pos<n;){if(s<=0){var u=e.readVarint();i=7&u,s=u>>3;}if(s--,1===i||2===i)a+=e.readSVarint(),o+=e.readSVarint(),1===i&&(r&&l.push(r),r=[]),r.push(new t(a,o));else {if(7!==i)throw new Error(\"unknown command \"+i);r&&r.push(r[0].clone());}}return r&&l.push(r),l},e.prototype.bbox=function(){var t=this._pbf;t.pos=this._geometry;for(var e=t.readVarint()+t.pos,r=1,n=0,i=0,s=0,a=1/0,o=-1/0,l=1/0,u=-1/0;t.pos<e;){if(n<=0){var c=t.readVarint();r=7&c,n=c>>3;}if(n--,1===r||2===r)(i+=t.readSVarint())<a&&(a=i),i>o&&(o=i),(s+=t.readSVarint())<l&&(l=s),s>u&&(u=s);else if(7!==r)throw new Error(\"unknown command \"+r)}return [a,l,o,u]},e.prototype.toGeoJSON=function(t,r,i){var s,a,o=this.extent*Math.pow(2,i),l=this.extent*t,u=this.extent*r,c=this.loadGeometry(),h=e.types[this.type];function p(t){for(var e=0;e<t.length;e++){var r=t[e];t[e]=[360*(r.x+l)/o-180,360/Math.PI*Math.atan(Math.exp((180-360*(r.y+u)/o)*Math.PI/180))-90];}}switch(this.type){case 1:var f=[];for(s=0;s<c.length;s++)f[s]=c[s][0];p(c=f);break;case 2:for(s=0;s<c.length;s++)p(c[s]);break;case 3:for(c=function(t){var e=t.length;if(e<=1)return [t];for(var r,i,s=[],a=0;a<e;a++){var o=n(t[a]);0!==o&&(void 0===i&&(i=o<0),i===o<0?(r&&s.push(r),r=[t[a]]):r.push(t[a]));}return r&&s.push(r),s}(c),s=0;s<c.length;s++)for(a=0;a<c[s].length;a++)p(c[s][a]);}1===c.length?c=c[0]:h=\"Multi\"+h;var d={type:\"Feature\",geometry:{type:h,coordinates:c},properties:this.properties};return \"id\"in this&&(d.id=this.id),d},hu}function bu(){if(du)return fu;du=1;var t=vu();function e(t,e){this.version=1,this.name=null,this.extent=4096,this.length=0,this._pbf=t,this._keys=[],this._values=[],this._features=[],t.readFields(r,this,e),this.length=this._features.length;}function r(t,e,r){15===t?e.version=r.readVarint():1===t?e.name=r.readString():5===t?e.extent=r.readVarint():2===t?e._features.push(r.pos):3===t?e._keys.push(r.readString()):4===t&&e._values.push(function(t){for(var e=null,r=t.readVarint()+t.pos;t.pos<r;){var n=t.readVarint()>>3;e=1===n?t.readString():2===n?t.readFloat():3===n?t.readDouble():4===n?t.readVarint64():5===n?t.readVarint():6===n?t.readSVarint():7===n?t.readBoolean():null;}return e}(r));}return fu=e,e.prototype.feature=function(e){if(e<0||e>=this._features.length)throw new Error(\"feature index out of bounds\");this._pbf.pos=this._features[e];var r=this._pbf.readVarint()+this._pbf.pos;return new t(this._pbf,r,this.extent,this._keys,this._values)},fu}function wu(){return gu||(gu=1,xu.VectorTile=function(){if(mu)return yu;mu=1;var t=bu();function e(e,r,n){if(3===e){var i=new t(n,n.readVarint()+n.pos);i.length&&(r[i.name]=i);}}return yu=function(t,r){this.layers=t.readFields(e,{},r);},yu}(),xu.VectorTileFeature=vu(),xu.VectorTileLayer=bu()),xu}var _u=r(wu());const Su=_u.VectorTileFeature.types,Au=Math.pow(2,13);function ku(t,e,r,n,i,s,a,o){t.emplaceBack(e,r,2*Math.floor(n*Au)+a,i*Au*2,s*Au*2,Math.round(o));}class Mu{constructor(t){this.zoom=t.zoom,this.globalState=t.globalState,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map((t=>t.id)),this.index=t.index,this.hasPattern=!1,this.layoutVertexArray=new La,this.centroidVertexArray=new Ta,this.indexArray=new Ga,this.programConfigurations=new So(t.layers,t.zoom),this.segments=new Ha,this.stateDependentLayerIds=this.layers.filter((t=>t.isStateDependent())).map((t=>t.id));}populate(t,e,r){this.features=[],this.hasPattern=bl(\"fill-extrusion\",this.layers,e);for(const{feature:n,id:i,index:s,sourceLayerIndex:a}of t){const t=this.layers[0]._featureFilter.needGeometry,o=Po(n,t);if(!this.layers[0]._featureFilter.filter(new Cs(this.zoom,{globalState:this.globalState}),o,r))continue;const l={id:i,sourceLayerIndex:a,index:s,geometry:t?o.geometry:zo(n),properties:n.properties,type:n.type,patterns:{}};this.hasPattern?this.features.push(wl(\"fill-extrusion\",this.layers,l,this.zoom,e)):this.addFeature(l,l.geometry,s,r,{},e.subdivisionGranularity),e.featureIndex.insert(n,l.geometry,s,a,this.index,!0);}}addFeatures(t,e,r){for(const n of this.features){const{geometry:i}=n;this.addFeature(n,i,n.index,e,r,t.subdivisionGranularity);}}update(t,e,r){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(t,e,this.stateDependentLayers,r);}isEmpty(){return 0===this.layoutVertexArray.length&&0===this.centroidVertexArray.length}uploadPending(){return !this.uploaded||this.programConfigurations.needsUpload}upload(t){this.uploaded||(this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,cu),this.centroidVertexBuffer=t.createVertexBuffer(this.centroidVertexArray,uu.members,!0),this.indexBuffer=t.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(t),this.uploaded=!0;}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.centroidVertexBuffer.destroy());}addFeature(t,e,r,n,i,s){for(const r of rn(e,500)){const e={x:0,y:0,sampleCount:0},i=this.layoutVertexArray.length;this.processPolygon(e,n,t,r,s);const a=this.layoutVertexArray.length-i,o=Math.floor(e.x/e.sampleCount),l=Math.floor(e.y/e.sampleCount);for(let t=0;t<a;t++)this.centroidVertexArray.emplaceBack(o,l);}this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,t,r,i,n);}processPolygon(t,e,r,n,i){if(n.length<1)return;if(Pu(n[0]))return;for(const e of n)0!==e.length&&Iu(t,e);const s={segment:this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray)},a=i.fill.getGranularityForZoomLevel(e.z),o=\"Polygon\"===Su[r.type];for(const t of n){if(0===t.length)continue;if(Pu(t))continue;const e=Ql(t,a,o);this._generateSideFaces(e,s);}if(!o)return;const l=Wl(n,e,a,!1),u=this.layoutVertexArray;eu(((t,e)=>{ku(u,t,e,0,0,1,1,0);}),this.segments,this.layoutVertexArray,this.indexArray,l.verticesFlattened,l.indicesTriangles);}_generateSideFaces(t,e){let r=0;for(let n=1;n<t.length;n++){const i=t[n],s=t[n-1];if(zu(i,s))continue;e.segment.vertexLength+4>Ha.MAX_VERTEX_ARRAY_LENGTH&&(e.segment=this.segments.prepareSegment(4,this.layoutVertexArray,this.indexArray));const a=i.sub(s)._perp()._unit(),o=s.dist(i);r+o>32768&&(r=0),ku(this.layoutVertexArray,i.x,i.y,a.x,a.y,0,0,r),ku(this.layoutVertexArray,i.x,i.y,a.x,a.y,0,1,r),r+=o,ku(this.layoutVertexArray,s.x,s.y,a.x,a.y,0,0,r),ku(this.layoutVertexArray,s.x,s.y,a.x,a.y,0,1,r);const l=e.segment.vertexLength;this.indexArray.emplaceBack(l,l+2,l+1),this.indexArray.emplaceBack(l+1,l+2,l+3),e.segment.vertexLength+=4,e.segment.primitiveLength+=2;}}}function Iu(t,e){for(let r=0;r<e.length;r++){const n=e[r];r===e.length-1&&e[0].x===n.x&&e[0].y===n.y||(t.x+=n.x,t.y+=n.y,t.sampleCount++);}}function zu(t,e){return t.x===e.x&&(t.x<0||t.x>E)||t.y===e.y&&(t.y<0||t.y>E)}function Pu(t){return t.every((t=>t.x<0))||t.every((t=>t.x>E))||t.every((t=>t.y<0))||t.every((t=>t.y>E))}let Cu;us(\"FillExtrusionBucket\",Mu,{omit:[\"layers\",\"features\"]});var Bu={get paint(){return Cu=Cu||new qs({\"fill-extrusion-opacity\":new Os(wt[\"paint_fill-extrusion\"][\"fill-extrusion-opacity\"]),\"fill-extrusion-color\":new Rs(wt[\"paint_fill-extrusion\"][\"fill-extrusion-color\"]),\"fill-extrusion-translate\":new Os(wt[\"paint_fill-extrusion\"][\"fill-extrusion-translate\"]),\"fill-extrusion-translate-anchor\":new Os(wt[\"paint_fill-extrusion\"][\"fill-extrusion-translate-anchor\"]),\"fill-extrusion-pattern\":new js(wt[\"paint_fill-extrusion\"][\"fill-extrusion-pattern\"]),\"fill-extrusion-height\":new Rs(wt[\"paint_fill-extrusion\"][\"fill-extrusion-height\"]),\"fill-extrusion-base\":new Rs(wt[\"paint_fill-extrusion\"][\"fill-extrusion-base\"]),\"fill-extrusion-vertical-gradient\":new Os(wt[\"paint_fill-extrusion\"][\"fill-extrusion-vertical-gradient\"])})}};class Eu extends Xs{constructor(t){super(t,Bu);}createBucket(t){return new Mu(t)}queryRadius(){return Go(this.paint.get(\"fill-extrusion-translate\"))}is3D(){return !0}queryIntersectsFeature({queryGeometry:t,feature:e,featureState:r,geometry:n,transform:i,pixelsToTileUnits:s,pixelPosMatrix:a}){const o=Xo(t,this.paint.get(\"fill-extrusion-translate\"),this.paint.get(\"fill-extrusion-translate-anchor\"),-i.bearingInRadians,s),u=this.paint.get(\"fill-extrusion-height\").evaluate(e,r),c=this.paint.get(\"fill-extrusion-base\").evaluate(e,r),h=function(t,e){const r=[];for(const n of t){const t=[n.x,n.y,0,1];I(t,t,e),r.push(new l(t[0]/t[3],t[1]/t[3]));}return r}(o,a),p=function(t,e,r,n){const i=[],s=[],a=n[8]*e,o=n[9]*e,u=n[10]*e,c=n[11]*e,h=n[8]*r,p=n[9]*r,f=n[10]*r,d=n[11]*r;for(const e of t){const t=[],r=[];for(const i of e){const e=i.x,s=i.y,y=n[0]*e+n[4]*s+n[12],m=n[1]*e+n[5]*s+n[13],g=n[2]*e+n[6]*s+n[14],x=n[3]*e+n[7]*s+n[15],v=g+u,b=x+c,w=y+h,_=m+p,S=g+f,A=x+d,k=new l((y+a)/b,(m+o)/b);k.z=v/b,t.push(k);const M=new l(w/A,_/A);M.z=S/A,r.push(M);}i.push(t),s.push(r);}return [i,s]}(n,c,u,a);return function(t,e,r){let n=1/0;Fo(r,e)&&(n=Vu(r,e[0]));for(let i=0;i<e.length;i++){const s=e[i],a=t[i];for(let t=0;t<s.length-1;t++){const e=s[t],i=[e,s[t+1],a[t+1],a[t],e];To(r,i)&&(n=Math.min(n,Vu(r,i)));}}return n!==1/0&&n}(p[0],p[1],h)}}function Tu(t,e){return t.x*e.x+t.y*e.y}function Vu(t,e){if(1===t.length){let r=0;const n=e[r++];let i;for(;!i||n.equals(i);)if(i=e[r++],!i)return 1/0;for(;r<e.length;r++){const s=e[r],a=t[0],o=i.sub(n),l=s.sub(n),u=a.sub(n),c=Tu(o,o),h=Tu(o,l),p=Tu(l,l),f=Tu(u,o),d=Tu(u,l),y=c*p-h*h,m=(p*f-h*d)/y,g=(c*d-h*f)/y,x=n.z*(1-m-g)+i.z*m+s.z*g;if(isFinite(x))return x}return 1/0}{let t=1/0;for(const r of e)t=Math.min(t,r.z);return t}}const Fu=Ks([{name:\"a_pos_normal\",components:2,type:\"Int16\"},{name:\"a_data\",components:4,type:\"Uint8\"}],4),{members:Lu}=Fu,$u=Ks([{name:\"a_uv_x\",components:1,type:\"Float32\"},{name:\"a_split_index\",components:1,type:\"Float32\"}]),{members:Du}=$u,Ou=_u.VectorTileFeature.types,Ru=Math.cos(Math.PI/180*37.5),ju=Math.pow(2,14)/.5;class Nu{constructor(t){this.zoom=t.zoom,this.globalState=t.globalState,this.overscaling=t.overscaling,this.layers=t.layers,this.layerIds=this.layers.map((t=>t.id)),this.index=t.index,this.hasPattern=!1,this.patternFeatures=[],this.lineClipsArray=[],this.gradients={},this.layers.forEach((t=>{this.gradients[t.id]={};})),this.layoutVertexArray=new $a,this.layoutVertexArray2=new Da,this.indexArray=new Ga,this.programConfigurations=new So(t.layers,t.zoom),this.segments=new Ha,this.maxLineLength=0,this.stateDependentLayerIds=this.layers.filter((t=>t.isStateDependent())).map((t=>t.id));}populate(t,e,r){this.hasPattern=bl(\"line\",this.layers,e);const n=this.layers[0].layout.get(\"line-sort-key\"),i=!n.isConstant(),s=[];for(const{feature:e,id:a,index:o,sourceLayerIndex:l}of t){const t=this.layers[0]._featureFilter.needGeometry,u=Po(e,t);if(!this.layers[0]._featureFilter.filter(new Cs(this.zoom,{globalState:this.globalState}),u,r))continue;const c=i?n.evaluate(u,{},r):void 0,h={id:a,properties:e.properties,type:e.type,sourceLayerIndex:l,index:o,geometry:t?u.geometry:zo(e),patterns:{},sortKey:c};s.push(h);}i&&s.sort(((t,e)=>t.sortKey-e.sortKey));for(const n of s){const{geometry:i,index:s,sourceLayerIndex:a}=n;if(this.hasPattern){const t=wl(\"line\",this.layers,n,this.zoom,e);this.patternFeatures.push(t);}else this.addFeature(n,i,s,r,{},e.subdivisionGranularity);e.featureIndex.insert(t[s].feature,i,s,a,this.index);}}update(t,e,r){this.stateDependentLayers.length&&this.programConfigurations.updatePaintArrays(t,e,this.stateDependentLayers,r);}addFeatures(t,e,r){for(const n of this.patternFeatures)this.addFeature(n,n.geometry,n.index,e,r,t.subdivisionGranularity);}isEmpty(){return 0===this.layoutVertexArray.length}uploadPending(){return !this.uploaded||this.programConfigurations.needsUpload}upload(t){this.uploaded||(0!==this.layoutVertexArray2.length&&(this.layoutVertexBuffer2=t.createVertexBuffer(this.layoutVertexArray2,Du)),this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,Lu),this.indexBuffer=t.createIndexBuffer(this.indexArray)),this.programConfigurations.upload(t),this.uploaded=!0;}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy());}lineFeatureClips(t){if(t.properties&&Object.prototype.hasOwnProperty.call(t.properties,\"mapbox_clip_start\")&&Object.prototype.hasOwnProperty.call(t.properties,\"mapbox_clip_end\"))return {start:+t.properties.mapbox_clip_start,end:+t.properties.mapbox_clip_end}}addFeature(t,e,r,n,i,s){const a=this.layers[0].layout,o=a.get(\"line-join\").evaluate(t,{}),l=a.get(\"line-cap\"),u=a.get(\"line-miter-limit\"),c=a.get(\"line-round-limit\");this.lineClips=this.lineFeatureClips(t);for(const r of e)this.addLine(r,t,o,l,u,c,n,s);this.programConfigurations.populatePaintArrays(this.layoutVertexArray.length,t,r,i,n);}addLine(t,e,r,n,i,s,a,o){if(this.distance=0,this.scaledDistance=0,this.totalDistance=0,t=Ql(t,a?o.line.getGranularityForZoomLevel(a.z):1),this.lineClips){this.lineClipsArray.push(this.lineClips);for(let e=0;e<t.length-1;e++)this.totalDistance+=t[e].dist(t[e+1]);this.updateScaledDistance(),this.maxLineLength=Math.max(this.maxLineLength,this.totalDistance);}const l=\"Polygon\"===Ou[e.type];let u=t.length;for(;u>=2&&t[u-1].equals(t[u-2]);)u--;let c=0;for(;c<u-1&&t[c].equals(t[c+1]);)c++;if(u<(l?3:2))return;\"bevel\"===r&&(i=1.05);const h=this.overscaling<=16?122880/(512*this.overscaling):0,p=this.segments.prepareSegment(10*u,this.layoutVertexArray,this.indexArray);let f,d,y,m,g;this.e1=this.e2=-1,l&&(f=t[u-2],g=t[c].sub(f)._unit()._perp());for(let e=c;e<u;e++){if(y=e===u-1?l?t[c+1]:void 0:t[e+1],y&&t[e].equals(y))continue;g&&(m=g),f&&(d=f),f=t[e],g=y?y.sub(f)._unit()._perp():m,m=m||g;let a=m.add(g);0===a.x&&0===a.y||a._unit();const o=m.x*g.x+m.y*g.y,x=a.x*g.x+a.y*g.y,v=0!==x?1/x:1/0,b=2*Math.sqrt(2-2*x),w=x<Ru&&d&&y,_=m.x*g.y-m.y*g.x>0;if(w&&e>c){const t=f.dist(d);if(t>2*h){const e=f.sub(f.sub(d)._mult(h/t)._round());this.updateDistance(d,e),this.addCurrentVertex(e,m,0,0,p),d=e;}}const S=d&&y;let A=S?r:l?\"butt\":n;if(S&&\"round\"===A&&(v<s?A=\"miter\":v<=2&&(A=\"fakeround\")),\"miter\"===A&&v>i&&(A=\"bevel\"),\"bevel\"===A&&(v>2&&(A=\"flipbevel\"),v<i&&(A=\"miter\")),d&&this.updateDistance(d,f),\"miter\"===A)a._mult(v),this.addCurrentVertex(f,a,0,0,p);else if(\"flipbevel\"===A){if(v>100)a=g.mult(-1);else {const t=v*m.add(g).mag()/m.sub(g).mag();a._perp()._mult(t*(_?-1:1));}this.addCurrentVertex(f,a,0,0,p),this.addCurrentVertex(f,a.mult(-1),0,0,p);}else if(\"bevel\"===A||\"fakeround\"===A){const t=-Math.sqrt(v*v-1),e=_?t:0,r=_?0:t;if(d&&this.addCurrentVertex(f,m,e,r,p),\"fakeround\"===A){const t=Math.round(180*b/Math.PI/20);for(let e=1;e<t;e++){let r=e/t;if(.5!==r){const t=r-.5;r+=r*t*(r-1)*((1.0904+o*(o*(3.55645-1.43519*o)-3.2452))*t*t+(.848013+o*(.215638*o-1.06021)));}const n=g.sub(m)._mult(r)._add(m)._unit()._mult(_?-1:1);this.addHalfVertex(f,n.x,n.y,!1,_,0,p);}}y&&this.addCurrentVertex(f,g,-e,-r,p);}else if(\"butt\"===A)this.addCurrentVertex(f,a,0,0,p);else if(\"square\"===A){const t=d?1:-1;this.addCurrentVertex(f,a,t,t,p);}else \"round\"===A&&(d&&(this.addCurrentVertex(f,m,0,0,p),this.addCurrentVertex(f,m,1,1,p,!0)),y&&(this.addCurrentVertex(f,g,-1,-1,p,!0),this.addCurrentVertex(f,g,0,0,p)));if(w&&e<u-1){const t=f.dist(y);if(t>2*h){const e=f.add(y.sub(f)._mult(h/t)._round());this.updateDistance(f,e),this.addCurrentVertex(e,g,0,0,p),f=e;}}}}addCurrentVertex(t,e,r,n,i,s=!1){const a=e.y*n-e.x,o=-e.y-e.x*n;this.addHalfVertex(t,e.x+e.y*r,e.y-e.x*r,s,!1,r,i),this.addHalfVertex(t,a,o,s,!0,-n,i),this.distance>ju/2&&0===this.totalDistance&&(this.distance=0,this.updateScaledDistance(),this.addCurrentVertex(t,e,r,n,i,s));}addHalfVertex({x:t,y:e},r,n,i,s,a,o){const l=.5*(this.lineClips?this.scaledDistance*(ju-1):this.scaledDistance);this.layoutVertexArray.emplaceBack((t<<1)+(i?1:0),(e<<1)+(s?1:0),Math.round(63*r)+128,Math.round(63*n)+128,1+(0===a?0:a<0?-1:1)|(63&l)<<2,l>>6),this.lineClips&&this.layoutVertexArray2.emplaceBack((this.scaledDistance-this.lineClips.start)/(this.lineClips.end-this.lineClips.start),this.lineClipsArray.length);const u=o.vertexLength++;this.e1>=0&&this.e2>=0&&(this.indexArray.emplaceBack(this.e1,u,this.e2),o.primitiveLength++),s?this.e2=u:this.e1=u;}updateScaledDistance(){this.scaledDistance=this.lineClips?this.lineClips.start+(this.lineClips.end-this.lineClips.start)*this.distance/this.totalDistance:this.distance;}updateDistance(t,e){this.distance+=t.dist(e),this.updateScaledDistance();}}let Uu,qu;us(\"LineBucket\",Nu,{omit:[\"layers\",\"patternFeatures\"]});var Gu={get paint(){return qu=qu||new qs({\"line-opacity\":new Rs(wt.paint_line[\"line-opacity\"]),\"line-color\":new Rs(wt.paint_line[\"line-color\"]),\"line-translate\":new Os(wt.paint_line[\"line-translate\"]),\"line-translate-anchor\":new Os(wt.paint_line[\"line-translate-anchor\"]),\"line-width\":new Rs(wt.paint_line[\"line-width\"]),\"line-gap-width\":new Rs(wt.paint_line[\"line-gap-width\"]),\"line-offset\":new Rs(wt.paint_line[\"line-offset\"]),\"line-blur\":new Rs(wt.paint_line[\"line-blur\"]),\"line-dasharray\":new Ns(wt.paint_line[\"line-dasharray\"]),\"line-pattern\":new js(wt.paint_line[\"line-pattern\"]),\"line-gradient\":new Us(wt.paint_line[\"line-gradient\"])})},get layout(){return Uu=Uu||new qs({\"line-cap\":new Os(wt.layout_line[\"line-cap\"]),\"line-join\":new Rs(wt.layout_line[\"line-join\"]),\"line-miter-limit\":new Os(wt.layout_line[\"line-miter-limit\"]),\"line-round-limit\":new Os(wt.layout_line[\"line-round-limit\"]),\"line-sort-key\":new Rs(wt.layout_line[\"line-sort-key\"])})}};class Xu extends Rs{possiblyEvaluate(t,e){return e=new Cs(Math.floor(e.zoom),{now:e.now,fadeDuration:e.fadeDuration,zoomHistory:e.zoomHistory,transition:e.transition}),super.possiblyEvaluate(t,e)}evaluate(t,e,r,n){return e=j({},e,{zoom:Math.floor(e.zoom)}),super.evaluate(t,e,r,n)}}let Zu;class Yu extends Xs{constructor(t){super(t,Gu),this.gradientVersion=0,Zu||(Zu=new Xu(Gu.paint.properties[\"line-width\"].specification),Zu.useIntegerZoom=!0);}_handleSpecialPaintPropertyUpdate(t){if(\"line-gradient\"===t){const t=this.gradientExpression();this.stepInterpolant=!!function(t){return void 0!==t._styleExpression}(t)&&t._styleExpression.expression instanceof ur,this.gradientVersion=(this.gradientVersion+1)%Number.MAX_SAFE_INTEGER;}}gradientExpression(){return this._transitionablePaint._values[\"line-gradient\"].value.expression}recalculate(t,e){super.recalculate(t,e),this.paint._values[\"line-floorwidth\"]=Zu.possiblyEvaluate(this._transitioningPaint._values[\"line-width\"].value,t);}createBucket(t){return new Nu(t)}queryRadius(t){const e=t,r=Hu(qo(\"line-width\",this,e),qo(\"line-gap-width\",this,e)),n=qo(\"line-offset\",this,e);return r/2+Math.abs(n)+Go(this.paint.get(\"line-translate\"))}queryIntersectsFeature({queryGeometry:t,feature:e,featureState:r,geometry:n,transform:i,pixelsToTileUnits:s}){const a=Xo(t,this.paint.get(\"line-translate\"),this.paint.get(\"line-translate-anchor\"),-i.bearingInRadians,s),o=s/2*Hu(this.paint.get(\"line-width\").evaluate(e,r),this.paint.get(\"line-gap-width\").evaluate(e,r)),u=this.paint.get(\"line-offset\").evaluate(e,r);return u&&(n=function(t,e){const r=[];for(let n=0;n<t.length;n++){const i=t[n],s=[];for(let t=0;t<i.length;t++){const r=i[t-1],n=i[t],a=i[t+1],o=0===t?new l(0,0):n.sub(r)._unit()._perp(),u=t===i.length-1?new l(0,0):a.sub(n)._unit()._perp(),c=o._add(u)._unit(),h=c.x*u.x+c.y*u.y;0!==h&&c._mult(1/h),s.push(c._mult(e)._add(n));}r.push(s);}return r}(n,u*s)),function(t,e,r){for(let n=0;n<e.length;n++){const i=e[n];if(t.length>=3)for(let e=0;e<i.length;e++)if(No(t,i[e]))return !0;if(Lo(t,i,r))return !0}return !1}(a,n,o)}isTileClipped(){return !0}}function Hu(t,e){return e>0?e+2*t:t}const Ku=Ks([{name:\"a_pos_offset\",components:4,type:\"Int16\"},{name:\"a_data\",components:4,type:\"Uint16\"},{name:\"a_pixeloffset\",components:4,type:\"Int16\"}],4),Ju=Ks([{name:\"a_projected_pos\",components:3,type:\"Float32\"}],4);Ks([{name:\"a_fade_opacity\",components:1,type:\"Uint32\"}],4);const Wu=Ks([{name:\"a_placed\",components:2,type:\"Uint8\"},{name:\"a_shift\",components:2,type:\"Float32\"},{name:\"a_box_real\",components:2,type:\"Int16\"}]);Ks([{type:\"Int16\",name:\"anchorPointX\"},{type:\"Int16\",name:\"anchorPointY\"},{type:\"Int16\",name:\"x1\"},{type:\"Int16\",name:\"y1\"},{type:\"Int16\",name:\"x2\"},{type:\"Int16\",name:\"y2\"},{type:\"Uint32\",name:\"featureIndex\"},{type:\"Uint16\",name:\"sourceLayerIndex\"},{type:\"Uint16\",name:\"bucketIndex\"}]);const Qu=Ks([{name:\"a_pos\",components:2,type:\"Int16\"},{name:\"a_anchor_pos\",components:2,type:\"Int16\"},{name:\"a_extrude\",components:2,type:\"Int16\"}],4),tc=Ks([{name:\"a_pos\",components:2,type:\"Float32\"},{name:\"a_radius\",components:1,type:\"Float32\"},{name:\"a_flags\",components:2,type:\"Int16\"}],4);function ec(t,e,r){return t.sections.forEach((t=>{t.text=function(t,e,r){const n=e.layout.get(\"text-transform\").evaluate(r,{});return \"uppercase\"===n?t=t.toLocaleUpperCase():\"lowercase\"===n&&(t=t.toLocaleLowerCase()),Ps.applyArabicShaping&&(t=Ps.applyArabicShaping(t)),t}(t.text,e,r);})),t}Ks([{name:\"triangle\",components:3,type:\"Uint16\"}]),Ks([{type:\"Int16\",name:\"anchorX\"},{type:\"Int16\",name:\"anchorY\"},{type:\"Uint16\",name:\"glyphStartIndex\"},{type:\"Uint16\",name:\"numGlyphs\"},{type:\"Uint32\",name:\"vertexStartIndex\"},{type:\"Uint32\",name:\"lineStartIndex\"},{type:\"Uint32\",name:\"lineLength\"},{type:\"Uint16\",name:\"segment\"},{type:\"Uint16\",name:\"lowerSize\"},{type:\"Uint16\",name:\"upperSize\"},{type:\"Float32\",name:\"lineOffsetX\"},{type:\"Float32\",name:\"lineOffsetY\"},{type:\"Uint8\",name:\"writingMode\"},{type:\"Uint8\",name:\"placedOrientation\"},{type:\"Uint8\",name:\"hidden\"},{type:\"Uint32\",name:\"crossTileID\"},{type:\"Int16\",name:\"associatedIconIndex\"}]),Ks([{type:\"Int16\",name:\"anchorX\"},{type:\"Int16\",name:\"anchorY\"},{type:\"Int16\",name:\"rightJustifiedTextSymbolIndex\"},{type:\"Int16\",name:\"centerJustifiedTextSymbolIndex\"},{type:\"Int16\",name:\"leftJustifiedTextSymbolIndex\"},{type:\"Int16\",name:\"verticalPlacedTextSymbolIndex\"},{type:\"Int16\",name:\"placedIconSymbolIndex\"},{type:\"Int16\",name:\"verticalPlacedIconSymbolIndex\"},{type:\"Uint16\",name:\"key\"},{type:\"Uint16\",name:\"textBoxStartIndex\"},{type:\"Uint16\",name:\"textBoxEndIndex\"},{type:\"Uint16\",name:\"verticalTextBoxStartIndex\"},{type:\"Uint16\",name:\"verticalTextBoxEndIndex\"},{type:\"Uint16\",name:\"iconBoxStartIndex\"},{type:\"Uint16\",name:\"iconBoxEndIndex\"},{type:\"Uint16\",name:\"verticalIconBoxStartIndex\"},{type:\"Uint16\",name:\"verticalIconBoxEndIndex\"},{type:\"Uint16\",name:\"featureIndex\"},{type:\"Uint16\",name:\"numHorizontalGlyphVertices\"},{type:\"Uint16\",name:\"numVerticalGlyphVertices\"},{type:\"Uint16\",name:\"numIconVertices\"},{type:\"Uint16\",name:\"numVerticalIconVertices\"},{type:\"Uint16\",name:\"useRuntimeCollisionCircles\"},{type:\"Uint32\",name:\"crossTileID\"},{type:\"Float32\",name:\"textBoxScale\"},{type:\"Float32\",name:\"collisionCircleDiameter\"},{type:\"Uint16\",name:\"textAnchorOffsetStartIndex\"},{type:\"Uint16\",name:\"textAnchorOffsetEndIndex\"}]),Ks([{type:\"Float32\",name:\"offsetX\"}]),Ks([{type:\"Int16\",name:\"x\"},{type:\"Int16\",name:\"y\"},{type:\"Int16\",name:\"tileUnitDistanceFromAnchor\"}]),Ks([{type:\"Uint16\",name:\"textAnchor\"},{type:\"Float32\",components:2,name:\"textOffset\"}]);const rc={\"!\":\"︕\",\"#\":\"＃\",$:\"＄\",\"%\":\"％\",\"&\":\"＆\",\"(\":\"︵\",\")\":\"︶\",\"*\":\"＊\",\"+\":\"＋\",\",\":\"︐\",\"-\":\"︲\",\".\":\"・\",\"/\":\"／\",\":\":\"︓\",\";\":\"︔\",\"<\":\"︿\",\"=\":\"＝\",\">\":\"﹀\",\"?\":\"︖\",\"@\":\"＠\",\"[\":\"﹇\",\"\\\\\":\"＼\",\"]\":\"﹈\",\"^\":\"＾\",_:\"︳\",\"`\":\"｀\",\"{\":\"︷\",\"|\":\"―\",\"}\":\"︸\",\"~\":\"～\",\"¢\":\"￠\",\"£\":\"￡\",\"¥\":\"￥\",\"¦\":\"￤\",\"¬\":\"￢\",\"¯\":\"￣\",\"–\":\"︲\",\"—\":\"︱\",\"‘\":\"﹃\",\"’\":\"﹄\",\"“\":\"﹁\",\"”\":\"﹂\",\"…\":\"︙\",\"‧\":\"・\",\"₩\":\"￦\",\"、\":\"︑\",\"。\":\"︒\",\"〈\":\"︿\",\"〉\":\"﹀\",\"《\":\"︽\",\"》\":\"︾\",\"「\":\"﹁\",\"」\":\"﹂\",\"『\":\"﹃\",\"』\":\"﹄\",\"【\":\"︻\",\"】\":\"︼\",\"〔\":\"︹\",\"〕\":\"︺\",\"〖\":\"︗\",\"〗\":\"︘\",\"！\":\"︕\",\"（\":\"︵\",\"）\":\"︶\",\"，\":\"︐\",\"－\":\"︲\",\"．\":\"・\",\"：\":\"︓\",\"；\":\"︔\",\"＜\":\"︿\",\"＞\":\"﹀\",\"？\":\"︖\",\"［\":\"﹇\",\"］\":\"﹈\",\"＿\":\"︳\",\"｛\":\"︷\",\"｜\":\"―\",\"｝\":\"︸\",\"｟\":\"︵\",\"｠\":\"︶\",\"｡\":\"︒\",\"｢\":\"﹁\",\"｣\":\"﹂\"};var nc,ic,sc,ac=24,oc={};function lc(){return nc||(nc=1,oc.read=function(t,e,r,n,i){var s,a,o=8*i-n-1,l=(1<<o)-1,u=l>>1,c=-7,h=r?i-1:0,p=r?-1:1,f=t[e+h];for(h+=p,s=f&(1<<-c)-1,f>>=-c,c+=o;c>0;s=256*s+t[e+h],h+=p,c-=8);for(a=s&(1<<-c)-1,s>>=-c,c+=n;c>0;a=256*a+t[e+h],h+=p,c-=8);if(0===s)s=1-u;else {if(s===l)return a?NaN:1/0*(f?-1:1);a+=Math.pow(2,n),s-=u;}return (f?-1:1)*a*Math.pow(2,s-n)},oc.write=function(t,e,r,n,i,s){var a,o,l,u=8*s-i-1,c=(1<<u)-1,h=c>>1,p=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,f=n?0:s-1,d=n?1:-1,y=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(o=isNaN(e)?1:0,a=c):(a=Math.floor(Math.log(e)/Math.LN2),e*(l=Math.pow(2,-a))<1&&(a--,l*=2),(e+=a+h>=1?p/l:p*Math.pow(2,1-h))*l>=2&&(a++,l/=2),a+h>=c?(o=0,a=c):a+h>=1?(o=(e*l-1)*Math.pow(2,i),a+=h):(o=e*Math.pow(2,h-1)*Math.pow(2,i),a=0));i>=8;t[r+f]=255&o,f+=d,o/=256,i-=8);for(a=a<<i|o,u+=i;u>0;t[r+f]=255&a,f+=d,a/=256,u-=8);t[r+f-d]|=128*y;}),oc}function uc(){if(sc)return ic;sc=1,ic=e;var t=lc();function e(t){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(t)?t:new Uint8Array(t||0),this.pos=0,this.type=0,this.length=this.buf.length;}e.Varint=0,e.Fixed64=1,e.Bytes=2,e.Fixed32=5;var r=4294967296,n=1/r,i=\"undefined\"==typeof TextDecoder?null:new TextDecoder(\"utf-8\");function s(t){return t.type===e.Bytes?t.readVarint()+t.pos:t.pos+1}function a(t,e,r){return r?4294967296*e+(t>>>0):4294967296*(e>>>0)+(t>>>0)}function o(t,e,r){var n=e<=16383?1:e<=2097151?2:e<=268435455?3:Math.floor(Math.log(e)/(7*Math.LN2));r.realloc(n);for(var i=r.pos-1;i>=t;i--)r.buf[i+n]=r.buf[i];}function l(t,e){for(var r=0;r<t.length;r++)e.writeVarint(t[r]);}function u(t,e){for(var r=0;r<t.length;r++)e.writeSVarint(t[r]);}function c(t,e){for(var r=0;r<t.length;r++)e.writeFloat(t[r]);}function h(t,e){for(var r=0;r<t.length;r++)e.writeDouble(t[r]);}function p(t,e){for(var r=0;r<t.length;r++)e.writeBoolean(t[r]);}function f(t,e){for(var r=0;r<t.length;r++)e.writeFixed32(t[r]);}function d(t,e){for(var r=0;r<t.length;r++)e.writeSFixed32(t[r]);}function y(t,e){for(var r=0;r<t.length;r++)e.writeFixed64(t[r]);}function m(t,e){for(var r=0;r<t.length;r++)e.writeSFixed64(t[r]);}function g(t,e){return (t[e]|t[e+1]<<8|t[e+2]<<16)+16777216*t[e+3]}function x(t,e,r){t[r]=e,t[r+1]=e>>>8,t[r+2]=e>>>16,t[r+3]=e>>>24;}function v(t,e){return (t[e]|t[e+1]<<8|t[e+2]<<16)+(t[e+3]<<24)}return e.prototype={destroy:function(){this.buf=null;},readFields:function(t,e,r){for(r=r||this.length;this.pos<r;){var n=this.readVarint(),i=n>>3,s=this.pos;this.type=7&n,t(i,e,this),this.pos===s&&this.skip(n);}return e},readMessage:function(t,e){return this.readFields(t,e,this.readVarint()+this.pos)},readFixed32:function(){var t=g(this.buf,this.pos);return this.pos+=4,t},readSFixed32:function(){var t=v(this.buf,this.pos);return this.pos+=4,t},readFixed64:function(){var t=g(this.buf,this.pos)+g(this.buf,this.pos+4)*r;return this.pos+=8,t},readSFixed64:function(){var t=g(this.buf,this.pos)+v(this.buf,this.pos+4)*r;return this.pos+=8,t},readFloat:function(){var e=t.read(this.buf,this.pos,!0,23,4);return this.pos+=4,e},readDouble:function(){var e=t.read(this.buf,this.pos,!0,52,8);return this.pos+=8,e},readVarint:function(t){var e,r,n=this.buf;return e=127&(r=n[this.pos++]),r<128?e:(e|=(127&(r=n[this.pos++]))<<7,r<128?e:(e|=(127&(r=n[this.pos++]))<<14,r<128?e:(e|=(127&(r=n[this.pos++]))<<21,r<128?e:function(t,e,r){var n,i,s=r.buf;if(n=(112&(i=s[r.pos++]))>>4,i<128)return a(t,n,e);if(n|=(127&(i=s[r.pos++]))<<3,i<128)return a(t,n,e);if(n|=(127&(i=s[r.pos++]))<<10,i<128)return a(t,n,e);if(n|=(127&(i=s[r.pos++]))<<17,i<128)return a(t,n,e);if(n|=(127&(i=s[r.pos++]))<<24,i<128)return a(t,n,e);if(n|=(1&(i=s[r.pos++]))<<31,i<128)return a(t,n,e);throw new Error(\"Expected varint not more than 10 bytes\")}(e|=(15&(r=n[this.pos]))<<28,t,this))))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var t=this.readVarint();return t%2==1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,e=this.pos;return this.pos=t,t-e>=12&&i?function(t,e,r){return i.decode(t.subarray(e,r))}(this.buf,e,t):function(t,e,r){for(var n=\"\",i=e;i<r;){var s,a,o,l=t[i],u=null,c=l>239?4:l>223?3:l>191?2:1;if(i+c>r)break;1===c?l<128&&(u=l):2===c?128==(192&(s=t[i+1]))&&(u=(31&l)<<6|63&s)<=127&&(u=null):3===c?(a=t[i+2],128==(192&(s=t[i+1]))&&128==(192&a)&&((u=(15&l)<<12|(63&s)<<6|63&a)<=2047||u>=55296&&u<=57343)&&(u=null)):4===c&&(a=t[i+2],o=t[i+3],128==(192&(s=t[i+1]))&&128==(192&a)&&128==(192&o)&&((u=(15&l)<<18|(63&s)<<12|(63&a)<<6|63&o)<=65535||u>=1114112)&&(u=null)),null===u?(u=65533,c=1):u>65535&&(u-=65536,n+=String.fromCharCode(u>>>10&1023|55296),u=56320|1023&u),n+=String.fromCharCode(u),i+=c;}return n}(this.buf,e,t)},readBytes:function(){var t=this.readVarint()+this.pos,e=this.buf.subarray(this.pos,t);return this.pos=t,e},readPackedVarint:function(t,r){if(this.type!==e.Bytes)return t.push(this.readVarint(r));var n=s(this);for(t=t||[];this.pos<n;)t.push(this.readVarint(r));return t},readPackedSVarint:function(t){if(this.type!==e.Bytes)return t.push(this.readSVarint());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readSVarint());return t},readPackedBoolean:function(t){if(this.type!==e.Bytes)return t.push(this.readBoolean());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readBoolean());return t},readPackedFloat:function(t){if(this.type!==e.Bytes)return t.push(this.readFloat());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readFloat());return t},readPackedDouble:function(t){if(this.type!==e.Bytes)return t.push(this.readDouble());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readDouble());return t},readPackedFixed32:function(t){if(this.type!==e.Bytes)return t.push(this.readFixed32());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readFixed32());return t},readPackedSFixed32:function(t){if(this.type!==e.Bytes)return t.push(this.readSFixed32());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readSFixed32());return t},readPackedFixed64:function(t){if(this.type!==e.Bytes)return t.push(this.readFixed64());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readFixed64());return t},readPackedSFixed64:function(t){if(this.type!==e.Bytes)return t.push(this.readSFixed64());var r=s(this);for(t=t||[];this.pos<r;)t.push(this.readSFixed64());return t},skip:function(t){var r=7&t;if(r===e.Varint)for(;this.buf[this.pos++]>127;);else if(r===e.Bytes)this.pos=this.readVarint()+this.pos;else if(r===e.Fixed32)this.pos+=4;else {if(r!==e.Fixed64)throw new Error(\"Unimplemented type: \"+r);this.pos+=8;}},writeTag:function(t,e){this.writeVarint(t<<3|e);},realloc:function(t){for(var e=this.length||16;e<this.pos+t;)e*=2;if(e!==this.length){var r=new Uint8Array(e);r.set(this.buf),this.buf=r,this.length=e;}},finish:function(){return this.length=this.pos,this.pos=0,this.buf.subarray(0,this.length)},writeFixed32:function(t){this.realloc(4),x(this.buf,t,this.pos),this.pos+=4;},writeSFixed32:function(t){this.realloc(4),x(this.buf,t,this.pos),this.pos+=4;},writeFixed64:function(t){this.realloc(8),x(this.buf,-1&t,this.pos),x(this.buf,Math.floor(t*n),this.pos+4),this.pos+=8;},writeSFixed64:function(t){this.realloc(8),x(this.buf,-1&t,this.pos),x(this.buf,Math.floor(t*n),this.pos+4),this.pos+=8;},writeVarint:function(t){(t=+t||0)>268435455||t<0?function(t,e){var r,n;if(t>=0?(r=t%4294967296|0,n=t/4294967296|0):(n=~(-t/4294967296),4294967295^(r=~(-t%4294967296))?r=r+1|0:(r=0,n=n+1|0)),t>=0x10000000000000000||t<-0x10000000000000000)throw new Error(\"Given varint doesn't fit into 10 bytes\");e.realloc(10),function(t,e,r){r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,t>>>=7,r.buf[r.pos++]=127&t|128,r.buf[r.pos]=127&(t>>>=7);}(r,0,e),function(t,e){var r=(7&t)<<4;e.buf[e.pos++]|=r|((t>>>=3)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t|((t>>>=7)?128:0),t&&(e.buf[e.pos++]=127&t)))));}(n,e);}(t,this):(this.realloc(4),this.buf[this.pos++]=127&t|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=127&(t>>>=7)|(t>127?128:0),t<=127||(this.buf[this.pos++]=t>>>7&127))));},writeSVarint:function(t){this.writeVarint(t<0?2*-t-1:2*t);},writeBoolean:function(t){this.writeVarint(Boolean(t));},writeString:function(t){t=String(t),this.realloc(4*t.length),this.pos++;var e=this.pos;this.pos=function(t,e,r){for(var n,i,s=0;s<e.length;s++){if((n=e.charCodeAt(s))>55295&&n<57344){if(!i){n>56319||s+1===e.length?(t[r++]=239,t[r++]=191,t[r++]=189):i=n;continue}if(n<56320){t[r++]=239,t[r++]=191,t[r++]=189,i=n;continue}n=i-55296<<10|n-56320|65536,i=null;}else i&&(t[r++]=239,t[r++]=191,t[r++]=189,i=null);n<128?t[r++]=n:(n<2048?t[r++]=n>>6|192:(n<65536?t[r++]=n>>12|224:(t[r++]=n>>18|240,t[r++]=n>>12&63|128),t[r++]=n>>6&63|128),t[r++]=63&n|128);}return r}(this.buf,t,this.pos);var r=this.pos-e;r>=128&&o(e,r,this),this.pos=e-1,this.writeVarint(r),this.pos+=r;},writeFloat:function(e){this.realloc(4),t.write(this.buf,e,this.pos,!0,23,4),this.pos+=4;},writeDouble:function(e){this.realloc(8),t.write(this.buf,e,this.pos,!0,52,8),this.pos+=8;},writeBytes:function(t){var e=t.length;this.writeVarint(e),this.realloc(e);for(var r=0;r<e;r++)this.buf[this.pos++]=t[r];},writeRawMessage:function(t,e){this.pos++;var r=this.pos;t(e,this);var n=this.pos-r;n>=128&&o(r,n,this),this.pos=r-1,this.writeVarint(n),this.pos+=n;},writeMessage:function(t,r,n){this.writeTag(t,e.Bytes),this.writeRawMessage(r,n);},writePackedVarint:function(t,e){e.length&&this.writeMessage(t,l,e);},writePackedSVarint:function(t,e){e.length&&this.writeMessage(t,u,e);},writePackedBoolean:function(t,e){e.length&&this.writeMessage(t,p,e);},writePackedFloat:function(t,e){e.length&&this.writeMessage(t,c,e);},writePackedDouble:function(t,e){e.length&&this.writeMessage(t,h,e);},writePackedFixed32:function(t,e){e.length&&this.writeMessage(t,f,e);},writePackedSFixed32:function(t,e){e.length&&this.writeMessage(t,d,e);},writePackedFixed64:function(t,e){e.length&&this.writeMessage(t,y,e);},writePackedSFixed64:function(t,e){e.length&&this.writeMessage(t,m,e);},writeBytesField:function(t,r){this.writeTag(t,e.Bytes),this.writeBytes(r);},writeFixed32Field:function(t,r){this.writeTag(t,e.Fixed32),this.writeFixed32(r);},writeSFixed32Field:function(t,r){this.writeTag(t,e.Fixed32),this.writeSFixed32(r);},writeFixed64Field:function(t,r){this.writeTag(t,e.Fixed64),this.writeFixed64(r);},writeSFixed64Field:function(t,r){this.writeTag(t,e.Fixed64),this.writeSFixed64(r);},writeVarintField:function(t,r){this.writeTag(t,e.Varint),this.writeVarint(r);},writeSVarintField:function(t,r){this.writeTag(t,e.Varint),this.writeSVarint(r);},writeStringField:function(t,r){this.writeTag(t,e.Bytes),this.writeString(r);},writeFloatField:function(t,r){this.writeTag(t,e.Fixed32),this.writeFloat(r);},writeDoubleField:function(t,r){this.writeTag(t,e.Fixed64),this.writeDouble(r);},writeBooleanField:function(t,e){this.writeVarintField(t,Boolean(e));}},ic}var cc,hc=r(uc());function pc(t,e,r){1===t&&r.readMessage(fc,e);}function fc(t,e,r){if(3===t){const{id:t,bitmap:n,width:i,height:s,left:a,top:o,advance:l}=r.readMessage(dc,{});e.push({id:t,bitmap:new il({width:i+6,height:s+6},n),metrics:{width:i,height:s,left:a,top:o,advance:l}});}}function dc(t,e,r){1===t?e.id=r.readVarint():2===t?e.bitmap=r.readBytes():3===t?e.width=r.readVarint():4===t?e.height=r.readVarint():5===t?e.left=r.readSVarint():6===t?e.top=r.readSVarint():7===t&&(e.advance=r.readVarint());}function yc(t){let e=0,r=0;for(const n of t)e+=n.w*n.h,r=Math.max(r,n.w);t.sort(((t,e)=>e.h-t.h));const n=[{x:0,y:0,w:Math.max(Math.ceil(Math.sqrt(e/.95)),r),h:1/0}];let i=0,s=0;for(const e of t)for(let t=n.length-1;t>=0;t--){const r=n[t];if(!(e.w>r.w||e.h>r.h)){if(e.x=r.x,e.y=r.y,s=Math.max(s,e.y+e.h),i=Math.max(i,e.x+e.w),e.w===r.w&&e.h===r.h){const e=n.pop();t<n.length&&(n[t]=e);}else e.h===r.h?(r.x+=e.w,r.w-=e.w):e.w===r.w?(r.y+=e.h,r.h-=e.h):(n.push({x:r.x+e.w,y:r.y,w:r.w-e.w,h:e.h}),r.y+=e.h,r.h-=e.h);break}}return {w:i,h:s,fill:e/(i*s)||0}}class mc{constructor(t,{pixelRatio:e,version:r,stretchX:n,stretchY:i,content:s,textFitWidth:a,textFitHeight:o}){this.paddedRect=t,this.pixelRatio=e,this.stretchX=n,this.stretchY=i,this.content=s,this.version=r,this.textFitWidth=a,this.textFitHeight=o;}get tl(){return [this.paddedRect.x+1,this.paddedRect.y+1]}get br(){return [this.paddedRect.x+this.paddedRect.w-1,this.paddedRect.y+this.paddedRect.h-1]}get tlbr(){return this.tl.concat(this.br)}get displaySize(){return [(this.paddedRect.w-2)/this.pixelRatio,(this.paddedRect.h-2)/this.pixelRatio]}}class gc{constructor(t,e){const r={},n={};this.haveRenderCallbacks=[];const i=[];this.addImages(t,r,i),this.addImages(e,n,i);const{w:s,h:a}=yc(i),o=new sl({width:s||1,height:a||1});for(const e in t){const n=t[e],i=r[e].paddedRect;sl.copy(n.data,o,{x:0,y:0},{x:i.x+1,y:i.y+1},n.data);}for(const t in e){const r=e[t],i=n[t].paddedRect,s=i.x+1,a=i.y+1,l=r.data.width,u=r.data.height;sl.copy(r.data,o,{x:0,y:0},{x:s,y:a},r.data),sl.copy(r.data,o,{x:0,y:u-1},{x:s,y:a-1},{width:l,height:1}),sl.copy(r.data,o,{x:0,y:0},{x:s,y:a+u},{width:l,height:1}),sl.copy(r.data,o,{x:l-1,y:0},{x:s-1,y:a},{width:1,height:u}),sl.copy(r.data,o,{x:0,y:0},{x:s+l,y:a},{width:1,height:u});}this.image=o,this.iconPositions=r,this.patternPositions=n;}addImages(t,e,r){for(const n in t){const i=t[n],s={x:0,y:0,w:i.data.width+2,h:i.data.height+2};r.push(s),e[n]=new mc(s,i),i.hasRenderCallback&&this.haveRenderCallbacks.push(n);}}patchUpdatedImages(t,e){t.dispatchRenderCallbacks(this.haveRenderCallbacks);for(const r in t.updatedImages)this.patchUpdatedImage(this.iconPositions[r],t.getImage(r),e),this.patchUpdatedImage(this.patternPositions[r],t.getImage(r),e);}patchUpdatedImage(t,e,r){if(!t||!e)return;if(t.version===e.version)return;t.version=e.version;const[n,i]=t.tl;r.update(e.data,void 0,{x:n,y:i});}}us(\"ImagePosition\",mc),us(\"ImageAtlas\",gc),t.an=void 0,(cc=t.an||(t.an={}))[cc.none=0]=\"none\",cc[cc.horizontal=1]=\"horizontal\",cc[cc.vertical=2]=\"vertical\",cc[cc.horizontalOnly=3]=\"horizontalOnly\";class xc{constructor(){this.scale=1,this.fontStack=\"\",this.imageName=null,this.verticalAlign=\"bottom\";}static forText(t,e,r){const n=new xc;return n.scale=t||1,n.fontStack=e,n.verticalAlign=r||\"bottom\",n}static forImage(t,e){const r=new xc;return r.imageName=t,r.verticalAlign=e||\"bottom\",r}}class vc{constructor(){this.text=\"\",this.sectionIndex=[],this.sections=[],this.imageSectionID=null;}static fromFeature(t,e){const r=new vc;for(let n=0;n<t.sections.length;n++){const i=t.sections[n];i.image?r.addImageSection(i):r.addTextSection(i,e);}return r}length(){return this.text.length}getSection(t){return this.sections[this.sectionIndex[t]]}getSectionIndex(t){return this.sectionIndex[t]}getCharCode(t){return this.text.charCodeAt(t)}verticalizePunctuation(){this.text=function(t){let e=\"\";for(let r=0;r<t.length;r++){const n=t.charCodeAt(r+1)||null,i=t.charCodeAt(r-1)||null;e+=n&&As(n)&&!rc[t[r+1]]||i&&As(i)&&!rc[t[r-1]]||!rc[t[r]]?t[r]:rc[t[r]];}return e}(this.text);}trim(){let t=0;for(let e=0;e<this.text.length&&wc[this.text.charCodeAt(e)];e++)t++;let e=this.text.length;for(let r=this.text.length-1;r>=0&&r>=t&&wc[this.text.charCodeAt(r)];r--)e--;this.text=this.text.substring(t,e),this.sectionIndex=this.sectionIndex.slice(t,e);}substring(t,e){const r=new vc;return r.text=this.text.substring(t,e),r.sectionIndex=this.sectionIndex.slice(t,e),r.sections=this.sections,r}toString(){return this.text}getMaxScale(){return this.sectionIndex.reduce(((t,e)=>Math.max(t,this.sections[e].scale)),0)}getMaxImageSize(t){let e=0,r=0;for(let n=0;n<this.length();n++){const i=this.getSection(n);if(i.imageName){const n=t[i.imageName];if(!n)continue;const s=n.displaySize;e=Math.max(e,s[0]),r=Math.max(r,s[1]);}}return {maxImageWidth:e,maxImageHeight:r}}addTextSection(t,e){this.text+=t.text,this.sections.push(xc.forText(t.scale,t.fontStack||e,t.verticalAlign));const r=this.sections.length-1;for(let e=0;e<t.text.length;++e)this.sectionIndex.push(r);}addImageSection(t){const e=t.image?t.image.name:\"\";if(0===e.length)return void Z(\"Can't add FormattedSection with an empty image.\");const r=this.getNextImageSectionCharCode();r?(this.text+=String.fromCharCode(r),this.sections.push(xc.forImage(e,t.verticalAlign)),this.sectionIndex.push(this.sections.length-1)):Z(\"Reached maximum number of images 6401\");}getNextImageSectionCharCode(){return this.imageSectionID?this.imageSectionID>=63743?null:++this.imageSectionID:(this.imageSectionID=57344,this.imageSectionID)}}function bc(e,r,n,i,s,a,o,l,u,c,h,p,f,d,y){const m=vc.fromFeature(e,s);let g;p===t.an.vertical&&m.verticalizePunctuation();const{processBidirectionalText:x,processStyledBidirectionalText:v}=Ps;if(x&&1===m.sections.length){g=[];const t=x(m.toString(),Pc(m,c,a,r,i,d));for(const e of t){const t=new vc;t.text=e,t.sections=m.sections;for(let r=0;r<e.length;r++)t.sectionIndex.push(0);g.push(t);}}else if(v){g=[];const t=v(m.text,m.sectionIndex,Pc(m,c,a,r,i,d));for(const e of t){const t=new vc;t.text=e[0],t.sectionIndex=e[1],t.sections=m.sections,g.push(t);}}else g=function(t,e){const r=[],n=t.text;let i=0;for(const n of e)r.push(t.substring(i,n)),i=n;return i<n.length&&r.push(t.substring(i,n.length)),r}(m,Pc(m,c,a,r,i,d));const b=[],w={positionedLines:b,text:m.toString(),top:h[1],bottom:h[1],left:h[0],right:h[0],writingMode:p,iconsInText:!1,verticalizable:!1};return function(t,e,r,n,i,s,a,o,l,u,c,h){let p=0,f=0,d=0,y=0;const m=\"right\"===o?1:\"left\"===o?0:.5,g=ac/h;let x=0;for(const a of i){a.trim();const i=a.getMaxScale(),o={positionedGlyphs:[],lineOffset:0};t.positionedLines[x]=o;const h=o.positionedGlyphs;let v=0;if(!a.length()){f+=s,++x;continue}const b=Bc(n,a,g);for(let s=0;s<a.length();s++){const o=a.getSection(s),d=a.getSectionIndex(s),y=a.getCharCode(s),m=Tc(l,c,y);let x;if(o.imageName){if(t.iconsInText=!0,o.scale=o.scale*g,x=Fc(o,m,i,b,n),!x)continue;v=Math.max(v,x.imageOffset);}else if(x=Vc(o,y,m,b,e,r),!x)continue;const{rect:w,metrics:_,baselineOffset:S}=x;h.push({glyph:y,imageName:o.imageName,x:p,y:f+S+-17,vertical:m,scale:o.scale,fontStack:o.fontStack,sectionIndex:d,metrics:_,rect:w}),m?(t.verticalizable=!0,p+=(o.imageName?_.advance:ac)*o.scale+u):p+=_.advance*o.scale+u;}0!==h.length&&(d=Math.max(p-u,d),Lc(h,0,h.length-1,m)),p=0,o.lineOffset=Math.max(v,(i-1)*ac);const w=s*i+v;f+=w,y=Math.max(w,y),++x;}const{horizontalAlign:v,verticalAlign:b}=Cc(a);((function(t,e,r,n,i,s,a,o,l){const u=(e-r)*i;let c=0;c=s!==a?-o*n- -17:-n*l*a+.5*a;for(const e of t)for(const t of e.positionedGlyphs)t.x+=u,t.y+=c;}))(t.positionedLines,m,v,b,d,y,s,f,i.length),t.top+=-b*f,t.bottom=t.top+f,t.left+=-v*d,t.right=t.left+d;}(w,r,n,i,g,o,l,u,p,c,f,y),!function(t){for(const e of t)if(0!==e.positionedGlyphs.length)return !1;return !0}(b)&&w}const wc={9:!0,10:!0,11:!0,12:!0,13:!0,32:!0},_c={10:!0,32:!0,38:!0,41:!0,43:!0,45:!0,47:!0,173:!0,183:!0,8203:!0,8208:!0,8211:!0,8231:!0},Sc={40:!0};function Ac(t,e,r,n,i,s){if(e.imageName){const t=n[e.imageName];return t?t.displaySize[0]*e.scale*ac/s+i:0}{const n=r[e.fontStack],s=n&&n[t];return s?s.metrics.advance*e.scale+i:0}}function kc(t,e,r,n){const i=Math.pow(t-e,2);return n?t<e?i/2:2*i:i+Math.abs(r)*r}function Mc(t,e,r){let n=0;return 10===t&&(n-=1e4),r&&(n+=150),40!==t&&65288!==t||(n+=50),41!==e&&65289!==e||(n+=50),n}function Ic(t,e,r,n,i,s){let a=null,o=kc(e,r,i,s);for(const t of n){const n=kc(e-t.x,r,i,s)+t.badness;n<=o&&(a=t,o=n);}return {index:t,x:e,priorBreak:a,badness:o}}function zc(t){return t?zc(t.priorBreak).concat(t.index):[]}function Pc(t,e,r,n,i,s){if(!t)return [];const a=[],o=function(t,e,r,n,i,s){let a=0;for(let r=0;r<t.length();r++){const o=t.getSection(r);a+=Ac(t.getCharCode(r),o,n,i,e,s);}return a/Math.max(1,Math.ceil(a/r))}(t,e,r,n,i,s),l=t.text.indexOf(\"​\")>=0;let u=0;for(let r=0;r<t.length();r++){const h=t.getSection(r),p=t.getCharCode(r);if(wc[p]||(u+=Ac(p,h,n,i,e,s)),r<t.length()-1){const e=!((c=p)<11904)&&(!!ms[\"CJK Compatibility Forms\"](c)||!!ms[\"CJK Compatibility\"](c)||!!ms[\"CJK Strokes\"](c)||!!ms[\"CJK Symbols and Punctuation\"](c)||!!ms[\"Enclosed CJK Letters and Months\"](c)||!!ms[\"Halfwidth and Fullwidth Forms\"](c)||!!ms[\"Ideographic Description Characters\"](c)||!!ms[\"Vertical Forms\"](c)||_s.test(String.fromCodePoint(c)));(_c[p]||e||h.imageName||r!==t.length()-2&&Sc[t.getCharCode(r+1)])&&a.push(Ic(r+1,u,o,a,Mc(p,t.getCharCode(r+1),e&&l),!1));}}var c;return zc(Ic(t.length(),u,o,a,0,!0))}function Cc(t){let e=.5,r=.5;switch(t){case \"right\":case \"top-right\":case \"bottom-right\":e=1;break;case \"left\":case \"top-left\":case \"bottom-left\":e=0;}switch(t){case \"bottom\":case \"bottom-right\":case \"bottom-left\":r=1;break;case \"top\":case \"top-right\":case \"top-left\":r=0;}return {horizontalAlign:e,verticalAlign:r}}function Bc(t,e,r){const n=e.getMaxScale()*ac,{maxImageWidth:i,maxImageHeight:s}=e.getMaxImageSize(t),a=Math.max(n,s*r);return {verticalLineContentWidth:Math.max(n,i*r),horizontalLineContentHeight:a}}function Ec(t){switch(t){case \"top\":return 0;case \"center\":return .5;default:return 1}}function Tc(e,r,n){return !(e===t.an.horizontal||!r&&!Ss(n)||r&&(wc[n]||(i=n,/\\p{sc=Arab}/u.test(String.fromCodePoint(i)))));var i;}function Vc(t,e,r,n,i,s){const a=s[t.fontStack],o=function(t,e,r,n){if(t&&t.rect)return t;const i=e[r.fontStack],s=i&&i[n];return s?{rect:null,metrics:s.metrics}:null}(a&&a[e],i,t,e);if(null===o)return null;let l;if(r)l=n.verticalLineContentWidth-t.scale*ac;else {const e=Ec(t.verticalAlign);l=(n.horizontalLineContentHeight-t.scale*ac)*e;}return {rect:o.rect,metrics:o.metrics,baselineOffset:l}}function Fc(t,e,r,n,i){const s=i[t.imageName];if(!s)return null;const a=s.paddedRect,o=s.displaySize,l={width:o[0],height:o[1],left:1,top:-3,advance:e?o[1]:o[0]};let u;if(e)u=n.verticalLineContentWidth-o[1]*t.scale;else {const e=Ec(t.verticalAlign);u=(n.horizontalLineContentHeight-o[1]*t.scale)*e;}return {rect:a,metrics:l,baselineOffset:u,imageOffset:(e?o[0]:o[1])*t.scale-ac*r}}function Lc(t,e,r,n){if(0===n)return;const i=t[r],s=(t[r].x+i.metrics.advance*i.scale)*n;for(let n=e;n<=r;n++)t[n].x-=s;}function $c(t,e,r){const{horizontalAlign:n,verticalAlign:i}=Cc(r),s=e[0]-t.displaySize[0]*n,a=e[1]-t.displaySize[1]*i;return {image:t,top:a,bottom:a+t.displaySize[1],left:s,right:s+t.displaySize[0]}}function Dc(t){var e,r;let n=t.left,i=t.top,s=t.right-n,a=t.bottom-i;const o=null!==(e=t.image.textFitWidth)&&void 0!==e?e:\"stretchOrShrink\",l=null!==(r=t.image.textFitHeight)&&void 0!==r?r:\"stretchOrShrink\",u=(t.image.content[2]-t.image.content[0])/(t.image.content[3]-t.image.content[1]);if(\"proportional\"===l){if(\"stretchOnly\"===o&&s/a<u||\"proportional\"===o){const t=Math.ceil(a*u);n*=t/s,s=t;}}else if(\"proportional\"===o&&\"stretchOnly\"===l&&0!==u&&s/a>u){const t=Math.ceil(s/u);i*=t/a,a=t;}return {x1:n,y1:i,x2:n+s,y2:i+a}}function Oc(t,e,r,n,i,s){const a=t.image;let o;if(a.content){const t=a.content,e=a.pixelRatio||1;o=[t[0]/e,t[1]/e,a.displaySize[0]-t[2]/e,a.displaySize[1]-t[3]/e];}const l=e.left*s,u=e.right*s;let c,h,p,f;\"width\"===r||\"both\"===r?(f=i[0]+l-n[3],h=i[0]+u+n[1]):(f=i[0]+(l+u-a.displaySize[0])/2,h=f+a.displaySize[0]);const d=e.top*s,y=e.bottom*s;return \"height\"===r||\"both\"===r?(c=i[1]+d-n[0],p=i[1]+y+n[2]):(c=i[1]+(d+y-a.displaySize[1])/2,p=c+a.displaySize[1]),{image:a,top:c,right:h,bottom:p,left:f,collisionPadding:o}}const Rc=128,jc=32640;function Nc(t,e){const{expression:r}=e;if(\"constant\"===r.kind)return {kind:\"constant\",layoutSize:r.evaluate(new Cs(t+1))};if(\"source\"===r.kind)return {kind:\"source\"};{const{zoomStops:e,interpolationType:n}=r;let i=0;for(;i<e.length&&e[i]<=t;)i++;i=Math.max(0,i-1);let s=i;for(;s<e.length&&e[s]<t+1;)s++;s=Math.min(e.length-1,s);const a=e[i],o=e[s];return \"composite\"===r.kind?{kind:\"composite\",minZoom:a,maxZoom:o,interpolationType:n}:{kind:\"camera\",minZoom:a,maxZoom:o,minSize:r.evaluate(new Cs(a)),maxSize:r.evaluate(new Cs(o)),interpolationType:n}}}function Uc(t,e,r){let n=\"never\";const i=t.get(e);return i?n=i:t.get(r)&&(n=\"always\"),n}const qc=_u.VectorTileFeature.types,Gc=[{name:\"a_fade_opacity\",components:1,type:\"Uint8\",offset:0}];function Xc(t,e,r,n,i,s,a,o,l,u,c,h,p){const f=o?Math.min(jc,Math.round(o[0])):0,d=o?Math.min(jc,Math.round(o[1])):0;t.emplaceBack(e,r,Math.round(32*n),Math.round(32*i),s,a,(f<<1)+(l?1:0),d,16*u,16*c,256*h,256*p);}function Zc(t,e,r){t.emplaceBack(e.x,e.y,r),t.emplaceBack(e.x,e.y,r),t.emplaceBack(e.x,e.y,r),t.emplaceBack(e.x,e.y,r);}function Yc(t){for(const e of t.sections)if(zs(e.text))return !0;return !1}class Hc{constructor(t){this.layoutVertexArray=new Ra,this.indexArray=new Ga,this.programConfigurations=t,this.segments=new Ha,this.dynamicLayoutVertexArray=new ja,this.opacityVertexArray=new Na,this.hasVisibleVertices=!1,this.placedSymbolArray=new Aa;}isEmpty(){return 0===this.layoutVertexArray.length&&0===this.indexArray.length&&0===this.dynamicLayoutVertexArray.length&&0===this.opacityVertexArray.length}upload(t,e,r,n){this.isEmpty()||(r&&(this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,Ku.members),this.indexBuffer=t.createIndexBuffer(this.indexArray,e),this.dynamicLayoutVertexBuffer=t.createVertexBuffer(this.dynamicLayoutVertexArray,Ju.members,!0),this.opacityVertexBuffer=t.createVertexBuffer(this.opacityVertexArray,Gc,!0),this.opacityVertexBuffer.itemSize=1),(r||n)&&this.programConfigurations.upload(t));}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.programConfigurations.destroy(),this.segments.destroy(),this.dynamicLayoutVertexBuffer.destroy(),this.opacityVertexBuffer.destroy());}}us(\"SymbolBuffers\",Hc);class Kc{constructor(t,e,r){this.layoutVertexArray=new t,this.layoutAttributes=e,this.indexArray=new r,this.segments=new Ha,this.collisionVertexArray=new qa;}upload(t){this.layoutVertexBuffer=t.createVertexBuffer(this.layoutVertexArray,this.layoutAttributes),this.indexBuffer=t.createIndexBuffer(this.indexArray),this.collisionVertexBuffer=t.createVertexBuffer(this.collisionVertexArray,Wu.members,!0);}destroy(){this.layoutVertexBuffer&&(this.layoutVertexBuffer.destroy(),this.indexBuffer.destroy(),this.segments.destroy(),this.collisionVertexBuffer.destroy());}}us(\"CollisionBuffers\",Kc);class Jc{constructor(e){this.collisionBoxArray=e.collisionBoxArray,this.zoom=e.zoom,this.globalState=e.globalState,this.overscaling=e.overscaling,this.layers=e.layers,this.layerIds=this.layers.map((t=>t.id)),this.index=e.index,this.pixelRatio=e.pixelRatio,this.sourceLayerIndex=e.sourceLayerIndex,this.hasPattern=!1,this.hasRTLText=!1,this.sortKeyRanges=[],this.collisionCircleArray=[];const r=this.layers[0]._unevaluatedLayout._values;this.textSizeData=Nc(this.zoom,r[\"text-size\"]),this.iconSizeData=Nc(this.zoom,r[\"icon-size\"]);const n=this.layers[0].layout,i=n.get(\"symbol-sort-key\"),s=n.get(\"symbol-z-order\");this.canOverlap=\"never\"!==Uc(n,\"text-overlap\",\"text-allow-overlap\")||\"never\"!==Uc(n,\"icon-overlap\",\"icon-allow-overlap\")||n.get(\"text-ignore-placement\")||n.get(\"icon-ignore-placement\"),this.sortFeaturesByKey=\"viewport-y\"!==s&&!i.isConstant(),this.sortFeaturesByY=(\"viewport-y\"===s||\"auto\"===s&&!this.sortFeaturesByKey)&&this.canOverlap,\"point\"===n.get(\"symbol-placement\")&&(this.writingModes=n.get(\"text-writing-mode\").map((e=>t.an[e]))),this.stateDependentLayerIds=this.layers.filter((t=>t.isStateDependent())).map((t=>t.id)),this.sourceID=e.sourceID;}createArrays(){this.text=new Hc(new So(this.layers,this.zoom,(t=>/^text/.test(t)))),this.icon=new Hc(new So(this.layers,this.zoom,(t=>/^icon/.test(t)))),this.glyphOffsetArray=new Ia,this.lineVertexArray=new za,this.symbolInstances=new Ma,this.textAnchorOffsets=new Ca;}calculateGlyphDependencies(t,e,r,n,i){for(let s=0;s<t.length;s++)if(e[t.charCodeAt(s)]=!0,(r||n)&&i){const r=rc[t.charAt(s)];r&&(e[r.charCodeAt(0)]=!0);}}populate(e,r,n){const i=this.layers[0],s=i.layout,a=s.get(\"text-font\"),o=s.get(\"text-field\"),l=s.get(\"icon-image\"),u=(\"constant\"!==o.value.kind||o.value.value instanceof Te&&!o.value.value.isEmpty()||o.value.value.toString().length>0)&&(\"constant\"!==a.value.kind||a.value.value.length>0),c=\"constant\"!==l.value.kind||!!l.value.value||Object.keys(l.parameters).length>0,h=s.get(\"symbol-sort-key\");if(this.features=[],!u&&!c)return;const p=r.iconDependencies,f=r.glyphDependencies,d=r.availableImages,y=new Cs(this.zoom,{globalState:this.globalState});for(const{feature:r,id:o,index:l,sourceLayerIndex:m}of e){const e=i._featureFilter.needGeometry,g=Po(r,e);if(!i._featureFilter.filter(y,g,n))continue;let x,v;if(e||(g.geometry=zo(r)),u){const t=i.getValueAndResolveTokens(\"text-field\",g,n,d),e=Te.factory(t),r=this.hasRTLText=this.hasRTLText||Yc(e);(!r||\"unavailable\"===Ps.getRTLTextPluginStatus()||r&&Ps.isParsed())&&(x=ec(e,i,g));}if(c){const t=i.getValueAndResolveTokens(\"icon-image\",g,n,d);v=t instanceof Re?t:Re.fromString(t);}if(!x&&!v)continue;const b=this.sortFeaturesByKey?h.evaluate(g,{},n):void 0;if(this.features.push({id:o,text:x,icon:v,index:l,sourceLayerIndex:m,geometry:g.geometry,properties:r.properties,type:qc[r.type],sortKey:b}),v&&(p[v.name]=!0),x){const e=a.evaluate(g,{},n).join(\",\"),r=\"viewport\"!==s.get(\"text-rotation-alignment\")&&\"point\"!==s.get(\"symbol-placement\");this.allowVerticalPlacement=this.writingModes&&this.writingModes.indexOf(t.an.vertical)>=0;for(const t of x.sections)if(t.image)p[t.image.name]=!0;else {const n=gs(x.toString()),i=t.fontStack||e,s=f[i]=f[i]||{};this.calculateGlyphDependencies(t.text,s,r,this.allowVerticalPlacement,n);}}}\"line\"===s.get(\"symbol-placement\")&&(this.features=function(t){const e={},r={},n=[];let i=0;function s(e){n.push(t[e]),i++;}function a(t,e,i){const s=r[t];return delete r[t],r[e]=s,n[s].geometry[0].pop(),n[s].geometry[0]=n[s].geometry[0].concat(i[0]),s}function o(t,r,i){const s=e[r];return delete e[r],e[t]=s,n[s].geometry[0].shift(),n[s].geometry[0]=i[0].concat(n[s].geometry[0]),s}function l(t,e,r){const n=r?e[0][e[0].length-1]:e[0][0];return `${t}:${n.x}:${n.y}`}for(let u=0;u<t.length;u++){const c=t[u],h=c.geometry,p=c.text?c.text.toString():null;if(!p){s(u);continue}const f=l(p,h),d=l(p,h,!0);if(f in r&&d in e&&r[f]!==e[d]){const t=o(f,d,h),i=a(f,d,n[t].geometry);delete e[f],delete r[d],r[l(p,n[i].geometry,!0)]=i,n[t].geometry=null;}else f in r?a(f,d,h):d in e?o(f,d,h):(s(u),e[f]=i-1,r[d]=i-1);}return n.filter((t=>t.geometry))}(this.features)),this.sortFeaturesByKey&&this.features.sort(((t,e)=>t.sortKey-e.sortKey));}update(t,e,r){this.stateDependentLayers.length&&(this.text.programConfigurations.updatePaintArrays(t,e,this.layers,r),this.icon.programConfigurations.updatePaintArrays(t,e,this.layers,r));}isEmpty(){return 0===this.symbolInstances.length&&!this.hasRTLText}uploadPending(){return !this.uploaded||this.text.programConfigurations.needsUpload||this.icon.programConfigurations.needsUpload}upload(t){!this.uploaded&&this.hasDebugData()&&(this.textCollisionBox.upload(t),this.iconCollisionBox.upload(t)),this.text.upload(t,this.sortFeaturesByY,!this.uploaded,this.text.programConfigurations.needsUpload),this.icon.upload(t,this.sortFeaturesByY,!this.uploaded,this.icon.programConfigurations.needsUpload),this.uploaded=!0;}destroyDebugData(){this.textCollisionBox.destroy(),this.iconCollisionBox.destroy();}destroy(){this.text.destroy(),this.icon.destroy(),this.hasDebugData()&&this.destroyDebugData();}addToLineVertexArray(t,e){const r=this.lineVertexArray.length;if(void 0!==t.segment){let r=t.dist(e[t.segment+1]),n=t.dist(e[t.segment]);const i={};for(let n=t.segment+1;n<e.length;n++)i[n]={x:e[n].x,y:e[n].y,tileUnitDistanceFromAnchor:r},n<e.length-1&&(r+=e[n+1].dist(e[n]));for(let r=t.segment||0;r>=0;r--)i[r]={x:e[r].x,y:e[r].y,tileUnitDistanceFromAnchor:n},r>0&&(n+=e[r-1].dist(e[r]));for(let t=0;t<e.length;t++){const e=i[t];this.lineVertexArray.emplaceBack(e.x,e.y,e.tileUnitDistanceFromAnchor);}}return {lineStartIndex:r,lineLength:this.lineVertexArray.length-r}}addSymbols(e,r,n,i,s,a,o,l,u,c,h,p){const f=e.indexArray,d=e.layoutVertexArray,y=e.segments.prepareSegment(4*r.length,d,f,this.canOverlap?a.sortKey:void 0),m=this.glyphOffsetArray.length,g=y.vertexLength,x=this.allowVerticalPlacement&&o===t.an.vertical?Math.PI/2:0,v=a.text&&a.text.sections;for(let t=0;t<r.length;t++){const{tl:i,tr:s,bl:o,br:u,tex:c,pixelOffsetTL:h,pixelOffsetBR:m,minFontScaleX:g,minFontScaleY:b,glyphOffset:w,isSDF:_,sectionIndex:S}=r[t],A=y.vertexLength,k=w[1];Xc(d,l.x,l.y,i.x,k+i.y,c.x,c.y,n,_,h.x,h.y,g,b),Xc(d,l.x,l.y,s.x,k+s.y,c.x+c.w,c.y,n,_,m.x,h.y,g,b),Xc(d,l.x,l.y,o.x,k+o.y,c.x,c.y+c.h,n,_,h.x,m.y,g,b),Xc(d,l.x,l.y,u.x,k+u.y,c.x+c.w,c.y+c.h,n,_,m.x,m.y,g,b),Zc(e.dynamicLayoutVertexArray,l,x),f.emplaceBack(A,A+2,A+1),f.emplaceBack(A+1,A+2,A+3),y.vertexLength+=4,y.primitiveLength+=2,this.glyphOffsetArray.emplaceBack(w[0]),t!==r.length-1&&S===r[t+1].sectionIndex||e.programConfigurations.populatePaintArrays(d.length,a,a.index,{},p,v&&v[S]);}e.placedSymbolArray.emplaceBack(l.x,l.y,m,this.glyphOffsetArray.length-m,g,u,c,l.segment,n?n[0]:0,n?n[1]:0,i[0],i[1],o,0,!1,0,h);}_addCollisionDebugVertex(t,e,r,n,i,s){return e.emplaceBack(0,0),t.emplaceBack(r.x,r.y,n,i,Math.round(s.x),Math.round(s.y))}addCollisionDebugVertices(t,e,r,n,i,s,a){const o=i.segments.prepareSegment(4,i.layoutVertexArray,i.indexArray),u=o.vertexLength,c=i.layoutVertexArray,h=i.collisionVertexArray,p=a.anchorX,f=a.anchorY;this._addCollisionDebugVertex(c,h,s,p,f,new l(t,e)),this._addCollisionDebugVertex(c,h,s,p,f,new l(r,e)),this._addCollisionDebugVertex(c,h,s,p,f,new l(r,n)),this._addCollisionDebugVertex(c,h,s,p,f,new l(t,n)),o.vertexLength+=4;const d=i.indexArray;d.emplaceBack(u,u+1),d.emplaceBack(u+1,u+2),d.emplaceBack(u+2,u+3),d.emplaceBack(u+3,u),o.primitiveLength+=4;}addDebugCollisionBoxes(t,e,r,n){for(let i=t;i<e;i++){const t=this.collisionBoxArray.get(i);this.addCollisionDebugVertices(t.x1,t.y1,t.x2,t.y2,n?this.textCollisionBox:this.iconCollisionBox,t.anchorPoint,r);}}generateCollisionDebugBuffers(){this.hasDebugData()&&this.destroyDebugData(),this.textCollisionBox=new Kc(Ua,Qu.members,Xa),this.iconCollisionBox=new Kc(Ua,Qu.members,Xa);for(let t=0;t<this.symbolInstances.length;t++){const e=this.symbolInstances.get(t);this.addDebugCollisionBoxes(e.textBoxStartIndex,e.textBoxEndIndex,e,!0),this.addDebugCollisionBoxes(e.verticalTextBoxStartIndex,e.verticalTextBoxEndIndex,e,!0),this.addDebugCollisionBoxes(e.iconBoxStartIndex,e.iconBoxEndIndex,e,!1),this.addDebugCollisionBoxes(e.verticalIconBoxStartIndex,e.verticalIconBoxEndIndex,e,!1);}}_deserializeCollisionBoxesForSymbol(t,e,r,n,i,s,a,o,l){const u={};for(let n=e;n<r;n++){const e=t.get(n);u.textBox={x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,anchorPointX:e.anchorPointX,anchorPointY:e.anchorPointY},u.textFeatureIndex=e.featureIndex;break}for(let e=n;e<i;e++){const r=t.get(e);u.verticalTextBox={x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,anchorPointX:r.anchorPointX,anchorPointY:r.anchorPointY},u.verticalTextFeatureIndex=r.featureIndex;break}for(let e=s;e<a;e++){const r=t.get(e);u.iconBox={x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,anchorPointX:r.anchorPointX,anchorPointY:r.anchorPointY},u.iconFeatureIndex=r.featureIndex;break}for(let e=o;e<l;e++){const r=t.get(e);u.verticalIconBox={x1:r.x1,y1:r.y1,x2:r.x2,y2:r.y2,anchorPointX:r.anchorPointX,anchorPointY:r.anchorPointY},u.verticalIconFeatureIndex=r.featureIndex;break}return u}deserializeCollisionBoxes(t){this.collisionArrays=[];for(let e=0;e<this.symbolInstances.length;e++){const r=this.symbolInstances.get(e);this.collisionArrays.push(this._deserializeCollisionBoxesForSymbol(t,r.textBoxStartIndex,r.textBoxEndIndex,r.verticalTextBoxStartIndex,r.verticalTextBoxEndIndex,r.iconBoxStartIndex,r.iconBoxEndIndex,r.verticalIconBoxStartIndex,r.verticalIconBoxEndIndex));}}hasTextData(){return this.text.segments.get().length>0}hasIconData(){return this.icon.segments.get().length>0}hasDebugData(){return this.textCollisionBox&&this.iconCollisionBox}hasTextCollisionBoxData(){return this.hasDebugData()&&this.textCollisionBox.segments.get().length>0}hasIconCollisionBoxData(){return this.hasDebugData()&&this.iconCollisionBox.segments.get().length>0}addIndicesForPlacedSymbol(t,e){const r=t.placedSymbolArray.get(e),n=r.vertexStartIndex+4*r.numGlyphs;for(let e=r.vertexStartIndex;e<n;e+=4)t.indexArray.emplaceBack(e,e+2,e+1),t.indexArray.emplaceBack(e+1,e+2,e+3);}getSortedSymbolIndexes(t){if(this.sortedAngle===t&&void 0!==this.symbolInstanceIndexes)return this.symbolInstanceIndexes;const e=Math.sin(t),r=Math.cos(t),n=[],i=[],s=[];for(let t=0;t<this.symbolInstances.length;++t){s.push(t);const a=this.symbolInstances.get(t);n.push(0|Math.round(e*a.anchorX+r*a.anchorY)),i.push(a.featureIndex);}return s.sort(((t,e)=>n[t]-n[e]||i[e]-i[t])),s}addToSortKeyRanges(t,e){const r=this.sortKeyRanges[this.sortKeyRanges.length-1];r&&r.sortKey===e?r.symbolInstanceEnd=t+1:this.sortKeyRanges.push({sortKey:e,symbolInstanceStart:t,symbolInstanceEnd:t+1});}sortFeatures(t){if(this.sortFeaturesByY&&this.sortedAngle!==t&&!(this.text.segments.get().length>1||this.icon.segments.get().length>1)){this.symbolInstanceIndexes=this.getSortedSymbolIndexes(t),this.sortedAngle=t,this.text.indexArray.clear(),this.icon.indexArray.clear(),this.featureSortOrder=[];for(const t of this.symbolInstanceIndexes){const e=this.symbolInstances.get(t);this.featureSortOrder.push(e.featureIndex),[e.rightJustifiedTextSymbolIndex,e.centerJustifiedTextSymbolIndex,e.leftJustifiedTextSymbolIndex].forEach(((t,e,r)=>{t>=0&&r.indexOf(t)===e&&this.addIndicesForPlacedSymbol(this.text,t);})),e.verticalPlacedTextSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.text,e.verticalPlacedTextSymbolIndex),e.placedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,e.placedIconSymbolIndex),e.verticalPlacedIconSymbolIndex>=0&&this.addIndicesForPlacedSymbol(this.icon,e.verticalPlacedIconSymbolIndex);}this.text.indexBuffer&&this.text.indexBuffer.updateData(this.text.indexArray),this.icon.indexBuffer&&this.icon.indexBuffer.updateData(this.icon.indexArray);}}}let Wc,Qc;us(\"SymbolBucket\",Jc,{omit:[\"layers\",\"collisionBoxArray\",\"features\",\"compareText\"]}),Jc.MAX_GLYPHS=65535,Jc.addDynamicAttributes=Zc;var th={get paint(){return Qc=Qc||new qs({\"icon-opacity\":new Rs(wt.paint_symbol[\"icon-opacity\"]),\"icon-color\":new Rs(wt.paint_symbol[\"icon-color\"]),\"icon-halo-color\":new Rs(wt.paint_symbol[\"icon-halo-color\"]),\"icon-halo-width\":new Rs(wt.paint_symbol[\"icon-halo-width\"]),\"icon-halo-blur\":new Rs(wt.paint_symbol[\"icon-halo-blur\"]),\"icon-translate\":new Os(wt.paint_symbol[\"icon-translate\"]),\"icon-translate-anchor\":new Os(wt.paint_symbol[\"icon-translate-anchor\"]),\"text-opacity\":new Rs(wt.paint_symbol[\"text-opacity\"]),\"text-color\":new Rs(wt.paint_symbol[\"text-color\"],{runtimeType:jt,getOverride:t=>t.textColor,hasOverride:t=>!!t.textColor}),\"text-halo-color\":new Rs(wt.paint_symbol[\"text-halo-color\"]),\"text-halo-width\":new Rs(wt.paint_symbol[\"text-halo-width\"]),\"text-halo-blur\":new Rs(wt.paint_symbol[\"text-halo-blur\"]),\"text-translate\":new Os(wt.paint_symbol[\"text-translate\"]),\"text-translate-anchor\":new Os(wt.paint_symbol[\"text-translate-anchor\"])})},get layout(){return Wc=Wc||new qs({\"symbol-placement\":new Os(wt.layout_symbol[\"symbol-placement\"]),\"symbol-spacing\":new Os(wt.layout_symbol[\"symbol-spacing\"]),\"symbol-avoid-edges\":new Os(wt.layout_symbol[\"symbol-avoid-edges\"]),\"symbol-sort-key\":new Rs(wt.layout_symbol[\"symbol-sort-key\"]),\"symbol-z-order\":new Os(wt.layout_symbol[\"symbol-z-order\"]),\"icon-allow-overlap\":new Os(wt.layout_symbol[\"icon-allow-overlap\"]),\"icon-overlap\":new Os(wt.layout_symbol[\"icon-overlap\"]),\"icon-ignore-placement\":new Os(wt.layout_symbol[\"icon-ignore-placement\"]),\"icon-optional\":new Os(wt.layout_symbol[\"icon-optional\"]),\"icon-rotation-alignment\":new Os(wt.layout_symbol[\"icon-rotation-alignment\"]),\"icon-size\":new Rs(wt.layout_symbol[\"icon-size\"]),\"icon-text-fit\":new Os(wt.layout_symbol[\"icon-text-fit\"]),\"icon-text-fit-padding\":new Os(wt.layout_symbol[\"icon-text-fit-padding\"]),\"icon-image\":new Rs(wt.layout_symbol[\"icon-image\"]),\"icon-rotate\":new Rs(wt.layout_symbol[\"icon-rotate\"]),\"icon-padding\":new Rs(wt.layout_symbol[\"icon-padding\"]),\"icon-keep-upright\":new Os(wt.layout_symbol[\"icon-keep-upright\"]),\"icon-offset\":new Rs(wt.layout_symbol[\"icon-offset\"]),\"icon-anchor\":new Rs(wt.layout_symbol[\"icon-anchor\"]),\"icon-pitch-alignment\":new Os(wt.layout_symbol[\"icon-pitch-alignment\"]),\"text-pitch-alignment\":new Os(wt.layout_symbol[\"text-pitch-alignment\"]),\"text-rotation-alignment\":new Os(wt.layout_symbol[\"text-rotation-alignment\"]),\"text-field\":new Rs(wt.layout_symbol[\"text-field\"]),\"text-font\":new Rs(wt.layout_symbol[\"text-font\"]),\"text-size\":new Rs(wt.layout_symbol[\"text-size\"]),\"text-max-width\":new Rs(wt.layout_symbol[\"text-max-width\"]),\"text-line-height\":new Os(wt.layout_symbol[\"text-line-height\"]),\"text-letter-spacing\":new Rs(wt.layout_symbol[\"text-letter-spacing\"]),\"text-justify\":new Rs(wt.layout_symbol[\"text-justify\"]),\"text-radial-offset\":new Rs(wt.layout_symbol[\"text-radial-offset\"]),\"text-variable-anchor\":new Os(wt.layout_symbol[\"text-variable-anchor\"]),\"text-variable-anchor-offset\":new Rs(wt.layout_symbol[\"text-variable-anchor-offset\"]),\"text-anchor\":new Rs(wt.layout_symbol[\"text-anchor\"]),\"text-max-angle\":new Os(wt.layout_symbol[\"text-max-angle\"]),\"text-writing-mode\":new Os(wt.layout_symbol[\"text-writing-mode\"]),\"text-rotate\":new Rs(wt.layout_symbol[\"text-rotate\"]),\"text-padding\":new Os(wt.layout_symbol[\"text-padding\"]),\"text-keep-upright\":new Os(wt.layout_symbol[\"text-keep-upright\"]),\"text-transform\":new Rs(wt.layout_symbol[\"text-transform\"]),\"text-offset\":new Rs(wt.layout_symbol[\"text-offset\"]),\"text-allow-overlap\":new Os(wt.layout_symbol[\"text-allow-overlap\"]),\"text-overlap\":new Os(wt.layout_symbol[\"text-overlap\"]),\"text-ignore-placement\":new Os(wt.layout_symbol[\"text-ignore-placement\"]),\"text-optional\":new Os(wt.layout_symbol[\"text-optional\"])})}};class eh{constructor(t){if(void 0===t.property.overrides)throw new Error(\"overrides must be provided to instantiate FormatSectionOverride class\");this.type=t.property.overrides?t.property.overrides.runtimeType:$t,this.defaultValue=t;}evaluate(t){if(t.formattedSection){const e=this.defaultValue.property.overrides;if(e&&e.hasOverride(t.formattedSection))return e.getOverride(t.formattedSection)}return t.feature&&t.featureState?this.defaultValue.evaluate(t.feature,t.featureState):this.defaultValue.property.specification.default}eachChild(t){this.defaultValue.isConstant()||t(this.defaultValue.value._styleExpression.expression);}outputDefined(){return !1}serialize(){return null}}us(\"FormatSectionOverride\",eh,{omit:[\"defaultValue\"]});class rh extends Xs{constructor(t){super(t,th);}recalculate(t,e){if(super.recalculate(t,e),\"auto\"===this.layout.get(\"icon-rotation-alignment\")&&(this.layout._values[\"icon-rotation-alignment\"]=\"point\"!==this.layout.get(\"symbol-placement\")?\"map\":\"viewport\"),\"auto\"===this.layout.get(\"text-rotation-alignment\")&&(this.layout._values[\"text-rotation-alignment\"]=\"point\"!==this.layout.get(\"symbol-placement\")?\"map\":\"viewport\"),\"auto\"===this.layout.get(\"text-pitch-alignment\")&&(this.layout._values[\"text-pitch-alignment\"]=\"map\"===this.layout.get(\"text-rotation-alignment\")?\"map\":\"viewport\"),\"auto\"===this.layout.get(\"icon-pitch-alignment\")&&(this.layout._values[\"icon-pitch-alignment\"]=this.layout.get(\"icon-rotation-alignment\")),\"point\"===this.layout.get(\"symbol-placement\")){const t=this.layout.get(\"text-writing-mode\");if(t){const e=[];for(const r of t)e.indexOf(r)<0&&e.push(r);this.layout._values[\"text-writing-mode\"]=e;}else this.layout._values[\"text-writing-mode\"]=[\"horizontal\"];}this._setPaintOverrides();}getValueAndResolveTokens(t,e,r,n){const i=this.layout.get(t).evaluate(e,{},r,n),s=this._unevaluatedLayout._values[t];return s.isDataDriven()||ii(s.value)||!i?i:function(t,e){return e.replace(/{([^{}]+)}/g,((e,r)=>t&&r in t?String(t[r]):\"\"))}(e.properties,i)}createBucket(t){return new Jc(t)}queryRadius(){return 0}queryIntersectsFeature(){throw new Error(\"Should take a different path in FeatureIndex\")}_setPaintOverrides(){for(const t of th.paint.overridableProperties){if(!rh.hasPaintOverride(this.layout,t))continue;const e=this.paint.get(t),r=new eh(e),n=new ni(r,e.property.specification);let i=null;i=\"constant\"===e.value.kind||\"source\"===e.value.kind?new ai(\"source\",n):new oi(\"composite\",n,e.value.zoomStops),this.paint._values[t]=new $s(e.property,i,e.parameters);}}_handleOverridablePaintPropertyUpdate(t,e,r){return !(!this.layout||e.isDataDriven()||r.isDataDriven())&&rh.hasPaintOverride(this.layout,t)}static hasPaintOverride(t,e){const r=t.get(\"text-field\"),n=th.paint.properties[e];let i=!1;const s=t=>{for(const e of t)if(n.overrides&&n.overrides.hasOverride(e))return void(i=!0)};if(\"constant\"===r.value.kind&&r.value.value instanceof Te)s(r.value.value.sections);else if(\"source\"===r.value.kind){const t=e=>{i||(e instanceof Xe&&qe(e.value)===Xt?s(e.value.sections):e instanceof Cr?s(e.sections):e.eachChild(t));},e=r.value;e._styleExpression&&t(e._styleExpression.expression);}return i}}let nh;var ih={get paint(){return nh=nh||new qs({\"background-color\":new Os(wt.paint_background[\"background-color\"]),\"background-pattern\":new Ns(wt.paint_background[\"background-pattern\"]),\"background-opacity\":new Os(wt.paint_background[\"background-opacity\"])})}};class sh extends Xs{constructor(t){super(t,ih);}}let ah;var oh={get paint(){return ah=ah||new qs({\"raster-opacity\":new Os(wt.paint_raster[\"raster-opacity\"]),\"raster-hue-rotate\":new Os(wt.paint_raster[\"raster-hue-rotate\"]),\"raster-brightness-min\":new Os(wt.paint_raster[\"raster-brightness-min\"]),\"raster-brightness-max\":new Os(wt.paint_raster[\"raster-brightness-max\"]),\"raster-saturation\":new Os(wt.paint_raster[\"raster-saturation\"]),\"raster-contrast\":new Os(wt.paint_raster[\"raster-contrast\"]),\"raster-resampling\":new Os(wt.paint_raster[\"raster-resampling\"]),\"raster-fade-duration\":new Os(wt.paint_raster[\"raster-fade-duration\"])})}};class lh extends Xs{constructor(t){super(t,oh);}}class uh extends Xs{constructor(t){super(t,{}),this.onAdd=t=>{this.implementation.onAdd&&this.implementation.onAdd(t,t.painter.context.gl);},this.onRemove=t=>{this.implementation.onRemove&&this.implementation.onRemove(t,t.painter.context.gl);},this.implementation=t;}is3D(){return \"3d\"===this.implementation.renderingMode}hasOffscreenPass(){return void 0!==this.implementation.prerender}recalculate(){}updateTransitions(){}hasTransition(){return !1}serialize(){throw new Error(\"Custom layers cannot be serialized\")}}class ch{constructor(t){this._methodToThrottle=t,this._triggered=!1,\"undefined\"!=typeof MessageChannel&&(this._channel=new MessageChannel,this._channel.port2.onmessage=()=>{this._triggered=!1,this._methodToThrottle();});}trigger(){this._triggered||(this._triggered=!0,this._channel?this._channel.port1.postMessage(!0):setTimeout((()=>{this._triggered=!1,this._methodToThrottle();}),0));}remove(){delete this._channel,this._methodToThrottle=()=>{};}}const hh={once:!0},ph=6371008.8;class fh{constructor(t,e){if(isNaN(t)||isNaN(e))throw new Error(`Invalid LngLat object: (${t}, ${e})`);if(this.lng=+t,this.lat=+e,this.lat>90||this.lat<-90)throw new Error(\"Invalid LngLat latitude value: must be between -90 and 90\")}wrap(){return new fh(R(this.lng,-180,180),this.lat)}toArray(){return [this.lng,this.lat]}toString(){return `LngLat(${this.lng}, ${this.lat})`}distanceTo(t){const e=Math.PI/180,r=this.lat*e,n=t.lat*e,i=Math.sin(r)*Math.sin(n)+Math.cos(r)*Math.cos(n)*Math.cos((t.lng-this.lng)*e);return ph*Math.acos(Math.min(i,1))}static convert(t){if(t instanceof fh)return t;if(Array.isArray(t)&&(2===t.length||3===t.length))return new fh(Number(t[0]),Number(t[1]));if(!Array.isArray(t)&&\"object\"==typeof t&&null!==t)return new fh(Number(\"lng\"in t?t.lng:t.lon),Number(t.lat));throw new Error(\"`LngLatLike` argument must be specified as a LngLat instance, an object {lng: <lng>, lat: <lat>}, an object {lon: <lng>, lat: <lat>}, or an array of [<lng>, <lat>]\")}}const dh=2*Math.PI*ph;function yh(t){return dh*Math.cos(t*Math.PI/180)}function mh(t){return (180+t)/360}function gh(t){return (180-180/Math.PI*Math.log(Math.tan(Math.PI/4+t*Math.PI/360)))/360}function xh(t,e){return t/yh(e)}function vh(t){return 360/Math.PI*Math.atan(Math.exp((180-360*t)*Math.PI/180))-90}function bh(t,e){return t*yh(vh(e))}class wh{constructor(t,e,r=0){this.x=+t,this.y=+e,this.z=+r;}static fromLngLat(t,e=0){const r=fh.convert(t);return new wh(mh(r.lng),gh(r.lat),xh(e,r.lat))}toLngLat(){return new fh(360*this.x-180,vh(this.y))}toAltitude(){return bh(this.z,this.y)}meterInMercatorCoordinateUnits(){return 1/dh*(t=vh(this.y),1/Math.cos(t*Math.PI/180));var t;}}function _h(t,e,r){var n=2*Math.PI*6378137/256/Math.pow(2,r);return [t*n-2*Math.PI*6378137/2,e*n-2*Math.PI*6378137/2]}class Sh{constructor(t,e,r){if(!function(t,e,r){return !(t<0||t>25||r<0||r>=Math.pow(2,t)||e<0||e>=Math.pow(2,t))}(t,e,r))throw new Error(`x=${e}, y=${r}, z=${t} outside of bounds. 0<=x<${Math.pow(2,t)}, 0<=y<${Math.pow(2,t)} 0<=z<=25 `);this.z=t,this.x=e,this.y=r,this.key=Mh(0,t,t,e,r);}equals(t){return this.z===t.z&&this.x===t.x&&this.y===t.y}url(t,e,r){const n=(s=this.y,a=this.z,o=_h(256*(i=this.x),256*(s=Math.pow(2,a)-s-1),a),l=_h(256*(i+1),256*(s+1),a),o[0]+\",\"+o[1]+\",\"+l[0]+\",\"+l[1]);var i,s,a,o,l;const u=function(t,e,r){let n,i=\"\";for(let s=t;s>0;s--)n=1<<s-1,i+=(e&n?1:0)+(r&n?2:0);return i}(this.z,this.x,this.y);return t[(this.x+this.y)%t.length].replace(/{prefix}/g,(this.x%16).toString(16)+(this.y%16).toString(16)).replace(/{z}/g,String(this.z)).replace(/{x}/g,String(this.x)).replace(/{y}/g,String(\"tms\"===r?Math.pow(2,this.z)-this.y-1:this.y)).replace(/{ratio}/g,e>1?\"@2x\":\"\").replace(/{quadkey}/g,u).replace(/{bbox-epsg-3857}/g,n)}isChildOf(t){const e=this.z-t.z;return e>0&&t.x===this.x>>e&&t.y===this.y>>e}getTilePoint(t){const e=Math.pow(2,this.z);return new l((t.x*e-this.x)*E,(t.y*e-this.y)*E)}toString(){return `${this.z}/${this.x}/${this.y}`}}class Ah{constructor(t,e){this.wrap=t,this.canonical=e,this.key=Mh(t,e.z,e.z,e.x,e.y);}}class kh{constructor(t,e,r,n,i){if(this.terrainRttPosMatrix32f=null,t<r)throw new Error(`overscaledZ should be >= z; overscaledZ = ${t}; z = ${r}`);this.overscaledZ=t,this.wrap=e,this.canonical=new Sh(r,+n,+i),this.key=Mh(e,t,r,n,i);}clone(){return new kh(this.overscaledZ,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)}equals(t){return this.overscaledZ===t.overscaledZ&&this.wrap===t.wrap&&this.canonical.equals(t.canonical)}scaledTo(t){if(t>this.overscaledZ)throw new Error(`targetZ > this.overscaledZ; targetZ = ${t}; overscaledZ = ${this.overscaledZ}`);const e=this.canonical.z-t;return t>this.canonical.z?new kh(t,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y):new kh(t,this.wrap,t,this.canonical.x>>e,this.canonical.y>>e)}calculateScaledKey(t,e){if(t>this.overscaledZ)throw new Error(`targetZ > this.overscaledZ; targetZ = ${t}; overscaledZ = ${this.overscaledZ}`);const r=this.canonical.z-t;return t>this.canonical.z?Mh(this.wrap*+e,t,this.canonical.z,this.canonical.x,this.canonical.y):Mh(this.wrap*+e,t,t,this.canonical.x>>r,this.canonical.y>>r)}isChildOf(t){if(t.wrap!==this.wrap)return !1;const e=this.canonical.z-t.canonical.z;return 0===t.overscaledZ||t.overscaledZ<this.overscaledZ&&t.canonical.x===this.canonical.x>>e&&t.canonical.y===this.canonical.y>>e}children(t){if(this.overscaledZ>=t)return [new kh(this.overscaledZ+1,this.wrap,this.canonical.z,this.canonical.x,this.canonical.y)];const e=this.canonical.z+1,r=2*this.canonical.x,n=2*this.canonical.y;return [new kh(e,this.wrap,e,r,n),new kh(e,this.wrap,e,r+1,n),new kh(e,this.wrap,e,r,n+1),new kh(e,this.wrap,e,r+1,n+1)]}isLessThan(t){return this.wrap<t.wrap||!(this.wrap>t.wrap)&&(this.overscaledZ<t.overscaledZ||!(this.overscaledZ>t.overscaledZ)&&(this.canonical.x<t.canonical.x||!(this.canonical.x>t.canonical.x)&&this.canonical.y<t.canonical.y))}wrapped(){return new kh(this.overscaledZ,0,this.canonical.z,this.canonical.x,this.canonical.y)}unwrapTo(t){return new kh(this.overscaledZ,t,this.canonical.z,this.canonical.x,this.canonical.y)}overscaleFactor(){return Math.pow(2,this.overscaledZ-this.canonical.z)}toUnwrapped(){return new Ah(this.wrap,this.canonical)}toString(){return `${this.overscaledZ}/${this.canonical.x}/${this.canonical.y}`}getTilePoint(t){return this.canonical.getTilePoint(new wh(t.x-this.wrap,t.y))}}function Mh(t,e,r,n,i){(t*=2)<0&&(t=-1*t-1);const s=1<<r;return (s*s*t+s*i+n).toString(36)+r.toString(36)+e.toString(36)}us(\"CanonicalTileID\",Sh),us(\"OverscaledTileID\",kh,{omit:[\"terrainRttPosMatrix32f\"]});class Ih{constructor(){this.minX=1/0,this.maxX=-1/0,this.minY=1/0,this.maxY=-1/0;}extend(t){return this.minX=Math.min(this.minX,t.x),this.minY=Math.min(this.minY,t.y),this.maxX=Math.max(this.maxX,t.x),this.maxY=Math.max(this.maxY,t.y),this}expandBy(t){return this.minX-=t,this.minY-=t,this.maxX+=t,this.maxY+=t,(this.minX>this.maxX||this.minY>this.maxY)&&(this.minX=1/0,this.maxX=-1/0,this.minY=1/0,this.maxY=-1/0),this}shrinkBy(t){return this.expandBy(-t)}map(t){const e=new Ih;return e.extend(t(new l(this.minX,this.minY))),e.extend(t(new l(this.maxX,this.minY))),e.extend(t(new l(this.minX,this.maxY))),e.extend(t(new l(this.maxX,this.maxY))),e}static fromPoints(t){const e=new Ih;for(const r of t)e.extend(r);return e}contains(t){return t.x>=this.minX&&t.x<=this.maxX&&t.y>=this.minY&&t.y<=this.maxY}empty(){return this.minX>this.maxX}width(){return this.maxX-this.minX}height(){return this.maxY-this.minY}covers(t){return !this.empty()&&!t.empty()&&t.minX>=this.minX&&t.maxX<=this.maxX&&t.minY>=this.minY&&t.maxY<=this.maxY}intersects(t){return !this.empty()&&!t.empty()&&t.minX<=this.maxX&&t.maxX>=this.minX&&t.minY<=this.maxY&&t.maxY>=this.minY}}class zh{constructor(t){this._stringToNumber={},this._numberToString=[];for(let e=0;e<t.length;e++){const r=t[e];this._stringToNumber[r]=e,this._numberToString[e]=r;}}encode(t){return this._stringToNumber[t]}decode(t){if(t>=this._numberToString.length)throw new Error(`Out of bounds. Index requested n=${t} can't be >= this._numberToString.length ${this._numberToString.length}`);return this._numberToString[t]}}class Ph{constructor(t,e,r,n,i){this.type=\"Feature\",this._vectorTileFeature=t,t._z=e,t._x=r,t._y=n,this.properties=t.properties,this.id=i;}get geometry(){return void 0===this._geometry&&(this._geometry=this._vectorTileFeature.toGeoJSON(this._vectorTileFeature._x,this._vectorTileFeature._y,this._vectorTileFeature._z).geometry),this._geometry}set geometry(t){this._geometry=t;}toJSON(){const t={geometry:this.geometry};for(const e in this)\"_geometry\"!==e&&\"_vectorTileFeature\"!==e&&(t[e]=this[e]);return t}}class Ch{constructor(t,e){this.tileID=t,this.x=t.canonical.x,this.y=t.canonical.y,this.z=t.canonical.z,this.grid=new os(E,16,0),this.grid3D=new os(E,16,0),this.featureIndexArray=new Ea,this.promoteId=e;}insert(t,e,r,n,i,s){const a=this.featureIndexArray.length;this.featureIndexArray.emplaceBack(r,n,i);const o=s?this.grid3D:this.grid;for(let t=0;t<e.length;t++){const r=e[t],n=[1/0,1/0,-1/0,-1/0];for(let t=0;t<r.length;t++){const e=r[t];n[0]=Math.min(n[0],e.x),n[1]=Math.min(n[1],e.y),n[2]=Math.max(n[2],e.x),n[3]=Math.max(n[3],e.y);}n[0]<E&&n[1]<E&&n[2]>=0&&n[3]>=0&&o.insert(a,n[0],n[1],n[2],n[3]);}}loadVTLayers(){return this.vtLayers||(this.vtLayers=new _u.VectorTile(new hc(this.rawTileData)).layers,this.sourceLayerCoder=new zh(this.vtLayers?Object.keys(this.vtLayers).sort():[\"_geojsonTileLayer\"])),this.vtLayers}query(t,e,r,n){this.loadVTLayers();const i=t.params,s=E/t.tileSize/t.scale,a=di(i.filter),o=t.queryGeometry,u=t.queryPadding*s,c=Ih.fromPoints(o),h=this.grid.query(c.minX-u,c.minY-u,c.maxX+u,c.maxY+u),p=Ih.fromPoints(t.cameraQueryGeometry).expandBy(u),f=this.grid3D.query(p.minX,p.minY,p.maxX,p.maxY,((e,r,n,i)=>function(t,e,r,n,i){for(const s of t)if(e<=s.x&&r<=s.y&&n>=s.x&&i>=s.y)return !0;const s=[new l(e,r),new l(e,i),new l(n,i),new l(n,r)];if(t.length>2)for(const e of s)if(No(t,e))return !0;for(let e=0;e<t.length-1;e++)if(Uo(t[e],t[e+1],s))return !0;return !1}(t.cameraQueryGeometry,e-u,r-u,n+u,i+u)));for(const t of f)h.push(t);h.sort(Eh);const d={};let y;for(let l=0;l<h.length;l++){const u=h[l];if(u===y)continue;y=u;const c=this.featureIndexArray.get(u);let p=null;this.loadMatchingFeature(d,c.bucketIndex,c.sourceLayerIndex,c.featureIndex,a,i.layers,i.availableImages,e,r,n,((e,r,n)=>(p||(p=zo(e)),r.queryIntersectsFeature({queryGeometry:o,feature:e,featureState:n,geometry:p,zoom:this.z,transform:t.transform,pixelsToTileUnits:s,pixelPosMatrix:t.pixelPosMatrix,unwrappedTileID:this.tileID.toUnwrapped(),getElevation:t.getElevation}))));}return d}loadMatchingFeature(t,e,r,n,i,s,a,o,l,u,c){const h=this.bucketLayerIDs[e];if(s&&!h.some((t=>s.has(t))))return;const p=this.sourceLayerCoder.decode(r),f=this.vtLayers[p].feature(n);if(i.needGeometry){const t=Po(f,!0);if(!i.filter(new Cs(this.tileID.overscaledZ),t,this.tileID.canonical))return}else if(!i.filter(new Cs(this.tileID.overscaledZ),f))return;const d=this.getId(f,p);for(let e=0;e<h.length;e++){const r=h[e];if(s&&!s.has(r))continue;const i=o[r];if(!i)continue;let p={};d&&u&&(p=u.getState(i.sourceLayer||\"_geojsonTileLayer\",d));const y=j({},l[r]);y.paint=Bh(y.paint,i.paint,f,p,a),y.layout=Bh(y.layout,i.layout,f,p,a);const m=!c||c(f,i,p);if(!m)continue;const g=new Ph(f,this.z,this.x,this.y,d);g.layer=y;let x=t[r];void 0===x&&(x=t[r]=[]),x.push({featureIndex:n,feature:g,intersectionZ:m});}}lookupSymbolFeatures(t,e,r,n,i,s,a,o){const l={};this.loadVTLayers();const u=di(i);for(const i of t)this.loadMatchingFeature(l,r,n,i,u,s,a,o,e);return l}hasLayer(t){for(const e of this.bucketLayerIDs)for(const r of e)if(t===r)return !0;return !1}getId(t,e){var r;let n=t.id;return this.promoteId&&(n=t.properties[\"string\"==typeof this.promoteId?this.promoteId:this.promoteId[e]],\"boolean\"==typeof n&&(n=Number(n)),void 0===n&&(null===(r=t.properties)||void 0===r?void 0:r.cluster)&&this.promoteId&&(n=Number(t.properties.cluster_id))),n}}function Bh(t,e,r,n,i){return U(t,((t,s)=>{const a=e instanceof Ds?e.get(s):null;return a&&a.evaluate?a.evaluate(r,n,i):a}))}function Eh(t,e){return e-t}function Th(t,e,r,n,i){const s=[];for(let a=0;a<t.length;a++){const o=t[a];let u;for(let t=0;t<o.length-1;t++){let a=o[t],c=o[t+1];a.x<e&&c.x<e||(a.x<e?a=new l(e,a.y+(e-a.x)/(c.x-a.x)*(c.y-a.y))._round():c.x<e&&(c=new l(e,a.y+(e-a.x)/(c.x-a.x)*(c.y-a.y))._round()),a.y<r&&c.y<r||(a.y<r?a=new l(a.x+(r-a.y)/(c.y-a.y)*(c.x-a.x),r)._round():c.y<r&&(c=new l(a.x+(r-a.y)/(c.y-a.y)*(c.x-a.x),r)._round()),a.x>=n&&c.x>=n||(a.x>=n?a=new l(n,a.y+(n-a.x)/(c.x-a.x)*(c.y-a.y))._round():c.x>=n&&(c=new l(n,a.y+(n-a.x)/(c.x-a.x)*(c.y-a.y))._round()),a.y>=i&&c.y>=i||(a.y>=i?a=new l(a.x+(i-a.y)/(c.y-a.y)*(c.x-a.x),i)._round():c.y>=i&&(c=new l(a.x+(i-a.y)/(c.y-a.y)*(c.x-a.x),i)._round()),u&&a.equals(u[u.length-1])||(u=[a],s.push(u)),u.push(c)))));}}return s}us(\"FeatureIndex\",Ch,{omit:[\"rawTileData\",\"sourceLayerCoder\"]});class Vh extends l{constructor(t,e,r,n){super(t,e),this.angle=r,void 0!==n&&(this.segment=n);}clone(){return new Vh(this.x,this.y,this.angle,this.segment)}}function Fh(t,e,r,n,i){if(void 0===e.segment||0===r)return !0;let s=e,a=e.segment+1,o=0;for(;o>-r/2;){if(a--,a<0)return !1;o-=t[a].dist(s),s=t[a];}o+=t[a].dist(t[a+1]),a++;const l=[];let u=0;for(;o<r/2;){const e=t[a],r=t[a+1];if(!r)return !1;let s=t[a-1].angleTo(e)-e.angleTo(r);for(s=Math.abs((s+3*Math.PI)%(2*Math.PI)-Math.PI),l.push({distance:o,angleDelta:s}),u+=s;o-l[0].distance>n;)u-=l.shift().angleDelta;if(u>i)return !1;a++,o+=e.dist(r);}return !0}function Lh(t){let e=0;for(let r=0;r<t.length-1;r++)e+=t[r].dist(t[r+1]);return e}function $h(t,e,r){return t?.6*e*r:0}function Dh(t,e){return Math.max(t?t.right-t.left:0,e?e.right-e.left:0)}function Oh(t,e,r,n,i,s){const a=$h(r,i,s),o=Dh(r,n)*s;let l=0;const u=Lh(t)/2;for(let r=0;r<t.length-1;r++){const n=t[r],i=t[r+1],s=n.dist(i);if(l+s>u){const c=(u-l)/s,h=gr.number(n.x,i.x,c),p=gr.number(n.y,i.y,c),f=new Vh(h,p,i.angleTo(n),r);return f._round(),!a||Fh(t,f,o,a,e)?f:void 0}l+=s;}}function Rh(t,e,r,n,i,s,a,o,l){const u=$h(n,s,a),c=Dh(n,i),h=c*a,p=0===t[0].x||t[0].x===l||0===t[0].y||t[0].y===l;return e-h<e/4&&(e=h+e/4),jh(t,p?e/2*o%e:(c/2+2*s)*a*o%e,e,u,r,h,p,!1,l)}function jh(t,e,r,n,i,s,a,o,l){const u=s/2,c=Lh(t);let h=0,p=e-r,f=[];for(let e=0;e<t.length-1;e++){const a=t[e],o=t[e+1],d=a.dist(o),y=o.angleTo(a);for(;p+r<h+d;){p+=r;const m=(p-h)/d,g=gr.number(a.x,o.x,m),x=gr.number(a.y,o.y,m);if(g>=0&&g<l&&x>=0&&x<l&&p-u>=0&&p+u<=c){const r=new Vh(g,x,y,e);r._round(),n&&!Fh(t,r,s,n,i)||f.push(r);}}h+=d;}return o||f.length||a||(f=jh(t,h/2,r,n,i,s,a,!0,l)),f}function Nh(t,e,r,n){const i=[],s=t.image,a=s.pixelRatio,o=s.paddedRect.w-2,u=s.paddedRect.h-2;let c={x1:t.left,y1:t.top,x2:t.right,y2:t.bottom};const h=s.stretchX||[[0,o]],p=s.stretchY||[[0,u]],f=(t,e)=>t+e[1]-e[0],d=h.reduce(f,0),y=p.reduce(f,0),m=o-d,g=u-y;let x=0,v=d,b=0,w=y,_=0,S=m,A=0,k=g;if(s.content&&n){const e=s.content,r=e[2]-e[0],n=e[3]-e[1];(s.textFitWidth||s.textFitHeight)&&(c=Dc(t)),x=Uh(h,0,e[0]),b=Uh(p,0,e[1]),v=Uh(h,e[0],e[2]),w=Uh(p,e[1],e[3]),_=e[0]-x,A=e[1]-b,S=r-v,k=n-w;}const M=c.x1,I=c.y1,z=c.x2-M,P=c.y2-I,C=(t,n,i,o)=>{const u=Gh(t.stretch-x,v,z,M),c=Xh(t.fixed-_,S,t.stretch,d),h=Gh(n.stretch-b,w,P,I),p=Xh(n.fixed-A,k,n.stretch,y),f=Gh(i.stretch-x,v,z,M),m=Xh(i.fixed-_,S,i.stretch,d),g=Gh(o.stretch-b,w,P,I),C=Xh(o.fixed-A,k,o.stretch,y),B=new l(u,h),E=new l(f,h),T=new l(f,g),V=new l(u,g),F=new l(c/a,p/a),L=new l(m/a,C/a),$=e*Math.PI/180;if($){const t=Math.sin($),e=Math.cos($),r=[e,-t,t,e];B._matMult(r),E._matMult(r),V._matMult(r),T._matMult(r);}const D=t.stretch+t.fixed,O=n.stretch+n.fixed;return {tl:B,tr:E,bl:V,br:T,tex:{x:s.paddedRect.x+1+D,y:s.paddedRect.y+1+O,w:i.stretch+i.fixed-D,h:o.stretch+o.fixed-O},writingMode:void 0,glyphOffset:[0,0],sectionIndex:0,pixelOffsetTL:F,pixelOffsetBR:L,minFontScaleX:S/a/z,minFontScaleY:k/a/P,isSDF:r}};if(n&&(s.stretchX||s.stretchY)){const t=qh(h,m,d),e=qh(p,g,y);for(let r=0;r<t.length-1;r++){const n=t[r],s=t[r+1];for(let t=0;t<e.length-1;t++)i.push(C(n,e[t],s,e[t+1]));}}else i.push(C({fixed:0,stretch:-1},{fixed:0,stretch:-1},{fixed:0,stretch:o+1},{fixed:0,stretch:u+1}));return i}function Uh(t,e,r){let n=0;for(const i of t)n+=Math.max(e,Math.min(r,i[1]))-Math.max(e,Math.min(r,i[0]));return n}function qh(t,e,r){const n=[{fixed:-1,stretch:0}];for(const[e,r]of t){const t=n[n.length-1];n.push({fixed:e-t.stretch,stretch:t.stretch}),n.push({fixed:e-t.stretch,stretch:t.stretch+(r-e)});}return n.push({fixed:e+1,stretch:r}),n}function Gh(t,e,r,n){return t/e*r+n}function Xh(t,e,r,n){return t-e*r/n}us(\"Anchor\",Vh);class Zh{constructor(t,e,r,n,i,s,a,o,u,c){var h;if(this.boxStartIndex=t.length,u){let t=s.top,e=s.bottom;const r=s.collisionPadding;r&&(t-=r[1],e+=r[3]);let n=e-t;n>0&&(n=Math.max(10,n),this.circleDiameter=n);}else {const u=(null===(h=s.image)||void 0===h?void 0:h.content)&&(s.image.textFitWidth||s.image.textFitHeight)?Dc(s):{x1:s.left,y1:s.top,x2:s.right,y2:s.bottom};u.y1=u.y1*a-o[0],u.y2=u.y2*a+o[2],u.x1=u.x1*a-o[3],u.x2=u.x2*a+o[1];const p=s.collisionPadding;if(p&&(u.x1-=p[0]*a,u.y1-=p[1]*a,u.x2+=p[2]*a,u.y2+=p[3]*a),c){const t=new l(u.x1,u.y1),e=new l(u.x2,u.y1),r=new l(u.x1,u.y2),n=new l(u.x2,u.y2),i=c*Math.PI/180;t._rotate(i),e._rotate(i),r._rotate(i),n._rotate(i),u.x1=Math.min(t.x,e.x,r.x,n.x),u.x2=Math.max(t.x,e.x,r.x,n.x),u.y1=Math.min(t.y,e.y,r.y,n.y),u.y2=Math.max(t.y,e.y,r.y,n.y);}t.emplaceBack(e.x,e.y,u.x1,u.y1,u.x2,u.y2,r,n,i);}this.boxEndIndex=t.length;}}class Yh{constructor(t=[],e=(t,e)=>t<e?-1:t>e?1:0){if(this.data=t,this.length=this.data.length,this.compare=e,this.length>0)for(let t=(this.length>>1)-1;t>=0;t--)this._down(t);}push(t){this.data.push(t),this._up(this.length++);}pop(){if(0===this.length)return;const t=this.data[0],e=this.data.pop();return --this.length>0&&(this.data[0]=e,this._down(0)),t}peek(){return this.data[0]}_up(t){const{data:e,compare:r}=this,n=e[t];for(;t>0;){const i=t-1>>1,s=e[i];if(r(n,s)>=0)break;e[t]=s,t=i;}e[t]=n;}_down(t){const{data:e,compare:r}=this,n=this.length>>1,i=e[t];for(;t<n;){let n=1+(t<<1);const s=n+1;if(s<this.length&&r(e[s],e[n])<0&&(n=s),r(e[n],i)>=0)break;e[t]=e[n],t=n;}e[t]=i;}}function Hh(t,e=1,r=!1){const n=Ih.fromPoints(t[0]),i=Math.min(n.width(),n.height());let s=i/2;const a=new Yh([],Kh),{minX:o,minY:u,maxX:c,maxY:h}=n;if(0===i)return new l(o,u);for(let e=o;e<c;e+=i)for(let r=u;r<h;r+=i)a.push(new Jh(e+s,r+s,s,t));let p=function(t){let e=0,r=0,n=0;const i=t[0];for(let t=0,s=i.length,a=s-1;t<s;a=t++){const s=i[t],o=i[a],l=s.x*o.y-o.x*s.y;r+=(s.x+o.x)*l,n+=(s.y+o.y)*l,e+=3*l;}return new Jh(r/e,n/e,0,t)}(t),f=a.length;for(;a.length;){const n=a.pop();(n.d>p.d||!p.d)&&(p=n,r&&console.log(\"found best %d after %d probes\",Math.round(1e4*n.d)/1e4,f)),n.max-p.d<=e||(s=n.h/2,a.push(new Jh(n.p.x-s,n.p.y-s,s,t)),a.push(new Jh(n.p.x+s,n.p.y-s,s,t)),a.push(new Jh(n.p.x-s,n.p.y+s,s,t)),a.push(new Jh(n.p.x+s,n.p.y+s,s,t)),f+=4);}return r&&(console.log(`num probes: ${f}`),console.log(`best distance: ${p.d}`)),p.p}function Kh(t,e){return e.max-t.max}function Jh(t,e,r,n){this.p=new l(t,e),this.h=r,this.d=function(t,e){let r=!1,n=1/0;for(let i=0;i<e.length;i++){const s=e[i];for(let e=0,i=s.length,a=i-1;e<i;a=e++){const i=s[e],o=s[a];i.y>t.y!=o.y>t.y&&t.x<(o.x-i.x)*(t.y-i.y)/(o.y-i.y)+i.x&&(r=!r),n=Math.min(n,Ro(t,i,o));}}return (r?1:-1)*Math.sqrt(n)}(this.p,n),this.max=this.d+this.h*Math.SQRT2;}var Wh;t.aD=void 0,(Wh=t.aD||(t.aD={}))[Wh.center=1]=\"center\",Wh[Wh.left=2]=\"left\",Wh[Wh.right=3]=\"right\",Wh[Wh.top=4]=\"top\",Wh[Wh.bottom=5]=\"bottom\",Wh[Wh[\"top-left\"]=6]=\"top-left\",Wh[Wh[\"top-right\"]=7]=\"top-right\",Wh[Wh[\"bottom-left\"]=8]=\"bottom-left\",Wh[Wh[\"bottom-right\"]=9]=\"bottom-right\";const Qh=Number.POSITIVE_INFINITY;function tp(t,e){return e[1]!==Qh?function(t,e,r){let n=0,i=0;switch(e=Math.abs(e),r=Math.abs(r),t){case \"top-right\":case \"top-left\":case \"top\":i=r-7;break;case \"bottom-right\":case \"bottom-left\":case \"bottom\":i=7-r;}switch(t){case \"top-right\":case \"bottom-right\":case \"right\":n=-e;break;case \"top-left\":case \"bottom-left\":case \"left\":n=e;}return [n,i]}(t,e[0],e[1]):function(t,e){let r=0,n=0;e<0&&(e=0);const i=e/Math.SQRT2;switch(t){case \"top-right\":case \"top-left\":n=i-7;break;case \"bottom-right\":case \"bottom-left\":n=7-i;break;case \"bottom\":n=7-e;break;case \"top\":n=e-7;}switch(t){case \"top-right\":case \"bottom-right\":r=-i;break;case \"top-left\":case \"bottom-left\":r=i;break;case \"left\":r=e;break;case \"right\":r=-e;}return [r,n]}(t,e[0])}function ep(t,e,r){var n;const i=t.layout,s=null===(n=i.get(\"text-variable-anchor-offset\"))||void 0===n?void 0:n.evaluate(e,{},r);if(s){const t=s.values,e=[];for(let r=0;r<t.length;r+=2){const n=e[r]=t[r],i=t[r+1].map((t=>t*ac));n.startsWith(\"top\")?i[1]-=7:n.startsWith(\"bottom\")&&(i[1]+=7),e[r+1]=i;}return new Oe(e)}const a=i.get(\"text-variable-anchor\");if(a){let n;n=void 0!==t._unevaluatedLayout.getValue(\"text-radial-offset\")?[i.get(\"text-radial-offset\").evaluate(e,{},r)*ac,Qh]:i.get(\"text-offset\").evaluate(e,{},r).map((t=>t*ac));const s=[];for(const t of a)s.push(t,tp(t,n));return new Oe(s)}return null}function rp(t){switch(t){case \"right\":case \"top-right\":case \"bottom-right\":return \"right\";case \"left\":case \"top-left\":case \"bottom-left\":return \"left\"}return \"center\"}function np(e,r,n,i,s,a,o,l,u,c,h,p){let f=a.textMaxSize.evaluate(r,{});void 0===f&&(f=o);const d=e.layers[0].layout,y=d.get(\"icon-offset\").evaluate(r,{},h),m=sp(n.horizontal),g=o/24,x=e.tilePixelRatio*g,v=e.tilePixelRatio*f/24,b=e.tilePixelRatio*l,w=e.tilePixelRatio*d.get(\"symbol-spacing\"),_=d.get(\"text-padding\")*e.tilePixelRatio,S=function(t,e,r,n=1){const i=t.get(\"icon-padding\").evaluate(e,{},r),s=i&&i.values;return [s[0]*n,s[1]*n,s[2]*n,s[3]*n]}(d,r,h,e.tilePixelRatio),A=d.get(\"text-max-angle\")/180*Math.PI,k=\"viewport\"!==d.get(\"text-rotation-alignment\")&&\"point\"!==d.get(\"symbol-placement\"),M=\"map\"===d.get(\"icon-rotation-alignment\")&&\"point\"!==d.get(\"symbol-placement\"),I=d.get(\"symbol-placement\"),z=w/2,P=d.get(\"icon-text-fit\");let C;i&&\"none\"!==P&&(e.allowVerticalPlacement&&n.vertical&&(C=Oc(i,n.vertical,P,d.get(\"icon-text-fit-padding\"),y,g)),m&&(i=Oc(i,m,P,d.get(\"icon-text-fit-padding\"),y,g)));const B=h?p.line.getGranularityForZoomLevel(h.z):1,T=(l,p)=>{p.x<0||p.x>=E||p.y<0||p.y>=E||function(e,r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g,x,v,b,w,_,S,A,k){const M=e.addToLineVertexArray(r,n);let I,z,P,C,B=0,E=0,T=0,V=0,F=-1,L=-1;const $={};let D=so(\"\");if(e.allowVerticalPlacement&&i.vertical){const t=l.layout.get(\"text-rotate\").evaluate(w,{},A)+90;P=new Zh(u,r,c,h,p,i.vertical,f,d,y,t),o&&(C=new Zh(u,r,c,h,p,o,g,x,y,t));}if(s){const n=l.layout.get(\"icon-rotate\").evaluate(w,{}),i=\"none\"!==l.layout.get(\"icon-text-fit\"),a=Nh(s,n,S,i),f=o?Nh(o,n,S,i):void 0;z=new Zh(u,r,c,h,p,s,g,x,!1,n),B=4*a.length;const d=e.iconSizeData;let y=null;\"source\"===d.kind?(y=[Rc*l.layout.get(\"icon-size\").evaluate(w,{})],y[0]>jc&&Z(`${e.layerIds[0]}: Value for \"icon-size\" is >= 255. Reduce your \"icon-size\".`)):\"composite\"===d.kind&&(y=[Rc*_.compositeIconSizes[0].evaluate(w,{},A),Rc*_.compositeIconSizes[1].evaluate(w,{},A)],(y[0]>jc||y[1]>jc)&&Z(`${e.layerIds[0]}: Value for \"icon-size\" is >= 255. Reduce your \"icon-size\".`)),e.addSymbols(e.icon,a,y,b,v,w,t.an.none,r,M.lineStartIndex,M.lineLength,-1,A),F=e.icon.placedSymbolArray.length-1,f&&(E=4*f.length,e.addSymbols(e.icon,f,y,b,v,w,t.an.vertical,r,M.lineStartIndex,M.lineLength,-1,A),L=e.icon.placedSymbolArray.length-1);}const O=Object.keys(i.horizontal);for(const n of O){const s=i.horizontal[n];if(!I){D=so(s.text);const t=l.layout.get(\"text-rotate\").evaluate(w,{},A);I=new Zh(u,r,c,h,p,s,f,d,y,t);}const o=1===s.positionedLines.length;if(T+=ip(e,r,s,a,l,y,w,m,M,i.vertical?t.an.horizontal:t.an.horizontalOnly,o?O:[n],$,F,_,A),o)break}i.vertical&&(V+=ip(e,r,i.vertical,a,l,y,w,m,M,t.an.vertical,[\"vertical\"],$,L,_,A));const R=I?I.boxStartIndex:e.collisionBoxArray.length,j=I?I.boxEndIndex:e.collisionBoxArray.length,N=P?P.boxStartIndex:e.collisionBoxArray.length,U=P?P.boxEndIndex:e.collisionBoxArray.length,q=z?z.boxStartIndex:e.collisionBoxArray.length,G=z?z.boxEndIndex:e.collisionBoxArray.length,X=C?C.boxStartIndex:e.collisionBoxArray.length,Y=C?C.boxEndIndex:e.collisionBoxArray.length;let H=-1;const K=(t,e)=>t&&t.circleDiameter?Math.max(t.circleDiameter,e):e;H=K(I,H),H=K(P,H),H=K(z,H),H=K(C,H);const J=H>-1?1:0;J&&(H*=k/ac),e.glyphOffsetArray.length>=Jc.MAX_GLYPHS&&Z(\"Too many glyphs being rendered in a tile. See https://github.com/mapbox/mapbox-gl-js/issues/2907\"),void 0!==w.sortKey&&e.addToSortKeyRanges(e.symbolInstances.length,w.sortKey);const W=ep(l,w,A),[Q,tt]=function(e,r){const n=e.length,i=null==r?void 0:r.values;if((null==i?void 0:i.length)>0)for(let r=0;r<i.length;r+=2){const n=i[r+1];e.emplaceBack(t.aD[i[r]],n[0],n[1]);}return [n,e.length]}(e.textAnchorOffsets,W);e.symbolInstances.emplaceBack(r.x,r.y,$.right>=0?$.right:-1,$.center>=0?$.center:-1,$.left>=0?$.left:-1,$.vertical||-1,F,L,D,R,j,N,U,q,G,X,Y,c,T,V,B,E,J,0,f,H,Q,tt);}(e,p,l,n,i,s,C,e.layers[0],e.collisionBoxArray,r.index,r.sourceLayerIndex,e.index,x,[_,_,_,_],k,u,b,S,M,y,r,a,c,h,o);};if(\"line\"===I)for(const t of Th(r.geometry,0,0,E,E)){const r=Ql(t,B),s=Rh(r,w,A,n.vertical||m,i,24,v,e.overscaling,E);for(const t of s)m&&ap(e,m.text,z,t)||T(r,t);}else if(\"line-center\"===I){for(const t of r.geometry)if(t.length>1){const e=Ql(t,B),r=Oh(e,A,n.vertical||m,i,24,v);r&&T(e,r);}}else if(\"Polygon\"===r.type)for(const t of rn(r.geometry,0)){const e=Hh(t,16);T(Ql(t[0],B,!0),new Vh(e.x,e.y,0));}else if(\"LineString\"===r.type)for(const t of r.geometry){const e=Ql(t,B);T(e,new Vh(e[0].x,e[0].y,0));}else if(\"Point\"===r.type)for(const t of r.geometry)for(const e of t)T([e],new Vh(e.x,e.y,0));}function ip(t,e,r,n,i,s,a,o,u,c,h,p,f,d,y){const m=function(t,e,r,n,i,s,a,o){const u=n.layout.get(\"text-rotate\").evaluate(s,{})*Math.PI/180,c=[];for(const t of e.positionedLines)for(const n of t.positionedGlyphs){if(!n.rect)continue;const s=n.rect||{};let h=4,p=!0,f=1,d=0;const y=(i||o)&&n.vertical,m=n.metrics.advance*n.scale/2;if(o&&e.verticalizable&&(d=t.lineOffset/2-(n.imageName?-(ac-n.metrics.width*n.scale)/2:(n.scale-1)*ac)),n.imageName){const t=a[n.imageName];p=t.sdf,f=t.pixelRatio,h=1/f;}const g=i?[n.x+m,n.y]:[0,0];let x=i?[0,0]:[n.x+m+r[0],n.y+r[1]-d],v=[0,0];y&&(v=x,x=[0,0]);const b=n.metrics.isDoubleResolution?2:1,w=(n.metrics.left-h)*n.scale-m+x[0],_=(-n.metrics.top-h)*n.scale+x[1],S=w+s.w/b*n.scale/f,A=_+s.h/b*n.scale/f,k=new l(w,_),M=new l(S,_),I=new l(w,A),z=new l(S,A);if(y){const t=new l(-m,m- -17),e=-Math.PI/2,r=12-m,i=new l(22-r,-(n.imageName?r:0)),s=new l(...v);k._rotateAround(e,t)._add(i)._add(s),M._rotateAround(e,t)._add(i)._add(s),I._rotateAround(e,t)._add(i)._add(s),z._rotateAround(e,t)._add(i)._add(s);}if(u){const t=Math.sin(u),e=Math.cos(u),r=[e,-t,t,e];k._matMult(r),M._matMult(r),I._matMult(r),z._matMult(r);}const P=new l(0,0),C=new l(0,0);c.push({tl:k,tr:M,bl:I,br:z,tex:s,writingMode:e.writingMode,glyphOffset:g,sectionIndex:n.sectionIndex,isSDF:p,pixelOffsetTL:P,pixelOffsetBR:C,minFontScaleX:0,minFontScaleY:0});}return c}(0,r,o,i,s,a,n,t.allowVerticalPlacement),g=t.textSizeData;let x=null;\"source\"===g.kind?(x=[Rc*i.layout.get(\"text-size\").evaluate(a,{})],x[0]>jc&&Z(`${t.layerIds[0]}: Value for \"text-size\" is >= 255. Reduce your \"text-size\".`)):\"composite\"===g.kind&&(x=[Rc*d.compositeTextSizes[0].evaluate(a,{},y),Rc*d.compositeTextSizes[1].evaluate(a,{},y)],(x[0]>jc||x[1]>jc)&&Z(`${t.layerIds[0]}: Value for \"text-size\" is >= 255. Reduce your \"text-size\".`)),t.addSymbols(t.text,m,x,o,s,a,c,e,u.lineStartIndex,u.lineLength,f,y);for(const e of h)p[e]=t.text.placedSymbolArray.length-1;return 4*m.length}function sp(t){for(const e in t)return t[e];return null}function ap(t,e,r,n){const i=t.compareText;if(e in i){const t=i[e];for(let e=t.length-1;e>=0;e--)if(n.dist(t[e])<r)return !0}else i[e]=[];return i[e].push(n),!1}const op=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];class lp{static from(t){if(!(t instanceof ArrayBuffer))throw new Error(\"Data must be an instance of ArrayBuffer.\");const[e,r]=new Uint8Array(t,0,2);if(219!==e)throw new Error(\"Data does not appear to be in a KDBush format.\");const n=r>>4;if(1!==n)throw new Error(`Got v${n} data when expected v1.`);const i=op[15&r];if(!i)throw new Error(\"Unrecognized array type.\");const[s]=new Uint16Array(t,2,1),[a]=new Uint32Array(t,4,1);return new lp(a,s,i,t)}constructor(t,e=64,r=Float64Array,n){if(isNaN(t)||t<0)throw new Error(`Unpexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.ArrayType=r,this.IndexArrayType=t<65536?Uint16Array:Uint32Array;const i=op.indexOf(this.ArrayType),s=2*t*this.ArrayType.BYTES_PER_ELEMENT,a=t*this.IndexArrayType.BYTES_PER_ELEMENT,o=(8-a%8)%8;if(i<0)throw new Error(`Unexpected typed array class: ${r}.`);n&&n instanceof ArrayBuffer?(this.data=n,this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+o,2*t),this._pos=2*t,this._finished=!0):(this.data=new ArrayBuffer(8+s+a+o),this.ids=new this.IndexArrayType(this.data,8,t),this.coords=new this.ArrayType(this.data,8+a+o,2*t),this._pos=0,this._finished=!1,new Uint8Array(this.data,0,2).set([219,16+i]),new Uint16Array(this.data,2,1)[0]=e,new Uint32Array(this.data,4,1)[0]=t);}add(t,e){const r=this._pos>>1;return this.ids[r]=r,this.coords[this._pos++]=t,this.coords[this._pos++]=e,r}finish(){const t=this._pos>>1;if(t!==this.numItems)throw new Error(`Added ${t} items when expected ${this.numItems}.`);return up(this.ids,this.coords,this.nodeSize,0,this.numItems-1,0),this._finished=!0,this}range(t,e,r,n){if(!this._finished)throw new Error(\"Data not yet indexed - call index.finish().\");const{ids:i,coords:s,nodeSize:a}=this,o=[0,i.length-1,0],l=[];for(;o.length;){const u=o.pop()||0,c=o.pop()||0,h=o.pop()||0;if(c-h<=a){for(let a=h;a<=c;a++){const o=s[2*a],u=s[2*a+1];o>=t&&o<=r&&u>=e&&u<=n&&l.push(i[a]);}continue}const p=h+c>>1,f=s[2*p],d=s[2*p+1];f>=t&&f<=r&&d>=e&&d<=n&&l.push(i[p]),(0===u?t<=f:e<=d)&&(o.push(h),o.push(p-1),o.push(1-u)),(0===u?r>=f:n>=d)&&(o.push(p+1),o.push(c),o.push(1-u));}return l}within(t,e,r){if(!this._finished)throw new Error(\"Data not yet indexed - call index.finish().\");const{ids:n,coords:i,nodeSize:s}=this,a=[0,n.length-1,0],o=[],l=r*r;for(;a.length;){const u=a.pop()||0,c=a.pop()||0,h=a.pop()||0;if(c-h<=s){for(let r=h;r<=c;r++)fp(i[2*r],i[2*r+1],t,e)<=l&&o.push(n[r]);continue}const p=h+c>>1,f=i[2*p],d=i[2*p+1];fp(f,d,t,e)<=l&&o.push(n[p]),(0===u?t-r<=f:e-r<=d)&&(a.push(h),a.push(p-1),a.push(1-u)),(0===u?t+r>=f:e+r>=d)&&(a.push(p+1),a.push(c),a.push(1-u));}return o}}function up(t,e,r,n,i,s){if(i-n<=r)return;const a=n+i>>1;cp(t,e,a,n,i,s),up(t,e,r,n,a-1,1-s),up(t,e,r,a+1,i,1-s);}function cp(t,e,r,n,i,s){for(;i>n;){if(i-n>600){const a=i-n+1,o=r-n+1,l=Math.log(a),u=.5*Math.exp(2*l/3),c=.5*Math.sqrt(l*u*(a-u)/a)*(o-a/2<0?-1:1);cp(t,e,r,Math.max(n,Math.floor(r-o*u/a+c)),Math.min(i,Math.floor(r+(a-o)*u/a+c)),s);}const a=e[2*r+s];let o=n,l=i;for(hp(t,e,n,r),e[2*i+s]>a&&hp(t,e,n,i);o<l;){for(hp(t,e,o,l),o++,l--;e[2*o+s]<a;)o++;for(;e[2*l+s]>a;)l--;}e[2*n+s]===a?hp(t,e,n,l):(l++,hp(t,e,l,i)),l<=r&&(n=l+1),r<=l&&(i=l-1);}}function hp(t,e,r,n){pp(t,r,n),pp(e,2*r,2*n),pp(e,2*r+1,2*n+1);}function pp(t,e,r){const n=t[e];t[e]=t[r],t[r]=n;}function fp(t,e,r,n){const i=t-r,s=e-n;return i*i+s*s}var dp;t.cw=void 0,(dp=t.cw||(t.cw={})).create=\"create\",dp.load=\"load\",dp.fullLoad=\"fullLoad\";let yp=null,mp=[];const gp=1e3/60,xp=\"loadTime\",vp=\"fullLoadTime\",bp={mark(t){performance.mark(t);},frame(t){const e=t;null!=yp&&mp.push(e-yp),yp=e;},clearMetrics(){yp=null,mp=[],performance.clearMeasures(xp),performance.clearMeasures(vp);for(const e in t.cw)performance.clearMarks(t.cw[e]);},getPerformanceMetrics(){performance.measure(xp,t.cw.create,t.cw.load),performance.measure(vp,t.cw.create,t.cw.fullLoad);const e=performance.getEntriesByName(xp)[0].duration,r=performance.getEntriesByName(vp)[0].duration,n=mp.length,i=1/(mp.reduce(((t,e)=>t+e),0)/n/1e3),s=mp.filter((t=>t>gp)).reduce(((t,e)=>t+(e-gp)/gp),0);return {loadTime:e,fullLoadTime:r,fps:i,percentDroppedFrames:s/(n+s)*100,totalFrames:n}}};t.$=E,t.A=m,t.B=function([t,e,r]){return e+=90,e*=Math.PI/180,r*=Math.PI/180,{x:t*Math.cos(e)*Math.sin(r),y:t*Math.sin(e)*Math.sin(r),z:t*Math.cos(r)}},t.C=gr,t.D=Os,t.E=bt,t.F=Cs,t.G=ns,t.H=function(t){if(null==K){const e=t.navigator?t.navigator.userAgent:null;K=!!t.safari||!(!e||!(/\\b(iPad|iPhone|iPod)\\b/.test(e)||e.match(\"Safari\")&&!e.match(\"Chrome\")));}return K},t.I=mc,t.J=class{constructor(t,e){this.target=t,this.mapId=e,this.resolveRejects={},this.tasks={},this.taskQueue=[],this.abortControllers={},this.messageHandlers={},this.invoker=new ch((()=>this.process())),this.subscription=rt(this.target,\"message\",(t=>this.receive(t)),!1),this.globalScope=H(self)?t:window;}registerMessageHandler(t,e){this.messageHandlers[t]=e;}sendAsync(t,e){return new Promise(((r,n)=>{const i=Math.round(1e18*Math.random()).toString(36).substring(0,10),s=e?rt(e.signal,\"abort\",(()=>{null==s||s.unsubscribe(),delete this.resolveRejects[i];const e={id:i,type:\"<cancel>\",origin:location.origin,targetMapId:t.targetMapId,sourceMapId:this.mapId};this.target.postMessage(e);}),hh):null;this.resolveRejects[i]={resolve:t=>{null==s||s.unsubscribe(),r(t);},reject:t=>{null==s||s.unsubscribe(),n(t);}};const a=[],o=Object.assign(Object.assign({},t),{id:i,sourceMapId:this.mapId,origin:location.origin,data:fs(t.data,a)});this.target.postMessage(o,{transfer:a});}))}receive(t){const e=t.data,r=e.id;if(!(\"file://\"!==e.origin&&\"file://\"!==location.origin&&\"resource://android\"!==e.origin&&\"resource://android\"!==location.origin&&e.origin!==location.origin||e.targetMapId&&this.mapId!==e.targetMapId)){if(\"<cancel>\"===e.type){delete this.tasks[r];const t=this.abortControllers[r];return delete this.abortControllers[r],void(t&&t.abort())}if(H(self)||e.mustQueue)return this.tasks[r]=e,this.taskQueue.push(r),void this.invoker.trigger();this.processTask(r,e);}}process(){if(0===this.taskQueue.length)return;const t=this.taskQueue.shift(),e=this.tasks[t];delete this.tasks[t],this.taskQueue.length>0&&this.invoker.trigger(),e&&this.processTask(t,e);}processTask(t,r){return e(this,void 0,void 0,(function*(){if(\"<response>\"===r.type){const e=this.resolveRejects[t];if(delete this.resolveRejects[t],!e)return;return void(r.error?e.reject(ds(r.error)):e.resolve(ds(r.data)))}if(!this.messageHandlers[r.type])return void this.completeTask(t,new Error(`Could not find a registered handler for ${r.type}, map ID: ${this.mapId}, available handlers: ${Object.keys(this.messageHandlers).join(\", \")}`));const e=ds(r.data),n=new AbortController;this.abortControllers[t]=n;try{const i=yield this.messageHandlers[r.type](r.sourceMapId,e,n);this.completeTask(t,null,i);}catch(e){this.completeTask(t,e);}}))}completeTask(t,e,r){const n=[];delete this.abortControllers[t];const i={id:t,type:\"<response>\",sourceMapId:this.mapId,origin:location.origin,error:e?fs(e):null,data:fs(r,n)};this.target.postMessage(i,{transfer:n});}remove(){this.invoker.remove(),this.subscription.unsubscribe();}},t.K=ht,t.L=function(){var t=new m(16);return m!=Float32Array&&(t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=0,t[12]=0,t[13]=0,t[14]=0),t[0]=1,t[5]=1,t[10]=1,t[15]=1,t},t.M=function(t,e,r){var n,i,s,a,o,l,u,c,h,p,f,d,y=r[0],m=r[1],g=r[2];return e===t?(t[12]=e[0]*y+e[4]*m+e[8]*g+e[12],t[13]=e[1]*y+e[5]*m+e[9]*g+e[13],t[14]=e[2]*y+e[6]*m+e[10]*g+e[14],t[15]=e[3]*y+e[7]*m+e[11]*g+e[15]):(i=e[1],s=e[2],a=e[3],o=e[4],l=e[5],u=e[6],c=e[7],h=e[8],p=e[9],f=e[10],d=e[11],t[0]=n=e[0],t[1]=i,t[2]=s,t[3]=a,t[4]=o,t[5]=l,t[6]=u,t[7]=c,t[8]=h,t[9]=p,t[10]=f,t[11]=d,t[12]=n*y+o*m+h*g+e[12],t[13]=i*y+l*m+p*g+e[13],t[14]=s*y+u*m+f*g+e[14],t[15]=a*y+c*m+d*g+e[15]),t},t.N=function(t,e,r){var n=r[0],i=r[1],s=r[2];return t[0]=e[0]*n,t[1]=e[1]*n,t[2]=e[2]*n,t[3]=e[3]*n,t[4]=e[4]*i,t[5]=e[5]*i,t[6]=e[6]*i,t[7]=e[7]*i,t[8]=e[8]*s,t[9]=e[9]*s,t[10]=e[10]*s,t[11]=e[11]*s,t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},t.O=function(t,e,r){var n=e[0],i=e[1],s=e[2],a=e[3],o=e[4],l=e[5],u=e[6],c=e[7],h=e[8],p=e[9],f=e[10],d=e[11],y=e[12],m=e[13],g=e[14],x=e[15],v=r[0],b=r[1],w=r[2],_=r[3];return t[0]=v*n+b*o+w*h+_*y,t[1]=v*i+b*l+w*p+_*m,t[2]=v*s+b*u+w*f+_*g,t[3]=v*a+b*c+w*d+_*x,t[4]=(v=r[4])*n+(b=r[5])*o+(w=r[6])*h+(_=r[7])*y,t[5]=v*i+b*l+w*p+_*m,t[6]=v*s+b*u+w*f+_*g,t[7]=v*a+b*c+w*d+_*x,t[8]=(v=r[8])*n+(b=r[9])*o+(w=r[10])*h+(_=r[11])*y,t[9]=v*i+b*l+w*p+_*m,t[10]=v*s+b*u+w*f+_*g,t[11]=v*a+b*c+w*d+_*x,t[12]=(v=r[12])*n+(b=r[13])*o+(w=r[14])*h+(_=r[15])*y,t[13]=v*i+b*l+w*p+_*m,t[14]=v*s+b*u+w*f+_*g,t[15]=v*a+b*c+w*d+_*x,t},t.P=l,t.Q=function(t,e){const r={};for(let n=0;n<e.length;n++){const i=e[n];i in t&&(r[i]=t[i]);}return r},t.R=sl,t.S=fh,t.T=dl,t.U=gh,t.V=mh,t.W=f,t.X=d,t.Y=Q,t.Z=kh,t._=e,t.a=ut,t.a$=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t[2]=e[2]*r,t[3]=e[3]*r,t},t.a0=wh,t.a1=Ih,t.a2=25,t.a3=Sh,t.a4=t=>{const e=window.document.createElement(\"video\");return e.muted=!0,new Promise((r=>{e.onloadstart=()=>{r(e);};for(const r of t){const t=window.document.createElement(\"source\");yt(r)||(e.crossOrigin=\"Anonymous\"),t.src=r,e.appendChild(t);}}))},t.a5=Tt,t.a6=function(){return N++},t.a7=_a,t.a8=Jc,t.a9=di,t.aA=ac,t.aB=T,t.aC=function(t,e,r,n,i=!1){if(!r[0]&&!r[1])return [0,0];const s=i?\"map\"===n?-t.bearingInRadians:0:\"viewport\"===n?t.bearingInRadians:0;if(s){const t=Math.sin(s),e=Math.cos(s);r=[r[0]*e-r[1]*t,r[0]*t+r[1]*e];}return [i?r[0]:T(e,r[0],t.zoom),i?r[1]:T(e,r[1],t.zoom)]},t.aE=Uc,t.aF=rp,t.aG=Cc,t.aH=lp,t.aI=Ks,t.aJ=Yl,t.aK=Ta,t.aL=Ha,t.aM=Ga,t.aN=R,t.aO=it,t.aP=bh,t.aQ=S,t.aR=_,t.aS=function(t){var e=new m(3);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e},t.aT=function(t,e,r){return t[0]=e[0]-r[0],t[1]=e[1]-r[1],t[2]=e[2]-r[2],t},t.aU=function(t,e){var r=e[0],n=e[1],i=e[2],s=r*r+n*n+i*i;return s>0&&(s=1/Math.sqrt(s)),t[0]=e[0]*s,t[1]=e[1]*s,t[2]=e[2]*s,t},t.aV=A,t.aW=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]},t.aX=function(t,e,r){return t[0]=e[0]*r[0],t[1]=e[1]*r[1],t[2]=e[2]*r[2],t[3]=e[3]*r[3],t},t.aY=b,t.aZ=function(t,e,r){const n=e[0]*r[0]+e[1]*r[1]+e[2]*r[2];return 0===n?null:(-(t[0]*r[0]+t[1]*r[1]+t[2]*r[2])-r[3])/n},t.a_=M,t.aa=Po,t.ab=Ph,t.ac=function(t){const e={};if(t.replace(/(?:^|(?:\\s*\\,\\s*))([^\\x00-\\x20\\(\\)<>@\\,;\\:\\\\\"\\/\\[\\]\\?\\=\\{\\}\\x7F]+)(?:\\=(?:([^\\x00-\\x20\\(\\)<>@\\,;\\:\\\\\"\\/\\[\\]\\?\\=\\{\\}\\x7F]+)|(?:\\\"((?:[^\"\\\\]|\\\\.)*)\\\")))?/g,((t,r,n,i)=>{const s=n||i;return e[r]=!s||s.toLowerCase(),\"\"})),e[\"max-age\"]){const t=parseInt(e[\"max-age\"],10);isNaN(t)?delete e[\"max-age\"]:e[\"max-age\"]=t;}return e},t.ad=nt,t.ae=function(t){return Math.pow(2,t)},t.af=x,t.ag=O,t.ah=85.051129,t.ai=xh,t.aj=function(t){return Math.log(t)/Math.LN2},t.ak=function(t){var e=t[0],r=t[1];return e*e+r*r},t.al=function(t,e){const r=[];for(const n in t)n in e||r.push(n);return r},t.am=function(t,e){let r=0,n=0;if(\"constant\"===t.kind)n=t.layoutSize;else if(\"source\"!==t.kind){const{interpolationType:i,minZoom:s,maxZoom:a}=t,o=i?O(yr.interpolationFactor(i,e,s,a),0,1):0;\"camera\"===t.kind?n=gr.number(t.minSize,t.maxSize,o):r=o;}return {uSizeT:r,uSize:n}},t.ao=function(t,{uSize:e,uSizeT:r},{lowerSize:n,upperSize:i}){return \"source\"===t.kind?n/Rc:\"composite\"===t.kind?gr.number(n/Rc,i/Rc,r):e},t.ap=function(t,e){var r=e[0],n=e[1],i=e[2],s=e[3],a=e[4],o=e[5],l=e[6],u=e[7],c=e[8],h=e[9],p=e[10],f=e[11],d=e[12],y=e[13],m=e[14],g=e[15],x=r*o-n*a,v=r*l-i*a,b=r*u-s*a,w=n*l-i*o,_=n*u-s*o,S=i*u-s*l,A=c*y-h*d,k=c*m-p*d,M=c*g-f*d,I=h*m-p*y,z=h*g-f*y,P=p*g-f*m,C=x*P-v*z+b*I+w*M-_*k+S*A;return C?(t[0]=(o*P-l*z+u*I)*(C=1/C),t[1]=(i*z-n*P-s*I)*C,t[2]=(y*S-m*_+g*w)*C,t[3]=(p*_-h*S-f*w)*C,t[4]=(l*M-a*P-u*k)*C,t[5]=(r*P-i*M+s*k)*C,t[6]=(m*b-d*S-g*v)*C,t[7]=(c*S-p*b+f*v)*C,t[8]=(a*z-o*M+u*A)*C,t[9]=(n*M-r*z-s*A)*C,t[10]=(d*_-y*b+g*x)*C,t[11]=(h*b-c*_-f*x)*C,t[12]=(o*k-a*I-l*A)*C,t[13]=(r*I-n*k+i*A)*C,t[14]=(y*v-d*w-m*x)*C,t[15]=(c*w-h*v+p*x)*C,t):null},t.aq=C,t.ar=function(t){return Math.hypot(t[0],t[1])},t.as=function(t){return t[0]=0,t[1]=0,t},t.at=function(t,e,r){return t[0]=e[0]*r,t[1]=e[1]*r,t},t.au=Zc,t.av=I,t.aw=function(t,e,r,n){const i=e.y-t.y,s=e.x-t.x,a=n.y-r.y,o=n.x-r.x,u=a*s-o*i;if(0===u)return null;const c=(o*(t.y-r.y)-a*(t.x-r.x))/u;return new l(t.x+c*s,t.y+c*i)},t.ax=Th,t.ay=To,t.az=function(t){let e=1/0,r=1/0,n=-1/0,i=-1/0;for(const s of t)e=Math.min(e,s.x),r=Math.min(r,s.y),n=Math.max(n,s.x),i=Math.max(i,s.y);return [e,r,n,i]},t.b=J,t.b$=tc,t.b0=function(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]},t.b1=Ah,t.b2=Mh,t.b3=function(t,e,r,n,i){var s,a=1/Math.tan(e/2);return t[0]=a/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[11]=-1,t[12]=0,t[13]=0,t[15]=0,null!=i&&i!==1/0?(t[10]=(i+n)*(s=1/(n-i)),t[14]=2*i*n*s):(t[10]=-1,t[14]=-2*n),t},t.b4=function(t){var e=new m(16);return e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e},t.b5=function(t,e,r){var n=Math.sin(r),i=Math.cos(r),s=e[0],a=e[1],o=e[2],l=e[3],u=e[4],c=e[5],h=e[6],p=e[7];return e!==t&&(t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t[0]=s*i+u*n,t[1]=a*i+c*n,t[2]=o*i+h*n,t[3]=l*i+p*n,t[4]=u*i-s*n,t[5]=c*i-a*n,t[6]=h*i-o*n,t[7]=p*i-l*n,t},t.b6=function(t,e,r){var n=Math.sin(r),i=Math.cos(r),s=e[4],a=e[5],o=e[6],l=e[7],u=e[8],c=e[9],h=e[10],p=e[11];return e!==t&&(t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t[4]=s*i+u*n,t[5]=a*i+c*n,t[6]=o*i+h*n,t[7]=l*i+p*n,t[8]=u*i-s*n,t[9]=c*i-a*n,t[10]=h*i-o*n,t[11]=p*i-l*n,t},t.b7=function(){const t=new Float32Array(16);return x(t),t},t.b8=function(){const t=new Float64Array(16);return x(t),t},t.b9=function(){return new Float64Array(16)},t.bA=function(t){return t[0]=0,t[1]=0,t[2]=0,t},t.bB=function(t,e,r,n){const i=Math.sqrt(t*t+e*e),s=Math.sqrt(r*r+n*n);t/=i,e/=i,r/=s,n/=s;const a=Math.acos(t*r+e*n);return -e*r+t*n>0?a:-a},t.bC=function(t,e){const r=V(t,2*Math.PI),n=V(e,2*Math.PI);return Math.min(Math.abs(r-n),Math.abs(r-n+2*Math.PI),Math.abs(r-n-2*Math.PI))},t.bD=function(){const t={},e=wt.$version;for(const r in wt.$root){const n=wt.$root[r];if(n.required){let i=null;i=\"version\"===r?e:\"array\"===n.type?[]:{},null!=i&&(t[r]=i);}}return t},t.bE=ys,t.bF=ft,t.bG=function t(e,r){if(Array.isArray(e)){if(!Array.isArray(r)||e.length!==r.length)return !1;for(let n=0;n<e.length;n++)if(!t(e[n],r[n]))return !1;return !0}if(\"object\"==typeof e&&null!==e&&null!==r){if(\"object\"!=typeof r)return !1;if(Object.keys(e).length!==Object.keys(r).length)return !1;for(const n in e)if(!t(e[n],r[n]))return !1;return !0}return e===r},t.bH=function(t){t=t.slice();const e=Object.create(null);for(let r=0;r<t.length;r++)e[t[r].id]=t[r];for(let r=0;r<t.length;r++)\"ref\"in t[r]&&(t[r]=St(t[r],e[t[r].ref]));return t},t.bI=function(t){if(\"custom\"===t.type)return new uh(t);switch(t.type){case \"background\":return new sh(t);case \"circle\":return new Ko(t);case \"color-relief\":return new gl(t);case \"fill\":return new ou(t);case \"fill-extrusion\":return new Eu(t);case \"heatmap\":return new ll(t);case \"hillshade\":return new hl(t);case \"line\":return new Yu(t);case \"raster\":return new lh(t);case \"symbol\":return new rh(t)}},t.bJ=G,t.bK=function(t,e){if(!t)return [{command:\"setStyle\",args:[e]}];let r=[];try{if(!At(t.version,e.version))return [{command:\"setStyle\",args:[e]}];At(t.center,e.center)||r.push({command:\"setCenter\",args:[e.center]}),At(t.state,e.state)||r.push({command:\"setGlobalState\",args:[e.state]}),At(t.centerAltitude,e.centerAltitude)||r.push({command:\"setCenterAltitude\",args:[e.centerAltitude]}),At(t.zoom,e.zoom)||r.push({command:\"setZoom\",args:[e.zoom]}),At(t.bearing,e.bearing)||r.push({command:\"setBearing\",args:[e.bearing]}),At(t.pitch,e.pitch)||r.push({command:\"setPitch\",args:[e.pitch]}),At(t.roll,e.roll)||r.push({command:\"setRoll\",args:[e.roll]}),At(t.sprite,e.sprite)||r.push({command:\"setSprite\",args:[e.sprite]}),At(t.glyphs,e.glyphs)||r.push({command:\"setGlyphs\",args:[e.glyphs]}),At(t.transition,e.transition)||r.push({command:\"setTransition\",args:[e.transition]}),At(t.light,e.light)||r.push({command:\"setLight\",args:[e.light]}),At(t.terrain,e.terrain)||r.push({command:\"setTerrain\",args:[e.terrain]}),At(t.sky,e.sky)||r.push({command:\"setSky\",args:[e.sky]}),At(t.projection,e.projection)||r.push({command:\"setProjection\",args:[e.projection]});const n={},i=[];!function(t,e,r,n){let i;for(i in e=e||{},t=t||{})Object.prototype.hasOwnProperty.call(t,i)&&(Object.prototype.hasOwnProperty.call(e,i)||It(i,r,n));for(i in e)Object.prototype.hasOwnProperty.call(e,i)&&(Object.prototype.hasOwnProperty.call(t,i)?At(t[i],e[i])||(\"geojson\"===t[i].type&&\"geojson\"===e[i].type&&Pt(t,e,i)?kt(r,{command:\"setGeoJSONSourceData\",args:[i,e[i].data]}):zt(i,e,r,n)):Mt(i,e,r));}(t.sources,e.sources,i,n);const s=[];t.layers&&t.layers.forEach((t=>{\"source\"in t&&n[t.source]?r.push({command:\"removeLayer\",args:[t.id]}):s.push(t);})),r=r.concat(i),function(t,e,r){e=e||[];const n=(t=t||[]).map(Bt),i=e.map(Bt),s=t.reduce(Et,{}),a=e.reduce(Et,{}),o=n.slice(),l=Object.create(null);let u,c,h,p,f;for(let t=0,e=0;t<n.length;t++)u=n[t],Object.prototype.hasOwnProperty.call(a,u)?e++:(kt(r,{command:\"removeLayer\",args:[u]}),o.splice(o.indexOf(u,e),1));for(let t=0,e=0;t<i.length;t++)u=i[i.length-1-t],o[o.length-1-t]!==u&&(Object.prototype.hasOwnProperty.call(s,u)?(kt(r,{command:\"removeLayer\",args:[u]}),o.splice(o.lastIndexOf(u,o.length-e),1)):e++,p=o[o.length-t],kt(r,{command:\"addLayer\",args:[a[u],p]}),o.splice(o.length-t,0,u),l[u]=!0);for(let t=0;t<i.length;t++)if(u=i[t],c=s[u],h=a[u],!l[u]&&!At(c,h))if(At(c.source,h.source)&&At(c[\"source-layer\"],h[\"source-layer\"])&&At(c.type,h.type)){for(f in Ct(c.layout,h.layout,r,u,null,\"setLayoutProperty\"),Ct(c.paint,h.paint,r,u,null,\"setPaintProperty\"),At(c.filter,h.filter)||kt(r,{command:\"setFilter\",args:[u,h.filter]}),At(c.minzoom,h.minzoom)&&At(c.maxzoom,h.maxzoom)||kt(r,{command:\"setLayerZoomRange\",args:[u,h.minzoom,h.maxzoom]}),c)Object.prototype.hasOwnProperty.call(c,f)&&\"layout\"!==f&&\"paint\"!==f&&\"filter\"!==f&&\"metadata\"!==f&&\"minzoom\"!==f&&\"maxzoom\"!==f&&(0===f.indexOf(\"paint.\")?Ct(c[f],h[f],r,u,f.slice(6),\"setPaintProperty\"):At(c[f],h[f])||kt(r,{command:\"setLayerProperty\",args:[u,f,h[f]]}));for(f in h)Object.prototype.hasOwnProperty.call(h,f)&&!Object.prototype.hasOwnProperty.call(c,f)&&\"layout\"!==f&&\"paint\"!==f&&\"filter\"!==f&&\"metadata\"!==f&&\"minzoom\"!==f&&\"maxzoom\"!==f&&(0===f.indexOf(\"paint.\")?Ct(c[f],h[f],r,u,f.slice(6),\"setPaintProperty\"):At(c[f],h[f])||kt(r,{command:\"setLayerProperty\",args:[u,f,h[f]]}));}else kt(r,{command:\"removeLayer\",args:[u]}),p=o[o.lastIndexOf(u)+1],kt(r,{command:\"addLayer\",args:[h,p]});}(s,e.layers,r);}catch(t){console.warn(\"Unable to compute style diff:\",t),r=[{command:\"setStyle\",args:[e]}];}return r},t.bL=function(t){const e=[],r=t.id;return void 0===r&&e.push({message:`layers.${r}: missing required property \"id\"`}),void 0===t.render&&e.push({message:`layers.${r}: missing required method \"render\"`}),t.renderingMode&&\"2d\"!==t.renderingMode&&\"3d\"!==t.renderingMode&&e.push({message:`layers.${r}: property \"renderingMode\" must be either \"2d\" or \"3d\"`}),e},t.bM=U,t.bN=q,t.bO=class extends co{constructor(t,e){super(t,e),this.current=0;}set(t){this.current!==t&&(this.current=t,this.gl.uniform1i(this.location,t));}},t.bP=fo,t.bQ=class extends co{constructor(t,e){super(t,e),this.current=yo;}set(t){if(t[12]!==this.current[12]||t[0]!==this.current[0])return this.current=t,void this.gl.uniformMatrix4fv(this.location,!1,t);for(let e=1;e<16;e++)if(t[e]!==this.current[e]){this.current=t,this.gl.uniformMatrix4fv(this.location,!1,t);break}}},t.bR=po,t.bS=class extends co{constructor(t,e){super(t,e),this.current=[0,0,0];}set(t){t[0]===this.current[0]&&t[1]===this.current[1]&&t[2]===this.current[2]||(this.current=t,this.gl.uniform3f(this.location,t[0],t[1],t[2]));}},t.bT=class extends co{constructor(t,e){super(t,e),this.current=[0,0];}set(t){t[0]===this.current[0]&&t[1]===this.current[1]||(this.current=t,this.gl.uniform2f(this.location,t[0],t[1]));}},t.bU=g,t.bV=function(t,e){var r=Math.sin(e),n=Math.cos(e);return t[0]=n,t[1]=r,t[2]=0,t[3]=-r,t[4]=n,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},t.bW=function(t,e,r){var n=e[0],i=e[1],s=e[2];return t[0]=n*r[0]+i*r[3]+s*r[6],t[1]=n*r[1]+i*r[4]+s*r[7],t[2]=n*r[2]+i*r[5]+s*r[8],t},t.bX=function(t,e,r,n,i,s,a){var o=1/(e-r),l=1/(n-i),u=1/(s-a);return t[0]=-2*o,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*l,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*u,t[11]=0,t[12]=(e+r)*o,t[13]=(i+n)*l,t[14]=(a+s)*u,t[15]=1,t},t.bY=class extends co{constructor(t,e){super(t,e),this.current=new Array;}set(t){if(t!=this.current){this.current=t;const e=new Float32Array(4*t.length);for(let r=0;r<t.length;r++)e[4*r]=t[r].r,e[4*r+1]=t[r].g,e[4*r+2]=t[r].b,e[4*r+3]=t[r].a;this.gl.uniform4fv(this.location,e);}}},t.bZ=class extends co{constructor(t,e){super(t,e),this.current=new Array;}set(t){if(t!=this.current){this.current=t;const e=new Float32Array(t);this.gl.uniform1fv(this.location,e);}}},t.b_=class extends ca{},t.ba=function(t,e,r){const n=new Float64Array(4);return P(n,t,e-90,r),n},t.bb=function(t,e,r,n){var i,s,a,o,l,u=e[0],c=e[1],h=e[2],p=e[3],f=r[0],d=r[1],m=r[2],g=r[3];return (s=u*f+c*d+h*m+p*g)<0&&(s=-s,f=-f,d=-d,m=-m,g=-g),1-s>y?(i=Math.acos(s),a=Math.sin(i),o=Math.sin((1-n)*i)/a,l=Math.sin(n*i)/a):(o=1-n,l=n),t[0]=o*u+l*f,t[1]=o*c+l*d,t[2]=o*h+l*m,t[3]=o*p+l*g,t},t.bc=function(t){const e=new Float64Array(9);var r,n,i,s,a,o,l,u,c,h,p,f,d,y,m,g,x,v;h=(i=(n=t)[0])*(l=i+i),p=(s=n[1])*l,d=(a=n[2])*l,y=a*(u=s+s),g=(o=n[3])*l,x=o*u,v=o*(c=a+a),(r=e)[0]=1-(f=s*u)-(m=a*c),r[3]=p-v,r[6]=d+x,r[1]=p+v,r[4]=1-h-m,r[7]=y-g,r[2]=d-x,r[5]=y+g,r[8]=1-h-f;const b=it(-Math.asin(O(e[2],-1,1)));let w,_;return Math.hypot(e[5],e[8])<.001?(w=0,_=-it(Math.atan2(e[3],e[4]))):(w=it(0===e[5]&&0===e[8]?0:Math.atan2(e[5],e[8])),_=it(0===e[1]&&0===e[0]?0:Math.atan2(e[1],e[0]))),{roll:w,pitch:b+90,bearing:_}},t.bd=function(t,e){return t.roll==e.roll&&t.pitch==e.pitch&&t.bearing==e.bearing},t.be=Pe,t.bf=ho,t.bg=Hl,t.bh=Kl,t.bi=Zl,t.bj=F,t.bk=L,t.bl=je,t.bm=function(t,e,r,n,i){return F(n,i,O((t-e)/(r-e),0,1))},t.bn=V,t.bo=function(){return new Float64Array(3)},t.bp=function(t,e,r,n){return t[0]=e[0]+r[0]*n,t[1]=e[1]+r[1]*n,t[2]=e[2]+r[2]*n,t},t.bq=P,t.br=function(t,e,r){var n=r[0],i=r[1],s=r[2],a=e[0],o=e[1],l=e[2],u=i*l-s*o,c=s*a-n*l,h=n*o-i*a,p=i*h-s*c,f=s*u-n*h,d=n*c-i*u,y=2*r[3];return c*=y,h*=y,f*=2,d*=2,t[0]=a+(u*=y)+(p*=2),t[1]=o+c+f,t[2]=l+h+d,t},t.bs=function(t,e,r){const n=(i=[t[0],t[1],t[2],e[0],e[1],e[2],r[0],r[1],r[2]])[0]*((c=i[8])*(a=i[4])-(o=i[5])*(u=i[7]))+i[1]*(-c*(s=i[3])+o*(l=i[6]))+i[2]*(u*s-a*l);var i,s,a,o,l,u,c;if(0===n)return null;const h=A([],[e[0],e[1],e[2]],[r[0],r[1],r[2]]),p=A([],[r[0],r[1],r[2]],[t[0],t[1],t[2]]),f=A([],[t[0],t[1],t[2]],[e[0],e[1],e[2]]),d=S([],h,-t[3]);return _(d,d,S([],p,-e[3])),_(d,d,S([],f,-r[3])),S(d,d,1/n),d},t.bt=ph,t.bu=function(){return new Float64Array(4)},t.bv=function(t,e,r,n){var i=[],s=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],s[0]=i[0]*Math.cos(n)-i[1]*Math.sin(n),s[1]=i[0]*Math.sin(n)+i[1]*Math.cos(n),s[2]=i[2],t[0]=s[0]+r[0],t[1]=s[1]+r[1],t[2]=s[2]+r[2],t},t.bw=function(t,e,r,n){var i=[],s=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],s[0]=i[0],s[1]=i[1]*Math.cos(n)-i[2]*Math.sin(n),s[2]=i[1]*Math.sin(n)+i[2]*Math.cos(n),t[0]=s[0]+r[0],t[1]=s[1]+r[1],t[2]=s[2]+r[2],t},t.bx=function(t,e,r,n){var i=[],s=[];return i[0]=e[0]-r[0],i[1]=e[1]-r[1],i[2]=e[2]-r[2],s[0]=i[2]*Math.sin(n)+i[0]*Math.cos(n),s[1]=i[1],s[2]=i[2]*Math.cos(n)-i[0]*Math.sin(n),t[0]=s[0]+r[0],t[1]=s[1]+r[1],t[2]=s[2]+r[2],t},t.by=function(t,e,r){var n=Math.sin(r),i=Math.cos(r),s=e[0],a=e[1],o=e[2],l=e[3],u=e[8],c=e[9],h=e[10],p=e[11];return e!==t&&(t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15]),t[0]=s*i-u*n,t[1]=a*i-c*n,t[2]=o*i-h*n,t[3]=l*i-p*n,t[8]=s*n+u*i,t[9]=a*n+c*i,t[10]=o*n+h*i,t[11]=l*n+p*i,t},t.bz=function(t,e){const r=V(t,360),n=V(e,360),i=n-r,s=n>r?i-360:i+360;return Math.abs(i)<Math.abs(s)?i:s},t.c=lt,t.c0=class extends pa{},t.c1=ol,t.c2=function(t){return t<=1?1:Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))},t.c3=al,t.c4=function(t,e,r){var n=e[0],i=e[1],s=e[2],a=r[3]*n+r[7]*i+r[11]*s+r[15];return t[0]=(r[0]*n+r[4]*i+r[8]*s+r[12])/(a=a||1),t[1]=(r[1]*n+r[5]*i+r[9]*s+r[13])/a,t[2]=(r[2]*n+r[6]*i+r[10]*s+r[14])/a,t},t.c5=class extends ta{},t.c6=class extends va{},t.c7=function(t,e){return t[0]===e[0]&&t[1]===e[1]&&t[2]===e[2]&&t[3]===e[3]&&t[4]===e[4]&&t[5]===e[5]&&t[6]===e[6]&&t[7]===e[7]&&t[8]===e[8]&&t[9]===e[9]&&t[10]===e[10]&&t[11]===e[11]&&t[12]===e[12]&&t[13]===e[13]&&t[14]===e[14]&&t[15]===e[15]},t.c8=function(t,e){var r=t[0],n=t[1],i=t[2],s=t[3],a=t[4],o=t[5],l=t[6],u=t[7],c=t[8],h=t[9],p=t[10],f=t[11],d=t[12],m=t[13],g=t[14],x=t[15],v=e[0],b=e[1],w=e[2],_=e[3],S=e[4],A=e[5],k=e[6],M=e[7],I=e[8],z=e[9],P=e[10],C=e[11],B=e[12],E=e[13],T=e[14],V=e[15];return Math.abs(r-v)<=y*Math.max(1,Math.abs(r),Math.abs(v))&&Math.abs(n-b)<=y*Math.max(1,Math.abs(n),Math.abs(b))&&Math.abs(i-w)<=y*Math.max(1,Math.abs(i),Math.abs(w))&&Math.abs(s-_)<=y*Math.max(1,Math.abs(s),Math.abs(_))&&Math.abs(a-S)<=y*Math.max(1,Math.abs(a),Math.abs(S))&&Math.abs(o-A)<=y*Math.max(1,Math.abs(o),Math.abs(A))&&Math.abs(l-k)<=y*Math.max(1,Math.abs(l),Math.abs(k))&&Math.abs(u-M)<=y*Math.max(1,Math.abs(u),Math.abs(M))&&Math.abs(c-I)<=y*Math.max(1,Math.abs(c),Math.abs(I))&&Math.abs(h-z)<=y*Math.max(1,Math.abs(h),Math.abs(z))&&Math.abs(p-P)<=y*Math.max(1,Math.abs(p),Math.abs(P))&&Math.abs(f-C)<=y*Math.max(1,Math.abs(f),Math.abs(C))&&Math.abs(d-B)<=y*Math.max(1,Math.abs(d),Math.abs(B))&&Math.abs(m-E)<=y*Math.max(1,Math.abs(m),Math.abs(E))&&Math.abs(g-T)<=y*Math.max(1,Math.abs(g),Math.abs(T))&&Math.abs(x-V)<=y*Math.max(1,Math.abs(x),Math.abs(V))},t.c9=function(t,e){return t[0]=e[0],t[1]=e[1],t[2]=e[2],t[3]=e[3],t[4]=e[4],t[5]=e[5],t[6]=e[6],t[7]=e[7],t[8]=e[8],t[9]=e[9],t[10]=e[10],t[11]=e[11],t[12]=e[12],t[13]=e[13],t[14]=e[14],t[15]=e[15],t},t.cA=function(t){delete ut.REGISTERED_PROTOCOLS[t];},t.cB=function(t,e){const r={};for(let n=0;n<t.length;n++){const i=e&&e[t[n].id]||Si(t[n]);e&&(e[t[n].id]=i);let s=r[i];s||(s=r[i]=[]),s.push(t[n]);}const n=[];for(const t in r)n.push(r[t]);return n},t.cC=us,t.cD=zh,t.cE=Ch,t.cF=gc,t.cG=function(e){e.bucket.createArrays(),e.bucket.tilePixelRatio=E/(512*e.bucket.overscaling),e.bucket.compareText={},e.bucket.iconsNeedLinear=!1;const r=e.bucket.layers[0],n=r.layout,i=r._unevaluatedLayout._values,s={layoutIconSize:i[\"icon-size\"].possiblyEvaluate(new Cs(e.bucket.zoom+1),e.canonical),layoutTextSize:i[\"text-size\"].possiblyEvaluate(new Cs(e.bucket.zoom+1),e.canonical),textMaxSize:i[\"text-size\"].possiblyEvaluate(new Cs(18))};if(\"composite\"===e.bucket.textSizeData.kind){const{minZoom:t,maxZoom:r}=e.bucket.textSizeData;s.compositeTextSizes=[i[\"text-size\"].possiblyEvaluate(new Cs(t),e.canonical),i[\"text-size\"].possiblyEvaluate(new Cs(r),e.canonical)];}if(\"composite\"===e.bucket.iconSizeData.kind){const{minZoom:t,maxZoom:r}=e.bucket.iconSizeData;s.compositeIconSizes=[i[\"icon-size\"].possiblyEvaluate(new Cs(t),e.canonical),i[\"icon-size\"].possiblyEvaluate(new Cs(r),e.canonical)];}const a=n.get(\"text-line-height\")*ac,o=\"viewport\"!==n.get(\"text-rotation-alignment\")&&\"point\"!==n.get(\"symbol-placement\"),l=n.get(\"text-keep-upright\"),u=n.get(\"text-size\");for(const i of e.bucket.features){const c=n.get(\"text-font\").evaluate(i,{},e.canonical).join(\",\"),h=u.evaluate(i,{},e.canonical),p=s.layoutTextSize.evaluate(i,{},e.canonical),f=s.layoutIconSize.evaluate(i,{},e.canonical),d={horizontal:{},vertical:void 0},y=i.text;let m,g=[0,0];if(y){const s=y.toString(),u=n.get(\"text-letter-spacing\").evaluate(i,{},e.canonical)*ac,f=xs(s)?u:0,m=n.get(\"text-anchor\").evaluate(i,{},e.canonical),x=ep(r,i,e.canonical);if(!x){const t=n.get(\"text-radial-offset\").evaluate(i,{},e.canonical);g=t?tp(m,[t*ac,Qh]):n.get(\"text-offset\").evaluate(i,{},e.canonical).map((t=>t*ac));}let v=o?\"center\":n.get(\"text-justify\").evaluate(i,{},e.canonical);const b=\"point\"===n.get(\"symbol-placement\")?n.get(\"text-max-width\").evaluate(i,{},e.canonical)*ac:1/0,w=()=>{e.bucket.allowVerticalPlacement&&gs(s)&&(d.vertical=bc(y,e.glyphMap,e.glyphPositions,e.imagePositions,c,b,a,m,\"left\",f,g,t.an.vertical,!0,p,h));};if(!o&&x){const r=new Set;if(\"auto\"===v)for(let t=0;t<x.values.length;t+=2)r.add(rp(x.values[t]));else r.add(v);let n=!1;for(const i of r)if(!d.horizontal[i])if(n)d.horizontal[i]=d.horizontal[0];else {const r=bc(y,e.glyphMap,e.glyphPositions,e.imagePositions,c,b,a,\"center\",i,f,g,t.an.horizontal,!1,p,h);r&&(d.horizontal[i]=r,n=1===r.positionedLines.length);}w();}else {\"auto\"===v&&(v=rp(m));const r=bc(y,e.glyphMap,e.glyphPositions,e.imagePositions,c,b,a,m,v,f,g,t.an.horizontal,!1,p,h);r&&(d.horizontal[v]=r),w(),gs(s)&&o&&l&&(d.vertical=bc(y,e.glyphMap,e.glyphPositions,e.imagePositions,c,b,a,m,v,f,g,t.an.vertical,!1,p,h));}}let x=!1;if(i.icon&&i.icon.name){const t=e.imageMap[i.icon.name];t&&(m=$c(e.imagePositions[i.icon.name],n.get(\"icon-offset\").evaluate(i,{},e.canonical),n.get(\"icon-anchor\").evaluate(i,{},e.canonical)),x=!!t.sdf,void 0===e.bucket.sdfIcons?e.bucket.sdfIcons=x:e.bucket.sdfIcons!==x&&Z(\"Style sheet warning: Cannot mix SDF and non-SDF icons in one buffer\"),(t.pixelRatio!==e.bucket.pixelRatio||0!==n.get(\"icon-rotate\").constantOr(1))&&(e.bucket.iconsNeedLinear=!0));}const v=sp(d.horizontal)||d.vertical;e.bucket.iconsInText=!!v&&v.iconsInText,(v||m)&&np(e.bucket,i,d,m,e.imageMap,s,p,f,g,x,e.canonical,e.subdivisionGranularity);}e.showCollisionBoxes&&e.bucket.generateCollisionDebugBuffers();},t.cH=Nu,t.cI=nu,t.cJ=Mu,t.cK=_u,t.cL=hc,t.cM=class{constructor(t){this._marks={start:[t.url,\"start\"].join(\"#\"),end:[t.url,\"end\"].join(\"#\"),measure:t.url.toString()},performance.mark(this._marks.start);}finish(){performance.mark(this._marks.end);let t=performance.getEntriesByName(this._marks.measure);return 0===t.length&&(performance.measure(this._marks.measure,this._marks.start,this._marks.end),t=performance.getEntriesByName(this._marks.measure),performance.clearMarks(this._marks.start),performance.clearMarks(this._marks.end),performance.clearMeasures(this._marks.measure)),t}},t.cN=function(t,r,n,i,s){return e(this,void 0,void 0,(function*(){if(d())try{return yield Q(t,r,n,i,s)}catch(t){}return function(t,e,r,n,i){const s=t.width,a=t.height;tt&&et||(tt=new OffscreenCanvas(s,a),et=tt.getContext(\"2d\",{willReadFrequently:!0})),tt.width=s,tt.height=a,et.drawImage(t,0,0,s,a);const o=et.getImageData(e,r,n,i);return et.clearRect(0,0,s,a),o.data}(t,r,n,i,s)}))},t.cO=yl,t.cP=r,t.cQ=s,t.cR=wu,t.cS=uc,t.cT=si,t.cU=Ps,t.ca=t=>\"symbol\"===t.type,t.cb=t=>\"circle\"===t.type,t.cc=t=>\"heatmap\"===t.type,t.cd=t=>\"line\"===t.type,t.ce=t=>\"fill\"===t.type,t.cf=t=>\"fill-extrusion\"===t.type,t.cg=t=>\"hillshade\"===t.type,t.ch=t=>\"color-relief\"===t.type,t.ci=t=>\"raster\"===t.type,t.cj=t=>\"background\"===t.type,t.ck=t=>\"custom\"===t.type,t.cl=$,t.cm=function(t,e,r){const n=B(e.x-r.x,e.y-r.y),i=B(t.x-r.x,t.y-r.y);var s,a;return it(Math.atan2(n[0]*i[1]-n[1]*i[0],(s=n)[0]*(a=i)[0]+s[1]*a[1]))},t.cn=D,t.co=function(t,e){return at[e]&&(t instanceof MouseEvent||t instanceof WheelEvent)},t.cp=function(t,e){return st[e]&&\"touches\"in t},t.cq=function(t){return st[t]||at[t]},t.cr=function(t,e,r){var n=e[0],i=e[1];return t[0]=r[0]*n+r[4]*i+r[12],t[1]=r[1]*n+r[5]*i+r[13],t},t.cs=function(t,e){const{x:r,y:n}=wh.fromLngLat(e);return !(t<0||t>25||n<0||n>=1||r<0||r>=1)},t.ct=function(t,e){return t[0]=e[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=e[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=e[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},t.cu=class extends Qs{},t.cv=bp,t.cx=function(t){return t.message===ot},t.cy=pt,t.cz=function(t,e){ut.REGISTERED_PROTOCOLS[t]=e;},t.d=yt,t.e=j,t.f=t=>e(void 0,void 0,void 0,(function*(){if(0===t.byteLength)return createImageBitmap(new ImageData(1,1));const e=new Blob([new Uint8Array(t)],{type:\"image/png\"});try{return createImageBitmap(e)}catch(t){throw new Error(`Could not load image because of ${t.message}. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`)}})),t.g=ct,t.h=t=>new Promise(((e,r)=>{const n=new Image;n.onload=()=>{e(n),URL.revokeObjectURL(n.src),n.onload=null,window.requestAnimationFrame((()=>{n.src=W;}));},n.onerror=()=>r(new Error(\"Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.\"));const i=new Blob([new Uint8Array(t)],{type:\"image/png\"});n.src=t.byteLength?URL.createObjectURL(i):W;})),t.i=H,t.j=(t,e)=>dt(j(t,{type:\"json\"}),e),t.k=vt,t.l=xt,t.m=dt,t.n=(t,e)=>dt(j(t,{type:\"arrayBuffer\"}),e),t.o=function(t){return new hc(t).readFields(pc,[])},t.p=yc,t.q=il,t.r=qs,t.s=rt,t.t=Ts,t.u=ms,t.v=wt,t.w=Z,t.x=rs,t.y=as,t.z=es;}));\n\ndefine(\"worker\",[\"./shared\"],(function(e){\"use strict\";class t{constructor(e){this.keyCache={},e&&this.replace(e);}replace(e){this._layerConfigs={},this._layers={},this.update(e,[]);}update(t,o){for(const o of t){this._layerConfigs[o.id]=o;const t=this._layers[o.id]=e.bI(o);t._featureFilter=e.a9(t.filter),this.keyCache[o.id]&&delete this.keyCache[o.id];}for(const e of o)delete this.keyCache[e],delete this._layerConfigs[e],delete this._layers[e];this.familiesBySource={};const i=e.cB(Object.values(this._layerConfigs),this.keyCache);for(const e of i){const t=e.map((e=>this._layers[e.id])),o=t[0];if(\"none\"===o.visibility)continue;const i=o.source||\"\";let r=this.familiesBySource[i];r||(r=this.familiesBySource[i]={});const s=o.sourceLayer||\"_geojsonTileLayer\";let n=r[s];n||(n=r[s]=[]),n.push(t);}}}class o{constructor(t){const o={},i=[];for(const e in t){const r=t[e],s=o[e]={};for(const e in r){const t=r[+e];if(!t||0===t.bitmap.width||0===t.bitmap.height)continue;const o={x:0,y:0,w:t.bitmap.width+2,h:t.bitmap.height+2};i.push(o),s[e]={rect:o,metrics:t.metrics};}}const{w:r,h:s}=e.p(i),n=new e.q({width:r||1,height:s||1});for(const i in t){const r=t[i];for(const t in r){const s=r[+t];if(!s||0===s.bitmap.width||0===s.bitmap.height)continue;const a=o[i][t].rect;e.q.copy(s.bitmap,n,{x:0,y:0},{x:a.x+1,y:a.y+1},s.bitmap);}}this.image=n,this.positions=o;}}e.cC(\"GlyphAtlas\",o);class i{constructor(t){this.tileID=new e.Z(t.tileID.overscaledZ,t.tileID.wrap,t.tileID.canonical.z,t.tileID.canonical.x,t.tileID.canonical.y),this.uid=t.uid,this.zoom=t.zoom,this.pixelRatio=t.pixelRatio,this.tileSize=t.tileSize,this.source=t.source,this.overscaling=this.tileID.overscaleFactor(),this.showCollisionBoxes=t.showCollisionBoxes,this.collectResourceTiming=!!t.collectResourceTiming,this.returnDependencies=!!t.returnDependencies,this.promoteId=t.promoteId,this.inFlightDependencies=[],this.globalState=t.globalState;}parse(t,i,s,n,a){return e._(this,void 0,void 0,(function*(){this.status=\"parsing\",this.data=t,this.collisionBoxArray=new e.a7;const l=new e.cD(Object.keys(t.layers).sort()),c=new e.cE(this.tileID,this.promoteId);c.bucketLayerIDs=[];const u={},h={featureIndex:c,iconDependencies:{},patternDependencies:{},glyphDependencies:{},availableImages:s,subdivisionGranularity:a},d=i.familiesBySource[this.source];for(const o in d){const i=t.layers[o];if(!i)continue;1===i.version&&e.w(`Vector tile source \"${this.source}\" layer \"${o}\" does not use vector tile spec v2 and therefore may have some rendering errors.`);const n=l.encode(o),a=[];for(let e=0;e<i.length;e++){const t=i.feature(e),r=c.getId(t,o);a.push({feature:t,id:r,index:e,sourceLayerIndex:n});}for(const t of d[o]){const o=t[0];o.source!==this.source&&e.w(`layer.source = ${o.source} does not equal this.source = ${this.source}`),o.minzoom&&this.zoom<Math.floor(o.minzoom)||o.maxzoom&&this.zoom>=o.maxzoom||\"none\"!==o.visibility&&(r(t,this.zoom,s),(u[o.id]=o.createBucket({index:c.bucketLayerIDs.length,layers:t,zoom:this.zoom,pixelRatio:this.pixelRatio,overscaling:this.overscaling,collisionBoxArray:this.collisionBoxArray,sourceLayerIndex:n,sourceID:this.source,globalState:this.globalState})).populate(a,h,this.tileID.canonical),c.bucketLayerIDs.push(t.map((e=>e.id))));}}const f=e.bM(h.glyphDependencies,(e=>Object.keys(e).map(Number)));this.inFlightDependencies.forEach((e=>null==e?void 0:e.abort())),this.inFlightDependencies=[];let g=Promise.resolve({});if(Object.keys(f).length){const e=new AbortController;this.inFlightDependencies.push(e),g=n.sendAsync({type:\"GG\",data:{stacks:f,source:this.source,tileID:this.tileID,type:\"glyphs\"}},e);}const p=Object.keys(h.iconDependencies);let m=Promise.resolve({});if(p.length){const e=new AbortController;this.inFlightDependencies.push(e),m=n.sendAsync({type:\"GI\",data:{icons:p,source:this.source,tileID:this.tileID,type:\"icons\"}},e);}const y=Object.keys(h.patternDependencies);let v=Promise.resolve({});if(y.length){const e=new AbortController;this.inFlightDependencies.push(e),v=n.sendAsync({type:\"GI\",data:{icons:y,source:this.source,tileID:this.tileID,type:\"patterns\"}},e);}const[w,x,b]=yield Promise.all([g,m,v]),S=new o(w),_=new e.cF(x,b);for(const t in u){const o=u[t];o instanceof e.a8?(r(o.layers,this.zoom,s),e.cG({bucket:o,glyphMap:w,glyphPositions:S.positions,imageMap:x,imagePositions:_.iconPositions,showCollisionBoxes:this.showCollisionBoxes,canonical:this.tileID.canonical,subdivisionGranularity:h.subdivisionGranularity})):o.hasPattern&&(o instanceof e.cH||o instanceof e.cI||o instanceof e.cJ)&&(r(o.layers,this.zoom,s),o.addFeatures(h,this.tileID.canonical,_.patternPositions));}return this.status=\"done\",{buckets:Object.values(u).filter((e=>!e.isEmpty())),featureIndex:c,collisionBoxArray:this.collisionBoxArray,glyphAtlasImage:S.image,imageAtlas:_,glyphMap:this.returnDependencies?w:null,iconMap:this.returnDependencies?x:null,glyphPositions:this.returnDependencies?S.positions:null}}))}}function r(t,o,i){const r=new e.F(o);for(const e of t)e.recalculate(r,i);}class s{constructor(e,t,o){this.actor=e,this.layerIndex=t,this.availableImages=o,this.fetching={},this.loading={},this.loaded={};}loadVectorTile(t,o){return e._(this,void 0,void 0,(function*(){const i=yield e.n(t.request,o);try{return {vectorTile:new e.cK.VectorTile(new e.cL(i.data)),rawData:i.data,cacheControl:i.cacheControl,expires:i.expires}}catch(e){const o=new Uint8Array(i.data);let r=`Unable to parse the tile at ${t.request.url}, `;throw r+=31===o[0]&&139===o[1]?\"please make sure the data is not gzipped and that you have configured the relevant header in the server\":`got error: ${e.message}`,new Error(r)}}))}loadTile(t){return e._(this,void 0,void 0,(function*(){const o=t.uid,r=!!(t&&t.request&&t.request.collectResourceTiming)&&new e.cM(t.request),s=new i(t);this.loading[o]=s;const n=new AbortController;s.abort=n;try{const i=yield this.loadVectorTile(t,n);if(delete this.loading[o],!i)return null;const a=i.rawData,l={};i.expires&&(l.expires=i.expires),i.cacheControl&&(l.cacheControl=i.cacheControl);const c={};if(r){const e=r.finish();e&&(c.resourceTiming=JSON.parse(JSON.stringify(e)));}s.vectorTile=i.vectorTile;const u=s.parse(i.vectorTile,this.layerIndex,this.availableImages,this.actor,t.subdivisionGranularity);this.loaded[o]=s,this.fetching[o]={rawTileData:a,cacheControl:l,resourceTiming:c};try{const t=yield u;return e.e({rawTileData:a.slice(0)},t,l,c)}finally{delete this.fetching[o];}}catch(e){throw delete this.loading[o],s.status=\"done\",this.loaded[o]=s,e}}))}reloadTile(t){return e._(this,void 0,void 0,(function*(){const o=t.uid;if(!this.loaded||!this.loaded[o])throw new Error(\"Should not be trying to reload a tile that was never loaded or has been removed\");const i=this.loaded[o];if(i.showCollisionBoxes=t.showCollisionBoxes,i.globalState=t.globalState,\"parsing\"===i.status){const r=yield i.parse(i.vectorTile,this.layerIndex,this.availableImages,this.actor,t.subdivisionGranularity);let s;if(this.fetching[o]){const{rawTileData:t,cacheControl:i,resourceTiming:n}=this.fetching[o];delete this.fetching[o],s=e.e({rawTileData:t.slice(0)},r,i,n);}else s=r;return s}if(\"done\"===i.status&&i.vectorTile)return i.parse(i.vectorTile,this.layerIndex,this.availableImages,this.actor,t.subdivisionGranularity)}))}abortTile(t){return e._(this,void 0,void 0,(function*(){const e=this.loading,o=t.uid;e&&e[o]&&e[o].abort&&(e[o].abort.abort(),delete e[o]);}))}removeTile(t){return e._(this,void 0,void 0,(function*(){this.loaded&&this.loaded[t.uid]&&delete this.loaded[t.uid];}))}}class n{constructor(){this.loaded={};}loadTile(t){return e._(this,void 0,void 0,(function*(){const{uid:o,encoding:i,rawImageData:r,redFactor:s,greenFactor:n,blueFactor:a,baseShift:l}=t,c=r.width+2,u=r.height+2,h=e.b(r)?new e.R({width:c,height:u},yield e.cN(r,-1,-1,c,u)):r,d=new e.cO(o,h,i,s,n,a,l);return this.loaded=this.loaded||{},this.loaded[o]=d,d}))}removeTile(e){const t=this.loaded,o=e.uid;t&&t[o]&&delete t[o];}}var a,l,c=function(){if(l)return a;function e(e,o){if(0!==e.length){t(e[0],o);for(var i=1;i<e.length;i++)t(e[i],!o);}}function t(e,t){for(var o=0,i=0,r=0,s=e.length,n=s-1;r<s;n=r++){var a=(e[r][0]-e[n][0])*(e[n][1]+e[r][1]),l=o+a;i+=Math.abs(o)>=Math.abs(a)?o-l+a:a-l+o,o=l;}o+i>=0!=!!t&&e.reverse();}return l=1,a=function t(o,i){var r,s=o&&o.type;if(\"FeatureCollection\"===s)for(r=0;r<o.features.length;r++)t(o.features[r],i);else if(\"GeometryCollection\"===s)for(r=0;r<o.geometries.length;r++)t(o.geometries[r],i);else if(\"Feature\"===s)t(o.geometry,i);else if(\"Polygon\"===s)e(o.coordinates,i);else if(\"MultiPolygon\"===s)for(r=0;r<o.coordinates.length;r++)e(o.coordinates[r],i);return o}}(),u=e.cP(c);const h=e.cK.VectorTileFeature.prototype.toGeoJSON;class d{constructor(t){this._feature=t,this.extent=e.$,this.type=t.type,this.properties=t.tags,\"id\"in t&&!isNaN(t.id)&&(this.id=parseInt(t.id,10));}loadGeometry(){if(1===this._feature.type){const t=[];for(const o of this._feature.geometry)t.push([new e.P(o[0],o[1])]);return t}{const t=[];for(const o of this._feature.geometry){const i=[];for(const t of o)i.push(new e.P(t[0],t[1]));t.push(i);}return t}}toGeoJSON(e,t,o){return h.call(this,e,t,o)}}class f{constructor(t){this.layers={_geojsonTileLayer:this},this.name=\"_geojsonTileLayer\",this.extent=e.$,this.length=t.length,this._features=t;}feature(e){return new d(this._features[e])}}var g,p,m,y={exports:{}},v=function(){if(m)return y.exports;m=1;var t=e.cS(),o=function(){if(p)return g;p=1;var t=e.cQ(),o=e.cR().VectorTileFeature;function i(e,t){this.options=t||{},this.features=e,this.length=e.length;}function r(e,t){this.id=\"number\"==typeof e.id?e.id:void 0,this.type=e.type,this.rawGeometry=1===e.type?[e.geometry]:e.geometry,this.properties=e.tags,this.extent=t||4096;}return g=i,i.prototype.feature=function(e){return new r(this.features[e],this.options.extent)},r.prototype.loadGeometry=function(){var e=this.rawGeometry;this.geometry=[];for(var o=0;o<e.length;o++){for(var i=e[o],r=[],s=0;s<i.length;s++)r.push(new t(i[s][0],i[s][1]));this.geometry.push(r);}return this.geometry},r.prototype.bbox=function(){this.geometry||this.loadGeometry();for(var e=this.geometry,t=1/0,o=-1/0,i=1/0,r=-1/0,s=0;s<e.length;s++)for(var n=e[s],a=0;a<n.length;a++){var l=n[a];t=Math.min(t,l.x),o=Math.max(o,l.x),i=Math.min(i,l.y),r=Math.max(r,l.y);}return [t,i,o,r]},r.prototype.toGeoJSON=o.prototype.toGeoJSON,g}();function i(e){var o=new t;return function(e,t){for(var o in e.layers)t.writeMessage(3,r,e.layers[o]);}(e,o),o.finish()}function r(e,t){var o;t.writeVarintField(15,e.version||1),t.writeStringField(1,e.name||\"\"),t.writeVarintField(5,e.extent||4096);var i={keys:[],values:[],keycache:{},valuecache:{}};for(o=0;o<e.length;o++)i.feature=e.feature(o),t.writeMessage(2,s,i);var r=i.keys;for(o=0;o<r.length;o++)t.writeStringField(3,r[o]);var n=i.values;for(o=0;o<n.length;o++)t.writeMessage(4,u,n[o]);}function s(e,t){var o=e.feature;void 0!==o.id&&t.writeVarintField(1,o.id),t.writeMessage(2,n,e),t.writeVarintField(3,o.type),t.writeMessage(4,c,o);}function n(e,t){var o=e.feature,i=e.keys,r=e.values,s=e.keycache,n=e.valuecache;for(var a in o.properties){var l=o.properties[a],c=s[a];if(null!==l){void 0===c&&(i.push(a),s[a]=c=i.length-1),t.writeVarint(c);var u=typeof l;\"string\"!==u&&\"boolean\"!==u&&\"number\"!==u&&(l=JSON.stringify(l));var h=u+\":\"+l,d=n[h];void 0===d&&(r.push(l),n[h]=d=r.length-1),t.writeVarint(d);}}}function a(e,t){return (t<<3)+(7&e)}function l(e){return e<<1^e>>31}function c(e,t){for(var o=e.loadGeometry(),i=e.type,r=0,s=0,n=o.length,c=0;c<n;c++){var u=o[c],h=1;1===i&&(h=u.length),t.writeVarint(a(1,h));for(var d=3===i?u.length-1:u.length,f=0;f<d;f++){1===f&&1!==i&&t.writeVarint(a(2,d-1));var g=u[f].x-r,p=u[f].y-s;t.writeVarint(l(g)),t.writeVarint(l(p)),r+=g,s+=p;}3===i&&t.writeVarint(a(7,1));}}function u(e,t){var o=typeof e;\"string\"===o?t.writeStringField(1,e):\"boolean\"===o?t.writeBooleanField(7,e):\"number\"===o&&(e%1!=0?t.writeDoubleField(3,e):e<0?t.writeSVarintField(6,e):t.writeVarintField(5,e));}return y.exports=i,y.exports.fromVectorTileJs=i,y.exports.fromGeojsonVt=function(e,t){t=t||{};var r={};for(var s in e)r[s]=new o(e[s].features,t),r[s].name=s,r[s].version=t.version,r[s].extent=t.extent;return i({layers:r})},y.exports.GeoJSONWrapper=o,y.exports}(),w=e.cP(v);const x={minZoom:0,maxZoom:16,minPoints:2,radius:40,extent:512,nodeSize:64,log:!1,generateId:!1,reduce:null,map:e=>e},b=Math.fround||(S=new Float32Array(1),e=>(S[0]=+e,S[0]));var S;class _{constructor(e){this.options=Object.assign(Object.create(x),e),this.trees=new Array(this.options.maxZoom+1),this.stride=this.options.reduce?7:6,this.clusterProps=[];}load(e){const{log:t,minZoom:o,maxZoom:i}=this.options;t&&console.time(\"total time\");const r=`prepare ${e.length} points`;t&&console.time(r),this.points=e;const s=[];for(let t=0;t<e.length;t++){const o=e[t];if(!o.geometry)continue;const[i,r]=o.geometry.coordinates,n=b(P(i)),a=b(k(r));s.push(n,a,1/0,t,-1,1),this.options.reduce&&s.push(0);}let n=this.trees[i+1]=this._createTree(s);t&&console.timeEnd(r);for(let e=i;e>=o;e--){const o=+Date.now();n=this.trees[e]=this._createTree(this._cluster(n,e)),t&&console.log(\"z%d: %d clusters in %dms\",e,n.numItems,+Date.now()-o);}return t&&console.timeEnd(\"total time\"),this}getClusters(e,t){let o=((e[0]+180)%360+360)%360-180;const i=Math.max(-90,Math.min(90,e[1]));let r=180===e[2]?180:((e[2]+180)%360+360)%360-180;const s=Math.max(-90,Math.min(90,e[3]));if(e[2]-e[0]>=360)o=-180,r=180;else if(o>r){const e=this.getClusters([o,i,180,s],t),n=this.getClusters([-180,i,r,s],t);return e.concat(n)}const n=this.trees[this._limitZoom(t)],a=n.range(P(o),k(s),P(r),k(i)),l=n.data,c=[];for(const e of a){const t=this.stride*e;c.push(l[t+5]>1?M(l,t,this.clusterProps):this.points[l[t+3]]);}return c}getChildren(e){const t=this._getOriginId(e),o=this._getOriginZoom(e),i=\"No cluster with the specified id.\",r=this.trees[o];if(!r)throw new Error(i);const s=r.data;if(t*this.stride>=s.length)throw new Error(i);const n=this.options.radius/(this.options.extent*Math.pow(2,o-1)),a=r.within(s[t*this.stride],s[t*this.stride+1],n),l=[];for(const t of a){const o=t*this.stride;s[o+4]===e&&l.push(s[o+5]>1?M(s,o,this.clusterProps):this.points[s[o+3]]);}if(0===l.length)throw new Error(i);return l}getLeaves(e,t,o){const i=[];return this._appendLeaves(i,e,t=t||10,o=o||0,0),i}getTile(e,t,o){const i=this.trees[this._limitZoom(e)],r=Math.pow(2,e),{extent:s,radius:n}=this.options,a=n/s,l=(o-a)/r,c=(o+1+a)/r,u={features:[]};return this._addTileFeatures(i.range((t-a)/r,l,(t+1+a)/r,c),i.data,t,o,r,u),0===t&&this._addTileFeatures(i.range(1-a/r,l,1,c),i.data,r,o,r,u),t===r-1&&this._addTileFeatures(i.range(0,l,a/r,c),i.data,-1,o,r,u),u.features.length?u:null}getClusterExpansionZoom(e){let t=this._getOriginZoom(e)-1;for(;t<=this.options.maxZoom;){const o=this.getChildren(e);if(t++,1!==o.length)break;e=o[0].properties.cluster_id;}return t}_appendLeaves(e,t,o,i,r){const s=this.getChildren(t);for(const t of s){const s=t.properties;if(s&&s.cluster?r+s.point_count<=i?r+=s.point_count:r=this._appendLeaves(e,s.cluster_id,o,i,r):r<i?r++:e.push(t),e.length===o)break}return r}_createTree(t){const o=new e.aH(t.length/this.stride|0,this.options.nodeSize,Float32Array);for(let e=0;e<t.length;e+=this.stride)o.add(t[e],t[e+1]);return o.finish(),o.data=t,o}_addTileFeatures(e,t,o,i,r,s){for(const n of e){const e=n*this.stride,a=t[e+5]>1;let l,c,u;if(a)l=I(t,e,this.clusterProps),c=t[e],u=t[e+1];else {const o=this.points[t[e+3]];l=o.properties;const[i,r]=o.geometry.coordinates;c=P(i),u=k(r);}const h={type:1,geometry:[[Math.round(this.options.extent*(c*r-o)),Math.round(this.options.extent*(u*r-i))]],tags:l};let d;d=a||this.options.generateId?t[e+3]:this.points[t[e+3]].id,void 0!==d&&(h.id=d),s.features.push(h);}}_limitZoom(e){return Math.max(this.options.minZoom,Math.min(Math.floor(+e),this.options.maxZoom+1))}_cluster(e,t){const{radius:o,extent:i,reduce:r,minPoints:s}=this.options,n=o/(i*Math.pow(2,t)),a=e.data,l=[],c=this.stride;for(let o=0;o<a.length;o+=c){if(a[o+2]<=t)continue;a[o+2]=t;const i=a[o],u=a[o+1],h=e.within(a[o],a[o+1],n),d=a[o+5];let f=d;for(const e of h){const o=e*c;a[o+2]>t&&(f+=a[o+5]);}if(f>d&&f>=s){let e,s=i*d,n=u*d,g=-1;const p=(o/c<<5)+(t+1)+this.points.length;for(const i of h){const l=i*c;if(a[l+2]<=t)continue;a[l+2]=t;const u=a[l+5];s+=a[l]*u,n+=a[l+1]*u,a[l+4]=p,r&&(e||(e=this._map(a,o,!0),g=this.clusterProps.length,this.clusterProps.push(e)),r(e,this._map(a,l)));}a[o+4]=p,l.push(s/f,n/f,1/0,p,-1,f),r&&l.push(g);}else {for(let e=0;e<c;e++)l.push(a[o+e]);if(f>1)for(const e of h){const o=e*c;if(!(a[o+2]<=t)){a[o+2]=t;for(let e=0;e<c;e++)l.push(a[o+e]);}}}}return l}_getOriginId(e){return e-this.points.length>>5}_getOriginZoom(e){return (e-this.points.length)%32}_map(e,t,o){if(e[t+5]>1){const i=this.clusterProps[e[t+6]];return o?Object.assign({},i):i}const i=this.points[e[t+3]].properties,r=this.options.map(i);return o&&r===i?Object.assign({},r):r}}function M(e,t,o){return {type:\"Feature\",id:e[t+3],properties:I(e,t,o),geometry:{type:\"Point\",coordinates:[(i=e[t],360*(i-.5)),T(e[t+1])]}};var i;}function I(e,t,o){const i=e[t+5],r=i>=1e4?`${Math.round(i/1e3)}k`:i>=1e3?Math.round(i/100)/10+\"k\":i,s=e[t+6],n=-1===s?{}:Object.assign({},o[s]);return Object.assign(n,{cluster:!0,cluster_id:e[t+3],point_count:i,point_count_abbreviated:r})}function P(e){return e/360+.5}function k(e){const t=Math.sin(e*Math.PI/180),o=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return o<0?0:o>1?1:o}function T(e){const t=(180-360*e)*Math.PI/180;return 360*Math.atan(Math.exp(t))/Math.PI-90}function D(e,t,o,i){let r=i;const s=t+(o-t>>1);let n,a=o-t;const l=e[t],c=e[t+1],u=e[o],h=e[o+1];for(let i=t+3;i<o;i+=3){const t=C(e[i],e[i+1],l,c,u,h);if(t>r)n=i,r=t;else if(t===r){const e=Math.abs(i-s);e<a&&(n=i,a=e);}}r>i&&(n-t>3&&D(e,t,n,i),e[n+2]=r,o-n>3&&D(e,n,o,i));}function C(e,t,o,i,r,s){let n=r-o,a=s-i;if(0!==n||0!==a){const l=((e-o)*n+(t-i)*a)/(n*n+a*a);l>1?(o=r,i=s):l>0&&(o+=n*l,i+=a*l);}return n=e-o,a=t-i,n*n+a*a}function O(e,t,o,i){const r={id:null==e?null:e,type:t,geometry:o,tags:i,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0};if(\"Point\"===t||\"MultiPoint\"===t||\"LineString\"===t)L(r,o);else if(\"Polygon\"===t)L(r,o[0]);else if(\"MultiLineString\"===t)for(const e of o)L(r,e);else if(\"MultiPolygon\"===t)for(const e of o)L(r,e[0]);return r}function L(e,t){for(let o=0;o<t.length;o+=3)e.minX=Math.min(e.minX,t[o]),e.minY=Math.min(e.minY,t[o+1]),e.maxX=Math.max(e.maxX,t[o]),e.maxY=Math.max(e.maxY,t[o+1]);}function F(e,t,o,i){if(!t.geometry)return;const r=t.geometry.coordinates;if(r&&0===r.length)return;const s=t.geometry.type,n=Math.pow(o.tolerance/((1<<o.maxZoom)*o.extent),2);let a=[],l=t.id;if(o.promoteId?l=t.properties[o.promoteId]:o.generateId&&(l=i||0),\"Point\"===s)G(r,a);else if(\"MultiPoint\"===s)for(const e of r)G(e,a);else if(\"LineString\"===s)z(r,a,n,!1);else if(\"MultiLineString\"===s){if(o.lineMetrics){for(const o of r)a=[],z(o,a,n,!1),e.push(O(l,\"LineString\",a,t.properties));return}A(r,a,n,!1);}else if(\"Polygon\"===s)A(r,a,n,!0);else {if(\"MultiPolygon\"!==s){if(\"GeometryCollection\"===s){for(const r of t.geometry.geometries)F(e,{id:l,geometry:r,properties:t.properties},o,i);return}throw new Error(\"Input data is not a valid GeoJSON object.\")}for(const e of r){const t=[];A(e,t,n,!0),a.push(t);}}e.push(O(l,s,a,t.properties));}function G(e,t){t.push(j(e[0]),E(e[1]),0);}function z(e,t,o,i){let r,s,n=0;for(let o=0;o<e.length;o++){const a=j(e[o][0]),l=E(e[o][1]);t.push(a,l,0),o>0&&(n+=i?(r*l-a*s)/2:Math.sqrt(Math.pow(a-r,2)+Math.pow(l-s,2))),r=a,s=l;}const a=t.length-3;t[2]=1,D(t,0,a,o),t[a+2]=1,t.size=Math.abs(n),t.start=0,t.end=t.size;}function A(e,t,o,i){for(let r=0;r<e.length;r++){const s=[];z(e[r],s,o,i),t.push(s);}}function j(e){return e/360+.5}function E(e){const t=Math.sin(e*Math.PI/180),o=.5-.25*Math.log((1+t)/(1-t))/Math.PI;return o<0?0:o>1?1:o}function Z(e,t,o,i,r,s,n,a){if(i/=t,s>=(o/=t)&&n<i)return e;if(n<o||s>=i)return null;const l=[];for(const t of e){const e=t.geometry;let s=t.type;const n=0===r?t.minX:t.minY,c=0===r?t.maxX:t.maxY;if(n>=o&&c<i){l.push(t);continue}if(c<o||n>=i)continue;let u=[];if(\"Point\"===s||\"MultiPoint\"===s)N(e,u,o,i,r);else if(\"LineString\"===s)J(e,u,o,i,r,!1,a.lineMetrics);else if(\"MultiLineString\"===s)W(e,u,o,i,r,!1);else if(\"Polygon\"===s)W(e,u,o,i,r,!0);else if(\"MultiPolygon\"===s)for(const t of e){const e=[];W(t,e,o,i,r,!0),e.length&&u.push(e);}if(u.length){if(a.lineMetrics&&\"LineString\"===s){for(const e of u)l.push(O(t.id,s,e,t.tags));continue}\"LineString\"!==s&&\"MultiLineString\"!==s||(1===u.length?(s=\"LineString\",u=u[0]):s=\"MultiLineString\"),\"Point\"!==s&&\"MultiPoint\"!==s||(s=3===u.length?\"Point\":\"MultiPoint\"),l.push(O(t.id,s,u,t.tags));}}return l.length?l:null}function N(e,t,o,i,r){for(let s=0;s<e.length;s+=3){const n=e[s+r];n>=o&&n<=i&&Y(t,e[s],e[s+1],e[s+2]);}}function J(e,t,o,i,r,s,n){let a=R(e);const l=0===r?V:q;let c,u,h=e.start;for(let d=0;d<e.length-3;d+=3){const f=e[d],g=e[d+1],p=e[d+2],m=e[d+3],y=e[d+4],v=0===r?f:g,w=0===r?m:y;let x=!1;n&&(c=Math.sqrt(Math.pow(f-m,2)+Math.pow(g-y,2))),v<o?w>o&&(u=l(a,f,g,m,y,o),n&&(a.start=h+c*u)):v>i?w<i&&(u=l(a,f,g,m,y,i),n&&(a.start=h+c*u)):Y(a,f,g,p),w<o&&v>=o&&(u=l(a,f,g,m,y,o),x=!0),w>i&&v<=i&&(u=l(a,f,g,m,y,i),x=!0),!s&&x&&(n&&(a.end=h+c*u),t.push(a),a=R(e)),n&&(h+=c);}let d=e.length-3;const f=e[d],g=e[d+1],p=0===r?f:g;p>=o&&p<=i&&Y(a,f,g,e[d+2]),d=a.length-3,s&&d>=3&&(a[d]!==a[0]||a[d+1]!==a[1])&&Y(a,a[0],a[1],a[2]),a.length&&t.push(a);}function R(e){const t=[];return t.size=e.size,t.start=e.start,t.end=e.end,t}function W(e,t,o,i,r,s){for(const n of e)J(n,t,o,i,r,s,!1);}function Y(e,t,o,i){e.push(t,o,i);}function V(e,t,o,i,r,s){const n=(s-t)/(i-t);return Y(e,s,o+(r-o)*n,1),n}function q(e,t,o,i,r,s){const n=(s-o)/(r-o);return Y(e,t+(i-t)*n,s,1),n}function H(e,t){const o=[];for(let i=0;i<e.length;i++){const r=e[i],s=r.type;let n;if(\"Point\"===s||\"MultiPoint\"===s||\"LineString\"===s)n=X(r.geometry,t);else if(\"MultiLineString\"===s||\"Polygon\"===s){n=[];for(const e of r.geometry)n.push(X(e,t));}else if(\"MultiPolygon\"===s){n=[];for(const e of r.geometry){const o=[];for(const i of e)o.push(X(i,t));n.push(o);}}o.push(O(r.id,s,n,r.tags));}return o}function X(e,t){const o=[];o.size=e.size,void 0!==e.start&&(o.start=e.start,o.end=e.end);for(let i=0;i<e.length;i+=3)o.push(e[i]+t,e[i+1],e[i+2]);return o}function B(e,t){if(e.transformed)return e;const o=1<<e.z,i=e.x,r=e.y;for(const s of e.features){const e=s.geometry,n=s.type;if(s.geometry=[],1===n)for(let n=0;n<e.length;n+=2)s.geometry.push($(e[n],e[n+1],t,o,i,r));else for(let n=0;n<e.length;n++){const a=[];for(let s=0;s<e[n].length;s+=2)a.push($(e[n][s],e[n][s+1],t,o,i,r));s.geometry.push(a);}}return e.transformed=!0,e}function $(e,t,o,i,r,s){return [Math.round(o*(e*i-r)),Math.round(o*(t*i-s))]}function U(e,t,o,i,r){const s=t===r.maxZoom?0:r.tolerance/((1<<t)*r.extent),n={features:[],numPoints:0,numSimplified:0,numFeatures:e.length,source:null,x:o,y:i,z:t,transformed:!1,minX:2,minY:1,maxX:-1,maxY:0};for(const t of e)K(n,t,s,r);return n}function K(e,t,o,i){const r=t.geometry,s=t.type,n=[];if(e.minX=Math.min(e.minX,t.minX),e.minY=Math.min(e.minY,t.minY),e.maxX=Math.max(e.maxX,t.maxX),e.maxY=Math.max(e.maxY,t.maxY),\"Point\"===s||\"MultiPoint\"===s)for(let t=0;t<r.length;t+=3)n.push(r[t],r[t+1]),e.numPoints++,e.numSimplified++;else if(\"LineString\"===s)Q(n,r,e,o,!1,!1);else if(\"MultiLineString\"===s||\"Polygon\"===s)for(let t=0;t<r.length;t++)Q(n,r[t],e,o,\"Polygon\"===s,0===t);else if(\"MultiPolygon\"===s)for(let t=0;t<r.length;t++){const i=r[t];for(let t=0;t<i.length;t++)Q(n,i[t],e,o,!0,0===t);}if(n.length){let o=t.tags||null;if(\"LineString\"===s&&i.lineMetrics){o={};for(const e in t.tags)o[e]=t.tags[e];o.mapbox_clip_start=r.start/r.size,o.mapbox_clip_end=r.end/r.size;}const a={geometry:n,type:\"Polygon\"===s||\"MultiPolygon\"===s?3:\"LineString\"===s||\"MultiLineString\"===s?2:1,tags:o};null!==t.id&&(a.id=t.id),e.features.push(a);}}function Q(e,t,o,i,r,s){const n=i*i;if(i>0&&t.size<(r?n:i))return void(o.numPoints+=t.length/3);const a=[];for(let e=0;e<t.length;e+=3)(0===i||t[e+2]>n)&&(o.numSimplified++,a.push(t[e],t[e+1])),o.numPoints++;r&&function(e,t){let o=0;for(let t=0,i=e.length,r=i-2;t<i;r=t,t+=2)o+=(e[t]-e[r])*(e[t+1]+e[r+1]);if(o>0===t)for(let t=0,o=e.length;t<o/2;t+=2){const i=e[t],r=e[t+1];e[t]=e[o-2-t],e[t+1]=e[o-1-t],e[o-2-t]=i,e[o-1-t]=r;}}(a,s),e.push(a);}const ee={maxZoom:14,indexMaxZoom:5,indexMaxPoints:1e5,tolerance:3,extent:4096,buffer:64,lineMetrics:!1,promoteId:null,generateId:!1,debug:0};class te{constructor(e,t){const o=(t=this.options=function(e,t){for(const o in t)e[o]=t[o];return e}(Object.create(ee),t)).debug;if(o&&console.time(\"preprocess data\"),t.maxZoom<0||t.maxZoom>24)throw new Error(\"maxZoom should be in the 0-24 range\");if(t.promoteId&&t.generateId)throw new Error(\"promoteId and generateId cannot be used together.\");let i=function(e,t){const o=[];if(\"FeatureCollection\"===e.type)for(let i=0;i<e.features.length;i++)F(o,e.features[i],t,i);else F(o,\"Feature\"===e.type?e:{geometry:e},t);return o}(e,t);this.tiles={},this.tileCoords=[],o&&(console.timeEnd(\"preprocess data\"),console.log(\"index: maxZoom: %d, maxPoints: %d\",t.indexMaxZoom,t.indexMaxPoints),console.time(\"generate tiles\"),this.stats={},this.total=0),i=function(e,t){const o=t.buffer/t.extent;let i=e;const r=Z(e,1,-1-o,o,0,-1,2,t),s=Z(e,1,1-o,2+o,0,-1,2,t);return (r||s)&&(i=Z(e,1,-o,1+o,0,-1,2,t)||[],r&&(i=H(r,1).concat(i)),s&&(i=i.concat(H(s,-1)))),i}(i,t),i.length&&this.splitTile(i,0,0,0),o&&(i.length&&console.log(\"features: %d, points: %d\",this.tiles[0].numFeatures,this.tiles[0].numPoints),console.timeEnd(\"generate tiles\"),console.log(\"tiles generated:\",this.total,JSON.stringify(this.stats)));}splitTile(e,t,o,i,r,s,n){const a=[e,t,o,i],l=this.options,c=l.debug;for(;a.length;){i=a.pop(),o=a.pop(),t=a.pop(),e=a.pop();const u=1<<t,h=oe(t,o,i);let d=this.tiles[h];if(!d&&(c>1&&console.time(\"creation\"),d=this.tiles[h]=U(e,t,o,i,l),this.tileCoords.push({z:t,x:o,y:i}),c)){c>1&&(console.log(\"tile z%d-%d-%d (features: %d, points: %d, simplified: %d)\",t,o,i,d.numFeatures,d.numPoints,d.numSimplified),console.timeEnd(\"creation\"));const e=`z${t}`;this.stats[e]=(this.stats[e]||0)+1,this.total++;}if(d.source=e,null==r){if(t===l.indexMaxZoom||d.numPoints<=l.indexMaxPoints)continue}else {if(t===l.maxZoom||t===r)continue;if(null!=r){const e=r-t;if(o!==s>>e||i!==n>>e)continue}}if(d.source=null,0===e.length)continue;c>1&&console.time(\"clipping\");const f=.5*l.buffer/l.extent,g=.5-f,p=.5+f,m=1+f;let y=null,v=null,w=null,x=null,b=Z(e,u,o-f,o+p,0,d.minX,d.maxX,l),S=Z(e,u,o+g,o+m,0,d.minX,d.maxX,l);e=null,b&&(y=Z(b,u,i-f,i+p,1,d.minY,d.maxY,l),v=Z(b,u,i+g,i+m,1,d.minY,d.maxY,l),b=null),S&&(w=Z(S,u,i-f,i+p,1,d.minY,d.maxY,l),x=Z(S,u,i+g,i+m,1,d.minY,d.maxY,l),S=null),c>1&&console.timeEnd(\"clipping\"),a.push(y||[],t+1,2*o,2*i),a.push(v||[],t+1,2*o,2*i+1),a.push(w||[],t+1,2*o+1,2*i),a.push(x||[],t+1,2*o+1,2*i+1);}}getTile(e,t,o){e=+e,t=+t,o=+o;const i=this.options,{extent:r,debug:s}=i;if(e<0||e>24)return null;const n=1<<e,a=oe(e,t=t+n&n-1,o);if(this.tiles[a])return B(this.tiles[a],r);s>1&&console.log(\"drilling down to z%d-%d-%d\",e,t,o);let l,c=e,u=t,h=o;for(;!l&&c>0;)c--,u>>=1,h>>=1,l=this.tiles[oe(c,u,h)];return l&&l.source?(s>1&&(console.log(\"found parent tile z%d-%d-%d\",c,u,h),console.time(\"drilling down\")),this.splitTile(l.source,c,u,h,e,t,o),s>1&&console.timeEnd(\"drilling down\"),this.tiles[a]?B(this.tiles[a],r):null):null}}function oe(e,t,o){return 32*((1<<e)*o+t)+e}function ie(e,t){return t?e.properties[t]:e.id}function re(e,t){if(null==e)return !0;if(\"Feature\"===e.type)return null!=ie(e,t);if(\"FeatureCollection\"===e.type){const o=new Set;for(const i of e.features){const e=ie(i,t);if(null==e)return !1;if(o.has(e))return !1;o.add(e);}return !0}return !1}function se(e,t){const o=new Map;if(null==e);else if(\"Feature\"===e.type)o.set(ie(e,t),e);else for(const i of e.features)o.set(ie(i,t),i);return o}class ne extends s{constructor(){super(...arguments),this._dataUpdateable=new Map;}loadVectorTile(t,o){return e._(this,void 0,void 0,(function*(){const e=t.tileID.canonical;if(!this._geoJSONIndex)throw new Error(\"Unable to parse the data into a cluster or geojson\");const o=this._geoJSONIndex.getTile(e.z,e.x,e.y);if(!o)return null;const i=new f(o.features);let r=w(i);return 0===r.byteOffset&&r.byteLength===r.buffer.byteLength||(r=new Uint8Array(r)),{vectorTile:i,rawData:r.buffer}}))}loadData(t){return e._(this,void 0,void 0,(function*(){var o;null===(o=this._pendingRequest)||void 0===o||o.abort();const i=!!(t&&t.request&&t.request.collectResourceTiming)&&new e.cM(t.request);this._pendingRequest=new AbortController;try{this._pendingData=this.loadAndProcessGeoJSON(t,this._pendingRequest),this._geoJSONIndex=t.cluster?new _(function({superclusterOptions:t,clusterProperties:o}){if(!o||!t)return t;const i={},r={},s={accumulated:null,zoom:0},n={properties:null},a=Object.keys(o);for(const t of a){const[s,n]=o[t],a=e.cT(n),l=e.cT(\"string\"==typeof s?[s,[\"accumulated\"],[\"get\",t]]:s);i[t]=a.value,r[t]=l.value;}return t.map=e=>{n.properties=e;const t={};for(const e of a)t[e]=i[e].evaluate(s,n);return t},t.reduce=(e,t)=>{n.properties=t;for(const t of a)s.accumulated=e[t],e[t]=r[t].evaluate(s,n);},t}(t)).load((yield this._pendingData).features):(r=yield this._pendingData,new te(r,t.geojsonVtOptions)),this.loaded={};const o={};if(i){const e=i.finish();e&&(o.resourceTiming={},o.resourceTiming[t.source]=JSON.parse(JSON.stringify(e)));}return o}catch(t){if(delete this._pendingRequest,e.cx(t))return {abandoned:!0};throw t}var r;}))}getData(){return e._(this,void 0,void 0,(function*(){return this._pendingData}))}reloadTile(e){const t=this.loaded;return t&&t[e.uid]?super.reloadTile(e):this.loadTile(e)}loadAndProcessGeoJSON(t,o){return e._(this,void 0,void 0,(function*(){let i=yield this.loadGeoJSON(t,o);if(delete this._pendingRequest,\"object\"!=typeof i)throw new Error(`Input data given to '${t.source}' is not a valid GeoJSON object.`);if(u(i,!0),t.filter){const o=e.cT(t.filter,{type:\"boolean\",\"property-type\":\"data-driven\",overridable:!1,transition:!1});if(\"error\"===o.result)throw new Error(o.value.map((e=>`${e.key}: ${e.message}`)).join(\", \"));const r=i.features.filter((e=>o.value.evaluate({zoom:0},e)));i={type:\"FeatureCollection\",features:r};}return i}))}loadGeoJSON(t,o){return e._(this,void 0,void 0,(function*(){const{promoteId:i}=t;if(t.request){const r=yield e.j(t.request,o);return this._dataUpdateable=re(r.data,i)?se(r.data,i):void 0,r.data}if(\"string\"==typeof t.data)try{const e=JSON.parse(t.data);return this._dataUpdateable=re(e,i)?se(e,i):void 0,e}catch(e){throw new Error(`Input data given to '${t.source}' is not a valid GeoJSON object.`)}if(!t.dataDiff)throw new Error(`Input data given to '${t.source}' is not a valid GeoJSON object.`);if(!this._dataUpdateable)throw new Error(`Cannot update existing geojson data in ${t.source}`);return function(e,t,o){var i,r,s,n;if(t.removeAll&&e.clear(),t.remove)for(const o of t.remove)e.delete(o);if(t.add)for(const i of t.add){const t=ie(i,o);null!=t&&e.set(t,i);}if(t.update)for(const o of t.update){let t=e.get(o.id);if(null==t)continue;const a=!o.removeAllProperties&&((null===(i=o.removeProperties)||void 0===i?void 0:i.length)>0||(null===(r=o.addOrUpdateProperties)||void 0===r?void 0:r.length)>0);if((o.newGeometry||o.removeAllProperties||a)&&(t=Object.assign({},t),e.set(o.id,t),a&&(t.properties=Object.assign({},t.properties))),o.newGeometry&&(t.geometry=o.newGeometry),o.removeAllProperties)t.properties={};else if((null===(s=o.removeProperties)||void 0===s?void 0:s.length)>0)for(const e of o.removeProperties)Object.prototype.hasOwnProperty.call(t.properties,e)&&delete t.properties[e];if((null===(n=o.addOrUpdateProperties)||void 0===n?void 0:n.length)>0)for(const{key:e,value:i}of o.addOrUpdateProperties)t.properties[e]=i;}}(this._dataUpdateable,t.dataDiff,i),{type:\"FeatureCollection\",features:Array.from(this._dataUpdateable.values())}}))}removeSource(t){return e._(this,void 0,void 0,(function*(){this._pendingRequest&&this._pendingRequest.abort();}))}getClusterExpansionZoom(e){return this._geoJSONIndex.getClusterExpansionZoom(e.clusterId)}getClusterChildren(e){return this._geoJSONIndex.getChildren(e.clusterId)}getClusterLeaves(e){return this._geoJSONIndex.getLeaves(e.clusterId,e.limit,e.offset)}}class ae{constructor(t){this.self=t,this.actor=new e.J(t),this.layerIndexes={},this.availableImages={},this.workerSources={},this.demWorkerSources={},this.externalWorkerSourceTypes={},this.self.registerWorkerSource=(e,t)=>{if(this.externalWorkerSourceTypes[e])throw new Error(`Worker source with name \"${e}\" already registered.`);this.externalWorkerSourceTypes[e]=t;},this.self.addProtocol=e.cz,this.self.removeProtocol=e.cA,this.self.registerRTLTextPlugin=t=>{e.cU.setMethods(t);},this.actor.registerMessageHandler(\"LDT\",((e,t)=>this._getDEMWorkerSource(e,t.source).loadTile(t))),this.actor.registerMessageHandler(\"RDT\",((t,o)=>e._(this,void 0,void 0,(function*(){this._getDEMWorkerSource(t,o.source).removeTile(o);})))),this.actor.registerMessageHandler(\"GCEZ\",((t,o)=>e._(this,void 0,void 0,(function*(){return this._getWorkerSource(t,o.type,o.source).getClusterExpansionZoom(o)})))),this.actor.registerMessageHandler(\"GCC\",((t,o)=>e._(this,void 0,void 0,(function*(){return this._getWorkerSource(t,o.type,o.source).getClusterChildren(o)})))),this.actor.registerMessageHandler(\"GCL\",((t,o)=>e._(this,void 0,void 0,(function*(){return this._getWorkerSource(t,o.type,o.source).getClusterLeaves(o)})))),this.actor.registerMessageHandler(\"LD\",((e,t)=>this._getWorkerSource(e,t.type,t.source).loadData(t))),this.actor.registerMessageHandler(\"GD\",((e,t)=>this._getWorkerSource(e,t.type,t.source).getData())),this.actor.registerMessageHandler(\"LT\",((e,t)=>this._getWorkerSource(e,t.type,t.source).loadTile(t))),this.actor.registerMessageHandler(\"RT\",((e,t)=>this._getWorkerSource(e,t.type,t.source).reloadTile(t))),this.actor.registerMessageHandler(\"AT\",((e,t)=>this._getWorkerSource(e,t.type,t.source).abortTile(t))),this.actor.registerMessageHandler(\"RMT\",((e,t)=>this._getWorkerSource(e,t.type,t.source).removeTile(t))),this.actor.registerMessageHandler(\"RS\",((t,o)=>e._(this,void 0,void 0,(function*(){if(!this.workerSources[t]||!this.workerSources[t][o.type]||!this.workerSources[t][o.type][o.source])return;const e=this.workerSources[t][o.type][o.source];delete this.workerSources[t][o.type][o.source],void 0!==e.removeSource&&e.removeSource(o);})))),this.actor.registerMessageHandler(\"RM\",(t=>e._(this,void 0,void 0,(function*(){delete this.layerIndexes[t],delete this.availableImages[t],delete this.workerSources[t],delete this.demWorkerSources[t];})))),this.actor.registerMessageHandler(\"SR\",((t,o)=>e._(this,void 0,void 0,(function*(){this.referrer=o;})))),this.actor.registerMessageHandler(\"SRPS\",((e,t)=>this._syncRTLPluginState(e,t))),this.actor.registerMessageHandler(\"IS\",((t,o)=>e._(this,void 0,void 0,(function*(){this.self.importScripts(o);})))),this.actor.registerMessageHandler(\"SI\",((e,t)=>this._setImages(e,t))),this.actor.registerMessageHandler(\"UL\",((t,o)=>e._(this,void 0,void 0,(function*(){this._getLayerIndex(t).update(o.layers,o.removedIds);})))),this.actor.registerMessageHandler(\"SL\",((t,o)=>e._(this,void 0,void 0,(function*(){this._getLayerIndex(t).replace(o);}))));}_setImages(t,o){return e._(this,void 0,void 0,(function*(){this.availableImages[t]=o;for(const e in this.workerSources[t]){const i=this.workerSources[t][e];for(const e in i)i[e].availableImages=o;}}))}_syncRTLPluginState(t,o){return e._(this,void 0,void 0,(function*(){return yield e.cU.syncState(o,this.self.importScripts)}))}_getAvailableImages(e){let t=this.availableImages[e];return t||(t=[]),t}_getLayerIndex(e){let o=this.layerIndexes[e];return o||(o=this.layerIndexes[e]=new t),o}_getWorkerSource(e,t,o){if(this.workerSources[e]||(this.workerSources[e]={}),this.workerSources[e][t]||(this.workerSources[e][t]={}),!this.workerSources[e][t][o]){const i={sendAsync:(t,o)=>(t.targetMapId=e,this.actor.sendAsync(t,o))};switch(t){case \"vector\":this.workerSources[e][t][o]=new s(i,this._getLayerIndex(e),this._getAvailableImages(e));break;case \"geojson\":this.workerSources[e][t][o]=new ne(i,this._getLayerIndex(e),this._getAvailableImages(e));break;default:this.workerSources[e][t][o]=new this.externalWorkerSourceTypes[t](i,this._getLayerIndex(e),this._getAvailableImages(e));}}return this.workerSources[e][t][o]}_getDEMWorkerSource(e,t){return this.demWorkerSources[e]||(this.demWorkerSources[e]={}),this.demWorkerSources[e][t]||(this.demWorkerSources[e][t]=new n),this.demWorkerSources[e][t]}}return e.i(self)&&(self.worker=new ae(self)),ae}));\n\ndefine(\"index\",[\"exports\",\"./shared\"],(function(e,t){\"use strict\";var i=\"5.6.0\";function o(){var e=new t.A(4);return t.A!=Float32Array&&(e[1]=0,e[2]=0),e[0]=1,e[3]=1,e}let r,a;const s={now:\"undefined\"!=typeof performance&&performance&&performance.now?performance.now.bind(performance):Date.now.bind(Date),frame(e,i,o){const r=requestAnimationFrame((e=>{a(),i(e);})),{unsubscribe:a}=t.s(e.signal,\"abort\",(()=>{a(),cancelAnimationFrame(r),o(t.c());}),!1);},frameAsync(e){return new Promise(((t,i)=>{this.frame(e,t,i);}))},getImageData(e,t=0){return this.getImageCanvasContext(e).getImageData(-t,-t,e.width+2*t,e.height+2*t)},getImageCanvasContext(e){const t=window.document.createElement(\"canvas\"),i=t.getContext(\"2d\",{willReadFrequently:!0});if(!i)throw new Error(\"failed to create canvas 2d context\");return t.width=e.width,t.height=e.height,i.drawImage(e,0,0,e.width,e.height),i},resolveURL:e=>(r||(r=document.createElement(\"a\")),r.href=e,r.href),hardwareConcurrency:\"undefined\"!=typeof navigator&&navigator.hardwareConcurrency||4,get prefersReducedMotion(){return !!matchMedia&&(null==a&&(a=matchMedia(\"(prefers-reduced-motion: reduce)\")),a.matches)}};class n{static testProp(e){if(!n.docStyle)return e[0];for(let t=0;t<e.length;t++)if(e[t]in n.docStyle)return e[t];return e[0]}static create(e,t,i){const o=window.document.createElement(e);return void 0!==t&&(o.className=t),i&&i.appendChild(o),o}static createNS(e,t){return window.document.createElementNS(e,t)}static disableDrag(){n.docStyle&&n.selectProp&&(n.userSelect=n.docStyle[n.selectProp],n.docStyle[n.selectProp]=\"none\");}static enableDrag(){n.docStyle&&n.selectProp&&(n.docStyle[n.selectProp]=n.userSelect);}static setTransform(e,t){e.style[n.transformProp]=t;}static addEventListener(e,t,i,o={}){e.addEventListener(t,i,\"passive\"in o?o:o.capture);}static removeEventListener(e,t,i,o={}){e.removeEventListener(t,i,\"passive\"in o?o:o.capture);}static suppressClickInternal(e){e.preventDefault(),e.stopPropagation(),window.removeEventListener(\"click\",n.suppressClickInternal,!0);}static suppressClick(){window.addEventListener(\"click\",n.suppressClickInternal,!0),window.setTimeout((()=>{window.removeEventListener(\"click\",n.suppressClickInternal,!0);}),0);}static getScale(e){const t=e.getBoundingClientRect();return {x:t.width/e.offsetWidth||1,y:t.height/e.offsetHeight||1,boundingClientRect:t}}static getPoint(e,i,o){const r=i.boundingClientRect;return new t.P((o.clientX-r.left)/i.x-e.clientLeft,(o.clientY-r.top)/i.y-e.clientTop)}static mousePos(e,t){const i=n.getScale(e);return n.getPoint(e,i,t)}static touchPos(e,t){const i=[],o=n.getScale(e);for(let r=0;r<t.length;r++)i.push(n.getPoint(e,o,t[r]));return i}static mouseButton(e){return e.button}static remove(e){e.parentNode&&e.parentNode.removeChild(e);}static sanitize(e){const t=(new DOMParser).parseFromString(e,\"text/html\").body||document.createElement(\"body\"),i=t.querySelectorAll(\"script\");for(const e of i)e.remove();return n.clean(t),t.innerHTML}static isPossiblyDangerous(e,t){const i=t.replace(/\\s+/g,\"\").toLowerCase();return !(![\"src\",\"href\",\"xlink:href\"].includes(e)||!i.includes(\"javascript:\")&&!i.includes(\"data:\"))||!!e.startsWith(\"on\")||void 0}static clean(e){const t=e.children;for(const e of t)n.removeAttributes(e),n.clean(e);}static removeAttributes(e){for(const{name:t,value:i}of e.attributes)n.isPossiblyDangerous(t,i)&&e.removeAttribute(t);}}n.docStyle=\"undefined\"!=typeof window&&window.document&&window.document.documentElement.style,n.selectProp=n.testProp([\"userSelect\",\"MozUserSelect\",\"WebkitUserSelect\",\"msUserSelect\"]),n.transformProp=n.testProp([\"transform\",\"WebkitTransform\"]);const l={supported:!1,testSupport:function(e){!u&&h&&(d?_(e):c=e);}};let c,h,u=!1,d=!1;function _(e){const t=e.createTexture();e.bindTexture(e.TEXTURE_2D,t);try{if(e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,h),e.isContextLost())return;l.supported=!0;}catch(e){}e.deleteTexture(t),u=!0;}var p;\"undefined\"!=typeof document&&(h=document.createElement(\"img\"),h.onload=()=>{c&&_(c),c=null,d=!0;},h.onerror=()=>{u=!0,c=null;},h.src=\"data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA=\"),function(e){let i,o,r,a;e.resetRequestQueue=()=>{i=[],o=0,r=0,a={};},e.addThrottleControl=e=>{const t=r++;return a[t]=e,t},e.removeThrottleControl=e=>{delete a[e],n();},e.getImage=(e,o,r=!0)=>new Promise(((a,s)=>{l.supported&&(e.headers||(e.headers={}),e.headers.accept=\"image/webp,*/*\"),t.e(e,{type:\"image\"}),i.push({abortController:o,requestParameters:e,supportImageRefresh:r,state:\"queued\",onError:e=>{s(e);},onSuccess:e=>{a(e);}}),n();}));const s=e=>t._(this,void 0,void 0,(function*(){e.state=\"running\";const{requestParameters:i,supportImageRefresh:r,onError:a,onSuccess:s,abortController:l}=e,h=!1===r&&!t.i(self)&&!t.g(i.url)&&(!i.headers||Object.keys(i.headers).reduce(((e,t)=>e&&\"accept\"===t),!0));o++;const u=h?c(i,l):t.m(i,l);try{const i=yield u;delete e.abortController,e.state=\"completed\",i.data instanceof HTMLImageElement||t.b(i.data)?s(i):i.data&&s({data:yield(d=i.data,\"function\"==typeof createImageBitmap?t.f(d):t.h(d)),cacheControl:i.cacheControl,expires:i.expires});}catch(t){delete e.abortController,a(t);}finally{o--,n();}var d;})),n=()=>{const e=(()=>{for(const e of Object.keys(a))if(a[e]())return !0;return !1})()?t.a.MAX_PARALLEL_IMAGE_REQUESTS_PER_FRAME:t.a.MAX_PARALLEL_IMAGE_REQUESTS;for(let t=o;t<e&&i.length>0;t++){const e=i.shift();e.abortController.signal.aborted?t--:s(e);}},c=(e,i)=>new Promise(((o,r)=>{const a=new Image,s=e.url,n=e.credentials;n&&\"include\"===n?a.crossOrigin=\"use-credentials\":(n&&\"same-origin\"===n||!t.d(s))&&(a.crossOrigin=\"anonymous\"),i.signal.addEventListener(\"abort\",(()=>{a.src=\"\",r(t.c());})),a.fetchPriority=\"high\",a.onload=()=>{a.onerror=a.onload=null,o({data:a});},a.onerror=()=>{a.onerror=a.onload=null,i.signal.aborted||r(new Error(\"Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.\"));},a.src=s;}));}(p||(p={})),p.resetRequestQueue();class m{constructor(e){this._transformRequestFn=e;}transformRequest(e,t){return this._transformRequestFn&&this._transformRequestFn(e,t)||{url:e}}setTransformRequest(e){this._transformRequestFn=e;}}function f(e){const t=[];if(\"string\"==typeof e)t.push({id:\"default\",url:e});else if(e&&e.length>0){const i=[];for(const{id:o,url:r}of e){const e=`${o}${r}`;-1===i.indexOf(e)&&(i.push(e),t.push({id:o,url:r}));}}return t}function g(e,t,i){try{const o=new URL(e);return o.pathname+=`${t}${i}`,o.toString()}catch(t){throw new Error(`Invalid sprite URL \"${e}\", must be absolute. Modify style specification directly or use TransformStyleFunction to correct the issue dynamically`)}}function v(e){const{userImage:t}=e;return !!(t&&t.render&&t.render())&&(e.data.replace(new Uint8Array(t.data.buffer)),!0)}class b extends t.E{constructor(){super(),this.images={},this.updatedImages={},this.callbackDispatchedThisFrame={},this.loaded=!1,this.requestors=[],this.patterns={},this.atlasImage=new t.R({width:1,height:1}),this.dirty=!0;}isLoaded(){return this.loaded}setLoaded(e){if(this.loaded!==e&&(this.loaded=e,e)){for(const{ids:e,promiseResolve:t}of this.requestors)t(this._getImagesForIds(e));this.requestors=[];}}getImage(e){const i=this.images[e];if(i&&!i.data&&i.spriteData){const e=i.spriteData;i.data=new t.R({width:e.width,height:e.height},e.context.getImageData(e.x,e.y,e.width,e.height).data),i.spriteData=null;}return i}addImage(e,t){if(this.images[e])throw new Error(`Image id ${e} already exist, use updateImage instead`);this._validate(e,t)&&(this.images[e]=t);}_validate(e,i){let o=!0;const r=i.data||i.spriteData;return this._validateStretch(i.stretchX,r&&r.width)||(this.fire(new t.k(new Error(`Image \"${e}\" has invalid \"stretchX\" value`))),o=!1),this._validateStretch(i.stretchY,r&&r.height)||(this.fire(new t.k(new Error(`Image \"${e}\" has invalid \"stretchY\" value`))),o=!1),this._validateContent(i.content,i)||(this.fire(new t.k(new Error(`Image \"${e}\" has invalid \"content\" value`))),o=!1),o}_validateStretch(e,t){if(!e)return !0;let i=0;for(const o of e){if(o[0]<i||o[1]<o[0]||t<o[1])return !1;i=o[1];}return !0}_validateContent(e,t){if(!e)return !0;if(4!==e.length)return !1;const i=t.spriteData,o=i&&i.width||t.data.width,r=i&&i.height||t.data.height;return !(e[0]<0||o<e[0]||e[1]<0||r<e[1]||e[2]<0||o<e[2]||e[3]<0||r<e[3]||e[2]<e[0]||e[3]<e[1])}updateImage(e,t,i=!0){const o=this.getImage(e);if(i&&(o.data.width!==t.data.width||o.data.height!==t.data.height))throw new Error(`size mismatch between old image (${o.data.width}x${o.data.height}) and new image (${t.data.width}x${t.data.height}).`);t.version=o.version+1,this.images[e]=t,this.updatedImages[e]=!0;}removeImage(e){const t=this.images[e];delete this.images[e],delete this.patterns[e],t.userImage&&t.userImage.onRemove&&t.userImage.onRemove();}listImages(){return Object.keys(this.images)}getImages(e){return new Promise(((t,i)=>{let o=!0;if(!this.isLoaded())for(const t of e)this.images[t]||(o=!1);this.isLoaded()||o?t(this._getImagesForIds(e)):this.requestors.push({ids:e,promiseResolve:t});}))}_getImagesForIds(e){const i={};for(const o of e){let e=this.getImage(o);e||(this.fire(new t.l(\"styleimagemissing\",{id:o})),e=this.getImage(o)),e?i[o]={data:e.data.clone(),pixelRatio:e.pixelRatio,sdf:e.sdf,version:e.version,stretchX:e.stretchX,stretchY:e.stretchY,content:e.content,textFitWidth:e.textFitWidth,textFitHeight:e.textFitHeight,hasRenderCallback:Boolean(e.userImage&&e.userImage.render)}:t.w(`Image \"${o}\" could not be loaded. Please make sure you have added the image with map.addImage() or a \"sprite\" property in your style. You can provide missing images by listening for the \"styleimagemissing\" map event.`);}return i}getPixelSize(){const{width:e,height:t}=this.atlasImage;return {width:e,height:t}}getPattern(e){const i=this.patterns[e],o=this.getImage(e);if(!o)return null;if(i&&i.position.version===o.version)return i.position;if(i)i.position.version=o.version;else {const i={w:o.data.width+2,h:o.data.height+2,x:0,y:0},r=new t.I(i,o);this.patterns[e]={bin:i,position:r};}return this._updatePatternAtlas(),this.patterns[e].position}bind(e){const i=e.gl;this.atlasTexture?this.dirty&&(this.atlasTexture.update(this.atlasImage),this.dirty=!1):this.atlasTexture=new t.T(e,this.atlasImage,i.RGBA),this.atlasTexture.bind(i.LINEAR,i.CLAMP_TO_EDGE);}_updatePatternAtlas(){const e=[];for(const t in this.patterns)e.push(this.patterns[t].bin);const{w:i,h:o}=t.p(e),r=this.atlasImage;r.resize({width:i||1,height:o||1});for(const e in this.patterns){const{bin:i}=this.patterns[e],o=i.x+1,a=i.y+1,s=this.getImage(e).data,n=s.width,l=s.height;t.R.copy(s,r,{x:0,y:0},{x:o,y:a},{width:n,height:l}),t.R.copy(s,r,{x:0,y:l-1},{x:o,y:a-1},{width:n,height:1}),t.R.copy(s,r,{x:0,y:0},{x:o,y:a+l},{width:n,height:1}),t.R.copy(s,r,{x:n-1,y:0},{x:o-1,y:a},{width:1,height:l}),t.R.copy(s,r,{x:0,y:0},{x:o+n,y:a},{width:1,height:l});}this.dirty=!0;}beginFrame(){this.callbackDispatchedThisFrame={};}dispatchRenderCallbacks(e){for(const i of e){if(this.callbackDispatchedThisFrame[i])continue;this.callbackDispatchedThisFrame[i]=!0;const e=this.getImage(i);e||t.w(`Image with ID: \"${i}\" was not found`),v(e)&&this.updateImage(i,e);}}}const x=1e20;function y(e,t,i,o,r,a,s,n,l){for(let c=t;c<t+o;c++)w(e,i*a+c,a,r,s,n,l);for(let c=i;c<i+r;c++)w(e,c*a+t,1,o,s,n,l);}function w(e,t,i,o,r,a,s){a[0]=0,s[0]=-1e20,s[1]=x,r[0]=e[t];for(let n=1,l=0,c=0;n<o;n++){r[n]=e[t+n*i];const o=n*n;do{const e=a[l];c=(r[n]-r[e]+o-e*e)/(n-e)/2;}while(c<=s[l]&&--l>-1);l++,a[l]=n,s[l]=c,s[l+1]=x;}for(let n=0,l=0;n<o;n++){for(;s[l+1]<n;)l++;const o=a[l],c=n-o;e[t+n*i]=r[o]+c*c;}}class T{constructor(e,t){this.requestManager=e,this.localIdeographFontFamily=t,this.entries={};}setURL(e){this.url=e;}getGlyphs(e){return t._(this,void 0,void 0,(function*(){const t=[];for(const i in e)for(const o of e[i])t.push(this._getAndCacheGlyphsPromise(i,o));const i=yield Promise.all(t),o={};for(const{stack:e,id:t,glyph:r}of i)o[e]||(o[e]={}),o[e][t]=r&&{id:r.id,bitmap:r.bitmap.clone(),metrics:r.metrics};return o}))}_getAndCacheGlyphsPromise(e,i){return t._(this,void 0,void 0,(function*(){let t=this.entries[e];t||(t=this.entries[e]={glyphs:{},requests:{},ranges:{}});let o=t.glyphs[i];if(void 0!==o)return {stack:e,id:i,glyph:o};if(o=this._tinySDF(t,e,i),o)return t.glyphs[i]=o,{stack:e,id:i,glyph:o};const r=Math.floor(i/256);if(256*r>65535)throw new Error(\"glyphs > 65535 not supported\");if(t.ranges[r])return {stack:e,id:i,glyph:o};if(!this.url)throw new Error(\"glyphsUrl is not set\");if(!t.requests[r]){const i=T.loadGlyphRange(e,r,this.url,this.requestManager);t.requests[r]=i;}const a=yield t.requests[r];for(const e in a)this._doesCharSupportLocalGlyph(+e)||(t.glyphs[+e]=a[+e]);return t.ranges[r]=!0,{stack:e,id:i,glyph:a[i]||null}}))}_doesCharSupportLocalGlyph(e){return !!this.localIdeographFontFamily&&(/\\p{Ideo}|\\p{sc=Hang}|\\p{sc=Hira}|\\p{sc=Kana}/u.test(String.fromCodePoint(e))||t.u[\"CJK Unified Ideographs\"](e)||t.u[\"Hangul Syllables\"](e)||t.u.Hiragana(e)||t.u.Katakana(e)||t.u[\"CJK Symbols and Punctuation\"](e)||t.u[\"Halfwidth and Fullwidth Forms\"](e))}_tinySDF(e,i,o){const r=this.localIdeographFontFamily;if(!r)return;if(!this._doesCharSupportLocalGlyph(o))return;let a=e.tinySDF;if(!a){let t=\"400\";/bold/i.test(i)?t=\"900\":/medium/i.test(i)?t=\"500\":/light/i.test(i)&&(t=\"200\"),a=e.tinySDF=new T.TinySDF({fontSize:48,buffer:6,radius:16,cutoff:.25,fontFamily:r,fontWeight:t});}const s=a.draw(String.fromCharCode(o));return {id:o,bitmap:new t.q({width:s.width||60,height:s.height||60},s.data),metrics:{width:s.glyphWidth/2||24,height:s.glyphHeight/2||24,left:s.glyphLeft/2+.5||0,top:s.glyphTop/2-27.5||-8,advance:s.glyphAdvance/2||24,isDoubleResolution:!0}}}}T.loadGlyphRange=function(e,i,o,r){return t._(this,void 0,void 0,(function*(){const a=256*i,s=a+255,n=r.transformRequest(o.replace(\"{fontstack}\",e).replace(\"{range}\",`${a}-${s}`),\"Glyphs\"),l=yield t.n(n,new AbortController);if(!l||!l.data)throw new Error(`Could not load glyph range. range: ${i}, ${a}-${s}`);const c={};for(const e of t.o(l.data))c[e.id]=e;return c}))},T.TinySDF=class{constructor({fontSize:e=24,buffer:t=3,radius:i=8,cutoff:o=.25,fontFamily:r=\"sans-serif\",fontWeight:a=\"normal\",fontStyle:s=\"normal\"}={}){this.buffer=t,this.cutoff=o,this.radius=i;const n=this.size=e+4*t,l=this._createCanvas(n),c=this.ctx=l.getContext(\"2d\",{willReadFrequently:!0});c.font=`${s} ${a} ${e}px ${r}`,c.textBaseline=\"alphabetic\",c.textAlign=\"left\",c.fillStyle=\"black\",this.gridOuter=new Float64Array(n*n),this.gridInner=new Float64Array(n*n),this.f=new Float64Array(n),this.z=new Float64Array(n+1),this.v=new Uint16Array(n);}_createCanvas(e){const t=document.createElement(\"canvas\");return t.width=t.height=e,t}draw(e){const{width:t,actualBoundingBoxAscent:i,actualBoundingBoxDescent:o,actualBoundingBoxLeft:r,actualBoundingBoxRight:a}=this.ctx.measureText(e),s=Math.ceil(i),n=Math.max(0,Math.min(this.size-this.buffer,Math.ceil(a-r))),l=Math.min(this.size-this.buffer,s+Math.ceil(o)),c=n+2*this.buffer,h=l+2*this.buffer,u=Math.max(c*h,0),d=new Uint8ClampedArray(u),_={data:d,width:c,height:h,glyphWidth:n,glyphHeight:l,glyphTop:s,glyphLeft:0,glyphAdvance:t};if(0===n||0===l)return _;const{ctx:p,buffer:m,gridInner:f,gridOuter:g}=this;p.clearRect(m,m,n,l),p.fillText(e,m,m+s);const v=p.getImageData(m,m,n,l);g.fill(x,0,u),f.fill(0,0,u);for(let e=0;e<l;e++)for(let t=0;t<n;t++){const i=v.data[4*(e*n+t)+3]/255;if(0===i)continue;const o=(e+m)*c+t+m;if(1===i)g[o]=0,f[o]=x;else {const e=.5-i;g[o]=e>0?e*e:0,f[o]=e<0?e*e:0;}}y(g,0,0,c,h,c,this.f,this.v,this.z),y(f,m,m,n,l,c,this.f,this.v,this.z);for(let e=0;e<u;e++){const t=Math.sqrt(g[e])-Math.sqrt(f[e]);d[e]=Math.round(255-255*(t/this.radius+this.cutoff));}return _}};class P{constructor(){this.specification=t.v.light.position;}possiblyEvaluate(e,i){return t.B(e.expression.evaluate(i))}interpolate(e,i,o){return {x:t.C.number(e.x,i.x,o),y:t.C.number(e.y,i.y,o),z:t.C.number(e.z,i.z,o)}}}let C;class I extends t.E{constructor(e){super(),C=C||new t.r({anchor:new t.D(t.v.light.anchor),position:new P,color:new t.D(t.v.light.color),intensity:new t.D(t.v.light.intensity)}),this._transitionable=new t.t(C),this.setLight(e),this._transitioning=this._transitionable.untransitioned();}getLight(){return this._transitionable.serialize()}setLight(e,i={}){if(!this._validate(t.x,e,i))for(const t in e){const i=e[t];t.endsWith(\"-transition\")?this._transitionable.setTransition(t.slice(0,-11),i):this._transitionable.setValue(t,i);}}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning);}hasTransition(){return this._transitioning.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e);}_validate(e,i,o){return (!o||!1!==o.validate)&&t.y(this,e.call(t.z,{value:i,style:{glyphs:!0,sprite:!0},styleSpec:t.v}))}}const M=new t.r({\"sky-color\":new t.D(t.v.sky[\"sky-color\"]),\"horizon-color\":new t.D(t.v.sky[\"horizon-color\"]),\"fog-color\":new t.D(t.v.sky[\"fog-color\"]),\"fog-ground-blend\":new t.D(t.v.sky[\"fog-ground-blend\"]),\"horizon-fog-blend\":new t.D(t.v.sky[\"horizon-fog-blend\"]),\"sky-horizon-blend\":new t.D(t.v.sky[\"sky-horizon-blend\"]),\"atmosphere-blend\":new t.D(t.v.sky[\"atmosphere-blend\"])});class S extends t.E{constructor(e){super(),this._transitionable=new t.t(M),this.setSky(e),this._transitioning=this._transitionable.untransitioned(),this.recalculate(new t.F(0));}setSky(e,i={}){if(!this._validate(t.G,e,i)){e||(e={\"sky-color\":\"transparent\",\"horizon-color\":\"transparent\",\"fog-color\":\"transparent\",\"fog-ground-blend\":1,\"atmosphere-blend\":0});for(const t in e){const i=e[t];t.endsWith(\"-transition\")?this._transitionable.setTransition(t.slice(0,-11),i):this._transitionable.setValue(t,i);}}}getSky(){return this._transitionable.serialize()}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning);}hasTransition(){return this._transitioning.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e);}_validate(e,i,o={}){return !1!==(null==o?void 0:o.validate)&&t.y(this,e.call(t.z,t.e({value:i,style:{glyphs:!0,sprite:!0},styleSpec:t.v})))}calculateFogBlendOpacity(e){return e<60?0:e<70?(e-60)/10:1}}class E{constructor(e,t){this.width=e,this.height=t,this.nextRow=0,this.data=new Uint8Array(this.width*this.height),this.dashEntry={};}getDash(e,t){const i=e.join(\",\")+String(t);return this.dashEntry[i]||(this.dashEntry[i]=this.addDash(e,t)),this.dashEntry[i]}getDashRanges(e,t,i){const o=[];let r=e.length%2==1?-e[e.length-1]*i:0,a=e[0]*i,s=!0;o.push({left:r,right:a,isDash:s,zeroLength:0===e[0]});let n=e[0];for(let t=1;t<e.length;t++){s=!s;const l=e[t];r=n*i,n+=l,a=n*i,o.push({left:r,right:a,isDash:s,zeroLength:0===l});}return o}addRoundDash(e,t,i){const o=t/2;for(let t=-i;t<=i;t++){const r=this.width*(this.nextRow+i+t);let a=0,s=e[a];for(let n=0;n<this.width;n++){n/s.right>1&&(s=e[++a]);const l=Math.abs(n-s.left),c=Math.abs(n-s.right),h=Math.min(l,c);let u;const d=t/i*(o+1);if(s.isDash){const e=o-Math.abs(d);u=Math.sqrt(h*h+e*e);}else u=o-Math.sqrt(h*h+d*d);this.data[r+n]=Math.max(0,Math.min(255,u+128));}}}addRegularDash(e){for(let t=e.length-1;t>=0;--t){const i=e[t],o=e[t+1];i.zeroLength?e.splice(t,1):o&&o.isDash===i.isDash&&(o.left=i.left,e.splice(t,1));}const t=e[0],i=e[e.length-1];t.isDash===i.isDash&&(t.left=i.left-this.width,i.right=t.right+this.width);const o=this.width*this.nextRow;let r=0,a=e[r];for(let t=0;t<this.width;t++){t/a.right>1&&(a=e[++r]);const i=Math.abs(t-a.left),s=Math.abs(t-a.right),n=Math.min(i,s);this.data[o+t]=Math.max(0,Math.min(255,(a.isDash?n:-n)+128));}}addDash(e,i){const o=i?7:0,r=2*o+1;if(this.nextRow+r>this.height)return t.w(\"LineAtlas out of space\"),null;let a=0;for(let t=0;t<e.length;t++)a+=e[t];if(0!==a){const t=this.width/a,r=this.getDashRanges(e,this.width,t);i?this.addRoundDash(r,t,o):this.addRegularDash(r);}const s={y:(this.nextRow+o+.5)/this.height,height:2*o/this.height,width:a};return this.nextRow+=r,this.dirty=!0,s}bind(e){const t=e.gl;this.texture?(t.bindTexture(t.TEXTURE_2D,this.texture),this.dirty&&(this.dirty=!1,t.texSubImage2D(t.TEXTURE_2D,0,0,0,this.width,this.height,t.ALPHA,t.UNSIGNED_BYTE,this.data))):(this.texture=t.createTexture(),t.bindTexture(t.TEXTURE_2D,this.texture),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.REPEAT),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texImage2D(t.TEXTURE_2D,0,t.ALPHA,this.width,this.height,0,t.ALPHA,t.UNSIGNED_BYTE,this.data));}}const R=\"maplibre_preloaded_worker_pool\";class z{constructor(){this.active={};}acquire(e){if(!this.workers)for(this.workers=[];this.workers.length<z.workerCount;)this.workers.push(new Worker(t.a.WORKER_URL));return this.active[e]=!0,this.workers.slice()}release(e){delete this.active[e],0===this.numActive()&&(this.workers.forEach((e=>{e.terminate();})),this.workers=null);}isPreloaded(){return !!this.active[R]}numActive(){return Object.keys(this.active).length}}const D=Math.floor(s.hardwareConcurrency/2);let A,L;function k(){return A||(A=new z),A}z.workerCount=t.H(globalThis)?Math.max(Math.min(D,3),1):1;class F{constructor(e,i){this.workerPool=e,this.actors=[],this.currentActor=0,this.id=i;const o=this.workerPool.acquire(i);for(let e=0;e<o.length;e++){const r=new t.J(o[e],i);r.name=`Worker ${e}`,this.actors.push(r);}if(!this.actors.length)throw new Error(\"No actors found\")}broadcast(e,t){const i=[];for(const o of this.actors)i.push(o.sendAsync({type:e,data:t}));return Promise.all(i)}getActor(){return this.currentActor=(this.currentActor+1)%this.actors.length,this.actors[this.currentActor]}remove(e=!0){this.actors.forEach((e=>{e.remove();})),this.actors=[],e&&this.workerPool.release(this.id);}registerMessageHandler(e,t){for(const i of this.actors)i.registerMessageHandler(e,t);}}function B(){return L||(L=new F(k(),t.K),L.registerMessageHandler(\"GR\",((e,i,o)=>t.m(i,o)))),L}function O(e,i){const o=t.L();return t.M(o,o,[1,1,0]),t.N(o,o,[.5*e.width,.5*e.height,1]),e.calculatePosMatrix?t.O(o,o,e.calculatePosMatrix(i.toUnwrapped())):o}function j(e,t,i,o,r,a,s){var n;const l=function(e,t,i){if(e)for(const o of e){const e=t[o];if(e&&e.source===i&&\"fill-extrusion\"===e.type)return !0}else for(const e in t){const o=t[e];if(o.source===i&&\"fill-extrusion\"===o.type)return !0}return !1}(null!==(n=null==r?void 0:r.layers)&&void 0!==n?n:null,t,e.id),c=a.maxPitchScaleFactor(),h=e.tilesIn(o,c,l);h.sort(N);const u=[];for(const o of h)u.push({wrappedTileID:o.tileID.wrapped().key,queryResults:o.tile.queryRenderedFeatures(t,i,e._state,o.queryGeometry,o.cameraQueryGeometry,o.scale,r,a,c,O(e.transform,o.tileID),s?(e,t)=>s(o.tileID,e,t):void 0)});return function(e,t){for(const i in e)for(const o of e[i])Z(o,t);return e}(function(e){const t={},i={};for(const o of e){const e=o.queryResults,r=o.wrappedTileID,a=i[r]=i[r]||{};for(const i in e){const o=e[i],r=a[i]=a[i]||{},s=t[i]=t[i]||[];for(const e of o)r[e.featureIndex]||(r[e.featureIndex]=!0,s.push(e));}}return t}(u),e)}function N(e,t){const i=e.tileID,o=t.tileID;return i.overscaledZ-o.overscaledZ||i.canonical.y-o.canonical.y||i.wrap-o.wrap||i.canonical.x-o.canonical.x}function Z(e,t){const i=e.feature,o=t.getFeatureState(i.layer[\"source-layer\"],i.id);i.source=i.layer.source,i.layer[\"source-layer\"]&&(i.sourceLayer=i.layer[\"source-layer\"]),i.state=o;}function U(e,i,o){return t._(this,void 0,void 0,(function*(){let r=e;if(e.url?r=(yield t.j(i.transformRequest(e.url,\"Source\"),o)).data:yield s.frameAsync(o),!r)return null;const a=t.Q(t.e(r,e),[\"tiles\",\"minzoom\",\"maxzoom\",\"attribution\",\"bounds\",\"scheme\",\"tileSize\",\"encoding\"]);return \"vector_layers\"in r&&r.vector_layers&&(a.vectorLayerIds=r.vector_layers.map((e=>e.id))),a}))}class G{constructor(e,t){e&&(t?this.setSouthWest(e).setNorthEast(t):Array.isArray(e)&&(4===e.length?this.setSouthWest([e[0],e[1]]).setNorthEast([e[2],e[3]]):this.setSouthWest(e[0]).setNorthEast(e[1])));}setNorthEast(e){return this._ne=e instanceof t.S?new t.S(e.lng,e.lat):t.S.convert(e),this}setSouthWest(e){return this._sw=e instanceof t.S?new t.S(e.lng,e.lat):t.S.convert(e),this}extend(e){const i=this._sw,o=this._ne;let r,a;if(e instanceof t.S)r=e,a=e;else {if(!(e instanceof G))return Array.isArray(e)?4===e.length||e.every(Array.isArray)?this.extend(G.convert(e)):this.extend(t.S.convert(e)):e&&(\"lng\"in e||\"lon\"in e)&&\"lat\"in e?this.extend(t.S.convert(e)):this;if(r=e._sw,a=e._ne,!r||!a)return this}return i||o?(i.lng=Math.min(r.lng,i.lng),i.lat=Math.min(r.lat,i.lat),o.lng=Math.max(a.lng,o.lng),o.lat=Math.max(a.lat,o.lat)):(this._sw=new t.S(r.lng,r.lat),this._ne=new t.S(a.lng,a.lat)),this}getCenter(){return new t.S((this._sw.lng+this._ne.lng)/2,(this._sw.lat+this._ne.lat)/2)}getSouthWest(){return this._sw}getNorthEast(){return this._ne}getNorthWest(){return new t.S(this.getWest(),this.getNorth())}getSouthEast(){return new t.S(this.getEast(),this.getSouth())}getWest(){return this._sw.lng}getSouth(){return this._sw.lat}getEast(){return this._ne.lng}getNorth(){return this._ne.lat}toArray(){return [this._sw.toArray(),this._ne.toArray()]}toString(){return `LngLatBounds(${this._sw.toString()}, ${this._ne.toString()})`}isEmpty(){return !(this._sw&&this._ne)}contains(e){const{lng:i,lat:o}=t.S.convert(e);let r=this._sw.lng<=i&&i<=this._ne.lng;return this._sw.lng>this._ne.lng&&(r=this._sw.lng>=i&&i>=this._ne.lng),this._sw.lat<=o&&o<=this._ne.lat&&r}static convert(e){return e instanceof G?e:e?new G(e):e}static fromLngLat(e,i=0){const o=360*i/40075017,r=o/Math.cos(Math.PI/180*e.lat);return new G(new t.S(e.lng-r,e.lat-o),new t.S(e.lng+r,e.lat+o))}adjustAntiMeridian(){const e=new t.S(this._sw.lng,this._sw.lat),i=new t.S(this._ne.lng,this._ne.lat);return new G(e,e.lng>i.lng?new t.S(i.lng+360,i.lat):i)}}class V{constructor(e,t,i){this.bounds=G.convert(this.validateBounds(e)),this.minzoom=t||0,this.maxzoom=i||24;}validateBounds(e){return Array.isArray(e)&&4===e.length?[Math.max(-180,e[0]),Math.max(-90,e[1]),Math.min(180,e[2]),Math.min(90,e[3])]:[-180,-90,180,90]}contains(e){const i=Math.pow(2,e.z),o=Math.floor(t.V(this.bounds.getWest())*i),r=Math.floor(t.U(this.bounds.getNorth())*i),a=Math.ceil(t.V(this.bounds.getEast())*i),s=Math.ceil(t.U(this.bounds.getSouth())*i);return e.x>=o&&e.x<a&&e.y>=r&&e.y<s}}class $ extends t.E{constructor(e,i,o,r){if(super(),this.id=e,this.dispatcher=o,this.type=\"vector\",this.minzoom=0,this.maxzoom=22,this.scheme=\"xyz\",this.tileSize=512,this.reparseOverscaled=!0,this.isTileClipped=!0,this._loaded=!1,t.e(this,t.Q(i,[\"url\",\"scheme\",\"tileSize\",\"promoteId\"])),this._options=t.e({type:\"vector\"},i),this._collectResourceTiming=i.collectResourceTiming,512!==this.tileSize)throw new Error(\"vector tile sources must have a tileSize of 512\");this.setEventedParent(r);}load(){return t._(this,void 0,void 0,(function*(){this._loaded=!1,this.fire(new t.l(\"dataloading\",{dataType:\"source\"})),this._tileJSONRequest=new AbortController;try{const e=yield U(this._options,this.map._requestManager,this._tileJSONRequest);this._tileJSONRequest=null,this._loaded=!0,this.map.style.sourceCaches[this.id].clearTiles(),e&&(t.e(this,e),e.bounds&&(this.tileBounds=new V(e.bounds,this.minzoom,this.maxzoom)),this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"metadata\"})),this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"content\"})));}catch(e){this._tileJSONRequest=null,this.fire(new t.k(e));}}))}loaded(){return this._loaded}hasTile(e){return !this.tileBounds||this.tileBounds.contains(e.canonical)}onAdd(e){this.map=e,this.load();}setSourceProperty(e){this._tileJSONRequest&&this._tileJSONRequest.abort(),e(),this.load();}setTiles(e){return this.setSourceProperty((()=>{this._options.tiles=e;})),this}setUrl(e){return this.setSourceProperty((()=>{this.url=e,this._options.url=e;})),this}onRemove(){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null);}serialize(){return t.e({},this._options)}loadTile(e){return t._(this,void 0,void 0,(function*(){const t=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),i={request:this.map._requestManager.transformRequest(t,\"Tile\"),uid:e.uid,tileID:e.tileID,zoom:e.tileID.overscaledZ,tileSize:this.tileSize*e.tileID.overscaleFactor(),type:this.type,source:this.id,pixelRatio:this.map.getPixelRatio(),showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId,subdivisionGranularity:this.map.style.projection.subdivisionGranularity,globalState:this.map.getGlobalState()};i.request.collectResourceTiming=this._collectResourceTiming;let o=\"RT\";if(e.actor&&\"expired\"!==e.state){if(\"loading\"===e.state)return new Promise(((t,i)=>{e.reloadPromise={resolve:t,reject:i};}))}else e.actor=this.dispatcher.getActor(),o=\"LT\";e.abortController=new AbortController;try{const t=yield e.actor.sendAsync({type:o,data:i},e.abortController);if(delete e.abortController,e.aborted)return;this._afterTileLoadWorkerResponse(e,t);}catch(t){if(delete e.abortController,e.aborted)return;if(t&&404!==t.status)throw t;this._afterTileLoadWorkerResponse(e,null);}}))}_afterTileLoadWorkerResponse(e,t){if(t&&t.resourceTiming&&(e.resourceTiming=t.resourceTiming),t&&this.map._refreshExpiredTiles&&e.setExpiryData(t),e.loadVectorData(t,this.map.painter),e.reloadPromise){const t=e.reloadPromise;e.reloadPromise=null,this.loadTile(e).then(t.resolve).catch(t.reject);}}abortTile(e){return t._(this,void 0,void 0,(function*(){e.abortController&&(e.abortController.abort(),delete e.abortController),e.actor&&(yield e.actor.sendAsync({type:\"AT\",data:{uid:e.uid,type:this.type,source:this.id}}));}))}unloadTile(e){return t._(this,void 0,void 0,(function*(){e.unloadVectorData(),e.actor&&(yield e.actor.sendAsync({type:\"RMT\",data:{uid:e.uid,type:this.type,source:this.id}}));}))}hasTransition(){return !1}}class q extends t.E{constructor(e,i,o,r){super(),this.id=e,this.dispatcher=o,this.setEventedParent(r),this.type=\"raster\",this.minzoom=0,this.maxzoom=22,this.roundZoom=!0,this.scheme=\"xyz\",this.tileSize=512,this._loaded=!1,this._options=t.e({type:\"raster\"},i),t.e(this,t.Q(i,[\"url\",\"scheme\",\"tileSize\"]));}load(){return t._(this,arguments,void 0,(function*(e=!1){this._loaded=!1,this.fire(new t.l(\"dataloading\",{dataType:\"source\"})),this._tileJSONRequest=new AbortController;try{const i=yield U(this._options,this.map._requestManager,this._tileJSONRequest);this._tileJSONRequest=null,this._loaded=!0,i&&(t.e(this,i),i.bounds&&(this.tileBounds=new V(i.bounds,this.minzoom,this.maxzoom)),this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"metadata\"})),this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"content\",sourceDataChanged:e})));}catch(e){this._tileJSONRequest=null,this.fire(new t.k(e));}}))}loaded(){return this._loaded}onAdd(e){this.map=e,this.load();}onRemove(){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null);}setSourceProperty(e){this._tileJSONRequest&&(this._tileJSONRequest.abort(),this._tileJSONRequest=null),e(),this.load(!0);}setTiles(e){return this.setSourceProperty((()=>{this._options.tiles=e;})),this}setUrl(e){return this.setSourceProperty((()=>{this.url=e,this._options.url=e;})),this}serialize(){return t.e({},this._options)}hasTile(e){return !this.tileBounds||this.tileBounds.contains(e.canonical)}loadTile(e){return t._(this,void 0,void 0,(function*(){const i=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme);e.abortController=new AbortController;try{const o=yield p.getImage(this.map._requestManager.transformRequest(i,\"Tile\"),e.abortController,this.map._refreshExpiredTiles);if(delete e.abortController,e.aborted)return void(e.state=\"unloaded\");if(o&&o.data){this.map._refreshExpiredTiles&&(o.cacheControl||o.expires)&&e.setExpiryData({cacheControl:o.cacheControl,expires:o.expires});const i=this.map.painter.context,r=i.gl,a=o.data;e.texture=this.map.painter.getTileTexture(a.width),e.texture?e.texture.update(a,{useMipmap:!0}):(e.texture=new t.T(i,a,r.RGBA,{useMipmap:!0}),e.texture.bind(r.LINEAR,r.CLAMP_TO_EDGE,r.LINEAR_MIPMAP_NEAREST)),e.state=\"loaded\";}}catch(t){if(delete e.abortController,e.aborted)e.state=\"unloaded\";else if(t)throw e.state=\"errored\",t}}))}abortTile(e){return t._(this,void 0,void 0,(function*(){e.abortController&&(e.abortController.abort(),delete e.abortController);}))}unloadTile(e){return t._(this,void 0,void 0,(function*(){e.texture&&this.map.painter.saveTileTexture(e.texture);}))}hasTransition(){return !1}}class W extends q{constructor(e,i,o,r){super(e,i,o,r),this.type=\"raster-dem\",this.maxzoom=22,this._options=t.e({type:\"raster-dem\"},i),this.encoding=i.encoding||\"mapbox\",this.redFactor=i.redFactor,this.greenFactor=i.greenFactor,this.blueFactor=i.blueFactor,this.baseShift=i.baseShift;}loadTile(e){return t._(this,void 0,void 0,(function*(){const i=e.tileID.canonical.url(this.tiles,this.map.getPixelRatio(),this.scheme),o=this.map._requestManager.transformRequest(i,\"Tile\");e.neighboringTiles=this._getNeighboringTiles(e.tileID),e.abortController=new AbortController;try{const i=yield p.getImage(o,e.abortController,this.map._refreshExpiredTiles);if(delete e.abortController,e.aborted)return void(e.state=\"unloaded\");if(i&&i.data){const o=i.data;this.map._refreshExpiredTiles&&(i.cacheControl||i.expires)&&e.setExpiryData({cacheControl:i.cacheControl,expires:i.expires});const r=t.b(o)&&t.W()?o:yield this.readImageNow(o),a={type:this.type,uid:e.uid,source:this.id,rawImageData:r,encoding:this.encoding,redFactor:this.redFactor,greenFactor:this.greenFactor,blueFactor:this.blueFactor,baseShift:this.baseShift};if(!e.actor||\"expired\"===e.state){e.actor=this.dispatcher.getActor();const t=yield e.actor.sendAsync({type:\"LDT\",data:a});e.dem=t,e.needsHillshadePrepare=!0,e.needsTerrainPrepare=!0,e.state=\"loaded\";}}}catch(t){if(delete e.abortController,e.aborted)e.state=\"unloaded\";else if(t)throw e.state=\"errored\",t}}))}readImageNow(e){return t._(this,void 0,void 0,(function*(){if(\"undefined\"!=typeof VideoFrame&&t.X()){const i=e.width+2,o=e.height+2;try{return new t.R({width:i,height:o},yield t.Y(e,-1,-1,i,o))}catch(e){}}return s.getImageData(e,1)}))}_getNeighboringTiles(e){const i=e.canonical,o=Math.pow(2,i.z),r=(i.x-1+o)%o,a=0===i.x?e.wrap-1:e.wrap,s=(i.x+1+o)%o,n=i.x+1===o?e.wrap+1:e.wrap,l={};return l[new t.Z(e.overscaledZ,a,i.z,r,i.y).key]={backfilled:!1},l[new t.Z(e.overscaledZ,n,i.z,s,i.y).key]={backfilled:!1},i.y>0&&(l[new t.Z(e.overscaledZ,a,i.z,r,i.y-1).key]={backfilled:!1},l[new t.Z(e.overscaledZ,e.wrap,i.z,i.x,i.y-1).key]={backfilled:!1},l[new t.Z(e.overscaledZ,n,i.z,s,i.y-1).key]={backfilled:!1}),i.y+1<o&&(l[new t.Z(e.overscaledZ,a,i.z,r,i.y+1).key]={backfilled:!1},l[new t.Z(e.overscaledZ,e.wrap,i.z,i.x,i.y+1).key]={backfilled:!1},l[new t.Z(e.overscaledZ,n,i.z,s,i.y+1).key]={backfilled:!1}),l}unloadTile(e){return t._(this,void 0,void 0,(function*(){e.demTexture&&this.map.painter.saveTileTexture(e.demTexture),e.fbo&&(e.fbo.destroy(),delete e.fbo),e.dem&&delete e.dem,delete e.neighboringTiles,e.state=\"unloaded\",e.actor&&(yield e.actor.sendAsync({type:\"RDT\",data:{type:this.type,uid:e.uid,source:this.id}}));}))}}class H extends t.E{constructor(e,i,o,r){super(),this.id=e,this.type=\"geojson\",this.minzoom=0,this.maxzoom=18,this.tileSize=512,this.isTileClipped=!0,this.reparseOverscaled=!0,this._removed=!1,this._pendingLoads=0,this.actor=o.getActor(),this.setEventedParent(r),this._data=i.data,this._options=t.e({},i),this._collectResourceTiming=i.collectResourceTiming,void 0!==i.maxzoom&&(this.maxzoom=i.maxzoom),i.type&&(this.type=i.type),i.attribution&&(this.attribution=i.attribution),this.promoteId=i.promoteId,void 0!==i.clusterMaxZoom&&this.maxzoom<=i.clusterMaxZoom&&t.w(`The maxzoom value \"${this.maxzoom}\" is expected to be greater than the clusterMaxZoom value \"${i.clusterMaxZoom}\".`),this.workerOptions=t.e({source:this.id,cluster:i.cluster||!1,geojsonVtOptions:{buffer:this._pixelsToTileUnits(void 0!==i.buffer?i.buffer:128),tolerance:this._pixelsToTileUnits(void 0!==i.tolerance?i.tolerance:.375),extent:t.$,maxZoom:this.maxzoom,lineMetrics:i.lineMetrics||!1,generateId:i.generateId||!1},superclusterOptions:{maxZoom:this._getClusterMaxZoom(i.clusterMaxZoom),minPoints:Math.max(2,i.clusterMinPoints||2),extent:t.$,radius:this._pixelsToTileUnits(i.clusterRadius||50),log:!1,generateId:i.generateId||!1},clusterProperties:i.clusterProperties,filter:i.filter},i.workerOptions),\"string\"==typeof this.promoteId&&(this.workerOptions.promoteId=this.promoteId);}_pixelsToTileUnits(e){return e*(t.$/this.tileSize)}_getClusterMaxZoom(e){const i=e?Math.round(e):this.maxzoom-1;return Number.isInteger(e)||void 0===e||t.w(`Integer expected for option 'clusterMaxZoom': provided value \"${e}\" rounded to \"${i}\"`),i}load(){return t._(this,void 0,void 0,(function*(){yield this._updateWorkerData();}))}onAdd(e){this.map=e,this.load();}setData(e){return this._data=e,this._updateWorkerData(),this}updateData(e){return this._updateWorkerData(e),this}getData(){return t._(this,void 0,void 0,(function*(){const e=t.e({type:this.type},this.workerOptions);return this.actor.sendAsync({type:\"GD\",data:e})}))}getCoordinatesFromGeometry(e){return \"GeometryCollection\"===e.type?e.geometries.map((e=>e.coordinates)).flat(1/0):e.coordinates.flat(1/0)}getBounds(){return t._(this,void 0,void 0,(function*(){const e=new G,t=yield this.getData();let i;switch(t.type){case \"FeatureCollection\":i=t.features.map((e=>this.getCoordinatesFromGeometry(e.geometry))).flat(1/0);break;case \"Feature\":i=this.getCoordinatesFromGeometry(t.geometry);break;default:i=this.getCoordinatesFromGeometry(t);}if(0==i.length)return e;for(let t=0;t<i.length-1;t+=2)e.extend([i[t],i[t+1]]);return e}))}setClusterOptions(e){return this.workerOptions.cluster=e.cluster,e&&(void 0!==e.clusterRadius&&(this.workerOptions.superclusterOptions.radius=this._pixelsToTileUnits(e.clusterRadius)),void 0!==e.clusterMaxZoom&&(this.workerOptions.superclusterOptions.maxZoom=this._getClusterMaxZoom(e.clusterMaxZoom))),this._updateWorkerData(),this}getClusterExpansionZoom(e){return this.actor.sendAsync({type:\"GCEZ\",data:{type:this.type,clusterId:e,source:this.id}})}getClusterChildren(e){return this.actor.sendAsync({type:\"GCC\",data:{type:this.type,clusterId:e,source:this.id}})}getClusterLeaves(e,t,i){return this.actor.sendAsync({type:\"GCL\",data:{type:this.type,source:this.id,clusterId:e,limit:t,offset:i}})}_updateWorkerData(e){return t._(this,void 0,void 0,(function*(){const i=t.e({type:this.type},this.workerOptions);e?i.dataDiff=e:\"string\"==typeof this._data?(i.request=this.map._requestManager.transformRequest(s.resolveURL(this._data),\"Source\"),i.request.collectResourceTiming=this._collectResourceTiming):i.data=JSON.stringify(this._data),this._pendingLoads++,this.fire(new t.l(\"dataloading\",{dataType:\"source\"}));try{const e=yield this.actor.sendAsync({type:\"LD\",data:i});if(this._pendingLoads--,this._removed||e.abandoned)return void this.fire(new t.l(\"dataabort\",{dataType:\"source\"}));let o=null;e.resourceTiming&&e.resourceTiming[this.id]&&(o=e.resourceTiming[this.id].slice(0));const r={dataType:\"source\"};this._collectResourceTiming&&o&&o.length>0&&t.e(r,{resourceTiming:o}),this.fire(new t.l(\"data\",Object.assign(Object.assign({},r),{sourceDataType:\"metadata\"}))),this.fire(new t.l(\"data\",Object.assign(Object.assign({},r),{sourceDataType:\"content\"})));}catch(e){if(this._pendingLoads--,this._removed)return void this.fire(new t.l(\"dataabort\",{dataType:\"source\"}));this.fire(new t.k(e));}}))}loaded(){return 0===this._pendingLoads}loadTile(e){return t._(this,void 0,void 0,(function*(){const t=e.actor?\"RT\":\"LT\";e.actor=this.actor;const i={type:this.type,uid:e.uid,tileID:e.tileID,zoom:e.tileID.overscaledZ,maxZoom:this.maxzoom,tileSize:this.tileSize,source:this.id,pixelRatio:this.map.getPixelRatio(),showCollisionBoxes:this.map.showCollisionBoxes,promoteId:this.promoteId,subdivisionGranularity:this.map.style.projection.subdivisionGranularity,globalState:this.map.getGlobalState()};e.abortController=new AbortController;const o=yield this.actor.sendAsync({type:t,data:i},e.abortController);delete e.abortController,e.unloadVectorData(),e.aborted||e.loadVectorData(o,this.map.painter,\"RT\"===t);}))}abortTile(e){return t._(this,void 0,void 0,(function*(){e.abortController&&(e.abortController.abort(),delete e.abortController),e.aborted=!0;}))}unloadTile(e){return t._(this,void 0,void 0,(function*(){e.unloadVectorData(),yield this.actor.sendAsync({type:\"RMT\",data:{uid:e.uid,type:this.type,source:this.id}});}))}onRemove(){this._removed=!0,this.actor.sendAsync({type:\"RS\",data:{type:this.type,source:this.id}});}serialize(){return t.e({},this._options,{type:this.type,data:this._data})}hasTransition(){return !1}}class X extends t.E{constructor(e,t,i,o){super(),this.flippedWindingOrder=!1,this.id=e,this.dispatcher=i,this.coordinates=t.coordinates,this.type=\"image\",this.minzoom=0,this.maxzoom=22,this.tileSize=512,this.tiles={},this._loaded=!1,this.setEventedParent(o),this.options=t;}load(e){return t._(this,void 0,void 0,(function*(){this._loaded=!1,this.fire(new t.l(\"dataloading\",{dataType:\"source\"})),this.url=this.options.url,this._request=new AbortController;try{const t=yield p.getImage(this.map._requestManager.transformRequest(this.url,\"Image\"),this._request);this._request=null,this._loaded=!0,t&&t.data&&(this.image=t.data,e&&(this.coordinates=e),this._finishLoading());}catch(e){this._request=null,this._loaded=!0,this.fire(new t.k(e));}}))}loaded(){return this._loaded}updateImage(e){return e.url?(this._request&&(this._request.abort(),this._request=null),this.options.url=e.url,this.load(e.coordinates).finally((()=>{this.texture=null;})),this):this}_finishLoading(){this.map&&(this.setCoordinates(this.coordinates),this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"metadata\"})));}onAdd(e){this.map=e,this.load();}onRemove(){this._request&&(this._request.abort(),this._request=null);}setCoordinates(e){this.coordinates=e;const i=e.map(t.a0.fromLngLat);var o;return this.tileID=function(e){const i=t.a1.fromPoints(e),o=i.width(),r=i.height(),a=Math.max(o,r),s=Math.max(0,Math.floor(-Math.log(a)/Math.LN2)),n=Math.pow(2,s);return new t.a3(s,Math.floor((i.minX+i.maxX)/2*n),Math.floor((i.minY+i.maxY)/2*n))}(i),this.terrainTileRanges=this._getOverlappingTileRanges(i),this.minzoom=this.maxzoom=this.tileID.z,this.tileCoords=i.map((e=>this.tileID.getTilePoint(e)._round())),this.flippedWindingOrder=((o=this.tileCoords)[1].x-o[0].x)*(o[2].y-o[0].y)-(o[1].y-o[0].y)*(o[2].x-o[0].x)<0,this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"content\"})),this}prepare(){if(0===Object.keys(this.tiles).length||!this.image)return;const e=this.map.painter.context,i=e.gl;this.texture||(this.texture=new t.T(e,this.image,i.RGBA),this.texture.bind(i.LINEAR,i.CLAMP_TO_EDGE));let o=!1;for(const e in this.tiles){const t=this.tiles[e];\"loaded\"!==t.state&&(t.state=\"loaded\",t.texture=this.texture,o=!0);}o&&this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"idle\",sourceId:this.id}));}loadTile(e){return t._(this,void 0,void 0,(function*(){this.tileID&&this.tileID.equals(e.tileID.canonical)?(this.tiles[String(e.tileID.wrap)]=e,e.buckets={}):e.state=\"errored\";}))}serialize(){return {type:\"image\",url:this.options.url,coordinates:this.coordinates}}hasTransition(){return !1}_getOverlappingTileRanges(e){const{minX:i,minY:o,maxX:r,maxY:a}=t.a1.fromPoints(e),s={};for(let e=0;e<=t.a2;e++){const t=Math.pow(2,e),n=Math.floor(i*t),l=Math.floor(o*t),c=Math.floor(r*t),h=Math.floor(a*t);s[e]={minTileX:n,minTileY:l,maxTileX:c,maxTileY:h};}return s}}class K extends X{constructor(e,t,i,o){super(e,t,i,o),this.roundZoom=!0,this.type=\"video\",this.options=t;}load(){return t._(this,void 0,void 0,(function*(){this._loaded=!1;const e=this.options;this.urls=[];for(const t of e.urls)this.urls.push(this.map._requestManager.transformRequest(t,\"Source\").url);try{const e=yield t.a4(this.urls);if(this._loaded=!0,!e)return;this.video=e,this.video.loop=!0,this.video.addEventListener(\"playing\",(()=>{this.map.triggerRepaint();})),this.map&&this.video.play(),this._finishLoading();}catch(e){this.fire(new t.k(e));}}))}pause(){this.video&&this.video.pause();}play(){this.video&&this.video.play();}seek(e){if(this.video){const i=this.video.seekable;e<i.start(0)||e>i.end(0)?this.fire(new t.k(new t.a5(`sources.${this.id}`,null,`Playback for this video can be set only between the ${i.start(0)} and ${i.end(0)}-second mark.`))):this.video.currentTime=e;}}getVideo(){return this.video}onAdd(e){this.map||(this.map=e,this.load(),this.video&&(this.video.play(),this.setCoordinates(this.coordinates)));}prepare(){if(0===Object.keys(this.tiles).length||this.video.readyState<2)return;const e=this.map.painter.context,i=e.gl;this.texture?this.video.paused||(this.texture.bind(i.LINEAR,i.CLAMP_TO_EDGE),i.texSubImage2D(i.TEXTURE_2D,0,0,0,i.RGBA,i.UNSIGNED_BYTE,this.video)):(this.texture=new t.T(e,this.video,i.RGBA),this.texture.bind(i.LINEAR,i.CLAMP_TO_EDGE));let o=!1;for(const e in this.tiles){const t=this.tiles[e];\"loaded\"!==t.state&&(t.state=\"loaded\",t.texture=this.texture,o=!0);}o&&this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"idle\",sourceId:this.id}));}serialize(){return {type:\"video\",urls:this.urls,coordinates:this.coordinates}}hasTransition(){return this.video&&!this.video.paused}}class Y extends X{constructor(e,i,o,r){super(e,i,o,r),i.coordinates?Array.isArray(i.coordinates)&&4===i.coordinates.length&&!i.coordinates.some((e=>!Array.isArray(e)||2!==e.length||e.some((e=>\"number\"!=typeof e))))||this.fire(new t.k(new t.a5(`sources.${e}`,null,'\"coordinates\" property must be an array of 4 longitude/latitude array pairs'))):this.fire(new t.k(new t.a5(`sources.${e}`,null,'missing required property \"coordinates\"'))),i.animate&&\"boolean\"!=typeof i.animate&&this.fire(new t.k(new t.a5(`sources.${e}`,null,'optional \"animate\" property must be a boolean value'))),i.canvas?\"string\"==typeof i.canvas||i.canvas instanceof HTMLCanvasElement||this.fire(new t.k(new t.a5(`sources.${e}`,null,'\"canvas\" must be either a string representing the ID of the canvas element from which to read, or an HTMLCanvasElement instance'))):this.fire(new t.k(new t.a5(`sources.${e}`,null,'missing required property \"canvas\"'))),this.options=i,this.animate=void 0===i.animate||i.animate;}load(){return t._(this,void 0,void 0,(function*(){this._loaded=!0,this.canvas||(this.canvas=this.options.canvas instanceof HTMLCanvasElement?this.options.canvas:document.getElementById(this.options.canvas)),this.width=this.canvas.width,this.height=this.canvas.height,this._hasInvalidDimensions()?this.fire(new t.k(new Error(\"Canvas dimensions cannot be less than or equal to zero.\"))):(this.play=function(){this._playing=!0,this.map.triggerRepaint();},this.pause=function(){this._playing&&(this.prepare(),this._playing=!1);},this._finishLoading());}))}getCanvas(){return this.canvas}onAdd(e){this.map=e,this.load(),this.canvas&&this.animate&&this.play();}onRemove(){this.pause();}prepare(){let e=!1;if(this.canvas.width!==this.width&&(this.width=this.canvas.width,e=!0),this.canvas.height!==this.height&&(this.height=this.canvas.height,e=!0),this._hasInvalidDimensions())return;if(0===Object.keys(this.tiles).length)return;const i=this.map.painter.context,o=i.gl;this.texture?(e||this._playing)&&this.texture.update(this.canvas,{premultiply:!0}):this.texture=new t.T(i,this.canvas,o.RGBA,{premultiply:!0});let r=!1;for(const e in this.tiles){const t=this.tiles[e];\"loaded\"!==t.state&&(t.state=\"loaded\",t.texture=this.texture,r=!0);}r&&this.fire(new t.l(\"data\",{dataType:\"source\",sourceDataType:\"idle\",sourceId:this.id}));}serialize(){return {type:\"canvas\",coordinates:this.coordinates}}hasTransition(){return this._playing}_hasInvalidDimensions(){for(const e of [this.canvas.width,this.canvas.height])if(isNaN(e)||e<=0)return !0;return !1}}const Q={},J=e=>{switch(e){case \"geojson\":return H;case \"image\":return X;case \"raster\":return q;case \"raster-dem\":return W;case \"vector\":return $;case \"video\":return K;case \"canvas\":return Y}return Q[e]},ee=\"RTLPluginLoaded\";class te extends t.E{constructor(){super(...arguments),this.status=\"unavailable\",this.url=null,this.dispatcher=B();}_syncState(e){return this.status=e,this.dispatcher.broadcast(\"SRPS\",{pluginStatus:e,pluginURL:this.url}).catch((e=>{throw this.status=\"error\",e}))}getRTLTextPluginStatus(){return this.status}clearRTLTextPlugin(){this.status=\"unavailable\",this.url=null;}setRTLTextPlugin(e){return t._(this,arguments,void 0,(function*(e,t=!1){if(this.url)throw new Error(\"setRTLTextPlugin cannot be called multiple times.\");if(this.url=s.resolveURL(e),!this.url)throw new Error(`requested url ${e} is invalid`);if(\"unavailable\"===this.status){if(!t)return this._requestImport();this.status=\"deferred\",this._syncState(this.status);}else if(\"requested\"===this.status)return this._requestImport()}))}_requestImport(){return t._(this,void 0,void 0,(function*(){yield this._syncState(\"loading\"),this.status=\"loaded\",this.fire(new t.l(ee));}))}lazyLoad(){\"unavailable\"===this.status?this.status=\"requested\":\"deferred\"===this.status&&this._requestImport();}}let ie=null;function oe(){return ie||(ie=new te),ie}class re{constructor(e,i){this.timeAdded=0,this.fadeEndTime=0,this.tileID=e,this.uid=t.a6(),this.uses=0,this.tileSize=i,this.buckets={},this.expirationTime=null,this.queryPadding=0,this.hasSymbolBuckets=!1,this.hasRTLText=!1,this.dependencies={},this.rtt=[],this.rttCoords={},this.expiredRequestCount=0,this.state=\"loading\";}registerFadeDuration(e){const t=e+this.timeAdded;t<this.fadeEndTime||(this.fadeEndTime=t);}wasRequested(){return \"errored\"===this.state||\"loaded\"===this.state||\"reloading\"===this.state}clearTextures(e){this.demTexture&&e.saveTileTexture(this.demTexture),this.demTexture=null;}loadVectorData(e,i,o){if(this.hasData()&&this.unloadVectorData(),this.state=\"loaded\",e){e.featureIndex&&(this.latestFeatureIndex=e.featureIndex,e.rawTileData?(this.latestRawTileData=e.rawTileData,this.latestFeatureIndex.rawTileData=e.rawTileData):this.latestRawTileData&&(this.latestFeatureIndex.rawTileData=this.latestRawTileData)),this.collisionBoxArray=e.collisionBoxArray,this.buckets=function(e,t){const i={};if(!t)return i;for(const o of e){const e=o.layerIds.map((e=>t.getLayer(e))).filter(Boolean);if(0!==e.length){o.layers=e,o.stateDependentLayerIds&&(o.stateDependentLayers=o.stateDependentLayerIds.map((t=>e.filter((e=>e.id===t))[0])));for(const t of e)i[t.id]=o;}}return i}(e.buckets,null==i?void 0:i.style),this.hasSymbolBuckets=!1;for(const e in this.buckets){const i=this.buckets[e];if(i instanceof t.a8){if(this.hasSymbolBuckets=!0,!o)break;i.justReloaded=!0;}}if(this.hasRTLText=!1,this.hasSymbolBuckets)for(const e in this.buckets){const i=this.buckets[e];if(i instanceof t.a8&&i.hasRTLText){this.hasRTLText=!0,oe().lazyLoad();break}}this.queryPadding=0;for(const e in this.buckets){const t=this.buckets[e];this.queryPadding=Math.max(this.queryPadding,i.style.getLayer(e).queryRadius(t));}e.imageAtlas&&(this.imageAtlas=e.imageAtlas),e.glyphAtlasImage&&(this.glyphAtlasImage=e.glyphAtlasImage);}else this.collisionBoxArray=new t.a7;}unloadVectorData(){for(const e in this.buckets)this.buckets[e].destroy();this.buckets={},this.imageAtlasTexture&&this.imageAtlasTexture.destroy(),this.imageAtlas&&(this.imageAtlas=null),this.glyphAtlasTexture&&this.glyphAtlasTexture.destroy(),this.latestFeatureIndex=null,this.state=\"unloaded\";}getBucket(e){return this.buckets[e.id]}upload(e){for(const t in this.buckets){const i=this.buckets[t];i.uploadPending()&&i.upload(e);}const i=e.gl;this.imageAtlas&&!this.imageAtlas.uploaded&&(this.imageAtlasTexture=new t.T(e,this.imageAtlas.image,i.RGBA),this.imageAtlas.uploaded=!0),this.glyphAtlasImage&&(this.glyphAtlasTexture=new t.T(e,this.glyphAtlasImage,i.ALPHA),this.glyphAtlasImage=null);}prepare(e){this.imageAtlas&&this.imageAtlas.patchUpdatedImages(e,this.imageAtlasTexture);}queryRenderedFeatures(e,t,i,o,r,a,s,n,l,c,h){return this.latestFeatureIndex&&this.latestFeatureIndex.rawTileData?this.latestFeatureIndex.query({queryGeometry:o,cameraQueryGeometry:r,scale:a,tileSize:this.tileSize,pixelPosMatrix:c,transform:n,params:s,queryPadding:this.queryPadding*l,getElevation:h},e,t,i):{}}querySourceFeatures(e,i){const o=this.latestFeatureIndex;if(!o||!o.rawTileData)return;const r=o.loadVTLayers(),a=i&&i.sourceLayer?i.sourceLayer:\"\",s=r._geojsonTileLayer||r[a];if(!s)return;const n=t.a9(i&&i.filter),{z:l,x:c,y:h}=this.tileID.canonical,u={z:l,x:c,y:h};for(let i=0;i<s.length;i++){const r=s.feature(i);if(n.needGeometry){const e=t.aa(r,!0);if(!n.filter(new t.F(this.tileID.overscaledZ),e,this.tileID.canonical))continue}else if(!n.filter(new t.F(this.tileID.overscaledZ),r))continue;const d=o.getId(r,a),_=new t.ab(r,l,c,h,d);_.tile=u,e.push(_);}}hasData(){return \"loaded\"===this.state||\"reloading\"===this.state||\"expired\"===this.state}patternsLoaded(){return this.imageAtlas&&!!Object.keys(this.imageAtlas.patternPositions).length}setExpiryData(e){const i=this.expirationTime;if(e.cacheControl){const i=t.ac(e.cacheControl);i[\"max-age\"]&&(this.expirationTime=Date.now()+1e3*i[\"max-age\"]);}else e.expires&&(this.expirationTime=new Date(e.expires).getTime());if(this.expirationTime){const e=Date.now();let t=!1;if(this.expirationTime>e)t=!1;else if(i)if(this.expirationTime<i)t=!0;else {const o=this.expirationTime-i;o?this.expirationTime=e+Math.max(o,3e4):t=!0;}else t=!0;t?(this.expiredRequestCount++,this.state=\"expired\"):this.expiredRequestCount=0;}}getExpiryTimeout(){if(this.expirationTime)return this.expiredRequestCount?1e3*(1<<Math.min(this.expiredRequestCount-1,31)):Math.min(this.expirationTime-(new Date).getTime(),Math.pow(2,31)-1)}setFeatureState(e,t){if(!this.latestFeatureIndex||!this.latestFeatureIndex.rawTileData||0===Object.keys(e).length)return;const i=this.latestFeatureIndex.loadVTLayers();for(const o in this.buckets){if(!t.style.hasLayer(o))continue;const r=this.buckets[o],a=r.layers[0].sourceLayer||\"_geojsonTileLayer\",s=i[a],n=e[a];if(!s||!n||0===Object.keys(n).length)continue;r.update(n,s,this.imageAtlas&&this.imageAtlas.patternPositions||{});const l=t&&t.style&&t.style.getLayer(o);l&&(this.queryPadding=Math.max(this.queryPadding,l.queryRadius(r)));}}holdingForFade(){return void 0!==this.symbolFadeHoldUntil}symbolFadeFinished(){return !this.symbolFadeHoldUntil||this.symbolFadeHoldUntil<s.now()}clearFadeHold(){this.symbolFadeHoldUntil=void 0;}setHoldDuration(e){this.symbolFadeHoldUntil=s.now()+e;}setDependencies(e,t){const i={};for(const e of t)i[e]=!0;this.dependencies[e]=i;}hasDependency(e,t){for(const i of e){const e=this.dependencies[i];if(e)for(const i of t)if(e[i])return !0}return !1}}class ae{constructor(e,t){this.max=e,this.onRemove=t,this.reset();}reset(){for(const e in this.data)for(const t of this.data[e])t.timeout&&clearTimeout(t.timeout),this.onRemove(t.value);return this.data={},this.order=[],this}add(e,t,i){const o=e.wrapped().key;void 0===this.data[o]&&(this.data[o]=[]);const r={value:t,timeout:void 0};if(void 0!==i&&(r.timeout=setTimeout((()=>{this.remove(e,r);}),i)),this.data[o].push(r),this.order.push(o),this.order.length>this.max){const e=this._getAndRemoveByKey(this.order[0]);e&&this.onRemove(e);}return this}has(e){return e.wrapped().key in this.data}getAndRemove(e){return this.has(e)?this._getAndRemoveByKey(e.wrapped().key):null}_getAndRemoveByKey(e){const t=this.data[e].shift();return t.timeout&&clearTimeout(t.timeout),0===this.data[e].length&&delete this.data[e],this.order.splice(this.order.indexOf(e),1),t.value}getByKey(e){const t=this.data[e];return t?t[0].value:null}get(e){return this.has(e)?this.data[e.wrapped().key][0].value:null}remove(e,t){if(!this.has(e))return this;const i=e.wrapped().key,o=void 0===t?0:this.data[i].indexOf(t),r=this.data[i][o];return this.data[i].splice(o,1),r.timeout&&clearTimeout(r.timeout),0===this.data[i].length&&delete this.data[i],this.onRemove(r.value),this.order.splice(this.order.indexOf(i),1),this}setMaxSize(e){for(this.max=e;this.order.length>this.max;){const e=this._getAndRemoveByKey(this.order[0]);e&&this.onRemove(e);}return this}filter(e){const t=[];for(const i in this.data)for(const o of this.data[i])e(o.value)||t.push(o);for(const e of t)this.remove(e.value.tileID,e);}}class se{constructor(){this.state={},this.stateChanges={},this.deletedStates={};}updateState(e,i,o){const r=String(i);if(this.stateChanges[e]=this.stateChanges[e]||{},this.stateChanges[e][r]=this.stateChanges[e][r]||{},t.e(this.stateChanges[e][r],o),null===this.deletedStates[e]){this.deletedStates[e]={};for(const t in this.state[e])t!==r&&(this.deletedStates[e][t]=null);}else if(this.deletedStates[e]&&null===this.deletedStates[e][r]){this.deletedStates[e][r]={};for(const t in this.state[e][r])o[t]||(this.deletedStates[e][r][t]=null);}else for(const t in o)this.deletedStates[e]&&this.deletedStates[e][r]&&null===this.deletedStates[e][r][t]&&delete this.deletedStates[e][r][t];}removeFeatureState(e,t,i){if(null===this.deletedStates[e])return;const o=String(t);if(this.deletedStates[e]=this.deletedStates[e]||{},i&&void 0!==t)null!==this.deletedStates[e][o]&&(this.deletedStates[e][o]=this.deletedStates[e][o]||{},this.deletedStates[e][o][i]=null);else if(void 0!==t)if(this.stateChanges[e]&&this.stateChanges[e][o])for(i in this.deletedStates[e][o]={},this.stateChanges[e][o])this.deletedStates[e][o][i]=null;else this.deletedStates[e][o]=null;else this.deletedStates[e]=null;}getState(e,i){const o=String(i),r=t.e({},(this.state[e]||{})[o],(this.stateChanges[e]||{})[o]);if(null===this.deletedStates[e])return {};if(this.deletedStates[e]){const t=this.deletedStates[e][i];if(null===t)return {};for(const e in t)delete r[e];}return r}initializeTileState(e,t){e.setFeatureState(this.state,t);}coalesceChanges(e,i){const o={};for(const e in this.stateChanges){this.state[e]=this.state[e]||{};const i={};for(const o in this.stateChanges[e])this.state[e][o]||(this.state[e][o]={}),t.e(this.state[e][o],this.stateChanges[e][o]),i[o]=this.state[e][o];o[e]=i;}for(const e in this.deletedStates){this.state[e]=this.state[e]||{};const i={};if(null===this.deletedStates[e])for(const t in this.state[e])i[t]={},this.state[e][t]={};else for(const t in this.deletedStates[e]){if(null===this.deletedStates[e][t])this.state[e][t]={};else for(const i of Object.keys(this.deletedStates[e][t]))delete this.state[e][t][i];i[t]=this.state[e][t];}o[e]=o[e]||{},t.e(o[e],i);}if(this.stateChanges={},this.deletedStates={},0!==Object.keys(o).length)for(const t in e)e[t].setFeatureState(o,i);}}const ne=89.25;function le(e,i){const o=t.ag(i.lat,-85.051129,t.ah);return new t.P(t.V(i.lng)*e,t.U(o)*e)}function ce(e,i){return new t.a0(i.x/e,i.y/e).toLngLat()}function he(e){return e.cameraToCenterDistance*Math.min(.85*Math.tan(t.ad(90-e.pitch)),Math.tan(t.ad(ne-e.pitch)))}function ue(e,i){const o=e.canonical,r=i/t.ae(o.z),a=o.x+Math.pow(2,o.z)*e.wrap,s=t.af(new Float64Array(16));return t.M(s,s,[a*r,o.y*r,0]),t.N(s,s,[r/t.$,r/t.$,1]),s}function de(e,i,o,r,a){const s=t.a0.fromLngLat(e,i),n=a*t.ai(1,e.lat),l=n*Math.cos(t.ad(o)),c=Math.sqrt(n*n-l*l),h=c*Math.sin(t.ad(-r)),u=c*Math.cos(t.ad(-r));return new t.a0(s.x+h,s.y+u,s.z+l)}function _e(e,t,i){const o=t.intersectsFrustum(e);if(!i||0===o)return o;const r=t.intersectsPlane(i);return 0===r?0:2===o&&2===r?2:1}function pe(e,t,i){let o=0;const r=(i-t)/10;for(let a=0;a<10;a++)o+=r*Math.pow(Math.cos(t+(a+.5)/10*(i-t)),e);return o}function me(e,i){return function(o,r,a,s,n){const l=2*((e-1)/t.aj(Math.cos(t.ad(ne-n))/Math.cos(t.ad(ne)))-1),c=Math.acos(a/s),h=2*pe(l-1,0,t.ad(n/2)),u=Math.min(t.ad(ne),c+t.ad(n/2)),d=pe(l-1,Math.min(u,c-t.ad(n/2)),u),_=Math.atan(r/a),p=Math.hypot(r,a);let m=o;return m+=t.aj(s/p/Math.max(.5,Math.cos(t.ad(n/2)))),m+=l*t.aj(Math.cos(_))/2,m-=t.aj(Math.max(1,d/h/i))/2,m}}const fe=me(9.314,3);function ge(e,i){const o=(i.roundZoom?Math.round:Math.floor)(e.zoom+t.aj(e.tileSize/i.tileSize));return Math.max(0,o)}function ve(e,i){const o=e.getCameraFrustum(),r=e.getClippingPlane(),a=e.screenPointToMercatorCoordinate(e.getCameraPoint()),s=t.a0.fromLngLat(e.center,e.elevation);a.z=s.z+Math.cos(e.pitchInRadians)*e.cameraToCenterDistance/e.worldSize;const n=e.getCoveringTilesDetailsProvider(),l=n.allowVariableZoom(e,i),c=ge(e,i),h=i.minzoom||0,u=void 0!==i.maxzoom?i.maxzoom:e.maxZoom,d=Math.min(Math.max(0,c),u),_=Math.pow(2,d),p=[_*a.x,_*a.y,0],m=[_*s.x,_*s.y,0],f=Math.hypot(s.x-a.x,s.y-a.y),g=Math.abs(s.z-a.z),v=Math.hypot(f,g),b=e=>({zoom:0,x:0,y:0,wrap:e,fullyVisible:!1}),x=[],y=[];if(e.renderWorldCopies&&n.allowWorldCopies())for(let e=1;e<=3;e++)x.push(b(-e)),x.push(b(e));for(x.push(b(0));x.length>0;){const _=x.pop(),f=_.x,b=_.y;let w=_.fullyVisible;const T={x:f,y:b,z:_.zoom},P=n.getTileBoundingVolume(T,_.wrap,e.elevation,i);if(!w){const e=_e(o,P,r);if(0===e)continue;w=2===e;}const C=n.distanceToTile2d(a.x,a.y,T,P);let I=c;l&&(I=(i.calculateTileZoom||fe)(e.zoom+t.aj(e.tileSize/i.tileSize),C,g,v,e.fov)),I=(i.roundZoom?Math.round:Math.floor)(I),I=Math.max(0,I);const M=Math.min(I,u);if(_.wrap=n.getWrap(s,T,_.wrap),_.zoom>=M){if(_.zoom<h)continue;const e=d-_.zoom,o=p[0]-.5-(f<<e),r=p[1]-.5-(b<<e),a=i.reparseOverscaled?Math.max(_.zoom,I):_.zoom;y.push({tileID:new t.Z(_.zoom===u?a:_.zoom,_.wrap,_.zoom,f,b),distanceSq:t.ak([m[0]-.5-f,m[1]-.5-b]),tileDistanceToCamera:Math.sqrt(o*o+r*r)});}else for(let e=0;e<4;e++)x.push({zoom:_.zoom+1,x:(f<<1)+e%2,y:(b<<1)+(e>>1),wrap:_.wrap,fullyVisible:w});}return y.sort(((e,t)=>e.distanceSq-t.distanceSq)).map((e=>e.tileID))}const be=t.a1.fromPoints([new t.P(0,0),new t.P(t.$,t.$)]);class xe extends t.E{constructor(e,t,i){super(),this.id=e,this.dispatcher=i,this.on(\"data\",(e=>this._dataHandler(e))),this.on(\"dataloading\",(()=>{this._sourceErrored=!1;})),this.on(\"error\",(()=>{this._sourceErrored=this._source.loaded();})),this._source=((e,t,i,o)=>{const r=new(J(t.type))(e,t,i,o);if(r.id!==e)throw new Error(`Expected Source id to be ${e} instead of ${r.id}`);return r})(e,t,i,this),this._tiles={},this._cache=new ae(0,(e=>this._unloadTile(e))),this._timers={},this._cacheTimers={},this._maxTileCacheSize=null,this._maxTileCacheZoomLevels=null,this._loadedParentTiles={},this._coveredTiles={},this._state=new se,this._didEmitContent=!1,this._updated=!1;}onAdd(e){this.map=e,this._maxTileCacheSize=e?e._maxTileCacheSize:null,this._maxTileCacheZoomLevels=e?e._maxTileCacheZoomLevels:null,this._source&&this._source.onAdd&&this._source.onAdd(e);}onRemove(e){this.clearTiles(),this._source&&this._source.onRemove&&this._source.onRemove(e);}loaded(){if(this._sourceErrored)return !0;if(!this._sourceLoaded)return !1;if(!this._source.loaded())return !1;if(!(void 0===this.used&&void 0===this.usedForTerrain||this.used||this.usedForTerrain))return !0;if(!this._updated)return !1;for(const e in this._tiles){const t=this._tiles[e];if(\"loaded\"!==t.state&&\"errored\"!==t.state)return !1}return !0}getSource(){return this._source}pause(){this._paused=!0;}resume(){if(!this._paused)return;const e=this._shouldReloadOnResume;this._paused=!1,this._shouldReloadOnResume=!1,e&&this.reload(),this.transform&&this.update(this.transform,this.terrain);}_loadTile(e,i,o){return t._(this,void 0,void 0,(function*(){try{yield this._source.loadTile(e),this._tileLoaded(e,i,o);}catch(i){e.state=\"errored\",404!==i.status?this._source.fire(new t.k(i,{tile:e})):this.update(this.transform,this.terrain);}}))}_unloadTile(e){this._source.unloadTile&&this._source.unloadTile(e);}_abortTile(e){this._source.abortTile&&this._source.abortTile(e),this._source.fire(new t.l(\"dataabort\",{tile:e,coord:e.tileID,dataType:\"source\"}));}serialize(){return this._source.serialize()}prepare(e){this._source.prepare&&this._source.prepare(),this._state.coalesceChanges(this._tiles,this.map?this.map.painter:null);for(const t in this._tiles){const i=this._tiles[t];i.upload(e),i.prepare(this.map.style.imageManager);}}getIds(){return Object.values(this._tiles).map((e=>e.tileID)).sort(ye).map((e=>e.key))}getRenderableIds(e){const i=[];for(const t in this._tiles)this._isIdRenderable(t,e)&&i.push(this._tiles[t]);return e?i.sort(((e,i)=>{const o=e.tileID,r=i.tileID,a=new t.P(o.canonical.x,o.canonical.y)._rotate(-this.transform.bearingInRadians),s=new t.P(r.canonical.x,r.canonical.y)._rotate(-this.transform.bearingInRadians);return o.overscaledZ-r.overscaledZ||s.y-a.y||s.x-a.x})).map((e=>e.tileID.key)):i.map((e=>e.tileID)).sort(ye).map((e=>e.key))}hasRenderableParent(e){const t=this.findLoadedParent(e,0);return !!t&&this._isIdRenderable(t.tileID.key)}_isIdRenderable(e,t){return this._tiles[e]&&this._tiles[e].hasData()&&!this._coveredTiles[e]&&(t||!this._tiles[e].holdingForFade())}reload(e){if(this._paused)this._shouldReloadOnResume=!0;else {this._cache.reset();for(const t in this._tiles)e?this._reloadTile(t,\"expired\"):\"errored\"!==this._tiles[t].state&&this._reloadTile(t,\"reloading\");}}_reloadTile(e,i){return t._(this,void 0,void 0,(function*(){const t=this._tiles[e];t&&(\"loading\"!==t.state&&(t.state=i),yield this._loadTile(t,e,i));}))}_tileLoaded(e,i,o){e.timeAdded=s.now(),\"expired\"===o&&(e.refreshedUponExpiration=!0),this._setTileReloadTimer(i,e),\"raster-dem\"===this.getSource().type&&e.dem&&this._backfillDEM(e),this._state.initializeTileState(e,this.map?this.map.painter:null),e.aborted||this._source.fire(new t.l(\"data\",{dataType:\"source\",tile:e,coord:e.tileID}));}_backfillDEM(e){const t=this.getRenderableIds();for(let o=0;o<t.length;o++){const r=t[o];if(e.neighboringTiles&&e.neighboringTiles[r]){const t=this.getTileByID(r);i(e,t),i(t,e);}}function i(e,t){e.needsHillshadePrepare=!0,e.needsTerrainPrepare=!0;let i=t.tileID.canonical.x-e.tileID.canonical.x;const o=t.tileID.canonical.y-e.tileID.canonical.y,r=Math.pow(2,e.tileID.canonical.z),a=t.tileID.key;0===i&&0===o||Math.abs(o)>1||(Math.abs(i)>1&&(1===Math.abs(i+r)?i+=r:1===Math.abs(i-r)&&(i-=r)),t.dem&&e.dem&&(e.dem.backfillBorder(t.dem,i,o),e.neighboringTiles&&e.neighboringTiles[a]&&(e.neighboringTiles[a].backfilled=!0)));}}getTile(e){return this.getTileByID(e.key)}getTileByID(e){return this._tiles[e]}_retainLoadedChildren(e,t,i,o){for(const r in this._tiles){let a=this._tiles[r];if(o[r]||!a.hasData()||a.tileID.overscaledZ<=t||a.tileID.overscaledZ>i)continue;let s=a.tileID;for(;a&&a.tileID.overscaledZ>t+1;){const e=a.tileID.scaledTo(a.tileID.overscaledZ-1);a=this._tiles[e.key],a&&a.hasData()&&(s=e);}let n=s;for(;n.overscaledZ>t;)if(n=n.scaledTo(n.overscaledZ-1),e[n.key]||e[n.canonical.key]){o[s.key]=s;break}}}findLoadedParent(e,t){if(e.key in this._loadedParentTiles){const i=this._loadedParentTiles[e.key];return i&&i.tileID.overscaledZ>=t?i:null}for(let i=e.overscaledZ-1;i>=t;i--){const t=e.scaledTo(i),o=this._getLoadedTile(t);if(o)return o}}findLoadedSibling(e){return this._getLoadedTile(e)}_getLoadedTile(e){const t=this._tiles[e.key];return t&&t.hasData()?t:this._cache.getByKey(e.wrapped().key)}updateCacheSize(e){const i=Math.ceil(e.width/this._source.tileSize)+1,o=Math.ceil(e.height/this._source.tileSize)+1,r=Math.floor(i*o*(null===this._maxTileCacheZoomLevels?t.a.MAX_TILE_CACHE_ZOOM_LEVELS:this._maxTileCacheZoomLevels)),a=\"number\"==typeof this._maxTileCacheSize?Math.min(this._maxTileCacheSize,r):r;this._cache.setMaxSize(a);}handleWrapJump(e){const t=Math.round((e-(void 0===this._prevLng?e:this._prevLng))/360);if(this._prevLng=e,t){const e={};for(const i in this._tiles){const o=this._tiles[i];o.tileID=o.tileID.unwrapTo(o.tileID.wrap+t),e[o.tileID.key]=o;}this._tiles=e;for(const e in this._timers)clearTimeout(this._timers[e]),delete this._timers[e];for(const e in this._tiles)this._setTileReloadTimer(e,this._tiles[e]);}}_updateCoveredAndRetainedTiles(e,t,i,o,r,a){const n={},l={},c=Object.keys(e),h=s.now();for(const i of c){const o=e[i],r=this._tiles[i];if(!r||0!==r.fadeEndTime&&r.fadeEndTime<=h)continue;const a=this.findLoadedParent(o,t),s=this.findLoadedSibling(o),c=a||s||null;c&&(this._addTile(c.tileID),n[c.tileID.key]=c.tileID),l[i]=o;}this._retainLoadedChildren(l,o,i,e);for(const t in n)e[t]||(this._coveredTiles[t]=!0,e[t]=n[t]);if(a){const t={},i={};for(const e of r)this._tiles[e.key].hasData()?t[e.key]=e:i[e.key]=e;for(const o in i){const r=i[o].children(this._source.maxzoom);this._tiles[r[0].key]&&this._tiles[r[1].key]&&this._tiles[r[2].key]&&this._tiles[r[3].key]&&(t[r[0].key]=e[r[0].key]=r[0],t[r[1].key]=e[r[1].key]=r[1],t[r[2].key]=e[r[2].key]=r[2],t[r[3].key]=e[r[3].key]=r[3],delete i[o]);}for(const o in i){const r=i[o],a=this.findLoadedParent(r,this._source.minzoom),s=this.findLoadedSibling(r),n=a||s||null;if(n){t[n.tileID.key]=e[n.tileID.key]=n.tileID;for(const e in t)t[e].isChildOf(n.tileID)&&delete t[e];}}for(const e in this._tiles)t[e]||(this._coveredTiles[e]=!0);}}update(e,i){if(!this._sourceLoaded||this._paused)return;let o;this.transform=e,this.terrain=i,this.updateCacheSize(e),this.handleWrapJump(this.transform.center.lng),this._coveredTiles={},this.used||this.usedForTerrain?this._source.tileID?o=e.getVisibleUnwrappedCoordinates(this._source.tileID).map((e=>new t.Z(e.canonical.z,e.wrap,e.canonical.z,e.canonical.x,e.canonical.y))):(o=ve(e,{tileSize:this.usedForTerrain?this.tileSize:this._source.tileSize,minzoom:this._source.minzoom,maxzoom:this._source.maxzoom,roundZoom:!this.usedForTerrain&&this._source.roundZoom,reparseOverscaled:this._source.reparseOverscaled,terrain:i,calculateTileZoom:this._source.calculateTileZoom}),this._source.hasTile&&(o=o.filter((e=>this._source.hasTile(e))))):o=[];const r=ge(e,this._source),a=Math.max(r-xe.maxOverzooming,this._source.minzoom),s=Math.max(r+xe.maxUnderzooming,this._source.minzoom);if(this.usedForTerrain){const e={};for(const t of o)if(t.canonical.z>this._source.minzoom){const i=t.scaledTo(t.canonical.z-1);e[i.key]=i;const o=t.scaledTo(Math.max(this._source.minzoom,Math.min(t.canonical.z,5)));e[o.key]=o;}o=o.concat(Object.values(e));}const n=0===o.length&&!this._updated&&this._didEmitContent;this._updated=!0,n&&this.fire(new t.l(\"data\",{sourceDataType:\"idle\",dataType:\"source\",sourceId:this.id}));const l=this._updateRetainedTiles(o,r);we(this._source.type)&&this._updateCoveredAndRetainedTiles(l,a,s,r,o,i);for(const e in l)this._tiles[e].clearFadeHold();const c=t.al(this._tiles,l);for(const e of c){const t=this._tiles[e];t.hasSymbolBuckets&&!t.holdingForFade()?t.setHoldDuration(this.map._fadeDuration):t.hasSymbolBuckets&&!t.symbolFadeFinished()||this._removeTile(e);}this._updateLoadedParentTileCache(),this._updateLoadedSiblingTileCache();}releaseSymbolFadeTiles(){for(const e in this._tiles)this._tiles[e].holdingForFade()&&this._removeTile(e);}_updateRetainedTiles(e,t){var i;const o={},r={},a=Math.max(t-xe.maxOverzooming,this._source.minzoom),s=Math.max(t+xe.maxUnderzooming,this._source.minzoom),n={};for(const i of e){const e=this._addTile(i);o[i.key]=i,e.hasData()||t<this._source.maxzoom&&(n[i.key]=i);}this._retainLoadedChildren(n,t,s,o);for(const s of e){let e=this._tiles[s.key];if(e.hasData())continue;if(t+1>this._source.maxzoom){const e=s.children(this._source.maxzoom)[0],t=this.getTile(e);if(t&&t.hasData()){o[e.key]=e;continue}}else {const e=s.children(this._source.maxzoom);if(o[e[0].key]&&o[e[1].key]&&o[e[2].key]&&o[e[3].key])continue}let n=e.wasRequested();for(let t=s.overscaledZ-1;t>=a;--t){const a=s.scaledTo(t);if(r[a.key])break;if(r[a.key]=!0,e=this.getTile(a),!e&&n&&(e=this._addTile(a)),e){const t=e.hasData();if((t||!(null===(i=this.map)||void 0===i?void 0:i.cancelPendingTileRequestsWhileZooming)||n)&&(o[a.key]=a),n=e.wasRequested(),t)break}}}return o}_updateLoadedParentTileCache(){this._loadedParentTiles={};for(const e in this._tiles){const t=[];let i,o=this._tiles[e].tileID;for(;o.overscaledZ>0;){if(o.key in this._loadedParentTiles){i=this._loadedParentTiles[o.key];break}t.push(o.key);const e=o.scaledTo(o.overscaledZ-1);if(i=this._getLoadedTile(e),i)break;o=e;}for(const e of t)this._loadedParentTiles[e]=i;}}_updateLoadedSiblingTileCache(){this._loadedSiblingTiles={};for(const e in this._tiles){const t=this._tiles[e].tileID,i=this._getLoadedTile(t);this._loadedSiblingTiles[t.key]=i;}}_addTile(e){let i=this._tiles[e.key];if(i)return i;i=this._cache.getAndRemove(e),i&&(this._setTileReloadTimer(e.key,i),i.tileID=e,this._state.initializeTileState(i,this.map?this.map.painter:null),this._cacheTimers[e.key]&&(clearTimeout(this._cacheTimers[e.key]),delete this._cacheTimers[e.key],this._setTileReloadTimer(e.key,i)));const o=i;return i||(i=new re(e,this._source.tileSize*e.overscaleFactor()),this._loadTile(i,e.key,i.state)),i.uses++,this._tiles[e.key]=i,o||this._source.fire(new t.l(\"dataloading\",{tile:i,coord:i.tileID,dataType:\"source\"})),i}_setTileReloadTimer(e,t){e in this._timers&&(clearTimeout(this._timers[e]),delete this._timers[e]);const i=t.getExpiryTimeout();i&&(this._timers[e]=setTimeout((()=>{this._reloadTile(e,\"expired\"),delete this._timers[e];}),i));}refreshTiles(e){for(const t in this._tiles)(this._isIdRenderable(t)||\"errored\"==this._tiles[t].state)&&e.some((e=>e.equals(this._tiles[t].tileID.canonical)))&&this._reloadTile(t,\"expired\");}_removeTile(e){const t=this._tiles[e];t&&(t.uses--,delete this._tiles[e],this._timers[e]&&(clearTimeout(this._timers[e]),delete this._timers[e]),t.uses>0||(t.hasData()&&\"reloading\"!==t.state?this._cache.add(t.tileID,t,t.getExpiryTimeout()):(t.aborted=!0,this._abortTile(t),this._unloadTile(t))));}_dataHandler(e){const t=e.sourceDataType;\"source\"===e.dataType&&\"metadata\"===t&&(this._sourceLoaded=!0),this._sourceLoaded&&!this._paused&&\"source\"===e.dataType&&\"content\"===t&&(this.reload(e.sourceDataChanged),this.transform&&this.update(this.transform,this.terrain),this._didEmitContent=!0);}clearTiles(){this._shouldReloadOnResume=!1,this._paused=!1;for(const e in this._tiles)this._removeTile(e);this._cache.reset();}tilesIn(e,i,o){const r=[],a=this.transform;if(!a)return r;const s=a.getCoveringTilesDetailsProvider().allowWorldCopies(),n=o?a.getCameraQueryGeometry(e):e,l=e=>a.screenPointToMercatorCoordinate(e,this.terrain),c=this.transformBbox(e,l,!s),h=this.transformBbox(n,l,!s),u=this.getIds(),d=t.a1.fromPoints(h);for(let e=0;e<u.length;e++){const o=this._tiles[u[e]];if(o.holdingForFade())continue;const n=s?[o.tileID]:[o.tileID.unwrapTo(-1),o.tileID.unwrapTo(0)],l=Math.pow(2,a.zoom-o.tileID.overscaledZ),_=i*o.queryPadding*t.$/o.tileSize/l;for(const e of n){const i=d.map((i=>e.getTilePoint(new t.a0(i.x,i.y))));if(i.expandBy(_),i.intersects(be)){const t=c.map((t=>e.getTilePoint(t))),i=h.map((t=>e.getTilePoint(t)));r.push({tile:o,tileID:s?e:e.unwrapTo(0),queryGeometry:t,cameraQueryGeometry:i,scale:l});}}}return r}transformBbox(e,i,o){let r=e.map(i);if(o){const o=t.a1.fromPoints(e);o.shrinkBy(.001*Math.min(o.width(),o.height()));const a=o.map(i);t.a1.fromPoints(r).covers(a)||(r=r.map((e=>e.x>.5?new t.a0(e.x-1,e.y,e.z):e)));}return r}getVisibleCoordinates(e){const t=this.getRenderableIds(e).map((e=>this._tiles[e].tileID));return this.transform&&this.transform.populateCache(t),t}hasTransition(){if(this._source.hasTransition())return !0;if(we(this._source.type)){const e=s.now();for(const t in this._tiles)if(this._tiles[t].fadeEndTime>=e)return !0}return !1}setFeatureState(e,t,i){this._state.updateState(e=e||\"_geojsonTileLayer\",t,i);}removeFeatureState(e,t,i){this._state.removeFeatureState(e=e||\"_geojsonTileLayer\",t,i);}getFeatureState(e,t){return this._state.getState(e=e||\"_geojsonTileLayer\",t)}setDependencies(e,t,i){const o=this._tiles[e];o&&o.setDependencies(t,i);}reloadTilesForDependencies(e,t){for(const i in this._tiles)this._tiles[i].hasDependency(e,t)&&this._reloadTile(i,\"reloading\");this._cache.filter((i=>!i.hasDependency(e,t)));}}function ye(e,t){const i=Math.abs(2*e.wrap)-+(e.wrap<0),o=Math.abs(2*t.wrap)-+(t.wrap<0);return e.overscaledZ-t.overscaledZ||o-i||t.canonical.y-e.canonical.y||t.canonical.x-e.canonical.x}function we(e){return \"raster\"===e||\"image\"===e||\"video\"===e}xe.maxOverzooming=10,xe.maxUnderzooming=3;class Te{constructor(e,t){this.reset(e,t);}reset(e,t){this.points=e||[],this._distances=[0];for(let e=1;e<this.points.length;e++)this._distances[e]=this._distances[e-1]+this.points[e].dist(this.points[e-1]);this.length=this._distances[this._distances.length-1],this.padding=Math.min(t||0,.5*this.length),this.paddedLength=this.length-2*this.padding;}lerp(e){if(1===this.points.length)return this.points[0];e=t.ag(e,0,1);let i=1,o=this._distances[i];const r=e*this.paddedLength+this.padding;for(;o<r&&i<this._distances.length;)o=this._distances[++i];const a=i-1,s=this._distances[a],n=o-s,l=n>0?(r-s)/n:0;return this.points[a].mult(1-l).add(this.points[i].mult(l))}}function Pe(e,t){let i=!0;return \"always\"===e||\"never\"!==e&&\"never\"!==t||(i=!1),i}class Ce{constructor(e,t,i){const o=this.boxCells=[],r=this.circleCells=[];this.xCellCount=Math.ceil(e/i),this.yCellCount=Math.ceil(t/i);for(let e=0;e<this.xCellCount*this.yCellCount;e++)o.push([]),r.push([]);this.circleKeys=[],this.boxKeys=[],this.bboxes=[],this.circles=[],this.width=e,this.height=t,this.xScale=this.xCellCount/e,this.yScale=this.yCellCount/t,this.boxUid=0,this.circleUid=0;}keysLength(){return this.boxKeys.length+this.circleKeys.length}insert(e,t,i,o,r){this._forEachCell(t,i,o,r,this._insertBoxCell,this.boxUid++),this.boxKeys.push(e),this.bboxes.push(t),this.bboxes.push(i),this.bboxes.push(o),this.bboxes.push(r);}insertCircle(e,t,i,o){this._forEachCell(t-o,i-o,t+o,i+o,this._insertCircleCell,this.circleUid++),this.circleKeys.push(e),this.circles.push(t),this.circles.push(i),this.circles.push(o);}_insertBoxCell(e,t,i,o,r,a){this.boxCells[r].push(a);}_insertCircleCell(e,t,i,o,r,a){this.circleCells[r].push(a);}_query(e,t,i,o,r,a,s){if(i<0||e>this.width||o<0||t>this.height)return [];const n=[];if(e<=0&&t<=0&&this.width<=i&&this.height<=o){if(r)return [{key:null,x1:e,y1:t,x2:i,y2:o}];for(let e=0;e<this.boxKeys.length;e++)n.push({key:this.boxKeys[e],x1:this.bboxes[4*e],y1:this.bboxes[4*e+1],x2:this.bboxes[4*e+2],y2:this.bboxes[4*e+3]});for(let e=0;e<this.circleKeys.length;e++){const t=this.circles[3*e],i=this.circles[3*e+1],o=this.circles[3*e+2];n.push({key:this.circleKeys[e],x1:t-o,y1:i-o,x2:t+o,y2:i+o});}}else this._forEachCell(e,t,i,o,this._queryCell,n,{hitTest:r,overlapMode:a,seenUids:{box:{},circle:{}}},s);return n}query(e,t,i,o){return this._query(e,t,i,o,!1,null)}hitTest(e,t,i,o,r,a){return this._query(e,t,i,o,!0,r,a).length>0}hitTestCircle(e,t,i,o,r){const a=e-i,s=e+i,n=t-i,l=t+i;if(s<0||a>this.width||l<0||n>this.height)return !1;const c=[];return this._forEachCell(a,n,s,l,this._queryCellCircle,c,{hitTest:!0,overlapMode:o,circle:{x:e,y:t,radius:i},seenUids:{box:{},circle:{}}},r),c.length>0}_queryCell(e,t,i,o,r,a,s,n){const{seenUids:l,hitTest:c,overlapMode:h}=s,u=this.boxCells[r];if(null!==u){const r=this.bboxes;for(const s of u)if(!l.box[s]){l.box[s]=!0;const u=4*s,d=this.boxKeys[s];if(e<=r[u+2]&&t<=r[u+3]&&i>=r[u+0]&&o>=r[u+1]&&(!n||n(d))&&(!c||!Pe(h,d.overlapMode))&&(a.push({key:d,x1:r[u],y1:r[u+1],x2:r[u+2],y2:r[u+3]}),c))return !0}}const d=this.circleCells[r];if(null!==d){const r=this.circles;for(const s of d)if(!l.circle[s]){l.circle[s]=!0;const u=3*s,d=this.circleKeys[s];if(this._circleAndRectCollide(r[u],r[u+1],r[u+2],e,t,i,o)&&(!n||n(d))&&(!c||!Pe(h,d.overlapMode))){const e=r[u],t=r[u+1],i=r[u+2];if(a.push({key:d,x1:e-i,y1:t-i,x2:e+i,y2:t+i}),c)return !0}}}return !1}_queryCellCircle(e,t,i,o,r,a,s,n){const{circle:l,seenUids:c,overlapMode:h}=s,u=this.boxCells[r];if(null!==u){const e=this.bboxes;for(const t of u)if(!c.box[t]){c.box[t]=!0;const i=4*t,o=this.boxKeys[t];if(this._circleAndRectCollide(l.x,l.y,l.radius,e[i+0],e[i+1],e[i+2],e[i+3])&&(!n||n(o))&&!Pe(h,o.overlapMode))return a.push(!0),!0}}const d=this.circleCells[r];if(null!==d){const e=this.circles;for(const t of d)if(!c.circle[t]){c.circle[t]=!0;const i=3*t,o=this.circleKeys[t];if(this._circlesCollide(e[i],e[i+1],e[i+2],l.x,l.y,l.radius)&&(!n||n(o))&&!Pe(h,o.overlapMode))return a.push(!0),!0}}}_forEachCell(e,t,i,o,r,a,s,n){const l=this._convertToXCellCoord(e),c=this._convertToYCellCoord(t),h=this._convertToXCellCoord(i),u=this._convertToYCellCoord(o);for(let d=l;d<=h;d++)for(let l=c;l<=u;l++)if(r.call(this,e,t,i,o,this.xCellCount*l+d,a,s,n))return}_convertToXCellCoord(e){return Math.max(0,Math.min(this.xCellCount-1,Math.floor(e*this.xScale)))}_convertToYCellCoord(e){return Math.max(0,Math.min(this.yCellCount-1,Math.floor(e*this.yScale)))}_circlesCollide(e,t,i,o,r,a){const s=o-e,n=r-t,l=i+a;return l*l>s*s+n*n}_circleAndRectCollide(e,t,i,o,r,a,s){const n=(a-o)/2,l=Math.abs(e-(o+n));if(l>n+i)return !1;const c=(s-r)/2,h=Math.abs(t-(r+c));if(h>c+i)return !1;if(l<=n||h<=c)return !0;const u=l-n,d=h-c;return u*u+d*d<=i*i}}function Ie(e,i,r){const a=t.L();if(!e){const{vecSouth:e,vecEast:t}=Se(i),r=o();r[0]=t[0],r[1]=t[1],r[2]=e[0],r[3]=e[1],s=r,(d=(l=(n=r)[0])*(u=n[3])-(h=n[2])*(c=n[1]))&&(s[0]=u*(d=1/d),s[1]=-c*d,s[2]=-h*d,s[3]=l*d),a[0]=r[0],a[1]=r[1],a[4]=r[2],a[5]=r[3];}var s,n,l,c,h,u,d;return t.N(a,a,[1/r,1/r,1]),a}function Me(e,i,o,r){if(e){const e=t.L();if(!i){const{vecSouth:t,vecEast:i}=Se(o);e[0]=i[0],e[1]=i[1],e[4]=t[0],e[5]=t[1];}return t.N(e,e,[r,r,1]),e}return o.pixelsToClipSpaceMatrix}function Se(e){const i=Math.cos(e.rollInRadians),o=Math.sin(e.rollInRadians),r=Math.cos(e.pitchInRadians),a=Math.cos(e.bearingInRadians),s=Math.sin(e.bearingInRadians),n=t.aq();n[0]=-a*r*o-s*i,n[1]=-s*r*o+a*i;const l=t.ar(n);l<1e-9?t.as(n):t.at(n,n,1/l);const c=t.aq();c[0]=a*r*i-s*o,c[1]=s*r*i+a*o;const h=t.ar(c);return h<1e-9?t.as(c):t.at(c,c,1/h),{vecEast:c,vecSouth:n}}function Ee(e,i,o,r){let a;r?(a=[e,i,r(e,i),1],t.av(a,a,o)):(a=[e,i,0,1],qe(a,a,o));const s=a[3];return {point:new t.P(a[0]/s,a[1]/s),signedDistanceFromCamera:s,isOccluded:!1}}function Re(e,t){return .5+e/t*.5}function ze(e,t){return e.x>=-t[0]&&e.x<=t[0]&&e.y>=-t[1]&&e.y<=t[1]}function De(e,i,o,r,a,s,n,l,c,h,u,d,_){const p=o?e.textSizeData:e.iconSizeData,m=t.am(p,i.transform.zoom),f=[256/i.width*2+1,256/i.height*2+1],g=o?e.text.dynamicLayoutVertexArray:e.icon.dynamicLayoutVertexArray;g.clear();const v=e.lineVertexArray,b=o?e.text.placedSymbolArray:e.icon.placedSymbolArray,x=i.transform.width/i.transform.height;let y=!1;for(let o=0;o<b.length;o++){const w=b.get(o);if(w.hidden||w.writingMode===t.an.vertical&&!y){$e(w.numGlyphs,g);continue}y=!1;const T=new t.P(w.anchorX,w.anchorY),P={getElevation:_,pitchedLabelPlaneMatrix:r,lineVertexArray:v,pitchWithMap:s,projectionCache:{projections:{},offsets:{},cachedAnchorPoint:void 0,anyProjectionOccluded:!1},transform:i.transform,tileAnchorPoint:T,unwrappedTileID:c,width:h,height:u,translation:d},C=Ne(w.anchorX,w.anchorY,P);if(!ze(C.point,f)){$e(w.numGlyphs,g);continue}const I=Re(i.transform.cameraToCenterDistance,C.signedDistanceFromCamera),M=t.ao(p,m,w),S=s?M*i.transform.getPitchedTextCorrection(w.anchorX,w.anchorY,c)/I:M*I,E=ke({projectionContext:P,pitchedLabelPlaneMatrixInverse:a,symbol:w,fontSize:S,flip:!1,keepUpright:n,glyphOffsetArray:e.glyphOffsetArray,dynamicLayoutVertexArray:g,aspectRatio:x,rotateToLine:l});y=E.useVertical,(E.notEnoughRoom||y||E.needsFlipping&&ke({projectionContext:P,pitchedLabelPlaneMatrixInverse:a,symbol:w,fontSize:S,flip:!0,keepUpright:n,glyphOffsetArray:e.glyphOffsetArray,dynamicLayoutVertexArray:g,aspectRatio:x,rotateToLine:l}).notEnoughRoom)&&$e(w.numGlyphs,g);}o?e.text.dynamicLayoutVertexBuffer.updateData(g):e.icon.dynamicLayoutVertexBuffer.updateData(g);}function Ae(e,t,i,o,r,a,s,n){const l=a.glyphStartIndex+a.numGlyphs,c=a.lineStartIndex,h=a.lineStartIndex+a.lineLength,u=t.getoffsetX(a.glyphStartIndex),d=t.getoffsetX(l-1),_=Ge(e*u,i,o,r,a.segment,c,h,n,s);if(!_)return null;const p=Ge(e*d,i,o,r,a.segment,c,h,n,s);return p?n.projectionCache.anyProjectionOccluded?null:{first:_,last:p}:null}function Le(e,i,o,r){return e===t.an.horizontal&&Math.abs(o.y-i.y)>Math.abs(o.x-i.x)*r?{useVertical:!0}:(e===t.an.vertical?i.y<o.y:i.x>o.x)?{needsFlipping:!0}:null}function ke(e){const{projectionContext:i,pitchedLabelPlaneMatrixInverse:o,symbol:r,fontSize:a,flip:s,keepUpright:n,glyphOffsetArray:l,dynamicLayoutVertexArray:c,aspectRatio:h,rotateToLine:u}=e,d=a/24,_=r.lineOffsetX*d,p=r.lineOffsetY*d;let m;if(r.numGlyphs>1){const e=r.glyphStartIndex+r.numGlyphs,t=r.lineStartIndex,a=r.lineStartIndex+r.lineLength,c=Ae(d,l,_,p,s,r,u,i);if(!c)return {notEnoughRoom:!0};const f=je(c.first.point.x,c.first.point.y,i,o),g=je(c.last.point.x,c.last.point.y,i,o);if(n&&!s){const e=Le(r.writingMode,f,g,h);if(e)return e}m=[c.first];for(let o=r.glyphStartIndex+1;o<e-1;o++){const e=Ge(d*l.getoffsetX(o),_,p,s,r.segment,t,a,i,u);if(!e)return {notEnoughRoom:!0};m.push(e);}m.push(c.last);}else {if(n&&!s){const e=Oe(i.tileAnchorPoint.x,i.tileAnchorPoint.y,i).point,a=r.lineStartIndex+r.segment+1,s=new t.P(i.lineVertexArray.getx(a),i.lineVertexArray.gety(a)),n=Oe(s.x,s.y,i),l=n.signedDistanceFromCamera>0?n.point:Fe(i.tileAnchorPoint,s,e,1,i),c=je(e.x,e.y,i,o),u=je(l.x,l.y,i,o),d=Le(r.writingMode,c,u,h);if(d)return d}const e=Ge(d*l.getoffsetX(r.glyphStartIndex),_,p,s,r.segment,r.lineStartIndex,r.lineStartIndex+r.lineLength,i,u);if(!e||i.projectionCache.anyProjectionOccluded)return {notEnoughRoom:!0};m=[e];}for(const e of m)t.au(c,e.point,e.angle);return {}}function Fe(e,t,i,o,r){const a=e.add(e.sub(t)._unit()),s=Oe(a.x,a.y,r).point,n=i.sub(s);return i.add(n._mult(o/n.mag()))}function Be(e,i,o){const r=i.projectionCache;if(r.projections[e])return r.projections[e];const a=new t.P(i.lineVertexArray.getx(e),i.lineVertexArray.gety(e)),s=Oe(a.x,a.y,i);if(s.signedDistanceFromCamera>0)return r.projections[e]=s.point,r.anyProjectionOccluded=r.anyProjectionOccluded||s.isOccluded,s.point;const n=e-o.direction;return Fe(0===o.distanceFromAnchor?i.tileAnchorPoint:new t.P(i.lineVertexArray.getx(n),i.lineVertexArray.gety(n)),a,o.previousVertex,o.absOffsetX-o.distanceFromAnchor+1,i)}function Oe(e,t,i){const o=e+i.translation[0],r=t+i.translation[1];let a;return i.pitchWithMap?(a=Ee(o,r,i.pitchedLabelPlaneMatrix,i.getElevation),a.isOccluded=!1):(a=i.transform.projectTileCoordinates(o,r,i.unwrappedTileID,i.getElevation),a.point.x=(.5*a.point.x+.5)*i.width,a.point.y=(.5*-a.point.y+.5)*i.height),a}function je(e,i,o,r){if(o.pitchWithMap){const a=[e,i,0,1];return t.av(a,a,r),o.transform.projectTileCoordinates(a[0]/a[3],a[1]/a[3],o.unwrappedTileID,o.getElevation).point}return {x:e/o.width*2-1,y:i/o.height*2-1}}function Ne(e,t,i){return i.transform.projectTileCoordinates(e,t,i.unwrappedTileID,i.getElevation)}function Ze(e,t,i){return e._unit()._perp()._mult(t*i)}function Ue(e,i,o,r,a,s,n,l,c){if(l.projectionCache.offsets[e])return l.projectionCache.offsets[e];const h=o.add(i);if(e+c.direction<r||e+c.direction>=a)return l.projectionCache.offsets[e]=h,h;const u=Be(e+c.direction,l,c),d=Ze(u.sub(o),n,c.direction),_=o.add(d),p=u.add(d);return l.projectionCache.offsets[e]=t.aw(s,h,_,p)||h,l.projectionCache.offsets[e]}function Ge(e,t,i,o,r,a,s,n,l){const c=o?e-t:e+t;let h=c>0?1:-1,u=0;o&&(h*=-1,u=Math.PI),h<0&&(u+=Math.PI);let d,_=h>0?a+r:a+r+1;n.projectionCache.cachedAnchorPoint?d=n.projectionCache.cachedAnchorPoint:(d=Oe(n.tileAnchorPoint.x,n.tileAnchorPoint.y,n).point,n.projectionCache.cachedAnchorPoint=d);let p,m,f=d,g=d,v=0,b=0;const x=Math.abs(c),y=[];let w;for(;v+b<=x;){if(_+=h,_<a||_>=s)return null;v+=b,g=f,m=p;const e={absOffsetX:x,direction:h,distanceFromAnchor:v,previousVertex:g};if(f=Be(_,n,e),0===i)y.push(g),w=f.sub(g);else {let t;const o=f.sub(g);t=0===o.mag()?Ze(Be(_+h,n,e).sub(f),i,h):Ze(o,i,h),m||(m=g.add(t)),p=Ue(_,t,f,a,s,m,i,n,e),y.push(m),w=p.sub(m);}b=w.mag();}const T=w._mult((x-v)/b)._add(m||g),P=u+Math.atan2(f.y-g.y,f.x-g.x);return y.push(T),{point:T,angle:l?P:0,path:y}}const Ve=new Float32Array([-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0,-1/0,-1/0,0]);function $e(e,t){for(let i=0;i<e;i++){const e=t.length;t.resize(e+4),t.float32.set(Ve,3*e);}}function qe(e,t,i){const o=t[0],r=t[1];return e[0]=i[0]*o+i[4]*r+i[12],e[1]=i[1]*o+i[5]*r+i[13],e[3]=i[3]*o+i[7]*r+i[15],e}const We=100;class He{constructor(e,t=new Ce(e.width+200,e.height+200,25),i=new Ce(e.width+200,e.height+200,25)){this.transform=e,this.grid=t,this.ignoredGrid=i,this.pitchFactor=Math.cos(e.pitch*Math.PI/180)*e.cameraToCenterDistance,this.screenRightBoundary=e.width+We,this.screenBottomBoundary=e.height+We,this.gridRightBoundary=e.width+200,this.gridBottomBoundary=e.height+200,this.perspectiveRatioCutoff=.6;}placeCollisionBox(e,t,i,o,r,a,s,n,l,c,h,u){const d=this.projectAndGetPerspectiveRatio(e.anchorPointX+n[0],e.anchorPointY+n[1],r,c,u),_=i*d.perspectiveRatio;let p;if(a||s)p=this._projectCollisionBox(e,_,o,r,a,s,n,d,c,h,u);else {const t=d.x+(h?h.x*_:0),i=d.y+(h?h.y*_:0);p={allPointsOccluded:!1,box:[t+e.x1*_,i+e.y1*_,t+e.x2*_,i+e.y2*_]};}const[m,f,g,v]=p.box,b=a?p.allPointsOccluded:d.isOccluded;let x=b;return x||(x=d.perspectiveRatio<this.perspectiveRatioCutoff),x||(x=!this.isInsideGrid(m,f,g,v)),x||\"always\"!==t&&this.grid.hitTest(m,f,g,v,t,l)?{box:[m,f,g,v],placeable:!1,offscreen:!1,occluded:b}:{box:[m,f,g,v],placeable:!0,offscreen:this.isOffscreen(m,f,g,v),occluded:b}}placeCollisionCircles(e,i,o,r,a,s,n,l,c,h,u,d,_,p){const m=[],f=new t.P(i.anchorX,i.anchorY),g=this.getPerspectiveRatio(f.x,f.y,s,p),v=(c?a*this.transform.getPitchedTextCorrection(i.anchorX,i.anchorY,s)/g:a*g)/t.aA,b={getElevation:p,pitchedLabelPlaneMatrix:n,lineVertexArray:o,pitchWithMap:c,projectionCache:{projections:{},offsets:{},cachedAnchorPoint:void 0,anyProjectionOccluded:!1},transform:this.transform,tileAnchorPoint:f,unwrappedTileID:s,width:this.transform.width,height:this.transform.height,translation:_},x=Ae(v,r,i.lineOffsetX*v,i.lineOffsetY*v,!1,i,!1,b);let y=!1,w=!1,T=!0;if(x){const i=.5*u*g+d,o=new t.P(-100,-100),r=new t.P(this.screenRightBoundary,this.screenBottomBoundary),a=new Te,s=x.first,n=x.last;let _=[];for(let e=s.path.length-1;e>=1;e--)_.push(s.path[e]);for(let e=1;e<n.path.length;e++)_.push(n.path[e]);const p=2.5*i;if(c){const e=this.projectPathToScreenSpace(_,b);_=e.some((e=>e.signedDistanceFromCamera<=0))?[]:e.map((e=>e.point));}let f=[];if(_.length>0){const e=_[0].clone(),i=_[0].clone();for(let t=1;t<_.length;t++)e.x=Math.min(e.x,_[t].x),e.y=Math.min(e.y,_[t].y),i.x=Math.max(i.x,_[t].x),i.y=Math.max(i.y,_[t].y);f=e.x>=o.x&&i.x<=r.x&&e.y>=o.y&&i.y<=r.y?[_]:i.x<o.x||e.x>r.x||i.y<o.y||e.y>r.y?[]:t.ax([_],o.x,o.y,r.x,r.y);}for(const t of f){a.reset(t,.25*i);let o=0;o=a.length<=.5*i?1:Math.ceil(a.paddedLength/p)+1;for(let t=0;t<o;t++){const r=t/Math.max(o-1,1),s=a.lerp(r),n=s.x+We,c=s.y+We;m.push(n,c,i,0);const u=n-i,d=c-i,_=n+i,p=c+i;if(T=T&&this.isOffscreen(u,d,_,p),w=w||this.isInsideGrid(u,d,_,p),\"always\"!==e&&this.grid.hitTestCircle(n,c,i,e,h)&&(y=!0,!l))return {circles:[],offscreen:!1,collisionDetected:y}}}}return {circles:!l&&y||!w||g<this.perspectiveRatioCutoff?[]:m,offscreen:T,collisionDetected:y}}projectPathToScreenSpace(e,i){const o=function(e,i){const o=t.L();return t.ap(o,i.pitchedLabelPlaneMatrix),e.map((e=>{const t=Ee(e.x,e.y,o,i.getElevation),r=i.transform.projectTileCoordinates(t.point.x,t.point.y,i.unwrappedTileID,i.getElevation);return r.point.x=(.5*r.point.x+.5)*i.width,r.point.y=(.5*-r.point.y+.5)*i.height,r}))}(e,i);return function(e){let t=0,i=0,o=0,r=0;for(let a=0;a<e.length;a++)e[a].isOccluded?(o=a+1,r=0):(r++,r>i&&(i=r,t=o));return e.slice(t,t+i)}(o)}queryRenderedSymbols(e){if(0===e.length||0===this.grid.keysLength()&&0===this.ignoredGrid.keysLength())return {};const i=[],o=new t.a1;for(const r of e){const e=new t.P(r.x+We,r.y+We);o.extend(e),i.push(e);}const{minX:r,minY:a,maxX:s,maxY:n}=o,l=this.grid.query(r,a,s,n).concat(this.ignoredGrid.query(r,a,s,n)),c={},h={};for(const e of l){const o=e.key;if(void 0===c[o.bucketInstanceId]&&(c[o.bucketInstanceId]={}),c[o.bucketInstanceId][o.featureIndex])continue;const r=[new t.P(e.x1,e.y1),new t.P(e.x2,e.y1),new t.P(e.x2,e.y2),new t.P(e.x1,e.y2)];t.ay(i,r)&&(c[o.bucketInstanceId][o.featureIndex]=!0,void 0===h[o.bucketInstanceId]&&(h[o.bucketInstanceId]=[]),h[o.bucketInstanceId].push(o.featureIndex));}return h}insertCollisionBox(e,t,i,o,r,a){(i?this.ignoredGrid:this.grid).insert({bucketInstanceId:o,featureIndex:r,collisionGroupID:a,overlapMode:t},e[0],e[1],e[2],e[3]);}insertCollisionCircles(e,t,i,o,r,a){const s=i?this.ignoredGrid:this.grid,n={bucketInstanceId:o,featureIndex:r,collisionGroupID:a,overlapMode:t};for(let t=0;t<e.length;t+=4)s.insertCircle(n,e[t],e[t+1],e[t+2]);}projectAndGetPerspectiveRatio(e,i,o,r,a){if(a){let o;r?(o=[e,i,r(e,i),1],t.av(o,o,a)):(o=[e,i,0,1],qe(o,o,a));const s=o[3];return {x:(o[0]/s+1)/2*this.transform.width+We,y:(-o[1]/s+1)/2*this.transform.height+We,perspectiveRatio:.5+this.transform.cameraToCenterDistance/s*.5,isOccluded:!1,signedDistanceFromCamera:s}}{const t=this.transform.projectTileCoordinates(e,i,o,r);return {x:(t.point.x+1)/2*this.transform.width+We,y:(1-t.point.y)/2*this.transform.height+We,perspectiveRatio:.5+this.transform.cameraToCenterDistance/t.signedDistanceFromCamera*.5,isOccluded:t.isOccluded,signedDistanceFromCamera:t.signedDistanceFromCamera}}}getPerspectiveRatio(e,t,i,o){const r=this.transform.projectTileCoordinates(e,t,i,o);return .5+this.transform.cameraToCenterDistance/r.signedDistanceFromCamera*.5}isOffscreen(e,t,i,o){return i<We||e>=this.screenRightBoundary||o<We||t>this.screenBottomBoundary}isInsideGrid(e,t,i,o){return i>=0&&e<this.gridRightBoundary&&o>=0&&t<this.gridBottomBoundary}getViewportMatrix(){const e=t.af([]);return t.M(e,e,[-100,-100,0]),e}_projectCollisionBox(e,i,o,r,a,s,n,l,c,h,u){let d=1,_=0,p=0,m=1;const f=e.anchorPointX+n[0],g=e.anchorPointY+n[1];if(s&&!a){const e=this.projectAndGetPerspectiveRatio(f+1,g,r,c,u),t=e.x-l.x,i=Math.atan((e.y-l.y)/t)+(t<0?Math.PI:0),o=Math.sin(i),a=Math.cos(i);d=a,_=o,p=-o,m=a;}else if(!s&&a){const e=Se(this.transform);d=e.vecEast[0],_=e.vecEast[1],p=e.vecSouth[0],m=e.vecSouth[1];}let v=l.x,b=l.y,x=i;a&&(v=f,b=g,x=Math.pow(2,-(this.transform.zoom-o.overscaledZ)),x*=this.transform.getPitchedTextCorrection(f,g,r),h||(x*=t.ag(.5+l.signedDistanceFromCamera/this.transform.cameraToCenterDistance*.5,0,4))),h&&(v+=d*h.x*x+p*h.y*x,b+=_*h.x*x+m*h.y*x);const y=e.x1*x,w=e.x2*x,T=(y+w)/2,P=e.y1*x,C=e.y2*x,I=(P+C)/2,M=[{offsetX:y,offsetY:P},{offsetX:T,offsetY:P},{offsetX:w,offsetY:P},{offsetX:w,offsetY:I},{offsetX:w,offsetY:C},{offsetX:T,offsetY:C},{offsetX:y,offsetY:C},{offsetX:y,offsetY:I}];let S=[];for(const{offsetX:e,offsetY:i}of M)S.push(new t.P(v+d*e+p*i,b+_*e+m*i));let E=!1;if(a){const e=S.map((e=>this.projectAndGetPerspectiveRatio(e.x,e.y,r,c,u)));E=e.some((e=>!e.isOccluded)),S=e.map((e=>new t.P(e.x,e.y)));}else E=!0;return {box:t.az(S),allPointsOccluded:!E}}}class Xe{constructor(e,t,i,o){this.opacity=e?Math.max(0,Math.min(1,e.opacity+(e.placed?t:-t))):o&&i?1:0,this.placed=i;}isHidden(){return 0===this.opacity&&!this.placed}}class Ke{constructor(e,t,i,o,r){this.text=new Xe(e?e.text:null,t,i,r),this.icon=new Xe(e?e.icon:null,t,o,r);}isHidden(){return this.text.isHidden()&&this.icon.isHidden()}}class Ye{constructor(e,t,i){this.text=e,this.icon=t,this.skipFade=i;}}class Qe{constructor(e,t,i,o,r){this.bucketInstanceId=e,this.featureIndex=t,this.sourceLayerIndex=i,this.bucketIndex=o,this.tileID=r;}}class Je{constructor(e){this.crossSourceCollisions=e,this.maxGroupID=0,this.collisionGroups={};}get(e){if(this.crossSourceCollisions)return {ID:0,predicate:null};if(!this.collisionGroups[e]){const t=++this.maxGroupID;this.collisionGroups[e]={ID:t,predicate:e=>e.collisionGroupID===t};}return this.collisionGroups[e]}}function et(e,i,o,r,a){const{horizontalAlign:s,verticalAlign:n}=t.aG(e);return new t.P(-(s-.5)*i+r[0]*a,-(n-.5)*o+r[1]*a)}class tt{constructor(e,t,i,o,r){this.transform=e.clone(),this.terrain=t,this.collisionIndex=new He(this.transform),this.placements={},this.opacities={},this.variableOffsets={},this.stale=!1,this.commitTime=0,this.fadeDuration=i,this.retainedQueryData={},this.collisionGroups=new Je(o),this.collisionCircleArrays={},this.collisionBoxArrays=new Map,this.prevPlacement=r,r&&(r.prevPlacement=void 0),this.placedOrientations={};}_getTerrainElevationFunc(e){const t=this.terrain;return t?(i,o)=>t.getElevation(e,i,o):null}getBucketParts(e,i,o,r){const a=o.getBucket(i),s=o.latestFeatureIndex;if(!a||!s||i.id!==a.layerIds[0])return;const n=o.collisionBoxArray,l=a.layers[0].layout,c=a.layers[0].paint,h=Math.pow(2,this.transform.zoom-o.tileID.overscaledZ),u=o.tileSize/t.$,d=o.tileID.toUnwrapped(),_=\"map\"===l.get(\"text-rotation-alignment\"),p=t.aB(o,1,this.transform.zoom),m=t.aC(this.collisionIndex.transform,o,c.get(\"text-translate\"),c.get(\"text-translate-anchor\")),f=t.aC(this.collisionIndex.transform,o,c.get(\"icon-translate\"),c.get(\"icon-translate-anchor\")),g=Ie(_,this.transform,p);this.retainedQueryData[a.bucketInstanceId]=new Qe(a.bucketInstanceId,s,a.sourceLayerIndex,a.index,o.tileID);const v={bucket:a,layout:l,translationText:m,translationIcon:f,unwrappedTileID:d,pitchedLabelPlaneMatrix:g,scale:h,textPixelRatio:u,holdingForFade:o.holdingForFade(),collisionBoxArray:n,partiallyEvaluatedTextSize:t.am(a.textSizeData,this.transform.zoom),collisionGroup:this.collisionGroups.get(a.sourceID)};if(r)for(const t of a.sortKeyRanges){const{sortKey:i,symbolInstanceStart:o,symbolInstanceEnd:r}=t;e.push({sortKey:i,symbolInstanceStart:o,symbolInstanceEnd:r,parameters:v});}else e.push({symbolInstanceStart:0,symbolInstanceEnd:a.symbolInstances.length,parameters:v});}attemptAnchorPlacement(e,i,o,r,a,s,n,l,c,h,u,d,_,p,m,f,g,v,b,x){const y=t.aD[e.textAnchor],w=[e.textOffset0,e.textOffset1],T=et(y,o,r,w,a),P=this.collisionIndex.placeCollisionBox(i,d,l,c,h,n,s,f,u.predicate,b,T,x);if((!v||this.collisionIndex.placeCollisionBox(v,d,l,c,h,n,s,g,u.predicate,b,T,x).placeable)&&P.placeable){let e;if(this.prevPlacement&&this.prevPlacement.variableOffsets[_.crossTileID]&&this.prevPlacement.placements[_.crossTileID]&&this.prevPlacement.placements[_.crossTileID].text&&(e=this.prevPlacement.variableOffsets[_.crossTileID].anchor),0===_.crossTileID)throw new Error(\"symbolInstance.crossTileID can't be 0\");return this.variableOffsets[_.crossTileID]={textOffset:w,width:o,height:r,anchor:y,textBoxScale:a,prevAnchor:e},this.markUsedJustification(p,y,_,m),p.allowVerticalPlacement&&(this.markUsedOrientation(p,m,_),this.placedOrientations[_.crossTileID]=m),{shift:T,placedGlyphBoxes:P}}}placeLayerBucketPart(e,i,o){const{bucket:r,layout:a,translationText:s,translationIcon:n,unwrappedTileID:l,pitchedLabelPlaneMatrix:c,textPixelRatio:h,holdingForFade:u,collisionBoxArray:d,partiallyEvaluatedTextSize:_,collisionGroup:p}=e.parameters,m=a.get(\"text-optional\"),f=a.get(\"icon-optional\"),g=t.aE(a,\"text-overlap\",\"text-allow-overlap\"),v=\"always\"===g,b=t.aE(a,\"icon-overlap\",\"icon-allow-overlap\"),x=\"always\"===b,y=\"map\"===a.get(\"text-rotation-alignment\"),w=\"map\"===a.get(\"text-pitch-alignment\"),T=\"none\"!==a.get(\"icon-text-fit\"),P=\"viewport-y\"===a.get(\"symbol-z-order\"),C=v&&(x||!r.hasIconData()||f),I=x&&(v||!r.hasTextData()||m);!r.collisionArrays&&d&&r.deserializeCollisionBoxes(d);const M=this.retainedQueryData[r.bucketInstanceId].tileID,S=this._getTerrainElevationFunc(M),E=this.transform.getFastPathSimpleProjectionMatrix(M),R=(e,d,x)=>{var P,R;if(i[e.crossTileID])return;if(u)return void(this.placements[e.crossTileID]=new Ye(!1,!1,!1));let z=!1,D=!1,A=!0,L=null,k={box:null,placeable:!1,offscreen:null,occluded:!1},F={placeable:!1},B=null,O=null,j=null,N=0,Z=0,U=0;d.textFeatureIndex?N=d.textFeatureIndex:e.useRuntimeCollisionCircles&&(N=e.featureIndex),d.verticalTextFeatureIndex&&(Z=d.verticalTextFeatureIndex);const G=d.textBox;if(G){const i=i=>{let o=t.an.horizontal;if(r.allowVerticalPlacement&&!i&&this.prevPlacement){const t=this.prevPlacement.placedOrientations[e.crossTileID];t&&(this.placedOrientations[e.crossTileID]=t,o=t,this.markUsedOrientation(r,o,e));}return o},a=(i,o)=>{if(r.allowVerticalPlacement&&e.numVerticalGlyphVertices>0&&d.verticalTextBox){for(const e of r.writingModes)if(e===t.an.vertical?(k=o(),F=k):k=i(),k&&k.placeable)break}else k=i();},c=e.textAnchorOffsetStartIndex,u=e.textAnchorOffsetEndIndex;if(u===c){const o=(t,i)=>{const o=this.collisionIndex.placeCollisionBox(t,g,h,M,l,w,y,s,p.predicate,S,void 0,E);return o&&o.placeable&&(this.markUsedOrientation(r,i,e),this.placedOrientations[e.crossTileID]=i),o};a((()=>o(G,t.an.horizontal)),(()=>{const i=d.verticalTextBox;return r.allowVerticalPlacement&&e.numVerticalGlyphVertices>0&&i?o(i,t.an.vertical):{box:null,offscreen:null}})),i(k&&k.placeable);}else {let _=t.aD[null===(R=null===(P=this.prevPlacement)||void 0===P?void 0:P.variableOffsets[e.crossTileID])||void 0===R?void 0:R.anchor];const m=(t,i,a)=>{const d=t.x2-t.x1,m=t.y2-t.y1,f=e.textBoxScale,v=T&&\"never\"===b?i:null;let x=null,P=\"never\"===g?1:2,C=\"never\";_&&P++;for(let i=0;i<P;i++){for(let i=c;i<u;i++){const o=r.textAnchorOffsets.get(i);if(_&&o.textAnchor!==_)continue;const c=this.attemptAnchorPlacement(o,t,d,m,f,y,w,h,M,l,p,C,e,r,a,s,n,v,S);if(c&&(x=c.placedGlyphBoxes,x&&x.placeable))return z=!0,L=c.shift,x}_?_=null:C=g;}return o&&!x&&(x={box:this.collisionIndex.placeCollisionBox(G,\"always\",h,M,l,w,y,s,p.predicate,S,void 0,E).box,offscreen:!1,placeable:!1,occluded:!1}),x};a((()=>m(G,d.iconBox,t.an.horizontal)),(()=>{const i=d.verticalTextBox;return r.allowVerticalPlacement&&(!k||!k.placeable)&&e.numVerticalGlyphVertices>0&&i?m(i,d.verticalIconBox,t.an.vertical):{box:null,occluded:!0,offscreen:null}})),k&&(z=k.placeable,A=k.offscreen);const f=i(k&&k.placeable);if(!z&&this.prevPlacement){const t=this.prevPlacement.variableOffsets[e.crossTileID];t&&(this.variableOffsets[e.crossTileID]=t,this.markUsedJustification(r,t.anchor,e,f));}}}if(B=k,z=B&&B.placeable,A=B&&B.offscreen,e.useRuntimeCollisionCircles){const i=r.text.placedSymbolArray.get(e.centerJustifiedTextSymbolIndex),n=t.ao(r.textSizeData,_,i),h=a.get(\"text-padding\");O=this.collisionIndex.placeCollisionCircles(g,i,r.lineVertexArray,r.glyphOffsetArray,n,l,c,o,w,p.predicate,e.collisionCircleDiameter,h,s,S),O.circles.length&&O.collisionDetected&&!o&&t.w(\"Collisions detected, but collision boxes are not shown\"),z=v||O.circles.length>0&&!O.collisionDetected,A=A&&O.offscreen;}if(d.iconFeatureIndex&&(U=d.iconFeatureIndex),d.iconBox){const e=e=>this.collisionIndex.placeCollisionBox(e,b,h,M,l,w,y,n,p.predicate,S,T&&L?L:void 0,E);F&&F.placeable&&d.verticalIconBox?(j=e(d.verticalIconBox),D=j.placeable):(j=e(d.iconBox),D=j.placeable),A=A&&j.offscreen;}const V=m||0===e.numHorizontalGlyphVertices&&0===e.numVerticalGlyphVertices,$=f||0===e.numIconVertices;V||$?$?V||(D=D&&z):z=D&&z:D=z=D&&z;const q=D&&j.placeable;if(z&&B.placeable&&this.collisionIndex.insertCollisionBox(B.box,g,a.get(\"text-ignore-placement\"),r.bucketInstanceId,F&&F.placeable&&Z?Z:N,p.ID),q&&this.collisionIndex.insertCollisionBox(j.box,b,a.get(\"icon-ignore-placement\"),r.bucketInstanceId,U,p.ID),O&&z&&this.collisionIndex.insertCollisionCircles(O.circles,g,a.get(\"text-ignore-placement\"),r.bucketInstanceId,N,p.ID),o&&this.storeCollisionData(r.bucketInstanceId,x,d,B,j,O),0===e.crossTileID)throw new Error(\"symbolInstance.crossTileID can't be 0\");if(0===r.bucketInstanceId)throw new Error(\"bucket.bucketInstanceId can't be 0\");this.placements[e.crossTileID]=new Ye((z||C)&&!(null==B?void 0:B.occluded),(D||I)&&!(null==j?void 0:j.occluded),A||r.justReloaded),i[e.crossTileID]=!0;};if(P){if(0!==e.symbolInstanceStart)throw new Error(\"bucket.bucketInstanceId should be 0\");const t=r.getSortedSymbolIndexes(-this.transform.bearingInRadians);for(let e=t.length-1;e>=0;--e){const i=t[e];R(r.symbolInstances.get(i),r.collisionArrays[i],i);}}else for(let t=e.symbolInstanceStart;t<e.symbolInstanceEnd;t++)R(r.symbolInstances.get(t),r.collisionArrays[t],t);r.justReloaded=!1;}storeCollisionData(e,t,i,o,r,a){if(i.textBox||i.iconBox){let a,s;this.collisionBoxArrays.has(e)?a=this.collisionBoxArrays.get(e):(a=new Map,this.collisionBoxArrays.set(e,a)),a.has(t)?s=a.get(t):(s={text:null,icon:null},a.set(t,s)),i.textBox&&(s.text=o.box),i.iconBox&&(s.icon=r.box);}if(a){let t=this.collisionCircleArrays[e];void 0===t&&(t=this.collisionCircleArrays[e]=[]);for(let e=0;e<a.circles.length;e+=4)t.push(a.circles[e+0]-We),t.push(a.circles[e+1]-We),t.push(a.circles[e+2]),t.push(a.collisionDetected?1:0);}}markUsedJustification(e,i,o,r){let a;a=r===t.an.vertical?o.verticalPlacedTextSymbolIndex:{left:o.leftJustifiedTextSymbolIndex,center:o.centerJustifiedTextSymbolIndex,right:o.rightJustifiedTextSymbolIndex}[t.aF(i)];const s=[o.leftJustifiedTextSymbolIndex,o.centerJustifiedTextSymbolIndex,o.rightJustifiedTextSymbolIndex,o.verticalPlacedTextSymbolIndex];for(const t of s)t>=0&&(e.text.placedSymbolArray.get(t).crossTileID=a>=0&&t!==a?0:o.crossTileID);}markUsedOrientation(e,i,o){const r=i===t.an.horizontal||i===t.an.horizontalOnly?i:0,a=i===t.an.vertical?i:0,s=[o.leftJustifiedTextSymbolIndex,o.centerJustifiedTextSymbolIndex,o.rightJustifiedTextSymbolIndex];for(const t of s)e.text.placedSymbolArray.get(t).placedOrientation=r;o.verticalPlacedTextSymbolIndex&&(e.text.placedSymbolArray.get(o.verticalPlacedTextSymbolIndex).placedOrientation=a);}commit(e){this.commitTime=e,this.zoomAtLastRecencyCheck=this.transform.zoom;const t=this.prevPlacement;let i=!1;this.prevZoomAdjustment=t?t.zoomAdjustment(this.transform.zoom):0;const o=t?t.symbolFadeChange(e):1,r=t?t.opacities:{},a=t?t.variableOffsets:{},s=t?t.placedOrientations:{};for(const e in this.placements){const t=this.placements[e],a=r[e];a?(this.opacities[e]=new Ke(a,o,t.text,t.icon),i=i||t.text!==a.text.placed||t.icon!==a.icon.placed):(this.opacities[e]=new Ke(null,o,t.text,t.icon,t.skipFade),i=i||t.text||t.icon);}for(const e in r){const t=r[e];if(!this.opacities[e]){const r=new Ke(t,o,!1,!1);r.isHidden()||(this.opacities[e]=r,i=i||t.text.placed||t.icon.placed);}}for(const e in a)this.variableOffsets[e]||!this.opacities[e]||this.opacities[e].isHidden()||(this.variableOffsets[e]=a[e]);for(const e in s)this.placedOrientations[e]||!this.opacities[e]||this.opacities[e].isHidden()||(this.placedOrientations[e]=s[e]);if(t&&void 0===t.lastPlacementChangeTime)throw new Error(\"Last placement time for previous placement is not defined\");i?this.lastPlacementChangeTime=e:\"number\"!=typeof this.lastPlacementChangeTime&&(this.lastPlacementChangeTime=t?t.lastPlacementChangeTime:e);}updateLayerOpacities(e,t){const i={};for(const o of t){const t=o.getBucket(e);t&&o.latestFeatureIndex&&e.id===t.layerIds[0]&&this.updateBucketOpacities(t,o.tileID,i,o.collisionBoxArray);}}updateBucketOpacities(e,i,o,r){e.hasTextData()&&(e.text.opacityVertexArray.clear(),e.text.hasVisibleVertices=!1),e.hasIconData()&&(e.icon.opacityVertexArray.clear(),e.icon.hasVisibleVertices=!1),e.hasIconCollisionBoxData()&&e.iconCollisionBox.collisionVertexArray.clear(),e.hasTextCollisionBoxData()&&e.textCollisionBox.collisionVertexArray.clear();const a=e.layers[0],s=a.layout,n=new Ke(null,0,!1,!1,!0),l=s.get(\"text-allow-overlap\"),c=s.get(\"icon-allow-overlap\"),h=a._unevaluatedLayout.hasValue(\"text-variable-anchor\")||a._unevaluatedLayout.hasValue(\"text-variable-anchor-offset\"),u=\"map\"===s.get(\"text-rotation-alignment\"),d=\"map\"===s.get(\"text-pitch-alignment\"),_=\"none\"!==s.get(\"icon-text-fit\"),p=new Ke(null,0,l&&(c||!e.hasIconData()||s.get(\"icon-optional\")),c&&(l||!e.hasTextData()||s.get(\"text-optional\")),!0);!e.collisionArrays&&r&&(e.hasIconCollisionBoxData()||e.hasTextCollisionBoxData())&&e.deserializeCollisionBoxes(r);const m=(e,t,i)=>{for(let o=0;o<t/4;o++)e.opacityVertexArray.emplaceBack(i);e.hasVisibleVertices=e.hasVisibleVertices||i!==ut;},f=this.collisionBoxArrays.get(e.bucketInstanceId);for(let i=0;i<e.symbolInstances.length;i++){const r=e.symbolInstances.get(i),{numHorizontalGlyphVertices:a,numVerticalGlyphVertices:s,crossTileID:l}=r;let c=this.opacities[l];o[l]?c=n:c||(c=p,this.opacities[l]=c),o[l]=!0;const g=r.numIconVertices>0,v=this.placedOrientations[r.crossTileID],b=v===t.an.vertical,x=v===t.an.horizontal||v===t.an.horizontalOnly;if(a>0||s>0){const t=ht(c.text);m(e.text,a,b?ut:t),m(e.text,s,x?ut:t);const i=c.text.isHidden();[r.rightJustifiedTextSymbolIndex,r.centerJustifiedTextSymbolIndex,r.leftJustifiedTextSymbolIndex].forEach((t=>{t>=0&&(e.text.placedSymbolArray.get(t).hidden=i||b?1:0);})),r.verticalPlacedTextSymbolIndex>=0&&(e.text.placedSymbolArray.get(r.verticalPlacedTextSymbolIndex).hidden=i||x?1:0);const o=this.variableOffsets[r.crossTileID];o&&this.markUsedJustification(e,o.anchor,r,v);const n=this.placedOrientations[r.crossTileID];n&&(this.markUsedJustification(e,\"left\",r,n),this.markUsedOrientation(e,n,r));}if(g){const t=ht(c.icon),i=!(_&&r.verticalPlacedIconSymbolIndex&&b);r.placedIconSymbolIndex>=0&&(m(e.icon,r.numIconVertices,i?t:ut),e.icon.placedSymbolArray.get(r.placedIconSymbolIndex).hidden=c.icon.isHidden()),r.verticalPlacedIconSymbolIndex>=0&&(m(e.icon,r.numVerticalIconVertices,i?ut:t),e.icon.placedSymbolArray.get(r.verticalPlacedIconSymbolIndex).hidden=c.icon.isHidden());}const y=f&&f.has(i)?f.get(i):{text:null,icon:null};if(e.hasIconCollisionBoxData()||e.hasTextCollisionBoxData()){const o=e.collisionArrays[i];if(o){let i=new t.P(0,0);if(o.textBox||o.verticalTextBox){let t=!0;if(h){const e=this.variableOffsets[l];e?(i=et(e.anchor,e.width,e.height,e.textOffset,e.textBoxScale),u&&i._rotate(d?-this.transform.bearingInRadians:this.transform.bearingInRadians)):t=!1;}if(o.textBox||o.verticalTextBox){let r;o.textBox&&(r=b),o.verticalTextBox&&(r=x),it(e.textCollisionBox.collisionVertexArray,c.text.placed,!t||r,y.text,i.x,i.y);}}if(o.iconBox||o.verticalIconBox){const t=Boolean(!x&&o.verticalIconBox);let r;o.iconBox&&(r=t),o.verticalIconBox&&(r=!t),it(e.iconCollisionBox.collisionVertexArray,c.icon.placed,r,y.icon,_?i.x:0,_?i.y:0);}}}}if(e.sortFeatures(-this.transform.bearingInRadians),this.retainedQueryData[e.bucketInstanceId]&&(this.retainedQueryData[e.bucketInstanceId].featureSortOrder=e.featureSortOrder),e.hasTextData()&&e.text.opacityVertexBuffer&&e.text.opacityVertexBuffer.updateData(e.text.opacityVertexArray),e.hasIconData()&&e.icon.opacityVertexBuffer&&e.icon.opacityVertexBuffer.updateData(e.icon.opacityVertexArray),e.hasIconCollisionBoxData()&&e.iconCollisionBox.collisionVertexBuffer&&e.iconCollisionBox.collisionVertexBuffer.updateData(e.iconCollisionBox.collisionVertexArray),e.hasTextCollisionBoxData()&&e.textCollisionBox.collisionVertexBuffer&&e.textCollisionBox.collisionVertexBuffer.updateData(e.textCollisionBox.collisionVertexArray),e.text.opacityVertexArray.length!==e.text.layoutVertexArray.length/4)throw new Error(`bucket.text.opacityVertexArray.length (= ${e.text.opacityVertexArray.length}) !== bucket.text.layoutVertexArray.length (= ${e.text.layoutVertexArray.length}) / 4`);if(e.icon.opacityVertexArray.length!==e.icon.layoutVertexArray.length/4)throw new Error(`bucket.icon.opacityVertexArray.length (= ${e.icon.opacityVertexArray.length}) !== bucket.icon.layoutVertexArray.length (= ${e.icon.layoutVertexArray.length}) / 4`);e.bucketInstanceId in this.collisionCircleArrays&&(e.collisionCircleArray=this.collisionCircleArrays[e.bucketInstanceId],delete this.collisionCircleArrays[e.bucketInstanceId]);}symbolFadeChange(e){return 0===this.fadeDuration?1:(e-this.commitTime)/this.fadeDuration+this.prevZoomAdjustment}zoomAdjustment(e){return Math.max(0,(this.transform.zoom-e)/1.5)}hasTransitions(e){return this.stale||e-this.lastPlacementChangeTime<this.fadeDuration}stillRecent(e,t){const i=this.zoomAtLastRecencyCheck===t?1-this.zoomAdjustment(t):1;return this.zoomAtLastRecencyCheck=t,this.commitTime+this.fadeDuration*i>e}setStale(){this.stale=!0;}}function it(e,t,i,o,r,a){o&&0!==o.length||(o=[0,0,0,0]);const s=o[0]-We,n=o[1]-We,l=o[2]-We,c=o[3]-We;e.emplaceBack(t?1:0,i?1:0,r||0,a||0,s,n),e.emplaceBack(t?1:0,i?1:0,r||0,a||0,l,n),e.emplaceBack(t?1:0,i?1:0,r||0,a||0,l,c),e.emplaceBack(t?1:0,i?1:0,r||0,a||0,s,c);}const ot=Math.pow(2,25),rt=Math.pow(2,24),at=Math.pow(2,17),st=Math.pow(2,16),nt=Math.pow(2,9),lt=Math.pow(2,8),ct=Math.pow(2,1);function ht(e){if(0===e.opacity&&!e.placed)return 0;if(1===e.opacity&&e.placed)return 4294967295;const t=e.placed?1:0,i=Math.floor(127*e.opacity);return i*ot+t*rt+i*at+t*st+i*nt+t*lt+i*ct+t}const ut=0;class dt{constructor(e){this._sortAcrossTiles=\"viewport-y\"!==e.layout.get(\"symbol-z-order\")&&!e.layout.get(\"symbol-sort-key\").isConstant(),this._currentTileIndex=0,this._currentPartIndex=0,this._seenCrossTileIDs={},this._bucketParts=[];}continuePlacement(e,t,i,o,r){const a=this._bucketParts;for(;this._currentTileIndex<e.length;)if(t.getBucketParts(a,o,e[this._currentTileIndex],this._sortAcrossTiles),this._currentTileIndex++,r())return !0;for(this._sortAcrossTiles&&(this._sortAcrossTiles=!1,a.sort(((e,t)=>e.sortKey-t.sortKey)));this._currentPartIndex<a.length;)if(t.placeLayerBucketPart(a[this._currentPartIndex],this._seenCrossTileIDs,i),this._currentPartIndex++,r())return !0;return !1}}class _t{constructor(e,t,i,o,r,a,s,n){this.placement=new tt(e,t,a,s,n),this._currentPlacementIndex=i.length-1,this._forceFullPlacement=o,this._showCollisionBoxes=r,this._done=!1;}isDone(){return this._done}continuePlacement(e,t,i){const o=s.now(),r=()=>!this._forceFullPlacement&&s.now()-o>2;for(;this._currentPlacementIndex>=0;){const o=t[e[this._currentPlacementIndex]],a=this.placement.collisionIndex.transform.zoom;if(\"symbol\"===o.type&&(!o.minzoom||o.minzoom<=a)&&(!o.maxzoom||o.maxzoom>a)){if(this._inProgressLayer||(this._inProgressLayer=new dt(o)),this._inProgressLayer.continuePlacement(i[o.source],this.placement,this._showCollisionBoxes,o,r))return;delete this._inProgressLayer;}this._currentPlacementIndex--;}this._done=!0;}commit(e){return this.placement.commit(e),this.placement}}const pt=512/t.$/2;class mt{constructor(e,i,o){this.tileID=e,this.bucketInstanceId=o,this._symbolsByKey={};const r=new Map;for(let e=0;e<i.length;e++){const t=i.get(e),o=t.key,a=r.get(o);a?a.push(t):r.set(o,[t]);}for(const[e,i]of r){const o={positions:i.map((e=>({x:Math.floor(e.anchorX*pt),y:Math.floor(e.anchorY*pt)}))),crossTileIDs:i.map((e=>e.crossTileID))};if(o.positions.length>128){const e=new t.aH(o.positions.length,16,Uint16Array);for(const{x:t,y:i}of o.positions)e.add(t,i);e.finish(),delete o.positions,o.index=e;}this._symbolsByKey[e]=o;}}getScaledCoordinates(e,i){const{x:o,y:r,z:a}=this.tileID.canonical,{x:s,y:n,z:l}=i.canonical,c=pt/Math.pow(2,l-a),h=(n*t.$+e.anchorY)*c,u=r*t.$*pt;return {x:Math.floor((s*t.$+e.anchorX)*c-o*t.$*pt),y:Math.floor(h-u)}}findMatches(e,t,i){const o=this.tileID.canonical.z<t.canonical.z?1:Math.pow(2,this.tileID.canonical.z-t.canonical.z);for(let r=0;r<e.length;r++){const a=e.get(r);if(a.crossTileID)continue;const s=this._symbolsByKey[a.key];if(!s)continue;const n=this.getScaledCoordinates(a,t);if(s.index){const e=s.index.range(n.x-o,n.y-o,n.x+o,n.y+o).sort();for(const t of e){const e=s.crossTileIDs[t];if(!i[e]){i[e]=!0,a.crossTileID=e;break}}}else if(s.positions)for(let e=0;e<s.positions.length;e++){const t=s.positions[e],r=s.crossTileIDs[e];if(Math.abs(t.x-n.x)<=o&&Math.abs(t.y-n.y)<=o&&!i[r]){i[r]=!0,a.crossTileID=r;break}}}}getCrossTileIDsLists(){return Object.values(this._symbolsByKey).map((({crossTileIDs:e})=>e))}}class ft{constructor(){this.maxCrossTileID=0;}generate(){return ++this.maxCrossTileID}}class gt{constructor(){this.indexes={},this.usedCrossTileIDs={},this.lng=0;}handleWrapJump(e){const t=Math.round((e-this.lng)/360);if(0!==t)for(const e in this.indexes){const i=this.indexes[e],o={};for(const e in i){const r=i[e];r.tileID=r.tileID.unwrapTo(r.tileID.wrap+t),o[r.tileID.key]=r;}this.indexes[e]=o;}this.lng=e;}addBucket(e,t,i){if(this.indexes[e.overscaledZ]&&this.indexes[e.overscaledZ][e.key]){if(this.indexes[e.overscaledZ][e.key].bucketInstanceId===t.bucketInstanceId)return !1;this.removeBucketCrossTileIDs(e.overscaledZ,this.indexes[e.overscaledZ][e.key]);}for(let e=0;e<t.symbolInstances.length;e++)t.symbolInstances.get(e).crossTileID=0;this.usedCrossTileIDs[e.overscaledZ]||(this.usedCrossTileIDs[e.overscaledZ]={});const o=this.usedCrossTileIDs[e.overscaledZ];for(const i in this.indexes){const r=this.indexes[i];if(Number(i)>e.overscaledZ)for(const i in r){const a=r[i];a.tileID.isChildOf(e)&&a.findMatches(t.symbolInstances,e,o);}else {const a=r[e.scaledTo(Number(i)).key];a&&a.findMatches(t.symbolInstances,e,o);}}for(let e=0;e<t.symbolInstances.length;e++){const r=t.symbolInstances.get(e);r.crossTileID||(r.crossTileID=i.generate(),o[r.crossTileID]=!0);}return void 0===this.indexes[e.overscaledZ]&&(this.indexes[e.overscaledZ]={}),this.indexes[e.overscaledZ][e.key]=new mt(e,t.symbolInstances,t.bucketInstanceId),!0}removeBucketCrossTileIDs(e,t){for(const i of t.getCrossTileIDsLists())for(const t of i)delete this.usedCrossTileIDs[e][t];}removeStaleBuckets(e){let t=!1;for(const i in this.indexes){const o=this.indexes[i];for(const r in o)e[o[r].bucketInstanceId]||(this.removeBucketCrossTileIDs(i,o[r]),delete o[r],t=!0);}return t}}class vt{constructor(){this.layerIndexes={},this.crossTileIDs=new ft,this.maxBucketInstanceId=0,this.bucketsInCurrentPlacement={};}addLayer(e,t,i){let o=this.layerIndexes[e.id];void 0===o&&(o=this.layerIndexes[e.id]=new gt);let r=!1;const a={};o.handleWrapJump(i);for(const i of t){const t=i.getBucket(e);t&&e.id===t.layerIds[0]&&(t.bucketInstanceId||(t.bucketInstanceId=++this.maxBucketInstanceId),o.addBucket(i.tileID,t,this.crossTileIDs)&&(r=!0),a[t.bucketInstanceId]=!0);}return o.removeStaleBuckets(a)&&(r=!0),r}pruneUnusedLayers(e){const t={};e.forEach((e=>{t[e]=!0;}));for(const e in this.layerIndexes)t[e]||delete this.layerIndexes[e];}}var bt=\"void main() {fragColor=vec4(1.0);}\";const xt={prelude:yt(\"#ifdef GL_ES\\nprecision mediump float;\\n#else\\n#if !defined(lowp)\\n#define lowp\\n#endif\\n#if !defined(mediump)\\n#define mediump\\n#endif\\n#if !defined(highp)\\n#define highp\\n#endif\\n#endif\\nout highp vec4 fragColor;\",\"#ifdef GL_ES\\nprecision highp float;\\n#else\\n#if !defined(lowp)\\n#define lowp\\n#endif\\n#if !defined(mediump)\\n#define mediump\\n#endif\\n#if !defined(highp)\\n#define highp\\n#endif\\n#endif\\nvec2 unpack_float(const float packedValue) {int packedIntValue=int(packedValue);int v0=packedIntValue/256;return vec2(v0,packedIntValue-v0*256);}vec2 unpack_opacity(const float packedOpacity) {int intOpacity=int(packedOpacity)/2;return vec2(float(intOpacity)/127.0,mod(packedOpacity,2.0));}vec4 decode_color(const vec2 encodedColor) {return vec4(unpack_float(encodedColor[0])/255.0,unpack_float(encodedColor[1])/255.0\\n);}float unpack_mix_vec2(const vec2 packedValue,const float t) {return mix(packedValue[0],packedValue[1],t);}vec4 unpack_mix_color(const vec4 packedColors,const float t) {vec4 minColor=decode_color(vec2(packedColors[0],packedColors[1]));vec4 maxColor=decode_color(vec2(packedColors[2],packedColors[3]));return mix(minColor,maxColor,t);}vec2 get_pattern_pos(const vec2 pixel_coord_upper,const vec2 pixel_coord_lower,const vec2 pattern_size,const float tile_units_to_pixels,const vec2 pos) {vec2 offset=mod(mod(mod(pixel_coord_upper,pattern_size)*256.0,pattern_size)*256.0+pixel_coord_lower,pattern_size);return (tile_units_to_pixels*pos+offset)/pattern_size;}mat3 rotationMatrixFromAxisAngle(vec3 u,float angle) {float c=cos(angle);float s=sin(angle);float c2=1.0-c;return mat3(u.x*u.x*c2+      c,u.x*u.y*c2-u.z*s,u.x*u.z*c2+u.y*s,u.y*u.x*c2+u.z*s,u.y*u.y*c2+    c,u.y*u.z*c2-u.x*s,u.z*u.x*c2-u.y*s,u.z*u.y*c2+u.x*s,u.z*u.z*c2+    c\\n);}\\n#ifdef TERRAIN3D\\nuniform sampler2D u_terrain;uniform float u_terrain_dim;uniform mat4 u_terrain_matrix;uniform vec4 u_terrain_unpack;uniform float u_terrain_exaggeration;uniform highp sampler2D u_depth;\\n#endif\\nconst highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitShifts=vec4(1.)/bitSh;highp float unpack(highp vec4 color) {return dot(color,bitShifts);}highp float depthOpacity(vec3 frag) {\\n#ifdef TERRAIN3D\\nhighp float d=unpack(texture(u_depth,frag.xy*0.5+0.5))+0.0001-frag.z;return 1.0-max(0.0,min(1.0,-d*500.0));\\n#else\\nreturn 1.0;\\n#endif\\n}float calculate_visibility(vec4 pos) {\\n#ifdef TERRAIN3D\\nvec3 frag=pos.xyz/pos.w;highp float d=depthOpacity(frag);if (d > 0.95) return 1.0;return (d+depthOpacity(frag+vec3(0.0,0.01,0.0)))/2.0;\\n#else\\nreturn 1.0;\\n#endif\\n}float ele(vec2 pos) {\\n#ifdef TERRAIN3D\\nvec4 rgb=(texture(u_terrain,pos)*255.0)*u_terrain_unpack;return rgb.r+rgb.g+rgb.b-u_terrain_unpack.a;\\n#else\\nreturn 0.0;\\n#endif\\n}float get_elevation(vec2 pos) {\\n#ifdef TERRAIN3D\\n#ifdef GLOBE\\nif ((pos.y <-32767.5) || (pos.y > 32766.5)) {return 0.0;}\\n#endif\\nvec2 coord=(u_terrain_matrix*vec4(pos,0.0,1.0)).xy*u_terrain_dim+1.0;vec2 f=fract(coord);vec2 c=(floor(coord)+0.5)/(u_terrain_dim+2.0);float d=1.0/(u_terrain_dim+2.0);float tl=ele(c);float tr=ele(c+vec2(d,0.0));float bl=ele(c+vec2(0.0,d));float br=ele(c+vec2(d,d));float elevation=mix(mix(tl,tr,f.x),mix(bl,br,f.x),f.y);return elevation*u_terrain_exaggeration;\\n#else\\nreturn 0.0;\\n#endif\\n}const float PI=3.141592653589793;uniform mat4 u_projection_matrix;\"),projectionMercator:yt(\"\",\"float projectLineThickness(float tileY) {return 1.0;}float projectCircleRadius(float tileY) {return 1.0;}vec4 projectTile(vec2 p) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);return result;}vec4 projectTile(vec2 p,vec2 rawPos) {vec4 result=u_projection_matrix*vec4(p,0.0,1.0);if (rawPos.y <-32767.5 || rawPos.y > 32766.5) {result.z=-10000000.0;}return result;}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return u_projection_matrix*vec4(posInTile,elevation,1.0);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {return projectTileWithElevation(posInTile,elevation);}\"),projectionGlobe:yt(\"\",\"#define GLOBE_RADIUS 6371008.8\\nuniform highp vec4 u_projection_tile_mercator_coords;uniform highp vec4 u_projection_clipping_plane;uniform highp float u_projection_transition;uniform mat4 u_projection_fallback_matrix;vec3 globeRotateVector(vec3 vec,vec2 angles) {vec3 axisRight=vec3(vec.z,0.0,-vec.x);vec3 axisUp=cross(axisRight,vec);axisRight=normalize(axisRight);axisUp=normalize(axisUp);vec2 t=tan(angles);return normalize(vec+axisRight*t.x+axisUp*t.y);}mat3 globeGetRotationMatrix(vec3 spherePos) {vec3 axisRight=vec3(spherePos.z,0.0,-spherePos.x);vec3 axisDown=cross(axisRight,spherePos);axisRight=normalize(axisRight);axisDown=normalize(axisDown);return mat3(axisRight,axisDown,spherePos\\n);}float circumferenceRatioAtTileY(float tileY) {float mercator_pos_y=u_projection_tile_mercator_coords.y+u_projection_tile_mercator_coords.w*tileY;float spherical_y=2.0*atan(exp(PI-(mercator_pos_y*PI*2.0)))-PI*0.5;return cos(spherical_y);}float projectLineThickness(float tileY) {float thickness=1.0/circumferenceRatioAtTileY(tileY); \\nif (u_projection_transition < 0.999) {return mix(1.0,thickness,u_projection_transition);} else {return thickness;}}vec3 projectToSphere(vec2 translatedPos,vec2 rawPos) {vec2 mercator_pos=u_projection_tile_mercator_coords.xy+u_projection_tile_mercator_coords.zw*translatedPos;vec2 spherical;spherical.x=mercator_pos.x*PI*2.0+PI;spherical.y=2.0*atan(exp(PI-(mercator_pos.y*PI*2.0)))-PI*0.5;float len=cos(spherical.y);vec3 pos=vec3(sin(spherical.x)*len,sin(spherical.y),cos(spherical.x)*len\\n);if (rawPos.y <-32767.5) {pos=vec3(0.0,1.0,0.0);}if (rawPos.y > 32766.5) {pos=vec3(0.0,-1.0,0.0);}return pos;}vec3 projectToSphere(vec2 posInTile) {return projectToSphere(posInTile,vec2(0.0,0.0));}float globeComputeClippingZ(vec3 spherePos) {return (1.0-(dot(spherePos,u_projection_clipping_plane.xyz)+u_projection_clipping_plane.w));}vec4 interpolateProjection(vec2 posInTile,vec3 spherePos,float elevation) {vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);globePosition.z=globeComputeClippingZ(elevatedPos)*globePosition.w;if (u_projection_transition > 0.999) {return globePosition;}vec4 flatPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);const float z_globeness_threshold=0.2;vec4 result=globePosition;result.z=mix(0.0,globePosition.z,clamp((u_projection_transition-z_globeness_threshold)/(1.0-z_globeness_threshold),0.0,1.0));result.xyw=mix(flatPosition.xyw,globePosition.xyw,u_projection_transition);if ((posInTile.y <-32767.5) || (posInTile.y > 32766.5)) {result=globePosition;const float poles_hidden_anim_percentage=0.02;result.z=mix(globePosition.z,100.0,pow(max((1.0-u_projection_transition)/poles_hidden_anim_percentage,0.0),8.0));}return result;}vec4 interpolateProjectionFor3D(vec2 posInTile,vec3 spherePos,float elevation) {vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);vec4 globePosition=u_projection_matrix*vec4(elevatedPos,1.0);if (u_projection_transition > 0.999) {return globePosition;}vec4 fallbackPosition=u_projection_fallback_matrix*vec4(posInTile,elevation,1.0);return mix(fallbackPosition,globePosition,u_projection_transition);}vec4 projectTile(vec2 posInTile) {return interpolateProjection(posInTile,projectToSphere(posInTile),0.0);}vec4 projectTile(vec2 posInTile,vec2 rawPos) {return interpolateProjection(posInTile,projectToSphere(posInTile,rawPos),0.0);}vec4 projectTileWithElevation(vec2 posInTile,float elevation) {return interpolateProjection(posInTile,projectToSphere(posInTile),elevation);}vec4 projectTileFor3D(vec2 posInTile,float elevation) {vec3 spherePos=projectToSphere(posInTile,posInTile);return interpolateProjectionFor3D(posInTile,spherePos,elevation);}\"),background:yt(\"uniform vec4 u_color;uniform float u_opacity;void main() {fragColor=u_color*u_opacity;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}\"),backgroundPattern:yt(\"uniform vec2 u_pattern_tl_a;uniform vec2 u_pattern_br_a;uniform vec2 u_pattern_tl_b;uniform vec2 u_pattern_br_b;uniform vec2 u_texsize;uniform float u_mix;uniform float u_opacity;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;void main() {vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(u_pattern_tl_a/u_texsize,u_pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(u_pattern_tl_b/u_texsize,u_pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_mix)*u_opacity;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_pattern_size_a;uniform vec2 u_pattern_size_b;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_scale_a;uniform float u_scale_b;uniform float u_tile_units_to_pixels;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;void main() {gl_Position=projectTile(a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_a*u_pattern_size_a,u_tile_units_to_pixels,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,u_scale_b*u_pattern_size_b,u_tile_units_to_pixels,a_pos);}\"),circle:yt(\"in vec3 v_data;in float v_visibility;\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define mediump float radius\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define highp vec4 stroke_color\\n#pragma mapbox: define mediump float stroke_width\\n#pragma mapbox: define lowp float stroke_opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize mediump float radius\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize highp vec4 stroke_color\\n#pragma mapbox: initialize mediump float stroke_width\\n#pragma mapbox: initialize lowp float stroke_opacity\\nvec2 extrude=v_data.xy;float extrude_length=length(extrude);float antialiased_blur=v_data.z;float opacity_t=smoothstep(0.0,antialiased_blur,extrude_length-1.0);float color_t=stroke_width < 0.01 ? 0.0 : smoothstep(antialiased_blur,0.0,extrude_length-radius/(radius+stroke_width));fragColor=v_visibility*opacity_t*mix(color*opacity,stroke_color*stroke_opacity,color_t);const float epsilon=0.5/255.0;if (fragColor.r < epsilon && fragColor.g < epsilon && fragColor.b < epsilon && fragColor.a < epsilon) {discard;}\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform bool u_scale_with_map;uniform bool u_pitch_with_map;uniform vec2 u_extrude_scale;uniform highp float u_globe_extrude_scale;uniform lowp float u_device_pixel_ratio;uniform highp float u_camera_to_center_distance;uniform vec2 u_translate;in vec2 a_pos;out vec3 v_data;out float v_visibility;\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define mediump float radius\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define highp vec4 stroke_color\\n#pragma mapbox: define mediump float stroke_width\\n#pragma mapbox: define lowp float stroke_opacity\\nvoid main(void) {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize mediump float radius\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize highp vec4 stroke_color\\n#pragma mapbox: initialize mediump float stroke_width\\n#pragma mapbox: initialize lowp float stroke_opacity\\nvec2 pos_raw=a_pos+32768.0;vec2 extrude=vec2(mod(pos_raw,8.0)/7.0*2.0-1.0);vec2 circle_center=floor(pos_raw/8.0)+u_translate;float ele=get_elevation(circle_center);v_visibility=calculate_visibility(projectTileWithElevation(circle_center,ele));if (u_pitch_with_map) {\\n#ifdef GLOBE\\nvec3 center_vector=projectToSphere(circle_center);\\n#endif\\nfloat angle_scale=u_globe_extrude_scale;vec2 corner_position=circle_center;if (u_scale_with_map) {angle_scale*=(radius+stroke_width);corner_position+=extrude*u_extrude_scale*(radius+stroke_width);} else {\\n#ifdef GLOBE\\nvec4 projected_center=interpolateProjection(circle_center,center_vector,ele);\\n#else\\nvec4 projected_center=projectTileWithElevation(circle_center,ele);\\n#endif\\ncorner_position+=extrude*u_extrude_scale*(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);angle_scale*=(radius+stroke_width)*(projected_center.w/u_camera_to_center_distance);}\\n#ifdef GLOBE\\nvec2 angles=extrude*angle_scale;vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(corner_position,corner_vector,ele);\\n#else\\ngl_Position=projectTileWithElevation(corner_position,ele);\\n#endif\\n} else {gl_Position=projectTileWithElevation(circle_center,ele);if (gl_Position.z/gl_Position.w > 1.0) {gl_Position.xy=vec2(10000.0);}if (u_scale_with_map) {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*u_camera_to_center_distance;} else {gl_Position.xy+=extrude*(radius+stroke_width)*u_extrude_scale*gl_Position.w;}}float antialiasblur=-max(1.0/u_device_pixel_ratio/(radius+stroke_width),blur);v_data=vec3(extrude.x,extrude.y,antialiasblur);}\"),clippingMask:yt(bt,\"in vec2 a_pos;void main() {gl_Position=projectTile(a_pos);}\"),heatmap:yt(\"uniform highp float u_intensity;in vec2 v_extrude;\\n#pragma mapbox: define highp float weight\\n#define GAUSS_COEF 0.3989422804014327\\nvoid main() {\\n#pragma mapbox: initialize highp float weight\\nfloat d=-0.5*3.0*3.0*dot(v_extrude,v_extrude);float val=weight*u_intensity*GAUSS_COEF*exp(d);fragColor=vec4(val,1.0,1.0,1.0);\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform float u_extrude_scale;uniform float u_opacity;uniform float u_intensity;uniform highp float u_globe_extrude_scale;in vec2 a_pos;out vec2 v_extrude;\\n#pragma mapbox: define highp float weight\\n#pragma mapbox: define mediump float radius\\nconst highp float ZERO=1.0/255.0/16.0;\\n#define GAUSS_COEF 0.3989422804014327\\nvoid main(void) {\\n#pragma mapbox: initialize highp float weight\\n#pragma mapbox: initialize mediump float radius\\nvec2 pos_raw=a_pos+32768.0;vec2 unscaled_extrude=vec2(mod(pos_raw,8.0)/7.0*2.0-1.0);float S=sqrt(-2.0*log(ZERO/weight/u_intensity/GAUSS_COEF))/3.0;v_extrude=S*unscaled_extrude;vec2 extrude=v_extrude*radius*u_extrude_scale;vec2 circle_center=floor(pos_raw/8.0);\\n#ifdef GLOBE\\nvec2 angles=v_extrude*radius*u_globe_extrude_scale;vec3 center_vector=projectToSphere(circle_center);vec3 corner_vector=globeRotateVector(center_vector,angles);gl_Position=interpolateProjection(circle_center+extrude,corner_vector,0.0);\\n#else\\ngl_Position=projectTileFor3D(circle_center+extrude,get_elevation(circle_center));\\n#endif\\n}\"),heatmapTexture:yt(\"uniform sampler2D u_image;uniform sampler2D u_color_ramp;uniform float u_opacity;in vec2 v_pos;void main() {float t=texture(u_image,v_pos).r;vec4 color=texture(u_color_ramp,vec2(t,0.5));fragColor=color*u_opacity;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(0.0);\\n#endif\\n}\",\"uniform mat4 u_matrix;uniform vec2 u_world;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos*u_world,0,1);v_pos.x=a_pos.x;v_pos.y=1.0-a_pos.y;}\"),collisionBox:yt(\"in float v_placed;in float v_notUsed;void main() {float alpha=0.5;fragColor=vec4(1.0,0.0,0.0,1.0)*alpha;if (v_placed > 0.5) {fragColor=vec4(0.0,0.0,1.0,0.5)*alpha;}if (v_notUsed > 0.5) {fragColor*=.1;}}\",\"in vec2 a_anchor_pos;in vec2 a_placed;in vec2 a_box_real;uniform vec2 u_pixel_extrude_scale;out float v_placed;out float v_notUsed;void main() {gl_Position=projectTileWithElevation(a_anchor_pos,get_elevation(a_anchor_pos));gl_Position.xy=((a_box_real+0.5)*u_pixel_extrude_scale*2.0-1.0)*vec2(1.0,-1.0)*gl_Position.w;if (gl_Position.z/gl_Position.w < 1.1) {gl_Position.z=0.5;}v_placed=a_placed.x;v_notUsed=a_placed.y;}\"),collisionCircle:yt(\"in float v_radius;in vec2 v_extrude;in float v_collision;void main() {float alpha=0.5;float stroke_radius=0.9;float distance_to_center=length(v_extrude);float distance_to_edge=abs(distance_to_center-v_radius);float opacity_t=smoothstep(-stroke_radius,0.0,-distance_to_edge);vec4 color=mix(vec4(0.0,0.0,1.0,0.5),vec4(1.0,0.0,0.0,1.0),v_collision);fragColor=color*alpha*opacity_t;}\",\"in vec2 a_pos;in float a_radius;in vec2 a_flags;uniform vec2 u_viewport_size;out float v_radius;out vec2 v_extrude;out float v_collision;void main() {float radius=a_radius;float collision=a_flags.x;float vertexIdx=a_flags.y;vec2 quadVertexOffset=vec2(mix(-1.0,1.0,float(vertexIdx >=2.0)),mix(-1.0,1.0,float(vertexIdx >=1.0 && vertexIdx <=2.0)));vec2 quadVertexExtent=quadVertexOffset*radius;float padding_factor=1.2;v_radius=radius;v_extrude=quadVertexExtent*padding_factor;v_collision=collision;gl_Position=vec4((a_pos/u_viewport_size*2.0-1.0)*vec2(1.0,-1.0),0.0,1.0)+vec4(quadVertexExtent*padding_factor/u_viewport_size*2.0,0.0,0.0);}\"),colorRelief:yt(\"#ifdef GL_ES\\nprecision highp float;\\n#endif\\nuniform sampler2D u_image;uniform vec4 u_unpack;uniform sampler2D u_elevation_stops;uniform sampler2D u_color_stops;uniform float u_opacity;in vec2 v_pos;float getElevation(vec2 coord) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}float getElevationStop(int stop) {float x=(float(stop)+0.5)/float(textureSize(u_elevation_stops,0)[0]);vec4 data=texture(u_elevation_stops,vec2(x,0))*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {float el=getElevation(v_pos);int num_elevation_stops=textureSize(u_elevation_stops,0)[0];int r=(num_elevation_stops-1);int l=0;float el_l=getElevationStop(l);float el_r=getElevationStop(r);while(r-l > 1){int m=(r+l)/2;float el_m=getElevationStop(m);if(el < el_m){r=m;el_r=el_m;}else\\n{l=m;el_l=el_m;}}float x=(float(l)+(el-el_l)/(el_r-el_l)+0.5)/float(textureSize(u_color_stops,0)[0]);fragColor=u_opacity*texture(u_color_stops,vec2(x,0));\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_dimension;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_pos/8192.0)*scale+epsilon;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}\"),debug:yt(\"uniform highp vec4 u_color;uniform sampler2D u_overlay;in vec2 v_uv;void main() {vec4 overlay_color=texture(u_overlay,v_uv);fragColor=mix(u_color,overlay_color,overlay_color.a);}\",\"in vec2 a_pos;out vec2 v_uv;uniform float u_overlay_scale;void main() {v_uv=a_pos/8192.0;gl_Position=projectTileWithElevation(a_pos*u_overlay_scale,get_elevation(a_pos));}\"),depth:yt(bt,\"in vec2 a_pos;void main() {\\n#ifdef GLOBE\\ngl_Position=projectTileFor3D(a_pos,0.0);\\n#else\\ngl_Position=u_projection_matrix*vec4(a_pos,0.0,1.0);\\n#endif\\n}\"),fill:yt(\"#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float opacity\\nfragColor=color*opacity;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_fill_translate;in vec2 a_pos;\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float opacity\\ngl_Position=projectTile(a_pos+u_fill_translate,a_pos);}\"),fillOutline:yt(\"in vec2 v_pos;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 outline_color\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 outline_color\\n#pragma mapbox: initialize lowp float opacity\\nfloat dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=outline_color*(alpha*opacity);\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_world;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 outline_color\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 outline_color\\n#pragma mapbox: initialize lowp float opacity\\ngl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n}\"),fillOutlinePattern:yt(\"uniform vec2 u_texsize;uniform sampler2D u_image;uniform float u_fade;in vec2 v_pos_a;in vec2 v_pos_b;in vec2 v_pos;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);float dist=length(v_pos-gl_FragCoord.xy);float alpha=1.0-smoothstep(0.0,1.0,dist);fragColor=mix(color1,color2,u_fade)*alpha*opacity;\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_world;uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;out vec2 v_pos;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,a_pos);v_pos=(gl_Position.xy/gl_Position.w+1.0)/2.0*u_world;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n}\"),fillPattern:yt(\"#ifdef GL_ES\\nprecision highp float;\\n#endif\\nuniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);fragColor=mix(color1,color2,u_fade)*opacity;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform vec3 u_scale;uniform vec2 u_fill_translate;in vec2 a_pos;out vec2 v_pos_a;out vec2 v_pos_b;\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;gl_Position=projectTile(a_pos+u_fill_translate,a_pos);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileZoomRatio,a_pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileZoomRatio,a_pos);}\"),fillExtrusion:yt(\"in vec4 v_color;void main() {fragColor=v_color;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;in vec2 a_pos;in vec4 a_normal_ed;\\n#ifdef TERRAIN3D\\nin vec2 a_centroid;\\n#endif\\nout vec4 v_color;\\n#pragma mapbox: define highp float base\\n#pragma mapbox: define highp float height\\n#pragma mapbox: define highp vec4 color\\nvoid main() {\\n#pragma mapbox: initialize highp float base\\n#pragma mapbox: initialize highp float height\\n#pragma mapbox: initialize highp vec4 color\\nvec3 normal=a_normal_ed.xyz;\\n#ifdef TERRAIN3D\\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\\n#else\\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\\n#endif\\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=mod(normal.x,2.0);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\\n#ifdef GLOBE\\nvec3 spherePos=projectToSphere(posInTile,a_pos);gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\\n#else\\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\\n#endif\\nfloat colorvalue=color.r*0.2126+color.g*0.7152+color.b*0.0722;v_color=vec4(0.0,0.0,0.0,1.0);vec4 ambientlight=vec4(0.03,0.03,0.03,1.0);color+=ambientlight;vec3 normalForLighting=normal/16384.0;float directional=clamp(dot(normalForLighting,u_lightpos),0.0,1.0);\\n#ifdef GLOBE\\nmat3 rotMatrix=globeGetRotationMatrix(spherePos);normalForLighting=rotMatrix*normalForLighting;directional=mix(directional,clamp(dot(normalForLighting,u_lightpos_globe),0.0,1.0),u_projection_transition);\\n#endif\\ndirectional=mix((1.0-u_lightintensity),max((1.0-colorvalue+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_color.r+=clamp(color.r*directional*u_lightcolor.r,mix(0.0,0.3,1.0-u_lightcolor.r),1.0);v_color.g+=clamp(color.g*directional*u_lightcolor.g,mix(0.0,0.3,1.0-u_lightcolor.g),1.0);v_color.b+=clamp(color.b*directional*u_lightcolor.b,mix(0.0,0.3,1.0-u_lightcolor.b),1.0);v_color*=u_opacity;}\"),fillExtrusionPattern:yt(\"uniform vec2 u_texsize;uniform float u_fade;uniform sampler2D u_image;in vec2 v_pos_a;in vec2 v_pos_b;in vec4 v_lighting;\\n#pragma mapbox: define lowp float base\\n#pragma mapbox: define lowp float height\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float base\\n#pragma mapbox: initialize lowp float height\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;vec2 imagecoord=mod(v_pos_a,1.0);vec2 pos=mix(pattern_tl_a/u_texsize,pattern_br_a/u_texsize,imagecoord);vec4 color1=texture(u_image,pos);vec2 imagecoord_b=mod(v_pos_b,1.0);vec2 pos2=mix(pattern_tl_b/u_texsize,pattern_br_b/u_texsize,imagecoord_b);vec4 color2=texture(u_image,pos2);vec4 mixedColor=mix(color1,color2,u_fade);fragColor=mixedColor*v_lighting;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_pixel_coord_upper;uniform vec2 u_pixel_coord_lower;uniform float u_height_factor;uniform vec3 u_scale;uniform float u_vertical_gradient;uniform lowp float u_opacity;uniform vec2 u_fill_translate;uniform vec3 u_lightcolor;uniform lowp vec3 u_lightpos;uniform lowp vec3 u_lightpos_globe;uniform lowp float u_lightintensity;in vec2 a_pos;in vec4 a_normal_ed;\\n#ifdef TERRAIN3D\\nin vec2 a_centroid;\\n#endif\\n#ifdef GLOBE\\nout vec3 v_sphere_pos;\\n#endif\\nout vec2 v_pos_a;out vec2 v_pos_b;out vec4 v_lighting;\\n#pragma mapbox: define lowp float base\\n#pragma mapbox: define lowp float height\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float base\\n#pragma mapbox: initialize lowp float height\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec3 normal=a_normal_ed.xyz;float edgedistance=a_normal_ed.w;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;\\n#ifdef TERRAIN3D\\nfloat height_terrain3d_offset=get_elevation(a_centroid);float base_terrain3d_offset=height_terrain3d_offset-(base > 0.0 ? 0.0 : 10.0);\\n#else\\nfloat height_terrain3d_offset=0.0;float base_terrain3d_offset=0.0;\\n#endif\\nbase=max(0.0,base)+base_terrain3d_offset;height=max(0.0,height)+height_terrain3d_offset;float t=mod(normal.x,2.0);float elevation=t > 0.0 ? height : base;vec2 posInTile=a_pos+u_fill_translate;\\n#ifdef GLOBE\\nvec3 spherePos=projectToSphere(posInTile,a_pos);vec3 elevatedPos=spherePos*(1.0+elevation/GLOBE_RADIUS);v_sphere_pos=elevatedPos;gl_Position=interpolateProjectionFor3D(posInTile,spherePos,elevation);\\n#else\\ngl_Position=u_projection_matrix*vec4(posInTile,elevation,1.0);\\n#endif\\nvec2 pos=normal.x==1.0 && normal.y==0.0 && normal.z==16384.0\\n? a_pos\\n: vec2(edgedistance,elevation*u_height_factor);v_pos_a=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,fromScale*display_size_a,tileRatio,pos);v_pos_b=get_pattern_pos(u_pixel_coord_upper,u_pixel_coord_lower,toScale*display_size_b,tileRatio,pos);v_lighting=vec4(0.0,0.0,0.0,1.0);float directional=clamp(dot(normal/16383.0,u_lightpos),0.0,1.0);directional=mix((1.0-u_lightintensity),max((0.5+u_lightintensity),1.0),directional);if (normal.y !=0.0) {directional*=((1.0-u_vertical_gradient)+(u_vertical_gradient*clamp((t+base)*pow(height/150.0,0.5),mix(0.7,0.98,1.0-u_lightintensity),1.0)));}v_lighting.rgb+=clamp(directional*u_lightcolor,mix(vec3(0.0),vec3(0.3),1.0-u_lightcolor),vec3(1.0));v_lighting*=u_opacity;}\"),hillshadePrepare:yt(\"#ifdef GL_ES\\nprecision highp float;\\n#endif\\nuniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_dimension;uniform float u_zoom;uniform vec4 u_unpack;float getElevation(vec2 coord,float bias) {vec4 data=texture(u_image,coord)*255.0;data.a=-1.0;return dot(data,u_unpack);}void main() {vec2 epsilon=1.0/u_dimension;float tileSize=u_dimension.x-2.0;float a=getElevation(v_pos+vec2(-epsilon.x,-epsilon.y),0.0);float b=getElevation(v_pos+vec2(0,-epsilon.y),0.0);float c=getElevation(v_pos+vec2(epsilon.x,-epsilon.y),0.0);float d=getElevation(v_pos+vec2(-epsilon.x,0),0.0);float e=getElevation(v_pos,0.0);float f=getElevation(v_pos+vec2(epsilon.x,0),0.0);float g=getElevation(v_pos+vec2(-epsilon.x,epsilon.y),0.0);float h=getElevation(v_pos+vec2(0,epsilon.y),0.0);float i=getElevation(v_pos+vec2(epsilon.x,epsilon.y),0.0);float exaggerationFactor=u_zoom < 2.0 ? 0.4 : u_zoom < 4.5 ? 0.35 : 0.3;float exaggeration=u_zoom < 15.0 ? (u_zoom-15.0)*exaggerationFactor : 0.0;vec2 deriv=vec2((c+f+f+i)-(a+d+d+g),(g+h+h+i)-(a+b+b+c))*tileSize/pow(2.0,exaggeration+(28.2562-u_zoom));fragColor=clamp(vec4(deriv.x/8.0+0.5,deriv.y/8.0+0.5,1.0,1.0),0.0,1.0);\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform mat4 u_matrix;uniform vec2 u_dimension;in vec2 a_pos;in vec2 a_texture_pos;out vec2 v_pos;void main() {gl_Position=u_matrix*vec4(a_pos,0,1);highp vec2 epsilon=1.0/u_dimension;float scale=(u_dimension.x-2.0)/u_dimension.x;v_pos=(a_texture_pos/8192.0)*scale+epsilon;}\"),hillshade:yt(\"uniform sampler2D u_image;in vec2 v_pos;uniform vec2 u_latrange;uniform float u_exaggeration;uniform vec4 u_accent;uniform int u_method;uniform float u_altitudes[NUM_ILLUMINATION_SOURCES];uniform float u_azimuths[NUM_ILLUMINATION_SOURCES];uniform vec4 u_shadows[NUM_ILLUMINATION_SOURCES];uniform vec4 u_highlights[NUM_ILLUMINATION_SOURCES];\\n#define PI 3.141592653589793\\n#define STANDARD 0\\n#define COMBINED 1\\n#define IGOR 2\\n#define MULTIDIRECTIONAL 3\\n#define BASIC 4\\nfloat get_aspect(vec2 deriv){return deriv.x !=0.0 ? atan(deriv.y,-deriv.x) : PI/2.0*(deriv.y > 0.0 ? 1.0 :-1.0);}void igor_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float aspect=get_aspect(deriv);float azimuth=u_azimuths[0]+PI;float slope_stength=atan(length(deriv))*2.0/PI;float aspect_strength=1.0-abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);float shadow_strength=slope_stength*aspect_strength;float highlight_strength=slope_stength*(1.0-aspect_strength);fragColor=u_shadows[0]*shadow_strength+u_highlights[0]*highlight_strength;}void standard_hillshade(vec2 deriv){float azimuth=u_azimuths[0]+PI;float slope=atan(0.625*length(deriv));float aspect=get_aspect(deriv);float intensity=u_exaggeration;float base=1.875-intensity*1.75;float maxValue=0.5*PI;float scaledSlope=intensity !=0.5 ? ((pow(base,slope)-1.0)/(pow(base,maxValue)-1.0))*maxValue : slope;float accent=cos(scaledSlope);vec4 accent_color=(1.0-accent)*u_accent*clamp(intensity*2.0,0.0,1.0);float shade=abs(mod((aspect+azimuth)/PI+0.5,2.0)-1.0);vec4 shade_color=mix(u_shadows[0],u_highlights[0],shade)*sin(scaledSlope)*clamp(intensity*2.0,0.0,1.0);fragColor=accent_color*(1.0-shade_color.a)+shade_color;}void basic_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor=u_highlights[0]*(2.0*shade-1.0);}else\\n{fragColor=u_shadows[0]*(1.0-2.0*shade);}}void multidirectional_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;fragColor=vec4(0,0,0,0);for(int i=0; i < NUM_ILLUMINATION_SOURCES; i++){float cos_alt=cos(u_altitudes[i]);float sin_alt=sin(u_altitudes[i]);float cos_az=-cos(u_azimuths[i]);float sin_az=-sin(u_azimuths[i]);float cang=(sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv));float shade=clamp(cang,0.0,1.0);if(shade > 0.5){fragColor+=u_highlights[i]*(2.0*shade-1.0)/float(NUM_ILLUMINATION_SOURCES);}else\\n{fragColor+=u_shadows[i]*(1.0-2.0*shade)/float(NUM_ILLUMINATION_SOURCES);}}}void combined_hillshade(vec2 deriv){deriv=deriv*u_exaggeration*2.0;float azimuth=u_azimuths[0]+PI;float cos_az=cos(azimuth);float sin_az=sin(azimuth);float cos_alt=cos(u_altitudes[0]);float sin_alt=sin(u_altitudes[0]);float cang=acos((sin_alt-(deriv.y*cos_az*cos_alt-deriv.x*sin_az*cos_alt))/sqrt(1.0+dot(deriv,deriv)));cang=clamp(cang,0.0,PI/2.0);float shade=cang*atan(length(deriv))*4.0/PI/PI;float highlight=(PI/2.0-cang)*atan(length(deriv))*4.0/PI/PI;fragColor=u_shadows[0]*shade+u_highlights[0]*highlight;}void main() {vec4 pixel=texture(u_image,v_pos);float scaleFactor=cos(radians((u_latrange[0]-u_latrange[1])*(1.0-v_pos.y)+u_latrange[1]));vec2 deriv=((pixel.rg*8.0)-4.0)/scaleFactor;switch(u_method){case BASIC:\\nbasic_hillshade(deriv);break;case COMBINED:\\ncombined_hillshade(deriv);break;case IGOR:\\nigor_hillshade(deriv);break;case MULTIDIRECTIONAL:\\nmultidirectional_hillshade(deriv);break;case STANDARD:\\ndefault:\\nstandard_hillshade(deriv);break;}\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform mat4 u_matrix;in vec2 a_pos;out vec2 v_pos;void main() {gl_Position=projectTile(a_pos,a_pos);v_pos=a_pos/8192.0;if (a_pos.y <-32767.5) {v_pos.y=0.0;}if (a_pos.y > 32766.5) {v_pos.y=1.0;}}\"),line:yt(\"uniform lowp float u_device_pixel_ratio;in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);fragColor=color*(alpha*opacity);\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"\\n#define scale 0.015873016\\nin vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform vec2 u_units_to_pixels;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;out vec2 v_width2;out float v_gamma_scale;out highp float v_linesofar;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define mediump float gapwidth\\n#pragma mapbox: define lowp float offset\\n#pragma mapbox: define mediump float width\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump float gapwidth\\n#pragma mapbox: initialize lowp float offset\\n#pragma mapbox: initialize mediump float width\\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;v_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*2.0;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n#ifdef TERRAIN3D\\nv_gamma_scale=1.0;\\n#else\\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\\n#endif\\nv_width2=vec2(outset,inset);}\"),lineGradient:yt(\"uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;in vec2 v_width2;in vec2 v_normal;in float v_gamma_scale;in highp vec2 v_uv;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);vec4 color=texture(u_image,v_uv);fragColor=color*(alpha*opacity);\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"\\n#define scale 0.015873016\\nin vec2 a_pos_normal;in vec4 a_data;in float a_uv_x;in float a_split_index;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_units_to_pixels;uniform float u_image_height;out vec2 v_normal;out vec2 v_width2;out float v_gamma_scale;out highp vec2 v_uv;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define mediump float gapwidth\\n#pragma mapbox: define lowp float offset\\n#pragma mapbox: define mediump float width\\nvoid main() {\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump float gapwidth\\n#pragma mapbox: initialize lowp float offset\\n#pragma mapbox: initialize mediump float width\\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;highp float texel_height=1.0/u_image_height;highp float half_texel_height=0.5*texel_height;v_uv=vec2(a_uv_x,a_split_index*texel_height-half_texel_height);vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n#ifdef TERRAIN3D\\nv_gamma_scale=1.0;\\n#else\\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\\n#endif\\nv_width2=vec2(outset,inset);}\"),linePattern:yt(\"#ifdef GL_ES\\nprecision highp float;\\n#endif\\nuniform lowp float u_device_pixel_ratio;uniform vec2 u_texsize;uniform float u_fade;uniform mediump vec3 u_scale;uniform sampler2D u_image;in vec2 v_normal;in vec2 v_width2;in float v_linesofar;in float v_gamma_scale;in float v_width;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\nvec2 pattern_tl_a=pattern_from.xy;vec2 pattern_br_a=pattern_from.zw;vec2 pattern_tl_b=pattern_to.xy;vec2 pattern_br_b=pattern_to.zw;float tileZoomRatio=u_scale.x;float fromScale=u_scale.y;float toScale=u_scale.z;vec2 display_size_a=(pattern_br_a-pattern_tl_a)/pixel_ratio_from;vec2 display_size_b=(pattern_br_b-pattern_tl_b)/pixel_ratio_to;vec2 pattern_size_a=vec2(display_size_a.x*fromScale/tileZoomRatio,display_size_a.y);vec2 pattern_size_b=vec2(display_size_b.x*toScale/tileZoomRatio,display_size_b.y);float aspect_a=display_size_a.y/v_width;float aspect_b=display_size_b.y/v_width;float dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float x_a=mod(v_linesofar/pattern_size_a.x*aspect_a,1.0);float x_b=mod(v_linesofar/pattern_size_b.x*aspect_b,1.0);float y=0.5*v_normal.y+0.5;vec2 texel_size=1.0/u_texsize;vec2 pos_a=mix(pattern_tl_a*texel_size-texel_size,pattern_br_a*texel_size+texel_size,vec2(x_a,y));vec2 pos_b=mix(pattern_tl_b*texel_size-texel_size,pattern_br_b*texel_size+texel_size,vec2(x_b,y));vec4 color=mix(texture(u_image,pos_a),texture(u_image,pos_b),u_fade);fragColor=color*alpha*opacity;\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"\\n#define scale 0.015873016\\n#define LINE_DISTANCE_SCALE 2.0\\nin vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform vec2 u_units_to_pixels;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;out vec2 v_normal;out vec2 v_width2;out float v_linesofar;out float v_gamma_scale;out float v_width;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp float offset\\n#pragma mapbox: define mediump float gapwidth\\n#pragma mapbox: define mediump float width\\n#pragma mapbox: define lowp float floorwidth\\n#pragma mapbox: define lowp vec4 pattern_from\\n#pragma mapbox: define lowp vec4 pattern_to\\n#pragma mapbox: define lowp float pixel_ratio_from\\n#pragma mapbox: define lowp float pixel_ratio_to\\nvoid main() {\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize lowp float offset\\n#pragma mapbox: initialize mediump float gapwidth\\n#pragma mapbox: initialize mediump float width\\n#pragma mapbox: initialize lowp float floorwidth\\n#pragma mapbox: initialize mediump vec4 pattern_from\\n#pragma mapbox: initialize mediump vec4 pattern_to\\n#pragma mapbox: initialize lowp float pixel_ratio_from\\n#pragma mapbox: initialize lowp float pixel_ratio_to\\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n#ifdef TERRAIN3D\\nv_gamma_scale=1.0;\\n#else\\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\\n#endif\\nv_linesofar=a_linesofar;v_width2=vec2(outset,inset);v_width=floorwidth;}\"),lineSDF:yt(\"uniform lowp float u_device_pixel_ratio;uniform sampler2D u_image;uniform float u_sdfgamma;uniform float u_mix;in vec2 v_normal;in vec2 v_width2;in vec2 v_tex_a;in vec2 v_tex_b;in float v_gamma_scale;\\n#ifdef GLOBE\\nin float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define mediump float width\\n#pragma mapbox: define lowp float floorwidth\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump float width\\n#pragma mapbox: initialize lowp float floorwidth\\nfloat dist=length(v_normal)*v_width2.s;float blur2=(blur+1.0/u_device_pixel_ratio)*v_gamma_scale;float alpha=clamp(min(dist-(v_width2.t-blur2),v_width2.s-dist)/blur2,0.0,1.0);float sdfdist_a=texture(u_image,v_tex_a).a;float sdfdist_b=texture(u_image,v_tex_b).a;float sdfdist=mix(sdfdist_a,sdfdist_b,u_mix);alpha*=smoothstep(0.5-u_sdfgamma/floorwidth,0.5+u_sdfgamma/floorwidth,sdfdist);fragColor=color*(alpha*opacity);\\n#ifdef GLOBE\\nif (v_depth > 1.0) {discard;}\\n#endif\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"\\n#define scale 0.015873016\\n#define LINE_DISTANCE_SCALE 2.0\\nin vec2 a_pos_normal;in vec4 a_data;uniform vec2 u_translation;uniform mediump float u_ratio;uniform lowp float u_device_pixel_ratio;uniform vec2 u_patternscale_a;uniform float u_tex_y_a;uniform vec2 u_patternscale_b;uniform float u_tex_y_b;uniform vec2 u_units_to_pixels;out vec2 v_normal;out vec2 v_width2;out vec2 v_tex_a;out vec2 v_tex_b;out float v_gamma_scale;\\n#ifdef GLOBE\\nout float v_depth;\\n#endif\\n#pragma mapbox: define highp vec4 color\\n#pragma mapbox: define lowp float blur\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define mediump float gapwidth\\n#pragma mapbox: define lowp float offset\\n#pragma mapbox: define mediump float width\\n#pragma mapbox: define lowp float floorwidth\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 color\\n#pragma mapbox: initialize lowp float blur\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize mediump float gapwidth\\n#pragma mapbox: initialize lowp float offset\\n#pragma mapbox: initialize mediump float width\\n#pragma mapbox: initialize lowp float floorwidth\\nfloat ANTIALIASING=1.0/u_device_pixel_ratio/2.0;vec2 a_extrude=a_data.xy-128.0;float a_direction=mod(a_data.z,4.0)-1.0;float a_linesofar=(floor(a_data.z/4.0)+a_data.w*64.0)*LINE_DISTANCE_SCALE;vec2 pos=floor(a_pos_normal*0.5);mediump vec2 normal=a_pos_normal-2.0*pos;normal.y=normal.y*2.0-1.0;v_normal=normal;gapwidth=gapwidth/2.0;float halfwidth=width/2.0;offset=-1.0*offset;float inset=gapwidth+(gapwidth > 0.0 ? ANTIALIASING : 0.0);float outset=gapwidth+halfwidth*(gapwidth > 0.0 ? 2.0 : 1.0)+(halfwidth==0.0 ? 0.0 : ANTIALIASING);mediump vec2 dist=outset*a_extrude*scale;mediump float u=0.5*a_direction;mediump float t=1.0-abs(u);mediump vec2 offset2=offset*a_extrude*scale*normal.y*mat2(t,-u,u,t);float adjustedThickness=projectLineThickness(pos.y);vec4 projected_no_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation);vec4 projected_with_extrude=projectTile(pos+offset2/u_ratio*adjustedThickness+u_translation+dist/u_ratio*adjustedThickness);gl_Position=projected_with_extrude;\\n#ifdef GLOBE\\nv_depth=gl_Position.z/gl_Position.w;\\n#endif\\n#ifdef TERRAIN3D\\nv_gamma_scale=1.0;\\n#else\\nfloat extrude_length_without_perspective=length(dist);float extrude_length_with_perspective=length((projected_with_extrude.xy-projected_no_extrude.xy)/projected_with_extrude.w*u_units_to_pixels);v_gamma_scale=extrude_length_without_perspective/extrude_length_with_perspective;\\n#endif\\nv_tex_a=vec2(a_linesofar*u_patternscale_a.x/floorwidth,normal.y*u_patternscale_a.y+u_tex_y_a);v_tex_b=vec2(a_linesofar*u_patternscale_b.x/floorwidth,normal.y*u_patternscale_b.y+u_tex_y_b);v_width2=vec2(outset,inset);}\"),raster:yt(\"uniform float u_fade_t;uniform float u_opacity;uniform sampler2D u_image0;uniform sampler2D u_image1;in vec2 v_pos0;in vec2 v_pos1;uniform float u_brightness_low;uniform float u_brightness_high;uniform float u_saturation_factor;uniform float u_contrast_factor;uniform vec3 u_spin_weights;void main() {vec4 color0=texture(u_image0,v_pos0);vec4 color1=texture(u_image1,v_pos1);if (color0.a > 0.0) {color0.rgb=color0.rgb/color0.a;}if (color1.a > 0.0) {color1.rgb=color1.rgb/color1.a;}vec4 color=mix(color0,color1,u_fade_t);color.a*=u_opacity;vec3 rgb=color.rgb;rgb=vec3(dot(rgb,u_spin_weights.xyz),dot(rgb,u_spin_weights.zxy),dot(rgb,u_spin_weights.yzx));float average=(color.r+color.g+color.b)/3.0;rgb+=(average-rgb)*u_saturation_factor;rgb=(rgb-0.5)*u_contrast_factor+0.5;vec3 u_high_vec=vec3(u_brightness_low,u_brightness_low,u_brightness_low);vec3 u_low_vec=vec3(u_brightness_high,u_brightness_high,u_brightness_high);fragColor=vec4(mix(u_high_vec,u_low_vec,rgb)*color.a,color.a);\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"uniform vec2 u_tl_parent;uniform float u_scale_parent;uniform float u_buffer_scale;uniform vec4 u_coords_top;uniform vec4 u_coords_bottom;in vec2 a_pos;out vec2 v_pos0;out vec2 v_pos1;void main() {vec2 fractionalPos=a_pos/8192.0;vec2 position=mix(mix(u_coords_top.xy,u_coords_top.zw,fractionalPos.x),mix(u_coords_bottom.xy,u_coords_bottom.zw,fractionalPos.x),fractionalPos.y);gl_Position=projectTile(position,position);v_pos0=((fractionalPos-0.5)/u_buffer_scale)+0.5;\\n#ifdef GLOBE\\nif (a_pos.y <-32767.5) {v_pos0.y=0.0;}if (a_pos.y > 32766.5) {v_pos0.y=1.0;}\\n#endif\\nv_pos1=(v_pos0*u_scale_parent)+u_tl_parent;}\"),symbolIcon:yt(\"uniform sampler2D u_texture;in vec2 v_tex;in float v_fade_opacity;\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\nlowp float alpha=opacity*v_fade_opacity;fragColor=texture(u_texture,v_tex)*alpha;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"in vec4 a_pos_offset;in vec4 a_data;in vec4 a_pixeloffset;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform highp float u_camera_to_center_distance;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform float u_fade_change;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform vec2 u_texsize;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;out vec2 v_tex;out float v_fade_opacity;\\n#pragma mapbox: define lowp float opacity\\nvoid main() {\\n#pragma mapbox: initialize lowp float opacity\\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;vec2 a_minFontScale=a_pixeloffset.zw/256.0;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\\ncamera_to_anchor_distance/u_camera_to_center_distance :\\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\\n#ifdef GLOBE\\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\\n#endif\\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*max(a_minFontScale,fontScale)+a_pxoffset/16.0)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}gl_Position=finalPos;v_tex=a_tex/u_texsize;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float visibility=calculate_visibility(projectedPoint);v_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));}\"),symbolSDF:yt(\"#define SDF_PX 8.0\\nuniform bool u_is_halo;uniform sampler2D u_texture;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;uniform bool u_is_text;in vec2 v_data0;in vec3 v_data1;\\n#pragma mapbox: define highp vec4 fill_color\\n#pragma mapbox: define highp vec4 halo_color\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp float halo_width\\n#pragma mapbox: define lowp float halo_blur\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 fill_color\\n#pragma mapbox: initialize highp vec4 halo_color\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize lowp float halo_width\\n#pragma mapbox: initialize lowp float halo_blur\\nfloat EDGE_GAMMA=0.105/u_device_pixel_ratio;vec2 tex=v_data0.xy;float gamma_scale=v_data1.x;float size=v_data1.y;float fade_opacity=v_data1[2];float fontScale=u_is_text ? size/24.0 : size;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float inner_edge=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);inner_edge=inner_edge+gamma*gamma_scale;}lowp float dist=texture(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(inner_edge-gamma_scaled,inner_edge+gamma_scaled,dist);if (u_is_halo) {lowp float halo_edge=(6.0-halo_width/fontScale)/SDF_PX;alpha=min(smoothstep(halo_edge-gamma_scaled,halo_edge+gamma_scaled,dist),1.0-alpha);}fragColor=color*(alpha*opacity*fade_opacity);\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"in vec4 a_pos_offset;in vec4 a_data;in vec4 a_pixeloffset;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_translation;uniform float u_pitched_scale;out vec2 v_data0;out vec3 v_data1;\\n#pragma mapbox: define highp vec4 fill_color\\n#pragma mapbox: define highp vec4 halo_color\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp float halo_width\\n#pragma mapbox: define lowp float halo_blur\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 fill_color\\n#pragma mapbox: initialize highp vec4 halo_color\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize lowp float halo_width\\n#pragma mapbox: initialize lowp float halo_blur\\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);vec2 a_pxoffset=a_pixeloffset.xy;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\\ncamera_to_anchor_distance/u_camera_to_center_distance :\\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=u_is_text ? size/24.0 : size;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\\n#ifdef GLOBE\\nif(u_pitch_with_map) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\\n#endif\\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale+a_pxoffset)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));v_data0=a_tex/u_texsize;v_data1=vec3(gamma_scale,size,interpolated_fade_opacity);}\"),symbolTextAndIcon:yt(\"#define SDF_PX 8.0\\n#define SDF 1.0\\n#define ICON 0.0\\nuniform bool u_is_halo;uniform sampler2D u_texture;uniform sampler2D u_texture_icon;uniform highp float u_gamma_scale;uniform lowp float u_device_pixel_ratio;in vec4 v_data0;in vec4 v_data1;\\n#pragma mapbox: define highp vec4 fill_color\\n#pragma mapbox: define highp vec4 halo_color\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp float halo_width\\n#pragma mapbox: define lowp float halo_blur\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 fill_color\\n#pragma mapbox: initialize highp vec4 halo_color\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize lowp float halo_width\\n#pragma mapbox: initialize lowp float halo_blur\\nfloat fade_opacity=v_data1[2];if (v_data1.w==ICON) {vec2 tex_icon=v_data0.zw;lowp float alpha=opacity*fade_opacity;fragColor=texture(u_texture_icon,tex_icon)*alpha;\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\nreturn;}vec2 tex=v_data0.xy;float EDGE_GAMMA=0.105/u_device_pixel_ratio;float gamma_scale=v_data1.x;float size=v_data1.y;float fontScale=size/24.0;lowp vec4 color=fill_color;highp float gamma=EDGE_GAMMA/(fontScale*u_gamma_scale);lowp float buff=(256.0-64.0)/256.0;if (u_is_halo) {color=halo_color;gamma=(halo_blur*1.19/SDF_PX+EDGE_GAMMA)/(fontScale*u_gamma_scale);buff=(6.0-halo_width/fontScale)/SDF_PX;}lowp float dist=texture(u_texture,tex).a;highp float gamma_scaled=gamma*gamma_scale;highp float alpha=smoothstep(buff-gamma_scaled,buff+gamma_scaled,dist);fragColor=color*(alpha*opacity*fade_opacity);\\n#ifdef OVERDRAW_INSPECTOR\\nfragColor=vec4(1.0);\\n#endif\\n}\",\"in vec4 a_pos_offset;in vec4 a_data;in vec3 a_projected_pos;in float a_fade_opacity;uniform bool u_is_size_zoom_constant;uniform bool u_is_size_feature_constant;uniform highp float u_size_t;uniform highp float u_size;uniform mat4 u_label_plane_matrix;uniform mat4 u_coord_matrix;uniform bool u_is_text;uniform bool u_pitch_with_map;uniform highp float u_pitch;uniform bool u_rotate_symbol;uniform highp float u_aspect_ratio;uniform highp float u_camera_to_center_distance;uniform float u_fade_change;uniform vec2 u_texsize;uniform vec2 u_texsize_icon;uniform bool u_is_along_line;uniform bool u_is_variable_anchor;uniform vec2 u_translation;uniform float u_pitched_scale;out vec4 v_data0;out vec4 v_data1;\\n#pragma mapbox: define highp vec4 fill_color\\n#pragma mapbox: define highp vec4 halo_color\\n#pragma mapbox: define lowp float opacity\\n#pragma mapbox: define lowp float halo_width\\n#pragma mapbox: define lowp float halo_blur\\nvoid main() {\\n#pragma mapbox: initialize highp vec4 fill_color\\n#pragma mapbox: initialize highp vec4 halo_color\\n#pragma mapbox: initialize lowp float opacity\\n#pragma mapbox: initialize lowp float halo_width\\n#pragma mapbox: initialize lowp float halo_blur\\nvec2 a_pos=a_pos_offset.xy;vec2 a_offset=a_pos_offset.zw;vec2 a_tex=a_data.xy;vec2 a_size=a_data.zw;float a_size_min=floor(a_size[0]*0.5);float is_sdf=a_size[0]-2.0*a_size_min;float ele=get_elevation(a_pos);highp float segment_angle=-a_projected_pos[2];float size;if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {size=mix(a_size_min,a_size[1],u_size_t)/128.0;} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {size=a_size_min/128.0;} else {size=u_size;}vec2 translated_a_pos=a_pos+u_translation;vec4 projectedPoint=projectTileWithElevation(translated_a_pos,ele);highp float camera_to_anchor_distance=projectedPoint.w;highp float distance_ratio=u_pitch_with_map ?\\ncamera_to_anchor_distance/u_camera_to_center_distance :\\nu_camera_to_center_distance/camera_to_anchor_distance;highp float perspective_ratio=clamp(0.5+0.5*distance_ratio,0.0,4.0);size*=perspective_ratio;float fontScale=size/24.0;highp float symbol_rotation=0.0;if (u_rotate_symbol) {vec4 offsetProjectedPoint=projectTileWithElevation(translated_a_pos+vec2(1,0),ele);vec2 a=projectedPoint.xy/projectedPoint.w;vec2 b=offsetProjectedPoint.xy/offsetProjectedPoint.w;symbol_rotation=atan((b.y-a.y)/u_aspect_ratio,b.x-a.x);}highp float angle_sin=sin(segment_angle+symbol_rotation);highp float angle_cos=cos(segment_angle+symbol_rotation);mat2 rotation_matrix=mat2(angle_cos,-1.0*angle_sin,angle_sin,angle_cos);vec4 projected_pos;if (u_is_along_line || u_is_variable_anchor) {projected_pos=vec4(a_projected_pos.xy,ele,1.0);} else if (u_pitch_with_map) {projected_pos=u_label_plane_matrix*vec4(a_projected_pos.xy+u_translation,ele,1.0);} else {projected_pos=u_label_plane_matrix*projectTileWithElevation(a_projected_pos.xy+u_translation,ele);}float z=float(u_pitch_with_map)*projected_pos.z/projected_pos.w;float projectionScaling=1.0;\\n#ifdef GLOBE\\nif(u_pitch_with_map && !u_is_along_line) {float anchor_pos_tile_y=(u_coord_matrix*vec4(projected_pos.xy/projected_pos.w,z,1.0)).y;projectionScaling=mix(projectionScaling,1.0/circumferenceRatioAtTileY(anchor_pos_tile_y)*u_pitched_scale,u_projection_transition);}\\n#endif\\nvec4 finalPos=u_coord_matrix*vec4(projected_pos.xy/projected_pos.w+rotation_matrix*(a_offset/32.0*fontScale)*projectionScaling,z,1.0);if(u_pitch_with_map) {finalPos=projectTileWithElevation(finalPos.xy,finalPos.z);}float gamma_scale=finalPos.w;gl_Position=finalPos;vec2 fade_opacity=unpack_opacity(a_fade_opacity);float visibility=calculate_visibility(projectedPoint);float fade_change=fade_opacity[1] > 0.5 ? u_fade_change :-u_fade_change;float interpolated_fade_opacity=max(0.0,min(visibility,fade_opacity[0]+fade_change));v_data0.xy=a_tex/u_texsize;v_data0.zw=a_tex/u_texsize_icon;v_data1=vec4(gamma_scale,size,interpolated_fade_opacity,is_sdf);}\"),terrain:yt(\"uniform sampler2D u_texture;uniform vec4 u_fog_color;uniform vec4 u_horizon_color;uniform float u_fog_ground_blend;uniform float u_fog_ground_blend_opacity;uniform float u_horizon_fog_blend;uniform bool u_is_globe_mode;in vec2 v_texture_pos;in float v_fog_depth;const float gamma=2.2;vec4 gammaToLinear(vec4 color) {return pow(color,vec4(gamma));}vec4 linearToGamma(vec4 color) {return pow(color,vec4(1.0/gamma));}void main() {vec4 surface_color=texture(u_texture,vec2(v_texture_pos.x,1.0-v_texture_pos.y));if (!u_is_globe_mode && v_fog_depth > u_fog_ground_blend) {vec4 surface_color_linear=gammaToLinear(surface_color);float blend_color=smoothstep(0.0,1.0,max((v_fog_depth-u_horizon_fog_blend)/(1.0-u_horizon_fog_blend),0.0));vec4 fog_horizon_color_linear=mix(gammaToLinear(u_fog_color),gammaToLinear(u_horizon_color),blend_color);float factor_fog=max(v_fog_depth-u_fog_ground_blend,0.0)/(1.0-u_fog_ground_blend);fragColor=linearToGamma(mix(surface_color_linear,fog_horizon_color_linear,pow(factor_fog,2.0)*u_fog_ground_blend_opacity));} else {fragColor=surface_color;}}\",\"in vec3 a_pos3d;uniform mat4 u_fog_matrix;uniform float u_ele_delta;out vec2 v_texture_pos;out float v_fog_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,get_elevation(a_pos3d.xy)-ele_delta);vec4 pos=u_fog_matrix*vec4(a_pos3d.xy,ele,1.0);v_fog_depth=pos.z/pos.w*0.5+0.5;}\"),terrainDepth:yt(\"in float v_depth;const highp vec4 bitSh=vec4(256.*256.*256.,256.*256.,256.,1.);const highp vec4 bitMsk=vec4(0.,vec3(1./256.0));highp vec4 pack(highp float value) {highp vec4 comp=fract(value*bitSh);comp-=comp.xxyz*bitMsk;return comp;}void main() {fragColor=pack(v_depth);}\",\"in vec3 a_pos3d;uniform float u_ele_delta;out float v_depth;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);v_depth=gl_Position.z/gl_Position.w;}\"),terrainCoords:yt(\"precision mediump float;uniform sampler2D u_texture;uniform float u_terrain_coords_id;in vec2 v_texture_pos;void main() {vec4 rgba=texture(u_texture,v_texture_pos);fragColor=vec4(rgba.r,rgba.g,rgba.b,u_terrain_coords_id);}\",\"in vec3 a_pos3d;uniform float u_ele_delta;out vec2 v_texture_pos;void main() {float ele=get_elevation(a_pos3d.xy);float ele_delta=a_pos3d.z==1.0 ? u_ele_delta : 0.0;v_texture_pos=a_pos3d.xy/8192.0;gl_Position=projectTileFor3D(a_pos3d.xy,ele-ele_delta);}\"),projectionErrorMeasurement:yt(\"in vec4 v_output_error_encoded;void main() {fragColor=v_output_error_encoded;}\",\"in vec2 a_pos;uniform highp float u_input;uniform highp float u_output_expected;out vec4 v_output_error_encoded;void main() {float real_output=2.0*atan(exp(PI-(u_input*PI*2.0)))-PI*0.5;float error=real_output-u_output_expected;float abs_error=abs(error)*128.0;v_output_error_encoded.x=min(floor(abs_error*256.0),255.0)/255.0;abs_error-=v_output_error_encoded.x;v_output_error_encoded.y=min(floor(abs_error*65536.0),255.0)/255.0;abs_error-=v_output_error_encoded.x/255.0;v_output_error_encoded.z=min(floor(abs_error*16777216.0),255.0)/255.0;v_output_error_encoded.w=error >=0.0 ? 1.0 : 0.0;gl_Position=vec4(a_pos,0.0,1.0);}\"),atmosphere:yt(\"in vec3 view_direction;uniform vec3 u_sun_pos;uniform vec3 u_globe_position;uniform float u_globe_radius;uniform float u_atmosphere_blend;/**Shader use from https:*Made some change to adapt to MapLibre Globe geometry*/const float PI=3.141592653589793;const int iSteps=5;const int jSteps=3;/*radius of the planet*/const float EARTH_RADIUS=6371e3;/*radius of the atmosphere*/const float ATMOS_RADIUS=6471e3;vec2 rsi(vec3 r0,vec3 rd,float sr) {float a=dot(rd,rd);float b=2.0*dot(rd,r0);float c=dot(r0,r0)-(sr*sr);float d=(b*b)-4.0*a*c;if (d < 0.0) return vec2(1e5,-1e5);return vec2((-b-sqrt(d))/(2.0*a),(-b+sqrt(d))/(2.0*a));}vec4 atmosphere(vec3 r,vec3 r0,vec3 pSun,float iSun,float rPlanet,float rAtmos,vec3 kRlh,float kMie,float shRlh,float shMie,float g) {pSun=normalize(pSun);r=normalize(r);vec2 p=rsi(r0,r,rAtmos);if (p.x > p.y) {return vec4(0.0,0.0,0.0,1.0);}if (p.x < 0.0) {p.x=0.0;}vec3 pos=r0+r*p.x;vec2 p2=rsi(r0,r,rPlanet);if (p2.x <=p2.y && p2.x > 0.0) {p.y=min(p.y,p2.x);}float iStepSize=(p.y-p.x)/float(iSteps);float iTime=p.x+iStepSize*0.5;vec3 totalRlh=vec3(0,0,0);vec3 totalMie=vec3(0,0,0);float iOdRlh=0.0;float iOdMie=0.0;float mu=dot(r,pSun);float mumu=mu*mu;float gg=g*g;float pRlh=3.0/(16.0*PI)*(1.0+mumu);float pMie=3.0/(8.0*PI)*((1.0-gg)*(mumu+1.0))/(pow(1.0+gg-2.0*mu*g,1.5)*(2.0+gg));for (int i=0; i < iSteps; i++) {vec3 iPos=r0+r*iTime;float iHeight=length(iPos)-rPlanet;float odStepRlh=exp(-iHeight/shRlh)*iStepSize;float odStepMie=exp(-iHeight/shMie)*iStepSize;iOdRlh+=odStepRlh;iOdMie+=odStepMie;float jStepSize=rsi(iPos,pSun,rAtmos).y/float(jSteps);float jTime=jStepSize*0.5;float jOdRlh=0.0;float jOdMie=0.0;for (int j=0; j < jSteps; j++) {vec3 jPos=iPos+pSun*jTime;float jHeight=length(jPos)-rPlanet;jOdRlh+=exp(-jHeight/shRlh)*jStepSize;jOdMie+=exp(-jHeight/shMie)*jStepSize;jTime+=jStepSize;}vec3 attn=exp(-(kMie*(iOdMie+jOdMie)+kRlh*(iOdRlh+jOdRlh)));totalRlh+=odStepRlh*attn;totalMie+=odStepMie*attn;iTime+=iStepSize;}float opacity=exp(-(length(kRlh)*length(totalRlh)+kMie*length(totalMie)));vec3 color=iSun*(pRlh*kRlh*totalRlh+pMie*kMie*totalMie);return vec4(color,opacity);}void main() {vec3 scale_camera_pos=-u_globe_position*EARTH_RADIUS/u_globe_radius;vec4 color=atmosphere(normalize(view_direction),scale_camera_pos,u_sun_pos,22.0,EARTH_RADIUS,ATMOS_RADIUS,vec3(5.5e-6,13.0e-6,22.4e-6),21e-6,8e3,1.2e3,0.758\\n);color.rgb=1.0-exp(-1.0*color.rgb);color=pow(color,vec4(1.0/2.2));fragColor=vec4(color.rgb,1.0-color.a)*u_atmosphere_blend;}\",\"in vec2 a_pos;uniform mat4 u_inv_proj_matrix;out vec3 view_direction;void main() {view_direction=(u_inv_proj_matrix*vec4(a_pos,0.0,1.0)).xyz;gl_Position=vec4(a_pos,0.0,1.0);}\"),sky:yt(\"uniform vec4 u_sky_color;uniform vec4 u_horizon_color;uniform vec2 u_horizon;uniform vec2 u_horizon_normal;uniform float u_sky_horizon_blend;uniform float u_sky_blend;void main() {float x=gl_FragCoord.x;float y=gl_FragCoord.y;float blend=(y-u_horizon.y)*u_horizon_normal.y+(x-u_horizon.x)*u_horizon_normal.x;if (blend > 0.0) {if (blend < u_sky_horizon_blend) {fragColor=mix(u_sky_color,u_horizon_color,pow(1.0-blend/u_sky_horizon_blend,2.0));} else {fragColor=u_sky_color;}}fragColor=mix(fragColor,vec4(vec3(0.0),0.0),u_sky_blend);}\",\"in vec2 a_pos;void main() {gl_Position=vec4(a_pos,1.0,1.0);}\")};function yt(e,t){const i=/#pragma mapbox: ([\\w]+) ([\\w]+) ([\\w]+) ([\\w]+)/g,o=t.match(/in ([\\w]+) ([\\w]+)/g),r=e.match(/uniform ([\\w]+) ([\\w]+)([\\s]*)([\\w]*)/g),a=t.match(/uniform ([\\w]+) ([\\w]+)([\\s]*)([\\w]*)/g),s=a?a.concat(r):r,n={};return {fragmentSource:e=e.replace(i,((e,t,i,o,r)=>(n[r]=!0,\"define\"===t?`\\n#ifndef HAS_UNIFORM_u_${r}\\nin ${i} ${o} ${r};\\n#else\\nuniform ${i} ${o} u_${r};\\n#endif\\n`:`\\n#ifdef HAS_UNIFORM_u_${r}\\n    ${i} ${o} ${r} = u_${r};\\n#endif\\n`))),vertexSource:t=t.replace(i,((e,t,i,o,r)=>{const a=\"float\"===o?\"vec2\":\"vec4\",s=r.match(/color/)?\"color\":a;return n[r]?\"define\"===t?`\\n#ifndef HAS_UNIFORM_u_${r}\\nuniform lowp float u_${r}_t;\\nin ${i} ${a} a_${r};\\nout ${i} ${o} ${r};\\n#else\\nuniform ${i} ${o} u_${r};\\n#endif\\n`:\"vec4\"===s?`\\n#ifndef HAS_UNIFORM_u_${r}\\n    ${r} = a_${r};\\n#else\\n    ${i} ${o} ${r} = u_${r};\\n#endif\\n`:`\\n#ifndef HAS_UNIFORM_u_${r}\\n    ${r} = unpack_mix_${s}(a_${r}, u_${r}_t);\\n#else\\n    ${i} ${o} ${r} = u_${r};\\n#endif\\n`:\"define\"===t?`\\n#ifndef HAS_UNIFORM_u_${r}\\nuniform lowp float u_${r}_t;\\nin ${i} ${a} a_${r};\\n#else\\nuniform ${i} ${o} u_${r};\\n#endif\\n`:\"vec4\"===s?`\\n#ifndef HAS_UNIFORM_u_${r}\\n    ${i} ${o} ${r} = a_${r};\\n#else\\n    ${i} ${o} ${r} = u_${r};\\n#endif\\n`:`\\n#ifndef HAS_UNIFORM_u_${r}\\n    ${i} ${o} ${r} = unpack_mix_${s}(a_${r}, u_${r}_t);\\n#else\\n    ${i} ${o} ${r} = u_${r};\\n#endif\\n`})),staticAttributes:o,staticUniforms:s}}class wt{constructor(e,t,i){this.vertexBuffer=e,this.indexBuffer=t,this.segments=i;}destroy(){this.vertexBuffer.destroy(),this.indexBuffer.destroy(),this.segments.destroy(),this.vertexBuffer=null,this.indexBuffer=null,this.segments=null;}}var Tt=t.aI([{name:\"a_pos\",type:\"Int16\",components:2}]);const Pt=\"#define PROJECTION_MERCATOR\",Ct=\"mercator\";class It{constructor(){this._cachedMesh=null;}get name(){return \"mercator\"}get useSubdivision(){return !1}get shaderVariantName(){return Ct}get shaderDefine(){return Pt}get shaderPreludeCode(){return xt.projectionMercator}get vertexShaderPreludeCode(){return xt.projectionMercator.vertexSource}get subdivisionGranularity(){return t.aJ.noSubdivision}get useGlobeControls(){return !1}get transitionState(){return 0}get latitudeErrorCorrectionRadians(){return 0}destroy(){}updateGPUdependent(e){}getMeshFromTileID(e,i,o,r,a){if(this._cachedMesh)return this._cachedMesh;const s=new t.aK;s.emplaceBack(0,0),s.emplaceBack(t.$,0),s.emplaceBack(0,t.$),s.emplaceBack(t.$,t.$);const n=e.createVertexBuffer(s,Tt.members),l=t.aL.simpleSegment(0,0,4,2),c=new t.aM;c.emplaceBack(1,0,2),c.emplaceBack(1,2,3);const h=e.createIndexBuffer(c);return this._cachedMesh=new wt(n,h,l),this._cachedMesh}recalculate(){}hasTransition(){return !1}setErrorQueryLatitudeDegrees(e){}}class Mt{constructor(e=0,t=0,i=0,o=0){if(isNaN(e)||e<0||isNaN(t)||t<0||isNaN(i)||i<0||isNaN(o)||o<0)throw new Error(\"Invalid value for edge-insets, top, bottom, left and right must all be numbers\");this.top=e,this.bottom=t,this.left=i,this.right=o;}interpolate(e,i,o){return null!=i.top&&null!=e.top&&(this.top=t.C.number(e.top,i.top,o)),null!=i.bottom&&null!=e.bottom&&(this.bottom=t.C.number(e.bottom,i.bottom,o)),null!=i.left&&null!=e.left&&(this.left=t.C.number(e.left,i.left,o)),null!=i.right&&null!=e.right&&(this.right=t.C.number(e.right,i.right,o)),this}getCenter(e,i){const o=t.ag((this.left+e-this.right)/2,0,e),r=t.ag((this.top+i-this.bottom)/2,0,i);return new t.P(o,r)}equals(e){return this.top===e.top&&this.bottom===e.bottom&&this.left===e.left&&this.right===e.right}clone(){return new Mt(this.top,this.bottom,this.left,this.right)}toJSON(){return {top:this.top,bottom:this.bottom,left:this.left,right:this.right}}}function St(e,t){if(!e.renderWorldCopies||e.lngRange)return;const i=t.lng-e.center.lng;t.lng+=i>180?-360:i<-180?360:0;}function Et(e){return Math.max(0,Math.floor(e))}class Rt{constructor(e,i,o,r,a,s){this._callbacks=e,this._tileSize=512,this._renderWorldCopies=void 0===s||!!s,this._minZoom=i||0,this._maxZoom=o||22,this._minPitch=null==r?0:r,this._maxPitch=null==a?60:a,this.setMaxBounds(),this._width=0,this._height=0,this._center=new t.S(0,0),this._elevation=0,this._zoom=0,this._tileZoom=Et(this._zoom),this._scale=t.ae(this._zoom),this._bearingInRadians=0,this._fovInRadians=.6435011087932844,this._pitchInRadians=0,this._rollInRadians=0,this._unmodified=!0,this._edgeInsets=new Mt,this._minElevationForCurrentTile=0,this._autoCalculateNearFarZ=!0;}apply(e,i,o){this._latRange=e.latRange,this._lngRange=e.lngRange,this._width=e.width,this._height=e.height,this._center=e.center,this._elevation=e.elevation,this._minElevationForCurrentTile=e.minElevationForCurrentTile,this._zoom=e.zoom,this._tileZoom=Et(this._zoom),this._scale=t.ae(this._zoom),this._bearingInRadians=e.bearingInRadians,this._fovInRadians=e.fovInRadians,this._pitchInRadians=e.pitchInRadians,this._rollInRadians=e.rollInRadians,this._unmodified=e.unmodified,this._edgeInsets=new Mt(e.padding.top,e.padding.bottom,e.padding.left,e.padding.right),this._minZoom=e.minZoom,this._maxZoom=e.maxZoom,this._minPitch=e.minPitch,this._maxPitch=e.maxPitch,this._renderWorldCopies=e.renderWorldCopies,this._cameraToCenterDistance=e.cameraToCenterDistance,this._nearZ=e.nearZ,this._farZ=e.farZ,this._autoCalculateNearFarZ=!o&&e.autoCalculateNearFarZ,i&&this._constrain(),this._calcMatrices();}get pixelsToClipSpaceMatrix(){return this._pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._clipSpaceToPixelsMatrix}get minElevationForCurrentTile(){return this._minElevationForCurrentTile}setMinElevationForCurrentTile(e){this._minElevationForCurrentTile=e;}get tileSize(){return this._tileSize}get tileZoom(){return this._tileZoom}get scale(){return this._scale}get width(){return this._width}get height(){return this._height}get bearingInRadians(){return this._bearingInRadians}get lngRange(){return this._lngRange}get latRange(){return this._latRange}get pixelsToGLUnits(){return this._pixelsToGLUnits}get minZoom(){return this._minZoom}setMinZoom(e){this._minZoom!==e&&(this._minZoom=e,this.setZoom(this.getConstrained(this._center,this.zoom).zoom));}get maxZoom(){return this._maxZoom}setMaxZoom(e){this._maxZoom!==e&&(this._maxZoom=e,this.setZoom(this.getConstrained(this._center,this.zoom).zoom));}get minPitch(){return this._minPitch}setMinPitch(e){this._minPitch!==e&&(this._minPitch=e,this.setPitch(Math.max(this.pitch,e)));}get maxPitch(){return this._maxPitch}setMaxPitch(e){this._maxPitch!==e&&(this._maxPitch=e,this.setPitch(Math.min(this.pitch,e)));}get renderWorldCopies(){return this._renderWorldCopies}setRenderWorldCopies(e){void 0===e?e=!0:null===e&&(e=!1),this._renderWorldCopies=e;}get worldSize(){return this._tileSize*this._scale}get centerOffset(){return this.centerPoint._sub(this.size._div(2))}get size(){return new t.P(this._width,this._height)}get bearing(){return this._bearingInRadians/Math.PI*180}setBearing(e){const i=t.aN(e,-180,180)*Math.PI/180;var r,a,s,n,l,c,h,u,d;this._bearingInRadians!==i&&(this._unmodified=!1,this._bearingInRadians=i,this._calcMatrices(),this._rotationMatrix=o(),r=this._rotationMatrix,s=-this._bearingInRadians,n=(a=this._rotationMatrix)[0],l=a[1],c=a[2],h=a[3],u=Math.sin(s),d=Math.cos(s),r[0]=n*d+c*u,r[1]=l*d+h*u,r[2]=n*-u+c*d,r[3]=l*-u+h*d);}get rotationMatrix(){return this._rotationMatrix}get pitchInRadians(){return this._pitchInRadians}get pitch(){return this._pitchInRadians/Math.PI*180}setPitch(e){const i=t.ag(e,this.minPitch,this.maxPitch)/180*Math.PI;this._pitchInRadians!==i&&(this._unmodified=!1,this._pitchInRadians=i,this._calcMatrices());}get rollInRadians(){return this._rollInRadians}get roll(){return this._rollInRadians/Math.PI*180}setRoll(e){const t=e/180*Math.PI;this._rollInRadians!==t&&(this._unmodified=!1,this._rollInRadians=t,this._calcMatrices());}get fovInRadians(){return this._fovInRadians}get fov(){return t.aO(this._fovInRadians)}setFov(e){e=t.ag(e,.1,150),this.fov!==e&&(this._unmodified=!1,this._fovInRadians=t.ad(e),this._calcMatrices());}get zoom(){return this._zoom}setZoom(e){const i=this.getConstrained(this._center,e).zoom;this._zoom!==i&&(this._unmodified=!1,this._zoom=i,this._tileZoom=Math.max(0,Math.floor(i)),this._scale=t.ae(i),this._constrain(),this._calcMatrices());}get center(){return this._center}setCenter(e){e.lat===this._center.lat&&e.lng===this._center.lng||(this._unmodified=!1,this._center=e,this._constrain(),this._calcMatrices());}get elevation(){return this._elevation}setElevation(e){e!==this._elevation&&(this._elevation=e,this._constrain(),this._calcMatrices());}get padding(){return this._edgeInsets.toJSON()}setPadding(e){this._edgeInsets.equals(e)||(this._unmodified=!1,this._edgeInsets.interpolate(this._edgeInsets,e,1),this._calcMatrices());}get centerPoint(){return this._edgeInsets.getCenter(this._width,this._height)}get pixelsPerMeter(){return this._pixelPerMeter}get unmodified(){return this._unmodified}get cameraToCenterDistance(){return this._cameraToCenterDistance}get nearZ(){return this._nearZ}get farZ(){return this._farZ}get autoCalculateNearFarZ(){return this._autoCalculateNearFarZ}overrideNearFarZ(e,t){this._autoCalculateNearFarZ=!1,this._nearZ=e,this._farZ=t,this._calcMatrices();}clearNearFarZOverride(){this._autoCalculateNearFarZ=!0,this._calcMatrices();}isPaddingEqual(e){return this._edgeInsets.equals(e)}interpolatePadding(e,t,i){this._unmodified=!1,this._edgeInsets.interpolate(e,t,i),this._constrain(),this._calcMatrices();}resize(e,t,i=!0){this._width=e,this._height=t,i&&this._constrain(),this._calcMatrices();}getMaxBounds(){return this._latRange&&2===this._latRange.length&&this._lngRange&&2===this._lngRange.length?new G([this._lngRange[0],this._latRange[0]],[this._lngRange[1],this._latRange[1]]):null}setMaxBounds(e){e?(this._lngRange=[e.getWest(),e.getEast()],this._latRange=[e.getSouth(),e.getNorth()],this._constrain()):(this._lngRange=null,this._latRange=[-85.051129,t.ah]);}getConstrained(e,t){return this._callbacks.getConstrained(e,t)}getCameraQueryGeometry(e,i){if(1===i.length)return [i[0],e];{const{minX:o,minY:r,maxX:a,maxY:s}=t.a1.fromPoints(i).extend(e);return [new t.P(o,r),new t.P(a,r),new t.P(a,s),new t.P(o,s),new t.P(o,r)]}}_constrain(){if(!this.center||!this._width||!this._height||this._constraining)return;this._constraining=!0;const e=this._unmodified,{center:t,zoom:i}=this.getConstrained(this.center,this.zoom);this.setCenter(t),this.setZoom(i),this._unmodified=e,this._constraining=!1;}_calcMatrices(){if(this._width&&this._height){this._pixelsToGLUnits=[2/this._width,-2/this._height];let e=t.af(new Float64Array(16));t.N(e,e,[this._width/2,-this._height/2,1]),t.M(e,e,[1,-1,0]),this._clipSpaceToPixelsMatrix=e,e=t.af(new Float64Array(16)),t.N(e,e,[1,-1,1]),t.M(e,e,[-1,-1,0]),t.N(e,e,[2/this._width,2/this._height,1]),this._pixelsToClipSpaceMatrix=e,this._cameraToCenterDistance=.5/Math.tan(this.fovInRadians/2)*this._height;}this._callbacks.calcMatrices();}calculateCenterFromCameraLngLatAlt(e,i,o,r){const a=void 0!==o?o:this.bearing,s=r=void 0!==r?r:this.pitch,n=t.a0.fromLngLat(e,i),l=-Math.cos(t.ad(s)),c=Math.sin(t.ad(s)),h=c*Math.sin(t.ad(a)),u=-c*Math.cos(t.ad(a));let d=this.elevation;const _=i-d;let p;l*_>=0||Math.abs(l)<.1?(p=1e4,d=i+p*l):p=-_/l;let m,f,g=t.aP(1,n.y),v=0;do{if(v+=1,v>10)break;f=p/g,m=new t.a0(n.x+h*f,n.y+u*f),g=1/m.meterInMercatorCoordinateUnits();}while(Math.abs(p-f*g)>1e-12);return {center:m.toLngLat(),elevation:d,zoom:t.aj(this.height/2/Math.tan(this.fovInRadians/2)/f/this.tileSize)}}recalculateZoomAndCenter(e){if(this.elevation-e==0)return;const i=t.ai(1,this.center.lat)*this.worldSize,o=this.cameraToCenterDistance/i,r=t.a0.fromLngLat(this.center,this.elevation),a=de(this.center,this.elevation,this.pitch,this.bearing,o);this._elevation=e;const s=this.calculateCenterFromCameraLngLatAlt(a.toLngLat(),t.aP(a.z,r.y),this.bearing,this.pitch);this._elevation=s.elevation,this._center=s.center,this.setZoom(s.zoom);}getCameraPoint(){const e=Math.tan(this.pitchInRadians)*(this.cameraToCenterDistance||1);return this.centerPoint.add(new t.P(e*Math.sin(this.rollInRadians),e*Math.cos(this.rollInRadians)))}getCameraAltitude(){return Math.cos(this.pitchInRadians)*this._cameraToCenterDistance/this._pixelPerMeter+this.elevation}getCameraLngLat(){const e=t.ai(1,this.center.lat)*this.worldSize;return de(this.center,this.elevation,this.pitch,this.bearing,this.cameraToCenterDistance/e).toLngLat()}getMercatorTileCoordinates(e){if(!e)return [0,0,1,1];const i=e.canonical.z>=0?1<<e.canonical.z:Math.pow(2,e.canonical.z);return [e.canonical.x/i,e.canonical.y/i,1/i/t.$,1/i/t.$]}}class zt{constructor(e,i){this.min=e,this.max=i,this.center=t.aQ([],t.aR([],this.min,this.max),.5);}quadrant(e){const i=[e%2==0,e<2],o=t.aS(this.min),r=t.aS(this.max);for(let e=0;e<i.length;e++)o[e]=i[e]?this.min[e]:this.center[e],r[e]=i[e]?this.center[e]:this.max[e];return r[2]=this.max[2],new zt(o,r)}distanceX(e){return Math.max(Math.min(this.max[0],e[0]),this.min[0])-e[0]}distanceY(e){return Math.max(Math.min(this.max[1],e[1]),this.min[1])-e[1]}intersectsFrustum(e){let t=!0;for(let i=0;i<e.planes.length;i++){const o=this.intersectsPlane(e.planes[i]);if(0===o)return 0;1===o&&(t=!1);}return t?2:e.aabb.min[0]>this.max[0]||e.aabb.min[1]>this.max[1]||e.aabb.min[2]>this.max[2]||e.aabb.max[0]<this.min[0]||e.aabb.max[1]<this.min[1]||e.aabb.max[2]<this.min[2]?0:1}intersectsPlane(e){let t=e[3],i=e[3];for(let o=0;o<3;o++)e[o]>0?(t+=e[o]*this.min[o],i+=e[o]*this.max[o]):(i+=e[o]*this.min[o],t+=e[o]*this.max[o]);return t>=0?2:i<0?0:1}}class Dt{distanceToTile2d(e,t,i,o){const r=o.distanceX([e,t]),a=o.distanceY([e,t]);return Math.hypot(r,a)}getWrap(e,t,i){return i}getTileBoundingVolume(e,i,o,r){var a,s;let n=o,l=o;if(null==r?void 0:r.terrain){const c=new t.Z(e.z,i,e.z,e.x,e.y),h=r.terrain.getMinMaxElevation(c);n=null!==(a=h.minElevation)&&void 0!==a?a:o,l=null!==(s=h.maxElevation)&&void 0!==s?s:o;}const c=1<<e.z;return new zt([i+e.x/c,e.y/c,n],[i+(e.x+1)/c,(e.y+1)/c,l])}allowVariableZoom(e,i){const o=e.fov*(Math.abs(Math.cos(e.rollInRadians))*e.height+Math.abs(Math.sin(e.rollInRadians))*e.width)/e.height,r=t.ag(78.5-o/2,0,60);return !!i.terrain||e.pitch>r}allowWorldCopies(){return !0}prepareNextFrame(){}}class At{constructor(e,t,i){this.points=e,this.planes=t,this.aabb=i;}static fromInvProjectionMatrix(e,i=1,o=0,r,a){const s=a?[[6,5,4],[0,1,2],[0,3,7],[2,1,5],[3,2,6],[0,4,5]]:[[0,1,2],[6,5,4],[0,3,7],[2,1,5],[3,2,6],[0,4,5]],n=Math.pow(2,o),l=[[-1,1,-1,1],[1,1,-1,1],[1,-1,-1,1],[-1,-1,-1,1],[-1,1,1,1],[1,1,1,1],[1,-1,1,1],[-1,-1,1,1]].map((o=>function(e,i,o,r){const a=t.av([],e,i),s=1/a[3]/o*r;return t.aX(a,a,[s,s,1/a[3],s])}(o,e,i,n)));r&&function(e,i,o,r){const a=r?4:0,s=r?0:4;let n=0;const l=[],c=[];for(let i=0;i<4;i++){const o=t.aT([],e[i+s],e[i+a]),r=t.aY(o);t.aQ(o,o,1/r),l.push(r),c.push(o);}for(let i=0;i<4;i++){const r=t.aZ(e[i+a],c[i],o);n=null!==r&&r>=0?Math.max(n,r):Math.max(n,l[i]);}const h=function(e,i){const o=t.aT([],e[i[0]],e[i[1]]),r=t.aT([],e[i[2]],e[i[1]]),a=[0,0,0,0];return t.aU(a,t.aV([],o,r)),a[3]=-t.aW(a,e[i[0]]),a}(e,i),u=function(e,i){const o=t.a_(e),r=t.a$([],e,1/o),a=t.aT([],i,t.aQ([],r,t.aW(i,r))),s=t.a_(a);if(s>0){const e=Math.sqrt(1-r[3]*r[3]),o=t.aQ([],r,-r[3]),n=t.aR([],o,t.aQ([],a,e/s));return t.b0(i,n)}return null}(o,h);if(null!==u){const e=u/t.aW(c[0],h);n=Math.min(n,e);}for(let t=0;t<4;t++){const i=Math.min(n,l[t]);e[t+s]=[e[t+a][0]+c[t][0]*i,e[t+a][1]+c[t][1]*i,e[t+a][2]+c[t][2]*i,1];}}(l,s[0],r,a);const c=s.map((e=>{const i=t.aT([],l[e[0]],l[e[1]]),o=t.aT([],l[e[2]],l[e[1]]),r=t.aU([],t.aV([],i,o)),a=-t.aW(r,l[e[1]]);return r.concat(a)})),h=[Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY],u=[Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY];for(const e of l)for(let t=0;t<3;t++)h[t]=Math.min(h[t],e[t]),u[t]=Math.max(u[t],e[t]);return new At(l,c,new zt(h,u))}}class Lt{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(e){this._helper.setMinZoom(e);}setMaxZoom(e){this._helper.setMaxZoom(e);}setMinPitch(e){this._helper.setMinPitch(e);}setMaxPitch(e){this._helper.setMaxPitch(e);}setRenderWorldCopies(e){this._helper.setRenderWorldCopies(e);}setBearing(e){this._helper.setBearing(e);}setPitch(e){this._helper.setPitch(e);}setRoll(e){this._helper.setRoll(e);}setFov(e){this._helper.setFov(e);}setZoom(e){this._helper.setZoom(e);}setCenter(e){this._helper.setCenter(e);}setElevation(e){this._helper.setElevation(e);}setMinElevationForCurrentTile(e){this._helper.setMinElevationForCurrentTile(e);}setPadding(e){this._helper.setPadding(e);}interpolatePadding(e,t,i){return this._helper.interpolatePadding(e,t,i)}isPaddingEqual(e){return this._helper.isPaddingEqual(e)}resize(e,t,i=!0){this._helper.resize(e,t,i);}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(e){this._helper.setMaxBounds(e);}overrideNearFarZ(e,t){this._helper.overrideNearFarZ(e,t);}clearNearFarZOverride(){this._helper.clearNearFarZOverride();}getCameraQueryGeometry(e){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),e)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}setTransitionState(e,t){}constructor(e,t,i,o,r){this._posMatrixCache=new Map,this._alignedPosMatrixCache=new Map,this._fogMatrixCacheF32=new Map,this._helper=new Rt({calcMatrices:()=>{this._calcMatrices();},getConstrained:(e,t)=>this.getConstrained(e,t)},e,t,i,o,r),this._coveringTilesDetailsProvider=new Dt;}clone(){const e=new Lt;return e.apply(this),e}apply(e,t,i){this._helper.apply(e,t,i);}get cameraPosition(){return this._cameraPosition}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._viewProjMatrix}get inverseProjectionMatrix(){return this._invProjMatrix}get mercatorMatrix(){return this._mercatorMatrix}getVisibleUnwrappedCoordinates(e){const i=[new t.b1(0,e)];if(this._helper._renderWorldCopies){const o=this.screenPointToMercatorCoordinate(new t.P(0,0)),r=this.screenPointToMercatorCoordinate(new t.P(this._helper._width,0)),a=this.screenPointToMercatorCoordinate(new t.P(this._helper._width,this._helper._height)),s=this.screenPointToMercatorCoordinate(new t.P(0,this._helper._height)),n=Math.floor(Math.min(o.x,r.x,a.x,s.x)),l=Math.floor(Math.max(o.x,r.x,a.x,s.x)),c=1;for(let o=n-c;o<=l+c;o++)0!==o&&i.push(new t.b1(o,e));}return i}getCameraFrustum(){return At.fromInvProjectionMatrix(this._invViewProjMatrix,this.worldSize)}getClippingPlane(){return null}getCoveringTilesDetailsProvider(){return this._coveringTilesDetailsProvider}recalculateZoomAndCenter(e){const t=this.screenPointToLocation(this.centerPoint,e),i=e?e.getElevationForLngLatZoom(t,this._helper._tileZoom):0;this._helper.recalculateZoomAndCenter(i);}setLocationAtPoint(e,i){const o=t.ai(this.elevation,this.center.lat),r=this.screenPointToMercatorCoordinateAtZ(i,o),a=this.screenPointToMercatorCoordinateAtZ(this.centerPoint,o),s=t.a0.fromLngLat(e),n=new t.a0(s.x-(r.x-a.x),s.y-(r.y-a.y));this.setCenter(null==n?void 0:n.toLngLat()),this._helper._renderWorldCopies&&this.setCenter(this.center.wrap());}locationToScreenPoint(e,i){return i?this.coordinatePoint(t.a0.fromLngLat(e),i.getElevationForLngLatZoom(e,this._helper._tileZoom),this._pixelMatrix3D):this.coordinatePoint(t.a0.fromLngLat(e))}screenPointToLocation(e,t){var i;return null===(i=this.screenPointToMercatorCoordinate(e,t))||void 0===i?void 0:i.toLngLat()}screenPointToMercatorCoordinate(e,t){if(t){const i=t.pointCoordinate(e);if(null!=i)return i}return this.screenPointToMercatorCoordinateAtZ(e)}screenPointToMercatorCoordinateAtZ(e,i){const o=i||0,r=[e.x,e.y,0,1],a=[e.x,e.y,1,1];t.av(r,r,this._pixelMatrixInverse),t.av(a,a,this._pixelMatrixInverse);const s=r[3],n=a[3],l=r[1]/s,c=a[1]/n,h=r[2]/s,u=a[2]/n,d=h===u?0:(o-h)/(u-h);return new t.a0(t.C.number(r[0]/s,a[0]/n,d)/this.worldSize,t.C.number(l,c,d)/this.worldSize,o)}coordinatePoint(e,i=0,o=this._pixelMatrix){const r=[e.x*this.worldSize,e.y*this.worldSize,i,1];return t.av(r,r,o),new t.P(r[0]/r[3],r[1]/r[3])}getBounds(){const e=Math.max(0,this._helper._height/2-he(this));return (new G).extend(this.screenPointToLocation(new t.P(0,e))).extend(this.screenPointToLocation(new t.P(this._helper._width,e))).extend(this.screenPointToLocation(new t.P(this._helper._width,this._helper._height))).extend(this.screenPointToLocation(new t.P(0,this._helper._height)))}isPointOnMapSurface(e,t){return t?null!=t.pointCoordinate(e):e.y>this.height/2-he(this)}calculatePosMatrix(e,i=!1,o){var r;const a=null!==(r=e.key)&&void 0!==r?r:t.b2(e.wrap,e.canonical.z,e.canonical.z,e.canonical.x,e.canonical.y),s=i?this._alignedPosMatrixCache:this._posMatrixCache;if(s.has(a)){const e=s.get(a);return o?e.f32:e.f64}const n=ue(e,this.worldSize);t.O(n,i?this._alignedProjMatrix:this._viewProjMatrix,n);const l={f64:n,f32:new Float32Array(n)};return s.set(a,l),o?l.f32:l.f64}calculateFogMatrix(e){const i=e.key,o=this._fogMatrixCacheF32;if(o.has(i))return o.get(i);const r=ue(e,this.worldSize);return t.O(r,this._fogMatrix,r),o.set(i,new Float32Array(r)),o.get(i)}getConstrained(e,i){i=t.ag(+i,this.minZoom,this.maxZoom);const o={center:new t.S(e.lng,e.lat),zoom:i};let r=this._helper._lngRange;this._helper._renderWorldCopies||null!==r||(r=[-179.9999999999,180-1e-10]);const a=this.tileSize*t.ae(o.zoom);let s=0,n=a,l=0,c=a,h=0,u=0;const{x:d,y:_}=this.size;if(this._helper._latRange){const e=this._helper._latRange;s=t.U(e[1])*a,n=t.U(e[0])*a,n-s<_&&(h=_/(n-s));}r&&(l=t.aN(t.V(r[0])*a,0,a),c=t.aN(t.V(r[1])*a,0,a),c<l&&(c+=a),c-l<d&&(u=d/(c-l)));const{x:p,y:m}=le(a,e);let f,g;const v=Math.max(u||0,h||0);if(v){const e=new t.P(u?(c+l)/2:p,h?(n+s)/2:m);return o.center=ce(a,e).wrap(),o.zoom+=t.aj(v),o}if(this._helper._latRange){const e=_/2;m-e<s&&(g=s+e),m+e>n&&(g=n-e);}if(r){const e=(l+c)/2;let i=p;this._helper._renderWorldCopies&&(i=t.aN(p,e-a/2,e+a/2));const o=d/2;i-o<l&&(f=l+o),i+o>c&&(f=c-o);}if(void 0!==f||void 0!==g){const e=new t.P(null!=f?f:p,null!=g?g:m);o.center=ce(a,e).wrap();}return o}calculateCenterFromCameraLngLatAlt(e,t,i,o){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,i,o)}_calculateNearFarZIfNeeded(e,i,o){if(!this._helper.autoCalculateNearFarZ)return;const r=Math.min(this.elevation,this.minElevationForCurrentTile,this.getCameraAltitude()-100),a=e-r*this._helper._pixelPerMeter/Math.cos(i),s=r<0?a:e,n=Math.PI/2+this.pitchInRadians,l=t.ad(this.fov)*(Math.abs(Math.cos(t.ad(this.roll)))*this.height+Math.abs(Math.sin(t.ad(this.roll)))*this.width)/this.height*(.5+o.y/this.height),c=Math.sin(l)*s/Math.sin(t.ag(Math.PI-n-l,.01,Math.PI-.01)),h=he(this),u=Math.atan(h/this._helper.cameraToCenterDistance),d=t.ad(.75),_=u>d?2*u*(.5+o.y/(2*h)):d,p=Math.sin(_)*s/Math.sin(t.ag(Math.PI-n-_,.01,Math.PI-.01)),m=Math.min(c,p);this._helper._farZ=1.01*(Math.cos(Math.PI/2-i)*m+s),this._helper._nearZ=this._helper._height/50;}_calcMatrices(){if(!this._helper._height)return;const e=this.centerOffset,i=le(this.worldSize,this.center),o=i.x,r=i.y;this._helper._pixelPerMeter=t.ai(1,this.center.lat)*this.worldSize;const a=t.ad(Math.min(this.pitch,ne)),s=Math.max(this._helper.cameraToCenterDistance/2,this._helper.cameraToCenterDistance+this._helper._elevation*this._helper._pixelPerMeter/Math.cos(a));let n;this._calculateNearFarZIfNeeded(s,a,e),n=new Float64Array(16),t.b3(n,this.fovInRadians,this._helper._width/this._helper._height,this._helper._nearZ,this._helper._farZ),this._invProjMatrix=new Float64Array(16),t.ap(this._invProjMatrix,n),n[8]=2*-e.x/this._helper._width,n[9]=2*e.y/this._helper._height,this._projectionMatrix=t.b4(n),t.N(n,n,[1,-1,1]),t.M(n,n,[0,0,-this._helper.cameraToCenterDistance]),t.b5(n,n,-this.rollInRadians),t.b6(n,n,this.pitchInRadians),t.b5(n,n,-this.bearingInRadians),t.M(n,n,[-o,-r,0]),this._mercatorMatrix=t.N([],n,[this.worldSize,this.worldSize,this.worldSize]),t.N(n,n,[1,1,this._helper._pixelPerMeter]),this._pixelMatrix=t.O(new Float64Array(16),this.clipSpaceToPixelsMatrix,n),t.M(n,n,[0,0,-this.elevation]),this._viewProjMatrix=n,this._invViewProjMatrix=t.ap([],n);const l=[0,0,-1,1];t.av(l,l,this._invViewProjMatrix),this._cameraPosition=[l[0]/l[3],l[1]/l[3],l[2]/l[3]],this._fogMatrix=new Float64Array(16),t.b3(this._fogMatrix,this.fovInRadians,this.width/this.height,s,this._helper._farZ),this._fogMatrix[8]=2*-e.x/this.width,this._fogMatrix[9]=2*e.y/this.height,t.N(this._fogMatrix,this._fogMatrix,[1,-1,1]),t.M(this._fogMatrix,this._fogMatrix,[0,0,-this.cameraToCenterDistance]),t.b5(this._fogMatrix,this._fogMatrix,-this.rollInRadians),t.b6(this._fogMatrix,this._fogMatrix,this.pitchInRadians),t.b5(this._fogMatrix,this._fogMatrix,-this.bearingInRadians),t.M(this._fogMatrix,this._fogMatrix,[-o,-r,0]),t.N(this._fogMatrix,this._fogMatrix,[1,1,this._helper._pixelPerMeter]),t.M(this._fogMatrix,this._fogMatrix,[0,0,-this.elevation]),this._pixelMatrix3D=t.O(new Float64Array(16),this.clipSpaceToPixelsMatrix,n);const c=this._helper._width%2/2,h=this._helper._height%2/2,u=Math.cos(this.bearingInRadians),d=Math.sin(-this.bearingInRadians),_=o-Math.round(o)+u*c+d*h,p=r-Math.round(r)+u*h+d*c,m=new Float64Array(n);if(t.M(m,m,[_>.5?_-1:_,p>.5?p-1:p,0]),this._alignedProjMatrix=m,n=t.ap(new Float64Array(16),this._pixelMatrix),!n)throw new Error(\"failed to invert matrix\");this._pixelMatrixInverse=n,this._clearMatrixCaches();}_clearMatrixCaches(){this._posMatrixCache.clear(),this._alignedPosMatrixCache.clear(),this._fogMatrixCacheF32.clear();}maxPitchScaleFactor(){if(!this._pixelMatrixInverse)return 1;const e=this.screenPointToMercatorCoordinate(new t.P(0,0)),i=[e.x*this.worldSize,e.y*this.worldSize,0,1];return t.av(i,i,this._pixelMatrix)[3]/this._helper.cameraToCenterDistance}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){const e=t.ai(1,this.center.lat)*this.worldSize;return de(this.center,this.elevation,this.pitch,this.bearing,this._helper.cameraToCenterDistance/e).toLngLat()}lngLatToCameraDepth(e,i){const o=t.a0.fromLngLat(e),r=[o.x*this.worldSize,o.y*this.worldSize,i,1];return t.av(r,r,this._viewProjMatrix),r[2]/r[3]}getProjectionData(e){const{overscaledTileID:i,aligned:o,applyTerrainMatrix:r}=e,a=this._helper.getMercatorTileCoordinates(i),s=i?this.calculatePosMatrix(i,o,!0):null;let n;return n=i&&i.terrainRttPosMatrix32f&&r?i.terrainRttPosMatrix32f:s||t.b7(),{mainMatrix:n,tileMercatorCoords:a,clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:n}}isLocationOccluded(e){return !1}getPixelScale(){return 1}getCircleRadiusCorrection(){return 1}getPitchedTextCorrection(e,t,i){return 1}transformLightDirection(e){return t.aS(e)}getRayDirectionFromPixel(e){throw new Error(\"Not implemented.\")}projectTileCoordinates(e,i,o,r){const a=this.calculatePosMatrix(o);let s;r?(s=[e,i,r(e,i),1],t.av(s,s,a)):(s=[e,i,0,1],qe(s,s,a));const n=s[3];return {point:new t.P(s[0]/n,s[1]/n),signedDistanceFromCamera:n,isOccluded:!1}}populateCache(e){for(const t of e)this.calculatePosMatrix(t);}getMatrixForModel(e,i){const o=t.a0.fromLngLat(e,i),r=o.meterInMercatorCoordinateUnits(),a=t.b8();return t.M(a,a,[o.x,o.y,o.z]),t.b5(a,a,Math.PI),t.b6(a,a,Math.PI/2),t.N(a,a,[-r,r,r]),a}getProjectionDataForCustomLayer(e=!0){const i=new t.Z(0,0,0,0,0),o=this.getProjectionData({overscaledTileID:i,applyGlobeMatrix:e}),r=ue(i,this.worldSize);t.O(r,this._viewProjMatrix,r),o.tileMercatorCoords=[0,0,1,1];const a=[t.$,t.$,this.worldSize/this._helper.pixelsPerMeter],s=t.b9();return t.N(s,r,a),o.fallbackMatrix=s,o.mainMatrix=s,o}getFastPathSimpleProjectionMatrix(e){return this.calculatePosMatrix(e)}}function kt(){t.w(\"Map cannot fit within canvas with the given bounds, padding, and/or offset.\");}function Ft(e){if(e.useSlerp)if(e.k<1){const i=t.ba(e.startEulerAngles.roll,e.startEulerAngles.pitch,e.startEulerAngles.bearing),o=t.ba(e.endEulerAngles.roll,e.endEulerAngles.pitch,e.endEulerAngles.bearing),r=new Float64Array(4);t.bb(r,i,o,e.k);const a=t.bc(r);e.tr.setRoll(a.roll),e.tr.setPitch(a.pitch),e.tr.setBearing(a.bearing);}else e.tr.setRoll(e.endEulerAngles.roll),e.tr.setPitch(e.endEulerAngles.pitch),e.tr.setBearing(e.endEulerAngles.bearing);else e.tr.setRoll(t.C.number(e.startEulerAngles.roll,e.endEulerAngles.roll,e.k)),e.tr.setPitch(t.C.number(e.startEulerAngles.pitch,e.endEulerAngles.pitch,e.k)),e.tr.setBearing(t.C.number(e.startEulerAngles.bearing,e.endEulerAngles.bearing,e.k));}function Bt(e,i,o,r,a){const s=a.padding,n=le(a.worldSize,o.getNorthWest()),l=le(a.worldSize,o.getNorthEast()),c=le(a.worldSize,o.getSouthEast()),h=le(a.worldSize,o.getSouthWest()),u=t.ad(-r),d=n.rotate(u),_=l.rotate(u),p=c.rotate(u),m=h.rotate(u),f=new t.P(Math.max(d.x,_.x,m.x,p.x),Math.max(d.y,_.y,m.y,p.y)),g=new t.P(Math.min(d.x,_.x,m.x,p.x),Math.min(d.y,_.y,m.y,p.y)),v=f.sub(g),b=(a.width-(s.left+s.right+i.left+i.right))/v.x,x=(a.height-(s.top+s.bottom+i.top+i.bottom))/v.y;if(x<0||b<0)return void kt();const y=Math.min(t.aj(a.scale*Math.min(b,x)),e.maxZoom),w=t.P.convert(e.offset),T=new t.P((i.left-i.right)/2,(i.top-i.bottom)/2).rotate(t.ad(r)),P=w.add(T).mult(a.scale/t.ae(y));return {center:ce(a.worldSize,n.add(c).div(2).sub(P)),zoom:y,bearing:r}}class Ot{get useGlobeControls(){return !1}handlePanInertia(e,t){return {easingOffset:e,easingCenter:t.center}}handleMapControlsRollPitchBearingZoom(e,t){e.bearingDelta&&t.setBearing(t.bearing+e.bearingDelta),e.pitchDelta&&t.setPitch(t.pitch+e.pitchDelta),e.rollDelta&&t.setRoll(t.roll+e.rollDelta),e.zoomDelta&&t.setZoom(t.zoom+e.zoomDelta);}handleMapControlsPan(e,t,i){e.around.distSqr(t.centerPoint)<.01||t.setLocationAtPoint(i,e.around);}cameraForBoxAndBearing(e,t,i,o,r){return Bt(e,t,i,o,r)}handleJumpToCenterZoom(e,i){e.zoom!==(void 0!==i.zoom?+i.zoom:e.zoom)&&e.setZoom(+i.zoom),void 0!==i.center&&e.setCenter(t.S.convert(i.center));}handleEaseTo(e,i){const o=e.zoom,r=e.padding,a={roll:e.roll,pitch:e.pitch,bearing:e.bearing},s={roll:void 0===i.roll?e.roll:i.roll,pitch:void 0===i.pitch?e.pitch:i.pitch,bearing:void 0===i.bearing?e.bearing:i.bearing},n=void 0!==i.zoom,l=!e.isPaddingEqual(i.padding);let c=!1;const h=n?+i.zoom:e.zoom;let u=e.centerPoint.add(i.offsetAsPoint);const d=e.screenPointToLocation(u),{center:_,zoom:p}=e.getConstrained(t.S.convert(i.center||d),null!=h?h:o);St(e,_);const m=le(e.worldSize,d),f=le(e.worldSize,_).sub(m),g=t.ae(p-o);return c=p!==o,{easeFunc:n=>{if(c&&e.setZoom(t.C.number(o,p,n)),t.bd(a,s)||Ft({startEulerAngles:a,endEulerAngles:s,tr:e,k:n,useSlerp:a.roll!=s.roll}),l&&(e.interpolatePadding(r,i.padding,n),u=e.centerPoint.add(i.offsetAsPoint)),i.around)e.setLocationAtPoint(i.around,i.aroundPoint);else {const i=t.ae(e.zoom-o),r=p>o?Math.min(2,g):Math.max(.5,g),a=Math.pow(r,1-n),s=ce(e.worldSize,m.add(f.mult(n*a)).mult(i));e.setLocationAtPoint(e.renderWorldCopies?s.wrap():s,u);}},isZooming:c,elevationCenter:_}}handleFlyTo(e,i){const o=void 0!==i.zoom,r=e.zoom,a=e.getConstrained(t.S.convert(i.center||i.locationAtOffset),o?+i.zoom:r),s=a.center,n=a.zoom;St(e,s);const l=le(e.worldSize,i.locationAtOffset),c=le(e.worldSize,s).sub(l),h=c.mag(),u=t.ae(n-r);let d;if(void 0!==i.minZoom){const o=Math.min(+i.minZoom,r,n),a=e.getConstrained(s,o).zoom;d=t.ae(a-r);}return {easeFunc:(i,o,a,h)=>{e.setZoom(1===i?n:r+t.aj(o));const u=1===i?s:ce(e.worldSize,l.add(c.mult(a)).mult(o));e.setLocationAtPoint(e.renderWorldCopies?u.wrap():u,h);},scaleOfZoom:u,targetCenter:s,scaleOfMinZoom:d,pixelPathLength:h}}}class jt{constructor(e,t,i){this.blendFunction=e,this.blendColor=t,this.mask=i;}}jt.Replace=[1,0],jt.disabled=new jt(jt.Replace,t.be.transparent,[!1,!1,!1,!1]),jt.unblended=new jt(jt.Replace,t.be.transparent,[!0,!0,!0,!0]),jt.alphaBlended=new jt([1,771],t.be.transparent,[!0,!0,!0,!0]);const Nt=2305;class Zt{constructor(e,t,i){this.enable=e,this.mode=t,this.frontFace=i;}}Zt.disabled=new Zt(!1,1029,Nt),Zt.backCCW=new Zt(!0,1029,Nt),Zt.frontCCW=new Zt(!0,1028,Nt);class Ut{constructor(e,t,i){this.func=e,this.mask=t,this.range=i;}}Ut.ReadOnly=!1,Ut.ReadWrite=!0,Ut.disabled=new Ut(519,Ut.ReadOnly,[0,1]);const Gt=7680;class Vt{constructor(e,t,i,o,r,a){this.test=e,this.ref=t,this.mask=i,this.fail=o,this.depthFail=r,this.pass=a;}}Vt.disabled=new Vt({func:519,mask:0},0,0,Gt,Gt,Gt);const $t=new WeakMap;function qt(e){var t;if($t.has(e))return $t.get(e);{const i=null===(t=e.getParameter(e.VERSION))||void 0===t?void 0:t.startsWith(\"WebGL 2.0\");return $t.set(e,i),i}}class Wt{get awaitingQuery(){return !!this._readbackQueue}constructor(e){this._readbackWaitFrames=4,this._measureWaitFrames=6,this._texWidth=1,this._texHeight=1,this._measuredError=0,this._updateCount=0,this._lastReadbackFrame=-1e3,this._readbackQueue=null,this._cachedRenderContext=e;const i=e.context,o=i.gl;this._texFormat=o.RGBA,this._texType=o.UNSIGNED_BYTE;const r=new t.aK;r.emplaceBack(-1,-1),r.emplaceBack(2,-1),r.emplaceBack(-1,2);const a=new t.aM;a.emplaceBack(0,1,2),this._fullscreenTriangle=new wt(i.createVertexBuffer(r,Tt.members),i.createIndexBuffer(a),t.aL.simpleSegment(0,0,r.length,a.length)),this._resultBuffer=new Uint8Array(4),i.activeTexture.set(o.TEXTURE1);const s=o.createTexture();o.bindTexture(o.TEXTURE_2D,s),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_S,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_WRAP_T,o.CLAMP_TO_EDGE),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MIN_FILTER,o.NEAREST),o.texParameteri(o.TEXTURE_2D,o.TEXTURE_MAG_FILTER,o.NEAREST),o.texImage2D(o.TEXTURE_2D,0,this._texFormat,this._texWidth,this._texHeight,0,this._texFormat,this._texType,null),this._fbo=i.createFramebuffer(this._texWidth,this._texHeight,!1,!1),this._fbo.colorAttachment.set(s),qt(o)&&(this._pbo=o.createBuffer(),o.bindBuffer(o.PIXEL_PACK_BUFFER,this._pbo),o.bufferData(o.PIXEL_PACK_BUFFER,4,o.STREAM_READ),o.bindBuffer(o.PIXEL_PACK_BUFFER,null));}destroy(){const e=this._cachedRenderContext.context.gl;this._fullscreenTriangle.destroy(),this._fbo.destroy(),e.deleteBuffer(this._pbo),this._fullscreenTriangle=null,this._fbo=null,this._pbo=null,this._resultBuffer=null;}updateErrorLoop(e,t){const i=this._updateCount;return this._readbackQueue?i>=this._readbackQueue.frameNumberIssued+this._readbackWaitFrames&&this._tryReadback():i>=this._lastReadbackFrame+this._measureWaitFrames&&this._renderErrorTexture(e,t),this._updateCount++,this._measuredError}_bindFramebuffer(){const e=this._cachedRenderContext.context,t=e.gl;e.activeTexture.set(t.TEXTURE1),t.bindTexture(t.TEXTURE_2D,this._fbo.colorAttachment.get()),e.bindFramebuffer.set(this._fbo.framebuffer);}_renderErrorTexture(e,i){const o=this._cachedRenderContext.context,r=o.gl;if(this._bindFramebuffer(),o.viewport.set([0,0,this._texWidth,this._texHeight]),o.clear({color:t.be.transparent}),this._cachedRenderContext.useProgram(\"projectionErrorMeasurement\").draw(o,r.TRIANGLES,Ut.disabled,Vt.disabled,jt.unblended,Zt.disabled,((e,t)=>({u_input:e,u_output_expected:t}))(e,i),null,null,\"$clipping\",this._fullscreenTriangle.vertexBuffer,this._fullscreenTriangle.indexBuffer,this._fullscreenTriangle.segments),this._pbo&&qt(r)){r.bindBuffer(r.PIXEL_PACK_BUFFER,this._pbo),r.readBuffer(r.COLOR_ATTACHMENT0),r.readPixels(0,0,this._texWidth,this._texHeight,this._texFormat,this._texType,0),r.bindBuffer(r.PIXEL_PACK_BUFFER,null);const e=r.fenceSync(r.SYNC_GPU_COMMANDS_COMPLETE,0);r.flush(),this._readbackQueue={frameNumberIssued:this._updateCount,sync:e};}else this._readbackQueue={frameNumberIssued:this._updateCount,sync:null};}_tryReadback(){const e=this._cachedRenderContext.context.gl;if(this._pbo&&this._readbackQueue&&qt(e)){const i=e.clientWaitSync(this._readbackQueue.sync,0,0);if(i===e.WAIT_FAILED)return t.w(\"WebGL2 clientWaitSync failed.\"),this._readbackQueue=null,void(this._lastReadbackFrame=this._updateCount);if(i===e.TIMEOUT_EXPIRED)return;e.bindBuffer(e.PIXEL_PACK_BUFFER,this._pbo),e.getBufferSubData(e.PIXEL_PACK_BUFFER,0,this._resultBuffer,0,4),e.bindBuffer(e.PIXEL_PACK_BUFFER,null);}else this._bindFramebuffer(),e.readPixels(0,0,this._texWidth,this._texHeight,this._texFormat,this._texType,this._resultBuffer);this._readbackQueue=null,this._measuredError=Wt._parseRGBA8float(this._resultBuffer),this._lastReadbackFrame=this._updateCount;}static _parseRGBA8float(e){let t=0;return t+=e[0]/256,t+=e[1]/65536,t+=e[2]/16777216,e[3]<127&&(t=-t),t/128}}const Ht=t.$/128;function Xt(e,i){const o=void 0!==e.granularity?Math.max(e.granularity,1):1,r=o+(e.generateBorders?2:0),a=o+(e.extendToNorthPole||e.generateBorders?1:0)+(e.extendToSouthPole||e.generateBorders?1:0),s=r+1,n=a+1,l=e.generateBorders?-1:0,c=e.generateBorders||e.extendToNorthPole?-1:0,h=o+(e.generateBorders?1:0),u=o+(e.generateBorders||e.extendToSouthPole?1:0),d=s*n,_=r*a*6,p=s*n>65536;if(p&&\"16bit\"===i)throw new Error(\"Granularity is too large and meshes would not fit inside 16 bit vertex indices.\");const m=p||\"32bit\"===i,f=new Int16Array(2*d);let g=0;for(let i=c;i<=u;i++)for(let r=l;r<=h;r++){let a=r/o*t.$;-1===r&&(a=-64),r===o+1&&(a=t.$+Ht);let s=i/o*t.$;-1===i&&(s=e.extendToNorthPole?t.bg:-64),i===o+1&&(s=e.extendToSouthPole?t.bh:t.$+Ht),f[g++]=a,f[g++]=s;}const v=m?new Uint32Array(_):new Uint16Array(_);let b=0;for(let e=0;e<a;e++)for(let t=0;t<r;t++){const i=t+1+e*s,o=t+(e+1)*s,r=t+1+(e+1)*s;v[b++]=t+e*s,v[b++]=o,v[b++]=i,v[b++]=i,v[b++]=o,v[b++]=r;}return {vertices:f.buffer.slice(0),indices:v.buffer.slice(0),uses32bitIndices:m}}const Kt=new t.aJ({fill:new t.bi(128,2),line:new t.bi(512,0),tile:new t.bi(128,32),stencil:new t.bi(128,1),circle:3});class Yt{constructor(){this._tileMeshCache={},this._errorCorrectionUsable=0,this._errorMeasurementLastValue=0,this._errorCorrectionPreviousValue=0,this._errorMeasurementLastChangeTime=-1e3;}get name(){return \"vertical-perspective\"}get transitionState(){return 1}get useSubdivision(){return !0}get shaderVariantName(){return \"globe\"}get shaderDefine(){return \"#define GLOBE\"}get shaderPreludeCode(){return xt.projectionGlobe}get vertexShaderPreludeCode(){return xt.projectionMercator.vertexSource}get subdivisionGranularity(){return Kt}get useGlobeControls(){return !0}get latitudeErrorCorrectionRadians(){return this._errorCorrectionUsable}destroy(){this._errorMeasurement&&this._errorMeasurement.destroy();}updateGPUdependent(e){this._errorMeasurement||(this._errorMeasurement=new Wt(e));const i=t.U(this._errorQueryLatitudeDegrees),o=2*Math.atan(Math.exp(Math.PI-i*Math.PI*2))-.5*Math.PI,r=this._errorMeasurement.updateErrorLoop(i,o),a=s.now();r!==this._errorMeasurementLastValue&&(this._errorCorrectionPreviousValue=this._errorCorrectionUsable,this._errorMeasurementLastValue=r,this._errorMeasurementLastChangeTime=a);const n=Math.min(Math.max((a-this._errorMeasurementLastChangeTime)/1e3/.5,0),1);this._errorCorrectionUsable=t.bj(this._errorCorrectionPreviousValue,-this._errorMeasurementLastValue,t.bk(n));}_getMeshKey(e){return `${e.granularity.toString(36)}_${e.generateBorders?\"b\":\"\"}${e.extendToNorthPole?\"n\":\"\"}${e.extendToSouthPole?\"s\":\"\"}`}getMeshFromTileID(e,t,i,o,r){const a=(\"stencil\"===r?Kt.stencil:Kt.tile).getGranularityForZoomLevel(t.z);return this._getMesh(e,{granularity:a,generateBorders:i,extendToNorthPole:0===t.y&&o,extendToSouthPole:t.y===(1<<t.z)-1&&o})}_getMesh(e,i){const o=this._getMeshKey(i);if(o in this._tileMeshCache)return this._tileMeshCache[o];const r=function(e,i){const o=Xt(i,\"16bit\"),r=t.aK.deserialize({arrayBuffer:o.vertices,length:o.vertices.byteLength/2/2}),a=t.aM.deserialize({arrayBuffer:o.indices,length:o.indices.byteLength/2/3});return new wt(e.createVertexBuffer(r,Tt.members),e.createIndexBuffer(a),t.aL.simpleSegment(0,0,r.length,a.length))}(e,i);return this._tileMeshCache[o]=r,r}recalculate(e){}hasTransition(){const e=s.now();let t=!1;return t=t||(e-this._errorMeasurementLastChangeTime)/1e3<.7,t=t||this._errorMeasurement&&this._errorMeasurement.awaitingQuery,t}setErrorQueryLatitudeDegrees(e){this._errorQueryLatitudeDegrees=e;}}const Qt=new t.r({type:new t.D(t.v.projection.type)});class Jt extends t.E{constructor(e){super(),this._transitionable=new t.t(Qt),this.setProjection(e),this._transitioning=this._transitionable.untransitioned(),this.recalculate(new t.F(0)),this._mercatorProjection=new It,this._verticalPerspectiveProjection=new Yt;}get transitionState(){const e=this.properties.get(\"type\");if(\"string\"==typeof e&&\"mercator\"===e)return 0;if(\"string\"==typeof e&&\"vertical-perspective\"===e)return 1;if(e instanceof t.bl){if(\"vertical-perspective\"===e.from&&\"mercator\"===e.to)return 1-e.transition;if(\"mercator\"===e.from&&\"vertical-perspective\"===e.to)return e.transition}return 1}get useGlobeRendering(){return this.transitionState>0}get latitudeErrorCorrectionRadians(){return this._verticalPerspectiveProjection.latitudeErrorCorrectionRadians}get currentProjection(){return this.useGlobeRendering?this._verticalPerspectiveProjection:this._mercatorProjection}get name(){return \"globe\"}get useSubdivision(){return this.currentProjection.useSubdivision}get shaderVariantName(){return this.currentProjection.shaderVariantName}get shaderDefine(){return this.currentProjection.shaderDefine}get shaderPreludeCode(){return this.currentProjection.shaderPreludeCode}get vertexShaderPreludeCode(){return this.currentProjection.vertexShaderPreludeCode}get subdivisionGranularity(){return this.currentProjection.subdivisionGranularity}get useGlobeControls(){return this.transitionState>0}destroy(){this._mercatorProjection.destroy(),this._verticalPerspectiveProjection.destroy();}updateGPUdependent(e){this._mercatorProjection.updateGPUdependent(e),this._verticalPerspectiveProjection.updateGPUdependent(e);}getMeshFromTileID(e,t,i,o,r){return this.currentProjection.getMeshFromTileID(e,t,i,o,r)}setProjection(e){this._transitionable.setValue(\"type\",(null==e?void 0:e.type)||\"mercator\");}updateTransitions(e){this._transitioning=this._transitionable.transitioned(e,this._transitioning);}hasTransition(){return this._transitioning.hasTransition()||this.currentProjection.hasTransition()}recalculate(e){this.properties=this._transitioning.possiblyEvaluate(e);}setErrorQueryLatitudeDegrees(e){this._verticalPerspectiveProjection.setErrorQueryLatitudeDegrees(e),this._mercatorProjection.setErrorQueryLatitudeDegrees(e);}}function ei(e){const t=oi(e.worldSize,e.center.lat);return 2*Math.PI*t}function ti(e,i,o,r,a){const s=1/(1<<a),n=i/t.$*s+r*s,l=t.bn((e/t.$*s+o*s)*Math.PI*2+Math.PI,2*Math.PI),c=2*Math.atan(Math.exp(Math.PI-n*Math.PI*2))-.5*Math.PI,h=Math.cos(c),u=new Float64Array(3);return u[0]=Math.sin(l)*h,u[1]=Math.sin(c),u[2]=Math.cos(l)*h,u}function ii(e){return function(e,t){const i=Math.cos(t),o=new Float64Array(3);return o[0]=Math.sin(e)*i,o[1]=Math.sin(t),o[2]=Math.cos(e)*i,o}(e.lng*Math.PI/180,e.lat*Math.PI/180)}function oi(e,t){return e/(2*Math.PI)/Math.cos(t*Math.PI/180)}function ri(e){const i=Math.asin(e[1])/Math.PI*180,o=Math.sqrt(e[0]*e[0]+e[2]*e[2]);if(o>1e-6){const r=e[0]/o,a=Math.acos(e[2]/o),s=(r>0?a:-a)/Math.PI*180;return new t.S(t.aN(s,-180,180),i)}return new t.S(0,i)}function ai(e){return Math.cos(e*Math.PI/180)}function si(e,i){const o=ai(e),r=ai(i);return t.aj(r/o)}function ni(e,i){const o=e.rotate(i.bearingInRadians),r=i.zoom+si(i.center.lat,0),a=t.bj(1/ai(i.center.lat),1/ai(Math.min(Math.abs(i.center.lat),60)),t.bm(r,7,3,0,1)),s=360/ei({worldSize:i.worldSize,center:{lat:i.center.lat}});return new t.S(i.center.lng-o.x*s*a,t.ag(i.center.lat+o.y*s,-85.051129,t.ah))}function li(e){const t=.5*e,i=Math.sin(t),o=Math.cos(t);return Math.log(i+o)-Math.log(o-i)}function ci(e,i,o,r){const a=e.lat+o*r;if(Math.abs(o)>1){const s=(Math.sign(e.lat+o)!==Math.sign(e.lat)?-Math.abs(e.lat):Math.abs(e.lat))*Math.PI/180,n=Math.abs(e.lat+o)*Math.PI/180,l=li(s+r*(n-s)),c=li(s),h=li(n);return new t.S(e.lng+i*((l-c)/(h-c)),a)}return new t.S(e.lng+i*r,a)}class hi{constructor(e){this._cachePrevious=new Map,this._cache=new Map,this._hadAnyChanges=!1,this._boundingVolumeFactory=e;}swapBuffers(){if(!this._hadAnyChanges)return;const e=this._cachePrevious;this._cachePrevious=this._cache,this._cache=e,this._cache.clear(),this._hadAnyChanges=!1;}getTileBoundingVolume(e,t,i,o){const r=`${e.z}_${e.x}_${e.y}_${(null==o?void 0:o.terrain)?\"t\":\"\"}`,a=this._cache.get(r);if(a)return a;const s=this._cachePrevious.get(r);if(s)return this._cache.set(r,s),s;const n=this._boundingVolumeFactory(e,t,i,o);return this._cache.set(r,n),this._hadAnyChanges=!0,n}}class ui{constructor(e,t,i,o){this.min=i,this.max=o,this.points=e,this.planes=t;}static fromAabb(e,t){const i=[];for(let o=0;o<8;o++)i.push([1&~o?e[0]:t[0],1==(o>>1&1)?t[1]:e[1],1==(o>>2&1)?t[2]:e[2]]);return new ui(i,[[-1,0,0,t[0]],[1,0,0,-e[0]],[0,-1,0,t[1]],[0,1,0,-e[1]],[0,0,-1,t[2]],[0,0,1,-e[2]]],e,t)}static fromCenterSizeAngles(e,i,o){const r=t.bq([],o[0],o[1],o[2]),a=t.br([],[i[0],0,0],r),s=t.br([],[0,i[1],0],r),n=t.br([],[0,0,i[2]],r),l=[...e],c=[...e];for(let t=0;t<8;t++)for(let i=0;i<3;i++){const o=e[i]+a[i]*(1&~t?-1:1)+s[i]*(1==(t>>1&1)?1:-1)+n[i]*(1==(t>>2&1)?1:-1);l[i]=Math.min(l[i],o),c[i]=Math.max(c[i],o);}const h=[];for(let i=0;i<8;i++){const o=[...e];t.aR(o,o,t.aQ([],a,1&~i?-1:1)),t.aR(o,o,t.aQ([],s,1==(i>>1&1)?1:-1)),t.aR(o,o,t.aQ([],n,1==(i>>2&1)?1:-1)),h.push(o);}return new ui(h,[[...a,-t.aW(a,h[0])],[...s,-t.aW(s,h[0])],[...n,-t.aW(n,h[0])],[-a[0],-a[1],-a[2],-t.aW(a,h[7])],[-s[0],-s[1],-s[2],-t.aW(s,h[7])],[-n[0],-n[1],-n[2],-t.aW(n,h[7])]],l,c)}intersectsFrustum(e){let t=!0;const i=this.points.length,o=this.planes.length,r=e.planes.length,a=e.points.length;for(let o=0;o<r;o++){const r=e.planes[o];let a=0;for(let e=0;e<i;e++){const t=this.points[e];r[0]*t[0]+r[1]*t[1]+r[2]*t[2]+r[3]>=0&&a++;}if(0===a)return 0;a<i&&(t=!1);}if(t)return 2;for(let t=0;t<o;t++){const i=this.planes[t];let o=0;for(let t=0;t<a;t++){const r=e.points[t];i[0]*r[0]+i[1]*r[1]+i[2]*r[2]+i[3]>=0&&o++;}if(0===o)return 0}return 1}intersectsPlane(e){const t=this.points.length;let i=0;for(let o=0;o<t;o++){const t=this.points[o];e[0]*t[0]+e[1]*t[1]+e[2]*t[2]+e[3]>=0&&i++;}return i===t?2:0===i?0:1}}function di(e,t,i){const o=e-t;return o<0?-o:Math.max(0,o-i)}function _i(e,t,i,o,r){const a=e-i;let s;return s=a<0?Math.min(-a,1+a-r):a>1?Math.min(Math.max(a-r,0),1-a):0,Math.max(s,di(t,o,r))}class pi{constructor(){this._boundingVolumeCache=new hi(this._computeTileBoundingVolume);}prepareNextFrame(){this._boundingVolumeCache.swapBuffers();}distanceToTile2d(e,t,i,o){const r=1<<i.z,a=1/r,s=i.x/r,n=i.y/r;let l=2;return l=Math.min(l,_i(e,t,s,n,a)),l=Math.min(l,_i(e,t,s+.5,-n-a,a)),l=Math.min(l,_i(e,t,s+.5,2-n-a,a)),l}getWrap(e,t,i){const o=1<<t.z,r=1/o,a=t.x/o,s=di(e.x,a,r),n=di(e.x,a-1,r),l=di(e.x,a+1,r),c=Math.min(s,n,l);return c===l?1:c===n?-1:0}allowVariableZoom(e,t){return ge(e,t)>4}allowWorldCopies(){return !1}getTileBoundingVolume(e,t,i,o){return this._boundingVolumeCache.getTileBoundingVolume(e,t,i,o)}_computeTileBoundingVolume(e,i,o,r){var a,s;let n=o,l=o;if(null==r?void 0:r.terrain){const c=new t.Z(e.z,i,e.z,e.x,e.y),h=r.terrain.getMinMaxElevation(c);n=null!==(a=h.minElevation)&&void 0!==a?a:o,l=null!==(s=h.maxElevation)&&void 0!==s?s:o;}if(n/=t.bt,l/=t.bt,n+=1,l+=1,e.z<=0)return ui.fromAabb([-l,-l,-l],[l,l,l]);if(1===e.z)return ui.fromAabb([0===e.x?-l:0,0===e.y?0:-l,-l],[0===e.x?0:l,0===e.y?l:0,l]);{const i=[ti(0,0,e.x,e.y,e.z),ti(t.$,0,e.x,e.y,e.z),ti(t.$,t.$,e.x,e.y,e.z),ti(0,t.$,e.x,e.y,e.z)],o=[];for(const e of i)o.push(t.aQ([],e,l));if(l!==n)for(const e of i)o.push(t.aQ([],e,n));0===e.y&&o.push([0,1,0]),e.y===(1<<e.z)-1&&o.push([0,-1,0]);const r=[1,1,1],a=[-1,-1,-1];for(const e of o)for(let t=0;t<3;t++)r[t]=Math.min(r[t],e[t]),a[t]=Math.max(a[t],e[t]);const s=ti(t.$/2,t.$/2,e.x,e.y,e.z),c=t.aV([],[0,1,0],s);t.aU(c,c);const h=t.aV([],s,c);t.aU(h,h);const u=t.aV([],i[2],i[1]);t.aU(u,u);const d=t.aV([],i[0],i[3]);t.aU(d,d),o.push(t.aQ([],s,l)),e.y>=(1<<e.z)/2&&o.push(t.aQ([],ti(t.$/2,0,e.x,e.y,e.z),l)),e.y<(1<<e.z)/2&&o.push(t.aQ([],ti(t.$/2,t.$,e.x,e.y,e.z),l));const _=mi(s,o),p=mi(h,o),m=[-s[0],-s[1],-s[2],_.max],f=[s[0],s[1],s[2],-_.min],g=[-h[0],-h[1],-h[2],p.max],v=[h[0],h[1],h[2],-p.min],b=[...u,0],x=[...d,0],y=[];return 0===e.y?y.push(t.bs(x,b,m),t.bs(x,b,f)):y.push(t.bs(g,b,m),t.bs(g,b,f),t.bs(g,x,m),t.bs(g,x,f)),e.y===(1<<e.z)-1?y.push(t.bs(x,b,m),t.bs(x,b,f)):y.push(t.bs(v,b,m),t.bs(v,b,f),t.bs(v,x,m),t.bs(v,x,f)),new ui(y,[m,f,g,v,b,x],r,a)}}}function mi(e,i){let o=1/0,r=-1/0;for(const a of i){const i=t.aW(e,a);o=Math.min(o,i),r=Math.max(r,i);}return {min:o,max:r}}class fi{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(e){this._helper.setMinZoom(e);}setMaxZoom(e){this._helper.setMaxZoom(e);}setMinPitch(e){this._helper.setMinPitch(e);}setMaxPitch(e){this._helper.setMaxPitch(e);}setRenderWorldCopies(e){this._helper.setRenderWorldCopies(e);}setBearing(e){this._helper.setBearing(e);}setPitch(e){this._helper.setPitch(e);}setRoll(e){this._helper.setRoll(e);}setFov(e){this._helper.setFov(e);}setZoom(e){this._helper.setZoom(e);}setCenter(e){this._helper.setCenter(e);}setElevation(e){this._helper.setElevation(e);}setMinElevationForCurrentTile(e){this._helper.setMinElevationForCurrentTile(e);}setPadding(e){this._helper.setPadding(e);}interpolatePadding(e,t,i){return this._helper.interpolatePadding(e,t,i)}isPaddingEqual(e){return this._helper.isPaddingEqual(e)}resize(e,t){this._helper.resize(e,t);}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(e){this._helper.setMaxBounds(e);}overrideNearFarZ(e,t){this._helper.overrideNearFarZ(e,t);}clearNearFarZOverride(){this._helper.clearNearFarZOverride();}getCameraQueryGeometry(e){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),e)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}setTransitionState(e){}constructor(){this._cachedClippingPlane=t.bu(),this._projectionMatrix=t.b8(),this._globeViewProjMatrix32f=t.b7(),this._globeViewProjMatrixNoCorrection=t.b8(),this._globeViewProjMatrixNoCorrectionInverted=t.b8(),this._globeProjMatrixInverted=t.b8(),this._cameraPosition=t.bo(),this._globeLatitudeErrorCorrectionRadians=0,this._helper=new Rt({calcMatrices:()=>{this._calcMatrices();},getConstrained:(e,t)=>this.getConstrained(e,t)}),this._coveringTilesDetailsProvider=new pi;}clone(){const e=new fi;return e.apply(this),e}apply(e,t){this._globeLatitudeErrorCorrectionRadians=t||0,this._helper.apply(e);}get projectionMatrix(){return this._projectionMatrix}get modelViewProjectionMatrix(){return this._globeViewProjMatrixNoCorrection}get inverseProjectionMatrix(){return this._globeProjMatrixInverted}get cameraPosition(){const e=t.bo();return e[0]=this._cameraPosition[0],e[1]=this._cameraPosition[1],e[2]=this._cameraPosition[2],e}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}getProjectionData(e){const{overscaledTileID:t,applyGlobeMatrix:i}=e,o=this._helper.getMercatorTileCoordinates(t);return {mainMatrix:this._globeViewProjMatrix32f,tileMercatorCoords:o,clippingPlane:this._cachedClippingPlane,projectionTransition:i?1:0,fallbackMatrix:this._globeViewProjMatrix32f}}_computeClippingPlane(e){const i=this.pitchInRadians,o=this.cameraToCenterDistance/e,r=Math.sin(i)*o,a=Math.cos(i)*o+1,s=1/Math.sqrt(r*r+a*a)*1;let n=-r,l=a;const c=Math.sqrt(n*n+l*l);n/=c,l/=c;const h=[0,n,l];t.bv(h,h,[0,0,0],-this.bearingInRadians),t.bw(h,h,[0,0,0],-1*this.center.lat*Math.PI/180),t.bx(h,h,[0,0,0],this.center.lng*Math.PI/180);const u=1/t.aY(h);return t.aQ(h,h,u),[...h,-s*u]}isLocationOccluded(e){return !this.isSurfacePointVisible(ii(e))}transformLightDirection(e){const i=this._helper._center.lng*Math.PI/180,o=this._helper._center.lat*Math.PI/180,r=Math.cos(o),a=[Math.sin(i)*r,Math.sin(o),Math.cos(i)*r],s=[a[2],0,-a[0]],n=[0,0,0];t.aV(n,s,a),t.aU(s,s),t.aU(n,n);const l=[0,0,0];return t.aU(l,[s[0]*e[0]+n[0]*e[1]+a[0]*e[2],s[1]*e[0]+n[1]*e[1]+a[1]*e[2],s[2]*e[0]+n[2]*e[1]+a[2]*e[2]]),l}getPixelScale(){return 1/Math.cos(this._helper._center.lat*Math.PI/180)}getCircleRadiusCorrection(){return Math.cos(this._helper._center.lat*Math.PI/180)}getPitchedTextCorrection(e,i,o){const r=function(e,i,o){const r=1/(1<<o.z);return new t.a0(e/t.$*r+o.x*r,i/t.$*r+o.y*r)}(e,i,o.canonical),a=(s=r.y,[t.bn(r.x*Math.PI*2+Math.PI,2*Math.PI),2*Math.atan(Math.exp(Math.PI-s*Math.PI*2))-.5*Math.PI]);var s;return this.getCircleRadiusCorrection()/Math.cos(a[1])}projectTileCoordinates(e,i,o,r){const a=o.canonical,s=ti(e,i,a.x,a.y,a.z),n=1+(r?r(e,i):0)/t.bt,l=[s[0]*n,s[1]*n,s[2]*n,1];t.av(l,l,this._globeViewProjMatrixNoCorrection);const c=this._cachedClippingPlane,h=c[0]*s[0]+c[1]*s[1]+c[2]*s[2]+c[3]<0;return {point:new t.P(l[0]/l[3],l[1]/l[3]),signedDistanceFromCamera:l[3],isOccluded:h}}_calcMatrices(){if(!this._helper._width||!this._helper._height)return;const e=oi(this.worldSize,this.center.lat),i=t.b9(),o=t.b9();this._helper.autoCalculateNearFarZ&&(this._helper._nearZ=.5,this._helper._farZ=this.cameraToCenterDistance+2*e),t.b3(i,this.fovInRadians,this.width/this.height,this._helper._nearZ,this._helper._farZ);const r=this.centerOffset;i[8]=2*-r.x/this._helper._width,i[9]=2*r.y/this._helper._height,this._projectionMatrix=t.b4(i),this._globeProjMatrixInverted=t.b9(),t.ap(this._globeProjMatrixInverted,i),t.M(i,i,[0,0,-this.cameraToCenterDistance]),t.b5(i,i,this.rollInRadians),t.b6(i,i,-this.pitchInRadians),t.b5(i,i,this.bearingInRadians),t.M(i,i,[0,0,-e]);const a=t.bo();a[0]=e,a[1]=e,a[2]=e,t.b6(o,i,this.center.lat*Math.PI/180),t.by(o,o,-this.center.lng*Math.PI/180),t.N(o,o,a),this._globeViewProjMatrixNoCorrection=o,t.b6(i,i,this.center.lat*Math.PI/180-this._globeLatitudeErrorCorrectionRadians),t.by(i,i,-this.center.lng*Math.PI/180),t.N(i,i,a),this._globeViewProjMatrix32f=new Float32Array(i),this._globeViewProjMatrixNoCorrectionInverted=t.b9(),t.ap(this._globeViewProjMatrixNoCorrectionInverted,o);const s=t.bo();this._cameraPosition=t.bo(),this._cameraPosition[2]=this.cameraToCenterDistance/e,t.bv(this._cameraPosition,this._cameraPosition,s,-this.rollInRadians),t.bw(this._cameraPosition,this._cameraPosition,s,this.pitchInRadians),t.bv(this._cameraPosition,this._cameraPosition,s,-this.bearingInRadians),t.aR(this._cameraPosition,this._cameraPosition,[0,0,1]),t.bw(this._cameraPosition,this._cameraPosition,s,-this.center.lat*Math.PI/180),t.bx(this._cameraPosition,this._cameraPosition,s,this.center.lng*Math.PI/180),this._cachedClippingPlane=this._computeClippingPlane(e);const n=t.b4(this._globeViewProjMatrixNoCorrectionInverted);t.N(n,n,[1,1,-1]),this._cachedFrustum=At.fromInvProjectionMatrix(n,1,0,this._cachedClippingPlane,!0);}calculateFogMatrix(e){t.w(\"calculateFogMatrix is not supported on globe projection.\");const i=t.b9();return t.af(i),i}getVisibleUnwrappedCoordinates(e){return [new t.b1(0,e)]}getCameraFrustum(){return this._cachedFrustum}getClippingPlane(){return this._cachedClippingPlane}getCoveringTilesDetailsProvider(){return this._coveringTilesDetailsProvider}recalculateZoomAndCenter(e){e&&t.w(\"terrain is not fully supported on vertical perspective projection.\"),this._helper.recalculateZoomAndCenter(0);}maxPitchScaleFactor(){return 1}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){return this._helper.getCameraLngLat()}lngLatToCameraDepth(e,i){if(!this._globeViewProjMatrixNoCorrection)return 1;const o=ii(e);t.aQ(o,o,1+i/t.bt);const r=t.bu();return t.av(r,[o[0],o[1],o[2],1],this._globeViewProjMatrixNoCorrection),r[2]/r[3]}populateCache(e){}getBounds(){const e=.5*this.width,i=.5*this.height,o=[new t.P(0,0),new t.P(e,0),new t.P(this.width,0),new t.P(this.width,i),new t.P(this.width,this.height),new t.P(e,this.height),new t.P(0,this.height),new t.P(0,i)],r=[];for(const e of o)r.push(this.unprojectScreenPoint(e));let a=0,s=0,n=0,l=0;const c=this.center;for(const e of r){const i=t.bz(c.lng,e.lng),o=t.bz(c.lat,e.lat);i<s&&(s=i),i>a&&(a=i),o<l&&(l=o),o>n&&(n=o);}const h=[c.lng+s,c.lat+l,c.lng+a,c.lat+n];return this.isSurfacePointOnScreen([0,1,0])&&(h[3]=90,h[0]=-180,h[2]=180),this.isSurfacePointOnScreen([0,-1,0])&&(h[1]=-90,h[0]=-180,h[2]=180),new G(h)}getConstrained(e,i){const o=t.ag(e.lat,-85.051129,t.ah),r=t.ag(+i,this.minZoom+si(0,o),this.maxZoom);return {center:new t.S(e.lng,o),zoom:r}}calculateCenterFromCameraLngLatAlt(e,t,i,o){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,i,o)}setLocationAtPoint(e,i){const o=ii(this.unprojectScreenPoint(i)),r=ii(e),a=t.bo();t.bA(a);const s=t.bo();t.bx(s,o,a,-this.center.lng*Math.PI/180),t.bw(s,s,a,this.center.lat*Math.PI/180);const n=r[0]*r[0]+r[2]*r[2],l=s[0]*s[0];if(n<l)return;const c=Math.sqrt(n-l),h=-c,u=t.bB(r[0],r[2],s[0],c),d=t.bB(r[0],r[2],s[0],h),_=t.bo();t.bx(_,r,a,-u);const p=t.bB(_[1],_[2],s[1],s[2]),m=t.bo();t.bx(m,r,a,-d);const f=t.bB(m[1],m[2],s[1],s[2]),g=.5*Math.PI,v=p>=-g&&p<=g,b=f>=-g&&f<=g;let x,y;if(v&&b){const e=this.center.lng*Math.PI/180,i=this.center.lat*Math.PI/180;t.bC(u,e)+t.bC(p,i)<t.bC(d,e)+t.bC(f,i)?(x=u,y=p):(x=d,y=f);}else if(v)x=u,y=p;else {if(!b)return;x=d,y=f;}const w=x/Math.PI*180,T=y/Math.PI*180,P=this.center.lat;this.setCenter(new t.S(w,t.ag(T,-90,90))),this.setZoom(this.zoom+si(P,this.center.lat));}locationToScreenPoint(e,i){const o=ii(e);if(i){const r=i.getElevationForLngLatZoom(e,this._helper._tileZoom);t.aQ(o,o,1+r/t.bt);}return this._projectSurfacePointToScreen(o)}_projectSurfacePointToScreen(e){const i=t.bu();return t.av(i,[...e,1],this._globeViewProjMatrixNoCorrection),i[0]/=i[3],i[1]/=i[3],new t.P((.5*i[0]+.5)*this.width,(.5*-i[1]+.5)*this.height)}screenPointToMercatorCoordinate(e,i){if(i){const t=i.pointCoordinate(e);if(t)return t}return t.a0.fromLngLat(this.unprojectScreenPoint(e))}screenPointToLocation(e,t){var i;return null===(i=this.screenPointToMercatorCoordinate(e,t))||void 0===i?void 0:i.toLngLat()}isPointOnMapSurface(e,t){const i=this._cameraPosition,o=this.getRayDirectionFromPixel(e);return !!this.rayPlanetIntersection(i,o)}getRayDirectionFromPixel(e){const i=t.bu();i[0]=e.x/this.width*2-1,i[1]=-1*(e.y/this.height*2-1),i[2]=1,i[3]=1,t.av(i,i,this._globeViewProjMatrixNoCorrectionInverted),i[0]/=i[3],i[1]/=i[3],i[2]/=i[3];const o=t.bo();o[0]=i[0]-this._cameraPosition[0],o[1]=i[1]-this._cameraPosition[1],o[2]=i[2]-this._cameraPosition[2];const r=t.bo();return t.aU(r,o),r}isSurfacePointVisible(e){const t=this._cachedClippingPlane;return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]>=0}isSurfacePointOnScreen(e){if(!this.isSurfacePointVisible(e))return !1;const i=t.bu();return t.av(i,[...e,1],this._globeViewProjMatrixNoCorrection),i[0]/=i[3],i[1]/=i[3],i[2]/=i[3],i[0]>-1&&i[0]<1&&i[1]>-1&&i[1]<1&&i[2]>-1&&i[2]<1}rayPlanetIntersection(e,i){const o=t.aW(e,i),r=t.bo(),a=t.bo();t.aQ(a,i,o),t.aT(r,e,a);const s=1-t.aW(r,r);if(s<0)return null;const n=t.aW(e,e)-1,l=-o+(o<0?1:-1)*Math.sqrt(s),c=n/l,h=l;return {tMin:Math.min(c,h),tMax:Math.max(c,h)}}unprojectScreenPoint(e){const i=this._cameraPosition,o=this.getRayDirectionFromPixel(e),r=this.rayPlanetIntersection(i,o);if(r){const e=t.bo();t.aR(e,i,[o[0]*r.tMin,o[1]*r.tMin,o[2]*r.tMin]);const a=t.bo();return t.aU(a,e),ri(a)}const a=this._cachedClippingPlane,s=a[0]*o[0]+a[1]*o[1]+a[2]*o[2],n=-t.b0(a,i)/s,l=t.bo();if(n>0)t.aR(l,i,[o[0]*n,o[1]*n,o[2]*n]);else {const e=t.bo();t.aR(e,i,[2*o[0],2*o[1],2*o[2]]);const r=t.b0(this._cachedClippingPlane,e);t.aT(l,e,[this._cachedClippingPlane[0]*r,this._cachedClippingPlane[1]*r,this._cachedClippingPlane[2]*r]);}const c=function(e){const i=t.bo();return i[0]=e[0]*-e[3],i[1]=e[1]*-e[3],i[2]=e[2]*-e[3],{center:i,radius:Math.sqrt(1-e[3]*e[3])}}(a);return ri(function(e,i,o){const r=t.bo();t.aT(r,o,e);const a=t.bo();return t.bp(a,e,r,i/t.a_(r)),a}(c.center,c.radius,l))}getMatrixForModel(e,i){const o=t.S.convert(e),r=1/t.bt,a=t.b8();return t.by(a,a,o.lng/180*Math.PI),t.b6(a,a,-o.lat/180*Math.PI),t.M(a,a,[0,0,1+i/t.bt]),t.b6(a,a,.5*Math.PI),t.N(a,a,[r,r,r]),a}getProjectionDataForCustomLayer(e=!0){const i=this.getProjectionData({overscaledTileID:new t.Z(0,0,0,0,0),applyGlobeMatrix:e});return i.tileMercatorCoords=[0,0,1,1],i}getFastPathSimpleProjectionMatrix(e){}}class gi{get pixelsToClipSpaceMatrix(){return this._helper.pixelsToClipSpaceMatrix}get clipSpaceToPixelsMatrix(){return this._helper.clipSpaceToPixelsMatrix}get pixelsToGLUnits(){return this._helper.pixelsToGLUnits}get centerOffset(){return this._helper.centerOffset}get size(){return this._helper.size}get rotationMatrix(){return this._helper.rotationMatrix}get centerPoint(){return this._helper.centerPoint}get pixelsPerMeter(){return this._helper.pixelsPerMeter}setMinZoom(e){this._helper.setMinZoom(e);}setMaxZoom(e){this._helper.setMaxZoom(e);}setMinPitch(e){this._helper.setMinPitch(e);}setMaxPitch(e){this._helper.setMaxPitch(e);}setRenderWorldCopies(e){this._helper.setRenderWorldCopies(e);}setBearing(e){this._helper.setBearing(e);}setPitch(e){this._helper.setPitch(e);}setRoll(e){this._helper.setRoll(e);}setFov(e){this._helper.setFov(e);}setZoom(e){this._helper.setZoom(e);}setCenter(e){this._helper.setCenter(e);}setElevation(e){this._helper.setElevation(e);}setMinElevationForCurrentTile(e){this._helper.setMinElevationForCurrentTile(e);}setPadding(e){this._helper.setPadding(e);}interpolatePadding(e,t,i){return this._helper.interpolatePadding(e,t,i)}isPaddingEqual(e){return this._helper.isPaddingEqual(e)}resize(e,t,i=!0){this._helper.resize(e,t,i);}getMaxBounds(){return this._helper.getMaxBounds()}setMaxBounds(e){this._helper.setMaxBounds(e);}overrideNearFarZ(e,t){this._helper.overrideNearFarZ(e,t);}clearNearFarZOverride(){this._helper.clearNearFarZOverride();}getCameraQueryGeometry(e){return this._helper.getCameraQueryGeometry(this.getCameraPoint(),e)}get tileSize(){return this._helper.tileSize}get tileZoom(){return this._helper.tileZoom}get scale(){return this._helper.scale}get worldSize(){return this._helper.worldSize}get width(){return this._helper.width}get height(){return this._helper.height}get lngRange(){return this._helper.lngRange}get latRange(){return this._helper.latRange}get minZoom(){return this._helper.minZoom}get maxZoom(){return this._helper.maxZoom}get zoom(){return this._helper.zoom}get center(){return this._helper.center}get minPitch(){return this._helper.minPitch}get maxPitch(){return this._helper.maxPitch}get pitch(){return this._helper.pitch}get pitchInRadians(){return this._helper.pitchInRadians}get roll(){return this._helper.roll}get rollInRadians(){return this._helper.rollInRadians}get bearing(){return this._helper.bearing}get bearingInRadians(){return this._helper.bearingInRadians}get fov(){return this._helper.fov}get fovInRadians(){return this._helper.fovInRadians}get elevation(){return this._helper.elevation}get minElevationForCurrentTile(){return this._helper.minElevationForCurrentTile}get padding(){return this._helper.padding}get unmodified(){return this._helper.unmodified}get renderWorldCopies(){return this._helper.renderWorldCopies}get cameraToCenterDistance(){return this._helper.cameraToCenterDistance}get nearZ(){return this._helper.nearZ}get farZ(){return this._helper.farZ}get autoCalculateNearFarZ(){return this._helper.autoCalculateNearFarZ}get isGlobeRendering(){return this._globeness>0}setTransitionState(e,t){this._globeness=e,this._globeLatitudeErrorCorrectionRadians=t,this._calcMatrices(),this._verticalPerspectiveTransform.getCoveringTilesDetailsProvider().prepareNextFrame(),this._mercatorTransform.getCoveringTilesDetailsProvider().prepareNextFrame();}get currentTransform(){return this.isGlobeRendering?this._verticalPerspectiveTransform:this._mercatorTransform}constructor(){this._globeLatitudeErrorCorrectionRadians=0,this._globeness=1,this._helper=new Rt({calcMatrices:()=>{this._calcMatrices();},getConstrained:(e,t)=>this.getConstrained(e,t)}),this._globeness=1,this._mercatorTransform=new Lt,this._verticalPerspectiveTransform=new fi;}clone(){const e=new gi;return e._globeness=this._globeness,e._globeLatitudeErrorCorrectionRadians=this._globeLatitudeErrorCorrectionRadians,e.apply(this),e}apply(e){this._helper.apply(e),this._mercatorTransform.apply(this),this._verticalPerspectiveTransform.apply(this,this._globeLatitudeErrorCorrectionRadians);}get projectionMatrix(){return this.currentTransform.projectionMatrix}get modelViewProjectionMatrix(){return this.currentTransform.modelViewProjectionMatrix}get inverseProjectionMatrix(){return this.currentTransform.inverseProjectionMatrix}get cameraPosition(){return this.currentTransform.cameraPosition}getProjectionData(e){const t=this._mercatorTransform.getProjectionData(e),i=this._verticalPerspectiveTransform.getProjectionData(e);return {mainMatrix:this.isGlobeRendering?i.mainMatrix:t.mainMatrix,clippingPlane:i.clippingPlane,tileMercatorCoords:i.tileMercatorCoords,projectionTransition:e.applyGlobeMatrix?this._globeness:0,fallbackMatrix:t.fallbackMatrix}}isLocationOccluded(e){return this.currentTransform.isLocationOccluded(e)}transformLightDirection(e){return this.currentTransform.transformLightDirection(e)}getPixelScale(){return t.bj(this._mercatorTransform.getPixelScale(),this._verticalPerspectiveTransform.getPixelScale(),this._globeness)}getCircleRadiusCorrection(){return t.bj(this._mercatorTransform.getCircleRadiusCorrection(),this._verticalPerspectiveTransform.getCircleRadiusCorrection(),this._globeness)}getPitchedTextCorrection(e,i,o){const r=this._mercatorTransform.getPitchedTextCorrection(e,i,o),a=this._verticalPerspectiveTransform.getPitchedTextCorrection(e,i,o);return t.bj(r,a,this._globeness)}projectTileCoordinates(e,t,i,o){return this.currentTransform.projectTileCoordinates(e,t,i,o)}_calcMatrices(){this._helper._width&&this._helper._height&&(this._verticalPerspectiveTransform.apply(this,this._globeLatitudeErrorCorrectionRadians),this._helper._nearZ=this._verticalPerspectiveTransform.nearZ,this._helper._farZ=this._verticalPerspectiveTransform.farZ,this._mercatorTransform.apply(this,!0,this.isGlobeRendering),this._helper._nearZ=this._mercatorTransform.nearZ,this._helper._farZ=this._mercatorTransform.farZ);}calculateFogMatrix(e){return this.currentTransform.calculateFogMatrix(e)}getVisibleUnwrappedCoordinates(e){return this.currentTransform.getVisibleUnwrappedCoordinates(e)}getCameraFrustum(){return this.currentTransform.getCameraFrustum()}getClippingPlane(){return this.currentTransform.getClippingPlane()}getCoveringTilesDetailsProvider(){return this.currentTransform.getCoveringTilesDetailsProvider()}recalculateZoomAndCenter(e){this._mercatorTransform.recalculateZoomAndCenter(e),this._verticalPerspectiveTransform.recalculateZoomAndCenter(e);}maxPitchScaleFactor(){return this._mercatorTransform.maxPitchScaleFactor()}getCameraPoint(){return this._helper.getCameraPoint()}getCameraAltitude(){return this._helper.getCameraAltitude()}getCameraLngLat(){return this._helper.getCameraLngLat()}lngLatToCameraDepth(e,t){return this.currentTransform.lngLatToCameraDepth(e,t)}populateCache(e){this._mercatorTransform.populateCache(e),this._verticalPerspectiveTransform.populateCache(e);}getBounds(){return this.currentTransform.getBounds()}getConstrained(e,t){return this.currentTransform.getConstrained(e,t)}calculateCenterFromCameraLngLatAlt(e,t,i,o){return this._helper.calculateCenterFromCameraLngLatAlt(e,t,i,o)}setLocationAtPoint(e,t){if(!this.isGlobeRendering)return this._mercatorTransform.setLocationAtPoint(e,t),void this.apply(this._mercatorTransform);this._verticalPerspectiveTransform.setLocationAtPoint(e,t),this.apply(this._verticalPerspectiveTransform);}locationToScreenPoint(e,t){return this.currentTransform.locationToScreenPoint(e,t)}screenPointToMercatorCoordinate(e,t){return this.currentTransform.screenPointToMercatorCoordinate(e,t)}screenPointToLocation(e,t){return this.currentTransform.screenPointToLocation(e,t)}isPointOnMapSurface(e,t){return this.currentTransform.isPointOnMapSurface(e,t)}getRayDirectionFromPixel(e){return this._verticalPerspectiveTransform.getRayDirectionFromPixel(e)}getMatrixForModel(e,t){return this.currentTransform.getMatrixForModel(e,t)}getProjectionDataForCustomLayer(e=!0){const t=this._mercatorTransform.getProjectionDataForCustomLayer(e);if(!this.isGlobeRendering)return t;const i=this._verticalPerspectiveTransform.getProjectionDataForCustomLayer(e);return i.fallbackMatrix=t.mainMatrix,i}getFastPathSimpleProjectionMatrix(e){return this.currentTransform.getFastPathSimpleProjectionMatrix(e)}}class vi{get useGlobeControls(){return !0}handlePanInertia(e,i){const o=ni(e,i);return Math.abs(o.lng-i.center.lng)>180&&(o.lng=i.center.lng+179.5*Math.sign(o.lng-i.center.lng)),{easingCenter:o,easingOffset:new t.P(0,0)}}handleMapControlsRollPitchBearingZoom(e,i){const o=e.around,r=i.screenPointToLocation(o);e.bearingDelta&&i.setBearing(i.bearing+e.bearingDelta),e.pitchDelta&&i.setPitch(i.pitch+e.pitchDelta),e.rollDelta&&i.setRoll(i.roll+e.rollDelta);const a=i.zoom;e.zoomDelta&&i.setZoom(i.zoom+e.zoomDelta);const s=i.zoom-a;if(0===s)return;const n=t.bz(i.center.lng,r.lng),l=n/(Math.abs(n/180)+1),c=t.bz(i.center.lat,r.lat),h=i.getRayDirectionFromPixel(o),u=i.cameraPosition,d=-1*t.aW(u,h),_=t.bo();t.aR(_,u,[h[0]*d,h[1]*d,h[2]*d]);const p=t.aY(_)-1,m=Math.exp(.5*-Math.max(p-.3,0)),f=oi(i.worldSize,i.center.lat)/Math.min(i.width,i.height),g=t.bm(f,.9,.5,1,.25),v=(1-t.ae(-s))*Math.min(m,g),b=i.center.lat,x=i.zoom,y=new t.S(i.center.lng+l*v,t.ag(i.center.lat+c*v,-85.051129,t.ah));i.setLocationAtPoint(r,o);const w=i.center,T=t.bm(Math.abs(n),45,85,0,1),P=t.bm(f,.75,.35,0,1),C=Math.pow(Math.max(T,P),.25),I=t.bz(w.lng,y.lng),M=t.bz(w.lat,y.lat);i.setCenter(new t.S(w.lng+I*C,w.lat+M*C).wrap()),i.setZoom(x+si(b,i.center.lat));}handleMapControlsPan(e,t,i){if(!e.panDelta)return;const o=t.center.lat,r=t.zoom;t.setCenter(ni(e.panDelta,t).wrap()),t.setZoom(r+si(o,t.center.lat));}cameraForBoxAndBearing(e,i,o,r,a){const s=Bt(e,i,o,r,a),n=i.left/a.width*2-1,l=(a.width-i.right)/a.width*2-1,c=i.top/a.height*-2+1,h=(a.height-i.bottom)/a.height*-2+1,u=t.bz(o.getWest(),o.getEast())<0,d=u?o.getEast():o.getWest(),_=u?o.getWest():o.getEast(),p=Math.max(o.getNorth(),o.getSouth()),m=Math.min(o.getNorth(),o.getSouth()),f=d+.5*t.bz(d,_),g=p+.5*t.bz(p,m),v=a.clone();v.setCenter(s.center),v.setBearing(s.bearing),v.setPitch(0),v.setRoll(0),v.setZoom(s.zoom);const b=v.modelViewProjectionMatrix,x=[ii(o.getNorthWest()),ii(o.getNorthEast()),ii(o.getSouthWest()),ii(o.getSouthEast()),ii(new t.S(_,g)),ii(new t.S(d,g)),ii(new t.S(f,p)),ii(new t.S(f,m))],y=ii(s.center);let w=Number.POSITIVE_INFINITY;for(const e of x)n<0&&(w=vi.getLesserNonNegativeNonNull(w,vi.solveVectorScale(e,y,b,\"x\",n))),l>0&&(w=vi.getLesserNonNegativeNonNull(w,vi.solveVectorScale(e,y,b,\"x\",l))),c>0&&(w=vi.getLesserNonNegativeNonNull(w,vi.solveVectorScale(e,y,b,\"y\",c))),h<0&&(w=vi.getLesserNonNegativeNonNull(w,vi.solveVectorScale(e,y,b,\"y\",h)));if(Number.isFinite(w)&&0!==w)return s.zoom=v.zoom+t.aj(w),s;kt();}handleJumpToCenterZoom(e,i){const o=e.center.lat,r=e.getConstrained(i.center?t.S.convert(i.center):e.center,e.zoom).center;e.setCenter(r.wrap());const a=void 0!==i.zoom?+i.zoom:e.zoom+si(o,r.lat);e.zoom!==a&&e.setZoom(a);}handleEaseTo(e,i){const o=e.zoom,r=e.center,a=e.padding,s={roll:e.roll,pitch:e.pitch,bearing:e.bearing},n={roll:void 0===i.roll?e.roll:i.roll,pitch:void 0===i.pitch?e.pitch:i.pitch,bearing:void 0===i.bearing?e.bearing:i.bearing},l=void 0!==i.zoom,c=!e.isPaddingEqual(i.padding);let h=!1;const u=i.center?t.S.convert(i.center):r,d=e.getConstrained(u,o).center;St(e,d);const _=e.clone();_.setCenter(d),_.setZoom(l?+i.zoom:o+si(r.lat,u.lat)),_.setBearing(i.bearing);const p=new t.P(t.ag(e.centerPoint.x+i.offsetAsPoint.x,0,e.width),t.ag(e.centerPoint.y+i.offsetAsPoint.y,0,e.height));_.setLocationAtPoint(d,p);const m=(i.offset&&i.offsetAsPoint.mag())>0?_.center:d,f=l?+i.zoom:o+si(r.lat,m.lat),g=o+si(r.lat,0),v=f+si(m.lat,0),b=t.bz(r.lng,m.lng),x=t.bz(r.lat,m.lat),y=t.ae(v-g);return h=f!==o,{easeFunc:o=>{if(t.bd(s,n)||Ft({startEulerAngles:s,endEulerAngles:n,tr:e,k:o,useSlerp:s.roll!=n.roll}),c&&e.interpolatePadding(a,i.padding,o),i.around)t.w(\"Easing around a point is not supported under globe projection.\"),e.setLocationAtPoint(i.around,i.aroundPoint);else {const t=v>g?Math.min(2,y):Math.max(.5,y),i=Math.pow(t,1-o),a=ci(r,b,x,o*i);e.setCenter(a.wrap());}if(h){const i=t.C.number(g,v,o)+si(0,e.center.lat);e.setZoom(i);}},isZooming:h,elevationCenter:m}}handleFlyTo(e,i){const o=void 0!==i.zoom,r=e.center,a=e.zoom,s=e.padding,n=!e.isPaddingEqual(i.padding),l=e.getConstrained(t.S.convert(i.center||i.locationAtOffset),a).center,c=o?+i.zoom:e.zoom+si(e.center.lat,l.lat),h=e.clone();h.setCenter(l),h.setZoom(c),h.setBearing(i.bearing);const u=new t.P(t.ag(e.centerPoint.x+i.offsetAsPoint.x,0,e.width),t.ag(e.centerPoint.y+i.offsetAsPoint.y,0,e.height));h.setLocationAtPoint(l,u);const d=h.center;St(e,d);const _=function(e,i,o){const r=ii(i),a=ii(o),s=t.aW(r,a),n=Math.acos(s),l=ei(e);return n/(2*Math.PI)*l}(e,r,d),p=a+si(r.lat,0),m=c+si(d.lat,0),f=t.ae(m-p);let g;if(\"number\"==typeof i.minZoom){const o=+i.minZoom+si(d.lat,0),r=Math.min(o,p,m)+si(0,d.lat),a=e.getConstrained(d,r).zoom+si(d.lat,0);g=t.ae(a-p);}const v=t.bz(r.lng,d.lng),b=t.bz(r.lat,d.lat);return {easeFunc:(o,a,l,h)=>{const u=ci(r,v,b,l);n&&e.interpolatePadding(s,i.padding,o);const _=1===o?d:u;e.setCenter(_.wrap());const m=p+t.aj(a);e.setZoom(1===o?c:m+si(0,_.lat));},scaleOfZoom:f,targetCenter:d,scaleOfMinZoom:g,pixelPathLength:_}}static solveVectorScale(e,t,i,o,r){const a=\"x\"===o?[i[0],i[4],i[8],i[12]]:[i[1],i[5],i[9],i[13]],s=[i[3],i[7],i[11],i[15]],n=e[0]*a[0]+e[1]*a[1]+e[2]*a[2],l=e[0]*s[0]+e[1]*s[1]+e[2]*s[2],c=t[0]*a[0]+t[1]*a[1]+t[2]*a[2],h=t[0]*s[0]+t[1]*s[1]+t[2]*s[2];return c+r*l===n+r*h||s[3]*(n-c)+a[3]*(h-l)+n*h==c*l?null:(c+a[3]-r*h-r*s[3])/(c-n-r*h+r*l)}static getLesserNonNegativeNonNull(e,t){return null!==t&&t>=0&&t<e?t:e}}class bi{constructor(e){this._globe=e,this._mercatorCameraHelper=new Ot,this._verticalPerspectiveCameraHelper=new vi;}get useGlobeControls(){return this._globe.useGlobeRendering}get currentHelper(){return this.useGlobeControls?this._verticalPerspectiveCameraHelper:this._mercatorCameraHelper}handlePanInertia(e,t){return this.currentHelper.handlePanInertia(e,t)}handleMapControlsRollPitchBearingZoom(e,t){return this.currentHelper.handleMapControlsRollPitchBearingZoom(e,t)}handleMapControlsPan(e,t,i){this.currentHelper.handleMapControlsPan(e,t,i);}cameraForBoxAndBearing(e,t,i,o,r){return this.currentHelper.cameraForBoxAndBearing(e,t,i,o,r)}handleJumpToCenterZoom(e,t){this.currentHelper.handleJumpToCenterZoom(e,t);}handleEaseTo(e,t){return this.currentHelper.handleEaseTo(e,t)}handleFlyTo(e,t){return this.currentHelper.handleFlyTo(e,t)}}const xi=(e,i)=>t.y(e,i&&i.filter((e=>\"source.canvas\"!==e.identifier))),yi=t.bD();class wi extends t.E{constructor(e,i={}){super(),this._rtlPluginLoaded=()=>{for(const e in this.sourceCaches){const t=this.sourceCaches[e].getSource().type;\"vector\"!==t&&\"geojson\"!==t||this.sourceCaches[e].reload();}},this.map=e,this.dispatcher=new F(k(),e._getMapId()),this.dispatcher.registerMessageHandler(\"GG\",((e,t)=>this.getGlyphs(e,t))),this.dispatcher.registerMessageHandler(\"GI\",((e,t)=>this.getImages(e,t))),this.imageManager=new b,this.imageManager.setEventedParent(this),this.glyphManager=new T(e._requestManager,i.localIdeographFontFamily),this.lineAtlas=new E(256,512),this.crossTileSymbolIndex=new vt,this._spritesImagesIds={},this._layers={},this._order=[],this.sourceCaches={},this.zoomHistory=new t.bE,this._loaded=!1,this._availableImages=[],this._globalState={},this._resetUpdates(),this.dispatcher.broadcast(\"SR\",t.bF()),oe().on(ee,this._rtlPluginLoaded),this.on(\"data\",(e=>{if(\"source\"!==e.dataType||\"metadata\"!==e.sourceDataType)return;const t=this.sourceCaches[e.sourceId];if(!t)return;const i=t.getSource();if(i&&i.vectorLayerIds)for(const e in this._layers){const t=this._layers[e];t.source===i.id&&this._validateLayer(t);}}));}setGlobalStateProperty(e,i){var o,r,a;this._checkLoaded();const s=null===i?null!==(a=null===(r=null===(o=this.stylesheet.state)||void 0===o?void 0:o[e])||void 0===r?void 0:r.default)&&void 0!==a?a:null:i;if(t.bG(s,this._globalState[e]))return this;this._globalState[e]=s;const n=this._findGlobalStateAffectedSources([e]);for(const e in this.sourceCaches)n.has(e)&&(this._reloadSource(e),this._changed=!0);}getGlobalState(){return this._globalState}setGlobalState(e){this._checkLoaded();const i=[];for(const o in e)!t.bG(this._globalState[o],e[o].default)&&(i.push(o),this._globalState[o]=e[o].default);const o=this._findGlobalStateAffectedSources(i);for(const e in this.sourceCaches)o.has(e)&&(this._reloadSource(e),this._changed=!0);}_findGlobalStateAffectedSources(e){if(0===e.length)return new Set;const t=new Set;for(const i in this._layers){const o=this._layers[i],r=o.getLayoutAffectingGlobalStateRefs();for(const i of e)r.has(i)&&t.add(o.source);}return t}loadURL(e,i={},o){this.fire(new t.l(\"dataloading\",{dataType:\"style\"})),i.validate=\"boolean\"!=typeof i.validate||i.validate;const r=this.map._requestManager.transformRequest(e,\"Style\");this._loadStyleRequest=new AbortController;const a=this._loadStyleRequest;t.j(r,this._loadStyleRequest).then((e=>{this._loadStyleRequest=null,this._load(e.data,i,o);})).catch((e=>{this._loadStyleRequest=null,e&&!a.signal.aborted&&this.fire(new t.k(e));}));}loadJSON(e,i={},o){this.fire(new t.l(\"dataloading\",{dataType:\"style\"})),this._frameRequest=new AbortController,s.frameAsync(this._frameRequest).then((()=>{this._frameRequest=null,i.validate=!1!==i.validate,this._load(e,i,o);})).catch((()=>{}));}loadEmpty(){this.fire(new t.l(\"dataloading\",{dataType:\"style\"})),this._load(yi,{validate:!1});}_load(e,i,o){var r,a,s;const n=i.transformStyle?i.transformStyle(o,e):e;if(!i.validate||!xi(this,t.z(n))){this._loaded=!0,this.stylesheet=n;for(const e in n.sources)this.addSource(e,n.sources[e],{validate:!1});n.sprite?this._loadSprite(n.sprite):this.imageManager.setLoaded(!0),this.glyphManager.setURL(n.glyphs),this._createLayers(),this.light=new I(this.stylesheet.light),this._setProjectionInternal((null===(r=this.stylesheet.projection)||void 0===r?void 0:r.type)||\"mercator\"),this.sky=new S(this.stylesheet.sky),this.map.setTerrain(null!==(a=this.stylesheet.terrain)&&void 0!==a?a:null),this.setGlobalState(null!==(s=this.stylesheet.state)&&void 0!==s?s:null),this.fire(new t.l(\"data\",{dataType:\"style\"})),this.fire(new t.l(\"style.load\"));}}_createLayers(){const e=t.bH(this.stylesheet.layers);this.dispatcher.broadcast(\"SL\",e),this._order=e.map((e=>e.id)),this._layers={},this._serializedLayers=null;for(const i of e){const e=t.bI(i);e.setEventedParent(this,{layer:{id:i.id}}),this._layers[i.id]=e;}}_loadSprite(e,i=!1,o=void 0){let r;this.imageManager.setLoaded(!1),this._spriteRequest=new AbortController,function(e,i,o,r){return t._(this,void 0,void 0,(function*(){const a=f(e),n=o>1?\"@2x\":\"\",l={},c={};for(const{id:e,url:o}of a){const a=i.transformRequest(g(o,n,\".json\"),\"SpriteJSON\");l[e]=t.j(a,r);const s=i.transformRequest(g(o,n,\".png\"),\"SpriteImage\");c[e]=p.getImage(s,r);}return yield Promise.all([...Object.values(l),...Object.values(c)]),function(e,i){return t._(this,void 0,void 0,(function*(){const t={};for(const o in e){t[o]={};const r=s.getImageCanvasContext((yield i[o]).data),a=(yield e[o]).data;for(const e in a){const{width:i,height:s,x:n,y:l,sdf:c,pixelRatio:h,stretchX:u,stretchY:d,content:_,textFitWidth:p,textFitHeight:m}=a[e];t[o][e]={data:null,pixelRatio:h,sdf:c,stretchX:u,stretchY:d,content:_,textFitWidth:p,textFitHeight:m,spriteData:{width:i,height:s,x:n,y:l,context:r}};}}return t}))}(l,c)}))}(e,this.map._requestManager,this.map.getPixelRatio(),this._spriteRequest).then((e=>{if(this._spriteRequest=null,e)for(const t in e){this._spritesImagesIds[t]=[];const o=this._spritesImagesIds[t]?this._spritesImagesIds[t].filter((t=>!(t in e))):[];for(const e of o)this.imageManager.removeImage(e),this._changedImages[e]=!0;for(const o in e[t]){const r=\"default\"===t?o:`${t}:${o}`;this._spritesImagesIds[t].push(r),r in this.imageManager.images?this.imageManager.updateImage(r,e[t][o],!1):this.imageManager.addImage(r,e[t][o]),i&&(this._changedImages[r]=!0);}}})).catch((e=>{this._spriteRequest=null,r=e,this.fire(new t.k(r));})).finally((()=>{this.imageManager.setLoaded(!0),this._availableImages=this.imageManager.listImages(),i&&(this._changed=!0),this.dispatcher.broadcast(\"SI\",this._availableImages),this.fire(new t.l(\"data\",{dataType:\"style\"})),o&&o(r);}));}_unloadSprite(){for(const e of Object.values(this._spritesImagesIds).flat())this.imageManager.removeImage(e),this._changedImages[e]=!0;this._spritesImagesIds={},this._availableImages=this.imageManager.listImages(),this._changed=!0,this.dispatcher.broadcast(\"SI\",this._availableImages),this.fire(new t.l(\"data\",{dataType:\"style\"}));}_validateLayer(e){const i=this.sourceCaches[e.source];if(!i)return;const o=e.sourceLayer;if(!o)return;const r=i.getSource();(\"geojson\"===r.type||r.vectorLayerIds&&-1===r.vectorLayerIds.indexOf(o))&&this.fire(new t.k(new Error(`Source layer \"${o}\" does not exist on source \"${r.id}\" as specified by style layer \"${e.id}\".`)));}loaded(){if(!this._loaded)return !1;if(Object.keys(this._updatedSources).length)return !1;for(const e in this.sourceCaches)if(!this.sourceCaches[e].loaded())return !1;return !!this.imageManager.isLoaded()}_serializeByIds(e,i=!1){const o=this._serializedAllLayers();if(!e||0===e.length)return Object.values(i?t.bJ(o):o);const r=[];for(const a of e)if(o[a]){const e=i?t.bJ(o[a]):o[a];r.push(e);}return r}_serializedAllLayers(){let e=this._serializedLayers;if(e)return e;e=this._serializedLayers={};const t=Object.keys(this._layers);for(const i of t){const t=this._layers[i];\"custom\"!==t.type&&(e[i]=t.serialize());}return e}hasTransitions(){var e,t,i;if(null===(e=this.light)||void 0===e?void 0:e.hasTransition())return !0;if(null===(t=this.sky)||void 0===t?void 0:t.hasTransition())return !0;if(null===(i=this.projection)||void 0===i?void 0:i.hasTransition())return !0;for(const e in this.sourceCaches)if(this.sourceCaches[e].hasTransition())return !0;for(const e in this._layers)if(this._layers[e].hasTransition())return !0;return !1}_checkLoaded(){if(!this._loaded)throw new Error(\"Style is not done loading.\")}update(e){if(!this._loaded)return;const i=this._changed;if(i){const t=Object.keys(this._updatedLayers),i=Object.keys(this._removedLayers);(t.length||i.length)&&this._updateWorkerLayers(t,i);for(const e in this._updatedSources){const t=this._updatedSources[e];if(\"reload\"===t)this._reloadSource(e);else {if(\"clear\"!==t)throw new Error(`Invalid action ${t}`);this._clearSource(e);}}this._updateTilesForChangedImages(),this._updateTilesForChangedGlyphs();for(const t in this._updatedPaintProps)this._layers[t].updateTransitions(e);this.light.updateTransitions(e),this.sky.updateTransitions(e),this._resetUpdates();}const o={};for(const e in this.sourceCaches){const t=this.sourceCaches[e];o[e]=t.used,t.used=!1;}for(const t of this._order){const i=this._layers[t];i.recalculate(e,this._availableImages),!i.isHidden(e.zoom)&&i.source&&(this.sourceCaches[i.source].used=!0);}for(const e in o){const i=this.sourceCaches[e];!!o[e]!=!!i.used&&i.fire(new t.l(\"data\",{sourceDataType:\"visibility\",dataType:\"source\",sourceId:e}));}this.light.recalculate(e),this.sky.recalculate(e),this.projection.recalculate(e),this.z=e.zoom,i&&this.fire(new t.l(\"data\",{dataType:\"style\"}));}_updateTilesForChangedImages(){const e=Object.keys(this._changedImages);if(e.length){for(const t in this.sourceCaches)this.sourceCaches[t].reloadTilesForDependencies([\"icons\",\"patterns\"],e);this._changedImages={};}}_updateTilesForChangedGlyphs(){if(this._glyphsDidChange){for(const e in this.sourceCaches)this.sourceCaches[e].reloadTilesForDependencies([\"glyphs\"],[\"\"]);this._glyphsDidChange=!1;}}_updateWorkerLayers(e,t){this.dispatcher.broadcast(\"UL\",{layers:this._serializeByIds(e,!1),removedIds:t});}_resetUpdates(){this._changed=!1,this._updatedLayers={},this._removedLayers={},this._updatedSources={},this._updatedPaintProps={},this._changedImages={},this._glyphsDidChange=!1;}setState(e,i={}){var o;this._checkLoaded();const r=this.serialize();if(e=i.transformStyle?i.transformStyle(r,e):e,(null===(o=i.validate)||void 0===o||o)&&xi(this,t.z(e)))return !1;(e=t.bJ(e)).layers=t.bH(e.layers);const a=t.bK(r,e),s=this._getOperationsToPerform(a);if(s.unimplemented.length>0)throw new Error(`Unimplemented: ${s.unimplemented.join(\", \")}.`);if(0===s.operations.length)return !1;for(const e of s.operations)e();return this.stylesheet=e,this._serializedLayers=null,!0}_getOperationsToPerform(e){const t=[],i=[];for(const o of e)switch(o.command){case \"setCenter\":case \"setZoom\":case \"setBearing\":case \"setPitch\":case \"setRoll\":continue;case \"addLayer\":t.push((()=>this.addLayer.apply(this,o.args)));break;case \"removeLayer\":t.push((()=>this.removeLayer.apply(this,o.args)));break;case \"setPaintProperty\":t.push((()=>this.setPaintProperty.apply(this,o.args)));break;case \"setLayoutProperty\":t.push((()=>this.setLayoutProperty.apply(this,o.args)));break;case \"setFilter\":t.push((()=>this.setFilter.apply(this,o.args)));break;case \"addSource\":t.push((()=>this.addSource.apply(this,o.args)));break;case \"removeSource\":t.push((()=>this.removeSource.apply(this,o.args)));break;case \"setLayerZoomRange\":t.push((()=>this.setLayerZoomRange.apply(this,o.args)));break;case \"setLight\":t.push((()=>this.setLight.apply(this,o.args)));break;case \"setGeoJSONSourceData\":t.push((()=>this.setGeoJSONSourceData.apply(this,o.args)));break;case \"setGlyphs\":t.push((()=>this.setGlyphs.apply(this,o.args)));break;case \"setSprite\":t.push((()=>this.setSprite.apply(this,o.args)));break;case \"setTerrain\":t.push((()=>this.map.setTerrain.apply(this,o.args)));break;case \"setSky\":t.push((()=>this.setSky.apply(this,o.args)));break;case \"setProjection\":this.setProjection.apply(this,o.args);break;case \"setGlobalState\":t.push((()=>this.setGlobalState.apply(this,o.args)));break;case \"setTransition\":t.push((()=>{}));break;default:i.push(o.command);}return {operations:t,unimplemented:i}}addImage(e,i){if(this.getImage(e))return this.fire(new t.k(new Error(`An image named \"${e}\" already exists.`)));this.imageManager.addImage(e,i),this._afterImageUpdated(e);}updateImage(e,t){this.imageManager.updateImage(e,t);}getImage(e){return this.imageManager.getImage(e)}removeImage(e){if(!this.getImage(e))return this.fire(new t.k(new Error(`An image named \"${e}\" does not exist.`)));this.imageManager.removeImage(e),this._afterImageUpdated(e);}_afterImageUpdated(e){this._availableImages=this.imageManager.listImages(),this._changedImages[e]=!0,this._changed=!0,this.dispatcher.broadcast(\"SI\",this._availableImages),this.fire(new t.l(\"data\",{dataType:\"style\"}));}listImages(){return this._checkLoaded(),this.imageManager.listImages()}addSource(e,i,o={}){if(this._checkLoaded(),void 0!==this.sourceCaches[e])throw new Error(`Source \"${e}\" already exists.`);if(!i.type)throw new Error(`The type property must be defined, but only the following properties were given: ${Object.keys(i).join(\", \")}.`);if([\"vector\",\"raster\",\"geojson\",\"video\",\"image\"].indexOf(i.type)>=0&&this._validate(t.z.source,`sources.${e}`,i,null,o))return;this.map&&this.map._collectResourceTiming&&(i.collectResourceTiming=!0);const r=this.sourceCaches[e]=new xe(e,i,this.dispatcher);r.style=this,r.setEventedParent(this,(()=>({isSourceLoaded:r.loaded(),source:r.serialize(),sourceId:e}))),r.onAdd(this.map),this._changed=!0;}removeSource(e){if(this._checkLoaded(),void 0===this.sourceCaches[e])throw new Error(\"There is no source with this ID\");for(const i in this._layers)if(this._layers[i].source===e)return this.fire(new t.k(new Error(`Source \"${e}\" cannot be removed while layer \"${i}\" is using it.`)));const i=this.sourceCaches[e];delete this.sourceCaches[e],delete this._updatedSources[e],i.fire(new t.l(\"data\",{sourceDataType:\"metadata\",dataType:\"source\",sourceId:e})),i.setEventedParent(null),i.onRemove(this.map),this._changed=!0;}setGeoJSONSourceData(e,t){if(this._checkLoaded(),void 0===this.sourceCaches[e])throw new Error(`There is no source with this ID=${e}`);const i=this.sourceCaches[e].getSource();if(\"geojson\"!==i.type)throw new Error(`geojsonSource.type is ${i.type}, which is !== 'geojson`);i.setData(t),this._changed=!0;}getSource(e){return this.sourceCaches[e]&&this.sourceCaches[e].getSource()}addLayer(e,i,o={}){this._checkLoaded();const r=e.id;if(this.getLayer(r))return void this.fire(new t.k(new Error(`Layer \"${r}\" already exists on this map.`)));let a;if(\"custom\"===e.type){if(xi(this,t.bL(e)))return;a=t.bI(e);}else {if(\"source\"in e&&\"object\"==typeof e.source&&(this.addSource(r,e.source),e=t.bJ(e),e=t.e(e,{source:r})),this._validate(t.z.layer,`layers.${r}`,e,{arrayIndex:-1},o))return;a=t.bI(e),this._validateLayer(a),a.setEventedParent(this,{layer:{id:r}});}const s=i?this._order.indexOf(i):this._order.length;if(i&&-1===s)this.fire(new t.k(new Error(`Cannot add layer \"${r}\" before non-existing layer \"${i}\".`)));else {if(this._order.splice(s,0,r),this._layerOrderChanged=!0,this._layers[r]=a,this._removedLayers[r]&&a.source&&\"custom\"!==a.type){const e=this._removedLayers[r];delete this._removedLayers[r],e.type!==a.type?this._updatedSources[a.source]=\"clear\":(this._updatedSources[a.source]=\"reload\",this.sourceCaches[a.source].pause());}this._updateLayer(a),a.onAdd&&a.onAdd(this.map);}}moveLayer(e,i){if(this._checkLoaded(),this._changed=!0,!this._layers[e])return void this.fire(new t.k(new Error(`The layer '${e}' does not exist in the map's style and cannot be moved.`)));if(e===i)return;const o=this._order.indexOf(e);this._order.splice(o,1);const r=i?this._order.indexOf(i):this._order.length;i&&-1===r?this.fire(new t.k(new Error(`Cannot move layer \"${e}\" before non-existing layer \"${i}\".`))):(this._order.splice(r,0,e),this._layerOrderChanged=!0);}removeLayer(e){this._checkLoaded();const i=this._layers[e];if(!i)return void this.fire(new t.k(new Error(`Cannot remove non-existing layer \"${e}\".`)));i.setEventedParent(null);const o=this._order.indexOf(e);this._order.splice(o,1),this._layerOrderChanged=!0,this._changed=!0,this._removedLayers[e]=i,delete this._layers[e],this._serializedLayers&&delete this._serializedLayers[e],delete this._updatedLayers[e],delete this._updatedPaintProps[e],i.onRemove&&i.onRemove(this.map);}getLayer(e){return this._layers[e]}getLayersOrder(){return [...this._order]}hasLayer(e){return e in this._layers}setLayerZoomRange(e,i,o){this._checkLoaded();const r=this.getLayer(e);r?r.minzoom===i&&r.maxzoom===o||(null!=i&&(r.minzoom=i),null!=o&&(r.maxzoom=o),this._updateLayer(r)):this.fire(new t.k(new Error(`Cannot set the zoom range of non-existing layer \"${e}\".`)));}setFilter(e,i,o={}){this._checkLoaded();const r=this.getLayer(e);if(r){if(!t.bG(r.filter,i))return null==i?(r.setFilter(void 0),void this._updateLayer(r)):void(this._validate(t.z.filter,`layers.${r.id}.filter`,i,null,o)||(r.setFilter(t.bJ(i)),this._updateLayer(r)))}else this.fire(new t.k(new Error(`Cannot filter non-existing layer \"${e}\".`)));}getFilter(e){return t.bJ(this.getLayer(e).filter)}setLayoutProperty(e,i,o,r={}){this._checkLoaded();const a=this.getLayer(e);a?t.bG(a.getLayoutProperty(i),o)||(a.setLayoutProperty(i,o,r),this._updateLayer(a)):this.fire(new t.k(new Error(`Cannot style non-existing layer \"${e}\".`)));}getLayoutProperty(e,i){const o=this.getLayer(e);if(o)return o.getLayoutProperty(i);this.fire(new t.k(new Error(`Cannot get style of non-existing layer \"${e}\".`)));}setPaintProperty(e,i,o,r={}){this._checkLoaded();const a=this.getLayer(e);a?t.bG(a.getPaintProperty(i),o)||(a.setPaintProperty(i,o,r)&&this._updateLayer(a),this._changed=!0,this._updatedPaintProps[e]=!0,this._serializedLayers=null):this.fire(new t.k(new Error(`Cannot style non-existing layer \"${e}\".`)));}getPaintProperty(e,t){return this.getLayer(e).getPaintProperty(t)}setFeatureState(e,i){this._checkLoaded();const o=e.source,r=e.sourceLayer,a=this.sourceCaches[o];if(void 0===a)return void this.fire(new t.k(new Error(`The source '${o}' does not exist in the map's style.`)));const s=a.getSource().type;\"geojson\"===s&&r?this.fire(new t.k(new Error(\"GeoJSON sources cannot have a sourceLayer parameter.\"))):\"vector\"!==s||r?(void 0===e.id&&this.fire(new t.k(new Error(\"The feature id parameter must be provided.\"))),a.setFeatureState(r,e.id,i)):this.fire(new t.k(new Error(\"The sourceLayer parameter must be provided for vector source types.\")));}removeFeatureState(e,i){this._checkLoaded();const o=e.source,r=this.sourceCaches[o];if(void 0===r)return void this.fire(new t.k(new Error(`The source '${o}' does not exist in the map's style.`)));const a=r.getSource().type,s=\"vector\"===a?e.sourceLayer:void 0;\"vector\"!==a||s?i&&\"string\"!=typeof e.id&&\"number\"!=typeof e.id?this.fire(new t.k(new Error(\"A feature id is required to remove its specific state property.\"))):r.removeFeatureState(s,e.id,i):this.fire(new t.k(new Error(\"The sourceLayer parameter must be provided for vector source types.\")));}getFeatureState(e){this._checkLoaded();const i=e.source,o=e.sourceLayer,r=this.sourceCaches[i];if(void 0!==r)return \"vector\"!==r.getSource().type||o?(void 0===e.id&&this.fire(new t.k(new Error(\"The feature id parameter must be provided.\"))),r.getFeatureState(o,e.id)):void this.fire(new t.k(new Error(\"The sourceLayer parameter must be provided for vector source types.\")));this.fire(new t.k(new Error(`The source '${i}' does not exist in the map's style.`)));}getTransition(){return t.e({duration:300,delay:0},this.stylesheet&&this.stylesheet.transition)}serialize(){if(!this._loaded)return;const e=t.bM(this.sourceCaches,(e=>e.serialize())),i=this._serializeByIds(this._order,!0),o=this.map.getTerrain()||void 0,r=this.stylesheet;return t.bN({version:r.version,name:r.name,metadata:r.metadata,light:r.light,sky:r.sky,center:r.center,zoom:r.zoom,bearing:r.bearing,pitch:r.pitch,sprite:r.sprite,glyphs:r.glyphs,transition:r.transition,projection:r.projection,sources:e,layers:i,terrain:o},(e=>void 0!==e))}_updateLayer(e){this._updatedLayers[e.id]=!0,e.source&&!this._updatedSources[e.source]&&\"raster\"!==this.sourceCaches[e.source].getSource().type&&(this._updatedSources[e.source]=\"reload\",this.sourceCaches[e.source].pause()),this._serializedLayers=null,this._changed=!0;}_flattenAndSortRenderedFeatures(e){const t=e=>\"fill-extrusion\"===this._layers[e].type,i={},o=[];for(let r=this._order.length-1;r>=0;r--){const a=this._order[r];if(t(a)){i[a]=r;for(const t of e){const e=t[a];if(e)for(const t of e)o.push(t);}}}o.sort(((e,t)=>t.intersectionZ-e.intersectionZ));const r=[];for(let a=this._order.length-1;a>=0;a--){const s=this._order[a];if(t(s))for(let e=o.length-1;e>=0;e--){const t=o[e].feature;if(i[t.layer.id]<a)break;r.push(t),o.pop();}else for(const t of e){const e=t[s];if(e)for(const t of e)r.push(t.feature);}}return r}queryRenderedFeatures(e,i,o){i&&i.filter&&this._validate(t.z.filter,\"queryRenderedFeatures.filter\",i.filter,null,i);const r={};if(i&&i.layers){if(!(Array.isArray(i.layers)||i.layers instanceof Set))return this.fire(new t.k(new Error(\"parameters.layers must be an Array or a Set of strings\"))),[];for(const e of i.layers){const i=this._layers[e];if(!i)return this.fire(new t.k(new Error(`The layer '${e}' does not exist in the map's style and cannot be queried for features.`))),[];r[i.source]=!0;}}const a=[];i.availableImages=this._availableImages;const s=this._serializedAllLayers(),n=i.layers instanceof Set?i.layers:Array.isArray(i.layers)?new Set(i.layers):null,l=Object.assign(Object.assign({},i),{layers:n});for(const t in this.sourceCaches)i.layers&&!r[t]||a.push(j(this.sourceCaches[t],this._layers,s,e,l,o,this.map.terrain?(e,t,i)=>this.map.terrain.getElevation(e,t,i):void 0));return this.placement&&a.push(function(e,t,i,o,r,a,s){const n={},l=a.queryRenderedSymbols(o),c=[];for(const e of Object.keys(l).map(Number))c.push(s[e]);c.sort(N);for(const i of c){const o=i.featureIndex.lookupSymbolFeatures(l[i.bucketInstanceId],t,i.bucketIndex,i.sourceLayerIndex,r.filter,r.layers,r.availableImages,e);for(const e in o){const t=n[e]=n[e]||[],r=o[e];r.sort(((e,t)=>{const o=i.featureSortOrder;if(o){const i=o.indexOf(e.featureIndex);return o.indexOf(t.featureIndex)-i}return t.featureIndex-e.featureIndex}));for(const e of r)t.push(e);}}return function(e,t,i){for(const o in e)for(const r of e[o])Z(r,i[t[o].source]);return e}(n,e,i)}(this._layers,s,this.sourceCaches,e,l,this.placement.collisionIndex,this.placement.retainedQueryData)),this._flattenAndSortRenderedFeatures(a)}querySourceFeatures(e,i){i&&i.filter&&this._validate(t.z.filter,\"querySourceFeatures.filter\",i.filter,null,i);const o=this.sourceCaches[e];return o?function(e,t){const i=e.getRenderableIds().map((t=>e.getTileByID(t))),o=[],r={};for(let e=0;e<i.length;e++){const a=i[e],s=a.tileID.canonical.key;r[s]||(r[s]=!0,a.querySourceFeatures(o,t));}return o}(o,i):[]}getLight(){return this.light.getLight()}setLight(e,i={}){this._checkLoaded();const o=this.light.getLight();let r=!1;for(const i in e)if(!t.bG(e[i],o[i])){r=!0;break}if(!r)return;const a={now:s.now(),transition:t.e({duration:300,delay:0},this.stylesheet.transition)};this.light.setLight(e,i),this.light.updateTransitions(a);}getProjection(){var e;return null===(e=this.stylesheet)||void 0===e?void 0:e.projection}setProjection(e){if(this._checkLoaded(),this.projection){if(this.projection.name===e.type)return;this.projection.destroy(),delete this.projection;}this.stylesheet.projection=e,this._setProjectionInternal(e.type);}getSky(){var e;return null===(e=this.stylesheet)||void 0===e?void 0:e.sky}setSky(e,i={}){this._checkLoaded();const o=this.getSky();let r=!1;if(!e&&!o)return;if(e&&!o)r=!0;else if(!e&&o)r=!0;else for(const i in e)if(!t.bG(e[i],o[i])){r=!0;break}if(!r)return;const a={now:s.now(),transition:t.e({duration:300,delay:0},this.stylesheet.transition)};this.stylesheet.sky=e,this.sky.setSky(e,i),this.sky.updateTransitions(a);}_setProjectionInternal(e){const i=function(e){if(Array.isArray(e)){const t=new Jt({type:e});return {projection:t,transform:new gi,cameraHelper:new bi(t)}}switch(e){case \"mercator\":return {projection:new It,transform:new Lt,cameraHelper:new Ot};case \"globe\":{const e=new Jt({type:[\"interpolate\",[\"linear\"],[\"zoom\"],11,\"vertical-perspective\",12,\"mercator\"]});return {projection:e,transform:new gi,cameraHelper:new bi(e)}}case \"vertical-perspective\":return {projection:new Yt,transform:new fi,cameraHelper:new vi};default:return t.w(`Unknown projection name: ${e}. Falling back to mercator projection.`),{projection:new It,transform:new Lt,cameraHelper:new Ot}}}(e);this.projection=i.projection,this.map.migrateProjection(i.transform,i.cameraHelper);for(const e in this.sourceCaches)this.sourceCaches[e].reload();}_validate(e,i,o,r,a={}){return (!a||!1!==a.validate)&&xi(this,e.call(t.z,t.e({key:i,style:this.serialize(),value:o,styleSpec:t.v},r)))}_remove(e=!0){this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._loadStyleRequest&&(this._loadStyleRequest.abort(),this._loadStyleRequest=null),this._spriteRequest&&(this._spriteRequest.abort(),this._spriteRequest=null),oe().off(ee,this._rtlPluginLoaded);for(const e in this._layers)this._layers[e].setEventedParent(null);for(const e in this.sourceCaches){const t=this.sourceCaches[e];t.setEventedParent(null),t.onRemove(this.map);}this.imageManager.setEventedParent(null),this.setEventedParent(null),e&&this.dispatcher.broadcast(\"RM\",void 0),this.dispatcher.remove(e);}_clearSource(e){this.sourceCaches[e].clearTiles();}_reloadSource(e){this.sourceCaches[e].resume(),this.sourceCaches[e].reload();}_updateSources(e){for(const t in this.sourceCaches)this.sourceCaches[t].update(e,this.map.terrain);}_generateCollisionBoxes(){for(const e in this.sourceCaches)this._reloadSource(e);}_updatePlacement(e,t,i,o,r=!1){let a=!1,n=!1;const l={};for(const t of this._order){const i=this._layers[t];if(\"symbol\"!==i.type)continue;if(!l[i.source]){const e=this.sourceCaches[i.source];l[i.source]=e.getRenderableIds(!0).map((t=>e.getTileByID(t))).sort(((e,t)=>t.tileID.overscaledZ-e.tileID.overscaledZ||(e.tileID.isLessThan(t.tileID)?-1:1)));}const o=this.crossTileSymbolIndex.addLayer(i,l[i.source],e.center.lng);a=a||o;}if(this.crossTileSymbolIndex.pruneUnusedLayers(this._order),((r=r||this._layerOrderChanged||0===i)||!this.pauseablePlacement||this.pauseablePlacement.isDone()&&!this.placement.stillRecent(s.now(),e.zoom))&&(this.pauseablePlacement=new _t(e,this.map.terrain,this._order,r,t,i,o,this.placement),this._layerOrderChanged=!1),this.pauseablePlacement.isDone()?this.placement.setStale():(this.pauseablePlacement.continuePlacement(this._order,this._layers,l),this.pauseablePlacement.isDone()&&(this.placement=this.pauseablePlacement.commit(s.now()),n=!0),a&&this.pauseablePlacement.placement.setStale()),n||a)for(const e of this._order){const t=this._layers[e];\"symbol\"===t.type&&this.placement.updateLayerOpacities(t,l[t.source]);}return !this.pauseablePlacement.isDone()||this.placement.hasTransitions(s.now())}_releaseSymbolFadeTiles(){for(const e in this.sourceCaches)this.sourceCaches[e].releaseSymbolFadeTiles();}getImages(e,i){return t._(this,void 0,void 0,(function*(){const e=yield this.imageManager.getImages(i.icons);this._updateTilesForChangedImages();const t=this.sourceCaches[i.source];return t&&t.setDependencies(i.tileID.key,i.type,i.icons),e}))}getGlyphs(e,i){return t._(this,void 0,void 0,(function*(){const e=yield this.glyphManager.getGlyphs(i.stacks),t=this.sourceCaches[i.source];return t&&t.setDependencies(i.tileID.key,i.type,[\"\"]),e}))}getGlyphsUrl(){return this.stylesheet.glyphs||null}setGlyphs(e,i={}){this._checkLoaded(),e&&this._validate(t.z.glyphs,\"glyphs\",e,null,i)||(this._glyphsDidChange=!0,this.stylesheet.glyphs=e,this.glyphManager.entries={},this.glyphManager.setURL(e));}addSprite(e,i,o={},r){this._checkLoaded();const a=[{id:e,url:i}],s=[...f(this.stylesheet.sprite),...a];this._validate(t.z.sprite,\"sprite\",s,null,o)||(this.stylesheet.sprite=s,this._loadSprite(a,!0,r));}removeSprite(e){this._checkLoaded();const i=f(this.stylesheet.sprite);if(i.find((t=>t.id===e))){if(this._spritesImagesIds[e])for(const t of this._spritesImagesIds[e])this.imageManager.removeImage(t),this._changedImages[t]=!0;i.splice(i.findIndex((t=>t.id===e)),1),this.stylesheet.sprite=i.length>0?i:void 0,delete this._spritesImagesIds[e],this._availableImages=this.imageManager.listImages(),this._changed=!0,this.dispatcher.broadcast(\"SI\",this._availableImages),this.fire(new t.l(\"data\",{dataType:\"style\"}));}else this.fire(new t.k(new Error(`Sprite \"${e}\" doesn't exists on this map.`)));}getSprite(){return f(this.stylesheet.sprite)}setSprite(e,i={},o){this._checkLoaded(),e&&this._validate(t.z.sprite,\"sprite\",e,null,i)||(this.stylesheet.sprite=e,e?this._loadSprite(e,!0,o):(this._unloadSprite(),o&&o(null)));}}var Ti=t.aI([{name:\"a_pos\",type:\"Int16\",components:2},{name:\"a_texture_pos\",type:\"Int16\",components:2}]);class Pi{constructor(){this.boundProgram=null,this.boundLayoutVertexBuffer=null,this.boundPaintVertexBuffers=[],this.boundIndexBuffer=null,this.boundVertexOffset=null,this.boundDynamicVertexBuffer=null,this.vao=null;}bind(e,t,i,o,r,a,s,n,l){this.context=e;let c=this.boundPaintVertexBuffers.length!==o.length;for(let e=0;!c&&e<o.length;e++)this.boundPaintVertexBuffers[e]!==o[e]&&(c=!0);!this.vao||this.boundProgram!==t||this.boundLayoutVertexBuffer!==i||c||this.boundIndexBuffer!==r||this.boundVertexOffset!==a||this.boundDynamicVertexBuffer!==s||this.boundDynamicVertexBuffer2!==n||this.boundDynamicVertexBuffer3!==l?this.freshBind(t,i,o,r,a,s,n,l):(e.bindVertexArray.set(this.vao),s&&s.bind(),r&&r.dynamicDraw&&r.bind(),n&&n.bind(),l&&l.bind());}freshBind(e,t,i,o,r,a,s,n){const l=e.numAttributes,c=this.context,h=c.gl;this.vao&&this.destroy(),this.vao=c.createVertexArray(),c.bindVertexArray.set(this.vao),this.boundProgram=e,this.boundLayoutVertexBuffer=t,this.boundPaintVertexBuffers=i,this.boundIndexBuffer=o,this.boundVertexOffset=r,this.boundDynamicVertexBuffer=a,this.boundDynamicVertexBuffer2=s,this.boundDynamicVertexBuffer3=n,t.enableAttributes(h,e);for(const t of i)t.enableAttributes(h,e);a&&a.enableAttributes(h,e),s&&s.enableAttributes(h,e),n&&n.enableAttributes(h,e),t.bind(),t.setVertexAttribPointers(h,e,r);for(const t of i)t.bind(),t.setVertexAttribPointers(h,e,r);a&&(a.bind(),a.setVertexAttribPointers(h,e,r)),o&&o.bind(),s&&(s.bind(),s.setVertexAttribPointers(h,e,r)),n&&(n.bind(),n.setVertexAttribPointers(h,e,r)),c.currentNumAttributes=l;}destroy(){this.vao&&(this.context.deleteVertexArray(this.vao),this.vao=null);}}const Ci=(e,i,o,r,a)=>({u_texture:0,u_ele_delta:e,u_fog_matrix:i,u_fog_color:o?o.properties.get(\"fog-color\"):t.be.white,u_fog_ground_blend:o?o.properties.get(\"fog-ground-blend\"):1,u_fog_ground_blend_opacity:a?0:o?o.calculateFogBlendOpacity(r):0,u_horizon_color:o?o.properties.get(\"horizon-color\"):t.be.white,u_horizon_fog_blend:o?o.properties.get(\"horizon-fog-blend\"):1,u_is_globe_mode:a?1:0}),Ii={mainMatrix:\"u_projection_matrix\",tileMercatorCoords:\"u_projection_tile_mercator_coords\",clippingPlane:\"u_projection_clipping_plane\",projectionTransition:\"u_projection_transition\",fallbackMatrix:\"u_projection_fallback_matrix\"};function Mi(e){const t=[];for(let i=0;i<e.length;i++){if(null===e[i])continue;const o=e[i].split(\" \");t.push(o.pop());}return t}class Si{constructor(e,i,o,r,a,s,n,l,c=[]){const h=e.gl;this.program=h.createProgram();const u=Mi(i.staticAttributes),d=o?o.getBinderAttributes():[],_=u.concat(d),p=xt.prelude.staticUniforms?Mi(xt.prelude.staticUniforms):[],m=n.staticUniforms?Mi(n.staticUniforms):[],f=i.staticUniforms?Mi(i.staticUniforms):[],g=o?o.getBinderUniforms():[],v=p.concat(m).concat(f).concat(g),b=[];for(const e of v)b.indexOf(e)<0&&b.push(e);const x=o?o.defines():[];qt(h)&&x.unshift(\"#version 300 es\"),a&&x.push(\"#define OVERDRAW_INSPECTOR;\"),s&&x.push(\"#define TERRAIN3D;\"),l&&x.push(l),c&&x.push(...c);let y=x.concat(xt.prelude.fragmentSource,n.fragmentSource,i.fragmentSource).join(\"\\n\"),w=x.concat(xt.prelude.vertexSource,n.vertexSource,i.vertexSource).join(\"\\n\");qt(h)||(y=function(e){return e.replace(/\\bin\\s/g,\"varying \").replace(\"out highp vec4 fragColor;\",\"\").replace(/fragColor/g,\"gl_FragColor\").replace(/texture\\(/g,\"texture2D(\")}(y),w=function(e){return e.replace(/\\bin\\s/g,\"attribute \").replace(/\\bout\\s/g,\"varying \").replace(/texture\\(/g,\"texture2D(\")}(w));const T=h.createShader(h.FRAGMENT_SHADER);if(h.isContextLost())return void(this.failedToCreate=!0);if(h.shaderSource(T,y),h.compileShader(T),!h.getShaderParameter(T,h.COMPILE_STATUS))throw new Error(`Could not compile fragment shader: ${h.getShaderInfoLog(T)}`);h.attachShader(this.program,T);const P=h.createShader(h.VERTEX_SHADER);if(h.isContextLost())return void(this.failedToCreate=!0);if(h.shaderSource(P,w),h.compileShader(P),!h.getShaderParameter(P,h.COMPILE_STATUS))throw new Error(`Could not compile vertex shader: ${h.getShaderInfoLog(P)}`);h.attachShader(this.program,P),this.attributes={};const C={};this.numAttributes=_.length;for(let e=0;e<this.numAttributes;e++)_[e]&&(h.bindAttribLocation(this.program,e,_[e]),this.attributes[_[e]]=e);if(h.linkProgram(this.program),!h.getProgramParameter(this.program,h.LINK_STATUS))throw new Error(`Program failed to link: ${h.getProgramInfoLog(this.program)}`);h.deleteShader(P),h.deleteShader(T);for(let e=0;e<b.length;e++){const t=b[e];if(t&&!C[t]){const e=h.getUniformLocation(this.program,t);e&&(C[t]=e);}}this.fixedUniforms=r(e,C),this.terrainUniforms=((e,i)=>({u_depth:new t.bO(e,i.u_depth),u_terrain:new t.bO(e,i.u_terrain),u_terrain_dim:new t.bf(e,i.u_terrain_dim),u_terrain_matrix:new t.bQ(e,i.u_terrain_matrix),u_terrain_unpack:new t.bR(e,i.u_terrain_unpack),u_terrain_exaggeration:new t.bf(e,i.u_terrain_exaggeration)}))(e,C),this.projectionUniforms=((e,i)=>({u_projection_matrix:new t.bQ(e,i.u_projection_matrix),u_projection_tile_mercator_coords:new t.bR(e,i.u_projection_tile_mercator_coords),u_projection_clipping_plane:new t.bR(e,i.u_projection_clipping_plane),u_projection_transition:new t.bf(e,i.u_projection_transition),u_projection_fallback_matrix:new t.bQ(e,i.u_projection_fallback_matrix)}))(e,C),this.binderUniforms=o?o.getUniforms(e,C):[];}draw(e,t,i,o,r,a,s,n,l,c,h,u,d,_,p,m,f,g,v){const b=e.gl;if(this.failedToCreate)return;if(e.program.set(this.program),e.setDepthMode(i),e.setStencilMode(o),e.setColorMode(r),e.setCullFace(a),n){e.activeTexture.set(b.TEXTURE2),b.bindTexture(b.TEXTURE_2D,n.depthTexture),e.activeTexture.set(b.TEXTURE3),b.bindTexture(b.TEXTURE_2D,n.texture);for(const e in this.terrainUniforms)this.terrainUniforms[e].set(n[e]);}if(l)for(const e in l)this.projectionUniforms[Ii[e]].set(l[e]);if(s)for(const e in this.fixedUniforms)this.fixedUniforms[e].set(s[e]);m&&m.setUniforms(e,this.binderUniforms,_,{zoom:p});let x=0;switch(t){case b.LINES:x=2;break;case b.TRIANGLES:x=3;break;case b.LINE_STRIP:x=1;}for(const i of d.get()){const o=i.vaos||(i.vaos={});(o[c]||(o[c]=new Pi)).bind(e,this,h,m?m.getPaintVertexBuffers():[],u,i.vertexOffset,f,g,v),b.drawElements(t,i.primitiveLength*x,b.UNSIGNED_SHORT,i.primitiveOffset*x*2);}}}function Ei(e,i,o){const r=1/t.aB(o,1,i.transform.tileZoom),a=Math.pow(2,o.tileID.overscaledZ),s=o.tileSize*Math.pow(2,i.transform.tileZoom)/a,n=s*(o.tileID.canonical.x+o.tileID.wrap*a),l=s*o.tileID.canonical.y;return {u_image:0,u_texsize:o.imageAtlasTexture.size,u_scale:[r,e.fromScale,e.toScale],u_fade:e.t,u_pixel_coord_upper:[n>>16,l>>16],u_pixel_coord_lower:[65535&n,65535&l]}}const Ri=(e,i,o,r)=>{const a=e.style.light,s=a.properties.get(\"position\"),n=[s.x,s.y,s.z],l=t.bU();\"viewport\"===a.properties.get(\"anchor\")&&t.bV(l,e.transform.bearingInRadians),t.bW(n,n,l);const c=e.transform.transformLightDirection(n),h=a.properties.get(\"color\");return {u_lightpos:n,u_lightpos_globe:c,u_lightintensity:a.properties.get(\"intensity\"),u_lightcolor:[h.r,h.g,h.b],u_vertical_gradient:+i,u_opacity:o,u_fill_translate:r}},zi=(e,i,o,r,a,s,n)=>t.e(Ri(e,i,o,r),Ei(s,e,n),{u_height_factor:-Math.pow(2,a.overscaledZ)/n.tileSize/8}),Di=(e,i,o,r)=>t.e(Ei(i,e,o),{u_fill_translate:r}),Ai=(e,t)=>({u_world:e,u_fill_translate:t}),Li=(e,i,o,r,a)=>t.e(Di(e,i,o,a),{u_world:r}),ki=(e,i,o,r,a)=>{const s=e.transform;let n,l,c=0;if(\"map\"===o.paint.get(\"circle-pitch-alignment\")){const e=t.aB(i,1,s.zoom);n=!0,l=[e,e],c=e/(t.$*Math.pow(2,i.tileID.overscaledZ))*2*Math.PI*a;}else n=!1,l=s.pixelsToGLUnits;return {u_camera_to_center_distance:s.cameraToCenterDistance,u_scale_with_map:+(\"map\"===o.paint.get(\"circle-pitch-scale\")),u_pitch_with_map:+n,u_device_pixel_ratio:e.pixelRatio,u_extrude_scale:l,u_globe_extrude_scale:c,u_translate:r}},Fi=e=>({u_pixel_extrude_scale:[1/e.width,1/e.height]}),Bi=e=>({u_viewport_size:[e.width,e.height]}),Oi=(e,t=1)=>({u_color:e,u_overlay:0,u_overlay_scale:t}),ji=(e,i,o,r)=>{const a=t.aB(e,1,i)/(t.$*Math.pow(2,e.tileID.overscaledZ))*2*Math.PI*r;return {u_extrude_scale:t.aB(e,1,i),u_intensity:o,u_globe_extrude_scale:a}},Ni=(e,i,o,r)=>{const a=t.L();t.bX(a,0,e.width,e.height,0,0,1);const s=e.context.gl;return {u_matrix:a,u_world:[s.drawingBufferWidth,s.drawingBufferHeight],u_image:o,u_color_ramp:r,u_opacity:i.paint.get(\"heatmap-opacity\")}},Zi=(e,t,i)=>{const o=i.paint.get(\"hillshade-accent-color\");let r;switch(i.paint.get(\"hillshade-method\")){case \"basic\":r=4;break;case \"combined\":r=1;break;case \"igor\":r=2;break;case \"multidirectional\":r=3;break;default:r=0;}const a=i.getIlluminationProperties();for(let t=0;t<a.directionRadians.length;t++)\"viewport\"===i.paint.get(\"hillshade-illumination-anchor\")&&(a.directionRadians[t]+=e.transform.bearingInRadians);return {u_image:0,u_latrange:Gi(0,t.tileID),u_exaggeration:i.paint.get(\"hillshade-exaggeration\"),u_altitudes:a.altitudeRadians,u_azimuths:a.directionRadians,u_accent:o,u_method:r,u_highlights:a.highlightColor,u_shadows:a.shadowColor}},Ui=(e,i)=>{const o=i.stride,r=t.L();return t.bX(r,0,t.$,-8192,0,0,1),t.M(r,r,[0,-8192,0]),{u_matrix:r,u_image:1,u_dimension:[o,o],u_zoom:e.overscaledZ,u_unpack:i.getUnpackVector()}};function Gi(e,i){const o=Math.pow(2,i.canonical.z),r=i.canonical.y;return [new t.a0(0,r/o).toLngLat().lat,new t.a0(0,(r+1)/o).toLngLat().lat]}const Vi=(e,t)=>({u_image:0,u_unpack:t.getUnpackVector(),u_dimension:[t.stride,t.stride],u_elevation_stops:1,u_color_stops:4,u_opacity:e.paint.get(\"color-relief-opacity\")}),$i=(e,i,o,r)=>{const a=e.transform;return {u_translation:Ki(e,i,o),u_ratio:r/t.aB(i,1,a.zoom),u_device_pixel_ratio:e.pixelRatio,u_units_to_pixels:[1/a.pixelsToGLUnits[0],1/a.pixelsToGLUnits[1]]}},qi=(e,i,o,r,a)=>t.e($i(e,i,o,r),{u_image:0,u_image_height:a}),Wi=(e,i,o,r,a)=>{const s=e.transform,n=Xi(i,s);return {u_translation:Ki(e,i,o),u_texsize:i.imageAtlasTexture.size,u_ratio:r/t.aB(i,1,s.zoom),u_device_pixel_ratio:e.pixelRatio,u_image:0,u_scale:[n,a.fromScale,a.toScale],u_fade:a.t,u_units_to_pixels:[1/s.pixelsToGLUnits[0],1/s.pixelsToGLUnits[1]]}},Hi=(e,i,o,r,a,s)=>{const n=e.lineAtlas,l=Xi(i,e.transform),c=\"round\"===o.layout.get(\"line-cap\"),h=n.getDash(a.from,c),u=n.getDash(a.to,c),d=h.width*s.fromScale,_=u.width*s.toScale;return t.e($i(e,i,o,r),{u_patternscale_a:[l/d,-h.height/2],u_patternscale_b:[l/_,-u.height/2],u_sdfgamma:n.width/(256*Math.min(d,_)*e.pixelRatio)/2,u_image:0,u_tex_y_a:h.y,u_tex_y_b:u.y,u_mix:s.t})};function Xi(e,i){return 1/t.aB(e,1,i.tileZoom)}function Ki(e,i,o){return t.aC(e.transform,i,o.paint.get(\"line-translate\"),o.paint.get(\"line-translate-anchor\"))}const Yi=(e,t,i,o,r)=>{return {u_tl_parent:e,u_scale_parent:t,u_buffer_scale:1,u_fade_t:i.mix,u_opacity:i.opacity*o.paint.get(\"raster-opacity\"),u_image0:0,u_image1:1,u_brightness_low:o.paint.get(\"raster-brightness-min\"),u_brightness_high:o.paint.get(\"raster-brightness-max\"),u_saturation_factor:(s=o.paint.get(\"raster-saturation\"),s>0?1-1/(1.001-s):-s),u_contrast_factor:(a=o.paint.get(\"raster-contrast\"),a>0?1/(1-a):1+a),u_spin_weights:Qi(o.paint.get(\"raster-hue-rotate\")),u_coords_top:[r[0].x,r[0].y,r[1].x,r[1].y],u_coords_bottom:[r[3].x,r[3].y,r[2].x,r[2].y]};var a,s;};function Qi(e){e*=Math.PI/180;const t=Math.sin(e),i=Math.cos(e);return [(2*i+1)/3,(-Math.sqrt(3)*t-i+1)/3,(Math.sqrt(3)*t-i+1)/3]}const Ji=(e,t,i,o,r,a,s,n,l,c,h,u,d)=>{const _=s.transform;return {u_is_size_zoom_constant:+(\"constant\"===e||\"source\"===e),u_is_size_feature_constant:+(\"constant\"===e||\"camera\"===e),u_size_t:t?t.uSizeT:0,u_size:t?t.uSize:0,u_camera_to_center_distance:_.cameraToCenterDistance,u_pitch:_.pitch/360*2*Math.PI,u_rotate_symbol:+i,u_aspect_ratio:_.width/_.height,u_fade_change:s.options.fadeDuration?s.symbolFadeChange:1,u_label_plane_matrix:n,u_coord_matrix:l,u_is_text:+h,u_pitch_with_map:+o,u_is_along_line:r,u_is_variable_anchor:a,u_texsize:u,u_texture:0,u_translation:c,u_pitched_scale:d}},eo=(e,i,o,r,a,s,n,l,c,h,u,d,_,p)=>{const m=n.transform;return t.e(Ji(e,i,o,r,a,s,n,l,c,h,u,d,p),{u_gamma_scale:r?Math.cos(m.pitch*Math.PI/180)*m.cameraToCenterDistance:1,u_device_pixel_ratio:n.pixelRatio,u_is_halo:1})},to=(e,i,o,r,a,s,n,l,c,h,u,d,_)=>t.e(eo(e,i,o,r,a,s,n,l,c,h,!0,u,0,_),{u_texsize_icon:d,u_texture_icon:1}),io=(e,t)=>({u_opacity:e,u_color:t}),oo=(e,i,o,r,a)=>t.e(function(e,i,o,r){const a=o.imageManager.getPattern(e.from.toString()),s=o.imageManager.getPattern(e.to.toString()),{width:n,height:l}=o.imageManager.getPixelSize(),c=Math.pow(2,r.tileID.overscaledZ),h=r.tileSize*Math.pow(2,o.transform.tileZoom)/c,u=h*(r.tileID.canonical.x+r.tileID.wrap*c),d=h*r.tileID.canonical.y;return {u_image:0,u_pattern_tl_a:a.tl,u_pattern_br_a:a.br,u_pattern_tl_b:s.tl,u_pattern_br_b:s.br,u_texsize:[n,l],u_mix:i.t,u_pattern_size_a:a.displaySize,u_pattern_size_b:s.displaySize,u_scale_a:i.fromScale,u_scale_b:i.toScale,u_tile_units_to_pixels:1/t.aB(r,1,o.transform.tileZoom),u_pixel_coord_upper:[u>>16,d>>16],u_pixel_coord_lower:[65535&u,65535&d]}}(o,a,i,r),{u_opacity:e}),ro=(e,t)=>{},ao={fillExtrusion:(e,i)=>({u_lightpos:new t.bS(e,i.u_lightpos),u_lightpos_globe:new t.bS(e,i.u_lightpos_globe),u_lightintensity:new t.bf(e,i.u_lightintensity),u_lightcolor:new t.bS(e,i.u_lightcolor),u_vertical_gradient:new t.bf(e,i.u_vertical_gradient),u_opacity:new t.bf(e,i.u_opacity),u_fill_translate:new t.bT(e,i.u_fill_translate)}),fillExtrusionPattern:(e,i)=>({u_lightpos:new t.bS(e,i.u_lightpos),u_lightpos_globe:new t.bS(e,i.u_lightpos_globe),u_lightintensity:new t.bf(e,i.u_lightintensity),u_lightcolor:new t.bS(e,i.u_lightcolor),u_vertical_gradient:new t.bf(e,i.u_vertical_gradient),u_height_factor:new t.bf(e,i.u_height_factor),u_opacity:new t.bf(e,i.u_opacity),u_fill_translate:new t.bT(e,i.u_fill_translate),u_image:new t.bO(e,i.u_image),u_texsize:new t.bT(e,i.u_texsize),u_pixel_coord_upper:new t.bT(e,i.u_pixel_coord_upper),u_pixel_coord_lower:new t.bT(e,i.u_pixel_coord_lower),u_scale:new t.bS(e,i.u_scale),u_fade:new t.bf(e,i.u_fade)}),fill:(e,i)=>({u_fill_translate:new t.bT(e,i.u_fill_translate)}),fillPattern:(e,i)=>({u_image:new t.bO(e,i.u_image),u_texsize:new t.bT(e,i.u_texsize),u_pixel_coord_upper:new t.bT(e,i.u_pixel_coord_upper),u_pixel_coord_lower:new t.bT(e,i.u_pixel_coord_lower),u_scale:new t.bS(e,i.u_scale),u_fade:new t.bf(e,i.u_fade),u_fill_translate:new t.bT(e,i.u_fill_translate)}),fillOutline:(e,i)=>({u_world:new t.bT(e,i.u_world),u_fill_translate:new t.bT(e,i.u_fill_translate)}),fillOutlinePattern:(e,i)=>({u_world:new t.bT(e,i.u_world),u_image:new t.bO(e,i.u_image),u_texsize:new t.bT(e,i.u_texsize),u_pixel_coord_upper:new t.bT(e,i.u_pixel_coord_upper),u_pixel_coord_lower:new t.bT(e,i.u_pixel_coord_lower),u_scale:new t.bS(e,i.u_scale),u_fade:new t.bf(e,i.u_fade),u_fill_translate:new t.bT(e,i.u_fill_translate)}),circle:(e,i)=>({u_camera_to_center_distance:new t.bf(e,i.u_camera_to_center_distance),u_scale_with_map:new t.bO(e,i.u_scale_with_map),u_pitch_with_map:new t.bO(e,i.u_pitch_with_map),u_extrude_scale:new t.bT(e,i.u_extrude_scale),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_globe_extrude_scale:new t.bf(e,i.u_globe_extrude_scale),u_translate:new t.bT(e,i.u_translate)}),collisionBox:(e,i)=>({u_pixel_extrude_scale:new t.bT(e,i.u_pixel_extrude_scale)}),collisionCircle:(e,i)=>({u_viewport_size:new t.bT(e,i.u_viewport_size)}),debug:(e,i)=>({u_color:new t.bP(e,i.u_color),u_overlay:new t.bO(e,i.u_overlay),u_overlay_scale:new t.bf(e,i.u_overlay_scale)}),depth:ro,clippingMask:ro,heatmap:(e,i)=>({u_extrude_scale:new t.bf(e,i.u_extrude_scale),u_intensity:new t.bf(e,i.u_intensity),u_globe_extrude_scale:new t.bf(e,i.u_globe_extrude_scale)}),heatmapTexture:(e,i)=>({u_matrix:new t.bQ(e,i.u_matrix),u_world:new t.bT(e,i.u_world),u_image:new t.bO(e,i.u_image),u_color_ramp:new t.bO(e,i.u_color_ramp),u_opacity:new t.bf(e,i.u_opacity)}),hillshade:(e,i)=>({u_image:new t.bO(e,i.u_image),u_latrange:new t.bT(e,i.u_latrange),u_exaggeration:new t.bf(e,i.u_exaggeration),u_altitudes:new t.bZ(e,i.u_altitudes),u_azimuths:new t.bZ(e,i.u_azimuths),u_accent:new t.bP(e,i.u_accent),u_method:new t.bO(e,i.u_method),u_shadows:new t.bY(e,i.u_shadows),u_highlights:new t.bY(e,i.u_highlights)}),hillshadePrepare:(e,i)=>({u_matrix:new t.bQ(e,i.u_matrix),u_image:new t.bO(e,i.u_image),u_dimension:new t.bT(e,i.u_dimension),u_zoom:new t.bf(e,i.u_zoom),u_unpack:new t.bR(e,i.u_unpack)}),colorRelief:(e,i)=>({u_image:new t.bO(e,i.u_image),u_unpack:new t.bR(e,i.u_unpack),u_dimension:new t.bT(e,i.u_dimension),u_elevation_stops:new t.bO(e,i.u_elevation_stops),u_color_stops:new t.bO(e,i.u_color_stops),u_opacity:new t.bf(e,i.u_opacity)}),line:(e,i)=>({u_translation:new t.bT(e,i.u_translation),u_ratio:new t.bf(e,i.u_ratio),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_units_to_pixels:new t.bT(e,i.u_units_to_pixels)}),lineGradient:(e,i)=>({u_translation:new t.bT(e,i.u_translation),u_ratio:new t.bf(e,i.u_ratio),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_units_to_pixels:new t.bT(e,i.u_units_to_pixels),u_image:new t.bO(e,i.u_image),u_image_height:new t.bf(e,i.u_image_height)}),linePattern:(e,i)=>({u_translation:new t.bT(e,i.u_translation),u_texsize:new t.bT(e,i.u_texsize),u_ratio:new t.bf(e,i.u_ratio),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_image:new t.bO(e,i.u_image),u_units_to_pixels:new t.bT(e,i.u_units_to_pixels),u_scale:new t.bS(e,i.u_scale),u_fade:new t.bf(e,i.u_fade)}),lineSDF:(e,i)=>({u_translation:new t.bT(e,i.u_translation),u_ratio:new t.bf(e,i.u_ratio),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_units_to_pixels:new t.bT(e,i.u_units_to_pixels),u_patternscale_a:new t.bT(e,i.u_patternscale_a),u_patternscale_b:new t.bT(e,i.u_patternscale_b),u_sdfgamma:new t.bf(e,i.u_sdfgamma),u_image:new t.bO(e,i.u_image),u_tex_y_a:new t.bf(e,i.u_tex_y_a),u_tex_y_b:new t.bf(e,i.u_tex_y_b),u_mix:new t.bf(e,i.u_mix)}),raster:(e,i)=>({u_tl_parent:new t.bT(e,i.u_tl_parent),u_scale_parent:new t.bf(e,i.u_scale_parent),u_buffer_scale:new t.bf(e,i.u_buffer_scale),u_fade_t:new t.bf(e,i.u_fade_t),u_opacity:new t.bf(e,i.u_opacity),u_image0:new t.bO(e,i.u_image0),u_image1:new t.bO(e,i.u_image1),u_brightness_low:new t.bf(e,i.u_brightness_low),u_brightness_high:new t.bf(e,i.u_brightness_high),u_saturation_factor:new t.bf(e,i.u_saturation_factor),u_contrast_factor:new t.bf(e,i.u_contrast_factor),u_spin_weights:new t.bS(e,i.u_spin_weights),u_coords_top:new t.bR(e,i.u_coords_top),u_coords_bottom:new t.bR(e,i.u_coords_bottom)}),symbolIcon:(e,i)=>({u_is_size_zoom_constant:new t.bO(e,i.u_is_size_zoom_constant),u_is_size_feature_constant:new t.bO(e,i.u_is_size_feature_constant),u_size_t:new t.bf(e,i.u_size_t),u_size:new t.bf(e,i.u_size),u_camera_to_center_distance:new t.bf(e,i.u_camera_to_center_distance),u_pitch:new t.bf(e,i.u_pitch),u_rotate_symbol:new t.bO(e,i.u_rotate_symbol),u_aspect_ratio:new t.bf(e,i.u_aspect_ratio),u_fade_change:new t.bf(e,i.u_fade_change),u_label_plane_matrix:new t.bQ(e,i.u_label_plane_matrix),u_coord_matrix:new t.bQ(e,i.u_coord_matrix),u_is_text:new t.bO(e,i.u_is_text),u_pitch_with_map:new t.bO(e,i.u_pitch_with_map),u_is_along_line:new t.bO(e,i.u_is_along_line),u_is_variable_anchor:new t.bO(e,i.u_is_variable_anchor),u_texsize:new t.bT(e,i.u_texsize),u_texture:new t.bO(e,i.u_texture),u_translation:new t.bT(e,i.u_translation),u_pitched_scale:new t.bf(e,i.u_pitched_scale)}),symbolSDF:(e,i)=>({u_is_size_zoom_constant:new t.bO(e,i.u_is_size_zoom_constant),u_is_size_feature_constant:new t.bO(e,i.u_is_size_feature_constant),u_size_t:new t.bf(e,i.u_size_t),u_size:new t.bf(e,i.u_size),u_camera_to_center_distance:new t.bf(e,i.u_camera_to_center_distance),u_pitch:new t.bf(e,i.u_pitch),u_rotate_symbol:new t.bO(e,i.u_rotate_symbol),u_aspect_ratio:new t.bf(e,i.u_aspect_ratio),u_fade_change:new t.bf(e,i.u_fade_change),u_label_plane_matrix:new t.bQ(e,i.u_label_plane_matrix),u_coord_matrix:new t.bQ(e,i.u_coord_matrix),u_is_text:new t.bO(e,i.u_is_text),u_pitch_with_map:new t.bO(e,i.u_pitch_with_map),u_is_along_line:new t.bO(e,i.u_is_along_line),u_is_variable_anchor:new t.bO(e,i.u_is_variable_anchor),u_texsize:new t.bT(e,i.u_texsize),u_texture:new t.bO(e,i.u_texture),u_gamma_scale:new t.bf(e,i.u_gamma_scale),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_is_halo:new t.bO(e,i.u_is_halo),u_translation:new t.bT(e,i.u_translation),u_pitched_scale:new t.bf(e,i.u_pitched_scale)}),symbolTextAndIcon:(e,i)=>({u_is_size_zoom_constant:new t.bO(e,i.u_is_size_zoom_constant),u_is_size_feature_constant:new t.bO(e,i.u_is_size_feature_constant),u_size_t:new t.bf(e,i.u_size_t),u_size:new t.bf(e,i.u_size),u_camera_to_center_distance:new t.bf(e,i.u_camera_to_center_distance),u_pitch:new t.bf(e,i.u_pitch),u_rotate_symbol:new t.bO(e,i.u_rotate_symbol),u_aspect_ratio:new t.bf(e,i.u_aspect_ratio),u_fade_change:new t.bf(e,i.u_fade_change),u_label_plane_matrix:new t.bQ(e,i.u_label_plane_matrix),u_coord_matrix:new t.bQ(e,i.u_coord_matrix),u_is_text:new t.bO(e,i.u_is_text),u_pitch_with_map:new t.bO(e,i.u_pitch_with_map),u_is_along_line:new t.bO(e,i.u_is_along_line),u_is_variable_anchor:new t.bO(e,i.u_is_variable_anchor),u_texsize:new t.bT(e,i.u_texsize),u_texsize_icon:new t.bT(e,i.u_texsize_icon),u_texture:new t.bO(e,i.u_texture),u_texture_icon:new t.bO(e,i.u_texture_icon),u_gamma_scale:new t.bf(e,i.u_gamma_scale),u_device_pixel_ratio:new t.bf(e,i.u_device_pixel_ratio),u_is_halo:new t.bO(e,i.u_is_halo),u_translation:new t.bT(e,i.u_translation),u_pitched_scale:new t.bf(e,i.u_pitched_scale)}),background:(e,i)=>({u_opacity:new t.bf(e,i.u_opacity),u_color:new t.bP(e,i.u_color)}),backgroundPattern:(e,i)=>({u_opacity:new t.bf(e,i.u_opacity),u_image:new t.bO(e,i.u_image),u_pattern_tl_a:new t.bT(e,i.u_pattern_tl_a),u_pattern_br_a:new t.bT(e,i.u_pattern_br_a),u_pattern_tl_b:new t.bT(e,i.u_pattern_tl_b),u_pattern_br_b:new t.bT(e,i.u_pattern_br_b),u_texsize:new t.bT(e,i.u_texsize),u_mix:new t.bf(e,i.u_mix),u_pattern_size_a:new t.bT(e,i.u_pattern_size_a),u_pattern_size_b:new t.bT(e,i.u_pattern_size_b),u_scale_a:new t.bf(e,i.u_scale_a),u_scale_b:new t.bf(e,i.u_scale_b),u_pixel_coord_upper:new t.bT(e,i.u_pixel_coord_upper),u_pixel_coord_lower:new t.bT(e,i.u_pixel_coord_lower),u_tile_units_to_pixels:new t.bf(e,i.u_tile_units_to_pixels)}),terrain:(e,i)=>({u_texture:new t.bO(e,i.u_texture),u_ele_delta:new t.bf(e,i.u_ele_delta),u_fog_matrix:new t.bQ(e,i.u_fog_matrix),u_fog_color:new t.bP(e,i.u_fog_color),u_fog_ground_blend:new t.bf(e,i.u_fog_ground_blend),u_fog_ground_blend_opacity:new t.bf(e,i.u_fog_ground_blend_opacity),u_horizon_color:new t.bP(e,i.u_horizon_color),u_horizon_fog_blend:new t.bf(e,i.u_horizon_fog_blend),u_is_globe_mode:new t.bf(e,i.u_is_globe_mode)}),terrainDepth:(e,i)=>({u_ele_delta:new t.bf(e,i.u_ele_delta)}),terrainCoords:(e,i)=>({u_texture:new t.bO(e,i.u_texture),u_terrain_coords_id:new t.bf(e,i.u_terrain_coords_id),u_ele_delta:new t.bf(e,i.u_ele_delta)}),projectionErrorMeasurement:(e,i)=>({u_input:new t.bf(e,i.u_input),u_output_expected:new t.bf(e,i.u_output_expected)}),atmosphere:(e,i)=>({u_sun_pos:new t.bS(e,i.u_sun_pos),u_atmosphere_blend:new t.bf(e,i.u_atmosphere_blend),u_globe_position:new t.bS(e,i.u_globe_position),u_globe_radius:new t.bf(e,i.u_globe_radius),u_inv_proj_matrix:new t.bQ(e,i.u_inv_proj_matrix)}),sky:(e,i)=>({u_sky_color:new t.bP(e,i.u_sky_color),u_horizon_color:new t.bP(e,i.u_horizon_color),u_horizon:new t.bT(e,i.u_horizon),u_horizon_normal:new t.bT(e,i.u_horizon_normal),u_sky_horizon_blend:new t.bf(e,i.u_sky_horizon_blend),u_sky_blend:new t.bf(e,i.u_sky_blend)})};class so{constructor(e,t,i){this.context=e;const o=e.gl;this.buffer=o.createBuffer(),this.dynamicDraw=Boolean(i),this.context.unbindVAO(),e.bindElementBuffer.set(this.buffer),o.bufferData(o.ELEMENT_ARRAY_BUFFER,t.arrayBuffer,this.dynamicDraw?o.DYNAMIC_DRAW:o.STATIC_DRAW),this.dynamicDraw||delete t.arrayBuffer;}bind(){this.context.bindElementBuffer.set(this.buffer);}updateData(e){const t=this.context.gl;if(!this.dynamicDraw)throw new Error(\"Attempted to update data while not in dynamic mode.\");this.context.unbindVAO(),this.bind(),t.bufferSubData(t.ELEMENT_ARRAY_BUFFER,0,e.arrayBuffer);}destroy(){this.buffer&&(this.context.gl.deleteBuffer(this.buffer),delete this.buffer);}}const no={Int8:\"BYTE\",Uint8:\"UNSIGNED_BYTE\",Int16:\"SHORT\",Uint16:\"UNSIGNED_SHORT\",Int32:\"INT\",Uint32:\"UNSIGNED_INT\",Float32:\"FLOAT\"};class lo{constructor(e,t,i,o){this.length=t.length,this.attributes=i,this.itemSize=t.bytesPerElement,this.dynamicDraw=o,this.context=e;const r=e.gl;this.buffer=r.createBuffer(),e.bindVertexBuffer.set(this.buffer),r.bufferData(r.ARRAY_BUFFER,t.arrayBuffer,this.dynamicDraw?r.DYNAMIC_DRAW:r.STATIC_DRAW),this.dynamicDraw||delete t.arrayBuffer;}bind(){this.context.bindVertexBuffer.set(this.buffer);}updateData(e){if(e.length!==this.length)throw new Error(`Length of new data is ${e.length}, which doesn't match current length of ${this.length}`);const t=this.context.gl;this.bind(),t.bufferSubData(t.ARRAY_BUFFER,0,e.arrayBuffer);}enableAttributes(e,t){for(let i=0;i<this.attributes.length;i++){const o=t.attributes[this.attributes[i].name];void 0!==o&&e.enableVertexAttribArray(o);}}setVertexAttribPointers(e,t,i){for(let o=0;o<this.attributes.length;o++){const r=this.attributes[o],a=t.attributes[r.name];void 0!==a&&e.vertexAttribPointer(a,r.components,e[no[r.type]],!1,this.itemSize,r.offset+this.itemSize*(i||0));}}destroy(){this.buffer&&(this.context.gl.deleteBuffer(this.buffer),delete this.buffer);}}class co{constructor(e){this.gl=e.gl,this.default=this.getDefault(),this.current=this.default,this.dirty=!1;}get(){return this.current}set(e){}getDefault(){return this.default}setDefault(){this.set(this.default);}}class ho extends co{getDefault(){return t.be.transparent}set(e){const t=this.current;(e.r!==t.r||e.g!==t.g||e.b!==t.b||e.a!==t.a||this.dirty)&&(this.gl.clearColor(e.r,e.g,e.b,e.a),this.current=e,this.dirty=!1);}}class uo extends co{getDefault(){return 1}set(e){(e!==this.current||this.dirty)&&(this.gl.clearDepth(e),this.current=e,this.dirty=!1);}}class _o extends co{getDefault(){return 0}set(e){(e!==this.current||this.dirty)&&(this.gl.clearStencil(e),this.current=e,this.dirty=!1);}}class po extends co{getDefault(){return [!0,!0,!0,!0]}set(e){const t=this.current;(e[0]!==t[0]||e[1]!==t[1]||e[2]!==t[2]||e[3]!==t[3]||this.dirty)&&(this.gl.colorMask(e[0],e[1],e[2],e[3]),this.current=e,this.dirty=!1);}}class mo extends co{getDefault(){return !0}set(e){(e!==this.current||this.dirty)&&(this.gl.depthMask(e),this.current=e,this.dirty=!1);}}class fo extends co{getDefault(){return 255}set(e){(e!==this.current||this.dirty)&&(this.gl.stencilMask(e),this.current=e,this.dirty=!1);}}class go extends co{getDefault(){return {func:this.gl.ALWAYS,ref:0,mask:255}}set(e){const t=this.current;(e.func!==t.func||e.ref!==t.ref||e.mask!==t.mask||this.dirty)&&(this.gl.stencilFunc(e.func,e.ref,e.mask),this.current=e,this.dirty=!1);}}class vo extends co{getDefault(){const e=this.gl;return [e.KEEP,e.KEEP,e.KEEP]}set(e){const t=this.current;(e[0]!==t[0]||e[1]!==t[1]||e[2]!==t[2]||this.dirty)&&(this.gl.stencilOp(e[0],e[1],e[2]),this.current=e,this.dirty=!1);}}class bo extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;e?t.enable(t.STENCIL_TEST):t.disable(t.STENCIL_TEST),this.current=e,this.dirty=!1;}}class xo extends co{getDefault(){return [0,1]}set(e){const t=this.current;(e[0]!==t[0]||e[1]!==t[1]||this.dirty)&&(this.gl.depthRange(e[0],e[1]),this.current=e,this.dirty=!1);}}class yo extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;e?t.enable(t.DEPTH_TEST):t.disable(t.DEPTH_TEST),this.current=e,this.dirty=!1;}}class wo extends co{getDefault(){return this.gl.LESS}set(e){(e!==this.current||this.dirty)&&(this.gl.depthFunc(e),this.current=e,this.dirty=!1);}}class To extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;e?t.enable(t.BLEND):t.disable(t.BLEND),this.current=e,this.dirty=!1;}}class Po extends co{getDefault(){const e=this.gl;return [e.ONE,e.ZERO]}set(e){const t=this.current;(e[0]!==t[0]||e[1]!==t[1]||this.dirty)&&(this.gl.blendFunc(e[0],e[1]),this.current=e,this.dirty=!1);}}class Co extends co{getDefault(){return t.be.transparent}set(e){const t=this.current;(e.r!==t.r||e.g!==t.g||e.b!==t.b||e.a!==t.a||this.dirty)&&(this.gl.blendColor(e.r,e.g,e.b,e.a),this.current=e,this.dirty=!1);}}class Io extends co{getDefault(){return this.gl.FUNC_ADD}set(e){(e!==this.current||this.dirty)&&(this.gl.blendEquation(e),this.current=e,this.dirty=!1);}}class Mo extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;e?t.enable(t.CULL_FACE):t.disable(t.CULL_FACE),this.current=e,this.dirty=!1;}}class So extends co{getDefault(){return this.gl.BACK}set(e){(e!==this.current||this.dirty)&&(this.gl.cullFace(e),this.current=e,this.dirty=!1);}}class Eo extends co{getDefault(){return this.gl.CCW}set(e){(e!==this.current||this.dirty)&&(this.gl.frontFace(e),this.current=e,this.dirty=!1);}}class Ro extends co{getDefault(){return null}set(e){(e!==this.current||this.dirty)&&(this.gl.useProgram(e),this.current=e,this.dirty=!1);}}class zo extends co{getDefault(){return this.gl.TEXTURE0}set(e){(e!==this.current||this.dirty)&&(this.gl.activeTexture(e),this.current=e,this.dirty=!1);}}class Do extends co{getDefault(){const e=this.gl;return [0,0,e.drawingBufferWidth,e.drawingBufferHeight]}set(e){const t=this.current;(e[0]!==t[0]||e[1]!==t[1]||e[2]!==t[2]||e[3]!==t[3]||this.dirty)&&(this.gl.viewport(e[0],e[1],e[2],e[3]),this.current=e,this.dirty=!1);}}class Ao extends co{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.bindFramebuffer(t.FRAMEBUFFER,e),this.current=e,this.dirty=!1;}}class Lo extends co{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.bindRenderbuffer(t.RENDERBUFFER,e),this.current=e,this.dirty=!1;}}class ko extends co{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.bindTexture(t.TEXTURE_2D,e),this.current=e,this.dirty=!1;}}class Fo extends co{getDefault(){return null}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.bindBuffer(t.ARRAY_BUFFER,e),this.current=e,this.dirty=!1;}}class Bo extends co{getDefault(){return null}set(e){const t=this.gl;t.bindBuffer(t.ELEMENT_ARRAY_BUFFER,e),this.current=e,this.dirty=!1;}}class Oo extends co{getDefault(){return null}set(e){var t;if(e===this.current&&!this.dirty)return;const i=this.gl;qt(i)?i.bindVertexArray(e):null===(t=i.getExtension(\"OES_vertex_array_object\"))||void 0===t||t.bindVertexArrayOES(e),this.current=e,this.dirty=!1;}}class jo extends co{getDefault(){return 4}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.pixelStorei(t.UNPACK_ALIGNMENT,e),this.current=e,this.dirty=!1;}}class No extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.pixelStorei(t.UNPACK_PREMULTIPLY_ALPHA_WEBGL,e),this.current=e,this.dirty=!1;}}class Zo extends co{getDefault(){return !1}set(e){if(e===this.current&&!this.dirty)return;const t=this.gl;t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL,e),this.current=e,this.dirty=!1;}}class Uo extends co{constructor(e,t){super(e),this.context=e,this.parent=t;}getDefault(){return null}}class Go extends Uo{setDirty(){this.dirty=!0;}set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);const t=this.gl;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_2D,e,0),this.current=e,this.dirty=!1;}}class Vo extends Uo{set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);const t=this.gl;t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_ATTACHMENT,t.RENDERBUFFER,e),this.current=e,this.dirty=!1;}}class $o extends Uo{set(e){if(e===this.current&&!this.dirty)return;this.context.bindFramebuffer.set(this.parent);const t=this.gl;t.framebufferRenderbuffer(t.FRAMEBUFFER,t.DEPTH_STENCIL_ATTACHMENT,t.RENDERBUFFER,e),this.current=e,this.dirty=!1;}}const qo=\"Framebuffer is not complete\";class Wo{constructor(e,t,i,o,r){this.context=e,this.width=t,this.height=i;const a=e.gl,s=this.framebuffer=a.createFramebuffer();if(this.colorAttachment=new Go(e,s),o)this.depthAttachment=r?new $o(e,s):new Vo(e,s);else if(r)throw new Error(\"Stencil cannot be set without depth\");if(a.checkFramebufferStatus(a.FRAMEBUFFER)!==a.FRAMEBUFFER_COMPLETE)throw new Error(qo)}destroy(){const e=this.context.gl,t=this.colorAttachment.get();if(t&&e.deleteTexture(t),this.depthAttachment){const t=this.depthAttachment.get();t&&e.deleteRenderbuffer(t);}e.deleteFramebuffer(this.framebuffer);}}class Ho{constructor(e){var t,i;if(this.gl=e,this.clearColor=new ho(this),this.clearDepth=new uo(this),this.clearStencil=new _o(this),this.colorMask=new po(this),this.depthMask=new mo(this),this.stencilMask=new fo(this),this.stencilFunc=new go(this),this.stencilOp=new vo(this),this.stencilTest=new bo(this),this.depthRange=new xo(this),this.depthTest=new yo(this),this.depthFunc=new wo(this),this.blend=new To(this),this.blendFunc=new Po(this),this.blendColor=new Co(this),this.blendEquation=new Io(this),this.cullFace=new Mo(this),this.cullFaceSide=new So(this),this.frontFace=new Eo(this),this.program=new Ro(this),this.activeTexture=new zo(this),this.viewport=new Do(this),this.bindFramebuffer=new Ao(this),this.bindRenderbuffer=new Lo(this),this.bindTexture=new ko(this),this.bindVertexBuffer=new Fo(this),this.bindElementBuffer=new Bo(this),this.bindVertexArray=new Oo(this),this.pixelStoreUnpack=new jo(this),this.pixelStoreUnpackPremultiplyAlpha=new No(this),this.pixelStoreUnpackFlipY=new Zo(this),this.extTextureFilterAnisotropic=e.getExtension(\"EXT_texture_filter_anisotropic\")||e.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||e.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\"),this.extTextureFilterAnisotropic&&(this.extTextureFilterAnisotropicMax=e.getParameter(this.extTextureFilterAnisotropic.MAX_TEXTURE_MAX_ANISOTROPY_EXT)),this.maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),qt(e)){this.HALF_FLOAT=e.HALF_FLOAT;const o=e.getExtension(\"EXT_color_buffer_half_float\");this.RGBA16F=null!==(t=e.RGBA16F)&&void 0!==t?t:null==o?void 0:o.RGBA16F_EXT,this.RGB16F=null!==(i=e.RGB16F)&&void 0!==i?i:null==o?void 0:o.RGB16F_EXT,e.getExtension(\"EXT_color_buffer_float\");}else {e.getExtension(\"EXT_color_buffer_half_float\"),e.getExtension(\"OES_texture_half_float_linear\");const t=e.getExtension(\"OES_texture_half_float\");this.HALF_FLOAT=null==t?void 0:t.HALF_FLOAT_OES;}}setDefault(){this.unbindVAO(),this.clearColor.setDefault(),this.clearDepth.setDefault(),this.clearStencil.setDefault(),this.colorMask.setDefault(),this.depthMask.setDefault(),this.stencilMask.setDefault(),this.stencilFunc.setDefault(),this.stencilOp.setDefault(),this.stencilTest.setDefault(),this.depthRange.setDefault(),this.depthTest.setDefault(),this.depthFunc.setDefault(),this.blend.setDefault(),this.blendFunc.setDefault(),this.blendColor.setDefault(),this.blendEquation.setDefault(),this.cullFace.setDefault(),this.cullFaceSide.setDefault(),this.frontFace.setDefault(),this.program.setDefault(),this.activeTexture.setDefault(),this.bindFramebuffer.setDefault(),this.pixelStoreUnpack.setDefault(),this.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.pixelStoreUnpackFlipY.setDefault();}setDirty(){this.clearColor.dirty=!0,this.clearDepth.dirty=!0,this.clearStencil.dirty=!0,this.colorMask.dirty=!0,this.depthMask.dirty=!0,this.stencilMask.dirty=!0,this.stencilFunc.dirty=!0,this.stencilOp.dirty=!0,this.stencilTest.dirty=!0,this.depthRange.dirty=!0,this.depthTest.dirty=!0,this.depthFunc.dirty=!0,this.blend.dirty=!0,this.blendFunc.dirty=!0,this.blendColor.dirty=!0,this.blendEquation.dirty=!0,this.cullFace.dirty=!0,this.cullFaceSide.dirty=!0,this.frontFace.dirty=!0,this.program.dirty=!0,this.activeTexture.dirty=!0,this.viewport.dirty=!0,this.bindFramebuffer.dirty=!0,this.bindRenderbuffer.dirty=!0,this.bindTexture.dirty=!0,this.bindVertexBuffer.dirty=!0,this.bindElementBuffer.dirty=!0,this.bindVertexArray.dirty=!0,this.pixelStoreUnpack.dirty=!0,this.pixelStoreUnpackPremultiplyAlpha.dirty=!0,this.pixelStoreUnpackFlipY.dirty=!0;}createIndexBuffer(e,t){return new so(this,e,t)}createVertexBuffer(e,t,i){return new lo(this,e,t,i)}createRenderbuffer(e,t,i){const o=this.gl,r=o.createRenderbuffer();return this.bindRenderbuffer.set(r),o.renderbufferStorage(o.RENDERBUFFER,e,t,i),this.bindRenderbuffer.set(null),r}createFramebuffer(e,t,i,o){return new Wo(this,e,t,i,o)}clear({color:e,depth:t,stencil:i}){const o=this.gl;let r=0;e&&(r|=o.COLOR_BUFFER_BIT,this.clearColor.set(e),this.colorMask.set([!0,!0,!0,!0])),void 0!==t&&(r|=o.DEPTH_BUFFER_BIT,this.depthRange.set([0,1]),this.clearDepth.set(t),this.depthMask.set(!0)),void 0!==i&&(r|=o.STENCIL_BUFFER_BIT,this.clearStencil.set(i),this.stencilMask.set(255)),o.clear(r);}setCullFace(e){!1===e.enable?this.cullFace.set(!1):(this.cullFace.set(!0),this.cullFaceSide.set(e.mode),this.frontFace.set(e.frontFace));}setDepthMode(e){e.func!==this.gl.ALWAYS||e.mask?(this.depthTest.set(!0),this.depthFunc.set(e.func),this.depthMask.set(e.mask),this.depthRange.set(e.range)):this.depthTest.set(!1);}setStencilMode(e){e.test.func!==this.gl.ALWAYS||e.mask?(this.stencilTest.set(!0),this.stencilMask.set(e.mask),this.stencilOp.set([e.fail,e.depthFail,e.pass]),this.stencilFunc.set({func:e.test.func,ref:e.ref,mask:e.test.mask})):this.stencilTest.set(!1);}setColorMode(e){t.bG(e.blendFunction,jt.Replace)?this.blend.set(!1):(this.blend.set(!0),this.blendFunc.set(e.blendFunction),this.blendColor.set(e.blendColor)),this.colorMask.set(e.mask);}createVertexArray(){var e;return qt(this.gl)?this.gl.createVertexArray():null===(e=this.gl.getExtension(\"OES_vertex_array_object\"))||void 0===e?void 0:e.createVertexArrayOES()}deleteVertexArray(e){var t;return qt(this.gl)?this.gl.deleteVertexArray(e):null===(t=this.gl.getExtension(\"OES_vertex_array_object\"))||void 0===t?void 0:t.deleteVertexArrayOES(e)}unbindVAO(){this.bindVertexArray.set(null);}}let Xo;function Ko(e,i,o,r,a){const s=e.context,n=e.transform,l=s.gl,c=e.useProgram(\"collisionBox\"),h=[];let u=0,d=0;for(let t=0;t<r.length;t++){const _=r[t],p=i.getTile(_).getBucket(o);if(!p)continue;const m=a?p.textCollisionBox:p.iconCollisionBox,f=p.collisionCircleArray;f.length>0&&(h.push({circleArray:f,circleOffset:d,coord:_}),u+=f.length/4,d=u),m&&c.draw(s,l.LINES,Ut.disabled,Vt.disabled,e.colorModeForRenderPass(),Zt.disabled,Fi(e.transform),e.style.map.terrain&&e.style.map.terrain.getTerrainData(_),n.getProjectionData({overscaledTileID:_,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),o.id,m.layoutVertexBuffer,m.indexBuffer,m.segments,null,e.transform.zoom,null,null,m.collisionVertexBuffer);}if(!a||!h.length)return;const _=e.useProgram(\"collisionCircle\"),p=new t.b_;p.resize(4*u),p._trim();let m=0;for(const e of h)for(let t=0;t<e.circleArray.length/4;t++){const i=4*t,o=e.circleArray[i+0],r=e.circleArray[i+1],a=e.circleArray[i+2],s=e.circleArray[i+3];p.emplace(m++,o,r,a,s,0),p.emplace(m++,o,r,a,s,1),p.emplace(m++,o,r,a,s,2),p.emplace(m++,o,r,a,s,3);}(!Xo||Xo.length<2*u)&&(Xo=function(e){const i=2*e,o=new t.c0;o.resize(i),o._trim();for(let e=0;e<i;e++){const t=6*e;o.uint16[t+0]=4*e+0,o.uint16[t+1]=4*e+1,o.uint16[t+2]=4*e+2,o.uint16[t+3]=4*e+2,o.uint16[t+4]=4*e+3,o.uint16[t+5]=4*e+0;}return o}(u));const f=s.createIndexBuffer(Xo,!0),g=s.createVertexBuffer(p,t.b$.members,!0);for(const i of h){const r=Bi(e.transform);_.draw(s,l.TRIANGLES,Ut.disabled,Vt.disabled,e.colorModeForRenderPass(),Zt.disabled,r,e.style.map.terrain&&e.style.map.terrain.getTerrainData(i.coord),null,o.id,g,f,t.aL.simpleSegment(0,2*i.circleOffset,i.circleArray.length,i.circleArray.length/2),null,e.transform.zoom,null,null,null);}g.destroy(),f.destroy();}const Yo=t.af(new Float32Array(16));function Qo(e,i,o,r,a,s){const{horizontalAlign:n,verticalAlign:l}=t.aG(e);return new t.P((-(n-.5)*i/a+r[0])*s,(-(l-.5)*o/a+r[1])*s)}function Jo(e,i,o,r,a,s){const n=i.tileAnchorPoint.add(new t.P(i.translation[0],i.translation[1]));if(i.pitchWithMap){let e=r.mult(s);o||(e=e.rotate(-a));const t=n.add(e);return Ee(t.x,t.y,i.pitchedLabelPlaneMatrix,i.getElevation).point}if(o){const t=Oe(i.tileAnchorPoint.x+1,i.tileAnchorPoint.y,i).point.sub(e),o=Math.atan(t.y/t.x)+(t.x<0?Math.PI:0);return e.add(r.rotate(o))}return e.add(r)}function er(e,i,o,r,a,s,n,l,c,h,u,d){const _=e.text.placedSymbolArray,p=e.text.dynamicLayoutVertexArray,m=e.icon.dynamicLayoutVertexArray,f={};p.clear();for(let m=0;m<_.length;m++){const g=_.get(m),v=g.hidden||!g.crossTileID||e.allowVerticalPlacement&&!g.placedOrientation?null:r[g.crossTileID];if(v){const r=new t.P(g.anchorX,g.anchorY),_={getElevation:d,width:a.width,height:a.height,pitchedLabelPlaneMatrix:s,pitchWithMap:o,transform:a,tileAnchorPoint:r,translation:h,unwrappedTileID:u},m=o?Ne(r.x,r.y,_):Oe(r.x,r.y,_),b=Re(a.cameraToCenterDistance,m.signedDistanceFromCamera);let x=t.ao(e.textSizeData,l,g)*b/t.aA;o&&(x*=e.tilePixelRatio/n);const{width:y,height:w,anchor:T,textOffset:P,textBoxScale:C}=v,I=Qo(T,y,w,P,C,x),M=a.getPitchedTextCorrection(r.x+h[0],r.y+h[1],u),S=Jo(m.point,_,i,I,-a.bearingInRadians,M),E=e.allowVerticalPlacement&&g.placedOrientation===t.an.vertical?Math.PI/2:0;for(let e=0;e<g.numGlyphs;e++)t.au(p,S,E);c&&g.associatedIconIndex>=0&&(f[g.associatedIconIndex]={shiftedAnchor:S,angle:E});}else $e(g.numGlyphs,p);}if(c){m.clear();const i=e.icon.placedSymbolArray;for(let e=0;e<i.length;e++){const o=i.get(e);if(o.hidden)$e(o.numGlyphs,m);else {const i=f[e];if(i)for(let e=0;e<o.numGlyphs;e++)t.au(m,i.shiftedAnchor,i.angle);else $e(o.numGlyphs,m);}}e.icon.dynamicLayoutVertexBuffer.updateData(m);}e.text.dynamicLayoutVertexBuffer.updateData(p);}function tr(e,t,i){return i.iconsInText&&t?\"symbolTextAndIcon\":e?\"symbolSDF\":\"symbolIcon\"}function ir(e,i,o,r,a,s,n,l,c,h,u,d,_){const p=e.context,m=p.gl,f=e.transform,g=\"map\"===l,v=\"map\"===c,b=\"viewport\"!==l&&\"point\"!==o.layout.get(\"symbol-placement\"),x=g&&!v&&!b,y=!o.layout.get(\"symbol-sort-key\").isConstant();let w=!1;const T=e.getDepthModeForSublayer(0,Ut.ReadOnly),P=o._unevaluatedLayout.hasValue(\"text-variable-anchor\")||o._unevaluatedLayout.hasValue(\"text-variable-anchor-offset\"),C=[],I=f.getCircleRadiusCorrection();for(const l of r){const r=i.getTile(l),c=r.getBucket(o);if(!c)continue;const u=a?c.text:c.icon;if(!u||!u.segments.get().length||!u.hasVisibleVertices)continue;const d=u.programConfigurations.get(o.id),p=a||c.sdfIcons,T=a?c.textSizeData:c.iconSizeData,M=v||0!==f.pitch,S=e.useProgram(tr(p,a,c),d),E=t.am(T,f.zoom),R=e.style.map.terrain&&e.style.map.terrain.getTerrainData(l);let z,D,A,L,k=[0,0],F=null;if(a)D=r.glyphAtlasTexture,A=m.LINEAR,z=r.glyphAtlasTexture.size,c.iconsInText&&(k=r.imageAtlasTexture.size,F=r.imageAtlasTexture,L=M||e.options.rotating||e.options.zooming||\"composite\"===T.kind||\"camera\"===T.kind?m.LINEAR:m.NEAREST);else {const t=1!==o.layout.get(\"icon-size\").constantOr(0)||c.iconsNeedLinear;D=r.imageAtlasTexture,A=p||e.options.rotating||e.options.zooming||t||M?m.LINEAR:m.NEAREST,z=r.imageAtlasTexture.size;}const B=t.aB(r,1,e.transform.zoom),O=Ie(g,e.transform,B),j=t.L();t.ap(j,O);const N=Me(v,g,e.transform,B),Z=t.aC(f,r,s,n),U=f.getProjectionData({overscaledTileID:l,applyGlobeMatrix:!_,applyTerrainMatrix:!0}),G=P&&c.hasTextData(),V=\"none\"!==o.layout.get(\"icon-text-fit\")&&G&&c.hasIconData();if(b){const t=e.style.map.terrain?(t,i)=>e.style.map.terrain.getElevation(l,t,i):null,i=\"map\"===o.layout.get(\"text-rotation-alignment\");De(c,e,a,O,j,v,h,i,l.toUnwrapped(),f.width,f.height,Z,t);}const $=a&&P||V,q=b||$?Yo:v?O:e.transform.clipSpaceToPixelsMatrix,W=p&&0!==o.paint.get(a?\"text-halo-width\":\"icon-halo-width\").constantOr(1);let H;H=p?c.iconsInText?to(T.kind,E,x,v,b,$,e,q,N,Z,z,k,I):eo(T.kind,E,x,v,b,$,e,q,N,Z,a,z,0,I):Ji(T.kind,E,x,v,b,$,e,q,N,Z,a,z,I);const X={program:S,buffers:u,uniformValues:H,projectionData:U,atlasTexture:D,atlasTextureIcon:F,atlasInterpolation:A,atlasInterpolationIcon:L,isSDF:p,hasHalo:W};if(y&&c.canOverlap){w=!0;const e=u.segments.get();for(const i of e)C.push({segments:new t.aL([i]),sortKey:i.sortKey,state:X,terrainData:R});}else C.push({segments:u.segments,sortKey:0,state:X,terrainData:R});}w&&C.sort(((e,t)=>e.sortKey-t.sortKey));for(const t of C){const i=t.state;if(p.activeTexture.set(m.TEXTURE0),i.atlasTexture.bind(i.atlasInterpolation,m.CLAMP_TO_EDGE),i.atlasTextureIcon&&(p.activeTexture.set(m.TEXTURE1),i.atlasTextureIcon&&i.atlasTextureIcon.bind(i.atlasInterpolationIcon,m.CLAMP_TO_EDGE)),i.isSDF){const r=i.uniformValues;i.hasHalo&&(r.u_is_halo=1,or(i.buffers,t.segments,o,e,i.program,T,u,d,r,i.projectionData,t.terrainData)),r.u_is_halo=0;}or(i.buffers,t.segments,o,e,i.program,T,u,d,i.uniformValues,i.projectionData,t.terrainData);}}function or(e,t,i,o,r,a,s,n,l,c,h){const u=o.context;r.draw(u,u.gl.TRIANGLES,a,s,n,Zt.backCCW,l,h,c,i.id,e.layoutVertexBuffer,e.indexBuffer,t,i.paint,o.transform.zoom,e.programConfigurations.get(i.id),e.dynamicLayoutVertexBuffer,e.opacityVertexBuffer);}function rr(e,i,o,r,a){const s=e.context,n=s.gl,l=Vt.disabled,c=new jt([n.ONE,n.ONE],t.be.transparent,[!0,!0,!0,!0]),h=i.getBucket(o);if(!h)return;const u=r.key;let d=o.heatmapFbos.get(u);d||(d=sr(s,i.tileSize,i.tileSize),o.heatmapFbos.set(u,d)),s.bindFramebuffer.set(d.framebuffer),s.viewport.set([0,0,i.tileSize,i.tileSize]),s.clear({color:t.be.transparent});const _=h.programConfigurations.get(o.id),p=e.useProgram(\"heatmap\",_,!a),m=e.transform.getProjectionData({overscaledTileID:i.tileID,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),f=e.style.map.terrain.getTerrainData(r);p.draw(s,n.TRIANGLES,Ut.disabled,l,c,Zt.disabled,ji(i,e.transform.zoom,o.paint.get(\"heatmap-intensity\"),1),f,m,o.id,h.layoutVertexBuffer,h.indexBuffer,h.segments,o.paint,e.transform.zoom,_);}function ar(e,t,i,o,r){const a=e.context,s=a.gl,n=e.transform;a.setColorMode(e.colorModeForRenderPass());const l=nr(a,t),c=i.key,h=t.heatmapFbos.get(c);if(!h)return;a.activeTexture.set(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,h.colorAttachment.get()),a.activeTexture.set(s.TEXTURE1),l.bind(s.LINEAR,s.CLAMP_TO_EDGE);const u=n.getProjectionData({overscaledTileID:i,applyTerrainMatrix:r,applyGlobeMatrix:!o});e.useProgram(\"heatmapTexture\").draw(a,s.TRIANGLES,Ut.disabled,Vt.disabled,e.colorModeForRenderPass(),Zt.disabled,Ni(e,t,0,1),null,u,t.id,e.rasterBoundsBuffer,e.quadTriangleIndexBuffer,e.rasterBoundsSegments,t.paint,n.zoom),h.destroy(),t.heatmapFbos.delete(c);}function sr(e,t,i){var o,r;const a=e.gl,s=a.createTexture();a.bindTexture(a.TEXTURE_2D,s),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR);const n=null!==(o=e.HALF_FLOAT)&&void 0!==o?o:a.UNSIGNED_BYTE,l=null!==(r=e.RGBA16F)&&void 0!==r?r:a.RGBA;a.texImage2D(a.TEXTURE_2D,0,l,t,i,0,a.RGBA,n,null);const c=e.createFramebuffer(t,i,!1,!1);return c.colorAttachment.set(s),c}function nr(e,i){return i.colorRampTexture||(i.colorRampTexture=new t.T(e,i.colorRamp,e.gl.RGBA)),i.colorRampTexture}function lr(e,t,i,o,r){if(!i||!o||!o.imageAtlas)return;const a=o.imageAtlas.patternPositions;let s=a[i.to.toString()],n=a[i.from.toString()];if(!s&&n&&(s=n),!n&&s&&(n=s),!s||!n){const e=r.getPaintProperty(t);s=a[e],n=a[e];}s&&n&&e.setConstantPatternPositions(s,n);}function cr(e,i,o,r,a,s,n,l){const c=e.context.gl,h=\"fill-pattern\",u=o.paint.get(h),d=u&&u.constantOr(1),_=o.getCrossfadeParameters();let p,m,f,g,v;const b=e.transform,x=o.paint.get(\"fill-translate\"),y=o.paint.get(\"fill-translate-anchor\");n?(m=d&&!o.getPaintProperty(\"fill-outline-color\")?\"fillOutlinePattern\":\"fillOutline\",p=c.LINES):(m=d?\"fillPattern\":\"fill\",p=c.TRIANGLES);const w=u.constantOr(null);for(const u of r){const r=i.getTile(u);if(d&&!r.patternsLoaded())continue;const T=r.getBucket(o);if(!T)continue;const P=T.programConfigurations.get(o.id),C=e.useProgram(m,P),I=e.style.map.terrain&&e.style.map.terrain.getTerrainData(u);d&&(e.context.activeTexture.set(c.TEXTURE0),r.imageAtlasTexture.bind(c.LINEAR,c.CLAMP_TO_EDGE),P.updatePaintBuffers(_)),lr(P,h,w,r,o);const M=b.getProjectionData({overscaledTileID:u,applyGlobeMatrix:!l,applyTerrainMatrix:!0}),S=t.aC(b,r,x,y);if(n){g=T.indexBuffer2,v=T.segments2;const t=[c.drawingBufferWidth,c.drawingBufferHeight];f=\"fillOutlinePattern\"===m&&d?Li(e,_,r,t,S):Ai(t,S);}else g=T.indexBuffer,v=T.segments,f=d?Di(e,_,r,S):{u_fill_translate:S};const E=e.stencilModeForClipping(u);C.draw(e.context,p,a,E,s,Zt.backCCW,f,I,M,o.id,T.layoutVertexBuffer,g,v,o.paint,e.transform.zoom,P);}}function hr(e,i,o,r,a,s,n,l){const c=e.context,h=c.gl,u=\"fill-extrusion-pattern\",d=o.paint.get(u),_=d.constantOr(1),p=o.getCrossfadeParameters(),m=o.paint.get(\"fill-extrusion-opacity\"),f=d.constantOr(null),g=e.transform;for(const d of r){const r=i.getTile(d),v=r.getBucket(o);if(!v)continue;const b=e.style.map.terrain&&e.style.map.terrain.getTerrainData(d),x=v.programConfigurations.get(o.id),y=e.useProgram(_?\"fillExtrusionPattern\":\"fillExtrusion\",x);_&&(e.context.activeTexture.set(h.TEXTURE0),r.imageAtlasTexture.bind(h.LINEAR,h.CLAMP_TO_EDGE),x.updatePaintBuffers(p));const w=g.getProjectionData({overscaledTileID:d,applyGlobeMatrix:!l,applyTerrainMatrix:!0});lr(x,u,f,r,o);const T=t.aC(g,r,o.paint.get(\"fill-extrusion-translate\"),o.paint.get(\"fill-extrusion-translate-anchor\")),P=o.paint.get(\"fill-extrusion-vertical-gradient\"),C=_?zi(e,P,m,T,d,p,r):Ri(e,P,m,T);y.draw(c,c.gl.TRIANGLES,a,s,n,Zt.backCCW,C,b,w,o.id,v.layoutVertexBuffer,v.indexBuffer,v.segments,o.paint,e.transform.zoom,x,e.style.map.terrain&&v.centroidVertexBuffer);}}function ur(e,t,i,o,r,a,s,n,l){var c;const h=e.style.projection,u=e.context,d=e.transform,_=u.gl,p=[`#define NUM_ILLUMINATION_SOURCES ${i.paint.get(\"hillshade-highlight-color\").values.length}`],m=e.useProgram(\"hillshade\",null,!1,p),f=!e.options.moving;for(const p of o){const o=t.getTile(p),g=o.fbo;if(!g)continue;const v=h.getMeshFromTileID(u,p.canonical,n,!0,\"raster\"),b=null===(c=e.style.map.terrain)||void 0===c?void 0:c.getTerrainData(p);u.activeTexture.set(_.TEXTURE0),_.bindTexture(_.TEXTURE_2D,g.colorAttachment.get());const x=d.getProjectionData({overscaledTileID:p,aligned:f,applyGlobeMatrix:!l,applyTerrainMatrix:!0});m.draw(u,_.TRIANGLES,a,r[p.overscaledZ],s,Zt.backCCW,Zi(e,o,i),b,x,i.id,v.vertexBuffer,v.indexBuffer,v.segments);}}function dr(e,i,o,r,a,s,n,l,c){var h;const u=e.style.projection,d=e.context,_=e.transform,p=d.gl,m=e.useProgram(\"colorRelief\"),f=!e.options.moving;let g=!0;for(const v of r){const r=i.getTile(v),b=r.dem;if(g){const e=p.getParameter(p.MAX_TEXTURE_SIZE),{elevationTexture:t,colorTexture:i}=o.getColorRampTextures(d,e,b.getUnpackVector());d.activeTexture.set(p.TEXTURE1),t.bind(p.NEAREST,p.CLAMP_TO_EDGE),d.activeTexture.set(p.TEXTURE4),i.bind(p.LINEAR,p.CLAMP_TO_EDGE),g=!1;}if(!b||!b.data)continue;const x=b.stride,y=b.getPixels();if(d.activeTexture.set(p.TEXTURE0),d.pixelStoreUnpackPremultiplyAlpha.set(!1),r.demTexture=r.demTexture||e.getTileTexture(x),r.demTexture){const e=r.demTexture;e.update(y,{premultiply:!1}),e.bind(p.LINEAR,p.CLAMP_TO_EDGE);}else r.demTexture=new t.T(d,y,p.RGBA,{premultiply:!1}),r.demTexture.bind(p.LINEAR,p.CLAMP_TO_EDGE);const w=u.getMeshFromTileID(d,v.canonical,l,!0,\"raster\"),T=null===(h=e.style.map.terrain)||void 0===h?void 0:h.getTerrainData(v),P=_.getProjectionData({overscaledTileID:v,aligned:f,applyGlobeMatrix:!c,applyTerrainMatrix:!0});m.draw(d,p.TRIANGLES,s,a[v.overscaledZ],n,Zt.backCCW,Vi(o,r.dem),T,P,o.id,w.vertexBuffer,w.indexBuffer,w.segments);}}const _r=[new t.P(0,0),new t.P(t.$,0),new t.P(t.$,t.$),new t.P(0,t.$)];function pr(e,t,i,o,r,a,s,n,l=!1,c=!1){const h=o[o.length-1].overscaledZ,u=e.context,d=u.gl,_=e.useProgram(\"raster\"),p=e.transform,m=e.style.projection,f=e.colorModeForRenderPass(),g=!e.options.moving;for(const v of o){const o=e.getDepthModeForSublayer(v.overscaledZ-h,1===i.paint.get(\"raster-opacity\")?Ut.ReadWrite:Ut.ReadOnly,d.LESS),b=t.getTile(v);b.registerFadeDuration(i.paint.get(\"raster-fade-duration\"));const x=t.findLoadedParent(v,0),y=t.findLoadedSibling(v),w=mr(b,x||y||null,t,i,e.transform,e.style.map.terrain);let T,P;const C=\"nearest\"===i.paint.get(\"raster-resampling\")?d.NEAREST:d.LINEAR;u.activeTexture.set(d.TEXTURE0),b.texture.bind(C,d.CLAMP_TO_EDGE,d.LINEAR_MIPMAP_NEAREST),u.activeTexture.set(d.TEXTURE1),x?(x.texture.bind(C,d.CLAMP_TO_EDGE,d.LINEAR_MIPMAP_NEAREST),T=Math.pow(2,x.tileID.overscaledZ-b.tileID.overscaledZ),P=[b.tileID.canonical.x*T%1,b.tileID.canonical.y*T%1]):b.texture.bind(C,d.CLAMP_TO_EDGE,d.LINEAR_MIPMAP_NEAREST),b.texture.useMipmap&&u.extTextureFilterAnisotropic&&e.transform.pitch>20&&d.texParameterf(d.TEXTURE_2D,u.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,u.extTextureFilterAnisotropicMax);const I=e.style.map.terrain&&e.style.map.terrain.getTerrainData(v),M=p.getProjectionData({overscaledTileID:v,aligned:g,applyGlobeMatrix:!c,applyTerrainMatrix:!0}),S=Yi(P||[0,0],T||1,w,i,n),E=m.getMeshFromTileID(u,v.canonical,a,s,\"raster\");_.draw(u,d.TRIANGLES,o,r?r[v.overscaledZ]:Vt.disabled,f,l?Zt.frontCCW:Zt.backCCW,S,I,M,i.id,E.vertexBuffer,E.indexBuffer,E.segments);}}function mr(e,i,o,r,a,n){const l=r.paint.get(\"raster-fade-duration\");if(!n&&l>0){const r=s.now(),n=(r-e.timeAdded)/l,c=i?(r-i.timeAdded)/l:-1,h=o.getSource(),u=ge(a,{tileSize:h.tileSize,roundZoom:h.roundZoom}),d=!i||Math.abs(i.tileID.overscaledZ-u)>Math.abs(e.tileID.overscaledZ-u),_=d&&e.refreshedUponExpiration?1:t.ag(d?n:1-c,0,1);return e.refreshedUponExpiration&&n>=1&&(e.refreshedUponExpiration=!1),i?{opacity:1,mix:1-_}:{opacity:_,mix:0}}return {opacity:1,mix:0}}const fr=new t.be(1,0,0,1),gr=new t.be(0,1,0,1),vr=new t.be(0,0,1,1),br=new t.be(1,0,1,1),xr=new t.be(0,1,1,1);function yr(e,t,i,o){Tr(e,0,t+i/2,e.transform.width,i,o);}function wr(e,t,i,o){Tr(e,t-i/2,0,i,e.transform.height,o);}function Tr(e,t,i,o,r,a){const s=e.context,n=s.gl;n.enable(n.SCISSOR_TEST),n.scissor(t*e.pixelRatio,i*e.pixelRatio,o*e.pixelRatio,r*e.pixelRatio),s.clear({color:a}),n.disable(n.SCISSOR_TEST);}function Pr(e,i,o){const r=e.context,a=r.gl,s=e.useProgram(\"debug\"),n=Ut.disabled,l=Vt.disabled,c=e.colorModeForRenderPass(),h=\"$debug\",u=e.style.map.terrain&&e.style.map.terrain.getTerrainData(o);r.activeTexture.set(a.TEXTURE0);const d=i.getTileByID(o.key).latestRawTileData,_=Math.floor((d&&d.byteLength||0)/1024),p=i.getTile(o).tileSize,m=512/Math.min(p,512)*(o.overscaledZ/e.transform.zoom)*.5;let f=o.canonical.toString();o.overscaledZ!==o.canonical.z&&(f+=` => ${o.overscaledZ}`),function(e,t){e.initDebugOverlayCanvas();const i=e.debugOverlayCanvas,o=e.context.gl,r=e.debugOverlayCanvas.getContext(\"2d\");r.clearRect(0,0,i.width,i.height),r.shadowColor=\"white\",r.shadowBlur=2,r.lineWidth=1.5,r.strokeStyle=\"white\",r.textBaseline=\"top\",r.font=\"bold 36px Open Sans, sans-serif\",r.fillText(t,5,5),r.strokeText(t,5,5),e.debugOverlayTexture.update(i),e.debugOverlayTexture.bind(o.LINEAR,o.CLAMP_TO_EDGE);}(e,`${f} ${_}kB`);const g=e.transform.getProjectionData({overscaledTileID:o,applyGlobeMatrix:!0,applyTerrainMatrix:!0});s.draw(r,a.TRIANGLES,n,l,jt.alphaBlended,Zt.disabled,Oi(t.be.transparent,m),null,g,h,e.debugBuffer,e.quadTriangleIndexBuffer,e.debugSegments),s.draw(r,a.LINE_STRIP,n,l,c,Zt.disabled,Oi(t.be.red),u,g,h,e.debugBuffer,e.tileBorderIndexBuffer,e.debugSegments);}function Cr(e,t,i,o){const{isRenderingGlobe:r}=o,a=e.context,s=a.gl,n=e.transform,l=e.colorModeForRenderPass(),c=e.getDepthModeFor3D(),h=e.useProgram(\"terrain\");a.bindFramebuffer.set(null),a.viewport.set([0,0,e.width,e.height]);for(const o of i){const i=t.getTerrainMesh(o.tileID),u=e.renderToTexture.getTexture(o),d=t.getTerrainData(o.tileID);a.activeTexture.set(s.TEXTURE0),s.bindTexture(s.TEXTURE_2D,u.texture);const _=t.getMeshFrameDelta(n.zoom),p=n.calculateFogMatrix(o.tileID.toUnwrapped()),m=Ci(_,p,e.style.sky,n.pitch,r),f=n.getProjectionData({overscaledTileID:o.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0});h.draw(a,s.TRIANGLES,c,Vt.disabled,l,Zt.backCCW,m,d,f,\"terrain\",i.vertexBuffer,i.indexBuffer,i.segments);}}function Ir(e,i){if(!i.mesh){const o=new t.aK;o.emplaceBack(-1,-1),o.emplaceBack(1,-1),o.emplaceBack(1,1),o.emplaceBack(-1,1);const r=new t.aM;r.emplaceBack(0,1,2),r.emplaceBack(0,2,3),i.mesh=new wt(e.createVertexBuffer(o,Tt.members),e.createIndexBuffer(r),t.aL.simpleSegment(0,0,o.length,r.length));}return i.mesh}class Mr{constructor(e,i){this.context=new Ho(e),this.transform=i,this._tileTextures={},this.terrainFacilitator={dirty:!0,matrix:t.af(new Float64Array(16)),renderTime:0},this.setup(),this.numSublayers=xe.maxUnderzooming+xe.maxOverzooming+1,this.depthEpsilon=1/Math.pow(2,16),this.crossTileSymbolIndex=new vt;}resize(e,t,i){if(this.width=Math.floor(e*i),this.height=Math.floor(t*i),this.pixelRatio=i,this.context.viewport.set([0,0,this.width,this.height]),this.style)for(const e of this.style._order)this.style._layers[e].resize();}setup(){const e=this.context,i=new t.aK;i.emplaceBack(0,0),i.emplaceBack(t.$,0),i.emplaceBack(0,t.$),i.emplaceBack(t.$,t.$),this.tileExtentBuffer=e.createVertexBuffer(i,Tt.members),this.tileExtentSegments=t.aL.simpleSegment(0,0,4,2);const o=new t.aK;o.emplaceBack(0,0),o.emplaceBack(t.$,0),o.emplaceBack(0,t.$),o.emplaceBack(t.$,t.$),this.debugBuffer=e.createVertexBuffer(o,Tt.members),this.debugSegments=t.aL.simpleSegment(0,0,4,5);const r=new t.c5;r.emplaceBack(0,0,0,0),r.emplaceBack(t.$,0,t.$,0),r.emplaceBack(0,t.$,0,t.$),r.emplaceBack(t.$,t.$,t.$,t.$),this.rasterBoundsBuffer=e.createVertexBuffer(r,Ti.members),this.rasterBoundsSegments=t.aL.simpleSegment(0,0,4,2);const a=new t.aK;a.emplaceBack(0,0),a.emplaceBack(t.$,0),a.emplaceBack(0,t.$),a.emplaceBack(t.$,t.$),this.rasterBoundsBufferPosOnly=e.createVertexBuffer(a,Tt.members),this.rasterBoundsSegmentsPosOnly=t.aL.simpleSegment(0,0,4,5);const s=new t.aK;s.emplaceBack(0,0),s.emplaceBack(1,0),s.emplaceBack(0,1),s.emplaceBack(1,1),this.viewportBuffer=e.createVertexBuffer(s,Tt.members),this.viewportSegments=t.aL.simpleSegment(0,0,4,2);const n=new t.c6;n.emplaceBack(0),n.emplaceBack(1),n.emplaceBack(3),n.emplaceBack(2),n.emplaceBack(0),this.tileBorderIndexBuffer=e.createIndexBuffer(n);const l=new t.aM;l.emplaceBack(1,0,2),l.emplaceBack(1,2,3),this.quadTriangleIndexBuffer=e.createIndexBuffer(l);const c=this.context.gl;this.stencilClearMode=new Vt({func:c.ALWAYS,mask:0},0,255,c.ZERO,c.ZERO,c.ZERO),this.tileExtentMesh=new wt(this.tileExtentBuffer,this.quadTriangleIndexBuffer,this.tileExtentSegments);}clearStencil(){const e=this.context,i=e.gl;this.nextStencilID=1,this.currentStencilSource=void 0;const o=t.L();t.bX(o,0,this.width,this.height,0,0,1),t.N(o,o,[i.drawingBufferWidth,i.drawingBufferHeight,0]);const r={mainMatrix:o,tileMercatorCoords:[0,0,1,1],clippingPlane:[0,0,0,0],projectionTransition:0,fallbackMatrix:o};this.useProgram(\"clippingMask\",null,!0).draw(e,i.TRIANGLES,Ut.disabled,this.stencilClearMode,jt.disabled,Zt.disabled,null,null,r,\"$clipping\",this.viewportBuffer,this.quadTriangleIndexBuffer,this.viewportSegments);}_renderTileClippingMasks(e,t,i){if(this.currentStencilSource===e.source||!e.isTileClipped()||!t||!t.length)return;this.currentStencilSource=e.source,this.nextStencilID+t.length>256&&this.clearStencil();const o=this.context;o.setColorMode(jt.disabled),o.setDepthMode(Ut.disabled);const r={};for(const e of t)r[e.key]=this.nextStencilID++;this._renderTileMasks(r,t,i,!0),this._renderTileMasks(r,t,i,!1),this._tileClippingMaskIDs=r;}_renderTileMasks(e,t,i,o){const r=this.context,a=r.gl,s=this.style.projection,n=this.transform,l=this.useProgram(\"clippingMask\");for(const c of t){const t=e[c.key],h=this.style.map.terrain&&this.style.map.terrain.getTerrainData(c),u=s.getMeshFromTileID(this.context,c.canonical,o,!0,\"stencil\"),d=n.getProjectionData({overscaledTileID:c,applyGlobeMatrix:!i,applyTerrainMatrix:!0});l.draw(r,a.TRIANGLES,Ut.disabled,new Vt({func:a.ALWAYS,mask:0},t,255,a.KEEP,a.KEEP,a.REPLACE),jt.disabled,i?Zt.disabled:Zt.backCCW,null,h,d,\"$clipping\",u.vertexBuffer,u.indexBuffer,u.segments);}}_renderTilesDepthBuffer(){const e=this.context,t=e.gl,i=this.style.projection,o=this.transform,r=this.useProgram(\"depth\"),a=this.getDepthModeFor3D(),s=ve(o,{tileSize:o.tileSize});for(const n of s){const s=this.style.map.terrain&&this.style.map.terrain.getTerrainData(n),l=i.getMeshFromTileID(this.context,n.canonical,!0,!0,\"raster\"),c=o.getProjectionData({overscaledTileID:n,applyGlobeMatrix:!0,applyTerrainMatrix:!0});r.draw(e,t.TRIANGLES,a,Vt.disabled,jt.disabled,Zt.backCCW,null,s,c,\"$clipping\",l.vertexBuffer,l.indexBuffer,l.segments);}}stencilModeFor3D(){this.currentStencilSource=void 0,this.nextStencilID+1>256&&this.clearStencil();const e=this.nextStencilID++,t=this.context.gl;return new Vt({func:t.NOTEQUAL,mask:255},e,255,t.KEEP,t.KEEP,t.REPLACE)}stencilModeForClipping(e){const t=this.context.gl;return new Vt({func:t.EQUAL,mask:255},this._tileClippingMaskIDs[e.key],0,t.KEEP,t.KEEP,t.REPLACE)}getStencilConfigForOverlapAndUpdateStencilID(e){const t=this.context.gl,i=e.sort(((e,t)=>t.overscaledZ-e.overscaledZ)),o=i[i.length-1].overscaledZ,r=i[0].overscaledZ-o+1;if(r>1){this.currentStencilSource=void 0,this.nextStencilID+r>256&&this.clearStencil();const e={};for(let i=0;i<r;i++)e[i+o]=new Vt({func:t.GEQUAL,mask:255},i+this.nextStencilID,255,t.KEEP,t.KEEP,t.REPLACE);return this.nextStencilID+=r,[e,i]}return [{[o]:Vt.disabled},i]}stencilConfigForOverlapTwoPass(e){const t=this.context.gl,i=e.sort(((e,t)=>t.overscaledZ-e.overscaledZ)),o=i[i.length-1].overscaledZ,r=i[0].overscaledZ-o+1;if(this.clearStencil(),r>1){const e={},a={};for(let i=0;i<r;i++)e[i+o]=new Vt({func:t.GREATER,mask:255},r+1+i,255,t.KEEP,t.KEEP,t.REPLACE),a[i+o]=new Vt({func:t.GREATER,mask:255},1+i,255,t.KEEP,t.KEEP,t.REPLACE);return this.nextStencilID=2*r+1,[e,a,i]}return this.nextStencilID=3,[{[o]:new Vt({func:t.GREATER,mask:255},2,255,t.KEEP,t.KEEP,t.REPLACE)},{[o]:new Vt({func:t.GREATER,mask:255},1,255,t.KEEP,t.KEEP,t.REPLACE)},i]}colorModeForRenderPass(){const e=this.context.gl;if(this._showOverdrawInspector){const i=1/8;return new jt([e.CONSTANT_COLOR,e.ONE],new t.be(i,i,i,0),[!0,!0,!0,!0])}return \"opaque\"===this.renderPass?jt.unblended:jt.alphaBlended}getDepthModeForSublayer(e,t,i){if(!this.opaquePassEnabledForLayer())return Ut.disabled;const o=1-((1+this.currentLayer)*this.numSublayers+e)*this.depthEpsilon;return new Ut(i||this.context.gl.LEQUAL,t,[o,o])}getDepthModeFor3D(){return new Ut(this.context.gl.LEQUAL,Ut.ReadWrite,this.depthRangeFor3D)}opaquePassEnabledForLayer(){return this.currentLayer<this.opaquePassCutoff}render(e,i){var o,r;this.style=e,this.options=i,this.lineAtlas=e.lineAtlas,this.imageManager=e.imageManager,this.glyphManager=e.glyphManager,this.symbolFadeChange=e.placement.symbolFadeChange(s.now()),this.imageManager.beginFrame();const a=this.style._order,n=this.style.sourceCaches,l={},c={},h={},u={isRenderingToTexture:!1,isRenderingGlobe:(null===(o=e.projection)||void 0===o?void 0:o.transitionState)>0};for(const e in n){const t=n[e];t.used&&t.prepare(this.context),l[e]=t.getVisibleCoordinates(!1),c[e]=l[e].slice().reverse(),h[e]=t.getVisibleCoordinates(!0).reverse();}this.opaquePassCutoff=1/0;for(let e=0;e<a.length;e++)if(this.style._layers[a[e]].is3D()){this.opaquePassCutoff=e;break}this.maybeDrawDepthAndCoords(!1),this.renderToTexture&&(this.renderToTexture.prepareForRender(this.style,this.transform.zoom),this.opaquePassCutoff=0),this.renderPass=\"offscreen\";for(const e of a){const t=this.style._layers[e];if(!t.hasOffscreenPass()||t.isHidden(this.transform.zoom))continue;const i=c[t.source];(\"custom\"===t.type||i.length)&&this.renderLayer(this,n[t.source],t,i,u);}if(null===(r=this.style.projection)||void 0===r||r.updateGPUdependent({context:this.context,useProgram:e=>this.useProgram(e)}),this.context.viewport.set([0,0,this.width,this.height]),this.context.bindFramebuffer.set(null),this.context.clear({color:i.showOverdrawInspector?t.be.black:t.be.transparent,depth:1}),this.clearStencil(),this.style.sky&&function(e,t){const i=e.context,o=i.gl,r=((e,t,i)=>{const o=Math.cos(t.rollInRadians),r=Math.sin(t.rollInRadians),a=he(t),s=t.getProjectionData({overscaledTileID:null,applyGlobeMatrix:!0,applyTerrainMatrix:!0}).projectionTransition;return {u_sky_color:e.properties.get(\"sky-color\"),u_horizon_color:e.properties.get(\"horizon-color\"),u_horizon:[(t.width/2-a*r)*i,(t.height/2+a*o)*i],u_horizon_normal:[-r,o],u_sky_horizon_blend:e.properties.get(\"sky-horizon-blend\")*t.height/2*i,u_sky_blend:s}})(t,e.style.map.transform,e.pixelRatio),a=new Ut(o.LEQUAL,Ut.ReadWrite,[0,1]),s=Vt.disabled,n=e.colorModeForRenderPass(),l=e.useProgram(\"sky\"),c=Ir(i,t);l.draw(i,o.TRIANGLES,a,s,n,Zt.disabled,r,null,void 0,\"sky\",c.vertexBuffer,c.indexBuffer,c.segments);}(this,this.style.sky),this._showOverdrawInspector=i.showOverdrawInspector,this.depthRangeFor3D=[0,1-(e._order.length+2)*this.numSublayers*this.depthEpsilon],!this.renderToTexture)for(this.renderPass=\"opaque\",this.currentLayer=a.length-1;this.currentLayer>=0;this.currentLayer--){const e=this.style._layers[a[this.currentLayer]],t=n[e.source],i=l[e.source];this._renderTileClippingMasks(e,i,!1),this.renderLayer(this,t,e,i,u);}this.renderPass=\"translucent\";let d=!1;for(this.currentLayer=0;this.currentLayer<a.length;this.currentLayer++){const e=this.style._layers[a[this.currentLayer]],t=n[e.source];if(this.renderToTexture&&this.renderToTexture.renderLayer(e,u))continue;this.opaquePassEnabledForLayer()||d||(d=!0,u.isRenderingGlobe&&!this.style.map.terrain&&this._renderTilesDepthBuffer());const i=(\"symbol\"===e.type?h:c)[e.source];this._renderTileClippingMasks(e,l[e.source],!!this.renderToTexture),this.renderLayer(this,t,e,i,u);}if(u.isRenderingGlobe&&function(e,i,o){const r=e.context,a=r.gl,s=e.useProgram(\"atmosphere\"),n=new Ut(a.LEQUAL,Ut.ReadOnly,[0,1]),l=e.transform,c=function(e,i){const o=e.properties.get(\"position\"),r=[-o.x,-o.y,-o.z],a=t.af(new Float64Array(16));return \"map\"===e.properties.get(\"anchor\")&&(t.b5(a,a,i.rollInRadians),t.b6(a,a,-i.pitchInRadians),t.b5(a,a,i.bearingInRadians),t.b6(a,a,i.center.lat*Math.PI/180),t.by(a,a,-i.center.lng*Math.PI/180)),t.c4(r,r,a),r}(o,e.transform),h=l.getProjectionData({overscaledTileID:null,applyGlobeMatrix:!0,applyTerrainMatrix:!0}),u=i.properties.get(\"atmosphere-blend\")*h.projectionTransition;if(0===u)return;const d=oi(l.worldSize,l.center.lat),_=l.inverseProjectionMatrix,p=new Float64Array(4);p[3]=1,t.av(p,p,l.modelViewProjectionMatrix),p[0]/=p[3],p[1]/=p[3],p[2]/=p[3],p[3]=1,t.av(p,p,_),p[0]/=p[3],p[1]/=p[3],p[2]/=p[3],p[3]=1;const m=((e,t,i,o,r)=>({u_sun_pos:e,u_atmosphere_blend:t,u_globe_position:i,u_globe_radius:o,u_inv_proj_matrix:r}))(c,u,[p[0],p[1],p[2]],d,_),f=Ir(r,i);s.draw(r,a.TRIANGLES,n,Vt.disabled,jt.alphaBlended,Zt.disabled,m,null,null,\"atmosphere\",f.vertexBuffer,f.indexBuffer,f.segments);}(this,this.style.sky,this.style.light),this.options.showTileBoundaries){const e=function(e,t){let i=null;const o=Object.values(e._layers).flatMap((i=>i.source&&!i.isHidden(t)?[e.sourceCaches[i.source]]:[])),r=o.filter((e=>\"vector\"===e.getSource().type)),a=o.filter((e=>\"vector\"!==e.getSource().type)),s=e=>{(!i||i.getSource().maxzoom<e.getSource().maxzoom)&&(i=e);};return r.forEach((e=>s(e))),i||a.forEach((e=>s(e))),i}(this.style,this.transform.zoom);e&&function(e,t,i){for(let o=0;o<i.length;o++)Pr(e,t,i[o]);}(this,e,e.getVisibleCoordinates());}this.options.showPadding&&function(e){const t=e.transform.padding;yr(e,e.transform.height-(t.top||0),3,fr),yr(e,t.bottom||0,3,gr),wr(e,t.left||0,3,vr),wr(e,e.transform.width-(t.right||0),3,br);const i=e.transform.centerPoint;!function(e,t,i,o){Tr(e,t-1,i-10,2,20,o),Tr(e,t-10,i-1,20,2,o);}(e,i.x,e.transform.height-i.y,xr);}(this),this.context.setDefault();}maybeDrawDepthAndCoords(e){if(!this.style||!this.style.map||!this.style.map.terrain)return;const i=this.terrainFacilitator.matrix,o=this.transform.modelViewProjectionMatrix;let r=this.terrainFacilitator.dirty;r||(r=e?!t.c7(i,o):!t.c8(i,o)),r||(r=this.style.map.terrain.sourceCache.anyTilesAfterTime(this.terrainFacilitator.renderTime)),r&&(t.c9(i,o),this.terrainFacilitator.renderTime=Date.now(),this.terrainFacilitator.dirty=!1,function(e,i){const o=e.context,r=o.gl,a=e.transform,s=jt.unblended,n=new Ut(r.LEQUAL,Ut.ReadWrite,[0,1]),l=i.sourceCache.getRenderableTiles(),c=e.useProgram(\"terrainDepth\");o.bindFramebuffer.set(i.getFramebuffer(\"depth\").framebuffer),o.viewport.set([0,0,e.width/devicePixelRatio,e.height/devicePixelRatio]),o.clear({color:t.be.transparent,depth:1});for(const e of l){const t=i.getTerrainMesh(e.tileID),l=i.getTerrainData(e.tileID),h=a.getProjectionData({overscaledTileID:e.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0}),u={u_ele_delta:i.getMeshFrameDelta(a.zoom)};c.draw(o,r.TRIANGLES,n,Vt.disabled,s,Zt.backCCW,u,l,h,\"terrain\",t.vertexBuffer,t.indexBuffer,t.segments);}o.bindFramebuffer.set(null),o.viewport.set([0,0,e.width,e.height]);}(this,this.style.map.terrain),function(e,i){const o=e.context,r=o.gl,a=e.transform,s=jt.unblended,n=new Ut(r.LEQUAL,Ut.ReadWrite,[0,1]),l=i.getCoordsTexture(),c=i.sourceCache.getRenderableTiles(),h=e.useProgram(\"terrainCoords\");o.bindFramebuffer.set(i.getFramebuffer(\"coords\").framebuffer),o.viewport.set([0,0,e.width/devicePixelRatio,e.height/devicePixelRatio]),o.clear({color:t.be.transparent,depth:1}),i.coordsIndex=[];for(const e of c){const t=i.getTerrainMesh(e.tileID),c=i.getTerrainData(e.tileID);o.activeTexture.set(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,l.texture);const u={u_terrain_coords_id:(255-i.coordsIndex.length)/255,u_texture:0,u_ele_delta:i.getMeshFrameDelta(a.zoom)},d=a.getProjectionData({overscaledTileID:e.tileID,applyTerrainMatrix:!1,applyGlobeMatrix:!0});h.draw(o,r.TRIANGLES,n,Vt.disabled,s,Zt.backCCW,u,c,d,\"terrain\",t.vertexBuffer,t.indexBuffer,t.segments),i.coordsIndex.push(e.tileID.key);}o.bindFramebuffer.set(null),o.viewport.set([0,0,e.width,e.height]);}(this,this.style.map.terrain));}renderLayer(e,i,o,r,a){o.isHidden(this.transform.zoom)||(\"background\"===o.type||\"custom\"===o.type||(r||[]).length)&&(this.id=o.id,t.ca(o)?function(e,i,o,r,a,s){if(\"translucent\"!==e.renderPass)return;const{isRenderingToTexture:n}=s,l=Vt.disabled,c=e.colorModeForRenderPass();(o._unevaluatedLayout.hasValue(\"text-variable-anchor\")||o._unevaluatedLayout.hasValue(\"text-variable-anchor-offset\"))&&function(e,i,o,r,a,s,n,l,c){const h=i.transform,u=i.style.map.terrain,d=\"map\"===a,_=\"map\"===s;for(const a of e){const e=r.getTile(a),s=e.getBucket(o);if(!s||!s.text||!s.text.segments.get().length)continue;const p=t.am(s.textSizeData,h.zoom),m=t.aB(e,1,i.transform.zoom),f=Ie(d,i.transform,m),g=\"none\"!==o.layout.get(\"icon-text-fit\")&&s.hasIconData();if(p){const i=Math.pow(2,h.zoom-e.tileID.overscaledZ),o=u?(e,t)=>u.getElevation(a,e,t):null;er(s,d,_,c,h,f,i,p,g,t.aC(h,e,n,l),a.toUnwrapped(),o);}}}(r,e,o,i,o.layout.get(\"text-rotation-alignment\"),o.layout.get(\"text-pitch-alignment\"),o.paint.get(\"text-translate\"),o.paint.get(\"text-translate-anchor\"),a),0!==o.paint.get(\"icon-opacity\").constantOr(1)&&ir(e,i,o,r,!1,o.paint.get(\"icon-translate\"),o.paint.get(\"icon-translate-anchor\"),o.layout.get(\"icon-rotation-alignment\"),o.layout.get(\"icon-pitch-alignment\"),o.layout.get(\"icon-keep-upright\"),l,c,n),0!==o.paint.get(\"text-opacity\").constantOr(1)&&ir(e,i,o,r,!0,o.paint.get(\"text-translate\"),o.paint.get(\"text-translate-anchor\"),o.layout.get(\"text-rotation-alignment\"),o.layout.get(\"text-pitch-alignment\"),o.layout.get(\"text-keep-upright\"),l,c,n),i.map.showCollisionBoxes&&(Ko(e,i,o,r,!0),Ko(e,i,o,r,!1));}(e,i,o,r,this.style.placement.variableOffsets,a):t.cb(o)?function(e,i,o,r,a){if(\"translucent\"!==e.renderPass)return;const{isRenderingToTexture:s}=a,n=o.paint.get(\"circle-opacity\"),l=o.paint.get(\"circle-stroke-width\"),c=o.paint.get(\"circle-stroke-opacity\"),h=!o.layout.get(\"circle-sort-key\").isConstant();if(0===n.constantOr(1)&&(0===l.constantOr(1)||0===c.constantOr(1)))return;const u=e.context,d=u.gl,_=e.transform,p=e.getDepthModeForSublayer(0,Ut.ReadOnly),m=Vt.disabled,f=e.colorModeForRenderPass(),g=[],v=_.getCircleRadiusCorrection();for(let a=0;a<r.length;a++){const n=r[a],l=i.getTile(n),c=l.getBucket(o);if(!c)continue;const u=o.paint.get(\"circle-translate\"),d=o.paint.get(\"circle-translate-anchor\"),p=t.aC(_,l,u,d),m=c.programConfigurations.get(o.id),f=e.useProgram(\"circle\",m),b=c.layoutVertexBuffer,x=c.indexBuffer,y=e.style.map.terrain&&e.style.map.terrain.getTerrainData(n),w={programConfiguration:m,program:f,layoutVertexBuffer:b,indexBuffer:x,uniformValues:ki(e,l,o,p,v),terrainData:y,projectionData:_.getProjectionData({overscaledTileID:n,applyGlobeMatrix:!s,applyTerrainMatrix:!0})};if(h){const e=c.segments.get();for(const i of e)g.push({segments:new t.aL([i]),sortKey:i.sortKey,state:w});}else g.push({segments:c.segments,sortKey:0,state:w});}h&&g.sort(((e,t)=>e.sortKey-t.sortKey));for(const t of g){const{programConfiguration:i,program:r,layoutVertexBuffer:a,indexBuffer:s,uniformValues:n,terrainData:l,projectionData:c}=t.state;r.draw(u,d.TRIANGLES,p,m,f,Zt.backCCW,n,l,c,o.id,a,s,t.segments,o.paint,e.transform.zoom,i);}}(e,i,o,r,a):t.cc(o)?function(e,i,o,r,a){if(0===o.paint.get(\"heatmap-opacity\"))return;const s=e.context,{isRenderingToTexture:n,isRenderingGlobe:l}=a;if(e.style.map.terrain){for(const t of r){const r=i.getTile(t);i.hasRenderableParent(t)||(\"offscreen\"===e.renderPass?rr(e,r,o,t,l):\"translucent\"===e.renderPass&&ar(e,o,t,n,l));}s.viewport.set([0,0,e.width,e.height]);}else \"offscreen\"===e.renderPass?function(e,i,o,r){const a=e.context,s=a.gl,n=e.transform,l=Vt.disabled,c=new jt([s.ONE,s.ONE],t.be.transparent,[!0,!0,!0,!0]);((function(e,i,o){const r=e.gl;e.activeTexture.set(r.TEXTURE1),e.viewport.set([0,0,i.width/4,i.height/4]);let a=o.heatmapFbos.get(t.c1);a?(r.bindTexture(r.TEXTURE_2D,a.colorAttachment.get()),e.bindFramebuffer.set(a.framebuffer)):(a=sr(e,i.width/4,i.height/4),o.heatmapFbos.set(t.c1,a));}))(a,e,o),a.clear({color:t.be.transparent});for(let t=0;t<r.length;t++){const h=r[t];if(i.hasRenderableParent(h))continue;const u=i.getTile(h),d=u.getBucket(o);if(!d)continue;const _=d.programConfigurations.get(o.id),p=e.useProgram(\"heatmap\",_),m=n.getProjectionData({overscaledTileID:h,applyGlobeMatrix:!0,applyTerrainMatrix:!1}),f=n.getCircleRadiusCorrection();p.draw(a,s.TRIANGLES,Ut.disabled,l,c,Zt.backCCW,ji(u,n.zoom,o.paint.get(\"heatmap-intensity\"),f),null,m,o.id,d.layoutVertexBuffer,d.indexBuffer,d.segments,o.paint,n.zoom,_);}a.viewport.set([0,0,e.width,e.height]);}(e,i,o,r):\"translucent\"===e.renderPass&&function(e,i){const o=e.context,r=o.gl;o.setColorMode(e.colorModeForRenderPass());const a=i.heatmapFbos.get(t.c1);a&&(o.activeTexture.set(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,a.colorAttachment.get()),o.activeTexture.set(r.TEXTURE1),nr(o,i).bind(r.LINEAR,r.CLAMP_TO_EDGE),e.useProgram(\"heatmapTexture\").draw(o,r.TRIANGLES,Ut.disabled,Vt.disabled,e.colorModeForRenderPass(),Zt.disabled,Ni(e,i,0,1),null,null,i.id,e.viewportBuffer,e.quadTriangleIndexBuffer,e.viewportSegments,i.paint,e.transform.zoom));}(e,o);}(e,i,o,r,a):t.cd(o)?function(e,i,o,r,a){if(\"translucent\"!==e.renderPass)return;const{isRenderingToTexture:s}=a,n=o.paint.get(\"line-opacity\"),l=o.paint.get(\"line-width\");if(0===n.constantOr(1)||0===l.constantOr(1))return;const c=e.getDepthModeForSublayer(0,Ut.ReadOnly),h=e.colorModeForRenderPass(),u=o.paint.get(\"line-dasharray\"),d=o.paint.get(\"line-pattern\"),_=d.constantOr(1),p=o.paint.get(\"line-gradient\"),m=o.getCrossfadeParameters(),f=_?\"linePattern\":u?\"lineSDF\":p?\"lineGradient\":\"line\",g=e.context,v=g.gl,b=e.transform;let x=!0;for(const a of r){const r=i.getTile(a);if(_&&!r.patternsLoaded())continue;const n=r.getBucket(o);if(!n)continue;const l=n.programConfigurations.get(o.id),y=e.context.program.get(),w=e.useProgram(f,l),T=x||w.program!==y,P=e.style.map.terrain&&e.style.map.terrain.getTerrainData(a),C=d.constantOr(null);if(C&&r.imageAtlas){const e=r.imageAtlas,t=e.patternPositions[C.to.toString()],i=e.patternPositions[C.from.toString()];t&&i&&l.setConstantPatternPositions(t,i);}const I=b.getProjectionData({overscaledTileID:a,applyGlobeMatrix:!s,applyTerrainMatrix:!0}),M=b.getPixelScale(),S=_?Wi(e,r,o,M,m):u?Hi(e,r,o,M,u,m):p?qi(e,r,o,M,n.lineClipsArray.length):$i(e,r,o,M);if(_)g.activeTexture.set(v.TEXTURE0),r.imageAtlasTexture.bind(v.LINEAR,v.CLAMP_TO_EDGE),l.updatePaintBuffers(m);else if(u&&(T||e.lineAtlas.dirty))g.activeTexture.set(v.TEXTURE0),e.lineAtlas.bind(g);else if(p){const r=n.gradients[o.id];let s=r.texture;if(o.gradientVersion!==r.version){let l=256;if(o.stepInterpolant){const o=i.getSource().maxzoom,r=a.canonical.z===o?Math.ceil(1<<e.transform.maxZoom-a.canonical.z):1;l=t.ag(t.c2(n.maxLineLength/t.$*1024*r),256,g.maxTextureSize);}r.gradient=t.c3({expression:o.gradientExpression(),evaluationKey:\"lineProgress\",resolution:l,image:r.gradient||void 0,clips:n.lineClipsArray}),r.texture?r.texture.update(r.gradient):r.texture=new t.T(g,r.gradient,v.RGBA),r.version=o.gradientVersion,s=r.texture;}g.activeTexture.set(v.TEXTURE0),s.bind(o.stepInterpolant?v.NEAREST:v.LINEAR,v.CLAMP_TO_EDGE);}const E=e.stencilModeForClipping(a);w.draw(g,v.TRIANGLES,c,E,h,Zt.disabled,S,P,I,o.id,n.layoutVertexBuffer,n.indexBuffer,n.segments,o.paint,e.transform.zoom,l,n.layoutVertexBuffer2),x=!1;}}(e,i,o,r,a):t.ce(o)?function(e,i,o,r,a){const s=o.paint.get(\"fill-color\"),n=o.paint.get(\"fill-opacity\");if(0===n.constantOr(1))return;const{isRenderingToTexture:l}=a,c=e.colorModeForRenderPass(),h=o.paint.get(\"fill-pattern\"),u=e.opaquePassEnabledForLayer()&&!h.constantOr(1)&&1===s.constantOr(t.be.transparent).a&&1===n.constantOr(0)?\"opaque\":\"translucent\";if(e.renderPass===u){const t=e.getDepthModeForSublayer(1,\"opaque\"===e.renderPass?Ut.ReadWrite:Ut.ReadOnly);cr(e,i,o,r,t,c,!1,l);}if(\"translucent\"===e.renderPass&&o.paint.get(\"fill-antialias\")){const t=e.getDepthModeForSublayer(o.getPaintProperty(\"fill-outline-color\")?2:0,Ut.ReadOnly);cr(e,i,o,r,t,c,!0,l);}}(e,i,o,r,a):t.cf(o)?function(e,t,i,o,r){const a=i.paint.get(\"fill-extrusion-opacity\");if(0===a)return;const{isRenderingToTexture:s}=r;if(\"translucent\"===e.renderPass){const r=new Ut(e.context.gl.LEQUAL,Ut.ReadWrite,e.depthRangeFor3D);if(1!==a||i.paint.get(\"fill-extrusion-pattern\").constantOr(1))hr(e,t,i,o,r,Vt.disabled,jt.disabled,s),hr(e,t,i,o,r,e.stencilModeFor3D(),e.colorModeForRenderPass(),s);else {const a=e.colorModeForRenderPass();hr(e,t,i,o,r,Vt.disabled,a,s);}}}(e,i,o,r,a):t.cg(o)?function(e,i,o,r,a){if(\"offscreen\"!==e.renderPass&&\"translucent\"!==e.renderPass)return;const{isRenderingToTexture:s}=a,n=e.context,l=e.style.projection.useSubdivision,c=e.getDepthModeForSublayer(0,Ut.ReadOnly),h=e.colorModeForRenderPass();if(\"offscreen\"===e.renderPass)!function(e,i,o,r,a,s,n){const l=e.context,c=l.gl;for(const h of o){const o=i.getTile(h),u=o.dem;if(!u||!u.data)continue;if(!o.needsHillshadePrepare)continue;const d=u.dim,_=u.stride,p=u.getPixels();if(l.activeTexture.set(c.TEXTURE1),l.pixelStoreUnpackPremultiplyAlpha.set(!1),o.demTexture=o.demTexture||e.getTileTexture(_),o.demTexture){const e=o.demTexture;e.update(p,{premultiply:!1}),e.bind(c.NEAREST,c.CLAMP_TO_EDGE);}else o.demTexture=new t.T(l,p,c.RGBA,{premultiply:!1}),o.demTexture.bind(c.NEAREST,c.CLAMP_TO_EDGE);l.activeTexture.set(c.TEXTURE0);let m=o.fbo;if(!m){const e=new t.T(l,{width:d,height:d,data:null},c.RGBA);e.bind(c.LINEAR,c.CLAMP_TO_EDGE),m=o.fbo=l.createFramebuffer(d,d,!0,!1),m.colorAttachment.set(e.texture);}l.bindFramebuffer.set(m.framebuffer),l.viewport.set([0,0,d,d]),e.useProgram(\"hillshadePrepare\").draw(l,c.TRIANGLES,a,s,n,Zt.disabled,Ui(o.tileID,u),null,null,r.id,e.rasterBoundsBuffer,e.quadTriangleIndexBuffer,e.rasterBoundsSegments),o.needsHillshadePrepare=!1;}}(e,i,r,o,c,Vt.disabled,h),n.viewport.set([0,0,e.width,e.height]);else if(\"translucent\"===e.renderPass)if(l){const[t,a,n]=e.stencilConfigForOverlapTwoPass(r);ur(e,i,o,n,t,c,h,!1,s),ur(e,i,o,n,a,c,h,!0,s);}else {const[t,a]=e.getStencilConfigForOverlapAndUpdateStencilID(r);ur(e,i,o,a,t,c,h,!1,s);}}(e,i,o,r,a):t.ch(o)?function(e,t,i,o,r){if(\"translucent\"!==e.renderPass)return;if(!o.length)return;const{isRenderingToTexture:a}=r,s=e.style.projection.useSubdivision,n=e.getDepthModeForSublayer(0,Ut.ReadOnly),l=e.colorModeForRenderPass();if(s){const[r,s,c]=e.stencilConfigForOverlapTwoPass(o);dr(e,t,i,c,r,n,l,!1,a),dr(e,t,i,c,s,n,l,!0,a);}else {const[r,s]=e.getStencilConfigForOverlapAndUpdateStencilID(o);dr(e,t,i,s,r,n,l,!1,a);}}(e,i,o,r,a):t.ci(o)?function(e,t,i,o,r){if(\"translucent\"!==e.renderPass)return;if(0===i.paint.get(\"raster-opacity\"))return;if(!o.length)return;const{isRenderingToTexture:a}=r,s=t.getSource(),n=e.style.projection.useSubdivision;if(s instanceof X)pr(e,t,i,o,null,!1,!1,s.tileCoords,s.flippedWindingOrder,a);else if(n){const[r,s,n]=e.stencilConfigForOverlapTwoPass(o);pr(e,t,i,n,r,!1,!0,_r,!1,a),pr(e,t,i,n,s,!0,!0,_r,!1,a);}else {const[r,s]=e.getStencilConfigForOverlapAndUpdateStencilID(o);pr(e,t,i,s,r,!1,!0,_r,!1,a);}}(e,i,o,r,a):t.cj(o)?function(e,t,i,o,r){const a=i.paint.get(\"background-color\"),s=i.paint.get(\"background-opacity\");if(0===s)return;const{isRenderingToTexture:n}=r,l=e.context,c=l.gl,h=e.style.projection,u=e.transform,d=u.tileSize,_=i.paint.get(\"background-pattern\");if(e.isPatternMissing(_))return;const p=!_&&1===a.a&&1===s&&e.opaquePassEnabledForLayer()?\"opaque\":\"translucent\";if(e.renderPass!==p)return;const m=Vt.disabled,f=e.getDepthModeForSublayer(0,\"opaque\"===p?Ut.ReadWrite:Ut.ReadOnly),g=e.colorModeForRenderPass(),v=e.useProgram(_?\"backgroundPattern\":\"background\"),b=o||ve(u,{tileSize:d,terrain:e.style.map.terrain});_&&(l.activeTexture.set(c.TEXTURE0),e.imageManager.bind(e.context));const x=i.getCrossfadeParameters();for(const t of b){const o=u.getProjectionData({overscaledTileID:t,applyGlobeMatrix:!n,applyTerrainMatrix:!0}),r=_?oo(s,e,_,{tileID:t,tileSize:d},x):io(s,a),p=e.style.map.terrain&&e.style.map.terrain.getTerrainData(t),b=h.getMeshFromTileID(l,t.canonical,!1,!0,\"raster\");v.draw(l,c.TRIANGLES,f,m,g,Zt.backCCW,r,p,o,i.id,b.vertexBuffer,b.indexBuffer,b.segments);}}(e,0,o,r,a):t.ck(o)&&function(e,t,i,o){const{isRenderingGlobe:r}=o,a=e.context,s=i.implementation,n=e.style.projection,l=e.transform,c=l.getProjectionDataForCustomLayer(r),h={farZ:l.farZ,nearZ:l.nearZ,fov:l.fov*Math.PI/180,modelViewProjectionMatrix:l.modelViewProjectionMatrix,projectionMatrix:l.projectionMatrix,shaderData:{variantName:n.shaderVariantName,vertexShaderPrelude:`const float PI = 3.141592653589793;\\nuniform mat4 u_projection_matrix;\\n${n.shaderPreludeCode.vertexSource}`,define:n.shaderDefine},defaultProjectionData:c},u=s.renderingMode?s.renderingMode:\"2d\";if(\"offscreen\"===e.renderPass){const t=s.prerender;t&&(e.setCustomLayerDefaults(),a.setColorMode(e.colorModeForRenderPass()),t.call(s,a.gl,h),a.setDirty(),e.setBaseState());}else if(\"translucent\"===e.renderPass){e.setCustomLayerDefaults(),a.setColorMode(e.colorModeForRenderPass()),a.setStencilMode(Vt.disabled);const t=\"3d\"===u?e.getDepthModeFor3D():e.getDepthModeForSublayer(0,Ut.ReadOnly);a.setDepthMode(t),s.render(a.gl,h),a.setDirty(),e.setBaseState(),a.bindFramebuffer.set(null);}}(e,0,o,a));}saveTileTexture(e){const t=this._tileTextures[e.size[0]];t?t.push(e):this._tileTextures[e.size[0]]=[e];}getTileTexture(e){const t=this._tileTextures[e];return t&&t.length>0?t.pop():null}isPatternMissing(e){if(!e)return !1;if(!e.from||!e.to)return !0;const t=this.imageManager.getPattern(e.from.toString()),i=this.imageManager.getPattern(e.to.toString());return !t||!i}useProgram(e,t,i=!1,o=[]){this.cache=this.cache||{};const r=!!this.style.map.terrain,a=this.style.projection,s=i?xt.projectionMercator:a.shaderPreludeCode,n=i?Pt:a.shaderDefine,l=e+(t?t.cacheKey:\"\")+`/${i?Ct:a.shaderVariantName}`+(this._showOverdrawInspector?\"/overdraw\":\"\")+(r?\"/terrain\":\"\")+(o?`/${o.join(\"/\")}`:\"\");return this.cache[l]||(this.cache[l]=new Si(this.context,xt[e],t,ao[e],this._showOverdrawInspector,r,s,n,o)),this.cache[l]}setCustomLayerDefaults(){this.context.unbindVAO(),this.context.cullFace.setDefault(),this.context.activeTexture.setDefault(),this.context.pixelStoreUnpack.setDefault(),this.context.pixelStoreUnpackPremultiplyAlpha.setDefault(),this.context.pixelStoreUnpackFlipY.setDefault();}setBaseState(){const e=this.context.gl;this.context.cullFace.set(!1),this.context.viewport.set([0,0,this.width,this.height]),this.context.blendEquation.set(e.FUNC_ADD);}initDebugOverlayCanvas(){null==this.debugOverlayCanvas&&(this.debugOverlayCanvas=document.createElement(\"canvas\"),this.debugOverlayCanvas.width=512,this.debugOverlayCanvas.height=512,this.debugOverlayTexture=new t.T(this.context,this.debugOverlayCanvas,this.context.gl.RGBA));}destroy(){this.debugOverlayTexture&&this.debugOverlayTexture.destroy();}overLimit(){const{drawingBufferWidth:e,drawingBufferHeight:t}=this.context.gl;return this.width!==e||this.height!==t}}function Sr(e,t){let i,o=!1,r=null,a=null;const s=()=>{r=null,o&&(e.apply(a,i),r=setTimeout(s,t),o=!1);};return (...e)=>(o=!0,a=this,i=e,r||s(),r)}class Er{constructor(e){this._getCurrentHash=()=>{const e=window.location.hash.replace(\"#\",\"\");if(this._hashName){let t;return e.split(\"&\").map((e=>e.split(\"=\"))).forEach((e=>{e[0]===this._hashName&&(t=e);})),(t&&t[1]||\"\").split(\"/\")}return e.split(\"/\")},this._onHashChange=()=>{const e=this._getCurrentHash();if(!this._isValidHash(e))return !1;const t=this._map.dragRotate.isEnabled()&&this._map.touchZoomRotate.isEnabled()?+(e[3]||0):this._map.getBearing();return this._map.jumpTo({center:[+e[2],+e[1]],zoom:+e[0],bearing:t,pitch:+(e[4]||0)}),!0},this._updateHashUnthrottled=()=>{const e=window.location.href.replace(/(#.*)?$/,this.getHashString());window.history.replaceState(window.history.state,null,e);},this._removeHash=()=>{const e=this._getCurrentHash();if(0===e.length)return;const t=e.join(\"/\");let i=t;i.split(\"&\").length>0&&(i=i.split(\"&\")[0]),this._hashName&&(i=`${this._hashName}=${t}`);let o=window.location.hash.replace(i,\"\");o.startsWith(\"#&\")?o=o.slice(0,1)+o.slice(2):\"#\"===o&&(o=\"\");let r=window.location.href.replace(/(#.+)?$/,o);r=r.replace(\"&&\",\"&\"),window.history.replaceState(window.history.state,null,r);},this._updateHash=Sr(this._updateHashUnthrottled,300),this._hashName=e&&encodeURIComponent(e);}addTo(e){return this._map=e,addEventListener(\"hashchange\",this._onHashChange,!1),this._map.on(\"moveend\",this._updateHash),this}remove(){return removeEventListener(\"hashchange\",this._onHashChange,!1),this._map.off(\"moveend\",this._updateHash),clearTimeout(this._updateHash()),this._removeHash(),delete this._map,this}getHashString(e){const t=this._map.getCenter(),i=Math.round(100*this._map.getZoom())/100,o=Math.ceil((i*Math.LN2+Math.log(512/360/.5))/Math.LN10),r=Math.pow(10,o),a=Math.round(t.lng*r)/r,s=Math.round(t.lat*r)/r,n=this._map.getBearing(),l=this._map.getPitch();let c=\"\";if(c+=e?`/${a}/${s}/${i}`:`${i}/${s}/${a}`,(n||l)&&(c+=\"/\"+Math.round(10*n)/10),l&&(c+=`/${Math.round(l)}`),this._hashName){const e=this._hashName;let t=!1;const i=window.location.hash.slice(1).split(\"&\").map((i=>{const o=i.split(\"=\")[0];return o===e?(t=!0,`${o}=${c}`):i})).filter((e=>e));return t||i.push(`${e}=${c}`),`#${i.join(\"&\")}`}return `#${c}`}_isValidHash(e){if(e.length<3||e.some(isNaN))return !1;try{new t.S(+e[2],+e[1]);}catch(e){return !1}const i=+e[0],o=+(e[3]||0),r=+(e[4]||0);return i>=this._map.getMinZoom()&&i<=this._map.getMaxZoom()&&o>=-180&&o<=180&&r>=this._map.getMinPitch()&&r<=this._map.getMaxPitch()}}const Rr={linearity:.3,easing:t.cl(0,0,.3,1)},zr=t.e({deceleration:2500,maxSpeed:1400},Rr),Dr=t.e({deceleration:20,maxSpeed:1400},Rr),Ar=t.e({deceleration:1e3,maxSpeed:360},Rr),Lr=t.e({deceleration:1e3,maxSpeed:90},Rr),kr=t.e({deceleration:1e3,maxSpeed:360},Rr);class Fr{constructor(e){this._map=e,this.clear();}clear(){this._inertiaBuffer=[];}record(e){this._drainInertiaBuffer(),this._inertiaBuffer.push({time:s.now(),settings:e});}_drainInertiaBuffer(){const e=this._inertiaBuffer,t=s.now();for(;e.length>0&&t-e[0].time>160;)e.shift();}_onMoveEnd(e){if(this._drainInertiaBuffer(),this._inertiaBuffer.length<2)return;const i={zoom:0,bearing:0,pitch:0,roll:0,pan:new t.P(0,0),pinchAround:void 0,around:void 0};for(const{settings:e}of this._inertiaBuffer)i.zoom+=e.zoomDelta||0,i.bearing+=e.bearingDelta||0,i.pitch+=e.pitchDelta||0,i.roll+=e.rollDelta||0,e.panDelta&&i.pan._add(e.panDelta),e.around&&(i.around=e.around),e.pinchAround&&(i.pinchAround=e.pinchAround);const o=this._inertiaBuffer[this._inertiaBuffer.length-1].time-this._inertiaBuffer[0].time,r={};if(i.pan.mag()){const a=Or(i.pan.mag(),o,t.e({},zr,e||{})),s=i.pan.mult(a.amount/i.pan.mag()),n=this._map.cameraHelper.handlePanInertia(s,this._map.transform);r.center=n.easingCenter,r.offset=n.easingOffset,Br(r,a);}if(i.zoom){const e=Or(i.zoom,o,Dr);r.zoom=this._map.transform.zoom+e.amount,Br(r,e);}if(i.bearing){const e=Or(i.bearing,o,Ar);r.bearing=this._map.transform.bearing+t.ag(e.amount,-179,179),Br(r,e);}if(i.pitch){const e=Or(i.pitch,o,Lr);r.pitch=this._map.transform.pitch+e.amount,Br(r,e);}if(i.roll){const e=Or(i.roll,o,kr);r.roll=this._map.transform.roll+t.ag(e.amount,-179,179),Br(r,e);}if(r.zoom||r.bearing){const e=void 0===i.pinchAround?i.around:i.pinchAround;r.around=e?this._map.unproject(e):this._map.getCenter();}return this.clear(),t.e(r,{noMoveStart:!0})}}function Br(e,t){(!e.duration||e.duration<t.duration)&&(e.duration=t.duration,e.easing=t.easing);}function Or(e,i,o){const{maxSpeed:r,linearity:a,deceleration:s}=o,n=t.ag(e*a/(i/1e3),-r,r),l=Math.abs(n)/(s*a);return {easing:o.easing,duration:1e3*l,amount:n*(l/2)}}class jr extends t.l{preventDefault(){this._defaultPrevented=!0;}get defaultPrevented(){return this._defaultPrevented}constructor(e,i,o,r={}){o=o instanceof MouseEvent?o:new MouseEvent(e,o);const a=n.mousePos(i.getCanvas(),o),s=i.unproject(a);super(e,t.e({point:a,lngLat:s,originalEvent:o},r)),this._defaultPrevented=!1,this.target=i;}}class Nr extends t.l{preventDefault(){this._defaultPrevented=!0;}get defaultPrevented(){return this._defaultPrevented}constructor(e,i,o){const r=\"touchend\"===e?o.changedTouches:o.touches,a=n.touchPos(i.getCanvasContainer(),r),s=a.map((e=>i.unproject(e))),l=a.reduce(((e,t,i,o)=>e.add(t.div(o.length))),new t.P(0,0));super(e,{points:a,point:l,lngLats:s,lngLat:i.unproject(l),originalEvent:o}),this._defaultPrevented=!1;}}class Zr extends t.l{preventDefault(){this._defaultPrevented=!0;}get defaultPrevented(){return this._defaultPrevented}constructor(e,t,i){super(e,{originalEvent:i}),this._defaultPrevented=!1;}}class Ur{constructor(e,t){this._map=e,this._clickTolerance=t.clickTolerance;}reset(){delete this._mousedownPos;}wheel(e){return this._firePreventable(new Zr(e.type,this._map,e))}mousedown(e,t){return this._mousedownPos=t,this._firePreventable(new jr(e.type,this._map,e))}mouseup(e){this._map.fire(new jr(e.type,this._map,e));}click(e,t){this._mousedownPos&&this._mousedownPos.dist(t)>=this._clickTolerance||this._map.fire(new jr(e.type,this._map,e));}dblclick(e){return this._firePreventable(new jr(e.type,this._map,e))}mouseover(e){this._map.fire(new jr(e.type,this._map,e));}mouseout(e){this._map.fire(new jr(e.type,this._map,e));}touchstart(e){return this._firePreventable(new Nr(e.type,this._map,e))}touchmove(e){this._map.fire(new Nr(e.type,this._map,e));}touchend(e){this._map.fire(new Nr(e.type,this._map,e));}touchcancel(e){this._map.fire(new Nr(e.type,this._map,e));}_firePreventable(e){if(this._map.fire(e),e.defaultPrevented)return {}}isEnabled(){return !0}isActive(){return !1}enable(){}disable(){}}class Gr{constructor(e){this._map=e;}reset(){this._delayContextMenu=!1,this._ignoreContextMenu=!0,delete this._contextMenuEvent;}mousemove(e){this._map.fire(new jr(e.type,this._map,e));}mousedown(){this._delayContextMenu=!0,this._ignoreContextMenu=!1;}mouseup(){this._delayContextMenu=!1,this._contextMenuEvent&&(this._map.fire(new jr(\"contextmenu\",this._map,this._contextMenuEvent)),delete this._contextMenuEvent);}contextmenu(e){this._delayContextMenu?this._contextMenuEvent=e:this._ignoreContextMenu||this._map.fire(new jr(e.type,this._map,e)),this._map.listens(\"contextmenu\")&&e.preventDefault();}isEnabled(){return !0}isActive(){return !1}enable(){}disable(){}}class Vr{constructor(e){this._map=e;}get transform(){return this._map._requestedCameraState||this._map.transform}get center(){return {lng:this.transform.center.lng,lat:this.transform.center.lat}}get zoom(){return this.transform.zoom}get pitch(){return this.transform.pitch}get bearing(){return this.transform.bearing}unproject(e){return this.transform.screenPointToLocation(t.P.convert(e),this._map.terrain)}}class $r{constructor(e,t){this._map=e,this._tr=new Vr(e),this._el=e.getCanvasContainer(),this._container=e.getContainer(),this._clickTolerance=t.clickTolerance||1;}isEnabled(){return !!this._enabled}isActive(){return !!this._active}enable(){this.isEnabled()||(this._enabled=!0);}disable(){this.isEnabled()&&(this._enabled=!1);}mousedown(e,t){this.isEnabled()&&e.shiftKey&&0===e.button&&(n.disableDrag(),this._startPos=this._lastPos=t,this._active=!0);}mousemoveWindow(e,t){if(!this._active)return;const i=t;if(this._lastPos.equals(i)||!this._box&&i.dist(this._startPos)<this._clickTolerance)return;const o=this._startPos;this._lastPos=i,this._box||(this._box=n.create(\"div\",\"maplibregl-boxzoom\",this._container),this._container.classList.add(\"maplibregl-crosshair\"),this._fireEvent(\"boxzoomstart\",e));const r=Math.min(o.x,i.x),a=Math.max(o.x,i.x),s=Math.min(o.y,i.y),l=Math.max(o.y,i.y);n.setTransform(this._box,`translate(${r}px,${s}px)`),this._box.style.width=a-r+\"px\",this._box.style.height=l-s+\"px\";}mouseupWindow(e,i){if(!this._active)return;if(0!==e.button)return;const o=this._startPos,r=i;if(this.reset(),n.suppressClick(),o.x!==r.x||o.y!==r.y)return this._map.fire(new t.l(\"boxzoomend\",{originalEvent:e})),{cameraAnimation:e=>e.fitScreenCoordinates(o,r,this._tr.bearing,{linear:!0})};this._fireEvent(\"boxzoomcancel\",e);}keydown(e){this._active&&27===e.keyCode&&(this.reset(),this._fireEvent(\"boxzoomcancel\",e));}reset(){this._active=!1,this._container.classList.remove(\"maplibregl-crosshair\"),this._box&&(n.remove(this._box),this._box=null),n.enableDrag(),delete this._startPos,delete this._lastPos;}_fireEvent(e,i){return this._map.fire(new t.l(e,{originalEvent:i}))}}function qr(e,t){if(e.length!==t.length)throw new Error(`The number of touches and points are not equal - touches ${e.length}, points ${t.length}`);const i={};for(let o=0;o<e.length;o++)i[e[o].identifier]=t[o];return i}class Wr{constructor(e){this.reset(),this.numTouches=e.numTouches;}reset(){delete this.centroid,delete this.startTime,delete this.touches,this.aborted=!1;}touchstart(e,i,o){(this.centroid||o.length>this.numTouches)&&(this.aborted=!0),this.aborted||(void 0===this.startTime&&(this.startTime=e.timeStamp),o.length===this.numTouches&&(this.centroid=function(e){const i=new t.P(0,0);for(const t of e)i._add(t);return i.div(e.length)}(i),this.touches=qr(o,i)));}touchmove(e,t,i){if(this.aborted||!this.centroid)return;const o=qr(i,t);for(const e in this.touches){const t=o[e];(!t||t.dist(this.touches[e])>30)&&(this.aborted=!0);}}touchend(e,t,i){if((!this.centroid||e.timeStamp-this.startTime>500)&&(this.aborted=!0),0===i.length){const e=!this.aborted&&this.centroid;if(this.reset(),e)return e}}}class Hr{constructor(e){this.singleTap=new Wr(e),this.numTaps=e.numTaps,this.reset();}reset(){this.lastTime=1/0,delete this.lastTap,this.count=0,this.singleTap.reset();}touchstart(e,t,i){this.singleTap.touchstart(e,t,i);}touchmove(e,t,i){this.singleTap.touchmove(e,t,i);}touchend(e,t,i){const o=this.singleTap.touchend(e,t,i);if(o){const t=e.timeStamp-this.lastTime<500,i=!this.lastTap||this.lastTap.dist(o)<30;if(t&&i||this.reset(),this.count++,this.lastTime=e.timeStamp,this.lastTap=o,this.count===this.numTaps)return this.reset(),o}}}class Xr{constructor(e){this._tr=new Vr(e),this._zoomIn=new Hr({numTouches:1,numTaps:2}),this._zoomOut=new Hr({numTouches:2,numTaps:1}),this.reset();}reset(){this._active=!1,this._zoomIn.reset(),this._zoomOut.reset();}touchstart(e,t,i){this._zoomIn.touchstart(e,t,i),this._zoomOut.touchstart(e,t,i);}touchmove(e,t,i){this._zoomIn.touchmove(e,t,i),this._zoomOut.touchmove(e,t,i);}touchend(e,t,i){const o=this._zoomIn.touchend(e,t,i),r=this._zoomOut.touchend(e,t,i),a=this._tr;return o?(this._active=!0,e.preventDefault(),setTimeout((()=>this.reset()),0),{cameraAnimation:t=>t.easeTo({duration:300,zoom:a.zoom+1,around:a.unproject(o)},{originalEvent:e})}):r?(this._active=!0,e.preventDefault(),setTimeout((()=>this.reset()),0),{cameraAnimation:t=>t.easeTo({duration:300,zoom:a.zoom-1,around:a.unproject(r)},{originalEvent:e})}):void 0}touchcancel(){this.reset();}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}}class Kr{constructor(e){this._enabled=!!e.enable,this._moveStateManager=e.moveStateManager,this._clickTolerance=e.clickTolerance||1,this._moveFunction=e.move,this._activateOnStart=!!e.activateOnStart,e.assignEvents(this),this.reset();}reset(e){this._active=!1,this._moved=!1,delete this._lastPoint,this._moveStateManager.endMove(e);}_move(...e){const t=this._moveFunction(...e);if(t.bearingDelta||t.pitchDelta||t.rollDelta||t.around||t.panDelta)return this._active=!0,t}dragStart(e,t){this.isEnabled()&&!this._lastPoint&&this._moveStateManager.isValidStartEvent(e)&&(this._moveStateManager.startMove(e),this._lastPoint=Array.isArray(t)?t[0]:t,this._activateOnStart&&this._lastPoint&&(this._active=!0));}dragMove(e,t){if(!this.isEnabled())return;const i=this._lastPoint;if(!i)return;if(e.preventDefault(),!this._moveStateManager.isValidMoveEvent(e))return void this.reset(e);const o=Array.isArray(t)?t[0]:t;return !this._moved&&o.dist(i)<this._clickTolerance?void 0:(this._moved=!0,this._lastPoint=o,this._move(i,o))}dragEnd(e){this.isEnabled()&&this._lastPoint&&this._moveStateManager.isValidEndEvent(e)&&(this._moved&&n.suppressClick(),this.reset(e));}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}getClickTolerance(){return this._clickTolerance}}const Yr=0,Qr=2,Jr={[Yr]:1,[Qr]:2};class ea{constructor(e){this._correctEvent=e.checkCorrectEvent;}startMove(e){const t=n.mouseButton(e);this._eventButton=t;}endMove(e){delete this._eventButton;}isValidStartEvent(e){return this._correctEvent(e)}isValidMoveEvent(e){return !function(e,t){const i=Jr[t];return void 0===e.buttons||(e.buttons&i)!==i}(e,this._eventButton)}isValidEndEvent(e){return n.mouseButton(e)===this._eventButton}}class ta{constructor(){this._firstTouch=void 0;}_isOneFingerTouch(e){return 1===e.targetTouches.length}_isSameTouchEvent(e){return e.targetTouches[0].identifier===this._firstTouch}startMove(e){this._firstTouch=e.targetTouches[0].identifier;}endMove(e){delete this._firstTouch;}isValidStartEvent(e){return this._isOneFingerTouch(e)}isValidMoveEvent(e){return this._isOneFingerTouch(e)&&this._isSameTouchEvent(e)}isValidEndEvent(e){return this._isOneFingerTouch(e)&&this._isSameTouchEvent(e)}}class ia{constructor(e=new ea({checkCorrectEvent:()=>!0}),t=new ta){this.mouseMoveStateManager=e,this.oneFingerTouchMoveStateManager=t;}_executeRelevantHandler(e,t,i){return e instanceof MouseEvent?t(e):\"undefined\"!=typeof TouchEvent&&e instanceof TouchEvent?i(e):void 0}startMove(e){this._executeRelevantHandler(e,(e=>this.mouseMoveStateManager.startMove(e)),(e=>this.oneFingerTouchMoveStateManager.startMove(e)));}endMove(e){this._executeRelevantHandler(e,(e=>this.mouseMoveStateManager.endMove(e)),(e=>this.oneFingerTouchMoveStateManager.endMove(e)));}isValidStartEvent(e){return this._executeRelevantHandler(e,(e=>this.mouseMoveStateManager.isValidStartEvent(e)),(e=>this.oneFingerTouchMoveStateManager.isValidStartEvent(e)))}isValidMoveEvent(e){return this._executeRelevantHandler(e,(e=>this.mouseMoveStateManager.isValidMoveEvent(e)),(e=>this.oneFingerTouchMoveStateManager.isValidMoveEvent(e)))}isValidEndEvent(e){return this._executeRelevantHandler(e,(e=>this.mouseMoveStateManager.isValidEndEvent(e)),(e=>this.oneFingerTouchMoveStateManager.isValidEndEvent(e)))}}const oa=e=>{e.mousedown=e.dragStart,e.mousemoveWindow=e.dragMove,e.mouseup=e.dragEnd,e.contextmenu=e=>{e.preventDefault();};};class ra{constructor(e,t){this._clickTolerance=e.clickTolerance||1,this._map=t,this.reset();}reset(){this._active=!1,this._touches={},this._sum=new t.P(0,0);}_shouldBePrevented(e){return e<(this._map.cooperativeGestures.isEnabled()?2:1)}touchstart(e,t,i){return this._calculateTransform(e,t,i)}touchmove(e,t,i){if(this._active){if(!this._shouldBePrevented(i.length))return e.preventDefault(),this._calculateTransform(e,t,i);this._map.cooperativeGestures.notifyGestureBlocked(\"touch_pan\",e);}}touchend(e,t,i){this._calculateTransform(e,t,i),this._active&&this._shouldBePrevented(i.length)&&this.reset();}touchcancel(){this.reset();}_calculateTransform(e,i,o){o.length>0&&(this._active=!0);const r=qr(o,i),a=new t.P(0,0),s=new t.P(0,0);let n=0;for(const e in r){const t=r[e],i=this._touches[e];i&&(a._add(t),s._add(t.sub(i)),n++,r[e]=t);}if(this._touches=r,this._shouldBePrevented(n)||!s.mag())return;const l=s.div(n);return this._sum._add(l),this._sum.mag()<this._clickTolerance?void 0:{around:a.div(n),panDelta:l}}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}}class aa{constructor(){this.reset();}reset(){this._active=!1,delete this._firstTwoTouches;}touchstart(e,t,i){this._firstTwoTouches||i.length<2||(this._firstTwoTouches=[i[0].identifier,i[1].identifier],this._start([t[0],t[1]]));}touchmove(e,t,i){if(!this._firstTwoTouches)return;e.preventDefault();const[o,r]=this._firstTwoTouches,a=sa(i,t,o),s=sa(i,t,r);if(!a||!s)return;const n=this._aroundCenter?null:a.add(s).div(2);return this._move([a,s],n,e)}touchend(e,t,i){if(!this._firstTwoTouches)return;const[o,r]=this._firstTwoTouches,a=sa(i,t,o),s=sa(i,t,r);a&&s||(this._active&&n.suppressClick(),this.reset());}touchcancel(){this.reset();}enable(e){this._enabled=!0,this._aroundCenter=!!e&&\"center\"===e.around;}disable(){this._enabled=!1,this.reset();}isEnabled(){return !!this._enabled}isActive(){return !!this._active}}function sa(e,t,i){for(let o=0;o<e.length;o++)if(e[o].identifier===i)return t[o]}function na(e,t){return Math.log(e/t)/Math.LN2}class la extends aa{reset(){super.reset(),delete this._distance,delete this._startDistance;}_start(e){this._startDistance=this._distance=e[0].dist(e[1]);}_move(e,t){const i=this._distance;if(this._distance=e[0].dist(e[1]),this._active||!(Math.abs(na(this._distance,this._startDistance))<.1))return this._active=!0,{zoomDelta:na(this._distance,i),pinchAround:t}}}function ca(e,t){return 180*e.angleWith(t)/Math.PI}class ha extends aa{reset(){super.reset(),delete this._minDiameter,delete this._startVector,delete this._vector;}_start(e){this._startVector=this._vector=e[0].sub(e[1]),this._minDiameter=e[0].dist(e[1]);}_move(e,t,i){const o=this._vector;if(this._vector=e[0].sub(e[1]),this._active||!this._isBelowThreshold(this._vector))return this._active=!0,{bearingDelta:ca(this._vector,o),pinchAround:t}}_isBelowThreshold(e){this._minDiameter=Math.min(this._minDiameter,e.mag());const t=25/(Math.PI*this._minDiameter)*360,i=ca(e,this._startVector);return Math.abs(i)<t}}function ua(e){return Math.abs(e.y)>Math.abs(e.x)}class da extends aa{constructor(e){super(),this._currentTouchCount=0,this._map=e;}reset(){super.reset(),this._valid=void 0,delete this._firstMove,delete this._lastPoints;}touchstart(e,t,i){super.touchstart(e,t,i),this._currentTouchCount=i.length;}_start(e){this._lastPoints=e,ua(e[0].sub(e[1]))&&(this._valid=!1);}_move(e,t,i){if(this._map.cooperativeGestures.isEnabled()&&this._currentTouchCount<3)return;const o=e[0].sub(this._lastPoints[0]),r=e[1].sub(this._lastPoints[1]);return this._valid=this.gestureBeginsVertically(o,r,i.timeStamp),this._valid?(this._lastPoints=e,this._active=!0,{pitchDelta:(o.y+r.y)/2*-.5}):void 0}gestureBeginsVertically(e,t,i){if(void 0!==this._valid)return this._valid;const o=e.mag()>=2,r=t.mag()>=2;if(!o&&!r)return;if(!o||!r)return void 0===this._firstMove&&(this._firstMove=i),i-this._firstMove<100&&void 0;const a=e.y>0==t.y>0;return ua(e)&&ua(t)&&a}}const _a={panStep:100,bearingStep:15,pitchStep:10};class pa{constructor(e){this._tr=new Vr(e);const t=_a;this._panStep=t.panStep,this._bearingStep=t.bearingStep,this._pitchStep=t.pitchStep,this._rotationDisabled=!1;}reset(){this._active=!1;}keydown(e){if(e.altKey||e.ctrlKey||e.metaKey)return;let t=0,i=0,o=0,r=0,a=0;switch(e.keyCode){case 61:case 107:case 171:case 187:t=1;break;case 189:case 109:case 173:t=-1;break;case 37:e.shiftKey?i=-1:(e.preventDefault(),r=-1);break;case 39:e.shiftKey?i=1:(e.preventDefault(),r=1);break;case 38:e.shiftKey?o=1:(e.preventDefault(),a=-1);break;case 40:e.shiftKey?o=-1:(e.preventDefault(),a=1);break;default:return}return this._rotationDisabled&&(i=0,o=0),{cameraAnimation:s=>{const n=this._tr;s.easeTo({duration:300,easeId:\"keyboardHandler\",easing:ma,zoom:t?Math.round(n.zoom)+t*(e.shiftKey?2:1):n.zoom,bearing:n.bearing+i*this._bearingStep,pitch:n.pitch+o*this._pitchStep,offset:[-r*this._panStep,-a*this._panStep],center:n.center},{originalEvent:e});}}}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}disableRotation(){this._rotationDisabled=!0;}enableRotation(){this._rotationDisabled=!1;}}function ma(e){return e*(2-e)}const fa=4.000244140625,ga=1/450;class va{constructor(e,t){this._onTimeout=e=>{this._type=\"wheel\",this._delta-=this._lastValue,this._active||this._start(e);},this._map=e,this._tr=new Vr(e),this._triggerRenderFrame=t,this._delta=0,this._defaultZoomRate=.01,this._wheelZoomRate=ga;}setZoomRate(e){this._defaultZoomRate=e;}setWheelZoomRate(e){this._wheelZoomRate=e;}isEnabled(){return !!this._enabled}isActive(){return !!this._active||void 0!==this._finishTimeout}isZooming(){return !!this._zooming}enable(e){this.isEnabled()||(this._enabled=!0,this._aroundCenter=!!e&&\"center\"===e.around);}disable(){this.isEnabled()&&(this._enabled=!1);}_shouldBePrevented(e){return !!this._map.cooperativeGestures.isEnabled()&&!(e.ctrlKey||this._map.cooperativeGestures.isBypassed(e))}wheel(e){if(!this.isEnabled())return;if(this._shouldBePrevented(e))return void this._map.cooperativeGestures.notifyGestureBlocked(\"wheel_zoom\",e);let t=e.deltaMode===WheelEvent.DOM_DELTA_LINE?40*e.deltaY:e.deltaY;const i=s.now(),o=i-(this._lastWheelEventTime||0);this._lastWheelEventTime=i,0!==t&&t%fa==0?this._type=\"wheel\":0!==t&&Math.abs(t)<4?this._type=\"trackpad\":o>400?(this._type=null,this._lastValue=t,this._timeout=setTimeout(this._onTimeout,40,e)):this._type||(this._type=Math.abs(o*t)<200?\"trackpad\":\"wheel\",this._timeout&&(clearTimeout(this._timeout),this._timeout=null,t+=this._lastValue)),e.shiftKey&&t&&(t/=4),this._type&&(this._lastWheelEvent=e,this._delta-=t,this._active||this._start(e)),e.preventDefault();}_start(e){if(!this._delta)return;this._frameId&&(this._frameId=null),this._active=!0,this.isZooming()||(this._zooming=!0),this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout);const i=n.mousePos(this._map.getCanvas(),e),o=this._tr;this._aroundPoint=this._aroundCenter?o.transform.locationToScreenPoint(t.S.convert(o.center)):i,this._frameId||(this._frameId=!0,this._triggerRenderFrame());}renderFrame(){if(!this._frameId)return;if(this._frameId=null,!this.isActive())return;const e=this._tr.transform;if(\"number\"==typeof this._lastExpectedZoom){const t=e.zoom-this._lastExpectedZoom;\"number\"==typeof this._startZoom&&(this._startZoom+=t),\"number\"==typeof this._targetZoom&&(this._targetZoom+=t);}if(0!==this._delta){const i=\"wheel\"===this._type&&Math.abs(this._delta)>fa?this._wheelZoomRate:this._defaultZoomRate;let o=2/(1+Math.exp(-Math.abs(this._delta*i)));this._delta<0&&0!==o&&(o=1/o);const r=\"number\"!=typeof this._targetZoom?e.scale:t.ae(this._targetZoom);this._targetZoom=e.getConstrained(e.getCameraLngLat(),t.aj(r*o)).zoom,\"wheel\"===this._type&&(this._startZoom=e.zoom,this._easing=this._smoothOutEasing(200)),this._delta=0;}const i=\"number\"!=typeof this._targetZoom?e.zoom:this._targetZoom,o=this._startZoom,r=this._easing;let a,n=!1;if(\"wheel\"===this._type&&o&&r){const e=s.now()-this._lastWheelEventTime,l=Math.min((e+5)/200,1),c=r(l);a=t.C.number(o,i,c),l<1?this._frameId||(this._frameId=!0):n=!0;}else a=i,n=!0;return this._active=!0,n&&(this._active=!1,this._finishTimeout=setTimeout((()=>{this._zooming=!1,this._triggerRenderFrame(),delete this._targetZoom,delete this._lastExpectedZoom,delete this._finishTimeout;}),200)),this._lastExpectedZoom=a,{noInertia:!0,needsRenderFrame:!n,zoomDelta:a-e.zoom,around:this._aroundPoint,originalEvent:this._lastWheelEvent}}_smoothOutEasing(e){let i=t.cn;if(this._prevEase){const e=this._prevEase,o=(s.now()-e.start)/e.duration,r=e.easing(o+.01)-e.easing(o),a=.27/Math.sqrt(r*r+1e-4)*.01,n=Math.sqrt(.0729-a*a);i=t.cl(a,n,.25,1);}return this._prevEase={start:s.now(),duration:e,easing:i},i}reset(){this._active=!1,this._zooming=!1,delete this._targetZoom,delete this._lastExpectedZoom,this._finishTimeout&&(clearTimeout(this._finishTimeout),delete this._finishTimeout);}}class ba{constructor(e,t){this._clickZoom=e,this._tapZoom=t;}enable(){this._clickZoom.enable(),this._tapZoom.enable();}disable(){this._clickZoom.disable(),this._tapZoom.disable();}isEnabled(){return this._clickZoom.isEnabled()&&this._tapZoom.isEnabled()}isActive(){return this._clickZoom.isActive()||this._tapZoom.isActive()}}class xa{constructor(e){this._tr=new Vr(e),this.reset();}reset(){this._active=!1;}dblclick(e,t){return e.preventDefault(),{cameraAnimation:i=>{i.easeTo({duration:300,zoom:this._tr.zoom+(e.shiftKey?-1:1),around:this._tr.unproject(t)},{originalEvent:e});}}}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}}class ya{constructor(){this._tap=new Hr({numTouches:1,numTaps:1}),this.reset();}reset(){this._active=!1,delete this._swipePoint,delete this._swipeTouch,delete this._tapTime,delete this._tapPoint,this._tap.reset();}touchstart(e,t,i){if(!this._swipePoint)if(this._tapTime){const o=t[0],r=e.timeStamp-this._tapTime<500,a=this._tapPoint.dist(o)<30;r&&a?i.length>0&&(this._swipePoint=o,this._swipeTouch=i[0].identifier):this.reset();}else this._tap.touchstart(e,t,i);}touchmove(e,t,i){if(this._tapTime){if(this._swipePoint){if(i[0].identifier!==this._swipeTouch)return;const o=t[0],r=o.y-this._swipePoint.y;return this._swipePoint=o,e.preventDefault(),this._active=!0,{zoomDelta:r/128}}}else this._tap.touchmove(e,t,i);}touchend(e,t,i){if(this._tapTime)this._swipePoint&&0===i.length&&this.reset();else {const o=this._tap.touchend(e,t,i);o&&(this._tapTime=e.timeStamp,this._tapPoint=o);}}touchcancel(){this.reset();}enable(){this._enabled=!0;}disable(){this._enabled=!1,this.reset();}isEnabled(){return this._enabled}isActive(){return this._active}}class wa{constructor(e,t,i){this._el=e,this._mousePan=t,this._touchPan=i;}enable(e){this._inertiaOptions=e||{},this._mousePan.enable(),this._touchPan.enable(),this._el.classList.add(\"maplibregl-touch-drag-pan\");}disable(){this._mousePan.disable(),this._touchPan.disable(),this._el.classList.remove(\"maplibregl-touch-drag-pan\");}isEnabled(){return this._mousePan.isEnabled()&&this._touchPan.isEnabled()}isActive(){return this._mousePan.isActive()||this._touchPan.isActive()}}class Ta{constructor(e,t,i,o){this._pitchWithRotate=e.pitchWithRotate,this._rollEnabled=e.rollEnabled,this._mouseRotate=t,this._mousePitch=i,this._mouseRoll=o;}enable(){this._mouseRotate.enable(),this._pitchWithRotate&&this._mousePitch.enable(),this._rollEnabled&&this._mouseRoll.enable();}disable(){this._mouseRotate.disable(),this._mousePitch.disable(),this._mouseRoll.disable();}isEnabled(){return this._mouseRotate.isEnabled()&&(!this._pitchWithRotate||this._mousePitch.isEnabled())&&(!this._rollEnabled||this._mouseRoll.isEnabled())}isActive(){return this._mouseRotate.isActive()||this._mousePitch.isActive()||this._mouseRoll.isActive()}}class Pa{constructor(e,t,i,o){this._el=e,this._touchZoom=t,this._touchRotate=i,this._tapDragZoom=o,this._rotationDisabled=!1,this._enabled=!0;}enable(e){this._touchZoom.enable(e),this._rotationDisabled||this._touchRotate.enable(e),this._tapDragZoom.enable(),this._el.classList.add(\"maplibregl-touch-zoom-rotate\");}disable(){this._touchZoom.disable(),this._touchRotate.disable(),this._tapDragZoom.disable(),this._el.classList.remove(\"maplibregl-touch-zoom-rotate\");}isEnabled(){return this._touchZoom.isEnabled()&&(this._rotationDisabled||this._touchRotate.isEnabled())&&this._tapDragZoom.isEnabled()}isActive(){return this._touchZoom.isActive()||this._touchRotate.isActive()||this._tapDragZoom.isActive()}disableRotation(){this._rotationDisabled=!0,this._touchRotate.disable();}enableRotation(){this._rotationDisabled=!1,this._touchZoom.isEnabled()&&this._touchRotate.enable();}}class Ca{constructor(e,t){this._bypassKey=-1!==navigator.userAgent.indexOf(\"Mac\")?\"metaKey\":\"ctrlKey\",this._map=e,this._options=t,this._enabled=!1;}isActive(){return !1}reset(){}_setupUI(){if(this._container)return;const e=this._map.getCanvasContainer();e.classList.add(\"maplibregl-cooperative-gestures\"),this._container=n.create(\"div\",\"maplibregl-cooperative-gesture-screen\",e);let t=this._map._getUIString(\"CooperativeGesturesHandler.WindowsHelpText\");\"metaKey\"===this._bypassKey&&(t=this._map._getUIString(\"CooperativeGesturesHandler.MacHelpText\"));const i=this._map._getUIString(\"CooperativeGesturesHandler.MobileHelpText\"),o=document.createElement(\"div\");o.className=\"maplibregl-desktop-message\",o.textContent=t,this._container.appendChild(o);const r=document.createElement(\"div\");r.className=\"maplibregl-mobile-message\",r.textContent=i,this._container.appendChild(r),this._container.setAttribute(\"aria-hidden\",\"true\");}_destroyUI(){this._container&&(n.remove(this._container),this._map.getCanvasContainer().classList.remove(\"maplibregl-cooperative-gestures\")),delete this._container;}enable(){this._setupUI(),this._enabled=!0;}disable(){this._enabled=!1,this._destroyUI();}isEnabled(){return this._enabled}isBypassed(e){return e[this._bypassKey]}notifyGestureBlocked(e,i){this._enabled&&(this._map.fire(new t.l(\"cooperativegestureprevented\",{gestureType:e,originalEvent:i})),this._container.classList.add(\"maplibregl-show\"),setTimeout((()=>{this._container.classList.remove(\"maplibregl-show\");}),100));}}const Ia=e=>e.zoom||e.drag||e.roll||e.pitch||e.rotate;class Ma extends t.l{}function Sa(e){return e.panDelta&&e.panDelta.mag()||e.zoomDelta||e.bearingDelta||e.pitchDelta||e.rollDelta}class Ea{constructor(e,i){this.handleWindowEvent=e=>{this.handleEvent(e,`${e.type}Window`);},this.handleEvent=(e,i)=>{if(\"blur\"===e.type)return void this.stop(!0);this._updatingCamera=!0;const o=\"renderFrame\"===e.type?void 0:e,r={needsRenderFrame:!1},a={},s={};for(const{handlerName:l,handler:c,allowed:h}of this._handlers){if(!c.isEnabled())continue;let u;if(this._blockedByActive(s,h,l))c.reset();else if(c[i||e.type]){if(t.co(e,i||e.type)){const t=n.mousePos(this._map.getCanvas(),e);u=c[i||e.type](e,t);}else if(t.cp(e,i||e.type)){const t=this._getMapTouches(e.touches),o=n.touchPos(this._map.getCanvas(),t);u=c[i||e.type](e,o,t);}else t.cq(i||e.type)||(u=c[i||e.type](e));this.mergeHandlerResult(r,a,u,l,o),u&&u.needsRenderFrame&&this._triggerRenderFrame();}(u||c.isActive())&&(s[l]=c);}const l={};for(const e in this._previousActiveHandlers)s[e]||(l[e]=o);this._previousActiveHandlers=s,(Object.keys(l).length||Sa(r))&&(this._changes.push([r,a,l]),this._triggerRenderFrame()),(Object.keys(s).length||Sa(r))&&this._map._stop(!0),this._updatingCamera=!1;const{cameraAnimation:c}=r;c&&(this._inertia.clear(),this._fireEvents({},{},!0),this._changes=[],c(this._map));},this._map=e,this._el=this._map.getCanvasContainer(),this._handlers=[],this._handlersById={},this._changes=[],this._inertia=new Fr(e),this._bearingSnap=i.bearingSnap,this._previousActiveHandlers={},this._eventsInProgress={},this._addDefaultHandlers(i);const o=this._el;this._listeners=[[o,\"touchstart\",{passive:!0}],[o,\"touchmove\",{passive:!1}],[o,\"touchend\",void 0],[o,\"touchcancel\",void 0],[o,\"mousedown\",void 0],[o,\"mousemove\",void 0],[o,\"mouseup\",void 0],[document,\"mousemove\",{capture:!0}],[document,\"mouseup\",void 0],[o,\"mouseover\",void 0],[o,\"mouseout\",void 0],[o,\"dblclick\",void 0],[o,\"click\",void 0],[o,\"keydown\",{capture:!1}],[o,\"keyup\",void 0],[o,\"wheel\",{passive:!1}],[o,\"contextmenu\",void 0],[window,\"blur\",void 0]];for(const[e,t,i]of this._listeners)n.addEventListener(e,t,e===document?this.handleWindowEvent:this.handleEvent,i);}destroy(){for(const[e,t,i]of this._listeners)n.removeEventListener(e,t,e===document?this.handleWindowEvent:this.handleEvent,i);}_addDefaultHandlers(e){const i=this._map,o=i.getCanvasContainer();this._add(\"mapEvent\",new Ur(i,e));const r=i.boxZoom=new $r(i,e);this._add(\"boxZoom\",r),e.interactive&&e.boxZoom&&r.enable();const a=i.cooperativeGestures=new Ca(i,e.cooperativeGestures);this._add(\"cooperativeGestures\",a),e.cooperativeGestures&&a.enable();const s=new Xr(i),l=new xa(i);i.doubleClickZoom=new ba(l,s),this._add(\"tapZoom\",s),this._add(\"clickZoom\",l),e.interactive&&e.doubleClickZoom&&i.doubleClickZoom.enable();const c=new ya;this._add(\"tapDragZoom\",c);const h=i.touchPitch=new da(i);this._add(\"touchPitch\",h),e.interactive&&e.touchPitch&&i.touchPitch.enable(e.touchPitch);const u=()=>i.project(i.getCenter()),d=function({enable:e,clickTolerance:i,aroundCenter:o=!0,minPixelCenterThreshold:r=100,rotateDegreesPerPixelMoved:a=.8},s){const l=new ea({checkCorrectEvent:e=>0===n.mouseButton(e)&&e.ctrlKey||2===n.mouseButton(e)&&!e.ctrlKey});return new Kr({clickTolerance:i,move:(e,i)=>{const n=s();if(o&&Math.abs(n.y-e.y)>r)return {bearingDelta:t.cm(new t.P(e.x,i.y),i,n)};let l=(i.x-e.x)*a;return o&&i.y<n.y&&(l=-l),{bearingDelta:l}},moveStateManager:l,enable:e,assignEvents:oa})}(e,u),_=function({enable:e,clickTolerance:t,pitchDegreesPerPixelMoved:i=-.5}){const o=new ea({checkCorrectEvent:e=>0===n.mouseButton(e)&&e.ctrlKey||2===n.mouseButton(e)});return new Kr({clickTolerance:t,move:(e,t)=>({pitchDelta:(t.y-e.y)*i}),moveStateManager:o,enable:e,assignEvents:oa})}(e),p=function({enable:e,clickTolerance:t,rollDegreesPerPixelMoved:i=.3},o){const r=new ea({checkCorrectEvent:e=>2===n.mouseButton(e)&&e.ctrlKey});return new Kr({clickTolerance:t,move:(e,t)=>{const r=o();let a=(t.x-e.x)*i;return t.y<r.y&&(a=-a),{rollDelta:a}},moveStateManager:r,enable:e,assignEvents:oa})}(e,u);i.dragRotate=new Ta(e,d,_,p),this._add(\"mouseRotate\",d,[\"mousePitch\"]),this._add(\"mousePitch\",_,[\"mouseRotate\",\"mouseRoll\"]),this._add(\"mouseRoll\",p,[\"mousePitch\"]),e.interactive&&e.dragRotate&&i.dragRotate.enable();const m=function({enable:e,clickTolerance:t}){const i=new ea({checkCorrectEvent:e=>0===n.mouseButton(e)&&!e.ctrlKey});return new Kr({clickTolerance:t,move:(e,t)=>({around:t,panDelta:t.sub(e)}),activateOnStart:!0,moveStateManager:i,enable:e,assignEvents:oa})}(e),f=new ra(e,i);i.dragPan=new wa(o,m,f),this._add(\"mousePan\",m),this._add(\"touchPan\",f,[\"touchZoom\",\"touchRotate\"]),e.interactive&&e.dragPan&&i.dragPan.enable(e.dragPan);const g=new ha,v=new la;i.touchZoomRotate=new Pa(o,v,g,c),this._add(\"touchRotate\",g,[\"touchPan\",\"touchZoom\"]),this._add(\"touchZoom\",v,[\"touchPan\",\"touchRotate\"]),e.interactive&&e.touchZoomRotate&&i.touchZoomRotate.enable(e.touchZoomRotate);const b=i.scrollZoom=new va(i,(()=>this._triggerRenderFrame()));this._add(\"scrollZoom\",b,[\"mousePan\"]),e.interactive&&e.scrollZoom&&i.scrollZoom.enable(e.scrollZoom);const x=i.keyboard=new pa(i);this._add(\"keyboard\",x),e.interactive&&e.keyboard&&i.keyboard.enable(),this._add(\"blockableMapEvent\",new Gr(i));}_add(e,t,i){this._handlers.push({handlerName:e,handler:t,allowed:i}),this._handlersById[e]=t;}stop(e){if(!this._updatingCamera){for(const{handler:e}of this._handlers)e.reset();this._inertia.clear(),this._fireEvents({},{},e),this._changes=[];}}isActive(){for(const{handler:e}of this._handlers)if(e.isActive())return !0;return !1}isZooming(){return !!this._eventsInProgress.zoom||this._map.scrollZoom.isZooming()}isRotating(){return !!this._eventsInProgress.rotate}isMoving(){return Boolean(Ia(this._eventsInProgress))||this.isZooming()}_blockedByActive(e,t,i){for(const o in e)if(o!==i&&(!t||t.indexOf(o)<0))return !0;return !1}_getMapTouches(e){const t=[];for(const i of e)this._el.contains(i.target)&&t.push(i);return t}mergeHandlerResult(e,i,o,r,a){if(!o)return;t.e(e,o);const s={handlerName:r,originalEvent:o.originalEvent||a};void 0!==o.zoomDelta&&(i.zoom=s),void 0!==o.panDelta&&(i.drag=s),void 0!==o.rollDelta&&(i.roll=s),void 0!==o.pitchDelta&&(i.pitch=s),void 0!==o.bearingDelta&&(i.rotate=s);}_applyChanges(){const e={},i={},o={};for(const[r,a,s]of this._changes)r.panDelta&&(e.panDelta=(e.panDelta||new t.P(0,0))._add(r.panDelta)),r.zoomDelta&&(e.zoomDelta=(e.zoomDelta||0)+r.zoomDelta),r.bearingDelta&&(e.bearingDelta=(e.bearingDelta||0)+r.bearingDelta),r.pitchDelta&&(e.pitchDelta=(e.pitchDelta||0)+r.pitchDelta),r.rollDelta&&(e.rollDelta=(e.rollDelta||0)+r.rollDelta),void 0!==r.around&&(e.around=r.around),void 0!==r.pinchAround&&(e.pinchAround=r.pinchAround),r.noInertia&&(e.noInertia=r.noInertia),t.e(i,a),t.e(o,s);this._updateMapTransform(e,i,o),this._changes=[];}_updateMapTransform(e,t,i){const o=this._map,r=o._getTransformForUpdate(),a=o.terrain;if(!(Sa(e)||a&&this._terrainMovement))return this._fireEvents(t,i,!0);o._stop(!0);let{panDelta:s,zoomDelta:n,bearingDelta:l,pitchDelta:c,rollDelta:h,around:u,pinchAround:d}=e;void 0!==d&&(u=d),u=u||o.transform.centerPoint,a&&!r.isPointOnMapSurface(u)&&(u=r.centerPoint);const _={panDelta:s,zoomDelta:n,rollDelta:h,pitchDelta:c,bearingDelta:l,around:u};this._map.cameraHelper.useGlobeControls&&!r.isPointOnMapSurface(u)&&(u=r.centerPoint);const p=u.distSqr(r.centerPoint)<.01?r.center:r.screenPointToLocation(s?u.sub(s):u);a?(this._map.cameraHelper.handleMapControlsRollPitchBearingZoom(_,r),this._terrainMovement||!t.drag&&!t.zoom?t.drag&&this._terrainMovement?r.setCenter(r.screenPointToLocation(r.centerPoint.sub(s))):this._map.cameraHelper.handleMapControlsPan(_,r,p):(this._terrainMovement=!0,this._map._elevationFreeze=!0,this._map.cameraHelper.handleMapControlsPan(_,r,p))):(this._map.cameraHelper.handleMapControlsRollPitchBearingZoom(_,r),this._map.cameraHelper.handleMapControlsPan(_,r,p)),o._applyUpdatedTransform(r),this._map._update(),e.noInertia||this._inertia.record(e),this._fireEvents(t,i,!0);}_fireEvents(e,i,o){const r=Ia(this._eventsInProgress),a=Ia(e),n={};for(const t in e){const{originalEvent:i}=e[t];this._eventsInProgress[t]||(n[`${t}start`]=i),this._eventsInProgress[t]=e[t];}!r&&a&&this._fireEvent(\"movestart\",a.originalEvent);for(const e in n)this._fireEvent(e,n[e]);a&&this._fireEvent(\"move\",a.originalEvent);for(const t in e){const{originalEvent:i}=e[t];this._fireEvent(t,i);}const l={};let c;for(const e in this._eventsInProgress){const{handlerName:t,originalEvent:o}=this._eventsInProgress[e];this._handlersById[t].isActive()||(delete this._eventsInProgress[e],c=i[t]||o,l[`${e}end`]=c);}for(const e in l)this._fireEvent(e,l[e]);const h=Ia(this._eventsInProgress),u=(r||a)&&!h;if(u&&this._terrainMovement){this._map._elevationFreeze=!1,this._terrainMovement=!1;const e=this._map._getTransformForUpdate();this._map.getCenterClampedToGround()&&e.recalculateZoomAndCenter(this._map.terrain),this._map._applyUpdatedTransform(e);}if(o&&u){this._updatingCamera=!0;const e=this._inertia._onMoveEnd(this._map.dragPan._inertiaOptions),i=e=>0!==e&&-this._bearingSnap<e&&e<this._bearingSnap;!e||!e.essential&&s.prefersReducedMotion?(this._map.fire(new t.l(\"moveend\",{originalEvent:c})),i(this._map.getBearing())&&this._map.resetNorth()):(i(e.bearing||this._map.getBearing())&&(e.bearing=0),e.freezeElevation=!0,this._map.easeTo(e,{originalEvent:c})),this._updatingCamera=!1;}}_fireEvent(e,i){this._map.fire(new t.l(e,i?{originalEvent:i}:{}));}_requestFrame(){return this._map.triggerRepaint(),this._map._renderTaskQueue.add((e=>{delete this._frameId,this.handleEvent(new Ma(\"renderFrame\",{timeStamp:e})),this._applyChanges();}))}_triggerRenderFrame(){void 0===this._frameId&&(this._frameId=this._requestFrame());}}class Ra extends t.E{constructor(e,t,i){super(),this._renderFrameCallback=()=>{const e=Math.min((s.now()-this._easeStart)/this._easeOptions.duration,1);this._onEaseFrame(this._easeOptions.easing(e)),e<1&&this._easeFrameId?this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback):this.stop();},this._moving=!1,this._zooming=!1,this.transform=e,this._bearingSnap=i.bearingSnap,this.cameraHelper=t,this.on(\"moveend\",(()=>{delete this._requestedCameraState;}));}migrateProjection(e,t){e.apply(this.transform),this.transform=e,this.cameraHelper=t;}getCenter(){return new t.S(this.transform.center.lng,this.transform.center.lat)}setCenter(e,t){return this.jumpTo({center:e},t)}getCenterElevation(){return this.transform.elevation}setCenterElevation(e,t){return this.jumpTo({elevation:e},t),this}getCenterClampedToGround(){return this._centerClampedToGround}setCenterClampedToGround(e){this._centerClampedToGround=e;}panBy(e,i,o){return e=t.P.convert(e).mult(-1),this.panTo(this.transform.center,t.e({offset:e},i),o)}panTo(e,i,o){return this.easeTo(t.e({center:e},i),o)}getZoom(){return this.transform.zoom}setZoom(e,t){return this.jumpTo({zoom:e},t),this}zoomTo(e,i,o){return this.easeTo(t.e({zoom:e},i),o)}zoomIn(e,t){return this.zoomTo(this.getZoom()+1,e,t),this}zoomOut(e,t){return this.zoomTo(this.getZoom()-1,e,t),this}getVerticalFieldOfView(){return this.transform.fov}setVerticalFieldOfView(e,i){return e!=this.transform.fov&&(this.transform.setFov(e),this.fire(new t.l(\"movestart\",i)).fire(new t.l(\"move\",i)).fire(new t.l(\"moveend\",i))),this}getBearing(){return this.transform.bearing}setBearing(e,t){return this.jumpTo({bearing:e},t),this}getPadding(){return this.transform.padding}setPadding(e,t){return this.jumpTo({padding:e},t),this}rotateTo(e,i,o){return this.easeTo(t.e({bearing:e},i),o)}resetNorth(e,i){return this.rotateTo(0,t.e({duration:1e3},e),i),this}resetNorthPitch(e,i){return this.easeTo(t.e({bearing:0,pitch:0,roll:0,duration:1e3},e),i),this}snapToNorth(e,t){return Math.abs(this.getBearing())<this._bearingSnap?this.resetNorth(e,t):this}getPitch(){return this.transform.pitch}setPitch(e,t){return this.jumpTo({pitch:e},t),this}getRoll(){return this.transform.roll}setRoll(e,t){return this.jumpTo({roll:e},t),this}cameraForBounds(e,t){e=G.convert(e).adjustAntiMeridian();const i=t&&t.bearing||0;return this._cameraForBoxAndBearing(e.getNorthWest(),e.getSouthEast(),i,t)}_cameraForBoxAndBearing(e,i,o,r){const a={top:0,bottom:0,right:0,left:0};if(\"number\"==typeof(r=t.e({padding:a,offset:[0,0],maxZoom:this.transform.maxZoom},r)).padding){const e=r.padding;r.padding={top:e,bottom:e,right:e,left:e};}const s=t.e(a,r.padding);r.padding=s;const n=this.transform,l=new G(e,i);return this.cameraHelper.cameraForBoxAndBearing(r,s,l,o,n)}fitBounds(e,t,i){return this._fitInternal(this.cameraForBounds(e,t),t,i)}fitScreenCoordinates(e,i,o,r,a){return this._fitInternal(this._cameraForBoxAndBearing(this.transform.screenPointToLocation(t.P.convert(e)),this.transform.screenPointToLocation(t.P.convert(i)),o,r),r,a)}_fitInternal(e,i,o){return e?(delete(i=t.e(e,i)).padding,i.linear?this.easeTo(i,o):this.flyTo(i,o)):this}jumpTo(e,i){this.stop();const o=this._getTransformForUpdate();let r=!1,a=!1,s=!1;const n=o.zoom;this.cameraHelper.handleJumpToCenterZoom(o,e);const l=o.zoom!==n;return \"elevation\"in e&&o.elevation!==+e.elevation&&o.setElevation(+e.elevation),\"bearing\"in e&&o.bearing!==+e.bearing&&(r=!0,o.setBearing(+e.bearing)),\"pitch\"in e&&o.pitch!==+e.pitch&&(a=!0,o.setPitch(+e.pitch)),\"roll\"in e&&o.roll!==+e.roll&&(s=!0,o.setRoll(+e.roll)),null==e.padding||o.isPaddingEqual(e.padding)||o.setPadding(e.padding),this._applyUpdatedTransform(o),this.fire(new t.l(\"movestart\",i)).fire(new t.l(\"move\",i)),l&&this.fire(new t.l(\"zoomstart\",i)).fire(new t.l(\"zoom\",i)).fire(new t.l(\"zoomend\",i)),r&&this.fire(new t.l(\"rotatestart\",i)).fire(new t.l(\"rotate\",i)).fire(new t.l(\"rotateend\",i)),a&&this.fire(new t.l(\"pitchstart\",i)).fire(new t.l(\"pitch\",i)).fire(new t.l(\"pitchend\",i)),s&&this.fire(new t.l(\"rollstart\",i)).fire(new t.l(\"roll\",i)).fire(new t.l(\"rollend\",i)),this.fire(new t.l(\"moveend\",i))}calculateCameraOptionsFromTo(e,i,o,r=0){const a=t.a0.fromLngLat(e,i),s=t.a0.fromLngLat(o,r),n=s.x-a.x,l=s.y-a.y,c=s.z-a.z,h=Math.hypot(n,l,c);if(0===h)throw new Error(\"Can't calculate camera options with same From and To\");const u=Math.hypot(n,l),d=t.aj(this.transform.cameraToCenterDistance/h/this.transform.tileSize),_=180*Math.atan2(n,-l)/Math.PI;let p=180*Math.acos(u/h)/Math.PI;return p=c<0?90-p:90+p,{center:s.toLngLat(),elevation:r,zoom:d,pitch:p,bearing:_}}calculateCameraOptionsFromCameraLngLatAltRotation(e,t,i,o,r){const a=this.transform.calculateCenterFromCameraLngLatAlt(e,t,i,o);return {center:a.center,elevation:a.elevation,zoom:a.zoom,bearing:i,pitch:o,roll:r}}easeTo(e,i){this._stop(!1,e.easeId),(!1===(e=t.e({offset:[0,0],duration:500,easing:t.cn},e)).animate||!e.essential&&s.prefersReducedMotion)&&(e.duration=0);const o=this._getTransformForUpdate(),r=this.getBearing(),a=o.pitch,n=o.roll,l=\"bearing\"in e?this._normalizeBearing(e.bearing,r):r,c=\"pitch\"in e?+e.pitch:a,h=\"roll\"in e?this._normalizeBearing(e.roll,n):n,u=\"padding\"in e?e.padding:o.padding,d=t.P.convert(e.offset);let _,p;e.around&&(_=t.S.convert(e.around),p=o.locationToScreenPoint(_));const m={moving:this._moving,zooming:this._zooming,rotating:this._rotating,pitching:this._pitching,rolling:this._rolling},f=this.cameraHelper.handleEaseTo(o,{bearing:l,pitch:c,roll:h,padding:u,around:_,aroundPoint:p,offsetAsPoint:d,offset:e.offset,zoom:e.zoom,center:e.center});return this._rotating=this._rotating||r!==l,this._pitching=this._pitching||c!==a,this._rolling=this._rolling||h!==n,this._padding=!o.isPaddingEqual(u),this._zooming=this._zooming||f.isZooming,this._easeId=e.easeId,this._prepareEase(i,e.noMoveStart,m),this.terrain&&this._prepareElevation(f.elevationCenter),this._ease((t=>{f.easeFunc(t),this.terrain&&!e.freezeElevation&&this._updateElevation(t),this._applyUpdatedTransform(o),this._fireMoveEvents(i);}),(t=>{this.terrain&&e.freezeElevation&&this._finalizeElevation(),this._afterEase(i,t);}),e),this}_prepareEase(e,i,o={}){this._moving=!0,i||o.moving||this.fire(new t.l(\"movestart\",e)),this._zooming&&!o.zooming&&this.fire(new t.l(\"zoomstart\",e)),this._rotating&&!o.rotating&&this.fire(new t.l(\"rotatestart\",e)),this._pitching&&!o.pitching&&this.fire(new t.l(\"pitchstart\",e)),this._rolling&&!o.rolling&&this.fire(new t.l(\"rollstart\",e));}_prepareElevation(e){this._elevationCenter=e,this._elevationStart=this.transform.elevation,this._elevationTarget=this.terrain.getElevationForLngLatZoom(e,this.transform.tileZoom),this._elevationFreeze=!0;}_updateElevation(e){this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this._elevationCenter,this.transform.tileZoom));const i=this.terrain.getElevationForLngLatZoom(this._elevationCenter,this.transform.tileZoom);if(e<1&&i!==this._elevationTarget){const t=this._elevationTarget-this._elevationStart;this._elevationStart+=e*(t-(i-(t*e+this._elevationStart))/(1-e)),this._elevationTarget=i;}this.transform.setElevation(t.C.number(this._elevationStart,this._elevationTarget,e));}_finalizeElevation(){this._elevationFreeze=!1,this.getCenterClampedToGround()&&this.transform.recalculateZoomAndCenter(this.terrain);}_getTransformForUpdate(){return this.transformCameraUpdate||this.terrain?(this._requestedCameraState||(this._requestedCameraState=this.transform.clone()),this._requestedCameraState):this.transform}_elevateCameraIfInsideTerrain(e){if(!this.terrain&&e.elevation>=0&&e.pitch<=90)return {};const t=e.getCameraLngLat(),i=e.getCameraAltitude(),o=this.terrain?this.terrain.getElevationForLngLatZoom(t,e.zoom):0;if(i<o){const i=this.calculateCameraOptionsFromTo(t,o,e.center,e.elevation);return {pitch:i.pitch,zoom:i.zoom}}return {}}_applyUpdatedTransform(e){const t=[];if(t.push((e=>this._elevateCameraIfInsideTerrain(e))),this.transformCameraUpdate&&t.push((e=>this.transformCameraUpdate(e))),!t.length)return;const i=e.clone();for(const e of t){const t=i.clone(),{center:o,zoom:r,roll:a,pitch:s,bearing:n,elevation:l}=e(t);o&&t.setCenter(o),void 0!==l&&t.setElevation(l),void 0!==r&&t.setZoom(r),void 0!==a&&t.setRoll(a),void 0!==s&&t.setPitch(s),void 0!==n&&t.setBearing(n),i.apply(t);}this.transform.apply(i);}_fireMoveEvents(e){this.fire(new t.l(\"move\",e)),this._zooming&&this.fire(new t.l(\"zoom\",e)),this._rotating&&this.fire(new t.l(\"rotate\",e)),this._pitching&&this.fire(new t.l(\"pitch\",e)),this._rolling&&this.fire(new t.l(\"roll\",e));}_afterEase(e,i){if(this._easeId&&i&&this._easeId===i)return;delete this._easeId;const o=this._zooming,r=this._rotating,a=this._pitching,s=this._rolling;this._moving=!1,this._zooming=!1,this._rotating=!1,this._pitching=!1,this._rolling=!1,this._padding=!1,o&&this.fire(new t.l(\"zoomend\",e)),r&&this.fire(new t.l(\"rotateend\",e)),a&&this.fire(new t.l(\"pitchend\",e)),s&&this.fire(new t.l(\"rollend\",e)),this.fire(new t.l(\"moveend\",e));}flyTo(e,i){if(!e.essential&&s.prefersReducedMotion){const o=t.Q(e,[\"center\",\"zoom\",\"bearing\",\"pitch\",\"roll\",\"elevation\"]);return this.jumpTo(o,i)}this.stop(),e=t.e({offset:[0,0],speed:1.2,curve:1.42,easing:t.cn},e);const o=this._getTransformForUpdate(),r=o.bearing,a=o.pitch,n=o.roll,l=o.padding,c=\"bearing\"in e?this._normalizeBearing(e.bearing,r):r,h=\"pitch\"in e?+e.pitch:a,u=\"roll\"in e?this._normalizeBearing(e.roll,n):n,d=\"padding\"in e?e.padding:o.padding,_=t.P.convert(e.offset);let p=o.centerPoint.add(_);const m=o.screenPointToLocation(p),f=this.cameraHelper.handleFlyTo(o,{bearing:c,pitch:h,roll:u,padding:d,locationAtOffset:m,offsetAsPoint:_,center:e.center,minZoom:e.minZoom,zoom:e.zoom});let g=e.curve;const v=Math.max(o.width,o.height),b=v/f.scaleOfZoom,x=f.pixelPathLength;\"number\"==typeof f.scaleOfMinZoom&&(g=Math.sqrt(v/f.scaleOfMinZoom/x*2));const y=g*g;function w(e){const t=(b*b-v*v+(e?-1:1)*y*y*x*x)/(2*(e?b:v)*y*x);return Math.log(Math.sqrt(t*t+1)-t)}function T(e){return (Math.exp(e)-Math.exp(-e))/2}function P(e){return (Math.exp(e)+Math.exp(-e))/2}const C=w(!1);let I=function(e){return P(C)/P(C+g*e)},M=function(e){return v*((P(C)*(T(t=C+g*e)/P(t))-T(C))/y)/x;var t;},S=(w(!0)-C)/g;if(Math.abs(x)<2e-6||!isFinite(S)){if(Math.abs(v-b)<1e-6)return this.easeTo(e,i);const t=b<v?-1:1;S=Math.abs(Math.log(b/v))/g,M=()=>0,I=e=>Math.exp(t*g*e);}return e.duration=\"duration\"in e?+e.duration:1e3*S/(\"screenSpeed\"in e?+e.screenSpeed/g:+e.speed),e.maxDuration&&e.duration>e.maxDuration&&(e.duration=0),this._zooming=!0,this._rotating=r!==c,this._pitching=h!==a,this._rolling=u!==n,this._padding=!o.isPaddingEqual(d),this._prepareEase(i,!1),this.terrain&&this._prepareElevation(f.targetCenter),this._ease((s=>{const m=s*S,g=1/I(m),v=M(m);this._rotating&&o.setBearing(t.C.number(r,c,s)),this._pitching&&o.setPitch(t.C.number(a,h,s)),this._rolling&&o.setRoll(t.C.number(n,u,s)),this._padding&&(o.interpolatePadding(l,d,s),p=o.centerPoint.add(_)),f.easeFunc(s,g,v,p),this.terrain&&!e.freezeElevation&&this._updateElevation(s),this._applyUpdatedTransform(o),this._fireMoveEvents(i);}),(()=>{this.terrain&&e.freezeElevation&&this._finalizeElevation(),this._afterEase(i);}),e),this}isEasing(){return !!this._easeFrameId}stop(){return this._stop()}_stop(e,t){var i;if(this._easeFrameId&&(this._cancelRenderFrame(this._easeFrameId),delete this._easeFrameId,delete this._onEaseFrame),this._onEaseEnd){const e=this._onEaseEnd;delete this._onEaseEnd,e.call(this,t);}return e||null===(i=this.handlers)||void 0===i||i.stop(!1),this}_ease(e,t,i){!1===i.animate||0===i.duration?(e(1),t()):(this._easeStart=s.now(),this._easeOptions=i,this._onEaseFrame=e,this._onEaseEnd=t,this._easeFrameId=this._requestRenderFrame(this._renderFrameCallback));}_normalizeBearing(e,i){e=t.aN(e,-180,180);const o=Math.abs(e-i);return Math.abs(e-360-i)<o&&(e-=360),Math.abs(e+360-i)<o&&(e+=360),e}queryTerrainElevation(e){return this.terrain?this.terrain.getElevationForLngLatZoom(t.S.convert(e),this.transform.tileZoom):null}}const za={compact:!0,customAttribution:'<a href=\"https://maplibre.org/\" target=\"_blank\">MapLibre</a>'};class Da{constructor(e=za){this._toggleAttribution=()=>{this._container.classList.contains(\"maplibregl-compact\")&&(this._container.classList.contains(\"maplibregl-compact-show\")?(this._container.setAttribute(\"open\",\"\"),this._container.classList.remove(\"maplibregl-compact-show\")):(this._container.classList.add(\"maplibregl-compact-show\"),this._container.removeAttribute(\"open\")));},this._updateData=e=>{!e||\"metadata\"!==e.sourceDataType&&\"visibility\"!==e.sourceDataType&&\"style\"!==e.dataType&&\"terrain\"!==e.type||this._updateAttributions();},this._updateCompact=()=>{this._map.getCanvasContainer().offsetWidth<=640||this._compact?!1===this._compact?this._container.setAttribute(\"open\",\"\"):this._container.classList.contains(\"maplibregl-compact\")||this._container.classList.contains(\"maplibregl-attrib-empty\")||(this._container.setAttribute(\"open\",\"\"),this._container.classList.add(\"maplibregl-compact\",\"maplibregl-compact-show\")):(this._container.setAttribute(\"open\",\"\"),this._container.classList.contains(\"maplibregl-compact\")&&this._container.classList.remove(\"maplibregl-compact\",\"maplibregl-compact-show\"));},this._updateCompactMinimize=()=>{this._container.classList.contains(\"maplibregl-compact\")&&this._container.classList.contains(\"maplibregl-compact-show\")&&this._container.classList.remove(\"maplibregl-compact-show\");},this.options=e;}getDefaultPosition(){return \"bottom-right\"}onAdd(e){return this._map=e,this._compact=this.options.compact,this._container=n.create(\"details\",\"maplibregl-ctrl maplibregl-ctrl-attrib\"),this._compactButton=n.create(\"summary\",\"maplibregl-ctrl-attrib-button\",this._container),this._compactButton.addEventListener(\"click\",this._toggleAttribution),this._setElementTitle(this._compactButton,\"ToggleAttribution\"),this._innerContainer=n.create(\"div\",\"maplibregl-ctrl-attrib-inner\",this._container),this._updateAttributions(),this._updateCompact(),this._map.on(\"styledata\",this._updateData),this._map.on(\"sourcedata\",this._updateData),this._map.on(\"terrain\",this._updateData),this._map.on(\"resize\",this._updateCompact),this._map.on(\"drag\",this._updateCompactMinimize),this._container}onRemove(){n.remove(this._container),this._map.off(\"styledata\",this._updateData),this._map.off(\"sourcedata\",this._updateData),this._map.off(\"terrain\",this._updateData),this._map.off(\"resize\",this._updateCompact),this._map.off(\"drag\",this._updateCompactMinimize),this._map=void 0,this._compact=void 0,this._attribHTML=void 0;}_setElementTitle(e,t){const i=this._map._getUIString(`AttributionControl.${t}`);e.title=i,e.setAttribute(\"aria-label\",i);}_updateAttributions(){if(!this._map.style)return;let e=[];if(this.options.customAttribution&&(Array.isArray(this.options.customAttribution)?e=e.concat(this.options.customAttribution.map((e=>\"string\"!=typeof e?\"\":e))):\"string\"==typeof this.options.customAttribution&&e.push(this.options.customAttribution)),this._map.style.stylesheet){const e=this._map.style.stylesheet;this.styleOwner=e.owner,this.styleId=e.id;}const t=this._map.style.sourceCaches;for(const i in t){const o=t[i];if(o.used||o.usedForTerrain){const t=o.getSource();t.attribution&&e.indexOf(t.attribution)<0&&e.push(t.attribution);}}e=e.filter((e=>String(e).trim())),e.sort(((e,t)=>e.length-t.length)),e=e.filter(((t,i)=>{for(let o=i+1;o<e.length;o++)if(e[o].indexOf(t)>=0)return !1;return !0}));const i=e.join(\" | \");i!==this._attribHTML&&(this._attribHTML=i,e.length?(this._innerContainer.innerHTML=n.sanitize(i),this._container.classList.remove(\"maplibregl-attrib-empty\")):this._container.classList.add(\"maplibregl-attrib-empty\"),this._updateCompact(),this._editLink=null);}}class Aa{constructor(e={}){this._updateCompact=()=>{const e=this._container.children;if(e.length){const t=e[0];this._map.getCanvasContainer().offsetWidth<=640||this._compact?!1!==this._compact&&t.classList.add(\"maplibregl-compact\"):t.classList.remove(\"maplibregl-compact\");}},this.options=e;}getDefaultPosition(){return \"bottom-left\"}onAdd(e){this._map=e,this._compact=this.options&&this.options.compact,this._container=n.create(\"div\",\"maplibregl-ctrl\");const t=n.create(\"a\",\"maplibregl-ctrl-logo\");return t.target=\"_blank\",t.rel=\"noopener nofollow\",t.href=\"https://maplibre.org/\",t.setAttribute(\"aria-label\",this._map._getUIString(\"LogoControl.Title\")),t.setAttribute(\"rel\",\"noopener nofollow\"),this._container.appendChild(t),this._container.style.display=\"block\",this._map.on(\"resize\",this._updateCompact),this._updateCompact(),this._container}onRemove(){n.remove(this._container),this._map.off(\"resize\",this._updateCompact),this._map=void 0,this._compact=void 0;}}class La{constructor(){this._queue=[],this._id=0,this._cleared=!1,this._currentlyRunning=!1;}add(e){const t=++this._id;return this._queue.push({callback:e,id:t,cancelled:!1}),t}remove(e){const t=this._currentlyRunning,i=t?this._queue.concat(t):this._queue;for(const t of i)if(t.id===e)return void(t.cancelled=!0)}run(e=0){if(this._currentlyRunning)throw new Error(\"Attempting to run(), but is already running.\");const t=this._currentlyRunning=this._queue;this._queue=[];for(const i of t)if(!i.cancelled&&(i.callback(e),this._cleared))break;this._cleared=!1,this._currentlyRunning=!1;}clear(){this._currentlyRunning&&(this._cleared=!0),this._queue=[];}}var ka=t.aI([{name:\"a_pos3d\",type:\"Int16\",components:3}]);class Fa extends t.E{constructor(e){super(),this._lastTilesetChange=s.now(),this.sourceCache=e,this._tiles={},this._renderableTilesKeys=[],this._sourceTileCache={},this.minzoom=0,this.maxzoom=22,this.deltaZoom=1,this.tileSize=e._source.tileSize*2**this.deltaZoom,e.usedForTerrain=!0,e.tileSize=this.tileSize;}destruct(){this.sourceCache.usedForTerrain=!1,this.sourceCache.tileSize=null;}update(e,i){this.sourceCache.update(e,i),this._renderableTilesKeys=[];const o={};for(const r of ve(e,{tileSize:this.tileSize,minzoom:this.minzoom,maxzoom:this.maxzoom,reparseOverscaled:!1,terrain:i,calculateTileZoom:this.sourceCache._source.calculateTileZoom}))o[r.key]=!0,this._renderableTilesKeys.push(r.key),this._tiles[r.key]||(r.terrainRttPosMatrix32f=new Float64Array(16),t.bX(r.terrainRttPosMatrix32f,0,t.$,t.$,0,0,1),this._tiles[r.key]=new re(r,this.tileSize),this._lastTilesetChange=s.now());for(const e in this._tiles)o[e]||delete this._tiles[e];}freeRtt(e){for(const t in this._tiles){const i=this._tiles[t];(!e||i.tileID.equals(e)||i.tileID.isChildOf(e)||e.isChildOf(i.tileID))&&(i.rtt=[]);}}getRenderableTiles(){return this._renderableTilesKeys.map((e=>this.getTileByID(e)))}getTileByID(e){return this._tiles[e]}getTerrainCoords(e,t){return t?this._getTerrainCoordsForTileRanges(e,t):this._getTerrainCoordsForRegularTile(e)}_getTerrainCoordsForRegularTile(e){const i={};for(const o of this._renderableTilesKeys){const r=this._tiles[o].tileID,a=e.clone(),s=t.b9();if(r.canonical.equals(e.canonical))t.bX(s,0,t.$,t.$,0,0,1);else if(r.canonical.isChildOf(e.canonical)){const i=r.canonical.z-e.canonical.z,o=r.canonical.x-(r.canonical.x>>i<<i),a=r.canonical.y-(r.canonical.y>>i<<i),n=t.$>>i;t.bX(s,0,n,n,0,0,1),t.M(s,s,[-o*n,-a*n,0]);}else {if(!e.canonical.isChildOf(r.canonical))continue;{const i=e.canonical.z-r.canonical.z,o=e.canonical.x-(e.canonical.x>>i<<i),a=e.canonical.y-(e.canonical.y>>i<<i),n=t.$>>i;t.bX(s,0,t.$,t.$,0,0,1),t.M(s,s,[o*n,a*n,0]),t.N(s,s,[1/2**i,1/2**i,0]);}}a.terrainRttPosMatrix32f=new Float32Array(s),i[o]=a;}return i}_getTerrainCoordsForTileRanges(e,i){const o={};for(const r of this._renderableTilesKeys){const a=this._tiles[r].tileID;if(!this._isWithinTileRanges(a,i))continue;const s=e.clone(),n=t.b9();if(a.canonical.z===e.canonical.z){const i=e.canonical.x-a.canonical.x,o=e.canonical.y-a.canonical.y;t.bX(n,0,t.$,t.$,0,0,1),t.M(n,n,[i*t.$,o*t.$,0]);}else if(a.canonical.z>e.canonical.z){const i=a.canonical.z-e.canonical.z,o=a.canonical.x-(a.canonical.x>>i<<i),r=a.canonical.y-(a.canonical.y>>i<<i),s=e.canonical.x-(a.canonical.x>>i),l=e.canonical.y-(a.canonical.y>>i),c=t.$>>i;t.bX(n,0,c,c,0,0,1),t.M(n,n,[-o*c+s*t.$,-r*c+l*t.$,0]);}else {const i=e.canonical.z-a.canonical.z,o=e.canonical.x-(e.canonical.x>>i<<i),r=e.canonical.y-(e.canonical.y>>i<<i),s=(e.canonical.x>>i)-a.canonical.x,l=(e.canonical.y>>i)-a.canonical.y,c=t.$<<i;t.bX(n,0,c,c,0,0,1),t.M(n,n,[o*t.$+s*c,r*t.$+l*c,0]);}s.terrainRttPosMatrix32f=new Float32Array(n),o[r]=s;}return o}getSourceTile(e,t){const i=this.sourceCache._source;let o=e.overscaledZ-this.deltaZoom;if(o>i.maxzoom&&(o=i.maxzoom),o<i.minzoom)return null;this._sourceTileCache[e.key]||(this._sourceTileCache[e.key]=e.scaledTo(o).key);let r=this.sourceCache.getTileByID(this._sourceTileCache[e.key]);if((!r||!r.dem)&&t)for(;o>=i.minzoom&&(!r||!r.dem);)r=this.sourceCache.getTileByID(e.scaledTo(o--).key);return r}anyTilesAfterTime(e=Date.now()){return this._lastTilesetChange>=e}_isWithinTileRanges(e,t){return t[e.canonical.z]&&e.canonical.x>=t[e.canonical.z].minTileX&&e.canonical.x<=t[e.canonical.z].maxTileX&&e.canonical.y>=t[e.canonical.z].minTileY&&e.canonical.y<=t[e.canonical.z].maxTileY}}class Ba{constructor(e,t,i){this._meshCache={},this.painter=e,this.sourceCache=new Fa(t),this.options=i,this.exaggeration=\"number\"==typeof i.exaggeration?i.exaggeration:1,this.qualityFactor=2,this.meshSize=128,this._demMatrixCache={},this.coordsIndex=[],this._coordsTextureSize=1024;}getDEMElevation(e,i,o,r=t.$){var a;if(!(i>=0&&i<r&&o>=0&&o<r))return 0;const s=this.getTerrainData(e),n=null===(a=s.tile)||void 0===a?void 0:a.dem;if(!n)return 0;const l=t.cr([],[i/r*t.$,o/r*t.$],s.u_terrain_matrix),c=[l[0]*n.dim,l[1]*n.dim],h=Math.floor(c[0]),u=Math.floor(c[1]),d=c[0]-h,_=c[1]-u;return n.get(h,u)*(1-d)*(1-_)+n.get(h+1,u)*d*(1-_)+n.get(h,u+1)*(1-d)*_+n.get(h+1,u+1)*d*_}getElevationForLngLatZoom(e,i){if(!t.cs(i,e.wrap()))return 0;const{tileID:o,mercatorX:r,mercatorY:a}=this._getOverscaledTileIDFromLngLatZoom(e,i);return this.getElevation(o,r%t.$,a%t.$,t.$)}getElevation(e,i,o,r=t.$){return this.getDEMElevation(e,i,o,r)*this.exaggeration}getTerrainData(e){if(!this._emptyDemTexture){const e=this.painter.context,i=new t.R({width:1,height:1},new Uint8Array(4));this._emptyDepthTexture=new t.T(e,i,e.gl.RGBA,{premultiply:!1}),this._emptyDemUnpack=[0,0,0,0],this._emptyDemTexture=new t.T(e,new t.R({width:1,height:1}),e.gl.RGBA,{premultiply:!1}),this._emptyDemTexture.bind(e.gl.NEAREST,e.gl.CLAMP_TO_EDGE),this._emptyDemMatrix=t.af([]);}const i=this.sourceCache.getSourceTile(e,!0);if(i&&i.dem&&(!i.demTexture||i.needsTerrainPrepare)){const e=this.painter.context;i.demTexture=this.painter.getTileTexture(i.dem.stride),i.demTexture?i.demTexture.update(i.dem.getPixels(),{premultiply:!1}):i.demTexture=new t.T(e,i.dem.getPixels(),e.gl.RGBA,{premultiply:!1}),i.demTexture.bind(e.gl.NEAREST,e.gl.CLAMP_TO_EDGE),i.needsTerrainPrepare=!1;}const o=i&&i+i.tileID.key+e.key;if(o&&!this._demMatrixCache[o]){const o=this.sourceCache.sourceCache._source.maxzoom;let r=e.canonical.z-i.tileID.canonical.z;e.overscaledZ>e.canonical.z&&(e.canonical.z>=o?r=e.canonical.z-o:t.w(\"cannot calculate elevation if elevation maxzoom > source.maxzoom\"));const a=e.canonical.x-(e.canonical.x>>r<<r),s=e.canonical.y-(e.canonical.y>>r<<r),n=t.ct(new Float64Array(16),[1/(t.$<<r),1/(t.$<<r),0]);t.M(n,n,[a*t.$,s*t.$,0]),this._demMatrixCache[e.key]={matrix:n,coord:e};}return {u_depth:2,u_terrain:3,u_terrain_dim:i&&i.dem&&i.dem.dim||1,u_terrain_matrix:o?this._demMatrixCache[e.key].matrix:this._emptyDemMatrix,u_terrain_unpack:i&&i.dem&&i.dem.getUnpackVector()||this._emptyDemUnpack,u_terrain_exaggeration:this.exaggeration,texture:(i&&i.demTexture||this._emptyDemTexture).texture,depthTexture:(this._fboDepthTexture||this._emptyDepthTexture).texture,tile:i}}getFramebuffer(e){const i=this.painter,o=i.width/devicePixelRatio,r=i.height/devicePixelRatio;return !this._fbo||this._fbo.width===o&&this._fbo.height===r||(this._fbo.destroy(),this._fboCoordsTexture.destroy(),this._fboDepthTexture.destroy(),delete this._fbo,delete this._fboDepthTexture,delete this._fboCoordsTexture),this._fboCoordsTexture||(this._fboCoordsTexture=new t.T(i.context,{width:o,height:r,data:null},i.context.gl.RGBA,{premultiply:!1}),this._fboCoordsTexture.bind(i.context.gl.NEAREST,i.context.gl.CLAMP_TO_EDGE)),this._fboDepthTexture||(this._fboDepthTexture=new t.T(i.context,{width:o,height:r,data:null},i.context.gl.RGBA,{premultiply:!1}),this._fboDepthTexture.bind(i.context.gl.NEAREST,i.context.gl.CLAMP_TO_EDGE)),this._fbo||(this._fbo=i.context.createFramebuffer(o,r,!0,!1),this._fbo.depthAttachment.set(i.context.createRenderbuffer(i.context.gl.DEPTH_COMPONENT16,o,r))),this._fbo.colorAttachment.set(\"coords\"===e?this._fboCoordsTexture.texture:this._fboDepthTexture.texture),this._fbo}getCoordsTexture(){const e=this.painter.context;if(this._coordsTexture)return this._coordsTexture;const i=new Uint8Array(this._coordsTextureSize*this._coordsTextureSize*4);for(let e=0,t=0;e<this._coordsTextureSize;e++)for(let o=0;o<this._coordsTextureSize;o++,t+=4)i[t+0]=255&o,i[t+1]=255&e,i[t+2]=o>>8<<4|e>>8,i[t+3]=0;const o=new t.R({width:this._coordsTextureSize,height:this._coordsTextureSize},new Uint8Array(i.buffer)),r=new t.T(e,o,e.gl.RGBA,{premultiply:!1});return r.bind(e.gl.NEAREST,e.gl.CLAMP_TO_EDGE),this._coordsTexture=r,r}pointCoordinate(e){this.painter.maybeDrawDepthAndCoords(!0);const i=new Uint8Array(4),o=this.painter.context,r=o.gl,a=Math.round(e.x*this.painter.pixelRatio/devicePixelRatio),s=Math.round(e.y*this.painter.pixelRatio/devicePixelRatio),n=Math.round(this.painter.height/devicePixelRatio);o.bindFramebuffer.set(this.getFramebuffer(\"coords\").framebuffer),r.readPixels(a,n-s-1,1,1,r.RGBA,r.UNSIGNED_BYTE,i),o.bindFramebuffer.set(null);const l=i[0]+(i[2]>>4<<8),c=i[1]+((15&i[2])<<8),h=this.coordsIndex[255-i[3]],u=h&&this.sourceCache.getTileByID(h);if(!u)return null;const d=this._coordsTextureSize,_=(1<<u.tileID.canonical.z)*d;return new t.a0((u.tileID.canonical.x*d+l)/_+u.tileID.wrap,(u.tileID.canonical.y*d+c)/_,this.getElevation(u.tileID,l,c,d))}depthAtPoint(e){const t=new Uint8Array(4),i=this.painter.context,o=i.gl;return i.bindFramebuffer.set(this.getFramebuffer(\"depth\").framebuffer),o.readPixels(e.x,this.painter.height/devicePixelRatio-e.y-1,1,1,o.RGBA,o.UNSIGNED_BYTE,t),i.bindFramebuffer.set(null),(t[0]/16777216+t[1]/65536+t[2]/256+t[3])/256}getTerrainMesh(e){var i;const o=(null===(i=this.painter.style.projection)||void 0===i?void 0:i.transitionState)>0,r=o&&0===e.canonical.y,a=o&&e.canonical.y===(1<<e.canonical.z)-1,s=`m_${r?\"n\":\"\"}_${a?\"s\":\"\"}`;if(this._meshCache[s])return this._meshCache[s];const n=this.painter.context,l=new t.cu,c=new t.aM,h=this.meshSize,u=t.$/h,d=h*h;for(let e=0;e<=h;e++)for(let t=0;t<=h;t++)l.emplaceBack(t*u,e*u,0);for(let e=0;e<d;e+=h+1)for(let t=0;t<h;t++)c.emplaceBack(t+e,h+t+e+1,h+t+e+2),c.emplaceBack(t+e,h+t+e+2,t+e+1);const _=l.length,p=_+(h+1),m=(h+1)*h,f=r?t.bg:0,g=r?0:1,v=a?t.bh:t.$,b=a?0:1;for(let e=0;e<=h;e++)l.emplaceBack(e*u,f,g);for(let e=0;e<=h;e++)l.emplaceBack(e*u,v,b);for(let e=0;e<h;e++)c.emplaceBack(m+e,p+e,p+e+1),c.emplaceBack(m+e,p+e+1,m+e+1),c.emplaceBack(0+e,_+e+1,_+e),c.emplaceBack(0+e,0+e+1,_+e+1);const x=l.length,y=x+2*(h+1);for(const e of [0,1])for(let i=0;i<=h;i++)for(const o of [0,1])l.emplaceBack(e*t.$,i*u,o);for(let e=0;e<2*h;e+=2)c.emplaceBack(x+e,x+e+1,x+e+3),c.emplaceBack(x+e,x+e+3,x+e+2),c.emplaceBack(y+e,y+e+3,y+e+1),c.emplaceBack(y+e,y+e+2,y+e+3);const w=new wt(n.createVertexBuffer(l,ka.members),n.createIndexBuffer(c),t.aL.simpleSegment(0,0,l.length,c.length));return this._meshCache[s]=w,w}getMeshFrameDelta(e){return 2*Math.PI*t.bt/Math.pow(2,Math.max(e,0))/5}getMinTileElevationForLngLatZoom(e,t){var i;const{tileID:o}=this._getOverscaledTileIDFromLngLatZoom(e,t);return null!==(i=this.getMinMaxElevation(o).minElevation)&&void 0!==i?i:0}getMinMaxElevation(e){const t=this.getTerrainData(e).tile,i={minElevation:null,maxElevation:null};return t&&t.dem&&(i.minElevation=t.dem.min*this.exaggeration,i.maxElevation=t.dem.max*this.exaggeration),i}_getOverscaledTileIDFromLngLatZoom(e,i){const o=t.a0.fromLngLat(e.wrap()),r=(1<<i)*t.$,a=o.x*r,s=o.y*r,n=Math.floor(a/t.$),l=Math.floor(s/t.$);return {tileID:new t.Z(i,0,i,n,l),mercatorX:a,mercatorY:s}}}class Oa{constructor(e,t,i){this._context=e,this._size=t,this._tileSize=i,this._objects=[],this._recentlyUsed=[],this._stamp=0;}destruct(){for(const e of this._objects)e.texture.destroy(),e.fbo.destroy();}_createObject(e){const i=this._context.createFramebuffer(this._tileSize,this._tileSize,!0,!0),o=new t.T(this._context,{width:this._tileSize,height:this._tileSize,data:null},this._context.gl.RGBA);return o.bind(this._context.gl.LINEAR,this._context.gl.CLAMP_TO_EDGE),this._context.extTextureFilterAnisotropic&&this._context.gl.texParameterf(this._context.gl.TEXTURE_2D,this._context.extTextureFilterAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,this._context.extTextureFilterAnisotropicMax),i.depthAttachment.set(this._context.createRenderbuffer(this._context.gl.DEPTH_STENCIL,this._tileSize,this._tileSize)),i.colorAttachment.set(o.texture),{id:e,fbo:i,texture:o,stamp:-1,inUse:!1}}getObjectForId(e){return this._objects[e]}useObject(e){e.inUse=!0,this._recentlyUsed=this._recentlyUsed.filter((t=>e.id!==t)),this._recentlyUsed.push(e.id);}stampObject(e){e.stamp=++this._stamp;}getOrCreateFreeObject(){for(const e of this._recentlyUsed)if(!this._objects[e].inUse)return this._objects[e];if(this._objects.length>=this._size)throw new Error(\"No free RenderPool available, call freeAllObjects() required!\");const e=this._createObject(this._objects.length);return this._objects.push(e),e}freeObject(e){e.inUse=!1;}freeAllObjects(){for(const e of this._objects)this.freeObject(e);}isFull(){return !(this._objects.length<this._size)&&!1===this._objects.some((e=>!e.inUse))}}const ja={background:!0,fill:!0,line:!0,raster:!0,hillshade:!0,\"color-relief\":!0};class Na{constructor(e,t){this.painter=e,this.terrain=t,this.pool=new Oa(e.context,30,t.sourceCache.tileSize*t.qualityFactor);}destruct(){this.pool.destruct();}getTexture(e){return this.pool.getObjectForId(e.rtt[this._stacks.length-1].id).texture}prepareForRender(e,t){this._stacks=[],this._prevType=null,this._rttTiles=[],this._renderableTiles=this.terrain.sourceCache.getRenderableTiles(),this._renderableLayerIds=e._order.filter((i=>!e._layers[i].isHidden(t))),this._coordsAscending={};for(const t in e.sourceCaches){this._coordsAscending[t]={};const i=e.sourceCaches[t].getVisibleCoordinates(),o=e.sourceCaches[t].getSource(),r=o instanceof X?o.terrainTileRanges:null;for(const e of i){const i=this.terrain.sourceCache.getTerrainCoords(e,r);for(const e in i)this._coordsAscending[t][e]||(this._coordsAscending[t][e]=[]),this._coordsAscending[t][e].push(i[e]);}}this._coordsAscendingStr={};for(const t of e._order){const i=e._layers[t],o=i.source;if(ja[i.type]&&!this._coordsAscendingStr[o]){this._coordsAscendingStr[o]={};for(const e in this._coordsAscending[o])this._coordsAscendingStr[o][e]=this._coordsAscending[o][e].map((e=>e.key)).sort().join();}}for(const e of this._renderableTiles)for(const t in this._coordsAscendingStr){const i=this._coordsAscendingStr[t][e.tileID.key];i&&i!==e.rttCoords[t]&&(e.rtt=[]);}}renderLayer(e,i){if(e.isHidden(this.painter.transform.zoom))return !1;const o=Object.assign(Object.assign({},i),{isRenderingToTexture:!0}),r=e.type,a=this.painter,s=this._renderableLayerIds[this._renderableLayerIds.length-1]===e.id;if(ja[r]&&(this._prevType&&ja[this._prevType]||this._stacks.push([]),this._prevType=r,this._stacks[this._stacks.length-1].push(e.id),!s))return !0;if(ja[this._prevType]||ja[r]&&s){this._prevType=r;const e=this._stacks.length-1,i=this._stacks[e]||[];for(const r of this._renderableTiles){if(this.pool.isFull()&&(Cr(this.painter,this.terrain,this._rttTiles,o),this._rttTiles=[],this.pool.freeAllObjects()),this._rttTiles.push(r),r.rtt[e]){const t=this.pool.getObjectForId(r.rtt[e].id);if(t.stamp===r.rtt[e].stamp){this.pool.useObject(t);continue}}const s=this.pool.getOrCreateFreeObject();this.pool.useObject(s),this.pool.stampObject(s),r.rtt[e]={id:s.id,stamp:s.stamp},a.context.bindFramebuffer.set(s.fbo.framebuffer),a.context.clear({color:t.be.transparent,stencil:0}),a.currentStencilSource=void 0;for(let e=0;e<i.length;e++){const t=a.style._layers[i[e]],n=t.source?this._coordsAscending[t.source][r.tileID.key]:[r.tileID];a.context.viewport.set([0,0,s.fbo.width,s.fbo.height]),a._renderTileClippingMasks(t,n,!0),a.renderLayer(a,a.style.sourceCaches[t.source],t,n,o),t.source&&(r.rttCoords[t.source]=this._coordsAscendingStr[t.source][r.tileID.key]);}}return Cr(this.painter,this.terrain,this._rttTiles,o),this._rttTiles=[],this.pool.freeAllObjects(),ja[r]}return !1}}const Za={\"AttributionControl.ToggleAttribution\":\"Toggle attribution\",\"AttributionControl.MapFeedback\":\"Map feedback\",\"FullscreenControl.Enter\":\"Enter fullscreen\",\"FullscreenControl.Exit\":\"Exit fullscreen\",\"GeolocateControl.FindMyLocation\":\"Find my location\",\"GeolocateControl.LocationNotAvailable\":\"Location not available\",\"LogoControl.Title\":\"MapLibre logo\",\"Map.Title\":\"Map\",\"Marker.Title\":\"Map marker\",\"NavigationControl.ResetBearing\":\"Reset bearing to north\",\"NavigationControl.ZoomIn\":\"Zoom in\",\"NavigationControl.ZoomOut\":\"Zoom out\",\"Popup.Close\":\"Close popup\",\"ScaleControl.Feet\":\"ft\",\"ScaleControl.Meters\":\"m\",\"ScaleControl.Kilometers\":\"km\",\"ScaleControl.Miles\":\"mi\",\"ScaleControl.NauticalMiles\":\"nm\",\"GlobeControl.Enable\":\"Enable globe\",\"GlobeControl.Disable\":\"Disable globe\",\"TerrainControl.Enable\":\"Enable terrain\",\"TerrainControl.Disable\":\"Disable terrain\",\"CooperativeGesturesHandler.WindowsHelpText\":\"Use Ctrl + scroll to zoom the map\",\"CooperativeGesturesHandler.MacHelpText\":\"Use ⌘ + scroll to zoom the map\",\"CooperativeGesturesHandler.MobileHelpText\":\"Use two fingers to move the map\"},Ua=i,Ga={hash:!1,interactive:!0,bearingSnap:7,attributionControl:za,maplibreLogo:!1,refreshExpiredTiles:!0,canvasContextAttributes:{antialias:!1,preserveDrawingBuffer:!1,powerPreference:\"high-performance\",failIfMajorPerformanceCaveat:!1,desynchronized:!1,contextType:void 0},scrollZoom:!0,minZoom:-2,maxZoom:22,minPitch:0,maxPitch:60,boxZoom:!0,dragRotate:!0,dragPan:!0,keyboard:!0,doubleClickZoom:!0,touchZoomRotate:!0,touchPitch:!0,cooperativeGestures:!1,trackResize:!0,center:[0,0],elevation:0,zoom:0,bearing:0,pitch:0,roll:0,renderWorldCopies:!0,maxTileCacheSize:null,maxTileCacheZoomLevels:t.a.MAX_TILE_CACHE_ZOOM_LEVELS,transformRequest:null,transformCameraUpdate:null,fadeDuration:300,crossSourceCollisions:!0,clickTolerance:3,localIdeographFontFamily:\"sans-serif\",pitchWithRotate:!0,rollEnabled:!1,validateStyle:!0,maxCanvasSize:[4096,4096],cancelPendingTileRequestsWhileZooming:!0,centerClampedToGround:!0},Va={showCompass:!0,showZoom:!0,visualizePitch:!1,visualizeRoll:!0};class $a{constructor(e,i,o=!1){this.mousedown=e=>{this.startMove(e,n.mousePos(this.element,e)),n.addEventListener(window,\"mousemove\",this.mousemove),n.addEventListener(window,\"mouseup\",this.mouseup);},this.mousemove=e=>{this.move(e,n.mousePos(this.element,e));},this.mouseup=e=>{this._rotatePitchHanlder.dragEnd(e),this.offTemp();},this.touchstart=e=>{1!==e.targetTouches.length?this.reset():(this._startPos=this._lastPos=n.touchPos(this.element,e.targetTouches)[0],this.startMove(e,this._startPos),n.addEventListener(window,\"touchmove\",this.touchmove,{passive:!1}),n.addEventListener(window,\"touchend\",this.touchend));},this.touchmove=e=>{1!==e.targetTouches.length?this.reset():(this._lastPos=n.touchPos(this.element,e.targetTouches)[0],this.move(e,this._lastPos));},this.touchend=e=>{0===e.targetTouches.length&&this._startPos&&this._lastPos&&this._startPos.dist(this._lastPos)<this._clickTolerance&&this.element.click(),delete this._startPos,delete this._lastPos,this.offTemp();},this.reset=()=>{this._rotatePitchHanlder.reset(),delete this._startPos,delete this._lastPos,this.offTemp();},this._clickTolerance=10,this.element=i;const r=new ia;this._rotatePitchHanlder=new Kr({clickTolerance:3,move:(e,r)=>{const a=i.getBoundingClientRect(),s=new t.P((a.bottom-a.top)/2,(a.right-a.left)/2);return {bearingDelta:t.cm(new t.P(e.x,r.y),r,s),pitchDelta:o?-.5*(r.y-e.y):void 0}},moveStateManager:r,enable:!0,assignEvents:()=>{}}),this.map=e,n.addEventListener(i,\"mousedown\",this.mousedown),n.addEventListener(i,\"touchstart\",this.touchstart,{passive:!1}),n.addEventListener(i,\"touchcancel\",this.reset);}startMove(e,t){this._rotatePitchHanlder.dragStart(e,t),n.disableDrag();}move(e,t){const i=this.map,{bearingDelta:o,pitchDelta:r}=this._rotatePitchHanlder.dragMove(e,t)||{};o&&i.setBearing(i.getBearing()+o),r&&i.setPitch(i.getPitch()+r);}off(){const e=this.element;n.removeEventListener(e,\"mousedown\",this.mousedown),n.removeEventListener(e,\"touchstart\",this.touchstart,{passive:!1}),n.removeEventListener(window,\"touchmove\",this.touchmove,{passive:!1}),n.removeEventListener(window,\"touchend\",this.touchend),n.removeEventListener(e,\"touchcancel\",this.reset),this.offTemp();}offTemp(){n.enableDrag(),n.removeEventListener(window,\"mousemove\",this.mousemove),n.removeEventListener(window,\"mouseup\",this.mouseup),n.removeEventListener(window,\"touchmove\",this.touchmove,{passive:!1}),n.removeEventListener(window,\"touchend\",this.touchend);}}let qa;function Wa(e,i,o,r=!1){if(r||!o.getCoveringTilesDetailsProvider().allowWorldCopies())return null==e?void 0:e.wrap();const a=new t.S(e.lng,e.lat);if(e=new t.S(e.lng,e.lat),i){const r=new t.S(e.lng-360,e.lat),a=new t.S(e.lng+360,e.lat),s=o.locationToScreenPoint(e).distSqr(i);o.locationToScreenPoint(r).distSqr(i)<s?e=r:o.locationToScreenPoint(a).distSqr(i)<s&&(e=a);}for(;Math.abs(e.lng-o.center.lng)>180;){const t=o.locationToScreenPoint(e);if(t.x>=0&&t.y>=0&&t.x<=o.width&&t.y<=o.height)break;e.lng>o.center.lng?e.lng-=360:e.lng+=360;}return e.lng!==a.lng&&o.isPointOnMapSurface(o.locationToScreenPoint(e))?e:a}const Ha={center:\"translate(-50%,-50%)\",top:\"translate(-50%,0)\",\"top-left\":\"translate(0,0)\",\"top-right\":\"translate(-100%,0)\",bottom:\"translate(-50%,-100%)\",\"bottom-left\":\"translate(0,-100%)\",\"bottom-right\":\"translate(-100%,-100%)\",left:\"translate(0,-50%)\",right:\"translate(-100%,-50%)\"};function Xa(e,t,i){const o=e.classList;for(const e in Ha)o.remove(`maplibregl-${i}-anchor-${e}`);o.add(`maplibregl-${i}-anchor-${t}`);}class Ka extends t.E{constructor(e){if(super(),this._onKeyPress=e=>{const t=e.code,i=e.charCode||e.keyCode;\"Space\"!==t&&\"Enter\"!==t&&32!==i&&13!==i||this.togglePopup();},this._onMapClick=e=>{const t=e.originalEvent.target,i=this._element;this._popup&&(t===i||i.contains(t))&&this.togglePopup();},this._update=e=>{if(!this._map)return;const t=this._map.loaded()&&!this._map.isMoving();(\"terrain\"===(null==e?void 0:e.type)||\"render\"===(null==e?void 0:e.type)&&!t)&&this._map.once(\"render\",this._update),this._lngLat=Wa(this._lngLat,this._flatPos,this._map.transform),this._flatPos=this._pos=this._map.project(this._lngLat)._add(this._offset),this._map.terrain&&(this._flatPos=this._map.transform.locationToScreenPoint(this._lngLat)._add(this._offset));let i=\"\";\"viewport\"===this._rotationAlignment||\"auto\"===this._rotationAlignment?i=`rotateZ(${this._rotation}deg)`:\"map\"===this._rotationAlignment&&(i=`rotateZ(${this._rotation-this._map.getBearing()}deg)`);let o=\"\";\"viewport\"===this._pitchAlignment||\"auto\"===this._pitchAlignment?o=\"rotateX(0deg)\":\"map\"===this._pitchAlignment&&(o=`rotateX(${this._map.getPitch()}deg)`),this._subpixelPositioning||e&&\"moveend\"!==e.type||(this._pos=this._pos.round()),n.setTransform(this._element,`${Ha[this._anchor]} translate(${this._pos.x}px, ${this._pos.y}px) ${o} ${i}`),s.frameAsync(new AbortController).then((()=>{this._updateOpacity(e&&\"moveend\"===e.type);})).catch((()=>{}));},this._onMove=e=>{if(!this._isDragging){const t=this._clickTolerance||this._map._clickTolerance;this._isDragging=e.point.dist(this._pointerdownPos)>=t;}this._isDragging&&(this._pos=e.point.sub(this._positionDelta),this._lngLat=this._map.unproject(this._pos),this.setLngLat(this._lngLat),this._element.style.pointerEvents=\"none\",\"pending\"===this._state&&(this._state=\"active\",this.fire(new t.l(\"dragstart\"))),this.fire(new t.l(\"drag\")));},this._onUp=()=>{this._element.style.pointerEvents=\"auto\",this._positionDelta=null,this._pointerdownPos=null,this._isDragging=!1,this._map.off(\"mousemove\",this._onMove),this._map.off(\"touchmove\",this._onMove),\"active\"===this._state&&this.fire(new t.l(\"dragend\")),this._state=\"inactive\";},this._addDragHandler=e=>{this._element.contains(e.originalEvent.target)&&(e.preventDefault(),this._positionDelta=e.point.sub(this._pos).add(this._offset),this._pointerdownPos=e.point,this._state=\"pending\",this._map.on(\"mousemove\",this._onMove),this._map.on(\"touchmove\",this._onMove),this._map.once(\"mouseup\",this._onUp),this._map.once(\"touchend\",this._onUp));},this._anchor=e&&e.anchor||\"center\",this._color=e&&e.color||\"#3FB1CE\",this._scale=e&&e.scale||1,this._draggable=e&&e.draggable||!1,this._clickTolerance=e&&e.clickTolerance||0,this._subpixelPositioning=e&&e.subpixelPositioning||!1,this._isDragging=!1,this._state=\"inactive\",this._rotation=e&&e.rotation||0,this._rotationAlignment=e&&e.rotationAlignment||\"auto\",this._pitchAlignment=e&&e.pitchAlignment&&\"auto\"!==e.pitchAlignment?e.pitchAlignment:this._rotationAlignment,this.setOpacity(null==e?void 0:e.opacity,null==e?void 0:e.opacityWhenCovered),e&&e.element)this._element=e.element,this._offset=t.P.convert(e&&e.offset||[0,0]);else {this._defaultMarker=!0,this._element=n.create(\"div\");const i=n.createNS(\"http://www.w3.org/2000/svg\",\"svg\"),o=41,r=27;i.setAttributeNS(null,\"display\",\"block\"),i.setAttributeNS(null,\"height\",`${o}px`),i.setAttributeNS(null,\"width\",`${r}px`),i.setAttributeNS(null,\"viewBox\",`0 0 ${r} ${o}`);const a=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");a.setAttributeNS(null,\"stroke\",\"none\"),a.setAttributeNS(null,\"stroke-width\",\"1\"),a.setAttributeNS(null,\"fill\",\"none\"),a.setAttributeNS(null,\"fill-rule\",\"evenodd\");const s=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");s.setAttributeNS(null,\"fill-rule\",\"nonzero\");const l=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");l.setAttributeNS(null,\"transform\",\"translate(3.0, 29.0)\"),l.setAttributeNS(null,\"fill\",\"#000000\");const c=[{rx:\"10.5\",ry:\"5.25002273\"},{rx:\"10.5\",ry:\"5.25002273\"},{rx:\"9.5\",ry:\"4.77275007\"},{rx:\"8.5\",ry:\"4.29549936\"},{rx:\"7.5\",ry:\"3.81822308\"},{rx:\"6.5\",ry:\"3.34094679\"},{rx:\"5.5\",ry:\"2.86367051\"},{rx:\"4.5\",ry:\"2.38636864\"}];for(const e of c){const t=n.createNS(\"http://www.w3.org/2000/svg\",\"ellipse\");t.setAttributeNS(null,\"opacity\",\"0.04\"),t.setAttributeNS(null,\"cx\",\"10.5\"),t.setAttributeNS(null,\"cy\",\"5.80029008\"),t.setAttributeNS(null,\"rx\",e.rx),t.setAttributeNS(null,\"ry\",e.ry),l.appendChild(t);}const h=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");h.setAttributeNS(null,\"fill\",this._color);const u=n.createNS(\"http://www.w3.org/2000/svg\",\"path\");u.setAttributeNS(null,\"d\",\"M27,13.5 C27,19.074644 20.250001,27.000002 14.75,34.500002 C14.016665,35.500004 12.983335,35.500004 12.25,34.500002 C6.7499993,27.000002 0,19.222562 0,13.5 C0,6.0441559 6.0441559,0 13.5,0 C20.955844,0 27,6.0441559 27,13.5 Z\"),h.appendChild(u);const d=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");d.setAttributeNS(null,\"opacity\",\"0.25\"),d.setAttributeNS(null,\"fill\",\"#000000\");const _=n.createNS(\"http://www.w3.org/2000/svg\",\"path\");_.setAttributeNS(null,\"d\",\"M13.5,0 C6.0441559,0 0,6.0441559 0,13.5 C0,19.222562 6.7499993,27 12.25,34.5 C13,35.522727 14.016664,35.500004 14.75,34.5 C20.250001,27 27,19.074644 27,13.5 C27,6.0441559 20.955844,0 13.5,0 Z M13.5,1 C20.415404,1 26,6.584596 26,13.5 C26,15.898657 24.495584,19.181431 22.220703,22.738281 C19.945823,26.295132 16.705119,30.142167 13.943359,33.908203 C13.743445,34.180814 13.612715,34.322738 13.5,34.441406 C13.387285,34.322738 13.256555,34.180814 13.056641,33.908203 C10.284481,30.127985 7.4148684,26.314159 5.015625,22.773438 C2.6163816,19.232715 1,15.953538 1,13.5 C1,6.584596 6.584596,1 13.5,1 Z\"),d.appendChild(_);const p=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");p.setAttributeNS(null,\"transform\",\"translate(6.0, 7.0)\"),p.setAttributeNS(null,\"fill\",\"#FFFFFF\");const m=n.createNS(\"http://www.w3.org/2000/svg\",\"g\");m.setAttributeNS(null,\"transform\",\"translate(8.0, 8.0)\");const f=n.createNS(\"http://www.w3.org/2000/svg\",\"circle\");f.setAttributeNS(null,\"fill\",\"#000000\"),f.setAttributeNS(null,\"opacity\",\"0.25\"),f.setAttributeNS(null,\"cx\",\"5.5\"),f.setAttributeNS(null,\"cy\",\"5.5\"),f.setAttributeNS(null,\"r\",\"5.4999962\");const g=n.createNS(\"http://www.w3.org/2000/svg\",\"circle\");g.setAttributeNS(null,\"fill\",\"#FFFFFF\"),g.setAttributeNS(null,\"cx\",\"5.5\"),g.setAttributeNS(null,\"cy\",\"5.5\"),g.setAttributeNS(null,\"r\",\"5.4999962\"),m.appendChild(f),m.appendChild(g),s.appendChild(l),s.appendChild(h),s.appendChild(d),s.appendChild(p),s.appendChild(m),i.appendChild(s),i.setAttributeNS(null,\"height\",o*this._scale+\"px\"),i.setAttributeNS(null,\"width\",r*this._scale+\"px\"),this._element.appendChild(i),this._offset=t.P.convert(e&&e.offset||[0,-14]);}if(this._element.classList.add(\"maplibregl-marker\"),this._element.addEventListener(\"dragstart\",(e=>{e.preventDefault();})),this._element.addEventListener(\"mousedown\",(e=>{e.preventDefault();})),Xa(this._element,this._anchor,\"marker\"),e&&e.className)for(const t of e.className.split(\" \"))this._element.classList.add(t);this._popup=null;}addTo(e){return this.remove(),this._map=e,this._element.hasAttribute(\"aria-label\")||this._element.setAttribute(\"aria-label\",e._getUIString(\"Marker.Title\")),e.getCanvasContainer().appendChild(this._element),e.on(\"move\",this._update),e.on(\"moveend\",this._update),e.on(\"terrain\",this._update),e.on(\"projectiontransition\",this._update),this.setDraggable(this._draggable),this._update(),this._map.on(\"click\",this._onMapClick),this}remove(){return this._opacityTimeout&&(clearTimeout(this._opacityTimeout),delete this._opacityTimeout),this._map&&(this._map.off(\"click\",this._onMapClick),this._map.off(\"move\",this._update),this._map.off(\"moveend\",this._update),this._map.off(\"terrain\",this._update),this._map.off(\"projectiontransition\",this._update),this._map.off(\"mousedown\",this._addDragHandler),this._map.off(\"touchstart\",this._addDragHandler),this._map.off(\"mouseup\",this._onUp),this._map.off(\"touchend\",this._onUp),this._map.off(\"mousemove\",this._onMove),this._map.off(\"touchmove\",this._onMove),delete this._map),n.remove(this._element),this._popup&&this._popup.remove(),this}getLngLat(){return this._lngLat}setLngLat(e){return this._lngLat=t.S.convert(e),this._pos=null,this._popup&&this._popup.setLngLat(this._lngLat),this._update(),this}getElement(){return this._element}setPopup(e){if(this._popup&&(this._popup.remove(),this._popup=null,this._element.removeEventListener(\"keypress\",this._onKeyPress),this._originalTabIndex||this._element.removeAttribute(\"tabindex\")),e){if(!(\"offset\"in e.options)){const t=38.1,i=13.5,o=Math.abs(i)/Math.SQRT2;e.options.offset=this._defaultMarker?{top:[0,0],\"top-left\":[0,0],\"top-right\":[0,0],bottom:[0,-38.1],\"bottom-left\":[o,-1*(t-i+o)],\"bottom-right\":[-o,-1*(t-i+o)],left:[i,-1*(t-i)],right:[-13.5,-1*(t-i)]}:this._offset;}this._popup=e,this._originalTabIndex=this._element.getAttribute(\"tabindex\"),this._originalTabIndex||this._element.setAttribute(\"tabindex\",\"0\"),this._element.addEventListener(\"keypress\",this._onKeyPress);}return this}setSubpixelPositioning(e){return this._subpixelPositioning=e,this}getPopup(){return this._popup}togglePopup(){const e=this._popup;return this._element.style.opacity===this._opacityWhenCovered?this:e?(e.isOpen()?e.remove():(e.setLngLat(this._lngLat),e.addTo(this._map)),this):this}_updateOpacity(e=!1){var i,o;const r=null===(i=this._map)||void 0===i?void 0:i.terrain,a=this._map.transform.isLocationOccluded(this._lngLat);if(!r||a){const e=a?this._opacityWhenCovered:this._opacity;return void(this._element.style.opacity!==e&&(this._element.style.opacity=e))}if(e)this._opacityTimeout=null;else {if(this._opacityTimeout)return;this._opacityTimeout=setTimeout((()=>{this._opacityTimeout=null;}),100);}const s=this._map,n=s.terrain.depthAtPoint(this._pos),l=s.terrain.getElevationForLngLatZoom(this._lngLat,s.transform.tileZoom);if(s.transform.lngLatToCameraDepth(this._lngLat,l)-n<.006)return void(this._element.style.opacity=this._opacity);const c=-this._offset.y/s.transform.pixelsPerMeter,h=Math.sin(s.getPitch()*Math.PI/180)*c,u=s.terrain.depthAtPoint(new t.P(this._pos.x,this._pos.y-this._offset.y)),d=s.transform.lngLatToCameraDepth(this._lngLat,l+h)-u>.006;(null===(o=this._popup)||void 0===o?void 0:o.isOpen())&&d&&this._popup.remove(),this._element.style.opacity=d?this._opacityWhenCovered:this._opacity;}getOffset(){return this._offset}setOffset(e){return this._offset=t.P.convert(e),this._update(),this}addClassName(e){this._element.classList.add(e);}removeClassName(e){this._element.classList.remove(e);}toggleClassName(e){return this._element.classList.toggle(e)}setDraggable(e){return this._draggable=!!e,this._map&&(e?(this._map.on(\"mousedown\",this._addDragHandler),this._map.on(\"touchstart\",this._addDragHandler)):(this._map.off(\"mousedown\",this._addDragHandler),this._map.off(\"touchstart\",this._addDragHandler))),this}isDraggable(){return this._draggable}setRotation(e){return this._rotation=e||0,this._update(),this}getRotation(){return this._rotation}setRotationAlignment(e){return this._rotationAlignment=e||\"auto\",this._update(),this}getRotationAlignment(){return this._rotationAlignment}setPitchAlignment(e){return this._pitchAlignment=e&&\"auto\"!==e?e:this._rotationAlignment,this._update(),this}getPitchAlignment(){return this._pitchAlignment}setOpacity(e,t){return (void 0===this._opacity||void 0===e&&void 0===t)&&(this._opacity=\"1\",this._opacityWhenCovered=\"0.2\"),void 0!==e&&(this._opacity=e),void 0!==t&&(this._opacityWhenCovered=t),this._map&&this._updateOpacity(!0),this}}const Ya={positionOptions:{enableHighAccuracy:!1,maximumAge:0,timeout:6e3},fitBoundsOptions:{maxZoom:15},trackUserLocation:!1,showAccuracyCircle:!0,showUserLocation:!0};let Qa=0,Ja=!1;const es={maxWidth:100,unit:\"metric\"};function ts(e,t,i){const o=i&&i.maxWidth||100,r=e._container.clientHeight/2,a=e._container.clientWidth/2,s=e.unproject([a-o/2,r]),n=e.unproject([a+o/2,r]),l=Math.round(e.project(n).x-e.project(s).x),c=Math.min(o,l,e._container.clientWidth),h=s.distanceTo(n);if(i&&\"imperial\"===i.unit){const i=3.2808*h;i>5280?is(t,c,i/5280,e._getUIString(\"ScaleControl.Miles\")):is(t,c,i,e._getUIString(\"ScaleControl.Feet\"));}else i&&\"nautical\"===i.unit?is(t,c,h/1852,e._getUIString(\"ScaleControl.NauticalMiles\")):h>=1e3?is(t,c,h/1e3,e._getUIString(\"ScaleControl.Kilometers\")):is(t,c,h,e._getUIString(\"ScaleControl.Meters\"));}function is(e,t,i,o){const r=function(e){const t=Math.pow(10,`${Math.floor(e)}`.length-1);let i=e/t;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:i>=1?1:function(e){const t=Math.pow(10,Math.ceil(-Math.log(e)/Math.LN10));return Math.round(e*t)/t}(i),t*i}(i);e.style.width=t*(r/i)+\"px\",e.innerHTML=`${r}&nbsp;${o}`;}const os={closeButton:!0,closeOnClick:!0,focusAfterOpen:!0,className:\"\",maxWidth:\"240px\",subpixelPositioning:!1,locationOccludedOpacity:void 0},rs=[\"a[href]\",\"[tabindex]:not([tabindex='-1'])\",\"[contenteditable]:not([contenteditable='false'])\",\"button:not([disabled])\",\"input:not([disabled])\",\"select:not([disabled])\",\"textarea:not([disabled])\"].join(\", \");function as(e){if(e){if(\"number\"==typeof e){const i=Math.round(Math.abs(e)/Math.SQRT2);return {center:new t.P(0,0),top:new t.P(0,e),\"top-left\":new t.P(i,i),\"top-right\":new t.P(-i,i),bottom:new t.P(0,-e),\"bottom-left\":new t.P(i,-i),\"bottom-right\":new t.P(-i,-i),left:new t.P(e,0),right:new t.P(-e,0)}}if(e instanceof t.P||Array.isArray(e)){const i=t.P.convert(e);return {center:i,top:i,\"top-left\":i,\"top-right\":i,bottom:i,\"bottom-left\":i,\"bottom-right\":i,left:i,right:i}}return {center:t.P.convert(e.center||[0,0]),top:t.P.convert(e.top||[0,0]),\"top-left\":t.P.convert(e[\"top-left\"]||[0,0]),\"top-right\":t.P.convert(e[\"top-right\"]||[0,0]),bottom:t.P.convert(e.bottom||[0,0]),\"bottom-left\":t.P.convert(e[\"bottom-left\"]||[0,0]),\"bottom-right\":t.P.convert(e[\"bottom-right\"]||[0,0]),left:t.P.convert(e.left||[0,0]),right:t.P.convert(e.right||[0,0])}}return as(new t.P(0,0))}const ss=i;e.AJAXError=t.cy,e.Event=t.l,e.Evented=t.E,e.LngLat=t.S,e.MercatorCoordinate=t.a0,e.Point=t.P,e.addProtocol=t.cz,e.config=t.a,e.removeProtocol=t.cA,e.AttributionControl=Da,e.BoxZoomHandler=$r,e.CanvasSource=Y,e.CooperativeGesturesHandler=Ca,e.DoubleClickZoomHandler=ba,e.DragPanHandler=wa,e.DragRotateHandler=Ta,e.EdgeInsets=Mt,e.FullscreenControl=class extends t.E{constructor(e={}){super(),this._onFullscreenChange=()=>{var e;let t=window.document.fullscreenElement||window.document.mozFullScreenElement||window.document.webkitFullscreenElement||window.document.msFullscreenElement;for(;null===(e=null==t?void 0:t.shadowRoot)||void 0===e?void 0:e.fullscreenElement;)t=t.shadowRoot.fullscreenElement;t===this._container!==this._fullscreen&&this._handleFullscreenChange();},this._onClickFullscreen=()=>{this._isFullscreen()?this._exitFullscreen():this._requestFullscreen();},this._fullscreen=!1,e&&e.container&&(e.container instanceof HTMLElement?this._container=e.container:t.w(\"Full screen control 'container' must be a DOM element.\")),\"onfullscreenchange\"in document?this._fullscreenchange=\"fullscreenchange\":\"onmozfullscreenchange\"in document?this._fullscreenchange=\"mozfullscreenchange\":\"onwebkitfullscreenchange\"in document?this._fullscreenchange=\"webkitfullscreenchange\":\"onmsfullscreenchange\"in document&&(this._fullscreenchange=\"MSFullscreenChange\");}onAdd(e){return this._map=e,this._container||(this._container=this._map.getContainer()),this._controlContainer=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-group\"),this._setupUI(),this._controlContainer}onRemove(){n.remove(this._controlContainer),this._map=null,window.document.removeEventListener(this._fullscreenchange,this._onFullscreenChange);}_setupUI(){const e=this._fullscreenButton=n.create(\"button\",\"maplibregl-ctrl-fullscreen\",this._controlContainer);n.create(\"span\",\"maplibregl-ctrl-icon\",e).setAttribute(\"aria-hidden\",\"true\"),e.type=\"button\",this._updateTitle(),this._fullscreenButton.addEventListener(\"click\",this._onClickFullscreen),window.document.addEventListener(this._fullscreenchange,this._onFullscreenChange);}_updateTitle(){const e=this._getTitle();this._fullscreenButton.setAttribute(\"aria-label\",e),this._fullscreenButton.title=e;}_getTitle(){return this._map._getUIString(this._isFullscreen()?\"FullscreenControl.Exit\":\"FullscreenControl.Enter\")}_isFullscreen(){return this._fullscreen}_handleFullscreenChange(){this._fullscreen=!this._fullscreen,this._fullscreenButton.classList.toggle(\"maplibregl-ctrl-shrink\"),this._fullscreenButton.classList.toggle(\"maplibregl-ctrl-fullscreen\"),this._updateTitle(),this._fullscreen?(this.fire(new t.l(\"fullscreenstart\")),this._prevCooperativeGesturesEnabled=this._map.cooperativeGestures.isEnabled(),this._map.cooperativeGestures.disable()):(this.fire(new t.l(\"fullscreenend\")),this._prevCooperativeGesturesEnabled&&this._map.cooperativeGestures.enable());}_exitFullscreen(){window.document.exitFullscreen?window.document.exitFullscreen():window.document.mozCancelFullScreen?window.document.mozCancelFullScreen():window.document.msExitFullscreen?window.document.msExitFullscreen():window.document.webkitCancelFullScreen?window.document.webkitCancelFullScreen():this._togglePseudoFullScreen();}_requestFullscreen(){this._container.requestFullscreen?this._container.requestFullscreen():this._container.mozRequestFullScreen?this._container.mozRequestFullScreen():this._container.msRequestFullscreen?this._container.msRequestFullscreen():this._container.webkitRequestFullscreen?this._container.webkitRequestFullscreen():this._togglePseudoFullScreen();}_togglePseudoFullScreen(){this._container.classList.toggle(\"maplibregl-pseudo-fullscreen\"),this._handleFullscreenChange(),this._map.resize();}},e.GeoJSONSource=H,e.GeolocateControl=class extends t.E{constructor(e){super(),this._onSuccess=e=>{if(this._map){if(this._isOutOfMapMaxBounds(e))return this._setErrorState(),this.fire(new t.l(\"outofmaxbounds\",e)),this._updateMarker(),void this._finish();if(this.options.trackUserLocation)switch(this._lastKnownPosition=e,this._watchState){case \"WAITING_ACTIVE\":case \"ACTIVE_LOCK\":case \"ACTIVE_ERROR\":this._watchState=\"ACTIVE_LOCK\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active-error\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-active\");break;case \"BACKGROUND\":case \"BACKGROUND_ERROR\":this._watchState=\"BACKGROUND\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background-error\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-background\");break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}this.options.showUserLocation&&\"OFF\"!==this._watchState&&this._updateMarker(e),this.options.trackUserLocation&&\"ACTIVE_LOCK\"!==this._watchState||this._updateCamera(e),this.options.showUserLocation&&this._dotElement.classList.remove(\"maplibregl-user-location-dot-stale\"),this.fire(new t.l(\"geolocate\",e)),this._finish();}},this._updateCamera=e=>{const i=new t.S(e.coords.longitude,e.coords.latitude),o=e.coords.accuracy,r=this._map.getBearing(),a=t.e({bearing:r},this.options.fitBoundsOptions),s=G.fromLngLat(i,o);this._map.fitBounds(s,a,{geolocateSource:!0});},this._updateMarker=e=>{if(e){const i=new t.S(e.coords.longitude,e.coords.latitude);this._accuracyCircleMarker.setLngLat(i).addTo(this._map),this._userLocationDotMarker.setLngLat(i).addTo(this._map),this._accuracy=e.coords.accuracy,this.options.showUserLocation&&this.options.showAccuracyCircle&&this._updateCircleRadius();}else this._userLocationDotMarker.remove(),this._accuracyCircleMarker.remove();},this._onZoom=()=>{this.options.showUserLocation&&this.options.showAccuracyCircle&&this._updateCircleRadius();},this._onError=e=>{if(this._map){if(1===e.code){this._watchState=\"OFF\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active-error\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background-error\"),this._geolocateButton.disabled=!0;const e=this._map._getUIString(\"GeolocateControl.LocationNotAvailable\");this._geolocateButton.title=e,this._geolocateButton.setAttribute(\"aria-label\",e),void 0!==this._geolocationWatchID&&this._clearWatch();}else {if(3===e.code&&Ja)return;this.options.trackUserLocation&&this._setErrorState();}\"OFF\"!==this._watchState&&this.options.showUserLocation&&this._dotElement.classList.add(\"maplibregl-user-location-dot-stale\"),this.fire(new t.l(\"error\",e)),this._finish();}},this._finish=()=>{this._timeoutId&&clearTimeout(this._timeoutId),this._timeoutId=void 0;},this._setupUI=()=>{this._map&&(this._container.addEventListener(\"contextmenu\",(e=>e.preventDefault())),this._geolocateButton=n.create(\"button\",\"maplibregl-ctrl-geolocate\",this._container),n.create(\"span\",\"maplibregl-ctrl-icon\",this._geolocateButton).setAttribute(\"aria-hidden\",\"true\"),this._geolocateButton.type=\"button\",this._geolocateButton.disabled=!0);},this._finishSetupUI=e=>{if(this._map){if(!1===e){t.w(\"Geolocation support is not available so the GeolocateControl will be disabled.\");const e=this._map._getUIString(\"GeolocateControl.LocationNotAvailable\");this._geolocateButton.disabled=!0,this._geolocateButton.title=e,this._geolocateButton.setAttribute(\"aria-label\",e);}else {const e=this._map._getUIString(\"GeolocateControl.FindMyLocation\");this._geolocateButton.disabled=!1,this._geolocateButton.title=e,this._geolocateButton.setAttribute(\"aria-label\",e);}this.options.trackUserLocation&&(this._geolocateButton.setAttribute(\"aria-pressed\",\"false\"),this._watchState=\"OFF\"),this.options.showUserLocation&&(this._dotElement=n.create(\"div\",\"maplibregl-user-location-dot\"),this._userLocationDotMarker=new Ka({element:this._dotElement}),this._circleElement=n.create(\"div\",\"maplibregl-user-location-accuracy-circle\"),this._accuracyCircleMarker=new Ka({element:this._circleElement,pitchAlignment:\"map\"}),this.options.trackUserLocation&&(this._watchState=\"OFF\"),this._map.on(\"zoom\",this._onZoom)),this._geolocateButton.addEventListener(\"click\",(()=>this.trigger())),this._setup=!0,this.options.trackUserLocation&&this._map.on(\"movestart\",(e=>{e.geolocateSource||\"ACTIVE_LOCK\"!==this._watchState||e.originalEvent&&\"resize\"===e.originalEvent.type||(this._watchState=\"BACKGROUND\",this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-background\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active\"),this.fire(new t.l(\"trackuserlocationend\")),this.fire(new t.l(\"userlocationlostfocus\")));}));}},this.options=t.e({},Ya,e);}onAdd(e){return this._map=e,this._container=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-group\"),this._setupUI(),function(){return t._(this,arguments,void 0,(function*(e=!1){if(void 0!==qa&&!e)return qa;if(void 0===window.navigator.permissions)return qa=!!window.navigator.geolocation,qa;try{const e=yield window.navigator.permissions.query({name:\"geolocation\"});qa=\"denied\"!==e.state;}catch(e){qa=!!window.navigator.geolocation;}return qa}))}().then((e=>this._finishSetupUI(e))),this._container}onRemove(){void 0!==this._geolocationWatchID&&(window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0),this.options.showUserLocation&&this._userLocationDotMarker&&this._userLocationDotMarker.remove(),this.options.showAccuracyCircle&&this._accuracyCircleMarker&&this._accuracyCircleMarker.remove(),n.remove(this._container),this._map.off(\"zoom\",this._onZoom),this._map=void 0,Qa=0,Ja=!1;}_isOutOfMapMaxBounds(e){const t=this._map.getMaxBounds(),i=e.coords;return t&&(i.longitude<t.getWest()||i.longitude>t.getEast()||i.latitude<t.getSouth()||i.latitude>t.getNorth())}_setErrorState(){switch(this._watchState){case \"WAITING_ACTIVE\":this._watchState=\"ACTIVE_ERROR\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-active-error\");break;case \"ACTIVE_LOCK\":this._watchState=\"ACTIVE_ERROR\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-active-error\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-waiting\");break;case \"BACKGROUND\":this._watchState=\"BACKGROUND_ERROR\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-background-error\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-waiting\");break;case \"ACTIVE_ERROR\":break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}}_updateCircleRadius(){const e=this._map.getBounds(),t=e.getSouthEast(),i=e.getNorthEast(),o=t.distanceTo(i),r=Math.ceil(this._accuracy/(o/this._map._container.clientHeight)*2);this._circleElement.style.width=`${r}px`,this._circleElement.style.height=`${r}px`;}trigger(){if(!this._setup)return t.w(\"Geolocate control triggered before added to a map\"),!1;if(this.options.trackUserLocation){switch(this._watchState){case \"OFF\":this._watchState=\"WAITING_ACTIVE\",this.fire(new t.l(\"trackuserlocationstart\"));break;case \"WAITING_ACTIVE\":case \"ACTIVE_LOCK\":case \"ACTIVE_ERROR\":case \"BACKGROUND_ERROR\":Qa--,Ja=!1,this._watchState=\"OFF\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-active-error\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background\"),this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background-error\"),this.fire(new t.l(\"trackuserlocationend\"));break;case \"BACKGROUND\":this._watchState=\"ACTIVE_LOCK\",this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-background\"),this._lastKnownPosition&&this._updateCamera(this._lastKnownPosition),this.fire(new t.l(\"trackuserlocationstart\")),this.fire(new t.l(\"userlocationfocus\"));break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}switch(this._watchState){case \"WAITING_ACTIVE\":this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-active\");break;case \"ACTIVE_LOCK\":this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-active\");break;case \"OFF\":break;default:throw new Error(`Unexpected watchState ${this._watchState}`)}if(\"OFF\"===this._watchState&&void 0!==this._geolocationWatchID)this._clearWatch();else if(void 0===this._geolocationWatchID){let e;this._geolocateButton.classList.add(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.setAttribute(\"aria-pressed\",\"true\"),Qa++,Qa>1?(e={maximumAge:6e5,timeout:0},Ja=!0):(e=this.options.positionOptions,Ja=!1),this._geolocationWatchID=window.navigator.geolocation.watchPosition(this._onSuccess,this._onError,e);}}else window.navigator.geolocation.getCurrentPosition(this._onSuccess,this._onError,this.options.positionOptions),this._timeoutId=setTimeout(this._finish,1e4);return !0}_clearWatch(){window.navigator.geolocation.clearWatch(this._geolocationWatchID),this._geolocationWatchID=void 0,this._geolocateButton.classList.remove(\"maplibregl-ctrl-geolocate-waiting\"),this._geolocateButton.setAttribute(\"aria-pressed\",\"false\"),this.options.showUserLocation&&this._updateMarker(null);}},e.GlobeControl=class{constructor(){this._toggleProjection=()=>{var e;const t=null===(e=this._map.getProjection())||void 0===e?void 0:e.type;this._map.setProjection(\"mercator\"!==t&&t?{type:\"mercator\"}:{type:\"globe\"}),this._updateGlobeIcon();},this._updateGlobeIcon=()=>{var e;this._globeButton.classList.remove(\"maplibregl-ctrl-globe\"),this._globeButton.classList.remove(\"maplibregl-ctrl-globe-enabled\"),\"globe\"===(null===(e=this._map.getProjection())||void 0===e?void 0:e.type)?(this._globeButton.classList.add(\"maplibregl-ctrl-globe-enabled\"),this._globeButton.title=this._map._getUIString(\"GlobeControl.Disable\")):(this._globeButton.classList.add(\"maplibregl-ctrl-globe\"),this._globeButton.title=this._map._getUIString(\"GlobeControl.Enable\"));};}onAdd(e){return this._map=e,this._container=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-group\"),this._globeButton=n.create(\"button\",\"maplibregl-ctrl-globe\",this._container),n.create(\"span\",\"maplibregl-ctrl-icon\",this._globeButton).setAttribute(\"aria-hidden\",\"true\"),this._globeButton.type=\"button\",this._globeButton.addEventListener(\"click\",this._toggleProjection),this._updateGlobeIcon(),this._map.on(\"styledata\",this._updateGlobeIcon),this._container}onRemove(){n.remove(this._container),this._map.off(\"styledata\",this._updateGlobeIcon),this._globeButton.removeEventListener(\"click\",this._toggleProjection),this._map=void 0;}},e.Hash=Er,e.ImageSource=X,e.KeyboardHandler=pa,e.LngLatBounds=G,e.LogoControl=Aa,e.Map=class extends Ra{constructor(e){var i,o;t.cv.mark(t.cw.create);const r=Object.assign(Object.assign(Object.assign({},Ga),e),{canvasContextAttributes:Object.assign(Object.assign({},Ga.canvasContextAttributes),e.canvasContextAttributes)});if(null!=r.minZoom&&null!=r.maxZoom&&r.minZoom>r.maxZoom)throw new Error(\"maxZoom must be greater than or equal to minZoom\");if(null!=r.minPitch&&null!=r.maxPitch&&r.minPitch>r.maxPitch)throw new Error(\"maxPitch must be greater than or equal to minPitch\");if(null!=r.minPitch&&r.minPitch<0)throw new Error(\"minPitch must be greater than or equal to 0\");if(null!=r.maxPitch&&r.maxPitch>180)throw new Error(\"maxPitch must be less than or equal to 180\");const a=new Lt,s=new Ot;if(void 0!==r.minZoom&&a.setMinZoom(r.minZoom),void 0!==r.maxZoom&&a.setMaxZoom(r.maxZoom),void 0!==r.minPitch&&a.setMinPitch(r.minPitch),void 0!==r.maxPitch&&a.setMaxPitch(r.maxPitch),void 0!==r.renderWorldCopies&&a.setRenderWorldCopies(r.renderWorldCopies),super(a,s,{bearingSnap:r.bearingSnap}),this._idleTriggered=!1,this._crossFadingFactor=1,this._renderTaskQueue=new La,this._controls=[],this._mapId=t.a6(),this._contextLost=e=>{e.preventDefault(),this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this.fire(new t.l(\"webglcontextlost\",{originalEvent:e}));},this._contextRestored=e=>{this._setupPainter(),this.resize(),this._update(),this.fire(new t.l(\"webglcontextrestored\",{originalEvent:e}));},this._onMapScroll=e=>{if(e.target===this._container)return this._container.scrollTop=0,this._container.scrollLeft=0,!1},this._onWindowOnline=()=>{this._update();},this._interactive=r.interactive,this._maxTileCacheSize=r.maxTileCacheSize,this._maxTileCacheZoomLevels=r.maxTileCacheZoomLevels,this._canvasContextAttributes=Object.assign({},r.canvasContextAttributes),this._trackResize=!0===r.trackResize,this._bearingSnap=r.bearingSnap,this._centerClampedToGround=r.centerClampedToGround,this._refreshExpiredTiles=!0===r.refreshExpiredTiles,this._fadeDuration=r.fadeDuration,this._crossSourceCollisions=!0===r.crossSourceCollisions,this._collectResourceTiming=!0===r.collectResourceTiming,this._locale=Object.assign(Object.assign({},Za),r.locale),this._clickTolerance=r.clickTolerance,this._overridePixelRatio=r.pixelRatio,this._maxCanvasSize=r.maxCanvasSize,this.transformCameraUpdate=r.transformCameraUpdate,this.cancelPendingTileRequestsWhileZooming=!0===r.cancelPendingTileRequestsWhileZooming,this._imageQueueHandle=p.addThrottleControl((()=>this.isMoving())),this._requestManager=new m(r.transformRequest),\"string\"==typeof r.container){if(this._container=document.getElementById(r.container),!this._container)throw new Error(`Container '${r.container}' not found.`)}else {if(!(r.container instanceof HTMLElement))throw new Error(\"Invalid type: 'container' must be a String or HTMLElement.\");this._container=r.container;}if(r.maxBounds&&this.setMaxBounds(r.maxBounds),this._setupContainer(),this._setupPainter(),this.on(\"move\",(()=>this._update(!1))),this.on(\"moveend\",(()=>this._update(!1))),this.on(\"zoom\",(()=>this._update(!0))),this.on(\"terrain\",(()=>{this.painter.terrainFacilitator.dirty=!0,this._update(!0);})),this.once(\"idle\",(()=>{this._idleTriggered=!0;})),\"undefined\"!=typeof window){addEventListener(\"online\",this._onWindowOnline,!1);let e=!1;const t=Sr((e=>{this._trackResize&&!this._removed&&(this.resize(e),this.redraw());}),50);this._resizeObserver=new ResizeObserver((i=>{e?t(i):e=!0;})),this._resizeObserver.observe(this._container);}this.handlers=new Ea(this,r),this._hash=r.hash&&new Er(\"string\"==typeof r.hash&&r.hash||void 0).addTo(this),this._hash&&this._hash._onHashChange()||(this.jumpTo({center:r.center,elevation:r.elevation,zoom:r.zoom,bearing:r.bearing,pitch:r.pitch,roll:r.roll}),r.bounds&&(this.resize(),this.fitBounds(r.bounds,t.e({},r.fitBoundsOptions,{duration:0}))));const n=\"string\"==typeof r.style||!(\"globe\"===(null===(o=null===(i=r.style)||void 0===i?void 0:i.projection)||void 0===o?void 0:o.type));this.resize(null,n),this._localIdeographFontFamily=r.localIdeographFontFamily,this._validateStyle=r.validateStyle,r.style&&this.setStyle(r.style,{localIdeographFontFamily:r.localIdeographFontFamily}),r.attributionControl&&this.addControl(new Da(\"boolean\"==typeof r.attributionControl?void 0:r.attributionControl)),r.maplibreLogo&&this.addControl(new Aa,r.logoPosition),this.on(\"style.load\",(()=>{if(n||this._resizeTransform(),this.transform.unmodified){const e=t.Q(this.style.stylesheet,[\"center\",\"zoom\",\"bearing\",\"pitch\",\"roll\"]);this.jumpTo(e);}})),this.on(\"data\",(e=>{this._update(\"style\"===e.dataType),this.fire(new t.l(`${e.dataType}data`,e));})),this.on(\"dataloading\",(e=>{this.fire(new t.l(`${e.dataType}dataloading`,e));})),this.on(\"dataabort\",(e=>{this.fire(new t.l(\"sourcedataabort\",e));}));}_getMapId(){return this._mapId}setGlobalStateProperty(e,t){return this.style.setGlobalStateProperty(e,t),this._update(!0)}getGlobalState(){return this.style.getGlobalState()}addControl(e,i){if(void 0===i&&(i=e.getDefaultPosition?e.getDefaultPosition():\"top-right\"),!e||!e.onAdd)return this.fire(new t.k(new Error(\"Invalid argument to map.addControl(). Argument must be a control with onAdd and onRemove methods.\")));const o=e.onAdd(this);this._controls.push(e);const r=this._controlPositions[i];return -1!==i.indexOf(\"bottom\")?r.insertBefore(o,r.firstChild):r.appendChild(o),this}removeControl(e){if(!e||!e.onRemove)return this.fire(new t.k(new Error(\"Invalid argument to map.removeControl(). Argument must be a control with onAdd and onRemove methods.\")));const i=this._controls.indexOf(e);return i>-1&&this._controls.splice(i,1),e.onRemove(this),this}hasControl(e){return this._controls.indexOf(e)>-1}calculateCameraOptionsFromTo(e,t,i,o){return null==o&&this.terrain&&(o=this.terrain.getElevationForLngLatZoom(i,this.transform.tileZoom)),super.calculateCameraOptionsFromTo(e,t,i,o)}resize(e,i=!0){const[o,r]=this._containerDimensions(),a=this._getClampedPixelRatio(o,r);if(this._resizeCanvas(o,r,a),this.painter.resize(o,r,a),this.painter.overLimit()){const e=this.painter.context.gl;this._maxCanvasSize=[e.drawingBufferWidth,e.drawingBufferHeight];const t=this._getClampedPixelRatio(o,r);this._resizeCanvas(o,r,t),this.painter.resize(o,r,t);}this._resizeTransform(i);const s=!this._moving;return s&&(this.stop(),this.fire(new t.l(\"movestart\",e)).fire(new t.l(\"move\",e))),this.fire(new t.l(\"resize\",e)),s&&this.fire(new t.l(\"moveend\",e)),this}_resizeTransform(e=!0){var t;const[i,o]=this._containerDimensions();this.transform.resize(i,o,e),null===(t=this._requestedCameraState)||void 0===t||t.resize(i,o,e);}_getClampedPixelRatio(e,t){const{0:i,1:o}=this._maxCanvasSize,r=this.getPixelRatio(),a=e*r,s=t*r;return Math.min(a>i?i/a:1,s>o?o/s:1)*r}getPixelRatio(){var e;return null!==(e=this._overridePixelRatio)&&void 0!==e?e:devicePixelRatio}setPixelRatio(e){this._overridePixelRatio=e,this.resize();}getBounds(){return this.transform.getBounds()}getMaxBounds(){return this.transform.getMaxBounds()}setMaxBounds(e){return this.transform.setMaxBounds(G.convert(e)),this._update()}setMinZoom(e){if((e=null==e?-2:e)>=-2&&e<=this.transform.maxZoom)return this.transform.setMinZoom(e),this._update(),this.getZoom()<e&&this.setZoom(e),this;throw new Error(\"minZoom must be between -2 and the current maxZoom, inclusive\")}getMinZoom(){return this.transform.minZoom}setMaxZoom(e){if((e=null==e?22:e)>=this.transform.minZoom)return this.transform.setMaxZoom(e),this._update(),this.getZoom()>e&&this.setZoom(e),this;throw new Error(\"maxZoom must be greater than the current minZoom\")}getMaxZoom(){return this.transform.maxZoom}setMinPitch(e){if((e=null==e?0:e)<0)throw new Error(\"minPitch must be greater than or equal to 0\");if(e>=0&&e<=this.transform.maxPitch)return this.transform.setMinPitch(e),this._update(),this.getPitch()<e&&this.setPitch(e),this;throw new Error(\"minPitch must be between 0 and the current maxPitch, inclusive\")}getMinPitch(){return this.transform.minPitch}setMaxPitch(e){if((e=null==e?60:e)>180)throw new Error(\"maxPitch must be less than or equal to 180\");if(e>=this.transform.minPitch)return this.transform.setMaxPitch(e),this._update(),this.getPitch()>e&&this.setPitch(e),this;throw new Error(\"maxPitch must be greater than the current minPitch\")}getMaxPitch(){return this.transform.maxPitch}getRenderWorldCopies(){return this.transform.renderWorldCopies}setRenderWorldCopies(e){return this.transform.setRenderWorldCopies(e),this._update()}project(e){return this.transform.locationToScreenPoint(t.S.convert(e),this.style&&this.terrain)}unproject(e){return this.transform.screenPointToLocation(t.P.convert(e),this.terrain)}isMoving(){var e;return this._moving||(null===(e=this.handlers)||void 0===e?void 0:e.isMoving())}isZooming(){var e;return this._zooming||(null===(e=this.handlers)||void 0===e?void 0:e.isZooming())}isRotating(){var e;return this._rotating||(null===(e=this.handlers)||void 0===e?void 0:e.isRotating())}_createDelegatedListener(e,t,i){if(\"mouseenter\"===e||\"mouseover\"===e){let o=!1;const r=r=>{const a=t.filter((e=>this.getLayer(e))),s=0!==a.length?this.queryRenderedFeatures(r.point,{layers:a}):[];s.length?o||(o=!0,i.call(this,new jr(e,this,r.originalEvent,{features:s}))):o=!1;};return {layers:t,listener:i,delegates:{mousemove:r,mouseout:()=>{o=!1;}}}}if(\"mouseleave\"===e||\"mouseout\"===e){let o=!1;const r=r=>{const a=t.filter((e=>this.getLayer(e)));(0!==a.length?this.queryRenderedFeatures(r.point,{layers:a}):[]).length?o=!0:o&&(o=!1,i.call(this,new jr(e,this,r.originalEvent)));},a=t=>{o&&(o=!1,i.call(this,new jr(e,this,t.originalEvent)));};return {layers:t,listener:i,delegates:{mousemove:r,mouseout:a}}}{const o=e=>{const o=t.filter((e=>this.getLayer(e))),r=0!==o.length?this.queryRenderedFeatures(e.point,{layers:o}):[];r.length&&(e.features=r,i.call(this,e),delete e.features);};return {layers:t,listener:i,delegates:{[e]:o}}}}_saveDelegatedListener(e,t){this._delegatedListeners=this._delegatedListeners||{},this._delegatedListeners[e]=this._delegatedListeners[e]||[],this._delegatedListeners[e].push(t);}_removeDelegatedListener(e,t,i){if(!this._delegatedListeners||!this._delegatedListeners[e])return;const o=this._delegatedListeners[e];for(let e=0;e<o.length;e++){const r=o[e];if(r.listener===i&&r.layers.length===t.length&&r.layers.every((e=>t.includes(e)))){for(const e in r.delegates)this.off(e,r.delegates[e]);return void o.splice(e,1)}}}on(e,t,i){if(void 0===i)return super.on(e,t);const o=\"string\"==typeof t?[t]:t,r=this._createDelegatedListener(e,o,i);this._saveDelegatedListener(e,r);for(const e in r.delegates)this.on(e,r.delegates[e]);return {unsubscribe:()=>{this._removeDelegatedListener(e,o,i);}}}once(e,t,i){if(void 0===i)return super.once(e,t);const o=\"string\"==typeof t?[t]:t,r=this._createDelegatedListener(e,o,i);for(const t in r.delegates){const a=r.delegates[t];r.delegates[t]=(...t)=>{this._removeDelegatedListener(e,o,i),a(...t);};}this._saveDelegatedListener(e,r);for(const e in r.delegates)this.once(e,r.delegates[e]);return this}off(e,t,i){return void 0===i?super.off(e,t):(this._removeDelegatedListener(e,\"string\"==typeof t?[t]:t,i),this)}queryRenderedFeatures(e,i){if(!this.style)return [];let o;const r=e instanceof t.P||Array.isArray(e),a=r?e:[[0,0],[this.transform.width,this.transform.height]];if(i=i||(r?{}:e)||{},a instanceof t.P||\"number\"==typeof a[0])o=[t.P.convert(a)];else {const e=t.P.convert(a[0]),i=t.P.convert(a[1]);o=[e,new t.P(i.x,e.y),i,new t.P(e.x,i.y),e];}return this.style.queryRenderedFeatures(o,i,this.transform)}querySourceFeatures(e,t){return this.style.querySourceFeatures(e,t)}setStyle(e,i){return !1!==(i=t.e({},{localIdeographFontFamily:this._localIdeographFontFamily,validate:this._validateStyle},i)).diff&&i.localIdeographFontFamily===this._localIdeographFontFamily&&this.style&&e?(this._diffStyle(e,i),this):(this._localIdeographFontFamily=i.localIdeographFontFamily,this._updateStyle(e,i))}setTransformRequest(e){return this._requestManager.setTransformRequest(e),this}_getUIString(e){const t=this._locale[e];if(null==t)throw new Error(`Missing UI string '${e}'`);return t}_updateStyle(e,t){var i,o;if(t.transformStyle&&this.style&&!this.style._loaded)return void this.style.once(\"style.load\",(()=>this._updateStyle(e,t)));const r=this.style&&t.transformStyle?this.style.serialize():void 0;return this.style&&(this.style.setEventedParent(null),this.style._remove(!e)),e?(this.style=new wi(this,t||{}),this.style.setEventedParent(this,{style:this.style}),\"string\"==typeof e?this.style.loadURL(e,t,r):this.style.loadJSON(e,t,r),this):(null===(o=null===(i=this.style)||void 0===i?void 0:i.projection)||void 0===o||o.destroy(),delete this.style,this)}_lazyInitEmptyStyle(){this.style||(this.style=new wi(this,{}),this.style.setEventedParent(this,{style:this.style}),this.style.loadEmpty());}_diffStyle(e,i){if(\"string\"==typeof e){const o=this._requestManager.transformRequest(e,\"Style\");t.j(o,new AbortController).then((e=>{this._updateDiff(e.data,i);})).catch((e=>{e&&this.fire(new t.k(e));}));}else \"object\"==typeof e&&this._updateDiff(e,i);}_updateDiff(e,i){try{this.style.setState(e,i)&&this._update(!0);}catch(o){t.w(`Unable to perform style diff: ${o.message||o.error||o}.  Rebuilding the style from scratch.`),this._updateStyle(e,i);}}getStyle(){if(this.style)return this.style.serialize()}isStyleLoaded(){return this.style?this.style.loaded():t.w(\"There is no style added to the map.\")}addSource(e,t){return this._lazyInitEmptyStyle(),this.style.addSource(e,t),this._update(!0)}isSourceLoaded(e){const i=this.style&&this.style.sourceCaches[e];if(void 0!==i)return i.loaded();this.fire(new t.k(new Error(`There is no source with ID '${e}'`)));}setTerrain(e){if(this.style._checkLoaded(),this._terrainDataCallback&&this.style.off(\"data\",this._terrainDataCallback),e){const i=this.style.sourceCaches[e.source];if(!i)throw new Error(`cannot load terrain, because there exists no source with ID: ${e.source}`);null===this.terrain&&i.reload();for(const i in this.style._layers){const o=this.style._layers[i];\"hillshade\"===o.type&&o.source===e.source&&t.w(\"You are using the same source for a hillshade layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.\"),\"color-relief\"===o.type&&o.source===e.source&&t.w(\"You are using the same source for a color-relief layer and for 3D terrain. Please consider using two separate sources to improve rendering quality.\");}this.terrain=new Ba(this.painter,i,e),this.painter.renderToTexture=new Na(this.painter,this.terrain),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this._terrainDataCallback=t=>{var i;\"style\"===t.dataType?this.terrain.sourceCache.freeRtt():\"source\"===t.dataType&&t.tile&&(t.sourceId!==e.source||this._elevationFreeze||(this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),this._centerClampedToGround&&this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom))),\"image\"===(null===(i=t.source)||void 0===i?void 0:i.type)?this.terrain.sourceCache.freeRtt():this.terrain.sourceCache.freeRtt(t.tile.tileID));},this.style.on(\"data\",this._terrainDataCallback);}else this.terrain&&this.terrain.sourceCache.destruct(),this.terrain=null,this.painter.renderToTexture&&this.painter.renderToTexture.destruct(),this.painter.renderToTexture=null,this.transform.setMinElevationForCurrentTile(0),this._centerClampedToGround&&this.transform.setElevation(0);return this.fire(new t.l(\"terrain\",{terrain:e})),this}getTerrain(){var e,t;return null!==(t=null===(e=this.terrain)||void 0===e?void 0:e.options)&&void 0!==t?t:null}areTilesLoaded(){const e=this.style&&this.style.sourceCaches;for(const t in e){const i=e[t]._tiles;for(const e in i){const t=i[e];if(\"loaded\"!==t.state&&\"errored\"!==t.state)return !1}}return !0}removeSource(e){return this.style.removeSource(e),this._update(!0)}getSource(e){return this.style.getSource(e)}setSourceTileLodParams(e,t,i){if(i){const o=this.getSource(i);if(!o)throw new Error(`There is no source with ID \"${i}\", cannot set LOD parameters`);o.calculateTileZoom=me(Math.max(1,e),Math.max(1,t));}else for(const i in this.style.sourceCaches)this.style.sourceCaches[i].getSource().calculateTileZoom=me(Math.max(1,e),Math.max(1,t));return this._update(!0),this}refreshTiles(e,i){const o=this.style.sourceCaches[e];if(!o)throw new Error(`There is no source cache with ID \"${e}\", cannot refresh tile`);void 0===i?o.reload(!0):o.refreshTiles(i.map((e=>new t.a3(e.z,e.x,e.y))));}addImage(e,i,o={}){const{pixelRatio:r=1,sdf:a=!1,stretchX:n,stretchY:l,content:c,textFitWidth:h,textFitHeight:u}=o;if(this._lazyInitEmptyStyle(),!(i instanceof HTMLImageElement||t.b(i))){if(void 0===i.width||void 0===i.height)return this.fire(new t.k(new Error(\"Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`\")));{const{width:o,height:s,data:d}=i,_=i;return this.style.addImage(e,{data:new t.R({width:o,height:s},new Uint8Array(d)),pixelRatio:r,stretchX:n,stretchY:l,content:c,textFitWidth:h,textFitHeight:u,sdf:a,version:0,userImage:_}),_.onAdd&&_.onAdd(this,e),this}}{const{width:o,height:d,data:_}=s.getImageData(i);this.style.addImage(e,{data:new t.R({width:o,height:d},_),pixelRatio:r,stretchX:n,stretchY:l,content:c,textFitWidth:h,textFitHeight:u,sdf:a,version:0});}}updateImage(e,i){const o=this.style.getImage(e);if(!o)return this.fire(new t.k(new Error(\"The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.\")));const r=i instanceof HTMLImageElement||t.b(i)?s.getImageData(i):i,{width:a,height:n,data:l}=r;if(void 0===a||void 0===n)return this.fire(new t.k(new Error(\"Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, or object with `width`, `height`, and `data` properties with the same format as `ImageData`\")));if(a!==o.data.width||n!==o.data.height)return this.fire(new t.k(new Error(\"The width and height of the updated image must be that same as the previous version of the image\")));const c=!(i instanceof HTMLImageElement||t.b(i));return o.data.replace(l,c),this.style.updateImage(e,o),this}getImage(e){return this.style.getImage(e)}hasImage(e){return e?!!this.style.getImage(e):(this.fire(new t.k(new Error(\"Missing required image id\"))),!1)}removeImage(e){this.style.removeImage(e);}loadImage(e){return p.getImage(this._requestManager.transformRequest(e,\"Image\"),new AbortController)}listImages(){return this.style.listImages()}addLayer(e,t){return this._lazyInitEmptyStyle(),this.style.addLayer(e,t),this._update(!0)}moveLayer(e,t){return this.style.moveLayer(e,t),this._update(!0)}removeLayer(e){return this.style.removeLayer(e),this._update(!0)}getLayer(e){return this.style.getLayer(e)}getLayersOrder(){return this.style.getLayersOrder()}setLayerZoomRange(e,t,i){return this.style.setLayerZoomRange(e,t,i),this._update(!0)}setFilter(e,t,i={}){return this.style.setFilter(e,t,i),this._update(!0)}getFilter(e){return this.style.getFilter(e)}setPaintProperty(e,t,i,o={}){return this.style.setPaintProperty(e,t,i,o),this._update(!0)}getPaintProperty(e,t){return this.style.getPaintProperty(e,t)}setLayoutProperty(e,t,i,o={}){return this.style.setLayoutProperty(e,t,i,o),this._update(!0)}getLayoutProperty(e,t){return this.style.getLayoutProperty(e,t)}setGlyphs(e,t={}){return this._lazyInitEmptyStyle(),this.style.setGlyphs(e,t),this._update(!0)}getGlyphs(){return this.style.getGlyphsUrl()}addSprite(e,t,i={}){return this._lazyInitEmptyStyle(),this.style.addSprite(e,t,i,(e=>{e||this._update(!0);})),this}removeSprite(e){return this._lazyInitEmptyStyle(),this.style.removeSprite(e),this._update(!0)}getSprite(){return this.style.getSprite()}setSprite(e,t={}){return this._lazyInitEmptyStyle(),this.style.setSprite(e,t,(e=>{e||this._update(!0);})),this}setLight(e,t={}){return this._lazyInitEmptyStyle(),this.style.setLight(e,t),this._update(!0)}getLight(){return this.style.getLight()}setSky(e,t={}){return this._lazyInitEmptyStyle(),this.style.setSky(e,t),this._update(!0)}getSky(){return this.style.getSky()}setFeatureState(e,t){return this.style.setFeatureState(e,t),this._update()}removeFeatureState(e,t){return this.style.removeFeatureState(e,t),this._update()}getFeatureState(e){return this.style.getFeatureState(e)}getContainer(){return this._container}getCanvasContainer(){return this._canvasContainer}getCanvas(){return this._canvas}_containerDimensions(){let e=0,t=0;return this._container&&(e=this._container.clientWidth||400,t=this._container.clientHeight||300),[e,t]}_setupContainer(){const e=this._container;e.classList.add(\"maplibregl-map\");const t=this._canvasContainer=n.create(\"div\",\"maplibregl-canvas-container\",e);this._interactive&&t.classList.add(\"maplibregl-interactive\"),this._canvas=n.create(\"canvas\",\"maplibregl-canvas\",t),this._canvas.addEventListener(\"webglcontextlost\",this._contextLost,!1),this._canvas.addEventListener(\"webglcontextrestored\",this._contextRestored,!1),this._canvas.setAttribute(\"tabindex\",this._interactive?\"0\":\"-1\"),this._canvas.setAttribute(\"aria-label\",this._getUIString(\"Map.Title\")),this._canvas.setAttribute(\"role\",\"region\");const i=this._containerDimensions(),o=this._getClampedPixelRatio(i[0],i[1]);this._resizeCanvas(i[0],i[1],o);const r=this._controlContainer=n.create(\"div\",\"maplibregl-control-container\",e),a=this._controlPositions={};[\"top-left\",\"top-right\",\"bottom-left\",\"bottom-right\"].forEach((e=>{a[e]=n.create(\"div\",`maplibregl-ctrl-${e} `,r);})),this._container.addEventListener(\"scroll\",this._onMapScroll,!1);}_resizeCanvas(e,t,i){this._canvas.width=Math.floor(i*e),this._canvas.height=Math.floor(i*t),this._canvas.style.width=`${e}px`,this._canvas.style.height=`${t}px`;}_setupPainter(){const e=Object.assign(Object.assign({},this._canvasContextAttributes),{alpha:!0,depth:!0,stencil:!0,premultipliedAlpha:!0});let t=null;this._canvas.addEventListener(\"webglcontextcreationerror\",(i=>{t={requestedAttributes:e},i&&(t.statusMessage=i.statusMessage,t.type=i.type);}),{once:!0});let i=null;if(i=this._canvasContextAttributes.contextType?this._canvas.getContext(this._canvasContextAttributes.contextType,e):this._canvas.getContext(\"webgl2\",e)||this._canvas.getContext(\"webgl\",e),!i){const e=\"Failed to initialize WebGL\";throw t?(t.message=e,new Error(JSON.stringify(t))):new Error(e)}this.painter=new Mr(i,this.transform),l.testSupport(i);}migrateProjection(e,i){super.migrateProjection(e,i),this.painter.transform=e,this.fire(new t.l(\"projectiontransition\",{newProjection:this.style.projection.name}));}loaded(){return !this._styleDirty&&!this._sourcesDirty&&!!this.style&&this.style.loaded()}_update(e){return this.style&&this.style._loaded?(this._styleDirty=this._styleDirty||e,this._sourcesDirty=!0,this.triggerRepaint(),this):this}_requestRenderFrame(e){return this._update(),this._renderTaskQueue.add(e)}_cancelRenderFrame(e){this._renderTaskQueue.remove(e);}_render(e){var i,o,r,a,n;const l=this._idleTriggered?this._fadeDuration:0,c=(null===(i=this.style.projection)||void 0===i?void 0:i.transitionState)>0;if(this.painter.context.setDirty(),this.painter.setBaseState(),this._renderTaskQueue.run(e),this._removed)return;let h=!1;if(this.style&&this._styleDirty){this._styleDirty=!1;const e=this.transform.zoom,i=s.now();this.style.zoomHistory.update(e,i);const o=new t.F(e,{now:i,fadeDuration:l,zoomHistory:this.style.zoomHistory,transition:this.style.getTransition(),globalState:this.style.getGlobalState()}),r=o.crossFadingFactor();1===r&&r===this._crossFadingFactor||(h=!0,this._crossFadingFactor=r),this.style.update(o);}const u=(null===(o=this.style.projection)||void 0===o?void 0:o.transitionState)>0!==c;null===(r=this.style.projection)||void 0===r||r.setErrorQueryLatitudeDegrees(this.transform.center.lat),this.transform.setTransitionState(null===(a=this.style.projection)||void 0===a?void 0:a.transitionState,null===(n=this.style.projection)||void 0===n?void 0:n.latitudeErrorCorrectionRadians),this.style&&(this._sourcesDirty||u)&&(this._sourcesDirty=!1,this.style._updateSources(this.transform)),this.terrain?(this.terrain.sourceCache.update(this.transform,this.terrain),this.transform.setMinElevationForCurrentTile(this.terrain.getMinTileElevationForLngLatZoom(this.transform.center,this.transform.tileZoom)),!this._elevationFreeze&&this._centerClampedToGround&&this.transform.setElevation(this.terrain.getElevationForLngLatZoom(this.transform.center,this.transform.tileZoom))):(this.transform.setMinElevationForCurrentTile(0),this._centerClampedToGround&&this.transform.setElevation(0)),this._placementDirty=this.style&&this.style._updatePlacement(this.transform,this.showCollisionBoxes,l,this._crossSourceCollisions,u),this.painter.render(this.style,{showTileBoundaries:this.showTileBoundaries,showOverdrawInspector:this._showOverdrawInspector,rotating:this.isRotating(),zooming:this.isZooming(),moving:this.isMoving(),fadeDuration:l,showPadding:this.showPadding}),this.fire(new t.l(\"render\")),this.loaded()&&!this._loaded&&(this._loaded=!0,t.cv.mark(t.cw.load),this.fire(new t.l(\"load\"))),this.style&&(this.style.hasTransitions()||h)&&(this._styleDirty=!0),this.style&&!this._placementDirty&&this.style._releaseSymbolFadeTiles();const d=this._sourcesDirty||this._styleDirty||this._placementDirty;return d||this._repaint?this.triggerRepaint():!this.isMoving()&&this.loaded()&&this.fire(new t.l(\"idle\")),!this._loaded||this._fullyLoaded||d||(this._fullyLoaded=!0,t.cv.mark(t.cw.fullLoad)),this}redraw(){return this.style&&(this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._render(0)),this}remove(){var e;this._hash&&this._hash.remove();for(const e of this._controls)e.onRemove(this);this._controls=[],this._frameRequest&&(this._frameRequest.abort(),this._frameRequest=null),this._renderTaskQueue.clear(),this.painter.destroy(),this.handlers.destroy(),delete this.handlers,this.setStyle(null),\"undefined\"!=typeof window&&removeEventListener(\"online\",this._onWindowOnline,!1),p.removeThrottleControl(this._imageQueueHandle),null===(e=this._resizeObserver)||void 0===e||e.disconnect();const i=this.painter.context.gl.getExtension(\"WEBGL_lose_context\");(null==i?void 0:i.loseContext)&&i.loseContext(),this._canvas.removeEventListener(\"webglcontextrestored\",this._contextRestored,!1),this._canvas.removeEventListener(\"webglcontextlost\",this._contextLost,!1),n.remove(this._canvasContainer),n.remove(this._controlContainer),this._container.removeEventListener(\"scroll\",this._onMapScroll,!1),this._container.classList.remove(\"maplibregl-map\"),t.cv.clearMetrics(),this._removed=!0,this.fire(new t.l(\"remove\"));}triggerRepaint(){this.style&&!this._frameRequest&&(this._frameRequest=new AbortController,s.frame(this._frameRequest,(e=>{t.cv.frame(e),this._frameRequest=null;try{this._render(e);}catch(e){if(!t.cx(e)&&!function(e){return e.message===qo}(e))throw e}}),(()=>{})));}get showTileBoundaries(){return !!this._showTileBoundaries}set showTileBoundaries(e){this._showTileBoundaries!==e&&(this._showTileBoundaries=e,this._update());}get showPadding(){return !!this._showPadding}set showPadding(e){this._showPadding!==e&&(this._showPadding=e,this._update());}get showCollisionBoxes(){return !!this._showCollisionBoxes}set showCollisionBoxes(e){this._showCollisionBoxes!==e&&(this._showCollisionBoxes=e,e?this.style._generateCollisionBoxes():this._update());}get showOverdrawInspector(){return !!this._showOverdrawInspector}set showOverdrawInspector(e){this._showOverdrawInspector!==e&&(this._showOverdrawInspector=e,this._update());}get repaint(){return !!this._repaint}set repaint(e){this._repaint!==e&&(this._repaint=e,this.triggerRepaint());}get vertices(){return !!this._vertices}set vertices(e){this._vertices=e,this._update();}get version(){return Ua}getCameraTargetElevation(){return this.transform.elevation}getProjection(){return this.style.getProjection()}setProjection(e){return this._lazyInitEmptyStyle(),this.style.setProjection(e),this._update(!0)}},e.MapMouseEvent=jr,e.MapTouchEvent=Nr,e.MapWheelEvent=Zr,e.Marker=Ka,e.NavigationControl=class{constructor(e){this._updateZoomButtons=()=>{const e=this._map.getZoom(),t=e===this._map.getMaxZoom(),i=e===this._map.getMinZoom();this._zoomInButton.disabled=t,this._zoomOutButton.disabled=i,this._zoomInButton.setAttribute(\"aria-disabled\",t.toString()),this._zoomOutButton.setAttribute(\"aria-disabled\",i.toString());},this._rotateCompassArrow=()=>{this._compassIcon.style.transform=this.options.visualizePitch&&this.options.visualizeRoll?`scale(${1/Math.pow(Math.cos(this._map.transform.pitchInRadians),.5)}) rotateZ(${-this._map.transform.roll}deg) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`:this.options.visualizePitch?`scale(${1/Math.pow(Math.cos(this._map.transform.pitchInRadians),.5)}) rotateX(${this._map.transform.pitch}deg) rotateZ(${-this._map.transform.bearing}deg)`:this.options.visualizeRoll?`rotate(${-this._map.transform.bearing-this._map.transform.roll}deg)`:`rotate(${-this._map.transform.bearing}deg)`;},this._setButtonTitle=(e,t)=>{const i=this._map._getUIString(`NavigationControl.${t}`);e.title=i,e.setAttribute(\"aria-label\",i);},this.options=t.e({},Va,e),this._container=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-group\"),this._container.addEventListener(\"contextmenu\",(e=>e.preventDefault())),this.options.showZoom&&(this._zoomInButton=this._createButton(\"maplibregl-ctrl-zoom-in\",(e=>this._map.zoomIn({},{originalEvent:e}))),n.create(\"span\",\"maplibregl-ctrl-icon\",this._zoomInButton).setAttribute(\"aria-hidden\",\"true\"),this._zoomOutButton=this._createButton(\"maplibregl-ctrl-zoom-out\",(e=>this._map.zoomOut({},{originalEvent:e}))),n.create(\"span\",\"maplibregl-ctrl-icon\",this._zoomOutButton).setAttribute(\"aria-hidden\",\"true\")),this.options.showCompass&&(this._compass=this._createButton(\"maplibregl-ctrl-compass\",(e=>{this.options.visualizePitch?this._map.resetNorthPitch({},{originalEvent:e}):this._map.resetNorth({},{originalEvent:e});})),this._compassIcon=n.create(\"span\",\"maplibregl-ctrl-icon\",this._compass),this._compassIcon.setAttribute(\"aria-hidden\",\"true\"));}onAdd(e){return this._map=e,this.options.showZoom&&(this._setButtonTitle(this._zoomInButton,\"ZoomIn\"),this._setButtonTitle(this._zoomOutButton,\"ZoomOut\"),this._map.on(\"zoom\",this._updateZoomButtons),this._updateZoomButtons()),this.options.showCompass&&(this._setButtonTitle(this._compass,\"ResetBearing\"),this.options.visualizePitch&&this._map.on(\"pitch\",this._rotateCompassArrow),this.options.visualizeRoll&&this._map.on(\"roll\",this._rotateCompassArrow),this._map.on(\"rotate\",this._rotateCompassArrow),this._rotateCompassArrow(),this._handler=new $a(this._map,this._compass,this.options.visualizePitch)),this._container}onRemove(){n.remove(this._container),this.options.showZoom&&this._map.off(\"zoom\",this._updateZoomButtons),this.options.showCompass&&(this.options.visualizePitch&&this._map.off(\"pitch\",this._rotateCompassArrow),this.options.visualizeRoll&&this._map.off(\"roll\",this._rotateCompassArrow),this._map.off(\"rotate\",this._rotateCompassArrow),this._handler.off(),delete this._handler),delete this._map;}_createButton(e,t){const i=n.create(\"button\",e,this._container);return i.type=\"button\",i.addEventListener(\"click\",t),i}},e.Popup=class extends t.E{constructor(e){super(),this._updateOpacity=()=>{void 0!==this.options.locationOccludedOpacity&&(this._container.style.opacity=this._map.transform.isLocationOccluded(this.getLngLat())?`${this.options.locationOccludedOpacity}`:void 0);},this.remove=()=>(this._content&&n.remove(this._content),this._container&&(n.remove(this._container),delete this._container),this._map&&(this._map.off(\"move\",this._update),this._map.off(\"move\",this._onClose),this._map.off(\"click\",this._onClose),this._map.off(\"remove\",this.remove),this._map.off(\"mousemove\",this._onMouseMove),this._map.off(\"mouseup\",this._onMouseUp),this._map.off(\"drag\",this._onDrag),this._map._canvasContainer.classList.remove(\"maplibregl-track-pointer\"),delete this._map,this.fire(new t.l(\"close\"))),this),this._onMouseUp=e=>{this._update(e.point);},this._onMouseMove=e=>{this._update(e.point);},this._onDrag=e=>{this._update(e.point);},this._update=e=>{if(!this._map||!this._lngLat&&!this._trackPointer||!this._content)return;if(!this._container){if(this._container=n.create(\"div\",\"maplibregl-popup\",this._map.getContainer()),this._tip=n.create(\"div\",\"maplibregl-popup-tip\",this._container),this._container.appendChild(this._content),this.options.className)for(const e of this.options.className.split(\" \"))this._container.classList.add(e);this._closeButton&&this._closeButton.setAttribute(\"aria-label\",this._map._getUIString(\"Popup.Close\")),this._trackPointer&&this._container.classList.add(\"maplibregl-popup-track-pointer\");}if(this.options.maxWidth&&this._container.style.maxWidth!==this.options.maxWidth&&(this._container.style.maxWidth=this.options.maxWidth),this._lngLat=Wa(this._lngLat,this._flatPos,this._map.transform,this._trackPointer),this._trackPointer&&!e)return;const t=this._flatPos=this._pos=this._trackPointer&&e?e:this._map.project(this._lngLat);this._map.terrain&&(this._flatPos=this._trackPointer&&e?e:this._map.transform.locationToScreenPoint(this._lngLat));let i=this.options.anchor;const o=as(this.options.offset);if(!i){const e=this._container.offsetWidth,r=this._container.offsetHeight;let a;a=t.y+o.bottom.y<r?[\"top\"]:t.y>this._map.transform.height-r?[\"bottom\"]:[],t.x<e/2?a.push(\"left\"):t.x>this._map.transform.width-e/2&&a.push(\"right\"),i=0===a.length?\"bottom\":a.join(\"-\");}let r=t.add(o[i]);this.options.subpixelPositioning||(r=r.round()),n.setTransform(this._container,`${Ha[i]} translate(${r.x}px,${r.y}px)`),Xa(this._container,i,\"popup\"),this._updateOpacity();},this._onClose=()=>{this.remove();},this.options=t.e(Object.create(os),e);}addTo(e){return this._map&&this.remove(),this._map=e,this.options.closeOnClick&&this._map.on(\"click\",this._onClose),this.options.closeOnMove&&this._map.on(\"move\",this._onClose),this._map.on(\"remove\",this.remove),this._update(),this._focusFirstElement(),this._trackPointer?(this._map.on(\"mousemove\",this._onMouseMove),this._map.on(\"mouseup\",this._onMouseUp),this._container&&this._container.classList.add(\"maplibregl-popup-track-pointer\"),this._map._canvasContainer.classList.add(\"maplibregl-track-pointer\")):this._map.on(\"move\",this._update),this.fire(new t.l(\"open\")),this}isOpen(){return !!this._map}getLngLat(){return this._lngLat}setLngLat(e){return this._lngLat=t.S.convert(e),this._pos=null,this._flatPos=null,this._trackPointer=!1,this._update(),this._map&&(this._map.on(\"move\",this._update),this._map.off(\"mousemove\",this._onMouseMove),this._container&&this._container.classList.remove(\"maplibregl-popup-track-pointer\"),this._map._canvasContainer.classList.remove(\"maplibregl-track-pointer\")),this}trackPointer(){return this._trackPointer=!0,this._pos=null,this._flatPos=null,this._update(),this._map&&(this._map.off(\"move\",this._update),this._map.on(\"mousemove\",this._onMouseMove),this._map.on(\"drag\",this._onDrag),this._container&&this._container.classList.add(\"maplibregl-popup-track-pointer\"),this._map._canvasContainer.classList.add(\"maplibregl-track-pointer\")),this}getElement(){return this._container}setText(e){return this.setDOMContent(document.createTextNode(e))}setHTML(e){const t=document.createDocumentFragment(),i=document.createElement(\"body\");let o;for(i.innerHTML=e;o=i.firstChild,o;)t.appendChild(o);return this.setDOMContent(t)}getMaxWidth(){var e;return null===(e=this._container)||void 0===e?void 0:e.style.maxWidth}setMaxWidth(e){return this.options.maxWidth=e,this._update(),this}setDOMContent(e){if(this._content)for(;this._content.hasChildNodes();)this._content.firstChild&&this._content.removeChild(this._content.firstChild);else this._content=n.create(\"div\",\"maplibregl-popup-content\",this._container);return this._content.appendChild(e),this._createCloseButton(),this._update(),this._focusFirstElement(),this}addClassName(e){return this._container&&this._container.classList.add(e),this}removeClassName(e){return this._container&&this._container.classList.remove(e),this}setOffset(e){return this.options.offset=e,this._update(),this}toggleClassName(e){if(this._container)return this._container.classList.toggle(e)}setSubpixelPositioning(e){this.options.subpixelPositioning=e;}_createCloseButton(){this.options.closeButton&&(this._closeButton=n.create(\"button\",\"maplibregl-popup-close-button\",this._content),this._closeButton.type=\"button\",this._closeButton.innerHTML=\"&#215;\",this._closeButton.addEventListener(\"click\",this._onClose));}_focusFirstElement(){if(!this.options.focusAfterOpen||!this._container)return;const e=this._container.querySelector(rs);e&&e.focus();}},e.RasterDEMTileSource=W,e.RasterTileSource=q,e.ScaleControl=class{constructor(e){this._onMove=()=>{ts(this._map,this._container,this.options);},this.setUnit=e=>{this.options.unit=e,ts(this._map,this._container,this.options);},this.options=Object.assign(Object.assign({},es),e);}getDefaultPosition(){return \"bottom-left\"}onAdd(e){return this._map=e,this._container=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-scale\",e.getContainer()),this._map.on(\"move\",this._onMove),this._onMove(),this._container}onRemove(){n.remove(this._container),this._map.off(\"move\",this._onMove),this._map=void 0;}},e.ScrollZoomHandler=va,e.Style=wi,e.TerrainControl=class{constructor(e){this._toggleTerrain=()=>{this._map.getTerrain()?this._map.setTerrain(null):this._map.setTerrain(this.options),this._updateTerrainIcon();},this._updateTerrainIcon=()=>{this._terrainButton.classList.remove(\"maplibregl-ctrl-terrain\"),this._terrainButton.classList.remove(\"maplibregl-ctrl-terrain-enabled\"),this._map.terrain?(this._terrainButton.classList.add(\"maplibregl-ctrl-terrain-enabled\"),this._terrainButton.title=this._map._getUIString(\"TerrainControl.Disable\")):(this._terrainButton.classList.add(\"maplibregl-ctrl-terrain\"),this._terrainButton.title=this._map._getUIString(\"TerrainControl.Enable\"));},this.options=e;}onAdd(e){return this._map=e,this._container=n.create(\"div\",\"maplibregl-ctrl maplibregl-ctrl-group\"),this._terrainButton=n.create(\"button\",\"maplibregl-ctrl-terrain\",this._container),n.create(\"span\",\"maplibregl-ctrl-icon\",this._terrainButton).setAttribute(\"aria-hidden\",\"true\"),this._terrainButton.type=\"button\",this._terrainButton.addEventListener(\"click\",this._toggleTerrain),this._updateTerrainIcon(),this._map.on(\"terrain\",this._updateTerrainIcon),this._container}onRemove(){n.remove(this._container),this._map.off(\"terrain\",this._updateTerrainIcon),this._map=void 0;}},e.TwoFingersTouchPitchHandler=da,e.TwoFingersTouchRotateHandler=ha,e.TwoFingersTouchZoomHandler=la,e.TwoFingersTouchZoomRotateHandler=Pa,e.VectorTileSource=$,e.VideoSource=K,e.addSourceType=(e,i)=>t._(void 0,void 0,void 0,(function*(){if(J(e))throw new Error(`A source type called \"${e}\" already exists.`);((e,t)=>{Q[e]=t;})(e,i);})),e.clearPrewarmedResources=function(){const e=A;e&&(e.isPreloaded()&&1===e.numActive()?(e.release(R),A=null):console.warn(\"Could not clear WebWorkers since there are active Map instances that still reference it. The pre-warmed WebWorker pool can only be cleared when all map instances have been removed with map.remove()\"));},e.createTileMesh=Xt,e.getMaxParallelImageRequests=function(){return t.a.MAX_PARALLEL_IMAGE_REQUESTS},e.getRTLTextPluginStatus=function(){return oe().getRTLTextPluginStatus()},e.getVersion=function(){return ss},e.getWorkerCount=function(){return z.workerCount},e.getWorkerUrl=function(){return t.a.WORKER_URL},e.importScriptInWorkers=function(e){return B().broadcast(\"IS\",e)},e.prewarm=function(){k().acquire(R);},e.setMaxParallelImageRequests=function(e){t.a.MAX_PARALLEL_IMAGE_REQUESTS=e;},e.setRTLTextPlugin=function(e,t){return oe().setRTLTextPlugin(e,t)},e.setWorkerCount=function(e){z.workerCount=e;},e.setWorkerUrl=function(e){t.a.WORKER_URL=e;};}));\n\n//\n// Our custom intro provides a specialized \"define()\" function, called by the\n// AMD modules below, that sets up the worker blob URL and then executes the\n// main module, storing its exported value as 'maplibregl'\n\n\nvar maplibregl$1 = maplibregl;\n\nreturn maplibregl$1;\n\n}));\n//# sourceMappingURL=maplibre-gl.js.map\n","modules/coach-world/vendor/provenance.json":"[\n  {\n    \"file\": \"h3.mjs\",\n    \"url\": \"https://cdn.jsdelivr.net/npm/h3-js@4.3.0/dist/h3-js.es.js\",\n    \"bytes\": 482898,\n    \"sha256\": \"5666d069cc4d1b92226c3385418a4ad1edcf3b6df9891a663a38f8b4cf57afad\",\n    \"upstreamSha256\": \"f7d985df3db21937e4daf1a93d9a66c3bc17dcaf925eb51f5f647514bb2b2d85\",\n    \"modifications\": \"Disabled Node environment detection and removed unreachable CommonJS filesystem loader. This prevents Vite SSR from injecting createRequire(import.meta.url) into Workers; embedded asm.js memory remains unchanged.\"\n  },\n  {\n    \"file\": \"h3-LICENSE.txt\",\n    \"url\": \"https://cdn.jsdelivr.net/npm/h3-js@4.3.0/LICENSE\",\n    \"bytes\": 11357,\n    \"sha256\": \"c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4\"\n  },\n  {\n    \"file\": \"maplibre-gl.js\",\n    \"url\": \"https://cdn.jsdelivr.net/npm/maplibre-gl@5.6.0/dist/maplibre-gl.js\",\n    \"bytes\": 939269,\n    \"sha256\": \"07e6ca71a5b6d835a7c3803fb484f0a6e5f0dcbfa131407666edb9e9316564f9\"\n  },\n  {\n    \"file\": \"maplibre-gl.css\",\n    \"url\": \"https://cdn.jsdelivr.net/npm/maplibre-gl@5.6.0/dist/maplibre-gl.css\",\n    \"bytes\": 69422,\n    \"sha256\": \"792ac997dcf6ae6f643eb4e2dee4630c85e7056526bd8fb85ffe83c67d6c41b4\"\n  },\n  {\n    \"file\": \"maplibre-LICENSE.txt\",\n    \"url\": \"https://cdn.jsdelivr.net/npm/maplibre-gl@5.6.0/LICENSE.txt\",\n    \"bytes\": 5984,\n    \"sha256\": \"ee5fc05a0677eaf69601d2c7db0d9ecd6cc27c3abc1d0733bc9ed34707cf8ef2\"\n  }\n]\n","modules/coach-world/view.mjs":"import {BUILDINGS,FACTIONS,FACTION_BY_ID,MAX_LEVEL,RULES} from './catalog.mjs';\r\nimport {constructionQuote} from './state.mjs';\r\nimport {unitRoster,expeditionQuote,SHIP_ROLES} from './expedition-catalog.mjs';\r\nimport {createWorldClient} from './client.mjs';\r\nimport {mountBaseScene,constructionCountdown} from './canvas-scene.mjs';\r\nimport {mountSectors} from './map-view.mjs';\r\nimport {mountCameraView} from './camera-view.mjs';\r\nimport {mountLocationDrops} from './location-drops-view.mjs';\r\n\r\nlet panel=null,cleanup=null;\r\nexport function expeditionIdForSceneUnit(unit){if(unit.role==='worker')return 'myr5-worker';if(!unit.section)return null;return unit.role==='scout'?`companion-${unit.section}-scout`:unit.role==='carrier'?`companion-${unit.section}-hauler`:['boss','grunt'].includes(unit.role)?`${unit.role}-${unit.section}`:null;}\r\nconst roleEffectText=effects=>(Array.isArray(effects)?effects:[]).map(effect=>typeof effect==='string'?effect:effect.description||effect.label).filter(Boolean).join(' / ');\r\nconst el=(tag,value,className)=>{const n=document.createElement(tag);if(value!=null)n.textContent=value;if(className)n.className=className;return n;};\r\nexport function characterWarRoomUrl(faction,environmentFaction){const id=FACTIONS.some(f=>f.id===environmentFaction)?environmentFaction:FACTIONS.some(f=>f.id===faction)?faction:FACTIONS[0].id;return `/war-room/index.html?from=world&biome=${encodeURIComponent(id)}`;}\r\nexport function openWorld({onEnterWarRoom}={}){\r\n if(panel?.open){panel.querySelector('h2').focus();return panel;}\r\n cleanup?.();if(!document.querySelector('link[data-coach-world]')){const link=document.createElement('link');link.rel='stylesheet';link.href='/modules/coach-world/world.css';link.dataset.coachWorld='';document.head.append(link);}\r\n panel??=document.createElement('dialog');panel.id='coachWorldPanel';panel.className='cw-panel';panel.setAttribute('aria-labelledby','cw-title');\r\n panel.innerHTML='<div class=\"cw-shell\"><header class=\"cw-header\"><div><span class=\"cw-eyebrow\">MYR5 / WAR ROOM</span><h2 id=\"cw-title\" tabindex=\"-1\">Your home base.</h2></div><button data-close aria-label=\"Close Coach World\">✕</button></header><nav class=\"cw-tabs\" aria-label=\"World views\"><button data-tab=\"base\" aria-selected=\"true\">Base</button><button data-tab=\"sectors\" aria-selected=\"false\">Sectors</button><button data-tab=\"camera\" aria-selected=\"false\">Camera</button></nav><div data-identity class=\"cw-identity\">Opening your world…</div><div data-content class=\"cw-content\"></div><p data-status class=\"cw-status\" role=\"status\" aria-live=\"polite\"></p></div>';\r\n if(!panel.isConnected)document.body.append(panel);panel.showModal();panel.querySelector('h2').focus();\r\n const controller=new AbortController(),signal=controller.signal,host=panel.querySelector('[data-content]'),status=panel.querySelector('[data-status]');let snapshot=null,tab='base',selected='hq',mode=null,busy=false,closed=false,timer=0,countdownTimer=0,clock=null,enteredWarRoom=false,selectedTroops=[],missionDraft=null;\r\n const client=createWorldClient({signal,onInvalidate:()=>{status.textContent='Account changed. Reopen World to continue.';panel.close();}});\r\n const alive=()=>!closed&&!signal.aborted&&panel.open;\r\n const serverNow=()=>client.authenticated&&clock?clock.server+performance.now()-clock.local:Date.now();\r\n const setSnapshot=s=>{if(!alive())return;if(client.authenticated&&Number.isFinite(s.serverTime)&&(!clock||s.serverTime>clock.server))clock={server:s.serverTime,local:performance.now()};snapshot=s;identity();};\r\n function enterWarRoom(){if(!alive()||enteredWarRoom)return;enteredWarRoom=true;const url=characterWarRoomUrl(snapshot?.base?.faction,snapshot?.environment?.faction),biome=new URL(url,location.origin).searchParams.get('biome');panel.close();if(typeof onEnterWarRoom==='function')onEnterWarRoom(url,{biome});else location.assign(url);}\r\n function beginHQEntry(){if(mode?.enterWarRoom?.()&&alive()){for(const button of host.querySelectorAll('[data-enter-war-room]'))button.disabled=true;status.textContent='Entering character War Room...';}}\r\n function updateCountdowns(){if(!alive()||tab!=='base')return;const now=serverNow();for(const node of host.querySelectorAll('[data-construction-due]')){const remaining=constructionCountdown(Number(node.dataset.constructionDue),now);node.textContent=remaining==='Ready to finish'?(node.dataset.countdownReady||'Ready to finish - syncing saved construction'):`${remaining} remaining`;}}\r\n function identity(){const f=FACTION_BY_ID[snapshot?.base?.faction]||FACTIONS[0];panel.querySelector('[data-identity]').textContent=`${f.name}  /  ${client.authenticated?'Account saved':'Personal base · saved on this device'}`;panel.style.setProperty('--cw-faction',f.color);}\r\n async function command(action){if(busy)return;busy=true;status.textContent='Saving…';try{setSnapshot(await client.command(action));if(alive()){status.textContent='Saved.';if(tab==='base')updateBase();}}catch(e){if(alive())status.textContent=e.message;}finally{busy=false;}}\r\n function updateBase(){if(!snapshot||tab!=='base')return;const base=snapshot.base,q=s=>host.querySelector(s);q('[data-fuel]').textContent=`${Math.round(base.fuel||0)} / 100`;q('[data-calm]').textContent=`${Math.round(base.calm||0)} / 100`;q('[data-charge]').textContent=String(base.launchCharge||0);q('[data-rest]').textContent=base.rest?'Resume the settlement':'Let the crew rest';q('[data-rest-note]').textContent=base.rest?'RESTING · progress and permanent levels are safe':'Crew at work · train to grow your settlement';\r\n  const list=q('[data-building-list]');list.replaceChildren();for(const def of BUILDINGS){const b=base.buildings[def.id],button=el('button',`${def.label} · ${b?.level===0?'Unbuilt':`${b?.level||1}/${MAX_LEVEL}`}${b?.job?' ◷':''}`);button.className=selected===def.id?'is-selected':'';button.onclick=()=>{selected=def.id;mode?.select?.(selected);updateBase();};if(b?.job){const countdown=el('span');countdown.dataset.constructionDue=String(b.job.dueAt);countdown.style.display='block';button.append(countdown);}list.append(button);}\r\n  const def=BUILDINGS.find(b=>b.id===selected)||BUILDINGS[0],b=base.buildings[def.id],f=FACTION_BY_ID[def.track]||FACTION_BY_ID[base.faction]||FACTIONS[0],sheet=q('[data-sheet]');sheet.replaceChildren();sheet.append(el('span',b?.level===0?`${def.kind.toUpperCase()} / UNBUILT SITE`:`${def.kind.toUpperCase()} / LEVEL ${b?.level||1} OF ${MAX_LEVEL}`,'cw-eyebrow'),el('h3',def.label),el('p',f.description,'cw-description'));\r\n  const select=el('select');select.setAttribute('aria-label','Materials to use for this upgrade');for(const faction of def.track?[f]:FACTIONS){const option=el('option',`${faction.label} · ${base.materials?.[faction.id]||0} materials`);option.value=faction.id;select.append(option);}sheet.append(select);\r\n  const next=(b?.level??1)+1,info=el('p',null,'cw-note'),progress=el('p',null,'cw-note'),prerequisites=el('p',null,'cw-note');sheet.append(info,progress,prerequisites);\r\n  const quoteText=()=>{const quote=constructionQuote(base,def.id,select.value);info.textContent=b?.job?'Construction is saved and continues while this screen is closed.':next>MAX_LEVEL?'Monument complete. This permanent level is yours.':`${b?.level===0?'Build':'Next level'}: ${quote.cost} materials / ${quote.fuelCost} fuel / ${Math.ceil((quote.durationMs||0)/60000)} min`;progress.textContent=`${quote.qualifyingDays??0} of ${quote.daysRequired??0} qualifying days. ${quote.allowed?'Ready to construct.':quote.reason||''}`;prerequisites.textContent=(quote.prerequisites||[]).map(p=>`${p.met?'Ready':'Need'}: ${BUILDINGS.find(d=>d.id===p.buildingId)?.label||p.buildingId} level ${p.level}`).join(' / ');if(quote.softCapMultiplier>1)prerequisites.textContent+=` Support balance: ${quote.softCapMultiplier.toFixed(2)}x cost and time.`;};select.onchange=quoteText;quoteText();\r\n  const actions=el('div',null,'cw-actions');if(b?.job){const due=b.job.dueAt;if(due){const countdown=el('p');countdown.dataset.constructionDue=String(due);countdown.setAttribute('role','timer');countdown.setAttribute('aria-live','off');sheet.append(countdown);}const cancel=el('button','Cancel construction');cancel.onclick=()=>command({type:'cancel',buildingId:def.id});actions.append(cancel);}else if(next<=MAX_LEVEL){const upgrade=el('button',b.level===0?'Build this site':`Upgrade to level ${next}`);upgrade.className='cw-primary';upgrade.onclick=()=>command({type:b.level===0?'build':'upgrade',buildingId:def.id,track:select.value});actions.append(upgrade);}sheet.append(actions);if(def.id==='hq'){const enter=el('button','Enter character War Room','cw-primary');enter.dataset.enterWarRoom='';enter.onclick=beginHQEntry;sheet.append(enter);}\r\n  if(def.kind==='production'){sheet.append(el('h4','Companion training'));for(const unit of unitRoster(base).filter(u=>u.faction===def.track&&u.trainable)){const card=el('div',null,'cw-training-row');card.append(el('strong',`${unit.label} / ${unit.role}`),el('p',unit.description,'cw-note'));if(unit.training){const time=el('span');time.dataset.constructionDue=String(unit.training.dueAt);time.dataset.countdownReady='Training complete - syncing crew';card.append(time);const cancel=el('button','Cancel training');cancel.onclick=()=>command({type:'cancel-training',unitId:unit.id});card.append(cancel);}else if(unit.owned)card.append(el('p','Ready for expedition duty.','cw-note'));else{const train=el('button',`Train / ${unit.materialCost} materials / ${Math.ceil(unit.trainingMs/60000)} min`);train.onclick=()=>command({type:'train-unit',unitId:unit.id});card.append(train);if(!unit.unlocked)card.append(el('p',`Requires production level ${unit.requiredLevel}.`,'cw-note'));}sheet.append(card);}}\r\n  if(!b?.job){const move=el('div',null,'cw-actions');for(const [name,dx,dy] of [['Move left',-1,0],['Move up',0,-1],['Move down',0,1],['Move right',1,0]]){const button=el('button',name);button.onclick=()=>command({type:'move',buildingId:def.id,x:b.x+dx,y:b.y+dy});move.append(button);}sheet.append(el('p','Move one plot; every entrance must remain reachable.','cw-note'),move);}\r\n  if(def.kind==='hangar'){const ships=el('select');ships.setAttribute('aria-label','Owned ship');for(const [id,hull] of Object.entries(base.ships||{})){const option=el('option',`${id} · ${hull.tier===0?'starter':`tier ${hull.tier}`}`);option.value=id;ships.append(option);}ships.value=base.selectedShip;const choose=el('button','Select ship');choose.onclick=()=>command({type:'select-ship',shipId:ships.value});sheet.append(ships,choose);}\r\n  renderExpedition();updateCountdowns();\r\n }\r\n function renderExpedition(){const node=host.querySelector('[data-expedition]');if(!node||!snapshot)return;const base=snapshot.base;node.replaceChildren();node.append(el('span','EXPEDITION STAGING','cw-eyebrow'),el('h3','Send a small crew.'));const mission=base.expedition;\r\n  if(mission){const f=FACTION_BY_ID[mission.factionId];const effects=roleEffectText(mission.roleEffects);if(effects)node.append(el('p',effects,'cw-note'));node.append(el('p',`${f?.name||'Civilization'} / ${mission.status.toUpperCase()} / ${mission.supply} of ${mission.capacity} supply`),el('p',`${mission.shipId} / ${mission.unitIds.length} roles / ${mission.materialCost} materials + ${mission.fuelCost} fuel`,'cw-note'));if(mission.status==='prepared'){const launch=el('button','Launch personal expedition','cw-primary');launch.onclick=()=>command({type:'launch-expedition'});const cancel=el('button','Cancel prepared expedition');cancel.onclick=()=>command({type:'cancel-expedition'});node.append(launch,cancel);}else if(['launched','returning'].includes(mission.status)){const timer=el('p');timer.dataset.constructionDue=String(mission.status==='returning'?mission.returnDueAt:mission.dueAt);timer.dataset.countdownReady='Journey complete - syncing your crew';timer.setAttribute('role','timer');node.append(timer);if(mission.status==='launched'){const recall=el('button','Recall crew / begin return');recall.onclick=()=>command({type:'return-expedition'});node.append(recall);}node.append(el('p','Your permanent buildings and coaches are safe while the crew travels.','cw-note'));return;}else node.append(el('p','The crew is home. You can prepare another personal mission.','cw-note'));if(mission.status==='prepared')return;}\r\n  missionDraft??={factionId:base.faction,shipId:base.selectedShip,unitIds:['myr5-worker']};const faction=el('select');faction.setAttribute('aria-label','Expedition civilization');for(const f of FACTIONS){const option=el('option',f.name);option.value=f.id;faction.append(option);}faction.value=missionDraft.factionId;const ship=el('select');ship.setAttribute('aria-label','Expedition ship');for(const [id,hull]of Object.entries(base.ships)){const option=el('option',`${id} / ${SHIP_ROLES[id]?.role||'carrier'} / ${id==='supportive'?4:4+2*(hull.tier||1)} supply`);option.value=id;ship.append(option);}ship.value=missionDraft.shipId;node.append(faction,ship);const roster=unitRoster(base).filter(u=>!u.faction||u.faction===missionDraft.factionId),list=el('div',null,'cw-role-list'),summary=el('p',null,'cw-note'),prepare=el('button','Prepare personal mission','cw-primary');\r\n  const quote=()=>{const q=expeditionQuote(base,{...missionDraft,shared:false});summary.textContent=(q.allowed?`${q.supply}/${q.capacity} supply / ${q.materialCost} materials / ${q.fuelCost} fuel / ${Math.ceil(q.durationMs/60000)} min + ${Math.ceil((q.returnDurationMs||60000)/60000)} min return`:q.reason)+(roleEffectText(q.roleEffects)?` / ${roleEffectText(q.roleEffects)}`:'');prepare.disabled=!q.allowed;};\r\n  for(const unit of roster){const label=el('label',null,'cw-role-option'),input=el('input');input.type='checkbox';input.value=unit.id;input.checked=missionDraft.unitIds.includes(unit.id);input.disabled=!unit.available;input.onchange=()=>{missionDraft.unitIds=[...list.querySelectorAll('input:checked')].map(i=>i.value);quote();};label.append(input,el('span',`${unit.label} / ${unit.role} / ${unit.supply} supply${unit.reserved?' / away':!unit.owned?' / train or unlock first':''}`));list.append(label);}node.append(list,summary);faction.onchange=()=>{missionDraft.factionId=faction.value;missionDraft.unitIds=['myr5-worker'];renderExpedition();};ship.onchange=()=>{missionDraft.shipId=ship.value;quote();};prepare.onclick=()=>command({type:'prepare-expedition',...missionDraft,shared:false});\r\n  const stage=el('button','Stage selected troops');stage.onclick=()=>{const available=new Set(roster.filter(u=>u.available).map(u=>u.id));missionDraft.unitIds=[...new Set(selectedTroops.map(expeditionIdForSceneUnit).filter(id=>available.has(id)))];status.textContent=`Staged ${missionDraft.unitIds.length} mission-ready roles. Production training prepares garrison companions for expedition duty.`;renderExpedition();};node.append(stage,prepare,el('p','Personal missions travel from your base. Nearby public battles stay in Sectors. Training unlocks expedition duty for your home companions.','cw-note'));quote();\r\n }\r\n function renderBase(){host.innerHTML='<section class=\"cw-base-layout\"><div class=\"cw-base-main\"><div class=\"cw-vitals\"><div><span>FUEL</span><b data-fuel></b></div><div><span>CALM</span><b data-calm></b></div><div><span>LAUNCH</span><b data-charge></b></div></div><div class=\"cw-scene-wrap\"><canvas class=\"cw-base-canvas\" aria-label=\"Your pixel settlement. Tap a building or use the building list below.\"></canvas><span class=\"cw-scene-tag\">PERMANENT HOME BASE</span><button class=\"cw-recenter\" data-center>Center</button></div><div class=\"cw-troop-tools\"><button data-select-troops aria-pressed=\"false\">Select troops</button><button data-clear-troops>Clear selection</button><button data-rally-hq>Rally at command</button></div><p data-troop-status class=\"cw-note\" role=\"status\">Hold still, then drag to collect troops. Short drags pan the view.</p><div class=\"cw-actions\"><button data-enter-war-room class=\"cw-primary\">Enter character War Room</button></div><p class=\"cw-note\">Tap the central command habitat to enter your character War Room.</p><p class=\"cw-note\">Drag to pan · pinch to zoom · tap a hall to upgrade</p><div data-building-list class=\"cw-building-list\" aria-label=\"Select building\"></div></div><aside class=\"cw-base-side\"><section data-sheet class=\"cw-card cw-building-sheet\"></section><section data-expedition class=\"cw-card\"></section><section class=\"cw-card\"><span class=\"cw-eyebrow\">A LITTLE CARE GOES A LONG WAY</span><h3>Keep the station humming.</h3><div class=\"cw-actions\"><button data-greet>Greet crew</button><button data-feed>Fuel station</button><button data-meditate>Calm station</button><button data-rest></button></div><p data-rest-note class=\"cw-note\"></p><p class=\"cw-note\">Fuel uses rations earned from logged food. Calm uses recorded meditation. Rest preserves every building.</p></section><section class=\"cw-card\"><h3>Your civilization</h3><select data-faction aria-label=\"Workout civilization\"></select><button data-change-faction>Choose faction</button><p class=\"cw-note\">Your workout halls stay permanent. Switching shared territory faction follows the server cooldown.</p></section></aside></section>';\r\n  const home=el('section',null,'cw-card');home.append(el('h3','A private home in the fog'),el('p','Set the place where your base lives. Strangers only see public sectors. This does not share your exact location with friends.','cw-note'));const setHome=el('button',snapshot.base.home?'Update private home here':'Set private home here');setHome.disabled=!client.authenticated;setHome.onclick=()=>{if(!navigator.geolocation){status.textContent='Location unavailable. Your base is still saved.';return;}status.textContent='Waiting for a location fix for your private home…';navigator.geolocation.getCurrentPosition(p=>{if(alive())void command({type:'home',latitude:p.coords.latitude,longitude:p.coords.longitude,consent:true});},()=>{if(alive())status.textContent='Home location was not changed. Allow location access and retry.';},{enableHighAccuracy:true,maximumAge:0,timeout:15000});};home.append(setHome);if(!client.authenticated)home.append(el('p','Sign in to set a private home anchor.','cw-note'));const dropsHost=el('section');dropsHost.dataset.locationDrops='';host.querySelector('.cw-base-side').append(home,dropsHost);\r\n  const sceneMode=mountBaseScene(host.querySelector('canvas'),{getBase:()=>snapshot?.base,getServerTime:serverNow,onEnterWarRoom:enterWarRoom,onSelectionChange:detail=>{selectedTroops=detail.units;const node=host.querySelector('[data-troop-status]');if(node)node.textContent=detail.count?`${detail.count} troops selected. Tap empty ground to rally; drag a box to refine selection.`:'Hold still, then drag to collect troops. Short drags pan the view.';host.querySelector('[data-select-troops]')?.setAttribute('aria-pressed',String(detail.selectionMode));},onRally:detail=>{status.textContent=`${detail.count} troops moving to the rally point.`;},onSelect:id=>{selected=id;updateBase();}});const dropsMode=mountLocationDrops(dropsHost,{client,signal});mode={...sceneMode,dispose(){dropsMode.dispose();sceneMode.dispose();}};for(const button of host.querySelectorAll('[data-enter-war-room]'))button.onclick=beginHQEntry;host.querySelector('[data-center]').onclick=()=>mode.recenter();host.querySelector('[data-select-troops]').onclick=()=>mode.selectTroops();host.querySelector('[data-clear-troops]').onclick=()=>mode.clearSelection();host.querySelector('[data-rally-hq]').onclick=()=>{if(!mode.rallyAtHQ())status.textContent=snapshot.base.rest?'Resume the settlement before giving rally orders.':'Select available troops first.';};host.querySelector('[data-greet]').onclick=()=>command({type:'care',kind:'greet'});host.querySelector('[data-feed]').onclick=()=>command({type:'care',kind:'fuel'});host.querySelector('[data-meditate]').onclick=()=>command({type:'care',kind:'meditate'});host.querySelector('[data-rest]').onclick=()=>command({type:'rest',value:!snapshot.base.rest});const select=host.querySelector('[data-faction]');for(const f of FACTIONS){const o=el('option',`${f.label} / ${f.name}`);o.value=f.id;select.append(o);}select.value=snapshot.base.faction;host.querySelector('[data-change-faction]').onclick=()=>command({type:'faction',factionId:select.value});updateBase();\r\n }\r\n function show(next){if(!alive())return;tab=next;mode?.dispose();mode=null;host.replaceChildren();for(const button of panel.querySelectorAll('[data-tab]'))button.setAttribute('aria-selected',String(button.dataset.tab===tab));if(!snapshot){host.append(el('p','Loading your saved base…','cw-loading'));return;}if(tab==='base')renderBase();else if(tab==='sectors')mode=mountSectors(host,{client,signal,onSnapshot:setSnapshot});else mode=mountCameraView(host,{getBase:()=>snapshot.base,signal,loadFriends:client.authenticated?center=>client.map(center):async()=>({friends:[]})});}\r\n for(const button of panel.querySelectorAll('[data-tab]'))button.onclick=()=>show(button.dataset.tab);panel.querySelector('[data-close]').onclick=()=>panel.close();\r\n const dispose=()=>{if(closed)return;closed=true;controller.abort();mode?.dispose();mode=null;clearInterval(timer);clearInterval(countdownTimer);client.dispose();};cleanup=dispose;panel.addEventListener('close',dispose,{once:true});globalThis.addEventListener('pagehide',()=>panel.close(),{signal});\r\n void client.load().then(s=>{if(alive()){setSnapshot(s);show(tab);}}).catch(e=>{if(alive()){status.textContent=e.message;host.append(el('button','Retry opening World','cw-button'));host.lastChild.onclick=()=>{panel.close();openWorld();};}});\r\n countdownTimer=setInterval(updateCountdowns,1000);\r\n timer=setInterval(()=>{if(alive()&&tab==='base'&&!busy&&(Object.values(snapshot?.base?.buildings||{}).some(b=>b.job)||Object.keys(snapshot?.base?.training||{}).length||['launched','returning'].includes(snapshot?.base?.expedition?.status)))void command({type:client.authenticated?'tick':'rest',...(client.authenticated?{}:{value:snapshot.base.rest})});},30000);\r\n return panel;\r\n}\r\n","modules/coach-world/world-nodes.mjs":"import {FACTIONS,FACTION_BY_ID} from './catalog.mjs';\r\nimport {WORLD_SITES} from './sites.mjs';\r\nimport {cellToBoundary,cellToLatLng,latLngToCell,containsPoint} from './geo.mjs';\r\nimport {isValidCell,getResolution} from './vendor/h3.mjs';\r\n\r\n// Display catalog only. These nodes never grant materials or authorize visits.\r\nexport const RESOURCE_NODE_TYPES=Object.freeze(Object.fromEntries([\r\n ['chest','press-alloy','Pressforge compression ore','pressed-ore'],\r\n ['quads','stride-basalt','Stride Citadel squatstone','stepped-crystal'],\r\n ['glutes','thrustroot-seed','Thrustroot growth pods','root-pod'],\r\n ['arms-shoulders','orbit-conductor','Orbit Arsenal conductor coils','coil-cluster'],\r\n ['yoga','stillwave-prism','Stillwave balance prisms','balanced-prism'],\r\n ['martial-arts','moltguard-chitin','Moltguard training husks','folded-husk'],\r\n ['cardio','pulseway-cell','Pulseway turbine cells','turbine-cell'],\r\n].map(([faction,kind,label,shape])=>[faction,Object.freeze({faction,kind,label,shape,spriteKey:`resource-${faction}`})])));\r\nconst NEUTRAL=Object.freeze({faction:'neutral',kind:'unclaimed-mineral',label:'Unclaimed mineral formation',shape:'mineral-cluster',spriteKey:'resource-neutral'});\r\nconst SITES=Object.freeze(Object.fromEntries(WORLD_SITES.map(site=>[site.id,site])));\r\nconst phase=value=>['stable','warzone','contested','converting','healing'].includes(value)?value:'neutral';\r\nconst knownFaction=value=>Object.hasOwn(FACTION_BY_ID,value)?value:null;\r\nfunction hash(value){let result=2166136261;for(const c of String(value))result=Math.imul(result^c.charCodeAt(0),16777619)>>>0;return result;}\r\nfunction random(seed){let state=hash(seed);return ()=>{state=(Math.imul(state,1664525)+1013904223)>>>0;return state/4294967296;};}\r\nconst wrap=longitude=>((longitude+180)%360+360)%360-180;\r\nconst unwrap=(longitude,anchor)=>anchor+wrap(longitude-anchor);\r\nconst cellsOnly=id=>typeof id==='string'&&isValidCell(id)&&getResolution(id)===10;\r\nfunction cellGeometry(id){const [lat,lng]=cellToLatLng(id),ring=cellToBoundary(id,true);ring.push([...ring[0]]);return {lat,lng,geometry:{type:'Polygon',coordinates:[ring]}};}\r\nfunction interior(geometry,seed,anchor,extra=()=>true){\r\n const reference=anchor.lng,polygons=geometry.type==='MultiPolygon'?geometry.coordinates:[geometry.coordinates],normalized={type:'MultiPolygon',coordinates:polygons.map(p=>p.map(r=>r.map(([lng,lat])=>[unwrap(lng,reference),lat])))};\r\n const rings=normalized.coordinates.map(p=>p[0]).filter(r=>r?.length>=4),points=rings.flat();if(!points.length)return null;\r\n const west=Math.min(...points.map(p=>p[0])),east=Math.max(...points.map(p=>p[0])),south=Math.min(...points.map(p=>p[1])),north=Math.max(...points.map(p=>p[1])),rng=random(seed);\r\n for(let i=0;i<96;i++){const lng=west+(east-west)*(.12+.76*rng()),lat=south+(north-south)*(.12+.76*rng());if(containsPoint(normalized,lat,lng)&&extra(lat,wrap(lng)))return {lat,lng:wrap(lng)};}\r\n if(containsPoint(normalized,anchor.lat,reference)&&extra(anchor.lat,anchor.lng))return anchor;return null;\r\n}\r\nfunction factionFor(sector,fallback=null){return knownFaction(sector?.controller)||knownFaction(sector?.faction)||knownFaction(sector?.initialFaction)||knownFaction(fallback)||'neutral';}\r\nfunction baseNode({id,type,kind,faction,point,label,sectorId=null,siteId=null,phase:state='neutral',spriteKey,shape,referenceOnly=false}){\r\n return {id,type,kind,faction,lat:point.lat,lng:point.lng,latitude:point.lat,longitude:point.lng,label,sectorId,siteId,phase:state,spriteKey,shape,interactive:type==='public-hub',inspectable:true,harvestable:false,harvestStatus:type==='resource'?'cosmetic-only-no-harvest':null,rewardAuthority:'server-workout-records',isVenue:type==='public-hub',referenceOnly,canNavigate:false,walkabilityVerified:false,actions:type==='public-hub'?['inspect-existing-hub']:['inspect-scenery']};\r\n}\r\n/** Anonymous public H3 display geometry in, original decorative nodes out.\r\n * Never pass private bases/friend landmarks. Unknown fields and input coordinates\r\n * are deliberately ignored: sector positions come from canonical H3 geometry;\r\n * hub positions come only from the existing seven-site public catalog.\r\n */\r\nexport function buildWorldNodes(sectors=[],sites=[],options={}){\r\n options=options&&typeof options==='object'?options:{};\r\n const version=Number.isSafeInteger(options.version)&&options.version>0?options.version:1,maxNodes=Number.isFinite(options.maxNodes)?Math.max(0,Math.min(512,Math.floor(options.maxNodes))):256,density=Number.isFinite(options.resourceDensity)?Math.max(0,Math.min(1,options.resourceDensity)):.65,publicModulo=Number.isSafeInteger(options.publicNodeModulo)&&options.publicNodeModulo>0?options.publicNodeModulo:1;\r\n const sectorMap=new Map();for(const value of Array.isArray(sectors)?sectors:[]){if(!value||!cellsOnly(value.id)||value.enabled===false)continue;const previous=sectorMap.get(value.id),revision=Number.isSafeInteger(value.revision)?value.revision:0,previousRevision=Number.isSafeInteger(previous?.revision)?previous.revision:0,signature=v=>JSON.stringify([factionFor(v),phase(v?.phase)]);if(!previous||revision>previousRevision||(revision===previousRevision&&signature(value)>signature(previous)))sectorMap.set(value.id,value);}\r\n const publicSites=new Map();for(const supplied of Array.isArray(sites)?sites:[]){const site=Object.hasOwn(SITES,supplied?.id)?SITES[supplied.id]:null;if(site&&site.enabled&&supplied.enabled!==false)publicSites.set(site.id,site);}\r\n const hubs=[],props=[],resources=[];\r\n for(const site of [...publicSites.values()].sort((a,b)=>a.id.localeCompare(b.id))){\r\n  const center={lat:site.latitude,lng:site.longitude},sectorId=latLngToCell(center.lat,center.lng,10),sector=sectorMap.get(sectorId),faction=factionFor(sector,site.faction),state=phase(sector?.phase),definition=FACTION_BY_ID[faction];\r\n  hubs.push(baseNode({id:`world-node:v${version}:hub:${site.id}`,type:'public-hub',kind:'existing-public-hub',faction,point:center,label:site.name,sectorId,siteId:site.id,phase:state,spriteKey:`hub-${faction}`,shape:'public-outpost',referenceOnly:true}));\r\n  if(hash(`public:${site.id}`)%publicModulo!==0)continue;\r\n  const point=interior(site.geometry,`public:${version}:${site.id}`,center);if(!point)continue;const propSectorId=latLngToCell(point.lat,point.lng,10),propSector=sectorMap.get(propSectorId),propFaction=factionFor(propSector,site.faction);\r\n  props.push(baseNode({id:`world-node:v${version}:public:${site.id}`,type:'public-node',kind:'training-relay',faction:propFaction,point,label:`${FACTION_BY_ID[propFaction]?.name||definition?.name||'Alien'} training relay`,sectorId:propSectorId,siteId:site.id,phase:phase(propSector?.phase),spriteKey:`public-${propFaction}`,shape:'training-relay'}));\r\n }\r\n for(const sector of [...sectorMap.values()].sort((a,b)=>a.id.localeCompare(b.id))){\r\n  if(hubs.length+props.length+resources.length>=maxNodes)break;\r\n  if(hash(`resource-density:${version}:${sector.id}`)/4294967296>=density)continue;\r\n  const shape=cellGeometry(sector.id),site=Object.hasOwn(SITES,sector.siteId)?SITES[sector.siteId]:null,point=interior(shape.geometry,`resource:${version}:${sector.id}`,{lat:shape.lat,lng:shape.lng},(lat,lng)=>latLngToCell(lat,lng,10)===sector.id&&(!site||containsPoint(site.geometry,lat,lng)));if(!point)continue;\r\n  const faction=factionFor(sector),resource=RESOURCE_NODE_TYPES[faction]||NEUTRAL;\r\n  resources.push(baseNode({id:`world-node:v${version}:resource:${sector.id}`,type:'resource',kind:resource.kind,faction,point,label:resource.label,sectorId:sector.id,siteId:site?.id??null,phase:phase(sector.phase),spriteKey:resource.spriteKey,shape:resource.shape}));\r\n }\r\n // Existing hub markers get priority. No generated prop becomes a new venue.\r\n return [...hubs,...props,...resources].slice(0,maxNodes);\r\n}\r\n","modules/coach-world/world.css":".cw-panel{--cw-faction:#88c6ae;--cw-ink:#e5eee8;--cw-muted:#a8b8b5;color:var(--cw-ink);background:#101e24;border:1px solid #5c7466;border-radius:18px;width:min(1180px,100vw - 20px);height:min(930px,100dvh - 20px);max-height:calc(100dvh - 20px);max-width:calc(100vw - 20px);padding:0;box-shadow:0 24px 120px #000b;font:14px/1.5 system-ui,sans-serif}.cw-panel::backdrop{background:#040d15cf;backdrop-filter:blur(8px)}.cw-panel *{box-sizing:border-box}.cw-shell{min-height:100%;display:flex;flex-direction:column}.cw-header{display:flex;align-items:center;justify-content:space-between;padding:22px 24px 16px;border-bottom:1px solid #ffffff13;background:radial-gradient(ellipse at 15% 0,#36514780,transparent 70%)}.cw-panel h2{font:700 clamp(23px,4vw,36px)/1.1 system-ui;margin:8px 0 0;letter-spacing:-1.5px}.cw-panel h3{font-size:20px;line-height:1.2;margin:7px 0 12px;letter-spacing:-.5px}.cw-eyebrow{font:700 10px/1.3 ui-monospace,monospace;letter-spacing:2px;color:#c9d4ac}.cw-panel p{margin:9px 0 14px}.cw-panel button,.cw-button,.cw-panel select,.cw-panel input{font:600 13px/1.3 system-ui;color:var(--cw-ink);background:#25363c;border:1px solid #526266;border-radius:8px;min-height:44px;padding:11px 14px;max-width:100%}.cw-panel button{cursor:pointer}.cw-panel button:hover{background:#354c4e}.cw-panel button:focus-visible,.cw-panel a:focus-visible,.cw-panel select:focus-visible,.cw-panel input:focus-visible{outline:3px solid #f6d58c;outline-offset:3px}.cw-panel button:disabled{opacity:.45;cursor:default}.cw-panel input{width:190px;min-width:0}.cw-panel a{color:#b8daca}.cw-panel .cw-primary,.cw-panel button[aria-selected=true]{background:#c5d5ad;color:#182b28;border-color:#e5e8bd}.cw-tabs{display:flex;gap:6px;padding:12px 24px 0}.cw-tabs button{flex:1;max-width:180px}.cw-identity{padding:12px 24px;font:11px ui-monospace,monospace;color:var(--cw-muted);border-bottom:1px solid #ffffff12}.cw-content{padding:20px 24px;flex:1;min-height:260px}.cw-base-layout{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(270px,1fr);gap:20px}.cw-base-main,.cw-base-side{min-width:0}.cw-vitals{display:flex;gap:8px;margin-bottom:10px}.cw-vitals>div{background:#1e3138;border:1px solid #52655a66;padding:8px 12px;flex:1;border-radius:8px}.cw-vitals span{display:block;font:9px ui-monospace,monospace;color:#c8d7bb;letter-spacing:1.5px}.cw-vitals b{font:600 17px ui-monospace,monospace}.cw-scene-wrap{position:relative;border:1px solid #52655a88;border-radius:12px;overflow:hidden;background:#0d1924;isolation:isolate}.cw-base-canvas{width:100%;height:470px;display:block;touch-action:none;image-rendering:pixelated}.cw-scene-tag{position:absolute;top:12px;left:13px;color:#c5d5ad;font:9px ui-monospace,monospace;letter-spacing:1.5px;pointer-events:none}.cw-panel .cw-recenter{position:absolute;right:10px;bottom:10px;background:#12242dcc}.cw-note{font-size:12px;color:var(--cw-muted);line-height:1.55}.cw-card{background:linear-gradient(135deg,#25383c,#1c2d33);padding:18px;border:1px solid #60726366;border-radius:12px;margin-bottom:14px}.cw-card select{width:100%;margin-bottom:8px}.cw-actions{display:flex;flex-wrap:wrap;gap:8px;margin:12px 0 4px}.cw-building-list{display:flex;gap:7px;overflow:auto;padding:3px 2px 10px;scrollbar-width:thin}.cw-building-list button{flex-shrink:0;font-size:11px}.cw-building-list .is-selected{border-color:#d4dda8;color:#e7edc5;background:#3c5148}.cw-description{color:#d5ded6;font-size:13px}.cw-status{padding:0 24px 12px;color:#dfd7a9;min-height:23px}.cw-loading{padding:50px 0;text-align:center}.cw-sector-intro h3{font-size:32px}.cw-sector-intro{max-width:650px}.cw-sector-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(135px,1fr));gap:8px;margin:15px 0 25px}.cw-sector-tile{border:1px solid #6b7b7466;border-top:4px solid var(--sector-color);padding:12px;min-height:100px;background:linear-gradient(130deg,#243338,#18282e);border-radius:8px;display:flex;flex-direction:column;gap:4px;overflow:hidden}.cw-sector-tile strong{overflow-wrap:anywhere;font-size:11px}.cw-sector-tile span,.cw-sector-tile small{font-size:11px;color:#b8c7c1}.cw-sector-tile b{font:9px ui-monospace,monospace;color:#dbc9a2}.cw-sector-tile.is-scarred{background:repeating-linear-gradient(135deg,#3b3431 0 5px,#292e32 5px 18px);box-shadow:inset 0 -30px 35px #050d14aa}.cw-map{height:340px;border-radius:12px;overflow:hidden;margin:12px 0}.cw-map .maplibregl-ctrl-attrib{color:#111;font-size:10px}.cw-map .maplibregl-ctrl-attrib a{color:#233}.cw-camera-stage{height:480px;position:relative;background:radial-gradient(ellipse at 50% 70%,#566d67,#152437 65%);overflow:hidden;border:1px solid #52655a88;border-radius:12px}.cw-camera-stage video,.cw-camera-stage canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.cw-camera-stage canvas{touch-action:none}.cw-camera-label{position:absolute;bottom:12px;left:12px;background:#071422bb;padding:7px 12px;border-radius:6px;font:11px ui-monospace,monospace;pointer-events:none}.cw-photo{position:fixed;inset:12px;z-index:5;background:#10232b;overflow:auto;border:1px solid #c7d7b3;padding:16px;border-radius:12px;box-shadow:0 10px 90px #000;display:flex;gap:10px;flex-wrap:wrap;align-content:center;justify-content:center}.cw-photo img{max-width:100%;max-height:75dvh;object-fit:contain;width:100%}.cw-photo a{display:inline-flex;align-items:center;text-decoration:none}.cw-photo p{width:100%;text-align:center}\r\n@media(max-width:680px){.cw-panel{width:100vw;height:100dvh;max-width:100vw;max-height:100dvh;border-radius:0;border:0}.cw-header{padding:18px 16px 14px;padding-top:max(18px,env(safe-area-inset-top))}.cw-tabs{padding:12px 16px 0}.cw-identity{padding:11px 16px}.cw-content{padding:15px 12px}.cw-base-layout{display:block}.cw-base-canvas{height:370px}.cw-card{padding:16px}.cw-base-side{margin-top:14px}.cw-status{padding:0 16px max(16px,env(safe-area-inset-bottom))}.cw-camera-stage{height:440px}.cw-panel input{flex:1;min-width:120px}.cw-building-list{margin-bottom:6px}.cw-vitals>div{padding:8px}.cw-vitals b{font-size:15px}}\r\n@media(max-height:500px) and (orientation:landscape){.cw-panel{width:100vw;height:100dvh;max-height:100dvh;max-width:100vw;border-radius:0}.cw-header{padding:10px 18px}.cw-header h2{font-size:24px}.cw-tabs{position:absolute;right:76px;top:9px;padding:0}.cw-tabs button{min-height:38px;padding:8px 18px}.cw-content{padding-top:12px}.cw-base-layout{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(250px,1fr)}.cw-base-canvas{height:310px}.cw-camera-stage{height:calc(100dvh - 175px);min-height:230px}.cw-base-side{margin-top:0}}\r\n@media(prefers-reduced-motion:reduce){.cw-panel *{scroll-behavior:auto;animation:none!important}}\r\n.cw-check{display:flex;align-items:center;gap:10px;font-size:12px;color:var(--cw-muted);margin:15px 0}.cw-panel .cw-check input{min-width:22px;width:22px;height:22px;min-height:22px;flex:0 0 22px;accent-color:#bdd5a4}.cw-hub-art{float:right;width:110px;height:75px;image-rendering:pixelated;pointer-events:none}.cw-card::after{content:\"\";display:block;clear:both}\r\n.cw-panel:has(#coachDock) .cw-shell{padding-bottom:calc(96px + env(safe-area-inset-bottom,0px))}.cw-panel:has(#coachDock) .cw-status{padding-bottom:16px}\r\n\r\n.cw-troop-tools{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}.cw-troop-tools button{flex:1 1 110px;font-size:11px}.cw-troop-tools button[aria-pressed=\"true\"]{border-color:#eee1a7;background:#4a5140}.cw-base-canvas[data-troop-gesture=\"select\"]{cursor:crosshair}.cw-role-list{display:grid;gap:6px;margin:12px 0}.cw-role-option{display:flex;align-items:center;gap:10px;padding:10px;background:#07182155;border:1px solid #91aa8c33;border-radius:6px;font-size:12px;min-height:44px}.cw-panel .cw-role-option input{width:22px;min-width:22px;height:22px;min-height:22px;flex:0 0 22px;margin:0;accent-color:#c8d89a}.cw-role-option:has(input:disabled){color:#99aaa7}.cw-training-row{padding:12px 0;border-top:1px solid #91aa8c44}.cw-training-row strong{font-size:12px}.cw-training-row button{margin-top:8px}.cw-card[data-expedition]>button{margin:4px 4px 4px 0}\r\n.cw-drop-card{padding:12px;margin:10px 0;border:1px solid #91aa8c33;border-radius:8px;background:#07182144}.cw-drop-card h4{margin:0 0 8px;font-size:14px}.cw-drop-card .cw-actions button{flex:1 1 110px;font-size:11px}.cw-drop-card .cw-note{overflow-wrap:anywhere}\r\n","modules/graphics-lifecycle.mjs":"// Serialize renderer handoffs around the browser's asynchronous WebGL context-loss event.\r\n// Drivers can mark a context lost immediately while keeping its slot reserved until that event.\r\n// State lives on globalThis: app-runtime, launch-runtime and the raw modules each bundle their own copy of this file.\r\nconst G=globalThis.__myr5Graphics??={pending:new Set(),releasing:new WeakMap(),claims:new Set()};\r\nconst {pending,releasing}=G;\r\n\r\nexport function releaseGraphics(canvas,gl,release,{deadlineMs=250}={}){\r\n if(!canvas||!gl){try{release?.();}catch{}return Promise.resolve();}\r\n const existing=releasing.get(canvas);if(existing)return existing;\r\n let resolvePromise,timer=0,settled=false;\r\n const promise=new Promise(resolve=>{resolvePromise=resolve;});\r\n const finish=()=>{\r\n  if(settled)return;settled=true;clearTimeout(timer);canvas.removeEventListener('webglcontextlost',finish);pending.delete(promise);if(releasing.get(canvas)===promise)releasing.delete(canvas);resolvePromise();\r\n };\r\n pending.add(promise);releasing.set(canvas,promise);\r\n canvas.addEventListener('webglcontextlost',finish,{once:true});\r\n timer=setTimeout(finish,Math.max(0,deadlineMs)); // Broken drivers may omit the event; never stall navigation indefinitely.\r\n try{release?.();}catch{finish();}\r\n return promise;\r\n}\r\n\r\nexport async function waitForGraphicsRelease(){\r\n while(pending.size)await Promise.all([...pending]);\r\n}\r\n\r\n// A 3D screen claims the GPU before it creates its renderer: every long-lived renderer that listens for 'myr5:graphics-claim'\r\n// (the 3D coach = 'coach', the portal board/tunnel/peek = 'portal') gives its context back for real (detail.wait(promise)\r\n// until the loss lands) unless the claim keeps it, and rebuilds on 'myr5:graphics-free' once no claim excludes it.\r\n// iOS refuses new contexts while hidden ones still hold GPU memory (\"Error creating WebGL context\").\r\n// Returns release(); await release.ready before creating the renderer, call release(canvas) right after forceContextLoss\r\n// so the holders rebuild only once that context's loss has landed.\r\nexport function claimGraphics(owner,{keep=[]}={}){\r\n const claim={owner,keep};G.claims.add(claim);let done=false;const waits=[];\r\n const release=canvas=>{if(done)return;done=true;G.claims.delete(claim);\r\n  const lost=canvas?.addEventListener?new Promise(r=>{canvas.addEventListener('webglcontextlost',r,{once:true});setTimeout(r,250);}):null;\r\n  void Promise.resolve(lost).then(waitForGraphicsRelease).then(()=>{if(!G.claims.has(claim))dispatchEvent(new CustomEvent('myr5:graphics-free',{detail:{owner}}));});};\r\n try{dispatchEvent(new CustomEvent('myr5:graphics-claim',{detail:{owner,keep,wait:p=>waits.push(Promise.resolve(p).catch(()=>{}))}}));}catch{}\r\n release.ready=Promise.all(waits).then(waitForGraphicsRelease);\r\n return release;\r\n}\r\n// Is a holder ('coach', 'portal') kept off the GPU by a live claim?\r\nexport const graphicsBlocked=holder=>[...G.claims].some(c=>!c.keep.includes(holder));\r\n","modules/materials/chunk-delivery.mjs":"/** P13H: signed ordered chunks are the aggregate integrity guarantee; never assemble an asset. */\r\nimport { productionMaterialResourcePolicy } from './material-config.mjs';\r\nconst enc = new TextEncoder(), HEX = /^[a-f0-9]{64}$/i, ID = /^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,62})$/, OWNER = /^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/;\r\nconst plain = x => x && typeof x === 'object' && !Array.isArray(x), stable = x => Array.isArray(x) ? x.map(stable) : plain(x) ? Object.fromEntries(Object.keys(x).sort().map(k => [k, stable(x[k])])) : x;\r\nconst id = x => typeof x === 'string' && ID.test(x), safePath = x => typeof x === 'string' && /^assets\\/[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(x) && !x.includes('..') && !x.includes('//');\r\nasync function hash(data) { const b = data instanceof Uint8Array ? data : new Uint8Array(data); if (!globalThis.crypto?.subtle) throw new Error('WebCrypto is required for material chunk verification'); return [...new Uint8Array(await crypto.subtle.digest('SHA-256', b))].map(x => x.toString(16).padStart(2, '0')).join(''); }\r\nconst b64 = x => Uint8Array.from((typeof atob === 'function' ? atob(x) : Buffer.from(x, 'base64').toString('binary')), c => c.charCodeAt(0));\r\nconst productionPolicy=productionMaterialResourcePolicy();\r\nexport const DEFAULT_LOCAL_RESOURCE_POLICY = Object.freeze({ maxChunkBytes: 1024 * 1024, maxAssetBytes: 64 * 1024 * 1024, maxPackBytes: 128 * 1024 * 1024, maxAssets: 16, maxChunksPerAsset: 256, trustedOrigins: productionPolicy?.trustedOrigins??Object.freeze(typeof location === 'undefined' ? [] : [location.origin]), allowedProtocols: productionPolicy?.allowedProtocols??Object.freeze(['https:']), pathPrefix: productionPolicy?.pathPrefix??'/materials/' });\r\nexport const canonicalChunkPayload = m => JSON.stringify(stable({ schema: 'mom-material-chunks-v1', packId: m.packId, version: m.version, keyId: m.keyId, assets: m.assets.map(a => ({ path:a.path, bytes:a.bytes, sha256:a.sha256, chunks:a.chunks.map(c => ({ index:c.index, offset:c.offset, bytes:c.bytes, sha256:c.sha256, url:c.url, etag:c.etag })) })) }));\r\nfunction trustedUrl(value, policy) { try { const u = new URL(value); return (policy.trustedOrigins || []).includes(u.origin) && (policy.allowedProtocols || []).includes(u.protocol) && typeof policy.pathPrefix === 'string' && u.pathname.startsWith(policy.pathPrefix); } catch { return false; } }\r\n// Raw GitHub serves byte ranges but does not CORS-expose Content-Range. Only\r\n// this exact immutable host may use the signed chunk digest as its offset proof.\r\n// All status, length, streamed-size, signature, hash and ownership checks remain.\r\nfunction pinnedRawCorsRange(requested,response,policy){\r\n if(response.type!=='cors'||policy.trustedOrigins?.length!==1||policy.trustedOrigins[0]!=='https://raw.githubusercontent.com'||policy.allowedProtocols?.length!==1||policy.allowedProtocols[0]!=='https:'||!/^\\/[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/[a-f0-9]{40}\\/materials\\/$/.test(policy.pathPrefix))return false;\r\n try{const request=new URL(requested),final=new URL(response.url);return requested===request.href&&request.href===final.href&&trustedUrl(request.href,policy)&&trustedUrl(final.href,policy)&&!request.username&&!request.password&&!request.search&&!request.hash&&/^[A-Za-z0-9._/-]+$/.test(request.pathname)&&!request.pathname.includes('..')&&!request.pathname.includes('//');}catch{return false;}\r\n}\r\nexport function validateChunkManifest(m, policy = DEFAULT_LOCAL_RESOURCE_POLICY) { if (!plain(m) || m.schema !== 'mom-material-chunks-v1' || !id(m.packId) || !id(m.version) || !id(m.keyId) || !Array.isArray(m.assets) || typeof m.signature !== 'string') throw new Error('invalid chunk manifest shape'); if (!Number.isSafeInteger(policy.maxChunkBytes) || policy.maxChunkBytes < 1 || !Array.isArray(policy.trustedOrigins) || !Array.isArray(policy.allowedProtocols)) throw new Error('invalid local resource policy'); if (m.assets.length < 1 || m.assets.length > policy.maxAssets) throw new Error('asset count exceeds local policy'); const paths = new Set(); let total = 0; for (const a of m.assets) { if (!plain(a) || !safePath(a.path) || paths.has(a.path) || !Number.isSafeInteger(a.bytes) || a.bytes < 1 || a.bytes > policy.maxAssetBytes || !HEX.test(a.sha256) || !Array.isArray(a.chunks) || !a.chunks.length || a.chunks.length > policy.maxChunksPerAsset) throw new Error('invalid chunk asset'); paths.add(a.path); total += a.bytes; let offset = 0; for (let i=0;i<a.chunks.length;i++) { const c=a.chunks[i]; if (!plain(c) || c.index !== i || c.offset !== offset || !Number.isSafeInteger(c.bytes) || c.bytes < 1 || c.bytes > policy.maxChunkBytes || !HEX.test(c.sha256) || !trustedUrl(c.url,policy) || (c.etag !== undefined && (typeof c.etag !== 'string' || c.etag.length > 512))) throw new Error('invalid chunk ordering, URL, or record'); offset += c.bytes; } if(offset !== a.bytes) throw new Error('chunk sizes do not equal asset size'); } if(total > policy.maxPackBytes) throw new Error('pack exceeds local policy'); return true; }\r\nexport async function verifyChunkManifest(m, key, policy) { validateChunkManifest(m,policy); if(!plain(key)||key.kty!=='OKP'||key.crv!=='Ed25519') throw new Error('invalid material trust key'); const subtle=globalThis.crypto?.subtle; if(!subtle) throw new Error('WebCrypto is required for chunk manifest verification'); const trusted=await subtle.importKey('jwk',key,{name:'Ed25519'},false,['verify']); if(!await subtle.verify({name:'Ed25519'},trusted,b64(m.signature),enc.encode(canonicalChunkPayload(m)))) throw new Error('chunk manifest signature is invalid'); return true; }\r\n/** Test fixture only. Production callers use indexedDbChunkStore. */\r\nexport function memoryChunkStore({maxBytes=DEFAULT_LOCAL_RESOURCE_POLICY.maxPackBytes}={}) { const data=new Map();let used=0;return {maxBytes,get usedBytes(){return used},async get(k){const v=data.get(k);return v&&new Uint8Array(v)},async put(k,v){const b=new Uint8Array(v),old=data.get(k)?.byteLength??0;if(used-old+b.byteLength>maxBytes)throw new Error('chunk-store quota exceeded');data.set(k,new Uint8Array(b));used+=b.byteLength-old},async removePrefix(p){for(const k of [...data.keys()])if(k.startsWith(p)){used-=data.get(k).byteLength;data.delete(k)}}}; }\r\n/** Durable per-origin IndexedDB storage; read/write copies prevent mutation of saved chunks. */\r\nexport function indexedDbChunkStore({database='mom-material-chunks-v1',storeName='chunks'}={}) { if(!globalThis.indexedDB)throw new Error('IndexedDB durable storage is required');const open=new Promise((ok,no)=>{const r=indexedDB.open(database,1);r.onupgradeneeded=()=>r.result.createObjectStore(storeName);r.onsuccess=()=>ok(r.result);r.onerror=()=>no(r.error)});const run=async(mode,fn)=>{const db=await open;return new Promise((ok,no)=>{const t=db.transaction(storeName,mode),s=t.objectStore(storeName);let r;try{r=fn(s)}catch(e){t.abort();no(e);return}t.oncomplete=()=>ok(r?.result);t.onerror=()=>no(t.error||r?.error);t.onabort=()=>no(t.error||new Error('chunk-store transaction aborted'))})};return {async get(k){return run('readonly',s=>s.get(k)).then(v=>v&&new Uint8Array(v))},async put(k,v){return run('readwrite',s=>s.put(new Uint8Array(v),k))},async removePrefix(p){const db=await open;return new Promise((ok,no)=>{const t=db.transaction(storeName,'readwrite'),r=t.objectStore(storeName).openCursor();r.onsuccess=()=>{const c=r.result;if(!c)return;if(typeof c.key==='string'&&c.key.startsWith(p))c.delete();c.continue()};t.oncomplete=ok;t.onerror=()=>no(t.error)})}}; }\r\nexport class ChunkDownloader {\r\n constructor({store,fetchImpl=globalThis.fetch,policy=DEFAULT_LOCAL_RESOURCE_POLICY,ownership,online=()=>true,expectedVersion,manifestPublicKey}={}) { if(!store?.get||!store?.put||!store?.removePrefix||typeof fetchImpl!=='function')throw new Error('durable chunk store and fetch are required');if(typeof ownership!=='function')throw new Error('explicit authenticated ownership adapter is required');if(!id(expectedVersion))throw new Error('authoritative expectedVersion is required');if(fetchImpl===globalThis.fetch){const nativeFetch=fetchImpl;fetchImpl=(...args)=>Reflect.apply(nativeFetch,globalThis,args)}Object.assign(this,{store,fetchImpl,policy,ownership,online,expectedVersion,manifestPublicKey});this.maxAccountedAllocationBytes=0; }\r\n prefix(m,owner){return `material/${owner}/${m.packId}/${m.version}/${m.keyId}/`} key(m,o,a,c){return `${this.prefix(m,o)}${a.path}/${c.index}`}\r\n async ownerFor(m,prior=null){const o=await this.ownership({packId:m.packId,version:m.version});if(typeof o!=='string'||!OWNER.test(o))throw new Error('material is not owned by an authenticated account');if(prior&&o!==prior)throw new Error('authenticated account changed during material operation');return o}\r\n async prepare(m){const owner=await this.ownerFor(m);if(!this.manifestPublicKey)throw new Error('trusted manifest public key is required');await verifyChunkManifest(m,this.manifestPublicKey,this.policy);if(m.version!==this.expectedVersion)throw new Error('replayed or unexpected manifest version');return this.ownerFor(m,owner)}\r\nasync download(m,{signal,retry=1}={}) { const owner=await this.prepare(m);if(!this.online())throw new Error('offline; resume available');let received=0;for(const a of m.assets)for(const c of a.chunks){await this.ownerFor(m,owner);const key=this.key(m,owner,a,c),saved=await this.store.get(key);if(saved?.byteLength===c.bytes&&await hash(saved)===c.sha256){await this.ownerFor(m,owner);received+=saved.byteLength;continue}await this.ownerFor(m,owner);if(signal?.aborted)throw new Error('download cancelled; resume available');if(saved)await this.store.removePrefix(key);let failure;for(let attempt=0;attempt<=retry;attempt++){let reader;try{if(signal?.aborted)throw new Error('download cancelled; resume available');await this.ownerFor(m,owner);if(!this.online())throw new Error('offline; resume available');const response=await this.fetchImpl(c.url,{headers:{Range:`bytes=${c.offset}-${c.offset+c.bytes-1}`,...(c.etag?{'If-Range':c.etag}:{})},signal,redirect:'error'});if(!response.ok||response.status!==206||response.redirected||!trustedUrl(response.url||c.url,this.policy))throw new Error(`chunk HTTP/redirect policy failure (${response.status})`);if(c.etag&&response.headers.get('etag')!==c.etag)throw new Error('chunk ETag changed');const range=response.headers.get('content-range');if(range===null?!pinnedRawCorsRange(c.url,response,this.policy):!new RegExp(`^bytes ${c.offset}-${c.offset+c.bytes-1}/\\\\d+$`).test(range))throw new Error('invalid chunk Content-Range');if(Number(response.headers.get('content-length'))!==c.bytes)throw new Error('chunk response size mismatch');reader=response.body?.getReader();if(!reader)throw new Error('streaming response body required');const joined=new Uint8Array(c.bytes);let size=0,largest=0;for(;;){const part=await reader.read();if(part.done)break;const value=part.value instanceof Uint8Array?part.value:new Uint8Array(part.value);largest=Math.max(largest,value.byteLength);size+=value.byteLength;if(size>c.bytes)throw new Error('chunk response too large');joined.set(value,size-value.byteLength)}this.maxAccountedAllocationBytes=Math.max(this.maxAccountedAllocationBytes,joined.byteLength*2+largest);if(size!==c.bytes)throw new Error('chunk response truncated');if(await hash(joined)!==c.sha256)throw new Error('chunk hash mismatch');if(signal?.aborted)throw new Error('download cancelled; resume available');await this.ownerFor(m,owner);await this.store.put(key,joined);await this.ownerFor(m,owner);received+=size;failure=null;break}catch(e){failure=signal?.aborted?new Error('download cancelled; resume available'):e;if(signal?.aborted||/ETag|hash|size|cancelled|Content-Range|redirect|account changed/.test(e.message))break}finally{if(reader)await reader.cancel().catch(()=>{})}}if(failure)throw failure}await this.ownerFor(m,owner);if(signal?.aborted)throw new Error('download cancelled; resume available');return {receivedBytes:received,maxAccountedAllocationBytes:this.maxAccountedAllocationBytes,browserMemoryLimitation:'Browser network and stream buffers are implementation-controlled; this bounds only staged chunk, store-copy, and largest read segment, never an asset.'} }\r\n /** Same signed/resumable flow, with progress from verified cached or newly committed chunks. */\r\n async downloadWithProgress(m,{signal,retry=1,onProgress}={}) {\r\n  const owner=await this.prepare(m), totalBytes=m.assets.reduce((n,a)=>n+a.bytes,0),verified=new Set();let receivedBytes=0;\r\n  const report=()=>{if(signal?.aborted)return;try{onProgress?.({packId:m.packId,receivedBytes,totalBytes,percent:totalBytes?receivedBytes/totalBytes:1})}catch{/* progress observers cannot affect delivery */}};\r\n  report();\r\n  for(const asset of m.assets)for(const chunk of asset.chunks){\r\n   if(signal?.aborted)throw new Error('download cancelled; resume available');\r\n   await this.ownerFor(m,owner);const key=this.key(m,owner,asset,chunk),saved=await this.store.get(key);\r\n   const valid=saved?.byteLength===chunk.bytes&&await hash(saved)===chunk.sha256;await this.ownerFor(m,owner);\r\n   if(valid){verified.add(key);receivedBytes+=saved.byteLength;report()}\r\n  }\r\n  const baseStore=this.store;\r\n  const progressStore={\r\n   get:key=>baseStore.get(key),\r\n   async put(key,bytes){await baseStore.put(key,bytes);if(!verified.has(key)){verified.add(key);receivedBytes+=bytes.byteLength;report()}},\r\n   removePrefix:prefix=>baseStore.removePrefix(prefix),\r\n  };\r\n  const downloader=new ChunkDownloader({store:progressStore,fetchImpl:this.fetchImpl,policy:this.policy,ownership:()=>this.ownerFor(m,owner),online:this.online,expectedVersion:this.expectedVersion,manifestPublicKey:this.manifestPublicKey});\r\n  const result=await downloader.download(m,{signal,retry});this.maxAccountedAllocationBytes=Math.max(this.maxAccountedAllocationBytes,downloader.maxAccountedAllocationBytes);return result;\r\n }\r\n async verifyStored(m){const owner=await this.prepare(m);for(const a of m.assets)for(const c of a.chunks){await this.ownerFor(m,owner);const v=await this.store.get(this.key(m,owner,a,c));if(!v||v.byteLength!==c.bytes||await hash(v)!==c.sha256)throw new Error(`unverified stored chunk: ${a.path}/${c.index}`);await this.ownerFor(m,owner)}await this.ownerFor(m,owner);return {verified:true,owner,guarantee:'canonical signed ordered chunk list'}}\r\n /** Reconstruct one requested asset after the whole signed chunk set has verified, bounding working memory for large optional packs. */\r\n async readVerifiedAsset(m,path){const verified=await this.verifyStored(m),a=m.assets.find(asset=>asset.path===path);if(!a)throw new Error(`unknown asset path: ${path}`);const out=new Uint8Array(a.bytes);for(const c of a.chunks){await this.ownerFor(m,verified.owner);const value=await this.store.get(this.key(m,verified.owner,a,c));if(!value||value.byteLength!==c.bytes||await hash(value)!==c.sha256)throw new Error(`stored chunk changed: ${a.path}/${c.index}`);await this.ownerFor(m,verified.owner);out.set(value,c.offset)}if(await hash(out)!==a.sha256)throw new Error(`stored asset aggregate hash mismatch: ${a.path}`);await this.ownerFor(m,verified.owner);return Object.freeze({path:a.path,bytes:out})}\r\n /** Bytes are reconstructed only after every signed chunk and aggregate asset digest verify. */\r\n async readVerifiedAssets(m){const verified=await this.verifyStored(m),assets=[];for(const a of m.assets){const out=new Uint8Array(a.bytes);for(const c of a.chunks){await this.ownerFor(m,verified.owner);const value=await this.store.get(this.key(m,verified.owner,a,c));if(!value||value.byteLength!==c.bytes||await hash(value)!==c.sha256)throw new Error(`stored chunk changed: ${a.path}/${c.index}`);await this.ownerFor(m,verified.owner);out.set(value,c.offset)}if(await hash(out)!==a.sha256)throw new Error(`stored asset aggregate hash mismatch: ${a.path}`);await this.ownerFor(m,verified.owner);assets.push(Object.freeze({path:a.path,bytes:out}))}await this.ownerFor(m,verified.owner);return Object.freeze(assets)}\r\n async activate(m,activation){if(typeof activation!=='function')throw new Error('material activation adapter is required');const v=await this.verifyStored(m);await this.ownerFor(m,v.owner);let runtime;try{runtime=await activation({manifest:m,owner:v.owner,prefix:this.prefix(m,v.owner),store:this.store});await this.ownerFor(m,v.owner);return runtime}catch(error){runtime?.dispose?.();throw error}}\r\n async evict(m){const owner=await this.prepare(m);await this.store.removePrefix(this.prefix(m,owner))}\r\n}\r\nexport { hash as sha256Chunk };\r\n","modules/materials/installed-creature-skins.mjs":"import CATALOG from '../../creature/source/creator/creature-skins.json' with { type:'json' };\r\nimport { ACCOUNT_SCOPED_LEDGER_KINDS, isGranted, grantedIds } from '../../unlock-ledger.mjs';\r\nimport { ChunkDownloader, DEFAULT_LOCAL_RESOURCE_POLICY, indexedDbChunkStore, sha256Chunk, verifyChunkManifest } from './chunk-delivery.mjs';\r\nimport { productionMaterialTrust } from './material-config.mjs';\r\nimport { resolvePostDownloadSection } from './post-download-sections.mjs';\r\nimport { unpackVerifiedBundle } from './verified-bundle.mjs';\r\n\r\nconst safeOwner=value=>typeof value==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(value);\r\nconst mapNames=Object.freeze({basecolor:'basecolor',normal:'normal',roughness:'roughness',height:'height',metalness:'metalness',tintMask:'tintMask',ao:'ao',opacity:'opacity',emissive:'emissive',preview:'preview'});\r\n\r\n/** Read-only installed-pack seam. It verifies the hosted signature and already-stored chunks;\r\n * it never downloads missing chunks. The caller owns disposal and must replace it on account changes. */\r\nexport function createInstalledCreatureSkinSource({account=globalThis.myr5AuthenticatedAccount,fetchImpl=globalThis.fetch,store,policy=DEFAULT_LOCAL_RESOURCE_POLICY,trust=productionMaterialTrust()}={}){\r\n const owner=typeof account==='string'?account:account?.user?.id;\r\n if(!safeOwner(owner)||!trust)return Object.freeze({owner:null,list:async()=>[],resolve:async()=>null,dispose(){}});\r\n if(!ACCOUNT_SCOPED_LEDGER_KINDS?.includes('creature-skin'))return Object.freeze({owner:null,list:async()=>[],resolve:async()=>null,dispose(){}});\r\n let disposed=false,sectionStore=store;const tracks=new Map(),available=new Map(),abort=new AbortController();\r\n const current=()=>!disposed&&(typeof globalThis.myr5AuthenticatedAccount==='string'?globalThis.myr5AuthenticatedAccount:globalThis.myr5AuthenticatedAccount?.user?.id)===owner;\r\n const owned=id=>current()&&isGranted('creature-skin',id,{account:owner});\r\n async function loadTrack(track){\r\n  if(tracks.has(track))return tracks.get(track);\r\n  const work=(async()=>{\r\n   if(!current())throw new Error('Skin owner changed.');\r\n   sectionStore??=indexedDbChunkStore();\r\n   const sectionId=`track-${track}`,manifestKey=`material-manifest/${owner}/${sectionId}/1.0.0`;let resolved,networkFailed=false;\r\n   try{resolved=await resolvePostDownloadSection(sectionId,{fetchImpl:async(...args)=>{try{return await fetchImpl(...args);}catch(error){networkFailed=true;throw error;}},policy,trust,signal:abort.signal});\r\n    if(!current())throw new Error('Skin owner changed.');await sectionStore.put(manifestKey,resolved.manifestBytes);\r\n    if(!current()){await sectionStore.removePrefix(manifestKey);throw new Error('Skin owner changed.');}\r\n   }catch(error){\r\n    // Offline fallback may use only this owner's previously verified signed metadata.\r\n    // A responding server with invalid signatures/version must never be bypassed.\r\n    if(!networkFailed||!current())throw error;\r\n    const cached=await sectionStore.get(manifestKey);if(!cached||cached.byteLength>1024*1024)throw error;\r\n    const manifest=JSON.parse(new TextDecoder().decode(cached));if(manifest.packId!==sectionId||manifest.version!=='1.0.0')throw error;\r\n    await verifyChunkManifest(manifest,trust,policy);resolved={manifest,trust};\r\n   }\r\n   const downloader=new ChunkDownloader({store:sectionStore,fetchImpl,policy,expectedVersion:resolved.manifest.version,manifestPublicKey:resolved.trust,ownership:async info=>current()&&info.packId===sectionId?owner:false});\r\n   const path=`assets/${track}.m5bundle`,asset=await downloader.readVerifiedAsset(resolved.manifest,path);\r\n   const entries=await unpackVerifiedBundle(asset.bytes);\r\n   if(!current())throw new Error('Skin owner changed.');\r\n   return entries;\r\n  })();\r\n  tracks.set(track,work);try{return await work}catch(error){tracks.delete(track);throw error;}\r\n }\r\n async function list(){\r\n  if(!current())return Object.freeze([]);\r\n  const ids=new Set(grantedIds('creature-skin',{account:owner}));\r\n  const rows=CATALOG.skins.filter(skin=>ids.has(skin.id)&&owned(skin.id));\r\n  const groups=new Map();for(const skin of rows){if(!groups.has(skin.track))groups.set(skin.track,[]);groups.get(skin.track).push(skin);}\r\n  const found=[];\r\n  for(const [track,skins] of groups){\r\n   let bundle;try{bundle=await loadTrack(track)}catch{continue;}\r\n   for(const skin of skins){if(!owned(skin.id))continue;const maps={};let valid=true;for(const [name,expected] of Object.entries(skin.maps)){const bytes=bundle.get(`${skin.id}/${name}`);if(!mapNames[name]||!bytes||bytes.byteLength!==expected.bytes||await sha256Chunk(bytes)!==expected.sha256){valid=false;break;}maps[name]=bytes;}\r\n    if(valid&&Object.keys(maps).length){const item=Object.freeze({id:skin.id,displayName:skin.displayName,track,collection:skin.collection,maps:Object.freeze(maps)});available.set(skin.id,item);found.push(item);}\r\n   }\r\n  }\r\n  if(!current()){available.clear();return Object.freeze([]);}\r\n  return Object.freeze(found);\r\n }\r\n async function resolve(id){\r\n  if(!owned(id))return null;\r\n  if(!available.has(id))await list();\r\n  if(!owned(id))return null;\r\n  return available.get(id)??null;\r\n }\r\n return Object.freeze({owner,list,resolve,dispose(){disposed=true;abort.abort();available.clear();tracks.clear();}});\r\n}\r\n\r\nexport const CREATURE_SKIN_MAP_SEMANTICS=Object.freeze({\r\n basecolor:'srgb',tintMask:'srgb',emissive:'srgb',normal:'linear',roughness:'linear',height:'linear',metalness:'linear',ao:'linear',opacity:'linear',\r\n normalConvention:'OpenGL +Y',tint:'linear-space triad lookup driven by the decoded grayscale tint mask',\r\n});\r\n","modules/materials/liquid-runtime.mjs":"/** Trusted, app-owned liquid pilot. Downloaded pack bytes are data only. */\r\nexport function createLiquidPilotRuntime({ host, parameters = {} } = {}) {\r\n  if (!host?.ownerDocument) throw new Error('liquid runtime requires an owned host');\r\n  const canvas = host.ownerDocument.createElement('canvas');\r\n  canvas.width = 96; canvas.height = 64; canvas.className = 'material-liquid-pilot';\r\n  host.replaceChildren(canvas);\r\n  const ctx = canvas.getContext('2d'); let disposed = false; let energy = 0;\r\n  const hue = Number.isFinite(parameters.hue) ? Math.max(250, Math.min(310, parameters.hue)) : 278;\r\n  const strength = Number.isFinite(parameters.strength) ? Math.max(.1, Math.min(1, parameters.strength)) : .6;\r\n  const draw = () => { if (disposed || !ctx) return; const gradient = ctx.createRadialGradient(48, 32, 1, 48, 32, 58); gradient.addColorStop(0, `hsl(${hue - energy * 18} 85% ${44 + energy * 25}%)`); gradient.addColorStop(1, `hsl(${hue} 72% 10%)`); ctx.fillStyle = gradient; ctx.fillRect(0, 0, 96, 64); };\r\n  const pointer = event => { energy = strength; draw(); event.preventDefault?.(); };\r\n  canvas.addEventListener('pointerdown', pointer); draw();\r\n  return Object.freeze({ canvas, dispose() { if (disposed) return; disposed = true; canvas.removeEventListener('pointerdown', pointer); canvas.remove(); }, getDebug: () => ({ disposed, energy, hue }) });\r\n}\r\n","modules/materials/material-config.mjs":"// Release tooling injects only public verification material. Null is valid and fail-closed.\r\nexport const BUILT_PUBLIC_MATERIAL_SIGNING_JWK = typeof __MYR5_MATERIAL_PUBLIC_JWK__ === 'undefined' ? null : __MYR5_MATERIAL_PUBLIC_JWK__;\r\nexport const BUILT_MATERIAL_RESOURCE_POLICY = typeof __MYR5_MATERIAL_RESOURCE_POLICY__ === 'undefined' ? null : __MYR5_MATERIAL_RESOURCE_POLICY__;\r\n\r\nconst usableKey = key => key && typeof key === 'object' && key.kty === 'OKP' && key.crv === 'Ed25519'\r\n  && typeof key.x === 'string' && /^[A-Za-z0-9_-]{43}$/.test(key.x) && !/^A+$/.test(key.x);\r\n\r\nexport function productionMaterialTrust() {\r\n  return usableKey(BUILT_PUBLIC_MATERIAL_SIGNING_JWK) && !('d' in BUILT_PUBLIC_MATERIAL_SIGNING_JWK) ? BUILT_PUBLIC_MATERIAL_SIGNING_JWK : null;\r\n}\r\n\r\nexport function productionMaterialResourcePolicy() {\r\n  const value=BUILT_MATERIAL_RESOURCE_POLICY;\r\n  if(!value||value.trustedOrigins?.length!==1||value.trustedOrigins[0]!=='https://raw.githubusercontent.com'||value.allowedProtocols?.length!==1||value.allowedProtocols[0]!=='https:'||typeof value.pathPrefix!=='string'||!/^\\/[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+\\/[a-f0-9]{40}\\/materials\\/$/.test(value.pathPrefix))return null;\r\n  return Object.freeze({trustedOrigins:Object.freeze([...value.trustedOrigins]),allowedProtocols:Object.freeze([...value.allowedProtocols]),pathPrefix:value.pathPrefix});\r\n}\r\n\r\n// This is application-owned policy, never remotely supplied manifest policy.\r\nexport const MATERIAL_RUNTIME_POLICY = Object.freeze({\r\n  'liquid-amethyst': Object.freeze({ runtimeType: 'liquid-v1', parameterKeys: Object.freeze(['hue', 'strength']) }),\r\n});\r\n","modules/materials/material-controller.mjs":"/** Account-scoped material lifecycle; stored pack bytes are declarative data only. */\r\nimport { ChunkDownloader, indexedDbChunkStore, DEFAULT_LOCAL_RESOURCE_POLICY, verifyChunkManifest, canonicalChunkPayload } from './chunk-delivery.mjs';\r\nimport { resolveMaterialBundle, createMaterialRuntime, verifiedMaterialAccount, canonicalMaterialPayload, isSignedMaterialManifest } from './material-pack-entry.mjs';\r\nimport { productionMaterialTrust } from './material-config.mjs';\r\nimport { existingWorkoutIdleAdapter } from '../../packs/workout-idle-adapter.mjs';\r\nconst KEY='mom.material-controller.v2',OWNER=/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/;\r\nconst mountedControls=new WeakMap();\r\nconst read=s=>{try{const x=JSON.parse(s.getItem(KEY)||'');return x?.v===2&&x.accounts?x:{v:2,accounts:{}}}catch{return {v:2,accounts:{}}}},sum=m=>m.assets.reduce((n,x)=>n+x.bytes,0);\r\nconst owner=a=>{const id=a?.user?.id;if(typeof id!=='string'||!OWNER.test(id))throw new Error('a stable authenticated account identity is required');return id};\r\nconst semver=v=>{const x=/^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-[0-9A-Za-z.-]+)?(?:\\+[0-9A-Za-z.-]+)?$/.exec(v||'');if(!x)throw new Error('unsupported app version format');return x.slice(1).map(Number)},supported=(a,b)=>{a=semver(a);b=semver(b);return a[0]>b[0]||a[0]===b[0]&&(a[1]>b[1]||a[1]===b[1]&&a[2]>=b[2])};\r\nexport class MaterialController {\r\n constructor({account,workoutOwner,host,storage=globalThis.localStorage,chunkStore=indexedDbChunkStore(),fetchImpl=globalThis.fetch,policy,appVersion='1.0.0',onChange=()=>{},bootId}={}){if(!host?.ownerDocument)throw Error('material controls require an application host');Object.assign(this,{account,owner:owner(account),host,storage,chunkStore,fetchImpl:(...args)=>fetchImpl.call(globalThis,...args),policy,appVersion,onChange,bootId:bootId||crypto.randomUUID?.()||String(Date.now()),workout:existingWorkoutIdleAdapter({owner:workoutOwner}),db:read(storage),runtime:null,abort:null,bundle:null,disposed:false})}\r\n record(){return this.db.accounts[this.owner]||{active:null,candidate:null}} save(){this.storage.setItem(KEY,JSON.stringify(this.db))} status(){const r=this.record(),x=r.candidate||r.active||{};return {state:r.candidate?.state||r.active?.state||'absent',receivedBytes:x.receivedBytes||0,totalBytes:x.chunkManifest?sum(x.chunkManifest):0,error:x.error,pending:r.candidate?.state==='pending-equip',active:!!r.active}} emit(){this.save();this.onChange(this.status())}\r\n owned(m){return verifiedMaterialAccount(this.account).getEntitlements().some(x=>x.packId===m.packId)}\r\n epoch=0; revoked=false;\r\n assertLive(m=this.bundle?.manifest||this.record().active?.materialManifest,epoch=this.epoch){if(this.disposed)throw Error('material controller is disposed');if(this.revoked||epoch!==this.epoch)throw Error('material operation was revoked');if(this.account?.user?.id!==this.owner||(m&&!this.owned(m))){this.epoch++;this.revoked=true;this.cancel();this.runtime?.dispose?.();this.runtime=null;throw Error('material ownership was revoked or account changed')}}\r\n downloader(b=this.bundle,epoch=this.epoch){if(!b)throw Error('signed material metadata has not been loaded');const {manifest,trust}=b;return new ChunkDownloader({store:this.chunkStore,fetchImpl:this.fetchImpl,policy:this.policy||DEFAULT_LOCAL_RESOURCE_POLICY,expectedVersion:manifest.version,manifestPublicKey:trust,ownership:async x=>{this.assertLive(manifest,epoch);return x.packId===manifest.packId&&x.version===manifest.version?this.owner:false}})}\r\n validateBundle(b){const {manifest:m,chunkManifest:c}=b;if(m.version!==c.version||m.packId!==c.packId||m.keyId!==c.keyId||m.assets.length!==c.assets.length||c.assets.some((a,i)=>a.path!==m.assets[i].path||a.bytes!==m.assets[i].bytes||a.sha256!==m.assets[i].sha256))throw Error('signed material metadata is not bound to signed chunk manifest');if(!supported(this.appVersion,m.minAppVersion))throw Error('material requires a newer app version')}\r\n async load(options={}){const epoch=this.epoch;this.assertLive();const b=await resolveMaterialBundle(options);this.assertLive(b.manifest,epoch);this.validateBundle(b);this.bundle=b;return this.status()}\r\n putCandidate(c){this.db.accounts[this.owner]={...this.record(),candidate:c};this.emit()}\r\n async download(){this.assertLive();const b=this.bundle,epoch=this.epoch,d=this.downloader(b,epoch),old=this.record().candidate,abort=new AbortController();this.abort=abort;const candidate={state:'downloading',receivedBytes:old?.receivedBytes||0,chunkManifest:b.chunkManifest,materialManifest:b.manifest};this.putCandidate(candidate);try{const r=await d.download(b.chunkManifest,{signal:abort.signal});this.assertLive(b.manifest,epoch);if(this.record().candidate!==candidate)throw Error('material candidate changed during download');this.putCandidate({...candidate,state:'verified',receivedBytes:r.receivedBytes});return this.status()}catch(e){this.assertLive(b.manifest,epoch);if(this.record().candidate===candidate)this.putCandidate({...candidate,state:'failed',error:e.message||'download failed'});throw e}finally{if(this.abort===abort)this.abort=null}}\r\n cancel(){this.abort?.abort()} async equipAfterRestart(){this.assertLive();const c=this.record().candidate,b=this.bundle,epoch=this.epoch;if(!b||c?.state!=='verified'||c.materialManifest?.signature!==b.manifest.signature||c.chunkManifest?.signature!==b.chunkManifest.signature||canonicalMaterialPayload(c.materialManifest)!==canonicalMaterialPayload(b.manifest)||canonicalChunkPayload(c.chunkManifest)!==canonicalChunkPayload(b.chunkManifest))throw Error('only verified material chunks can be equipped');await this.downloader(b,epoch).verifyStored(b.chunkManifest);this.assertLive(b.manifest,epoch);if(this.record().candidate!==c)throw Error('material candidate changed during verification');this.putCandidate({...c,state:'pending-equip',bootId:this.bootId});return this.status()}\r\n async savedBundle(r,options={}){\r\n  if(!r?.materialManifest||!r?.chunkManifest)throw Error('saved material metadata is incomplete');\r\n  const epoch=this.epoch;this.assertLive(r.materialManifest,epoch);\r\n  // Authenticate the exact persisted metadata using application-owned trust, never a stored key.\r\n  const trust=options.testTrust?.purpose==='test-only-signed-material'?options.testTrust.publicKey:productionMaterialTrust(),manifest=r.materialManifest,chunkManifest=r.chunkManifest;\r\n  if(!isSignedMaterialManifest(manifest)||!trust||trust.kty!=='OKP'||trust.crv!=='Ed25519')throw Error('saved material manifest signature is invalid');\r\n  const key=await crypto.subtle.importKey('jwk',trust,{name:'Ed25519'},false,['verify']);this.assertLive(manifest,epoch);\r\n  const signature=Uint8Array.from(atob(manifest.signature),x=>x.charCodeAt(0));\r\n  const valid=await crypto.subtle.verify({name:'Ed25519'},key,signature,new TextEncoder().encode(canonicalMaterialPayload(manifest)));this.assertLive(manifest,epoch);\r\n  if(!valid)throw Error('saved material manifest signature is invalid');\r\n  await verifyChunkManifest(chunkManifest,trust,this.policy||DEFAULT_LOCAL_RESOURCE_POLICY);this.assertLive(manifest,epoch);\r\n  const b={manifest,chunkManifest,trust};this.validateBundle(b);return b;\r\n }\r\n async activate(b,c,{restore=false,epoch=this.epoch}={}){\r\n  this.assertLive(b.manifest,epoch);const idle=await this.workout.saveAndConfirmIdle();let next;\r\n  try{\r\n   this.assertLive(b.manifest,epoch);if(!(idle?.saved&&idle?.idle))throw Error(idle?.reason||'workout save/idle acknowledgment is required before activation');\r\n   const assets=await this.downloader(b,epoch).readVerifiedAssets(b.chunkManifest);this.assertLive(b.manifest,epoch);\r\n   next=await createMaterialRuntime(b.manifest.packId,{verifiedAssets:assets},b.manifest,this.host);this.assertLive(b.manifest,epoch);\r\n   if((restore?this.record().active:this.record().candidate)!==c)throw Error('material record changed during activation');\r\n   const old=this.runtime;this.runtime=next;next=null;old?.dispose?.();\r\n   if(!restore){this.db.accounts[this.owner]={active:{...c,state:'active'},candidate:null};this.emit()}\r\n   return this.status();\r\n  }finally{try{next?.dispose?.()}finally{idle?.release?.()}}\r\n }\r\n async restorePending(options={}){\r\n  this.assertLive();const r=this.record(),c=r.candidate,epoch=this.epoch;\r\n  if(c?.state!=='pending-equip'||c.bootId===this.bootId)return r.active?this.restoreActive(options):this.status();\r\n  try{const b=await this.savedBundle(c,options);this.assertLive(b.manifest,epoch);return await this.activate(b,c,{epoch})}\r\n  catch(e){this.assertLive(c.materialManifest,epoch);if(this.record().candidate===c)this.putCandidate({...c,state:'pending-equip',error:`activation failed: ${e.message||e}`});if(r.active)await this.restoreActive(options);throw e}\r\n }\r\n async restoreActive(options={}){this.assertLive();const a=this.record().active,epoch=this.epoch;if(!a)return this.status();const b=await this.savedBundle(a,options);this.assertLive(b.manifest,epoch);return this.activate(b,a,{restore:true,epoch})}\r\n revoke(){this.epoch++;this.revoked=true;this.cancel();this.runtime?.dispose?.();this.runtime=null;this.bundle=null;this.db.accounts[this.owner]={active:null,candidate:null};this.emit()} dispose(){if(this.disposed)return;this.epoch++;this.disposed=true;this.cancel();this.runtime?.dispose?.();this.runtime=null}\r\n}\r\nexport function mountMaterialControls({document=globalThis.document,account,workoutOwner,fixture,testTrust,policy,fetchImpl,appVersion}={}){const panel=document?.getElementById('materialControls'),host=document?.getElementById('materialRuntime');if(!panel||!host)return null;const prior=mountedControls.get(panel);if(prior)return prior;const status=panel.querySelector('[data-material-status]'),download=panel.querySelector('[data-material-download]'),cancel=panel.querySelector('[data-material-cancel]'),equip=panel.querySelector('[data-material-equip]');const render=v=>{status.textContent=v.error||`${v.state}${v.totalBytes?` · ${v.receivedBytes}/${v.totalBytes} bytes`:''}`;download.disabled=!account||v.state==='downloading'||v.pending;cancel.hidden=v.state!=='downloading';equip.disabled=v.state!=='verified'};let c;try{c=new MaterialController({account,workoutOwner,host,policy,fetchImpl,appVersion,onChange:render})}catch(e){render({state:'failed',error:e.message});return null}const options={fixture,testTrust},prepare=async()=>{if(!c.bundle)await c.load(options);return c},dl=async()=>{try{await(await prepare()).download()}catch(e){render({...c.status(),error:e.message})}},eq=async()=>{try{await(await prepare()).equipAfterRestart();render({...c.status(),error:'Verified. Reload Coach to activate.'})}catch(e){render({...c.status(),error:e.message})}},changed=()=>{try{c.assertLive()}catch{c.revoke();render({...c.status(),error:'Material access changed.'})}},cleared=()=>{c.revoke();render({...c.status(),error:'Material access changed.'})};download.addEventListener('click',dl);cancel.addEventListener('click',()=>c.cancel());equip.addEventListener('click',eq);globalThis.addEventListener?.('myr5:account-ready',changed);globalThis.addEventListener?.('myr5:account-cleared',cleared);render(c.status());void c.restorePending(options).catch(e=>render({...c.status(),error:e.message}));const dispose=c.dispose.bind(c);c.dispose=()=>{download.removeEventListener('click',dl);equip.removeEventListener('click',eq);globalThis.removeEventListener?.('myr5:account-ready',changed);globalThis.removeEventListener?.('myr5:account-cleared',cleared);mountedControls.delete(panel);dispose()};mountedControls.set(panel,c);return c}\r\n","modules/materials/material-pack-entry.mjs":"import { createIsolatedPackControl, authenticatedPackAccount } from '../../packs/isolated-pack-control.mjs';\r\nimport { MATERIAL_RUNTIME_POLICY, productionMaterialTrust } from './material-config.mjs';\r\nimport { verifyChunkManifest } from './chunk-delivery.mjs';\r\n\r\nexport const MATERIAL_MANIFEST_SCHEMA = 'mom-material-pack-v1';\r\nconst hex = value => typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value);\r\nconst b64 = value => typeof value === 'string' && /^[A-Za-z0-9+/]+={0,2}$/.test(value) && value.length >= 80;\r\nconst plain = value => value && typeof value === 'object' && !Array.isArray(value);\r\nconst resource = asset => plain(asset) && typeof asset.path === 'string' && /^assets\\/[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(asset.path) && !asset.path.includes('..') && !/\\.(?:m?js|cjs|html?)$/i.test(asset.path) && Number.isSafeInteger(asset.bytes) && asset.bytes > 0 && asset.bytes <= 512 * 1024 && hex(asset.sha256);\r\nconst stable = value => { if (Array.isArray(value)) return value.map(stable); if (plain(value)) return Object.fromEntries(Object.keys(value).sort().map(key => [key, stable(value[key]) ])); if (value === null || ['string', 'number', 'boolean'].includes(typeof value)) return value; throw new Error('parameters must be declarative JSON'); };\r\nexport const canonicalMaterialPayload = manifest => JSON.stringify(stable({ schema: manifest.schema, packId: manifest.packId, version: manifest.version, minAppVersion: manifest.minAppVersion, sha256: manifest.sha256, alg: manifest.alg, keyId: manifest.keyId, materialId: manifest.materialId, runtimeType: manifest.runtimeType, parameters: manifest.parameters, assets: manifest.assets.map(({ path, bytes, sha256 }) => ({ path, bytes, sha256 })) }));\r\nexport function isSignedMaterialManifest(m) { const policy = MATERIAL_RUNTIME_POLICY[m?.materialId]; return plain(m) && m.schema === MATERIAL_MANIFEST_SCHEMA && typeof m.packId === 'string' && m.packId === m.materialId && typeof m.version === 'string' && typeof m.minAppVersion === 'string' && hex(m.sha256) && m.alg === 'Ed25519' && m.keyId === 'mom-material-production-v1' && b64(m.signature) && policy?.runtimeType === m.runtimeType && plain(m.parameters) && Object.keys(m.parameters).every(key => policy.parameterKeys.includes(key)) && Array.isArray(m.assets) && m.assets.length > 0 && m.assets.length <= 16 && m.assets.every(resource) && m.assets.reduce((sum, asset) => sum + asset.bytes, 0) <= 2 * 1024 * 1024; }\r\nconst bytes = value => Uint8Array.from((typeof atob === 'function' ? atob(value) : Buffer.from(value, 'base64').toString('binary')), char => char.charCodeAt(0));\r\nasync function verified(m, key) { if (!isSignedMaterialManifest(m) || !plain(key) || key.kty !== 'OKP' || key.crv !== 'Ed25519') return false; try { const crypto = globalThis.crypto?.subtle; if (!crypto) return false; const trusted = await crypto.importKey('jwk', key, { name: 'Ed25519' }, false, ['verify']); return crypto.verify({ name: 'Ed25519' }, trusted, bytes(m.signature), new TextEncoder().encode(canonicalMaterialPayload(m))); } catch { return false; } }\r\nexport async function resolveMaterialManifest({ fixture = null, testTrust = null } = {}) { const trust = testTrust?.purpose === 'test-only-signed-material' ? testTrust.publicKey : (fixture ? null : productionMaterialTrust()); if (!trust) throw new Error('Material unavailable: trusted public configuration is not configured'); const manifest = fixture?.manifest; if (!fixture || !(await verified(manifest, trust))) throw new Error('Material manifest signature is invalid'); return { manifest, source: fixture.source }; }\r\nexport async function resolveMaterialBundle({ fixture = null, testTrust = null } = {}) {\r\n const { manifest } = await resolveMaterialManifest({ fixture, testTrust }); const chunks = fixture?.chunkManifest;\r\n if (!chunks) throw new Error('Material chunk manifest is unavailable');\r\n const trust = testTrust?.purpose === 'test-only-signed-material' ? testTrust.publicKey : productionMaterialTrust();\r\n await verifyChunkManifest(chunks, trust, fixture?.policy);\r\n if (chunks.packId !== manifest.packId || chunks.version !== manifest.version || chunks.keyId !== manifest.keyId || chunks.assets.length !== manifest.assets.length || chunks.assets.some((asset, i) => asset.path !== manifest.assets[i].path || asset.bytes !== manifest.assets[i].bytes || asset.sha256 !== manifest.assets[i].sha256)) throw new Error('signed material metadata is not bound to signed chunk manifest');\r\n return { manifest, chunkManifest: chunks, trust };\r\n}\r\nexport function verifiedMaterialAccount(account) {\r\n const grants=authenticatedPackAccount(account);\r\n return Object.freeze({...grants,getEntitlements:()=>grants.getEntitlements().filter(item=>Object.hasOwn(MATERIAL_RUNTIME_POLICY,item.packId))});\r\n}\r\nexport async function createMaterialRuntime(id, record, manifest, host) { if (!record?.verifiedAssets || !isSignedMaterialManifest(manifest) || manifest.materialId !== id) throw new Error('verified stored material data is required'); if (manifest.runtimeType !== 'liquid-v1') throw new Error('unknown material runtime'); const asset=record.verifiedAssets[0]; if (!asset?.bytes || asset.bytes.byteLength>64*1024) throw new Error('material declarative config is missing or too large'); let config;try{config=JSON.parse(new TextDecoder().decode(asset.bytes));}catch{throw new Error('material declarative config is invalid')}if(!plain(config)||Object.keys(config).some(key=>!['hue','strength'].includes(key))||Object.values(config).some(value=>typeof value!=='number'||!Number.isFinite(value)))throw new Error('material declarative config is invalid'); const { createLiquidPilotRuntime } = await import('./liquid-runtime.mjs'); return createLiquidPilotRuntime({ host, parameters: {...manifest.parameters,...config} }); }\r\nexport function createMaterialPackControl({ account, host, ...options } = {}) { return createIsolatedPackControl({ account: verifiedMaterialAccount(account), runtimeFactory: (id, record, manifest) => createMaterialRuntime(id, record, manifest, host), ...options }); }\r\n","modules/materials/post-download-controller.mjs":"import { ChunkDownloader, DEFAULT_LOCAL_RESOURCE_POLICY, indexedDbChunkStore } from './chunk-delivery.mjs';\r\nimport { resolvePostDownloadSection } from './post-download-sections.mjs';\r\nimport { productionMaterialTrust } from './material-config.mjs';\r\n\r\nconst stable=id=>typeof id==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(id);\r\nconst getOwner=account=>account?.user?.id;\r\n\r\n/** Resumable section delivery for a signed-in owner, invoked only after an explicit user action. */\r\nexport async function downloadPostDownloadSection({id,account=globalThis.myr5AuthenticatedAccount,authorize=()=>false,fetchImpl=globalThis.fetch,store=indexedDbChunkStore(),policy=DEFAULT_LOCAL_RESOURCE_POLICY,trust=productionMaterialTrust(),signal,onProgress}={}){\r\n const owner=getOwner(account);if(!stable(owner))throw new Error('Sign in before downloading a post-download section.');\r\n if(!authorize(id,account))throw new Error('Section access has not been authorized.');\r\n // An explicit null is a logout, never permission to reuse the captured account.\r\n const current=()=>Object.hasOwn(globalThis,'myr5AuthenticatedAccount')?globalThis.myr5AuthenticatedAccount:account;\r\n const allowed=()=>getOwner(current())===owner&&authorize(id,current());\r\n if(signal?.aborted||!allowed())throw new Error('Section download cancelled or account changed.');\r\n const resolved=await resolvePostDownloadSection(id,{fetchImpl,policy,trust,signal});\r\n const downloader=new ChunkDownloader({store,fetchImpl,policy,expectedVersion:resolved.manifest.version,manifestPublicKey:resolved.trust,ownership:async info=>info.packId===id&&allowed()?owner:false});\r\n const result=await downloader.downloadWithProgress(resolved.manifest,{signal,onProgress});await downloader.verifyStored(resolved.manifest);\r\n if(signal?.aborted||!allowed())throw new Error('Section download cancelled or account changed.');\r\n const manifestKey=`material-manifest/${owner}/${id}/${resolved.manifest.version}`;\r\n await store.put(manifestKey,resolved.manifestBytes);\r\n if(signal?.aborted||!allowed()){await store.removePrefix(manifestKey);throw new Error('Section download cancelled or account changed.');}\r\n return Object.freeze({section:resolved.section,manifest:resolved.manifest,downloader,result,isOwned:()=>allowed()});\r\n}\r\n\r\nexport async function downloadAllPostDownloadSections(options={}){\r\n options={...options,account:options.account??globalThis.myr5AuthenticatedAccount};\r\n const {fullPostDownloadSectionIds}=await import('./post-download-sections.mjs');const output=[];\r\n for(const id of fullPostDownloadSectionIds()){if(options.signal?.aborted)throw new Error('section download paused; resume is available');output.push(await downloadPostDownloadSection({...options,id}));}\r\n return Object.freeze(output);\r\n}\r\n\r\n/** Starter set: exactly the selected exercise packets plus Meditation. */\r\nexport async function downloadStarterPostDownloadSections(options={}){\r\n options={...options,account:options.account??globalThis.myr5AuthenticatedAccount};\r\n const {POST_DOWNLOAD_SECTIONS,starterPostDownloadSectionIds}=await import('./post-download-sections.mjs');\r\n const ids=starterPostDownloadSectionIds(options.account??globalThis.myr5AuthenticatedAccount);\r\n const output=[];\r\n for(const id of ids){if(options.signal?.aborted)throw new Error('section download paused; resume is available');output.push(await downloadPostDownloadSection({...options,id}));}\r\n return Object.freeze(output);\r\n}\r\n","modules/materials/post-download-sections.mjs":"import { DEFAULT_LOCAL_RESOURCE_POLICY, verifyChunkManifest } from './chunk-delivery.mjs';\r\nimport { productionMaterialTrust } from './material-config.mjs';\r\n\r\n// Metadata is intentionally small and core-safe. Track bundles combine both skin collections;\r\n// the source manifests/chunk bytes stay on the post-download host and require a real signature.\r\nimport { readSelectedTracks } from '../../chosen-styles.mjs';\r\n\r\nexport const POST_DOWNLOAD_SECTIONS = Object.freeze([\r\n  ...['chest','quads','glutes','arms','yoga','martial-arts','cardio','meditation'].map(track => Object.freeze({ id:`track-${track}`, track, title:track==='arms'?'Arms & Shoulders':track[0].toUpperCase()+track.slice(1), kind:'creature-skins', path:`/materials/track-${track}/chunk-manifest.json`, version:'1.0.0' })),\r\n  Object.freeze({ id:'coach-ships-biomes', title:'Ships and worlds', kind:'ships-biomes', path:'/materials/coach-ships-biomes/chunk-manifest.json', version:'1.0.0' }),\r\n]);\r\n\r\nconst TRACK_PACKET_ALIAS=Object.freeze({'arms-shoulders':'arms'});\r\nexport function starterPostDownloadSectionIds(account=globalThis.myr5AuthenticatedAccount){\r\n  const picked=readSelectedTracks({account});\r\n  if(picked.length!==2)return Object.freeze([]);\r\n  const tracks=[...new Set(['meditation',...picked].map(track=>TRACK_PACKET_ALIAS[track]??track))];\r\n  return Object.freeze(tracks.map(track=>`track-${track}`));\r\n}\r\nexport function fullPostDownloadSectionIds(){ return Object.freeze(POST_DOWNLOAD_SECTIONS.map(section=>section.id)); }\r\n\r\nconst base64Signature = value => typeof value === 'string' && /^[A-Za-z0-9+/]+={0,2}$/.test(value) && value.length >= 80;\r\nasync function boundedManifest(response){\r\n  const limit=1024*1024,reader=response.body?.getReader();if(!reader)throw new Error('Streaming manifest response is required.');\r\n  let total=0;const parts=[];\r\n  try{for(;;){const part=await reader.read();if(part.done)break;total+=part.value.byteLength;if(total>limit)throw new Error('Section manifest exceeds local size policy.');parts.push(part.value);}const bytes=new Uint8Array(total);let offset=0;for(const part of parts){bytes.set(part,offset);offset+=part.byteLength;}return {manifest:JSON.parse(new TextDecoder().decode(bytes)),bytes};}\r\n  finally{await reader.cancel().catch(()=>{});}\r\n}\r\n\r\nexport async function resolvePostDownloadSection(id, { fetchImpl = globalThis.fetch, trust = productionMaterialTrust(), policy = DEFAULT_LOCAL_RESOURCE_POLICY, signal } = {}) {\r\n  const section = POST_DOWNLOAD_SECTIONS.find(row => row.id === id);\r\n  if (!section) throw new Error('Unknown post-download section.');\r\n  if (!trust) throw new Error('This section is unavailable until a production signing key is configured.');\r\n  const response = await fetchImpl(section.path, { credentials:'same-origin', redirect:'error', cache:'no-store', signal });\r\n  if (!response.ok || response.redirected) throw new Error('The signed section manifest could not be loaded.');\r\n  const {manifest,bytes:manifestBytes} = await boundedManifest(response);\r\n  if (manifest.packId !== section.id || manifest.version !== section.version || !base64Signature(manifest.signature)) throw new Error('The section has no valid published signature.');\r\n  await verifyChunkManifest(manifest, trust, policy);\r\n  return Object.freeze({ section, manifest, manifestBytes, trust, policy });\r\n}\r\n\r\nexport function postDownloadSectionStatus(id, { trust = productionMaterialTrust(), manifest = null } = {}) {\r\n  const section = POST_DOWNLOAD_SECTIONS.find(row => row.id === id);\r\n  if (!section) return Object.freeze({ available:false, reason:'unknown-section' });\r\n  if (!trust) return Object.freeze({ available:false, reason:'signing-key-not-configured' });\r\n  if (!manifest || manifest.packId !== id || manifest.version !== section.version || !base64Signature(manifest.signature)) return Object.freeze({ available:false, reason:'signed-hosted-manifest-required' });\r\n  // Syntactic metadata is not evidence of a trusted signature. Only the async\r\n  // resolver may make a section available after cryptographic verification.\r\n  return Object.freeze({ available:false, reason:'signature-verification-required' });\r\n}\r\n","modules/materials/post-download-ui.mjs":"import { downloadAllPostDownloadSections, downloadPostDownloadSection, downloadStarterPostDownloadSections } from './post-download-controller.mjs';\r\nimport { POST_DOWNLOAD_SECTIONS, resolvePostDownloadSection, starterPostDownloadSectionIds } from './post-download-sections.mjs';\r\nimport { productionMaterialTrust } from './material-config.mjs';\r\n\r\nexport function postDownloadChoices(account, availableIds) {\r\n  if (!account?.user?.id || !(availableIds instanceof Set)) return Object.freeze({ starter:[], individual:[], all:[] });\r\n  const all=POST_DOWNLOAD_SECTIONS.map(section=>section.id).filter(id=>availableIds.has(id));\r\n  const wantedStarter=starterPostDownloadSectionIds(account), starter=wantedStarter.every(id=>availableIds.has(id))?wantedStarter:[];\r\n  const selected=new Set(starter);\r\n  return Object.freeze({\r\n    starter:Object.freeze(starter),\r\n    individual:Object.freeze(all.filter(id=>id==='coach-ships-biomes'||(id.startsWith('track-')&&!selected.has(id)))),\r\n    all:Object.freeze(all),\r\n  });\r\n}\r\n\r\n/** Account-scoped explicit-action controls; anonymous core download remains independent. */\r\nexport function mountPostDownloadSections({ host, account=globalThis.myr5AuthenticatedAccount, fetchImpl=globalThis.fetch, trust=productionMaterialTrust(), policy, store }={}) {\r\n  const accountId=value=>typeof value?.user?.id==='string'?value.user.id:null;\r\n  if (!host || !trust || !accountId(account)) return null;\r\n  const panel=document.createElement('section');\r\n  panel.className='post-download-sections';panel.hidden=true;\r\n  panel.innerHTML='<h3>Extra offline packs</h3><p data-status role=\"status\"></p><button type=\"button\" data-retry hidden>Try again</button><div data-actions></div><progress max=\"1\" value=\"0\" hidden aria-label=\"Extra pack download progress\"></progress><button type=\"button\" data-pause hidden>Pause</button>';\r\n  host.append(panel);\r\n  const status=panel.querySelector('[data-status]'), actions=panel.querySelector('[data-actions]'), progress=panel.querySelector('progress'), pause=panel.querySelector('[data-pause]'), retry=panel.querySelector('[data-retry]');\r\n  let currentAccount=account, owner=null, available=new Map(), controller=null, pausedIds=null,epoch=0,disposed=false,checking=null;\r\n  const allowed=()=>!disposed&&!!owner&&accountId(Object.hasOwn(globalThis,'myr5AuthenticatedAccount')?globalThis.myr5AuthenticatedAccount:currentAccount)===owner;\r\n  const labels=new Map(POST_DOWNLOAD_SECTIONS.map(section=>[section.id,section.title]));\r\n  function clear(){available=new Map();actions.replaceChildren();panel.hidden=true;retry.hidden=true;status.textContent='';}\r\n  function button(label,ids,operation){const b=document.createElement('button');b.type='button';b.disabled=!!controller;b.dataset.sections=ids.join(' ');const resume=pausedIds&&JSON.stringify(pausedIds)===JSON.stringify(ids);b.textContent=resume?label.replace(/^Download/,'Resume'):label;b.addEventListener('click',()=>{pausedIds=null;void run(ids,operation);});actions.append(b);}\r\n  function render(){\r\n    if(!allowed()){clear();return;}\r\n    const choices=postDownloadChoices(currentAccount,new Set(available.keys()));\r\n    actions.replaceChildren();\r\n    if(choices.starter.length)button('Download starter styles',choices.starter,opts=>downloadStarterPostDownloadSections(opts));\r\n    for(const id of choices.individual)button(id==='coach-ships-biomes'?'Download ships & worlds':`Download ${labels.get(id)} pack`,[id],opts=>downloadPostDownloadSection({...opts,id}));\r\n    if(choices.all.length===POST_DOWNLOAD_SECTIONS.length)button('Download every extra',choices.all,opts=>downloadAllPostDownloadSections(opts));\r\n    if(actions.childElementCount)panel.hidden=false;\r\n  }\r\n  function report(info){progress.hidden=false;progress.value=Math.max(0,Math.min(1,Number(info?.percent)||0));status.textContent=`Downloading ${labels.get(info?.packId)||'offline packs'} · ${Math.round(progress.value*100)}%`;}\r\n  async function run(ids,operation){\r\n    if(controller||!allowed())return;\r\n    const runEpoch=epoch,runOwner=owner,runAccount=currentAccount,abort=new AbortController();controller=abort;\r\n    const active=()=>runEpoch===epoch&&allowed()&&owner===runOwner;\r\n    pause.hidden=false;pause.disabled=false;pause.textContent='Pause';status.textContent='Preparing verified download…';render();\r\n    try{await operation({signal:abort.signal,account:runAccount,authorize:()=>active(),fetchImpl,trust,policy,store,onProgress:info=>{if(active())report(info);}});if(active()){status.textContent='Offline packs ready.';progress.value=1;window.dispatchEvent(new CustomEvent('myr5:sections-installed',{detail:{ownerId:runOwner,sections:[...ids]}}));}}\r\n    catch(error){if(active()){if(abort.signal.aborted){pausedIds=[...ids];status.textContent='Download paused. Resume is available.';}else status.textContent=error.message||'Download unavailable. Try again later.';}}\r\n    finally{if(controller===abort){controller=null;pause.hidden=true;if(active())render();}}\r\n  }\r\n  pause.addEventListener('click',()=>{if(controller){controller.abort();pause.disabled=true;}});\r\n  retry.addEventListener('click',()=>void refresh());\r\n  async function refresh(){\r\n    const refreshEpoch=++epoch;controller?.abort();controller=null;checking?.abort();checking=new AbortController();\r\n    pausedIds=null;pause.hidden=true;progress.hidden=true;progress.value=0;retry.hidden=true;owner=accountId(currentAccount);\r\n    if(!owner||disposed){clear();return;}\r\n    panel.hidden=false;actions.replaceChildren();status.textContent='Checking signed offline packs…';\r\n    const signal=checking.signal;\r\n    // A section that can't be resolved (bad network, unsupported browser crypto, a stale manifest)\r\n    // is logged, not swallowed: the others still render, and the status line says what to do next.\r\n    const results=await Promise.all(POST_DOWNLOAD_SECTIONS.map(async section=>{\r\n      try{return [section.id,await resolvePostDownloadSection(section.id,{fetchImpl,trust,policy,signal})];}\r\n      catch(error){if(!signal.aborted)console.warn(`Offline pack unavailable: ${section.id}`,error);return [section.id,null];}\r\n    }));\r\n    if(refreshEpoch!==epoch||!allowed()||signal.aborted)return;\r\n    checking=null;\r\n    available=new Map(results.filter(([,value])=>value));\r\n    const failed=results.length-available.size;\r\n    render();\r\n    if(!available.size){retry.hidden=false;panel.hidden=false;status.textContent='Could not check offline packs. Check your connection, then try again.';}\r\n    else if(failed){retry.hidden=false;status.textContent=`${failed} of ${results.length} packs could not be checked. Try again for the rest.`;}\r\n    else if(!actions.childElementCount)panel.hidden=true;\r\n    else status.textContent='';\r\n  }\r\n  const onReady=event=>{currentAccount=event.detail;if(owner&&accountId(currentAccount)===owner){if(!controller&&!pausedIds&&!checking&&available.size<POST_DOWNLOAD_SECTIONS.length)void refresh();else render();return;}void refresh();};\r\n  const onCleared=()=>{currentAccount=null;void refresh();};\r\n  window.addEventListener('myr5:account-ready',onReady);window.addEventListener('myr5:account-cleared',onCleared);\r\n  void refresh();\r\n  return Object.freeze({panel,refresh,dispose(){disposed=true;++epoch;controller?.abort();checking?.abort();window.removeEventListener('myr5:account-ready',onReady);window.removeEventListener('myr5:account-cleared',onCleared);panel.remove();}});\r\n}\r\n","modules/materials/verified-bundle.mjs":"import { sha256Chunk } from './chunk-delivery.mjs';\r\n\r\n/** Decode the deterministic M5 bundle only after its enclosing asset passed ChunkDownloader verification. */\r\nexport async function unpackVerifiedBundle(value) {\r\n  const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);\r\n  if (bytes.byteLength < 6 || bytes.byteLength>64*1024*1024) throw new Error('verified bundle size exceeds policy');\r\n  const headerBytes = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);\r\n  if (headerBytes < 2 || headerBytes > 1024 * 1024 || headerBytes > bytes.byteLength - 4) throw new Error('invalid verified bundle index size');\r\n  const index = JSON.parse(new TextDecoder().decode(bytes.subarray(4,4+headerBytes)));\r\n  if (!index || typeof index !== 'object' || Array.isArray(index) || Object.keys(index).length > 512) throw new Error('invalid verified bundle index');\r\n  const contentStart=4+headerBytes, values=new Map(); let expectedOffset=0;\r\n  for (const [name,entry] of Object.entries(index)) {\r\n    if (!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(name) || name.includes('..') || name.includes('//') || name.endsWith('/') || name.length>300 || !entry || !Number.isSafeInteger(entry.offset) || entry.offset!==expectedOffset || !Number.isSafeInteger(entry.bytes) || entry.bytes<1 || !/^[a-f0-9]{64}$/.test(entry.sha256||'')) throw new Error(`invalid bundled entry: ${name}`);\r\n    const end=contentStart+entry.offset+entry.bytes;\r\n    if (end>bytes.byteLength) throw new Error(`truncated bundled entry: ${name}`);\r\n    const data=bytes.slice(contentStart+entry.offset,end);\r\n    if (await sha256Chunk(data)!==entry.sha256) throw new Error(`bundled entry integrity failure: ${name}`);\r\n    values.set(name,data); expectedOffset+=entry.bytes;\r\n  }\r\n  if(contentStart+expectedOffset!==bytes.byteLength)throw new Error('verified bundle has unindexed trailing bytes');\r\n  return values;\r\n}\r\n","modules/new/expansion-config.mjs":"// This value is replaced by the release build from PUBLIC_EXPANSION_SIGNING_JWK.\r\n// It is intentionally empty in source: an unconfigured build must not pretend to\r\n// have a production trust anchor. A public verification key is safe to ship; a\r\n// private signing key must never enter this repository or the build output.\r\nexport const BUILT_PUBLIC_EXPANSION_SIGNING_JWK = null;\r\n\r\nconst isUsablePublicKey = value => value && typeof value === 'object' && !Array.isArray(value)\r\n  && value.kty === 'OKP' && value.crv === 'Ed25519' && typeof value.x === 'string'\r\n  && /^[A-Za-z0-9_-]{43}$/.test(value.x) && !/^A+$/.test(value.x);\r\n\r\nexport function productionExpansionTrust() {\r\n  return isUsablePublicKey(BUILT_PUBLIC_EXPANSION_SIGNING_JWK) ? BUILT_PUBLIC_EXPANSION_SIGNING_JWK : null;\r\n}\r\n\r\nexport function validatePublicExpansionSigningKey(value) {\r\n  if (!isUsablePublicKey(value)) throw new Error('PUBLIC_EXPANSION_SIGNING_JWK must be an Ed25519 public JWK with a non-placeholder x value');\r\n  return Object.freeze({ kty: 'OKP', crv: 'Ed25519', x: value.x, ext: true });\r\n}\r\n","modules/new/expansion-entry.mjs":"import { hasPackGrant, accountPackGrants, packAccountIdentity } from '../../packs/pack-entitlements.mjs';\r\nimport { createIsolatedPackControl } from '../../packs/isolated-pack-control.mjs';\r\nimport { productionExpansionTrust } from './expansion-config.mjs';\r\n\r\nexport const EXPANSION_ID = 'mom-paper-tear';\r\nexport const MANIFEST_URL = '/modules/new/manifest.json';\r\nconst MAX_ASSET_BYTES = 512 * 1024, MAX_PACK_BYTES = 2 * 1024 * 1024;\r\n// Production trust comes only from the validated release-build public config,\r\n// never from a manifest-provided key. Null is deliberate fail-closed state.\r\nexport const PRODUCTION_EXPANSION_KEY = productionExpansionTrust();\r\nconst hex = value => typeof value === 'string' && /^[a-f0-9]{64}$/i.test(value);\r\nconst plain = value => value && typeof value === 'object' && !Array.isArray(value);\r\nconst b64 = value => typeof value === 'string' && /^[A-Za-z0-9+/]+={0,2}$/.test(value) && value.length >= 80;\r\nconst canonical = m => JSON.stringify({ packId:m.packId,version:m.version,minAppVersion:m.minAppVersion,sha256:m.sha256,alg:m.alg,keyId:m.keyId,assets:m.assets.map(({path,bytes,sha256})=>({path,bytes,sha256})) });\r\nconst safeAsset = a => plain(a) && typeof a.path === 'string' && /^assets\\/[a-zA-Z0-9][a-zA-Z0-9._/-]*$/.test(a.path) && !a.path.includes('..') && Number.isSafeInteger(a.bytes) && a.bytes > 0 && a.bytes <= MAX_ASSET_BYTES && hex(a.sha256);\r\n\r\n/** Shape checking is separate from cryptographic verification. `signed: true` never grants trust. */\r\nexport function isSignedExpansionManifest(value) {\r\n return plain(value) && value.packId === EXPANSION_ID && typeof value.version === 'string' && value.version.length <= 64 && typeof value.minAppVersion === 'string' && hex(value.sha256) && value.alg === 'Ed25519' && value.keyId === 'mom-paper-production-v1' && b64(value.signature) && Array.isArray(value.assets) && value.assets.length > 0 && value.assets.length <= 16 && value.assets.every(safeAsset) && value.assets.reduce((n,a)=>n+a.bytes,0) <= MAX_PACK_BYTES;\r\n}\r\nconst b64bytes = value => { const binary=typeof atob==='function'?atob(value):Buffer.from(value,'base64').toString('binary'); return Uint8Array.from(binary,c=>c.charCodeAt(0)); };\r\nasync function subtle(){if(!globalThis.crypto?.subtle)throw new Error('Web Crypto unavailable');return globalThis.crypto.subtle;}\r\nexport async function verifyExpansionManifest(manifest,key){\r\n if(!isSignedExpansionManifest(manifest)||!plain(key)||key.kty!=='OKP'||key.crv!=='Ed25519'||typeof key.x!=='string')return false;\r\n try{const crypto=await subtle(),trusted=await crypto.importKey('jwk',key,{name:'Ed25519'},false,['verify']);return await crypto.verify({name:'Ed25519'},trusted,b64bytes(manifest.signature),new TextEncoder().encode(canonical(manifest)));}catch{return false;}\r\n}\r\nfunction safeAssetUrl(path,base){const url=new URL(path,base);if(url.origin!==base.origin||!url.pathname.startsWith('/modules/new/assets/'))throw new Error('Expansion asset origin/path is not allowed');return url;}\r\n\r\n/** Tests may inject a test public key only with the explicit test-only purpose. Production remains fail-closed without a valid production signature. */\r\nexport async function resolveExpansionManifest({fetchImpl=globalThis.fetch,url=MANIFEST_URL,fixture=null,testTrust=null}={}){\r\n const trust=testTrust?.purpose==='test-only-signed-expansion'?testTrust.publicKey:(fixture?null:PRODUCTION_EXPANSION_KEY);\r\n if(!fixture&&!trust)throw new Error('Expansion unavailable: trusted production signing key is not configured');\r\n const manifest=fixture?.manifest??await(async()=>{if(typeof fetchImpl!=='function')throw new Error('Expansion manifest unavailable');const r=await fetchImpl(url,{cache:'no-store',credentials:'same-origin'});if(!r.ok)throw new Error(`Expansion manifest unavailable (${r.status})`);return r.json();})();\r\n if(!(await verifyExpansionManifest(manifest,trust)))throw new Error('Expansion manifest signature is invalid');\r\n if(fixture){if(!testTrust)throw new Error('Expansion fixture requires explicit test-only trust');return {manifest,source:fixture.source};}\r\n const base=new URL(url,globalThis.location?.origin||'http://localhost');\r\n return {manifest,source:{async get(asset,previous){\r\n  const offset=previous?.byteLength||0;\r\n  if(offset>=asset.bytes)throw new Error('Invalid expansion resume offset');\r\n  const r=await fetchImpl(safeAssetUrl(asset.path,base),{cache:'no-store',credentials:'same-origin',redirect:'error',headers:offset?{Range:`bytes=${offset}-`}:undefined});\r\n  if(!r.ok||r.redirected||![200,206].includes(r.status))throw new Error(`Asset unavailable (${r.status})`);\r\n  const body=new Uint8Array(await r.arrayBuffer());\r\n  // Servers may ignore Range. A 200 is a complete replacement, never a suffix.\r\n  if(r.status===200){if(body.byteLength!==asset.bytes)throw new Error('Expansion asset length does not match manifest');return body;}\r\n  const range=/^bytes (\\d+)-(\\d+)\\/(\\d+)$/.exec(r.headers?.get('content-range')||'');\r\n  if(!range||Number(range[1])!==offset||Number(range[2])!==asset.bytes-1||Number(range[3])!==asset.bytes||body.byteLength!==asset.bytes-offset)throw new Error('Expansion Content-Range does not match manifest');\r\n  return offset?new Uint8Array([...previous,...body]):body;\r\n }}};\r\n}\r\n\r\n// The pull and the reveal go down the phone, following the user's finger.\r\nexport function tearProgress(start,point,safeHeight=400){return !start||!point?0:Math.max(0,Math.min(1,(point.y-start.y)/Math.max(96,safeHeight*.28)));}\r\nexport function createPaperTearShell({document:doc=globalThis.document,onOpen=()=>{}}={}){\r\n if(!doc)return null;const shell=doc.createElement('section');shell.className='mom-paper-expansion';shell.setAttribute('aria-label','MOM paper expansion');shell.hidden=true;shell.innerHTML='<div class=\"paper-top-safe-area\"><button type=\"button\" class=\"paper-logo\" aria-label=\"Pull MOM paper expansion down to open\"><span aria-hidden=\"true\">MOM</span><small>PULL DOWN TO OPEN</small></button></div><p class=\"paper-status\" role=\"status\"></p><div class=\"dimension-shell\" hidden><div class=\"dimension-slot\" aria-label=\"Expansion scene slot\">COACH POD // PAPER DIMENSION</div><button type=\"button\" class=\"paper-reopen\">Close paper dimension</button></div>';\r\n const logo=shell.querySelector('.paper-logo'),status=shell.querySelector('.paper-status'),dimension=shell.querySelector('.dimension-shell');let start=null;const cancel=()=>{start=null;shell.classList.remove('paper-tearing');logo.style.removeProperty('--tear-progress');status.textContent='Pull canceled. Paper restored.';},open=()=>{dimension.hidden=false;logo.hidden=true;status.textContent='Paper dimension open.';onOpen(dimension);};\r\n logo.addEventListener('pointerdown',e=>{try{logo.setPointerCapture?.(e.pointerId);}catch{}start={x:e.clientX,y:e.clientY};shell.classList.add('paper-tearing');status.textContent='Pull down to tear.';});logo.addEventListener('pointermove',e=>{if(start)logo.style.setProperty('--tear-progress',tearProgress(start,{x:e.clientX,y:e.clientY},shell.clientHeight||400));});logo.addEventListener('pointerup',e=>{if(!start)return;const progress=tearProgress(start,{x:e.clientX,y:e.clientY},shell.clientHeight||400);start=null;shell.classList.remove('paper-tearing');logo.style.removeProperty('--tear-progress');if(progress>=.72)open();else cancel();});logo.addEventListener('pointercancel',cancel);shell.querySelector('.paper-reopen').addEventListener('click',()=>{dimension.hidden=true;logo.hidden=false;status.textContent='Paper restored. Pull down to reopen.';});logo.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();open();}});return shell;\r\n}\r\nexport function mountExpansion({account,workoutOwner,workout,storage,assetStore,fetchImpl,fixture,testTrust,events=globalThis.window,host=globalThis.document?.querySelector('.crew-footer')}={}){\r\n if(!host||!hasPackGrant(account,EXPANSION_ID))return null;\r\n const doc=host.ownerDocument,panel=doc.createElement('section');panel.className='expansion-control';panel.setAttribute('aria-label','Optional MOM paper expansion');panel.innerHTML='<h2>OPTIONAL PAPER DIMENSION</h2><p data-expansion-copy>Verified pack access. Download the optional expansion when ready.</p><button type=\"button\" data-expansion-download>Download optional expansion</button><p data-expansion-status role=\"status\"></p>';host.before(panel);\r\n const button=panel.querySelector('[data-expansion-download]'),status=panel.querySelector('[data-expansion-status]');\r\n const trust=testTrust?.purpose==='test-only-signed-expansion'?testTrust.publicKey:(fixture?null:PRODUCTION_EXPANSION_KEY);\r\n let control=null,shell=null,generation=0,disposed=false,ready;\r\n const identity=packAccountIdentity;\r\n let observedIdentity=identity(account),observedDataEpoch=account?.dataEpoch;\r\n const paint=v=>{if(!v)return;status.textContent=v.error||`${v.state}${v.receivedBytes?` · ${v.receivedBytes} bytes`:''}`;button.disabled=['downloading','verified','pending-equip','active'].includes(v.state);if(v.state==='active'){panel.querySelector('[data-expansion-copy]').textContent='Verified optional expansion active.';if(shell)shell.hidden=false;}};\r\n const runtimeFactory=async()=>{\r\n  const prepared=createPaperTearShell({document:doc});\r\n  return {activate(){shell=prepared;panel.append(prepared);prepared.hidden=false;},dispose(){prepared?.remove();if(shell===prepared)shell=null;}};\r\n };\r\n const setup=async({activateAtBoot=false}={})=>{\r\n  const ticket=++generation;\r\n  control?.dispose();\r\n  let life;\r\n  const current=()=>!disposed&&ticket===generation&&control===life&&hasPackGrant(account,EXPANSION_ID);\r\n  button.disabled=true;status.textContent='Checking signed expansion manifest\\u2026';\r\n  try{\r\n   life=createIsolatedPackControl({account:{getIdentity:()=>identity(account),getGeneration:()=>JSON.stringify([generation,account?.dataEpoch??null]),getEntitlements:()=>!disposed?accountPackGrants(account):[]},workout,workoutOwner,storage,assetStore,runtimeFactory,verifyManifest:manifest=>verifyExpansionManifest(manifest,trust),onChange:value=>{if(ticket===generation&&!disposed)paint(value);}});\r\n   control=life;\r\n   // Restore exact signed metadata and bytes before attempting any network call.\r\n   if(activateAtBoot){\r\n    if(life.pending)await life.restart();\r\n    if(!current())return;\r\n    if(!life.runtime&&life.equipped)await life.restore();\r\n    if(!current())return;\r\n    paint(life.status(EXPANSION_ID));\r\n   }\r\n   const entry=await resolveExpansionManifest({fetchImpl,fixture,testTrust});\r\n   if(!current())return;\r\n   life.manifest(entry.manifest,entry.source);paint(life.status(EXPANSION_ID));\r\n  }catch(error){\r\n   if(disposed||ticket!==generation||!hasPackGrant(account,EXPANSION_ID))return;\r\n   if(life?.runtime){paint(life.status(EXPANSION_ID));return;}\r\n   status.textContent=error.message||'Production expansion unavailable.';button.disabled=false;\r\n  }\r\n };\r\n button.addEventListener('click',async()=>{\r\n  const life=control,ticket=generation;\r\n  const current=()=>!disposed&&ticket===generation&&life===control&&hasPackGrant(account,EXPANSION_ID);\r\n  if(!life?.manifests.has(EXPANSION_ID)){ready=setup();return ready;}\r\n  button.disabled=true;\r\n  try{\r\n   const downloaded=await life.download(EXPANSION_ID);if(!current())return;paint(downloaded);\r\n   const verified=await life.verify(EXPANSION_ID);if(!current())return;paint(verified);\r\n   const pending=await life.equipPending(EXPANSION_ID);if(!current())return;paint(pending);\r\n   status.textContent='Verified and saved as pending. Reload Coach to activate.';button.disabled=false;\r\n  }catch(error){if(current()){status.textContent=error.message||'Download failed. Tap to retry.';button.disabled=false;}}\r\n });\r\n const clear=()=>{generation++;control?.dispose();control=null;account=null;panel.hidden=true;};\r\n const accountReady=event=>{\r\n  const next=event.detail,changed=identity(next)!==observedIdentity||next?.dataEpoch!==observedDataEpoch;\r\n  account=next;observedIdentity=identity(next);observedDataEpoch=next?.dataEpoch;\r\n  if(!hasPackGrant(account,EXPANSION_ID)){clear();return;}\r\n  panel.hidden=false;\r\n  if(changed||!control){ready=setup({activateAtBoot:true});}\r\n };\r\n events?.addEventListener?.('myr5:account-cleared',clear);\r\n events?.addEventListener?.('myr5:account-ready',accountReady);\r\n // Assets are fetched only by the explicit Download action. Restored or pending\r\n // packs still require the workout owner's held idle lease at boot.\r\n ready=setup({activateAtBoot:true});\r\n return {panel,get lifecycle(){return control;},get ready(){return ready;},dispose(){disposed=true;clear();events?.removeEventListener?.('myr5:account-cleared',clear);events?.removeEventListener?.('myr5:account-ready',accountReady);panel.remove();}};\r\n}\r\nif(typeof document!=='undefined'){const style=document.createElement('link');style.rel='stylesheet';style.href=new URL('./expansion.css',import.meta.url);document.head.append(style);}\r\n","modules/new/expansion.css":".expansion-control,.mom-paper-expansion{max-width:42rem;margin:1rem auto;padding:1rem;border:1px solid #7b5265;background:#241827;color:#f5e4ba}.expansion-control h2{font-size:.8rem;letter-spacing:.12em}.expansion-control button,.paper-reopen{min-height:48px;padding:.7rem 1rem;background:#b8e9cf;color:#17111e;border:0;font-weight:700}.paper-top-safe-area{padding:env(safe-area-inset-top,8px) 8px 8px;min-height:74px}.paper-logo{min-height:48px;width:min(142px,100%);border:2px dashed #efc56d;background:#f5e4ba;color:#241827;touch-action:none;transform:translateY(calc(var(--tear-progress,0) * 22px));clip-path:inset(0 0 calc((1 - var(--tear-progress,0)) * 42%) 0);transition:transform .12s ease,clip-path .12s ease}.paper-logo span{display:block;font-weight:900;letter-spacing:.18em}.paper-logo small{font-size:.6rem}.paper-status{min-height:1.5em}.dimension-shell{padding:1rem;border:1px solid #b8e9cf}.dimension-slot{min-height:120px;display:grid;place-items:center;border:1px dotted #efc56d;letter-spacing:.1em}.paper-reopen{margin-top:1rem;background:transparent;color:#b8e9cf;border:1px solid #b8e9cf}@media(prefers-reduced-motion:reduce){.paper-logo{transition:none}.paper-tearing .paper-logo{transform:none}}\r\n","modules/phone-orientation.mjs":"const PHONE_UA=/(?:iPhone|iPod|Android.*Mobile)/i;\r\nconst NOTICE_STYLE=`\r\n[data-phone-portrait-notice]{box-sizing:border-box;position:fixed;inset:0;width:100vw;height:100vh;height:100dvh;max-width:none;max-height:none;margin:0;padding:max(24px,env(safe-area-inset-top)) 24px max(24px,env(safe-area-inset-bottom));border:0;border-radius:0;background:#110d1df5;color:#fff4d8;box-shadow:none;font:700 clamp(22px,6vw,34px)/1.35 system-ui,sans-serif;text-align:center;display:grid;place-items:center;z-index:2147483647;}\r\n[data-phone-portrait-notice]::backdrop{background:#090611eF}\r\n[data-phone-portrait-notice][hidden]{display:none!important}\r\n`;\r\n\r\nexport function isPhone(navigator=globalThis.navigator){\r\n return navigator?.userAgentData?.mobile===true||PHONE_UA.test(navigator?.userAgent||'');\r\n}\r\n\r\n// Use physical orientation signals only. innerWidth/innerHeight and visualViewport can flip\r\n// while the on-screen keyboard is open, which must never trigger the rotate notice.\r\nexport function isPhysicalLandscape(screen=globalThis.screen,win=globalThis.window){\r\n const type=screen?.orientation?.type;\r\n if(typeof type==='string'&&type.startsWith('landscape'))return true;\r\n if(typeof type==='string'&&type.startsWith('portrait'))return false;\r\n const angle=win?.orientation;\r\n return typeof angle==='number'&&Math.abs(angle)%180===90;\r\n}\r\n\r\nexport function mountPhoneOrientation(){\r\n const win=globalThis.window,doc=globalThis.document,nav=globalThis.navigator,scr=globalThis.screen;\r\n if(!win||!doc||!isPhone(nav))return()=>{};\r\n const orientation=scr?.orientation;\r\n const notice=doc.createElement('dialog');notice.dataset.phonePortraitNotice='';notice.setAttribute('role','alert');notice.setAttribute('aria-live','assertive');\r\n notice.textContent='Rotate your phone upright to continue.';\r\n if(typeof notice.showPopover==='function')notice.setAttribute('popover','manual');\r\n let style=doc.querySelector('style[data-phone-orientation-style]'),ownsStyle=!style;\r\n if(!style){style=doc.createElement('style');style.dataset.phoneOrientationStyle='';style.textContent=NOTICE_STYLE;doc.head.append(style);}\r\n doc.body.append(notice);\r\n let disposed=false,locked=false,pending=false,gestureUsed=false,restacking=false,shown=false,modalFallback=false;\r\n const open=()=>{try{return notice.open||notice.matches(':popover-open');}catch{return notice.open||(!notice.hidden&&shown);}};\r\n const anotherModalOpen=()=>[...doc.querySelectorAll('dialog[open]')].some(dialog=>dialog!==notice&&dialog.matches(':modal'));\r\n function show(){\r\n  if(disposed)return;\r\n  notice.hidden=false;\r\n  // A popover opened outside a modal dialog's top layer can be inert in Chromium.\r\n  // Promote the guard to a modal dialog whenever an app dialog is already active.\r\n  if(anotherModalOpen()){\r\n   if(notice.matches?.(':popover-open'))try{notice.hidePopover();}catch{}\r\n   showModalFallback();return;\r\n  }\r\n  if(typeof notice.showPopover==='function'){\r\n   if(!open())try{notice.showPopover();shown=true;}catch{showModalFallback();}\r\n  }else showModalFallback();\r\n }\r\n function showModalFallback(){if(disposed)return;try{if(!notice.open){notice.showModal();modalFallback=true;}shown=true;}catch{notice.hidden=false;shown=true;}}\r\n function hide(){\r\n  if(typeof notice.hidePopover==='function'&&open())try{notice.hidePopover();}catch{}\r\n  if(notice.open)try{notice.close();}catch{}\r\n  notice.hidden=true;shown=false;\r\n }\r\n function updateNotice(){if(isPhysicalLandscape(scr,win))show();else hide();}\r\n function restack(){\r\n  if(disposed||restacking||!isPhysicalLandscape(scr,win)||!open())return;\r\n  restacking=true;\r\n  try{\r\n   if(anotherModalOpen()&&notice.matches(':popover-open')){notice.hidePopover();showModalFallback();}\r\n   else if(notice.matches(':popover-open')&&typeof notice.hidePopover==='function'){notice.hidePopover();notice.showPopover();}\r\n   else if(notice.open&&modalFallback){notice.close();notice.showModal();}\r\n   shown=true;\r\n  }catch{}\r\n  queueMicrotask(()=>{restacking=false;});\r\n }\r\n async function requestLock(){\r\n  if(disposed||pending||locked||typeof orientation?.lock!=='function'){updateNotice();return false;}\r\n  pending=true;\r\n  try{await orientation.lock.call(orientation,'portrait-primary');if(disposed){try{orientation.unlock?.call(orientation);}catch{}return false;}locked=true;updateNotice();return true;}\r\n  catch{if(!disposed)updateNotice();return false;}\r\n  finally{pending=false;}\r\n }\r\n function firstGesture(){if(gestureUsed)return;gestureUsed=true;void requestLock();}\r\n function blockLandscapeKeys(event){if(!disposed&&isPhysicalLandscape(scr,win)&&open()){event.preventDefault();event.stopImmediatePropagation();}}\r\n function onFullscreen(){if(!doc.fullscreenElement)locked=false;void requestLock();updateNotice();}\r\n function onOrientation(){updateNotice();}\r\n function onTopLayerChange(event){\r\n  if(event.target===notice)return;\r\n  const target=event.target;if(target?.matches?.('dialog[open]')){queueMicrotask(restack);return;}\r\n  try{if(target?.matches?.('[popover]:popover-open'))queueMicrotask(restack);}catch{}\r\n }\r\n const layers=new MutationObserver(records=>{\r\n  if(records.some(record=>record.target!==notice&&record.target?.tagName==='DIALOG'&&record.attributeName==='open'&&record.target.open))queueMicrotask(restack);\r\n });\r\n layers.observe(doc.body,{subtree:true,attributes:true,attributeFilter:['open']});\r\n win.addEventListener('pointerdown',firstGesture,{capture:true,once:true});\r\n win.addEventListener('keydown',firstGesture,{capture:true,once:true});\r\n win.addEventListener('keydown',blockLandscapeKeys,true);\r\n win.addEventListener('orientationchange',onOrientation);\r\n win.addEventListener('resize',onOrientation); // the physical orientation check ignores keyboard-only viewport changes\r\n doc.addEventListener('fullscreenchange',onFullscreen);\r\n doc.addEventListener('toggle',onTopLayerChange,true);\r\n orientation?.addEventListener?.('change',onOrientation);\r\n void requestLock();\r\n updateNotice();\r\n return()=>{\r\n  if(disposed)return;disposed=true;layers.disconnect();\r\n  win.removeEventListener('pointerdown',firstGesture,true);win.removeEventListener('keydown',firstGesture,true);\r\n  win.removeEventListener('keydown',blockLandscapeKeys,true);\r\n  win.removeEventListener('orientationchange',onOrientation);win.removeEventListener('resize',onOrientation);\r\n  doc.removeEventListener('fullscreenchange',onFullscreen);doc.removeEventListener('toggle',onTopLayerChange,true);\r\n  orientation?.removeEventListener?.('change',onOrientation);\r\n  if(locked)try{orientation?.unlock?.call(orientation);}catch{}\r\n  if(typeof notice.hidePopover==='function'&&open())try{notice.hidePopover();}catch{}\r\n  if(notice.open)try{notice.close();}catch{}\r\n  notice.remove();\r\n  if(ownsStyle)style?.remove();\r\n };\r\n}\r\n","modules/pod-chrome.mjs":"// A single set of controls follows the active top-layer menu; no duplicate buttons.\r\nexport function mountPodChrome(grimoireButton,{signal}={}){\r\n const doc=grimoireButton.ownerDocument;\r\n let nav=doc.getElementById('podPersistentChrome');\r\n if(nav){\r\n  const current=nav.querySelector('.metal-grimoire-key');\r\n  if(current!==grimoireButton){\r\n   grimoireButton.classList.add('metal-grimoire-key');\r\n   grimoireButton.hidden=!nav.classList.contains('frame-mounted');\r\n   current?.replaceWith(grimoireButton);\r\n   // A lazy pod key stays available if the heavyweight portal is later disposed.\r\n   const fallback=nav._lazyGrimoireButton;\r\n   if(fallback&&signal)signal.addEventListener('abort',()=>{\r\n    if(nav.isConnected&&grimoireButton.parentNode===nav){fallback.hidden=grimoireButton.hidden;grimoireButton.replaceWith(fallback);}\r\n   },{once:true});\r\n  }\r\n  return nav;\r\n }\r\n // The mark already says MOM INC. Keep the real home link and its image, but clear\r\n // the duplicate wordmark and location caption from the visible ship header.\r\n const brand=doc.querySelector('.ship-header .mom-brand');\r\n brand?.querySelectorAll(':scope > span').forEach(text=>text.remove());\r\n if(brand){brand.setAttribute('aria-label','Return to the pod');brand.querySelector('img')?.setAttribute('alt','MOM Inc');}\r\n doc.querySelectorAll('.ship-header .ship-location').forEach(location=>location.remove());\r\n const settingsKey=doc.getElementById('openSettings');\r\n if(settingsKey){\r\n  settingsKey.classList.add('ship-settings-toggle');\r\n  settingsKey.setAttribute('aria-label','Open settings terminal');\r\n  settingsKey.setAttribute('aria-haspopup','dialog');\r\n  settingsKey.setAttribute('aria-controls','settings');\r\n  const handle=doc.createElement('span');handle.className='ship-settings-handle';handle.setAttribute('aria-hidden','true');\r\n  const screen=doc.createElement('span');screen.className='ship-settings-screen';screen.setAttribute('aria-hidden','true');\r\n  const status=doc.createElement('small');status.textContent='SHIP SYSTEMS';\r\n  const title=doc.createElement('strong');title.textContent='SETTINGS';screen.append(status,title);\r\n  settingsKey.replaceChildren(handle,screen);\r\n }\r\n doc.getElementById('coachDock')?.classList.add('ship-control-deck');\r\n nav=doc.createElement('nav');nav.id='podPersistentChrome';nav.className='pod-persistent-chrome';nav.setAttribute('aria-label','Pod terminals');\r\n grimoireButton.classList.add('metal-grimoire-key');\r\n if(grimoireButton.id==='podGrimoireLazyOpen')nav._lazyGrimoireButton=grimoireButton;\r\n const playing=doc.createElement('button');playing.type='button';playing.id='spotifyNowPlayingOpen';playing.className='pod-now-playing';playing.setAttribute('aria-label','Open actual.dj');\r\n const caption=doc.createElement('small');caption.textContent='NOW PLAYING';\r\n const label=doc.createElement('span');label.id='spotifyNowPlayingLabel';label.textContent='actual.dj';playing.append(caption,label);nav.append(grimoireButton,playing);doc.body.append(nav);\r\n const move=()=>{\r\n  const settings=doc.getElementById('settings');\r\n  if(settingsKey)settingsKey.setAttribute('aria-expanded',String(!!settings?.open));\r\n  const dialogs=[...doc.querySelectorAll('dialog[open]')].filter(d=>!d.matches('[data-phone-portrait-notice],#coachGate'));\r\n  const active=dialogs.at(-1);\r\n  const portal=doc.getElementById('portalHome');\r\n  const housing=doc.getElementById('portalChrome');\r\n  const cutaway=active?.classList.contains('portal-shaped')&&!active.classList.contains('portal-fullscreen');\r\n  const frame=cutaway?housing?.querySelector('.portal-frame'):!active&&portal&&!portal.hidden?portal.querySelector('#portalBoardHost > .portal-frame'):null;\r\n  // The board's frame sits below its full-screen drawing canvas. Keep interactive\r\n  // terminals in the portal's control layer, outside that lower stacking context.\r\n  const owner=frame&&frame.closest('#portalHome')?portal:frame||(!active?doc.querySelector('.ship-header'):null)||doc.body;\r\n  // Native modal dialogs make external controls inert, even in a raised popover.\r\n  // Hide those keys until returning to the Grimoire rather than draw dead buttons.\r\n  nav.hidden=!!active&&(!cutaway||active.matches(':modal'));\r\n  nav.classList.toggle('frame-mounted',!!frame);\r\n  const grimoireKey=nav.querySelector('.metal-grimoire-key');\r\n  if(grimoireKey)grimoireKey.hidden=!frame;\r\n  if(frame){frame.removeAttribute('aria-hidden');housing?.removeAttribute('aria-hidden');}\r\n  if(nav.parentNode!==owner)owner.append(nav);\r\n  for(const dialog of dialogs)if(dialog.classList.contains('has-pod-chrome'))dialog.classList.remove('has-pod-chrome');\r\n };\r\n const observer=new MutationObserver(records=>{if(records.some(r=>r.target!==nav&&!nav.contains(r.target)))move();});observer.observe(doc.body,{subtree:true,childList:true,attributes:true,attributeFilter:['open','hidden','class']});\r\n const close=()=>queueMicrotask(move);doc.addEventListener('close',close,true);\r\n const dispose=()=>{observer.disconnect();doc.removeEventListener('close',close,true);nav.remove();};\r\n signal?.addEventListener('abort',dispose,{once:true});move();return nav;\r\n}\r\n","modules/portal/cracked-glass-core.mjs":"// Cracked-glass fracture core, vendored unchanged from https://github.com/kossik/cracked-glass v0.7.0 (commit 6cb13c6932eba3e532c52115efdddcef2b79cbf7), MIT licence — see LICENSES/cracked-glass.txt.\r\n// src/core/math.ts\r\nvar TAU = Math.PI * 2;\r\nfunction clamp(v, lo, hi) {\r\n  return v < lo ? lo : v > hi ? hi : v;\r\n}\r\nfunction clamp01(v) {\r\n  return v < 0 ? 0 : v > 1 ? 1 : v;\r\n}\r\nfunction lerp(a, b, t) {\r\n  return a + (b - a) * t;\r\n}\r\nfunction degToRad(d) {\r\n  return d * Math.PI / 180;\r\n}\r\nfunction smoothstep(t) {\r\n  const x = clamp01(t);\r\n  return x * x * (3 - 2 * x);\r\n}\r\nfunction easeOutCubic(t) {\r\n  const x = clamp01(t);\r\n  return 1 - (1 - x) * (1 - x) * (1 - x);\r\n}\r\nfunction easeOutQuart(t) {\r\n  const x = clamp01(t);\r\n  const y = 1 - x;\r\n  return 1 - y * y * y * y;\r\n}\r\nfunction easeOutExpo(t) {\r\n  const x = clamp01(t);\r\n  return x >= 1 ? 1 : 1 - Math.pow(2, -10 * x);\r\n}\r\nfunction fmt(n, precision = 2) {\r\n  if (!Number.isFinite(n)) return \"0\";\r\n  let s = n.toFixed(precision);\r\n  if (s.indexOf(\".\") >= 0) {\r\n    s = s.replace(/0+$/, \"\");\r\n    if (s.endsWith(\".\")) s = s.slice(0, -1);\r\n  }\r\n  if (s === \"-0\") s = \"0\";\r\n  return s;\r\n}\r\n\r\n// src/core/geometry.ts\r\nfunction signedArea(poly) {\r\n  let a = 0;\r\n  for (let i = 0; i < poly.length; i++) {\r\n    const p = poly[i];\r\n    const q = poly[(i + 1) % poly.length];\r\n    a += p[0] * q[1] - q[0] * p[1];\r\n  }\r\n  return a / 2;\r\n}\r\nfunction ensurePositiveWinding(poly) {\r\n  return signedArea(poly) >= 0 ? poly : poly.slice().reverse();\r\n}\r\nfunction pointInPolygon(p, poly) {\r\n  let inside = false;\r\n  const n = poly.length;\r\n  for (let i = 0, j = n - 1; i < n; j = i++) {\r\n    const a = poly[i];\r\n    const b = poly[j];\r\n    if (a[1] > p[1] !== b[1] > p[1]) {\r\n      const x = (b[0] - a[0]) * (p[1] - a[1]) / (b[1] - a[1]) + a[0];\r\n      if (p[0] < x) inside = !inside;\r\n    }\r\n  }\r\n  return inside;\r\n}\r\nfunction polygonCentroid(poly) {\r\n  let a = 0;\r\n  let cx = 0;\r\n  let cy = 0;\r\n  for (let i = 0; i < poly.length; i++) {\r\n    const p = poly[i];\r\n    const q = poly[(i + 1) % poly.length];\r\n    const cross = p[0] * q[1] - q[0] * p[1];\r\n    a += cross;\r\n    cx += (p[0] + q[0]) * cross;\r\n    cy += (p[1] + q[1]) * cross;\r\n  }\r\n  a /= 2;\r\n  if (Math.abs(a) < 1e-9) {\r\n    let sx = 0;\r\n    let sy = 0;\r\n    for (const p of poly) {\r\n      sx += p[0];\r\n      sy += p[1];\r\n    }\r\n    return [sx / poly.length, sy / poly.length];\r\n  }\r\n  return [cx / (6 * a), cy / (6 * a)];\r\n}\r\nfunction dedupePolygon(poly, eps = 1e-7) {\r\n  const out = [];\r\n  for (const p of poly) {\r\n    const last = out[out.length - 1];\r\n    if (!last || Math.abs(last[0] - p[0]) > eps || Math.abs(last[1] - p[1]) > eps) {\r\n      out.push(p);\r\n    }\r\n  }\r\n  if (out.length > 1) {\r\n    const first = out[0];\r\n    const last = out[out.length - 1];\r\n    if (Math.abs(first[0] - last[0]) <= eps && Math.abs(first[1] - last[1]) <= eps) {\r\n      out.pop();\r\n    }\r\n  }\r\n  return out;\r\n}\r\nfunction clipPolygonToRect(poly, w, h) {\r\n  const edges = [\r\n    { inside: (p) => p[0] >= 0, cut: (a, b) => cutX(a, b, 0) },\r\n    { inside: (p) => p[0] <= w, cut: (a, b) => cutX(a, b, w) },\r\n    { inside: (p) => p[1] >= 0, cut: (a, b) => cutY(a, b, 0) },\r\n    { inside: (p) => p[1] <= h, cut: (a, b) => cutY(a, b, h) }\r\n  ];\r\n  let cur = poly;\r\n  for (const e of edges) {\r\n    if (cur.length === 0) return [];\r\n    const next = [];\r\n    for (let i = 0; i < cur.length; i++) {\r\n      const a = cur[i];\r\n      const b = cur[(i + 1) % cur.length];\r\n      const ain = e.inside(a);\r\n      const bin = e.inside(b);\r\n      if (ain) {\r\n        next.push(a);\r\n        if (!bin) next.push(e.cut(a, b));\r\n      } else if (bin) {\r\n        next.push(e.cut(a, b));\r\n      }\r\n    }\r\n    cur = next;\r\n  }\r\n  return dedupePolygon(cur);\r\n}\r\nfunction cutX(a, b, x) {\r\n  const t = (x - a[0]) / (b[0] - a[0]);\r\n  return [x, a[1] + (b[1] - a[1]) * t];\r\n}\r\nfunction cutY(a, b, y) {\r\n  const t = (y - a[1]) / (b[1] - a[1]);\r\n  return [a[0] + (b[0] - a[0]) * t, y];\r\n}\r\nfunction offsetPolygon(poly, dist, miterLimit = 3) {\r\n  const n = poly.length;\r\n  if (n < 3 || dist === 0) return poly.slice();\r\n  const out = [];\r\n  for (let i = 0; i < n; i++) {\r\n    const prev = poly[(i - 1 + n) % n];\r\n    const v = poly[i];\r\n    const next = poly[(i + 1) % n];\r\n    const n1 = edgeOutwardNormal(prev, v);\r\n    const n2 = edgeOutwardNormal(v, next);\r\n    let mx = n1[0] + n2[0];\r\n    let my = n1[1] + n2[1];\r\n    const ml = Math.hypot(mx, my);\r\n    if (ml < 1e-9) {\r\n      mx = n1[0];\r\n      my = n1[1];\r\n    } else {\r\n      mx /= ml;\r\n      my /= ml;\r\n    }\r\n    const dot = mx * n1[0] + my * n1[1];\r\n    let scale = dot > 1e-6 ? 1 / dot : miterLimit;\r\n    if (scale > miterLimit) scale = miterLimit;\r\n    out.push([v[0] + mx * dist * scale, v[1] + my * dist * scale]);\r\n  }\r\n  return out;\r\n}\r\nfunction edgeOutwardNormal(a, b) {\r\n  const dx = b[0] - a[0];\r\n  const dy = b[1] - a[1];\r\n  const l = Math.hypot(dx, dy);\r\n  if (l < 1e-9) return [0, 0];\r\n  return [dy / l, -dx / l];\r\n}\r\nfunction segmentIntersection(a1, a2, b1, b2) {\r\n  const dax = a2[0] - a1[0];\r\n  const day = a2[1] - a1[1];\r\n  const dbx = b2[0] - b1[0];\r\n  const dby = b2[1] - b1[1];\r\n  const den = dax * dby - day * dbx;\r\n  if (Math.abs(den) < 1e-12) return null;\r\n  const ex = b1[0] - a1[0];\r\n  const ey = b1[1] - a1[1];\r\n  const ta = (ex * dby - ey * dbx) / den;\r\n  const tb = (ex * day - ey * dax) / den;\r\n  if (ta < -1e-9 || ta > 1 + 1e-9 || tb < -1e-9 || tb > 1 + 1e-9) return null;\r\n  return { p: [a1[0] + dax * ta, a1[1] + day * ta], ta, tb };\r\n}\r\nfunction cumulativeLengths(pts) {\r\n  const cum = [0];\r\n  for (let i = 1; i < pts.length; i++) {\r\n    cum.push(cum[i - 1] + Math.hypot(pts[i][0] - pts[i - 1][0], pts[i][1] - pts[i - 1][1]));\r\n  }\r\n  return cum;\r\n}\r\nfunction pointAtLength(pts, cum, len) {\r\n  const total = cum[cum.length - 1];\r\n  if (len <= 0) return pts[0];\r\n  if (len >= total) return pts[pts.length - 1];\r\n  let lo = 0;\r\n  let hi = cum.length - 1;\r\n  while (lo + 1 < hi) {\r\n    const mid = lo + hi >> 1;\r\n    if (cum[mid] <= len) lo = mid;\r\n    else hi = mid;\r\n  }\r\n  const segLen = cum[hi] - cum[lo];\r\n  const t = segLen > 1e-12 ? (len - cum[lo]) / segLen : 0;\r\n  return [\r\n    pts[lo][0] + (pts[hi][0] - pts[lo][0]) * t,\r\n    pts[lo][1] + (pts[hi][1] - pts[lo][1]) * t\r\n  ];\r\n}\r\nfunction tangentAtLength(pts, cum, len) {\r\n  let lo = 0;\r\n  let hi = cum.length - 1;\r\n  if (len <= 0) hi = 1;\r\n  else if (len >= cum[cum.length - 1]) lo = cum.length - 2;\r\n  else {\r\n    while (lo + 1 < hi) {\r\n      const mid = lo + hi >> 1;\r\n      if (cum[mid] <= len) lo = mid;\r\n      else hi = mid;\r\n    }\r\n  }\r\n  const dx = pts[hi][0] - pts[lo][0];\r\n  const dy = pts[hi][1] - pts[lo][1];\r\n  const l = Math.hypot(dx, dy) || 1;\r\n  return [dx / l, dy / l];\r\n}\r\nfunction toCssPolygon(poly, precision = 2) {\r\n  const parts = [];\r\n  for (let i = 0; i + 1 < poly.length; i += 2) {\r\n    parts.push(`${fmt(poly[i], precision)}px ${fmt(poly[i + 1], precision)}px`);\r\n  }\r\n  return `polygon(${parts.join(\", \")})`;\r\n}\r\nfunction toSvgPathD(poly, closed, precision = 2) {\r\n  if (poly.length < 2) return \"\";\r\n  let d = `M${fmt(poly[0], precision)} ${fmt(poly[1], precision)}`;\r\n  for (let i = 2; i + 1 < poly.length; i += 2) {\r\n    d += `L${fmt(poly[i], precision)} ${fmt(poly[i + 1], precision)}`;\r\n  }\r\n  return closed ? d + \"Z\" : d;\r\n}\r\nfunction insetPolygonTowardCentroid(flat, centroid, inset) {\r\n  const out = [];\r\n  for (let i = 0; i + 1 < flat.length; i += 2) {\r\n    const dx = centroid[0] - flat[i];\r\n    const dy = centroid[1] - flat[i + 1];\r\n    const d = Math.hypot(dx, dy) || 1;\r\n    const m = Math.min(inset, d * 0.45) / d;\r\n    out.push(flat[i] + dx * m, flat[i + 1] + dy * m);\r\n  }\r\n  return out;\r\n}\r\nfunction reverseFlat(flat) {\r\n  const out = [];\r\n  for (let i = flat.length - 2; i >= 0; i -= 2) {\r\n    out.push(flat[i], flat[i + 1]);\r\n  }\r\n  return out;\r\n}\r\nfunction ringPathD(outerFlat, innerFlat) {\r\n  return toSvgPathD(outerFlat, true) + toSvgPathD(reverseFlat(innerFlat), true);\r\n}\r\nfunction toSvgPoints(poly, precision = 2) {\r\n  const parts = [];\r\n  for (let i = 0; i + 1 < poly.length; i += 2) {\r\n    parts.push(`${fmt(poly[i], precision)},${fmt(poly[i + 1], precision)}`);\r\n  }\r\n  return parts.join(\" \");\r\n}\r\nfunction flattenPts(pts) {\r\n  const out = [];\r\n  for (const p of pts) {\r\n    out.push(p[0], p[1]);\r\n  }\r\n  return out;\r\n}\r\nfunction unflattenPts(flat) {\r\n  const out = [];\r\n  for (let i = 0; i + 1 < flat.length; i += 2) {\r\n    out.push([flat[i], flat[i + 1]]);\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/core/prng.ts\r\nfunction hashString(s) {\r\n  let h = 2166136261;\r\n  for (let i = 0; i < s.length; i++) {\r\n    h ^= s.charCodeAt(i);\r\n    h = Math.imul(h, 16777619);\r\n  }\r\n  return h >>> 0;\r\n}\r\nfunction hashCombine(...vals) {\r\n  let h = 2654435769;\r\n  for (let i = 0; i < vals.length; i++) {\r\n    let x = vals[i] >>> 0;\r\n    x = Math.imul(x ^ x >>> 16, 2246822507);\r\n    x = Math.imul(x ^ x >>> 13, 3266489909);\r\n    x ^= x >>> 16;\r\n    h = (Math.imul(h, 16777619) ^ x) >>> 0;\r\n  }\r\n  return h >>> 0;\r\n}\r\nfunction hashTo01(h) {\r\n  return (h >>> 0) / 4294967296;\r\n}\r\nfunction mulberry32(seed) {\r\n  let a = seed >>> 0;\r\n  return () => {\r\n    a = a + 1831565813 | 0;\r\n    let t = a;\r\n    t = Math.imul(t ^ t >>> 15, t | 1);\r\n    t ^= t + Math.imul(t ^ t >>> 7, t | 61);\r\n    return ((t ^ t >>> 14) >>> 0) / 4294967296;\r\n  };\r\n}\r\nfunction rngFor(seed, subsystem, ...idx) {\r\n  return mulberry32(hashCombine(seed >>> 0, hashString(subsystem), ...idx));\r\n}\r\nfunction rand01(seed, subsystem, ...idx) {\r\n  return hashTo01(hashCombine(seed >>> 0, hashString(subsystem), ...idx));\r\n}\r\n\r\n// src/fracture/build.ts\r\nfunction resolveFractureOptions(opts) {\r\n  if (!Number.isFinite(opts.width) || opts.width <= 0) throw new Error(\"cracked-glass: width must be > 0\");\r\n  if (!Number.isFinite(opts.height) || opts.height <= 0) throw new Error(\"cracked-glass: height must be > 0\");\r\n  if (!Number.isFinite(opts.seed)) throw new Error(\"cracked-glass: seed must be a finite number\");\r\n  const seed = opts.seed >>> 0;\r\n  const micro = opts.micro;\r\n  const defaultMicroCount = opts.mode === \"radial\" ? 110 : opts.mode === \"collapse\" ? 90 : opts.mode === \"hero\" ? 0 : 36;\r\n  const angleA = opts.collapse?.angleA ?? 14;\r\n  let angleB = opts.collapse?.angleB ?? 76;\r\n  const sep = Math.abs((angleB - angleA + 90) % 180 - 90);\r\n  if (sep < 35) angleB = angleA + (angleB >= angleA ? 35 : -35);\r\n  return {\r\n    mode: opts.mode,\r\n    width: opts.width,\r\n    height: opts.height,\r\n    seed,\r\n    instanceId: opts.instanceId ?? `cg${seed.toString(36)}`,\r\n    edgeDetail: clamp(Math.round(opts.edgeDetail ?? 2), 0, 3),\r\n    jaggedness: clamp(opts.jaggedness ?? 0.5, 0, 1),\r\n    seamOutsetPx: opts.seamOutsetPx ?? 0.4,\r\n    deviation: clamp(opts.deviation ?? 0.35, 0, 1),\r\n    microCount: micro === false ? 0 : Math.max(0, Math.round(micro?.count ?? defaultMicroCount)),\r\n    microSizeRange: micro === false ? [0, 0] : micro?.sizeRange ?? [1.5, 5],\r\n    stubs: opts.stubs === false ? false : {\r\n      maxPerCrack: Math.max(0, Math.round(opts.stubs?.maxPerCrack ?? 4)),\r\n      atJunctions: opts.stubs?.atJunctions ?? true\r\n    },\r\n    bands: {\r\n      count: opts.bands?.count ?? [3, 5],\r\n      waviness: clamp(opts.bands?.waviness ?? 0.5, 0, 1),\r\n      diagonalChance: clamp(opts.bands?.diagonalChance ?? 0.6, 0, 1),\r\n      tilt: clamp(opts.bands?.tilt ?? 0.6, 0, 1),\r\n      splitters: clamp(Math.round(opts.bands?.splitters ?? 3), 1, 3),\r\n      diagonal: clamp(opts.bands?.diagonal ?? 0.7, 0, 1)\r\n    },\r\n    impact: opts.impact ? [clamp(opts.impact.x, 0, opts.width), clamp(opts.impact.y, 0, opts.height)] : [opts.width / 2, opts.height / 2],\r\n    impactHole: clamp(opts.impactHole ?? 1, 0.3, 3),\r\n    rays: {\r\n      // lower default ray count keeps the cell count (and thus per-shard DOM cost) sane;\r\n      // the lab lets you crank it higher when you want a denser web.\r\n      count: Math.max(3, Math.round(opts.rays?.count ?? 6)),\r\n      angleJitter: clamp(opts.rays?.angleJitter ?? 0.6, 0, 1),\r\n      waviness: clamp(opts.rays?.waviness ?? 0.5, 0, 1),\r\n      doubling: opts.rays?.doubling ?? true,\r\n      doublingStartRing: Math.max(1, Math.round(opts.rays?.doublingStartRing ?? 3))\r\n    },\r\n    rings: {\r\n      count: Math.max(1, Math.round(opts.rings?.count ?? 4)),\r\n      spacing: opts.rings?.spacing ?? \"geometric\",\r\n      jitter: clamp(opts.rings?.jitter ?? 0.5, 0, 1),\r\n      partial: clamp(opts.rings?.partial ?? 0.88, 0, 1),\r\n      asymmetry: clamp(opts.rings?.asymmetry ?? 0.45, 0, 1)\r\n    },\r\n    collapse: {\r\n      angleA,\r\n      angleB,\r\n      countA: opts.collapse?.countA ?? [3, 5],\r\n      countB: opts.collapse?.countB ?? [4, 7],\r\n      waviness: clamp(opts.collapse?.waviness ?? 0.5, 0, 1),\r\n      merge: clamp(opts.collapse?.merge ?? 0.3, 0, 1)\r\n    },\r\n    hero: {\r\n      count: clamp(Math.round(opts.hero?.count ?? 1), 1, 3),\r\n      sizeFrac: clamp(opts.hero?.sizeFrac ?? 0.34, 0.05, 0.48),\r\n      spread: clamp(opts.hero?.spread ?? 0.5, 0, 1),\r\n      overlap: clamp(opts.hero?.overlap ?? 0, 0, 1)\r\n    },\r\n    web: {\r\n      rays: Math.max(3, Math.round(opts.web?.rays ?? 9)),\r\n      rings: Math.max(1, Math.round(opts.web?.rings ?? 4)),\r\n      irregularity: clamp(opts.web?.irregularity ?? 0.6, 0, 1),\r\n      dir: opts.web?.dir ?? 90,\r\n      distance: clamp(opts.web?.distance ?? 1.2, 0.2, 6)\r\n    },\r\n    corners: opts.corners === false ? false : { relief: clamp(opts.corners?.relief ?? 0.55, 0, 1) }\r\n  };\r\n}\r\nfunction makeCrack(seed, id, kind, pts, birth, growDuration, withTicks = true) {\r\n  const cum = cumulativeLengths(pts);\r\n  const totalLen = cum[cum.length - 1];\r\n  const ticks = [];\r\n  const rng = rngFor(seed, \"ticks\", hashString(id));\r\n  const spacing = 11;\r\n  for (let s = withTicks ? spacing * (0.5 + rng()) : totalLen; s < totalLen - 4; s += spacing * (0.7 + rng() * 0.8)) {\r\n    const p = pointAt(pts, cum, s);\r\n    const q = pointAt(pts, cum, Math.min(totalLen, s + 1.5));\r\n    let dx = q[0] - p[0];\r\n    let dy = q[1] - p[1];\r\n    const l = Math.hypot(dx, dy) || 1;\r\n    dx /= l;\r\n    dy /= l;\r\n    const side = rng() < 0.5 ? 1 : -1;\r\n    const len = 1.6 + rng() * 3.2;\r\n    const a = (55 + rng() * 25) * (Math.PI / 180) * side;\r\n    const cos = Math.cos(a);\r\n    const sin = Math.sin(a);\r\n    const tx = dx * cos - dy * sin;\r\n    const ty = dx * sin + dy * cos;\r\n    ticks.push(s, p[0], p[1], p[0] + tx * len, p[1] + ty * len);\r\n  }\r\n  return {\r\n    id,\r\n    kind,\r\n    points: flattenPts(pts),\r\n    cumLen: cum,\r\n    totalLen,\r\n    birth,\r\n    growDuration,\r\n    ticks\r\n  };\r\n}\r\nfunction pointAt(pts, cum, len) {\r\n  const total = cum[cum.length - 1];\r\n  if (len <= 0) return pts[0];\r\n  if (len >= total) return pts[pts.length - 1];\r\n  let lo = 0;\r\n  let hi = cum.length - 1;\r\n  while (lo + 1 < hi) {\r\n    const mid = lo + hi >> 1;\r\n    if (cum[mid] <= len) lo = mid;\r\n    else hi = mid;\r\n  }\r\n  const segLen = cum[hi] - cum[lo];\r\n  const t = segLen > 1e-12 ? (len - cum[lo]) / segLen : 0;\r\n  return [pts[lo][0] + (pts[hi][0] - pts[lo][0]) * t, pts[lo][1] + (pts[hi][1] - pts[lo][1]) * t];\r\n}\r\nfunction makeShard(seed, index, poly, ringIndex, z, seamOutsetPx) {\r\n  const cleaned = dedupePolygon(poly);\r\n  if (cleaned.length < 3) return null;\r\n  const wound = ensurePositiveWinding(cleaned);\r\n  const area = signedArea(wound);\r\n  if (area < 2) return null;\r\n  const outset = seamOutsetPx > 0 ? offsetPolygon(wound, seamOutsetPx) : wound;\r\n  return {\r\n    id: `s${index}`,\r\n    polygon: flattenPts(wound),\r\n    outsetPolygon: flattenPts(outset),\r\n    centroid: polygonCentroid(wound),\r\n    area,\r\n    ringIndex,\r\n    z,\r\n    hash: hashCombine(seed, hashString(\"shard\"), index)\r\n  };\r\n}\r\nfunction shuffledRanks(seed, key, n) {\r\n  const rng = rngFor(seed, key);\r\n  const idx = Array.from({ length: n }, (_, i) => i);\r\n  for (let i = n - 1; i > 0; i--) {\r\n    const j = Math.floor(rng() * (i + 1));\r\n    const tmp = idx[i];\r\n    idx[i] = idx[j];\r\n    idx[j] = tmp;\r\n  }\r\n  const ranks = new Array(n);\r\n  for (let rank = 0; rank < n; rank++) ranks[idx[rank]] = rank;\r\n  return ranks;\r\n}\r\nfunction stitchLoop(segments) {\r\n  const out = [];\r\n  for (const seg of segments) {\r\n    const start = out.length === 0 ? 0 : 1;\r\n    for (let i = start; i < seg.length; i++) out.push(seg[i]);\r\n  }\r\n  return dedupePolygon(out);\r\n}\r\nfunction reversePts(pts) {\r\n  return pts.slice().reverse();\r\n}\r\n\r\n// src/core/noise.ts\r\nfunction valueNoise1D(seed, x) {\r\n  const xi = Math.floor(x);\r\n  const xf = x - xi;\r\n  const r0 = hashTo01(hashCombine(seed, xi | 0));\r\n  const r1 = hashTo01(hashCombine(seed, xi + 1 | 0));\r\n  return lerp(r0, r1, smoothstep(xf)) * 2 - 1;\r\n}\r\nfunction fbm1D(seed, x, octaves = 3, lacunarity = 2, gain = 0.5) {\r\n  let amp = 1;\r\n  let freq = 1;\r\n  let sum = 0;\r\n  let norm = 0;\r\n  for (let o = 0; o < octaves; o++) {\r\n    sum += amp * valueNoise1D(hashCombine(seed, o), x * freq);\r\n    norm += amp;\r\n    amp *= gain;\r\n    freq *= lacunarity;\r\n  }\r\n  return norm > 0 ? sum / norm : 0;\r\n}\r\nfunction subdivideMidpoint(pts, depth, roughness, seed, maxOffset = Infinity) {\r\n  let cur = pts;\r\n  for (let level = 0; level < depth; level++) {\r\n    const next = [cur[0]];\r\n    const levelAmp = roughness * 0.5 * Math.pow(0.55, level);\r\n    for (let i = 0; i < cur.length - 1; i++) {\r\n      const a = cur[i];\r\n      const b = cur[i + 1];\r\n      const dx = b[0] - a[0];\r\n      const dy = b[1] - a[1];\r\n      const segLen = Math.hypot(dx, dy);\r\n      if (segLen > 1e-9) {\r\n        const nx = -dy / segLen;\r\n        const ny = dx / segLen;\r\n        const r = hashTo01(hashCombine(seed, level, i)) * 2 - 1;\r\n        let off = r * levelAmp * segLen;\r\n        if (off > maxOffset) off = maxOffset;\r\n        if (off < -maxOffset) off = -maxOffset;\r\n        next.push([(a[0] + b[0]) / 2 + nx * off, (a[1] + b[1]) / 2 + ny * off]);\r\n      }\r\n      next.push(b);\r\n    }\r\n    cur = next;\r\n  }\r\n  return cur;\r\n}\r\n\r\n// src/fracture/lines.ts\r\nfunction makeExcursions(seed, group, lineKey, deviation, ampMax) {\r\n  if (deviation <= 0) return [];\r\n  const out = [];\r\n  for (let idx = 0; idx < 2; idx++) {\r\n    const p = idx === 0 ? deviation * 0.75 : deviation * 0.35;\r\n    if (rand01(seed, `${group}:dev`, lineKey, idx) >= p) continue;\r\n    const r1 = rand01(seed, `${group}:devA`, lineKey, idx);\r\n    const r2 = rand01(seed, `${group}:devB`, lineKey, idx);\r\n    const r3 = rand01(seed, `${group}:devC`, lineKey, idx);\r\n    const r4 = rand01(seed, `${group}:devD`, lineKey, idx);\r\n    const r5 = rand01(seed, `${group}:devE`, lineKey, idx);\r\n    out.push({\r\n      c: 0.15 + 0.7 * r1,\r\n      half: 0.08 + 0.1 * r2,\r\n      amp: (0.25 + 0.45 * r3) * ampMax * (r4 < 0.5 ? -1 : 1),\r\n      kink: r5 < 0.5\r\n    });\r\n  }\r\n  return out;\r\n}\r\nfunction excursionOffset(evts, u) {\r\n  let v = 0;\r\n  for (const e of evts) {\r\n    const d = Math.abs(u - e.c);\r\n    if (d >= e.half) continue;\r\n    const x = 1 - d / e.half;\r\n    v += e.amp * (e.kink ? x : 0.5 * (1 - Math.cos(Math.PI * x)));\r\n  }\r\n  return v;\r\n}\r\nfunction baseLine(o) {\r\n  const waveSeed = hashCombine(o.seed, hashString(`${o.group}:wave`), o.key);\r\n  const evts = makeExcursions(o.seed, o.group, o.key, o.deviation, o.devAmpMax);\r\n  const u = [];\r\n  const v = [];\r\n  for (let i = 0; i <= o.segments; i++) {\r\n    const f = i / o.segments;\r\n    u.push(o.u0 + (o.u1 - o.u0) * f);\r\n    v.push(o.offset + fbm1D(waveSeed, i * 0.85, 3) * o.waveAmp + excursionOffset(evts, f));\r\n  }\r\n  for (let pass = 0; pass < 2; pass++) {\r\n    for (let i = 1; i < v.length; i++) {\r\n      const du = u[i] - u[i - 1];\r\n      v[i] = clamp(v[i], v[i - 1] - o.slopeMax * du, v[i - 1] + o.slopeMax * du);\r\n    }\r\n    for (let i = 0; i < v.length; i++) {\r\n      v[i] = clamp(v[i], o.offset - o.corridorHalf, o.offset + o.corridorHalf);\r\n    }\r\n  }\r\n  return { u, v };\r\n}\r\n\r\n// src/fracture/title.ts\r\nfunction generateTitleFracture(o) {\r\n  const { width: w, height: h, seed } = o;\r\n  const rngCount = rngFor(seed, \"title:count\");\r\n  const bandCount = Array.isArray(o.bands.count) ? Math.round(\r\n    clamp(\r\n      o.bands.count[0] + rngCount() * (o.bands.count[1] - o.bands.count[0]),\r\n      Math.min(o.bands.count[0], o.bands.count[1]),\r\n      Math.max(o.bands.count[0], o.bands.count[1])\r\n    )\r\n  ) : Math.max(2, Math.round(o.bands.count));\r\n  const gap = h / bandCount;\r\n  const tiltOn = o.bands.tilt > 0;\r\n  const offs = new Array(bandCount + 1).fill(0);\r\n  const tilts = new Array(bandCount + 1).fill(0);\r\n  for (let k = 1; k < bandCount; k++) {\r\n    const rngB = rngFor(seed, \"title:boundary\", k);\r\n    offs[k] = (rngB() - 0.5) * gap * 0.36;\r\n    if (tiltOn) {\r\n      const sign = k % 2 === 0 ? 1 : -1;\r\n      tilts[k] = sign * (0.3 + 0.7 * rand01(seed, \"title:tilt\", k)) * 0.225 * o.bands.tilt * (gap / (w / 2));\r\n    }\r\n  }\r\n  const yLine = (k, x) => {\r\n    if (k <= 0) return 0;\r\n    if (k >= bandCount) return h;\r\n    return gap * k + offs[k] + tilts[k] * (x - w / 2);\r\n  };\r\n  const boundaries = [];\r\n  const segments = Math.max(4, Math.round(w / 160));\r\n  for (let k = 0; k <= bandCount; k++) {\r\n    if (k === 0 || k === bandCount) {\r\n      boundaries.push([\r\n        [0, k === 0 ? 0 : h],\r\n        [w, k === 0 ? 0 : h]\r\n      ]);\r\n      continue;\r\n    }\r\n    const waveAmp = o.bands.waviness * gap * 0.22;\r\n    const waveSeed = hashCombine(seed, hashString(\"title:wave\"), k);\r\n    const excursions = o.deviation > 0 ? makeExcursions(seed, \"title\", k, o.deviation, gap) : [];\r\n    const base = [];\r\n    for (let i = 0; i <= segments; i++) {\r\n      const x = w * i / segments;\r\n      let y = yLine(k, x) + fbm1D(waveSeed, i * 0.85, 3) * waveAmp;\r\n      if (excursions.length > 0) y += excursionOffset(excursions, i / segments);\r\n      base.push([x, y]);\r\n    }\r\n    let jagged = subdivideMidpoint(\r\n      base,\r\n      o.edgeDetail,\r\n      o.jaggedness * 0.5,\r\n      hashCombine(seed, hashString(\"title:jag\"), k),\r\n      gap * 0.17\r\n    );\r\n    if (tiltOn) {\r\n      jagged = jagged.map(([x, y]) => {\r\n        const lo = (yLine(k - 1, x) + yLine(k, x)) / 2 + 0.06 * gap;\r\n        const hi = (yLine(k, x) + yLine(k + 1, x)) / 2 - 0.06 * gap;\r\n        return [x, y < lo ? lo : y > hi ? hi : y];\r\n      });\r\n    } else if (o.deviation > 0) {\r\n      const lo = gap * k - gap * 0.45;\r\n      const hi = gap * k + gap * 0.45;\r\n      jagged = jagged.map(([x, y]) => [x, y < lo ? lo : y > hi ? hi : y]);\r\n    }\r\n    boundaries.push(jagged);\r\n  }\r\n  const raw = [];\r\n  const cracks = [];\r\n  const junctions = [];\r\n  let crackIdx = 0;\r\n  const order = boundaryBirthOrder(bandCount);\r\n  for (let k = 1; k < bandCount; k++) {\r\n    const rngC = rngFor(seed, \"title:crack\", k);\r\n    const pts = k % 2 === 0 ? reversePts(boundaries[k]) : boundaries[k].slice();\r\n    const rank = order.indexOf(k);\r\n    const grow = 0.38 + rngC() * 0.14;\r\n    const birth = Math.min(0.04 + rank / Math.max(1, bandCount - 2) * 0.38 + rngC() * 0.06, 0.97 - grow);\r\n    cracks.push(makeCrack(seed, `c${crackIdx++}`, \"band\", pts, birth, grow));\r\n  }\r\n  for (let band = 0; band < bandCount; band++) {\r\n    const top = boundaries[band];\r\n    const bot = boundaries[band + 1];\r\n    if (o.bands.splitters === 1) {\r\n      const rngS = rngFor(seed, \"title:split\", band);\r\n      const wantSplit = rngS() < o.bands.diagonalChance && top.length > 6 && bot.length > 6;\r\n      if (!wantSplit) {\r\n        raw.push({ poly: [...top, ...reversePts(bot)], band });\r\n        continue;\r\n      }\r\n      const targetX = (0.3 + rngS() * 0.4) * w;\r\n      const iT = nearestIndexByX(top, targetX, 2);\r\n      const diag2 = o.bands.diagonal;\r\n      const lean = (rngS() * 2 - 1) * (diag2 > 0 ? diag2 * 0.6 * gap : (0.35 + 0.9 * o.deviation) * gap);\r\n      const iB = nearestIndexByX(bot, top[iT][0] + lean, 2);\r\n      const a = top[iT];\r\n      const b = bot[iB];\r\n      const splitBase = [a, [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2], b];\r\n      let splitter = subdivideMidpoint(\r\n        splitBase,\r\n        o.edgeDetail,\r\n        o.jaggedness * 0.45,\r\n        hashCombine(seed, hashString(\"title:splitjag\"), band),\r\n        gap * 0.16\r\n      );\r\n      if (diag2 > 0) splitter = clampSplitterToBand(splitter, top, bot, gap);\r\n      const left = [...top.slice(0, iT + 1), ...splitter.slice(1), ...reversePts(bot.slice(0, iB))];\r\n      const right = [\r\n        ...top.slice(iT),\r\n        ...reversePts(bot.slice(iB)),\r\n        ...reversePts(splitter.slice(1, -1))\r\n      ];\r\n      raw.push({ poly: left, band });\r\n      raw.push({ poly: right, band });\r\n      const rngC = rngFor(seed, \"title:splitcrack\", band);\r\n      const sGrow = 0.22 + rngC() * 0.1;\r\n      cracks.push(\r\n        makeCrack(seed, `c${crackIdx++}`, \"split\", splitter, Math.min(0.5 + rngC() * 0.18, 0.97 - sGrow), sGrow)\r\n      );\r\n      const ci1 = cracks.length - 1;\r\n      junctions.push({ crackIndex: ci1, s: 0 }, { crackIndex: ci1, s: cracks[ci1].totalLen });\r\n      continue;\r\n    }\r\n    if (top.length <= 6 || bot.length <= 6) {\r\n      raw.push({ poly: [...top, ...reversePts(bot)], band });\r\n      continue;\r\n    }\r\n    const m = o.bands.splitters;\r\n    const q = o.bands.diagonalChance;\r\n    const probs = [q, 0.45 * q, 0.2 * q].slice(0, m);\r\n    const slotLo = 0.15 * w;\r\n    const slotW = 0.7 * w / m;\r\n    const diag = o.bands.diagonal;\r\n    const bandSign = rand01(seed, \"title:diagSign\", band) < 0.5 ? -1 : 1;\r\n    const cands = [];\r\n    for (let j = 0; j < m; j++) {\r\n      if (rand01(seed, \"title:msplitG\", band, j) >= probs[j]) continue;\r\n      const r1 = rand01(seed, \"title:msplitX\", band, j);\r\n      const r2 = rand01(seed, \"title:msplitL\", band, j);\r\n      const targetX = slotLo + slotW * j + (0.25 + 0.5 * r1) * slotW;\r\n      const iT = nearestIndexByX(top, targetX, 2);\r\n      const lean = diag > 0 ? bandSign * Math.min((0.35 + 0.65 * r2) * diag, 0.6) * gap : (r2 * 2 - 1) * Math.min((0.35 + 0.9 * o.deviation) * gap, 0.2 * slotW);\r\n      const iB = nearestIndexByX(bot, top[iT][0] + lean, 2);\r\n      const a = top[iT];\r\n      const b = bot[iB];\r\n      const splitBase = [a, [(a[0] + b[0]) / 2, (a[1] + b[1]) / 2], b];\r\n      let pts = subdivideMidpoint(\r\n        splitBase,\r\n        o.edgeDetail,\r\n        o.jaggedness * 0.45,\r\n        hashCombine(seed, hashString(\"title:msplitjag\"), band, j),\r\n        Math.min(gap * 0.16, 0.1 * slotW)\r\n      );\r\n      if (diag > 0) pts = clampSplitterToBand(pts, top, bot, gap);\r\n      cands.push({ iT, iB, pts });\r\n    }\r\n    cands.sort((a, b) => a.iT - b.iT);\r\n    const acc = [];\r\n    for (const c of cands) {\r\n      const prev = acc[acc.length - 1];\r\n      if (c.iT < 2 || c.iT > top.length - 3 || c.iB < 2 || c.iB > bot.length - 3) continue;\r\n      if (prev && (c.iT - prev.iT < 4 || c.iB - prev.iB < 4)) continue;\r\n      acc.push(c);\r\n    }\r\n    if (acc.length === 0) {\r\n      raw.push({ poly: [...top, ...reversePts(bot)], band });\r\n      continue;\r\n    }\r\n    raw.push({\r\n      poly: [...top.slice(0, acc[0].iT + 1), ...acc[0].pts.slice(1), ...reversePts(bot.slice(0, acc[0].iB))],\r\n      band\r\n    });\r\n    for (let j = 0; j + 1 < acc.length; j++) {\r\n      raw.push({\r\n        poly: [\r\n          ...top.slice(acc[j].iT, acc[j + 1].iT + 1),\r\n          ...acc[j + 1].pts.slice(1),\r\n          ...reversePts(bot.slice(acc[j].iB, acc[j + 1].iB)),\r\n          ...reversePts(acc[j].pts.slice(1, -1))\r\n        ],\r\n        band\r\n      });\r\n    }\r\n    const last = acc[acc.length - 1];\r\n    raw.push({\r\n      poly: [...top.slice(last.iT), ...reversePts(bot.slice(last.iB)), ...reversePts(last.pts.slice(1, -1))],\r\n      band\r\n    });\r\n    for (let j = 0; j < acc.length; j++) {\r\n      const rB1 = rand01(seed, \"title:msplitGrow\", band, j);\r\n      const rB2 = rand01(seed, \"title:msplitBirth\", band, j);\r\n      const sGrow = 0.22 + rB1 * 0.1;\r\n      cracks.push(\r\n        makeCrack(seed, `c${crackIdx++}`, \"split\", acc[j].pts, Math.min(0.5 + rB2 * 0.18, 0.97 - sGrow), sGrow)\r\n      );\r\n      const ciM = cracks.length - 1;\r\n      junctions.push({ crackIndex: ciM, s: 0 }, { crackIndex: ciM, s: cracks[ciM].totalLen });\r\n    }\r\n  }\r\n  const ranks = shuffledRanks(seed, \"title:z\", raw.length);\r\n  const shards = [];\r\n  for (let i = 0; i < raw.length; i++) {\r\n    const s = makeShard(seed, i, raw[i].poly, raw[i].band, ranks[i], o.seamOutsetPx);\r\n    if (s) shards.push(s);\r\n  }\r\n  return { shards, cracks, junctions, stubScale: gap };\r\n}\r\nfunction boundaryBirthOrder(bandCount) {\r\n  const ks = Array.from({ length: bandCount - 1 }, (_, i) => i + 1);\r\n  const mid = bandCount / 2;\r\n  return ks.sort((p, q) => Math.abs(p - mid) - Math.abs(q - mid) || p - q);\r\n}\r\nfunction interpY(poly, x) {\r\n  if (x <= poly[0][0]) return poly[0][1];\r\n  const last = poly[poly.length - 1];\r\n  if (x >= last[0]) return last[1];\r\n  for (let i = 0; i + 1 < poly.length; i++) {\r\n    if (x >= poly[i][0] && x <= poly[i + 1][0]) {\r\n      const t = (x - poly[i][0]) / Math.max(1e-9, poly[i + 1][0] - poly[i][0]);\r\n      return poly[i][1] + (poly[i + 1][1] - poly[i][1]) * t;\r\n    }\r\n  }\r\n  return last[1];\r\n}\r\nfunction clampSplitterToBand(pts, top, bot, gap) {\r\n  const m = 0.05 * gap;\r\n  return pts.map((p, i) => {\r\n    if (i === 0 || i === pts.length - 1) return p;\r\n    const lo = interpY(top, p[0]) + m;\r\n    const hi = interpY(bot, p[0]) - m;\r\n    return [p[0], p[1] < lo ? lo : p[1] > hi ? hi : p[1]];\r\n  });\r\n}\r\nfunction nearestIndexByX(pts, x, margin) {\r\n  let best = margin;\r\n  let bestD = Infinity;\r\n  for (let i = margin; i < pts.length - margin; i++) {\r\n    const d = Math.abs(pts[i][0] - x);\r\n    if (d < bestD) {\r\n      bestD = d;\r\n      best = i;\r\n    }\r\n  }\r\n  return best;\r\n}\r\n\r\n// src/fracture/radial.ts\r\nfunction generateRadialFracture(o) {\r\n  const { width: w, height: h, seed } = o;\r\n  const [ix, iy] = o.impact;\r\n  const N = o.rays.count;\r\n  const M = o.rings.count;\r\n  let doubling = o.rays.doubling && N >= 3;\r\n  let dS = Math.min(Math.max(1, o.rays.doublingStartRing), M);\r\n  if (dS >= M + 1) doubling = false;\r\n  if (M < 2) doubling = false;\r\n  const count = doubling ? 2 * N : N;\r\n  const R = Math.max(\r\n    Math.hypot(ix, iy),\r\n    Math.hypot(w - ix, iy),\r\n    Math.hypot(ix, h - iy),\r\n    Math.hypot(w - ix, h - iy)\r\n  ) * 1.08;\r\n  const r0 = Math.max(6, 0.05 * Math.min(w, h)) * o.impactHole;\r\n  const slot = TAU / N;\r\n  const stepAtRing = (j) => !doubling ? 1 : j >= dS ? 1 : 2;\r\n  const rayStartRing = (a) => !doubling || a % 2 === 0 ? 0 : dS;\r\n  const asym = o.rings.asymmetry;\r\n  const strongDir = rand01(seed, \"radial:strongDir\") * TAU;\r\n  const keepArc = (j, a) => {\r\n    if (j <= 0 || j >= M) return true;\r\n    if (doubling && j === dS) return true;\r\n    if (o.rings.partial <= 0) return true;\r\n    const ramp = M >= 3 ? (j - 1) / (M - 2) : 1;\r\n    let keepProb = 1 - o.rings.partial * (0.1 + 0.45 * ramp);\r\n    if (asym > 0) {\r\n      const side = 0.5 + 0.5 * Math.cos(angles[a] - strongDir);\r\n      const dropScale = 1 + asym * 1.6 * (1 - side);\r\n      keepProb = Math.max(0.02, 1 - (1 - keepProb) * dropScale);\r\n    }\r\n    return rand01(seed, \"radial:arcKeep\", j, a) < keepProb;\r\n  };\r\n  const baseAngles = [];\r\n  for (let i = 0; i < N; i++) {\r\n    const r = rand01(seed, \"radial:baseAngle\", i);\r\n    baseAngles.push(slot * i + (r - 0.5) * 2 * 0.18 * slot * o.rays.angleJitter);\r\n  }\r\n  const angles = [];\r\n  if (doubling) {\r\n    for (let i = 0; i < N; i++) {\r\n      angles.push(baseAngles[i]);\r\n      const next = i + 1 < N ? baseAngles[i + 1] : baseAngles[0] + TAU;\r\n      const r = rand01(seed, \"radial:secAngle\", i);\r\n      angles.push((baseAngles[i] + next) / 2 + (r - 0.5) * 2 * 0.1 * slot);\r\n    }\r\n  } else {\r\n    angles.push(...baseAngles);\r\n  }\r\n  const weights = [];\r\n  {\r\n    let sum = 0;\r\n    for (let j = 1; j <= M; j++) {\r\n      const wj = o.rings.spacing === \"geometric\" ? Math.pow(1.55, j - 1) : 1;\r\n      weights.push(wj);\r\n      sum += wj;\r\n    }\r\n    for (let j = 0; j < M; j++) weights[j] /= sum;\r\n  }\r\n  const radii = [];\r\n  for (let a = 0; a < count; a++) {\r\n    const row = [0];\r\n    let cum = 0;\r\n    for (let j = 1; j <= M; j++) {\r\n      const jit = (rand01(seed, \"radial:ring\", a, j) - 0.5) * 2 * 0.35 * o.rings.jitter;\r\n      cum += weights[j - 1] * (1 + jit);\r\n      row.push(cum);\r\n    }\r\n    const total = row[M];\r\n    for (let j = 0; j <= M; j++) row[j] = r0 + (R - r0) * row[j] / total;\r\n    radii.push(row);\r\n  }\r\n  const wobAmp = (j) => 0.1 * o.rays.waviness * slot * (stepAtRing(j) === 2 || !doubling ? 1 : 0.5);\r\n  const hasDeviation = o.deviation > 0;\r\n  const budget = [];\r\n  const kinkMag = [];\r\n  const kinkRing = [];\r\n  for (let a = 0; a < count; a++) {\r\n    const prev = angles[(a - 1 + count) % count] - (a === 0 ? TAU : 0);\r\n    const next = angles[(a + 1) % count] + (a === count - 1 ? TAU : 0);\r\n    budget.push(0.32 * Math.min(angles[a] - prev, next - angles[a]));\r\n    if (hasDeviation && rand01(seed, \"radial:kink\", a) < o.deviation * 0.55 && M > 1) {\r\n      const jk = 1 + Math.floor(rand01(seed, \"radial:kinkJ\", a) * (M - 1));\r\n      const sign = rand01(seed, \"radial:kinkS\", a) < 0.5 ? -1 : 1;\r\n      kinkMag.push(sign * (0.5 + 0.5 * rand01(seed, \"radial:kinkM\", a)) * budget[a]);\r\n      kinkRing.push(jk);\r\n    } else {\r\n      kinkMag.push(0);\r\n      kinkRing.push(0);\r\n    }\r\n  }\r\n  const anchorAngle = (a, j) => {\r\n    const wobble = fbm1D(hashCombine(seed, hashString(\"radial:wob\"), a), j * 0.8, 2) * wobAmp(j);\r\n    if (!hasDeviation) return angles[a] + wobble;\r\n    const kink = kinkMag[a] * Math.min(1, Math.max(0, j - kinkRing[a]) / 1.5);\r\n    const phi = Math.max(-budget[a], Math.min(budget[a], wobble + kink));\r\n    return angles[a] + phi;\r\n  };\r\n  const anchors = [];\r\n  for (let a = 0; a < count; a++) {\r\n    const row = [];\r\n    for (let j = 0; j <= M; j++) {\r\n      const ang = anchorAngle(a, j);\r\n      row.push([ix + Math.cos(ang) * radii[a][j], iy + Math.sin(ang) * radii[a][j]]);\r\n    }\r\n    anchors.push(row);\r\n  }\r\n  const rayEdges = /* @__PURE__ */ new Map();\r\n  for (let a = 0; a < count; a++) {\r\n    for (let j = rayStartRing(a); j < M; j++) {\r\n      const A = anchors[a][j];\r\n      const B = anchors[a][j + 1];\r\n      const rMid = (radii[a][j] + radii[a][j + 1]) / 2;\r\n      const angMid = angles[a] + fbm1D(hashCombine(seed, hashString(\"radial:wob\"), a), (j + 0.5) * 0.8, 2) * Math.min(wobAmp(j), wobAmp(j + 1));\r\n      const mid = [ix + Math.cos(angMid) * rMid, iy + Math.sin(angMid) * rMid];\r\n      const lateralGap = rMid * slot * (doubling && stepAtRing(j) === 1 ? 0.5 : 1);\r\n      const pts = subdivideMidpoint(\r\n        [A, mid, B],\r\n        o.edgeDetail,\r\n        o.jaggedness * 0.5,\r\n        hashCombine(seed, hashString(\"radial:rayjag\"), a, j),\r\n        0.25 * lateralGap\r\n      );\r\n      rayEdges.set(`${a}:${j}`, pts);\r\n    }\r\n  }\r\n  const arcEdges = /* @__PURE__ */ new Map();\r\n  for (let j = 0; j <= M; j++) {\r\n    const step = stepAtRing(j);\r\n    for (let a = 0; a < count; a += step) {\r\n      const b = (a + step) % count;\r\n      const A = anchors[a][j];\r\n      const B = anchors[b][j];\r\n      const angA = anchorAngle(a, j);\r\n      let angB = anchorAngle(b, j);\r\n      if (angB <= angA) angB += TAU;\r\n      const rA = radii[a][j];\r\n      const rB = radii[b][j];\r\n      const gapDown = j > 0 ? Math.min(rA - radii[a][j - 1], rB - radii[b][j - 1]) : r0;\r\n      const gapUp = j < M ? Math.min(radii[a][j + 1] - rA, radii[b][j + 1] - rB) : gapDown;\r\n      const minGap = Math.max(1, Math.min(gapDown, gapUp));\r\n      const bulgeSeed = hashCombine(seed, hashString(\"radial:bulge\"), j, a);\r\n      const base = [A];\r\n      const innerSamples = 2;\r\n      for (let s = 1; s <= innerSamples; s++) {\r\n        const f = s / (innerSamples + 1);\r\n        const ang = lerp(angA, angB, f);\r\n        const r = lerp(rA, rB, f) + fbm1D(bulgeSeed, f * 2.3, 2) * 0.14 * minGap * (0.4 + 0.6 * o.rings.jitter);\r\n        base.push([ix + Math.cos(ang) * r, iy + Math.sin(ang) * r]);\r\n      }\r\n      base.push(B);\r\n      const pts = subdivideMidpoint(\r\n        base,\r\n        o.edgeDetail,\r\n        o.jaggedness * 0.4,\r\n        hashCombine(seed, hashString(\"radial:arcjag\"), j, a),\r\n        0.22 * minGap\r\n      );\r\n      arcEdges.set(`${j}:${a}`, pts);\r\n    }\r\n  }\r\n  const raw = [];\r\n  {\r\n    const segs = [];\r\n    const step = stepAtRing(0);\r\n    for (let a = 0; a < count; a += step) segs.push(arcEdges.get(`0:${a}`));\r\n    const clipped = clipPolygonToRect(stitchLoop(segs), w, h);\r\n    if (clipped.length >= 3) raw.push({ poly: clipped, ring: 0 });\r\n  }\r\n  for (let j = 0; j < M; j++) {\r\n    const bandStep = stepAtRing(j);\r\n    for (let aL = 0; aL < count; aL += bandStep) {\r\n      if (!keepArc(j, aL)) continue;\r\n      let j1 = j;\r\n      while (j1 + 1 < M && !keepArc(j1 + 1, aL)) j1++;\r\n      const aR = (aL + bandStep) % count;\r\n      const segs = [];\r\n      for (let jj = j; jj <= j1; jj++) segs.push(rayEdges.get(`${aL}:${jj}`));\r\n      const outerStep = stepAtRing(j1 + 1);\r\n      const nOuter = bandStep / outerStep;\r\n      for (let s = 0; s < nOuter; s++) {\r\n        segs.push(arcEdges.get(`${j1 + 1}:${(aL + s * outerStep) % count}`));\r\n      }\r\n      for (let jj = j1; jj >= j; jj--) segs.push(reversePts(rayEdges.get(`${aR}:${jj}`)));\r\n      segs.push(reversePts(arcEdges.get(`${j}:${aL}`)));\r\n      const poly = stitchLoop(segs);\r\n      const clipped = clipPolygonToRect(poly, w, h);\r\n      if (clipped.length >= 3) raw.push({ poly: clipped, ring: j + 1 });\r\n    }\r\n  }\r\n  const ranks = shuffledRanks(seed, \"radial:z\", raw.length);\r\n  const shards = [];\r\n  for (let i = 0; i < raw.length; i++) {\r\n    const s = makeShard(seed, i, raw[i].poly, raw[i].ring, ranks[i], o.seamOutsetPx);\r\n    if (s) shards.push(s);\r\n  }\r\n  const cracks = [];\r\n  let ci = 0;\r\n  {\r\n    const segs = [];\r\n    const step = stepAtRing(0);\r\n    for (let a = 0; a < count; a += step) segs.push(arcEdges.get(`0:${a}`));\r\n    const loop = concatPolylines(segs);\r\n    cracks.push(makeCrack(seed, `c${ci++}`, \"crush\", loop, 0, 0.12));\r\n  }\r\n  for (let a = 0; a < count; a++) {\r\n    const start = rayStartRing(a);\r\n    if (start >= M) continue;\r\n    const segs = [];\r\n    for (let j = start; j < M; j++) segs.push(rayEdges.get(`${a}:${j}`));\r\n    const pts = concatPolylines(segs);\r\n    const rngC = rngFor(seed, \"radial:raybirth\", a);\r\n    const secondary = doubling && a % 2 === 1;\r\n    const birth = secondary ? 0.32 + rngC() * 0.08 : 0.02 + rngC() * 0.08;\r\n    const grow = secondary ? 0.3 : 0.48 + rngC() * 0.14;\r\n    cracks.push(makeCrack(seed, `c${ci++}`, \"ray\", pts, birth, grow));\r\n  }\r\n  const junctions = [];\r\n  for (let j = 1; j < M; j++) {\r\n    const step = stepAtRing(j);\r\n    const arcStarts = [];\r\n    for (let a = 0; a < count; a += step) arcStarts.push(a);\r\n    const kept = arcStarts.map((a) => keepArc(j, a));\r\n    const rngC = rngFor(seed, \"radial:ringbirth\", j);\r\n    const base = 0.34 + (j - 1) / Math.max(1, M - 2) * 0.38 + rngC() * 0.05;\r\n    if (kept.every(Boolean)) {\r\n      const segs = arcStarts.map((a) => arcEdges.get(`${j}:${a}`));\r\n      const pts = concatPolylines(segs);\r\n      cracks.push(makeCrack(seed, `c${ci++}`, \"ring\", pts, Math.min(base, 0.97 - 0.26), 0.26));\r\n      continue;\r\n    }\r\n    if (!kept.some(Boolean)) continue;\r\n    const n = arcStarts.length;\r\n    for (let i = 0; i < n; i++) {\r\n      if (!kept[i] || kept[(i - 1 + n) % n]) continue;\r\n      const segs = [];\r\n      for (let k = 0; k < n && kept[(i + k) % n]; k++) {\r\n        segs.push(arcEdges.get(`${j}:${arcStarts[(i + k) % n]}`));\r\n      }\r\n      const pts = concatPolylines(segs);\r\n      const birth = Math.min(base + 0.04 * rand01(seed, \"radial:ringrun\", j, arcStarts[i]), 0.97 - 0.26);\r\n      cracks.push(makeCrack(seed, `c${ci++}`, \"ring\", pts, birth, 0.26));\r\n      const ciRun = cracks.length - 1;\r\n      junctions.push({ crackIndex: ciRun, s: 0 }, { crackIndex: ciRun, s: cracks[ciRun].totalLen });\r\n    }\r\n  }\r\n  return {\r\n    shards,\r\n    cracks,\r\n    maxRing: M,\r\n    junctions,\r\n    stubScale: Math.sqrt(w * h / Math.max(1, shards.length))\r\n  };\r\n}\r\nfunction concatPolylines(segs) {\r\n  const out = [];\r\n  for (const seg of segs) {\r\n    const start = out.length === 0 ? 0 : 1;\r\n    for (let i = start; i < seg.length; i++) out.push(seg[i]);\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/fracture/collapse.ts\r\nfunction generateCollapseFracture(o) {\r\n  const { width: w, height: h, seed } = o;\r\n  const diag = Math.hypot(w, h);\r\n  const pad = 0.6 * diag;\r\n  const sep = Math.abs((o.collapse.angleB - o.collapse.angleA + 90) % 180 - 90);\r\n  const theta = Math.min(16, (Math.max(sep, 35) - 20) / 2);\r\n  const slopeMax = Math.tan(degToRad(theta));\r\n  const rngA = rngFor(seed, \"collapse:countA\");\r\n  const rngB = rngFor(seed, \"collapse:countB\");\r\n  const countA = resolveCount(o.collapse.countA, rngA);\r\n  const countB = resolveCount(o.collapse.countB, rngB);\r\n  const famA = buildFamily(o, \"A\", o.collapse.angleA, countA, slopeMax, w, h, pad);\r\n  const famB = buildFamily(o, \"B\", o.collapse.angleB, countB, slopeMax, w, h, pad);\r\n  const nA = famA.length;\r\n  const nB = famB.length;\r\n  const cross = [];\r\n  for (let i = 0; i < nA; i++) {\r\n    const row = [];\r\n    const A = famA[i];\r\n    for (let j = 0; j < nB; j++) {\r\n      const B = famB[j];\r\n      let found = null;\r\n      outer: for (let p = 0; p < A.pts.length - 1; p++) {\r\n        for (let q = 0; q < B.pts.length - 1; q++) {\r\n          const hit = segmentIntersection(A.pts[p], A.pts[p + 1], B.pts[q], B.pts[q + 1]);\r\n          if (hit) {\r\n            found = {\r\n              p: hit.p,\r\n              sA: A.cum[p] + hit.ta * (A.cum[p + 1] - A.cum[p]),\r\n              sB: B.cum[q] + hit.tb * (B.cum[q + 1] - B.cum[q])\r\n            };\r\n            break outer;\r\n          }\r\n        }\r\n      }\r\n      if (!found) {\r\n        const fallback = [w / 2, h / 2];\r\n        found = { p: fallback, sA: A.cum[A.cum.length - 1] / 2, sB: B.cum[B.cum.length - 1] / 2 };\r\n      }\r\n      row.push(found);\r\n    }\r\n    cross.push(row);\r\n  }\r\n  const gapA = approxGap(famA);\r\n  const gapB = approxGap(famB);\r\n  const maxOff = 0.2 * Math.min(gapA, gapB);\r\n  const sliceA = /* @__PURE__ */ new Map();\r\n  const sliceB = /* @__PURE__ */ new Map();\r\n  for (let i = 0; i < nA; i++) {\r\n    for (let j = 0; j < nB - 1; j++) {\r\n      sliceA.set(\r\n        `${i}:${j}`,\r\n        jagSlice(famA[i], cross[i][j].sA, cross[i][j + 1].sA, cross[i][j].p, cross[i][j + 1].p, o, hashCombine(seed, hashString(\"collapse:Ajag\"), i, j), maxOff)\r\n      );\r\n    }\r\n  }\r\n  for (let j = 0; j < nB; j++) {\r\n    for (let i = 0; i < nA - 1; i++) {\r\n      sliceB.set(\r\n        `${j}:${i}`,\r\n        jagSlice(famB[j], cross[i][j].sB, cross[i + 1][j].sB, cross[i][j].p, cross[i + 1][j].p, o, hashCombine(seed, hashString(\"collapse:Bjag\"), j, i), maxOff)\r\n      );\r\n    }\r\n  }\r\n  const keepB = (j, i) => {\r\n    if (j <= 0 || j >= nB - 1) return true;\r\n    if (o.collapse.merge <= 0) return true;\r\n    return rand01(o.seed, \"collapse:mergeB\", j, i) >= o.collapse.merge;\r\n  };\r\n  const rows = nA - 1;\r\n  const raw = [];\r\n  for (let i = 0; i < nA - 1; i++) {\r\n    for (let j = 0; j < nB - 1; j++) {\r\n      if (!keepB(j, i)) continue;\r\n      let j1 = j;\r\n      while (j1 + 1 < nB - 1 && !keepB(j1 + 1, i)) j1++;\r\n      const segs = [];\r\n      for (let jj = j; jj <= j1; jj++) segs.push(sliceA.get(`${i}:${jj}`));\r\n      segs.push(sliceB.get(`${j1 + 1}:${i}`));\r\n      for (let jj = j1; jj >= j; jj--) segs.push(reversePts(sliceA.get(`${i + 1}:${jj}`)));\r\n      segs.push(reversePts(sliceB.get(`${j}:${i}`)));\r\n      const poly = stitchLoop(segs);\r\n      const clipped = clipPolygonToRect(poly, w, h);\r\n      if (clipped.length >= 3) raw.push({ poly: clipped, row: rows - 1 - i });\r\n    }\r\n  }\r\n  const ranks = shuffledRanks(seed, \"collapse:z\", raw.length);\r\n  const shards = [];\r\n  for (let i = 0; i < raw.length; i++) {\r\n    const s = makeShard(seed, i, raw[i].poly, raw[i].row, ranks[i], o.seamOutsetPx);\r\n    if (s) shards.push(s);\r\n  }\r\n  const cracks = [];\r\n  const junctions = [];\r\n  let ci = 0;\r\n  for (let li = 1; li < famA.length - 1; li++) {\r\n    const segs = [];\r\n    for (let k = 0; k < nB - 1; k++) {\r\n      const s = sliceA.get(`${li}:${k}`);\r\n      if (s) segs.push(s);\r\n    }\r\n    if (segs.length === 0) continue;\r\n    let pts = concatPolylines2(segs);\r\n    const rngC = rngFor(seed, \"collapse:A:birth\", li);\r\n    if (li % 2 === 0) pts = reversePts(pts);\r\n    const grow = 0.3 + rngC() * 0.12;\r\n    const birth = Math.min(rngC() * 0.45, 0.97 - grow);\r\n    cracks.push(makeCrack(seed, `c${ci++}`, \"mesh\", pts, birth, grow));\r\n  }\r\n  for (let li = 1; li < famB.length - 1; li++) {\r\n    const rngC = rngFor(seed, \"collapse:B:birth\", li);\r\n    const grow = 0.3 + rngC() * 0.12;\r\n    const birthBase = Math.min(rngC() * 0.45, 0.97 - grow);\r\n    const spans = nA - 1;\r\n    const kept = [];\r\n    for (let i = 0; i < spans; i++) kept.push(keepB(li, i));\r\n    if (kept.every(Boolean)) {\r\n      const segs = [];\r\n      for (let k = 0; k < spans; k++) {\r\n        const s = sliceB.get(`${li}:${k}`);\r\n        if (s) segs.push(s);\r\n      }\r\n      if (segs.length === 0) continue;\r\n      let pts = concatPolylines2(segs);\r\n      if (li % 2 === 0) pts = reversePts(pts);\r\n      cracks.push(makeCrack(seed, `c${ci++}`, \"mesh\", pts, birthBase, grow));\r\n      continue;\r\n    }\r\n    for (let i0 = 0; i0 < spans; i0++) {\r\n      if (!kept[i0] || i0 > 0 && kept[i0 - 1]) continue;\r\n      const segs = [];\r\n      for (let k = i0; k < spans && kept[k]; k++) {\r\n        const s = sliceB.get(`${li}:${k}`);\r\n        if (s) segs.push(s);\r\n      }\r\n      if (segs.length === 0) continue;\r\n      let pts = concatPolylines2(segs);\r\n      if (li % 2 === 0) pts = reversePts(pts);\r\n      const birth = Math.min(birthBase + 0.05 * rand01(seed, \"collapse:Brun\", li, i0), 0.985 - grow);\r\n      cracks.push(makeCrack(seed, `c${ci++}`, \"mesh\", pts, birth, grow));\r\n      const ciRun = cracks.length - 1;\r\n      junctions.push({ crackIndex: ciRun, s: 0 }, { crackIndex: ciRun, s: cracks[ciRun].totalLen });\r\n    }\r\n  }\r\n  return { shards, cracks, rows, junctions, stubScale: Math.min(approxGap(famA), approxGap(famB)) };\r\n}\r\nfunction resolveCount(spec, rng) {\r\n  if (Array.isArray(spec)) {\r\n    const lo = Math.min(spec[0], spec[1]);\r\n    const hi = Math.max(spec[0], spec[1]);\r\n    return Math.max(1, Math.round(lo + rng() * (hi - lo)));\r\n  }\r\n  return Math.max(1, Math.round(spec));\r\n}\r\nfunction buildFamily(o, famKey, angleDeg, count, slopeMax, w, h, pad) {\r\n  const a = degToRad(angleDeg);\r\n  const dir = [Math.cos(a), Math.sin(a)];\r\n  const nrm = [-Math.sin(a), Math.cos(a)];\r\n  const corners = [\r\n    [0, 0],\r\n    [w, 0],\r\n    [w, h],\r\n    [0, h]\r\n  ];\r\n  let uMin = Infinity;\r\n  let uMax = -Infinity;\r\n  let vMin = Infinity;\r\n  let vMax = -Infinity;\r\n  for (const c of corners) {\r\n    const u = c[0] * dir[0] + c[1] * dir[1];\r\n    const v = c[0] * nrm[0] + c[1] * nrm[1];\r\n    uMin = Math.min(uMin, u);\r\n    uMax = Math.max(uMax, u);\r\n    vMin = Math.min(vMin, v);\r\n    vMax = Math.max(vMax, v);\r\n  }\r\n  const gap = (vMax - vMin) / (count + 1);\r\n  const offsets = [vMin - 0.75 * gap];\r\n  const rngJ = rngFor(o.seed, `collapse:${famKey}:offsets`);\r\n  for (let k = 0; k < count; k++) {\r\n    offsets.push(vMin + gap * (k + 1) + (rngJ() - 0.5) * gap * 0.55);\r\n  }\r\n  offsets.push(vMax + 0.75 * gap);\r\n  const u0 = uMin - pad;\r\n  const u1 = uMax + pad;\r\n  const segments = Math.max(8, Math.round((u1 - u0) / 120));\r\n  const lines = [];\r\n  for (let li = 0; li < offsets.length; li++) {\r\n    const gapPrev = li > 0 ? offsets[li] - offsets[li - 1] : gap;\r\n    const gapNext = li < offsets.length - 1 ? offsets[li + 1] - offsets[li] : gap;\r\n    const corridorHalf = 0.45 * Math.max(4, Math.min(gapPrev, gapNext));\r\n    const { u, v } = baseLine({\r\n      seed: o.seed,\r\n      group: `collapse:${famKey}`,\r\n      key: li,\r\n      u0,\r\n      u1,\r\n      segments,\r\n      offset: offsets[li],\r\n      waveAmp: o.collapse.waviness * gap * 0.2,\r\n      deviation: o.deviation,\r\n      devAmpMax: gap,\r\n      slopeMax,\r\n      corridorHalf\r\n    });\r\n    const pts = u.map((uu, k) => [dir[0] * uu + nrm[0] * v[k], dir[1] * uu + nrm[1] * v[k]]);\r\n    lines.push({ pts, cum: cumulativeLengths(pts) });\r\n  }\r\n  return lines;\r\n}\r\nfunction approxGap(fam) {\r\n  if (fam.length < 2) return 40;\r\n  const a = fam[0].pts[0];\r\n  const b = fam[fam.length - 1].pts[0];\r\n  return Math.max(8, Math.hypot(b[0] - a[0], b[1] - a[1]) / (fam.length - 1));\r\n}\r\nfunction jagSlice(line, s0, s1, p0, p1, o, jagSeed, maxOff) {\r\n  const lo = Math.min(s0, s1);\r\n  const hi = Math.max(s0, s1);\r\n  const base = [lo === s0 ? p0 : p1];\r\n  for (let i = 0; i < line.pts.length; i++) {\r\n    if (line.cum[i] > lo + 0.5 && line.cum[i] < hi - 0.5) base.push(line.pts[i]);\r\n  }\r\n  base.push(lo === s0 ? p1 : p0);\r\n  let out = subdivideMidpoint(base, o.edgeDetail, o.jaggedness * 0.45, jagSeed, maxOff);\r\n  if (lo !== s0) out = reversePts(out);\r\n  return out;\r\n}\r\nfunction concatPolylines2(segs) {\r\n  const out = [];\r\n  for (const seg of segs) {\r\n    const start = out.length === 0 ? 0 : 1;\r\n    for (let i = start; i < seg.length; i++) out.push(seg[i]);\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/fracture/hero.ts\r\nfunction generateHeroFracture(o) {\r\n  const w = o.width;\r\n  const h = o.height;\r\n  const minDim = Math.min(w, h);\r\n  const baseR = o.hero.sizeFrac * minDim;\r\n  const centers = layoutCenters(o, baseR);\r\n  const shards = [];\r\n  for (let k = 0; k < centers.length; k++) {\r\n    const rng = rngFor(o.seed, \"hero\", k);\r\n    const nV = 11 + Math.floor(rng() * 5);\r\n    const rotOff = rng() * TAU;\r\n    const rScale = 0.88 + rng() * 0.24;\r\n    const slot = TAU / nV;\r\n    const ring = [];\r\n    for (let i = 0; i < nV; i++) {\r\n      const ang = rotOff + i * slot + (rng() - 0.5) * slot * 0.55;\r\n      const rad = baseR * rScale * (0.76 + 0.46 * rng());\r\n      ring.push([centers[k][0] + Math.cos(ang) * rad, centers[k][1] + Math.sin(ang) * rad]);\r\n    }\r\n    ring.push(ring[0]);\r\n    const jagged = subdivideMidpoint(\r\n      ring,\r\n      o.edgeDetail,\r\n      o.jaggedness * 0.5,\r\n      rngFor(o.seed, \"hero:jag\", k)() * 4294967295,\r\n      baseR * 0.12\r\n    );\r\n    jagged.pop();\r\n    const shard = makeShard(o.seed, k, jagged, 0, k, o.seamOutsetPx);\r\n    if (shard) shards.push(shard);\r\n  }\r\n  return { shards, cracks: [], junctions: [], stubScale: baseR };\r\n}\r\nfunction layoutCenters(o, baseR) {\r\n  const cx = o.width / 2;\r\n  const cy = o.height / 2;\r\n  const K = o.hero.count;\r\n  if (K === 1) return [[cx, cy]];\r\n  const rng = rngFor(o.seed, \"hero:layout\");\r\n  const sep = baseR * (1.05 + 0.9 * o.hero.spread) * (1 - 0.72 * o.hero.overlap);\r\n  if (K === 2) {\r\n    const dx = baseR * 0.22 * (rng() * 2 - 1);\r\n    return [\r\n      [cx + dx, cy - sep / 2],\r\n      [cx - dx, cy + sep / 2]\r\n    ];\r\n  }\r\n  const a0 = -Math.PI / 2 + (rng() - 0.5) * 0.5;\r\n  const out = [];\r\n  for (let k = 0; k < 3; k++) {\r\n    const a = a0 + k * TAU / 3;\r\n    out.push([cx + Math.cos(a) * sep * 0.62, cy + Math.sin(a) * sep * 0.62]);\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/fracture/web.ts\r\nfunction wrapAngle(d) {\r\n  return ((d + Math.PI) % TAU + TAU) % TAU - Math.PI;\r\n}\r\nfunction webOrigin(w, h, dirDeg, distance) {\r\n  const dirRad = degToRad(dirDeg);\r\n  const maxDim = Math.max(w, h);\r\n  const cx = w / 2;\r\n  const cy = h / 2;\r\n  const ux = -Math.cos(dirRad);\r\n  const uy = -Math.sin(dirRad);\r\n  let tBound = Infinity;\r\n  if (ux > 1e-9) tBound = Math.min(tBound, (w - cx) / ux);\r\n  else if (ux < -1e-9) tBound = Math.min(tBound, -cx / ux);\r\n  if (uy > 1e-9) tBound = Math.min(tBound, (h - cy) / uy);\r\n  else if (uy < -1e-9) tBound = Math.min(tBound, -cy / uy);\r\n  if (!Number.isFinite(tBound)) tBound = maxDim;\r\n  const dist = Math.max(distance * maxDim, tBound + 0.2 * maxDim);\r\n  return [cx + ux * dist, cy + uy * dist];\r\n}\r\nfunction generateWebFracture(o) {\r\n  const { width: w, height: h, seed } = o;\r\n  const N = o.web.rays;\r\n  const M = o.web.rings;\r\n  const irr = o.web.irregularity;\r\n  const ringDetail = Math.min(1, o.edgeDetail);\r\n  const dirRad = degToRad(o.web.dir);\r\n  const maxDim = Math.max(w, h);\r\n  const P = webOrigin(w, h, o.web.dir, o.web.distance);\r\n  const [px, py] = P;\r\n  const corners = [\r\n    [0, 0],\r\n    [w, 0],\r\n    [w, h],\r\n    [0, h]\r\n  ];\r\n  let maxDev = 0;\r\n  let maxCornerDist = 0;\r\n  for (const c of corners) {\r\n    const dev = Math.abs(wrapAngle(Math.atan2(c[1] - py, c[0] - px) - dirRad));\r\n    if (dev > maxDev) maxDev = dev;\r\n    const d = Math.hypot(c[0] - px, c[1] - py);\r\n    if (d > maxCornerDist) maxCornerDist = d;\r\n  }\r\n  const slot0 = 2 * maxDev / Math.max(1, N - 1);\r\n  const spread = Math.min(TAU * 0.95, 2 * maxDev + 2 * slot0);\r\n  const slot = spread / Math.max(1, N - 1);\r\n  const nearX = Math.max(0, Math.min(w, px));\r\n  const nearY = Math.max(0, Math.min(h, py));\r\n  const dNear = Math.hypot(px - nearX, py - nearY);\r\n  const margin = 0.05 * maxDim;\r\n  const r0 = Math.max(5, dNear - margin);\r\n  const R = maxCornerDist / Math.max(0.2, Math.cos(slot / 2)) * 1.06 + margin;\r\n  const asym = o.rings.asymmetry;\r\n  const strongDir = dirRad + (rand01(seed, \"web:strongDir\") - 0.5) * spread;\r\n  const keepArc = (j, a) => {\r\n    if (j <= 0 || j >= M) return true;\r\n    if (o.rings.partial <= 0) return true;\r\n    const ramp = M >= 3 ? (j - 1) / (M - 2) : 1;\r\n    let keepProb = 1 - o.rings.partial * (0.1 + 0.45 * ramp);\r\n    if (asym > 0) {\r\n      const side = 0.5 + 0.5 * Math.cos(angles[a] - strongDir);\r\n      keepProb = Math.max(0.02, 1 - (1 - keepProb) * (1 + asym * 1.6 * (1 - side)));\r\n    }\r\n    return rand01(seed, \"web:arcKeep\", j, a) < keepProb;\r\n  };\r\n  const angles = [];\r\n  for (let a = 0; a < N; a++) {\r\n    const base = dirRad - spread / 2 + (N > 1 ? a / (N - 1) * spread : 0);\r\n    const jit = (rand01(seed, \"web:angle\", a) - 0.5) * 2 * 0.15 * slot * o.rays.angleJitter;\r\n    angles.push(base + jit);\r\n  }\r\n  const weights = [];\r\n  {\r\n    let sum = 0;\r\n    for (let j = 1; j <= M; j++) {\r\n      const wj = o.rings.spacing === \"uniform\" ? 1 : Math.pow(1.35, j - 1);\r\n      weights.push(wj);\r\n      sum += wj;\r\n    }\r\n    for (let j = 0; j < M; j++) weights[j] /= sum;\r\n  }\r\n  const ringR = [0];\r\n  {\r\n    let cum = 0;\r\n    for (let j = 1; j <= M; j++) {\r\n      const jit = (rand01(seed, \"web:ringbase\", j) - 0.5) * 2 * 0.3 * o.rings.jitter;\r\n      cum += weights[j - 1] * (1 + jit);\r\n      ringR.push(cum);\r\n    }\r\n    for (let j = 0; j <= M; j++) ringR[j] = r0 + (R - r0) * ringR[j] / cum;\r\n  }\r\n  const radii = [];\r\n  for (let a = 0; a < N; a++) {\r\n    const row = [r0];\r\n    for (let j = 1; j <= M; j++) {\r\n      if (j === M) {\r\n        row.push(ringR[M]);\r\n        continue;\r\n      }\r\n      const gUp = ringR[j + 1] - ringR[j];\r\n      const gDn = ringR[j] - ringR[j - 1];\r\n      const bound = 0.4 * Math.max(1, Math.min(gUp, gDn));\r\n      const pert = (rand01(seed, \"web:ringpert\", a, j) - 0.5) * 2 * (0.3 + 0.7 * irr) * bound;\r\n      row.push(ringR[j] + pert);\r\n    }\r\n    radii.push(row);\r\n  }\r\n  const wobAmp = (0.05 * o.rays.waviness + 0.04 * irr) * slot;\r\n  const anchorAngle = (a, j) => angles[a] + fbm1D(hashCombine(seed, hashString(\"web:wob\"), a), j * 0.8, 2) * wobAmp;\r\n  const anchors = [];\r\n  for (let a = 0; a < N; a++) {\r\n    const row = [];\r\n    for (let j = 0; j <= M; j++) {\r\n      const ang = anchorAngle(a, j);\r\n      row.push([px + Math.cos(ang) * radii[a][j], py + Math.sin(ang) * radii[a][j]]);\r\n    }\r\n    anchors.push(row);\r\n  }\r\n  const rayEdges = /* @__PURE__ */ new Map();\r\n  for (let a = 0; a < N; a++) {\r\n    for (let j = 0; j < M; j++) {\r\n      const A = anchors[a][j];\r\n      const B = anchors[a][j + 1];\r\n      const mid = [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];\r\n      const lateralGap = Math.min((radii[a][j] + radii[a][j + 1]) / 2 * slot, 0.12 * maxDim);\r\n      rayEdges.set(\r\n        `${a}:${j}`,\r\n        subdivideMidpoint([A, mid, B], o.edgeDetail, o.jaggedness * 0.5, hashCombine(seed, hashString(\"web:rayjag\"), a, j), 0.18 * lateralGap)\r\n      );\r\n    }\r\n  }\r\n  const ringEdges = /* @__PURE__ */ new Map();\r\n  for (let j = 0; j <= M; j++) {\r\n    for (let a = 0; a + 1 < N; a++) {\r\n      const b = a + 1;\r\n      const A = anchors[a][j];\r\n      const B = anchors[b][j];\r\n      const angA = anchorAngle(a, j);\r\n      const angB = anchorAngle(b, j);\r\n      const rA = radii[a][j];\r\n      const rB = radii[b][j];\r\n      const base = [A];\r\n      for (let s = 1; s <= 2; s++) {\r\n        const f = s / 3;\r\n        const ang = lerp(angA, angB, f);\r\n        const r = lerp(rA, rB, f);\r\n        base.push([px + Math.cos(ang) * r, py + Math.sin(ang) * r]);\r\n      }\r\n      base.push(B);\r\n      const gapDown = j > 0 ? Math.min(rA - radii[a][j - 1], rB - radii[b][j - 1]) : r0;\r\n      const gapUp = j < M ? Math.min(radii[a][j + 1] - rA, radii[b][j + 1] - rB) : gapDown;\r\n      const minGap = Math.max(1, Math.min(gapDown, gapUp, 0.1 * maxDim));\r\n      ringEdges.set(\r\n        `${j}:${a}`,\r\n        subdivideMidpoint(base, ringDetail, o.jaggedness * 0.22, hashCombine(seed, hashString(\"web:ringjag\"), j, a), 0.18 * minGap)\r\n      );\r\n    }\r\n  }\r\n  const raw = [];\r\n  for (let j = 0; j < M; j++) {\r\n    for (let aL = 0; aL + 1 < N; aL++) {\r\n      if (!keepArc(j, aL)) continue;\r\n      let j1 = j;\r\n      while (j1 + 1 < M && !keepArc(j1 + 1, aL)) j1++;\r\n      const aR = aL + 1;\r\n      const segs = [];\r\n      for (let jj = j; jj <= j1; jj++) segs.push(rayEdges.get(`${aL}:${jj}`));\r\n      segs.push(ringEdges.get(`${j1 + 1}:${aL}`));\r\n      for (let jj = j1; jj >= j; jj--) segs.push(reversePts(rayEdges.get(`${aR}:${jj}`)));\r\n      segs.push(reversePts(ringEdges.get(`${j}:${aL}`)));\r\n      const clipped = clipPolygonToRect(stitchLoop(segs), w, h);\r\n      if (clipped.length >= 3) raw.push({ poly: clipped, ring: j + 1 });\r\n    }\r\n  }\r\n  const ranks = shuffledRanks(seed, \"web:z\", raw.length);\r\n  const shards = [];\r\n  for (let i = 0; i < raw.length; i++) {\r\n    const s = makeShard(seed, i, raw[i].poly, raw[i].ring, ranks[i], o.seamOutsetPx);\r\n    if (s) shards.push(s);\r\n  }\r\n  const cracks = [];\r\n  const junctions = [];\r\n  let cid = 0;\r\n  for (let a = 0; a < N; a++) {\r\n    const pts = [];\r\n    for (let j = 0; j < M; j++) {\r\n      const e = rayEdges.get(`${a}:${j}`);\r\n      for (let k = j === 0 ? 0 : 1; k < e.length; k++) pts.push(e[k]);\r\n    }\r\n    const birth = rand01(seed, \"web:raybirth\", a) * 0.06;\r\n    cracks.push(makeCrack(seed, `wr${cid++}`, \"ray\", pts, birth, 0.42 + rand01(seed, \"web:raygrow\", a) * 0.12, true));\r\n  }\r\n  for (let j = 1; j < M; j++) {\r\n    let a = 0;\r\n    while (a + 1 < N) {\r\n      if (!keepArc(j, a)) {\r\n        a++;\r\n        continue;\r\n      }\r\n      const runStart = a;\r\n      const pts = [];\r\n      while (a + 1 < N && keepArc(j, a)) {\r\n        const e = ringEdges.get(`${j}:${a}`);\r\n        for (let k = a === runStart ? 0 : 1; k < e.length; k++) pts.push(e[k]);\r\n        a++;\r\n      }\r\n      if (pts.length >= 2) {\r\n        const birth = 0.08 + j / M * 0.2 + rand01(seed, \"web:ringbirth\", j, runStart) * 0.05;\r\n        cracks.push(makeCrack(seed, `wg${cid++}`, \"ring\", pts, Math.min(birth, 0.9), 0.28, false));\r\n      }\r\n    }\r\n  }\r\n  const stubScale = Math.sqrt(w * h / Math.max(1, shards.length));\r\n  return { shards, cracks, maxRing: M, junctions, stubScale };\r\n}\r\n\r\n// src/fracture/corners.ts\r\nfunction chordIsInterior(pts, ci, vi) {\r\n  const n = pts.length;\r\n  const A = pts[ci];\r\n  const B = pts[vi];\r\n  const mid = [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];\r\n  if (!pointInPolygon(mid, pts)) return false;\r\n  for (let j = 0; j < n; j++) {\r\n    const k = (j + 1) % n;\r\n    if (j === ci || k === ci || j === vi || k === vi) continue;\r\n    const hit = segmentIntersection(pts[j], pts[k], A, B);\r\n    if (hit && hit.ta > 1e-6 && hit.ta < 1 - 1e-6 && hit.tb > 1e-6 && hit.tb < 1 - 1e-6) return false;\r\n  }\r\n  return true;\r\n}\r\nfunction applyCornerRelief(o, shards, cracks) {\r\n  if (o.corners === false || o.corners.relief <= 0 || o.mode === \"hero\") return;\r\n  const { width: w, height: h, seed } = o;\r\n  const relief = o.corners.relief;\r\n  const eps = 1e-3;\r\n  const onBorder = (a, b) => a[0] < eps && b[0] < eps || a[0] > w - eps && b[0] > w - eps || a[1] < eps && b[1] < eps || a[1] > h - eps && b[1] > h - eps;\r\n  const baseN = shards.length;\r\n  let maxZ = 0;\r\n  for (const s of shards) if (s.z > maxZ) maxZ = s.z;\r\n  let appended = 0;\r\n  let crackId = 0;\r\n  const corners = [\r\n    [0, 0],\r\n    [w, 0],\r\n    [w, h],\r\n    [0, h]\r\n  ];\r\n  for (let c = 0; c < corners.length; c++) {\r\n    const C = corners[c];\r\n    let ownerIdx = -1;\r\n    let owners = 0;\r\n    for (let si = 0; si < baseN; si++) {\r\n      const poly = shards[si].polygon;\r\n      for (let p = 0; p + 1 < poly.length; p += 2) {\r\n        if (Math.abs(poly[p] - C[0]) < eps && Math.abs(poly[p + 1] - C[1]) < eps) {\r\n          owners++;\r\n          ownerIdx = si;\r\n          break;\r\n        }\r\n      }\r\n      if (owners > 1) break;\r\n    }\r\n    if (owners !== 1) continue;\r\n    const owner = shards[ownerIdx];\r\n    if ((o.mode === \"radial\" || o.mode === \"web\") && owner.ringIndex === 0) continue;\r\n    const raw = unflattenPts(owner.polygon);\r\n    const n = raw.length;\r\n    if (n < 5) continue;\r\n    let ci0 = -1;\r\n    for (let i = 0; i < n; i++) {\r\n      if (Math.abs(raw[i][0] - C[0]) < eps && Math.abs(raw[i][1] - C[1]) < eps) {\r\n        ci0 = i;\r\n        break;\r\n      }\r\n    }\r\n    if (ci0 < 0) continue;\r\n    if (!onBorder(raw[(ci0 - 1 + n) % n], C) || !onBorder(C, raw[(ci0 + 1) % n])) continue;\r\n    const pts = [...raw.slice(ci0), ...raw.slice(0, ci0)];\r\n    const jit = 0.8 + 0.4 * rand01(seed, \"corner\", c);\r\n    const reach = relief * Math.min(0.55 * Math.sqrt(owner.area), 95) * jit;\r\n    const distC = (i) => Math.hypot(pts[i][0] - C[0], pts[i][1] - C[1]);\r\n    const mid = Math.floor(n / 2);\r\n    const pick = (lo, hi, step) => {\r\n      let best = -1;\r\n      let bestErr = Infinity;\r\n      for (let i = lo; step > 0 ? i <= hi : i >= hi; i += step) {\r\n        if (i <= 1 || i >= n - 1) continue;\r\n        if (distC(i) < 8) continue;\r\n        if (!chordIsInterior(pts, 0, i)) continue;\r\n        const err = Math.abs(distC(i) - reach);\r\n        if (err < bestErr) {\r\n          bestErr = err;\r\n          best = i;\r\n        }\r\n      }\r\n      return best;\r\n    };\r\n    const vF = pick(2, mid, 1);\r\n    const vB = pick(n - 2, mid + 1, -1);\r\n    const targets = [];\r\n    if (vF > 0) targets.push(vF);\r\n    if (vB > 0 && vB !== vF) targets.push(vB);\r\n    targets.sort((a, b) => a - b);\r\n    if (targets.length === 0) continue;\r\n    const pieces = [];\r\n    pieces.push(pts.slice(0, targets[0] + 1));\r\n    for (let k = 0; k + 1 < targets.length; k++) {\r\n      pieces.push([pts[0], ...pts.slice(targets[k], targets[k + 1] + 1)]);\r\n    }\r\n    pieces.push([pts[0], ...pts.slice(targets[targets.length - 1])]);\r\n    const built = [];\r\n    let ok = true;\r\n    for (let k = 0; k < pieces.length; k++) {\r\n      const idx = k === 0 ? ownerIdx : baseN + appended + (k - 1);\r\n      const z = k === 0 ? owner.z : maxZ + 1 + appended + (k - 1);\r\n      const sh = makeShard(seed, idx, pieces[k], owner.ringIndex, z, o.seamOutsetPx);\r\n      if (!sh) {\r\n        ok = false;\r\n        break;\r\n      }\r\n      built.push(sh);\r\n    }\r\n    if (!ok) continue;\r\n    shards[ownerIdx] = built[0];\r\n    for (let k = 1; k < built.length; k++) shards.push(built[k]);\r\n    appended += built.length - 1;\r\n    const birth = 0 + 0.06 * rand01(seed, \"corner:birth\", c);\r\n    for (const v of targets) {\r\n      cracks.push(makeCrack(seed, `cr${crackId++}`, \"split\", [C, pts[v]], birth, 0.32, false));\r\n    }\r\n  }\r\n}\r\n\r\n// src/fracture/stubs.ts\r\nvar MAX_TOTAL_STUBS = 200;\r\nfunction addStubCracks(o, cracks, junctions, localScale) {\r\n  if (o.stubs === false || o.stubs.maxPerCrack <= 0) return;\r\n  const { width: w, height: h, seed } = o;\r\n  const mainCount = cracks.length;\r\n  const recs = [];\r\n  const forkSeeds = [];\r\n  const tryStub = (parentIdx, sStation, keyA, keyB, group, freeAngle) => {\r\n    const c = cracks[parentIdx];\r\n    const rs = (field) => rand01(seed, `${group}:${field}`, keyA, keyB);\r\n    const pts = unflattenPts(c.points);\r\n    const p = pointAtLength(pts, c.cumLen, sStation);\r\n    if (p[0] < 2 || p[0] > w - 2 || p[1] < 2 || p[1] > h - 2) return;\r\n    const tan = tangentAtLength(pts, c.cumLen, sStation);\r\n    const side = rs(\"side\") < 0.5 ? 1 : -1;\r\n    const angDeg = freeAngle ? 25 + 55 * rs(\"ang\") : 20 + 35 * rs(\"ang\");\r\n    const ang = degToRad(angDeg) * side;\r\n    const cos = Math.cos(ang);\r\n    const sin = Math.sin(ang);\r\n    const dir = [tan[0] * cos - tan[1] * sin, tan[0] * sin + tan[1] * cos];\r\n    const sinA = Math.max(0.2, Math.abs(Math.sin(ang)));\r\n    const L = Math.min(45, (0.18 + 0.45 * rs(\"len\")) * localScale, 0.55 * localScale / sinA);\r\n    if (L < 4) return;\r\n    const arrival = c.birth + c.growDuration * (1 - Math.pow(Math.max(0, 1 - sStation / Math.max(1e-6, c.totalLen)), 0.25));\r\n    if (arrival > 0.965) return;\r\n    const grow = Math.min(0.04 + 0.04 * rs(\"grow\"), 0.985 - arrival);\r\n    if (grow < 0.02) return;\r\n    const curve = (rs(\"curve\") - 0.5) * 0.24 * L;\r\n    const perp = [-dir[1], dir[0]];\r\n    const base = [\r\n      p,\r\n      [p[0] + dir[0] * 0.55 * L + perp[0] * curve, p[1] + dir[1] * 0.55 * L + perp[1] * curve],\r\n      [p[0] + dir[0] * L, p[1] + dir[1] * L]\r\n    ];\r\n    const jag = subdivideMidpoint(\r\n      base,\r\n      Math.min(2, o.edgeDetail),\r\n      o.jaggedness * 0.4,\r\n      hashCombine(seed, hashString(`${group}:jag`), keyA, keyB),\r\n      0.15 * L\r\n    );\r\n    const rec = { parent: parentIdx, pts: jag, birth: arrival, grow };\r\n    recs.push(rec);\r\n    if (rs(\"fork\") < 0.25) forkSeeds.push({ rec, key: hashCombine(keyA, keyB) });\r\n  };\r\n  for (let ci = 0; ci < mainCount; ci++) {\r\n    const c = cracks[ci];\r\n    if (c.kind === \"crush\" || c.totalLen < 30) continue;\r\n    const n = Math.min(1 + Math.floor(rand01(seed, \"stub:n\", ci) * 3.2), o.stubs.maxPerCrack);\r\n    for (let k = 0; k < n; k++) {\r\n      const s = (0.08 + 0.84 * rand01(seed, \"stub:s\", ci, k)) * c.totalLen;\r\n      tryStub(ci, s, ci, k, \"stub\", false);\r\n    }\r\n  }\r\n  if (o.stubs.atJunctions) {\r\n    for (let ji = 0; ji < junctions.length; ji++) {\r\n      if (rand01(seed, \"stub:junction\", ji) >= 0.3) continue;\r\n      const jn = junctions[ji];\r\n      tryStub(jn.crackIndex, jn.s, 1000003 + ji, 0, \"stubj\", true);\r\n    }\r\n  }\r\n  const forkRecs = [];\r\n  for (let fi = 0; fi < forkSeeds.length; fi++) {\r\n    const { rec, key } = forkSeeds[fi];\r\n    const rf = (field) => rand01(seed, `stubf:${field}`, key, fi);\r\n    const cum = cumulativeLengths(rec.pts);\r\n    const total = cum[cum.length - 1];\r\n    const sF = 0.6 * total;\r\n    const p = pointAtLength(rec.pts, cum, sF);\r\n    const tan = tangentAtLength(rec.pts, cum, sF);\r\n    const side = rf(\"side\") < 0.5 ? 1 : -1;\r\n    const ang = degToRad(15 + 15 * rf(\"ang\")) * side;\r\n    const cos = Math.cos(ang);\r\n    const sin = Math.sin(ang);\r\n    const dir = [tan[0] * cos - tan[1] * sin, tan[0] * sin + tan[1] * cos];\r\n    const L = 0.4 * total;\r\n    if (L < 4) continue;\r\n    const forkBirth = rec.birth + rec.grow * (1 - Math.pow(1 - 0.6, 0.25));\r\n    const forkGrow = Math.min(0.03 + 0.03 * rf(\"grow\"), 0.985 - forkBirth);\r\n    if (forkGrow < 0.02) continue;\r\n    const base = [\r\n      p,\r\n      [p[0] + dir[0] * 0.5 * L, p[1] + dir[1] * 0.5 * L],\r\n      [p[0] + dir[0] * L, p[1] + dir[1] * L]\r\n    ];\r\n    const jag = subdivideMidpoint(\r\n      base,\r\n      Math.min(2, o.edgeDetail),\r\n      o.jaggedness * 0.4,\r\n      hashCombine(seed, hashString(\"stubf:jag\"), key, fi),\r\n      0.15 * L\r\n    );\r\n    forkRecs.push({ parent: rec.parent, pts: jag, birth: forkBirth, grow: forkGrow });\r\n  }\r\n  const all = [...recs, ...forkRecs].slice(0, MAX_TOTAL_STUBS);\r\n  for (let si = 0; si < all.length; si++) {\r\n    const r = all[si];\r\n    const crack = makeCrack(seed, `st${si}`, \"stub\", r.pts, r.birth, r.grow, false);\r\n    crack.parent = r.parent;\r\n    cracks.push(crack);\r\n  }\r\n}\r\n\r\n// src/fracture/micro.ts\r\nfunction seedMicroShards(o, allCracks, ringIndexAt) {\r\n  const cracks = allCracks.filter((c) => c.kind !== \"stub\");\r\n  if (o.microCount <= 0 || cracks.length === 0) return [];\r\n  const cumTotals = [];\r\n  let total = 0;\r\n  for (const c of cracks) {\r\n    total += c.totalLen;\r\n    cumTotals.push(total);\r\n  }\r\n  if (total <= 0) return [];\r\n  const out = [];\r\n  for (let i = 0; i < o.microCount; i++) {\r\n    const rng = rngFor(o.seed, \"micro\", i);\r\n    const pickLen = rng() * total;\r\n    let ci = 0;\r\n    while (ci < cumTotals.length - 1 && cumTotals[ci] <= pickLen) ci++;\r\n    const crack = cracks[ci];\r\n    const pts = unflattenPts(crack.points);\r\n    const s = rng() * crack.totalLen;\r\n    const p = pointAtLength(pts, crack.cumLen, s);\r\n    const offAng = rng() * TAU;\r\n    const offDist = 1 + rng() * 4;\r\n    const origin = [p[0] + Math.cos(offAng) * offDist, p[1] + Math.sin(offAng) * offDist];\r\n    const sizeT = Math.pow(rng(), 1.6);\r\n    const size = lerp(o.microSizeRange[0], o.microSizeRange[1], sizeT);\r\n    const nPts = rng() < 0.6 ? 3 : 4;\r\n    const baseAng = rng() * TAU;\r\n    const elong = 0.45 + rng() * 0.55;\r\n    const poly = [];\r\n    for (let k = 0; k < nPts; k++) {\r\n      const a = baseAng + k / nPts * TAU + (rng() - 0.5) * 0.9;\r\n      const r = size * (0.5 + rng() * 0.6);\r\n      poly.push(Math.cos(a) * r, Math.sin(a) * r * elong);\r\n    }\r\n    const birth = clamp01(crack.birth + s / Math.max(1e-6, crack.totalLen) * crack.growDuration);\r\n    out.push({\r\n      id: `m${i}`,\r\n      polygon: poly,\r\n      origin,\r\n      hash: hashCombine(o.seed, hashString(\"micro\"), i),\r\n      birth,\r\n      ringIndex: ringIndexAt(origin)\r\n    });\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/fracture/index.ts\r\nfunction generateFracture(opts) {\r\n  const o = resolveFractureOptions(opts);\r\n  let shards;\r\n  let cracks;\r\n  let junctions;\r\n  let stubScale;\r\n  let ringIndexAt;\r\n  if (o.mode === \"title\") {\r\n    const res = generateTitleFracture(o);\r\n    shards = res.shards;\r\n    cracks = res.cracks;\r\n    junctions = res.junctions;\r\n    stubScale = res.stubScale;\r\n    const bandH = o.height / Math.max(1, Math.max(...shards.map((s) => s.ringIndex)) + 1);\r\n    ringIndexAt = (origin) => Math.max(0, Math.min(Math.floor(origin[1] / bandH), 64));\r\n  } else if (o.mode === \"hero\") {\r\n    const res = generateHeroFracture(o);\r\n    shards = res.shards;\r\n    cracks = res.cracks;\r\n    junctions = res.junctions;\r\n    stubScale = res.stubScale;\r\n    ringIndexAt = () => 0;\r\n  } else if (o.mode === \"web\") {\r\n    const res = generateWebFracture(o);\r\n    shards = res.shards;\r\n    cracks = res.cracks;\r\n    junctions = res.junctions;\r\n    stubScale = res.stubScale;\r\n    const [Px, Py] = webOrigin(o.width, o.height, o.web.dir, o.web.distance);\r\n    let dMin = Infinity;\r\n    let dMax = 0;\r\n    for (const c of [[0, 0], [o.width, 0], [o.width, o.height], [0, o.height]]) {\r\n      const d = Math.hypot(c[0] - Px, c[1] - Py);\r\n      if (d < dMin) dMin = d;\r\n      if (d > dMax) dMax = d;\r\n    }\r\n    ringIndexAt = (origin) => {\r\n      const d = Math.hypot(origin[0] - Px, origin[1] - Py);\r\n      return Math.max(0, Math.min(Math.round((d - dMin) / Math.max(1, dMax - dMin) * (res.maxRing + 1)), res.maxRing + 1));\r\n    };\r\n  } else if (o.mode === \"collapse\") {\r\n    const res = generateCollapseFracture(o);\r\n    shards = res.shards;\r\n    cracks = res.cracks;\r\n    junctions = res.junctions;\r\n    stubScale = res.stubScale;\r\n    const rowH = o.height / Math.max(1, res.rows);\r\n    ringIndexAt = (origin) => Math.max(0, Math.min(Math.floor((o.height - origin[1]) / rowH), res.rows - 1));\r\n  } else {\r\n    const res = generateRadialFracture(o);\r\n    shards = res.shards;\r\n    cracks = res.cracks;\r\n    junctions = res.junctions;\r\n    stubScale = res.stubScale;\r\n    const R = Math.hypot(Math.max(o.impact[0], o.width - o.impact[0]), Math.max(o.impact[1], o.height - o.impact[1]));\r\n    ringIndexAt = (origin) => {\r\n      const d = Math.hypot(origin[0] - o.impact[0], origin[1] - o.impact[1]);\r\n      return Math.max(0, Math.min(Math.round(d / Math.max(1, R) * (res.maxRing + 1)), res.maxRing + 1));\r\n    };\r\n  }\r\n  applyCornerRelief(o, shards, cracks);\r\n  addStubCracks(o, cracks, junctions, stubScale);\r\n  const micro = seedMicroShards(o, cracks, ringIndexAt);\r\n  const pattern = {\r\n    version: 7,\r\n    mode: o.mode,\r\n    width: o.width,\r\n    height: o.height,\r\n    seed: o.seed,\r\n    instanceId: o.instanceId,\r\n    impact: o.impact,\r\n    shards,\r\n    cracks,\r\n    micro\r\n  };\r\n  return deepFreeze(pattern);\r\n}\r\nfunction deepFreeze(obj) {\r\n  if (obj && typeof obj === \"object\" && !Object.isFrozen(obj)) {\r\n    Object.freeze(obj);\r\n    for (const key of Object.keys(obj)) {\r\n      deepFreeze(obj[key]);\r\n    }\r\n  }\r\n  return obj;\r\n}\r\n\r\n// src/motion/timeline.ts\r\nfunction resolvePhase(t, tl) {\r\n  const crackProgress = tl.crackEnd <= tl.crackStart ? t >= tl.crackEnd ? 1 : 0 : clamp01((t - tl.crackStart) / (tl.crackEnd - tl.crackStart));\r\n  const shattering = Number.isFinite(tl.shatterStart) && t >= tl.shatterStart;\r\n  const shatterTau = shattering ? t - tl.shatterStart : 0;\r\n  let phase;\r\n  if (shattering) phase = \"shattering\";\r\n  else if (crackProgress <= 0) phase = \"intact\";\r\n  else if (crackProgress < 1) phase = \"cracking\";\r\n  else phase = \"cracked\";\r\n  return { phase, crackProgress, shatterTau };\r\n}\r\nvar staticCrackedTimeline = {\r\n  crackStart: -1,\r\n  crackEnd: 0,\r\n  shatterStart: Infinity\r\n};\r\n\r\n// src/motion/kinematics.ts\r\nfunction classifyOutlier(hash, outliers) {\r\n  const r = hashTo01(hashCombine(hash, hashString(\"outlier\")));\r\n  if (r < outliers.dropFraction) return \"dropped\";\r\n  if (r < outliers.dropFraction + outliers.slipFraction) return \"slipped\";\r\n  if (r < outliers.dropFraction + outliers.slipFraction + outliers.rebelFraction) return \"rebel\";\r\n  return \"none\";\r\n}\r\nfunction assignOutliers(pattern, outliers) {\r\n  const kinds = [];\r\n  let hasException = false;\r\n  for (const s of pattern.shards) {\r\n    if (pattern.mode === \"radial\" && s.ringIndex === 0) {\r\n      kinds.push(\"none\");\r\n      continue;\r\n    }\r\n    const k = classifyOutlier(s.hash, outliers);\r\n    if (k !== \"none\") hasException = true;\r\n    kinds.push(k);\r\n  }\r\n  if (outliers.dropFraction > 0) {\r\n    const maxDrop = Math.max(1, Math.ceil(pattern.shards.length * outliers.dropFraction));\r\n    const dropped = [];\r\n    for (let i = 0; i < kinds.length; i++) {\r\n      if (kinds[i] === \"dropped\") {\r\n        dropped.push({ i, r: hashTo01(hashCombine(pattern.shards[i].hash, hashString(\"outlier\"))) });\r\n      }\r\n    }\r\n    if (dropped.length > maxDrop) {\r\n      dropped.sort((a, b) => b.r - a.r || a.i - b.i);\r\n      for (let k = 0; k < dropped.length - maxDrop; k++) kinds[dropped[k].i] = \"slipped\";\r\n    }\r\n  }\r\n  if (!hasException && pattern.mode !== \"hero\" && // free-floating heroes get no forced exception\r\n  pattern.shards.length <= 12 && outliers.slipFraction + outliers.rebelFraction > 0) {\r\n    let best = -1;\r\n    let bestR = Infinity;\r\n    for (let i = 0; i < pattern.shards.length; i++) {\r\n      if (kinds[i] !== \"none\") continue;\r\n      if (pattern.mode === \"radial\" && pattern.shards[i].ringIndex === 0) continue;\r\n      const r = hashTo01(hashCombine(pattern.shards[i].hash, hashString(\"outlier\")));\r\n      if (r < bestR) {\r\n        bestR = r;\r\n        best = i;\r\n      }\r\n    }\r\n    if (best >= 0) kinds[best] = \"slipped\";\r\n  }\r\n  return kinds;\r\n}\r\nfunction flightOffset(tau, v0, g, drag) {\r\n  if (tau <= 0) return [0, 0];\r\n  if (drag <= 1e-6) {\r\n    return [v0[0] * tau + 0.5 * g[0] * tau * tau, v0[1] * tau + 0.5 * g[1] * tau * tau];\r\n  }\r\n  const e = Math.exp(-drag * tau);\r\n  const a = (1 - e) / drag;\r\n  const b = (drag * tau - 1 + e) / (drag * drag);\r\n  return [v0[0] * a + g[0] * b, v0[1] * a + g[1] * b];\r\n}\r\nfunction flightSpeed(tau, v0, g, drag) {\r\n  if (tau < 0) tau = 0;\r\n  let vx;\r\n  let vy;\r\n  if (drag <= 1e-6) {\r\n    vx = v0[0] + g[0] * tau;\r\n    vy = v0[1] + g[1] * tau;\r\n  } else {\r\n    const e = Math.exp(-drag * tau);\r\n    vx = v0[0] * e + g[0] * (1 - e) / drag;\r\n    vy = v0[1] * e + g[1] * (1 - e) / drag;\r\n  }\r\n  return Math.hypot(vx, vy);\r\n}\r\nfunction shardMotion(pattern, shard, fx, kind = \"none\") {\r\n  const rng = rngFor(shard.hash, \"motion\");\r\n  const sh = fx.shatter;\r\n  const jitter = (amount) => 1 + (rng() * 2 - 1) * sh.jitter * amount;\r\n  let dirX;\r\n  let dirY;\r\n  let speed;\r\n  if (typeof sh.direction === \"number\") {\r\n    const a = degToRad(sh.direction);\r\n    dirX = Math.cos(a);\r\n    dirY = Math.sin(a);\r\n    speed = sh.speed * jitter(0.5);\r\n  } else if (pattern.mode === \"radial\" || pattern.mode === \"web\") {\r\n    const dx = shard.centroid[0] - pattern.impact[0];\r\n    const dy = shard.centroid[1] - pattern.impact[1];\r\n    const d = Math.hypot(dx, dy) || 1;\r\n    const scatter = (rng() * 2 - 1) * 0.22;\r\n    const cos = Math.cos(scatter);\r\n    const sin = Math.sin(scatter);\r\n    dirX = dx / d * cos - dy / d * sin;\r\n    dirY = dx / d * sin + dy / d * cos;\r\n    speed = sh.speed * jitter(0.6) / (1 + 0.35 * shard.ringIndex);\r\n  } else if (pattern.mode === \"collapse\") {\r\n    dirX = (rng() * 2 - 1) * 0.18;\r\n    dirY = 0.15 + rng() * 0.25;\r\n    const n = Math.hypot(dirX, dirY) || 1;\r\n    dirX /= n;\r\n    dirY /= n;\r\n    speed = sh.speed * 0.18 * jitter(0.6);\r\n  } else {\r\n    const side = shard.centroid[0] < pattern.width / 2 ? -1 : 1;\r\n    if (sh.spread === \"apart\") {\r\n      dirX = side * (0.85 + rng() * 0.15);\r\n      dirY = 0.12 + rng() * 0.18;\r\n    } else if (sh.spread === \"slide\") {\r\n      dirX = side * (0.5 + rng() * 0.25);\r\n      dirY = 0.35 + rng() * 0.3;\r\n    } else {\r\n      dirX = (rng() * 2 - 1) * 0.35;\r\n      dirY = 0.45 + rng() * 0.4;\r\n    }\r\n    const n = Math.hypot(dirX, dirY) || 1;\r\n    dirX /= n;\r\n    dirY /= n;\r\n    speed = sh.speed * 0.55 * jitter(0.6);\r\n  }\r\n  const sizeFactor = 1 / Math.max(0.45, Math.pow(shard.area / 12e3, 0.25));\r\n  const omega = (rng() * 2 - 1) * sh.spinDegMax * sizeFactor;\r\n  const tumbleX = (rng() * 2 - 1) * sh.tumbleDegMax * sizeFactor;\r\n  const tumbleY = (rng() * 2 - 1) * sh.tumbleDegMax * sizeFactor;\r\n  let birthDelay = shard.ringIndex * sh.staggerPerRing * jitter(1);\r\n  if (pattern.mode === \"collapse\") {\r\n    birthDelay += rng() * sh.staggerPerRing * 1.5;\r\n  }\r\n  let vx = dirX * speed;\r\n  let vy = dirY * speed;\r\n  let omegaOut = omega;\r\n  if (kind === \"rebel\") {\r\n    const rr = rngFor(shard.hash, \"rebel\");\r\n    const ang = (rr() * 2 - 1) * 0.6;\r\n    const cos = Math.cos(ang);\r\n    const sin = Math.sin(ang);\r\n    const rvx = (vx * cos - vy * sin) * 1.35;\r\n    const rvy = (vx * sin + vy * cos) * 1.35;\r\n    vx = rvx;\r\n    vy = rvy;\r\n    omegaOut = omega * 1.6;\r\n    birthDelay = rr() < 0.5 ? birthDelay * 0.15 : birthDelay * 1.8 + 0.05;\r\n  }\r\n  return { v0: [vx, vy], omega: omegaOut, tumbleX, tumbleY, birthDelay };\r\n}\r\nfunction microMotion(pattern, origin, hash, ringIndex, fx) {\r\n  const rng = rngFor(hash, \"micromotion\");\r\n  const sh = fx.shatter;\r\n  let dirX;\r\n  let dirY;\r\n  if (pattern.mode === \"radial\" || pattern.mode === \"web\") {\r\n    const dx = origin[0] - pattern.impact[0];\r\n    const dy = origin[1] - pattern.impact[1];\r\n    const d = Math.hypot(dx, dy) || 1;\r\n    const scatter = (rng() * 2 - 1) * 0.5;\r\n    const cos = Math.cos(scatter);\r\n    const sin = Math.sin(scatter);\r\n    dirX = dx / d * cos - dy / d * sin;\r\n    dirY = dx / d * sin + dy / d * cos;\r\n  } else if (pattern.mode === \"collapse\") {\r\n    dirX = (rng() * 2 - 1) * 0.3;\r\n    dirY = 0.5 + rng() * 0.5;\r\n    const n = Math.hypot(dirX, dirY) || 1;\r\n    dirX /= n;\r\n    dirY /= n;\r\n  } else if (fx.shatter.spread !== \"fall\") {\r\n    const side = origin[0] < pattern.width / 2 ? -1 : 1;\r\n    const lateral = fx.shatter.spread === \"apart\" ? 0.8 : 0.5;\r\n    dirX = side * lateral + (rng() * 2 - 1) * 0.2;\r\n    dirY = (fx.shatter.spread === \"apart\" ? 0.2 : 0.5) + rng() * 0.4;\r\n    const n = Math.hypot(dirX, dirY) || 1;\r\n    dirX /= n;\r\n    dirY /= n;\r\n  } else {\r\n    const a = rng() * TAU;\r\n    dirX = Math.cos(a) * 0.4;\r\n    dirY = 0.6 + rng() * 0.5;\r\n    const n = Math.hypot(dirX, dirY) || 1;\r\n    dirX /= n;\r\n    dirY /= n;\r\n  }\r\n  const speed = sh.speed * fx.micro.speedScale * (0.35 + rng() * 0.75) / (1 + 0.25 * ringIndex);\r\n  const omega = (rng() * 2 - 1) * sh.spinDegMax * 3;\r\n  const birthDelay = ringIndex * sh.staggerPerRing * (0.6 + rng() * 0.8);\r\n  return { v0: [dirX * speed, dirY * speed], omega, tumbleX: 0, tumbleY: 0, birthDelay };\r\n}\r\n\r\n// src/render/params.ts\r\nvar defaultEffectParams = {\r\n  quality: \"normal\",\r\n  // glass cracks fast, holds (the money frame), then the pieces fall\r\n  timeline: { crackStart: 0.02, crackEnd: 0.2, shatterStart: 0.32 },\r\n  medium: \"content\",\r\n  refraction: { offsetPx: 6, rotateDeg: 0.9, scaleAmp: 0.016, tiltDeg: 1.6, perspectivePx: 800 },\r\n  optics: { brightnessAmp: 0.13, contrastAmp: 0.07, blurPx: 0.5, lightAngleDeg: -60, grainOpacity: 0.06, trackLight: false },\r\n  chroma: {\r\n    mode: \"shadow\",\r\n    offsetPx: 2.6,\r\n    angleDeg: 14,\r\n    opacity: 0.5,\r\n    blendMode: \"screen\",\r\n    colorA: \"rgba(255,42,84,0.55)\",\r\n    colorB: \"rgba(0,212,255,0.55)\"\r\n  },\r\n  facet: {\r\n    strength: 0.55,\r\n    tint: \"rgba(185,215,255,0.05)\",\r\n    opacity: 0.55,\r\n    blendMode: \"overlay\"\r\n  },\r\n  crackStyle: {\r\n    coreColor: \"rgba(255,255,255,0.92)\",\r\n    coreWidth: 1.1,\r\n    shadowColor: \"rgba(0,0,0,0.5)\",\r\n    shadowWidth: 2.4,\r\n    shadowOffsetPx: 1.4,\r\n    widthVariance: 0.6,\r\n    doubleEdge: 0.5,\r\n    subCracks: 0.6,\r\n    brightnessVar: 0.65,\r\n    hackleDensity: 0.55,\r\n    sparkle: true,\r\n    growth: \"snap\",\r\n    blendMode: \"multiply\"\r\n  },\r\n  bevel: {\r\n    widthPx: 1.5,\r\n    intensity: 0.7,\r\n    glintStrength: 0.6,\r\n    lightColor: \"rgba(255,255,255,0.95)\",\r\n    darkColor: \"rgba(8,12,18,0.75)\",\r\n    blendMode: \"screen\",\r\n    scatter: 0.65,\r\n    facetVariation: 0.6\r\n  },\r\n  crush: { punch: true, scaleTo: 0.9 },\r\n  outliers: {\r\n    dropFraction: 0.05,\r\n    slipFraction: 0.09,\r\n    rebelFraction: 0.12,\r\n    slipPx: 10,\r\n    slipRotDeg: 2.5\r\n  },\r\n  spectrum: {\r\n    count: 2,\r\n    opacity: 0.3,\r\n    bandWidth: 0.6,\r\n    blendMode: \"screen\",\r\n    edgeOnly: 0\r\n  },\r\n  edgeDistortion: { widthPx: 10, strength: 0, blurPx: 0.6 },\r\n  shatter: {\r\n    speed: 950,\r\n    gravity: [0, 1250],\r\n    drag: 1.6,\r\n    spinDegMax: 170,\r\n    tumbleDegMax: 70,\r\n    staggerPerRing: 0.035,\r\n    jitter: 0.4,\r\n    fadeOut: [0.86, 1],\r\n    spread: \"fall\",\r\n    preSpreadPx: 0\r\n  },\r\n  motionBlur: { dt: 0.012, opacityFalloff: 0.5, speedThreshold: 140, smearPx: 14, smearBlurPx: 1.2 },\r\n  micro: { opacity: 0.85, speedScale: 1.5, fill: \"rgba(255,255,255,0.85)\", fillAlt: \"rgba(20,26,34,0.6)\" },\r\n  settle: { amplitudePx: 0, frequency: 2.2 },\r\n  float: { bobPx: 10, swayPx: 6, rotDeg: 2.5, cycles: 1 }\r\n};\r\nfunction normalizeEffectParams(fx) {\r\n  const d = defaultEffectParams;\r\n  if (!fx) return d;\r\n  return {\r\n    quality: fx.quality ?? d.quality,\r\n    timeline: { ...d.timeline, ...fx.timeline },\r\n    medium: fx.medium ?? d.medium,\r\n    refraction: { ...d.refraction, ...fx.refraction },\r\n    optics: { ...d.optics, ...fx.optics },\r\n    chroma: { ...d.chroma, ...fx.chroma },\r\n    facet: { ...d.facet, ...fx.facet },\r\n    crackStyle: { ...d.crackStyle, ...fx.crackStyle },\r\n    bevel: { ...d.bevel, ...fx.bevel },\r\n    crush: { ...d.crush, ...fx.crush },\r\n    outliers: { ...d.outliers, ...fx.outliers },\r\n    spectrum: { ...d.spectrum, ...fx.spectrum },\r\n    edgeDistortion: { ...d.edgeDistortion, ...fx.edgeDistortion },\r\n    shatter: { ...d.shatter, ...fx.shatter },\r\n    motionBlur: { ...d.motionBlur, ...fx.motionBlur },\r\n    micro: { ...d.micro, ...fx.micro },\r\n    settle: { ...d.settle, ...fx.settle },\r\n    float: { ...d.float, ...fx.float }\r\n  };\r\n}\r\n\r\n// src/render/quality.ts\r\nvar qualityPresets = {\r\n  draft: { chromaGhosts: 0, motionGhosts: 0, smearGhosts: 0, bevel: false, edgeDistortion: false, spectrum: false, stubCap: 0, maxBlurPx: 0, grain: false, microShardCap: 40 },\r\n  normal: { chromaGhosts: 2, motionGhosts: 0, smearGhosts: 2, bevel: true, edgeDistortion: true, spectrum: true, stubCap: 80, maxBlurPx: 2, grain: false, microShardCap: 140 },\r\n  high: { chromaGhosts: 2, motionGhosts: 0, smearGhosts: 3, bevel: true, edgeDistortion: true, spectrum: true, stubCap: 200, maxBlurPx: 4, grain: true, microShardCap: 400 }\r\n};\r\nfunction resolveQuality(q) {\r\n  if (q === void 0) return qualityPresets.normal;\r\n  if (typeof q === \"string\") return qualityPresets[q] ?? qualityPresets.normal;\r\n  return { ...qualityPresets.normal, ...q };\r\n}\r\n\r\n// src/render/cracks.ts\r\nfunction crackLayer(pattern, info, fx, q) {\r\n  const style = fx.crackStyle;\r\n  const growthVis = (local) => {\r\n    if (style.growth === \"quart\") return easeOutQuart(local);\r\n    if (style.growth === \"expo\") return easeOutExpo(local);\r\n    return local >= 0.4 ? 1 : easeOutQuart(local / 0.4);\r\n  };\r\n  const shAng = degToRad(fx.optics.lightAngleDeg + 180);\r\n  const sox = Math.cos(shAng) * style.shadowOffsetPx;\r\n  const soy = Math.sin(shAng) * style.shadowOffsetPx;\r\n  const shadowRatio = style.shadowWidth / Math.max(1e-3, style.coreWidth);\r\n  const bv = clamp01(style.brightnessVar);\r\n  let core = \"\";\r\n  let coreDim = \"\";\r\n  let stubD = \"\";\r\n  let shadow = \"\";\r\n  let highlight = \"\";\r\n  let hackle = \"\";\r\n  let stubOrdinal = -1;\r\n  for (let ci = 0; ci < pattern.cracks.length; ci++) {\r\n    const crack = pattern.cracks[ci];\r\n    if (crack.kind === \"stub\") {\r\n      stubOrdinal++;\r\n      if (stubOrdinal >= q.stubCap || style.subCracks <= 0) continue;\r\n      if (hashTo01(hashCombine(pattern.seed, hashString(\"stub:pick\"), stubOrdinal)) >= style.subCracks) continue;\r\n      const local2 = clamp01((info.crackProgress - crack.birth) / Math.max(1e-6, crack.growDuration));\r\n      if (local2 <= 0) continue;\r\n      const vis2 = growthVis(local2) * crack.totalLen;\r\n      const part2 = partialPolylineWithS(unflattenPts(crack.points), crack.cumLen, vis2);\r\n      if (part2.pts.length < 2) continue;\r\n      const frame2 = miterFrame(part2.pts);\r\n      const wSeed2 = hashCombine(pattern.seed, hashString(\"stubribbon\"), stubOrdinal);\r\n      const halfs = [];\r\n      for (let i = 0; i < part2.pts.length; i++) {\r\n        const profile = clamp(1 + style.widthVariance * 1.25 * fbm1D(wSeed2, part2.s[i] * 0.06), 0.35, 2.2);\r\n        const taper = Math.min(1, (vis2 - part2.s[i]) / 9);\r\n        const base = 0.5 * style.coreWidth * 0.4 * profile * Math.max(0, taper);\r\n        halfs.push(Math.min(base, frame2.maxHalf[i]));\r\n      }\r\n      stubD += ribbonPath(part2.pts, frame2, halfs, 0, 0);\r\n      continue;\r\n    }\r\n    const local = clamp01((info.crackProgress - crack.birth) / Math.max(1e-6, crack.growDuration));\r\n    if (local <= 0) continue;\r\n    const vis = growthVis(local) * crack.totalLen;\r\n    const all = unflattenPts(crack.points);\r\n    const part = partialPolylineWithS(all, crack.cumLen, vis);\r\n    if (part.pts.length < 2) continue;\r\n    let brightAt = null;\r\n    if (bv > 0) {\r\n      const rngD = rngFor(pattern.seed, \"coreDim\", ci);\r\n      const kB = 2 + Math.floor(3 * rngD());\r\n      const bounds = [];\r\n      for (let b = 0; b < kB; b++) bounds.push(rngD() * crack.totalLen);\r\n      bounds.sort((a, b) => a - b);\r\n      brightAt = (s) => {\r\n        if (s < 15) return 1;\r\n        let idx = 0;\r\n        while (idx < bounds.length && bounds[idx] <= s) idx++;\r\n        const inBright = idx % 2 === 0;\r\n        const dPrev = idx > 0 ? s - bounds[idx - 1] : Infinity;\r\n        const dNext = idx < bounds.length ? bounds[idx] - s : Infinity;\r\n        const d = Math.min(dPrev, dNext);\r\n        if (d >= 3) return inBright ? 1 : 0;\r\n        const f = 0.5 + d / 3 * 0.5;\r\n        return inBright ? f : 1 - f;\r\n      };\r\n      const stations = [];\r\n      for (const b of bounds) stations.push(b - 3, b, b + 3);\r\n      insertStations(part, stations.sort((a, b) => a - b), vis);\r\n    }\r\n    const frame = miterFrame(part.pts);\r\n    const wSeed = hashCombine(pattern.seed, hashString(\"ribbon\"), ci);\r\n    const halfCore = [];\r\n    const halfDim = [];\r\n    const halfShadow = [];\r\n    for (let i = 0; i < part.pts.length; i++) {\r\n      const profile = clamp(1 + style.widthVariance * 1.25 * fbm1D(wSeed, part.s[i] * 0.06), 0.35, 2.2);\r\n      const taper = Math.min(1, (vis - part.s[i]) / 9);\r\n      const base = 0.5 * style.coreWidth * profile * Math.max(0, taper);\r\n      const bright = brightAt ? brightAt(part.s[i]) : 1;\r\n      halfCore.push(Math.min(base * bright, frame.maxHalf[i]));\r\n      if (brightAt) halfDim.push(Math.min(base, frame.maxHalf[i]));\r\n      halfShadow.push(Math.min(base * shadowRatio, frame.maxHalf[i] * 1.6));\r\n    }\r\n    core += ribbonPath(part.pts, frame, halfCore, 0, 0);\r\n    if (brightAt) coreDim += ribbonPath(part.pts, frame, halfDim, 0, 0);\r\n    shadow += ribbonPath(part.pts, frame, halfShadow, sox, soy);\r\n    if (style.doubleEdge > 0) {\r\n      const nF = rand01(pattern.seed, \"fil\", ci) < style.doubleEdge ? rand01(pattern.seed, \"fil2\", ci) < 0.4 ? 2 : 1 : 0;\r\n      for (let k = 0; k < nF; k++) {\r\n        const r1 = rand01(pattern.seed, \"filA\", ci, k);\r\n        const r2 = rand01(pattern.seed, \"filB\", ci, k);\r\n        const r3 = rand01(pattern.seed, \"filC\", ci, k);\r\n        const r4 = rand01(pattern.seed, \"filD\", ci, k);\r\n        const s0 = r1 * crack.totalLen * 0.7;\r\n        const sEnd = Math.min(s0 + (0.12 + 0.18 * r2) * crack.totalLen, crack.totalLen, vis);\r\n        if (sEnd - s0 < 6) continue;\r\n        const side = r3 < 0.5 ? 1 : -1;\r\n        const dist = 1.5 + 1.5 * r4;\r\n        let d = \"\";\r\n        let started = false;\r\n        for (let i = 0; i < part.pts.length; i++) {\r\n          if (part.s[i] < s0 || part.s[i] > sEnd) {\r\n            started = false;\r\n            continue;\r\n          }\r\n          const x = part.pts[i][0] + frame.mx[i] * frame.scale[i] * side * dist;\r\n          const y = part.pts[i][1] + frame.my[i] * frame.scale[i] * side * dist;\r\n          d += `${started ? \"L\" : \"M\"}${fmt(x)} ${fmt(y)}`;\r\n          started = true;\r\n        }\r\n        if (d.indexOf(\"L\") >= 0) highlight += d;\r\n      }\r\n    }\r\n    if (style.hackleDensity > 0) {\r\n      const ticks = crack.ticks;\r\n      for (let ti = 0, j = 0; ti + 4 < ticks.length; ti += 5, j++) {\r\n        if (ticks[ti] > vis) continue;\r\n        if (hashTo01(hashCombine(ci, j)) >= style.hackleDensity) continue;\r\n        hackle += `M${fmt(ticks[ti + 1])} ${fmt(ticks[ti + 2])}L${fmt(ticks[ti + 3])} ${fmt(ticks[ti + 4])}`;\r\n      }\r\n    }\r\n  }\r\n  let fadeWindow = 0.07;\r\n  if (fx.medium === \"glass\") {\r\n    let maxRing = 0;\r\n    for (const s of pattern.shards) if (s.ringIndex > maxRing) maxRing = s.ringIndex;\r\n    fadeWindow = maxRing * fx.shatter.staggerPerRing * 1.4 + 0.07;\r\n  }\r\n  const opacity = info.phase === \"shattering\" ? clamp01(1 - info.shatterTau / fadeWindow) : 1;\r\n  let sparkle = null;\r\n  if (style.sparkle && pattern.mode === \"radial\") {\r\n    const [ix, iy] = pattern.impact;\r\n    const rMax = Math.max(\r\n      Math.hypot(ix, iy),\r\n      Math.hypot(pattern.width - ix, iy),\r\n      Math.hypot(ix, pattern.height - iy),\r\n      Math.hypot(pattern.width - ix, pattern.height - iy)\r\n    );\r\n    const punch = fx.crush.punch ? easeOutCubic(clamp01((info.crackProgress - 0.1) * 2.2)) : 0;\r\n    sparkle = {\r\n      cx: ix,\r\n      cy: iy,\r\n      r: rMax * 0.045 * (0.5 + 0.5 * easeOutCubic(info.crackProgress)),\r\n      opacity: easeOutCubic(info.crackProgress) * 0.9 * (1 - punch)\r\n    };\r\n  }\r\n  return {\r\n    corePath: core,\r\n    coreDimPath: coreDim,\r\n    stubPath: stubD,\r\n    shadowPath: shadow,\r\n    highlightPath: highlight,\r\n    hacklePath: hackle,\r\n    coreDimOpacity: Math.max(0.35, 1 - 0.65 * bv),\r\n    coreOpacity: bv > 0 ? Math.min(1, bv / 0.25) : 1,\r\n    opacity,\r\n    style,\r\n    sparkle\r\n  };\r\n}\r\nfunction partialPolylineWithS(pts, cum, vis) {\r\n  const total = cum[cum.length - 1];\r\n  if (vis <= 0) return { pts: [], s: [] };\r\n  if (vis >= total) return { pts: pts.slice(), s: cum.slice() };\r\n  const outP = [pts[0]];\r\n  const outS = [0];\r\n  for (let i = 1; i < pts.length; i++) {\r\n    if (cum[i] <= vis) {\r\n      outP.push(pts[i]);\r\n      outS.push(cum[i]);\r\n    } else {\r\n      const segLen = cum[i] - cum[i - 1];\r\n      const t = segLen > 1e-12 ? (vis - cum[i - 1]) / segLen : 0;\r\n      outP.push([\r\n        pts[i - 1][0] + (pts[i][0] - pts[i - 1][0]) * t,\r\n        pts[i - 1][1] + (pts[i][1] - pts[i - 1][1]) * t\r\n      ]);\r\n      outS.push(vis);\r\n      break;\r\n    }\r\n  }\r\n  return { pts: outP, s: outS };\r\n}\r\nfunction insertStations(part, stations, vis) {\r\n  for (const st of stations) {\r\n    if (st <= 0.05 || st >= Math.min(vis, part.s[part.s.length - 1]) - 0.05) continue;\r\n    let i = 0;\r\n    while (i < part.s.length && part.s[i] <= st) i++;\r\n    if (i === 0 || i >= part.s.length) continue;\r\n    if (st - part.s[i - 1] < 0.05 || part.s[i] - st < 0.05) continue;\r\n    const t = (st - part.s[i - 1]) / (part.s[i] - part.s[i - 1]);\r\n    part.pts.splice(i, 0, [\r\n      part.pts[i - 1][0] + (part.pts[i][0] - part.pts[i - 1][0]) * t,\r\n      part.pts[i - 1][1] + (part.pts[i][1] - part.pts[i - 1][1]) * t\r\n    ]);\r\n    part.s.splice(i, 0, st);\r\n  }\r\n}\r\nfunction miterFrame(pts) {\r\n  const n = pts.length;\r\n  const segNx = [];\r\n  const segNy = [];\r\n  const segL = [];\r\n  for (let i = 0; i < n - 1; i++) {\r\n    const dx = pts[i + 1][0] - pts[i][0];\r\n    const dy = pts[i + 1][1] - pts[i][1];\r\n    const l = Math.hypot(dx, dy) || 1e-9;\r\n    segNx.push(-dy / l);\r\n    segNy.push(dx / l);\r\n    segL.push(l);\r\n  }\r\n  const mx = [];\r\n  const my = [];\r\n  const scale = [];\r\n  const maxHalf = [];\r\n  for (let i = 0; i < n; i++) {\r\n    const a = i === 0 ? 0 : i - 1;\r\n    const b = i === n - 1 ? n - 2 : i;\r\n    let x = segNx[a] + segNx[b];\r\n    let y = segNy[a] + segNy[b];\r\n    const l = Math.hypot(x, y);\r\n    if (l < 1e-9) {\r\n      x = segNx[b];\r\n      y = segNy[b];\r\n    } else {\r\n      x /= l;\r\n      y /= l;\r\n    }\r\n    const dot = x * segNx[b] + y * segNy[b];\r\n    mx.push(x);\r\n    my.push(y);\r\n    scale.push(Math.min(2, 1 / Math.max(0.35, dot)));\r\n    maxHalf.push(0.4 * Math.min(segL[a], segL[b]));\r\n  }\r\n  return { mx, my, scale, maxHalf };\r\n}\r\nfunction ribbonPath(pts, frame, halfWs, ox, oy) {\r\n  const n = pts.length;\r\n  if (n < 2) return \"\";\r\n  let left = \"\";\r\n  let right = \"\";\r\n  for (let i = 0; i < n; i++) {\r\n    const w = halfWs[i] * frame.scale[i];\r\n    const lx = pts[i][0] + frame.mx[i] * w + ox;\r\n    const ly = pts[i][1] + frame.my[i] * w + oy;\r\n    left += `${i === 0 ? \"M\" : \"L\"}${fmt(lx)} ${fmt(ly)}`;\r\n    const rx = pts[i][0] - frame.mx[i] * w + ox;\r\n    const ry = pts[i][1] - frame.my[i] * w + oy;\r\n    right = `L${fmt(rx)} ${fmt(ry)}` + right;\r\n  }\r\n  return left + right + \"Z\";\r\n}\r\n\r\n// src/motion/settle.ts\r\nfunction floatOffset(t, shardHash, f) {\r\n  if (f.bobPx <= 0 && f.swayPx <= 0 && f.rotDeg <= 0) return { dx: 0, dy: 0, rot: 0 };\r\n  const phaseA = hashTo01(hashCombine(shardHash, 41)) * TAU;\r\n  const phaseB = hashTo01(hashCombine(shardHash, 53)) * TAU;\r\n  const phaseC = hashTo01(hashCombine(shardHash, 67)) * TAU;\r\n  const w = TAU * f.cycles;\r\n  return {\r\n    dx: Math.sin(w * t + phaseA) * f.swayPx,\r\n    dy: Math.sin(w * t + phaseB) * f.bobPx,\r\n    rot: Math.sin(w * t + phaseC) * f.rotDeg\r\n  };\r\n}\r\nfunction settleOffset(t, shardHash, amplitudePx, frequency, sinceT) {\r\n  if (amplitudePx <= 0) return { dx: 0, dy: 0, rot: 0 };\r\n  const tau = Math.max(0, t - sinceT);\r\n  const damp = Math.exp(-3.2 * tau);\r\n  const phaseA = hashTo01(hashCombine(shardHash, 11)) * TAU;\r\n  const phaseB = hashTo01(hashCombine(shardHash, 23)) * TAU;\r\n  const w = TAU * frequency;\r\n  return {\r\n    dx: Math.sin(w * tau + phaseA) * amplitudePx * damp,\r\n    dy: Math.cos(w * tau * 0.9 + phaseB) * amplitudePx * 0.7 * damp,\r\n    rot: Math.sin(w * tau * 0.75 + phaseA + phaseB) * amplitudePx * 0.12 * damp\r\n  };\r\n}\r\n\r\n// src/render/shardStyle.ts\r\nvar BEVEL_SECTORS = 12;\r\nvar staticCache = /* @__PURE__ */ new WeakMap();\r\nfunction staticShardStrings(pattern) {\r\n  let entry = staticCache.get(pattern);\r\n  if (!entry) {\r\n    entry = {\r\n      clip: pattern.shards.map((s) => toCssPolygon(s.outsetPolygon)),\r\n      innerClip: pattern.shards.map((s) => toCssPolygon(s.polygon)),\r\n      origin: pattern.shards.map((s) => `${fmt(s.centroid[0])}px ${fmt(s.centroid[1])}px`),\r\n      bevel: pattern.shards.map((s) => bevelSectors(s, pattern.width, pattern.height))\r\n    };\r\n    staticCache.set(pattern, entry);\r\n  }\r\n  return entry;\r\n}\r\nvar BEVEL_SCATTER_KEY = hashString(\"bevelScatter\");\r\nvar BEVEL_SPEC_FRACTION = 0.3;\r\nvar BEVEL_INTRINSIC_KEY = hashString(\"bevelIntrinsic\");\r\nvar BEVEL_JITTER_KEY = hashString(\"bevelJitter\");\r\nfunction bevelSectors(shard, w, h) {\r\n  const poly = shard.polygon;\r\n  const n = poly.length / 2;\r\n  const full = new Array(BEVEL_SECTORS).fill(\"\");\r\n  const spec = new Array(BEVEL_SECTORS).fill(\"\");\r\n  const shaded = new Array(BEVEL_SECTORS).fill(\"\");\r\n  const eps = 0.75;\r\n  const onSameBorder = (x1, y1, x2, y2) => x1 < eps && x2 < eps || x1 > w - eps && x2 > w - eps || y1 < eps && y2 < eps || y1 > h - eps && y2 > h - eps;\r\n  for (let i = 0; i < n; i++) {\r\n    const x1 = poly[i * 2];\r\n    const y1 = poly[i * 2 + 1];\r\n    const j = (i + 1) % n;\r\n    const x2 = poly[j * 2];\r\n    const y2 = poly[j * 2 + 1];\r\n    if (onSameBorder(x1, y1, x2, y2)) continue;\r\n    const dx = x2 - x1;\r\n    const dy = y2 - y1;\r\n    const len = Math.hypot(dx, dy);\r\n    if (len < 0.5) continue;\r\n    let ang = Math.atan2(-dx, dy);\r\n    if (ang < 0) ang += TAU;\r\n    const sector = Math.min(BEVEL_SECTORS - 1, Math.floor(ang / TAU * BEVEL_SECTORS));\r\n    const seg = `M${fmt(x1)} ${fmt(y1)}L${fmt(x2)} ${fmt(y2)}`;\r\n    full[sector] += seg;\r\n    if (hashTo01(hashCombine(shard.hash, BEVEL_SCATTER_KEY, i)) < BEVEL_SPEC_FRACTION) {\r\n      spec[sector] += seg;\r\n    } else {\r\n      shaded[sector] += seg;\r\n    }\r\n  }\r\n  const out = [];\r\n  for (let s = 0; s < BEVEL_SECTORS; s++) {\r\n    if (full[s]) {\r\n      out.push({\r\n        dFull: full[s],\r\n        dSpec: spec[s],\r\n        dShaded: shaded[s],\r\n        angle: (s + 0.5) / BEVEL_SECTORS * TAU,\r\n        intrinsic: 0.45 + 0.55 * hashTo01(hashCombine(shard.hash, BEVEL_INTRINSIC_KEY, s)),\r\n        jitter: (hashTo01(hashCombine(shard.hash, BEVEL_JITTER_KEY, s)) - 0.5) * 0.8\r\n      });\r\n    }\r\n  }\r\n  return out;\r\n}\r\nfunction shardPose(hash, fx) {\r\n  const rng = rngFor(hash, \"pose\");\r\n  return {\r\n    refrAngle: rng() * TAU,\r\n    refrMag: fx.refraction.offsetPx * (0.4 + 0.6 * rng()),\r\n    rotZ: fx.refraction.rotateDeg * (rng() * 2 - 1),\r\n    scaleDev: fx.refraction.scaleAmp * (rng() * 2 - 1),\r\n    tiltAxis: rng() * TAU,\r\n    tiltMag: fx.refraction.tiltDeg * (0.35 + 0.65 * rng()),\r\n    facetAngle: rng() * 360,\r\n    facetMag: 0.6 + 0.4 * rng(),\r\n    contrastSign: rng() < 0.5 ? -1 : 1,\r\n    chromaMagF: 0.55 + 0.45 * rng()\r\n  };\r\n}\r\nfunction rotate2D(x, y, rad) {\r\n  const c = Math.cos(rad);\r\n  const s = Math.sin(rad);\r\n  return [x * c - y * s, x * s + y * c];\r\n}\r\nfunction gravityDir(g) {\r\n  const l = Math.hypot(g[0], g[1]);\r\n  return l > 1e-6 ? [g[0] / l, g[1] / l] : [0, 1];\r\n}\r\nfunction buildShardFrame(t, pattern, shard, shardIndex, info, fx, q, pose, kind, spectral) {\r\n  const statics = staticShardStrings(pattern);\r\n  const ease = easeOutCubic(info.crackProgress);\r\n  const lightRad = degToRad(fx.optics.lightAngleDeg);\r\n  const motion = shardMotion(pattern, shard, fx, kind);\r\n  const tau = Math.max(0, info.shatterTau - motion.birthDelay);\r\n  const flying = info.phase === \"shattering\" && tau > 0;\r\n  const [fdx, fdy] = flightOffset(tau, motion.v0, fx.shatter.gravity, fx.shatter.drag);\r\n  const spin = motion.omega * tau;\r\n  const tumX = clamp(motion.tumbleX * tau, -78, 78);\r\n  const tumY = clamp(motion.tumbleY * tau, -78, 78);\r\n  const speed = flying ? flightSpeed(tau, motion.v0, fx.shatter.gravity, fx.shatter.drag) : 0;\r\n  const speedStrength = clamp01((speed - fx.motionBlur.speedThreshold) / (fx.motionBlur.speedThreshold * 2));\r\n  const st = info.phase === \"cracked\" ? settleOffset(t, shard.hash, fx.settle.amplitudePx, fx.settle.frequency, 0) : { dx: 0, dy: 0, rot: 0 };\r\n  let preDx = 0;\r\n  if (info.phase === \"cracked\" && pattern.mode === \"title\" && fx.shatter.preSpreadPx > 0) {\r\n    const side = shard.centroid[0] < pattern.width / 2 ? -1 : 1;\r\n    preDx = side * fx.shatter.preSpreadPx * ease;\r\n  }\r\n  let opacity = 1;\r\n  if (info.phase === \"shattering\") {\r\n    const [f0, f1] = fx.shatter.fadeOut;\r\n    opacity = 1 - clamp01((t - f0) / Math.max(1e-6, f1 - f0));\r\n  }\r\n  const isCrush = pattern.mode === \"radial\" && shard.ringIndex === 0;\r\n  const punch = isCrush && fx.crush.punch ? easeOutCubic(clamp01((info.crackProgress - 0.1) * 2.2)) : 0;\r\n  let dropEase = 0;\r\n  if (kind === \"dropped\") {\r\n    const dropStart = 0.45 + 0.3 * hashTo01(hashCombine(shard.hash, hashString(\"outlier:dropT\")));\r\n    dropEase = easeOutCubic(clamp01((info.crackProgress - dropStart) / 0.25));\r\n  }\r\n  const vanish = Math.max(punch, dropEase);\r\n  opacity *= 1 - vanish;\r\n  const gdir = gravityDir(fx.shatter.gravity);\r\n  const sinkPx = clamp(0.12 * Math.sqrt(shard.area / Math.PI), 1.5, 5) * vanish;\r\n  const rigidScale = (1 - (1 - fx.crush.scaleTo) * punch) * (1 - 0.05 * dropEase);\r\n  let slipDx = 0;\r\n  let slipDy = 0;\r\n  let slipRot = 0;\r\n  if (kind === \"slipped\") {\r\n    const slipMagF = hashTo01(hashCombine(shard.hash, hashString(\"outlier:slipMag\")));\r\n    const slipSign = hashTo01(hashCombine(shard.hash, hashString(\"outlier:slipRot\"))) < 0.5 ? -1 : 1;\r\n    const slipJit = hashTo01(hashCombine(shard.hash, hashString(\"outlier:slipDir\")));\r\n    let dir;\r\n    if (pattern.mode === \"radial\" || pattern.mode === \"web\") {\r\n      const dx = shard.centroid[0] - pattern.impact[0];\r\n      const dy = shard.centroid[1] - pattern.impact[1];\r\n      const l = Math.hypot(dx, dy) || 1;\r\n      dir = [dx / l, dy / l];\r\n    } else {\r\n      dir = gdir;\r\n    }\r\n    const rotated = rotate2D(dir[0], dir[1], (slipJit - 0.5) * 0.9);\r\n    const mag = fx.outliers.slipPx * (0.6 + 0.8 * slipMagF) * ease;\r\n    slipDx = rotated[0] * mag;\r\n    slipDy = rotated[1] * mag;\r\n    slipRot = slipSign * fx.outliers.slipRotDeg * (0.5 + slipMagF) * ease;\r\n  }\r\n  const fl = pattern.mode === \"hero\" ? floatOffset(t, shard.hash, fx.float) : { dx: 0, dy: 0, rot: 0 };\r\n  const rigidDx = fdx + st.dx + slipDx + fl.dx + preDx + gdir[0] * sinkPx;\r\n  const rigidDy = fdy + st.dy + slipDy + fl.dy + gdir[1] * sinkPx;\r\n  const rigidRot = spin + st.rot + slipRot + fl.rot;\r\n  const glass = fx.medium === \"glass\";\r\n  const glassInv = glass ? {\r\n    dx: Number(fmt(rigidDx)),\r\n    dy: Number(fmt(rigidDy)),\r\n    rot: Number(fmt(rigidRot, 3)),\r\n    scale: Number(fmt(Math.max(rigidScale, 0.05), 4))\r\n  } : null;\r\n  const glassWrap = (core) => glassInv ? `scale(${fmt(1 / glassInv.scale, 6)}) rotate(${fmt(-glassInv.rot, 3)}deg) ${core} translate(${fmt(-glassInv.dx)}px, ${fmt(-glassInv.dy)}px)` : core;\r\n  let shardTransform;\r\n  if (glassInv) {\r\n    shardTransform = `translate(${fmt(glassInv.dx)}px, ${fmt(glassInv.dy)}px) rotate(${fmt(glassInv.rot, 3)}deg) scale(${fmt(glassInv.scale, 4)})`;\r\n  } else {\r\n    shardTransform = `translate(${fmt(rigidDx)}px, ${fmt(rigidDy)}px)`;\r\n    if (fx.shatter.tumbleDegMax > 0 && flying) {\r\n      shardTransform += ` perspective(${fmt(fx.refraction.perspectivePx)}px) rotateX(${fmt(tumX, 3)}deg) rotateY(${fmt(tumY, 3)}deg)`;\r\n    }\r\n    shardTransform += ` rotate(${fmt(rigidRot, 3)}deg) scale(${fmt(rigidScale, 4)})`;\r\n  }\r\n  const refDx = Math.cos(pose.refrAngle) * pose.refrMag * ease;\r\n  const refDy = Math.sin(pose.refrAngle) * pose.refrMag * ease;\r\n  const refRot = pose.rotZ * ease;\r\n  const refScale = 1 + pose.scaleDev * ease;\r\n  const tiltX = Math.sin(pose.tiltAxis) * pose.tiltMag * ease;\r\n  const tiltY = Math.cos(pose.tiltAxis) * pose.tiltMag * ease;\r\n  let refrCore = `translate(${fmt(refDx)}px, ${fmt(refDy)}px)`;\r\n  if (fx.refraction.tiltDeg > 0) {\r\n    refrCore += ` perspective(${fmt(fx.refraction.perspectivePx)}px) rotateX(${fmt(tiltX, 3)}deg) rotateY(${fmt(tiltY, 3)}deg)`;\r\n  }\r\n  refrCore += ` rotate(${fmt(refRot, 3)}deg) scale(${fmt(refScale, 4)})`;\r\n  const contentTransform = glassWrap(refrCore);\r\n  const live = fx.optics.trackLight;\r\n  const lightDot = live ? Math.cos(pose.tiltAxis + degToRad(rigidRot) - lightRad) * (0.35 + 0.65 * (pose.tiltMag / Math.max(1e-3, fx.refraction.tiltDeg || 1))) : Math.cos(pose.tiltAxis - lightRad) * (0.35 + 0.65 * (pose.tiltMag / Math.max(1e-3, fx.refraction.tiltDeg || 1)));\r\n  const brightness = 1 + fx.optics.brightnessAmp * lightDot * ease;\r\n  const contrast = 1 + fx.optics.contrastAmp * pose.contrastSign * ease;\r\n  const smearBlurAdd = flying ? fx.motionBlur.smearBlurPx * speedStrength : 0;\r\n  const blurPx = clamp(clamp(fx.optics.blurPx, 0, q.maxBlurPx) * ease + smearBlurAdd, 0, q.maxBlurPx);\r\n  const chromaScale = (ease + (flying ? Math.min(1, tau * 2.2) : 0)) * pose.chromaMagF;\r\n  let chDx;\r\n  let chDy;\r\n  if (live) {\r\n    const chRadLive = degToRad(fx.chroma.angleDeg - rigidRot);\r\n    chDx = Math.cos(chRadLive) * fx.chroma.offsetPx * chromaScale;\r\n    chDy = Math.sin(chRadLive) * fx.chroma.offsetPx * chromaScale;\r\n  } else {\r\n    const chRad = degToRad(fx.chroma.angleDeg);\r\n    chDx = Math.cos(chRad) * fx.chroma.offsetPx * chromaScale;\r\n    chDy = Math.sin(chRad) * fx.chroma.offsetPx * chromaScale;\r\n  }\r\n  let contentFilter = `brightness(${fmt(brightness, 3)}) contrast(${fmt(contrast, 3)})`;\r\n  const smearFilter = contentFilter;\r\n  if (blurPx > 0.02) contentFilter += ` blur(${fmt(blurPx, 2)}px)`;\r\n  if (fx.chroma.mode === \"shadow\" && fx.chroma.offsetPx > 0) {\r\n    contentFilter += ` drop-shadow(${fmt(chDx)}px ${fmt(chDy)}px 0 ${fx.chroma.colorA}) drop-shadow(${fmt(-chDx)}px ${fmt(-chDy)}px 0 ${fx.chroma.colorB})`;\r\n  }\r\n  const chroma = [];\r\n  if (fx.chroma.mode === \"ghost\" && q.chromaGhosts > 0 && fx.chroma.offsetPx > 0) {\r\n    let gChDx = chDx;\r\n    let gChDy = chDy;\r\n    if (glass) {\r\n      const gRad = degToRad(live ? fx.chroma.angleDeg : fx.chroma.angleDeg + rigidRot);\r\n      gChDx = Math.cos(gRad) * fx.chroma.offsetPx * chromaScale;\r\n      gChDy = Math.sin(gRad) * fx.chroma.offsetPx * chromaScale;\r\n    }\r\n    const signs = q.chromaGhosts === 1 ? [1] : [1, -1];\r\n    for (const sign of signs) {\r\n      chroma.push({\r\n        transform: glassWrap(\r\n          `translate(${fmt(refDx + sign * gChDx)}px, ${fmt(refDy + sign * gChDy)}px) rotate(${fmt(refRot, 3)}deg) scale(${fmt(refScale, 4)})`\r\n        ),\r\n        filter: `hue-rotate(${sign > 0 ? 115 : -115}deg) saturate(1.7)`,\r\n        mixBlendMode: fx.chroma.blendMode,\r\n        opacity: fx.chroma.opacity * ease * opacity\r\n      });\r\n    }\r\n  }\r\n  const facetAngleOut = live ? pose.facetAngle - rigidRot : pose.facetAngle;\r\n  const facetWhite = fx.facet.strength * 0.65 * pose.facetMag;\r\n  const facetBlack = fx.facet.strength * 0.5 * pose.facetMag;\r\n  let facet = null;\r\n  if (fx.facet.opacity > 0 && fx.facet.strength > 0) {\r\n    let background = `linear-gradient(${fmt(facetAngleOut, 1)}deg, rgba(255,255,255,${fmt(facetWhite, 3)}) 0%, rgba(255,255,255,0) 38%, rgba(0,0,0,0) 62%, rgba(0,0,0,${fmt(facetBlack, 3)}) 100%)`;\r\n    if (fx.facet.tint) background += `, linear-gradient(0deg, ${fx.facet.tint}, ${fx.facet.tint})`;\r\n    facet = {\r\n      background,\r\n      mixBlendMode: fx.facet.blendMode,\r\n      opacity: fx.facet.opacity * ease * opacity\r\n    };\r\n  }\r\n  const wantEdge = q.edgeDistortion && fx.edgeDistortion.strength > 0 && fx.edgeDistortion.widthPx > 0.5;\r\n  const wantSpectrumRing = spectral !== null && fx.spectrum.edgeOnly > 0;\r\n  let ringD = \"\";\r\n  let ringClipCss = \"\";\r\n  if (wantEdge || wantSpectrumRing) {\r\n    const inner = insetPolygonTowardCentroid(shard.polygon, shard.centroid, fx.edgeDistortion.widthPx);\r\n    ringD = ringPathD(shard.polygon, inner);\r\n    ringClipCss = `path(\"${ringD}\")`;\r\n  }\r\n  let edge = null;\r\n  if (wantEdge) {\r\n    const k = 1 + 1.6 * fx.edgeDistortion.strength;\r\n    const eDx = refDx * k;\r\n    const eDy = refDy * k;\r\n    const eRot = refRot * (1 + 0.6 * fx.edgeDistortion.strength);\r\n    const eScale = refScale * (1 + 0.045 * fx.edgeDistortion.strength * ease);\r\n    let edgeCore = `translate(${fmt(eDx)}px, ${fmt(eDy)}px)`;\r\n    if (fx.refraction.tiltDeg > 0) {\r\n      edgeCore += ` perspective(${fmt(fx.refraction.perspectivePx)}px) rotateX(${fmt(tiltX, 3)}deg) rotateY(${fmt(tiltY, 3)}deg)`;\r\n    }\r\n    edgeCore += ` rotate(${fmt(eRot, 3)}deg) scale(${fmt(eScale, 4)})`;\r\n    const eBlur = clamp(fx.edgeDistortion.blurPx, 0, q.maxBlurPx);\r\n    let edgeFilter = contentFilter;\r\n    if (eBlur > 0.02) edgeFilter += ` blur(${fmt(eBlur, 2)}px)`;\r\n    edge = {\r\n      clipPath: ringClipCss,\r\n      d: ringD,\r\n      transform: glassWrap(edgeCore),\r\n      filter: edgeFilter,\r\n      opacity: ease,\r\n      // ramps in with the crack network; the wrapper already carries shard opacity\r\n      dx: eDx,\r\n      dy: eDy,\r\n      rot: eRot,\r\n      scale: eScale\r\n    };\r\n  }\r\n  let spectrum = null;\r\n  if (spectral) {\r\n    const specAngle = live ? fx.optics.lightAngleDeg - rigidRot : fx.optics.lightAngleDeg;\r\n    const cssAngle = live ? specAngle + 90 : fx.optics.lightAngleDeg + 90;\r\n    const c = spectral.center01 * 100;\r\n    const hw = spectral.width01 * 100 / 2;\r\n    const stops = `rgba(255,70,70,0) ${fmt(c - hw, 2)}%, rgba(255,70,70,0.85) ${fmt(c - hw * 0.6, 2)}%, rgba(255,210,70,0.85) ${fmt(c - hw * 0.25, 2)}%, rgba(110,255,150,0.85) ${fmt(c, 2)}%, rgba(80,200,255,0.85) ${fmt(c + hw * 0.35, 2)}%, rgba(170,100,255,0.85) ${fmt(c + hw * 0.65, 2)}%, rgba(170,100,255,0) ${fmt(c + hw, 2)}%`;\r\n    const glint = Math.max(0, Math.cos(degToRad(rigidRot)));\r\n    spectrum = {\r\n      background: `linear-gradient(${fmt(cssAngle, 1)}deg, ${stops})`,\r\n      mixBlendMode: fx.spectrum.blendMode,\r\n      opacity: fx.spectrum.opacity * ease * opacity * glint,\r\n      angleDeg: specAngle,\r\n      center01: spectral.center01,\r\n      width01: spectral.width01\r\n    };\r\n    if (wantSpectrumRing) {\r\n      spectrum.clipPath = ringClipCss;\r\n      spectrum.d = ringD;\r\n    }\r\n  }\r\n  const bevel = [];\r\n  if (q.bevel && fx.bevel.intensity > 0) {\r\n    const spinRad = degToRad(rigidRot);\r\n    const glintBoost = flying ? 1 + fx.bevel.glintStrength * Math.min(1, tau * 3) : 1;\r\n    const sigma = clamp01(fx.bevel.scatter);\r\n    const fv = clamp01(fx.bevel.facetVariation);\r\n    const fl2 = (x) => fv > 0 && x < 1e-6 ? 0 : x;\r\n    for (const sec of statics.bevel[shardIndex]) {\r\n      const Lang = fv > 0 ? sec.angle + fv * sec.jitter : sec.angle;\r\n      const L = Math.cos(Lang + spinRad - lightRad);\r\n      const im = fv > 0 ? 1 - fv + fv * sec.intrinsic : 1;\r\n      if (sigma <= 0) {\r\n        const lit = L > 0;\r\n        const mag = Math.min(1, Math.pow(Math.abs(L), 1.2) * fx.bevel.intensity * ease * opacity * glintBoost);\r\n        bevel.push({ d: sec.dFull, stroke: fx.bevel.lightColor, mixBlendMode: fx.bevel.blendMode, opacity: fl2((lit ? mag : 0) * im) });\r\n        bevel.push({ d: sec.dFull, stroke: fx.bevel.darkColor, mixBlendMode: \"normal\", opacity: fl2((lit ? 0 : Math.min(1, mag * 0.5)) * im) });\r\n        continue;\r\n      }\r\n      const base = fx.bevel.intensity * ease * opacity * im;\r\n      const gP = Math.pow(Math.max(0, L), 1.2) * glintBoost;\r\n      const gM = Math.pow(Math.max(0, -L), 1.2) * glintBoost;\r\n      const att = 1 - sigma;\r\n      if (sec.dSpec) {\r\n        const litOp = Math.min(1, base * (gP + sigma * (0.35 + 0.65 * gP - gP)));\r\n        const darkOp = Math.min(1, 0.5 * base * att * att * gM);\r\n        bevel.push({ d: sec.dSpec, stroke: fx.bevel.darkColor, mixBlendMode: \"normal\", opacity: fl2(darkOp) });\r\n        bevel.push({ d: sec.dSpec, stroke: fx.bevel.lightColor, mixBlendMode: fx.bevel.blendMode, opacity: fl2(litOp) });\r\n      }\r\n      if (sec.dShaded) {\r\n        const cross = 1 - 0.88 * sigma;\r\n        const litOp = Math.min(1, base * gP * cross * cross);\r\n        const darkOp = Math.min(1, 0.5 * base * (gM + sigma * (0.75 + 0.25 * gM - gM)));\r\n        bevel.push({ d: sec.dShaded, stroke: fx.bevel.darkColor, mixBlendMode: \"normal\", opacity: fl2(darkOp) });\r\n        bevel.push({ d: sec.dShaded, stroke: fx.bevel.lightColor, mixBlendMode: fx.bevel.blendMode, opacity: fl2(litOp) });\r\n      }\r\n    }\r\n  }\r\n  const smear = [];\r\n  if (q.smearGhosts > 0) {\r\n    const active = !glass && flying && speedStrength > 0;\r\n    let deltas = [];\r\n    if (active) {\r\n      const raw = [];\r\n      for (let k = 1; k <= q.smearGhosts; k++) {\r\n        const tk = Math.max(0, tau - k * fx.motionBlur.dt);\r\n        const [gx, gy] = flightOffset(tk, motion.v0, fx.shatter.gravity, fx.shatter.drag);\r\n        raw.push([gx - fdx, gy - fdy]);\r\n      }\r\n      const last = raw[raw.length - 1];\r\n      const lastLen = Math.hypot(last[0], last[1]);\r\n      const capScale = lastLen > 1e-6 ? Math.min(1, fx.motionBlur.smearPx / lastLen) : 0;\r\n      deltas = raw.map(([x, y]) => rotate2D(x * capScale, y * capScale, -degToRad(rigidRot)));\r\n    }\r\n    for (let k = 0; k < q.smearGhosts; k++) {\r\n      const d = deltas[k];\r\n      const op = active && d ? opacity * speedStrength * Math.pow(fx.motionBlur.opacityFalloff, k + 1) : 0;\r\n      smear.push({\r\n        transform: d ? `translate(${fmt(d[0])}px, ${fmt(d[1])}px) ${contentTransform}` : contentTransform,\r\n        dx: d ? d[0] : 0,\r\n        dy: d ? d[1] : 0,\r\n        opacity: op\r\n      });\r\n    }\r\n  }\r\n  const ghosts = [];\r\n  const ghostCount = glass ? 0 : Math.min(q.motionGhosts, fx.motionBlur.ghosts ?? q.motionGhosts);\r\n  if (flying && ghostCount > 0 && speedStrength > 0) {\r\n    for (let k = 1; k <= ghostCount; k++) {\r\n      const tk = tau - k * fx.motionBlur.dt;\r\n      if (tk <= 0) break;\r\n      const [gx, gy] = flightOffset(tk, motion.v0, fx.shatter.gravity, fx.shatter.drag);\r\n      let gt = `translate(${fmt(gx + st.dx)}px, ${fmt(gy + st.dy)}px)`;\r\n      if (fx.shatter.tumbleDegMax > 0) {\r\n        gt += ` perspective(${fmt(fx.refraction.perspectivePx)}px) rotateX(${fmt(clamp(motion.tumbleX * tk, -78, 78), 3)}deg) rotateY(${fmt(clamp(motion.tumbleY * tk, -78, 78), 3)}deg)`;\r\n      }\r\n      gt += ` rotate(${fmt(motion.omega * tk, 3)}deg)`;\r\n      ghosts.push({\r\n        shardTransform: gt,\r\n        opacity: opacity * speedStrength * Math.pow(fx.motionBlur.opacityFalloff, k)\r\n      });\r\n    }\r\n  }\r\n  return {\r\n    id: shard.id,\r\n    clipPath: statics.clip[shardIndex],\r\n    innerClipPath: statics.innerClip[shardIndex],\r\n    transformOrigin: statics.origin[shardIndex],\r\n    shardTransform,\r\n    contentTransform,\r\n    contentFilter,\r\n    opacity,\r\n    zIndex: (shard.z + 1) * 10,\r\n    facet,\r\n    spectrum,\r\n    edge,\r\n    chroma,\r\n    ghosts,\r\n    smear,\r\n    smearFilter,\r\n    bevel,\r\n    raw: {\r\n      // glass: tumble is hard-disabled and the scale is clamped (matches raw.glass and the\r\n      // emitted strings, so a consumer composing from raw.rigid stays in lockstep)\r\n      rigid: {\r\n        dx: rigidDx,\r\n        dy: rigidDy,\r\n        rotZ: rigidRot,\r\n        rotX: glass ? 0 : tumX,\r\n        rotY: glass ? 0 : tumY,\r\n        scale: glassInv ? glassInv.scale : rigidScale\r\n      },\r\n      refraction: { dx: refDx, dy: refDy, rot: refRot, scale: refScale, tiltX, tiltY },\r\n      glass: glassInv,\r\n      brightness,\r\n      contrast,\r\n      blurPx,\r\n      chromaDx: chDx,\r\n      chromaDy: chDy,\r\n      facetAngleDeg: facetAngleOut,\r\n      facetWhite,\r\n      facetBlack\r\n    }\r\n  };\r\n}\r\n\r\n// src/render/frame.ts\r\nfunction computeFrame(t, pattern, fxPartial) {\r\n  const tc = clamp01(t);\r\n  const fx = normalizeEffectParams(fxPartial);\r\n  const q = resolveQuality(fx.quality);\r\n  const info = resolvePhase(tc, fx.timeline);\r\n  const poses = pattern.shards.map((s) => shardPose(s.hash, fx));\r\n  const kinds = assignOutliers(pattern, fx.outliers);\r\n  const spectral = selectSpectral(pattern, poses, fx, q.spectrum);\r\n  const shards = pattern.shards.map(\r\n    (s, i) => buildShardFrame(tc, pattern, s, i, info, fx, q, poses[i], kinds[i], spectral[i])\r\n  );\r\n  const cracks = crackLayer(pattern, info, fx, q);\r\n  const microCount = Math.min(pattern.micro.length, q.microShardCap);\r\n  const micro = [];\r\n  for (let i = 0; i < microCount; i++) {\r\n    const m = pattern.micro[i];\r\n    const visible = clamp01((info.crackProgress - m.birth) / 0.05);\r\n    const mm = microMotion(pattern, m.origin, m.hash, m.ringIndex, fx);\r\n    const tau = info.phase === \"shattering\" ? Math.max(0, info.shatterTau - mm.birthDelay) : 0;\r\n    const [fdx, fdy] = flightOffset(tau, mm.v0, fx.shatter.gravity, fx.shatter.drag);\r\n    const twinklePhase = hashTo01(hashCombine(m.hash, 77)) * 6.283;\r\n    const twinkle = 0.8 + 0.2 * Math.sin(tc * 21 + twinklePhase);\r\n    let opacity = visible * fx.micro.opacity * twinkle;\r\n    if (info.phase === \"shattering\") {\r\n      const [f0, f1] = fx.shatter.fadeOut;\r\n      opacity *= 1 - clamp01((tc - (f0 - 0.04)) / Math.max(1e-6, f1 - f0));\r\n    }\r\n    micro.push({\r\n      id: m.id,\r\n      points: toSvgPoints(m.polygon),\r\n      transform: `translate(${fmt(m.origin[0] + fdx)} ${fmt(m.origin[1] + fdy)}) rotate(${fmt(mm.omega * tau, 2)})`,\r\n      opacity: Math.max(0, Math.min(1, opacity)),\r\n      fill: hashTo01(hashCombine(m.hash, 5)) < 0.72 ? fx.micro.fill : fx.micro.fillAlt\r\n    });\r\n  }\r\n  return {\r\n    t: tc,\r\n    phase: info.phase,\r\n    shards,\r\n    cracks,\r\n    micro,\r\n    grain: q.grain ? { opacity: fx.optics.grainOpacity } : null\r\n  };\r\n}\r\nfunction selectSpectral(pattern, poses, fx, enabled) {\r\n  const out = pattern.shards.map(() => null);\r\n  if (!enabled || fx.spectrum.count <= 0 || fx.spectrum.opacity <= 0) return out;\r\n  const lightRad = degToRad(fx.optics.lightAngleDeg);\r\n  const dirX = Math.cos(lightRad);\r\n  const dirY = Math.sin(lightRad);\r\n  const w = pattern.width;\r\n  const h = pattern.height;\r\n  const corners = [\r\n    [0, 0],\r\n    [w, 0],\r\n    [w, h],\r\n    [0, h]\r\n  ];\r\n  let tMin = Infinity;\r\n  let tMax = -Infinity;\r\n  for (const c of corners) {\r\n    const p = c[0] * dirX + c[1] * dirY;\r\n    if (p < tMin) tMin = p;\r\n    if (p > tMax) tMax = p;\r\n  }\r\n  const span = Math.max(1e-6, tMax - tMin);\r\n  const minArea = 0.02 * w * h;\r\n  let candidates = [];\r\n  for (let i = 0; i < pattern.shards.length; i++) {\r\n    if (pattern.shards[i].area >= minArea) candidates.push(i);\r\n  }\r\n  if (candidates.length === 0) candidates = pattern.shards.map((_, i) => i);\r\n  const edgeOnly = clamp(fx.spectrum.edgeOnly, 0, 1);\r\n  let maxArea = 1;\r\n  if (edgeOnly > 0) {\r\n    for (const i of candidates) maxArea = Math.max(maxArea, pattern.shards[i].area);\r\n  }\r\n  const score = (i) => {\r\n    const align = Math.cos(poses[i].tiltAxis - lightRad);\r\n    return edgeOnly > 0 ? align + 1.2 * edgeOnly * (1 - pattern.shards[i].area / maxArea) : align;\r\n  };\r\n  candidates.sort((a, b) => score(b) - score(a) || a - b);\r\n  const picked = candidates.slice(0, Math.min(fx.spectrum.count, candidates.length));\r\n  for (const i of picked) {\r\n    const s = pattern.shards[i];\r\n    const rng = rngFor(s.hash, \"spectrum\");\r\n    const centroidT = (s.centroid[0] * dirX + s.centroid[1] * dirY - tMin) / span;\r\n    let eMin = Infinity;\r\n    let eMax = -Infinity;\r\n    for (let p = 0; p + 1 < s.polygon.length; p += 2) {\r\n      const pr = s.polygon[p] * dirX + s.polygon[p + 1] * dirY;\r\n      if (pr < eMin) eMin = pr;\r\n      if (pr > eMax) eMax = pr;\r\n    }\r\n    const extent01 = (eMax - eMin) / span;\r\n    const baseCenter = clamp(centroidT + (rng() - 0.5) * 0.12, 0.05, 0.95);\r\n    const baseWidth = clamp(extent01 * fx.spectrum.bandWidth, 0.02, 0.5);\r\n    const rimCenter = clamp((eMax - tMin) / span - baseWidth * 0.3, 0.05, 0.95);\r\n    out[i] = {\r\n      center01: baseCenter + (rimCenter - baseCenter) * edgeOnly,\r\n      width01: baseWidth * (1 - 0.55 * edgeOnly)\r\n    };\r\n  }\r\n  return out;\r\n}\r\n\r\n// src/motion/presets.ts\r\nvar impactTimeline = { crackStart: 0, crackEnd: 0.2, shatterStart: 0.25 };\r\nvar suspenseTimeline = { crackStart: 0, crackEnd: 0.55, shatterStart: 0.72 };\r\nvar hardBlastShatter = {\r\n  speed: 1600,\r\n  gravity: [0, 420],\r\n  drag: 1,\r\n  spinDegMax: 200,\r\n  tumbleDegMax: 80,\r\n  staggerPerRing: 0.03\r\n};\r\nvar gentleCrumbleShatter = {\r\n  speed: 280,\r\n  gravity: [0, 2200],\r\n  drag: 0.6,\r\n  spinDegMax: 70,\r\n  tumbleDegMax: 28,\r\n  staggerPerRing: 0.07\r\n};\r\nvar motionPresets = {\r\n  impact: { label: \"Impact - hard blast\", timeline: impactTimeline, shatter: hardBlastShatter },\r\n  suspense: { label: \"Suspense - long crack, late shatter\", timeline: suspenseTimeline },\r\n  crumble: { label: \"Crumble - reluctant gravity fall\", shatter: gentleCrumbleShatter },\r\n  poster: { label: \"Poster - static cracked, no shatter\", timeline: staticCrackedTimeline }\r\n};\r\n\r\n// src/index.ts\r\nvar collapseShatterPreset = {\r\n  speed: 300,\r\n  gravity: [0, 2200],\r\n  drag: 0.6,\r\n  spinDegMax: 80,\r\n  tumbleDegMax: 30,\r\n  staggerPerRing: 0.05\r\n};\r\nexport {\r\n  collapseShatterPreset,\r\n  computeFrame,\r\n  defaultEffectParams,\r\n  flightOffset,\r\n  flightSpeed,\r\n  generateFracture,\r\n  gentleCrumbleShatter,\r\n  hardBlastShatter,\r\n  impactTimeline,\r\n  motionPresets,\r\n  normalizeEffectParams,\r\n  qualityPresets,\r\n  resolvePhase,\r\n  resolveQuality,\r\n  staticCrackedTimeline,\r\n  suspenseTimeline\r\n};\r\n","modules/portal/peer.mjs":"// #135 look-around behind the portal window. The portal's destination framing (portal.mjs) writes the eye here while a\r\n// destination is open inside the metal frame: x right, y down, each -1..1 at the tilt clamp, 0 when off (reduced\r\n// motion, camera-only, no destination). A three.js scene behind the window calls offAxis() every frame.\r\n// Standalone and dependency-free: served unbundled next to portal.mjs and imported by the scenes that use it.\r\n// AGPL-3.0-or-later.\r\nexport const eye={x:0,y:0};\r\n\r\n// Off-axis (head-coupled) projection: the eye slides parallel to the window while the window's edges stay pinned, so\r\n// the scene behind shows its sides like a real hole in a wall (Kooima's frustum for a screen-parallel window). Call it\r\n// after the scene has posed its camera for the frame, right before render. dist: the camera's distance to the window\r\n// plane (put it at the subject: nearer things swing more, farther less); deg: the view shift at full tilt. It undoes\r\n// its own last shift if the scene left the camera where it was, so a camera posed once (not every frame) is fine too,\r\n// and rebuilds the frustum every call (the scene's own updateProjectionMatrix() makes it symmetric again).\r\nexport function offAxis(camera,dist,deg=12){\r\n const u=camera.userData;\r\n if(u.peerAt&&camera.position.equals(u.peerAt)){camera.translateX(-u.peerX);camera.translateY(-u.peerY);}\r\n camera.updateProjectionMatrix();\r\n const k=Math.tan(deg*Math.PI/180)*dist,ex=eye.x*k,ey=-eye.y*k; // world units at the window plane; screen y is down\r\n u.peerX=ex;u.peerY=ey;\r\n if(ex||ey){\r\n  camera.translateX(ex);camera.translateY(ey);\r\n  const near=camera.near,top=near*Math.tan(camera.fov*Math.PI/360)/camera.zoom,half=top*camera.aspect,s=near/dist;\r\n  camera.projectionMatrix.makePerspective(-half-ex*s,half-ex*s,top-ey*s,-top-ey*s,near,camera.far);\r\n  camera.projectionMatrixInverse.copy(camera.projectionMatrix).invert();\r\n }\r\n (u.peerAt??=camera.position.clone()).copy(camera.position);\r\n}\r\n","modules/portal/portal-apertures.mjs":"// Shared manufacturing and portal release contours, in the supplied rectangle's units.\r\n// Mechanical boards build these seams before input; other boards use the same windows.\r\nimport {SHAPES} from './portal-shapes.mjs';\r\nconst closeLoop=pts=>{const a=pts[0],b=pts.at(-1);return a[0]===b[0]&&a[1]===b[1]?pts:[...pts,a];};\r\nconst toClientPts=(pts,rect)=>pts.map(([x,y])=>[rect.left+x*rect.width,rect.top+y*rect.height]);\r\nconst LINE_IDS=new Set(['line-lr','line-rl','line-down']);\r\nexport function shapeOutlinePts(id){\r\n const pts=SHAPES[id][0].points;\r\n if(id!=='oval')return pts;\r\n const step=Math.max(1,Math.floor(pts.length/48));\r\n return pts.filter((_,i)=>i%step===0);\r\n}\r\nexport function lensPts([ax,ay],[bx,by],half,n=24){\r\n const l=Math.hypot(bx-ax,by-ay)||1,nx=-(by-ay)/l,ny=(bx-ax)/l;\r\n const side=sign=>Array.from({length:n+1},(_,i)=>{const t=sign>0?i/n:1-i/n,w=sign*half*Math.sin(Math.PI*t);return [ax+(bx-ax)*t+nx*w,ay+(by-ay)*t+ny*w];});\r\n return closeLoop([...side(1),...side(-1).slice(1,-1)]);\r\n}\r\nexport function portalWindow(id,rect){\r\n if(LINE_IDS.has(id)){\r\n  const points=SHAPES.line[id==='line-lr'||id==='line-rl'?1:0].points;\r\n  const [a,b]=toClientPts(points,rect),len=Math.hypot(b[0]-a[0],b[1]-a[1]);\r\n  return {pts:lensPts(a,b,Math.min(.17*len,.3*rect.width)),axis:[a,b]};\r\n }\r\n if(id==='x'){\r\n  const cx=rect.left+rect.width/2,cy=rect.top+rect.height/2,r=.3*Math.min(rect.width,rect.height);\r\n  return {pts:closeLoop([[cx,cy-r],[cx+r,cy],[cx,cy+r],[cx-r,cy]])};\r\n }\r\n return {pts:closeLoop(toClientPts(shapeOutlinePts(id),rect))};\r\n}\r\n","modules/portal/portal-board-cogs.mjs":"// Pre-sectioned mechanical metal grimoire. Existing kit gears, shared portal shapes.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/addons/libs/meshopt_decoder.module.js';\r\nimport {orientMatrix,pointInPolygon,GLB} from './portal-board-glb.mjs';\r\nimport {MECHANICAL_FRAME,mechanicalPaths,releasePaths,sectionPanels,mechanicalLayout,mechanismLayout,pointOnPath,signedRailImpulse} from './portal-mechanical-layout.mjs';\r\n\r\nexport const LAYOUT='/pod/worlds/boards/cogs/door-layout.json';\r\nconst PARTS='/pod/worlds/boards/cogs/parts-kit.glb';\r\n// The same inset shape frame is shared by the metal assemblies and 2D fallback.\r\nexport const DEFAULT_FRAME=MECHANICAL_FRAME;\r\nconst HUB_NODE='m19';\r\nconst TAU=Math.PI*2,FRICTION=1.6,REST=.02,TAP_IMPULSE=4,MOVE_EPS=.006;\r\n// ponytail: hard speed cap, not a torque/inertia model — keeps a wild flick from strobing the spokes.\r\nconst MAX_OMEGA=12;\r\n// Valves idle at VALVE_IDLE rad/s in the (single, shared) train direction plus VALVE_RATIO of its\r\n// omega, but (see valveActive in step()) only while the train or a finger is actually active.\r\n// ponytail: every valve and every gear tree shares one idle direction/rate rather than each valve\r\n// following its own nearest tree — give valves a `drives`-like link to their tree if two trains ever\r\n// spin opposite and it reads wrong.\r\nconst VALVE_IDLE=.25,VALVE_RATIO=.15,LIGHT_COLOR='#c59a56';\r\nconst LAMP_CORE=new THREE.Color('#ffd9a0'),LAMP_OFF=new THREE.Color('#3d2f14'),lampOn=new THREE.Color(),lampTmp=new THREE.Color();\r\nlet selectedTint='#c59a56',selectedBackplateTint='#263943',weldTrace=null;\r\n// Retained for existing callers; rebuilt metal uses its independent backplate tint.\r\nexport function doorTone(hex){\r\n const n=parseInt(hex.slice(1),16),r=(n>>16&255)/255,g=(n>>8&255)/255,b=(n&255)/255,mx=Math.max(r,g,b),mn=Math.min(r,g,b),l=(mx+mn)/2,d=mx-mn;\r\n let h=0;if(d){h=mx===r?((g-b)/d+6)%6:mx===g?(b-r)/d+2:(r-g)/d+4;h/=6;}\r\n const s=d?d/(1-Math.abs(2*l-1)):0,H=(h+.5)%1,S=s*.5,L=Math.min(l,.5)*.75,a=S*Math.min(L,1-L);\r\n const f=k=>{const t=(k+H*12)%12;return Math.round(255*(L-a*Math.max(-1,Math.min(t-3,9-t,1))));};\r\n return '#'+[f(0),f(8),f(4)].map(v=>v.toString(16).padStart(2,'0')).join('');\r\n}\r\nconst validTint=hex=>typeof hex==='string'&&/^#[0-9a-f]{6}$/i.test(hex);\r\n\r\n// All touch-reactive tuning in one place. Pipes wiggle as a damped torsion spring, angle'' =\r\n// -w0^2*angle - damping*angle' (w0 = 2*pi*wiggleFreqHz): underdamped, so a kick visibly oscillates a\r\n// few times before decaying under wiggleRestAngle/wiggleRestOmega (~1s at the defaults below).\r\n// Lights sit at lightOff until a finger comes within lightRadius (face-width fraction), ramp to\r\n// lightOn over lightRampMs, hold while near and for lightHoldMs after, then fade back over\r\n// lightFadeMs.\r\nexport const KNOBS={\r\n wiggleKick:5,          // rad/s added per (face-width/s) of sideways finger speed, per move event\r\n wiggleTapKick:.6,      // rad/s added by a plain tap on a pipe (no motion to read a speed from)\r\n wiggleMargin:.02,      // face-width fraction added to a pipe's r for \"near enough to react\"\r\n wiggleFreqHz:6,\r\n wiggleDamping:8,       // x'' + damping*x' + w0^2*x = 0\r\n wiggleMaxAngle:10*Math.PI/180, // clamp so repeated re-excites can't wind past this\r\n wiggleBob:.02,         // z bob at full amplitude, as a fraction of face width\r\n wiggleRestAngle:.004,  // rad — below this and wiggleRestOmega, a pipe counts as settled\r\n wiggleRestOmega:.05,   // rad/s\r\n lightRadius:.12,\r\n lightRampMs:120,\r\n lightHoldMs:800,\r\n lightFadeMs:1200,\r\n lightOff:0,\r\n lightOn:1.6,\r\n lightFlicker:.06,      // +/- fraction of lightOn while fully lit\r\n hubIdleAccel:.6,       // rad/s^2 \"motor\" on each hub gear, balanced by FRICTION into a steady idle\r\n                         // spin (equilibrium omega ~= hubIdleAccel/FRICTION, ~.25-.4 rad/s here)\r\n // Welding trail: sizes are given in SCREEN px (so they read at a glance on a phone) and converted to\r\n // canvas px each draw via pxScale() — the live canvas-to-screen scale (measured off the rendered\r\n // <canvas> + the same fit math portal-board-glb.mjs's computeFit() uses) — rather than baked to a\r\n // fixed texture-px size. Sparks fly at \"screen px/s\" so a frame's streak (speed*dt) reads as roughly\r\n // sparkSpeedMinPx..MaxPx/60 wide at 60fps. Timeline: hot trail .5s (weldHotMs, held near-full for\r\n // weldHotHold of that then cooling), then the bead holds (weldBeadHold of weldBeadMs) and fades —\r\n // total 2.5s end to end. The seam sits on the plate face, with raised gears occluding it.\r\n sparkSpeedMinPx:300,sparkSpeedMaxPx:1100, // screen px/s, radial spray (slow ones dribble, fast ones fly)\r\n sparkGravityPx:1500,                       // screen px/s^2, downward: sparks arc over and fall\r\n sparkLifeMin:.35,sparkLifeMax:.9,          // s — the wider range reads as \"some fly further\"\r\n sparkWidthPx:2.4,                          // screen px, streak stroke width (thin incandescent wire)\r\n sparkStreakS:.02,                          // s of velocity drawn behind each spark: its motion-blur streak\r\n sparkBounce:.35,                           // fraction of sparks that hit a \"floor\" below the torch and skitter\r\n sparkFloorMinPx:30,sparkFloorMaxPx:110,    // screen px below the torch where a bouncing spark lands\r\n sparkBounceKeep:.38,                       // vertical speed kept on the bounce (horizontal keeps .8)\r\n sparkPressCount:24,sparkReleaseCount:6,sparkIdleCount:4,sparkIdleMs:45, // press flare spray; trickle while held\r\n sparkPerFrac:.004,sparkMoveMax:12,         // sparks per face-width-fraction of travel per move event\r\n sparkMax:200,                              // ponytail: hard cap on live sparks\r\n torchCorePx:4.5,            // screen px, white-hot core radius at the contact point while a finger is down\r\n torchBloomPx:20,          // screen px, blue-white -> warm bloom around the core\r\n torchFlareMs:220,         // the press flare: core+bloom swell this long after touch-down\r\n torchFlareScale:2.2,      // how much bigger the bloom is at the instant of the press\r\n tintHaloMix:.22,          // the selected tint only tints the outer halo of the hot trail, this much\r\n weldStep:.016,            // face-width fraction: trail-point spacing\r\n weldHotMs:500,            // hot-glow portion of the trail\r\n weldHotHold:.35,           // fraction of weldHotMs held near-full brightness before it starts cooling\r\n weldBeadMs:2000,           // bead hold (weldBeadHold) + fade after the trail cools\r\n weldBeadHold:.625,         // 1.25s hold followed by .75s fade\r\n weldTrailWidthPx:3,        // screen px, hot-trail core stroke width\r\n weldTrailHaloPx:9,        // screen px, hot-trail bloom halo width\r\n weldBeadRadiusPx:2.5,      // screen px, bead half-width (~5px seam)\r\n weldRipplePx:3.8,          // screen px between \"stack of dimes\" ripples along the bead\r\n weldHaloRadiusPx:5.5,       // screen px, heat-tint band (straw next to the bead -> blue outside) half-width\r\n weldCap:260,               // ponytail: hard cap on stored trail points\r\n};\r\n// The tint picker recolours the kit parts (cogs, lamps, pipes...) as anodized metal (see metalFinish).\r\nexport const METAL={metalness:.92,roughness:.3,envIntensity:1.25};\r\n// Portal release moves whole prebuilt plate assemblies with the existing timing and tilt.\r\nconst FALL_MS=1100,FALL_TILT=35*Math.PI/180;\r\n\r\n// --- Pure train kinematics (unit-tested; no THREE/DOM) --------------------------------------\r\n// Walks a gear's `drives` chain to the train's root and returns {root,ratio} such that, once\r\n// settled, gears[i].omega === ratio*gears[root].omega (each mesh flips sign: ratio *= -r[parent]/r[self]).\r\nfunction rootRatio(gears,i){\r\n let idx=i,ratio=1;\r\n while(gears[idx].drives!=null){const p=gears[idx].drives;ratio*=gears[idx].driveRatio??(-gears[p].r/gears[idx].r);idx=p;}\r\n return {root:idx,ratio};\r\n}\r\n// Adds torque/impulse `omega` at gear i, converted to the equivalent change at the train's root —\r\n// a rigidly meshed train shares one momentum, so nudging any gear nudges the whole train.\r\nexport function applyTorque(gears,i,omega){\r\n const {root,ratio}=rootRatio(gears,i);\r\n const r=gears[root];\r\n r.omega=Math.max(-MAX_OMEGA,Math.min(MAX_OMEGA,r.omega+omega/ratio));\r\n}\r\n// Friction on the roots only (drives==null), then every meshed gear's speed is re-derived from its\r\n// parent and angles integrate. Returns true while the train is still moving fast enough to render.\r\nexport function stepTrain(gears,dt){\r\n for(const g of gears)if(g.drives==null)g.omega*=Math.exp(-dt*FRICTION);\r\n for(const g of gears){\r\n  if(g.drives!=null){const p=gears[g.drives];g.omega=p.omega*(g.driveRatio??(-p.r/g.r));}\r\n  g.angle+=g.omega*dt;\r\n }\r\n return gears.some(g=>Math.abs(g.omega)>REST);\r\n}\r\n// Hub idle motor: every gear with an idleDir is pushed along it. Pure (tested): the board calls it each frame\r\n// unless prefers-reduced-motion is on. Returns true when it is pushing, so the render loop stays awake.\r\nexport function idleSpin(gears,dt,accel,reduced){\r\n if(reduced)return false;let on=false;\r\n for(const g of gears)if(g.idleDir){g.omega+=g.idleDir*accel*dt;on=true;}\r\n return on;\r\n}\r\n// Layout parts -> a physics gears array indexed 0..n over just the kind:'gear' entries, with each\r\n// one's `drives` (a parts-array index) remapped to a gear-array index (absent/non-gear -> its own\r\n// root). No tooth data in the layout (real kit models, not procedural teeth), so a gear's initial\r\n// angle is just its `rot`; the train settles its own phase from there once it's nudged.\r\nexport function gearsFromLayout(parts){\r\n const idx=[];parts.forEach((p,i)=>{if(p.kind==='gear')idx.push(i);});\r\n const at=new Map(idx.map((partI,gi)=>[partI,gi]));\r\n return idx.map(partI=>{\r\n  const p=parts[partI];\r\n  return {u:p.u,v:p.v,r:p.r,drives:p.drives!=null?(at.get(p.drives)??null):null,angle:(p.rot||0)*Math.PI/180,omega:0,driveRatio:p.driveRatio};\r\n });\r\n}\r\n// Nearest gear (layout circle: centre u,v, radius r*face.w) to (u,v), skipping any index in `skip`\r\n// (gone with a falling cut piece); -1 if none is under the point.\r\nexport function hitGear(gears,face,u,v,skip){\r\n let best=-1,bestT=1;\r\n for(let i=0;i<gears.length;i++){\r\n  if(skip?.has(i))continue;\r\n  const g=gears[i],dx=(u-g.u)*face.w,dy=(v-g.v)*face.h,t=Math.hypot(dx,dy)/(g.r*face.w);\r\n  if(t<1&&t<bestT){bestT=t;best=i;}\r\n }\r\n return best;\r\n}\r\n// Dressing keep-out (pure, tested): drops layout parts whose circle (r+.012) comes within `clear` face-widths of any shape\r\n// path, or that overlap a keep-out circle {u,v,r} / cable segment {a,b,r}. Distances are in face-width units.\r\nexport function dressingKeep(parts,paths,face,circles=[],segments=[],clear=.012){\r\n return parts.filter(p=>{\r\n  const R=p.r+.012,hit=pointOnPath(paths,face,p.u,p.v);\r\n  if(hit&&hit.distance-R<clear)return false;\r\n  for(const c of circles)if(Math.hypot((p.u-c.u)*face.w,(p.v-c.v)*face.h)<c.r+p.r)return false;\r\n  for(const s of segments){\r\n   const dx=(s.b[0]-s.a[0])*face.w,dy=(s.b[1]-s.a[1])*face.h,l2=dx*dx+dy*dy||1,t=Math.max(0,Math.min(1,((p.u-s.a[0])*face.w*dx+(p.v-s.a[1])*face.h*dy)/l2));\r\n   if(Math.hypot((p.u-s.a[0])*face.w-dx*t,(p.v-s.a[1])*face.h-dy*t)<s.r+p.r)return false;\r\n  }\r\n  return true;\r\n });\r\n}\r\n// Parts that fail dressingKeep where the old door put them are slid to the nearest free spot (spiral search, then shrunk\r\n// to 70%/50%) so the panels fill up even though the shape lines own most of the old positions. Never overlaps an\r\n// already-placed part. Returns the placed parts (moved ones carry the new u,v,r).\r\nexport function dressingPlace(parts,paths,face,circles=[],segments=[],clear=.012,reach=.16){\r\n const placed=[];\r\n for(const p of parts)for(const k of [1,.7,.5]){\r\n  const q=dressingKeepAt(p,k,paths,face,circles.concat(placed.map(o=>({u:o.u,v:o.v,r:o.r}))),segments,clear,reach);\r\n  if(q){placed.push(q);break;}\r\n }\r\n return placed;\r\n}\r\nfunction dressingKeepAt(p,k,paths,face,circles,segments,clear,reach){\r\n const r=p.r*k;\r\n for(let d=0;d<=reach;d+=.012)for(let n=d?Math.round(d/.012)*6:1,i=0;i<n;i++){\r\n  const a=i/n*TAU,q={...p,r,u:p.u+Math.cos(a)*d,v:p.v+Math.sin(a)*d*face.w/face.h};\r\n  const ry=r*face.w/face.h;if(q.u-r<.012||q.u+r>.988||q.v-ry<.008||q.v+ry>.992)continue; // keep whole part on the door\r\n  if(dressingKeep([q],paths,face,circles,segments,clear).length)return q;\r\n }\r\n return null;\r\n}\r\n// Nearest pipe (by centre) within r+margin of (u,v) — pipe equivalent of hitGear above, but with a\r\n// margin since a pipe should react to a finger passing near it, not only dead-centre on it.\r\nexport function nearestPipe(pipes,face,u,v,margin){\r\n let best=-1,bestD=Infinity;\r\n for(let i=0;i<pipes.length;i++){\r\n  const p=pipes[i],dx=(u-p.u)*face.w,dy=(v-p.v)*face.h,d=Math.hypot(dx,dy),lim=(p.r+margin)*face.w;\r\n  if(d<lim&&d<bestD){bestD=d;best=i;}\r\n }\r\n return best;\r\n}\r\n// One step of a pipe's damped torsion spring (angle'' = -w0^2*angle - damping*angle'), clamped to\r\n// +-maxAngle so several quick re-excites can't wind it up past that.\r\nexport function wiggleStep(angle,omega,dt,freqHz,damping,maxAngle){\r\n const w0=TAU*freqHz;\r\n omega+=(-w0*w0*angle-damping*omega)*dt;\r\n angle+=omega*dt;\r\n if(angle>maxAngle){angle=maxAngle;if(omega>0)omega=0;}\r\n else if(angle<-maxAngle){angle=-maxAngle;if(omega<0)omega=0;}\r\n return {angle,omega};\r\n}\r\n// Angular kick for a pipe from a finger's raw per-event displacement (vx,vy, face-plane x/y — no\r\n// timestamp between move events to divide by, the same \"impulse per event\" approximation the gear\r\n// drag in move() already uses): the component of that motion across the pipe's long axis (rot),\r\n// signed so the pipe swings away from the swipe.\r\nexport function wiggleKick(vx,vy,rot,gain){\r\n return -gain*(-Math.sin(rot)*vx+Math.cos(rot)*vy);\r\n}\r\n// A valve's own dwell angle: idles at VALVE_IDLE in the train's shared direction, plus a small share\r\n// of its raw speed, alternating direction per valve (dir = ±1).\r\nexport function valveAngle(angle,dt,dir,valveDir,rootOmega){\r\n return (angle+dir*(VALVE_IDLE*valveDir+VALVE_RATIO*rootOmega)*dt)%TAU;\r\n}\r\n// A light's on/off level (0..1), stepped one dt toward `target` (1 near, 0 not) — ramping up over\r\n// rampMs, fading down over fadeMs. The \"how long since it was last near\" shape comes from the caller\r\n// holding target at 1 for a while after the finger leaves (see nearUntil in step()).\r\nexport function lightLevel(level,target,dt,rampMs,fadeMs){\r\n const rate=1000/(target>level?rampMs:fadeMs);\r\n return target>level?Math.min(target,level+rate*dt):Math.max(target,level-rate*dt);\r\n}\r\n// Lock-progress helpers (pure, tested). p = fraction of a path's length traced; n = stations on that path.\r\nexport const boltOut=(p,station,n)=>Math.max(0,Math.min(1,p*n-station));\r\nexport const pistonExt=(stroke,angle)=>stroke*(.5+.5*Math.sin(angle));\r\nexport const lampLit=(p,station,n)=>p>0&&p>=station/n-1e-9;\r\n// Fraction (0..1) of a polyline's length at the point (u,v) lying on segment `segment` (pointOnPath's hit).\r\nexport function pathProgress(points,face,segment,u,v){\r\n let before=0,total=0;\r\n for(let i=1;i<points.length;i++){const l=Math.hypot((points[i][0]-points[i-1][0])*face.w,(points[i][1]-points[i-1][1])*face.h);if(i-1<segment)before+=l;total+=l;}\r\n const a=points[segment];return Math.min(1,(before+Math.hypot((u-a[0])*face.w,(v-a[1])*face.h))/(total||1));\r\n}\r\n\r\n// Weld-heat colour ramp (0=freshest): white-hot -> yellow -> orange -> dull red, as {r,g,b} 0..255.\r\nconst HEAT_STOPS=[[1,1,.9],[1,.82,.24],[1,.47,.08],[.47,.14,.04]];\r\nexport function heatColor(f){\r\n f=Math.max(0,Math.min(1,f));\r\n const n=HEAT_STOPS.length-1,x=f*n,i=Math.min(n-1,Math.floor(x)),t=x-i,[r0,g0,b0]=HEAT_STOPS[i],[r1,g1,b1]=HEAT_STOPS[i+1];\r\n return {r:Math.round((r0+(r1-r0)*t)*255),g:Math.round((g0+(g1-g0)*t)*255),b:Math.round((b0+(b1-b0)*t)*255)};\r\n}\r\n// A weld bead's alpha at `age` ms since its trail point was laid: 0 until the trail cools (hotMs), 1\r\n// through a hold window (holdFrac of beadMs), then fading to 0 by hotMs+beadMs.\r\nexport function weldBeadAlpha(age,hotMs,beadMs,holdFrac){\r\n if(age<hotMs||age>hotMs+beadMs)return 0;\r\n const bf=(age-hotMs)/beadMs;\r\n return bf<holdFrac?1:Math.max(0,1-(bf-holdFrac)/(1-holdFrac));\r\n}\r\n\r\n// Linear 0..1 blend of the heat colour with the tint, as an rgba() string: the hot trail's outer halo only.\r\nfunction haloRGBA(f,tint,mix,alpha){\r\n const {r,g,b}=heatColor(f);if(!tint)return `rgba(${r},${g},${b},${Math.max(0,alpha)})`;\r\n const n=parseInt(tint.slice(1),16),m=a=>Math.round(a);\r\n return `rgba(${m(r+((n>>16)-r)*mix)},${m(g+(((n>>8)&255)-g)*mix)},${m(b+((n&255)-b)*mix)},${Math.max(0,alpha)})`;\r\n}\r\n\r\n// --- Metal finish for the kit parts --------------------------------------------------------------\r\n// One shared tint/mix uniform pair for every kit material: the selected tint turns the parts' baked\r\n// brass/copper albedo into luminance x tint (anodized metal), with real metalness/roughness and a small\r\n// studio env map so the metal has something to reflect. No tint -> mix 0 and the original PBR values,\r\n// i.e. the stock look.\r\nconst uMetalTint={value:new THREE.Color(1,1,1)},uMetalMix={value:0};\r\nlet envTex=null;\r\n// A tiny equirect \"studio\": dark floor, grey horizon, bright sky and two softbox stripes for highlights.\r\nfunction studioEnv(){\r\n if(envTex)return envTex;\r\n const c=document.createElement('canvas');c.width=128;c.height=64;const x=c.getContext('2d');\r\n const g=x.createLinearGradient(0,0,0,64);g.addColorStop(0,'#f4f6fa');g.addColorStop(.42,'#8a9098');g.addColorStop(.55,'#32353b');g.addColorStop(1,'#08090b');\r\n x.fillStyle=g;x.fillRect(0,0,128,64);x.fillStyle='#ffffff';x.fillRect(18,8,10,22);x.fillRect(80,4,22,9);x.fillRect(46,10,16,14);x.fillRect(104,14,8,18);\r\n envTex=new THREE.CanvasTexture(c);envTex.mapping=THREE.EquirectangularReflectionMapping;envTex.colorSpace=THREE.SRGBColorSpace;\r\n return envTex;\r\n}\r\nfunction metalFinish(mat){\r\n if(mat.userData.cogsMetal)return;\r\n mat.userData.cogsMetal={metalness:mat.metalness,roughness:mat.roughness,metalnessMap:mat.metalnessMap,roughnessMap:mat.roughnessMap,envMap:mat.envMap,envMapIntensity:mat.envMapIntensity};\r\n mat.onBeforeCompile=shader=>{\r\n  shader.uniforms.uMetalTint=uMetalTint;shader.uniforms.uMetalMix=uMetalMix;\r\n  shader.fragmentShader='uniform vec3 uMetalTint;\\nuniform float uMetalMix;\\n'+shader.fragmentShader\r\n   .replace('#include <map_fragment>','#include <map_fragment>\\n{float ml=dot(diffuseColor.rgb,vec3(.2126,.7152,.0722));diffuseColor.rgb=mix(diffuseColor.rgb,uMetalTint*clamp(.35+1.4*ml,0.,1.2),uMetalMix);}')\r\n   .replace('#include <emissivemap_fragment>','#include <emissivemap_fragment>\\n#ifdef USE_EMISSIVEMAP\\ntotalEmissiveRadiance=mix(totalEmissiveRadiance,emissive*(.4+dot(emissiveColor.rgb,vec3(.2126,.7152,.0722))),uMetalMix);\\n#endif');\r\n };\r\n mat.customProgramCacheKey=()=>'cogs-metal';mat.needsUpdate=true;\r\n}\r\nfunction applyMetal(mats){\r\n const on=!!selectedTint;uMetalMix.value=on?1:0;if(on)uMetalTint.value.set(selectedTint);\r\n for(const mat of mats){\r\n  const o=mat.userData.cogsMetal;if(!o)continue;\r\n  if(mat.userData.cogsOn!==on){mat.userData.cogsOn=on;mat.needsUpdate=true;} // maps/env swap: recompile once\r\n  Object.assign(mat,on?{metalness:METAL.metalness,roughness:METAL.roughness,metalnessMap:null,roughnessMap:null,envMap:studioEnv(),envMapIntensity:METAL.envIntensity}:o);\r\n }\r\n}\r\n\r\n// --- Effect glue -------------------------------------------------------------------------------\r\nlet S=null; // per-instance state; one portal board is ever active at once\r\nexport function setCogsTint(hex,selected=true){\r\n if(!validTint(hex))return;\r\n selectedTint=hex;\r\n if(S){for(const part of S.parts)if(part.kind==='light')part.mat.emissive.set(selectedTint||LIGHT_COLOR);applyMetal(S.mats);S.tint=selectedTint;S.wake?.();}\r\n if(weldTrace){weldTrace.tint=selectedTint;weldTrace.wake?.();}\r\n}\r\n\r\n// One GLTFLoader promise per file, so every slot using a kit shares a single load.\r\nconst models=new Map();\r\nconst loadModel=url=>{let pending=models.get(url);if(!pending){pending=new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).loadAsync(url).catch(error=>{models.delete(url);throw error;});models.set(url,pending);}return pending;};\r\nexport function setCogsBackplateTint(hex,selected=true){\r\n if(selected&&!validTint(hex))return;selectedBackplateTint=selected?hex:'#263943';\r\n if(S){S.backplateMaterial?.color.set(selectedBackplateTint);S.wake?.();}\r\n}\r\nfunction kitMesh(gltf,name){\r\n gltf.scene.updateMatrixWorld(true);\r\n let src=null;(name?gltf.scene.getObjectByName(name):gltf.scene)?.traverse(o=>{if(o.isMesh&&!src)src=o;});\r\n if(!src)throw new Error('no mesh '+(name||''));\r\n return src;\r\n}\r\n// A mesh sharing src's geometry/material, fitted by its matrix: thin axis -> +Z (if orient), centred\r\n// on its bbox, face-plane bbox radius = radius. Returns it with its fitted depth.\r\nfunction fitModel(src,radius,orient){\r\n const box=new THREE.Box3().setFromObject(src),rot=new THREE.Matrix4();\r\n if(orient){const R=orientMatrix(box.getSize(new THREE.Vector3()));rot.set(...R[0],0,...R[1],0,...R[2],0,0,0,0,1);box.applyMatrix4(rot);}\r\n const size=box.getSize(new THREE.Vector3()),k=radius/(Math.max(size.x,size.y)/2),c=box.getCenter(new THREE.Vector3());\r\n const m=new THREE.Mesh(src.geometry,src.material);m.frustumCulled=false;m.matrixAutoUpdate=false;\r\n m.matrix.makeScale(k,k,k).multiply(new THREE.Matrix4().makeTranslation(-c.x,-c.y,-c.z)).multiply(rot).multiply(src.matrixWorld);\r\n return {m,depth:size.z*k};\r\n}\r\n// Builds every layout entry as a Mesh (kit meshes lie flat, face at +Z — no thin-axis turn, same as\r\n// the old props): positioned on the door's front face, z-stacked by layer, rotated by rot. Returns\r\n// {parts,gearPivots}: parts for cut/heal (every kind); gearPivots indexed like gearsFromLayout's\r\n// output (undefined slot = that node failed to load; still driven, just invisible) for the physics\r\n// rotation each frame. ponytail: one Mesh per entry (draw calls ~= entry count, ~150-250 here); if\r\n// the pane ever shows frame drops, switch the static kinds (pipe/screw/plate/valve/light) to one\r\n// InstancedMesh per shared node — gears alone would still need their own objects to spin independently.\r\nfunction buildParts(parent,gltf,list,front,fw,fh,mats){\r\n const parts=[],gearPivots=[],batches=new Map();let gi=0;\r\n list.forEach((p,i)=>{\r\n  const isGear=p.kind==='gear';\r\n  let src;\r\n  try{src=kitMesh(gltf,p.node);}\r\n  catch(e){console.warn('portal-board-cogs: missing node',p.node,e);if(isGear)gi++;return;}\r\n  const x=(p.u-.5)*fw,y=(.5-p.v)*fh,{m,depth}=fitModel(src,p.r*fw,true),pivot=new THREE.Group();\r\n  const rot=(p.rot||0)*Math.PI/180;\r\n  const part={...p,pivot,rot,angle:0,omega:0};\r\n  pivot.position.set(x,y,front+(p.layer||0)*.006*fw+depth/2);\r\n  part.z0=pivot.position.z;part.top=part.z0+depth/2; // rest z; pipes bob off this and back\r\n  if(p.kind==='light'){\r\n   // A previous board may have left the shared kit material in its metal state: start the clone from the stock values.\r\n   const mat=src.material.clone(),stock=src.material.userData.cogsMetal;mat.userData={};if(stock)Object.assign(mat,stock);mat.emissive.set(selectedTint||LIGHT_COLOR);mat.emissiveMap=mat.map;mat.emissiveIntensity=KNOBS.lightOff;m.material=mat;\r\n   mats.push(mat);Object.assign(part,{mat,phase:i*2.3,level:0,nearUntil:-Infinity});\r\n  }else if(p.kind==='valve')part.dir=i%2?1:-1;\r\n  pivot.rotation.z=rot;\r\n  if(isGear){\r\n   let batch=batches.get(p.node);if(!batch){const mat=src.material.clone();mat.userData={};mats.push(mat);const mesh=new THREE.InstancedMesh(src.geometry,mat,list.filter(q=>q.kind==='gear'&&q.node===p.node).length);mesh.frustumCulled=false;mesh.castShadow=true;mesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);parent.add(mesh);batch={mesh,next:0};batches.set(p.node,batch);}\r\n   part.instance={mesh:batch.mesh,index:batch.next++,matrix:m.matrix.clone()};part.mat=batch.mesh.material;\r\n  }else{pivot.add(m);part.mat=m.material;}\r\n  parent.add(pivot);parts.push(part);\r\n  if(isGear){gearPivots[gi]=pivot;gi++;}\r\n });\r\n return {parts,gearPivots,batches:[...batches.values()].map(b=>b.mesh)};\r\n}\r\n// The old door's pipes/screws/plates/valves, one BatchedMesh per kit material (the kit has two) = 2 draw calls total.\r\n// Parts keep their own pivot (so pipes wiggle / valves spin / panels fall) and write into the batch via the same\r\n// `instance` path as the gears; `matrix` is the fitted model matrix.\r\nfunction buildDressing(parent,gltf,list,front,fw,fh,mats){\r\n const items=[],groups=new Map();\r\n for(const p of list){\r\n  let src;try{src=kitMesh(gltf,p.node);}catch(e){console.warn('portal-board-cogs: missing node',p.node,e);continue;}\r\n  const {m,depth}=fitModel(src,p.r*fw,true),pivot=new THREE.Group(),rot=(p.rot||0)*Math.PI/180,z=front+(p.layer||0)*.006*fw+depth/2;\r\n  pivot.position.set((p.u-.5)*fw,(.5-p.v)*fh,z);pivot.rotation.z=rot;\r\n  const part={...p,pivot,rot,angle:0,omega:0,z0:z,top:z+depth/2,dir:p.kind==='valve'?(items.length%2?1:-1):undefined,instance:{mesh:null,index:-1,matrix:m.matrix.clone()}};\r\n  let g=groups.get(src.material);if(!g){g={material:src.material,geos:new Map(),items:[]};groups.set(src.material,g);}\r\n  g.geos.set(src.geometry,null);g.items.push({part,geometry:src.geometry});items.push(part);\r\n }\r\n const batches=[];\r\n for(const g of groups.values()){\r\n  let v=0,ix=0;for(const geo of g.geos.keys()){v+=geo.attributes.position.count;ix+=geo.index?geo.index.count:0;}\r\n  const mat=g.material.clone();mat.userData={};mats.push(mat);\r\n  const mesh=new THREE.BatchedMesh(g.items.length,v,ix,mat);mesh.frustumCulled=false;mesh.perObjectFrustumCulled=false;parent.add(mesh);batches.push(mesh);\r\n  for(const geo of g.geos.keys())g.geos.set(geo,mesh.addGeometry(geo));\r\n  for(const it of g.items){it.part.instance.mesh=mesh;it.part.instance.index=mesh.addInstance(g.geos.get(it.geometry));it.part.mat=mat;}\r\n }\r\n return {parts:items,batches};\r\n}\r\nconst instanceTransform=new THREE.Matrix4(),instanceZero=new THREE.Matrix4().makeScale(0,0,0);\r\nfunction updateGearInstances(state){\r\n for(const panel of state.panels){panel.group.updateMatrix();state.panelBatch.setMatrixAt(panel.batchId,panel.group.matrix);state.panelBatch.setVisibleAt(panel.batchId,panel.group.visible);}\r\n for(const part of state.parts)if(part.instance){\r\n  const {mesh,index,matrix}=part.instance;part.pivot.updateMatrix();\r\n  if(!part.pivot.parent.visible)mesh.setMatrixAt(index,instanceZero);\r\n  else{instanceTransform.multiplyMatrices(part.pivot.parent.matrix,part.pivot.matrix).multiply(matrix);mesh.setMatrixAt(index,instanceTransform);}\r\n }\r\n for(const batch of state.batches)if(batch.instanceMatrix)batch.instanceMatrix.needsUpdate=true; // BatchedMesh uploads its own matrices\r\n}\r\n\r\n// The weld trail's own two layers in 3D, floating just above the tallest kit part so gears and pipes\r\n// never hide the sparks or the bead: the bead layer (normal blend) and the glow layer (additive) on top.\r\n// The door's own paint/glow inputs stay blank, so the trail isn't drawn twice.\r\nfunction weldLayer(parent,w,h,fw,fh,z,additive){\r\n const canvas=document.createElement('canvas');canvas.width=w;canvas.height=h;\r\n const texture=new THREE.CanvasTexture(canvas);texture.colorSpace=THREE.SRGBColorSpace; // flipY default: canvas row 0 = plane top\r\n const material=new THREE.MeshBasicMaterial({map:texture,transparent:true,depthWrite:false,polygonOffset:true,polygonOffsetFactor:-2,toneMapped:false,...(additive?{blending:THREE.AdditiveBlending}:{})});\r\n const mesh=new THREE.Mesh(new THREE.PlaneGeometry(fw,fh),material);mesh.position.z=z;mesh.renderOrder=additive?11:10;mesh.frustumCulled=false;parent.add(mesh);\r\n return {canvas,ctx:canvas.getContext('2d'),texture,mesh};\r\n}\r\n\r\nasync function init({mesh,face,wake,paint,glow}){\r\n const fw=face.w,fh=face.h,parent=mesh.isMesh?mesh.parent:mesh;\r\n const originals=[];mesh.traverse(n=>{if(n.isMesh){originals.push(n);n.visible=false;}});\r\n const [layout,gltf]=await Promise.all([\r\n  fetch(cogs.layoutAsset||LAYOUT).then(r=>{if(!r.ok)throw new Error(String(r.status));return r.json();}),\r\n  loadModel(cogs.partsAsset||PARTS),\r\n ]);\r\n cogs.frame=DEFAULT_FRAME;\r\n const paths=mechanicalPaths(),panels=sectionPanels([...paths,...releasePaths(face)]),owned=new THREE.Group();parent.add(owned);\r\n const railCanvas=document.createElement('canvas');railCanvas.width=paint.canvas.width;railCanvas.height=paint.canvas.height;\r\n const ctx=railCanvas.getContext('2d');ctx.strokeStyle='#fff';ctx.lineWidth=railCanvas.width*.006;ctx.lineJoin='round';ctx.lineCap='round';\r\n for(const path of paths){ctx.beginPath();path.points.forEach(([u,v],i)=>i?ctx.lineTo(u*railCanvas.width,v*railCanvas.height):ctx.moveTo(u*railCanvas.width,v*railCanvas.height));ctx.stroke();}\r\n const railTexture=new THREE.CanvasTexture(railCanvas);railTexture.flipY=false;\r\n const backplateMaterial=new THREE.MeshStandardMaterial({color:selectedBackplateTint,metalness:.55,roughness:.42,envMap:studioEnv(),envMapIntensity:.8});\r\n backplateMaterial.onBeforeCompile=shader=>{\r\n  shader.uniforms.uRailTint=uMetalTint;shader.uniforms.uRails={value:railTexture};\r\n  shader.fragmentShader='uniform vec3 uRailTint;uniform sampler2D uRails;varying vec2 vMetalUv;\\n'+shader.fragmentShader;\r\n  shader.vertexShader='varying vec2 vMetalUv;\\n'+shader.vertexShader.replace('#include <begin_vertex>','#include <begin_vertex>\\nvMetalUv=vec2(position.x/'+fw+'+.5,.5-position.y/'+fh+');');\r\n  shader.fragmentShader=shader.fragmentShader.replace('#include <color_fragment>','#include <color_fragment>\\nfloat rail=texture2D(uRails,vMetalUv).r;diffuseColor.rgb=mix(diffuseColor.rgb,uRailTint*.7,rail);');\r\n  // Directional polishing and fine abrasion remain part of the steel material,\r\n  // so they keep the selected back-wall hue and respond to its studio reflection.\r\n  shader.fragmentShader=shader.fragmentShader.replace('#include <roughnessmap_fragment>','#include <roughnessmap_fragment>\\nfloat brush=sin(vMetalUv.y*2350.0+sin(vMetalUv.x*80.0)*.65);roughnessFactor=clamp(roughnessFactor+brush*.055,.28,.62);')\r\n   .replace('#include <normal_fragment_maps>','#include <normal_fragment_maps>\\nnormal=normalize(normal+vec3(0.,brush*.045,0.));');\r\n };\r\n backplateMaterial.customProgramCacheKey=()=>`mechanical-backplate-${fw}-${fh}`;\r\n const front=.025*fw,depth=.026*fw;\r\n for(const panel of panels){\r\n  const shape=new THREE.Shape();panel.points.forEach(([u,v],i)=>{\r\n   // Inset toward each vertex's interior bisector. Bevel width is less than the\r\n   // inset, so the real joint remains open instead of bevels growing together.\r\n   const prev=panel.points[(i+panel.points.length-1)%panel.points.length],next=panel.points[(i+1)%panel.points.length],ax=(u-prev[0])*fw,ay=(v-prev[1])*fh,bx=(next[0]-u)*fw,by=(next[1]-v)*fh,al=Math.hypot(ax,ay),bl=Math.hypot(bx,by),nx=-ay/al-by/bl,ny=ax/al+bx/bl,nl=Math.hypot(nx,ny)||1,inset=Math.min(.0012*fw,al*.08,bl*.08),x=(u-.5)*fw+nx/nl*inset,y=(.5-v)*fh-ny/nl*inset;\r\n   i?shape.lineTo(x,y):shape.moveTo(x,y);\r\n  });shape.closePath();\r\n  const geometry=new THREE.ExtrudeGeometry(shape,{depth,bevelEnabled:true,bevelThickness:.0012*fw,bevelSize:.00065*fw,bevelSegments:1,steps:1,curveSegments:1});\r\n  // Each cell is an opaque, thick manufactured plate. A small normal inset makes\r\n  // the pre-existing joints visible without eroding the small oval-edge facets.\r\n  const positions=geometry.attributes.position;for(let i=0;i<positions.count;i++)positions.setZ(i,positions.getZ(i)+front-depth);\r\n  const group=new THREE.Group();owned.add(group);panel.group=group;panel.geometry=geometry;panel.gearIndices=[];\r\n }\r\n // BatchedMesh keeps every manufactured plate distinct while sharing its one\r\n // material and draw call. Release changes whole plate transforms only.\r\n const vertexCount=panels.reduce((n,p)=>n+p.geometry.attributes.position.count,0),panelBatch=new THREE.BatchedMesh(panels.length,vertexCount,0,backplateMaterial);panelBatch.frustumCulled=false;panelBatch.perObjectFrustumCulled=false;panelBatch.receiveShadow=true;owned.add(panelBatch);\r\n for(const panel of panels){const geometryId=panelBatch.addGeometry(panel.geometry);panel.batchId=panelBatch.addInstance(geometryId);}\r\n const nodes=[HUB_NODE]; // the kit's thin, face-on twenty-spoke cog: no bulky ornamental substitutes\r\n const built=mechanicalLayout(face,paths,nodes.length?nodes:[HUB_NODE]),list=built.parts;\r\n // Coaxial/belt couplers share the developed damped momentum across all rails;\r\n // individual meshes still counter-rotate at equal rim speeds along a rail.\r\n const first=built.trains[0]?.[0];for(const train of built.trains.slice(1)){const i=train[0];list[i].drives=first;list[i].driveRatio=list[first].r/list[i].r;}\r\n const gears=gearsFromLayout(list),mats=[],mech=mechanismLayout(face,paths,built),deg=a=>-a*180/Math.PI; // layout rot is face-uv (y down); the scene is y up\r\n mech.dial=[].concat(mech.dial)[0];\r\n list.push({node:HUB_NODE,kind:'dial',u:mech.dial.u,v:mech.dial.v,r:mech.dial.r,rot:0,layer:13});\r\n if(gears[0])gears[0].idleDir=1;\r\n const {parts,gearPivots,batches}=gltf?buildParts(owned,gltf,list,front,fw,fh,mats):{parts:[],gearPivots:[],batches:[]};\r\n // The previous door's kit dressing (pipes/screws/plates/valves) fills the panels between the shape lines; gears/lights are our own.\r\n const keepOut=[...list.map(g=>({u:g.u,v:g.v,r:g.r+.006})),...mech.lamps.map(l=>({u:l.u,v:l.v,r:l.r+.006})),...mech.weights.map(w=>({u:w.u,v:w.v,r:w.r+.006})),...mech.bolts.map(b=>({u:b.u,v:b.v,r:.055})),...mech.pistons.map(p=>({u:p.u,v:p.v,r:.05}))];\r\n const dress=dressingPlace((layout.parts||[]).filter(p=>['pipe','screw','plate','valve'].includes(p.kind)).map(p=>({...p,drives:undefined,layer:{plate:.3,screw:1.6,pipe:1.4,valve:1.4}[p.kind]})),[...paths,...releasePaths(face)],face,keepOut,mech.cables.map(c=>({a:c.from,b:c.to,r:c.r+.004})));\r\n const dressed=gltf&&dress.length?buildDressing(owned,gltf,dress,front,fw,fh,mats):{parts:[],batches:[]};\r\n batches.push(...dressed.batches);\r\n const panelAt=(u,v)=>panels.find(p=>pointInPolygon(u,v,p.points))||panels.reduce((a,b)=>Math.hypot((a.center[0]-u)*fw,(a.center[1]-v)*fh)<Math.hypot((b.center[0]-u)*fw,(b.center[1]-v)*fh)?a:b);\r\n for(const p of parts)if(p.kind!=='gear')panelAt(p.u,p.v).group.add(p.pivot); // the dial rides its panel\r\n for(const p of dressed.parts){panelAt(p.u,p.v).group.add(p.pivot);parts.push(p);}\r\n for(let gi=0;gi<gearPivots.length;gi++){\r\n  const g=gears[gi],h=list[gi].hub,dx=g.u-.5,dy=g.v-.495,l=Math.hypot(dx,dy)||1,u=g.u+(h?(g.u<.5?-.015:.015):dx/l*.004),v=g.v+(h?(g.v<.5?-.01:.01):dy/l*.004),panel=panelAt(u,v); // non-hub gears nudge outward like the other seam parts\r\n  if(gearPivots[gi])panel.group.add(gearPivots[gi]);panel.gearIndices.push(gi);\r\n }\r\n // The gold channels are real raised metal mounted on each pre-existing cell,\r\n // not a floating drawing. Each half-channel belongs to one side of its joint,\r\n // so the released plate carries its physical channel away with it.\r\n const railSegments=[];\r\n for(const panel of panels)for(let i=0;i<panel.points.length;i++){\r\n  const a=panel.points[i],b=panel.points[(i+1)%panel.points.length],hit=pointOnPath(paths,face,(a[0]+b[0])/2,(a[1]+b[1])/2),dx=(b[0]-a[0])*fw,dy=-(b[1]-a[1])*fh,length=Math.hypot(dx,dy);\r\n  if(!hit||hit.distance>1e-5*fw||length<.005*fw)continue;\r\n  railSegments.push({panel,a,b,dx,dy,length});\r\n }\r\n const railGeometry=new THREE.BoxGeometry(1,1,1),railMaterial=new THREE.MeshStandardMaterial({color:'#ffffff',metalness:.92,roughness:.3,envMap:studioEnv(),envMapIntensity:1.25}),railBatch=new THREE.InstancedMesh(railGeometry,railMaterial,railSegments.length);railBatch.frustumCulled=false;railBatch.castShadow=true;railBatch.instanceMatrix.setUsage(THREE.DynamicDrawUsage);owned.add(railBatch);batches.push(railBatch);mats.push(railMaterial);\r\n railSegments.forEach(({panel,a,b,dx,dy,length},index)=>{\r\n  const pivot=new THREE.Group(),width=.0028*fw;\r\n  // Clockwise face contour: right normal points inside the panel.\r\n  pivot.position.set(((a[0]+b[0])/2-.5)*fw+dy/length*.0024*fw,(.5-(a[1]+b[1])/2)*fh-dx/length*.0024*fw,front+.0035*fw);pivot.rotation.z=Math.atan2(dy,dx);panel.group.add(pivot);\r\n  parts.push({kind:'rail',pivot,mat:railMaterial,instance:{mesh:railBatch,index,matrix:new THREE.Matrix4().makeScale(Math.max(.001*fw,length-.0012*fw),width,.007*fw)}});\r\n });\r\n const shaftGeometry=new THREE.CylinderGeometry(1,1,1,10);shaftGeometry.rotateX(Math.PI/2);\r\n const shaftBatch=new THREE.InstancedMesh(shaftGeometry,railMaterial,gears.length);shaftBatch.frustumCulled=false;shaftBatch.castShadow=true;shaftBatch.instanceMatrix.setUsage(THREE.DynamicDrawUsage);owned.add(shaftBatch);batches.push(shaftBatch);\r\n for(let gi=0;gi<gears.length;gi++){\r\n  const gear=gears[gi],gearPart=parts.find(p=>p.kind==='gear'&&p.pivot===gearPivots[gi]);if(!gearPart)continue;\r\n  const bottom=2*gearPart.z0-gearPart.top,height=Math.max(.004*fw,bottom-front),pivot=new THREE.Group();pivot.position.set((gear.u-.5)*fw,(.5-gear.v)*fh,front+height/2);gearPivots[gi].parent.add(pivot);\r\n  parts.push({kind:'shaft',pivot,mat:railMaterial,instance:{mesh:shaftBatch,index:gi,matrix:new THREE.Matrix4().makeScale(gear.r*.2*fw,gear.r*.2*fw,height)}});\r\n }\r\n const bearingGeometry=new THREE.TorusGeometry(.009*fw,.0025*fw,5,20);\r\n built.trains.forEach((train,i)=>{\r\n  const g=gears[train[0]],panel=panels.find(p=>p.gearIndices.includes(train[0])),mat=new THREE.MeshStandardMaterial({color:selectedTint,metalness:.72,roughness:.32,emissive:selectedTint,emissiveIntensity:0}),pivot=new THREE.Group();\r\n  pivot.position.set((g.u-.5)*fw,(.5-g.v)*fh,(parts.find(p=>p.pathIndex===i)?.top||front+.02*fw)+.001*fw);pivot.add(new THREE.Mesh(bearingGeometry,mat));panel.group.add(pivot);mats.push(mat);\r\n  parts.push({kind:'light',u:g.u,v:g.v,r:.02,pivot,mat,phase:i*2.3,level:0,nearUntil:-Infinity});\r\n });\r\n // Procedural mechanism pieces share the rail material: one InstancedMesh per kind; each part's pivot rides its panel, poseMech() moves the matrix.\r\n const mechGeos=[],mk=(geo,n)=>{const m=new THREE.InstancedMesh(geo,railMaterial,n);m.frustumCulled=false;m.castShadow=true;m.instanceMatrix.setUsage(THREE.DynamicDrawUsage);m.userData.n=0;owned.add(m);batches.push(m);mechGeos.push(geo);return m;};\r\n const bar=new THREE.CylinderGeometry(1,1,1,10).rotateZ(Math.PI/2),box=new THREE.BoxGeometry(1,1,1),ring=new THREE.TorusGeometry(1,.07,6,28);\r\n const boltMesh=mk(box,mech.bolts.length),tubeMesh=mk(bar,mech.tubes.length),bodyMesh=mk(bar,mech.pistons.length),rodMesh=mk(bar,mech.pistons.length),cableMesh=mk(bar,mech.cables.length),weightMesh=mk(box,mech.weights.length),notchMesh=mk(box,12),rimMesh=mk(ring,mech.pulleys.length);\r\n // Lamps: emissive core sphere + two additive halo batches (tight glow, wide \"cast light\" on the door). Cast no shadow.\r\n const lampMat=new THREE.MeshBasicMaterial({toneMapped:false}),lampMesh=new THREE.InstancedMesh(new THREE.SphereGeometry(1,12,8),lampMat,mech.lamps.length);\r\n lampMesh.frustumCulled=false;lampMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);lampMesh.userData.n=0;owned.add(lampMesh);batches.push(lampMesh);mechGeos.push(lampMesh.geometry,lampMat);\r\n const haloTex=(()=>{const c=document.createElement('canvas');c.width=c.height=64;const x=c.getContext('2d'),g=x.createRadialGradient(32,32,0,32,32,32);g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(.25,'rgba(255,255,255,.45)');g.addColorStop(.6,'rgba(255,255,255,.1)');g.addColorStop(1,'rgba(255,255,255,0)');x.fillStyle=g;x.fillRect(0,0,64,64);return new THREE.CanvasTexture(c);})();\r\n const haloGeo=new THREE.PlaneGeometry(2,2),mkHalo=(order)=>{const m=new THREE.InstancedMesh(haloGeo,new THREE.MeshBasicMaterial({map:haloTex,blending:THREE.AdditiveBlending,transparent:true,depthWrite:false,toneMapped:false}),mech.lamps.length);m.frustumCulled=false;m.renderOrder=order;m.instanceMatrix.setUsage(THREE.DynamicDrawUsage);m.userData.n=0;owned.add(m);batches.push(m);mechGeos.push(m.material,haloTex);return m;};\r\n const glowMesh=mkHalo(20),castMesh=mkHalo(19);mechGeos.push(haloGeo);\r\n // Seam parts are nudged .004 outward (bolts inward) before choosing a panel, so each rides one side of its joint and falls with it.\r\n const side=(u,v,k)=>{const dx=u-.5,dy=v-.495,l=Math.hypot(dx,dy)||1,n=k==='bolt'?-.004:['tube','body','rod','lamp'].includes(k)?.004:0;return [u+dx/l*n,v+dy/l*n];};\r\n const add=(mesh,kind,u,v,rot,z,extra,group)=>{const pivot=new THREE.Group(),part={kind,pivot,mat:railMaterial,u,v,rot,instance:{mesh,index:mesh.userData.n++,matrix:new THREE.Matrix4()},...extra};pivot.position.set((u-.5)*fw,(.5-v)*fh,z);pivot.rotation.z=rot;(group||panelAt(...side(u,v,kind)).group).add(pivot);parts.push(part);return part;};\r\n const zAt=layer=>front+layer*.006*fw,uvRot=a=>-a;\r\n for(const b of mech.bolts)add(boltMesh,'bolt',b.u,b.v,uvRot(b.rot),zAt(4),{pathIndex:b.pathIndex,station:b.station,throw:b.throw,side:b.side??1});\r\n for(const t of mech.tubes)add(tubeMesh,'tube',t.u,t.v,uvRot(t.rot),zAt(3),{}).instance.matrix.makeScale(t.len*fw,(t.r||.007)*fw,(t.r||.007)*fw);\r\n for(const p of mech.pistons){const hb=1.2*p.r*fw;add(bodyMesh,'body',p.u,p.v,uvRot(p.rot),zAt(4),{}).instance.matrix.makeScale(hb*2,.012*fw,.012*fw);add(rodMesh,'rod',p.u,p.v,uvRot(p.rot),zAt(4),{stroke:p.stroke,drives:p.drives,hb,Lr:hb*1.5,rr:.005*fw});}\r\n mech.lamps.forEach((l,i)=>{add(lampMesh,'lamp',l.u,l.v,0,zAt(12),{r0:l.r*fw,pathIndex:l.pathIndex,station:l.station,phase:i*2.3,level:0,nearUntil:-Infinity,flashUntil:-Infinity}).instance.matrix.makeScale(l.r*fw,l.r*fw,l.r*fw);lampMesh.setColorAt(i,LAMP_OFF);const pt=parts[parts.length-1];for(const [key,hm] of [['glow',glowMesh],['cast',castMesh]]){const h={kind:'halo',pivot:pt.pivot,mat:railMaterial,instance:{mesh:hm,index:hm.userData.n++,matrix:new THREE.Matrix4().makeScale(0,0,0)}};parts.push(h);pt[key]=h;hm.setColorAt(h.instance.index,LAMP_OFF);}});\r\n for(const c of mech.cables){const dx=(c.to[0]-c.from[0])*fw,dy=-(c.to[1]-c.from[1])*fh,len=Math.hypot(dx,dy),pt=add(cableMesh,'cable',(c.from[0]+c.to[0])/2,(c.from[1]+c.to[1])/2,Math.atan2(dy,dx),zAt(2),{});pt.instance.matrix.makeScale(len,c.r*fw,c.r*fw);}\r\n mech.weights.forEach((w,i)=>{const c=mech.cables[i]??mech.cables[0];if(!c)return;add(weightMesh,'weight',w.u,w.v,Math.atan2(-(c.to[1]-c.from[1])*fh,(c.to[0]-c.from[0])*fw),zAt(3),{travel:w.travel,drives:w.drives,size:w.r*2*fw});});\r\n for(const p of mech.pulleys){const gp=parts.find(q=>q.pivot===gearPivots[p.drives]);if(!gp)continue;const pt=add(rimMesh,'rim',p.u,p.v,0,gp.top+.001*fw,{},gearPivots[p.drives].parent);pt.instance.matrix.makeScale(p.r*fw*1.08,p.r*fw*1.08,.005*fw);}\r\n for(let k=0;k<12;k++){const a=k*Math.PI/6,d=parts.find(q=>q.kind==='dial'),pt=add(notchMesh,'notch',mech.dial.u,mech.dial.v,a,(d?.top??zAt(14))+.001*fw,{});pt.instance.matrix.makeScale(.012*fw,.006*fw,.006*fw).setPosition(mech.dial.r*fw*.9,0,0);}\r\n for(const m of batches)if(m.userData.n!=null)m.count=m.userData.n;\r\n const tally=(a)=>a.reduce((o,x)=>(o[x.pathIndex]=(o[x.pathIndex]||0)+1,o),{});\r\n mats.push(...new Set(parts.map(p=>p.mat)));\r\n for(const m of mats)metalFinish(m);applyMetal(mats);\r\n const tw=paint.canvas.width,th=paint.canvas.height;\r\n // Weld lies on the plate face; proud gears correctly occlude it. No elevated\r\n // full-board decal can hang over an opening left by a released assembly.\r\n const beadLayer=weldLayer(owned,tw,th,fw,fh,front+.0018*fw,false),glowLayer=weldLayer(owned,tw,th,fw,fh,front+.002*fw,true);\r\n const motion=matchMedia?.('(prefers-reduced-motion: reduce)'),reducedMotion=!!motion?.matches;\r\n S={dial:mech.dial,closed:paths.map(p=>Math.hypot(p.points[0][0]-p.points.at(-1)[0],p.points[0][1]-p.points.at(-1)[1])<1e-7),prog:paths.map(()=>0),cutToken:null,cutTimer:null,cutResolve:null,boltN:tally(mech.bolts),lampN:tally(mech.lamps),mechGeos,spin:null,motion,gears,gearPivots,parts,face,aspect:fh/fw,valveDir:1,mats,drag:new Map(),fall:null,wake,reducedMotion,paths,trains:built.trains,panels,owned,originals,backplateMaterial,railTexture,batches,bearingGeometry,railGeometry,shaftGeometry,panelBatch,\r\n    paint:beadLayer,glow:glowLayer,layers:[beadLayer,glowLayer],texW:tw,texH:th,\r\n    sparks:[],weld:[],weldHeads:new Map(),weldActive:false,tint:selectedTint};\r\n updateGearInstances(S);\r\n}\r\n// --- Welding trail: torch core + sparks + hot streak (glow layer) + cooling weld bead (paint layer) ---\r\n// A spark: {x,y (canvas px),vx,vy (px/s),born (ms),life (s),floor (canvas y it bounces off once, or\r\n// Infinity)}. Speeds/gravity are screen px scaled to canvas px at spawn (S.scale, refreshed per frame).\r\nfunction spawnSparks(S,u,v,count){\r\n if(count<=0)return;\r\n const scale=S.scale||pxScale(S),cx=u*S.texW,cy=v*S.texH,now=performance.now(),K=KNOBS;\r\n for(let i=0;i<count&&S.sparks.length<K.sparkMax;i++){\r\n  const a=Math.random()*TAU,spd=(K.sparkSpeedMinPx+Math.random()*(K.sparkSpeedMaxPx-K.sparkSpeedMinPx))*scale;\r\n  const floor=Math.random()<K.sparkBounce?cy+(K.sparkFloorMinPx+Math.random()*(K.sparkFloorMaxPx-K.sparkFloorMinPx))*scale:Infinity;\r\n  S.sparks.push({x:cx,y:cy,vx:Math.cos(a)*spd,vy:Math.sin(a)*spd,born:now,floor,\r\n   life:K.sparkLifeMin+Math.random()*(K.sparkLifeMax-K.sparkLifeMin)});\r\n }\r\n}\r\n// One spark step: gravity, move, and a single damped bounce off its floor (the skitter). Pure, tested.\r\nexport function stepSpark(s,dt,grav,keep){\r\n s.vy+=grav*dt;s.x+=s.vx*dt;s.y+=s.vy*dt;\r\n if(s.y>s.floor&&s.vy>0){s.y=s.floor;s.vy*=-keep;s.vx*=.8;s.floor=Infinity;}\r\n return s;\r\n}\r\n// A weld-trail point {u,v,t (ms),prev,d}: prev links to the same finger's previous point (per id, via\r\n// weldHeads) so two simultaneous strokes never draw a segment joining them; d is the running seam\r\n// length (face widths) so the bead's ripples sit at fixed spacing however the points fall.\r\nfunction weldPushPoint(S,id,u,v){\r\n if(S.fall&&pointInPolygon(u,v,S.fall.poly)){S.weldHeads.delete(id);return;}\r\n const prev=S.weldHeads.get(id)||null,len=prev?Math.hypot(u-prev.u,(v-prev.v)*S.aspect):0;\r\n if(prev&&len<KNOBS.weldStep)return;\r\n const p={u,v,t:performance.now(),prev,d:prev?prev.d+len:0};S.weld.push(p);S.weldHeads.set(id,p);\r\n if(S.weld.length>KNOBS.weldCap)S.weld.splice(0,S.weld.length-KNOBS.weldCap); // ponytail: hard cap\r\n}\r\nfunction weldRelease(S,id,u,v){\r\n weldPushPoint(S,id,u,v);S.weldHeads.delete(id);spawnSparks(S,u,v,KNOBS.sparkReleaseCount);\r\n}\r\nfunction heatRGBA(f,alpha){const {r,g,b}=heatColor(f);return `rgba(${r},${g},${b},${Math.max(0,alpha)})`;}\r\n// Canvas px per screen px right now: measured off the live rendered <canvas> (its CSS box) with the\r\n// same margin-fit math computeFit() uses in portal-board-glb.mjs (GLB.margin), so every xxxPx knob\r\n// stays a true screen size regardless of GLB.texSize, host width or devicePixelRatio. Read once per\r\n// frame (stepWeld caches it on S.scale).\r\nfunction pxScale(S){\r\n const el=document.querySelector('canvas.portal-board-canvas'),cw=el?.clientWidth,ch=el?.clientHeight;\r\n if(!cw||!ch)return 2; // not laid out yet: a reasonable guess, corrected the moment it is\r\n const availW=cw*(1-2*GLB.margin),availH=ch*(1-2*GLB.margin),scaleFit=Math.min(availW/S.face.w,availH/S.face.h);\r\n return S.texW/(scaleFit*S.face.w);\r\n}\r\n// The bead shows from the moment a point is laid (the hot glow sits on top of it while it cools), holds,\r\n// then fades, all within weldHotMs+weldBeadMs.\r\nexport const beadAlpha=age=>{const K=KNOBS,total=K.weldHotMs+K.weldBeadMs;return weldBeadAlpha(age,0,total,(K.weldHotMs+K.weldBeadHold*K.weldBeadMs)/total);};\r\nconst HOT_BUCKETS=8,BEAD_BUCKETS=8;\r\nfunction clipMetalSurface(S,ctx){\r\n if(!S.fall)return;ctx.beginPath();ctx.rect(0,0,S.texW,S.texH);\r\n S.fall.poly.forEach(([u,v],i)=>i?ctx.lineTo(u*S.texW,v*S.texH):ctx.moveTo(u*S.texW,v*S.texH));ctx.closePath();ctx.clip('evenodd');\r\n}\r\n// Hot trail, bucketed by age: each bucket is ONE path, so overlapping segment caps don't stack into a\r\n// row of brighter dots (the old per-segment strokes did). Blurred halo pass, then a crisp core pass:\r\n// white-hot, cooling yellow->orange->red. The selected tint only leans the outer halo a little.\r\nfunction weldRenderGlow(S,now,scale){\r\n const {ctx}=S.glow,w=S.texW,h=S.texH,K=KNOBS;\r\n const coreW=K.weldTrailWidthPx*scale,haloW=K.weldTrailHaloPx*scale,sparkW=K.sparkWidthPx*scale;\r\n ctx.clearRect(0,0,w,h);\r\n ctx.save();clipMetalSurface(S,ctx);ctx.globalCompositeOperation='lighter';ctx.lineCap='round';ctx.lineJoin='round';\r\n for(let pass=0;pass<2;pass++){\r\n  ctx.filter=pass?'none':`blur(${(haloW*.35).toFixed(1)}px)`;ctx.lineWidth=pass?coreW:haloW;\r\n  for(let b=0;b<HOT_BUCKETS;b++){\r\n   let any=false;ctx.beginPath();\r\n   for(const p of S.weld){\r\n    const age=now-p.t;if(!p.prev||age>=K.weldHotMs||Math.min(HOT_BUCKETS-1,(age/K.weldHotMs*HOT_BUCKETS)|0)!==b)continue;\r\n    ctx.moveTo(p.prev.u*w,p.prev.v*h);ctx.lineTo(p.u*w,p.v*h);any=true;\r\n   }\r\n   if(!any)continue;\r\n   const f=(b+.5)/HOT_BUCKETS,af=f<K.weldHotHold?1:1-(f-K.weldHotHold)/(1-K.weldHotHold);\r\n   ctx.strokeStyle=pass?heatRGBA(f,af):haloRGBA(f,S.tint,K.tintHaloMix,af*.55);ctx.stroke();\r\n  }\r\n }\r\n ctx.filter='none';\r\n // Sparks: thin incandescent streaks (white -> yellow -> orange as they cool), each with a faint warm\r\n // sheath, drawn back along their velocity so a fast one reads as a streak and a slow one as a dot.\r\n for(const s of S.sparks){\r\n  const f=Math.min(1,(now-s.born)/1000/s.life),x0=s.x-s.vx*K.sparkStreakS,y0=s.y-s.vy*K.sparkStreakS,a=1-f*f;\r\n  ctx.lineWidth=sparkW*(2.2-f);ctx.strokeStyle=heatRGBA(.35+f*.5,a*.14);ctx.beginPath();ctx.moveTo(x0,y0);ctx.lineTo(s.x,s.y);ctx.stroke();\r\n  ctx.lineWidth=sparkW*(1-.55*f);ctx.strokeStyle=heatRGBA(f*.85,a);ctx.beginPath();ctx.moveTo(x0,y0);ctx.lineTo(s.x,s.y);ctx.stroke();\r\n }\r\n // The torch itself at each finger: a white-hot core in a blue-white bloom that fades to a warm edge,\r\n // flickering, and swollen for a moment right after touch-down (the press flare).\r\n for(const d of S.drag.values()){\r\n  if(S.fall&&pointInPolygon(d.u,d.v,S.fall.poly))continue;\r\n  const k=Math.max(0,1-(now-(d.t0||0))/K.torchFlareMs),fl=.88+Math.random()*.24,cx=d.u*w,cy=d.v*h;\r\n  const R=K.torchBloomPx*scale*(1+(K.torchFlareScale-1)*k)*fl,core=K.torchCorePx*scale*(1+.6*k)*fl;\r\n  const g=ctx.createRadialGradient(cx,cy,0,cx,cy,R);\r\n  g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(Math.min(.5,core/R),'rgba(225,238,255,.95)');\r\n  g.addColorStop(Math.min(.6,core/R*2.2),'rgba(140,180,255,.45)');g.addColorStop(.75,'rgba(255,160,60,.16)');g.addColorStop(1,'rgba(255,110,30,0)');\r\n  ctx.fillStyle=g;ctx.fillRect(cx-R,cy-R,2*R,2*R);\r\n  ctx.fillStyle='#fff';ctx.beginPath();ctx.arc(cx,cy,core*.55,0,TAU);ctx.fill();\r\n }\r\n ctx.restore();S.glow.texture.needsUpdate=true;\r\n}\r\n// The weld bead: one continuous seam, not a row of dots. Per alpha bucket the seam is one path stroked\r\n// several times: a blue heat-tint band, a straw band inside it, a drop shadow, the steel bead body, a\r\n// lighter crown and a thin specular ridge (upper-left lit, like the rest of the board). Then the\r\n// \"stack of dimes\": overlapping ripple arcs every weldRipplePx along the seam, convex in the travel\r\n// direction, each a dark crease with a bright lip behind it.\r\nconst BEAD_STROKES=[ // [width: multiple of the bead half-width R, or a heat band; offset in R; style]\r\n ['halo',0,'rgba(58,78,170,.26)'],['wide',0,'rgba(110,96,150,.22)'],['mid',0,'rgba(196,156,72,.36)'],[2,.3,'rgba(6,5,4,.8)'],\r\n [2,0,'rgb(118,120,126)'],[1.25,-.08,'rgb(162,164,170)'],[.36,-.36,'rgba(250,250,255,.8)'],\r\n];\r\nfunction weldRenderPaint(S,now,scale){\r\n const {ctx}=S.paint,w=S.texW,h=S.texH,K=KNOBS,R=K.weldBeadRadiusPx*scale,halo=K.weldHaloRadiusPx*scale;\r\n const sp=K.weldRipplePx*scale/w,rr=R*.82; // ripple spacing in face widths, ripple radius in canvas px\r\n ctx.clearRect(0,0,w,h);\r\n ctx.save();clipMetalSurface(S,ctx);ctx.lineCap='round';ctx.lineJoin='round';\r\n for(let b=1;b<=BEAD_BUCKETS;b++){\r\n  let any=false;ctx.beginPath();\r\n  for(const p of S.weld){if(Math.ceil(beadAlpha(now-p.t)*BEAD_BUCKETS)!==b)continue;const q=p.prev||p;ctx.moveTo(q.u*w,q.v*h);ctx.lineTo(p.u*w,p.v*h);any=true;}\r\n  if(!any)continue;\r\n  ctx.globalAlpha=b/BEAD_BUCKETS;\r\n  for(const [wd,off,style] of BEAD_STROKES){\r\n   ctx.lineWidth=wd==='halo'?2*halo:wd==='wide'?R*.6+halo*1.4:wd==='mid'?R*1.2+halo*.8:wd*R;ctx.strokeStyle=style;\r\n   if(off){ctx.translate(off*R,off*R);ctx.stroke();ctx.setTransform(1,0,0,1,0,0);}else ctx.stroke();\r\n  }\r\n  // ripples: dark crease, then the bright lip just behind it\r\n  for(let pass=0;pass<2;pass++){\r\n   ctx.beginPath();\r\n   for(const p of S.weld){\r\n    if(!p.prev||Math.ceil(beadAlpha(now-p.t)*BEAD_BUCKETS)!==b)continue;\r\n    const q=p.prev,dx=(p.u-q.u)*w,dy=(p.v-q.v)*h,len=p.d-q.d;if(len<=0)continue;\r\n    const th=Math.atan2(dy,dx),back=pass?rr*.55:rr*.35,ox=Math.cos(th)*back,oy=Math.sin(th)*back;\r\n    for(let k=Math.ceil(q.d/sp);k*sp<=p.d;k++){\r\n     const t=(k*sp-q.d)/len,cx=q.u*w+dx*t-ox,cy=q.v*h+dy*t-oy;\r\n     ctx.moveTo(cx+Math.cos(th-1.15)*rr,cy+Math.sin(th-1.15)*rr);ctx.arc(cx,cy,rr,th-1.15,th+1.15);\r\n    }\r\n   }\r\n   ctx.lineWidth=(pass?.7:.9)*scale;ctx.strokeStyle=pass?'rgba(232,234,242,.55)':'rgba(34,34,40,.75)';ctx.stroke();\r\n  }\r\n }\r\n ctx.restore();S.paint.texture.needsUpdate=true;\r\n}\r\n// Redraws (clears+repaints) both canvases every frame while anything welding is live (or a finger is\r\n// down: the torch core flickers), and one frame past that to wipe the last remnants, then leaves them\r\n// alone — see the sleep note on step().\r\nfunction stepWeld(S,dt,now){\r\n const K=KNOBS,scale=S.scale=pxScale(S),grav=K.sparkGravityPx*scale;\r\n let n=0;for(const s of S.sparks)if((now-s.born)/1000<s.life)S.sparks[n++]=stepSpark(s,dt,grav,K.sparkBounceKeep);\r\n S.sparks.length=n; // compacted in place: no per-frame array\r\n for(const d of S.drag.values())if(now-(d.lastSparkT||0)>K.sparkIdleMs){d.lastSparkT=now;spawnSparks(S,d.u,d.v,K.sparkIdleCount);}\r\n let k=0;while(k<S.weld.length&&now-S.weld[k].t>K.weldHotMs+K.weldBeadMs)k++;if(k)S.weld.splice(0,k);\r\n const active=S.sparks.length>0||S.weld.length>0||S.drag.size>0;\r\n if(active||S.weldActive){weldRenderGlow(S,now,scale);weldRenderPaint(S,now,scale);}\r\n S.weldActive=active;\r\n return active;\r\n}\r\n\r\n// Lock progress: arc length a finger actually covers along ONE path (it sticks to it while within .03 face-widths), so\r\n// taps, reverse traces and crossing other shapes never jump the lock. `d` is the finger's {pi,f} memory.\r\nexport function trackFinger(paths,closed,face,prog,d,u,v){\r\n const w=face.w;let hit=null,pi=d.pi;\r\n if(pi!=null){hit=pointOnPath([paths[pi]],face,u,v);if(hit.distance>=.03*w)hit=null;}\r\n if(!hit){hit=pointOnPath(paths,face,u,v);if(!hit||hit.distance>=.03*w){d.pi=d.f=null;d.lu=u;d.lv=v;return;}pi=hit.pathIndex;}\r\n const pts=paths[pi].points,f=pathProgress(pts,face,hit.segment,hit.u,hit.v);\r\n let pf=pi===d.pi?d.f:null; // switching paths (e.g. leaving a shared corner): start from where the last sample sat on this one\r\n if(pf==null&&d.lu!=null){const h0=pointOnPath([paths[pi]],face,d.lu,d.lv);if(h0.distance<.03*w)pf=pathProgress(pts,face,h0.segment,h0.u,h0.v);}\r\n if(pf!=null&&d.lu!=null){\r\n  let df=Math.abs(f-pf);if(closed[pi])df=Math.min(df,1-df);\r\n  let L=0;for(let i=1;i<pts.length;i++)L+=Math.hypot((pts[i][0]-pts[i-1][0])*face.w,(pts[i][1]-pts[i-1][1])*face.h);\r\n  // progress can't outrun the finger: a fast swipe on a long straight line still counts, a teleport doesn't\r\n  if(df*L<=1.5*Math.hypot((u-d.lu)*face.w,(v-d.lv)*face.h)+.01*w){prog[pi]=Math.min(1,prog[pi]+df);if(prog[pi]>=.94)prog[pi]=1;}\r\n }\r\n d.pi=pi;d.f=f;d.lu=u;d.lv=v;\r\n}\r\nfunction progress(i,p){if(S&&i in S.prog){S.prog[i]=Math.max(0,Math.min(1,p));S.wake?.();}}\r\nfunction press(id,u,v){\r\n if(!S||S.fall&&pointInPolygon(u,v,S.fall.poly))return;\r\n const skip=S.fall?.gearIndices;\r\n S.drag.set(id,{gi:hitGear(S.gears,S.face,u,v,skip),moved:false,u,v,t0:performance.now(),pi:null,f:null});\r\n weldPushPoint(S,id,u,v);spawnSparks(S,u,v,KNOBS.sparkPressCount);\r\n}\r\nfunction move(id,u,v,pu,pv){\r\n if(!S)return;\r\n const d=S.drag.get(id);if(!d)return;\r\n if(Math.hypot(u-pu,v-pv)>MOVE_EPS)d.moved=true;\r\n d.u=u;d.v=v;\r\n if(S.fall&&pointInPolygon(u,v,S.fall.poly)){S.weldHeads.delete(id);return;}\r\n trackFinger(S.paths,S.closed,S.face,S.prog,d,u,v);\r\n // Acquire the rail on every move: starting between gears still turns the\r\n // entire train. Projection onto its tangent preserves forward/reverse swipes.\r\n const rail=pointOnPath(S.paths,S.face,u,v);\r\n if(rail&&rail.distance<.075*S.face.w){\r\n  const train=S.trains[rail.pathIndex],gi=train.reduce((a,b)=>Math.hypot(S.gears[a].u-u,(S.gears[a].v-v)*S.aspect)<Math.hypot(S.gears[b].u-u,(S.gears[b].v-v)*S.aspect)?a:b);\r\n  if(!S.fall?.gearIndices.has(gi)){d.gi=gi;applyTorque(S.gears,train[0],signedRailImpulse(rail,u-pu,v-pv,S.face,S.gears[gi].r,.8));}\r\n }\r\n // Pipes don't need a drag origin to react — any pipe the finger passes near this event gets a kick,\r\n // not only the one (if any) under the initial press.\r\n const vx=(u-pu)*S.face.w,vy=-(v-pv)*S.face.h;\r\n for(const part of S.parts){\r\n  if(part.kind!=='pipe'||S.fall?.pivots.has(part.pivot))continue;\r\n  const dxp=(u-part.u)*S.face.w,dyp=(v-part.v)*S.face.h,lim=(part.r+KNOBS.wiggleMargin)*S.face.w;\r\n  if(Math.hypot(dxp,dyp)<lim)part.omega+=wiggleKick(vx,vy,part.rot,KNOBS.wiggleKick);\r\n }\r\n weldPushPoint(S,id,u,v);\r\n spawnSparks(S,u,v,Math.min(KNOBS.sparkMoveMax,Math.round(Math.hypot(u-pu,v-pv)/KNOBS.sparkPerFrac)));\r\n}\r\nfunction release(id){\r\n if(!S)return;\r\n const d=S.drag.get(id);if(!d)return;\r\n if(!d.moved){\r\n  if(d.gi>=0)applyTorque(S.gears,d.gi,TAP_IMPULSE);\r\n  else{\r\n   const pipes=S.parts.filter(p=>p.kind==='pipe'&&!S.fall?.pivots.has(p.pivot));\r\n   const pi=nearestPipe(pipes,S.face,d.u,d.v,KNOBS.wiggleMargin);\r\n   if(pi>=0)pipes[pi].omega+=KNOBS.wiggleTapKick;\r\n  }\r\n }\r\n weldRelease(S,id,d.u,d.v);\r\n S.drag.delete(id);\r\n}\r\n// Moves the procedural mechanism pieces: bolts by trace progress, rods/weights/dial by their driving gear's angle.\r\nfunction poseMech(S,now){\r\n const fw=S.face.w,G=S.gears,sp=S.spin?Math.min(1,(now-S.spin.t0)/S.spin.ms):0,dialA=G[S.dial.drives].angle+TAU*sp*sp*(3-2*sp);\r\n for(const p of S.parts){\r\n  const m=p.instance?.matrix;\r\n  if(p.kind==='bolt')m.makeScale(.014*fw,2*p.throw*fw,.008*fw).setPosition(0,p.side*boltOut(S.prog[p.pathIndex],p.station,S.boltN[p.pathIndex])*p.throw*1.1*fw,0);\r\n  else if(p.kind==='rod')m.makeScale(p.Lr,p.rr,p.rr).setPosition(p.hb-p.Lr/2+pistonExt(p.stroke,G[p.drives].angle)*fw,0,0);\r\n  else if(p.kind==='weight')m.makeScale(p.size,p.size,p.size).setPosition(p.travel*fw*(.5+.5*Math.sin(G[p.drives].angle)),0,0);\r\n  else if(p.kind==='dial')p.pivot.rotation.z=dialA;\r\n  else if(p.kind==='notch')p.pivot.rotation.z=p.rot+dialA;\r\n }\r\n if(sp>=1)S.spin=null;\r\n}\r\nfunction step(dt,now){\r\n if(!S)return false;\r\n // Live media query (not just at init) and the motor runs before the rest check, so a sleeping loop can never\r\n // be left with the hubs \"at rest\" while the motor is on.\r\n const idling=idleSpin(S.gears,dt,KNOBS.hubIdleAccel,S.motion?S.motion.matches:S.reducedMotion);\r\n const moving=stepTrain(S.gears,dt)||idling;\r\n S.gears.forEach((g,gi)=>{if(S.gearPivots[gi])S.gearPivots[gi].rotation.z=g.angle%TAU;});\r\n let rootOmega=0;\r\n for(const g of S.gears)if(g.drives==null&&Math.abs(g.omega)>Math.abs(rootOmega))rootOmega=g.omega;\r\n if(Math.abs(rootOmega)>REST)S.valveDir=Math.sign(rootOmega);\r\n // ponytail: valves used to idle forever on their own VALVE_IDLE baseline, which alone kept the board\r\n // rendering every frame at rest; now they only turn while the train or a finger is actually doing\r\n // something (they've never had a canonical rest angle, so freezing wherever they stop is fine). The\r\n // five big hub gears (HUBS) still idle-spin nonstop even at rest (their own small idleDir motor,\r\n // applied below) — unlike everything else here, that keeps the board rendering permanently while\r\n // shown, except under prefers-reduced-motion, where the motor is off and it can settle/sleep too.\r\n const valveActive=Math.abs(rootOmega)>REST||S.drag.size>0;\r\n let wobbling=false,lit=false;\r\n for(const part of S.parts){\r\n  const falling=S.fall?.pivots.has(part.pivot.parent);\r\n  if(part.kind==='valve'){\r\n   if(valveActive){part.angle=valveAngle(part.angle,dt,part.dir,S.valveDir,rootOmega);part.pivot.rotation.z=part.rot+part.angle;}\r\n  }else if(part.kind==='pipe'&&!falling){\r\n   const r=wiggleStep(part.angle,part.omega,dt,KNOBS.wiggleFreqHz,KNOBS.wiggleDamping,KNOBS.wiggleMaxAngle);\r\n   part.angle=r.angle;part.omega=r.omega;\r\n   if(Math.abs(part.angle)<KNOBS.wiggleRestAngle&&Math.abs(part.omega)<KNOBS.wiggleRestOmega){\r\n    if(part.angle!==0||part.pivot.position.z!==part.z0){part.angle=0;part.omega=0;part.pivot.rotation.z=part.rot;part.pivot.position.z=part.z0;}\r\n   }else{\r\n    wobbling=true;\r\n    part.pivot.rotation.z=part.rot+part.angle;\r\n    part.pivot.position.z=part.z0+Math.abs(part.angle)/KNOBS.wiggleMaxAngle*KNOBS.wiggleBob*S.face.w;\r\n   }\r\n  }else if((part.kind==='light'||part.kind==='lamp')&&!falling){\r\n   let near=false;\r\n   for(const d of S.drag.values()){const dx=(d.u-part.u)*S.face.w,dy=(d.v-part.v)*S.face.h;if(Math.hypot(dx,dy)<KNOBS.lightRadius*S.face.w){near=true;break;}}\r\n   if(near)part.nearUntil=now+KNOBS.lightHoldMs;\r\n   const target=now<part.nearUntil||now<part.flashUntil||(part.pathIndex!=null&&lampLit(S.prog[part.pathIndex],part.station,S.lampN[part.pathIndex]))?1:0;\r\n   part.level=lightLevel(part.level,target,dt,KNOBS.lightRampMs,KNOBS.lightFadeMs);\r\n   const reduced=S.motion?S.motion.matches:S.reducedMotion;\r\n   if(part.kind==='lamp'){\r\n    const {mesh,index}=part.instance,fl=!reduced&&part.level>.95?1+Math.sin(now*.02+part.phase)*KNOBS.lightFlicker:1,L=part.level,k=part.r0*(.4+.6*L);\r\n   lampOn.set(selectedTint||LIGHT_COLOR).lerp(LAMP_CORE,.6); // warm white-amber core, 40% tint\r\n   part.instance.matrix.makeScale(k,k,k);mesh.setColorAt(index,lampTmp.copy(LAMP_OFF).lerp(lampOn,L).multiplyScalar(fl));mesh.instanceColor.needsUpdate=true;\r\n   // halos (additive: colour*level carries the fade); matrices are pivot-local, updateGearInstances composes them\r\n   for(const [h,sc,gain,z] of [[part.glow,5*k,1,part.r0*.9],[part.cast,10*part.r0*L,.28,-.068*S.face.w]]){h.instance.matrix.makeScale(sc,sc,sc).setPosition(0,0,z);h.instance.mesh.setColorAt(h.instance.index,lampTmp.set(selectedTint||LIGHT_COLOR).multiplyScalar(gain*L*fl*fl));h.instance.mesh.instanceColor.needsUpdate=true;}\r\n   }else{\r\n    const flicker=!reduced&&part.level>.95?Math.sin(now*.02+part.phase)*KNOBS.lightFlicker*KNOBS.lightOn:0;\r\n    part.mat.emissiveIntensity=Math.max(0,KNOBS.lightOff+(KNOBS.lightOn-KNOBS.lightOff)*part.level+flicker);\r\n   }\r\n   if(part.level!==target||(!reduced&&part.level>.001))lit=true; // under reduced motion a settled lit lamp lets the loop sleep\r\n  }\r\n }\r\n const f=S.fall,t=f?Math.min(1,(now-f.t0)/Math.max(1,f.ms)):1,e=t*t;\r\n if(f)for(const [p,z0] of f.pivots){p.position.z=z0-f.dist*e;p.position.y=p.userData.restY-f.dist*.3*e;p.rotation.x=FALL_TILT*e;p.visible=t<1;}\r\n poseMech(S,now);\r\n updateGearInstances(S);\r\n const weldActive=stepWeld(S,dt,now);\r\n // Sleeps (returns false) once no gear is moving, no pipe is wobbling, no light is lit, no weld spark/\r\n // trail is live and no cut animation is running — the board (portal-board-glb.mjs) stops driving rAF\r\n // at that point. In practice that's \"never\" while reducedMotion is off: the hub gears' idle motor\r\n // above keeps `moving` true forever.\r\n return moving||wobbling||lit||weldActive||t<1||!!S.spin;\r\n}\r\n// Release existing opaque assemblies at their manufactured scale.\r\n// Completion: the released outline's rings fill, lamps flash, the dial turns once (300 ms), then the panels fall.\r\n// heal() inside that window cancels the release (cutToken) and resolves the promise early.\r\nfunction cut(poly,color,ms=FALL_MS){\r\n if(!S)return Promise.resolve();\r\n const s=S,spin=s.motion?.matches?0:300,now=performance.now();heal();\r\n const ring=[...poly,poly[0]],done=s.paths.map((p,i)=>p.points.every(([u,v])=>pointOnPath([{points:ring}],s.face,u,v).distance<.01*s.face.w)?i:-1).filter(i=>i>=0);\r\n for(const i of done)s.prog[i]=1;\r\n for(const p of s.parts)if(p.kind==='light'||p.kind==='lamp')p.flashUntil=now+900;\r\n s.spin=spin?{t0:now,ms:spin}:null;const token=s.cutToken={};s.wake?.();\r\n return new Promise(res=>{s.cutResolve=res;s.cutTimer=setTimeout(()=>{\r\n  s.cutResolve=null;if(S!==s||s.cutToken!==token)return res();s.cutToken=null;\r\n  const p=s.prog.slice(),fell=fall(poly,color,ms);s.prog.splice(0,p.length,...p);\r\n  const t=performance.now();for(const q of s.parts)if(q.kind==='light'||q.kind==='lamp')q.flashUntil=t+600;\r\n  res(fell);},spin);});\r\n}\r\nfunction fall(poly,color,ms=FALL_MS){\r\n if(!S)return Promise.resolve();heal();S.weld.length=0;S.weldHeads.clear();S.sparks.length=0;S.drag.clear();\r\n // Erase both surface layers immediately, including the torch, before a plate\r\n // departs. Future points in the aperture are rejected by weldPushPoint.\r\n for(const l of S.layers){l.ctx.clearRect(0,0,S.texW,S.texH);l.texture.needsUpdate=true;}\r\n const pivots=new Map(),gearIndices=new Set();\r\n for(const panel of S.panels)if(pointInPolygon(...panel.center,poly)){\r\n  panel.group.userData.restY=panel.group.position.y;pivots.set(panel.group,panel.group.position.z);panel.gearIndices.forEach(i=>gearIndices.add(i));\r\n }\r\n if(S.motion?.matches)ms=0;\r\n let resolve;const done=new Promise(r=>{resolve=r;}),fall={pivots,gearIndices,poly,t0:performance.now(),ms,dist:Math.max(S.face.w,S.face.h)*.35,resolve,timer:null};\r\n fall.connections=S.gears.map(g=>({drives:g.drives,driveRatio:g.driveRatio,idleDir:g.idleDir}));\r\n S.gears.forEach((g,i)=>{if(g.drives!=null&&gearIndices.has(i)!==gearIndices.has(g.drives)){g.drives=null;delete g.driveRatio;}if(gearIndices.has(i))g.idleDir=0;});\r\n S.fall=fall;fall.timer=setTimeout(()=>{for(const p of pivots.keys())p.visible=false;if(S?.fall===fall)updateGearInstances(S);fall.resolve?.();fall.resolve=null;S?.wake?.();},Math.max(0,ms));S.wake?.();return done;\r\n}\r\nfunction heal(){\r\n if(!S)return;\r\n S.drag.clear();S.weld.length=0;S.weldHeads.clear();S.sparks.length=0;S.weldActive=false;S.prog.fill(0);S.spin=null;\r\n if(S.cutToken){clearTimeout(S.cutTimer);S.cutToken=null;S.cutResolve?.();S.cutResolve=null;}\r\n for(const p of S.parts)if(p.kind==='light'||p.kind==='lamp')p.flashUntil=-Infinity;\r\n for(const l of S.layers){l.ctx.clearRect(0,0,S.texW,S.texH);l.texture.needsUpdate=true;}\r\n if(!S.fall){S.wake?.();return;}\r\n clearTimeout(S.fall.timer);S.fall.resolve?.();\r\n for(const [p,z0] of S.fall.pivots){p.position.z=z0;p.position.y=p.userData.restY;p.rotation.x=0;p.visible=true;}\r\n S.gears.forEach((g,i)=>{Object.assign(g,S.fall.connections[i]);g.omega=0;});\r\n S.fall=null;\r\n updateGearInstances(S);\r\n S.wake?.();\r\n}\r\nfunction dispose(){\r\n if(!S)return;heal();\r\n for(const l of S.layers){l.mesh.removeFromParent();l.mesh.geometry.dispose();l.mesh.material.dispose();l.texture.dispose();}\r\n for(const part of S.parts)part.pivot.removeFromParent();\r\n for(const panel of S.panels)panel.geometry.dispose();S.panelBatch.dispose();for(const b of S.batches||[])b.dispose?.();\r\n S.owned.removeFromParent();S.railTexture.dispose();S.backplateMaterial.dispose();S.bearingGeometry.dispose();S.railGeometry.dispose();S.shaftGeometry.dispose();for(const g of S.mechGeos)g.dispose();\r\n for(const m of new Set(S.mats))m.dispose();\r\n S=null;\r\n}\r\n\r\n// R7: the weld trail alone in 2D, for the flat board (no gears, pipes or lights without WebGL): its own state.\r\nexport function cogsWeld(){\r\n let S=null;\r\n return {\r\n  init({paint,glow,face,wake}){S={face,aspect:face.h/face.w,paint,glow,texW:paint.canvas.width,texH:paint.canvas.height,drag:new Map(),sparks:[],weld:[],weldHeads:new Map(),weldActive:false,wake,tint:selectedTint};weldTrace=S;},\r\n  setTint(hex,selected=true){setCogsTint(hex,selected);},\r\n  press(id,u,v){S.drag.set(id,{u,v,t0:performance.now()});weldPushPoint(S,id,u,v);spawnSparks(S,u,v,KNOBS.sparkPressCount);},\r\n  move(id,u,v,pu,pv){const d=S.drag.get(id);if(d){d.u=u;d.v=v;}weldPushPoint(S,id,u,v);spawnSparks(S,u,v,Math.min(KNOBS.sparkMoveMax,Math.round(Math.hypot(u-pu,v-pv)/KNOBS.sparkPerFrac)));},\r\n  release(id,u,v){S.drag.delete(id);weldRelease(S,id,u,v);},\r\n  step:(dt,now)=>stepWeld(S,dt,now),\r\n  dispose(){if(S===weldTrace)weldTrace=null;S=null;},\r\n };\r\n}\r\n\r\ncogsWeld.metal=true; // the flat poster tints as anodized metal, not a flat wash (portal-board.mjs paintStill)\r\n\r\nexport const cogs={\r\n id:'cogs',shadows:true,asset:'/pod/worlds/boards/cogs/door.glb',flip:false,background:'#161310',\r\n guide:null,frame:DEFAULT_FRAME,ink:false, // the weld trail replaces the shared ink line\r\n presectioned:true,progress,init,press,move,release,step,cut,heal,dispose,setTint:setCogsTint,setBackplateTint:setCogsBackplateTint,doorTone,tintTarget:'trace',trace2d:cogsWeld,\r\n};\r\n","modules/portal/portal-board-glb.mjs":"// Generic 3D tablet board for the portal home: loads a decimated GLB board (Tripo -> Blender), fits\r\n// its front face to the host, and lets an effect module paint two canvas textures onto it (finger\r\n// dent + paint/glow layers injected into the GLB's own material via onBeforeCompile). Same public\r\n// interface as createQuiltBoard so portal.mjs can swap boards freely. AGPL-3.0-or-later.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/addons/libs/meshopt_decoder.module.js';\r\nimport {SHAPES,fromFrame} from './portal-shapes.mjs';\r\nimport {createPortalCutMask} from './portal-cut.mjs';\r\n\r\nexport const GLB={inset:.06,texSize:1024,sleepMs:1500,dent:10,dentRadius:48,margin:.02};\r\n\r\n// --- Pure helpers (no THREE dependency) -------------------------------------------------------\r\nconst AXIS={x:[1,0,0],y:[0,1,0],z:[0,0,1]};\r\nconst cross=(a,b)=>[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]];\r\n// size={x,y,z} bbox dims -> row-major 3x3 rotation [ex,ey,ez] sending the thinnest local axis to\r\n// world Z and the longer of the remaining two to world Y. ex=ey×ez keeps it a proper rotation\r\n// (det +1), never a mirror.\r\nexport function orientMatrix(size){\r\n const axes=['x','y','z'],thin=axes.reduce((a,b)=>size[a]<=size[b]?a:b);\r\n const others=axes.filter(a=>a!==thin),long=size[others[0]]>=size[others[1]]?others[0]:others[1];\r\n const ez=AXIS[thin],ey=AXIS[long];\r\n return [cross(ey,ez),ey,ez];\r\n}\r\n// rect={left,top,width,height} client px -> [u,v] on the face, u right, v down, corners at 0/1.\r\nexport function faceUV(rect,clientX,clientY){return [(clientX-rect.left)/rect.width,(clientY-rect.top)/rect.height];}\r\n// Even-odd ray cast: is (u,v) inside the closed polygon poly=[[u,v],...]? A repeated closing point is harmless.\r\nexport function pointInPolygon(u,v,poly){\r\n let inside=false;\r\n for(let i=0,j=poly.length-1;i<poly.length;j=i++){const [xi,yi]=poly[i],[xj,yj]=poly[j];if((yi>v)!==(yj>v)&&u<(xj-xi)*(v-yi)/(yj-yi)+xi)inside=!inside;}\r\n return inside;\r\n}\r\n// Splits a triangle index by where each triangle's centroid lands: positions is flat xyz, toUv(x,y)->[u,v]\r\n// maps it to face coords; triangles inside poly go to `cut`, the rest to `keep` (both flat index arrays).\r\nexport function splitIndexByPolygon(positions,index,toUv,poly){\r\n const keep=[],cut=[],us=poly.map(p=>p[0]),vs=poly.map(p=>p[1]),u0=Math.min(...us),u1=Math.max(...us),v0=Math.min(...vs),v1=Math.max(...vs);\r\n for(let t=0;t<index.length;t+=3){\r\n  const a=3*index[t],b=3*index[t+1],c=3*index[t+2],[u,v]=toUv((positions[a]+positions[b]+positions[c])/3,(positions[a+1]+positions[b+1]+positions[c+1])/3);\r\n  (u>=u0&&u<=u1&&v>=v0&&v<=v1&&pointInPolygon(u,v,poly)?cut:keep).push(index[t],index[t+1],index[t+2]);\r\n }\r\n return {keep,cut};\r\n}\r\n\r\n// --- Cut-away pieces (shared with the quilt board) ----------------------------------------------\r\nconst TILT=35*Math.PI/180;\r\n// Transparent twin of a board material for a falling piece. clone() drops the instance-assigned\r\n// onBeforeCompile/customProgramCacheKey, so the paint/glow/rim injection is copied across by hand.\r\nexport function pieceMaterial(src){const m=src.clone();m.onBeforeCompile=src.onBeforeCompile;m.customProgramCacheKey=src.customProgramCacheKey;m.transparent=true;return m;}\r\n// Drops pieces [{pivot,material,drop()}] (pivot at the piece centroid): each sinks `fall` along -z into\r\n// the board, tilts about one random in-plane axis up to ~35°, shrinks to .6 and fades out, ease-in over\r\n// ms; then drop() removes it and `done` resolves. Timed by setTimeout, not rAF, so a paused or\r\n// backgrounded board can't stall the portal; the board's tick calls pose(now) while `live`.\r\nexport function fallPieces(pieces,fall,ms){\r\n const a=Math.random()*Math.PI*2,axis=new THREE.Vector3(Math.cos(a),Math.sin(a),0),t0=performance.now(),z0=pieces.map(p=>p.pivot.position.z);\r\n const f={live:true,pose(now){const t=Math.min(1,(now-t0)/Math.max(1,ms)),e=t*t;pieces.forEach((p,i)=>{p.pivot.position.z=z0[i]-fall*e;p.pivot.quaternion.setFromAxisAngle(axis,TILT*e);p.pivot.scale.setScalar(1-.4*e);p.material.opacity=1-e;});}};\r\n f.pose(t0);\r\n f.done=new Promise(resolve=>{f.end=()=>{if(!f.live)return;f.live=false;pieces.forEach(p=>p.drop());resolve();};if(ms>0)setTimeout(f.end,ms);else f.end();});\r\n return f;\r\n}\r\n// A piece's geometry rides on the door's own vertex buffers; detach them before dispose() or WebGL\r\n// frees buffers the door is still drawing with.\r\nfunction sharedGeometry(src,index){const g=new THREE.BufferGeometry();for(const k in src.attributes)g.setAttribute(k,src.attributes[k]);g.setIndex(index?.isBufferAttribute?index.clone():new THREE.BufferAttribute(index.slice?.()||index,1));return g;}\r\nfunction disposeShared(g){for(const k in g.attributes)g.deleteAttribute(k);g.dispose();}\r\n\r\n// --- Shader injection defaults -----------------------------------------------------------------\r\nconst DEFAULT_DISPLACE=`for(int di=0;di<8;di++){if(di>=uTouchCount)break;vec4 t=uTouch[di];vec2 tp=uFaceMin+vec2(t.x,1.0-t.y)*uFaceSize;float dd=distance(position.xy,tp);if(dd<uDentRadius){float f=1.0-dd/uDentRadius;transformed.z-=uDent*f*f*t.z;}}`;\r\n\r\nfunction makeCanvasTex(w,h){\r\n const canvas=document.createElement('canvas');canvas.width=w;canvas.height=h;\r\n const texture=new THREE.CanvasTexture(canvas);texture.flipY=false;texture.colorSpace=THREE.SRGBColorSpace; // canvas row 0 = board top = vPlanar.y 0; canvas colours are sRGB (sampler returns linear)\r\n return {canvas,ctx:canvas.getContext('2d'),texture};\r\n}\r\n// The eight traceable shapes, stitched onto the paint layer so every board shows them (skip 'line':\r\n// it shares geometry with 'cross').\r\n// Where the eight shapes sit on the face: the board's own carving when it has one (effect.frame,\r\n// x0/y0/x1/y1 UV fractions — or the older effect.pattern left/top/right/bottom some boards still set),\r\n// else an even inset. Traces are normalised against it (see toFrame/fromFrame in portal-shapes.mjs).\r\nexport const frameOf=(effect,knobs)=>effect.frame||(effect.pattern&&{x0:effect.pattern.left,y0:effect.pattern.top,x1:effect.pattern.right,y1:effect.pattern.bottom})||{x0:knobs.inset,y0:knobs.inset,x1:1-knobs.inset,y1:1-knobs.inset};\r\n// Each hint is drawn twice — a wide blurred halo, then a thin core — so it glows softly instead of reading as a hard wire.\r\nfunction drawGuides(paint,texW,texH,knobs,effect){\r\n if(effect.guide===null)return;\r\n const g=effect.guide||{color:'#fff',alpha:.5,width:4},scale=knobs.texSize/1024,F=frameOf(effect,knobs);\r\n const ctx=paint.ctx;ctx.save();ctx.strokeStyle=g.color;ctx.lineCap='round';ctx.lineJoin='round';\r\n const trace=()=>{for(const [id,polys] of Object.entries(SHAPES)){\r\n  if(id==='line')continue;\r\n  for(const poly of polys){ctx.beginPath();poly.points.forEach(([x,y],i)=>{const [fx,fy]=fromFrame(x,y,F),cx=fx*texW,cy=fy*texH;i?ctx.lineTo(cx,cy):ctx.moveTo(cx,cy);});ctx.stroke();}\r\n }};\r\n ctx.filter=`blur(${6*scale}px)`;ctx.globalAlpha=g.alpha*.6;ctx.lineWidth=g.width*2*scale;trace();\r\n ctx.filter='none';ctx.globalAlpha=g.alpha;ctx.lineWidth=g.width*.5*scale;trace();\r\n ctx.restore();paint.texture.needsUpdate=true;\r\n}\r\n\r\nexport async function createGlbBoard(host,{effect,knobs=GLB}={}){\r\n // Outside the try: a build that fails part-way must still stop its frame loop, release its context and undo its effect.\r\n let renderer=null,inited=false,frame=0,disposed=false,awakeUntil=0,last=0,frameMs=0,cutting=null;\r\n try{\r\n const scene=new THREE.Scene(),camera=new THREE.PerspectiveCamera(42,1,1,20000);\r\n scene.add(new THREE.HemisphereLight(0xfff4e6,0x3a2f40,1.1));\r\n const sun=new THREE.DirectionalLight(0xfff0dc,2.4);sun.position.set(-.7,.55,.45);scene.add(sun);\r\n\r\n // Load, orient (thin axis -> +Z, long axis -> +Y), centre, and bake it all into the geometry.\r\n // effect.build (Pond, R21): a procedural board instead of a GLB, same orient/fit/cut path.\r\n const gltf=effect.build?{scene:effect.build(THREE)}:await new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).loadAsync(effect.asset);\r\n gltf.scene.updateMatrixWorld(true);\r\n const meshes=[];gltf.scene.traverse(o=>{if(o.isMesh)meshes.push(o);});\r\n if(!meshes.length)throw new Error('portal-board-glb: no mesh in '+effect.asset);\r\n // The boards ship quantized (gltfpack: interleaved, normalized int16 positions). cut() reads position.array as flat float\r\n // xyz, so it found no triangle inside the shape and the wormhole never showed through a GLB board (R7); and applyMatrix4\r\n // would clamp a normalized attribute to [-1,1]. Plain float positions first.\r\n const rawGeoms=meshes.map(m=>{const g=m.geometry.clone(),p=g.attributes.position;g.setAttribute('position',new THREE.Float32BufferAttribute(Float32Array.from({length:p.count*3},(_,i)=>p.getComponent(i/3|0,i%3)),3));g.applyMatrix4(m.matrixWorld);return g;});\r\n const rawBox=new THREE.Box3();for(const g of rawGeoms){g.computeBoundingBox();rawBox.union(g.boundingBox);}\r\n const size=rawBox.getSize(new THREE.Vector3());\r\n const rot=orientMatrix({x:size.x,y:size.y,z:size.z});\r\n const rotM=new THREE.Matrix4().set(rot[0][0],rot[0][1],rot[0][2],0, rot[1][0],rot[1][1],rot[1][2],0, rot[2][0],rot[2][1],rot[2][2],0, 0,0,0,1);\r\n if(effect.flip)rotM.premultiply(new THREE.Matrix4().makeRotationY(Math.PI));\r\n const geoms=rawGeoms.map(g=>{g.applyMatrix4(rotM);return g;});\r\n const box=new THREE.Box3();for(const g of geoms){g.computeBoundingBox();box.union(g.boundingBox);}\r\n const center=box.getCenter(new THREE.Vector3());\r\n for(const g of geoms)g.translate(-center.x,-center.y,-center.z);\r\n const fw=box.max.x-box.min.x,fh=box.max.y-box.min.y,halfDepth=(box.max.z-box.min.z)/2,faceMin={x:-fw/2,y:-fh/2};\r\n\r\n const group=new THREE.Group();\r\n const meshObjs=geoms.map((g,i)=>{const mm=new THREE.Mesh(g,meshes[i].material);group.add(mm);return mm;});\r\n scene.add(group);\r\n const preservedAspect=true; // The mechanical cap fills the unused space; artwork retains its aspect.\r\n\r\n const texW=knobs.texSize,texH=Math.max(1,Math.round(knobs.texSize*fh/fw));\r\n // rim: the cut edge's neon outline, on its own half-res layer because effects clear `glow` every frame.\r\n const paint=makeCanvasTex(texW,texH),glow=makeCanvasTex(texW,texH),rim=makeCanvasTex(texW>>1,texH>>1);\r\n // Guides are drawn after layout and effect.init, which may discover a painted frame.\r\n\r\n const touchArr=Array.from({length:8},()=>new THREE.Vector4(0,0,0,0));\r\n const uBoardTint={value:new THREE.Color('#b026ff')};\r\n\r\n const uniforms={\r\n  uTime:{value:0},uTouch:{value:touchArr},uTouchCount:{value:0},\r\n  uPaint:{value:paint.texture},uGlow:{value:glow.texture},uRim:{value:rim.texture},uGlowStrength:{value:1.2},\r\n  uFaceMin:{value:new THREE.Vector2(faceMin.x,faceMin.y)},uFaceSize:{value:new THREE.Vector2(fw,fh)},\r\n  uDent:{value:knobs.dent},uDentRadius:{value:knobs.dentRadius},\r\n  uBoardTint,\r\n  ...(effect.uniforms||{}),\r\n };\r\n const portalCutMask={value:null};\r\n function setupMaterial(mat){\r\n  const portalCutSide={value:0};mat.userData.portalCutSideUniform=portalCutSide;\r\n  mat.customProgramCacheKey=()=>effect.id;\r\n  mat.onBeforeCompile=shader=>{\r\n   Object.assign(shader.uniforms,uniforms,{uPortalCutMask:portalCutMask,uPortalCutSide:portalCutSide});\r\n   // uniformDecls go to both stages; vertexDecls/fragmentDecls to one only, so a big uniform array (jelly's trail) never\r\n   // takes a second stage's uniform space on a phone GPU.\r\n   const decl=`varying vec2 vPlanar;\\nvarying vec2 vPortalCutUv;\\nuniform sampler2D uPortalCutMask;\\nuniform float uPortalCutSide;\\nuniform float uTime;\\nuniform vec4 uTouch[8];\\nuniform int uTouchCount;\\nuniform vec2 uFaceMin;\\nuniform vec2 uFaceSize;\\nuniform sampler2D uPaint;\\nuniform sampler2D uGlow;\\nuniform sampler2D uRim;\\nuniform float uGlowStrength;\\nuniform float uDent;\\nuniform float uDentRadius;\\nuniform vec3 uBoardTint;\\n${effect.uniformDecls||''}\\n`;\r\n   shader.vertexShader=decl+(effect.vertexDecls||'')+shader.vertexShader.replace('#include <begin_vertex>',\r\n    `#include <begin_vertex>\\nvec2 planar=(position.xy-uFaceMin)/uFaceSize;planar.y=1.0-planar.y;vPlanar=planar;vPortalCutUv=planar;\\n${effect.vertexDisplace||DEFAULT_DISPLACE}`);\r\n   shader.fragmentShader=decl+(effect.fragmentDecls||'')+shader.fragmentShader\r\n    .replace('#include <map_fragment>','#include <map_fragment>\\nfloat portalCutCoverage=1.0;if(abs(uPortalCutSide)>.5){portalCutCoverage=texture2D(uPortalCutMask,vPortalCutUv).r;if(uPortalCutSide>.5&&portalCutCoverage<.5)discard;if(uPortalCutSide<-.5&&portalCutCoverage>=.5)discard;}\\nfloat lum=dot(diffuseColor.rgb,vec3(.2126,.7152,.0722));diffuseColor.rgb=mix(diffuseColor.rgb,vec3(lum)*uBoardTint,1.0);vec4 pnt=texture2D(uPaint,vPlanar);diffuseColor.rgb=mix(diffuseColor.rgb,pnt.rgb,pnt.a);')\r\n\r\n    .replace('#include <emissivemap_fragment>','#include <emissivemap_fragment>\\nvec4 glo=texture2D(uGlow,vPlanar),cutRim=texture2D(uRim,vPlanar);totalEmissiveRadiance+=glo.rgb*glo.a*uGlowStrength+cutRim.rgb*cutRim.a*2.0;\\n'+(effect.fragment||'')); // optional effect GLSL: runs before lighting, may edit diffuseColor/roughnessFactor/normal (view space)/totalEmissiveRadiance\r\n  };\r\n  mat.needsUpdate=true;\r\n }\r\n\r\n let width=1,height=1,faceRect={left:0,top:0,width:1,height:1},scaleFit=1,viewFrame=frameOf(effect,knobs);\r\n function computeFit(){\r\n  width=Math.max(1,host.clientWidth);height=Math.max(1,host.clientHeight);\r\n  scaleFit=Math.min(width/fw,height/fh);\r\n  uniforms.uDent.value=knobs.dent/scaleFit;uniforms.uDentRadius.value=knobs.dentRadius/scaleFit;\r\n  faceRect={left:(width-fw*scaleFit)/2,top:height-fh*scaleFit,width:fw*scaleFit,height:fh*scaleFit};\r\n  group.scale.setScalar(scaleFit);group.position.set(width/2,-(faceRect.top+faceRect.height/2),-scaleFit*halfDepth);\r\n  viewFrame=frameOf(effect,knobs);\r\n  for(const k in faceRect)host.style.setProperty('--face-'+k,faceRect[k]+'px');\r\n }\r\n computeFit();\r\n const toWorld=(u,v)=>[faceRect.left+u*faceRect.width,-(faceRect.top+v*faceRect.height)];\r\n await effect.init?.({THREE,scene,mesh:meshObjs.length===1?meshObjs[0]:group,material:meshObjs[0].material,uniforms,paint,glow,face:{w:fw,h:fh},toWorld,faceZ:0,wake});inited=true;\r\n computeFit();drawGuides(paint,texW,texH,knobs,{...effect,frame:viewFrame});\r\n meshObjs.forEach(m=>setupMaterial(m.material));\r\n // Transparent twins for cut pieces, drawn once at load (opacity 0, over the door itself: invisible) so\r\n // the first cut doesn't hitch on a shader compile.\r\n const pieceMats=new Map(),warm=[];\r\n meshObjs.forEach(o=>{if(!pieceMats.has(o.material)){const m=pieceMaterial(o.material),sourceCompile=m.onBeforeCompile,side={value:0};m.userData.portalCutSideUniform=side;m.onBeforeCompile=function(shader,renderer){sourceCompile.call(this,shader,renderer);shader.uniforms.uPortalCutMask=portalCutMask;shader.uniforms.uPortalCutSide=side;};m.opacity=0;pieceMats.set(o.material,m);warm.push(new THREE.Mesh(o.geometry,m));}});\r\n warm.forEach(w=>group.add(w));\r\n\r\n // The renderer (and its WebGL context) only now, once every download is in: a stalled one never holds a context.\r\n // Transparent canvas: the solid board colour is #portalHome's background (portal.mjs reads board.background),\r\n // so the neon glass can sit between the two and show only through a cut.\r\n renderer=new THREE.WebGLRenderer({antialias:true,alpha:true,powerPreference:'low-power'});\r\n renderer.setPixelRatio(Math.min(devicePixelRatio||1,2));renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.setClearColor(0x000000,0);\r\n if(effect.shadows){renderer.shadowMap.enabled=true;renderer.shadowMap.type=THREE.PCFShadowMap;sun.castShadow=true;sun.shadow.normalBias=.02;sun.shadow.bias=-.0004;}\r\n const canvas=renderer.domElement;canvas.className='portal-board-canvas';canvas.setAttribute('aria-hidden','true');canvas.style.cssText='display:block;width:100%;height:100%';host.append(canvas);\r\n const startTime=performance.now(),pointers=new Map();\r\n function layout(){\r\n  computeFit();\r\n  if(effect.guide!==null){paint.ctx.clearRect(0,0,texW,texH);drawGuides(paint,texW,texH,knobs,{...effect,frame:viewFrame});}\r\n  renderer.setSize(width,height,false);camera.aspect=width/height;\r\n  camera.position.set(width/2,-height/2,(height/2)/Math.tan(THREE.MathUtils.degToRad(camera.fov/2)));camera.near=camera.position.z/10;camera.far=camera.position.z*10;camera.lookAt(width/2,-height/2,0);camera.updateProjectionMatrix();\r\n  if(effect.shadows){ // tight ortho shadow camera on the board face (world units are px; group sits at the face centre)\r\n   const cx=width/2,cy=-(faceRect.top+faceRect.height/2),R=Math.hypot(faceRect.width,faceRect.height)/2,d=Math.max(width,height)*2,sc=sun.shadow.camera,ms=Math.min(width,height)<500?512:1024;\r\n   sun.target.position.set(cx,cy,0);sun.target.updateMatrixWorld();sun.position.set(cx-.7*d,cy+.55*d,.45*d);\r\n   Object.assign(sc,{left:-R,right:R,top:R,bottom:-R,near:d*.2,far:d*2});sc.updateProjectionMatrix();\r\n   if(sun.shadow.mapSize.x!==ms){sun.shadow.mapSize.set(ms,ms);sun.shadow.map?.dispose();sun.shadow.map=null;}\r\n  }\r\n  effect.resize?.({w:fw,h:fh});wake();\r\n }\r\n function wake(){awakeUntil=performance.now()+knobs.sleepMs;if(!frame&&!disposed&&renderer){last=performance.now();frame=requestAnimationFrame(tick);}}\r\n function fillTouches(now){\r\n  let i=0;for(const p of pointers.values()){if(i>=8)break;touchArr[i].set(p.u,p.v,1,(now-p.t0)/1000);i++;}\r\n  for(;i<8;i++)touchArr[i].set(0,0,0,0);\r\n  uniforms.uTouchCount.value=Math.min(pointers.size,8);\r\n }\r\n function tick(now){\r\n  frame=0;if(disposed)return;\r\n  const dt=Math.min(1/30,Math.max(1/240,(now-last)/1000));last=now;\r\n  let animating=false;\r\n  if(!document.hidden){\r\n   const t0=performance.now();\r\n   uniforms.uTime.value=(now-startTime)/1000;fillTouches(now);\r\n   if(effect.step)animating=!!effect.step(dt,now);\r\n   if(cutting?.fall.live){cutting.fall.pose(now);animating=true;}\r\n   renderer.render(scene,camera);\r\n   frameMs=frameMs*.9+(performance.now()-t0)*.1;\r\n  }\r\n  if(pointers.size||now<awakeUntil||animating)frame=requestAnimationFrame(tick);\r\n }\r\n function faceRectClient(){const hostBox=host.getBoundingClientRect();const sx=hostBox.width/width,sy=hostBox.height/height;return {left:hostBox.left+faceRect.left*sx,top:hostBox.top+faceRect.top*sy,width:faceRect.width*sx,height:faceRect.height*sy};}\r\n const observer=new ResizeObserver(layout);observer.observe(host);layout();renderer.render(scene,camera);warm.forEach(w=>group.remove(w));\r\n\r\n // Cut-away: every triangle of the board's own mesh(es) whose centroid is inside polyUv (face coords, v down;\r\n // planar uv exactly as the shader computes it) moves into a falling piece that shares the mesh's vertex\r\n // buffers; the mesh keeps the rest, so the board has a real hole. Effect-owned meshes/props are never\r\n // sliced here: an effect takes part through its optional cut(polyUv,color)/heal() hooks (pointInPolygon is exported for them).\r\n const toUv=(x,y)=>[(x-faceMin.x)/fw,1-(y-faceMin.y)/fh];\r\n function drawRim(poly,color){\r\n  const {ctx:c,canvas:{width:w,height:h}}=rim,s=w/512;c.clearRect(0,0,w,h);c.save();c.lineJoin='round';\r\n  c.beginPath();poly.forEach(([u,v],i)=>i?c.lineTo(u*w,v*h):c.moveTo(u*w,v*h));c.closePath();\r\n  c.strokeStyle=color;c.shadowColor=color;c.shadowBlur=14*s;c.lineWidth=7*s;c.stroke();c.shadowBlur=0;c.strokeStyle='#fff';c.lineWidth=2*s;c.stroke();\r\n  c.restore();rim.texture.needsUpdate=true;\r\n }\r\n function cut(polyUv,color='#ffffff',ms=1100){\r\n  heal();\r\n  // Mechanical modules already have seams and thickness. Release those assemblies\r\n  // through their own lifecycle rather than manufacturing a sliced door mesh.\r\n  if(effect.presectioned){\r\n   const done=effect.cut?.(polyUv,color,ms);\r\n   wake();\r\n   return Promise.resolve(done);\r\n  }\r\n  const pieces=[];portalCutMask.value=createPortalCutMask(polyUv);\r\n  for(const mesh of meshObjs){\r\n   const g=mesh.geometry,p=g.attributes.position.array,index=g.index||(g.setIndex([...Array(g.attributes.position.count).keys()]),g.index);\r\n   // Both copies retain every boundary triangle; complementary face-space discards produce the exact cut.\r\n   let u=0,v=0;for(const point of polyUv){u+=point[0];v+=point[1];}u/=polyUv.length;v/=polyUv.length;\r\n   const cx=faceMin.x+u*fw,cy=faceMin.y+(1-v)*fh,cz=0;\r\n   const pg=sharedGeometry(g,index.array),material=pieceMats.get(mesh.material)||pieceMats.set(mesh.material,pieceMaterial(mesh.material)).get(mesh.material);\r\n   mesh.material.userData.portalCutSideUniform.value=-1;material.userData.portalCutSideUniform.value=1;\r\n   const piece=new THREE.Mesh(pg,material),pivot=new THREE.Group();piece.frustumCulled=false;piece.position.set(-cx,-cy,-cz);pivot.position.set(cx,cy,cz);pivot.add(piece);mesh.add(pivot);\r\n   pieces.push({pivot,material,drop(){pivot.removeFromParent();disposeShared(pg);}});\r\n  }\r\n  drawRim(polyUv,color);\r\n  cutting={fall:fallPieces(pieces,Math.max(fw,fh)*.35,ms)};effect.cut?.(polyUv,color);wake();\r\n  return cutting.fall.done;\r\n }\r\n function heal(){\r\n  effect.healSecret?.(); // ice secret (L3): restore the shattered crystal (cut() heals first too)\r\n  if(effect.presectioned){effect.heal?.();if(!disposed&&renderer)renderer.render(scene,camera);return;}\r\n  if(!cutting)return;\r\n  cutting.fall.end();for(const mesh of meshObjs){mesh.material.userData.portalCutSideUniform.value=0;const piece=pieceMats.get(mesh.material);if(piece?.userData.portalCutSideUniform)piece.userData.portalCutSideUniform.value=0;}portalCutMask.value?.dispose();portalCutMask.value=null;cutting=null;effect.heal?.();\r\n  rim.ctx.clearRect(0,0,rim.canvas.width,rim.canvas.height);rim.texture.needsUpdate=true;\r\n  if(preservedAspect)computeFit();\r\n  if(!disposed)renderer.render(scene,camera); // healed frame on the canvas now, even while paused\r\n }\r\n const claimed=new Map();\r\n return {\r\n  canvas,\r\n  glContext:renderer.getContext(),\r\n  background:effect.background||'#17111e',\r\n  faceRect:faceRectClient,\r\n  cut,heal,\r\n  patternRect(){const hostBox=host.getBoundingClientRect(),F=viewFrame,sx=hostBox.width/width,sy=hostBox.height/height;if(preservedAspect)return {left:hostBox.left+(faceRect.left+faceRect.width*F.x0)*sx,top:hostBox.top+(faceRect.top+faceRect.height*F.y0)*sy,width:faceRect.width*(F.x1-F.x0)*sx,height:faceRect.height*(F.y1-F.y0)*sy};return {left:hostBox.left+hostBox.width*F.x0,top:hostBox.top+hostBox.height*F.y0,width:hostBox.width*(F.x1-F.x0),height:hostBox.height*(F.y1-F.y0)};},\r\n  setTint(hex,selected=true){\r\n   if(!/^#[0-9a-f]{6}$/i.test(hex))return;\r\n   if(effect.id==='grass'||effect.presectioned)effect.setTint?.(hex,selected);\r\n   else{uBoardTint.value.set(effect.doorTone?effect.doorTone(hex):hex);effect.setTint?.(hex,selected);}\r\n\r\n   wake();\r\n  },\r\n  setBackplateTint(hex){\r\n   if(!/^#[0-9a-f]{6}$/i.test(hex))return;\r\n   uBoardTint.value.set(hex);effect.setBackplateTint?.(hex);wake();\r\n  },\r\n  press(id,clientX,clientY){\r\n   const painted=faceRectClient();\r\n   const [u,v]=faceUV(painted,clientX,clientY),cu=Math.min(1,Math.max(0,u)),cv=Math.min(1,Math.max(0,v)),ex=pointers.get(id);\r\n   if(ex){effect.move?.(id,cu,cv,ex.u,ex.v);ex.u=cu;ex.v=cv;}\r\n   else{pointers.set(id,{u:cu,v:cv,t0:performance.now()});effect.press?.(id,cu,cv);}\r\n   wake();\r\n  },\r\n  // claims(id): asked BEFORE effect.release forgets the pointer; a released id keeps its answer until portal reads it once.\r\n  claims(id){if(claimed.has(id)){const c=claimed.get(id);claimed.delete(id);return c;}return !!effect.claims?.(id);},\r\n  release(id){const p=pointers.get(id);if(p){claimed.set(id,!!effect.claims?.(id));effect.release?.(id,p.u,p.v);pointers.delete(id);}wake();},\r\n  frameMs:()=>frameMs,\r\n  ink:effect.ink, // false: the effect draws its own trace trail, portal.mjs skips its glowing ink line\r\n  pause(){for(const [id,p] of pointers)effect.release?.(id,p.u,p.v);pointers.clear();cancelAnimationFrame(frame);frame=0;},\r\n  resume:wake,\r\n  dispose(){\r\n   cutting?.fall.end();portalCutMask.value?.dispose();portalCutMask.value=null;disposed=true;cancelAnimationFrame(frame);observer.disconnect();effect.dispose?.();pieceMats.forEach(m=>m.dispose());rim.texture.dispose();\r\n   group.traverse(n=>{n.geometry?.dispose();if(n.material)for(const mat of [n.material].flat()){for(const v of Object.values(mat))if(v?.isTexture)v.dispose();mat.dispose();}});\r\n   paint.texture.dispose();glow.texture.dispose();renderer.dispose();renderer.forceContextLoss();canvas.remove();\r\n  },\r\n };\r\n }catch(error){disposed=true;cancelAnimationFrame(frame);if(inited)effect.dispose?.();renderer?.dispose();renderer?.forceContextLoss();renderer?.domElement.remove();throw error;}\r\n}\r\n","modules/portal/portal-board-grass.mjs":"// grass board effect for portal-board-glb.mjs: a dense instanced blade lawn covers the block (hiding its\r\n// quilted diamonds so the traced-shape guides are the only pattern), blades sway in the wind, part\r\n// around a touch and spring back on release; mixed-colour flower clusters plant along a drag, pop in,\r\n// and fade away 7 s later; cut()/heal() open the lawn over the board's cut-out. JS drives touch/flower\r\n// state; all blade motion is GLSL. Vault secret (Achievement Vault L5): a tiny purple alien cap in one corner, a buried UFO in the\r\n// opposite one; a flower line drawn between them walks the alien to the ship, which cracks the ground open on a metal plate. AGPL-3.0-or-later.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/addons/libs/meshopt_decoder.module.js';\r\nimport {pointInPolygon} from './portal-board-glb.mjs';\r\n\r\nconst FLOWER_ASSET='/pod/worlds/boards/flower.glb',FLOWER_CAP=120,PLANT_STEP_PX=36,POP_MS=300,SPRING_LIFE=1.2;\r\nconst FADE_MS=7000; // Ian: everything returns to normal after 7 s (2026-09-22)\r\nconst FADE_OUT_MS=700,FLOWER_FRAC=.075,CLUSTER_FRAC=.04,FLOWER_TILT=1.2,FLOWER_LIFT=.02;\r\nconst BLADES=7000,BLADE_W=.015,BLOCK_EXPOSURE=.75,FIELD_INSET=.025,GUIDE_GLOW='0.6'; // inset keeps edge tufts from overhanging far\r\n\r\n// --- Pure helpers (no THREE dependency) -------------------------------------------------------\r\nconst clamp01=x=>Math.min(1,Math.max(0,x));\r\nexport const popScale=(ageMs,durMs=POP_MS)=>{const t=clamp01(ageMs/durMs);return 1-(1-t)*(1-t);};\r\n// 1 while the flower lives, then eases in to 0 over outMs (shrink + fade), 0 after.\r\nexport const fadeLife=(ageMs,liveMs=FADE_MS,outMs=FADE_OUT_MS)=>{const t=clamp01((ageMs-liveMs)/outMs);return 1-t*t;};\r\nexport const springActive=(ageS,maxS=SPRING_LIFE)=>ageS>=0&&ageS<maxS;\r\nexport const plantStep=(lx,ly,x,y,stepPx=PLANT_STEP_PX)=>Math.hypot(x-lx,y-ly)>=stepPx;\r\n// HSL triples: red, orange, yellow, pink, magenta, violet, white, sky blue.\r\nexport const FLOWER_HSL=[[0,.8,.52],[.07,.9,.55],[.14,.95,.56],[.94,.75,.74],[.86,.75,.52],[.76,.6,.6],[0,0,.95],[.56,.75,.66]];\r\nconst GREENS=[[.29,.6,.42],[.31,.62,.38],[.33,.55,.34],[.36,.5,.32],[.40,.45,.30]],YELLOW_GREENS=[[.22,.7,.48],[.24,.65,.52]];\r\nconst pickHSL=(set,rand,dh,ds,dl)=>{const [h,s,l]=set[Math.min(set.length-1,Math.floor(rand()*set.length))];return [(h+(rand()-.5)*dh+1)%1,clamp01(s+(rand()-.5)*ds),clamp01(l+(rand()-.5)*dl)];};\r\nexport const flowerHSL=(rand=Math.random)=>pickHSL(FLOWER_HSL,rand,0,.16,.12);\r\nexport const bladeHSL=(rand=Math.random)=>pickHSL(rand()<.06?YELLOW_GREENS:GREENS,rand,.02,.1,.08);\r\n// n uniform random points in a disc of radius maxR.\r\n// Indices of the roots (flat u0,v0,u1,v1,... face coords, v down) inside the closed polygon poly.\r\nexport const rootsInside=(uv,poly)=>{const out=[];for(let i=0;i<uv.length;i+=2)if(pointInPolygon(uv[i],uv[i+1],poly))out.push(i/2);return out;};\r\nexport const clusterOffsets=(n,maxR,rand=Math.random)=>Array.from({length:n},()=>{const a=rand()*Math.PI*2,r=maxR*Math.sqrt(rand());return [Math.cos(a)*r,Math.sin(a)*r];});\r\n\r\n// Block shader: copies DEFAULT_DISPLACE's finger-dent loop (vertexDisplace replaces it), adds a slab\r\n// bend away from the touch, a damped echo per released touch (uSpring ring buffer, filled in release())\r\n// and a faint breeze gated by uBreeze (off under reduced motion). Mostly hidden under the blades now.\r\nconst VERTEX_DISPLACE=\r\n`for(int di=0;di<8;di++){if(di>=uTouchCount)break;vec4 t=uTouch[di];vec2 tp=uFaceMin+vec2(t.x,1.0-t.y)*uFaceSize;float dd=distance(position.xy,tp);if(dd<uDentRadius){float f=1.0-dd/uDentRadius;transformed.z-=uDent*f*f*t.z;}}\r\nfloat tipW=smoothstep(-uHalfDepth,uHalfDepth,position.z);\r\nfloat bendR=uFaceSize.x*0.22,bendA=uFaceSize.x*0.06;\r\nvec2 bend=vec2(0.0);\r\nfor(int bi=0;bi<8;bi++){if(bi>=uTouchCount)break;vec4 t=uTouch[bi];vec2 tp=uFaceMin+vec2(t.x,1.0-t.y)*uFaceSize;vec2 d=position.xy-tp;float dist=length(d);if(dist<bendR&&dist>1e-4){float f=1.0-dist/bendR;bend+=normalize(d)*bendA*f*f;}}\r\nfor(int si=0;si<6;si++){vec4 s=uSpring[si];if(s.w<=0.0)continue;float age=uTime-s.z;if(age<0.0||age>1.2)continue;vec2 sp=uFaceMin+vec2(s.x,1.0-s.y)*uFaceSize;vec2 d=position.xy-sp;float dist=length(d);if(dist<bendR&&dist>1e-4){float f=1.0-dist/bendR,wave=exp(-age*4.0)*sin(age*14.0);bend+=normalize(d)*bendA*f*f*wave*s.w;}}\r\ntransformed.xy+=bend*tipW;\r\ntransformed.xy+=vec2(uBreeze*uFaceSize.x*0.004*sin(uTime*1.3+planar.x*9.0))*tipW;`;\r\n\r\n// Blade shader (replaces project_vertex; blade-local y is 0 at the root, 1 at the tip). Works in the\r\n// board group's local space: sway on a travelling wave, bend away from each held touch (eased in over\r\n// 120 ms), a damped cos spring-back from the release pose (the whole blade leans, so the lawn parts; wind moves tips). vPlanar is\r\n// the rest position on the face so the guide paint sits on the lawn like the block's own paint did.\r\nconst BLADE_VDECL='varying vec2 vPlanar;\\nuniform float uTime;\\nuniform vec4 uTouch[8];\\nuniform int uTouchCount;\\nuniform vec2 uFaceMin;\\nuniform vec2 uFaceSize;\\nuniform vec4 uSpring[6];\\nuniform float uBreeze;\\n';\r\nconst BLADE_VERTEX=\r\n`vec4 bw=instanceMatrix*vec4(transformed,1.0);\r\nvec2 root=instanceMatrix[3].xy,rp=(bw.xy-uFaceMin)/uFaceSize,pr=(root-uFaceMin)/uFaceSize;vPlanar=vec2(rp.x,1.0-rp.y);\r\nfloat tw=position.y*position.y,bendR=uFaceSize.x*0.2,bendA=uFaceSize.x*0.1;\r\nvec2 bend=vec2(0.0);\r\nfor(int i=0;i<8;i++){if(i>=uTouchCount)break;vec4 t=uTouch[i];vec2 d=root-(uFaceMin+vec2(t.x,1.0-t.y)*uFaceSize);float dist=length(d);if(dist<bendR&&dist>1e-4){float f=1.0-dist/bendR;bend+=d/dist*bendA*f*f*t.z*smoothstep(0.0,0.12,t.w);}}\r\nfor(int i=0;i<6;i++){vec4 s=uSpring[i];float age=uTime-s.z;if(s.w<=0.0||age<0.0||age>1.2)continue;vec2 d=root-(uFaceMin+vec2(s.x,1.0-s.y)*uFaceSize);float dist=length(d);if(dist<bendR&&dist>1e-4){float f=1.0-dist/bendR;bend+=d/dist*bendA*f*f*exp(-age*4.0)*cos(age*14.0)*s.w;}}\r\nvec2 wind=vec2(0.9,0.4)*uBreeze*uFaceSize.x*0.006*sin(uTime*1.6+pr.x*9.0+pr.y*5.0);\r\nbw.xy+=bend*position.y+wind*tw;bw.z-=length(bend)*0.5*position.y;\r\nvec4 mvPosition=modelViewMatrix*bw;gl_Position=projectionMatrix*mvPosition;`;\r\n\r\n// --- Vault secret: pure reducer (face-width units: x=u, y=v/aspect; state is replaced, never mutated) ---\r\nexport const SECRET={speed:1.5,lag:2,gapMs:3000,boardMs:700,flyMs:1400,crackMs:1700,splitMs:1900,shipR:.14,reach:1.5};\r\nconst d2=(a,b)=>Math.hypot(a[0]-b[0],a[1]-b[1]);\r\nexport const grassSecretInit=(start,ship,step)=>({phase:'idle',start,ship,step,path:[],len:0,pos:0,drawing:null,wait:0,last:null,t0:0,claimed:false,resets:0,added:0});\r\nexport const secretPoint=(path,d)=>{for(let i=1;i<path.length;i++){const l=d2(path[i-1],path[i]);if(d<=l||i===path.length-1){const k=l?Math.min(1,d/l):1,a=path[i-1],b=path[i];return [a[0]+(b[0]-a[0])*k,a[1]+(b[1]-a[1])*k];}d-=l;}return path[0]||[0,0];};\r\nconst NEXT={board:['boardMs','fly'],fly:['flyMs','crack'],crack:['crackMs','split'],split:['splitMs','done']};\r\n// ev: {t:'down'|'move',id,x,y} | {t:'up',id} | {t:'tick'} | {t:'reset'}. A stroke starts within reach of the alien and each point\r\n// must land 1..1.5 steps from the line's tip (a longer jump plants nothing: that is the gap).\r\nexport function grassSecret(s,ev,now){\r\n const C=SECRET,tip=s.path[s.path.length-1],p=[ev.x,ev.y];\r\n if(ev.t==='down'){\r\n  if(s.phase==='idle'&&d2(p,s.start)<=C.reach*s.step)return grassSecret({...s,phase:'walk',path:[s.start],len:0,pos:0,drawing:ev.id,wait:0,last:now,claimed:false},{...ev,t:'move'},now);\r\n  if(s.phase==='walk'&&s.drawing==null&&d2(p,tip)<=C.reach*s.step)return {...s,drawing:ev.id,wait:0};\r\n  return s;\r\n }\r\n if(ev.t==='move'){\r\n  if(s.phase!=='walk'||s.drawing!==ev.id)return s;\r\n  const d=d2(p,tip);if(d<s.step||d>C.reach*s.step)return s;\r\n  return {...s,path:[...s.path,p],len:s.len+d,wait:0,added:s.added+1};\r\n }\r\n if(ev.t==='up')return s.drawing===ev.id?{...s,drawing:null}:s;\r\n if(ev.t==='reset')return {...grassSecretInit(s.start,s.ship,s.step),resets:s.resets+1};\r\n if(ev.t!=='tick')return s;\r\n const dt=s.last==null?0:Math.min(.1,Math.max(0,(now-s.last)/1000)),n={...s,last:now};\r\n if(s.phase==='walk'){\r\n  const near=tip&&d2(tip,s.ship)<=C.shipR,limit=s.drawing!=null&&!near?Math.max(0,s.len-C.lag*s.step):s.len;\r\n  if(n.pos<limit-1e-9){n.pos=Math.min(limit,n.pos+C.speed*dt);n.wait=0;if(n.pos>0)n.claimed=true;}\r\n  else if(near&&s.len>0){n.phase='board';n.t0=now;}\r\n  else{n.wait+=dt*1000;if(n.wait>C.gapMs)return {...grassSecretInit(s.start,s.ship,s.step),last:now,resets:s.resets+1,added:s.added};}\r\n }else if(NEXT[s.phase]&&now-s.t0>=C[NEXT[s.phase][0]]){n.phase=NEXT[s.phase][1];n.t0=now;}\r\n return n;\r\n}\r\n// Pointer ids the board must not also treat as a tap/shape: the line stroke once the alien walks, everything after boarding.\r\nexport const grassSecretClaims=(s,id)=>s.phase!=='idle'&&(s.phase==='walk'?s.drawing===id&&s.claimed:true);\r\n// Jagged angular bolt a->b (face-width units), endpoints exact, offsets taper to 0 at the ends and alternate sides so it stays simple.\r\nexport function crackPath(a,b,rand=Math.random,n=12){\r\n const dx=b[0]-a[0],dy=b[1]-a[1],L=Math.hypot(dx,dy),nx=-dy/L,ny=dx/L,out=[a];\r\n for(let i=1;i<n;i++){const t=(i+(rand()-.5)*.5)/n,o=(i%2?1:-1)*L*(.03+rand()*.045)*Math.sin(Math.PI*t);out.push([a[0]+dx*t+nx*o,a[1]+dy*t+ny*o]);}\r\n return [...out,b];\r\n}\r\n\r\nlet S=null; // per-instance state; a single portal board is ever active at once (see portal-board-ice.mjs)\r\n\r\n// Tapered, slightly drooping strip: 4 rows x 2 verts = 3 quads; vertex colour darkens toward the root.\r\nfunction bladeGeometry(T){\r\n const pos=[],col=[],idx=[];\r\n [[0,.5],[.35,.42],[.7,.28],[1,.06]].forEach(([y,w],i)=>{const z=-.22*y*y,c=.55+.45*y;pos.push(-w,y,z,w,y,z);col.push(c,c,c,c,c,c);if(i)idx.push(2*i-2,2*i-1,2*i+1,2*i-2,2*i+1,2*i);});\r\n const g=new T.BufferGeometry();g.setAttribute('position',new T.Float32BufferAttribute(pos,3));g.setAttribute('color',new T.Float32BufferAttribute(col,3));g.setIndex(idx);g.computeVertexNormals();\r\n return g;\r\n}\r\n// One InstancedMesh under the board group (instance matrices in its local space, so it scales with the\r\n// board). rootUV keeps each blade's root in face coords for cut(); rest is the matrix buffer heal() restores.\r\nfunction makeBlades(T,uniforms,group){\r\n const fw=uniforms.uFaceSize.value.x,fh=uniforms.uFaceSize.value.y,min=uniforms.uFaceMin.value,z0=uniforms.uHalfDepth.value-fw*.004;\r\n const cols=Math.round(Math.sqrt(BLADES*fw/fh)),rows=Math.round(BLADES/cols);\r\n const mat=new T.MeshLambertMaterial({vertexColors:true,side:T.DoubleSide});\r\n mat.customProgramCacheKey=()=>'grass-blades';\r\n mat.onBeforeCompile=sh=>{\r\n  for(const k of ['uTime','uTouch','uTouchCount','uFaceMin','uFaceSize','uSpring','uBreeze','uPaint'])sh.uniforms[k]=uniforms[k];\r\n  sh.vertexShader=BLADE_VDECL+sh.vertexShader.replace('#include <project_vertex>',BLADE_VERTEX);\r\n  sh.fragmentShader='varying vec2 vPlanar;\\nuniform sampler2D uPaint;\\n'+sh.fragmentShader\r\n   .replace('#include <normal_fragment_begin>','#include <normal_fragment_begin>\\nnormal=normalize(mix(normal,vec3(0.0,0.0,1.0),0.5));') // half the lawn normal: calmer shading\r\n   .replace('#include <color_fragment>','#include <color_fragment>\\nvec4 pnt=texture2D(uPaint,vPlanar);diffuseColor.rgb=mix(diffuseColor.rgb,pnt.rgb,pnt.a);')\r\n   .replace('#include <emissivemap_fragment>','#include <emissivemap_fragment>\\ntotalEmissiveRadiance+=pnt.rgb*pnt.a*'+GUIDE_GLOW+';'); // faint glow so the guides read over the busy blades\r\n };\r\n const im=new T.InstancedMesh(bladeGeometry(T),mat,cols*rows),rootUV=new Float32Array(cols*rows*2),o=new T.Object3D(),c=new T.Color();\r\n im.frustumCulled=false;\r\n for(let r=0,i=0;r<rows;r++)for(let q=0;q<cols;q++,i++){\r\n  const h=fw*(.04+Math.random()*.03),lean=.6+Math.random()*.62; // 4-7% of face width, 34-70 deg off the normal\r\n  const fx=FIELD_INSET+(q+Math.random())/cols*(1-2*FIELD_INSET),fy=FIELD_INSET+(r+Math.random())/rows*(1-2*FIELD_INSET);\r\n  o.position.set(min.x+fx*fw,min.y+fy*fh,z0);\r\n  o.rotation.set(Math.PI/2-lean,Math.random()-.5,Math.random()*Math.PI*2,'ZXY');\r\n  o.scale.set(fw*BLADE_W*(.8+Math.random()*.45),h,h);\r\n  o.updateMatrix();im.setMatrixAt(i,o.matrix);im.setColorAt(i,c.setHSL(...bladeHSL()));\r\n  rootUV[2*i]=fx;rootUV[2*i+1]=1-fy;\r\n }\r\n group.add(im);\r\n return {im,rootUV,rest:im.instanceMatrix.array.slice(),cutIdx:null};\r\n}\r\n\r\nasync function init({THREE:T,scene,mesh,material,uniforms,toWorld,faceZ,wake}){\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const box=new T.Box3();\r\n for(const m of mesh.isMesh?[mesh]:mesh.children.filter(c=>c.isMesh)){if(!m.geometry.boundingBox)m.geometry.computeBoundingBox();box.union(m.geometry.boundingBox);}\r\n uniforms.uHalfDepth.value=box.max.z; // slab is centred by the generic board: front face sits at +max.z\r\n uniforms.uBreeze.value=reduced?0:1;\r\n uniforms.uSpring.value.forEach(v=>v.set(0,0,0,0));\r\n material.color.multiplyScalar(BLOCK_EXPOSURE); // gaps between blades read as shade, not quilting\r\n const warm=new T.DirectionalLight(0xffe6b0,1.1);warm.position.set(.4,.85,.55);scene.add(warm);\r\n const [x0,y0]=toWorld(0,0),[x1,y1]=toWorld(1,1),faceW=Math.abs(x1-x0),faceH=Math.abs(y1-y0);\r\n const gltf=await new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).loadAsync(FLOWER_ASSET);\r\n const tmpl=gltf.scene,tsize=new T.Box3().setFromObject(tmpl).getSize(new T.Vector3());\r\n let petal=null;\r\n tmpl.traverse(n=>{if(!n.isMesh)return;n.material.metalness=0; // Kenney ships metalness 1: black without an env map\r\n  const c=n.material.color;if(n.material.name==='colorRed'||(c.r>.5&&c.g<.3&&c.b<.3))petal=n.material;});\r\n S={blocks:mesh.isMesh?[mesh]:mesh.children.filter(c=>c.isMesh),scene,toWorld,faceZ,uniforms,tmpl,petal,lawn:makeBlades(T,uniforms,mesh.isMesh?mesh.parent:mesh),warm,wake,reduced,faceW,aspect:faceW/faceH,\r\n  flowerScale:faceW*FLOWER_FRAC/(Math.max(tsize.x,tsize.z)||1),flowerScaleRatio:FLOWER_FRAC/(Math.max(tsize.x,tsize.z)||1),flowers:[],pool:[],lastPlanted:new Map(),springIdx:0,timer:0,petalTint:null};\r\n S.ob=buildSecret(T,scene);secReset();\r\n window.myr5GrassSecret={autoWalk,state:()=>S?.sec,claims:id=>claims(id),freeze};\r\n}\r\nfunction makeFlower(){\r\n const obj=S.tmpl.clone(true),mats=[];let petal=null;\r\n obj.traverse(n=>{if(!n.isMesh)return;const m=n.material.clone();m.transparent=true;if(n.material===S.petal)petal=m;n.material=m;mats.push(m);});\r\n return {obj,mats,petal,randomColor:new THREE.Color()};\r\n}\r\nfunction setPetalTint(hex,selected=true){\r\n if(!S)return;if(selected&&!/^#[0-9a-f]{6}$/i.test(hex||''))return;\r\n S.petalTint=selected?new THREE.Color(hex):null;\r\n for(const f of [...S.flowers,...S.pool])f.petal?.color.copy(S.petalTint||f.randomColor);\r\n}\r\nfunction plant(u,v,hold){\r\n const [wx,wy]=S.toWorld(u,v);\r\n const f=(S.flowers.length>=FLOWER_CAP?S.flowers.shift():S.pool.pop())||makeFlower();\r\n f.randomColor.setHSL(...flowerHSL());f.petal?.color.copy(S.petalTint||f.randomColor);\r\n f.obj.position.set(wx,wy,S.faceZ+S.faceW*FLOWER_LIFT);f.obj.visible=true;f.u=u;f.v=v;\r\n f.obj.rotation.set(FLOWER_TILT,Math.random()*Math.PI*2,0); // stand toward the camera, random yaw about the stem\r\n f.hold=!!hold;f.sizeFactor=.8+Math.random()*.5;f.target=S.flowerScale*f.sizeFactor;f.born=performance.now();\r\n f.obj.scale.setScalar(S.reduced?f.target:1e-4);\r\n for(const m of f.mats)m.opacity=1;\r\n S.scene.add(f.obj);S.flowers.push(f);\r\n}\r\nfunction plantCluster(u,v,n,hold){for(const [du,dv] of clusterOffsets(n,CLUSTER_FRAC))plant(clamp01(u+du),clamp01(v+dv*S.aspect),hold);}\r\n// Vault secret: a stroke the reducer owns plants only the flowers that extend its line (so planted line === walkable line).\r\nconst pt=(u,v)=>({x:u,y:v/S.aspect});\r\nfunction press(id,u,v){\r\n if(S.sec.phase==='done')secReset(); // the board was healed/resumed after the door showed: start over\r\n secEv({t:'down',id,...pt(u,v)});\r\n plantCluster(u,v,3,S.sec.drawing===id);S.lastPlanted.set(id,[u,v]);\r\n}\r\nfunction claims(id){return !!S&&grassSecretClaims(S.sec,id);}\r\nfunction move(id,u,v){\r\n if(S.sec.drawing===id){const n=S.sec.added;secEv({t:'move',id,...pt(u,v)});if(S.sec.added!==n)plantCluster(u,v,2+(Math.random()<.5),true);return;}\r\n if(S.sec.phase!=='idle'&&S.sec.phase!=='walk')return;\r\n const cur=S.toWorld(u,v),last=S.lastPlanted.get(id);\r\n if(!last){S.lastPlanted.set(id,[u,v]);return;}\r\n const old=S.toWorld(last[0],last[1]);\r\n if(plantStep(old[0],old[1],cur[0],cur[1])){plantCluster(u,v,2+(Math.random()<.5));S.lastPlanted.set(id,[u,v]);}\r\n}\r\nfunction resize(){\r\n if(!S)return;\r\n const [x0,y0]=S.toWorld(0,0),[x1,y1]=S.toWorld(1,1);S.faceW=Math.abs(x1-x0);S.aspect=S.faceW/Math.max(1,Math.abs(y1-y0));S.flowerScale=S.faceW*S.flowerScaleRatio;if(S.sec.phase==='idle')secReset();\r\n const now=performance.now();\r\n for(const f of S.flowers){\r\n  const [x,y]=S.toWorld(f.u,f.v),age=now-f.born,k=fadeLife(age),pop=S.reduced?1:popScale(age);\r\n  f.obj.position.set(x,y,S.faceZ+S.faceW*FLOWER_LIFT);f.target=S.flowerScale*f.sizeFactor;f.obj.scale.setScalar(f.target*pop*k);\r\n }\r\n}\r\nfunction release(id,u,v){\r\n secEv({t:'up',id});S.lastPlanted.delete(id);\r\n const slot=S.uniforms.uSpring.value[S.springIdx];\r\n slot.set(u,v,S.uniforms.uTime.value,1);\r\n S.springIdx=(S.springIdx+1)%S.uniforms.uSpring.value.length;\r\n}\r\nfunction step(dt,now){\r\n let animating=secStep(dt,now);\r\n for(let i=S.flowers.length-1;i>=0;i--){\r\n  const f=S.flowers[i],age=now-f.born,k=fadeLife(age);\r\n  if(k<=0||(S.reduced&&k<1)){S.scene.remove(f.obj);S.pool.push(f);S.flowers.splice(i,1);continue;}\r\n  const pop=S.reduced?1:popScale(age);\r\n  if(pop<1||k<1)animating=true;\r\n  f.obj.scale.setScalar(f.target*pop*k);\r\n  for(const m of f.mats)m.opacity=k;\r\n }\r\n const t=S.uniforms.uTime.value;\r\n for(const v of S.uniforms.uSpring.value){\r\n  if(v.w<=0)continue;\r\n  if(springActive(t-v.z))animating=true;else v.set(0,0,0,0);\r\n }\r\n // Flowers still waiting to fade: sleep, but wake when the oldest one's fade starts.\r\n clearTimeout(S.timer);\r\n if(!animating&&S.flowers.length)S.timer=setTimeout(S.wake,Math.max(0,S.flowers[0].born+FADE_MS-now));\r\n return animating;\r\n}\r\n// Board hooks: after the board cuts polyUv (face coords, v down) out of the block, collapse every blade\r\n// rooted inside it (zero the instance's 3x3, so its triangles are zero-area) and hide flowers inside it,\r\n// so the hole's edge follows the shape; heal() restores the saved matrices and shows the flowers.\r\nfunction cut(polyUv){\r\n if(!S)return;\r\n heal();\r\n const {im,rootUV}=S.lawn,m=im.instanceMatrix.array,idx=rootsInside(rootUV,polyUv);\r\n for(const i of idx)for(const k of [0,1,2,4,5,6,8,9,10])m[16*i+k]=0;\r\n im.instanceMatrix.needsUpdate=true;S.lawn.cutIdx=idx;\r\n for(const f of S.flowers)if(pointInPolygon(f.u,f.v,polyUv))f.obj.visible=false;\r\n}\r\nfunction heal(){\r\n if(!S)return;if(S.sec.phase!=='idle')secReset();\r\n if(!S.lawn.cutIdx)return;\r\n const {im,rest,cutIdx}=S.lawn,m=im.instanceMatrix.array;\r\n for(const i of cutIdx)m.set(rest.subarray(16*i,16*i+16),16*i);\r\n im.instanceMatrix.needsUpdate=true;S.lawn.cutIdx=null;\r\n for(const f of S.flowers)f.obj.visible=true;\r\n}\r\nfunction dispose(){\r\n clearTimeout(S.timer);\r\n for(const f of [...S.flowers,...S.pool]){S.scene.remove(f.obj);for(const m of f.mats)m.dispose();}\r\n S.tmpl.traverse(n=>{n.geometry?.dispose();if(n.material)for(const m of [n.material].flat())m.dispose();});\r\n const {im}=S.lawn;im.removeFromParent();im.geometry.dispose();im.material.dispose();im.dispose();\r\n S.scene.remove(S.warm);\r\n if(S.fx)secDropFx();for(const o of [S.ob.shade,S.ob.alien,S.ob.tuft,S.ob.ufo,S.ob.beam])S.scene.remove(o);for(const d of S.ob.dis)d.dispose();delete window.myr5GrassSecret;\r\n S=null;\r\n}\r\n\r\n// --- Vault secret: THREE visuals (all primitives; unit = face width, so every object is scaled by S.faceW) ---\r\nconst SEC_START=[.1,.085],SEC_SHIP=[.9,.915]; // face (u,v) corners: alien top-left, ship bottom-right\r\nconst ease=t=>{t=clamp01(t);return t*t*(3-2*t);};\r\nfunction secGeom(){const W=S.faceW,hw=1/S.aspect;return {W,hw,start:[SEC_START[0],SEC_START[1]*hw],ship:[SEC_SHIP[0],SEC_SHIP[1]*hw]};}\r\nfunction secReset(){const g=secGeom();if(S.fx)secDropFx();for(const f of S.flowers)f.obj.visible=true;S.sec=grassSecretInit(g.start,g.ship,PLANT_STEP_PX/g.W);S.emerge=0;S.fired=false;S.vis=null;S.seen=0;S.apos=g.start;}\r\nfunction secEv(ev){const before=S.sec;S.sec=grassSecret(S.sec,ev,performance.now());return S.sec!==before;}\r\nfunction buildSecret(T,scene){\r\n const dis=[],mat=m=>(dis.push(m),m),geo=g=>(dis.push(g),g),radial=col=>{const c=document.createElement('canvas');c.width=c.height=64;const g=c.getContext('2d'),r=g.createRadialGradient(32,32,2,32,32,32);r.addColorStop(0,col);r.addColorStop(1,'rgba(0,0,0,0)');g.fillStyle=r;g.fillRect(0,0,64,64);const t=new T.CanvasTexture(c);dis.push(t);return t;};\r\n const lam=(color,extra)=>mat(new T.MeshLambertMaterial({color,...extra})),blob=(r,sx,sy,m)=>{const o=new T.Mesh(geo(new T.SphereGeometry(r,16,10)),m);o.scale.set(sx,sy,1);return o;};\r\n const disc=(r,col,op)=>new T.Mesh(geo(new T.PlaneGeometry(r*2,r*2)),mat(new T.MeshBasicMaterial({map:radial(col),transparent:true,opacity:op,depthWrite:false})));\r\n // alien: the top of a MYR5 alien's head, a purple cone (MOM purple #7a2fc4) with a pale nub, half hidden by a grass tuft until it walks\r\n const coneG=geo(new T.ConeGeometry(.03,.075,20));coneG.translate(0,.0375,0);\r\n const cone=new T.Mesh(coneG,lam(0xa45cff,{emissive:0x5a24a8})),rim=new T.Mesh(coneG,mat(new T.MeshBasicMaterial({color:0xe4ccff,side:T.BackSide}))),nub=new T.Mesh(geo(new T.SphereGeometry(.006,10,8)),mat(new T.MeshBasicMaterial({color:0xc9a0ff})));nub.position.y=.076;\r\n rim.scale.set(1.28,1.1,1.28);rim.position.y=-.004;const alien=new T.Group();alien.add(rim,cone,nub);\r\n const tuft=new T.Group(),shade=disc(.12,'rgba(0,0,0,.95)',.8);tuft.add(blob(.034,1.1,.4,lam(0x2f7a24,{emissive:0x0c2a08})));\r\n // ufo: squashed sphere + glass dome + gold ring, tilted sideways, its lower side buried in a dirt mound\r\n const ufoTilt=new T.Group(),saucer=blob(.07,1,.32,lam(0xc4ccd6,{emissive:0x3a424c})),ring=new T.Mesh(geo(new T.TorusGeometry(.07,.005,6,28)),lam(0xffd36e,{emissive:0x6a4a10})),dome=new T.Mesh(geo(new T.SphereGeometry(.034,16,10,0,Math.PI*2,0,Math.PI/2)),lam(0xbfe6ff,{emissive:0x2a5a7a,transparent:true,opacity:.8}));\r\n ring.rotation.x=Math.PI/2;dome.position.y=.008;ufoTilt.add(saucer,ring,dome);ufoTilt.rotation.z=-.9;\r\n const mound=blob(.045,1.2,.4,lam(0x6b4526)),dirt=disc(.12,'rgba(70,44,24,1)',.85);mound.position.set(-.03,.048,.02);\r\n const ufo=new T.Group();ufo.add(dirt,ufoTilt,mound);\r\n const bc=document.createElement('canvas');bc.width=8;bc.height=64;{const g=bc.getContext('2d'),r=g.createLinearGradient(0,0,0,64);r.addColorStop(0,'rgba(255,236,170,.95)');r.addColorStop(1,'rgba(176,108,255,0)');g.fillStyle=r;g.fillRect(0,0,8,64);}\r\n const bt=new T.CanvasTexture(bc);dis.push(bt);const beam=new T.Mesh(geo(new T.PlaneGeometry(1,1)),mat(new T.MeshBasicMaterial({map:bt,transparent:true,blending:T.AdditiveBlending,depthWrite:false,opacity:0})));beam.visible=false;\r\n for(const o of [shade,alien,tuft,ufo,beam])scene.add(o);\r\n return {alien,tuft,shade,ufo,ufoTilt,beam,dis};\r\n}\r\n// ground crack + split, built into the living lawn: the real blades near the bolt bend away from it, dirt shows in the line, then the\r\n// blades/flowers of each side (plus a dark ground sheet each, standing in for the hidden block) slide apart and reveal a gunmetal/gold/purple\r\n// plate (stands in for the vault door poster).\r\nfunction buildCrack(){\r\n const T=THREE,{W,hw,start,ship}=secGeom(),main=crackPath(ship,start),edge=[[1,hw],...main,[0,0]],clampP=p=>[Math.min(1,Math.max(0,p[0])),Math.min(hw,Math.max(0,p[1]))];\r\n const polyA=[...edge,[1,0]],polyB=[...edge,[0,hw]],cw=384,ch=Math.round(cw*hw),dis=[];\r\n const cvs=()=>{const c=document.createElement('canvas');c.width=cw;c.height=ch;return c;},path=(g,pts)=>{g.beginPath();pts.forEach(([x,y],i)=>g[i?'lineTo':'moveTo'](x*cw,y*cw));};\r\n const tex=c=>{const t=new T.CanvasTexture(c);t.colorSpace=T.SRGBColorSpace;dis.push(t);return t;};\r\n const ground=poly=>{const c=cvs(),g=c.getContext('2d');g.save();path(g,poly);g.closePath();g.clip();g.fillStyle='#24132f';g.fillRect(0,0,cw,ch);\r\n  g.lineJoin='miter';path(g,edge);g.strokeStyle='#2e1b0e';g.lineWidth=cw*.045;g.stroke();g.strokeStyle='#6b4a2a';g.lineWidth=cw*.016;g.stroke();g.restore();return tex(c);};\r\n const plate=(()=>{const c=cvs(),g=c.getContext('2d'),gr=g.createLinearGradient(0,0,cw,ch);gr.addColorStop(0,'#1d2026');gr.addColorStop(.5,'#2b2f38');gr.addColorStop(1,'#16181d');g.fillStyle=gr;g.fillRect(0,0,cw,ch); // dark gunmetal\r\n  g.strokeStyle='rgba(255,255,255,.04)';for(let y=0;y<ch;y+=3){g.beginPath();g.moveTo(0,y);g.lineTo(cw,y);g.stroke();}\r\n  const glow=g.createRadialGradient(cw/2,ch/2,cw*.05,cw/2,ch/2,cw*.75);glow.addColorStop(0,'rgba(150,70,240,.55)');glow.addColorStop(1,'rgba(122,47,196,0)');g.fillStyle=glow;g.fillRect(0,0,cw,ch); // purple glow\r\n  g.strokeStyle='#0d0e11';g.lineWidth=7;g.strokeRect(cw*.08,ch*.1,cw*.84,ch*.8);g.strokeStyle='#ffd36e';g.lineWidth=3;g.strokeRect(cw*.08+5,ch*.1+5,cw*.84-10,ch*.8-10); // gold trim\r\n  g.fillStyle='#ffd36e';for(const [x,y] of [[.14,.14],[.86,.14],[.14,.86],[.86,.86]]){g.beginPath();g.arc(x*cw,y*ch,5,0,7);g.fill();}\r\n  g.shadowColor='#b06cff';g.shadowBlur=18;g.strokeStyle='#ffd36e';g.lineWidth=4;g.beginPath();g.arc(cw/2,ch/2,cw*.18,0,7);g.stroke();return tex(c);})();\r\n const shape=(poly,t)=>{const sh=new T.Shape();poly.forEach(([x,y],i)=>sh[i?'lineTo':'moveTo'](x-.5,hw/2-y));const g=new T.ShapeGeometry(sh),p=g.attributes.position,uv=g.attributes.uv;dis.push(g);\r\n  for(let i=0;i<p.count;i++)uv.setXY(i,p.getX(i)+.5,1-(hw/2-p.getY(i))/hw);\r\n  const m=new T.MeshBasicMaterial({map:t});dis.push(m);const o=new T.Mesh(g,m);o.scale.setScalar(W);return o;};\r\n const A=shape(polyA,ground(polyA)),B=shape(polyB,ground(polyB)),P=new T.Mesh(new T.PlaneGeometry(1,hw),new T.MeshBasicMaterial({map:plate}));dis.push(P.geometry,P.material);P.scale.setScalar(W);P.visible=false;\r\n const gc=cvs(),glow=new T.CanvasTexture(gc),G=new T.Mesh(new T.PlaneGeometry(1,hw),new T.MeshBasicMaterial({map:glow,transparent:true,depthWrite:false}));dis.push(glow,G.geometry,G.material);G.scale.setScalar(W);\r\n const branches=[2,5,8].map(i=>{const a=main[i],d=i%2?1:-1;return [a,clampP([a[0]+.06*d,a[1]+.05]),clampP([a[0]+.1*d,a[1]+.045*d+.09]),clampP([a[0]+.13*d,a[1]+.14])];});\r\n const cx=S.toWorld(.5,.5),ctr=(o,z)=>o.position.set(cx[0],cx[1],S.faceZ+W*z);\r\n ctr(A,-.0045);ctr(B,-.0045);ctr(P,-.0052);ctr(G,.08);for(const o of [A,B,P,G])S.scene.add(o);\r\n const mean=p=>p.reduce((a,q)=>[a[0]+q[0]/p.length,a[1]+q[1]/p.length],[0,0]),ca=mean(polyA),cb=mean(polyB),dx=ca[0]-cb[0],dy=-(ca[1]-cb[1]),dl=Math.hypot(dx,dy)||1;\r\n // every blade/flower: which side of the bolt and how far from it (face-width units)\r\n const uvA=polyA.map(([x,y])=>[x,y*S.aspect]),dseg=(p,a,b)=>{const vx=b[0]-a[0],vy=b[1]-a[1],k=clamp01(((p[0]-a[0])*vx+(p[1]-a[1])*vy)/(vx*vx+vy*vy||1));return Math.hypot(p[0]-a[0]-vx*k,p[1]-a[1]-vy*k);};\r\n const ru=S.lawn.rootUV,n=ru.length/2,bs=new Int8Array(n),bd=new Float32Array(n);\r\n for(let i=0;i<n;i++){const p=[ru[2*i],ru[2*i+1]/S.aspect];bs[i]=pointInPolygon(ru[2*i],ru[2*i+1],uvA)?1:-1;let d=9;for(let k=1;k<main.length;k++)d=Math.min(d,dseg(p,main[k-1],main[k]));bd[i]=d;}\r\n for(const f of S.flowers)f.side=pointInPolygon(f.u,f.v,uvA)?1:-1;\r\n for(const m of S.blocks)m.visible=false; // the ground sheets stand in for the block\r\n S.fx={A,B,P,G,main,branches,gc,glow,cw,ch,cx,dir:[dx/dl,dy/dl],dis,drawn:-1,bs,bd};\r\n}\r\nfunction drawCrack(prog){\r\n const F=S.fx;if(F.drawn===prog)return;F.drawn=prog;const g=F.gc.getContext('2d'),{cw,ch}=F;g.clearRect(0,0,cw,ch);if(prog<=0){F.glow.needsUpdate=true;return;}\r\n const seg=(pts,k)=>{g.beginPath();let tot=0;for(let i=1;i<pts.length;i++)tot+=d2(pts[i-1],pts[i]);let rem=tot*k;g.moveTo(pts[0][0]*cw,pts[0][1]*cw);for(let i=1;i<pts.length&&rem>0;i++){const l=d2(pts[i-1],pts[i]),f=Math.min(1,rem/l);g.lineTo((pts[i-1][0]+(pts[i][0]-pts[i-1][0])*f)*cw,(pts[i-1][1]+(pts[i][1]-pts[i-1][1])*f)*cw);rem-=l;}g.stroke();};\r\n g.lineJoin='miter';g.lineCap='round';g.miterLimit=3;\r\n for(const [w,col,blur] of [[cw*.045,'#1c0f06',0],[cw*.026,'#4a2f19',0],[cw*.016,'#ff8a1f',cw*.04],[cw*.006,'#fff3c2',0]]){g.lineWidth=w;g.strokeStyle=col;g.shadowColor='#ff9a2a';g.shadowBlur=blur;seg(F.main,prog);if(prog>.35)for(const b of F.branches)seg(b,Math.min(1,(prog-.35)/.5));} // dirt bed, then the glow\r\n F.glow.needsUpdate=true;\r\n}\r\n// slide each real blade along the bolt's cross direction: crack-time parting (blades near the line lean away) + split-time pull-apart\r\nfunction moveLawn(part,sp){\r\n const F=S.fx,{im,rest}=S.lawn,m=im.instanceMatrix.array,fw=S.uniforms.uFaceSize.value.x,[dx,dy]=F.dir,pa=part*.06*fw,mv=sp*.7*fw;\r\n for(let i=0;i<F.bs.length;i++){const k=Math.max(0,1-F.bd[i]/.09),o=F.bs[i]*(k*k*pa+mv);m[16*i+12]=rest[16*i+12]+dx*o;m[16*i+13]=rest[16*i+13]+dy*o;}\r\n im.instanceMatrix.needsUpdate=true;\r\n}\r\nfunction secDropFx(){const F=S.fx;S.fx=null;for(const o of [F.A,F.B,F.P,F.G])S.scene.remove(o);for(const d of F.dis)d.dispose();\r\n const {im,rest}=S.lawn,m=im.instanceMatrix.array;for(let i=0;i<F.bs.length;i++){m[16*i+12]=rest[16*i+12];m[16*i+13]=rest[16*i+13];}im.instanceMatrix.needsUpdate=true;im.visible=true;\r\n for(const b of S.blocks)b.visible=true;resize();}\r\n// per-frame: tick the reducer, then pose everything from it. Returns true while anything is moving.\r\nfunction secStep(dt,now){\r\n if(S.sec.phase==='done'&&S.fired&&!S.vis)return false;\r\n if(S.freezeT==null)S.sec=grassSecret(S.sec,{t:'tick'},now);const sec=S.sec,ph=sec.phase,W=S.faceW,wp=(x,y)=>S.toWorld(x,y*S.aspect),set=(o,[x,y],z,sc=1)=>{const [px,py]=wp(x,y);o.position.set(px,py,S.faceZ+W*z);o.scale.setScalar(W*sc);},t=S.freezeT??now-sec.t0;\r\n if(sec.resets!==S.seen){S.seen=sec.resets;S.vis={t0:now,from:S.apos};}\r\n S.emerge=ph==='walk'?Math.min(1,S.emerge+dt*3):ph==='idle'?0:S.emerge;\r\n let ap=ph==='walk'?secretPoint(sec.path,sec.pos):sec.start,asc=1;\r\n if(ph==='board'){const k=ease(t/SECRET.boardMs),e=secretPoint(sec.path,sec.len);ap=[e[0]+(sec.ship[0]-e[0])*k,e[1]+(sec.ship[1]-e[1])*k];asc=1-k;}\r\n let vis=false;\r\n if(S.vis){const k=(now-S.vis.t0)/350;vis=k<2.4;if(k<1){ap=S.vis.from||ap;asc=1-ease(k);}else asc=ease((k-1)/1.4);if(!vis)S.vis=null;}\r\n S.apos=ap;const bob=ph==='walk'?Math.abs(Math.sin(now*.012))*.01:0,{alien,tuft,shade,ufo,ufoTilt}=S.ob,em=S.emerge;\r\n alien.visible=ph==='idle'||ph==='walk'||ph==='board'||vis;alien.rotation.z=ph==='walk'?Math.sin(now*.012)*.14:0;set(alien,[ap[0],ap[1]+(1-em)*.02-bob],.03,asc);\r\n tuft.visible=alien.visible&&em<1;set(tuft,[sec.start[0],sec.start[1]+.005],.036,1-em);shade.visible=ph==='idle'||ph==='walk'||vis;set(shade,sec.start,.02);\r\n let up=sec.ship,usc=1,tilt=-.9,fk=0;const spent=ph==='crack'||ph==='split'||ph==='done';\r\n if(ph==='fly'){fk=ease(t/SECRET.flyMs);up=[sec.ship[0]+Math.sin(t*.018)*.014*(1-fk),sec.ship[1]-fk*fk*2.2];usc=1-.85*fk;tilt=-.9*(1-Math.min(1,fk*4))+Math.sin(t*.014)*.08*(1-fk);} // straight up, small wobble\r\n ufo.visible=!spent;ufoTilt.rotation.z=tilt;set(ufo,up,.016+fk*.3,usc);\r\n {const b=S.ob.beam;b.visible=ph==='fly'&&fk<.97;if(b.visible){const h=Math.max(.1,sec.ship[1]-up[1]+.08),[bx,by]=wp(up[0],up[1]+h/2);b.position.set(bx,by,S.faceZ+W*.05);b.scale.set(W*.1*usc,W*h,1);b.material.opacity=.75*Math.sin(Math.PI*Math.min(1,fk*1.1+.05));}}\r\n let anim=ph==='walk'||ph==='board'||ph==='fly'||vis;\r\n if(spent){\r\n  if(!S.fx)buildCrack();\r\n  const F=S.fx,k=ph==='crack'?t/SECRET.crackMs:1,sk=ph==='split'?t/SECRET.splitMs:ph==='done'?1:0,sp=ease(sk),prog=Math.round(ease(Math.min(1,k*1.15))*40)/40;\r\n  drawCrack(prog);F.G.material.opacity=1-clamp01(sk*3);F.G.visible=sk<.34;F.P.visible=sk>0;\r\n  const sig=prog+'|'+sp.toFixed(3);if(F.sig!==sig){F.sig=sig;moveLawn(prog,sp);}\r\n  const gone=sk>=.85;S.lawn.im.visible=!gone;\r\n  for(const [o,sg] of [[F.A,1],[F.B,-1]]){o.visible=!gone;o.position.set(F.cx[0]+F.dir[0]*sg*sp*W*.7,F.cx[1]+F.dir[1]*sg*sp*W*.7,S.faceZ-W*.0045);}\r\n  for(const f of S.flowers){const [x,y]=S.toWorld(f.u,f.v);f.obj.visible=!gone;f.obj.position.set(x+F.dir[0]*f.side*sp*W*.7,y+F.dir[1]*f.side*sp*W*.7,S.faceZ+W*FLOWER_LIFT);}\r\n  anim=ph!=='done';\r\n  if(ph==='done'&&!S.fired){S.fired=true;window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'grass'}}));}\r\n }\r\n // line flowers never fade while a walk is live: pin them at full pop age\r\n if(ph!=='idle')for(const f of S.flowers)if(f.hold&&now-f.born>FADE_MS-1500)f.born=now-POP_MS-1;\r\n return anim;\r\n}\r\n// debug hook (screenshots): hold the ship/crack sequence at phase `ph`, fraction k of its duration; freeze(null) resumes from idle.\r\nfunction freeze(ph,k=0){\r\n if(!ph){S.freezeT=null;secReset();return;}\r\n if(S.fx)secDropFx();for(const f of S.flowers)f.obj.visible=true;\r\n const g=secGeom(),e=g.start,d=SECRET[NEXT[ph]?.[0]]||1;S.freezeT=k*d;S.fired=false;\r\n S.sec={...grassSecretInit(g.start,g.ship,PLANT_STEP_PX/g.W),phase:ph,path:[e,g.ship],len:d2(e,g.ship)};S.wake();\r\n}\r\n// debug / test hook: draw a flower line from the alien to the ship through the real press/move/release path.\r\n// opts: gapAt (0..1 of the way: lift there), gapMs (stay lifted this long, then draw on; 0 = never resume), rate (steps per second).\r\nasync function autoWalk({gapAt=null,gapMs=0,rate=30}={}){\r\n const g=secGeom(),sleep=ms=>new Promise(r=>setTimeout(r,ms)),id=77,at=k=>[g.start[0]+(g.ship[0]-g.start[0])*k,g.start[1]+(g.ship[1]-g.start[1])*k],uv=([x,y])=>[x,y*S.aspect],n=Math.ceil(d2(g.start,g.ship)/(PLANT_STEP_PX/g.W*1.1));\r\n let down=false;\r\n for(let i=0;i<=n;i++){\r\n  const k=i/n,[u,v]=uv(at(k));\r\n  if(gapAt!=null&&k>=gapAt&&down){release(id,u,v);down=false;if(!gapMs)return;await sleep(gapMs);gapAt=null;}\r\n  if(!down){press(id,u,v);down=true;}else move(id,u,v);\r\n  S.wake();await sleep(1000/rate);\r\n }\r\n if(down)release(id,...uv(g.ship));\r\n}\r\n\r\n// R7: the flowers in 2D, for the flat board: the same clusters along a drag, popping in and fading out after FADE_MS,\r\n// drawn on `paint` as five-petal blooms with a dark rim so they read on the lawn. Own state, no THREE.\r\nexport function grassFlowers(){\r\n let S=null;\r\n const bloom=(g,f,k)=>{\r\n  const r=f.r*k;if(r<.5)return;\r\n  g.save();g.translate(f.x,f.y);g.rotate(f.rot);g.globalAlpha=k;g.fillStyle=f.col;g.strokeStyle='rgba(20,30,10,.55)';g.lineWidth=r*.12;\r\n  for(let i=0;i<5;i++){const a=i*Math.PI*2/5;g.beginPath();g.ellipse(Math.cos(a)*r*.55,Math.sin(a)*r*.55,r*.52,r*.34,a,0,Math.PI*2);g.fill();g.stroke();}\r\n  g.fillStyle='#ffd23a';g.beginPath();g.arc(0,0,r*.27,0,Math.PI*2);g.fill();g.stroke();g.restore();\r\n };\r\n const plantOne=(u,v)=>{const [h,s,l]=flowerHSL(),randomColor=`hsl(${h*360} ${s*100}% ${l*100}%)`;S.flowers.push({x:u*S.W,y:v*S.H,r:S.W*FLOWER_FRAC*.5*(.8+Math.random()*.5),rot:Math.random()*Math.PI,randomColor,col:S.petalTint||randomColor,born:performance.now()});if(S.flowers.length>FLOWER_CAP)S.flowers.shift();};\r\n const cluster=(u,v,n)=>{for(const [du,dv] of clusterOffsets(n,CLUSTER_FRAC))plantOne(clamp01(u+du),clamp01(v+dv*S.aspect));};\r\n return {\r\n  init({paint,toWorld,wake}){S={paint,toWorld,wake,W:paint.canvas.width,H:paint.canvas.height,aspect:paint.canvas.width/paint.canvas.height,flowers:[],last:new Map(),timer:0,reduced:matchMedia('(prefers-reduced-motion: reduce)').matches,petalTint:null};},\r\n  setTint(hex,selected=true){if(selected&&!/^#[0-9a-f]{6}$/i.test(hex||''))return;S.petalTint=selected?hex:null;for(const f of S.flowers)f.col=S.petalTint||f.randomColor;S.wake();},\r\n  press(id,u,v){cluster(u,v,3);S.last.set(id,S.toWorld(u,v));},\r\n  move(id,u,v){const cur=S.toWorld(u,v),last=S.last.get(id);if(!last){S.last.set(id,cur);return;}if(plantStep(last[0],last[1],cur[0],cur[1])){cluster(u,v,2+(Math.random()<.5));S.last.set(id,cur);}},\r\n  release(id){S.last.delete(id);},\r\n  step(dt,now){\r\n   const g=S.paint.ctx,n=S.flowers.length;let animating=false;\r\n   S.flowers=S.flowers.filter(f=>fadeLife(now-f.born)>0);\r\n   g.clearRect(0,0,S.W,S.H);\r\n   for(const f of S.flowers){const age=now-f.born,k=fadeLife(age),pop=S.reduced?1:popScale(age);if(pop<1||k<1)animating=true;bloom(g,f,pop*k);}\r\n   clearTimeout(S.timer);if(!animating&&S.flowers.length)S.timer=setTimeout(S.wake,Math.max(0,S.flowers[0].born+FADE_MS-now));\r\n   return animating||S.flowers.length!==n;\r\n  },\r\n  dispose(){clearTimeout(S?.timer);S=null;},\r\n };\r\n}\r\ngrassFlowers.tintTarget='trace';\r\n\r\nexport const grass={\r\n id:'grass',asset:'/pod/worlds/boards/grass.glb',flip:false,background:'#0b150a',\r\n guide:{color:'#d8ffc0',alpha:.2,width:4},\r\n uniforms:{uHalfDepth:{value:0},uSpring:{value:Array.from({length:6},()=>new THREE.Vector4(0,0,0,0))},uBreeze:{value:1}},\r\n uniformDecls:'uniform float uHalfDepth;\\nuniform vec4 uSpring[6];\\nuniform float uBreeze;\\n',\r\n vertexDisplace:VERTEX_DISPLACE,\r\n  init,press,move,release,claims,resize,step,cut,heal,healSecret:heal,dispose,setTint:setPetalTint,trace2d:grassFlowers,\r\n};\r\n","modules/portal/portal-board-ice.mjs":"// Cracking-ice effect for portal-board-glb.mjs. Fracture geometry for the big crack comes from the vendored\r\n// MIT cracked-glass core (cracked-glass-core.mjs) unchanged; this file only drives it: one big radial crack\r\n// where the finger lands, then, as the finger drags, a hairline along its path with small V / Y / Z cracks\r\n// shooting off sideways just behind it, each retracting tips-first back into its root. All drawn on the glow\r\n// layer only so the paint layer keeps the guides: a cyan-white core over a thin dark rim (EDGE), which emits nothing\r\n// but darkens the ice under it (ice.fragment), so the cracks read on the dark 3D ice and on the pale flat poster alike.\r\n// AGPL-3.0-or-later.\r\nimport {generateFracture,computeFrame} from './cracked-glass-core.mjs';\r\n\r\n// Big press crack: field side as a fraction of the paint width, lifecycle (ms), fracture options.\r\nexport const BIG={frac:.45,grow:300,hold:1000,shrink:400,opts:{rays:{count:7},rings:{count:3}}};\r\n// Drag trail knobs. Timings in ms: shoot out (ease-out) / hold / retract (the growth run backwards).\r\n// Ranges are [min,max] picked at random per crack. Screen px, so they look the same on any face size.\r\n// Each crack is gone 1.71 s after its birth (R7: held ~2x longer so it reads), well inside Ian's 7 s rule.\r\nexport const TRAIL={grow:110,hold:700,retract:900,\r\n spacing:[9,20],   // screen px of finger travel between cracks\r\n size:[18,40],     // screen px, a crack's unit length (V prongs ~ size, Y and Z a bit shorter overall)\r\n sweep:[10,55],    // degrees a crack leans back from square-off the path (a wake behind the finger)\r\n jag:.13,          // sideways kink of each third of a segment, as a fraction of its length\r\n // R7 (Ian 26 Sept: \"i cant see ... the ice cracks\"): 5x the first tuning; a 1024 px face is ~330 CSS px on a phone.\r\n width:9,hair:5,taper:.75, // core width at the root / of the path hairline (paint px at 1024), tip taper\r\n max:70};          // ponytail: cap on live trail cracks; the oldest (already mostly retracted) is dropped first on a very fast drag\r\nconst MAX_BIG=14; // the 10-tap chain keeps one crack per tap\r\n// ponytail: POOL big fractures reused with a random spin, LEVELS cached frames each, since\r\n// computeFrame is ~2 ms per call; raise POOL if repeats ever show.\r\nconst POOL=6,LEVELS=16,FRAME_OPTS={quality:'normal',timeline:{crackStart:0,crackEnd:1,shatterStart:Infinity}};\r\n// CORE: the crack line (a tight cyan GLINT round it); EDGE: the dark rim, EDGE_PX each side; BIG_EDGE: the big crack's\r\n// stroke. Paint px at 1024.\r\nconst CORE='#d6fbff',GLINT='rgba(120,230,255,.9)',EDGE='rgba(2,20,32,.95)',EDGE_PX=3,BIG_EDGE=4;\r\nlet selectedTint=null;\r\nconst validTint=hex=>typeof hex==='string'&&/^#[0-9a-f]{6}$/i.test(hex);\r\nfunction tintRgba(hex,alpha){const n=parseInt(hex.slice(1),16);return `rgba(${n>>16},${(n>>8)&255},${n&255},${alpha})`;}\r\n\r\n// --- Pure lifecycle helpers (age in ms since spawn) ------------------------------------------\r\n// Big crack growth 0..1: grow, hold at 1, shrink back to 0; reduced motion is fully grown until the hold ends.\r\nexport function crackT(age,reduced=false,L=BIG){\r\n if(age<0||crackAlpha(age,reduced,L)===0)return 0;\r\n if(reduced)return 1;\r\n if(age<L.grow)return age/L.grow;\r\n if(age<L.grow+L.hold)return 1;\r\n return 1-(age-L.grow-L.hold)/L.shrink;\r\n}\r\n// Big crack opacity: 1 until the shrink starts, then fades with it; 0 means dead.\r\nexport function crackAlpha(age,reduced=false,L=BIG){\r\n if(age<0)return 0;\r\n const held=L.grow+L.hold;\r\n if(age<held)return 1;\r\n if(reduced)return 0;\r\n return Math.max(0,1-(age-held)/L.shrink);\r\n}\r\n// Trail crack: fraction 0..1 of its length that is visible. No fade: it shoots out, holds, then the same\r\n// curve runs backwards so it retracts tips-first into its root. Reduced motion: whole until the hold ends.\r\nexport const trailLife=(reduced=false,K=TRAIL)=>K.grow+K.hold+(reduced?0:K.retract);\r\nconst easeOut=x=>1-(1-x)*(1-x);\r\nexport function trailReach(age,reduced=false,K=TRAIL){\r\n if(age<0||age>=trailLife(reduced,K))return 0;\r\n if(reduced)return 1;\r\n if(age<K.grow)return easeOut(age/K.grow);\r\n if(age<K.grow+K.hold)return 1;\r\n return easeOut(1-(age-K.grow-K.hold)/K.retract);\r\n}\r\n\r\n// --- Pure shape helpers ------------------------------------------------------------------------\r\n// A crack is a list of branches; a branch is points [x,y,d] from where it attaches outward, d = arc distance\r\n// from the crack's root (a Y's fork branches start at the stem's length). Unit frame: root at 0,0, pointing +x.\r\nfunction jag(pts,amt,rnd){ // split each segment in three, nudging the two inner points sideways by up to amt x its length\r\n const out=[pts[0]];\r\n for(let i=1;i<pts.length;i++){\r\n  const [ax,ay]=pts[i-1],[bx,by]=pts[i],dx=bx-ax,dy=by-ay;\r\n  for(const f of [1/3,2/3]){const o=(rnd()*2-1)*amt;out.push([ax+dx*f-dy*o,ay+dy*f+dx*o]);}\r\n  out.push(pts[i]);\r\n }\r\n return out;\r\n}\r\nfunction withD(pts,d0){let d=d0;return pts.map((p,i)=>[p[0],p[1],d+=i?Math.hypot(p[0]-pts[i-1][0],p[1]-pts[i-1][1]):0]);}\r\nexport function crackShape(kind,rnd=Math.random,j=TRAIL.jag){\r\n const r=(a,b)=>a+(b-a)*rnd(),deg=Math.PI/180,ray=([x,y],a,l)=>[x+Math.cos(a)*l,y+Math.sin(a)*l],arm=(pts,d0)=>withD(jag(pts,j,rnd),d0);\r\n if(kind==='V'){const h=r(16,32)*deg;return [1,-1].map(s=>arm([[0,0],ray([0,0],s*h,r(.7,1))],0));}\r\n if(kind==='Y'){ // short stem, then a fork\r\n  const t=r(-8,8)*deg,stem=arm([[0,0],ray([0,0],t,r(.3,.45))],0),end=stem.at(-1),h=r(18,34)*deg;\r\n  return [stem,...[1,-1].map(s=>arm([end,ray(end,t+s*h,r(.45,.65))],end[2]))];\r\n }\r\n // Z: out, a sharp turn back across, out again\r\n const a=r(30,45)*deg,b=r(0,15)*deg,p1=ray([0,0],-a,r(.45,.55)),p2=ray(p1,Math.PI/2+b,r(.5,.6)),p3=ray(p2,-a,r(.45,.55));\r\n return [arm([[0,0],p1,p2,p3],0)];\r\n}\r\n// The part of a branch within arc distance r of the root, ending on an interpolated tip.\r\nexport function visible(b,r){\r\n const out=[];\r\n for(let i=0;i<b.length;i++){\r\n  const p=b[i];\r\n  if(p[2]<=r){out.push(p);continue;}\r\n  const q=b[i-1];\r\n  if(i&&r>q[2]){const f=(r-q[2])/(p[2]-q[2]);out.push([q[0]+(p[0]-q[0])*f,q[1]+(p[1]-q[1])*f,r]);}\r\n  break;\r\n }\r\n return out;\r\n}\r\n// Add a filled tapered outline of visible points p to the current path, pointed at its last point. Every\r\n// outline winds the same way, so one nonzero fill unions them all.\r\n// pad: added to every half-width, tip included (the dark rim round a crack).\r\nfunction ribbon(gc,p,h0,taper,len,pad=0){\r\n const n=p.length,o=[];\r\n for(let i=0;i<n;i++){\r\n  const a=p[i?i-1:0],b=p[i<n-1?i+1:i],dx=b[0]-a[0],dy=b[1]-a[1],l=Math.hypot(dx,dy)||1,h=pad+(i<n-1?h0*(1-taper*p[i][2]/len):0);\r\n  o.push(-dy/l*h,dx/l*h);\r\n }\r\n gc.moveTo(p[0][0]+o[0],p[0][1]+o[1]);\r\n for(let i=1;i<n;i++)gc.lineTo(p[i][0]+o[2*i],p[i][1]+o[2*i+1]);\r\n for(let i=n-1;i>=0;i--)gc.lineTo(p[i][0]-o[2*i],p[i][1]-o[2*i+1]);\r\n gc.closePath();\r\n}\r\n\r\n// Secret (Ian 6 Oct: \"10 taps in a row ... crystal explodes and shatters\"): pure reducer, testable without WebGL.\r\n// A tap = press..release within TAP_MS and under TAP_PX of finger travel; each press must come within TAP_MS of the previous press.\r\n// Events: {type:'press'} {type:'move',dist} {type:'release'}; now in ms. The 10th tap sets shattered.\r\nexport const SECRET={taps:10,gap:600,drift:12,claimFrom:3};\r\nexport const newSecret=()=>({taps:[],lastPress:-1e9,pressAt:0,down:false,moved:0,shattered:false});\r\nexport function iceSecret(state,ev,now){\r\n const S=state||newSecret();\r\n if(S.shattered)return S;\r\n if(ev.type==='press'){\r\n  if(now-S.lastPress>SECRET.gap)S.taps=[];\r\n  S.lastPress=S.pressAt=now;S.down=true;S.moved=0;\r\n }else if(ev.type==='move'){\r\n  S.moved+=ev.dist??0;\r\n  if(S.moved>=SECRET.drift)S.taps=[]; // a drag; the release below sees moved and stays out of the chain\r\n }else if(ev.type==='release'){\r\n  const tap=S.down&&S.moved<SECRET.drift&&now-S.pressAt<=SECRET.gap;\r\n  S.down=false;\r\n  if(!tap)S.taps=[];\r\n  else{S.taps.push(now);S.lastRelease=now;if(S.taps.length>=SECRET.taps)S.shattered=true;}\r\n }\r\n return S;\r\n}\r\n// Taps 1-2 stay eligible for the stitched-outline double-tap open; a press that would be the 3rd+ tap is claimed.\r\nexport const iceClaims=S=>!!S&&(S.shattered||S.taps.length+(S.down&&S.moved<SECRET.drift?1:0)>=SECRET.claimFrom);\r\n\r\n// One instance per board layer: the 3D board's (ice itself) and the flat board's 2D trace (ice.trace2d, R7) each get their own.\r\nexport function iceEffect(){\r\nlet S=null; // per-instance state\r\nlet tapState=null; // pure reducer state for secret tracking\r\nconst unkeep=now=>{for(const c of S.live)if(c.keep){c.keep=false;c.t0=now-BIG.grow-BIG.hold;}S.dirty=true;}; // chain broke: the kept cracks heal on the usual shrink\r\n\r\nfunction frame(i,k){ // cached Path2D of big pool pattern i at growth level k (lazily computed)\r\n const f=S.field;\r\n const p=S.pool[i]??={data:generateFracture({mode:'radial',width:f,height:f,seed:i+1,impact:{x:f/2,y:f/2},impactHole:0,...BIG.opts}),paths:[]};\r\n return p.paths[k]??=new Path2D(computeFrame(k/LEVELS,p.data,FRAME_OPTS).cracks.corePath);\r\n}\r\nconst rand=([a,b])=>a+(b-a)*Math.random();\r\n// One trail crack rooted at x,y (paint px) for a finger heading dx,dy (unit), k = paint px per screen px;\r\n// its hairline runs back to the previous root p.x,p.y. Geometry is fixed here, once; frames only clip it.\r\nfunction spawnTrail(p,x,y,dx,dy,k){\r\n const side=Math.random()<.5?1:-1,w=rand(TRAIL.sweep)*Math.PI/180,m=Math.random()<.5?1:-1,size=rand(TRAIL.size)*k;\r\n const ux=side*-dy*Math.cos(w)-dx*Math.sin(w),uy=side*dx*Math.cos(w)-dy*Math.sin(w); // sideways, leaning back\r\n const shape=crackShape('VYZ'[Math.floor(Math.random()*3)]).map(b=>b.map(([px,py,d])=>[x+size*(ux*px-uy*m*py),y+size*(uy*px+ux*m*py),d*size]));\r\n const hair=withD(jag([[x,y],[p.x,p.y]],TRAIL.jag,Math.random),0);\r\n if(S.trail.length>=TRAIL.max)S.trail.shift();\r\n S.trail.push({t0:performance.now(),shape,hair,len:Math.max(hair.at(-1)[2],...shape.map(b=>b.at(-1)[2])),reach:Math.max(...shape.map(b=>b.at(-1)[2]))});\r\n p.x=x;p.y=y;S.dirty=true;\r\n}\r\n// Shatter (Ian: \"explode and shatter\"): the crystal face becomes ~48 real 3D prisms (jittered-grid triangles, same material so\r\n// they carry the ice texture and the cracks), bursting toward the camera with spin + gravity, plus a flash and sparkle dust.\r\n// The board meshes hide, leaving a dark backplate, until heal(). Units: local board units, fw = face width.\r\nconst SHARD_MS=1700,NX=4,NY=6;\r\nfunction shatter(now){\r\n redraw(now);const {THREE,mesh,face:{w:fw,h:fh}}=S,orig=mesh.isGroup?[...mesh.children]:[mesh];\r\n const root=mesh.isGroup?mesh:mesh.parent,box=new THREE.Box3();\r\n for(const o of orig)if(o.geometry){o.geometry.computeBoundingBox();box.union(o.geometry.boundingBox);}\r\n const zf=box.max.z,t=fw*.03,pt=[];\r\n for(let j=0;j<=NY;j++){pt[j]=[];for(let i=0;i<=NX;i++){const e=i%NX&&j%NY; // jitter interior vertices only so the outline stays square\r\n  pt[j][i]=[(i/NX-.5)*fw+(e?(Math.random()-.5)*.7*fw/NX:0),(.5-j/NY)*fh+(e?(Math.random()-.5)*.7*fh/NY:0)];}}\r\n const mat=orig[0].material.clone();mat.onBeforeCompile=orig[0].material.onBeforeCompile;mat.customProgramCacheKey=orig[0].material.customProgramCacheKey;mat.transparent=true;\r\n const shards=[],cx=S.hit?(S.hit[0]-.5)*fw:0,cy=S.hit?(.5-S.hit[1])*fh:0;\r\n for(let j=0;j<NY;j++)for(let i=0;i<NX;i++){\r\n  const a=pt[j][i],b=pt[j][i+1],c=pt[j+1][i+1],d=pt[j+1][i],flip=(i+j)&1;\r\n  for(const T of flip?[[a,b,d],[b,c,d]]:[[a,b,c],[a,c,d]]){const tri=T.slice().reverse(); // the grid is clockwise, faces need CCW\r\n   const mx=(tri[0][0]+tri[1][0]+tri[2][0])/3,my=(tri[0][1]+tri[1][1]+tri[2][1])/3,pos=[],uv=[];\r\n   const V=(p,z)=>{pos.push(p[0]-mx,p[1]-my,z);uv.push(p[0]/fw+.5,p[1]/fh+.5);};\r\n   tri.forEach(p=>V(p,t/2));tri.forEach((p,k)=>V(tri[2-k],-t/2)); // front CCW, back reversed\r\n   for(let k=0;k<3;k++){const p=tri[k],q=tri[(k+1)%3];V(p,t/2);V(p,-t/2);V(q,-t/2);V(p,t/2);V(q,-t/2);V(q,t/2);}\r\n   const geo=new THREE.BufferGeometry();geo.setAttribute('position',new THREE.Float32BufferAttribute(pos,3));geo.setAttribute('uv',new THREE.Float32BufferAttribute(uv,2));geo.computeVertexNormals();\r\n   const m=new THREE.Mesh(geo,mat);m.position.set(mx,my,zf-t/2);m.frustumCulled=false;root.add(m);\r\n   const dx=mx-cx,dy=my-cy,dl=Math.hypot(dx,dy)||1,k=fw*(.4+1.1*Math.random())/(1+dl/fw);\r\n   shards.push({m,vx:dx/dl*k,vy:dy/dl*k+fh*.3*Math.random(),vz:fw*(.15+.7*Math.random()),sx:(Math.random()-.5)*14,sy:(Math.random()-.5)*14,sz:(Math.random()-.5)*10});\r\n  }}\r\n const back=new THREE.Mesh(new THREE.PlaneGeometry(fw*1.01,fh*1.01),new THREE.MeshBasicMaterial({color:0x04080c}));back.position.z=zf-t-fw*.002;root.add(back);\r\n const flash=new THREE.Mesh(new THREE.PlaneGeometry(Math.max(fw,fh)*4,Math.max(fw,fh)*4),new THREE.MeshBasicMaterial({color:0xcff8ff,transparent:true,blending:THREE.AdditiveBlending,depthTest:false,depthWrite:false}));flash.position.z=zf+fw*.6;flash.renderOrder=20;root.add(flash);\r\n const N=160,dp=new Float32Array(N*3),dv=[],dg=new THREE.BufferGeometry();\r\n for(let n=0;n<N;n++){dp[n*3]=cx+(Math.random()-.5)*fw*.3;dp[n*3+1]=cy+(Math.random()-.5)*fh*.2;dp[n*3+2]=zf;const th=Math.random()*6.283,sp=fw*(.4+2.2*Math.random());dv.push([Math.cos(th)*sp,Math.sin(th)*sp,fw*(.3+1.6*Math.random())]);}\r\n dg.setAttribute('position',new THREE.BufferAttribute(dp,3));\r\n const dust=new THREE.Points(dg,new THREE.PointsMaterial({color:0xd6fbff,size:4,sizeAttenuation:false,transparent:true,blending:THREE.AdditiveBlending,depthTest:false,depthWrite:false}));dust.frustumCulled=false;dust.renderOrder=19;root.add(dust);\r\n for(const o of orig)o.visible=false;\r\n S.shat={t0:now,orig,shards,mat,back,flash,dust,dp,dv,N,fh,done:false};\r\n}\r\nfunction unshatter(){\r\n const z=S.shat;if(!z)return;\r\n for(const s of z.shards){s.m.removeFromParent();s.m.geometry.dispose();}\r\n for(const o of [z.back,z.flash,z.dust]){o.removeFromParent();o.geometry.dispose();o.material.dispose();}\r\n z.mat.dispose();for(const o of z.orig)o.visible=true;S.shat=null;\r\n}\r\nfunction stepShatter(_,now){\r\n const z=S.shat,dt=Math.min(.1,(now-(z.last??now))/1000),age=now-z.t0,fade=Math.max(0,1-Math.max(0,age-SHARD_MS*.55)/(SHARD_MS*.45)),G=z.fh*2.4;\r\n for(const s of z.shards){const m=s.m;s.vy-=G*dt;m.position.x+=s.vx*dt;m.position.y+=s.vy*dt;m.position.z+=s.vz*dt;m.rotation.x+=s.sx*dt;m.rotation.y+=s.sy*dt;m.rotation.z+=s.sz*dt;}\r\n z.last=now;z.mat.opacity=fade;\r\n z.flash.material.opacity=Math.max(0,.75*(1-age/380));\r\n for(let n=0;n<z.N;n++){const v=z.dv[n];v[1]-=G*.4*dt;for(let k=0;k<3;k++)z.dp[n*3+k]+=v[k]*dt;}\r\n z.dust.geometry.attributes.position.needsUpdate=true;z.dust.material.opacity=fade;\r\n if(age>=SHARD_MS&&!z.done){z.done=true;for(const s of z.shards)s.m.visible=false;window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'ice'}}));}\r\n return !z.done;\r\n}\r\nfunction redraw(now){\r\n const gc=S.glow.ctx,f=S.field/2,h=.5*S.scale,pad=EDGE_PX*S.scale,core=S.tint||CORE,glintColor=S.tint?tintRgba(S.tint,.9):GLINT,glint=()=>{gc.shadowColor=glintColor;gc.shadowBlur=3*S.scale;},flat=()=>{gc.shadowBlur=0;};\r\n gc.clearRect(0,0,S.glow.canvas.width,S.glow.canvas.height);\r\n gc.save();gc.lineJoin='round';\r\n for(const c of S.live){ // dark rim, then the core\r\n  const age=c.keep?Math.min(now-c.t0,BIG.grow+BIG.hold-1):now-c.t0,k=Math.round(crackT(age,S.reduced)*LEVELS);\r\n  if(!k)continue;\r\n  gc.setTransform(1,0,0,1,0,0);gc.translate(c.x,c.y);gc.rotate(c.rot);gc.translate(-f,-f);\r\n  gc.globalAlpha=crackAlpha(age,S.reduced);const p=frame(c.i,k);\r\n  flat();gc.strokeStyle=EDGE;gc.lineWidth=(BIG_EDGE+2*EDGE_PX)*S.scale;gc.stroke(p);\r\n  glint();gc.fillStyle=gc.strokeStyle=core;gc.fill(p);gc.lineWidth=BIG_EDGE*S.scale;gc.stroke(p);\r\n }\r\n if(S.trail.length){ // every live crack in one path per pass: the rims (padded), then the cores\r\n  gc.setTransform(1,0,0,1,0,0);gc.globalAlpha=1;\r\n  const cracks=pad=>{gc.beginPath();for(const c of S.trail){\r\n   const r=trailReach(now-c.t0,S.reduced)*c.len;\r\n   for(const b of c.shape){const v=visible(b,r);if(v.length>1)ribbon(gc,v,TRAIL.width*h,TRAIL.taper,c.reach,pad);}\r\n   const v=visible(c.hair,r);if(v.length>1)ribbon(gc,v,TRAIL.hair*h,0,1,pad);\r\n  }};\r\n  flat();cracks(pad);gc.fillStyle=EDGE;gc.fill();\r\n  glint();cracks(0);gc.fillStyle=core;gc.fill();\r\n }\r\n gc.restore();\r\n S.glow.texture.needsUpdate=true;\r\n}\r\n\r\nfunction init({THREE,mesh,face,paint,glow,toWorld,wake}){\r\n const w=paint.canvas.width;\r\n S={THREE,mesh,face,glow,toWorld,live:[],trail:[],pool:[],next:Math.floor(Math.random()*POOL),drag:new Map(),dirty:false,\r\n  field:Math.round(w*BIG.frac),scale:w/1024,sx:w,sy:paint.canvas.height,\r\n  reduced:matchMedia('(prefers-reduced-motion: reduce)').matches,tint:selectedTint,wake};\r\n tapState=newSecret();\r\n}\r\nfunction setTint(hex,selected=true){if(selected&&!validTint(hex))return;selectedTint=selected?hex:null;if(S){S.tint=selectedTint;S.dirty=true;S.wake?.();}}\r\nfunction press(id,u,v){\r\n if(S.shat){if(!S.shat.done)return;heal();} // fallback if the host never called healSecret(): the next touch brings the crystal back\r\n const now=performance.now(),x=u*S.sx,y=v*S.sy;\r\n tapState=iceSecret(tapState,{type:'press'},now);\r\n if(!tapState.taps.length)unkeep(now); // gap too long: the old web heals\r\n S.drag.set(id,{u,v,x,y,left:rand(TRAIL.spacing)});\r\n if(S.live.length>=MAX_BIG)S.live.shift();\r\n const c={x,y,i:S.next++%POOL,rot:Math.random()*Math.PI*2,t0:now};S.live.push(c);S.cur=c;S.hit=[u,v];\r\n S.dirty=true;\r\n}\r\n// Walk the finger's path since the last move, dropping a trail crack every `spacing` screen px so fast drags stay continuous.\r\nfunction move(id,u,v){\r\n const p=S.drag.get(id);if(!p||S.shat)return;\r\n const [tx,ty]=[(u-p.u)*S.sx,(v-p.v)*S.sy],d=Math.hypot(tx,ty);\r\n if(!d)return;\r\n tapState=iceSecret(tapState,{type:'move',dist:Math.hypot(...S.toWorld(u,v).map((q,i)=>q-S.toWorld(p.u,p.v)[i]))},performance.now()); // screen px\r\n if(!tapState.taps.length)unkeep(performance.now());\r\n const td=d,k=S.scale;\r\n let s=p.left;\r\n for(;s<=d;s+=rand(TRAIL.spacing))spawnTrail(p,(p.u+(u-p.u)*s/d)*S.sx,(p.v+(v-p.v)*s/d)*S.sy,tx/td,ty/td,td/d);\r\n p.left=s-d;p.u=u;p.v=v;\r\n}\r\nfunction release(id){\r\n if(!S.drag.delete(id)||S.shat)return;\r\n const now=performance.now();tapState=iceSecret(tapState,{type:'release'},now);\r\n if(!tapState.taps.length)unkeep(now);else if(S.cur)S.cur.keep=true; // a tap in the chain: its crack stays\r\n if(tapState.shattered){for(const c of S.live)c.keep=true;S.THREE?shatter(now):window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'ice'}}));S.wake?.();} // the flat 2D trace has no mesh: secret at once\r\n}\r\n// Asked by the glb wrapper just before release(): true for the 3rd tap on, and for the whole shatter.\r\nfunction claims(){return !!S&&iceClaims(tapState);}\r\nfunction step(dt,now){\r\nnow=Math.max(now,performance.now()); // rAF's timestamp is the frame start, before a crack born in a slow frame (negative age = dead on arrival)\r\n if(S.shat)return stepShatter(dt,now);\r\n if(tapState.taps.length&&!S.drag.size&&now-tapState.lastRelease>SECRET.gap){tapState.taps=[];unkeep(now);} // chain timed out: the web heals\r\n const n=S.live.length+S.trail.length;\r\n if(!n)return false;\r\n const life=trailLife(S.reduced);\r\n S.live=S.live.filter(c=>c.keep||crackAlpha(now-c.t0,S.reduced)>0);\r\n S.trail=S.trail.filter(c=>now-c.t0<life);\r\n // Reduced motion: frames only change when a crack is born or dies; otherwise every frame animates.\r\n if(!S.reduced||S.dirty||S.live.length+S.trail.length!==n)redraw(now);\r\n S.dirty=false;\r\n return S.live.length+S.trail.length>0;\r\n}\r\n// Whole crystal back, chain reset. Called through the board's heal() (portal.mjs heals on every hide/show/escape).\r\nfunction heal(){if(!S)return;unshatter();S.live=[];S.trail=[];S.cur=null;tapState=newSecret();S.dirty=true;redraw(performance.now());S.wake?.();}\r\nfunction dispose(){if(S)unshatter();S=null;tapState=null;}\r\nreturn {init,setTint,press,move,release,claims,step,healSecret:heal,dispose,tapState:()=>tapState};\r\n}\r\n\r\n// fragment (3D): the ice under the glow layer darkens by its alpha, so the dark rim (which emits nothing) shows as dark.\r\nexport const ice={id:'ice',asset:'/pod/worlds/boards/ice.glb',flip:false,background:'#0b1a26',guide:{color:'#eaf7ff',alpha:.22,width:5},pattern:{left:.035,top:.025,right:.965,bottom:.78},tintTarget:'trace',\r\n fragment:'diffuseColor.rgb*=1.0-0.85*glo.a;',...iceEffect(),trace2d:iceEffect};\r\n","modules/portal/portal-board-jelly.mjs":"// Jelly board effect for portal-board-glb.mjs — Ian's green lattice-brick GLB (the \"bog swamp\r\n// bones\" asset was never made) driven to wobble like jelly. Wobble is a ring buffer of up to 6\r\n// ripples pushed on press/drag/release; vertexDisplace turns each into a decaying radial heave\r\n// (z) plus outward slosh (xy), weighted toward the front face so the back of the slab stays put.\r\n// The camera looks straight at the face, so z alone barely reads: the analytic height gradient of\r\n// dent + ripples also tilts vNormal, letting the lights (and the normal map's TBN) show the wobble.\r\n// Distance is normalised by face width (uFaceSize.x) rather than raw model units so the k/decay/\r\n// spread constants below don't depend on the GLB's arbitrary export scale.\r\n// The raised lattice rods are BONES: vertices above uBoneZ sample the field once at their grid\r\n// cell's centre (damped by follow), so each cell of rod moves as one rigid vertebra riding the\r\n// jelly. The fragment hook shades them as solid struts (ivory core, jelly-tinted rim, rim light,\r\n// brighter knuckles on the tallest nodes) and cuts the trail: a finger SPLITS the jelly (dark gash,\r\n// bright lips, normals rolling into the cut) that closes behind it, all shading, no geometry.\r\n// AGPL-3.0-or-later.\r\n\r\nconst RK=12,RW=10.5,RDECAY=1.7,RSPREAD=1.8,SLOSH=.5; // spatial freq, temporal freq (rad/s: ~2.5 wobbles in 1.5 s), time decay, spatial decay (all in \"face widths\"), lateral/heave ratio\r\nconst TAP_AMP=.065,DRAG_AMP=.03,RELEASE_AMP=.03; // ripple heave at the centre, in face widths\r\nconst DENT_AMT=2.6,DENT_RAD=1.4; // finger dent vs. DEFAULT_DISPLACE (ice): deeper, wider/softer falloff\r\nlet selectedTint=null,trail3d=null,trail2d=null;\r\nconst validTint=hex=>typeof hex==='string'&&/^#[0-9a-f]{6}$/i.test(hex);\r\nfunction tintRgb(hex,factor=1){const m=hex?.match(/^#([0-9a-f]{6})$/i);if(!m)return null;const n=parseInt(m[1],16);return `rgb(${[n>>16,(n>>8)&255,n&255].map(v=>Math.round(v*factor)).join(',')})`;}\r\nfunction writeLinearTint(color,hex){const n=parseInt((hex||'#ffffff').slice(1),16),linear=c=>{const s=c/255;return s<=.04045?s/12.92:((s+.055)/1.055)**2.4;};color.r=linear(n>>16);color.g=linear((n>>8)&255);color.b=linear(n&255);color.isColor=true;}\r\n// Ian: bones rigid + segmented, jelly wobbles (2026-09-22)\r\n// zFrac: bone threshold as a fraction of depth back->front (jelly face sits ~.89-.93, rods .94-1);\r\n// seg: segment length in face widths, with centre: a face uv (v down) the grid is centred on — the\r\n// middle rod crossing; this seg puts the straight rods (x 0/±.25, rows .162 apart) mid-cell, so\r\n// no rod is split lengthwise between two cells; follow: bones' share of the jelly motion;\r\n// ridgeAmp/ridgeFreq: per-segment sine ridge in the normal (0 = off: it banded the rods into\r\n// broken-looking beads). Shading (fragment, by undisplaced depth fraction): mask ramps over\r\n// mask[0]..mask[1], core over core[0]..core[1] (rod crest), knuckle over knuckle[0..1] (the tallest\r\n// nodes, mostly where rods cross); tint: how far the texture is pulled to the bone colours.\r\nconst BONE={zFrac:.94,seg:.0546,centre:[.5,.444],follow:.55,ridgeAmp:0,ridgeFreq:1,\r\n mask:[.925,.945],core:[.935,.965],knuckle:[.965,.985],tint:.7,\r\n coreRGB:[.95,.85,.6],rimRGB:[.24,.22,.07],rough:.45,rimLight:.25,rimLightRGB:[.55,.8,.35],knuckleGlow:.1};\r\n// Ian: the trail SPLITS the jelly and it re-heals behind the finger (2026-09-23). Face widths / s.\r\n// width: gash width at the finger; close: s until the lips meet (width -> 0, so the gash tapers\r\n// back along the trail); ease: closing curve exponent; life: s until seam + bulge are gone (points\r\n// evicted, well inside the 7 s rule); step: min spacing between trail points.\r\n// Ian 2026-09-26: \"lets make the trail shorter for the jelly\" — only the recent part of the stroke is kept (cap\r\n// points, oldest evicted: cap x step = .96 face widths) and the slit closes within close, so it's a short gash that\r\n// follows the finger. This replaces 2026-09-24's longer, slower slit.\r\n// Lips: a ridge of half-width lip on each edge (normal tilt lipTilt, glossy, lipGlow sheen) plus a\r\n// crisp edgeGlow line on the cut edge. Inside: wallRGB at the walls to deepRGB at the centre (mixed\r\n// by interior), matte (interiorRough), walls tilting wallTilt into the cut; the wall facing the key\r\n// light glows litRGB (litWall) and its edge line is brighter, the far wall stays dark.\r\n// Healing: the two lip ridges merge into one bulge (bulge x a lip, bulgeW wide, its sheen fading\r\n// with it) that wobbles at wobbleHz, dying at wobbleDecay /s, over a dark seam (half-width seam,\r\n// seamDark); all of it fades out between close and life.\r\nexport const TRAIL={\r\n // R7 (Android): cap is the GLSL uTrail array size and the fragment loop bound. At 160 it made Jelly's fragment shader\r\n // ~206 uniform vectors (the GLES 3.0 floor is 224; every other board is under ~50), dynamically indexed in a 160-pass\r\n // loop, and picking Jelly took down the phone's GPU process and with it WebGL for every board. Keep it at 32 or under\r\n // (tests/portal-board-jelly.test.mjs); uTrailBounds still skips the loop off the gash.\r\n cap:32,\r\n // R7: wider and brighter-lipped than 24 Sept so the short gash reads on a phone.\r\n step:.03,width:.055,close:.8,ease:1,life:2.3,\r\n lip:.0035,lipTilt:1,lipGlow:.45,lipRGB:[.8,1,.65],edgeGlow:1.2,edgeRGB:[.85,1,.75],\r\n wallTilt:.7,wallRGB:[.05,.15,.03],deepRGB:[.004,.025,.004],interior:.92,interiorRough:.85,litWall:.5,litRGB:[.25,.55,.12],\r\n light:[-.79,.62], // key light (portal-board-glb's sun) as a face-xy direction, y up\r\n bulge:1.2,bulgeW:.01,wobbleHz:4.5,wobbleDecay:1.6,seam:.006,seamDark:.6,\r\n};\r\nconst RIPPLE_MAX_AGE=2,DRAG_STEP_PX=30;\r\nconst F=x=>x.toFixed(4); // GLSL float literal\r\nconst V3=a=>`vec3(${a.map(F).join(',')})`;\r\n\r\n// Pure mirror of the shader's quantisation: centre of the seg-sized grid cell (corner at ox,oy)\r\n// holding (x,y).\r\nexport const segmentCentre=(x,y,seg,ox=0,oy=0)=>[(Math.floor((x-ox)/seg)+.5)*seg+ox,(Math.floor((y-oy)/seg)+.5)*seg+oy];\r\n// Pure mirror of the shader's gash: full width (face widths) at `age` s behind the finger.\r\nexport const gashWidth=(age,T=TRAIL)=>T.width*Math.max(0,1-Math.max(0,age)/T.close)**T.ease;\r\n// Trail points {u,v,t,prev}: prev is the same stroke's previous point (null = stroke start).\r\n// No-THREE helpers (edit pts in place): append, evicting the oldest past cap; drop points older\r\n// than life at time now.\r\nexport function trailPush(pts,p,cap=TRAIL.cap){pts.push(p);if(pts.length>cap)pts.splice(0,pts.length-cap);return pts;}\r\nexport function trailExpire(pts,now,life=TRAIL.life){let k=0;while(k<pts.length&&now-pts[k].t>life)k++;if(k)pts.splice(0,k);return pts;}\r\n// Pure: pack into out[i].set(u,v,birth,back) where back = how many slots behind its predecessor\r\n// sits (0: none, or evicted), so interleaved strokes from two fingers still join up.\r\nexport function trailPack(pts,out){\r\n const at=new Map(pts.map((p,i)=>[p,i]));\r\n pts.forEach((p,i)=>out[i].set(p.u,p.v,p.t,at.has(p.prev)?i-at.get(p.prev):0));\r\n return pts.length;\r\n}\r\n// Pure: axis-aligned face-uv box around the whole trail, padded by the widest the gash ever gets\r\n// (half the max width, plus a hair of slack) — marginV divided by the board's aspect since the\r\n// shader's distance test scales v by it (a non-square face reaches further in raw v than in u for\r\n// the same on-screen width). Lets the fragment shader reject a pixel nowhere near the trail with\r\n// one cheap test instead of walking the (now much bigger) point array per pixel. null when there's\r\n// no trail to bound.\r\nexport function trailBounds(pts,marginU=TRAIL.width/2+.01,marginV=marginU){\r\n if(!pts.length)return null;\r\n let minU=Infinity,minV=Infinity,maxU=-Infinity,maxV=-Infinity;\r\n for(const{u,v}of pts){if(u<minU)minU=u;if(u>maxU)maxU=u;if(v<minV)minV=v;if(v>maxV)maxV=v;}\r\n return[minU-marginU,minV-marginV,maxU+marginU,maxV+marginV];\r\n}\r\n\r\n// Dent + ripple displacement (xy slosh, z heave) at face point p, plus its height gradient.\r\n// Rides in vertexDecls: a GLSL function can't be declared inside main(), where vertexDisplace goes.\r\nconst JELLY_FIELD=`\r\nvec3 jellyField(vec2 p,out vec2 grad){\r\nvec3 d=vec3(0.0);grad=vec2(0.0);\r\nfor(int di=0;di<8;di++){if(di>=uTouchCount)break;vec4 t=uTouch[di];vec2 dv=p-(uFaceMin+vec2(t.x,1.0-t.y)*uFaceSize);float dd=length(dv),rad=uDentRadius*${F(DENT_RAD)};if(dd<rad){float s=1.0-dd/rad,f=s*s*(3.0-2.0*s),h=uDent*${F(DENT_AMT)}*t.z;d.z-=h*f*f;if(dd>1e-4)grad+=dv/dd*h*12.0*f*s*(1.0-s)/rad;}}\r\nfor(int ri=0;ri<6;ri++){vec4 r=uRipple[ri];if(r.w<=0.0)continue;float age=uTime-r.z;if(age<0.0||age>${F(RIPPLE_MAX_AGE)})continue;vec2 dv=p-(uFaceMin+vec2(r.x,1.0-r.y)*uFaceSize);float dist=length(dv),dn=dist/uFaceSize.x,env=r.w*exp(-age*${F(RDECAY)})*exp(-dn*${F(RSPREAD)}),phase=dn*${F(RK)}-age*${F(RW)},sn=sin(phase),cs=cos(phase);d.z+=env*sn;if(dist>1e-4){vec2 dir=dv/dist;d.xy+=dir*env*${F(SLOSH)}*cs*smoothstep(0.0,0.1,dn);grad+=dir*env*(${F(RK)}*cs-${F(RSPREAD)}*sn)/uFaceSize.x;}}\r\nreturn d;\r\n}\r\n`;\r\n\r\n// Bones: the whole cell shares one sample and one weight (front weight is ~1 that high, so it's\r\n// dropped to keep the segment rigid). Ridge on both in-cell axes: a straight rod sits mid-cell, so\r\n// its across term is ~0 and the along term bands it; diagonals get bands from both.\r\nconst VERTEX_DISPLACE=`\r\nbool bone=position.z>uBoneZ;vec2 q=(floor((position.xy-uGridO)/uSeg)+0.5)*uSeg+uGridO,jg;\r\nvDepthF=0.5+0.5*position.z/uHalfDepth;\r\nfloat jw=bone?uBoneFollow:smoothstep(-uHalfDepth,uHalfDepth,position.z);\r\ntransformed+=jellyField(bone?q:position.xy,jg)*jw;jg*=jw;\r\nif(bone)jg+=uRidgeAmp*sin((position.xy-q)*uRidgeFreq);\r\n#ifndef FLAT_SHADED\r\nvNormal=normalize(normalMatrix*(objectNormal-vec3(jg,0.0)));\r\n#endif\r\n`;\r\n\r\n// Runs before lighting (portal-board-glb's effect.fragment). The board is never rotated and the\r\n// camera looks straight down -z, so view-space xy = face xy (y up) and normals tilt directly.\r\nconst T=TRAIL,B=BONE;\r\nconst FRAGMENT=`\r\nfloat boneM=smoothstep(${F(B.mask[0])},${F(B.mask[1])},vDepthF),boneC=smoothstep(${F(B.core[0])},${F(B.core[1])},vDepthF),knuckle=smoothstep(${F(B.knuckle[0])},${F(B.knuckle[1])},vDepthF);\r\n{float lum=dot(diffuseColor.rgb,vec3(0.3,0.59,0.11));\r\nvec3 bc=mix(${V3(B.rimRGB)},${V3(B.coreRGB)},boneC)*(0.7+0.6*lum)*(1.0+0.25*knuckle);\r\ndiffuseColor.rgb=mix(diffuseColor.rgb,bc,boneM*${F(B.tint)});roughnessFactor=mix(roughnessFactor,${F(B.rough)},boneM);\r\nfloat fr=1.0-clamp(normal.z,0.0,1.0);totalEmissiveRadiance+=boneM*(${V3(B.coreRGB)}*${F(B.knuckleGlow)}*knuckle+${V3(B.rimLightRGB)}*${F(B.rimLight)}*fr*fr*(1.0-boneC));}\r\nif(uTrailN>0&&vPlanar.x>=uTrailBounds.x&&vPlanar.x<=uTrailBounds.z&&vPlanar.y>=uTrailBounds.y&&vPlanar.y<=uTrailBounds.w){\r\n float asp=uFaceSize.y/uFaceSize.x,best=1e9,bd=1.0,ba=1e9;vec2 P=vec2(vPlanar.x,vPlanar.y*asp),dir=vec2(0.0);\r\n for(int i=0;i<${T.cap};i++){if(i>=uTrailN)break;vec4 b=uTrail[i],a=b.w>0.5?uTrail[i-int(b.w+0.5)]:b;\r\n  if(uTime-max(a.z,b.z)>${F(T.life)})continue;\r\n  vec2 A=vec2(a.x,a.y*asp),ab=vec2(b.x,b.y*asp)-A,ap=P-A;float h=clamp(dot(ap,ab)/max(dot(ab,ab),1e-10),0.0,1.0);\r\n  vec2 off=ap-ab*h;float d=length(off),age=max(uTime-mix(a.z,b.z,h),0.0),e=d-${F(T.width/2)}*pow(max(0.0,1.0-age/${F(T.close)}),${F(T.ease)});\r\n  if(e<best){best=e;bd=d;ba=age;dir=off/max(d,1e-6);}}\r\n float open=pow(max(0.0,1.0-ba/${F(T.close)}),${F(T.ease)}),hw=${F(T.width/2)}*open,keep=(1.0-boneM)*(1.0-smoothstep(${F(T.close)},${F(T.life)},ba)),aa=fwidth(P.x);\r\n float inside=(1.0-smoothstep(hw-aa,hw+aa,bd))*smoothstep(0.0,0.15,open)*keep,dep=1.0-bd*bd/max(hw*hw,1e-10);\r\n float since=max(ba-${F(T.close)},0.0),amp=open>0.0?mix(${F(T.bulge)},1.0,open):${F(T.bulge)}*exp(-since*${F(T.wobbleDecay)})*mix(1.0,cos(since*${F(2*Math.PI*T.wobbleHz)}),uWobble);\r\n float x=(bd-hw)/mix(${F(T.bulgeW)},${F(T.lip)},open),g=exp(-x*x),edge=(1.0-smoothstep(0.0,1.5*aa,abs(bd-hw)))*keep;\r\n vec2 tilt=(dir*(${F(T.lipTilt/.4289)}*amp*x*g)-dir*${F(T.wallTilt)}*inside*bd/max(hw,1e-5))*keep;\r\n normal=normalize(normal+vec3(tilt.x,-tilt.y,0.0));\r\n float lit=max(0.0,dot(vec2(-dir.x,dir.y),vec2(${F(T.light[0])},${F(T.light[1])}))); // wall/lip whose inward normal faces the light\r\n diffuseColor.rgb=mix(diffuseColor.rgb,mix(mix(${V3(T.wallRGB)},${V3(T.deepRGB)},dep),uTrailTint,uTrailTintMix),inside*${F(T.interior)});\r\n totalEmissiveRadiance+=mix(${V3(T.litRGB)},uTrailTint,uTrailTintMix)*${F(T.litWall)}*lit*(1.0-dep)*inside*open;\r\n roughnessFactor=mix(mix(roughnessFactor,0.12,g*keep*open),${F(T.interiorRough)},inside);\r\n totalEmissiveRadiance+=mix(${V3(T.lipRGB)},uTrailTint,uTrailTintMix)*${F(T.lipGlow)}*g*keep*(1.0-inside)*abs(amp)+mix(${V3(T.edgeRGB)},uTrailTint,uTrailTintMix)*${F(T.edgeGlow)}*edge*(0.3+0.7*lit)*open;\r\n diffuseColor.rgb=mix(diffuseColor.rgb,mix(${V3(T.deepRGB)},uTrailTint,uTrailTintMix),${F(T.seamDark)}*(1.0-smoothstep(0.0,${F(T.seam)}+aa,bd))*(1.0-open)*keep);\r\n}\r\n`;\r\n\r\n// ---- Vault secret (Ian 2026-10-06): hold one finger 7 s -> bubbles spread from the finger and cluster on the bones,\r\n// the block boils, a dark door rises out of the middle and parts the jelly. Fires myr5:portal-secret {board:'jelly'}.\r\n// jellySecret is the pure reducer (ms clock): state {id,x,y,t0,skip,up,upH,done}; held() is the effective hold in ms\r\n// (a lifted finger's value drains to 0 over `subside`, so every visual below just follows it).\r\nexport const HOLD={ms:7000,drift:24,subside:1000,front:6,boil:5.5,doorFrom:6.2,door:7,sink:.7}; // seconds: front reaches every bone, boil ramp starts, door rise, lands at ms; sink = door drop per s on lift\r\nexport const held=(s,now)=>s.done?HOLD.ms:s.id==null?0:s.up!=null?Math.max(0,s.upH*(1-(now-s.up)/HOLD.subside)):Math.max(0,now-s.t0+s.skip);\r\nexport function jellySecret(s,ev,now){\r\n s=s||{};const live=s.id!=null&&s.up==null&&!s.done,mine=live&&ev.id===s.id;\r\n switch(ev.type){\r\n  case'down':return s.done||live?s:{id:ev.id,x:ev.x,y:ev.y,t0:now,skip:0,up:null,done:false};\r\n  case'move':return mine&&Math.hypot(ev.x-s.x,ev.y-s.y)>HOLD.drift?{...s,up:now,upH:held(s,now),drift:true}:s;\r\n  case'up':return mine?{...s,up:now,upH:held(s,now)}:s;\r\n  case'skip':return live?{...s,skip:s.skip+ev.ms}:s;\r\n  case'tick':return live&&held(s,now)>=HOLD.ms?{...s,done:true}:s;\r\n }\r\n return s;\r\n}\r\nconst clamp01=x=>Math.max(0,Math.min(1,x)),ease=x=>x*x*(3-2*x);\r\nfunction rng(seed){return()=>(seed=(seed*1664525+1013904223)>>>0)/4294967296;}\r\nconst NB=300,NS=36; // bubbles (bone clusters + free + boil extras), steam puffs\r\nfunction makeFx(THREE,scene,mesh,face,toWorld,boneZ){\r\n const rnd=rng(7),g=new THREE.Group(),dummy=new THREE.Object3D(),bones=[];\r\n g.frustumCulled=false;\r\n const geo=mesh.isMesh?mesh.geometry:mesh.children?.[0]?.geometry,pos=geo?.attributes?.position;\r\n if(pos&&pos.count){const st=Math.max(1,Math.floor(pos.count/400));for(let i=0;i<pos.count;i+=st)if(pos.getZ(i)>boneZ)bones.push([(pos.getX(i)+face.w/2)/face.w,(face.h/2-pos.getY(i))/face.h]);}\r\n if(!bones.length)for(let i=0;i<150;i++)bones.push([.1+.8*rnd(),.08+.84*rnd()]); // no mesh (tests): scatter\r\n const bub=Array.from({length:NB},(_,i)=>{ // 0-159 ride the bones, 160-219 free, 220+ boil extras\r\n  const b=i<160?bones[Math.floor(rnd()*bones.length)]:[.06+.88*rnd(),.05+.9*rnd()],j=i<160?.012:0;\r\n  return{u:b[0]+(rnd()-.5)*j,v:b[1]+(rnd()-.5)*j,r:3+4*rnd(),P:.8+.5*rnd(),ph:rnd(),w:rnd()*6.28,extra:i>=220?rnd():-1};});\r\n const bm=new THREE.InstancedMesh(new THREE.SphereGeometry(1,10,8),new THREE.MeshStandardMaterial({color:0xcfffb8,emissive:0x2f7a22,roughness:.1,transparent:true,opacity:.5,depthWrite:false}),NB);\r\n const sc=document.createElement('canvas');sc.width=sc.height=64;const x=sc.getContext('2d'),gr=x.createRadialGradient(32,32,0,32,32,32);gr.addColorStop(0,'rgba(235,255,225,.9)');gr.addColorStop(1,'rgba(235,255,225,0)');x.fillStyle=gr;x.fillRect(0,0,64,64);\r\n const steamTex=new THREE.CanvasTexture(sc),sm=new THREE.InstancedMesh(new THREE.PlaneGeometry(1,1),new THREE.MeshBasicMaterial({map:steamTex,transparent:true,opacity:.3,depthWrite:false}),NS);\r\n const steam=Array.from({length:NS},()=>({u:rnd(),P:1.6+1.2*rnd(),ph:rnd(),s:30+30*rnd(),w:rnd()*6.28}));\r\n bm.frustumCulled=sm.frustumCulled=false;g.add(bm,sm);\r\n // door: dark gap, gold frame, slab, flywheel; two jelly flaps part to either side\r\n const door=new THREE.Group(),m=(c,o={})=>new THREE.MeshStandardMaterial({color:c,...o}),B=new THREE.BoxGeometry(1,1,1);\r\n const add=(geom,mat,px,py,pz,sx,sy,sz)=>{const o=new THREE.Mesh(geom,mat);o.position.set(px,py,pz);o.scale.set(sx,sy,sz);door.add(o);return o;};\r\n const flapMat=new THREE.MeshStandardMaterial({color:0x7ddc4a,emissive:0x1d4a12,roughness:.15,transparent:true,opacity:.62,depthWrite:false});\r\n const flaps=[-1,1].map(()=>{const f=new THREE.Mesh(new THREE.SphereGeometry(1,16,12),flapMat);g.add(f);return f;});\r\n const parts={gap:add(B,new THREE.MeshBasicMaterial({color:0x04060a,transparent:true,opacity:.92}),0,0,0,1.1,1.06,.1),\r\n  frame:add(B,m(0xc9a24a,{metalness:.8,roughness:.35,emissive:0x2a1f05}),0,0,1,1.07,1.04,.6),\r\n  slab:add(B,m(0x34303c,{metalness:.7,roughness:.42,emissive:0x120a1c}),0,0,2,1,1,1),\r\n  wheel:add(new THREE.TorusGeometry(1,.14,8,24),m(0xd8b45c,{metalness:.8,roughness:.3,emissive:0x2a1f05}),0,0,2,1,1,1)};\r\n g.add(door);door.visible=false;scene.add(g);\r\n const sizes=()=>{const[x0,y0]=toWorld(0,0),[x1,y1]=toWorld(1,1);return{fw:x1-x0,fh:y0-y1,cx:(x0+x1)/2,cy:(y0+y1)/2-.03*(y0-y1)};};\r\n let doorP=0,lastT=0;\r\n return{bones:bones.length,get doorP(){return doorP;},reset(){doorP=0;},\r\n  update(h,calm,time){ // h seconds held, calm 0..1 post-done fade, time seconds (any clock)\r\n   const{fw,fh,cx,cy}=sizes(),[fu,fv]=S.fin,boil=ease(clamp01(h-HOLD.boil)),dmax=Math.max(.6,...bub.map(b=>Math.hypot(b.u-fu,(b.v-fv)*face.h/face.w))),keep=1-calm,Z=3,k=fw/300;\r\n   bub.forEach((b,i)=>{\r\n    const[wx,wy]=toWorld(b.u,b.v),d=Math.hypot(b.u-fu,(b.v-fv)*face.h/face.w);\r\n    const delay=b.extra>=0?HOLD.boil+b.extra:d<.5?d*8:4+(d-.5)/Math.max(.1,dmax-.5)*(HOLD.front-4),c=h-delay,P=b.P*(1-.45*boil);\r\n    let ph=(c/P+b.ph)%1;if(ph<0)ph+=1;\r\n    const grow=ease(clamp01(c/.3))*(ph<.82?1:(1-ph)/.18)*keep,r=b.r*(1+.7*boil)*grow*k;\r\n    dummy.position.set(wx+Math.sin(time*3+b.w)*3*(1+boil),wy+ph*fw*(.09+.1*boil),Z+r);dummy.scale.setScalar(Math.max(r,1e-4));dummy.updateMatrix();bm.setMatrixAt(i,dummy.matrix);});\r\n   bm.instanceMatrix.needsUpdate=true;\r\n   steam.forEach((s,i)=>{const ph=(time/s.P+s.ph)%1,a=boil*keep*Math.sin(ph*Math.PI),[sx,sy]=toWorld(s.u,.9-ph*.7);\r\n    dummy.position.set(sx+Math.sin(time*.8+s.w)*10,sy,Z+14);dummy.scale.setScalar(Math.max(s.s*(.6+ph)*k*a,1e-4));dummy.updateMatrix();sm.setMatrixAt(i,dummy.matrix);});\r\n   sm.instanceMatrix.needsUpdate=true;\r\n   const tp=ease(clamp01((h-HOLD.doorFrom)/(HOLD.door-HOLD.doorFrom))),dt=Math.max(0,Math.min(.1,time-lastT));lastT=time;doorP=Math.max(tp,doorP-HOLD.sink*dt);const p=doorP,W=fw*.36,H=fh*.44,D=14*k;door.visible=p>.01;\r\n   door.position.set(cx,cy,-D+p*D*1.8);door.scale.setScalar(Math.max(p,1e-3));\r\n   parts.gap.scale.set(W*1.1,H*1.06,.1);parts.frame.scale.set(W*1.07,H*1.04,D*.6);parts.slab.scale.set(W,H,D);parts.slab.position.z=D*.3;parts.wheel.scale.setScalar(W*.2);parts.wheel.position.z=D*.9;\r\n   flaps.forEach((f,i)=>{f.visible=p>.01;f.position.set(cx+(i?1:-1)*(W*p/2+W*.1),cy,Z+4);f.scale.set(W*.14*p+1e-3,H*.55*p+1e-3,10*k);});\r\n  },\r\n  dispose(){scene.remove?.(g);g.traverse(o=>{o.geometry?.dispose();o.material?.dispose?.();});steamTex.dispose();bm.dispose();sm.dispose();}};\r\n}\r\n\r\nlet S=null; // per-instance state; a single portal board is ever active at once\r\n\r\nfunction computeHalfDepth(THREE,mesh){\r\n const box=new THREE.Box3(),parts=mesh.isMesh?[mesh]:mesh.children;\r\n for(const m of parts){m.geometry.computeBoundingBox();box.union(m.geometry.boundingBox);}\r\n return box.max.z;\r\n}\r\n// uTime only advances on rendered frames, so a press on a sleeping board would stamp a stale time\r\n// and the ripple would be born already expired. Stamp with the live clock (epoch learnt in step).\r\nconst clock=()=>S.epoch==null?S.uniforms.uTime.value:performance.now()/1000-S.epoch;\r\nfunction pushRipple(u,v,amp){\r\n if(S.reduced)return; // reduced motion: no ripples (the gash still cuts, without the wobble)\r\n S.rippleVecs[S.nextSlot].set(u,v,clock(),amp);\r\n S.nextSlot=(S.nextSlot+1)%6;\r\n}\r\nfunction pushTrail(id,u,v,join){\r\n const prev=join?S.heads.get(id):null;\r\n if(prev&&Math.hypot(u-prev.u,(v-prev.v)*S.aspect)<TRAIL.step)return;\r\n const p={u,v,t:clock(),prev:prev||null};trailPush(S.trail,p);S.heads.set(id,p);\r\n}\r\n\r\nasync function init({THREE,mesh,material,uniforms,scene,face,toWorld,wake}){\r\n material.roughness=.28;material.metalness=0;\r\n const rim=new THREE.DirectionalLight(0x9fe8ff,1.1);rim.position.set(.7,.6,.5);scene.add(rim); // cool highlight, upper-right-front\r\n uniforms.uRipple.value=Array.from({length:6},()=>new THREE.Vector4(0,0,0,0));\r\n uniforms.uTrail.value=Array.from({length:TRAIL.cap},()=>new THREE.Vector4(0,0,0,0));uniforms.uTrailN.value=0;\r\n uniforms.uTrailBounds.value=new THREE.Vector4(0,0,0,0);\r\n const hd=computeHalfDepth(THREE,mesh),seg=BONE.seg*face.w; // glb centres the mesh: z spans -hd..hd\r\n uniforms.uHalfDepth.value=hd;uniforms.uBoneZ.value=hd*(2*BONE.zFrac-1);uniforms.uSeg.value=seg;uniforms.uBoneFollow.value=BONE.follow;\r\n uniforms.uGridO.value=new THREE.Vector2((BONE.centre[0]-.5)*face.w-seg/2,(.5-BONE.centre[1])*face.h-seg/2); // face centred on 0\r\n uniforms.uRidgeAmp.value=BONE.ridgeAmp;uniforms.uRidgeFreq.value=2*Math.PI*BONE.ridgeFreq/seg;\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;uniforms.uWobble.value=reduced?0:1;\r\n uniforms.uTrailTint.value={r:1,g:1,b:1,isColor:true};writeLinearTint(uniforms.uTrailTint.value,selectedTint||'#ffffff');uniforms.uTrailTintMix.value=selectedTint?1:0;\r\n S={uniforms,toWorld,faceW:face.w,aspect:face.h/face.w,rippleVecs:uniforms.uRipple.value,nextSlot:0,lastSpawn:new Map(),\r\n    reduced,trail:[],heads:new Map(),epoch:null,wake,sec:{},fin:[.5,.5],fxLast:0,calmAt:0,\r\n    fx:THREE.InstancedMesh&&typeof document!=='undefined'?makeFx(THREE,scene,mesh,face,toWorld,uniforms.uBoneZ.value):{update(){},reset(){},dispose(){}}};trail3d=S;\r\n globalThis.myr5JellyFF=ms=>{S&&secret({type:'skip',ms});S?.wake();};myr5JellyFF.held=()=>S&&held(S.sec,performance.now())/1000;myr5JellyFF.door=()=>S?.fx.doorP; // debug: fast-forward the hold / read it\r\n}\r\nfunction press(id,u,v){\r\n const[x,y]=S.toWorld(u,v);if(S.sec.id==null||S.sec.up!=null){S.fin=[u,v];}secret({type:'down',id,x,y});\r\n S.lastSpawn.set(id,[u,v]);\r\n pushRipple(u,v,S.faceW*TAP_AMP);\r\n pushTrail(id,u,v,false);\r\n}\r\nfunction move(id,u,v,pu,pv){\r\n {const[x,y]=S.toWorld(u,v);secret({type:'move',id,x,y});}\r\n const last=S.lastSpawn.get(id)||[pu,pv],[lx,ly]=S.toWorld(last[0],last[1]),[cx,cy]=S.toWorld(u,v);\r\n if(Math.hypot(cx-lx,cy-ly)>=DRAG_STEP_PX){pushRipple(u,v,S.faceW*DRAG_AMP);S.lastSpawn.set(id,[u,v]);}\r\n pushTrail(id,u,v,true);\r\n}\r\nfunction release(id,u,v){secret({type:'up',id});pushRipple(u,v,S.faceW*RELEASE_AMP);S.lastSpawn.delete(id);pushTrail(id,u,v,true);S.heads.delete(id);}\r\nconst secret=ev=>{S.sec=jellySecret(S.sec,ev,performance.now());};\r\n// claims(id): the finger that is (still) holding the secret; a drifted-off finger is just a stroke again.\r\nconst claims=id=>!!S&&S.sec.id===id&&S.sec.up==null;\r\nfunction step(dt,frameNow){\r\n let active=false;\r\n const ut=S.uniforms.uTime.value;S.epoch=frameNow/1000-ut;\r\n {const was=S.sec.done,now=frameNow;S.sec=jellySecret(S.sec,{type:'tick'},now);\r\n  if(S.sec.done&&!was){S.calmAt=now;if(typeof window!=='undefined')window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'jelly'}}));}\r\n  const h=held(S.sec,now)/1000,calm=S.sec.done?clamp01((now-S.calmAt)/1500):0;\r\n  if(h>0){ // finger bobble, then a harder boil: ripples around the finger / anywhere\r\n   const gap=h>HOLD.boil?140:450;if(now-S.fxLast>gap){S.fxLast=now;const b=h>HOLD.boil,a=Math.random();pushRipple(b?.1+.8*a:S.fin[0]+(a-.5)*.2,b?.1+.8*Math.random():S.fin[1]+(Math.random()-.5)*.2,S.faceW*(b?.03:.015)*(1-calm));}}\r\n  S.fx.update(h,calm,now/1000);active=h>0&&calm<1||!S.sec.done&&S.fx.doorP>.01;}\r\n for(const r of S.rippleVecs)if(r.w>0&&(ut-r.z)<RIPPLE_MAX_AGE)active=true;\r\n trailExpire(S.trail,ut);\r\n S.uniforms.uTrailN.value=trailPack(S.trail,S.uniforms.uTrail.value);\r\n const margin=TRAIL.width/2+.01,b=trailBounds(S.trail,margin,margin/S.aspect);\r\n S.uniforms.uTrailBounds.value.set(...(b||[0,0,0,0]));\r\n return active||S.trail.length>0;\r\n}\r\nfunction setJellyTint(hex,selected=true){\r\n if(selected&&!validTint(hex))return;\r\n selectedTint=selected?hex:null;\r\n if(trail3d){writeLinearTint(trail3d.uniforms.uTrailTint.value,selectedTint||'#ffffff');trail3d.uniforms.uTrailTintMix.value=selectedTint?1:0;trail3d.wake?.();}\r\n if(trail2d){trail2d.tint=selectedTint;trail2d.wake?.();}\r\n}\r\n// Back to a fresh block after the secret (portal.mjs / the glb host call this through heal): door, flaps and bubbles gone, hold forgotten.\r\nfunction healSecret(){if(!S)return;S.sec={};S.calmAt=0;S.fx.reset();S.fx.update(0,0,performance.now()/1000);S.wake?.();}\r\nfunction dispose(){S?.fx.dispose();delete globalThis.myr5JellyFF;if(S===trail3d)trail3d=null;S=null;}\r\n\r\n// R7: the gash in 2D, for the flat board: the same short trail (trailPush/trailExpire/gashWidth) as a translucent lime\r\n// slit on `paint` (drawn opaque, deeper down its middle, then faded as a whole by SLIT.alpha, so the round joins never\r\n// stack into beads) inside a light rim on `glow`, tapering to a thin healing seam behind the finger. Own state, no THREE.\r\nconst SLIT={lime:'rgb(150,240,70)',deep:'rgb(45,125,20)',deepFrac:.4,alpha:.62,rim:.008,seam:'rgb(195,255,140)',seamAlpha:.55};\r\nexport function jellyGash(){\r\n let S=null;\r\n const rgb=(c,k)=>`rgb(${c.map(v=>v*k*255|0)})`;\r\n const push=(id,u,v,join)=>{const prev=join?S.heads.get(id):null;if(prev&&Math.hypot(u-prev.u,(v-prev.v)*S.aspect)<TRAIL.step)return;const p={u,v,t:performance.now()/1000,prev:prev||null};trailPush(S.trail,p);S.heads.set(id,p);};\r\n return {\r\n  init({paint,glow,wake}){S={paint,glow,W:paint.canvas.width,H:paint.canvas.height,aspect:paint.canvas.height/paint.canvas.width,trail:[],heads:new Map(),wake,tint:selectedTint};trail2d=S;},\r\n  setTint(hex,selected=true){setJellyTint(hex,selected);},\r\n  press(id,u,v){push(id,u,v,false);},\r\n  move(id,u,v){push(id,u,v,true);},\r\n  release(id,u,v){push(id,u,v,true);S.heads.delete(id);},\r\n  step(dt,now){\r\n   const t=now/1000,{W,H}=S,pc=S.paint.ctx,gc=S.glow.ctx,live=new Set(trailExpire(S.trail,t));\r\n   pc.clearRect(0,0,W,H);gc.clearRect(0,0,W,H);pc.lineCap=gc.lineCap='round';\r\n   const segs=[...live].filter(b=>b.prev&&live.has(b.prev)).map(b=>{const a=b.prev,age=t-(a.t+b.t)/2;return {age,w:gashWidth(age)*W,x0:a.u*W,y0:a.v*H,x1:b.u*W,y1:b.v*H};});\r\n   const line=(c,s,width,{x0,y0,x1,y1})=>{c.strokeStyle=s;c.lineWidth=width;c.beginPath();c.moveTo(x0,y0);c.lineTo(x1,y1);c.stroke();};\r\n   const open=segs.filter(s=>s.w>.5);\r\n   const lime=S.tint?tintRgb(S.tint):SLIT.lime,deep=S.tint?tintRgb(S.tint,.42):SLIT.deep,seam=S.tint?tintRgb(S.tint,.82):SLIT.seam,edge=S.tint?tintRgb(S.tint,.92):rgb(TRAIL.edgeRGB,1);\r\n   for(const s of open)line(pc,lime,s.w,s);for(const s of open)line(pc,deep,s.w*SLIT.deepFrac,s); // the slit, opaque\r\n   pc.globalCompositeOperation='destination-in';pc.fillStyle=`rgba(0,0,0,${SLIT.alpha})`;pc.fillRect(0,0,W,H);pc.globalCompositeOperation='source-over'; // then translucent\r\n   for(const s of segs)if(s.w<=.5){pc.globalAlpha=SLIT.seamAlpha*(1-Math.min(1,(s.age-TRAIL.close)/(TRAIL.life-TRAIL.close)));line(pc,seam,W*TRAIL.seam,s);} // the healing tail\r\n   pc.globalAlpha=1;\r\n   for(const s of open)line(gc,edge,s.w+2*W*SLIT.rim,s); // the rim, the slit cut out of it\r\n   gc.globalCompositeOperation='destination-out';for(const s of open)line(gc,'#000',s.w,s);gc.globalCompositeOperation='source-over';\r\n   return S.trail.length>0;\r\n  },\r\n  dispose(){if(S===trail2d)trail2d=null;S=null;},\r\n };\r\n}\r\n\r\nexport const jelly={\r\n id:'jelly',asset:'/pod/worlds/boards/jelly.glb',flip:false,background:'#0d160a',ink:false, // the gash is the trace trail: no portal ink line over it\r\n guide:{color:'#c8ffb0',alpha:.12,width:4},\r\n pattern:{left:.07,top:.055,right:.93,bottom:.87}, // measured in-browser against the carved oval's extremes\r\n uniforms:{uRipple:{value:[]},uHalfDepth:{value:1},uBoneZ:{value:1},uSeg:{value:1},uGridO:{value:null},uBoneFollow:{value:1},uRidgeAmp:{value:0},uRidgeFreq:{value:0},uTrail:{value:[]},uTrailN:{value:0},uTrailBounds:{value:null},uWobble:{value:1},uTrailTint:{value:null},uTrailTintMix:{value:0}},\r\n uniformDecls:'varying float vDepthF;\\n',\r\n vertexDecls:'uniform vec4 uRipple[6];\\nuniform float uHalfDepth;\\nuniform float uBoneZ;\\nuniform float uSeg;\\nuniform vec2 uGridO;\\nuniform float uBoneFollow;\\nuniform float uRidgeAmp;\\nuniform float uRidgeFreq;\\n'+JELLY_FIELD,\r\n fragmentDecls:`uniform vec4 uTrail[${TRAIL.cap}];\\nuniform int uTrailN;\\nuniform vec4 uTrailBounds;\\nuniform float uWobble;\\nuniform vec3 uTrailTint;\\nuniform float uTrailTintMix;\\n`, // fragment only (portal-board-glb.mjs)\r\n vertexDisplace:VERTEX_DISPLACE,\r\n fragment:FRAGMENT,\r\n init,press,move,release,claims,step,healSecret,dispose,setTint:setJellyTint,tintTarget:'trace',trace2d:jellyGash,\r\n};\r\n","modules/portal/portal-board-pond.mjs":"// Pond grimoire (R21 L4) for portal-board-glb.mjs: a square, murky, brackish blue-green pond. The water is a\r\n// procedural plane (effect.build, no GLB) whose surface runs a CPU ripple height-field (the physics): it bends\r\n// the bed and the koi like the portal's liquid glass (GLASS bend + fringe + finger-lit rim, portal.mjs lensMap/\r\n// tunnelFragment), tilts the pads, and pushes the free ones. Small instanced low-poly 3D lily pads (with their\r\n// notch) and lily flowers float on top: anchor lilies rest on every vertex/base/apex/line end of every traceable\r\n// template (and along each template so the shapes read). All pads move aside around the finger and ripples, then\r\n// ease home; free ones also drift. Under the surface, blurred dark koi shadows wander (boids); a held finger slowly draws them\r\n// in, arriving face first under it; drawing leads them as a snaking school that grows as more join. 8 s with no\r\n// touch (idleMs 4 s wander + scatterMs 4 s): the fish scatter off the pond, one huge koi shadow drifts slowly across in a\r\n// random direction for bigMs 16 s, then they come back. SECRET (Achievement Vault): press and hold on the huge koi; it\r\n// pitches up toward the surface, grows and warms to koi colour over <= 2 s (its shadow shrinks on the bed), then bursts into\r\n// ripples + droplets and dispatches 'myr5:portal-secret' {board:'pond'}. Lift early and it gets bored: turns and swims off\r\n// the face (no award). pondSecret is the pure reducer. Reduced motion: still water, still fish. AGPL-3.0-or-later.\r\nimport {SHAPES,fromFrame} from './portal-shapes.mjs';\r\nimport {pointInPolygon} from './portal-cut.mjs';\r\n\r\n// Every tunable in one place. Lengths are in face widths (the pond's width = 1), speeds per second.\r\nexport const POND={\r\n aspect:16/9,          // face height / width (portal.mjs FACE.pond = 1/aspect)\r\n frame:{x0:.1,y0:.13,x1:.9,y1:.85}, // where the templates sit on the face (UV, v down)\r\n padR:.058,            // pad radius: ~100 pads side by side fill a phone screen\r\n anchorSpacing:.17,    // anchor lilies along each template, at most this far apart\r\n anchorMerge:.075,     // anchors closer than this are one lily (templates overlap a lot)\r\n anchorScale:.5,      // an along-the-line anchor pad vs a vertex one\r\n freePads:16,lilyShare:.35,padClear:2.1, // drifting pads, the share carrying a flower, min spacing (pad radii)\r\n drift:.014,driftHz:.045,                // free pads' slow wander about home\r\n spring:2.6,damping:2.2,pushR:.17,pushK:1.6,waveK:1.5,tilt:2.5, // pad physics: back home, finger push, ripple push, ripple tilt\r\n fish:14,koiLen:.24,koiAlpha:.72,swimHz:1.1,bend:.5, // koi shadows: count, length, darkness, tail beat, body undulation\r\n wanderSpeed:.06,attractSpeed:.17,schoolSpeed:.6,scatterSpeed:.4,maxForce:.9,arriveR:.14,\r\n jitter:2.4,margin:.12,sepR:.07,sepK:.6,\r\n attractR:.14,joinR:.085,leaveR:.22,gap:.075,trailStep:.012,trailCap:160, // stronger nearby attraction and a more persistent following school\r\n releaseMs:850,releaseSpeed:.52, // a short outward swim when the finger lifts\r\n idleMs:4000,scatterMs:4000,bigMs:16000,bigLen:1.3,bigAlpha:.62, // big fish starts at eight seconds total\r\n wave:{cols:64,damping:.982,press:.9,drag:.35,hold:.05,holdHz:1.6,gain:90}, // ripple height-field\r\n glass:{bend:.12,fringe:.3,rim:.55},     // refraction (face widths at full slope), dispersion, finger-lit rim glint\r\n lily:'#ffd3e4',lilyCore:'#ffcc33',shadow:[.01,.035,.03],\r\n};\r\n\r\n// --- Pure helpers (no THREE, no DOM) ------------------------------------------------------------\r\n// Seedable PRNG (mulberry32): the layout is the same every visit, and tests can drive the fish.\r\nexport function rng(seed=1){let a=seed>>>0;return()=>{a=a+0x6D2B79F5>>>0;let t=a;t=Math.imul(t^t>>>15,t|1);t^=t+Math.imul(t^t>>>7,t|61);return((t^t>>>14)>>>0)/4294967296;};}\r\nconst TAU=Math.PI*2;\r\n// Secret reducer. s={st:'idle'|'hold'|'done'|'bored',id,t0,x0,y0}. ev (pond space): {type:'down',id,x,y,phase,big:{x,y}},\r\n// {type:'move',id,x,y}, {type:'up',id}, {type:'tick'}, {type:'reset'}. Held >= riseMs => done; early lift or > drift => bored.\r\nexport const SECRET={riseMs:2000,drift:.07,hit:.35}; // drift 24 px ~ .07 face widths on a 345 px face\r\nexport function pondSecret(s,ev,now,K=POND,C=SECRET){\r\n s=s||{st:'idle',id:null};\r\n if(ev.type==='reset')return {st:'idle',id:null};\r\n if(ev.type==='down')return s.st==='idle'&&ev.phase==='big'&&Math.hypot(ev.x-ev.big.x,ev.y-ev.big.y)<=K.bigLen*C.hit?{st:'hold',id:ev.id,t0:now,x0:ev.x,y0:ev.y}:s;\r\n if(s.st!=='hold')return ev.type==='up'&&ev.id===s.id?{...s,id:null}:s;\r\n if(ev.type==='tick')return now-s.t0>=C.riseMs?{...s,st:'done'}:s;\r\n if(ev.id!==s.id)return s;\r\n if(ev.type==='move')return Math.hypot(ev.x-s.x0,ev.y-s.y0)>C.drift?{...s,st:'bored'}:s;\r\n return {...s,st:now-s.t0>=C.riseMs?'done':'bored',id:null}; // up\r\n}\r\n// Template point -> pond space (x right, y down, both in face widths: y = v * aspect).\r\nconst toPond=(tx,ty,frame,A)=>{const [u,v]=fromFrame(tx,ty,frame);return [u,v*A];};\r\n// Every vertex / base / apex / line end of every template: the oval's four extremes, every other polyline's points.\r\nexport function templateVertices(){\r\n const out=[];\r\n for(const polys of Object.values(SHAPES))for(const {points} of polys){\r\n  if(points.length>40){for(const k of [0,.25,.5,.75])out.push(points[Math.round(k*points.length)%points.length]);}\r\n  else for(const p of points)out.push(p);\r\n }\r\n return out;\r\n}\r\n// Anchor lilies [{x,y,vertex}] in pond space: a lily on every template vertex (merged when near-duplicate), then pads\r\n// along every template, spaced at most `spacing`, skipping any spot within `merge` of an anchor already placed.\r\nexport function anchorLilies(frame=POND.frame,A=POND.aspect,{spacing=POND.anchorSpacing,merge=POND.anchorMerge}={}){\r\n const out=[],near=(x,y)=>out.some(p=>Math.hypot(p.x-x,p.y-y)<merge),add=(x,y,vertex)=>{if(!near(x,y))out.push({x,y,vertex});};\r\n for(const [tx,ty] of templateVertices())add(...toPond(tx,ty,frame,A),true);\r\n for(const polys of Object.values(SHAPES))for(const {points} of polys){\r\n  const pts=points.map(([tx,ty])=>toPond(tx,ty,frame,A));if(points.length>40)pts.push(pts[0]); // close the oval\r\n  if(points.length>40){ // smooth: walk the arc length\r\n   let run=0;for(let i=1;i<pts.length;i++){const d=Math.hypot(pts[i][0]-pts[i-1][0],pts[i][1]-pts[i-1][1]);run+=d;if(run>=spacing){add(pts[i][0],pts[i][1],false);run=0;}}\r\n  }else for(let i=1;i<pts.length;i++){ // straight: even steps along each side\r\n   const [ax,ay]=pts[i-1],[bx,by]=pts[i],n=Math.ceil(Math.hypot(bx-ax,by-ay)/spacing);\r\n   for(let k=1;k<n;k++)add(ax+(bx-ax)*k/n,ay+(by-ay)*k/n,false);\r\n  }\r\n }\r\n return out;\r\n}\r\n// Free pads scattered between the anchors (rejection sampling, seeded): [{x,y}] in pond space.\r\nexport function freePads(anchors,A=POND.aspect,rand=rng(7),K=POND){\r\n const out=[],r=K.padR,min=K.padClear*r,all=[...anchors];\r\n for(let t=0;t<4000&&out.length<K.freePads;t++){\r\n  const x=r+rand()*(1-2*r),y=r+rand()*(A-2*r);\r\n  if(all.some(p=>Math.hypot(p.x-x,p.y-y)<min*(p.vertex===false?.8:1)))continue;\r\n  const p={x,y};out.push(p);all.push(p);\r\n }\r\n return out;\r\n}\r\n// Idle show by ms since the last touch: 'wander' for idleMs, then 'scatter' (fish leave), then 'big' (the huge koi\r\n// crosses), then round again (the fish return during the next wander). cycle counts shows, so each crossing differs.\r\nexport function idlePhase(ms,K=POND){\r\n const P=K.idleMs+K.scatterMs+K.bigMs,cycle=Math.floor(Math.max(0,ms)/P),m=Math.max(0,ms)-cycle*P;\r\n if(m<K.idleMs)return {phase:'wander',t:m,cycle};\r\n if(m<K.idleMs+K.scatterMs)return {phase:'scatter',t:m-K.idleMs,cycle};\r\n return {phase:'big',t:m-K.idleMs-K.scatterMs,cycle};\r\n}\r\n// The huge koi's pose t01 of the way across (pond space): a random direction per show, a line through near the\r\n// centre, starting and ending fully off the pond.\r\nexport function bigFishPose(seed,t01,A=POND.aspect,len=POND.bigLen,out={x:0,y:0,a:0}){\r\n const r=rng(seed*7919+13),a=r()*TAU,off=(r()-.5)*.5,dx=Math.cos(a),dy=Math.sin(a),R=Math.hypot(.5,A/2)+len*.6;\r\n const cx=.5-dy*off,cy=A/2+dx*off;out.x=cx+dx*R*(2*t01-1);out.y=cy+dy*R*(2*t01-1);out.a=a;return out;\r\n}\r\n// Steer (Reynolds seek with arrival) f={x,y,vx,vy} toward (tx,ty): desired speed max, slowing inside arrive; the\r\n// change of velocity is capped at force per second. Integrates position. Returns the distance left.\r\nexport function steer(f,tx,ty,max,force,arrive,dt){\r\n const dx=tx-f.x,dy=ty-f.y,d=Math.hypot(dx,dy)||1e-9,sp=d<arrive?max*d/arrive:max;\r\n let ax=dx/d*sp-f.vx,ay=dy/d*sp-f.vy;const a=Math.hypot(ax,ay),cap=force*dt;if(a>cap){ax*=cap/a;ay*=cap/a;}\r\n f.vx+=ax;f.vy+=ay;f.x+=f.vx*dt;f.y+=f.vy*dt;return d;\r\n}\r\n// The finger's trail as a ring buffer in pond space; pointAt walks back `dist` along it from the newest point.\r\nexport function makeTrail(cap=POND.trailCap){return {x:new Float32Array(cap),y:new Float32Array(cap),n:0,head:-1,cap};}\r\nexport function trailPush(T,x,y,step=POND.trailStep){\r\n if(T.n&&Math.hypot(x-T.x[T.head],y-T.y[T.head])<step)return false;\r\n T.head=(T.head+1)%T.cap;T.x[T.head]=x;T.y[T.head]=y;T.n=Math.min(T.cap,T.n+1);return true;\r\n}\r\nexport function trailAt(T,dist,out){\r\n let i=T.head,x=T.x[i],y=T.y[i],left=dist;\r\n for(let k=1;k<T.n;k++){const j=(T.head-k+T.cap)%T.cap,d=Math.hypot(T.x[j]-x,T.y[j]-y);if(d>=left){const s=left/d;out.x=x+(T.x[j]-x)*s;out.y=y+(T.y[j]-y)*s;return out;}left-=d;x=T.x[j];y=T.y[j];}\r\n out.x=x;out.y=y;return out;\r\n}\r\n// The school: koi shadows in pond space with their swim state.\r\nexport function makeFish(n=POND.fish,A=POND.aspect,rand=Math.random){\r\n return Array.from({length:n},()=>({x:.15+.7*rand(),y:A*(.1+.8*rand()),vx:0,vy:0,a:rand()*TAU,w:rand()*TAU,phase:rand()*TAU,member:-1}));\r\n}\r\nconst P0={x:0,y:0};\r\n// One step of every fish. S={fish,A,rand,touch:{x,y}|null,lastTouch(ms),trail,members}. Sets S.phase.\r\nexport function stepFish(S,dt,now,K=POND){\r\n const {fish,A,touch}=S,idle=touch?null:idlePhase(now-S.lastTouch,K),away=idle&&idle.phase!=='wander',releasing=!touch&&now<(S.releaseUntil||0);\r\n S.phase=touch?'touch':releasing?'release':idle.phase;\r\n for(const f of fish){\r\n  let tx,ty,max,arrive=K.arriveR,face=false;\r\n  if(touch){\r\n   if(f.member>=0){trailAt(S.trail,f.member*K.gap,P0);if(Math.hypot(f.x-P0.x,f.y-P0.y)>K.leaveR)f.member=-1;}\r\n   const fingerDist=Math.hypot(f.x-touch.x,f.y-touch.y);\r\n   if(f.member<0&&fingerDist<K.joinR)f.member=S.members++;\r\n   if(f.member>=0){trailAt(S.trail,f.member*K.gap,P0);tx=P0.x;ty=P0.y;max=K.schoolSpeed;arrive=K.arriveR*.6;}\r\n   else if(fingerDist<K.attractR){tx=touch.x;ty=touch.y;max=K.attractSpeed;}\r\n   if(tx!==undefined)face=Math.hypot(tx-f.x,ty-f.y)<arrive;\r\n  }else if(releasing&&f.release){ // only fish that noticed the finger fan out\r\n   const dx=f.x-S.releaseX,dy=f.y-S.releaseY,d=Math.hypot(dx,dy)||1;\r\n   tx=f.x+(dx||Math.cos(f.a)*.01)/d;ty=f.y+(dy||Math.sin(f.a)*.01)/d;max=K.releaseSpeed;arrive=.01;\r\n  }else if(away){ // swim straight out, away from the middle\r\n   let ox=f.x-.5,oy=f.y-A/2;const o=Math.hypot(ox,oy)||1,R=Math.hypot(.5,A/2)+.25;ox/=o;oy/=o;tx=.5+ox*R;ty=A/2+oy*R;max=K.scatterSpeed;arrive=.01;\r\n  }\r\n  if(tx===undefined){ // wander: a jittered heading, turned back toward the pond when near or past its edge\r\n   f.w+=(S.rand()-.5)*K.jitter*dt*4;\r\n   const m=K.margin,out=f.x<m||f.x>1-m||f.y<m||f.y>A-m;\r\n   if(out){tx=.5+(f.x<.5?-.1:.1);ty=A/2;max=K.wanderSpeed*(f.x<-.05||f.x>1.05||f.y<-.05||f.y>A+.05?2.5:1.2);}\r\n   else{const h=Math.atan2(f.vy,f.vx)||f.a;tx=f.x+Math.cos(h)*.25+Math.cos(f.w)*.15;ty=f.y+Math.sin(h)*.25+Math.sin(f.w)*.15;max=K.wanderSpeed;}\r\n   arrive=.01;\r\n  }\r\n  // separation: koi keep a body's width apart (all n², n is small)\r\n  for(const g of fish)if(g!==f){const dx=f.x-g.x,dy=f.y-g.y,d=Math.hypot(dx,dy);if(d>1e-6&&d<K.sepR){const k=K.sepK*(1-d/K.sepR)*dt;f.vx+=dx/d*k;f.vy+=dy/d*k;}}\r\n  steer(f,tx,ty,max,K.maxForce,arrive,dt);\r\n  // heading follows the velocity; arrived under the finger, it turns to face the finger (face first)\r\n  const sp=Math.hypot(f.vx,f.vy),want=face?Math.atan2(touch.y-f.y,touch.x-f.x):sp>.004?Math.atan2(f.vy,f.vx):f.a;\r\n  let da=want-f.a;da-=TAU*Math.round(da/TAU);f.a+=da*Math.min(1,dt*(face?2.5:4));\r\n  f.phase+=dt*TAU*K.swimHz*(.5+Math.min(2,sp/K.wanderSpeed)*.5);\r\n }\r\n if(touch){let n=0;for(const f of fish.filter(f=>f.member>=0).sort((a,b)=>a.member-b.member))f.member=n++;S.members=n;}\r\n}\r\n// Pointer state for stepFish: the newest finger leads.\r\nexport function fishTouch(S,x,y,now){if(!S.touch){S.trail.n=0;S.trail.head=-1;S.members=0;for(const f of S.fish){f.member=-1;f.release=false;}}S.releaseUntil=0;S.touch=S.touch||{x,y};S.touch.x=x;S.touch.y=y;trailPush(S.trail,x,y);S.lastTouch=now;}\r\nexport function fishRelease(S,now){if(S.touch){S.releaseX=S.touch.x;S.releaseY=S.touch.y;S.releaseUntil=now+POND.releaseMs;}S.touch=null;S.members=0;for(const f of S.fish){f.release=f.member>=0||Math.hypot(f.x-S.releaseX,f.y-S.releaseY)<POND.attractR;f.member=-1;}S.lastTouch=now;}\r\n\r\n// --- Ripple height-field (classic two-buffer wave), pure typed arrays ---------------------------------------\r\nexport function makeWaves(cols,rows){return {cols,rows,cur:new Float32Array(cols*rows),prev:new Float32Array(cols*rows),energy:0};}\r\nexport function disturb(W,x,y,amp){ // x,y in 0..1 face UV\r\n const cx=Math.round(x*(W.cols-1)),cy=Math.round(y*(W.rows-1));\r\n for(let j=-2;j<=2;j++)for(let i=-2;i<=2;i++){const X=cx+i,Y=cy+j;if(X<1||Y<1||X>=W.cols-1||Y>=W.rows-1)continue;W.cur[Y*W.cols+X]-=amp*Math.exp(-(i*i+j*j)/2);}\r\n W.energy=Math.max(W.energy,Math.abs(amp));\r\n}\r\nexport function stepWaves(W,damping){\r\n const {cols,rows}=W;let {cur,prev}=W,e=0;\r\n for(let y=1;y<rows-1;y++)for(let x=1,i=y*cols+1;x<cols-1;x++,i++){const v=((cur[i-1]+cur[i+1]+cur[i-cols]+cur[i+cols])*.5-prev[i])*damping;prev[i]=v;const a=v<0?-v:v;if(a>e)e=a;}\r\n W.prev=cur;W.cur=prev;W.energy=e;return e;\r\n}\r\n// Surface slope at x,y (face UV) in height per cell: [dh/du, dh/dv] (into out).\r\nexport function slopeAt(W,x,y,out){const X=Math.min(W.cols-2,Math.max(1,Math.round(x*(W.cols-1)))),Y=Math.min(W.rows-2,Math.max(1,Math.round(y*(W.rows-1)))),i=Y*W.cols+X,c=W.cur;out[0]=(c[i+1]-c[i-1])*.5;out[1]=(c[i+W.cols]-c[i-W.cols])*.5;return out;}\r\n\r\n// --- Shaders --------------------------------------------------------------------------------------------\r\nconst F=x=>(+x).toFixed(4),V3=a=>`vec3(${a.map(F).join(',')})`,G=POND.glass;\r\n// Murky bed: deep blue-green, brackish olive silt, darker in the deep middle; a dark mossy stone lip makes it a square pond.\r\nconst WATER_DECLS=`uniform sampler2D uWave;uniform vec4 uFinger;\r\nfloat pH(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nfloat pN(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.0-2.0*f);return mix(mix(pH(i),pH(i+vec2(1.0,0.0)),f.x),mix(pH(i+vec2(0.0,1.0)),pH(i+1.0),f.x),f.y);}\r\nvec3 pondBed(vec2 p,float asp){\r\n float n=pN(p*5.0+vec2(uTime*.02,0.0))*.62+pN(p*13.0-vec2(0.0,uTime*.035))*.38;\r\n vec3 c=mix(vec3(.008,.040,.062),vec3(.040,.135,.150),n);\r\n c=mix(c,vec3(.090,.130,.075),smoothstep(.62,.92,n)*.45);\r\n float deep=1.0-smoothstep(.0,.55,length((p-vec2(.5,asp*.5))*vec2(1.0,.62)));\r\n return c*(1.0-.45*deep);\r\n}\r\n`;\r\nconst WATER_FRAGMENT=`{\r\n float asp=uFaceSize.y/uFaceSize.x;vec2 P=vec2(vPlanar.x,vPlanar.y*asp);\r\n vec4 wv=texture2D(uWave,vPlanar);vec2 g=(wv.rg-0.5)*2.0;float slope=length(g);\r\n vec2 off=g*${F(G.bend)};\r\n vec3 col=slope>.02?vec3(pondBed(P+off*${F(1-G.fringe)},asp).r,pondBed(P+off,asp).g,pondBed(P+off*${F(1+G.fringe)},asp).b):pondBed(P+off,asp);\r\n vec2 L=normalize(uFinger.xy*vec2(1.0,asp)-P+vec2(1e-4));float lit=max(dot(g/max(slope,1e-4),L),0.0);\r\n totalEmissiveRadiance+=vec3(.75,.95,.9)*${F(G.rim)}*pow(lit,1.4)*smoothstep(.04,.5,slope)*(.35+.65*uFinger.z);\r\n totalEmissiveRadiance+=vec3(.6,.8,.75)*.05*smoothstep(.15,.6,slope);\r\n float e=min(min(vPlanar.x,1.0-vPlanar.x),min(vPlanar.y,1.0-vPlanar.y)*asp),lip=1.0-smoothstep(.018,.024,e);\r\n col*=.55+.45*smoothstep(.02,.09,e);\r\n vec3 stone=mix(vec3(.10,.115,.09),vec3(.20,.21,.16),pN(P*40.0))*(.75+.5*smoothstep(.0,.02,e));\r\n diffuseColor.rgb=mix(col,stone,lip);roughnessFactor=mix(.16,.85,lip);metalnessFactor=0.0;\r\n normal=normalize(normal+vec3(-g.x,g.y,0.0)*1.6*(1.0-lip));\r\n vec4 pg=texture2D(uPaint,vPlanar);totalEmissiveRadiance+=pg.rgb*pg.a*.8*(1.0-lip);\r\n}`;\r\n// Koi shadows: a segmented strip (head at +x) whose tail sways (phase travels head->tail), shifted by the same water\r\n// slope as the bed (the refraction), drawn as a dark blurred silhouette under the pads.\r\nconst FISH_VS=`attribute vec4 aFish;uniform sampler2D uWave;uniform vec4 uFace;uniform float uRefract;varying vec2 vUv;varying float vA;varying float vC;\r\nvoid main(){\r\n vec3 p=position;float t=0.5-p.x;\r\n p.y+=sin(aFish.x-t*4.5)*aFish.z*t*t*.32;p.x+=(cos(aFish.x-t*4.5)-1.0)*aFish.z*t*.03;\r\n vec4 w=instanceMatrix*vec4(p,1.0);\r\n vec2 uv=vec2((w.x-uFace.x)/uFace.z,(-w.y-uFace.y)/uFace.w);\r\n vec2 g=(texture2D(uWave,clamp(uv,0.0,1.0)).rg-0.5)*2.0;w.xy+=vec2(g.x,-g.y)*uRefract;\r\n vA=aFish.y;vC=aFish.w;vUv=vec2(position.x+0.5,position.y/.5+0.5);\r\n gl_Position=projectionMatrix*modelViewMatrix*w;\r\n}`;\r\nconst FISH_FS=`uniform sampler2D uKoi;uniform vec3 uShadow;uniform float uFade;varying vec2 vUv;varying float vA;varying float vC;\r\nvoid main(){float t=texture2D(uKoi,vUv).a,a=mix(t,smoothstep(.14,.42,t),vC)*vA*uFade;if(a<.004)discard;\r\n float p=sin(vUv.x*11.0+1.0)*.5+sin(vUv.x*4.0+vUv.y*9.0)*.5; // the risen koi: crisp edge, orange with cream patches\r\n vec3 koi=mix(vec3(.95,.42,.12),vec3(.98,.92,.82),smoothstep(.15,.4,p));\r\n koi*=.7+.3*(1.0-abs(vUv.y-.5)*1.8);koi=mix(koi,vec3(.04,.03,.03),max(smoothstep(.03,.015,length(vec2(vUv.x-.8,abs(vUv.y-.5)-.1))),0.0)*step(.6,vC));\r\n gl_FragColor=vec4(mix(uShadow,koi,vC),a);}`;\r\n\r\n// --- Procedural low-poly meshes --------------------------------------------------------------------------\r\nfunction padGeometry(THREE,rand){\r\n const seg=13,notch=.55,pos=[0,0,.05],idx=[];\r\n for(let i=0;i<=seg;i++){const a=notch/2+(TAU-notch)*i/seg;\r\n  pos.push(Math.cos(a)*.55,Math.sin(a)*.55,.03+rand()*.04);\r\n  pos.push(Math.cos(a)*(.97+rand()*.06),Math.sin(a)*(.97+rand()*.06),.1+rand()*.08);}\r\n for(let i=0;i<seg;i++){const a=1+2*i,b=a+1,c=a+2,d=a+3;idx.push(0,a,c, a,b,d, a,d,c);}\r\n idx.push(0,1,2);idx.push(0,2*seg+2,2*seg+1); // the notch's two cut edges stay closed to the centre\r\n const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(pos,3));g.setIndex(idx);\r\n const flat=g.toNonIndexed();flat.computeVertexNormals();g.dispose();return flat;\r\n}\r\nfunction lilyGeometry(THREE){\r\n const pos=[],col=[],tri=(a,b,c,ca,cb,cc)=>{pos.push(...a,...b,...c);col.push(...ca,...cb,...cc);};\r\n const base=[1,.82,.88],tip=[1,1,1],mid=[1,.93,.95];\r\n for(const L of [{n:8,len:1,lift:.45,w:.36,rot:0},{n:6,len:.72,lift:.8,w:.34,rot:.4}]){\r\n  for(let i=0;i<L.n;i++){\r\n   const a=L.rot+TAU*i/L.n,c=Math.cos(a),s=Math.sin(a),at=(r,da,z)=>[Math.cos(a+da)*r,Math.sin(a+da)*r,z];\r\n   const o=[c*.06,s*.06,.1],t=[c*L.len,s*L.len,.1+L.lift*L.len],l=at(L.len*.5,L.w,.1+L.lift*L.len*.35),r=at(L.len*.5,-L.w,.1+L.lift*L.len*.35),m=at(L.len*.55,0,.06+L.lift*L.len*.42);\r\n   tri(o,r,m,base,mid,mid);tri(o,m,l,base,mid,mid);tri(r,t,m,mid,tip,mid);tri(m,t,l,mid,tip,mid);\r\n  }\r\n }\r\n const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(pos,3));g.setAttribute('color',new THREE.Float32BufferAttribute(col,3));g.computeVertexNormals();return g;\r\n}\r\nfunction coreGeometry(THREE){const g=new THREE.ConeGeometry(.2,.32,6,1);g.rotateX(Math.PI/2);g.translate(0,0,.32);return g;}\r\n// The koi silhouette (alpha only, head right), blurred by the shadow trick (works where ctx.filter doesn't).\r\nfunction koiTexture(THREE){\r\n const W=256,H=128,c=document.createElement('canvas');c.width=W;c.height=H;const x=c.getContext('2d');\r\n x.translate(-W*2,0);x.shadowOffsetX=W*2;x.shadowColor='#000';x.shadowBlur=9;x.fillStyle='#000';\r\n x.beginPath();x.ellipse(150,64,74,20,0,0,TAU);x.fill(); // body\r\n x.beginPath();x.ellipse(205,64,22,15,0,0,TAU);x.fill(); // head\r\n x.beginPath();x.moveTo(84,64);x.quadraticCurveTo(48,52,22,30);x.quadraticCurveTo(40,64,22,98);x.quadraticCurveTo(48,76,84,64);x.fill(); // tail\r\n for(const s of [-1,1]){x.beginPath();x.moveTo(172,64+s*14);x.quadraticCurveTo(160,64+s*44,138,64+s*42);x.quadraticCurveTo(150,64+s*26,160,64+s*12);x.fill();} // pectoral fins\r\n for(const s of [-1,1]){x.beginPath();x.moveTo(108,64+s*12);x.quadraticCurveTo(98,64+s*30,86,64+s*28);x.quadraticCurveTo(96,64+s*18,100,64+s*8);x.fill();} // pelvic fins\r\n const t=new THREE.CanvasTexture(c);t.colorSpace=THREE.NoColorSpace;return t;\r\n}\r\n\r\n// --- The effect -------------------------------------------------------------------------------------------\r\nlet S=null; // one portal board at a time\r\nconst DROPS=72;\r\nconst reducedMotion=()=>typeof matchMedia==='function'&&matchMedia('(prefers-reduced-motion: reduce)').matches;\r\nconst validTint=hex=>typeof hex==='string'&&/^#[0-9a-f]{6}$/i.test(hex);\r\n\r\nfunction dropTexture(THREE){const c=document.createElement('canvas');c.width=c.height=32;const x=c.getContext('2d'),g=x.createRadialGradient(16,16,2,16,16,15);g.addColorStop(0,'#fff');g.addColorStop(.6,'rgba(255,255,255,.85)');g.addColorStop(1,'rgba(255,255,255,0)');x.fillStyle=g;x.fillRect(0,0,32,32);return new THREE.CanvasTexture(c);}\r\nfunction build(THREE){\r\n const A=POND.aspect,geo=new THREE.PlaneGeometry(1,A,16,28);\r\n return new THREE.Mesh(geo,new THREE.MeshStandardMaterial({color:0x0b2626,roughness:.2,metalness:0}));\r\n}\r\n\r\nfunction init({THREE,scene,mesh,uniforms,toWorld,wake}){\r\n const K=POND,A=K.aspect,rand=rng(21),reduced=reducedMotion();\r\n // Water: the ripple field, packed as slope (rg) + height (b) into a small texture the water and the koi both read.\r\n const cols=K.wave.cols,rows=Math.round(cols*A),waves=makeWaves(cols,rows),data=new Uint8Array(cols*rows*4).fill(128);\r\n const waveTex=new THREE.DataTexture(data,cols,rows,THREE.RGBAFormat,THREE.UnsignedByteType);\r\n waveTex.magFilter=waveTex.minFilter=THREE.LinearFilter;waveTex.needsUpdate=true;\r\n uniforms.uWave.value=waveTex;uniforms.uFinger.value=new THREE.Vector4(.5,.3,0,0);\r\n mesh.material&&(mesh.material.roughness=.2);\r\n\r\n // Pads and lilies: shape anchors first, then the freely drifting ones.\r\n const anchors=anchorLilies(K.frame,A),free=freePads(anchors,A,rng(7),K),pads=[...anchors.map(p=>({...p,anchor:true})),...free.map(p=>({...p,anchor:false,vertex:false}))];\r\n const lr=rng(11);\r\n for(const p of pads){p.hx=p.x;p.hy=p.y;p.vx=p.vy=0;p.rot=lr()*TAU;p.s=(p.anchor&&!p.vertex?K.anchorScale:.85+lr()*.3);p.seed=lr()*TAU;p.lily=p.vertex||(!p.anchor&&lr()<K.lilyShare);p.hidden=false;}\r\n const lilies=pads.filter(p=>p.lily);\r\n const padMat=new THREE.MeshStandardMaterial({flatShading:true,roughness:.62,metalness:0});\r\n const padMesh=new THREE.InstancedMesh(padGeometry(THREE,rng(3)),padMat,pads.length);\r\n const green=new THREE.Color();pads.forEach((p,i)=>{green.setHSL(.27+lr()*.06,.42+lr()*.15,.2+lr()*.08);padMesh.setColorAt(i,green);});\r\n const lilyMat=new THREE.MeshStandardMaterial({vertexColors:true,flatShading:true,roughness:.5,side:THREE.DoubleSide,emissive:0x2a1c22});\r\n const lilyMesh=new THREE.InstancedMesh(lilyGeometry(THREE),lilyMat,lilies.length);\r\n const coreMesh=new THREE.InstancedMesh(coreGeometry(THREE),new THREE.MeshStandardMaterial({color:K.lilyCore,flatShading:true,roughness:.5,emissive:0x332200}),lilies.length);\r\n for(const m of [padMesh,lilyMesh,coreMesh]){m.frustumCulled=false;m.instanceMatrix.setUsage(THREE.DynamicDrawUsage);scene.add(m);}\r\n\r\n // Koi shadows (+2: the huge one and its bed shadow while it rises), one instanced strip.\r\n const n=K.fish,fishGeo=new THREE.PlaneGeometry(1,.5,12,1),aFish=new THREE.InstancedBufferAttribute(new Float32Array((n+2)*4),4);\r\n aFish.setUsage(THREE.DynamicDrawUsage);fishGeo.setAttribute('aFish',aFish);\r\n const koi=koiTexture(THREE),fishMat=new THREE.ShaderMaterial({vertexShader:FISH_VS,fragmentShader:FISH_FS,transparent:true,depthWrite:false,\r\n  uniforms:{uKoi:{value:koi},uWave:uniforms.uWave,uFace:{value:new THREE.Vector4(0,0,1,1)},uRefract:{value:0},uShadow:{value:new THREE.Vector3(...K.shadow)},uFade:{value:1}}});\r\n const fishMesh=new THREE.InstancedMesh(fishGeo,fishMat,n+2);fishMesh.frustumCulled=false;fishMesh.instanceMatrix.setUsage(THREE.DynamicDrawUsage);fishMesh.renderOrder=1;scene.add(fishMesh);\r\n\r\n const dropPos=new Float32Array(DROPS*3),dropGeo=new THREE.BufferGeometry();dropGeo.setAttribute('position',new THREE.BufferAttribute(dropPos,3));\r\n const dropTex=dropTexture(THREE),dropMat=new THREE.PointsMaterial({color:0xe8fbff,map:dropTex,size:15,sizeAttenuation:false,transparent:true,depthWrite:false}),dropMesh=new THREE.Points(dropGeo,dropMat);dropMesh.frustumCulled=false;dropMesh.visible=false;dropMesh.renderOrder=3;scene.add(dropMesh);\r\n const foam=new THREE.Mesh(new THREE.PlaneGeometry(1,1),new THREE.MeshBasicMaterial({map:dropTex,transparent:true,depthWrite:false,opacity:0}));foam.visible=false;foam.renderOrder=4;scene.add(foam);\r\n const fishS={fish:makeFish(n,A,rng(5)),A,rand:rng(9),touch:null,lastTouch:performance.now(),trail:makeTrail(K.trailCap),members:0,phase:'wander'};\r\n S={foam,dropTex,sec:{st:'idle',id:null},an:null,drops:[],dropPos,dropGeo,dropMat,dropMesh,THREE,K,A,toWorld,wake,uniforms,reduced,waves,waveTex,data,pads,lilies,padMesh,lilyMesh,coreMesh,fishMesh,fishMat,aFish,koi,fishS,\r\n  pointers:new Map(),lilyColor:new THREE.Color(K.lily),m:new THREE.Matrix4(),q:new THREE.Quaternion(),e:new THREE.Euler(),v:new THREE.Vector3(),sc:new THREE.Vector3(),\r\n  born:performance.now(),lead:null,slope:[0,0],big:{x:0,y:0,a:0},bigSeed:Math.floor(Math.random()*1e6),fade:1,fadeTo:1,cutPoly:null,lastNow:performance.now(),dirty:true};\r\n setLilyColor(K.lily);\r\n place(0,performance.now());\r\n}\r\n\r\nfunction setLilyColor(hex){if(!S)return;S.lilyColor.set(hex);for(let i=0;i<S.lilies.length;i++)S.lilyMesh.setColorAt(i,S.lilyColor);if(S.lilyMesh.instanceColor)S.lilyMesh.instanceColor.needsUpdate=true;S.wake?.();}\r\nlet selectedTint=null;\r\nfunction setTint(hex,selected=true){if(selected&&!validTint(hex))return;selectedTint=selected?hex:null;setLilyColor(selectedTint||POND.lily);}\r\n\r\n// Writes every instance's matrix: pads ride the ripples (tilt), koi sway, the huge koi crosses.\r\nfunction place(dt,now){\r\n const {K,A,toWorld,pads,lilies,padMesh,lilyMesh,coreMesh,fishMesh,aFish,m,q,e,v,sc,slope,waves}=S;\r\n const [ox,oy]=toWorld(0,0),[x1]=toWorld(1,0),px=x1-ox; // face width in world px\r\n const put=(x,y,z,rx,ry,rz,s,s2=s)=>{e.set(rx,ry,rz);q.setFromEuler(e);v.set(ox+x*px,oy-y*px,z);sc.set(s,s2,s);m.compose(v,q,sc);return m;};\r\n let li=0;\r\n pads.forEach((p,i)=>{\r\n  slopeAt(waves,p.x,p.y/A,slope);const tx=-slope[1]*K.tilt,ty=slope[0]*K.tilt,r=K.padR*px*p.s*(p.hidden?0:1);\r\n  padMesh.setMatrixAt(i,put(p.x,p.y,2+i*.03,tx,ty,p.rot,r));\r\n  if(p.lily){lilyMesh.setMatrixAt(li,put(p.x,p.y,2.4+i*.03,tx,ty,p.rot+p.seed,r*.6));coreMesh.setMatrixAt(li,m);li++;}\r\n });\r\n padMesh.instanceMatrix.needsUpdate=lilyMesh.instanceMatrix.needsUpdate=coreMesh.instanceMatrix.needsUpdate=true;\r\n const fish=S.fishS.fish,ph=S.fishS.phase,arr=aFish.array,bend=S.reduced?0:K.bend;if(ph==='big'&&!S.bigSent){S.bigSent=1;dispatchEvent(new CustomEvent('myr5:vault-bump',{detail:{counter:'pond-fish'}}));}\r\n fish.forEach((f,i)=>{fishMesh.setMatrixAt(i,put(f.x,f.y,.6+i*.01,0,0,-f.a,K.koiLen*px));arr[4*i]=f.phase;arr[4*i+1]=K.koiAlpha;arr[4*i+2]=bend;});\r\n // The huge koi: only while the fish are away.\r\n const n=fish.length,idle=ph==='big'&&S.sec.st==='idle'?idlePhase(now-S.fishS.lastTouch,K):null,b=S.an;\r\n arr[4*n+3]=arr[4*n+7]=0;arr[4*n+5]=0;\r\n if(b){\r\n  e.set(0,-b.pitch,-b.a,'ZYX');q.setFromEuler(e);e.order='XYZ';v.set(ox+b.x*px,oy-b.y*px,b.z*px+.4);sc.set(b.s*px,b.s*px,b.s*px);m.compose(v,q,sc);fishMesh.setMatrixAt(n,m);\r\n  arr[4*n]=now/1000*TAU*.35*(1+6*b.e);arr[4*n+1]=b.alpha;arr[4*n+2]=bend*(.7+.8*b.e);arr[4*n+3]=b.mix;\r\n  fishMesh.setMatrixAt(n+1,put(b.sx,b.sy,.35,0,0,-b.sa,b.ss*px));arr[4*n+4]=arr[4*n];arr[4*n+5]=b.sAlpha;arr[4*n+6]=bend*.7;\r\n }else if(idle){const b=bigFishPose(S.bigSeed+idle.cycle,idle.t/K.bigMs,A,K.bigLen,S.big),fadeIn=Math.min(1,idle.t/1500,(K.bigMs-idle.t)/1500);fishMesh.setMatrixAt(n,put(b.x,b.y,.4,0,0,-b.a,K.bigLen*px));arr[4*n]=now/1000*TAU*.35;arr[4*n+1]=.8*Math.max(0,fadeIn)*(.92+.08*Math.sin(now/300));arr[4*n+2]=bend*.7;arr[4*n+3]=.6;}\r\n else arr[4*n+1]=0;\r\n fishMesh.instanceMatrix.needsUpdate=true;aFish.needsUpdate=true;\r\n S.fishMat.uniforms.uFace.value.set(ox,-oy,px,px*A);S.fishMat.uniforms.uRefract.value=K.glass.bend*px*2;\r\n}\r\n\r\nexport function stepPads(state,dt,t){\r\n const {K,A,pads,pointers,waves,slope}=state;\r\n for(const p of pads){\r\n  if(p.hidden)continue;\r\n  const drift=p.anchor?0:K.drift;\r\n  const hx=p.hx+Math.sin(t*K.driftHz*TAU+p.seed)*drift,hy=p.hy+Math.cos(t*K.driftHz*TAU*.8+p.seed*1.7)*drift;\r\n  let fx=(hx-p.x)*K.spring-p.vx*K.damping,fy=(hy-p.y)*K.spring-p.vy*K.damping;\r\n  for(const f of pointers.values()){\r\n   let dx=p.x-f.x,dy=p.y-f.y,d=Math.hypot(dx,dy);\r\n   if(d<K.pushR){\r\n    // Even a pad directly under the fingertip needs a direction to move aside.\r\n    if(d<1e-5){dx=Math.cos(p.seed);dy=Math.sin(p.seed);d=1;}\r\n    const distance=Math.hypot(p.x-f.x,p.y-f.y),k=K.pushK*(1-distance/K.pushR)**2;\r\n    fx+=dx/d*k;fy+=dy/d*k;\r\n   }\r\n  }\r\n  slopeAt(waves,p.x,p.y/A,slope);fx-=slope[0]*K.waveK;fy-=slope[1]*K.waveK;\r\n  p.vx+=fx*dt;p.vy+=fy*dt;p.x+=p.vx*dt;p.y+=p.vy*dt;p.rot+=(p.vx-p.vy)*dt*2;\r\n }\r\n}\r\n\r\nfunction stepWater(t){\r\n const {K,waves,pointers}=S;\r\n for(const f of pointers.values()){disturb(waves,f.x,f.y/S.A,f.moved?K.wave.drag:K.wave.hold*Math.sin(t*TAU*K.wave.holdHz));f.moved=false;}\r\n const e=stepWaves(waves,K.wave.damping);\r\n if(e>1e-4||S.dirty){\r\n  const {cur,cols,rows}=waves,d=S.data,gain=K.wave.gain;\r\n  for(let y=0;y<rows;y++)for(let x=0;x<cols;x++){\r\n   const i=y*cols+x,l=cur[x>0?i-1:i],r=cur[x<cols-1?i+1:i],u=cur[y>0?i-cols:i],dn=cur[y<rows-1?i+cols:i],o=4*i;\r\n   d[o]=Math.max(0,Math.min(255,128+(r-l)*gain));d[o+1]=Math.max(0,Math.min(255,128+(dn-u)*gain));d[o+2]=Math.max(0,Math.min(255,128+cur[i]*gain));\r\n  }\r\n  S.waveTex.needsUpdate=true;S.dirty=e>1e-4;\r\n }\r\n return e>1e-4;\r\n}\r\n\r\nfunction step(dt,now){\r\n if(!S)return false;\r\n const t=now/1000,fin=S.lead;\r\n S.fade+=(S.fadeTo-S.fade)*Math.min(1,dt*4);S.fishMat.uniforms.uFade.value=S.fade;\r\n if(fin)S.uniforms.uFinger.value.set(fin.x,fin.y/S.A,1,0);else S.uniforms.uFinger.value.z=Math.max(0,S.uniforms.uFinger.value.z-dt*2);\r\n if(S.reduced){secretStep(dt,now);place(dt,now);return Math.abs(S.fade-S.fadeTo)>.01||S.sec.st!=='idle';}\r\n stepWater(t);stepPads(S,dt,t);stepFish(S.fishS,dt,now,S.K);secretStep(dt,now);place(dt,now);\r\n return true; // the koi never stop swimming\r\n}\r\n\r\n// --- Secret animation: rise (held), splash (done), bored (lifted early) --------------------------------------\r\nconst wrapA=d=>d-TAU*Math.round(d/TAU),ease=p=>p*p*(3-2*p);\r\nfunction startSecret(now){ // a hold landed on the big koi: freeze its pose and take it over from the idle show\r\n const b=S.big,K=S.K;S.an={x:b.x,y:b.y,a:b.a,a0:b.a,x0:b.x,y0:b.y,pitch:0,z:0,s:K.bigLen,alpha:.8,mix:.6,e:0,sx:b.x,sy:b.y,sa:b.a,ss:K.bigLen,sAlpha:K.bigAlpha*.8,bt:0};S.wake?.();\r\n}\r\nfunction startBored(){S.an.bt=.001;S.an.tgt=Math.hypot(S.an.x-.5,S.an.y-S.A/2)>.05?Math.atan2(S.an.y-S.A/2,S.an.x-.5):S.an.a+Math.PI/2;S.wake?.();}\r\nfunction startSplash(now){\r\n const c={x:.5,y:S.A/2};S.an=null;S.sec={...S.sec,st:'done'};S.splashT=now;S.splashFired=false;S.ringN=0;S.drops=[];\r\n for(let i=0;i<DROPS;i++){const ang=Math.random()*TAU,up=i%2===0; // even: a spray column; odd: a crown arcing out\r\n  S.drops.push({x:c.x+Math.cos(ang)*.03,y:c.y+Math.sin(ang)*.02,cx:Math.cos(ang),cy:Math.sin(ang),vr:up?.04+Math.random()*.2:.35+Math.random()*1.0,vh:up?4.2+Math.random()*2.2:2.4+Math.random()*1.8,landed:false});}\r\n for(const d of S.drops)d.life=2*d.vh/6;\r\n for(const p of S.pads){const dx=p.x-c.x,dy=p.y-c.y,d=Math.hypot(dx,dy)||1,k=.5*Math.max(0,1-d/1.3);p.vx+=dx/d*k;p.vy+=dy/d*k;} // pads ride the wave outward\r\n S.dropMesh.visible=true;S.foam.visible=true;disturb(S.waves,.5,.5,6);S.dirty=true;S.wake?.();\r\n}\r\nfunction secretStep(dt,now){\r\n const sec=S.sec,an=S.an,K=S.K;\r\n if(sec.st==='hold'){\r\n  const ns=pondSecret(sec,{type:'tick'},now);S.sec=ns;if(ns.st==='done')return startSplash(now);\r\n  const p=Math.min(1,(now-sec.t0)/SECRET.riseMs),e=ease(p),ep=ease(Math.min(1,p*1.5)); // steers to the middle a little ahead of the growth\r\n  an.e=e;an.x=an.x0+(.5-an.x0)*ep;an.y=an.y0+(S.A/2-an.y0)*ep;an.a=an.a0+wrapA(-Math.PI/2-an.a0)*ep;an.pitch=e*.55;an.z=e*.56;an.s=K.bigLen*(1+e*.4);an.alpha=.8+.2*e;an.mix=.6+.4*e;an.ss=K.bigLen*(1-e*.55);an.sAlpha=K.bigAlpha*.8*(1-e*.75);\r\n }else if(sec.st==='bored'&&an&&!an.bt)startBored();\r\n if(sec.st==='bored'&&an&&an.bt){ // turns away, levels out, swims off the face\r\n  an.bt+=dt;const k=Math.min(1,dt*3.5),f=Math.exp(-dt*5);\r\n  an.a+=wrapA(an.tgt-an.a)*k;an.pitch*=f;an.z*=f;an.s+=(K.bigLen-an.s)*Math.min(1,dt*3);an.mix+=(.6-an.mix)*k;an.alpha+=(.8-an.alpha)*k;an.e*=f;an.sAlpha*=Math.exp(-dt*6);\r\n  const sp=Math.min(.55,.1+an.bt*.5);an.x+=Math.cos(an.a)*sp*dt;an.y+=Math.sin(an.a)*sp*dt;an.sx=an.x;an.sy=an.y;an.sa=an.a;an.ss=an.s;\r\n  if(Math.hypot(an.x-.5,an.y-S.A/2)>Math.hypot(.5,S.A/2)+K.bigLen*.6||an.bt>9)endSecret(now);\r\n }\r\n if(sec.st==='done'&&!an){ // splash: rings across the face, foam flash, spray column + crown that fall back with tiny ripples\r\n  const t=now-S.splashT,rings=[[130,.5,.5,5],[300,.5,.5,4],[480,.5,.5,3.2],[680,.5,.5,2.4],[200,.4,.42,2.5],[260,.6,.58,2.5]];\r\n  while(S.ringN<rings.length&&t>=rings[S.ringN][0]){const r=rings[S.ringN++];disturb(S.waves,r[1],r[2],r[3]);S.dirty=true;}\r\n  const [wx,wy]=S.toWorld(0,0),[x1]=S.toWorld(1,0),px=x1-wx,ts=t/1000;\r\n  S.drops.forEach((d,i)=>{const h=d.vh*ts-3*ts*ts,ok=ts<d.life,gx=d.x+d.cx*d.vr*ts,gy=d.y+d.cy*d.vr*ts*.6;\r\n   if(!ok&&!d.landed){d.landed=true;disturb(S.waves,Math.min(.97,Math.max(.03,gx)),Math.min(.97,Math.max(.03,gy/S.A)),.7);S.dirty=true;}\r\n   S.dropPos[3*i]=wx+gx*px;S.dropPos[3*i+1]=wy-(gy-Math.max(0,h)*.35)*px;S.dropPos[3*i+2]=ok?4:-9999;});\r\n  S.dropGeo.attributes.position.needsUpdate=true;S.dropMat.opacity=Math.min(1,Math.max(0,(1900-t)/500));\r\n  const f=Math.max(0,1-t/420),fs=(.35+Math.min(1,t/420)*1.5)*px;S.foam.position.set(wx+.5*px,wy-S.A/2*px,4.5);S.foam.scale.set(fs,fs,1);S.foam.material.opacity=f*.85;\r\n  if(!S.splashFired&&t>=1300){S.splashFired=true;typeof window!=='undefined'&&window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'pond'}}));}\r\n  if(t>=1900)endSecret(now);\r\n }\r\n}\r\nfunction endSecret(now){S.an=null;S.sec={st:'idle',id:null};S.dropMesh.visible=false;S.foam.visible=false;S.fishS.lastTouch=now;S.wake?.();}\r\n// Back to a calm pond after the secret (the board was paused mid-splash when the vault opened): foam, spray and the held koi gone.\r\nfunction healSecret(){if(S&&(S.an||S.sec.st!=='idle'))endSecret(performance.now());}\r\nconst toPondXY=(u,v)=>({x:u,y:v*POND.aspect});\r\nfunction press(id,u,v){\r\n if(!S)return;const p=toPondXY(u,v),now=performance.now(),was=S.sec.st;\r\n S.sec=pondSecret(S.sec,{type:'down',id,x:p.x,y:p.y,phase:S.fishS.phase,big:S.big},now);if(was==='idle'&&S.sec.st==='hold')startSecret(now);\r\n S.lead={...p,moved:true};S.pointers.set(id,S.lead);\r\n if(!S.reduced)disturb(S.waves,u,v,S.K.wave.press);\r\n if(S.sec.id!==id)fishTouch(S.fishS,p.x,p.y,now); // a claimed hold leaves the fish show alone\r\n S.dirty=true;\r\n}\r\nfunction move(id,u,v){\r\n if(!S)return;const f=S.pointers.get(id),p=toPondXY(u,v);if(!f)return press(id,u,v);\r\n f.moved=f.moved||Math.hypot(p.x-f.x,p.y-f.y)>.002;f.x=p.x;f.y=p.y;\r\n S.sec=pondSecret(S.sec,{type:'move',id,x:p.x,y:p.y},performance.now());\r\n if(S.sec.id!==id)fishTouch(S.fishS,p.x,p.y,performance.now());\r\n}\r\nfunction release(id){\r\n if(!S)return;const mine=S.sec.id===id,now=performance.now();S.pointers.delete(id);const last=S.lead=[...S.pointers.values()].at(-1)||null;\r\n if(mine){S.sec=pondSecret(S.sec,{type:'up',id},now);if(S.sec.st==='done'&&S.an)startSplash(now);return;}\r\n if(last)fishTouch(S.fishS,last.x,last.y,now);else fishRelease(S.fishS,now);\r\n}\r\nconst claims=id=>!!S&&S.sec.id===id; // read by the board wrapper before release forgets the pointer\r\n// The cut: pads inside the shape sink away with the water; the koi dive (fade) until it heals.\r\nfunction cut(polyUv){\r\n if(!S)return;S.cutPoly=polyUv;\r\n for(const p of S.pads)p.hidden=pointInPolygon(p.x,p.y/S.A,polyUv);\r\n S.fadeTo=0;S.wake?.();\r\n}\r\nfunction heal(){if(!S)return;S.cutPoly=null;for(const p of S.pads)p.hidden=false;S.fadeTo=1;S.wake?.();}\r\nfunction dispose(){\r\n if(!S)return;\r\n for(const m of [S.padMesh,S.lilyMesh,S.coreMesh,S.fishMesh]){m.removeFromParent();m.geometry.dispose();m.material.dispose();m.dispose?.();}\r\n S.foam.removeFromParent();S.foam.geometry.dispose();S.foam.material.dispose();S.dropMesh.removeFromParent();S.dropGeo.dispose();S.dropMat.dispose();S.dropTex.dispose();\r\n S.koi.dispose();S.waveTex.dispose();S=null;\r\n}\r\n\r\nexport const pond={\r\n id:'pond',build,background:'#06110f',ink:true,\r\n guide:{color:'#bff8ee',alpha:.08,width:4}, // the hint shapes glow faintly on the water\r\n frame:POND.frame,keepColors:true,tintTarget:'trace',\r\n uniforms:{uWave:{value:null},uFinger:{value:null}},\r\n fragmentDecls:WATER_DECLS,\r\n vertexDisplace:'/* pond: flat water; the ripples live in the fragment */',\r\n fragment:WATER_FRAGMENT,\r\n init,step,press,move,release,claims,cut,heal,healSecret,dispose,setTint,\r\n forceBig(){if(!S)return;const K=S.K,now=performance.now();S.sec={st:'idle',id:null};S.an=null;S.fishS.touch=null;S.fishS.lastTouch=now-(K.idleMs+K.scatterMs+K.bigMs*.5);S.wake?.();}, // test/preview: big koi mid-crossing now\r\n debug:()=>S&&{sec:S.sec.st,big:S.big,an:S.an&&{...S.an},phase:S.fishS.phase,since:performance.now()-S.fishS.lastTouch,born:S.born,members:S.fishS.members,fish:S.fishS.fish.map(f=>[f.x,f.y,f.a]),pads:S.pads.length,lilies:S.lilies.length,anchors:S.pads.filter(p=>p.anchor).length},\r\n};\r\n","modules/portal/portal-board-wood.mjs":"// Burning-wood board effect for portal-board-glb.mjs: press/drag drops dwell-scaled embers that age\r\n// on the clock (deep orange -> dark ember -> char) on `paint`, glow on `glow` while hot, then fade out\r\n// so the board returns to just its guides; procedural smoke sprites puff while burning. AGPL-3.0-or-later.\r\n// Secret (Achievement Vault): scrub one face quadrant (>=8 reversals in 3 s) -> heat builds -> fire; one tap -> steam,\r\n// ash, crumble; then window event 'myr5:portal-secret' {board:'wood'}. The gesture is the pure reducer woodSecret().\r\n\r\nconst COOL_MS=2600; // ember age at which it reaches char\r\nconst FADE_MS=7000,FADE_OUT_MS=1200; // Ian: everything returns to normal after 7 s (2026-09-22)\r\nconst TICK_MS=80; // paint/glow redraw period while anything is changing\r\nconst STAMP_FRAC=.04,STAMP_STEP=12; // ember radius as a fraction of face width; paint-px between embers along a drag\r\nconst GLOW_GAIN=1.6;\r\n// Per-ember alpha by ms spent per STAMP_STEP: embers overlap ~7x along a drag, so a normal stroke\r\n// ends fully black and a held finger stacks a fresh ember every EMBER_PERIOD_MS.\r\nconst DWELL_CAP_MS=300,DWELL_MIN=.45,DWELL_MAX=1;\r\nconst EMBER_PERIOD_MS=90,SPRITES=32;\r\nconst SMOKE_COUNT=40,SMOKE_PERIOD_MS=90,SMOKE_LIFE_MS=2000,SMOKE_RISE=55/1000,SMOKE_DRIFT=14/1000;\r\nconst SMOKE_R0=34,SMOKE_R1=90,SMOKE_COLOR='216,220,223',SMOKE_OPACITY=.55,SMOKE_Z=14;\r\n\r\n// --- Pure helpers (no THREE dependency) -----------------------------------------------------\r\n// Ember colour by age in ms: deep orange -> red -> dark ember -> char at COOL_MS (then held).\r\nconst STOPS=[[0,255,106,0],[.35,255,45,0],[.65,122,20,0],[1,10,6,4]];\r\nexport function emberColor(age){\r\n const f=Math.min(1,Math.max(0,age/COOL_MS));\r\n let i=0;while(i<STOPS.length-2&&f>STOPS[i+1][0])i++;\r\n const lo=STOPS[i],hi=STOPS[i+1],t=(f-lo[0])/(hi[0]-lo[0]);\r\n return {r:Math.round(lo[1]+(hi[1]-lo[1])*t),g:Math.round(lo[2]+(hi[2]-lo[2])*t),b:Math.round(lo[3]+(hi[3]-lo[3])*t)};\r\n}\r\n// Scorch opacity multiplier by age: 1 until FADE_MS, then out to 0 over FADE_OUT_MS (0 = dropped).\r\nexport function emberFade(age){return Math.min(1,Math.max(0,1-(age-FADE_MS)/FADE_OUT_MS));}\r\n// ms since the previous stamp on this stroke -> per-ember alpha, capped so dwell can't overshoot.\r\nexport function dwellAlpha(msSinceLast){\r\n const c=Math.min(DWELL_CAP_MS,Math.max(0,msSinceLast));\r\n return DWELL_MIN+(DWELL_MAX-DWELL_MIN)*(c/DWELL_CAP_MS);\r\n}\r\nexport {COOL_MS,FADE_MS,FADE_OUT_MS};\r\nconst lerp=(a,b,t)=>a+(b-a)*t;\r\n\r\n// --- Secret gesture (pure) ----------------------------------------------------------------------\r\n// State: {phase:'idle'|'fire'|'ash', id:tracked pointer, q:quadrant, ax/ay:{ref,dir,ext,ts} per-axis turn trackers,\r\n// claimId:pointer to claim, at:{x,y} fire origin}. Events: {t:'down'|'move'|'up', id, x, y (face px), w, h (face px size), edge}.\r\nexport const SECRET={leg:18,revs:8,claimRevs:4,windowMs:3000};\r\nexport const woodSecretInit=()=>({phase:'idle',id:null,q:-1,ax:null,ay:null,claimId:null,at:null,fireAt:0,ashAt:0});\r\nconst axis=(a,p,now)=>{ // a leg is >= SECRET.leg px; a reversal is a counter-move of that size off the extreme\r\n let {ref,dir,ext,ts}=a;\r\n if(!dir){if(Math.abs(p-ref)>=SECRET.leg){dir=Math.sign(p-ref);ext=p;}}\r\n else if(dir*(p-ext)>0)ext=p;\r\n else if(Math.abs(p-ext)>=SECRET.leg){ts=[...ts.filter(t=>now-t<SECRET.windowMs),now];ref=ext;dir=-dir;ext=p;}\r\n return {ref,dir,ext,ts};\r\n};\r\nconst quad=e=>(e.x<e.w/2?0:1)+(e.y<e.h/2?0:2);\r\nconst fresh=(s,e)=>({...s,id:e.id,q:quad(e),ax:{ref:e.x,dir:0,ext:e.x,ts:[]},ay:{ref:e.y,dir:0,ext:e.y,ts:[]}});\r\n// Reversals still inside the 3 s window (the larger of the x and y counts).\r\nexport const revNow=(s,now)=>s.ax?Math.max(...[s.ax,s.ay].map(a=>a.ts.filter(t=>now-t<SECRET.windowMs).length)):0;\r\nexport function woodSecret(s,e,now){\r\n s=s||woodSecretInit();\r\n if(s.phase==='ash')return s;\r\n if(s.phase==='fire')return e.t==='down'?{...s,phase:'ash',ashAt:now,claimId:e.id}:s; // any tap puts it out (claimed so portal ignores it)\r\n if(e.t==='down')return s.id!=null||e.edge?s:fresh({...s,claimId:null},e); // first finger only; edge touches (back-swipe zone) ignored\r\n if(e.id!==s.id)return s;\r\n if(e.t==='up')return {...s,id:null,ax:null,ay:null};\r\n if(quad(e)!==s.q)return fresh(s,e); // left the quadrant: start over from here\r\n const n={...s,ax:axis(s.ax,e.x,now),ay:axis(s.ay,e.y,now)},rev=revNow(n,now);\r\n if(rev>=SECRET.claimRevs)n.claimId=e.id;\r\n if(rev>=SECRET.revs){n.phase='fire';n.fireAt=now;n.at={x:e.x,y:e.y};}\r\n return n;\r\n}\r\n// Does portal.mjs need to leave this pointer alone? (scrubbing, or the board is burning/ashed)\r\nexport const woodClaims=(s,id)=>!!s&&(s.claimId===id||s.phase!=='idle');\r\n\r\n// One instance per board layer: the 3D board's (wood itself) and the flat board's 2D trace (wood.trace2d, R7: embers,\r\n// char and glow; no scene, so no smoke) each get their own.\r\nexport function woodEffect(){\r\nlet S=null; // per-instance state\r\nconst U={uAsh:{value:0},uCrumble:{value:0},uCrack:{value:0},uFireR:{value:0},uAsp:{value:1},uFireO:{value:null},uCell:{value:null}}; // ash/crumble shader uniforms (portal-board-glb merges effect.uniforms)\r\n\r\nfunction softCircleTexture(THREE){\r\n const c=document.createElement('canvas');c.width=c.height=64;\r\n const ctx=c.getContext('2d'),g=ctx.createRadialGradient(32,32,0,32,32,32);\r\n g.addColorStop(0,`rgba(${SMOKE_COLOR},.9)`);g.addColorStop(1,`rgba(${SMOKE_COLOR},0)`);\r\n ctx.fillStyle=g;ctx.fillRect(0,0,64,64);\r\n const tex=new THREE.CanvasTexture(c);tex.needsUpdate=true;return tex;\r\n}\r\n// Soft ember disc at colour step k (0 = birth .. SPRITES-1 = char), cached: redraws are just drawImage.\r\nfunction sprite(k){\r\n if(S.sprites[k])return S.sprites[k];\r\n const r=S.r,d=Math.ceil(2*r),c=document.createElement('canvas');c.width=c.height=d;\r\n const {r:cr,g:cg,b:cb}=emberColor(k/(SPRITES-1)*COOL_MS),ctx=c.getContext('2d'),g=ctx.createRadialGradient(r,r,0,r,r,r);\r\n g.addColorStop(0,`rgba(${cr},${cg},${cb},1)`);g.addColorStop(.5,`rgba(${cr},${cg},${cb},.85)`);g.addColorStop(1,`rgba(${cr},${cg},${cb},0)`);\r\n ctx.fillStyle=g;ctx.fillRect(0,0,d,d);\r\n return S.sprites[k]=c;\r\n}\r\nfunction stamp(u,v,heat){if(S.heat)heat=Math.min(1,heat*(1+.6*S.heat));S.embers.push({x:u*S.paint.canvas.width,y:v*S.paint.canvas.height,heat,t0:performance.now(),k:-1,a:-1});}\r\n\r\n// One redraw pass. Paint: restore the pristine guides inside the union of every ember whose colour or\r\n// opacity changed, then redraw the live embers overlapping it (clipped, oldest first). Glow: clear and\r\n// re-draw the hot embers in their own colour (source-over, so overlaps never sum to yellow); wiped once\r\n// when the last one cools. Returns whether anything is still changing.\r\n// ponytail: redraw cost grows with embers under the dirty rect; cap S.embers if long scribbles stutter.\r\nfunction tick(now){\r\n const R=S.r,last=SPRITES-1,live=[];let x0=Infinity,y0=Infinity,x1=-Infinity,y1=-Infinity;\r\n for(const e of S.embers){\r\n  const age=now-e.t0,a=Math.round(e.heat*emberFade(age)*100)/100,k=S.reduced?last:Math.round(Math.min(1,age*(1-.7*S.heat)/COOL_MS)*last); // heat keeps embers hot\r\n  if(k!==e.k||a!==e.a){e.k=k;e.a=a;x0=Math.min(x0,e.x-R);y0=Math.min(y0,e.y-R);x1=Math.max(x1,e.x+R);y1=Math.max(y1,e.y+R);}\r\n  if(a>0)live.push(e);\r\n }\r\n S.embers=live;\r\n const pc=S.paint.ctx,W=S.paint.canvas.width,H=S.paint.canvas.height;\r\n const x=Math.max(0,Math.floor(x0)),y=Math.max(0,Math.floor(y0)),w=Math.min(W,Math.ceil(x1))-x,h=Math.min(H,Math.ceil(y1))-y,changed=w>0&&h>0;\r\n if(changed){\r\n  pc.save();pc.beginPath();pc.rect(x,y,w,h);pc.clip();pc.clearRect(x,y,w,h);pc.drawImage(S.pristine,x,y,w,h,x,y,w,h);\r\n  for(const e of live)if(e.x+R>x&&e.x-R<x+w&&e.y+R>y&&e.y-R<y+h){pc.globalAlpha=e.a;pc.drawImage(sprite(e.k),e.x-R,e.y-R);}\r\n  pc.restore();S.paint.texture.needsUpdate=true;\r\n }\r\n const hot=S.reduced?[]:live.filter(e=>now-e.t0<COOL_MS);\r\n if(hot.length||S.glowOn){\r\n  const gc=S.glow.ctx;gc.clearRect(0,0,S.glow.canvas.width,S.glow.canvas.height);\r\n  gc.save();\r\n  for(const e of hot){gc.globalAlpha=Math.min(1,GLOW_GAIN*(1+S.heat)*e.heat*(1-(now-e.t0)*(1-.7*S.heat)/COOL_MS));gc.drawImage(sprite(e.k),e.x-R,e.y-R);}\r\n  gc.restore();S.glow.texture.needsUpdate=true;S.glowOn=hot.length>0;\r\n }\r\n const busy=changed||hot.length>0;\r\n // Char sits still until FADE_MS: sleep and let a timer wake the board for the fade-out.\r\n clearTimeout(S.timer);\r\n if(!busy&&live.length)S.timer=setTimeout(()=>S?.wake?.(),Math.max(0,live[0].t0+FADE_MS-now));\r\n return busy;\r\n}\r\n\r\nfunction spawnSmoke(u,v,at,k=1,tone=0){ // k: rise speed multiplier; tone 1 = small pale ash dust, 2 = dark smoke\r\n const dead=S.smoke.find(s=>!s.alive);if(!dead)return;\r\n const [x,y]=at||S.toWorld(u,v);\r\n dead.alive=true;dead.k=k;dead.size=tone===1?.55:1;dead.t0=S.hold?S.hold-Math.random()*1200:performance.now();dead.sprite.material.color?.setScalar?.(tone===2?.3:1);dead.x0=x;dead.y0=y;dead.dir=Math.random()<.5?-1:1;\r\n dead.sprite.visible=true;dead.sprite.position.set(x,y,S.faceZ+SMOKE_Z);dead.sprite.material.opacity=0;\r\n}\r\nfunction stepSmoke(now){\r\n let any=false;\r\n for(const s of S.smoke){\r\n  if(!s.alive)continue;\r\n  const age=now-s.t0,t=age/SMOKE_LIFE_MS;\r\n  if(t>=1){s.alive=false;s.sprite.visible=false;continue;}\r\n  any=true;\r\n  const sc=lerp(SMOKE_R0,SMOKE_R1,t)*(s.size||1);\r\n  s.sprite.position.set(s.x0+s.dir*SMOKE_DRIFT*age,s.y0+SMOKE_RISE*(s.k||1)*age,S.faceZ+SMOKE_Z);\r\n  s.sprite.scale.set(sc,sc,1);\r\n  s.sprite.material.opacity=SMOKE_OPACITY*(1-t);\r\n }\r\n return any;\r\n}\r\n\r\n// --- Secret: heat -> blaze -> steam/ash -> crack & crumble ---------------------------------------\r\nconst NF=48,NS=40,NK=260,ASH_MS=1100,HOLD_MS=700,CRUMBLE_MS=3200,SPREAD_MS=1500,CHUNK_BURST=.6;\r\nconst faceW=()=>S.toWorld(1,0)[0]-S.toWorld(0,0)[0],faceH=()=>S.toWorld(0,0)[1]-S.toWorld(0,1)[1];\r\nconst wp=(x,y)=>{const [ox,oy]=S.toWorld(0,0);return [ox+x,oy-y];}; // face px -> world\r\nconst rnd=Math.random;\r\nfunction isEdge(u,v){ // first touch within 24 px of the screen edge = iOS back-swipe / home bar: never a scrub\r\n const c=document.querySelector?.('.portal-board-canvas');if(!c)return false;\r\n const r=c.getBoundingClientRect(),[x,y]=S.toWorld(u,v),sx=r.left+x,sy=r.top-y;\r\n return sx<24||sy<24||sx>innerWidth-24||sy>innerHeight-24;\r\n}\r\nfunction secretEv(t,id,u,v){\r\n if(!S.scene)return;\r\n const w=faceW(),h=faceH();S.rs=woodSecret(S.rs,{t,id,x:u*w,y:v*h,w,h,edge:t==='down'&&isEdge(u,v)},performance.now());\r\n if(t!=='up')S.finger=[u,v];\r\n}\r\nfunction flameTexture(){\r\n const c=document.createElement('canvas');c.width=64;c.height=128;const x=c.getContext('2d');\r\n const g=x.createRadialGradient(32,96,2,32,90,64);g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(.5,'rgba(255,255,255,.55)');g.addColorStop(1,'rgba(255,255,255,0)');\r\n x.filter='blur(2px)';x.fillStyle=g;x.beginPath();x.moveTo(32,2);x.bezierCurveTo(30,34,6,60,8,92);x.bezierCurveTo(10,120,54,120,56,92);x.bezierCurveTo(58,60,34,34,32,2);x.fill();\r\n return c;\r\n}\r\nfunction dotTexture(){\r\n const c=document.createElement('canvas');c.width=c.height=16;const x=c.getContext('2d'),g=x.createRadialGradient(8,8,0,8,8,8);\r\n g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(.4,'rgba(255,255,255,.6)');g.addColorStop(1,'rgba(255,255,255,0)');x.fillStyle=g;x.fillRect(0,0,16,16);return c;\r\n}\r\nconst LAYERS=[[0xff3a00,1,.32,.9],[0xff7a10,.62,.34,.8],[0xffd890,.32,.4,.9]]; // colour, size, base alpha, shape: outer/mid/core tongues\r\nfunction ensureFx(){\r\n if(S.fx||!S.scene)return;\r\n const T=S.THREE,mk=(map,color)=>{const m=new T.SpriteMaterial({map,color,transparent:true,opacity:0,depthWrite:false,depthTest:false,blending:T.AdditiveBlending}),sp=new T.Sprite(m);sp.visible=false;sp.renderOrder=20;S.scene.add(sp);return sp;};\r\n const ft=new T.CanvasTexture(flameTexture()),dt=new T.CanvasTexture(dotTexture());\r\n S.fx={ft,dt,flames:Array.from({length:NF},()=>({alive:false,sp:LAYERS.map(l=>{const sp=mk(ft,l[0]);sp.center.set(.5,.08);return sp;})})),\r\n  sparks:Array.from({length:NS},()=>({alive:false,sp:mk(dt,0xffa030)})),light:new T.PointLight(0xff6a1a,0,900,0)};\r\n S.scene.add(S.fx.light);\r\n}\r\n// Cracks: a jittered-grid Voronoi of the face (unit space, x 0..1, y 0..asp). Each cell has a break threshold (the bottom lets go\r\n// first); a data texture carries R = threshold, G = distance to the nearest crack, which the board shader reads for the glowing\r\n// char cracks, the ash cracks and the crumble. The same cells become the falling chunks.\r\nfunction clip(poly,a,b,c){ // keep a*x+b*y<=c\r\n const out=[];for(let i=0;i<poly.length;i++){const p=poly[i],q=poly[(i+1)%poly.length],dp=a*p[0]+b*p[1]-c,dq=a*q[0]+b*q[1]-c;\r\n  if(dp<=0)out.push(p);if(dp*dq<0){const t=dp/(dp-dq);out.push([p[0]+(q[0]-p[0])*t,p[1]+(q[1]-p[1])*t]);}}\r\n return out;\r\n}\r\nfunction ensureCells(){\r\n if(S.cells||!S.scene)return;\r\n const asp=faceH()/faceW(),gx=8,gy=Math.max(2,Math.round(8*asp)),seeds=[];\r\n for(let j=0;j<gy;j++)for(let i=0;i<gx;i++)seeds.push({x:(i+.15+.7*rnd())/gx,y:(j+.15+.7*rnd())/gy*asp});\r\n const cells=seeds.map((s,i)=>{\r\n  let poly=[[0,0],[1,0],[1,asp],[0,asp]];\r\n  for(const o of seeds)if(o!==s){const dx=o.x-s.x,dy=o.y-s.y;if(dx*dx+dy*dy<.09)poly=clip(poly,dx,dy,(o.x*o.x+o.y*o.y-s.x*s.x-s.y*s.y)/2);}\r\n  const cx=poly.reduce((a,p)=>a+p[0],0)/poly.length,cy=poly.reduce((a,p)=>a+p[1],0)/poly.length;\r\n  return {s,poly,cx,cy,T:Math.max(.02,Math.min(1,.45*rnd()+.55*(1-s.y/asp)))};\r\n });\r\n S.cells=cells;S.corder=[...cells.keys()].sort((a,b)=>cells[a].T-cells[b].T);S.cptr=0;\r\n if(!S.THREE.DataTexture)return;\r\n const TW=128,TH=Math.round(128*asp),px=new Uint8Array(TW*TH*4);\r\n for(let py=0;py<TH;py++)for(let qx=0;qx<TW;qx++){\r\n  const x=(qx+.5)/TW,y=(py+.5)/TH*asp;let d1=9,d2=9,b=0;\r\n  for(let k=0;k<seeds.length;k++){const d=Math.hypot(seeds[k].x-x,seeds[k].y-y);if(d<d1){d2=d1;d1=d;b=k;}else if(d<d2)d2=d;}\r\n  const o=(py*TW+qx)*4;px[o]=Math.round(cells[b].T*255);px[o+1]=Math.round(Math.min(1,(d2-d1)/2/.06)*255);px[o+3]=255;\r\n }\r\n const tex=new S.THREE.DataTexture(px,TW,TH);tex.magFilter=tex.minFilter=S.THREE.LinearFilter;tex.needsUpdate=true;U.uCell.value=tex;\r\n}\r\nfunction ensureChunks(){\r\n if(S.chunks||!S.scene||!S.cells)return;\r\n const T=S.THREE,W=faceW();\r\n S.chunks=S.cells.map(c=>{\r\n  const sh=new T.Shape(c.poly.map(p=>new T.Vector2((p[0]-c.cx)*W*.97,-(p[1]-c.cy)*W*.97)));\r\n  const m=new T.Mesh(new T.ExtrudeGeometry(sh,{depth:6,bevelEnabled:false}),new T.MeshLambertMaterial({color:0x6e6a64,emissive:0x000000}));\r\n  m.visible=false;m.renderOrder=16;S.scene.add(m);return {m,alive:false,c};\r\n });\r\n}\r\nfunction ensureFlakes(){\r\n if(S.flakes||!S.scene)return;\r\n const T=S.THREE,geo=new T.BoxGeometry(1,1,.3),mats=['#8f8a82','#6a655e','#4a4540'].map(c=>new T.MeshBasicMaterial({color:c}));\r\n S.flakes={geo,mats,list:Array.from({length:NK},(_,i)=>{const m=new T.Mesh(geo,mats[i%3]);m.visible=false;m.renderOrder=15;S.scene.add(m);return {m,alive:false};})};\r\n}\r\nfunction spawnFlame(cx,cy,R,sz,now){\r\n const f=S.fx.flames.find(f=>!f.alive);if(!f)return;\r\n const W=faceW(),H=faceH(),[ox,oy]=S.toWorld(0,0);let x,y;\r\n for(let i=0;i<6;i++){const a=rnd()*6.283,r=R*Math.sqrt(rnd());x=cx+Math.cos(a)*r;y=cy+Math.sin(a)*r*.9;if(x>ox+W*.03&&x<ox+W*.97&&y<oy-H*.04&&y>oy-H*.96)break;} // resample off-board picks so a big burn doesn't pile up on the rim\r\n f.alive=true;f.life=650+rnd()*600;f.t0=now-(S.hold?rnd()*f.life*.7:0);f.ph=rnd()*6.283;f.sz=sz*(.7+.7*rnd());\r\n f.x=Math.min(ox+W*.97,Math.max(ox+W*.03,x));f.y=Math.min(oy-H*.04,Math.max(oy-H*.96,y));\r\n}\r\nfunction spawnSpark(cx,cy,R,now){\r\n const k=S.fx.sparks.find(k=>!k.alive);if(!k)return;const a=rnd()*6.283,r=R*Math.sqrt(rnd());\r\n Object.assign(k,{alive:true,t0:now-(S.hold?rnd()*900:0),life:800+rnd()*900,x:cx+Math.cos(a)*r,y:cy+Math.sin(a)*r*.9,vx:(rnd()-.5)*120,vy:160+rnd()*260,s:3+rnd()*4});\r\n}\r\n// Flame field around (cx,cy) radius R at intensity I (0..1, how many tongues are alive); kill 0..1 fades everything out.\r\nfunction stepFire(now,I,cx,cy,R,kill){\r\n const fx=S.fx,W=faceW(),sc=W/340;let alive=0;\r\n if(I>0){\r\n  let n=fx.flames.filter(f=>f.alive).length;for(let i=0;n<I*NF&&i<8;i++,n++)spawnFlame(cx,cy,R,sc,now);\r\n  if(rnd()<I*.7)spawnSpark(cx,cy,R,now);\r\n }\r\n for(const f of fx.flames){\r\n  if(!f.alive)continue;const t=(now-f.t0)/f.life;\r\n  if(t>=1){f.alive=false;f.sp.forEach(s=>s.visible=false);continue;}\r\n  alive++;const env=Math.min(1,t*5)*(1-t)**.7*(1-kill),fl=.8+.2*Math.sin(now*.018+f.ph),sway=Math.sin(now*.007+f.ph)*14*sc*t;\r\n  f.sp.forEach((s,i)=>{const [,size,a,sh]=LAYERS[i];s.visible=true;s.position.set(f.x+sway*(1-i*.3),f.y+t*70*sc*(1+i*.4),S.faceZ+10);\r\n   s.scale.set(120*sc*f.sz*size*fl*(1-.45*t),(150+210*(1-i*.25))*sc*f.sz*size*(.9+.2*fl)*(1+.35*t),1);s.material.opacity=env*a*(i==2?2.2:1.6)*sh;});\r\n }\r\n for(const k of fx.sparks){\r\n  if(!k.alive)continue;const age=(now-k.t0)/1000,t=age*1000/k.life;\r\n  if(t>=1){k.alive=false;k.sp.visible=false;continue;}alive++;\r\n  k.sp.visible=true;k.sp.position.set(k.x+k.vx*age+Math.sin(age*9+k.x)*6,k.y+k.vy*age,S.faceZ+12);k.sp.scale.setScalar(k.s*sc*(1-.5*t));k.sp.material.opacity=(1-t)*(1-kill);\r\n }\r\n fx.light.position.set(cx,cy+R*.3,W*.45);fx.light.intensity=I*(1-kill)*(4+1.2*Math.sin(now*.03)+.7*Math.sin(now*.071));\r\n return alive>0;\r\n}\r\nfunction spawnFlake(x,y,vx,vy,size,age){\r\n const k=S.flakes.list.find(k=>!k.alive);if(!k)return;\r\n Object.assign(k,{alive:true,t0:S.hold?performance.now()-(age||0)*1000:performance.now(),x,y,vx,vy,rx:(rnd()-.5)*10,ry:(rnd()-.5)*10,rz:(rnd()-.5)*10,sx:size*(.7+rnd()),sy:size*(.5+rnd()*.8)});k.m.visible=true;\r\n}\r\nfunction stepFlakes(now){\r\n let any=false;\r\n for(const k of S.flakes.list){\r\n  if(!k.alive)continue;const age=(now-k.t0)/1000,m=k.m;\r\n  if(age>2.2){k.alive=false;m.visible=false;continue;}any=true;\r\n  m.position.set(k.x+k.vx*age,k.y+k.vy*age-420*age*age,S.faceZ+4);\r\n  m.rotation.set(k.rx*age,k.ry*age,k.rz*age);m.scale.set(k.sx,k.sy,k.sx).multiplyScalar(Math.min(1,(2.2-age)*2));\r\n }\r\n return any;\r\n}\r\n// A chunk lets go: it sags (tilts and drops), tumbles under gravity, then breaks into flakes and an ash-dust puff.\r\nfunction stepChunks(now){\r\n let any=false;\r\n for(const k of S.chunks||[]){\r\n  if(!k.alive)continue;const a=(now-k.t0)/1000,m=k.m;\r\n  if(a>=k.burst){\r\n   k.alive=false;m.visible=false;\r\n   const x=k.x+k.vx*a,y=k.y+k.vy*a-450*a*a;\r\n   for(let i=0;i<5;i++)spawnFlake(x+(rnd()-.5)*30,y+(rnd()-.5)*30,k.vx+(rnd()-.5)*140,k.vy-450*a+rnd()*60,6+rnd()*6,S.hold?rnd()*1.5:0);\r\n   spawnSmoke(0,0,[x,y],.35,1);continue;\r\n  }\r\n  any=true;const e=Math.min(1,a/.5);\r\n  m.position.set(k.x+k.vx*a,k.y+k.vy*a-450*a*a,S.faceZ-3);m.rotation.set(k.rx*a*a*3,0,k.rz*a*a*3);\r\n  const g=(1-e)*(1-e)*.012;m.material.emissive.setRGB(g,g*.3,g*.05); // the break edge glows briefly\r\n }\r\n return any;\r\n}\r\n// Release every cell whose threshold the crumble front c has passed (hold: also show earlier breaks as flakes, for stills).\r\nfunction breakCells(c,now){\r\n while(S.cptr<S.corder.length&&S.cells[S.corder[S.cptr]].T<=c){\r\n  const i=S.corder[S.cptr++],cell=S.cells[i],k=S.chunks[i],[x,y]=wp(cell.cx*faceW(),cell.cy*faceW());\r\n  if(S.hold&&cell.T<c-.12){for(let j=0;j<5;j++)spawnFlake(x+(rnd()-.5)*30,y+(rnd()-.5)*30,(rnd()-.5)*140,-rnd()*200,6+rnd()*6,rnd()*1.8);continue;}\r\n  Object.assign(k,{alive:true,t0:now-(S.hold?rnd()*.45:0),x,y,vx:(rnd()-.5)*50,vy:-rnd()*25,rx:(rnd()-.5)*2,rz:(rnd()-.5)*2,burst:CHUNK_BURST+rnd()*.25});k.m.visible=true;\r\n }\r\n}\r\nfunction ashPaint(){ // scorch + glow gone, guides back\r\n S.embers=[];const pc=S.paint.ctx,gc=S.glow.ctx;\r\n pc.clearRect(0,0,S.paint.canvas.width,S.paint.canvas.height);pc.drawImage(S.pristine,0,0);S.paint.texture.needsUpdate=true;\r\n gc.clearRect(0,0,S.glow.canvas.width,S.glow.canvas.height);S.glow.texture.needsUpdate=true;S.glowOn=false;S.pointers.clear();\r\n}\r\nfunction secretStep(dt,now){\r\n if(!S.scene)return false;\r\n if(S.hold)now=S.hold; // debug.pose: time frozen\r\n const rs=S.rs,U_=S.uni;let busy=false;\r\n S.heat+=((S.stage==='idle'?revNow(rs,now)/SECRET.revs:S.stage==='fire'?1:0)-S.heat)*Math.min(1,dt*5);\r\n if(S.heat<.005)S.heat=0;\r\n if(U_.glowS)U_.glowS.value=1.2+1.8*S.heat;\r\n if(S.heat>.3)ensureCells(); // build the crack map before it is needed\r\n if(S.stage==='idle'&&rs.phase==='fire'){S.stage='fire';S.t0=now;S.fc=wp(rs.at.x,rs.at.y);S.fo=[rs.at.x/faceW(),rs.at.y/faceH()];ensureCells();}\r\n if((S.stage==='idle'||S.stage==='fire')&&rs.phase==='ash'){ // tap: hiss, steam, embers out, board greys\r\n  S.stage='ash';S.t0=now;ashPaint();ensureCells();\r\n  const [cx,cy]=S.fc||wp(faceW()/2,faceH()/2),W=faceW();\r\n  for(let i=0;i<S.smoke.length;i++)spawnSmoke(0,0,[cx+(rnd()-.5)*W*.9,cy+(rnd()-.5)*W*.6],1.2);\r\n  if(typeof window!=='undefined')window.dispatchEvent(new CustomEvent('myr5:portal-sound',{detail:{kind:'hiss',board:'wood'}}));\r\n }\r\n U.uAsp.value=faceH()/faceW();\r\n if(S.stage==='idle'){\r\n  const I=Math.max(0,S.heat-.4)*.5; // small tongues at the finger while the heat builds\r\n  if(I>0||S.fx?.flames.some(f=>f.alive)){ensureFx();const [fx,fy]=S.finger?S.toWorld(...S.finger):[0,0];busy=stepFire(now,I,fx,fy,faceW()*.07,0);}\r\n }else if(S.stage==='fire'){\r\n  ensureFx();const ft=now-S.t0,W=faceW(),sp=Math.min(1,ft/SPREAD_MS),R=W*(.1+1.05*sp);\r\n  busy=stepFire(now,Math.min(1,.5+sp*.5),S.fc[0],S.fc[1],R,0);\r\n  U.uFireR.value=1.7*Math.min(1,ft/(SPREAD_MS*1.4));if(U.uFireO.value?.set)U.uFireO.value.set(S.fo[0],S.fo[1]);\r\n  if(now-S.lastSmoke>70&&!S.reduced){S.lastSmoke=now;const a=rnd()*6.283,r=R*Math.sqrt(rnd());spawnSmoke(0,0,[S.fc[0]+Math.cos(a)*r,S.fc[1]+Math.sin(a)*r*.9],3,2);}\r\n  busy=true;\r\n }else{\r\n  const t=now-S.t0;\r\n  if(S.fx)busy=stepFire(now,0,0,0,1,Math.min(1,t/350));\r\n  U.uFireR.value=0;\r\n  if(S.stage==='ash'){\r\n   U.uAsh.value=Math.min(1,t/ASH_MS);U.uCrack.value=Math.min(1,t/(ASH_MS+HOLD_MS));busy=true;\r\n   if(t>ASH_MS+HOLD_MS){S.stage='crumble';S.t0=now;ensureFlakes();ensureChunks();S.cptr=0;}\r\n  }\r\n  if(S.stage==='crumble'){\r\n   const p=Math.min(1,(now-S.t0)/CRUMBLE_MS),c=1.02*p**1.25;U.uCrumble.value=c;ensureFlakes();ensureChunks();if(S.chunks)breakCells(c,now);busy=true;\r\n   if(p>=1&&!S.hold){S.stage='gone';S.t0=now;window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'wood'}}));S.timer2=setTimeout(heal,9000);}\r\n  }\r\n  if(S.chunks)busy=stepChunks(now)||busy;\r\n  if(S.flakes)busy=stepFlakes(now)||busy;\r\n }\r\n return busy||S.heat>0;\r\n}\r\n// Back to a fresh board. portal's board.heal() only reaches us after a cut, so this also runs on the next press and 9 s after the end.\r\nfunction heal(){\r\n if(!S)return;S.hold=0;clearTimeout(S.timer2);\r\n S.stage='idle';S.rs=woodSecretInit();S.heat=0;S.fc=null;S.finger=null;S.cptr=0;\r\n U.uAsh.value=U.uCrumble.value=U.uCrack.value=U.uFireR.value=0;if(S.uni.glowS)S.uni.glowS.value=1.2;\r\n for(const f of S.fx?.flames||[]){f.alive=false;f.sp.forEach(s=>s.visible=false);}\r\n for(const k of S.fx?.sparks||[]){k.alive=false;k.sp.visible=false;}\r\n if(S.fx)S.fx.light.intensity=0;\r\n for(const k of S.flakes?.list||[]){k.alive=false;k.m.visible=false;}\r\n for(const k of S.chunks||[]){k.alive=false;k.m.visible=false;}\r\n S.wake?.();\r\n}\r\n\r\n\r\nfunction init({THREE,scene,uniforms,paint,glow,toWorld,faceZ,wake}){\r\n const pristine=document.createElement('canvas');pristine.width=paint.canvas.width;pristine.height=paint.canvas.height;\r\n pristine.getContext('2d').drawImage(paint.canvas,0,0); // the guides, as drawn before init\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const tex=reduced||!scene?null:softCircleTexture(THREE);\r\n const smoke=reduced||!scene?[]:Array.from({length:SMOKE_COUNT},()=>{\r\n  const mat=new THREE.SpriteMaterial({map:tex,color:0xffffff,transparent:true,opacity:0,depthWrite:false,depthTest:false}); // raised carving must never hide smoke\r\n  const sprite=new THREE.Sprite(mat);sprite.visible=false;scene.add(sprite);\r\n  return {sprite,alive:false,t0:0,x0:0,y0:0,dir:1};\r\n });\r\n S={THREE,scene,paint,glow,toWorld,faceZ,wake,reduced,smoke,smokeTex:tex,pristine,r:paint.canvas.width*STAMP_FRAC,sprites:[],\r\n  pointers:new Map(),embers:[],glowOn:false,busy:false,lastTick:-Infinity,lastSmoke:0,timer:0,\r\n  rs:woodSecretInit(),stage:'idle',heat:0,lastStamp:0,uni:{ash:U.uAsh,crumble:U.uCrumble,glowS:uniforms?.uGlowStrength}};\r\n if(scene){if(THREE.Vector2)U.uFireO.value=new THREE.Vector2();if(THREE.DataTexture){const t=new THREE.DataTexture(new Uint8Array([255,255,255,255]),1,1);t.needsUpdate=true;U.uCell.value=t;}} // (white = 'no cracks' until ensureCells())\r\n if(scene&&typeof window!=='undefined')window.myr5Wood=debug; // 3D board only\r\n}\r\nfunction press(id,u,v){\r\n if(S.stage==='gone')heal();if(S.stage==='ash'||S.stage==='crumble')return;secretEv('down',id,u,v);\r\n S.pointers.set(id,{u,v,t:performance.now()});stamp(u,v,dwellAlpha(EMBER_PERIOD_MS));} // one hold-tick's worth\r\n// Walk from the last ember toward the finger in STAMP_STEP paint-px hops so fast drags stay continuous;\r\n// the remainder carries to the next move, and each hop's heat scales with the ms it took.\r\nfunction move(id,u,v){\r\n if(S.stage==='ash'||S.stage==='crumble'||S.stage==='gone')return;secretEv('move',id,u,v);\r\n const p=S.pointers.get(id);const now=performance.now();\r\n if(!p){S.pointers.set(id,{u,v,t:now});return;}\r\n const W=S.paint.canvas.width,H=S.paint.canvas.height,d=Math.hypot((u-p.u)*W,(v-p.v)*H),n=Math.floor(d/STAMP_STEP);\r\n if(!n)return;\r\n const a=dwellAlpha((now-p.t)*STAMP_STEP/d),su=(u-p.u)*STAMP_STEP/d,sv=(v-p.v)*STAMP_STEP/d;\r\n for(let i=0;i<n;i++){p.u+=su;p.v+=sv;stamp(p.u,p.v,a);}\r\n p.t=now;\r\n}\r\nfunction claims(id){return woodClaims(S?.rs,id);}\r\nfunction release(id){if(S?.scene)secretEv('up',id,0,0);S.pointers.delete(id);}\r\nfunction step(dt,now){\r\n if(S.pointers.size){ // held still: keep stacking fresh embers under each finger, and puff smoke\r\n  for(const p of S.pointers.values())if(now-p.t>=EMBER_PERIOD_MS){stamp(p.u,p.v,dwellAlpha(now-p.t));p.t=now;}\r\n  if(!S.reduced&&now-S.lastSmoke>=SMOKE_PERIOD_MS*(1-.5*S.heat)){S.lastSmoke=now;for(const p of S.pointers.values())spawnSmoke(p.u,p.v);}\r\n }\r\n const smokeAlive=(S.reduced?false:stepSmoke(now))|secretStep(dt,now);\r\n if(now-S.lastTick>=TICK_MS){S.lastTick=now;S.busy=tick(now);}\r\n return smokeAlive||S.busy||S.pointers.size>0;\r\n}\r\nconst debug={ // preview/test hooks: jump to a stage\r\n fire(){const w=faceW(),h=faceH();S.rs={...woodSecretInit(),phase:'fire',fireAt:performance.now(),at:{x:w*.3,y:h*.35}};S.wake?.();},\r\n ash(){if(S.rs.phase==='idle')debug.fire();S.rs={...S.rs,phase:'ash'};S.wake?.();},\r\n pose(stage,p){ // freeze mid-stage for screenshots: 'fire'|'ash'|'crumble', p 0..1\r\n  const now=performance.now();debug.heal();S.hold=now;\r\n  if(stage==='fire'){debug.fire();S.stage='fire';S.t0=now-p*SPREAD_MS;S.fc=wp(faceW()*.3,faceH()*.35);S.fo=[.3,.35];ensureCells();}\r\n  else{debug.ash();ensureCells();S.fc=wp(faceW()*.3,faceH()*.35);S.stage=stage;S.t0=now-p*(stage==='ash'?ASH_MS+HOLD_MS:CRUMBLE_MS);U.uAsh.value=1;U.uCrack.value=1;S.cptr=0;ensureFlakes();ensureChunks();}\r\n  S.wake?.();},\r\n adv(ms){S.hold+=ms;S.wake?.();}, // debug: step frozen time\r\n heal,state:()=>({stage:S.stage,rs:S.rs,heat:S.heat}),\r\n};\r\nfunction dispose(){\r\n if(S){clearTimeout(S.timer);clearTimeout(S.timer2);if(typeof window!=='undefined'&&window.myr5Wood===debug)delete window.myr5Wood;\r\n  for(const f of S.fx?.flames||[])f.sp.forEach(s=>{s.parent?.remove(s);s.material.dispose();});for(const k of S.fx?.sparks||[]){k.sp.parent?.remove(k.sp);k.sp.material.dispose();}\r\n  if(S.fx){S.fx.light.parent?.remove(S.fx.light);S.fx.ft.dispose();S.fx.dt.dispose();}\r\n  for(const k of S.flakes?.list||[])k.m.parent?.remove(k.m);if(S.flakes){S.flakes.geo.dispose();S.flakes.mats.forEach(m=>m.dispose());}\r\n  U.uCell.value?.dispose();U.uCell.value=null;for(const k of S.chunks||[]){k.m.parent?.remove(k.m);k.m.geometry.dispose();k.m.material.dispose();}for(const s of S.smoke)s.sprite.parent?.remove(s.sprite);for(const s of S.smoke)s.sprite.material.dispose();S.smokeTex?.dispose();}\r\n S=null;\r\n}\r\nconst WGLSL=`uniform float uAsh;uniform float uCrumble;uniform float uCrack;uniform float uFireR;uniform float uAsp;uniform vec2 uFireO;uniform sampler2D uCell;\r\nfloat wh(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nfloat wn(vec2 p){vec2 i=floor(p),f=fract(p);f=f*f*(3.0-2.0*f);return mix(mix(wh(i),wh(i+vec2(1.0,0.0)),f.x),mix(wh(i+vec2(0.0,1.0)),wh(i+vec2(1.0,1.0)),f.x),f.y);}\r\nfloat wf(vec2 p){return wn(p)*.55+wn(p*2.1+7.3)*.3+wn(p*4.3+3.1)*.15;}\r\n`;\r\n// Board shader: charring + glowing cracks/grain embers while burning, blotchy ash with a crack network, then cell-by-cell crumble with dark char edges.\r\nconst WFRAG=`vec4 wcl=texture2D(uCell,vPlanar);float wce=wcl.g;\r\nif(uFireR>0.0){\r\n float bd=length((vPlanar-uFireO)*vec2(1.0,uAsp)),ch=smoothstep(uFireR,uFireR-.25,bd+wf(vPlanar*6.0)*.3-.15),fk=.75+.25*sin(uTime*9.0+wf(vPlanar*9.0)*30.0);\r\n diffuseColor.rgb=mix(diffuseColor.rgb,diffuseColor.rgb*vec3(.2,.13,.1),ch*.92);\r\n float crk=smoothstep(.09,.0,wce)*ch,spk=smoothstep(.62,.82,wf(vPlanar*vec2(16.0,44.0)+3.0))*ch;\r\n totalEmissiveRadiance+=vec3(1.0,.36,.05)*(crk*1.1+spk*.8)*fk;\r\n}\r\nif(uAsh>0.0){\r\n float bl=smoothstep(.4,.78,wf(vPlanar*vec2(5.0,4.0)+1.7));\r\n vec3 ac=mix(vec3(.68,.66,.62),vec3(.14,.12,.11),bl*.85)*clamp(.5+lum,.4,1.25)*(.8+.4*wn(vPlanar*60.0));\r\n diffuseColor.rgb=mix(diffuseColor.rgb,ac,uAsh);roughnessFactor=mix(roughnessFactor,1.0,uAsh);\r\n diffuseColor.rgb*=1.0-.8*smoothstep(.14,.0,wce)*uCrack;\r\n}\r\nif(uCrumble>0.0){\r\n float ct=wcl.r;if(ct<uCrumble)discard;\r\n diffuseColor.rgb*=1.0-.6*smoothstep(.3,.0,wce);\r\n totalEmissiveRadiance+=vec3(1.0,.35,.05)*smoothstep(.08,.0,ct-uCrumble)*smoothstep(.35,.0,wce)*1.5;\r\n}`;\r\nreturn {init,press,move,release,step,dispose,claims,heal,healSecret:heal,uniforms:U,fragmentDecls:WGLSL,fragment:WFRAG};\r\n}\r\n\r\nexport const wood={\r\n id:'wood',asset:'/pod/worlds/boards/wood.glb',flip:false,background:'#140c06',\r\n guide:{color:'#ffe0b0',alpha:.1,width:4},\r\n pattern:{left:.07,top:.03,right:.93,bottom:.78}, // measured in-browser against the carved oval's extremes\r\n ...woodEffect(),trace2d:woodEffect,\r\n};\r\n","modules/portal/portal-board.mjs":"// Quilt cloth board for the portal home. The solver is a port of Ten Minute Physics\r\n// \"Cloth Simulation\" (c) 2022 Matthias Müller, MIT licence (see portal-board NOTICE below),\r\n// adapted to a quilt pinned at its border that fingers press and drag. AGPL-3.0-or-later wrapper.\r\n// MIT License — Copyright (c) 2022 Matthias Müller\r\n// Permission is hereby granted, free of charge, to any person obtaining a copy of this software\r\n// and associated documentation files (the \"Software\"), to deal in the Software without restriction,\r\n// including without limitation the rights to use, copy, modify, merge, publish, distribute,\r\n// sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is\r\n// furnished to do so, subject to the following conditions:\r\n// The above copyright notice and this permission notice shall be included in all copies or\r\n// substantial portions of the Software.\r\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING\r\n// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r\n// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\r\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\nimport * as THREE from 'three';\r\nimport {pieceMaterial,fallPieces,createPortalCutMask} from './portal-cut.mjs';\r\nimport {SHAPES,fromFrame} from './portal-shapes.mjs';\r\n\r\nconst IMAGE='/pod/worlds/quilt.webp',IMAGE_W=1024,IMAGE_H=1666,TRACE_PX=640;\r\n// Stitched pattern (the eight shapes) inside the quilt image, as image fractions.\r\nconst PATTERN={left:22/IMAGE_W,top:22/IMAGE_H,right:1002/IMAGE_W,bottom:1575/IMAGE_H};\r\nconst PATTERN_RATIO=(1002-22)/(1575-22);\r\n// Ian: heavier, calmer (2026-09-22)\r\nexport const QUILT={segX:24,substeps:6,compliance:3e-6,restore:1.0,stretch:1.15,damping:.955,radius:60,depth:40,drag:.7,sleepMs:1500};\r\nconst BACKGROUND='#17111e';\r\n// W2-2O: the quilt texture is Starter-pack art. Without it (offline, not downloaded) the board is a plain\r\n// stitched quilt, same layout: cream cloth in its dark binding, the traceable shapes stitched where the art has them.\r\nconst STITCHES=[['oval','#c42a3c'],['x','#e0388f'],['up','#2c5cc2'],['down','#2f8a4c'],['cross','#4ea6da']];\r\n\r\n// Preserve the complete source image; unused space belongs to the mechanical cap.\r\nexport function quiltSurfaceLayout(width,height){\r\n const w=Math.max(1,width),h=Math.max(1,height),fw=Math.min(w,h*IMAGE_W/IMAGE_H),fh=fw*IMAGE_H/IMAGE_W;\r\n const face={left:(w-fw)/2,top:h-fh,width:fw,height:fh};\r\n return {face,pattern:{left:face.left+fw*PATTERN.left,top:face.top+fh*PATTERN.top,width:fw*(PATTERN.right-PATTERN.left),height:fh*(PATTERN.bottom-PATTERN.top)}};\r\n}\r\n// Vault secret (quilt): two-step fold. Pure reducer: ev {type:'down'|'move'|'up'|'tick'|'cancel',id,x,y,face,w,h} (client px).\r\n// Step 1: two fingers in the face's bottom-left/bottom-right quadrants drag up (>=35% of face height, <=2.5 s) -> lower half folds up.\r\n// Step 2 (<=8 s later): one finger in the folded half's upper band, one in its lower band drag right (>=40% of face width).\r\n// p (0-1) is the live fold progress; release at p>=.6 completes, else falls back. Touches within 24 px of a screen edge (40 px left in step 2) are ignored.\r\nexport const QUILT_SECRET={edge:24,edgeLeft2:40,min1:.35,min2:.4,done:.6,ms1:2500,ms2:8000};\r\nexport const quiltSecretInit=()=>({phase:'idle',pts:{},pair:null,p:0,claimed:[],until:0});\r\nexport function quiltSecret(s,ev,now){\r\n const Q=QUILT_SECRET;s={...s,pts:{...s.pts}};\r\n if(s.phase==='folded1'&&now>s.until)s={...s,phase:'idle',pair:null,p:0}; // window over: the quilt unfolds\r\n const base=s.phase==='fold2'||s.phase==='folded1'?'folded1':'idle',{x,y,face:f}=ev,id=String(ev.id);\r\n if(ev.type==='cancel'){return {...s,phase:s.phase==='done'?'done':base,pts:{},pair:null,p:s.phase==='done'?1:0};}\r\n if(s.phase==='done'||!f)return s;\r\n if(ev.type==='down'){\r\n  if(x<(base==='folded1'?Q.edgeLeft2:Q.edge)||x>ev.w-Q.edge||y<Q.edge||y>ev.h-Q.edge)return s;\r\n  s.pts[id]={x0:x,y0:y,x,y};\r\n  if(!s.pair&&(s.phase==='idle'||s.phase==='folded1')){\r\n   const zone=q=>{if(q.x0<f.left||q.x0>f.left+f.width)return null;const v=(q.y0-f.top)/f.height,l=q.x0<f.left+f.width/2;\r\n    return s.phase==='idle'?(v>.5&&v<=1?(l?'L':'R'):null):(v>=0&&v<.25?'U':v>=.25&&v<=.5?'D':null);};\r\n   const ids=Object.keys(s.pts),z=ids.map(k=>zone(s.pts[k])),want=s.phase==='idle'?['L','R']:['U','D'],a=z.indexOf(want[0]),b=z.indexOf(want[1]);\r\n   if(a>=0&&b>=0)s={...s,phase:s.phase==='idle'?'fold1':'fold2',pair:{a:ids[a],b:ids[b],t0:now},p:0,claimed:[ids[a],ids[b]]};\r\n  }\r\n  return s;\r\n }\r\n if(ev.type==='move'){\r\n  const q=s.pts[id];if(!q)return s;s.pts[id]={...q,x,y};\r\n  if(s.pair&&(id===s.pair.a||id===s.pair.b)){\r\n   const A=s.pts[s.pair.a],B=s.pts[s.pair.b];\r\n   s.p=s.phase==='fold1'?Math.max(0,Math.min(1,Math.min(A.y0-A.y,B.y0-B.y)/(Q.min1*f.height/Q.done))):Math.max(0,Math.min(1,Math.min(A.x-A.x0,B.x-B.x0)/(Q.min2*f.width/Q.done)));\r\n  }\r\n  return s;\r\n }\r\n if(ev.type==='up'){\r\n  delete s.pts[id];\r\n  if(s.pair&&(id===s.pair.a||id===s.pair.b)){\r\n   const ok=s.p>=Q.done&&(s.phase==='fold2'||now-s.pair.t0<=Q.ms1);delete s.pts[s.pair.a];delete s.pts[s.pair.b];\r\n   s=ok?(s.phase==='fold1'?{...s,phase:'folded1',until:now+Q.ms2,pair:null,p:1}:{...s,phase:'done',pair:null,p:1}):{...s,phase:base,pair:null,p:0};\r\n  }\r\n }\r\n return s;\r\n}\r\n// Rigid hinge bend of a point d along a flap (and z0 above it) folded by th about a hinge of radius R: [along, up]. th=pi lays the flap back over the stay half.\r\nexport function quiltBend(d,z0,th,R){const a=Math.min(d/R,th),r=d-R*a;return [R*Math.sin(a)+r*Math.cos(a)-z0*Math.sin(a),R*(1-Math.cos(a))+r*Math.sin(a)+z0*Math.cos(a)];}\r\n\r\nexport function quiltSourceToSurface(u,v,width,height){\r\n const {face}=quiltSurfaceLayout(width,height);return [face.left+u*face.width,face.top+v*face.height];\r\n}\r\n\r\n// Client coordinates are post-transform; the cloth solver is in the host's untransformed\r\n// CSS-pixel space.  A scaled portal therefore keeps presses underneath the visible finger.\r\nexport function clientToBoardLocal(clientX,clientY,clientRect,boardWidth,boardHeight){\r\n if(!clientRect.width||!clientRect.height)return [0,0];\r\n return [(clientX-clientRect.left)*boardWidth/clientRect.width,(clientY-clientRect.top)*boardHeight/clientRect.height];\r\n}\r\n\r\nfunction axisWithAnchors(segments,...anchors){\r\n const values=[0,1,...Array.from({length:segments-1},(_,i)=>(i+1)/segments),...anchors];\r\n return [...new Set(values.map(v=>Math.round(Math.min(1,Math.max(0,v))*1e8)/1e8))].sort((a,b)=>a-b);\r\n}\r\n\r\nfunction remapMargin(t,start,end,sourceStart,sourceEnd){\r\n if(t<=start)return start?sourceStart*t/start:sourceStart;\r\n if(t>=end)return end<1?sourceEnd+(1-sourceEnd)*(t-end)/(1-end):sourceEnd;\r\n return sourceStart+(sourceEnd-sourceStart)*(t-start)/(end-start);\r\n}\r\nfunction plainQuilt(){\r\n const canvas=document.createElement('canvas'),g=canvas.getContext('2d');canvas.width=IMAGE_W/2;canvas.height=IMAGE_H/2;g.scale(.5,.5);\r\n g.fillStyle='#3b3441';g.fillRect(0,0,IMAGE_W,IMAGE_H);g.fillStyle='#efe6d3';g.fillRect(22,22,IMAGE_W-44,IMAGE_H-44);\r\n const x=PATTERN.left*IMAGE_W,y=PATTERN.top*IMAGE_H,w=(PATTERN.right-PATTERN.left)*IMAGE_W,h=(PATTERN.bottom-PATTERN.top)*IMAGE_H;\r\n g.lineWidth=8;g.lineCap='round';g.setLineDash([18,10]);\r\n for(const [id,color] of STITCHES)for(const {points} of SHAPES[id]){\r\n  g.strokeStyle=color;g.beginPath();points.forEach(([u,v],i)=>g[i?'lineTo':'moveTo'](x+u*w,y+v*h));if(id==='oval')g.closePath();g.stroke();\r\n }\r\n return canvas;\r\n}\r\n\r\n// Measured fresh from the host box, so it stays correct before ResizeObserver runs and while the portal is CSS-scaled during a dive.\r\nfunction quiltRectOf(host){const box=host.getBoundingClientRect(),f=quiltSurfaceLayout(box.width,box.height).face;return {left:box.left+f.left,top:box.top+f.top,width:f.width,height:f.height};}\r\nfunction patternRectOf(host){const q=quiltRectOf(host);return {left:q.left+q.width*PATTERN.left,top:q.top+q.height*PATTERN.top,width:q.width*(PATTERN.right-PATTERN.left),height:q.height*(PATTERN.bottom-PATTERN.top)};}\r\n\r\n// The flat board: one still picture on a plain 2D canvas with a board's face layout, shape frame, cut hole and public\r\n// interface. portal.mjs mounts it first, as the base layer under the 3D board, and shows it whenever 3D isn't drawing\r\n// (no WebGL, a lost context, a stalled or broken download), so the portal is never a blank sheet.\r\n// Quilt (the default) draws its plain stitched quilt at once and its art when that arrives, so it cannot fail. A grimoire\r\n// board passes its poster (src), face width/height (ratio), shape frame ({x0,y0,x1,y1} face fractions) and guide, and\r\n// rejects when the poster doesn't load within waitMs, so the portal can keep the board it already shows.\r\n// trace (R7): the board's own touch effect in 2D (ice cracks, flowers, embers, weld, jelly gash) for when its 3D can't\r\n// draw: a factory for an effect with portal-board-glb's interface, given 2D paint/glow layers over the face (glow adds\r\n// light, as the 3D emissive does). The canvas redraws only while that effect animates.\r\n// ponytail: no cloth ripple, dent or falling piece; the cut just opens a hole.\r\nexport async function createQuiltBoard2D(host,{src=IMAGE,ratio=IMAGE_W/IMAGE_H,frame={x0:PATTERN.left,y0:PATTERN.top,x1:PATTERN.right,y1:PATTERN.bottom},background=BACKGROUND,guide=null,fallback=src===IMAGE?plainQuilt:null,waitMs=0,trace=null,tint=null,tintSelected=true,tintTarget='poster',backplateTint='#263943',backplateTintSelected=true}={}){\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n const art=new Promise((ok,fail)=>{const img=new Image();img.onload=()=>ok(img);img.onerror=()=>fail(new Error('Board art unavailable: '+src));img.src=src;if(waitMs)setTimeout(()=>fail(new Error('Board art timed out: '+src)),waitMs);});\r\n let image=fallback?.(),width=1,height=1,holes=[],disposed=false,_tint=(typeof tint==='string'&&/^#[0-9A-Fa-f]{6}$/.test(tint))?tint:null,_traceTint=_tint,_traceSelected=!!tintSelected,_backplateTint=(typeof backplateTint==='string'&&/^#[0-9A-Fa-f]{6}$/.test(backplateTint))?backplateTint:'#263943',_backplateSelected=!!backplateTintSelected;\r\n if(image)art.then(img=>{image=img;draw();},()=>{});else image=await art;\r\n const canvas=document.createElement('canvas'),g=canvas.getContext('2d'); // no 2D context: a bare face, but the frame, layout and cuts still work\r\n canvas.className='portal-board-canvas';canvas.setAttribute('aria-hidden','true');canvas.style.cssText='position:absolute;inset:0;display:block;width:100%;height:100%';host.append(canvas);\r\n const faceOf=(w,h)=>{const fw=Math.min(w,h*ratio);return {left:(w-fw)/2,top:h-fw/ratio,width:fw,height:fw/ratio};};\r\n const rectOf=()=>{const box=host.getBoundingClientRect(),f=faceOf(box.width,box.height);return {left:box.left+f.left,top:box.top+f.top,width:f.width,height:f.height};};\r\n // The poster and its guides. A board with a trace draws them once per size into `still` and blits that on every trace\r\n // frame: re-drawing the poster and the blurred guide strokes each frame starved a phone's main thread (and a test's rAF).\r\n let still=null;\r\nconst tintCache=new Map();\r\n function paintStill(c,face){\r\n  if(_tint){\r\n    const tw=Math.max(1,Math.round(face.width)),th=Math.max(1,Math.round(face.height));\r\n    const metal=!!trace?.metal&&_traceSelected,cogs=tintTarget==='cogs',key=`${image.src}-${tw}x${th}-${_tint}-${metal}-${cogs}-${_backplateTint}-${_backplateSelected}`;\r\n    let off;\r\n    if(tintCache.has(key)){\r\n      off=tintCache.get(key);\r\n    }else{\r\n      const tmp=document.createElement('canvas');\r\n      tmp.width=tw;tmp.height=th;\r\n      const tc=tmp.getContext('2d');\r\n      tc.drawImage(image,0,0,tw,th);\r\n      const imgData=tc.getImageData(0,0,tw,th);\r\n      const data=imgData.data;\r\n      const tintRGB=parseInt(_tint.slice(1),16);\r\n      const tr=(tintRGB>>16)&255, tg=(tintRGB>>8)&255, tb=tintRGB&255;\r\n      for(let i=0;i<data.length;i+=4){\r\n        const a=data[i+3];\r\n        if(a===0)continue;\r\n        const lum=data[i]*.2126+data[i+1]*.7152+data[i+2]*.0722;\r\n        if(cogs){\r\n         const hi=Math.max(data[i],data[i+1],data[i+2]),lo=Math.min(data[i],data[i+1],data[i+2]),chroma=hi-lo,l=lum/255;\r\n         if(chroma<42&&l>.055&&l<.49){ // muted dark panels in the poster stand in for the separate backplate\r\n          const rgb=parseInt(_backplateTint.slice(1),16),k=.28+.78*l;\r\n          data[i]=Math.min(255,((rgb>>16)&255)*k);data[i+1]=Math.min(255,((rgb>>8)&255)*k);data[i+2]=Math.min(255,(rgb&255)*k);\r\n         }else if(chroma>=42){ // colored gear teeth, pipes and lamps share the mechanism tint, including its default\r\n          const l0=lum/255,k=.12+1.35*l0,s=l0>.55?((l0-.55)/.45)**2*.7:0;\r\n          data[i]=Math.min(255,tr*k)*(1-s)+255*s;data[i+1]=Math.min(255,tg*k)*(1-s)+255*s;data[i+2]=Math.min(255,tb*k)*(1-s)+255*s;\r\n         }\r\n         continue;\r\n        }\r\n        if(metal){ // anodized metal (Cogs): deeper shadows, tint through the mids, a white-hot specular top\r\n         const l=lum/255,k=.12+1.35*l,s=l>.55?((l-.55)/.45)**2*.7:0;\r\n         data[i]=Math.min(255,tr*k)*(1-s)+255*s;data[i+1]=Math.min(255,tg*k)*(1-s)+255*s;data[i+2]=Math.min(255,tb*k)*(1-s)+255*s;\r\n         continue;\r\n        }\r\n        data[i]=lum*tr/255;\r\n        data[i+1]=lum*tg/255;\r\n        data[i+2]=lum*tb/255;\r\n      }\r\n      tc.putImageData(imgData,0,0);\r\n      off=tmp;\r\n      tintCache.clear();\r\ntintCache.set(key,tmp);\r\n    }\r\n    c.drawImage(off,face.left,face.top,face.width,face.height);\r\n  } else {\r\n    c.drawImage(image,face.left,face.top,face.width,face.height);\r\n  }\r\n  // A GLB board's guides are carved or painted in 3D, not in its flat poster: draw the same shape paths in its frame.\r\n  if(guide){\r\n   const trace=()=>{for(const [id,polys] of Object.entries(SHAPES)){if(id==='line')continue;for(const {points} of polys){c.beginPath();points.forEach(([u,v],i)=>{const [fu,fv]=fromFrame(u,v,frame);c[i?'lineTo':'moveTo'](face.left+fu*face.width,face.top+fv*face.height);});c.stroke();}}};\r\n   const alpha=Math.max(guide.alpha||0,.42);c.strokeStyle=guide.color||'#fff';c.lineCap=c.lineJoin='round';\r\n   c.shadowColor=c.strokeStyle;c.shadowBlur=8;c.globalAlpha=alpha*.65;c.lineWidth=5;trace();c.shadowBlur=0;c.globalAlpha=alpha;c.lineWidth=2;trace();\r\n  }\r\n }\r\n function draw(){\r\n  if(disposed||!g)return;\r\n  const scale=Math.min(devicePixelRatio||1,2),face=faceOf(width,height),W=Math.round(width*scale),H=Math.round(height*scale);\r\n  if(canvas.width!==W||canvas.height!==H){canvas.width=W;canvas.height=H;}else{g.setTransform(1,0,0,1,0,0);g.clearRect(0,0,W,H);} // resizing also clears\r\n  if(fx&&(still?.width!==W||still.height!==H||still.image!==image)){still=Object.assign(document.createElement('canvas'),{width:W,height:H,image});const c=still.getContext('2d');c.setTransform(scale,0,0,scale,0,0);paintStill(c,face);}\r\n  g.setTransform(scale,0,0,scale,0,0);g.save();\r\n  if(holes.length){g.beginPath();g.rect(0,0,width,height);for(const poly of holes){poly.forEach(([u,v],i)=>g[i?'lineTo':'moveTo'](face.left+u*face.width,face.top+v*face.height));g.closePath();}g.clip('evenodd');}\r\n  if(fx)g.drawImage(still,0,0,width,height);else paintStill(g,face);\r\n  if(fx){ // paint, a dark silhouette of the glow (so light glow still reads on a pale poster like Ice's), then the glow as light\r\n   const put=c=>g.drawImage(c,face.left,face.top,face.width,face.height);\r\n   g.globalAlpha=1;g.shadowBlur=0;put(fx.paint.canvas);g.filter='brightness(0)';g.globalAlpha=.8;put(fx.glow.canvas);g.filter='none';g.globalAlpha=1;g.globalCompositeOperation='lighter';put(fx.glow.canvas);\r\n  }\r\n  g.restore();\r\n }\r\n function layout(box={width:host.clientWidth,height:host.clientHeight}){\r\n  if(!box.width||!box.height)return; // hidden (display:none) reads 0x0: keep the last layout\r\n  width=box.width;height=box.height;\r\n  if(canvas.style.visibility!=='hidden')for(const [k,v] of Object.entries(faceOf(width,height)))host.style.setProperty('--face-'+k,v+'px'); // under a live 3D board, that board owns the frame\r\n  draw();\r\n }\r\n // The 2D trace: its layers TRACE_PX wide in face coords (u right, v down) like the 3D board's, redrawn by rAF while it runs.\r\n let fx=null,raf=0,last=0;const pointers=new Map();\r\n function tick(now){raf=0;if(disposed||!fx)return;const on=fx.step?.(Math.min(1/30,Math.max(1/240,(now-last)/1000)),now);last=now;draw();if(on||pointers.size)raf=requestAnimationFrame(tick);}\r\n const wake=()=>{if(!raf&&fx&&!disposed){last=performance.now();raf=requestAnimationFrame(tick);}};\r\n const observer=new ResizeObserver(entries=>layout(entries.at(-1).contentRect));observer.observe(host);layout();\r\n if(trace&&g){\r\n  const layer=()=>{const c=document.createElement('canvas');c.width=TRACE_PX;c.height=Math.max(1,Math.round(TRACE_PX/ratio));return {canvas:c,ctx:c.getContext('2d'),texture:{}};};\r\n  const toWorld=(u,v)=>{const f=faceOf(width,height);return [f.left+u*f.width,-(f.top+v*f.height)];};\r\n  const next=trace(),paint=layer(),glow=layer();\r\n  await next.init({paint,glow,face:{w:1,h:1/ratio},toWorld,wake});\r\n  fx=Object.assign(next,{paint,glow});if(_traceTint&&/^#[0-9a-f]{6}$/i.test(_traceTint))fx.setTint?.(_traceTint,_traceSelected);draw(); // the still is ready before the first touch\r\n }\r\n return {\r\n  canvas,background,faceRect:rectOf,quiltRect:rectOf,\r\n  patternRect(){const q=rectOf();return {left:q.left+q.width*frame.x0,top:q.top+q.height*frame.y0,width:q.width*(frame.x1-frame.x0),height:q.height*(frame.y1-frame.y0)};},\r\n  cut(poly,color,ms=1100){holes=[poly];draw();return new Promise(done=>setTimeout(done,reduced?0:ms));},\r\n  heal(){if(holes.length){holes=[];draw();}},\r\n  setTint(hex,selected=true){\r\n   if(!/^#[0-9a-f]{6}$/i.test(hex))return;\r\n   _traceTint=hex;_traceSelected=selected;fx?.setTint?.(hex,selected);\r\n   if(tintTarget==='trace')return;\r\n   _tint=hex;\r\n   still=null;\r\n   draw();\r\n  },\r\n  setBackplateTint(hex,selected=true){\r\n   if(!/^#[0-9a-f]{6}$/i.test(hex))return;\r\n   _backplateTint=selected?hex:'#263943';_backplateSelected=selected;\r\n   still=null;draw();\r\n  },\r\n  press(id,x,y){\r\n   if(!fx)return;const r=rectOf(),u=Math.min(1,Math.max(0,(x-r.left)/r.width)),v=Math.min(1,Math.max(0,(y-r.top)/r.height)),p=pointers.get(id);\r\n   if(p){fx.move?.(id,u,v,p.u,p.v);p.u=u;p.v=v;}else{pointers.set(id,{u,v});fx.press?.(id,u,v);}\r\n   wake();\r\n  },\r\n  claims(){return false;},\r\n  release(id){const p=pointers.get(id);if(p){pointers.delete(id);fx.release?.(id,p.u,p.v);wake();}},\r\n  frameMs:()=>0,\r\n  pause(){for(const [id,p] of pointers)fx.release?.(id,p.u,p.v);pointers.clear();cancelAnimationFrame(raf);raf=0;},\r\n  resume(){layout();wake();}, // back on screen (or back from under a 3D board): re-take the frame\r\n  dispose(){disposed=true;cancelAnimationFrame(raf);observer.disconnect();fx?.dispose?.();canvas.remove();},\r\n };\r\n}\r\n\r\n// The WebGL cloth quilt (portal.mjs lays it over the flat quilt once it has drawn).\r\nexport async function createQuiltBoardGL(host,{knobs=QUILT}={}){\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n // The art first, the renderer after: a stalled download never holds a WebGL context.\r\n let texture;\r\n try{texture=await new THREE.TextureLoader().loadAsync(IMAGE);}\r\n catch{texture=new THREE.CanvasTexture(plainQuilt());}\r\n // Transparent canvas; BACKGROUND goes on #portalHome (board.background) so the neon glass shows only through a cut.\r\n const renderer=new THREE.WebGLRenderer({antialias:true,alpha:true,powerPreference:'low-power'});\r\n renderer.setPixelRatio(Math.min(devicePixelRatio||1,2));renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.setClearColor(0x000000,0);\r\n const canvas=renderer.domElement;canvas.className='portal-board-canvas';canvas.setAttribute('aria-hidden','true');canvas.style.cssText='display:block;width:100%;height:100%';host.append(canvas);\r\n let observer,geometry,material,pieceMat,cutMask=null,frame=0,disposed=false; // outside the try: a failed build must also stop its frame loop\r\n try{ // a failure after the renderer exists must not leave its canvas and context behind\r\n texture.colorSpace=THREE.SRGBColorSpace;texture.anisotropy=4;\r\n const scene=new THREE.Scene(),camera=new THREE.PerspectiveCamera(42,1,1,20000);\r\n scene.add(new THREE.HemisphereLight(0xfff4e6,0x3a2f40,1.1));\r\n const sun=new THREE.DirectionalLight(0xfff0dc,2.4);sun.position.set(-.7,.55,.45);scene.add(sun);\r\n material=new THREE.MeshStandardMaterial({map:texture,roughness:.95,metalness:0,side:THREE.DoubleSide});\r\n const cutSide={value:0},cutMaskUniform={value:null};material.userData.portalCutSideUniform=cutSide;\r\n material.onBeforeCompile=shader=>{\r\n  shader.uniforms.uPortalCutMask=cutMaskUniform;shader.uniforms.uPortalCutSide=cutSide;\r\n  shader.vertexShader=shader.vertexShader.replace('#include <common>','#include <common>\\nattribute vec2 portalCutUv;\\nvarying vec2 vPortalCutUv;')\r\n   .replace('#include <begin_vertex>','#include <begin_vertex>\\nvPortalCutUv=portalCutUv;');\r\n  shader.fragmentShader=shader.fragmentShader.replace('#include <common>','#include <common>\\nvarying vec2 vPortalCutUv;\\nuniform sampler2D uPortalCutMask;\\nuniform float uPortalCutSide;')\r\n   .replace('#include <map_fragment>','#include <map_fragment>\\nif(!gl_FrontFacing){vec2 q=vPortalCutUv;float bind=step(q.x,.022)+step(.978,q.x)+step(q.y,.015)+step(.985,q.y);float lum=dot(diffuseColor.rgb,vec3(.3,.59,.11));vec3 back=mix(vec3(lum),diffuseColor.rgb,.4)*vec3(.62,.58,.55);vec2 cell=fract(q*vec2(12.,19.5));float edge=min(min(cell.x,1.-cell.x),min(cell.y,1.-cell.y)),puff=sin(cell.x*3.14159)*sin(cell.y*3.14159);float stitch=(1.-smoothstep(.015,.05,edge))*step(.35,fract((q.x+q.y)*150.));back*=.72+.38*puff;back=mix(back,back*.3,(1.-smoothstep(.0,.09,edge))*.55);back=mix(back,vec3(.62,.55,.46),stitch*.8);diffuseColor.rgb=mix(back,vec3(.04,.035,.045),min(bind,1.));}')\r\n   .replace('#include <opaque_fragment>','if(!gl_FrontFacing)outgoingLight=max(outgoingLight,diffuseColor.rgb*.6);\\n#include <opaque_fragment>')\r\n   .replace('#include <alphatest_fragment>','float portalCutCoverage=1.0;if(abs(uPortalCutSide)>.5){portalCutCoverage=texture2D(uPortalCutMask,vPortalCutUv).r;if(uPortalCutSide>.5&&portalCutCoverage<.5)discard;if(uPortalCutSide<-.5&&portalCutCoverage>=.5)discard;}\\n#include <alphatest_fragment>');\r\n };\r\n material.customProgramCacheKey=()=> 'portal-quilt-cut-mask-v2';\r\n const segX=knobs.segX,segY=Math.round(segX*IMAGE_H/IMAGE_W);\r\n // Source-pattern anchor vertices stay in the topology.  layout() moves them to the\r\n // current pattern boundary, so resizing or rotation never interpolates across a stitch edge.\r\n const xAxis=axisWithAnchors(segX,PATTERN.left,PATTERN.right),yAxis=axisWithAnchors(segY,PATTERN.top,PATTERN.bottom),cols=xAxis.length,rows=yAxis.length,count=cols*rows;\r\n const pos=new Float32Array(count*3),prev=new Float32Array(count*3),rest=new Float32Array(count*3),invMass=new Float32Array(count),uv=new Float32Array(count*2),index=[];\r\n for(let j=0;j<rows;j++)for(let i=0;i<cols;i++){const n=j*cols+i;invMass[n]=i===0||j===0||i===cols-1||j===rows-1?0:1;}\r\n for(let j=0;j<rows-1;j++)for(let i=0;i<cols-1;i++){const a=j*cols+i,b=a+1,c=a+cols,d=c+1;index.push(a,c,b,b,c,d);}\r\n // Stretch constraints along every triangle edge; bending between the two far corners of each triangle pair.\r\n const edges=new Map();\r\n for(let t=0;t<index.length;t+=3)for(let k=0;k<3;k++){const a=index[t+k],b=index[t+(k+1)%3],o=index[t+(k+2)%3],key=Math.min(a,b)*count+Math.max(a,b);(edges.get(key)||edges.set(key,{a,b,far:[]}).get(key)).far.push(o);}\r\n const stretch=[],bend=[];for(const e of edges.values()){stretch.push(e.a,e.b);if(e.far.length===2)bend.push(e.far[0],e.far[1]);}\r\n const stretchIds=new Int32Array(stretch),bendIds=new Int32Array(bend),stretchLen=new Float32Array(stretch.length/2),bendLen=new Float32Array(bend.length/2);\r\n const cutUv=new Float32Array(count*2);\r\n geometry=new THREE.BufferGeometry();geometry.setAttribute('position',new THREE.BufferAttribute(pos,3));geometry.setAttribute('uv',new THREE.BufferAttribute(uv,2));geometry.setAttribute('portalCutUv',new THREE.BufferAttribute(cutUv,2));geometry.setIndex(index);\r\n const mesh=new THREE.Mesh(geometry,material);mesh.frustumCulled=false;scene.add(mesh);\r\n // Transparent twin for cut pieces, drawn once at load (opacity 0 over the quilt: invisible) so the first cut doesn't hitch on a compile.\r\n pieceMat=pieceMaterial(material);const pieceSide={value:0},sourceCompile=pieceMat.onBeforeCompile;pieceMat.userData.portalCutSideUniform=pieceSide;pieceMat.onBeforeCompile=function(shader,renderer){sourceCompile.call(this,shader,renderer);shader.uniforms.uPortalCutMask=cutMaskUniform;shader.uniforms.uPortalCutSide=pieceSide;};const warm=new THREE.Mesh(geometry,pieceMat);pieceMat.opacity=0;warm.frustumCulled=false;scene.add(warm);\r\n const fullIndex=geometry.index;let cutting=null;\r\n\r\n let width=1,height=1,surface=quiltSurfaceLayout(1,1),paused=false,awakeUntil=0,last=0,frameMs=0;\r\n const pointers=new Map();\r\n\r\n // Vault secret: fold state (see quiltSecret). vis = on-screen fold progress of step 1/2 (follows the fingers, eases otherwise).\r\n let qs=quiltSecretInit(),slide=0,slid=false,wasFolded=false,hing={x:0,y:0};const vis=[0,0],seen=new Set(),claimedIds=new Set(),R1=3,R2=10;\r\n const shadowTex=(()=>{const c=document.createElement('canvas');c.width=c.height=128;const g=c.getContext('2d');g.shadowColor='#140a1e';g.shadowBlur=22;g.shadowOffsetX=1000;g.fillStyle='#000';g.fillRect(-1000-60,24,1000+60+128+60,200);return new THREE.CanvasTexture(c);})();\r\n const shadow=new THREE.Mesh(new THREE.PlaneGeometry(1,1),new THREE.MeshBasicMaterial({map:shadowTex,transparent:true,depthWrite:false,opacity:0}));shadow.visible=false;shadow.frustumCulled=false;scene.add(shadow);\r\n // Untransformed size (the observer's contentRect, else clientWidth): the portal can be re-shown mid-dive, scaled.\r\n function layout(box={width:host.clientWidth,height:host.clientHeight}){\r\n  width=Math.max(1,box.width);height=Math.max(1,box.height);\r\n  surface=quiltSurfaceLayout(width,height);const {face,pattern}=surface;\r\n  for(const k in face)host.style.setProperty('--face-'+k,face[k]+'px'); // the portal's metal frame (#111) wraps the full cloth\r\n  for(let j=0;j<rows;j++)for(let i=0;i<cols;i++){\r\n   const n=j*cols+i,p=3*n,u=xAxis[i],v=yAxis[j];\r\n   rest[p]=face.left+u*face.width;\r\n   rest[p+1]=-(face.top+v*face.height);rest[p+2]=0;\r\n   uv[2*n]=u;uv[2*n+1]=1-v;cutUv[2*n]=u;cutUv[2*n+1]=v;\r\n  }\r\n  pos.set(rest);prev.set(rest);\r\n  {let by=1/0,bx=1/0;for(let j=0;j<rows;j++){const y=rest[3*j*cols+1];if(Math.abs(y+face.top+face.height/2)<by){by=Math.abs(y+face.top+face.height/2);hing.y=y;}}for(let i=0;i<cols;i++){const x=rest[3*i];if(Math.abs(x-face.left-face.width/2)<bx){bx=Math.abs(x-face.left-face.width/2);hing.x=x;}}} // hinge lines sit on the nearest grid row/column to the face centre\r\n  const dist=(ids,k,a=ids[2*k],b=ids[2*k+1])=>Math.hypot(rest[3*a]-rest[3*b],rest[3*a+1]-rest[3*b+1]);\r\n  for(let k=0;k<stretchLen.length;k++)stretchLen[k]=dist(stretchIds,k);for(let k=0;k<bendLen.length;k++)bendLen[k]=dist(bendIds,k);\r\n  renderer.setSize(width,height,false);camera.aspect=width/height;\r\n  // World units are CSS pixels on the z=0 plane: x right, y up (screen y negated).\r\n  camera.position.set(width/2,-height/2,(height/2)/Math.tan(THREE.MathUtils.degToRad(camera.fov/2)));camera.near=camera.position.z/10;camera.far=camera.position.z*10;camera.lookAt(width/2,-height/2,0);camera.updateProjectionMatrix();\r\n  geometry.attributes.position.needsUpdate=true;geometry.attributes.uv.needsUpdate=true;geometry.attributes.portalCutUv.needsUpdate=true;geometry.computeVertexNormals();wake();\r\n }\r\n\r\n const folded=()=>vis[0]>0||vis[1]>0||slide>0,qBusy=()=>qs.phase!=='idle'||folded()&&!(slid&&qs.phase==='done');\r\n function applyFold(){\r\n  const a1=vis[0]*Math.PI,a2=vis[1]*Math.PI,f=surface.face,ox=slide*(width-hing.x+60);\r\n  for(let n=0;n<count;n++){const p=3*n;let x=rest[p],y=rest[p+1],z=0;\r\n   if(a1>0&&y<hing.y-.01){const b=quiltBend(hing.y-y,0,a1,R1);y=hing.y-b[0];z=b[1];}\r\n   if(a2>0&&x<hing.x-.01){const b=quiltBend(hing.x-x,z,a2,R2);x=hing.x-b[0];z=b[1];}\r\n   pos[p]=prev[p]=x+ox;pos[p+1]=prev[p+1]=y;pos[p+2]=prev[p+2]=z*1.5;} // z stretched 1.5x so a lifted flap shows real perspective\r\n  // soft shadow on the half under the lifted flap: a gradient plane, hard at the hinge, fading toward the flap's far end\r\n  const two=a2>.01,a=two?a2:a1,R=two?R2:R1,far=two?hing.x-f.left:hing.y+f.top+f.height,ext=-quiltBend(far,two?R1*2:0,a,R)[0],ok=a>.01&&ext>1&&!slide;\r\n  shadow.visible=ok;if(!ok)return;\r\n  shadow.material.opacity=.7*Math.sin(a);const L=(ext*1.15+24)/.8125;\r\n  if(two){shadow.rotation.z=-Math.PI/2;shadow.scale.set(-f.top-hing.y,L,1);shadow.position.set(hing.x+L/2,(hing.y-f.top)/2,7.5);} // stay half = top-right quarter: y from face top to the hinge\r\n  else{shadow.rotation.z=0;shadow.scale.set(f.width,L,1);shadow.position.set(f.left+f.width/2,hing.y+L/2,1);}\r\n }\r\n function qAnim(dt,now){\r\n  qs=quiltSecret(qs,{type:'tick'},now);const ph=qs.phase,t=[ph==='idle'?0:ph==='fold1'?qs.p:1,ph==='fold2'?qs.p:ph==='done'?1:0];\r\n  for(let i=0;i<2;i++){const live=ph===(i?'fold2':'fold1');vis[i]=reduced||live&&Math.abs(t[i]-vis[i])<.5?t[i]:vis[i]+Math.sign(t[i]-vis[i])*Math.min(Math.abs(t[i]-vis[i]),dt*(live?6:3.2));}\r\n  if(ph==='done'&&vis[1]>=.999){slide=reduced?1:Math.min(1,slide+dt/.7);if(slide>=1&&!slid){slid=true;dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:'quilt'}}));}}\r\n  else if(ph!=='done')slide=0;\r\n }\r\n function qEv(ev){\r\n  qs=quiltSecret(qs,{...ev,face:quiltRect(),w:innerWidth,h:innerHeight},performance.now());qs.claimed.forEach(i=>claimedIds.add(i));\r\n  if(qs.pair){pointers.delete(+qs.pair.a);pointers.delete(+qs.pair.b);}wake();\r\n }\r\n function resetSecret(){\r\n  const was=wasFolded||qs.phase!=='idle'||folded();qs=quiltSecretInit();vis[0]=vis[1]=slide=0;slid=false;seen.clear();claimedIds.clear();shadow.visible=false;wasFolded=false;\r\n  if(was&&!disposed){pos.set(rest);prev.set(rest);geometry.attributes.position.needsUpdate=true;geometry.computeVertexNormals();renderer.render(scene,camera);}\r\n }\r\n function solve(ids,lengths,alpha){\r\n  for(let k=0;k<lengths.length;k++){\r\n   const a=ids[2*k],b=ids[2*k+1],wa=invMass[a],wb=invMass[b],w=wa+wb;if(!w)continue;\r\n   const dx=pos[3*a]-pos[3*b],dy=pos[3*a+1]-pos[3*b+1],dz=pos[3*a+2]-pos[3*b+2],len=Math.hypot(dx,dy,dz);if(!len)continue;\r\n   const s=-(len-lengths[k])/(w+alpha)/len;\r\n   pos[3*a]+=dx*s*wa;pos[3*a+1]+=dy*s*wa;pos[3*a+2]+=dz*s*wa;pos[3*b]-=dx*s*wb;pos[3*b+1]-=dy*s*wb;pos[3*b+2]-=dz*s*wb;\r\n  }\r\n }\r\n function step(dt){\r\n  const sdt=dt/knobs.substeps,alpha=knobs.compliance/sdt/sdt,pull=1-Math.exp(-knobs.restore*sdt),r2=knobs.radius*knobs.radius;\r\n  for(let s=0;s<knobs.substeps;s++){\r\n   for(let n=0;n<count;n++){if(!invMass[n])continue;const p=3*n;\r\n    for(let c=0;c<3;c++){const v=(pos[p+c]-prev[p+c])*knobs.damping;prev[p+c]=pos[p+c];pos[p+c]+=v+(rest[p+c]-pos[p+c])*pull;}\r\n   }\r\n   // A finger presses the fabric in and drags it a little along the stroke.\r\n   for(const touch of pointers.values()){\r\n    const tx=touch.x,ty=-touch.y,mx=(touch.x-touch.px)*knobs.drag/knobs.substeps,my=-(touch.y-touch.py)*knobs.drag/knobs.substeps;\r\n    for(let n=0;n<count;n++){if(!invMass[n])continue;const p=3*n,dx=pos[p]-tx,dy=pos[p+1]-ty,d2=dx*dx+dy*dy;if(d2>r2)continue;\r\n     const f=(1-Math.sqrt(d2)/knobs.radius)**2;pos[p+2]=Math.min(pos[p+2],pos[p+2]+(-knobs.depth*f-pos[p+2])*.5);pos[p]+=mx*f;pos[p+1]+=my*f;}\r\n   }\r\n   solve(stretchIds,stretchLen,alpha);solve(bendIds,bendLen,alpha*4);\r\n  }\r\n  for(const touch of pointers.values()){touch.px=touch.x;touch.py=touch.y;}\r\n }\r\n function wake(){awakeUntil=performance.now()+(reduced?0:knobs.sleepMs);if(!frame&&!disposed&&!paused){last=performance.now();frame=requestAnimationFrame(tick);}}\r\n function tick(now){\r\n  frame=0;if(disposed||paused)return;\r\n  const dt=Math.min(1/30,Math.max(1/240,(now-last)/1000));last=now;\r\n  if(!document.hidden){const t=performance.now();qAnim(dt,now);if(folded()){applyFold();wasFolded=true;}else{if(wasFolded){wasFolded=false;shadow.visible=false;pos.set(rest);prev.set(rest);}if(!reduced)step(dt);}if(cutting?.fall.live)cutting.fall.pose(now);geometry.attributes.position.needsUpdate=true;geometry.computeVertexNormals();renderer.render(scene,camera);frameMs=frameMs*.9+(performance.now()-t)*.1;}\r\n  if(pointers.size||now<awakeUntil||cutting?.fall.live||qBusy())frame=requestAnimationFrame(tick);\r\n }\r\n const local=(x,y)=>clientToBoardLocal(x,y,host.getBoundingClientRect(),width,height);\r\n // Hidden (display:none) reads as 0x0: keep the last layout rather than shrink the renderer and reset the cloth, only to\r\n // rebuild both at full size the moment the quilt shows again.\r\n observer=new ResizeObserver(entries=>{const box=entries.at(-1).contentRect;if(box.width&&box.height)layout(box);});observer.observe(host);layout();renderer.render(scene,camera);scene.remove(warm);\r\n const quiltRect=()=>quiltRectOf(host);\r\n // Both the cloth and its falling snapshot retain boundary triangles. A shared local face-space\r\n // mask discards complementary pixels, so cut quality does not depend on the cloth grid density.\r\n function cut(poly,color,ms=1100){\r\n  if(reduced)ms=0;\r\n  heal();\r\n  cutMask=createPortalCutMask(poly);cutMaskUniform.value=cutMask;cutSide.value=-1;pieceSide.value=1;\r\n  const P=pos.slice(),U=uv.slice(),C=cutUv.slice(),pieceGeometry=new THREE.BufferGeometry();\r\n  pieceGeometry.setAttribute('position',new THREE.Float32BufferAttribute(P,3));pieceGeometry.setAttribute('uv',new THREE.Float32BufferAttribute(U,2));pieceGeometry.setAttribute('portalCutUv',new THREE.Float32BufferAttribute(C,2));pieceGeometry.setIndex(new THREE.BufferAttribute(fullIndex.array.slice(),1));pieceGeometry.computeVertexNormals();\r\n  let u=0,v=0;for(const point of poly){u+=point[0];v+=point[1];}u/=poly.length;v/=poly.length;\r\n  const cx=surface.face.left+u*surface.face.width,cy=-(surface.face.top+v*surface.face.height),cz=0;\r\n  const piece=new THREE.Mesh(pieceGeometry,pieceMat),pivot=new THREE.Group();piece.frustumCulled=false;piece.position.set(-cx,-cy,-cz);pivot.position.set(cx,cy,cz);pivot.add(piece);scene.add(pivot);\r\n  const pieces=[{pivot,material:pieceMat,drop(){scene.remove(pivot);pieceGeometry.dispose();}}];\r\n  cutting={fall:fallPieces(pieces,height*.35,ms)};wake();\r\n  return cutting.fall.done;\r\n }\r\n function heal(){\r\n  resetSecret();\r\n  if(!cutting)return;\r\n  cutting.fall.end();cutSide.value=0;pieceSide.value=0;cutMaskUniform.value=null;cutMask?.dispose();cutMask=null;cutting=null;\r\n  if(!disposed){geometry.computeVertexNormals();renderer.render(scene,camera);} // healed frame on the canvas now, even while paused\r\n }\r\n return {\r\n  canvas,\r\n  glContext:renderer.getContext(),\r\n  background:BACKGROUND,\r\n  faceRect:quiltRect,\r\n  cut,heal,\r\n  // Stitched-shape area in client pixels; the portal normalises traces against it.\r\n  patternRect:()=>patternRectOf(host),\r\n  quiltRect,\r\n  press(id,clientX,clientY){const k=String(id),first=!seen.has(id);if(first)claimedIds.delete(k);seen.add(id);qEv({type:first?'down':'move',id,x:clientX,y:clientY});if(qs.pair&&(k===qs.pair.a||k===qs.pair.b))return;if(reduced)return;const [x,y]=local(clientX,clientY),touch=pointers.get(id);if(touch){touch.x=x;touch.y=y;}else pointers.set(id,{x,y,px:x,py:y});wake();},\r\n  claims:id=>claimedIds.has(String(id)),\r\n  release(id){seen.delete(id);qEv({type:'up',id});pointers.delete(id);wake();},\r\n  // test/preview: drive a fold step through the real reducer (p 0-1 of the gesture; release=true lifts the fingers). Step 2 needs step 1 done first.\r\n  secretDebug:{cancel:()=>qEv({type:'cancel'}),state:()=>qs,vis:()=>[...vis,slide],\r\n   fold(step,p,release=true){const f=quiltRect(),A=9001,B=9002,s=step===1,pts=s?[[.25,.85],[.75,.85]]:[[.3,.1],[.3,.35]],Q=QUILT_SECRET,d=p*(s?Q.min1*f.height:Q.min2*f.width)/Q.done;\r\n    const at=(k,dx,dy)=>[f.left+f.width*pts[k][0]+dx,f.top+f.height*pts[k][1]+dy];\r\n    for(const [k,id] of [[0,A],[1,B]]){seen.add(id);claimedIds.delete(String(id));qEv({type:'down',id,x:at(k,0,0)[0],y:at(k,0,0)[1]});}\r\n    for(const [k,id] of [[0,A],[1,B]])qEv({type:'move',id,x:at(k,s?0:d,s?-d:0)[0],y:at(k,s?0:d,s?-d:0)[1]});\r\n    if(release)for(const id of [A,B]){seen.delete(id);qEv({type:'up',id});}}},\r\n  frameMs:()=>frameMs,\r\n  pause(){paused=true;pointers.clear();if(qs.pair)qEv({type:'cancel'});cancelAnimationFrame(frame);frame=0;},\r\n  resume(){paused=false;wake();},\r\n  dispose(){cutting?.fall.end();cutMask?.dispose();cutMask=null;pieceMat.dispose();disposed=true;cancelAnimationFrame(frame);observer.disconnect();geometry.dispose();material.dispose();texture.dispose();renderer.dispose();renderer.forceContextLoss();canvas.remove();},\r\n };\r\n }catch(error){disposed=true;cancelAnimationFrame(frame);observer?.disconnect();pieceMat?.dispose();geometry?.dispose();material?.dispose();texture?.dispose();renderer.dispose();renderer.forceContextLoss();canvas.remove();throw error;}\r\n}\r\n","modules/portal/portal-cut.mjs":"import * as THREE from 'three';\r\n\r\n// One antialiased face-space mask defines both sides of a portal cut. Drawing the polygon once and\r\n// sampling it in each material keeps the board opening and the piece edge complementary even when\r\n// the falling piece translates, tilts, or scales in its own local space.\r\nexport function createPortalCutMask(poly,size=1024){\r\n const canvas=document.createElement('canvas');canvas.width=canvas.height=size;\r\n const ctx=canvas.getContext('2d');ctx.clearRect(0,0,size,size);ctx.fillStyle='#fff';ctx.beginPath();\r\n poly.forEach(([u,v],i)=>i?ctx.lineTo(u*size,v*size):ctx.moveTo(u*size,v*size));ctx.closePath();ctx.fill();\r\n const texture=new THREE.CanvasTexture(canvas);texture.flipY=false;texture.colorSpace=THREE.NoColorSpace;texture.minFilter=THREE.LinearFilter;texture.magFilter=THREE.LinearFilter;texture.generateMipmaps=false;texture.needsUpdate=true;\r\n return texture;\r\n}\r\n\r\nexport function pointInPolygon(u,v,poly){\r\n let inside=false;\r\n for(let i=0,j=poly.length-1;i<poly.length;j=i++){\r\n  const [xi,yi]=poly[i],[xj,yj]=poly[j];\r\n  if((yi>v)!==(yj>v)&&u<(xj-xi)*(v-yi)/(yj-yi)+xi)inside=!inside;\r\n }\r\n return inside;\r\n}\r\n\r\nexport function splitIndexByPolygon(positions,index,toUv,poly){\r\n const keep=[],cut=[],us=poly.map(p=>p[0]),vs=poly.map(p=>p[1]),u0=Math.min(...us),u1=Math.max(...us),v0=Math.min(...vs),v1=Math.max(...vs);\r\n for(let t=0;t<index.length;t+=3){\r\n  const a=3*index[t],b=3*index[t+1],c=3*index[t+2],[u,v]=toUv((positions[a]+positions[b]+positions[c])/3,(positions[a+1]+positions[b+1]+positions[c+1])/3);\r\n  (u>=u0&&u<=u1&&v>=v0&&v<=v1&&pointInPolygon(u,v,poly)?cut:keep).push(index[t],index[t+1],index[t+2]);\r\n }\r\n return {keep,cut};\r\n}\r\n\r\nexport function pieceMaterial(src){const m=src.clone();m.onBeforeCompile=src.onBeforeCompile;m.customProgramCacheKey=src.customProgramCacheKey;m.transparent=true;return m;}\r\nexport function fallPieces(pieces,fall,ms){\r\n const angle=Math.random()*Math.PI*2,axis=new THREE.Vector3(Math.cos(angle),Math.sin(angle),0),t0=performance.now(),z0=pieces.map(p=>p.pivot.position.z);\r\n const f={live:true,pose(now){const t=Math.min(1,(now-t0)/Math.max(1,ms)),e=t*t;pieces.forEach((p,i)=>{p.pivot.position.z=z0[i]-fall*e;p.pivot.quaternion.setFromAxisAngle(axis,(35*Math.PI/180)*e);p.pivot.scale.setScalar(1-.4*e);p.material.opacity=1-e;});}};\r\n f.pose(t0);\r\n f.done=new Promise(resolve=>{f.end=()=>{if(!f.live)return;f.live=false;pieces.forEach(p=>p.drop());resolve();};if(ms>0)setTimeout(f.end,ms);else f.end();});\r\n return f;\r\n}\r\n","modules/portal/portal-entry.mjs":"let loading,mounted;\r\n\r\nexport async function ensurePortalMounted(){\r\n  if(mounted?.disposed)loading=null;\r\n  if(!loading){\r\n    loading=(async()=>{\r\n      const style=document.createElement('link');\r\n      style.rel='stylesheet';style.href='/modules/portal/portal.css';\r\n      const styled=new Promise((resolve,reject)=>{style.onload=resolve;style.onerror=()=>reject(new Error('Portal styles unavailable.'));});\r\n      document.head.append(style);\r\n      try{\r\n        const [{mountPortal}]=await Promise.all([import('./portal.mjs'),styled]);\r\n        mounted=await mountPortal();\r\n        const dispose=mounted.dispose;mounted.dispose=()=>{dispose();style.remove();};\r\n        return mounted;\r\n      }catch(error){style.remove();throw error;}\r\n    })().catch(error=>{loading=null;throw error;});\r\n  }\r\n  return loading;\r\n}\r\n\r\nexport async function openQuiltPortal({shouldShow=()=>true}={}) {\r\n  const portal=await ensurePortalMounted();\r\n  if(!shouldShow())return null;\r\n  portal.show();\r\n  return portal;\r\n}\r\n","modules/portal/portal-look.mjs":"// Device-local portal appearance: metal colours, light-strip colour, board. Shared by the portal and War Room; guests included.\r\nexport const LOOK_KEYS={portal:'myr5.portalMetal',strip:'myr5.portalStrip'};\r\nexport const LOOK_DEFAULTS={portal:'#4d3d4f',strip:'#b026ff'};\r\nconst LEGACY_FRAME_KEY='myr5.portalFrameMetal';\r\nexport const BOARD_CHOICES=[['quilt','Quilt'],['ice','Crystal'],['grass','Grass'],['jelly','Jelly'],['wood','Wood'],['pond','Pond']];\r\nexport const cleanColor=(v,fallback)=>/^#[0-9a-f]{6}$/i.test(v)?v.toLowerCase():fallback;\r\nconst get=k=>{try{return localStorage.getItem(k)}catch{return null}};\r\nexport const readLook=()=>({portal:cleanColor(get(LOOK_KEYS.portal),cleanColor(get(LEGACY_FRAME_KEY),LOOK_DEFAULTS.portal)),strip:cleanColor(get(LOOK_KEYS.strip),LOOK_DEFAULTS.strip)});\r\n// The default (or junk) removes the key, so \"reset\" leaves nothing behind.\r\nexport function saveLook(name,value){try{if(!Object.hasOwn(LOOK_KEYS,name))return;if(name==='portal')localStorage.removeItem(LEGACY_FRAME_KEY);const c=cleanColor(value,null);c&&c!==LOOK_DEFAULTS[name]?localStorage.setItem(LOOK_KEYS[name],c):localStorage.removeItem(LOOK_KEYS[name]);}catch{}}\r\n// Flowing strip in one colour: bright, dim, bright, pale.\r\nexport const stripSeq=c=>{const mix=(t,to)=>'#'+[1,3,5].map(i=>Math.round(parseInt(c.slice(i,i+2),16)*(1-t)+to*t).toString(16).padStart(2,'0')).join('');return [c,mix(.6,0),c,mix(.55,255)];};\r\n// Sets the CSS variables portal.css reads; defaults leave them unset so the stock look is untouched.\r\nexport function applyLookVars(el=document.documentElement,look=readLook()){\r\n if(look.portal===LOOK_DEFAULTS.portal){el.style.removeProperty('--portal-metal');el.style.removeProperty('--frame-metal');}\r\n else{el.style.setProperty('--portal-metal',look.portal);el.style.setProperty('--frame-metal',look.portal);}\r\n el.style.setProperty('--portal-strip-glow',`${look.strip}40`);\r\n}\r\nexport const readBoard=()=>{const id=get('myr5.portalBoard');return BOARD_CHOICES.some(choice=>choice[0]===id)?id:'quilt';};\r\nexport const saveBoard=id=>{try{localStorage.setItem('myr5.portalBoard',BOARD_CHOICES.some(choice=>choice[0]===id)?id:'quilt');}catch{}};\r\n","modules/portal/portal-mechanical-layout.mjs":"// Shared-shape mechanical layout. All seams exist before a gesture is made.\r\nimport {SHAPES,fromFrame} from './portal-shapes.mjs';\r\nimport {portalWindow,shapeOutlinePts} from './portal-apertures.mjs';\r\nexport const MECHANICAL_FRAME={x0:.085,y0:.065,x1:.915,y1:.925};\r\nconst EPS=1e-7;\r\nexport const area=poly=>poly.reduce((a,p,i)=>{const q=poly[(i+1)%poly.length];return a+p[0]*q[1]-q[0]*p[1];},0)/2;\r\nexport function interiorPoint(poly){\r\n const cross=(a,b,c)=>(b[0]-a[0])*(c[1]-a[1])-(b[1]-a[1])*(c[0]-a[0]);\r\n for(let i=0;i<poly.length;i++){\r\n  const ai=(i+poly.length-1)%poly.length,ci=(i+1)%poly.length,a=poly[ai],b=poly[i],c=poly[ci];\r\n  if(cross(a,b,c)<=EPS)continue;\r\n  const blocked=poly.some((p,j)=>j!==ai&&j!==i&&j!==ci&&cross(a,b,p)>=-EPS&&cross(b,c,p)>=-EPS&&cross(c,a,p)>=-EPS);\r\n  if(!blocked)return [(a[0]+b[0]+c[0])/3,(a[1]+b[1]+c[1])/3];\r\n }\r\n throw new Error('Mechanical panel has no interior ear');\r\n}\r\nexport function mechanicalPaths(frame=MECHANICAL_FRAME){\r\n return Object.entries(SHAPES).flatMap(([id,lines])=>id==='line'?[]:lines.map((l,line)=>{const points=(id==='oval'?shapeOutlinePts(id):l.points).map(p=>fromFrame(...p,frame));if(id==='oval')points.push(points[0]);return {id,line,points};}));\r\n}\r\nexport function releasePaths(face,frame=MECHANICAL_FRAME){\r\n const rect={left:frame.x0*face.w,top:frame.y0*face.h,width:(frame.x1-frame.x0)*face.w,height:(frame.y1-frame.y0)*face.h};\r\n return ['rect','oval','up','down','vdiamond','hdiamond','x','line-lr','line-down'].map(id=>({id:'release-'+id,points:portalWindow(id,rect).pts.map(([x,y])=>[x/face.w,y/face.h])}));\r\n}\r\n// Split each finite segment at intersections, then walk the planar graph's bounded faces.\r\n// Unlike cutting the slab during release, these separate pieces are manufactured at init.\r\nexport function sectionPanels(paths=mechanicalPaths()){\r\n const segments=[],seen=new Set(),key=p=>p.map(v=>v.toFixed(6)).join(',');\r\n const add=(a,b)=>{const k=[key(a),key(b)].sort().join('|');if(k!==[key(a),key(a)].join('|')&&!seen.has(k)){seen.add(k);segments.push({a,b,ts:[0,1]});}};\r\n const border=[[0,0],[1,0],[1,1],[0,1],[0,0]];\r\n [border,...paths.map(p=>p.points)].forEach(ps=>{for(let i=1;i<ps.length;i++)add(ps[i-1],ps[i]);});\r\n // Join the inset rectangular frame to the outer casing so the graph has no\r\n // disconnected outer face whose geometry would incorrectly cover inner cells.\r\n const rect=paths.find(p=>p.id==='rect');if(rect)for(let i=0;i<4;i++)add(border[i],rect.points[i]);\r\n for(let i=0;i<segments.length;i++)for(let j=i+1;j<segments.length;j++){\r\n  const s=segments[i],t=segments[j],rx=s.b[0]-s.a[0],ry=s.b[1]-s.a[1],sx=t.b[0]-t.a[0],sy=t.b[1]-t.a[1],cross=rx*sy-ry*sx;\r\n  if(Math.abs(cross)<EPS){\r\n   const dx=t.a[0]-s.a[0],dy=t.a[1]-s.a[1];\r\n   if(Math.abs(dx*ry-dy*rx)<EPS){\r\n    const project=(p,a,x,y)=>(p[0]-a[0])*x/(x*x+y*y)+(p[1]-a[1])*y/(x*x+y*y);\r\n    for(const p of [t.a,t.b]){const u=project(p,s.a,rx,ry);if(u>=0&&u<=1)s.ts.push(u);}\r\n    for(const p of [s.a,s.b]){const v=project(p,t.a,sx,sy);if(v>=0&&v<=1)t.ts.push(v);}\r\n   }continue;\r\n  }\r\n  const dx=t.a[0]-s.a[0],dy=t.a[1]-s.a[1],u=(dx*sy-dy*sx)/cross,v=(dx*ry-dy*rx)/cross;\r\n  if(u>=-EPS&&u<=1+EPS&&v>=-EPS&&v<=1+EPS){s.ts.push(Math.max(0,Math.min(1,u)));t.ts.push(Math.max(0,Math.min(1,v)));}\r\n }\r\n const vertices=new Map(),edges=new Set(),buckets=new Map(),snap=1e-6;\r\n const vertex=p=>{\r\n  const x=Math.floor(p[0]/snap),y=Math.floor(p[1]/snap);\r\n  for(let dx=-1;dx<=1;dx++)for(let dy=-1;dy<=1;dy++)for(const v of buckets.get((x+dx)+','+(y+dy))||[])if(Math.hypot(p[0]-v.p[0],p[1]-v.p[1])<=snap)return v;\r\n  const k=String(vertices.size),v={k,p,neighbors:[]},bucket=x+','+y;vertices.set(k,v);if(!buckets.has(bucket))buckets.set(bucket,[]);buckets.get(bucket).push(v);return v;\r\n };\r\n for(const s of segments){const ts=[...new Set(s.ts.map(t=>+t.toFixed(12)))].sort((a,b)=>a-b);for(let i=1;i<ts.length;i++){\r\n  const at=t=>[s.a[0]+(s.b[0]-s.a[0])*t,s.a[1]+(s.b[1]-s.a[1])*t],a=vertex(at(ts[i-1])),b=vertex(at(ts[i])),ek=[a.k,b.k].sort().join('|');\r\n  if(a===b||edges.has(ek))continue;edges.add(ek);a.neighbors.push(b);b.neighbors.push(a);\r\n }}\r\n for(const v of vertices.values())v.neighbors.sort((a,b)=>Math.atan2(a.p[1]-v.p[1],a.p[0]-v.p[0])-Math.atan2(b.p[1]-v.p[1],b.p[0]-v.p[0]));\r\n const walked=new Set(),panels=[];\r\n for(const a of vertices.values())for(const b of a.neighbors){\r\n  if(walked.has(a.k+'>'+b.k))continue;let prev=a,next=b,poly=[];\r\n  for(let n=0;n<edges.size*2+2;n++){\r\n   const ek=prev.k+'>'+next.k;if(walked.has(ek))break;walked.add(ek);poly.push(prev.p);\r\n   const ns=next.neighbors,index=ns.indexOf(prev),after=ns[(index-1+ns.length)%ns.length];prev=next;next=after;\r\n   if(prev===a&&next===b)break;\r\n  }\r\n  if(poly.length>=3&&area(poly)>EPS)panels.push({points:poly,center:interiorPoint(poly)});\r\n }\r\n return panels;\r\n}\r\nexport function pointOnPath(paths,face,u,v){\r\n let best=null;\r\n paths.forEach((path,pathIndex)=>{for(let i=1;i<path.points.length;i++){\r\n  const a=path.points[i-1],b=path.points[i],dx=(b[0]-a[0])*face.w,dy=(b[1]-a[1])*face.h,len2=dx*dx+dy*dy;\r\n  if(!len2)continue;const t=Math.max(0,Math.min(1,((u-a[0])*face.w*dx+(v-a[1])*face.h*dy)/len2)),q=[a[0]+(b[0]-a[0])*t,a[1]+(b[1]-a[1])*t],distance=Math.hypot((u-q[0])*face.w,(v-q[1])*face.h);\r\n  if(!best||distance<best.distance)best={pathIndex,segment:i-1,u:q[0],v:q[1],distance,tx:dx/Math.sqrt(len2),ty:dy/Math.sqrt(len2)};\r\n }});return best;\r\n}\r\n// Paired gears mesh at each drive station. Long spans and junctions are carried\r\n// by metal transmission channels, leaving the shared shape silhouettes readable.\r\nexport function mechanicalLayout(face,paths=mechanicalPaths(),nodes=['m19']){\r\n const parts=[],trains=[];\r\n paths.forEach((path,pathIndex)=>{\r\n  const train=[],lengths=path.points.slice(1).map((b,i)=>Math.hypot((b[0]-path.points[i][0])*face.w,(b[1]-path.points[i][1])*face.h)),length=lengths.reduce((a,b)=>a+b,0),closed=Math.hypot(path.points[0][0]-path.points.at(-1)[0],path.points[0][1]-path.points.at(-1)[1])<EPS;\r\n  const count=Math.max(2,Math.round(length/(.5*face.w)));let segment=0,offset=0;\r\n  for(let i=0;i<count;i++){\r\n   const distance=(i+.5)*length/count;while(segment<lengths.length-1&&offset+lengths[segment]<distance){offset+=lengths[segment++];}\r\n   const a=path.points[segment],b=path.points[segment+1],t=(distance-offset)/lengths[segment],tx=(b[0]-a[0])*face.w/lengths[segment],ty=(b[1]-a[1])*face.h/lengths[segment],rA=i===0?.029:.021,rB=rA,gap=(rA+rB)*face.w*.94;\r\n   for(let k=0;k<2;k++){\r\n    const d=(k?1:-1)*gap/2,index=parts.length,r=k?rB:rA;\r\n    const drives=k?train.at(-1):(train.length?train.at(-2):null),driveRatio=!k&&drives!=null?parts[drives].r/r:undefined;\r\n    parts.push({node:nodes[(i+pathIndex)%nodes.length],kind:'gear',u:a[0]+(b[0]-a[0])*t+tx*d/face.w,v:a[1]+(b[1]-a[1])*t+ty*d/face.h,r,rot:k?9:0,layer:pathIndex,pathIndex,station:i,drives,driveRatio});train.push(index);\r\n   }\r\n  }\r\n  trains.push(train);\r\n });\r\n const first=trains[0]?.[0];for(const train of trains.slice(1)){const i=train[0];parts[i].drives=first;parts[i].driveRatio=parts[first].r/parts[i].r;}\r\n // Four larger flywheels are mounted on the casing around the shape frame.\r\n // They reuse the same existing kit cog and drive through their smaller axles.\r\n for(const [u,v] of [[MECHANICAL_FRAME.x0,MECHANICAL_FRAME.y0],[MECHANICAL_FRAME.x1,MECHANICAL_FRAME.y0],[MECHANICAL_FRAME.x1,MECHANICAL_FRAME.y1],[MECHANICAL_FRAME.x0,MECHANICAL_FRAME.y1]])parts.push({node:nodes[0],kind:'gear',u,v,r:.055,rot:0,layer:11,hub:true,pathIndex:-1,drives:first,driveRatio:parts[first].r/.055});\r\n return {parts,trains,paths};\r\n}\r\nexport function signedRailImpulse(hit,du,dv,face,r,gain=2){return (du*face.w*hit.tx+dv*face.h*hit.ty)/(r*face.w)*gain;}\r\n// Lock-ring machinery along the shape lines. Lengths/radii are face-WIDTH fractions, rot = tangent in face space.\r\n// bolt.side: sign so that local +y*side (3D, y up = -v) withdraws toward the path centroid; in uv the withdrawn centre is c+side*throw*(sin,-cos) in face-width units.\r\nexport function mechanismLayout(face,paths=mechanicalPaths(),gearLayout=mechanicalLayout(face,paths)){\r\n const {parts}=gearLayout,out={tubes:[],bolts:[],pistons:[],pulleys:[],cables:[],weights:[],lamps:[],dial:[]};\r\n const W=(a,b)=>Math.hypot(b[0]-a[0],(b[1]-a[1])*face.h/face.w),rotOf=(a,b)=>Math.atan2((b[1]-a[1])*face.h,(b[0]-a[0])*face.w);\r\n const nearGear=(u,v)=>parts.reduce((best,p,i)=>W([u,v],[p.u,p.v])<W([u,v],[parts[best].u,parts[best].v])?i:best,0);\r\n paths.forEach((path,pathIndex)=>{\r\n  const pts=path.points,closed=Math.hypot(pts[0][0]-pts.at(-1)[0],pts[0][1]-pts.at(-1)[1])<EPS,gs=parts.filter(p=>p.pathIndex===pathIndex),st=[];\r\n  const body=closed?pts.slice(1):pts,cu=body.reduce((a,p)=>a+p[0],0)/body.length,cv=body.reduce((a,p)=>a+p[1],0)/body.length;\r\n  for(let i=0;i<gs.length;i+=2){const a=gs[i],b=gs[i+1],u=(a.u+b.u)/2,v=(a.v+b.v)/2;st.push({u,v,segment:pointOnPath([path],face,u,v).segment,station:a.station,clear:(a.r+b.r)*.47+a.r});}\r\n  for(const s of st){\r\n   const a=pts[s.segment],b=pts[s.segment+1],rot=rotOf(a,b),L=W(a,b),at=W(a,[s.u,s.v]),to=Math.min(Math.max(at,.03),L-.03),bu=s.u+(b[0]-a[0])*(to-at)/L,bv=s.v+(b[1]-a[1])*(to-at)/L;\r\n   out.lamps.push({u:s.u,v:s.v,r:.018,pathIndex,station:s.station});\r\n   // a bolt on a vertex slides .03 along its segment so the withdrawn bar stays inside the polygon\r\n   if(closed)out.bolts.push({u:L>.06?bu:s.u,v:L>.06?bv:s.v,rot,r:.02,pathIndex,station:s.station,throw:.025,side:Math.sign(Math.sin(rot)*(cu-bu)*face.w-Math.cos(rot)*(cv-bv)*face.h)||1});\r\n  }\r\n  const mine=out.tubes.length;\r\n  for(let seg=0;seg<pts.length-1;seg++){\r\n   const a=pts[seg],b=pts[seg+1],L=W(a,b),rot=rotOf(a,b),nodes=[{s:0,c:0},...st.filter(s=>s.segment===seg).map(s=>({s:W(a,[s.u,s.v]),c:s.clear+.005})),{s:L,c:0}];\r\n   // every crossing with another path splits the tube, so a tube never spans two panels\r\n   paths.forEach((q,j)=>{if(j===pathIndex)return;for(let k=0;k<q.points.length-1;k++){\r\n    const c=q.points[k],d=q.points[k+1],rx=b[0]-a[0],ry=b[1]-a[1],sx=d[0]-c[0],sy=d[1]-c[1],x=rx*sy-ry*sx;\r\n    if(Math.abs(x)<EPS)continue;const t=((c[0]-a[0])*sy-(c[1]-a[1])*sx)/x,u=((c[0]-a[0])*ry-(c[1]-a[1])*rx)/x;\r\n    if(t>=-EPS&&t<=1+EPS&&u>=-EPS&&u<=1+EPS)nodes.push({s:t*L,c:.003});\r\n   }});\r\n   nodes.sort((p,q)=>p.s-q.s);\r\n   for(let i=1;i<nodes.length;i++){\r\n    const from=nodes[i-1].s+nodes[i-1].c,to=nodes[i].s-nodes[i].c,len=to-from;\r\n    if(len<.012)continue;const t=(from+to)/2/L;\r\n    out.tubes.push({u:a[0]+(b[0]-a[0])*t,v:a[1]+(b[1]-a[1])*t,len,rot,r:.007,pathIndex,segment:seg});\r\n   }\r\n  }\r\n  // one piston per path, at the centre of its longest tube\r\n  const t=out.tubes.slice(mine).sort((p,q)=>q.len-p.len)[0];\r\n  if(t)out.pistons.push({u:t.u,v:t.v,rot:t.rot,r:.02,stroke:.04,pathIndex,drives:nearGear(t.u,t.v)});\r\n });\r\n // Corner hubs become pulleys; cables hang in the side margin outside the frame so nothing hides them.\r\n parts.forEach((p,drives)=>{if(!p.hub)return;\r\n  const sx=p.u<.5?-1:1,sy=p.v<.5?1:-1,from=[p.u+sx*p.r,p.v],to=[from[0],p.v+sy*.22],len=W(from,to);\r\n  out.pulleys.push({u:p.u,v:p.v,r:p.r,drives});out.cables.push({from,to,r:.004});\r\n  out.weights.push({u:from[0]+(to[0]-from[0])*.4,v:from[1]+(to[1]-from[1])*.4,r:.016,travel:len*.5,drives});\r\n });\r\n const oi=paths.findIndex(p=>p.id==='oval'),op=paths[oi].points.slice(1);\r\n out.dial.push({u:op.reduce((a,p)=>a+p[0],0)/op.length,v:op.reduce((a,p)=>a+p[1],0)/op.length,r:.11,drives:gearLayout.trains[oi][0]});\r\n return out;\r\n}\r\n","modules/portal/portal-peek.mjs":"// PORTAL-PEEK (Ian 1 Oct 2026): a see-through portal. While the cut is open, the destination scene is rendered\r\n// offscreen into one reused render target and blended into the wormhole's centre (portal.mjs keeps the wormhole at\r\n// the rim). Technique from Wormhole by AidanHT (src/render/PortalRenderer.ts): RT scaled per quality (RT_SCALE),\r\n// capped at MAX_RT_DIM. Our destinations are their own scenes, so there is no portal-pair camera and nothing in\r\n// front of a portal plane to clip (no oblique near plane needed). On by default (R17); localStorage.myr5PortalPeek = \"0\" turns it off.\r\n// Served unbundled (dynamic import from portal.mjs on the first peek): plain JS, no .ts, no __MYR5_* defines.\r\nimport * as THREE from 'three';\r\nimport {recipeShipTint,applyShipTint,SHIP_ANCHOR_Y,SHIP_FACING,SHIP_REST_Z,shipPoseAbove,measureShip} from '../ships/ship-scene-domain.mjs';\r\nimport {STARTER_WONDERS,backgroundForDay,starterWonderUrl} from '../../meditation-backgrounds.mjs';\r\nimport {createCoachPreviewSpace} from '../../coach-preview-space.mjs';\r\nimport {releaseGraphics} from '../graphics-lifecycle.mjs';\r\n\r\nexport const RT_SCALE=Object.freeze({high:1,medium:.55,low:.35});\r\nexport const MAX_RT_DIM=2048,MAX_DPR=1.5;\r\nconst FLAG='myr5PortalPeek';\r\n\r\n// \"0\" = off (kill switch); \"low\"/\"medium\"/\"high\" force one (for measuring); anything else is auto: a 4-core-or-less\r\n// phone is low quality and gets no peek (plain wormhole, the tunnel's own coarse hint); everything else medium.\r\nexport function peekQuality(){\r\n let v=null;try{v=localStorage.getItem(FLAG);}catch{}\r\n if(v==='0')return null;\r\n if(RT_SCALE[v])return v;\r\n return (navigator.hardwareConcurrency||8)<=4?null:'medium';\r\n}\r\n\r\n/** One render target, reused; resize() reallocates only when the size changes, render() never allocates. */\r\nexport function createPortalPeek({renderer,quality='medium'}){\r\n const rt=new THREE.WebGLRenderTarget(16,16,{depthBuffer:true}),scale=RT_SCALE[quality]||RT_SCALE.medium;\r\n let source=null,pixels=new Uint8Array(16*16*4),disposed=false;activePeeks++;\r\n const peek={\r\n  target:rt,texture:rt.texture,width:16,height:16,\r\n  setSource(next){source=typeof next==='function'?{render:next}:next;if(source?.camera)peek.resize(peek.cssW||16,peek.cssH||16);},\r\n  // w,h: CSS px of the window the peek fills.\r\n  resize(w,h){\r\n   peek.cssW=w;peek.cssH=h;\r\n   const k=Math.min(devicePixelRatio||1,MAX_DPR)*scale,rw=Math.min(MAX_RT_DIM,Math.max(16,Math.round(w*k))),rh=Math.min(MAX_RT_DIM,Math.max(16,Math.round(h*k)));\r\n   if(source?.camera){source.camera.aspect=w/Math.max(1,h);source.camera.updateProjectionMatrix();}\r\n   if(rw===peek.width&&rh===peek.height)return;\r\n   rt.setSize(rw,rh);peek.width=rw;peek.height=rh;pixels=new Uint8Array(rw*rh*4);\r\n  },\r\n  render(now=performance.now()){\r\n   if(!source)return false;\r\n   const prev=renderer.getRenderTarget();renderer.setRenderTarget(rt);\r\n   if(source.render)source.render(renderer,now);else{source.update?.(now);renderer.render(source.scene,source.camera);}\r\n   renderer.setRenderTarget(prev);return true;\r\n  },\r\n  // The wormhole draws in its own WebGL2 context, so the frame crosses over as pixels (bottom row first, linear RGB).\r\n  lost:()=>renderer.getContext().isContextLost(),\r\n  read(){renderer.readRenderTargetPixels(rt,0,0,peek.width,peek.height,pixels);return pixels;},\r\n  dispose(){if(disposed)return;disposed=true;source?.dispose?.();source=null;rt.dispose();activePeeks=Math.max(0,activePeeks-1);releasePeekRendererIfIdle();},\r\n };\r\n return peek;\r\n}\r\n\r\n// One three.js context for the page's life (like the tunnel's), created on the first peek.\r\nlet shared=null;\r\nlet activePeeks=0;\r\nexport function peekRenderer(){\r\n if(shared&&!shared.getContext().isContextLost())return shared;\r\n const canvas=document.createElement('canvas');\r\n try{shared=new THREE.WebGLRenderer({canvas,alpha:false,antialias:false,powerPreference:'low-power'});}catch{return shared=null;}\r\n canvas.addEventListener('webglcontextlost',()=>{if(shared?.domElement===canvas)shared=null;});\r\n return shared;\r\n}\r\n// A stopped peek no longer needs its GPU context. Keep the shared renderer only while a phase uses it.\r\nexport function releasePeekRendererIfIdle(){\r\n if(activePeeks||!shared)return false;\r\n const renderer=shared;shared=null;\r\n const gl=renderer.getContext(),canvas=renderer.domElement;\r\n return releaseGraphics(canvas,gl,()=>{renderer.dispose();renderer.forceContextLoss();}).then(()=>{canvas.remove();return true;});\r\n}\r\n\r\n// scene.background with CSS \"cover\" (three stretches a background texture to the viewport otherwise).\r\nfunction cover(texture,aspect){\r\n const img=texture.image,ia=img?(img.width/img.height):1,r=aspect/ia;\r\n texture.matrixAutoUpdate=true;\r\n if(r>1){texture.repeat.set(1,1/r);texture.offset.set(0,(1-1/r)/2);}else{texture.repeat.set(r,1);texture.offset.set((1-r)/2,0);}\r\n}\r\nconst textures=new THREE.TextureLoader();\r\nasync function wonder(){\r\n const t=await textures.loadAsync(starterWonderUrl(backgroundForDay(STARTER_WONDERS)));\r\n t.colorSpace=THREE.SRGBColorSpace;\r\n return t;\r\n}\r\nfunction disposeTree(root){root.traverse(n=>{n.geometry?.dispose();for(const m of [].concat(n.material||[])){for(const v of Object.values(m))if(v?.isTexture)v.dispose();m.dispose();}});}\r\n\r\n// Parsed once per page; dispose() frees the GPU copies and the next peek re-uploads them.\r\nlet starterShip=null;\r\n// Ship pod: the starter ship hovering over the supply-drop space, as in the full ship view.\r\n// ponytail: always the starter ship; an owned pack ship needs app.mjs's bridge, which this unbundled module can't reach.\r\nasync function shipSource(){\r\n const {GLTFLoader}=await import('three/addons/loaders/GLTFLoader.js');\r\n starterShip??=new GLTFLoader().loadAsync('/pod/worlds/starter/supportive.glb').catch(e=>{starterShip=null;throw e;});\r\n const gltf=await starterShip;\r\n const scene=new THREE.Scene(),camera=new THREE.PerspectiveCamera(34,1,.1,400);\r\n camera.position.set(0,.45,7);camera.lookAt(0,.9,0);\r\n const space=createCoachPreviewSpace(THREE,{pixelRatio:Math.min(devicePixelRatio||1,MAX_DPR)});\r\n scene.background=space.background;scene.fog=space.fog;scene.add(space.group);\r\n scene.add(new THREE.HemisphereLight(0xe9d9ff,0x23162d,2.5));\r\n const key=new THREE.DirectionalLight(0xffefca,4.2);key.position.set(-3,5,4);scene.add(key);\r\n const rim=new THREE.DirectionalLight(0xb58cff,3.2);rim.position.set(4,2,-3);scene.add(rim);\r\n const model=gltf.scene.clone(true),box=new THREE.Box3().setFromObject(model),size=box.getSize(new THREE.Vector3());\r\n model.position.sub(box.getCenter(new THREE.Vector3()));\r\n try{applyShipTint(model,recipeShipTint(JSON.parse(localStorage.getItem('myr5-recipe-v1')||'{}')));}catch{} // the coach's saved ship colour (the ship itself stays the starter, see above)\r\n const turn=new THREE.Group(),group=new THREE.Group(),fit=2.25/(Math.max(size.x,size.y,size.z)||1);\r\n turn.rotation.y=SHIP_FACING;turn.add(model);group.add(turn);group.scale.setScalar(fit);\r\n group.position.set(0,SHIP_ANCHOR_Y,SHIP_REST_Z);group.rotation.set(.08,-.32,0);scene.add(group);\r\n let pose=null,aspect=0;const t0=performance.now();\r\n return {scene,camera,\r\n  update(now){\r\n   if(camera.aspect!==aspect){aspect=camera.aspect;group.scale.setScalar(fit);group.position.y=SHIP_ANCHOR_Y;pose=shipPoseAbove({top:.4,bottom:-.4,aspect},measureShip(THREE,group,camera));group.scale.setScalar(fit*pose.scale);}\r\n   group.position.y=pose.y+Math.sin((now-t0)/820)*.07*pose.scale;group.rotation.y=-.32+Math.sin((now-t0)/1700)*.055;\r\n  },\r\n  dispose(){space.dispose();disposeTree(group);}};\r\n}\r\n// Meditation: the still room's far layer, today's wonder (the glass is greyscale on this route).\r\n// ponytail: the sleeping coach and your character are DOM/creature-viewer layers, not offscreen-renderable here.\r\nasync function meditationSource(){\r\n const bg=await wonder(),scene=new THREE.Scene(),camera=new THREE.PerspectiveCamera();\r\n scene.background=bg;let aspect=0;\r\n return {scene,camera,update(){if(camera.aspect!==aspect){aspect=camera.aspect;cover(bg,aspect);}},dispose(){bg.dispose();}};\r\n}\r\n// Customizer creature: no traced shape leads there (it opens from the ship), so it has no peek.\r\nexport const PEEK_SOURCES=Object.freeze({select:shipSource,meditate:meditationSource});\r\n\r\n/** For portal.mjs: a peek for `route` sized to a w x h CSS px window, or null (switched off, low end, no source, no WebGL). */\r\nexport async function openPeek(route,w,h,{shouldOpen=()=>true}={}){\r\n const quality=peekQuality(),load=PEEK_SOURCES[route];\r\n if(!quality||!load)return null;\r\n let source;\r\n try{source=await load();}catch(error){console.warn('Portal peek unavailable',error);return null;}\r\n if(!shouldOpen()){source?.dispose?.();return null;}\r\n const renderer=peekRenderer();if(!renderer){source?.dispose?.();return null;}\r\n const peek=createPortalPeek({renderer,quality});\r\n try{peek.resize(w,h);peek.setSource(source);}catch(error){peek.dispose();console.warn('Portal peek unavailable',error);return null;}\r\n return peek;\r\n}\r\n","modules/portal/portal-shapes.mjs":"// portal-shapes.mjs\r\n//\r\n// Minimal shape recogniser for a phone board app.\r\n// No external dependencies – pure ES‑module JavaScript.\r\n//\r\n// The recogniser works by resampling each template polyline into evenly spaced\r\n// points and then comparing the trace against those points.  A candidate is\r\n// accepted only if both the trace covers at least TOLERANCE.cover of the template and\r\n// vice‑versa, using a distance tolerance of TOLERANCE.dist in board coordinates.\r\n//\r\n// The module exports:\r\n//\r\n//   SHAPE_IDS – array of the nine shape identifiers.\r\n//   SHAPES    – mapping from id → array of polylines (each polyline is an\r\n//                object with `points` and pre‑sampled `sampled` arrays).\r\n//   recognizeShape(strokes) – returns one id string or null.\r\n//\r\n// The recogniser never throws; malformed input results in a null return.\r\n\r\n// Match slack. Ian 2026-09-22: \"the shapes should be more forgiving on all boards\" — ~40 % looser than\r\n// the original 0.09 / 0.85: dist = how far (board fractions) a trace point may sit from the template (and\r\n// vice versa); 1 - cover = the share of the trace (overshoot) and of the template (closing gap, skipped\r\n// corner) allowed to fall outside dist. maxLength: the trace's path length (wiggles under 0.05 dropped)\r\n// may be at most this many times the template's — loose coverage alone would let a scribble that fills a\r\n// thin shape (hdiamond) pass; a real trace, even one that goes round twice, stays well under it.\r\nexport const TOLERANCE = { dist: 0.125, cover: 0.79, maxLength: 3 };\r\n\r\n/** Path length of polylines, ignoring moves shorter than `step` (finger jitter). */\r\nconst pathLength = (lines, step = 0.05) => {\r\n  let len = 0;\r\n  for (const pts of lines) {\r\n    let last = null;\r\n    for (const p of pts) {\r\n      if (!last) { last = p; continue; }\r\n      const d = dist(p, last);\r\n      if (d >= step) { len += d; last = p; }\r\n    }\r\n  }\r\n  return len;\r\n};\r\n\r\n// A single-stroke straight line is direction-aware: 'line-down'/'line-up' for the vertical template,\r\n// 'line-lr'/'line-rl' for the horizontal one, named for the stroke's first vs last point (see recognizeShape).\r\nconst SHAPE_IDS = [\r\n  'cross',\r\n  'down',\r\n  'hdiamond',\r\n  'line-down',\r\n  'line-lr',\r\n  'line-rl',\r\n  'line-up',\r\n  'oval',\r\n  'rect',\r\n  'up',\r\n  'vdiamond',\r\n  'x',\r\n];\r\n\r\n// Shape frame: the sub-rect of a board's face (UV, v down) where the templates above actually sit —\r\n// e.g. a painted door with a blank panel strip below the art, or a carved pattern inset from the\r\n// edges. toFrame maps a face-UV point into the frame's own 0..1 space (a raw trace, before\r\n// recognizeShape); fromFrame is the inverse (a template point, placed back onto the face for the\r\n// cut, the portal-glass clip, and guide drawing). Default = the whole face, a no-op.\r\nexport const FULL_FRAME = { x0: 0, y0: 0, x1: 1, y1: 1 };\r\nexport const toFrame = (u, v, frame = FULL_FRAME) => [\r\n  (u - frame.x0) / (frame.x1 - frame.x0),\r\n  (v - frame.y0) / (frame.y1 - frame.y0),\r\n];\r\nexport const fromFrame = (u, v, frame = FULL_FRAME) => [\r\n  frame.x0 + u * (frame.x1 - frame.x0),\r\n  frame.y0 + v * (frame.y1 - frame.y0),\r\n];\r\n\r\n// ---------------------------------------------------------------------------\r\n// Utility helpers\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Euclidean distance between two points. */\r\nconst dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1]);\r\n\r\n/**\r\n * Return the minimum distance from point `p` to any point in array `set`.\r\n * The set is expected to be small (< 500 points), so a linear scan is fine.\r\n */\r\nconst minDistToSet = (p, set) => {\r\n  let best = Infinity;\r\n  for (const q of set) {\r\n    const d = dist(p, q);\r\n    if (d < best) best = d;\r\n  }\r\n  return best;\r\n};\r\n\r\n/**\r\n * Sample a polyline into points spaced by `spacing` along its length.\r\n * The input is an array of [x,y] pairs.  The output includes the final\r\n * endpoint exactly.\r\n */\r\nconst samplePolyline = (pts, spacing = 0.01) => {\r\n  if (!Array.isArray(pts) || pts.length < 2) return [];\r\n  const res = [];\r\n  // Compute segment lengths and total length\r\n  const segLens = [];\r\n  let totalLen = 0;\r\n  for (let i = 0; i < pts.length - 1; ++i) {\r\n    const d = dist(pts[i], pts[i + 1]);\r\n    segLens.push(d);\r\n    totalLen += d;\r\n  }\r\n  if (totalLen === 0) return [pts[0]];\r\n\r\n  let curSeg = 0;\r\n  let segStart = pts[0];\r\n  let segDist = 0; // distance travelled along current segment\r\n  let nextSample = 0;\r\n\r\n  while (nextSample <= totalLen + 1e-9) {\r\n    // Advance to the segment that contains `nextSample`\r\n    while (\r\n      curSeg < segLens.length &&\r\n      nextSample > segDist + segLens[curSeg] + 1e-9\r\n    ) {\r\n      segDist += segLens[curSeg];\r\n      ++curSeg;\r\n      segStart = pts[curSeg];\r\n    }\r\n    if (curSeg >= segLens.length) break;\r\n\r\n    const t =\r\n      segLens[curSeg] === 0\r\n        ? 0\r\n        : (nextSample - segDist) / segLens[curSeg];\r\n    const [x1, y1] = segStart;\r\n    const [x2, y2] = pts[curSeg + 1];\r\n    res.push([x1 + (x2 - x1) * t, y1 + (y2 - y1) * t]);\r\n\r\n    nextSample += spacing;\r\n  }\r\n\r\n  // Ensure the final endpoint is present\r\n  if (\r\n    res.length === 0 ||\r\n    dist(res[res.length - 1], pts[pts.length - 1]) > 1e-9\r\n  ) {\r\n    res.push(pts[pts.length - 1]);\r\n  }\r\n  return res;\r\n};\r\n\r\n/** Helper to create a polyline object with pre‑sampled points. */\r\nconst makePoly = (points) => ({\r\n  points,\r\n  sampled: samplePolyline(points),\r\n});\r\n\r\n// Rank already-accepted candidates by shape after allowing the small placement/\r\n// size differences of the carved boards. Keep the original coverage gate and\r\n// bound this fit so it cannot turn a small/off-centre gesture into a valid one.\r\nconst registeredTemplate = (template, trace) => {\r\n  const bounds = (points) => points.reduce((b, [x, y]) => [\r\n    Math.min(b[0], x), Math.min(b[1], y), Math.max(b[2], x), Math.max(b[3], y),\r\n  ], [Infinity, Infinity, -Infinity, -Infinity]);\r\n  const a = bounds(template), b = bounds(trace);\r\n  const clamp = (v, lo, hi) => Math.max(lo, Math.min(hi, v));\r\n  const sx = clamp((b[2] - b[0]) / (a[2] - a[0]), 0.8, 1.15);\r\n  const sy = clamp((b[3] - b[1]) / (a[3] - a[1]), 0.8, 1.15);\r\n  const cx = (a[0] + a[2]) / 2, cy = (a[1] + a[3]) / 2;\r\n  const dx = clamp((b[0] + b[2]) / 2 - cx, -0.08, 0.08);\r\n  const dy = clamp((b[1] + b[3]) / 2 - cy, -0.08, 0.08);\r\n  return template.map(([x, y]) => [cx + (x - cx) * sx + dx, cy + (y - cy) * sy + dy]);\r\n};\r\n\r\n// Corner detection, used only to break ties when a trace passes the distance/coverage\r\n// check against more than one template (e.g. a rect traced a few % smaller than its\r\n// template happens to land closer, on raw mean distance alone, to the oval template than\r\n// to its own — see recognizeShape). A raw trace's per-point finger jitter (up to ~0.045 in\r\n// the sloppy-trace tests) is *larger* than the ~0.01 spacing between consecutive points, so\r\n// it must be smoothed — not just scanned at a coarser step — before direction can mean\r\n// anything: a box filter (smoothCorner) first, over a window well wider than the jitter,\r\n// then a scan that measures the turn at each point using a neighbour CORNER_REACH away\r\n// (rather than the adjacent sample) so a single noisy sample can't fake a corner, while a\r\n// real corner still reads as sharp regardless of exactly where the scan lands on it. Flag\r\n// direction changes sharper than CORNER_ANGLE and merge adjacent flags into one corner,\r\n// since a real corner stays sharp for a whole CORNER_REACH-ish stretch either side of it.\r\n// (Constants tuned against tests/portal-shapes.test.mjs's own jittered traces, amount<=.045.)\r\nconst CORNER_SMOOTH_RADIUS = 10; // samples of the .01-spaced fine resample, each side (~.1 window)\r\nconst CORNER_SCAN_STEP = 0.03;\r\nconst CORNER_REACH = 0.15;\r\nconst CORNER_ANGLE = 40; // degrees: real corners here are 47-90°, background noise stays well under this\r\n\r\nconst smoothPolyline = (pts, radius) => {\r\n  const n = pts.length;\r\n  const out = [];\r\n  for (let i = 0; i < n; ++i) {\r\n    let sx = 0, sy = 0, c = 0;\r\n    for (let k = -radius; k <= radius; ++k) {\r\n      const j = i + k;\r\n      if (j < 0 || j >= n) continue;\r\n      sx += pts[j][0]; sy += pts[j][1]; ++c;\r\n    }\r\n    out.push([sx / c, sy / c]);\r\n  }\r\n  return out;\r\n};\r\n\r\nconst countCorners = (points, angleDeg = CORNER_ANGLE) => {\r\n  const fine = samplePolyline(points, 0.01);\r\n  const smoothed = smoothPolyline(fine, CORNER_SMOOTH_RADIUS);\r\n  const pts = samplePolyline(smoothed, CORNER_SCAN_STEP);\r\n  const n = pts.length;\r\n  const reach = Math.round(CORNER_REACH / CORNER_SCAN_STEP);\r\n  if (n < reach * 2 + 3) return 0;\r\n  const closed = dist(pts[0], pts[n - 1]) < CORNER_SCAN_STEP * 3;\r\n  const idxs = [];\r\n  for (let i = 0; i < n; ++i) {\r\n    if (!closed && (i - reach < 0 || i + reach >= n)) continue; // no far-enough neighbour at open endpoints\r\n    idxs.push(i);\r\n  }\r\n  const isCorner = (i) => {\r\n    const prev = pts[(i - reach + n) % n];\r\n    const cur = pts[i];\r\n    const next = pts[(i + reach) % n];\r\n    const v1 = [cur[0] - prev[0], cur[1] - prev[1]];\r\n    const v2 = [next[0] - cur[0], next[1] - cur[1]];\r\n    const m1 = Math.hypot(v1[0], v1[1]);\r\n    const m2 = Math.hypot(v2[0], v2[1]);\r\n    if (m1 < 1e-6 || m2 < 1e-6) return false;\r\n    const cos = Math.max(-1, Math.min(1, (v1[0] * v2[0] + v1[1] * v2[1]) / (m1 * m2)));\r\n    return (Math.acos(cos) * 180) / Math.PI >= angleDeg;\r\n  };\r\n  const flags = idxs.map(isCorner);\r\n  let count = 0;\r\n  for (let i = 0; i < flags.length; ++i) {\r\n    const prevFlag = i === 0 ? (closed ? flags[flags.length - 1] : false) : flags[i - 1];\r\n    if (flags[i] && !prevFlag) count++;\r\n  }\r\n  return count;\r\n};\r\n\r\n/**\r\n * Generate an ellipse as a polyline of `n` points.\r\n * The ellipse is centered at (cx,cy) with radii rx and ry.\r\n */\r\nconst makeEllipse = (cx, cy, rx, ry, n = 200) => {\r\n  const pts = [];\r\n  for (let i = 0; i < n; ++i) {\r\n    const t = (2 * Math.PI * i) / n;\r\n    pts.push([cx + rx * Math.cos(t), cy + ry * Math.sin(t)]);\r\n  }\r\n  return makePoly(pts);\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Shape templates\r\n// ---------------------------------------------------------------------------\r\n\r\nconst SHAPES = {\r\n  rect: [\r\n    makePoly([\r\n      [0, 0],\r\n      [1, 0],\r\n      [1, 1],\r\n      [0, 1],\r\n      [0, 0], // closed\r\n    ]),\r\n  ],\r\n\r\n  oval: [makeEllipse(0.5, 0.5, 0.5, 0.5)],\r\n\r\n  up: [\r\n    makePoly([\r\n      [0.5, 0],\r\n      [1, 0.71],\r\n      [0, 0.71],\r\n      [0.5, 0], // closed\r\n    ]),\r\n  ],\r\n\r\n  down: [\r\n    makePoly([\r\n      [0, 0.29],\r\n      [1, 0.29],\r\n      [0.5, 1],\r\n      [0, 0.29], // closed\r\n    ]),\r\n  ],\r\n\r\n  vdiamond: [\r\n    makePoly([\r\n      [0.5, 0],\r\n      [1, 0.5],\r\n      [0.5, 1],\r\n      [0, 0.5],\r\n      [0.5, 0], // closed\r\n    ]),\r\n  ],\r\n\r\n  hdiamond: [\r\n    makePoly([\r\n      [0, 0.5],\r\n      [0.5, 0.29],\r\n      [1, 0.5],\r\n      [0.5, 0.71],\r\n      [0, 0.5], // closed\r\n    ]),\r\n  ],\r\n\r\n  x: [\r\n    makePoly([[0, 0], [1, 1]]),\r\n    makePoly([[1, 0], [0, 1]]),\r\n  ],\r\n\r\n  cross: [\r\n    makePoly([[0.5, 0], [0.5, 1]]), // vertical\r\n    makePoly([[0, 0.5], [1, 0.5]]), // horizontal\r\n  ],\r\n\r\n  line: [\r\n    makePoly([[0.5, 0], [0.5, 1]]), // vertical\r\n    makePoly([[0, 0.5], [1, 0.5]]), // horizontal\r\n  ],\r\n};\r\n\r\n// Expected corner count per template, for the tie-break in recognizeShape: polygons carry\r\n// their real vertex count (closed `points` list repeats the first point, so length - 1\r\n// unique corners); oval and line are smooth/straight and never register a corner.\r\nconst CORNER_COUNTS = Object.fromEntries(\r\n  ['rect', 'up', 'down', 'vdiamond', 'hdiamond'].map((id) => [id, SHAPES[id][0].points.length - 1])\r\n);\r\nCORNER_COUNTS.oval = 0;\r\nCORNER_COUNTS.line = 0;\r\n\r\n// ---------------------------------------------------------------------------\r\n// Recogniser\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Recognise a shape from an array of strokes.\r\n *\r\n * @param {Array<Array<[number, number]>>} strokes\r\n * @returns {string|null}\r\n */\r\nexport const recognizeShape = (strokes) => {\r\n  // Basic validation – never throw on malformed input.\r\n  if (!Array.isArray(strokes)) return null;\r\n  const tracePoints = [];\r\n  for (const stroke of strokes) {\r\n    if (!Array.isArray(stroke)) return null;\r\n    for (const pt of stroke) {\r\n      if (\r\n        !Array.isArray(pt) ||\r\n        pt.length !== 2 ||\r\n        typeof pt[0] !== 'number' ||\r\n        typeof pt[1] !== 'number' ||\r\n        !Number.isFinite(pt[0]) ||\r\n        !Number.isFinite(pt[1])\r\n      )\r\n        return null;\r\n      tracePoints.push([pt[0], pt[1]]);\r\n    }\r\n  }\r\n  if (tracePoints.length === 0) return null;\r\n  // Fast swipes arrive as a few far-apart points; fill in each stroke so coverage is measured along the path.\r\n  const dense = strokes.flatMap((stroke) => stroke.length > 1 ? samplePolyline(stroke) : stroke);\r\n  tracePoints.length = 0;\r\n  tracePoints.push(...dense);\r\n\r\n  const strokeCount = strokes.length;\r\n  let candidates = [];\r\n  if (strokeCount === 1)\r\n    candidates = [\r\n      'rect',\r\n      'up',\r\n      'down',\r\n      'vdiamond',\r\n      'hdiamond',\r\n      'oval',\r\n      'line',\r\n    ];\r\n  else if (strokeCount === 2) candidates = ['x', 'cross'];\r\n  else return null;\r\n\r\n  const tolerance = TOLERANCE.dist;\r\n  const traceLength = pathLength(strokes);\r\n  const tooLong = (polys) => traceLength > TOLERANCE.maxLength * pathLength(polys.map((p) => p.points), 0);\r\n  // Corner count of the trace, computed once and used as the primary tie-break below: more\r\n  // than one template can pass the distance/coverage check at once (a board's carved\r\n  // pattern can sit a few % off the ideal template — see countCorners above), and on raw\r\n  // mean distance alone a smooth template (oval) can numerically edge out a cornered\r\n  // template that's the visually obvious match, or vice versa.\r\n  const traceCorners = strokeCount === 1 ? countCorners(tracePoints) : 0;\r\n  let bestId = null;\r\n  let bestCornerDiff = Infinity; // primary: |expected corners - trace corners|\r\n  let bestScore = Infinity; // secondary: mean distance, both ways\r\n\r\n  const consider = (id, templatePts) => {\r\n    const traceWithin =\r\n      tracePoints.filter((p) => minDistToSet(p, templatePts) <= tolerance).length /\r\n      tracePoints.length;\r\n    const templateWithin =\r\n      templatePts.filter((tp) => minDistToSet(tp, tracePoints) <= tolerance).length /\r\n      templatePts.length;\r\n    if (traceWithin < TOLERANCE.cover || templateWithin < TOLERANCE.cover) return;\r\n\r\n    let sum = 0;\r\n    for (const p of tracePoints) sum += minDistToSet(p, templatePts);\r\n    let sum2 = 0;\r\n    for (const tp of templatePts) sum2 += minDistToSet(tp, tracePoints);\r\n    const score = (sum / tracePoints.length + sum2 / templatePts.length) / 2;\r\n    const cornerDiff = strokeCount === 1 ? Math.abs((CORNER_COUNTS[id] ?? 0) - traceCorners) : 0;\r\n\r\n    if (cornerDiff < bestCornerDiff || (cornerDiff === bestCornerDiff && score < bestScore)) {\r\n      bestCornerDiff = cornerDiff;\r\n      bestScore = score;\r\n      bestId = id;\r\n    }\r\n  };\r\n\r\n  for (const id of candidates) {\r\n    if (id === 'line') {\r\n      // Evaluate vertical and horizontal orientations separately.\r\n      if (tooLong(SHAPES['line'].slice(0, 1))) continue;\r\n      for (let i=0;i<SHAPES.line.length;i++) {const raw=strokes[0],first=raw[0],last=raw[raw.length-1];const name=i===0?(last[1]>=first[1]?'line-down':'line-up'):(last[0]>=first[0]?'line-lr':'line-rl');consider(name,SHAPES.line[i].sampled);}\r\n    } else {\r\n      if (tooLong(SHAPES[id])) continue;\r\n      consider(id, SHAPES[id].flatMap((poly) => poly.sampled));\r\n    }\r\n  }\r\n\r\n  return bestId;\r\n};\r\n\r\n/**\r\n * #21 \"almost\": the closest candidate even when it fails TOLERANCE.cover, for a near-miss hint.\r\n * Reuses recognizeShape's own coverage math (same candidates, same tolerance, same tooLong guard)\r\n * without the pass/fail gate, so it stays in lockstep with what recognizeShape accepts.\r\n *\r\n * @param {Array<Array<[number, number]>>} strokes\r\n * @returns {{id:string,score:number}|null} score is min(traceWithin,templateWithin) in [0,1); recognizeShape\r\n *  would accept the same candidate once that reaches TOLERANCE.cover. Never throws; null on malformed input,\r\n *  no strokes, or a trace too long/short-stroked to score against anything.\r\n */\r\nexport const nearestShape = (strokes) => {\r\n  if (!Array.isArray(strokes)) return null;\r\n  const tracePoints = [];\r\n  for (const stroke of strokes) {\r\n    if (!Array.isArray(stroke)) return null;\r\n    for (const pt of stroke) {\r\n      if (\r\n        !Array.isArray(pt) ||\r\n        pt.length !== 2 ||\r\n        typeof pt[0] !== 'number' ||\r\n        typeof pt[1] !== 'number' ||\r\n        !Number.isFinite(pt[0]) ||\r\n        !Number.isFinite(pt[1])\r\n      )\r\n        return null;\r\n      tracePoints.push(pt);\r\n    }\r\n  }\r\n  if (tracePoints.length === 0) return null;\r\n  const dense = strokes.flatMap((stroke) => stroke.length > 1 ? samplePolyline(stroke) : stroke);\r\n  const points = dense.length ? dense : tracePoints;\r\n\r\n  const strokeCount = strokes.length;\r\n  let candidates = [];\r\n  if (strokeCount === 1)\r\n    candidates = ['rect', 'up', 'down', 'vdiamond', 'hdiamond', 'oval', 'line'];\r\n  else if (strokeCount === 2) candidates = ['x', 'cross'];\r\n  else return null;\r\n\r\n  const tolerance = TOLERANCE.dist;\r\n  const traceLength = pathLength(strokes);\r\n  const tooLong = (polys) => traceLength > TOLERANCE.maxLength * pathLength(polys.map((p) => p.points), 0);\r\n  let best = null;\r\n  const consider = (id, templatePts) => {\r\n    const traceWithin =\r\n      points.filter((p) => minDistToSet(p, templatePts) <= tolerance).length / points.length;\r\n    const templateWithin =\r\n      templatePts.filter((tp) => minDistToSet(tp, points) <= tolerance).length / templatePts.length;\r\n    const score = Math.min(traceWithin, templateWithin);\r\n    if (!best || score > best.score) best = { id, score };\r\n  };\r\n\r\n  for (const id of candidates) {\r\n    if (id === 'line') {\r\n      if (tooLong(SHAPES.line.slice(0, 1))) continue;\r\n      const raw = strokes[0], first = raw[0], last = raw[raw.length - 1];\r\n      SHAPES.line.forEach((poly, i) => {\r\n        const name = i === 0\r\n          ? (last[1] >= first[1] ? 'line-down' : 'line-up')\r\n          : (last[0] >= first[0] ? 'line-lr' : 'line-rl');\r\n        consider(name, poly.sampled);\r\n      });\r\n    } else {\r\n      if (tooLong(SHAPES[id])) continue;\r\n      consider(id, SHAPES[id].flatMap((poly) => poly.sampled));\r\n    }\r\n  }\r\n  return best;\r\n};\r\n\r\nexport { SHAPE_IDS, SHAPES };\r\n","modules/portal/portal-tunnel-cogs.mjs":"// Optional pipe-and-steam tunnel, downloaded with the mechanical door. Toothed gear bands counter-rotate as the tunnel flows.\r\nexport const material=`vec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\n float edge=abs(sin(a-.7)),pipe=1.-smoothstep(.085,.115,edge);float roundness=sqrt(max(0.,1.-pow(edge/.115,2.)));\r\n float joint=1.-smoothstep(.03,.09,abs(fract(v*.55)-.5));float steam=pow(max(0.,sin(a*5.+sin(v*1.2))*sin(v*.8+a)),4.);\r\n vec3 wall=seq(0.)*.04+seq(1.)*.04*pow(.5+.5*cos(a*12.),12.);\r\n vec3 metal=seq(2.)*(.2+.8*roundness)+seq(3.)*joint;\r\n float gi=floor(v*.3),gv=fract(v*.3)-.5,dir=mod(gi,2.)*2.-1.;\r\n float tooth=smoothstep(-.2,.2,sin(a*24.+v*2.4*dir+gi*1.7));\r\n float gear=1.-smoothstep(.2+.07*tooth,.24+.07*tooth,abs(gv)),hub=1.-smoothstep(.06,.12,abs(sin(a*12.+v*1.2*dir)));\r\n vec3 brass=seq(2.)*(.55+.45*tooth)*(1.-.28*hub);\r\n return mix(mix(wall,metal,pipe),brass,gear*aa)+seq(1.)*steam*.65;\r\n}`;\r\nexport const core='#91aaa5';\r\n","modules/portal/portal-tunnel-grass.mjs":"// Optional grimoire tunnel material; downloaded with its board. Blades and flower glints are cells in (a,v), so they stream past with travel.\r\nexport const material=`float gH(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nvec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\n float ca=a*9.549296586,cv=v*1.25;vec2 id=vec2(mod(floor(ca),60.),floor(cv)),q=vec2(fract(ca)-.5,fract(cv));\r\n float h=gH(id),n=gH(vec2(floor(a*38.2),floor(v*3.)));\r\n vec3 c=mix(seq(0.)*.52,seq(1.)*.82,n)+mix(seq(0.),seq(1.),.5)*.12*(.5+.5*sin(a*14.+v*.9));\r\n float lean=(h-.5)*.6,w=.2*(1.-q.y)+.015,blade=(1.-smoothstep(w*.6,w,abs(q.x-lean*q.y)))*step(.3,h)*aa;\r\n c=mix(c,mix(seq(0.),seq(1.)*1.18,q.y),blade);\r\n float f=gH(id+7.3),d=length((q-vec2(0.,.5))*vec2(1.,.8));\r\n float bloom=(1.-smoothstep(.07,.2,d))*step(.9,f)*aa,tw=.6+.4*sin(v*5.+f*40.);\r\n vec3 pet=f>.95?acc(1.):acc(0.);\r\n c=mix(c,pet*tw+base*.5,bloom)+pet*bloom*.35*tw;\r\n return c;\r\n}`;\r\nexport const core='#7dff5a';\r\n","modules/portal/portal-tunnel-ice.mjs":"// Optional reflective ice tunnel; packaged with the ice board.\r\nexport const material=`float iH(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nvec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\n float facet=.5+.5*sin(a*7.+sin(v*.42)*2.);float reflection=pow(max(0.,sin(a*3.+v*.75)),32.);float crack=1.-smoothstep(.014,.045,abs(sin(a*9.+sin(v*.6))));\r\n vec2 id=vec2(mod(floor(a*3.183),20.),floor(v*.9));float h=iH(id);float shard=.55+.45*h;\r\n float glint=pow(max(0.,sin(v*2.4+h*6.2832)),20.)*step(.45,h)*aa;\r\n vec3 paletteColor=seq(floor(a*3.183)+floor(v*.9));\r\n vec3 iceColor=mix(base,paletteColor,facet*shard);\r\n return vec3(.15+.42*facet*shard)+iceColor*vec3(reflection*.7+crack*.25+glint*.9);\r\n}`;\r\n","modules/portal/portal-tunnel-jelly.mjs":"// Optional grimoire tunnel material; downloaded with its board. The wall wobbles and bulges as it flows.\r\nexport const material=`vec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\n float w=.5*sin(a*6.+v*2.)+.5*sin(a*3.-v*1.3+1.);float bulge=pow(.5+.5*w,2.);\r\n float bump=pow(max(0.,sin(a*8.+sin(v))*sin(v*3.)),3.);float shine=pow(max(0.,sin(a*8.+.4+w)*sin(v*3.+.5+w)),18.);\r\n float rim=pow(1.-abs(w),5.);\r\n vec3 pal=seq(floor(a*1.273)+floor(v*.5));\r\n vec3 jellyCol=mix(pal, pal*1.2, bulge);\r\n return (.18+.35*bulge+.3*bump)*jellyCol+vec3(rim*.25)+vec3(.06+.3*shine)*aa;\r\n}`;\r\n","modules/portal/portal-tunnel-palettes.mjs":"/**\r\n * Material-specific wormhole palette presets.\r\n * Pure ES module. No storage, DOM, or external dependencies.\r\n */\r\n\r\nexport { RAW_PALETTE_DATA as PALETTES };\r\nconst RAW_PALETTE_DATA = {\r\n  wood: [\r\n    { id: 'oak', label: 'Oak', colors: ['#D2B48C', '#C19A6B', '#A67B5B', '#8B5A2B'], core: '#8B5A2B' },\r\n    { id: 'cherry', label: 'Cherry', colors: ['#DEB887', '#CD853F', '#B22222', '#8B0000'], core: '#8B0000' },\r\n    { id: 'walnut', label: 'Walnut', colors: ['#5C4033', '#4A3020', '#3B2415', '#2C1810'], core: '#2C1810' },\r\n    { id: 'maple', label: 'Maple', colors: ['#F4A460', '#E69550', '#D88640', '#C97730'], core: '#C97730' }\r\n  ],\r\n  ice: [\r\n    { id: 'clear_crystal', label: 'Clear Crystal', colors: ['#E0F7FA', '#B2EBF2', '#80DEEA', '#4DD0E1'], core: '#4DD0E1' },\r\n    { id: 'amethyst', label: 'Amethyst', colors: ['#E1BEE7', '#CE93D8', '#BA68C8', '#9C27B0'], core: '#9C27B0' },\r\n    { id: 'ruby', label: 'Ruby', colors: ['#FFCDD2', '#EF9A9A', '#E57373', '#D32F2F'], core: '#D32F2F' },\r\n    { id: 'emerald', label: 'Emerald', colors: ['#C8E6C9', '#A5D6A7', '#81C784', '#4CAF50'], core: '#4CAF50' },\r\n    { id: 'sapphire', label: 'Sapphire', colors: ['#BBDEFB', '#90CAF9', '#64B5F6', '#2196F3'], core: '#2196F3' }\r\n  ],\r\n  cogs: [\r\n    { id: 'steel', label: 'Steel', colors: ['#CFD8DC', '#B0BEC5', '#90A4AE', '#78909C'], core: '#78909C' },\r\n    { id: 'iron', label: 'Iron', colors: ['#757575', '#616161', '#484848', '#303030'], core: '#303030' },\r\n    { id: 'copper', label: 'Copper', colors: ['#FFCC80', '#FFB74D', '#FFA726', '#FB8C00'], core: '#FB8C00' },\r\n    { id: 'bronze', label: 'Bronze', colors: ['#D7CCC8', '#BCAAA4', '#A1887F', '#8D6E63'], core: '#8D6E63' },\r\n    { id: 'silver', label: 'Silver', colors: ['#ECEFF1', '#CFD8DC', '#B0BEC5', '#90A4AE'], core: '#90A4AE' },\r\n    { id: 'gold', label: 'Gold', colors: ['#FFF9C4', '#FFF59D', '#FFF176', '#FFEE58'], core: '#FFEE58' }\r\n  ],\r\n  grass: [\r\n    { id: 'meadow', label: 'Meadow Greens', colors: ['#70A64D', '#326B3D', '#8CC25A', '#4E8A3F'], accents: ['#F3D66B', '#F09BB8'], core: '#7AC85B' },\r\n    { id: 'wildflowers', label: 'Wildflowers', colors: ['#6E9F45', '#28593A', '#86B84F', '#3F7A44'], accents: ['#E87AAE', '#9B72D2'], core: '#72BF55' },\r\n    { id: 'daisies', label: 'Daisies', colors: ['#76A84D', '#315F3A', '#8FC95F', '#4A8742'], accents: ['#FFFDF2', '#F4D64E'], core: '#80C75B' }\r\n  ],\r\n  jelly: [\r\n    { id: 'candy', label: 'Candy', colors: ['#F48FB1', '#CE93D8', '#90CAF9', '#80CBC4'], core: '#CE93D8' },\r\n    { id: 'neon', label: 'Neon', colors: ['#E040FB', '#D500F9', '#AA00FF', '#6200EA'], core: '#6200EA' },\r\n    { id: 'cosmic', label: 'Cosmic', colors: ['#7E57C2', '#5E35B1', '#4527A0', '#311B92'], core: '#311B92' },\r\n    { id: 'fruit', label: 'Fruit', colors: ['#FFAB91', '#FF8A65', '#FF7043', '#F4511E'], core: '#F4511E' }\r\n  ],\r\n  pond: [\r\n    { id: 'brackish', label: 'Brackish', colors: ['#0E3B3A', '#2E6B5C', '#7FB8A0', '#4F7A2E'], core: '#5FD3B8' },\r\n    { id: 'koi', label: 'Koi', colors: ['#0B2E33', '#1F5C66', '#FF8A3D', '#3F6F2A'], core: '#FFB067' },\r\n    { id: 'lotus', label: 'Lotus', colors: ['#12313A', '#3B6E73', '#FFC2D9', '#4D7B33'], core: '#FFD3E4' },\r\n    { id: 'moonlit', label: 'Moonlit', colors: ['#071A2B', '#1D4766', '#9CC9E0', '#2F5A4A'], core: '#CFE8F5' }\r\n  ]\r\n};\r\n\r\n// Helper to check if a string is a valid 6-digit hex color\r\nfunction isValidHexColor(color) {\r\n  return typeof color === 'string' && /^#[0-9A-Fa-f]{6}$/.test(color);\r\n}\r\n\r\n// Helper to validate a palette entry\r\nfunction isValidPaletteEntry(entry) {\r\n  if (!entry || typeof entry !== 'object') return false;\r\n  if (!entry.id || typeof entry.id !== 'string') return false;\r\n  if (!entry.label || typeof entry.label !== 'string') return false;\r\n  if (!Array.isArray(entry.colors) || entry.colors.length < 3 || entry.colors.length > 6) return false;\r\n  if (!entry.colors.every(isValidHexColor)) return false;\r\n  if (!isValidHexColor(entry.core)) return false;\r\n  // Optional flower glints kept out of the ring colours (a Grass wormhole without its material must still read green).\r\n  if (entry.accents !== undefined && !(Array.isArray(entry.accents) && entry.accents.length === 2 && entry.accents.every(isValidHexColor))) return false;\r\n  return true;\r\n}\r\n\r\n// Helper to deep clone a palette entry defensively\r\nfunction clonePaletteEntry(entry) {\r\n  return {\r\n    id: entry.id,\r\n    label: entry.label,\r\n    colors: [...entry.colors],\r\n    ...(entry.accents ? { accents: [...entry.accents] } : {}),\r\n    core: entry.core\r\n  };\r\n}\r\n\r\n// Helper to get all valid presets for a category\r\nfunction getValidPresets(category) {\r\n  const presets = RAW_PALETTE_DATA[category];\r\n  if (!Array.isArray(presets)) return [];\r\n  return presets.filter(isValidPaletteEntry).map(clonePaletteEntry);\r\n}\r\n\r\n// Helper to find the first valid preset in a category\r\nfunction getFirstValidPreset(category) {\r\n  const presets = getValidPresets(category);\r\n  return presets.length > 0 ? presets[0] : null;\r\n}\r\n\r\n/**\r\n * Get a specific palette for a board ID and preset ID.\r\n * @param {string} boardId - The board identifier.\r\n * @param {string} presetId - The preset identifier.\r\n * @returns {object|null} - A defensive copy of the palette object, or null.\r\n */\r\nexport function paletteFor(boardId, presetId) {\r\n  // Check for null/undefined boardId\r\n  if (boardId == null) return null;\r\n\r\n  // Check for prototype property access (e.g., __proto__, constructor, toString)\r\n  if (Object.prototype.hasOwnProperty.call(Object, boardId) || boardId in Object.prototype) {\r\n    return null;\r\n  }\r\n\r\n  // Check if boardId is a direct property of RAW_PALETTE_DATA\r\n  if (!Object.prototype.hasOwnProperty.call(RAW_PALETTE_DATA, boardId)) {\r\n    return null;\r\n  }\r\n\r\n  const presets = RAW_PALETTE_DATA[boardId];\r\n  if (!Array.isArray(presets)) return null;\r\n\r\n  // If presetId is provided, find the matching preset\r\n  if (presetId != null && typeof presetId === 'string') {\r\n    const found = presets.find(p => p.id === presetId);\r\n    if (found && isValidPaletteEntry(found)) {\r\n      return clonePaletteEntry(found);\r\n    }\r\n  }\r\n\r\n  // Return the first valid preset as default\r\n  return getFirstValidPreset(boardId);\r\n}\r\n\r\n/**\r\n * Get all available palette options for a board ID.\r\n * @param {string} boardId - The board identifier.\r\n * @returns {Array} - An array of defensive copies of palette objects.\r\n */\r\nexport function paletteOptions(boardId) {\r\n  // Check for null/undefined boardId\r\n  if (boardId == null) return [];\r\n\r\n  // Check for prototype property access\r\n  if (Object.prototype.hasOwnProperty.call(Object, boardId) || boardId in Object.prototype) {\r\n    return [];\r\n  }\r\n\r\n  // Check if boardId is a direct property of RAW_PALETTE_DATA\r\n  if (!Object.prototype.hasOwnProperty.call(RAW_PALETTE_DATA, boardId)) {\r\n    return [];\r\n  }\r\n\r\n  return getValidPresets(boardId);\r\n}\r\n","modules/portal/portal-tunnel-pond.mjs":"// Optional grimoire tunnel material; downloaded with its board. A murky water well: rippling rings, silt drifting\r\n// down the walls, lily pads floating past and koi shadows sliding through the green.\r\nexport const material=`float pH(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nvec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\n float rip=.5+.5*sin(v*6.2832+sin(a*4.+v)*1.4),silt=pH(vec2(floor(a*40.),floor(v*6.)));\r\n vec3 c=mix(seq(0.)*.18,seq(1.)*.5,rip*.7+silt*.3);\r\n c+=seq(2.)*.25*pow(max(0.,sin(a*5.-v*2.3)),8.)*aa;\r\n float ca=a*4.774648,cv=v*.9;vec2 id=vec2(mod(floor(ca),30.),floor(cv)),q=vec2(fract(ca)-.5,fract(cv)-.5);float h=pH(id);\r\n float pad=(1.-smoothstep(.22,.27,length(q)))*step(.62,h)*step(.12,abs(atan(q.y,q.x)-h*6.))*aa;\r\n c=mix(c,seq(3.)*(.55+.3*h),pad);\r\n float koi=(1.-smoothstep(.1,.5,length(vec2(fract(a*.477+v*.11)-.5,(fract(v*.35)-.5)*3.))))*.6;\r\n return mix(c,c*.25,koi)+base*.12;\r\n}`;\r\nexport const core='#5fd3b8';\r\n","modules/portal/portal-tunnel-wood.mjs":"// Optional grimoire tunnel material; downloaded with its board. Cracks pulse and embers stream past with travel.\r\nexport const material=`float wH(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5453);}\r\nvec3 material(float a,float v,float z,float r,float aa,vec3 base){\r\nfloat bark=.5+.5*sin(a*28.+sin(v*.8)*2.);float crack=pow(1.-bark,16.);float ember=(.45+.55*sin(v*2.+a*3.))*crack;float ash=fract(sin(floor(a*150.)+floor(v*42.)*17.)*437.);\r\n float ca=a*9.549296586,cv=v*1.6;vec2 id=vec2(mod(floor(ca),60.),floor(cv)),q=vec2(fract(ca)-.5,fract(cv)-.5);float h=wH(id);\r\n float spark=(1.-smoothstep(.03,.11,length(q*vec2(1.,.6))))*step(.72,h)*(.5+.5*sin(v*6.+h*40.))*aa;\r\n vec3 woodBase=mix(seq(0.)*.05,seq(1.)*.32,bark);\r\n return woodBase*(.48+.52*ash)+base*ember*.9+mix(seq(2.),seq(3.),.5)*spark*1.4;\r\n}`;\r\nexport const core='#fa5815';\r\n","modules/portal/portal.css":"#portalHome{position:fixed;inset:0;z-index:35;background:#150f1e;overflow:hidden;touch-action:none}\r\n#portalHome[hidden]{display:none}\r\n#portalHome[hidden][data-building]{display:block;visibility:hidden;pointer-events:none}\r\n/* #111 MOM Inc metal frame. The board fills the window behind the overlay controls; its rail runs at the physical\r\n   perimeter. A board sets --face-* (its face box in the host; default: the whole\r\n   host) and the frame wraps it, above the board canvas, under the glass bezel and the trace canvas: it never takes a\r\n   pointer, and it scales with #portalHome in a dive to a home/nav destination (a dialog destination keeps the frame\r\n   still: see #portalChrome). Metal after the pod capsule and control board: CSS only. */\r\n#portalHome,#portalChrome{--portal-rail:15px}\r\n/* War Room metal (portal.mjs applyLookVars): unset keeps the stock look; set, the rail shades derive from one colour. */\r\n#portalHome,#portalChrome{--pm:var(--portal-metal)}\r\n.portal-frame{--mh:color-mix(in srgb,var(--pm) 62%,#fff);--md:color-mix(in srgb,var(--pm) 75%,#000);--mx:color-mix(in srgb,var(--pm) 55%,#000);--me:color-mix(in srgb,var(--pm) 90%,#fff)}\r\n#portalHome,#portalChrome{--portal-top-band:52px;--portal-key-w:100px;--portal-key-end:124px}\r\n#portalBoardHost{position:absolute;z-index:1;inset:var(--portal-top-band) var(--portal-rail) calc(var(--myr5-bar,88px) + var(--portal-rail))}\r\n.portal-frame{--screw:#cbbab0 0 1.4px,#57474f 1.9px 3px,#0000 3.5px;position:absolute;z-index:1;box-sizing:border-box;left:var(--face-left,0px);top:var(--face-top,0px);width:var(--face-width,100%);height:var(--face-height,100%);border-radius:3px;pointer-events:none;box-shadow:0 0 0 calc(var(--portal-rail) + 1px) #0e0a12,0 8px 16px calc(var(--portal-rail) - 2px) #000b}\r\n.portal-frame:before{content:'';position:absolute;inset:calc(-1*var(--portal-rail));padding:var(--portal-rail);border-radius:calc(var(--portal-rail)/2 + 3px);background:repeating-linear-gradient(90deg,#0000 0 3px,#ffffff06 3px 4px),repeating-linear-gradient(0deg,#0000 0 2px,#00000010 2px 3px),linear-gradient(160deg,var(--mh,#7e6a7c),var(--pm,#4d3d4f) 26%,var(--md,#3b2f42) 52%,var(--mx,#2b2132) 78%,var(--me,#564458));box-shadow:inset 0 1px #e6d2da99,inset 1px 0 #d6c0cc44,inset 0 -2px #000a,inset -1px 0 #0007;-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}\r\n/* The lip: a dark seam, a back-lit bevel line on the rail's inner edge, and the rail's shadow falling onto the board. */\r\n.portal-frame:after{content:'';position:absolute;inset:0;border-radius:inherit;box-shadow:0 0 0 1px #0e0a12,0 0 0 2.5px #bba4b355,inset 0 4px 6px #000b,inset 3px 0 5px #0007,inset -2px 0 4px #0006,inset 0 -2px 4px #0007}\r\n/* Hex bolts on washers at the rail's centre line: --x/--y are 0/1 for the sides, fractions along them. */\r\n.portal-frame i{position:absolute;width:10px;height:10px;margin:-5px;left:calc(var(--x)*(100% + var(--portal-rail)) - var(--portal-rail)/2);top:calc(var(--y)*(100% + var(--portal-rail)) - var(--portal-rail)/2);border-radius:50%;background:radial-gradient(circle at 50% 40%,#3a2d3e,#150f19 70%);box-shadow:0 1px 1px #000a,0 -1px #e6d2da40}\r\n.portal-frame i:before{content:'';position:absolute;inset:1px;clip-path:polygon(25% 6%,75% 6%,100% 50%,75% 94%,25% 94%,0 50%);background:radial-gradient(circle at 34% 28%,#f4e8dd,#bca6b2 32%,#6d5a6b 68%,#3a2d3e)}\r\n/* Energy (Ian 23 Sept): a recessed channel down the middle of each rail, each holding a neon stripe (JS sets --energy,\r\n   hard colour stops; --energy-px, one cycle) that slides along it by transform. Faint at rest, bright (.hot) while a\r\n   portal opens or closes; the joins sit under the corner bolts. */\r\n.portal-energy{position:absolute;inset:calc(var(--portal-rail)/-2);opacity:.55;transition:opacity .4s}\r\n.portal-energy.hot{opacity:1}\r\n.portal-energy>span{position:absolute;overflow:hidden;border-radius:2px;background:#0d0a10;box-shadow:0 0 0 1px #0000004d,0 0 5px var(--portal-strip-glow,#b026ff40)}\r\n.portal-energy>span:nth-child(odd){left:0;right:0;height:4px}\r\n.portal-energy>span:nth-child(1){top:-2px}\r\n.portal-energy>span:nth-child(3){bottom:-2px}\r\n.portal-energy>span:nth-child(even){top:0;bottom:0;width:4px}\r\n.portal-energy>span:nth-child(2){right:-2px}\r\n.portal-energy>span:nth-child(4){left:-2px}\r\n.portal-energy>span>span{position:absolute;left:0;top:0;background:repeating-linear-gradient(var(--dir),var(--energy));box-shadow:inset 0 0 1px 1px #0d0a10b0}\r\n.portal-energy>span:nth-child(odd)>span{--dir:90deg;height:100%;width:calc(100% + var(--energy-px))}\r\n.portal-energy>span:nth-child(even)>span{--dir:180deg;width:100%;height:calc(100% + var(--energy-px))}\r\n/* R20 (Ian 2 Oct): the MOM Inc logo engraved into the top rail, right of the Grimoire key's slot (#portalSettingsButton).\r\n   The logo's ink (pod/mom-inc-engrave.png: black deep, purple shallower) is a mask: a dark cut with a lit lower lip.\r\n   Its box is measured from the frame's top-left so it stays put through a dive; it fills a 52px top band, or shrinks\r\n   into a plain 15px rail. */\r\n.portal-frame b{--eh:clamp(11px,calc(var(--cap,var(--portal-rail)) - 28px),24px);position:absolute;left:calc(var(--portal-key-end,124px) - var(--side,var(--portal-rail)));top:calc(min(var(--cap,var(--portal-rail)),var(--portal-top-band,52px))/2 - var(--cap,var(--portal-rail)));translate:0 -50%;width:calc(var(--eh)*363/72);height:var(--eh);font-size:0;color:#0000;pointer-events:none}\r\n.portal-frame b:before,.portal-frame b:after{content:'';position:absolute;inset:0;-webkit-mask:url(/pod/mom-inc-engrave.png) center/contain no-repeat;mask:url(/pod/mom-inc-engrave.png) center/contain no-repeat}\r\n.portal-frame b:after{background:#e8d4e070;translate:0 1px}\r\n.portal-frame b:before{z-index:1;background:linear-gradient(#0b060eee,#2a1d30cc)}\r\n/* The border stays when a destination opens: #portalChrome, a top-layer copy of the frame at the board's rest box (JS sets\r\n   --face-*) above the destination dialog, with a matte of the board colour over the rest of the screen, so the dive\r\n   plays in the frame's window and the dialog (.portal-framed) sits in it. Camera-only mode hides it with every other\r\n   body child. The app's bottom bar sits below the frame: see the release 5 rules after these. */\r\n#portalChrome{position:fixed;inset:0;width:auto;height:auto;max-width:none;max-height:none;margin:0;padding:0;border:0;background:none;overflow:hidden;pointer-events:none}\r\n#portalChrome::backdrop{display:none}\r\n#portalChrome .portal-frame{box-shadow:0 0 0 calc(var(--portal-rail) + 1px) #0e0a12,0 8px 16px calc(var(--portal-rail) - 2px) #000b,0 0 0 100vmax #17111e}\r\ndialog.portal-framed{position:fixed!important;inset:auto!important;left:var(--face-left)!important;top:var(--face-top)!important;width:var(--face-width)!important;height:var(--face-height)!important;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;margin:0!important;border-radius:3px!important;box-sizing:border-box!important}\r\ndialog.portal-framed.portal-fullscreen{--portal-rail:15px;left:var(--face-left)!important;top:var(--face-top)!important;width:var(--face-width)!important;height:var(--face-height)!important;border:0!important;border-radius:3px!important;clip-path:none!important}\r\ndialog.portal-framed.portal-fullscreen.meditation-panel .meditation-speech{padding-inline:8px!important;overflow-wrap:anywhere}\r\ndialog.portal-framed::backdrop{background:#17111e!important}\r\n/* The dock and portal controls float above the cloth. They no longer reserve a blank band inside the frame. */\r\n/* #134 the energy round an open destination, in its portal's shape (JS: portal.mjs showAura). All masks drawn once; in\r\n   each fire layer a wheel of the neons (a conic gradient round the outline's centre, JS sizes it) turns by transform.\r\n   Takes no pointer (the chrome takes none). */\r\n.portal-aura{position:absolute;z-index:2;inset:0;pointer-events:none;--aura:#fff}\r\n.portal-aura>*{position:absolute;inset:0;width:100%;height:100%}\r\n.portal-aura-fire,.portal-aura-flash{display:block;-webkit-mask-size:100% 100%;mask-size:100% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}\r\n.portal-aura-fire{overflow:hidden}\r\n.portal-aura-fire>i{position:absolute;background:conic-gradient(var(--aura-seq));will-change:transform}\r\n.portal-aura-fire>i.b{opacity:.45;background:conic-gradient(from 90deg,var(--aura-seq))}\r\n.portal-aura-fire>.portal-aura-spec{border-radius:50%;background:radial-gradient(circle,#fff 0,#ffffffa0 22%,#fff0 68%);opacity:.75}\r\n.portal-aura-flash{background:radial-gradient(circle at var(--cx) var(--cy),#fff,color-mix(in srgb,var(--aura) 55%,#fff))}\r\n.portal-aura>b{position:absolute;inset:auto;width:6px;height:6px;margin:-3px;border-radius:50%;box-shadow:0 0 8px 2px var(--aura)}\r\n/* #132 a whole window's name rides its upper rail, outside the window. R7: a peer-through cut has none. */\r\n.portal-aura>svg{overflow:visible}\r\n.portal-aura-name{font:800 9.5px/1 ui-monospace,'Cascadia Mono',Consolas,Menlo,monospace;letter-spacing:.38em;fill:color-mix(in srgb,var(--aura) 70%,#fff);stroke:#0b0710;stroke-width:3px;stroke-linejoin:round;paint-order:stroke}\r\n/* #131 seen through the hole: the quilt stays on as the wall, so a shaped destination's backdrop is clear (the dialog's\r\n   clip-path is JS's). */\r\ndialog.portal-framed.portal-shaped::backdrop{background:none!important;-webkit-backdrop-filter:none!important;backdrop-filter:none!important}\r\n/* R7 (Ian 26 and 29 Sept): a scene seen through its cut shows the scene and nothing else, no text and none of \"the close\r\n   and all that is unimportant\": titles, Close/Done, labels, toggles, status lines, cards, the tilt chip. visibility (not\r\n   opacity), so nothing hidden takes a tap or focus. The scene's own objects stay tappable (the pyramid, the bosses, the\r\n   whiteboard, the ship). The ways on: phone back or Escape, the bar, and a double-tap to the full screen, which brings\r\n   it all back. (A flat menu in a cut, .portal-inset, is its text: it keeps it.) */\r\ndialog.portal-shaped:not(.portal-inset,.portal-leaned)>:not(#coachDock){visibility:hidden}\r\ndialog.portal-shaped:not(.portal-inset,.portal-leaned) :is(#pyramidScanner,.ach-stage,.classroom-stage,.ship-view-stage){visibility:visible}\r\ndialog.portal-shaped:not(.portal-inset,.portal-leaned) :is(.pyramid-ui,.paper-poster,.paper-note,.pyramid-loading-text,.classroom-note,.classroom-desks :is(button,figcaption),.classroom-board>*,.ship-scene-status){visibility:hidden}\r\n/* R7: no two-finger zoom while the portal or any menu is up (framed or opened from the bar); one finger still scrolls, taps\r\n   and traces (touch-action is intersected down the tree, so this reaches everything, top-layer menus included). */\r\nhtml:has(#portalHome:not([hidden]),dialog[open]){touch-action:pan-x pan-y}\r\n/* A flat menu in a cut: its box is the cut's largest rectangle (JS sets --face-*), its content laid out zoomed out\r\n   (--inset-zoom) and scrolling inside it, sliding a little with tilt behind the fixed wall. The bar and the portal's\r\n   buttons are not its content. */\r\ndialog.portal-framed.portal-inset{padding:10px 8px!important;overflow:auto!important;overscroll-behavior:contain}\r\ndialog.portal-framed.portal-inset>:not(#coachDock):not(.portal-peer-ui){zoom:var(--inset-zoom,1);translate:calc(var(--peer-x,0)*3px) calc(var(--peer-y,0)*3px)}\r\ndialog.portal-framed.portal-inset :is(h1,h2){white-space:normal!important;overflow-wrap:break-word}\r\n/* The phone scoreboard normally floats Done over its heading. In the narrow diamond,\r\n   give it a separate row so zoom cannot put the button over the title. */\r\n#accountPanel.portal-inset>header{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;min-height:0}\r\n#accountPanel.portal-inset>header>[data-close]{position:static;grid-row:1;justify-self:end}\r\n#accountPanel.portal-inset>header>div{grid-row:2;min-width:0}\r\n#accountPanel.portal-inset>header h2{padding-top:0}\r\n/* The wormhole's still depth left in the cut round a flat menu (portal.mjs quietPhase). */\r\n.portal-glass.still{background:radial-gradient(ellipse at 50% 45%,color-mix(in srgb,var(--glass) 26%,#1b1229) 0,#110a19 62%,#08050c 100%)}\r\n.portal-glass.still>b,.portal-glass.still:after{display:none}\r\n.portal-peer-ui{position:fixed;left:0;top:0;width:0;height:0;z-index:60}\r\n.portal-peer-ui>button:not(#_){all:unset;position:fixed;box-sizing:border-box;display:grid;place-items:center;width:44px;height:44px;border-radius:50%;background:#140e1ee6;color:#fff;font:700 18px/1 system-ui,sans-serif;border:2px solid color-mix(in srgb,var(--peer-ui,#b026ff) 70%,#fff);box-shadow:0 0 0 1px #0008,0 0 14px var(--peer-ui,#b026ff),0 4px 10px #0009;cursor:pointer;touch-action:manipulation;-webkit-tap-highlight-color:transparent}\r\n.portal-peer-ui>button:not(#_):focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n.portal-peer-ui>.portal-tilt-chip:not(#_){width:auto;height:26px;padding:0 3px 0 10px;border-radius:8px 8px 0 0;display:flex;gap:8px;font:600 11px/1 system-ui,sans-serif}\r\n.portal-tilt-chip b{padding:4px 9px;border-radius:999px;background:#fff;color:#1a1024}\r\ndialog.portal-leaned .portal-peer-ui>[data-peer-close]:not(#_){visibility:hidden}\r\ndialog.portal-leaned .portal-peer-ui>[data-peer-lean]:not(#_){width:36px;height:36px;font-size:15px;opacity:.85}\r\n/* Closing: the destination's empty shell, shrinking into the wormhole core over the reverse dive. */\r\ndialog.portal-ghost{display:block!important;z-index:36!important;pointer-events:none!important;overflow:hidden!important}\r\n#portalShadows{position:absolute;inset:0;z-index:2;pointer-events:none;mix-blend-mode:multiply;opacity:.12}\r\n#portalShadows i{position:absolute;width:60%;height:60%;border-radius:50%;background:radial-gradient(circle,#000 0%,transparent 70%);filter:blur(30px)}\r\n#portalShadows i:nth-child(1){left:-10%;top:-10%;animation:portal-drift-a 34s ease-in-out infinite alternate}\r\n#portalShadows i:nth-child(2){right:-15%;top:20%;animation:portal-drift-b 41s ease-in-out infinite alternate}\r\n#portalShadows i:nth-child(3){left:20%;bottom:-20%;animation:portal-drift-c 27s ease-in-out infinite alternate}\r\n@keyframes portal-drift-a{from{transform:translate(0,0)}to{transform:translate(18%,12%)}}\r\n@keyframes portal-drift-b{from{transform:translate(0,0)}to{transform:translate(-14%,10%)}}\r\n@keyframes portal-drift-c{from{transform:translate(0,0)}to{transform:translate(10%,-16%)}}\r\n@media (prefers-reduced-motion:reduce){#portalShadows i{animation:none!important}}\r\n#portalOverlay{position:absolute;inset:0;z-index:5;width:100%;height:100%;touch-action:none}\r\n#portalObjects{position:absolute;inset:0;z-index:8;pointer-events:none}\r\n.portal-object{position:fixed;left:0;top:0;width:64px;height:64px;margin:-32px 0 0 -32px;border-radius:50%;display:grid;place-items:center;color:#fff;background:radial-gradient(circle,color-mix(in srgb,var(--glow) 40%,#1a1024) 0%,transparent 72%);box-shadow:0 0 22px var(--glow),inset 0 0 12px var(--glow);transform:scale(1) rotate(0deg);opacity:1;transition:transform .6s cubic-bezier(.3,0,.7,1),opacity .6s ease,left .6s cubic-bezier(.3,0,.7,1),top .6s cubic-bezier(.3,0,.7,1);pointer-events:none;z-index:8}\r\n.portal-object.falling{transform:scale(.05) rotate(240deg);opacity:0}\r\n/* Neon liquid glass: sits between #portalHome's background and the (transparent) board canvas, boxed and clipped\r\n   to the cut shape (JS sets the box and clip), so it only shows through the hole. JS fades it in (portal-glass-in,\r\n   600 ms). The WebGL wormhole canvas draws the whole look (.gl); <b> and the sheen are the no-WebGL fallback. */\r\n.portal-glass{position:absolute;z-index:0;pointer-events:none;overflow:hidden;--glass:#fff}\r\n/* R7: without WebGL (Android after a GPU reset) this is the wormhole on every board: the neon rings (JS: --seq0/--seq, the\r\n   WebGL tunnel's ring colours) streaming into a bright core (--ring is registered so the stops can move), twisted streaks\r\n   turning with the rainbow, depth fog toward the rim. Compositor-cheap; still under reduced motion. */\r\n@property --ring{syntax:'<length>';inherits:false;initial-value:0px}\r\n.portal-glass>b{position:absolute;inset:-25%;background:radial-gradient(circle at 50% 46%,#fff 0,color-mix(in srgb,var(--glass) 40%,#fff) 3%,#fff0 13%),radial-gradient(circle at 50% 46%,#07040b00 22%,#07040b99 72%),repeating-conic-gradient(from 0deg at 50% 46%,#07040b00 0deg 9deg,#07040b40 13deg,#07040b00 17deg 24deg),repeating-radial-gradient(circle at 50% 46%,var(--seq0,#ff5f1f) var(--ring),var(--seq,#ffff33,#39ff14,#1f51ff,#b026ff,#ff10f0),var(--seq0,#ff5f1f) calc(var(--ring) + 168px))}\r\n.portal-glass>canvas{position:absolute;inset:0;width:100%;height:100%;display:block}\r\n.portal-glass.gl>b,.portal-glass.gl:after{display:none}\r\n.portal-glass:not(.gl)>b{animation:portal-rainbow-turn 9s linear infinite,portal-rings 2.4s linear infinite;transform-origin:50% 46%}\r\n@keyframes portal-rainbow-turn{to{transform:rotate(360deg)}}\r\n@keyframes portal-rings{from{--ring:0px}to{--ring:-168px}}\r\n.portal-glass:after{content:\"\";position:absolute;top:-20%;bottom:-20%;left:-60%;right:-60%;mix-blend-mode:screen;background:linear-gradient(105deg,transparent 42%,#ffffff55 49%,#ffffff1a 53%,transparent 60%);animation:portal-sheen 6s ease-in-out infinite alternate}\r\n/* Glass bezel over the board along the exact cut outline, wide enough (JS sets it) to cover the cloth's stair-stepped\r\n   hole edge: soft shadow, smoky glass lit top-left, a neon filament with its glow, a specular line. Static, no filters. */\r\n.portal-bezel{position:absolute;inset:0;width:100%;height:100%;z-index:3;pointer-events:none;overflow:visible}\r\n.portal-bezel polygon{fill:none;stroke-linejoin:round}\r\n.portal-bezel .shade{stroke:#000;stroke-opacity:.2}\r\n.portal-bezel .body{stroke:url(#portalBezelLit)}\r\n.portal-bezel .glow{stroke:var(--glass);stroke-opacity:.3}\r\n.portal-bezel .core{stroke:color-mix(in srgb,var(--glass) 55%,#fff)}\r\n.portal-bezel .spec{stroke:url(#portalBezelSpec)}\r\n.portal-bezel .lit{stop-color:color-mix(in srgb,var(--glass) 40%,#3a3048)}\r\n.portal-bezel .mid{stop-color:color-mix(in srgb,var(--glass) 22%,#140e1e)}\r\n.portal-bezel .far{stop-color:color-mix(in srgb,var(--glass) 12%,#08050c)}\r\n.portal-ripple{position:absolute;width:150px;height:150px;margin:-75px 0 0 -75px;border-radius:50%;border:3px solid color-mix(in srgb,var(--glass) 15%,#fff);box-shadow:0 0 0 2px color-mix(in srgb,var(--glass) 55%,#000),0 0 22px 3px #ffffff90,inset 0 0 26px #ffffffa0;opacity:0;pointer-events:none}\r\n/* A destination dialog growing out of the wormhole's core: its backdrop fades in over the dive (JS sets class + duration). */\r\n.portal-arriving::backdrop{animation:portal-glass-in var(--portal-arrive,.6s) ease both}\r\n@keyframes portal-sheen{from{transform:translateX(-28%)}to{transform:translateX(28%)}}\r\n@keyframes portal-glass-in{from{opacity:0}}\r\n@keyframes portal-ripple{from{transform:scale(.12);opacity:.95}to{transform:scale(2.2);opacity:0}}\r\n@media (prefers-reduced-motion:reduce){.portal-glass:after,.portal-glass>b{animation:none}}\r\n#portalStatus{position:fixed;left:16px;right:16px;bottom:calc(108px + env(safe-area-inset-bottom));z-index:10;margin:0;text-align:center;color:#f5d9ff;font:13px/1.4 var(--font,system-ui);text-shadow:0 1px 3px #000}\r\n#portalStatus:empty{display:none}\r\n#portalRetry{position:fixed;left:50%;bottom:calc(76px + env(safe-area-inset-bottom));z-index:11;transform:translateX(-50%);padding:9px 16px;border:1px solid #f5d9ff;border-radius:999px;background:#241331;color:#fff;font:600 14px/1.2 var(--font,system-ui);box-shadow:0 2px 10px #0008}\r\n#portalRetry[hidden]{display:none}\r\n#portalMenuButton{position:fixed;left:50%;bottom:max(16px,env(safe-area-inset-bottom));transform:translateX(-50%);z-index:10;min-height:48px;min-width:120px;padding:0 22px;border-radius:999px;border:1px solid #ffffff55;background:#1c1428e6;color:#f5eaff;font:600 15px/1 var(--font,system-ui);backdrop-filter:blur(10px);box-shadow:0 6px 20px #0007}\r\n#portalExitButton{position:fixed;right:12px;top:max(12px,env(safe-area-inset-top));z-index:10;min-height:44px;padding:0 14px;border-radius:999px;border:1px solid #ffffff55;background:#1c1428e6;color:#f5eaff;font:600 14px/1 var(--font,system-ui)}\r\n/* R20 (Ian 2 Oct): the Grimoire opener is a metal key set into the top rail at the left, like the dock keys (raised on a\r\n   dark shadow, pressed down on tap), with its label lit CRT-orange in a small recessed screen. The board starts below\r\n   the 52px top band (#portalBoardHost), so the key and the engraved logo beside it cover nothing. */\r\n#portalSettingsButton{position:fixed;left:12px;top:4px;z-index:10;box-sizing:border-box;height:44px;min-height:44px;width:var(--portal-key-w,100px);margin:0;padding:0 0 1px;border:0;border-radius:4px;background:none;-webkit-appearance:none;appearance:none;color:#ff8800;font:700 11px/1 ui-monospace,'Cascadia Mono',Consolas,Menlo,monospace;letter-spacing:.12em;text-shadow:0 0 4px #ff8800,0 0 9px #ff880099;filter:drop-shadow(0 3px 0 #130d18) drop-shadow(0 0 1px #000);touch-action:manipulation;isolation:isolate;cursor:pointer}\r\n#portalSettingsButton::before{content:\"\";position:absolute;inset:4px 0;z-index:-1;pointer-events:none;border-radius:4px;background:linear-gradient(145deg,#a58a9c,#5a4560 55%,#3b2c42);box-shadow:inset 2px 2px #ffffff40,inset -2px -3px #0006}\r\n#portalSettingsButton::after{content:\"\";position:absolute;inset:10px 7px;z-index:-1;pointer-events:none;border-radius:3px;background:repeating-linear-gradient(#00000066 0 1px,#0000 1px 3px),radial-gradient(ellipse 90% 100% at 50% 40%,#3a2008,#150b06 70%,#050304);box-shadow:inset 0 0 6px 1px #000,0 1px #ffffff30}\r\n#portalSettingsButton:active{filter:drop-shadow(0 1px 0 #130d18) drop-shadow(0 0 1px #000);translate:0 2px}\r\n#portalSettingsButton:focus-visible,.portal-palette select:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n/* The \"Updated: …\" toast (app-updates.mjs) sits over the portal's bottom controls at its default\r\n   position; while the quilt is up, lift it clear of the Menu button (it's exempted from the portal's\r\n   inert sweep in portal.mjs, so it stays tappable there instead). */\r\nbody:has(#portalHome:not([hidden])) .app-update-banner{bottom:calc(76px + env(safe-area-inset-bottom))}\r\n/* Release 5: Armie's inbox button (armie-inbox-ui.mjs) sits bottom-right above the bar, which on the quilt is the\r\n   metal frame's corner bolt and the board face. While the quilt is up it moves to the top-left of the band above the\r\n   frame, level with Pod (exempt from the inert sweep and in the focus cycle, portal.mjs, so it works there). */\r\nbody:has(#portalHome:not([hidden])) .armie-inbox-launcher{top:calc(max(12px,env(safe-area-inset-top)) + 2px);bottom:auto;left:auto;right:calc(12px + env(safe-area-inset-right,0px))} /* R20: top-right, clear of the Grimoire key */\r\n/* Any dialog opened over the quilt: the board should still glow through instead of going near-black. */\r\nbody:has(#portalHome:not([hidden])) dialog::backdrop{background:#0c081266}\r\n.portal-transition-flash{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;z-index:10000;pointer-events:none;background:radial-gradient(ellipse at center,#fff 0%,#fff8dc 45%,#ffd86a 100%);animation:portal-transition-flash .52s ease-in-out both}\r\n@keyframes portal-transition-flash{0%{opacity:0}35%{opacity:1}65%{opacity:1}100%{opacity:0}}\r\n@media(prefers-reduced-motion:reduce){.portal-transition-flash{animation:none;opacity:1}}\r\n.portal-menu{border:1px solid #ffffff33;border-radius:16px;background:#1a1224f5;color:#f5eaff;padding:18px;max-width:360px;width:88vw;max-height:min(88dvh,760px);overflow:auto;overscroll-behavior:contain}\r\n.portal-menu::backdrop{background:#0c0812cc}\r\n.portal-menu header{display:flex;align-items:center;justify-content:space-between;gap:12px}\r\n.portal-menu-grid{display:grid;gap:8px;margin:12px 0}\r\n.portal-menu-grid button{display:flex;align-items:center;min-height:44px;padding:10px 12px;border-radius:10px;background:#ffffff10;color:inherit;font:15px/1 var(--font,system-ui);text-align:left;touch-action:manipulation}\r\n.portal-menu-grid button i{display:inline-block;width:10px;height:10px;border-radius:50%;background:var(--dot);margin-right:10px;box-shadow:0 0 8px var(--dot)}\r\n.portal-board-chips{display:flex;align-items:center;flex-wrap:wrap;gap:6px;margin:0 0 12px}\r\n.portal-board-chips button{min-height:44px;padding:6px 9px;border-radius:999px;background:#ffffff10;color:inherit;font:13px/1 var(--font,system-ui);border:1px solid #ffffff2a;touch-action:manipulation}\r\n.portal-board-chips button[aria-pressed=\"true\"]{background:#ffffff30;border-color:#ffffff66}\r\n.portal-palette{display:grid;gap:6px;margin:12px 0;color:inherit;font:600 14px/1.3 var(--font,system-ui)}\r\n.portal-palette select{min-height:44px;padding:8px 10px;border:1px solid #ffffff44;border-radius:8px;background:#21172c;color:inherit;font:inherit}\r\n.portal-menu header [data-menu-close],.portal-look-controls [data-look-reset]{min-height:44px;padding:0 14px;border:1px solid #ffffff44;border-radius:8px;background:#ffffff12;color:inherit;font:600 13px/1 var(--font,system-ui);touch-action:manipulation}\r\n.portal-menu :is(button,summary,input,select):focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n.portal-look-controls{margin:10px 0;padding:8px;border:1px solid #ffffff26;border-radius:10px}\r\n.portal-look-controls legend{padding:0 6px;font:600 12px/1 var(--font,system-ui);opacity:.75}\r\n.portal-look-controls>div{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}\r\n.portal-look-controls label{display:grid;justify-items:center;gap:4px;font:12px/1.2 var(--font,system-ui)}\r\n.portal-look-controls input{box-sizing:border-box;width:48px;height:44px;padding:3px;border:1px solid #ac91a4;border-radius:6px;background:#302338}\r\n.portal-look-controls [data-look-reset]{margin-top:8px}\r\n.portal-full-menu{margin:12px 0}\r\n.portal-full-menu>summary{display:flex;align-items:center;min-height:44px;padding:0 12px;border:1px solid #ffffff33;border-radius:9px;background:#ffffff10;font:600 14px/1 var(--font,system-ui);cursor:pointer;touch-action:manipulation}\r\n.portal-full-menu>summary::marker{color:#f5eaff}\r\n.portal-full-menu[open]>summary{border-color:#ffffff66}\r\n#portalMenuStatus:empty{display:none}\r\n/* The locked intake theme turns off every animation; the portal home is for everyone. */\r\nhtml[data-public-state] #portalHome .portal-glass:after{animation:portal-sheen 6s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] #portalShadows i:nth-child(1){animation:portal-drift-a 34s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] #portalShadows i:nth-child(2){animation:portal-drift-b 41s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] #portalShadows i:nth-child(3){animation:portal-drift-c 27s ease-in-out infinite alternate!important}\r\nhtml[data-public-state] #portalObjects .portal-object{transition:transform .6s cubic-bezier(.3,0,.7,1),opacity .6s ease,left .6s ease,top .6s ease!important}\r\n@media (prefers-reduced-motion:reduce){html[data-public-state] #portalHome *,html[data-public-state] #portalHome :after{animation:none!important;transition:none!important}}\r\n.portal-menu header button{min-height:44px;padding:0 16px;border-radius:10px;border:1px solid #ffffff44;background:#ffffff14;color:#f5eaff}\r\n\r\n/* Full device metalwork surrounds the proportionate board. The upper plate occupies the\r\n   unused height; texture pixels are never pulled into it. */\r\n#portalBoardHost .portal-frame{--cap:calc(var(--face-top,0px) + var(--portal-top-band));--side:calc(var(--face-left,0px) + var(--portal-rail))}\r\n#portalChrome .portal-frame{--cap:var(--face-top,15px);--side:var(--face-left,15px)}\r\n.portal-frame:before{top:calc(-1*var(--cap));left:calc(-1*var(--side));right:calc(-1*var(--side));bottom:calc(-1*var(--myr5-bar,88px));padding:var(--cap) var(--side) var(--myr5-bar,88px);background:repeating-linear-gradient(0deg,#0000 0 25px,#0b071966 26px,#d3bed92e 27px,#0000 29px),repeating-linear-gradient(90deg,#0000 0 3px,#ffffff06 3px 4px),linear-gradient(160deg,var(--mh,#7e6a7c),var(--pm,#4d3d4f) 26%,var(--md,#3b2f42) 52%,var(--mx,#2b2132) 78%,var(--me,#564458))}\r\n#coachDock.coach-dock{height:var(--myr5-bar,88px);gap:8px;padding:9px 12px calc(12px + env(safe-area-inset-bottom));border-top:0;background:repeating-linear-gradient(90deg,#0000 0 3px,#ffffff06 3px 4px),linear-gradient(#493a50,#2b2132);box-shadow:inset 0 2px #ad97ad66,inset 0 6px 9px #0007;backdrop-filter:none}\r\n#coachDock.coach-dock button,#coachDock.coach-dock button.dock-portal{position:relative;height:53px;min-width:0;border:2px solid #9a8295;border-top-color:#cbb5c5;border-bottom-color:#4b384d;border-radius:4px!important;background:linear-gradient(145deg,#806979,#4a394e 80%);box-shadow:0 0 0 3px #1c1421,0 6px 0 2px #130d18,inset 1px 2px #e0c3d366,inset -2px -3px #25182c99;color:#f6e5d5;transform:none;translate:none}\r\n#coachDock.coach-dock button:active,#coachDock.coach-dock button[aria-current=page]{transform:translateY(4px);box-shadow:0 0 0 3px #1c1421,0 2px 0 2px #130d18,inset 1px 2px 5px #0008;border-top-color:#9b8194;color:#fff3d3}\r\n#coachDock.coach-dock button:before{background:#211927;border-color:#100b16;border-radius:1px}\r\n#coachDock.coach-dock button[aria-current=page]:before{background:#e7b875;box-shadow:0 0 6px #f9c88088}\r\n#portalMenuButton,#portalExitButton{border-radius:4px;backdrop-filter:none;background:linear-gradient(#8b7586,#514055);border:2px outset #ae94a7;box-shadow:0 4px #211626,inset 0 1px #dbc1cd66}\r\n#portalMenuButton:active,#portalExitButton:active{box-shadow:0 1px #211626;translate:0 3px}\r\n.portal-color{display:flex;align-items:center;justify-content:space-between;gap:16px;font:13px system-ui;margin:12px 0}.portal-color input{width:48px;height:44px;padding:3px;border:1px solid #ac91a4;background:#302338}\r\n/* Full scenes stay inside the inset face; the room reserves its dock within that face. */\r\n#portalChrome.portal-housing-fullscreen .portal-frame:before{bottom:calc(-1*var(--portal-rail));padding-bottom:var(--portal-rail)}\r\n/* R20 (Ian 2 Oct): the dock is a fixed console below the housing on every page, never inside the frame or its glow. The\r\n   chrome (frame, matte, aura) stops at the dock's top edge, so it never paints over the keys. */\r\n#portalChrome{bottom:var(--myr5-bar)}\r\n:is(body[data-tracking=true],body[data-screen=rest]) #portalChrome{bottom:0}\r\ndialog.portal-framed.portal-fullscreen #coachDock{left:0!important;right:0!important;bottom:0!important;width:auto!important;height:var(--myr5-bar)!important}\r\n\r\n\r\n/* A decoded meal photo and a classroom whiteboard tap step into the full destination. */\r\n#mealsPanel.portal-fullscreen #mealScanStage{inset:0!important;width:100%!important;height:100%!important}\r\n#mealsPanel.portal-fullscreen .food-sheet{padding-bottom:max(12px,env(safe-area-inset-bottom))}\r\n\r\n\r\n/* Dock keys: 44px hit boxes with smaller tactile silhouettes on the span; the Portal key sits at true centre. */\r\n#coachDock.coach-dock{box-sizing:border-box;height:var(--myr5-bar,88px);max-width:100vw;display:grid;grid-template-columns:repeat(2,44px) 1fr repeat(3,44px);grid-template-rows:44px;align-content:center;align-items:center;gap:0 4px;padding:0 max(8px,env(safe-area-inset-right)) env(safe-area-inset-bottom) max(8px,env(safe-area-inset-left));overflow:visible}\r\n#coachDock.coach-dock.coach-dock button.dock-control{grid-row:1;width:44px;height:44px;min-height:44px;padding:0;display:grid;place-items:center;background:none;border:0;box-shadow:none;border-radius:0!important;clip-path:none;filter:drop-shadow(0 3px 0 #130d18) drop-shadow(0 0 1px #000)}\r\n#coachDock.coach-dock.coach-dock button.dock-control:before{display:none}\r\n#coachDock .dock-control>span{width:36px;height:36px;display:grid;place-items:center;color:#f6e5d5;background:linear-gradient(145deg,#a58a9c,#5a4560 55%,#3b2c42);box-shadow:inset 2px 2px #ffffff40,inset -2px -3px #0006;transition:transform .08s}\r\n#coachDock .dock-control>span svg{width:22px;height:22px}\r\n#coachDock .dock-control:is(:active,[aria-current=page]){filter:drop-shadow(0 1px 0 #130d18)}\r\n#coachDock .dock-control:is(:active,[aria-current=page])>span{transform:translateY(2px);color:#ffd48a}\r\n#coachDock .dock-settings{grid-column:1}#coachDock .dock-settings>span{border-radius:50%}\r\n#coachDock .dock-scoreboard{grid-column:2}#coachDock .dock-scoreboard>span{border-radius:14px 14px 6px 6px}\r\n#coachDock .dock-food{grid-column:4}#coachDock .dock-food>span{width:40px;height:30px;border-radius:5px 5px 9px 9px}\r\n#coachDock .dock-achievements{grid-column:5}#coachDock .dock-achievements>span{clip-path:polygon(0 0,100% 0,100% 55%,50% 100%,0 55%);background:linear-gradient(145deg,#f2c46f,#b98033)}\r\n#coachDock .dock-pod{grid-column:6}#coachDock .dock-pod>span{width:30px;border-radius:15px}\r\n/* The existing pod sound switch (#toggleVoice, moved here by mountLaunch) sits in the blank dock slot beside the phone key: same 44px hit box, its ON/OFF text in a 36px key, its SOUND label in the spare strip under the row. */\r\n#coachDock .dock-sound{grid-row:1;position:relative;width:44px;height:44px}\r\n#coachDock.coach-dock.coach-dock .dock-sound button.dock-control{font:700 10px var(--pixel-font,ui-monospace,monospace);color:#f6e5d5;padding:4px;background:linear-gradient(145deg,#a58a9c,#5a4560 55%,#3b2c42) content-box;box-shadow:none}\r\n#coachDock .dock-sound button[data-on=true]{color:#ffd48a;text-shadow:0 0 6px #ffd36e}\r\n#coachDock .dock-sound button:disabled{opacity:.5}\r\n#coachDock .dock-sound .cb-label{position:absolute;top:100%;left:50%;translate:-50% 0;margin-top:4px;z-index:1;font:700 8px/1 ui-monospace,'Cascadia Mono',Consolas,Menlo,monospace;letter-spacing:.06em;color:#f6e5d5;white-space:nowrap;pointer-events:none}\r\n@media(orientation:landscape) and (max-height:500px){#coachDock .dock-sound .cb-label{margin-top:1px}} /* R20: fits the 64px landscape console */\r\n#coachDock.coach-dock button.dock-portal{position:absolute;left:50%;top:50%;translate:-50% -50%;width:62px;height:62px;min-width:62px;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;font-size:10px;line-height:1;letter-spacing:.04em}\r\n#coachDock .dock-portal svg{width:22px;height:22px;flex:none}#coachDock .dock-portal span{max-width:100%}\r\n\r\n\r\n#coachDock .dock-live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}\r\n/* Menu content uses its natural line wrapping and an inner scroller instead of zoomed tabs that can clip on phones. */\r\n#portalMenu.portal-framed.portal-inset{box-sizing:border-box;min-width:0;min-height:0;overflow:auto!important;padding:10px!important;overscroll-behavior:contain}\r\n#portalMenu.portal-framed.portal-inset>:not(#coachDock):not(.portal-peer-ui){zoom:1!important;translate:none!important}\r\n#portalMenu .portal-menu-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:7px}\r\n#portalMenu .portal-menu-grid button{box-sizing:border-box;min-width:0;min-height:42px;padding:8px;font-size:clamp(12px,3.6vw,15px);overflow-wrap:anywhere}\r\n#portalMenu .portal-board-chips{max-width:100%;}\r\n#portalMenu .portal-board-chips button{padding:6px 9px}\r\n\r\n#mealsPanel.portal-shaped .pyramid-tag{display:none!important}\r\n\r\n\r\n#coachDock.coach-dock button>span{pointer-events:none}\r\n\r\n/* One recessed ship console follows every route. Existing buttons keep their IDs and handlers. */\r\n#coachDock.coach-dock.ship-control-deck{border-top:3px solid #b8a890;background:radial-gradient(circle at 12px 9px,#d4c3a9 0 2px,#292832 3px 5px,transparent 6px),radial-gradient(circle at calc(100% - 12px) 9px,#d4c3a9 0 2px,#292832 3px 5px,transparent 6px),repeating-linear-gradient(90deg,#ffffff08 0 1px,transparent 1px 5px),linear-gradient(180deg,#48545a,#252f38 38%,#171e27);box-shadow:inset 0 2px #e5d8bd72,inset 0 7px 8px #1117229c,0 -4px 18px #070b11a8}\r\n#coachDock.coach-dock.ship-control-deck:after{content:'';position:absolute;left:8px;right:8px;top:9px;height:1px;background:linear-gradient(90deg,transparent,#d5c9ad80 15%,#d5c9ad80 85%,transparent);pointer-events:none}\r\n#coachDock.coach-dock.ship-control-deck :is(button,a).dock-control{filter:none;overflow:visible}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span{position:relative;box-sizing:border-box;width:35px;height:35px;border:2px solid #c6b9a0;border-top-color:#f1e3c7;border-bottom-color:#665e56;border-radius:4px;clip-path:none;background:linear-gradient(145deg,#bcc8c2,#81918f 43%,#4b5c60);box-shadow:inset 0 1px #fff9,inset -2px -3px #22343b88,0 3px 0 #182127,0 5px 5px #000a;color:#243640}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span:after{content:'';position:absolute;right:2px;top:2px;width:4px;height:4px;border-radius:50%;background:#263d40;box-shadow:0 0 0 1px #e5e1cb77}\r\n#coachDock.coach-dock.ship-control-deck .dock-control[aria-current=page]>span:after{background:#ffd07c;box-shadow:0 0 6px #ffce78,0 0 0 1px #ffeed3}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span svg{width:21px;height:21px;filter:drop-shadow(0 1px #f2ffed77)}\r\n#coachDock.coach-dock.ship-control-deck .dock-control:active>span,#coachDock.coach-dock.ship-control-deck .dock-control[aria-current=page]>span{transform:translateY(3px);box-shadow:inset 1px 3px 4px #1e2d34ad,0 1px 0 #182127;color:#17282a}\r\n#coachDock.coach-dock.ship-control-deck .dock-control:focus-visible{outline:3px solid #ffe19a;outline-offset:2px}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings>span{border-radius:50%;background:radial-gradient(circle,#d6ddcf 0 24%,#8fa69e 25% 49%,#526d70 50% 67%,#b4bfb6 69%);box-shadow:inset 0 1px #fff9,0 3px #29363a,0 0 0 2px #132128}\r\n#coachDock.coach-dock.ship-control-deck .dock-scoreboard>span{border-radius:5px 5px 10px 10px;background:linear-gradient(90deg,#596b72 0 20%,#becac3 22% 72%,#596b72 75%);}\r\n#coachDock.coach-dock.ship-control-deck .dock-food>span{height:31px;border-radius:3px 3px 9px 9px;background:linear-gradient(#ffe0a9,#c69458 48%,#845837);color:#493322}\r\n#coachDock.coach-dock.ship-control-deck .dock-achievements>span{border-radius:3px;clip-path:polygon(0 0,100% 0,100% 71%,50% 100%,0 71%);background:linear-gradient(140deg,#ffe8ac,#b98b44 67%,#765223);color:#533e25}\r\n#coachDock.coach-dock.ship-control-deck .dock-pod>span{width:29px;border-radius:12px;background:linear-gradient(90deg,#496c70,#b8d1bd 35%,#6d9d92 65%,#35585d);color:#183b3c}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings:after,#coachDock.coach-dock.ship-control-deck .dock-scoreboard:after,#coachDock.coach-dock.ship-control-deck .dock-food:after,#coachDock.coach-dock.ship-control-deck .dock-achievements:after,#coachDock.coach-dock.ship-control-deck .dock-pod:after{position:absolute;top:calc(100% + 4px);left:50%;translate:-50% 0;color:#c5d5cb;font:700 7px/1 ui-monospace,Consolas,monospace;letter-spacing:.05em;white-space:nowrap;text-shadow:0 1px #071118;pointer-events:none}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings:after{content:'COACH'}#coachDock.coach-dock.ship-control-deck .dock-scoreboard:after{content:'SCORES'}#coachDock.coach-dock.ship-control-deck .dock-food:after{content:'FOOD'}#coachDock.coach-dock.ship-control-deck .dock-achievements:after{content:'BADGES'}#coachDock.coach-dock.ship-control-deck .dock-pod:after{content:'COMMS'}\r\n#coachDock.coach-dock.ship-control-deck :is(button,a).dock-portal{border:3px solid #9eb7b1;border-top-color:#e1eed6;border-bottom-color:#445b5b;border-radius:50%!important;background:radial-gradient(circle at 50% 40%,#1a4545 0 46%,#0b212a 47% 58%,transparent 59%),repeating-conic-gradient(#b6c6b3 0deg 8deg,#51666a 8deg 15deg);box-shadow:0 0 0 3px #17262b,0 4px 0 3px #0a141b,inset 0 0 11px #85f9ce7e,0 0 12px #85f9ce50;color:#d7ffe6;text-shadow:0 0 5px #71ebb0}\r\n#coachDock.coach-dock.ship-control-deck :is(button,a).dock-portal:before{display:none}\r\n#coachDock.coach-dock.ship-control-deck :is(button,a).dock-portal:active,#coachDock.coach-dock.ship-control-deck :is(button,a).dock-portal[aria-current=page]{transform:translateY(3px);box-shadow:0 0 0 3px #17262b,0 1px 0 3px #0a141b,inset 0 0 15px #a4ffe7,0 0 18px #88ffd2}\r\n#coachDock.coach-dock.ship-control-deck .dock-portal svg{width:20px;height:20px}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control{box-sizing:border-box;width:42px;height:43px;padding:15px 2px 2px;border:2px solid #afbbad;border-top-color:#e8e9d4;border-bottom-color:#566963;border-radius:4px!important;background:linear-gradient(145deg,#adbcb4,#526c6b 65%,#365154);box-shadow:inset 0 1px #fff9,inset 0 -2px #2a4747,0 3px #142324;color:#173f3a;font:700 8px ui-monospace,Consolas,monospace}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control:before{content:'';display:block;position:absolute;left:8px;top:5px;width:23px;height:8px;border:1px solid #172b2d;border-radius:2px;background:linear-gradient(90deg,#23383a 0 45%,#e4cfaa 48% 85%,#788c88 88%);box-shadow:inset 0 1px 2px #0008}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control[data-on=false]:before{background:linear-gradient(90deg,#e4cfaa 0 40%,#758c89 43%,#23383a 48%)}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control[data-on=true]{color:#f8e3ab;text-shadow:0 0 5px #ffe19a}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound .cb-label{color:#c5d5cb}\r\n/* The logo in the ship header is the single brand mark in a framed workout view. */\r\n.portal-frame>b{display:none}\r\n@media(orientation:landscape) and (max-height:500px){#coachDock.coach-dock.ship-control-deck .dock-control:after{display:none}}\r\n.portal-menu{background:#000a0f!important;border-color:#ffffff22!important;position:relative}\r\n.portal-menu::backdrop{background:#000a0fcc!important}\r\n.portal-menu header h2{color:#ff8800!important;font-family:monospace!important;text-shadow:0 0 4px #ff8800!important}\r\n.portal-menu,.portal-menu *{color:#ff8800!important;font-family:monospace!important}\r\n.portal-menu::before{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background-image:repeating-linear-gradient(#000 0 1.5px,transparent 1.5px 3px);opacity:.22;animation:crt-roll 9s linear infinite;pointer-events:none;z-index:1}\r\n.portal-menu::after{content:\"\";position:absolute;top:0;left:0;width:100%;height:100%;background:linear-gradient(180deg,#ffffff2e 0%,#ffffff12 12%,transparent 30%),radial-gradient(ellipse 60% 40% at 24% 10%,#ffffff26,transparent 55%),radial-gradient(ellipse 75% 70% at 50% 50%,transparent 42%,#000000b3 100%);pointer-events:none;z-index:2}\r\n@keyframes crt-roll{to{background-position-y:12px}}\r\n\r\n/* Keep seven physical controls on one rail before and after scene loading. */\r\n#coachDock.coach-dock.ship-control-deck{display:flex;justify-content:space-between;align-items:center;gap:3px}\r\n#coachDock.coach-dock.ship-control-deck .dock-control,#coachDock.coach-dock.ship-control-deck .dock-sound{flex:0 0 40px;min-width:0;width:40px}\r\n#coachDock.coach-dock.ship-control-deck .dock-portal{position:relative!important;left:auto!important;top:auto!important;translate:none!important;flex:0 0 56px;width:56px;min-width:56px}\r\n#coachDock.ship-control-deck .dock-settings{order:1}#coachDock.ship-control-deck .dock-food{order:2}#coachDock.ship-control-deck .dock-scoreboard{order:3}#coachDock.ship-control-deck .dock-portal{order:4}#coachDock.ship-control-deck .dock-achievements{order:5}#coachDock.ship-control-deck .dock-pod{order:6}#coachDock.ship-control-deck .dock-sound{order:7}\r\n#coachDock.ship-control-deck .dock-live{position:absolute}\r\n/* The hub uses the selected grimoire metal in every shared dock. */\r\n#coachDock.coach-dock.ship-control-deck :is(button,a).dock-portal{border-color:color-mix(in srgb,var(--portal-metal,#4d3d4f),#fff 40%);background:radial-gradient(circle at 50% 40%,var(--portal-metal,#4d3d4f) 0 46%,color-mix(in srgb,var(--portal-metal,#4d3d4f),#000 65%) 47% 58%,transparent 59%),repeating-conic-gradient(color-mix(in srgb,var(--portal-metal,#4d3d4f),#fff 40%) 0deg 8deg,color-mix(in srgb,var(--portal-metal,#4d3d4f),#000 30%) 8deg 15deg)}\r\n","modules/portal/portal.mjs":"import {portalWindow,lensPts,shapeOutlinePts} from './portal-apertures.mjs';\r\nimport {createTiltLook} from '../../character-phone-sensor.mjs';\r\nexport {portalWindow,lensPts} from './portal-apertures.mjs';\r\n// Portal home board: the quilt cloth board replaces the app home menu. Tracing one of the eight\r\n// stitched shapes cuts that shape out of the 3D board — the piece falls in, neon liquid glass glows\r\n// through the hole behind it for a short interactive loading phase — then opens the shape's menu.\r\n// AGPL-3.0-or-later.\r\nimport {createQuiltBoard2D,createQuiltBoardGL,QUILT} from './portal-board.mjs';\r\nimport {createGlbBoard,frameOf,GLB} from './portal-board-glb.mjs';\r\nimport {ice} from './portal-board-ice.mjs';\r\nimport {grass} from './portal-board-grass.mjs';\r\nimport {cogs} from './portal-board-cogs.mjs';\r\nimport {jelly} from './portal-board-jelly.mjs';\r\nimport {wood} from './portal-board-wood.mjs';\r\nimport {pond} from './portal-board-pond.mjs';\r\nimport {readLook,saveLook,applyLookVars,stripSeq,LOOK_DEFAULTS} from './portal-look.mjs';\r\nimport {recognizeShape,nearestShape,SHAPES} from './portal-shapes.mjs';\r\nimport {pointInPolygon} from './portal-cut.mjs';\r\nimport {eye} from './peer.mjs';\r\nimport {mountPodChrome} from '../pod-chrome.mjs';\r\nimport {paletteFor,paletteOptions} from './portal-tunnel-palettes.mjs';\r\nimport {releaseGraphics,waitForGraphicsRelease,graphicsBlocked} from '../graphics-lifecycle.mjs';\r\n\r\n// Portal sequence timings (ms): the cut piece falling in, the minimum live-glass loading phase, the\r\n// dive into the wormhole (the destination appears from its core), the healed board fading back in, one touch ripple on\r\n// the glass. tunnelFrom/To: wormhole speed (rings per second) at the cut, ramping up to tunnelTo by the dive, which adds\r\n// up to tunnelDive more. short (#124): the lines' and the X's wormhole runs the same cut, glass and dive at this share of\r\n// the closed shapes' cut/loading/dive timings.\r\nexport const PORTAL={cutMs:867,loadMinMs:2333,revealMs:733,healMs:267,rippleMs:600,tunnelFrom:.35,tunnelTo:1.5,tunnelDive:6,short:.58};\r\n// Liquid-glass slab over the wormhole (CSS px): lens-map texel, bevel depth, max refraction at the rim,\r\n// rim inset inside the cut (the cloth hole's edge is ragged by about half a grid cell). #125 (Ian: \"stronger\"): thicker\r\n// bevel and deeper bend; fringe: the red/blue sample spread at the rim (blue bends furthest); magnify: centre lens.\r\nconst GLASS={mapPx:3,bevel:42,bend:36,rimInset:8,fringe:.3,magnify:.035};\r\n// #104/#105 (W2-2E): the six neons already used for the \"all menus\" glass (portal.css .portal-glass.all),\r\n// reused for the flowing finger-trail ribbon. IDLE (Ian 26 Sept: \"just the slow one with 7 seconds of idle time\"): 7s of\r\n// no touch arms the cycle, 2.5s per shape in the order below with a gapMs of nothing between them, until the next touch.\r\n// TRAIL_FADE_MS: how long a trail segment (live or just-released) stays lit before it's fully faded.\r\nconst TRAIL_NEONS=['#ff5f1f','#b026ff','#ff10f0','#1f51ff','#39ff14','#ffff33'];\r\nconst TRAIL_NEON_RGB=TRAIL_NEONS.map(h=>[parseInt(h.slice(1,3),16),parseInt(h.slice(3,5),16),parseInt(h.slice(5,7),16)]);\r\nconst IDLE={armMs:7000,slowMs:2500,gapMs:600};\r\n// Ian 2026-09-23: square, oval, triangle, inverted triangle, diamond, X, then the four lines; cross last.\r\nconst IDLE_ORDER=['rect','oval','up','down','vdiamond','x','line-lr','line-rl','line-down'];\r\nconst TRAIL_FADE_MS=800;\r\n// #20 double-tap to open: a second tap within TAP_MS and TAP_MOVE_PX of the first counts as one double-tap;\r\n// TAP_HIT_PX is how close (client px) it must land to a shape's stitched outline. #21 \"almost\": a failed\r\n// trace whose closest candidate (nearestShape) still covers at least ALMOST_COVER of both trace and template\r\n// gets the near-miss flash instead of silence; ALMOST_MS is how long that flash (with its label) stays up.\r\n// #22 first-run hint: HINT_MS is one lap of the glowing fingertip around the square.\r\n// ALMOST_COVER sits well above the ~0.55-0.60 a wrong-shape trace (a circle, an L, a stray diagonal) scores\r\n// against its closest candidate, and below the ~0.65-0.78 a genuine partial trace of the right shape (most\r\n// of a rect with the last side never closed) scores — calibrated against portal-shapes.test.mjs's near-miss\r\n// fixtures so a scribble never earns an \"Almost\".\r\nconst TAP_MS=350,TAP_MOVE_PX=32,TAP_HIT_PX=14,ALMOST_COVER=.65,ALMOST_MS=1200,HINT_MS=2600,HINT_KEY='myr5.portalHintShown';\r\n// Only the shapes that actually cut/glass/dive through portalSequence's default branch (SHAPES entries\r\n// that are single closed-area strokes, i.e. not 'x'/'cross'/'line') are tap targets — matches #20's \"same\r\n// cut, glass and dive\" as tracing.\r\nconst TAPPABLE_IDS=Object.keys(SHAPES).filter(id=>!['x','cross','line'].includes(id));\r\n\r\n// Board catalogue: add one line per wave-2 board here. Each board is two layers: `flat`, a still picture on a 2D canvas\r\n// (portal-board.mjs createQuiltBoard2D) that is always mounted and never needs WebGL, and `create`, the 3D board drawn over\r\n// it once it has rendered. A grimoire's flat picture is its poster, laid out at its GLB face's width/height (FACE, measured)\r\n// with its guides drawn in its shape frame. WAIT (ms): how long a poster, then a 3D board, may take before it counts as failed,\r\n// and how long the first mount waits for 3D before the portal comes up flat (3D then takes over when it has drawn).\r\nexport const PRODUCTION_PORTALS=Object.freeze(['quilt','ice','grass','jelly','wood','pond']);\r\nconst FACE={ice:.5903,grass:.5625,cogs:.5715,jelly:.5892,wood:.5847,pond:.5625},WAIT={poster:6000,threeD:20000,mount:4000};\r\n// trace (R7): the flat poster keeps the board's own touch effect in 2D (ice cracks, flowers, weld, jelly gash, embers).\r\nconst grimoire=(label,effect)=>({label,flat:async host=>{const flat=await createQuiltBoard2D(host,{src:`/pod/worlds/boards/${effect.id}-poster.webp`,ratio:FACE[effect.id],frame:frameOf(effect,GLB),background:effect.background,guide:effect.guide,waitMs:WAIT.poster,trace:effect.trace2d,tint:effect.keepColors?null:boardTint(effect.id),tintSelected:hasBoardTint(effect.id),tintTarget:effect.id==='grass'||effect.keepColors?'trace':effect.id==='cogs'?'cogs':'poster',...(effect.id==='cogs'?{backplateTint:cogsBackplateTint(),backplateTintSelected:hasCogsBackplateTint()}: {})});if(effect.id==='cogs')flat.setBackplateTint?.(cogsBackplateTint(),hasCogsBackplateTint());return flat;},create:host=>{if(effect.id==='cogs')effect.setBackplateTint?.(cogsBackplateTint(),hasCogsBackplateTint());return createGlbBoard(host,{effect});}});\r\nconst BOARDS={quilt:{label:'Quilt',flat:host=>createQuiltBoard2D(host),create:host=>createQuiltBoardGL(host)},ice:grimoire('Crystal',ice),grass:grimoire('Grass',grass),cogs:grimoire('Cogs',cogs),jelly:grimoire('Jelly',jelly),wood:grimoire('Wood',wood),pond:grimoire('Pond',pond)};\r\n// Test-only stub board — never in PRODUCTION_PORTALS, so it's invisible to real users — letting tests drive\r\n// a non-quilt boardId (via ?board=__stub__) without a second real board existing yet. Set before this module\r\n// is imported (window.__portalTrailProbe above is the same pattern). Its create() only touches `host` at\r\n// call time, never `document` at module-eval time, so importing this module without a DOM still works.\r\nif(typeof window!=='undefined'&&window.__portalTestStubBoard===true)\r\n BOARDS.__stub__={label:'Stub',flat:host=>Promise.resolve({\r\n  background:'#000',\r\n  faceRect:()=>({left:0,top:0,width:host.clientWidth||1,height:host.clientHeight||1}),\r\n  patternRect:()=>({left:0,top:0,width:host.clientWidth||1,height:host.clientHeight||1}),\r\n  cut:()=>Promise.resolve(),heal(){},press(){},release(){},claims:id=>!!window.__portalTestClaims?.(id),pause(){},resume(){},dispose(){},\r\n })};\r\nconst BOARD_KEY='myr5.portalBoard';\r\nconst portalSound=(kind,extra={})=>window.dispatchEvent(new CustomEvent('myr5:portal-sound',{detail:{kind,board:boardId,...extra}}));\r\nconst tintKey=id=>'myr5.grimoireColor.'+id;\r\nconst validHex=value=>/^#[0-9a-f]{6}$/i.test(value||'');\r\nconst boardTint=(id=boardId)=>validHex(store.get(tintKey(id)))?store.get(tintKey(id)):(id==='cogs'?'#c59a56':'#b026ff');\r\nconst hasBoardTint=(id=boardId)=>/^#[0-9a-f]{6}$/i.test(store.get(tintKey(id))||'');\r\nconst COGS_BACKPLATE_KEY='myr5.grimoireBackplateColor.cogs';\r\nconst cogsBackplateTint=()=>validHex(store.get(COGS_BACKPLATE_KEY))?store.get(COGS_BACKPLATE_KEY):'#263943';\r\nconst hasCogsBackplateTint=()=>validHex(store.get(COGS_BACKPLATE_KEY));\r\nconst boardTintLabel=()=>boardId==='grass'?'Flower colour':boardId==='cogs'?'Mechanism colour':boardId==='pond'?'Lily colour':'Grimoire colour';\r\nconst paletteKey=id=>'myr5.wormholePalette.'+id;\r\nconst materialLoads=new Map();\r\n// Sandboxed frames and private-mode Safari throw on localStorage access; never let that kill mountPortal.\r\nconst store={get(k){try{return localStorage.getItem(k)}catch{return null}},set(k,v){try{localStorage.setItem(k,v)}catch{}}};\r\nfunction initialBoardId(){\r\n const p=new URLSearchParams(location.search).get('board');if(p&&PRODUCTION_PORTALS.includes(p))return p;\r\n const stored=store.get(BOARD_KEY);if(stored&&PRODUCTION_PORTALS.includes(stored))return stored;\r\n return 'quilt';\r\n}\r\n\r\n// placeholder until Ian's Tripo models arrive — simple inline-SVG icons on a glowing disc (the X/cross \"all menus\" fall-in)\r\nconst ICONS={\r\n dumbbell:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"3\" stroke-linecap=\"round\"><rect x=\"6\" y=\"18\" width=\"8\" height=\"12\" rx=\"2\"/><rect x=\"34\" y=\"18\" width=\"8\" height=\"12\" rx=\"2\"/><path d=\"M14 24h20\"/></svg>',\r\n lotus:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M24 40c-10-4-14-12-14-18 6 2 11 6 14 12 3-6 8-10 14-12 0 6-4 14-14 18z\"/><path d=\"M24 40c-5-8-5-16 0-24 5 8 5 16 0 24z\"/></svg>',\r\n brush:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"14\" cy=\"12\" r=\"6\"/><path d=\"M30 8l10 10-14 14-10-4 4-10z\"/><path d=\"M16 28l-6 12 12-6\"/></svg>',\r\n bowl:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M8 22a16 8 0 0 0 32 0z\"/><path d=\"M8 22h32\"/><path d=\"M20 8c0 3-2 3-2 6M28 8c0 3 2 3 2 6\"/></svg>',\r\n trophy:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><path d=\"M16 8h16v10a8 8 0 0 1-16 0z\"/><path d=\"M16 10H8v4a8 8 0 0 0 8 8M32 10h8v4a8 8 0 0 1-8 8\"/><path d=\"M24 26v8M17 40h14M20 34h8v6h-8z\"/></svg>',\r\n rocket:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M24 4c7 6 9 15 6 26H18C15 19 17 10 24 4z\"/><circle cx=\"24\" cy=\"17\" r=\"3.5\"/><path d=\"M18 30l-6 6 7 1M30 30l6 6-7 1M21 38l3 6 3-6\"/></svg>',\r\n joystick:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\"><circle cx=\"24\" cy=\"14\" r=\"6\"/><path d=\"M24 20v10\"/><rect x=\"10\" y=\"30\" width=\"28\" height=\"10\" rx=\"3\"/></svg>',\r\n star:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linejoin=\"round\"><path d=\"M24 6l5.2 11.4L41 19l-9 8.3 2.4 12.2L24 33.4 13.6 39.5 16 27.3 7 19l11.8-1.6z\"/></svg>',\r\n bell:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M24 6c-6 0-9 5-9 12v6l-4 8h26l-4-8v-6c0-7-3-12-9-12z\"/><path d=\"M19 38a5 5 0 0 0 10 0\"/></svg>',\r\n gear:'<svg viewBox=\"0 0 48 48\" width=\"34\" height=\"34\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"24\" cy=\"24\" r=\"7\"/><path d=\"M24 4v6M24 38v6M44 24h-6M10 24H4M37.6 10.4l-4.2 4.2M14.6 33.4l-4.2 4.2M37.6 37.6l-4.2-4.2M14.6 14.6l-4.2-4.2\"/></svg>',\r\n};\r\n\r\n// Shape -> menu. Ian's gesture map (2026-09-22): rect/oval are camera/nav-free (\"home\") destinations —\r\n// hide the portal, then trigger the pod's own control; up/down/diamonds/lines/x open a dialog or navigate.\r\n// Neon colours: Ian picked the six most popular neons (2026-09-22) — orange, purple, pink, green, yellow,\r\n// electric blue — reused freely across destinations; #ff4fa0 is the dedicated Achievements pink.\r\n// `hidden:true` keeps an id routable (gesture lookup, MENUS[id]) without adding a duplicate row to the\r\n// Menu sheet grid — used for the second diamond (same destination as the first) and line-up (opens the\r\n// sheet itself, so it can't also be a row in it).\r\n// W2-2A: each destination opens through the app's router (modules/routes.mjs, window.myr5Routes): it sets the\r\n// route's #hash, lights the bottom bar and hands back the dialog for the dive and fade-back. A page without the\r\n// router (a bare portal page) keeps the direct opener.\r\nconst via=(route,direct)=>()=>window.myr5Routes?window.myr5Routes.go(route,{portal:true}):direct();\r\nconst LEADERBOARD={label:'Leaderboard',route:'scoreboard',color:'#ffff33',icon:ICONS.trophy,kind:'dialog',open:via('scoreboard',()=>{document.querySelector('.coach-dock [data-panel=\"account\"]')?.click();return document.getElementById('accountPanel');})};\r\n// Exported so tests can check the gesture -> destination table without a DOM.\r\nexport const MENUS={\r\n // Ian 2026-09-23: the square opens the workout start page (the pod scrolled to its viewing port, control board and\r\n // BEGIN; no auto-start); the oval is the coach's arrival in the ship view, its entrance played every time.\r\n rect:{label:'Workout',route:'workout',color:'#ff5f1f',icon:ICONS.dumbbell,kind:'dialog',open:via('workout',()=>openWorkoutHome())},\r\n oval:{label:'Choose Workout',route:'select',color:'#1f51ff',icon:ICONS.dumbbell,kind:'dialog',open:via('select',()=>window.myr5Menus?.ship?.({entrance:'always',hash:'#select'}))},\r\n up:{label:'Food',route:'food',color:'#39ff14',icon:ICONS.bowl,kind:'dialog',open:via('food',()=>{document.querySelector('.coach-dock [data-panel=\"meals\"]')?.click();return document.getElementById('mealsPanel');})},\r\n down:{label:'Achievements',route:'achievements',color:'#ff4fa0',icon:ICONS.star,kind:'dialog',open:via('achievements',()=>window.myr5Menus?.achievements?.())},\r\n vdiamond:LEADERBOARD,\r\n hdiamond:{label:'Spotify DJ',route:'spotify',color:'#ff982f',icon:ICONS.joystick,kind:'dialog',open:via('spotify',()=>window.myr5Menus?.spotify?.())},\r\n x:{label:'War Room',route:'war-room',color:'#ff10f0',icon:ICONS.joystick,kind:'nav',open:via('war-room',()=>location.assign('/war-room/index.html'))},\r\n 'line-lr':{label:'Meditation',route:'meditate',color:'#b026ff',icon:ICONS.lotus,kind:'dialog',open:via('meditate',()=>{document.querySelector('.meditation-entry')?.click();return document.querySelector('.meditation-panel');})},\r\n 'line-rl':{label:'Reminders',route:'reminders',color:'#ff10f0',icon:ICONS.bell,kind:'dialog',open:via('reminders',()=>{document.querySelector('.coach-dock [data-panel=\"reminders\"]')?.click();return document.getElementById('remindersPanel');})},\r\n 'line-down':{label:'Settings',route:'settings',color:'#39ff14',icon:ICONS.gear,kind:'dialog',open:via('settings',()=>{document.getElementById('openSettings')?.click();return document.getElementById('settings');})},\r\n // Line-up opens the Menu sheet; it is hidden from the sheet grid itself.\r\n // Full-screen ship view (Ian 2026-09-22: the coach capsule view, full screen, with the ship and pixel planet). Menu sheet only.\r\n // War Room/Arcade has no gesture: Menu sheet only, same lock as before.\r\n};\r\n\r\n// The locked intake theme disables transitions with !important; inline !important keeps the portal moving.\r\nconst motion=(el,value)=>value?el.style.setProperty('transition',prefersReducedMotion()?'none':value,'important'):el.style.removeProperty('transition');\r\nconst prefersReducedMotion=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n// #29: a short buzz on a recognised match (trace or tap), a double pulse on an \"almost\" near-miss. iOS\r\n// ignores navigator.vibrate; never vibrate under reduced motion.\r\nconst buzz=pattern=>{if(!prefersReducedMotion())navigator.vibrate?.(pattern);};\r\nconst raf=()=>new Promise(r=>requestAnimationFrame(r));\r\nconst sleep=ms=>new Promise(r=>setTimeout(r,ms));\r\n// Lets a just-opened dialog's layout settle before we measure it. Races two frames against a plain\r\n// timeout so a backgrounded tab (rAF paused) can't stall the whole reveal indefinitely.\r\nconst settle=()=>Promise.race([raf().then(raf),new Promise(r=>setTimeout(r,50))]);\r\nconst toClientPts=(pts,rect)=>pts.map(([x,y])=>[rect.left+x*rect.width,rect.top+y*rect.height]);\r\nconst closeLoop=pts=>{const a=pts[0],b=pts.at(-1);return(a[0]===b[0]&&a[1]===b[1])?pts:[...pts,a];};\r\nconst rectBox=el=>{const r=el.getBoundingClientRect();return{width:r.width,height:r.height};};\r\nfunction centroidOf(closedPts){const n=closedPts.length-1;let sx=0,sy=0;for(let i=0;i<n;i++){sx+=closedPts[i][0];sy+=closedPts[i][1];}return[sx/n,sy/n];}\r\nconst shapeClipPts=(id,rect)=>closeLoop(toClientPts(shapeOutlinePts(id),rect));\r\n// R21 L2: the opened window sits AURA.inset px inside the board face on every side, so the rim and its glow leave a strip of board\r\n// round them instead of touching the metal rail. Scales per axis about the box centre; the rect (the whole face) is left alone.\r\nfunction insetPts(pts,id){\r\n if(id==='rect'||!AURA.inset)return pts;\r\n const xs=pts.map(p=>p[0]),ys=pts.map(p=>p[1]),x0=Math.min(...xs),x1=Math.max(...xs),y0=Math.min(...ys),y1=Math.max(...ys),\r\n  kx=Math.max(.5,1-2*AURA.inset/(x1-x0||1)),ky=Math.max(.5,1-2*AURA.inset/(y1-y0||1)),cx=(x0+x1)/2,cy=(y0+y1)/2;\r\n return pts.map(([x,y])=>[cx+(x-cx)*kx,cy+(y-cy)*ky]);\r\n}\r\n// The glass clip bleeds GLASS_BLEED px past the shape (clamped to the board face): triangles are cut by centroid, so the\r\n// hole's edge is jagged and would otherwise show bare background in the notches beyond the exact outline.\r\nconst GLASS_BLEED=18;\r\nfunction bleedPts(pts,d=GLASS_BLEED){\r\n const c=centroidOf(pts),f=board?.faceRect(),clamp=(v,lo,len)=>f?Math.min(Math.max(v,lo),lo+len):v;\r\n return pts.map(([x,y])=>{const k=1+d/(Math.hypot(x-c[0],y-c[1])||1);return [clamp(c[0]+(x-c[0])*k,f?.left,f?.width),clamp(c[1]+(y-c[1])*k,f?.top,f?.height)];});\r\n}\r\n\r\n// Scales the shape polygon about its own centroid before cutting the hole; ponytail: a large fixed\r\n// multiplier rather than measuring the exact box coverage needed — plenty for a phone/tablet screen,\r\n// revisit with a measured scale if a very large display ever hosts this board.\r\nconst GROW=40;\r\nfunction buildHoleClip(pts,box,scale){\r\n const c=centroidOf(pts),scaled=scale===1?pts:pts.map(([x,y])=>[c[0]+(x-c[0])*scale,c[1]+(y-c[1])*scale]);\r\n const outer=[[0,0],[box.width,0],[box.width,box.height],[0,box.height],[0,0]];\r\n return `polygon(evenodd, ${[...outer,...scaled,[0,0]].map(([x,y])=>`${x}px ${y}px`).join(',')})`;\r\n}\r\n// Home destinations (the app under the portal) open from the tunnel's core during the dive: a shape-shaped hole grows\r\n// from the vanishing point to 1.15x the shape, which covers everything the dive leaves on screen.\r\nfunction growHole(el,pts,box,current=()=>true,ms=PORTAL.revealMs){\r\n return new Promise(resolve=>{\r\n  motion(el,'none');el.style.clipPath=buildHoleClip(pts,box,.02);\r\n  if(prefersReducedMotion()){el.style.clipPath=buildHoleClip(pts,box,GROW);resolve();return;}\r\n  settle().then(()=>{\r\n   if(!current()){resolve();return;}\r\n   motion(el,`clip-path ${ms}ms cubic-bezier(.4,0,.7,1)`);\r\n   el.style.clipPath=buildHoleClip(pts,box,1.15);\r\n   setTimeout(resolve,ms);\r\n  });\r\n });\r\n}\r\n\r\nlet portalHome,boardHost,overlay,ctx,objectsLayer,statusEl,menuBtn,menuSheet,boardBtn,settingsBtn,overlayObserver,lifecycle,chrome,workoutHome,workoutSlots=[];\r\nlet wantedBoard=null,sequence=0,visibilityRun=0,boardLoad=0,menuChosen=false,focusBefore=null;\r\nconst backgroundInert=new Map(),flashes=new Set();\r\n// board: what the portal cuts and measures: the 3D layer (gl3) once it has drawn, else the flat layer (base) under it.\r\nlet board=null,base=null,gl3=null,boardShown=false,boardId='quilt';\r\n// Per board, this session (never one global flag): '3d' drawing, 'lost' (its context dropped once: one more try), 'flat' (3D\r\n// failed: the flat board stays until the board is picked again or the app restarts). pending3D: 3D builds still out.\r\nconst art={},losses={},pending3D=new Set();let ready3D=Promise.resolve();\r\nlet pointers=new Map(),pendingStrokes=[],pendingTrailPts=[],finalizeTimer=0,outlineFlash=null,rafId=0;\r\n// busy: a portal sequence is running (traces ignored, touches ripple the glass); phase: the live glass {glass,pts,color,t0,pulse}.\r\nlet busy=false,phase=null;\r\n// #104: idleTimer arms after IDLE.armMs of eligibility (board shown, nothing busy, no touch, no dialog,\r\n// tab visible); idleCycle is the running cycle ({t0}) or {static:true} under reduced\r\n// motion. #105: fading holds just-released strokes still fading out, drawn alongside any live ones.\r\nlet idleTimer=0,idleCycle=null,fading=[];\r\n// #22 first-run hint: {t0} while the glowing-fingertip demo plays, else null. idleEligible() also checks\r\n// this (below) so the idle ambient flash never runs underneath it.\r\nlet hint=null,lastTap=null;\r\n\r\nfunction menuButtonsHtml(){return Object.entries(MENUS).filter(([,m])=>!m.hidden).map(([id,m])=>`<button type=\"button\" data-menu=\"${id}\"><i aria-hidden=\"true\" style=\"--dot:${m.color}\"></i>${m.label}</button>`).join('');}\r\nfunction boardChipsHtml(){return Object.entries(BOARDS).filter(([id])=>PRODUCTION_PORTALS.includes(id)).map(([id,b])=>`<button type=\"button\" data-board=\"${id}\" aria-pressed=\"${id===boardId}\">${b.label}</button>`).join('');}\r\nconst htmlSafe=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));\r\nfunction paletteSelectHtml(id=boardId){\r\n if(id==='quilt')return '';\r\n const rows=paletteOptions(id),selected=paletteFor(id,store.get(paletteKey(id)))?.id;\r\n if(!rows.length)return '';\r\n return `<label class=\"portal-palette\">Wormhole palette <select aria-label=\"Wormhole palette\" data-palette>${rows.map(p=>`<option value=\"${htmlSafe(p.id)}\"${p.id===selected?' selected':''}>${htmlSafe(p.label)}</option>`).join('')}</select></label>`;\r\n}\r\nfunction lookControlsHtml(){\r\n const look=readLook();\r\n return `<fieldset class=\"portal-look-controls\"><legend>Portal appearance</legend><div>${[['portal','Metal'],['strip','Strip']].map(([key,label])=>`<label>${label}<input type=\"color\" data-look=\"${key}\" aria-label=\"${label}\" value=\"${look[key]}\"></label>`).join('')}</div><button type=\"button\" data-look-reset>Reset portal appearance</button></fieldset>`;\r\n}\r\nfunction boardTintControlsHtml(){\r\n const mechanism=`<label class=\"portal-color\">${boardTintLabel()} <input type=\"color\" aria-label=\"${boardTintLabel()}\" data-board-tint value=\"${boardTint()}\"></label>`;\r\n return `${mechanism}${boardId==='cogs'?`<label class=\"portal-color\">Back wall colour <input type=\"color\" aria-label=\"Back wall colour\" data-backplate-tint value=\"${cogsBackplateTint()}\"></label>`:''}`;\r\n}\r\nfunction updateBoardChips(){\r\n const tint=menuSheet?.querySelector('[data-board-tint]'),label=tint?.closest('.portal-color');\r\n if(tint){tint.value=boardTint();tint.setAttribute('aria-label',boardTintLabel());if(label?.firstChild?.nodeType===Node.TEXT_NODE)label.firstChild.textContent=boardTintLabel()+' ';}\r\n const backplate=menuSheet?.querySelector('[data-backplate-tint]')?.closest('.portal-color');\r\n if(boardId==='cogs'&&!backplate)label?.insertAdjacentHTML('afterend',boardTintControlsHtml().slice(boardTintControlsHtml().indexOf('<label',1)));\r\n else if(boardId!=='cogs')backplate?.remove();\r\n const backplateInput=menuSheet?.querySelector('[data-backplate-tint]');if(backplateInput)backplateInput.value=cogsBackplateTint();\r\n menuSheet?.querySelectorAll('[data-board]').forEach(btn=>btn.setAttribute('aria-pressed',String(btn.dataset.board===boardId)));\r\n const row=menuSheet?.querySelector('[data-palette-row]');if(row)row.innerHTML=paletteSelectHtml();\r\n}\r\nexport function setCogsBackplateTint(hex,selected=true){\r\n if(!validHex(hex))return false;\r\n if(selected)store.set(COGS_BACKPLATE_KEY,hex);else {try{localStorage.removeItem(COGS_BACKPLATE_KEY);}catch{}}\r\n if(base&&boardId==='cogs')base.setBackplateTint?.(hex,selected);\r\n if(gl3&&boardId==='cogs')gl3.setBackplateTint?.(hex,selected);\r\n return true;\r\n}\r\n// Swaps the mounted board. The flat layer goes up first: a poster that doesn't arrive keeps the board already showing (the\r\n// last good one), else the Quilt, whose own art is drawn in code when it must be, so there is always a board. Then 3D is\r\n// laid over it while the portal is on screen (threeD). Pointer listeners read the `board` variable at call time.\r\n// Loads run one at a time: effects (jelly's module state) are singletons, so the old 3D board is disposed before the next\r\n// one's build can start. A load superseded while queued does nothing.\r\nlet loadQueue=Promise.resolve();\r\nfunction loadBoard(id){\r\n if(!PRODUCTION_PORTALS.includes(id)&&id!=='__stub__')id='quilt';\r\n wantedBoard=id;delete art[id];losses[id]=0; // a pick (or a cold start) gives its 3D another go\r\n const load=++boardLoad,run=loadQueue.then(()=>load===boardLoad?loadBoardNow(id,load):null);\r\n loadQueue=run.catch(()=>{});return run;\r\n}\r\nfunction disposeBoard(value){\r\n if(!value)return Promise.resolve();\r\n const gl=value.glContext||null;\r\n if(!gl){try{value.dispose();}catch{}return Promise.resolve();}\r\n return releaseGraphics(value.canvas,gl,()=>value.dispose());\r\n}\r\nasync function loadBoardNow(id,load){\r\n const label=BOARDS[id].label;\r\n status(`Loading ${label} board…`);\r\n let next,failureMessage='';\r\n try{next=await BOARDS[id].flat(boardHost);}\r\n catch(error){\r\n  console.warn(`${label} board art is unavailable.`,error);\r\n  if(load!==boardLoad)return null;\r\n  if(base){status(`${label} board art is unavailable. ${BOARDS[boardId].label} stays; try again later or check Downloads.`);updateBoardChips();return base;}\r\n  failureMessage=`${label} board art is unavailable. Quilt is ready; try again later or check Downloads.`;\r\n  id='quilt';next=await BOARDS.quilt.flat(boardHost);\r\n }\r\n if(load!==boardLoad){next.dispose();return null;}\r\n clearTimeout(finalizeTimer);pendingStrokes=[];\r\n pointers.forEach((_,pid)=>board?.release(pid));pointers.clear();\r\n const old=[gl3,base];gl3=null;base=board=next;lastTap=null;for(const b of old)void disposeBoard(b);\r\n if(!boardShown)base.pause();\r\n portalHome.style.background=base.background||''; // the canvases are transparent; the board colour lives here, behind the glass\r\n portalHome.dataset.board=boardId=id;portalHome.dataset.art='flat';\r\n portalSound('board');\r\n store.set(BOARD_KEY,id); // the saved choice is the board on screen: a failed pick keeps the last good one, a failed start the Quilt\r\n status(failureMessage);updateBoardChips();\r\n threeD();\r\n return base;\r\n}\r\n// 3D over the flat board: while the portal is on screen (or about to be: mount), one build per board at a time. It takes over\r\n// only once it has drawn on a live context and no cut is open; a throw, a timeout or a lost context leaves the flat board (fell).\r\nfunction threeD(mounting=false){\r\n const id=boardId,make=BOARDS[id].create,generation=boardLoad;\r\n if(!make||gl3||!(boardShown||mounting)||pending3D.has(id)||art[id]==='flat'||lifecycle.signal.aborted||graphicsBlocked('portal'))return ready3D; // the Vault holds the GPU; graphics-free rebuilds\r\n pending3D.add(id);portalHome.dataset.building=''; // portal.css keeps a hidden portal laid out meanwhile: effects measure the host as they build\r\n return ready3D=(async()=>{\r\n  await waitForGraphicsRelease();\r\n  if(generation!==boardLoad||id!==boardId||lifecycle.signal.aborted||gl3||(!boardShown&&!mounting)||graphicsBlocked('portal'))return;\r\n  const build=make(boardHost);build.catch(()=>{});\r\n  let created;\r\n  try{created=await Promise.race([build,sleep(WAIT.threeD).then(()=>{throw new Error(`3D took over ${WAIT.threeD} ms`);})]);}\r\n  catch(error){build.then(late=>{void disposeBoard(late);},()=>{});if(generation!==boardLoad||id!==boardId||lifecycle.signal.aborted)return;return fell(id,error);} // stale builds cannot overwrite a newer board; late ones are released at once\r\n  created.canvas.style.opacity='0'; // drawn but out of sight until it takes over (opacity, not visibility: its frame still reaches the screen)\r\n  while((busy||phase)&&id===boardId&&!lifecycle.signal.aborted)await sleep(250); // ponytail: polls; a sequence ends within seconds\r\n  if(id!==boardId||generation!==boardLoad||gl3||lifecycle.signal.aborted||(!boardShown&&!mounting)){await disposeBoard(created);return;}\r\n  if(created.canvas.getContext('webgl2')?.isContextLost()!==false){await disposeBoard(created);return fell(id,new Error('WebGL context lost before its first frame'));}\r\n  if(id!=='quilt')created.setTint?.(boardTint(id),hasBoardTint(id));\r\n  if(id==='cogs')created.setBackplateTint?.(cogsBackplateTint(),hasCogsBackplateTint());\r\n  gl3=board=created;created.canvas.style.opacity='';if(base.canvas)base.canvas.style.visibility='hidden';\r\n  if(boardShown)created.resume();else created.pause(); // resume draws a fresh frame now it's in sight\r\n  art[id]='3d';portalHome.dataset.art='3d';\r\n })().finally(()=>{pending3D.delete(id);if(!pending3D.size)delete portalHome.dataset.building;});\r\n}\r\nfunction fell(id,error){\r\n console.warn(`${BOARDS[id].label} 3D is unavailable; its flat board stays.`,error);\r\n art[id]='flat';\r\n if(id===boardId&&id!=='quilt'&&!lifecycle.signal.aborted)status(`${BOARDS[id].label} is showing its flat art: its 3D didn't load.`,{label:'Retry 3D',run:()=>loadBoard(id)}); // the flat quilt is its own art\r\n}\r\n// Android drops live WebGL contexts under memory pressure: the flat board takes over at once and 3D gets one more try a\r\n// moment later; a second loss this session leaves the board flat.\r\nfunction lost3D(){\r\n const id=boardId,dead=gl3;gl3=null;board=base;\r\n if(base.canvas)base.canvas.style.visibility='';base.resume();portalHome.dataset.art='flat';void disposeBoard(dead);\r\n if((losses[id]=(losses[id]||0)+1)>1)return fell(id,new Error('WebGL context lost again'));\r\n art[id]='lost';setTimeout(()=>threeD(),1000);\r\n}\r\n\r\n// #111 metal frame (portal.css .portal-frame): the energy channel, bolts at the four corners and two down each long side,\r\n// the nameplate. One copy sits on the board; #portalChrome holds another that stays around an open destination.\r\nconst FRAME_BOLTS=[[0,0],[1,0],[0,1],[1,1],[0,.33],[0,.67],[1,.33],[1,.67]];\r\nconst frameHtml=()=>`<div class=\"portal-frame\" aria-hidden=\"true\"><span class=\"portal-energy\">${'<span><span></span></span>'.repeat(4)}</span>${FRAME_BOLTS.map(([x,y])=>`<i style=\"--x:${x};--y:${y}\"></i>`).join('')}<b>MOM INC</b></div>`;\r\n// Energy around the frame (Ian 23 Sept): the neons flow clockwise along a channel in the rail, one clipped channel per\r\n// side, each a neon stripe (ENERGY.px per colour cycle) sliding by transform: compositor-only, no repaint per frame.\r\n// Gentle at rest; the selected Strip sequence remains constant as the channel brightens and speeds up.\r\n// Reduced motion: static. Both frame copies share timing and rate, so handing over to the chrome is seamless; the\r\n// loops pause while neither copy is on screen.\r\nconst ENERGY={px:360,loopMs:9000,surge:4,dive:10};\r\nconst ENERGY_MOVES=[['X',1],['Y',1],['X',-1],['Y',-1]]; // top →, right ↓, bottom ←, left ↑\r\nconst energyAnims=[];\r\nfunction energize(seq,rate=1,hot=false){\r\n const seg=seq&&ENERGY.px/seq.length,stops=seq?.map((c,i)=>`${c} ${i*seg}px ${(i+1)*seg}px`).join(',');\r\n for(const el of document.querySelectorAll('.portal-energy')){if(seq)el.style.setProperty('--energy',stops);el.classList.toggle('hot',hot);}\r\n energyAnims.forEach(a=>a.updatePlaybackRate(rate));\r\n}\r\nfunction syncEnergy(){const on=boardShown||!!framed;energyAnims.forEach(a=>on?a.play():a.pause());}\r\n// War Room look (device-local, guests too): metal colours ride CSS variables, the strip colour feeds energize(). Reapplied on\r\n// load, return to the portal and cross-tab/bfcache changes; a board pick made elsewhere loads once (an uncached one falls back).\r\nconst restSeq=()=>stripSeq(readLook().strip);\r\n function applyLook(){const look=readLook();applyLookVars(document.documentElement,look);document.documentElement.style.setProperty('--portal-strip-glow',`${look.strip}40`);menuSheet?.querySelectorAll('[data-look]').forEach(input=>{input.value=look[input.dataset.look];});if(aura?.el){const seq=stripSeq(look.strip);aura.el.style.setProperty('--aura',look.strip);aura.el.style.setProperty('--aura-edge',`color-mix(in srgb,${look.strip} 45%,#fff)`);aura.el.style.setProperty('--aura-seq',[...seq,seq[0]].join(','));}if(!phase)energize(restSeq());}\r\nfunction syncLook(){applyLook();const stored=store.get(BOARD_KEY);if(stored&&PRODUCTION_PORTALS.includes(stored)&&stored!==wantedBoard&&!busy)loadBoard(stored).catch(()=>{});}\r\nfunction buildDom(){\r\n portalHome=document.createElement('div');portalHome.id='portalHome';\r\n portalHome.hidden=true;portalHome.setAttribute('role','dialog');portalHome.setAttribute('aria-label','Quilt portal');portalHome.setAttribute('aria-modal','true');\r\n portalHome.innerHTML=`\r\n  <div id=\"portalShadows\" aria-hidden=\"true\"><i></i><i></i><i></i></div>\r\n  <div id=\"portalBoardHost\">${frameHtml()}</div>\r\n  <canvas id=\"portalOverlay\" aria-hidden=\"true\"></canvas>\r\n  <div id=\"portalObjects\" aria-hidden=\"true\"></div>\r\n  <p id=\"portalStatus\" role=\"status\"></p>\r\n  <button id=\"portalRetry\" type=\"button\" hidden></button>\r\n  <button id=\"portalSettingsButton\" type=\"button\" aria-label=\"Grimoire settings\">GRIMOIRE</button>\r\n  <button id=\"portalExitButton\" type=\"button\">Pod</button>`;\r\n document.body.append(portalHome);\r\n chrome=document.createElement('div');chrome.id='portalChrome';chrome.setAttribute('popover','manual');chrome.setAttribute('aria-hidden','true');chrome.innerHTML=frameHtml();document.body.append(chrome);\r\n if(!chrome.showPopover)chrome.remove(); // no Popover API (iOS Safari 16-): no UA hidden state, so it would sit over every screen; frameOn() skips framing\r\n applyLookVars();energize(restSeq());\r\n for(const el of document.querySelectorAll('.portal-energy')){\r\n  el.style.setProperty('--energy-px',ENERGY.px+'px');\r\n  if(!prefersReducedMotion())[...el.children].forEach((channel,i)=>{const [axis,dir]=ENERGY_MOVES[i],from=`translate${axis}(${-ENERGY.px*(dir>0)}px)`,to=`translate${axis}(${-ENERGY.px*(dir<0)}px)`;energyAnims.push(channel.firstElementChild.animate([{transform:from},{transform:to}],{duration:ENERGY.loopMs,iterations:Infinity}));});\r\n }\r\n syncEnergy();\r\n boardHost=portalHome.querySelector('#portalBoardHost');\r\n boardHost.addEventListener('webglcontextlost',e=>{if(gl3&&e.target===gl3.canvas)lost3D();},true); // capture: the event doesn't bubble\r\n const resizeFullscreenFace=()=>{const dialog=framed?.dialog;if(!dialog?.classList.contains('portal-fullscreen'))return;const face=fullscreenFace();setFace(dialog,face);setFace(chrome,face);if(aura)showAura(screenLook(framed.look,face),'open');};\r\n addEventListener('resize',resizeFullscreenFace,{signal:lifecycle.signal});window.visualViewport?.addEventListener('resize',resizeFullscreenFace,{signal:lifecycle.signal});\r\n overlay=portalHome.querySelector('#portalOverlay');ctx=overlay.getContext('2d');\r\n objectsLayer=portalHome.querySelector('#portalObjects');\r\n statusEl=portalHome.querySelector('#portalStatus');\r\n const retryBtn=portalHome.querySelector('#portalRetry');\r\n retryBtn.addEventListener('click',()=>retryBtn._run?.(),{signal:lifecycle.signal});\r\n // W2-2A: the app's bottom bar (routes.mjs) is up on the quilt; its centre Portal button replaces the floating Menu\r\n // button, and the focus trap cycles the whole bar plus Pod (and Armie's inbox button, which stays live on the quilt).\r\n const barPortal=document.querySelector('.coach-dock [data-route=\"portal\"]'),bar=barPortal?.closest('.coach-dock');\r\n menuBtn=barPortal||portalHome.querySelector('#portalExitButton');\r\n const exitBtn=portalHome.querySelector('#portalExitButton');\r\n settingsBtn=portalHome.querySelector('#portalSettingsButton');\r\n settingsBtn.onclick=()=>openMenu();\r\n mountPodChrome(settingsBtn,{signal:lifecycle.signal});\r\n if(bar)exitBtn.remove(); // the centre mechanical key returns to the pod when the dock is present\r\n else exitBtn.onclick=()=>setVisible(false);\r\n const armie=()=>[...document.querySelectorAll('.armie-inbox-launcher')].filter(el=>el.getClientRects().length);\r\n const trap=e=>{if(e.key==='Escape'){e.preventDefault();setVisible(false);}else if(e.key==='Tab'){const buttons=[...new Set([...(bar?bar.querySelectorAll('button'):[menuBtn]),settingsBtn,document.getElementById('spotifyNowPlayingOpen'),...armie(),...(exitBtn.isConnected?[exitBtn]:[])])],index=buttons.indexOf(document.activeElement);e.preventDefault();buttons[(index+(e.shiftKey?-1:1)+buttons.length)%buttons.length].focus();}};\r\n portalHome.addEventListener('keydown',trap);\r\n bar?.addEventListener('keydown',e=>{if(boardShown&&!bar.closest('dialog'))trap(e);},{signal:lifecycle.signal});\r\n document.addEventListener('keydown',e=>{if(boardShown&&e.target.classList?.contains('armie-inbox-launcher'))trap(e);},{signal:lifecycle.signal});\r\n boardBtn=document.getElementById('openBoard');\r\n // The fallback menu sheet lives outside portalHome too: a dialog nested in a hidden ancestor\r\n // would be hidden along with it while open (e.g. mid-fade during the \"all\" portal reveal).\r\n menuSheet=document.createElement('dialog');menuSheet.id='portalMenu';menuSheet.className='portal-menu';menuSheet.setAttribute('aria-labelledby','portalMenuTitle');\r\n // The board picker row only earns its place once a second board ships; one option is nothing to pick from.\r\n const boardRow=PRODUCTION_PORTALS.length<2?'':`<div class=\"portal-board-chips\" role=\"group\" aria-label=\"Board\">${boardChipsHtml()}</div>`;\r\n menuSheet.innerHTML=`<header><h2 id=\"portalMenuTitle\">GRIMOIRE SETTINGS</h2><button type=\"button\" data-menu-close>Back to portal</button></header>${lookControlsHtml()}${boardTintControlsHtml()}${boardRow}<div data-palette-row>${paletteSelectHtml()}</div><details class=\"portal-full-menu\"><summary>Full menu</summary><div class=\"portal-menu-grid\">${menuButtonsHtml()}</div></details><p id=\"portalMenuStatus\" role=\"status\"></p>`;\r\n menuSheet.querySelector('[data-menu-close]').onclick=()=>menuSheet.close();\r\n menuSheet.querySelectorAll('[data-look]').forEach(input=>input.oninput=()=>{saveLook(input.dataset.look,input.value);applyLook();});\r\n menuSheet.querySelector('[data-look-reset]').onclick=()=>{for(const name of ['portal','strip'])saveLook(name,LOOK_DEFAULTS[name]);applyLook();};\r\n document.body.append(menuSheet);\r\n menuSheet.querySelectorAll('[data-menu]').forEach(btn=>btn.onclick=()=>{\r\n  const menu=MENUS[btn.dataset.menu];\r\n  if(menu.locked?.()){menuSheet.querySelector('#portalMenuStatus').textContent=menu.lockedMessage;return;}\r\n  menuSheet.querySelector('#portalMenuStatus').textContent='';menuChosen=true;menuSheet.close();\r\n  // A traced-shape dialog open fades back to the quilt when its dialog closes (openDirect). Route the\r\n  // same destinations opened from the Menu sheet through the same flow, or closing leaves the pod\r\n  // showing instead of the quilt. kind:'home' and kind:'nav' keep their plain setVisible+open.\r\n  if(menu.kind==='dialog'){const run=++sequence;openDirect(menu,()=>run===sequence&&!lifecycle.signal.aborted);return;}\r\n  setVisible(false);menu.open?.();\r\n });\r\n menuSheet.addEventListener('input',e=>{\r\n  if(e.target.matches('[data-board-tint]')){\r\n   const color=e.target.value;store.set(tintKey(boardId),color);\r\n   if(base&&boardId!=='quilt')base.setTint?.(color);\r\n   if(gl3&&boardId!=='quilt')gl3.setTint?.(color);\r\n   e.target.setAttribute('value',color);\r\n  }else if(e.target.matches('[data-backplate-tint]')){\r\n   setCogsBackplateTint(e.target.value);e.target.setAttribute('value',e.target.value);\r\n  }\r\n },{signal:lifecycle.signal});\r\n menuSheet.addEventListener('change',e=>{if(e.target.matches('[data-palette]')){const options=paletteOptions(boardId);if(options.some(p=>p.id===e.target.value))store.set(paletteKey(boardId),e.target.value);}}, {signal:lifecycle.signal});\r\n menuSheet.querySelectorAll('[data-board]').forEach(btn=>btn.onclick=async()=>{menuChosen=true;menuSheet.close();const selected=btn.dataset.board;await loadBoard(selected);if(!lifecycle.signal.aborted)setVisible(true);});\r\n workoutHome=document.createElement('dialog');workoutHome.id='portalWorkoutHome';workoutHome.className='portal-workout-home';document.body.append(workoutHome);\r\n workoutHome.addEventListener('close',()=>{if(!workoutHome.open)restoreWorkoutHome();});\r\n}\r\n\r\nfunction restoreWorkoutHome(){\r\n for(const {node,slot} of workoutSlots){if(slot.parentNode)slot.replaceWith(node);}\r\n workoutSlots=[];\r\n}\r\nfunction openWorkoutHome(){\r\n if(!workoutHome)return null;\r\n if(workoutHome.open)return workoutHome;\r\n if(workoutSlots.length){workoutHome.showModal();return workoutHome;}\r\n const home=document.getElementById('homeScreen');if(!home)return null;\r\n backgroundBlocked(false);\r\n const nodes=[document.getElementById('podShipBackdrop'),document.querySelector('body>.ship-header'),home].filter(node=>node&&!workoutHome.contains(node));\r\n workoutSlots=nodes.map(node=>{const slot=document.createComment('pod-workout-home-slot');node.parentNode?.insertBefore(slot,node);return{node,slot};});\r\n workoutHome.append(...nodes);workoutHome.showModal();\r\n return workoutHome;\r\n}\r\n\r\nfunction backgroundBlocked(block){\r\n // Dialogs that are open or hidden are never made inert: one opened as a modal while the quilt is up (the full-download\r\n // offer, setup gate, reward reveals) sits in the top layer and must stay tappable, or the app freezes. A closed dialog\r\n // that is still drawn (styled display:grid) stays inert so it can't catch taps meant for the quilt. The \"Updated: …\"\r\n // toast (app-updates.mjs) is a non-dialog element sitting over the portal's own controls; it's exempt too, or its\r\n // \"Got it\" tap falls through to whatever is underneath (portal.css raises it above the Menu button while up).\r\n const liveDialog=el=>el.tagName==='DIALOG'&&(el.open||getComputedStyle(el).display==='none');\r\n const exempt=el=>el===portalHome||el===menuSheet||liveDialog(el)||el.classList.contains('app-update-banner')||el.classList.contains('coach-dock')||el.classList.contains('armie-inbox-launcher')||el.classList.contains('reward-pack-launch'); // the reward-pack chip must stay tappable over the grimoire\r\n if(block){for(const el of document.body.children)if(!exempt(el)&&!backgroundInert.has(el)){backgroundInert.set(el,el.inert);el.inert=true;}}\r\n else{for(const [el,inert]of backgroundInert)el.inert=inert;backgroundInert.clear();}\r\n}\r\nfunction openMenu(){\r\n portalSound('menu');\r\n const returnToQuilt=boardShown,{face}=restFace();setVisible(false);menuChosen=false;menuSheet.showModal();\r\n if(face&&frameOn(face,windowLook('line-up',MENUS['line-up'],face)))frameDialog(menuSheet);\r\n menuSheet.addEventListener('close',()=>{if(framed?.dialog===menuSheet)frameOff();if(returnToQuilt&&!menuChosen&&!lifecycle.signal.aborted)setVisible(true);},{once:true});\r\n}\r\n\r\n// Every hide/show path heals the board (idempotent), so it always comes back whole.\r\n// Vault telemetry: raw-served file, so no import (the app bundle's vault store listens); the store listens for these.\r\nconst vaultSend=detail=>{try{dispatchEvent(new CustomEvent('myr5:vault-bump',{detail}));}catch{/* no window */}};\r\nlet visibleSince=0;const grimFlush=()=>{if(visibleSince){vaultSend({counter:'grim-time',ms:Date.now()-visibleSince});visibleSince=0;}};\r\nfunction setVisible(v){\r\n visibilityRun++;\r\n // Routes can put the quilt back while its destination's reverse dive is still awaiting its\r\n // animation. Invalidate and remove that return phase now; otherwise its glass stays mounted\r\n // until the old animation resolves. A forward phase has no backT0, so showing the quilt does\r\n // not interrupt a newly-started portal sequence.\r\n if(v&&phase?.backT0){endPhase();portalHome.style.transformOrigin='';}\r\n if(!v){sequence++;busy=false;clearTimeout(finalizeTimer);pendingStrokes=[];pendingTrailPts=[];fading.length=0;pointers.forEach((_,pid)=>board?.release(pid));pointers.clear();outlineFlash=null;objectsLayer.replaceChildren();cancelAnimationFrame(rafId);rafId=0;grimFlush();}\r\n board?.heal();\r\n portalHome.hidden=!v;\r\n if(boardBtn)boardBtn.hidden=v;\r\n if(v){if(!boardShown)focusBefore=document.activeElement;motion(portalHome,'');portalHome.style.opacity='';portalHome.style.clipPath='';board?.resume();backgroundBlocked(true);menuBtn.focus();maybeStartHint();if(!document.hidden&&!visibleSince)visibleSince=Date.now();}\r\n else{endPhase();board?.pause();backgroundBlocked(false);if(focusBefore?.isConnected)focusBefore.focus();}\r\n boardShown=v;frameOff();if(v)applyLook();syncEnergy();\r\n portalSound('scene',{visible:v});\r\n scheduleIdle();if(v)threeD();\r\n}\r\nfunction fadeOutBoard(){\r\n const run=++visibilityRun;\r\n backgroundBlocked(false);\r\n portalSound('scene',{visible:false});\r\n motion(portalHome,'opacity .3s ease');portalHome.style.opacity='0';\r\n return new Promise(r=>setTimeout(()=>{if(run===visibilityRun){portalHome.hidden=true;if(boardBtn)boardBtn.hidden=false;endPhase();board?.heal();board?.pause();boardShown=false;syncEnergy();scheduleIdle();}r();},prefersReducedMotion()?0:300));\r\n}\r\nfunction fadeInBoard(){\r\n visibilityRun++;\r\n endPhase();board?.heal();\r\n portalHome.hidden=false;portalHome.style.clipPath='';motion(portalHome,'none');portalHome.style.opacity='0';\r\n if(boardBtn)boardBtn.hidden=true;\r\n board?.resume();boardShown=true;frameOff();syncEnergy();backgroundBlocked(true);menuBtn.focus();scheduleIdle();threeD();\r\n portalSound('scene',{visible:true});\r\n const run=visibilityRun;\r\n settle().then(()=>{if(run!==visibilityRun)return;motion(portalHome,`opacity ${PORTAL.healMs}ms ease`);portalHome.style.opacity='1';});\r\n}\r\n// The border stays when a destination opens (Ian 23 Sept): #portalChrome shows a copy of the frame at the board's rest box\r\n// in the top layer, with a matte outside it, and the destination dialog is fitted into its window (.portal-framed).\r\n// look (#134): how the window reads: {id,color,label,pts: its outline (client px, closed),shaped,name: #132's rim path};\r\n// shaped (#131): the destination is seen through the cut in the quilt, which stays on as the wall around it.\r\n// ponytail: the box is measured once per destination, so a rotation while one is open keeps the old box until it closes.\r\nlet framed=null,ghostEl=null;\r\nfunction restFace(){const hidden=portalHome.hidden;portalHome.hidden=false;const face=board?.faceRect(),pattern=board?.patternRect();portalHome.hidden=hidden;return {face,pattern};}\r\nconst setFace=(el,face)=>{for(const k of ['left','top','width','height'])face?el.style.setProperty('--face-'+k,face[k]+'px'):el.style.removeProperty('--face-'+k);};\r\nconst rectPts=f=>closeLoop([[f.left,f.top],[f.left+f.width,f.top],[f.left+f.width,f.top+f.height],[f.left,f.top+f.height]]);\r\nconst menuFor=route=>Object.entries(MENUS).find(([,m])=>m.route===route)||[null,null];\r\n// A full-window look (the lines, the Menu sheet, a bottom-bar switch): the window's own rectangle, the name on the upper rail.\r\n const windowLook=(id,menu,face)=>({id,color:boardTint(),strip:readLook().strip,label:menu?.label||'',pts:rectPts(face),shaped:false,name:namePath(face)});\r\n// R7 (Ian 26 Sept): no text in a peer-through view, so the cut's rim (and the window it steps in to) carries no name.\r\n const shapeLook=(id,menu,pts)=>({id,color:boardTint(),strip:readLook().strip,label:menu.label,pts,shaped:true,name:null});\r\n// Fullscreen destinations keep the energy and feather it inward along the inset face.\r\n const screenLook=(look,face=fullscreenFace())=>({...look,pts:rectPts(face),shaped:false,fullscreen:true,name:null});\r\n // R20 (Ian 2 Oct): the housing ends above the dock, a separate console fixed below it (0 while the dock is hidden).\r\n // The console's height comes from --myr5-bar (the dock may be mid-move between dialogs, measuring 0, when a face is set);\r\n // 0 when the app hides the dock (tracking, rest) or there is none.\r\n let barProbe=null;\r\n const dockHeight=()=>{const b=document.body;if(!document.getElementById('coachDock')||b.dataset.tracking==='true'||b.dataset.screen==='rest')return 0;if(!barProbe?.isConnected){barProbe=document.createElement('div');barProbe.setAttribute('aria-hidden','true');barProbe.style.cssText='position:fixed;left:-9px;top:0;width:1px;height:var(--myr5-bar,88px);visibility:hidden;pointer-events:none';b.append(barProbe);}return barProbe.getBoundingClientRect().height;};\r\n function fullscreenFace(){const rail=15;return {left:rail,top:rail,width:Math.max(1,innerWidth-rail*2),height:Math.max(1,innerHeight-rail*2-dockHeight())};}\r\nfunction frameOn(face,look){\r\n frameOff();\r\n if(!chrome.showPopover||!face)return false; // no popover API (Safari before 17): destinations open as they always have\r\n framed={face,look:look||windowLook(null,null,face),leaned:false,ctl:new AbortController()};setFace(chrome,face);chrome.showPopover();syncEnergy();\r\n if(framed.look.shaped)framed.outlines=windowOutlines(framed.look.pts,face);\r\n // Release 5 open item: switching routes from the bottom bar while a destination is framed used to open the next page\r\n // unframed with the reverse dive playing behind it. The frame now moves to the next route's dialog (routes.mjs's\r\n // observer, created first, has already adopted it, so it carries its data-route), and a page route puts it away (closed).\r\n framed.watch=new MutationObserver(records=>{for(const {target} of records)if(framed?.dialog&&target!==framed.dialog&&target instanceof HTMLDialogElement&&target.open&&target.dataset.route)handOver(target);});\r\n framed.watch.observe(document.body,{subtree:true,attributeFilter:['open']});\r\n return true;\r\n}\r\n function frameDialog(dialog){\r\n  if(!framed||!(dialog instanceof HTMLDialogElement)||framed.dialog===dialog)return;\r\n  unframe(framed.dialog);framed.dialog=dialog;dialog.classList.add('portal-framed');\r\n  const route=framed.directRoute||dialog.dataset.route;\r\n  const full=framed.direct===true||dialog.matches('.meditation-panel')||dialog.id==='portalWorkoutHome',face=full?fullscreenFace():framed.face;setFace(dialog,face);setFace(chrome,face);\r\n  dialog.classList.toggle('portal-fullscreen',full);chrome.classList.toggle('portal-housing-fullscreen',full);chrome.classList.remove('portal-garage');if(full)chrome.dataset.destination=framed.directRoute|| (dialog.matches('.meditation-panel')?'meditation':'workout');else delete chrome.dataset.destination;\r\n // Back above the dialog, which opened on top of it. Re-shown a frame later: a popover hidden and shown in one task can\r\n // keep its old top-layer slot (under the dialog's backdrop) on WebKit. The rim is drawn then too, sized to the shown\r\n // frame (a hidden popover measures 0x0): it bursts open as the destination lands (not under the dive's scale).\r\n  chrome.hidePopover();requestAnimationFrame(()=>{if(framed?.dialog!==dialog)return;if(!chrome.matches(':popover-open'))chrome.showPopover();showAura(full?screenLook(framed.look,face):aura?.look||framed.look,'open');});\r\n peerOn(dialog); // R7 (Ian 26 Sept): the tilt stays on every menu, full screen too\r\n if(!full&&framed.look.shaped)shapeDialog(dialog);\r\n}\r\n// The room remains visible through its cut until a double-tap or a scene action steps inside (full screen). Keep the\r\n// route/dialog identity, so Back and Close still return through their original portal. The housing remains around the inset face.\r\nfunction expandScene(dialog){\r\n if(!dialog?.open||framed?.dialog!==dialog||framed.expanded)return false;\r\n layoutInCut(dialog,false);framed.expanded=true;framed.leaned=true;\r\n dialog.classList.remove('portal-shaped','portal-inset','portal-leaned');dialog.classList.add('portal-fullscreen');chrome.classList.add('portal-housing-fullscreen');\r\n dialog.style.removeProperty('clip-path');dialog.style.removeProperty('--inset-zoom');motion(dialog,'');\r\n  const face=fullscreenFace();setFace(dialog,face);setFace(chrome,face);\r\n  chrome.classList.remove('portal-garage');showAura(screenLook(framed.look,face),'lean');\r\n stowBoard();return true;\r\n}\r\n// A destination can showModal() before its open() settles (the ship view loads after): frame it as it opens, before\r\n// its first paint (MutationObserver callbacks run ahead of rendering). Returns the disconnect.\r\nfunction watchDialog(){\r\n if(!framed)return null;\r\n const watch=new MutationObserver(records=>{for(const {target} of records)if(target instanceof HTMLDialogElement&&target.open)frameDialog(target);});\r\n watch.observe(document.body,{subtree:true,attributeFilter:['open']});\r\n return ()=>watch.disconnect();\r\n}\r\nfunction unframe(dialog){\r\n if(!dialog)return;\r\n if(framed?.dialog===dialog){peerOff();if(framed.look.shaped)layoutInCut(dialog,false);framed.dialog=null;}\r\n dialog.classList.remove('portal-framed','portal-shaped','portal-leaned','portal-inset','portal-fullscreen');setFace(dialog,null);dialog.style.removeProperty('--inset-zoom');\r\n dialog.style.removeProperty('clip-path');motion(dialog,'');\r\n dialog.querySelector(':scope>.portal-peer-ui')?.remove();\r\n}\r\nfunction frameOff(){\r\n if(!framed)return;\r\n const f=framed;f.watch?.disconnect();f.ctl.abort();\r\n if(f.directClose&&f.dialog)f.dialog.removeEventListener('close',f.directClose);\r\n unframe(f.dialog);ghostEl?.remove();ghostEl=null;framed=null;hideAura();chrome.classList.remove('portal-garage','portal-housing-fullscreen');delete chrome.dataset.destination;chrome.hidePopover();syncEnergy();\r\n}\r\nfunction frameDirectDestination(dialog,id){\r\n if(!(dialog instanceof HTMLDialogElement)||!dialog.open)return false;\r\n if(framed?.direct&&framed.dialog===dialog&&framed.directRoute===id)return true;\r\n const [shape,menu]=menuFor(id),route=window.myr5Routes?.ROUTES?.[id];\r\n sequence++;\r\n setVisible(false);\r\n const face=fullscreenFace(),look=windowLook(shape,menu||{label:route?.label||id},face);\r\n if(!frameOn(face,look))return false;\r\n dialog.dataset.route=id;\r\n framed.direct=true;framed.directRoute=id;\r\n frameDialog(dialog);\r\n const owner=framed;\r\n owner.directClose=()=>{if(framed===owner&&owner.dialog===dialog)frameOff();};\r\n dialog.addEventListener('close',owner.directClose);\r\n return true;\r\n}\r\n// The bar switched routes: the next route's dialog takes the frame, full window, in its own colour and name.\r\nfunction handOver(dialog){\r\n const route=dialog.dataset.route,[id,found]=menuFor(route),menu=found||{label:window.myr5Routes?.ROUTES?.[route]?.label};\r\n unframe(framed.dialog);\r\n if(framed.look.shaped)stowBoard(); // the quilt wall goes with the hole it framed\r\n Object.assign(framed,{look:windowLook(id,menu,framed.face),leaned:false,outlines:null,expanded:false});\r\n hideAura();frameDialog(dialog);\r\n const run=++sequence;\r\n dialog.addEventListener('close',()=>closed(dialog,{pts:backPts(id),color:menu?.color||'#b026ff'},()=>run===sequence&&!lifecycle.signal.aborted),{once:true});\r\n}\r\nfunction backPts(id){const {pattern}=restFace();if(!pattern)return pattern;const sid=id&&SHAPES[id]&&id!=='x'&&id!=='cross'?id:'rect';return boardId==='cogs'?shapeClipPts(sid,pattern):insetPts(shapeClipPts(sid,pattern),sid);}\r\nfunction stowBoard(){visibilityRun++;portalHome.hidden=true;if(boardBtn)boardBtn.hidden=false;endPhase();board?.heal();board?.pause();boardShown=false;syncEnergy();portalSound('scene',{visible:false});}\r\n// A destination from the portal closed: back out to the quilt (the reverse dive, or #131's fizzle for a hole), unless the\r\n// frame already moved on (handOver) or the bar went to another route (it is the active route now).\r\nfunction closed(dialog,back,current){\r\n if(!current()||(framed&&framed.dialog!==dialog))return; // never framed (no popover API, no board): still back out\r\n const now=window.myr5Routes?.current?.();\r\n if(now&&now!==dialog.dataset.route){frameOff();return;}\r\n (back.shaped&&!framed?.expanded?fizzleBack:diveBack)({dialog,...back},current);\r\n}\r\n// The closed destination's empty shell (a shallow copy keeps its own look), shrinking into the wormhole core.\r\nfunction shrinkShell(dialog,[cx,cy],ms){\r\n if(!framed||dialog!==framed.dialog)return;\r\n const shell=dialog.cloneNode(false),f=framed.face;shell.removeAttribute('open');shell.inert=true;shell.classList.add('portal-ghost');\r\n shell.style.transformOrigin=`${cx-f.left}px ${cy-f.top}px`;document.body.append(shell);ghostEl=shell;\r\n shell.animate([{transform:'none',opacity:1},{transform:'scale(.05)',opacity:0}],{duration:ms,easing:'cubic-bezier(.7,0,.8,1)',fill:'forwards'}).finished.then(()=>shell.remove(),()=>{});\r\n}\r\n// Closing a destination flies back OUT of the wormhole (Ian 23 Sept): the destination shrinks into the tunnel core while\r\n// the portal scales back down from the dive and the tunnel slows, then the cut heals and the chrome hands back to the\r\n// board's own frame. Same revealMs as the dive in; reduced motion is the plain quick fade.\r\n// A way back that loses the screen to a newer show (routes' home-after-close can land first) drops its own glass and dive\r\n// on the way out, so none is left under the quilt, and always hands back busy (backRun: the latest way back owns it).\r\nlet backRun=0;\r\nfunction stale(run,ph,current){\r\n if(run===visibilityRun&&current())return false;\r\n if(phase===ph){endPhase();portalHome.style.transformOrigin='';}\r\n return true;\r\n}\r\nasync function diveBack({dialog,pts,color},current){\r\n if(prefersReducedMotion()||!board||!pts){fadeInBoard();return;}\r\n const run=++visibilityRun;backRun=run;\r\n auraOut();shrinkShell(dialog,centroidOf(pts),PORTAL.revealMs*.55);unframe(dialog);\r\n busy=true;\r\n try{\r\n  portalHome.hidden=false;motion(portalHome,'none');portalHome.style.opacity='';portalHome.style.clipPath='';\r\n  if(boardBtn)boardBtn.hidden=true;\r\n  board.resume();boardShown=true;syncEnergy();backgroundBlocked(true);\r\n  showGlass(pts,color);const ph=phase;\r\n  for(const el of [phase.glass,phase.bezel])el?.style.setProperty('animation','none','important'); // already there\r\n  phase.t0-=PORTAL.cutMs+PORTAL.loadMinMs; // the tunnel is already at full speed\r\n  cutBoard(pts,color,0);\r\n  await dive(pts,true);\r\n  if(stale(run,ph,current))return;\r\n  board.heal();\r\n  await phase?.bezel?.animate([{opacity:1},{opacity:0}],{duration:PORTAL.healMs}).finished.catch(()=>{});\r\n  if(stale(run,ph,current))return;\r\n  endPhase();frameOff();menuBtn.focus();scheduleIdle();\r\n }finally{if(backRun===run)busy=false;}\r\n}\r\n// #131/#130 closing a destination seen through the hole: it fizzles shut. The destination's shell shrinks into the\r\n// wormhole's core with a flash along the rim and sparks falling in, then the cut heals and the quilt is home again.\r\nasync function fizzleBack({dialog,pts,color},current){\r\n const run=++visibilityRun,ms=PORTAL.revealMs*.55;backRun=run;\r\n if(prefersReducedMotion()||!board||!pts){unframe(dialog);homeAgain();return;}\r\n busy=true;\r\n try{\r\n  auraOut();shrinkShell(dialog,centroidOf(pts),ms);unframe(dialog);\r\n  showGlass(pts,color);const ph=phase;phase.t0-=PORTAL.cutMs+PORTAL.loadMinMs;phase.backT0=performance.now();cutBoard(pts,color,0);board.resume();\r\n  await sleep(ms);\r\n  if(stale(run,ph,current))return;\r\n  board.heal();\r\n  await phase?.bezel?.animate([{opacity:1},{opacity:0}],{duration:PORTAL.healMs}).finished.catch(()=>{});\r\n  if(stale(run,ph,current))return;\r\n  homeAgain();\r\n }finally{if(backRun===run)busy=false;}\r\n}\r\nfunction homeAgain(){endPhase();board?.heal();board?.resume();frameOff();backgroundBlocked(true);menuBtn.focus();scheduleIdle();}\r\n\r\n// ---- #131 seen through the hole -------------------------------------------------------------------------------------\r\n// The oval, the diamonds and both triangles open INTO the cut: the quilt stays on screen as the wall around the hole and\r\n// the destination (fitted to the window as usual, so nothing inside it changes) is clipped to the cut outline, plus the\r\n// bottom bar and the portal's own buttons on the quilt beside the hole (children of the modal dialog, so they stay\r\n// tappable). ✕ closes through the destination's own Close; ⤢ \"steps in\" (#131's gentle zoom): the hole morphs out to the\r\n// whole window so all of the menu is in reach, and ⤡ steps back. Keyboard focus landing on something the wall hides\r\n// steps in too.\r\nconst scalePts=(pts,k)=>{const [cx,cy]=centroidOf(pts);return pts.map(([x,y])=>[cx+(x-cx)*k,cy+(y-cy)*k]);};\r\n// The farthest crossing of a ray from c at angle a with a closed polygon (the shapes are star-shaped about their centroid).\r\nexport function rayHit([cx,cy],a,poly){\r\n const dx=Math.cos(a),dy=Math.sin(a);let best=0;\r\n for(let i=0;i<poly.length-1;i++){\r\n  const [ax,ay]=poly[i],[bx,by]=poly[i+1],ex=bx-ax,ey=by-ay,den=dx*ey-dy*ex;if(Math.abs(den)<1e-9)continue;\r\n  const t=((ax-cx)*ey-(ay-cy)*ex)/den,u=((ax-cx)*dy-(ay-cy)*dx)/den;\r\n  if(t>0&&u>=-1e-9&&u<=1+1e-9)best=Math.max(best,t);\r\n }\r\n return [cx+dx*best,cy+dy*best];\r\n}\r\n// The hole and the whole window as matched outlines (the same rays from the shape's centroid, through every corner of\r\n// both), so a clip-path can morph one into the other.\r\nexport function windowOutlines(shape,face,n=48){\r\n const c=centroidOf(shape),box=rectPts(face),ang=([x,y])=>Math.atan2(y-c[1],x-c[0]);\r\n const as=[...Array.from({length:n},(_,i)=>-Math.PI+2*Math.PI*i/n),...shape.slice(0,-1).map(ang),...box.slice(0,-1).map(ang)].sort((a,b)=>a-b).filter((a,i,s)=>!i||a-s[i-1]>1e-4);\r\n return {shape:closeLoop(as.map(a=>rayHit(c,a,shape))),rect:closeLoop(as.map(a=>rayHit(c,a,box)))};\r\n}\r\nfunction peerUi(dialog){\r\n const ui=dialog.querySelector(':scope>.portal-peer-ui')||dialog.appendChild(Object.assign(document.createElement('div'),{className:'portal-peer-ui'}));\r\n if(framed)ui.style.setProperty('--peer-ui',framed.look.color);return ui;\r\n}\r\n// A flat menu (conductor 24 Sept) is laid out in the largest rectangle inside the cut (insetRect), a little zoomed out and\r\n// scrolling inside it, the rest of the cut showing the destination's still depth; a scene fills the cut and shows nothing\r\n// but itself (R7, Ian 29 Sept: portal.css hides its titles and controls until full screen), and cfg.fit sizes a scene\r\n// layer to the cut (the constellation).\r\nfunction shapeDialog(dialog){\r\n const {look}=framed,ui=peerUi(dialog),cfg=peerCfg(dialog);\r\n framed.flat=!cfg.scene;framed.cfg=cfg;\r\n dialog.classList.add('portal-shaped');\r\n const r=framed.flat&&(framed.inset??=insetRect(framed.outlines.shape)),small=r&&(r.width-2*INSET.margin<INSET.minW||r.height-2*INSET.margin<INSET.minH);\r\n if(small){framed.leaned=true;dialog.classList.add('portal-leaned');showAura({...look,pts:rectPts(framed.face),shaped:false},'lean');}\r\n else layoutInCut(dialog,true);\r\n dialog.addEventListener('focusin',({target})=>{if(framed?.dialog===dialog&&!framed.leaned&&!ui.contains(target)&&target.matches?.(':focus-visible')&&!throughCut(target))lean(true);},{signal:framed.ctl.signal});\r\n clipTo(dialog,small?framed.outlines.rect:framed.outlines.shape,{from:scalePts(framed.outlines.shape,.04),ms:prefersReducedMotion()?0:650,ease:'cubic-bezier(.2,1.25,.4,1)'});\r\n // R7 (Ian 26 Sept): a double-tap on the open menu (not on one of its controls) steps in to the full screen.\r\n const at=e=>({x:e.clientX,y:e.clientY,t:(isFinite(e.timeStamp)&&e.timeStamp>0?e.timeStamp:performance.now()),id:e.pointerId}),near=(a,b)=>a&&b&&b.t-a.t>=0&&b.t-a.t<=TAP_MS&&Math.hypot(b.x-a.x,b.y-a.y)<=TAP_MOVE_PX,opts={capture:true,signal:framed.ctl.signal};\r\n let down=null,tap=null,multitouch=false;\r\n const activePointers=new Set();\r\n dialog.addEventListener('pointerdown',e=>{\r\n   activePointers.add(e.pointerId);\r\n   if(multitouch) return;\r\n   if(activePointers.size>1){multitouch=true;down=null;tap=null;return;}\r\n   down=at(e);\r\n },opts);\r\n dialog.addEventListener('pointerup',e=>{\r\n   activePointers.delete(e.pointerId);\r\n   if(multitouch){if(activePointers.size===0)multitouch=false;return;}\r\n   if(!down||down.id!==e.pointerId){down=null;return;}\r\n   const up=at(e),t=near(down,up)&&!e.target.closest?.('button,a,input,select,textarea,label,summary')?up:null;\r\n   if(t&&near(tap,t)){tap=null;expandScene(dialog);}else tap=t;\r\n   down=null;\r\n },opts);\r\n dialog.addEventListener('pointercancel',e=>{\r\n   activePointers.delete(e.pointerId);\r\n   down=null;\r\n   tap=null;\r\n   if(activePointers.size===0){multitouch=false;}\r\n },opts);\r\n // A tap on the scene that opens one of its cards (a boss's detail, a pyramid screen or dial) steps in to show it.\r\n if(cfg.cards){\r\n  let shut=[];const open=()=>[...dialog.querySelectorAll(cfg.cards)].filter(el=>!el.hidden);\r\n  dialog.addEventListener('click',()=>{shut=open();},opts);\r\n  dialog.addEventListener('click',()=>{if(open().some(el=>!shut.includes(el)))expandScene(dialog);},{signal:framed.ctl.signal});\r\n }\r\n}\r\nfunction peerCfg(dialog){return PEER_DEPTH.find(([s])=>dialog.matches(s))?.[1]||PEER_2D;}\r\n// Largest axis-aligned rectangle inside a convex outline (client px, closed), leaning a little toward width so a menu's\r\n// text column stays readable (scored width^1.5 x height). For a convex shape the rectangle's sides are bounded by the\r\n// chords at its top and bottom edges only, so every pair of sampled chords is a candidate.\r\nexport function insetRect(poly,n=48){\r\n const ys=poly.map(p=>p[1]),y0=Math.min(...ys),y1=Math.max(...ys);\r\n const chord=y=>{let l=Infinity,r=-Infinity;for(let i=0;i<poly.length-1;i++){const [ax,ay]=poly[i],[bx,by]=poly[i+1];if(ay===by||(ay-y)*(by-y)>0)continue;const x=ax+(bx-ax)*(y-ay)/(by-ay);l=Math.min(l,x);r=Math.max(r,x);}return [l,r];};\r\n const Y=Array.from({length:n+1},(_,i)=>y0+(y1-y0)*i/n),C=Y.map(chord);\r\n let best=null;\r\n for(let i=0;i<=n;i++)for(let j=i+1;j<=n;j++){\r\n  const l=Math.max(C[i][0],C[j][0]),r=Math.min(C[i][1],C[j][1]),w=r-l,h=Y[j]-Y[i],score=w**1.5*h;\r\n  if(w>0&&(!best||score>best.score))best={score,left:l,top:Y[i],width:w,height:h};\r\n }\r\n return best&&{left:best.left,top:best.top,width:best.width,height:best.height};\r\n}\r\n// px clear of the rim; the width a menu is laid out at and its floor zoom; below minW x minH the cut is too small to hold a\r\n// menu and the portal opens stepped in (the squat diamond).\r\nconst INSET={margin:10,layoutPx:240,minZoom:.6,minW:150,minH:190};\r\n// on: lay the destination out for the cut (flat: into its rectangle; scene: fit cfg.fit); off: the whole window (step in).\r\nfunction layoutInCut(dialog,on){\r\n const f=framed;if(!f)return;\r\n if(f.flat){\r\n  if(!on){dialog.classList.remove('portal-inset');dialog.style.removeProperty('--inset-zoom');setFace(dialog,f.face);return;}\r\n  const r=f.inset??=insetRect(f.outlines.shape),m=INSET.margin,box={left:r.left+m,top:r.top+m,width:r.width-2*m,height:r.height-2*m};\r\n  setFace(dialog,box);dialog.classList.add('portal-inset');\r\n  dialog.style.setProperty('--inset-zoom',Math.max(INSET.minZoom,Math.min(1,(box.width-40)/INSET.layoutPx)).toFixed(3));\r\n  return;\r\n }\r\n const fit=f.cfg?.fit,el=fit&&dialog.querySelector(fit.sel);if(!el)return;\r\n if(!on){for(const k of ['height','margin-top','align-self'])el.style.removeProperty(k);return;}\r\n // The layer's band [top,bottom] (fractions of its height) spans the cut's height, its top at the cut's top.\r\n const ys=f.look.pts.map(p=>p[1]),top=Math.min(...ys),H=(Math.max(...ys)-top)/(fit.band[1]-fit.band[0]);\r\n el.style.setProperty('height',d2(H)+'px','important');el.style.setProperty('align-self','start','important');el.style.setProperty('margin-top',d2(top-f.face.top-fit.band[0]*H)+'px','important');\r\n}\r\nfunction throughCut(el){const r=el.getBoundingClientRect();return pointInPolygon(r.left+r.width/2,r.top+r.height/2,framed.outlines.shape);}\r\n// clip-path for a shaped dialog: the outline (client px -> the dialog's box) plus the bar's box (a separate subpath; nonzero\r\n// fill unions them). R7: nothing of a scene shows in front of the wall any more, so nothing else pokes through.\r\nfunction clipFor(dialog,pts){\r\n const r=dialog.getBoundingClientRect(),o=([x,y])=>`${d2(x-r.left)} ${d2(y-r.top)}`,box=el=>el?.getClientRects().length?el.getBoundingClientRect():null;\r\n const bar=box(document.getElementById('coachDock')),parts=bar?[`M${o([bar.left,bar.top])}L${o([bar.right,bar.top])}L${o([bar.right,bar.bottom])}L${o([bar.left,bar.bottom])}Z`]:[];\r\n return `path('M${pts.slice(0,-1).map(o).join('L')}Z${parts.join('')}')`;\r\n}\r\nfunction clipTo(dialog,pts,{from=null,ms=0,ease='ease'}={}){\r\n const go=()=>{if(framed?.dialog!==dialog)return;motion(dialog,ms?`clip-path ${ms}ms ${ease}`:'none');dialog.style.clipPath=clipFor(dialog,pts);};\r\n if(from){motion(dialog,'none');dialog.style.clipPath=clipFor(dialog,from);settle().then(go);}else go();\r\n}\r\nfunction lean(on){\r\n const f=framed;if(!f?.look.shaped||!f.dialog||f.leaned===on)return;\r\n f.leaned=on;const dialog=f.dialog;leanButton(dialog.querySelector('[data-peer-lean]'),on,f.look.label);\r\n dialog.classList.toggle('portal-leaned',on);\r\n layoutInCut(dialog,!on);\r\n clipTo(dialog,on?f.outlines.rect:f.outlines.shape,{ms:prefersReducedMotion()?0:520,ease:'cubic-bezier(.3,0,.2,1)'});\r\n showAura(on?{...f.look,pts:rectPts(f.face),shaped:false}:f.look,'lean');\r\n}\r\nfunction leanButton(step,on,label){if(!step)return;step.setAttribute('aria-pressed',String(on));step.setAttribute('aria-label',`${on?'Step back from':'Step in to'} ${label}`);step.textContent=on?'⤡':'⤢';}\r\n// #132: a whole window's name rides its upper rail, drawn left to right so it reads upright (the bottom rail is occupied by\r\n// the physical dock). R7: a cut carries none.\r\nconst d2=v=>(+v).toFixed(1);\r\nconst pathD=pts=>`M${pts.slice(0,-1).map(([x,y])=>d2(x)+' '+d2(y)).join('L')}Z`;\r\nexport function namePath(face,gap=7){const y=d2(face.top-gap);return `M${d2(face.left)} ${y}L${d2(face.left+face.width)} ${y}`;}\r\n\r\n// ---- #134 the energy round the open destination ---------------------------------------------------------------------\r\n// Ian 23 Sept: \"a vignetted colourful energy around the edge of the menu, in the shape of the portal that leads to it, but\r\n// not covering the menus\". The six neons flow round the window's outline with the shape's colour leading, as #130's\r\n// Portal-style rim: round fire tongues, a burst on open and a fizzle on close. It never covers the menu: the colour sits\r\n// in a band on the window's edge, outward over the quilt (or the frame's rail) and inward only as a faint vignette that\r\n// is gone within ~20 px (inside the menus' own padding); nothing in it takes a pointer, and the name (#132) rides outside\r\n// the window. Built from masks drawn once; the flow is a conic gradient turning inside them by transform, so running it\r\n// costs the compositor, not a repaint. Static under reduced motion.\r\nconst AURA={spinMs:16000,flickerMs:1300,sparks:18,sparkMs:800,specPx:40,maskScale:.5,\r\n // R21 L2: the inward feather fades over featherFrac of the face's short side (was ~36px) at featherAlpha peak (was .9 stacked), shadeK scales the dark depth strokes, fullFrac/fullAlpha are the same for full-screen faces, fullCurve the falloff exponent (2 = ease-out, most of it near the edge), railAlpha the faint glow left on their rail (was solid).\r\n edgeAlpha:.5,featherFrac:.3,featherAlpha:.3,fullFrac:.2,fullAlpha:.2,fullCurve:2,railAlpha:.15,shadeK:.4,outK:.5,ringAlpha:.5,inset:12}; // outK scales the outward glow bands past the first; ringAlpha is the rim's own peak opacity (was .9); inset pulls shaped windows in from the face edge (px)\r\nlet aura=null;\r\n// White-on-clear mask of the rim band: an inward vignette (clipped inside the outline), an outward glow (outside it) with\r\n// round fire tongues (a seeded dash rhythm on a wide round-capped stroke). A soft glow needs no detail, so it's drawn once\r\n// on a canvas at AURA.maskScale and handed over as a PNG: an SVG mask re-rasterised at the screen's full density cost\r\n// hundreds of ms on the first frame. The hot rim line is a crisp stroke in the aura's own svg instead.\r\nfunction rimMask(pts,w,h,seed,shaped,fullscreen=false,face=null){\r\n const k=AURA.maskScale,c=document.createElement('canvas');c.width=Math.ceil(w*k);c.height=Math.ceil(h*k);\r\n const g=c.getContext('2d',{willReadFrequently:true}),path=new Path2D(pathD(pts)),outside=new Path2D(`M0 0H${w}V${h}H0Z${pathD(pts)}`);\r\n let s=seed;const r=()=>(s=(s*16807)%2147483647)/2147483647,dash=(a,b)=>Array.from({length:12},()=>[a*(.3+r()),b*(.6+r())]).flat();\r\n g.scale(k,k);g.strokeStyle='#fff';g.lineJoin='round';\r\n const band=(width,alpha,dashes=null,cap='butt')=>{g.lineWidth=width;g.globalAlpha=alpha;g.lineCap=cap;g.setLineDash(dashes||[]);g.stroke(path);};\r\n g.save();if(face)g.clip(new Path2D(`M${face.left} ${face.top}h${face.width}v${face.height}h${-face.width}Z`)); // never over the rail, bolts or corners\r\n g.clip(outside,'evenodd');\r\n if(fullscreen){\r\n   const image=g.createImageData(c.width,c.height),smooth=t=>t*t*(3-2*t),xs=pts.map(p=>p[0]),ys=pts.map(p=>p[1]),bx=Math.min(...xs),by=Math.min(...ys),bx2=Math.max(...xs),by2=Math.max(...ys),rail=Math.max(1,Math.min(bx,by,w-bx2,h-by2));\r\n   for(let y=0;y<c.height;y++)for(let x=0;x<c.width;x++){\r\n    const X=x/k,Y=y/k,dx=Math.max(bx-X,0,X-bx2),dy=Math.max(by-Y,0,Y-by2),d=Math.hypot(dx,dy),alpha=(d==0||d>=rail)?0:Math.round(255*AURA.railAlpha*(1-smooth(d/rail))**.8),i=4*(y*c.width+x);\r\n    image.data[i]=image.data[i+1]=image.data[i+2]=255;image.data[i+3]=alpha;\r\n   }\r\n   g.putImageData(image,0,0);\r\n  }\r\n  else if(shaped){for(const [a,b] of [[5,.9],[12,.5],[24,.26],[42,.11],[66,.04]])band(a,a===5?AURA.ringAlpha:b*AURA.outK);band(24,.3,dash(5,44),'round');g.lineDashOffset=r()*60;band(14,.5,dash(3,30),'round');}\r\n else{for(const [a,b] of [[5,.85],[11,.4],[18,.16]])band(a,a===5?AURA.ringAlpha:b*AURA.outK);band(11,.32,dash(3,26),'round');}\r\n g.restore();\r\n // Last: the full-screen glow is a putImageData, which overwrites every pixel it covers, so the inward feather goes on top of it.\r\n g.save();g.clip(path);\r\n {const px=pts.map(p=>p[0]),py=pts.map(p=>p[1]),short=Math.min(Math.max(...px)-Math.min(...px),Math.max(...py)-Math.min(...py)),\r\n   D=short*(fullscreen?AURA.fullFrac:AURA.featherFrac),peak=fullscreen?AURA.fullAlpha:AURA.featherAlpha,n=10;\r\n  for(let i=0;i<n;i++)band(2*D*(1-i/n)**(fullscreen?AURA.fullCurve:1),peak/n); // stacked strokes: opacity falls off linearly from the rim to D inside\r\n  band(4,AURA.edgeAlpha);} // the thin bright neon edge that still reads as a portal\r\n g.restore();\r\n return `url(\"${c.toDataURL()}\")`;\r\n}\r\nconst setMask=(el,url)=>{el.style.webkitMaskImage=url;el.style.maskImage=url;};\r\nfunction hideAura(){aura?.anims.forEach(a=>a.cancel());aura?.el.remove();aura=null;}\r\n// Closing: the rim fizzles (burst) and goes out, so nothing but the frame rides the way back.\r\nfunction auraOut(){\r\n burst('close');const a=aura;if(!a)return;aura=null;\r\n a.el.animate([{opacity:1},{opacity:0}],{duration:prefersReducedMotion()?0:420,easing:'ease-in',fill:'forwards'}).finished.then(()=>{a.anims.forEach(x=>x.cancel());a.el.remove();},()=>{});\r\n}\r\nfunction showAura(look,why='open'){\r\n hideAura();\r\n if(!look?.pts)return;\r\n const w=Math.max(1,chrome.clientWidth),h=Math.max(1,chrome.clientHeight),d=pathD(look.pts),[cx,cy]=centroidOf(look.pts),strip=readLook().strip,seq=stripSeq(strip),reduced=prefersReducedMotion();\r\n const xs=look.pts.map(p=>p[0]),ys=look.pts.map(p=>p[1]),bx=Math.min(...xs),by=Math.min(...ys),bw=Math.max(...xs)-bx,bh=Math.max(...ys)-by;\r\n const el=document.createElement('div');el.className='portal-aura';el.setAttribute('aria-hidden','true');el.classList.toggle('shaped',!!look.shaped);\r\n el.style.cssText=`--aura:${strip};--aura-edge:color-mix(in srgb,${strip} 45%,#fff);--aura-seq:${[...seq,seq[0]].join(',')};--cx:${d2(cx)}px;--cy:${d2(cy)}px`;\r\n const label=look.id==='down'?'':String(look.label||'').toUpperCase().replace(/[<&>]/g,''); // Achievements already titles the scene inside the cut.\r\n // One static svg (the aperture's depth inside the outline, the name outside it) and one masked layer holding the\r\n // flow: two neon wheels turning against each other (the second flickering, for the fire) and the specular blob.\r\n el.innerHTML=`<svg viewBox=\"0 0 ${w} ${h}\" preserveAspectRatio=\"none\"><defs><path id=\"portalAuraP\" d=\"${d}\"/><clipPath id=\"portalAuraIn\"><use href=\"#portalAuraP\"/></clipPath>${look.name?`<path id=\"portalAuraName\" d=\"${look.name}\"/>`:''}</defs><g clip-path=\"url(#portalAuraIn)\" fill=\"none\" stroke-linejoin=\"round\"><use href=\"#portalAuraP\" stroke=\"#07040b\" stroke-opacity=\"${d2(.2*AURA.shadeK)}\" stroke-width=\"34\"/><use href=\"#portalAuraP\" stroke=\"#07040b\" stroke-opacity=\"${d2(.28*AURA.shadeK)}\" stroke-width=\"15\"/><use href=\"#portalAuraP\" stroke=\"#fff\" stroke-opacity=\".6\" stroke-width=\"2.4\"/></g><use href=\"#portalAuraP\" fill=\"none\" stroke=\"var(--aura-edge)\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>`\r\n  +(label&&look.name?`<text class=\"portal-aura-name\"><textPath href=\"#portalAuraName\" startOffset=\"50%\" text-anchor=\"middle\">${label}</textPath></text>`:'')+'</svg>'\r\n  +'<i class=\"portal-aura-fire\"><i></i><i class=\"b\"></i><i class=\"portal-aura-spec\"></i></i>';\r\n const fire=el.querySelector('.portal-aura-fire'),[wa,wb,blob]=fire.children;\r\n const fl=parseFloat(chrome.style.getPropertyValue('--face-left')),ft=parseFloat(chrome.style.getPropertyValue('--face-top')),fw=parseFloat(chrome.style.getPropertyValue('--face-width')),fh=parseFloat(chrome.style.getPropertyValue('--face-height')),\r\n  face=[fl,ft,fw,fh].every(Number.isFinite)?{left:fl,top:ft,width:fw,height:fh}:null;\r\n setMask(fire,rimMask(look.pts,w,h,7,look.shaped,look.fullscreen,look.fullscreen?null:face)); // full-screen faces keep their deliberate rail glow (R19)\r\n const R=Math.max(bw,bh)*.45,far=Math.ceil(Math.max(...[[0,0],[w,0],[0,h],[w,h]].map(([x,y])=>Math.hypot(x-cx,y-cy))));\r\n blob.style.cssText=`left:${d2(bx+bw*.2-R/2)}px;top:${d2(by+bh*.14-R/2)}px;width:${d2(R)}px;height:${d2(R)}px`;\r\n for(const wheel of [wa,wb])wheel.style.cssText=`left:${d2(cx-far)}px;top:${d2(cy-far)}px;width:${2*far}px;height:${2*far}px`;\r\n chrome.append(el);\r\n aura={el,look,spec:blob,anims:[]};\r\n if(reduced)return;\r\n aura.anims.push(wa.animate([{transform:'rotate(0deg)'},{transform:'rotate(360deg)'}],{duration:AURA.spinMs,iterations:Infinity}),\r\n  wb.animate([{transform:'rotate(360deg)'},{transform:'rotate(0deg)'}],{duration:AURA.spinMs*.62,iterations:Infinity}),\r\n  wb.animate([{opacity:.15},{opacity:.7}],{duration:AURA.flickerMs,iterations:Infinity,direction:'alternate',easing:'ease-in-out'}),\r\n  el.animate([{opacity:0},{opacity:1}],{duration:why==='open'?420:260,easing:'ease-out'}));\r\n if(why==='open')burst('open');\r\n}\r\n// #130's open burst / close fizzle: a white flash along the rim and sparks flying off it (open) or falling into the\r\n// core (close). Compositor-only (transform and opacity), gone in under a second.\r\nfunction burst(kind){\r\n if(!aura||prefersReducedMotion())return;\r\n const {el,look}=aura,pts=look.pts,[cx,cy]=centroidOf(pts),close=kind==='close';\r\n const flash=document.createElement('i');flash.className='portal-aura-flash';setMask(flash,el.querySelector('.portal-aura-fire').style.maskImage);el.append(flash);\r\n flash.animate([{opacity:close?.6:.95},{opacity:0}],{duration:close?420:620,easing:'ease-out',fill:'forwards'}).finished.then(()=>flash.remove(),()=>flash.remove());\r\n for(let k=0;k<AURA.sparks;k++){\r\n  const i=Math.floor(Math.random()*(pts.length-1)),f=Math.random(),x=pts[i][0]+(pts[i+1][0]-pts[i][0])*f,y=pts[i][1]+(pts[i+1][1]-pts[i][1])*f;\r\n  const dx=x-cx,dy=y-cy,l=Math.hypot(dx,dy)||1,go=(close?-1:1)*(16+Math.random()*48),b=document.createElement('b');\r\n  b.style.left=d2(x)+'px';b.style.top=d2(y)+'px';b.style.background=k%3?'#fff':look.color;el.append(b);\r\n  b.animate([{transform:'translate(0,0) scale(1)',opacity:1},{transform:`translate(${d2(dx/l*go)}px,${d2(dy/l*go)}px) scale(.2)`,opacity:0}],{duration:AURA.sparkMs*(.55+Math.random()*.6),easing:'cubic-bezier(.2,.7,.3,1)',fill:'forwards'}).finished.then(()=>b.remove(),()=>b.remove());\r\n }\r\n}\r\n\r\n// ---- #135 #126 looking round the scene behind the window ------------------------------------------------------------\r\n// The eye follows the phone's tilt from a baseline caught when the destination opens (createTiltLook: gravity-based,\r\n// clamped, smoothed here, and re-centring on whatever hold the phone settles at; knobs in character-phone-sensor TILT), or, on flat menus with no tilt, a finger drag\r\n// (springing back on release). It slides each destination's layers against the fixed frame (depths below) and drives the\r\n// 3D scenes' off-axis cameras through peer.mjs. iOS asks once, from a chip on the first 3D destination (never a modal),\r\n// and the answer is kept. Off under reduced motion and in camera-only mode (D24); paused while the page is hidden.\r\n// dead (R7, Ian's Android): a new reading must move the eye by this share of full tilt (about half a degree) or it is\r\n// sensor noise and ignored, so a phone held still lets the look-around stop instead of restyling every frame.\r\nconst PEER={smoothMs:110,dragPx:160,dead:.04};\r\nconst peerTilt=createTiltLook();\r\nconst TILT_KEY='myr5.tiltPermission';\r\n// Any framed destination can mark its own layers data-peer-depth=\"far|mid|near\": they slide PEER_LAYER px at full tilt\r\n// (far with the eye, near against it), times the destination's strength; the dialog also carries --peer-x/--peer-y\r\n// (-1..1) while a flat menu sits in a cut (.portal-inset, the only CSS that reads them: on anything else they would restyle\r\n// the whole menu every frame). Per destination: move: px the whole dialog slides (flat menus, a third of the scenes' range);\r\n// layers: [selector,px] for destinations that don't mark theirs (nested ones add up); scene: a 3D scene reading peer.mjs\r\n// (no drag look-around: a drag there turns the scene; it fills its cut, see shapeDialog); chip: offer iOS's tilt\r\n// permission (the scenes always do); cards/fit: shapeDialog.\r\nconst PEER_LAYER={far:14,mid:5,near:-4};\r\nconst PEER_DEPTH=[\r\n ['#accountPanel.classroom-panel',{scene:true}],\r\n ['#mealsPanel',{scene:true,cards:'.pyramid-zoom,#foodDial,#mealConfirmation',fit:{sel:'#pyramidScanner',band:[0,1]}}],\r\n ['#remindersPanel',{scene:true,layers:[['.reminders-computer-stage',8],['.reminders-computer-screen',3]]}],\r\n ['dialog.ship-view',{scene:true,layers:[['.ship-view-bg',16],['.ship-view-coach',5]]}],\r\n // The constellation's bosses (7.5-90% of the art's height) span the cut: its top row along the inverted triangle's top.\r\n ['.ach-board',{scene:true,layers:[['.ach-stage',10],['.ach-stars',-4]],cards:'.ach-detail',fit:{sel:'.ach-stage',band:[.075,.9]}}],\r\n   ['#battlePassPanel',{move:2,strength:.6,chip:true,layers:[['.pass-map-shell',8]]}],\r\n   ['#library',{move:2,strength:.6,chip:true,layers:[['#holoStage',8],['.movement-cards',4]]}],\r\n   ['#spotifyPanel',{move:2,strength:.6,chip:true}],\r\n ['#coachPathPicker',{move:2,strength:.6,chip:true}],\r\n   ['.meditation-panel',{move:2,strength:.6,chip:true}], // #127: the still room peers in too, gentler\r\n];\r\nconst PEER_2D={move:4};\r\nconst peer={dialog:null,cfg:null,els:[],depths:[],flatEls:[],x:0,y:0,tx:0,ty:0,raf:0,last:0,drag:null,sensor:false,ctl:null,watch:null};\r\nconst clamp1=v=>Math.max(-1,Math.min(1,v));\r\nfunction tiltAccess(){\r\n if(typeof DeviceOrientationEvent==='undefined')return 'none';\r\n if(typeof DeviceOrientationEvent.requestPermission!=='function')return 'free';\r\n try{return localStorage.getItem(TILT_KEY)||'ask';}catch{return 'ask';}\r\n}\r\nfunction peerOn(dialog){\r\n peerOff();\r\n if(prefersReducedMotion()||document.body.dataset.cameraWorkout==='true')return;\r\n const cfg=peerCfg(dialog),signal=(peer.ctl=new AbortController()).signal;\r\n Object.assign(peer,{dialog,cfg,x:0,y:0,tx:0,ty:0,drag:null,sensor:false});peerTilt.reset();\r\n refreshPeerTargets(dialog,cfg);\r\n peer.watch=new MutationObserver(()=>{if(peer.dialog!==dialog)return;refreshPeerTargets(dialog,cfg);kickPeer();});\r\n peer.watch.observe(dialog,{subtree:true,childList:true,attributes:true,attributeFilter:['data-peer-depth']});\r\n const access=tiltAccess();\r\n if(access==='free'||access==='granted')addEventListener('deviceorientation',onOrient,{signal});\r\n else if(access==='ask'&&(cfg.scene||cfg.chip))tiltChip(dialog);\r\n if(!cfg.scene&&!dialog.classList.contains('portal-fullscreen')){ // a full-screen room keeps its own drag (meditation's)\r\n  dialog.addEventListener('pointerdown',e=>{if(e.pointerType==='touch'&&!peer.sensor)peer.drag={x:e.clientX,y:e.clientY,id:e.pointerId};},{signal,passive:true});\r\n  dialog.addEventListener('pointermove',e=>{const g=peer.drag;if(g?.id!==e.pointerId)return;peer.tx=clamp1((e.clientX-g.x)/PEER.dragPx);peer.ty=clamp1((e.clientY-g.y)/PEER.dragPx);kickPeer();},{signal,passive:true});\r\n  for(const type of ['pointerup','pointercancel'])dialog.addEventListener(type,e=>{if(peer.drag?.id===e.pointerId){peer.drag=null;peer.tx=peer.ty=0;kickPeer();}},{signal,passive:true});\r\n }\r\n if(framed?.direct){\r\n  dialog.addEventListener('pointermove',e=>{if(peer.sensor||document.hidden)return;const r=dialog.getBoundingClientRect();peer.tx=clamp1((e.clientX-r.left-r.width/2)/(r.width*.45));peer.ty=clamp1((e.clientY-r.top-r.height/2)/(r.height*.45));kickPeer();},{signal,passive:true});\r\n  dialog.addEventListener('pointerleave',()=>{if(!peer.sensor){peer.tx=peer.ty=0;kickPeer();}},{signal,passive:true});\r\n }\r\n document.addEventListener('visibilitychange',()=>{peerTilt.reset();if(document.hidden){cancelAnimationFrame(peer.raf);peer.raf=0;peer.last=0;}else kickPeer();},{signal});\r\n addEventListener('orientationchange',()=>peerTilt.reset(),{signal});\r\n}\r\nfunction peerOff(){\r\n peer.ctl?.abort();peer.ctl=null;peer.watch?.disconnect();peer.watch=null;cancelAnimationFrame(peer.raf);peer.raf=0;\r\n const {dialog}=peer;\r\n if(dialog){\r\n  for(const k of ['left','top','--peer-x','--peer-y'])dialog.style.removeProperty(k);\r\n  dialog.querySelector(':scope>.portal-peer-ui>.portal-tilt-chip')?.remove();\r\n  for(const el of dialog.querySelectorAll('[data-peer-depth]'))el.style.translate='';\r\n }\r\n for(const [el] of peer.els)el.style.translate='';\r\n for(const el of peer.flatEls)el.style.translate='';\r\n Object.assign(peer,{dialog:null,cfg:null,els:[],depths:[],flatEls:[],x:0,y:0,tx:0,ty:0,last:0,drag:null,sensor:false});eye.x=eye.y=0;\r\n if(aura?.spec)aura.spec.style.translate='';\r\n}\r\nfunction refreshPeerTargets(dialog=peer.dialog,cfg=peer.cfg){\r\n if(!dialog||!cfg)return;\r\n peer.els=(cfg.layers||[]).flatMap(([s,px])=>[...dialog.querySelectorAll(s)].map(el=>[el,px]));\r\n peer.depths=[...dialog.querySelectorAll('[data-peer-depth]')];\r\n peer.flatEls=framed?.direct&&dialog.classList.contains('portal-fullscreen')&&!cfg.scene\r\n  ?[...dialog.children].filter(el=>el.id!=='coachDock'&&!el.matches('.portal-peer-ui')):[];\r\n}\r\nfunction onOrient(e){\r\n if(!peer.dialog)return;\r\n const t=peerTilt.read(e,performance.now());if(!t)return;\r\n peer.sensor=true;peer.drag=null;\r\n const dG=t.x,dB=t.y;\r\n if(Math.abs(dG-peer.tx)+Math.abs(dB-peer.ty)<PEER.dead)return;\r\n // As through a real window: turn the phone's face to the left (its right edge back) and the eye is now to the window's\r\n // right, so the pyramid shows its right side (Ian); tip the top edge back and the eye drops below it.\r\n peer.tx=dG;peer.ty=dB;kickPeer();\r\n}\r\n// Each run of steps (until the eye settles) looks its depth layers up once: a scene may add layers after it opens.\r\nfunction kickPeer(){if(!peer.raf&&peer.dialog&&!document.hidden){if(!peer.last){peer.last=performance.now();refreshPeerTargets();}peer.raf=requestAnimationFrame(stepPeer);}}\r\nfunction stepPeer(now){\r\n peer.raf=0;\r\n const k=1-Math.exp(-Math.max(0,now-peer.last)/PEER.smoothMs);peer.last=now; // low-pass by time, the same at any frame rate\r\n peer.x+=(peer.tx-peer.x)*k;peer.y+=(peer.ty-peer.y)*k;\r\n if(Math.abs(peer.tx-peer.x)+Math.abs(peer.ty-peer.y)<.002){peer.x=peer.tx;peer.y=peer.ty;peer.last=0;}else kickPeer();\r\n const {x,y,cfg,dialog}=peer;if(!dialog)return;\r\n eye.x=x;eye.y=y;\r\n const full=dialog.classList.contains('portal-fullscreen');\r\n if(cfg.move&&framed?.face&&!framed.look.shaped&&!full){dialog.style.setProperty('left',d2(framed.face.left+x*cfg.move)+'px','important');dialog.style.setProperty('top',d2(framed.face.top+y*cfg.move)+'px','important');}\r\n if(dialog.classList.contains('portal-inset')){dialog.style.setProperty('--peer-x',x.toFixed(3));dialog.style.setProperty('--peer-y',y.toFixed(3));}\r\n const slide=(el,px)=>{el.style.translate=`${d2(x*px)}px ${d2(y*px)}px`;};\r\n for(const [el,px] of peer.els)slide(el,px);\r\n for(const el of peer.depths)slide(el,(PEER_LAYER[el.dataset.peerDepth]||0)*(cfg.strength??1));\r\n for(const el of peer.flatEls)slide(el,cfg.move||PEER_2D.move);\r\n if(aura?.spec)aura.spec.style.translate=`${d2(-x*AURA.specPx)}px ${d2(-y*AURA.specPx)}px`;\r\n}\r\n// iOS 13+: DeviceOrientationEvent.requestPermission() needs a tap. A small chip in the window's corner, never a modal.\r\nfunction tiltChip(dialog){\r\n const chip=document.createElement('button'),f=framed?.face;chip.type='button';chip.className='portal-tilt-chip';chip.innerHTML='Tilt to look around <b>Allow</b>';\r\n if(f){\r\n  const dockEl=document.getElementById('coachDock'),dock=dockEl?.getClientRects().length?dockEl.getBoundingClientRect():null;\r\n  chip.style.left=f.left+8+'px';\r\n  chip.style.top=Math.max(f.top+8,Math.min(f.top+f.height-26,dock?.top==null?Infinity:dock.top-26))+'px'; // R19: a slim tab sitting on the dock's top edge, left side (meditation's counter chip is bottom-right)\r\n }\r\n chip.onclick=async()=>{\r\n  let answer='denied';try{answer=await DeviceOrientationEvent.requestPermission();}catch{}\r\n  try{localStorage.setItem(TILT_KEY,answer==='granted'?'granted':'denied');}catch{}\r\n  chip.remove();\r\n  if(answer==='granted'&&peer.dialog===dialog)addEventListener('deviceorientation',onOrient,{signal:peer.ctl.signal});\r\n };\r\n peerUi(dialog).append(chip); // hidden while a scene is peered at (portal.css): full screen offers it\r\n}\r\nfunction status(text,action=null){\r\n statusEl.textContent=text;\r\n const button=portalHome?.querySelector('#portalRetry');\r\n if(button){button.hidden=!action;button.textContent=action?.label||'';button._run=action?.run||null;}\r\n}\r\n\r\n// Layout size, not the on-screen box: the observer also fires as the portal is shown mid-dive (scaled), and a backing\r\n// store sized from the scaled box drew every later trail and outline shrunk toward the corner.\r\nfunction resizeOverlay(){\r\n const dpr=Math.min(devicePixelRatio||1,2),r={width:overlay.clientWidth,height:overlay.clientHeight};\r\n overlay.width=Math.round(Math.max(1,r.width)*dpr);overlay.height=Math.round(Math.max(1,r.height)*dpr);\r\n ctx.setTransform(dpr,0,0,dpr,0,0);\r\n}\r\nfunction mapOverlayClientSpace(){\r\n const dpr=Math.min(devicePixelRatio||1,2),r=overlay.getBoundingClientRect(),w=overlay.clientWidth||1,h=overlay.clientHeight||1,sx=w/Math.max(1,r.width),sy=h/Math.max(1,r.height);\r\n ctx.setTransform(dpr*sx,0,0,dpr*sy,-r.left*dpr*sx,-r.top*dpr*sy);\r\n}\r\nfunction strokeGlow(pts,color,alpha,width){\r\n if(pts.length<2)return;\r\n ctx.save();ctx.globalAlpha=alpha;ctx.lineCap='round';ctx.lineJoin='round';\r\n ctx.shadowColor=color;ctx.shadowBlur=18;ctx.strokeStyle=color;ctx.lineWidth=width+4;\r\n ctx.beginPath();pts.forEach(([x,y],i)=>i?ctx.lineTo(x,y):ctx.moveTo(x,y));ctx.stroke();\r\n ctx.shadowBlur=0;ctx.strokeStyle='#fff';ctx.lineWidth=Math.max(1,width-2);ctx.stroke();\r\n ctx.restore();\r\n}\r\nfunction touchDot(x,y,color){\r\n ctx.save();const g=ctx.createRadialGradient(x,y,0,x,y,20);g.addColorStop(0,color+'cc');g.addColorStop(1,color+'00');\r\n ctx.fillStyle=g;ctx.beginPath();ctx.arc(x,y,20,0,Math.PI*2);ctx.fill();ctx.restore();\r\n}\r\nfunction kickRender(){if(!rafId&&!probeFrozen)rafId=requestAnimationFrame(drawFrame);}\r\n\r\n// #105 magical trail (W2-2E2). Colour flows through TRAIL_NEONS once every TRAIL_NEON_PX of stroke length (anchored\r\n// to where the finger went, drifting slowly toward the tip); alpha follows each point's age, eased so it holds\r\n// near full strength before it fades. Normal source-over throughout: additive washes out on the light quilt.\r\nconst TRAIL_NEON_PX=48,TRAIL_STOP_PX=12,TRAIL_MAX_STOPS=64,SHIMMER_MS=450;\r\nconst TAU=Math.PI*2,UNDERGLOW=[16,8,28],WHITE=[255,255,255];\r\nfunction neonRGB(t){\r\n const n=TRAIL_NEON_RGB.length,i=((Math.floor(t)%n)+n)%n,j=(i+1)%n,f=t-Math.floor(t);\r\n const[r1,g1,b1]=TRAIL_NEON_RGB[i],[r2,g2,b2]=TRAIL_NEON_RGB[j];\r\n return[r1+(r2-r1)*f|0,g1+(g2-g1)*f|0,b1+(b2-b1)*f|0];\r\n}\r\nconst trailColor=(d,now)=>neonRGB((d+now*.06)/TRAIL_NEON_PX);\r\nconst fadeAlpha=age=>{const k=Math.min(1,Math.max(0,age/TRAIL_FADE_MS));return 1-k*k*(3-2*k);};\r\n// Fixed-size sparkle pool (typed arrays, ring-buffer cursor) so shedding dust never allocates. Each mote is a\r\n// 2–5px neon disc with a white centre on a soft dark backing (so it reads on beige), twinkling on its own\r\n// phase, drifting outward and slowing to a stop as it dies.\r\nconst SPARK_N=400,SPARK_LIFE=700;\r\nconst sparkX=new Float32Array(SPARK_N),sparkY=new Float32Array(SPARK_N),sparkVX=new Float32Array(SPARK_N),sparkVY=new Float32Array(SPARK_N),sparkSize=new Float32Array(SPARK_N),sparkHue=new Int8Array(SPARK_N),sparkBorn=new Float32Array(SPARK_N).fill(-1e9);\r\nlet sparkCursor=0;\r\nfunction spawnSpark(x,y,born){\r\n const i=sparkCursor;sparkCursor=(sparkCursor+1)%SPARK_N;\r\n const a=Math.random()*TAU,s=30+Math.random()*110,off=4+Math.random()*6; // born just off the point, heading out\r\n sparkX[i]=x+Math.cos(a)*off;sparkY[i]=y+Math.sin(a)*off;sparkVX[i]=Math.cos(a)*s;sparkVY[i]=Math.sin(a)*s;\r\n sparkSize[i]=1.4+Math.random()*1.1;sparkHue[i]=(Math.random()*TRAIL_NEONS.length)|0;sparkBorn[i]=born;\r\n}\r\n// Per live frame (self-capping: a slow frame rate sheds less): three motes off the fingertip, four scattered\r\n// along the last SHED_RECENT_MS of path.\r\nconst SHED_RECENT_MS=250;\r\nfunction shedSparks(pts,now){\r\n const last=pts.length-1,tip=pts[last];for(let k=0;k<3;k++)spawnSpark(tip.x,tip.y,now);\r\n let first=last;while(first>0&&now-pts[first-1].t<SHED_RECENT_MS)first--;\r\n if(first===last)return;\r\n for(let k=0;k<4;k++){const i=first+1+((Math.random()*(last-first))|0),f=Math.random(),a=pts[i-1],b=pts[i];spawnSpark(a.x+(b.x-a.x)*f,a.y+(b.y-a.y)*f,now);}\r\n}\r\nfunction sparksAlive(now){for(let i=0;i<SPARK_N;i++)if(now-sparkBorn[i]<SPARK_LIFE)return true;return false;}\r\n// Mote sprites, drawn once: a row of the six neons in one small canvas, so each mote is a single drawImage\r\n// from one source (which the canvas batches) instead of three path fills. Cell = soft dark backing, neon\r\n// disc at MOTE_NEON of the cell radius, white centre at MOTE_WHITE.\r\nconst MOTE_PX=20,MOTE_NEON=.68,MOTE_WHITE=.3;\r\nlet moteSprites=null;\r\nfunction motes(){\r\n if(moteSprites)return moteSprites;\r\n const c=document.createElement('canvas'),g=c.getContext('2d'),R=MOTE_PX/2;c.width=MOTE_PX*TRAIL_NEONS.length;c.height=MOTE_PX;\r\n TRAIL_NEONS.forEach((color,i)=>{\r\n  const x=i*MOTE_PX+R,disc=(r,style)=>{g.fillStyle=style;g.beginPath();g.arc(x,R,r,0,TAU);g.fill();};\r\n  const back=g.createRadialGradient(x,R,0,x,R,R);back.addColorStop(0,'rgba(16,8,28,.5)');back.addColorStop(1,'rgba(16,8,28,0)');\r\n  disc(R,back);disc(R*MOTE_NEON,color);disc(R*MOTE_WHITE,'#fff');\r\n });\r\n return moteSprites=c;\r\n}\r\nfunction drawSparks(now){\r\n const sprites=motes();\r\n ctx.save();\r\n for(let i=0;i<SPARK_N;i++){\r\n  const age=now-sparkBorn[i];if(age<0||age>=SPARK_LIFE)continue;\r\n  const life=age/SPARK_LIFE,drift=age/1000*(1-life/2),x=sparkX[i]+sparkVX[i]*drift,y=sparkY[i]+sparkVY[i]*drift+16*life*life;\r\n  const tw=.5+.5*Math.sin(age*.04+i*2.4),h=sparkSize[i]*(.8+.2*tw)/MOTE_NEON;\r\n  ctx.globalAlpha=(1-life*life)*(.55+.45*tw);\r\n  ctx.drawImage(sprites,sparkHue[i]*MOTE_PX,0,MOTE_PX,MOTE_PX,x-h,y-h,2*h,2*h);\r\n }\r\n ctx.restore();\r\n}\r\nfunction starPath(p,x,y,len,waist,rot){\r\n for(let k=0;k<8;k++){const a=rot+k*Math.PI/4,rr=k%2?waist:len,px=x+Math.cos(a)*rr,py=y+Math.sin(a)*rr;k?p.lineTo(px,py):p.moveTo(px,py);}\r\n p.closePath();\r\n}\r\n// Fingertip bloom + slowly turning star flare: a dark halo (so it reads on beige), a white-hot → neon bloom,\r\n// then a long and a short four-point star in one fill. A few fills per tip per frame, not per particle.\r\n// size scales the whole flare (the release shimmer reuses it as a smaller, faster-turning glint).\r\n// `rgb` is an [r,g,b] triple so rgba() stops can be built directly.\r\nfunction drawFlare(x,y,[r,g,b],alpha,now,size=1){\r\n const neon=a=>`rgba(${r},${g},${b},${a})`;\r\n ctx.save();ctx.globalAlpha=alpha;ctx.translate(x,y);ctx.scale(size,size);\r\n let grad=ctx.createRadialGradient(0,0,0,0,0,30);grad.addColorStop(0,'rgba(16,8,28,.3)');grad.addColorStop(1,'rgba(16,8,28,0)');\r\n ctx.fillStyle=grad;ctx.fillRect(-30,-30,60,60);\r\n grad=ctx.createRadialGradient(0,0,0,0,0,20);\r\n grad.addColorStop(0,'#fff');grad.addColorStop(.25,'rgba(255,255,255,.9)');grad.addColorStop(.5,neon(.75));grad.addColorStop(1,neon(0));\r\n ctx.fillStyle=grad;ctx.fillRect(-20,-20,40,40);\r\n const star=new Path2D(),rot=now/1200;starPath(star,0,0,28,3,rot);starPath(star,0,0,14,2.5,rot+Math.PI/4);\r\n grad=ctx.createRadialGradient(0,0,0,0,0,28);\r\n grad.addColorStop(0,'#fff');grad.addColorStop(.18,'#fff');grad.addColorStop(.45,neon(.95));grad.addColorStop(1,neon(0));\r\n ctx.fillStyle=grad;ctx.fill(star);\r\n ctx.restore();\r\n}\r\nconst pathLength=pts=>{let d=0;for(let i=1;i<pts.length;i++)d+=Math.hypot(pts[i].x-pts[i-1].x,pts[i].y-pts[i-1].y);return d;};\r\nconst ribbonPath=pts=>{const p=new Path2D();pts.forEach((pt,i)=>i?p.lineTo(pt.x,pt.y):p.moveTo(pt.x,pt.y));return p;};\r\n// Gradient stops every TRAIL_STOP_PX of arc length (interpolated inside long segments, capped at\r\n// TRAIL_MAX_STOPS so cost doesn't grow with point count), each placed at its projection on the tail→head\r\n// axis — the one line a canvas gradient follows — so colour and fade track the path for any stroke that\r\n// doesn't fold back past 90°. d0: stroke length already faded off the tail (keeps colours anchored).\r\nfunction ribbonSamples(pts,now,d0){\r\n const tail=pts[0],head=pts[pts.length-1],ax=head.x-tail.x,ay=head.y-tail.y,len2=ax*ax+ay*ay;\r\n if(len2<1)return null;\r\n const total=pathLength(pts),step=Math.max(TRAIL_STOP_PX,total/TRAIL_MAX_STOPS),stops=[];\r\n let d=0,next=0,off=0;\r\n for(let i=1;i<pts.length;i++){\r\n  const a=pts[i-1],b=pts[i],seg=Math.hypot(b.x-a.x,b.y-a.y);\r\n  while(next<=d+seg){\r\n   const f=seg?(next-d)/seg:0,x=a.x+(b.x-a.x)*f,y=a.y+(b.y-a.y)*f;\r\n   off=Math.max(off,Math.min(1,((x-tail.x)*ax+(y-tail.y)*ay)/len2));\r\n   stops.push({off,alpha:fadeAlpha(now-(a.t+(b.t-a.t)*f)),d:d0+next});next+=step;\r\n  }\r\n  d+=seg;\r\n }\r\n stops.push({off:1,alpha:fadeAlpha(now-head.t),d:d0+total});\r\n return{tail,head,stops};\r\n}\r\nfunction ribbonGradient({tail,head,stops},colorAt){\r\n const g=ctx.createLinearGradient(tail.x,tail.y,head.x,head.y);\r\n for(const s of stops){const[r,gg,b]=colorAt(s.d);g.addColorStop(s.off,`rgba(${r},${gg},${b},${s.alpha.toFixed(3)})`);}\r\n return g;\r\n}\r\n// Full-motion trail: six stroke() passes over one Path2D (no shadows, so cost doesn't scale with point\r\n// count) — a soft dark underglow so the neon pops on the light quilt, a wide soft two-step neon glow, a\r\n// vivid core, a white-hot centre — then the tip flare. `live` also sheds dust; a just-released trail (in\r\n// `fading`) keeps rendering with no new tip dust until it ages out.\r\nfunction renderRibbon(pts,now,live){\r\n let start=0,d0=0;\r\n while(start<pts.length-1&&now-pts[start].t>=TRAIL_FADE_MS){d0+=Math.hypot(pts[start+1].x-pts[start].x,pts[start+1].y-pts[start].y);start++;}\r\n if(now-pts[start].t>=TRAIL_FADE_MS)return;\r\n const visible=start?pts.slice(start):pts,tip=visible[visible.length-1];\r\n const samples=visible.length>1&&ribbonSamples(visible,now,d0);\r\n if(samples){\r\n  const path=ribbonPath(visible),dark=ribbonGradient(samples,()=>UNDERGLOW),neon=ribbonGradient(samples,d=>trailColor(d,now)),hot=ribbonGradient(samples,()=>WHITE);\r\n  ctx.save();ctx.lineCap='round';ctx.lineJoin='round';\r\n  const pass=(style,alpha,width)=>{ctx.strokeStyle=style;ctx.globalAlpha=alpha;ctx.lineWidth=width;ctx.stroke(path);};\r\n  pass(dark,.08,40);pass(dark,.12,32); // soft dark underglow\r\n  pass(neon,.3,26);pass(neon,.42,17); // wide soft glow\r\n  pass(neon,1,6.5); // vivid core\r\n  pass(hot,1,1.5); // white-hot centre\r\n  ctx.restore();\r\n }\r\n drawFlare(tip.x,tip.y,trailColor(d0+pathLength(visible),now),Math.max(.35,fadeAlpha(now-tip.t)),now);\r\n if(live)shedSparks(visible,now);\r\n}\r\n// #105 release shimmer: a star glint sweeps the part of the path still lit at release, tail→tip, over\r\n// SHIMMER_MS, shaking dust loose as it goes (so the last motes are gone ~SHIMMER_MS+SPARK_LIFE after release).\r\nfunction shimmerPoint({pts,releasedAt},now){\r\n const k=(now-releasedAt)/SHIMMER_MS;if(k<0||k>1)return null;\r\n let i=0,d=0;\r\n while(i<pts.length-1&&releasedAt-pts[i].t>=TRAIL_FADE_MS){d+=Math.hypot(pts[i+1].x-pts[i].x,pts[i+1].y-pts[i].y);i++;}\r\n let left=k*pathLength(pts.slice(i));d+=left;\r\n for(;i<pts.length-1;i++){\r\n  const a=pts[i],b=pts[i+1],seg=Math.hypot(b.x-a.x,b.y-a.y);\r\n  if(seg>=left){const f=seg?left/seg:0;return{x:a.x+(b.x-a.x)*f,y:a.y+(b.y-a.y)*f,d,k};}\r\n  left-=seg;\r\n }\r\n return{x:pts[i].x,y:pts[i].y,d,k};\r\n}\r\nfunction shimmerDust(entry,now){const s=shimmerPoint(entry,now);if(s){spawnSpark(s.x,s.y,now);spawnSpark(s.x,s.y,now);}return s;}\r\nfunction drawShimmer(entry,now){\r\n const s=shimmerDust(entry,now);if(s)drawFlare(s.x,s.y,trailColor(s.d,now),1-.4*s.k,now*2,.7);\r\n}\r\nfunction renderPlainTrail(pts,now){\r\n const trail=pts.filter(pt=>now-pt.t<TRAIL_FADE_MS).map(pt=>[pt.x,pt.y]);\r\n strokeGlow(trail,'#d8f6ff',1,4);\r\n const last=pts.at(-1);if(last&&now-last.t<TRAIL_FADE_MS)touchDot(last.x,last.y,'#d8f6ff');\r\n}\r\n// Test-only trail probe: exposed as myr5Portal.trailProbe only when a test sets window.__portalTrailProbe\r\n// before mount (the app never does). It drives the trail renderer directly, skipping the cloth-board press\r\n// that makes synthetic drags slower than the fade in headless runs, so frames show the trail at full strength.\r\nconst PROBE_ID=-1;\r\nlet probeFrozen=false;\r\nconst trailProbe={\r\n // Draws one frozen frame of `xy` ([[x,y],…]) swept over durationMs ending now (or releasedAgoMs ago), with\r\n // the dust those frames would have shed replayed at 60fps. Returns how many motes are alive. dust:false\r\n // draws the ribbon and tip alone, so a cross-section measures the strokes without motes drifting across it.\r\n draw(xy,{durationMs=350,releasedAgoMs=null,dust=true}={}){\r\n  cancelAnimationFrame(rafId);rafId=0;probeFrozen=true;clearTimeout(idleTimer);idleCycle=null;\r\n  const now=performance.now(),end=now-(releasedAgoMs??0),n=xy.length;\r\n  const pts=xy.map(([x,y],i)=>({x,y,t:end-durationMs*(1-i/Math.max(1,n-1))}));\r\n  sparkBorn.fill(-1e9);\r\n  if(!dust){ctx.save();ctx.setTransform(1,0,0,1,0,0);ctx.clearRect(0,0,overlay.width,overlay.height);ctx.restore();renderRibbon(pts,now,false);return 0;}\r\n  for(let ft=pts[0].t;ft<end;ft+=1000/60)shedSparks(pts.filter(p=>p.t<=ft),ft);\r\n  pointers.delete(PROBE_ID);fading.length=0;\r\n  if(releasedAgoMs==null)pointers.set(PROBE_ID,{pts,norm:[]});\r\n  else{const entry={pts,releasedAt:end};fading.push(entry);for(let ft=end;ft<now;ft+=1000/60)shimmerDust(entry,ft);}\r\n  drawFrame(0,now);\r\n  let alive=0;for(let i=0;i<SPARK_N;i++)if(now-sparkBorn[i]<SPARK_LIFE)alive++;\r\n  return alive;\r\n },\r\n // Live strokes (fps check): down/move/up like a finger, minus the cloth press and shape matching.\r\n down(x,y){probeFrozen=false;pointers.set(PROBE_ID,{pts:[{x,y,t:performance.now()}],norm:[]});scheduleIdle();kickRender();},\r\n move(x,y){pointers.get(PROBE_ID)?.pts.push({x,y,t:performance.now()});},\r\n up(){const p=pointers.get(PROBE_ID);pointers.delete(PROBE_ID);if(p?.pts.length>1)fading.push({pts:p.pts,releasedAt:performance.now()});scheduleIdle();kickRender();},\r\n resume(){probeFrozen=false;pointers.delete(PROBE_ID);fading.length=0;kickRender();},\r\n};\r\n\r\n// #104 idle ambient flash: which id is showing right now, and how strongly, given the time since the cycle began.\r\nfunction idleFrame(now){\r\n const elapsed=now-idleCycle.t0,dur=IDLE.slowMs,slot=dur+IDLE.gapMs,t=elapsed%slot;\r\n if(t>=dur)return null; // #133: the gap between shapes\r\n return{id:IDLE_ORDER[Math.floor(elapsed/slot)%IDLE_ORDER.length],alpha:Math.max(.12,.5*Math.min(1,t/60,(dur-t)/60))};\r\n}\r\n// Outline + label (+ arrow for a line) for one idle-flash entry; `rect` is the stitched-pattern rect.\r\nfunction idleShapeInfo(id,rect){\r\n if(id==='cross'){\r\n  const polys=SHAPES.cross.map(p=>toClientPts(p.points,rect));\r\n  return{polys,color:'#ffffff',label:MENUS['line-up'].label,labelPt:[rect.left+rect.width/2,rect.top+rect.height/2],arrow:null};\r\n }\r\n const menu=MENUS[id];\r\n if(id==='x'){\r\n  const polys=SHAPES.x.map(p=>toClientPts(p.points,rect));\r\n  return{polys,color:menu.color,label:menu.label,labelPt:polys[0][0],arrow:null};\r\n }\r\n if(LINE_IDS.has(id)){\r\n  const[a,b]=toClientPts(lineTemplatePts(id),rect),reversed=id==='line-rl'||id==='line-up',start=reversed?b:a,end=reversed?a:b;\r\n  return{polys:[[a,b]],color:menu.color,label:menu.label,labelPt:start,arrow:{from:start,to:end}};\r\n }\r\n const pts=shapeClipPts(id,rect);\r\n return{polys:[pts],color:menu.color,label:menu.label,labelPt:pts[0],arrow:null};\r\n}\r\nfunction drawArrow(from,to,color,alpha){\r\n const mx=(from[0]+to[0])/2,my=(from[1]+to[1])/2,ang=Math.atan2(to[1]-from[1],to[0]-from[0]),len=10;\r\n ctx.save();ctx.globalAlpha=alpha;ctx.strokeStyle=color;ctx.lineWidth=2;ctx.lineCap='round';ctx.shadowColor=color;ctx.shadowBlur=6;\r\n ctx.translate(mx,my);ctx.rotate(ang);\r\n ctx.beginPath();ctx.moveTo(-len,0);ctx.lineTo(len,0);ctx.moveTo(len-6,-5);ctx.lineTo(len,0);ctx.lineTo(len-6,5);ctx.stroke();\r\n ctx.restore();\r\n}\r\n// A bold, pill-backed label near the shape's start point, clear of the stroke and clamped inside the\r\n// board face with a 12px margin (conductor review 2026-09-23: the old plain small text ran off-board in\r\n// a corner). Flips to whichever side keeps it fully on-board rather than clipping.\r\nfunction drawLabel(text,[x,y],color,alpha,rect){\r\n ctx.save();ctx.font='700 15px system-ui,sans-serif';ctx.textBaseline='middle';\r\n const padX=9,padY=6,h=15+padY*2,w=ctx.measureText(text).width+padX*2,margin=12;\r\n const face=rect||fallbackRect();\r\n let lx=x+12,ly=y-14;\r\n if(lx+w>face.left+face.width-margin)lx=x-12-w;\r\n lx=Math.min(Math.max(lx,face.left+margin),face.left+face.width-margin-w);\r\n ly=Math.min(Math.max(ly,face.top+margin+h/2),face.top+face.height-margin-h/2);\r\n ctx.globalAlpha=alpha;\r\n ctx.fillStyle='rgba(8,5,14,.75)';\r\n ctx.beginPath();ctx.roundRect(lx,ly-h/2,w,h,h/2);ctx.fill();\r\n ctx.fillStyle=color;ctx.shadowColor=color;ctx.shadowBlur=6;\r\n ctx.fillText(text,lx+padX,ly+1);\r\n ctx.restore();\r\n}\r\nfunction drawIdleShape({polys,color,label,labelPt,arrow},alpha,width,rect,drawRouteLabel=true){\r\n polys.forEach(p=>strokeGlow(p,color,alpha,width));\r\n if(arrow)drawArrow(arrow.from,arrow.to,color,alpha);\r\n if(drawRouteLabel)drawLabel(label,labelPt,color,alpha,rect);\r\n}\r\nfunction drawIdle(now){\r\n const rect=board?board.patternRect():fallbackRect(),face=board?board.faceRect():rect;\r\n if(idleCycle.static){IDLE_ORDER.forEach(id=>drawIdleShape(idleShapeInfo(id,rect),.35,3,face,false));return;}\r\n const f=idleFrame(now);\r\n if(f)drawIdleShape(idleShapeInfo(f.id,rect),f.alpha,3,face);\r\n}\r\n\r\n// #22 first-run hint: a glowing fingertip traces the stitched square once, labelled, the first time the\r\n// quilt shows (never again once seen). localStorage is wrapped in try/catch — sandboxed frames and\r\n// private-mode Safari throw, and a blocked flag must never crash the hint (or nag every visit: on error we\r\n// act as if it's already been seen).\r\nfunction hintSeen(){try{return localStorage.getItem(HINT_KEY)==='1';}catch{return true;}}\r\nfunction markHintSeen(){try{localStorage.setItem(HINT_KEY,'1');}catch{}}\r\n// Points on a closed polyline from its start up to `frac` of the way around (arc-length, not index).\r\nfunction tracedPrefix(pts,frac){\r\n const segs=[];let total=0;\r\n for(let i=0;i<pts.length-1;i++){total+=segs[i]=Math.hypot(pts[i+1][0]-pts[i][0],pts[i+1][1]-pts[i][1]);}\r\n let left=frac*total,out=[pts[0]];\r\n for(let i=0;i<segs.length;i++){\r\n  if(segs[i]>=left){const f=segs[i]?left/segs[i]:0;const[ax,ay]=pts[i],[bx,by]=pts[i+1];out.push([ax+(bx-ax)*f,ay+(by-ay)*f]);break;}\r\n  left-=segs[i];out.push(pts[i+1]);\r\n }\r\n return out;\r\n}\r\n// Coordinates with idle flashing (COMMON): idleEligible() also checks `!hint` so the two never overlap;\r\n// starting/stopping the hint just re-runs scheduleIdle() to pick that up, without touching idle's own state.\r\nfunction maybeStartHint(){\r\n // Ian 2026-09-23: \"the magical finger is only for the quilt\" — same board-scoping as the trail above.\r\n if(hint||idleCycle||hintSeen()||boardId!=='quilt')return;\r\n hint={t0:performance.now()};\r\n scheduleIdle();kickRender();\r\n}\r\nfunction stopHint(){\r\n if(!hint)return;\r\n hint=null;\r\n scheduleIdle();\r\n}\r\nfunction drawHint(now){\r\n const rect=board?board.patternRect():fallbackRect(),face=board?board.faceRect():rect;\r\n const elapsed=now-hint.t0;\r\n if(elapsed>=HINT_MS){stopHint();return;} // one lap done: clear it through stopHint so idle re-arms too\r\n const pts=shapeClipPts('rect',rect),reduced=prefersReducedMotion();\r\n strokeGlow(pts,'#ffffff',.18,3);\r\n const prefix=reduced?pts:tracedPrefix(pts,elapsed/HINT_MS);\r\n strokeGlow(prefix,'#ffffff',.9,4);\r\n const tip=prefix[prefix.length-1];touchDot(tip[0],tip[1],'#ffffff');\r\n drawLabel('Trace to start your workout',pts[0],'#ffffff',.85,face);\r\n}\r\n\r\n// #20 tap as well as trace: nearest tappable shape outline to a client-px point, or null past TAP_HIT_PX.\r\n// Point-to-segment distance over each candidate's own closed outline (shapeClipPts), not nearest vertex, so\r\n// a 5-corner rect/diamond still hit-tests accurately along its straight edges.\r\nfunction distToPolyline(pt,pts){\r\n let best=Infinity;\r\n for(let i=0;i<pts.length-1;i++){\r\n  const[ax,ay]=pts[i],[bx,by]=pts[i+1],dx=bx-ax,dy=by-ay,len2=dx*dx+dy*dy;\r\n  const t=len2?Math.max(0,Math.min(1,((pt[0]-ax)*dx+(pt[1]-ay)*dy)/len2)):0;\r\n  best=Math.min(best,Math.hypot(pt[0]-(ax+dx*t),pt[1]-(ay+dy*t)));\r\n }\r\n return best;\r\n}\r\nfunction nearestTapShape(x,y){\r\n const rect=board?board.patternRect():fallbackRect();\r\n let bestId=null,bestDist=TAP_HIT_PX;\r\n for(const id of TAPPABLE_IDS){\r\n  const d=distToPolyline([x,y],shapeClipPts(id,rect));\r\n  if(d<=bestDist){bestDist=d;bestId=id;}\r\n }\r\n return bestId;\r\n}\r\n\r\n// now: the trail probe draws a frozen frame at a chosen time (rAF's own timestamp arrives first and is ignored).\r\nfunction drawFrame(_,now=performance.now()){\r\n // #104 risk 4: eligibility (no open dialog, tab visible, etc.) is otherwise only rechecked when the\r\n // cycle arms/starts, so a dialog opened over a running cycle (setup gate, a reward reveal) would keep\r\n // flashing underneath it. Catch that on the very next drawn frame instead.\r\n if(idleCycle&&!idleEligible())scheduleIdle();\r\n rafId=0;\r\n ctx.save();ctx.setTransform(1,0,0,1,0,0);ctx.clearRect(0,0,overlay.width,overlay.height);ctx.restore();\r\n mapOverlayClientSpace();\r\n if(outlineFlash){\r\n  const dur=outlineFlash.duration||350,t=now-outlineFlash.start;\r\n  if(t<dur){\r\n   const alpha=1-t/dur;\r\n   outlineFlash.polys.forEach(p=>strokeGlow(p,outlineFlash.color,alpha,4));\r\n   if(outlineFlash.label)drawLabel(outlineFlash.label,outlineFlash.labelPt,outlineFlash.color,Math.min(.6,alpha),board?board.faceRect():fallbackRect());\r\n  }else outlineFlash=null;\r\n }\r\n if(idleCycle)drawIdle(now);\r\n // Any active pointer — a real touch (wirePointerEvents' own pointerdown already calls stopHint()\r\n // synchronously, before this ever runs) or the test-only trailProbe's simulated one — ends the hint for\r\n // good; probeFrozen means trailProbe wants a clean frame with nothing else drawn on it.\r\n if(hint){if(pointers.size)stopHint();else if(!probeFrozen)drawHint(now);}\r\n if(phase?.pulse&&phase.pts)strokeGlow(phase.pts,phase.color,.4+.25*Math.sin((now-phase.t0)/280),3); // soft breathing outline while loading\r\n for(let i=fading.length-1;i>=0;i--)if(now-fading[i].pts.at(-1).t>=TRAIL_FADE_MS)fading.splice(i,1);\r\n const reduced=prefersReducedMotion();\r\n // Ian 2026-09-23: \"the magical finger is only for the quilt\" — other boards (ice, grass, cogs, jelly,\r\n // wood) bring their own touch effects, so the trail only draws while the mounted board is the quilt.\r\n if(boardId==='quilt'){\r\n  for(const p of pointers.values())reduced?renderPlainTrail(p.pts,now):renderRibbon(p.pts,now,true);\r\n  for(const entry of fading){\r\n   if(reduced){renderPlainTrail(entry.pts,now);continue;}\r\n   renderRibbon(entry.pts,now,false);drawShimmer(entry,now); // #105: a shimmer ripples along the path as it fades\r\n  }\r\n  if(!reduced)drawSparks(now);\r\n }\r\n if(pointers.size||fading.length||outlineFlash||(idleCycle&&!idleCycle.static)||(phase?.pulse)||(!reduced&&sparksAlive(now))||hint)kickRender();\r\n}\r\n// opts (#21 \"almost\"): {label,labelPt,duration} — a plain match flash stays the original quick 350ms\r\n// outline-only pulse; an \"almost\" flash carries a fading label and runs ~1.2s (ALMOST_MS below).\r\nfunction flashOutline(polys,color,opts){if(prefersReducedMotion())return;outlineFlash={polys,color,start:performance.now(),...opts};kickRender();}\r\n\r\n// #104: arms/disarms the idle cycle from every place eligibility can change (touch, sequence start/end,\r\n// show/hide, tab visibility). Always safe to call — it's a no-op when nothing needs to change.\r\nfunction idleEligible(){return boardShown&&!busy&&!hint&&pointers.size===0&&!document.hidden&&!document.querySelector('dialog[open]');}\r\nfunction scheduleIdle(){\r\n clearTimeout(idleTimer);idleTimer=0;\r\n if(idleCycle){idleCycle=null;kickRender();} // clears the drawn hint on the next frame\r\n if(idleEligible())idleTimer=setTimeout(beginIdleCycle,IDLE.armMs);\r\n}\r\nfunction beginIdleCycle(){\r\n idleTimer=0;\r\n if(!idleEligible())return;\r\n idleCycle=prefersReducedMotion()?{static:true}:{t0:performance.now()};\r\n kickRender();\r\n}\r\n\r\nfunction fallInAll([cx,cy]){\r\n const menus=Object.values(MENUS),n=menus.length,R=90;\r\n const els=menus.map((m,i)=>{\r\n  const a=(i/n)*Math.PI*2,el=document.createElement('div');el.className='portal-object';\r\n  el.style.left=(cx+Math.cos(a)*R)+'px';el.style.top=(cy+Math.sin(a)*R)+'px';\r\n  el.style.setProperty('--glow',m.color);el.innerHTML=m.icon;objectsLayer.append(el);return el;\r\n });\r\n return new Promise(resolve=>{\r\n  if(prefersReducedMotion()){els.forEach(el=>el.remove());resolve();return;}\r\n  settle().then(()=>{els.forEach(el=>{el.style.left=cx+'px';el.style.top=cy+'px';el.classList.add('falling');});setTimeout(()=>{els.forEach(el=>el.remove());resolve();},600);});\r\n });\r\n}\r\n// Neon wormhole under a liquid-glass slab (Ian 2026-09-23: \"a mix of colours with the apple glass effect\",\r\n// \"a wormhole with endless depth\"). One raw WebGL2 triangle fills a canvas the size of the glass box (the cut's\r\n// bounds + bleed): polar tunnel around the centroid, the six neons streaming inward as twisted rings with the\r\n// shape's colour leading, a glowing core and depth fog. The glass comes from a per-shape lens map: refraction\r\n// that bends the tunnel near the rim, chromatic fringe, a bright specular rim on the lit (top-left) edge, a softer\r\n// inner edge on the far side, frosting with boosted saturation and a light sweep.\r\nconst NEONS=['#ff5f1f','#ffff33','#39ff14','#1f51ff','#b026ff','#ff10f0']; // Ian's six, in hue order so neighbours mix clean\r\n// Ring colours down the tunnel: the shape's colour on about 40% of the rings, the other neons between; the cross is an even rainbow.\r\nexport function ringColours(color,all=false){\r\n if(all)return NEONS;\r\n const seq=[];NEONS.filter(c=>c!==color).forEach((c,i)=>{if(i%3!==2)seq.push(color);seq.push(c);});return seq;\r\n}\r\n// Lens map, one RGBA texel per GLASS.mapPx: rg = outward normal of the nearest rim edge, b = signed distance to the\r\n// rim (.5 on it, 1 at GLASS.bevel inside, 0 at GLASS.bevel outside). poly: closed, box-local CSS px.\r\nexport function lensMap(poly,w,h,px=GLASS.mapPx,bevel=GLASS.bevel){\r\n const mw=Math.max(1,Math.ceil(w/px)),mh=Math.max(1,Math.ceil(h/px)),data=new Uint8Array(mw*mh*4),P=Float64Array.from(poly.flat()),n=P.length-2;\r\n for(let j=0;j<mh;j++)for(let i=0;i<mw;i++){\r\n  const x=(i+.5)*px,y=(j+.5)*px;let best=Infinity,nx=0,ny=0,inside=false;\r\n  for(let k=0;k<n;k+=2){ // nearest point on each edge + even-odd crossing, in one pass (runs once per glass, at the cut)\r\n   const ax=P[k],ay=P[k+1],bx=P[k+2],by=P[k+3],dx=bx-ax,dy=by-ay,t=Math.max(0,Math.min(1,((x-ax)*dx+(y-ay)*dy)/(dx*dx+dy*dy||1))),qx=ax+t*dx-x,qy=ay+t*dy-y,d=qx*qx+qy*qy;\r\n   if(d<best){best=d;nx=qx;ny=qy;}\r\n   if((ay>y)!==(by>y)&&x<dx*(y-ay)/dy+ax)inside=!inside;\r\n  }\r\n  const d=Math.sqrt(best)||1,s=inside?1:-1,o=4*(j*mw+i);\r\n  data[o]=128+127*s*nx/d;data[o+1]=128+127*s*ny/d;data[o+2]=255*Math.min(1,Math.max(0,.5+s*d/(2*bevel)));data[o+3]=255;\r\n }\r\n return {data,mw,mh};\r\n}\r\nconst TUNNEL_VS='#version 300 es\\nvoid main(){vec2 p=vec2((gl_VertexID<<1)&2,gl_VertexID&2);gl_Position=vec4(p*2.-1.,0,1);}';\r\nconst tunnelFragment=(material='')=>`#version 300 es\r\nprecision highp float;\r\nuniform vec2 uRes,uC,uLP;uniform float uR,uT,uSpin,uSweep,uLens,uBevel,uPr,uFringe,uMag,uN;uniform vec3 uSeq[12],uCore,uTint;uniform float uBlur;uniform sampler2D uMap;uniform sampler2D uPeek;uniform float uPeekOn;out vec4 o;\r\nvec3 seq(float i){return uSeq[int(mod(i,uN))];}\r\nvec3 acc(float i){return uSeq[int(uN)+int(mod(i,2.))];} // accent colours sit after the ring colours (up to 10), so uSeq has 12 slots\r\n${material}\r\nvec3 tunnel(vec2 p,float fz){\r\n float aa=1.-smoothstep(.25,.9,fz); // fade ring detail that gets finer than a pixel\r\n vec2 d=(p-uC)/uR;float r=max(length(d),1e-3),z=3.4/r,a=atan(d.y,d.x)+uSpin+.12*z;\r\n float v=z-uT+.35*sin(a*3.+z*.5)*aa,i=floor(v),f=v-i;         // wavy ring edges: the colours flow, not a target\r\n vec3 c=mix(seq(i),seq(i+1.),smoothstep(.65,1.,f));\r\n c*=mix(.85,.55+.45*(.5+.5*sin(a*7.+v*6.2832)),aa); // twisted streaks\r\n c+=max(pow(f,12.),1.-smoothstep(0.,1.5*fz,f))*aa*(c*.8+.35); // bright leading edge of each ring, antialiased across the wrap\r\n${material ? ' c=material(a,v,z,r,aa,c);' : ''}\r\n c=mix(c,uCore,smoothstep(7.,40.,z));            // depth fog: the far end glows\r\n c+=uCore*exp(-r*16.)*1.1;                        // bright core at the vanishing point\r\n return c*mix(1.,.78,smoothstep(1.,1.8,r));      // walls dim a little toward the opening (more turns neon yellow olive)\r\n}\r\nvoid main(){\r\n vec2 p0=vec2(gl_FragCoord.x,uRes.y-gl_FragCoord.y);vec4 m=texture(uMap,p0/uRes);\r\n vec2 n=m.rg*2.-1.;n/=max(length(n),1e-3);\r\n float sd=(m.b-.5)*2.*uBevel,e=clamp(sd/uBevel,0.,1.),bend=(1.-e)*(1.-e);\r\n vec2 p=uC+(p0-uC)/(1.+uMag*e);                  // #125: the flat middle magnifies a little, like a lens\r\n float fz=fwidth(3.4*uR/max(length(p-uC),1e-3)); // ring depth change per pixel\r\n vec2 off=n*uLens*bend;                           // refraction: the thick bevel shows the tunnel from further out\r\n vec3 c=uFringe>0.&&bend>.02?vec3(tunnel(p+off*(1.-uFringe),fz).r,tunnel(p+off,fz).g,tunnel(p+off*(1.+uFringe),fz).b):tunnel(p+off,fz); // dispersion: blue bends furthest\r\n if(uBlur>0.)c=mix(c,tunnel(uC+(p+off-uC)*1.016,fz),uBlur); // short radial exposure\r\n if(uPeekOn>0.){vec2 q=(p+off)/uRes;c=mix(c,pow(texture(uPeek,vec2(q.x,1.-q.y)).rgb,vec3(.4545)),uPeekOn*(1.-smoothstep(.3,.75,length((p0-uC)/uRes)*2.))*step(0.,sd));} // PORTAL-PEEK: the destination in the centre, the wormhole at the rim\r\n float l=dot(c,vec3(.299,.587,.114));c=mix(vec3(l),c,1.45)*.9+.07; // frosted: lifted, saturation boosted\r\n c=mix(c,vec3(l)*.55+.42,.2*bend);                // frost in the bevel band only: a milky thick edge against the clear middle\r\n vec2 L=normalize(uLP-p0);float lit=max(dot(n,L),0.),far=max(-dot(n,L),0.); // lit from the finger (or the top-left)\r\n c+=(1.-smoothstep(0.,4.*uPr,abs(sd)))*(1.9*pow(lit,1.4)+.5*pow(far,3.)); // bright specular rim facing the light, faint glint opposite\r\n c+=bend*(1.-e)*.3*(.5+.5*lit);                   // Fresnel: the whole bevel brightens toward the rim\r\n float inner=(1.-smoothstep(0.,28.*uPr,sd))*step(0.,sd);\r\n c=mix(c,c*.45+.08,inner*far*.8)+inner*inner*lit*.4; // darker inner edge on the far side, glow inside the lit edge\r\n c+=.1*(1.-smoothstep(0.,.75,length((p0-uLP)/uRes*.6)))*step(0.,sd); // broad glare toward the light\r\n if(sd<0.)c*=.55;                                 // beyond the rim, under the cloth's ragged edge\r\n float s=dot(p0/length(uRes),normalize(vec2(1.,.45)))-uSweep;c+=exp(-s*s*160.)*.2*step(0.,sd); // light sweep\r\n o=vec4(c+(fract(sin(dot(p0,vec2(12.9898,78.233)))*43758.5453)-.5)/255.,1);\r\n}`;\r\n// One WebGL2 context for the portal's life, created on the first glass and reused; null when unavailable (CSS glass then).\r\nlet tunnel=null;\r\nfunction tunnelGL(material='',{activate=true}={}) {\r\n const uniforms=['uRes','uC','uLP','uR','uT','uSpin','uSweep','uLens','uBevel','uPr','uFringe','uMag','uN','uSeq','uCore','uTint','uBlur','uPeek','uPeekOn'];\r\n if(!tunnel){\r\n  const canvas=document.createElement('canvas'),gl=canvas.getContext('webgl2',{alpha:false,antialias:false,depth:false,stencil:false,powerPreference:'low-power'});\r\n  if(!gl)return null;\r\n  const owner={canvas,gl,programs:new Map(),texture:gl.createTexture(),active:null};tunnel=owner;\r\n  gl.bindTexture(gl.TEXTURE_2D,owner.texture);\r\n  for(const k of [gl.TEXTURE_WRAP_S,gl.TEXTURE_WRAP_T])gl.texParameteri(gl.TEXTURE_2D,k,gl.CLAMP_TO_EDGE);\r\n  for(const k of [gl.TEXTURE_MIN_FILTER,gl.TEXTURE_MAG_FILTER])gl.texParameteri(gl.TEXTURE_2D,k,gl.LINEAR);\r\n  canvas.addEventListener('webglcontextlost',()=>{\r\n   owner.programs.clear();if(tunnel===owner)tunnel=null;\r\n   canvas.parentNode?.classList.remove('gl');canvas.remove();\r\n  });\r\n }\r\n const owner=tunnel,{gl,canvas}=owner;\r\n let selected=owner.programs.get(material),compiled=false;\r\n if(!selected){\r\n  const vs=gl.createShader(gl.VERTEX_SHADER),fs=gl.createShader(gl.FRAGMENT_SHADER),program=gl.createProgram();\r\n  const compile=(shader,source)=>{gl.shaderSource(shader,source);gl.compileShader(shader);return gl.getShaderParameter(shader,gl.COMPILE_STATUS);};\r\n  const valid=compile(vs,TUNNEL_VS)&&compile(fs,tunnelFragment(material));\r\n  if(!valid){gl.deleteShader(vs);gl.deleteShader(fs);gl.deleteProgram(program);return null;}\r\n  gl.attachShader(program,vs);gl.attachShader(program,fs);gl.linkProgram(program);gl.deleteShader(vs);gl.deleteShader(fs);\r\n  if(!gl.getProgramParameter(program,gl.LINK_STATUS)){gl.deleteProgram(program);return null;}\r\n  const u={};for(const k of uniforms)u[k]=gl.getUniformLocation(program,k);\r\n  selected={program,u};owner.programs.set(material,selected);compiled=true;\r\n  // Warm each new linked program once so the first full-size frame doesn't pay lazy driver setup cost.\r\n  // Restore the prior program: a deferred cache fill can run while another material owns a live phase.\r\n  if(owner.programs.size===1)canvas.width=canvas.height=1;\r\n  const previous=gl.getParameter(gl.CURRENT_PROGRAM),previousViewport=gl.getParameter(gl.VIEWPORT);\r\n  gl.useProgram(program);gl.bindTexture(gl.TEXTURE_2D,owner.texture);gl.viewport(0,0,1,1);gl.drawArrays(gl.TRIANGLES,0,3);\r\n  gl.readPixels(0,0,1,1,gl.RGBA,gl.UNSIGNED_BYTE,new Uint8Array(4));gl.useProgram(previous);gl.viewport(...previousViewport);\r\n }\r\n if(activate){gl.useProgram(selected.program);owner.active=selected;owner.u=selected.u;}\r\n return owner;\r\n}\r\n// A secret handoff immediately allocates the Vault's own renderer. Drop the portal's offscreen\r\n// WebGL2 context first; hidden canvases still count against mobile GPU context/memory budgets.\r\nasync function releaseTunnel(){\r\n const owner=tunnel;if(!owner)return;\r\n tunnel=null;\r\n const {gl,canvas}=owner;\r\n owner.programs.clear();owner.active=null;\r\n try{if(owner.texture)gl.deleteTexture(owner.texture);}catch{}\r\n owner.texture=null;\r\n await releaseGraphics(canvas,gl,()=>gl.getExtension('WEBGL_lose_context')?.loseContext());\r\n canvas.remove();\r\n}\r\nfunction stopWormhole(){\r\n if(!wormhole)return;\r\n const current=wormhole;wormhole=null;\r\n current.ph.stop?.();current.el.remove();\r\n}\r\nconst rgb=hex=>[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16)/255);\r\nconst easeInOut=t=>t<=0?0:t>=1?1:t*t*(3-2*t);\r\n// PORTAL-PEEK (R17, on by default; localStorage.myr5PortalPeek=\"0\" is the kill switch): the destination rendered offscreen (portal-peek.mjs)\r\n// and sampled in the wormhole's centre on texture unit 1. Loads after the wormhole starts; fades in once ready; any\r\n// failure, a lost context or the lite fallback leaves the plain wormhole.\r\nfunction startPeek(ph,{gl,active:{program,u}},w,h){\r\n let flag=null;try{flag=localStorage.getItem('myr5PortalPeek');}catch{}\r\n if(!ph.peek||flag==='0')return null;\r\n const s={peek:null,tex:null,on:0,n:0,dead:false};\r\n import('./portal-peek.mjs').then(m=>m.openPeek(ph.peek,w,h,{shouldOpen:()=>!s.dead&&!gl.isContextLost()})).then(peek=>{\r\n  if(!peek)return;if(s.dead||gl.isContextLost())return peek.dispose();\r\n  s.peek=peek;s.tex=gl.createTexture();gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,s.tex);\r\n  for(const k of [gl.TEXTURE_WRAP_S,gl.TEXTURE_WRAP_T])gl.texParameteri(gl.TEXTURE_2D,k,gl.CLAMP_TO_EDGE);\r\n  for(const k of [gl.TEXTURE_MIN_FILTER,gl.TEXTURE_MAG_FILTER])gl.texParameteri(gl.TEXTURE_2D,k,gl.LINEAR);\r\n  gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,peek.width,peek.height,0,gl.RGBA,gl.UNSIGNED_BYTE,null);gl.activeTexture(gl.TEXTURE0);\r\n }).catch(()=>{});\r\n s.frame=(dt,now)=>{\r\n  if(!s.peek)return;if(s.peek.lost()){s.stop();gl.useProgram(program);gl.uniform1f(u.uPeekOn,0);return;}\r\n  if(s.n++&1)return; // ponytail: half rate (each read stalls the GPU); go every frame if phones show judder\r\n  s.peek.render(now);const px=s.peek.read();\r\n  gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,s.tex);gl.texSubImage2D(gl.TEXTURE_2D,0,0,0,s.peek.width,s.peek.height,gl.RGBA,gl.UNSIGNED_BYTE,px);gl.activeTexture(gl.TEXTURE0);\r\n  s.on=Math.min(1,s.on+dt*5);gl.useProgram(program);gl.uniform1f(u.uPeekOn,s.on);\r\n };\r\n s.stop=()=>{s.dead=true;s.peek?.dispose();s.peek=null;if(s.tex)gl.deleteTexture(s.tex);s.tex=null;};\r\n return s;\r\n}\r\n// Runs the wormhole for one glass phase: speed ramps up across the cut + loading phase, the vanishing point drifts\r\n// toward the finger (and with device tilt where that needs no permission prompt). Reduced motion uses static CSS glass.\r\n// ph.stop() freezes it (at the reveal) and endPhase() always stops it.\r\nasync function startTunnel(ph,poly,color,all){\r\n const capturedBoardId=boardId,capturedSignal=lifecycle?.signal;\r\n let cancelled=false,raf=0,tiltOk=false,onTilt=null;\r\n // Install cancellation before any optional material import can yield. Standalone wormholes have their own phase object.\r\n ph.stop=()=>{cancelled=true;cancelAnimationFrame(raf);if(tiltOk&&onTilt)removeEventListener('deviceorientation',onTilt);};\r\n const palette=!all?paletteFor(capturedBoardId,store.get(paletteKey(capturedBoardId))):null;\r\n const seq=all||capturedBoardId==='quilt'?ringColours(color,all):palette?.colors||ringColours(color,all),core=palette?.core||color;\r\n ph.glass.dataset.tunnel=capturedBoardId;ph.glass.style.setProperty('--tint',boardTint(capturedBoardId));\r\n const [seq0,...seqN]=seq;ph.glass.style.setProperty('--seq0',seq0);ph.glass.style.setProperty('--seq',seqN.join(','));\r\n if(prefersReducedMotion())return; // CSS uses the selected sequence without creating WebGL under reduced motion.\r\n let material='';\r\n if(!all&&palette&&capturedBoardId!=='quilt'){\r\n  let pending=materialLoads.get(capturedBoardId);\r\n  if(!pending){pending=import(`./portal-tunnel-${capturedBoardId}.mjs`).then(m=>typeof m.material==='string'?m.material:'').catch(()=> '');materialLoads.set(capturedBoardId,pending);}\r\n  material=await Promise.race([pending,sleep(900).then(()=> '')]);\r\n }\r\n if(cancelled||!ph.glass.isConnected||capturedSignal?.aborted)return;\r\n const t=tunnelGL(material);if(!t)return;\r\n const {gl,canvas}=t,{program,u}=t.active,{left,top,w,h}=ph.box,reduced=prefersReducedMotion();\r\n const bindPhaseProgram=()=>gl.useProgram(program);\r\n bindPhaseProgram();\r\n gl.bindTexture(gl.TEXTURE_2D,t.texture);\r\n const tex=lensMap((ph.fullscreen?poly:bleedPts(poly,-GLASS.rimInset)).map(([x,y])=>[x-left,y-top]),w,h);\r\n gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,tex.mw,tex.mh,0,gl.RGBA,gl.UNSIGNED_BYTE,tex.data);\r\n const flat=new Float32Array(36);seq.forEach((c,i)=>flat.set(rgb(c),3*i));(palette?.accents||[seq[0],seq[0]]).forEach((c,i)=>flat.set(rgb(c),3*(seq.length+i)));gl.uniform3fv(u.uSeq,flat);gl.uniform1f(u.uN,seq.length);\r\n gl.uniform3fv(u.uTint,rgb(boardTint(capturedBoardId)));\r\n gl.uniform3fv(u.uCore,all?[1,1,1]:rgb(core).map(v=>v*.5+.5));\r\n const [cx,cy]=centroidOf(poly).map((v,i)=>v-(i?top:left)),xs=poly.map(p=>p[0]),ys=poly.map(p=>p[1]),R=.5*Math.min(Math.max(...xs)-Math.min(...xs),Math.max(...ys)-Math.min(...ys));\r\n // ponytail: hardwareConcurrency is a coarse low-end hint (and capped on some browsers); the measured-frame check below is the real guard.\r\n let pr=Math.min(devicePixelRatio||1,(navigator.hardwareConcurrency||8)<=4?1:1.5),lite=false,travel=.3,last=ph.t0,tilt=null;\r\n const par=[0,0],slow=[],rest=[-.35*w,-.55*h],light=[...rest]; // #125 the specular follows the finger, else sits up-left (and leans with tilt)\r\n const size=()=>{\r\n  bindPhaseProgram();\r\n  canvas.width=Math.max(1,Math.round(w*pr));canvas.height=Math.max(1,Math.round(h*pr));gl.viewport(0,0,canvas.width,canvas.height);\r\n  gl.uniform2f(u.uRes,canvas.width,canvas.height);gl.uniform1f(u.uPr,pr);gl.uniform1f(u.uR,Math.max(R,1)*pr);gl.uniform1f(u.uLens,GLASS.bend*pr);gl.uniform1f(u.uBevel,GLASS.bevel*pr);gl.uniform1f(u.uFringe,lite||reduced?0:GLASS.fringe);gl.uniform1f(u.uMag,GLASS.magnify);gl.uniform1f(u.uBlur,lite||reduced?0:.18);\r\n  gl.uniform1i(u.uPeek,1);gl.uniform1f(u.uPeekOn,0); // PORTAL-PEEK\r\n };\r\n const draw=now=>{\r\n  bindPhaseProgram();\r\n  const age=now-ph.t0;\r\n  gl.uniform1f(u.uT,travel);gl.uniform1f(u.uSpin,reduced?0:(age*.000225)%(2*Math.PI));gl.uniform1f(u.uSweep,reduced?.45:-.35+1.7*((age/3200)%1));\r\n  gl.uniform2f(u.uC,(cx+par[0])*pr,(cy+par[1])*pr);gl.uniform2f(u.uLP,light[0]*pr,light[1]*pr);gl.drawArrays(gl.TRIANGLES,0,3);\r\n };\r\n const look=createTiltLook();onTilt=e=>{const t=look.read(e,performance.now());if(t)tilt=[-t.x*R*.2,-t.y*R*.2];};\r\n const frame=now=>{\r\n  if(cancelled||!ph.glass.isConnected||capturedSignal?.aborted||gl.isContextLost())return;\r\n  const dt=Math.min(.05,Math.max(0,(now-last)/1000));last=now;\r\n  // Graceful degrade: if frames 10-40 run slow (median under ~45 fps), drop resolution and the fringe.\r\n  if(!lite&&slow.length<40&&slow.push(dt)===40&&slow.slice(10).sort((a,b)=>a-b)[15]>.022){lite=true;pr=Math.min(pr,.75);pk?.stop();size();ph.glass.dataset.lite='1';} // PORTAL-PEEK: lite drops the peek\r\n  const T=ph.T,d=ph.diveT0?Math.min(1,(now-ph.diveT0)/T.reveal):ph.backT0?Math.max(0,1-(now-ph.backT0)/T.reveal):0; // the dive adds up to tunnelDive rings/s (the dive back sheds it)\r\n  travel=(travel+dt*1.25*(PORTAL.tunnelFrom+(PORTAL.tunnelTo-PORTAL.tunnelFrom)*easeInOut((now-ph.t0)/(T.cut+T.load))+PORTAL.tunnelDive*d*d))%seq.length;\r\n  const finger=[...pointers.values()].at(-1)?.pts.at(-1);let tx=(tilt?.[0]||0)+(finger?(finger.x-left-cx)*.12:0),ty=(tilt?.[1]||0)+(finger?(finger.y-top-cy)*.12:0);\r\n  const k=Math.min(1,.2*R/(Math.hypot(tx,ty)||1));par[0]+=(tx*k-par[0])*Math.min(1,dt*5);par[1]+=(ty*k-par[1])*Math.min(1,dt*5);\r\n  const lx=finger?finger.x-left:rest[0]-(tilt?.[0]||0)*8,ly=finger?finger.y-top:rest[1]-(tilt?.[1]||0)*8;light[0]+=(lx-light[0])*Math.min(1,dt*9);light[1]+=(ly-light[1])*Math.min(1,dt*9);\r\n  pk?.frame(dt,now);draw(now);raf=requestAnimationFrame(frame); // PORTAL-PEEK\r\n };\r\n size();ph.glass.append(canvas);ph.glass.classList.add('gl');draw(ph.t0);\r\n if(reduced)return;\r\n const pk=startPeek(ph,t,w,h),stop0=ph.stop;if(pk)ph.stop=()=>{stop0();pk.stop();}; // PORTAL-PEEK\r\n tiltOk=typeof DeviceOrientationEvent!=='undefined'&&typeof DeviceOrientationEvent.requestPermission!=='function';\r\n if(tiltOk)addEventListener('deviceorientation',onTilt);\r\n raf=requestAnimationFrame(frame);\r\n}\r\n// The glass sits between #portalHome's background and the board canvas, so it shows only through the cut.\r\n// pts: client-px polygon to clip to (null = whole screen); all: even rainbow (the cross). The box is the clip's\r\n// bounds, so the wormhole only fills what can show. <b> is the CSS fallback when WebGL2 is unavailable.\r\n// edge: the cut outline. A static glass bezel is drawn along it ABOVE the board: the cut drops whole mesh\r\n// triangles, so the cloth's hole edge stair-steps up to ~12 px either side of the outline, and the bezel covers that.\r\n// T: this sequence's {cut,load,reveal} ms (#124's lines and X run PORTAL.short of them); axis: a line's [a,b], whose\r\n// glowing bezel starts as a slit along it and opens into the lens over the cut, the wormhole pouring through the tear.\r\nconst FULL_T={cut:PORTAL.cutMs,load:PORTAL.loadMinMs,reveal:PORTAL.revealMs};\r\nfunction showGlass(pts,color,all=false,edge=pts,{T=FULL_T,axis=null,monochrome=false,peek=null}={}){\r\n endPhase();\r\n const poly=pts||closeLoop([[0,0],[innerWidth,0],[innerWidth,innerHeight],[0,innerHeight]]),clip=pts?bleedPts(pts):poly;\r\n const xs=clip.map(p=>p[0]),ys=clip.map(p=>p[1]),left=Math.floor(Math.min(...xs)),top=Math.floor(Math.min(...ys)),w=Math.ceil(Math.max(...xs))-left,h=Math.ceil(Math.max(...ys))-top;\r\n const el=document.createElement('div');el.className='portal-glass';el.setAttribute('aria-hidden','true');el.innerHTML='<b></b>';el.classList.toggle('all',all);\r\n el.style.cssText=`left:${left}px;top:${top}px;width:${w}px;height:${h}px`;el.style.setProperty('--glass',color);\r\n const reduced=prefersReducedMotion(),slit=axis&&!reduced;\r\n if(pts)el.style.clipPath=`polygon(${clip.map(([x,y])=>`${x-left}px ${y-top}px`).join(',')})`;\r\n if(!reduced&&!slit)el.style.setProperty('animation','portal-glass-in .6s ease both','important'); // beats the locked theme's animation:none\r\n portalHome.append(el);\r\n el.dataset.tunnel=boardId;\r\n if(monochrome){el.style.filter='grayscale(1)';if(!reduced)el.animate([{filter:'grayscale(0)'},{filter:'grayscale(1)'}],{duration:T.cut+T.load+T.reveal,easing:'linear',fill:'forwards'});}\r\n let bezel=null;\r\n if(edge){\r\n  // Width: 1.55 grid cells (24 px on a phone). Measured at 375x812, the hole edge strays up to 11.2 px (0.72 cell) from the outline.\r\n  const B=1.55*(board?.faceRect().width||375)/QUILT.segX,p=edge.map(q=>q.join(',')).join(' '),ring=(cls,w,more='')=>`<polygon class=\"${cls}\" stroke-width=\"${w}\" ${more} points=\"${p}\"/>`;\r\n  portalHome.insertAdjacentHTML('beforeend',`<svg class=\"portal-bezel\" aria-hidden=\"true\" style=\"--glass:${color}\"><defs><linearGradient id=\"portalBezelLit\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" class=\"lit\"/><stop offset=\".5\" class=\"mid\"/><stop offset=\"1\" class=\"far\"/></linearGradient><linearGradient id=\"portalBezelSpec\" x1=\"0\" y1=\"0\" x2=\"1\" y2=\"1\"><stop offset=\"0\" stop-color=\"#fff\"/><stop offset=\".55\" stop-color=\"#fff\" stop-opacity=\".2\"/><stop offset=\"1\" stop-color=\"#fff\" stop-opacity=\".6\"/></linearGradient></defs>${ring('shade',B+10)+ring('shade',B+5)+ring('body',B)+ring('glow',B*.6)+ring('glow',B*.36)+ring('core',2.5)+ring('spec',2,`transform=\"translate(${-.3*B} ${-.3*B})\"`)}</svg>`); // stacked strokes, no blur filters: those cost a ~100 ms first paint\r\n  bezel=portalHome.lastElementChild;\r\n  if(!reduced&&!slit)bezel.style.setProperty('animation','portal-glass-in .3s ease both','important');\r\n  if(slit){ // squashed flat onto the line, then out to the lens\r\n   const [[ax,ay],[bx,by]]=axis,a=Math.atan2(by-ay,bx-ax)*180/Math.PI;bezel.style.transformOrigin=`${d2((ax+bx)/2)}px ${d2((ay+by)/2)}px`;\r\n   bezel.animate([{transform:`rotate(${d2(a)}deg) scale(1,.04) rotate(${d2(-a)}deg)`},{transform:'none'}],{duration:T.cut,easing:'cubic-bezier(.5,0,.2,1)'});\r\n  }\r\n }\r\n phase={glass:el,bezel,pts,color,T,t0:performance.now(),pulse:false,box:{left,top,w,h},peek}; // PORTAL-PEEK: peek = destination route\r\n startTunnel(phase,poly,color,all);\r\n energize(restSeq(),ENERGY.surge,true);\r\n}\r\nfunction endPhase(){phase?.stop?.();phase?.dive?.cancel();phase?.glass.remove();phase?.bezel?.remove();phase=null;energize(restSeq());}\r\n// The wormhole on its own, for transitions elsewhere (a workout's rest <-> attack, leaving Meditation): 'in' opens it\r\n// from the centre of the screen until it covers everything (then it stays up, still flowing, while the caller swaps\r\n// what is under it); 'out' shrinks it back into its core and removes it. Resolves when that half is done. One wormhole\r\n// canvas is shared with the quilt's glass, so don't play it while the quilt is mid-portal. Reduced motion: instant.\r\nlet wormhole=null;\r\nexport async function playWormhole({direction='in',minMs=900,color='#b026ff'}={}){\r\n portalSound('travel');\r\n const ms=prefersReducedMotion()?0:Math.max(0,minMs),R=Math.ceil(Math.hypot(innerWidth,innerHeight)/2);\r\n if(!wormhole){\r\n  const el=document.createElement('div'),w=innerWidth,h=innerHeight;el.className='portal-glass portal-wormhole';el.setAttribute('aria-hidden','true');el.innerHTML='<b></b>';\r\n  el.style.cssText=`position:fixed;inset:0;width:${w}px;height:${h}px;margin:0;padding:0;border:0;max-width:none;max-height:none;overflow:hidden;background:#000;pointer-events:none;z-index:10000;--glass:${color}`;\r\n  if(direction==='out')el.style.clipPath=`circle(${R}px at 50% 50%)`;\r\n  document.body.append(el);if(el.showPopover){el.setAttribute('popover','manual');el.showPopover();}\r\n  const ph={glass:el,fullscreen:true,box:{left:0,top:0,w,h},T:{cut:Math.max(1,ms),load:0,reveal:Math.max(1,ms)},t0:performance.now()-(direction==='out'?ms:0),pulse:false};\r\n  startTunnel(ph,closeLoop([[0,0],[w,0],[w,h],[0,h]]),color,false);\r\n  wormhole={el,ph};\r\n }\r\n const {el,ph}=wormhole,out=direction==='out';\r\n ph[out?'backT0':'diveT0']=performance.now();\r\n await el.animate([{clipPath:'circle(0px at 50% 50%)'},{clipPath:`circle(${R}px at 50% 50%)`}],{duration:ms,easing:out?'cubic-bezier(.6,0,.9,.4)':'cubic-bezier(.2,.6,.3,1)',direction:out?'reverse':'normal',fill:'forwards'}).finished.catch(()=>{});\r\n if(out&&wormhole?.el===el){ph.stop?.();el.remove();wormhole=null;}\r\n}\r\n// A destination seen through the hole: stop the wormhole and leave its still depth (what a flat menu's rectangle sits in),\r\n// the bezel staying over the cloth's ragged edge.\r\nfunction quietPhase(){if(!phase)return;phase.stop?.();phase.stop=null;phase.pulse=false;phase.glass.classList.remove('gl');phase.glass.classList.add('still');phase.glass.querySelector('canvas')?.remove();energize(restSeq());}\r\nfunction ripple(x,y){\r\n if(!phase||prefersReducedMotion())return;\r\n const r=document.createElement('i');r.className='portal-ripple';r.style.left=(x-phase.box.left)+'px';r.style.top=(y-phase.box.top)+'px';\r\n r.style.setProperty('animation',`portal-ripple ${PORTAL.rippleMs}ms cubic-bezier(.2,.6,.3,1) forwards`,'important'); // beats the locked theme's animation:none\r\n phase.glass.append(r);setTimeout(()=>r.remove(),PORTAL.rippleMs);\r\n}\r\n// Cuts a client-px polygon out of the board (board.cut takes face coords, v down) and resolves once the piece has fallen in.\r\nfunction cutBoard(pts,color,ms=prefersReducedMotion()?0:PORTAL.cutMs){\r\n const f=board?.faceRect();if(!f)return Promise.resolve();\r\n return board.cut(pts.map(([x,y])=>[(x-f.left)/f.width,(y-f.top)/f.height]),color,ms);\r\n}\r\n// Resolves once it has landed (the transition's own end: a slow frame can hold its start back well past ms).\r\nfunction revealDialogFromPoint(dialog,[cx,cy],ms=500){\r\n if(prefersReducedMotion())return Promise.resolve();\r\n const dbox=dialog.getBoundingClientRect();\r\n dialog.style.transformOrigin=`${cx-dbox.left}px ${cy-dbox.top}px`;motion(dialog,'none');dialog.style.transform='scale(.05)';dialog.style.opacity='0';\r\n return settle().then(()=>{\r\n  if(!dialog.open)return;\r\n  motion(dialog,`transform ${ms}ms cubic-bezier(.2,0,.3,1),opacity ${ms*.8}ms ease`);dialog.style.transform='';dialog.style.opacity='';\r\n  getComputedStyle(dialog).transform; // starts the transition now, so it can be awaited\r\n  const grow=dialog.getAnimations().find(a=>a.transitionProperty==='transform');\r\n  return grow?grow.finished.catch(()=>{}):undefined;\r\n });\r\n}\r\n// Dive into the wormhole (Ian 2026-09-23, #103 \"zoom into each portal once opened\"): the whole portal scales up about the\r\n// vanishing point until the shape covers the screen, easing in over revealMs while the tunnel speeds up. A compositor-only\r\n// Web Animation: the locked theme can't switch it off and it leaves `transition` free for the hole/fade. Reduced motion: a\r\n// quick fade. endPhase() cancels it. back: the same dive played in reverse, out of the wormhole (diveBack).\r\nfunction dive(pts,back=false){\r\n if(!phase)return Promise.resolve();\r\n if(back)portalSound('travel');\r\n const c=centroidOf(pts);let rIn=Infinity;\r\n for(let k=0;k<pts.length-1;k++){const [ax,ay]=pts[k],[bx,by]=pts[k+1],dx=bx-ax,dy=by-ay,t=Math.max(0,Math.min(1,((c[0]-ax)*dx+(c[1]-ay)*dy)/(dx*dx+dy*dy||1)));rIn=Math.min(rIn,Math.hypot(ax+t*dx-c[0],ay+t*dy-c[1]));}\r\n const far=Math.max(...[[0,0],[innerWidth,0],[0,innerHeight],[innerWidth,innerHeight]].map(([x,y])=>Math.hypot(x-c[0],y-c[1]))),reduced=prefersReducedMotion();\r\n portalHome.style.transformOrigin=`${c[0]}px ${c[1]}px`;phase[back?'backT0':'diveT0']=performance.now();\r\n energize(null,ENERGY.dive,true);\r\n phase.dive=portalHome.animate(reduced?[{opacity:1},{opacity:0}]:[{transform:'none'},{transform:`scale(${Math.max(1.5,1.05*far/Math.max(rIn,1))})`}],{duration:reduced?200:phase.T.reveal,easing:reduced?'ease':'cubic-bezier(.55,0,.9,.5)',fill:back?'none':'forwards',direction:back?'reverse':'normal'});\r\n return phase.dive.finished.catch(()=>{});\r\n}\r\n// The destination dialog grows out of the tunnel's core; its backdrop fades in so the dive stays visible behind it.\r\n// Release 5: the bottom bar (routes.mjs moves it into the open route's dialog) must not ride the arrival's scale. It waits\r\n// on the page, still showing below the frame (portal.css ends the framed backdrop above it), and goes back in once the\r\n// dialog has landed, unless the route moved on meanwhile (routes.mjs then already re-homed it).\r\nfunction arriveFromCore(dialog,core,ms){\r\n if(prefersReducedMotion())return;\r\n const bar=dialog.querySelector(':scope>#coachDock');if(bar)document.body.append(bar);\r\n dialog.style.setProperty('--portal-arrive',ms+'ms');dialog.classList.add('portal-arriving');\r\n // The bar goes back in only once the scale has landed (a fixed bar inside a scaled dialog would ride the scale).\r\n revealDialogFromPoint(dialog,core,ms).then(()=>{dialog.classList.remove('portal-arriving');dialog.style.removeProperty('--portal-arrive');motion(dialog,'');dialog.style.transformOrigin='';if(bar?.parentNode===document.body&&dialog.open)dialog.append(bar);});\r\n}\r\n\r\nfunction fallbackRect(){const r=overlay.getBoundingClientRect();return{left:r.left,top:r.top,width:r.width,height:r.height};}\r\n\r\nconst musicHold=hold=>window.dispatchEvent(new CustomEvent('myr5:music-hold',{detail:{hold}})); // page music: silent through the trace + tunnel, destination track fades in after\r\nasync function runShape(id){\r\n if(busy||!boardShown||!MENUS[id])return;\r\n const run=++sequence;busy=true;scheduleIdle();musicHold(true);\r\n try{await portalSequence(id,()=>run===sequence&&!lifecycle.signal.aborted);vaultSend({counter:'shape-opened',key:id});}\r\n finally{musicHold(false);if(run===sequence){busy=false;scheduleIdle();}}\r\n}\r\n// Lines are open strokes with no enclosed area; portalWindow() gives them (and the X) a window to cut (#124).\r\nconst LINE_IDS=new Set(['line-lr','line-rl','line-down']);\r\nconst lineTemplatePts=id=>SHAPES.line[(id==='line-lr'||id==='line-rl')?1:0].points;\r\nasync function openDirect(menu,current){\r\n // No dive in, but the way back out is still the wormhole: the destination's own shape, or the full square.\r\n const id=Object.keys(MENUS).find(k=>MENUS[k]===menu),{face}=restFace(),pts=backPts(id);\r\n let dialog=null;\r\n backgroundBlocked(false);\r\n frameOn(face,face&&windowLook(id,menu,face));const unwatch=watchDialog();\r\n try{dialog=await menu.open?.();}catch(error){console.warn(`${menu.label} failed to open.`,error);}finally{unwatch?.();}\r\n if(!current())return;\r\n const shown=dialog instanceof HTMLDialogElement?dialog.open:dialog?.getClientRects?.().length>0;\r\n if(!shown){status(`${menu.label} isn't available here yet.`);await fadeOutBoard();fadeInBoard();return;}\r\n if(dialog instanceof HTMLDialogElement){\r\n  frameDialog(dialog);\r\n  dialog.addEventListener('close',()=>closed(dialog,{pts,color:menu.color},current),{once:true});\r\n }else frameOff();\r\n await fadeOutBoard();\r\n}\r\n// #131: the shapes that aren't full screen open INTO their cut, the quilt staying on as the wall; the rest dive until\r\n// the destination fills the frame. #124: the four lines and the X get the wormhole too, shorter (PORTAL.short): a line\r\n// has no area to cut, so a glowing slit along it opens into a lens-shaped window; the X opens the diamond between its arms.\r\nconst SHAPED=new Set(['rect','oval','up','down','vdiamond','hdiamond']);\r\n// A lens along a -> b: two sine arcs bulging `half` px either side (pointed at the ends), n+1 points a side.\r\nasync function portalSequence(id,current){\r\n const rect=board?board.patternRect():fallbackRect(),face=board?.faceRect();\r\n if(id==='cross'){\r\n  portalSound('travel');\r\n  flashOutline(SHAPES.cross.map(p=>toClientPts(p.points,rect)),'#ffffff');\r\n  const center=[rect.left+rect.width/2,rect.top+rect.height/2];\r\n  const face=board?.faceRect();\r\n  const cut=shapeClipPts('rect',rect);\r\n  showGlass(face&&closeLoop(toClientPts([[0,0],[1,0],[1,1],[0,1]],face)),'#ffffff',true,cut); // rainbow glass behind the whole board; the whole pattern falls in over it\r\n  await Promise.all([cutBoard(cut,'#ffffff'),fallInAll(center)]);\r\n  if(!current())return;\r\n  openMenu();\r\n  await settle();\r\n  revealDialogFromPoint(menuSheet,center);\r\n  menuSheet.addEventListener('close',()=>{motion(menuSheet,'');menuSheet.style.transform='';menuSheet.style.opacity='';},{once:true});\r\n  return;\r\n }\r\n const menu=MENUS[id];if(!menu)return;\r\n const line=LINE_IDS.has(id),short=line||id==='x';\r\n if(!SHAPES[id]&&!line){if(menu.locked?.()){status(menu.lockedMessage);return;}setVisible(false);menu.open?.();return;} // menu without a traced shape (opened by id)\r\n const win=portalWindow(id,rect),pts=boardId==='cogs'?win.pts:insetPts(win.pts,id);\r\n flashOutline(id==='x'?SHAPES.x.map(p=>toClientPts(p.points,rect)):line?[toClientPts(lineTemplatePts(id),rect)]:[pts],menu.color);\r\n if(menu.locked?.()){status(menu.lockedMessage);return;}\r\n status('');\r\n portalSound('travel');\r\n const k=short?PORTAL.short:1,T={cut:PORTAL.cutMs*k,load:PORTAL.loadMinMs*k,reveal:PORTAL.revealMs*k},reduced=prefersReducedMotion();\r\n showGlass(pts,menu.color,false,pts,{T,axis:win.axis,monochrome:menu.route==='meditate',peek:menu.route}); // PORTAL-PEEK: route\r\n await cutBoard(pts,menu.color,reduced?0:T.cut);\r\n if(!current())return;\r\n // Loading phase: the glass stays live (touch ripples, breathing outline) for at least T.load.\r\n if(phase)phase.pulse=!reduced;\r\n if(phase?.pulse)kickRender();\r\n await sleep(reduced?0:T.load);\r\n if(!current())return;\r\n if(SHAPED.has(id)&&id!=='rect'&&menu.kind==='dialog'&&face){await openInHole(id,menu,pts,face,current);return;}\r\n // Reveal: dive into the wormhole; the destination appears from its core over the last `arrive` ms of the dive.\r\n const dove=dive(pts),core=centroidOf(pts),arrive=T.reveal*.55;\r\n if(menu.kind==='dialog')frameOn(face,face&&windowLook(id,menu,face)); // the frame stays put and the dive happens in its window\r\n if(reduced||menu.kind==='nav'||menu.kind==='menu')await dove;else await sleep(T.reveal-arrive);\r\n if(!current())return;\r\n if(menu.kind==='home'){await growHole(portalHome,pts,rectBox(portalHome),current,arrive);if(current()){setVisible(false);menu.open?.();}return;}\r\n if(menu.kind==='nav'){menu.open();return;} // X -> the Character editor: dive, then navigate (the glass stays up while it loads)\r\n if(menu.kind==='menu'){ // line-up: the Menu sheet grows out of the core (openMenu hides the portal itself)\r\n  openMenu();await settle();revealDialogFromPoint(menuSheet,core);\r\n  menuSheet.addEventListener('close',()=>{motion(menuSheet,'');menuSheet.style.transform='';menuSheet.style.opacity='';},{once:true});\r\n  return;\r\n }\r\n let dialog=null;\r\n backgroundBlocked(false);\r\n const unwatch=watchDialog();\r\n try{dialog=await menu.open?.();}catch(error){console.warn(`${menu.label} failed to open.`,error);}finally{unwatch?.();}\r\n if(dialog instanceof HTMLDialogElement&&dialog.open&&current()){frameDialog(dialog);arriveFromCore(dialog,core,arrive);} // before its first paint: no full-size flash\r\n await settle();\r\n if(!current())return;\r\n const shown=dialog instanceof HTMLDialogElement?dialog.open:dialog?.getClientRects?.().length>0;\r\n // Panel missing in this build (or it refused to open): never leave the screen stuck on the glass.\r\n if(!shown){status(`${menu.label} isn't available here yet.`);await fadeOutBoard();fadeInBoard();return;}\r\n if(dialog instanceof HTMLDialogElement){\r\n  await dove;\r\n  if(!current())return;\r\n  if(!dialog.open){fadeInBoard();return;} // closed mid-reveal\r\n  dialog.addEventListener('close',()=>closed(dialog,{pts,color:menu.color},current),{once:true});\r\n }else frameOff();\r\n fadeOutBoard();\r\n}\r\n// #131 the destination opens in the hole (Portal's \"open\"): the frame's chrome and the rim come up with a burst, the\r\n// dialog opens clipped to the cut, growing out of the core to the outline (shapeDialog), the wormhole under it stops and\r\n// the quilt stays on as the wall. Closing fizzles it shut (fizzleBack).\r\nasync function openInHole(id,menu,pts,face,current){\r\n frameOn(face,shapeLook(id,menu,pts));\r\n let dialog=null;\r\n backgroundBlocked(false);\r\n const unwatch=watchDialog();\r\n try{dialog=await menu.open?.();}catch(error){console.warn(`${menu.label} failed to open.`,error);}finally{unwatch?.();}\r\n if(!current())return;\r\n if(dialog instanceof HTMLDialogElement&&dialog.open)frameDialog(dialog);\r\n await settle();\r\n if(!current())return;\r\n const shown=dialog instanceof HTMLDialogElement?dialog.open:dialog?.getClientRects?.().length>0;\r\n if(!shown){frameOff();status(`${menu.label} isn't available here yet.`);await fadeOutBoard();fadeInBoard();return;}\r\n if(!(dialog instanceof HTMLDialogElement)){frameOff();fadeOutBoard();return;}\r\n dialog.addEventListener('close',()=>closed(dialog,{pts,color:menu.color,shaped:true},current),{once:true});\r\n await sleep(prefersReducedMotion()?0:700); // the wormhole shows round the destination while the hole opens out\r\n if(current()&&framed?.dialog===dialog&&!framed.expanded){quietPhase();board?.pause();}\r\n}\r\n\r\n// Vault secret: a finished board secret goes straight to the vault route and its 3D safe door (Ian 7 Oct: no flat door poster).\r\n// setVisible(false) hides the portal; every later show heals the board (glb host -> effect.healSecret) so the secret never lingers.\r\nfunction goVault(){const r=window.myr5Routes;return r?r.go('vault'):import('../routes.mjs').then(m=>m.mountRoutes().go('vault'));}\r\n// Give back every portal WebGL context (3D board, tunnel, idle peek). The flat board and its chosen ID stay, so the next\r\n// show (or 'myr5:graphics-free' when the Vault closes) builds the original 3D board again.\r\nasync function releasePortalGraphics(){\r\n boardLoad++;const previous=gl3;gl3=null;board=base;delete art[boardId];\r\n if(base?.canvas)base.canvas.style.visibility='';\r\n if(previous){portalHome.dataset.art='flat';if(boardShown)base?.resume();}\r\n stopWormhole();\r\n const boardRelease=previous?releaseGraphics(previous.canvas,previous.glContext||null,()=>previous.dispose()):Promise.resolve();\r\n await Promise.all([boardRelease,releaseTunnel()]);\r\n await waitForGraphicsRelease();\r\n try{const peek=await import('./portal-peek.mjs');await peek.releasePeekRendererIfIdle();}catch{}\r\n}\r\nasync function showVaultDoor(secretId=boardId){\r\n if(!boardShown||!board)return;\r\n pointers.clear();clearTimeout(finalizeTimer);pendingStrokes=[];pendingTrailPts=[];lastTap=null;\r\n // Free the portal's WebGL contexts before the door and hall allocate theirs.\r\n const released=releasePortalGraphics();base?.resume();\r\n setVisible(false); // also stops any active portal-peek source before the Vault claims a WebGL context\r\n await released;\r\n try{\r\n  const store=await import('../vault/vault-store.mjs');await store.markSecret(secretId);\r\n }catch(error){\r\n  console.error('Could not save the Achievement Vault secret.',error);\r\n  setVisible(true);status('The secret could not be saved yet. It has not been discarded; retry the Vault handoff.',{label:'Retry Save + Vault',run:()=>showVaultDoor(secretId)});return;\r\n }\r\n try{\r\n  await goVault();\r\n }catch(error){\r\n  console.error('Could not open the Achievement Vault.',error);\r\n  setVisible(true);status('Your secret is saved. The Vault could not open; try again.',{label:'Retry Vault',run:()=>showVaultDoor(secretId)});\r\n }\r\n}\r\nfunction toNorm(x,y){const r=board.patternRect();return[(x-r.left)/r.width,(y-r.top)/r.height];}\r\nfunction endPointer(e,cancel){ if(cancel) lastTap=null;\r\n const p=pointers.get(e.pointerId);if(!p)return;\r\n pointers.delete(e.pointerId);board.release(e.pointerId);\r\n const claimed=!!board.claims?.(e.pointerId); // vault secrets: asked after release (the glb wrapper answered before its effect forgot the pointer)\r\n // #105: the just-released stroke keeps fading (light-painting), independent of whether it matches.\r\n if(p.pts.length>1)fading.push({pts:p.pts,releasedAt:performance.now()});\r\n scheduleIdle();kickRender();\r\n if(cancel||busy)return;\r\n markHintSeen(); // #22: any real released touch, trace or tap, ends the first-run hint window for good.\r\n const xs=p.norm.map(n=>n[0]),ys=p.norm.map(n=>n[1]);\r\n const size=Math.hypot(Math.max(...xs)-Math.min(...xs),Math.max(...ys)-Math.min(...ys));\r\n if(size<.03){\r\n  // #20: a second tap within TAP_MS and TAP_MOVE_PX of the first, near a shape's stitched outline (within\r\n  // TAP_HIT_PX), opens it exactly as tracing does. A single tap, or a double-tap far from any outline,\r\n  // just ripples the fabric (board.press on pointerdown already does that).\r\n  const tap={x:e.clientX,y:e.clientY,t:(Number.isFinite(e.timeStamp)&&e.timeStamp>0?e.timeStamp:performance.now())};\r\n  const isDouble=lastTap&&tap.t-lastTap.t>=0&&tap.t-lastTap.t<=TAP_MS&&Math.hypot(tap.x-lastTap.x,tap.y-lastTap.y)<=TAP_MOVE_PX;\r\n  lastTap=isDouble?null:tap;\r\n  if(isDouble){\r\n   const id=nearestTapShape(tap.x,tap.y);\r\n   if(MENUS[id]){buzz(12);runShape(id);return;} // an outline double-tap opens its shape before any secret may claim it\r\n  }\r\n  if(claimed)lastTap=null;\r\n  return;\r\n }\r\n lastTap=null;\r\n if(claimed)return; // a claimed stroke is a secret gesture: no shape recognition, no \"Almost\"\r\n\r\n pendingStrokes.push(p.norm);pendingTrailPts.push(p.pts);\r\n clearTimeout(finalizeTimer);\r\n finalizeTimer=setTimeout(()=>{\r\n  const strokes=pendingStrokes,trailPts=pendingTrailPts;pendingStrokes=[];pendingTrailPts=[];\r\n  const id=recognizeShape(strokes);\r\n  if(MENUS[id]){\r\n   // #105: on a match, the drawn trail itself flashes the destination colour before the cut starts.\r\n   flashOutline(trailPts.map(pts=>pts.map(pt=>[pt.x,pt.y])),id==='cross'?'#ffffff':(MENUS[id]?.color||'#ffffff'));\r\n   buzz(12); // #29\r\n   runShape(id);\r\n   return;\r\n  }\r\n  // #21 \"almost\": close but not a match — flash the nearest candidate's outline + faint label, don't open it.\r\n  const near=nearestShape(strokes);\r\n  if(near&&MENUS[near.id]&&near.score>=ALMOST_COVER){\r\n   const rect=board?board.patternRect():fallbackRect(),info=idleShapeInfo(near.id,rect);\r\n   flashOutline(info.polys,info.color,{label:`Almost: ${info.label}`,labelPt:info.labelPt,duration:ALMOST_MS});\r\n   buzz([12,40,12]); // #29 double-pulse\r\n  }\r\n },450);\r\n}\r\nfunction wirePointerEvents(){\r\n overlay.addEventListener('pointerdown',e=>{ if(pointers.size>0){lastTap=null;}\r\n  stopHint(); // #22: any touch stops the first-run hint immediately, mid-animation or not.\r\n  overlay.setPointerCapture(e.pointerId);clearTimeout(finalizeTimer);\r\n  pointers.set(e.pointerId,{pts:[{x:e.clientX,y:e.clientY,t:performance.now()}],norm:[toNorm(e.clientX,e.clientY)],soundX:e.clientX,soundY:e.clientY,soundT:performance.now()});\r\n  if(pointers.size===1&&!busy)portalSound('press');\r\n  scheduleIdle();\r\n  if(busy)ripple(e.clientX,e.clientY);else board.press(e.pointerId,e.clientX,e.clientY);\r\n  kickRender();\r\n });\r\n overlay.addEventListener('pointermove',e=>{\r\n  const p=pointers.get(e.pointerId);if(!p)return;\r\n  p.pts.push({x:e.clientX,y:e.clientY,t:performance.now()});p.norm.push(toNorm(e.clientX,e.clientY));\r\n  if(pointers.size===1&&!busy&&performance.now()-p.soundT>115&&Math.hypot(e.clientX-p.soundX,e.clientY-p.soundY)>12){p.soundX=e.clientX;p.soundY=e.clientY;p.soundT=performance.now();portalSound('drag');}\r\n  if(!busy)board.press(e.pointerId,e.clientX,e.clientY);\r\n });\r\n overlay.addEventListener('pointerup',e=>endPointer(e,false));\r\n overlay.addEventListener('pointercancel',e=>endPointer(e,true));\r\n}\r\n\r\nfunction initialVisible(){\r\n return !(new URLSearchParams(location.search).has('panel')||location.hash==='#pod'||document.body.dataset.screen==='rest');\r\n}\r\n\r\nexport async function mountPortal({visible=false}={}){\r\n if(window.myr5Portal&&!window.myr5Portal.disposed)return window.myr5Portal;\r\n const lifetime=new AbortController();lifecycle=lifetime;\r\n buildDom();\r\n addEventListener('myr5:food-photo-ready',()=>expandScene(document.getElementById('mealsPanel')),{signal:lifecycle.signal});\r\n document.addEventListener('myr5:classroom-board',e=>{if(e.target?.id==='accountPanel')expandScene(e.target);},{signal:lifecycle.signal});\r\n document.addEventListener('room-ready',e=>{const f=framed;if(e.target?.id==='accountPanel'&&f?.dialog===e.target&&!f.expanded&&f.look.shaped){layoutInCut(e.target,true);clipTo(e.target,f.outlines.shape);}},{signal:lifecycle.signal});\r\n document.addEventListener('click',e=>{if(workoutHome?.open&&e.target.closest?.('#start')){setVisible(false);restoreWorkoutHome();workoutHome.close();}},{capture:true,signal:lifecycle.signal});\r\n for(const type of ['storage','pageshow'])addEventListener(type,syncLook,{signal:lifecycle.signal});\r\n if(menuBtn!==portalHome.querySelector('#portalExitButton'))menuBtn.addEventListener('click',()=>{if(busy)return;setVisible(!boardShown);},{signal:lifecycle.signal});\r\n boardBtn?.addEventListener('click',()=>setVisible(true),{signal:lifecycle.signal});\r\n addEventListener('pagehide',grimFlush,{signal:lifecycle.signal});document.addEventListener('visibilitychange',()=>{if(document.hidden)grimFlush();else if(boardShown&&!visibleSince)visibleSince=Date.now();},{signal:lifecycle.signal});\r\n addEventListener('myr5:portal-secret',e=>{const id=e.detail?.board||boardId;void showVaultDoor(id);},{signal:lifecycle.signal});\r\n // A 3D screen (the Vault from any route, food pyramid, ...) claims the GPU: hand the board back, rebuild 3D when it is free again.\r\n addEventListener('myr5:graphics-claim',e=>{if(!e.detail?.keep?.includes('portal'))e.detail?.wait?.(releasePortalGraphics());},{signal:lifecycle.signal});\r\n addEventListener('myr5:graphics-free',()=>{if(boardShown)threeD();},{signal:lifecycle.signal});\r\n await loadBoard(initialBoardId());\r\n await Promise.race([threeD(true),sleep(WAIT.mount)]); // come up in 3D when it's quick; never wait on a stalled one\r\n wirePointerEvents(); // Allocate the tunnel only when a transition actually needs it.\r\n resizeOverlay();overlayObserver=new ResizeObserver(resizeOverlay);overlayObserver.observe(portalHome);\r\n setVisible(visible&&initialVisible());\r\n // Back from a 'nav' portal via the bfcache: drop the stale glass and hole.\r\n let resumeAfterPageShow=false;\r\n addEventListener('pagehide',()=>{resumeAfterPageShow=boardShown;setVisible(false);},{signal:lifecycle.signal});\r\n addEventListener('pageshow',e=>{if(e.persisted&&resumeAfterPageShow)setVisible(true);},{signal:lifecycle.signal});\r\n // #104: pause/resume the idle cycle with the tab (a backgrounded tab must not keep animating).\r\n document.addEventListener('visibilitychange',scheduleIdle,{signal:lifecycle.signal});\r\n // Risk 4: a dialog over the quilt (setup gate, a reward reveal) that doesn't hide the portal still\r\n // blocks idleEligible() while open, but nothing then re-arms the idle timer once it closes. 'close'\r\n // doesn't bubble, but it still reaches a capturing listener on document for any dialog in the page.\r\n document.addEventListener('close',scheduleIdle,{capture:true,signal:lifecycle.signal});\r\n window.myr5Portal={\r\n  get disposed(){return lifetime.signal.aborted;},\r\n  dispose(){if(lifetime.signal.aborted)return;clearTimeout(idleTimer);idleTimer=0;idleCycle=null;setVisible(false);fading.length=0;boardLoad++;lifecycle.abort();overlayObserver?.disconnect();void disposeBoard(gl3);base?.dispose();gl3=base=board=null;menuChosen=true;menuSheet.close();menuSheet.remove();restoreWorkoutHome();workoutHome?.close();workoutHome?.remove();portalHome.remove();chrome.remove();energyAnims.length=0;void releaseTunnel();void import('./portal-peek.mjs').then(m=>m.releasePeekRendererIfIdle()).catch(()=>{});for(const cancel of flashes)cancel();window.myr5Portal=null;},\r\n  secret:id=>window.dispatchEvent(new CustomEvent('myr5:portal-secret',{detail:{board:id||boardId}})), // debug/test: same event the boards fire\r\n  show:()=>setVisible(true),\r\n  hide:()=>setVisible(false),\r\n  open:id=>runShape(id),\r\n  frameDirectDestination,\r\n  trace(strokes){const id=recognizeShape(strokes);if(MENUS[id])runShape(id);return MENUS[id]?id:null;},\r\n  board:id=>loadBoard(id).then(()=>ready3D), // resolves once 3D is drawing or has fallen back to the flat board\r\n  openWorkoutHome,\r\n  flashTransition:async({duration=520}={})=>{\r\n   duration=Number.isFinite(duration)?Math.max(0,Math.min(duration,10000)):520;\r\n   if(prefersReducedMotion())duration=0;\r\n   const flash=document.createElement('div');flash.className='portal-transition-flash';flash.setAttribute('aria-hidden','true');document.body.append(flash);\r\n   flash.style.setProperty('animation',`portal-transition-flash ${duration}ms ease-in-out both`,'important');\r\n   if(flash.showPopover){flash.setAttribute('popover','manual');flash.showPopover();}\r\n   window.dispatchEvent(new CustomEvent('myr5:portal-transition',{detail:{phase:'flash',duration}}));\r\n   if(!duration){flash.remove();window.dispatchEvent(new CustomEvent('myr5:portal-transition',{detail:{phase:'complete'}}));return;}\r\n   await new Promise((resolve,reject)=>{let timer;const finish=()=>{clearTimeout(timer);flashes.delete(cancel);resolve();},cancel=()=>{clearTimeout(timer);flash.remove();flashes.delete(cancel);reject(new DOMException('Portal closed.','AbortError'));};flashes.add(cancel);flash.addEventListener('animationend',finish,{once:true});timer=setTimeout(finish,duration+100);});\r\n   if(lifetime.signal.aborted){flash.remove();throw new DOMException('Portal closed.','AbortError');}\r\n   flash.remove();window.dispatchEvent(new CustomEvent('myr5:portal-transition',{detail:{phase:'complete'}}));\r\n  },\r\n  current:()=>board,\r\n  playWormhole, // #149: Meditation's early-stop smack exits through it (meditation.mjs throughWormhole)\r\n };\r\n if(window.__portalTrailProbe===true)window.myr5Portal.trailProbe=trailProbe;\r\n if(new URLSearchParams(location.search).has('vault'))void goVault(); // ?vault=1 boot, like ?board=\r\n return window.myr5Portal;\r\n}\r\n","modules/portal/standalone-housing.css":":root{--myr5-bar:calc(88px + env(safe-area-inset-bottom))}\r\n@media(orientation:landscape) and (max-height:500px){:root{--myr5-bar:calc(64px + env(safe-area-inset-bottom))}} /* R20: a lower console on landscape phones, every page alike */\r\n:is(#portalChrome,#cameraWorkout).portal-standalone{--portal-rail:15px;--pm:var(--portal-metal,#4d3d4f);}\r\n:is(#portalChrome,#cameraWorkout).portal-standalone .portal-frame{--face-left:15px;--face-top:15px;--face-width:calc(100vw - 30px);--face-height:calc(100dvh - 30px);}\r\n/* R20: the customizer's housing ends above its dock (the chrome stops at the dock's top edge: portal.css). */\r\n#portalChrome.portal-standalone .portal-frame{--face-height:calc(100dvh - 30px - var(--myr5-bar))}\r\n:is(#portalChrome,#cameraWorkout).portal-standalone .portal-standalone-aura{--ft:48px;--pk:30%;--ln:2px;position:absolute;z-index:60;inset:var(--portal-rail,15px);pointer-events:none;box-sizing:border-box;opacity:.95;background:linear-gradient(to bottom,var(--aura,#b026ff),transparent) top/100% var(--ln) no-repeat,linear-gradient(to top,var(--aura,#b026ff),transparent) bottom/100% var(--ln) no-repeat,linear-gradient(to right,var(--aura,#b026ff),transparent) left/var(--ln) 100% no-repeat,linear-gradient(to left,var(--aura,#b026ff),transparent) right/var(--ln) 100% no-repeat,linear-gradient(to bottom,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*1),transparent),color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.35),transparent) 30%,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.08),transparent) 65%,transparent) top/100% var(--ft) no-repeat,linear-gradient(to top,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*1),transparent),color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.35),transparent) 30%,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.08),transparent) 65%,transparent) bottom/100% var(--ft) no-repeat,linear-gradient(to right,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*1),transparent),color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.35),transparent) 30%,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.08),transparent) 65%,transparent) left/var(--ft) 100% no-repeat,linear-gradient(to left,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*1),transparent),color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.35),transparent) 30%,color-mix(in srgb,var(--aura,#b026ff) calc(var(--pk)*0.08),transparent) 65%,transparent) right/var(--ft) 100% no-repeat} /* R21 L2: --ft feather width, --pk peak opacity, --ln thin edge */\r\n#portalChrome.portal-standalone .portal-energy{opacity:.86}\r\n#portalChrome.portal-standalone .portal-energy.hot{opacity:1}\r\n:is(#portalChrome,#cameraWorkout).portal-standalone .portal-frame{box-shadow:0 0 0 calc(var(--portal-rail) + 1px) #0e0a12,0 8px 16px calc(var(--portal-rail) - 2px) #000b;}\r\n.editor-tilt-request{min-width:44px;min-height:40px;padding:0 10px;border:1px solid #e0c9ef;border-radius:999px;background:#201728e8;color:#fff;font:600 12px system-ui,sans-serif;pointer-events:auto;touch-action:manipulation}\r\n.editor-tilt-request:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n#coachDock.coach-dock a[aria-current=page]{color:#fff7e0;border-color:#ffb24d;background:#4d305f;box-shadow:0 0 0 1px #ffb24d,0 0 14px #ffb24d80}\r\n/* R20: the same 88px console as the app (portal.css draws it), full width at the bottom, keys in the app's order. */\r\n#coachDock.coach-dock{position:fixed;z-index:40;inset:auto 0 0!important;width:auto;margin:0}\r\n#coachDock.coach-dock>a{grid-column:auto!important}\r\n#coachDock.coach-dock a{text-decoration:none}\r\n#coachDock.coach-dock a.dock-portal{font:600 10px/1 system-ui,sans-serif;letter-spacing:.4px}\r\n#coachDock.coach-dock a.dock-control{position:relative;grid-row:1;box-sizing:border-box;width:44px;height:44px;min-width:44px;padding:0;display:grid;place-items:center;border:0;border-radius:0;background:none;box-shadow:none;filter:drop-shadow(0 3px 0 #130d18) drop-shadow(0 0 1px #000);color:#f4e4fa}\r\n#coachDock .dock-control>span{width:36px;height:36px;display:grid;place-items:center;color:#f6e5d5;background:linear-gradient(145deg,#a58a9c,#5a4560 55%,#3b2c42);box-shadow:inset 2px 2px #ffffff40,inset -2px -3px #0006}\r\n#coachDock .dock-settings>span{border-radius:50%}\r\n#coachDock .dock-food>span{width:40px;height:30px;border-radius:5px 5px 9px 9px}\r\n#coachDock .dock-scoreboard>span{border-radius:14px 14px 6px 6px}\r\n#coachDock .dock-achievements>span{clip-path:polygon(0 0,100% 0,100% 55%,50% 100%,0 55%);background:linear-gradient(145deg,#f2c46f,#b98033)}\r\n#coachDock .dock-pod>span{width:30px;border-radius:15px}\r\n#coachDock.coach-dock a.dock-control span{pointer-events:none}\r\n#coachDock.coach-dock a.dock-portal{position:absolute;grid-row:1;left:50%;top:50%;translate:-50% -50%;justify-self:center;box-sizing:border-box;width:62px;height:62px;min-width:62px;padding:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;border:2px solid #9a8295;border-top-color:#cbb5c5;border-bottom-color:#4b384d;border-radius:4px;background:linear-gradient(145deg,#806979,#4a394e 80%);box-shadow:0 0 0 3px #1c1421,0 6px 0 2px #130d18,inset 1px 2px #e0c3d366,inset -2px -3px #25182c99;color:#fff;font-size:10px;line-height:1}\r\n#coachDock.coach-dock svg{display:block}\r\n.editor-shell{translate:var(--editor-peer-x,0px) var(--editor-peer-y,0px);rotate:var(--editor-peer-tilt,0deg);}\r\n@media(prefers-reduced-motion:reduce){.editor-shell{translate:none!important;rotate:none!important}#portalChrome.portal-standalone .portal-standalone-aura{opacity:.8}}\r\n","modules/portal/standalone-housing.mjs":"import {readLook,applyLookVars,stripSeq} from './portal-look.mjs';\r\nimport {requestPhoneMotion,createTiltLook} from '../../character-phone-sensor.mjs';\r\n\r\nconst BOLTS=[[0,0],[1,0],[0,1],[1,1],[0,.33],[0,.67],[1,.33],[1,.67]];\r\nexport const frameMarkup=()=>`<div class=\"portal-frame\" aria-hidden=\"true\"><span class=\"portal-energy\">${'<span><span></span></span>'.repeat(4)}</span>${BOLTS.map(([x,y])=>`<i style=\"--x:${x};--y:${y}\"></i>`).join('')}<b>MOM INC</b></div><div class=\"portal-standalone-aura\" aria-hidden=\"true\"></div>`;\r\n\r\n/** Applies the saved metal colour and strip colour to a frameMarkup() host (shared with the camera workout). */\r\nexport function paintHousing(chrome,doc=document){const look=readLook();applyLookVars(doc.documentElement,look);chrome.style.setProperty('--portal-strip-glow',`${look.strip}40`);chrome.querySelector('.portal-standalone-aura')?.style.setProperty('--aura',look.strip);const seq=stripSeq(look.strip);for(const [i,channel] of [...chrome.querySelectorAll('.portal-energy>span')].entries()){channel.style.setProperty('--dir',i%2?'180deg':'90deg');channel.firstElementChild.style.background=`repeating-linear-gradient(${i%2?'180deg':'90deg'},${seq.map((color,j)=>`${color} ${j*90}px ${(j+1)*90}px`).join(',')})`;}}\r\n\r\n/** A lightweight persistent frame for the separately-loaded coach customizer. */\r\nexport async function mountStandaloneHousing({content=document.querySelector('.editor-shell'),doc=document}={}){\r\n if(!content||!doc)return ()=>{};\r\n const view=doc.defaultView;let leftEarly=false;\r\n const beforeReady=event=>{if(!event.persisted)leftEarly=true;};view?.addEventListener('pagehide',beforeReady);\r\n const loadCss=href=>new Promise((resolve,reject)=>{const link=doc.createElement('link');link.rel='stylesheet';link.href=href;link.onload=()=>resolve(link);link.onerror=()=>reject(Error(`Could not load ${href}`));doc.head.append(link);});\r\n const links=await Promise.all(['/modules/portal/portal.css','/modules/portal/standalone-housing.css'].map(loadCss));\r\n if(leftEarly){links.forEach(link=>link.remove());view?.removeEventListener('pagehide',beforeReady);return ()=>{};}\r\n doc.getElementById('coachDock')?.classList.add('ship-control-deck');\r\n let chrome=doc.getElementById('portalChrome');if(!chrome){chrome=doc.createElement('div');chrome.id='portalChrome';chrome.setAttribute('popover','manual');chrome.setAttribute('aria-hidden','true');doc.body.append(chrome);}\r\n chrome.classList.add('portal-standalone');chrome.innerHTML=frameMarkup();\r\n const face=()=>{const rail=15;for(const [key,value] of Object.entries({left:rail,top:rail,width:Math.max(1,innerWidth-2*rail),height:Math.max(1,innerHeight-2*rail-(doc.getElementById('coachDock')?.getBoundingClientRect().height||0))}))chrome.style.setProperty('--face-'+key,value+'px');};\r\n const updateLook=()=>paintHousing(chrome,doc);\r\n face();updateLook();\r\n if(chrome.showPopover){if(!chrome.matches(':popover-open'))chrome.showPopover();}else chrome.removeAttribute('popover');\r\n const reduced=view?.matchMedia?.('(prefers-reduced-motion: reduce)');let raf=0,tx=0,ty=0,x=0,y=0,disposed=false,last=0;const look=createTiltLook(view);\r\n const requestTilt=()=>{if(!disposed&&!raf&&!doc.hidden&&!reduced?.matches)raf=requestAnimationFrame(step);};\r\n const pointer=e=>{if(disposed||reduced?.matches||doc.hidden)return;tx=Math.max(-1,Math.min(1,(e.clientX/Math.max(1,view.innerWidth)-.5)*2));ty=Math.max(-1,Math.min(1,(e.clientY/Math.max(1,view.innerHeight)-.5)*2));requestTilt();};\r\n const step=now=>{raf=0;const k=last?1-Math.exp(-Math.min(100,now-last)/300):.055;last=now;x+=(tx-x)*k;y+=(ty-y)*k;content.style.setProperty('--editor-peer-x',(x*2.5).toFixed(2)+'px');content.style.setProperty('--editor-peer-y',(y*2.5).toFixed(2)+'px');content.style.setProperty('--editor-peer-tilt',(x*.65).toFixed(2)+'deg');if(Math.abs(tx-x)+Math.abs(ty-y)>.01)raf=requestAnimationFrame(step);else last=0;};\r\n const orientation=event=>{if(disposed||reduced?.matches||doc.hidden)return;const t=look.read(event,view.performance.now());if(!t)return;tx=t.x;ty=t.y;requestTilt();};\r\n const allowTilt=async()=>{try{const granted=await requestPhoneMotion();if(disposed)return;if(granted){view.addEventListener('deviceorientation',orientation);chip?.remove();}}catch{}}\r\n const chip=view?.DeviceOrientationEvent?.requestPermission?doc.createElement('button'):null;\r\n if(chip){chip.type='button';chip.className='editor-tilt-request';chip.textContent='Enable tilt';chip.setAttribute('aria-label','Enable device tilt to look around');(doc.querySelector('.view-buttons')||doc.querySelector('.preview-toolbar')||content).append(chip);chip.addEventListener('click',allowTilt);}\r\n else if(view?.DeviceOrientationEvent)view.addEventListener('deviceorientation',orientation);\r\n const resize=()=>face(),storage=e=>{if(!e.key||e.key.startsWith('myr5.portal'))updateLook();};\r\n const clearPeer=()=>{tx=ty=x=y=0;content.style.removeProperty('--editor-peer-x');content.style.removeProperty('--editor-peer-y');content.style.removeProperty('--editor-peer-tilt');};\r\n const onVisibility=()=>{look.reset();if(doc.hidden){clearPeer();cancelAnimationFrame(raf);raf=0;last=0;}else requestTilt();};\r\n const onReduced=()=>{if(reduced.matches){clearPeer();cancelAnimationFrame(raf);raf=0;last=0;}else requestTilt();};\r\n const dispose=()=>{if(disposed)return;disposed=true;cancelAnimationFrame(raf);doc.removeEventListener('visibilitychange',onVisibility);view?.removeEventListener('pagehide',pagehide);view?.removeEventListener('pointermove',pointer);view?.removeEventListener('resize',resize);view?.removeEventListener('storage',storage);view?.removeEventListener('focus',updateLook);view?.removeEventListener('deviceorientation',orientation);reduced?.removeEventListener?.('change',onReduced);chip?.remove();clearPeer();chrome.hidePopover?.();chrome.remove();links.forEach(link=>link.remove());};\r\n const pagehide=event=>{if(!event.persisted)dispose();};\r\n view?.removeEventListener('pagehide',beforeReady);view?.addEventListener('pagehide',pagehide);view?.addEventListener('pointermove',pointer,{passive:true});view?.addEventListener('resize',resize);view?.addEventListener('storage',storage);view?.addEventListener('focus',updateLook);doc.addEventListener('visibilitychange',onVisibility);reduced?.addEventListener?.('change',onReduced);\r\n return dispose;\r\n}\r\n","modules/rooms/classroom.css":".classroom-panel[data-room=loading],.classroom-panel[data-room=ready]{height:min(100dvh - 28px,900px);overflow:hidden}\r\n.classroom-panel[data-room]:not([data-room-view=board])[open]{display:block;padding:0;position:relative}\r\n.classroom-panel[data-room]:not([data-room-view=board])>:not(header,.classroom-host,#coachDock,.portal-peer-ui){display:none!important}\r\n.classroom-panel[data-room]:not([data-room-view=board])>header{position:absolute;z-index:3;inset:0 0 auto;margin:0;padding:12px 14px 10px;background:transparent;border:0;box-shadow:none;pointer-events:none}\r\n.classroom-panel[data-room]:not([data-room-view=board])>header>*{pointer-events:auto}\r\n.classroom-host{position:relative}\r\n.classroom-panel[data-room]:not([data-room-view=board]) .classroom-host{position:absolute;inset:0;min-height:0}\r\n.classroom-stage{position:absolute;inset:0;overflow:hidden;background:#d9c9b0}\r\n.classroom-canvas,.classroom-fallback,.classroom-desks,.classroom-ui{position:absolute;inset:0;width:100%;height:100%}\r\n.classroom-fallback{background:linear-gradient(180deg,#b6a182 0 64%,#a79681 64%);pointer-events:none}\r\n.classroom-fallback[hidden]{display:none}\r\n.classroom-desks,.classroom-ui{pointer-events:none}\r\n.classroom-desks{z-index:2}.classroom-ui{z-index:1}\r\n.classroom-desks>*,.classroom-ui>*{pointer-events:auto}\r\n#accountPanel.classroom-panel .classroom-board{position:absolute;left:29%;top:12%;width:42%;height:35%;display:grid;place-items:end center;padding:0 0 8px;background:transparent;border:3px dashed transparent;border-radius:6px;box-shadow:none;cursor:pointer;transform:none}\r\n.classroom-panel .classroom-board span{font:17px/1.2 BoardHand0,cursive;color:#35507a;background:#fffdf5e8;padding:3px 10px;border-radius:12px}\r\n.classroom-panel .classroom-board:hover,.classroom-panel .classroom-board:focus-visible{border-color:#174b92;outline:2px solid #174b92}\r\n.classroom-desk{position:absolute;top:63%;transform:translate(-50%,-100%);display:grid;justify-items:center}\r\n.classroom-desk:first-child{left:27%}.classroom-desk:nth-child(2){left:73%}\r\n#accountPanel .classroom-desk .crew-head{width:58px;height:58px;background:transparent;border:0;box-shadow:none}\r\n.classroom-desk .crew-head canvas{width:54px;height:54px}\r\n.classroom-desk figure{margin:0;display:grid;justify-items:center;gap:3px}\r\n.classroom-desk figure{animation:classroom-pop .55s cubic-bezier(.2,.8,.2,1) both}\r\n@keyframes classroom-pop{from{opacity:0;transform:translateY(16px) scale(.9)}to{opacity:1;transform:translateY(0) scale(1)}}\r\n@media(prefers-reduced-motion:reduce){.classroom-desk figure{animation:none}}\r\n.classroom-desk figcaption{font:700 13px/1.2 Arial,sans-serif;color:#2e3e56;background:#fffdf5e6;padding:2px 8px;border-radius:9px;max-width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n#accountPanel .classroom-desk button{display:grid;place-items:center;width:54px;height:54px;min-width:0;min-height:0;padding:0;border-radius:50%;font:17px/1 BoardHand0,cursive}\r\n#accountPanel .classroom-desk button b{font:700 29px/1 Arial,sans-serif}\r\n#accountPanel .classroom-desk button span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}\r\n.classroom-note{position:absolute;bottom:10px;left:10px;right:10px;text-align:center;background:#fffdf5dd;padding:5px;border-radius:6px;font:15px Arial,sans-serif}\r\n.classroom-panel[data-room-view=board]{height:auto;max-height:calc(100dvh - 28px);overflow-y:auto;background:linear-gradient(110deg,#fbf8ef,#f1ede2);border-color:#a7a49c}\r\n.classroom-panel[data-room-view=board] .classroom-host{display:none}\r\n","modules/rooms/classroom.mjs":"import {buildPaperCrawler} from './paper-crawler.mjs';\r\nimport {claimGraphics} from '../graphics-lifecycle.mjs';\r\n// Optional scoreboard classroom. Mounted only while the scoreboard dialog is open.\r\nconst CLASS={fov:40,eye:[0,.5,1.6],look:[0,.5,0],desks:{at:[0,.15,.14],scale:.75},board:{min:[-.29,.52,-.42],max:[.29,.83,-.42]},heads:[[-.19,.44,.28],[.19,.44,.28]]};\r\nlet stylesheet;\r\nfunction loadStyle(){return stylesheet??=new Promise(resolve=>{const link=document.createElement('link');link.rel='stylesheet';link.href='/modules/rooms/classroom.css';link.onload=link.onerror=resolve;document.head.append(link);});}\r\nexport function mountClassroom(panel,{host=panel.querySelector('[data-room-host]')}={}){\r\n if(!host){host=document.createElement('div');host.dataset.roomHost='';panel.querySelector('header')?.after(host);}\r\n host.classList.add('classroom-host');host.innerHTML='<div class=\"classroom-stage room-stage\"><div class=\"classroom-fallback\" data-peer-depth=\"far\" aria-hidden=\"true\"></div><div class=\"classroom-desks\" data-peer-depth=\"mid\"></div><div class=\"classroom-ui\" data-peer-depth=\"near\"><button type=\"button\" class=\"classroom-board\" data-room-board aria-label=\"Open the scoreboard whiteboard\"><span>Tap the board</span></button></div><p class=\"classroom-note\" role=\"status\">Entering classroom…</p></div>';\r\n panel.dataset.room='loading';delete panel.dataset.roomView;\r\n const stage=host.querySelector('.classroom-stage'),desksLayer=host.querySelector('.classroom-desks'),boardButton=host.querySelector('.classroom-board'),note=host.querySelector('.classroom-note');\r\n let disposed=false,releaseGpu=null,renderer=null,scene=null,camera=null,resizeObserver=null,raf=0,slots=[],three=null;\r\n let scary=false,crawler=null,hemisphere=null,sunlight=null,origin=performance.now(),stopAnimation=()=>{};\r\n const reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n function showBoard(){if(disposed||panel.dataset.roomView==='board')return;cancelAnimationFrame(raf);raf=0;panel.dispatchEvent(new CustomEvent('myr5:classroom-board',{bubbles:true}));panel.dataset.roomView='board';panel.scrollTop=0;(panel.querySelector('#accountContent:not([hidden]) h3, #signIn')||panel).focus?.({preventScroll:true});}\r\n function setDesks(nodes){if(disposed)return;desksLayer.replaceChildren();slots=[];for(const node of nodes.slice(0,2)){const slot=document.createElement('div');slot.className='classroom-desk';slot.append(node);desksLayer.append(slot);slots.push(slot);}place();}\r\n function place(){if(!camera||!stage.isConnected)return;const rect=stage.getBoundingClientRect();if(!rect.width||!rect.height)return;const project=(x,y,z)=>{const p=new three.Vector3(x,y,z).project(camera);return [(p.x+1)*rect.width/2,(1-p.y)*rect.height/2];};const [x0,y0]=project(CLASS.board.min[0],CLASS.board.max[1],CLASS.board.min[2]),[x1,y1]=project(CLASS.board.max[0],CLASS.board.min[1],CLASS.board.max[2]);Object.assign(boardButton.style,{left:x0+'px',top:y0+'px',width:Math.max(44,x1-x0)+'px',height:Math.max(44,y1-y0)+'px'});slots.forEach((slot,i)=>{const [x,y]=project(...CLASS.heads[i]);slot.style.left=x+'px';slot.style.top=y+'px';});}\r\n function dispose(){if(disposed)return;disposed=true;stopAnimation();cancelAnimationFrame(raf);resizeObserver?.disconnect();if(scene){scene.traverse(node=>{node.geometry?.dispose();for(const material of [].concat(node.material||[])){if(!material)continue;for(const value of Object.values(material))if(value?.isTexture)value.dispose();material.dispose();}});}renderer?.dispose();renderer?.forceContextLoss();releaseGpu?.(renderer?.domElement);releaseGpu=null;host.replaceChildren();delete panel.dataset.room;delete panel.dataset.roomView;panel.dispatchEvent(new CustomEvent('room-gone',{bubbles:true}));}\r\n boardButton.onclick=showBoard;\r\n const controller={setDesks,showBoard,dispose};\r\n const ready=(async()=>{\r\n  await loadStyle();if(disposed)return;\r\n  try{\r\n   const [THREE,{GLTFLoader}]=await Promise.all([import('three'),import('three/addons/loaders/GLTFLoader.js')]);\r\n   const loader=new GLTFLoader();const [wall,desks]=await Promise.all(['/pod/rooms/classroom-wall.glb','/pod/rooms/classroom-desks.glb'].map(url=>loader.loadAsync(url).then(g=>g.scene)));\r\n   if(disposed){for(const root of [wall,desks])root.traverse(n=>{n.geometry?.dispose();for(const m of [].concat(n.material||[]))m?.dispose();});return;}\r\n   releaseGpu=claimGraphics('classroom',{keep:['portal']});await releaseGpu.ready; // the hidden 3D coach yields; back on close\r\n   if(disposed){releaseGpu();releaseGpu=null;for(const root of [wall,desks])root.traverse(n=>{n.geometry?.dispose();for(const m of [].concat(n.material||[]))m?.dispose();});return;}\r\n   const canvas=document.createElement('canvas');canvas.className='classroom-canvas';canvas.dataset.peerDepth='far';canvas.setAttribute('aria-hidden','true');stage.prepend(canvas);\r\n   renderer=new THREE.WebGLRenderer({canvas,antialias:true,powerPreference:'low-power'});renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.setPixelRatio(Math.min(devicePixelRatio||1,2));\r\n   scene=new THREE.Scene();scene.background=new THREE.Color('#d9c9b0');hemisphere=new THREE.HemisphereLight(0xfff4e6,0x8a7a66,2.2);scene.add(hemisphere);const sun=new THREE.DirectionalLight(0xffe2bd,2.4);sunlight=sun;sun.position.set(-1,2,2.5);scene.add(sun);desks.position.set(...CLASS.desks.at);desks.scale.setScalar(CLASS.desks.scale);scene.add(wall,desks);\r\n   const floor=new THREE.Mesh(new THREE.PlaneGeometry(3,3),new THREE.MeshStandardMaterial({color:'#c3b6a3',roughness:1}));floor.rotation.x=-Math.PI/2;floor.position.z=.9;scene.add(floor);\r\n   const paperMat=new THREE.MeshStandardMaterial({color:0xc9b68f,roughness:1}),suitMat=new THREE.MeshStandardMaterial({color:0x544438,roughness:1}),caseMat=new THREE.MeshStandardMaterial({color:0x24231e,roughness:1});\r\n   crawler=buildPaperCrawler(THREE,{paperMat,suitMat,caseMat});crawler.root.scale.setScalar(.19);crawler.root.rotation.y=-Math.PI/2;crawler.root.visible=false;scene.add(crawler.root);\r\n   // Clip the lower three quarters at the desk edge. All parts use one renderer.\r\n   renderer.localClippingEnabled=true;const deskEdge=new THREE.Plane(new THREE.Vector3(0,1,0),-.285);\r\n   crawler.root.traverse(node=>{if(node.material){node.material.clippingPlanes=[deskEdge];node.material.needsUpdate=true;}});\r\n   camera=new THREE.PerspectiveCamera(CLASS.fov,1,.05,20);camera.position.set(...CLASS.eye);camera.lookAt(...CLASS.look);three=THREE;\r\n   function resize(){if(disposed)return;const r=stage.getBoundingClientRect();if(!r.width||!r.height)return;renderer.setSize(r.width,r.height,false);camera.aspect=r.width/r.height;camera.updateProjectionMatrix();place();renderer.render(scene,camera);}\r\n   function animate(now){raf=0;if(disposed||document.hidden||!panel.open||panel.dataset.roomView==='board')return;const elapsed=now-origin,phase=elapsed%15000,on=!reduced.matches&&elapsed>=15000&&phase<4200;\r\n    const flicker=on?(phase<450?(.12+.11*Math.abs(Math.sin(phase*.065))):phase<3600?.13:Math.min(1,.13+(phase-3600)/600)):1;\r\n    hemisphere.intensity=2.2*flicker;sunlight.intensity=2.4*flicker;stage.classList.toggle('classroom-dim',on);\r\n    if(on!==scary){scary=on;window.dispatchEvent(new CustomEvent(on?'myr5:music-cut':'myr5:music-resume'));}\r\n    crawler.root.visible=on;if(on){crawler.root.position.set(-.8+phase/4200*1.6,.18,.48);crawler.pose(phase/1000);}\r\n    renderer.render(scene,camera);if(!reduced.matches)raf=requestAnimationFrame(animate);\r\n   }\r\n   const visible=()=>{cancelAnimationFrame(raf);raf=0;if(scary&&(document.hidden||!panel.open||panel.dataset.roomView==='board')){scary=false;window.dispatchEvent(new CustomEvent('myr5:music-resume'));}if(!disposed&&!document.hidden&&panel.open&&panel.dataset.roomView!=='board')raf=requestAnimationFrame(animate);};\r\n   const roomView=new MutationObserver(visible);roomView.observe(panel,{attributes:true,attributeFilter:['data-room-view','open']});\r\n   stopAnimation=()=>{if(scary){scary=false;window.dispatchEvent(new CustomEvent('myr5:music-resume'));}roomView.disconnect();document.removeEventListener('visibilitychange',visible);cancelAnimationFrame(raf);raf=0;};\r\n   document.addEventListener('visibilitychange',visible);panel.addEventListener('close',stopAnimation,{once:true});visible();\r\n   resizeObserver=new ResizeObserver(resize);resizeObserver.observe(stage);resize();panel.dataset.room='ready';note.hidden=true;stage.querySelector('.classroom-fallback').hidden=true;\r\n   panel.dispatchEvent(new CustomEvent('room-ready',{bubbles:true,detail:controller}));\r\n  }catch(error){if(disposed)return;panel.dataset.room='ready';note.textContent='Classroom art is unavailable on this device.';const download=document.createElement('button');download.type='button';download.textContent='Download classroom';download.onclick=()=>window.myr5Packs?.open?.('room-scoreboard');note.append(' ',download);panel.dispatchEvent(new CustomEvent('room-ready',{bubbles:true,detail:controller}));console.warn('Classroom art unavailable',error);}\r\n })();\r\n return {...controller,ready};\r\n}\r\n","modules/rooms/paper-crawler.mjs":"export function buildPaperCrawler(THREE,{paperMat,suitMat,caseMat}){\r\n const g=new THREE.Group();\r\n const eyeMat=new THREE.MeshStandardMaterial({color:0x0a0806,roughness:1});\r\n // helpers\r\n const grp=(x,y,z,p)=>{const o=new THREE.Group();o.position.set(x,y,z);(p||g).add(o);return o;}\r\n const part=(geo,mat,x,y,z,p)=>{const m=new THREE.Mesh(geo,mat);m.position.set(x,y,z);(p||g).add(m);return m;}\r\n // body constants\r\n const THIGH=0.6, SHIN=0.45, SPINE=0.68, UARM=0.34, FARM=0.32;\r\n const HIP_Y=0.7, HIP_Z=-0.45; // crawling pose\r\n // pelvis & torso\r\n part(new THREE.BoxGeometry(0.34,0.2,0.22),suitMat,0,HIP_Y,HIP_Z);\r\n const torso=grp(0,HIP_Y,HIP_Z);torso.rotation.x=Math.PI/2+0.25;\r\n // chest\r\n part(new THREE.CylinderGeometry(0.21,0.15,SPINE,10),suitMat,0,SPINE/2,0,torso).scale.z=0.62;\r\n for(const s of[-1,1])part(new THREE.SphereGeometry(0.08,10,8),suitMat,s*0.26,SPINE-0.05,0,torso);\r\n // neck\r\n const neck=grp(0,SPINE,0,torso); part(new THREE.CylinderGeometry(0.06,0.07,0.16,8),paperMat,0,0.06,0,neck);\r\n // head\r\n const head=grp(0,0,0);head.rotation.order='YXZ';\r\n part(new THREE.SphereGeometry(0.17,16,12),paperMat,0,0,0,head).scale.set(1,1.12,0.95);\r\n part(new THREE.SphereGeometry(0.1,12,8),paperMat,0,-0.14,0.05,head).scale.set(1,0.55,0.9);\r\n for(const s of[-1,1])part(new THREE.SphereGeometry(0.036,8,6),eyeMat,s*0.065,0.035,0.135,head);\r\n const nose=part(new THREE.ConeGeometry(0.03,0.08,6),paperMat,0,-0.035,0.19,head);nose.rotation.x=Math.PI/2;\r\n part(new THREE.SphereGeometry(0.175,12,8,0,Math.PI*2,0,Math.PI*0.4),caseMat,0,0.012,-0.012,head).scale.set(1,1.12,0.97);\r\n // limb builder\r\n const limb=(px,py,pz,upLen,loLen,upR,loR)=>{const up=grp(px,py,pz);part(new THREE.CylinderGeometry(upR,upR*0.82,upLen,8),suitMat,0,-upLen/2,0,up);\r\n  part(new THREE.SphereGeometry(upR*1.05,8,6),suitMat,0,-upLen,0,up);const lo=grp(0,-upLen,0,up);part(new THREE.CylinderGeometry(loR,loR*0.85,loLen,8),suitMat,0,-loLen/2,0,lo);\r\n  return{upper:up,lower:lo};}\r\n const armL=limb(0,0,0,UARM,FARM,0.05,0.04),armR=limb(0,0,0,UARM,FARM,0.05,0.04);\r\n const legL=limb(-0.1,HIP_Y,HIP_Z,THIGH,SHIN,0.075,0.06),legR=limb(0.1,HIP_Y,HIP_Z,THIGH,SHIN,0.075,0.06);\r\n // feet\r\n for(const leg of[legL,legR]){const foot=grp(0,-SHIN,0,leg.lower);foot.rotation.x=Math.PI-( -0.15+Math.PI/2-0.1 );part(new THREE.BoxGeometry(0.11,0.06,0.27),caseMat,0,-0.02,0.08,foot);}\r\n // hands\r\n const handL=grp(0,-FARM,0,armL.lower);const handR=grp(0,-FARM,0,armR.lower);\r\n part(new THREE.BoxGeometry(0.09,0.11,0.035),paperMat,0,-0.055,0,handL);part(new THREE.BoxGeometry(0.09,0.11,0.035),paperMat,0,-0.055,0,handR);\r\n for(const h of[handL,handR])for(const fx of[-0.028,0,0.028])part(new THREE.BoxGeometry(0.018,0.075,0.022),paperMat,fx,-0.145,0,h);\r\n // rest rotations\r\n armL.upper.rotation.set(-0.45,0,0);armR.upper.rotation.set(-0.45,0,0);\r\n armL.lower.rotation.x=armR.lower.rotation.x=-0.3;\r\n legL.upper.rotation.x=legR.upper.rotation.x=-0.15;\r\n legL.lower.rotation.x=legR.lower.rotation.x=Math.PI/2-0.1;\r\n head.rotation.x=0.3;\r\n // layout\r\n const v=new THREE.Vector3();\r\n function layout(dip){torso.rotation.x=Math.PI/2+0.25;const lift=0.1-0.17*dip;\r\n  v.set(0,SPINE+0.26,0).applyEuler(torso.rotation);head.position.set(v.x,HIP_Y+v.y+lift,HIP_Z+v.z);\r\n  v.set(-0.27,SPINE-0.06,0).applyEuler(torso.rotation);armL.upper.position.set(v.x,HIP_Y+v.y,HIP_Z+v.z);\r\n  v.set(0.27,SPINE-0.06,0).applyEuler(torso.rotation);armR.upper.position.set(v.x,HIP_Y+v.y,HIP_Z+v.z);}\r\n layout(0);\r\n // pose function\r\n const rest={headP:0.3,armU:-0.45,armL:-0.3,legU:-0.15,legL:Math.PI/2-0.1};\r\n function pose(seconds){const t=seconds*4*Math.PI; // 2Hz\r\n  armL.upper.rotation.x=rest.armU+0.4*Math.sin(t);armR.upper.rotation.x=rest.armU+0.4*Math.cos(t);\r\n  armL.lower.rotation.x=rest.armL+0.3*Math.sin(t);armR.lower.rotation.x=rest.armL+0.3*Math.cos(t);\r\n  legL.upper.rotation.x=rest.legU+0.5*Math.sin(t+Math.PI/2);legR.upper.rotation.x=rest.legU+0.5*Math.cos(t+Math.PI/2);\r\n  legL.lower.rotation.x=rest.legL+0.4*Math.sin(t+Math.PI/2);legR.lower.rotation.x=rest.legL+0.4*Math.cos(t+Math.PI/2);\r\n  const dip=Math.abs(Math.sin(t*3));layout(dip);}\r\n g.visible=true;\r\n return{root:g,pose};\r\n}","modules/rooms/reminders-computer.css":"/* reminders-computer:glb-v2 */\r\n.reminders-computer-offer{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:0 0 12px}\r\n.reminders-computer-offer button{min-height:44px}\r\n.reminders-computer-offer span{font-size:12px}\r\n#remindersPanel[data-reminder-room=ready]{\r\n position:fixed;inset:3dvh auto auto 50%;transform:translateX(-50%);\r\n box-sizing:border-box;width:min(620px,calc(100vw - 16px));height:94dvh;max-width:none;max-height:none;\r\n padding:0!important;overflow:hidden;overscroll-behavior:contain;border:0!important;border-radius:0!important;\r\n background:transparent!important;box-shadow:none!important;color:#efe7ff;isolation:isolate;\r\n}\r\n/* A portal face can be smaller than a viewport. Keep the model and its fitted screen inside that face. */\r\n#remindersPanel.portal-framed[data-reminder-room=ready]{\r\n inset:var(--face-top) auto auto var(--face-left);width:var(--face-width);height:var(--face-height);transform:none;\r\n}\r\n#remindersPanel[data-reminder-room=ready]>.reminders-computer-stage,\r\n#remindersPanel[data-reminder-room=ready]>.reminders-computer-screen{position:absolute;inset:0;box-sizing:border-box}\r\n#remindersPanel[data-reminder-room=ready]>.reminders-computer-stage{z-index:0;pointer-events:none;overflow:hidden}\r\n.reminders-computer-canvas{display:block;width:100%;height:100%;pointer-events:none}\r\n#remindersPanel[data-reminder-room=ready]>.reminders-computer-screen{\r\n z-index:1;inset:auto;overflow:auto;overscroll-behavior:contain;padding:8px 10px;\r\n border:1px solid #8e6cc4;border-radius:8px;background:#21172feF;scrollbar-color:#9670bc #21172f;\r\n}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen>header{\r\n display:flex;justify-content:space-between;align-items:center;gap:10px;\r\n margin:0 0 8px;padding:5px 0 8px;background:transparent;border:0;border-bottom:1px solid #8e6cc4;border-radius:0;\r\n}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen h2{font-size:18px;margin:0}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen p{margin:6px 0}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen .status{padding:5px 8px;min-height:0}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen form{gap:8px}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen label{font-size:12px;gap:3px}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen input,\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen select{padding:7px;font-size:16px}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen .fields{gap:7px}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen button{min-height:40px;padding:6px 9px}\r\n#remindersPanel[data-reminder-room=ready] .reminders-computer-screen .reminders-computer-offer{display:none}\r\n#remindersPanel[data-reminder-room=ready]:focus-visible{outline:2px solid #b99cff;outline-offset:-2px}\r\n#remindersPanel[data-reminder-room=ready]::backdrop{background:radial-gradient(ellipse at 50% 40%,#3a1d63e6,#07040de6 70%)}\r\n#remindersPanel[data-reminder-room=ready]{touch-action:pan-y}\r\n#remindersPanel[data-reminder-room=ready] :is(button,input,select,textarea,a,label,summary){cursor:auto}\r\n@media(max-width:390px){#remindersPanel[data-reminder-room=ready]>.reminders-computer-screen{padding:6px 7px}}\r\n@media(prefers-reduced-motion:reduce){#remindersPanel[data-reminder-room=ready]{scroll-behavior:auto}}\r\n","modules/rooms/reminders-computer.mjs":"import * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {claimGraphics} from '../graphics-lifecycle.mjs';\r\n\r\nconst MODEL='/pod/rooms/console.glb',STYLE='/modules/rooms/reminders-computer.css';\r\nconst MAX_SPIN=10,KEY_STEP=2,DRAG_DEG_PER_PX=.16,DRAG_SLOP=8;\r\nconst INTERACTIVE='button,input,select,textarea,a,label,summary,[contenteditable]';\r\nconst SCREEN={left:-.185,right:.185,bottom:.39,top:.66,z:.115};\r\nconst MODEL_CENTER=new THREE.Vector3(0,.515,.10668);\r\nconst MODEL_SIZE=new THREE.Vector3(.527069,.9804382,.481444);\r\nconst REDUCED=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n\r\nexport const spinBy=(spin,delta)=>Math.max(-MAX_SPIN,Math.min(MAX_SPIN,spin+delta));\r\n\r\nconst current=(panel,token,epoch)=>!token.disposed&&token.epoch===epoch&&panel.open&&panel.isConnected;\r\nasync function cachedRoomAssets(isCurrent){\r\n const storage=globalThis.caches;\r\n if(!storage?.keys||!storage?.open)throw new Error('The optional Reminders room is not downloaded.');\r\n const names=await storage.keys();if(!isCurrent())return null;\r\n // CacheStorage returns names in creation order. Search newest first so an old retained shell cannot\r\n // shadow the complete packet installed later; model and stylesheet must come from the same store.\r\n for(const name of names.reverse()){\r\n  const store=await storage.open(name);if(!isCurrent())return null;\r\n  const model=await store.match(MODEL);if(!isCurrent())return null;\r\n  if(!model?.ok)continue;\r\n  let style=await store.match(STYLE);if(!isCurrent())return null;\r\n  let styleText=style?.ok?await style.clone().text():'';if(!isCurrent())return null;\r\n  if(!styleText.includes('reminders-computer:glb-v2')){\r\n   // A previous release may already have the large model. Refresh only the small stylesheet\r\n   // from the current release and place it beside that model; never redownload the GLB here.\r\n   try{\r\n    const response=await fetch(STYLE,{cache:'no-store'});if(!isCurrent())return null;\r\n    if(response.ok){const updated=response.clone(),candidate=await response.text();if(!isCurrent())return null;\r\n     if(candidate.includes('reminders-computer:glb-v2')){await store.put(STYLE,updated);if(!isCurrent())return null;styleText=candidate;}\r\n    }\r\n   }catch{}\r\n  }\r\n  if(!styleText.includes('reminders-computer:glb-v2'))continue;\r\n  return {model,styleText};\r\n }\r\n throw new Error('The optional Reminders room is not downloaded.');\r\n}\r\n\r\nfunction useStyle(text,token){\r\n let style=document.getElementById('remindersComputerStyle');\r\n if(!style){style=document.createElement('style');style.id='remindersComputerStyle';document.head.append(style);}\r\n style.textContent=text;token.style=style;\r\n}\r\nfunction loadingManager(){\r\n const manager=new THREE.LoadingManager();\r\n manager.setURLModifier(url=>{\r\n  if(/^(?:data:|blob:)/i.test(url))return url;\r\n  throw new Error('The Reminders model contains an external dependency.');\r\n });\r\n return manager;\r\n}\r\n\r\nfunction releaseObject(root){\r\n const geometries=new Set(),materials=new Set(),textures=new Set(),images=new Set();\r\n root?.traverse?.(node=>{\r\n  if(node.geometry)geometries.add(node.geometry);\r\n  for(const material of [].concat(node.material||[]))if(material){materials.add(material);for(const value of Object.values(material))if(value?.isTexture)textures.add(value);}\r\n });\r\n for(const texture of textures){const image=texture.source?.data??texture.image;if(image&&typeof image.close==='function')images.add(image);texture.dispose();}\r\n for(const geometry of geometries)geometry.dispose();for(const material of materials)material.dispose();\r\n for(const image of images)try{image.close();}catch{}\r\n}\r\nfunction releaseView(view){\r\n if(!view||view.disposed)return;view.disposed=true;cancelAnimationFrame(view.raf);view.resize?.disconnect();\r\n for(const [target,name,fn] of view.listeners)target.removeEventListener(name,fn);\r\n releaseObject(view.scene);view.renderer?.dispose();view.renderer?.forceContextLoss();view.releaseGpu?.(view.canvas);\r\n view.canvas?.remove();view.screen?.remove();\r\n}\r\n\r\nexport function makeCords(scene){\r\n const colors=[0x52e4ff,0xff45d5,0xffc95c,0x9d78ff,0x52e4ff,0xff45d5,0xffc95c,0x4cc9e8,0xff6eac,0xa38aff,0xf3a765,0x53dfca,0x8cd6ff];\r\n const paths=[\r\n  [[-.22,1.02,-.28],[-.35,.92,-.32],[-.4,.75,-.34],[-.31,.65,-.32],[-.29,.55,-.31],[-.39,.47,-.34],[-.37,.3,-.32],[-.29,.12,-.31]],\r\n  [[.22,1,-.27],[.34,.9,-.32],[.4,.73,-.34],[.31,.63,-.32],[.29,.52,-.31],[.4,.43,-.34],[.37,.27,-.32],[.3,.08,-.31]],\r\n  [[-.2,.83,-.32],[-.34,.78,-.35],[-.41,.67,-.36],[-.36,.59,-.34],[-.29,.64,-.32],[-.36,.72,-.34],[-.43,.63,-.36],[-.39,.48,-.34],[-.34,.23,-.31]],\r\n  [[.2,.78,-.32],[.34,.73,-.35],[.42,.64,-.36],[.36,.55,-.34],[.29,.6,-.32],[.37,.69,-.34],[.44,.59,-.36],[.4,.42,-.34],[.34,.19,-.31]],\r\n  [[-.3,.98,-.36],[-.43,.88,-.38],[-.42,.79,-.38],[-.32,.84,-.36],[-.26,.77,-.34],[-.42,.69,-.38],[-.44,.56,-.38],[-.33,.5,-.35]],\r\n  [[.3,.96,-.36],[.43,.86,-.38],[.42,.77,-.38],[.32,.82,-.36],[.26,.74,-.34],[.43,.65,-.38],[.45,.51,-.38],[.34,.45,-.35]],\r\n  [[-.48,1.08,-.42],[-.25,1.12,-.43],[0,1.06,-.44],[.24,1.12,-.43],[.48,1.04,-.42],[.4,.94,-.42],[.18,.98,-.43],[-.05,.93,-.43],[-.3,.99,-.42],[-.48,.9,-.42]],\r\n  [[-.49,-.08,-.42],[-.28,-.14,-.43],[-.05,-.07,-.44],[.19,-.14,-.43],[.46,-.05,-.42],[.4,.05,-.42],[.16,-.01,-.43],[-.1,.06,-.43],[-.35,.01,-.42],[-.49,.12,-.42]],\r\n  [[-.5,.74,-.45],[-.42,.98,-.46],[-.26,1.07,-.47],[-.15,.98,-.46],[-.3,.83,-.45],[-.45,.61,-.46],[-.43,.42,-.47],[-.25,.34,-.46],[-.14,.43,-.45],[-.35,.64,-.46],[-.5,.74,-.45]],\r\n  [[.5,.71,-.45],[.42,.95,-.46],[.26,1.04,-.47],[.15,.95,-.46],[.3,.8,-.45],[.45,.58,-.46],[.43,.39,-.47],[.25,.31,-.46],[.14,.4,-.45],[.35,.61,-.46],[.5,.71,-.45]],\r\n  [[-.48,1.03,-.5],[-.34,.94,-.51],[-.18,.82,-.52],[0,.66,-.52],[.18,.49,-.51],[.34,.31,-.51],[.49,.12,-.5]],\r\n  [[.48,1.02,-.5],[.34,.91,-.51],[.18,.78,-.52],[0,.63,-.52],[-.18,.46,-.51],[-.34,.28,-.51],[-.49,.1,-.5]],\r\n  [[-.52,.28,-.48],[-.36,.39,-.49],[-.18,.47,-.5],[0,.53,-.51],[.2,.61,-.5],[.38,.72,-.49],[.52,.86,-.48]]\r\n ];\r\n const radii=[.0032,.0038,.0028,.0034,.0026,.003,.0035,.0028,.0042,.003,.0028,.0036,.0034];\r\n if(paths.length!==colors.length||paths.length!==radii.length||radii.some(radius=>!Number.isFinite(radius)||radius<=0||radius>.01))throw new Error('Invalid Reminders cable layout.');\r\n for(let i=0;i<paths.length;i++){\r\n  const points=paths[i].map(point=>new THREE.Vector3(...point));\r\n  const curve=new THREE.CatmullRomCurve3(points,false,'centripetal');\r\n  const radius=radii[i];\r\n  const mesh=new THREE.Mesh(new THREE.TubeGeometry(curve,48,radius,5,false),new THREE.MeshBasicMaterial({color:colors[i],transparent:true,opacity:.72,depthWrite:false}));\r\n  mesh.renderOrder=-1;scene.add(mesh);\r\n }\r\n}\r\n\r\nexport function mountRemindersComputer(panel=document.getElementById('remindersPanel')){\r\n if(!panel)return null;\r\n let disposed=false,epoch=0,pendingEpoch=-1,style=null,active=null,wrapped=null,restoreChildren=null;\r\n const token={get disposed(){return disposed;},get epoch(){return epoch;},view:null,style:null,fail:null};\r\n const offer=document.createElement('div');offer.className='reminders-computer-offer';\r\n const button=document.createElement('button');button.type='button';button.textContent='Download Reminders computer';\r\n const note=document.createElement('span');note.setAttribute('role','status');offer.append(button,note);\r\n const hint=document.createElement('span');hint.id='remindersComputerHint';hint.textContent='Drag the computer sideways, or press Left and Right arrow keys, to turn it.';\r\n Object.assign(hint.style,{position:'absolute',width:'1px',height:'1px',padding:'0',margin:'-1px',overflow:'hidden',clip:'rect(0,0,0,0)',whiteSpace:'nowrap',border:'0'});\r\n const setFallback=message=>{\r\n  panel.dataset.reminderRoom='offer';panel.tabIndex=-1;note.textContent=message;offer.hidden=false;offer.style.removeProperty('display');\r\n };\r\n const buttonClick=()=>{if(!window.myr5Packs?.open?.('room-reminders'))note.textContent='Open Downloads from Settings to add this room.';};\r\n button.addEventListener('click',buttonClick);\r\n panel.querySelector('header')?.after(offer);\r\n const unwrap=()=>{\r\n  if(!restoreChildren)return;\r\n  const {screen,host,children,originalNext}=restoreChildren;\r\n  for(let index=children.length-1;index>=0;index--){\r\n   const node=children[index];if(node.parentNode!==screen)continue;\r\n   const original=originalNext.get(node);\r\n   const anchor=original?.parentNode===panel?original:children.slice(index+1).find(next=>next.parentNode===panel)||screen;\r\n   panel.insertBefore(node,anchor);\r\n  }\r\n  screen.remove();host.remove();offer.hidden=false;offer.style.removeProperty('display');restoreChildren=null;\r\n };\r\n const tearDown=()=>{\r\n  if(wrapped){unwrap();wrapped=null;}\r\n  if(active){releaseView(active);active=null;}\r\n  panel.removeAttribute('aria-describedby');panel.removeAttribute('aria-keyshortcuts');panel.removeAttribute('tabindex');\r\n  delete panel.dataset.reminderRoom;\r\n  if(style){style.remove();style=null;token.style=null;}\r\n };\r\n token.fail=error=>{if(disposed)return;epoch++;tearDown();setFallback('The 3D computer is unavailable here; reminders still work.');};\r\n async function check(){\r\n  if(disposed||!panel.open||panel.dataset.reminderRoom==='ready'||pendingEpoch===epoch)return;\r\n  const mine=++epoch;pendingEpoch=mine;let parsed=null;\r\n  try{\r\n   const assets=await cachedRoomAssets(()=>current(panel,token,mine));\r\n   if(!assets||!current(panel,token,mine))return;\r\n   const modelBytes=await assets.model.arrayBuffer();\r\n   if(!current(panel,token,mine))return;\r\n   const styleText=assets.styleText;\r\n   useStyle(styleText,token);style=token.style;\r\n   const manager=loadingManager(),loader=new GLTFLoader(manager),gltf=await loader.parseAsync(modelBytes,'');parsed=gltf.scene;\r\n   if(!current(panel,token,mine)){releaseObject(parsed);return;}\r\n   const releaseGpu=claimGraphics('reminders',{keep:['portal']});await releaseGpu.ready; // the hidden 3D coach yields; back on close\r\n   if(!current(panel,token,mine)){releaseGpu();releaseObject(parsed);return;}\r\n   const host=document.createElement('div');host.className='reminders-computer-stage';\r\n   const children=[...panel.children].filter(node=>node!==offer&&node!==hint&&node.id!=='coachDock'&&!node.classList.contains('portal-peer-ui'));\r\n   const originalNext=new Map(children.map(node=>[node,node.nextSibling]));\r\n   const screen=document.createElement('div');screen.className='reminders-computer-screen';screen.dataset.computerScreen='';screen.append(...children);\r\n   panel.prepend(host);host.append(document.createElement('canvas'));const canvas=host.firstElementChild;canvas.className='reminders-computer-canvas';canvas.setAttribute('aria-hidden','true');\r\n   panel.append(screen);restoreChildren={screen,host,children,originalNext};wrapped=restoreChildren;\r\n   const scene=new THREE.Scene();const model=new THREE.Group();model.position.copy(MODEL_CENTER);gltf.scene.position.sub(MODEL_CENTER);model.add(gltf.scene);scene.add(model);makeCords(scene);\r\n   const view={releaseGpu,canvas,screen,renderer:null,scene,camera:null,model,resize:null,raf:0,listeners:[],disposed:false};active=view;token.view=view;parsed=null;\r\n   const renderer=new THREE.WebGLRenderer({canvas,alpha:true,antialias:true,powerPreference:'low-power'});view.renderer=renderer;\r\n   renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.setPixelRatio(Math.min(devicePixelRatio||1,1.5));renderer.setClearColor(0x000000,0);\r\n   scene.add(new THREE.HemisphereLight(0xe8f8ff,0x241532,2.1));const keyLight=new THREE.DirectionalLight(0xffedcf,2.5);keyLight.position.set(-1.5,2,2.5);scene.add(keyLight);\r\n   const camera=new THREE.PerspectiveCamera(31,1,.05,12);view.camera=camera;let width=0,height=0,yaw=0,turn=0,lastFrame=0,start=performance.now();\r\n   function listen(target,name,fn){target.addEventListener(name,fn);view.listeners.push([target,name,fn]);}\r\n   function project(x,y,z){const point=new THREE.Vector3(x,y,z).sub(MODEL_CENTER);point.applyAxisAngle(new THREE.Vector3(0,1,0),turn).add(MODEL_CENTER).project(camera);return [(point.x+1)*width/2,(1-point.y)*height/2];}\r\n   function screenRect(){const points=[[SCREEN.left,SCREEN.bottom,SCREEN.z],[SCREEN.right,SCREEN.bottom,SCREEN.z],[SCREEN.right,SCREEN.top,SCREEN.z],[SCREEN.left,SCREEN.top,SCREEN.z]].map(p=>project(...p));const xs=points.map(p=>p[0]),ys=points.map(p=>p[1]);const left=Math.min(...xs),top=Math.min(...ys);Object.assign(screen.style,{left:left+'px',top:top+'px',width:Math.max(...xs)-left+'px',height:Math.max(...ys)-top+'px'});}\r\n   function render(now=performance.now()){if(view.disposed||!panel.open||!panel.isConnected)return;if(width&&height){model.rotation.y=turn=yaw+(REDUCED()?0:Math.sin((now-start)/3300)*.012);renderer.render(scene,camera);screenRect();}}\r\n   function resize(){if(view.disposed)return;\r\n    // getBoundingClientRect() includes portal arrival transforms (scale(.05) -> scale(1)) and\r\n    // portal-inset zoom. Those are visual transforms, not layout changes; using them as the\r\n    // renderer's coordinate system permanently shrinks the projected screen after arrival.\r\n    width=host.clientWidth;height=host.clientHeight;if(!width||!height)return;\r\n    renderer.setSize(width,height,false);camera.aspect=width/height;const vfov=THREE.MathUtils.degToRad(camera.fov),distance=Math.max(MODEL_SIZE.y*.53/Math.tan(vfov/2),MODEL_SIZE.x*.53/Math.tan(vfov/2)/camera.aspect)*1.08;camera.position.set(0,.515,.10668+distance);camera.lookAt(MODEL_CENTER);camera.zoom=1.5;camera.updateProjectionMatrix();render();}\r\n   let drag=null;const down=event=>{if(event.target.closest?.(INTERACTIVE)||(event.pointerType==='mouse'&&event.button!==0))return;drag={id:event.pointerId,x:event.clientX,y:event.clientY,yaw,moving:false};};\r\n   const move=event=>{if(!drag||drag.id!==event.pointerId)return;const dx=event.clientX-drag.x,dy=event.clientY-drag.y;if(!drag.moving){if(Math.abs(dy)>DRAG_SLOP&&Math.abs(dy)>Math.abs(dx)){drag=null;return;}if(Math.abs(dx)<DRAG_SLOP)return;drag.moving=true;panel.setPointerCapture?.(drag.id);}yaw=THREE.MathUtils.degToRad(spinBy(THREE.MathUtils.radToDeg(drag.yaw),dx*DRAG_DEG_PER_PX));render();window.dispatchEvent(new Event('myr5:reminders-turn'));};\r\n   const end=event=>{if(drag?.id===event.pointerId){if(drag.moving)panel.releasePointerCapture?.(drag.id);drag=null;}};\r\n   const key=event=>{if(event.target!==panel||!/^Arrow(Left|Right)$/.test(event.key))return;event.preventDefault();yaw=THREE.MathUtils.degToRad(spinBy(THREE.MathUtils.radToDeg(yaw),event.key==='ArrowLeft'?-KEY_STEP:KEY_STEP));render();window.dispatchEvent(new Event('myr5:reminders-turn'));};\r\n   listen(panel,'pointerdown',down);listen(panel,'pointermove',move);listen(panel,'pointerup',end);listen(panel,'pointercancel',end);listen(panel,'lostpointercapture',end);listen(panel,'keydown',key);\r\n   listen(canvas,'webglcontextlost',event=>{event.preventDefault();if(current(panel,token,mine))token.fail(new Error('WebGL context lost'));});\r\n   // Activate the stage/screen layout before measuring it. In the portal the dialog is\r\n   // already clipped to a small face; measuring while the ready rules are inactive can\r\n   // produce a zero-sized stage and leave the wrapped controls with no projected screen.\r\n   panel.dataset.reminderRoom='ready';panel.tabIndex=0;panel.setAttribute('aria-keyshortcuts','ArrowLeft ArrowRight');panel.setAttribute('aria-describedby',hint.id);\r\n   view.resize=new ResizeObserver(resize);view.resize.observe(host);resize();\r\n   const media=matchMedia('(prefers-reduced-motion: reduce)');\r\n   const tick=now=>{if(view.disposed||!current(panel,token,mine)||document.visibilityState!=='visible'||media.matches){view.raf=0;return;}if(now-lastFrame>=1000/24){lastFrame=now;render(now);}view.raf=requestAnimationFrame(tick);};\r\n   const startLoop=()=>{if(!view.disposed&&current(panel,token,mine)&&document.visibilityState==='visible'&&!media.matches&&!view.raf)view.raf=requestAnimationFrame(tick);};\r\n   listen(document,'visibilitychange',()=>{if(document.visibilityState!=='visible'&&view.raf){cancelAnimationFrame(view.raf);view.raf=0;}else startLoop();});\r\n   listen(media,'change',()=>{if(media.matches){if(view.raf){cancelAnimationFrame(view.raf);view.raf=0;}render();}else startLoop();});startLoop();\r\n   offer.hidden=true;offer.style.display='none';\r\n  }catch(error){if(parsed)releaseObject(parsed);if(!current(panel,token,mine))return;tearDown();setFallback('The computer room is an optional download. Reminders still work.');}\r\n  finally{if(pendingEpoch===mine)pendingEpoch=-1;}\r\n }\r\n const observer=new MutationObserver(()=>{if(panel.open){window.dispatchEvent(new Event('myr5:reminders-open'));void check();}else{epoch++;tearDown();}});observer.observe(panel,{attributes:true,attributeFilter:['open']});\r\n const onFocus=()=>{if(panel.open)void check();};const onPageHide=()=>{epoch++;tearDown();};const onPageShow=()=>{if(panel.open)void check();};\r\n window.addEventListener('focus',onFocus);window.addEventListener('pagehide',onPageHide);window.addEventListener('pageshow',onPageShow);\r\n const onAccountTransition=()=>{if(pendingEpoch<0)return;epoch++;pendingEpoch=-1;if(panel.open)queueMicrotask(()=>void check());};\r\n window.addEventListener('myr5:account-ready',onAccountTransition);window.addEventListener('myr5:account-cleared',onAccountTransition);\r\n panel.append(hint);\r\n if(panel.open)void check();\r\n return()=>{if(disposed)return;disposed=true;epoch++;observer.disconnect();window.removeEventListener('focus',onFocus);window.removeEventListener('pagehide',onPageHide);window.removeEventListener('pageshow',onPageShow);window.removeEventListener('myr5:account-ready',onAccountTransition);window.removeEventListener('myr5:account-cleared',onAccountTransition);tearDown();button.removeEventListener('click',buttonClick);offer.remove();hint.remove();};\r\n}\r\n","modules/routes.mjs":"// W2-2A (#4, #5, #17, #18, #30): one hash route per scene, one bottom bar everywhere.\r\n// Each route reuses the opener the app already had (the portal's MENUS open() calls go()). A route's dialog is\r\n// adopted however it was opened (bar button, traced shape, header button, deep link): its #hash goes into\r\n// history, the bottom bar moves inside it (a modal dialog makes everything outside it inert, so the bar has to\r\n// be in there to stay tappable), the bar lights the route, focus goes to its heading and a polite live region\r\n// names it. Phone back closes it and returns to the quilt; back on the quilt asks once before leaving.\r\n// Bundled into app-runtime via app.mjs; no .ts imports, no build defines.\r\nimport {openCustomizer} from './ships/ship-scene-domain.mjs';\r\nimport {ensurePortalMounted} from './portal/portal-entry.mjs';\r\nconst $=id=>document.getElementById(id);\r\n// Kept by reference: the bar can sit inside a dialog that is being removed (portal dispose) and must come back.\r\nlet dockEl=null;\r\nconst dock=()=>dockEl||=$('coachDock');\r\nconst quiltUp=()=>$('portalHome')?.hidden===false;\r\nconst reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\nconst hideQuilt=()=>{if(quiltUp())window.myr5Portal?.hide?.();};\r\nconst panel=name=>{const dialog=$(name+'Panel'),button=document.querySelector(`.coach-dock [data-panel=\"${name}\"]`);if(button)button.click();else if(dialog&&!dialog.open)dialog.showModal();return dialog;};\r\nconst bare=()=>location.pathname+location.search;\r\n// The ship view resolves only once its entrance is over; the portal's dive needs the dialog as soon as it opens.\r\nconst whenOpen=(selector,opening)=>new Promise(resolve=>{\r\n const open=()=>{const found=document.querySelector(selector);return found?.open?found:null;};\r\n const watch=new MutationObserver(()=>{const found=open();if(found){watch.disconnect();resolve(found);}});\r\n watch.observe(document.body,{subtree:true,childList:true,attributes:true,attributeFilter:['open']});\r\n Promise.resolve(opening).then(dialog=>{watch.disconnect();resolve(open()||dialog);},()=>{watch.disconnect();resolve(null);});\r\n});\r\n\r\n// id -> {label, open() -> its dialog (or a promise of it), dialog: selector of the dialog it owns (adopted\r\n// however it opens), page: a no-dialog scene, focus: what a page route focuses, nav: another page, own: the\r\n// dialog keeps its own history (ship-view.mjs pushes #ship itself), shared: adopts that dialog only when it opened it}.\r\nexport const ROUTES={\n world:{label:'War Room base',dialog:'#coachWorldPanel',open:()=>import('./coach-world/view.mjs').then(m=>m.openWorld())},\n // Ian 2026-09-23: the square is the workout start page (the pod's viewing port, control board and BEGIN, which\r\n // starts the camera as always) and the oval is the coach's arrival: its ship flies in and beams it down, every time.\r\n // W2-2M: from the top, but BEGIN never under the bar: the page fits at 375x812, a shorter phone scrolls just enough.\r\n workout:{label:'Workout',page:true,dialog:'#portalWorkoutHome',focus:'#view',open(){const portalHome=window.myr5Portal?.openWorkoutHome?.();if(portalHome)return portalHome;hideQuilt();const begin=$('start')?.getBoundingClientRect(),room=innerHeight-(dock()?.offsetHeight||0)-8;scrollTo({top:begin?.height?Math.max(0,scrollY+begin.bottom-room):0,behavior:reduced()?'auto':'smooth'});}},\r\n // W2-2Q: the router is the one owner of the ship view's #ship/#select history (the view only keeps its own standalone).\r\n select:{label:'Coach arrival',dialog:'dialog.ship-view',shared:true,open:()=>whenOpen('dialog.ship-view',window.myr5Menus?.ship?.({entrance:'always',hash:'#select'}))},\r\n food:{label:'Food',dialog:'#mealsPanel',open:()=>typeof window.myr5Menus?.food==='function'?window.myr5Menus.food():panel('meals')},\r\n // R-1017: one achievements page (constellation on top, XP flight below); #battlepass stays as an alias for old links.\r\n achievements:{label:'Achievements',dialog:'#battlePassPanel',open:()=>window.myr5Menus?.achievements?.()},\r\n battlepass:{label:'Achievements',dialog:'#battlePassPanel',shared:true,open:()=>window.myr5Menus?.battlePass?.()},\r\n // The existing opener owns workout shutdown, movement selection, and the hologram lifecycle.\r\n // Direct taps are adopted by the dialog observer; go('library') uses that same opener once.\r\n library:{label:'Movements',dialog:'#library',open(){$('openLibrary')?.click();return $('library');}},\r\n spotify:{label:'Spotify DJ',dialog:'#spotifyPanel',open:()=>window.myr5Menus?.spotify?.()},\r\n paths:{label:'Workout paths',dialog:'#coachPathPicker',open:()=>window.myr5Menus?.paths?.()},\r\n scoreboard:{label:'Scoreboard',dialog:'#accountPanel',open:()=>panel('account')},\r\n // #148 (Ian 2026-09-23): the customizer's one door is the oval: its ship arrives and the user taps it (ship-intro.mjs\r\n // opens /creature/index.html with the gate the editor checks). So #customize, the X and any link to it land on the arrival.\r\n customize:{label:'War Room base',alias:'world'},\n // Ian 26 Sep: the dock's far-left key (still the gear icon) skips the arrival and opens the customizer directly,\r\n // the same admission openCustomizer() gives the oval ship (ship-view.mjs, ship-intro.mjs) — not #customize/War Room.\r\n customizeCoach:{label:'Customize coach',open:()=>openCustomizer()},\r\n meditate:{label:'Meditation',dialog:'.meditation-panel',open(){document.querySelector('.meditation-entry')?.click();return document.querySelector('.meditation-panel');}},\r\n reminders:{label:'Reminders',dialog:'#remindersPanel',open:()=>panel('reminders')},\r\n settings:{label:'Settings',dialog:'#settings',open(){$('openSettings')?.click();return $('settings');}},\r\n ship:{label:'Ship',dialog:'dialog.ship-view',open:()=>window.myr5Menus?.ship?.()},\r\n 'war-room':{label:'War Room base',alias:'world'},\n pod:{label:'Training pod',page:true,focus:'#homeScreen',open:hideQuilt},\r\n history:{label:'History',dialog:'#historyPanel',open:()=>panel('history')},\r\n install:{label:'Install',dialog:'#installPanel',open:()=>panel('install')},\r\n // Achievement Vault: reached only through a grimoire secret (portal.mjs door poster); vault-door.mjs builds #vaultPanel.\r\n vault:{label:'Vault',dialog:'#vaultPanel',open:()=>import('./vault/vault-door.mjs').then(m=>m.openVault())},\r\n};\r\n// Old ?panel= deep links (reminder pushes, update emails, recovery) open the same routes.\r\nexport const PANEL_ROUTES={spotify:'spotify',meals:'food',reminders:'reminders',account:'scoreboard',history:'history',install:'install'};\r\nexport function hashRoute(hash=location.hash){const id=hash.slice(1);return Object.hasOwn(ROUTES,id)?id:'';}\r\n\r\nlet active=null,expectBack=false,guardArmed=false,guardHref='',hintTimer=0,routeGeneration=0;\r\nconst pending=new Map();\r\n\r\nfunction paint(){\r\n const current=active?active.id:quiltUp()?'portal':'';\r\n window.dispatchEvent(new CustomEvent('myr5:route',{detail:{id:current}})); // page music follows the scene\r\n for(const button of dock()?.querySelectorAll('[data-route]')||[]){if(button.dataset.route===current)button.setAttribute('aria-current','page');else button.removeAttribute('aria-current');}\r\n const centre=dock()?.querySelector('.dock-portal');\r\n if(centre){const onQuilt=quiltUp()&&!active;centre.querySelector('span').textContent=onQuilt?'POD':'PORTAL';centre.setAttribute('aria-label',onQuilt?'Open workout pod':'Return to portal grimoire');centre.title=centre.getAttribute('aria-label');}\r\n}\r\nfunction say(text){\r\n const live=dock()?.querySelector('.dock-live');if(!live)return;\r\n live.textContent='';setTimeout(()=>{live.textContent=text;},60);\r\n}\r\nfunction announce(entry){\r\n const route=ROUTES[entry.id],target=entry.dialog?[...entry.dialog.querySelectorAll('h1,h2')].find(h=>h.getClientRects().length):document.querySelector(route.focus);\r\n if(target){\r\n  if(!target.hasAttribute('tabindex'))target.setAttribute('tabindex','-1');\r\n  target.focus({preventScroll:true});\r\n  // A #hash that is also an element id (#settings is the Settings dialog's) gets the browser's fragment focus after\r\n  // popstate; take it back once the navigation is done.\r\n  setTimeout(()=>{const now=document.activeElement;if(active===entry&&(now===document.body||now===entry.dialog))target.focus({preventScroll:true});});\r\n }\r\n say(route.label);\r\n}\r\n// Home is the quilt: after a back (or closing a cold deep link) bring it up unless something else now owns the screen.\r\nfunction showQuiltLater(force=false){\r\n setTimeout(()=>{\r\n  const body=document.body.dataset;\r\n  const idle=()=>!quiltUp()&&!document.querySelector('dialog[open]')&&body.tracking!=='true'&&body.cameraWorkout!=='true'&&body.screen!=='rest';\r\n  if(idle()&&(force||window.coachPlan||window.myr5Portal))void window.myr5Menus?.portal?.({shouldShow:idle});\r\n });\r\n}\r\n\r\nfunction adopt(id,dialog){\r\n if(active&&active.dialog===dialog&&active.id===id)return active;\r\n const route=ROUTES[id],flags=pending.get(id)||{};pending.delete(id);\r\n const prev=active,entry={id,dialog,own:!!route.own,pushed:false,deepLink:!!flags.deepLink,portalOrigin:!!flags.portal,reason:''};\r\n active=entry;\r\n if(prev)finish(prev,'switch');\r\n if(!entry.own){\r\n  const state={myr5Route:id},url=bare()+'#'+id;\r\n  // Switching from one route to the next replaces its history entry, so back always lands on the quilt.\r\n  if(location.hash==='#'+id){entry.pushed=!!flags.fromHash&&!entry.deepLink;history.replaceState(state,'',url);}\r\n  else if(prev?.pushed&&!prev.own){entry.pushed=true;history.replaceState(state,'',url);}\r\n  else if(entry.deepLink)history.replaceState(state,'',url);\r\n  else{entry.pushed=true;history.pushState(state,'',url);}\r\n }\r\n if(dialog){\r\n  dialog.dataset.route=id;\r\n  const bar=dock();if(bar)dialog.append(bar);\r\n  entry.closeListener=()=>{\r\n   // A native close event can arrive after this shared dialog was reopened in the same task.\r\n   // Keep this session's listener armed for its eventual real close.\r\n   if(dialog.open||entry.done)return;\r\n   dialog.removeEventListener('close',entry.closeListener);\r\n   const reason=dialog.dataset.workoutBegin==='true'?'workout-begin':entry.reason||'user';delete dialog.dataset.workoutBegin;\r\n   finish(entry,reason);\r\n  };\r\n  dialog.addEventListener('close',entry.closeListener);\r\n }\r\n if(id==='history')import('./vault/vault-store.mjs').then(m=>m.bump('history-open')).catch(()=>{});\r\n window.myr5MenuLifecycle?.enter(dialog??id);\r\n if(dialog)window.myr5MenuLifecycle?.closeInactive(dialog);\r\n paint();announce(entry);return entry;\r\n}\r\nfunction finish(entry,reason){\r\n if(entry.done)return;\r\n entry.done=true;entry.reason=reason;\r\n window.myr5MenuLifecycle?.leave(entry.dialog??entry.id,reason);\r\n window.dispatchEvent(new CustomEvent('myr5:route-leave',{detail:{id:entry.id,reason}}));\r\n if(entry.dialog&&entry.closeListener)entry.dialog.removeEventListener('close',entry.closeListener);\r\n if(active===entry)active=null;\r\n const {dialog}=entry;\r\n if(dialog&&dialog!==active?.dialog){\r\n  delete dialog.dataset.route;\r\n  const bar=dock();if(bar?.parentNode===dialog)(active?.dialog||document.body).append(bar);\r\n  if(dialog.open)dialog.close();\r\n }\r\n if(!entry.own&&(reason==='user'||reason==='portal'||reason==='workout-begin')&&location.hash==='#'+entry.id){\r\n  if(entry.pushed){expectBack=true;history.back();}else history.replaceState(null,'',bare());\r\n }\r\n if(reason==='back'||(reason==='user'&&entry.deepLink))showQuiltLater();\r\n paint();\r\n}\r\n\r\n// Any direct dialog route gets the same hardware surround and tilt as a room opened from the quilt.\r\n// Portal-origin routes carry {portal:true}, so their shaped-cut presentation stays intact.\r\nconst HOUSING_ROUTES=new Set(['food','achievements','battlepass','library','spotify','paths','reminders','scoreboard','meditate','settings','ship','select','history','install']);\r\nexport function go(id,{deepLink=false,fromHash=false,portal=false}={}){\n const route=ROUTES[id];if(!route)return undefined;\n if(route.alias)return go(route.alias,{deepLink,fromHash,portal});\n if(route.nav){\r\n  if(active)active.reason='nav';\r\n  if(hashRoute())history.replaceState(history.state?.myr5Home?history.state:null,'',bare());\r\n  location.assign(route.nav);return undefined;\r\n }\r\n if(active?.id===id&&(!active.dialog||active.dialog.open)){\r\n  const current=active;\r\n  if(current.dialog&&HOUSING_ROUTES.has(id)&&!portal)return ensurePortalMounted().then(housing=>{if(active===current&&current.dialog.open)housing.frameDirectDestination?.(current.dialog,id);return current.dialog;});\r\n  return active.dialog||undefined;\r\n }\r\n const generation=++routeGeneration;pending.clear();\r\n const request={deepLink,fromHash,portal,generation};pending.set(id,request);\r\n let result;\r\n try{\r\n  result=HOUSING_ROUTES.has(id)&&!portal\r\n   ?(async()=>{\r\n     const housing=await ensurePortalMounted();if(pending.get(id)!==request||routeGeneration!==generation)return null;\r\n     const opened=route.open();\r\n     const finishHousing=dialog=>{if(dialog instanceof HTMLDialogElement&&dialog.open&&routeGeneration===generation&&(pending.get(id)===request||(active?.id===id&&active.dialog===dialog)))housing.frameDirectDestination?.(dialog,id);return dialog;};\r\n     return opened instanceof Promise?finishHousing(await opened):finishHousing(opened);\r\n    })()\r\n   :route.open();\r\n }catch(error){pending.delete(id);throw error;}\r\n // Only this request may adopt: an older, slower open of the same route (the ship view's) must not take it back.\r\n const settle=dialog=>{\r\n  if(pending.get(id)!==request)return;\r\n  if(dialog instanceof HTMLDialogElement&&dialog.open)adopt(id,dialog);\r\n  else if(route.page&&!(result instanceof Promise))adopt(id,null);\r\n  else pending.delete(id);\r\n };\r\n if(result instanceof Promise)result.then(settle,()=>{if(pending.get(id)===request)pending.delete(id);});else settle(result);\r\n return result;\r\n}\r\n\r\n// Back/forward and #links. popstate covers traversal (and fragment links in current browsers); hashchange is the\r\n// fallback for a link that fired no popstate.\r\nfunction sync(event){\r\n if(event.type==='popstate'&&expectBack){expectBack=false;return;}\r\n const id=hashRoute(),state=event.state??history.state;\r\n if(active){\r\n  if(active.id!==id){if(active.own)active.reason='back';else finish(active,'back');}\r\n  return;\r\n }\r\n if(state?.myr5Route&&ROUTES[state.myr5Route]){go(state.myr5Route,{fromHash:true});return;}\r\n if(event.type==='popstate'&&guardArmed&&!state?.myr5Home&&location.href===guardHref){\r\n  // The first back on the quilt lands here instead of leaving the app; the next one leaves.\r\n  guardArmed=false;\r\n  const bar=dock();\r\n  if(bar){bar.dataset.hint='Press back again to leave Coach';clearTimeout(hintTimer);hintTimer=setTimeout(()=>delete bar.dataset.hint,3000);}\r\n  say('Press back again to leave Coach');showQuiltLater();return;\r\n }\r\n // A route already opening is the same request (#customize rewrites itself to #select before its hashchange lands).\r\n if(id&&!pending.has(id))go(id,{fromHash:true});\r\n}\r\n// The back guard is pushed only after a tap or key (browsers skip history entries added without one).\r\nfunction armGuard(){\r\n if(history.state?.myr5Home){guardArmed=true;return;}\r\n if(guardArmed||active)return;\r\n guardHref=location.href;history.pushState({myr5Home:true},'',guardHref);guardArmed=true;\r\n}\r\n// Closes whatever route is open and brings up the quilt. Used by the bar's centre Portal off the quilt, and by\r\n// anything else that wants to send the user home (#56's rest exit, a stopped/paused set, the Settings PORTAL link).\r\nexport function home(){\r\n routeGeneration++;pending.clear();\r\n if(active){const entry=active;if(entry.dialog?.open)entry.reason='portal';finish(entry,'portal');}\r\n showQuiltLater(true);\r\n}\r\n// The bar's centre Portal: on the quilt the portal's own handler opens the Menu sheet; anywhere else it goes\r\n// home to the quilt (closing the open route).\r\nfunction dockRoute(event){\r\nconst button=event.target.closest?.('#coachDock [data-route]');\r\n if(!button||button.dataset.route==='portal')return;\r\n // Route.open() may activate the same panel button as its legacy opener. The opener's\r\n // request owns this click; adopting it again would invalidate its housing continuation.\r\n if(button.hasAttribute('data-panel')&&pending.has(button.dataset.route))return;\r\n go(button.dataset.route);\r\n}\r\nfunction portalButton(event){\r\n if(!event.target.closest?.('#coachDock [data-route=\"portal\"]'))return;\r\n if(quiltUp()&&!active)return;\r\n event.stopPropagation();\r\n home();\r\n}\r\n\r\nexport function mountRoutes(){\r\n if(window.myr5Routes)return window.myr5Routes;\r\n import('./vault/vault-banner.mjs').catch(()=>{}).then(()=>import('./vault/vault-store.mjs')).catch(()=>{}); // banner first so it hears the drained-pending earns; loads the store so it hears myr5:vault-bump from raw-served files (portal, pond)\r\n let seen='';\r\n addEventListener('popstate',event=>{seen=location.href;sync(event);});\r\n addEventListener('hashchange',()=>{const href=location.href,handled=href===seen;seen='';if(!handled)sync({type:'hashchange',state:history.state});});\r\n addEventListener('pointerup',armGuard,true);addEventListener('keydown',armGuard,true);\r\n document.addEventListener('click',portalButton,true);\r\n document.addEventListener('click',dockRoute);\r\n // Legacy War Room doors enter the base; the HQ explicitly enters its editor.\n document.addEventListener('click',event=>{const link=event.target.closest?.('a[href]');if(!link||event.defaultPrevented||event.button||event.metaKey||event.ctrlKey||event.shiftKey||event.altKey)return;const url=new URL(link.href,location.href);if(url.pathname.startsWith('/war-room/')&&url.searchParams.get('from')==='world')return;if(url.origin===location.origin&&/^\\/(?:creature|war-room)\\/(index\\.html)?$/.test(url.pathname)){event.preventDefault();go('world');}});\n new MutationObserver(records=>{\r\n  const newlyOpen=new Set();let homeChanged=false;\r\n  for(const {target,attributeName} of records){\r\n   if(attributeName==='open'&&target.tagName==='DIALOG'&&target.open)newlyOpen.add(target);\r\n   else if(attributeName==='hidden'&&target.id==='portalHome')homeChanged=true;\r\n  }\r\n  for(const target of newlyOpen){\r\n   const owns=key=>ROUTES[key].dialog&&target.matches(ROUTES[key].dialog);\r\n   // A shared dialog can represent Ship or Coach arrival. Preserve the alias already adopted for\r\n   // this open session; a second record from close/reopen must not fall back to the first alias.\r\n   const current=active?.dialog===target&&owns(active.id)?active.id:null;\r\n   const id=[...pending.keys()].reverse().find(owns)||current||Object.keys(ROUTES).find(key=>!ROUTES[key].shared&&owns(key));\r\n   if(id){\r\n    const request=pending.get(id),generation=request?.generation??routeGeneration;\r\n    const entry=adopt(id,target);\r\n    if(HOUSING_ROUTES.has(id)&&!entry.portalOrigin){\r\n     void ensurePortalMounted().then(housing=>{if(active===entry&&target.open&&routeGeneration===generation)housing.frameDirectDestination?.(target,id);});\r\n    }\r\n   }\r\n  }\r\n  if(homeChanged){\r\n   if(quiltUp()&&active&&!active.dialog)finish(active,'user');\r\n   paint();\r\n  }\r\n }).observe(document.body,{subtree:true,attributes:true,attributeFilter:['open','hidden']});\r\n return window.myr5Routes={\r\n  go,home,ROUTES,hashRoute,\r\n  current:()=>active?.id||'',\r\n  // launch.mjs calls this once the panels exist: a ?panel= or #route deep link opens its route.\r\n  boot(panelName){const id=PANEL_ROUTES[panelName]||hashRoute();if(id&&id!=='pod')go(id,{deepLink:true});else paint();},\r\n };\r\n}\r\n","modules/ships/ship-access.mjs":"import * as ledger from '../../unlock-ledger.mjs';\r\nimport {shipAccess} from '../../performance-progress.mjs';\r\n\r\nexport const SHIP_REVEAL_KEY = 'myr5-ship-reveal-seen-v1';\r\nexport const SHIP_IDS = Object.freeze(['supportive','direct','analytical','playful','calm','mom']);\r\nconst stableOwner = account => {\r\n  const id = typeof account==='string'?account:account?.user?.id;\r\n  return typeof id === 'string' && /^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(id) ? id : null;\r\n};\r\nconst ownedId = (id,options) => SHIP_IDS.includes(id) && (shipAccess(id,options)||ledger.isGranted('ship', `ship-${id}`,options));\r\nfunction read(store = globalThis.localStorage) {\r\n  try { const value = JSON.parse(store?.getItem(SHIP_REVEAL_KEY) || '{}'); return value && typeof value === 'object' && !Array.isArray(value) ? value : {}; }\r\n  catch { return {}; }\r\n}\r\n\r\nexport function ownedShipIds(options) { return SHIP_IDS.filter(id=>ownedId(id,options)); }\r\nexport function hasSeenShipReveal(ship, { account = globalThis.myr5AuthenticatedAccount, storage = globalThis.localStorage } = {}) {\r\n  const owner = stableOwner(account);\r\n  return !!owner && ownedId(ship,{account}) && Array.isArray(read(storage)[owner]) && read(storage)[owner].includes(ship);\r\n}\r\nexport function markShipRevealSeen(ship, { account = globalThis.myr5AuthenticatedAccount, storage = globalThis.localStorage } = {}) {\r\n  const owner = stableOwner(account);\r\n  if (!owner || !ownedId(ship,{account}) || !storage?.setItem) return false;\r\n  const data = read(storage), seen = new Set(Array.isArray(data[owner]) ? data[owner] : []);\r\n  seen.add(ship); data[owner] = [...seen].filter(SHIP_IDS.includes.bind(SHIP_IDS)).sort();\r\n  try { storage.setItem(SHIP_REVEAL_KEY, JSON.stringify(data)); return true; } catch { return false; }\r\n}\r\nexport function coachEditorShips(options = {}) {\r\n  return ownedShipIds(options).filter(ship => hasSeenShipReveal(ship, options));\r\n}\r\nexport const canShowCoachEditorShipSection = (options = {}) => coachEditorShips(options).length > 0;\r\n\r\n/** Only the scene's post-flash completion event advances reveal-seen state. */\r\nexport function acceptShipRevealComplete(event, options = {}) {\r\n  const detail = event?.detail;\r\n  if (!detail?.revealComplete || !SHIP_IDS.includes(detail.ship) || detail.ownerId!==stableOwner(options.account??globalThis.myr5AuthenticatedAccount)) return false;\r\n  return markShipRevealSeen(detail.ship, options);\r\n}\r\n","modules/ships/ship-catalog.mjs":"// These IDs are the same keys used by recipes, rewards and the verified GLB pack.\r\nexport const SHIP_CATALOG=Object.freeze([\r\n {id:'supportive',name:'Bubble shuttle',description:'A rounded cockpit with four bulbous engine pods around a compact hull.'},\r\n {id:'direct',name:'Wing fighter',description:'A pointed cockpit between broad swept wings and long engine rails.'},\r\n {id:'analytical',name:'Ring-engine scout',description:'A narrow cockpit and small fins ahead of a large circular rear engine.'},\r\n {id:'playful',name:'Fork interceptor',description:'A dark central cockpit between long forked nose rails, with two side engine pods.'},\r\n {id:'calm',name:'Capsule pod',description:'A short rounded capsule with a forward cockpit and a thick rear housing.'},\r\n {id:'mom',name:'Cargo carrier',description:'A broad blocky hull with a raised centre tower and two large front engine housings.'},\r\n].map(ship=>Object.freeze({...ship,assetPath:`assets/ships/${ship.id}.glb`})));\r\nexport const shipDetails=id=>SHIP_CATALOG.find(ship=>ship.id===id)||SHIP_CATALOG[0];\r\n","modules/ships/ship-intro.mjs":"import * as THREE from 'three';\r\nimport { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';\r\nimport { offAxis } from '../portal/peer.mjs'; // #135: tilt looks round the ship through the portal window\r\nimport { createCoachPreviewSpace } from '../../coach-preview-space.mjs';\r\nimport { initialScene,recipeShipTint,applyShipTint,normalizeBackground,normalizeShip,resolveSceneSwap,sampleApproach,SHIP_ANCHOR_Y,coachBand,shipPoseAbove,measureShip,APPROACH_MS,BEAM_CHARGE_MS,SHIP_FACING,SHIP_REST_Z,openCustomizer as openGatedCustomizer } from './ship-scene-domain.mjs';\r\n\r\nconst reduced=()=>matchMedia('(prefers-reduced-motion: reduce)').matches;\r\nconst RECIPE_KEY='myr5-recipe-v1';\r\nconst recipe=()=>{try{return JSON.parse(localStorage.getItem(RECIPE_KEY)||'{}')}catch{return{}}};\r\nconst SHIP_SETTINGS_KEY='myr5-ship-customization-v1';\r\nconst savedShip=owner=>{try{return JSON.parse(localStorage.getItem(`${SHIP_SETTINGS_KEY}/${owner}`)||'{}')}catch{return{}}};\r\nfunction disposeModel(root){const geometries=new Set(),materials=new Set(),textures=new Set();root?.traverse(node=>{if(node.geometry)geometries.add(node.geometry);for(const mat of Array.isArray(node.material)?node.material:[node.material])if(mat){materials.add(mat);for(const value of Object.values(mat))if(value?.isTexture)textures.add(value);}});for(const t of textures){t.source?.data?.close?.();t.dispose();}for(const m of materials)m.dispose();for(const g of geometries)g.dispose();}\r\n\r\n/** Mount the coach-arrival scene. `assetBridge` must come from signed, owned, verified chunk data, or with\r\n * `starter` serve Original MYR5's bundled starter ship from /pod/worlds/starter/ (no owner needed; never marks a reveal seen). */\r\nexport function mountShipScene({host=document.getElementById('view'),customizer='/creature/index.html',assetBridge,ship:initialShip,starter=false,gpu=null}={}){ // gpu: claimGraphics release, called once this scene's context is gone\r\n if(!host||!assetBridge?.getShipUrl)throw new Error('A verified owned ship section is required.');\r\n const ownerId=globalThis.myr5AuthenticatedAccount?.user?.id;if(!ownerId&&!starter)throw new Error('An authenticated ship owner is required.');\r\n const lifecycle=new AbortController();\r\n const assertLive=()=>{if(lifecycle.signal.aborted||globalThis.myr5AuthenticatedAccount?.user?.id!==ownerId)throw new DOMException('Ship scene cancelled','AbortError');assetBridge.ownedShipIds();};\r\n const pause=ms=>new Promise((resolve,reject)=>{assertLive();const cancelled=()=>{clearTimeout(timer);reject(new DOMException('Ship scene cancelled','AbortError'));},timer=setTimeout(()=>{lifecycle.signal.removeEventListener('abort',cancelled);try{assertLive();resolve();}catch(error){reject(error);}},ms);lifecycle.signal.addEventListener('abort',cancelled,{once:true});});\r\n const ownedShips=assetBridge.ownedShipIds?.()||[];if(!ownedShips.length)throw new Error('No owned ship is available for the arrival scene.');\r\n if(host.querySelector(':scope > .ship-scene'))return window.myr5ShipScene||null;\r\n const root=document.createElement('section');root.className='ship-scene';root.setAttribute('aria-label','Coach arrival');\r\n root.innerHTML='<div class=\"ship-scene-background\" aria-hidden=\"true\"></div><div class=\"ship-scene-vignette\" aria-hidden=\"true\"></div><div class=\"ship-scene-beam\" aria-hidden=\"true\"></div><canvas class=\"ship-scene-canvas\" tabindex=\"0\" role=\"button\" aria-label=\"Customize this coach\"></canvas><p class=\"ship-scene-status\" role=\"status\">Preparing coach arrival…</p>';\r\n host.prepend(root);host.classList.add('ship-intro-conceals-coach');\r\n const beam=root.querySelector('.ship-scene-beam'),canvas=root.querySelector('canvas'),status=root.querySelector('.ship-scene-status');\r\n const flash=document.createElement('div');flash.className='ship-scene-flash';flash.setAttribute('aria-hidden','true');document.body.append(flash);\r\n const scene=new THREE.Scene(),camera=new THREE.PerspectiveCamera(34,1,.1,400);let renderer;\r\n try{renderer=new THREE.WebGLRenderer({canvas,alpha:true,antialias:true,powerPreference:'high-performance'});}catch(error){gpu?.();host.classList.remove('ship-intro-conceals-coach');root.remove();flash.remove();assetBridge.dispose?.();throw error;}\r\n renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.toneMapping=THREE.ACESFilmicToneMapping;renderer.toneMappingExposure=1.15;renderer.setPixelRatio(Math.min(devicePixelRatio,2));renderer.shadowMap.enabled=true;\r\n const space=createCoachPreviewSpace(THREE,{pixelRatio:renderer.getPixelRatio()});scene.background=space.background;scene.fog=space.fog;scene.add(space.group);\r\n camera.position.set(0,.45,7);camera.lookAt(0,.9,0);scene.add(new THREE.HemisphereLight(0xe9d9ff,0x23162d,2.5));\r\n const key=new THREE.DirectionalLight(0xffefca,4.2);key.position.set(-3,5,4);key.castShadow=true;scene.add(key);const rim=new THREE.DirectionalLight(0xb58cff,3.2);rim.position.set(4,2,-3);scene.add(rim);\r\n const manager=new THREE.LoadingManager();manager.setURLModifier(url=>{if(!/^(blob:|data:)/.test(url)&&!(starter&&url.startsWith('/pod/worlds/starter/')))throw new Error('Ship assets must be embedded verified bytes');return url;});\r\n const loader=new GLTFLoader(manager),raycaster=new THREE.Raycaster(),pointer=new THREE.Vector2(),cache=new Map(),models=new Set(),custom=savedShip(ownerId);let state={...initialScene(recipe()),ship:ownedShips.includes(initialShip)?initialShip:ownedShips.includes(custom.ship)?custom.ship:ownedShips.includes(initialScene(recipe()).ship)?initialScene(recipe()).ship:ownedShips[0]},ship=null,shipMeshes=[],shipEpoch=0,disposed=false,raf=0,approachStart=0,approaching=false,hoverStart=performance.now(),swapChain=Promise.resolve(),measured=null,pose={y:SHIP_ANCHOR_Y,scale:1},shipTint=/^#[0-9a-f]{6}$/i.test(custom.tint||'')?custom.tint:recipeShipTint(recipe())||'#ffffff';\r\n const css=document.createElement('link');css.rel='stylesheet';css.href='/modules/ships/ship-scene.css';document.head.append(css);\r\n // The hull hovers above the coach card (see shipPoseAbove); recomputed whenever the layout changes.\r\n const placeShip=()=>{const card=host.querySelector('.myr5-companion-card');if(!measured||!card)return;pose=shipPoseAbove(coachBand(root.getBoundingClientRect(),card.getBoundingClientRect()),measured);root.style.setProperty('--ship-belly',`${Math.max(0,(1-pose.belly)*50)}%`);};\r\n const resize=()=>{const rect=root.getBoundingClientRect(),w=Math.max(1,rect.width),h=Math.max(1,rect.height);renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();placeShip()};\r\n const observer=new ResizeObserver(resize);observer.observe(root);resize();\r\n function tintShip(color){shipTint=/^#[0-9a-f]{6}$/i.test(color||'')?color:'#ffffff';for(const mesh of shipMeshes)applyShipTint(mesh,shipTint==='#ffffff'?null:shipTint);}\r\n async function loadShip(id){assertLive();id=normalizeShip(id);const epoch=++shipEpoch;status.textContent=`Loading ${id} ship…`;let source=cache.get(id);if(!source){source=loader.loadAsync(assetBridge.getShipUrl(id)).then(gltf=>{if(disposed){disposeModel(gltf.scene);throw new DOMException('Ship scene cancelled','AbortError');}const box=new THREE.Box3().setFromObject(gltf.scene),size=box.getSize(new THREE.Vector3()),center=box.getCenter(new THREE.Vector3()),normalized=new THREE.Group();gltf.scene.position.sub(center);normalized.add(gltf.scene);normalized.scale.setScalar(2.25/(Math.max(size.x,size.y,size.z)||1));models.add(normalized);return normalized;}).catch(error=>{cache.delete(id);throw error;});cache.set(id,source)}const loaded=await source;assertLive();if(epoch!==shipEpoch)return false;if(ship)scene.remove(ship);ship=new THREE.Group();const model=loaded.clone(true);model.rotation.y=SHIP_FACING;ship.add(model);ship.position.set(0,SHIP_ANCHOR_Y,SHIP_REST_Z);ship.rotation.set(.08,-.32,0);scene.add(ship);measured=measureShip(THREE,ship,camera);placeShip();ship.position.y=pose.y;ship.scale.setScalar(pose.scale);shipMeshes=[];ship.traverse(o=>{if(o.isMesh)shipMeshes.push(o)});tintShip(shipTint);state=resolveSceneSwap(state,{ship:id});root.dataset.ship=id;status.textContent='Ship ready.';return true;}\r\n // Background selection remains scene metadata; pixel worlds belong to the center pod viewport.\r\n function setBackground(id){id=normalizeBackground(id);root.dataset.background=id;state=resolveSceneSwap(state,{background:id});return id}\r\n function setCoach(coach){state=resolveSceneSwap(state,{coach});root.dataset.coach=typeof coach==='string'?coach:'recipe';if(coach&&typeof coach==='object')window.dispatchEvent(new CustomEvent('myr5:recipe',{detail:coach}));window.dispatchEvent(new CustomEvent('myr5:coach-scene-swap',{detail:{coach}}));return coach}\r\n async function ensureCoach(){if(!document.querySelector('.myr5-companion-card'))try{await import('/creature/assets/phone.js')}catch(error){console.warn('Coach viewer unavailable',error)}assertLive();const started=performance.now();while(!document.querySelector('.myr5-companion-card')&&performance.now()-started<8000)await pause(50);if(!document.querySelector('.myr5-companion-card'))throw new Error('Coach viewer did not become ready');}\r\n async function flashTransition(change){assertLive();flash.setAttribute('popover','manual');try{flash.showPopover?.();}catch{}flash.classList.add('is-on');window.dispatchEvent(new CustomEvent('myr5:portal-transition',{detail:{phase:'flash',duration:reduced()?112:732,source:'coach-scene'}}));try{await pause(16);await pause(reduced()?40:340);await change();assertLive();host.classList.remove('ship-intro-conceals-coach');host.classList.add('ship-intro-revealed');placeShip();await pause(16);flash.classList.remove('is-on');await pause(reduced()?40:360);assertLive();window.dispatchEvent(new CustomEvent('myr5:portal-transition',{detail:{phase:'complete',source:'coach-scene'}}));}finally{flash.classList.remove('is-on');try{flash.hidePopover?.();}catch{}}}\r\n function ready(revealComplete=false){assertLive();window.dispatchEvent(new CustomEvent('myr5:ship-scene-ready',{detail:{...state,revealComplete:revealComplete&&!starter,ownerId,starter}}))}\r\n async function revealShip(id=state.ship,coach=state.coach){assertLive();if(!assetBridge.ownedShipIds().includes(normalizeShip(id)))throw new Error('ship is not owned');state=resolveSceneSwap(state,{ship:id,coach});setBackground(state.background);const loaded=await Promise.all([loadShip(state.ship),ensureCoach()]);assertLive();if(!loaded[0])return false;placeShip();/* the coach card may land after the hull did */if(!reduced()){root.dataset.phase='approach';approaching=true;approachStart=performance.now();await pause(APPROACH_MS);root.dataset.phase='beam';beam.classList.add('is-charging');await pause(BEAM_CHARGE_MS);beam.classList.add('is-open');await pause(450);}await flashTransition(async()=>{beam.classList.remove('is-open','is-charging');setCoach(coach)});root.dataset.phase='ready';status.textContent='Coach ready. Select the ship to customize.';ready(true);return true}\r\n async function swap(next={},options={}){swapChain=swapChain.catch(()=>{}).then(async()=>{assertLive();const target=resolveSceneSwap(state,next);if(!assetBridge.ownedShipIds().includes(target.ship))throw new Error('ship is not owned');const change=async()=>{if(target.ship!==state.ship&&!await loadShip(target.ship))throw new Error('Ship changed while loading');assertLive();if(target.background!==state.background)setBackground(target.background);if(target.coach!==state.coach)setCoach(target.coach);state=target};if(options.flash===false)await change();else await flashTransition(change);ready(false);return state});return swapChain}\r\n async function play(){return revealShip(state.ship,state.coach)}\r\n function hit(event){if(!ship)return false;const rect=canvas.getBoundingClientRect();pointer.set((event.clientX-rect.left)/rect.width*2-1,-((event.clientY-rect.top)/rect.height*2-1));raycaster.setFromCamera(pointer,camera);return raycaster.intersectObjects(shipMeshes,false).length>0}\r\n const openCustomizer=()=>{if(root.dataset.phase==='ready')openGatedCustomizer(customizer);};canvas.addEventListener('pointermove',e=>canvas.classList.toggle('is-over-ship',hit(e)));canvas.addEventListener('pointerleave',()=>canvas.classList.remove('is-over-ship'));canvas.addEventListener('click',e=>{if(hit(e))openCustomizer()});canvas.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();openCustomizer()}});\r\n function tick(now){if(disposed)return;if(ship){if(reduced()){approaching=false;ship.position.set(0,pose.y,SHIP_REST_Z);ship.scale.setScalar(pose.scale);ship.rotation.set(.08,-.32,0);}else if(approaching){const p=sampleApproach(now-approachStart);ship.position.set(p.x,p.y-SHIP_ANCHOR_Y+pose.y,p.z);ship.scale.setScalar(p.scale*pose.scale);ship.rotation.z=p.roll;if(p.done){approaching=false;hoverStart=now;ship.rotation.z=0}}else{ship.position.y=pose.y+Math.sin((now-hoverStart)/820)*.07*pose.scale;ship.scale.setScalar(pose.scale);ship.rotation.y=-.32+Math.sin((now-hoverStart)/1700)*.055}}offAxis(camera,7);renderer.render(scene,camera);raf=requestAnimationFrame(tick)}raf=requestAnimationFrame(tick);\r\n const failed=error=>{if(!disposed){status.textContent='Ship unavailable. Your coach is still ready.';host.classList.remove('ship-intro-conceals-coach');beam.classList.remove('is-open','is-charging');}if(error?.name!=='AbortError')console.warn('Coach ship unavailable',error);};\r\n const storage=e=>{if(e.key===RECIPE_KEY&&e.newValue)try{const parsed=JSON.parse(e.newValue),next=initialScene(parsed);void swap(next).then(()=>tintShip(recipeShipTint(parsed)||'#ffffff')).catch(failed)}catch{}};\r\n const recolor=e=>{if(e.detail?.ownerId!==ownerId)return;if(e.detail.ship===state.ship)tintShip(e.detail.tint);else if(assetBridge.ownedShipIds().includes(e.detail.ship))void swap({ship:e.detail.ship},{flash:false}).then(()=>tintShip(e.detail.tint)).catch(failed);};\r\n const accountChanged=()=>{if(globalThis.myr5AuthenticatedAccount?.user?.id!==ownerId)api.dispose();};\r\n window.addEventListener('storage',storage);window.addEventListener('myr5:ship-customization',recolor);window.addEventListener('myr5:account-ready',accountChanged);window.addEventListener('myr5:account-cleared',accountChanged);\r\n const api={get state(){return{...state}},swap,setShip:ship=>swap({ship},{flash:false}),setBackground:background=>swap({background},{flash:false}),setCoach:coach=>swap({coach},{flash:false}),setShipTint:tint=>{assertLive();tintShip(tint)},play,reveal:revealShip,openCustomizer,dispose(){if(disposed)return;disposed=true;lifecycle.abort();++shipEpoch;cancelAnimationFrame(raf);observer.disconnect();window.removeEventListener('storage',storage);window.removeEventListener('myr5:ship-customization',recolor);window.removeEventListener('myr5:account-ready',accountChanged);window.removeEventListener('myr5:account-cleared',accountChanged);window.removeEventListener('pagehide',pagehide);for(const model of models)disposeModel(model);models.clear();cache.clear();space.dispose();renderer.dispose();renderer.forceContextLoss();gpu?.(canvas);flash.remove();root.remove();css.remove();host.classList.remove('ship-intro-conceals-coach','ship-intro-revealed');assetBridge.dispose?.();if(window.myr5ShipScene===api)delete window.myr5ShipScene;}};\r\n const pagehide=()=>api.dispose();window.addEventListener('pagehide',pagehide);\r\n window.myr5ShipScene=api;api.ready=revealShip(state.ship,state.coach).catch(error=>{failed(error);return false;});return api;\r\n}\r\n","modules/ships/ship-scene-domain.mjs":"export const SHIP_STYLES=Object.freeze(['supportive','direct','analytical','playful','calm','mom']);\r\nexport const BIOMES=Object.freeze(['original','patch','fold','lattice','wax','fungi','glass','bristle','cork','coral','metal','feather','moss','stormcloud','frost','ember','shadow','dragon','spring','vine','chitin','puff','rock','shag']);\r\nconst PART_WEIGHTS=Object.freeze({body:3,head:2,eye:1,collar:1,arms:1,feet:1});\r\nexport const normalizeShip=value=>SHIP_STYLES.includes(value)?value:'supportive';\r\nexport function normalizeBackground(value){if(typeof value==='number'&&Number.isInteger(value))return BIOMES[value]||BIOMES[0];return BIOMES.includes(value)?value:BIOMES[0];}\r\nexport function dominantFamily(design={}){const styles=design.styles&&typeof design.styles==='object'?design.styles:design,body=Number.isInteger(Number(styles.body))?Number(styles.body):0,score=new Map();for(const [part,weight]of Object.entries(PART_WEIGHTS)){const value=Number(styles[part]);if(Number.isInteger(value)&&value>=0)score.set(value,(score.get(value)||0)+weight)}if(!score.size)return body;let best=body,bestScore=score.get(body)||-1;for(const [family,value]of score)if(value>bestScore||(value===bestScore&&family===body)){best=family;bestScore=value}return best;}\r\n/** The tint the recipe saved for the coach's ship; null keeps the ship's own materials. */\r\nexport const recipeShipTint=design=>/^#[0-9a-f]{6}$/i.test(design?.shipColor||'')?design.shipColor:null;\r\n/** Multiply the hull's base colours by `color` (shading, textures and glowing windows/lights stay); null restores the originals. */\r\nexport function applyShipTint(root,color){const hex=/^#[0-9a-f]{6}$/i.test(color||'')?color:null;root?.traverse(node=>{for(const m of [].concat(node.material||[])){if(!m?.color)continue;if(m.userData.shipBase===undefined)m.userData.shipBase=m.color.getHex();if(m.emissive&&m.emissive.getHex()&&m.emissiveIntensity>0)continue;m.color.set(hex??m.userData.shipBase);m.needsUpdate=true;}});}\r\nexport function initialScene(design={}){return Object.freeze({ship:normalizeShip(design.shipId??design.coach),background:normalizeBackground(dominantFamily(design)),coach:design});}\r\nexport function resolveSceneSwap(current,next={}){return Object.freeze({ship:next.ship===undefined?normalizeShip(current.ship):normalizeShip(next.ship),background:next.background===undefined?normalizeBackground(current.background):normalizeBackground(next.background),coach:next.coach===undefined?current.coach:next.coach});}\r\n// #145 (Ian 2026-09-23): the ship shows its stern to the viewer, flies in over their head and settles nearer the\r\n// camera than the coach; the beam waits until it has landed. The duration knobs: the flight, then the beam's charge.\r\nexport const APPROACH_MS=2200,BEAM_CHARGE_MS=500;\r\n// The starter ship's nose is its model +x (cockpit; the engines are at -x): a quarter turn puts the stern to the camera.\r\nexport const SHIP_FACING=Math.PI/2,SHIP_REST_Z=1.5;\r\n// From above and behind the camera (z 7) it glides forward and down over the coach into its hover spot: depth and\r\n// drift ease out, height a little faster, so it drops into view at the top edge and slows into place.\r\nexport function sampleApproach(elapsed,duration=APPROACH_MS){const t=Math.max(0,Math.min(1,elapsed/duration)),far=Math.pow(1-t,3),high=Math.pow(1-t,5);if(t===1)return Object.freeze({x:0,y:SHIP_ANCHOR_Y,z:SHIP_REST_Z,scale:1,roll:0,done:true});return Object.freeze({x:1.4*far,y:SHIP_ANCHOR_Y+2.6*high,z:SHIP_REST_Z+8.5*far,scale:1,roll:-.25*far,done:false});}\r\n// Hover pose that keeps the whole hull above the coach. The coach card is framed body-to-edges (viewer\r\n// 'overlay' stage: feet on its bottom edge, head at or below its top), so its top edge bounds the head.\r\n// band: NDC y range above the card; measured: the ship's NDC y box (top/bottom) and origin at the base\r\n// anchor and scale 1, plus unit = NDC y per world unit of height. Returns world y, scale and the NDC y of\r\n// the posed hull's belly (where the beam starts). A band too short to use keeps the base pose.\r\nexport const SHIP_ANCHOR_Y=1.82;\r\nexport function coachBand(stage,coach,{margin=.08,gap=.02}={}){const h=stage.height||1,top=h*margin,bottom=coach.top-stage.top-h*gap;return {top:1-2*top/h,bottom:1-2*bottom/h,aspect:stage.width/h};}\r\n// A portrait phone (375x812) sees less width than height: the hull's widest side (NDC x, about the centred origin)\r\n// also caps the scale so the wings are never cut by the stage edges. `side` is the NDC half-width it may use.\r\nexport function shipPoseAbove(band,measured,fill=.85,side=.9){\r\n // NDC x shrinks as the stage widens: rescale a measurement taken at another aspect (a later resize) to this one.\r\n const height=measured.top-measured.bottom,stretch=band.aspect>0&&measured.aspect>0?measured.aspect/band.aspect:1,half=Math.max(Math.abs(measured.left??0),Math.abs(measured.right??0))*stretch,wide=half>side?side/half:1;\r\n if(!(band.top-band.bottom>.2)||!(height>0)||!(measured.unit>0))return Object.freeze({y:SHIP_ANCHOR_Y,scale:wide,belly:measured.bottom-(measured.bottom-measured.origin)*(1-wide)});\r\n const scale=Math.min(1,wide,(band.top-band.bottom)*fill/height),centre=(band.top+band.bottom)/2;\r\n return Object.freeze({y:SHIP_ANCHOR_Y+(centre-((measured.top+measured.bottom)/2-measured.origin)*scale-measured.origin)/measured.unit,scale,belly:centre-height*scale/2});\r\n}\r\n// NDC y (and x) extent of an object's projected vertices (the visible hull, not its looser bounding box), its\r\n// origin and NDC y per world unit, for shipPoseAbove.\r\nexport function measureShip(THREE,object,camera){\r\n camera.updateMatrixWorld();object.updateMatrixWorld(true);\r\n const v=new THREE.Vector3();let top=-Infinity,bottom=Infinity,left=Infinity,right=-Infinity;\r\n object.traverse(mesh=>{const position=mesh.isMesh&&mesh.geometry.attributes.position;if(position)for(let i=0;i<position.count;i++){v.fromBufferAttribute(position,i).applyMatrix4(mesh.matrixWorld).project(camera);if(v.y>top)top=v.y;if(v.y<bottom)bottom=v.y;if(v.x<left)left=v.x;if(v.x>right)right=v.x;}});\r\n const origin=object.position.clone().project(camera).y,above=object.position.clone().add(new THREE.Vector3(0,1,0)).project(camera).y;\r\n return {top,bottom,left,right,aspect:camera.aspect,origin,unit:above-origin};\r\n}\r\n// #148: each ship activation writes a one-use, versioned admission token. The editor consumes it as\r\n// soon as it loads, so a typed URL cannot reuse an old visit's sessionStorage value.\r\nexport const SHIP_GATE='myr5-ship-gate',SHIP_GATE_TOKEN='ship-admission-v2',SHIP_HISTORY_ADMISSION='myr5-ship-admitted-v2';\r\nexport function openCustomizer(url='/creature/index.html'){try{sessionStorage.setItem(SHIP_GATE,SHIP_GATE_TOKEN);location.assign(url);}catch{try{sessionStorage.removeItem(SHIP_GATE)}catch{}location.assign('/pose.html#select');}}\r\n","modules/ships/ship-scene.css":".containment-pod{isolation:isolate}\r\n.ship-scene{position:absolute;inset:0;z-index:2;overflow:hidden;border-radius:inherit;background:#100b1a}\r\n.ship-scene-background,.ship-scene-vignette,.ship-scene-beam,.ship-scene-canvas{position:absolute;inset:0}\r\n.ship-scene-background{background:radial-gradient(ellipse at 28% 24%,#50326960,transparent 50%),linear-gradient(#090815,#20162f 60%,#120d1e);image-rendering:auto;transform:scale(1.02)}\r\n.ship-scene-vignette{z-index:4;pointer-events:none;background:linear-gradient(#130b2430 0 34%,#12091f00 55%,#07040dcc),radial-gradient(circle at 50% 42%,transparent 30%,#08040d99 100%)}\r\n.ship-scene-canvas{z-index:3;width:100%;height:100%;outline:0}\r\n.ship-scene-canvas.is-over-ship{cursor:pointer;filter:drop-shadow(0 0 10px #ffd86f)}\r\n.ship-scene-canvas:focus-visible{outline:3px solid #ffd76d;outline-offset:-5px}\r\n.ship-scene-beam{z-index:4;pointer-events:none;inset:var(--ship-belly,31%) 18% -12%;opacity:0;clip-path:polygon(43% 0,57% 0,92% 100%,8% 100%);background:radial-gradient(ellipse at 50% 0,#fff 0 5%,#fff4ba 9%,#ffc641a8 34%,#ffad1820 70%,transparent 74%);filter:blur(5px);transform:scaleX(.18);transform-origin:50% 0;transition:opacity .28s,transform .55s cubic-bezier(.15,.8,.2,1)}\r\n.ship-scene-beam.is-charging{opacity:.46}\r\n.ship-scene-beam.is-open{opacity:1;transform:scaleX(1)}\r\n.ship-scene-status{position:absolute;z-index:5;left:12px;right:12px;bottom:9px;margin:0;text-align:center;color:#fff0c0;font:700 10px/1.4 ui-monospace,monospace;letter-spacing:.06em;text-shadow:0 2px 3px #000}\r\n.ship-scene-flash{position:fixed;inset:0;z-index:2147483000;pointer-events:none;opacity:0;background:radial-gradient(circle at 50% 48%,#fff 0 40%,#fffdf0 63%,#ffd65a 100%);transition:opacity .31s ease-in}\r\n.ship-scene-flash.is-on{opacity:1;transition-timing-function:cubic-bezier(.1,.9,.1,1)}\r\n#view.ship-intro-conceals-coach .coach-mount,#view.ship-intro-conceals-coach .myr5-companion-card{opacity:0!important}\r\n#view.ship-intro-revealed .coach-mount{position:absolute;z-index:4;background:transparent!important;pointer-events:none}\r\n#view.ship-intro-revealed .myr5-companion-card{position:absolute;z-index:4;left:18%;right:18%;top:29%;bottom:-2%;width:auto;height:auto;border:0;background:transparent;overflow:visible;backdrop-filter:none;pointer-events:none}\r\n#view.ship-intro-revealed .myr5-companion-stage{width:100%;height:100%;background:transparent;filter:drop-shadow(0 9px 12px #0009)}\r\n#view.ship-intro-revealed .myr5-companion-status,#view.ship-intro-revealed .myr5-customize,#view.ship-intro-revealed .myr5-hide{display:none!important}\r\n.ship-scene~.pod-floor,.ship-scene~.pod-nameplate,.ship-scene~.camera-preview{z-index:5}\r\n@media(prefers-reduced-motion:reduce){.ship-scene-beam,.ship-scene-flash{transition-duration:.01ms!important}.ship-scene-background{transform:none}}\r\n.ship-scene-flash[popover]{margin:0;border:0;padding:0;max-width:none;max-height:none;width:100vw;height:100dvh;}\r\n","modules/ships/ship-section-controller.mjs":"import { DEFAULT_LOCAL_RESOURCE_POLICY, indexedDbChunkStore } from '../materials/chunk-delivery.mjs';\r\nimport { downloadPostDownloadSection } from '../materials/post-download-controller.mjs';\r\nimport { createVerifiedShipAssetBridge } from './verified-ship-assets.mjs';\r\nimport { ownedShipIds } from './ship-access.mjs';\r\n\r\nconst ownerId=account=>account?.user?.id;\r\nconst stable=id=>typeof id==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(id);\r\n\r\n/** User-triggered ship section download; requires signed hosted metadata and explicit access authorization. */\r\nexport async function downloadOwnedShipSection({account=globalThis.myr5AuthenticatedAccount,authorize=()=>false,fetchImpl=globalThis.fetch,store=indexedDbChunkStore(),policy=DEFAULT_LOCAL_RESOURCE_POLICY,signal,onProgress}={}){\r\n const owner=ownerId(account);if(!stable(owner)||!ownedShipIds().length)throw new Error('Sign in and unlock a ship before downloading this section.');\r\n if(!authorize('coach-ships-biomes',account))throw new Error('Ship section access has not been authorized.');\r\n const delivery=await downloadPostDownloadSection({id:'coach-ships-biomes',account,authorize:(_id,current)=>ownerId(current)===owner&&authorize(_id,current)&&ownedShipIds().length>0,fetchImpl,store,policy,signal,onProgress});\r\n return Object.freeze({manifest:delivery.manifest,downloader:delivery.downloader,createBridge:()=>createVerifiedShipAssetBridge({downloader:delivery.downloader,manifest:delivery.manifest,isOwned:id=>id==='coach-ships-biomes'&&delivery.isOwned()&&ownedShipIds().length>0,canUseShip:ownedShipIds})});\r\n}\r\n","modules/ships/ship-view-bridge.mjs":"// Statically imported by app.mjs ONLY (never by modules/ships/ship-view.mjs, which scripts/build.mjs\r\n// serves unbundled in production — see external list). Being a static import of app.mjs means this\r\n// module, and everything under it (material-config.mjs's build-time trust key define,\r\n// post-download-sections.mjs -> battle-pass.mjs -> a .ts file), gets compiled into app-runtime.mjs\r\n// instead of being fetched raw by the browser, where the define would be undefined and the .ts file\r\n// would 404. tests/ship-view-import-graph.test.mjs enforces that ship-view.mjs never re-acquires\r\n// this chain.\r\nimport {ownedShipIds,hasSeenShipReveal,acceptShipRevealComplete} from './ship-access.mjs';\r\n\r\nexport {ownedShipIds};\r\n// Shared with the customizer's Ship tab preview (creature/source/editor-workbench.ts).\r\nexport {localVerifiedBridge} from './verified-ship-assets.mjs';\r\n\r\n/** Called only with the view's verified local bridge. The real post-flash scene\r\n * event is the sole source of reveal completion; cancellation never marks seen. */\r\nexport async function mountFirstShipArrival({host,assetBridge,isCurrent = () => true}) {\r\n const ownerId = globalThis.myr5AuthenticatedAccount?.user?.id;\r\n const ship = assetBridge.ownedShipIds().find(id => !hasSeenShipReveal(id));\r\n if (!ownerId || !ship) return null;\r\n // Optional scene code must not become a core-only offline startup dependency.\r\n const [{mountShipScene},{claimGraphics}] = await Promise.all([import('./ship-intro.mjs'),import('../graphics-lifecycle.mjs')]);\r\n const gpu = claimGraphics('ship',{keep:['coach']});await gpu.ready; // the hidden portal board yields; the coach rides the beam\r\n if (!isCurrent() || globalThis.myr5AuthenticatedAccount?.user?.id !== ownerId) {gpu();throw new DOMException('Ship arrival cancelled', 'AbortError');}\r\n let scene, disposed = false;\r\n const complete = event => {\r\n  if (!disposed && scene && event.detail?.ownerId === ownerId && event.detail?.ship === ship) acceptShipRevealComplete(event);\r\n };\r\n window.addEventListener('myr5:ship-scene-ready', complete);\r\n try { scene = mountShipScene({host,assetBridge,ship,gpu}); }\r\n catch (error) { window.removeEventListener('myr5:ship-scene-ready', complete); throw error; }\r\n return {\r\n  ready: scene.ready.finally(() => window.removeEventListener('myr5:ship-scene-ready', complete)),\r\n  dispose() { if (disposed) return; disposed = true; window.removeEventListener('myr5:ship-scene-ready', complete); scene.dispose(); }\r\n };\r\n}\r\n","modules/ships/ship-view.css":".ship-view{position:fixed;inset:0;width:100vw;height:100dvh;max-width:none;max-height:none;margin:0;padding:0;border:0;background:#0b0714;color:#fff0c0}\r\n.ship-view::backdrop{background:#000}\r\n.ship-view-stage{position:absolute;inset:0;overflow:hidden}\r\n.ship-view-bg{position:absolute;inset:0;z-index:0;background:radial-gradient(ellipse at 28% 24%,#50326960,transparent 50%),linear-gradient(#090815,#20162f 60%,#120d1e);image-rendering:auto}\r\n.ship-view-canvas{position:absolute;inset:0;z-index:1;width:100%;height:100%}\r\n.ship-view-coach{position:absolute;inset:36% 0 0;z-index:2}\r\n.ship-view-coach .myr5-companion-card{position:absolute;inset:0;width:auto;height:auto;border:0;background:transparent;overflow:visible;backdrop-filter:none;border-radius:0}\r\n.ship-view-coach .myr5-companion-stage{width:100%;height:100%;background:transparent}\r\n.ship-view-coach .myr5-companion-status,.ship-view-coach .myr5-customize,.ship-view-coach .myr5-hide{display:none!important}\r\n.ship-view-note{position:absolute;z-index:3;left:12px;right:12px;bottom:9px;margin:0;text-align:center;color:#fff0c0;font:700 11px/1.4 ui-monospace,monospace;letter-spacing:.05em;text-shadow:0 2px 3px #000}\r\n.ship-view-fallback{position:absolute;z-index:3;left:12px;right:12px;bottom:max(12px,env(safe-area-inset-bottom));display:flex;flex-direction:column;gap:8px;align-items:center;padding:8px 12px;border-radius:12px;background:#000000b3;backdrop-filter:blur(4px)}\r\n.ship-view-fallback p{margin:0;color:#fff0c0;font:600 11px/1.4 ui-monospace,monospace;text-align:center}\r\n.ship-view-error{display:block;color:#ffb4a8;font:700 11px/1.4 ui-monospace,monospace;text-align:center}\r\n.ship-view-error[hidden]{display:none}\r\n.ship-view-download,.ship-view-retry{min-height:40px;padding:0 16px;border:0;border-radius:8px;background:#ffd76d;color:#241407;font:700 13px/1 ui-monospace,monospace}\r\n.ship-view-close{position:absolute;z-index:4;top:max(12px,env(safe-area-inset-top));right:max(12px,env(safe-area-inset-right));width:40px;height:40px;border-radius:50%;border:1px solid #70568b80;background:#21162bc9;color:#fff0c0;font-size:16px}\r\n@media(prefers-reduced-motion:reduce){.ship-view *{animation:none!important;transition:none!important}}\r\n\r\n.ship-view-stage.ship-intro-conceals-coach .ship-view-coach{opacity:0;pointer-events:none}\r\n.ship-view-stage.ship-intro-revealed .ship-view-coach{z-index:3;pointer-events:none}\r\n/* The arrival scene's status line sits up top here, clear of the upgrade line at the bottom. */\r\n.ship-view-stage .ship-scene-status{top:max(24px,env(safe-area-inset-top));bottom:auto;left:60px;right:60px}\r\n/* That status already reports the load; the view's own loading note steps aside while the scene is up. */\r\n.ship-view-stage:has(> .ship-scene) + .ship-view-note{visibility:hidden}\r\n","modules/ships/ship-view.mjs":"// D-ship-route: full-screen ship view. Same coach capsule renderer as the pod's \"Show my coach\"\r\n// card (creature/assets/phone.js), reparented full-screen, with the owned ship + supply-drop space\r\n// composed behind it when the signed \"Ships and worlds\" pack is already downloaded and verified\r\n// locally. Without that pack (signed out, no ship owned, or not downloaded) Original MYR5's bundled\r\n// starter ship shows instead, with his entrance the first open of the session.\r\n// `getBridge`/`ownedShipIds` are injected by app.mjs (modules/ships/ship-view-bridge.mjs) —\r\n// scripts/build.mjs serves THIS file unbundled in production (no Vite, no build-time defines), so it\r\n// must stay free of imports that need either. tests/ship-view-import-graph.test.mjs enforces that.\r\nimport {offAxis} from '../portal/peer.mjs'; // #135: tilt looks round the ship through the portal window\r\nimport {initialScene,recipeShipTint,applyShipTint,SHIP_ANCHOR_Y,SHIP_FACING,SHIP_REST_Z,coachBand,shipPoseAbove,measureShip,openCustomizer} from './ship-scene-domain.mjs';\r\nimport {createCoachPreviewSpace} from '../../coach-preview-space.mjs';\r\nimport {claimGraphics} from '../graphics-lifecycle.mjs';\r\n// Ship scenes keep the 3D coach (it rides the beam) and take the hidden portal board's context until they close.\r\nconst shipGpu=async()=>{const release=claimGraphics('ship',{keep:['coach']});await release.ready;return release;};\r\n\r\nconst HASH = '#ship';\r\nconst RECIPE_KEY = 'myr5-recipe-v1';\r\nconst SHIP_SETTINGS_KEY = 'myr5-ship-customization-v1';\r\nconst readJSON = key => { try { const v = JSON.parse(localStorage.getItem(key) || '{}'); return v && typeof v === 'object' && !Array.isArray(v) ? v : {}; } catch { return {}; } };\r\n\r\nconst savedTint = () => recipeShipTint(readJSON(RECIPE_KEY));\r\n// Original MYR5's recipe (coach 'supportive') maps to this ship through initialScene().\r\nconst STARTER_SHIP = 'supportive', STARTER_SHIP_URL = '/pod/worlds/starter/supportive.glb';\r\nconst UPGRADE_TEXT = 'Earn ships on your tracks · Download Ships & worlds for all of them';\r\nlet starterEntranceDone = false; // once per app session (page lifetime)\r\n\r\nfunction disposeModel(root) {\r\n const geometries = new Set(), materials = new Set(), textures = new Set();\r\n root?.traverse(node => { if (node.geometry) geometries.add(node.geometry); for (const mat of [].concat(node.material || [])) if (mat) { materials.add(mat); for (const value of Object.values(mat)) if (value?.isTexture) textures.add(value); } });\r\n for (const t of textures) t.dispose(); for (const m of materials) m.dispose(); for (const g of geometries) g.dispose();\r\n}\r\n\r\n/** A still (idle hover only) ship + supply-drop space, not the full approach/beam/flash cinematic —\r\n * used after the first arrival has completed. */\r\nasync function mountRealShip({ stage, bridge, ship, tint = null }) {\r\n const [THREE, { GLTFLoader }] = await Promise.all([import('three'), import('three/addons/loaders/GLTFLoader.js')]);\r\n const canvas = document.createElement('canvas'); canvas.className = 'ship-view-canvas'; stage.append(canvas);\r\n const scene = new THREE.Scene(), camera = new THREE.PerspectiveCamera(34, 1, .1, 400);\r\n let renderer;const gpu = await shipGpu();\r\n try { renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true, powerPreference: 'high-performance' }); }\r\n catch (error) { gpu(); canvas.remove(); throw error; }\r\n renderer.outputColorSpace = THREE.SRGBColorSpace; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = 1.15; renderer.setPixelRatio(Math.min(devicePixelRatio, 2));\r\n const space = createCoachPreviewSpace(THREE, { pixelRatio: renderer.getPixelRatio() });\r\n scene.background = space.background; scene.fog = space.fog; scene.add(space.group);\r\n camera.position.set(0, .45, 7); camera.lookAt(0, .9, 0);\r\n scene.add(new THREE.HemisphereLight(0xe9d9ff, 0x23162d, 2.5));\r\n const key = new THREE.DirectionalLight(0xffefca, 4.2); key.position.set(-3, 5, 4); scene.add(key);\r\n const rim = new THREE.DirectionalLight(0xb58cff, 3.2); rim.position.set(4, 2, -3); scene.add(rim);\r\n let place = () => {};\r\n const resize = () => { const r = stage.getBoundingClientRect(), w = Math.max(1, r.width), h = Math.max(1, r.height); renderer.setSize(w, h, false); camera.aspect = w / h; camera.updateProjectionMatrix(); place(); };\r\n const observer = new ResizeObserver(resize); observer.observe(stage); resize();\r\n let disposed = false;\r\n let loaded;\r\n try { loaded = await new GLTFLoader().loadAsync(bridge.getShipUrl(ship)); }\r\n catch (error) { observer.disconnect(); space.dispose(); renderer.dispose(); renderer.forceContextLoss(); gpu(canvas); canvas.remove(); throw error; }\r\n if (disposed) { disposeModel(loaded.scene); observer.disconnect(); space.dispose(); renderer.dispose(); renderer.forceContextLoss(); gpu(canvas); canvas.remove(); throw new DOMException('Ship view closed', 'AbortError'); }\r\n const box = new THREE.Box3().setFromObject(loaded.scene), size = box.getSize(new THREE.Vector3()), center = box.getCenter(new THREE.Vector3());\r\n loaded.scene.position.sub(center);\r\n const group = new THREE.Group(), model = new THREE.Group(), fit = 2.25 / (Math.max(size.x, size.y, size.z) || 1); model.rotation.y = SHIP_FACING; model.add(loaded.scene); applyShipTint(model, tint); group.add(model); group.scale.setScalar(fit);\r\n group.position.set(0, SHIP_ANCHOR_Y, SHIP_REST_Z); group.rotation.set(.08, -.32, 0); scene.add(group);\r\n // Same hover pose as the arrival scene's end: the whole hull above the coach card.\r\n const measured = measureShip(THREE, group, camera); let pose;\r\n place = () => { pose = shipPoseAbove(coachBand(stage.getBoundingClientRect(), coachMount.getBoundingClientRect()), measured); group.position.y = pose.y; group.scale.setScalar(fit * pose.scale); };\r\n place();\r\n // #148: the still ship opens the customizer exactly like the arrival's ship does (tap the hull, or Enter/Space).\r\n const raycaster = new THREE.Raycaster(), pointer = new THREE.Vector2();\r\n canvas.tabIndex = 0; canvas.setAttribute('role', 'button'); canvas.setAttribute('aria-label', 'Customize this coach');\r\n canvas.addEventListener('click', e => { const r = canvas.getBoundingClientRect(); pointer.set((e.clientX - r.left) / r.width * 2 - 1, -((e.clientY - r.top) / r.height * 2 - 1)); raycaster.setFromCamera(pointer, camera); if (raycaster.intersectObject(group, true).length) openCustomizer(); });\r\n canvas.addEventListener('keydown', e => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openCustomizer(); } });\r\n const reduced = matchMedia('(prefers-reduced-motion: reduce)').matches;\r\n let raf = 0; const start = performance.now();\r\n function tick(now) {\r\n  if (disposed) return;\r\n  if (!reduced) { group.position.y = pose.y + Math.sin((now - start) / 820) * .07 * pose.scale; group.rotation.y = -.32 + Math.sin((now - start) / 1700) * .055; }\r\n  offAxis(camera, 7); renderer.render(scene, camera); raf = requestAnimationFrame(tick);\r\n }\r\n raf = requestAnimationFrame(tick);\r\n return {\r\n  dispose() {\r\n   if (disposed) return; disposed = true; cancelAnimationFrame(raf); observer.disconnect();\r\n   space.dispose(); disposeModel(scene); renderer.dispose(); renderer.forceContextLoss(); gpu(canvas); canvas.remove();\r\n   bridge.dispose?.();\r\n  }\r\n };\r\n}\r\n\r\nlet dialog = null, stage = null, bgEl = null, coachMount = null, note = null, fallback = null, downloadBtn = null, customizeBtn = null, retryBtn = null, errorLine = null;\r\nlet viewOwner = null, lastOpen = {};\r\nlet realShip = null, pushedHash = false, openEpoch = 0, coachStage = null, openHash = HASH;\r\nconst LOADING = 'Loading your ship…';\r\n\r\nfunction clearShipVisual() { realShip?.dispose(); realShip = null; bgEl.style.backgroundImage = ''; fallback.hidden = true; customizeBtn.hidden = true; retryBtn.hidden = true; errorLine.hidden = true; }\r\n// #148: no ship to tap (no WebGL, or the model failed): the customizer is still one plain button away.\r\nfunction offerCustomizer() { fallback.hidden = false; customizeBtn.hidden = false; }\r\n// A ship that failed to load says so and can be tried again (the same open, re-run in place).\r\nfunction offerRetry(text) { errorLine.textContent = text; errorLine.hidden = false; retryBtn.hidden = false; fallback.hidden = false; }\r\n// Inside the app modules/routes.mjs owns this view's #hash (it pushes and pops it: one owner of history). Standalone\r\n// (no router) the view keeps its own.\r\nconst routed = () => !!window.myr5Routes;\r\n\r\n/** W2-2O: the starter ship and wonders are Starter-pack art. When the ship didn't load because it isn't on this\r\n * phone (offline, never downloaded; not a WebGL failure), the plain backdrop and the coach stay, and the Starter\r\n * pack is offered. */\r\nasync function offerStarter(isCurrent) {\r\n if (navigator.onLine || await globalThis.caches?.match(STARTER_SHIP_URL).catch(() => null) || !isCurrent()) return false;\r\n const line = fallback.querySelector('p'); line.textContent = 'Your starter ship and its worlds come with the Starter pack.'; line.hidden = false;\r\n downloadBtn.textContent = 'Download the Starter pack'; downloadBtn.dataset.pack = 'starter'; downloadBtn.hidden = false; fallback.hidden = false;\r\n return true;\r\n}\r\n\r\n/** No verified pack: the starter ship over the supply-drop space. The upgrade line shows only when\r\n * signed in; the download button only when they own a ship. Reduced motion or a repeat open idles. */\r\nasync function showStarter({ signedIn, owned, isCurrent, always = false }) {\r\n const line = fallback.querySelector('p'); line.textContent = UPGRADE_TEXT; line.hidden = !signedIn; downloadBtn.textContent = 'Download Ships & worlds'; downloadBtn.dataset.pack = 'coach-ships-biomes'; downloadBtn.hidden = !owned.length; fallback.hidden = !signedIn;\r\n const bridge = { ownedShipIds: () => [STARTER_SHIP], getShipUrl: () => STARTER_SHIP_URL };\r\n try {\r\n  if ((always || !starterEntranceDone) && !matchMedia('(prefers-reduced-motion: reduce)').matches) {\r\n   const { mountShipScene } = await import('./ship-intro.mjs');\r\n   const gpu = await shipGpu();\r\n   if (!isCurrent()) { gpu(); return; }\r\n   const scene = realShip = mountShipScene({ host: stage, assetBridge: bridge, ship: STARTER_SHIP, starter: true, gpu });\r\n   // Offered (W2-2O): the arrival scene steps aside (its beam and status), leaving the plain backdrop, the coach and the offer.\r\n   // No ship to tap either way (#148): the plain customizer button shows too.\r\n   if (await scene.ready) { if (isCurrent()) starterEntranceDone = true; return true; }\r\n   if (await offerStarter(isCurrent) && realShip === scene) { scene.dispose(); realShip = null; } if (isCurrent()) offerCustomizer();\r\n   return false;\r\n  }\r\n  const mounted = await mountRealShip({ stage, bridge, ship: STARTER_SHIP, tint: savedTint() });\r\n  if (!isCurrent()) mounted.dispose(); else realShip = mounted;\r\n  return true;\r\n } catch { await offerStarter(isCurrent); if (isCurrent()) offerCustomizer(); /* no WebGL or model: the space fallback and coach still show */ return false; }\r\n}\r\n\r\nasync function waitForCard(timeoutMs = 8000) {\r\n const started = performance.now();\r\n while (!document.querySelector('.myr5-companion-card') && performance.now() - started < timeoutMs) await new Promise(r => setTimeout(r, 50));\r\n return document.querySelector('.myr5-companion-card');\r\n}\r\n\r\nfunction onPopState() { if (!routed() && dialog?.open && location.hash !== openHash) dialog.close(); }\r\n\r\nfunction onClose() {\r\n // The native `close` event is queued. A same-task route handoff can close and immediately reopen this\r\n // shared dialog before that event is delivered; that old event must not invalidate the new open.\r\n if (dialog?.open) return;\r\n openEpoch++; clearShipVisual();\r\n document.body.dataset.shipView = '';\r\n if (coachStage) window.myr5Creature?.stage?.(coachStage); coachStage = null;\r\n window.myr5Creature?.park?.(); // the capsule stops drawing under the quilt; its next stage() (this view, a workout) wakes it\r\n const card = coachMount.querySelector('.myr5-companion-card');\r\n if (card) document.getElementById('coachMount')?.append(card); // pod.mjs's own observer re-homes it (rest vs pod)\r\n if (!routed() && location.hash === openHash) { if (pushedHash) history.back(); else history.replaceState(null, '', location.pathname + location.search); }\r\n pushedHash = false;\r\n}\r\n\r\nfunction build() {\r\n dialog = document.createElement('dialog'); dialog.className = 'ship-view'; dialog.setAttribute('aria-label', 'Your ship');\r\n dialog.innerHTML = '<div class=\"ship-view-stage\"><div class=\"ship-view-bg\" aria-hidden=\"true\"></div><div class=\"ship-view-coach\"></div></div>'\r\n  + '<p class=\"ship-view-note\" role=\"status\"></p>'\r\n  + '<div class=\"ship-view-fallback\" hidden><strong class=\"ship-view-error\" role=\"alert\" hidden></strong><p></p><button type=\"button\" class=\"ship-view-retry\" hidden>Try again</button><button type=\"button\" class=\"ship-view-download\">Download Ships &amp; worlds</button><button type=\"button\" class=\"ship-view-customize\" hidden>Open the customizer</button></div>'\r\n  + '<button type=\"button\" class=\"ship-view-close\" aria-label=\"Close\">✕</button>';\r\n document.body.append(dialog);\r\n stage = dialog.querySelector('.ship-view-stage'); bgEl = dialog.querySelector('.ship-view-bg'); coachMount = dialog.querySelector('.ship-view-coach');\r\n note = dialog.querySelector('.ship-view-note'); fallback = dialog.querySelector('.ship-view-fallback'); downloadBtn = dialog.querySelector('.ship-view-download'); customizeBtn = dialog.querySelector('.ship-view-customize');\r\n retryBtn = dialog.querySelector('.ship-view-retry'); errorLine = dialog.querySelector('.ship-view-error');\r\n retryBtn.onclick = () => { if (dialog.open) void openShipView(lastOpen); };\r\n customizeBtn.onclick = () => openCustomizer();\r\n dialog.querySelector('.ship-view-close').onclick = () => dialog.close();\r\n downloadBtn.onclick = () => { if (typeof window.myr5Packs?.open === 'function') window.myr5Packs.open(downloadBtn.dataset.pack || 'coach-ships-biomes'); else document.querySelector('.coach-dock [data-panel=\"install\"]')?.click(); };\r\n dialog.addEventListener('close', onClose);\r\n window.addEventListener('popstate', onPopState);\r\n window.addEventListener('pagehide', () => { openEpoch++; clearShipVisual(); });\r\n const accountChanged = () => { if (dialog.open && globalThis.myr5AuthenticatedAccount?.user?.id !== viewOwner) { openEpoch++; clearShipVisual(); dialog.close(); } };\r\n window.addEventListener('myr5:account-ready', accountChanged);\r\n window.addEventListener('myr5:account-cleared', accountChanged);\r\n const css = document.createElement('link'); css.rel = 'stylesheet'; css.href = '/modules/ships/ship-view.css'; document.head.append(css);\r\n}\r\n\r\n/** window.myr5Menus.ship(): opens the full-screen ship view and returns its <dialog> (the portal\r\n * uses this for its porthole reveal / fade-back, same contract as achievements). `loadCoachViewer`\r\n * is app.mjs's existing coach-capsule loader (same function \"Show my coach\" uses); `getBridge` and\r\n * `ownedShipIds` come from app.mjs's statically-bundled modules/ships/ship-view-bridge.mjs (this\r\n * file is served unbundled and cannot import that chain itself — see the header comment). Both are\r\n * overridable for tests. W2-2A: `entrance: 'always'` plays the ship's fly-in and beam-down on every open (the\r\n * portal's oval, Ian 2026-09-23) instead of once per session / once per ship; `hash` is the route this open\r\n * owns in history (the oval's is '#select'; Menu -> Ship keeps '#ship' and the once-per-session entrance). */\r\nexport async function openShipView({ loadCoachViewer, getBridge = async () => null, ownedShipIds = () => [], mountArrival = () => null, entrance = 'first', hash = HASH } = {}) {\r\n if (!dialog) build();\r\n lastOpen = arguments[0] || {};\r\n const epoch = ++openEpoch;\r\n const owner = viewOwner = globalThis.myr5AuthenticatedAccount?.user?.id;\r\n const isCurrent = () => epoch === openEpoch && dialog.open && globalThis.myr5AuthenticatedAccount?.user?.id === owner;\r\n clearShipVisual(); note.textContent = 'Preparing your coach…';\r\n const firstOpen = !dialog.open;\r\n if (firstOpen) { openHash = hash; dialog.showModal(); }\r\n if (routed()) pushedHash = false; else if (location.hash !== openHash) { pushedHash = true; history.pushState({ myr5Ship: true }, '', openHash); } else if (firstOpen) pushedHash = false;\r\n document.body.dataset.shipView = 'true';\r\n try { await loadCoachViewer?.(); } catch { /* surfaced below via the missing card */ }\r\n const card = await waitForCard();\r\n if (!isCurrent()) return dialog;\r\n // Frame the whole body in the card (feet on its bottom edge) so the ship can hover clear above its top edge.\r\n if (card) { coachMount.append(card); note.textContent = LOADING; coachStage ??= window.myr5Creature?.stats?.().stage || null; window.myr5Creature?.stage?.('overlay'); }\r\n else note.textContent = 'Coach could not load. Check your connection and try again.';\r\n try { await showShip({ getBridge, ownedShipIds, mountArrival, entrance, owner, isCurrent }); }\r\n finally { if (epoch === openEpoch && note.textContent === LOADING) note.textContent = ''; }\r\n return dialog;\r\n}\r\n\r\nasync function showShip({ getBridge, ownedShipIds, mountArrival, entrance, owner, isCurrent }) {\r\n const signedIn = !!globalThis.myr5AuthenticatedAccount?.user?.id;\r\n const custom = readJSON(`${SHIP_SETTINGS_KEY}/${owner}`);\r\n if(custom.ship===STARTER_SHIP){await showStarter({signedIn,owned:signedIn?ownedShipIds():[],isCurrent,always:entrance==='always'});return;}\r\n let bridge = null;\r\n try { bridge = await getBridge(); } catch { bridge = null; }\r\n if (!isCurrent()) { bridge?.dispose?.(); return; }\r\n const always = entrance === 'always';\r\n if (!bridge) { if (!await showStarter({ signedIn, owned: signedIn ? ownedShipIds() : [], isCurrent, always }) && isCurrent()) offerRetry('The ship could not load.'); return; }\r\n try {\r\n  const owned = bridge.ownedShipIds();\r\n  // An explicit selection takes priority over an unrelated newly earned ship's reveal.\r\n  const arrival = owned.includes(custom.ship)?null:await mountArrival({host:stage,assetBridge:bridge,isCurrent});\r\n  if (!isCurrent()) { if (arrival) arrival.dispose(); else bridge.dispose?.(); return; }\r\n  if (arrival) {\r\n   realShip = arrival;\r\n   const completed = await arrival.ready;\r\n   if (!isCurrent()) { arrival.dispose(); return; }\r\n   if (!completed) throw new Error('Ship arrival did not complete');\r\n   fallback.hidden = true; return;\r\n  }\r\n  const scene = initialScene(readJSON(RECIPE_KEY));\r\n  const shipId = owned.includes(custom.ship) ? custom.ship : owned.includes(scene.ship) ? scene.ship : owned[0];\r\n  if (always && !matchMedia('(prefers-reduced-motion: reduce)').matches) {\r\n   const { mountShipScene } = await import('./ship-intro.mjs');\r\n   const gpu = await shipGpu();\r\n   if (!isCurrent()) { gpu(); bridge.dispose?.(); return; }\r\n   const intro = mountShipScene({ host: stage, assetBridge: bridge, ship: shipId, gpu });\r\n   realShip = { dispose() { intro.dispose(); bridge.dispose?.(); } };\r\n   const arrived = await intro.ready; if (!isCurrent()) return;\r\n   if (!arrived) throw new Error('Ship arrival did not complete'); // the owned ship failed: fall back to the starter below\r\n   fallback.hidden = true; return;\r\n  }\r\n  const mounted = await mountRealShip({ stage, bridge, ship: shipId, tint: /^#[0-9a-f]{6}$/i.test(custom.tint || '') ? custom.tint : savedTint() });\r\n  if (!isCurrent()) { mounted.dispose(); return; }\r\n  realShip = mounted; fallback.hidden = true;\r\n } catch (error) {\r\n  if (!isCurrent()) { bridge.dispose?.(); return; }\r\n  if (error?.name !== 'AbortError') console.warn('Owned ship unavailable', error);\r\n  clearShipVisual(); bridge.dispose?.();\r\n  const starter = await showStarter({ signedIn, owned: signedIn ? ownedShipIds() : [], isCurrent, always });\r\n  if (isCurrent()) offerRetry(starter ? 'Your ship did not load, so the starter ship came instead.' : 'Your ship did not load.');\r\n }\r\n}\r\n","modules/ships/verified-ship-assets.mjs":"import { unpackVerifiedBundle } from '../materials/verified-bundle.mjs';\r\nimport { SHIP_STYLES, BIOMES } from './ship-scene-domain.mjs';\r\nimport { ownedShipIds } from './ship-access.mjs';\r\nimport { SHIP_CATALOG } from './ship-catalog.mjs';\r\nimport { productionMaterialTrust } from '../materials/material-config.mjs';\r\nimport { resolvePostDownloadSection } from '../materials/post-download-sections.mjs';\r\nimport { ChunkDownloader, indexedDbChunkStore, DEFAULT_LOCAL_RESOURCE_POLICY } from '../materials/chunk-delivery.mjs';\r\n\r\nconst SHIP_PATHS=Object.freeze(Object.fromEntries(SHIP_CATALOG.map(ship=>[ship.id,ship.assetPath])));\r\nconst BIOME_BUNDLE='assets/biomes.m5bundle';\r\n\r\n/** Make scene URLs only from individually reconstructed, signed, owner-checked assets. */\r\nexport async function createVerifiedShipAssetBridge({ downloader, manifest, isOwned, canUseShip=ownedShipIds, urlApi=globalThis.URL, events=globalThis.window }={}) {\r\n  if(!downloader?.readVerifiedAsset||!manifest?.assets||typeof isOwned!=='function')throw new Error('verified ship downloader and ownership check are required');\r\n  const created=new Set(),ships=new Map(),backgrounds=new Map();let disposed=false;\r\n  const dispose=()=>{if(disposed)return;disposed=true;for(const value of created)urlApi.revokeObjectURL(value);created.clear();ships.clear();backgrounds.clear();events?.removeEventListener('myr5:account-cleared',dispose);events?.removeEventListener('myr5:account-ready',onAccount);};\r\n  const assertOwned=()=>{if(disposed||!isOwned(manifest.packId)){dispose();throw new Error('ship section ownership was revoked');}};\r\n  const onAccount=()=>{if(!isOwned(manifest.packId))dispose();};\r\n  events?.addEventListener('myr5:account-cleared',dispose);events?.addEventListener('myr5:account-ready',onAccount);\r\n  const objectUrl=blob=>{const value=urlApi.createObjectURL(blob);created.add(value);return value;};\r\n  try {\r\n    for(const id of SHIP_STYLES.filter(id=>canUseShip().includes(id))){\r\n      assertOwned();const asset=await downloader.readVerifiedAsset(manifest,SHIP_PATHS[id]);assertOwned();\r\n      ships.set(id,objectUrl(new Blob([asset.bytes],{type:'model/gltf-binary'})));\r\n    }\r\n    assertOwned();const bundle=await downloader.readVerifiedAsset(manifest,BIOME_BUNDLE);assertOwned();\r\n    const plates=await unpackVerifiedBundle(bundle.bytes);\r\n    assertOwned();for(const name of BIOMES){const bytes=plates.get(`${name}.webp`);if(!bytes)throw new Error(`verified biome plate is missing: ${name}`);backgrounds.set(name,objectUrl(new Blob([bytes],{type:'image/webp'})));}assertOwned();\r\n  } catch(error){dispose();throw error;}\r\n  const api={\r\n    getShipUrl(id){assertOwned();if(!SHIP_STYLES.includes(id)||!canUseShip().includes(id))throw new Error('ship is not owned');const url=ships.get(id);if(!url)throw new Error('ship model is unavailable');return url;},\r\n    getBackgroundUrl(id){assertOwned();const url=backgrounds.get(id);if(!url)throw new Error('biome plate is unavailable');return url;},\r\n    ownedShipIds(){assertOwned();return [...canUseShip()].filter(id=>ships.has(id));},\r\n    dispose,\r\n  };\r\n  return Object.freeze(api);\r\n}\r\n\r\n/** Read-only: resolves to a ready ship/background asset bridge only if this account's owned ship\r\n * section is already downloaded and verified on this device. Never fetches chunk bytes — a\r\n * missing/partial pack always resolves to null, so opening the ship view can never start the 60MB\r\n * download on its own. */\r\nexport async function localVerifiedBridge() {\r\n const account = globalThis.myr5AuthenticatedAccount, owner = account?.user?.id;\r\n if (!owner || !ownedShipIds().length) return null;\r\n const assertOwner = () => { if (globalThis.myr5AuthenticatedAccount?.user?.id !== owner) throw new DOMException('Ship owner changed', 'AbortError'); };\r\n const trust = productionMaterialTrust(); if (!trust) return null;\r\n const resolved = await resolvePostDownloadSection('coach-ships-biomes', { trust });\r\n assertOwner();\r\n const downloader = new ChunkDownloader({ store: indexedDbChunkStore(), policy: DEFAULT_LOCAL_RESOURCE_POLICY, expectedVersion: resolved.manifest.version, manifestPublicKey: resolved.trust, ownership: async () => { assertOwner(); return owner; } });\r\n await downloader.verifyStored(resolved.manifest); // local store reads + hash checks only, no network\r\n assertOwner();\r\n return createVerifiedShipAssetBridge({ downloader, manifest: resolved.manifest, isOwned: id => id === 'coach-ships-biomes' && globalThis.myr5AuthenticatedAccount?.user?.id === owner, canUseShip: () => { assertOwner(); return ownedShipIds(); } });\r\n}\r\n","modules/vault/quest-progress.mjs":"// Narrow progress bridge for skill-based Vault quests. Game/workout events carry\r\n// the owner captured when the run began; account changes invalidate late callbacks.\r\nimport { EXERCISES } from '../../exercise-library.mjs';\r\nimport { performanceOwner } from '../../performance-progress.mjs';\r\nimport { HOLD_CAP_SECONDS, REP_CAP } from '../../progression-rules.mjs';\r\nimport { powerProgress, retainedPowerStyle } from '../../arcade/power/power.mjs';\r\nimport { holdStyleForExercise } from '../../arcade/workout-effects-state.mjs';\r\nimport { bump, read as readVaultState } from './vault-store.mjs';\r\n\r\nconst LIMITS = Object.freeze({\r\n  'pyramid-level': [1, 20, true], 'pyramid-complete': [1, 1, true],\r\n  'fruit-streak': [3, 64, true], 'aura-tier': [1, 6, true],\r\n  'blizzard-tier': [1, 6, true], 'fire-tier': [1, 6, true],\r\n  'lightning-tier': [1, 6, true], 'yoga-hold-seconds': [1, 60, false],\r\n});\r\n\r\nfunction validValue(counter, value) {\r\n  const rule = LIMITS[counter];\r\n  return !!rule && Number.isFinite(value) && value >= rule[0] && value <= rule[1]\r\n    && (!rule[2] || Number.isSafeInteger(value));\r\n}\r\nlet cacheOwner = null, highWater = new Map();\r\n\r\n/** Record a bounded max metric only for the owner captured at run start. */\r\nexport function recordQuestProgress({ ownerId, counter, value } = {}) {\r\n  try {\r\n    if (typeof ownerId !== 'string' || !ownerId || ownerId !== performanceOwner()\r\n        || !validValue(counter, value)) return false;\r\n    if (cacheOwner !== ownerId) { cacheOwner = ownerId; highWater = new Map(); }\r\n    const previous = highWater.has(counter) ? highWater.get(counter)\r\n      : Number(readVaultState()?.counters?.[counter]) || 0;\r\n    if (value <= previous) { highWater.set(counter, previous); return false; }\r\n    bump(counter, value);\r\n    const persisted=Number(readVaultState()?.counters?.[counter])||0;\r\n    if(persisted>previous)highWater.set(counter,persisted);\r\n    return persisted>=value;\r\n  } catch { return false; }\r\n}\r\n\r\n/** Whether the current owner's persisted max already covers a queued event. */\r\nexport function questProgressStored(ownerId,counter,value){\r\n  try{return ownerId===performanceOwner()&&validValue(counter,value)&&(Number(readVaultState()?.counters?.[counter])||0)>=value;}catch{return false;}\r\n}\r\n\r\n/** Consume an authoritative workout-effects snapshot without changing workout flow. */\r\nexport function recordWorkoutQuestProgress(detail = {}) {\r\n  const workout = detail?.workout;\r\n  if (!workout || workout.stage !== 'working' || workout.paused === true\r\n      || typeof workout.ownerId !== 'string' || workout.ownerId !== performanceOwner()) return false;\r\n  const exercise = EXERCISES[workout.mode];\r\n  if (!exercise || workout.kind !== exercise.kind) return false;\r\n  if (workout.kind === 'reps' && (!Number.isFinite(workout.workingReps)\r\n      || workout.workingReps < 0 || workout.workingReps > REP_CAP)) return false;\r\n  if (workout.kind === 'hold' && (!Number.isFinite(workout.activeSeconds)\r\n      || workout.activeSeconds < 0 || workout.activeSeconds > HOLD_CAP_SECONDS)) return false;\r\n\r\n  if (workout.kind === 'hold' && exercise.group === 'yoga'\r\n      && holdStyleForExercise(exercise) === 'living') {\r\n    return recordQuestProgress({ ownerId: workout.ownerId, counter: 'yoga-hold-seconds',\r\n      value: Math.min(60, Math.floor(Number(workout.activeSeconds) || 0)) });\r\n  }\r\n\r\n  if (workout.kind === 'hold' && ['core', 'balance'].includes(exercise.group)\r\n      && retainedPowerStyle(exercise) === 'blizzard') {\r\n    const progress = powerProgress(workout);\r\n    return recordQuestProgress({ ownerId: workout.ownerId, counter: 'blizzard-tier', value: progress.tier });\r\n  }\r\n\r\n  if (workout.kind !== 'reps') return false;\r\n  const style = retainedPowerStyle(exercise), progress = powerProgress(workout);\r\n  const counter = style === 'aura' ? 'aura-tier' : style === 'floor' ? 'fire-tier'\r\n    : style === 'lightning' ? 'lightning-tier' : null;\r\n  if (!counter || progress.kind !== 'reps') return false;\r\n  return recordQuestProgress({ ownerId: workout.ownerId, counter, value: progress.tier });\r\n}\r\n","modules/vault/vault-banner.mjs":"// \"ACHIEVEMENT UNLOCKED\" banner: listens for myr5:vault-earned {ids}, shows one goal at a time at the top for 5 s, fades 0.6 s.\r\nimport {GOALS} from './vault-goals.mjs';\r\nexport const SHOW_MS=5000,FADE_MS=600;\r\n/** Queue + timing, DOM-free so tests can drive it: show(goal) / hide() are callbacks. */\r\nexport function createBanner({show,hide,done=()=>{},setTimer=setTimeout,clearTimer=clearTimeout}){\r\n const q=[];let busy=false,t=0;\r\n const next=()=>{const g=q.shift();if(!g){busy=false;return;}busy=true;show(g);t=setTimer(()=>{hide();t=setTimer(()=>{done();next();},FADE_MS);},SHOW_MS);};\r\n return {push(ids){for(const id of ids||[]){const g=GOALS.find(x=>x.id===id);if(g)q.push(g);}if(!busy)next();},\r\n  dismiss(){if(!busy)return;clearTimer(t);hide();t=setTimer(()=>{done();next();},FADE_MS);}};\r\n}\r\nconst CSS=`.vault-banner{position:fixed;inset:auto;margin:0;overflow:visible;left:50%;top:calc(env(safe-area-inset-top,0px) + 10px);z-index:2147483000;width:min(92vw,420px);box-sizing:border-box;padding:10px 14px;transform:translate(-50%,-14px);opacity:0;transition:opacity .6s ease,transform .6s ease;pointer-events:none;text-align:center;font:12px/1.35 ui-monospace,Menlo,Consolas,monospace;color:#ff9a3c;text-shadow:0 0 6px rgba(255,140,40,.7);background:linear-gradient(160deg,rgba(76,29,120,.88),rgba(36,12,64,.92));border:2px solid #e6b94c;border-radius:12px;box-shadow:0 0 18px rgba(176,96,255,.55),inset 0 0 14px rgba(230,185,76,.18);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px)}\r\n.vault-banner.on{opacity:1;transform:translate(-50%,0);pointer-events:auto}\r\n.vault-banner small{display:block;letter-spacing:.2em;font-size:10px;color:#e6b94c}\r\n.vault-banner b{display:block;font-size:17px;letter-spacing:.06em;margin:2px 0;text-transform:uppercase}\r\n.vault-banner span{display:block;opacity:.85}`;\r\nexport function mountBanner(doc=document,win=window){\r\n if(win.myr5VaultBanner)return win.myr5VaultBanner;\r\n const st=doc.createElement('style');st.textContent=CSS;doc.head.append(st);\r\n const el=doc.createElement('div');el.className='vault-banner';el.setAttribute('role','status');el.setAttribute('aria-live','polite');el.setAttribute('popover','manual');\r\n const lab=doc.createElement('small'),ti=doc.createElement('b'),de=doc.createElement('span');lab.textContent='ACHIEVEMENT UNLOCKED';el.append(lab,ti,de);doc.body.append(el);\r\n const b=createBanner({show:g=>{ti.textContent=g.title;de.textContent=g.clue;try{el.showPopover();}catch{el.style.display='block';}void el.offsetWidth;el.classList.add('on');},hide:()=>el.classList.remove('on'),done:()=>{try{el.hidePopover();}catch{el.style.display='';}}});\r\n el.addEventListener('click',()=>b.dismiss());\r\n win.addEventListener('myr5:vault-earned',e=>b.push(e.detail?.ids));\r\n return win.myr5VaultBanner=b;\r\n}\r\nif(typeof document!=='undefined'&&typeof window!=='undefined')mountBanner();\r\n","modules/vault/vault-door.mjs":"// The vault door: Ian's old painted cogs door (door.glb art + kit gear trains, valves, lights, pipes, weld trail) plus the\r\n// mechanical door's pistons, bolts, tubes, pulleys/cables/weights, lamps with halos, dial and real shadows, in MOM purple/gold.\r\n// Nothing here is tied to the eight portal shapes: any touch drives whatever mechanism is near it. Top-middle a MOM logo plate and a\r\n// purple CRT (orange text) show one goal's clue; the dial knob scrolls goals; one full turn of the MOM flywheel swings the door open.\r\n// Renders on demand only (wake/awakeUntil, no free-running RAF); shadows are on only while the loop is awake. AGPL-3.0-or-later.\r\nimport * as THREE from 'three';\r\nimport {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';\r\nimport {MeshoptDecoder} from 'three/addons/libs/meshopt_decoder.module.js';\r\nimport {orientMatrix} from '../portal/portal-board-glb.mjs';\r\nimport {applyTorque,stepTrain,gearsFromLayout,hitGear,nearestPipe,wiggleStep,wiggleKick,valveAngle,lightLevel,heatColor,beadAlpha,stepSpark,KNOBS,pistonExt} from '../portal/portal-board-cogs.mjs';\r\nimport {releaseGraphics,claimGraphics} from '../graphics-lifecycle.mjs';\r\nimport {exitHall} from './vault-hall.mjs';\r\n\r\nconst BOARD='/pod/worlds/boards/cogs/',DOOR_GLB=BOARD+'door.glb',KIT_GLB=BOARD+'parts-kit.glb',LAYOUT=BOARD+'door-layout.json',LOGO='/pod/mom-inc-engrave.png';\r\nconst TAU=Math.PI*2,PURPLE='#7a2fc4',GOLD='#ffd36e',WALL='#171020',CREAM='#f6eddf',ORANGE='#ff9a2b';\r\n// The painted art is 1024x1792; the square door shows rows Y0..Y0+1024 (lower neon \"V\", the plain gear strip, the bottom hub).\r\nconst IMG_H=1792,Y0=700,SLAB=.07,DETENT=Math.PI/6,SWING=100*Math.PI/180,SWING_MS=1300;\r\nconst vOf=v=>(v*IMG_H-Y0)/1024; // layout v (full image) -> door v (0 top .. 1 bottom, width units)\r\n// Door-plane layout (u across, v down, both in door widths).\r\nconst L={logo:{u:.5,v:.032,w:.44,h:.054},crt:{u:.5,v:.212,w:.72,h:.29,sw:.65,sh:.25},knob:{u:.5,v:.455,r:.062},fly:{u:.5,v:.718,r:.15}};\r\nconst LAMPS=[[.1,.47],[.1,.57],[.1,.67],[.9,.47],[.9,.57],[.9,.67]],PISTONS=[[.2,.455,1],[.8,.455,-1]],PULLEYS=[[.09,.11],[.91,.11]],BOLTS=[[.06,.3,1],[.06,.56,1],[.06,.86,1],[.94,.3,-1],[.94,.56,-1],[.94,.86,-1]];\r\n\r\n// --- Pure reducers (unit-tested) -----------------------------------------------------------------\r\nexport const wrapPi=a=>a-TAU*Math.round(a/TAU);\r\nexport const wrapIndex=(i,n)=>n?((i%n)+n)%n:0;\r\n// Dial: feed it the finger's angle round the knob. Returns {st,steps}: every DETENT (30 deg) of travel is one step (+ clockwise on screen).\r\nexport function knobStep(st,angle,detent=DETENT){\r\n if(st.last==null)return {st:{last:angle,acc:0,total:0},steps:0};\r\n const d=wrapPi(angle-st.last);let acc=st.acc+d;const steps=Math.trunc(acc/detent);acc-=steps*detent;\r\n return {st:{last:angle,acc,total:st.total+d},steps};\r\n}\r\n// Flywheel: signed accumulated turn, clamped to one full turn each way; progress 0..1, open at 1.\r\nexport function flyTurn(st,angle){\r\n if(st.last==null)return {last:angle,total:st.total||0,progress:Math.min(1,Math.abs(st.total||0)/TAU)};\r\n const total=Math.max(-TAU,Math.min(TAU,st.total+wrapPi(angle-st.last)));\r\n return {last:angle,total,progress:Math.abs(total)/TAU};\r\n}\r\nexport function wrapText(text,cols){\r\n const lines=[];let line='';\r\n for(const w of String(text||'').split(/\\s+/).filter(Boolean)){\r\n  if(line&&(line+' '+w).length>cols){lines.push(line);line=w;}else line=line?line+' '+w:w;\r\n }\r\n if(line)lines.push(line);return lines;\r\n}\r\n// How long a lost context may take to come back before the vault shows its failure screen.\r\nexport const RESTORE_MS=3000;\r\n// Renderer start (tuning knobs): attempts run in order after the GPU claim; a refused context waits retryMs and tries the\r\n// next, lighter one (iOS can refuse an antialiased high-DPR context while memory from a just-lost one is still freeing).\r\nexport const VAULT_GL={attempts:[{antialias:true,pixelRatio:2,shadows:true},{antialias:false,pixelRatio:1,shadows:false}],retryMs:400};\r\n// Bottom offset (px) that clears the coach dock routes.mjs moves into the open dialog, so Retry stays tappable.\r\nexport function aboveDock(gap=24){const r=document.getElementById('coachDock')?.getBoundingClientRect();return gap+(r&&r.height&&r.top<innerHeight?Math.max(0,innerHeight-r.top):0);}\r\nconst safe=(f,...a)=>{try{return f?.(...a);}catch{return undefined;}};\r\n// What the CRT shows for goal i: header, wrapped clue, footer ({earned,progress have/need}).\r\nexport function crtView(goals,i,state,cols=24){\r\n const n=goals.length;if(!n)return {head:'NO SIGNAL',lines:[],foot:'',earned:false};\r\n const g=goals[wrapIndex(i,n)],earned=!!(state?.earned?.[g.id]||safe(g.test,state));\r\n const p=safe(g.progress,state),have=p&&typeof p==='object'?p.have:null,need=p&&typeof p==='object'?p.need:null;\r\n const foot=earned?'✓ '+(g.title||g.id):have!=null&&need?have+' / '+need:typeof p==='number'?Math.round(Math.min(1,p)*100)+'%':'';\r\n return {head:'GOAL '+String(wrapIndex(i,n)+1).padStart(2,'0')+'/'+String(n).padStart(2,'0')+' · '+String(g.tier||'').toUpperCase(),lines:wrapText(g.clue,cols).slice(0,4),foot,earned,id:g.id};\r\n}\r\n\r\n// --- Textures --------------------------------------------------------------------------------------\r\nconst ctxOf=(w,h)=>{const c=document.createElement('canvas');c.width=w;c.height=h;return c.getContext('2d');};\r\nconst tex=(c,srgb=true)=>{const t=new THREE.CanvasTexture(c.canvas||c);if(srgb)t.colorSpace=THREE.SRGBColorSpace;t.anisotropy=4;return t;};\r\nconst CW_=768,CH_=312;\r\nfunction drawCrt(c,w,h,view,t=0){\r\n const g=c.createRadialGradient(w/2,h/2,10,w/2,h/2,w*.62);g.addColorStop(0,'#4a1a7a');g.addColorStop(.7,'#2a0d4a');g.addColorStop(1,'#12041f');\r\n c.fillStyle=g;c.fillRect(0,0,w,h);\r\n c.font='bold 25px ui-monospace,Menlo,Consolas,monospace';c.textBaseline='top';c.shadowColor=ORANGE;c.shadowBlur=10;c.fillStyle=ORANGE;\r\n c.globalAlpha=.75;c.fillText(view.head,30,14);c.globalAlpha=1;\r\n c.font='bold 44px ui-monospace,Menlo,Consolas,monospace';\r\n view.lines.forEach((s,i)=>c.fillText(s,30,50+i*52));\r\n c.font='bold 30px ui-monospace,Menlo,Consolas,monospace';c.fillStyle=view.earned?'#ffd36e':ORANGE;c.shadowColor=c.fillStyle;\r\n c.fillText(view.foot,30,h-46);c.shadowBlur=0;\r\n c.fillStyle='rgba(0,0,0,.28)';for(let y=(t|0)%4;y<h;y+=4)c.fillRect(0,y,w,1.6);\r\n const v=c.createRadialGradient(w/2,h/2,h*.35,w/2,h/2,w*.62);v.addColorStop(0,'rgba(0,0,0,0)');v.addColorStop(1,'rgba(0,0,0,.7)');c.fillStyle=v;c.fillRect(0,0,w,h);\r\n}\r\nfunction doorwayTexture(){\r\n // dark gunmetal wall, gold trim, faint purple glow, one small USB-A port (~8% of the door width) in the centre\r\n const c=ctxOf(512,512);c.fillStyle='#1d1f29';c.fillRect(0,0,512,512);\r\n c.strokeStyle='#0c0d13';c.lineWidth=3;for(let i=0;i<=512;i+=128){c.beginPath();c.moveTo(i,0);c.lineTo(i,512);c.moveTo(0,i);c.lineTo(512,i);c.stroke();}\r\n c.strokeStyle=GOLD;c.globalAlpha=.7;c.lineWidth=3;c.strokeRect(14,14,484,484);c.globalAlpha=1;\r\n c.fillStyle=GOLD;for(const [x,y] of [[30,30],[482,30],[30,482],[482,482]]){c.beginPath();c.arc(x,y,5,0,TAU);c.fill();}\r\n const g=c.createRadialGradient(256,256,4,256,256,230);g.addColorStop(0,'rgba(154,75,224,.55)');g.addColorStop(1,'rgba(122,47,196,0)');c.fillStyle=g;c.fillRect(0,0,512,512);\r\n c.fillStyle='rgba(255,154,43,.95)';c.font='bold 17px ui-monospace,Menlo,Consolas,monospace';c.textAlign='center';c.fillText('TAP THE PORT',256,318);\r\n c.fillStyle='#ffd36e';c.fillRect(230,242,52,28);c.fillStyle='#07040f';c.fillRect(234,246,44,20);\r\n const p=c.createLinearGradient(0,246,0,266);p.addColorStop(0,'#d9a8ff');p.addColorStop(1,'#7a2fc4');c.fillStyle=p;c.shadowColor='#b66cff';c.shadowBlur=16;c.fillRect(236,248,40,16);c.shadowBlur=0;\r\n c.fillStyle='#07040f';c.fillRect(240,254,32,5);\r\n return tex(c);\r\n}\r\nlet envTex=null;\r\nfunction studioEnv(){\r\n if(envTex)return envTex;\r\n const c=ctxOf(128,64),g=c.createLinearGradient(0,0,0,64);g.addColorStop(0,'#f4f0fa');g.addColorStop(.42,'#8a8498');g.addColorStop(.55,'#2b2535');g.addColorStop(1,'#08070b');\r\n c.fillStyle=g;c.fillRect(0,0,128,64);c.fillStyle='#fff';[[18,8,10,22],[80,4,22,9],[46,10,16,14],[104,14,8,18]].forEach(r=>c.fillRect(...r));\r\n envTex=tex(c);envTex.mapping=THREE.EquirectangularReflectionMapping;return envTex;\r\n}\r\n// MOM logo (white-on-clear PNG) as an engraved decal: dark cut with a gold lip, or plain gold.\r\nasync function logoTexture(engrave,signal){\r\n const img=await new Promise((res,rej)=>{const i=new Image();i.onload=()=>res(i);i.onerror=rej;i.src=LOGO;}).catch(()=>null);\r\n if(signal?.aborted){const error=new Error('Vault mount canceled');error.name='AbortError';throw error;}\r\n const w=512,h=Math.round(w*(img?img.height/img.width:72/363)),c=ctxOf(w,h),pass=(dx,dy,col,a)=>{\r\n  const t=ctxOf(w,h);if(img)t.drawImage(img,8,8,w-16,h-16);t.globalCompositeOperation='source-in';t.fillStyle=col;t.fillRect(0,0,w,h);\r\n  c.globalAlpha=a;c.drawImage(t.canvas,dx,dy);c.globalAlpha=1;\r\n };\r\n if(engrave){pass(3,3,'#ffd36e',.55);pass(-1.5,-1.5,'#05020a',.95);pass(0,0,'#1a1022',.9);}else{pass(2,2,'#05020a',.8);pass(0,0,GOLD,1);}\r\n const t=tex(c);return {t,aspect:h/w};\r\n}\r\n\r\n// --- Kit helpers (copied from the cogs door: not exported there) ---------------------------------\r\nfunction kitMesh(gltf,name){\r\n gltf.scene.updateMatrixWorld(true);let src=null;(name?gltf.scene.getObjectByName(name):gltf.scene)?.traverse(o=>{if(o.isMesh&&!src)src=o;});\r\n if(!src)throw Error('no mesh '+name);return src;\r\n}\r\nfunction fitModel(src,radius){\r\n const box=new THREE.Box3().setFromObject(src),rot=new THREE.Matrix4(),R=orientMatrix(box.getSize(new THREE.Vector3()));\r\n rot.set(...R[0],0,...R[1],0,...R[2],0,0,0,0,1);box.applyMatrix4(rot);\r\n const size=box.getSize(new THREE.Vector3()),k=radius/(Math.max(size.x,size.y)/2),c=box.getCenter(new THREE.Vector3());\r\n const m=new THREE.Mesh(src.geometry,src.material);m.frustumCulled=false;m.matrixAutoUpdate=false;\r\n m.matrix.makeScale(k,k,k).multiply(new THREE.Matrix4().makeTranslation(-c.x,-c.y,-c.z)).multiply(rot).multiply(src.matrixWorld);\r\n return {m,depth:size.z*k};\r\n}\r\nconst loads=new Map(),load=u=>{let p=loads.get(u);if(!p){p=new GLTFLoader().setMeshoptDecoder(MeshoptDecoder).loadAsync(u).catch(e=>{loads.delete(u);throw e;});loads.set(u,p);}return p;};\r\nconst metal=(color,m=.85,r=.38)=>new THREE.MeshStandardMaterial({color,metalness:m,roughness:r,envMap:studioEnv(),envMapIntensity:1.1});\r\n\r\n// Is (u,v) free of the CRT stack, dial, flywheel, pistons, lamps and pulley strips? r = the part's own radius.\r\nexport function blocked(u,v,r=0){\r\n const d=(a,b)=>Math.hypot(u-a,v-b),box=(b,pad)=>Math.abs(u-b.u)<b.w/2+pad&&Math.abs(v-b.v)<b.h/2+pad;\r\n return box(L.logo,r)||box(L.crt,r)||d(L.knob.u,L.knob.v)<L.knob.r*1.5+r||d(L.fly.u,L.fly.v)<L.fly.r*1.12+r\r\n  ||PISTONS.some(([pu,pv])=>Math.abs(u-pu)<.13+r&&Math.abs(v-pv)<.04+r)||LAMPS.some(([lu,lv])=>d(lu,lv)<.04+r)\r\n  ||PULLEYS.some(([pu])=>Math.abs(u-pu)<.04+r&&v<.42)||BOLTS.some(([bu,bv])=>Math.abs(u-bu)<.1+r&&Math.abs(v-bv)<.025+r)||u<.065&&v>.07&&v<.93||u>.935&&v>.07&&v<.93;\r\n}\r\n\r\n// --- The scene -----------------------------------------------------------------------------------------\r\n// host: element to fill. goals/read: the vault contract. onEnter(api): the doorway was tapped. Resolves to the door api.\r\nexport async function mountVaultDoor(host,{goals=[],read=()=>({}),onEnter,onOpen,onFatal,signal}={}){\r\n let renderer=null,glAttempt=VAULT_GL.attempts[0],releaseClaim=null,scene=null,ro=null,canvas=null,frame=0,cleaned=false,stage='renderer',onContextLost=null,onContextRestored=null,loseExt=null,lost=false,parked=false,lostTimer=0,hallSession=false,abortListener=null,S=null;\r\n let firstFrameSettled=false,resolveFirstFrame,rejectFirstFrame;\r\n const firstFrame=new Promise((resolve,reject)=>{resolveFirstFrame=resolve;rejectFirstFrame=reject;});\r\n firstFrame.catch(()=>{});\r\n const ownedTextures=new Set(),sharedGeometry=new Set(),cleanupCallbacks=new Set();\r\n const cleanup=()=>{\r\n  if(cleaned)return;cleaned=true;cancelAnimationFrame(frame);ro?.disconnect();if(onContextLost)canvas?.removeEventListener('webglcontextlost',onContextLost);if(abortListener)signal?.removeEventListener('abort',abortListener);\r\n  if(S)S.alive=false;for(const f of cleanupCallbacks)try{f();}catch{}cleanupCallbacks.clear();\r\n  if(hallSession){hallSession=false;try{exitHall();}catch{}}\r\n  if(scene)scene.traverse(o=>{try{if(o.geometry&&!sharedGeometry.has(o.geometry))o.geometry.dispose();}catch{}for(const m of [].concat(o.material||[]))try{m?.dispose?.();}catch{}});\r\n  for(const t of ownedTextures)try{t.dispose();}catch{}ownedTextures.clear();\r\n  if(renderer){\r\n   const ownedRenderer=renderer,ownedCanvas=canvas;renderer=null;\r\n   void releaseGraphics(ownedCanvas,ownedRenderer.getContext?.(),()=>{try{ownedRenderer.dispose();}catch{}try{ownedRenderer.forceContextLoss();}catch{}});\r\n  }canvas?.remove();releaseClaim?.();releaseClaim=null;\r\n };\r\n let rejectAbort;const abortPromise=new Promise((_,reject)=>{rejectAbort=reject;});abortPromise.catch(()=>{});\r\n abortListener=()=>{const error=new Error('Vault mount canceled');error.name='AbortError';if(!firstFrameSettled){firstFrameSettled=true;rejectFirstFrame(error);}cleanup();rejectAbort(error);};\r\n const waitForMount=promise=>signal?Promise.race([promise,abortPromise]):promise;\r\n try{\r\n if(signal?.aborted)abortListener();else signal?.addEventListener('abort',abortListener,{once:true});\r\n if(signal?.aborted)throw new Error('Vault mount canceled');\r\n // Every other app renderer (3D coach, portal board/tunnel/peek) gives its context back first; they rebuild when the Vault closes.\r\n stage='graphics-release';releaseClaim=claimGraphics('vault');await waitForMount(releaseClaim.ready);if(signal?.aborted)throw new Error('Vault mount canceled');\r\n stage='renderer';\r\n for(let i=0;!renderer;i++){\r\n  glAttempt=VAULT_GL.attempts[i];\r\n  try{renderer=new THREE.WebGLRenderer({antialias:glAttempt.antialias,alpha:false,powerPreference:'low-power'});}\r\n  catch(error){if(i>=VAULT_GL.attempts.length-1)throw error;console.warn('Vault renderer refused; trying lighter settings.',error);await waitForMount(new Promise(r=>setTimeout(r,VAULT_GL.retryMs)));if(signal?.aborted)throw new Error('Vault mount canceled');}\r\n }\r\n renderer.setPixelRatio(Math.min(devicePixelRatio||1,glAttempt.pixelRatio));renderer.outputColorSpace=THREE.SRGBColorSpace;renderer.setClearColor(WALL);\r\n renderer.shadowMap.enabled=glAttempt.shadows;renderer.shadowMap.type=THREE.PCFShadowMap;\r\n loseExt=renderer.getContext().getExtension('WEBGL_lose_context');\r\n canvas=renderer.domElement;canvas.style.cssText='display:block;width:100%;height:100%;touch-action:none';canvas.setAttribute('aria-label','Vault door');\r\n stage='scene';scene=new THREE.Scene();const camera=new THREE.PerspectiveCamera(32,1,.1,40),root=new THREE.Group();scene.add(root);\r\n scene.add(new THREE.HemisphereLight('#d9c8ff','#241532',1.1));\r\n const sun=new THREE.DirectionalLight('#fff0d8',2.6);sun.position.set(-.9,1.4,3);sun.castShadow=true;sun.shadow.normalBias=.01;sun.shadow.bias=-.0005;\r\n const small=Math.min(host.clientWidth||400,host.clientHeight||400)<500;sun.shadow.mapSize.set(small?512:1024,small?512:1024);\r\n Object.assign(sun.shadow.camera,{left:-.9,right:.9,top:.9,bottom:-.9,near:.5,far:7});scene.add(sun,sun.target);\r\n const face=new THREE.Group(),pivot=new THREE.Group();pivot.position.set(-.5,0,0);face.position.set(.5,0,0);pivot.add(face);root.add(pivot);\r\n const at=(u,v,z=0)=>new THREE.Vector3(u-.5,.5-v,z),wallMat=metal('#2a1d3c',.5,.6);\r\n const mk=(geo,mat,parent,p,shadow=true)=>{const m=new THREE.Mesh(geo,mat);if(p)m.position.copy(p);m.castShadow=shadow;m.receiveShadow=true;parent.add(m);return m;};\r\n // wall + casing + doorway (static)\r\n// the vault wall: a gunmetal space-hull bulkhead that fills the frame (1 world unit = 320 px; canvas centre = world origin)\r\n stage='wall-texture';const wallTex=(()=>{const W=1024,H=2176,c=ctxOf(W,H),X=x=>W/2+x*320,Y=y=>H/2-y*320,g=c.createLinearGradient(0,0,0,H);g.addColorStop(0,'#2a2c38');g.addColorStop(.5,'#23252f');g.addColorStop(1,'#1a1b24');c.fillStyle=g;c.fillRect(0,0,W,H);\r\n  for(let i=0;i<9000;i++){c.fillStyle=Math.random()>.5?'rgba(255,255,255,.025)':'rgba(0,0,0,.05)';c.fillRect(Math.random()*W,Math.random()*H,2+Math.random()*10,1);}\r\n  const seam=(x0,y0,x1,y1)=>{c.strokeStyle='#0b0b11';c.lineWidth=4;c.beginPath();c.moveTo(x0,y0);c.lineTo(x1,y1);c.stroke();c.strokeStyle='rgba(255,255,255,.1)';c.lineWidth=1.5;c.beginPath();c.moveTo(x0+3,y0+3);c.lineTo(x1+3,y1+3);c.stroke();\r\n   const n=Math.hypot(x1-x0,y1-y0)/56|0;for(let k=1;k<n;k++){const x=x0+(x1-x0)*k/n,y=y0+(y1-y0)*k/n+(y1===y0?10:0),r=c.createRadialGradient(x-1,y-1,0,x,y,4);r.addColorStop(0,'#9fa2b5');r.addColorStop(1,'#444656');c.fillStyle=r;c.beginPath();c.arc(x,y,3.6,0,TAU);c.fill();}};\r\n  for(let y=-8;y<=8;y++)seam(0,Y(y*.85),W,Y(y*.85));\r\n  for(let y=-8;y<8;y++)for(let x=-4;x<=4;x++)seam(X(x*.8+(y&1?.4:0)),Y(y*.85),X(x*.8+(y&1?.4:0)),Y((y+1)*.85));\r\n  const gold=(y,w)=>{c.fillStyle=GOLD;c.globalAlpha=.85;c.fillRect(0,Y(y),W,w);c.fillRect(0,Y(y)+w+7,W,w*.4);c.globalAlpha=1;};gold(1.13,6);gold(-1.1,6);\r\n  const star=(cx,cy,r)=>{const g2=c.createRadialGradient(cx,cy,0,cx,cy,r);g2.addColorStop(0,'#241040');g2.addColorStop(.6,'#0c0618');g2.addColorStop(1,'#04020a');c.save();c.beginPath();c.arc(cx,cy,r,0,TAU);c.clip();c.fillStyle=g2;c.fillRect(cx-r,cy-r,2*r,2*r);\r\n   for(let i=0;i<46;i++){const q=Math.random();c.fillStyle=q>.9?GOLD:q>.7?'#d9b8ff':'#fff';c.globalAlpha=.3+Math.random()*.7;c.fillRect(cx+(Math.random()*2-1)*r,cy+(Math.random()*2-1)*r,1.6,1.6);}c.globalAlpha=1;c.restore();\r\n   c.strokeStyle=GOLD;c.lineWidth=7;c.beginPath();c.arc(cx,cy,r+3,0,TAU);c.stroke();c.strokeStyle='#0b0b11';c.lineWidth=5;c.beginPath();c.arc(cx,cy,r+10,0,TAU);c.stroke();\r\n   for(let k=0;k<12;k++){const a=k*TAU/12;c.fillStyle='#8e91a6';c.beginPath();c.arc(cx+Math.cos(a)*(r+19),cy+Math.sin(a)*(r+19),3.4,0,TAU);c.fill();}};\r\n  star(X(-.3),Y(.88),42);star(X(.3),Y(.88),42);star(X(-.3),Y(-.91),42);star(X(.3),Y(-.91),42);\r\n  const led=(x,y,col)=>{c.shadowColor=col;c.shadowBlur=14;c.fillStyle=col;c.beginPath();c.arc(x,y,5,0,TAU);c.fill();c.shadowBlur=0;};\r\n  [-.12,-.04,.04,.12].forEach((x,i)=>led(X(x),Y(.88),i%3===2?GOLD:'#b66cff'));\r\n  [-.12,-.04,.04,.12].forEach((x,i)=>led(X(x),Y(-.91),i%3===1?GOLD:'#b66cff'));\r\n  c.fillStyle='rgba(255,211,110,.8)';c.font='bold 22px ui-monospace,Menlo,Consolas,monospace';c.textAlign='center';c.fillText('M.O.M. INC. · VAULT 01',W/2,Y(-1.19));\r\n  c.fillStyle='#ffd36e';\r\n  return tex(c);})();ownedTextures.add(wallTex);\r\n const wall=new THREE.Mesh(new THREE.PlaneGeometry(3.2,6.8),new THREE.MeshBasicMaterial({map:wallTex,toneMapped:false}));wall.position.z=-.22;root.add(wall);\r\n const cas=metal('#3a3c4a',.9,.38),jamb=metal('#15131c',.7,.5),CW=1.34,HOLE=1.02;\r\n [[0,(CW+HOLE)/4,CW,(CW-HOLE)/2],[0,-(CW+HOLE)/4,CW,(CW-HOLE)/2]].forEach(([x,y,w,h])=>mk(new THREE.BoxGeometry(w,h,.24),cas,root,new THREE.Vector3(x,y,-.1)));\r\n [[-(CW+HOLE)/4,0],[(CW+HOLE)/4,0]].forEach(([x,y])=>mk(new THREE.BoxGeometry((CW-HOLE)/2,HOLE,.24),cas,root,new THREE.Vector3(x,y,-.1)));\r\n for(const [x,y,w,h] of [[0,.5,HOLE,.02],[0,-.5,HOLE,.02],[-.5,0,.02,HOLE],[.5,0,.02,HOLE]])mk(new THREE.BoxGeometry(w,h,.2),jamb,root,new THREE.Vector3(x,y,-.12),false);\r\n for(const sx of [-1,1])for(const sy of [-1,1])mk(new THREE.CylinderGeometry(.022,.022,.03,8).rotateX(Math.PI/2),metal(GOLD,.9,.3),root,new THREE.Vector3(sx*.6,sy*.6,.025));\r\n stage='doorway-texture';const screenTex=doorwayTexture();ownedTextures.add(screenTex);const screenMat=new THREE.MeshBasicMaterial({map:screenTex,toneMapped:false}),doorway=new THREE.Mesh(new THREE.PlaneGeometry(HOLE,HOLE),screenMat);doorway.position.z=-.2;root.add(doorway);\r\n // the door slab: Ian's painted art, cropped square, duotoned to MOM purple/gold\r\n stage='door-art';const doorGltf=await waitForMount(load(DOOR_GLB).catch(()=>null)),art=doorGltf?.scene.getObjectByProperty('isMesh',true)?.material.map?.clone();if(art)ownedTextures.add(art);\r\n const side=metal('#2c2e3a',.9,.4),back=metal('#4a4d5e',.9,.35);\r\n const front=new THREE.MeshStandardMaterial({color:'#fff',metalness:.35,roughness:.55,envMap:studioEnv(),envMapIntensity:.7,map:art||null});\r\n if(art){art.repeat.set(1,-1024/IMG_H);art.offset.set(0,(Y0+1024)/IMG_H);art.wrapS=art.wrapT=THREE.ClampToEdgeWrapping;art.needsUpdate=true;}\r\n front.onBeforeCompile=sh=>{sh.fragmentShader=sh.fragmentShader.replace('#include <map_fragment>','#include <map_fragment>\\n{float l=clamp(dot(diffuseColor.rgb,vec3(.2126,.7152,.0722))*1.9,0.,1.);vec3 w=vec3(.05,.052,.075),p=vec3(.5,.2,.85),g=vec3(1.,.83,.43);vec3 d=l<.5?mix(w,p,l*2.):mix(p,g,(l-.5)*2.);diffuseColor.rgb=mix(diffuseColor.rgb*vec3(.4,.4,.5),d*1.25,.85);}');};\r\n front.customProgramCacheKey=()=>'vault-duotone';\r\n const slab=new THREE.Mesh(new THREE.BoxGeometry(1,1,SLAB),[side,side,side,side,front,back]);slab.position.z=-SLAB/2;slab.castShadow=slab.receiveShadow=true;face.add(slab);\r\n const trimMat=metal(GOLD,.9,.32);for(const [x,y,w,h] of [[0,.49,1,.02],[0,-.49,1,.02],[-.49,0,.02,1],[.49,0,.02,1]])mk(new THREE.BoxGeometry(w,h,.016),trimMat,face,new THREE.Vector3(x,y,.006),false);\r\n const hit=new THREE.Mesh(new THREE.PlaneGeometry(1,1),new THREE.MeshBasicMaterial({visible:false}));face.add(hit);\r\n // state\r\n S={goals,read,idx:0,total:0,progress:0,open:0,opening:false,target:0,flySpin:0,phase:0,pomega:0,drag:new Map(),weld:[],sparks:[],heads:new Map(),glitch:0,alive:true,knob:{last:null,acc:0,total:0},fly:{last:null,total:0}};\r\n const parts={gears:[],pipes:[],valves:[],lights:[],lamps:[],bolts:[],pistons:[],weights:[],pulleys:[],spin:[]},rest=[];\r\n // kit parts from the old door layout, cropped to the square, kept clear of the new controls\r\n stage='door-kit';const [layout,kit]=await waitForMount(Promise.all([fetch(LAYOUT).then(r=>{if(!r.ok)throw new Error('layout HTTP '+r.status);return r.json();}),load(KIT_GLB)]).catch(e=>{if(e?.name==='AbortError')throw e;console.warn('vault door kit',e);return [null,null];}));kit?.scene?.traverse(o=>{if(o.geometry)sharedGeometry.add(o.geometry);});\r\n const mats=new Map(),matFor=(src,kind)=>{const k=src.material.uuid+kind;let m=mats.get(k);if(!m){m=src.material.clone();m.envMap=studioEnv();m.envMapIntensity=1.1;m.metalness=.9;m.roughness=.34;m.map=src.material.map;\r\n  m.color.set(kind==='plate'?'#8a8da2':kind==='pipe'?'#c9a8ff':kind==='light'?'#ffffff':'#ffd9a0');if(kind==='pipe'){m.emissive.set(PURPLE);m.emissiveMap=m.map;m.emissiveIntensity=.9;}if(kind==='light'){m.emissive.set(GOLD);m.emissiveMap=m.map;m.emissiveIntensity=0;}mats.set(k,m);}return m;};\r\n let topZ=.03;\r\n if(layout&&kit){\r\n  const list=[],keep=new Map(),cyc={},pick=k=>{const a=layout.parts.filter(p=>p.kind===k);cyc[k]=((cyc[k]??-1)+1)%a.length;return a[cyc[k]];};\r\n  // trains: the old lower-left cluster squeezed (positions and radii together, so teeth still mesh) into the bottom strip, mirrored to the right\r\n  const SC=.71,xf=(p,m)=>({...p,u:m?1-(.075+(p.u-.04)*SC):.075+(p.u-.04)*SC,v:.76+(vOf(p.v)-.7307)*SC,r:p.r*SC,rot:m?-(p.rot||0):p.rot});\r\n  for(const m of [0,1])layout.parts.slice(0,16).forEach((p,i)=>{const q=xf(p,m);if(blocked(q.u,q.v,q.r*.8))return;keep.set(m*100+i,list.length);list.push({...q,drives:p.drives!=null?m*100+p.drives:undefined});});\r\n  list.forEach(q=>{q.drives=q.drives!=null?keep.get(q.drives):undefined;});\r\n  // tidy mounted fittings on a symmetric grid in the free panels beside the dial and flywheel, a light row, and screws\r\n  const slot=(kind,u,v,r,rot)=>{const p=pick(kind);list.push({node:p.node,kind,u,v,r:Math.min(p.r,r),rot,layer:list.length%9+1});};\r\n  for(const u of [.24,.76])for(const v of [.52,.67])slot('pipe',u,v,.06,0);\r\n  for(const u of [.24,.76])slot('valve',u,.595,.035,0);\r\n  for(const u of [.17,.83])for(const v of [.52,.67])slot('screw',u,v,.014,0);\r\n  for(const [u,v] of [[.12,.032],[.2,.032],[.8,.032],[.88,.032],[.47,.968],[.53,.968]])slot('light',u,v,.015,0);\r\n  parts.gears=gearsFromLayout(list);\r\n  let gi=0;\r\n  list.forEach((p,i)=>{\r\n   let src;try{src=kitMesh(kit,p.node);}catch{if(p.kind==='gear')gi++;return;}\r\n   const {m,depth}=fitModel(src,p.r),g=new THREE.Group();m.material=matFor(src,p.kind);m.castShadow=m.receiveShadow=true;g.add(m);\r\n   const z=.002+(p.layer||0)*.0035+depth/2;g.position.set(p.u-.5,.5-p.v,z);g.rotation.z=(p.rot||0)*Math.PI/180;face.add(g);topZ=Math.max(topZ,z+depth/2);\r\n   const part={...p,g,rot:g.rotation.z,angle:0,omega:0,z0:z,mat:m.material,level:0,nearUntil:-Infinity,phase:i*2.3,dir:i%2?1:-1};\r\n   if(p.kind==='gear')parts.gears[gi++].g=g;else if(p.kind==='pipe')parts.pipes.push(part);else if(p.kind==='valve')parts.valves.push(part);else if(p.kind==='light'){m.material=m.material.clone();part.mat=m.material;parts.lights.push(part);}\r\n  });\r\n  // the flywheel: the kit's twenty-spoke cog, big, over the painted bottom hub, MOM logo on its boss\r\n  try{\r\n   const src=kitMesh(kit,'m19'),{m,depth}=fitModel(src,L.fly.r),g=new THREE.Group();m.material=matFor(src,'gear');m.castShadow=m.receiveShadow=true;g.add(m);\r\n   g.position.copy(at(L.fly.u,L.fly.v,.03+depth/2));face.add(g);S.flyG=g;\r\n   const boss=mk(new THREE.CylinderGeometry(.062,.062,.02,28).rotateX(Math.PI/2),metal('#2a1d3c',.8,.4),g,new THREE.Vector3(0,0,depth/2+.006));\r\n   S.bossLogo=boss;\r\n  }catch(e){console.warn('flywheel',e);}\r\n }\r\n if(!S.flyG){const g=new THREE.Group();g.position.copy(at(L.fly.u,L.fly.v,.05));g.add(new THREE.Mesh(new THREE.TorusGeometry(L.fly.r,.02,8,36),metal(GOLD,.9,.3)));face.add(g);S.flyG=g;S.bossLogo=mk(new THREE.CylinderGeometry(.062,.062,.02,28).rotateX(Math.PI/2),metal('#2a1d3c',.8,.4),g,new THREE.Vector3(0,0,.01));}\r\n const mount=new THREE.Group();face.add(mount);S.mount=mount;\r\n stage='door-markings';const [engr,gold]=await waitForMount(Promise.all([logoTexture(true,signal),logoTexture(false,signal)]));ownedTextures.add(engr.t);ownedTextures.add(gold.t);\r\n // logo plate (engraved) + CRT bezel/screen\r\n const plate=mk(new THREE.BoxGeometry(L.logo.w,L.logo.h,.02),metal('#2b1f3a',.75,.45),face,at(L.logo.u,L.logo.v,.012));\r\n const decal=new THREE.Mesh(new THREE.PlaneGeometry(L.logo.w*.9,L.logo.w*.9*engr.aspect),new THREE.MeshBasicMaterial({map:engr.t,transparent:true,depthWrite:false,toneMapped:false}));decal.position.copy(at(L.logo.u,L.logo.v,.024));face.add(decal);\r\n const bossDecal=new THREE.Mesh(new THREE.PlaneGeometry(.1,.1*gold.aspect),new THREE.MeshBasicMaterial({map:gold.t,transparent:true,depthWrite:false,toneMapped:false}));bossDecal.position.z=.0125;S.bossLogo.add(bossDecal);bossDecal.rotation.x=0;\r\n // CylinderGeometry rotated about X: its cap faces +z; the decal sits on it\r\n mk(new THREE.BoxGeometry(L.crt.w,L.crt.h,.05),metal('#1b1226',.7,.5),face,at(L.crt.u,L.crt.v,.02));\r\n const cc=ctxOf(CW_,CH_),crtTex=tex(cc),sg=new THREE.PlaneGeometry(L.crt.sw,L.crt.sh,18,10),uv=sg.attributes.uv;ownedTextures.add(crtTex);\r\n for(let i=0;i<uv.count;i++){const x=uv.getX(i)-.5,y=uv.getY(i)-.5,k=1+.12*(x*x+y*y);uv.setXY(i,.5+x*k,.5+y*k);}\r\n const crt=new THREE.Mesh(sg,new THREE.MeshBasicMaterial({map:crtTex,toneMapped:false}));crt.position.copy(at(L.crt.u,L.crt.v,.047));face.add(crt);\r\n const drawView=()=>{S.view=crtView(S.goals,S.idx,S.read());drawCrt(cc,CW_,CH_,S.view,performance.now()/60|0);crtTex.needsUpdate=true;};\r\n // dial knob with 12 static tick marks\r\n const knob=new THREE.Group();knob.position.copy(at(L.knob.u,L.knob.v,.03));face.add(knob);S.knobG=knob;\r\n mk(new THREE.CylinderGeometry(L.knob.r,L.knob.r*1.06,.05,24).rotateX(Math.PI/2),metal('#d8b25a',.95,.28),knob,new THREE.Vector3(0,0,.03));\r\n mk(new THREE.BoxGeometry(.012,L.knob.r*.8,.012),metal('#1a1022',.4,.6),knob,new THREE.Vector3(0,L.knob.r*.5,.058),false);\r\n for(let k=0;k<12;k++){const a=k*Math.PI/6;mk(new THREE.BoxGeometry(.008,.02,.008),metal(GOLD,.9,.3),face,at(L.knob.u+Math.sin(a)*L.knob.r*1.4,L.knob.v-Math.cos(a)*L.knob.r*1.4,.03),false).rotation.z=-a;}\r\n // pistons (body + rod), bolts (latch bars), tubes, pulleys + cables + weights, lamps + halos\r\n const bodyGeo=new THREE.CylinderGeometry(1,1,1,12).rotateZ(Math.PI/2),pm=metal('#ffd36e',.95,.28),rod=metal('#e8e2f0',.95,.2);\r\n for(const [u,v,s] of PISTONS){const body=mk(bodyGeo,pm,face,at(u,v,.03));body.scale.set(.1,.022,.022);const r=mk(bodyGeo,rod,face,at(u,v,.03));r.scale.set(.06,.009,.009);parts.pistons.push({r,u,s,base:u+s*.08});}\r\n for(const [u,v,s] of BOLTS){const b=mk(new THREE.BoxGeometry(.14,.03,.02),metal('#8b7fa0',.9,.3),face,at(u-s*.02,v,.026));parts.bolts.push({b,u:u-s*.02,s});}\r\n for(const u of [.035,.965])mk(new THREE.CylinderGeometry(.011,.011,.84,10),metal(PURPLE,.7,.35),face,at(u,.5,.022));\r\n for(const [u,v] of PULLEYS){const p=mk(new THREE.TorusGeometry(.04,.012,8,24),pm,face,at(u,v,.03));parts.pulleys.push(p);mk(new THREE.CylinderGeometry(.012,.012,.02,8).rotateX(Math.PI/2),pm,face,at(u,v,.03),false);\r\n  const c=mk(new THREE.BoxGeometry(.005,1,.005),metal('#3a2a50',.5,.6),face,at(u,v+.2,.026),false),w=mk(new THREE.BoxGeometry(.05,.05,.04),pm,face,at(u,v+.3,.03));parts.weights.push({c,w,u,v});}\r\n const halo=(()=>{const c=ctxOf(64,64),g=c.createRadialGradient(32,32,0,32,32,32);g.addColorStop(0,'rgba(255,255,255,1)');g.addColorStop(.3,'rgba(255,255,255,.4)');g.addColorStop(1,'rgba(255,255,255,0)');c.fillStyle=g;c.fillRect(0,0,64,64);return tex(c);})();ownedTextures.add(halo);\r\n LAMPS.forEach(([u,v],i)=>{\r\n  mk(new THREE.TorusGeometry(.027,.007,6,16),metal(GOLD,.9,.3),face,at(u,v,.036),false);\r\n  const core=new THREE.Mesh(new THREE.SphereGeometry(.02,12,8),new THREE.MeshBasicMaterial({color:'#2a1d12',toneMapped:false}));core.position.copy(at(u,v,.04));face.add(core);\r\n  const h=new THREE.Mesh(new THREE.PlaneGeometry(.2,.2),new THREE.MeshBasicMaterial({map:halo,color:GOLD,blending:THREE.AdditiveBlending,transparent:true,depthWrite:false,toneMapped:false,opacity:0}));h.position.copy(at(u,v,.05));h.renderOrder=20;face.add(h);\r\n  parts.lamps.push({core,h,u,v,level:0,nearUntil:-Infinity,phase:i*2.3,station:i,n:LAMPS.length});\r\n });\r\n // weld trail layers (on the door, so they swing with it): bead (normal) and glow (additive) on the door plane\r\n const layer=(add,z)=>{const c=ctxOf(512,512),t=tex(c),m=new THREE.Mesh(new THREE.PlaneGeometry(1,1),new THREE.MeshBasicMaterial({map:t,transparent:true,depthWrite:false,toneMapped:false,blending:add?THREE.AdditiveBlending:THREE.NormalBlending}));ownedTextures.add(t);m.position.z=z;m.renderOrder=add?31:30;face.add(m);return {c,t};};\r\n const bead=layer(false,topZ+.004),glow=layer(true,topZ+.006);\r\n for(const c of [...face.children])if(c!==slab&&c!==hit&&c!==mount)mount.add(c); // everything on the front rides in one group, hidden once the door swings (edge-on bits)\r\n drawView();\r\n const ringTex=(()=>{const c=ctxOf(128,128),g=c.createRadialGradient(64,64,34,64,64,62);g.addColorStop(0,'rgba(182,108,255,0)');g.addColorStop(.55,'rgba(182,108,255,.95)');g.addColorStop(1,'rgba(122,47,196,0)');c.fillStyle=g;c.fillRect(0,0,128,128);return tex(c);})();ownedTextures.add(ringTex);\r\n const ring=new THREE.Mesh(new THREE.PlaneGeometry(.26,.26),new THREE.MeshBasicMaterial({map:ringTex,transparent:true,blending:THREE.AdditiveBlending,depthWrite:false,toneMapped:false}));ring.position.set(0,0,-.19);ring.visible=false;root.add(ring);\r\n // --- camera & layout\r\n function layout2(){\r\n  const w=Math.max(1,host.clientWidth),h=Math.max(1,host.clientHeight),aspect=w/h;renderer.setSize(w,h,false);camera.aspect=aspect;\r\n  const need=1.09,fovT=Math.tan(THREE.MathUtils.degToRad(camera.fov/2)),dist=Math.max(need/2/(fovT*aspect),1.5/2/fovT);S.base=dist;\r\n  camera.position.set(0,-.08,dist);camera.lookAt(0,-.08,0);camera.updateProjectionMatrix();S.pxPerUnit=h/(2*dist*fovT);S.scale=512/Math.max(60,S.pxPerUnit);\r\n  sun.target.position.set(0,0,0);wake();\r\n }\r\n const ray=new THREE.Raycaster(),ndc=new THREE.Vector2();\r\n const pick=(cx,cy)=>{const r=canvas.getBoundingClientRect();ndc.set((cx-r.left)/r.width*2-1,-((cy-r.top)/r.height)*2+1);ray.setFromCamera(ndc,camera);\r\n  if(S.open>.6){const h=ray.intersectObject(doorway)[0];return h&&Math.hypot(h.uv.x-.5,h.uv.y-.5)*HOLE<.14?{screen:true}:{wall:true};}\r\n  const h=ray.intersectObject(hit)[0];return h?{u:h.uv.x,v:1-h.uv.y}:{wall:true};};\r\n // --- weld (compact: hot trail + sparks on the glow layer, cooling bead on the paint layer)\r\n const spark=(u,v,n)=>{for(let i=0;i<n&&S.sparks.length<KNOBS.sparkMax;i++){const a=Math.random()*TAU,sp=(KNOBS.sparkSpeedMinPx+Math.random()*(KNOBS.sparkSpeedMaxPx-KNOBS.sparkSpeedMinPx))*S.scale;S.sparks.push({x:u*512,y:v*512,vx:Math.cos(a)*sp,vy:Math.sin(a)*sp,born:performance.now(),life:KNOBS.sparkLifeMin+Math.random()*(KNOBS.sparkLifeMax-KNOBS.sparkLifeMin),floor:Math.random()<KNOBS.sparkBounce?v*512+(30+Math.random()*80)*S.scale:Infinity});}};\r\n const weldPush=(id,u,v)=>{const prev=S.heads.get(id)||null;if(prev&&Math.hypot(u-prev.u,v-prev.v)<KNOBS.weldStep)return;const p={u,v,t:performance.now(),prev};S.weld.push(p);S.heads.set(id,p);if(S.weld.length>KNOBS.weldCap)S.weld.shift();};\r\n function weldDraw(now){\r\n  const K=KNOBS,sc=S.scale,g=glow.c,b=bead.c;g.clearRect(0,0,512,512);b.clearRect(0,0,512,512);g.lineCap=b.lineCap='round';\r\n  g.globalCompositeOperation='lighter';\r\n  for(const p of S.weld){if(!p.prev)continue;const age=now-p.t;\r\n   if(age<K.weldHotMs){const f=age/K.weldHotMs,c=heatColor(f);g.lineWidth=K.weldTrailHaloPx*sc;g.strokeStyle=`rgba(${c.r},${c.g},${c.b},${.35*(1-f)})`;g.beginPath();g.moveTo(p.prev.u*512,p.prev.v*512);g.lineTo(p.u*512,p.v*512);g.stroke();g.lineWidth=K.weldTrailWidthPx*sc;g.strokeStyle=`rgba(${c.r},${c.g},${c.b},${1-f})`;g.stroke();}\r\n   const a=beadAlpha(age);if(a>0){b.globalAlpha=a;b.lineWidth=K.weldBeadRadiusPx*2*sc;b.strokeStyle='#767880';b.beginPath();b.moveTo(p.prev.u*512,p.prev.v*512);b.lineTo(p.u*512,p.v*512);b.stroke();b.lineWidth=K.weldBeadRadiusPx*.7*sc;b.strokeStyle='#d6d8e0';b.stroke();}}\r\n  b.globalAlpha=1;\r\n  for(const s of S.sparks){const f=Math.min(1,(now-s.born)/1000/s.life),c=heatColor(f*.85);g.lineWidth=K.sparkWidthPx*sc*(1-.5*f);g.strokeStyle=`rgba(${c.r},${c.g},${c.b},${1-f*f})`;g.beginPath();g.moveTo(s.x-s.vx*K.sparkStreakS,s.y-s.vy*K.sparkStreakS);g.lineTo(s.x,s.y);g.stroke();}\r\n  for(const d of S.drag.values())if(d.weld){const R=K.torchBloomPx*sc*(.88+Math.random()*.24),x=d.u*512,y=d.v*512,gr=g.createRadialGradient(x,y,0,x,y,R);gr.addColorStop(0,'rgba(255,255,255,1)');gr.addColorStop(.25,'rgba(225,238,255,.9)');gr.addColorStop(.5,'rgba(255,160,60,.3)');gr.addColorStop(1,'rgba(255,110,30,0)');g.fillStyle=gr;g.fillRect(x-R,y-R,2*R,2*R);}\r\n  g.globalCompositeOperation='source-over';glow.t.needsUpdate=bead.t.needsUpdate=true;\r\n }\r\n // --- input\r\n const clientToUv=(e)=>pick(e.clientX,e.clientY);\r\n const angleOf=(u,v,c)=>Math.atan2(v-c.v,u-c.u);\r\n function setIdx(i){if(!S.alive)return;const n=S.goals.length;S.idx=wrapIndex(i,n);S.glitch=performance.now()+160;drawView();}\r\n function onDown(e){\r\n  const p=clientToUv(e);canvas.setPointerCapture?.(e.pointerId);\r\n  if(p.screen){S.drag.set(e.pointerId,{tap:'enter',x:e.clientX,y:e.clientY});return;}\r\n  if(p.wall){if(S.open>.6)S.drag.set(e.pointerId,{tap:'close',x:e.clientX,y:e.clientY});return;}\r\n  const d={u:p.u,v:p.v,pu:p.u,pv:p.v,t0:performance.now(),weld:false,mode:'touch',moved:false};\r\n  if(!S.opening&&S.open<.02&&Math.hypot(p.u-L.fly.u,p.v-L.fly.v)<L.fly.r*1.15){d.mode='fly';S.fly={last:null,total:S.fly.total};S.flySpin=0;S.fly=flyTurn(S.fly,angleOf(p.u,p.v,L.fly));}\r\n  else if(Math.hypot(p.u-L.knob.u,p.v-L.knob.v)<L.knob.r*1.6){d.mode='knob';S.knob={last:null,acc:0,total:S.knob.total};S.knob=knobStep(S.knob,angleOf(p.u,p.v,L.knob)).st;}\r\n  else{d.weld=true;d.gi=hitGear(parts.gears,{w:1,h:1},p.u,p.v);weldPush(e.pointerId,p.u,p.v);spark(p.u,p.v,KNOBS.sparkPressCount);}\r\n  S.drag.set(e.pointerId,d);wake();\r\n }\r\n function onMove(e){\r\n  const d=S.drag.get(e.pointerId);if(!d||d.tap)return;const p=clientToUv(e);if(p.u==null)return;\r\n  const du=p.u-d.u,dv=p.v-d.v;d.pu=d.u;d.pv=d.v;d.u=p.u;d.v=p.v;if(Math.hypot(du,dv)>.004)d.moved=true;\r\n  if(d.mode==='fly'){S.fly=flyTurn(S.fly,angleOf(p.u,p.v,L.fly));S.progress=S.fly.progress;if(S.progress>=1)openDoor();}\r\n  else if(d.mode==='knob'){const r=knobStep(S.knob,angleOf(p.u,p.v,L.knob));S.knob=r.st;if(r.steps){setIdx(S.idx+r.steps);navigator.vibrate?.(5);}}\r\n  else{\r\n   S.pomega+=Math.hypot(du,dv)*70;\r\n   // gears near the finger: tangential drag turns the whole train (scene y is up, uv y is down)\r\n   parts.gears.forEach((g,gi)=>{const dx=d.pu-g.u,dy=d.pv-g.v,r2=dx*dx+dy*dy;if(r2<(g.r*2.2)**2&&r2>1e-8)applyTorque(parts.gears,gi,-(dx*dv-dy*du)/r2*18);});\r\n   for(const pp of parts.pipes)if(Math.hypot(p.u-pp.u,p.v-pp.v)<pp.r+KNOBS.wiggleMargin)pp.omega+=wiggleKick(du,-dv,pp.rot,KNOBS.wiggleKick);\r\n   weldPush(e.pointerId,p.u,p.v);spark(p.u,p.v,Math.min(KNOBS.sparkMoveMax,Math.round(Math.hypot(du,dv)/KNOBS.sparkPerFrac)));\r\n  }\r\n  wake();\r\n }\r\n function onUp(e){\r\n  const d=S.drag.get(e.pointerId);S.drag.delete(e.pointerId);if(!d)return;\r\n  if(d.tap){if(Math.hypot(e.clientX-d.x,e.clientY-d.y)<12){if(d.tap==='enter')enter();else closeDoor();}return;}\r\n  if(d.weld){if(!d.moved){if(d.gi>=0)applyTorque(parts.gears,d.gi,KNOBS.wiggleTapKick*6);else{const i=nearestPipe(parts.pipes,{w:1,h:1},d.u,d.v,KNOBS.wiggleMargin);if(i>=0)parts.pipes[i].omega+=KNOBS.wiggleTapKick;}}S.heads.delete(e.pointerId);spark(d.u,d.v,KNOBS.sparkReleaseCount);}\r\n  wake();\r\n }\r\n const detachInput=()=>{canvas.removeEventListener('pointerdown',onDown);canvas.removeEventListener('pointermove',onMove);canvas.removeEventListener('pointerup',onUp);canvas.removeEventListener('pointercancel',onUp);};\r\n canvas.addEventListener('pointerdown',onDown);canvas.addEventListener('pointermove',onMove);canvas.addEventListener('pointerup',onUp);canvas.addEventListener('pointercancel',onUp);cleanupCallbacks.add(detachInput);\r\n // --- door open / close / enter\r\n function openDoor(){if(!S.alive||S.opening||S.target)return;S.opening=true;S.target=1;S.t0=performance.now();S.from=S.open;\r\n  window.dispatchEvent(new CustomEvent('myr5:vault-door-open'));import('./vault-hall.mjs').catch(()=>{}); // warm the hall while the door swings\r\n  import('./vault-store.mjs').then(m=>m.bump?.('door-open')).catch(()=>{});onOpen?.(api);wake();}\r\n function closeDoor(){if(!S.alive)return;S.dolly=null;S.veil?.remove();S.veil=null;S.target=0;S.t0=performance.now();S.from=S.open;S.opening=false;S.fly={last:null,total:0};S.progress=0;wake();}\r\n function enter(){\r\n  if(!S.alive||S.dolly)return;S.dolly={t0:performance.now()};\r\n  const veil=document.createElement('div');veil.style.cssText='position:absolute;inset:0;background:radial-gradient(circle,#d9a8ff,#7a2fc4 55%,#2a0d4a);opacity:0;pointer-events:none';host.append(veil);S.veil=veil;wake();onEnter?.(api);\r\n }\r\n // The hall covers the whole screen, so the door parks its GPU context (released through the shared lifecycle) while the\r\n // hall runs and restores it when the hall exits: door + hall never hold two full-screen MSAA contexts at once.\r\n function hallOffline(error){\r\n  S.dolly=null;S.veil?.remove();S.veil=null;\r\n  const hall=host.querySelector('.vh');\r\n  if(hall){const canvas=hall.querySelector('canvas');for(const kind of ['webgl2','webgl'])try{canvas?.getContext(kind)?.getExtension('WEBGL_lose_context')?.loseContext();}catch{}hall.remove();}\r\n  S.view={head:'HALL OFFLINE',lines:['YOUR SECRETS ARE SAFE.','RETRY THE 3D HALL.'],foot:'',earned:false};drawCrt(cc,CW_,CH_,S.view,0);crtTex.needsUpdate=true;\r\n  hallRetry?.remove();hallRetry=document.createElement('button');hallRetry.type='button';hallRetry.textContent='Retry 3D Hall';hallRetry.setAttribute('aria-label','Retry the 3D Achievement Hall');\r\n  hallRetry.style.cssText=`position:absolute;left:50%;bottom:${aboveDock()}px;z-index:4;transform:translateX(-50%);padding:12px 20px;border:1px solid #d4a4ff;border-radius:999px;background:#251334;color:#fff;font:600 16px system-ui`;\r\n  hallRetry.onclick=()=>{hallRetry?.remove();hallRetry=null;enter();};host.append(hallRetry);\r\n  console.error('Achievement Hall renderer failed; retry is available.',error);unpark();\r\n }\r\n function unpark(){\r\n  if(!parked)return;parked=false;\r\n  if(lost){try{loseExt?.restoreContext();}catch{}armRestoreTimeout();}else wake();\r\n }\r\n const onHallExit=e=>{\r\n  if(!S.alive||!hallSession)return;hallSession=false;\r\n  if(e.detail?.error){hallOffline(e.detail.error);return;}\r\n  S.dolly=null;S.veil?.remove();S.veil=null;unpark(); // back at the open door, not a purple veil over a parked renderer\r\n };\r\n window.addEventListener('myr5:vault-hall-exit',onHallExit);cleanupCallbacks.add(()=>window.removeEventListener('myr5:vault-hall-exit',onHallExit));\r\n function finishDolly(){\r\n  hallSession=true;\r\n  import('./vault-hall.mjs').then(async m=>{\r\n   if(!S.alive||!host.isConnected)return null;\r\n   if(!m.enterHall)throw Error('no hall');\r\n   parked=true;cancelAnimationFrame(frame);frame=0;clearTimeout(lostTimer);reconnecting.hidden=true; // a parked door has no restore deadline\r\n   if(!lost)void releaseGraphics(canvas,renderer.getContext(),()=>loseExt?.loseContext()); // enterHall waits for this release\r\n   const hall=await m.enterHall({host,door:api,goals:S.goals,read:S.read});\r\n   if(!S.alive||!host.isConnected){hall?.exit?.();return null;}\r\n   return hall;\r\n  })\r\n   .catch(error=>{\r\n    if(!S.alive||!host.isConnected){import('./vault-hall.mjs').then(m=>m.exitHall?.()).catch(()=>{});return;}\r\n    hallSession=false;hallOffline(error);\r\n   });\r\n }\r\n // --- on-demand loop\r\n let awakeUntil=0,last=0,hallRetry=null;\r\n function wake(){awakeUntil=performance.now()+1500;if(!frame&&S.alive&&!lost&&!parked){last=performance.now();frame=requestAnimationFrame(tick);}}\r\n const reduced=matchMedia?.('(prefers-reduced-motion: reduce)');\r\n const frameFailure=error=>{\r\n  try{error.vaultStage=firstFrameSettled?'runtime-render':'first-render';}catch{}\r\n  if(!firstFrameSettled){firstFrameSettled=true;rejectFirstFrame(error);return;}\r\n  if(cleaned)return;S.alive=false;cleanup();onFatal?.(error);\r\n };\r\n // Context loss is survivable: Android drops contexts on app switches and GPU pressure and gives them back. Pause, say so\r\n // quietly, and let three.js rebuild on restore; only a context that stays gone past RESTORE_MS is a failure.\r\n const reconnecting=document.createElement('div');reconnecting.setAttribute('role','status');reconnecting.textContent='Reconnecting 3D…';reconnecting.hidden=true;\r\n reconnecting.style.cssText='position:absolute;left:50%;top:45%;transform:translateX(-50%);z-index:3;padding:10px 18px;border:1px solid #7a2fc4;border-radius:999px;background:#171020cc;color:#f6eddf;font:600 15px system-ui;pointer-events:none';\r\n const armRestoreTimeout=()=>{clearTimeout(lostTimer);reconnecting.hidden=false;lostTimer=setTimeout(()=>{if(lost)frameFailure(new Error('WebGL context lost'));},RESTORE_MS);};\r\n onContextLost=event=>{\r\n  event.preventDefault();lost=true;cancelAnimationFrame(frame);frame=0;\r\n  if(!parked)armRestoreTimeout();\r\n };\r\n onContextRestored=()=>{\r\n  lost=false;clearTimeout(lostTimer);reconnecting.hidden=true;\r\n  if(parked)return;\r\n  // three.js re-created its GL state on this event; canvas-backed textures re-upload on the next render.\r\n  crtTex.needsUpdate=glow.t.needsUpdate=bead.t.needsUpdate=true;wake();\r\n };\r\n canvas.addEventListener('webglcontextlost',onContextLost);canvas.addEventListener('webglcontextrestored',onContextRestored);\r\n cleanupCallbacks.add(()=>{clearTimeout(lostTimer);canvas.removeEventListener('webglcontextrestored',onContextRestored);reconnecting.remove();});\r\n host.append(canvas,reconnecting);\r\n function tick(now){\r\n  frame=0;if(!S.alive)return;\r\n  try{const rdt=Math.min(.5,(now-last)/1000||.016),dt=Math.min(.05,rdt);last=now;let busy=S.drag.size>0;\r\n  renderer.shadowMap.enabled=glAttempt.shadows;\r\n  // flywheel: follows the finger; unfinished turns spring back\r\n  if(!S.drag.size&&!S.opening&&S.open<.02&&Math.abs(S.fly.total)>.01){S.fly={last:null,total:S.fly.total*Math.exp(-rdt*5)};S.progress=Math.abs(S.fly.total)/TAU;busy=true;}\r\n  S.flyG.rotation.z=-S.fly.total;\r\n  // door swing (ease in-out)\r\n  if(S.open!==S.target){const k=Math.min(1,(now-S.t0)/SWING_MS),e=k*k*(3-2*k);S.open=S.from+(S.target-S.from)*e;if(k>=1){S.open=S.target;if(!S.target)S.opening=false;}busy=true;}\r\n  pivot.rotation.y=-S.open*SWING;mount.visible=S.open<.2;\r\n  if(S.open>=.99&&S.target===1){if(!S.pulseUntil)S.pulseUntil=now+6000;}else S.pulseUntil=0;\r\n  ring.visible=S.open>=.99&&!S.dolly;if(ring.visible){const k=Math.sin(now*.006);ring.scale.setScalar(1+.22*k);ring.material.opacity=.7+.3*k;if(now<S.pulseUntil)busy=true;}camera.position.set(-.2*S.open,-.08,S.base*(1+.2*S.open));camera.lookAt(-.2*S.open,-.08,0);\r\n  if(S.dolly){const k=Math.min(1,(now-S.dolly.t0)/1000),e=k*k*(3-2*k),z0=S.base*1.2;camera.position.set(-.2*S.open*(1-e),-.08*(1-e),z0+(-.1-z0)*e);camera.lookAt(0,0,-.2);if(S.veil)S.veil.style.opacity=Math.max(0,Math.min(1,(k-.55)/.4));if(k<1)busy=true;if(k>=1&&!S.dolly.done){S.dolly.done=true;finishDolly();}}\r\n  // knob follows the finger\r\n  S.knobG.rotation.z=-S.knob.total;\r\n  // train, valves, pipes, lights, lamps\r\n  const moving=stepTrain(parts.gears,dt);parts.gears.forEach(g=>{if(g.g)g.g.rotation.z=g.angle%TAU;});\r\n  let rootOmega=0;for(const g of parts.gears)if(g.drives==null&&Math.abs(g.omega)>Math.abs(rootOmega))rootOmega=g.omega;\r\n  if(Math.abs(rootOmega)>.02||S.drag.size)for(const v of parts.valves){v.angle=valveAngle(v.angle,dt,v.dir,Math.sign(rootOmega)||1,rootOmega);v.g.rotation.z=v.rot+v.angle;}\r\n  let wob=false;\r\n  for(const p of parts.pipes){const r=wiggleStep(p.angle,p.omega,dt,KNOBS.wiggleFreqHz,KNOBS.wiggleDamping,KNOBS.wiggleMaxAngle);p.angle=r.angle;p.omega=r.omega;\r\n   if(Math.abs(p.angle)<KNOBS.wiggleRestAngle&&Math.abs(p.omega)<KNOBS.wiggleRestOmega){if(p.angle){p.angle=p.omega=0;p.g.rotation.z=p.rot;p.g.position.z=p.z0;}}\r\n   else{wob=true;p.g.rotation.z=p.rot+p.angle;p.g.position.z=p.z0+Math.abs(p.angle)/KNOBS.wiggleMaxAngle*KNOBS.wiggleBob;}}\r\n  let lit=false;const near=(u,v)=>{for(const d of S.drag.values())if(d.u!=null&&Math.hypot(d.u-u,d.v-v)<KNOBS.lightRadius)return true;return false;};\r\n  for(const l of parts.lights){if(near(l.u,l.v))l.nearUntil=now+KNOBS.lightHoldMs;const t=now<l.nearUntil?1:0;l.level=lightLevel(l.level,t,dt,KNOBS.lightRampMs,KNOBS.lightFadeMs);l.mat.emissiveIntensity=KNOBS.lightOn*l.level;if(l.level!==t)lit=true;}\r\n  for(const l of parts.lamps){if(near(l.u,l.v))l.nearUntil=now+KNOBS.lightHoldMs;const t=now<l.nearUntil||S.progress>=(l.station+.5)/l.n*.999||S.open>.02?1:0;l.level=lightLevel(l.level,t,dt,KNOBS.lightRampMs,KNOBS.lightFadeMs);\r\n   const fl=!reduced?.matches&&l.level>.95?1+Math.sin(now*.02+l.phase)*KNOBS.lightFlicker:1,k=.6+.5*l.level;l.core.material.color.set('#2a1d12').lerp(new THREE.Color(GOLD),l.level*fl);l.core.scale.setScalar(k);l.h.material.opacity=l.level*.9*fl;if(l.level!==t)lit=true;}\r\n  // pistons/weights/pulleys: pumped by finger travel and flywheel turn\r\n  S.pomega*=Math.exp(-dt*2.2);S.phase+=(S.pomega+Math.abs(rootOmega)*.5)*dt;const ph=S.phase+S.fly.total*3;\r\n  for(const p of parts.pistons)p.r.position.x=(p.u-.5)+p.s*(.04+pistonExt(.05,ph));\r\n  for(const w of parts.weights){const t=.5+.5*Math.sin(ph),y=.2+.07*t;w.w.position.y=.5-(w.v+y);w.c.scale.y=y;w.c.position.y=.5-(w.v+y/2);}\r\n  for(const p of parts.pulleys)p.rotation.z=-ph;\r\n  for(const b of parts.bolts)b.b.position.x=(b.u-.5)+b.s*.07*Math.max(S.progress,Math.min(1,S.open*5));\r\n  // weld\r\n  S.scale=512/Math.max(60,S.pxPerUnit);let n=0;for(const s of S.sparks)if((now-s.born)/1000<s.life)S.sparks[n++]=stepSpark(s,dt,KNOBS.sparkGravityPx*S.scale,KNOBS.sparkBounceKeep);S.sparks.length=n;\r\n  for(const d of S.drag.values())if(d.weld&&now-(d.ls||0)>KNOBS.sparkIdleMs){d.ls=now;spark(d.u,d.v,KNOBS.sparkIdleCount);}\r\n  let k=0;while(k<S.weld.length&&now-S.weld[k].t>KNOBS.weldHotMs+KNOBS.weldBeadMs)k++;if(k)S.weld.splice(0,k);\r\n  const weldLive=S.sparks.length>0||S.weld.length>0||[...S.drag.values()].some(d=>d.weld);\r\n  if(weldLive||S.weldWas)weldDraw(now);S.weldWas=weldLive;\r\n  if(now<S.glitch){crt.position.x=(Math.random()-.5)*.006;drawCrt(cc,CW_,CH_,S.view,now/60|0);crtTex.needsUpdate=true;busy=true;}else if(crt.position.x!==at(L.crt.u,L.crt.v).x){crt.position.x=at(L.crt.u,L.crt.v).x;drawView();}\r\n  if(renderer.getContext().isContextLost())return; // the webglcontextlost event (queued) decides what happens next\r\n  renderer.render(scene,camera);if(!firstFrameSettled){firstFrameSettled=true;resolveFirstFrame();}\r\n  const go=busy||moving||wob||lit||weldLive||S.pomega>.05||now<awakeUntil;\r\n  if(go)frame=requestAnimationFrame(tick);else renderer.shadowMap.enabled=false; // asleep: the canvas keeps its last (shadowed) frame\r\n  }catch(error){frameFailure(error);}\r\n }\r\n stage='layout';ro=new ResizeObserver(layout2);ro.observe(host);layout2();stage='ready';\r\n const api={\r\n  canvas,renderer,state:S,goals:()=>S.goals,\r\n  goTo:setIdx,step:n=>setIdx(S.idx+n),openDoor,closeDoor,enter,wake,\r\n  // client position of a door-plane point (u,v in door widths): for scripted/driven tests\r\n  project(u,v,z=0){const p=new THREE.Vector3(u-.5,.5-v,z);face.localToWorld(p);pivot.updateMatrixWorld(true);p.project(camera);const r=canvas.getBoundingClientRect();return {x:r.left+(p.x+1)/2*r.width,y:r.top+(1-p.y)/2*r.height};},\r\n  projectWorld(x,y,z){const p=new THREE.Vector3(x,y,z).project(camera),r=canvas.getBoundingClientRect();return {x:r.left+(p.x+1)/2*r.width,y:r.top+(1-p.y)/2*r.height};},\r\n  info:()=>({idx:S.idx,open:S.open,progress:S.progress,shadows:renderer.shadowMap.enabled,awake:!!frame,view:S.view,kitParts:parts.gears.length+parts.pipes.length+parts.valves.length+parts.lights.length}),\r\n  dispose(){if(cleaned)return;cleanup();},\r\n };\r\n stage='first-render';await firstFrame;stage='ready';if(abortListener)signal?.removeEventListener('abort',abortListener);\r\n return api;\r\n }catch(error){cleanup();try{error.vaultStage=stage;}catch{}throw error;}\r\n}\r\n\r\n// The route entry: a modal dialog (#vaultPanel) holding the door. Returns the dialog.\r\nexport async function openVault(){\r\n let dlg=document.getElementById('vaultPanel');\r\n if(!dlg){dlg=document.createElement('dialog');dlg.id='vaultPanel';document.body.append(dlg);}\r\n dlg.style.cssText='position:fixed;inset:0;width:100%;height:100%;max-width:none;max-height:none;margin:0;padding:0;border:0;background:#171020;color:#f6eddf;overflow:hidden';\r\n dlg._vaultMountAbort?.abort();dlg._vaultMountAbort=null;dlg._vault?.dispose?.();dlg._vault=null;const generation=(dlg._vaultGeneration||0)+1;dlg._vaultGeneration=generation;\r\n const mountController=new AbortController();dlg._vaultMountAbort=mountController;\r\n dlg.replaceChildren();const host=document.createElement('div');host.style.cssText='position:absolute;inset:0';dlg.append(host);\r\n const loading=document.createElement('div');loading.setAttribute('role','status');loading.textContent='Opening the Achievement Vault…';loading.style.cssText='position:absolute;inset:0;display:grid;place-items:center;padding:24px;text-align:center;color:#f6eddf;font:600 18px/1.5 system-ui';host.append(loading);\r\n const close=document.createElement('button');close.textContent='✕';close.setAttribute('aria-label','Close vault');close.style.cssText='position:absolute;top:10px;right:10px;z-index:2;width:44px;height:44px;border-radius:22px;border:1px solid #7a2fc4;background:#171020cc;color:#ffd36e;font-size:18px';\r\n close.onclick=()=>dlg.close();dlg.append(close);\r\n if(!dlg.open)dlg.showModal?.();\r\n dlg._vaultCloseHandler&&dlg.removeEventListener('close',dlg._vaultCloseHandler);\r\n dlg._vaultCloseHandler=()=>{dlg._vaultGeneration++;mountController.abort();if(dlg._vaultMountAbort===mountController)dlg._vaultMountAbort=null;dlg._vault?.dispose?.();dlg._vault=null;};\r\n dlg.addEventListener('close',dlg._vaultCloseHandler,{once:true});\r\n const retry=document.createElement('button');retry.type='button';retry.textContent='Retry 3D';retry.hidden=true;retry.style.cssText='position:absolute;left:50%;bottom:24px;z-index:41;transform:translateX(-50%);padding:12px 20px;border:1px solid #d4a4ff;border-radius:999px;background:#251334;color:#fff;font:600 16px system-ui';\r\n retry.addEventListener('click',()=>void mount());dlg.append(retry);\r\n const showFailure=error=>{\r\n  if(!dlg.open||dlg._vaultGeneration!==generation)return;\r\n  host.replaceChildren();\r\n  const message=document.createElement('div');message.setAttribute('role','alert');message.style.cssText='position:absolute;inset:0;display:grid;place-content:center;gap:14px;padding:24px;text-align:center;color:#f6eddf;font:600 17px/1.5 system-ui';\r\n  const heading=document.createElement('strong');heading.textContent='The 3D Vault could not start.';\r\n  const detail=document.createElement('span');detail.textContent='Your earned secrets are safe. Retry when the device is ready.';\r\n  const safePart=(v,max)=>String(v||'').replace(/https?:\\/\\/\\S+/gi,'[URL]').replace(/[\\r\\n\\t]/g,' ').replace(/[^\\x20-\\x7e]/g,'?').slice(0,max);\r\n  const diagnostic=document.createElement('small');diagnostic.textContent=`${safePart(error?.vaultStage||'open-vault',48)} · ${safePart(error?.name||'Error',48)}: ${safePart(error?.message||'Unknown startup error',180)}`;\r\n  diagnostic.dataset.vaultDiagnostic='true';message.dataset.vaultErrorName=safePart(error?.name||'Error',48);message.dataset.vaultErrorStage=safePart(error?.vaultStage||'open-vault',48);message.dataset.vaultErrorMessage=safePart(error?.message||'Unknown startup error',180);\r\n  message.append(heading,detail,diagnostic);host.append(message);retry.style.bottom=aboveDock()+'px';retry.hidden=false;retry.disabled=false;retry.textContent='Retry 3D';\r\n  console.error('Achievement Vault renderer failed; retry is available.',error);\r\n };\r\n let mounting=null;\r\n const mount=()=>{\r\n  if(mounting)return mounting;\r\n  mounting=(async()=>{\r\n  retry.disabled=true;retry.textContent='Opening…';retry.hidden=true;host.replaceChildren(loading);\r\n  try{\r\n   const [{GOALS},{view}]=await Promise.all([import('./vault-goals.mjs'),import('./vault-store.mjs')]);\r\n   const api=await mountVaultDoor(host,{goals:GOALS,read:view,signal:mountController.signal,onFatal:error=>{dlg._vault=null;showFailure(error);}});\r\n   if(!dlg.open||dlg._vaultGeneration!==generation){api.dispose();return null;}\r\n   dlg._vault=api;loading.remove();return api;\r\n  }catch(error){\r\n   for(const canvas of host.querySelectorAll('canvas')){\r\n    for(const kind of ['webgl2','webgl','experimental-webgl'])try{canvas.getContext(kind)?.getExtension('WEBGL_lose_context')?.loseContext();}catch{}\r\n   }\r\n   if(!dlg.open||dlg._vaultGeneration!==generation){host.replaceChildren();return null;}\r\n   showFailure(error);\r\n   return null;\r\n  }\r\n  })().finally(()=>{mounting=null;});\r\n  return mounting;\r\n };\r\n await mount();\r\n return dlg;\r\n}\r\n","modules/vault/vault-goals.mjs":"import {COACH_REQUIREMENTS} from '../../performance-catalog.mjs';\r\n// Achievement Vault: the achievement table (hall order = array order, easy -> hard) and its tunable thresholds.\r\n// Pure. Every test(v) / progress(v) is total: an empty or missing state never throws.\r\n// v = vault-store's view of the world: {counters:{name:n}, time:{name:ms}, secrets:{board:ts}, snap:{...collection snapshot}}.\r\n//  snap (taken by vault-store from the real stores): coachesHave/coachesNeed, catsHave:{track:n earned coaches},\r\n//  texturedCoaches, coloursHave/coloursNeed, texturesHave/texturesNeed (distinct ids granted vs pool), bossSkins, vaultPacksOpened.\r\n// Clues are cryptic CRT text (L10 writes the real copy; placeholders are 'clue:<id>'); the title is revealed on earn.\r\nexport const VAULT_GOALS=Object.freeze({\r\n grimMinutes:Object.freeze([5,30,120]),timeCapMinutesPerDay:20, // addTime caps grimoire time per local day\r\n share:Object.freeze([1,25]),armieRead:Object.freeze([5,100]),armieIgnored:Object.freeze([5,100]),\r\n libraryOpen:10,djSessions:10,foodScans:10,arcadeScore:30,galaSlots:8,breathModes:2,shapes:9,\r\n pyramidLevels:Object.freeze([5,10,15]),fruitStreaks:Object.freeze([5,8,12]),powerLevels:Object.freeze([3,4,6]),\r\n effectTier:4,yogaHoldSeconds:60,\r\n});\r\n// How a counter counts (bump): 'day' = +n at most once per local day (default), 'max' = best value seen,\r\n// 'keyed' = distinct keys (one per Armie letter id, gala slot, breathing mode, portal shape).\r\nexport const COUNTER_MODES=Object.freeze({'arcade-score':'max','pyramid-level':'max','pyramid-complete':'max','fruit-streak':'max','aura-tier':'max','blizzard-tier':'max','fire-tier':'max','lightning-tier':'max','yoga-hold-seconds':'max','armie-ignored':'keyed','gala-slot':'keyed','breath-mode':'keyed','shape-opened':'keyed','library-open':'keyed'});\r\nexport const MAX_COUNTER_VALUES=Object.freeze({'pyramid-level':20,'pyramid-complete':1,'fruit-streak':64,'aura-tier':6,'blizzard-tier':6,'fire-tier':6,'lightning-tier':6,'yoga-hold-seconds':60});\r\nexport const INTEGER_MAX_COUNTERS=Object.freeze(['pyramid-level','pyramid-complete','fruit-streak','aura-tier','blizzard-tier','fire-tier','lightning-tier']);\r\nexport const SECRET_BOARDS=Object.freeze(['pond','wood','ice','quilt','grass','jelly']);\r\nexport const COACH_CATEGORIES=Object.freeze({meditation:'Meditation',yoga:'Yoga',cardio:'Cardio',quads:'Quads',glutes:'Glutes',chest:'Chest',arms:'Arms','martial-arts':'Martial arts'});\r\nconst num=x=>Number.isFinite(x)?x:0;\r\nconst count=(v,c)=>num(v?.counters?.[c]);\r\nconst CLUES={\r\n 'still-pond':\"Mother says the big one only rises for hands that stay.\",\r\n 'fire-starter':\"Rub the grain the wrong way. Apologise with one tap. Sweep up.\",\r\n 'shatter':\"Knock ten times on the cold window. It was never load-bearing.\",\r\n 'fold-twice':\"Make the bed like Mother taught you: up from the bottom, then across.\",\r\n 'little-way-home':\"He is very small and very far from his car. Plant him a road.\",\r\n 'boiling-point':\"Keep one finger in the pudding until the bones complain.\",\r\n 'grim-time-1':\"Stare at the book long enough and it starts staring back.\",\r\n 'grim-time-2':\"The book has learned your name. It is still reading.\",\r\n 'grim-time-3':\"You have spent a working day in a book with no words.\",\r\n 'history-open':\"Somewhere behind you is a ledger of every rep you lied about.\",\r\n 'scoreboard-link':\"Shake hands with a number that isn't yours.\",\r\n 'door-open':\"Spin the wheel. Not that one. The heavy one.\",\r\n 'hall-end':\"Walk past every ghost until there is no one left to judge you.\",\r\n 'vault-pack-opened':\"A box from the basement. Mother says don't shake it. Open it.\",\r\n 'ar-first':\"Invite a coach into your living room. Apologise for the mess.\",\r\n 'reminder-set':\"Ask Mother to nag you. She has been waiting for permission.\",\r\n 'reminder-kept':\"Let the nagging live for seven sunrises.\",\r\n 'pond-fish-seen':\"Ten times you sat still enough for the shadow to pass.\",\r\n 'armie-read-1':\"Somebody in uniform wrote to you. Have the decency.\",\r\n 'armie-ignored-1':\"Leave the soldiers on read. They will survive. Probably.\",\r\n 'armie-read-100':\"A hundred envelopes from the front. You opened every one.\",\r\n 'armie-ignored-100':\"A hundred envelopes in the bin. Command has noticed.\",\r\n 'dj-first':\"Make the spinning man play something.\",\r\n 'dj-10':\"Ten nights at the club where nobody dances but you.\",\r\n 'gala-first-part':\"Change one thing about the little pixel person.\",\r\n 'gala-all-slots':\"Try every coat in the tiny wardrobe. Every hat. Every blade.\",\r\n 'breath-all':\"Inhale every way Mother knows how to inhale.\",\r\n 'library-10':\"Thumb through the book of bodies. Ten pages.\",\r\n 'food-scan-10':\"Hold ten dinners up to the pyramid for judgement.\",\r\n 'shapes-all':\"Trace every door in the book. Even the rude ones.\",\r\n 'arcade-30':\"Pilot the bathtub. Shoot rocks. Earn thirty reasons.\",\r\n 'share-1':\"Tell one person outside the house about the house.\",\r\n 'share-25':\"Twenty-five days of telling people. Mother is so proud.\",\r\n 'coach-meditation':\"Earn someone who is very good at sitting.\",\r\n 'coach-yoga':\"Earn someone who can lick their own elbow.\",\r\n 'coach-cardio':\"Earn someone whose heart is always in a hurry.\",\r\n 'coach-quads':\"Earn someone with thighs like a planning dispute.\",\r\n 'coach-glutes':\"Earn someone who leads from behind.\",\r\n 'coach-chest':\"Earn someone who pushes the floor away.\",\r\n 'coach-arms':\"Earn someone who carries the groceries in one trip.\",\r\n 'coach-martial-arts':\"Earn someone who bows before they hurt you.\",\r\n 'boss-skin-first':\"Beat a boss so hard they come back in eight bits.\",\r\n 'texture-every-coach':\"Dress every alien in something with a feel to it.\",\r\n 'all-colours':\"Own every crayon in the box, even the ugly beige.\",\r\n 'all-six':\"Six books, six secrets. The wood, the water, the glass, the quilt, the grass, the goo.\",\r\n 'all-coaches':\"Collect the entire family. Mother will set extra places.\",\r\n 'unlocked-everything':\"Everyone. Every coat. Every colour. Then come find me.\"\r\n , 'pyramid-level-5':\"Five floors above the office. The paper is getting thin.\",\r\n 'pyramid-level-10':\"Ten floors into the fold. Keep your footing.\",\r\n 'pyramid-level-15':\"Fifteen levels up. The desk can see you now.\",\r\n 'pyramid-level-20':\"You landed on Mother's desk. She was expecting you.\",\r\n 'fruit-streak-5':\"Five clean cuts before the fruit can fall.\",\r\n 'fruit-streak-8':\"Eight in one rush. Keep your eyes ahead of your hand.\",\r\n 'fruit-streak-12':\"Twelve hits in a streak. The blade is keeping score.\",\r\n 'aura-level-3':\"Twelve counted reps. The aura is starting to take shape.\",\r\n 'aura-level-4':\"Sixteen counted reps. Keep the light under control.\",\r\n 'aura-level-6':\"Twenty-six counted reps. The aura has reached its top tier.\",\r\n 'blizzard-level-2':\"One active minute in a core or balance hold. The cold has noticed.\",\r\n 'blizzard-level-4':\"Seven minutes and forty-five active seconds. Ice holds its shape.\",\r\n 'fire-level-4':\"Sixteen push-ups or bridges in one set. Feel the ground heat up.\",\r\n 'lightning-level-4':\"Sixteen arm or shoulder reps in one set. Hold the charge.\",\r\n 'yoga-hold-60':\"Hold a yoga pose for sixty counted seconds. Breathe normally.\"\r\n};\r\nconst goal=(id,tier,title,test,progress)=>Object.freeze({id,tier,title,clue:CLUES[id]||'clue:'+id,test:v=>{try{return !!test(v||{});}catch{return false;}},...(progress?{progress:v=>{try{const p=progress(v||{});return {have:Math.max(0,Math.min(p.need,num(p.have))),need:p.need};}catch{return {have:0,need:1};}}}:{})});\r\nconst counter=(id,tier,title,name,need)=>goal(id,tier,title,v=>count(v,name)>=need,v=>({have:count(v,name),need}));\r\nconst minutes=(id,tier,title,mins)=>goal(id,tier,title,v=>num(v.time?.['grim-time'])>=mins*60000,v=>({have:Math.floor(num(v.time?.['grim-time'])/60000),need:mins}));\r\nconst secret=(id,title,board)=>goal(id,'rare',title,v=>!!v.secrets?.[board]);\r\nconst ratio=(id,tier,title,have,need)=>goal(id,tier,title,v=>num(v.snap?.[need])>0&&num(v.snap?.[have])>=num(v.snap?.[need]),v=>({have:num(v.snap?.[have]),need:Math.max(1,num(v.snap?.[need]))}));\r\nconst G=VAULT_GOALS;\r\nconst all=v=>[['coachesHave','coachesNeed'],['texturedCoaches','coachesNeed'],['coloursHave','coloursNeed'],['texturesHave','texturesNeed']].every(([h,n])=>num(v.snap?.[n])>0&&num(v.snap?.[h])>=num(v.snap?.[n]));\r\nconst DEFINED_GOALS=Object.freeze([\r\n counter('history-open','rare','Looked Back','history-open',1),\r\n counter('scoreboard-link','rare','Linked Up','scoreboard-link',1),\r\n counter('reminder-set','rare','Remembered','reminder-set',1),\r\n counter('ar-first','rare','Out in the World','ar-session',1),\r\n counter('dj-first','rare','First Request','dj-session',1),\r\n counter('share-1','rare','Spread the Word','share',G.share[0]),\r\n counter('gala-first-part','rare','New Look','gala-part',1),\r\n counter('door-open','rare','Door Opener','door-open',1),\r\n secret('still-pond','Still Waters','pond'),\r\n secret('shatter','Shatterproof No More','ice'),\r\n minutes('grim-time-1','rare','Grimoire Gazer',G.grimMinutes[0]),\r\n secret('fire-starter','Fire Starter','wood'),\r\n counter('armie-read-1','rare','Good Correspondent','armie-read',G.armieRead[0]),\r\n counter('breath-all','rare','Every Breath','breath-mode',G.breathModes),\r\n counter('library-10','rare','Movement Scholar','library-open',G.libraryOpen),\r\n counter('food-scan-10','rare','Plate Detective','food-scan',G.foodScans),\r\n counter('shapes-all','rare','Shape Collector','shape-opened',G.shapes),\r\n secret('fold-twice','Folded Twice','quilt'),\r\n counter('armie-ignored-1','rare','Left on Read','armie-ignored',G.armieIgnored[0]),\r\n counter('gala-all-slots','rare','Try Everything','gala-slot',G.galaSlots),\r\n secret('little-way-home','Little Way Home','grass'),\r\n counter('arcade-30','rare','Tub Pilot','arcade-score',G.arcadeScore),\r\n counter('dj-10','rare','Regular Request','dj-session',G.djSessions),\r\n counter('reminder-kept','rare','Kept It Up','reminder-kept',1),\r\n counter('pond-fish-seen','rare','Big Fish Believer','pond-fish',10),\r\n secret('boiling-point','Boiling Point','jelly'),\r\n goal('hall-end','rare','Down the Hall',v=>count(v,'hall-end')>=1),\r\n goal('vault-pack-opened','rare','Pack Rat',v=>num(v.snap?.vaultPacksOpened)>=1),\r\n minutes('grim-time-2','rare','Grimoire Regular',G.grimMinutes[1]),\r\n ...Object.entries(COACH_CATEGORIES).map(([track,label])=>goal('coach-'+track,'rare','First '+label+' Coach',v=>num(v.snap?.catsHave?.[track])>=1)),\r\n counter('pyramid-level-5','rare','Paper Climber I','pyramid-level',G.pyramidLevels[0]),\r\n counter('pyramid-level-10','rare','Paper Climber II','pyramid-level',G.pyramidLevels[1]),\r\n counter('pyramid-level-15','legendary','Paper Climber III','pyramid-level',G.pyramidLevels[2]),\r\n counter('pyramid-level-20','legendary','Desk Landing','pyramid-complete',1),\r\n ...G.fruitStreaks.map((need,index)=>counter(`fruit-streak-${need}`,index===2?'legendary':'rare',`Fruit Streak ${need}`,'fruit-streak',need)),\r\n ...G.powerLevels.map((need,index)=>counter(`aura-level-${need}`,index===2?'legendary':'rare',`Aura Tier ${need}`,'aura-tier',need)),\r\n counter('blizzard-level-2','rare','Blizzard Tier 2','blizzard-tier',2),\r\n counter('blizzard-level-4','legendary','Blizzard Tier 4','blizzard-tier',4),\r\n counter('fire-level-4','rare','Fire Tier 4','fire-tier',G.effectTier),\r\n counter('lightning-level-4','rare','Lightning Tier 4','lightning-tier',G.effectTier),\r\n counter('yoga-hold-60','rare','Living Hold','yoga-hold-seconds',G.yogaHoldSeconds),\r\n goal('boss-skin-first','rare','Pixel Perfect',v=>num(v.snap?.bossSkins)>=1),\r\n counter('share-25','rare','Town Crier','share',G.share[1]),\r\n counter('armie-read-100','rare','Pen Pal','armie-read',G.armieRead[1]),\r\n counter('armie-ignored-100','rare','Professional Ghost','armie-ignored',G.armieIgnored[1]),\r\n goal('all-six','legendary','Six Secrets',v=>SECRET_BOARDS.every(b=>!!v.secrets?.[b]),v=>({have:SECRET_BOARDS.filter(b=>v.secrets?.[b]).length,need:SECRET_BOARDS.length})),\r\n minutes('grim-time-3','legendary','Grimoire Devotee',G.grimMinutes[2]),\r\n ratio('all-coaches','legendary','Full Roster','coachesHave','coachesNeed'),\r\n ratio('texture-every-coach','legendary','Dressed to Impress','texturedCoaches','coachesNeed'),\r\n ratio('all-colours','legendary','Every Colour','coloursHave','coloursNeed'),\r\n goal('unlocked-everything','legendary','Unlocked Everything',all),\r\n]);\r\nexport const ARCHIVED_GOAL_IDS=Object.freeze(['grim-time-1','grim-time-2','grim-time-3','share-1','share-25','armie-read-1','armie-read-100','armie-ignored-1','armie-ignored-100','dj-first','dj-10','library-10']);\r\nconst ARCHIVED_SET=new Set(ARCHIVED_GOAL_IDS);\r\nexport const ARCHIVED_GOALS=Object.freeze(DEFINED_GOALS.filter(g=>ARCHIVED_SET.has(g.id)));\r\nexport const GOALS=Object.freeze(DEFINED_GOALS.filter(g=>!ARCHIVED_SET.has(g.id)));\r\nexport const goalById=id=>GOALS.find(g=>g.id===id)||ARCHIVED_GOALS.find(g=>g.id===id);\r\n/** Ids whose test passes in v and are not already earned (earned: {id:ts}). */\r\nexport const newlyEarned=(v,earned={})=>GOALS.filter(g=>!earned[g.id]&&g.test(v)).map(g=>g.id);\r\nconst RANK={easy:0,medium:1,hard:2,expert:3};\r\n/** One statue coach per goal (hall order): the HIGHEST-level coaches (difficulty, then later in the catalog = later unlock), hardest goal gets the highest. -> [{goalId,coachId}] */\r\nexport function statueCoaches(goals=GOALS){\r\n const ranked=COACH_REQUIREMENTS.map((c,i)=>[c,i]).sort((a,b)=>(RANK[a[0].difficulty]??0)-(RANK[b[0].difficulty]??0)||a[1]-b[1]).map(([c])=>c.id);\r\n const top=ranked.slice(-goals.length);\r\n return goals.map((g,i)=>({goalId:g.id,coachId:top[i+top.length-goals.length]??top[i]}));\r\n}\r\n","modules/vault/vault-hall.mjs":"// Achievement Vault atomic hall: purple screen -> shrink -> a straight hall of coach statues, one per goal\r\n// (easy -> hard). Walk/inspect feel ported from play/lilboyfriend (eased route, drag/wheel/keys/held arrows,\r\n// nearest-exhibit inspect). Lazy: loaded only by the vault door. AGPL-3.0-or-later.\r\nimport {releaseGraphics,waitForGraphicsRelease} from '../graphics-lifecycle.mjs';\r\nexport const GAP=6, ROOT='/creature/models/roster/', TOP=1.55;\r\n// One statue per goal. Coaches are chosen by unlock level, highest first, working down (only as many as there are\r\n// goals); the hall then runs low -> high so the last goal ('unlocked-everything') wears the highest-level coach.\r\nconst RANK={easy:0,medium:1,hard:2,expert:3};\r\nexport const pickCoaches=(n,reqs)=>{const top=[...reqs].sort((a,b)=>(RANK[b.difficulty]??0)-(RANK[a.difficulty]??0)).slice(0,n);return top.reverse().map(c=>c.id);};\r\nexport const coachPath=id=>ROOT+String(id).replace(/^roster\\//,'')+'.glb';\r\nexport const statueZ=i=>-GAP*(i+1),STOP=4.8; // route value at which you stand in front of statue i\r\nexport const stopAt=i=>-statueZ(i)-STOP;\r\nexport const nearestStatue=(route,n,max=1.6)=>{let b=-1,d=max;for(let i=0;i<n;i++){const e=Math.abs(stopAt(i)-route);if(e<d){b=i;d=e;}}return b;};\r\n// <=5 resident: 1 behind, current, 3 ahead.\r\nexport const residentWindow=(cur,n)=>{const o=[];for(let i=Math.max(0,cur-1);i<=Math.min(n-1,cur+3);i++)o.push(i);return o;};\r\nconst safe=(f,d)=>{try{return f()??d;}catch{return d;}};\r\nexport const isEarned=(g,state)=>!!(safe(()=>g.test(state),false)||state?.earned?.[g.id]);\r\nexport const firstUnearned=(goals,state)=>goals.findIndex(g=>!isEarned(g,state));\r\nexport function cardModel(g,state,packs=[]){\r\n const e=isEarned(g,state),at=state?.earned?.[g.id],t=at&&(at.at??at.ts??at),p=safe(()=>g.progress(state),null);\r\n return {earned:e,tier:g.tier,clue:g.clue,title:e?g.title:'???',date:e&&t&&!isNaN(new Date(t))?new Date(t).toLocaleDateString():'',\r\n  progress:!e&&p&&p.need>1?{have:Math.max(0,Math.min(p.have|0,p.need)),need:p.need}:null,\r\n  pack:e&&packs.find(id=>String(id).endsWith(':vault-'+g.id))||null};\r\n}\r\nexport function archivedCompletionRows(entries){\r\n return (Array.isArray(entries)?entries:[]).filter(entry=>entry&&entry.earned!==undefined&&entry.earned!==null&&typeof entry.title==='string')\r\n  .map(entry=>{const stamp=entry.earned&&typeof entry.earned==='object'?(entry.earned.at??entry.earned.ts):entry.earned,date=stamp!==undefined&&stamp!==null&&!isNaN(new Date(stamp))?new Date(stamp).toLocaleDateString():'';return {id:String(entry.id??''),title:entry.title,date,tier:String(entry.tier??''),packId:String(entry.packId??'')};});\r\n}\r\nexport function archivePackLabel(row,opened=false){return row?.packId?(opened?'Reward pack opened':'Reward pack earned'):'';}\r\nexport function bindArchiveDialog({dialog,openButton,closeButton,documentRef=globalThis.document}={}){\r\n let opener=null;\r\n const open=()=>{if(!dialog.hidden)return;opener=openButton;dialog.hidden=false;closeButton.focus?.();};\r\n const close=()=>{if(dialog.hidden)return;dialog.hidden=true;if(opener?.isConnected!==false)opener?.focus?.();opener=null;};\r\n const onOpen=()=>open(),onClose=()=>close(),onKey=e=>{if(dialog.hidden)return;if(e.key==='Escape'){e.preventDefault?.();e.stopImmediatePropagation?.();close();}else if(e.key==='Tab'){e.preventDefault?.();e.stopImmediatePropagation?.();closeButton.focus?.();}};\r\n openButton?.addEventListener('click',onOpen);closeButton?.addEventListener('click',onClose);documentRef?.addEventListener('keydown',onKey);\r\n return {open,close,dispose(){openButton?.removeEventListener('click',onOpen);closeButton?.removeEventListener('click',onClose);documentRef?.removeEventListener('keydown',onKey);close();}};\r\n}\r\nlet live=null;\r\n// error: the hall's context was lost and never came back; the door shows its Retry 3D Hall state.\r\nexport function exitHall(error){const l=live;live=null;if(!l)return;l.stop();window.dispatchEvent(new CustomEvent('myr5:vault-hall-exit',{detail:error instanceof Error?{error}:{}}));}\r\nconst CSS=`.vh{position:fixed;inset:0;z-index:7000;background:#08030f;overflow:hidden;touch-action:none;font:500 15px/1.4 system-ui;color:#fff4d6;user-select:none}\r\n.vh canvas{position:absolute;inset:0;width:100%;height:100%;display:block}\r\n.vh-pur{position:absolute;inset:0;background:radial-gradient(circle at 50% 50%,#b56bff,#7a2fc4 55%,#3a0f66);pointer-events:none}\r\n.vh-x{position:absolute;left:12px;top:calc(12px + env(safe-area-inset-top,0px));min-height:44px;padding:0 16px;border:2px solid #ffd36e;border-radius:22px;background:#171020cc;color:#ffd36e;font:800 14px system-ui;z-index:3}\r\n.vh-rc{position:absolute;left:50%;top:45%;transform:translateX(-50%);padding:10px 18px;border:1px solid #7a2fc4;border-radius:999px;background:#171020cc;color:#f6eddf;font:600 15px system-ui;z-index:4;pointer-events:none}.vh-rc[hidden]{display:none}\r\n.vh-pos{position:absolute;right:14px;top:calc(22px + env(safe-area-inset-top,0px));font:800 13px ui-monospace,monospace;color:#ff9c36;letter-spacing:.1em;z-index:3}\r\n.vh-arr{position:absolute;right:14px;bottom:calc(24px + env(safe-area-inset-bottom,0px));display:flex;flex-direction:column;gap:10px;z-index:3}\r\n.vh-arr button{width:56px;height:56px;border-radius:28px;border:2px solid #ffd36e;background:#171020cc;color:#ffd36e;font-size:22px;touch-action:none}\r\n.vh-card{position:absolute;left:12px;right:84px;bottom:calc(20px + env(safe-area-inset-bottom,0px));padding:14px 16px;border:2px solid #7a2fc4;border-radius:16px;background:#171020ee;box-shadow:0 0 30px #7a2fc488;z-index:3;transition:opacity .25s,transform .25s}\r\n.vh-card[hidden]{display:block;opacity:0;transform:translateY(16px);pointer-events:none}\r\n.vh-card h3{margin:2px 0 6px;font:900 19px/1.15 system-ui;color:#ffd36e}.vh-card .t{font:800 11px ui-monospace,monospace;letter-spacing:.18em;text-transform:uppercase;color:#b56bff}.vh-card .t.legendary{color:#ff9c36}\r\n.vh-card .c{font:600 16px/1.35 ui-monospace,monospace;color:#ff9c36;text-shadow:0 0 8px #ff9c3688;margin:6px 0}\r\n.vh-bar{height:10px;border-radius:5px;background:#3a2358;overflow:hidden}.vh-bar i{display:block;height:100%;background:linear-gradient(90deg,#ff9c36,#ffd36e)}.vh-card small{display:block;margin-top:4px;color:#d8c8ee}\r\n.vh-card button{margin-top:8px;min-height:44px;padding:0 18px;border:0;border-radius:12px;background:#ffd36e;color:#15101c;font:800 15px system-ui}\r\n.vh-archive-open{position:absolute;left:12px;top:calc(68px + env(safe-area-inset-top,0px));min-height:44px;padding:0 14px;border:1px solid #b56bff;border-radius:22px;background:#171020eF;color:#f2dfff;font:750 13px system-ui;z-index:3}\r\n.vh-archive[hidden]{display:none}.vh-archive:not([hidden]){position:absolute;inset:0;z-index:8;display:grid;place-items:center;padding:18px;background:#08030fdd;box-sizing:border-box}\r\n.vh-archive-panel{width:min(600px,100%);max-height:82vh;overflow:auto;padding:18px;border:2px solid #7a2fc4;border-radius:18px;background:#171020f5;box-shadow:0 0 32px #7a2fc488;box-sizing:border-box}\r\n.vh-archive-panel h2{margin:0 56px 14px 0;color:#ffd36e;font:900 22px/1.2 system-ui}.vh-archive-panel ul{list-style:none;margin:0;padding:0}.vh-archive-panel li{padding:12px 2px;border-top:1px solid #61417b}.vh-archive-panel strong{display:block;color:#fff4d6}.vh-archive-panel small{display:block;margin-top:4px;color:#d8c8ee;overflow-wrap:anywhere}.vh-archive-panel button{float:right;min-height:44px;padding:0 14px;border:1px solid #ffd36e;border-radius:12px;background:#24182f;color:#ffd36e;font:800 14px system-ui}`;\r\nconst esc=t=>String(t??'').replace(/[&<>\"]/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;'}[c]));\r\nconst HOLO_V=`uniform float uT;varying vec3 vN,vV;varying float vH,vY;\r\nfloat h1(float n){return fract(sin(n*91.7)*43758.5);}\r\nvoid main(){vec4 w=modelMatrix*vec4(position,1.);float g=step(.975,h1(floor(uT*7.)+floor(w.y*9.)))*.05;w.x+=g*(h1(floor(uT*7.))-.5)*2.;vY=w.y;vH=(w.y-.5)/${TOP.toFixed(2)};vN=normalize(normalMatrix*normal);vec4 mv=viewMatrix*w;vV=-mv.xyz;gl_Position=projectionMatrix*mv;}`;\r\nconst HOLO_F=`uniform float uT,uEarn,uBoost,uSeed;uniform vec3 uP,uPr,uO,uOr;varying vec3 vN,vV;varying float vH,vY;\r\nfloat h1(float n){return fract(sin(n*91.7)*43758.5);}\r\nvoid main(){float f=pow(1.-abs(dot(normalize(vN),normalize(vV))),2.2);\r\n float front=uEarn*1.25-.1,on=1.-smoothstep(front-.04,front+.04,vH),band=exp(-pow((vH-front)*9.,2.))*step(.001,uEarn)*step(uEarn,.999);\r\n vec3 base=mix(mix(uP,uPr,f),mix(uO,uOr,f),on);\r\n float scan=.55+.45*sin(vY*95.-uT*3.2),fine=.85+.15*sin(vY*420.+uT*9.);\r\n float fl=.88+.12*sin(uT*37.+uSeed)*step(.9,h1(floor(uT*6.)+uSeed));\r\n float a=(.2+f*.95)*scan*fine*fl*uBoost*(1.+on*1.2)+band*.9; // earned orange reads brighter than the purple locked ghost\r\n gl_FragColor=vec4(base*(1.+band*2.)*a*1.4,a);}`;\r\nconst BEAM_F=`uniform vec3 uC;uniform float uT;varying vec2 vU;void main(){float a=pow(1.-vU.y,2.2)*.05*(.8+.2*sin(vU.y*30.-uT*4.));gl_FragColor=vec4(uC,a);}`;\r\nconst BEAM_V=`varying vec2 vU;void main(){vU=uv;gl_Position=projectionMatrix*modelViewMatrix*vec4(position,1.);}`;\r\n// Inside of a fibre-optic data cable: strands along the walk direction, data packets, glyph flecks.\r\nconst CABLE_V=`varying vec2 vU;varying float vD;void main(){vU=uv;vec4 mv=modelViewMatrix*vec4(position,1.);vD=-mv.z;gl_Position=projectionMatrix*mv;}`;\r\nconst CABLE_F=`uniform float uT,uLen;varying vec2 vU;varying float vD;\r\nfloat h2(vec2 p){return fract(sin(dot(p,vec2(127.1,311.7)))*43758.5);}\r\nvoid main(){float S=64.,cx=vU.x*S,id=floor(cx),fx=fract(cx)-.5,hs=h2(vec2(id,1.));\r\n float line=(1.-smoothstep(0.,.09,abs(fx)))*step(.35,hs);float z=vU.y*uLen;\r\n float pk=(1.-smoothstep(0.,.16,fract(z*(.02+hs*.03)-uT*(.35+hs*.9)+hs*7.)))*step(.35,hs);\r\n vec3 c1=mix(vec3(.48,.18,.77),vec3(1.,.82,.43),step(.8,h2(vec2(id,2.))));\r\n vec3 col=c1*(line*.9+pk*line*3.5+(1.-smoothstep(.1,.45,abs(fx)))*.05);\r\n vec2 cell=vec2(id,floor(z*1.7));float fl=step(.975,h2(cell))*(.5+.5*sin(uT*3.+h2(cell)*40.))*(1.-smoothstep(.1,.3,abs(fx)));\r\n col+=vec3(1.,.85,.5)*fl*.6;float a=clamp(max(max(col.r,col.g),col.b),0.,1.)*(1.-smoothstep(12.,70.,vD));\r\n gl_FragColor=vec4(col,a);}`;\r\nexport async function enterHall(arg=document.body){\r\n const host=arg?.host||(arg instanceof Element?arg:document.body); // the door passes {host,door,goals,read}\r\n exitHall();\r\n const THREE=await import('three'),{GLTFLoader}=await import('three/addons/loaders/GLTFLoader.js'),{MeshoptDecoder}=await import('three/addons/libs/meshopt_decoder.module.js');\r\n const goalsMod=await import('./vault-goals.mjs'),{GOALS}=goalsMod,store=await import('./vault-store.mjs').catch(()=>({}));\r\n const rewardPacks=await import('../../reward-packs.mjs').catch(()=>null),{COACH_REQUIREMENTS}=await import('../../performance-catalog.mjs');\r\n void store.drainQuestPending?.();\r\n const N=GOALS.length,limit=stopAt(N-1)+2,state=()=>safe(()=>store.state(),{}),readArchive=()=>archivedCompletionRows(safe(()=>store.archivedCompletions?.(),[]));\r\n // L0's statueCoaches(goals) wins when present (ids or {id}); otherwise highest-unlock-level coaches, working down.\r\n const FILES=(safe(()=>goalsMod.statueCoaches(GOALS),null)||pickCoaches(N,COACH_REQUIREMENTS)).map(c=>coachPath(c.coachId||c.id||c));\r\n const el=document.createElement('div');el.className='vh';\r\n el.innerHTML=`<style>${CSS}</style><canvas></canvas><div class=\"vh-pur\"></div><button class=\"vh-x\" aria-label=\"Leave the hall\">&larr; Exit</button>${readArchive().length?'<button class=\"vh-archive-open\" type=\"button\">Past achievements</button>':''}<div class=\"vh-pos\"></div><div class=\"vh-rc\" role=\"status\" hidden>Reconnecting 3D…</div><div class=\"vh-arr\"><button data-d=\"-1\" aria-label=\"Walk forward\">&#9650;</button><button data-d=\"1\" aria-label=\"Walk back\">&#9660;</button></div><div class=\"vh-card\" hidden></div><section class=\"vh-archive\" role=\"dialog\" aria-modal=\"true\" aria-labelledby=\"vh-archive-title\" hidden><div class=\"vh-archive-panel\" tabindex=\"-1\"><button class=\"vh-archive-close\" type=\"button\" aria-label=\"Close past achievements\">Close</button><h2 id=\"vh-archive-title\">Past achievements</h2><ul></ul></div></section>`;\r\n host.append(el);const $=s=>el.querySelector(s),canvas=$('canvas'),card=$('.vh-card'),pur=$('.vh-pur'),pos=$('.vh-pos'),archiveDialog=$('.vh-archive'),archiveOpen=$('.vh-archive-open'),archiveClose=$('.vh-archive-close'),archiveList=$('.vh-archive-panel ul');\r\n const archiveBinding=archiveOpen?bindArchiveDialog({dialog:archiveDialog,openButton:archiveOpen,closeButton:archiveClose}):null;\r\n const paintArchive=()=>{const rows=readArchive();if(archiveOpen)archiveOpen.hidden=!rows.length;if(!rows.length){archiveBinding?.close();return;}archiveList.innerHTML=rows.map(row=>{const opened=row.packId&&safe(()=>rewardPacks?.openedPack(row.packId),false);const pack=archivePackLabel(row,!!opened);return `<li><strong>${esc(row.title)}</strong><small>${row.date?`Earned ${esc(row.date)}`:'Earned date unavailable'}${row.tier?` · ${esc(row.tier)}`:''}${pack?` · ${pack}`:''}</small></li>`;}).join('');};\r\n archiveOpen?.addEventListener('click',paintArchive);paintArchive();\r\n await waitForGraphicsRelease();\r\n const renderer=new THREE.WebGLRenderer({canvas,antialias:true});renderer.setPixelRatio(Math.min(devicePixelRatio||1,1.75));\r\n // Survive context loss like the door: pause, show a quiet status, resume when three.js has rebuilt; give up after 3 s.\r\n let lost=false,lostTimer=0;const rc=$('.vh-rc');\r\n const onLost=e=>{e.preventDefault();lost=true;cancelAnimationFrame(raf);raf=0;rc.hidden=false;clearTimeout(lostTimer);lostTimer=setTimeout(()=>{if(lost&&live)exitHall(Object.assign(new Error('WebGL context lost'),{vaultStage:'hall-runtime-render'}));},3000);};\r\n const onRestored=()=>{lost=false;clearTimeout(lostTimer);rc.hidden=true;vis();};\r\n canvas.addEventListener('webglcontextlost',onLost);canvas.addEventListener('webglcontextrestored',onRestored);\r\n const scene=new THREE.Scene();scene.background=new THREE.Color('#050210');\r\n const camera=new THREE.PerspectiveCamera(60,1,.1,140);\r\n const own=[],glow=(c,o=1)=>{const m=new THREE.MeshBasicMaterial({color:c,transparent:true,opacity:o,blending:THREE.AdditiveBlending,depthWrite:false});own.push(m);return m;};\r\n const uT={value:0},len=limit+34,zMid=-len/2+10;\r\n // Cable tube (transparent so stars/atoms show through the gaps), floor plate, gold cable rings.\r\n const tubeG=new THREE.CylinderGeometry(4.2,4.2,len,64,1,true),tubeM=new THREE.ShaderMaterial({uniforms:{uT,uLen:{value:len}},vertexShader:CABLE_V,fragmentShader:CABLE_F,transparent:true,side:THREE.BackSide,depthWrite:false,blending:THREE.AdditiveBlending});own.push(tubeG,tubeM);\r\n const tube=new THREE.Mesh(tubeG,tubeM);tube.rotation.x=Math.PI/2;tube.position.set(0,1.4,zMid);scene.add(tube);\r\n const fl=new THREE.MeshStandardMaterial({color:'#0c0818',metalness:.85,roughness:.35,emissive:'#1a0a33'}),floorG=new THREE.PlaneGeometry(7.2,len);own.push(fl,floorG);\r\n const floor=new THREE.Mesh(floorG,fl);floor.rotation.x=-Math.PI/2;floor.position.set(0,-.01,zMid);scene.add(floor);\r\n scene.add(new THREE.HemisphereLight('#b07cff','#120824',.5));\r\n const ringG=new THREE.TorusGeometry(4.15,.07,8,72),ringM=new THREE.MeshStandardMaterial({color:'#ffd36e',metalness:1,roughness:.3,emissive:'#7a5a10',emissiveIntensity:.6}),ringHalo=glow('#ffd36e',.18),haloG=new THREE.TorusGeometry(4.15,.3,6,72);own.push(ringG,ringM,haloG);\r\n const sun=new THREE.DirectionalLight('#ffe2b0',1.2);sun.position.set(2,5,3);scene.add(sun);\r\n for(let i=0;i<=N+4;i++){const z=-GAP*i+GAP/2,r=new THREE.Mesh(ringG,ringM),h=new THREE.Mesh(haloG,ringHalo);r.position.set(0,1.4,z);h.position.copy(r.position);scene.add(r,h);}\r\n // Space beyond the cable: stars + a few atoms (nucleus particle clusters with electron rings).\r\n const stN=500,st=new Float32Array(stN*3);for(let i=0;i<stN;i++)st.set([(Math.random()-.5)*70,(Math.random()-.5)*40+1,-Math.random()*len+10],i*3);\r\n const stG=new THREE.BufferGeometry();stG.setAttribute('position',new THREE.BufferAttribute(st,3));const stM=new THREE.PointsMaterial({color:'#e6d8ff',size:.14,transparent:true,opacity:.8,depthWrite:false});own.push(stG,stM);scene.add(new THREE.Points(stG,stM));\r\n const atoms=[],elecG=new THREE.SphereGeometry(.09,8,8),thin=new THREE.TorusGeometry(1,.012,6,72),pal=['#7a2fc4','#ff9c36','#ffd36e'],white=glow('#fff4d6');own.push(elecG,thin);\r\n for(let k=0;k<Math.ceil(limit/14)+2;k++){\r\n  const side=k%2?1:-1,g=new THREE.Group();g.position.set(side*(8+(k*37%6)),(k*53%9)-1,-k*14-3);\r\n  const pts=new Float32Array(90);for(let j=0;j<30;j++){const a=Math.random()*6.28,b=Math.acos(2*Math.random()-1),r=.5*Math.cbrt(Math.random());pts.set([r*Math.sin(b)*Math.cos(a),r*Math.sin(b)*Math.sin(a),r*Math.cos(b)],j*3);}\r\n  const pg=new THREE.BufferGeometry();pg.setAttribute('position',new THREE.BufferAttribute(pts,3));const pm=new THREE.PointsMaterial({color:pal[k%3],size:.16,transparent:true,blending:THREE.AdditiveBlending,depthWrite:false});own.push(pg,pm);g.add(new THREE.Points(pg,pm));\r\n  const rm=glow(pal[(k+1)%3],.5),rings=[];\r\n  for(let j=0;j<3;j++){const rg=new THREE.Group(),rr=1.3+j*.6,ring=new THREE.Mesh(thin,rm),e=new THREE.Mesh(elecG,white);ring.scale.setScalar(rr);rg.add(ring,e);rg.rotation.set(j*1.05,j*.7+k,0);rg.userData={e,rr,sp:.6+j*.35,ph:k+j};g.add(rg);rings.push(rg);}\r\n  scene.add(g);atoms.push({g,rings});\r\n }\r\n // Warp streaks for the entry shrink.\r\n const sN=320,sp=new Float32Array(sN*6);for(let i=0;i<sN;i++){const a=Math.random()*6.28,r=.6+Math.random()*3.4,z=-Math.random()*40;sp.set([Math.cos(a)*r,Math.sin(a)*r+1.4,z,Math.cos(a)*r,Math.sin(a)*r+1.4,z-1.5],i*6);}\r\n const sg=new THREE.BufferGeometry();sg.setAttribute('position',new THREE.BufferAttribute(sp,3));const sm=new THREE.LineBasicMaterial({color:'#ffe9c0',transparent:true,blending:THREE.AdditiveBlending,depthWrite:false});const streaks=new THREE.LineSegments(sg,sm);streaks.frustumCulled=false;scene.add(streaks);own.push(sg,sm);\r\n // USB drop: two rows of gold contact pins streak past (dashed lines along z) before the cable strands resolve.\r\n const pinP=[];for(let k=0;k<10;k++)for(const y of[.95,1.85])for(let d=0;d<14;d++){const x=(k-4.5)*.4,z=-d*4.2;pinP.push(x,y,z,x,y,z-2.6);}\r\n const pg2=new THREE.BufferGeometry();pg2.setAttribute('position',new THREE.Float32BufferAttribute(pinP,3));const pinM=new THREE.LineBasicMaterial({color:'#ffd36e',transparent:true,blending:THREE.AdditiveBlending,depthWrite:false});const pins=new THREE.LineSegments(pg2,pinM);pins.frustumCulled=false;scene.add(pins);own.push(pg2,pinM);\r\n // Hologram statues: one ShaderMaterial program (cloned per statue for its own earn state), purple locked -> orange earned.\r\n const col=h=>new THREE.Color(h),holo=new THREE.ShaderMaterial({uniforms:{uT,uEarn:{value:0},uBoost:{value:1},uSeed:{value:0},uP:{value:col('#7a2fc4')},uPr:{value:col('#b07cff')},uO:{value:col('#ff9a2e')},uOr:{value:col('#ffd08a')}},vertexShader:HOLO_V,fragmentShader:HOLO_F,transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.DoubleSide});own.push(holo);\r\n const pedG=new THREE.CylinderGeometry(.7,.85,.5,24),pedM=new THREE.MeshStandardMaterial({color:'#15101f',metalness:.9,roughness:.3}),capG=new THREE.TorusGeometry(.72,.035,6,32),capM=new THREE.MeshStandardMaterial({color:'#ffd36e',metalness:1,roughness:.25,emissive:'#8a6a18',emissiveIntensity:.8}),haloG2=new THREE.CircleGeometry(1.1,32),nextM=glow('#b07cff',.5),beamG=new THREE.CylinderGeometry(.5,.72,2.1,24,1,true);own.push(pedG,pedM,capG,capM,haloG2,beamG);\r\n const pulseM=glow('#ffd36e',.9),pulseG=new THREE.TorusGeometry(.85,.05,8,48),pulse=new THREE.Mesh(pulseG,pulseM);own.push(pulseG);pulse.rotation.x=Math.PI/2;pulse.visible=false;scene.add(pulse);\r\n const nextLight=new THREE.PointLight('#b07cff',0,8,2);scene.add(nextLight);\r\n const statues=GOALS.map((g,i)=>{const grp=new THREE.Group(),x=i%2?1.7:-1.7;grp.position.set(x,0,statueZ(i));grp.rotation.y=i%2?-.5:.5;\r\n  const ped=new THREE.Mesh(pedG,pedM);ped.position.y=.25;const cap=new THREE.Mesh(capG,capM);cap.rotation.x=Math.PI/2;cap.position.y=.5;\r\n  const halo=new THREE.Mesh(haloG2,nextM);halo.rotation.x=-Math.PI/2;halo.position.y=.02;halo.visible=false;\r\n  const mat=holo.clone();mat.uniforms={...holo.uniforms,uEarn:{value:0},uBoost:{value:1},uSeed:{value:i*3.7}};own.push(mat);\r\n  const bm=new THREE.ShaderMaterial({uniforms:{uC:{value:col('#7a2fc4')},uT},vertexShader:BEAM_V,fragmentShader:BEAM_F,transparent:true,depthWrite:false,blending:THREE.AdditiveBlending,side:THREE.DoubleSide});own.push(bm);\r\n  const beam=new THREE.Mesh(beamG,bm);beam.position.y=.5+1.05;beam.scale.y=-1;\r\n  grp.add(ped,cap,halo,beam);scene.add(grp);return {g,i,grp,halo,mat,bm,model:null,loading:0,tk:0,earned:false,anim:-1};});\r\n const loader=new GLTFLoader().setMeshoptDecoder(MeshoptDecoder);\r\n // Keep model decoding bounded on mobile while preserving the same five-statue resident window.\r\n const modelQueue=[];let activeModelLoads=0;const pumpModelLoads=()=>{while(activeModelLoads<1&&modelQueue.length){const job=modelQueue.shift();activeModelLoads++;Promise.resolve().then(job.run).catch(e=>console.warn('vault statue',e)).finally(()=>{activeModelLoads--;pumpModelLoads();});}};\r\n // Earn state: instant on load/refresh, 0.6 s sweep up the statue when newly earned while the hall is open.\r\n function setEarn(s,animate){const e=!!(s.g&&isEarned(s.g,state()));if(e===s.earned)return;s.earned=e;if(e&&animate&&s.model)s.anim=0;else{s.anim=-1;s.mat.uniforms.uEarn.value=e?1:0;}s.bm.uniforms.uC.value.set(e?'#ff9a2e':'#7a2fc4');}\r\n function freeModel(m){m.traverse(o=>{if(o.isMesh)o.geometry.dispose();});}\r\n function drop(s){if(!s.model)return;s.grp.remove(s.model);freeModel(s.model);s.model=null;}\r\n function load(s){if(s.model||s.loading)return;const tk=s.loading=++s.tk;modelQueue.push({run:async()=>{if(s.loading!==tk||!live||!want.includes(s.i)){if(s.loading===tk)s.loading=0;return;}try{const m=(await loader.loadAsync(FILES[s.i])).scene;\r\n  // Original materials are never shown: free them right away, wear the hologram.\r\n  m.traverse(o=>{if(!o.isMesh)return;for(const mm of[].concat(o.material)){for(const v of Object.values(mm))if(v?.isTexture)v.dispose();mm.dispose();}o.material=s.mat;});\r\n  if(s.loading!==tk||s.model||!live||!want.includes(s.i)){freeModel(m);return;}\r\n  const box=new THREE.Box3().setFromObject(m),sz=box.getSize(new THREE.Vector3()),k=TOP/Math.max(sz.y,.001),c=box.getCenter(new THREE.Vector3());m.scale.setScalar(k);m.position.set(-c.x*k,.5-box.min.y*k,-c.z*k);\r\n  s.model=m;s.grp.add(m);}catch(e){throw e;}finally{if(s.loading===tk)s.loading=0;}}});pumpModelLoads();}\r\n let want=[];function stream(c){want=residentWindow(c,N);statues.forEach(s=>{if(want.includes(s.i))load(s);else{s.loading=0;drop(s);}});}\r\n // Walk state (ported from lilboyfriend).\r\n let fixT=-1,route=0,target=0,vel=0,held=0,cur=-1,insp=-1,blend=0,nextI=-1,started=performance.now(),last=started,raf=0,reached=false;\r\n const clamp=(v,a,b)=>Math.max(a,Math.min(b,v)),move=d=>{target=clamp(target+d,0,limit);};\r\n const packId=g=>`reward-pack:secret:vault-${g.id}`;\r\n let rsum=null;import('../../reward-pack-ui.mjs').then(m=>{rsum=m.rewardSummary;if(insp>=0)showCard(insp);},()=>{});\r\n const showCard=i=>{const g=GOALS[i],m=cardModel(g,state(),safe(()=>rewardPacks.unopenedPacks(),[]));card.hidden=false;const got=m.earned&&safe(()=>rewardPacks.openedPack(packId(g)),null),list=got&&rsum?got.rewards.map(r=>{const q=rsum({reward:r,category:r.category});return `<div class=\"c\">${esc(q.title)} <small style=\"display:inline\">${esc(q.detail)}</small></div>`;}).join(''):'';\r\n  card.innerHTML=`<div class=\"t ${m.tier}\">secret &middot; ${m.earned?'unlocked':'locked'}${i===nextI?' &middot; next':''}</div>`+(m.earned?`<h3>${esc(m.title)}</h3>${m.date?`<small>Earned ${m.date}</small>`:''}${list||(m.pack?'<button data-pack>Open pack</button>':'')}`:`<div class=\"c\">${esc(m.clue)}</div>`+(m.progress?`<div class=\"vh-bar\"><i style=\"width:${100*m.progress.have/m.progress.need}%\"></i></div><small>${m.progress.have} / ${m.progress.need}</small>`:''));};\r\n const refresh=()=>{nextI=firstUnearned(GOALS,state());statues.forEach(s=>{setEarn(s,true);s.halo.visible=s.i===nextI;});const n=statues[nextI];pulse.visible=!!n;nextLight.intensity=n?6:0;if(n){nextLight.position.set(n.grp.position.x*.6,1.8,n.grp.position.z+1.4);pulse.position.set(n.grp.position.x,.06,n.grp.position.z);}if(insp>=0)showCard(insp);};\r\n card.addEventListener('click',async e=>{const b=e.target.closest?.('[data-pack]');if(!b||!rewardPacks)return;const g=GOALS[insp];if(!g)return;b.disabled=true;\r\n  // The holographic drop pod plays; the pack opens when the pod is tapped. Without the pod module (offline) it opens plainly.\r\n  const item=rewardPacks.packItem('secret',packId(g)),pods=await import('../../drop-pod-opening.mjs').catch(()=>null),ui=pods&&await import('../../reward-pack-ui.mjs').catch(()=>null);\r\n  if(pods&&ui){pods.playDropPod({tier:'secret',hasNext:false,onExit:()=>showCard(insp),open:async()=>{const o=await rewardPacks.openRewardPackExclusive(item);if(!o)return null;showCard(insp);return ui.unlocked(o);}});return;}\r\n  const opened=await rewardPacks.openRewardPackExclusive(item);if(!opened){b.disabled=false;b.textContent='Try again';return;}showCard(insp);});\r\n // Input: drag up/down walks, wheel, keys, held arrows, tap a statue to walk to it.\r\n let drag=null;const ray=new THREE.Raycaster(),ndc=new THREE.Vector2();\r\n canvas.addEventListener('pointerdown',e=>{drag={id:e.pointerId,y:e.clientY,x:e.clientX,moved:0};canvas.setPointerCapture(e.pointerId);});\r\n canvas.addEventListener('pointermove',e=>{if(!drag||e.pointerId!==drag.id)return;const dy=e.clientY-drag.y;drag.moved+=Math.abs(dy)+Math.abs(e.clientX-drag.x);drag.y=e.clientY;drag.x=e.clientX;move(dy*.012);});\r\n const up=e=>{if(!drag||e.pointerId!==drag.id)return;const d=drag;drag=null;if(e.type==='pointerup'&&d.moved<10)tap(e);};\r\n canvas.addEventListener('pointerup',up);canvas.addEventListener('pointercancel',up);\r\n function tap(e){const r=canvas.getBoundingClientRect();ndc.set((e.clientX-r.left)/r.width*2-1,-((e.clientY-r.top)/r.height)*2+1);ray.setFromCamera(ndc,camera);\r\n  for(const s of statues)if(s.model&&ray.intersectObject(s.grp,true).length){target=clamp(stopAt(s.i),0,limit);return;}}\r\n canvas.addEventListener('wheel',e=>{e.preventDefault();move(clamp(e.deltaY*.008,-1.5,1.5));},{passive:false});\r\n const kd=e=>{if(!archiveDialog.hidden)return;const k=e.key;if(k==='ArrowUp'||k==='w')held=-1;else if(k==='ArrowDown'||k==='s')held=1;else if(k==='Escape')exitHall();},ku=()=>{held=0;};addEventListener('keydown',kd);addEventListener('keyup',ku);\r\n for(const b of el.querySelectorAll('.vh-arr button')){const d=+b.dataset.d;b.addEventListener('pointerdown',e=>{e.preventDefault();b.setPointerCapture(e.pointerId);held=-d;});b.addEventListener('pointerup',ku);b.addEventListener('pointercancel',ku);}\r\n $('.vh-x').onclick=exitHall;\r\n window.addEventListener('myr5:vault-earned',refresh);\r\n const resize=()=>{const w=el.clientWidth||innerWidth,h=el.clientHeight||innerHeight;renderer.setSize(w,h,false);camera.aspect=w/h;camera.updateProjectionMatrix();};\r\n addEventListener('resize',resize);resize();\r\n const look=new THREE.Vector3();\r\n function frame(now){raf=0;if(!live||document.hidden||lost||renderer.getContext().isContextLost())return;const dt=Math.min(.05,(now-last)/1000);last=now;const t=fixT>=0?fixT:(now-started)/1000;uT.value=t;\r\n  // Entry: purple fades out, camera starts high + far and shrinks down into the hall with an FOV warp; streaks fade.\r\n  const e=clamp((t-.3)/2.6,0,1),ease=1-Math.pow(1-e,3),inv=1-ease;pur.style.opacity=String(1-clamp((t-.7)/1.7,0,1));\r\n  sm.opacity=Math.min(1,(1-e)*1.4);streaks.position.z=(t*40)%40;streaks.visible=e<1;pins.position.z=(t*46)%4.2*1+camera.position.z*0;pinM.opacity=Math.min(1,(1-e)*1.8);pins.visible=e<1;\r\n  if(!archiveDialog.hidden){held=0;vel=0;target=route;}else if(e>=1)move(held*dt*3);\r\n  const gap=target-route;vel+=(clamp(gap*7,-3.3,3.3)-vel)*(1-Math.exp(-dt*14));const step=Math.abs(vel*dt)<Math.abs(gap)?vel*dt:gap;route+=Math.sign(step)===Math.sign(gap)?step:0;if(Math.abs(gap)<.001)vel=0;\r\n  const near=e>=1&&Math.abs(vel)<.25?nearestStatue(route,N):-1;\r\n  if(near!==insp){insp=near;if(insp>=0)showCard(insp);else card.hidden=true;}\r\n  blend+=((insp>=0?1:0)-blend)*(1-Math.exp(-dt*6));\r\n  const c=Math.max(0,Math.round((route+STOP-GAP)/GAP));if(c!==cur){cur=c;stream(clamp(cur,0,N-1));}\r\n  pos.textContent=`${clamp(Math.floor((route+STOP+.01)/GAP),0,N)} / ${N}`;\r\n  if(!reached&&route>=limit-2.2){reached=true;window.dispatchEvent(new CustomEvent('myr5:vault-hall-end'));store.bump?.('hall-end');}\r\n  camera.fov=60+inv*60;camera.updateProjectionMatrix();\r\n  camera.position.set(0,1.55+inv*7,-route+inv*18);look.set(0,1.55-inv*6,camera.position.z-20);\r\n  if(insp>=0&&blend>.01){const s=statues[insp].grp.position;camera.position.x=s.x*.35*blend;look.lerp(new THREE.Vector3(s.x,.65,s.z),blend);}\r\n  camera.lookAt(look);\r\n  for(const s of statues){if(s.model)s.model.rotation.y=Math.sin(t*.6+s.i)*.2;\r\n   if(s.anim>=0){s.anim+=dt/.6;s.mat.uniforms.uEarn.value=Math.min(1,s.anim);if(s.anim>=1)s.anim=-1;}\r\n   s.mat.uniforms.uBoost.value=(s.earned?1:1.5)+(s.i===nextI?1+.7*Math.sin(t*3.2):0);}\r\n  for(const a of atoms){a.g.rotation.y+=dt*.15;for(const r of a.rings){const u=r.userData,p=t*u.sp+u.ph;u.e.position.set(Math.cos(p)*u.rr,Math.sin(p)*u.rr,0);}}\r\n  if(nextI>=0){nextLight.intensity=5+Math.sin(t*3)*2;nextM.opacity=.45+.25*Math.sin(t*3);const ph=(t%1.4)/1.4;pulse.scale.setScalar(1+ph*.9);pulseM.opacity=(1-ph)*.95;}\r\n  renderer.render(scene,camera);raf=requestAnimationFrame(frame);}\r\n const vis=()=>{if(!document.hidden&&live&&!raf&&!lost){last=performance.now();raf=requestAnimationFrame(frame);}};document.addEventListener('visibilitychange',vis);\r\n live={stop(){cancelAnimationFrame(raf);raf=0;clearTimeout(lostTimer);canvas.removeEventListener('webglcontextlost',onLost);canvas.removeEventListener('webglcontextrestored',onRestored);removeEventListener('resize',resize);removeEventListener('keydown',kd);removeEventListener('keyup',ku);document.removeEventListener('visibilitychange',vis);window.removeEventListener('myr5:vault-earned',refresh);\r\n  archiveBinding?.dispose();archiveOpen?.removeEventListener('click',paintArchive);statues.forEach(s=>{s.loading=0;drop(s);});own.forEach(o=>o.dispose?.());\r\n  void releaseGraphics(canvas,renderer.getContext?.(),()=>{renderer.dispose();renderer.forceContextLoss();});el.remove();delete window.myr5Hall;}};\r\n // Debug/test hooks.\r\n if(/[?&]debug/.test(location.search)||localStorage.myr5Debug)window.myr5Hall={debug:()=>({route,target,insp,cur,nextI,n:N,resident:statues.filter(s=>s.model).map(s=>s.i),earned:statues.filter(s=>s.earned).map(s=>s.i)}),go:r=>{target=clamp(r,0,limit);},jump:r=>{route=target=clamp(r,0,limit);vel=0;},skip:()=>{started-=4000;},at:x=>{fixT=x;},refresh};\r\n statues.forEach(s=>setEarn(s,false));stream(0);refresh();\r\n // Prove the scene can produce a real frame before enterHall reports success to the door.\r\n // This keeps shader/driver first-use errors inside finishDolly's existing retry path.\r\n try{frame(performance.now());}catch(error){exitHall();try{error.vaultStage='hall-first-render';}catch{}throw error;}\r\n return {exit:exitHall};\r\n}\r\n","modules/vault/vault-store.mjs":"// Achievement Vault store (owner-scoped localStorage `myr5-vault-v1/<owner>`). Every write re-evaluates the goals,\r\n// grants a vault pack per newly earned goal (unlock-ledger, idempotent) and dispatches `myr5:vault-earned {ids}`. No timers.\r\n// Counters follow vault-goals COUNTER_MODES: once per local day by default (anti-farm), 'max', or distinct keys.\r\nimport {GOALS,ARCHIVED_GOALS,VAULT_GOALS,COUNTER_MODES,MAX_COUNTER_VALUES,INTEGER_MAX_COUNTERS,SECRET_BOARDS,COACH_CATEGORIES,newlyEarned} from './vault-goals.mjs';\r\nimport {performanceOwner,localDay,unlockedCoachIds} from '../../performance-progress.mjs';\r\nimport {COACHES,COACH_REQUIREMENTS,EXCLUDED_COACH_IDS} from '../../performance-catalog.mjs';\r\nimport {colourRewardPool,textureRewardPool} from '../../battle-pass-rewards.mjs';\r\nimport * as cosmetics from '../../creature/source/creator/unlock-store.ts';\r\nimport * as ledger from '../../unlock-ledger.mjs';\r\nimport {openedPack,noteVaultPack} from '../../reward-packs.mjs';\r\nexport const VAULT_KEY='myr5-vault-v1';\r\nconst key=()=>`${VAULT_KEY}/${encodeURIComponent(performanceOwner())}`;\r\nconst obj=v=>v&&typeof v==='object'&&!Array.isArray(v)?v:{};\r\nconst empty=()=>({counters:{},days:{},keys:{},time:{},timeDay:{},secrets:{},earned:{}});\r\nexport function read(){\r\n try{const d=obj(JSON.parse(localStorage.getItem(key())||'null')),e=empty();for(const k of Object.keys(e))e[k]=obj(d[k]);return e;}catch{return empty();}\r\n}\r\nconst write=d=>{try{localStorage.setItem(key(),JSON.stringify(d));return true;}catch{return false;}};\r\nconst finite=n=>Number.isFinite(n)?n:0;\r\n/** Collection facts from the real stores, so goal tests stay pure. */\r\nexport function snapshot(){\r\n const out={coachesHave:0,coachesNeed:0,catsHave:{},texturedCoaches:0,coloursHave:0,coloursNeed:0,texturesHave:0,texturesNeed:0,bossSkins:0,vaultPacksOpened:0};\r\n try{\r\n  const obtainable=COACHES.map(c=>c.id).filter(id=>!EXCLUDED_COACH_IDS.includes(id)),mine=new Set(unlockedCoachIds());\r\n  out.coachesNeed=obtainable.length;out.coachesHave=obtainable.filter(id=>mine.has(id)).length;\r\n  for(const track of Object.keys(COACH_CATEGORIES))out.catsHave[track]=COACH_REQUIREMENTS.filter(r=>r.tracks[0]===track&&mine.has(r.id)).length;\r\n  const textures=cosmetics.ownerGrantedIds('texture'),coachOf=s=>decodeURIComponent(/^coach:([^:]*):/.exec(s)?.[1]||''),idOf=s=>s.replace(/^coach:[^:]*:/,'');\r\n  out.texturedCoaches=new Set(textures.map(coachOf).filter(id=>obtainable.includes(id))).size;\r\n  const colourIds=new Set(colourRewardPool().map(c=>c.id)),textureIds=new Set(textureRewardPool().map(t=>t.id));\r\n  out.coloursNeed=colourIds.size;out.texturesNeed=textureIds.size;\r\n  out.coloursHave=new Set([...cosmetics.ownerGrantedIds('color'),...cosmetics.ownerGrantedIds('palette')].map(idOf).filter(id=>colourIds.has(id))).size;\r\n  out.texturesHave=new Set(textures.map(idOf).filter(id=>textureIds.has(id))).size;\r\n  out.bossSkins=ledger.grantedIds('boss-skin').length;\r\n  out.vaultPacksOpened=ledger.grantedIds('reward-pack').filter(id=>id.includes(':vault-')&&openedPack(id)).length;\r\n }catch{/* a missing store leaves zeros: goals just stay locked */}\r\n return out;\r\n}\r\nexport const view=(d=read())=>({counters:d.counters,time:d.time,secrets:d.secrets,earned:d.earned,snap:snapshot()});\r\nexport const packId=g=>`reward-pack:secret:vault-${g.id}`;\r\n/** Read-only completions for goals retired from active evaluation. Existing earned timestamps and packs stay untouched. */\r\nexport function archivedCompletions(d=read()){\r\n return ARCHIVED_GOALS.filter(g=>Object.hasOwn(d.earned||{},g.id)).map(g=>({id:g.id,title:g.title,clue:g.clue,tier:g.tier,earned:d.earned[g.id],packId:packId(g)}));\r\n}\r\nfunction grant(ids,d){\r\n const now=Date.now(),done=[];\r\n for(const id of ids){if(GOALS.some(g=>g.id===id)&&!d.earned[id]){d.earned[id]=now;done.push(id);}}\r\n if(!done.length||!write(d))return [];\r\n for(const id of done){const g=GOALS.find(x=>x.id===id);noteVaultPack(packId(g),g.tier);ledger.grantUnlock('reward-pack',packId(g));}\r\n try{window.dispatchEvent(new CustomEvent('myr5:vault-earned',{detail:{ids:done}}));}catch{/* no window in node */}\r\n return done;\r\n}\r\n/** Newly earned ids after this call (also grants their packs and fires myr5:vault-earned). */\r\nexport function evaluate(d=read()){return grant(newlyEarned(view(d),d.earned),d);}\r\nexport function bump(counter,n=1,{key:k,day=localDay()}={}){\r\n const d=read(),mode=COUNTER_MODES[counter]||'day',add=Math.max(0,finite(n));\r\n if(mode==='max'){\r\n  const limit=MAX_COUNTER_VALUES[counter];\r\n  if(limit!==undefined&&(add>limit||(INTEGER_MAX_COUNTERS.includes(counter)&&!Number.isSafeInteger(add))))return evaluate(d);\r\n  d.counters[counter]=Math.max(finite(d.counters[counter]),add);\r\n }\r\n else if(mode==='keyed'){if(k==null)return evaluate(d);const keys=Array.isArray(d.keys[counter])?d.keys[counter]:[];if(!keys.includes(String(k)))keys.push(String(k));d.keys[counter]=keys;d.counters[counter]=keys.length;}\r\n else{if(d.days[counter]===day)return evaluate(d);d.days[counter]=day;d.counters[counter]=finite(d.counters[counter])+add;}\r\n write(d);return evaluate(d);\r\n}\r\n/** Visible-time counter in ms, capped per local day (VAULT_GOALS.timeCapMinutesPerDay). */\r\nexport function addTime(counter,ms,{day=localDay()}={}){\r\n const d=read(),cap=VAULT_GOALS.timeCapMinutesPerDay*60000,t=obj(d.timeDay[counter]),used=t.day===day?finite(t.ms):0,add=Math.max(0,Math.min(finite(ms),cap-used));\r\n if(add>0){d.time[counter]=finite(d.time[counter])+add;d.timeDay[counter]={day,ms:used+add};write(d);}\r\n return evaluate(d);\r\n}\r\nexport function markSecret(board){\r\n if(!SECRET_BOARDS.includes(board))return [];\r\n const d=read();if(!d.secrets[board]){d.secrets[board]=Date.now();write(d);}\r\n return evaluate(d);\r\n}\r\nexport const state=()=>view();\r\n// Raw-served files (portal, pond) cannot import this module, and the arcade/war-room pages never load it: they send `myr5:vault-bump`\r\n// {counter,n,key|ms} or queue [counter,n,key] in `myr5-vault-pending`, drained here at load.\r\nexport function drainPending(){try{const q=JSON.parse(localStorage.getItem('myr5-vault-pending')||'[]');localStorage.removeItem('myr5-vault-pending');for(const [c,n,k] of Array.isArray(q)?q:[])bump(c,n,{key:k});}catch{/* none */}}\r\n/** Retry bounded game maxima whenever the Vault hall is entered, even if this module was already cached. */\r\nexport function drainQuestPending(options={}){return import('../../arcade/quest-progress-reporter.mjs').then(({drainQueuedQuestProgress})=>drainQueuedQuestProgress(options)).catch(()=>false);}\r\nif(typeof window!=='undefined'){\r\n window.addEventListener?.('myr5:vault-bump',e=>{const {counter,n,key,ms}=e.detail||{};if(typeof counter!=='string')return;ms!=null?addTime(counter,ms):bump(counter,n,{key});});\r\n drainPending();\r\n // Game metrics may have been earned while the optional Vault module was offline.\r\n void drainQuestPending();\r\n}\r\nif(typeof window!=='undefined')window.myr5Vault={earn:id=>grant([id],read()),reset:()=>{try{localStorage.removeItem(key());}catch{/* private mode */}},state,bump,addTime,markSecret,evaluate,archivedCompletions};\r\n","movement-engine.mjs":"// MYR5 movement rules. AGPL-3.0-or-later, like the accompanying test app.\r\n// These are counting/shape heuristics, not assessments of exercise technique.\r\nimport {EXERCISES} from './exercise-library.mjs';\r\nimport {createHeadBob} from './arcade/runner/pose-input.mjs';\r\nimport {evaluateMovement,JOINTS} from './movement-rules.mjs';\r\nimport {PoseClassifier} from './pose-classifier.mjs';\r\nimport POSE_SAMPLES from './pose-samples.mjs';\r\nconst LEGACY_MOVEMENTS = {\r\n  squat: { name: 'Squats', kind: 'reps', hint: 'Keep shoulders and hips visible. Start standing tall. Feet can stay outside the picture.' },\r\n  pushup: { name: 'Push-ups', kind: 'reps', hint: 'Place the camera beside you. Start at the top with your arm visible.' },\r\n  tree: { name: 'Tree pose', kind: 'hold', hint: 'Show your shoulders, hips and knees. The hold is estimated from your upper-leg position.' },\r\n  warrior: { name: 'Warrior II', kind: 'hold', hint: 'Show your arms, hips and knees. Either direction works; feet are not tracked.' },\r\n  horse: { name: 'Horse stance', kind: 'hold', hint: 'Show your hips and knees in your comfortable wide stance. Feet are not tracked.' },\r\n  boxing: { name: 'Air boxing', kind: 'pace', hint: 'Keep shoulders, elbows and hands visible. Measures time and relative hand pace.' },\r\n  jogging: { name: 'Jogging in place', kind: 'steps', hint: 'Show both knees. Steps are estimated from alternating knee lifts. Keep the phone still.' },\r\n  jumping: { name: 'Jumping', kind: 'jumps', hint: 'Show your shoulders and hips. Jumps are estimated from body rise. Keep the phone still.' }\r\n};\r\nexport const MOVEMENTS={...LEGACY_MOVEMENTS,...EXERCISES};\r\nconst SIDES = { left: { s:11,e:13,w:15,h:23,k:25 }, right: { s:12,e:14,w:16,h:24,k:26 } };\r\n// CPU tracking can run below 6 Hz. Treat a genuine interruption differently\r\n// from a slower, continuous stream; never require seven frames in 1.1 seconds.\r\nconst MAX_FRAME_GAP=.75;\r\nconst clamp=(v,a,b)=>Math.max(a,Math.min(b,v));\r\nconst distance=(a,b)=>Math.hypot(a.x-b.x,a.y-b.y,(a.z??0)-(b.z??0));\r\nconst midpoint=(a,b)=>({x:(a.x+b.x)/2,y:(a.y+b.y)/2,z:((a.z??0)+(b.z??0))/2});\r\nexport function jointAngle(a,b,c){\r\n  const u=[a.x-b.x,a.y-b.y,(a.z??0)-(b.z??0)],v=[c.x-b.x,c.y-b.y,(c.z??0)-(b.z??0)];\r\n  const divisor=Math.hypot(...u)*Math.hypot(...v);\r\n  return divisor>1e-8?Math.acos(clamp(u.reduce((n,x,i)=>n+x*v[i],0)/divisor,-1,1))*180/Math.PI:NaN;\r\n}\r\nfunction median(a){const s=[...a].sort((a,b)=>a-b);return s[Math.floor(s.length/2)];}\r\nexport function features(raw,aspect=1,world=null){\r\n  if(!raw||raw.length<27)return null;\r\n  // Lower-leg landmarks never enter the movement rules, including legacy modes.\r\n  raw=raw.map((v,i)=>i>26?{x:0,y:0,visibility:0}:v);\r\n  while(raw.length<33)raw.push({x:0,y:0,visibility:0});\r\n  world=world?.map((v,i)=>i>26?null:v)??null;\r\n  // Normalized x and y have different scales in portrait video. Restore aspect.\r\n  // MediaPipe's web result publishes visibility, not a per-joint presence score.\r\n  const p=raw.map(v=>({x:v.x*aspect,y:v.y,z:0,visibility:Number.isFinite(v.visibility)?v.visibility:0}));\r\n  const inFrame=i=>p[i]&&Number.isFinite(p[i].x)&&Number.isFinite(p[i].y)&&raw[i].x>=-.03&&raw[i].x<=1.03&&raw[i].y>=-.03&&raw[i].y<=1.03;\r\n  const visible=ids=>ids.every(i=>inFrame(i)&&p[i].visibility>=.45);\r\n  const issues=ids=>ids.filter(i=>!visible([i])).map(i=>!inFrame(i)?`${JOINTS[i]} outside picture`:`${JOINTS[i]} unclear (${Math.round(p[i].visibility*100)}%)`);\r\n  const sides={};\r\n  for(const [name,id] of Object.entries(SIDES)){\r\n    const q=Object.fromEntries(Object.entries(id).map(([key,i])=>[key,p[i]]));\r\n    const torso=distance(q.s,q.h);\r\n    sides[name]={...q,id,torso,\r\n      core:visible([id.s,id.h])&&torso>.035,\r\n      coreQuality:Math.min(p[id.s].visibility,p[id.h].visibility),\r\n      arm:visible([id.s,id.e,id.w,id.h])&&torso>.035,\r\n      armQuality:Math.min(...[id.s,id.e,id.w,id.h].map(i=>p[i].visibility)),\r\n      elbow:jointAngle(q.s,q.e,q.w),\r\n      horizontal:Math.abs(q.s.x-q.h.x)/Math.max(torso,.035)\r\n    };\r\n  }\r\n  const torso=(sides.left.torso+sides.right.torso)/2;\r\n  const hip=midpoint(p[23],p[24]),shoulder=midpoint(p[11],p[12]);\r\n  return {p,world,visible,issues,sides,torso,hip,shoulder,\r\n    upright:(hip.y-shoulder.y)/Math.max(torso,.035)>.65,\r\n    knees:visible([11,12,23,24,25,26])&&torso>.035};\r\n}\r\n\r\nexport class MovementSession {\r\n  constructor(mode='squat',options={}){this.reset(mode,options);}\r\n  reset(mode=this.mode,options={}){\r\n    if(!MOVEMENTS[mode])throw new Error('Unknown movement');\r\n    this.mode=mode;this.duration=Number(options.duration)||0;this.count=0;this.elapsed=0;this.hold=0;this.totalHold=0;this.bestHold=0;this.active=0;this.speed=0;this.bestSpeed=0;\r\n    this.started=null;this.last=null;this.complete=false;this.eventTimes=[];this.side=null;this.calibration=[];this.base=null;this.filtered={};this.phase='ready';this.phaseSince=null;this.lastRep=-Infinity;this.dt=0;this.lastMatch=null;\r\n    this.candidate=null;this.missAt=null;this.previousMatch=false;this.hands={};this.kneeArmed={left:false,right:false};this.lastStep=-Infinity;this.bob=null;\r\n    this.message=MOVEMENTS[mode].hint;this.measurement='';this.tracking=false;this.progress=0;this.setupProgress=0;this.setupReason='';this.jointReadings='';\r\n    // A recorded samples file switches this exercise's reps to the k-NN classifier; {samples:null} forces the rules.\r\n    const samples='samples' in options?options.samples:POSE_SAMPLES[mode];\r\n    this.knn=samples&&MOVEMENTS[mode].kind==='reps'?new PoseClassifier(samples):null;\r\n    return this.snapshot();\r\n  }\r\n  smooth(key,value,dt){const old=this.filtered[key];const a=1-Math.exp(-Math.max(dt,.01)/.085);return this.filtered[key]=old===undefined?value:old+(value-old)*a;}\r\n  lose(t,message='Keep the needed joints in view.'){\r\n    this.tracking=false;this.message=message;this.measurement='Tracking paused';this.phase='ready';this.phaseSince=null;this.filtered={};this.calibration=[];this.setupProgress=0;this.progress=0;this.kneeArmed={left:false,right:false};this.hands={};this.speed=0;\r\n    this.previousMatch=false;this.candidate=null;if(this.missAt===null)this.missAt=t;\r\n    if(t-this.missAt>.35)this.hold=0;\r\n  }\r\n  selectSide(f,kind,t){\r\n    const candidates=Object.entries(f.sides).filter(([,s])=>s[kind]);\r\n    if(!candidates.length){\r\n      const required=s=>kind==='core'?[s.id.s,s.id.h]:[s.id.s,s.id.e,s.id.w,s.id.h];\r\n      const nearest=Object.values(f.sides).map(s=>({s,issues:f.issues(required(s))})).sort((a,b)=>a.issues.length-b.issues.length)[0];\r\n      this.lose(t,nearest.issues.length?'Counting paused: '+nearest.issues.slice(0,2).join('; ')+'.':'Move a little closer so your torso is clear.');return null;\r\n    }\r\n    const key=kind==='core'?'coreQuality':'armQuality';\r\n    const chosen=candidates.find(([name])=>name===this.side)||candidates.sort((a,b)=>b[1][key]-a[1][key])[0];\r\n    if(this.side!==chosen[0]){this.side=chosen[0];this.base=null;this.calibration=[];this.phase='ready';this.phaseSince=null;this.filtered={};}\r\n    return chosen[1];\r\n  }\r\n  calibrate(sample,ready,t){\r\n    if(!ready){this.calibration=[];this.setupProgress=0;this.setupReason='Starting position not yet detected';return false;}\r\n    // Three samples must fit the window at any continuous rate (gaps up to MAX_FRAME_GAP). A fixed 1.1 s\r\n    // window silently needed 2 updates/s: a phone tracking at 1.4–1.9/s stayed on \"Setting start\" forever.\r\n    this.calibration.push({t,...sample});this.calibration=this.calibration.filter(v=>t-v.t<=2*MAX_FRAME_GAP);\r\n    this.setupProgress=Math.min(1,this.calibration.length/3,(t-this.calibration[0].t)/.7);this.setupReason='Hold steady';\r\n    if(this.calibration.length<3||t-this.calibration[0].t<.7)return false;\r\n    // A moving starting position is not a useful baseline.\r\n    const key=sample.hipY!==undefined?'hipY':'angle';\r\n    const values=this.calibration.map(v=>v[key]);\r\n    if(Math.max(...values)-Math.min(...values)>(key==='angle'?12:.025)){this.setupProgress=0;this.setupReason='Waiting for a steadier starting position';return false;}\r\n    this.base=Object.fromEntries(Object.keys(sample).map(k=>[k,median(this.calibration.map(v=>v[k]))]));\r\n    this.calibration=[];this.setupProgress=1;this.setupReason='Ready';this.phase='top';this.phaseSince=null;return true;\r\n  }\r\n  // Dwell is time-based: a phase first seen is credited half the gap since the previous sample (on average the body\r\n  // entered the zone midway). At phone rates (1.4–2.5 updates/s) one sample in the zone satisfies the default 0.1 s\r\n  // dwell instead of needing two; pause reps (0.8 s) still need the time. The up/down gap, a full down→up cycle,\r\n  // minDuration and the 0.45 s refractory still block double counts at 30 updates/s.\r\n  repetition(down,up,t,minDuration,dwell=.10){\r\n    if(this.phase==='ready'){\r\n      if(up){this.phase='top';this.phaseSince=null;}return;\r\n    }\r\n    const seen=t-this.dt/2;\r\n    // At <=10 Hz a terminal zone may occupy exactly one sample. Keep multi-sample\r\n    // debounce at higher rates, and retain explicit long holds for pause exercises.\r\n    const dwellFor=seconds=>this.dt>=.1-1e-9&&seconds<=.1?Math.min(seconds,this.dt/2):seconds;\r\n    if(this.phase==='top'){\r\n      if(down){if(this.phaseSince===null)this.phaseSince=seen;if(t-this.phaseSince+1e-9>=dwellFor(dwell)){this.phase='bottom';this.phaseSince=null;this.downAt=t;}}else this.phaseSince=null;\r\n    }else if(this.phase==='bottom'){\r\n      if(up){if(this.phaseSince===null)this.phaseSince=seen;if(t-this.phaseSince+1e-9>=dwellFor(.10)&&t-this.downAt>=minDuration&&t-this.lastRep>=.45){this.count++;this.lastRep=t;this.eventTimes.push(t);this.phase='top';this.phaseSince=null;}}else this.phaseSince=null;\r\n    }\r\n  }\r\n  recipeUpdate(f,t,dt){\r\n    // Rule angles get the same EMA as the legacy paths (near-raw at phone rates, calmer at 30 updates/s).\r\n    const m=MOVEMENTS[this.mode],rule=evaluateMovement(f,m,this.side,(key,value)=>this.smooth(key,value,dt));\r\n    // Hold grace: under MAX_FRAME_GAP of unseen or off-shape frames keeps the hold. Unseen time is credited when the\r\n    // shape returns (the user most likely held it); off-shape time is not, but a flicker no longer restarts the hold.\r\n    if(m.kind==='hold'&&!rule.match&&this.candidate!==null){\r\n      this.missAt??=t;\r\n      if(t-this.missAt<MAX_FRAME_GAP){if(rule.valid)this.previousMatch=false;this.tracking=rule.valid;this.progress=0;this.message='Hold paused. '+rule.message;return;}\r\n    }\r\n    if(!rule.valid){this.lose(t,rule.message);return;}\r\n    if(rule.side&&this.side!==rule.side){this.side=rule.side;this.base=null;this.calibration=[];this.phase='ready';this.phaseSince=null;this.filtered={};}\r\n    this.tracking=true;\r\n    if(m.kind==='hold'){\r\n      if(rule.match){\r\n        if(this.candidate===null)this.candidate=t;\r\n        if(t-this.candidate>=.45&&this.previousMatch){const d=t-this.lastMatch;this.hold+=d;this.totalHold+=d;this.bestHold=Math.max(this.bestHold,this.hold);}\r\n        this.previousMatch=true;this.missAt=null;this.lastMatch=t;\r\n      }else{this.previousMatch=false;this.candidate=null;this.hold=0;}\r\n      this.progress=Number(rule.match);this.message=rule.match?(rule.estimated?'Hold estimated from your upper body. Keep this position.':'Position detected. Hold comfortably.'):'Hold paused. '+rule.message;\r\n    }else{\r\n      let up=rule.up,down=rule.down;\r\n      if(rule.travel){\r\n        if(this.base){const travel=this.smooth('recipeMetric',(rule.sample.hipY-this.base.hipY)/this.base.torso,dt);down=travel>=rule.travel;up=travel<=rule.travel*.6;this.progress=clamp(travel/.5,0,1);}else up=true;\r\n      }else this.progress=clamp(rule.metric,0,1);\r\n      if(!this.base){this.calibrate(rule.sample??{angle:0},up,t);this.message=this.base?'Ready. Begin when you are ready.':m.hint+' Hold the starting position briefly.';this.progress=this.setupProgress;}\r\n      else{this.repetition(down,up,t,m.minCycle??.18,m.dwell??.10);this.message=this.phase==='bottom'?'Return to your starting position.':'Move with control. Complete the full return to count.';}\r\n    }\r\n    this.measurement=m.measurement+' · '+m.limits;\r\n  }\r\n  // k-NN reps (pose-classifier.mjs): EMA of the \"down\" vote, entering at 6/10 and leaving at 4/10 as in\r\n  // MediaPipe's repetition counter, then the same dwell/minimum-duration gate as the rules.\r\n  knnUpdate(f,t,dt){\r\n    const m=MOVEMENTS[this.mode],need=this.knn.need;\r\n    if(!f.visible(need)){this.lose(t,'Counting paused: '+f.issues(need).slice(0,2).join('; ')+'.');return;}\r\n    this.tracking=true;\r\n    const down=this.smooth('knnDown',this.knn.classify(f.p).down??0,dt);\r\n    this.repetition(down>=.6,down<=.4,t,m.minCycle??.18,m.dwell??.10);\r\n    if(this.phase!=='ready')this.base??={};\r\n    this.progress=clamp(down,0,1);\r\n    this.message=this.phase==='bottom'?'Return to your starting position.':this.phase==='ready'?'Start in your recorded top position.':'Move with control. Complete the full return to count.';\r\n    this.measurement='Matched to recorded poses · '+m.limits;\r\n  }\r\n  repUpdate(f,t,dt){\r\n    const squat=this.mode==='squat';const s=this.selectSide(f,squat?'core':'arm',t);if(!s)return;\r\n    if(!squat&&s.horizontal<.5){this.lose(t,'Place the camera beside you so it can see your push-up position.');return;}\r\n    this.tracking=true;\r\n\r\n    const a=this.smooth('angle',squat?180:s.elbow,dt),hipY=this.smooth('hipY',s.h.y,dt);\r\n    if(!this.base){\r\n      const ready=squat?(s.h.y-s.s.y)/s.torso>.65:a>145&&s.horizontal>=.5;\r\n      const calibrated=this.calibrate(squat?{hipY,torso:s.torso,angle:a}:{angle:a},ready,t);\r\n      this.message=calibrated?'Ready. Begin when you are ready.':!ready?(squat?'Start standing tall with your shoulders and hips visible.':'Start at the top with your arm extended.'):this.setupReason==='Hold steady'?`Setting start: ${Math.round(this.setupProgress*100)}%. Hold still briefly.`:this.setupReason+'.';\r\n      this.progress=this.setupProgress;\r\n      this.measurement=`${this.side} side · ${Math.round(a)}°`;return;\r\n    }\r\n\r\n    const bend=squat?0:this.base.angle-a,drop=squat?(hipY-this.base.hipY)/this.base.torso:0;\r\n    // Hip travel relative to the starting torso supports cropped frontal views.\r\n    // Counts use only torso movement; lower-leg landmarks are discarded.\r\n    const down=squat?drop>=.25:bend>=35;\r\n    const up=squat?drop<=.15:bend<=14;\r\n    this.repetition(down,up,t,.18);\r\n    this.message=this.phase==='bottom'?'Movement registered. Return to your starting position.':this.phase==='ready'?'Return to your starting position to resume.':'Ready for the next repetition.';\r\n    this.progress=clamp(squat?Math.max(bend/40,drop/.5):bend/50,0,1);\r\n    this.measurement=squat?`${this.side} hip · travel ${Math.max(0,drop).toFixed(2)} · torso only`:`${this.side} arm · bend ${Math.round(bend)}°`;\r\n  }\r\n  holdUpdate(f,t,dt){\r\n    if(!f.knees){this.lose(t,'Hold paused: '+(f.issues([11,12,23,24,25,26]).slice(0,2).join('; ')||'move a little closer')+'. Feet do not need to be visible.');return;}\r\n    this.tracking=true;const l=f.sides.left,r=f.sides.right;\r\n    const spread=Math.abs(l.k.x-r.k.x)/f.torso;\r\n    let match=false,label='';\r\n    if(this.mode==='tree'){\r\n      for(const [raised,support,name] of [[l,r,'Left leg raised'],[r,l,'Right leg raised']]){\r\n        const raisedOut=Math.abs(raised.k.x-raised.h.x)/f.torso,supportOut=Math.abs(support.k.x-support.h.x)/f.torso;\r\n        if(f.upright&&raisedOut>.4&&supportOut<.55&&(support.k.y-raised.k.y)/f.torso>.15){match=true;label=name+' · estimated from upper legs';break;}\r\n      }\r\n    }else if(this.mode==='warrior'){\r\n      const arms=f.visible([11,12,13,14,15,16])&&l.elbow>140&&r.elbow>140&&Math.abs(l.w.y-l.s.y)/f.torso<.4&&Math.abs(r.w.y-r.s.y)/f.torso<.4&&Math.abs(l.w.x-r.w.x)/f.torso>2.2;\r\n      const leftDrop=(l.k.y-l.h.y)/f.torso,rightDrop=(r.k.y-r.h.y)/f.torso;\r\n      match=f.upright&&spread>1.15&&arms&&((leftDrop<.85&&rightDrop>.85)||(rightDrop<.85&&leftDrop>.85));label='Arms and upper-leg stance · estimated hold';\r\n    }else{\r\n      match=f.upright&&spread>1.5&&Math.abs(l.k.x-l.h.x)/f.torso>.5&&Math.abs(r.k.x-r.h.x)/f.torso>.5&&(l.k.y-l.h.y)/f.torso<1&&(r.k.y-r.h.y)/f.torso<1;label='Wide upper-leg stance · estimated hold';\r\n    }\r\n    if(match){\r\n      if(this.missAt!==null&&t-this.missAt>.35)this.hold=0;\r\n      this.missAt=null;if(this.candidate===null)this.candidate=t;\r\n      if(t-this.candidate>=.45){if(this.previousMatch){this.hold+=dt;this.totalHold+=dt;this.bestHold=Math.max(this.bestHold,this.hold);}this.message='Pose detected. Hold at your own comfort level.';}\r\n      else this.message='Position found. Hold steady…';\r\n      this.previousMatch=true;this.measurement=label;\r\n    }else{\r\n      if(this.missAt===null)this.missAt=t;if(t-this.missAt>.35){this.hold=0;this.candidate=null;}\r\n      this.previousMatch=false;this.message='Hold timer paused. Reposition if needed.';this.measurement=MOVEMENTS[this.mode].hint;\r\n    }\r\n    this.progress=match?1:0;\r\n  }\r\n  boxingUpdate(f,t,dt){\r\n    const selected=MOVEMENTS[this.mode].side;\r\n    const available=Object.entries(f.sides).filter(([name,s])=>s.arm&&(!selected||selected===name));\r\n    if(!available.length){this.selectSide(f,'arm',t);return;}\r\n    this.tracking=true;const velocities=[];const next={};\r\n    for(const [name,s] of available){\r\n      const w=f.world;const ids=s.id;\r\n      const useWorld=w&&[ids.s,ids.w,ids.h].every(i=>w[i]&&Number.isFinite(w[i].x)&&Number.isFinite(w[i].y)&&Number.isFinite(w[i].z));\r\n      const hand=useWorld?w[ids.w]:s.w,shoulder=useWorld?w[ids.s]:s.s,hip=useWorld?w[ids.h]:s.h;\r\n      const scale=Math.max(distance(shoulder,hip),.035);\r\n      const point={x:(hand.x-shoulder.x)/scale,y:(hand.y-shoulder.y)/scale,z:((hand.z??0)-(shoulder.z??0))/scale};\r\n      const previous=this.hands[name];\r\n      if(previous&&previous.world===!!useWorld&&dt>.005){const speed=distance(point,previous.point)/dt;if(speed<20)velocities.push(speed);}\r\n      next[name]={point,world:!!useWorld};\r\n    }\r\n    this.hands=next;const instant=velocities.length?Math.max(...velocities):0;\r\n    this.speed+= (instant-this.speed)*(1-Math.exp(-dt/.25));\r\n    if(this.speed>.7)this.active+=dt;this.bestSpeed=Math.max(this.bestSpeed,this.speed);\r\n    this.message=this.speed>.7?'Movement detected. Keep your own rhythm.':'Active timer paused. Move your hands when ready.';\r\n    this.measurement='Hand pace is relative to torso length. No punch-accuracy score.';this.progress=clamp(this.speed/5,0,1);\r\n  }\r\n  jogUpdate(f,t,dt){\r\n    // Cool Cardio on a treadmill: the console hides the knees, so a head bob is the step (keeps active time and XP counting).\r\n    if(!f.knees&&EXERCISES[this.mode]?.runner&&f.visible([0,11,12])){\r\n      this.tracking=true;this.bob??=createHeadBob();if(this.bob.update(f.p,t)){this.count++;this.eventTimes.push(t);this.lastStep=t;}\r\n      this.message='Counting head bobs (treadmill).';this.measurement='Estimated steps from head bob; knees are not tracked.';this.progress=clamp((t-this.lastStep)<1?1:0,0,1);return;\r\n    }\r\n    if(!f.knees){this.lose(t,'Steps paused: '+(f.issues([11,12,23,24,25,26]).slice(0,2).join('; ')||'move a little closer')+'. Feet are not tracked.');return;}\r\n    this.tracking=true;const l=f.sides.left,r=f.sides.right;\r\n    for(const [name,a,b] of [['left',l,r],['right',r,l]]){\r\n      const lift=this.smooth(name+'Lift',(b.k.y-a.k.y)/f.torso,dt);\r\n      if(lift<.05)this.kneeArmed[name]=true;\r\n      if(this.kneeArmed[name]&&lift>(MOVEMENTS[this.mode].lift??.13)&&t-this.lastStep>.17){this.count++;this.eventTimes.push(t);this.lastStep=t;this.kneeArmed[name]=false;}\r\n    }\r\n    this.message='Counting alternating knee lifts.';this.measurement='Estimated steps from knees; feet are not tracked.';this.progress=clamp(Math.abs(l.k.y-r.k.y)/f.torso/.3,0,1);\r\n  }\r\n  jumpUpdate(f,t,dt){\r\n    const s=this.selectSide(f,'core',t);if(!s)return;this.tracking=true;\r\n    const hip=this.smooth('hip',s.h.y,dt),shoulder=this.smooth('shoulder',s.s.y,dt);\r\n    if(!this.base){this.calibrate({hipY:hip,shoulder,torso:s.torso},(s.h.y-s.s.y)/s.torso>.65,t);this.message=this.base?'Ready. Begin when you are ready.':`Setting start: ${Math.round(this.setupProgress*100)}%. Stand still briefly.`;this.progress=this.setupProgress;return;}\r\n    if(Math.abs(s.torso/this.base.torso-1)>.3){this.base=null;this.calibration=[];this.phase='ready';this.message='Distance changed. Stand still to reset your start.';return;}\r\n    const lift=(this.base.hipY-hip)/this.base.torso,shoulderLift=(this.base.shoulder-shoulder)/this.base.torso;\r\n    if(this.phase==='ready'&&lift<.07)this.phase='top';\r\n    if(this.phase==='top'&&lift>.16&&shoulderLift>.12){this.phase='air';this.airAt=t;}\r\n    else if(this.phase==='air'&&lift<.07){if(t-this.airAt>.12&&t-this.lastRep>.35){this.count++;this.eventTimes.push(t);this.lastRep=t;}this.phase='top';}\r\n    this.message=this.phase==='air'?'Body rise detected. Return to your starting height.':'Ready for the next estimated jump.';this.measurement='Estimated from body rise; landing cannot be verified without feet.';this.progress=clamp(lift/.4,0,1);\r\n  }\r\n  update(raw,timestamp,aspect=1,world=null){\r\n    const t=timestamp/1000;if(!Number.isFinite(t))return this.snapshot();\r\n    if(this.last!==null&&t<=this.last)return this.snapshot();\r\n    const gap=this.last===null?0:t-this.last;const dt=gap>MAX_FRAME_GAP?0:gap;this.last=t;this.dt=dt;\r\n    if(this.complete)return this.snapshot();\r\n    const f=features(raw,aspect,world);\r\n    this.jointReadings=f?Object.entries(f.sides).map(([side,s])=>`${side}: `+[s.id.s,s.id.h,s.id.k].map(i=>`${JOINTS[i].split(' ')[1]} ${Math.round(f.p[i].visibility*100)}%${f.visible([i])?'':' ×'}`).join(', ')).join(' | '):'No body landmarks';\r\n    if(this.started===null&&f&&Object.values(f.sides).some(s=>s.core||s.arm))this.started=t;\r\n    this.elapsed=this.started===null?0:t-this.started;\r\n    if(this.duration>0&&this.elapsed>=this.duration){this.elapsed=this.duration;this.complete=true;this.message='Round complete.';return this.snapshot();}\r\n    if(gap>MAX_FRAME_GAP){this.lose(t);this.phase='ready';this.hold=0;this.candidate=null;}\r\n    if(!f){this.lose(t,'No body found. Step into view.');return this.snapshot();}\r\n    const recipe=MOVEMENTS[this.mode];\r\n    if(this.knn)this.knnUpdate(f,t,dt);\r\n    else if(this.mode==='squat'||this.mode==='pushup')this.repUpdate(f,t,dt);\r\n    else if(['tree','warrior','horse'].includes(this.mode))this.holdUpdate(f,t,dt);\r\n    else if(recipe.detector==='boxing')this.boxingUpdate(f,t,dt);\r\n    else if(recipe.detector==='march')this.jogUpdate(f,t,dt);\r\n    else if(EXERCISES[this.mode])this.recipeUpdate(f,t,dt);\r\n    else this.jumpUpdate(f,t,dt);\r\n    return this.snapshot();\r\n  }\r\n  snapshot(){\r\n    const window=Math.min(10,this.elapsed);const now=this.last??0;\r\n    this.eventTimes=this.eventTimes.filter(t=>now-t<=10);\r\n    return {mode:this.mode,name:MOVEMENTS[this.mode].name,kind:MOVEMENTS[this.mode].kind,count:this.count,elapsed:this.elapsed,remaining:this.duration?Math.max(0,this.duration-this.elapsed):null,\r\n      hold:this.hold,totalHold:this.totalHold,bestHold:this.bestHold,active:this.active,speed:this.speed,bestSpeed:this.bestSpeed,cadence:window>=2?this.eventTimes.length*60/window:0,\r\n      complete:this.complete,tracking:this.tracking,calibrated:!!this.base,setupProgress:this.setupProgress,phase:this.phase,message:this.message,measurement:this.measurement,progress:this.progress,side:this.side,jointReadings:this.jointReadings};\r\n  }\r\n}\r\n","movement-rules.mjs":"// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Deliberately coarse movement measurements, not a form or injury-risk score.\r\n// Counting rules are data: one row per exercise (or per detector family), run by the small interpreter below.\r\n// Pattern after yakupzengin/fitness-trainer-pose-estimation (MIT): joint triplets with up/down thresholds.\r\n// squat, pushup, tree, warrior and horse still count on their hand-tuned paths in movement-engine.mjs (the ones\r\n// tested on Ian's phone); boxing (pace), march (steps) and jumping (body rise) are not threshold rules.\r\n//\r\n// A condition is 'measure op number', 'both measure op number' (true for the left AND the right side), a bare\r\n// flag ('upright'), or 'clear <landmarks>' (each visible, >= .45 like the engine). A measure is a joint triplet such as\r\n// 's-e-w' (the elbow angle on the counted side: s shoulder, e elbow, w wrist, h hip, k knee; MediaPipe ids work\r\n// too) or a name from MEASURES. Row fields:\r\n//  need   landmarks the counted side must show; the clearer side is picked, or the exercise's fixed side.\r\n//         Side-view rows need only the near side: the far side is naturally hidden.\r\n//  anySide  ignore the exercise's fixed side (its far leg may be the one hidden).\r\n//  fallback  row used when no side shows every `need` landmark (plank with the knees cropped).\r\n//  gate   conditions that must hold or counting pauses.\r\n//  up/down  start and far positions of a repetition (hysteresis sits in the gap between the thresholds).\r\n//  match  hold shape; with either:true it may hold for either leg (mirror).\r\n//  metric 'measure zero span' progress, (value-zero)/span; a list takes the smallest.\r\n//  travel hip travel from the calibrated start, in torso lengths (squats).\r\n// Timing (dwell, minCycle) stays on the exercise-library row. Angles are EMA-smoothed by the engine.\r\nconst clamp=(x,a,b)=>Math.max(a,Math.min(b,x));\r\nconst angle=(a,b,c)=>{const u=[a.x-b.x,a.y-b.y,(a.z??0)-(b.z??0)],v=[c.x-b.x,c.y-b.y,(c.z??0)-(b.z??0)],d=Math.hypot(...u)*Math.hypot(...v);return d>1e-8?Math.acos(clamp(u.reduce((s,x,i)=>s+x*v[i],0)/d,-1,1))*180/Math.PI:NaN;};\r\n// World angles are optional: never combine world and image coordinates.\r\nconst a3=(f,a,b,c)=>{const w=f.world;return w&&[a,b,c].every(i=>w[i]&&[w[i].x,w[i].y,w[i].z].every(Number.isFinite))?angle(w[a],w[b],w[c]):angle(f.p[a],f.p[b],f.p[c]);};\r\n// s: counted side, o: the other side. …Drop: below its reference in the counted side's torso lengths; the rest use\r\n// the body torso T (both sides averaged).\r\nexport const JOINTS={11:'left shoulder',12:'right shoulder',13:'left elbow',14:'right elbow',15:'left hand',16:'right hand',23:'left hip',24:'right hip',25:'left knee',26:'right knee'};\r\n// What to tell the user when a gate or hold condition on this measure fails; others fall back to the hint.\r\nconst TIPS={upright:'Stand tall',hipDrop:'Stand tall',horizontal:'Get level, side-on to the camera',wristDrop:'Hands under your shoulders','s-h-k':'Straighten your back','s-e-w':'Adjust your arms',kneeDrop:'Adjust your knees',kneeY:'Adjust your knees',kneeOut:'Widen your stance',spread:'Adjust your stance',wristY:'Reach your arms overhead'};\r\nconst unseen=ids=>\"Can't see your \"+ids.slice(0,2).map(i=>JOINTS[i]).join(' or ');\r\nconst MEASURES={\r\n core:c=>c.s.core,upright:c=>c.f.upright,horizontal:c=>c.s.horizontal,imageElbow:c=>c.s.elbow,\r\n hipDrop:c=>(c.s.h.y-c.s.s.y)/c.s.torso,wristDrop:c=>(c.s.w.y-c.s.s.y)/c.s.torso,kneeDrop:c=>(c.s.k.y-c.s.h.y)/c.s.torso,shoulderDrop:c=>(c.s.s.y-c.s.k.y)/c.s.torso,\r\n wristY:c=>(c.s.w.y-c.s.s.y)/c.T,elbowY:c=>(c.s.e.y-c.s.s.y)/c.T,wristElbowY:c=>(c.s.w.y-c.s.e.y)/c.T,wristLevel:c=>Math.abs(c.s.w.y-c.s.s.y)/c.T,\r\n kneeY:c=>(c.s.k.y-c.s.h.y)/c.T,otherKneeY:c=>(c.o.k.y-c.o.h.y)/c.T,kneeOut:c=>Math.abs(c.s.k.x-c.s.h.x)/c.T,otherKneeOut:c=>Math.abs(c.o.k.x-c.o.h.x)/c.T,kneeGap:c=>(c.o.k.y-c.s.k.y)/c.T,\r\n spread:c=>Math.abs(c.l.k.x-c.r.k.x)/c.T,wristSpan:c=>Math.abs(c.l.w.x-c.r.w.x)/c.T,shoulderStackY:c=>Math.abs(c.l.s.y-c.r.s.y)/c.T,shoulderStackX:c=>Math.abs(c.l.s.x-c.r.s.x)/c.T\r\n};\r\nconst UPPER='clear 11 12 13 14 15 16 23 24',LEGS='clear 11 12 23 24 25 26',OVERHEAD=[UPPER,'both wristY < -.65'];\r\nconst push={need:'s e w h',gate:['horizontal >= .5','wristDrop >= .12'],up:['s-e-w > 150'],down:['s-e-w < 112'],metric:'s-e-w 165 -60'};\r\nconst incline={...push,gate:['horizontal >= .28','wristDrop >= .12']};\r\nconst squat={gate:['core','hipDrop >= .55'],travel:.25};\r\nconst hinge={need:'s h k',gate:['kneeDrop >= .35'],up:['s-h-k > 158'],down:['s-h-k < 135'],metric:'s-h-k 180 -65'};\r\n// Knees cropped: the shoulder–hip line and the support arm alone (ankles never reach the rules).\r\n// ponytail: without a knee this cannot tell a plank from hands-and-knees; add hip–ankle if ankles are ever kept.\r\nconst plankRow=elbow=>({need:'s e w h k',gate:['horizontal > .65'],match:['s-h-k > 155','wristDrop > .2',...elbow],fallback:{need:'s e w h',gate:['horizontal > .75'],match:['wristDrop > .2',...elbow]}});\r\nconst plank=plankRow(['s-e-w > 145']);\r\nconst raise={gate:[UPPER,'upright'],up:['both h-s-w < 30'],down:['both h-s-w > 65','both s-e-w > 145'],metric:'both h-s-w 0 90'};\r\nconst standing=[LEGS,'upright'],straightLegs=['both kneeOut < .55','both kneeY > .7','spread < 1.2'];\r\nconst balance={gate:standing,either:true,match:['otherKneeOut < .55','otherKneeY > .5','kneeGap > .15','kneeOut > .4']};\r\nconst horse=deepest=>({gate:standing,match:['spread > 1.4','both kneeOut > .5','both kneeY > .08','both kneeY < '+deepest]});\r\n// Side view: the near leg is the front (bent) or back (angled) leg; either is well out from under the hip.\r\nconst front={need:'s h k',anySide:true,gate:['hipDrop > .65'],match:['kneeOut > .35']};\r\nconst jack={gate:[UPPER,LEGS,'upright'],up:['spread < 1.3','both h-s-w < 45'],down:['spread > 1.5','both h-s-w > 120'],metric:['spread 0 1.5','both h-s-w 0 140']};\r\n// Keyed by exercise id, falling back to the exercise's detector.\r\nexport const RULES={\r\n pushup:push,'high-incline-pushup':incline,'low-incline-pushup':incline,\r\n squat,'shallow-squat':{...squat,travel:.18},\r\n split:{need:'s h k',gate:['upright','kneeDrop >= 0'],up:['s-h-k > 155'],down:['s-h-k < 135'],metric:'s-h-k 165 -60'},\r\n hinge,'small-hinge':{...hinge,down:['s-h-k < 155']},\r\n bridge:{need:'s h k',gate:['horizontal >= .5','kneeDrop < .2','shoulderDrop >= .1'],up:['s-h-k < 145'],down:['s-h-k > 162'],metric:'s-h-k 125 50'},\r\n plank,'forearm-plank':plankRow(['s-e-w > 60','s-e-w < 120']),\r\n sideplank:{need:'s e h k',gate:['clear 11 12 23 24 e k'],match:['shoulderStackY > .3','shoulderStackX < .5','horizontal > .7','s-h-k > 153','elbowY > .15']},\r\n raise,'front-raise':{need:'s e w h',gate:['hipDrop > .65'],up:['h-s-w < 30'],down:['h-s-w > 65','s-e-w > 145'],metric:'h-s-w 0 90'},'overhead-reach':{...raise,down:['both h-s-w > 150','both s-e-w > 145'],metric:'both h-s-w 0 160'},\r\n press:{gate:[UPPER,'upright'],up:['both s-e-w < 115','both wristY < .2'],down:['both wristY < -.65','both s-e-w > 155'],metric:'both h-s-w 0 90'},\r\n balance,'low-tree':{...balance,match:['otherKneeOut < .55','otherKneeY > .5','kneeGap > .08','kneeOut > .2']},\r\n 'knee-balance':{...balance,match:['otherKneeOut < .55','otherKneeY > .5','kneeGap > .35']},'overhead-tree':{...balance,match:[...balance.match,...OVERHEAD]},\r\n mountain:{gate:standing,match:[...straightLegs,UPPER,'both wristY > .5']},salute:{gate:standing,match:[...straightLegs,...OVERHEAD]},\r\n chair:{need:'s e w h k',gate:['hipDrop > .65'],match:['kneeDrop > .08','kneeDrop < .8','wristDrop < -.65']},\r\n 'warrior-one':{...front,need:'s e w h k',match:[...front.match,'wristDrop < -.65']},\r\n 'wall-sit':{need:'s h k',gate:['hipDrop > .65'],match:['s-h-k > 70','s-h-k < 120','kneeDrop < .5']},\r\n warrior:{gate:standing,either:true,match:['spread > 1.1','kneeY < .85','otherKneeY > .85',UPPER,'both imageElbow > 145','both wristLevel < .3','wristSpan > 2']},\r\n goddess:{gate:standing,match:[...horse(1).match,UPPER,'both imageElbow < 120','both wristElbowY < 0']},\r\n stance:horse(1),'high-horse':horse(1.25),'low-horse':horse(.6),'front-stance-left':front,'front-stance-right':front,\r\n jack,'step-jack':{...jack,down:['spread > 1.3','both h-s-w > 120']}\r\n};\r\nconst OPS={'<':(a,b)=>a<b,'>':(a,b)=>a>b,'<=':(a,b)=>a<=b,'>=':(a,b)=>a>=b};\r\nconst swap=c=>({...c,s:c.o,o:c.s});\r\nfunction measure(name){\r\n if(MEASURES[name])return MEASURES[name];\r\n if(!/^([sewhk]|\\d+)-([sewhk]|\\d+)-([sewhk]|\\d+)$/.test(name))throw new Error('Unknown movement measure: '+name);\r\n const keys=name.split('-');\r\n return c=>{\r\n  const [a,b,d]=keys.map(k=>c.s.id[k]??Number(k)),v=a3(c.f,a,b,d);\r\n  if(!Number.isFinite(v)){c.flags.nan=true;return v;}\r\n  return c.smooth?c.smooth(a+name,v):v;\r\n };\r\n}\r\nfunction condition(text){\r\n const t=text.split(' ');\r\n if(t[0]==='clear'){const keys=t.slice(1);return c=>keys.every(k=>c.f.visible([c.s.id[k]??Number(k)]));}\r\n const both=t[0]==='both';if(both)t.shift();\r\n const [name,op,value]=t,get=measure(name);if(op&&!OPS[op])throw new Error('Unknown movement operator: '+text);\r\n const one=op?c=>OPS[op](get(c),Number(value)):c=>!!get(c);\r\n return both?c=>[one(c),one(swap(c))].every(Boolean):one;\r\n}\r\nfunction progress(text){\r\n const t=text.split(' '),both=t[0]==='both';if(both)t.shift();\r\n const get=measure(t[0]),zero=Number(t[1]),span=Number(t[2]),one=c=>(get(c)-zero)/span;\r\n return both?c=>Math.min(one(c),one(swap(c))):one;\r\n}\r\n// Every condition is evaluated (no short-circuit) so an unusable angle anywhere in a repetition rule is seen.\r\n// The first failing condition is kept on c.failed for the pause message.\r\nconst all=list=>{const tests=list.map(text=>[text,condition(text)]);return c=>tests.map(([text,test])=>test(c)||(c.failed??=text,false)).every(Boolean);};\r\nfunction tip(c,text,hint){\r\n const t=text.split(' ');\r\n if(t[0]==='clear')return unseen(t.slice(1).map(k=>c.s.id[k]??Number(k)).filter(i=>!c.f.visible([i])));\r\n return TIPS[t[t[0]==='both'?1:0]]??hint;\r\n}\r\nconst compile=r=>({...r,fallback:r.fallback&&compile(r.fallback),need:r.need?.split(' ')??null,gate:all(r.gate??[]),match:r.match&&all(r.match),up:all(r.up??[]),down:all(r.down??[]),metric:[r.metric??[]].flat().map(progress)});\r\n// Rows compile once (a typo fails when this module loads); a row added later compiles on first use.\r\nconst compiled=new WeakMap(),ruleFor=rule=>rule&&(compiled.get(rule)??compiled.set(rule,compile(rule)).get(rule));\r\nObject.values(RULES).forEach(ruleFor);\r\n// smooth(key,value) is the engine's EMA; tests and one-off checks pass none.\r\nexport function evaluateMovement(f,m,previousSide=null,smooth=null){\r\n let rule=ruleFor(RULES[m.id]??RULES[m.detector]);\r\n const fixed=rule?.anySide?null:m.side,usable=r=>Object.entries(f.sides).filter(([name,s])=>(!fixed||fixed===name)&&s.torso>.035&&(!r.need||f.visible(r.need.map(k=>s.id[k]))));\r\n let candidates=rule?usable(rule):[],estimated=false;\r\n if(!candidates.length&&rule?.fallback){rule=rule.fallback;candidates=usable(rule);estimated=true;}\r\n const need=rule?.need,picked=candidates.find(([name])=>name===previousSide)??candidates.sort((a,b)=>b[1].coreQuality-a[1].coreQuality)[0];\r\n const out={valid:false,up:false,down:false,match:false,metric:0,side:picked?.[0]??null,message:m.hint,estimated};\r\n if(!rule)return out;\r\n if(need&&!picked){\r\n  // Name the joints the nearest side is missing.\r\n  const missing=Object.entries(f.sides).filter(([name])=>!fixed||fixed===name).map(([,s])=>need.map(k=>s.id[k]).filter(i=>!f.visible([i]))).sort((a,b)=>a.length-b.length)[0];\r\n  if(missing?.length)out.message=unseen(missing);return out;\r\n }\r\n const l=f.sides.left,r=f.sides.right,s=fixed?f.sides[fixed]:picked?.[1]??l;\r\n const c={f,l,r,s,o:s===l?r:l,T:Math.max(f.torso,.035),smooth,flags:{nan:false},failed:null};\r\n if(!rule.gate(c)){out.message=tip(c,c.failed,m.hint);return out;}\r\n if(rule.travel){out.valid=true;out.travel=rule.travel;out.sample={hipY:s.h.y,torso:s.torso,angle:0};out.metric=s.h.y;return out;}\r\n if(rule.match){\r\n  out.valid=true;out.match=rule.either?[c,swap(c)].some(x=>rule.match(x)):rule.match(c);out.metric=Number(out.match);\r\n  if(!out.match)out.message=tip(c,c.failed,m.hint);return out;\r\n }\r\n const up=rule.up(c),down=rule.down(c),metric=rule.metric.length?Math.min(...rule.metric.map(p=>p(c))):0;\r\n if(c.flags.nan)return out;\r\n return Object.assign(out,{valid:true,up,down,metric});\r\n}\r\n","movement-setup.mjs":"// Camera instructions describe the joints used by Coach, never feet or ankles.\r\nexport function movementSetup(m){\r\n const d=m.detector,side=m.side?`${m.side} side`:'near side';\r\n let joints=['Shoulders','Hips','Both knees'];\r\n if(d==='pushup')joints=['Shoulder','Elbow','Wrist','Hip'];\r\n else if(d==='squat'||m.id==='jumping')joints=['Shoulders','Hips'];\r\n else if(['hinge','split','bridge'].includes(d))joints=['Shoulder','Hip','Knee'];\r\n else if(d==='plank')joints=['Shoulder','Elbow','Wrist','Hip','Knee'];\r\n else if(d==='sideplank')joints=['Both shoulders','Both hips','Supporting elbow','Supporting knee'];\r\n else if(['raise','press','boxing'].includes(d))joints=['Both shoulders','Both elbows','Both wrists','Hips'];\r\n else if(d==='yoga'||d==='jack'||(d==='balance'&&m.overhead))joints=['Shoulders','Elbows','Wrists','Hips','Both knees'];\r\n const floor=['bridge','plank','sideplank'].includes(d)||(d==='pushup'&&!m.incline);\r\n const position=d==='sideplank'?'Chest toward camera':m.view==='side'?'Side view':m.view==='angle'?'Slight angle':'Front view';\r\n const placement=floor?'Phone low · steady support':'Phone at waist height · steady support';\r\n const framing=['pushup','hinge','split','bridge','plank'].includes(d)?`${side[0].toUpperCase()+side.slice(1)} clear · room to move`:'Keep these in frame as you move.';\r\n return {position,placement,framing,joints,feet:'Feet and ankles are not tracked.'};\r\n}\r\n","nutrition.mjs":"export const MACROS=[['calories','Calories','kcal'],['protein','Protein','g'],['carbs','Carbs','g'],['fat','Fat','g']];\r\nexport const MICROS=[['calcium','Calcium','mg'],['iron','Iron','mg'],['magnesium','Magnesium','mg'],['potassium','Potassium','mg'],['sodium','Sodium','mg'],['zinc','Zinc','mg'],['vitaminA','Vitamin A','µg RAE'],['vitaminC','Vitamin C','mg'],['vitaminD','Vitamin D','µg'],['vitaminE','Vitamin E','mg'],['vitaminB12','Vitamin B12','µg'],['folate','Folate','µg']];\r\nexport const NUTRIENTS=[...MACROS,...MICROS];\r\nconst aliases={'french fries':'potatoes french fried','ice cream':'ice creams','hamburger':'hamburger','hot dog':'frankfurter','grilled salmon':'salmon cooked','grilled cheese sandwich':'sandwich cheese','macaroni and cheese':'macaroni cheese','steak':'beef steak cooked','french toast':'french toast','fried rice':'rice fried','sashimi':'fish raw','omelette':'egg omelet'};\r\nconst words=value=>value.toLowerCase().replace(/[^a-z0-9 ]/g,' ').split(/\\s+/).filter(w=>w.length>1&&!['and','with','the'].includes(w)).map(w=>w.replace(/s$/,''));\r\nexport function findFoods(foods,query,limit=8){\r\n const terms=words(aliases[query.toLowerCase()]||query);if(!terms.length)return [];\r\n return foods.map(food=>{const tokens=words(food.name);if(!terms.every(t=>tokens.includes(t)))return null;return {food,score:tokens.length+( /babyfood|infant|dry mix|powder|dehydrated/i.test(food.name)?60:0)};}).filter(Boolean).sort((a,b)=>a.score-b.score).slice(0,limit).map(x=>x.food);\r\n}\r\nexport function portionNutrition(food,grams){\r\n if(!food||!Number.isFinite(grams)||grams<=0||grams>2000)return Object.fromEntries(NUTRIENTS.map(([k])=>[k,null]));\r\n return Object.fromEntries(NUTRIENTS.map(([k])=>[k,food[k]==null?null:Math.round(food[k]*grams/100*100)/100]));\r\n}\r\nexport function displayNutrient(value,unit){return value==null?'—':`${new Intl.NumberFormat(undefined,{maximumFractionDigits:unit==='kcal'?0:2}).format(value)} ${unit}`;}\r\n","office-domain.mjs":"export const OFFICE_STYLES=['Original MYR5','Verdant','Mycelial','Chitin','Reptilian','Abyssal','Coral','Skeletal','Spectral','Infernal','Celestial','Voidborn','Eldritch','Stone Golem','Crystal','Magma','Glacial','Stormcharged','Clockwork','Neon Synth'];\r\nexport const OFFICE_SECTIONS={fuel:'B. Caffeine & supplements',goon:'C. Support & accountability',lilboyfriend:'D. Premises & equipment',djscratch:'E. Motivation & communication',corgi:'F. Sleep & stress',girlfriend:'G. Advice & sources',armie:'H. Movement history & limits'};\r\nexport const OFFICE_REQUIRED_FIELDS=['goal','goalWeightLbs','experience','sessionMinutes','coach'];\r\nexport function withOfficeDefaults(data){\r\n const value=structuredClone(data),profile=value.profile??={};\r\n const defaults={name:'You',trainingStyle:'Gradual progression',guidance:'Balanced',restSeconds:'60',trainingTime:'17:00',timezone:'UTC',reminderTone:'gentle',reminderDays:'3'};\r\n for(const [key,fallback] of Object.entries(defaults))if(profile[key]==null||typeof profile[key]==='string'&&!profile[key].trim())profile[key]=fallback;\r\n if(profile.exercises==null||Array.isArray(profile.exercises)&&!profile.exercises.length)profile.exercises=['squat','pushup','tree','warrior','horse','boxing','jogging','jumping'];\r\n value.appearance??={};value.appearance['myr5-recipe-v1']??={version:1,styles:{head:0,eye:0,collar:0,body:0,arms:0,feet:0},eye:'sleepy',fur:1,iris:1,pupil:'round',pupilSize:1,detail:1,coach:'supportive',fingers:4,toes:3,eyeLayout:'single'};\r\n value.answers??={};value.siteChoices??={};value.officeBanter??=true;\r\n // Submitting the office form accepts its current/default appearance; games keep their explicit studio gate.\r\n value.customizationConfirmed=true;value.armieCompleted=false;\r\n return value;\r\n}\r\nexport function createOfficeDraft(timezone){\r\n return withOfficeDefaults({version:1,entryRoute:'office',profile:{timezone},answers:{}});\r\n}\r\nexport function officeBanterAllowed(data){\r\n if(data?.entryRoute!=='office'||data.officeBanter!==true||data.profile?.guidance==='Quiet')return false;\r\n const boundary=data.answers?.djscratch?.q3||'';\r\n return !/(?:no|never|don['’]?t|do not)\\s+(?:\\w+\\s+){0,2}(?:teas|mock|roast|insult|banter|jok)|(?:teas|mock|roast|banter).{0,20}(?:off limits|not allowed)/i.test(boundary);\r\n}\r\nexport function officeLine(data,stage=0){\r\n if(!officeBanterAllowed(data))return 'Your coach is reviewing the paperwork. Every answer still counts.';\r\n const lines=[\r\n  'You were offered an adventure. You requested a form. I have never been more fluorescently lit.',\r\n  'Look at you, choosing boxes over boss battles. A true employee of the month.',\r\n  'I could be in a game right now. Instead, I am emotionally attached to a stapler.',\r\n  'Another section complete. Riveting. I have scheduled my yawn for 2:30.',\r\n  'Paperwork approved. Tragically, I still have to be an excellent coach for you.'\r\n ];\r\n const line=lines[Math.min(lines.length-1,Math.max(0,Math.floor(stage)))];\r\n const blocked=(data.answers?.djscratch?.q3||'').split(/[,;\\n]/).map(s=>s.trim().toLowerCase()).filter(s=>s.length>=3&&!/^none\\.?$/.test(s));\r\n return blocked.some(s=>line.toLowerCase().includes(s))?'Your coach is reviewing the paperwork. Every answer still counts.':line;\r\n}\r\nexport function officeEncouragement(data,day=1){\r\n if(!officeBanterAllowed(data))return null;\r\n const lines=['Your paperwork was thrilling. Let’s make this movement even more exciting. Keep your own pace.','The Department of Tiny Progress has approved your next comfortable rep.','You chose forms over games. Fine. I still believe in your next small step.'];\r\n const line=lines[Math.abs(Math.floor(day)-1)%lines.length];\r\n const blocked=(data.answers?.djscratch?.q3||'').split(/[,;\\n]/).map(s=>s.trim().toLowerCase()).filter(s=>s.length>=3&&!/^none\\.?$/.test(s));\r\n return blocked.some(s=>line.toLowerCase().includes(s))?null:line;\r\n}\r\n","office-form.mjs":"import {OFFICE_STYLES,officeLine} from './office-domain.mjs?v=office-short-v1';\r\nconst node=(tag,text)=>{const e=document.createElement(tag);if(text)e.textContent=text;return e;};\r\nexport function mountOfficeAppearance(form,data,{optional=false}={}){\r\n const panel=node('aside');panel.className='office-supervisor';panel.setAttribute('aria-label','Your bored paperwork supervisor');\r\n const mascot=node('div');mascot.className='office-mascot';mascot.setAttribute('aria-hidden','true');\r\n const eye=node('span');eye.className='office-eye';mascot.append(eye,node('i'));\r\n const speech=node('div'),badge=node('strong','COACH / TEMPORARILY ASSIGNED TO ADMIN'),line=node('p');line.setAttribute('aria-live','polite');speech.append(badge,line);panel.append(mascot,speech);form.append(panel);\r\n const appearance=node('fieldset');appearance.append(node('legend','Coach appearance'));\r\n appearance.append(node('p','Choose the look your coach will wear in the app. This office sketch is your bored supervisor; the app uses your selected creature parts.'));\r\n const grid=node('div');grid.className='setup-fields';const recipe=data.appearance['myr5-recipe-v1'];\r\n for(const [key,title] of Object.entries({head:'Crown & scales',eye:'Eye style',collar:'Shaggy collar',body:'Body',arms:'Arms & hands',feet:'Legs & feet'})){\r\n  const label=node('label',title),select=node('select');select.name='appearance.'+key;\r\n  OFFICE_STYLES.forEach((text,i)=>select.append(new Option(text,String(i))));select.value=String(recipe.styles[key]);label.append(select);grid.append(label);\r\n }\r\n const expression=node('label','Expression'),eyes=node('select');eyes.name='appearance.expression';for(const [id,title] of [['sleepy','Bored by paperwork'],['open','Trying to look interested'],['wide','Shocked you picked paperwork']])eyes.append(new Option(title,id));eyes.value=recipe.eye;expression.append(eyes);grid.append(expression);appearance.append(grid);\r\n const banterLabel=node('label');banterLabel.className='office-check';const banter=node('input');banter.type='checkbox';banter.name='officeBanter';banter.checked=data.officeBanter===true;banterLabel.append(banter,document.createTextNode('Let my coach roast my choice of paperwork.'));if(!optional)appearance.append(banterLabel,node('p','Uncheck for quiet paperwork. “Quiet” guidance and requests for no teasing also silence the jokes.'));\r\n return {appearance,banterLabel,collect(){for(const k of Object.keys(recipe.styles))recipe.styles[k]=Number(form.elements.namedItem('appearance.'+k).value);recipe.eye=eyes.value;recipe.coach=data.profile.coach||'supportive';data.customizationConfirmed=true;data.officeBanter=banter.checked;},paint(missing,total){mascot.dataset.eye=recipe.eye;const next=officeLine(data,missing===0?4:Math.min(3,Math.floor((1-missing/total)*4)));if(line.textContent!==next)line.textContent=next;}};\r\n}\r\n","office-quick-form.mjs":"import {FIELDS,missingFields} from './onboarding-domain.mjs?v=office-short-v1';\r\nimport {OFFICE_REQUIRED_FIELDS,withOfficeDefaults} from './office-domain.mjs?v=office-short-v1';\r\nimport {mountOfficeAppearance} from './office-form.mjs?v=office-short-v1';\r\nconst node=(tag,text)=>{const e=document.createElement(tag);if(text)e.textContent=text;return e;};\r\nexport function mountOfficeQuickForm(host,initial,{save,label='Unlock my Coach',changed=()=>{}}){\r\n const data=withOfficeDefaults(initial),form=node('form');form.className='setup-form';\r\n const customizer=mountOfficeAppearance(form,data,{optional:true});\r\n const essentials=node('fieldset');essentials.append(node('legend','Six answers. One coach.'));\r\n const grid=node('div');grid.className='setup-fields';const controls=new Map();\r\n const keys=['goal','goalWeightLbs','experience','limits','sessionMinutes','coach'];\r\n keys.forEach((key,index)=>{\r\n  const field=FIELDS.find(f=>f.key===key),wrap=node('label',(index+1)+'. '+(field?.label||'Any injuries or movement limitations?'));let input;\r\n  if(key==='limits'){input=node('textarea');input.rows=2;input.maxLength=2000;input.name='armie.q3';input.value=data.answers.armie?.q3||'';input.placeholder='Write “none” if there are none.';}\r\n  else if(field.options){input=node('select');input.append(new Option('Choose…',''));for(const value of field.options)input.append(new Option(value[0].toUpperCase()+value.slice(1),value));input.value=data.profile[key]??'';}\r\n  else{input=node('input');input.type=field.type;input.min=field.min;input.max=field.max;input.step=key==='goalWeightLbs'?'0.1':'1';input.value=data.profile[key]??'';}\r\n  input.required=true;input.name||=key;controls.set(key,input);wrap.append(input);grid.append(wrap);\r\n });\r\n essentials.append(grid);form.append(essentials,customizer.banterLabel);\r\n const options=node('details');options.append(node('summary','Name & appearance (optional)'));\r\n const nameLabel=node('label','What should your coach call you?'),name=node('input');name.name='name';name.maxLength=60;name.value=data.profile.name==='You'?'':data.profile.name||'';name.placeholder='Optional';nameLabel.append(name);options.append(nameLabel,customizer.appearance);form.append(options);\r\n const targets=node('p');targets.className='setup-targets';\r\n const defaults=node('p','We’ll start with balanced coaching, gradual progression and 60-second rests. Choose movements and adjust any setting in Coach.');\r\n const status=node('p');status.role='status';const submit=node('button',label);submit.type='submit';submit.className='setup-submit';form.append(targets,defaults,status,submit);host.replaceChildren(form);\r\n function collect(){for(const key of OFFICE_REQUIRED_FIELDS){const input=controls.get(key);data.profile[key]=input.type==='number'?(input.value===''?null:Number(input.value)):input.value;}data.profile.name=name.value.trim();data.answers.armie??={};data.answers.armie.q3=controls.get('limits').value.trim();customizer.collect();return data;}\r\n function paint(){collect();const missing=missingFields(data);status.textContent=missing.length?`${missing.length} answer${missing.length===1?'':'s'} still needed. ${missing[0]}`:'Six answers filed. Your coach is ready.';submit.disabled=missing.length>0;const weight=data.profile.goalWeightLbs;targets.textContent=`Start at 3 reps and 9-second holds, adding 1 each day.${weight>0?` Daily targets: ${weight} g protein · ${weight} oz water.`:''}`;customizer.paint(missing.length,6);changed(structuredClone(data));}\r\n form.addEventListener('input',paint);form.addEventListener('change',paint);\r\n form.onsubmit=async event=>{event.preventDefault();collect();if(missingFields(data).length||!form.reportValidity()){paint();return;}submit.disabled=true;status.textContent='Filing your six answers…';try{await save(structuredClone(data));}catch(error){status.textContent=error.message;submit.disabled=false;}};\r\n paint();return {form,collect};\r\n}\r\n","office.css":".setup-route-choices{display:grid;grid-template-columns:1fr 1fr;gap:20px;margin:26px 0}.setup-route{display:flex;flex-direction:column;align-items:flex-start;padding:24px;border:2px solid #aa97bd;border-radius:16px}.setup-route h2{font-size:24px;margin:0}.setup-route p{flex:1}.setup-route.games{background:#312242}.setup-route.office{background:#e7e4db;color:#30312c;border:1px solid #8d8d7d;border-radius:0;font-family:'Courier New',monospace;box-shadow:4px 4px 0 #a19e92}.setup-route.office p{color:#41423b}.setup-route.office .setup-action{background:#d3d1c8;border:2px outset #f3f1e7;box-shadow:none;border-radius:0;color:#242720;font-family:inherit}.draft-notice{font-size:14px}\r\nbody.office-mode{color-scheme:light;background:#c9cbc3;color:#292d29;font-family:'Courier New',monospace}.office-mode .setup-shell{background:#f2f0e6;border:1px solid #92978d;border-top:16px solid #868d80;border-radius:0;box-shadow:8px 8px 0 #9ca295;padding:clamp(18px,4vw,38px)}.office-mode .setup-brand{color:#4f584f;font-size:14px;letter-spacing:1px;border-bottom:2px solid #535f50;padding-bottom:14px}.office-mode .setup-shell h1{font-size:clamp(26px,4vw,36px);letter-spacing:-1px}.office-mode .setup-shell p{color:#414a40}.office-mode fieldset,.office-mode details{border:1px solid #879080;border-radius:0;background:#faf9f1}.office-mode summary{color:#303b2c}.office-mode .setup-form label{font-size:16px}.office-mode .setup-form input,.office-mode .setup-form select,.office-mode .setup-form textarea{border:1px solid #818b78;background:#fffefa;color:#242c23;border-radius:0;font-family:inherit;font-size:16px;box-shadow:inset 1px 2px 0 #d9ddd2}.office-mode legend{text-transform:uppercase;letter-spacing:.5px;font-size:16px}.office-mode .setup-submit,.office-mode .setup-action{font-family:inherit;background:#d1d5c8;border:2px outset #f8f9f2;border-radius:0;box-shadow:none;color:#252f23}.office-mode .setup-submit{width:100%;text-transform:uppercase}.office-mode .setup-submit:disabled{opacity:.55}.office-mode .setup-targets{background:#e3e8da;border-left-color:#586b4b}.office-mode .office-check{display:flex;align-items:center;gap:12px}.office-mode .office-check input{width:24px;height:24px;flex:none;accent-color:#4f6344}.office-exit{margin:18px 0 24px}.office-exit .setup-action{font-size:14px;background:transparent;border:0;padding:0;text-decoration:underline;text-underline-offset:4px}.office-mode :focus-visible{outline-color:#305d32}\r\n.office-supervisor{position:sticky;top:8px;z-index:5;display:flex;align-items:center;gap:20px;background:#e3e7da;border:2px solid #7b8870;padding:18px;box-shadow:3px 4px 0 #9ea695;margin:24px 0}.office-supervisor strong{font-size:14px;letter-spacing:.4px}.office-supervisor p{font-size:16px;line-height:1.4;margin:8px 0 0}.office-mascot{width:80px;height:86px;flex:none;background:#816393;border:3px solid #493254;border-radius:40% 40% 22% 22%;position:relative;transform:rotate(-5deg);box-shadow:inset -10px -6px 0 #664977}.office-mascot:before,.office-mascot:after{content:'';position:absolute;width:16px;height:20px;border-radius:7px;background:#493254;bottom:-12px}.office-mascot:before{left:6px}.office-mascot:after{right:6px}.office-eye{position:absolute;left:16px;top:18px;width:42px;height:26px;background:#faf8dd;border:2px solid #3e2c43;border-radius:50%;overflow:hidden}.office-eye:before{content:'';position:absolute;left:14px;top:2px;width:13px;height:22px;border-radius:50%;background:#302b26}.office-eye:after{content:'';position:absolute;left:-3px;right:-3px;top:-2px;height:16px;background:#8d6c9e;border-bottom:3px solid #45304e}.office-mascot[data-eye=open] .office-eye:after{height:4px}.office-mascot[data-eye=wide] .office-eye:after{height:0;border:0}.office-mascot i{position:absolute;width:24px;height:3px;left:24px;bottom:18px;background:#38263d;transform:rotate(-8deg)}\r\n@media(max-width:600px){.setup-route-choices{grid-template-columns:1fr}.setup-route{padding:20px}.office-supervisor{padding:12px;gap:12px;top:4px}.office-supervisor strong{font-size:12px}.office-supervisor p{font-size:14px}.office-mascot{width:64px;height:72px}.office-eye{left:8px;top:12px}.office-mascot i{left:18px}.office-mode .setup-shell{padding:16px}.office-mode .setup-form label{font-size:16px}.office-mode .setup-fields{grid-template-columns:1fr}}\r\n","offline-install.mjs":"// Installation is ready only after the worker has saved the core offline app.\r\nexport async function prepareOfflineApp(serviceWorker=globalThis.navigator?.serviceWorker){\r\n if(!serviceWorker)throw Error('This browser cannot save Coach on this device. Open the installer in Chrome, Edge, or Safari.');\r\n const registration=await serviceWorker.register('/sw.js',{updateViaCache:'none'});\r\n const worker=registration.installing||registration.waiting||registration.active;\r\n if(!worker)throw Error('Coach could not finish downloading. Reconnect and retry.');\r\n await new Promise((resolve,reject)=>{\r\n  function check(){\r\n   if(['installed','activating','activated'].includes(worker.state)){worker.removeEventListener('statechange',check);resolve();}\r\n   else if(worker.state==='redundant'){worker.removeEventListener('statechange',check);reject(Error('Coach could not be saved. Check your connection and free space, then retry.'));}\r\n  }\r\n  worker.addEventListener('statechange',check);check();\r\n });\r\n return registration;\r\n}\r\n","onboarding-domain.mjs":"import {SITE_QUESTIONS} from './onboarding-questions.mjs';\r\nimport {OFFICE_REQUIRED_FIELDS,withOfficeDefaults} from './office-domain.mjs?v=office-short-v1';\r\nimport {QUICK_REQUIRED_FIELDS,withQuickDefaults} from './quick-setup.mjs';\r\nimport {EYE_STYLE_IDS} from './eye-styles.mjs';\r\nexport {SITE_QUESTIONS};\r\nexport const WEBSITE='https://mominc.online';\r\nexport const COACH_APP='https://myr5.mominc.online';\r\nexport const COACHES=['supportive','direct','analytical','playful','calm','mom'];\r\nexport const EXERCISES={squat:'Squats',pushup:'Push-ups',tree:'Tree pose',warrior:'Warrior II',horse:'Horse stance',boxing:'Air boxing',jogging:'Jogging in place',jumping:'Jumps'};\r\nexport const FIELDS=[\r\n {key:'name',label:'What should your coach call you?',max:60},\r\n {key:'goalWeightLbs',label:'Goal weight (lb)',type:'number',min:1,max:1500},\r\n {key:'goal',label:'Your main training goal',options:['Build a routine','Build strength','Improve mobility and balance','Improve stamina','Manage weight']},\r\n {key:'experience',label:'Current training experience',options:['New to training','Returning to training','Training regularly']},\r\n {key:'coach',label:'Coach personality',options:COACHES},\r\n {key:'trainingStyle',label:'How should your coach guide training?',options:['Controlled reps','Gradual progression','Technique first']},\r\n {key:'guidance',label:'How much should your coach talk?',options:['Quiet','Balanced','Detailed']},\r\n {key:'sessionMinutes',label:'Minutes available per session',type:'number',min:1,max:180},\r\n {key:'restSeconds',label:'Rest between sets',options:['30','45','60','90','120','180']},\r\n {key:'trainingTime',label:'Usual training time',type:'time'},\r\n {key:'timezone',label:'Time zone'},\r\n {key:'reminderTone',label:'Reminder wording',options:['gentle','direct','cheeky']},\r\n {key:'reminderDays',label:'Reminder days per week',options:['1','3','5','7']},\r\n {key:'foodPreference',label:'Food preference',options:['Everything','Vegetarian','Vegan','Other preference']},\r\n {key:'foodLimits',label:'Food allergies or restrictions (write “none” if there are none)',max:600},\r\n];\r\nconst object=v=>v&&typeof v==='object'&&!Array.isArray(v);\r\nconst validText=(v,max=600)=>typeof v==='string'&&v.trim().length>0&&v.length<=max;\r\n// Rank 4: a region may also carry a decoupled texture+colour choice (see design.ts's\r\n// MaterialChoice/parseRecipe, which this mirrors). Optional and additive - old recipes\r\n// without it, and recipes that only ever used it on some regions, both stay valid.\r\nconst validMaterialChoice=v=>object(v)&&typeof v.textureId==='string'&&typeof v.colorId==='string'&&Number.isFinite(v.sparkle)&&v.sparkle>=0&&v.sparkle<=1&&Number.isFinite(v.metallic)&&v.metallic>=0&&v.metallic<=1;\r\nconst validMaterials=m=>m===undefined||(object(m)&&Object.entries(m).every(([k,v])=>['head','eye','collar','body','arms','feet'].includes(k)&&validMaterialChoice(v)));\r\nexport function validRecipe(r){return object(r)&&r.version===1&&object(r.styles)&&['head','eye','collar','body','arms','feet'].every(k=>Number.isInteger(r.styles[k])&&r.styles[k]>=0&&r.styles[k]<23)&&COACHES.includes(r.coach)&&EYE_STYLE_IDS.includes(r.eye)&&Number.isFinite(r.fur)&&r.fur>=.65&&r.fur<=1.4&&Number.isFinite(r.iris)&&r.iris>=.7&&r.iris<=1.25&&['round','vertical','horizontal','oval','diamond','star','heart','cross'].includes(r.pupil??'round')&&Number.isFinite(r.pupilSize??1)&&(r.pupilSize??1)>=.6&&(r.pupilSize??1)<=1.15&&Number.isFinite(r.detail??1)&&(r.detail??1)>=.5&&(r.detail??1)<=1.5&&Number.isInteger(r.fingers??4)&&(r.fingers??4)>=2&&(r.fingers??4)<=6&&Number.isInteger(r.toes??3)&&(r.toes??3)>=1&&(r.toes??3)<=6&&['single','horizontal','vertical','frontBack','triangle','around','spider','square'].includes(r.eyeLayout??'single')&&validMaterials(r.materials);}\r\nexport function missingFields(v){\r\n const missing=[];if(!object(v))return ['Complete your coach setup'];if(!['games','office'].includes(v.entryRoute??'games'))return ['Choose games or the office form'];const office=v.entryRoute==='office',quick=v.setupMode==='quick';\r\n if(quick){if(v.profile!=null&&!object(v.profile)||v.answers!=null&&!object(v.answers)||v.appearance!=null&&!object(v.appearance))return ['Choose a valid coach profile'];v=withQuickDefaults(v);}\r\n if(office){if(v.profile!=null&&!object(v.profile)||v.answers!=null&&!object(v.answers)||v.appearance!=null&&!object(v.appearance))return ['Choose a valid coach profile'];v=withOfficeDefaults(v);}\r\n const p=v.profile||{};\r\n for(const f of FIELDS){const a=p[f.key];if((quick?!QUICK_REQUIRED_FIELDS.includes(f.key):office&&!OFFICE_REQUIRED_FIELDS.includes(f.key))&&(a==null||typeof a==='string'&&!a.trim()))continue;if(f.type==='number'?typeof a!=='number'||!Number.isFinite(a)||a<f.min||a>f.max:f.options?!f.options.includes(String(a)):f.type==='time'?!/^([01]\\d|2[0-3]):[0-5]\\d$/.test(a||''):!validText(a,f.max||160))missing.push(f.label);}\r\n try{if(!p.timezone)throw Error();new Intl.DateTimeFormat('en',{timeZone:p.timezone}).format();}catch{if(!missing.includes('Time zone'))missing.push('Time zone');}\r\n if(!Array.isArray(p.exercises)||!p.exercises.length||p.exercises.some(k=>!Object.hasOwn(EXERCISES,k)))missing.push('Choose at least one movement');\r\n for(const group of SITE_QUESTIONS)for(let i=0;i<group.questions.length;i++){const a=v.answers?.[group.id]?.['q'+(i+1)],required=!quick&&(!office||group.id==='armie'&&i===2);if(!required&&(a==null||typeof a==='string'&&!a.trim()))continue;if(!validText(a,2000))missing.push(group.questions[i]);}\r\n if(!validRecipe(v.appearance?.['myr5-recipe-v1']))missing.push('Save your customized coach');\r\n if(v.customizationConfirmed!==true)missing.push('Confirm your coach appearance');\r\n if((v.entryRoute??'games')==='games'&&v.armieCompleted!==true)missing.push('Finish Coach Armie');\r\n if(v.entryRoute==='office'&&typeof v.officeBanter!=='boolean')missing.push('Choose your paperwork banter setting');\r\n return missing;\r\n}\r\nexport function validateOnboarding(v){\r\n const missing=missingFields(v);if(missing.length)throw Object.assign(Error('Complete your coach setup: '+missing[0]),{status:400,missing});\r\n if(v.setupMode==='quick')v=withQuickDefaults(v);else if(v.entryRoute==='office')v=withOfficeDefaults(v);\r\n const profile=Object.fromEntries(FIELDS.map(f=>[f.key,typeof v.profile[f.key]==='string'?v.profile[f.key].trim():v.profile[f.key]]));\r\n profile.exercises=[...new Set(v.profile.exercises)];\r\n const answers=Object.fromEntries(SITE_QUESTIONS.map(g=>[g.id,Object.fromEntries(g.questions.map((_,i)=>['q'+(i+1),(v.answers?.[g.id]?.['q'+(i+1)]??'').trim()]))]));\r\n const appearance={};for(const k of ['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1'])if(v.appearance[k]!=null){if(!object(v.appearance[k])||JSON.stringify(v.appearance[k]).length>30000)throw Object.assign(Error('Choose a valid saved appearance.'),{status:400});appearance[k]=v.appearance[k];}\r\n appearance['myr5-recipe-v1'].coach=profile.coach;\r\n const context=object(v.siteChoices)?v.siteChoices:{};if(JSON.stringify(context).length>20000)throw Object.assign(Error('The website choices are too large.'),{status:400});\r\n const entryRoute=v.entryRoute??'games';\r\n return {version:1,...(v.setupMode==='quick'?{setupMode:'quick'}:{}),profile,answers,appearance,siteChoices:context,entryRoute,officeBanter:entryRoute==='office'&&v.officeBanter===true,armieCompleted:entryRoute==='games',customizationConfirmed:true};\r\n}\r\nexport function calendarDay(now,timezone){const p=Object.fromEntries(new Intl.DateTimeFormat('en-CA',{timeZone:timezone,year:'numeric',month:'2-digit',day:'2-digit'}).formatToParts(new Date(now)).map(x=>[x.type,x.value]));return `${p.year}-${p.month}-${p.day}`;}\r\nexport function dailyTargets(profile,startDay,now=Date.now()){\r\n const today=calendarDay(now,profile.timezone),elapsed=Math.max(0,Math.round((Date.parse(today+'T00:00:00Z')-Date.parse(startDay+'T00:00:00Z'))/86400000));\r\n const reps=3+elapsed,holdSeconds=9+elapsed;\r\n return {day:elapsed+1,date:today,reps,holdSeconds,proteinGrams:profile.goalWeightLbs??null,waterOz:profile.goalWeightLbs??null,goals:Object.fromEntries(Object.keys(EXERCISES).map(k=>[k,['tree','warrior','horse','boxing'].includes(k)?holdSeconds:reps]))};\r\n}\r\nexport function encodeHandoff(v){const bytes=new TextEncoder().encode(JSON.stringify(v));if(bytes.length>55000)throw Error('Your profile is too large to transfer. Shorten long answers and try again.');let s='';for(const b of bytes)s+=String.fromCharCode(b);return btoa(s).replaceAll('+','-').replaceAll('/','_').replace(/=+$/,'');}\r\nexport function decodeHandoff(raw){if(typeof raw!=='string'||raw.length>75000||!/^[A-Za-z0-9_-]+$/.test(raw))throw Error('This coach transfer could not be read. Return to the website and open Coach again.');return JSON.parse(new TextDecoder().decode(Uint8Array.from(atob(raw.replaceAll('-','+').replaceAll('_','/')),c=>c.charCodeAt(0))));}\r\n","onboarding-form.mjs":"import {FIELDS,SITE_QUESTIONS,EXERCISES,missingFields,dailyTargets,calendarDay} from './onboarding-domain.mjs?v=quick-install-v1';\r\nimport {mountOfficeQuickForm} from './office-quick-form.mjs?v=office-short-v1';\r\nimport {OFFICE_SECTIONS,OFFICE_REQUIRED_FIELDS,withOfficeDefaults} from './office-domain.mjs?v=office-short-v1';\r\nimport {mountOfficeAppearance} from './office-form.mjs?v=office-short-v1';\r\nimport {mountQuickSetup} from './quick-setup-form.mjs';\r\nimport {QUICK_REQUIRED_FIELDS} from './quick-setup.mjs';\r\nconst node=(tag,text)=>{const e=document.createElement(tag);if(text)e.textContent=text;return e;};\r\nexport function mountProfileForm(host,initial,{save,label='Unlock my Coach app',changed=()=>{},fullSettings=false}){\r\n if(!fullSettings)return mountQuickSetup(host,initial,{save,label,changed});\r\n const data=initial.entryRoute==='office'?withOfficeDefaults(initial):structuredClone(initial);data.profile??={};data.answers??={};const form=node('form');form.className='setup-form';const status=node('p');status.role='status';const sections=[];const office=data.entryRoute==='office',quick=data.setupMode==='quick',customizer=office?mountOfficeAppearance(form,data):null;\r\n const basics=node('fieldset'),legend=node('legend',office?'Training':'Training');basics.append(legend);const grid=node('div');grid.className='setup-fields';\r\n for(const field of FIELDS){const wrap=node('label',field.label);let input;if(field.options){input=node('select');input.append(new Option('Choose…',''));for(const value of field.options)input.append(new Option(value[0].toUpperCase()+value.slice(1),value));}else{input=node('input');input.type=field.type||'text';if(field.min!=null){input.min=field.min;input.max=field.max;input.step=field.key==='goalWeightLbs'?'0.1':'1';}input.maxLength=field.max||160;}input.name=field.key;input.required=quick?QUICK_REQUIRED_FIELDS.includes(field.key):!office||OFFICE_REQUIRED_FIELDS.includes(field.key);input.value=data.profile[field.key]??'';wrap.append(input);grid.append(wrap);}\r\n basics.append(grid);const movement=node('fieldset');movement.append(node('legend','Starting movements'));const choices=node('div');choices.className='setup-choices';for(const [key,label] of Object.entries(EXERCISES)){const l=node('label'),i=node('input');i.type='checkbox';i.name='exercises';i.value=key;i.checked=data.profile.exercises?.includes(key)||false;l.append(i,document.createTextNode(label));choices.append(l);}movement.append(choices,node('p','Choose what fits your space and limits.'));basics.append(movement);form.append(basics);\r\n for(const group of SITE_QUESTIONS){const details=node('details'),summary=node('summary',group.title);details.append(summary);for(let i=0;i<group.questions.length;i++){const name='q'+(i+1),label=node('label',group.questions[i]),input=node('textarea');input.name=group.id+'.'+name;input.rows=2;input.maxLength=2000;input.required=(!office&&!quick)||group.id==='armie'&&name==='q3';input.value=data.answers[group.id]?.[name]||'';label.append(input);details.append(label);}sections.push({group,details,summary});form.append(details);}\r\n if(customizer)form.append(customizer.appearance);const targets=node('p');targets.className='setup-targets';form.append(targets,node('p',''));\r\n const submit=node('button',label);submit.type='submit';submit.className='setup-submit';form.append(status,submit);host.replaceChildren(form);\r\n function collect(){for(const f of FIELDS){const value=form.elements.namedItem(f.key).value;data.profile[f.key]=f.type==='number'?(value===''?null:Number(value)):value;}data.profile.exercises=[...form.querySelectorAll('[name=exercises]:checked')].map(e=>e.value);for(const g of SITE_QUESTIONS){data.answers[g.id]??={};for(let i=0;i<g.questions.length;i++)data.answers[g.id]['q'+(i+1)]=form.elements.namedItem(g.id+'.q'+(i+1)).value.trim();}customizer?.collect();return data;}\r\n function paint(){collect();const missing=missingFields(data);status.textContent=missing.length?`${missing.length} answer${missing.length===1?'':'s'} still needed. ${missing[0]}`:'Ready';submit.disabled=missing.length>0;for(const {group,details,summary} of sections){const n=office||quick?(group.id==='armie'&&!data.answers.armie.q3?.trim()?1:0):group.questions.filter((_,i)=>!data.answers[group.id]['q'+(i+1)]?.trim()).length;summary.textContent=(office?OFFICE_SECTIONS[group.id]:group.title)+((office||quick)&&group.id!=='armie'?' · Optional':n?` · ${n} to answer`:' · Complete');if(n)details.open=true;}try{const t=dailyTargets(data.profile,calendarDay(Date.now(),data.profile.timezone));targets.textContent=`Day 1: 3 reps · 9-second holds. ${t.proteinGrams?`Daily targets: ${t.proteinGrams} g protein · ${t.waterOz} oz water.`:'Weight-based targets are optional.'}`;}catch{targets.textContent='Day 1: 3 reps · 9-second holds.';}customizer?.paint(missing.length,FIELDS.length+SITE_QUESTIONS.reduce((n,g)=>n+g.questions.length,0)+2);changed(structuredClone(data));}\r\n form.addEventListener('input',paint);form.addEventListener('change',paint);form.addEventListener('invalid',e=>{const details=e.target.closest('details');if(details)details.open=true;},true);\r\n form.onsubmit=async e=>{e.preventDefault();collect();if(missingFields(data).length||!form.reportValidity()){paint();return;}submit.disabled=true;status.textContent='Saving your coach…';try{await save(structuredClone(data));}catch(error){status.textContent=error.message;submit.disabled=false;}};paint();return {form,collect};\r\n}\r\n","onboarding-questions.mjs":"// Coach questions from the character-site manifest. Preserve their q1/q2/q3 keys.\r\nexport const SITE_QUESTIONS=[\r\n  {\r\n    \"id\": \"fuel\",\r\n    \"title\": \"DRINKS\",\r\n    \"questions\": [\r\n      \"How does caffeine usually hit you: fine, jittery, anxious, sleepless, or you do not use it?\",\r\n      \"Which supplements do you already take, if any?\",\r\n      \"When do you usually train: morning, afternoon, evening, or it moves around?\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"goon\",\r\n    \"title\": \"GOON\",\r\n    \"questions\": [\r\n      \"Who, if anyone, supports what you are trying to do?\",\r\n      \"Should the coach involve them, remind you about them, or keep the plan between you and the coach?\",\r\n      \"When do you reliably have help, company or accountability?\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"lilboyfriend\",\r\n    \"title\": \"LIL BOYFRIEND\",\r\n    \"questions\": [\r\n      \"Where would you usually train: home, gym, outdoors, somewhere else, or not sure yet?\",\r\n      \"How much clear floor space do you actually have?\",\r\n      \"What equipment is available to you right now? None is a complete answer.\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"djscratch\",\r\n    \"title\": \"DJ SCRATCH\",\r\n    \"questions\": [\r\n      \"What reliably gets you to start: a deadline, a person, music, a checklist, a joke, or something else?\",\r\n      \"How should your coach speak to you: direct, calm, warm, funny, quiet, or a mix?\",\r\n      \"What should your coach never say to you?\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"corgi\",\r\n    \"title\": \"CORTISOL CORGI\",\r\n    \"questions\": [\r\n      \"How many hours do you usually sleep on a normal night?\",\r\n      \"How heavy is your stress load this week: light, manageable, heavy, or prefer not to say?\",\r\n      \"How much news do you take in on a normal day: none, under 30 minutes, 30 to 90 minutes, or more?\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"girlfriend\",\r\n    \"title\": \"DR GIRLFRIEND\",\r\n    \"questions\": [\r\n      \"What health or fitness advice do you already believe?\",\r\n      \"Where did that advice come from?\",\r\n      \"How confident are you checking a claim against its original source: not yet, sometimes, usually, or very?\"\r\n    ]\r\n  },\r\n  {\r\n    \"id\": \"armie\",\r\n    \"title\": \"COACH ARMIE\",\r\n    \"questions\": [\r\n      \"What movement do you do in a normal week right now?\",\r\n      \"What movement have you done before, even if you stopped?\",\r\n      \"Any injury, pain, disability or other limit the coach should work around? This is context, not a diagnosis.\"\r\n    ]\r\n  }\r\n];\r\n","onboarding.css":":root{color-scheme:dark;font-family:Arial,sans-serif;background:#160f23;color:#f3eee1}*{box-sizing:border-box}body{margin:0;padding:clamp(12px,4vw,48px);background:radial-gradient(ellipse at top,#49325c,#160f23 70%);min-height:100vh}.setup-shell{max-width:880px;margin:auto;border:8px solid #574738;border-radius:28px;padding:clamp(18px,4vw,38px);background:linear-gradient(140deg,#292334,#15121b);box-shadow:inset 0 3px 2px #ac9671,0 14px 0 #171110,0 24px 60px #0009}.setup-brand{color:#c9b589;font-size:12px;letter-spacing:3px}.setup-shell h1{font-size:clamp(26px,5vw,42px);margin:.5em 0}.setup-shell p{line-height:1.6;color:#cfc6d5}a{color:#bdeada}.setup-form label{display:grid;gap:8px;font-size:14px;margin:16px 0}.setup-form input,.setup-form select,.setup-form textarea{font:inherit;color:#fff;background:#14131a;border:2px solid #716777;border-radius:8px;padding:12px;width:100%;max-width:100%}.setup-fields{display:grid;grid-template-columns:1fr 1fr;gap:0 22px}fieldset{border:1px solid #7f728b;border-radius:12px;margin:24px 0;padding:18px}legend{font-weight:700;padding:0 9px}details{border:1px solid #6a5b75;border-radius:10px;padding:16px;margin:15px 0}summary{cursor:pointer;font-weight:700;color:#dcceac}.setup-choices{display:grid;grid-template-columns:1fr 1fr;gap:6px 20px}.setup-choices label{display:flex;align-items:center;margin:6px 0}.setup-choices input{width:22px;height:22px;accent-color:#d7c6a2}.setup-submit,.setup-action{display:inline-block;background:linear-gradient(#eddfb9,#bbaa7c);border:2px solid #f5e8c2;color:#201a24;border-radius:12px;padding:16px 23px;box-shadow:0 5px 0 #615039;font:700 16px Arial;cursor:pointer;text-decoration:none}.setup-submit:disabled{opacity:.5;cursor:default}.setup-submit:active,.setup-action:active{transform:translateY(3px);box-shadow:0 2px 0 #615039}.setup-targets{border-left:4px solid #a8d9ba;padding:16px;background:#172720}input:focus-visible,select:focus-visible,textarea:focus-visible,button:focus-visible,a:focus-visible,summary:focus-visible{outline:3px solid #9ce1cb;outline-offset:4px}[hidden]{display:none!important}@media(max-width:600px){.setup-fields{grid-template-columns:1fr}.setup-shell{border-width:5px}fieldset{padding:12px}.setup-submit{width:100%}}\r\n\r\n.quick-mode .setup-shell{max-width:480px}.quick-mode .setup-brand{font-size:14px;letter-spacing:1px}.quick-mode .setup-shell h1{font-size:1.75rem}.quick-setup label{font-size:1rem}.quick-setup textarea{resize:vertical}.quick-setup .setup-submit{width:100%;margin-top:8px}.draft-notice:empty{display:none}\r\n","onboarding.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><meta name=\"referrer\" content=\"no-referrer\"><title>Start your Coach</title><link rel=\"stylesheet\" href=\"/onboarding.css\"><link rel=\"stylesheet\" href=\"/office.css\"></head><body><main class=\"setup-shell\"><div class=\"setup-brand\">MOM INC / COACH ACTIVATION</div><h1>Set up Coach</h1><p id=\"setupStatus\" role=\"status\">Loading…</p><div id=\"setupBody\"></div></main><script type=\"module\" src=\"/onboarding.mjs?v=quick-install-v2\"></script></body></html>\r\n","onboarding.mjs":"import {authTransitions} from './auth-transition.mjs';\r\nimport {createAccountSessionActions} from './account-session-actions.mjs';\r\nimport {signInPath} from './auth-paths.mjs';\r\nimport {authFetch} from './auth-client.mjs';\r\nimport {setupAllowed} from './install-context.mjs';\r\nimport {restoreInstall} from './install-transfer.mjs';\r\nimport {withQuickDefaults} from './quick-setup.mjs';\r\nimport {receiveCoach} from './receive-coach.mjs';\r\nimport {readIncomingCoach,saveIncomingCoach,clearIncomingCoach} from './pending-coach.mjs';\r\nimport {decodeHandoff,missingFields,WEBSITE,calendarDay} from './onboarding-domain.mjs?v=quick-install-v1';\r\nimport {mountProfileForm} from './onboarding-form.mjs?v=quick-install-v1';\r\nimport {createOfficeDraft} from './office-domain.mjs?v=office-short-v1';\r\nimport {openLocalCoach,probeOptionalAccount,probeOptionalTransfer} from './local-coach-runtime.mjs';\r\nconst status=document.getElementById('setupStatus'),host=document.getElementById('setupBody'),title=document.querySelector('h1');\r\nconst KEY='myr5-incoming-coach-v1',OFFICE_KEY='myr5-office-draft-v1',params=new URLSearchParams(location.search);\r\nlet account=null,localCoach=null,localScope=null,localIntake=null;\r\nconst transitions=authTransitions(),accountActions=createAccountSessionActions({api,transitions});\r\nasync function api(path,method='GET',data,assertions={},signal){const ticket=transitions.capture();const r=await authFetch(path,{method,guestSkip:method==='GET'&&/^\\/api\\/(?:account\\?core=1|updates\\/subscription)$/.test(path),signal:signal?AbortSignal.any([ticket.signal,signal]):ticket.signal,credentials:'same-origin',headers:{...(data?{'Content-Type':'application/json'}:{}),...assertions},body:data?JSON.stringify(data):undefined,cache:'no-store'});transitions.assertCurrent(ticket);if(!r.headers.get('content-type')?.includes('application/json'))throw Object.assign(Error(r.status>=500?'Coach service is unavailable. Please retry.':'Sign in to save your coach.'),{status:r.status});const value=await r.json();transitions.assertCurrent(ticket);if(!r.ok)throw Object.assign(Error(value.error||'Could not save. Please retry.'),{status:r.status,code:value.code});return value;}\r\nfunction link(text,href,parent=host){const a=document.createElement('a');a.className='setup-action';a.textContent=text;a.href=href;a.target='_top';parent.append(a);return a;}\r\nfunction readDraft(key){try{return JSON.parse(sessionStorage.getItem(key)||'null');}catch{return null;}}\r\nfunction removeDraft(key){try{sessionStorage.removeItem(key);}catch{}}\r\nfunction restore(appearance){for(const [key,v] of Object.entries(appearance||{}))if(['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1'].includes(key))localStorage.setItem(key,typeof v==='string'?v:JSON.stringify(v));}\r\nfunction signIn(returnTo){return signInPath(returnTo);}\r\nfunction chooseRoute(){\r\n title.textContent='Set up Coach';\r\n status.textContent='Choose your route.';\r\n const choices=document.createElement('div');choices.className='setup-route-choices';\r\n for(const route of [\r\n  {theme:'games',heading:'Play the character games',description:'Meet the crew. Build your coach.',label:'Take the fun route',href:WEBSITE+'/tv/?ch=mominc'},\r\n  {theme:'office',heading:'Quick setup',description:'Three questions.',label:readDraft(OFFICE_KEY)?'Resume my paperwork':'Start setup',href:'/onboarding.html?route=office'}\r\n ]){const card=document.createElement('section');card.className='setup-route '+route.theme;const h=document.createElement('h2'),p=document.createElement('p');h.textContent=route.heading;p.textContent=route.description;card.append(h,p);link(route.label,route.href,card);choices.append(card);}\r\n host.replaceChildren(choices);\r\n if(!account)link('Already have a coach? Sign in',signIn('/onboarding.html'));\r\n}\r\nasync function renderForm(data,{edit=false,autoSave=false}={}){\r\n const displayedAccount=account;\r\n if(!edit)data=withQuickDefaults(data);\r\n const office=data.entryRoute==='office',draftKey=office?OFFICE_KEY:KEY;\r\n document.body.classList.toggle('office-mode',office&&edit);document.body.classList.toggle('quick-mode',!edit);\r\n title.textContent=edit?'Settings':'Set up Coach';\r\n status.textContent=edit?'':office?'':'';\r\n const formHost=document.createElement('div'),notice=document.createElement('p');notice.role='status';notice.className='draft-notice';\r\n host.replaceChildren();\r\n\r\n\r\n host.append(formHost,notice);\r\n function remember(value){if(edit)return;try{if(office)sessionStorage.setItem(draftKey,JSON.stringify(value));else saveIncomingCoach(value);notice.textContent='';}catch{notice.textContent='Your browser cannot save a draft. Keep this page open and sign in before completing the form.';}}\r\n async function save(value){\r\n   if(!displayedAccount){const result=await localScope.saveSetup(value,{startDay:calendarDay(Date.now(),value.profile.timezone)});restore(result.intake.appearance);clearIncomingCoach();removeDraft(KEY);removeDraft(OFFICE_KEY);location.replace('/pose.html');return;}\r\n  const saved=await accountActions.saveOnboarding(displayedAccount,value);transitions.assertCurrent(saved.transitionTicket);\r\n  try{\r\n  const currentOwner = localStorage.getItem('myr5-coach-owner');\r\n  let priorSnap = {};\r\n  if (currentOwner === saved.ownerId) {\r\n    const raw = localStorage.getItem('myr5-synced-appearance');\r\n    if (raw) {\r\n      try{\r\n        const parsed = JSON.parse(raw);\r\n        if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) priorSnap = parsed;\r\n      }catch(e){/* ignore corrupt baseline */}\r\n    }\r\n  }\r\n  const canonicalKeys = ['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1','myr5-pod-power-v1','handborne-recipe-v4','mbs-dj-identity-v1'];\r\n  const merged = {};\r\n  for(const k of canonicalKeys){\r\n    const snapVal = priorSnap[k];\r\n    if(typeof snapVal==='string') merged[k]=snapVal;\r\n\r\n\r\n  }\r\n  const overrideKeys = ['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1'];\r\n  const appearance = saved.result.appearance;\r\n  if (appearance && typeof appearance === 'object') {\r\n    for(const k of overrideKeys){\r\n      if (appearance[k] != null) {\r\n        merged[k] = typeof appearance[k] === 'object' ? JSON.stringify(appearance[k]) : appearance[k];\r\n      }\r\n    }\r\n  }\r\n  const final = Object.fromEntries(canonicalKeys.filter(k => typeof merged[k]==='string').map(k=>[k, merged[k]]));\r\n  localStorage.setItem('myr5-synced-appearance',JSON.stringify(final));\r\n  restore(saved.result.appearance);\r\n  localStorage.setItem('myr5-coach-owner',saved.ownerId);\r\n}catch{}\r\n  clearIncomingCoach();removeDraft(KEY);removeDraft(OFFICE_KEY);location.replace('/pose.html');\r\n }\r\n if(autoSave&&!missingFields(withQuickDefaults(data)).length){status.textContent=office?'Saving…':'Saving…';try{await save(data);return;}catch(e){status.textContent=e.message;}}\r\n  mountProfileForm(formHost,data,{save,label:edit?'Save settings':'Start my coach',changed:remember,fullSettings:edit});\r\n if(edit)link('Back to Coach','/pose.html');\r\n}\r\ntry{\r\n let incoming=readIncomingCoach();\r\n const raw=new URLSearchParams(location.hash.slice(1)).get('coach');\r\n if(raw){incoming=saveIncomingCoach(decodeHandoff(raw));history.replaceState(null,'',location.pathname+location.search);}\r\n if(params.get('receive')==='1'&&!incoming){status.textContent='Bringing your saved website choices aboard…';incoming=await receiveCoach(raw=>saveIncomingCoach(raw));}\r\n account=await probeOptionalAccount(({signal})=>api('/api/account?core=1','GET',undefined,{},signal));\r\n localCoach=await openLocalCoach();try{localScope=localCoach.forOwner(localCoach.guestOwnerId);localIntake=await localScope.getIntake();}catch(error){localCoach.close();localCoach=null;throw error;}window.addEventListener('pagehide',()=>localCoach?.close(),{once:true});\r\n const edit=params.get('edit')==='1',office=params.get('route')==='office';\r\n if(!edit&&!setupAllowed()&&!account?.onboarding){location.replace('/install.html'+(office?'?route=office':''));}else{\r\n if(setupAllowed()&&!edit&&!raw)incoming=(account?await restoreInstall():await probeOptionalTransfer(({signal})=>restoreInstall(fetch,sessionStorage,localStorage,{signal})))||incoming;\r\n if(edit){\r\n   if(!account&&!localIntake){status.textContent='Set up your coach on this device first.';link('Set up Coach','/onboarding.html');}\r\n   else if(!account){await renderForm(structuredClone(localIntake),{edit:true});}\r\n  else if(!account.onboarding)chooseRoute();\r\n  else {const data=structuredClone(account.onboarding.data);for(const key of ['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1'])if(account.profile[key])data.appearance[key]=JSON.parse(account.profile[key]);data.profile.coach=data.appearance['myr5-recipe-v1'].coach;await renderForm(data,{edit:true});}\r\n }else if(incoming&&!office){await renderForm(incoming,{autoSave:!!account});}\r\n  else if(account?.onboarding){try{restore(account.profile);}catch{}location.replace('/pose.html');}\r\n  else if(localIntake){try{restore(localIntake.appearance);}catch{}location.replace('/pose.html');}\r\n else if(office){let data=readDraft(OFFICE_KEY);if(data?.entryRoute!=='office')data=createOfficeDraft(Intl.DateTimeFormat().resolvedOptions().timeZone);await renderForm(data,{autoSave:params.get('submit')==='1'&&!!account});}\r\n else if(setupAllowed()){const draft=readDraft(OFFICE_KEY);await renderForm(draft?.entryRoute==='office'?draft:createOfficeDraft(Intl.DateTimeFormat().resolvedOptions().timeZone));}\r\n else chooseRoute();\r\n }\r\n}catch(e){status.textContent=e.message;link('Retry coach setup','/onboarding.html');}\r\n","package-lock.json":"{\r\n  \"name\": \"myr5-coach\",\r\n  \"version\": \"1.0.0\",\r\n  \"lockfileVersion\": 3,\r\n  \"requires\": true,\r\n  \"packages\": {\r\n    \"\": {\r\n      \"name\": \"myr5-coach\",\r\n      \"version\": \"1.0.0\",\r\n      \"dependencies\": {\r\n        \"@block65/webcrypto-web-push\": \"^2.0.0\",\r\n        \"@clerk/backend\": \"^3.17.2\",\r\n        \"dexie\": \"^4.4.6\",\r\n        \"three\": \"^0.169.0\",\r\n        \"zod\": \"^4.6.5\"\r\n      },\r\n      \"devDependencies\": {\r\n        \"@huggingface/transformers\": \"^3.8.1\",\r\n        \"@openai/sites-vite-plugin\": \"0.2.0\",\r\n        \"drizzle-kit\": \"0.31.4\",\r\n        \"drizzle-orm\": \"0.44.2\",\r\n        \"esbuild\": \"0.28.0\",\r\n        \"fake-indexeddb\": \"^6.2.5\",\r\n        \"meshoptimizer\": \"^1.3.0\",\r\n        \"miniflare\": \"4.20260515.0\",\r\n        \"playwright\": \"^1.63.0\",\r\n        \"shaders\": \"4.0.4\",\r\n        \"vite\": \"8.0.13\",\r\n        \"wrangler\": \"4.92.0\"\r\n      }\r\n    },\r\n    \"node_modules/@block65/webcrypto-web-push\": {\r\n      \"version\": \"2.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@block65/webcrypto-web-push/-/webcrypto-web-push-2.0.0.tgz\",\r\n      \"integrity\": \"sha512-BMrw8hABq5krABWPy3zFJvBC73HeRkyT/GTZ2AD7wqzo9hd9vO56MstBqjGMIxIw3e4lbRUbYxgihCcfhoTI2g==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"uint8array-extras\": \"^1.5.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@clerk/backend\": {\r\n      \"version\": \"3.17.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@clerk/backend/-/backend-3.17.2.tgz\",\r\n      \"integrity\": \"sha512-pQz/+ClFBcL4OijAX3gDcXQYNqr1JbabAqY8szuU8/Dcvuuk3WgUmQDGyIU0tIqmitdd17RLppDmhN088pADew==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@clerk/shared\": \"^4.31.1\",\r\n        \"standardwebhooks\": \"^1.0.0\",\r\n        \"tslib\": \"2.8.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20.9.0\"\r\n      }\r\n    },\r\n    \"node_modules/@clerk/shared\": {\r\n      \"version\": \"4.31.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@clerk/shared/-/shared-4.31.1.tgz\",\r\n      \"integrity\": \"sha512-j3cDEZ/j7r5tAv4mmo2JhpFRtL1z0JghjCgvBJjZSR6Q4ZVIlwd2Bv0loM+opKReeN17H30u1/WHEBl7pZuxrw==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@tanstack/query-core\": \"^5.101.4\",\r\n        \"dequal\": \"2.0.3\",\r\n        \"glob-to-regexp\": \"0.4.1\",\r\n        \"js-cookie\": \"3.0.8\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20.9.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0\",\r\n        \"react-dom\": \"^18.0.0 || ~19.0.3 || ~19.1.4 || ~19.2.3 || ~19.3.0-0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"react\": {\r\n          \"optional\": true\r\n        },\r\n        \"react-dom\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/kv-asset-handler\": {\r\n      \"version\": \"0.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz\",\r\n      \"integrity\": \"sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/unenv-preset\": {\r\n      \"version\": \"2.16.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz\",\r\n      \"integrity\": \"sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"peerDependencies\": {\r\n        \"unenv\": \"2.0.0-rc.24\",\r\n        \"workerd\": \">1.20260305.0 <2.0.0-0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"workerd\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-darwin-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-Wtw44el2pNbzixvTkWdfeBDTrQwQbJRz7/JUvPKV27I0pQWXbhNJPpM8cstq/pbrU5AGcA/HjFH6yPMRTIRKig==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-darwin-arm64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-X8EqkZej6FfmhF9AVAQ3FhyQRr9acS4RcDunMU2YiuxKHF1IU8zzH3vY30/POaG+rUu9vGDp/VgUl49VPenHJQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-linux-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-CDC89QxQ7Y7t7RG1Jd9vj/qolE1sQRkI2OSEuV5BMJi0vW/gV4OVG6xjpdK3b1OYnSWDzF7NpvlR5Yg86q7k4g==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-linux-arm64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-WxbW/PToYES4fvHXzsr/5qOiETQs/Z9iZ0mjSZAiEwq5cMLZemzGN0COx+uFb9OvQwzh6Pg159qPFnw3+i9FuA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cloudflare/workerd-windows-64\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-WmV/iv+MHjYsvkcMVzpM2B5/mf06UUkdpVhZrtMfV9graWjBGPYFvE/eab8748RPVGKh1Xe1vXofLzDSwc08lA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      }\r\n    },\r\n    \"node_modules/@cspotcode/source-map-support\": {\r\n      \"version\": \"0.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz\",\r\n      \"integrity\": \"sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/trace-mapping\": \"0.3.9\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@drizzle-team/brocli\": {\r\n      \"version\": \"0.10.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@drizzle-team/brocli/-/brocli-0.10.2.tgz\",\r\n      \"integrity\": \"sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/@emnapi/core\": {\r\n      \"version\": \"1.10.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz\",\r\n      \"integrity\": \"sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/wasi-threads\": \"1.2.1\",\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@emnapi/runtime\": {\r\n      \"version\": \"1.11.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz\",\r\n      \"integrity\": \"sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@emnapi/wasi-threads\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils\": {\r\n      \"version\": \"3.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild-kit/core-utils/-/core-utils-3.3.2.tgz\",\r\n      \"integrity\": \"sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==\",\r\n      \"deprecated\": \"Merged into tsx: https://tsx.hirok.io\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"esbuild\": \"~0.18.20\",\r\n        \"source-map-support\": \"^0.5.21\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-arm64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/android-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-arm64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/darwin-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-arm64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/freebsd-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-arm64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ia32\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-loong64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==\",\r\n      \"cpu\": [\r\n        \"loong64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-mips64el\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==\",\r\n      \"cpu\": [\r\n        \"mips64el\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-ppc64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-riscv64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-s390x\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/linux-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/netbsd-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/openbsd-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/sunos-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"sunos\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-arm64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-ia32\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/@esbuild/win32-x64\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/core-utils/node_modules/esbuild\": {\r\n      \"version\": \"0.18.20\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz\",\r\n      \"integrity\": \"sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"esbuild\": \"bin/esbuild\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@esbuild/android-arm\": \"0.18.20\",\r\n        \"@esbuild/android-arm64\": \"0.18.20\",\r\n        \"@esbuild/android-x64\": \"0.18.20\",\r\n        \"@esbuild/darwin-arm64\": \"0.18.20\",\r\n        \"@esbuild/darwin-x64\": \"0.18.20\",\r\n        \"@esbuild/freebsd-arm64\": \"0.18.20\",\r\n        \"@esbuild/freebsd-x64\": \"0.18.20\",\r\n        \"@esbuild/linux-arm\": \"0.18.20\",\r\n        \"@esbuild/linux-arm64\": \"0.18.20\",\r\n        \"@esbuild/linux-ia32\": \"0.18.20\",\r\n        \"@esbuild/linux-loong64\": \"0.18.20\",\r\n        \"@esbuild/linux-mips64el\": \"0.18.20\",\r\n        \"@esbuild/linux-ppc64\": \"0.18.20\",\r\n        \"@esbuild/linux-riscv64\": \"0.18.20\",\r\n        \"@esbuild/linux-s390x\": \"0.18.20\",\r\n        \"@esbuild/linux-x64\": \"0.18.20\",\r\n        \"@esbuild/netbsd-x64\": \"0.18.20\",\r\n        \"@esbuild/openbsd-x64\": \"0.18.20\",\r\n        \"@esbuild/sunos-x64\": \"0.18.20\",\r\n        \"@esbuild/win32-arm64\": \"0.18.20\",\r\n        \"@esbuild/win32-ia32\": \"0.18.20\",\r\n        \"@esbuild/win32-x64\": \"0.18.20\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild-kit/esm-loader\": {\r\n      \"version\": \"2.6.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild-kit/esm-loader/-/esm-loader-2.6.5.tgz\",\r\n      \"integrity\": \"sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==\",\r\n      \"deprecated\": \"Merged into tsx: https://tsx.hirok.io\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@esbuild-kit/core-utils\": \"^3.3.2\",\r\n        \"get-tsconfig\": \"^4.7.0\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/aix-ppc64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"aix\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-arm\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/android-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/darwin-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/darwin-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/freebsd-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/freebsd-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-arm\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-ia32\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-loong64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==\",\r\n      \"cpu\": [\r\n        \"loong64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-mips64el\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==\",\r\n      \"cpu\": [\r\n        \"mips64el\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-ppc64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-riscv64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-s390x\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/linux-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/netbsd-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/netbsd-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openbsd-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openbsd-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/openharmony-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/sunos-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"sunos\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-arm64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-ia32\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@esbuild/win32-x64\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@huggingface/jinja\": {\r\n      \"version\": \"0.5.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.5.10.tgz\",\r\n      \"integrity\": \"sha512-SgS1D1bglQ94ceD4ZCL6eayUDy9uV1xuyk61OjgSxU5GJh7upqZCKII0JoTYMc6wWsg3JUgaPRX0ElQzXPk3Cw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@huggingface/transformers\": {\r\n      \"version\": \"3.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@huggingface/transformers/-/transformers-3.8.1.tgz\",\r\n      \"integrity\": \"sha512-tsTk4zVjImqdqjS8/AOZg2yNLd1z9S5v+7oUPpXaasDRwEDhB+xnglK1k5cad26lL5/ZIaeREgWWy0bs9y9pPA==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"@huggingface/jinja\": \"^0.5.3\",\r\n        \"onnxruntime-node\": \"1.21.0\",\r\n        \"onnxruntime-web\": \"1.22.0-dev.20250409-89f8206ba4\",\r\n        \"sharp\": \"^0.34.1\"\r\n      }\r\n    },\r\n    \"node_modules/@img/colour\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-darwin-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-darwin-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-darwin-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-darwin-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-darwin-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-darwin-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-arm\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-ppc64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-riscv64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-s390x\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linux-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linuxmusl-arm64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-libvips-linuxmusl-x64\": {\r\n      \"version\": \"1.2.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz\",\r\n      \"integrity\": \"sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-arm\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-arm\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-ppc64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-ppc64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-riscv64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-riscv64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-s390x\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-s390x\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linux-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linux-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linuxmusl-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linuxmusl-arm64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-linuxmusl-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"Apache-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-libvips-linuxmusl-x64\": \"1.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-wasm32\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==\",\r\n      \"cpu\": [\r\n        \"wasm32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later AND MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/runtime\": \"^1.7.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-arm64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-ia32\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@img/sharp-win32-x64\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0 AND LGPL-3.0-or-later\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      }\r\n    },\r\n    \"node_modules/@isaacs/fs-minipass\": {\r\n      \"version\": \"4.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz\",\r\n      \"integrity\": \"sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\",\r\n      \"dependencies\": {\r\n        \"minipass\": \"^7.0.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/resolve-uri\": {\r\n      \"version\": \"3.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz\",\r\n      \"integrity\": \"sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@jridgewell/sourcemap-codec\": {\r\n      \"version\": \"1.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz\",\r\n      \"integrity\": \"sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@jridgewell/trace-mapping\": {\r\n      \"version\": \"0.3.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz\",\r\n      \"integrity\": \"sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@jridgewell/resolve-uri\": \"^3.0.3\",\r\n        \"@jridgewell/sourcemap-codec\": \"^1.4.10\"\r\n      }\r\n    },\r\n    \"node_modules/@napi-rs/wasm-runtime\": {\r\n      \"version\": \"1.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz\",\r\n      \"integrity\": \"sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@tybys/wasm-util\": \"^0.10.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || ^22.13.0 || >=23.5.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/Brooooooklyn\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@emnapi/core\": \"^1.7.1 || ^2.0.0-alpha.4\",\r\n        \"@emnapi/runtime\": \"^1.7.1 || ^2.0.0-alpha.4\"\r\n      }\r\n    },\r\n    \"node_modules/@openai/sites-vite-plugin\": {\r\n      \"version\": \"0.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@openai/sites-vite-plugin/-/sites-vite-plugin-0.2.0.tgz\",\r\n      \"integrity\": \"sha512-4ThLMW9eaf2gd+SqBwHmqBONKBAbQ2BuOFev7mHq7Y2W5mm/rfVJOSjcgQIsY2PqdXxXNZ4Yd0+s0DlSUYehag==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=22.13.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"vite\": \"^8.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@oxc-project/types\": {\r\n      \"version\": \"0.130.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@oxc-project/types/-/types-0.130.0.tgz\",\r\n      \"integrity\": \"sha512-ibD2usx9JRu7f5pu2tMKMI4cpA4NgXJQoYRP4pQ7Pxmn1l6k/53qWtQWZayhYy3X4QZkt90Ot+mJEaeXouio6Q==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/Boshen\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/colors\": {\r\n      \"version\": \"4.1.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz\",\r\n      \"integrity\": \"sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"kleur\": \"^4.1.5\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/dumper\": {\r\n      \"version\": \"0.6.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz\",\r\n      \"integrity\": \"sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/colors\": \"^4.1.5\",\r\n        \"@sindresorhus/is\": \"^7.0.2\",\r\n        \"supports-color\": \"^10.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/@poppinss/exception\": {\r\n      \"version\": \"1.2.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz\",\r\n      \"integrity\": \"sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@protobufjs/aspromise\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/base64\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/codegen\": {\r\n      \"version\": \"2.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz\",\r\n      \"integrity\": \"sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/eventemitter\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/fetch\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"@protobufjs/aspromise\": \"^1.1.1\"\r\n      }\r\n    },\r\n    \"node_modules/@protobufjs/float\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/path\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/pool\": {\r\n      \"version\": \"1.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz\",\r\n      \"integrity\": \"sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@protobufjs/utf8\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/@rolldown/binding-android-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-fJI3I0r3C3Oj/zdBCpaCmBRZYf07xpaq4yCfDDoSFm+beWNzbIl26puW8RraUdugoJw/95zerNOn6jasAhzSmg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-darwin-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-cKnAhWEsV7TPcA/5EAteDp6KcJZBQ2G+BqE7zayMMi7kMvwRsbv7WT9aOnn0WNl4SKEIf43vjS31iUPu80nzXg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-darwin-x64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-YKrVwQjIRBPo+5G/u03wGjbdy4q7pyzCe93DK9VJ7zkVmeg8LJ7GbgsiHWdR4xSoe4CAXRD7Bcjgbtr64bkXNg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-freebsd-x64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-z/oBsREo46SsFqBwYtFe0kpJeBijAT48O/WXLI4suiCLBkr03RTtTJMCzSdDd2znlh8VJizL09XVkQgk8IZonw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-ik8q7GM11zxvYxFc2PeDcT6TBvhCQMaUxfph/M5l9sKuTs/Sjg3L+Byw0F7w0ZVLBZmx30P+gG0ECzzN+MFcmQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-QoSx2EkyrrdZ6kcyE8stqZ62t0Yra8Fs5ia9lOxJrh6TMQJK7gQKmscdTHf7pOXKREKrVwOtJcQG3qVSfc866A==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-arm64-musl\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-uwNwFpwKeNiZawfAWBgg0VIztPTV3ihhh1vV334h9ivnNLorxnQMU6Fz8wG1Zb4Qh9LC1/MkcyT3YlDXG3Rsgg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-ppc64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-zY1bul7OWr7DFBiJ++wofXvnr8B45ce3QsQUhKrIhXsygAh7bTkwyeM1bi1a2g5C/yC/N8TZyGDEoMfm/l9mpg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-s390x-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-0frlsT/f4Ft6I7SMESTKnF3cZsdicQn1dCMkF/jT9wDLE+gGoiQfv1nmT9e+s7s/fekvvy6tZM2jHvI2tkbJDQ==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-x64-gnu\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-XABVmGp9Tg0WspTVvwduTc4fpqy6JnAUrSQe6OuyqD/03nI7r0O9OWUkMIwFrjKAIqolvqoA4ZrJppgwE0Gxmw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-linux-x64-musl\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-bV4fzswuzVcKD90o/VM6QqKxnxlDq0g2BISDLNVmxrnhpv1DDbyPhCIjYfvzYLV+MvkKKnQt2Q6AO86SEBULUQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-openharmony-arm64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-/Mh0Zhq3OP7fVs0kcQHZP6lZEthMGTaSf8UBQYSFEZDWGXXlEC+nJ6EqenaK2t4LBXMe3A+K/G2BVXXdtOr4PQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-wasm32-wasi\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-+1xc9X45l8ufsBAm6Gjvx2qDRIY9lTVt0cgWNcJ+1gdhXvkbxePA60yRTwSTuXL09CMhyJmjpV7E3NoyxbqFQQ==\",\r\n      \"cpu\": [\r\n        \"wasm32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"@emnapi/core\": \"1.10.0\",\r\n        \"@emnapi/runtime\": \"1.10.0\",\r\n        \"@napi-rs/wasm-runtime\": \"^1.1.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-wasm32-wasi/node_modules/@emnapi/runtime\": {\r\n      \"version\": \"1.10.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz\",\r\n      \"integrity\": \"sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-win32-arm64-msvc\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-1D+UqZdfnuR+Jy1GgMJwi85bD40H21uNmOPRWQhw4oRSuolZ/B5rixZ45DK2KXOTCvmVCecauWgEhbw8bI7tOw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/binding-win32-x64-msvc\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-INAycaWuhlOK3wk4mRHGsdgwYWmd9cChdPdE9bwWmy6rn9VqVNYNFGhOdXrofXUxwHIncSiPNb8tNm8knDVIeQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      }\r\n    },\r\n    \"node_modules/@rolldown/pluginutils\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@sindresorhus/is\": {\r\n      \"version\": \"7.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz\",\r\n      \"integrity\": \"sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sindresorhus/is?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/@speed-highlight/core\": {\r\n      \"version\": \"1.2.24\",\r\n      \"resolved\": \"https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.24.tgz\",\r\n      \"integrity\": \"sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==\",\r\n      \"dev\": true,\r\n      \"license\": \"CC0-1.0\"\r\n    },\r\n    \"node_modules/@stablelib/base64\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/@stablelib/base64/-/base64-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/@tanstack/query-core\": {\r\n      \"version\": \"5.102.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.102.8.tgz\",\r\n      \"integrity\": \"sha512-ZNjkJ33CqvPNec/6lZBnHqLc3EVGPZ9ySLhYahU9TcuRFdmwXewuj0c4hwSWcGHqEUwcSrKeZ+oGcvPBqXcQcg==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"type\": \"github\",\r\n        \"url\": \"https://github.com/sponsors/tannerlinsley\"\r\n      }\r\n    },\r\n    \"node_modules/@tybys/wasm-util\": {\r\n      \"version\": \"0.10.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz\",\r\n      \"integrity\": \"sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"dependencies\": {\r\n        \"tslib\": \"^2.4.0\"\r\n      }\r\n    },\r\n    \"node_modules/@types/node\": {\r\n      \"version\": \"22.20.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/@types/node/-/node-22.20.2.tgz\",\r\n      \"integrity\": \"sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"undici-types\": \"~6.21.0\"\r\n      }\r\n    },\r\n    \"node_modules/blake3-wasm\": {\r\n      \"version\": \"2.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz\",\r\n      \"integrity\": \"sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/boolean\": {\r\n      \"version\": \"3.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz\",\r\n      \"integrity\": \"sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==\",\r\n      \"deprecated\": \"Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/buffer-from\": {\r\n      \"version\": \"1.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz\",\r\n      \"integrity\": \"sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/chownr\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==\",\r\n      \"dev\": true,\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/cookie\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/express\"\r\n      }\r\n    },\r\n    \"node_modules/debug\": {\r\n      \"version\": \"4.4.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/debug/-/debug-4.4.3.tgz\",\r\n      \"integrity\": \"sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"ms\": \"^2.1.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=6.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"supports-color\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/define-data-property\": {\r\n      \"version\": \"1.1.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz\",\r\n      \"integrity\": \"sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-define-property\": \"^1.0.0\",\r\n        \"es-errors\": \"^1.3.0\",\r\n        \"gopd\": \"^1.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/define-properties\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"define-data-property\": \"^1.0.1\",\r\n        \"has-property-descriptors\": \"^1.0.0\",\r\n        \"object-keys\": \"^1.1.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/dequal\": {\r\n      \"version\": \"2.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz\",\r\n      \"integrity\": \"sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/detect-libc\": {\r\n      \"version\": \"2.1.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz\",\r\n      \"integrity\": \"sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=8\"\r\n      }\r\n    },\r\n    \"node_modules/detect-node\": {\r\n      \"version\": \"2.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz\",\r\n      \"integrity\": \"sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/dexie\": {\r\n      \"version\": \"4.4.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/dexie/-/dexie-4.4.6.tgz\",\r\n      \"integrity\": \"sha512-hJP/BO6mjB+tX6hToIO1kmxYLNmun90wYbfcoAoLpKEyDYal/k33dg0TAfoUe2TDsbbLoVIzljJ3BN2UbR5EOg==\",\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/drizzle-kit\": {\r\n      \"version\": \"0.31.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/drizzle-kit/-/drizzle-kit-0.31.4.tgz\",\r\n      \"integrity\": \"sha512-tCPWVZWZqWVx2XUsVpJRnH9Mx0ClVOf5YUHerZ5so1OKSlqww4zy1R5ksEdGRcO3tM3zj0PYN6V48TbQCL1RfA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@drizzle-team/brocli\": \"^0.10.2\",\r\n        \"@esbuild-kit/esm-loader\": \"^2.5.5\",\r\n        \"esbuild\": \"^0.25.4\",\r\n        \"esbuild-register\": \"^3.5.0\"\r\n      },\r\n      \"bin\": {\r\n        \"drizzle-kit\": \"bin.cjs\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/aix-ppc64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"aix\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/android-arm\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/android-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/android-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/darwin-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/darwin-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/freebsd-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/freebsd-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-arm\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-ia32\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-loong64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==\",\r\n      \"cpu\": [\r\n        \"loong64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-mips64el\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==\",\r\n      \"cpu\": [\r\n        \"mips64el\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-ppc64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-riscv64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-s390x\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/linux-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/netbsd-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/netbsd-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/openbsd-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/openbsd-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/openharmony-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/sunos-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"sunos\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/win32-arm64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/win32-ia32\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/@esbuild/win32-x64\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-kit/node_modules/esbuild\": {\r\n      \"version\": \"0.25.12\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz\",\r\n      \"integrity\": \"sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"esbuild\": \"bin/esbuild\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@esbuild/aix-ppc64\": \"0.25.12\",\r\n        \"@esbuild/android-arm\": \"0.25.12\",\r\n        \"@esbuild/android-arm64\": \"0.25.12\",\r\n        \"@esbuild/android-x64\": \"0.25.12\",\r\n        \"@esbuild/darwin-arm64\": \"0.25.12\",\r\n        \"@esbuild/darwin-x64\": \"0.25.12\",\r\n        \"@esbuild/freebsd-arm64\": \"0.25.12\",\r\n        \"@esbuild/freebsd-x64\": \"0.25.12\",\r\n        \"@esbuild/linux-arm\": \"0.25.12\",\r\n        \"@esbuild/linux-arm64\": \"0.25.12\",\r\n        \"@esbuild/linux-ia32\": \"0.25.12\",\r\n        \"@esbuild/linux-loong64\": \"0.25.12\",\r\n        \"@esbuild/linux-mips64el\": \"0.25.12\",\r\n        \"@esbuild/linux-ppc64\": \"0.25.12\",\r\n        \"@esbuild/linux-riscv64\": \"0.25.12\",\r\n        \"@esbuild/linux-s390x\": \"0.25.12\",\r\n        \"@esbuild/linux-x64\": \"0.25.12\",\r\n        \"@esbuild/netbsd-arm64\": \"0.25.12\",\r\n        \"@esbuild/netbsd-x64\": \"0.25.12\",\r\n        \"@esbuild/openbsd-arm64\": \"0.25.12\",\r\n        \"@esbuild/openbsd-x64\": \"0.25.12\",\r\n        \"@esbuild/openharmony-arm64\": \"0.25.12\",\r\n        \"@esbuild/sunos-x64\": \"0.25.12\",\r\n        \"@esbuild/win32-arm64\": \"0.25.12\",\r\n        \"@esbuild/win32-ia32\": \"0.25.12\",\r\n        \"@esbuild/win32-x64\": \"0.25.12\"\r\n      }\r\n    },\r\n    \"node_modules/drizzle-orm\": {\r\n      \"version\": \"0.44.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/drizzle-orm/-/drizzle-orm-0.44.2.tgz\",\r\n      \"integrity\": \"sha512-zGAqBzWWkVSFjZpwPOrmCrgO++1kZ5H/rZ4qTGeGOe18iXGVJWf3WPfHOVwFIbmi8kHjfJstC6rJomzGx8g/dQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"peerDependencies\": {\r\n        \"@aws-sdk/client-rds-data\": \">=3\",\r\n        \"@cloudflare/workers-types\": \">=4\",\r\n        \"@electric-sql/pglite\": \">=0.2.0\",\r\n        \"@libsql/client\": \">=0.10.0\",\r\n        \"@libsql/client-wasm\": \">=0.10.0\",\r\n        \"@neondatabase/serverless\": \">=0.10.0\",\r\n        \"@op-engineering/op-sqlite\": \">=2\",\r\n        \"@opentelemetry/api\": \"^1.4.1\",\r\n        \"@planetscale/database\": \">=1.13\",\r\n        \"@prisma/client\": \"*\",\r\n        \"@tidbcloud/serverless\": \"*\",\r\n        \"@types/better-sqlite3\": \"*\",\r\n        \"@types/pg\": \"*\",\r\n        \"@types/sql.js\": \"*\",\r\n        \"@upstash/redis\": \">=1.34.7\",\r\n        \"@vercel/postgres\": \">=0.8.0\",\r\n        \"@xata.io/client\": \"*\",\r\n        \"better-sqlite3\": \">=7\",\r\n        \"bun-types\": \"*\",\r\n        \"expo-sqlite\": \">=14.0.0\",\r\n        \"gel\": \">=2\",\r\n        \"knex\": \"*\",\r\n        \"kysely\": \"*\",\r\n        \"mysql2\": \">=2\",\r\n        \"pg\": \">=8\",\r\n        \"postgres\": \">=3\",\r\n        \"sql.js\": \">=1\",\r\n        \"sqlite3\": \">=5\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@aws-sdk/client-rds-data\": {\r\n          \"optional\": true\r\n        },\r\n        \"@cloudflare/workers-types\": {\r\n          \"optional\": true\r\n        },\r\n        \"@electric-sql/pglite\": {\r\n          \"optional\": true\r\n        },\r\n        \"@libsql/client\": {\r\n          \"optional\": true\r\n        },\r\n        \"@libsql/client-wasm\": {\r\n          \"optional\": true\r\n        },\r\n        \"@neondatabase/serverless\": {\r\n          \"optional\": true\r\n        },\r\n        \"@op-engineering/op-sqlite\": {\r\n          \"optional\": true\r\n        },\r\n        \"@opentelemetry/api\": {\r\n          \"optional\": true\r\n        },\r\n        \"@planetscale/database\": {\r\n          \"optional\": true\r\n        },\r\n        \"@prisma/client\": {\r\n          \"optional\": true\r\n        },\r\n        \"@tidbcloud/serverless\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/better-sqlite3\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/pg\": {\r\n          \"optional\": true\r\n        },\r\n        \"@types/sql.js\": {\r\n          \"optional\": true\r\n        },\r\n        \"@upstash/redis\": {\r\n          \"optional\": true\r\n        },\r\n        \"@vercel/postgres\": {\r\n          \"optional\": true\r\n        },\r\n        \"@xata.io/client\": {\r\n          \"optional\": true\r\n        },\r\n        \"better-sqlite3\": {\r\n          \"optional\": true\r\n        },\r\n        \"bun-types\": {\r\n          \"optional\": true\r\n        },\r\n        \"expo-sqlite\": {\r\n          \"optional\": true\r\n        },\r\n        \"gel\": {\r\n          \"optional\": true\r\n        },\r\n        \"knex\": {\r\n          \"optional\": true\r\n        },\r\n        \"kysely\": {\r\n          \"optional\": true\r\n        },\r\n        \"mysql2\": {\r\n          \"optional\": true\r\n        },\r\n        \"pg\": {\r\n          \"optional\": true\r\n        },\r\n        \"postgres\": {\r\n          \"optional\": true\r\n        },\r\n        \"prisma\": {\r\n          \"optional\": true\r\n        },\r\n        \"sql.js\": {\r\n          \"optional\": true\r\n        },\r\n        \"sqlite3\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/error-stack-parser-es\": {\r\n      \"version\": \"1.0.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz\",\r\n      \"integrity\": \"sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/antfu\"\r\n      }\r\n    },\r\n    \"node_modules/es-define-property\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/es-errors\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/es6-error\": {\r\n      \"version\": \"4.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz\",\r\n      \"integrity\": \"sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/esbuild\": {\r\n      \"version\": \"0.28.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.28.0.tgz\",\r\n      \"integrity\": \"sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"esbuild\": \"bin/esbuild\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@esbuild/aix-ppc64\": \"0.28.0\",\r\n        \"@esbuild/android-arm\": \"0.28.0\",\r\n        \"@esbuild/android-arm64\": \"0.28.0\",\r\n        \"@esbuild/android-x64\": \"0.28.0\",\r\n        \"@esbuild/darwin-arm64\": \"0.28.0\",\r\n        \"@esbuild/darwin-x64\": \"0.28.0\",\r\n        \"@esbuild/freebsd-arm64\": \"0.28.0\",\r\n        \"@esbuild/freebsd-x64\": \"0.28.0\",\r\n        \"@esbuild/linux-arm\": \"0.28.0\",\r\n        \"@esbuild/linux-arm64\": \"0.28.0\",\r\n        \"@esbuild/linux-ia32\": \"0.28.0\",\r\n        \"@esbuild/linux-loong64\": \"0.28.0\",\r\n        \"@esbuild/linux-mips64el\": \"0.28.0\",\r\n        \"@esbuild/linux-ppc64\": \"0.28.0\",\r\n        \"@esbuild/linux-riscv64\": \"0.28.0\",\r\n        \"@esbuild/linux-s390x\": \"0.28.0\",\r\n        \"@esbuild/linux-x64\": \"0.28.0\",\r\n        \"@esbuild/netbsd-arm64\": \"0.28.0\",\r\n        \"@esbuild/netbsd-x64\": \"0.28.0\",\r\n        \"@esbuild/openbsd-arm64\": \"0.28.0\",\r\n        \"@esbuild/openbsd-x64\": \"0.28.0\",\r\n        \"@esbuild/openharmony-arm64\": \"0.28.0\",\r\n        \"@esbuild/sunos-x64\": \"0.28.0\",\r\n        \"@esbuild/win32-arm64\": \"0.28.0\",\r\n        \"@esbuild/win32-ia32\": \"0.28.0\",\r\n        \"@esbuild/win32-x64\": \"0.28.0\"\r\n      }\r\n    },\r\n    \"node_modules/esbuild-register\": {\r\n      \"version\": \"3.6.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild-register/-/esbuild-register-3.6.0.tgz\",\r\n      \"integrity\": \"sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"debug\": \"^4.3.4\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"esbuild\": \">=0.12 <1\"\r\n      }\r\n    },\r\n    \"node_modules/escape-string-regexp\": {\r\n      \"version\": \"4.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz\",\r\n      \"integrity\": \"sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/fake-indexeddb\": {\r\n      \"version\": \"6.2.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/fake-indexeddb/-/fake-indexeddb-6.2.5.tgz\",\r\n      \"integrity\": \"sha512-CGnyrvbhPlWYMngksqrSSUT1BAVP49dZocrHuK0SvtR0D5TMs5wP0o3j7jexDJW01KSadjBp1M/71o/KR3nD1w==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/fast-sha256\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==\",\r\n      \"license\": \"Unlicense\"\r\n    },\r\n    \"node_modules/fdir\": {\r\n      \"version\": \"6.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz\",\r\n      \"integrity\": \"sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"picomatch\": \"^3 || ^4\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"picomatch\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/flatbuffers\": {\r\n      \"version\": \"25.9.23\",\r\n      \"resolved\": \"https://registry.npmjs.org/flatbuffers/-/flatbuffers-25.9.23.tgz\",\r\n      \"integrity\": \"sha512-MI1qs7Lo4Syw0EOzUl0xjs2lsoeqFku44KpngfIduHBYvzm8h2+7K8YMQh1JtVVVrUvhLpNwqVi4DERegUJhPQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/fsevents\": {\r\n      \"version\": \"2.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz\",\r\n      \"integrity\": \"sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \"^8.16.0 || ^10.6.0 || >=11.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/get-tsconfig\": {\r\n      \"version\": \"4.14.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.3.tgz\",\r\n      \"integrity\": \"sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"resolve-pkg-maps\": \"^1.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/privatenumber/get-tsconfig?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/glob-to-regexp\": {\r\n      \"version\": \"0.4.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz\",\r\n      \"integrity\": \"sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==\",\r\n      \"license\": \"BSD-2-Clause\"\r\n    },\r\n    \"node_modules/global-agent\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"boolean\": \"^3.0.1\",\r\n        \"es6-error\": \"^4.1.1\",\r\n        \"matcher\": \"^3.0.0\",\r\n        \"roarr\": \"^2.15.3\",\r\n        \"semver\": \"^7.3.2\",\r\n        \"serialize-error\": \"^7.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10.0\"\r\n      }\r\n    },\r\n    \"node_modules/global-agent/node_modules/serialize-error\": {\r\n      \"version\": \"7.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz\",\r\n      \"integrity\": \"sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"type-fest\": \"^0.13.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/global-agent/node_modules/type-fest\": {\r\n      \"version\": \"0.13.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz\",\r\n      \"integrity\": \"sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==\",\r\n      \"dev\": true,\r\n      \"license\": \"(MIT OR CC0-1.0)\",\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/globalthis\": {\r\n      \"version\": \"1.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz\",\r\n      \"integrity\": \"sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"define-properties\": \"^1.2.1\",\r\n        \"gopd\": \"^1.0.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/gopd\": {\r\n      \"version\": \"1.2.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz\",\r\n      \"integrity\": \"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/guid-typescript\": {\r\n      \"version\": \"1.0.9\",\r\n      \"resolved\": \"https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz\",\r\n      \"integrity\": \"sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/has-property-descriptors\": {\r\n      \"version\": \"1.0.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz\",\r\n      \"integrity\": \"sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"es-define-property\": \"^1.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/ljharb\"\r\n      }\r\n    },\r\n    \"node_modules/js-cookie\": {\r\n      \"version\": \"3.0.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.8.tgz\",\r\n      \"integrity\": \"sha512-yeJd4aNAdYZQjaon2bpD/Gb0B/omw7HQOsynXXcOiWVCacbBcPlgn8S/d1X6blFSaHao7ozqtW7NZW19xpCtIw==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/json-stringify-safe\": {\r\n      \"version\": \"5.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz\",\r\n      \"integrity\": \"sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/kleur\": {\r\n      \"version\": \"4.1.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz\",\r\n      \"integrity\": \"sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=6\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"dependencies\": {\r\n        \"detect-libc\": \"^2.0.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"lightningcss-android-arm64\": \"1.33.0\",\r\n        \"lightningcss-darwin-arm64\": \"1.33.0\",\r\n        \"lightningcss-darwin-x64\": \"1.33.0\",\r\n        \"lightningcss-freebsd-x64\": \"1.33.0\",\r\n        \"lightningcss-linux-arm-gnueabihf\": \"1.33.0\",\r\n        \"lightningcss-linux-arm64-gnu\": \"1.33.0\",\r\n        \"lightningcss-linux-arm64-musl\": \"1.33.0\",\r\n        \"lightningcss-linux-x64-gnu\": \"1.33.0\",\r\n        \"lightningcss-linux-x64-musl\": \"1.33.0\",\r\n        \"lightningcss-win32-arm64-msvc\": \"1.33.0\",\r\n        \"lightningcss-win32-x64-msvc\": \"1.33.0\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-android-arm64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-darwin-arm64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-darwin-x64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-freebsd-x64\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm-gnueabihf\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm64-gnu\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-arm64-musl\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-x64-gnu\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"glibc\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-linux-x64-musl\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"libc\": [\r\n        \"musl\"\r\n      ],\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-win32-arm64-msvc\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/lightningcss-win32-x64-msvc\": {\r\n      \"version\": \"1.33.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz\",\r\n      \"integrity\": \"sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MPL-2.0\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">= 12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"type\": \"opencollective\",\r\n        \"url\": \"https://opencollective.com/parcel\"\r\n      }\r\n    },\r\n    \"node_modules/long\": {\r\n      \"version\": \"5.3.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/long/-/long-5.3.2.tgz\",\r\n      \"integrity\": \"sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/matcher\": {\r\n      \"version\": \"3.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz\",\r\n      \"integrity\": \"sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"escape-string-regexp\": \"^4.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/meshoptimizer\": {\r\n      \"version\": \"1.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.3.0.tgz\",\r\n      \"integrity\": \"sha512-2oZqMAcEEiCtXWUjIGtZ71oPx1B0ZxYGTqIKsXB1wzWFhleNsCFxQuUJzgCV706bRcwPWtMGf1odmQvAcqKkIw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/miniflare\": {\r\n      \"version\": \"4.20260515.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/miniflare/-/miniflare-4.20260515.0.tgz\",\r\n      \"integrity\": \"sha512-2j0oQWizk1Eu4Cm8tDX7Z+Nsjd0nebIj1TQcQ+Oy1QKeo0Ay9+bdn8wfLAtOj9znDCybDCUlnS1+nYvKXEdfNg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@cspotcode/source-map-support\": \"0.8.1\",\r\n        \"sharp\": \"^0.34.5\",\r\n        \"undici\": \"7.24.8\",\r\n        \"workerd\": \"1.20260515.1\",\r\n        \"ws\": \"8.18.0\",\r\n        \"youch\": \"4.1.0-beta.10\"\r\n      },\r\n      \"bin\": {\r\n        \"miniflare\": \"bootstrap.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/minipass\": {\r\n      \"version\": \"7.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz\",\r\n      \"integrity\": \"sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==\",\r\n      \"dev\": true,\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"engines\": {\r\n        \"node\": \">=16 || 14 >=14.17\"\r\n      }\r\n    },\r\n    \"node_modules/minizlib\": {\r\n      \"version\": \"3.1.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz\",\r\n      \"integrity\": \"sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"minipass\": \"^7.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">= 18\"\r\n      }\r\n    },\r\n    \"node_modules/ms\": {\r\n      \"version\": \"2.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/ms/-/ms-2.1.3.tgz\",\r\n      \"integrity\": \"sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/nanoid\": {\r\n      \"version\": \"3.3.18\",\r\n      \"resolved\": \"https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz\",\r\n      \"integrity\": \"sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==\",\r\n      \"dev\": true,\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"nanoid\": \"bin/nanoid.cjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^10 || ^12 || ^13.7 || ^14 || >=15.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/object-keys\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">= 0.4\"\r\n      }\r\n    },\r\n    \"node_modules/onnxruntime-common\": {\r\n      \"version\": \"1.21.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.21.0.tgz\",\r\n      \"integrity\": \"sha512-Q632iLLrtCAVOTO65dh2+mNbQir/QNTVBG3h/QdZBpns7mZ0RYbLRBgGABPbpU9351AgYy7SJf1WaeVwMrBFPQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/onnxruntime-node\": {\r\n      \"version\": \"1.21.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.21.0.tgz\",\r\n      \"integrity\": \"sha512-NeaCX6WW2L8cRCSqy3bInlo5ojjQqu2fD3D+9W5qb5irwxhEyWKXeH2vZ8W9r6VxaMPUan+4/7NDwZMtouZxEw==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"os\": [\r\n        \"win32\",\r\n        \"darwin\",\r\n        \"linux\"\r\n      ],\r\n      \"dependencies\": {\r\n        \"global-agent\": \"^3.0.0\",\r\n        \"onnxruntime-common\": \"1.21.0\",\r\n        \"tar\": \"^7.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/onnxruntime-web\": {\r\n      \"version\": \"1.22.0-dev.20250409-89f8206ba4\",\r\n      \"resolved\": \"https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.22.0-dev.20250409-89f8206ba4.tgz\",\r\n      \"integrity\": \"sha512-0uS76OPgH0hWCPrFKlL8kYVV7ckM7t/36HfbgoFw6Nd0CZVVbQC4PkrR8mBX8LtNUFZO25IQBqV2Hx2ho3FlbQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"flatbuffers\": \"^25.1.24\",\r\n        \"guid-typescript\": \"^1.0.9\",\r\n        \"long\": \"^5.2.3\",\r\n        \"onnxruntime-common\": \"1.22.0-dev.20250409-89f8206ba4\",\r\n        \"platform\": \"^1.3.6\",\r\n        \"protobufjs\": \"^7.2.4\"\r\n      }\r\n    },\r\n    \"node_modules/onnxruntime-web/node_modules/onnxruntime-common\": {\r\n      \"version\": \"1.22.0-dev.20250409-89f8206ba4\",\r\n      \"resolved\": \"https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.22.0-dev.20250409-89f8206ba4.tgz\",\r\n      \"integrity\": \"sha512-vDJMkfCfb0b1A836rgHj+ORuZf4B4+cc2bASQtpeoJLueuFc5DuYwjIZUBrSvx/fO5IrLjLz+oTrB3pcGlhovQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/path-to-regexp\": {\r\n      \"version\": \"6.3.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz\",\r\n      \"integrity\": \"sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/pathe\": {\r\n      \"version\": \"2.0.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz\",\r\n      \"integrity\": \"sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/picocolors\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\"\r\n    },\r\n    \"node_modules/picomatch\": {\r\n      \"version\": \"4.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz\",\r\n      \"integrity\": \"sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/jonschlinkert\"\r\n      }\r\n    },\r\n    \"node_modules/platform\": {\r\n      \"version\": \"1.3.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/platform/-/platform-1.3.6.tgz\",\r\n      \"integrity\": \"sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/playwright\": {\r\n      \"version\": \"1.63.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/playwright/-/playwright-1.63.0.tgz\",\r\n      \"integrity\": \"sha512-+7ziBLidS4NaNCdt57SUDT+wYmmd5fmiQejUic/kb+YsYSCPyOOE9sebzMjNmQrsnNpDJqd4WHvV/8lfKfUDUg==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"playwright-core\": \"1.63.0\"\r\n      },\r\n      \"bin\": {\r\n        \"playwright\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      }\r\n    },\r\n    \"node_modules/playwright-core\": {\r\n      \"version\": \"1.63.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/playwright-core/-/playwright-core-1.63.0.tgz\",\r\n      \"integrity\": \"sha512-rYCsBF/M5HjUch52bbtVONEFjv6Xu8sm8h72dNlR5bzIE1fvC/bxgspzkjSfU+MweEMmPM8KJebG6nnyxo5mCg==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"bin\": {\r\n        \"playwright-core\": \"cli.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=20\"\r\n      }\r\n    },\r\n    \"node_modules/postcss\": {\r\n      \"version\": \"8.5.28\",\r\n      \"resolved\": \"https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz\",\r\n      \"integrity\": \"sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==\",\r\n      \"dev\": true,\r\n      \"funding\": [\r\n        {\r\n          \"type\": \"opencollective\",\r\n          \"url\": \"https://opencollective.com/postcss/\"\r\n        },\r\n        {\r\n          \"type\": \"tidelift\",\r\n          \"url\": \"https://tidelift.com/funding/github/npm/postcss\"\r\n        },\r\n        {\r\n          \"type\": \"github\",\r\n          \"url\": \"https://github.com/sponsors/ai\"\r\n        }\r\n      ],\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"nanoid\": \"^3.3.18\",\r\n        \"picocolors\": \"^1.1.1\",\r\n        \"source-map-js\": \"^1.2.1\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^10 || ^12 || >=14\"\r\n      }\r\n    },\r\n    \"node_modules/protobufjs\": {\r\n      \"version\": \"7.6.6\",\r\n      \"resolved\": \"https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz\",\r\n      \"integrity\": \"sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"@protobufjs/aspromise\": \"^1.1.2\",\r\n        \"@protobufjs/base64\": \"^1.1.2\",\r\n        \"@protobufjs/codegen\": \"^2.0.5\",\r\n        \"@protobufjs/eventemitter\": \"^1.1.1\",\r\n        \"@protobufjs/fetch\": \"^1.1.1\",\r\n        \"@protobufjs/float\": \"^1.0.2\",\r\n        \"@protobufjs/path\": \"^1.1.2\",\r\n        \"@protobufjs/pool\": \"^1.1.0\",\r\n        \"@protobufjs/utf8\": \"^1.1.1\",\r\n        \"@types/node\": \">=13.7.0\",\r\n        \"long\": \"^5.3.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12.0.0\"\r\n      }\r\n    },\r\n    \"node_modules/resolve-pkg-maps\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/privatenumber/resolve-pkg-maps?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/roarr\": {\r\n      \"version\": \"2.15.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz\",\r\n      \"integrity\": \"sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"dependencies\": {\r\n        \"boolean\": \"^3.0.1\",\r\n        \"detect-node\": \"^2.0.4\",\r\n        \"globalthis\": \"^1.0.1\",\r\n        \"json-stringify-safe\": \"^5.0.1\",\r\n        \"semver-compare\": \"^1.0.0\",\r\n        \"sprintf-js\": \"^1.1.2\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=8.0\"\r\n      }\r\n    },\r\n    \"node_modules/rolldown\": {\r\n      \"version\": \"1.0.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/rolldown/-/rolldown-1.0.1.tgz\",\r\n      \"integrity\": \"sha512-X0KQHljNnEkWNqqiz9zJrGunh1B0HgOxLXvnFpCOcadzcy5qohZ3tqMEUg00vncoRovXuK3ZqCT9KnnKzoInFQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@oxc-project/types\": \"=0.130.0\",\r\n        \"@rolldown/pluginutils\": \"^1.0.0\"\r\n      },\r\n      \"bin\": {\r\n        \"rolldown\": \"bin/cli.mjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@rolldown/binding-android-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-darwin-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-darwin-x64\": \"1.0.1\",\r\n        \"@rolldown/binding-freebsd-x64\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm-gnueabihf\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-arm64-musl\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-ppc64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-s390x-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-x64-gnu\": \"1.0.1\",\r\n        \"@rolldown/binding-linux-x64-musl\": \"1.0.1\",\r\n        \"@rolldown/binding-openharmony-arm64\": \"1.0.1\",\r\n        \"@rolldown/binding-wasm32-wasi\": \"1.0.1\",\r\n        \"@rolldown/binding-win32-arm64-msvc\": \"1.0.1\",\r\n        \"@rolldown/binding-win32-x64-msvc\": \"1.0.1\"\r\n      }\r\n    },\r\n    \"node_modules/semver\": {\r\n      \"version\": \"7.8.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/semver/-/semver-7.8.5.tgz\",\r\n      \"integrity\": \"sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==\",\r\n      \"dev\": true,\r\n      \"license\": \"ISC\",\r\n      \"bin\": {\r\n        \"semver\": \"bin/semver.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=10\"\r\n      }\r\n    },\r\n    \"node_modules/semver-compare\": {\r\n      \"version\": \"1.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz\",\r\n      \"integrity\": \"sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/shaders\": {\r\n      \"version\": \"4.0.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/shaders/-/shaders-4.0.4.tgz\",\r\n      \"integrity\": \"sha512-NB+/RiK0oydteeeKdPqsLpR3iSoDTvt8bsdgw2wPb697QVCY/yadZV8gitCyCQx5t/kb4nJicIR+cbG9Q6JFfQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"typegpu\": \"0.12.3\"\r\n      },\r\n      \"bin\": {\r\n        \"shaders\": \"dist/cli.js\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"react\": \"^18.0.0 || ^19.0.0\",\r\n        \"react-dom\": \"^18.0.0 || ^19.0.0\",\r\n        \"solid-js\": \"^1.8.0\",\r\n        \"svelte\": \"^5\",\r\n        \"vue\": \"^3.5.0\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"react\": {\r\n          \"optional\": true\r\n        },\r\n        \"react-dom\": {\r\n          \"optional\": true\r\n        },\r\n        \"solid-js\": {\r\n          \"optional\": true\r\n        },\r\n        \"svelte\": {\r\n          \"optional\": true\r\n        },\r\n        \"vue\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/sharp\": {\r\n      \"version\": \"0.34.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/sharp/-/sharp-0.34.5.tgz\",\r\n      \"integrity\": \"sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"@img/colour\": \"^1.0.0\",\r\n        \"detect-libc\": \"^2.1.2\",\r\n        \"semver\": \"^7.7.3\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^18.17.0 || ^20.3.0 || >=21.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://opencollective.com/libvips\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@img/sharp-darwin-arm64\": \"0.34.5\",\r\n        \"@img/sharp-darwin-x64\": \"0.34.5\",\r\n        \"@img/sharp-libvips-darwin-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-darwin-x64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-arm\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-ppc64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-riscv64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-s390x\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linux-x64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linuxmusl-arm64\": \"1.2.4\",\r\n        \"@img/sharp-libvips-linuxmusl-x64\": \"1.2.4\",\r\n        \"@img/sharp-linux-arm\": \"0.34.5\",\r\n        \"@img/sharp-linux-arm64\": \"0.34.5\",\r\n        \"@img/sharp-linux-ppc64\": \"0.34.5\",\r\n        \"@img/sharp-linux-riscv64\": \"0.34.5\",\r\n        \"@img/sharp-linux-s390x\": \"0.34.5\",\r\n        \"@img/sharp-linux-x64\": \"0.34.5\",\r\n        \"@img/sharp-linuxmusl-arm64\": \"0.34.5\",\r\n        \"@img/sharp-linuxmusl-x64\": \"0.34.5\",\r\n        \"@img/sharp-wasm32\": \"0.34.5\",\r\n        \"@img/sharp-win32-arm64\": \"0.34.5\",\r\n        \"@img/sharp-win32-ia32\": \"0.34.5\",\r\n        \"@img/sharp-win32-x64\": \"0.34.5\"\r\n      }\r\n    },\r\n    \"node_modules/source-map\": {\r\n      \"version\": \"0.6.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz\",\r\n      \"integrity\": \"sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/source-map-js\": {\r\n      \"version\": \"1.2.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz\",\r\n      \"integrity\": \"sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\",\r\n      \"engines\": {\r\n        \"node\": \">=0.10.0\"\r\n      }\r\n    },\r\n    \"node_modules/source-map-support\": {\r\n      \"version\": \"0.5.21\",\r\n      \"resolved\": \"https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz\",\r\n      \"integrity\": \"sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"buffer-from\": \"^1.0.0\",\r\n        \"source-map\": \"^0.6.0\"\r\n      }\r\n    },\r\n    \"node_modules/sprintf-js\": {\r\n      \"version\": \"1.1.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz\",\r\n      \"integrity\": \"sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==\",\r\n      \"dev\": true,\r\n      \"license\": \"BSD-3-Clause\"\r\n    },\r\n    \"node_modules/standardwebhooks\": {\r\n      \"version\": \"1.1.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/standardwebhooks/-/standardwebhooks-1.1.1.tgz\",\r\n      \"integrity\": \"sha512-bCbX9ZEyFkWPsRz7Bl3NuQUJohmwGSev/yhr7vhaGPlc4AfIrspIRa6cPTBuI1ItmrTDJ4d/S2hCsfe4+vQGnQ==\",\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@stablelib/base64\": \"^1.0.0\",\r\n        \"fast-sha256\": \"^1.3.0\"\r\n      }\r\n    },\r\n    \"node_modules/supports-color\": {\r\n      \"version\": \"10.2.2\",\r\n      \"resolved\": \"https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz\",\r\n      \"integrity\": \"sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/chalk/supports-color?sponsor=1\"\r\n      }\r\n    },\r\n    \"node_modules/tar\": {\r\n      \"version\": \"7.5.22\",\r\n      \"resolved\": \"https://registry.npmjs.org/tar/-/tar-7.5.22.tgz\",\r\n      \"integrity\": \"sha512-MFO/QzvtAOmJbkhOaCTvbGcFN9L9b+JunIsDwaKljSOdcLMea3NJ1k9Usz/rjdfSXTq4dfzfeS7W4p4YOAAHeA==\",\r\n      \"dev\": true,\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"dependencies\": {\r\n        \"@isaacs/fs-minipass\": \"^4.0.0\",\r\n        \"chownr\": \"^3.0.0\",\r\n        \"minipass\": \"^7.1.2\",\r\n        \"minizlib\": \"^3.1.0\",\r\n        \"yallist\": \"^5.0.0\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/three\": {\r\n      \"version\": \"0.169.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/three/-/three-0.169.0.tgz\",\r\n      \"integrity\": \"sha512-Ed906MA3dR4TS5riErd4QBsRGPcx+HBDX2O5yYE5GqJeFQTPU+M56Va/f/Oph9X7uZo3W3o4l2ZhBZ6f6qUv0w==\",\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/tinyest\": {\r\n      \"version\": \"0.3.4\",\r\n      \"resolved\": \"https://registry.npmjs.org/tinyest/-/tinyest-0.3.4.tgz\",\r\n      \"integrity\": \"sha512-81EcMHTCQ2IPweOGk9SpMgjbenR9ZJRsAE84btEv0DhvVKwhe7qBy28hWgatoXa9ppWzmtpHiJ+e86SiaAtY6w==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=12.20.0\"\r\n      }\r\n    },\r\n    \"node_modules/tinyglobby\": {\r\n      \"version\": \"0.2.17\",\r\n      \"resolved\": \"https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz\",\r\n      \"integrity\": \"sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"fdir\": \"^6.5.0\",\r\n        \"picomatch\": \"^4.0.4\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12.0.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/SuperchupuDev\"\r\n      }\r\n    },\r\n    \"node_modules/tslib\": {\r\n      \"version\": \"2.8.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz\",\r\n      \"integrity\": \"sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==\",\r\n      \"license\": \"0BSD\"\r\n    },\r\n    \"node_modules/tsover-runtime\": {\r\n      \"version\": \"0.0.7\",\r\n      \"resolved\": \"https://registry.npmjs.org/tsover-runtime/-/tsover-runtime-0.0.7.tgz\",\r\n      \"integrity\": \"sha512-FHHwMJzZbnP23+fU1PxXljy7j0RRRosL2r1/CRUNTqfW+l7m35JsUkM615x/cAzw4GqRdXPIl3axKMj9qzpZtQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"Apache-2.0\"\r\n    },\r\n    \"node_modules/typed-binary\": {\r\n      \"version\": \"4.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/typed-binary/-/typed-binary-4.3.3.tgz\",\r\n      \"integrity\": \"sha512-W2hLsSzt3k/tg38gDE4Fn/QiwcoqGuUHBc2cb3mXuH7KcYxe/GM57vzW14s2/bawB4R5knGgGq8Xb57vsaJ4Sg==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/typegpu\": {\r\n      \"version\": \"0.12.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/typegpu/-/typegpu-0.12.3.tgz\",\r\n      \"integrity\": \"sha512-zYwQEhnPPwhq5vQKmollXRK1LCVjStOnL+2B0PiebqvAzYPr25rPNR4r3olLoow5sKKjyj3kzHKEcpD5SyDzGQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"tinyest\": \"~0.3.2\",\r\n        \"tsover-runtime\": \"^0.0.7\",\r\n        \"typed-binary\": \"^4.3.3\"\r\n      },\r\n      \"bin\": {\r\n        \"typegpu\": \"bin.mjs\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=12.20.0\"\r\n      }\r\n    },\r\n    \"node_modules/uint8array-extras\": {\r\n      \"version\": \"1.5.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz\",\r\n      \"integrity\": \"sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==\",\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/sindresorhus\"\r\n      }\r\n    },\r\n    \"node_modules/undici\": {\r\n      \"version\": \"7.24.8\",\r\n      \"resolved\": \"https://registry.npmjs.org/undici/-/undici-7.24.8.tgz\",\r\n      \"integrity\": \"sha512-6KQ/+QxK49Z/p3HO6E5ZCZWNnCasyZLa5ExaVYyvPxUwKtbCPMKELJOqh7EqOle0t9cH/7d2TaaTRRa6Nhs4YQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=20.18.1\"\r\n      }\r\n    },\r\n    \"node_modules/undici-types\": {\r\n      \"version\": \"6.21.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz\",\r\n      \"integrity\": \"sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\"\r\n    },\r\n    \"node_modules/unenv\": {\r\n      \"version\": \"2.0.0-rc.24\",\r\n      \"resolved\": \"https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz\",\r\n      \"integrity\": \"sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"pathe\": \"^2.0.3\"\r\n      }\r\n    },\r\n    \"node_modules/vite\": {\r\n      \"version\": \"8.0.13\",\r\n      \"resolved\": \"https://registry.npmjs.org/vite/-/vite-8.0.13.tgz\",\r\n      \"integrity\": \"sha512-MFtjBYgzmSxmgA4RAfjIyXWpGe1oALnjgUTzzV7QLx/TKxCzjtMH6Fd9/eVK+5Fg1qNoz5VAwsmMs/NofrmJvw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"lightningcss\": \"^1.32.0\",\r\n        \"picomatch\": \"^4.0.4\",\r\n        \"postcss\": \"^8.5.14\",\r\n        \"rolldown\": \"1.0.1\",\r\n        \"tinyglobby\": \"^0.2.16\"\r\n      },\r\n      \"bin\": {\r\n        \"vite\": \"bin/vite.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \"^20.19.0 || >=22.12.0\"\r\n      },\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/vitejs/vite?sponsor=1\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"fsevents\": \"~2.3.3\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@types/node\": \"^20.19.0 || >=22.12.0\",\r\n        \"@vitejs/devtools\": \"^0.1.18\",\r\n        \"esbuild\": \"^0.27.0 || ^0.28.0\",\r\n        \"jiti\": \">=1.21.0\",\r\n        \"less\": \"^4.0.0\",\r\n        \"sass\": \"^1.70.0\",\r\n        \"sass-embedded\": \"^1.70.0\",\r\n        \"stylus\": \">=0.54.8\",\r\n        \"sugarss\": \"^5.0.0\",\r\n        \"terser\": \"^5.16.0\",\r\n        \"tsx\": \"^4.8.1\",\r\n        \"yaml\": \"^2.4.2\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@types/node\": {\r\n          \"optional\": true\r\n        },\r\n        \"@vitejs/devtools\": {\r\n          \"optional\": true\r\n        },\r\n        \"esbuild\": {\r\n          \"optional\": true\r\n        },\r\n        \"jiti\": {\r\n          \"optional\": true\r\n        },\r\n        \"less\": {\r\n          \"optional\": true\r\n        },\r\n        \"sass\": {\r\n          \"optional\": true\r\n        },\r\n        \"sass-embedded\": {\r\n          \"optional\": true\r\n        },\r\n        \"stylus\": {\r\n          \"optional\": true\r\n        },\r\n        \"sugarss\": {\r\n          \"optional\": true\r\n        },\r\n        \"terser\": {\r\n          \"optional\": true\r\n        },\r\n        \"tsx\": {\r\n          \"optional\": true\r\n        },\r\n        \"yaml\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/workerd\": {\r\n      \"version\": \"1.20260515.1\",\r\n      \"resolved\": \"https://registry.npmjs.org/workerd/-/workerd-1.20260515.1.tgz\",\r\n      \"integrity\": \"sha512-MjKOJLcvU45xXedQowvuiHtJTxu4WTHYQeIlF7YmjuqhiI6dImTFxWCEoRQHiskztxuVSNEmdO7/0UfDu6OMnQ==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"Apache-2.0\",\r\n      \"bin\": {\r\n        \"workerd\": \"bin/workerd\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=16\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@cloudflare/workerd-darwin-64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-darwin-arm64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-linux-64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-linux-arm64\": \"1.20260515.1\",\r\n        \"@cloudflare/workerd-windows-64\": \"1.20260515.1\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler\": {\r\n      \"version\": \"4.92.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/wrangler/-/wrangler-4.92.0.tgz\",\r\n      \"integrity\": \"sha512-/DKpQHPxkuZbQsO9dFW2700VTD/4DSZMHjy92fO/frNoDRi/zQsFCAd2ONCV6TGqcUoXcP3D8Bo2gj/L4M0qQQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT OR Apache-2.0\",\r\n      \"dependencies\": {\r\n        \"@cloudflare/kv-asset-handler\": \"0.5.0\",\r\n        \"@cloudflare/unenv-preset\": \"2.16.1\",\r\n        \"blake3-wasm\": \"2.1.5\",\r\n        \"esbuild\": \"0.27.3\",\r\n        \"miniflare\": \"4.20260515.0\",\r\n        \"path-to-regexp\": \"6.3.0\",\r\n        \"unenv\": \"2.0.0-rc.24\",\r\n        \"workerd\": \"1.20260515.1\"\r\n      },\r\n      \"bin\": {\r\n        \"wrangler\": \"bin/wrangler.js\",\r\n        \"wrangler2\": \"bin/wrangler.js\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=22.0.0\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"fsevents\": \"~2.3.2\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"@cloudflare/workers-types\": \"^4.20260515.1\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"@cloudflare/workers-types\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/aix-ppc64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"aix\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/android-arm\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/android-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/android-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"android\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/darwin-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/darwin-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"darwin\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/freebsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/freebsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"freebsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-arm\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==\",\r\n      \"cpu\": [\r\n        \"arm\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-ia32\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-loong64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==\",\r\n      \"cpu\": [\r\n        \"loong64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-mips64el\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==\",\r\n      \"cpu\": [\r\n        \"mips64el\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-ppc64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==\",\r\n      \"cpu\": [\r\n        \"ppc64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-riscv64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==\",\r\n      \"cpu\": [\r\n        \"riscv64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-s390x\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==\",\r\n      \"cpu\": [\r\n        \"s390x\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/linux-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"linux\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/netbsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/netbsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"netbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/openbsd-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/openbsd-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openbsd\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/openharmony-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"openharmony\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/sunos-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"sunos\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/win32-arm64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==\",\r\n      \"cpu\": [\r\n        \"arm64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/win32-ia32\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==\",\r\n      \"cpu\": [\r\n        \"ia32\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/@esbuild/win32-x64\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==\",\r\n      \"cpu\": [\r\n        \"x64\"\r\n      ],\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"optional\": true,\r\n      \"os\": [\r\n        \"win32\"\r\n      ],\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/wrangler/node_modules/esbuild\": {\r\n      \"version\": \"0.27.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz\",\r\n      \"integrity\": \"sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==\",\r\n      \"dev\": true,\r\n      \"hasInstallScript\": true,\r\n      \"license\": \"MIT\",\r\n      \"bin\": {\r\n        \"esbuild\": \"bin/esbuild\"\r\n      },\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      },\r\n      \"optionalDependencies\": {\r\n        \"@esbuild/aix-ppc64\": \"0.27.3\",\r\n        \"@esbuild/android-arm\": \"0.27.3\",\r\n        \"@esbuild/android-arm64\": \"0.27.3\",\r\n        \"@esbuild/android-x64\": \"0.27.3\",\r\n        \"@esbuild/darwin-arm64\": \"0.27.3\",\r\n        \"@esbuild/darwin-x64\": \"0.27.3\",\r\n        \"@esbuild/freebsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/freebsd-x64\": \"0.27.3\",\r\n        \"@esbuild/linux-arm\": \"0.27.3\",\r\n        \"@esbuild/linux-arm64\": \"0.27.3\",\r\n        \"@esbuild/linux-ia32\": \"0.27.3\",\r\n        \"@esbuild/linux-loong64\": \"0.27.3\",\r\n        \"@esbuild/linux-mips64el\": \"0.27.3\",\r\n        \"@esbuild/linux-ppc64\": \"0.27.3\",\r\n        \"@esbuild/linux-riscv64\": \"0.27.3\",\r\n        \"@esbuild/linux-s390x\": \"0.27.3\",\r\n        \"@esbuild/linux-x64\": \"0.27.3\",\r\n        \"@esbuild/netbsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/netbsd-x64\": \"0.27.3\",\r\n        \"@esbuild/openbsd-arm64\": \"0.27.3\",\r\n        \"@esbuild/openbsd-x64\": \"0.27.3\",\r\n        \"@esbuild/openharmony-arm64\": \"0.27.3\",\r\n        \"@esbuild/sunos-x64\": \"0.27.3\",\r\n        \"@esbuild/win32-arm64\": \"0.27.3\",\r\n        \"@esbuild/win32-ia32\": \"0.27.3\",\r\n        \"@esbuild/win32-x64\": \"0.27.3\"\r\n      }\r\n    },\r\n    \"node_modules/ws\": {\r\n      \"version\": \"8.18.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/ws/-/ws-8.18.0.tgz\",\r\n      \"integrity\": \"sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"engines\": {\r\n        \"node\": \">=10.0.0\"\r\n      },\r\n      \"peerDependencies\": {\r\n        \"bufferutil\": \"^4.0.1\",\r\n        \"utf-8-validate\": \">=5.0.2\"\r\n      },\r\n      \"peerDependenciesMeta\": {\r\n        \"bufferutil\": {\r\n          \"optional\": true\r\n        },\r\n        \"utf-8-validate\": {\r\n          \"optional\": true\r\n        }\r\n      }\r\n    },\r\n    \"node_modules/yallist\": {\r\n      \"version\": \"5.0.0\",\r\n      \"resolved\": \"https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz\",\r\n      \"integrity\": \"sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==\",\r\n      \"dev\": true,\r\n      \"license\": \"BlueOak-1.0.0\",\r\n      \"engines\": {\r\n        \"node\": \">=18\"\r\n      }\r\n    },\r\n    \"node_modules/youch\": {\r\n      \"version\": \"4.1.0-beta.10\",\r\n      \"resolved\": \"https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz\",\r\n      \"integrity\": \"sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/colors\": \"^4.1.5\",\r\n        \"@poppinss/dumper\": \"^0.6.4\",\r\n        \"@speed-highlight/core\": \"^1.2.7\",\r\n        \"cookie\": \"^1.0.2\",\r\n        \"youch-core\": \"^0.3.3\"\r\n      }\r\n    },\r\n    \"node_modules/youch-core\": {\r\n      \"version\": \"0.3.3\",\r\n      \"resolved\": \"https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz\",\r\n      \"integrity\": \"sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==\",\r\n      \"dev\": true,\r\n      \"license\": \"MIT\",\r\n      \"dependencies\": {\r\n        \"@poppinss/exception\": \"^1.2.2\",\r\n        \"error-stack-parser-es\": \"^1.0.5\"\r\n      }\r\n    },\r\n    \"node_modules/zod\": {\r\n      \"version\": \"4.6.5\",\r\n      \"resolved\": \"https://registry.npmjs.org/zod/-/zod-4.6.5.tgz\",\r\n      \"integrity\": \"sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==\",\r\n      \"license\": \"MIT\",\r\n      \"funding\": {\r\n        \"url\": \"https://github.com/sponsors/colinhacks\"\r\n      }\r\n    }\r\n  }\r\n}\r\n","package.json":"{\r\n  \"name\": \"myr5-coach\",\r\n  \"version\": \"1.0.0\",\r\n  \"private\": true,\r\n  \"type\": \"module\",\r\n  \"scripts\": {\r\n    \"dev\": \"node scripts/dev.mjs\",\r\n    \"build\": \"node scripts/build.mjs\",\r\n    \"catalog:provision-keys\": \"node scripts/provision-pack-catalog-keys.mjs\",\r\n    \"db:generate\": \"drizzle-kit generate\",\r\n    \"test\": \"node --test tests/*.test.mjs tests/packs/*.test.mjs\",\r\n    \"test:smoke\": \"node --test tests/release-smoke.browser.test.mjs\"\r\n  },\r\n  \"devDependencies\": {\r\n    \"@huggingface/transformers\": \"^3.8.1\",\r\n    \"@openai/sites-vite-plugin\": \"0.2.0\",\r\n    \"drizzle-kit\": \"0.31.4\",\r\n    \"drizzle-orm\": \"0.44.2\",\r\n    \"esbuild\": \"0.28.0\",\r\n    \"fake-indexeddb\": \"^6.2.5\",\r\n    \"meshoptimizer\": \"^1.3.0\",\r\n    \"miniflare\": \"4.20260515.0\",\r\n    \"playwright\": \"^1.63.0\",\r\n    \"shaders\": \"4.0.4\",\r\n    \"vite\": \"8.0.13\",\r\n    \"wrangler\": \"4.92.0\"\r\n  },\r\n  \"dependencies\": {\r\n    \"@block65/webcrypto-web-push\": \"^2.0.0\",\r\n    \"@clerk/backend\": \"^3.17.2\",\r\n    \"dexie\": \"^4.4.6\",\r\n    \"three\": \"^0.169.0\",\r\n    \"zod\": \"^4.6.5\"\r\n  }\r\n}\r\n","packs/browser-asset-store.mjs":"/**\r\n * P13C durable browser byte store.  Pack metadata remains in the lifecycle's\r\n * small metadata store; never place pack bytes in localStorage.\r\n */\r\nconst bytes = value => value instanceof Uint8Array ? value : new Uint8Array(value);\r\n\r\nexport function cacheStorageAssetStore({ cacheName = 'myr5-pack-assets-v1', cachesApi = globalThis.caches } = {}) {\r\n  if (!cachesApi?.open) throw new Error('CacheStorage is unavailable');\r\n  const request = key => new Request(`https://myr5.invalid/packs/${encodeURIComponent(key)}`);\r\n  const cache = () => cachesApi.open(cacheName);\r\n  return {\r\n    async get(key) { const response = await (await cache()).match(request(key)); return response ? new Uint8Array(await response.arrayBuffer()) : null; },\r\n    async put(key, value) {\r\n      try { await (await cache()).put(request(key), new Response(bytes(value), { headers: { 'content-type': 'application/octet-stream' } })); }\r\n      catch (error) { throw new Error(`durable asset write failed (quota/storage): ${error?.message || error}`); }\r\n    },\r\n    async remove(key) { await (await cache()).delete(request(key)); },\r\n    async removePrefix(prefix) {\r\n      const target = await cache();\r\n      await Promise.all((await target.keys()).filter(request => decodeURIComponent(new URL(request.url).pathname.split('/').pop() || '').startsWith(prefix)).map(request => target.delete(request)));\r\n    }\r\n  };\r\n}\r\n\r\n/** Test-only injection wrapper for deterministic quota/storage failures. */\r\nexport function quotaInjectingStore(store, { failPut = () => false } = {}) {\r\n  return { ...store, async put(key, value) { if (failPut(key, value)) throw new Error('injected quota exceeded'); return store.put(key, value); } };\r\n}\r\n","packs/catalog-config.mjs":"import {PUBLIC_PACK_CATALOG_KEYS} from './catalog-keys.generated.mjs';\r\n\r\nconst usable=entry=>entry&&typeof entry==='object'&&typeof entry.keyId==='string'&&entry.keyId.length>0\r\n && ['release','recovery'].includes(entry.role)&&Array.isArray(entry.protocols)&&entry.protocols.includes(1)\r\n && entry.publicKey?.kty==='OKP'&&entry.publicKey?.crv==='Ed25519'&&typeof entry.publicKey.x==='string'\r\n && /^[A-Za-z0-9_-]{43}$/.test(entry.publicKey.x)&&!/^A+$/.test(entry.publicKey.x);\r\nexport function productionCatalogKeyring(){\r\n const entries=PUBLIC_PACK_CATALOG_KEYS.filter(usable).map(entry=>Object.freeze({keyId:entry.keyId,role:entry.role,protocols:Object.freeze([...entry.protocols]),publicKey:Object.freeze({kty:'OKP',crv:'Ed25519',x:entry.publicKey.x,ext:true})}));\r\n return Object.freeze(entries);\r\n}\r\n","packs/catalog-keys.generated.mjs":"// Generated by scripts/provision-pack-catalog-keys.mjs. Private keys never belong in this repository.\r\nexport const PUBLIC_PACK_CATALOG_KEYS=Object.freeze([\r\n  {\r\n    \"keyId\": \"myr5-pack-release-2026-09-22-ab1e6c3eb95a\",\r\n    \"role\": \"release\",\r\n    \"protocols\": [\r\n      1\r\n    ],\r\n    \"publicKey\": {\r\n      \"kty\": \"OKP\",\r\n      \"crv\": \"Ed25519\",\r\n      \"x\": \"CW1fJQMSp5r6xXmbu-KdlWlPjcfmP464BT2xdpDzIPI\",\r\n      \"ext\": true\r\n    }\r\n  },\r\n  {\r\n    \"keyId\": \"myr5-pack-recovery-2026-09-22-6336b41e259d\",\r\n    \"role\": \"recovery\",\r\n    \"protocols\": [\r\n      1\r\n    ],\r\n    \"publicKey\": {\r\n      \"kty\": \"OKP\",\r\n      \"crv\": \"Ed25519\",\r\n      \"x\": \"pgBezjehRdmmNjrc4MF1X1zkrZeRhiSHVk1bOkL6Cpg\",\r\n      \"ext\": true\r\n    }\r\n  }\r\n].map(entry=>Object.freeze({...entry,protocols:Object.freeze(entry.protocols),publicKey:Object.freeze(entry.publicKey)})));\r\n","packs/catalog-state.mjs":"import {canonicalCatalogPayload,dependencyIdentity,verifyPackCatalog} from './catalog-trust.mjs';\r\n\r\nexport const PACK_CATALOG_STATE_KEY='myr5-pack-catalog-v1';\r\nconst clone=value=>JSON.parse(JSON.stringify(value));\r\nconst memory=()=>{const values=new Map();return {getItem:key=>values.get(key)??null,setItem:(key,value)=>values.set(key,String(value)),removeItem:key=>values.delete(key)};};\r\n\r\nexport async function readLastGoodCatalog({storage=globalThis.localStorage??memory(),keyring}={}){\r\n let record;try{record=JSON.parse(storage.getItem(PACK_CATALOG_STATE_KEY)||'null');}catch{return null;}\r\n if(!record?.catalog||!await verifyPackCatalog(record.catalog,keyring))return null;\r\n return clone(record.catalog);\r\n}\r\nexport async function promotePackCatalog({catalog,keyring,storage=globalThis.localStorage??memory(),now=()=>Date.now()}={}){\r\n if(!await verifyPackCatalog(catalog,keyring))throw Error('Pack catalog signature is invalid.');\r\n const previous=await readLastGoodCatalog({storage,keyring});\r\n if(previous){\r\n  if(catalog.generation<previous.generation)throw Error('Pack catalog generation cannot move backward.');\r\n  if(catalog.generation===previous.generation){if(canonicalCatalogPayload(catalog)!==canonicalCatalogPayload(previous)||catalog.signature!==previous.signature)throw Error('Pack catalog generation conflicts with the last good catalog.');return {catalog:previous,duplicate:true};}\r\n }\r\n storage.setItem(PACK_CATALOG_STATE_KEY,JSON.stringify({catalog:clone(catalog),verifiedAt:now()}));\r\n const restored=await readLastGoodCatalog({storage,keyring});if(!restored||restored.generation!==catalog.generation)throw Error('Pack catalog could not be restored after promotion.');\r\n return {catalog:restored,duplicate:false};\r\n}\r\nexport function dependencyReferenceCounts(catalog,installedPackIds){\r\n const selected=new Set(installedPackIds),counts=new Map(),records=new Map();\r\n for(const pack of catalog?.packs??[])if(selected.has(pack.packId))for(const dependency of pack.dependencies){const id=dependencyIdentity(dependency);counts.set(id,(counts.get(id)||0)+1);records.set(id,clone(dependency));}\r\n return new Map([...counts].sort(([a],[b])=>a.localeCompare(b)).map(([id,count])=>[id,Object.freeze({count,dependency:Object.freeze(records.get(id))})]));\r\n}\r\nexport function planPackRemoval(catalog,installedPackIds,removePackId){\r\n const before=dependencyReferenceCounts(catalog,installedPackIds),afterIds=[...installedPackIds].filter(id=>id!==removePackId),after=dependencyReferenceCounts(catalog,afterIds),remove=[];\r\n for(const [id,record] of before)if(!after.has(id))remove.push(record.dependency);\r\n return Object.freeze({installedPackIds:Object.freeze(afterIds),removeDependencies:Object.freeze(remove)});\r\n}\r\nexport function aggregateCatalogLicenses(catalog,installedPackIds=(catalog?.packs??[]).map(pack=>pack.packId)){\r\n const refs=dependencyReferenceCounts(catalog,installedPackIds),seen=new Set(),records=[];\r\n for(const {dependency} of refs.values()){const key=JSON.stringify([dependency.name,dependency.version,dependency.spdx,dependency.sourceUrl,dependency.attribution]);if(!seen.has(key)){seen.add(key);records.push({name:dependency.name,version:dependency.version,spdx:dependency.spdx,sourceUrl:dependency.sourceUrl,attribution:dependency.attribution});}}\r\n return Object.freeze(records.sort((a,b)=>a.name.localeCompare(b.name)||a.version.localeCompare(b.version)).map(Object.freeze));\r\n}\r\n","packs/catalog-trust.mjs":"const plain=value=>value&&typeof value==='object'&&!Array.isArray(value);\r\nconst text=(value,max=300)=>typeof value==='string'&&value.length>0&&value.length<=max&&value.trim()===value;\r\nconst hex=value=>typeof value==='string'&&/^[a-f0-9]{64}$/.test(value);\r\nconst signature=value=>typeof value==='string'&&/^[A-Za-z0-9+/]+={0,2}$/.test(value)&&value.length>=80;\r\nconst exactVersion=value=>text(value,80)&&!/[\\*\\^~<>=|\\s]/.test(value);\r\nconst safePath=value=>text(value,500)&&value.startsWith('/packs/')&&!value.includes('..')&&!/[?#]/.test(value);\r\nconst executable=value=>/\\.(?:m?js|cjs|wasm|html?)$/i.test(value);\r\nconst stable=value=>Array.isArray(value)?value.map(stable):plain(value)?Object.fromEntries(Object.keys(value).sort().map(key=>[key,stable(value[key])])):value;\r\nconst base64Bytes=value=>Uint8Array.from((typeof atob==='function'?atob(value):Buffer.from(value,'base64').toString('binary')),char=>char.charCodeAt(0));\r\nconst identity=dependency=>JSON.stringify([dependency.name,dependency.version,dependency.sha256]);\r\nconst sameOriginHashed=(path,hash)=>safePath(path)&&path.toLowerCase().includes(hash.toLowerCase());\r\n\r\nexport const PACK_CATALOG_SCHEMA='mom-pack-catalog-v1';\r\nexport const PACK_CATALOG_PROTOCOL=1;\r\nexport const PACK_ASSET_MAX_BYTES=512*1024;\r\nexport const PACK_TOTAL_MAX_BYTES=2*1024*1024;\r\nexport const canonicalCatalogPayload=catalog=>JSON.stringify(stable({schema:catalog.schema,protocol:catalog.protocol,generation:catalog.generation,publishedAt:catalog.publishedAt,keyId:catalog.keyId,alg:catalog.alg,packs:catalog.packs}));\r\n\r\nfunction validDependency(value){return plain(value)&&text(value.name,200)&&exactVersion(value.version)&&hex(value.sha256)&&Number.isSafeInteger(value.bytes)&&value.bytes>0&&value.bytes<=PACK_ASSET_MAX_BYTES&&sameOriginHashed(value.path,value.sha256)&&!executable(value.path)&&text(value.spdx,80)&&/^[-+.A-Za-z0-9]+$/.test(value.spdx)&&text(value.sourceUrl,1000)&&/^https:\\/\\//.test(value.sourceUrl)&&text(value.attribution,2000);}\r\nfunction validPack(value){\r\n if(!plain(value)||!text(value.packId,200)||!exactVersion(value.version)||!text(value.fallbackId,200)||!value.fallbackId.startsWith('builtin:')||!plain(value.manifest)||!hex(value.manifest.sha256)||!Number.isSafeInteger(value.manifest.bytes)||value.manifest.bytes<=0||value.manifest.bytes>1024*1024||!sameOriginHashed(value.manifest.path,value.manifest.sha256)||!value.manifest.path.endsWith('.json')||!Array.isArray(value.dependencies)||value.dependencies.length>128||!value.dependencies.every(validDependency)||!Number.isSafeInteger(value.totalBytes)||value.totalBytes>PACK_TOTAL_MAX_BYTES||value.totalBytes!==value.manifest.bytes+value.dependencies.reduce((sum,item)=>sum+item.bytes,0))return false;\r\n return new Set(value.dependencies.map(identity)).size===value.dependencies.length;\r\n}\r\nexport function isPackCatalog(value){return plain(value)&&value.schema===PACK_CATALOG_SCHEMA&&value.protocol===PACK_CATALOG_PROTOCOL&&Number.isSafeInteger(value.generation)&&value.generation>0&&Number.isSafeInteger(value.publishedAt)&&value.publishedAt>0&&text(value.keyId,200)&&value.alg==='Ed25519'&&signature(value.signature)&&Array.isArray(value.packs)&&value.packs.length>0&&value.packs.length<=200&&value.packs.every(validPack)&&new Set(value.packs.map(pack=>pack.packId)).size===value.packs.length;}\r\nfunction keyFor(keyring,catalog){return Array.isArray(keyring)?keyring.find(entry=>entry?.keyId===catalog.keyId&&['release','recovery'].includes(entry.role)&&entry.protocols?.includes(catalog.protocol)):null;}\r\nexport async function verifyPackCatalog(catalog,keyring){\r\n if(!isPackCatalog(catalog))return false;const entry=keyFor(keyring,catalog),key=entry?.publicKey;if(key?.kty!=='OKP'||key.crv!=='Ed25519'||typeof key.x!=='string')return false;\r\n try{const subtle=globalThis.crypto?.subtle;if(!subtle)return false;const imported=await subtle.importKey('jwk',key,{name:'Ed25519'},false,['verify']);return await subtle.verify({name:'Ed25519'},imported,base64Bytes(catalog.signature),new TextEncoder().encode(canonicalCatalogPayload(catalog)));}catch{return false;}\r\n}\r\nexport function dependencyIdentity(dependency){if(!validDependency(dependency))throw Error('Invalid catalog dependency.');return identity(dependency);}\r\n","packs/fixtures.mjs":"import { sha256 } from './pack-lifecycle.mjs';\r\nexport const FIXTURE_SOURCES = Object.freeze({ crystal: { 'crystal.json': '{\"kind\":\"crystal\",\"glow\":\"amber\"}' }, liquid: { 'liquid.json': '{\"kind\":\"liquid\",\"flow\":0.4}' }, jelly: { 'jelly.json': '{\"kind\":\"jelly\",\"squish\":0.7}' }, mechanical: { 'mechanical.json': '{\"kind\":\"mechanical\",\"gear\":3}' } });\r\nexport async function fixtureManifest(packId, version = '1.0.0') { const path = `${packId}.json`; const source = FIXTURE_SOURCES[packId]; const value = source[path]; const assetPath = Object.keys(source)[0]; const bytes = new TextEncoder().encode(source[assetPath]); return { packId, version, minAppVersion: '1.0.0', bytes: bytes.byteLength, sha256: await sha256(bytes), renderingRequirements: { webgpu: false, maxTextureSize: 64 }, fallbackPresentation: 'procedural-css', assets: [{ path: assetPath, bytes: bytes.byteLength, sha256: await sha256(bytes) }] }; }\r\n","packs/http-fixture-adapter.mjs":"/** P13C test fixture adapter; this is deliberately not a CDN integration. */\r\nconst concat = (left, right) => { const out = new Uint8Array(left.byteLength + right.byteLength); out.set(left); out.set(right, left.byteLength); return out; };\r\n\r\nexport function httpFixtureAssetSource({ baseUrl, fetchImpl = fetch, expectedEtag, expectedVersion }) {\r\n  if (!baseUrl || !expectedEtag || !expectedVersion) throw new Error('fixture source requires baseUrl, expected ETag, and pinned version');\r\n  return {\r\n    async get(asset, previous = null) {\r\n      const offset = previous?.byteLength || 0;\r\n      const headers = { 'x-fixture-version': expectedVersion };\r\n      if (offset) { headers.Range = `bytes=${offset}-`; headers['If-Range'] = expectedEtag; }\r\n      const response = await fetchImpl(new URL(asset.path, baseUrl), { headers });\r\n      if (!response.ok) throw new Error(`fixture HTTP ${response.status}`);\r\n      if (response.headers.get('etag') !== expectedEtag) throw new Error('fixture asset changed (ETag mismatch)');\r\n      if (response.headers.get('x-fixture-version') !== expectedVersion) throw new Error('fixture asset version changed');\r\n      if (offset && response.status !== 206) throw new Error('fixture server refused resumable Range response');\r\n      const received = new Uint8Array(await response.arrayBuffer());\r\n      const full = offset ? concat(previous, received) : received;\r\n      if (full.byteLength > asset.bytes) throw new Error('fixture asset exceeds manifest length');\r\n      return full;\r\n    }\r\n  };\r\n}\r\n","packs/isolated-pack-control.mjs":"/** P13C isolated opt-in pack control; app startup deliberately does not import this module. */\r\nimport { accountPackGrants, packAccountIdentity } from './pack-entitlements.mjs';\r\nimport { PackLifecycle } from './pack-lifecycle.mjs';\r\nimport { cacheStorageAssetStore } from './browser-asset-store.mjs';\r\nimport { existingWorkoutIdleAdapter } from './workout-idle-adapter.mjs';\r\n\r\nexport const fixtureEntitlementAccount = entitledPackIds => Object.freeze({\r\n  // Test-only explicit entitlement fixture.  This does not grant, mint, or fetch entitlement.\r\n  getEntitlements: () => [...entitledPackIds]\r\n});\r\n\r\n// Production adapter accepts only server serialized per-pack ownership records.\r\n// Coach unlocks, local cache, and test fixtures deliberately grant nothing.\r\nexport function authenticatedPackAccount(account) {\r\n const ownerId=packAccountIdentity(account);\r\n return Object.freeze({\r\n  getIdentity:()=>packAccountIdentity(account),\r\n  getGeneration:()=>account?.dataEpoch,\r\n  getEntitlements:()=>accountPackGrants(account,ownerId)\r\n });\r\n}\r\n\r\nexport function createIsolatedPackControl({ account = authenticatedPackAccount(), workout, workoutOwner, storage = globalThis.localStorage, assetStore = cacheStorageAssetStore(), ...options } = {}) {\r\n  // The caller supplies initPod().workoutOwner when a user explicitly opens pack controls.\r\n  return new PackLifecycle({ account, storage, assetStore, workout: workout || existingWorkoutIdleAdapter({ owner: workoutOwner }), ...options });\r\n}\r\n","packs/pack-entitlements.mjs":"// The authenticated account response is the grant authority. Never combine an\r\n// account identity with another object's globals or legacy top-level grants.\r\nexport function packAccountIdentity(account) {\r\n const id=account?.user?.id;\r\n return typeof id==='string'&&id.length>0&&id.length<=200&&id.trim()===id?id:null;\r\n}\r\nexport function accountPackGrants(account, ownerId=packAccountIdentity(account)) {\r\n if(!ownerId||packAccountIdentity(account)!==ownerId)return [];\r\n const grants=account?.entitlements?.ownedPacks;\r\n return Array.isArray(grants)?grants.filter(grant=>grant&&typeof grant.packId==='string'&&grant.packId.length>0&&grant.packId.trim()===grant.packId&&grant.status==='owned'&&Number.isSafeInteger(grant.grantedAt)):[];\r\n}\r\nexport function hasPackGrant(account,packId) { return accountPackGrants(account).some(grant=>grant.packId===packId); }\r\n","packs/pack-grant-cache.mjs":"import {accountPackGrants,packAccountIdentity} from './pack-entitlements.mjs';\r\n\r\nexport const PACK_GRANT_CACHE_KEY='myr5-pack-grants-v1';\r\nconst plain=value=>value&&typeof value==='object'&&!Array.isArray(value);\r\nconst owner=value=>typeof value==='string'&&value.length>0&&value.length<=200&&value.trim()===value?value:null;\r\nconst epoch=value=>Number.isSafeInteger(value)&&value>0?value:null;\r\nconst grant=value=>plain(value)&&typeof value.packId==='string'&&value.packId.length>0&&value.packId.length<=200&&value.packId.trim()===value.packId&&value.status==='owned'&&Number.isSafeInteger(value.grantedAt)&&value.grantedAt>=0;\r\nconst clone=value=>JSON.parse(JSON.stringify(value));\r\n\r\nexport function memoryGrantStorage(){const values=new Map();return {getItem:key=>values.get(key)??null,setItem:(key,value)=>values.set(key,String(value)),removeItem:key=>values.delete(key)};}\r\nfunction read(storage){\r\n try{\r\n  const value=JSON.parse(storage.getItem(PACK_GRANT_CACHE_KEY)||'{}');\r\n  if(!plain(value)||value.version!==1||!(value.activeOwner===null||owner(value.activeOwner))||!plain(value.owners))return {version:1,activeOwner:null,owners:{}};\r\n  const owners={};\r\n  for(const [id,record] of Object.entries(value.owners))if(owner(id)===id&&plain(record)&&epoch(record.dataEpoch)&&Number.isSafeInteger(record.confirmedAt)&&record.confirmedAt>=0&&Array.isArray(record.grants)&&record.grants.every(grant))owners[id]={dataEpoch:record.dataEpoch,confirmedAt:record.confirmedAt,grants:clone(record.grants)};\r\n  return {version:1,activeOwner:owners[value.activeOwner]?value.activeOwner:null,owners};\r\n }catch{return {version:1,activeOwner:null,owners:{}};}\r\n}\r\n\r\nexport function createPackGrantCache({storage=globalThis.localStorage??memoryGrantStorage(),now=()=>Date.now()}={}){\r\n let state=read(storage);\r\n const persist=()=>storage.setItem(PACK_GRANT_CACHE_KEY,JSON.stringify(state));\r\n return Object.freeze({\r\n  confirm(account){\r\n   const id=packAccountIdentity(account),dataEpoch=epoch(account?.dataEpoch);if(!id||!dataEpoch)throw Error('A canonical account scope is required to confirm pack grants.');\r\n   const grants=accountPackGrants(account,id).map(item=>({packId:item.packId,status:'owned',grantedAt:item.grantedAt}));\r\n   state={version:1,activeOwner:id,owners:{...state.owners,[id]:{dataEpoch,confirmedAt:now(),grants}}};persist();return account;\r\n  },\r\n  active(){const id=state.activeOwner,record=id&&state.owners[id];return record?Object.freeze({user:Object.freeze({id}),dataEpoch:record.dataEpoch,entitlements:Object.freeze({ownedPacks:Object.freeze(clone(record.grants))}),offlineGrantSnapshot:true}):null;},\r\n  forOwner(id){id=owner(id);const record=id&&state.owners[id];return record?Object.freeze({user:Object.freeze({id}),dataEpoch:record.dataEpoch,entitlements:Object.freeze({ownedPacks:Object.freeze(clone(record.grants))}),offlineGrantSnapshot:true}):null;},\r\n  deactivate(){if(state.activeOwner===null)return;state={...state,activeOwner:null};persist();},\r\n  remove(id){id=owner(id);if(!id)return;const owners={...state.owners};delete owners[id];state={version:1,activeOwner:state.activeOwner===id?null:state.activeOwner,owners};persist();},\r\n  inspect(){return clone(state);}\r\n });\r\n}\r\n","packs/pack-host-adapter.mjs":"/**\r\n * Cross-origin asset source for the public pack host (packs.mominc.online,\r\n * see pack-host-config.mjs). Unlike http-fixture-adapter.mjs (a local test\r\n * fixture that pins ETag/x-fixture-version headers no real static host\r\n * sends), this is a plain CORS GET: every asset is already pinned to an\r\n * exact sha256 + byte length by the pack's signed manifest, so\r\n * pack-lifecycle.mjs's own digest check (`validate()`) is what rejects a\r\n * tampered or mismatched file — this adapter only needs to fetch bytes.\r\n */\r\nimport { PACK_HOST_BASE_URL } from './pack-host-config.mjs';\r\n\r\nexport function packHostAssetSource({ baseUrl = PACK_HOST_BASE_URL, fetchImpl = fetch } = {}) {\r\n  if (!baseUrl) throw new Error('pack host adapter requires a baseUrl');\r\n  return {\r\n    // ponytail: no Range/resume — a retry re-fetches the whole asset. Safe to\r\n    // add later (Range + If-Range) without touching pack-lifecycle.mjs, since\r\n    // the sha256 pin already makes a bad resume detectable, just not cheap.\r\n    async get(asset) {\r\n      const response = await fetchImpl(new URL(asset.path, baseUrl), { mode: 'cors', cache: 'no-store' });\r\n      if (!response.ok) throw new Error(`pack host HTTP ${response.status} for ${asset.path}`);\r\n      const bytes = new Uint8Array(await response.arrayBuffer());\r\n      if (bytes.byteLength > asset.bytes) throw new Error(`pack host asset exceeds manifest length: ${asset.path}`);\r\n      return bytes;\r\n    }\r\n  };\r\n}\r\n","packs/pack-host-config.mjs":"// Rank 2b (D1): the one place that names where optional-art packs are served\r\n// from. Every pack consumer imports this instead of hardcoding a host, so\r\n// moving to a different static host later is a one-line change.\r\nexport const PACK_HOST_BASE_URL = 'https://packs.mominc.online';\r\n","packs/pack-license-surface.mjs":"import {productionCatalogKeyring} from './catalog-config.mjs';\r\nimport {aggregateCatalogLicenses,readLastGoodCatalog} from './catalog-state.mjs';\r\n\r\nexport async function mountPackLicenses({host,storage=globalThis.localStorage,keyring=productionCatalogKeyring()}={}){\r\n if(!host)return null;host.replaceChildren();\r\n const catalog=await readLastGoodCatalog({storage,keyring});\r\n const records=catalog?aggregateCatalogLicenses(catalog):[];\r\n if(!records.length){host.textContent='No optional pack licenses are installed.';return {catalog:null,records};}\r\n const list=host.ownerDocument.createElement('ul');\r\n for(const record of records){const item=host.ownerDocument.createElement('li'),link=host.ownerDocument.createElement('a'),copy=host.ownerDocument.createElement('span');link.href=record.sourceUrl;link.rel='noreferrer';link.textContent=record.name+' '+record.version+' ('+record.spdx+')';copy.textContent=' — '+record.attribution;item.append(link,copy);list.append(item);}\r\n host.append(list);return {catalog,records};\r\n}\r\n","packs/pack-lifecycle.mjs":"/** P13C provenance: copied from prototypes/packs/pack-lifecycle.mjs (reviewed P13B fixture lifecycle), then adapted only through its explicit asset-source adapter. */\r\nconst CACHE_KEY = 'p13b.device-cache';\r\nconst hasSubtle = globalThis.crypto?.subtle;\r\nconst nodeCrypto = 'node:crypto';\r\nasync function digest(bytes) { if (hasSubtle) { const h = await globalThis.crypto.subtle.digest('SHA-256', bytes); return [...new Uint8Array(h)].map(x => x.toString(16).padStart(2, '0')).join(''); } const { createHash } = await import(nodeCrypto); return createHash('sha256').update(Buffer.from(bytes)).digest('hex'); }\r\nconst bytesOf = value => value instanceof Uint8Array ? value : Array.isArray(value) ? new Uint8Array(value) : new TextEncoder().encode(value);\r\nconst clone = value => new Uint8Array(value);\r\nconst joinBytes = chunks => { const joined = new Uint8Array(chunks.reduce((n, data) => n + data.byteLength, 0)); let offset = 0; for (const data of chunks) { joined.set(data, offset); offset += data.byteLength; } return joined; };\r\nconst snapshot = value => JSON.parse(JSON.stringify(value));\r\nconst retire = runtime => { try { runtime?.dispose(); } catch { /* Retired runtime cleanup is best effort. */ } };\r\nconst stale = () => Object.assign(new Error('Pack account or operation changed'), { code: 'pack_operation_changed' });\r\nconst parts = value => String(value).split('.').map(x => /^\\d+$/.test(x) ? Number(x) : -1);\r\nexport const compareVersions = (left, right) => { const a = parts(left), b = parts(right); for (let i = 0; i < Math.max(a.length, b.length); i++) { const d = (a[i] ?? 0) - (b[i] ?? 0); if (d) return Math.sign(d); } return 0; };\r\nexport const PACK_STATES = Object.freeze(['absent', 'downloading', 'downloaded', 'verified', 'pending-equip', 'active', 'failed']);\r\nexport const memoryStore = () => { const map = new Map(); return { getItem: k => map.get(k) ?? null, setItem: (k, v) => map.set(k, String(v)), removeItem: k => map.delete(k) }; };\r\n\r\n/** Demo/test adapter only (64 KiB by default), never a production download cache. */\r\nexport function fixtureAssetStore({ maxBytes = 64 * 1024 } = {}) { const map = new Map(); let used = 0; return { maxBytes, async get(k) { const v = map.get(k); return v ? clone(v) : null; }, async put(k, v) { const data = bytesOf(v), old = map.get(k)?.byteLength ?? 0; if (used - old + data.byteLength > maxBytes) throw new Error('fixture asset-store quota exceeded'); map.set(k, clone(data)); used += data.byteLength - old; }, async remove(k) { const old = map.get(k); if (old) { used -= old.byteLength; map.delete(k); } }, async removePrefix(prefix) { for (const key of [...map.keys()]) if (key.startsWith(prefix)) await this.remove(key); } }; }\r\n\r\nexport class PackLifecycle {\r\n  constructor({ account, storage = globalThis.localStorage ?? memoryStore(), assetStore = fixtureAssetStore(), workout, appVersion = '1.0.0', runtimeFactory = () => ({ dispose() {} }), now = () => new Date().toISOString(), onChange = () => {}, verifyManifest = null, fail = {} } = {}) {\r\n    if (!account?.getEntitlements) throw new Error('account adapter with getEntitlements() is required'); if (!assetStore?.get || !assetStore?.put || !assetStore?.removePrefix) throw new Error('assetStore adapter is required'); if (!workout?.saveAndConfirmIdle) throw new Error('workout adapter with saveAndConfirmIdle() is required');\r\n    Object.assign(this, { account, storage, assetStore, workout, appVersion, runtimeFactory, now, onChange, verifyManifest, fail }); this.epoch = 0; this.disposed = false; this.identity = this.accountIdentity(); this.accountGeneration = this.account.getGeneration?.(); this.unsubscribe = this.account.subscribe?.(() => this.clear()); this.manifests = new Map(); this.runtime = null; const saved = this.readCache(); this.records = saved.packs ?? {}; this.candidates = saved.candidates ?? {}; this.equipped = saved.equipped ?? null; this.pending = saved.pending ?? null;\r\n  }\r\n  accountIdentity() { return this.account.getIdentity ? this.account.getIdentity() : (this.account.user?.id ?? this.account.id ?? this.account); }\r\n  clear() { this.epoch++; const old = this.runtime; this.runtime = null; retire(old); }\r\n  dispose() { this.disposed = true; this.clear(); this.unsubscribe?.(); }\r\n  capture(id) {\r\n    const identity = this.accountIdentity(), generation = this.account.getGeneration?.();\r\n    if (identity !== this.identity || generation !== this.accountGeneration) { this.clear(); this.identity = identity; this.accountGeneration = generation; }\r\n    if (this.disposed || !this.entitled(id)) { this.clear(); throw stale(); }\r\n    return { epoch: this.epoch, identity, generation };\r\n  }\r\n  current(ticket, id) {\r\n    const identity = this.accountIdentity(), generation = this.account.getGeneration?.();\r\n    if (identity !== this.identity || generation !== this.accountGeneration || !this.entitled(id)) { this.clear(); this.identity = identity; this.accountGeneration = generation; }\r\n    return !this.disposed && ticket.epoch === this.epoch && ticket.identity === identity && ticket.generation === generation && this.entitled(id);\r\n  }\r\n  assertCurrent(ticket, id) { if (!this.current(ticket, id)) throw stale(); }\r\n  async checked(promise, ticket, id) { const value = await promise; this.assertCurrent(ticket, id); return value; }\r\n  readCache() { try { return JSON.parse(this.storage.getItem(CACHE_KEY) || '{}'); } catch { return {}; } }\r\n  persist() { this.storage.setItem(CACHE_KEY, JSON.stringify({ packs: this.records, candidates: this.candidates, equipped: this.equipped, pending: this.pending })); }\r\n  emit(id) { this.persist(); this.onChange(this.status(id)); }\r\n  pin(m) { if (!m.version || !m.sha256) throw new Error('manifest requires pinned version and sha256'); return { version: m.version, manifestHash: m.sha256 }; }\r\n  key(id, pin, path) { return `${id}@${pin.version}@${pin.manifestHash}/${path}`; }\r\n  prefix(id, pin) { return `${id}@${pin.version}@${pin.manifestHash}/`; }\r\n  manifest(manifest, source = {}) { manifest = snapshot(manifest); const pin = this.pin(manifest); this.epoch++; this.manifests.set(manifest.packId, { manifest, source, pin }); this.records[manifest.packId] ??= { state: 'absent', receivedBytes: 0 }; return this.status(manifest.packId); }\r\n  entitled(id) { return !!this.account.getEntitlements().some(x => (typeof x === 'string' ? x : x.packId) === id); }\r\n  compatible(m) { return compareVersions(this.appVersion, m.minAppVersion) >= 0; }\r\n  isPinned(r, entry) { return r?.version === entry.pin.version && r?.manifestHash === entry.pin.manifestHash; }\r\n  candidateFor(id, e = this.manifests.get(id)) { const active = this.records[id]; return e && active?.state === 'active' && !this.isPinned(active, e) ? (this.candidates[id] ??= { state: 'absent', receivedBytes: 0, ...e.pin }) : active; }\r\n  status(id) { const e = this.manifests.get(id), active = this.records[id] ?? { state: 'absent', receivedBytes: 0 }, candidate = this.candidates[id]; const r = active.state === 'active' ? active : (candidate ?? active); return { ...(e ? { packId: id, version: r.version ?? e.manifest.version } : { packId: id }), ...r, entitlement: this.entitled(id), equipped: this.equipped?.packId === id, pending: this.pending?.packId === id, ...(active.state === 'active' && candidate ? { candidate: { ...candidate } } : {}) }; }\r\n  all() { return [...new Set([...this.manifests.keys(), ...Object.keys(this.records)])].map(id => this.status(id)); }\r\n  reset(id, entry) { const target = this.candidateFor(id, entry); if (target === this.records[id]) this.records[id] = { state: 'absent', receivedBytes: 0, ...entry.pin }; else this.candidates[id] = { state: 'absent', receivedBytes: 0, ...entry.pin }; }\r\n  async received(id, e, ticket) { let n = 0; for (const a of e.manifest.assets) n += (await this.checked(this.assetStore.get(this.key(id, e.pin, a.path)), ticket, id))?.byteLength ?? 0; return n; }\r\n  async download(id, { resume = true } = {}) {\r\n    const e = this.manifests.get(id); if (!e) throw new Error('unknown pack'); if (!this.entitled(id)) throw new Error('pack is not entitled');\r\n    const ticket = this.capture(id);\r\n    if (this.verifyManifest && !await this.checked(this.verifyManifest(e.manifest), ticket, id)) return this.failState(id, 'manifest signature is invalid');\r\n    if (!this.compatible(e.manifest)) return this.failState(id, 'incompatible app version'); let r = this.candidateFor(id, e);\r\n    if (!r || !this.isPinned(r, e) || !resume) { if (r && this.isPinned(r, e)) await this.checked(this.assetStore.removePrefix(this.prefix(id, e.pin)), ticket, id); this.reset(id, e); r = this.candidateFor(id, e); }\r\n    r.state = 'downloading'; r.manifest = snapshot(e.manifest); delete r.error; this.emit(id);\r\n    for (const a of e.manifest.assets) {\r\n      const key = this.key(id, e.pin, a.path); let old = resume ? await this.checked(this.assetStore.get(key), ticket, id) : null;\r\n      // A complete cached response is reusable only after its hash passes.\r\n      if (old?.byteLength === a.bytes && await this.checked(digest(old), ticket, id) === a.sha256) continue;\r\n      if (old?.byteLength >= a.bytes) old = null;\r\n      if (this.fail.download) return this.failState(id, 'download interrupted; resume available');\r\n      try {\r\n        const raw = typeof e.source?.get === 'function' ? await this.checked(e.source.get(a, old), ticket, id) : e.source[a.path];\r\n        this.assertCurrent(ticket, id);\r\n        if (raw === undefined) return this.failState(id, `missing fixture ${a.path}`);\r\n        await this.checked(this.assetStore.put(key, bytesOf(raw)), ticket, id);\r\n      } catch (error) {\r\n        this.assertCurrent(ticket, id);\r\n        return this.failState(id, `asset storage/download failed: ${error?.message || 'unknown failure'}`);\r\n      }\r\n      r.receivedBytes = await this.received(id, e, ticket); this.assertCurrent(ticket, id); this.emit(id);\r\n    }\r\n    r.receivedBytes = await this.received(id, e, ticket); this.assertCurrent(ticket, id); r.state = 'downloaded'; this.emit(id); return this.status(id);\r\n  }\r\n  async validate(id, { markFailed = true, record, entry, ticket = this.capture(id) } = {}) {\r\n    this.assertCurrent(ticket, id);\r\n    const e = entry !== undefined ? entry : this.manifests.get(id), r = record ?? this.candidateFor(id, e); let reason;\r\n    if (!e || !r) reason = 'missing manifest or cache record';\r\n    else if (e.manifest.packId !== id || !this.isPinned(r, { pin: this.pin(e.manifest) }) || !this.isPinned(r, e)) reason = 'cached pack does not match pinned manifest';\r\n    else if (this.verifyManifest && !await this.checked(this.verifyManifest(e.manifest), ticket, id)) reason = 'manifest signature is invalid';\r\n    else if (!this.compatible(e.manifest)) reason = 'incompatible app version';\r\n    const assembled = [];\r\n    if (!reason) for (const a of e.manifest.assets) {\r\n      const data = await this.checked(this.assetStore.get(this.key(id, e.pin, a.path)), ticket, id);\r\n      if (!data || data.byteLength !== a.bytes || await this.checked(digest(data), ticket, id) !== a.sha256) { reason = `integrity check failed: ${a.path}`; break; }\r\n      assembled.push(data);\r\n    }\r\n    if (!reason && await this.checked(digest(joinBytes(assembled)), ticket, id) !== e.manifest.sha256) reason = 'manifest integrity check failed';\r\n    this.assertCurrent(ticket, id); if (reason && markFailed) this.failState(id, reason); return { ok: !reason, reason };\r\n  }\r\n  async verify(id) {\r\n    const ticket = this.capture(id), r = this.candidateFor(id); if (!r || r.state !== 'downloaded') throw new Error('pack is not downloaded');\r\n    if (this.fail.verify) return this.failState(id, 'integrity check failed');\r\n    if (!(await this.validate(id, { ticket })).ok) return this.status(id); this.assertCurrent(ticket, id);\r\n    r.state = 'verified'; r.manifest = snapshot(this.manifests.get(id).manifest); r.verifiedAt = this.now(); delete r.error; this.emit(id); return this.status(id);\r\n  }\r\n  async equipPending(id) {\r\n    const ticket = this.capture(id), r = this.candidateFor(id); if (!r || r.state !== 'verified') throw new Error('only verified packs can be equipped');\r\n    if (!(await this.validate(id, { ticket })).ok) return this.status(id); this.assertCurrent(ticket, id);\r\n    if (this.pending && this.pending.packId !== id && this.records[this.pending.packId]?.state === 'pending-equip') this.records[this.pending.packId].state = 'verified';\r\n    this.pending = { packId: id, ...this.manifests.get(id).pin }; r.state = 'pending-equip'; this.emit(id); return this.status(id);\r\n  }\r\n  savedEntry(r) { return r?.manifest ? { manifest: snapshot(r.manifest), pin: this.pin(r.manifest) } : null; }\r\n  async activate(id, r, e, { restoring = false } = {}) {\r\n    const ticket = this.capture(id); let safe, candidate, published = false;\r\n    try {\r\n      safe = await this.workout.saveAndConfirmIdle(); this.assertCurrent(ticket, id);\r\n      if (!(safe === true || (safe?.saved === true && safe?.idle === true))) throw Object.assign(new Error('workout save/idle acknowledgment is required before activation'), { code: 'workout_not_idle' });\r\n      const checked = await this.validate(id, { markFailed: false, record: r, entry: e, ticket }); this.assertCurrent(ticket, id);\r\n      if (!checked.ok) {\r\n        if (r) { r.state = 'failed'; r.error = checked.reason; }\r\n        if (restoring) this.equipped = null; else this.pending = null;\r\n        this.persist(); return this.all();\r\n      }\r\n      if (this.fail.activation) throw new Error('activation failed');\r\n      candidate = await this.runtimeFactory(id, r, e.manifest); this.assertCurrent(ticket, id);\r\n      if (!candidate?.dispose) throw new Error('runtime factory returned no disposable runtime');\r\n      // Factories may prepare detached UI; only publish it after the final guard.\r\n      candidate.activate?.(); this.assertCurrent(ticket, id);\r\n      const old = this.runtime, previous = this.equipped?.packId;\r\n      this.runtime = candidate; this.equipped = { packId: id, ...e.pin }; r.state = 'active'; r.manifest = snapshot(e.manifest); delete r.error;\r\n      if (!restoring) { this.pending = null; this.records[id] = r; delete this.candidates[id]; }\r\n      if (previous && previous !== id && this.records[previous]) this.records[previous].state = 'verified';\r\n      this.persist(); published = true; retire(old); this.onChange(this.status(id)); return this.all();\r\n    } catch (error) {\r\n      if (!this.current(ticket, id)) throw stale();\r\n      if (error.code === 'workout_not_idle') throw error;\r\n      if (r) { r.state = restoring ? 'failed' : 'pending-equip'; r.error = `${restoring ? 'restore' : 'activation'} failed: ${error.message || 'runtime error'}`; }\r\n      if (restoring) this.equipped = null;\r\n      this.persist(); return this.all();\r\n    } finally { if (!published) retire(candidate); safe?.release?.(); }\r\n  }\r\n  async restart() {\r\n    if (!this.pending) return this.all(); const id = this.pending.packId;\r\n    // Pending metadata is persisted alongside its exact signature, so a network\r\n    // replacement cannot silently substitute another version at boot.\r\n    const r = [this.candidates[id], this.records[id]].find(value => this.isPinned(value, { pin: this.pending }));\r\n    const e = this.savedEntry(r) ?? this.manifests.get(id);\r\n    return this.activate(id, r, e);\r\n  }\r\n  async restore() {\r\n    if (!this.equipped) return this.all(); const id = this.equipped.packId, r = this.records[id];\r\n    // Authenticate this exact persisted manifest, never a newly fetched one.\r\n    return this.activate(id, r, this.savedEntry(r), { restoring: true });\r\n  }\r\n  async evict(id) { const ticket = this.capture(id), r = this.records[id], e = this.manifests.get(id); if (!r) return; if (this.equipped?.packId === id) throw new Error('cannot evict equipped pack'); if (e && this.isPinned(r, e)) await this.checked(this.assetStore.removePrefix(this.prefix(id, e.pin)), ticket, id); this.assertCurrent(ticket, id); this.records[id] = { state: 'absent', receivedBytes: 0 }; if (this.pending?.packId === id) this.pending = null; this.emit(id); }\r\n  failState(id, reason) { const e = this.manifests.get(id), r = this.candidateFor(id, e) ?? (this.records[id] ??= { receivedBytes: 0 }); r.state = 'failed'; r.error = reason; if (this.pending?.packId === id) this.pending = null; this.emit(id); return this.status(id); }\r\n}\r\nexport async function sha256(value) { return digest(bytesOf(value)); }\r\n\r\n","packs/workout-idle-adapter.mjs":"/**\r\n * P13C bridge point for the existing workout UI.  It never invents an idle\r\n * acknowledgement: until the workout owner exposes save + confirmed-idle,\r\n * pack activation stays pending and cannot interrupt camera tracking.\r\n */\r\nexport function existingWorkoutIdleAdapter({ owner, getWorkoutState, saveWorkout } = {}) {\r\n  return {\r\n    async saveAndConfirmIdle() {\r\n      if (owner?.acquireIdleLease && owner?.snapshot && owner?.save && owner?.releaseIdleLease) {\r\n        const lease = owner.acquireIdleLease();\r\n        if (!lease) return { saved: false, idle: false, reason: 'active workout must not be interrupted' };\r\n        try {\r\n          const saved = await owner.save();\r\n          const after = owner.snapshot();\r\n          if (saved !== true || after.phase !== 'idle' || after.revision !== lease.revision) {\r\n            owner.releaseIdleLease(lease);\r\n            return { saved: false, idle: false, reason: 'workout changed while saving' };\r\n          }\r\n          // PackLifecycle holds this through runtime activation, closing the idle-active-idle ABA gap.\r\n          return { saved: true, idle: true, local: true, accountSynced: false, lease, release: () => owner.releaseIdleLease(lease) };\r\n        } catch (error) {\r\n          owner.releaseIdleLease(lease);\r\n          return { saved: false, idle: false, reason: error?.message || 'workout save failed' };\r\n        }\r\n      }\r\n      if (typeof getWorkoutState !== 'function' || typeof saveWorkout !== 'function') return { saved: false, idle: false, reason: 'workout save/idle integration is not installed' };\r\n      const before = getWorkoutState();\r\n      if (!before || before.phase !== 'idle') return { saved: false, idle: false, reason: 'active workout must not be interrupted' };\r\n      // A state snapshot cannot prevent an idle-active-idle transition while\r\n      // activation awaits. Legacy callbacks must install the owner lease API.\r\n      return { saved: false, idle: false, reason: 'workout idle lease integration is not installed' };\r\n    }\r\n  };\r\n}\r\n","pending-coach.mjs":"import {validRecipe} from './onboarding-domain.mjs';\r\nexport const INCOMING_KEY='myr5-incoming-coach-v1';\r\nexport function validIncomingCoach(value){return !!(value&&value.version===1&&value.armieCompleted===true&&value.customizationConfirmed===true&&validRecipe(value.appearance?.['myr5-recipe-v1']));}\r\nexport function saveIncomingCoach(value,session=sessionStorage,local=localStorage){\r\n const raw=typeof value==='string'?value:JSON.stringify(value);\r\n if(new TextEncoder().encode(raw).length>55000)throw Error('This saved coach is too large to transfer. Return to the website and try again.');\r\n const data=JSON.parse(raw);\r\n if(!validIncomingCoach(data))throw Error('Your saved coach could not be read. Return to the creature studio and tap Use this coach again.');\r\n // Durable storage keeps the handoff available when the next app tab is opened.\r\n local.setItem(INCOMING_KEY,raw);\r\n try{session.setItem(INCOMING_KEY,raw);}catch{}\r\n return data;\r\n}\r\nexport function readIncomingCoach(session=sessionStorage,local=localStorage){\r\n for(const storage of [session,local])try{const value=JSON.parse(storage.getItem(INCOMING_KEY)||'null');if(validIncomingCoach(value))return value;}catch{}\r\n return null;\r\n}\r\nexport function clearIncomingCoach(session=sessionStorage,local=localStorage){for(const storage of [session,local])try{storage.removeItem(INCOMING_KEY);}catch{}}\r\n","performance-account-sync.mjs":"import {snapshotFromCompletedWorkout,prepareWorkoutImport} from './workout-import-codec.mjs';\r\nimport {performanceOwner} from './performance-progress.mjs';\r\nconst CACHE='myr5-performance-account-receipts-v2';\r\nconst identity=a=>typeof a?.user?.id==='string'&&a.user.id&&Number.isSafeInteger(a.dataEpoch)&&a.dataEpoch>0&&!a.stale?{id:a.user.id,epoch:a.dataEpoch}:null;\r\nconst same=(a,b)=>a&&b&&a.id===b.id&&a.epoch===b.epoch;\r\n\r\n/** Automatic upload applies only to workouts started for a captured account.\r\n * Guest history keeps its separate explicit import/keep-local consent flow. */\r\nexport function createPerformanceAccountSync({getAccount,getRows,api,transitions,onAccount,storage=globalThis.localStorage,maxUploads=20}={}){\r\n if(typeof getAccount!=='function'||typeof getRows!=='function'||typeof api!=='function'||!Number.isSafeInteger(maxUploads)||maxUploads<1||maxUploads>500)throw TypeError('Account workout sync requires scoped readers and API access.');\r\n let running=null,rerun=false;const memoryReceipts=new Map(),needsRefresh=new Set();\r\n async function once(attempted){\r\n  const account=getAccount(),actor=identity(account),result={synced:0,skipped:0,failed:[],aborted:false};if(!actor)return result;\r\n  const owner=performanceOwner(null,account),cacheKey=`${CACHE}/${owner}`;let receipts={};try{const value=JSON.parse(storage?.getItem(cacheKey)||'{}');if(value&&typeof value==='object'&&!Array.isArray(value))receipts=value;}catch{}receipts={...receipts,...(memoryReceipts.get(owner)??{})};memoryReceipts.set(owner,receipts);\r\n  const ticket=transitions?.capture?.(),current=()=>{if(!same(actor,identity(getAccount())))throw Object.assign(Error('Account changed during workout sync.'),{code:'account_scope_changed'});transitions?.assertCurrent?.(ticket);};\r\n  let rows;try{current();rows=await getRows();current();}catch(error){result.aborted=true;result.failed.push({id:null,error:error.message});return result;}\r\n  const eligible=(rows??[]).filter(row=>row?.status==='completed'&&row.progress?.performance?.performanceOwner===owner&&!row.progress.performance.preparation&&row.progress.performance.earned!==false&&!attempted.has(JSON.stringify([owner,row.id]))).sort((a,b)=>(a.completedAt??0)-(b.completedAt??0)||String(a.id).localeCompare(String(b.id)));\r\n  let uploads=0;\r\n  for(const row of eligible){\r\n   if(uploads>=maxUploads){rerun=true;break;}\r\n   attempted.add(JSON.stringify([owner,row.id]));\r\n   try{\r\n    current();const snapshot=snapshotFromCompletedWorkout(row);if(!snapshot.performance)throw Error('This workout lacks the performance evidence needed for account rewards.');\r\n    const prepared=await prepareWorkoutImport(snapshot,{targetAccountId:actor.id,targetDataEpoch:actor.epoch});current();\r\n    if(receipts[snapshot.clientWorkoutId]===prepared.fingerprint){result.skipped++;continue;}\r\n    uploads++;\r\n    const value=await api('/api/workouts/import','POST',{digestVersion:prepared.digestVersion,targetDataEpoch:actor.epoch,snapshot:prepared.snapshot,fingerprint:prepared.fingerprint},{'X-Target-Account':actor.id,'X-Expected-Data-Epoch':String(actor.epoch),'Idempotency-Key':prepared.idempotencyKey});current();\r\n    const receipt=value?.receipt,w=value?.workout;\r\n    if(receipt?.targetAccountId!==actor.id||receipt.targetDataEpoch!==actor.epoch||receipt.digestVersion!==prepared.digestVersion||receipt.fingerprint!==prepared.fingerprint||receipt.idempotencyKey!==prepared.idempotencyKey||w?.user_id!==actor.id||w.client_workout_id!==snapshot.clientWorkoutId||w.source!=='guest_import'||w.competitive_status!=='not_eligible')throw Error('Workout sync returned an unmatched receipt.');\r\n    receipts[snapshot.clientWorkoutId]=prepared.fingerprint;needsRefresh.add(owner);try{storage?.setItem(cacheKey,JSON.stringify(receipts));}catch{/* In-memory receipts and server idempotence keep retry behavior bounded. */}result.synced++;\r\n   }catch(error){if(!same(actor,identity(getAccount()))||['auth_transition','account_scope_changed'].includes(error.code)){result.aborted=true;break;}result.failed.push({id:row.id,error:error.message});}\r\n  }\r\n  if(needsRefresh.has(owner)){try{current();const value=await api('/api/account?core=1');current();if(!same(actor,identity(value)))throw Error('Account progress returned an unmatched identity.');await onAccount?.(value);current();needsRefresh.delete(owner);}catch(error){result.failed.push({id:null,error:error.message});if(!same(actor,identity(getAccount())))result.aborted=true;}}\r\n  return result;\r\n }\r\n async function drain(){const total={synced:0,skipped:0,failed:[],aborted:false},attempted=new Set();do{rerun=false;const result=await once(attempted);total.synced+=result.synced;total.skipped+=result.skipped;total.failed.push(...result.failed);total.aborted||=result.aborted;}while(rerun&&identity(getAccount()));return total;}\r\n return {flush(){if(running){rerun=true;return running;}running=drain().finally(()=>{running=null;});return running;},get running(){return !!running;}};\r\n}\r\n","performance-catalog.mjs":"import {EXERCISES,GROUP_EXERCISES} from './exercise-library.mjs';\r\nimport {coachName,EXCLUDED_COACH_IDS} from './coach-names.mjs';\r\nexport {EXCLUDED_COACH_IDS};\r\n// Provisional cadence defaults for modes without a user-specified unlock threshold.\r\n// These are performance/completion requirements; XP never unlocks coaches.\r\nexport const CADENCE_MILESTONES=Object.freeze({sprintRounds:5,gentleActiveSeconds:300,paceActiveSeconds:300,meditationDays:Object.freeze([3,6,9,12])});\r\n// sourceLabel is the old roster/source metadata; label is the centralized coach name.\r\nconst SOURCE_COACHES=[{\"id\":\"myr5\",\"sourceLabel\":\"Original MYR5\"},{\"id\":\"roster/01-seed-pearo--3d_character_model\",\"sourceLabel\":\"Seed · Pearo 1\",\"group\":\"Seed · Pearo\"},{\"id\":\"roster/01-seed-pearo--cute_alien_figure_3d_model\",\"sourceLabel\":\"Seed · Pearo 2\",\"group\":\"Seed · Pearo\"},{\"id\":\"roster/01-seed-pearo--blank_toy_figure_3d_model\",\"sourceLabel\":\"Seed · Pearo 5\",\"group\":\"Seed · Pearo\"},{\"id\":\"roster/02-taper-tallstalk--3d_humanoid_figure\",\"sourceLabel\":\"Taper · Tallstalk 1\",\"group\":\"Taper · Tallstalk\"},{\"id\":\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\"sourceLabel\":\"Taper · Tallstalk 2\",\"group\":\"Taper · Tallstalk\"},{\"id\":\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",\"sourceLabel\":\"Taper · Tallstalk 3\",\"group\":\"Taper · Tallstalk\"},{\"id\":\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",\"sourceLabel\":\"Pearl · Orb 1\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/03-pearl-orb-ring--circle_center\",\"sourceLabel\":\"Pearl · Orb 2\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\"sourceLabel\":\"Pearl · Orb 3\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/03-pearl-orb-ring--robot_3d_model\",\"sourceLabel\":\"Pearl · Orb 4\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_3d_character1\",\"sourceLabel\":\"Pearl · Orb 5\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"sourceLabel\":\"Pearl · Orb 6\",\"group\":\"Pearl · Orb\"},{\"id\":\"roster/04-crest-wedge--robot_creature_3d_model\",\"sourceLabel\":\"Crest · Wedge 1\",\"group\":\"Crest · Wedge\"},{\"id\":\"roster/04-crest-wedge--stylized_3d_character\",\"sourceLabel\":\"Crest · Wedge 2\",\"group\":\"Crest · Wedge\"},{\"id\":\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\"sourceLabel\":\"Slope · Bobble 1\",\"group\":\"Slope · Bobble\"},{\"id\":\"roster/06-ridge-triad--geometric_robot_3d_model1\",\"sourceLabel\":\"Ridge · Triad 1\",\"group\":\"Ridge · Triad\"},{\"id\":\"roster/06-ridge-triad--robot_3d_model1\",\"sourceLabel\":\"Ridge · Triad 2\",\"group\":\"Ridge · Triad\"},{\"id\":\"roster/07-bulb-sphereling--cute_robot_3d_model\",\"sourceLabel\":\"Bulb · Sphereling 1\",\"group\":\"Bulb · Sphereling\"},{\"id\":\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\"sourceLabel\":\"Bulb · Sphereling 2\",\"group\":\"Bulb · Sphereling\"},{\"id\":\"roster/08-shard-asym--geometric_robot_3d_model\",\"sourceLabel\":\"Shard · Asym 1\",\"group\":\"Shard · Asym\"},{\"id\":\"roster/08-shard-asym--robot_3d_model4\",\"sourceLabel\":\"Shard · Asym 2\",\"group\":\"Shard · Asym\"},{\"id\":\"roster/08-shard-asym--fantasy_creature_3d_model2\",\"sourceLabel\":\"Shard · Asym 3\",\"group\":\"Shard · Asym\"},{\"id\":\"roster/08-shard-asym--stylized_action_figure_3d_model\",\"sourceLabel\":\"Shard · Asym 4\",\"group\":\"Shard · Asym\"},{\"id\":\"roster/09-monolith-tanka--3d_robot_model\",\"sourceLabel\":\"Monolith · Tanka 1\",\"group\":\"Monolith · Tanka\"},{\"id\":\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\"sourceLabel\":\"Monolith · Tanka 2\",\"group\":\"Monolith · Tanka\"},{\"id\":\"roster/09-monolith-tanka--mini_robot_3d_model\",\"sourceLabel\":\"Monolith · Tanka 3\",\"group\":\"Monolith · Tanka\"},{\"id\":\"roster/09-monolith-tanka--robot_3d_model3\",\"sourceLabel\":\"Monolith · Tanka 5\",\"group\":\"Monolith · Tanka\"},{\"id\":\"roster/09-monolith-tanka--white_horned_robot_3d_model\",\"sourceLabel\":\"Monolith · Tanka 6\",\"group\":\"Monolith · Tanka\"},{\"id\":\"roster/10-petal-wisp--stylized_creature_3d_model\",\"sourceLabel\":\"Petal · Wisp 1\",\"group\":\"Petal · Wisp\"},{\"id\":\"roster/10-petal-wisp--ghost_character_3d_model\",\"sourceLabel\":\"Petal · Wisp 2\",\"group\":\"Petal · Wisp\"},{\"id\":\"roster/10-petal-wisp--fantasy_creature_3d_model4\",\"sourceLabel\":\"Petal · Wisp 3\",\"group\":\"Petal · Wisp\"},{\"id\":\"roster/11-anvil-cask--clay-style_robot_3d_model\",\"sourceLabel\":\"Anvil · Cask 1\",\"group\":\"Anvil · Cask\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\"sourceLabel\":\"Seedpod · Snailslug 1\",\"group\":\"Seedpod · Snailslug\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\"sourceLabel\":\"Seedpod · Snailslug 2\",\"group\":\"Seedpod · Snailslug\"},{\"id\":\"roster/13-fan-split--stylized_3d_character2\",\"sourceLabel\":\"Fan · Split 1\",\"group\":\"Fan · Split\"},{\"id\":\"roster/13-fan-split--stylized_toy_3d_model\",\"sourceLabel\":\"Fan · Split 2\",\"group\":\"Fan · Split\"},{\"id\":\"roster/14-chisel-spire--cone_head_3d_model\",\"sourceLabel\":\"Chisel · Spire 1\",\"group\":\"Chisel · Spire\"},{\"id\":\"roster/14-chisel-spire--low_poly_robot_3d_model\",\"sourceLabel\":\"Chisel · Spire 2\",\"group\":\"Chisel · Spire\"},{\"id\":\"roster/15-orbital-coili--robot_character_3d_model\",\"sourceLabel\":\"Orbital · Coili 1\",\"group\":\"Orbital · Coili\"},{\"id\":\"roster/16-spade-arch--pyramid_head_figure_3d_model\",\"sourceLabel\":\"Spade · Arch 1\",\"group\":\"Spade · Arch\"},{\"id\":\"roster/16-spade-arch--stylized_humanoid_3d_model\",\"sourceLabel\":\"Spade · Arch 2\",\"group\":\"Spade · Arch\"},{\"id\":\"roster/17-shellcap-manyarm--3d_character_figurine\",\"sourceLabel\":\"Shellcap · Manyarm 1\",\"group\":\"Shellcap · Manyarm\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\"sourceLabel\":\"Shellcap · Manyarm 2\",\"group\":\"Shellcap · Manyarm\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\"sourceLabel\":\"Shellcap · Manyarm 3\",\"group\":\"Shellcap · Manyarm\"},{\"id\":\"roster/18-quad-all--dragon_creature_3d_model\",\"sourceLabel\":\"Four-legged 1\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model1\",\"sourceLabel\":\"Four-legged 2\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model3\",\"sourceLabel\":\"Four-legged 3\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--four-legged_robot_3d_model\",\"sourceLabel\":\"Four-legged 4\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model1\",\"sourceLabel\":\"Four-legged 5\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model\",\"sourceLabel\":\"Four-legged 6\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--robotic_dog_3d_model\",\"sourceLabel\":\"Four-legged 7\",\"group\":\"Four-legged\"},{\"id\":\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",\"sourceLabel\":\"Four-legged 9\",\"group\":\"Four-legged\"},{\"id\":\"roster/19-genie-multi--fantasy_creature_3d_model\",\"sourceLabel\":\"Genie · Multi 1\",\"group\":\"Genie · Multi\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\"sourceLabel\":\"Genie · Multi 2\",\"group\":\"Genie · Multi\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\"sourceLabel\":\"Genie · Multi 3\",\"group\":\"Genie · Multi\"},{\"id\":\"roster/19-genie-multi--stylized_octopus_3d_model\",\"sourceLabel\":\"Genie · Multi 4\",\"group\":\"Genie · Multi\"},{\"id\":\"roster/20-lume--robotic_figure_3d_model\",\"sourceLabel\":\"Lume 1\",\"group\":\"Lume\"},{\"id\":\"roster/22-curve--stylized_alien_3d_model\",\"sourceLabel\":\"Curve 1\",\"group\":\"Curve\"},{\"id\":\"roster/22-curve--stylized_cartoon_figure_3d_model\",\"sourceLabel\":\"Curve 2\",\"group\":\"Curve\"},{\"id\":\"roster/23-blob-texture-bodies--blob_creature_3d_model\",\"sourceLabel\":\"Blob 1\",\"group\":\"Blob\"},{\"id\":\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",\"sourceLabel\":\"Blob 2\",\"group\":\"Blob\"},{\"id\":\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"sourceLabel\":\"Blob 3\",\"group\":\"Blob\"},{\"id\":\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"sourceLabel\":\"Blob 4\",\"group\":\"Blob\"},{\"id\":\"roster/23-blob-texture-bodies--sand_creature_3d_model\",\"sourceLabel\":\"Blob 5\",\"group\":\"Blob\"}];\r\nexport const COACHES=SOURCE_COACHES.map(c=>({...c,label:coachName(c.id)}));\r\n// The first block keeps the difficulties of the old sibling-position formula, frozen so earlier\r\n// achievements do not shift. The appended block is the former implicit starters, now earnable.\r\nconst placements=[{\"id\":\"roster/23-blob-texture-bodies--blob_creature_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"easy\"},{\"id\":\"roster/18-quad-all--dragon_creature_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"easy\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model1\",\"tracks\":[\"meditation\"],\"difficulty\":\"easy\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model3\",\"tracks\":[\"meditation\"],\"difficulty\":\"easy\"},{\"id\":\"roster/18-quad-all--four-legged_robot_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"medium\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model1\",\"tracks\":[\"meditation\"],\"difficulty\":\"medium\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"hard\"},{\"id\":\"roster/18-quad-all--robotic_dog_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"hard\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"hard\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"expert\"},{\"id\":\"roster/14-chisel-spire--low_poly_robot_3d_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"expert\"},{\"id\":\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"easy\"},{\"id\":\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"easy\"},{\"id\":\"roster/06-ridge-triad--robot_3d_model1\",\"tracks\":[\"cardio\"],\"difficulty\":\"medium\"},{\"id\":\"roster/03-pearl-orb-ring--robot_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"hard\"},{\"id\":\"roster/20-lume--robotic_figure_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"expert\"},{\"id\":\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\"tracks\":[\"arms\"],\"difficulty\":\"easy\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\"tracks\":[\"arms\"],\"difficulty\":\"easy\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\"tracks\":[\"arms\"],\"difficulty\":\"medium\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\"tracks\":[\"arms\"],\"difficulty\":\"medium\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\"tracks\":[\"arms\"],\"difficulty\":\"hard\"},{\"id\":\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"tracks\":[\"arms\"],\"difficulty\":\"hard\"},{\"id\":\"roster/08-shard-asym--robot_3d_model4\",\"tracks\":[\"arms\"],\"difficulty\":\"expert\"},{\"id\":\"roster/06-ridge-triad--geometric_robot_3d_model1\",\"tracks\":[\"chest\"],\"difficulty\":\"easy\"},{\"id\":\"roster/08-shard-asym--geometric_robot_3d_model\",\"tracks\":[\"chest\"],\"difficulty\":\"easy\"},{\"id\":\"roster/16-spade-arch--pyramid_head_figure_3d_model\",\"tracks\":[\"chest\",\"martial-arts\"],\"difficulty\":\"medium\"},{\"id\":\"roster/04-crest-wedge--robot_creature_3d_model\",\"tracks\":[\"chest\"],\"difficulty\":\"hard\"},{\"id\":\"roster/16-spade-arch--stylized_humanoid_3d_model\",\"tracks\":[\"chest\"],\"difficulty\":\"expert\"},{\"id\":\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"tracks\":[\"glutes\"],\"difficulty\":\"easy\"},{\"id\":\"roster/23-blob-texture-bodies--sand_creature_3d_model\",\"tracks\":[\"glutes\"],\"difficulty\":\"medium\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_3d_character1\",\"tracks\":[\"glutes\"],\"difficulty\":\"hard\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"tracks\":[\"glutes\"],\"difficulty\":\"expert\"},{\"id\":\"roster/15-orbital-coili--robot_character_3d_model\",\"tracks\":[\"quads\"],\"difficulty\":\"easy\"},{\"id\":\"roster/13-fan-split--stylized_3d_character2\",\"tracks\":[\"quads\"],\"difficulty\":\"medium\"},{\"id\":\"roster/22-curve--stylized_cartoon_figure_3d_model\",\"tracks\":[\"quads\"],\"difficulty\":\"hard\"},{\"id\":\"roster/10-petal-wisp--fantasy_creature_3d_model4\",\"tracks\":[\"yoga\"],\"difficulty\":\"easy\"},{\"id\":\"roster/19-genie-multi--fantasy_creature_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"easy\"},{\"id\":\"roster/10-petal-wisp--ghost_character_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"medium\"},{\"id\":\"roster/08-shard-asym--stylized_action_figure_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"medium\"},{\"id\":\"roster/22-curve--stylized_alien_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"hard\"},{\"id\":\"roster/10-petal-wisp--stylized_creature_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"hard\"},{\"id\":\"roster/19-genie-multi--stylized_octopus_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"expert\"},{\"id\":\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"easy\"},{\"id\":\"roster/11-anvil-cask--clay-style_robot_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"easy\"},{\"id\":\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"medium\"},{\"id\":\"roster/14-chisel-spire--cone_head_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"medium\"},{\"id\":\"roster/08-shard-asym--fantasy_creature_3d_model2\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"hard\"},{\"id\":\"roster/09-monolith-tanka--mini_robot_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"hard\"},{\"id\":\"roster/09-monolith-tanka--robot_3d_model3\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"expert\"},{\"id\":\"roster/13-fan-split--stylized_toy_3d_model\",\"tracks\":[\"martial-arts\"],\"difficulty\":\"expert\"},\r\n{\"id\":\"roster/01-seed-pearo--3d_character_model\",\"tracks\":[\"meditation\"],\"difficulty\":\"medium\"},\r\n{\"id\":\"roster/01-seed-pearo--cute_alien_figure_3d_model\",\"tracks\":[\"yoga\"],\"difficulty\":\"hard\"},\r\n{\"id\":\"roster/01-seed-pearo--blank_toy_figure_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"hard\"},\r\n{\"id\":\"roster/02-taper-tallstalk--3d_humanoid_figure\",\"tracks\":[\"quads\"],\"difficulty\":\"hard\"},\r\n{\"id\":\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",\"tracks\":[\"quads\"],\"difficulty\":\"expert\"},\r\n{\"id\":\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",\"tracks\":[\"glutes\"],\"difficulty\":\"easy\"},\r\n{\"id\":\"roster/03-pearl-orb-ring--circle_center\",\"tracks\":[\"glutes\"],\"difficulty\":\"medium\"},\r\n{\"id\":\"roster/04-crest-wedge--stylized_3d_character\",\"tracks\":[\"chest\"],\"difficulty\":\"easy\"},\r\n{\"id\":\"roster/07-bulb-sphereling--cute_robot_3d_model\",\"tracks\":[\"cardio\"],\"difficulty\":\"medium\"},\r\n{\"id\":\"roster/09-monolith-tanka--3d_robot_model\",\"tracks\":[\"chest\"],\"difficulty\":\"medium\"},\r\n{\"id\":\"roster/09-monolith-tanka--white_horned_robot_3d_model\",\"tracks\":[\"chest\"],\"difficulty\":\"hard\"},\r\n{\"id\":\"roster/17-shellcap-manyarm--3d_character_figurine\",\"tracks\":[\"arms\"],\"difficulty\":\"expert\"},\r\n{\"id\":\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",\"tracks\":[\"quads\"],\"difficulty\":\"medium\"},\r\n{\"id\":\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",\"tracks\":[\"glutes\"],\"difficulty\":\"hard\"}];\r\nconst groups={chest:['chest'],quads:['legs'],glutes:['hips'],arms:['shoulders'],yoga:['core','balance','yoga'],'martial-arts':['stances','boxing'],cardio:['cardio'],meditation:['meditation']};\r\n// Paths the user can pick. arms-shoulders is the chosen-styles id for the catalog track arms.\r\nexport const CHOOSABLE_TRACKS=Object.freeze(['chest','quads','glutes','arms-shoulders','yoga','martial-arts','cardio']);\r\nexport const PATH_TRACK_ALIASES=Object.freeze({arms:'arms-shoulders'});\r\nconst catalogTrack=path=>path==='arms-shoulders'?'arms':path;\r\n/** Canonical, de-duplicated choosable ids; unknown ids are dropped and \"arms\" becomes \"arms-shoulders\". */\r\nexport const normalizePaths=ids=>[...new Set((Array.isArray(ids)?ids:[]).map(id=>PATH_TRACK_ALIASES[id]??id).filter(id=>CHOOSABLE_TRACKS.includes(id)))];\r\nexport const WEAPON_GROUPS={chest:['crossbow','cannon'],legs:['greatsword','hammer'],hips:['scythe','halberd'],core:['mace','tome'],shoulders:['bow','trident'],balance:['axe','sabre'],yoga:['staff','wand'],stances:['dagger','spear'],boxing:['gauntlets','rapier'],cardio:['chakram','flail']};\r\nexport const STARTER_COACH_IDS=Object.freeze(['myr5','roster/23-blob-texture-bodies--blob_creature_3d_model']);\r\nexport function exerciseDifficulty(mode){const e=EXERCISES[mode];if(!e)return 'easy';const rows=GROUP_EXERCISES[e.group].filter(x=>x.kind===e.kind);return ['easy','medium','hard','expert'][Math.min(3,Math.floor(rows.indexOf(e)*4/rows.length))];}\r\nexport const COACH_REQUIREMENTS=placements.filter(p=>!STARTER_COACH_IDS.includes(p.id)).map(p=>({...p,name:coachName(p.id),groups:p.tracks.flatMap(t=>groups[t])}));\r\n// One introductory coach per path: the first easy coach whose primary track it is.\r\nexport const PATH_INTRO_COACH_IDS=Object.freeze(Object.fromEntries(CHOOSABLE_TRACKS.map(path=>[path,COACH_REQUIREMENTS.find(c=>c.tracks[0]===catalogTrack(path)&&c.difficulty==='easy').id])));\r\nexport const pathIntroCoachIds=paths=>normalizePaths(paths).map(path=>PATH_INTRO_COACH_IDS[path]);\r\nexport const SHIP_REQUIREMENTS=[{id:'supportive',group:'legs',kind:'hold'},{id:'direct',group:'legs',kind:'reps'},{id:'analytical',group:'chest',kind:'reps'},{id:'playful',group:'stances',kind:'hold'},{id:'calm',group:'yoga',kind:'hold'},{id:'mom',group:'hips',kind:'reps'}];\r\nexport function matchingCoaches(group,difficulty){return COACH_REQUIREMENTS.filter(c=>c.groups.includes(group)&&c.difficulty===difficulty);}\r\n","performance-import-codec.mjs":"import {EXERCISES} from './exercise-library.mjs';\r\nimport {COACHES} from './performance-catalog.mjs';\r\nimport {DIFFICULTIES,holdXp,repXp,SPRINT_ROUND_XP,GENTLE_BLOCK_XP,clampBonusXp} from './progression-rules.mjs';\r\nconst keys=['version','kind','difficulty','maxContinuousSeconds','perDifficultyContinuous','holdBlocks','coachId','rounds'];\r\nfunction data(raw){if(!raw||typeof raw!=='object'||Array.isArray(raw)||![Object.prototype,null].includes(Object.getPrototypeOf(raw)))throw Error('Invalid performance metadata.');const descriptors=Object.getOwnPropertyDescriptors(raw);if(Reflect.ownKeys(descriptors).some(k=>typeof k!=='string'||!Object.hasOwn(descriptors[k],'value')||!descriptors[k].enumerable))throw Error('Invalid performance metadata.');return Object.fromEntries(Object.entries(descriptors).map(([k,v])=>[k,v.value]));}\r\nconst finite=(n,max)=>Number.isFinite(n)&&n>=0&&n<=max;\r\nexport function validateImportedPerformance(raw,snapshot){\r\n const p=data(raw),e=EXERCISES[snapshot.mode],active=Math.min(1800,snapshot.activeSeconds);\r\n if(Object.keys(p).length!==keys.length+(Object.hasOwn(p,'bonusXp')?1:0)||keys.some(k=>!Object.hasOwn(p,k))||p.version!==2||!e||!DIFFICULTIES.includes(p.difficulty)||!finite(p.maxContinuousSeconds,active)||!Number.isInteger(p.rounds)||p.rounds<0||p.rounds>5||!(p.coachId===null||COACHES.some(c=>c.id===p.coachId)))throw Error('Invalid performance metadata.');\r\n const allowed=e.kind==='hold'?['hold']:e.group==='cardio'?['sprint','gentle']:e.kind==='pace'?['pace','gentle']:['reps'];if(!allowed.includes(p.kind)||p.kind==='reps'&&!Number.isSafeInteger(snapshot.value))throw Error('Performance kind does not match the exercise.');\r\n const continuous=data(p.perDifficultyContinuous);if(Object.entries(continuous).some(([d,n])=>!DIFFICULTIES.includes(d)||!finite(n,active))||Object.values(continuous).reduce((a,b)=>a+b,0)>active+1e-7)throw Error('Invalid continuous hold evidence.');\r\n if(!Array.isArray(p.holdBlocks)||p.holdBlocks.length>120)throw Error('Invalid paid hold blocks.');\r\n const blocks=p.holdBlocks.map((raw,index)=>{const b=data(raw);if(Object.keys(b).length!==3||!DIFFICULTIES.includes(b.difficulty)||b.activeStart!==index*15||!finite(b.continuousStart,b.activeStart)||b.continuousStart>=(continuous[b.difficulty]??0)&&b.continuousStart>=600)throw Error('Invalid paid hold blocks.');return {difficulty:b.difficulty,activeStart:b.activeStart,continuousStart:b.continuousStart};});\r\n if(p.kind==='hold'&&blocks.length!==Math.floor(active/15)||p.kind!=='hold'&&(blocks.length||Object.keys(continuous).length||p.maxContinuousSeconds)||p.kind==='sprint'&&(snapshot.activeSeconds+1e-7<p.rounds*15||snapshot.elapsedSeconds+1e-7<p.rounds*60))throw Error('Performance exceeds completed exercise time.');\r\n return {version:2,kind:p.kind,difficulty:p.difficulty,maxContinuousSeconds:p.maxContinuousSeconds,perDifficultyContinuous:Object.fromEntries(DIFFICULTIES.filter(d=>Object.hasOwn(continuous,d)).map(d=>[d,continuous[d]])),holdBlocks:blocks,coachId:p.coachId,rounds:p.rounds,...(Number.isSafeInteger(p.bonusXp)&&p.bonusXp>0?{bonusXp:p.bonusXp}:{})};\r\n}\r\nexport function projectImportedPerformance(raw,snapshot){const p=data(raw);return validateImportedPerformance({version:2,kind:p.kind,difficulty:p.difficulty,maxContinuousSeconds:p.maxContinuousSeconds??0,perDifficultyContinuous:p.kind==='hold'?(p.perDifficultyContinuous??{[p.difficulty]:p.maxContinuousSeconds??0}):{},holdBlocks:p.holdBlocks??[],coachId:p.coachId??null,rounds:p.kind==='sprint'?(p.rounds??0):0,...(Object.hasOwn(p,'bonusXp')?{bonusXp:p.bonusXp}:{})},snapshot);}\r\nexport function importedPerformanceXp(snapshot){const p=validateImportedPerformance(snapshot.performance,snapshot);let base;if(p.kind==='hold')base=p.holdBlocks.reduce((sum,b)=>sum+holdXp({difficulty:b.difficulty,from:b.activeStart,to:b.activeStart+15,continuousAtFrom:b.continuousStart}),0);else if(p.kind==='reps')base=repXp({difficulty:p.difficulty,to:Math.floor(snapshot.value)});else if(p.kind==='sprint')base=p.rounds*SPRINT_ROUND_XP;else base=Math.floor(Math.min(1800,snapshot.activeSeconds)/15)*GENTLE_BLOCK_XP;return base+clampBonusXp(p.bonusXp,base);}\r\n","performance-progress.mjs":"import {EXERCISES} from './exercise-library.mjs';\r\nimport {COACHES,COACH_REQUIREMENTS,STARTER_COACH_IDS,EXCLUDED_COACH_IDS,PATH_INTRO_COACH_IDS,CHOOSABLE_TRACKS,normalizePaths,pathIntroCoachIds,matchingCoaches,exerciseDifficulty,WEAPON_GROUPS,SHIP_REQUIREMENTS,CADENCE_MILESTONES} from './performance-catalog.mjs';\r\nimport {holdXp,repXp,performanceMilestones,performanceWeaponTier,coachXpMultiplier,DIFFICULTIES,XP_SCALE,DAILY_TRIO_BONUS} from './progression-rules.mjs';\r\nexport const PERFORMANCE_KEY='myr5-performance-progress-v2';\r\nexport function performanceOwner(storage=globalThis.localStorage,account=globalThis.myr5AuthenticatedAccount){\r\n const id=account?.user?.id;if(id)return `account:${id}${account.dataEpoch!=null?`:${account.dataEpoch}`:''}`;\r\n if(!storage)return 'guest:unavailable';\r\n const key='myr5-local-guest-owner-v1';try{let guest=storage.getItem(key);if(!guest){guest=globalThis.crypto?.randomUUID?.()||`guest-${Date.now()}-${Math.random()}`;storage.setItem(key,guest);}return `guest:${guest}`;}catch{return 'guest:unavailable';}\r\n}\r\nexport function localDay(time=Date.now()){const date=new Date(time);return `${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')}`;}\r\n// accessVersion 3: coaches are only the explicit starters plus earned coaches and the two chosen\r\n// path introductions. Older records also held every unplaced coach as an implicit starter.\r\nexport const ACCESS_VERSION=3;\r\nconst fresh=()=>({version:2,accessVersion:ACCESS_VERSION,xpScale:XP_SCALE,paths:[],sessions:{},days:{},coaches:[...STARTER_COACH_IDS],goldenCoaches:[],weapons:{},ships:[],completions:{},totalXp:0,excludedCoaches:[]});\r\nfunction scope(options={}){const storage=Object.hasOwn(options,'storage')?options.storage:globalThis.localStorage,account=Object.hasOwn(options,'account')?options.account:globalThis.myr5AuthenticatedAccount;return {storage,owner:options.owner??performanceOwner(storage,account)};}\r\nconst object=v=>v&&typeof v==='object'&&!Array.isArray(v);\r\nconst finite=v=>Number.isFinite(v)&&v>=0;\r\nconst validDay=day=>typeof day==='string'&&/^\\d{4}-\\d{2}-\\d{2}$/.test(day)&&new Date(`${day}T12:00:00Z`).toISOString().slice(0,10)===day;\r\nconst validPaths=p=>Array.isArray(p)&&(p.length===0||(p.length===2&&new Set(p).size===2&&p.every(id=>CHOOSABLE_TRACKS.includes(id))));\r\n/** Shape check for a stored or synced performance record (client cache and server alike). */\r\nexport function validPerformanceState(v){return validState(v);}\r\nfunction validState(v){return v?.version===2&&(v.accessVersion===undefined||v.accessVersion===ACCESS_VERSION)&&(v.xpScale===undefined||v.xpScale===XP_SCALE)&&(v.paths===undefined||validPaths(v.paths))&&(v.activities===undefined||(object(v.activities)&&Object.values(v.activities).every(a=>object(a)&&['meditation','food'].includes(a.kind)&&validDay(a.day))))&&object(v.sessions)&&object(v.days)&&object(v.weapons)&&object(v.completions)&&Array.isArray(v.coaches)&&v.coaches.every(id=>COACHES.some(c=>c.id===id)||EXCLUDED_COACH_IDS.includes(id))&&new Set(v.coaches).size===v.coaches.length&&Array.isArray(v.goldenCoaches)&&v.goldenCoaches.every(id=>v.coaches.includes(id))&&Array.isArray(v.ships)&&v.ships.every(id=>SHIP_REQUIREMENTS.some(s=>s.id===id))&&Object.values(v.weapons).every(n=>Number.isInteger(n)&&n>=0&&n<=20)&&Object.values(v.completions).every(n=>Number.isSafeInteger(n)&&n>=0)&&Object.entries(v.days).every(([day,d])=>validDay(day)&&object(d)&&finite(d.workoutXp)&&['workout','meditation','food'].every(k=>typeof d[k]==='boolean'))&&Object.values(v.sessions).every(s=>object(s)&&validDay(s.day)&&finite(s.xp)&&finite(s.value)&&finite(s.continuous));}\r\n// Coaches a record has really earned, rebuilt from its own history: the explicit starters, the\r\n// session milestones recordPerformanceSession applies, and completed meditation days.\r\nconst CADENCE_COUNT={sprint:CADENCE_MILESTONES.sprintRounds,gentle:CADENCE_MILESTONES.gentleActiveSeconds,pace:CADENCE_MILESTONES.paceActiveSeconds};\r\nfunction earnedCoaches(state){\r\n const earned=new Set(STARTER_COACH_IDS),grant=(group,level)=>{for(const coach of matchingCoaches(group,level))earned.add(coach.id);};\r\n for(const s of Object.values(state.sessions)){\r\n  if(s.kind==='hold'||s.kind==='reps'){\r\n   for(const [level,performance] of s.kind==='hold'?Object.entries(s.perDifficultyContinuous??{[s.difficulty]:s.continuous}):[[s.difficulty,s.value]])\r\n    if(finite(performance)&&performanceMilestones(s.kind,performance).coach)grant(s.group,level);\r\n  }else if(s.kind in CADENCE_COUNT&&s.value>=CADENCE_COUNT[s.kind])grant(s.group,s.difficulty);\r\n }\r\n const days=Object.values(state.days).filter(d=>d.meditation).length;\r\n DIFFICULTIES.forEach((level,i)=>{if(days>=CADENCE_MILESTONES.meditationDays[i])grant('meditation',level);});\r\n return earned;\r\n}\r\n/** Brings a validated record (client cache or synced copy) to the current access rules, in place.\r\n * Pre-v3 records are rebuilt from earnedCoaches() plus the chosen paths, so implicit starters are\r\n * dropped while sessions, days, XP, weapons and ships are untouched. Uses only the record itself. */\r\nexport function migratePerformanceAccess(state){\r\n // XP rescale: a record without the xpScale marker holds x1 XP. Multiply once, then mark; later runs skip.\r\n if(state.xpScale!==XP_SCALE){for(const d of Object.values(state.days))d.workoutXp*=XP_SCALE;for(const s of Object.values(state.sessions))s.xp*=XP_SCALE;state.xpScale=XP_SCALE;}\r\n state.excludedCoaches??=[];for(const id of EXCLUDED_COACH_IDS)if(!state.excludedCoaches.includes(id))state.excludedCoaches.push(id);\r\n state.paths??=[];\r\n if(state.accessVersion!==ACCESS_VERSION){\r\n  const keep=new Set([...earnedCoaches(state),...pathIntroCoachIds(state.paths)]);\r\n  state.coaches=COACHES.map(c=>c.id).filter(id=>keep.has(id));state.accessVersion=ACCESS_VERSION;\r\n }\r\n state.coaches=state.coaches.filter(id=>!EXCLUDED_COACH_IDS.includes(id));for(const id of STARTER_COACH_IDS)unique(state.coaches,id);\r\n state.goldenCoaches=state.goldenCoaches.filter(id=>state.coaches.includes(id));\r\n return state;\r\n}\r\nexport function readPerformanceProgress(options={}){try{const {storage,owner}=scope(options),value=JSON.parse(storage?.getItem(`${PERFORMANCE_KEY}/${owner}`)||'null');return validState(value)?recalculate(migratePerformanceAccess(value)):fresh();}catch{return fresh();}}\r\n/** One-time choice of exactly 2 paths (chosen-styles ids) for the options owner; grants and persists\r\n * their introductory coaches. The same pair is a no-op, a different pair needs options.reset. A reset\r\n * swaps the introductions (still exactly two) and never revokes earned coaches. */\r\nexport function choosePerformancePaths(ids,options={}){\r\n const paths=normalizePaths(ids);if(paths.length!==2)throw RangeError('Exactly 2 workout paths must be selected.');\r\n const state=readPerformanceProgress(options);\r\n if(state.paths.length){if(paths.every(p=>state.paths.includes(p)))return state;if(!options.reset)throw RangeError('Workout paths are already chosen.');}\r\n const earned=earnedCoaches(state),previous=pathIntroCoachIds(state.paths);\r\n state.coaches=state.coaches.filter(id=>!previous.includes(id)||earned.has(id));\r\n for(const id of pathIntroCoachIds(paths))unique(state.coaches,id);\r\n state.paths=paths;\r\n return save(state,options);\r\n}\r\nfunction save(state,options){const {storage,owner}=scope(options);if(!storage)throw Error('Progress storage is unavailable.');storage.setItem(`${PERFORMANCE_KEY}/${owner}`,JSON.stringify(state));if(typeof globalThis.CustomEvent==='function')globalThis.dispatchEvent?.(new CustomEvent('myr5:performance-progress',{detail:{owner,progress:state}}));return state;}\r\nfunction dayEntry(state,day){if(!validDay(day))throw RangeError('Invalid workout day.');return state.days[day]??=( {workoutXp:0,workout:false,meditation:false,food:false});}\r\nfunction recalculate(state){state.totalXp=Object.values(state.days).reduce((sum,d)=>sum+d.workoutXp*(d.meditation?2:1)+(d.workout&&d.meditation&&d.food?DAILY_TRIO_BONUS:0),0)+(Number.isFinite(state.worldBonusXp)&&state.worldBonusXp>=0?state.worldBonusXp:0);return state;}\nexport function recordDailyActivity(kind,{day=localDay(),id}={},options={}){if(!['meditation','food'].includes(kind))throw RangeError('Unknown daily activity.');const state=readPerformanceProgress(options);\r\n state.activities??={};if(id!=null){if(typeof id!=='string'||!id||['__proto__','constructor','prototype'].includes(id))throw RangeError('Invalid daily activity ID.');const key=`${kind}:${id}`;if(Object.hasOwn(state.activities,key))return state;state.activities[key]={kind,day};}\r\n dayEntry(state,day)[kind]=true;\r\n // Existing meditation coaches use completed-day milestones, separate from XP.\r\n // Three, six, nine and twelve days cover the four difficulty blocks.\r\n if(kind==='meditation'){const days=Object.values(state.days).filter(d=>d.meditation).length;for(let i=0;i<4;i++)if(days>=CADENCE_MILESTONES.meditationDays[i])for(const coach of matchingCoaches('meditation',['easy','medium','hard','expert'][i]))unique(state.coaches,coach.id);}\r\n return save(recalculate(state),options);}\r\nconst unique=(list,id)=>{if(!list.includes(id))list.push(id);};\r\nexport function recordPerformanceSession(record,options={}){\r\n if(!record||typeof record.id!=='string'||!record.id||['__proto__','constructor','prototype'].includes(record.id))throw RangeError('Saved workout ID is required.');\r\n const state=readPerformanceProgress(options);if(Object.hasOwn(state.sessions,record.id)||record.preparation||record.earned===false)return state;\r\n const exercise=EXERCISES[record.mode],kind=record.kind??(exercise?.kind==='hold'?'hold':'reps'),difficulty=record.difficulty??exerciseDifficulty(record.mode),group=exercise?.group??record.group;\r\n const day=record.day??localDay(record.completedAt??Date.now()),value=Number(record.value??record.activeSeconds??0),continuous=Number(record.maxContinuousSeconds??record.continuousSeconds??0);\r\n if(!Number.isFinite(value)||value<0||!Number.isFinite(continuous)||continuous<0)throw RangeError('Invalid saved performance.');\r\n if(kind==='hold'&&continuous>Number(record.activeSeconds??value))throw RangeError('Continuous time cannot exceed active hold time.');\r\n const holdPerformances=record.perDifficultyContinuous??{[difficulty]:continuous};\r\n if(kind==='hold'&&(!object(holdPerformances)||Object.entries(holdPerformances).some(([level,seconds])=>!DIFFICULTIES.includes(level)||!finite(seconds))||Object.values(holdPerformances).reduce((sum,seconds)=>sum+seconds,0)>Number(record.activeSeconds??value)+1e-7))throw RangeError('Invalid per-difficulty hold performance.');\r\n if(kind==='meditation')return recordDailyActivity('meditation',{day,id:record.id},options);\r\n const earnedCoachCount=record.earnedCoachCount??state.coaches.filter(id=>!STARTER_COACH_IDS.includes(id)).length;\r\n if(!Number.isSafeInteger(earnedCoachCount)||earnedCoachCount<0||earnedCoachCount>COACH_REQUIREMENTS.length)throw RangeError('Invalid saved coach bonus.');\r\n const multiplier=coachXpMultiplier(earnedCoachCount);\r\n let xp=record.xpBase??record.earnedXp;\r\n if(xp===undefined)xp=kind==='hold'?holdXp({difficulty,to:record.activeSeconds??value}):kind==='reps'?repXp({difficulty,to:Math.floor(value)}):0;\r\n if(!Number.isFinite(xp)||xp<0)throw RangeError('Invalid workout XP.');\r\n // Persisted controller totals may include difficulty switches. Bound the raw\r\n // total by the expert session cap without reassigning those completed segments.\r\n if(kind==='reps')xp=Math.min(xp,repXp({difficulty:'expert',to:30}));\r\n if(kind==='hold')xp=Math.min(xp,holdXp({difficulty:'expert',to:1800}));\r\n // Controllers provide base XP before coach/daily multipliers. A credited ID never earns twice.\r\n const entry=dayEntry(state,day);entry.workoutXp+=xp*multiplier;entry.workout=true;\r\n state.sessions[record.id]={mode:record.mode,group,kind,difficulty,value,continuous,day,xp:xp*multiplier,...(kind==='hold'?{perDifficultyContinuous:{...holdPerformances}}:{})};\r\n if(kind==='hold'||kind==='reps'){\r\n  for(const [performedDifficulty,performance] of kind==='hold'?Object.entries(holdPerformances):[[difficulty,value]]){\r\n  const milestones=performanceMilestones(kind,performance),matches=matchingCoaches(group,performedDifficulty);\r\n  if(milestones.coach)for(const coach of matches)unique(state.coaches,coach.id);\r\n  if(milestones.golden){for(const coach of matches)unique(state.goldenCoaches,coach.id);if(record.coachId&&state.coaches.includes(record.coachId))unique(state.goldenCoaches,record.coachId);}\r\n  const key=`${group}/${kind}/${performedDifficulty}`;\r\n  if(milestones.coach)state.completions[key]=(state.completions[key]??0)+1;\r\n  // The first coach clear keeps the two milestone tiers. Each re-clear upgrades\r\n  // once within this difficulty's five-tier block; a ten-minute hold earns its special.\r\n  const tier=milestones.special?performanceWeaponTier(performedDifficulty,5):milestones.coach?performanceWeaponTier(performedDifficulty,state.completions[key]+1):milestones.weapon2?performanceWeaponTier(performedDifficulty,0)+2:milestones.weapon1?performanceWeaponTier(performedDifficulty,0)+1:0;\r\n  for(const weapon of WEAPON_GROUPS[group]??[])if(tier)state.weapons[weapon]=Math.max(state.weapons[weapon]??0,Math.min(20,tier));\r\n  if(milestones.coach&&performedDifficulty==='expert')for(const ship of SHIP_REQUIREMENTS.filter(s=>s.group===group&&s.kind===kind))unique(state.ships,ship.id);\r\n  }\r\n }\r\n if(['sprint','gentle','pace'].includes(kind)){\r\n  const count=kind==='sprint'?Number(record.rounds??value):Number(record.activeSeconds??value),threshold=kind==='sprint'?CADENCE_MILESTONES.sprintRounds:kind==='gentle'?CADENCE_MILESTONES.gentleActiveSeconds:CADENCE_MILESTONES.paceActiveSeconds;\r\n  if(count>=threshold){for(const coach of matchingCoaches(group,difficulty))unique(state.coaches,coach.id);const key=`${group}/${kind}/${difficulty}`;state.completions[key]=(state.completions[key]??0)+1;for(const weapon of WEAPON_GROUPS[group]??[])state.weapons[weapon]=Math.max(state.weapons[weapon]??0,performanceWeaponTier(difficulty,state.completions[key]));}\r\n }\r\n return save(recalculate(state),options);\r\n}\r\n/** One workout (any, incl. Cool Cardio), one meditation and one food log open every coach, path and movement.\r\n * Derived from the stored sessions/days, so it persists and syncs exactly like the rest of progress. */\r\nexport function unlockStatus(state){\r\n const days=Object.values(state?.days??{}),workout=Object.keys(state?.sessions??{}).length>0||days.some(d=>d.workout),meditation=days.some(d=>d.meditation),food=days.some(d=>d.food);\r\n return {workout,meditation,food,done:workout&&meditation&&food};\r\n}\r\nexport const everythingUnlocked=(options={})=>unlockStatus(readPerformanceProgress(options)).done;\r\n/** Owned coaches; the unlock rule opens all of them (XP multipliers still use only earned coaches). */\r\nexport const unlockedCoachIds=(options={})=>{const s=readPerformanceProgress(options);return unlockStatus(s).done?COACHES.map(c=>c.id).filter(id=>!EXCLUDED_COACH_IDS.includes(id)):s.coaches;};\r\nexport const coachAccess=(id,options={})=>unlockedCoachIds(options).includes(id);\r\nexport const goldenCoach=(id,options={})=>readPerformanceProgress(options).goldenCoaches.includes(id);\r\nexport const weaponTierFor=(type,options={})=>readPerformanceProgress(options).weapons[type]??0;\r\nexport const shipAccess=(id,options={})=>readPerformanceProgress(options).ships.includes(id);\r\n/** Call only with the result of the authenticated account reader, never a\r\n * CustomEvent or user-supplied profile. Pending device-only sessions survive. */\r\nexport function mergeVerifiedPerformance(account,{storage=globalThis.localStorage}={}){\r\n const remote=account?.progress?.performance;if(!remote)return readPerformanceProgress({storage,account});\r\n if(!account?.user?.id||!Number.isSafeInteger(account.dataEpoch)||account.dataEpoch<1)throw RangeError('Verified account identity is required.');if(!validState(remote))throw RangeError('Invalid synced performance progress.');\r\n const options={storage,account},local=readPerformanceProgress(options),before=JSON.stringify(local),next=JSON.parse(before),theirs=migratePerformanceAccess(JSON.parse(JSON.stringify(remote)));\r\n next.sessions={...local.sessions,...theirs.sessions};next.days={};\n next.worldBonusXp=Number.isFinite(theirs.worldBonusXp)&&theirs.worldBonusXp>=0?theirs.worldBonusXp:0;\n for(const [day,d] of [...Object.entries(local.days),...Object.entries(remote.days)]){const entry=dayEntry(next,day);entry.food||=d.food;entry.meditation||=d.meditation;}\r\n for(const session of Object.values(next.sessions)){const entry=dayEntry(next,session.day);entry.workout=true;entry.workoutXp+=session.xp;}\r\n // Access is rebuilt from the merged history and paths; only non-introduction coaches carry over.\r\n next.paths=theirs.paths.length?theirs.paths:local.paths;\r\n const introductions=Object.values(PATH_INTRO_COACH_IDS),want=new Set([...local.coaches,...theirs.coaches].filter(id=>!introductions.includes(id)));\r\n for(const id of [...earnedCoaches(next),...pathIntroCoachIds(next.paths)])want.add(id);\r\n next.coaches=[...new Set([...local.coaches,...theirs.coaches,...COACHES.map(c=>c.id)])].filter(id=>want.has(id));\r\n next.goldenCoaches=[...new Set([...local.goldenCoaches,...theirs.goldenCoaches])].filter(id=>next.coaches.includes(id));next.ships=[...new Set([...local.ships,...remote.ships])];\r\n for(const [key,value] of Object.entries(remote.weapons))next.weapons[key]=Math.max(next.weapons[key]??0,value);\r\n for(const [key,value] of Object.entries(remote.completions))next.completions[key]=Math.max(next.completions[key]??0,value);\r\n next.activities={...(local.activities??{}),...(remote.activities??{})};migratePerformanceAccess(next);recalculate(next);\r\n return JSON.stringify(next)===before?local:!storage?next:save(next,options);\r\n}\r\nfunction priorDay(day,offset){const d=new Date(`${day}T12:00:00`);d.setDate(d.getDate()-offset);return localDay(d.getTime());}\r\nexport function workoutEligibility(mode,{day=localDay(),kind,...options}={}){const group=EXERCISES[mode]?.group;if(!group)return {allowed:true,reason:null,group:null};const sessions=Object.values(readPerformanceProgress(options).sessions),trained=d=>sessions.some(s=>s.day===d&&s.group===group);if(trained(priorDay(day,1))&&trained(priorDay(day,2)))return {allowed:false,reason:'Your boss is recovering. Take today off this muscle group.',group};if((kind??EXERCISES[mode].kind)==='reps'&&sessions.some(s=>s.day===day&&s.group===group&&s.kind==='reps'))return {allowed:false,reason:'Working set complete for this muscle group today.',group};return {allowed:true,reason:null,group};}\r\n","performance-reconcile.mjs":"import {XP_SCALE} from './progression-rules.mjs';\r\nimport {localDay,recordPerformanceSession,readPerformanceProgress} from './performance-progress.mjs';\r\n\r\n/** Only replay durable new-format completions for the requested progression owner.\r\n * The repository guest owner and account progression owner are separate: the\r\n * completion's captured performanceOwner is required and is never inferred. */\r\nexport function savedPerformanceRecords(rows,{owner}={}){\r\n if(typeof owner!=='string'||!owner)throw RangeError('A captured progression owner is required.');\r\n const seen=new Set(),records=[];\r\n for(const row of [...(rows??[])].sort((a,b)=>(a?.completedAt??0)-(b?.completedAt??0)||String(a?.id).localeCompare(String(b?.id)))){\r\n  const p=row?.progress?.performance;\r\n  if(row?.status!=='completed'||!Number.isSafeInteger(row.completedAt)||row.completedAt<0||typeof row.id!=='string'||!row.id||seen.has(row.id)||!p||typeof p!=='object'||Array.isArray(p))continue;\r\n  if(p.performanceOwner!==owner||row.progress.performanceOwner!=null&&row.progress.performanceOwner!==owner||p.id!=null&&p.id!==row.id||p.mode!==row.mode||p.preparation||p.earned===false||row.completion?.earned===false)continue;\r\n  if(!['hold','reps','sprint','gentle','pace'].includes(p.kind)||!Number.isFinite(p.xpBase)||p.xpBase<0)continue;\r\n  seen.add(row.id);records.push({...p,xpBase:p.xpScale===XP_SCALE?p.xpBase:p.xpBase*XP_SCALE,xpScale:XP_SCALE,id:row.id,completedAt:row.completedAt,day:p.day??localDay(row.completedAt)});\r\n }\r\n return records;\r\n}\r\n\r\n/** Retry-safe local repair after IndexedDB committed but the reward cache failed.\r\n * Call again on startup/history refresh. Failed writes remain retryable because\r\n * the durable completion is retained and only the reward ledger stores credit. */\r\nexport function reconcilePerformanceWorkouts(rows,options={}){\r\n const records=savedPerformanceRecords(rows,options),failed=[];let replayed=0,progress=readPerformanceProgress(options);\r\n for(const record of records){\r\n  if(Object.hasOwn(progress.sessions,record.id))continue;\r\n  try{progress=recordPerformanceSession(record,options);if(Object.hasOwn(progress.sessions,record.id))replayed++;}\r\n  catch(error){failed.push({id:record.id,error:error instanceof Error?error.message:String(error)});}\r\n }\r\n return {progress,replayed,failed};\r\n}\r\n","personal-tracker.css":".mom-tracker{margin:18px 0 10px;border:2px solid #a18796;border-radius:10px;padding:16px;background:linear-gradient(135deg,#534053,#302437);color:#f8ebd7;box-shadow:inset 0 1px #d7b9c6,0 5px 0 #191320;font:16px/1.4 Arial,sans-serif;overflow:hidden}\r\n.mom-tracker .tracker-brand{display:flex;align-items:center;gap:12px;margin:-16px -16px 18px;padding:12px 16px;background:#ead6ac;color:#362b3c;border-bottom:3px solid #9b815f}\r\n.tracker-brand img{width:48px;height:48px;object-fit:contain;flex:none}.tracker-brand>div{flex:1;min-width:0}.tracker-brand>div>span{font:700 17px/1.2 Arial,sans-serif;letter-spacing:3px}\r\n.mom-tracker h2{margin:3px 0 0;color:#574359;font:14px/1.3 Arial,sans-serif}.tracker-unit{font:700 12px/1.4 monospace;letter-spacing:1px;border:1px solid #897153;padding:5px}\r\n.tracker-identity{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:16px}.mom-tracker .tracker-label{display:block;font:700 12px/1.4 Arial,sans-serif;letter-spacing:1.4px;text-transform:uppercase;color:#d0b7c7}\r\n.tracker-member p{margin:4px 0;color:#fff3d5;font:700 clamp(24px,6vw,36px)/1.15 Arial,sans-serif;overflow-wrap:anywhere}\r\n.tracker-day{display:flex;align-items:center;gap:10px;padding:10px 14px;border:2px solid #b19465;border-radius:5px;background:#211c29;box-shadow:inset 0 2px 6px #0007}.tracker-day span{text-transform:uppercase;font-size:12px;letter-spacing:1px}.tracker-day strong{color:#ffe2a0;font:700 40px/1 monospace;font-variant-numeric:tabular-nums}\r\n.tracker-record{margin:16px 0;padding:12px 14px;border-left:4px solid #a7ccad;background:#211b2a}.tracker-record p{margin:2px 0;color:#edf6e7}.tracker-record strong{font-size:25px;font-variant-numeric:tabular-nums}\r\n.mom-tracker .tracker-target-title{font:700 12px/1.4 Arial,sans-serif;letter-spacing:1px;text-transform:uppercase;color:#eed8ba;margin:20px 0 9px}.tracker-targets{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;margin:0}.tracker-targets>div{border:1px solid #8d7588;border-radius:4px;padding:12px;background:#3a2e41}.tracker-targets [hidden]{display:none}.tracker-targets dt{font-size:13px;color:#dfc9d7}.tracker-targets dd{margin:3px 0 0;display:flex;gap:7px;align-items:baseline;flex-wrap:wrap;color:#efdcb7}.tracker-targets strong{font:700 27px/1.2 monospace;font-variant-numeric:tabular-nums}.tracker-targets dd span{font-size:12px}\r\n.tracker-focus{padding:16px 0}.tracker-focus p{margin:4px 0 0;font-size:15px;color:#f4e6d1}.tracker-footer{display:flex;gap:8px;align-items:center;justify-content:space-between;flex-wrap:wrap;border-top:1px solid #8b6f84;padding-top:8px}.tracker-footer>span{font:12px/1.5 monospace;letter-spacing:1px;color:#d3bfcf}.tracker-footer a{display:inline-flex;min-height:44px;align-items:center;color:#ffe2a0;font-size:14px;font-weight:700}.tracker-footer a:focus-visible{outline:3px solid #ffe2a0;outline-offset:4px}\r\n@media(max-width:360px){.tracker-brand img{width:38px;height:38px}.tracker-unit{display:none}.tracker-day{padding:8px;gap:6px}.tracker-day strong{font-size:32px}}\r\n.mom-tracker{padding:0}\r\n.mom-tracker .tracker-brand{margin:0;border-bottom:0;min-height:72px;cursor:pointer;list-style:none;gap:10px}\r\n.tracker-brand::-webkit-details-marker{display:none}\r\n.tracker-brand:focus-visible{outline:3px solid #ffe2a0;outline-offset:-4px}\r\n.tracker-brand img{width:38px;height:38px}\r\n.tracker-summary-day{white-space:nowrap;font:14px/1.3 Arial,sans-serif}\r\n.tracker-summary-day strong{font-variant-numeric:tabular-nums}\r\n.tracker-chevron{font-size:24px;transition:transform .2s}\r\n.tracker-collapse[open] .tracker-chevron{transform:rotate(180deg)}\r\n.tracker-collapse[open] .tracker-brand{border-bottom:3px solid #9b815f}\r\n.tracker-content{padding:16px}\r\n","personal-tracker.mjs":"export function renderPersonalTracker(plate,profile,targets,exerciseNames,progress){\r\n if(!plate.dataset.mounted){\r\n  plate.className='mom-tracker';plate.setAttribute('aria-labelledby','personalTrackerTitle');\r\n  plate.innerHTML=`<details class=\"tracker-collapse\"><summary class=\"tracker-brand\"><img src=\"/pod/mom-inc-mark.png\" alt=\"\"><div><span>MOM INC.</span><h2 id=\"personalTrackerTitle\">Personal tracker</h2></div><span class=\"tracker-summary-day\">Day <strong data-tracker=\"day\"></strong></span><span class=\"tracker-chevron\" aria-hidden=\"true\">⌄</span></summary>\r\n   <div class=\"tracker-content\"><div class=\"tracker-identity\"><div class=\"tracker-member\"><p data-tracker=\"name\"></p></div></div>\r\n   <div class=\"tracker-record\"><p><strong id=\"trackerCompletedSets\">0</strong> sets logged</p></div>\r\n   <h3 class=\"tracker-target-title\">Today’s targets</h3><dl class=\"tracker-targets\">\r\n    <div><dt>Reps / set</dt><dd><strong data-tracker=\"reps\"></strong><span>reps</span></dd></div>\r\n    <div><dt>Hold / set</dt><dd><strong data-tracker=\"hold\"></strong><span>sec</span></dd></div>\r\n    <div data-nutrition-target><dt>Protein</dt><dd><strong data-tracker=\"protein\"></strong><span>g / day</span></dd></div>\r\n    <div data-nutrition-target><dt>Water</dt><dd><strong data-tracker=\"water\"></strong><span>oz / day</span></dd></div>\r\n   </dl><div class=\"tracker-focus\"><span class=\"tracker-label\">Your program</span><p data-tracker=\"exercises\"></p></div>\r\n   <footer class=\"tracker-footer\"><a href=\"/onboarding.html?edit=1\">Settings ↗</a></footer></div></details>`;\r\n  plate.dataset.mounted='true';\r\n }\r\n const values={name:profile.name,day:String(targets.day).padStart(2,'0'),reps:targets.reps,hold:targets.holdSeconds,protein:targets.proteinGrams,water:targets.waterOz,exercises:profile.exercises.map(k=>exerciseNames[k]||k).join(' · ')};\r\n for(const [key,value]of Object.entries(values))plate.querySelector(`[data-tracker=\"${key}\"]`).textContent=value??'—';\r\n for(const tile of plate.querySelectorAll('[data-nutrition-target]'))tile.hidden=!targets.proteinGrams;\r\n updateTrackerProgress(progress);\r\n}\r\nexport function updateTrackerProgress(progress){const count=document.getElementById('trackerCompletedSets');if(count&&Number.isFinite(progress?.completedSets))count.textContent=String(progress.completedSets);}\r\n","pet-choice.mjs":"// The cage's device-local preference. A pet must also be a currently granted\r\n// battle-pass reward; this module never grants one or changes a coach recipe.\r\nimport {BOSSES,bossRewards} from './battle-pass-rewards.mjs';\r\nimport * as unlockLedger from './unlock-ledger.mjs';\r\n\r\nexport const PET_CHOICE_KEY='myr5-cage-selection-v1';\r\nexport const PET_CHOICE_SCOPE_LABEL='Selected on this device';\r\n\r\nconst canonicalPets=Object.freeze([...new Map(BOSSES.flatMap(boss=>bossRewards(boss.id).flat()).filter(item=>item.kind==='pet').map(item=>[item.id,Object.freeze({id:item.id,name:item.name})])).values()]);\r\nconst canonicalIds=new Set(canonicalPets.map(pet=>pet.id));\r\nconst empty=()=>({version:1,petId:null});\r\nconst storageFor=options=>{try{return options.storage??globalThis.localStorage;}catch{return null;}};\r\nconst ledgerFor=options=>options.ledger??unlockLedger;\r\nconst granted=(id,options)=>{try{return canonicalIds.has(id)&&ledgerFor(options).isGranted('pet',id)===true;}catch{return false;}};\r\nconst write=(selection,options)=>{try{const storage=storageFor(options);if(!storage)return false;storage.setItem(PET_CHOICE_KEY,JSON.stringify(selection));return true;}catch{return false;}};\r\n\r\n/** Includes None and only canonical battle-pass pets currently granted. */\r\nexport function availablePetChoices(options={}){\r\n return [{id:null,name:'None'},...canonicalPets.filter(pet=>granted(pet.id,options))];\r\n}\r\n\r\n/** Revalidates a saved preference against current grants on every read. */\r\nexport function selectedPetChoice(options={}){\r\n let saved;\r\n try{saved=storageFor(options)?.getItem(PET_CHOICE_KEY);if(saved===null||saved===undefined)return empty();saved=JSON.parse(saved);}catch{return empty();}\r\n if(saved?.version===1&&(saved.petId===null||typeof saved.petId==='string'&&granted(saved.petId,options)))return {version:1,petId:saved.petId};\r\n const selection=empty();write(selection,options);return selection;\r\n}\r\n\r\n/** Returns true only when the allowed choice was saved on this device. */\r\nexport function selectPetChoice(petId,options={}){\r\n if(petId!==null&&!(typeof petId==='string'&&granted(petId,options)))return false;\r\n return write({version:1,petId},options);\r\n}\r\n","player-level.mjs":"import {COSMETIC_LEVEL_XP,COSMETIC_XP_TARGET,cosmeticLevel,BENCHMARK} from './progression-rules.mjs';\r\nimport {readPerformanceProgress} from './performance-progress.mjs';\r\nexport const XP_KNOBS=Object.freeze({levels:250,maxXp:COSMETIC_XP_TARGET,...BENCHMARK});\r\nexport const LEVEL_XP=COSMETIC_LEVEL_XP;\r\nexport const levelFor=cosmeticLevel;\r\n// Aggregate set counts cannot reconstruct performance XP. Use the saved ledger.\r\nexport const xpFromHistory=({totalXp=0}={})=>Math.max(0,Number(totalXp)||0);\r\nexport const BASELINE_KEY='myr5.xpBaseline.v1';\r\nexport function playerLevel(progress,storage=globalThis.localStorage){return cosmeticLevel(progress?.performanceVersion===2?xpFromHistory(progress):readPerformanceProgress({storage}).totalXp);}\r\n","pocket-hardware.css":"/* The viewport is the face of a pocket field unit. The rim never catches taps. */\r\nhtml{background:radial-gradient(ellipse at top,#433a42,#15131a 70%);scroll-padding-block:36px}\r\nbody{width:calc(100% - 20px);max-width:760px;margin:12px auto;min-height:calc(100dvh - 24px);padding:20px 9px max(24px,env(safe-area-inset-bottom));border-radius:36px;background:repeating-linear-gradient(0deg,#dec5d604 0 1px,transparent 1px 4px),linear-gradient(115deg,#645361,#382f3c 35%,#332b39 72%,#705b6b);box-shadow:inset 0 0 0 2px #c1acb0,inset 0 0 0 7px #211b27,0 10px 0 #131017,0 18px 35px #000b}\r\n.device-bezel{position:fixed;z-index:25;top:10px;bottom:10px;left:50%;transform:translateX(-50%);width:calc(100% - 16px);max-width:764px;pointer-events:none;border:10px solid #766774;border-top-color:#c4b6b6;border-left-color:#a497a2;border-right-color:#4b3e50;border-bottom-color:#3e3347;border-radius:38px;box-shadow:inset 0 0 0 2px #e4d6d255,inset 0 0 0 5px #1b1720,inset 5px 0 12px #08060caa,0 0 0 2px #15131b,1px 4px 0 3px #08060b,7px 9px 24px #0008}\r\n.device-bezel:before{content:'';position:absolute;inset:6px;border:1px solid #ab8e9c55;border-radius:22px;box-shadow:inset 1px 2px 3px #0008}\r\n.device-bezel:after{content:'';position:absolute;top:31%;bottom:31%;left:-10px;right:-10px;border-left:4px solid #342d39;border-right:4px solid #261f2d;border-radius:5px;box-shadow:inset 1px 0 #d3bfca55}\r\n.case-screw{position:absolute;width:10px;height:10px;border:1px solid #302633;border-radius:50%;background:linear-gradient(135deg,#e0d7c8,#8d8d86 45%,#545563);box-shadow:inset 0 1px #ffffde,1px 2px 3px #000b}.case-screw:after{content:'';position:absolute;height:2px;background:#3b3441;top:3px;left:1px;right:1px;transform:rotate(-35deg);box-shadow:0 1px #ded6be88}.case-tl{top:1px;left:7px}.case-tr{top:1px;right:7px}.case-bl{bottom:1px;left:7px}.case-br{bottom:1px;right:7px}\r\n.ship-header{margin:0 6px;border:2px solid #251e2d;border-top-color:#a38a9c;border-radius:20px 20px 7px 7px;height:auto;min-height:72px;padding:14px 12px;box-shadow:inset 0 2px #d4bac444,0 3px 5px #120d19aa}\r\n.pod-page{padding:0 14px 12px}.deck-strip{padding:0 4px}.containment-bay{border-radius:18px;margin-top:5px;box-shadow:inset 0 3px 8px #0a0611aa,0 1px #a2899d77}.workout-console{border-radius:13px;border:2px solid #1c1722;border-top-color:#b39aa8;box-shadow:inset 0 2px #c4adbe44,inset -2px -3px 7px #1b102955,0 5px 0 #211926,0 8px 12px #0e0a15aa}.coach-line{border:1px solid #201928;border-bottom-color:#9e839877;border-radius:8px;background:#221c2a;box-shadow:inset 1px 3px 6px #0008;padding:10px 12px}.crew-footer{margin-top:18px}.sync-badge{padding:12px 8px;font-size:11px}\r\n#coachDock.coach-dock{border-top:2px solid #bca4b4;box-shadow:inset 0 2px #ecdae344,0 -5px 12px #0e0a15aa;backdrop-filter:none}\r\n.launch-panel{max-height:calc(100dvh - 68px);border-width:6px;border-radius:24px;padding:24px 20px;box-shadow:inset 0 0 0 2px #251c30,inset 0 3px #f8e6d944,0 7px 0 #1e1725,5px 16px 40px #000b}.launch-panel::backdrop{background:#110d17d9}.launch-panel header{position:relative}.launch-panel:not(.accomplishments-panel) header:before{content:'';position:absolute;left:0;right:0;bottom:-5px;height:3px;background:repeating-linear-gradient(90deg,#16121d 0 5px,transparent 5px 10px);opacity:.7}.launch-panel .fields>label{min-width:0}.launch-panel input,.launch-panel select{min-width:0}.launch-panel .entry-copy{overflow-wrap:anywhere}\r\n.meal-scan-stage{position:relative;margin:18px 0;border:5px solid #252832;border-top-color:#7e8c8d;border-bottom-color:#13121c;border-radius:15px;overflow:hidden;isolation:isolate;background:#08171a;box-shadow:inset 0 0 14px #000,0 2px #acc5b866}\r\n.launch-panel .meal-scan-stage .meal-preview{height:300px;max-height:48dvh;min-height:230px;margin:0;border-radius:0;object-fit:contain;background:#0a1419}\r\n.meal-scan-overlay{position:absolute;inset:0;pointer-events:none;color:#c3ffec;font:12px/1.5 var(--pixel-font);text-shadow:0 1px 3px #000;background:linear-gradient(#00191dd9,transparent 25%,transparent 64%,#001519f2);box-shadow:inset 0 0 35px #47e6d31c}\r\n.scan-heading{position:absolute;top:12px;left:12px;right:12px;display:flex;justify-content:space-between;gap:8px;letter-spacing:1px}.scan-heading time{font-variant-numeric:tabular-nums;color:#e2ffb6;flex-shrink:0}.scan-readout{position:absolute;bottom:12px;left:12px;right:12px;background:#001b21d9;border-left:2px solid #9dffe1;padding:8px 10px}.scan-readout>span{display:block}.launch-panel .scan-readout progress{height:7px;margin-top:7px;accent-color:#a8ffc9}.scan-grid{position:absolute;inset:0;background:linear-gradient(90deg,#78fbe410 1px,transparent 1px),linear-gradient(#78fbe410 1px,transparent 1px);background-size:32px 32px;opacity:.45}.scan-reticle{position:absolute;inset:24% 20% 29%;border:1px solid #bbffe940;border-radius:16px;box-shadow:0 0 0 10px #60ecc709}.scan-reticle:before,.scan-reticle:after{content:'';position:absolute;width:23px;height:23px;border:3px solid #a3ffdf}.scan-reticle:before{left:-2px;top:-2px;border-right:0;border-bottom:0}.scan-reticle:after{right:-2px;bottom:-2px;border-left:0;border-top:0}.scan-beam{display:none;position:absolute;left:0;right:0;top:20%;height:2px;background:#b0ffe0;box-shadow:0 0 20px 7px #56ffd955}\r\n.meal-scan-overlay:is([data-state=preparing],[data-state=loading],[data-state=analyzing]) .scan-beam{display:block;animation:food-sweep 3.8s ease-in-out infinite}.meal-scan-overlay[data-state=result] .scan-reticle{border-color:#c5ffc777}.meal-scan-overlay[data-state=error]{color:#ffe4bf}.scan-actions{margin:16px 0}.scan-note{font-size:12px!important}.launch-panel #foodSuggestions button{text-transform:capitalize}\r\n@keyframes food-sweep{0%,100%{top:22%;opacity:.4}50%{top:73%;opacity:.8}}\r\n.reminder-tuning{padding:20px 16px 16px;border:3px solid #26202d;border-top-color:#b399a8;border-radius:13px;background:repeating-linear-gradient(0deg,#ecd5e306 0 1px,transparent 1px 3px),linear-gradient(130deg,#735d70,#3c3246);box-shadow:inset 0 2px #dbc6d944,0 4px #211929;margin:10px 0;display:grid;gap:24px}.reminder-tuning label{font:700 12px var(--pixel-font);letter-spacing:1px}.tone-control{text-align:center}.tone-control>output{display:block;font:750 24px var(--pixel-font);margin-top:16px}.tone-dial-row{display:flex;align-items:center;justify-content:center;gap:20px;margin-top:20px}.tone-dial-row>button{width:44px;min-width:44px;padding:0;font-size:22px}.tone-dial{position:relative;width:110px;height:110px;flex-shrink:0;border:3px solid #2b2330;border-radius:50%;background:repeating-conic-gradient(#b6a4ac 0deg 4deg,#68566a 4deg 8deg);box-shadow:0 0 0 5px #201926,0 0 0 7px #ae91a166,0 9px 9px #0009;touch-action:none;cursor:grab}.tone-dial:before{content:'';position:absolute;inset:8px;border:2px solid #c2afbc;border-radius:50%;background:radial-gradient(circle at 32% 22%,#b1a0ad,#79667f 55%,#4c3b59);box-shadow:inset 0 3px #e0cdd355,inset 0 -4px #21172f66}.tone-dial i{position:absolute;inset:12px;transform:rotate(var(--turn,0deg));transition:transform .15s}.tone-dial i:after{content:'';position:absolute;width:5px;height:21px;top:0;left:calc(50% - 2.5px);background:#ffdb95;border:1px solid #fce8be;border-radius:2px;box-shadow:0 1px 3px #000b}.tone-dial:focus-visible{outline:3px solid #ffe0a5;outline-offset:10px}.tone-dial:active{cursor:grabbing}.tone-scale{font:10px var(--pixel-font);color:#d3bacb;letter-spacing:.6px;margin-top:9px}.consistency-control output{display:block;font:600 16px/1.5 var(--pixel-font);margin-top:10px;min-height:24px}.launch-panel #consistencySlider{appearance:none;width:100%;height:46px;border:0;padding:0;margin:8px 0 0;background:none;box-shadow:none;cursor:pointer;touch-action:pan-y}.launch-panel #consistencySlider::-webkit-slider-runnable-track{height:10px;border:2px solid #1c1721;border-bottom-color:#b899ac;background:linear-gradient(90deg,#d4ad70 var(--fill),#1c1822 var(--fill));border-radius:4px;box-shadow:inset 1px 2px 4px #0009}.launch-panel #consistencySlider::-webkit-slider-thumb{appearance:none;width:30px;height:36px;margin-top:-15px;border:2px solid #dbbeb9;border-radius:5px;background:repeating-linear-gradient(90deg,#967c90 0 5px,#4b3e55 5px 6px);box-shadow:inset 0 2px #eddccf,2px 5px 5px #0008}.launch-panel #consistencySlider::-moz-range-track{height:8px;background:#211829;border:2px solid #b899ac;border-radius:4px}.launch-panel #consistencySlider::-moz-range-thumb{width:28px;height:34px;border:2px solid #dbbeb9;border-radius:5px;background:repeating-linear-gradient(90deg,#967c90 0 5px,#4b3e55 5px 6px);box-shadow:2px 4px 4px #0008}.cadence-scale{display:flex;justify-content:space-between;font:10px var(--pixel-font);color:#cdb5c8}.message-preview{padding:14px;border:2px solid #201827;border-bottom-color:#b28a9a;border-radius:7px;background:#24212b;box-shadow:inset 1px 3px 6px #0009}.message-preview small{font:10px var(--pixel-font);letter-spacing:1px;color:#b7d0bd}.launch-panel .message-preview p{font:15px/1.6 var(--pixel-font);color:#e7edc9;margin:7px 0 0}.reminder-controls{flex-wrap:wrap}\r\n.install-transfer{border-block:2px solid #241b2d;margin-top:22px;padding:0 0 24px;box-shadow:0 1px #b998a355}.install-qr{display:block;width:min(100%,294px);margin:18px auto;padding:0;background:#fff;border:7px solid #dfd8c8;border-radius:12px;box-shadow:0 4px 0 #756e78,0 8px 12px #0008;overflow:hidden}.install-qr img{display:block;width:100%;height:auto}.install-transfer .actions{margin-top:14px}.install-transfer #installLink{font:12px/1.5 var(--pixel-font)}\r\n@media(min-width:800px){body{margin-block:24px;padding:22px 14px 30px}.device-bezel{top:22px;bottom:22px}.ship-header{padding-inline:22px}.pod-page{padding-inline:24px}.reminder-tuning{grid-template-columns:1fr 1fr;align-items:center;gap:24px 22px}.message-preview{grid-column:1/-1}}\r\n@media(max-width:430px){body{width:calc(100% - 12px);padding:20px 7px max(22px,env(safe-area-inset-bottom));margin-block:8px}.device-bezel{width:calc(100% - 8px);top:6px;bottom:6px;border-width:7px;border-radius:29px}.device-bezel:before{inset:4px;border-radius:20px}.device-bezel:after{left:-7px;right:-7px;border-width:3px}.ship-header{margin-inline:3px;padding-inline:10px;gap:8px}.ship-location{font-size:8px;letter-spacing:.2px}.ship-location small{font-size:7px;letter-spacing:.4px}.mom-brand{gap:4px}.mom-brand img{width:28px}.pod-page{padding-inline:10px}.workout-console{padding:15px 10px}.calibration-grid{grid-template-columns:minmax(0,1fr) 78px;padding:15px 0;gap:8px}.exercise-control{padding-right:0}.dial-controls{gap:4px}.dial-controls button{width:28px;min-width:28px;padding:0}.exercise-dial{width:64px;height:64px;flex-shrink:0}.signal-control .rocker-switch{min-width:54px;width:54px}.signal-control>small{font-size:10px}.calibration-grid label{font-size:9px}.exercise-control>strong{font-size:15px}.launch-panel{width:calc(100% - 26px);padding:20px 12px;border-width:5px;border-radius:20px}.launch-panel h2{font-size:21px}.reminder-tuning{padding-inline:12px}.tone-dial-row{gap:18px}.scan-heading{font-size:10px}.launch-panel .meal-scan-stage .meal-preview{height:270px}.launch-panel .reminder-controls{gap:8px}}\r\n@media(prefers-reduced-motion:reduce){.scan-beam{animation:none!important;top:45%!important;opacity:.4}.tone-dial i{transition:none}}\r\n\n/* Keep the coach, camera and live count in one visible area. */\n.training-view{position:relative;border-radius:16px;background:#241b2d;padding-bottom:2px}.training-view #hud{display:flex;justify-content:center;align-items:center;margin:12px 4px 0;padding:10px 14px;border:2px solid #977b98;border-radius:12px;background:linear-gradient(#201525,#36263e);box-shadow:inset 0 2px 8px #0009,0 3px #140d1b;text-align:center}.training-view .counter-readout{width:100%;display:flex;flex-direction:column;align-items:center}.training-view #setNumber{display:block;margin:0 0 5px;font-size:14px;letter-spacing:1px}.training-view #primary{--tile-width:40px;--tile-height:54px;--digit-size:41px}.training-view .counter-target{margin-top:7px;justify-content:center}.training-view #primaryLabel,.training-view #goalValue{font-size:16px}.training-view .counter-target{font-size:16px}body[data-tracking=true] .training-view{position:sticky;top:4px;z-index:20;box-shadow:0 6px 18px #0c071dcc}body[data-tracking=true] .training-view .containment-pod{height:clamp(190px,32dvh,310px)}\n@media(max-height:580px){body[data-tracking=true] .training-view .containment-pod{height:clamp(110px,27dvh,180px)}.training-view #primary{--tile-height:44px;--tile-width:33px;--digit-size:33px}.training-view #hud{padding:6px;margin-top:8px}.training-view #setNumber{margin-bottom:3px}.training-view .counter-target{margin-top:4px}}\n","pod/continue-workout.mjs":"// #19 (revised): today's newest paused/interrupted workout is offered as a Continue popup on the pod page\r\n// itself, never on the portal quilt. The popup lives inside #homeScreen, so it travels with the pod when the\r\n// portal hosts it in its full-screen workout dialog and is never left outside a modal (inert).\r\nexport function podShown(doc=document){\r\n const home=doc.getElementById('homeScreen');if(!home||home.hidden||doc.hidden||doc.body.dataset.screen==='rest')return false;\r\n const host=home.closest('dialog');if(host)return host.open;\r\n return doc.getElementById('portalHome')?.hidden!==false;\r\n}\r\nexport const continueVisible=({shown,idle,row,dismissed})=>!!row&&shown&&idle&&dismissed!==row.id;\r\nexport function continuePrompt(row,label,access){\r\n const legacyManual=row.metadata?.control==='manual';\r\n return {allowed:access.allowed,text:access.allowed?(legacyManual?'Saved manual set · Start with camera · ':'Continue · ')+label:`Saved ${label}. ${access.reason||'This workout path is locked.'} Your set remains in history.`,action:legacyManual?'Start with camera':'Continue'};\r\n}\r\nexport function mountContinueWorkout({doc=document,unfinished,idle,label,onContinue,canContinue=()=>({allowed:true})}){\r\n const home=doc.getElementById('homeScreen');\r\n const card=doc.createElement('section');card.className='continue-workout';card.hidden=true;card.setAttribute('role','dialog');card.setAttribute('aria-labelledby','continueWorkoutTitle');\r\n card.innerHTML='<p class=\"continue-eyebrow\">UNFINISHED SET</p><h2 id=\"continueWorkoutTitle\"></h2><div class=\"continue-actions\"><button type=\"button\" class=\"primary-action\" data-continue>Continue</button><button type=\"button\" data-dismiss>Not now</button></div>';\r\n home.append(card);\r\n let row=null,dismissed=null,queued=0,run=0;\r\n const hide=()=>{if(!card.hidden)card.hidden=true;};\r\n async function refresh(){\r\n  const ticket=++run;\r\n  if(!podShown(doc)||!idle()){hide();return;}\r\n  let next=null;try{next=await unfinished();}catch{}\r\n  if(ticket!==run)return;\r\n  row=next;\r\n  if(!continueVisible({shown:podShown(doc),idle:idle(),row,dismissed})){hide();return;}\r\n  const prompt=continuePrompt(row,label(row),canContinue(row));if(card.querySelector('h2').textContent!==prompt.text)card.querySelector('h2').textContent=prompt.text;\r\n  card.querySelector('[data-continue]').hidden=!prompt.allowed;\r\n  card.querySelector('[data-continue]').textContent=prompt.action;\r\n  // Sit just above the bottom bar, whatever height it has on this phone.\r\n  const bar=doc.getElementById('coachDock')?.getBoundingClientRect(),bottom=bar?.height?Math.max(16,innerHeight-bar.top+12)+'px':'';\r\n  if(card.style.bottom!==bottom)card.style.bottom=bottom;\r\n  if(card.hidden)card.hidden=false;\r\n }\r\n const queue=()=>{queued||=setTimeout(()=>{queued=0;void refresh();});};\r\n const observer=new MutationObserver(queue);\r\n const onVisibility=()=>{if(doc.hidden){run++;hide();}else queue();};\r\n doc.addEventListener('visibilitychange',onVisibility);\r\n observer.observe(doc.body,{subtree:true,attributes:true,attributeFilter:['hidden','open','aria-current','data-screen','data-tracking']});\r\n card.querySelector('[data-dismiss]').onclick=()=>{dismissed=row?.id??null;hide();};\r\n card.querySelector('[data-continue]').onclick=()=>{const chosen=row;hide();if(!chosen||!idle()||doc.hidden)return;if(!canContinue(chosen).allowed){dismissed=chosen.id;return;}onContinue(chosen);};\r\n queue();\r\n return {refresh,dispose(){observer.disconnect();doc.removeEventListener('visibilitychange',onVisibility);clearTimeout(queued);card.remove();}};\r\n}\r\n","pod/control-board.css":"/* #106 workout selector: one compact control board (readout, focus dial, level knob, lever, sound switch).\r\n   CSS only, no images. Self-contained under .control-board so it can move to the oval route (#60) as one block. */\r\n.control-board{--cb-ink:#f1dcb4;--cb-dim:#b9a1b0;--cb-gold:#ffd36e;--cb-mono:ui-monospace,'Cascadia Mono',Consolas,Menlo,monospace;\r\n --screw:#cbbab0 0 1.4px,#57474f 1.9px 3px,#0000 3.5px;\r\n position:relative;margin:0 0 10px;padding:10px 12px 2px;border:1px solid #0e0a12;border-radius:12px;\r\n background:radial-gradient(circle at 7px 7px,var(--screw)),radial-gradient(circle at calc(100% - 7px) 7px,var(--screw)),radial-gradient(circle at 7px calc(100% - 7px),var(--screw)),radial-gradient(circle at calc(100% - 7px) calc(100% - 7px),var(--screw)),\r\n  repeating-linear-gradient(90deg,#0000 0 3px,#ffffff05 3px 4px),linear-gradient(165deg,#5d4a5b,#3c3043 50%,#2e2436);\r\n box-shadow:inset 0 1px #dcc6d066,inset 0 -2px #0007,0 0 0 1px #8c768966,0 4px 0 #140f19,0 7px 12px #0006;\r\n font:700 8px/1 var(--cb-mono);letter-spacing:.14em;color:var(--cb-ink);-webkit-user-select:none;user-select:none}\r\n.control-board button{font:inherit;letter-spacing:inherit}\r\n\r\n/* Readout window + MOVEMENTS key */\r\n.control-board .cb-top{display:flex;gap:8px;align-items:stretch}\r\n.control-board .cb-readout{position:relative;flex:1;min-width:0;padding:7px 9px 5px;border:1px solid #09070b;border-radius:6px;background:repeating-linear-gradient(0deg,#ffd36e07 0 1px,#0000 1px 3px),radial-gradient(ellipse at 30% 0,#3a2a1a55,#0000 70%),#150f19;box-shadow:inset 0 2px 6px #000d,0 1px #cbb3bf44}\r\n.control-board .cb-line{display:flex;justify-content:space-between;gap:8px;color:#d2ae62}\r\n.control-board #exerciseName,.control-board #difficultySetting{font:inherit;color:inherit;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-transform:uppercase}\r\n.control-board #difficultySetting{flex:none}\r\n.control-board #variationName{position:static;display:block;width:100%;min-height:0;margin:4px 0 0;padding:0;border:0;border-radius:0;background:none;box-shadow:none;color:var(--cb-gold);font:700 15px/1.25 system-ui,-apple-system,'Segoe UI',sans-serif;letter-spacing:0;text-align:left;text-decoration:underline dotted #ffd36e66;text-underline-offset:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-shadow:0 0 8px #ffd36e40;cursor:pointer}\r\n.control-board #variationName:after{content:'';position:absolute;inset:0;border-radius:6px}\r\n.control-board #variationName:focus-visible{outline:0}.control-board #variationName:focus-visible:after{outline:3px solid var(--cb-gold);outline-offset:2px}\r\n.control-board .cb-key{flex:none;width:66px;min-height:44px;padding:4px 3px;border:1px solid #120d16;border-radius:6px;background:linear-gradient(#716070,#4a3b4b);box-shadow:inset 0 1px #dcc4cf99,inset 0 -2px #291f2d,0 3px 0 #140f19;color:var(--cb-ink);line-height:1.4;white-space:normal;transition:transform .07s,box-shadow .07s}\r\n.control-board .cb-key:active:not(:disabled){transform:translateY(2px);border-color:#120d16;box-shadow:inset 0 1px #dcc4cf55,0 1px 0 #140f19}\r\n\r\n/* The deck: stencilled plates over each part, a panel seam above */\r\n.control-board .cb-deck{display:flex;justify-content:space-between;align-items:flex-end;gap:4px;margin-top:8px;padding-top:7px;border-top:1px solid #150f19;box-shadow:inset 0 1px #c8b0bd30}\r\n.control-board .cb-part{display:flex;flex-direction:column;align-items:center;gap:5px}\r\n.control-board .cb-label{padding:3px 5px 2px;border-radius:2px;background:#1a141f;box-shadow:inset 0 1px 2px #000a,0 1px #c8b0bd33;font-size:10px}\r\n\r\n/* Rotaries: recessed well, detent ticks, a cap that turns to --angle and snaps with a little overshoot */\r\n.control-board .cb-rotary{--size:76px;--angle:-135deg;position:relative;flex:none;width:var(--size);height:var(--size);border-radius:50%;touch-action:none;cursor:grab;background:radial-gradient(closest-side,#0d0a10 76%,#2f2536 79% 87%,#0000 89%)}\r\n.control-board .cb-rotary:focus-visible{outline:3px solid var(--cb-gold);outline-offset:2px}\r\n.control-board .cb-rotary.is-turning{cursor:grabbing}\r\n.control-board .cb-rotary[aria-disabled=true]{opacity:.45;cursor:default}\r\n.control-board .cb-ticks{position:absolute;inset:0;pointer-events:none}\r\n.control-board .cb-ticks b{position:absolute;left:calc(50% - 1px);top:0;width:2px;height:5px;border-radius:1px;background:#8a7686;transform-origin:1px calc(var(--size) / 2);transform:rotate(var(--a))}\r\n.control-board .cb-ticks b[data-on]{background:var(--cb-gold);box-shadow:0 0 5px var(--cb-gold)}\r\n.control-board .cb-rotary i{position:absolute;inset:10px;border-radius:50%;transform:rotate(var(--angle));transition:transform .18s cubic-bezier(.3,1.6,.5,1),scale .08s;pointer-events:none}\r\n.control-board .cb-rotary.is-turning i{transition:scale .08s}\r\n.control-board .cb-rotary:active:not([aria-disabled=true]) i{scale:.95}\r\n.control-board .cb-rotary:after{content:'';position:absolute;inset:10px;border-radius:50%;background:radial-gradient(circle at 34% 28%,#ffffff40,#0000 48%);pointer-events:none}\r\n/* Focus dial: knurled edge, gold pointer */\r\n.control-board .cb-dial i{background:radial-gradient(closest-side,#7a6677 0 68%,#584656 74%,#0000 76%),repeating-conic-gradient(#ad99a5 0 5deg,#3a2e3f 5deg 10deg);box-shadow:0 3px 5px #000b,0 0 0 1px #0d0a10}\r\n.control-board .cb-dial i:after{content:'';position:absolute;left:calc(50% - 2px);top:3px;width:4px;height:16px;border-radius:2px;background:var(--cb-gold);box-shadow:0 0 6px #ffd36eaa}\r\n/* Level knob: bakelite pointer knob with min/max figures */\r\n.control-board .cb-knob{--size:58px}\r\n.control-board .cb-knob i{inset:9px;background:radial-gradient(closest-side,#302533 0 82%,#17111b 86%,#0000 90%);box-shadow:0 3px 4px #000b}\r\n.control-board .cb-knob i:before{content:'';position:absolute;left:calc(50% - 6px);top:-5px;bottom:-5px;width:12px;border-radius:6px;background:linear-gradient(90deg,#1e1822,#65536a 45%,#2b2231);box-shadow:0 2px 3px #000a}\r\n.control-board .cb-knob i:after{content:'';position:absolute;left:calc(50% - 1px);top:-3px;width:2px;height:15px;border-radius:1px;background:#fbefd9}\r\n.control-board .cb-knob:after{inset:9px}\r\n.control-board .cb-scale{display:flex;justify-content:space-between;width:58px;margin-top:-9px;padding:0 1px;color:var(--cb-dim);font-size:10px;letter-spacing:0}\r\n\r\n/* Lever: spring-loaded T-handle in a slot; HARDER above, EASIER below */\r\n.control-board .cb-lever{--pull:0px;position:relative;gap:0;width:46px;height:94px;border-radius:8px;background:linear-gradient(90deg,#19131e,#2c2332 50%,#19131e);box-shadow:inset 0 2px 5px #000c,0 1px #c8b0bd44;touch-action:none}\r\n.control-board .cb-lever:before{content:'';position:absolute;left:calc(50% - 3px);top:21px;bottom:21px;width:6px;border-radius:3px;background:#060408;box-shadow:inset 0 1px 2px #000,0 1px #c8b0bd33}\r\n.control-board .cb-lever button{position:relative;z-index:1;display:flex;justify-content:center;width:100%;height:47px;min-height:0;padding:5px 0;border:0;border-radius:8px;background:none;box-shadow:none;color:var(--cb-ink);font-size:10px;letter-spacing:.02em}\r\n.control-board .cb-lever #harder{align-items:flex-start}.control-board .cb-lever #easier{align-items:flex-end}\r\n.control-board .cb-lever button:focus-visible{outline-offset:-3px}\r\n.control-board .cb-lever button:active:not(:disabled){border-color:transparent;box-shadow:none;background:#ffd36e14}\r\n.control-board .cb-lever i{position:absolute;z-index:2;left:7px;right:7px;top:calc(50% - 7px);height:14px;border-radius:7px;background:linear-gradient(#ffd691,#c98640 55%,#8a5430);box-shadow:inset 0 1px #fff5,0 3px 4px #000b;transform:translateY(var(--pull));transition:transform .2s cubic-bezier(.3,1.6,.5,1);pointer-events:none}\r\n.control-board .cb-lever.is-pulling i{transition:none}\r\n.control-board .cb-lever:has(button:disabled){opacity:.45}\r\n\r\n/* Sound: bat-handle toggle on a plate; up is ON. app.mjs writes ON/OFF as the lamp text. */\r\n.control-board .cb-switch{position:relative;display:flex;align-items:flex-end;justify-content:center;width:44px;height:76px;min-height:0;padding:0 0 6px;border:1px solid #0d0a10;border-radius:7px;background:linear-gradient(#524352,#30273a);box-shadow:inset 0 1px #d4bdca66,inset 0 -2px #0006,0 3px 0 #140f19;color:#7d6c79;transition:transform .07s}\r\n.control-board .cb-switch:before{content:'';position:absolute;left:calc(50% - 4px);top:calc(40% - 26px);width:8px;height:26px;border-radius:4px 4px 2px 2px;background:linear-gradient(90deg,#6b5d69,#f4ebf0 45%,#857583);box-shadow:2px 2px 3px #0009;transform-origin:50% 100%;transition:transform .14s cubic-bezier(.3,1.5,.5,1)}\r\n.control-board .cb-switch:after{content:'';position:absolute;left:calc(50% - 8px);top:calc(40% - 8px);width:16px;height:16px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#dccbd4,#6e5f6c 60%,#382d3a);box-shadow:0 2px 3px #000a}\r\n.control-board .cb-switch[data-on=false]:before{transform:scaleY(-1)}\r\n.control-board .cb-switch[data-on=true]{color:var(--cb-gold);text-shadow:0 0 6px #ffd36e}\r\n.control-board .cb-switch:active:not(:disabled){transform:translateY(1px);border-color:#0d0a10;box-shadow:inset 0 1px #d4bdca44,0 2px 0 #140f19}\r\n\r\n/* Tracking notes: a slim hatch along the bottom edge */\r\n.control-board .movement-scope{margin:3px 8px 0;color:#e3cfde;font:12px/1.45 system-ui,-apple-system,'Segoe UI',sans-serif;letter-spacing:0;-webkit-user-select:text;user-select:text}\r\n.control-board .movement-scope summary{display:flex;align-items:center;gap:6px;min-height:24px;color:var(--cb-dim);font:700 8px/1 var(--cb-mono);letter-spacing:.14em;text-transform:uppercase;list-style:none;cursor:pointer}\r\n.control-board .movement-scope summary::-webkit-details-marker{display:none}\r\n.control-board .movement-scope summary:before{content:'▸'}.control-board .movement-scope[open] summary:before{content:'▾'}\r\n.control-board .movement-scope p{margin:4px 0}\r\n\r\n@media(max-width:370px){.control-board{padding:10px 9px 2px}.control-board .cb-dial{--size:68px}.control-board .cb-knob{--size:52px}.control-board .cb-scale{width:52px}.control-board .cb-key{width:58px}.control-board #variationName{font-size:13px}}\r\n@media(prefers-reduced-motion:reduce){.control-board *,.control-board *:before,.control-board *:after{transition:none!important}}\r\n\r\n/* Cool Cardio key: its own pressable metal bar under the dials, reachable on every coach path */\r\n.control-board .cb-cardio{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:44px;margin-top:9px;padding:6px 10px;border:1px solid #120d16;border-radius:7px;background:linear-gradient(#716070,#4a3b4b);box-shadow:inset 0 1px #dcc4cf99,inset 0 -2px #291f2d,0 4px 0 #140f19;color:var(--cb-ink);font:700 12px/1 var(--cb-mono);letter-spacing:.16em;transition:transform .07s,box-shadow .07s}\r\n.control-board .cb-cardio small{font:inherit;font-size:9px;color:var(--cb-gold);letter-spacing:.2em}\r\n.control-board .cb-cardio-led{width:9px;height:9px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#ffe9a8,#ffb42e 60%,#6b3d00);box-shadow:0 0 6px #ffd36e}\r\n.control-board .cb-cardio:active:not(:disabled){transform:translateY(3px);box-shadow:inset 0 1px #dcc4cf55,0 1px 0 #140f19}\r\n.control-board .cb-cardio:disabled{opacity:.55}\r\n.control-board .cb-cardio:focus-visible{outline:3px solid var(--cb-gold);outline-offset:2px}\r\n@media(max-width:370px){.control-board .cb-cardio{letter-spacing:.1em;font-size:11px}}\r\n","pod/dj-identity.js":"/* One identity follows the player from the Music Desk to the Gala. */\r\n(()=>{'use strict';\r\n const KEY='mbs-dj-identity-v1';\r\n const moniker=value=>String(value||'').normalize('NFKC').toUpperCase().replace(/[^A-Z0-9]/g,'').slice(0,3);\r\n function valid(value){return !!(value&&value.version===1&&typeof value.base==='string'&&value.base.length>0&&value.base.length<=48&&/^[A-Z0-9]{3}$/.test(value.moniker)&&Array.isArray(value.parts)&&value.parts.length===3&&value.parts.every(p=>typeof p==='string'&&p.length<24)&&Number.isSafeInteger(value.chosenAt)&&value.chosenAt>0&&(value.completedAt===null||Number.isSafeInteger(value.completedAt)&&value.completedAt>=value.chosenAt));}\r\n function read(){try{const value=JSON.parse(localStorage.getItem(KEY));return valid(value)?value:null;}catch{return null;}}\r\n function write(value){localStorage.setItem(KEY,JSON.stringify(value));window.dispatchEvent(new CustomEvent('mbs:dj-identity',{detail:value}));return value;}\r\n function choose(base,tag,parts){tag=moniker(tag);if(tag.length!==3)throw Error('Add three letters or numbers for your moniker.');base=String(base||'').trim().slice(0,48);if(!base||!Array.isArray(parts)||parts.length!==3||parts.some(p=>!p))throw Error('Choose all three parts of your DJ name.');const old=read();if(old?.completedAt&&(old.base!==base||old.moniker!==tag))throw Error('Your prisoner name is locked to this run.');return write({version:1,base,moniker:tag,parts,chosenAt:old?.chosenAt||Date.now(),completedAt:old?.completedAt||null});}\r\n function complete(){const current=read();if(!current)throw Error('Choose your DJ name first.');if(current.completedAt)return current;return write({...current,completedAt:Date.now()});}\r\n function name(value=read()){return value?`${value.base} · ${value.moniker}`:'Anonymous guest';}\r\n function display(value=read()){return value?.completedAt?`PRISONER ${name(value)}`:'Anonymous guest';}\r\n function retag(tag){const old=read();tag=moniker(tag);if(!old||tag.length!==3)throw Error('Use three letters or numbers.');return write({...old,moniker:tag});}\r\n window.MBS_DJ={KEY,moniker,valid,read,choose,complete,name,display,retag};\r\n})();\r\n","pod/encouragement.mjs":"import {valueOf} from './set-flow.mjs';\r\nconst LINES={reps:['Steady work.','One movement at a time.','Keep your own pace.'],hold:['Stay comfortable.','Take your time.','Steady work.'],pace:['Find your rhythm.','Keep your own pace.','Steady work.'],steps:['Find your rhythm.','One step at a time.','Keep your own pace.'],jumps:['Keep your own pace.','One movement at a time.','Steady work.']};\r\nexport class SetEncouragement {\r\n constructor(){this.reset();}\r\n reset(){this.first=null;this.last=-Infinity;this.halfway=false;this.index=0;}\r\n update(m,goal,now,otherCues=[]){\r\n  if(!m.tracking||m.complete||valueOf(m)>=goal)return null;\r\n  if(['squat','pushup','jumping'].includes(m.mode)&&!m.calibrated)return null;\r\n  if(m.kind==='hold'&&m.progress!==1)return null;\r\n  this.first??=now;\r\n  // Speak around counts; give setup, recovery and timer announcements priority.\r\n  if(otherCues.some(c=>c.key!=='count')||now-this.last<8000)return null;\r\n  if(!this.halfway&&valueOf(m)>=goal/2){this.halfway=true;this.last=now;return {text:'Halfway. Keep your own pace.',key:'encouragement'};}\r\n  if(now-this.first>=18000&&now-this.last>=20000){this.last=now;const choices=LINES[m.kind]||LINES.reps;return {text:choices[this.index++%choices.length],key:'encouragement'};}\r\n  return null;\r\n }\r\n}\r\n","pod/gala-avatar.js":"/* Original 64 × 96 layered pixel sprites. No external character art or game rules. */\r\n(()=>{'use strict';\r\nconst sections=[\r\n ['body','Body','A silhouette from somewhere very far away.',['Zorbian','Vexling','Orryx','Mollu','Krell','Nymbi','Quorlan','Xelith','Dravox','Ulumi']],\r\n ['skin','Skin','Twenty tones of otherworldly complexion.',['Nebula lilac','Reactor mint','Solar coral','Lunar porcelain','Void indigo','Comet gold','Plasma rose','Tidal teal','Martian ochre','Ghost ice']],\r\n ['face','Face','Make an unforgettable first impression.',['Vela gaze','Solo orb','Triune sight','Obsidian visor','Quasar quartet','Mothkin eyes','Ziggy grin','Mollu blush','Starborn mask','Oracle six']],\r\n ['hair','Hair','Coiffed, grown, or very carefully hatched.',['Vex wave','Quasar crest','Nebula bob','Orbital knots','Plasma cascade','Spore crown','Void slick','Comet braid','Prism spikes','Lunar fringe']],\r\n ['facial','Facial details','Whiskers, frills, and social signals.',['Vela bare','Zor whiskers','Krell beard','Mollu frill','Oracle dots','Quor tendrils','Vex moustache','Dravox jaw','Nymbi veil','Ulumi sparkle']],\r\n ['headwear','Headwear','MOM can spot good headwear across a galaxy.',['Vela circlet','Orryx crown','Quasar halo','Nymbi veil','Krell cap','Xelith horns','Mollu fascinator','Dravox helm','Orbital rings','Comet antennae']],\r\n ['neck','Neckwear','The smallest, most unreasonable finishing touch.',['Zor cravat','Vela bow','Orryx pearls','Quasar ruff','Mollu scarf','Krell collar','Xelith pendant','Nymbi ribbon','Dravox chain','Ulumi choker']],\r\n ['torso','Formalwear','Alien eveningwear. Excellent tailoring.',['Vex tuxedo','Mollu gown','Orryx brocade','Quasar jumpsuit','Nymbi corset','Krell robe','Xelith doublet','Dravox tailcoat','Ulumi wrap','Zor sequin suit']],\r\n ['shoulders','Shoulders','A little room for dramatic entrances.',['Vela epaulettes','Quor petals','Krell spikes','Nymbi puffs','Orryx mantle','Vex wings','Dravox plates','Mollu fronds','Xelith orbitals','Ulumi cape']],\r\n ['arms','Sleeves','Twenty ways to wave at someone important.',['Vela silk','Quasar flares','Krell cuffs','Mollu lace','Orryx stripes','Vex sheer','Dravox panels','Nymbi bells','Xelith rings','Ulumi ribbons']],\r\n ['hands','Gloves','Keep your hands where MOM can see them.',['Vela gloves','Krell talons','Orryx cuffs','Quasar mesh','Mollu mitts','Vex rings','Dravox gauntlets','Nymbi ruffles','Xelith claws','Ulumi glow']],\r\n ['legs','Lower half','Trousers, trains, and several extra possibilities.',['Vex trousers','Mollu bell skirt','Orryx pleats','Quasar split','Nymbi bubble','Krell drape','Xelith stripes','Dravox breeches','Ulumi train','Zor shimmer']],\r\n ['feet','Footwear','For the marble floors of an alien palace.',['Vela slippers','Krell platforms','Orryx curltoes','Quasar boots','Mollu petals','Vex heels','Dravox greaves','Nymbi clouds','Xelith skates','Ulumi moonsteps']],\r\n ['held','Held accessory','An arrival accessory, not a combat loadout.',['Vela flute','Orryx fan','Quasar clutch','Mollu bouquet','Krell cane','Nymbi lantern','Vex invitation','Dravox orb','Xelith parasol','Ulumi familiar']],\r\n ['back','Back accessory','Make leaving the room just as interesting.',['Vela ribbons','Orryx cape','Quasar fins','Mollu spores','Krell spines','Nymbi wings','Vex sash','Dravox coils','Xelith satellites','Ulumi starlight']],\r\n ['base','Display base','A tiny piece of the palace to call your own.',['Vela marble','Orryx dais','Quasar moon','Mollu garden','Krell obsidian','Nymbi cloud','Vex carpet','Dravox grille','Xelith crystal','Ulumi orbit']],\r\n ['pet','Pet','A companion dressed for the same questionable occasion.',['No companion','Mollu pup','Vex moth','Orryx beetle','Quasar cat','Nymbi jelly','Krell lizard','Xelith puff','Dravox bot','Ulumi sprout']]\r\n].map(([id,label,note,names])=>({id,label,note,names:[...names,...names.map(n=>'Xyrr '+(n==='No companion'?'slug':n)),...names.map(n=>'Auv '+(n==='No companion'?'slug':n)),...names.map(n=>'Oth '+(n==='No companion'?'slug':n))]}));\r\n// Twenty visually distinct choices per category. Keep original recipe IDs and\r\n// all legacy names/rendering so existing saves and coach imports remain unchanged.\r\n// Covers every base type; variants maximize visible differences across six outfits.\r\nconst curatedChoices={\r\n body:[0,11,2,12,32,3,13,33,14,34,15,35,6,16,36,37,18,28,19,39],\r\n skin:[0,20,11,12,32,23,33,14,34,5,25,35,6,26,36,7,37,38,19,39],\r\n face:[0,21,31,22,32,23,33,14,24,34,25,35,26,36,27,28,38,19,29,39],\r\n hair:[0,11,31,12,22,32,13,33,14,34,15,35,36,17,27,37,18,38,19,29],\r\n facial:[0,11,21,31,12,32,13,23,33,14,34,15,25,35,26,17,27,18,38,39],\r\n headwear:[0,11,21,12,22,32,13,23,33,14,24,34,25,16,36,37,38,19,29,39],\r\n neck:[0,20,30,11,2,13,23,33,14,24,34,15,25,36,7,27,37,28,19,29],\r\n torso:[0,11,31,12,22,32,13,24,34,25,35,26,36,17,27,37,18,28,38,9],\r\n shoulders:[0,30,11,12,23,33,24,15,25,35,16,36,17,27,37,18,38,19,29,39],\r\n arms:[0,11,12,13,33,14,15,25,6,26,36,7,27,37,18,28,38,19,29,39],\r\n hands:[0,11,21,31,12,22,33,14,24,34,25,36,17,27,37,18,28,38,9,29],\r\n legs:[0,11,21,31,22,32,23,24,34,15,25,35,16,36,27,37,18,28,38,29],\r\n feet:[0,11,21,31,12,32,3,13,14,24,34,25,26,36,17,37,28,38,9,29],\r\n held:[0,11,21,31,32,23,33,14,24,34,25,16,17,27,37,18,28,38,29,39],\r\n back:[0,11,21,31,12,22,13,23,33,14,34,15,35,16,26,17,37,38,19,29],\r\n base:[0,11,2,22,32,23,4,34,5,25,35,16,26,36,37,18,28,38,19,39],\r\n pet:[0,10,20,30,11,12,32,3,24,15,25,35,36,27,37,28,38,19,29,39],\r\n};\r\nsections.forEach(section=>{section.choices=curatedChoices[section.id];});\r\nconst dyes=['#9762b6','#bd476e','#467f9e','#4b9478','#d39d46','#485aa0','#d17e52','#c7adba','#5f596d','#83b8b6'];\r\nconst skin=['#b18fc8','#80ba98','#d78989','#ddd3c5','#7371ae','#c6a55e','#ce84b6','#67a5a6','#b77857','#a5c8d8'];\r\nconst defaultLook={schema:'mominc-avatar',version:1,name:'Velora of the Ninth Moon',dye:0,parts:Object.fromEntries(sections.map(s=>[s.id,0]))};\r\nfunction normalize(raw){if(!raw||raw.schema!=='mominc-avatar'||raw.version!==1||!raw.parts)throw Error('Choose a MOM Inc avatar file.');const n={schema:'mominc-avatar',version:1,name:typeof raw.name==='string'?raw.name.trim().slice(0,64):'',dye:raw.dye,parts:{}};if(!Number.isInteger(n.dye)||n.dye<0||n.dye>9)throw Error('This look has an unknown silk colour.');for(const s of sections){let v=raw.parts[s.id]??(s.id==='pet'?0:undefined);if(!Number.isInteger(v)||v<0||v>=s.names.length)throw Error('This look has an unknown wardrobe piece.');n.parts[s.id]=v;}if(raw.weapon!=null){if(!window.GalaWeapons)throw Error('Open the updated Gala to import this weapon.');n.weapon=window.GalaWeapons.normalize(raw.weapon);}return n;}\r\nfunction tone(hex,amount){let n=parseInt(hex.slice(1),16);return '#'+[n>>16,n>>8&255,n&255].map(v=>Math.max(0,Math.min(255,v+amount)).toString(16).padStart(2,'0')).join('');}\r\nfunction skinColor(look){const value=look.parts.skin||0,group=Math.floor(value/10);return tone(skin[value%10],group*14-(group===3?60:0));}\r\nfunction draw(canvas,look,{base=true,weapon=true,time=0,companion=true,petOnly=false,prop=true,blink=false,pose={}}={}){\r\n const equipment=!petOnly&&weapon&&look.weapon&&window.GalaWeapons?.unlocked(look.weapon)?look.weapon:null;canvas.width=equipment?96:64;canvas.height=96;const c=canvas.getContext('2d');c.imageSmoothingEnabled=false;const original=look.parts,p=Object.fromEntries(Object.entries(original).map(([k,v])=>[k,v%10])),group=key=>Math.floor((original[key]||0)/10),S=skinColor(look),D=tone(S,-37),L=tone(S,35),F=dyes[look.dye],H=tone(F,42),B=tone(F,-40),gold='#e6c880',ink='#21172e',white='#fbebce';\r\n const rect=(x,y,w,h,col)=>{c.fillStyle=col;c.fillRect(Math.round(x),Math.round(y),Math.round(w),Math.round(h));};\r\n const poly=(points,col,line=ink)=>{c.beginPath();points.forEach(([x,y],i)=>i?c.lineTo(x+.5,y+.5):c.moveTo(x+.5,y+.5));c.closePath();c.fillStyle=col;c.fill();if(line){c.strokeStyle=line;c.lineWidth=1;c.stroke();}};\r\n const dot=(x,y,col=gold)=>rect(x,y,1,1,col);\r\n const gem=(x,y,col=gold)=>{poly([[x,y-2],[x+2,y],[x,y+2],[x-2,y]],col);dot(x,y-1,white);};\r\n const box=(x,y,w,h,col)=>{rect(x,y,w,h,ink);rect(x+1,y+1,w-2,h-2,col);};\r\n const width=[0,-2,3,2,4,-1,1,-3,3,0][p.body];\r\n const armPose=side=>{const x=side<0?21-width:44+width,y=39;let angle=(pose.walk||0)*side*.1,stretch=1;if(pose.meditate)angle=-side*.45;else if(pose.meditationStanding)angle=-side*.92;else if(side>0&&pose.greet!=null)angle=-1.08+pose.greet*.36;else if(side<0&&pose.petting!=null){stretch=[1.8,1.5,1.02,1.55,1.5,1.4,1.5,1.4,1.25,1.16][p.pet];angle=Math.asin((x-14)/(23*stretch))+pose.petting*.045;}if(side>0&&pose.weapon)angle=-.8;c.translate(x,y);c.rotate(angle);c.scale(1,stretch);c.translate(-x,-y);};\n if(!petOnly){\r\n // Each base has its own silhouette and surface pattern.\r\n if(base){const i=p.base;poly([[13-i%3,87],[22,84],[43,84],[52+i%3,88],[45,93],[20,93]],i===6?'#913f58':i===4?'#383341':i===5?'#aea6c9':'#756580');for(let x=18;x<48;x+=3){rect(x,89,2,2,i%2?gold:'#bca7bd');if(i===3||i===9)gem(x,84-(x%3),i===3?'#81b791':H);}if(i===1)rect(18,85,29,2,gold);if(i===2)box(20,87,5,3,'#a4a0bd');if(i===7)for(let x=18;x<49;x+=4)rect(x,86,1,6,ink);if(i===8)for(let x=16;x<49;x+=8)poly([[x,88],[x+2,79],[x+5,88]],'#8db9d0');}\r\n // Back accessories, behind the body and all clothes.\r\n switch(p.back){case 0:poly([[23,37],[17,69],[21,73],[28,39]],H);poly([[39,38],[44,73],[47,69],[42,37]],B);break;\r\n case 1:poly([[23,35],[14,79],[48,79],[41,35]],B);for(let x=20;x<47;x+=7)rect(x,55,1,20,F);break;\r\n case 2:for(const x of [14,43])poly([[x+6,38],[x,24],[x-3,62],[x+9,55]],H);break;\r\n case 3:for(let i=0;i<6;i++){rect(15+i*7,29+i%2*7,1,35,B);box(12+i*7,27+i%2*7,7,5,H);}break;\r\n case 4:for(let i=0;i<5;i++){poly([[21,36+i*7],[11,31+i*8],[19,43+i*6]],gold);poly([[43,36+i*7],[53,31+i*8],[45,43+i*6]],gold);}break;\r\n case 5:poly([[24,42],[8,28],[6,47],[15,61],[25,53]],H);poly([[40,42],[56,28],[58,47],[49,61],[39,53]],H);break;\r\n case 6:poly([[21,37],[13,61],[22,77],[20,58],[28,37]],gold);break;\r\n case 7:for(let y=38;y<76;y+=7){box(12,y,10,5,B);box(42,y,10,5,H);}break;\r\n case 8:for(const [x,y] of [[10,32],[52,35],[8,61],[55,63]]){gem(x,y,H);rect(x-4,y,9,1,gold);}break;\r\n case 9:for(let i=0;i<16;i++)gem(7+(i*17)%51,24+(i*13)%53,i%2?gold:H);break;}\r\n // Alien body silhouettes: ears, horns, tails, and differing frames.\r\n if(p.body===3||p.body===7)poly([[40,65],[51,69],[51,76],[46,78],[44,73],[41,72]],S);\r\n if(p.body===6)for(let i=0;i<3;i++)poly([[27+i*5,73],[22+i*7,84],[25+i*7,86],[32+i*3,74]],S);\r\n poly([[25-width,34],[39+width,34],[42+width,48],[38+width,65],[26-width,65],[22-width,48]],S);rect(29,30,7,8,D);\r\n box(24-width,63,7+width,18,S);box(34,63,7+width,18,D);\r\n c.save();armPose(-1);poly([[23-width,36],[18-width,39],[16-width,58],[22-width,59],[26-width,43]],S);c.restore();c.save();armPose(1);poly([[41+width,36],[46+width,39],[48+width,58],[42+width,59],[38+width,43]],D);c.restore();\r\n if([1,4,8].includes(p.body)){poly([[23,21],[15,16],[18,28],[25,29]],S);poly([[40,21],[48,16],[45,28],[39,29]],D);}\r\n if(p.body===2||p.body===9){rect(25,8,2,10,D);rect(37,8,2,10,S);gem(25,8,H);gem(38,8,H);}\r\n poly([[25,14],[38,14],[42,18],[42,28],[37,34],[27,34],[22,28],[22,19]],S);rect(24,18,2,9,L);rect(39,20,2,9,D);rect(28,32,9,2,D);\r\n if(p.body===5){poly([[22,23],[16,25],[22,28]],L);poly([[42,23],[48,25],[42,28]],D);}\r\n if(p.body===8){rect(24,15,3,3,gold);rect(37,15,3,3,gold);}\r\n if(p.body===9)for(const x of [24,29,35,40])dot(x,29,H);\r\n // Lower clothing: distinct hems and cut.\r\n let leg=p.legs;\r\n if([1,2,4,5,8].includes(leg)){let flare=[0,7,4,0,8,3,0,0,10,0][leg];poly([[25-width,57],[39+width,57],[42+flare,79],[22-flare,79]],leg===5?B:F);for(let x=23-flare;x<43+flare;x+=4)rect(x,68,1,10,leg===2?gold:B);rect(22-flare,78,20+flare*2,2,H);if(leg===4){rect(19,65,27,6,H);rect(22,73,20,3,B);}if(leg===8)poly([[39,65],[54,82],[43,81]],H);}\r\n else{box(24-width,58,8+width,21,F);box(34,58,8+width,21,B);if(leg===3){rect(25,70,5,8,S);rect(35,70,5,8,S);}if(leg===6)for(let y=61;y<78;y+=3){rect(25-width,y,6+width,1,gold);rect(35,y,6+width,1,gold);}if(leg===7){rect(22-width,59,10+width,9,H);rect(34,59,10+width,9,H);}if(leg===9)for(let i=0;i<10;i++)dot(25+(i*7)%15,60+i*2,gold);}\r\n // Shoes each alter toe/height/surface, always visible below hems.\r\n for(const [x,flip] of [[23-width,false],[34,true]]){let i=p.feet;box(x,78-(i===3||i===6?5:0),9+width,6+(i===3||i===6?5:0),i===7?'#cfbddf':i===9?L:B);rect(x,83,9+width,i===1?3:1,gold);if(i===2)poly([[x,81],[x-3,77],[x-4,84],[x+4,84]],H);if(i===4)for(let z=0;z<3;z++)gem(x+z*3,79,H);if(i===5)rect(x+6,84,2,2,gold);if(i===8){rect(x-2,84,13,1,'#bdd3df');rect(x,85,2,1,'#bdd3df');}if(i===0)dot(x+3,80,gold);if(i===6)rect(x+3,75,2,8,gold);}\r\n // Torso cuts and embroidery.\r\n let t=p.torso;poly([[24-width,36],[39+width,36],[41+width,57],[38,62],[26,62],[22-width,57]],F);\r\n rect(24-width,40,2,16,H);rect(38+width,41,2,17,B);rect(25-width,58,14+width*2,2,gold);\r\n if(t===0||t===7){poly([[26,36],[32,49],[38,36]],white);poly([[23,36],[29,36],[32,50],[26,46]],B);poly([[41,36],[35,36],[32,50],[38,46]],B);for(let y=50;y<58;y+=3)dot(32,y,gold);if(t===7){poly([[24,57],[19,74],[28,64]],B);poly([[39,57],[45,74],[36,64]],B);}}\r\n if(t===1){poly([[24,36],[31,42],[40,36],[39,56],[25,56]],H);rect(29,44,6,12,F);}\r\n if(t===2)for(let y=39;y<57;y+=5)for(let x=26;x<39;x+=5)gem(x,y,gold);\r\n if(t===3){rect(30,36,4,22,B);for(let y=40;y<55;y+=4)rect(31,y,2,2,gold);}\r\n if(t===4){rect(27,42,10,14,B);for(let y=43;y<55;y+=3){rect(29,y,6,1,gold);dot(28,y-1,white);}}\r\n if(t===5){poly([[26,36],[36,37],[25,58],[23,51]],H);rect(32,48,2,10,gold);}\r\n if(t===6){rect(25,38,14,3,H);rect(25,43,14,3,B);rect(30,36,3,22,gold);}\r\n if(t===8){poly([[23,39],[40,53],[39,58],[23,43]],H);poly([[38,36],[40,40],[25,56],[23,52]],B);}\r\n if(t===9)for(let i=0;i<30;i++)dot(25+(i*7)%14,38+(i*11)%19,i%2?gold:H);\r\n // Sleeves and gloves.\r\n for(const side of [-1,1]){c.save();armPose(side);let x=side<0?18-width:41+width,i=p.arms;box(x,39,6,18,i===5?S:F);rect(x,40,1,14,H);if(i===1||i===7)poly([[x,46],[x+5,46],[x+8,56],[x-3,56]],H);if(i===2||i===6)box(x-1,50,8,5,B);if(i===6){box(x-1,43,8,5,gold);rect(x+2,49,2,5,H);}if(i===7){rect(x-2,54,10,3,gold);rect(x-1,48,8,3,B);}if(i===3)for(let y=42;y<55;y+=3){rect(x,y,6,1,white);dot(x+3,y+1,B);}if(i===4||i===8)for(let y=40;y<55;y+=4)rect(x-1,y,8,2,i===4?B:gold);if(i===9)poly([[x,42],[x-3,65],[x+2,60],[x+5,42]],H);\r\n let h=p.hands;box(x,56,6,7,[1,5,8].includes(h)?S:h===9?L:B);if(h===1||h===8)for(let z=0;z<3;z++)rect(x+z*2,62,1,h===8?4:2,gold);if(h===2||h===6)box(x-1,54,8,4,gold);if(h===6){rect(x+1,58,4,3,gold);rect(x+2,61,2,2,H);}if(h===3)for(let y=57;y<62;y+=2)rect(x+1,y,4,1,H);if(h===4)rect(x-1,58,8,4,H);if(h===5)gem(x+3,59,gold);if(h===7)for(let z=0;z<4;z++)rect(x-1+z*2,54-z%2,1,4,white);if(h===9)gem(x+2,59,white);c.restore();}\r\n // Shoulder forms.\r\n for(const side of [-1,1]){let x=side<0?18-width:40+width,i=p.shoulders;switch(i){case 0:box(x,36,7,4,gold);rect(x,40,1,4,gold);break;case 1:for(let z=0;z<3;z++)poly([[x+3,35],[x-2+z*3,31],[x+z*3,41]],H);break;case 2:poly([[x,39],[x,30],[x+3,35],[x+6,29],[x+7,40]],gold);break;case 3:poly([[x-2,37],[x,33],[x+6,33],[x+9,37],[x+6,43],[x,43]],H);break;case 4:box(x-1,35,9,7,B);rect(x,37,7,1,gold);break;case 5:poly([[x+3,39],[x-5*side,29],[x+8,34],[x+5,43]],H);break;case 6:box(x-1,35,9,8,B);gem(x+3,38,gold);break;case 7:for(let z=0;z<3;z++)poly([[x+3,35],[x-3+z*4,45],[x+z*3,46]],H);break;case 8:rect(x-2,35,11,2,gold);rect(x-1,40,10,1,gold);break;case 9:poly([[x,34],[x+7,34],[x+9,50],[x-3,49]],B);rect(x,35,6,2,gold);}}\r\n // Neck accessories are independent of the outfit.\r\n let n=p.neck;switch(n){case 0:poly([[29,35],[34,35],[35,43],[31,45],[29,41]],white);break;case 1:poly([[26,34],[32,36],[38,34],[38,40],[32,37],[26,40]],gold);break;case 2:for(let x=26;x<40;x+=3)box(x,35+Math.abs(32-x)*-.3,2,2,white);break;case 3:for(let x=25;x<40;x+=2)rect(x,33+(x%3),2,6,white);break;case 4:rect(27,34,12,4,H);rect(34,37,4,12,H);break;case 5:box(26,33,13,6,B);gem(32,35);break;case 6:rect(28,35,1,4,gold);rect(36,35,1,4,gold);gem(32,40);break;case 7:rect(28,34,10,2,H);poly([[31,36],[27,46],[31,44],[33,36]],H);break;case 8:for(let x=26;x<40;x+=2)rect(x,35+Math.floor((6-Math.abs(32-x))/2),2,2,gold);break;case 9:rect(27,33,11,2,gold);gem(32,34,H);}\r\n // Face features.\r\n let f=p.face;const eye=(x,y,w=3)=>{if(blink){rect(x,y+2,w+2,1,ink);return;}box(x,y,w+2,4,white);rect(x+2,y+1,1,2,ink);};\r\n if(f===1){if(blink){rect(26,24,12,1,ink);}else{box(26,21,12,7,white);box(30,22,5,5,'#926299');dot(31,23,white);}}else if(f===3){box(24,21,16,5,ink);rect(25,22,13,1,blink?B:H);}else if(f===5){poly([[24,20],[29,22],[29,27],[24,25]],ink);poly([[39,20],[34,22],[34,27],[39,25]],ink);if(blink){rect(24,20,6,7,S);rect(34,20,6,7,S);rect(24,24,5,1,ink);rect(35,24,5,1,ink);}else{dot(25,22,white);dot(36,22,white);}}else if(f===8){poly([[24,20],[32,22],[40,20],[38,28],[26,28]],gold);rect(26,23+(blink?1:0),3,blink?1:2,ink);rect(35,23+(blink?1:0),3,blink?1:2,ink);}else{eye(25,22);eye(34,22);if(f===2)eye(29,17);if(f===4){eye(25,17,2);eye(35,17,2);}if(f===9)for(const [x,y] of [[26,17],[34,17],[26,27],[34,27]])eye(x,y,1);}\r\n rect(29,29,f===6?8:5,1,ink);if(f===6){rect(30,30,6,1,white);rect(31,31,4,1,ink);}if(f===7){rect(24,27,3,1,'#df8b9b');rect(38,27,3,1,'#df8b9b');}\r\n // Facial ornament; zero is deliberately bare.\r\n let a=p.facial;if(a===1)for(const y of [27,29]){rect(19,y,7,1,gold);rect(39,y,7,1,gold);}if(a===2)poly([[26,30],[38,30],[36,37],[31,39],[27,35]],B);if(a===3)for(let x=24;x<41;x+=3)poly([[x,29],[x+1,36],[x+3,30]],H);if(a===4)for(const [x,y] of [[24,20],[40,20],[25,28],[39,28]])gem(x,y,H);if(a===5){poly([[28,29],[26,39],[29,36],[30,30]],D);poly([[35,29],[39,39],[36,36],[33,30]],D);}if(a===6){rect(26,28,12,2,B);rect(24,27,3,2,B);rect(38,27,3,2,B);}if(a===7){box(24,28,3,5,gold);box(38,28,3,5,gold);rect(27,32,11,1,gold);}if(a===8)poly([[24,27],[40,27],[37,35],[27,35]],H);if(a===9){gem(24,28,white);gem(40,28,white);}\r\n // Ten different hairstyles with different silhouettes.\r\n switch(p.hair){case 0:poly([[22,20],[23,14],[29,11],[39,13],[42,18],[35,17],[28,15]],B);rect(25,14,9,1,H);break;case 1:poly([[29,18],[28,7],[32,9],[36,6],[35,18]],H);rect(31,9,2,8,B);break;case 2:poly([[22,16],[27,12],[38,13],[42,17],[44,31],[39,32],[39,18],[26,18],[25,32],[20,29]],B);rect(22,19,2,10,H);break;case 3:box(18,10,9,9,B);box(37,10,9,9,B);rect(25,14,14,3,B);gem(22,12,H);gem(41,12,H);break;case 4:poly([[24,16],[28,11],[40,13],[43,21],[46,43],[39,39],[38,19],[30,16]],H);rect(42,22,1,17,B);break;case 5:poly([[19,17],[21,12],[27,9],[38,10],[44,15],[44,18]],H);for(const x of [23,29,37,41])box(x,12+x%3,3,2,white);break;case 6:poly([[23,17],[26,12],[39,12],[41,16],[29,15]],B);rect(28,13,10,1,H);break;case 7:rect(24,13,16,4,B);for(let y=17;y<48;y+=4){box(40,y,4,4,H);dot(42,y+1,gold);}break;case 8:poly([[21,19],[22,9],[28,14],[31,6],[35,13],[41,8],[42,19]],H);rect(29,14,6,2,B);break;case 9:poly([[22,17],[25,12],[38,12],[42,17],[38,22],[35,17],[29,21],[27,17],[23,22]],B);rect(26,14,12,1,H);}\r\n // Headwear.\r\n let h=p.headwear;if(h===0){rect(23,16,18,1,gold);gem(32,16);}if(h===1)poly([[22,16],[22,9],[27,13],[32,7],[37,13],[42,9],[41,16]],gold);if(h===2){rect(22,6,20,1,gold);rect(20,7,2,2,gold);rect(42,7,2,2,gold);rect(22,9,20,1,gold);}if(h===3){poly([[20,16],[22,10],[41,10],[47,40],[42,37],[38,14],[25,14],[20,35]],'#a89eb4');rect(24,11,15,2,white);}if(h===4){box(24,7,15,8,B);rect(20,14,25,2,gold);}if(h===5){poly([[23,16],[18,7],[21,6],[27,16]],gold);poly([[37,16],[43,5],[45,8],[41,17]],gold);}if(h===6){poly([[37,15],[42,4],[46,5],[41,16]],H);gem(41,15);}if(h===7){poly([[22,17],[24,9],[39,9],[43,17],[40,21],[38,14],[26,14],[24,21]],gold);gem(32,10,H);}if(h===8){rect(18,13,29,1,gold);rect(21,10,23,1,H);gem(44,13);}if(h===9){rect(25,6,1,9,gold);rect(38,4,1,11,gold);gem(25,5,H);gem(38,3,H);}\r\n // Party props remain independent from the earned floating weapon.\r\n if(prop)switch(p.held){case 0:box(48+width,47,5,8,'#c4bdcf');rect(50+width,55,1,8,gold);rect(48+width,63,5,1,gold);rect(49+width,49,3,3,H);break;case 1:poly([[48,59],[43,46],[49,40],[58,45],[60,53]],H);for(let i=0;i<4;i++)poly([[48,59],[45+i*4,44+i%2]],gold);break;case 2:box(46,56,13,9,H);rect(47,59,11,1,gold);gem(53,59);break;case 3:poly([[49,63],[45,47],[56,47],[51,63]],'#548267');for(const [x,y] of [[45,45],[51,42],[57,46],[49,49]])gem(x,y,H);break;case 4:rect(51,47,2,36,gold);box(47,45,7,3,gold);break;case 5:rect(51,47,1,6,gold);box(47,53,10,13,B);rect(49,56,6,7,gold);gem(52,59,white);break;case 6:box(47,53,12,9,white);rect(49,55,7,1,B);gem(53,59,H);break;case 7:box(48,47,9,9,H);gem(52,51,white);rect(50,56,5,2,gold);break;case 8:rect(52,29,1,35,gold);poly([[40,33],[43,25],[52,22],[62,29],[63,33]],H);rect(42,32,20,1,gold);break;case 9:poly([[48,48],[48,43],[51,46],[56,44],[59,48],[57,55],[50,54]],S);dot(51,49,ink);dot(56,49,ink);rect(51,55,1,4,gold);rect(56,55,1,4,gold);}\r\n // Three additional collections give every part new cuts or surface details.\r\n for(const section of sections){const g=group(section.id);if(!g||['skin','pet'].includes(section.id)||(!prop&&section.id==='held'))continue;const accent=g===1?gold:g===2?white:'#88e4d9';const shift=(original[section.id]%10)%3;\r\n switch(section.id){\r\n case 'body':for(const x of [18-width,45+width]){if(g===1)poly([[x,23],[x-3,17],[x+2,19],[x+3,28]],S);if(g===2)box(x-2,24,5,6,D);if(g===3)for(let y=22;y<32;y+=3)gem(x,y,accent);}break;\r\n case 'face':if(g===1){rect(25,19,5,1,accent);rect(35,19,5,1,accent);}if(g===2){gem(31,26,accent);rect(26,28,3,1,accent);}if(g===3){rect(23,23,1,7,accent);rect(41,23,1,7,accent);}break;\r\n case 'hair':for(let x=24;x<42;x+=5){if(g===1)poly([[x,15],[x+1,9-shift],[x+3,15]],H);if(g===2)box(x,14,3,3,accent);if(g===3)rect(x,11,1,9,accent);}break;\r\n case 'facial':if(g===1){rect(26,31,3,4,accent);rect(36,31,3,4,accent);}if(g===2)poly([[27,32],[32,39],[37,32]],H);if(g===3)for(const x of [22,27,37,42])gem(x,31,accent);break;\r\n case 'headwear':if(g===1){rect(17,12,30,1,accent);gem(20,11,accent);}if(g===2){poly([[40,13],[49,3],[50,12]],H);gem(43,13,accent);}if(g===3){rect(20,4,24,1,accent);for(const x of [20,32,43])gem(x,3,accent);}break;\r\n case 'neck':if(g===1)box(30,37,5,6,accent);if(g===2){rect(26,37,2,9,accent);rect(37,37,2,9,accent);}if(g===3)for(let x=26;x<40;x+=3)gem(x,36,accent);break;\r\n case 'torso':for(let y=44;y<57;y+=3){if(g===1)rect(25,y,14,1,accent);if(g===2){dot(27,y,accent);dot(36,y+1,accent);}if(g===3)gem(32,y,accent);}break;\r\n case 'shoulders':for(const x of [18-width,42+width]){if(g===1)for(let k=0;k<3;k++)rect(x+k*2,39,1,6,accent);if(g===2)poly([[x-3,38],[x,29],[x+5,39]],H);if(g===3){rect(x-4,33,11,1,accent);gem(x,35,accent);}}break;\r\n case 'arms':for(const x of [19-width,42+width]){c.save();armPose(x<32?-1:1);if(g===1)rect(x,44,2,10,accent);if(g===2)poly([[x,43],[x-4,54],[x+4,54]],B);if(g===3)for(let y=44;y<55;y+=4)gem(x+1,y,accent);c.restore();}break;\r\n case 'hands':for(const x of [19-width,42+width]){c.save();armPose(x<32?-1:1);if(g===1)gem(x+2,58,accent);if(g===2)for(let k=0;k<3;k++)rect(x+k*2,62,1,4,accent);if(g===3)box(x-1,58,7,3,accent);c.restore();}break;\r\n case 'legs':for(const x of [26,36]){if(g===1)rect(x,65,1,12,accent);if(g===2)for(let y=65;y<77;y+=3)rect(x-1,y,4,1,accent);if(g===3)poly([[x,64],[x-3,76],[x+4,74]],H);}break;\r\n case 'feet':for(const x of [23-width,34]){if(g===1)rect(x-1,83,12,2,accent);if(g===2)poly([[x,80],[x-3,76],[x-5,83],[x+3,83]],H);if(g===3)gem(x+4,81,accent);}break;\r\n case 'held':if(g===1){rect(48,58,12,1,accent);gem(59,58,accent);}if(g===2)poly([[51,61],[57,71],[55,61]],H);if(g===3)for(const [x,y] of [[45,45],[59,48],[58,62]])gem(x,y,accent);break;\r\n case 'back':if(g===1){poly([[16,40],[8,62],[14,69]],H);poly([[48,40],[56,62],[50,69]],H);}if(g===2)for(const x of [12,52])for(let y=40;y<74;y+=8)gem(x,y,accent);if(g===3){for(const [x,y] of [[13,31],[51,31],[10,43],[54,43]])gem(x,y,accent);}break;\r\n case 'base':if(base){if(g===1)rect(18,92,29,2,accent);if(g===2)for(let x=15;x<52;x+=6)gem(x,91,accent);if(g===3){rect(12,94,41,1,accent);rect(10,91,2,3,accent);rect(53,91,2,3,accent);}}break;\r\n }}\r\n }\r\n // pose.meditate (#149): seated cross-legged. Everything above the hips drops 14px onto a wide folded lap with the shins\r\n // crossed in front; the outswung hands (outside the legs' columns) come down onto the knees. The companion sits beside, after.\r\n if(pose.meditate&&!petOnly){const o=document.createElement('canvas');o.width=canvas.width;o.height=96;o.getContext('2d').drawImage(canvas,0,0);c.clearRect(0,0,canvas.width,96);\r\n  poly([[22,70],[42,70],[55,80],[55,87],[9,87],[9,80]],F);poly([[10,84],[32,88],[54,84],[54,89],[32,92],[10,89]],B);box(26,86,6,5,ink);box(32,86,6,5,ink);\r\n  c.drawImage(o,0,0,canvas.width,58,0,14,canvas.width,58);c.drawImage(o,0,58,16,14,0,72,16,14);c.drawImage(o,48,58,16,14,48,72,16,14);}\r\n if(pose.meditationStanding&&!petOnly){const o=document.createElement('canvas');o.width=canvas.width;o.height=96;o.getContext('2d').drawImage(canvas,0,0);c.clearRect(0,56,canvas.width,40);c.drawImage(o,0,56,canvas.width,40,-10,56,canvas.width+20,40);}\r\n // Forty companion choices, including an empty slot, are part of the saved avatar recipe.\r\n if(companion&&original.pet){const k=p.pet,g=group('pet'),fur=[H,S,gold,'#90bca2','#d99bae','#ad9ac8','#81a891','#b1accb','#9caabb','#83b587'][k],x=9,y=k===2?67:79;\r\n if(k===0){poly([[x-6,y+5],[x-3,y],[x+3,y-1],[x+8,y+5]],fur);rect(x+6,y-3,1,4,fur);dot(x+6,y-3,white);}\r\n if([1,4,6].includes(k)){box(x-5,y-3,11,8,fur);box(x+3,y-7,7,7,fur);rect(x-4,y+5,2,3,fur);rect(x+3,y+5,2,3,fur);poly([[x+3,y-7],[x+3,y-11],[x+6,y-7]],fur);poly([[x+7,y-7],[x+10,y-11],[x+10,y-6]],fur);dot(x+7,y-4,ink);if(k===6)poly([[x-5,y],[x-11,y-4],[x-8,y+3]],fur);else rect(x-7,y-4,2,7,fur);if(k===4)rect(x+8,y-2,5,1,white);}\r\n if(k===2){poly([[x,y],[x-9,y-8],[x-9,y+6],[x,y+2]],fur);poly([[x+2,y],[x+10,y-8],[x+10,y+6],[x+2,y+2]],fur);box(x,y-3,3,10,B);gem(x-5,y-1,gold);gem(x+7,y-1,gold);}\r\n if(k===3){box(x-5,y-6,12,11,fur);rect(x,y-5,1,9,B);for(let z=0;z<3;z++){rect(x-8,y-4+z*4,3,1,gold);rect(x+7,y-4+z*4,3,1,gold);}box(x-2,y-9,5,4,B);dot(x-1,y-8,white);dot(x+1,y-8,white);}\r\n if(k===5){poly([[x-6,y],[x-6,y-6],[x-2,y-10],[x+4,y-10],[x+8,y-5],[x+8,y]],fur);for(let z=0;z<4;z++)rect(x-4+z*3,y,1,7-z%2*3,fur);dot(x-1,y-5,ink);dot(x+4,y-5,ink);}\r\n if(k===7){poly([[x-7,y-2],[x-9,y-5],[x-5,y-6],[x-3,y-10],[x,y-7],[x+5,y-10],[x+6,y-6],[x+9,y-3],[x+6,y+4],[x-5,y+4]],fur);box(x-3,y-4,3,3,white);box(x+2,y-4,3,3,white);}\r\n if(k===8){box(x-6,y-10,13,12,fur);box(x-3,y-7,7,3,B);dot(x-2,y-6,white);dot(x+2,y-6,white);box(x-5,y+2,3,4,B);box(x+3,y+2,3,4,B);rect(x,y-14,1,4,gold);gem(x,y-14,H);}\r\n if(k===9){box(x-4,y-5,10,10,'#956e55');rect(x,y-15,2,11,fur);poly([[x,y-10],[x-7,y-15],[x-6,y-8]],fur);poly([[x+2,y-12],[x+8,y-17],[x+8,y-10]],fur);dot(x-1,y-2,white);dot(x+3,y-2,white);}\r\n rect(x-3,y,8,1,gold);gem(x+1,y+1,gold);\r\n if(g===1){poly([[x-5,y-8],[x-5,y-13],[x,y-10],[x+4,y-14],[x+6,y-8]],gold);}\r\n if(g===2){poly([[x-6,y],[x-12,y-6],[x-11,y+4]],H);poly([[x+6,y],[x+12,y-6],[x+11,y+4]],H);}\r\n if(g===3){for(const [xx,yy] of [[x-9,y-10],[x+10,y-8],[x,y-17]])gem(xx,yy,'#88e4d9');rect(x-5,y-7,10,1,'#88e4d9');}\r\n }\r\n\r\n if(equipment)window.GalaWeapons.draw(c,equipment,{x:64,y:10+Math.sin(time/900)*2,scale:.78});\r\n}\r\nwindow.GalaAvatar={sections,dyes,defaultLook,normalize,skinColor,draw};\r\n})();\r\n","pod/gala-coaches/manifest.json":"{\"version\":1,\"ramp\":[78,128,184,238],\"regions\":{\"outline\":0,\"body\":64,\"head\":128,\"eyes\":192},\"sheets\":{\"bodies\":{\"image\":\"bodies.png\",\"mask\":\"bodies-mask.png\",\"frame\":[64,96]},\"pets\":{\"image\":\"pets.png\",\"mask\":\"pets-mask.png\",\"frame\":[48,36]}},\"sprites\":[{\"id\":\"myr5\",\"family\":\"MYR5\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,0,64,96],\"unlock\":\"myr5\"},{\"id\":\"roster/01-seed-pearo--3d_character_model\",\"family\":\"Seed \\u00b7 Pearo\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,0,64,96],\"unlock\":\"roster/01-seed-pearo--3d_character_model\"},{\"id\":\"roster/01-seed-pearo--cute_alien_figure_3d_model\",\"family\":\"Seed \\u00b7 Pearo\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,0,64,96],\"unlock\":\"roster/01-seed-pearo--cute_alien_figure_3d_model\"},{\"id\":\"roster/01-seed-pearo--blank_toy_figure_3d_model\",\"family\":\"Seed \\u00b7 Pearo\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,0,64,96],\"unlock\":\"roster/01-seed-pearo--blank_toy_figure_3d_model\"},{\"id\":\"roster/02-taper-tallstalk--3d_humanoid_figure\",\"family\":\"Taper \\u00b7 Tallstalk\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,0,64,96],\"unlock\":\"roster/02-taper-tallstalk--3d_humanoid_figure\"},{\"id\":\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\"family\":\"Taper \\u00b7 Tallstalk\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,0,64,96],\"unlock\":\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\"},{\"id\":\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",\"family\":\"Taper \\u00b7 Tallstalk\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,0,64,96],\"unlock\":\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\"},{\"id\":\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,0,64,96],\"unlock\":\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\"},{\"id\":\"roster/03-pearl-orb-ring--circle_center\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,96,64,96],\"unlock\":\"roster/03-pearl-orb-ring--circle_center\"},{\"id\":\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,96,64,96],\"unlock\":\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\"},{\"id\":\"roster/03-pearl-orb-ring--robot_3d_model\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,96,64,96],\"unlock\":\"roster/03-pearl-orb-ring--robot_3d_model\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_3d_character1\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,96,64,96],\"unlock\":\"roster/03-pearl-orb-ring--stylized_3d_character1\"},{\"id\":\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"family\":\"Pearl \\u00b7 Orb\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,96,64,96],\"unlock\":\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\"},{\"id\":\"roster/04-crest-wedge--robot_creature_3d_model\",\"family\":\"Crest \\u00b7 Wedge\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,96,64,96],\"unlock\":\"roster/04-crest-wedge--robot_creature_3d_model\"},{\"id\":\"roster/04-crest-wedge--stylized_3d_character\",\"family\":\"Crest \\u00b7 Wedge\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,96,64,96],\"unlock\":\"roster/04-crest-wedge--stylized_3d_character\"},{\"id\":\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\"family\":\"Slope \\u00b7 Bobble\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,96,64,96],\"unlock\":\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\"},{\"id\":\"roster/06-ridge-triad--geometric_robot_3d_model1\",\"family\":\"Ridge \\u00b7 Triad\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,192,64,96],\"unlock\":\"roster/06-ridge-triad--geometric_robot_3d_model1\"},{\"id\":\"roster/06-ridge-triad--robot_3d_model1\",\"family\":\"Ridge \\u00b7 Triad\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,192,64,96],\"unlock\":\"roster/06-ridge-triad--robot_3d_model1\"},{\"id\":\"roster/07-bulb-sphereling--cute_robot_3d_model\",\"family\":\"Bulb \\u00b7 Sphereling\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,192,64,96],\"unlock\":\"roster/07-bulb-sphereling--cute_robot_3d_model\"},{\"id\":\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\"family\":\"Bulb \\u00b7 Sphereling\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,192,64,96],\"unlock\":\"roster/07-bulb-sphereling--humanoid_robot_3d_model\"},{\"id\":\"roster/08-shard-asym--geometric_robot_3d_model\",\"family\":\"Shard \\u00b7 Asym\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,192,64,96],\"unlock\":\"roster/08-shard-asym--geometric_robot_3d_model\"},{\"id\":\"roster/08-shard-asym--robot_3d_model4\",\"family\":\"Shard \\u00b7 Asym\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,192,64,96],\"unlock\":\"roster/08-shard-asym--robot_3d_model4\"},{\"id\":\"roster/08-shard-asym--fantasy_creature_3d_model2\",\"family\":\"Shard \\u00b7 Asym\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,192,64,96],\"unlock\":\"roster/08-shard-asym--fantasy_creature_3d_model2\"},{\"id\":\"roster/08-shard-asym--stylized_action_figure_3d_model\",\"family\":\"Shard \\u00b7 Asym\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,192,64,96],\"unlock\":\"roster/08-shard-asym--stylized_action_figure_3d_model\"},{\"id\":\"roster/09-monolith-tanka--3d_robot_model\",\"family\":\"Monolith \\u00b7 Tanka\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,288,64,96],\"unlock\":\"roster/09-monolith-tanka--3d_robot_model\"},{\"id\":\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\"family\":\"Monolith \\u00b7 Tanka\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,288,64,96],\"unlock\":\"roster/09-monolith-tanka--boxy_humanoid_3d_model\"},{\"id\":\"roster/09-monolith-tanka--mini_robot_3d_model\",\"family\":\"Monolith \\u00b7 Tanka\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,288,64,96],\"unlock\":\"roster/09-monolith-tanka--mini_robot_3d_model\"},{\"id\":\"roster/09-monolith-tanka--robot_3d_model3\",\"family\":\"Monolith \\u00b7 Tanka\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,288,64,96],\"unlock\":\"roster/09-monolith-tanka--robot_3d_model3\"},{\"id\":\"roster/09-monolith-tanka--white_horned_robot_3d_model\",\"family\":\"Monolith \\u00b7 Tanka\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,288,64,96],\"unlock\":\"roster/09-monolith-tanka--white_horned_robot_3d_model\"},{\"id\":\"roster/10-petal-wisp--stylized_creature_3d_model\",\"family\":\"Petal \\u00b7 Wisp\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,288,64,96],\"unlock\":\"roster/10-petal-wisp--stylized_creature_3d_model\"},{\"id\":\"roster/10-petal-wisp--ghost_character_3d_model\",\"family\":\"Petal \\u00b7 Wisp\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,288,64,96],\"unlock\":\"roster/10-petal-wisp--ghost_character_3d_model\"},{\"id\":\"roster/10-petal-wisp--fantasy_creature_3d_model4\",\"family\":\"Petal \\u00b7 Wisp\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,288,64,96],\"unlock\":\"roster/10-petal-wisp--fantasy_creature_3d_model4\"},{\"id\":\"roster/11-anvil-cask--clay-style_robot_3d_model\",\"family\":\"Anvil \\u00b7 Cask\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,384,64,96],\"unlock\":\"roster/11-anvil-cask--clay-style_robot_3d_model\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\"family\":\"Seedpod \\u00b7 Snailslug\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,384,64,96],\"unlock\":\"roster/12-seedpod-snailslug--stylized_slug_3d_model\"},{\"id\":\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\"family\":\"Seedpod \\u00b7 Snailslug\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,384,64,96],\"unlock\":\"roster/12-seedpod-snailslug--stylized_worm_3d_model\"},{\"id\":\"roster/13-fan-split--stylized_3d_character2\",\"family\":\"Fan \\u00b7 Split\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,384,64,96],\"unlock\":\"roster/13-fan-split--stylized_3d_character2\"},{\"id\":\"roster/13-fan-split--stylized_toy_3d_model\",\"family\":\"Fan \\u00b7 Split\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,384,64,96],\"unlock\":\"roster/13-fan-split--stylized_toy_3d_model\"},{\"id\":\"roster/14-chisel-spire--cone_head_3d_model\",\"family\":\"Chisel \\u00b7 Spire\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,384,64,96],\"unlock\":\"roster/14-chisel-spire--cone_head_3d_model\"},{\"id\":\"roster/14-chisel-spire--low_poly_robot_3d_model\",\"family\":\"Chisel \\u00b7 Spire\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,384,64,96],\"unlock\":\"roster/14-chisel-spire--low_poly_robot_3d_model\"},{\"id\":\"roster/15-orbital-coili--robot_character_3d_model\",\"family\":\"Orbital \\u00b7 Coili\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,384,64,96],\"unlock\":\"roster/15-orbital-coili--robot_character_3d_model\"},{\"id\":\"roster/16-spade-arch--pyramid_head_figure_3d_model\",\"family\":\"Spade \\u00b7 Arch\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,480,64,96],\"unlock\":\"roster/16-spade-arch--pyramid_head_figure_3d_model\"},{\"id\":\"roster/16-spade-arch--stylized_humanoid_3d_model\",\"family\":\"Spade \\u00b7 Arch\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,480,64,96],\"unlock\":\"roster/16-spade-arch--stylized_humanoid_3d_model\"},{\"id\":\"roster/17-shellcap-manyarm--3d_character_figurine\",\"family\":\"Shellcap \\u00b7 Manyarm\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,480,64,96],\"unlock\":\"roster/17-shellcap-manyarm--3d_character_figurine\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\"family\":\"Shellcap \\u00b7 Manyarm\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,480,64,96],\"unlock\":\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\"},{\"id\":\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\"family\":\"Shellcap \\u00b7 Manyarm\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,480,64,96],\"unlock\":\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\"},{\"id\":\"roster/19-genie-multi--fantasy_creature_3d_model\",\"family\":\"Genie \\u00b7 Multi\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,480,64,96],\"unlock\":\"roster/19-genie-multi--fantasy_creature_3d_model\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\"family\":\"Genie \\u00b7 Multi\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,480,64,96],\"unlock\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\"},{\"id\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\"family\":\"Genie \\u00b7 Multi\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,480,64,96],\"unlock\":\"roster/19-genie-multi--multi-armed_humanoid_3d_model\"},{\"id\":\"roster/19-genie-multi--stylized_octopus_3d_model\",\"family\":\"Genie \\u00b7 Multi\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,576,64,96],\"unlock\":\"roster/19-genie-multi--stylized_octopus_3d_model\"},{\"id\":\"roster/20-lume--robotic_figure_3d_model\",\"family\":\"Lume\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,576,64,96],\"unlock\":\"roster/20-lume--robotic_figure_3d_model\"},{\"id\":\"roster/21-flyer--winged_humanoid_3d_model\",\"family\":\"Flyer\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[128,576,64,96],\"unlock\":\"roster/21-flyer--winged_humanoid_3d_model\"},{\"id\":\"roster/22-curve--stylized_alien_3d_model\",\"family\":\"Curve\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[192,576,64,96],\"unlock\":\"roster/22-curve--stylized_alien_3d_model\"},{\"id\":\"roster/22-curve--stylized_cartoon_figure_3d_model\",\"family\":\"Curve\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[256,576,64,96],\"unlock\":\"roster/22-curve--stylized_cartoon_figure_3d_model\"},{\"id\":\"roster/23-blob-texture-bodies--blob_creature_3d_model\",\"family\":\"Blob\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[320,576,64,96],\"unlock\":\"roster/23-blob-texture-bodies--blob_creature_3d_model\"},{\"id\":\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",\"family\":\"Blob\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[384,576,64,96],\"unlock\":\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\"},{\"id\":\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"family\":\"Blob\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[448,576,64,96],\"unlock\":\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\"},{\"id\":\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"family\":\"Blob\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[0,672,64,96],\"unlock\":\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\"},{\"id\":\"roster/23-blob-texture-bodies--sand_creature_3d_model\",\"family\":\"Blob\",\"kind\":\"body\",\"sheet\":\"bodies\",\"frame\":[64,672,64,96],\"unlock\":\"roster/23-blob-texture-bodies--sand_creature_3d_model\"},{\"id\":\"roster/18-quad-all--dragon_creature_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[0,0,48,36],\"unlock\":\"roster/18-quad-all--dragon_creature_3d_model\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model1\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[48,0,48,36],\"unlock\":\"roster/18-quad-all--fantasy_creature_3d_model1\"},{\"id\":\"roster/18-quad-all--fantasy_creature_3d_model3\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[96,0,48,36],\"unlock\":\"roster/18-quad-all--fantasy_creature_3d_model3\"},{\"id\":\"roster/18-quad-all--four-legged_robot_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[144,0,48,36],\"unlock\":\"roster/18-quad-all--four-legged_robot_3d_model\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model1\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[192,0,48,36],\"unlock\":\"roster/18-quad-all--quadruped_robot_3d_model1\"},{\"id\":\"roster/18-quad-all--quadruped_robot_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[0,36,48,36],\"unlock\":\"roster/18-quad-all--quadruped_robot_3d_model\"},{\"id\":\"roster/18-quad-all--robotic_dog_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[48,36,48,36],\"unlock\":\"roster/18-quad-all--robotic_dog_3d_model\"},{\"id\":\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[96,36,48,36],\"unlock\":\"roster/18-quad-all--wooden_four-legged_robot_3d_model\"},{\"id\":\"roster/18-quad-all--wooden_robot_3d_model\",\"family\":\"Four-legged\",\"kind\":\"pet\",\"sheet\":\"pets\",\"frame\":[144,36,48,36],\"unlock\":\"roster/18-quad-all--wooden_robot_3d_model\"}]}","pod/gala-performer.js":"/* Cosmetic scenes for the player's saved Gala character. */\r\n(()=>{\r\n 'use strict';\r\n const A=window.GalaAvatar,W=window.GalaWeapons,TAU=Math.PI*2;\r\n const ease=value=>{const t=Math.max(0,Math.min(1,value));return t*t*(3-2*t);};\r\n function playlist(look){\r\n  const scenes=[{name:'idle',duration:6000}];\r\n  if(look.weapon&&W?.unlocked(look.weapon))scenes.push({name:'weapon',duration:4500},{name:'idle',duration:2500});\r\n  if(look.parts.pet)scenes.push({name:'pet',duration:5500},{name:'idle',duration:2500});\r\n  scenes.push({name:'face',duration:5500},{name:'idle',duration:2500},{name:'walk',duration:8000});return scenes;\r\n }\r\n function moment(scenes,time){\r\n  let remaining=Math.max(0,time)%scenes.reduce((sum,scene)=>sum+scene.duration,0);\r\n  for(const scene of scenes){if(remaining<scene.duration)return {...scene,time:remaining,progress:remaining/scene.duration};remaining-=scene.duration;}\r\n }\r\n function create(look,{draw=A.draw,hasPet=false,hasCoachBody=false}={}){\r\n  const body=document.createElement('canvas'),pet=document.createElement('canvas'),weapon=document.createElement('canvas');\r\n  const scenes=playlist(hasPet?{...look,parts:{...look.parts,pet:1}}:look),hasWeapon=scenes.some(scene=>scene.name==='weapon');let specialAt=-Infinity,powerTransform={offset:0,flip:false,zoom:0,gait:0};\r\n  weapon.width=40;weapon.height=72;if(hasWeapon)W.draw(weapon.getContext('2d'),look.weapon);\r\n  draw(pet,look,{base:false,weapon:false,petOnly:true});let lastPose='';\r\n  function paint(canvas,time=0,still=false,motion={}){\r\n   if(canvas.width!==160||canvas.height!==168){canvas.width=160;canvas.height=168;}\r\n   const specialPlaying=hasWeapon&&window.GalaWeaponMotion&&window.performance.now()-specialAt<(window.GalaWeaponMotion.abilityFor(look.weapon)?.animationMs||0);\r\n   const moving=motion.active===true&&motion.phase!=='gone';\r\n   const ctx=canvas.getContext('2d'),scene=still||moving?{name:'idle',time:0,progress:0,duration:6000}:specialPlaying?{name:'weapon',time:0,progress:0,duration:2000}:moment(scenes,time);\r\n   ctx.clearRect(0,0,160,168);ctx.imageSmoothingEnabled=false;canvas.dataset.scene=scene.name;\r\n   const motionPose=motion.pose||'idle',movement=still?'idle':({ 'air-run':'wiggle',bounce:'wiggle',wave:'greet',fall:'look-down','climb-out':'climb',recover:'walk' }[motionPose]||motionPose),active=movement!=='idle'&&movement!=='gone';\r\n   const seconds=scene.time/1000,wave=Math.sin(seconds*TAU*1.15),blink=!still&&(movement==='look-down'||(scene.name==='face'?(seconds>1.5&&seconds<1.68)||(seconds>3.2&&seconds<3.37):(time%4900>4570&&time%4900<4710)));\r\n   const pose={};if(scene.name==='walk'||movement==='walk'||movement==='wiggle'||movement==='climb')pose.walk=movement==='walk'?Math.sin(time/430)*.45:active?Math.sin(time/85)*.8:wave;\r\n   if(scene.name==='pet')pose.petting=wave;\r\n   if(movement==='climb')pose.petting=Math.sin(time/120)*.95;\r\n   if(movement==='greet')pose.greet=Math.sin(time/95);\r\n   if(scene.name==='weapon')pose.weapon=true;\r\n   const poseKey=JSON.stringify([blink,scene.name,movement,Math.round((pose.walk||pose.petting||0)*10),Math.round((pose.greet||0)*10)]);\r\n   if(poseKey!==lastPose){draw(body,look,{base:false,weapon:false,companion:false,prop:scene.name!=='weapon',blink,pose});lastPose=poseKey;}\r\n   let offset=0,flip=false,zoom=0;\r\n   if(scene.name==='walk'){\r\n    if(seconds<2.6){offset=170*ease(seconds/2.6);flip=true;}\r\n    else if(seconds<3.5)offset=170;\r\n    else if(seconds<6.5){offset=170*(1-ease((seconds-3.5)/3));}\r\n   }\r\n   if(scene.name==='face')zoom=ease(Math.min(seconds/.9,(5.5-seconds)/.9));\r\n   const bob=still?0:Math.sin(time/850)*.8;\r\n   if(zoom<1){ctx.globalAlpha=(1-zoom)*.5;ctx.fillStyle='#b69adb';ctx.beginPath();ctx.ellipse(80+offset,153,35,3,0,0,TAU);ctx.fill();ctx.globalAlpha=1;}\r\n   let gait=0;\r\n   if(scene.name==='walk'||movement==='walk'||movement==='wiggle'||movement==='climb'||movement==='look-down'){\r\n    gait=movement==='climb'?Math.sin(time/110)*7:movement==='wiggle'?Math.sin(time/72)*4:movement==='look-down'?Math.sin(time/90)*2:movement==='walk'?Math.sin(time/430)*3:wave*2;\r\n   }\r\n   powerTransform={offset,flip,zoom,gait};\r\n   ctx.save();ctx.translate(offset,0);if(flip){ctx.translate(160,0);ctx.scale(-1,1);}\r\n   if(scene.name==='walk'||movement==='walk'||movement==='wiggle'||movement==='climb'||movement==='look-down'){\r\n    ctx.drawImage(body,0,0,64,70,32,13+bob,96,105);\r\n    ctx.drawImage(body,0,70,32,26,32,118+gait,48,39);\r\n    ctx.drawImage(body,32,70,32,26,80,118-gait,48,39);\r\n   }else ctx.drawImage(body,17*zoom,10*zoom,64-34*zoom,96-66*zoom,32-24*zoom,13-3*zoom+bob,96+48*zoom,144);\r\n   if(hasCoachBody&&['greet','climb','wiggle'].includes(movement))drawCoachArms(ctx,body,movement,time);\r\n   if((look.parts.pet||hasPet)&&zoom<1){\r\n    ctx.globalAlpha=1-zoom;const affection=scene.name==='pet'?Math.max(0,wave)*1.3:0;ctx.drawImage(pet,32,13-affection,96,144);ctx.globalAlpha=1;\r\n    if(scene.name==='pet'){const rise=(seconds%1.25)/1.25,hx=45,hy=113-rise*18;ctx.globalAlpha=Math.sin(rise*Math.PI)*.85;ctx.fillStyle='#ff97c2';ctx.fillRect(hx-3,hy-2,3,3);ctx.fillRect(hx+1,hy-2,3,3);ctx.fillRect(hx-2,hy+1,5,2);ctx.fillRect(hx,hy+3,1,1);ctx.globalAlpha=1;}\r\n   }\r\n   if(motion.phase==='bounce'&&!still){ctx.save();ctx.globalAlpha=.76;ctx.fillStyle='#ead8bb';for(const [x,y] of [[34,151],[43,146],[53,151],[105,151],[116,145],[126,150]])ctx.fillRect(x+(Math.sin(time/70+x)*3|0),y,3,2);ctx.restore();}\r\n   if(hasWeapon&&zoom<1&&window.GalaWeaponMotion){\r\n    const M=window.GalaWeaponMotion,ability=M.abilityFor(look.weapon),special=ability&&window.performance.now()-specialAt<ability.animationMs;\r\n    const attack=scene.name==='weapon',beat=scene.time%1350;\r\n    ctx.save();ctx.globalAlpha=1-zoom;ctx.translate(112,88+bob*2);ctx.rotate(-Math.PI/2);\r\n    M.drawAnimatedWeapon(ctx,look.weapon,{weapons:W,x:0,y:0,scale:.55,now:special?window.performance.now():scene.time,action:special?{startedAt:specialAt,special:true}:attack?{startedAt:scene.time-beat,special:false}:null,reducedMotion:still});ctx.restore();\r\n   }else if(hasWeapon&&zoom<1){\r\n    ctx.globalAlpha=1-zoom;ctx.save();\r\n    if(scene.name==='weapon'){\r\n     const melee=['rapier','greatsword','dagger','spear','trident','scythe'].includes(look.weapon.type),beat=(seconds%1.35)/1.35;\r\n     ctx.translate(115,79);ctx.rotate(Math.sin(beat*TAU)*(melee ? .8 : .09));ctx.drawImage(weapon,-19,-36,38,68);ctx.restore();\r\n     ctx.strokeStyle='#87efff';ctx.lineWidth=2;ctx.globalAlpha=(1-zoom)*Math.sin(beat*Math.PI);\r\n     if(melee){ctx.beginPath();ctx.arc(106,77,30,-1.6,-.15);ctx.stroke();}\r\n     else{ctx.beginPath();ctx.ellipse(116,67,8+beat*16,6+beat*13,0,0,TAU);ctx.stroke();ctx.fillStyle='#d8ffff';ctx.fillRect(122+beat*24,62-beat*24,5,2);}\r\n    }else{ctx.translate(115,78+bob*2);ctx.rotate(-.1);ctx.drawImage(weapon,-16,-31,32,58);ctx.restore();}\r\n    ctx.globalAlpha=1;\r\n   }\r\n   ctx.restore();return scene;\r\n  }\r\n  return {paint,scenes,weapon:hasWeapon?look.weapon:null,get powerTransform(){return {...powerTransform};},get feetFraction(){\r\n   // Saved coach designs have different transparent margins below their feet.\r\n   const context=body.getContext('2d');if(!context.getImageData)return null;\r\n   const pixels=context.getImageData(0,0,body.width,body.height).data;\r\n   for(let y=body.height-1;y>=0;y--)for(let x=0;x<body.width;x++)if(pixels[(y*body.width+x)*4+3]>200)return (13+(y+1)*1.5)/168;\r\n   return null;\r\n  },triggerSpecial(){if(hasWeapon)specialAt=window.performance.now();}};\r\n }\r\n  function drawCoachArms(ctx,body,movement,time){\r\n   // Move the outer limb pixels; center-column crops also include the coach's face and torso.\r\n   const wave=Math.sin(time/170),climb=Math.sin(time/110),sway=Math.sin(time/72),arms=movement==='greet'?\r\n    [{x:48,y:43,w:16,h:29,px:48,py:62,angle:wave*.4}]:\r\n    [{x:0,y:52,w:16,h:25,px:16,py:52,angle:movement==='climb'?.5+climb*.25:sway*.3},\r\n     {x:48,y:52,w:16,h:25,px:48,py:52,angle:movement==='climb'?-.5-climb*.25:-sway*.3}];\r\n  ctx.save();ctx.translate(32,13);ctx.scale(1.5,1.5);\r\n  for(const arm of arms){\r\n    ctx.save();ctx.globalCompositeOperation='destination-out';ctx.fillRect(arm.x,arm.y,arm.w,arm.h);ctx.restore();\r\n    ctx.save();ctx.translate(arm.px,arm.py);ctx.rotate(arm.angle);ctx.drawImage(body,arm.x,arm.y,arm.w,arm.h,arm.x-arm.px,arm.y-arm.py,arm.w,arm.h);ctx.restore();\r\n  }\r\n  ctx.restore();\r\n }\r\n window.GalaPerformance={playlist,moment,create};\r\n})();\r\n","pod/gala-weapons.js":"/* Original modular sci-fi pixel weapons. Stable family IDs preserve saved loadouts. Tier zero plus twenty upgrades per family. */\r\n(()=>{'use strict';\r\nconst types=[['rapier','Plasma blade'],['greatsword','Ion cleaver'],['dagger','Phase dagger'],['sabre','Arc pistol'],['axe','Pulse rifle'],['hammer','Rail cannon'],['mace','Tesla emitter'],['flail','Tether drone'],['spear','Particle lance'],['trident','Tri-beam fork'],['halberd','Rocket pod'],['scythe','Gravity reaper'],['bow','Photon bow'],['crossbow','Gauss rifle'],['chakram','Orbit disc'],['gauntlets','Power gauntlets'],['staff','Gravity rod'],['wand','Sonic disruptor'],['tome','Nanite hive'],['cannon','Plasma cannon']].map(([id,name])=>({id,name}));\r\nconst tiers=['Field','Charged','Calibrated','Overclocked','Cryo-cooled','Twin-core','Ionized','Supercharged','Plasma-fed','Phase-linked','Quantum','Antimatter','Gravitic','Drone-linked','Neural','Singularity','Orbital','Rift-tech','Dark-matter','Starbreaker','MOM’s Impossible'];\r\nconst strength=[1,2,3,4,5,6,8,10,12,15,18,20,23,27,31,35,40,45,50,60,75];\r\nfunction normalize(value){if(!value||!types.some(t=>t.id===value.type)||!Number.isInteger(value.tier)||value.tier<0||value.tier>20)throw Error('This look has an unknown weapon.');return {type:value.type,tier:value.tier};}\r\n// R21: one global player level (player-level.mjs, bundled as MYR5Training); level N unlocks tier N-1 for every weapon.\r\nfunction level(progress=window.GalaProgress?.read()){return globalThis.MYR5Training?.playerLevel(progress)||{level:1,xp:0,floor:0,next:200,into:0,need:200,max:false};}\r\nfunction requirements(value){const w=normalize(value),block=Math.min(4,Math.ceil(w.tier/5));return {level:block,xp:0,strength:strength[w.tier],sets:0,label:w.tier===0?'Starter weapon':['Shallow','Medium','Hard','Expert'][block-1]+' performance · tier '+w.tier};}\r\nfunction unlocked(value){const w=normalize(value);return w.tier===0||(globalThis.MYR5Training?.weaponTierFor?.(w.type)||0)>=w.tier;}\r\nfunction name(value){const w=normalize(value);return tiers[w.tier]+' '+types.find(t=>t.id===w.type).name;}\r\nfunction draw(ctx,value,{x=0,y=0,scale=1,palette=null}={}){\r\n const w=normalize(value),i=types.findIndex(type=>type.id===w.type),t=w.tier;\r\n const ink='#111625',shell=palette?.shell||(t<8?'#59677e':t<16?'#889ab4':'#c4cae3'),dark='#283147',edge='#dbe8ff';\r\n const energy=palette?.energy||['#58e8ff','#76ffc8','#ba8cff','#ff879f','#ffd76c'][Math.min(4,Math.floor(t/5))],white='#f3ffff';\r\n ctx.save();ctx.translate(x,y);ctx.scale(scale,scale);ctx.imageSmoothingEnabled=false;\r\n const r=(x,y,w,h,c)=>{ctx.fillStyle=c;ctx.fillRect(Math.round(x),Math.round(y),Math.round(w),Math.round(h));};\r\n const p=(points,c,line=ink)=>{ctx.beginPath();points.forEach(([x,y],j)=>j?ctx.lineTo(x+.5,y+.5):ctx.moveTo(x+.5,y+.5));ctx.closePath();ctx.fillStyle=c;ctx.fill();if(line){ctx.strokeStyle=line;ctx.lineWidth=1;ctx.stroke();}};\r\n const panel=(x,y,w,h,c=shell)=>{r(x,y,w,h,ink);r(x+1,y+1,w-2,h-2,c);r(x+1,y+1,w-2,1,edge);};\r\n const core=(x,y,size=3)=>{r(x-size-1,y-size-1,size*2+3,size*2+3,ink);r(x-size,y-size,size*2+1,size*2+1,energy);r(x-size+1,y-size+1,Math.max(1,size-1),Math.max(1,size-1),white);};\r\n const vents=(x,y,count=3,vertical=false)=>{for(let k=0;k<count;k++)r(x+(vertical?0:k*3),y+(vertical?k*3:0),vertical?4:1,vertical?1:4,dark);};\r\n const grip=(x=17,y=48,h=14)=>{panel(x,y,7,h,dark);for(let k=3;k<h-2;k+=3)r(x+1,y+k,5,1,shell);r(x+2,y+h-3,3,1,energy);};\r\n const rail=(x=18,y=27,h=38)=>{panel(x,y,5,h,dark);r(x+2,y+2,1,h-5,energy);};\r\n const ring=(cx,cy,rx,ry,col=energy)=>{ctx.beginPath();ctx.ellipse(cx,cy,rx,ry,0,0,Math.PI*2);ctx.strokeStyle=col;ctx.lineWidth=1;ctx.stroke();};\r\n // Detached field stabilizers and an orbital frame arrive at advanced tiers.\r\n if(t>=12){for(const side of [-1,1]){const xx=side<0?2:34;panel(xx,20,4,23,dark);r(xx+1,22,2,6,energy);r(xx+1,34,2,6,energy);}}\r\n if(t>=16){ring(20,33,18,27);r(1,31,3,5,white);r(36,31,3,5,white);}\r\n switch(i){\r\n case 0: // Plasma blade: an emitter and a contained beam, without a metal blade.\r\n  grip();panel(13,42,15,8);core(20,45,2);p([[17,40],[17,14],[20,5],[23,14],[23,40]],energy);r(19,13,2,26,white);panel(15,35,3,7,dark);panel(23,35,3,7,dark);break;\r\n case 1: // Ion cleaver with split rails and a broad energy plane.\r\n  grip(17,53,12);panel(11,46,19,8);panel(9,13,5,35);panel(26,13,5,35);p([[14,44],[14,14],[20,5],[26,14],[26,44]],energy);r(18,14,4,29,white);core(20,49,2);break;\r\n case 2: // A compact phase blade carried in a powered socket.\r\n  grip(16,43,15);panel(12,38,17,7);p([[15,36],[15,27],[20,15],[25,27],[25,36]],energy);r(19,25,2,11,white);panel(12,31,4,8);panel(25,31,4,8);core(20,41,2);break;\r\n case 3: // Arc pistol, visibly horizontal and compact.\r\n  p([[10,33],[22,35],[18,53],[10,53],[13,40]],dark);panel(5,24,29,13);panel(30,22,7,16,dark);r(32,25,3,10,energy);panel(9,20,7,4);core(20,30,3);vents(8,27,3,true);r(15,43,3,6,energy);break;\r\n case 4: // Pulse rifle, vertical storage pose, magazine and forward handguard.\r\n  panel(17,8,6,16,dark);r(18,9,4,3,energy);panel(12,22,15,26);panel(8,27,4,15);vents(14,25,4,true);core(22,34,2);p([[14,47],[24,47],[28,63],[14,65]],shell);panel(24,41,9,13,dark);r(26,43,5,2,energy);break;\r\n case 5: // Rail cannon with open parallel acceleration rails.\r\n  grip(16,52,12);panel(9,35,23,17);panel(7,7,6,34);panel(27,7,6,34);r(13,10,2,29,energy);r(25,10,2,29,energy);r(19,14,2,23,white);for(let yy=15;yy<34;yy+=7){r(13,yy,4,2,energy);r(23,yy,4,2,energy);}core(20,44,4);break;\r\n case 6: // Tesla emitter: coil stack surrounding a live conductor.\r\n  grip(17,49,14);panel(11,37,19,12);rail(18,13,27);for(let yy=15;yy<36;yy+=6){panel(9,yy,23,3);r(10,yy+1,21,1,energy);}core(20,9,3);p([[19,17],[14,24],[20,23],[17,31],[24,22],[20,22]],white,null);break;\r\n case 7: // A tethered attack drone and its remote grip.\r\n  grip(6,47,14);panel(4,40,12,8);core(10,43,2);for(let k=0;k<9;k++)r(11+k,38-k*2,2,2,energy);panel(20,13,13,13);core(26,19,3);panel(14,16,5,8);panel(34,16,5,8);r(21,28,3,4,energy);r(29,28,3,4,energy);break;\r\n case 8: // Particle lance, twin emitter prongs and a narrow beam.\r\n  rail(18,29,38);panel(13,26,15,7);panel(11,16,5,13);panel(25,16,5,13);r(18,6,4,20,energy);r(19,4,2,22,white);core(20,30,2);break;\r\n case 9: // Three separately powered beam emitters.\r\n  rail(18,34,31);panel(8,28,25,8);for(const xx of [8,18,28]){panel(xx,17,5,13);r(xx+1,7-(xx===18?4:0),3,10+(xx===18?4:0),energy);r(xx+2,8,1,16,white);}core(20,32,2);break;\r\n case 10: // Rocket pod: six launch cells with guidance lights.\r\n  panel(7,15,27,31);for(let yy=20;yy<=34;yy+=14)for(let xx=12;xx<=26;xx+=7){panel(xx-2,yy-2,6,10,dark);r(xx,yy,2,4,energy);}panel(13,46,15,7);grip(17,52,11);r(4,23,2,15,energy);break;\r\n case 11: // Gravity reaper bends a field between three suspended pods.\r\n  rail(26,27,37);panel(22,19,13,9);p([[5,12],[18,8],[31,15],[27,19],[17,14],[7,17]],shell);panel(2,20,6,11);r(3,22,4,7,energy);ring(17,27,12,15);core(17,27,4);r(13,26,9,2,white);r(16,23,2,8,white);break;\r\n case 12: // Photon bow: floating emitter limbs and a laser string.\r\n  panel(18,29,8,12);p([[20,27],[25,17],[20,6],[14,7],[20,18],[15,27]],shell);p([[20,42],[25,52],[20,64],[14,63],[20,52],[15,42]],shell);r(13,9,1,53,energy);r(6,34,29,2,white);p([[34,31],[39,35],[34,39]],energy);core(21,34,2);break;\r\n case 13: // Gauss launcher uses sideways capacitors around an acceleration tube.\r\n  grip(17,49,14);panel(15,16,11,33);panel(4,27,10,13);panel(27,27,10,13);r(5,29,8,2,energy);r(28,29,8,2,energy);panel(17,9,7,9,dark);r(19,10,3,6,white);for(let yy=21;yy<43;yy+=6)r(17,yy,7,2,energy);break;\r\n case 14: // Orbit disc, segmented casing with an open energy aperture.\r\n  p([[13,15],[27,15],[35,23],[35,41],[27,49],[13,49],[5,41],[5,23]],shell);p([[15,22],[25,22],[28,27],[28,37],[24,42],[16,42],[12,37],[12,27]],ink);ring(20,32,10,12);for(const [xx,yy] of [[18,15],[31,30],[18,45],[5,30]])r(xx,yy,5,3,energy);core(20,32,2);break;\r\n case 15: // Powered gauntlets with knuckle emitters and battery cuffs.\r\n  for(const xx of [4,23]){panel(xx,27,13,25);for(let k=0;k<3;k++){panel(xx+1+k*4,20,3,10);r(xx+2+k*4,21,1,6,energy);}panel(xx-1,48,15,7,dark);core(xx+6,37,3);r(xx+3,50,7,2,energy);}break;\r\n case 16: // Gravity rod containing a miniature black-hole chamber.\r\n  rail(18,32,34);panel(11,27,19,7);panel(8,12,5,17);panel(28,12,5,17);ring(20,18,8,10);core(20,18,5);r(17,15,7,7,ink);r(18,14,5,1,white);r(14,19,12,1,energy);break;\r\n case 17: // Sonic disruptor with broad dish and expanding pulse rings.\r\n  grip(12,45,16);panel(8,30,17,16);p([[23,32],[30,23],[33,24],[33,45],[30,46],[23,38]],shell);r(30,27,2,15,energy);core(15,36,3);for(let k=0;k<3;k++){r(35+k*2,25+k*3,1,19-k*6,energy);}panel(6,33,3,8,dark);break;\r\n case 18: // Nanite hive replaces the spellbook with a floating drone cluster.\r\n  panel(10,27,21,23);panel(14,22,13,6);core(20,36,5);vents(14,44,4);for(const [xx,yy] of [[7,16],[28,10],[34,24],[5,42],[29,58]]){panel(xx-2,yy-2,5,5);r(xx,yy,1,1,energy);r(xx,yy+4,1,2,energy);}r(17,51,2,6,energy);r(23,51,2,6,energy);break;\r\n case 19: // Plasma cannon with a large chamber and bright muzzle aperture.\r\n  grip(12,43,16);panel(5,23,29,22);panel(29,19,9,29,dark);r(31,22,5,23,energy);r(33,25,2,17,white);core(16,33,6);vents(6,26,4,true);panel(9,17,17,6);r(11,19,13,2,energy);break;\r\n }\r\n // Progressive hardware: charge indicators, cooling fins, extra emitters, then drones.\r\n if(t>0){const rows=1+((t-1)%5);for(let k=0;k<rows;k++){r(15,54-k*3,10,2,ink);r(16,54-k*3,1+Math.min(7,t),1,energy);}}\r\n if(t>=4){panel(7,46,5,10,dark);r(8,48,3,5,energy);r(11,45,5,1,energy);}\r\n if(t>=8){\r\n  const row=types[i].id==='chakram'?19:12;\r\n  p([[8,row],[3,row-7],[3,row+9],[8,row+12]],shell);p([[32,row],[37,row-7],[37,row+9],[32,row+12]],shell);\r\n  r(4,row-3,2,9,energy);r(34,row-3,2,9,energy);\r\n  // Extra family-specific modules amplify the defining shape.\r\n  if([0,1,2,8,9].includes(i)){r(13,11,2,19,energy);r(26,11,2,19,energy);}\r\n  else if([3,4,5,10,13,19].includes(i)){panel(3,51,8,6);panel(29,51,8,6);r(4,53,6,2,energy);r(30,53,6,2,energy);}\r\n  else if([6,11,14,16,17].includes(i)){ring(20,29,14,19,energy);}\r\n  else {for(const xx of [7,32]){core(xx,57,2);r(xx,61,1,4,energy);}}\r\n }\r\n if(t>=13){for(let k=0;k<t-11;k++){const angle=k*Math.PI*2/(t-11);const xx=20+Math.cos(angle)*17,yy=33+Math.sin(angle)*28;r(xx-1,yy-1,3,3,energy);r(xx,yy,1,1,white);}}\r\n if(t===20){\r\n  // The final impossible machine opens a contained portal above the weapon.\r\n  ring(20,7,10,5,white);ring(20,7,7,3,energy);r(17,6,7,2,ink);\r\n  for(const xx of [6,33]){panel(xx-2,61,5,5);r(xx,67,1,3,energy);}r(18,64,5,2,white);r(20,66,1,5,energy);\r\n }\r\n ctx.restore();\r\n}\r\n\r\nwindow.GalaWeapons={types,tiers,normalize,requirements,level,unlocked,name,draw};\r\n})();\r\n","pod/hardware.css":"/* Powder-coated metal, exposed fasteners, and controls with visible travel. */\r\nbody{background:repeating-linear-gradient(90deg,#0000 0 2px,#b89bb403 2px 3px),radial-gradient(ellipse at 50% 15%,#3d2a43,#19141e 64%);max-width:680px}.ship-header{height:62px;border-bottom:3px solid #110d15;background:linear-gradient(#645163,#352b3e 15%,#2a2031 85%,#786476);box-shadow:inset 0 1px #b49eae,0 5px 10px #0005}.ship-location{font-size:8px}.ship-header .icon-button{border:2px solid #857381;background:linear-gradient(130deg,#716073,#2b2331);box-shadow:inset 1px 1px #c5afbd55,3px 4px #130f18;color:#f1d3a2}\r\n.pod-page{padding:0 14px 16px}.deck-strip{height:31px;font-size:9px}.containment-bay{position:relative;padding:15px 18px 8px}.bay-label{position:absolute;top:0;left:38px;font:8px var(--pixel-font);letter-spacing:1px;color:#a994a9}.bay-wires{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;filter:drop-shadow(2px 5px 2px #0009)}\r\n.containment-bay .containment-pod{height:clamp(240px,37dvh,360px);min-height:0;border:13px solid #544352;border-top-width:24px;border-bottom-width:25px;border-radius:25px 25px 18px 18px;background:radial-gradient(ellipse at 50% 76%,#b997b729,transparent 53%),repeating-linear-gradient(90deg,#0000 0 3px,#d7bde203 3px 4px),linear-gradient(130deg,#241d2b,#0e0d14 55%,#302234);box-shadow:inset 0 0 0 3px #141018,inset 2px 3px 6px #000,0 0 0 2px #9b8495,0 0 0 5px #241c2a,3px 8px 0 4px #0e0b12,5px 13px 18px #0009;overflow:visible;isolation:isolate}.containment-bay .containment-pod:before{inset:-11px;border:2px solid #aa92a477;border-radius:18px;box-shadow:inset 0 3px #b29aa233;z-index:5;background:linear-gradient(112deg,transparent 16%,#fff4df0b 17%,transparent 28%);pointer-events:none}.containment-bay .coach-mount{inset:-9px -5px -9px;overflow:hidden;border-radius:10px}.containment-bay .pod-rim{width:9px;top:22px;bottom:22px;background:linear-gradient(90deg,#100e14,#917783,#302738);border-color:#a28a9a77;z-index:6}.containment-bay .rim-left{left:-6px}.containment-bay .rim-right{right:-6px}.containment-bay .pod-rim:before{inset:10px 2px;background:repeating-linear-gradient(0deg,#e5c791 0 6px,#302333 6px 24px);filter:none;border-radius:0}.containment-bay .pod-inscription{top:-20px;font-size:8px;color:#d5c2cd;letter-spacing:3px}.containment-bay .pod-nameplate{bottom:-23px;left:25px;right:25px;height:23px;border:0;background:#211824;box-shadow:inset 0 1px 4px #000;color:#ceb992}.containment-bay .pod-nameplate a{font:9px var(--pixel-font);color:#eccb8f}.containment-bay .pod-floor{display:none}.frame-bolt{position:absolute;width:11px;height:11px;border-radius:50%;background:linear-gradient(130deg,#b6a696,#534644);border:1px solid #302727;box-shadow:1px 2px 2px #000b;z-index:8}.frame-bolt:after{content:'';position:absolute;left:2px;right:2px;top:4px;height:1px;transform:rotate(-35deg);background:#241c21}.frame-bolt.tl{left:-9px;top:-18px}.frame-bolt.tr{right:-9px;top:-18px}.frame-bolt.bl{left:-9px;bottom:-18px}.frame-bolt.br{right:-9px;bottom:-18px}.pod-top-vent{position:absolute;top:-22px;left:32%;right:32%;height:4px;background:repeating-linear-gradient(90deg,#110d17 0 3px,#a08b9633 3px 7px);z-index:7}.camera-preview{width:64px;height:84px;bottom:23px;right:12px}\r\n.coach-line{margin:10px 6px 7px;min-height:45px;padding:8px 13px;background:#15111b;border:1px solid #76607066;box-shadow:inset 2px 3px 6px #0007}.coach-line #coachCaption{font:11px/1.55 var(--pixel-font);color:#dfc89e}.voice-led{flex-shrink:0;background:#e0bb77;border-radius:0;box-shadow:0 0 8px #e8be7644}\r\n.workout-console{position:relative;padding:17px 15px 13px;border:2px solid #796773;border-radius:10px!important;background:repeating-linear-gradient(0deg,#c5abc604 0 1px,#0000 1px 3px),linear-gradient(125deg,#5d4a5b,#382e40 30%,#443545 70%,#645161);box-shadow:inset 0 2px #b09aa3aa,inset 1px 0 #bfaaac44,0 5px #18131e,0 9px 13px #0005}.workout-console:before,.workout-console:after{content:'×';position:absolute;top:8px;color:#282029;font:13px monospace;text-shadow:1px 1px #ab959f}.workout-console:before{left:8px}.workout-console:after{right:8px}\r\n.goal-control label{font:9px var(--pixel-font);letter-spacing:1px;color:#d4bec9}\r\n.goal-control{padding:11px 0 14px;border-top:1px solid #af929744}.goal-control>div:first-child{display:flex;justify-content:space-between;align-items:center;gap:8px}.goal-control output{font:700 14px var(--pixel-font);color:#efcd96}.goal-control input{display:block;appearance:none;width:100%;height:32px;background:transparent;margin:9px 0 1px;padding:0;cursor:pointer;touch-action:pan-y}.goal-control input::-webkit-slider-runnable-track{height:10px;border:2px solid #18121d;border-radius:3px;background:linear-gradient(90deg,#bc9158 0 var(--fill,31%),#1c1723 var(--fill,31%) 100%);box-shadow:0 1px #a28490,inset 0 2px 3px #0007}.goal-control input::-webkit-slider-thumb{appearance:none;width:26px;height:30px;margin-top:-12px;border:2px solid #b49aa3;border-radius:4px;background:repeating-linear-gradient(90deg,#6a5569 0 4px,#392c3e 4px 5px);box-shadow:inset 0 2px #d4bac2,2px 4px 4px #0007}.goal-control input::-moz-range-track{height:8px;background:#1c1723;border:2px solid #18121d}.goal-control input::-moz-range-thumb{width:24px;height:28px;border:2px solid #b49aa3;border-radius:3px;background:#6a5569}.slider-scale{display:flex;justify-content:space-between;font:8px var(--pixel-font);color:#b59aaa}.slider-scale span:nth-child(2){font-size:7px;letter-spacing:.7px}\r\n.workout-console .set-actions{display:grid;grid-template-columns:1fr 59px;gap:11px;min-width:0;align-items:stretch}.workout-console .set-actions .primary-action{display:flex;flex-direction:column;gap:5px;min-height:90px;padding:11px 8px;border:2px solid #dfac70;border-radius:7px;background:linear-gradient(#d9a66e,#b77749 50%,#945232);box-shadow:inset 0 2px #ffe1a9,inset -2px -3px #70422f,0 5px #462b27,0 7px 0 1px #1c1420;color:#221621;text-shadow:0 1px #ffca8677;white-space:normal}.set-actions .primary-action small{font:9px var(--pixel-font);letter-spacing:2px}.set-actions .primary-action strong{font:900 23px var(--pixel-font);letter-spacing:1px}.set-actions .primary-action span{font:7px var(--pixel-font);letter-spacing:.3px}.workout-console .set-actions .primary-action:active:not(:disabled){transform:translateY(4px);box-shadow:inset 1px 3px 6px #66321e88,0 1px #462b27}.workout-console #stop{padding:5px;font:700 10px var(--pixel-font);border:2px solid #8b6773;border-radius:6px;background:linear-gradient(#805768,#432f41);box-shadow:inset 0 1px #d0a0ab77,0 5px #201723;min-width:0}.workout-console #stop:disabled{opacity:.38}.set-track{margin-top:15px;height:5px;border-radius:0;background:#1b1422}.workout-console #status{font:10px/1.5 var(--pixel-font);margin:9px 0 0;min-height:0;color:#d5bece}\r\n.training-paths{gap:10px}.training-paths button{background:linear-gradient(140deg,#534253,#312636);border:2px solid #7d6576;border-radius:5px;box-shadow:inset 0 1px #b798a433,0 4px #1a1321;font-size:12px}.training-paths span{font-size:8px}.crew-footer{margin-top:5px}.settings-note{font:12px/1.5 var(--pixel-font);color:#c8b1c3}.pod-dialog button,.pod-dialog select{box-shadow:inset 0 1px #b99cb23b,2px 3px #140f19;border-width:2px;border-radius:4px}.pod-dialog{background:repeating-linear-gradient(0deg,#c5abc603 0 1px,#0000 1px 3px),linear-gradient(125deg,#403046,#241a31);border:2px solid #9a8095;box-shadow:inset 0 2px #c1a3b14f,8px 12px 40px #000a}\r\n@media(min-width:600px){.pod-page{padding:0 28px 20px}.containment-bay{padding-left:32px;padding-right:32px}.containment-bay .containment-pod{height:350px}.workout-console{padding:20px 28px}.goal-control{padding-top:15px}}\r\n@media(max-width:370px){.pod-page{padding-left:10px;padding-right:10px}.workout-console{padding:15px 10px}}\r\n","pod/hardware.mjs":"import {FOCUS_GROUPS,GROUP_EXERCISES,EXERCISES,exerciseAt,focusFor} from '../exercise-library.mjs';\r\nimport {workoutLevel} from '../workout-levels.mjs';\r\nconst $=id=>document.getElementById(id),clamp=(x,min,max)=>Math.max(min,Math.min(max,x));\r\n// #106 control board: a focus dial, a level knob, an easier/harder lever and a sound switch, all\r\n// driving the same #movement/#goal state the pod already uses. Rotaries sweep 270° (−135° … +135°).\r\nconst SWEEP=270,tick=(kind='dial')=>{try{navigator.vibrate?.(8);}catch{}window.dispatchEvent(new CustomEvent('myr5:hardware-detent',{detail:{kind}}));};\r\nexport const detentAngle=(i,n)=>n>1?-SWEEP/2+SWEEP*i/(n-1):0;\r\n// Relative turn: the detent reached by rotating detent `start` of `n` by `turn` degrees.\r\nexport const detentFor=(start,turn,n)=>clamp(Math.round(start+turn*(n-1)/SWEEP),0,Math.max(0,n-1));\r\n\r\n// Drag to turn (snaps and ticks at each detent), tap the left/right side to step, arrows/Home/End.\r\nfunction rotary(el,{count,value,preview,commit,locked}){\r\n const ticks=el.querySelector('.cb-ticks');let drag=null;\r\n function paint(index,angle=detentAngle(index,count())){\r\n  const n=count();\r\n  if(ticks.childElementCount!==n)ticks.replaceChildren(...Array.from({length:n},(_,i)=>{const b=document.createElement('b');b.style.setProperty('--a',`${detentAngle(i,n)}deg`);return b;}));\r\n  [...ticks.children].forEach((b,i)=>b.toggleAttribute('data-on',i===index));el.style.setProperty('--angle',`${angle}deg`);\r\n }\r\n function set(index){index=clamp(index,0,count()-1);if(locked())return;if(index!==value()){tick();commit(index);}else paint(index);}\r\n const angleOf=e=>{const r=el.getBoundingClientRect();return Math.atan2(e.clientX-r.left-r.width/2,-(e.clientY-r.top-r.height/2))*180/Math.PI;};\r\n el.addEventListener('pointerdown',e=>{if(locked())return;e.preventDefault();el.focus({preventScroll:true,focusVisible:false});el.setPointerCapture(e.pointerId);drag={id:e.pointerId,x:e.clientX,y:e.clientY,last:angleOf(e),turn:0,start:value(),at:value(),moved:false};el.classList.add('is-turning');});\r\n el.addEventListener('pointermove',e=>{\r\n  if(drag?.id!==e.pointerId)return;const a=angleOf(e);let d=a-drag.last;d-=360*Math.round(d/360);drag.last=a;drag.turn+=d;\r\n  if(!drag.moved&&Math.hypot(e.clientX-drag.x,e.clientY-drag.y)<6)return;drag.moved=true;\r\n  const n=count(),at=detentFor(drag.start,drag.turn,n);if(at!==drag.at){drag.at=at;tick();preview(at);}\r\n  paint(at,clamp(detentAngle(drag.start,n)+drag.turn,-SWEEP/2,SWEEP/2));\r\n });\r\n function end(e,cancelled){\r\n  if(drag?.id!==e.pointerId)return;const {moved,at,x}=drag;drag=null;el.classList.remove('is-turning');\r\n  if(cancelled){paint(value());return preview(value());}\r\n  if(moved)return set(at);const r=el.getBoundingClientRect();set(value()+(x<r.left+r.width/2?-1:1));\r\n }\r\n el.addEventListener('pointerup',e=>end(e,false));el.addEventListener('pointercancel',e=>end(e,true));\r\n el.addEventListener('keydown',e=>{\r\n  const step={ArrowLeft:-1,ArrowDown:-1,PageDown:-1,ArrowRight:1,ArrowUp:1,PageUp:1}[e.key];\r\n  if(step){e.preventDefault();set(value()+step);}else if(e.key==='Home'||e.key==='End'){e.preventDefault();set(e.key==='Home'?0:count()-1);}\r\n });\r\n return paint;\r\n}\r\n\r\nexport function initHardware({canUse=()=>true}={}){\r\n const select=$('movement'),goal=$('goal'),dial=$('exerciseDial'),knob=$('difficultySlider'),lever=document.querySelector('.cb-lever');\r\n let group=focusFor(select.value);const remembered=new Map();\r\n const groupIndex=()=>Math.max(0,FOCUS_GROUPS.findIndex(g=>g.id===group));\r\n const levelIndex=()=>Math.max(0,GROUP_EXERCISES[group].findIndex(m=>m.id===select.value));\r\n const levelText=(i,n)=>`${workoutLevel(GROUP_EXERCISES[group][i].id).label} ${i+1}/${n}`;\r\n function selectExercise(id){if(goal.disabled||!canUse(id))return;window.dispatchEvent(new Event('myr5:exercise-selected'));if(id!==select.value){select.value=id;select.dispatchEvent(new Event('change',{bubbles:true}));}sync();}\r\n const locked=()=>goal.disabled;\r\n const paintDial=rotary(dial,{count:()=>FOCUS_GROUPS.length,value:groupIndex,locked,preview:i=>{const next=FOCUS_GROUPS[i];$('exerciseName').textContent=next.name+(GROUP_EXERCISES[next.id].some(m=>canUse(m.id))?'':' · locked');},\r\n  commit:i=>{const next=FOCUS_GROUPS[i].id,preferred=exerciseAt(next,remembered.get(next)??0),exercise=canUse(preferred.id)?preferred:GROUP_EXERCISES[next].find(m=>canUse(m.id));if(exercise)selectExercise(exercise.id);else sync();}});\r\n const paintKnob=rotary(knob,{count:()=>GROUP_EXERCISES[group].length,value:levelIndex,locked:()=>locked()||!canUse(select.value),preview:i=>{$('difficultySetting').textContent=levelText(i,GROUP_EXERCISES[group].length);},\r\n  commit:i=>selectExercise(exerciseAt(group,i).id)});\r\n function sync(){\r\n  group=focusFor(select.value);const choices=GROUP_EXERCISES[group],index=levelIndex(),n=choices.length,focus=FOCUS_GROUPS[groupIndex()];\r\n  remembered.set(group,index);const isLocked=locked(),pathLocked=!canUse(select.value),m=EXERCISES[select.value]??choices[index];\r\n  dial.setAttribute('aria-valuenow',String(groupIndex()));dial.setAttribute('aria-valuemax',String(FOCUS_GROUPS.length-1));dial.setAttribute('aria-valuetext',focus.name);$('exerciseName').textContent=focus.name;\r\n  knob.setAttribute('aria-valuenow',String(index+1));knob.setAttribute('aria-valuemax',String(n));knob.setAttribute('aria-valuetext',`${workoutLevel(m.id).label}, ${m.name}, variation ${index+1} of ${n}`);$('difficultyMax').textContent=n;\r\n  dial.setAttribute('aria-disabled',String(isLocked));knob.setAttribute('aria-disabled',String(isLocked||pathLocked));\r\n  for(const id of ['harder','easier','goalSlider'])$(id).disabled=isLocked||pathLocked;\r\n  paintDial(groupIndex());paintKnob(index);\r\n  $('variationName').textContent=m.name;$('difficultySetting').textContent=levelText(index,n);\r\n  $('variationHint').textContent=pathLocked?'This workout path is locked. Choose it as one of your two paths or earn its coach.':m.hint+' '+workoutLevel(m.id).unlock;$('trackingScope').textContent='Camera estimates; not a form or safety check. '+m.measurement+' · '+m.limits;\r\n  const target=$('goalSlider');target.max=Math.max(0,goal.options.length-1);target.value=goal.selectedIndex;\r\n  const chosen=goal.selectedOptions[0];if(chosen){target.setAttribute('aria-valuetext',chosen.textContent);$('goalSetting').textContent=chosen.textContent;$('goalMin').textContent=goal.options[0].value;$('goalMax').textContent=goal.options[goal.options.length-1].value;target.style.setProperty('--fill',`${100*goal.selectedIndex/Math.max(1,goal.options.length-1)}%`);}\r\n }\r\n // Spring-loaded lever: tap HARDER/EASIER, or throw the handle up/down and let go. Arrow keys work on either end.\r\n const handle=lever.querySelector('i');let pull=null,thrown=-Infinity;\r\n function nudge(step,animate=true){\r\n  if(locked()||!canUse(select.value))return;const n=GROUP_EXERCISES[group].length,next=clamp(levelIndex()+step,0,n-1);\r\n  if(animate&&!matchMedia('(prefers-reduced-motion: reduce)').matches)handle.animate([{transform:'translateY(0)'},{transform:`translateY(${-step*24}px)`},{transform:'translateY(0)'}],{duration:260,easing:'ease-out'});\r\n  if(next!==levelIndex()){tick('lever');selectExercise(exerciseAt(group,next).id);}\r\n }\r\n $('harder').onclick=()=>{if(performance.now()-thrown>400)nudge(1);};$('easier').onclick=()=>{if(performance.now()-thrown>400)nudge(-1);};\r\n lever.addEventListener('pointerdown',e=>{if(!locked())pull={id:e.pointerId,y:e.clientY,held:false};});\r\n lever.addEventListener('pointermove',e=>{\r\n  if(pull?.id!==e.pointerId)return;const dy=clamp(e.clientY-pull.y,-26,26);\r\n  if(!pull.held&&Math.abs(dy)>6){pull.held=true;lever.setPointerCapture(e.pointerId);lever.classList.add('is-pulling');}\r\n  if(pull.held)lever.style.setProperty('--pull',`${dy}px`);\r\n });\r\n function release(e,cancelled){\r\n  if(pull?.id!==e.pointerId)return;const dy=clamp(e.clientY-pull.y,-26,26),held=pull.held;pull=null;\r\n  lever.classList.remove('is-pulling');lever.style.removeProperty('--pull');\r\n  if(held){thrown=performance.now();if(!cancelled&&Math.abs(dy)>=14)nudge(dy<0?1:-1,false);}\r\n }\r\n lever.addEventListener('pointerup',e=>release(e,false));lever.addEventListener('pointercancel',e=>release(e,true));\r\n lever.addEventListener('keydown',e=>{const step={ArrowUp:1,ArrowRight:1,ArrowDown:-1,ArrowLeft:-1}[e.key];if(step){e.preventDefault();nudge(step);}});\r\n // Toggle switch: app.mjs owns the click (voice on/off); the board adds the tick and arrow keys.\r\n const sound=$('toggleVoice');sound.addEventListener('click',()=>tick('switch'));\r\n sound.addEventListener('keydown',e=>{const on={ArrowUp:true,ArrowRight:true,ArrowDown:false,ArrowLeft:false}[e.key];if(on===undefined)return;e.preventDefault();if(!sound.disabled&&(sound.dataset.on==='true')!==on)sound.click();});\r\n $('goalSlider').addEventListener('input',()=>{if(goal.disabled)return;goal.selectedIndex=Number($('goalSlider').value);goal.dispatchEvent(new Event('change',{bubbles:true}));sync();});\r\n select.addEventListener('change',sync);goal.addEventListener('change',sync);window.addEventListener('myr5:movement-configured',sync);window.addEventListener('myr5:performance-progress',sync);window.addEventListener('myr5:account-ready',sync);\r\n const observer=new MutationObserver(sync);observer.observe(goal,{attributes:true,attributeFilter:['disabled'],childList:true});window.addEventListener('pagehide',()=>observer.disconnect());sync();\r\n}\r\n","pod/home-character.css":"/* W2-2M #117: your Gala character stands in the pod's viewing port (#view), over the pixel world. Tap it for the weapon attack. */\r\n.home-character{position:absolute;inset:0;z-index:3;min-width:0;overflow:visible;pointer-events:none}\r\n.home-character[hidden],#hud[hidden]{display:none!important}\r\n.home-character button{position:absolute;inset:0;display:block;width:100%;height:100%;min-height:0;padding:0;border:0;border-radius:0;background:transparent;box-shadow:none;color:#f1e8ff;cursor:pointer;pointer-events:auto;overflow:visible}\r\n.home-character button:focus-visible{outline:3px solid #b4efcf;outline-offset:-4px}\r\n.home-character canvas{position:absolute;left:50%;top:auto;bottom:calc(14% + 9.6px);display:block;min-height:0;width:auto;height:calc(125% - 120px);max-width:none;object-fit:contain;image-rendering:pixelated;filter:drop-shadow(3px 3px #211b31aa);transform:translateX(-50%);transform-origin:50% 50%;z-index:2}\r\n.home-character-platform{position:absolute;z-index:3;left:0;right:0;bottom:0;height:24%;border:2px solid #7b6689;border-bottom:0;background:repeating-linear-gradient(90deg,#bca7bd 0 18px,#86728f 18px 24px,#54465f 24px 30px);box-shadow:inset 0 4px #ead8bb55,inset 0 -5px #211b31,0 -3px 0 #211b31;image-rendering:pixelated;pointer-events:none}\r\n.home-character-platform:before{content:\"\";position:absolute;left:0;right:0;top:-4px;height:3px;background:repeating-linear-gradient(90deg,#ead8bb 0 16px,#ad98aa 16px 22px);border-top:1px solid #fff2d0}\r\n.home-character[data-phase=\"gone\"] .home-character-platform{opacity:.8}\r\n/* The weapon's name stays in the canvas's label and the Avatar dialog (the plate's \"Your avatar\"). */\r\n.home-character [data-weapon]{display:none}\r\n","pod/home-character.mjs":"import {GALA_KEY,loadGala} from './identity.mjs';\r\nimport {drawAnimatedWeapon} from './weapon-animator.mjs';\r\nimport {abilityFor,evolution} from './weapon-evolution.mjs';\r\nimport {createCharacterPhysics} from '../character-phone-physics.mjs';\r\nimport {subscribePhoneMotion} from '../character-phone-sensor.mjs';\r\nimport {createOptionalModuleLoader} from '../arcade/workout-effects-state.mjs';\r\n\r\n// R26: the War Room's coach body/pet (64-bit coach sprites in the saved coach's colours) stands here too. Loaded\r\n// lazily from the War Room bundle so the core app stays small; offline without it the Gala body shows.\r\nconst COACH_SPRITES='/war-room/coach-sprites.js',RECIPE_KEY='myr5-recipe-v1',COACH_CHOICE='myr5-war-room-coaches-v2/';\r\nconst loadPowerState=createOptionalModuleLoader('/arcade/power/avatar-power.mjs');\r\nconst loadPowerRenderer=createOptionalModuleLoader('/arcade/power/power.mjs');\r\nconst loadBlizzardRenderer=createOptionalModuleLoader('/arcade/hold/blizzard.mjs');\r\nexport function mountHomeCharacter(){\r\n const host=document.getElementById('homeCharacter'),canvas=host.querySelector('canvas'),hud=document.getElementById('hud');\r\n const W=window.GalaWeapons,A=window.GalaAvatar,reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n window.GalaWeaponMotion={drawAnimatedWeapon,abilityFor,evolution};\r\n let performer,frame=0,last=0,origin=performance.now(),visible=true,disposed=false,coaches=null,feetFraction=.835;\r\n let powerCanvas=null,powerCtx=null,powerModule=null,powerRenderer=null,blizzardModule=null,powerSchedule=null,powerRecord={version:1,equipped:null,styles:{}},powerOwnerId=null,powerFingerprint='',powerLoading=null,powerLoadToken=0,powerActive=false,powerTime=0,powerPulse=0,lastPowerAt=0,lastReducedPowerAt=0;\r\n const hasPower=()=>!!powerRecord.styles?.[powerRecord.equipped];\r\n function clearPower(){powerActive=false;powerPulse=0;if(powerCtx)powerCtx.clearRect(0,0,160,168);if(powerCanvas)powerCanvas.style.display='none';}\r\n function resizePower(){if(!powerCanvas||!powerCtx)return;const dpr=Math.max(1,Math.min(2,window.devicePixelRatio||1)),width=Math.round(160*dpr),height=Math.round(168*dpr);if(powerCanvas.width!==width)powerCanvas.width=width;if(powerCanvas.height!==height)powerCanvas.height=height;powerCtx.setTransform(dpr,0,0,dpr,0,0);powerCtx.imageSmoothingEnabled=false;}\r\n function makePowerCanvas(){if(powerCanvas)return;powerCanvas=document.createElement('canvas');powerCanvas.className='myr5-home-power-overlay';powerCanvas.width=160;powerCanvas.height=168;powerCanvas.setAttribute('aria-hidden','true');Object.assign(powerCanvas.style,{filter:'none',opacity:'.55',pointerEvents:'none',zIndex:'2',display:'none',bottom:canvas.style.bottom||'',transform:canvas.style.transform||'translateX(-50%)'});const button=host.querySelector('button');if(button?.appendChild)button.appendChild(powerCanvas);else host.append(powerCanvas);powerCtx=powerCanvas.getContext('2d',{alpha:true});if(!powerCtx){powerCanvas.remove();powerCanvas=null;return;}resizePower();}\r\n function ensurePowerRenderer(){if(powerModule&&powerRenderer&&powerSchedule){makePowerCanvas();sync();return;}if(powerLoading)return;const token=++powerLoadToken;powerLoading=Promise.all([loadPowerState(),loadPowerRenderer(),loadBlizzardRenderer()]).then(([avatar,power,blizzard])=>{if(disposed||token!==powerLoadToken||!hasPower())return;powerModule=avatar;powerRenderer=power;blizzardModule=blizzard;powerSchedule=avatar.createAvatarPowerSchedule({seed:0x4d595235});makePowerCanvas();resize();sync();}).catch(()=>{}).finally(()=>{if(token===powerLoadToken)powerLoading=null;});}\r\n function requestPowerSnapshot(){if(typeof CustomEvent==='function')window.dispatchEvent(new CustomEvent('myr5:retained-character-power-request'));}\r\n function paintPower(now,reducedMotion=false){\r\n  if(!powerCtx||!powerModule||!powerSchedule)return;\r\n  const dt=lastPowerAt?Math.max(0,Math.min(.25,(now-lastPowerAt)/1000)):0;lastPowerAt=now;\r\n  const canShow=hasPower()&&visible;\r\n  const active=powerSchedule.step(dt,canShow,reducedMotion);\r\n  if(!active){clearPower();return;}\r\n  powerCanvas.style.display='block';if(!powerActive)powerPulse=1;powerActive=true;\r\n  if(reducedMotion)powerPulse=0;else{powerTime+=dt;powerPulse=Math.max(0,powerPulse-dt*2.5);}\r\n  const transform=performer?.powerTransform||{offset:0,flip:false,zoom:0,gait:0};\r\n  const feetVisible=transform.zoom<.001;\r\n  const anchors=[{index:27,x:.46,y:feetFraction+(transform.gait||0)/168,visible:feetVisible},{index:28,x:.54,y:feetFraction-(transform.gait||0)/168,visible:feetVisible}];\r\n  const state=powerModule.avatarPowerState(powerRecord,160,168,reducedMotion?0:powerTime,reducedMotion?0:powerPulse,false,anchors);\r\n  powerCtx.clearRect(0,0,160,168);\r\n  powerCtx.save();powerCtx.translate(transform.offset||0,0);if(transform.flip){powerCtx.translate(160,0);powerCtx.scale(-1,1);}\r\n  if(state?.blizzard)blizzardModule?.renderBlizzard(powerCtx,state);else if(state)powerRenderer.renderPower(powerCtx,state);\r\n  powerCtx.restore();\r\n }\r\n function acceptPowerRecord(event){const detail=event?.detail;if(!detail||typeof detail.ownerId!=='string')return;const changedOwner=detail.ownerId!==powerOwnerId;powerOwnerId=detail.ownerId;const next=detail.record&&typeof detail.record==='object'?detail.record:{version:1,equipped:null,styles:{}},fingerprint=JSON.stringify(next);if(changedOwner||fingerprint!==powerFingerprint){powerFingerprint=fingerprint;powerLoadToken++;powerLoading=null;powerRecord=next;powerSchedule?.reset();powerTime=0;lastPowerAt=0;clearPower();}if(hasPower()){ensurePowerRenderer();sync();}}\r\n const platform=document.createElement('div');platform.className='home-character-platform';platform.setAttribute('aria-hidden','true');host.append(platform);\r\n const physics=createCharacterPhysics({width:host.clientWidth||320,height:host.clientHeight||220,bodyWidth:canvas.clientWidth||120,bodyHeight:canvas.clientHeight||240,buffer:0,ship:false,climb:false,contain:true});\r\n let motion={gx:0,gy:0,shake:0,angularSpeed:0,timeSeconds:0},unsubscribeMotion=()=>{};\r\n function load(){\r\n  let storage;try{storage=localStorage;}catch{}\r\n  const look=loadGala(storage,A).look,chosen=look.weapon||{type:'rapier',tier:0};\r\n  look.weapon=W.unlocked(chosen)?chosen:{type:chosen.type,tier:0};\r\n  performer=window.GalaPerformance.create(look,coaches?{draw:(canvas,value,options)=>coaches.draw(A.draw,canvas,value,options),hasPet:coaches.hasPet,hasCoachBody:coaches.hasBody}:{});origin=performance.now();\r\n  feetFraction=(coaches?.hasBody||coaches?.hasPet)? .935 : .835;\r\n  host.querySelector('[data-weapon]').textContent=W.name(look.weapon);\r\n  canvas.setAttribute('aria-label',`${look.name||'Your Gala character'} with ${W.name(look.weapon)}`);\r\n  performer.paint(canvas,0,reduced.matches,{pose:physics.state.pose,phase:physics.state.phase,active:physics.state.active});feetFraction=performer.feetFraction||feetFraction;resize();sync();\r\n }\r\n function shown(){return document.body.dataset.tracking!=='true'&&document.body.dataset.screen!=='rest';}\r\n function animate(now){\r\n  frame=0;if(disposed||!shown()||!visible||document.hidden||document.querySelector('dialog[open]'))return;\r\n  if(reduced.matches){if(physics.state.phase!=='idle'||canvas.style.transform!=='translateX(-50%)')resetForReducedMotion();if(now-lastReducedPowerAt>=100){paintPower(now,true);lastReducedPowerAt=now;}if(powerModule&&powerSchedule&&hasPower())frame=requestAnimationFrame(animate);return;}\r\n  if(now-last>32){\r\n   const dt=last?Math.min(.05,(now-last)/1000):1/60;last=now;\r\n   physics.sample(motion,now/1000);physics.step(dt);\r\n   const state=physics.state;\r\n   // CSS uses clockwise positive angles; the domain heading points the feet toward gravity.\r\n   const groundedLean=state.phase==='slide'?(canvas.clientHeight||0)*(feetFraction-.5)*(1-Math.cos(state.angle)):0;\r\n   const transform=`translate(calc(-50% + ${state.x}px),${state.y+groundedLean}px) rotate(${-state.angle}rad)`;canvas.style.transform=transform;if(powerCanvas)powerCanvas.style.transform=transform;\r\n   canvas.dataset.pose=state.pose;canvas.dataset.phase=state.phase;host.dataset.phase=state.phase;host.dataset.phonePhase=state.phase;host.dataset.phoneX=Math.round(state.x);host.dataset.phoneY=Math.round(state.y);\r\n   performer.paint(canvas,now-origin,false,{pose:state.pose,phase:state.phase,active:state.active});paintPower(now,false);\r\n  }\r\n  if(!reduced.matches||(powerModule&&powerSchedule&&hasPower()))frame=requestAnimationFrame(animate);\r\n }\r\n function sync(){\r\n  const show=shown();host.hidden=!show;hud.hidden=show;\r\n  if(!show||!visible||document.hidden){powerSchedule?.step(0,false,reduced.matches);lastPowerAt=0;clearPower();}\r\n  if(frame)cancelAnimationFrame(frame);frame=0;\r\n  if(!disposed&&show&&visible&&!document.hidden)frame=requestAnimationFrame(animate);\r\n }\r\n function listenForMotion(){unsubscribeMotion();unsubscribeMotion=()=>{};if(!disposed&&!reduced.matches)unsubscribeMotion=subscribePhoneMotion(sample=>{motion=sample;if(shown()&&visible&&!document.hidden&&!document.querySelector('dialog[open]'))physics.sample(sample,sample.timeSeconds);});}\r\n function resetForReducedMotion(){\r\n  unsubscribeMotion();unsubscribeMotion=()=>{};physics.reset();motion={gx:0,gy:1,shake:0,angularSpeed:0,timeSeconds:0};last=0;\r\n  canvas.style.transform='translateX(-50%)';canvas.dataset.pose='idle';canvas.dataset.phase='idle';\r\n  host.dataset.phase='idle';host.dataset.phonePhase='idle';host.dataset.phoneX='0';host.dataset.phoneY='0';\r\n   platform.style.transform='';if(powerCanvas)powerCanvas.style.transform=canvas.style.transform;\r\n  performer?.paint(canvas,0,true,{pose:'idle',phase:'idle',active:false});\r\n }\r\n function reducedChanged(){if(reduced.matches)resetForReducedMotion();else listenForMotion();sync();}\r\n function attack(){\r\n  if(!performer?.weapon)return;\r\n  const index=performer.scenes.findIndex(scene=>scene.name==='weapon');\r\n  if(index<0)return;\r\n  origin=performance.now()-performer.scenes.slice(0,index).reduce((sum,scene)=>sum+scene.duration,0);sync();\r\n }\r\n const observer=new MutationObserver(sync);observer.observe(document.body,{subtree:true,attributes:true,attributeFilter:['data-tracking','data-screen','open']});\r\n const intersection=new IntersectionObserver(entries=>{visible=entries[0].isIntersecting;sync();});intersection.observe(host);\r\n const storage=event=>{if(event.key===GALA_KEY||event.key===RECIPE_KEY||event.key?.startsWith(COACH_CHOICE))load();},shownAgain=event=>{if(event.persisted){listenForMotion();load();requestPowerSnapshot();}};\r\n listenForMotion();\r\n const resize=()=>{const width=host.clientWidth||320,height=host.clientHeight||220,bodyWidth=canvas.clientWidth||120,bodyHeight=canvas.clientHeight||240,bottom=height*.24-bodyHeight*(1-feetFraction);canvas.style.bottom=`${bottom}px`;if(powerCanvas){powerCanvas.style.bottom=`${bottom}px`;resizePower();}physics.setRestCenter(width/2,height-bottom-bodyHeight/2);physics.resize(width,height,bodyWidth,bodyHeight);};\r\n const layoutObserver=typeof ResizeObserver==='function'?new ResizeObserver(resize):null;\r\n layoutObserver?.observe(host);layoutObserver?.observe(canvas);\r\n resize();window.addEventListener('resize',resize);\r\n window.addEventListener('mominc-avatar-change',load);window.addEventListener('myr5:recipe',load);window.addEventListener('pageshow',shownAgain);window.addEventListener('myr5:account-progress',load);window.addEventListener('storage',storage);\r\n document.addEventListener('visibilitychange',sync);reduced.addEventListener('change',reducedChanged);window.addEventListener('myr5:retained-character-power',acceptPowerRecord);\r\n const entry=host.querySelector('button');entry.setAttribute('aria-label','Open your War Room base');\r\n entry.addEventListener('click',()=>{if(window.myr5Routes?.go)window.myr5Routes.go('world');else location.href='/pose.html#world';});\r\n load();requestPowerSnapshot();\r\n import(COACH_SPRITES).then(m=>m.loadWarRoomCoaches(document)).then(value=>{if(!disposed){coaches=value;load();}}).catch(()=>{});\r\n  window.addEventListener('pagehide',event=>{if(event.persisted){unsubscribeMotion();powerSchedule?.step(0,false,reduced.matches);lastPowerAt=0;clearPower();return;}disposed=true;powerLoadToken++;powerSchedule?.dispose();powerCanvas?.remove();powerCanvas=null;powerCtx=null;unsubscribeMotion();sync();observer.disconnect();intersection.disconnect();layoutObserver?.disconnect();window.removeEventListener('resize',resize);window.removeEventListener('mominc-avatar-change',load);window.removeEventListener('myr5:recipe',load);window.removeEventListener('pageshow',shownAgain);window.removeEventListener('myr5:account-progress',load);window.removeEventListener('storage',storage);window.removeEventListener('myr5:retained-character-power',acceptPowerRecord);document.removeEventListener('visibilitychange',sync);reduced.removeEventListener('change',reducedChanged);}); // a bfcache hide keeps it alive for pageshow\r\n}\r\n","pod/identity.mjs":"export const GALA_KEY='mominc-avatar-v1';\r\nexport const LIVE_GALA='https://mominc.online/gala/';\r\nexport function loadGala(storage,avatar){\r\n try{const raw=storage.getItem(GALA_KEY);if(raw)return {look:avatar.normalize(JSON.parse(raw)),linked:true};}catch{}\r\n return {look:structuredClone(avatar.defaultLook),linked:false};\r\n}\r\nexport function importGala(text,avatar){if(typeof text!=='string'||new TextEncoder().encode(text).length>30000)throw Error('Choose a Gala look file smaller than 30 KB.');return avatar.normalize(JSON.parse(text));}\r\nexport const POWERS={shield:{name:'Shield',line:'The shield holds.'},ember:{name:'Ember',line:'The ember field holds.'},arc:{name:'Arc',line:'The arc field holds.'},frost:{name:'Frost',line:'The frost field holds.'}};\r\nexport function loadPower(storage){try{const p=storage.getItem('myr5-pod-power-v1');if(POWERS[p])return p;}catch{}return 'shield';}\r\n","pod/performance-workout.mjs":"import {EXERCISES} from '../exercise-library.mjs';\r\nimport {holdXp,repXp,HOLD_TARGET_SECONDS,HOLD_CAP_SECONDS,HOLD_RECOVERY_SECONDS,WORKOUT_REST_SECONDS,REP_CAP,PREPARATION_REPS,SECOND_PREPARATION_TEMPO_SECONDS,SPRINT_ROUNDS,SPRINT_SECONDS,SPRINT_REST_SECONDS,HOLD_BLOCK_SECONDS,SPRINT_ROUND_XP,GENTLE_BLOCK_XP,clampBonusXp,XP_SCALE} from '../progression-rules.mjs';\r\n\r\nexport function exerciseDifficulty(mode){\r\n const exercise=EXERCISES[mode];if(!exercise)return 'easy';\r\n const rows=Object.values(EXERCISES).filter(row=>row.group===exercise.group&&row.kind===exercise.kind);\r\n const index=rows.findIndex(row=>row.id===mode);\r\n return ['easy','medium','hard','expert'][Math.min(3,Math.floor(Math.max(0,index)*4/Math.max(1,rows.length)))];\r\n}\r\nexport function preparationVariants(mode){\r\n const chosen=EXERCISES[mode],rows=Object.values(EXERCISES).filter(row=>row.group===chosen?.group&&row.kind==='reps');\r\n const index=rows.findIndex(row=>row.id===mode);\r\n return {easy:rows[Math.max(0,index-1)]??chosen,hard:rows[Math.min(rows.length-1,index+1)]??chosen};\r\n}\r\nconst number=value=>Math.max(0,Number(value)||0);\r\n/** One persisted workout contains preparations and one working set. Only the\r\n * working result is eligible for history/XP. Raw tracker counts are monotonic;\r\n * baselines exclude everything performed during a preparation or recovery. */\r\nexport class PerformanceWorkout {\r\n constructor({mode,kind,difficulty=exerciseDifficulty(mode),cardio='gentle',snapshot=null}={}){\r\n  // Cool Cardio (the runner) is endless gentle cardio: no sprint rounds, no 600 s finish; it ends on stop or when Coach catches you.\r\n  this.mode=mode;this.endless=!!EXERCISES[mode]?.endless;this.kind=kind==='hold'?'hold':kind==='reps'?'reps':cardio==='sprint'&&!this.endless?'sprint':'gentle';this.difficulty=difficulty;\r\n  this.stage=this.kind==='reps'?'preparation-easy':'working';this.raw=0;this.baseline=0;this.value=0;this.activeSeconds=0;this.continuousSeconds=0;this.maxContinuousSeconds=0;this.xpBase=0;this.recoveryUntil=0;this.paused=false;this.finished=false;this.round=1;this.sprintSeconds=0;this.lastNow=null;this.lastMovementNow=-Infinity;this.lastPreparationRepAt=null;this.slowAccepted=0;this.perDifficultyContinuous={};this.lastCameraHold=0;this.continuousRawOffset=0;this.holdBlocks=[];this.notice='';this.noticeUntil=0;\r\n  if(snapshot&&snapshot.mode===mode)Object.assign(this,snapshot,{finished:false,continuousSeconds:0,lastNow:null,lastCameraHold:0,continuousRawOffset:0});\r\n  if(snapshot?.activeSeconds>=HOLD_BLOCK_SECONDS&&!Array.isArray(snapshot.holdBlocks))this.holdBlocks=null;\r\n  if(!Object.keys(this.perDifficultyContinuous).length&&this.maxContinuousSeconds>0)this.perDifficultyContinuous[this.difficulty]=this.maxContinuousSeconds;\r\n }\r\n snapshot(){return Object.fromEntries(Object.entries(this).filter(([key])=>!['lastNow','lastMovementNow'].includes(key)));}\r\n get counting(){return !this.finished&&!this.paused&&this.stage!=='preparation-rest'&&this.stage!=='sprint-rest';}\r\n get instruction(){\r\n  if(this.notice&&Date.now()<this.noticeUntil)return this.notice;\r\n  const variants=preparationVariants(this.mode);\r\n  if(this.paused)return 'Shake out and recover. Resume whenever ready; recovery adds no XP.';\r\n  if(this.stage==='preparation-easy')return `Warm up: ${PREPARATION_REPS} ${variants.easy?.name??this.mode}, full comfortable range. Good job, superstar. No XP for preparation.`;\r\n  if(this.stage==='preparation-slow')return `Slow preparation: ${PREPARATION_REPS} ${variants.hard?.name??this.mode}. Take ${SECOND_PREPARATION_TEMPO_SECONDS} seconds for each full movement. No XP for preparation.`;\r\n  if(this.stage==='preparation-rest')return 'Recover for 30 seconds. Preparation does not count toward training history.';\r\n  if(this.stage==='sprint-rest')return `Round ${this.round}/${SPRINT_ROUNDS}: recover for 45 seconds.`;\r\n  if(this.kind==='sprint')return `Round ${this.round}/${SPRINT_ROUNDS}: sprint for 15 seconds. Warm up first.`;\r\n  if(this.kind==='reps')return this.value>=REP_CAP?'Please stop. Thirty reps is the counting limit.':'Working set: aim for 8–12 controlled reps. Finish when you choose.';\r\n  return this.activeSeconds>=HOLD_CAP_SECONDS?'Please stop. Thirty active minutes is the XP limit.':this.kind==='hold'?'Hold: active time counts up. Break whenever needed. Ten uninterrupted minutes earns gold.':'Gentle cardio: active movement earns XP; rest does not.';\r\n }\r\n breakHold(now=Date.now()){if(this.kind!=='hold'||this.finished)return;this.paused=true;this.continuousSeconds=0;this.recoveryUntil=now+HOLD_RECOVERY_SECONDS*1000;}\r\n resumeHold(){this.paused=false;this.continuousSeconds=0;this.recoveryUntil=0;}\r\n extendRecovery(seconds=15,now=Date.now()){this.recoveryUntil=Math.max(now,this.recoveryUntil)+seconds*1000;}\r\n advancePreparationRecovery(now=Date.now()){\r\n  if(this.stage!=='preparation-rest'||now<this.recoveryUntil)return false;\r\n  this.stage=this.nextStage;this.value=0;this.baseline=this.raw;this.lastPreparationRepAt=now;this.lastNow=null;return true;\r\n }\r\n rebaseTracking(){this.raw=0;this.baseline=0;this.value=0;this.lastNow=null;this.lastMovementNow=-Infinity;}\r\n switchDifficulty(difficulty){if(!['easy','medium','hard','expert'].includes(difficulty))throw Error('Unknown exercise difficulty.');if(difficulty===this.difficulty)return;if(this.kind!=='hold')throw Error('Choose repetition difficulty before the working set.');this.perDifficultyContinuous[this.difficulty]=Math.max(this.perDifficultyContinuous[this.difficulty]||0,this.maxContinuousSeconds);this.difficulty=difficulty;this.continuousSeconds=0;this.maxContinuousSeconds=0;this.continuousRawOffset=this.lastCameraHold;}\r\n update(m,now=Date.now()){\r\n  if(this.finished)return null;\r\n  const raw=number(this.kind==='hold'?m.totalHold:this.kind==='reps'?m.count:m.manual?m.elapsed:['steps','jumps','reps'].includes(m.kind)?m.count:m.active);\r\n  const delta=Math.max(0,raw-this.raw),elapsed=this.lastNow===null?0:Math.max(0,Math.min(1,(now-this.lastNow)/1000));this.raw=raw;this.lastNow=now;if(delta>0)this.lastMovementNow=now;const moving=m.manual?!this.paused:now-this.lastMovementNow<=1250;\r\n  if(this.stage==='preparation-rest'){\r\n   this.baseline=raw;this.advancePreparationRecovery(now);return null;\r\n  }\r\n  if(this.kind==='reps'){\r\n   this.value=Math.min(REP_CAP,Math.max(0,raw-this.baseline));\r\n   if(this.stage.startsWith('preparation-')){\r\n    if(this.stage==='preparation-slow'){if(raw>this.baseline){if(now-(this.lastPreparationRepAt??now)>=SECOND_PREPARATION_TEMPO_SECONDS*1000){this.slowAccepted++;this.lastPreparationRepAt=now;}this.baseline=raw;}this.value=this.slowAccepted;}\r\n    if(this.value>=PREPARATION_REPS){this.nextStage=this.stage==='preparation-easy'?'preparation-slow':'working';this.stage='preparation-rest';this.recoveryUntil=now+WORKOUT_REST_SECONDS*1000;this.value=0;this.baseline=raw;}\r\n    return null;\r\n   }\r\n   this.xpBase=repXp({difficulty:this.difficulty,to:Math.floor(this.value)});\r\n   if(this.value>=REP_CAP)return this.finish();return null;\r\n  }\r\n  if(this.kind==='hold'){\r\n   const wasHolding=this.continuousSeconds>0,cameraHold=number(m.hold);if(!m.manual&&cameraHold<this.lastCameraHold){this.continuousRawOffset=0;this.continuousSeconds=0;}this.lastCameraHold=cameraHold;const cameraContinuous=m.manual?null:Math.max(0,cameraHold-this.continuousRawOffset);\r\n   if(!m.manual&&cameraContinuous===0&&wasHolding)this.breakHold(now);\r\n   if(!m.manual&&this.paused&&cameraContinuous>0)this.resumeHold();\r\n   if(this.paused)return null;\r\n   const before=this.activeSeconds,continuousBefore=this.continuousSeconds;\r\n   this.activeSeconds=Math.min(HOLD_CAP_SECONDS,before+delta);\r\n   this.continuousSeconds=m.manual?continuousBefore+delta:cameraContinuous;\r\n   this.maxContinuousSeconds=Math.max(this.maxContinuousSeconds,this.continuousSeconds);\r\n   this.perDifficultyContinuous[this.difficulty]=Math.max(this.perDifficultyContinuous[this.difficulty]||0,this.continuousSeconds);\r\n   if(Array.isArray(this.holdBlocks))for(let block=Math.floor(before/HOLD_BLOCK_SECONDS);block<Math.floor(this.activeSeconds/HOLD_BLOCK_SECONDS);block++){const activeStart=block*HOLD_BLOCK_SECONDS;this.holdBlocks.push({difficulty:this.difficulty,activeStart,continuousStart:Math.max(0,continuousBefore+activeStart-before)});}\r\n   this.xpBase+=holdXp({difficulty:this.difficulty,from:before,to:this.activeSeconds,continuousAtFrom:continuousBefore});this.value=this.activeSeconds;\r\n   if(this.activeSeconds>=HOLD_CAP_SECONDS)return this.finish();return null;\r\n  }\r\n  if(this.kind==='sprint'){\r\n   if(this.stage==='sprint-rest'){\r\n    if(now>=this.recoveryUntil){if(this.round>=SPRINT_ROUNDS)return this.finish();this.round++;this.sprintSeconds=0;this.stage='working';}return null;\r\n   }\r\n   // Movement must be observed. An unattended wall-clock cannot award a sprint.\r\n   this.sprintSeconds+=moving?elapsed:0;this.activeSeconds+=moving?elapsed:0;this.value=this.activeSeconds;\r\n   if(this.sprintSeconds>=SPRINT_SECONDS){this.stage='sprint-rest';this.recoveryUntil=now+SPRINT_REST_SECONDS*1000;this.xpBase+=SPRINT_ROUND_XP;}\r\n   return null;\r\n  }\r\n  this.activeSeconds+=moving?elapsed:0;this.value=this.activeSeconds;this.xpBase=Math.floor(this.activeSeconds/15)*GENTLE_BLOCK_XP;if(!this.endless&&this.activeSeconds>=HOLD_TARGET_SECONDS)return this.finish();return null;\r\n }\r\n finish(){\r\n  if(this.finished||this.stage.startsWith('preparation-')||this.xpBase<=0||this.kind==='reps'&&this.value<1||this.kind!=='reps'&&this.activeSeconds<15){\r\n   // Refusals are shown via `instruction` for 4 s so a tap on Finish never fails silently.\r\n   if(!this.finished){this.notice=this.stage.startsWith('preparation-')?'Finish the preparation set first.':this.kind==='reps'?'Do at least one rep before finishing the set.':this.kind!=='reps'&&this.activeSeconds<15?'Keep moving: 15 active seconds are needed before this set can be saved.':'Nothing to save yet.';this.noticeUntil=Date.now()+4000;}\r\n   return null;\r\n  }\r\n  this.finished=true;const bonusXp=clampBonusXp(this.bonusXp,this.xpBase);return {mode:this.mode,kind:this.kind,difficulty:this.difficulty,value:this.value,activeSeconds:this.activeSeconds,maxContinuousSeconds:this.maxContinuousSeconds,perDifficultyContinuous:{...this.perDifficultyContinuous},...(this.kind==='hold'&&Array.isArray(this.holdBlocks)?{holdBlocks:this.holdBlocks.map(block=>({...block}))}:{}),xpBase:this.xpBase+bonusXp,xpScale:XP_SCALE,...(bonusXp>0?{bonusXp}:{}),earned:this.xpBase>0,preparation:false,working:true,rounds:this.kind==='sprint'?Math.min(SPRINT_ROUNDS,this.round):0};\r\n }\r\n}\r\n","pod/persistent-chrome.css":".pod-persistent-chrome{position:fixed;inset:max(7px,env(safe-area-inset-top)) 18px auto;z-index:2147483000;display:flex;justify-content:space-between;align-items:start;gap:12px;pointer-events:none;height:46px}\r\n.pod-persistent-chrome>button{pointer-events:auto!important;margin:0!important;position:relative!important;inset:auto!important;min-height:42px;max-width:45%;border-radius:4px;font:700 10px/1.2 monospace;letter-spacing:.1em;cursor:pointer}\r\n.pod-persistent-chrome .metal-grimoire-key{padding:10px 16px;color:#28231f!important;border:1px solid #514b41!important;background:linear-gradient(145deg,#bbb7a8,#80796b 48%,#b5ad99)!important;text-shadow:0 1px #e9e3ce;box-shadow:inset 0 1px #e8e3d0,inset 0 -3px #4c463d,0 3px 4px #0008!important}\r\n.pod-persistent-chrome .metal-grimoire-key:before,.pod-persistent-chrome .metal-grimoire-key:after{content:'+';position:absolute;top:4px;color:#514b41;font:9px monospace}.metal-grimoire-key:before{left:4px}.metal-grimoire-key:after{right:4px}\r\n.pod-now-playing{display:grid;gap:3px;padding:6px 9px;color:#ffb568;border:3px ridge #857563;background:repeating-linear-gradient(0deg,#24170f 0 2px,#170e09 2px 4px);text-align:left;box-shadow:inset 0 0 12px #000,0 2px 4px #0009;text-shadow:0 0 6px #ff8b37}\r\n.pod-now-playing small{font-size:8px;color:#cb8c56}.pod-now-playing span{display:block;max-width:135px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.has-pod-chrome>.ach-head{top:65px}.has-pod-chrome>.ach-close{top:65px}.has-pod-chrome>.ach-detail{padding-bottom:calc(24px + var(--myr5-bar,64px) + env(safe-area-inset-bottom))}\r\n.has-pod-chrome>header,.has-pod-chrome>.pass-header{margin-top:50px}\r\n.pod-header-actions{display:none!important}.deck-strip>span{display:none!important}.deck-strip{justify-content:flex-end!important}.containment-pod .coach-line{visibility:hidden}\r\n@media(max-width:480px){.pod-persistent-chrome{left:13px;right:13px}.pod-persistent-chrome .metal-grimoire-key{padding:10px}.pod-now-playing span{max-width:112px}}\r\n\r\n/* The stamped image is the brand. The small route caption and a second wordmark crowded the cockpit. */\r\n.ship-header .mom-brand>span,.ship-header .ship-location{display:none!important}\r\n.ship-header .mom-brand{gap:0;flex:none}.ship-header .mom-brand img{width:43px;height:43px;object-fit:contain;filter:drop-shadow(0 0 8px #e3a9f866)}\r\n.ship-header #openSettings.ship-settings-toggle{box-sizing:border-box;display:grid;grid-template-columns:27px minmax(0,1fr);align-items:center;gap:7px;width:132px;min-width:132px;min-height:48px;margin-left:auto;padding:5px 7px;border:2px solid #b5a0a3;border-top-color:#e4d4c8;border-bottom-color:#62545c;border-radius:5px;background:linear-gradient(135deg,#756d70,#38343d);box-shadow:inset 0 1px #fff8,inset 0 -3px #161a23,0 3px 0 #1b1720,0 5px 8px #0008;color:#c8fbd7;text-align:left;cursor:pointer}\r\n.ship-settings-handle{position:relative;display:block;width:25px;height:33px;border:2px solid #1b2226;border-radius:4px;background:linear-gradient(90deg,#191f25,#3b464d);box-shadow:inset 1px 2px 5px #000a,0 1px #c6b8af}\r\n.ship-settings-handle:before{content:'';position:absolute;left:3px;top:4px;width:15px;height:12px;border:1px solid #eee1cb;border-radius:2px;background:repeating-linear-gradient(90deg,#d4c8b7 0 3px,#918880 3px 4px);box-shadow:0 2px 2px #0009;transition:translate .12s}\r\n.ship-settings-screen{position:relative;display:grid;align-content:center;gap:2px;min-width:0;height:32px;padding:0 5px;border:2px inset #777569;border-radius:3px;background:repeating-linear-gradient(0deg,#1b382a 0 2px,#102719 2px 4px);box-shadow:inset 1px 2px 6px #000b,0 0 7px #89e8a837;color:#b7ffce;text-shadow:0 0 5px #65eb95;font:700 9px/1.1 ui-monospace,Consolas,monospace;letter-spacing:.09em;overflow:hidden}\r\n.ship-settings-screen small{font-size:6px;color:#82b995}.ship-settings-screen strong{font-size:9px}\r\n.ship-header #openSettings.ship-settings-toggle[aria-expanded=true] .ship-settings-handle:before{translate:0 10px;background:repeating-linear-gradient(90deg,#f6d19a 0 3px,#b98e5b 3px 4px)}\r\n.ship-header #openSettings.ship-settings-toggle[aria-expanded=true] .ship-settings-screen{color:#ffe7b6;text-shadow:0 0 6px #ffc66a;background:repeating-linear-gradient(0deg,#453322 0 2px,#2a211a 2px 4px)}\r\n.ship-header #openSettings.ship-settings-toggle:focus-visible{outline:3px solid #ffe49b;outline-offset:3px}\r\n.ship-header .pod-tilt-request{box-sizing:border-box;min-height:40px;padding:5px 9px;border:2px solid #aaa3a1;border-top-color:#e2d9c6;border-bottom-color:#615d62;border-radius:4px;background:linear-gradient(#6f7775,#414b4b);box-shadow:inset 0 1px #fff7,0 3px #222b30;color:#eaf4da;font:700 9px ui-monospace,Consolas,monospace;letter-spacing:.04em;text-shadow:0 1px #1d2b2a}\r\n/* The floating grimoire and DJ terminals sit below the header plate while the pod is in view. */\r\nbody>.pod-persistent-chrome,#portalWorkoutHome>.pod-persistent-chrome{top:calc(78px + env(safe-area-inset-top));left:18px;right:18px}\r\n@media(max-height:720px) and (orientation:portrait){body>.pod-persistent-chrome,#portalWorkoutHome>.pod-persistent-chrome{top:calc(66px + env(safe-area-inset-top))}}\r\n@media(max-width:480px){.ship-header #openSettings.ship-settings-toggle{width:119px;min-width:119px}.ship-settings-screen{padding:0 3px}body>.pod-persistent-chrome,#portalWorkoutHome>.pod-persistent-chrome{left:13px;right:13px}}\r\n\r\n/* Physical dock controls are available before the portal scene loads. */\r\n#coachDock.coach-dock.ship-control-deck{border-top:3px solid #b8a890;background:radial-gradient(circle at 12px 9px,#d4c3a9 0 2px,#292832 3px 5px,transparent 6px),radial-gradient(circle at calc(100% - 12px) 9px,#d4c3a9 0 2px,#292832 3px 5px,transparent 6px),repeating-linear-gradient(90deg,#ffffff08 0 1px,transparent 1px 5px),linear-gradient(180deg,#48545a,#252f38 38%,#171e27);box-shadow:inset 0 2px #e5d8bd72,inset 0 7px 8px #1117229c,0 -4px 18px #070b11a8}\r\n#coachDock.coach-dock.ship-control-deck:after{content:'';position:absolute;left:8px;right:8px;top:9px;height:1px;background:linear-gradient(90deg,transparent,#d5c9ad80 15%,#d5c9ad80 85%,transparent);pointer-events:none}\r\n#coachDock.coach-dock.ship-control-deck button.dock-control{filter:none;overflow:visible}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span{position:relative;box-sizing:border-box;width:35px;height:35px;border:2px solid #c6b9a0;border-top-color:#f1e3c7;border-bottom-color:#665e56;border-radius:4px;clip-path:none;background:linear-gradient(145deg,#bcc8c2,#81918f 43%,#4b5c60);box-shadow:inset 0 1px #fff9,inset -2px -3px #22343b88,0 3px 0 #182127,0 5px 5px #000a;color:#243640}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span:after{content:'';position:absolute;right:2px;top:2px;width:4px;height:4px;border-radius:50%;background:#263d40;box-shadow:0 0 0 1px #e5e1cb77}\r\n#coachDock.coach-dock.ship-control-deck .dock-control[aria-current=page]>span:after{background:#ffd07c;box-shadow:0 0 6px #ffce78,0 0 0 1px #ffeed3}\r\n#coachDock.coach-dock.ship-control-deck .dock-control>span svg{width:21px;height:21px;filter:drop-shadow(0 1px #f2ffed77)}\r\n#coachDock.coach-dock.ship-control-deck .dock-control:active>span,#coachDock.coach-dock.ship-control-deck .dock-control[aria-current=page]>span{transform:translateY(3px);box-shadow:inset 1px 3px 4px #1e2d34ad,0 1px 0 #182127;color:#17282a}\r\n#coachDock.coach-dock.ship-control-deck .dock-control:focus-visible{outline:3px solid #ffe19a;outline-offset:2px}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings>span{border-radius:50%;background:radial-gradient(circle,#d6ddcf 0 24%,#8fa69e 25% 49%,#526d70 50% 67%,#b4bfb6 69%);box-shadow:inset 0 1px #fff9,0 3px #29363a,0 0 0 2px #132128}\r\n#coachDock.coach-dock.ship-control-deck .dock-scoreboard>span{border-radius:5px 5px 10px 10px;background:linear-gradient(90deg,#596b72 0 20%,#becac3 22% 72%,#596b72 75%);}\r\n#coachDock.coach-dock.ship-control-deck .dock-food>span{height:31px;border-radius:3px 3px 9px 9px;background:linear-gradient(#ffe0a9,#c69458 48%,#845837);color:#493322}\r\n#coachDock.coach-dock.ship-control-deck .dock-achievements>span{border-radius:3px;clip-path:polygon(0 0,100% 0,100% 71%,50% 100%,0 71%);background:linear-gradient(140deg,#ffe8ac,#b98b44 67%,#765223);color:#533e25}\r\n#coachDock.coach-dock.ship-control-deck .dock-pod>span{width:29px;border-radius:12px;background:linear-gradient(90deg,#496c70,#b8d1bd 35%,#6d9d92 65%,#35585d);color:#183b3c}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings:after,#coachDock.coach-dock.ship-control-deck .dock-scoreboard:after,#coachDock.coach-dock.ship-control-deck .dock-food:after,#coachDock.coach-dock.ship-control-deck .dock-achievements:after,#coachDock.coach-dock.ship-control-deck .dock-pod:after{position:absolute;top:calc(100% + 4px);left:50%;translate:-50% 0;color:#c5d5cb;font:700 7px/1 ui-monospace,Consolas,monospace;letter-spacing:.05em;white-space:nowrap;text-shadow:0 1px #071118;pointer-events:none}\r\n#coachDock.coach-dock.ship-control-deck .dock-settings:after{content:'COACH'}#coachDock.coach-dock.ship-control-deck .dock-scoreboard:after{content:'SCORES'}#coachDock.coach-dock.ship-control-deck .dock-food:after{content:'FOOD'}#coachDock.coach-dock.ship-control-deck .dock-achievements:after{content:'BADGES'}#coachDock.coach-dock.ship-control-deck .dock-pod:after{content:'COMMS'}\r\n#coachDock.coach-dock.ship-control-deck button.dock-portal{border:3px solid #9eb7b1;border-top-color:#e1eed6;border-bottom-color:#445b5b;border-radius:50%!important;background:radial-gradient(circle at 50% 40%,#1a4545 0 46%,#0b212a 47% 58%,transparent 59%),repeating-conic-gradient(#b6c6b3 0deg 8deg,#51666a 8deg 15deg);box-shadow:0 0 0 3px #17262b,0 4px 0 3px #0a141b,inset 0 0 11px #85f9ce7e,0 0 12px #85f9ce50;color:#d7ffe6;text-shadow:0 0 5px #71ebb0}\r\n#coachDock.coach-dock.ship-control-deck button.dock-portal:before{display:none}\r\n#coachDock.coach-dock.ship-control-deck button.dock-portal:active,#coachDock.coach-dock.ship-control-deck button.dock-portal[aria-current=page]{transform:translateY(3px);box-shadow:0 0 0 3px #17262b,0 1px 0 3px #0a141b,inset 0 0 15px #a4ffe7,0 0 18px #88ffd2}\r\n#coachDock.coach-dock.ship-control-deck .dock-portal svg{width:20px;height:20px}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control{box-sizing:border-box;width:42px;height:43px;padding:15px 2px 2px;border:2px solid #afbbad;border-top-color:#e8e9d4;border-bottom-color:#566963;border-radius:4px!important;background:linear-gradient(145deg,#adbcb4,#526c6b 65%,#365154);box-shadow:inset 0 1px #fff9,inset 0 -2px #2a4747,0 3px #142324;color:#173f3a;font:700 8px ui-monospace,Consolas,monospace}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control:before{content:'';display:block;position:absolute;left:8px;top:5px;width:23px;height:8px;border:1px solid #172b2d;border-radius:2px;background:linear-gradient(90deg,#23383a 0 45%,#e4cfaa 48% 85%,#788c88 88%);box-shadow:inset 0 1px 2px #0008}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control[data-on=false]:before{background:linear-gradient(90deg,#e4cfaa 0 40%,#758c89 43%,#23383a 48%)}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound button.dock-control[data-on=true]{color:#f8e3ab;text-shadow:0 0 5px #ffe19a}\r\n#coachDock.coach-dock.ship-control-deck .dock-sound .cb-label{color:#c5d5cb}\r\n\r\n/* Keep seven physical controls on one rail before and after scene loading. */\r\n#coachDock.coach-dock.ship-control-deck{display:flex;justify-content:space-between;align-items:center;gap:3px}\r\n#coachDock.coach-dock.ship-control-deck .dock-control,#coachDock.coach-dock.ship-control-deck .dock-sound{flex:0 0 40px;min-width:0;width:40px}\r\n#coachDock.coach-dock.ship-control-deck .dock-portal{position:relative!important;left:auto!important;top:auto!important;translate:none!important;flex:0 0 56px;width:56px;min-width:56px}\r\n#coachDock.ship-control-deck .dock-settings{order:1}#coachDock.ship-control-deck .dock-food{order:2}#coachDock.ship-control-deck .dock-scoreboard{order:3}#coachDock.ship-control-deck .dock-portal{order:4}#coachDock.ship-control-deck .dock-achievements{order:5}#coachDock.ship-control-deck .dock-pod{order:6}#coachDock.ship-control-deck .dock-sound{order:7}\r\n#coachDock.ship-control-deck .dock-live{position:absolute}\r\n\r\n#homeScreen .deck-strip{justify-content:center!important}\r\nbody>#podPersistentChrome .pod-now-playing{width:112px;min-width:112px;max-width:112px}\r\n/* Terminals are attached to their housing, so they inherit its movement. */\r\n.pod-persistent-chrome[hidden]{display:none!important}\r\n.ship-header{position:relative}\r\n.ship-header>#podPersistentChrome{position:absolute;top:calc(100% + 8px);left:0;right:0;z-index:5;justify-content:flex-end}\r\n/* Returning from a modal mounts the terminal below this plate, over the deck strip. */\r\n.ship-header:has(>#podPersistentChrome:not([hidden])){z-index:13}\r\n.portal-frame>.pod-persistent-chrome{position:absolute;top:-22px;left:10px;right:10px;z-index:5;height:44px}\r\n.portal-frame>.pod-persistent-chrome>button{min-height:44px;font-size:9px}\r\n#portalHome>#podPersistentChrome{position:absolute;top:calc(var(--portal-top-band,52px) - 22px);left:calc(var(--portal-rail,15px) + 10px);right:calc(var(--portal-rail,15px) + 10px);z-index:10;height:44px}\r\n#portalHome>#podPersistentChrome>button{flex:0 0 auto;min-width:100px;min-height:44px}\r\n#coachDock.coach-dock.ship-control-deck button.dock-portal{border-color:color-mix(in srgb,var(--portal-metal,#4d3d4f),#fff 40%);background:radial-gradient(circle at 50% 40%,var(--portal-metal,#4d3d4f) 0 46%,color-mix(in srgb,var(--portal-metal,#4d3d4f),#000 65%) 47% 58%,transparent 59%),repeating-conic-gradient(color-mix(in srgb,var(--portal-metal,#4d3d4f),#fff 40%) 0deg 8deg,color-mix(in srgb,var(--portal-metal,#4d3d4f),#000 30%) 8deg 15deg)}\r\n","pod/pod-places.mjs":"import {STARTER_WONDERS,starterWonderUrl} from '../meditation-backgrounds.mjs';\r\n\r\nexport const POD_PLACE_KEY='myr5-pod-place-v1';\r\nexport const POD_PLACE_INTERVAL=20000;\r\nexport function choosePodPlace(previous,random=Math.random){\r\n const choices=STARTER_WONDERS.filter(id=>id!==previous);\r\n return choices[Math.min(choices.length-1,Math.max(0,Math.floor(random()*choices.length)))];\r\n}\r\nfunction available(url,ImageCtor){\r\n if(!ImageCtor)return Promise.resolve(true);\r\n return new Promise(resolve=>{\r\n  let done=false;\r\n  const finish=ok=>{if(done)return;done=true;clearTimeout(timer);resolve(ok);};\r\n  const image=new ImageCtor(),timer=setTimeout(()=>finish(false),3000);\r\n  image.onload=()=>finish(true);image.onerror=()=>finish(false);image.src=url;\r\n });\r\n}\r\n// Pixel photos belong only to the workout pod, not the shared room or oval ship scene.\r\nexport function mountPodPlaces(view,{documentRef=globalThis.document,windowRef=globalThis.window,storageRef,ImageCtor=globalThis.Image,random=Math.random}={}){\r\n if(!view)return ()=>{};\r\n let storage=storageRef;try{storage??=windowRef.localStorage;}catch{}\r\n let previous='';try{previous=storage?.getItem(POD_PLACE_KEY)||'';}catch{}\r\n let timer=0,generation=0,disposed=false,visible=!globalThis.IntersectionObserver,active=false;\r\n const shown=()=>!documentRef.hidden&&visible&&documentRef.body.dataset.tracking!=='true'&&documentRef.body.dataset.screen!=='rest'&&!documentRef.querySelector('dialog[open]');\r\n const rotate=async()=>{\r\n  const id=choosePodPlace(previous,random),token=++generation,url=starterWonderUrl(id);\r\n  if(!await available(url,ImageCtor)||disposed||token!==generation)return;\r\n  previous=id;view.style.setProperty('--pod-world',`url(\"${url}\")`);view.dataset.podPlace=id;\r\n  try{storage?.setItem(POD_PLACE_KEY,id);}catch{}\r\n };\r\n const schedule=()=>{windowRef.clearTimeout(timer);timer=0;if(active&&!disposed)timer=windowRef.setTimeout(()=>{void rotate();schedule();},POD_PLACE_INTERVAL);};\r\n const sync=()=>{const next=shown();if(next&&!active)void rotate();if(!next&&active)++generation;active=next;schedule();};\r\n const visibility=()=>sync();\r\n const pageShow=()=>sync();\r\n const dispose=()=>{disposed=true;++generation;windowRef.clearTimeout(timer);observer?.disconnect();intersection?.disconnect();documentRef.removeEventListener('visibilitychange',visibility);windowRef.removeEventListener('pageshow',pageShow);windowRef.removeEventListener('pagehide',pageHide);};\r\n const pageHide=event=>{if(event.persisted){active=false;windowRef.clearTimeout(timer);}else dispose();};\r\n const observer=globalThis.MutationObserver?new MutationObserver(sync):null;\r\n observer?.observe(documentRef.body,{subtree:true,attributes:true,attributeFilter:['data-screen','data-tracking','open']});\r\n const intersection=globalThis.IntersectionObserver?new IntersectionObserver(entries=>{visible=entries[0].isIntersecting;sync();}):null;\r\n intersection?.observe(view);\r\n documentRef.addEventListener('visibilitychange',visibility);windowRef.addEventListener('pageshow',pageShow);windowRef.addEventListener('pagehide',pageHide);\r\n sync();return dispose;\r\n}\r\n","pod/pod.css":"/* MOM's purple hardware. Gold readouts. Orange only on interaction. */\r\n.workout-route{margin:14px 0;padding:14px;border:1px solid #90769b55;border-radius:12px;background:#23182de0;font:14px/1.5 system-ui,sans-serif}.workout-route>small{color:#ffd36e;letter-spacing:.1em}.workout-route p{margin:6px 0}.workout-route [data-rounds]{font-size:12px;color:#cbbbd5}.workout-route button{width:100%;margin-top:8px}.workout-route details{margin-top:10px}.workout-route summary{cursor:pointer;min-height:32px}.workout-route ol{list-style:none;padding:0;margin:8px 0}.workout-route li{padding:5px 8px;border-left:2px solid #705082}.workout-route li[aria-current]{border-color:#ffd36e;background:#ffd36e12;color:#ffd36e}.rest-challenge{margin:10px 0}.rest-challenge strong{display:block;color:#ffd36e}\r\n:root{--wall:#171020;--purple:#7a2fc4;--gold:#ffd36e;--cream:#f6eddf;--muted:#bcb0cd;--power:#eacb8b;--font:system-ui,-apple-system,Segoe UI,sans-serif;color-scheme:dark}\r\n*{box-sizing:border-box}html,body{margin:0;min-height:100%;background:#120e19;color:var(--cream);font-family:var(--font)}\r\nbody{background:radial-gradient(ellipse at 50% 25%,#38224d 0%,#171020 60%),#171020;max-width:640px;margin:auto;min-height:100dvh;box-shadow:0 0 120px #0009}\r\n[hidden]{display:none!important}button,select,input{font:inherit}button,a,input,select{-webkit-tap-highlight-color:transparent}button,a{touch-action:manipulation}button,select,.file-label{min-height:44px;border:1px solid #6a537b;border-radius:10px;color:var(--cream);background:linear-gradient(160deg,#3b2b49,#271c32);padding:10px 14px;cursor:pointer}button:disabled{opacity:.4;cursor:default}button:focus-visible,a:focus-visible,select:focus-visible,input:focus-visible{outline:3px solid var(--gold);outline-offset:3px}a{color:var(--gold);text-decoration:none}select{min-width:0}button:active:not(:disabled){border-color:#ff9f4a;box-shadow:0 0 14px #ff8b3833}\r\n.ship-header{height:72px;display:flex;align-items:center;gap:14px;padding:12px 20px;border-bottom:1px solid #90769b44;background:linear-gradient(#44324e,#21172c);box-shadow:inset 0 1px #ae95ba44,inset 0 -5px #0b07123d;position:relative}\r\n.mom-brand{display:flex;align-items:center;gap:8px;color:#e9d3b1;font-weight:950;font-size:17px;line-height:.9;letter-spacing:-.6px}.mom-brand img{width:35px;height:36px;object-fit:contain}.mom-brand>span>span{display:block;font-size:10px;letter-spacing:5px;margin-top:5px}.ship-location{margin-left:auto;font:9px ui-monospace,monospace;letter-spacing:1px;color:#d6bddf}.ship-location small{display:block;font-size:8px;color:#9d8aaf;margin-top:6px;letter-spacing:1.2px}.icon-button{min-width:44px;font-size:22px;padding:6px;background:#24192e;box-shadow:inset 0 1px #ffffff13}\r\n.pod-page{padding:0 18px 8px}.deck-strip{display:flex;justify-content:space-between;align-items:center;height:36px;font:9px ui-monospace,monospace;letter-spacing:1.4px;color:#b8a6c8}.status-light,.voice-led{display:inline-block;width:5px;height:5px;background:#d7aaf5;box-shadow:0 0 9px #d7aaf5;border-radius:50%;margin-right:8px}\r\n.containment-pod{height:clamp(275px,43dvh,460px);position:relative;border:7px solid #49345c;border-radius:70px 70px 38px 38px;background:radial-gradient(ellipse at 50% 65%,#62308a50,transparent 60%),repeating-linear-gradient(0deg,#c4a2f104 0 1px,transparent 1px 4px),linear-gradient(120deg,#3e2b5066,#120e1ddd 28%,#171021 75%,#57376166);box-shadow:inset 0 0 0 2px #9a79ac77,inset 0 0 30px #0009,0 0 0 2px #100919,0 0 0 4px #574465,0 6px 18px #0006;isolation:isolate;overflow:hidden}\r\n.containment-pod:before{content:'';position:absolute;inset:8px;border:1px solid #b88de755;border-radius:56px 56px 28px 28px;pointer-events:none;z-index:4;background:linear-gradient(110deg,transparent 12%,#dfcdff0b 16%,transparent 25%)}\r\n.pod-rim{position:absolute;top:46px;bottom:24px;width:13px;border:1px solid #8d6ba266;border-radius:8px;background:linear-gradient(90deg,#191022,#6e4b84,#271931);z-index:5;box-shadow:0 0 12px #bb61ff33}.rim-left{left:7px}.rim-right{right:7px}.pod-rim:before{content:'';position:absolute;inset:12px 4px;background:repeating-linear-gradient(0deg,#debcff 0 4px,transparent 4px 23px);border-radius:5px;filter:drop-shadow(0 0 3px #d087ff)}\r\n.pod-inscription{position:absolute;top:17px;left:0;right:0;text-align:center;color:#b28fc1;font:9px ui-monospace,monospace;letter-spacing:5px;z-index:3}.coach-mount{position:absolute;inset:26px 18px 39px;z-index:2}#coachLoading{position:absolute;top:40%;left:0;right:0;text-align:center;font-size:12px;color:#aa92be}\r\n.pod-floor{position:absolute;bottom:2%;left:5%;right:5%;height:25%;border-radius:50%;transform:perspective(130px) rotateX(28deg);background:radial-gradient(ellipse,#9365bd30 20%,transparent 60%);border:1px solid #d7b8ff22;z-index:0}\r\n.pod-nameplate{position:absolute;bottom:0;left:32px;right:32px;display:flex;justify-content:space-between;align-items:center;height:34px;padding:0 14px;background:linear-gradient(#493253,#25172f);border:1px solid #a1849166;border-radius:8px 8px 0 0;font:8px ui-monospace,monospace;letter-spacing:1.2px;z-index:6}.pod-nameplate a{font:10px var(--font);letter-spacing:0}\r\n.myr5-companion-card{position:relative!important;inset:auto!important;width:100%!important;height:100%!important;border:0!important;border-radius:0!important;background:none!important;backdrop-filter:none!important;overflow:visible!important;box-shadow:none!important;pointer-events:none}\r\n.myr5-companion-stage{position:absolute!important;inset:0!important;width:100%!important;height:100%!important;background:none!important}.myr5-companion-status,.myr5-customize,.myr5-hide{display:none!important}.myr5-companion-stage canvas{position:static!important;width:100%!important;height:100%!important;pointer-events:none!important}\r\n.camera-preview{position:absolute;bottom:48px;right:23px;width:84px;height:108px;border-radius:13px;overflow:hidden;background:#191222;box-shadow:0 3px 14px #0006;border:1px solid #b08bc577;z-index:6;display:none}body[data-tracking=true] .camera-preview{display:block}.camera-preview video,.camera-preview canvas{position:absolute;inset:0;width:100%;height:100%;object-fit:contain}.camera-preview canvas{pointer-events:none}.camera-preview span{position:absolute;bottom:0;left:0;right:0;background:#17101bd9;text-align:center;padding:4px;color:#e6d4f3;font:7px ui-monospace,monospace}\r\n.coach-line{display:flex;align-items:center;justify-content:center;min-height:52px;padding:10px 8px;gap:2px}.coach-line p{margin:0;font-size:12px;line-height:1.45;color:#d6c3e4;text-align:center;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.voice-led{flex:none;width:4px;height:4px}\r\n.workout-console{padding:14px 16px 11px;background:linear-gradient(160deg,#493150,#30213a 55%,#23192d);border:1px solid #93789566;border-radius:20px;box-shadow:inset 0 1px #e1c7e12b,inset 0 -5px #09071144,0 7px 16px #0004}\r\n.set-heading{display:grid;grid-template-columns:1fr auto;align-items:center;gap:4px 10px}.set-heading label{grid-column:1/-1;font:8px ui-monospace,monospace;letter-spacing:1.3px;color:#bba4c7}.set-heading select{border:0;background:transparent;font-weight:650;font-size:20px;letter-spacing:-.6px;padding:4px 0;min-height:36px}.set-heading button{background:transparent;border:0;color:#e0c49c;font-size:11px;padding:5px;min-height:36px}\r\n.simple-counter{display:flex;align-items:center;justify-content:space-between;gap:15px;padding-top:8px;position:static!important;max-width:none!important;background:none!important}.simple-counter small{display:block;font:8px ui-monospace,monospace;letter-spacing:1.4px;color:#b19abf}.counter-number{display:flex;gap:9px;align-items:baseline;font-variant-numeric:tabular-nums;line-height:1.13}#primary{font-size:58px;font-weight:700;letter-spacing:-3px;color:var(--gold)}.goal-divider{font-size:24px;color:#8b739b;font-weight:200}#goalValue{font-size:29px;color:#ad94bd;letter-spacing:-1px}#primaryLabel{font-size:10px;color:#d4bfdb}.set-actions{display:flex;flex-direction:column;gap:4px;min-width:120px}.primary-action{display:flex;align-items:center;justify-content:center;gap:15px;border:1px solid #fff0bb88;background:linear-gradient(155deg,#ffe1a0,#d4ae64);color:#281b25;font-weight:750;font-size:13px;box-shadow:inset 0 1px #fff8,0 3px 0 #755237;min-height:48px;border-radius:10px;padding:10px 16px}.set-actions #stop{min-height:30px;padding:5px;background:none;border:0;color:#c7b0d4;font-size:11px}.set-track{height:3px;background:#190e22;border-radius:3px;margin-top:13px;overflow:hidden}#activity{height:100%;width:0;background:var(--gold);transition:width .2s}#status{font-size:10px;color:#bca6c9;line-height:1.4;margin:8px 0 0;min-height:14px}\r\n.crew-footer{display:flex;align-items:center;justify-content:space-between;gap:14px;padding-top:9px}.crew-footer button{display:flex;gap:5px;align-items:center;text-align:left;min-height:44px;background:none;border:0;padding:0;font-size:10px;color:#cbb6da}.crew-footer button span:first-of-type{max-width:155px}.crew-footer>span{font:7px ui-monospace,monospace;letter-spacing:.7px;color:#90789e}.crew-footer canvas{position:static!important;width:24px;height:36px;image-rendering:pixelated}\r\n.pod-dialog{width:min(440px,calc(100vw - 24px));max-height:calc(100dvh - 24px);padding:22px;border:1px solid #a387b5;border-radius:23px;color:var(--cream);background:linear-gradient(140deg,#392640,#1c1426 65%);box-shadow:0 25px 80px #0009}.pod-dialog::backdrop{background:#100b19d9;backdrop-filter:blur(8px)}.pod-dialog header{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:18px}.pod-dialog h2{font-size:21px;letter-spacing:-.6px;margin:0}.pod-dialog p{font-size:12px;line-height:1.5;color:#c8b4d4}.settings-fields{display:grid;grid-template-columns:1fr 1fr;gap:16px 10px}.settings-fields label{display:flex;flex-direction:column;gap:6px;font-size:11px;color:#c7b0d3}.settings-fields select{width:100%;font-size:12px;padding:9px}.voice-row{display:flex;flex-wrap:wrap;gap:8px;margin:18px 0 14px}.voice-row span{width:100%;font-size:10px;color:#b9a2c6}.voice-row button{flex:1;font-size:12px}.settings-actions{display:flex;gap:8px}.settings-actions button{flex:1;font-size:11px}.pod-dialog details{border-top:1px solid #70578188;margin-top:18px;padding-top:15px;color:#bfa5d1;font-size:12px}.pod-dialog summary{cursor:pointer;min-height:35px}.pod-dialog pre{font-size:9px;white-space:pre-wrap;overflow-wrap:anywhere}#roundControl{display:none!important}#identity{text-align:center}#identityAvatar{position:static;width:96px;height:144px;image-rendering:pixelated}#identityName{font-size:17px;color:var(--gold)}.file-label{position:relative;cursor:pointer}.file-label input{position:absolute;inset:0;opacity:0;width:100%;cursor:pointer}.pod-dialog>a{display:block;padding:16px;font-size:13px}#identityStatus{font-size:10px}\r\n.rest-page{padding:20px 22px 14px;min-height:calc(100dvh - 72px);display:flex;flex-direction:column;background:radial-gradient(ellipse at 50% 45%,#52247855,transparent 60%)}.rest-heading{display:flex;align-items:center;justify-content:space-between;gap:10px}.eyebrow{font:8px ui-monospace,monospace;letter-spacing:2px;color:#c59cda;margin:0 0 8px}.rest-heading h1{font-size:27px;letter-spacing:-1px;line-height:1.1;margin:0;font-weight:600;outline:none}.rest-receipt{display:flex;align-items:center;justify-content:space-between;gap:15px;font-size:10px;color:#ad93bf;padding:15px 0 0}#earnedXp{color:var(--gold);font:10px ui-monospace,monospace;white-space:nowrap}\r\n.encounter{position:relative;flex:1;min-height:360px;height:48dvh;max-height:600px;isolation:isolate;overflow:hidden;margin:8px -12px 0}.encounter-orbit{position:absolute;width:75%;height:55%;border:1px solid #9870b633;left:12.5%;top:16%;border-radius:50%;box-shadow:0 0 80px #853eda15}.encounter-orbit:after{content:'';position:absolute;inset:12px;border:1px dashed #a184b422;border-radius:50%}.encounter-grid{position:absolute;left:-30%;right:-30%;bottom:-5%;height:45%;transform:perspective(150px) rotateX(55deg);background:linear-gradient(#b184d022 1px,transparent 1px),linear-gradient(90deg,#b184d022 1px,transparent 1px);background-size:36px 36px;mask-image:linear-gradient(transparent,black)}\r\n.boss-status{position:absolute;top:11px;left:24px;right:24px;display:flex;justify-content:space-between;flex-wrap:wrap;gap:8px;font:8px ui-monospace,monospace;letter-spacing:1px;color:#c8b0d8;z-index:5}.boss-health{width:100%;height:3px;background:#1b1224}.boss-health i{display:block;width:100%;height:100%;background:linear-gradient(90deg,#7c3ca5,var(--power));box-shadow:0 0 5px #bb80e566;transition:width .25s}.rest-coach-mount{position:absolute;top:3%;left:-8%;width:116%;height:81%;z-index:2}.rest-coach-mount .myr5-companion-stage{filter:drop-shadow(0 0 14px color-mix(in srgb,var(--power) 14%,transparent))}\r\n.attack-target{position:absolute;inset:11% 8% 28%;background:none!important;border:0!important;box-shadow:none!important;z-index:6;border-radius:45%;touch-action:manipulation}.attack-target span{position:absolute;bottom:3px;left:0;right:0;text-align:center;font:8px ui-monospace,monospace;letter-spacing:2px;color:#d0afd7;opacity:.8}.attack-target:focus-visible{outline:2px solid var(--gold)}\r\n.player-platform{position:absolute;bottom:7%;left:50%;width:166px;height:45px;transform:translateX(-50%);z-index:7;pointer-events:none}.platform-top{position:absolute;inset:0;border-radius:50%;background:repeating-radial-gradient(ellipse,#5b466a 0 10px,#6e547e 11px 12px);border:2px solid #d0aec6;box-shadow:0 -4px 22px #d6a3ff11,inset 0 2px #f4d9ff66;z-index:2}.platform-edge{position:absolute;inset:4px 0 -10px;border-radius:50%;background:linear-gradient(#6b4b7e,#20132c);border:2px solid #8b638f;box-shadow:0 4px 0 #b083d7,0 8px 26px #a661e544}.platform-thruster{position:absolute;top:40px;left:45px;right:45px;height:35px;border-radius:0 0 50% 50%;background:linear-gradient(#d8a3ff88,transparent);filter:blur(5px)}#restAvatar{position:absolute;width:90px;height:135px;bottom:12px;left:38px;z-index:3;image-rendering:pixelated;transform-origin:50% 100%;pointer-events:none}.player-name{position:absolute;bottom:0;left:0;right:0;display:flex;gap:10px;justify-content:center;align-items:center;color:#ceb6db;font-size:10px;z-index:9}#restLevel{color:var(--gold);font:9px ui-monospace,monospace}\r\n.attack-flash{position:absolute;left:34%;top:36%;width:32%;height:25%;border:2px solid var(--power);border-radius:50%;opacity:0;z-index:5;pointer-events:none;box-shadow:0 0 16px color-mix(in srgb,var(--power) 30%,transparent)}.projectile{position:absolute;left:calc(50% - 3px);bottom:23%;width:5px;height:20px;border-radius:50%;background:#ffc478;box-shadow:0 0 9px #ffaa57;opacity:0;z-index:8;pointer-events:none}.damage-float{position:absolute;top:38%;left:0;right:0;text-align:center;color:var(--power);font:700 17px ui-monospace,monospace;z-index:9;opacity:0;pointer-events:none}.encounter.hit .attack-flash{animation:shield-hit .45s ease-out}.encounter.hit .projectile{animation:attack .28s ease-in}.encounter.hit .damage-float{animation:damage .65s ease-out}.encounter.hit #restAvatar{animation:player-hit .28s ease-out}\r\n.rest-feedback{text-align:center;min-height:28px;color:#c4accf;font-size:11px;line-height:1.5;margin:18px 0 5px}.rest-bottom{display:flex;align-items:center;justify-content:space-between;gap:15px;border-top:1px solid #87659255;padding-top:14px}.rest-clock small{display:block;font:8px ui-monospace,monospace;letter-spacing:1.5px;color:#b596c6}.rest-clock strong{display:block;color:var(--gold);font:500 37px var(--font);font-variant-numeric:tabular-nums;letter-spacing:-1.5px}.rest-bottom>div:last-child{min-width:155px}.rest-bottom .primary-action{width:100%}.text-button{display:block;background:none;border:0;box-shadow:none!important;font-size:10px;color:#c2a5d0;min-height:35px;padding:8px}.shield-note{text-align:center;color:#91789f;font:9px var(--font);line-height:1.4;margin:10px 0 0}\r\nbody[data-power=ember]{--power:#ff9d66}body[data-power=arc]{--power:#a4caff}body[data-power=frost]{--power:#b9eadf}\r\n@keyframes shield-hit{0%{opacity:.8;transform:scale(.65)}100%{opacity:0;transform:scale(1.3)}}@keyframes attack{0%{opacity:1;transform:translateY(0)}100%{opacity:.3;transform:translateY(-155px)}}@keyframes damage{0%{opacity:1;transform:translateY(0)}100%{opacity:0;transform:translateY(-28px)}}@keyframes player-hit{40%{transform:translateY(-9px) rotate(-6deg)}}\r\n#library{background:radial-gradient(ellipse at 20% 0%,#67437988,transparent 55%),#171020f7}#library .library-header small{color:#dbc095}#library .movement-card{background:linear-gradient(135deg,#60407244,#24152f99);border-color:#a783bd55}#library .holo-link{color:#e7c79a!important}#library .use-movement{background:#654978bb!important;border-color:#c0a0d388!important}#library #holoStage{background-color:#1a1026}#library button{border-color:#b493c455}\r\n@media(min-width:700px){body{border-left:1px solid #a57aad33;border-right:1px solid #a57aad33}.pod-page{padding:0 34px 10px}.ship-header{padding:12px 32px}.containment-pod{height:45dvh;min-height:310px}.rest-page{padding:24px 38px 18px}.encounter{min-height:390px}.crew-footer>span{font-size:8px}}\r\n@media(max-width:370px){.ship-header{padding:10px 14px;gap:8px}.ship-location{font-size:8px;letter-spacing:.3px}.pod-page{padding:0 13px 7px}.workout-console{padding:12px}.set-actions{min-width:108px}.set-heading select{font-size:18px}.rest-page{padding:17px}.rest-heading h1{font-size:24px}.counter-number{gap:6px}#primary{font-size:52px}}\r\n@media(max-height:720px) and (orientation:portrait){.ship-header{height:60px}.containment-pod{height:36dvh;min-height:235px}.coach-line{min-height:44px}.rest-page{min-height:calc(100dvh - 60px)}.encounter{min-height:290px}.rest-heading h1{font-size:23px}.rest-feedback{margin-top:10px}}\r\n@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation:none!important;transition:none!important}.encounter.hit .damage-float{opacity:1}.encounter.hit .attack-flash{opacity:.3}}\r\n#restCoachLoading{position:absolute;top:40%;left:10%;right:10%;text-align:center;font-size:12px;color:#c9add8;z-index:3}\r\n.set-actions .primary-action{gap:8px;padding:10px 11px;white-space:nowrap}\r\n.coach-line #coachCaption{color:#e8d5b3}\r\nbody:has(#library[open]) .myr5-companion-card{display:none!important}\r\n/* W2-2M #117: the pod is only the viewing port (your character over the pixel world), the control board and BEGIN,\r\n   sized so BEGIN sits above the bar without scrolling (the square's #workout start page scrolls to the top).\r\n   The viewing port takes whatever height is left; ids beat the optional hardware skins' .containment-pod heights. */\r\n#homeScreen{display:flex;flex-direction:column;min-height:calc(100dvh - 72px - var(--myr5-bar) - 12px)}\r\n#homeScreen>.training-view{flex:1 1 0;display:flex;flex-direction:column}\r\n#homeScreen .containment-bay{flex:1;display:flex;min-height:0}\r\n#homeScreen #view{flex:1;height:auto;min-height:150px;background:radial-gradient(ellipse at 50% 45%,transparent 58%,#120c1ccc),var(--pod-world,var(--room-world)) center 86%/cover no-repeat;background-position:center 45%,center bottom;background-size:auto,auto 125%;image-rendering:pixelated;container-type:size}\r\n#homeScreen #view #homeCharacter{inset:0}\r\n#view .pod-floor{display:none}\r\n/* The coach is parked here between scenes (its reveal is the oval's ship intro); the pre-set film still shows it. */\r\nbody:not([data-cinematic=pre]) #view .coach-mount,body[data-cinematic=pre] #view :is(.home-character,.coach-line){display:none}\r\n/* Pod header actions: the player's name (opens the avatar) and Customize coach, as plain text links. */\r\n.pod-header-actions{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:8px 2px 2px}\r\n.pod-header-actions #openIdentity,.pod-header-actions a{min-height:44px;display:flex;align-items:center;padding:0 4px;border:0;border-radius:6px;background:none;box-shadow:none;color:var(--gold);font:600 13px var(--font);text-decoration:underline;text-underline-offset:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:60%}\r\n.pod-header-actions #miniAvatar{display:none}\r\n/* Continue popup for today's unfinished set: on the pod, above the bottom bar. */\r\n.continue-workout{position:fixed;z-index:30;left:16px;right:16px;bottom:calc(var(--myr5-bar,0px) + 16px + env(safe-area-inset-bottom,0px));max-width:420px;margin:0 auto;padding:14px 16px;border:2px solid var(--gold);border-radius:14px;background:#21172ff2;box-shadow:0 10px 30px #000a}\r\n.continue-workout .continue-eyebrow{margin:0;color:var(--gold);font:800 11px ui-monospace,monospace;letter-spacing:.16em}.continue-workout h2{margin:4px 0 10px;font:800 19px/1.2 var(--font)}\r\n.continue-workout .continue-actions{display:flex;gap:10px}.continue-workout .continue-actions button{flex:1}\r\n/* Settings open folded: each group is a one-line summary until tapped. */\r\n#settings .settings-group>summary{min-height:44px;display:flex;align-items:center;cursor:pointer;font-weight:700}\r\n#settings .settings-group>summary::before{content:'▸';margin-right:8px}#settings .settings-group[open]>summary::before{content:'▾'}\r\n/* The coach's voice line is a radio band across the top of the viewing port. */\r\n#view .coach-line{position:absolute;z-index:5;top:32px;left:30px;right:30px;min-height:0;margin:0;padding:5px 10px;border:1px solid #b88de755;border-radius:8px;background:#140e1fd9;box-shadow:none}\r\n@container (max-height:220px){#view .coach-line{top:8px}#view .coach-line p{-webkit-line-clamp:1}#view .home-character{top:44px}#view .camera-preview{bottom:40px;width:60px;height:62px}}\r\n#controls>p:not([id]){margin:0 2px 8px;font-size:11px;line-height:1.35;color:#bca6c9}\r\n#controls .set-actions{flex-direction:row;align-items:stretch;gap:8px}#controls #start{flex:1;min-height:66px}#controls #stop{flex:none;min-width:64px}\r\n/* Goals: the daily circuit and the next-challenge card as a compact drop-down in the deck strip, over the viewing port. */\r\n.deck-strip{position:relative;z-index:12;height:44px;gap:8px}\r\n.pod-goals>summary{display:flex;align-items:center;gap:7px;min-height:36px;padding:0 12px;border:1px solid #6a537b;border-radius:8px;background:linear-gradient(#3b2b49,#271c32);box-shadow:inset 0 1px #ffffff14,0 2px 0 #0b0712;list-style:none;cursor:pointer;color:var(--gold);font:700 10px/1 ui-monospace,monospace;letter-spacing:.16em}\r\n.pod-goals>summary::-webkit-details-marker{display:none}\r\n.pod-goals>summary:after{content:'▾';font-size:11px;letter-spacing:0}.pod-goals[open]>summary:after{content:'▴'}\r\n.pod-goals>summary:focus-visible{outline:3px solid var(--gold);outline-offset:2px}\r\n.pod-goals [data-goals-status]{color:var(--cream);letter-spacing:.05em}\r\n.pod-goals-menu{position:absolute;left:0;right:0;top:calc(100% + 2px);max-height:calc(100dvh - 140px - var(--myr5-bar));overflow:auto;overscroll-behavior:contain;padding:12px 14px;border:1px solid #a387b5;border-radius:14px;background:linear-gradient(160deg,#3a2742,#1d1426);box-shadow:0 14px 34px #000c;font:14px/1.45 var(--font);letter-spacing:0;color:var(--cream)}\r\n.pod-goals-menu .daily-circuit>small{color:var(--gold);letter-spacing:.1em}.pod-goals-menu .daily-circuit meter{width:100%}.pod-goals-menu .daily-circuit p{margin:6px 0}.pod-goals-menu .daily-circuit ol{margin:6px 0;padding-left:22px}.pod-goals-menu .daily-circuit button{width:100%}\r\n.pod-goals-menu .workout-route{margin:12px 0 0}\r\n/* The pod's extras ride along to Records (coach-hub.mjs); Meditation there is the #meditate route's opener only. */\r\n.pod-extras .crew-footer{display:none}.pod-extras .meditation-entry{display:none}\r\n@media(max-height:720px) and (orientation:portrait){#homeScreen{min-height:calc(100dvh - 60px - var(--myr5-bar) - 12px)}}\r\n/* The one-time \"Updated\" notice sits above the bar, which on the pod is exactly where BEGIN is: off the quilt it sits\r\n   over the viewing port instead, clear of BEGIN below and of the downloads bar (.full-download-bar) at the top. */\r\nbody:not(:has(#portalHome:not([hidden]))):not([data-screen=rest]) .app-update-banner{top:calc(128px + env(safe-area-inset-top));bottom:auto}\r\n/* FULL WORKOUT circuit dropdown + runner overlay */\r\n#podFullWorkout{position:static}.fw-menu .fw-bar,.fw-menu .fw-style-bar{display:flex;gap:8px;margin:0 0 8px}.fw-menu button{min-height:34px;padding:0 12px;border:1px solid #6a537b;border-radius:8px;background:#3b2b49;color:var(--cream);font:700 12px/1 var(--font)}\r\n.fw-menu .fw-bar button{flex:1}.fw-menu .fw-count{margin:0 0 8px;font-size:12px;color:var(--gold)}\r\n.fw-style{margin:4px 0;border:1px solid #4a3858;border-radius:10px;padding:0 10px}.fw-style>summary{min-height:38px;display:flex;align-items:center;justify-content:space-between;cursor:pointer;font-weight:700;list-style:none}.fw-style>summary::-webkit-details-marker{display:none}.fw-style>summary span{font-size:11px;color:var(--gold)}\r\n.fw-row{display:flex;flex-wrap:wrap;align-items:center;gap:8px;min-height:36px}.fw-row input{width:20px;height:20px;accent-color:var(--gold)}.fw-row small{flex-basis:100%;margin:-4px 0 6px 28px;font-size:11px;color:#bca6c9}.fw-locked{opacity:.5}\r\n.fw-menu .fw-start{width:100%;min-height:48px;margin-top:10px;background:linear-gradient(#e0b04a,#a87a1f);color:#1b1022;border-color:#f5d27a;font-size:14px;letter-spacing:.08em}.fw-menu .fw-start:disabled{opacity:.4}\r\n#fullWorkoutHud{position:fixed;z-index:2147483000;left:0;right:0;top:0;font:14px/1.4 var(--font);color:var(--cream)}\r\n#fullWorkoutHud[data-mode=exercise]{pointer-events:none}#fullWorkoutHud .fw-top{pointer-events:auto;display:flex;align-items:center;gap:10px;margin:6px;padding:6px 10px;border:1px solid #a387b5;border-radius:10px;background:#1d1426e6}.fw-top span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fw-top button{min-height:32px;padding:0 12px;border-radius:8px;border:1px solid #6a537b;background:#3b2b49;color:var(--cream)}\r\n#fullWorkoutHud[data-mode=break],#fullWorkoutHud[data-mode=summary]{bottom:0;display:grid;place-items:center;background:#0b0712f2}\r\n.fw-panel{width:min(92vw,420px);max-height:92dvh;overflow:auto;text-align:center}.fw-panel h2{margin:0 0 6px}.fw-panel button{min-height:44px;margin:6px 4px;padding:0 18px;border:1px solid #a387b5;border-radius:10px;background:#3b2b49;color:var(--cream);font-weight:700}\r\n.fw-eyebrow{margin:0;color:var(--gold);letter-spacing:.2em;font:700 12px ui-monospace,monospace}.fw-clock{font:700 72px/1.1 ui-monospace,monospace;color:var(--gold)}.fw-big{font-size:22px;font-weight:700;margin:2px 0}.fw-sub{margin:0 0 10px;color:#bca6c9}\r\n.fw-panel ol{text-align:left;padding-left:24px}.fw-panel li span{float:right;color:var(--gold)}\r\n/* FULL WORKOUT switchboard: one brushed-metal plate, bat-handle toggles (same metal as .cb-switch), engraved plates, amber lamps */\r\n.fw-menu{background:repeating-linear-gradient(90deg,#ffffff0a 0 1px,#0000 1px 3px),linear-gradient(#5a4b5a,#34293b 40%,#2a2131);border:2px solid #14101a;box-shadow:inset 0 1px #d4bdca77,inset 0 -3px #0007,0 14px 34px #000c;color:#eadde6;padding-top:14px}\r\n.fw-menu .fw-bar{position:relative;padding:0 16px}.fw-screw{position:absolute;top:50%;width:9px;height:9px;margin-top:-4px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#dccbd4,#6e5f6c 60%,#382d3a);box-shadow:0 1px 2px #000a;pointer-events:none}.fw-screw:before{content:'';position:absolute;left:1px;right:1px;top:4px;height:1px;background:#2a2030;transform:rotate(35deg)}.fw-screw.l{left:0}.fw-screw.r{right:0}\r\n.fw-menu button:not(.fw-start):not(.fw-plug):not(.fw-hub){min-height:44px;border:1px solid #0d0a10;border-radius:7px;background:linear-gradient(#524352,#30273a);box-shadow:inset 0 1px #d4bdca66,inset 0 -2px #0006,0 3px 0 #140f19;color:#d9c9d3;letter-spacing:.12em;text-transform:uppercase;font-size:11px;transition:transform .07s}.fw-menu button:not(.fw-start):not(.fw-plug):not(.fw-hub):active{transform:translateY(2px);box-shadow:inset 0 1px #d4bdca44,0 1px 0 #140f19}\r\n.fw-menu .fw-count{text-align:center;font:700 11px ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase;color:var(--gold)}\r\n.fw-style{border:1px solid #14101a;background:linear-gradient(#3b2f41,#2b2232);box-shadow:inset 0 1px #d4bdca33,0 2px 0 #140f19}.fw-style>summary{min-height:48px}\r\n.fw-plate{padding:4px 10px;border:1px solid #0d0a10;border-radius:4px;background:linear-gradient(#b9a9b3,#7d6e7a);color:#2a2030;text-shadow:0 1px #ffffff55;font:800 12px/1 ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase;box-shadow:inset 0 1px #fff8}\r\n.fw-row{position:relative;min-height:48px;padding:0 4px;border-top:1px solid #ffffff10;gap:10px;cursor:pointer}.fw-row input{position:absolute;opacity:0;inset:0;width:100%;height:100%;margin:0;cursor:pointer}.fw-row input:disabled{cursor:not-allowed}\r\n.fw-name{flex:1;min-width:0}\r\n.fw-lamp{flex:none;width:10px;height:10px;border-radius:50%;background:radial-gradient(circle at 35% 30%,#6d5a50,#2a1d17);border:1px solid #0d0a10;box-shadow:inset 0 1px #fff3}.fw-row:has(input:checked) .fw-lamp{background:radial-gradient(circle at 35% 30%,#fff2b8,#ffb42e 55%,#a85a00);box-shadow:0 0 8px #ffb42ecc,inset 0 1px #fff8}\r\n.fw-tog{position:relative;flex:none;order:3;width:44px;height:48px;border:1px solid #0d0a10;border-radius:7px;background:linear-gradient(#524352,#30273a);box-shadow:inset 0 1px #d4bdca66,inset 0 -2px #0006,0 3px 0 #140f19}\r\n.fw-tog:before{content:'';position:absolute;left:calc(50% - 4px);top:calc(50% - 21px);width:8px;height:21px;border-radius:4px 4px 2px 2px;background:linear-gradient(90deg,#6b5d69,#f4ebf0 45%,#857583);box-shadow:2px 2px 3px #0009;transform-origin:50% 100%;transform:translateY(0) scaleY(-1);transition:transform .14s cubic-bezier(.3,1.5,.5,1)}\r\n.fw-tog:after{content:'';position:absolute;left:calc(50% - 7px);top:calc(50% - 7px);width:14px;height:14px;border-radius:50%;background:radial-gradient(circle at 40% 35%,#dccbd4,#6e5f6c 60%,#382d3a);box-shadow:0 2px 3px #000a}\r\n.fw-row input:checked~.fw-tog:before{transform:scaleY(1)}.fw-row input:focus-visible~.fw-tog{outline:3px solid var(--gold);outline-offset:2px}\r\n.fw-locked .fw-tog{filter:brightness(.55) saturate(.5)}.fw-guard{position:absolute;inset:-1px;z-index:2;display:grid;place-items:center;border:1px solid #0d0a10;border-radius:7px;background:repeating-linear-gradient(45deg,#8a7a28 0 5px,#2a2412 5px 10px);color:#ffe9a0;font:800 8px/1 ui-monospace,monospace;letter-spacing:.1em;text-shadow:0 1px #000}\r\n.fw-locked small{color:#c9b0bd}.fw-menu .fw-style-bar{gap:6px}.fw-menu .fw-style-bar button{flex:1}\r\n@media (prefers-reduced-motion:reduce){.fw-tog:before,.fw-menu button{transition:none}}\r\n/* FULL WORKOUT power bus + cables + level ladder */\r\n.fw-body{position:relative}.fw-wires{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible;pointer-events:none;z-index:3}\r\n.fw-power{position:relative;display:flex;align-items:center;justify-content:space-between;gap:10px;padding:10px 22px;border:2px solid #14101a;border-radius:10px;background:repeating-linear-gradient(90deg,#ffffff0d 0 1px,#0000 1px 4px),linear-gradient(#6a5a6a,#3a2e42);box-shadow:inset 0 1px #e6d3de88,inset 0 -3px #0008,0 4px 0 #140f19}\r\n.fw-power .fw-screw.l{left:7px}.fw-power .fw-screw.r{right:7px}.fw-power .fw-screw{top:50%}\r\n.fw-hub{flex:none;width:64px;height:64px;margin:0 auto;border-radius:50%!important;border:3px solid #14101a!important;background:radial-gradient(circle at 38% 30%,#e8dbe3,#8c7b88 45%,#3a2e3c)!important;box-shadow:inset 0 2px #fffa,inset 0 -4px #0008,0 4px 0 #140f19!important;color:#2a2030!important;font:700 30px/1 system-ui!important;letter-spacing:0!important;display:grid;place-items:center}\r\n.fw-hub[data-lit=true]{color:#ffb42e!important;text-shadow:0 0 10px #ffb42e;background:radial-gradient(circle at 38% 30%,#4a3a2a,#2a1d17 60%,#150f0b)!important;box-shadow:inset 0 2px #ffd36e55,0 0 18px #ffb42e99,0 4px 0 #140f19!important}\r\n.fw-bay{height:210px}\r\n.fw-pick{flex:1;min-width:0;margin:0 8px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right;font:700 11px ui-monospace,monospace;letter-spacing:.06em;color:var(--gold);text-transform:uppercase}\r\n.fw-socket{flex:none;position:relative;width:30px;height:30px;margin-right:2px;border-radius:50%;border:2px solid #0d0a10;background:radial-gradient(circle,#050308 35%,#4a3d4c 40%,#2c2330);box-shadow:inset 0 2px 4px #000,0 1px #ffffff22}\r\n.fw-style[data-power=on] .fw-socket{box-shadow:inset 0 2px 4px #000,0 0 10px #ffb42e}.fw-spark:after{content:'';position:absolute;inset:-14px;border-radius:50%;background:radial-gradient(circle,#fff8c8,#ffb42e66 40%,#0000 70%);animation:fwspark .5s ease-out both}\r\n@keyframes fwspark{from{transform:scale(.2);opacity:1}to{transform:scale(1.5);opacity:0}}\r\n.fw-style>summary{padding-right:8px}.fw-hint{margin:2px 0 8px;padding:6px 8px;border-radius:6px;background:#0005;color:#e8cf86;font-size:12px}\r\n.fw-plug{position:absolute;left:0;top:0;z-index:5;width:44px;height:44px;padding:0;border:0;background:none;touch-action:none;cursor:grab;will-change:transform}\r\n.fw-plug i{position:absolute;left:12px;top:2px;width:20px;height:40px;border-radius:5px 5px 9px 9px;border:1px solid #0d0a10;background:linear-gradient(90deg,#6b5d69,#f4ebf0 45%,#857583);box-shadow:0 3px 5px #000a}\r\n.fw-plug i:before{content:'';position:absolute;left:3px;right:3px;bottom:-9px;height:10px;background:linear-gradient(90deg,#9a8a96,#fff 50%,#9a8a96);border-radius:0 0 3px 3px;box-shadow:inset 0 -3px #0005}\r\n.fw-plug:focus-visible{outline:3px solid var(--gold);outline-offset:-2px;border-radius:10px}.fw-plug[aria-pressed=true] i{background:linear-gradient(90deg,#8a6a2a,#ffe9a0 45%,#a8802f)}\r\n.fw-capped i{background:repeating-linear-gradient(45deg,#8a7a28 0 5px,#2a2412 5px 10px)!important;filter:grayscale(.4)}.fw-capped i:after{content:'LOCK';position:absolute;inset:12px -6px auto;text-align:center;font:800 8px/1 ui-monospace,monospace;color:#ffe9a0;background:#000a;border-radius:3px;padding:2px 0}\r\n.fw-row.fw-dead{opacity:.55}.fw-row.fw-dead .fw-tog{filter:brightness(.6)}\r\n.fw-lv{display:inline-grid;place-items:center;width:20px;height:20px;margin-right:4px;border-radius:50%;background:#0006;color:var(--gold);font:700 11px ui-monospace,monospace}\r\n.fw-tog:before,.fw-lamp{transition-delay:calc(var(--d,0)*55ms)}.fw-lamp{transition:background .15s,box-shadow .15s}\r\n.fw-style:not([data-power=on]) .fw-row:has(input:checked) .fw-lamp{background:radial-gradient(circle at 35% 30%,#6d5a50,#2a1d17);box-shadow:inset 0 1px #fff3}\r\n.fw-style.fw-pulse[data-power=on] .fw-row:has(input:checked) .fw-lamp{animation:fwlamp .45s both;animation-delay:calc(var(--r)*80ms)}\r\n@keyframes fwlamp{from{background:#2a1d17;box-shadow:none;transform:scale(.6)}to{transform:scale(1)}}\r\n@media (prefers-reduced-motion:reduce){.fw-style.fw-pulse .fw-lamp{animation:none!important}.fw-spark:after{animation:none;opacity:.6}.fw-tog:before,.fw-lamp{transition:none;transition-delay:0s}}\r\n\r\n/* cord channel: a 64px gutter on the right carries every cable; sockets and the hub sit in it, labels never get crossed */\r\n.fw-body{padding-right:64px}\r\n.fw-power{position:sticky;top:-2px;z-index:6;margin-right:-64px;padding:8px 4px 8px 14px;min-height:72px}\r\n.fw-pw-l{display:flex;flex-direction:column;gap:4px;align-items:flex-start;min-width:0}.fw-pw-l .fw-count{margin:0;text-align:left;font-size:10px}\r\n.fw-hub{width:56px;height:56px;margin:0!important;font-size:26px!important}\r\n.fw-power .fw-screw.r{display:none}\r\n.fw-bay{height:200px;margin-right:-64px}\r\n.fw-style>summary{position:relative}.fw-socket{position:absolute;right:-48px;top:50%;margin:-15px 0 0}\r\n.fw-cord path{fill:none;stroke-linecap:round;stroke-linejoin:round}\r\n.fw-c-sh{stroke:#000;stroke-opacity:.45;stroke-width:11;transform:translate(2px,3px)}\r\n.fw-c-jk{stroke:#221a28;stroke-width:7}\r\n.fw-c-hl{stroke:#8d7f8c;stroke-opacity:.8;stroke-width:1.8;transform:translate(-1.6px,-1.6px)}\r\n.fw-c-pl{stroke:#ffc24a;stroke-width:2.4;stroke-dasharray:5 26;opacity:0;filter:drop-shadow(0 0 3px #ffb42e)}\r\n.fw-cord.on .fw-c-jk{stroke:#2e2018}.fw-cord.on .fw-c-hl{stroke:#ffb42e;stroke-opacity:.55}.fw-cord.on .fw-c-pl{opacity:1;animation:fwpulse 1.1s linear infinite}\r\n@keyframes fwpulse{to{stroke-dashoffset:-31}}\r\n@media (prefers-reduced-motion:reduce){.fw-cord.on .fw-c-pl{animation:none;stroke-dasharray:none;opacity:.5}}\r\n.fw-menu,.fw-menu *{-webkit-user-select:none;user-select:none}\r\n","pod/pod.mjs":"import {captureRestBossContext,hasRestBossDefeat,readRestBossRewards,recordRestBossDefeatExclusive} from '../rest-boss-rewards.mjs';\r\nimport {initRestArena} from './rest-arena.mjs';\r\nimport {abilityFor} from './weapon-evolution.mjs';\r\nimport {SetFlow,DEFAULT_GOALS,valueOf,bossHealthMax,shouldStartRestTargets} from './set-flow.mjs';\r\nimport {SetEncouragement} from './encouragement.mjs';\r\nimport {setFlipValue,clockDigits} from '../flip-display.mjs';\r\nimport {GALA_KEY,loadGala,importGala,loadPower,POWERS} from './identity.mjs';\r\nimport {mountWorkoutRoute} from '../workout-route-ui.mjs';\r\nimport {mountCircuitUI} from '../circuit-ui.mjs';\r\nimport {ROUTE_LINES,exerciseFamily} from '../workout-route.mjs';\r\nimport {physicalSound} from '../audio/physical-sound.mjs';\r\nimport {VOICE_MANIFEST} from '../robot-audio.mjs';\r\nimport {WorkoutSessionOwner} from './workout-session-owner.mjs';\r\nimport {combatLevel} from '../battle-pass.mjs';\r\nimport {throughWormhole,LINES} from './set-transition.mjs';\r\nimport {SPECIAL_LEVEL} from '../combat-config.mjs';\r\nimport {recordPerformanceSession,readPerformanceProgress,workoutEligibility,performanceOwner,localDay} from '../performance-progress.mjs';\r\nimport {STARTER_COACH_IDS} from '../performance-catalog.mjs';\r\nimport {HOLD_TARGET_SECONDS,REP_CAP} from '../progression-rules.mjs';\r\nimport {mountShipBackdropMotion} from './ship-backdrop.mjs';\r\nimport {coach3dEnabled} from '../coach3d-flag.mjs';\r\nimport {mountRestCoachSprite} from './rest-coach-sprite.mjs';\r\nlet voiceManifest=null;\r\n// Fetch the clips this set will say while the camera opens; sw.js stores /voice/* in the voice cache, so RobotAudio's later fetch is a hit.\r\nfunction warmVoice(goal){try{voiceManifest??=fetch(VOICE_MANIFEST).then(r=>r.json()).catch(()=>{voiceManifest=null;return null;});voiceManifest.then(m=>{if(!m)return;const say=['Get into position.',...Array.from({length:Math.min(60,Number(goal)||0)},(_,i)=>String(i+1))];for(const p of say){const u=m.phrases[p];if(u)fetch(u,{priority:'low'}).catch(()=>{});}});}catch{}}\r\nconst $=id=>document.getElementById(id),PROGRESS='myr5-workout-progress-v1',COOLDOWN='myr5-special-cooldown-v1';\r\nconst time=s=>`${Math.floor(s/60)}:${String(Math.floor(s%60)).padStart(2,'0')}`;\r\nconst safeRead=key=>{try{return localStorage.getItem(key);}catch{return null;}};\r\nexport const idleStatus=text=>{const value=String(text||'').trim();return !value||value==='Ready';};\r\nexport function initPod({voice,movements,onStop,onNext,workouts}){\r\n mountShipBackdropMotion();\r\n let hand={enter(){},leave(){},hit(){},dispose(){},edit(){}};let handOptionalLoaded=false;const arena=initRestArena();\r\n window.addEventListener('myr5:optional-materials-ready',async()=>{if(handOptionalLoaded)return;handOptionalLoaded=true;const {initHandCompanion}=await import('../hand-companion.mjs');hand=initHandCompanion();},{once:true});\r\n // safeRead(PROGRESS) restores the last-synced circuit snapshot (and completedSets) so the\r\n // circuit meter can render immediately on reopen, before the next account-progress event lands.\r\n const flow=new SetFlow(safeRead(PROGRESS),{cooldown:safeRead(COOLDOWN)}),encourage=new SetEncouragement();\r\n const workoutOwner=new WorkoutSessionOwner({saveProgress:async data=>{\r\n  try{return await workouts.complete(data.id,{value:data.value,activeSeconds:data.activeSeconds,elapsedSeconds:data.elapsedSeconds,earned:data.earned,progress:data.progress});}\r\n  catch(error){return {local:false,reason:error?.message||'Workout progress was not saved on this device.'};}\r\n }});\r\n let currentMode=null,card=null,observedCard=null,restTimer=0,hitTimer=0,lastSpoken=-Infinity,restCalled=false,look,preparationRest=false;\r\n let awaitingRound=null,pendingChallenge=null,pausedLocal=null,cardioStyle='gentle';\r\n const route=mountWorkoutRoute({mode:()=>currentMode||'squat',busy:()=>flow.phase!=='pod'||document.body.dataset.tracking==='true',pending:()=>!!awaitingRound,onNext});\r\n const circuit=mountCircuitUI({voice,onNext,busy:()=>flow.phase!=='pod'||document.body.dataset.tracking==='true',pending:()=>!!awaitingRound,cached:()=>flow.progress.circuit});\r\n window.addEventListener('myr5:coach-plan',()=>{if(flow.phase==='set')return;const mode=currentMode||'squat';currentMode=null;configure(mode);if(window.coachPlan?.data?.profile?.restSeconds)$('restDuration').value=window.coachPlan.data.profile.restSeconds;});\r\n const avatar=window.GalaAvatar;let storageAvailable=true;\r\n const store=(key,value)=>{try{localStorage.setItem(key,value);return true;}catch{storageAvailable=false;return false;}};\r\n function updateProgress(){flow.performanceXp=readPerformanceProgress().totalXp;const level=String(flow.level).padStart(2,'0');$('levelBadge').textContent='WORKOUT LV. '+level;$('restLevel').textContent='LV. '+level;$('setNumber').textContent='SET '+String(flow.progress.completedSets+1).padStart(2,'0');}\r\n function paintGuest(){\r\n  if(!avatar)return;\r\n  try{look=loadGala(localStorage,avatar);}catch{look={look:structuredClone(avatar.defaultLook),linked:false};}\r\n  for(const id of ['miniAvatar','identityAvatar'])avatar.draw($(id),look.look,{base:id!=='restAvatar'});\r\n  const name=window.MBS_DJ?.display()||(look.linked?(look.look.name||'Gala guest'):'Guest preview');arena.load();$('guestLabel').textContent=window.MBS_DJ?.display()||(look.linked?name:'Anonymous guest');$('restGuest').textContent=name;$('identityName').textContent=name;\r\n  $('restAvatar').setAttribute('aria-label',name+' on the floating platform');$('identityStatus').textContent=look.linked?'Appearance saved':'Guest appearance';\r\n }\r\n function moveCoach(){\r\n  // 3D coach off (coach3d-flag.mjs): the rest scene shows the 64-bit coach sprite; the 3D card never enters it.\r\n  if(!coach3dEnabled()&&(flow.phase==='rest'||preparationRest)){mountRestCoachSprite($('restCoachMount'));$('restCoachLoading').hidden=true;return;}\r\n  card??=document.querySelector('.myr5-companion-card');if(!card)return;\r\n  if(observedCard!==card){observer.observe(card,{childList:true,subtree:true,attributes:true,attributeFilter:['data-ready']});observedCard=card;}\r\n  // Full-screen workout mode parks the card in #coachOverlay (created at runtime by camera-workout.mjs,\r\n  // not a static pose.html id, hence document.getElementById here rather than the $() shorthand); leave it there while tracking.\r\n  if(!preparationRest&&((document.body.dataset.tracking==='true'&&document.getElementById('coachOverlay'))||document.body.dataset.shipView==='true')){}else{\r\n   const inRest=flow.phase==='rest'||preparationRest,mount=inRest?$('restCoachMount'):$('coachMount');if(card.parentElement!==mount)mount.append(card);\r\n   if(window.myr5Creature?.stats().stage!==(inRest?'encounter':'pod'))window.myr5Creature?.stage(inRest?'encounter':'pod');\r\n  }\r\n  const label=card.querySelector('.myr5-companion-status')?.textContent||'';\r\n  // Errors from the finished companion still need a visible place in the new shell.\r\n  for(const id of ['coachLoading','restCoachLoading']){const loading=$(id);loading.hidden=card.dataset.ready==='true';if(!loading.hidden&&loading.textContent!==label)loading.textContent=label;}\r\n }\r\n const observer=new MutationObserver(moveCoach);observer.observe($('view'),{childList:true,subtree:true});moveCoach();\r\n function configure(mode){\r\n  if(mode!==currentMode){currentMode=mode;const kind=movements[mode].kind,unit=kind==='hold'||kind==='pace'?'seconds':kind==='steps'?'steps':kind==='jumps'?'jumps':'reps';\r\n   const next=window.coachProgress?.exerciseRoute?.groups?.[exerciseFamily(mode)]?.next;\r\n   const planned=kind==='hold'?HOLD_TARGET_SECONDS:kind==='reps'?REP_CAP:HOLD_TARGET_SECONDS;\r\n   const values=[...new Set([1,2,3,5,9,10,15,20,30,45,60,90,120,180,planned,Math.max(1,planned-1),planned+1])].sort((a,b)=>a-b);\r\n   $('goal').replaceChildren(...values.map(n=>{const o=document.createElement('option');o.value=n;o.textContent=n+' '+unit;return o;}));$('goal').value=planned;\r\n  }\r\n  encourage.reset();$('goalValue').textContent=['hold','pace'].includes(movements[mode].kind)?time(Number($('goal').value)):String($('goal').value);updateProgress();route.render();circuit.render();if(document.body.dataset.tracking!=='true')$('start').disabled=!workoutEligibility(mode).allowed;\r\n }\r\n async function beginSet(mode,{manual=false}={}){if(manual)throw Error('Camera tracking is required for workout XP.');const startingOwner=performanceOwner(),restRewardsContext=captureRestBossContext();if(workoutOwner.snapshot().transitioning)throw Error('Coach is updating. Please wait.');configure(mode);pausedLocal=manual?await workouts.paused():null;if(performanceOwner()!==startingOwner)throw Error('Your account changed while the workout was opening. Start again.');const pausedOwner=pausedLocal?.progress?.performanceOwner??pausedLocal?.ownerId,legacyGuest=pausedLocal&&!pausedLocal.progress?.performanceOwner&&startingOwner.startsWith('guest:')&&pausedLocal.ownerId===workouts.ownerId;if(pausedLocal&&pausedOwner&&pausedOwner!==startingOwner&&!legacyGuest)throw Error('Resume this workout with the account or guest profile that started it.');if(workoutOwner.snapshot().transitioning)throw Error('Coach is updating. Please wait.');if(pausedLocal&&(!manual||pausedLocal.mode!==mode))throw Error('Resume or complete the paused manual workout first.');if(!pausedLocal&&!workoutOwner.canStart())throw Error('Workout activation is in progress. Try again.');const eligibility=workoutEligibility(mode);if(!eligibility.allowed)throw Error(eligibility.reason);const ownerStarted=!pausedLocal;if(ownerStarted&&!workoutOwner.start())throw Error('Workout activation is in progress. Try again.');let ticket=null;try{const goal=Number($('goal').value),restSeconds=30;ticket=await workouts.start({mode,goal,restSeconds,progress:{...(pausedLocal?.progress??{}),performanceOwner:startingOwner},metadata:{name:movements[mode].name},control:manual?'manual':'camera'});if(performanceOwner()!==startingOwner)throw Error('Your account changed while the workout was opening. Start again.');flow.start(mode,goal,restSeconds,{performance:true,kind:movements[mode].kind,snapshot:ticket.progress?.performanceWorkout,cardio:cardioStyle});if(legacyGuest){flow.workout.raw=Number(ticket.progress?.value)||0;flow.workout.baseline=flow.workout.raw;}flow.active.performanceOwner=startingOwner;flow.active.restRewardsContext=restRewardsContext;flow.active.localId=ticket.id;flow.active.control=manual?'manual':'camera';flow.active.savedProgress=ticket.progress??{};pausedLocal=null;if(!manual)warmVoice($('goal').value);document.body.dataset.screen='pod';clearInterval(restTimer);return ticket;}catch(error){if(ticket){await workouts.interrupt(ticket.id,ticket.progress??{}).catch(()=>{});if(flow.phase==='set'&&flow.active?.localId===ticket.id)flow.leave();pausedLocal=null;}if(ownerStarted||ticket)workoutOwner.stop();throw error;}}\r\n function setGoal(goal){if(![...$('goal').options].some(o=>Number(o.value)===goal)){const option=document.createElement('option');option.value=goal;option.textContent=goal+' '+(['hold','pace'].includes(movements[currentMode].kind)?'seconds':movements[currentMode].kind==='steps'?'steps':'reps');$('goal').append(option);}$('goal').value=goal;$('goal').dispatchEvent(new Event('change',{bubbles:true}));}\r\n function render(m){const goal=flow.active?.mode===m.mode?flow.active.goal:Number($('goal').value)||DEFAULT_GOALS[m.mode];$('activity').style.width=Math.min(100,valueOf(m)/goal*100)+'%';}\r\n function power(){const p=$('coachPower').value;document.body.dataset.power=p;$('powerName').textContent=POWERS[p].name.toUpperCase()+' ACTIVE';store('myr5-pod-power-v1',p);}\r\n // Each real preparation/working rest has one stable boss. Reopening a view\r\n // cannot create a new defeat, and practice rests never grant packs.\r\n function restEncounter(now){const active=flow.active,c=active?.restRewardsContext;if(!active?.localId||!c||flow.preview||performanceOwner()!==c.owner)return null;const stage=flow.workout?.stage==='preparation-rest'?(flow.workout.nextStage==='working'?'preparation-2':'preparation-1'):'working';return {id:`${active.localId}:${stage}`,context:{...c,day:localDay(now)}};}\r\n flow.beforeRestAttack=now=>{const fight=restEncounter(now);if(!fight){flow.restBossId=null;return;}const identity=fight.context.day+':'+fight.id;if(flow.restBossId!==identity){flow.restBossId=identity;flow.damage=hasRestBossDefeat(fight.id,fight.context)?bossHealthMax(flow.kitLevel):0;flow.lastPetTick=now;}};\r\n flow.onRestDamage=now=>{if(flow.coachHealth>0)return;const fight=restEncounter(now);if(!fight)return;void recordRestBossDefeatExclusive(fight.id,fight.context).then(result=>{if(performanceOwner()!==fight.context.owner)return;if(result.recorded){const message=result.granted.length?`Boss defeated! ${result.granted.map(p=>p.tier+' pack').join(' + ')} earned.`:`Boss defeated! ${result.count}/5 today.`;$('restFeedback').textContent=message;voice.say(message,{interrupt:true});}}).catch(()=>{});};\r\n function syncCombat(){flow.weapon=arena.weapon;const p=flow.combat;$('shieldNote').textContent=p?`${p.loginStreak} login days × weapon level ${arena.weapon.tier+1}${p.breathingCompleted?' ×100 breathing':''} · ${flow.attackDamage} damage`:`BASE POWER · ${flow.attackDamage} damage`;}\r\n function specialControls(){syncCombat();const weapon=arena.weapon,ability=abilityFor(weapon),remaining=flow.abilities.remaining(),button=$('weaponSpecial');const locked=flow.kitLevel<SPECIAL_LEVEL;button.disabled=flow.phase!=='rest'||locked||!ability||remaining>0;button.textContent=locked?`Special · level ${SPECIAL_LEVEL}`:!ability?'Special · tier 4':remaining?`${ability.name} · ${Math.ceil(remaining/1000)}s`:ability.name;$('weaponCooldown').value=remaining?Math.max(0,1-remaining/Math.max(1,flow.abilities.durationMs)):1;}\r\n $('coachPower').value=loadPower({getItem:safeRead});power();\r\n function paintHealth(){const hp=Math.ceil(flow.coachHealth),max=bossHealthMax(flow.kitLevel);$('coachHealth').textContent=hp.toLocaleString()+' HP';$('bossHealth').style.width=(hp/max*100)+'%';$('bossHealth').parentElement.setAttribute('aria-valuenow',String(hp));}\r\n function speakChallenge(){if(pendingChallenge&&flow.phase==='rest'&&!document.hidden&&!document.body.dataset.cinematic){const text=pendingChallenge;pendingChallenge=null;voice.say(text,{key:'challenge',interrupt:true});}}\r\n window.addEventListener('myr5:cinematic-end',speakChallenge);\r\n function tick(){\r\n  if(preparationRest){\r\n   const w=flow.workout,now=Date.now();w?.advancePreparationRecovery(now);\r\n   if(w?.stage!=='preparation-rest'){exitPreparation();return;}\r\n   setFlipValue($('restTime'),clockDigits(Math.max(0,Math.ceil((w.recoveryUntil-now)/1000))),'preparation recovery remaining');\r\n   specialControls();return;\r\n  }\r\n  if(flow.phase!=='rest')return;speakChallenge();const now=Date.now();if(flow.shouldEndRest(now)){leave();return;}specialControls();const remaining=flow.remaining(now),next=route.suggestion();setFlipValue($('restTime'),clockDigits(remaining),'recovery remaining');$('nextSet').disabled=remaining>0||!next;$('nextSet').textContent=remaining?'Recovering…':awaitingRound?'Waiting to sync…':next?'Preview next round →':'Finished for today';if(!remaining&&!restCalled&&!document.hidden){restCalled=true;voice.say('Rest complete. Keep tapping to stay.',{interrupt:true});}\r\n }\r\n\r\n // Fruit Ninja rest layer: lazy so the game stays out of the core bundle.\r\n const SLICE_GAME='/arcade/slice/rest-game.mjs'; // variable path: esbuild leaves it alone, so the game stays out of the core bundle\r\n let slice=null,sliceLoadGeneration=0;\r\n const restTargetsActive=()=>shouldStartRestTargets(flow.phase,preparationRest),sliceHost=()=>document.querySelector('.encounter');\r\n function retrySlice(){if(!slice&&restTargetsActive())startSlice();}\r\n function startSlice(){\r\n  if(slice||!restTargetsActive())return;\r\n  const generation=++sliceLoadGeneration;\r\n  import(SLICE_GAME).then(m=>{\r\n   if(generation!==sliceLoadGeneration||slice||!restTargetsActive())return;\r\n   const instance=m.mountRestGame(sliceHost(),{avatar:$('restAvatar'),attackButton:$('attackCoach'),feedback:$('restFeedback'),sound:k=>physicalSound.play(k)});\r\n   slice=instance;instance.start();\r\n  }).catch(error=>{\r\n   if(generation!==sliceLoadGeneration||!restTargetsActive())return;\r\n   slice?.stop();slice=null;console.error('Rest targets failed to start',error);\r\n   $('restFeedback').textContent='Targets failed to load. Tap the scene to retry.';\r\n   sliceHost()?.addEventListener('pointerdown',retrySlice,{once:true});\r\n  });\r\n }\r\n function stopSlice(){sliceLoadGeneration++;sliceHost()?.removeEventListener('pointerdown',retrySlice);slice?.stop();slice=null;}\r\n function enterRest(result=null){preparationRest=false;setPreparationControls(false);\r\n  flow.kitLevel=combatLevel(result?.mode||currentMode||'squat');flow.beforeRestAttack(Date.now()); // real battle-pass level for this boss's track (D8/D22)\r\n  for(const id of ['settings','identity'])if($(id).open)$(id).close();\r\n  document.body.dataset.screen='rest';$('homeScreen').hidden=true;$('restScreen').hidden=false;\r\n  $('restEyebrow').textContent=result?'SET COMPLETE':'REST PRACTICE';$('restHeading').textContent='Rest';\r\n  if(result)route.showResult();else route.hideResult();\r\n  $('setReceipt').textContent=result?`${result.name} · ${Math.round(result.value)} ${['hold','sprint','gentle'].includes(result.kind)||movements[result.mode].kind==='pace'?'seconds':movements[result.mode].kind==='steps'?'steps':movements[result.mode].kind==='jumps'?'jumps':'reps'}`:'Practice';\r\n  $('earnedXp').textContent=result?.earned?`+${result.xp} XP`:'NO XP';$('damageTotal').textContent=Math.round(flow.damage)+' DAMAGE';paintHealth();\r\n  syncCombat();\r\n  $('restFeedback').textContent='Every third tap: team strike';hand.enter();arena.start();startSlice();restCalled=false;lastSpoken=-Infinity;paintGuest();updateProgress();moveCoach();\r\n  clearInterval(restTimer);restTimer=setInterval(tick,250);tick();\r\n  history.replaceState(null,'','#rest');window.myr5Creature?.play(result?'celebrate':'rest');\r\n }\r\n // #150: into rest through the wormhole. The rest timer started with the set, so the time until rest shows (the save, the trip in) is added back;\r\n // the heading's focus and the voice line wait until the tunnel has opened.\r\n async function toRest(result=null,{silent=false,started=Date.now()}={}){\r\n  await throughWormhole(result?LINES.rest:LINES.practice,()=>{if(flow.phase!=='rest')return;flow.restUntil+=Date.now()-started;enterRest(result);});\r\n  if(flow.phase!=='rest')return;\r\n  $('restHeading').focus();if(!silent)voice.say(result?'Set complete. Take a breath.':'Tap to strike.',{interrupt:true});\r\n }\r\n async function persistResult(result,m,now){\r\n  const before={...flow.progress},id=flow.active?.localId,manual=flow.active?.control==='manual',owner=flow.active?.performanceOwner;\r\n  let coachId;try{coachId=JSON.parse(safeRead('myr5-recipe-v1')||'null')?.body;}catch{}\r\n  const earningProgress=readPerformanceProgress({owner}),earnedCoachCount=new Set(earningProgress.coaches.filter(id=>!STARTER_COACH_IDS.includes(id))).size;\r\n  const performance={...result,id,day:localDay(now),earnedCoachCount,performanceOwner:owner,...(coachId?{coachId}: {})};\r\n  const saved=await workoutOwner.complete({id,value:result.value,activeSeconds:result.activeSeconds||m.active||0,elapsedSeconds:m.elapsed||0,earned:result.earned,progress:{...flow.progress,value:result.value,performanceOwner:owner,performance,performanceWorkout:flow.workout?.snapshot()}});\r\n  if(!saved.saved){flow.progress=before;flow.phase='set';if(flow.workout)flow.workout.finished=false;throw Error(saved.reason);}\r\n  const priorXp=readPerformanceProgress({owner}).totalXp,progress=recordPerformanceSession(performance,{owner});result.xp=Math.max(0,progress.totalXp-priorXp);flow.performanceXp=progress.totalXp;flow.progress.completedSets++;\r\n  window.dispatchEvent(new Event('myr5:local-history-refresh'));window.dispatchEvent(new CustomEvent('myr5:set-complete',{detail:{mode:result.mode,value:result.value,xp:result.xp,earned:result.earned}}));onStop();await toRest(result,{silent:manual,started:now});return true;\r\n }\r\n async function consume(m,now){const result=flow.consume({...m,manual:flow.active?.control==='manual'},now);publishInstruction();if(!result)return false;return persistResult(result,m,now);}\r\n async function finishWorking(m,now=Date.now()){const result=flow.finishWorking({...m,manual:flow.active?.control==='manual'},now);return result?persistResult(result,m,now):false;}\r\n function setPreparationControls(active){\r\n  for(const id of ['leaveRest','nextSet','moreRest'])$(id).hidden=active;\r\n  $('restTime').style.fontSize=active?'28px':'';\r\n }\r\n function enterPreparation(){\r\n  const w=flow.workout;if(preparationRest||flow.phase!=='set'||w?.stage!=='preparation-rest')return;\r\n  preparationRest=true;flow.kitLevel=combatLevel(flow.active.mode);flow.beforeRestAttack(Date.now());\r\n  document.body.dataset.screen='rest';document.body.dataset.preparationRest='true';$('homeScreen').hidden=true;$('restScreen').hidden=false;\r\n  $('restEyebrow').textContent='PREPARATION';$('restHeading').textContent='Recovery';\r\n  $('setReceipt').textContent=w.nextStage==='working'?'Final warm-up complete':'Warm-up complete';\r\n  $('earnedXp').textContent='NO XP';$('restFeedback').textContent='Recover, then training resumes automatically.';\r\n  route.hideResult();setPreparationControls(true);$('damageTotal').textContent=Math.round(flow.damage)+' DAMAGE';paintHealth();syncCombat();\r\n  hand.enter();arena.start();startSlice();paintGuest();updateProgress();moveCoach();\r\n  clearInterval(restTimer);restTimer=setInterval(tick,250);\r\n  window.dispatchEvent(new CustomEvent('myr5:preparation-rest-start',{detail:{stage:w.stage,nextStage:w.nextStage,recoveryUntil:w.recoveryUntil}}));tick();\r\n }\r\n function exitPreparation({resume=true}={}){\r\n  if(!preparationRest)return;\r\n  preparationRest=false;delete document.body.dataset.preparationRest;hand.leave();arena.stop();stopSlice();clearInterval(restTimer);clearTimeout(hitTimer);\r\n  setPreparationControls(false);$('restScreen').hidden=true;$('homeScreen').hidden=false;document.body.dataset.screen='pod';\r\n  const coachOverlay=document.getElementById('coachOverlay');if(coachOverlay&&card&&document.body.dataset.tracking==='true')coachOverlay.append(card);\r\n  moveCoach();\r\n  if(resume){window.dispatchEvent(new CustomEvent('myr5:preparation-rest-end',{detail:{stage:flow.workout?.stage,mode:flow.active?.mode}}));publishInstruction();}\r\n }\r\n\r\n let lastInstruction='';\r\n function publishInstruction(){if(flow.phase==='set'&&flow.workout?.stage==='preparation-rest')enterPreparation();else if(preparationRest)exitPreparation();const instruction=flow.workout?.instruction??'';if(instruction===lastInstruction)return;lastInstruction=instruction;window.dispatchEvent(new CustomEvent('myr5:workout-stage',{detail:{stage:flow.workout?.stage,instruction,mode:flow.active?.mode}}));}\r\n function workoutMotion(m){const w=flow.workout;if(!w)return m;const cardio=['sprint','gentle'].includes(w.kind);return {...m,kind:cardio?'pace':m.kind,active:cardio?w.activeSeconds:m.active,count:w.kind==='reps'?w.value:m.count,totalHold:w.kind==='hold'?w.activeSeconds:m.totalHold,message:w.instruction,remaining:Math.max(0,(w.recoveryUntil-Date.now())/1000)};}\r\n async function saveManual(m){const id=flow.active?.localId;if(!id)return null;const value=valueOf(m),progress={...flow.progress,value,performanceOwner:flow.active?.performanceOwner,activeSeconds:m.active||0,elapsedSeconds:m.elapsed||0,performanceWorkout:flow.workout?.snapshot()};await workouts.update(id,progress);flow.active.savedProgress=progress;return progress;}\r\n async function pauseManual(m){const id=flow.active?.localId;if(!id)return null;const progress=await saveManual(m),workout=await workouts.pause(id,progress);exitPreparation({resume:false});pausedLocal=workout;flow.leave();return workout;}\r\n async function interruptCurrent(m){exitPreparation({resume:false});const id=flow.active?.localId;let timer;try{if(id)await Promise.race([workouts.interrupt(id,{...flow.progress,performanceOwner:flow.active?.performanceOwner,performanceWorkout:flow.workout?.snapshot(),value:m?valueOf(m):0,activeSeconds:m?.active||0,elapsedSeconds:m?.elapsed||0}),new Promise((_,reject)=>{timer=setTimeout(()=>reject(Error('Workout cleanup timed out. Reload Coach before starting again.')),5000);})]);}finally{clearTimeout(timer);if(flow.phase==='set')flow.leave();pausedLocal=null;workoutOwner.stop();route.render();circuit.render();}}\r\n // #150: the trips out of rest stop its timer first, so the idle end can't leave() under the tunnel.\r\n // #56: the ↗ exit goes home to the quilt (clears the hash, closes the route); \"Next set →\" stays in the pod.\r\n function leave({home=false}={}){exitPreparation({resume:false});pendingChallenge=null;hand.leave();arena.stop();stopSlice();clearInterval(restTimer);clearTimeout(hitTimer);voice.cancel();flow.leave();document.body.dataset.screen='pod';$('restScreen').hidden=true;$('homeScreen').hidden=false;moveCoach();if(home){history.replaceState(null,'',location.pathname+location.search);window.myr5Routes?.home?.();}else history.replaceState(null,'','#pod');$('start').disabled=!workoutEligibility(currentMode).allowed;route.render();circuit.render();$('start').focus();}\r\n document.querySelector('.encounter').addEventListener('pointerdown',()=>flow.touchRest(Date.now()),{passive:true});\r\n $('attackCoach').addEventListener('click',()=>{\r\n  syncCombat();const now=Date.now(),hit=preparationRest?flow.preparationTap(now,true):flow.tap(now,true);if(!hit)return;\r\n  if(preparationRest)window.dispatchEvent(new CustomEvent('myr5:preparation-hit',{detail:hit}));\r\n  // Spectacle only (D7): no gameplay listens for this, boss attacks never touch player HP.\r\n  if(hit.bossAttack)window.dispatchEvent(new CustomEvent('myr5:boss-attack',{detail:{level:flow.kitLevel}}));\r\n  hand.hit(hit);arena.attack(hit);window.myr5Creature?.play(hit.assisted?'encourage':hit.blocked?'agree':'rest');\r\n  $('damageTotal').textContent=Math.round(hit.totalDamage)+' DAMAGE';paintHealth();$('damageFloat').textContent=hit.blocked?(hit.assisted?'TEAM STRIKE · BLOCKED':'BLOCKED · 0'):(hit.assisted?'TEAM −':'−')+Math.round(hit.damage);\r\n  const scene=document.querySelector('.encounter');scene.classList.remove('hit');void scene.offsetWidth;scene.classList.add('hit');clearTimeout(hitTimer);hitTimer=setTimeout(()=>scene.classList.remove('hit'),650);\r\n  $('restFeedback').textContent=hit.blocked?`${POWERS[$('coachPower').value].line} ${hit.hits} ${hit.hits===1?'hit':'hits'}, zero damage.`:`${hit.assisted?'Helping Hand lands a team strike! ':''}${hit.hits} hits. ${hit.totalDamage} damage.`;\r\n  if(now-lastSpoken>10000){lastSpoken=now;window.myr5Creature?.play(hit.blocked?'agree':'encourage');voice.say(hit.blocked?'Nice teamwork. My shield is still intact. Keep training.':'You and that hand make quite a team. That one connected.',{key:'rest'});}\r\n });\r\n $('leaveRest').addEventListener('click',()=>{clearInterval(restTimer);void throughWormhole(LINES.home,()=>leave({home:true}));});$('moreRest').addEventListener('click',()=>{flow.extend(30,Date.now());restCalled=false;tick();voice.say('Thirty more seconds. Take your time.',{interrupt:true});});\r\n $('weaponSpecial').addEventListener('click',async()=>{\r\n  const activate=()=>{syncCombat();flow.abilities.merge(safeRead(COOLDOWN));const result=flow.special(arena.weapon,{now:Date.now(),progress:arena.progress,catalog:window.GalaWeapons});if(result.ok)store(COOLDOWN,JSON.stringify(flow.abilities.snapshot()));return result;};\r\n  const hit=navigator.locks?.request?await navigator.locks.request('myr5-weapon-special',activate):activate();if(!hit.ok){specialControls();return;}\r\n  arena.attack(hit);window.myr5Creature?.play(hit.blocked?'agree':'rest');\r\n  $('damageTotal').textContent=Math.round(hit.totalDamage)+' DAMAGE';paintHealth();\r\n  $('damageFloat').textContent=hit.blocked?'BLOCKED':'−'+hit.damage;$('restFeedback').textContent=hit.ability.name+(hit.blocked?' · Shielded':'');\r\n  const scene=document.querySelector('.encounter');scene.classList.remove('hit');void scene.offsetWidth;scene.classList.add('hit');clearTimeout(hitTimer);hitTimer=setTimeout(()=>scene.classList.remove('hit'),650);specialControls();\r\n });\r\n $('nextSet').addEventListener('click',async()=>{const next=route.suggestion();if(flow.remaining(Date.now())>0||!next)return;clearInterval(restTimer);await throughWormhole(LINES.next,leave);onNext(next);});\r\n $('visitRest').hidden=true;$('visitRest').disabled=true;\r\n $('openSettings').addEventListener('click',()=>{$('settings').showModal();voice.say('Pod controls.',{interrupt:true});});$('closeSettings').addEventListener('click',()=>$('settings').close());\r\n $('coachPower').addEventListener('change',()=>{power();voice.say(POWERS[$('coachPower').value].name+' selected.',{interrupt:true});});\r\n $('restDuration').addEventListener('change',()=>voice.say($('restDuration').value+' seconds between sets.',{interrupt:true}));\r\n $('openIdentity').addEventListener('click',()=>{paintGuest();$('identity').showModal();voice.say('Your Gala character.',{interrupt:true});});$('closeIdentity').addEventListener('click',()=>$('identity').close());\r\n $('importGala').addEventListener('change',async event=>{const f=event.target.files?.[0];if(!f)return;try{if(f.size>30000)throw Error('Choose your exported Gala look file.');const imported=importGala(await f.text(),avatar);if(!store(GALA_KEY,JSON.stringify(imported)))throw Error('Could not save this appearance on your device.');paintGuest();$('identityStatus').textContent='Appearance saved';voice.say('Appearance saved',{interrupt:true});}catch(error){$('identityStatus').textContent=error instanceof SyntaxError?'That file is not a Gala look.':error.message;}finally{event.target.value='';}});\r\n window.addEventListener('storage',e=>{if(e.key===GALA_KEY)paintGuest();});window.addEventListener('mominc-avatar-change',paintGuest);\r\n window.addEventListener('storage',e=>{if(e.key===COOLDOWN){flow.abilities.merge(e.newValue);if(flow.phase==='rest')specialControls();}});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden){voice.cancel();if(flow.phase==='rest')leave();}else tick();});\r\n window.addEventListener('myr5:route-leave',()=>{if(flow.phase==='rest')leave();});\r\n window.addEventListener('pagehide',()=>{hand.dispose();arena.dispose();clearInterval(restTimer);clearTimeout(hitTimer);observer.disconnect();});\r\n document.querySelector('.mom-brand').addEventListener('click',event=>{event.preventDefault();if(flow.phase==='rest')leave();});\r\n paintGuest();updateProgress();document.body.dataset.screen='pod';\r\n // The idle pod shows no \"Ready\" line: #status only appears while it has something to say (a set's hints, an error).\r\n const statusLine=$('status'),syncStatus=()=>{const quiet=idleStatus(statusLine.textContent);if(statusLine.hidden!==quiet)statusLine.hidden=quiet;};\r\n new MutationObserver(syncStatus).observe(statusLine,{childList:true,characterData:true,subtree:true});syncStatus();\r\n const requestedPanel=new URLSearchParams(location.search).get('panel');if(['avatar','hand'].includes(requestedPanel)){$('identity').showModal();if(requestedPanel==='hand')hand.edit();}\r\n window.addEventListener('myr5:account-progress',({detail:p})=>{flow.combat=p.combat;flow.progress.completedSets=p.completedSets;flow.progress.circuit=p.circuit||null;store(PROGRESS,JSON.stringify(flow.progress));for(const option of $('coachPower').options){if(option.value!=='shield'){option.disabled=!p.unlocks[option.value];option.textContent=POWERS[option.value].name+(option.disabled?' · Locked':'');}}if($('coachPower').selectedOptions[0]?.disabled)$('coachPower').value='shield';power();updateProgress();});\r\n window.addEventListener('myr5:performance-progress',()=>{updateProgress();if(flow.phase==='pod')$('start').disabled=!workoutEligibility(currentMode).allowed;});\r\n window.addEventListener('myr5:round-rejected',({detail})=>{if(awaitingRound?.id!==detail.id)return;awaitingRound=null;pendingChallenge=null;$('setReceipt').textContent=detail.message;$('earnedXp').textContent='NO XP';route.render();circuit.render();});\r\n window.addEventListener('myr5:account-progress',({detail:p})=>{if(awaitingRound&&p.lastSyncedWorkoutId===awaitingRound.id){awaitingRound=null;route.render();if(flow.phase==='rest'&&!flow.preview){const next=route.suggestion();pendingChallenge=(next?.line||ROUTE_LINES.limit)+' '+ROUTE_LINES.rest;speakChallenge();}}if(document.body.dataset.tracking!=='true')$('start').disabled=!workoutEligibility(currentMode).allowed;route.render();});\r\n // Reading a paused draft must never hold the only Begin lease. IndexedDB may be slow or\r\n // blocked after a tab was closed, while a fresh camera set can still be requested.\r\n void workouts.paused().then(paused=>{if(flow.phase==='pod')pausedLocal=paused;route.render();}).catch(()=>{});\r\n return {leave:()=>{if(flow.phase==='rest'){clearInterval(restTimer);leave();}},flow,workoutOwner,rebaseTracking:()=>flow.workout?.rebaseTracking(),preparationTap:()=>{const hit=flow.preparationTap();if(hit)window.dispatchEvent(new CustomEvent('myr5:preparation-hit',{detail:hit}));return hit;},configure,beginSet,consume,setCardioStyle:style=>{if(!['gentle','sprint'].includes(style))throw Error('Choose gentle cardio or sprint intervals.');if(flow.phase==='set')throw Error('Choose cardio style before starting.');cardioStyle=style;},switchDifficulty:style=>flow.workout?.switchDifficulty(style),finishWorking,workoutMotion,canCount:()=>flow.workout?.counting??true,breakHold:()=>{flow.workout?.breakHold();publishInstruction();},resumeHold:()=>{flow.workout?.resumeHold();publishInstruction();},extendHoldRecovery:()=>flow.workout?.extendRecovery(),saveManual,pauseManual,interruptCurrent,render,setGoal,canStart:mode=>(workoutOwner.canStart()||pausedLocal?.mode===mode)&&workoutEligibility(mode).allowed,encouragement:(m,now,events)=>flow.phase==='set'?encourage.update(m,flow.active.goal,now,events):null,stopped:interruptCurrent,goal:()=>Number($('goal').value)};\r\n}\r\n","pod/rest-arena.css":".encounter{min-height:390px;border:1px solid #b797c655;border-radius:26px;overflow:hidden;background:radial-gradient(ellipse at 68% 29%,#673d7838,transparent 45%),linear-gradient(#171026,#261c38);box-shadow:inset 0 0 45px #05020f99}.encounter-grid{opacity:.45}.rest-coach-mount{inset:6% 6% 29% 26%}.attack-target{inset:10% 5% 31% 28%}.coach-battle-platform{position:absolute;left:32%;right:7%;bottom:32%;height:45px;border-radius:50%;border:2px solid #edbd8555;background:repeating-radial-gradient(ellipse,#574155 0 8px,#8b686a 9px 10px);box-shadow:0 7px 0 #2a2037,0 9px 0 #977ca9,0 18px 24px #03000888;z-index:1}.player-platform{left:30%;bottom:12%;width:185px;height:50px}.platform-top{background:repeating-radial-gradient(ellipse,#324353 0 11px,#568b9a 12px 13px);border-color:#8de8d5;box-shadow:0 0 19px #64f5d344}.platform-edge{background:linear-gradient(#537287,#192031);border-color:#8bddd7;box-shadow:0 4px 0 #57b8ba,0 10px 24px #47cecf22}.platform-thruster{background:linear-gradient(#89ffde99,transparent)}#restAvatar{width:150px;height:158px;left:18px;bottom:15px}.rest-hand{left:auto;right:3%;bottom:10%;width:clamp(115px,32vw,175px);height:clamp(135px,38vw,200px)}.player-name{bottom:12px;gap:5px;flex-wrap:wrap;padding:0 8px;text-align:center;line-height:1.3}.player-name #restGuest{max-width:75%;overflow-wrap:anywhere}.rest-weapon-name{position:absolute;left:14px;bottom:30%;color:#9debd9;font:9px monospace;max-width:145px;z-index:9}.boss-status{z-index:9;padding:9px 12px}.attack-target span{font-size:9px;letter-spacing:1px;bottom:12px}.attack-flash{left:44%;top:27%}.projectile{left:31%;bottom:42%;background:#afffe7;box-shadow:0 0 12px #63ffc6;transform:rotate(38deg)}.encounter.hit .projectile{animation:arena-bolt .3s ease-in}.encounter[data-weapon=melee].hit .projectile{height:65px;width:65px;border-top:4px solid #b8ffeb;border-radius:50%;background:none;box-shadow:none;animation:arena-slash .35s ease-out}.encounter.team-strike.hit .attack-flash{border-width:5px;box-shadow:0 0 30px #e6b4ff99}.encounter.team-strike.hit .projectile{filter:drop-shadow(8px 5px 2px #cf95ff)}.encounter.hit #restAvatar{animation:none}.weapon-subsection{padding:15px;margin-top:15px;border:1px solid #7c8eaa;border-radius:12px;background:#13253166;text-align:left}.weapon-subsection h3{margin:0 0 10px;color:#b7fce4}.weapon-subsection label{display:block;font-size:13px;margin:10px 0}.level-bar{display:block;width:100%;height:10px;accent-color:#7cf0cf}.weapon-subsection select{display:block;width:100%;margin-top:5px}.weapon-subsection p{margin-bottom:0!important}@keyframes arena-bolt{0%{opacity:1;transform:translate(0,0) rotate(38deg)}100%{opacity:.3;transform:translate(105px,-130px) rotate(38deg)}}@keyframes arena-slash{0%{opacity:0;transform:translate(40px,-50px) rotate(-70deg)}50%{opacity:1}100%{opacity:0;transform:translate(100px,-100px) rotate(65deg)}}@media(max-width:370px){.encounter{min-height:350px}.player-platform{width:160px}.rest-hand{right:0;width:112px;height:138px}#restAvatar{left:5px}.rest-weapon-name{max-width:110px;font-size:8px}}@media(prefers-reduced-motion:reduce){.encounter.hit .projectile{animation:none;opacity:.7}.encounter.hit .attack-flash{animation:none;opacity:.4}}\r\n","pod/rest-arena.mjs":"import {GALA_KEY,loadGala} from './identity.mjs';\r\nimport {abilityFor,evolution} from './weapon-evolution.mjs';\r\nimport {drawAnimatedWeapon} from './weapon-animator.mjs';\r\nimport {createOptionalModuleLoader} from '../arcade/workout-effects-state.mjs';\r\nconst loadPowerState=createOptionalModuleLoader('/arcade/power/avatar-power.mjs');\r\nconst loadPowerRenderer=createOptionalModuleLoader('/arcade/power/power.mjs');\r\nconst loadBlizzardRenderer=createOptionalModuleLoader('/arcade/hold/blizzard.mjs');\r\nexport const MELEE=new Set(['rapier','greatsword','dagger','spear','trident','scythe','gauntlets']);\r\nexport function equipmentProgress(value={}){return {activeDays:Math.max(0,Number(value.activeDays)||0),totalXp:Math.max(0,Number(value.activeDays)||0)*100,completedSets:Math.max(0,Number(value.completedSets)||0),strength:1+Math.floor(Math.max(0,Number(value.completedSets)||0)/4),...(value.trainingVersion===1?{trainingVersion:1,training:value.training}:{})};}\r\n\r\nexport function initRestArena(){\r\n const A=window.GalaAvatar,W=window.GalaWeapons,canvas=document.getElementById('restAvatar'),scene=document.querySelector('.encounter');\r\n const fx=document.getElementById('restWeaponFx'),type=document.getElementById('weaponType'),tier=document.getElementById('weaponTier'),note=document.getElementById('weaponStatus'),bar=document.getElementById('weaponLevelBar');\r\n const body=document.createElement('canvas'),reduced=matchMedia('(prefers-reduced-motion: reduce)');\r\n let progress=equipmentProgress(),look=null,equipped={type:'rapier',tier:0},running=false,frame=0,last=0,action=null,queued=false;\r\n let powerRecord={version:1,equipped:null,styles:{}},powerOwnerId=null,powerFingerprint='',powerModule=null,powerRenderer=null,blizzardModule=null,powerSchedule=null,powerLoading=null,powerLoadToken=0,powerTime=0,powerPulse=0,lastPowerAt=0,powerArt=null,powerArtCtx=null;\r\n let anchor={x:0,y:0,scale:1},lastWeapon='';\r\n canvas.width=160;canvas.height=168;\r\n window.GalaProgress={read:()=>progress};\r\n for(const item of W.types){const option=document.createElement('option');option.value=item.id;option.textContent=item.name;type.append(option);}\r\n function measure(){\r\n  const bounds=scene.getBoundingClientRect(),avatar=canvas.getBoundingClientRect();\r\n  if(!bounds.width||!bounds.height)return;\r\n  const ratio=Math.min(1,Math.max(320,Math.round(bounds.width/2))/bounds.width);\r\n  fx.width=Math.round(bounds.width*ratio);fx.height=Math.round(bounds.height*ratio);\r\n  anchor={x:(avatar.left+avatar.width*.78-bounds.left)*ratio,y:(avatar.top+avatar.height*.48-bounds.top)*ratio,scale:ratio*1.15};\r\n }\r\n const hasPower=()=>!!powerRecord.styles?.[powerRecord.equipped];\r\n function resetPower(){powerSchedule?.reset();powerTime=0;powerPulse=0;lastPowerAt=0;}\r\n function makePowerArt(){if(powerArtCtx)return;powerArt=document.createElement('canvas');powerArt.width=160;powerArt.height=168;powerArtCtx=powerArt.getContext('2d',{alpha:true});if(!powerArtCtx){powerArt=null;return;}powerArtCtx.imageSmoothingEnabled=false;}\r\n function ensurePowerRenderer(){\r\n  if(powerModule&&powerRenderer&&blizzardModule&&powerSchedule){if(running)draw(performance.now());return;}\r\n  if(powerLoading||!hasPower())return;\r\n  const token=++powerLoadToken;\r\n  powerLoading=Promise.all([loadPowerState(),loadPowerRenderer(),loadBlizzardRenderer()])\r\n   .then(([avatar,power,blizzard])=>{if(token!==powerLoadToken||!hasPower())return;powerModule=avatar;powerRenderer=power;blizzardModule=blizzard;powerSchedule=avatar.createAvatarPowerSchedule({seed:0x525354});makePowerArt();resetPower();if(running)draw(performance.now());})\r\n   .catch(()=>{}).finally(()=>{if(token===powerLoadToken)powerLoading=null;});\r\n }\r\n function requestPowerSnapshot(){if(typeof CustomEvent==='function')window.dispatchEvent(new CustomEvent('myr5:retained-character-power-request'));}\r\n function retainedPower(event){const detail=event?.detail;if(!detail||typeof detail.ownerId!=='string')return;const next=detail.record&&typeof detail.record==='object'?detail.record:{version:1,equipped:null,styles:{}};const fingerprint=JSON.stringify(next);if(detail.ownerId===powerOwnerId&&fingerprint===powerFingerprint){if(hasPower())ensurePowerRenderer();return;}powerOwnerId=detail.ownerId;powerFingerprint=fingerprint;powerLoadToken++;powerLoading=null;powerRecord=next;resetPower();if(hasPower())ensurePowerRenderer();else if(look)draw(performance.now());}\r\n function load(){\r\n  try{look=loadGala(localStorage,A).look;}catch{look=structuredClone(A.defaultLook);}\r\n  const selected=look.weapon||{type:'rapier',tier:0};\r\n  equipped=W.unlocked(selected,progress)?selected:{type:selected.type,tier:0};\r\n  const key=equipped.type+':'+equipped.tier;if(lastWeapon!==key){action=null;queued=false;lastWeapon=key;}\r\n  A.draw(body,look,{base:false,weapon:false,prop:false});type.value=selected.type;tier.replaceChildren();\r\n  for(let i=0;i<W.tiers.length;i++){const item={type:selected.type,tier:i},option=document.createElement('option');option.value=i;option.disabled=!W.unlocked(item,progress);option.textContent=`${W.tiers[i]} · Level ${i+1}`;tier.append(option);}\r\n  tier.value=equipped.tier;const ability=abilityFor(equipped);\r\n  const lv=W.level(progress);\r\n  note.textContent=`Level ${lv.level} · `+(lv.max?'max level':`${lv.into}/${lv.need} XP to next`)+' · '+(ability?`${ability.name} · ${ability.cooldownMs/1000}s`:'Special at tier 4');\r\n  if(bar){bar.max=lv.max?1:lv.need;bar.value=lv.max?1:lv.into;bar.setAttribute('aria-valuetext',`Level ${lv.level}`+(lv.max?'':`, ${lv.into} of ${lv.need} XP`));}\r\n  if(selected.tier!==equipped.tier)note.textContent+=' Upgrade not yet earned.';\r\n  document.getElementById('restWeaponName').textContent=W.types.find(w=>w.id===equipped.type).name;\r\n  scene.dataset.weapon=MELEE.has(equipped.type)?'melee':'ranged';scene.classList.add('weapon-evolution');\r\n  scene.style.setProperty('--weapon-energy',evolution(equipped).energy);\r\n  measure();draw(performance.now());\r\n }\r\n function equip(){try{const next={type:type.value,tier:Number(tier.value)};if(!W.unlocked(next,progress))return;localStorage.setItem(GALA_KEY,JSON.stringify({...look,weapon:next}));window.dispatchEvent(new Event('mominc-avatar-change'));}catch{note.textContent='Could not save this weapon.';}}\r\n type.addEventListener('change',()=>{if(!W.unlocked({type:type.value,tier:Number(tier.value)},progress))tier.value='0';equip();});tier.addEventListener('change',equip);\r\n function duration(){return action?.special?abilityFor(equipped)?.animationMs||1100:evolution(equipped).attackMs;}\r\n function draw(now){\r\n  if(action&&now-action.startedAt>=duration()){action=queued?{startedAt:now,special:false}:null;queued=false;}\r\n  const ctx=canvas.getContext('2d');ctx.clearRect(0,0,160,168);ctx.imageSmoothingEnabled=false;\r\n  const pulse=action&&!reduced.matches?Math.sin(Math.min(1,(now-action.startedAt)/duration())*Math.PI):0;\r\n  ctx.drawImage(body,26+pulse*4,14-pulse*5,96,144);\r\n  if(powerSchedule&&powerModule&&powerRenderer&&blizzardModule){\r\n   const dt=lastPowerAt?Math.max(0,Math.min(.25,(now-lastPowerAt)/1000)):0;lastPowerAt=now;\r\n   const canShow=running&&!document.hidden&&hasPower(),active=canShow?powerSchedule.step(dt,true,reduced.matches):0;\r\n   if(active){powerTime+=reduced.matches?0:dt;if(powerPulse<=0)powerPulse=1;if(reduced.matches)powerPulse=0;else powerPulse=Math.max(0,powerPulse-dt*2.5);\r\n    const feet=[{index:27,x:.46,y:.835,visible:true},{index:28,x:.54,y:.835,visible:true}],state=powerModule.avatarPowerState(powerRecord,160,168,reduced.matches?0:powerTime,reduced.matches?0:powerPulse,false,feet);\r\n    if(state&&powerArtCtx){powerArtCtx.clearRect(0,0,160,168);if(state.blizzard)blizzardModule.renderBlizzard(powerArtCtx,state);else powerRenderer.renderPower(powerArtCtx,state);ctx.save();ctx.globalAlpha=.55;ctx.translate(-6+pulse*4,1-pulse*5);ctx.drawImage(powerArt,0,0);ctx.restore();}\r\n   }else{powerPulse=0;if(!canShow)powerTime=0;}\r\n  }\r\n  const effects=fx.getContext('2d');effects.clearRect(0,0,fx.width,fx.height);\r\n  effects.save();effects.translate(anchor.x,anchor.y);effects.rotate(-Math.PI/2-.13);\r\n  drawAnimatedWeapon(effects,equipped,{weapons:W,x:0,y:0,scale:anchor.scale,now,action,reducedMotion:reduced.matches});\r\n  effects.restore();\r\n }\r\n function tick(now){frame=0;if(!running||document.hidden)return;if(now-last>(reduced.matches?100:32)){draw(now);last=now;}frame=requestAnimationFrame(tick);}\r\n function start(){running=true;load();if(!frame)frame=requestAnimationFrame(tick);}\r\n function stop(){running=false;action=null;queued=false;if(frame)cancelAnimationFrame(frame);frame=0;resetPower();scene.classList.remove('team-strike');draw(performance.now());}\r\n const visibility=()=>{if(document.hidden){if(frame)cancelAnimationFrame(frame);frame=0;resetPower();draw(performance.now());}else if(running&&!frame){measure();last=0;frame=requestAnimationFrame(tick);}};\r\n const pageshow=()=>{requestPowerSnapshot();if(running&&!document.hidden&&!frame)frame=requestAnimationFrame(tick);};\r\n const account=event=>{progress=equipmentProgress(event.detail);load();};\r\n const resize=new ResizeObserver(measure);resize.observe(scene);\r\n window.addEventListener('myr5:account-progress',account);window.addEventListener('mominc-avatar-change',load);window.addEventListener('myr5:retained-character-power',retainedPower);window.addEventListener('pageshow',pageshow);document.addEventListener('visibilitychange',visibility);load();requestPowerSnapshot();\r\n return {load,start,stop,get weapon(){return {...equipped};},get progress(){return {...progress};},attack(hit){\r\n   const now=performance.now();\r\n   // A special finishes even if the user continues tapping. One queued basic\r\n   // preserves follow-through instead of restarting every windup.\r\n   if(!hit.special&&action&&now-action.startedAt<duration()){\r\n    if(action.special||now-action.startedAt<duration()*.6){queued=true;return;}\r\n   }\r\n   action={startedAt:now,special:!!hit.special};queued=false;\r\n   scene.classList.toggle('team-strike',!!hit.assisted);draw(now);\r\n  },dispose(){stop();powerLoadToken++;powerSchedule?.dispose();powerArt=null;powerArtCtx=null;resize.disconnect();window.removeEventListener('myr5:account-progress',account);window.removeEventListener('mominc-avatar-change',load);window.removeEventListener('myr5:retained-character-power',retainedPower);window.removeEventListener('pageshow',pageshow);document.removeEventListener('visibilitychange',visibility);type.removeEventListener('change',equip);tier.removeEventListener('change',equip);}};\r\n}\r\n","pod/rest-coach-sprite.mjs":"// Rest scene coach while the 3D coach is off (coach3d-flag.mjs): the 64-bit coach sprite, front-facing, standing\r\n// still in front of the user, beside the MOM gun lane. Same sprite source as the Fruit Ninja coach (camera-slice.mjs). Drawn once per call.\r\n// The MOM gun (arcade/slice/rest-game.mjs) hangs top-centre and fires down the middle at the player, so the coach stands\r\n// right of that lane, facing us. No seated frame exists in war-room/coach-sprites.js, so he stands still.\r\nexport const REST_SPRITE={heightPct:46,bottomPct:2,centerPct:70}; // tuning: size/feet/horizontal centre within the rest mount\r\nexport function mountRestCoachSprite(mount){\r\n if(!mount)return null;\r\n let canvas=mount.querySelector('canvas.rest-coach-sprite');\r\n if(!canvas){\r\n  canvas=document.createElement('canvas');canvas.className='rest-coach-sprite';canvas.width=64;canvas.height=96;canvas.setAttribute('aria-hidden','true');\r\n  const aspect=64/96;\r\n  canvas.style.cssText=`position:absolute;left:${REST_SPRITE.centerPct}%;bottom:${REST_SPRITE.bottomPct}%;height:${REST_SPRITE.heightPct}%;aspect-ratio:${aspect};transform:translateX(-50%);image-rendering:pixelated;pointer-events:none;`;\r\n  mount.append(canvas);\r\n }\r\n (async()=>{\r\n  try{const A=window.GalaAvatar,{loadGala}=await import('/pod/identity.mjs'),m=await import('/war-room/coach-sprites.js'),c=await m.loadWarRoomCoaches(document);\r\n   c.draw(A.draw,canvas,loadGala(localStorage,A).look,{});}\r\n  catch{const x=canvas.getContext('2d');x.fillStyle='#bc89ff';x.fillRect(20,30,24,50);x.fillStyle='#fff';x.fillRect(24,36,6,6);x.fillRect(34,36,6,6);}\r\n })();\r\n return canvas;\r\n}\r\n","pod/retro-rooms.css":"/* The original pixel world, with the current coach, Gala equipment and Helping Hand. */\r\n:root{--room-world:url('/pod/worlds/great-wall.webp');--room-pixel:ui-monospace,SFMono-Regular,Consolas,monospace}\r\nbody[data-screen=rest]{overflow:hidden;max-width:none}\r\nbody[data-screen=rest]>.ship-header,body[data-screen=rest] #coachDock.coach-dock,body[data-screen=rest]>.sync-badge{display:none}\r\n#restScreen{position:fixed;inset:0;z-index:30;min-height:0;padding:0;overflow:hidden;display:block;background:#211b32;font-family:var(--room-pixel)}\r\n#restScreen .encounter{position:absolute;inset:0;margin:0;width:100%;height:100%;min-height:0;max-height:none;border:0;border-radius:0;isolation:isolate;background:#413251}\r\n.rest-world-backdrop,.rest-world-floor{position:absolute;inset:0;background:var(--room-world) center/100% 100% no-repeat;image-rendering:pixelated;pointer-events:none}\r\n.rest-world-backdrop{z-index:0}\r\n.rest-world-floor{z-index:4;clip-path:inset(79% 0 0)}\r\n#restScreen .encounter-grid,#restScreen .encounter-orbit{display:none}\r\n#restScreen .rest-coach-mount{position:absolute;inset:4% -6% auto;width:112%;height:76%;z-index:3;pointer-events:none}\r\n#restScreen .rest-coach-mount canvas{image-rendering:pixelated}\r\n#restScreen .coach-battle-platform{left:12%;right:12%;bottom:21%;height:34px;z-index:2;border-radius:0;border:0;clip-path:polygon(0 0,100% 0,96% 75%,72% 100%,28% 100%,4% 75%);background:var(--room-world) center bottom/100% auto;box-shadow:0 5px #171327}\r\n#restScreen .attack-target{inset:18% 0 23%;width:100%;z-index:8;border-radius:0;background:none!important;box-shadow:none!important}\r\n#restScreen .attack-target span{bottom:18%;font:700 14px/1.4 var(--room-pixel);color:#fff4c9;text-shadow:2px 2px #201329,-2px -2px #201329}\r\n#restScreen .player-platform{left:50%;bottom:15%;width:clamp(220px,60vw,580px);height:28px;z-index:6;transform:translateX(-50%)}\r\n#restScreen .platform-top{border-radius:0;clip-path:polygon(3% 0,97% 0,100% 100%,0 100%);border:3px solid #cad1ab;background:var(--room-world) center bottom/100% auto;box-shadow:0 -4px #e2d7a6}\r\n#restScreen .platform-edge{inset:12px 0 -18px;border-radius:0;clip-path:polygon(0 0,100% 0,88% 85%,65% 100%,35% 100%,12% 85%);border-color:#b0a69c;background:linear-gradient(#5a5263,#211c30);box-shadow:none}\r\n#restScreen .platform-thruster{display:none}\r\n#restScreen #restAvatar{left:calc(50% - 58px);bottom:8px;width:116px;height:122px;image-rendering:pixelated;filter:drop-shadow(3px 3px #211b31aa)}\r\n#restScreen .rest-hand{left:auto;right:4%;bottom:17%;width:clamp(110px,24vw,210px);height:clamp(125px,29vw,230px);z-index:7;pointer-events:none}\r\n#restScreen .player-name{bottom:10.5%;z-index:9;left:0;right:0;font:14px/1.3 var(--room-pixel);color:#fff5dc;text-shadow:2px 2px #211329;background:#1a152a88;padding:5px}\r\n#restScreen .rest-weapon-name{left:12px;bottom:24%;z-index:9;font:14px/1.3 var(--room-pixel);text-shadow:2px 2px #211329}\r\n#restScreen .rest-heading{position:absolute;z-index:12;top:0;left:0;right:0;padding:calc(10px + env(safe-area-inset-top)) 16px 12px;background:linear-gradient(#171023ee,#17102390,transparent)}\r\n#restScreen .rest-heading h1{font:700 22px/1.2 var(--room-pixel);letter-spacing:0;color:#fff1cf}\r\n#restScreen .eyebrow{font:12px/1.4 var(--room-pixel)}\r\n#restScreen button{font-family:var(--room-pixel);border-radius:2px;box-shadow:3px 3px #110d1c;min-height:44px}\r\n#restScreen .boss-status{top:calc(88px + env(safe-area-inset-top));left:16px;right:16px;z-index:10;background:#201832b3;border:2px solid #cab7ce;border-radius:0;font:14px/1.3 var(--room-pixel)}\r\n#restScreen .boss-health{border-radius:0;height:10px}\r\n#restScreen .rest-receipt{position:absolute;z-index:12;top:calc(146px + env(safe-area-inset-top));left:16px;right:16px;padding:6px 10px;background:#211830aa;font:14px/1.3 var(--room-pixel);color:#fff0dc}\r\n#restScreen .rest-bottom{position:absolute;bottom:0;left:0;right:0;z-index:12;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 16px calc(10px + env(safe-area-inset-bottom));border-top:2px solid #b19bb8;background:#1a152af2}\r\n#restScreen .rest-bottom>div:last-child{display:flex;align-items:center;gap:10px}\r\n#restScreen .rest-bottom button{font-size:14px;white-space:nowrap}\r\n#restScreen .rest-clock small{font-size:12px}\r\n#restScreen .rest-clock strong{font:700 26px/1.1 var(--room-pixel)}\r\n#restScreen .hand-team{position:absolute;z-index:11;left:16px;bottom:calc(96px + env(safe-area-inset-bottom));margin:0;max-width:60%;background:#211830dd;padding:8px;border:1px solid #b2d2b3;border-radius:0;font:12px/1.3 var(--room-pixel)}\r\nbody[data-screen=rest] .reward-pack-launch{bottom:calc(156px + env(safe-area-inset-bottom,0px))}\r\n#restScreen .hand-team #handTeamStatus{display:none}\r\n#restScreen .hand-team small{font-size:12px}\r\n#restScreen .rest-feedback{position:absolute;left:16px;right:16px;top:calc(185px + env(safe-area-inset-top));z-index:11;margin:0;min-height:0;text-align:center;font:14px/1.4 var(--room-pixel);text-shadow:2px 2px #211329;color:#fff5da;pointer-events:none}\r\n#restScreen .shield-note{position:absolute;right:16px;bottom:calc(97px + env(safe-area-inset-bottom));z-index:11;max-width:35%;margin:0;text-align:right;font:12px/1.3 var(--room-pixel);text-shadow:2px 2px #211329;color:#fff5da}\r\n#restScreen .damage-float{z-index:11;top:40%;font:900 clamp(26px,7vw,48px)/1 var(--room-pixel);text-shadow:3px 3px #341630}\r\n#restScreen .attack-flash{z-index:7;top:36%;left:47%}\r\n\r\n.meditation-panel{width:min(900px,100vw)!important;max-width:100vw;max-height:100dvh;padding:16px!important;border:3px solid #b2a0bb!important;border-radius:0!important;background:#201b32!important;font-family:var(--room-pixel)}\r\n.meditation-panel header h2,.meditation-entry strong{font:700 20px/1.3 var(--room-pixel)}\r\n.meditation-panel header button,.meditation-panel [data-breath-pause],.meditation-entry{border-radius:2px!important;font-family:var(--room-pixel);box-shadow:3px 3px #110d1c}\r\n.meditation-stage{height:clamp(320px,58dvh,620px);margin-top:14px;overflow:hidden;border:3px solid #99889f;background:var(--room-world) center/100% 100% no-repeat;image-rendering:pixelated}\r\n.meditation-stage::after{content:'';position:absolute;inset:0;background:#1b164122;z-index:0;pointer-events:none}\r\n.meditation-character{position:absolute!important;bottom:15%;left:calc(50% - 64px);width:128px;height:192px;z-index:3;padding:0!important;image-rendering:pixelated}\r\n.meditation-character canvas{width:128px;height:192px;max-width:none;image-rendering:pixelated}\r\n.meditation-platform{position:absolute;left:20%;right:20%;bottom:14%;height:24px;z-index:2;border-top:5px solid #e1d3ab;border-bottom:8px solid #352b43;background:var(--room-world) center bottom/100% auto;clip-path:polygon(3% 0,97% 0,100% 55%,85% 100%,15% 100%,0 55%)}\r\n.meditation-panel .breathing-ring{bottom:12%;left:calc(50% - 120px);width:240px;height:240px;z-index:1;border:3px solid #c2f0c5;box-shadow:0 0 0 4px #26344e,0 0 0 7px #b8e8c455;animation-timing-function:steps(24)}\r\n.meditation-speech{min-height:28px;margin:14px 0;font:16px/1.5 var(--room-pixel);color:#fff0cf}\r\n.meditation-panel [data-breath-pause]{display:block;margin:auto;min-width:110px;min-height:44px;font-size:14px}\r\n.meditation-panel .meditation-can{top:auto;bottom:25%;border-radius:0;box-shadow:3px 3px #221a36}\r\n@media(min-width:760px){#restScreen .rest-coach-mount{left:12%;width:76%;height:82%;top:-2%}#restScreen .rest-heading,#restScreen .rest-bottom{padding-left:max(24px,calc((100vw - 1000px)/2));padding-right:max(24px,calc((100vw - 1000px)/2))}.meditation-stage{background-size:100% 130%;background-position:center bottom}}\r\n@media(max-height:600px){#restScreen .rest-heading{padding-top:8px}#restScreen .eyebrow,#restScreen .rest-receipt,#restScreen .rest-feedback{display:none}#restScreen .boss-status{top:64px}#restScreen .rest-coach-mount{height:83%;top:-5%}#restScreen .player-platform{bottom:24%}#restScreen #restAvatar{width:90px;height:95px;left:calc(50% - 45px)}#restScreen .player-name{bottom:18%}#restScreen .hand-team{bottom:84px}#restScreen .shield-note{bottom:86px}#restScreen .rest-hand{bottom:23%;height:140px;width:130px}}\r\n@media(max-width:370px){#restScreen .rest-bottom{padding-left:10px;padding-right:10px;gap:7px}#restScreen .rest-bottom>div:last-child{gap:6px}#restScreen .rest-bottom button{font-size:13px;padding:8px}#restScreen .hand-team{max-width:56%}}\r\n#restScreen .slice-layer{position:absolute;inset:0;width:100%;height:100%;z-index:7;pointer-events:none;image-rendering:pixelated}\r\n","pod/rooms/cage/draco_wasm_wrapper.js":"var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(h){var n=0;return function(){return n<h.length?{done:!1,value:h[n++]}:{done:!0}}};$jscomp.arrayIterator=function(h){return{next:$jscomp.arrayIteratorImpl(h)}};$jscomp.makeIterator=function(h){var n=\"undefined\"!=typeof Symbol&&Symbol.iterator&&h[Symbol.iterator];return n?n.call(h):$jscomp.arrayIterator(h)};$jscomp.ASSUME_ES5=!1;$jscomp.ASSUME_NO_NATIVE_MAP=!1;$jscomp.ASSUME_NO_NATIVE_SET=!1;$jscomp.SIMPLE_FROUND_POLYFILL=!1;\r\n$jscomp.ISOLATE_POLYFILLS=!1;$jscomp.FORCE_POLYFILL_PROMISE=!1;$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION=!1;$jscomp.getGlobal=function(h){h=[\"object\"==typeof globalThis&&globalThis,h,\"object\"==typeof window&&window,\"object\"==typeof self&&self,\"object\"==typeof global&&global];for(var n=0;n<h.length;++n){var k=h[n];if(k&&k.Math==Math)return k}throw Error(\"Cannot find global object\");};$jscomp.global=$jscomp.getGlobal(this);\r\n$jscomp.defineProperty=$jscomp.ASSUME_ES5||\"function\"==typeof Object.defineProperties?Object.defineProperty:function(h,n,k){if(h==Array.prototype||h==Object.prototype)return h;h[n]=k.value;return h};$jscomp.IS_SYMBOL_NATIVE=\"function\"===typeof Symbol&&\"symbol\"===typeof Symbol(\"x\");$jscomp.TRUST_ES6_POLYFILLS=!$jscomp.ISOLATE_POLYFILLS||$jscomp.IS_SYMBOL_NATIVE;$jscomp.polyfills={};$jscomp.propertyToPolyfillSymbol={};$jscomp.POLYFILL_PREFIX=\"$jscp$\";\r\nvar $jscomp$lookupPolyfilledValue=function(h,n){var k=$jscomp.propertyToPolyfillSymbol[n];if(null==k)return h[n];k=h[k];return void 0!==k?k:h[n]};$jscomp.polyfill=function(h,n,k,p){n&&($jscomp.ISOLATE_POLYFILLS?$jscomp.polyfillIsolated(h,n,k,p):$jscomp.polyfillUnisolated(h,n,k,p))};\r\n$jscomp.polyfillUnisolated=function(h,n,k,p){k=$jscomp.global;h=h.split(\".\");for(p=0;p<h.length-1;p++){var l=h[p];if(!(l in k))return;k=k[l]}h=h[h.length-1];p=k[h];n=n(p);n!=p&&null!=n&&$jscomp.defineProperty(k,h,{configurable:!0,writable:!0,value:n})};\r\n$jscomp.polyfillIsolated=function(h,n,k,p){var l=h.split(\".\");h=1===l.length;p=l[0];p=!h&&p in $jscomp.polyfills?$jscomp.polyfills:$jscomp.global;for(var y=0;y<l.length-1;y++){var f=l[y];if(!(f in p))return;p=p[f]}l=l[l.length-1];k=$jscomp.IS_SYMBOL_NATIVE&&\"es6\"===k?p[l]:null;n=n(k);null!=n&&(h?$jscomp.defineProperty($jscomp.polyfills,l,{configurable:!0,writable:!0,value:n}):n!==k&&(void 0===$jscomp.propertyToPolyfillSymbol[l]&&(k=1E9*Math.random()>>>0,$jscomp.propertyToPolyfillSymbol[l]=$jscomp.IS_SYMBOL_NATIVE?\r\n$jscomp.global.Symbol(l):$jscomp.POLYFILL_PREFIX+k+\"$\"+l),$jscomp.defineProperty(p,$jscomp.propertyToPolyfillSymbol[l],{configurable:!0,writable:!0,value:n})))};\r\n$jscomp.polyfill(\"Promise\",function(h){function n(){this.batch_=null}function k(f){return f instanceof l?f:new l(function(q,u){q(f)})}if(h&&(!($jscomp.FORCE_POLYFILL_PROMISE||$jscomp.FORCE_POLYFILL_PROMISE_WHEN_NO_UNHANDLED_REJECTION&&\"undefined\"===typeof $jscomp.global.PromiseRejectionEvent)||!$jscomp.global.Promise||-1===$jscomp.global.Promise.toString().indexOf(\"[native code]\")))return h;n.prototype.asyncExecute=function(f){if(null==this.batch_){this.batch_=[];var q=this;this.asyncExecuteFunction(function(){q.executeBatch_()})}this.batch_.push(f)};\r\nvar p=$jscomp.global.setTimeout;n.prototype.asyncExecuteFunction=function(f){p(f,0)};n.prototype.executeBatch_=function(){for(;this.batch_&&this.batch_.length;){var f=this.batch_;this.batch_=[];for(var q=0;q<f.length;++q){var u=f[q];f[q]=null;try{u()}catch(A){this.asyncThrow_(A)}}}this.batch_=null};n.prototype.asyncThrow_=function(f){this.asyncExecuteFunction(function(){throw f;})};var l=function(f){this.state_=0;this.result_=void 0;this.onSettledCallbacks_=[];this.isRejectionHandled_=!1;var q=this.createResolveAndReject_();\r\ntry{f(q.resolve,q.reject)}catch(u){q.reject(u)}};l.prototype.createResolveAndReject_=function(){function f(A){return function(F){u||(u=!0,A.call(q,F))}}var q=this,u=!1;return{resolve:f(this.resolveTo_),reject:f(this.reject_)}};l.prototype.resolveTo_=function(f){if(f===this)this.reject_(new TypeError(\"A Promise cannot resolve to itself\"));else if(f instanceof l)this.settleSameAsPromise_(f);else{a:switch(typeof f){case \"object\":var q=null!=f;break a;case \"function\":q=!0;break a;default:q=!1}q?this.resolveToNonPromiseObj_(f):\r\nthis.fulfill_(f)}};l.prototype.resolveToNonPromiseObj_=function(f){var q=void 0;try{q=f.then}catch(u){this.reject_(u);return}\"function\"==typeof q?this.settleSameAsThenable_(q,f):this.fulfill_(f)};l.prototype.reject_=function(f){this.settle_(2,f)};l.prototype.fulfill_=function(f){this.settle_(1,f)};l.prototype.settle_=function(f,q){if(0!=this.state_)throw Error(\"Cannot settle(\"+f+\", \"+q+\"): Promise already settled in state\"+this.state_);this.state_=f;this.result_=q;2===this.state_&&this.scheduleUnhandledRejectionCheck_();\r\nthis.executeOnSettledCallbacks_()};l.prototype.scheduleUnhandledRejectionCheck_=function(){var f=this;p(function(){if(f.notifyUnhandledRejection_()){var q=$jscomp.global.console;\"undefined\"!==typeof q&&q.error(f.result_)}},1)};l.prototype.notifyUnhandledRejection_=function(){if(this.isRejectionHandled_)return!1;var f=$jscomp.global.CustomEvent,q=$jscomp.global.Event,u=$jscomp.global.dispatchEvent;if(\"undefined\"===typeof u)return!0;\"function\"===typeof f?f=new f(\"unhandledrejection\",{cancelable:!0}):\r\n\"function\"===typeof q?f=new q(\"unhandledrejection\",{cancelable:!0}):(f=$jscomp.global.document.createEvent(\"CustomEvent\"),f.initCustomEvent(\"unhandledrejection\",!1,!0,f));f.promise=this;f.reason=this.result_;return u(f)};l.prototype.executeOnSettledCallbacks_=function(){if(null!=this.onSettledCallbacks_){for(var f=0;f<this.onSettledCallbacks_.length;++f)y.asyncExecute(this.onSettledCallbacks_[f]);this.onSettledCallbacks_=null}};var y=new n;l.prototype.settleSameAsPromise_=function(f){var q=this.createResolveAndReject_();\r\nf.callWhenSettled_(q.resolve,q.reject)};l.prototype.settleSameAsThenable_=function(f,q){var u=this.createResolveAndReject_();try{f.call(q,u.resolve,u.reject)}catch(A){u.reject(A)}};l.prototype.then=function(f,q){function u(w,B){return\"function\"==typeof w?function(R){try{A(w(R))}catch(Z){F(Z)}}:B}var A,F,v=new l(function(w,B){A=w;F=B});this.callWhenSettled_(u(f,A),u(q,F));return v};l.prototype.catch=function(f){return this.then(void 0,f)};l.prototype.callWhenSettled_=function(f,q){function u(){switch(A.state_){case 1:f(A.result_);\r\nbreak;case 2:q(A.result_);break;default:throw Error(\"Unexpected state: \"+A.state_);}}var A=this;null==this.onSettledCallbacks_?y.asyncExecute(u):this.onSettledCallbacks_.push(u);this.isRejectionHandled_=!0};l.resolve=k;l.reject=function(f){return new l(function(q,u){u(f)})};l.race=function(f){return new l(function(q,u){for(var A=$jscomp.makeIterator(f),F=A.next();!F.done;F=A.next())k(F.value).callWhenSettled_(q,u)})};l.all=function(f){var q=$jscomp.makeIterator(f),u=q.next();return u.done?k([]):new l(function(A,\r\nF){function v(R){return function(Z){w[R]=Z;B--;0==B&&A(w)}}var w=[],B=0;do w.push(void 0),B++,k(u.value).callWhenSettled_(v(w.length-1),F),u=q.next();while(!u.done)})};return l},\"es6\",\"es3\");$jscomp.owns=function(h,n){return Object.prototype.hasOwnProperty.call(h,n)};$jscomp.assign=$jscomp.TRUST_ES6_POLYFILLS&&\"function\"==typeof Object.assign?Object.assign:function(h,n){for(var k=1;k<arguments.length;k++){var p=arguments[k];if(p)for(var l in p)$jscomp.owns(p,l)&&(h[l]=p[l])}return h};\r\n$jscomp.polyfill(\"Object.assign\",function(h){return h||$jscomp.assign},\"es6\",\"es3\");$jscomp.checkStringArgs=function(h,n,k){if(null==h)throw new TypeError(\"The 'this' value for String.prototype.\"+k+\" must not be null or undefined\");if(n instanceof RegExp)throw new TypeError(\"First argument to String.prototype.\"+k+\" must not be a regular expression\");return h+\"\"};\r\n$jscomp.polyfill(\"String.prototype.startsWith\",function(h){return h?h:function(n,k){var p=$jscomp.checkStringArgs(this,n,\"startsWith\");n+=\"\";var l=p.length,y=n.length;k=Math.max(0,Math.min(k|0,p.length));for(var f=0;f<y&&k<l;)if(p[k++]!=n[f++])return!1;return f>=y}},\"es6\",\"es3\");\r\n$jscomp.polyfill(\"Array.prototype.copyWithin\",function(h){function n(k){k=Number(k);return Infinity===k||-Infinity===k?k:k|0}return h?h:function(k,p,l){var y=this.length;k=n(k);p=n(p);l=void 0===l?y:n(l);k=0>k?Math.max(y+k,0):Math.min(k,y);p=0>p?Math.max(y+p,0):Math.min(p,y);l=0>l?Math.max(y+l,0):Math.min(l,y);if(k<p)for(;p<l;)p in this?this[k++]=this[p++]:(delete this[k++],p++);else for(l=Math.min(l,y+p-k),k+=l-p;l>p;)--l in this?this[--k]=this[l]:delete this[--k];return this}},\"es6\",\"es3\");\r\n$jscomp.typedArrayCopyWithin=function(h){return h?h:Array.prototype.copyWithin};$jscomp.polyfill(\"Int8Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Uint8Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Uint8ClampedArray.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Int16Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");\r\n$jscomp.polyfill(\"Uint16Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Int32Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Uint32Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Float32Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");$jscomp.polyfill(\"Float64Array.prototype.copyWithin\",$jscomp.typedArrayCopyWithin,\"es6\",\"es5\");\r\nvar DracoDecoderModule=function(){var h=\"undefined\"!==typeof document&&document.currentScript?document.currentScript.src:void 0;\"undefined\"!==typeof __filename&&(h=h||__filename);return function(n){function k(e){return a.locateFile?a.locateFile(e,U):U+e}function p(e,b){if(e){var c=ia;var d=e+b;for(b=e;c[b]&&!(b>=d);)++b;if(16<b-e&&c.buffer&&ra)c=ra.decode(c.subarray(e,b));else{for(d=\"\";e<b;){var g=c[e++];if(g&128){var t=c[e++]&63;if(192==(g&224))d+=String.fromCharCode((g&31)<<6|t);else{var aa=c[e++]&\r\n63;g=224==(g&240)?(g&15)<<12|t<<6|aa:(g&7)<<18|t<<12|aa<<6|c[e++]&63;65536>g?d+=String.fromCharCode(g):(g-=65536,d+=String.fromCharCode(55296|g>>10,56320|g&1023))}}else d+=String.fromCharCode(g)}c=d}}else c=\"\";return c}function l(){var e=ja.buffer;a.HEAP8=W=new Int8Array(e);a.HEAP16=new Int16Array(e);a.HEAP32=ca=new Int32Array(e);a.HEAPU8=ia=new Uint8Array(e);a.HEAPU16=new Uint16Array(e);a.HEAPU32=Y=new Uint32Array(e);a.HEAPF32=new Float32Array(e);a.HEAPF64=new Float64Array(e)}function y(e){if(a.onAbort)a.onAbort(e);\r\ne=\"Aborted(\"+e+\")\";da(e);sa=!0;e=new WebAssembly.RuntimeError(e+\". Build with -sASSERTIONS for more info.\");ka(e);throw e;}function f(e){try{if(e==P&&ea)return new Uint8Array(ea);if(ma)return ma(e);throw\"both async and sync fetching of the wasm failed\";}catch(b){y(b)}}function q(){if(!ea&&(ta||fa)){if(\"function\"==typeof fetch&&!P.startsWith(\"file://\"))return fetch(P,{credentials:\"same-origin\"}).then(function(e){if(!e.ok)throw\"failed to load wasm binary file at '\"+P+\"'\";return e.arrayBuffer()}).catch(function(){return f(P)});\r\nif(na)return new Promise(function(e,b){na(P,function(c){e(new Uint8Array(c))},b)})}return Promise.resolve().then(function(){return f(P)})}function u(e){for(;0<e.length;)e.shift()(a)}function A(e){this.excPtr=e;this.ptr=e-24;this.set_type=function(b){Y[this.ptr+4>>2]=b};this.get_type=function(){return Y[this.ptr+4>>2]};this.set_destructor=function(b){Y[this.ptr+8>>2]=b};this.get_destructor=function(){return Y[this.ptr+8>>2]};this.set_refcount=function(b){ca[this.ptr>>2]=b};this.set_caught=function(b){W[this.ptr+\r\n12>>0]=b?1:0};this.get_caught=function(){return 0!=W[this.ptr+12>>0]};this.set_rethrown=function(b){W[this.ptr+13>>0]=b?1:0};this.get_rethrown=function(){return 0!=W[this.ptr+13>>0]};this.init=function(b,c){this.set_adjusted_ptr(0);this.set_type(b);this.set_destructor(c);this.set_refcount(0);this.set_caught(!1);this.set_rethrown(!1)};this.add_ref=function(){ca[this.ptr>>2]+=1};this.release_ref=function(){var b=ca[this.ptr>>2];ca[this.ptr>>2]=b-1;return 1===b};this.set_adjusted_ptr=function(b){Y[this.ptr+\r\n16>>2]=b};this.get_adjusted_ptr=function(){return Y[this.ptr+16>>2]};this.get_exception_ptr=function(){if(ua(this.get_type()))return Y[this.excPtr>>2];var b=this.get_adjusted_ptr();return 0!==b?b:this.excPtr}}function F(){function e(){if(!la&&(la=!0,a.calledRun=!0,!sa)){va=!0;u(oa);wa(a);if(a.onRuntimeInitialized)a.onRuntimeInitialized();if(a.postRun)for(\"function\"==typeof a.postRun&&(a.postRun=[a.postRun]);a.postRun.length;)xa.unshift(a.postRun.shift());u(xa)}}if(!(0<ba)){if(a.preRun)for(\"function\"==\r\ntypeof a.preRun&&(a.preRun=[a.preRun]);a.preRun.length;)ya.unshift(a.preRun.shift());u(ya);0<ba||(a.setStatus?(a.setStatus(\"Running...\"),setTimeout(function(){setTimeout(function(){a.setStatus(\"\")},1);e()},1)):e())}}function v(){}function w(e){return(e||v).__cache__}function B(e,b){var c=w(b),d=c[e];if(d)return d;d=Object.create((b||v).prototype);d.ptr=e;return c[e]=d}function R(e){if(\"string\"===typeof e){for(var b=0,c=0;c<e.length;++c){var d=e.charCodeAt(c);127>=d?b++:2047>=d?b+=2:55296<=d&&57343>=\r\nd?(b+=4,++c):b+=3}b=Array(b+1);c=0;d=b.length;if(0<d){d=c+d-1;for(var g=0;g<e.length;++g){var t=e.charCodeAt(g);if(55296<=t&&57343>=t){var aa=e.charCodeAt(++g);t=65536+((t&1023)<<10)|aa&1023}if(127>=t){if(c>=d)break;b[c++]=t}else{if(2047>=t){if(c+1>=d)break;b[c++]=192|t>>6}else{if(65535>=t){if(c+2>=d)break;b[c++]=224|t>>12}else{if(c+3>=d)break;b[c++]=240|t>>18;b[c++]=128|t>>12&63}b[c++]=128|t>>6&63}b[c++]=128|t&63}}b[c]=0}e=r.alloc(b,W);r.copy(b,W,e);return e}return e}function Z(e){if(\"object\"===\r\ntypeof e){var b=r.alloc(e,W);r.copy(e,W,b);return b}return e}function X(){throw\"cannot construct a VoidPtr, no constructor in IDL\";}function S(){this.ptr=za();w(S)[this.ptr]=this}function Q(){this.ptr=Aa();w(Q)[this.ptr]=this}function V(){this.ptr=Ba();w(V)[this.ptr]=this}function x(){this.ptr=Ca();w(x)[this.ptr]=this}function D(){this.ptr=Da();w(D)[this.ptr]=this}function G(){this.ptr=Ea();w(G)[this.ptr]=this}function H(){this.ptr=Fa();w(H)[this.ptr]=this}function E(){this.ptr=Ga();w(E)[this.ptr]=\r\nthis}function T(){this.ptr=Ha();w(T)[this.ptr]=this}function C(){throw\"cannot construct a Status, no constructor in IDL\";}function I(){this.ptr=Ia();w(I)[this.ptr]=this}function J(){this.ptr=Ja();w(J)[this.ptr]=this}function K(){this.ptr=Ka();w(K)[this.ptr]=this}function L(){this.ptr=La();w(L)[this.ptr]=this}function M(){this.ptr=Ma();w(M)[this.ptr]=this}function N(){this.ptr=Na();w(N)[this.ptr]=this}function O(){this.ptr=Oa();w(O)[this.ptr]=this}function z(){this.ptr=Pa();w(z)[this.ptr]=this}function m(){this.ptr=\r\nQa();w(m)[this.ptr]=this}n=void 0===n?{}:n;var a=\"undefined\"!=typeof n?n:{},wa,ka;a.ready=new Promise(function(e,b){wa=e;ka=b});var Ra=!1,Sa=!1;a.onRuntimeInitialized=function(){Ra=!0;if(Sa&&\"function\"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Sa=!0;if(Ra&&\"function\"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(e){if(\"string\"!==typeof e)return!1;e=e.split(\".\");return 2>e.length||3<e.length?!1:1==e[0]&&0<=e[1]&&5>=e[1]?!0:0!=e[0]||10<\r\ne[1]?!1:!0};var Ta=Object.assign({},a),ta=\"object\"==typeof window,fa=\"function\"==typeof importScripts,Ua=\"object\"==typeof process&&\"object\"==typeof process.versions&&\"string\"==typeof process.versions.node,U=\"\";if(Ua){var Va=require(\"fs\"),pa=require(\"path\");U=fa?pa.dirname(U)+\"/\":__dirname+\"/\";var Wa=function(e,b){e=e.startsWith(\"file://\")?new URL(e):pa.normalize(e);return Va.readFileSync(e,b?void 0:\"utf8\")};var ma=function(e){e=Wa(e,!0);e.buffer||(e=new Uint8Array(e));return e};var na=function(e,\r\nb,c){e=e.startsWith(\"file://\")?new URL(e):pa.normalize(e);Va.readFile(e,function(d,g){d?c(d):b(g.buffer)})};1<process.argv.length&&process.argv[1].replace(/\\\\/g,\"/\");process.argv.slice(2);a.inspect=function(){return\"[Emscripten Module object]\"}}else if(ta||fa)fa?U=self.location.href:\"undefined\"!=typeof document&&document.currentScript&&(U=document.currentScript.src),h&&(U=h),U=0!==U.indexOf(\"blob:\")?U.substr(0,U.replace(/[?#].*/,\"\").lastIndexOf(\"/\")+1):\"\",Wa=function(e){var b=new XMLHttpRequest;b.open(\"GET\",\r\ne,!1);b.send(null);return b.responseText},fa&&(ma=function(e){var b=new XMLHttpRequest;b.open(\"GET\",e,!1);b.responseType=\"arraybuffer\";b.send(null);return new Uint8Array(b.response)}),na=function(e,b,c){var d=new XMLHttpRequest;d.open(\"GET\",e,!0);d.responseType=\"arraybuffer\";d.onload=function(){200==d.status||0==d.status&&d.response?b(d.response):c()};d.onerror=c;d.send(null)};a.print||console.log.bind(console);var da=a.printErr||console.warn.bind(console);Object.assign(a,Ta);Ta=null;var ea;a.wasmBinary&&\r\n(ea=a.wasmBinary);\"object\"!=typeof WebAssembly&&y(\"no native wasm support detected\");var ja,sa=!1,ra=\"undefined\"!=typeof TextDecoder?new TextDecoder(\"utf8\"):void 0,W,ia,ca,Y,ya=[],oa=[],xa=[],va=!1,ba=0,qa=null,ha=null;var P=\"draco_decoder_gltf.wasm\";P.startsWith(\"data:application/octet-stream;base64,\")||(P=k(P));var pd=0,qd={b:function(e,b,c){(new A(e)).init(b,c);pd++;throw e;},a:function(){y(\"\")},d:function(e,b,c){ia.copyWithin(e,b,b+c)},c:function(e){var b=ia.length;e>>>=0;if(2147483648<e)return!1;\r\nfor(var c=1;4>=c;c*=2){var d=b*(1+.2/c);d=Math.min(d,e+100663296);var g=Math;d=Math.max(e,d);g=g.min.call(g,2147483648,d+(65536-d%65536)%65536);a:{d=ja.buffer;try{ja.grow(g-d.byteLength+65535>>>16);l();var t=1;break a}catch(aa){}t=void 0}if(t)return!0}return!1}};(function(){function e(g,t){a.asm=g.exports;ja=a.asm.e;l();oa.unshift(a.asm.f);ba--;a.monitorRunDependencies&&a.monitorRunDependencies(ba);0==ba&&(null!==qa&&(clearInterval(qa),qa=null),ha&&(g=ha,ha=null,g()))}function b(g){e(g.instance)}\r\nfunction c(g){return q().then(function(t){return WebAssembly.instantiate(t,d)}).then(function(t){return t}).then(g,function(t){da(\"failed to asynchronously prepare wasm: \"+t);y(t)})}var d={a:qd};ba++;a.monitorRunDependencies&&a.monitorRunDependencies(ba);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(g){da(\"Module.instantiateWasm callback failed with error: \"+g),ka(g)}(function(){return ea||\"function\"!=typeof WebAssembly.instantiateStreaming||P.startsWith(\"data:application/octet-stream;base64,\")||\r\nP.startsWith(\"file://\")||Ua||\"function\"!=typeof fetch?c(b):fetch(P,{credentials:\"same-origin\"}).then(function(g){return WebAssembly.instantiateStreaming(g,d).then(b,function(t){da(\"wasm streaming compile failed: \"+t);da(\"falling back to ArrayBuffer instantiation\");return c(b)})})})().catch(ka);return{}})();var Xa=a._emscripten_bind_VoidPtr___destroy___0=function(){return(Xa=a._emscripten_bind_VoidPtr___destroy___0=a.asm.h).apply(null,arguments)},za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=\r\nfunction(){return(za=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=a.asm.i).apply(null,arguments)},Ya=a._emscripten_bind_DecoderBuffer_Init_2=function(){return(Ya=a._emscripten_bind_DecoderBuffer_Init_2=a.asm.j).apply(null,arguments)},Za=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return(Za=a._emscripten_bind_DecoderBuffer___destroy___0=a.asm.k).apply(null,arguments)},Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=function(){return(Aa=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0=\r\na.asm.l).apply(null,arguments)},$a=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return($a=a._emscripten_bind_AttributeTransformData_transform_type_0=a.asm.m).apply(null,arguments)},ab=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return(ab=a._emscripten_bind_AttributeTransformData___destroy___0=a.asm.n).apply(null,arguments)},Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return(Ba=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=\r\na.asm.o).apply(null,arguments)},bb=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return(bb=a._emscripten_bind_GeometryAttribute___destroy___0=a.asm.p).apply(null,arguments)},Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=function(){return(Ca=a._emscripten_bind_PointAttribute_PointAttribute_0=a.asm.q).apply(null,arguments)},cb=a._emscripten_bind_PointAttribute_size_0=function(){return(cb=a._emscripten_bind_PointAttribute_size_0=a.asm.r).apply(null,arguments)},db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=\r\nfunction(){return(db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=a.asm.s).apply(null,arguments)},eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return(eb=a._emscripten_bind_PointAttribute_attribute_type_0=a.asm.t).apply(null,arguments)},fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return(fb=a._emscripten_bind_PointAttribute_data_type_0=a.asm.u).apply(null,arguments)},gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return(gb=a._emscripten_bind_PointAttribute_num_components_0=\r\na.asm.v).apply(null,arguments)},hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return(hb=a._emscripten_bind_PointAttribute_normalized_0=a.asm.w).apply(null,arguments)},ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return(ib=a._emscripten_bind_PointAttribute_byte_stride_0=a.asm.x).apply(null,arguments)},jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return(jb=a._emscripten_bind_PointAttribute_byte_offset_0=a.asm.y).apply(null,arguments)},kb=a._emscripten_bind_PointAttribute_unique_id_0=\r\nfunction(){return(kb=a._emscripten_bind_PointAttribute_unique_id_0=a.asm.z).apply(null,arguments)},lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return(lb=a._emscripten_bind_PointAttribute___destroy___0=a.asm.A).apply(null,arguments)},Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=function(){return(Da=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0=a.asm.B).apply(null,arguments)},mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=\r\nfunction(){return(mb=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=a.asm.C).apply(null,arguments)},nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return(nb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=a.asm.D).apply(null,arguments)},ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return(ob=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=a.asm.E).apply(null,arguments)},pb=\r\na._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return(pb=a._emscripten_bind_AttributeQuantizationTransform_range_0=a.asm.F).apply(null,arguments)},qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return(qb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=a.asm.G).apply(null,arguments)},Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return(Ea=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=\r\na.asm.H).apply(null,arguments)},rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=function(){return(rb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1=a.asm.I).apply(null,arguments)},sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return(sb=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=a.asm.J).apply(null,arguments)},tb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return(tb=\r\na._emscripten_bind_AttributeOctahedronTransform___destroy___0=a.asm.K).apply(null,arguments)},Fa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return(Fa=a._emscripten_bind_PointCloud_PointCloud_0=a.asm.L).apply(null,arguments)},ub=a._emscripten_bind_PointCloud_num_attributes_0=function(){return(ub=a._emscripten_bind_PointCloud_num_attributes_0=a.asm.M).apply(null,arguments)},vb=a._emscripten_bind_PointCloud_num_points_0=function(){return(vb=a._emscripten_bind_PointCloud_num_points_0=a.asm.N).apply(null,\r\narguments)},wb=a._emscripten_bind_PointCloud___destroy___0=function(){return(wb=a._emscripten_bind_PointCloud___destroy___0=a.asm.O).apply(null,arguments)},Ga=a._emscripten_bind_Mesh_Mesh_0=function(){return(Ga=a._emscripten_bind_Mesh_Mesh_0=a.asm.P).apply(null,arguments)},xb=a._emscripten_bind_Mesh_num_faces_0=function(){return(xb=a._emscripten_bind_Mesh_num_faces_0=a.asm.Q).apply(null,arguments)},yb=a._emscripten_bind_Mesh_num_attributes_0=function(){return(yb=a._emscripten_bind_Mesh_num_attributes_0=\r\na.asm.R).apply(null,arguments)},zb=a._emscripten_bind_Mesh_num_points_0=function(){return(zb=a._emscripten_bind_Mesh_num_points_0=a.asm.S).apply(null,arguments)},Ab=a._emscripten_bind_Mesh___destroy___0=function(){return(Ab=a._emscripten_bind_Mesh___destroy___0=a.asm.T).apply(null,arguments)},Ha=a._emscripten_bind_Metadata_Metadata_0=function(){return(Ha=a._emscripten_bind_Metadata_Metadata_0=a.asm.U).apply(null,arguments)},Bb=a._emscripten_bind_Metadata___destroy___0=function(){return(Bb=a._emscripten_bind_Metadata___destroy___0=\r\na.asm.V).apply(null,arguments)},Cb=a._emscripten_bind_Status_code_0=function(){return(Cb=a._emscripten_bind_Status_code_0=a.asm.W).apply(null,arguments)},Db=a._emscripten_bind_Status_ok_0=function(){return(Db=a._emscripten_bind_Status_ok_0=a.asm.X).apply(null,arguments)},Eb=a._emscripten_bind_Status_error_msg_0=function(){return(Eb=a._emscripten_bind_Status_error_msg_0=a.asm.Y).apply(null,arguments)},Fb=a._emscripten_bind_Status___destroy___0=function(){return(Fb=a._emscripten_bind_Status___destroy___0=\r\na.asm.Z).apply(null,arguments)},Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return(Ia=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=a.asm._).apply(null,arguments)},Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return(Gb=a._emscripten_bind_DracoFloat32Array_GetValue_1=a.asm.$).apply(null,arguments)},Hb=a._emscripten_bind_DracoFloat32Array_size_0=function(){return(Hb=a._emscripten_bind_DracoFloat32Array_size_0=a.asm.aa).apply(null,arguments)},Ib=\r\na._emscripten_bind_DracoFloat32Array___destroy___0=function(){return(Ib=a._emscripten_bind_DracoFloat32Array___destroy___0=a.asm.ba).apply(null,arguments)},Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return(Ja=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=a.asm.ca).apply(null,arguments)},Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return(Jb=a._emscripten_bind_DracoInt8Array_GetValue_1=a.asm.da).apply(null,arguments)},Kb=a._emscripten_bind_DracoInt8Array_size_0=\r\nfunction(){return(Kb=a._emscripten_bind_DracoInt8Array_size_0=a.asm.ea).apply(null,arguments)},Lb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return(Lb=a._emscripten_bind_DracoInt8Array___destroy___0=a.asm.fa).apply(null,arguments)},Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return(Ka=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=a.asm.ga).apply(null,arguments)},Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return(Mb=a._emscripten_bind_DracoUInt8Array_GetValue_1=\r\na.asm.ha).apply(null,arguments)},Nb=a._emscripten_bind_DracoUInt8Array_size_0=function(){return(Nb=a._emscripten_bind_DracoUInt8Array_size_0=a.asm.ia).apply(null,arguments)},Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return(Ob=a._emscripten_bind_DracoUInt8Array___destroy___0=a.asm.ja).apply(null,arguments)},La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return(La=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=a.asm.ka).apply(null,arguments)},Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=\r\nfunction(){return(Pb=a._emscripten_bind_DracoInt16Array_GetValue_1=a.asm.la).apply(null,arguments)},Qb=a._emscripten_bind_DracoInt16Array_size_0=function(){return(Qb=a._emscripten_bind_DracoInt16Array_size_0=a.asm.ma).apply(null,arguments)},Rb=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return(Rb=a._emscripten_bind_DracoInt16Array___destroy___0=a.asm.na).apply(null,arguments)},Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return(Ma=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=\r\na.asm.oa).apply(null,arguments)},Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return(Sb=a._emscripten_bind_DracoUInt16Array_GetValue_1=a.asm.pa).apply(null,arguments)},Tb=a._emscripten_bind_DracoUInt16Array_size_0=function(){return(Tb=a._emscripten_bind_DracoUInt16Array_size_0=a.asm.qa).apply(null,arguments)},Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return(Ub=a._emscripten_bind_DracoUInt16Array___destroy___0=a.asm.ra).apply(null,arguments)},Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=\r\nfunction(){return(Na=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=a.asm.sa).apply(null,arguments)},Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return(Vb=a._emscripten_bind_DracoInt32Array_GetValue_1=a.asm.ta).apply(null,arguments)},Wb=a._emscripten_bind_DracoInt32Array_size_0=function(){return(Wb=a._emscripten_bind_DracoInt32Array_size_0=a.asm.ua).apply(null,arguments)},Xb=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return(Xb=a._emscripten_bind_DracoInt32Array___destroy___0=\r\na.asm.va).apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return(Oa=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=a.asm.wa).apply(null,arguments)},Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return(Yb=a._emscripten_bind_DracoUInt32Array_GetValue_1=a.asm.xa).apply(null,arguments)},Zb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return(Zb=a._emscripten_bind_DracoUInt32Array_size_0=a.asm.ya).apply(null,arguments)},$b=a._emscripten_bind_DracoUInt32Array___destroy___0=\r\nfunction(){return($b=a._emscripten_bind_DracoUInt32Array___destroy___0=a.asm.za).apply(null,arguments)},Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return(Pa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=a.asm.Aa).apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return(ac=a._emscripten_bind_MetadataQuerier_HasEntry_2=a.asm.Ba).apply(null,arguments)},bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return(bc=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=\r\na.asm.Ca).apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=function(){return(cc=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3=a.asm.Da).apply(null,arguments)},dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return(dc=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=a.asm.Ea).apply(null,arguments)},ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return(ec=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=a.asm.Fa).apply(null,\r\narguments)},fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return(fc=a._emscripten_bind_MetadataQuerier_NumEntries_1=a.asm.Ga).apply(null,arguments)},gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return(gc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=a.asm.Ha).apply(null,arguments)},hc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return(hc=a._emscripten_bind_MetadataQuerier___destroy___0=a.asm.Ia).apply(null,arguments)},Qa=a._emscripten_bind_Decoder_Decoder_0=\r\nfunction(){return(Qa=a._emscripten_bind_Decoder_Decoder_0=a.asm.Ja).apply(null,arguments)},ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=function(){return(ic=a._emscripten_bind_Decoder_DecodeArrayToPointCloud_3=a.asm.Ka).apply(null,arguments)},jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=function(){return(jc=a._emscripten_bind_Decoder_DecodeArrayToMesh_3=a.asm.La).apply(null,arguments)},kc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return(kc=a._emscripten_bind_Decoder_GetAttributeId_2=\r\na.asm.Ma).apply(null,arguments)},lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return(lc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=a.asm.Na).apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return(mc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=a.asm.Oa).apply(null,arguments)},nc=a._emscripten_bind_Decoder_GetAttribute_2=function(){return(nc=a._emscripten_bind_Decoder_GetAttribute_2=a.asm.Pa).apply(null,arguments)},\r\noc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return(oc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=a.asm.Qa).apply(null,arguments)},pc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return(pc=a._emscripten_bind_Decoder_GetMetadata_1=a.asm.Ra).apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return(qc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=a.asm.Sa).apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=\r\nfunction(){return(rc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=a.asm.Ta).apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return(sc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=a.asm.Ua).apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return(tc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=a.asm.Va).apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=function(){return(uc=\r\na._emscripten_bind_Decoder_GetTrianglesUInt32Array_3=a.asm.Wa).apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return(vc=a._emscripten_bind_Decoder_GetAttributeFloat_3=a.asm.Xa).apply(null,arguments)},wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return(wc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=a.asm.Ya).apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return(xc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=\r\na.asm.Za).apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return(yc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=a.asm._a).apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return(zc=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=a.asm.$a).apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return(Ac=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=\r\na.asm.ab).apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return(Bc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=a.asm.bb).apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return(Cc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=a.asm.cb).apply(null,arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return(Dc=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=\r\na.asm.db).apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return(Ec=a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=a.asm.eb).apply(null,arguments)},Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return(Fc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=a.asm.fb).apply(null,arguments)},Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=function(){return(Gc=a._emscripten_bind_Decoder_GetEncodedGeometryType_Deprecated_1=\r\na.asm.gb).apply(null,arguments)},Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return(Hc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=a.asm.hb).apply(null,arguments)},Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return(Ic=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=a.asm.ib).apply(null,arguments)},Jc=a._emscripten_bind_Decoder___destroy___0=function(){return(Jc=a._emscripten_bind_Decoder___destroy___0=a.asm.jb).apply(null,arguments)},Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=\r\nfunction(){return(Kc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=a.asm.kb).apply(null,arguments)},Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return(Lc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=a.asm.lb).apply(null,arguments)},Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return(Mc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=\r\na.asm.mb).apply(null,arguments)},Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return(Nc=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=a.asm.nb).apply(null,arguments)},Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return(Oc=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=a.asm.ob).apply(null,arguments)},Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return(Pc=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=\r\na.asm.pb).apply(null,arguments)},Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return(Qc=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=a.asm.qb).apply(null,arguments)},Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=function(){return(Rc=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR=a.asm.rb).apply(null,arguments)},Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return(Sc=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=\r\na.asm.sb).apply(null,arguments)},Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return(Tc=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=a.asm.tb).apply(null,arguments)},Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return(Uc=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=a.asm.ub).apply(null,arguments)},Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return(Vc=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=\r\na.asm.vb).apply(null,arguments)},Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return(Wc=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=a.asm.wb).apply(null,arguments)},Xc=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return(Xc=a._emscripten_enum_draco_DataType_DT_INVALID=a.asm.xb).apply(null,arguments)},Yc=a._emscripten_enum_draco_DataType_DT_INT8=function(){return(Yc=a._emscripten_enum_draco_DataType_DT_INT8=a.asm.yb).apply(null,arguments)},Zc=\r\na._emscripten_enum_draco_DataType_DT_UINT8=function(){return(Zc=a._emscripten_enum_draco_DataType_DT_UINT8=a.asm.zb).apply(null,arguments)},$c=a._emscripten_enum_draco_DataType_DT_INT16=function(){return($c=a._emscripten_enum_draco_DataType_DT_INT16=a.asm.Ab).apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return(ad=a._emscripten_enum_draco_DataType_DT_UINT16=a.asm.Bb).apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return(bd=a._emscripten_enum_draco_DataType_DT_INT32=\r\na.asm.Cb).apply(null,arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return(cd=a._emscripten_enum_draco_DataType_DT_UINT32=a.asm.Db).apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return(dd=a._emscripten_enum_draco_DataType_DT_INT64=a.asm.Eb).apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return(ed=a._emscripten_enum_draco_DataType_DT_UINT64=a.asm.Fb).apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=\r\nfunction(){return(fd=a._emscripten_enum_draco_DataType_DT_FLOAT32=a.asm.Gb).apply(null,arguments)},gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return(gd=a._emscripten_enum_draco_DataType_DT_FLOAT64=a.asm.Hb).apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return(hd=a._emscripten_enum_draco_DataType_DT_BOOL=a.asm.Ib).apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return(id=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=\r\na.asm.Jb).apply(null,arguments)},jd=a._emscripten_enum_draco_StatusCode_OK=function(){return(jd=a._emscripten_enum_draco_StatusCode_OK=a.asm.Kb).apply(null,arguments)},kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return(kd=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=a.asm.Lb).apply(null,arguments)},ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return(ld=a._emscripten_enum_draco_StatusCode_IO_ERROR=a.asm.Mb).apply(null,arguments)},md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=\r\nfunction(){return(md=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=a.asm.Nb).apply(null,arguments)},nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=function(){return(nd=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION=a.asm.Ob).apply(null,arguments)},od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return(od=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=a.asm.Pb).apply(null,arguments)};a._malloc=function(){return(a._malloc=a.asm.Qb).apply(null,arguments)};\r\na._free=function(){return(a._free=a.asm.Rb).apply(null,arguments)};var ua=function(){return(ua=a.asm.Sb).apply(null,arguments)};a.___start_em_js=11660;a.___stop_em_js=11758;var la;ha=function b(){la||F();la||(ha=b)};if(a.preInit)for(\"function\"==typeof a.preInit&&(a.preInit=[a.preInit]);0<a.preInit.length;)a.preInit.pop()();F();v.prototype=Object.create(v.prototype);v.prototype.constructor=v;v.prototype.__class__=v;v.__cache__={};a.WrapperObject=v;a.getCache=w;a.wrapPointer=B;a.castObject=function(b,\r\nc){return B(b.ptr,c)};a.NULL=B(0);a.destroy=function(b){if(!b.__destroy__)throw\"Error: Cannot destroy object. (Did you create it yourself?)\";b.__destroy__();delete w(b.__class__)[b.ptr]};a.compare=function(b,c){return b.ptr===c.ptr};a.getPointer=function(b){return b.ptr};a.getClass=function(b){return b.__class__};var r={buffer:0,size:0,pos:0,temps:[],needed:0,prepare:function(){if(r.needed){for(var b=0;b<r.temps.length;b++)a._free(r.temps[b]);r.temps.length=0;a._free(r.buffer);r.buffer=0;r.size+=\r\nr.needed;r.needed=0}r.buffer||(r.size+=128,r.buffer=a._malloc(r.size),r.buffer||y(void 0));r.pos=0},alloc:function(b,c){r.buffer||y(void 0);b=b.length*c.BYTES_PER_ELEMENT;b=b+7&-8;r.pos+b>=r.size?(0<b||y(void 0),r.needed+=b,c=a._malloc(b),r.temps.push(c)):(c=r.buffer+r.pos,r.pos+=b);return c},copy:function(b,c,d){d>>>=0;switch(c.BYTES_PER_ELEMENT){case 2:d>>>=1;break;case 4:d>>>=2;break;case 8:d>>>=3}for(var g=0;g<b.length;g++)c[d+g]=b[g]}};X.prototype=Object.create(v.prototype);X.prototype.constructor=\r\nX;X.prototype.__class__=X;X.__cache__={};a.VoidPtr=X;X.prototype.__destroy__=X.prototype.__destroy__=function(){Xa(this.ptr)};S.prototype=Object.create(v.prototype);S.prototype.constructor=S;S.prototype.__class__=S;S.__cache__={};a.DecoderBuffer=S;S.prototype.Init=S.prototype.Init=function(b,c){var d=this.ptr;r.prepare();\"object\"==typeof b&&(b=Z(b));c&&\"object\"===typeof c&&(c=c.ptr);Ya(d,b,c)};S.prototype.__destroy__=S.prototype.__destroy__=function(){Za(this.ptr)};Q.prototype=Object.create(v.prototype);\r\nQ.prototype.constructor=Q;Q.prototype.__class__=Q;Q.__cache__={};a.AttributeTransformData=Q;Q.prototype.transform_type=Q.prototype.transform_type=function(){return $a(this.ptr)};Q.prototype.__destroy__=Q.prototype.__destroy__=function(){ab(this.ptr)};V.prototype=Object.create(v.prototype);V.prototype.constructor=V;V.prototype.__class__=V;V.__cache__={};a.GeometryAttribute=V;V.prototype.__destroy__=V.prototype.__destroy__=function(){bb(this.ptr)};x.prototype=Object.create(v.prototype);x.prototype.constructor=\r\nx;x.prototype.__class__=x;x.__cache__={};a.PointAttribute=x;x.prototype.size=x.prototype.size=function(){return cb(this.ptr)};x.prototype.GetAttributeTransformData=x.prototype.GetAttributeTransformData=function(){return B(db(this.ptr),Q)};x.prototype.attribute_type=x.prototype.attribute_type=function(){return eb(this.ptr)};x.prototype.data_type=x.prototype.data_type=function(){return fb(this.ptr)};x.prototype.num_components=x.prototype.num_components=function(){return gb(this.ptr)};x.prototype.normalized=\r\nx.prototype.normalized=function(){return!!hb(this.ptr)};x.prototype.byte_stride=x.prototype.byte_stride=function(){return ib(this.ptr)};x.prototype.byte_offset=x.prototype.byte_offset=function(){return jb(this.ptr)};x.prototype.unique_id=x.prototype.unique_id=function(){return kb(this.ptr)};x.prototype.__destroy__=x.prototype.__destroy__=function(){lb(this.ptr)};D.prototype=Object.create(v.prototype);D.prototype.constructor=D;D.prototype.__class__=D;D.__cache__={};a.AttributeQuantizationTransform=\r\nD;D.prototype.InitFromAttribute=D.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return!!mb(c,b)};D.prototype.quantization_bits=D.prototype.quantization_bits=function(){return nb(this.ptr)};D.prototype.min_value=D.prototype.min_value=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return ob(c,b)};D.prototype.range=D.prototype.range=function(){return pb(this.ptr)};D.prototype.__destroy__=D.prototype.__destroy__=function(){qb(this.ptr)};G.prototype=\r\nObject.create(v.prototype);G.prototype.constructor=G;G.prototype.__class__=G;G.__cache__={};a.AttributeOctahedronTransform=G;G.prototype.InitFromAttribute=G.prototype.InitFromAttribute=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return!!rb(c,b)};G.prototype.quantization_bits=G.prototype.quantization_bits=function(){return sb(this.ptr)};G.prototype.__destroy__=G.prototype.__destroy__=function(){tb(this.ptr)};H.prototype=Object.create(v.prototype);H.prototype.constructor=H;H.prototype.__class__=\r\nH;H.__cache__={};a.PointCloud=H;H.prototype.num_attributes=H.prototype.num_attributes=function(){return ub(this.ptr)};H.prototype.num_points=H.prototype.num_points=function(){return vb(this.ptr)};H.prototype.__destroy__=H.prototype.__destroy__=function(){wb(this.ptr)};E.prototype=Object.create(v.prototype);E.prototype.constructor=E;E.prototype.__class__=E;E.__cache__={};a.Mesh=E;E.prototype.num_faces=E.prototype.num_faces=function(){return xb(this.ptr)};E.prototype.num_attributes=E.prototype.num_attributes=\r\nfunction(){return yb(this.ptr)};E.prototype.num_points=E.prototype.num_points=function(){return zb(this.ptr)};E.prototype.__destroy__=E.prototype.__destroy__=function(){Ab(this.ptr)};T.prototype=Object.create(v.prototype);T.prototype.constructor=T;T.prototype.__class__=T;T.__cache__={};a.Metadata=T;T.prototype.__destroy__=T.prototype.__destroy__=function(){Bb(this.ptr)};C.prototype=Object.create(v.prototype);C.prototype.constructor=C;C.prototype.__class__=C;C.__cache__={};a.Status=C;C.prototype.code=\r\nC.prototype.code=function(){return Cb(this.ptr)};C.prototype.ok=C.prototype.ok=function(){return!!Db(this.ptr)};C.prototype.error_msg=C.prototype.error_msg=function(){return p(Eb(this.ptr))};C.prototype.__destroy__=C.prototype.__destroy__=function(){Fb(this.ptr)};I.prototype=Object.create(v.prototype);I.prototype.constructor=I;I.prototype.__class__=I;I.__cache__={};a.DracoFloat32Array=I;I.prototype.GetValue=I.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Gb(c,\r\nb)};I.prototype.size=I.prototype.size=function(){return Hb(this.ptr)};I.prototype.__destroy__=I.prototype.__destroy__=function(){Ib(this.ptr)};J.prototype=Object.create(v.prototype);J.prototype.constructor=J;J.prototype.__class__=J;J.__cache__={};a.DracoInt8Array=J;J.prototype.GetValue=J.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Jb(c,b)};J.prototype.size=J.prototype.size=function(){return Kb(this.ptr)};J.prototype.__destroy__=J.prototype.__destroy__=function(){Lb(this.ptr)};\r\nK.prototype=Object.create(v.prototype);K.prototype.constructor=K;K.prototype.__class__=K;K.__cache__={};a.DracoUInt8Array=K;K.prototype.GetValue=K.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Mb(c,b)};K.prototype.size=K.prototype.size=function(){return Nb(this.ptr)};K.prototype.__destroy__=K.prototype.__destroy__=function(){Ob(this.ptr)};L.prototype=Object.create(v.prototype);L.prototype.constructor=L;L.prototype.__class__=L;L.__cache__={};a.DracoInt16Array=\r\nL;L.prototype.GetValue=L.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Pb(c,b)};L.prototype.size=L.prototype.size=function(){return Qb(this.ptr)};L.prototype.__destroy__=L.prototype.__destroy__=function(){Rb(this.ptr)};M.prototype=Object.create(v.prototype);M.prototype.constructor=M;M.prototype.__class__=M;M.__cache__={};a.DracoUInt16Array=M;M.prototype.GetValue=M.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Sb(c,b)};\r\nM.prototype.size=M.prototype.size=function(){return Tb(this.ptr)};M.prototype.__destroy__=M.prototype.__destroy__=function(){Ub(this.ptr)};N.prototype=Object.create(v.prototype);N.prototype.constructor=N;N.prototype.__class__=N;N.__cache__={};a.DracoInt32Array=N;N.prototype.GetValue=N.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Vb(c,b)};N.prototype.size=N.prototype.size=function(){return Wb(this.ptr)};N.prototype.__destroy__=N.prototype.__destroy__=function(){Xb(this.ptr)};\r\nO.prototype=Object.create(v.prototype);O.prototype.constructor=O;O.prototype.__class__=O;O.__cache__={};a.DracoUInt32Array=O;O.prototype.GetValue=O.prototype.GetValue=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Yb(c,b)};O.prototype.size=O.prototype.size=function(){return Zb(this.ptr)};O.prototype.__destroy__=O.prototype.__destroy__=function(){$b(this.ptr)};z.prototype=Object.create(v.prototype);z.prototype.constructor=z;z.prototype.__class__=z;z.__cache__={};a.MetadataQuerier=\r\nz;z.prototype.HasEntry=z.prototype.HasEntry=function(b,c){var d=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);return!!ac(d,b,c)};z.prototype.GetIntEntry=z.prototype.GetIntEntry=function(b,c){var d=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);return bc(d,b,c)};z.prototype.GetIntEntryArray=z.prototype.GetIntEntryArray=function(b,c,d){var g=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===\r\ntypeof c?c.ptr:R(c);d&&\"object\"===typeof d&&(d=d.ptr);cc(g,b,c,d)};z.prototype.GetDoubleEntry=z.prototype.GetDoubleEntry=function(b,c){var d=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);return dc(d,b,c)};z.prototype.GetStringEntry=z.prototype.GetStringEntry=function(b,c){var d=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);return p(ec(d,b,c))};z.prototype.NumEntries=z.prototype.NumEntries=function(b){var c=this.ptr;\r\nb&&\"object\"===typeof b&&(b=b.ptr);return fc(c,b)};z.prototype.GetEntryName=z.prototype.GetEntryName=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);return p(gc(d,b,c))};z.prototype.__destroy__=z.prototype.__destroy__=function(){hc(this.ptr)};m.prototype=Object.create(v.prototype);m.prototype.constructor=m;m.prototype.__class__=m;m.__cache__={};a.Decoder=m;m.prototype.DecodeArrayToPointCloud=m.prototype.DecodeArrayToPointCloud=function(b,c,d){var g=\r\nthis.ptr;r.prepare();\"object\"==typeof b&&(b=Z(b));c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return B(ic(g,b,c,d),C)};m.prototype.DecodeArrayToMesh=m.prototype.DecodeArrayToMesh=function(b,c,d){var g=this.ptr;r.prepare();\"object\"==typeof b&&(b=Z(b));c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return B(jc(g,b,c,d),C)};m.prototype.GetAttributeId=m.prototype.GetAttributeId=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&\r\n(c=c.ptr);return kc(d,b,c)};m.prototype.GetAttributeIdByName=m.prototype.GetAttributeIdByName=function(b,c){var d=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);return lc(d,b,c)};m.prototype.GetAttributeIdByMetadataEntry=m.prototype.GetAttributeIdByMetadataEntry=function(b,c,d){var g=this.ptr;r.prepare();b&&\"object\"===typeof b&&(b=b.ptr);c=c&&\"object\"===typeof c?c.ptr:R(c);d=d&&\"object\"===typeof d?d.ptr:R(d);return mc(g,b,c,d)};m.prototype.GetAttribute=\r\nm.prototype.GetAttribute=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);return B(nc(d,b,c),x)};m.prototype.GetAttributeByUniqueId=m.prototype.GetAttributeByUniqueId=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);return B(oc(d,b,c),x)};m.prototype.GetMetadata=m.prototype.GetMetadata=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return B(pc(c,b),T)};m.prototype.GetAttributeMetadata=m.prototype.GetAttributeMetadata=\r\nfunction(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);return B(qc(d,b,c),T)};m.prototype.GetFaceFromMesh=m.prototype.GetFaceFromMesh=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!rc(g,b,c,d)};m.prototype.GetTriangleStripsFromMesh=m.prototype.GetTriangleStripsFromMesh=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);\r\nreturn sc(d,b,c)};m.prototype.GetTrianglesUInt16Array=m.prototype.GetTrianglesUInt16Array=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!tc(g,b,c,d)};m.prototype.GetTrianglesUInt32Array=m.prototype.GetTrianglesUInt32Array=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!uc(g,b,c,d)};m.prototype.GetAttributeFloat=m.prototype.GetAttributeFloat=\r\nfunction(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!vc(g,b,c,d)};m.prototype.GetAttributeFloatForAllPoints=m.prototype.GetAttributeFloatForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!wc(g,b,c,d)};m.prototype.GetAttributeIntForAllPoints=m.prototype.GetAttributeIntForAllPoints=function(b,c,d){var g=this.ptr;\r\nb&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!xc(g,b,c,d)};m.prototype.GetAttributeInt8ForAllPoints=m.prototype.GetAttributeInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!yc(g,b,c,d)};m.prototype.GetAttributeUInt8ForAllPoints=m.prototype.GetAttributeUInt8ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=\r\nb.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!zc(g,b,c,d)};m.prototype.GetAttributeInt16ForAllPoints=m.prototype.GetAttributeInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!Ac(g,b,c,d)};m.prototype.GetAttributeUInt16ForAllPoints=m.prototype.GetAttributeUInt16ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&\r\n(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!Bc(g,b,c,d)};m.prototype.GetAttributeInt32ForAllPoints=m.prototype.GetAttributeInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);return!!Cc(g,b,c,d)};m.prototype.GetAttributeUInt32ForAllPoints=m.prototype.GetAttributeUInt32ForAllPoints=function(b,c,d){var g=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===\r\ntypeof d&&(d=d.ptr);return!!Dc(g,b,c,d)};m.prototype.GetAttributeDataArrayForAllPoints=m.prototype.GetAttributeDataArrayForAllPoints=function(b,c,d,g,t){var aa=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);d&&\"object\"===typeof d&&(d=d.ptr);g&&\"object\"===typeof g&&(g=g.ptr);t&&\"object\"===typeof t&&(t=t.ptr);return!!Ec(aa,b,c,d,g,t)};m.prototype.SkipAttributeTransform=m.prototype.SkipAttributeTransform=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);Fc(c,\r\nb)};m.prototype.GetEncodedGeometryType_Deprecated=m.prototype.GetEncodedGeometryType_Deprecated=function(b){var c=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);return Gc(c,b)};m.prototype.DecodeBufferToPointCloud=m.prototype.DecodeBufferToPointCloud=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===typeof c&&(c=c.ptr);return B(Hc(d,b,c),C)};m.prototype.DecodeBufferToMesh=m.prototype.DecodeBufferToMesh=function(b,c){var d=this.ptr;b&&\"object\"===typeof b&&(b=b.ptr);c&&\"object\"===\r\ntypeof c&&(c=c.ptr);return B(Ic(d,b,c),C)};m.prototype.__destroy__=m.prototype.__destroy__=function(){Jc(this.ptr)};(function(){function b(){a.ATTRIBUTE_INVALID_TRANSFORM=Kc();a.ATTRIBUTE_NO_TRANSFORM=Lc();a.ATTRIBUTE_QUANTIZATION_TRANSFORM=Mc();a.ATTRIBUTE_OCTAHEDRON_TRANSFORM=Nc();a.INVALID=Oc();a.POSITION=Pc();a.NORMAL=Qc();a.COLOR=Rc();a.TEX_COORD=Sc();a.GENERIC=Tc();a.INVALID_GEOMETRY_TYPE=Uc();a.POINT_CLOUD=Vc();a.TRIANGULAR_MESH=Wc();a.DT_INVALID=Xc();a.DT_INT8=Yc();a.DT_UINT8=Zc();a.DT_INT16=\r\n$c();a.DT_UINT16=ad();a.DT_INT32=bd();a.DT_UINT32=cd();a.DT_INT64=dd();a.DT_UINT64=ed();a.DT_FLOAT32=fd();a.DT_FLOAT64=gd();a.DT_BOOL=hd();a.DT_TYPES_COUNT=id();a.OK=jd();a.DRACO_ERROR=kd();a.IO_ERROR=ld();a.INVALID_PARAMETER=md();a.UNSUPPORTED_VERSION=nd();a.UNKNOWN_VERSION=od()}va?b():oa.unshift(b)})();if(\"function\"===typeof a.onModuleParsed)a.onModuleParsed();a.Decoder.prototype.GetEncodedGeometryType=function(b){if(b.__class__&&b.__class__===a.DecoderBuffer)return a.Decoder.prototype.GetEncodedGeometryType_Deprecated(b);\r\nif(8>b.byteLength)return a.INVALID_GEOMETRY_TYPE;switch(b[7]){case 0:return a.POINT_CLOUD;case 1:return a.TRIANGULAR_MESH;default:return a.INVALID_GEOMETRY_TYPE}};return n.ready}}();\"object\"===typeof exports&&\"object\"===typeof module?module.exports=DracoDecoderModule:\"function\"===typeof define&&define.amd?define([],function(){return DracoDecoderModule}):\"object\"===typeof exports&&(exports.DracoDecoderModule=DracoDecoderModule);\r\n","pod/set-flow.mjs":"// Workout progress is earned by completed tracked sets. Rest taps never earn XP.\r\nexport const XP_PER_SET=25,XP_PER_LEVEL=100;\r\nexport const REST_IDLE_MS=3000;\r\nimport {weaponDamage,dayAt} from '../combat.mjs';\r\nimport {tapDamage,kitPetDps,bossHp,dailyCap,specialBudget,SPECIAL_LEVEL,BOSS_ATTACK_EVERY_HITS,REST_SECONDS} from '../combat-config.mjs';\r\nimport {EXERCISES} from '../exercise-library.mjs';\r\nimport {PerformanceWorkout} from './performance-workout.mjs';\r\nimport {cosmeticLevel} from '../progression-rules.mjs';\r\nimport {AbilityCooldown} from './weapon-evolution.mjs';\r\nexport {bossHp as bossHealthMax} from '../combat-config.mjs';\r\nexport const shouldStartRestTargets=(phase,preparationRest)=>phase==='rest'||preparationRest===true;\r\nexport const DEFAULT_GOALS={...Object.fromEntries(Object.values(EXERCISES).map(m=>[m.id,m.defaultGoal])),squat:3,pushup:3,tree:9,warrior:9,horse:9,boxing:9,jogging:3,jumping:3};\r\nexport const valueOf=m=>m.kind==='hold'?m.totalHold:m.kind==='pace'?(m.active??0):m.count;\r\nexport function readProgress(raw){\r\n // circuit is a cached mirror of the server-computed daily-circuit payload (circuit.mjs),\r\n // kept alongside completedSets so the circuit meter can render on reopen before the next\r\n // myr5:account-progress event lands (Rank 6: \"progress survives app close/reopen mid-circuit\").\r\n try{const p=typeof raw==='string'?JSON.parse(raw):raw;if(p?.version===1&&Number.isSafeInteger(p.completedSets)&&p.completedSets>=0)return {version:1,completedSets:Math.min(p.completedSets,1000000),circuit:p.circuit&&typeof p.circuit==='object'?p.circuit:null};}catch{}\r\n return {version:1,completedSets:0,circuit:null};\r\n}\r\nexport class SetFlow {\r\n constructor(progress=null,{cooldown=null,now=Date.now()}={}){this.progress=readProgress(progress);this.phase='pod';this.sequence=0;this.active=null;this.preview=false;this.restUntil=0;this.hits=0;this.damage=0;this.lastTap=-Infinity;this.lastRestInteraction=-Infinity;this.abilities=new AbilityCooldown(cooldown,now);\r\n  // Battle-pass kit level (D8/D22), 1-5: pod.mjs sets it from battle-pass.mjs (combatLevel)\r\n  // for the track of the set just finished; 1 (the weakest kit) until then.\r\n  this.kitLevel=1;\r\n  // Boss HP and the daily tap-damage cap are per calendar day, not per rest\r\n  // bout, so one boss fight can span all 3 rests of a workout (D20).\r\n  this.damageDay=dayAt(now);this.tapDamageToday=0;this.specialDamageToday=0;this.lastPetTick=null;\r\n }\r\n get xp(){return this.performanceXp??this.progress.completedSets*XP_PER_SET;}\r\n get level(){return this.performanceXp!==undefined?cosmeticLevel(this.xp).level:1+Math.floor(this.xp/XP_PER_LEVEL);}\r\n get coachHealth(){return Math.max(0,bossHp(this.kitLevel??1)-this.damage);}\r\n resetIfNewDay(now){const day=dayAt(now);if(this.damageDay!==day){this.damageDay=day;this.damage=0;this.tapDamageToday=0;this.specialDamageToday=0;}}\r\n // Pet DPS (D22) accrues for the time since the last tap/rest-start, capped\r\n // at 30s so a long idle gap can't award a lump of pet damage.\r\n // ponytail: only ticks on tap(), so an idle pet (no taps) deals no damage —\r\n // add a rest-phase timer if a truly continuous idle tick matters later.\r\n petTick(now){const dps=kitPetDps(this.kitLevel??1);const last=this.lastPetTick??now;this.lastPetTick=now;return dps>0?dps*Math.max(0,Math.min(30,(now-last)/1000)):0;}\r\n touchRest(now=Date.now()){if(this.phase==='rest')this.lastRestInteraction=Math.max(this.lastRestInteraction,now);}\r\n shouldEndRest(now=Date.now()){return this.phase==='rest'&&now>=Math.max(this.restUntil,this.lastRestInteraction)+REST_IDLE_MS;}\r\n get attackDamage(){return weaponDamage(this.combat,this.weapon);}\r\n start(mode,goal=DEFAULT_GOALS[mode],restSeconds=REST_SECONDS,options={}){\r\n  if(!Object.hasOwn(DEFAULT_GOALS,mode))throw new Error('Unknown exercise');\r\n  this.active={id:++this.sequence,mode,goal:Math.max(1,Number(goal)||DEFAULT_GOALS[mode]),restSeconds:Math.max(15,Math.min(180,Number(restSeconds)||REST_SECONDS))};this.phase='set';this.preview=false;this.workout=options.performance?new PerformanceWorkout({mode,kind:EXERCISES[mode]?.kind??(['tree','warrior','horse'].includes(mode)?'hold':'reps'),...options}):null;if(this.workout)this.active.restSeconds=30;return this.active;\r\n }\r\n consume(m,now){\r\n  if(this.phase!=='set'||!this.active||m.mode!==this.active.mode)return null;\r\n  if(this.workout){const result=this.workout.update(m,now);return result?this.completePerformance(result,now,m.name):null;}\r\n  const reached=valueOf(m)>=this.active.goal;\r\n  if(!reached)return null;\r\n  // Timed boxing needs observed hand movement, not simply an unattended timer.\r\n  const earned=m.kind!=='pace'||m.active>0;\r\n  if(earned)this.progress.completedSets++;\r\n  this.resetIfNewDay(now);\r\n  this.phase='rest';this.preview=false;this.restUntil=now+this.active.restSeconds*1000;this.hits=0;this.lastTap=-Infinity;this.lastRestInteraction=-Infinity;this.lastPetTick=now;\r\n  return {mode:m.mode,name:m.name,value:valueOf(m),goal:this.active.goal,earned,xp:earned?XP_PER_SET:0,level:this.level,set:this.progress.completedSets};\r\n }\r\n completePerformance(result,now,name){\r\n  this.resetIfNewDay(now);this.phase='rest';this.preview=false;this.restUntil=now+30000;this.hits=0;this.lastTap=-Infinity;this.lastRestInteraction=-Infinity;this.lastPetTick=now;\r\n  return {...result,name:name??EXERCISES[result.mode]?.name??result.mode,goal:this.active.goal,xp:result.xpBase,level:this.level,set:this.progress.completedSets+1};\r\n }\r\n finishWorking(m,now=Date.now()){\r\n  if(this.phase!=='set'||!this.workout)return null;const result=this.workout.update(m,now)??this.workout.finish();return result?this.completePerformance(result,now,m.name):null;\r\n }\r\n previewRest(now,seconds=REST_SECONDS){this.resetIfNewDay(now);this.phase='rest';this.preview=true;this.restUntil=now+seconds*1000;this.hits=0;this.lastTap=-Infinity;this.lastRestInteraction=-Infinity;this.lastPetTick=now;}\r\n remaining(now){return Math.max(0,Math.ceil((this.restUntil-now)/1000));}\r\n extend(seconds=30,now=Date.now()){if(this.phase==='rest')this.restUntil=Math.max(this.restUntil,now)+seconds*1000;}\r\n tap(now,withHand=false){\r\n  this.touchRest(now);\r\n  if(this.phase!=='rest'||now-this.lastTap<180)return null;\r\n  this.resetIfNewDay(now);this.beforeRestAttack?.(now);if(this.restBossId&&this.coachHealth<=0)return null;\r\n  const level=this.kitLevel??1;\r\n  if(this.tapDamageToday>=dailyCap(level))return null; // daily cap reached: no further damage events\r\n  this.lastTap=now;this.hits++;\r\n  const assisted=withHand&&this.hits%3===0,warmth=this.workout?(this.workout.stage==='preparation-rest'?(this.workout.nextStage==='working'?2:1):3):1,damage=tapDamage(level,this.combat,now)*warmth+this.petTick(now);\r\n  this.tapDamageToday+=Math.min(damage,this.restBossId?this.coachHealth:damage);this.damage+=damage;this.onRestDamage?.(now);\r\n  return {hits:this.hits,damage,totalDamage:this.damage,blocked:damage===0,assisted,charge:withHand?this.hits%3:0,bossAttack:this.hits%BOSS_ATTACK_EVERY_HITS===0};\r\n }\r\n preparationTap(now=Date.now(),withHand=false){if(this.phase!=='set'||this.workout?.stage!=='preparation-rest')return null;this.phase='rest';try{return this.tap(now,withHand);}finally{this.phase='set';}}\r\n special(weapon,{now=Date.now(),progress,catalog}={}){this.touchRest(now);this.resetIfNewDay(now);const level=this.kitLevel??1;if(this.phase==='rest'){this.beforeRestAttack?.(now);if(this.restBossId&&this.coachHealth<=0)return {ok:false,reason:'boss-defeated'};}\r\n if(level<SPECIAL_LEVEL)return {ok:false,reason:'level',unlockLevel:SPECIAL_LEVEL}; // D17: specials unlock at L3\r\n if(this.tapDamageToday>=dailyCap(level))return {ok:false,reason:'daily-cap'}; // both checked before activate() so a refused special never burns its cooldown\r\n const result=this.abilities.activate(weapon,{now,progress,catalog,inRest:this.phase==='rest'});if(!result.ok)return result;\r\n // Legacy weapon-tier damage, capped by the day's special budget (combat-config SPECIAL_DAMAGE_FRACTION).\r\n const damage=Math.min(weaponDamage(this.combat,weapon,now),Math.max(0,specialBudget(level)-this.specialDamageToday));this.specialDamageToday+=damage;this.damage+=damage;this.onRestDamage?.(now);return {...result,special:true,assisted:false,damage,totalDamage:this.damage,blocked:damage===0,hits:this.hits};}\r\n leave(){this.phase='pod';this.active=null;}\r\n}\r\n","pod/set-transition.mjs":"// #150 (Ian, D46): a finished set goes into rest through the wormhole and comes back out through it, slow enough to\r\n// load under it and to put the phone down or pick it up. Each trip is one pair: 'in' covers the screen, swap() changes\r\n// what is under it, 'out' opens it again (playWormhole('in') leaves its cover up until 'out' removes it).\r\n// Never over the live camera (D24); without the portal or with reduced motion, a plain fade.\r\nexport const TRANSITION_MIN_MS=2600; // the one knob: how long each trip keeps the screen moving/covered\r\nexport const FADE_MS=600;\r\nexport const LINES={rest:'Set complete — put the phone down, rest starts in a moment',practice:'Rest starts in a moment',next:'Next set — pick up your phone',home:'Leaving rest'};\r\nconst reducedMotion=()=>!!globalThis.matchMedia?.('(prefers-reduced-motion: reduce)').matches;\r\nfunction cover(text,fade){\r\n const el=document.createElement('div');el.className='set-transition';el.setAttribute('role','status');el.textContent=text;\r\n el.style.cssText=`position:fixed;inset:0;margin:0;padding:0 24px 22vh;border:0;width:auto;height:auto;max-width:none;max-height:none;display:flex;align-items:flex-end;justify-content:center;text-align:center;box-sizing:border-box;pointer-events:none;z-index:10001;color:#fff;font:600 17px/1.35 system-ui,sans-serif;text-shadow:0 1px 6px #000,0 0 14px #000;background:${fade?'#000':'transparent'}`;\r\n document.body.append(el);if(el.showPopover){el.setAttribute('popover','manual');el.showPopover();}\r\n return el;\r\n}\r\nconst fadeTo=(el,to)=>el.animate([{opacity:1-to},{opacity:to}],{duration:FADE_MS/2,easing:'ease',fill:'forwards'}).finished.catch(()=>{});\r\n// Resolves once the new screen is showing; swap()'s error (if any) is rethrown after the cover is gone.\r\nexport async function throughWormhole(text,swap){\r\n const body=document.body;\r\n if(body.dataset.tracking==='true'||body.dataset.cameraWorkout==='true')return swap();\r\n const portal=globalThis.myr5Portal,play=!reducedMotion()&&!portal?.disposed&&typeof portal?.playWormhole==='function'?portal.playWormhole:null;\r\n const half=TRANSITION_MIN_MS/2,wasInert=body.inert;body.inert=true; // the tunnel lets taps through; nothing under it is live\r\n let el=null;\r\n try{\r\n  if(play){const going=play({direction:'in',minMs:half});el=cover(text,false);await going;}\r\n  else{el=cover(text,true);await fadeTo(el,1);}\r\n  await swap();\r\n }finally{\r\n  try{if(play)await play({direction:'out',minMs:half});else if(el)await fadeTo(el,0);}catch{}\r\n  el?.remove();body.inert=wasInert;\r\n }\r\n}\r\n","pod/ship-backdrop.mjs":"import {requestPhoneMotion,createTiltLook} from '../character-phone-sensor.mjs';\r\n/** Keep the decorative pod scene moving only while the pod page is the visible workspace. */\r\nexport function mountShipBackdropMotion({root=document.getElementById('podShipBackdrop'),body=document.body,doc=document}={}){\r\n if(!root||!body||!doc)return ()=>{};\r\n const reduce=doc.defaultView?.matchMedia?.('(prefers-reduced-motion: reduce)');\r\n const view=doc.defaultView,tiltKey='myr5.tiltPermission';\r\n let tiltFrame=0,nx=0,ny=0,bx=0,by=0,cx=0,cy=0,bt=0,ct=0,lastFrame=0,sensorActive=false;\r\n const look=createTiltLook(view);\r\n const clearTilt=()=>{nx=ny=bx=by=cx=cy=bt=ct=0;body.style.setProperty('--pod-bg-x','0px');body.style.setProperty('--pod-bg-y','0px');body.style.setProperty('--pod-bg-tilt','0deg');body.style.setProperty('--pod-controls-x','0px');body.style.setProperty('--pod-controls-y','0px');body.style.setProperty('--pod-controls-tilt','0deg');};\r\n const tickTilt=now=>{\r\n  tiltFrame=0;if(root.dataset.motionRunning!=='true'){lastFrame=0;clearTilt();return;}\r\n  const elapsed=lastFrame?Math.min(100,Math.max(0,now-lastFrame)):16;lastFrame=now;\r\n  const bg=1-Math.exp(-elapsed/120),controls=1-Math.exp(-elapsed/360);\r\n  bx+=(nx*24-bx)*bg;by+=(ny*24-by)*bg;bt+=(nx*12-bt)*bg;\r\n  cx+=(nx*4-cx)*controls;cy+=(ny*4-cy)*controls;ct+=(nx*1.5-ct)*controls;\r\n  body.style.setProperty('--pod-bg-x',bx.toFixed(2)+'px');body.style.setProperty('--pod-bg-y',by.toFixed(2)+'px');body.style.setProperty('--pod-bg-tilt',bt.toFixed(2)+'deg');\r\n  body.style.setProperty('--pod-controls-x',cx.toFixed(2)+'px');body.style.setProperty('--pod-controls-y',cy.toFixed(2)+'px');body.style.setProperty('--pod-controls-tilt',ct.toFixed(2)+'deg');\r\n  if(Math.abs(nx*24-bx)+Math.abs(ny*24-by)+Math.abs(nx*4-cx)+Math.abs(ny*4-cy)>.08)tiltFrame=requestAnimationFrame(tickTilt);\r\n };\r\n const kickTilt=()=>{if(!tiltFrame&&root.dataset.motionRunning==='true')tiltFrame=requestAnimationFrame(tickTilt);};\r\n const pointerMove=event=>{if(root.dataset.motionRunning!=='true')return;const w=Math.max(1,doc.documentElement.clientWidth),h=Math.max(1,doc.documentElement.clientHeight);nx=Math.max(-1,Math.min(1,(event.clientX/w-.5)*2));ny=Math.max(-1,Math.min(1,(event.clientY/h-.5)*2));kickTilt();};\r\n const pointerLeave=()=>{nx=ny=0;kickTilt();};\r\n const orientation=event=>{\r\n  if(root.dataset.motionRunning!=='true')return;\r\n  const t=look.read(event,view.performance.now());if(!t)return;\r\n  nx=t.x;ny=t.y;kickTilt();\r\n };\r\n const startSensor=()=>{\r\n  if(sensorActive||!view?.DeviceOrientationEvent)return;\r\n  view.addEventListener('deviceorientation',orientation);sensorActive=true;look.reset();\r\n };\r\n const stopSensor=()=>{if(sensorActive)view?.removeEventListener('deviceorientation',orientation);sensorActive=false;look.reset();};\r\n const requestSensor=async()=>{\r\n  const api=view?.DeviceOrientationEvent;\r\n  if(!api?.requestPermission)return;\r\n  let answer='denied';try{answer=await requestPhoneMotion()?'granted':'denied';}catch{}\r\n  try{view.localStorage.setItem(tiltKey,answer==='granted'?'granted':'denied');}catch{}\r\n  if(answer==='granted'){startSensor();sensorButton?.remove();}\r\n };\r\n const sensorButton=view?.DeviceOrientationEvent?.requestPermission?doc.createElement('button'):null;\r\n if(sensorButton){sensorButton.type='button';sensorButton.className='pod-tilt-request';sensorButton.textContent='Enable tilt';sensorButton.setAttribute('aria-label','Enable device tilt to look around');sensorButton.addEventListener('click',requestSensor);doc.querySelector('.ship-header')?.append(sensorButton);}\r\n const active=()=>{\r\n  const workoutHome=doc.getElementById('portalWorkoutHome');\r\n  const portalHome=doc.getElementById('portalHome');\r\n  const portalShowing=!!portalHome&&!portalHome.hidden&&!workoutHome?.open;\r\n  const covered=portalShowing||[...doc.querySelectorAll('dialog[open]')].some(dialog=>dialog.id!=='portalWorkoutHome');\r\n  const onPod=body.dataset.screen==='pod'&&body.dataset.tracking!=='true'&&!covered;\r\n  const running=onPod&&!doc.hidden&&!reduce?.matches;\r\n  root.dataset.motionRunning=String(running);\r\n  root.dataset.visible=String(onPod);\r\n  if(running){\r\n   let stored='';try{stored=view.localStorage.getItem(tiltKey)||'';}catch{}\r\n   if(!view?.DeviceOrientationEvent?.requestPermission||stored==='granted')startSensor();\r\n  }else{stopSensor();nx=ny=0;lastFrame=0;cancelAnimationFrame(tiltFrame);tiltFrame=0;clearTilt();}\r\n };\r\n const routeObserver=new MutationObserver(active);\r\n routeObserver.observe(body,{attributes:true,attributeFilter:['data-screen','data-tracking','open','hidden'],subtree:true});\r\n // Runtime portal dialogs are attached directly to body; this small observer detects their insertion.\r\n const modalObserver=new MutationObserver(active);\r\n modalObserver.observe(body,{childList:true});\r\n doc.addEventListener('visibilitychange',active);\r\n doc.addEventListener('pointermove',pointerMove,{passive:true});doc.defaultView?.addEventListener('blur',pointerLeave);\r\n reduce?.addEventListener?.('change',active);\r\n  const onPageHide=event=>{if(!event.persisted)cleanup();else root.dataset.motionRunning='false';};\r\n const onPageShow=()=>active();\r\n view?.addEventListener('pagehide',onPageHide);\r\n view?.addEventListener('pageshow',onPageShow);\r\n active();\r\n function cleanup(){\r\n  routeObserver.disconnect();modalObserver.disconnect();doc.removeEventListener('visibilitychange',active);\r\n  doc.removeEventListener('pointermove',pointerMove);view?.removeEventListener('blur',pointerLeave);stopSensor();sensorButton?.remove();cancelAnimationFrame(tiltFrame);tiltFrame=0;lastFrame=0;clearTilt();\r\n  reduce?.removeEventListener?.('change',active);\r\n  view?.removeEventListener('pagehide',onPageHide);view?.removeEventListener('pageshow',onPageShow);\r\n  root.dataset.motionRunning='false';root.dataset.visible='false';\r\n }\r\n return cleanup;\r\n}\r\n","pod/ship-interior.css":"/* R16: decorative ship interior behind the existing pod controls and character. */\r\nbody[data-screen=\"pod\"]{background:transparent!important}\r\nbody[data-screen=\"pod\"]>.ship-header,\r\nbody[data-screen=\"pod\"]>#homeScreen,\r\n#portalWorkoutHome>.ship-header,\r\n#portalWorkoutHome>#homeScreen{position:relative;z-index:1}\r\nbody[data-screen=\"pod\"]>.ship-header,#portalWorkoutHome>.ship-header,\r\nbody[data-screen=\"pod\"]>#homeScreen,#portalWorkoutHome>#homeScreen{translate:var(--pod-controls-x,0px) var(--pod-controls-y,0px);rotate:var(--pod-controls-tilt,0deg)}\r\n\r\n.pod-ship-backdrop{\r\n position:fixed;z-index:0;inset:0 auto auto 50%;transform:translateX(-50%);\r\n width:min(100vw,640px);height:100dvh;overflow:hidden;isolation:isolate;\r\n background:#100b18;pointer-events:none;user-select:none;-webkit-user-select:none;\r\n visibility:hidden;\r\n}\r\nbody[data-screen=\"pod\"] .pod-ship-backdrop[data-visible=\"true\"]{visibility:visible}\r\nbody .pod-ship-backdrop[data-visible=\"false\"]{visibility:hidden}\r\n#portalWorkoutHome.portal-framed.portal-fullscreen{\r\n display:flex!important;flex-direction:column;overflow:hidden;background:transparent!important;\r\n padding:0!important; /* R20: the dock sits below the housing now, so the room reserves no band for it */\r\n}\r\n#portalWorkoutHome>.pod-ship-backdrop{position:absolute;inset:0;width:auto;height:auto;left:0;transform:none;z-index:0;border-radius:inherit}\r\n#portalWorkoutHome>#homeScreen{flex:1 1 auto;min-height:0;height:auto;overflow:hidden}\r\n#portalWorkoutHome>.ship-header{flex:none}\r\n.pod-ship-backdrop img,.pod-ship-lights{position:absolute;display:block;inset:0;width:100%;height:100%;pointer-events:none}\r\n.pod-ship-nebula{\r\n inset:auto!important;left:50%!important;top:50%!important;\r\n width:max(160%,160dvh)!important;height:max(160%,160dvh)!important;max-width:none;\r\n object-fit:cover;translate:calc(-50% + var(--pod-bg-x,0px)) calc(-50% + var(--pod-bg-y,0px));rotate:var(--pod-bg-tilt,0deg);transform-origin:center;\r\n animation:pod-nebula-drift 300s linear infinite;will-change:transform;z-index:0;\r\n}\r\n.pod-ship-cutout{z-index:2;object-fit:fill}\r\n.pod-ship-lights{\r\n z-index:3;opacity:.46;mix-blend-mode:screen;\r\n background:\r\n  radial-gradient(ellipse 8% 2.1% at 50% 7%,#ffe2a033 0,transparent 75%),\r\n  radial-gradient(ellipse 7% 3% at 5% 18%,#ffdfa01a 0,transparent 78%),\r\n  radial-gradient(ellipse 7% 3% at 95% 18%,#ffdfa01a 0,transparent 78%),\r\n  radial-gradient(ellipse 8% 2.5% at 50% 91%,#e5c9ff20 0,transparent 78%);\r\n}\r\n.pod-ship-lights:before,.pod-ship-lights:after{content:\"\";position:absolute;inset:0;pointer-events:none}\r\n.pod-ship-lights:before{\r\n background:\r\n  radial-gradient(ellipse 5.4% 2.2% at 36% 7.7%,#171022 0 35%,transparent 76%),\r\n  radial-gradient(ellipse 5.4% 2.2% at 64% 7.7%,#171022 0 35%,transparent 76%),\r\n  radial-gradient(ellipse 4.5% 3.2% at 5% 16%,#171022 0 32%,transparent 78%),\r\n  radial-gradient(ellipse 4.5% 3.2% at 95% 16%,#171022 0 32%,transparent 78%),\r\n  radial-gradient(ellipse 4.3% 2.6% at 5% 80%,#171022 0 32%,transparent 78%),\r\n  radial-gradient(ellipse 4.3% 2.6% at 95% 80%,#171022 0 32%,transparent 78%);\r\n mix-blend-mode:multiply;opacity:.05;animation:pod-lamp-dim 11.8s ease-in-out infinite;\r\n}\r\n.pod-ship-lights:after{\r\n background:\r\n  radial-gradient(ellipse 5.4% 2.2% at 36% 7.7%,#ffe6a3d9 0,transparent 75%),\r\n  radial-gradient(ellipse 5.4% 2.2% at 64% 7.7%,#ffe6a3d9 0,transparent 75%),\r\n  radial-gradient(ellipse 4.5% 3.2% at 5% 16%,#ffe5aad0 0,transparent 76%),\r\n  radial-gradient(ellipse 4.5% 3.2% at 95% 16%,#ffe5aad0 0,transparent 76%),\r\n  radial-gradient(ellipse 4.3% 2.6% at 5% 80%,#ffe6b9bd 0,transparent 76%),\r\n  radial-gradient(ellipse 4.3% 2.6% at 95% 80%,#ffe6b9bd 0,transparent 76%);\r\n mix-blend-mode:screen;opacity:.02;animation:pod-lamp-glow 13.4s ease-in-out infinite;\r\n}\r\n\r\n/* The hardware artwork is a transparent hologram plate, so the live interface remains the foreground. */\r\nbody[data-screen=\"pod\"]>.ship-header,\r\n#portalWorkoutHome>.ship-header{\r\n --pod-header-gap:clamp(12px,2dvh,20px);\r\n height:calc(72px - var(--pod-header-gap));margin:var(--pod-header-gap) 10px 0;padding:4px 16px;\r\n border:1px solid #c5a4db88;border-radius:13px;\r\n background:repeating-linear-gradient(0deg,#f5e4ff05 0 1px,transparent 1px 4px),linear-gradient(115deg,#39234a66,#291b3f59 55%,#4a2d5c5c);\r\n box-shadow:inset 0 1px #f5e3ff30,inset 0 -1px #a777ce48,0 0 0 1px #24152d99,0 0 22px #b36cdb32;\r\n backdrop-filter:blur(4px) saturate(1.14);-webkit-backdrop-filter:blur(4px) saturate(1.14);\r\n}\r\nbody[data-screen=\"pod\"]>.ship-header:before,\r\n#portalWorkoutHome>.ship-header:before{\r\n content:\"\";position:absolute;inset:3px;pointer-events:none;opacity:.8;filter:drop-shadow(0 0 2px #b877ed);\r\n background:\r\n  linear-gradient(#edd4ff,#edd4ff) left top/14px 1px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) left top/1px 10px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) right top/14px 1px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) right top/1px 10px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) left bottom/14px 1px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) left bottom/1px 10px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) right bottom/14px 1px no-repeat,\r\n  linear-gradient(#edd4ff,#edd4ff) right bottom/1px 10px no-repeat;\r\n}\r\nbody[data-screen=\"pod\"]>.ship-header>*,\r\n#portalWorkoutHome>.ship-header>*{position:relative;z-index:1}\r\nbody[data-screen=\"pod\"]>.ship-header .icon-button,\r\n#portalWorkoutHome>.ship-header .icon-button{\r\n border-color:#bd96d377;background:linear-gradient(145deg,#513561aa,#251a34cc);\r\n box-shadow:inset 0 1px #f6e7ff35,0 0 12px #ba7cdb30;color:#f5e6ff;\r\n}\r\n.pod-tilt-request{min-height:40px;padding:0 9px;border:1px solid #bd96d377;border-radius:9px;background:#251a34cc;color:#f5e6ff;font:600 11px system-ui,sans-serif;touch-action:manipulation}\r\n.pod-tilt-request:focus-visible{outline:3px solid #ffb24d;outline-offset:2px}\r\n\r\n@keyframes pod-nebula-drift{\r\n from{transform:rotate(0deg)}\r\n to{transform:rotate(360deg)}\r\n}\r\n@keyframes pod-lamp-dim{\r\n 0%,62%,100%{opacity:.04}\r\n 64%{opacity:.44}\r\n 66%{opacity:.38}\r\n 68%{opacity:.06}\r\n 70%{opacity:.3}\r\n 72%{opacity:.04}\r\n}\r\n@keyframes pod-lamp-glow{\r\n 0%,66%,100%{opacity:.02}\r\n 68%{opacity:.24}\r\n 70%{opacity:.5}\r\n 72%{opacity:.14}\r\n 74%{opacity:.02}\r\n}\r\n@media(prefers-reduced-motion:reduce){\r\n .pod-ship-nebula,.pod-ship-lights{animation:none!important;will-change:auto}\r\n .pod-ship-lights:before,.pod-ship-lights:after{animation:none!important;opacity:0!important}\r\n}\r\n@media(max-height:700px) and (max-width:600px) and (orientation:portrait){\r\n #homeScreen .pod-header-actions{padding-top:2px;padding-bottom:0}\r\n #homeScreen .deck-strip{height:32px}\r\n #homeScreen #view{min-height:100px}\r\n #homeScreen #view .coach-line{top:2px;padding:1px 5px}\r\n #homeScreen #view .coach-line p{font-size:11px;line-height:1.1;-webkit-line-clamp:1;white-space:nowrap}\r\n #homeScreen #view .home-character{inset:24px 8px 4px}\r\n #homeScreen .workout-console{padding-top:8px;padding-bottom:6px}\r\n}\r\n#podShipBackdrop[data-motion-running=\"false\"] .pod-ship-nebula,\r\n#podShipBackdrop[data-motion-running=\"false\"] .pod-ship-lights,\r\n#podShipBackdrop[data-motion-running=\"false\"] .pod-ship-lights:before,\r\n#podShipBackdrop[data-motion-running=\"false\"] .pod-ship-lights:after{animation-play-state:paused}\r\n","pod/weapon-abilities.css":"#restWeaponFx{position:absolute;inset:0;width:100%;height:100%;z-index:7;pointer-events:none;image-rendering:pixelated}\r\n#restScreen .weapon-evolution .projectile,#restScreen .weapon-evolution .attack-flash{display:none}\r\n#restScreen .weapon-ability{position:absolute;z-index:13;left:12px;top:46%;bottom:auto;transform:translateY(-50%);width:clamp(80px,18vw,104px);aspect-ratio:1;padding:0;background:#181425ed;border:2px solid #87c9c1;box-shadow:4px 4px 0 #090c17}\r\n#restScreen .weapon-ability button{display:block;width:100%;height:100%;min-height:44px;margin:0;border:0;border-radius:0;color:#c2fff1;background:#233e44;box-shadow:none;font:700 .875rem/1.25 var(--room-pixel);padding:8px 6px 14px;overflow-wrap:anywhere}\r\n#restScreen .weapon-ability button:disabled{opacity:1;background:#232c3c;color:#98aebf;cursor:default}\r\n#restScreen .weapon-ability button:focus-visible{outline:3px solid #fff1c8;outline-offset:3px}\r\n#restScreen .weapon-ability progress{position:absolute;left:0;bottom:0;width:100%;height:6px;display:block;border:0;background:#203044;accent-color:#9af5df;pointer-events:none}\r\n#restScreen .weapon-ability progress::-webkit-progress-bar{background:#203044}\r\n#restScreen .weapon-ability progress::-webkit-progress-value{background:#9af5df}\r\n@media(max-height:600px){#restScreen .weapon-ability{left:8px;top:48%;width:80px}}\r\n","pod/weapon-animator.mjs":"import {evolution} from './weapon-evolution.mjs';\r\n\r\nconst TAU = Math.PI * 2;\r\nconst clamp = value => Math.max(0, Math.min(1, value));\r\nconst point = (x, y) => [Math.round(x), Math.round(y)];\r\n\r\nfunction polygon(ctx, vertices, color, alpha = 1) {\r\n  ctx.save(); ctx.globalAlpha *= alpha; ctx.fillStyle = color; ctx.beginPath();\r\n  vertices.forEach(([x, y], i) => i ? ctx.lineTo(Math.round(x), Math.round(y)) : ctx.moveTo(Math.round(x), Math.round(y)));\r\n  ctx.closePath(); ctx.fill(); ctx.restore();\r\n}\r\nfunction line(ctx, vertices, color, width = 2, alpha = 1) {\r\n  ctx.save(); ctx.globalAlpha *= alpha; ctx.strokeStyle = color; ctx.lineWidth = width; ctx.lineJoin = 'miter'; ctx.beginPath();\r\n  vertices.forEach(([x, y], i) => i ? ctx.lineTo(Math.round(x), Math.round(y)) : ctx.moveTo(Math.round(x), Math.round(y)));\r\n  ctx.stroke(); ctx.restore();\r\n}\r\nfunction arc(ctx, x, y, radius, from, to, color, width = 2, alpha = 1) {\r\n  const count = Math.max(5, Math.ceil(Math.abs(to - from) * 5));\r\n  line(ctx, Array.from({length: count + 1}, (_, i) => point(x + Math.cos(from + (to - from) * i / count) * radius, y + Math.sin(from + (to - from) * i / count) * radius)), color, width, alpha);\r\n}\r\nfunction diamond(ctx, x, y, size, color, alpha = 1) {\r\n  polygon(ctx, [[x, y-size], [x+size, y], [x, y+size], [x-size, y]], color, alpha);\r\n}\r\n\r\n// Renders within the caller's canvas/transform. All timing is caller supplied;\r\n// no timers, event listeners, storage, or workout state live in the renderer.\r\nexport function drawAnimatedWeapon(ctx, value, {\r\n  weapons = globalThis.GalaWeapons,\r\n  x = 90, y = 90, scale = 1, now = 0, action = null, reducedMotion = false,\r\n} = {}) {\r\n  const p = evolution(value);\r\n  const duration = action?.special && p.ability ? p.ability.animationMs : p.attackMs;\r\n  const age = action ? (now - action.startedAt) / duration : -1;\r\n  const active = age >= 0 && age < 1;\r\n  const a = clamp(age), special = active && action.special && !!p.ability;\r\n  const pulse = active ? Math.sin(a * Math.PI) : 0;\r\n  const windup = active ? Math.sin(clamp(a / .23) * Math.PI / 2) : 0;\r\n  const power = (special ? 1.5 + p.stage * .11 : 1) * pulse;\r\n  const motion = p.family.motion;\r\n  const t = reducedMotion ? 0 : now / 1000;\r\n  const float = reducedMotion ? 0 : Math.sin(t * 1.7) * p.idleLift;\r\n  const reach = p.reach * (special ? 1.25 : 1);\r\n  const extent = special ? p.stage + 2 : 1;\r\n  const ranged = ['rail','lance','fork','rockets','arrow','gauss','burst'].includes(motion);\r\n  const horizontal = ['arc','plasma','sonic'].includes(motion);\r\n  let dx = 0, dy = float, rotation = ranged ? Math.PI / 2 : horizontal ? 0 : -.14;\r\n  if (active && !reducedMotion) {\r\n    if (motion === 'cut' || motion === 'reap') rotation += -1.15 + a * 2.9;\r\n    else if (motion === 'cleave') { rotation += -1.25 + a * 2.7; dy -= windup * 12 * (1 - a); }\r\n    else if (motion === 'blink') { dx = Math.sin(a * Math.PI) * reach; rotation += Math.sin(a * TAU) * .65; }\r\n    else if (motion === 'return') { dx = Math.sin(a * Math.PI) * reach; dy -= Math.sin(a * TAU) * 14; rotation += a * TAU * (2 + p.stage); }\r\n    else if (motion === 'rush') { dx = Math.sin(a * Math.PI) * 16; rotation = Math.sin(a * TAU * extent) * .45; }\r\n    else if (ranged || horizontal) { dx -= power * 7; rotation -= pulse * .09; }\r\n    else { dy -= power * 12; rotation += Math.sin(a * TAU) * .2; }\r\n  }\r\n\r\n  ctx.save(); ctx.translate(Math.round(x), Math.round(y)); ctx.scale(scale, scale); ctx.imageSmoothingEnabled = false;\r\n  // Slow orbiting hardware remains legible in idle and reduced-motion mode.\r\n  for (let k = 0; k < p.orbitCount; k++) {\r\n    const theta = t * .7 + k * TAU / p.orbitCount;\r\n    diamond(ctx, Math.cos(theta) * (24 + p.tier), Math.sin(theta) * (23 + p.tier * .4), 2 + p.stage * .35, p.energy, .5);\r\n  }\r\n  if (p.tier >= 12) arc(ctx, 0, 0, 24 + p.tier, -.7 + t * .12, 2.9 + t * .12, p.accent, 1, .22);\r\n\r\n  if (active && !reducedMotion) {\r\n    // Charge converges into the weapon before release. Advanced tiers add\r\n    // stepped afterimages, without large white flashes or camera shake.\r\n    if (a < .26) {\r\n      for (let k = 0; k < p.trailCount; k++) {\r\n        const theta = k * TAU / p.trailCount + t;\r\n        const r = (1 - a / .26) * (reach * .6) + 8;\r\n        diamond(ctx, Math.cos(theta) * r, Math.sin(theta) * r, 2, p.accent, .65);\r\n      }\r\n    }\r\n    for (let k = p.trailCount; k > 0; k--) {\r\n      if (motion === 'blink' || motion === 'rush' || motion === 'return') {\r\n        ctx.save(); ctx.globalAlpha = .06 + .08 * (1 - k / (p.trailCount + 1));\r\n        ctx.translate(dx - k * (special ? 9 : 5), dy); ctx.rotate(rotation);\r\n        weapons.draw(ctx, value, {x: -20, y: -40, palette: p}); ctx.restore();\r\n      }\r\n    }\r\n  }\r\n\r\n  // Additional geometry follows the defining family rather than applying a\r\n  // single generic decoration to every weapon. Proportions grow each tier.\r\n  ctx.save(); ctx.translate(Math.round(dx), Math.round(dy)); ctx.rotate(rotation);\r\n  ctx.scale(p.width * .8, p.length * .8);\r\n  weapons.draw(ctx, value, {x: -20, y: -40, palette: p});\r\n  if (p.tier > 0) {\r\n    const fin = p.finLength, count = 1 + p.stage;\r\n    if (['cut','cleave','blink','lance','fork','reap'].includes(motion)) {\r\n      for (const side of [-1, 1]) polygon(ctx, [[side*5,-8],[side*(7+fin*.32),-24-fin],[side*3,-29-fin],[side*3,-8]], p.accent, .65);\r\n    } else if (ranged || horizontal) {\r\n      for (let k = 0; k < count; k++) {\r\n        const yy = horizontal ? -15 : -25 - k * 3;\r\n        polygon(ctx, [[-13,yy],[-13-fin*.45,yy-4],[-13-fin*.45,yy+6],[-11,yy+4]], p.energy, .75);\r\n      }\r\n    } else if (motion === 'return') {\r\n      for (let k = 0; k < 3 + p.stage; k++) {\r\n        const theta = k * TAU / (3 + p.stage);\r\n        polygon(ctx, [[Math.cos(theta)*15,Math.sin(theta)*18-8],[Math.cos(theta+.16)*(20+fin*.3),Math.sin(theta+.16)*(23+fin*.3)-8],[Math.cos(theta+.3)*15,Math.sin(theta+.3)*18-8]], p.accent);\r\n      }\r\n    } else if (motion === 'rush') {\r\n      for (const side of [-1,1]) polygon(ctx, [[side*9,-18],[side*(9+fin*.5),-25-fin*.3],[side*14,-11]], p.accent);\r\n    } else {\r\n      for (let k = 0; k < count; k++) {\r\n        const theta = k * TAU / count - Math.PI / 2;\r\n        diamond(ctx, Math.cos(theta)*(22+fin*.2), Math.sin(theta)*(28+fin*.2)-4, 1.5+p.stage*.3, p.accent);\r\n      }\r\n    }\r\n  }\r\n  ctx.restore();\r\n\r\n  if (active && reducedMotion) {\r\n    // A contained, stationary emblem conveys an attack with no shake, rush,\r\n    // repeated blinking, or moving background.\r\n    diamond(ctx, 32, -16, special ? 11 : 6, p.energy, .75);\r\n    arc(ctx, 32, -16, special ? 16 : 10, 0, TAU, p.accent, 2, .65);\r\n  } else if (active && a > .18) {\r\n    const travel = clamp((a - .18) / .62), fade = Math.min(1, (1 - a) * 3.5);\r\n    const target = 32 + travel * reach, burst = Math.sin(travel * Math.PI);\r\n    const beam = (vertices, width = 2, alpha = 1, color = p.energy) => line(ctx, vertices, color, width, fade * alpha);\r\n    const ring = (xx, yy, radius, width = 2, alpha = 1) => arc(ctx, xx, yy, radius, 0, TAU, p.energy, width, fade * alpha);\r\n    const slash = (yy, reverse = false) => {\r\n      const radius = reach * (.58 + burst * .35);\r\n      for (let k = 0; k < p.trailCount; k++) arc(ctx, 8, yy, radius-k*3, (reverse?-.1:-1.4)+travel*.45, (reverse?1.5:.5)+travel*.55, k===0?p.core:p.energy, k===0?2:3, fade/(1+k*.35));\r\n    };\r\n    switch (motion) {\r\n      case 'cut': slash(-6); if (special) slash(14, true); break;\r\n      case 'cleave':\r\n        slash(6); beam([[24,-45],[target,32],[target+reach*.35,32]], 4+power*5);\r\n        if (special) for(let k=0;k<extent;k++) beam([[target,32],[target+(k-extent/2)*9,16-k*3],[target+(k-extent/2)*14,28]],2);\r\n        break;\r\n      case 'blink':\r\n        for(let k=0;k<extent;k++) beam([[target-k*9-9,-16+k*5],[target-k*9+10,6+k*5]],2+k%2);\r\n        break;\r\n      case 'arc':\r\n        for(let k=0;k<extent;k++) beam([[16,-10],[target*.4,-18+k*7],[target*.6,-4+k*4],[target,-14+k*8]],2);\r\n        break;\r\n      case 'burst':\r\n        for(let k=0;k<2+extent;k++) { const xx=24+((travel+k*.17)%1)*reach; beam([[xx-10,-12+k*5],[xx+5,-12+k*5]],2+special); }\r\n        break;\r\n      case 'rail':\r\n        beam([[5,-6],[32+reach,-6]],3+power*5); beam([[5,-6],[32+reach,-6]],2,1,p.core);\r\n        for(let k=0;k<extent;k++) ring(25+k*reach/extent,-6,5+burst*(6+p.stage),1,.7);\r\n        break;\r\n      case 'chain':\r\n        for(let k=0;k<extent+1;k++) { const yy=(k-extent/2)*12; beam([[0,-20],[25,-8],[48,yy-10],[65,yy+2],[target,yy-5]],2); diamond(ctx,target,yy-5,3,p.core,fade); }\r\n        break;\r\n      case 'drone':\r\n        for(let k=0;k<extent;k++) { const yy=Math.sin(travel*TAU+k)* (14+p.stage*3); beam([[target-20,yy-8],[target-9,yy],[target,yy]],1,.7); diamond(ctx,target,yy,4+p.stage*.5,p.energy,fade); }\r\n        break;\r\n      case 'lance':\r\n        polygon(ctx, [[12,-8],[target+30,-13-power*2],[target+43, -5],[target+30,3+power*2],[12,-2]],p.energy,fade*.8);\r\n        beam([[16,-5],[target+36,-5]],2,1,p.core); break;\r\n      case 'fork':\r\n        for(let k=-1;k<=1;k++) { const yy=k*(12+travel*16); beam([[0,k*7],[target,yy]],2+power*2); diamond(ctx,target,yy,3+p.stage,p.accent,fade); if(special)ring(target,yy,7+burst*10,1); }\r\n        break;\r\n      case 'rockets':\r\n        for(let k=0;k<2+extent;k++) { const yy=-Math.sin(travel*Math.PI)*(18+k*6)+k*5; beam([[target-13,yy+7],[target-6,yy+1],[target,yy]],2,.7); diamond(ctx,target,yy,3,p.accent,fade); if(travel>.8)ring(target,yy,4+burst*12,2); } break;\r\n      case 'reap': slash(-2); ring(target*.6,-6,10+burst*15,3,.7); if(special)slash(15,true); break;\r\n      case 'arrow':\r\n        for(let k=0;k<extent;k++) { const yy=(k-(extent-1)/2)*9; beam([[target-26,yy],[target+7,yy]],2); polygon(ctx,[[target+14,yy],[target+2,yy-5],[target+2,yy+5]],p.core,fade); } break;\r\n      case 'gauss':\r\n        for(let k=0;k<extent;k++) { const xx=target-k*11; diamond(ctx,xx,-6,7+p.stage,p.energy,fade); beam([[xx-23,-6],[xx,-6]],2,.8,p.accent); } break;\r\n      case 'return':\r\n        for(let k=0;k<extent;k++) arc(ctx,dx,dy,18+k*5,travel*TAU+k,travel*TAU+k+4,p.energy,2,fade*.8); break;\r\n      case 'rush':\r\n        for(let k=0;k<3+extent;k++) { const xx=20+((travel+k*.13)%1)*reach*.8,yy=Math.sin(k*2.1)*14; beam([[xx-19,yy],[xx+2,yy]],3); diamond(ctx,xx+5,yy,4+p.stage,p.accent,fade); } break;\r\n      case 'gravity':\r\n        polygon(ctx,Array.from({length:12},(_,k)=>{const theta=k*TAU/12;return [target*.7+Math.cos(theta)*(8+burst*18),-6+Math.sin(theta)*(8+burst*18)];}),'#080a1b',fade);\r\n        for(let k=0;k<extent+1;k++) arc(ctx,target*.7,-6,12+burst*19+k*4,k+t,-k+t+4,p.energy,2,fade*.8);\r\n        break;\r\n      case 'sonic':\r\n        for(let k=0;k<extent+1;k++) arc(ctx,8+k*15+travel*reach*.7,-5,8+travel*(18+p.tier)-k*2,-1.15,1.15,p.energy,2+special,fade*.8); break;\r\n      case 'swarm':\r\n        for(let k=0;k<4+extent*2;k++) { const theta=k*2.399+t*3; const xx=target*.8+Math.cos(theta)*(8+burst*16),yy=Math.sin(theta)*(12+burst*14); beam([[xx-7,yy+5],[xx,yy]],1,.6); diamond(ctx,xx,yy,2+k%2,p.energy,fade); } break;\r\n      case 'plasma':\r\n        beam([[10,-6],[target,-6]],6+power*8,.7);\r\n        diamond(ctx,target,-6,9+power*(7+p.stage),p.energy,fade);\r\n        diamond(ctx,target,-6,4+power*4,p.core,fade);\r\n        if(special)for(let k=0;k<extent;k++)ring(target,-6,12+k*5+burst*10,1,.55);\r\n        break;\r\n    }\r\n    // Deterministic shards use tier-driven counts; no random allocations or\r\n    // particle objects accumulate between frames.\r\n    if (special && travel > .5) {\r\n      for(let k=0;k<p.particleCount;k++) {\r\n        const theta=k*2.399, radius=(travel-.5)*(20+(k%7)*8+p.tier);\r\n        diamond(ctx,32+reach*.7+Math.cos(theta)*radius,Math.sin(theta)*radius*.65,1+k%2,k%3?p.energy:p.accent,fade*.7);\r\n      }\r\n    }\r\n  }\r\n  ctx.restore();\r\n  return {active, progress: a, profile: p};\r\n}\r\n","pod/weapon-evolution.mjs":"// Presentation and ability proposals. Saved weapon IDs and earned requirements\r\n// remain owned by GalaWeapons; this module does not award workout progress.\r\nconst definitions = [\r\n  ['rapier', 'cut', 186, 8, ['Crescent cut', 'Twin crescent', 'Sky sever', 'Rift ballet', 'Horizon split']],\r\n  ['greatsword', 'cleave', 215, 12, ['Heavy arc', 'Fault line', 'Meteor cleave', 'World breaker', 'Heaven fall']],\r\n  ['dagger', 'blink', 284, 6, ['Phase step', 'Double take', 'Ghost rush', 'Afterimage storm', 'Zero moment']],\r\n  ['sabre', 'arc', 191, 7, ['Arc shot', 'Ricochet', 'Chain flash', 'Lightning fan', 'Thunder crown']],\r\n  ['axe', 'burst', 153, 9, ['Pulse burst', 'Split volley', 'Crossfire', 'Aurora barrage', 'Infinite salvo']],\r\n  ['hammer', 'rail', 210, 14, ['Rail shot', 'Twin rail', 'Ion tunnel', 'Orbital piercer', 'Skyline erase']],\r\n  ['mace', 'chain', 271, 10, ['Coil lash', 'Forked current', 'Tesla web', 'Storm cage', 'Living lightning']],\r\n  ['flail', 'drone', 164, 10, ['Drone dive', 'Twin dive', 'Hunter spiral', 'Satellite rush', 'Constellation fall']],\r\n  ['spear', 'lance', 182, 9, ['Lance thrust', 'Triple pierce', 'Comet lance', 'Starfall spear', 'Event horizon']],\r\n  ['trident', 'fork', 233, 11, ['Tri-beam', 'Prism fork', 'Ninefold light', 'Sky lattice', 'Prism cathedral']],\r\n  ['halberd', 'rockets', 22, 14, ['Rocket salvo', 'Cluster bloom', 'Meteor rain', 'Orbital garden', 'Supernova parade']],\r\n  ['scythe', 'reap', 292, 12, ['Gravity sweep', 'Twin moon', 'Orbit harvest', 'Rift scythe', 'Eclipse reaper']],\r\n  ['bow', 'arrow', 168, 10, ['Photon arrow', 'Split star', 'Comet rain', 'Heaven string', 'Constellation arrow']],\r\n  ['crossbow', 'gauss', 216, 11, ['Gauss bolt', 'Capacitor burst', 'Prism bolt', 'Warp volley', 'Luminous spearhead']],\r\n  ['chakram', 'return', 308, 8, ['Orbit throw', 'Twin orbit', 'Solar wheel', 'Rift carousel', 'Galaxy return']],\r\n  ['gauntlets', 'rush', 25, 7, ['Power rush', 'Twin impact', 'Meteor fists', 'Dragon engine', 'Thousand suns']],\r\n  ['staff', 'gravity', 259, 14, ['Gravity well', 'Twin wells', 'Orbit crush', 'Singularity', 'Pocket universe']],\r\n  ['wand', 'sonic', 179, 9, ['Sonic ring', 'Triple echo', 'Resonance wall', 'Aurora wave', 'Universe echo']],\r\n  ['tome', 'swarm', 147, 12, ['Nanite rush', 'Split hive', 'Prism swarm', 'Astral flock', 'Living constellation']],\r\n  ['cannon', 'plasma', 320, 16, ['Plasma bloom', 'Twin reactor', 'Solar lance', 'Supernova', 'Impossible sun']],\r\n];\r\n\r\nexport const ABILITY_TIERS = Object.freeze([4, 8, 12, 16, 20]);\r\nexport const WEAPON_FAMILIES = Object.freeze(Object.fromEntries(definitions.map(\r\n  ([id, motion, hue, cooldown, moves]) => [id, Object.freeze({id, motion, hue, cooldown, moves: Object.freeze(moves)})],\r\n)));\r\nexport const MAX_COOLDOWN_MS = 40_000;\r\n\r\nexport function normalizeWeapon(value) {\r\n  if (!value || !Object.hasOwn(WEAPON_FAMILIES, value.type) ||\r\n      !Number.isInteger(value.tier) || value.tier < 0 || value.tier > 20) {\r\n    throw new Error('Unknown weapon or tier.');\r\n  }\r\n  return {type: value.type, tier: value.tier};\r\n}\r\n\r\nexport function evolution(value) {\r\n  const weapon = normalizeWeapon(value), family = WEAPON_FAMILIES[weapon.type];\r\n  const t = weapon.tier, stage = Math.floor(t / 4), fraction = t / 20;\r\n  // Every adjacent tier changes hue, proportions, and footprint. Milestones\r\n  // add silhouettes/choreography without resetting the smaller tier gains.\r\n  const hue = (family.hue + t * 4.7) % 360;\r\n  return {\r\n    ...weapon, family, stage, fraction,\r\n    energy: `hsl(${hue.toFixed(1)} 96% ${62 + fraction * 17}%)`,\r\n    accent: `hsl(${(hue + 55) % 360} 100% ${70 + fraction * 12}%)`,\r\n    shell: `hsl(${(family.hue + t * 2) % 360} ${18 + fraction * 24}% ${35 + fraction * 42}%)`,\r\n    core: '#f4fbff',\r\n    width: 1 + t * .023,\r\n    length: 1 + t * .031,\r\n    reach: 35 + t * 2.8,\r\n    trailCount: 1 + Math.floor(t / 3),\r\n    particleCount: 3 + t * 2,\r\n    orbitCount: stage,\r\n    finLength: 2 + t * .65,\r\n    idleLift: 1.5 + t * .12,\r\n    attackMs: Math.max(350, 680 - t * 11),\r\n    ability: abilityFor(weapon),\r\n  };\r\n}\r\n\r\nexport function abilityFor(value) {\r\n  const weapon = normalizeWeapon(value), family = WEAPON_FAMILIES[weapon.type];\r\n  if (weapon.tier < ABILITY_TIERS[0]) return null;\r\n  const rank = ABILITY_TIERS.filter(tier => weapon.tier >= tier).length;\r\n  return Object.freeze({\r\n    id: `${weapon.type}:${rank}`,\r\n    family: weapon.type,\r\n    name: family.moves[rank - 1],\r\n    rank,\r\n    unlockTier: ABILITY_TIERS[rank - 1],\r\n    cooldownMs: (family.cooldown + (rank - 1) * 2) * 1000,\r\n    animationMs: 1000 + rank * 180,\r\n    damageMultiplier: 2 + rank,\r\n    motion: family.motion,\r\n  });\r\n}\r\n\r\n// One shared special gauge: changing the family/tier or re-entering rest cannot\r\n// reset its timer. The arena owns persistence, and the gallery uses a separate\r\n// instance. Clamping time prevents a clock rollback from shortening a cooldown.\r\nexport class AbilityCooldown {\r\n  constructor(saved = null, now = Date.now()) {\r\n    if (!Number.isFinite(now) || now < 0) throw new Error('Invalid cooldown clock.');\r\n    if (typeof saved === 'string') { try { saved = JSON.parse(saved); } catch { saved = null; } }\r\n    this.lastNow = now;\r\n    this.readyAt = now;\r\n    this.durationMs = 0;\r\n    if (saved?.version === 1 && Number.isFinite(saved.readyAt)) {\r\n      this.readyAt = Math.max(now, Math.min(now + MAX_COOLDOWN_MS, saved.readyAt));\r\n      this.durationMs = Math.max(this.readyAt - now, Math.min(MAX_COOLDOWN_MS, Number(saved.durationMs) || 0));\r\n    }\r\n  }\r\n\r\n  clock(now) {\r\n    if (!Number.isFinite(now) || now < 0) throw new Error('Invalid cooldown clock.');\r\n    this.lastNow = Math.max(this.lastNow, now);\r\n    return this.lastNow;\r\n  }\r\n\r\n  remaining(now = Date.now()) {\r\n    return Math.max(0, this.readyAt - this.clock(now));\r\n  }\r\n\r\n  activate(value, {now = Date.now(), progress, inRest = false, catalog = globalThis.GalaWeapons} = {}) {\r\n    const weapon = normalizeWeapon(value), ability = abilityFor(weapon), at = this.clock(now);\r\n    if (!inRest) return {ok: false, reason: 'not-rest'};\r\n    if (!ability) return {ok: false, reason: 'tier', unlockTier: ABILITY_TIERS[0]};\r\n    if (!progress || !catalog?.unlocked(weapon, progress)) return {ok: false, reason: 'locked'};\r\n    const remainingMs = this.remaining(at);\r\n    if (remainingMs > 0) return {ok: false, reason: 'cooldown', remainingMs};\r\n    this.readyAt = at + ability.cooldownMs;\r\n    this.durationMs = ability.cooldownMs;\r\n    return {ok: true, ability, readyAt: this.readyAt};\r\n  }\r\n\r\n  snapshot() { return {version: 1, readyAt: this.readyAt, durationMs: this.durationMs}; }\r\n  merge(saved,now=Date.now()) { const incoming=new AbilityCooldown(saved,this.clock(now));if(incoming.readyAt>this.readyAt){this.readyAt=incoming.readyAt;this.durationMs=incoming.durationMs;}return this.remaining(now); }\r\n}\r\n","pod/weapon-review.css":":root{color-scheme:dark;--bg:#080c18;--panel:#101726;--line:#263347;--ink:#eaf4ff;--muted:#94a6bb;--accent:#90f6dc;font:15px/1.4 ui-sans-serif,system-ui,sans-serif;background:var(--bg);color:var(--ink)}\r\n*{box-sizing:border-box}body{margin:0}button,a,input{-webkit-tap-highlight-color:transparent}button{font:inherit;color:inherit;cursor:pointer;border:1px solid var(--line);border-radius:7px;background:#182334;min-height:44px;padding:9px 15px}button:hover{background:#24344c}button:disabled{cursor:default;opacity:.5}button:focus-visible,a:focus-visible,input:focus-visible{outline:3px solid var(--accent);outline-offset:3px}button[aria-pressed=true]{border-color:var(--accent);color:var(--accent);background:#173333}main{max-width:1350px;margin:auto;padding:24px 32px 36px}header{display:flex;align-items:center;gap:22px;margin:0 0 22px}header a{font-weight:900;letter-spacing:.1em;color:var(--accent);text-decoration:none}h1{font-size:22px;margin:0;font-weight:650}header>span{margin-left:auto;color:var(--muted);font-size:12px}.workspace{display:grid;grid-template-columns:195px 1fr;gap:25px}nav{display:grid;align-content:start;gap:5px}nav button{text-align:left;min-height:36px;padding:7px 11px;border-color:transparent;background:transparent;font-size:13px}nav button[aria-pressed=true]{border-color:var(--line)}.preview{min-width:0}.stage{position:relative;overflow:hidden;border:1px solid #34475b;border-radius:13px;background:#172541 url('worlds/great-wall.webp') center/cover}.stage:before{content:\"\";position:absolute;inset:0;background:linear-gradient(#111a357a,#1017299c);pointer-events:none}.stage-title{position:absolute;top:22px;left:25px;right:25px;display:flex;justify-content:space-between;gap:20px;z-index:1;pointer-events:none}.stage-title span{font-size:11px;text-transform:uppercase;letter-spacing:.14em;color:#b8d3dd}h2{font-size:25px;letter-spacing:-.03em;margin:3px 0;font-weight:650}#tierNumber{border:1px solid #60838377;height:32px;min-width:55px;text-align:center;line-height:30px;border-radius:5px}.stage canvas{display:block;position:relative;width:100%;height:auto;image-rendering:pixelated}.preview-badge{position:absolute;bottom:15px;left:23px;font-size:11px;color:#b6c8db}.controls{padding:18px 2px 20px}.tier-control{display:flex;gap:14px;align-items:center;margin-bottom:15px}.tier-control label{font-size:13px;color:var(--muted)}.tier-control input{width:100%;accent-color:var(--accent);cursor:pointer;min-height:24px}.tier-control output{font-variant-numeric:tabular-nums;min-width:23px}.action-controls{display:flex;gap:8px}#special{flex:1;background:var(--accent);border-color:var(--accent);color:#102628;font-weight:650}#special:disabled{opacity:1;background:#193437;border-color:#315252;color:#a6cfca}#cooldown{display:block;width:100%;height:4px;border:0;margin:13px 0 10px;accent-color:var(--accent);background:var(--line);border-radius:4px;overflow:hidden}#cooldown::-webkit-progress-bar{background:var(--line)}#cooldown::-webkit-progress-value{background:var(--accent)}.details{display:flex;justify-content:space-between;gap:15px;color:var(--muted);font-size:11px}.comparison{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}figure{margin:0;border:1px solid var(--line);border-radius:9px;background:var(--panel);overflow:hidden}figure:last-child{border-color:#578d89}figure canvas{width:100%;height:auto;display:block;image-rendering:pixelated}figcaption{padding:8px 12px 12px;font-size:11px;color:var(--muted)}figure:last-child figcaption{color:var(--accent)}.motion-note{color:var(--muted);font-size:12px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}\r\n@media(max-width:850px){main{padding:15px}.workspace{grid-template-columns:1fr;gap:14px}nav{display:flex;overflow-x:auto;gap:4px;padding-bottom:7px}nav button{flex-shrink:0}header{margin-bottom:15px;gap:15px}header>span{font-size:10px}.stage-title{top:15px;left:17px;right:17px}h2{font-size:20px}.preview-badge{font-size:10px;left:15px;bottom:10px}}\r\n@media(max-width:470px){main{padding:10px}h1{font-size:18px}header a{font-size:13px}.stage-title{top:10px;left:12px;right:12px}.stage-title span{font-size:9px}h2{font-size:17px}#tierNumber{height:25px;line-height:23px;min-width:40px}.preview-badge{font-size:9px;bottom:7px}.action-controls button{font-size:12px;padding:8px 10px}.comparison{gap:5px}figcaption{padding:4px 6px 9px;font-size:9px}.details{font-size:10px}.stage canvas{min-height:245px;object-fit:contain}.controls{padding-top:12px}}\r\n","pod/weapon-review.html":"<!doctype html>\r\n<html lang=\"en\">\r\n<head>\r\n  <meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\r\n  <meta name=\"robots\" content=\"noindex\"><title>Weapon lab · MYR5</title>\r\n  <link rel=\"stylesheet\" href=\"weapon-review.css\">\r\n</head>\r\n<body>\r\n  <main>\r\n    <header><a href=\"../pose.html\">MYR5</a><h1>Weapon lab</h1><span>Animation preview</span></header>\r\n    <div class=\"workspace\">\r\n      <nav aria-label=\"Weapons\" id=\"families\"></nav>\r\n      <section class=\"preview\" aria-label=\"Weapon preview\">\r\n        <div class=\"stage\">\r\n          <div class=\"stage-title\"><div><span id=\"tierLabel\"></span><h2 id=\"weaponName\"></h2></div><span id=\"tierNumber\"></span></div>\r\n          <canvas id=\"scene\" width=\"640\" height=\"360\" aria-label=\"Animated weapon demonstration\"></canvas>\r\n          <span class=\"preview-badge\">All tiers available here for review</span>\r\n        </div>\r\n        <div class=\"controls\">\r\n          <div class=\"tier-control\"><label for=\"tier\">Tier</label><input id=\"tier\" type=\"range\" min=\"0\" max=\"20\" value=\"4\"><output id=\"tierOutput\" for=\"tier\">4</output></div>\r\n          <div class=\"action-controls\"><button id=\"attack\">Attack</button><button id=\"special\" class=\"special\">Special</button><button id=\"autoplay\" aria-pressed=\"false\">Autoplay</button></div>\r\n          <progress id=\"cooldown\" max=\"1\" value=\"1\" aria-label=\"Special ability ready\"></progress>\r\n          <div class=\"details\"><span id=\"unlock\"></span><span id=\"abilityInfo\"></span></div>\r\n        </div>\r\n        <section class=\"comparison\" aria-label=\"Tier comparison\">\r\n          <figure><canvas width=\"320\" height=\"180\"></canvas><figcaption>Field · tier 0</figcaption></figure>\r\n          <figure><canvas width=\"320\" height=\"180\"></canvas><figcaption id=\"previousLabel\"></figcaption></figure>\r\n          <figure><canvas width=\"320\" height=\"180\"></canvas><figcaption id=\"currentLabel\"></figcaption></figure>\r\n        </section>\r\n        <p class=\"motion-note\" id=\"motionNote\" hidden>Reduced motion is on.</p>\r\n        <div id=\"status\" role=\"status\" aria-live=\"polite\" class=\"sr-only\"></div>\r\n      </section>\r\n    </div>\r\n  </main>\r\n  <script src=\"/workout-tracks.js\"></script><script src=\"gala-weapons.js\"></script>\r\n  <script type=\"module\" src=\"weapon-review.mjs\"></script>\r\n</body>\r\n</html>\r\n","pod/weapon-review.mjs":"import {AbilityCooldown, abilityFor, evolution} from './weapon-evolution.mjs';\r\nimport {drawAnimatedWeapon} from './weapon-animator.mjs';\r\n\r\nconst $ = id => document.getElementById(id), weapons = window.GalaWeapons;\r\nconst progress = {trainingVersion:1,training:Object.fromEntries(Object.keys(globalThis.MYR5Training.TRAINING_TRACKS).map(id=>[id,{activeDays:365,completedSets:365}]))};\r\n// Review-only progress and cooldown: never read or write account/localStorage.\r\nconst cooldown = new AbilityCooldown();\r\nconst reduced = matchMedia('(prefers-reduced-motion: reduce)');\r\nconst canvas = $('scene'), ctx = canvas.getContext('2d');\r\nconst comparison = [...document.querySelectorAll('.comparison canvas')];\r\nlet selected = {type: 'rapier', tier: 4}, action = null, autoplay = false;\r\nlet frame = 0, lastFrame = 0, lastAuto = 0, cooling = false;\r\n\r\nfor (const weapon of weapons.types) {\r\n  const button = document.createElement('button');\r\n  button.textContent = weapon.name; button.dataset.type = weapon.id;\r\n  button.setAttribute('aria-pressed', String(weapon.id === selected.type));\r\n  button.addEventListener('click', () => { selected = {...selected, type: weapon.id}; action = null; update(); });\r\n  $('families').append(button);\r\n}\r\n\r\nfunction update() {\r\n  const profile = evolution(selected), ability = profile.ability, required = weapons.requirements(selected);\r\n  document.documentElement.style.setProperty('--accent', profile.energy);\r\n  $('weaponName').textContent = weapons.types.find(w => w.id === selected.type).name;\r\n  $('tierLabel').textContent = weapons.tiers[selected.tier];\r\n  $('tierNumber').textContent = `${selected.tier} / 20`;\r\n  $('tierOutput').value = selected.tier;\r\n  $('previousLabel').textContent = `${weapons.tiers[Math.max(0, selected.tier - 1)]} · tier ${Math.max(0, selected.tier - 1)}`;\r\n  $('currentLabel').textContent = `${weapons.tiers[selected.tier]} · tier ${selected.tier}`;\r\n  $('unlock').textContent = selected.tier ? `${required.label} · ${required.xp} XP` : 'Available from the start';\r\n  $('abilityInfo').textContent = ability ? `Rank ${ability.rank} · ${ability.cooldownMs / 1000}s cooldown` : 'Special unlocks at tier 4';\r\n  for (const button of $('families').children) button.setAttribute('aria-pressed', String(button.dataset.type === selected.type));\r\n  updateCooldown();\r\n}\r\n\r\nfunction attack(special = false) {\r\n  if(!special&&action?.special&&performance.now()-action.startedAt<(abilityFor(selected)?.animationMs||0))return;\r\n  if (special) {\r\n    const result = cooldown.activate(selected, {progress, inRest: true, catalog: weapons});\r\n    if (!result.ok) return;\r\n    $('status').textContent = result.ability.name;\r\n    cooling = true;\r\n  }\r\n  action = {startedAt: performance.now(), special};\r\n  lastAuto = performance.now();\r\n}\r\n\r\nfunction updateCooldown() {\r\n  const ability = abilityFor(selected), remaining = cooldown.remaining();\r\n  $('attack').disabled=!!(action?.special&&performance.now()-action.startedAt<(ability?.animationMs||0));\r\n  $('special').disabled = !ability || remaining > 0;\r\n  $('special').textContent = !ability ? 'Unlocks at tier 4' : remaining ? `${ability.name} · ${(remaining / 1000).toFixed(1)}s` : `${ability.name} · Ready`;\r\n  // A shared clock may belong to another weapon, so its progress is measured\r\n  // against the last activated duration rather than the selected tier's timer.\r\n  const duration = cooldown.durationMs;\r\n  $('cooldown').value = remaining ? Math.max(0, 1 - remaining / Math.max(1, duration)) : 1;\r\n  $('cooldown').setAttribute('aria-label', remaining ? 'Special ability cooling down' : 'Special ability ready');\r\n  if (cooling && remaining === 0) { cooling = false; $('status').textContent = 'Special ready'; }\r\n}\r\n$('attack').addEventListener('click', () => attack());\r\n$('special').addEventListener('click', () => attack(true));\r\n$('tier').addEventListener('input', event => { selected = {...selected, tier: Number(event.target.value)}; action = null; update(); });\r\n$('autoplay').addEventListener('click', () => { autoplay = !autoplay; $('autoplay').setAttribute('aria-pressed', String(autoplay)); if (autoplay) attack(); });\r\n\r\nfunction platform(context, width, height) {\r\n  context.clearRect(0, 0, width, height); context.imageSmoothingEnabled = false;\r\n  const x = width * .29, y = height * .79, half = width * .23;\r\n  context.fillStyle = '#0b152c'; context.beginPath(); context.moveTo(x-half,y); context.lineTo(x+half,y); context.lineTo(x+half*.67,y+height*.08); context.lineTo(x-half*.55,y+height*.09); context.fill();\r\n  context.fillStyle = '#384a69'; context.fillRect(x-half,y-4,half*2,5);\r\n  context.fillStyle = '#78dbc4'; context.fillRect(x-half*.6,y+4,half*1.2,2);\r\n  context.fillStyle = '#a7d6e1'; context.globalAlpha = .35;\r\n  for(let k=0;k<13;k++) context.fillRect((k*59+23)%width,(k*31+19)%(height*.7),1,1);\r\n  context.globalAlpha = 1;\r\n}\r\n\r\nfunction render(now) {\r\n  frame = 0;\r\n  if (document.hidden) return;\r\n  if (now - lastFrame > (reduced.matches ? 100 : 32)) {\r\n    lastFrame = now;\r\n    if (autoplay && now - lastAuto > 2300) attack();\r\n    platform(ctx, canvas.width, canvas.height);\r\n    drawAnimatedWeapon(ctx, selected, {weapons, x: 185, y: 190, scale: 1.45, now, action, reducedMotion: reduced.matches});\r\n    const tiers = [0, Math.max(0, selected.tier - 1), selected.tier];\r\n    comparison.forEach((card, index) => {\r\n      const context = card.getContext('2d'); platform(context, card.width, card.height);\r\n      drawAnimatedWeapon(context, {...selected, tier: tiers[index]}, {weapons, x: 92, y: 88, scale: .65, now, action, reducedMotion: reduced.matches});\r\n    });\r\n    updateCooldown();\r\n  }\r\n  frame = requestAnimationFrame(render);\r\n}\r\n\r\nfunction motionPreference() { $('motionNote').hidden = !reduced.matches; }\r\nconst visibility = () => { if (document.hidden) { cancelAnimationFrame(frame); frame = 0; } else if (!frame) frame = requestAnimationFrame(render); };\r\ndocument.addEventListener('visibilitychange', visibility);\r\nreduced.addEventListener('change', motionPreference);\r\nwindow.addEventListener('pagehide', () => { cancelAnimationFrame(frame); frame = 0; document.removeEventListener('visibilitychange', visibility); reduced.removeEventListener('change', motionPreference); });\r\nupdate(); motionPreference(); frame = requestAnimationFrame(render);\r\n","pod/whiteboard.css":"@font-face{font-family:BoardHand0;font-style:normal;font-weight:400;font-display:swap;src:url('/pod/fonts/hand-0.woff2') format('woff2')}\r\n@font-face{font-family:BoardHand2;font-style:normal;font-weight:400;font-display:swap;src:url('/pod/fonts/hand-2.woff2') format('woff2')}\r\n@font-face{font-family:BoardHand6;font-style:normal;font-weight:400;font-display:swap;src:url('/pod/fonts/hand-6.woff2') format('woff2')}\r\n#accountPanel{color-scheme:light;--marker:#204f99;width:min(880px,calc(100vw - 22px));max-width:calc(100vw - 22px);max-height:calc(100dvh - 28px);padding:26px clamp(13px,4vw,38px) 35px;border:11px solid #bac0bf;border-top-color:#e3e6e4;border-left-color:#d5d9d7;border-right-color:#8c9698;border-bottom-width:17px;border-radius:8px;background:radial-gradient(ellipse at 8% 25%,#778e9809,transparent 33%),radial-gradient(ellipse at 83% 74%,#8b659c07,transparent 25%),linear-gradient(110deg,#fffefa,#f5f7ef 50%,#fffffb);box-shadow:inset 0 0 0 2px #818d9155,inset 3px 4px 14px #a4adac33,0 0 0 2px #475057,5px 12px 0 #333b42,0 25px 80px #000b;color:#204f99;font:22px/1.3 BoardHand0,'Comic Sans MS',cursive;overflow-x:hidden}\r\n#accountPanel::backdrop{background:#0c0b15cf;backdrop-filter:blur(7px)}#accountPanel header{align-items:flex-start;margin-bottom:16px;border-bottom:3px solid #243b6977;padding-bottom:13px;box-shadow:none;transform:rotate(-.25deg)}#accountPanel .progress-eyebrow{font:16px BoardHand2,cursive;color:#695979;letter-spacing:.8px}#accountPanel h2{font:clamp(29px,5vw,42px)/1.15 BoardHand6,cursive;color:#173c78;letter-spacing:-1px;margin-top:4px}\r\n#accountPanel button,#accountPanel .action-link{color:#263747;min-height:44px;padding:8px 14px;border:2px solid #66757b;border-radius:5px;background:linear-gradient(#f6f7eb,#d8dfd6);box-shadow:inset 0 2px #fff,0 4px #718088,0 6px #33434b55;font:19px/1.15 BoardHand0,cursive}#accountPanel button:active:not(:disabled){transform:translateY(3px);box-shadow:inset 1px 2px 4px #71808877,0 1px #718088}#accountPanel button:focus-visible,#accountPanel input:focus-visible,#accountPanel a:focus-visible,#accountPanel summary:focus-visible{outline:3px solid #174b92;outline-offset:3px}\r\n#accountPanel header>[data-close]{background:repeating-linear-gradient(0deg,#455d73 0 2px,#354d63 2px 4px);border:4px solid #bec8c7;color:#faf9f0;box-shadow:inset 0 2px #9daeb7,0 5px #33434b;min-width:65px;transform:rotate(3deg);font:18px BoardHand0,cursive}\r\n#accountPanel .progress-summary{border-bottom:1px solid #8fa8bb77;padding-bottom:16px;gap:10px}#accountPanel #accountLevel{font:30px BoardHand2,cursive;color:#883645}#accountPanel #accountSets{font:21px BoardHand0,cursive;color:#4b5461}#accountPanel p,#accountPanel .hint{font:19px/1.4 BoardHand0,cursive;color:#56606c}#accountPanel #recordsStatus{font-size:18px}#accountPanel .record-intro{margin-top:18px}\r\n#accountPanel .record-board{--ink:#204f99;margin-top:23px;color:var(--ink)}#accountPanel .record-board[data-kind=hold]{--ink:#773c86}#accountPanel .record-board[data-kind=steps]{--ink:#2e6d4c}#accountPanel .record-board[data-kind=jumps]{--ink:#a44144}#accountPanel .record-board[data-kind=pace]{--ink:#875b23}\r\n#accountPanel .record-heading{border-bottom:2px solid var(--ink);padding-bottom:6px;transform:rotate(-.25deg)}#accountPanel .record-heading h3{margin:0;font:29px BoardHand2,cursive;color:var(--ink)}#accountPanel .record-heading>span{font:18px BoardHand0,cursive;color:var(--ink)}#accountPanel table{font:23px BoardHand0,cursive;font-variant-numeric:tabular-nums}#accountPanel thead th{font:16px BoardHand0,cursive;color:#526575;letter-spacing:0;text-transform:none;padding-top:9px}#accountPanel thead th:first-child{font-size:0;width:28px}#accountPanel thead th:nth-child(2){width:41%}#accountPanel thead th:last-child{width:37px}\r\n#accountPanel tbody th,#accountPanel td{border-bottom:1px solid #8fa8bb55;padding:10px 4px;font-weight:400;color:var(--ink)}#accountPanel .record-rank{font:18px BoardHand0,cursive;color:var(--ink)}#accountPanel .record-best{font:30px BoardHand2,cursive;color:var(--ink);letter-spacing:-1px}#accountPanel tbody td:last-child{font:21px BoardHand0,cursive;color:var(--ink)}#accountPanel tr[data-record=false]{opacity:.6}#accountPanel tr[data-record=false] .record-best{color:var(--ink)}\r\n#accountPanel .unlock-board h3{font:28px BoardHand2,cursive;color:#6b3b80;border-bottom:2px solid #6b3b8077;padding-bottom:6px}#accountPanel .unlock-row{font:23px BoardHand0,cursive;border-color:#8fa8bb55;color:#6b3b80}#accountPanel .unlock-row>span:last-child{font:20px BoardHand0,cursive;color:#56606c}#accountPanel .unlock-row[data-unlocked=true]{background:linear-gradient(transparent 70%,#e9dc8140 71%,transparent 95%)}#accountPanel .unlock-row[data-unlocked=true]>span:last-child{color:#2e6d4c}\r\n#accountPanel .account-settings{border-color:#8fa8bb88}#accountPanel summary{font:22px BoardHand0,cursive;color:#485e78;cursor:pointer}#accountPanel .account-settings h3{font:25px BoardHand2,cursive;color:#6b3b80}#accountPanel input{background:#e7edf344;border:0;border-bottom:2px solid #667c99;color:#244873;font:22px BoardHand0,cursive;box-shadow:none}#accountPanel label{color:#485461;font:20px BoardHand0,cursive}#accountPanel a{color:#174b92}\r\n.marker-tray{position:sticky;bottom:-35px;height:25px;margin:23px -6px -35px;display:flex;gap:13px;align-items:flex-end;justify-content:flex-end;padding:0 16px 1px;background:linear-gradient(#97a7ad,#e2e7e4 45%,#929fa4 48%,#576771);border-radius:2px;border-top:1px solid #8b999f;box-shadow:0 -3px 8px #27343a22;pointer-events:none}.marker-tray i{height:11px;width:65px;background:linear-gradient(#fff,#d7dddd);border:1px solid #637076;border-right:18px solid var(--ink);border-left:7px solid var(--ink);border-radius:3px;box-shadow:0 2px 2px #1c293866;transform:rotate(-2deg)}.marker-tray i:nth-child(2){transform:rotate(2deg)}\r\n@media(min-width:650px){#workoutList{display:grid;grid-template-columns:1fr 1fr;column-gap:30px;align-items:start}.record-board:last-child{grid-column:1/-1}}\r\n@media(max-width:420px){#accountPanel{border-width:7px;border-bottom-width:13px;padding-top:20px}#accountPanel header{position:relative;display:block;min-height:99px;transform:none}#accountPanel header>[data-close]{position:absolute;top:0;right:0;min-width:55px;padding:7px}#accountPanel .progress-eyebrow{font-size:14px}#accountPanel h2{padding-top:24px;font-size:29px}#accountPanel .record-heading>span{font-size:16px}#accountPanel table{font-size:21px}#accountPanel thead th{font-size:14px}#accountPanel .record-best{font-size:26px}#accountPanel .progress-summary button{padding:8px;font-size:17px}}\r\n","pod/workout-session-owner.mjs":"const KEY = 'myr5-workout-session-owner-v1';\r\n\r\n// The pod is the workout owner.  This intentionally persists only a local\r\n// acknowledgement: account workout sync remains owned by launch.mjs.\r\nexport class WorkoutSessionOwner {\r\n  constructor({ storage = globalThis.localStorage, saveProgress } = {}) {\r\n    this.storage = storage;\r\n    this.saveProgress = saveProgress;\r\n    const prior = this.read();\r\n    // A camera/tracker cannot survive a reload, so never revive an active run.\r\n    this.phase = 'idle';\r\n    this.revision = Math.max(0, Number(prior?.revision) || 0) + (prior?.phase === 'active' ? 1 : 0);\r\n    this.lease = null;\r\n    this.persist();\r\n  }\r\n  read() { try { return JSON.parse(this.storage?.getItem(KEY) || 'null'); } catch { return null; } }\r\n  persist() { try { this.storage?.setItem(KEY, JSON.stringify({ version: 1, phase: this.phase, revision: this.revision })); return true; } catch { return false; } }\r\n  snapshot() { return { phase: this.phase, revision: this.revision, transitioning: !!this.lease }; }\r\n  canStart() { return this.phase === 'idle' && !this.lease; }\r\n  start() { if (!this.canStart()) return false; this.phase = 'active'; this.revision++; this.persist(); return true; }\r\n  // Idempotent release for every stop path (also drops a stale idle lease).\r\n  stop() { this.lease = null; if (this.phase !== 'idle') { this.phase = 'idle'; this.revision++; this.persist(); } }\r\n  async complete(payload) {\r\n    if (this.phase !== 'active') return { saved: false, reason: 'no active workout' };\r\n    let result;\r\n    try { result = await this.saveProgress?.(payload); } catch (error) { return { saved: false, reason: error?.message || 'workout progress was not saved' }; }\r\n    if (!result?.local) return { saved: false, reason: result?.reason || 'workout progress was not saved' };\r\n    this.phase = 'idle'; this.revision++;\r\n    const acknowledged=this.persist();\r\n    // The workout database is the completion authority. A failed UI cache write\r\n    // must not turn an already committed completion into an impossible retry.\r\n    return { saved: true, acknowledged, ...result };\r\n  }\r\n  acquireIdleLease() {\r\n    if (!this.canStart()) return null;\r\n    const lease = { revision: this.revision, released: false };\r\n    this.lease = lease;\r\n    return lease;\r\n  }\r\n  releaseIdleLease(lease) { if (this.lease === lease) { lease.released = true; this.lease = null; } }\r\n  async save() { return this.persist(); }\r\n}\r\n","pod/worlds/boards/cogs/door-layout.json":"{\"version\":1,\"image\":[1024,1792],\"frame\":{\"x0\":0.0244,\"y0\":0.0268,\"x1\":0.9756,\"y1\":0.8008},\"parts\":[{\"node\":\"m19\",\"kind\":\"gear\",\"u\":0.2834,\"v\":0.8087,\"r\":0.0493,\"rot\":77,\"layer\":0},{\"node\":\"g41\",\"kind\":\"gear\",\"u\":0.3648,\"v\":0.8356,\"r\":0.0447,\"rot\":24,\"layer\":1,\"drives\":0},{\"node\":\"m47\",\"kind\":\"gear\",\"u\":0.2834,\"v\":0.8621,\"r\":0.0442,\"rot\":274,\"layer\":2,\"drives\":0},{\"node\":\"m40\",\"kind\":\"gear\",\"u\":0.2033,\"v\":0.8352,\"r\":0.0432,\"rot\":298,\"layer\":3,\"drives\":0},{\"node\":\"m05\",\"kind\":\"gear\",\"u\":0.2043,\"v\":0.7826,\"r\":0.042,\"rot\":259,\"layer\":4,\"drives\":0},{\"node\":\"g53\",\"kind\":\"gear\",\"u\":0.4397,\"v\":0.8603,\"r\":0.0418,\"rot\":44,\"layer\":5,\"drives\":1},{\"node\":\"g07\",\"kind\":\"gear\",\"u\":0.3648,\"v\":0.8848,\"r\":0.0415,\"rot\":35,\"layer\":6,\"drives\":1},{\"node\":\"g54\",\"kind\":\"gear\",\"u\":0.2834,\"v\":0.911,\"r\":0.0414,\"rot\":282,\"layer\":7,\"drives\":2},{\"node\":\"g19\",\"kind\":\"gear\",\"u\":0.2094,\"v\":0.8866,\"r\":0.0413,\"rot\":289,\"layer\":8,\"drives\":2},{\"node\":\"g22\",\"kind\":\"gear\",\"u\":0.1301,\"v\":0.8593,\"r\":0.0413,\"rot\":114,\"layer\":9,\"drives\":3},{\"node\":\"g33\",\"kind\":\"gear\",\"u\":0.1322,\"v\":0.8064,\"r\":0.0438,\"rot\":298,\"layer\":10,\"drives\":3},{\"node\":\"g61\",\"kind\":\"gear\",\"u\":0.5112,\"v\":0.8839,\"r\":0.0407,\"rot\":295,\"layer\":11,\"drives\":5},{\"node\":\"g10\",\"kind\":\"gear\",\"u\":0.4397,\"v\":0.9073,\"r\":0.0404,\"rot\":25,\"layer\":12,\"drives\":5},{\"node\":\"g40\",\"kind\":\"gear\",\"u\":0.3648,\"v\":0.9311,\"r\":0.0394,\"rot\":23,\"layer\":13,\"drives\":6},{\"node\":\"g26\",\"kind\":\"gear\",\"u\":0.2834,\"v\":0.9565,\"r\":0.0382,\"rot\":68,\"layer\":14,\"drives\":7},{\"node\":\"g09\",\"kind\":\"gear\",\"u\":0.2158,\"v\":0.9333,\"r\":0.0367,\"rot\":73,\"layer\":15,\"drives\":7},{\"node\":\"g57\",\"kind\":\"light\",\"u\":0.7285,\"v\":0.8232,\"r\":0.0619,\"rot\":180,\"layer\":16},{\"node\":\"g51\",\"kind\":\"pipe\",\"u\":0.8094,\"v\":0.8797,\"r\":0.0504,\"rot\":180,\"layer\":17},{\"node\":\"m14\",\"kind\":\"screw\",\"u\":0.7202,\"v\":0.9125,\"r\":0.05,\"rot\":180,\"layer\":18},{\"node\":\"m21\",\"kind\":\"pipe\",\"u\":0.6333,\"v\":0.9436,\"r\":0.0475,\"rot\":180,\"layer\":19},{\"node\":\"m26\",\"kind\":\"light\",\"u\":0.88,\"v\":0.9217,\"r\":0.0473,\"rot\":292,\"layer\":20},{\"node\":\"g44\",\"kind\":\"pipe\",\"u\":0.1393,\"v\":0.9413,\"r\":0.0467,\"rot\":180,\"layer\":21},{\"node\":\"m31\",\"kind\":\"valve\",\"u\":0.3289,\"v\":0.6806,\"r\":0.0458,\"rot\":280,\"layer\":22},{\"node\":\"m27\",\"kind\":\"pipe\",\"u\":0.7249,\"v\":0.7036,\"r\":0.0441,\"rot\":180,\"layer\":23},{\"node\":\"m25\",\"kind\":\"pipe\",\"u\":0.1922,\"v\":0.0578,\"r\":0.044,\"rot\":180,\"layer\":24},{\"node\":\"m41\",\"kind\":\"plate\",\"u\":0.8594,\"v\":0.0592,\"r\":0.0436,\"rot\":254,\"layer\":25},{\"node\":\"g39\",\"kind\":\"plate\",\"u\":0.7331,\"v\":0.131,\"r\":0.0425,\"rot\":180,\"layer\":26},{\"node\":\"g06\",\"kind\":\"plate\",\"u\":0.2521,\"v\":0.1382,\"r\":0.0421,\"rot\":0,\"layer\":27},{\"node\":\"m09\",\"kind\":\"plate\",\"u\":0.8936,\"v\":0.8414,\"r\":0.0416,\"rot\":0,\"layer\":28},{\"node\":\"g12\",\"kind\":\"light\",\"u\":0.3184,\"v\":0.384,\"r\":0.0416,\"rot\":180,\"layer\":29},{\"node\":\"g21\",\"kind\":\"pipe\",\"u\":0.6797,\"v\":0.3881,\"r\":0.0416,\"rot\":0,\"layer\":30},{\"node\":\"m18\",\"kind\":\"valve\",\"u\":0.5469,\"v\":0.9576,\"r\":0.0415,\"rot\":92,\"layer\":31},{\"node\":\"m34\",\"kind\":\"pipe\",\"u\":0.6719,\"v\":0.4499,\"r\":0.0413,\"rot\":180,\"layer\":32},{\"node\":\"m42\",\"kind\":\"plate\",\"u\":0.3555,\"v\":0.4807,\"r\":0.0413,\"rot\":294,\"layer\":33},{\"node\":\"m48\",\"kind\":\"plate\",\"u\":0.6395,\"v\":0.8493,\"r\":0.0413,\"rot\":253,\"layer\":34},{\"node\":\"g16\",\"kind\":\"valve\",\"u\":0.1758,\"v\":0.2775,\"r\":0.0409,\"rot\":229,\"layer\":35},{\"node\":\"g62\",\"kind\":\"light\",\"u\":0.8223,\"v\":0.2775,\"r\":0.0409,\"rot\":37,\"layer\":36},{\"node\":\"m06\",\"kind\":\"plate\",\"u\":0.1758,\"v\":0.5356,\"r\":0.0407,\"rot\":0,\"layer\":37},{\"node\":\"m49\",\"kind\":\"screw\",\"u\":0.8223,\"v\":0.539,\"r\":0.0405,\"rot\":175,\"layer\":38},{\"node\":\"m46\",\"kind\":\"plate\",\"u\":0.0819,\"v\":0.6765,\"r\":0.0404,\"rot\":250,\"layer\":39},{\"node\":\"m50\",\"kind\":\"plate\",\"u\":0.0814,\"v\":0.1439,\"r\":0.0403,\"rot\":0,\"layer\":40},{\"node\":\"m13\",\"kind\":\"pipe\",\"u\":0.9252,\"v\":0.1462,\"r\":0.0399,\"rot\":180,\"layer\":41},{\"node\":\"m15\",\"kind\":\"plate\",\"u\":0.9186,\"v\":0.6848,\"r\":0.0399,\"rot\":285,\"layer\":42},{\"node\":\"m03\",\"kind\":\"plate\",\"u\":0.855,\"v\":0.7779,\"r\":0.0398,\"rot\":180,\"layer\":43},{\"node\":\"m29\",\"kind\":\"valve\",\"u\":0.3164,\"v\":0.106,\"r\":0.0398,\"rot\":160,\"layer\":44},{\"node\":\"m08\",\"kind\":\"light\",\"u\":0.4699,\"v\":0.9629,\"r\":0.0397,\"rot\":179,\"layer\":45},{\"node\":\"m38\",\"kind\":\"plate\",\"u\":0.8221,\"v\":0.9543,\"r\":0.0396,\"rot\":296,\"layer\":46},{\"node\":\"m12\",\"kind\":\"plate\",\"u\":0.3428,\"v\":0.7495,\"r\":0.0395,\"rot\":35,\"layer\":47},{\"node\":\"m01\",\"kind\":\"plate\",\"u\":0.7582,\"v\":0.0366,\"r\":0.0391,\"rot\":180,\"layer\":48},{\"node\":\"g59\",\"kind\":\"plate\",\"u\":0.1616,\"v\":0.6157,\"r\":0.038,\"rot\":180,\"layer\":49},{\"node\":\"g15\",\"kind\":\"light\",\"u\":0.5501,\"v\":0.6116,\"r\":0.038,\"rot\":0,\"layer\":50},{\"node\":\"g38\",\"kind\":\"plate\",\"u\":0.8242,\"v\":0.6015,\"r\":0.0378,\"rot\":180,\"layer\":51},{\"node\":\"g60\",\"kind\":\"valve\",\"u\":0.9289,\"v\":0.958,\"r\":0.0376,\"rot\":359,\"layer\":52},{\"node\":\"g46\",\"kind\":\"plate\",\"u\":0.6114,\"v\":0.7377,\"r\":0.0365,\"rot\":295,\"layer\":53},{\"node\":\"g63\",\"kind\":\"plate\",\"u\":0.6212,\"v\":0.0961,\"r\":0.0365,\"rot\":228,\"layer\":54},{\"node\":\"g03\",\"kind\":\"plate\",\"u\":0.4025,\"v\":0.6138,\"r\":0.0342,\"rot\":197,\"layer\":55},{\"node\":\"m07\",\"kind\":\"plate\",\"u\":0.0778,\"v\":0.9048,\"r\":0.0322,\"rot\":177,\"layer\":56},{\"node\":\"g02\",\"kind\":\"plate\",\"u\":0.597,\"v\":0.1989,\"r\":0.0322,\"rot\":236,\"layer\":57},{\"node\":\"g32\",\"kind\":\"screw\",\"u\":0.4258,\"v\":0.2184,\"r\":0.0318,\"rot\":312,\"layer\":58},{\"node\":\"g14\",\"kind\":\"screw\",\"u\":0.6653,\"v\":0.3307,\"r\":0.0316,\"rot\":30,\"layer\":59},{\"node\":\"g04\",\"kind\":\"screw\",\"u\":0.5908,\"v\":0.293,\"r\":0.031,\"rot\":147,\"layer\":60},{\"node\":\"m45\",\"kind\":\"screw\",\"u\":0.4286,\"v\":0.2726,\"r\":0.0307,\"rot\":126,\"layer\":61},{\"node\":\"g13\",\"kind\":\"screw\",\"u\":0.0703,\"v\":0.8248,\"r\":0.0306,\"rot\":254,\"layer\":62},{\"node\":\"m20\",\"kind\":\"pipe\",\"u\":0.7305,\"v\":0.9567,\"r\":0.03,\"rot\":0,\"layer\":63},{\"node\":\"g17\",\"kind\":\"light\",\"u\":0.6758,\"v\":0.4853,\"r\":0.0295,\"rot\":281,\"layer\":64},{\"node\":\"g36\",\"kind\":\"pipe\",\"u\":0.1524,\"v\":0.8913,\"r\":0.0483,\"rot\":60,\"layer\":65},{\"node\":\"g31\",\"kind\":\"plate\",\"u\":0.3672,\"v\":0.973,\"r\":0.0661,\"rot\":270,\"layer\":66},{\"node\":\"g34\",\"kind\":\"light\",\"u\":0.3086,\"v\":0.7157,\"r\":0.0549,\"rot\":210,\"layer\":67},{\"node\":\"g11\",\"kind\":\"pipe\",\"u\":0.4371,\"v\":0.318,\"r\":0.0462,\"rot\":123,\"layer\":68},{\"node\":\"g49\",\"kind\":\"pipe\",\"u\":0.9473,\"v\":0.7502,\"r\":0.0508,\"rot\":213,\"layer\":69},{\"node\":\"g58\",\"kind\":\"pipe\",\"u\":0.9374,\"v\":0.6478,\"r\":0.0447,\"rot\":153,\"layer\":70},{\"node\":\"m17\",\"kind\":\"screw\",\"u\":0.9199,\"v\":0.8025,\"r\":0.0437,\"rot\":0,\"layer\":71},{\"node\":\"m35\",\"kind\":\"light\",\"u\":0.4468,\"v\":0.6467,\"r\":0.0568,\"rot\":90,\"layer\":72},{\"node\":\"m22\",\"kind\":\"pipe\",\"u\":0.9227,\"v\":0.8807,\"r\":0.0647,\"rot\":327,\"layer\":73},{\"node\":\"m28\",\"kind\":\"pipe\",\"u\":0.6874,\"v\":0.7387,\"r\":0.0473,\"rot\":219,\"layer\":74},{\"node\":\"g29\",\"kind\":\"light\",\"u\":0.0997,\"v\":0.9818,\"r\":0.0966,\"rot\":270,\"layer\":75},{\"node\":\"g47\",\"kind\":\"light\",\"u\":0.2602,\"v\":0.983,\"r\":0.0639,\"rot\":180,\"layer\":76},{\"node\":\"g08\",\"kind\":\"plate\",\"u\":0.5651,\"v\":0.3223,\"r\":0.0352,\"rot\":57,\"layer\":77},{\"node\":\"m43\",\"kind\":\"pipe\",\"u\":0.7328,\"v\":0.6649,\"r\":0.0449,\"rot\":123,\"layer\":78},{\"node\":\"g01\",\"kind\":\"light\",\"u\":0.6817,\"v\":0.1606,\"r\":0.0516,\"rot\":204,\"layer\":79},{\"node\":\"g05\",\"kind\":\"light\",\"u\":0.6098,\"v\":0.0626,\"r\":0.0445,\"rot\":342,\"layer\":80},{\"node\":\"g43\",\"kind\":\"screw\",\"u\":0.0467,\"v\":0.7962,\"r\":0.0311,\"rot\":240,\"layer\":81},{\"node\":\"m44\",\"kind\":\"screw\",\"u\":0.9636,\"v\":0.0851,\"r\":0.0455,\"rot\":252,\"layer\":82},{\"node\":\"g24\",\"kind\":\"light\",\"u\":0.3949,\"v\":0.3749,\"r\":0.0457,\"rot\":210,\"layer\":83},{\"node\":\"g45\",\"kind\":\"light\",\"u\":0.2885,\"v\":0.4745,\"r\":0.0601,\"rot\":27,\"layer\":84},{\"node\":\"m11\",\"kind\":\"light\",\"u\":0.5698,\"v\":0.8782,\"r\":0.0477,\"rot\":93,\"layer\":85},{\"node\":\"m33\",\"kind\":\"light\",\"u\":0.8055,\"v\":0.3216,\"r\":0.046,\"rot\":114,\"layer\":86},{\"node\":\"m02\",\"kind\":\"screw\",\"u\":0.8534,\"v\":0.5129,\"r\":0.0437,\"rot\":117,\"layer\":87},{\"node\":\"g50\",\"kind\":\"screw\",\"u\":0.3909,\"v\":0.7386,\"r\":0.0387,\"rot\":201,\"layer\":88},{\"node\":\"g18\",\"kind\":\"screw\",\"u\":0.1773,\"v\":0.1955,\"r\":0.0352,\"rot\":36,\"layer\":89},{\"node\":\"m04\",\"kind\":\"light\",\"u\":0.6644,\"v\":0.6783,\"r\":0.0548,\"rot\":66,\"layer\":90},{\"node\":\"g37\",\"kind\":\"screw\",\"u\":0.755,\"v\":0.1615,\"r\":0.0301,\"rot\":327,\"layer\":91},{\"node\":\"g25\",\"kind\":\"screw\",\"u\":0.7443,\"v\":0.983,\"r\":0.0477,\"rot\":90,\"layer\":92},{\"node\":\"m16\",\"kind\":\"light\",\"u\":0.8438,\"v\":0.9849,\"r\":0.0518,\"rot\":270,\"layer\":93},{\"node\":\"m24\",\"kind\":\"light\",\"u\":0.9414,\"v\":0.9843,\"r\":0.0459,\"rot\":0,\"layer\":94},{\"node\":\"g27\",\"kind\":\"screw\",\"u\":0.8423,\"v\":0.2219,\"r\":0.0393,\"rot\":270,\"layer\":95},{\"node\":\"m30\",\"kind\":\"pipe\",\"u\":0.6451,\"v\":0.887,\"r\":0.0436,\"rot\":87,\"layer\":96},{\"node\":\"m23\",\"kind\":\"pipe\",\"u\":0.256,\"v\":0.04,\"r\":0.0424,\"rot\":216,\"layer\":97},{\"node\":\"g28\",\"kind\":\"screw\",\"u\":0.5398,\"v\":0.2797,\"r\":0.0388,\"rot\":0,\"layer\":98},{\"node\":\"m36\",\"kind\":\"pipe\",\"u\":0.1937,\"v\":0.4984,\"r\":0.0502,\"rot\":117,\"layer\":99},{\"node\":\"m32\",\"kind\":\"screw\",\"u\":0.2366,\"v\":0.5383,\"r\":0.0334,\"rot\":117,\"layer\":100},{\"node\":\"m37\",\"kind\":\"pipe\",\"u\":0.5677,\"v\":0.1682,\"r\":0.0429,\"rot\":294,\"layer\":101},{\"node\":\"g42\",\"kind\":\"screw\",\"u\":0.4304,\"v\":0.176,\"r\":0.0512,\"rot\":333,\"layer\":102},{\"node\":\"g30\",\"kind\":\"pipe\",\"u\":0.3811,\"v\":0.2147,\"r\":0.0331,\"rot\":153,\"layer\":103},{\"node\":\"g56\",\"kind\":\"screw\",\"u\":0.6164,\"v\":0.3953,\"r\":0.0314,\"rot\":90,\"layer\":104},{\"node\":\"g23\",\"kind\":\"light\",\"u\":0.0491,\"v\":0.6305,\"r\":0.0455,\"rot\":24,\"layer\":105},{\"node\":\"g48\",\"kind\":\"screw\",\"u\":0.9235,\"v\":0.0265,\"r\":0.0343,\"rot\":321,\"layer\":106},{\"node\":\"g20\",\"kind\":\"screw\",\"u\":0.6326,\"v\":0.7675,\"r\":0.0323,\"rot\":111,\"layer\":107},{\"node\":\"g35\",\"kind\":\"screw\",\"u\":0.3065,\"v\":0.6483,\"r\":0.0402,\"rot\":288,\"layer\":108},{\"node\":\"g05\",\"kind\":\"light\",\"u\":0.8177,\"v\":0.084,\"r\":0.0445,\"rot\":321,\"layer\":109},{\"node\":\"g55\",\"kind\":\"pipe\",\"u\":0.9649,\"v\":0.8429,\"r\":0.0572,\"rot\":270,\"layer\":110},{\"node\":\"g28\",\"kind\":\"screw\",\"u\":0.6194,\"v\":0.9827,\"r\":0.0457,\"rot\":270,\"layer\":111},{\"node\":\"g25\",\"kind\":\"screw\",\"u\":0.6295,\"v\":0.4841,\"r\":0.0343,\"rot\":216,\"layer\":112},{\"node\":\"g35\",\"kind\":\"screw\",\"u\":0.324,\"v\":0.1522,\"r\":0.0568,\"rot\":153,\"layer\":113},{\"node\":\"g31\",\"kind\":\"plate\",\"u\":0.6088,\"v\":0.8239,\"r\":0.0396,\"rot\":285,\"layer\":114},{\"node\":\"g24\",\"kind\":\"light\",\"u\":0.2036,\"v\":0.3182,\"r\":0.0457,\"rot\":327,\"layer\":115},{\"node\":\"m35\",\"kind\":\"light\",\"u\":0.7301,\"v\":0.3678,\"r\":0.0568,\"rot\":297,\"layer\":116},{\"node\":\"g11\",\"kind\":\"pipe\",\"u\":0.3844,\"v\":0.0867,\"r\":0.0544,\"rot\":246,\"layer\":117},{\"node\":\"g29\",\"kind\":\"light\",\"u\":0.5385,\"v\":0.6702,\"r\":0.0684,\"rot\":180,\"layer\":118},{\"node\":\"g18\",\"kind\":\"screw\",\"u\":0.5207,\"v\":0.8515,\"r\":0.0352,\"rot\":84,\"layer\":119},{\"node\":\"m44\",\"kind\":\"screw\",\"u\":0.9711,\"v\":0.712,\"r\":0.0537,\"rot\":90,\"layer\":120},{\"node\":\"g34\",\"kind\":\"light\",\"u\":0.4519,\"v\":0.5268,\"r\":0.0549,\"rot\":270,\"layer\":121},{\"node\":\"g52\",\"kind\":\"plate\",\"u\":0.6905,\"v\":0.0956,\"r\":0.0331,\"rot\":270,\"layer\":122},{\"node\":\"g56\",\"kind\":\"screw\",\"u\":0.5638,\"v\":0.9168,\"r\":0.0314,\"rot\":354,\"layer\":123},{\"node\":\"g48\",\"kind\":\"screw\",\"u\":0.6615,\"v\":0.5119,\"r\":0.0343,\"rot\":213,\"layer\":124},{\"node\":\"m24\",\"kind\":\"light\",\"u\":0.7051,\"v\":0.8683,\"r\":0.0459,\"rot\":180,\"layer\":125},{\"node\":\"g49\",\"kind\":\"pipe\",\"u\":0.221,\"v\":0.6085,\"r\":0.0508,\"rot\":147,\"layer\":126},{\"node\":\"g42\",\"kind\":\"screw\",\"u\":0.7335,\"v\":0.4579,\"r\":0.0307,\"rot\":180,\"layer\":127},{\"node\":\"g50\",\"kind\":\"screw\",\"u\":0.3901,\"v\":0.2785,\"r\":0.0328,\"rot\":207,\"layer\":128},{\"node\":\"g47\",\"kind\":\"light\",\"u\":0.0306,\"v\":0.7408,\"r\":0.0541,\"rot\":264,\"layer\":129},{\"node\":\"m17\",\"kind\":\"screw\",\"u\":0.0469,\"v\":0.0894,\"r\":0.0437,\"rot\":303,\"layer\":130},{\"node\":\"g36\",\"kind\":\"pipe\",\"u\":0.8719,\"v\":0.2987,\"r\":0.0483,\"rot\":339,\"layer\":131},{\"node\":\"m43\",\"kind\":\"pipe\",\"u\":0.3398,\"v\":0.4479,\"r\":0.0449,\"rot\":180,\"layer\":132},{\"node\":\"m04\",\"kind\":\"light\",\"u\":0.7884,\"v\":0.7835,\"r\":0.0464,\"rot\":90,\"layer\":133},{\"node\":\"m10\",\"kind\":\"pipe\",\"u\":0.8126,\"v\":0.8292,\"r\":0.0518,\"rot\":270,\"layer\":134},{\"node\":\"g37\",\"kind\":\"screw\",\"u\":0.6884,\"v\":0.0248,\"r\":0.0355,\"rot\":69,\"layer\":135},{\"node\":\"g45\",\"kind\":\"light\",\"u\":0.1146,\"v\":0.0413,\"r\":0.0601,\"rot\":210,\"layer\":136},{\"node\":\"m02\",\"kind\":\"screw\",\"u\":0.9712,\"v\":0.9375,\"r\":0.0437,\"rot\":90,\"layer\":137},{\"node\":\"g27\",\"kind\":\"screw\",\"u\":0.7159,\"v\":0.4876,\"r\":0.0333,\"rot\":333,\"layer\":138},{\"node\":\"g43\",\"kind\":\"screw\",\"u\":0.4201,\"v\":0.9385,\"r\":0.0311,\"rot\":138,\"layer\":139},{\"node\":\"g08\",\"kind\":\"plate\",\"u\":0.7815,\"v\":0.9163,\"r\":0.0352,\"rot\":270,\"layer\":140},{\"node\":\"g23\",\"kind\":\"light\",\"u\":0.1507,\"v\":0.3107,\"r\":0.0455,\"rot\":210,\"layer\":141},{\"node\":\"m36\",\"kind\":\"pipe\",\"u\":0.6026,\"v\":0.615,\"r\":0.0425,\"rot\":63,\"layer\":142},{\"node\":\"m32\",\"kind\":\"screw\",\"u\":0.5533,\"v\":0.1332,\"r\":0.0334,\"rot\":117,\"layer\":143},{\"node\":\"g58\",\"kind\":\"pipe\",\"u\":0.9433,\"v\":0.195,\"r\":0.0379,\"rot\":207,\"layer\":144},{\"node\":\"g20\",\"kind\":\"screw\",\"u\":0.0707,\"v\":0.9502,\"r\":0.0382,\"rot\":183,\"layer\":145},{\"node\":\"m33\",\"kind\":\"light\",\"u\":0.2566,\"v\":0.3799,\"r\":0.046,\"rot\":243,\"layer\":146},{\"node\":\"m37\",\"kind\":\"pipe\",\"u\":0.7698,\"v\":0.2851,\"r\":0.0364,\"rot\":114,\"layer\":147},{\"node\":\"g01\",\"kind\":\"light\",\"u\":0.4918,\"v\":0.928,\"r\":0.0437,\"rot\":138,\"layer\":148},{\"node\":\"m16\",\"kind\":\"light\",\"u\":0.1816,\"v\":0.0189,\"r\":0.0622,\"rot\":90,\"layer\":149},{\"node\":\"m30\",\"kind\":\"pipe\",\"u\":0.33,\"v\":0.3368,\"r\":0.0515,\"rot\":303,\"layer\":150},{\"node\":\"m39\",\"kind\":\"pipe\",\"u\":0.0519,\"v\":0.8586,\"r\":0.0425,\"rot\":165,\"layer\":151},{\"node\":\"m22\",\"kind\":\"pipe\",\"u\":0.806,\"v\":0.4967,\"r\":0.0548,\"rot\":63,\"layer\":152},{\"node\":\"m28\",\"kind\":\"pipe\",\"u\":0.0514,\"v\":0.19,\"r\":0.0473,\"rot\":240,\"layer\":153},{\"node\":\"m10\",\"kind\":\"pipe\",\"u\":0.6295,\"v\":0.3626,\"r\":0.0439,\"rot\":237,\"layer\":154},{\"node\":\"g28\",\"kind\":\"screw\",\"u\":0.5608,\"v\":0.543,\"r\":0.0457,\"rot\":90,\"layer\":155},{\"node\":\"g56\",\"kind\":\"screw\",\"u\":0.2562,\"v\":0.6812,\"r\":0.0371,\"rot\":183,\"layer\":156},{\"node\":\"m32\",\"kind\":\"screw\",\"u\":0.5373,\"v\":0.5134,\"r\":0.0334,\"rot\":270,\"layer\":157},{\"node\":\"m11\",\"kind\":\"light\",\"u\":0.5466,\"v\":0.2054,\"r\":0.0477,\"rot\":270,\"layer\":158},{\"node\":\"g27\",\"kind\":\"screw\",\"u\":0.177,\"v\":0.2216,\"r\":0.0393,\"rot\":90,\"layer\":159},{\"node\":\"g49\",\"kind\":\"pipe\",\"u\":0.787,\"v\":0.6175,\"r\":0.0508,\"rot\":33,\"layer\":160},{\"node\":\"m37\",\"kind\":\"pipe\",\"u\":0.8188,\"v\":0.0247,\"r\":0.0364,\"rot\":36,\"layer\":161},{\"node\":\"g42\",\"kind\":\"screw\",\"u\":0.5775,\"v\":0.649,\"r\":0.0363,\"rot\":333,\"layer\":162},{\"node\":\"g20\",\"kind\":\"screw\",\"u\":0.4111,\"v\":0.4507,\"r\":0.0323,\"rot\":315,\"layer\":163},{\"node\":\"m16\",\"kind\":\"light\",\"u\":0.4191,\"v\":0.5903,\"r\":0.0373,\"rot\":90,\"layer\":164},{\"node\":\"g47\",\"kind\":\"light\",\"u\":0.5336,\"v\":0.9855,\"r\":0.0541,\"rot\":180,\"layer\":165},{\"node\":\"g01\",\"kind\":\"light\",\"u\":0.1545,\"v\":0.7558,\"r\":0.0437,\"rot\":327,\"layer\":166},{\"node\":\"g08\",\"kind\":\"plate\",\"u\":0.9745,\"v\":0.1685,\"r\":0.0416,\"rot\":270,\"layer\":167},{\"node\":\"m24\",\"kind\":\"light\",\"u\":0.9726,\"v\":0.1239,\"r\":0.0459,\"rot\":90,\"layer\":168},{\"node\":\"g43\",\"kind\":\"screw\",\"u\":0.9748,\"v\":0.0263,\"r\":0.0311,\"rot\":0,\"layer\":169},{\"node\":\"g29\",\"kind\":\"light\",\"u\":0.1356,\"v\":0.5155,\"r\":0.0684,\"rot\":336,\"layer\":170},{\"node\":\"g36\",\"kind\":\"pipe\",\"u\":0.8051,\"v\":0.2012,\"r\":0.0483,\"rot\":147,\"layer\":171},{\"node\":\"g18\",\"kind\":\"screw\",\"u\":0.4515,\"v\":0.1307,\"r\":0.0298,\"rot\":333,\"layer\":172},{\"node\":\"m44\",\"kind\":\"screw\",\"u\":0.0584,\"v\":0.7108,\"r\":0.0455,\"rot\":339,\"layer\":173},{\"node\":\"g13\",\"kind\":\"screw\",\"u\":0.4519,\"v\":0.692,\"r\":0.0276,\"rot\":132,\"layer\":174},{\"node\":\"g04\",\"kind\":\"screw\",\"u\":0.6068,\"v\":0.4548,\"r\":0.0329,\"rot\":235,\"layer\":175},{\"node\":\"g22\",\"kind\":\"gear\",\"u\":0.0429,\"v\":0.0235,\"r\":0.0372,\"rot\":170,\"layer\":176},{\"node\":\"g02\",\"kind\":\"plate\",\"u\":0.8257,\"v\":0.6466,\"r\":0.029,\"rot\":310,\"layer\":177},{\"node\":\"m18\",\"kind\":\"valve\",\"u\":0.8285,\"v\":0.7468,\"r\":0.0373,\"rot\":126,\"layer\":178},{\"node\":\"g17\",\"kind\":\"light\",\"u\":0.666,\"v\":0.1148,\"r\":0.0266,\"rot\":11,\"layer\":179},{\"node\":\"g54\",\"kind\":\"gear\",\"u\":0.0363,\"v\":0.8873,\"r\":0.0372,\"rot\":113,\"layer\":180},{\"node\":\"m45\",\"kind\":\"screw\",\"u\":0.1632,\"v\":0.0951,\"r\":0.0276,\"rot\":114,\"layer\":181},{\"node\":\"g33\",\"kind\":\"gear\",\"u\":0.875,\"v\":0.0207,\"r\":0.0371,\"rot\":249,\"layer\":182},{\"node\":\"g07\",\"kind\":\"gear\",\"u\":0.0363,\"v\":0.927,\"r\":0.0373,\"rot\":120,\"layer\":183},{\"node\":\"g14\",\"kind\":\"screw\",\"u\":0.4222,\"v\":0.8274,\"r\":0.0285,\"rot\":155,\"layer\":184},{\"node\":\"g32\",\"kind\":\"screw\",\"u\":0.4019,\"v\":0.5456,\"r\":0.0286,\"rot\":76,\"layer\":185},{\"node\":\"m07\",\"kind\":\"plate\",\"u\":0.3164,\"v\":0.019,\"r\":0.0342,\"rot\":295,\"layer\":186},{\"node\":\"g26\",\"kind\":\"gear\",\"u\":0.3209,\"v\":0.5172,\"r\":0.0343,\"rot\":238,\"layer\":187},{\"node\":\"g40\",\"kind\":\"gear\",\"u\":0.9626,\"v\":0.6153,\"r\":0.0355,\"rot\":92,\"layer\":188},{\"node\":\"g46\",\"kind\":\"plate\",\"u\":0.9198,\"v\":0.7154,\"r\":0.0329,\"rot\":42,\"layer\":189},{\"node\":\"m03\",\"kind\":\"plate\",\"u\":0.9295,\"v\":0.1079,\"r\":0.0358,\"rot\":147,\"layer\":190},{\"node\":\"m20\",\"kind\":\"pipe\",\"u\":0.395,\"v\":0.7688,\"r\":0.0319,\"rot\":345,\"layer\":191},{\"node\":\"g53\",\"kind\":\"gear\",\"u\":0.0366,\"v\":0.1205,\"r\":0.0376,\"rot\":118,\"layer\":192},{\"node\":\"g03\",\"kind\":\"plate\",\"u\":0.58,\"v\":0.7718,\"r\":0.0308,\"rot\":325,\"layer\":193},{\"node\":\"g15\",\"kind\":\"light\",\"u\":0.082,\"v\":0.3599,\"r\":0.0285,\"rot\":180,\"layer\":194},{\"node\":\"m15\",\"kind\":\"plate\",\"u\":0.916,\"v\":0.3594,\"r\":0.0299,\"rot\":293,\"layer\":195},{\"node\":\"g25\",\"kind\":\"screw\",\"u\":0.9797,\"v\":0.783,\"r\":0.0286,\"rot\":0,\"layer\":196},{\"node\":\"g37\",\"kind\":\"screw\",\"u\":0.8516,\"v\":0.1986,\"r\":0.0251,\"rot\":15,\"layer\":197},{\"node\":\"m20\",\"kind\":\"pipe\",\"u\":0.3683,\"v\":0.3973,\"r\":0.0225,\"rot\":0,\"layer\":198},{\"node\":\"g50\",\"kind\":\"screw\",\"u\":0.5723,\"v\":0.5167,\"r\":0.0273,\"rot\":30,\"layer\":199},{\"node\":\"g52\",\"kind\":\"plate\",\"u\":0.6299,\"v\":0.1286,\"r\":0.0276,\"rot\":30,\"layer\":200},{\"node\":\"m36\",\"kind\":\"pipe\",\"u\":0.824,\"v\":0.9141,\"r\":0.0354,\"rot\":115,\"layer\":201},{\"node\":\"g35\",\"kind\":\"screw\",\"u\":0.6582,\"v\":0.8069,\"r\":0.0284,\"rot\":115,\"layer\":202},{\"node\":\"g11\",\"kind\":\"pipe\",\"u\":0.1266,\"v\":0.9024,\"r\":0.0326,\"rot\":125,\"layer\":203},{\"node\":\"g23\",\"kind\":\"light\",\"u\":0.8713,\"v\":0.9596,\"r\":0.0321,\"rot\":15,\"layer\":204},{\"node\":\"g17\",\"kind\":\"light\",\"u\":0.5918,\"v\":0.2254,\"r\":0.0221,\"rot\":40,\"layer\":205},{\"node\":\"m35\",\"kind\":\"light\",\"u\":0.6758,\"v\":0.9754,\"r\":0.0401,\"rot\":270,\"layer\":206},{\"node\":\"g42\",\"kind\":\"screw\",\"u\":0.3751,\"v\":0.704,\"r\":0.0256,\"rot\":210,\"layer\":207},{\"node\":\"g24\",\"kind\":\"light\",\"u\":0.6484,\"v\":0.7176,\"r\":0.0381,\"rot\":255,\"layer\":208},{\"node\":\"g20\",\"kind\":\"screw\",\"u\":0.877,\"v\":0.6049,\"r\":0.0269,\"rot\":165,\"layer\":209},{\"node\":\"g08\",\"kind\":\"plate\",\"u\":0.4473,\"v\":0.6038,\"r\":0.0294,\"rot\":30,\"layer\":210},{\"node\":\"m32\",\"kind\":\"screw\",\"u\":0.5977,\"v\":0.9096,\"r\":0.0278,\"rot\":115,\"layer\":211},{\"node\":\"g08\",\"kind\":\"plate\",\"u\":0.7686,\"v\":0.9431,\"r\":0.0294,\"rot\":125,\"layer\":212},{\"node\":\"g25\",\"kind\":\"screw\",\"u\":0.0323,\"v\":0.9542,\"r\":0.0286,\"rot\":115,\"layer\":213},{\"node\":\"g49\",\"kind\":\"pipe\",\"u\":0.2867,\"v\":0.3532,\"r\":0.0358,\"rot\":45,\"layer\":214},{\"node\":\"g49\",\"kind\":\"pipe\",\"u\":0.2543,\"v\":0.7081,\"r\":0.0358,\"rot\":285,\"layer\":215}]}","pose-classifier.mjs":"// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// k-NN pose classifier: a plain-JS reimplementation of the pose classification method documented by Google\r\n// MediaPipe (the \"Pose classification\" colab for MediaPipe Pose, Apache-2.0): normalise landmarks on the hip centre\r\n// and torso size, embed pairwise joint distances, keep the top 30 samples by max distance, then the top 10 by mean\r\n// distance, and vote. A mirrored pose (x negated, as in the original) also matches, so one side's recording\r\n// serves both. Differences: 2D (the engine keeps no z), feet and ankles dropped (they never enter counting).\r\n// Counting on these votes (EMA, enter/exit thresholds) lives in movement-engine.mjs.\r\nexport const EMBED_LANDMARKS=[11,12,13,14,15,16,23,24,25,26];\r\nconst PAIRS=[[11,13],[12,14],[13,15],[14,16],[23,25],[24,26],[11,15],[12,16],[23,15],[24,16],[13,14],[25,26],[15,16]];\r\n// p: aspect-corrected points (features().p). Returns 2 numbers per pair, torso first.\r\nexport function embed(p){\r\n const hx=(p[23].x+p[24].x)/2,hy=(p[23].y+p[24].y)/2,sx=(p[11].x+p[12].x)/2,sy=(p[11].y+p[12].y)/2;\r\n const size=Math.max(Math.hypot(sx-hx,sy-hy)*2.5,...EMBED_LANDMARKS.map(i=>Math.hypot(p[i].x-hx,p[i].y-hy)))||1;\r\n const e=[(sx-hx)/size,(sy-hy)/size];\r\n for(const [a,b] of PAIRS)e.push((p[b].x-p[a].x)/size,(p[b].y-p[a].y)/size);\r\n return e;\r\n}\r\n// samples file: {exercise, need:[landmark ids], samples:[[label,[embedding]],…]} from scripts/pose-samples.mjs.\r\nexport class PoseClassifier{\r\n constructor({need=[11,12,23,24],samples}){this.need=need;this.samples=samples.map(([label,e])=>({label,e:Float64Array.from(e)}));}\r\n classify(p){\r\n  const e=embed(p),m=e.map((v,i)=>i%2?v:-v),n=e.length;\r\n  const dist=(s,q)=>{let max=0,sum=0;for(let i=0;i<n;i++){const d=Math.abs(s[i]-q[i]);sum+=d;if(d>max)max=d;}return [max,sum/n];};\r\n  const scored=this.samples.map(({label,e:s})=>{const a=dist(s,e),b=dist(s,m);return {label,max:Math.min(a[0],b[0]),mean:Math.min(a[1],b[1])};});\r\n  const top=scored.sort((a,b)=>a.max-b.max).slice(0,30).sort((a,b)=>a.mean-b.mean).slice(0,10);\r\n  const votes={};for(const {label} of top)votes[label]=(votes[label]??0)+1/top.length;\r\n  return votes;\r\n }\r\n}\r\n","pose-frame.mjs":"// One pending camera callback, cancelled when the set stops. Prefer fresh decoded frames.\r\nexport class PoseFrameScheduler {\r\n constructor(video,{request=requestAnimationFrame,cancel=cancelAnimationFrame}={}){this.video=video;this.request=request;this.cancel=cancel;this.id=null;this.videoFrame=false;this.frame=null;}\r\n schedule(callback){\r\n  this.stop();this.videoFrame=typeof this.video.requestVideoFrameCallback==='function';\r\n  const run=(time,metadata)=>{this.id=null;this.frame=metadata??null;callback();};\r\n  this.id=this.videoFrame?this.video.requestVideoFrameCallback(run):this.request(run);\r\n }\r\n stop(){if(this.id!==null){if(this.videoFrame)this.video.cancelVideoFrameCallback(this.id);else this.cancel(this.id);this.id=null;}}\r\n}\r\n","pose-recorder.mjs":"// Dev-only, loaded by ?recordPose=1: records the camera workout's landmark stream plus tap-labelled \"down\"/\"up\"\r\n// frames as a JSON download for scripts/pose-samples.mjs. Tap Down or Up, get into that position during the\r\n// 3 s countdown and hold it; the next 1.5 s of frames carry the label. Switching exercise starts a new recording.\r\nexport function mountPoseRecorder(stage){\r\n let recording=null;\r\n const bar=document.createElement('div');bar.setAttribute('role','group');bar.setAttribute('aria-label','Pose recorder');\r\n bar.style.cssText='position:absolute;left:8px;right:8px;bottom:max(16px,env(safe-area-inset-bottom));z-index:2;display:flex;gap:8px;align-items:stretch;font:600 15px system-ui,sans-serif;color:#fff';\r\n const status=document.createElement('output');status.setAttribute('aria-live','polite');status.style.cssText='flex:1;min-width:0;padding:8px 10px;border-radius:12px;background:#000a';status.textContent='Recorder waiting for tracking';\r\n const button=(text,onClick)=>{const b=document.createElement('button');b.type='button';b.textContent=text;b.style.cssText='min-width:64px;min-height:48px;border:0;border-radius:12px;background:#fff;color:#000;font:inherit';b.addEventListener('click',onClick);bar.append(b);};\r\n const show=()=>{\r\n  if(!recording)return;const now=performance.now(),last=recording.labels.at(-1);\r\n  status.textContent=last&&now<last.from?`${last.label.toUpperCase()} in ${Math.ceil((last.from-now)/1000)}…`:last&&now<=last.to?`Hold ${last.label}…`:`${recording.exercise} · ${recording.frames.length} frames · ${recording.labels.length} labels · ${(window.myr5TestState?.rate??0).toFixed(1)}/s ${window.myr5TestState?.delegate||''}`;\r\n };\r\n const label=name=>{if(!recording)return;const from=Math.round(performance.now()+3000);recording.labels.push({label:name,from,to:from+1500});show();};\r\n bar.append(status);button('Down',()=>label('down'));button('Up',()=>label('up'));\r\n button('Save',()=>{\r\n  if(!recording?.frames.length)return;\r\n  const link=document.createElement('a');link.href=URL.createObjectURL(new Blob([JSON.stringify(recording)],{type:'application/json'}));\r\n  link.download=`recordPose-${recording.exercise}-${new Date().toISOString().slice(0,19).replace(/[:T]/g,'-')}.json`;\r\n  bar.append(link);link.click();link.remove();setTimeout(()=>URL.revokeObjectURL(link.href),10000);status.textContent='Saved '+link.download;\r\n });\r\n stage.append(bar);\r\n addEventListener('myr5:pose',({detail})=>{\r\n  const exercise=window.myr5TestState?.motion?.mode;if(stage.hidden||!detail.points||!exercise)return;\r\n  if(recording?.exercise!==exercise)recording={version:1,exercise,aspect:detail.width/detail.height,frames:[],labels:[]};\r\n  recording.frames.push([Math.round(detail.now),detail.points.slice(0,27).map(v=>[+v.x.toFixed(4),+v.y.toFixed(4),+(v.visibility??0).toFixed(3)]),...detail.world?[detail.world.slice(0,27).map(v=>[+v.x.toFixed(4),+v.y.toFixed(4),+v.z.toFixed(4)])]:[]]);\r\n  show();\r\n });\r\n}\r\n","pose-samples.mjs":"// Generated by scripts/pose-samples.mjs from pose-samples/*.samples.json. Do not edit by hand.\r\n// Exercises listed here count reps with the k-NN pose classifier; every other exercise uses the rules.\r\nexport default {};\r\n","pose.html":"<!doctype html>\r\n<!-- Pixel test adapted from Ian's MYR5 pose.html in the Barehands project.\r\n     Barehands copyright (c) 2026 Jared Rhodenizer; AGPL-3.0-or-later.\r\n     Source and license: /pose.html and /LICENSE. Camera frames stay in this browser. -->\r\n<html lang=\"en\">\r\n<meta charset=\"utf-8\">\r\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,viewport-fit=cover\">\r\n<title>MYR5 · AR alien workout coach</title>\r\n<meta name=\"description\" content=\"MYR5: free AR workout coach in your browser. A 3D alien coach counts your reps with your phone camera, on-device. No equipment, no headset.\">\r\n<link rel=\"canonical\" href=\"https://myr5.mominc.online/\">\r\n<meta property=\"og:type\" content=\"website\"><meta property=\"og:site_name\" content=\"MYR5 Coach\"><meta property=\"og:url\" content=\"https://myr5.mominc.online/\">\r\n<meta property=\"og:title\" content=\"MYR5 · AR alien workout coach\">\r\n<meta property=\"og:description\" content=\"Your phone camera counts reps on-device; finish sets to level up your alien coach. Free, no download.\">\r\n<meta property=\"og:image\" content=\"https://myr5.mominc.online/icons/myr5-alien-512.png\">\r\n<meta name=\"twitter:card\" content=\"summary\"><meta name=\"twitter:title\" content=\"MYR5 · AR alien workout coach\"><meta name=\"twitter:description\" content=\"Your phone camera counts reps on-device; finish sets to level up your alien coach. Free, no download.\"><meta name=\"twitter:image\" content=\"https://myr5.mominc.online/icons/myr5-alien-512.png\">\r\n<script type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://myr5.mominc.online/#operator\",\"name\":\"MYR5\",\"description\":\"Independent app maker of MYR5 Coach\",\"url\":\"https://myr5.mominc.online/about\",\"email\":\"ianmyersrocks97@gmail.com\"},{\"@type\":\"SoftwareApplication\",\"@id\":\"https://myr5.mominc.online/#app\",\"name\":\"MYR5 Coach\",\"alternateName\":\"MYR5\",\"url\":\"https://myr5.mominc.online/\",\"description\":\"Free browser workout app with a 3D alien coach. The phone camera counts reps and holds on the device; video frames are not uploaded. Installs as a web app; no equipment or headset. Intended for ages 13 and up.\",\"applicationCategory\":\"HealthApplication\",\"applicationSubCategory\":\"Fitness\",\"operatingSystem\":\"Any modern browser (Android, iOS, desktop)\",\"browserRequirements\":\"Requires JavaScript, WebGL and camera access for rep counting\",\"offers\":{\"@type\":\"Offer\",\"price\":\"0\",\"priceCurrency\":\"USD\"},\"typicalAgeRange\":\"13-\",\"author\":{\"@id\":\"https://myr5.mominc.online/#operator\"},\"publisher\":{\"@id\":\"https://myr5.mominc.online/#operator\"},\"mainEntityOfPage\":\"https://myr5.mominc.online/about\"}]}</script>\r\n<meta name=\"theme-color\" content=\"#21172f\">\r\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\r\n<meta name=\"apple-mobile-web-app-title\" content=\"MYR5 Coach\">\r\n<link rel=\"manifest\" href=\"/manifest.webmanifest?v=myr5-alien-v1\">\r\n<script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script>\r\n<link rel=\"modulepreload\" href=\"/launch-runtime.mjs?v=startup-recovery-1\">\r\n<link rel=\"modulepreload\" href=\"/app-runtime.mjs?v=rest-flow-1\">\r\n<link rel=\"modulepreload\" href=\"/local-coach-runtime.mjs?v=rest-flow-1\">\r\n<link rel=\"preconnect\" href=\"https://cdn.jsdelivr.net\" crossorigin>\r\n<link rel=\"preconnect\" href=\"https://storage.googleapis.com\" crossorigin>\r\n<link rel=\"icon\" type=\"image/webp\" href=\"/pod/mom-inc-mark-96.webp\"><link rel=\"apple-touch-icon\" href=\"/pod/mom-inc-mark-96.webp\">\r\n<link rel=\"stylesheet\" href=\"/launch.css\">\r\n<link rel=\"stylesheet\" href=\"/menu.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/pod.css\">\r\n<link rel=\"stylesheet\" href=\"/flip-display.css\">\r\n<link rel=\"stylesheet\" href=\"/food-live.css\">\r\n<link rel=\"stylesheet\" href=\"/battle-pass-page.css\">\r\n<link rel=\"stylesheet\" href=\"/spotify-terminal.css\">\r\n<link rel=\"stylesheet\" href=\"/actual-dj.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/whiteboard.css\">\r\n<link rel=\"stylesheet\" href=\"/focus-library.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/control-board.css\">\r\n<link rel=\"stylesheet\" href=\"/arcade/tub-flight/style.css\">\r\n<link rel=\"stylesheet\" href=\"/meditation.css\"><link rel=\"stylesheet\" href=\"/pod/rest-arena.css\">\r\n<link rel=\"stylesheet\" href=\"/personal-tracker.css\"><link rel=\"stylesheet\" href=\"/scoreboard.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/retro-rooms.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/weapon-abilities.css\">\r\n<link rel=\"stylesheet\" href=\"/coach-hub.css\"><link rel=\"stylesheet\" href=\"/settings-frame.css\"><link rel=\"stylesheet\" href=\"/settings-crt.css\"><link rel=\"stylesheet\" href=\"/achievements-board.css\"><link rel=\"stylesheet\" href=\"/pod/home-character.css\">\r\n<link rel=\"stylesheet\" href=\"/camera-workout.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/ship-interior.css\">\r\n<link rel=\"stylesheet\" href=\"/pod/persistent-chrome.css\">\r\n<link rel=\"stylesheet\" href=\"/shader-effects.css\">\r\n<div class=\"device-bezel\" aria-hidden=\"true\"><i class=\"case-screw case-tl\"></i><i class=\"case-screw case-tr\"></i><i class=\"case-screw case-bl\"></i><i class=\"case-screw case-br\"></i></div>\r\n<noscript><h1>MYR5 Coach: AR alien workout coach</h1><p>MYR5 is a free web app for bodyweight workouts with a 3D alien coach. Your phone's camera counts reps and holds on the device; video is not uploaded. It installs from the browser, with no store, headset or equipment. Intended for ages 13 and up. Made by MYR5, an independent app. The app itself needs JavaScript. <a href=\"/about\">About MYR5</a> | <a href=\"/privacy\">Privacy</a></p></noscript>\r\n<div id=\"podShipBackdrop\" class=\"pod-ship-backdrop\" aria-hidden=\"true\" data-motion-running=\"false\">\r\n <img class=\"pod-ship-nebula\" src=\"/pod/assets/nebula.webp\" alt=\"\" draggable=\"false\">\r\n <img class=\"pod-ship-cutout\" src=\"/pod/assets/ship-interior-cutout.png\" alt=\"\" draggable=\"false\">\r\n <span class=\"pod-ship-lights\" aria-hidden=\"true\"></span>\r\n</div>\r\n<header class=\"ship-header\"><a class=\"mom-brand\" href=\"#pod\" aria-label=\"Return to the pod\"><img src=\"/pod/mom-inc-mark-96.webp\" width=\"36\" height=\"36\" alt=\"MOM Inc\"></a><button id=\"openSettings\" class=\"icon-button ship-settings-toggle\" aria-label=\"Open settings terminal\" aria-haspopup=\"dialog\" aria-controls=\"settings\"><span class=\"ship-settings-handle\" aria-hidden=\"true\"></span><span class=\"ship-settings-screen\" aria-hidden=\"true\"><strong>SETTINGS</strong></span></button></header>\r\n<main id=\"homeScreen\" class=\"pod-page\">\r\n <nav class=\"pod-header-actions\" aria-label=\"Pod character\"><button id=\"openIdentity\" type=\"button\"><canvas id=\"miniAvatar\" width=\"64\" height=\"96\" aria-hidden=\"true\"></canvas><span id=\"guestLabel\">Anonymous guest</span></button><a data-access-route=\"/creature/index.html\" href=\"/creature/index.html\">Customize coach</a></nav>\r\n <div class=\"deck-strip\"><span><i class=\"status-light\"></i> POD 005</span><details id=\"podGoals\" class=\"pod-goals\"><summary>GOALS <span data-goals-status></span></summary><div class=\"pod-goals-menu\"></div></details><span id=\"levelBadge\">WORKOUT LV. 01</span></div>\r\n <div id=\"trainingView\" class=\"training-view\">\r\n <div class=\"containment-bay\">\r\n <section id=\"view\" class=\"containment-pod\" aria-label=\"Your character's viewing port\">\r\n  <i class=\"frame-bolt tl\" aria-hidden=\"true\"></i><i class=\"frame-bolt tr\" aria-hidden=\"true\"></i><i class=\"frame-bolt bl\" aria-hidden=\"true\"></i><i class=\"frame-bolt br\" aria-hidden=\"true\"></i><div class=\"pod-top-vent\" aria-hidden=\"true\"></div>\r\n  <div class=\"pod-rim rim-left\" aria-hidden=\"true\"></div><div class=\"pod-rim rim-right\" aria-hidden=\"true\"></div>\r\n  <div class=\"pod-inscription\" aria-hidden=\"true\">M Y R 5</div>\r\n  <div class=\"coach-line\"><span class=\"voice-led\" aria-hidden=\"true\"></span><p id=\"coachCaption\" aria-live=\"polite\">Ready when you are.</p></div>\r\n  <div id=\"coachMount\" class=\"coach-mount\"><p id=\"coachLoading\">Loading…</p></div>\r\n  <section id=\"homeCharacter\" class=\"home-character\" aria-label=\"Your Gala character\" hidden><button type=\"button\" aria-label=\"Play your equipped weapon attack\"><canvas width=\"160\" height=\"168\" role=\"img\" aria-label=\"Your Gala character\"></canvas><span data-weapon></span></button></section>\r\n  <div class=\"pod-floor\" aria-hidden=\"true\"></div>\r\n  <div id=\"cameraPreview\" class=\"camera-preview\"><video id=\"v\" playsinline muted></video><canvas id=\"c\"></canvas><span id=\"previewLabel\">CAMERA OFF</span></div>\r\n </section></div>\r\n  <div id=\"hud\" class=\"simple-counter\"><div class=\"counter-readout\"><small id=\"setNumber\">SET 01</small><span id=\"primary\">00</span><div class=\"counter-target\"><span id=\"primaryLabel\">reps</span><span class=\"target-divider\" aria-hidden=\"true\"></span><span>Goal <span id=\"goalValue\">3</span></span></div></div></div>\r\n </div>\r\n <section id=\"controls\" class=\"workout-console\" aria-label=\"Your set\">\r\n\r\n  <div class=\"control-board difficulty-control\" role=\"group\" aria-label=\"Workout selector\">\r\n   <div class=\"cb-top\"><div class=\"cb-readout\"><div class=\"cb-line\"><strong id=\"exerciseName\">Chest</strong><output id=\"difficultySetting\" for=\"difficultySlider\">LV 1/8</output></div><button type=\"button\" id=\"variationName\" aria-live=\"polite\" aria-haspopup=\"dialog\" aria-controls=\"library\" title=\"See this movement\">Knee push-up</button></div><button id=\"openLibrary\" class=\"cb-key\" aria-label=\"Open movement library\">MOVE&shy;MENTS ↗</button></div>\r\n   <select id=\"movement\" aria-label=\"Movement\" hidden></select>\r\n   <div class=\"cb-deck\">\r\n    <div class=\"cb-part\"><span class=\"cb-label\" id=\"exerciseDialLabel\">FOCUS</span><div id=\"exerciseDial\" class=\"cb-rotary cb-dial\" role=\"slider\" tabindex=\"0\" aria-labelledby=\"exerciseDialLabel\" aria-valuemin=\"0\" aria-valuemax=\"9\" aria-valuenow=\"0\" aria-valuetext=\"Chest\"><span class=\"cb-ticks\" aria-hidden=\"true\"></span><i aria-hidden=\"true\"></i></div></div>\r\n    <div class=\"cb-part\"><span class=\"cb-label\" id=\"difficultyLabel\">LEVEL</span><div id=\"difficultySlider\" class=\"cb-rotary cb-knob\" role=\"slider\" tabindex=\"0\" aria-labelledby=\"difficultyLabel\" aria-valuemin=\"1\" aria-valuemax=\"8\" aria-valuenow=\"1\" aria-valuetext=\"Knee push-up, level 1 of 8\"><span class=\"cb-ticks\" aria-hidden=\"true\"></span><i aria-hidden=\"true\"></i></div><span class=\"cb-scale\" aria-hidden=\"true\"><span>1</span><span id=\"difficultyMax\">8</span></span></div>\r\n    <div class=\"cb-part cb-lever\" role=\"group\" aria-label=\"Difficulty lever\"><button type=\"button\" id=\"harder\">HARDER</button><i aria-hidden=\"true\"></i><button type=\"button\" id=\"easier\">EASIER</button></div>\r\n    <div class=\"cb-part\"><span class=\"cb-label\" aria-hidden=\"true\">SOUND</span><button id=\"toggleVoice\" class=\"cb-switch\" role=\"switch\" aria-label=\"Coach sound\" aria-checked=\"true\" data-on=\"true\">ON</button></div>\r\n   </div>\r\n   <button type=\"button\" id=\"coolCardio\" class=\"cb-cardio\" aria-label=\"Start endless Cool Cardio runner\"><span class=\"cb-cardio-led\" aria-hidden=\"true\"></span><strong>COOL CARDIO</strong><small>ENDLESS</small></button>\r\n   <details class=\"movement-scope\"><summary>Tracking details</summary><p id=\"variationHint\"></p><p id=\"trackingScope\"></p></details>\r\n  </div>\r\n  <p>During camera workouts, tap the counter to stop.</p>\r\n  <div class=\"set-actions\"><button id=\"start\" aria-label=\"Begin set\" class=\"primary-action\"><strong>BEGIN</strong></button><button id=\"stop\" disabled hidden>STOP</button></div>\r\n  <div id=\"bar\" class=\"set-track\" aria-hidden=\"true\"><div id=\"activity\"></div></div>\r\n  <p id=\"status\" role=\"status\" hidden></p>\r\n  <span id=\"movementName\" hidden>Squats</span><span id=\"secondary\" hidden></span><span id=\"countState\" hidden></span>\r\n </section>\r\n <!-- W2-2M #117: the pod keeps only the viewing port, the control board and BEGIN. The extras that hang off\r\n      .crew-footer (personal tracker, optional expansion, Meditation entry) ride in #podExtras, which coach-hub.mjs\r\n      moves into Records (bar); Meditation stays reachable as the #meditate route. -->\r\n <div id=\"podExtras\" class=\"pod-extras\"><footer class=\"crew-footer\"></footer></div>\r\n</main>\r\n<main id=\"restScreen\" class=\"rest-page\" hidden aria-labelledby=\"restHeading\">\r\n <div class=\"rest-heading\"><div><p class=\"eyebrow\" id=\"restEyebrow\">SET COMPLETE</p><h1 id=\"restHeading\" tabindex=\"-1\">Rest</h1></div><button id=\"leaveRest\" class=\"icon-button\" aria-label=\"Return to the pod\">↗</button></div>\r\n <div class=\"rest-receipt\"><span id=\"setReceipt\">Set saved</span><span id=\"earnedXp\">+25 XP</span></div>\r\n <section class=\"encounter\" aria-label=\"Rest encounter with your custom coach\">\r\n  <div class=\"rest-world-backdrop\" aria-hidden=\"true\"></div><div class=\"rest-world-floor\" aria-hidden=\"true\"></div>\r\n  <div class=\"encounter-orbit\" aria-hidden=\"true\"></div><div class=\"encounter-grid\" aria-hidden=\"true\"></div>\r\n  <div class=\"boss-status\"><span id=\"powerName\">SHIELD ACTIVE</span><span id=\"damageTotal\">0 DAMAGE</span><span id=\"coachHealth\">1,000,000,000 HP</span><div class=\"boss-health\" role=\"progressbar\" aria-label=\"Coach health\" aria-valuemin=\"0\" aria-valuemax=\"1000000000\" aria-valuenow=\"1000000000\"><i id=\"bossHealth\"></i></div></div>\r\n  <div class=\"coach-battle-platform\" aria-hidden=\"true\"></div><span id=\"restWeaponName\" class=\"rest-weapon-name\"></span>\r\n  <div id=\"restCoachMount\" class=\"rest-coach-mount\"><p id=\"restCoachLoading\">Loading…</p></div>\r\n  <button id=\"attackCoach\" class=\"attack-target\" aria-label=\"Attack the coach with Helping Hand\"><span>TAP TO STRIKE</span></button>\r\n  <div id=\"attackFlash\" class=\"attack-flash\" aria-hidden=\"true\"></div><div id=\"projectile\" class=\"projectile\" aria-hidden=\"true\"></div>\r\n  <div id=\"damageFloat\" class=\"damage-float\" aria-hidden=\"true\"></div>\r\n  <div class=\"player-platform\"><div class=\"platform-top\"></div><div class=\"platform-edge\"></div><div class=\"platform-thruster\"></div><canvas id=\"restAvatar\" width=\"64\" height=\"96\" role=\"img\" aria-label=\"Your Gala character on the floating platform\"></canvas></div>\r\n  <canvas id=\"restWeaponFx\" width=\"640\" height=\"360\" aria-hidden=\"true\"></canvas>\r\n  <div class=\"weapon-ability\"><button id=\"weaponSpecial\" disabled>Special · tier 4</button><progress id=\"weaponCooldown\" max=\"1\" value=\"1\" aria-label=\"Special ability cooldown\"></progress></div>\r\n  <div class=\"rest-hand\"><div id=\"restHandMount\"></div><img id=\"restHandFallback\" data-optional-src=\"/handborne/previews/family-11.png?v=5\" alt=\"Your Helping Hand\" hidden></div>\r\n  <div class=\"player-name\"><span id=\"restGuest\">Gala guest</span><span id=\"restLevel\">LV. 01</span></div>\r\n </section>\r\n <div class=\"hand-team\"><span id=\"handTeamStatus\" role=\"status\">Helping Hand ready</span><button id=\"retryHand\" hidden>Retry hand</button><progress id=\"handCharge\" value=\"0\" max=\"3\" aria-label=\"Helping Hand team strike charge\"></progress><small id=\"handChargeLabel\">Team strike in 3 taps</small></div>\r\n <p id=\"restFeedback\" class=\"rest-feedback\" role=\"status\"></p>\r\n <div class=\"rest-bottom\"><div class=\"rest-clock\"><small>RECOVERY</small><strong id=\"restTime\">1:00</strong></div><div><button id=\"nextSet\" class=\"primary-action\" disabled>Next set →</button><button id=\"moreRest\" class=\"text-button\">+30 seconds</button></div></div>\r\n <p id=\"shieldNote\" class=\"shield-note\">Sign in to power your weapon.</p>\r\n</main>\r\n<dialog id=\"settings\" class=\"pod-dialog\" aria-labelledby=\"settingsTitle\"><header><h2 id=\"settingsTitle\">Settings</h2><button id=\"closeSettings\" aria-label=\"Close pod settings\">Close</button></header>\r\n  <details class=\"settings-group\"><summary>Workout</summary><div class=\"settings-fields\"><label>Set goal<select id=\"goal\" aria-label=\"Set goal\"></select></label><label>Rest between sets<select id=\"restDuration\"><option value=\"30\">30 seconds</option><option value=\"60\" selected>60 seconds</option><option value=\"90\">90 seconds</option><option value=\"120\">2 minutes</option></select></label><label>Camera<select id=\"camera\" aria-label=\"Camera\"><option value=\"user\">Front camera</option><option value=\"environment\">Back camera</option><option value=\"manual\">Manual / timer</option></select></label><label>Coach ability<select id=\"coachPower\"><option value=\"shield\">Shield</option><option value=\"ember\">Ember</option><option value=\"arc\">Arc</option><option value=\"frost\">Frost</option></select></label></div>\r\n   <div class=\"goal-control\"><div><label for=\"goalSlider\" id=\"goalLabel\">GOAL</label><output id=\"goalSetting\" for=\"goalSlider\">3 REPS</output></div><input id=\"goalSlider\" type=\"range\" min=\"0\" max=\"3\" step=\"1\" value=\"1\" aria-label=\"Set goal\"><div class=\"slider-scale\" aria-hidden=\"true\"><span id=\"goalMin\">1</span><span id=\"goalMax\">20</span></div></div></details>\r\n <details class=\"settings-group\"><summary>Voice</summary><div class=\"voice-row\"><button id=\"testVoice\">Test voice</button><span id=\"voiceType\">Robot voice</span></div></details>\r\n <details class=\"settings-group\"><summary>Materials</summary><div class=\"settings-fields\"><button id=\"manageMaterials\" type=\"button\">Manage materials</button><p id=\"materialsStatus\" role=\"status\">Sign in to download materials you own.</p><section id=\"materialControls\" hidden aria-label=\"Downloaded materials\"><button data-material-download type=\"button\">Download material</button><button data-material-cancel type=\"button\" hidden>Cancel</button><button data-material-equip type=\"button\" disabled>Equip after restart</button><p data-material-status role=\"status\"></p><div id=\"materialRuntime\" aria-label=\"Active material preview\"></div></section></div></details>\r\n <details class=\"settings-group\"><summary>Pod</summary><div class=\"settings-actions\"><button id=\"reset\">Reset count</button><button id=\"visitRest\">Rest room</button></div></details>\r\n <details><summary>About &amp; licenses</summary><p><a href=\"/LICENSE\">Coach source license</a> · <a href=\"/source.json\" download>Source code</a></p><div id=\"packLicenses\">Optional pack licenses load when Settings opens.</div></details>\r\n <details id=\"trackingDiag\"><summary>Camera & tracking</summary><p id=\"lensInfo\">The camera opens when you begin a set.</p><button id=\"widest\" disabled>Widest view</button><p id=\"hint\"></p><p id=\"paceNote\" hidden></p><p id=\"detail\">Camera off · Tracker closed</p><p id=\"measurement\"></p><p id=\"jointReadings\"></p><pre id=\"cameraDetails\"></pre><p id=\"note\">Keep the joints requested for your selected exercise in view. Movement estimates, not technique grades.</p></details>\r\n <div id=\"roundControl\" hidden><select id=\"duration\" aria-label=\"Legacy round duration\"><option value=\"0\">Open timer</option><option value=\"30\">30 seconds</option><option value=\"60\">1 minute</option><option value=\"120\">2 minutes</option><option value=\"180\">3 minutes</option></select></div>\r\n</dialog>\r\n<dialog id=\"identity\" class=\"pod-dialog avatar-dialog\" aria-labelledby=\"identityTitle\">\r\n <header><h2 id=\"identityTitle\">Your Gala avatar</h2><button id=\"closeIdentity\">Close</button></header>\r\n <div id=\"identitySummary\">\r\n  <canvas id=\"identityAvatar\" width=\"64\" height=\"96\" role=\"img\" aria-label=\"Your saved Gala appearance\"></canvas><p id=\"identityName\">Gala guest</p>\r\n  <details class=\"gala-import\"><summary>Change your Gala look</summary><label class=\"primary-action file-label\">Import Gala look<input id=\"importGala\" type=\"file\" accept=\"application/json,.json\"></label><a href=\"https://mominc.online/gala/\" target=\"_blank\" rel=\"noopener noreferrer\">Open Join Gala ↗</a></details>\r\n  <p id=\"identityStatus\" role=\"status\">Saved on this device</p>\r\n  <section class=\"weapon-subsection\" aria-labelledby=\"weaponHeading\"><h3 id=\"weaponHeading\">Weapon</h3><label>Weapon<select id=\"weaponType\"></select></label><label>Upgrade<select id=\"weaponTier\"></select></label><progress id=\"weaponLevelBar\" class=\"level-bar\" max=\"1\" value=\"0\" aria-label=\"XP to next level\"></progress><p id=\"weaponStatus\" role=\"status\"></p><details><summary>Upgrades</summary><p>Every workout earns XP toward your level; each level unlocks the next upgrade. Rest attacks earn no XP.</p></details></section>\r\n  <section class=\"hand-subsection\" aria-labelledby=\"handTitle\"><img id=\"identityHandPreview\" data-optional-src=\"/handborne/previews/family-11.png?v=5\" alt=\"Helping Hand creature family preview\"><div><h3 id=\"handTitle\">Helping Hand</h3><button id=\"customizeHand\" data-access-route=\"/handborne/index.html\" class=\"primary-action\">Customize hand →</button></div></section>\r\n </div>\r\n <section id=\"handEditorPanel\" hidden aria-label=\"Customize your companion\"><div class=\"hand-editor-bar\"><button id=\"backToAvatar\">← Your Gala avatar</button><span>Autosaved</span></div><iframe id=\"handEditorFrame\" title=\"Helping Hand customizer with live preview\" allow=\"clipboard-write\"></iframe></section>\r\n</dialog>\r\n\r\n<dialog id=\"library\" aria-labelledby=\"libraryTitle\">\r\n  <video id=\"handVideo\" playsinline muted hidden></video>\r\n  <div class=\"glass-shell\">\r\n    <header class=\"library-header\"><div><h1 id=\"libraryTitle\">Movements</h1></div><button id=\"closeLibrary\" data-hand aria-label=\"Close library\">Close</button></header>\r\n    <label class=\"library-filter\" for=\"libraryFocus\">Focus<select id=\"libraryFocus\"></select></label>\r\n    <section id=\"movementCards\" class=\"movement-cards\" aria-label=\"Movement library\"></section>\r\n    <nav id=\"libraryPages\" class=\"library-pages\" aria-label=\"Movement pages\"><button id=\"previousPage\" data-hand>Previous</button><span id=\"pageNumber\">1 / 2</span><button id=\"nextPage\" data-hand>Next</button></nav>\r\n    <section id=\"hologramPanel\" hidden>\r\n      <div class=\"holo-heading\"><button id=\"backLibrary\" data-hand>Back</button><h2 id=\"holoName\">Squat hologram</h2></div>\r\n      <div id=\"holoStage\" role=\"img\" aria-label=\"Interactive exercise hologram. Drag to rotate.\"><p id=\"holoStatus\" role=\"status\">Loading hologram…</p></div>\r\n      <aside class=\"holo-setup\" aria-label=\"Camera setup for this exercise\">\r\n        <div class=\"holo-setup-block\"><h3>Camera</h3><p id=\"holoCameraPosition\" class=\"holo-position\"></p><p id=\"holoCameraPlacement\"></p></div>\r\n        <div class=\"holo-setup-block\"><h3>Keep visible</h3><ul id=\"holoVisibleJoints\" class=\"holo-joints\"></ul><p id=\"holoFrameNote\"></p></div>\r\n        <p class=\"holo-no-feet\">No foot or ankle tracking.</p>\r\n      </aside>\r\n      <div class=\"holo-tools\"><button id=\"holoPlay\" data-hand>Pause animation</button><button id=\"holoReset\" data-hand>Reset view</button></div>\r\n\r\n      <p id=\"introCue\" class=\"intro-cue\" hidden></p>\r\n      <button id=\"useHologram\" data-hand class=\"use-movement\">Begin</button>\r\n    </section>\r\n    <footer class=\"library-footer\">\r\n      <button id=\"startFromLibrary\" data-hand class=\"use-movement\">Start Squats</button>\r\n      <details id=\"gestureArea\"><summary>Gestures</summary><div class=\"hand-row\"><button id=\"toggleHands\" aria-pressed=\"false\">Enable exercise gestures</button><span id=\"handState\" role=\"status\">Touch controls ready</span></div>\r\n      <progress id=\"confirmProgress\" max=\"1\" value=\"0\" aria-label=\"Thumbs-up confirmation\"></progress>\r\n      <details id=\"handHelp\"><summary>Gesture guide</summary><p>Push-ups: raise one arm and point at its upper arm with your other index finger. Squats: hands on hips. Tree: hands together overhead. Warrior: arms out in a T. Horse: hands together at your chest. Boxing: two fists near your shoulders. Jogging: pump your arms alternately four times. Jumping: hands raised apart.</p><p>Hold thumbs up to confirm.</p></details></details>\r\n    </footer>\r\n  </div>\r\n  <div id=\"handCursor\" hidden aria-hidden=\"true\"></div>\r\n</dialog>\r\n<script src=\"/workout-tracks.js\"></script><script src=\"/pod/gala-weapons.js\"></script><script src=\"/pod/gala-avatar.js\"></script><script src=\"/pod/gala-performer.js\"></script><script src=\"/pod/dj-identity.js\"></script>\r\n<script type=\"module\" src=\"/app-runtime.mjs?v=rest-flow-1\"></script>\r\n<script type=\"module\" src=\"/launch-bootstrap.mjs?v=startup-recovery-1\"></script>\r\n<script type=\"module\" src=\"/shader-entry.mjs?v=rest-flow-1\"></script>\r\n</html>\r\n","post-download.mjs":"// D34 post-download package, picked in a Downloads menu. scripts/offline-assets.mjs tags every package\r\n// file with a group; the service worker owns this release's package cache and, for the groups this\r\n// device chose, says what is still missing and how big each group is (PACKAGE_PLAN). This page fetches\r\n// those whole files (Sites has no byte ranges), each checked against its build sha256, so an interrupted\r\n// download resumes file by file, across reloads. The menu is its own full-screen page, shown once after\r\n// the first open and never over the quilt portal (the portal waits, hidden, until it closes); Settings\r\n// and Install reopen it (window.myr5Packs.open). A fresh installed-app launch saves the full public\r\n// package automatically; ordinary web visits keep a deliberate Download action.\r\nimport {ROWS,TRACKS,LEVELS_PER_BOSS} from './battle-pass-rewards.mjs';\r\nimport {RELEASE} from './release-info.mjs';\r\n\r\nconst STATE='myr5-full-download',CHOSEN='myr5-download-groups',SEEN='myr5-downloads-seen',INSTALL_PENDING='myr5-full-package-install-pending',INSTALLED_SEEN='myr5-full-package-installed-app-seen';\r\nconst BUSY=['camera','model','tracking','manual'];\r\nconst mb=bytes=>bytes>0&&bytes<104858?'<0.1 MB':(bytes/1048576).toFixed(bytes<10*1048576?1:0)+' MB';\r\nconst read=(store,key)=>{try{return store.getItem(key);}catch{return null;}};\r\nconst write=(store,key,value)=>{try{value==null?store.removeItem(key):store.setItem(key,value);}catch{}};\r\nconst say=text=>Object.assign(Error(text),{shown:true});\r\n// Group ids come from scripts/offline-assets.mjs; a row shows only when this build has that group.\r\nconst GROUPS=[\r\n // W2-2O (#136): the portal experience's art, offered first (and picked) on the first open.\r\n ['starter','Starter: portal, pyramid, ship and worlds','The offline workout tracker, the quilt portal, the Food pyramid, the starter ship and its worlds, and the achievements art.'],\r\n ['grimoire-ice','Crystal grimoire portal','Crystal board art and its reflective color-matched wormhole.'],\r\n ['grimoire-grass','Grass grimoire portal','Grass and flower art with its dirt, roots and bugs wormhole.'],\r\n ['grimoire-cogs','Cogs grimoire portal','Clockwork board parts, door art and its mechanical wormhole.'],\r\n ['grimoire-jelly','Jelly grimoire portal','Jelly board art and its bumpy color-matched wormhole.'],\r\n ['grimoire-wood','Wood grimoire portal','Wood board art and its ember, bark and charcoal wormhole.'],\r\n ['grimoire-pond','Pond grimoire portal','Pond poster art and its murky water, lily and koi wormhole.'],\r\n ['room-scoreboard','Scoreboard classroom','The 3D classroom wall and desks, with friends at their seats and a whiteboard you can enter.'],\r\n ['room-reminders','Reminders computer','The purple space computer around your reminder controls.'],\r\n ['room-cage','3D customizer cage','Your coach on a pedestal, with pet cages, a weapon wall and a mirror you tap to open each part of the customizer.'],\r\n ['coach','Your coach','The regular coach models, the customizer and exercise demos.'],\r\n ['bodies','Extra coach bodies','More body shapes for the customizer, by workout section. A body you pick also downloads by itself.'],\r\n ['hand','Helping Hand','Your hand companion and all its looks.'],\r\n ['music','Page music','Six looping songs for the pod, grimoire, achievements, customizer, food pyramid and classroom.'],\r\n ['drop-pods','Reward drop pods','The 3D drop pods that land when you open a reward pack.'],\r\n ['voices','Voices','Your coach’s spoken lines.'],\r\n ['food','Food scanner','The food scanner model and the food list.'],\r\n ['meditation','Meditation & backgrounds','Meditation, rest and board backgrounds.'],\r\n ['games','Games & War Room','Arcade games and the War Room.'],\r\n ['vault','Achievement Vault','Vault hall, secret worlds, boards, models and art.'],\r\n];\r\n// Body sections follow the board rows (#102): a section's bodies unlock when every boss in its row\r\n// is beaten. Mirrors track-placements.ts sectionComplete(), which can't be imported here (its catalog\r\n// pulls three.js into the launch bundle).\r\nconst SECTIONS=[{id:'bodies-starter',name:'Starter',row:null},...ROWS.filter(row=>row.track).map(row=>({id:'bodies-'+TRACKS[row.track].catalog,name:TRACKS[row.track].name,row}))];\r\nconst sectionLocked=(row,progress)=>!!row&&!Array.from({length:row.bosses},(_,i)=>progress[`${row.id}-${i+1}`]??0).every(levels=>levels>=LEVELS_PER_BOSS);\r\nconst row=(id,title,text,extra='')=>`<label class=\"download-row\"><input type=\"checkbox\" ${id.startsWith('*')?`data-all=\"${id.slice(1)}\"`:`data-group=\"${id}\"`}><span><strong>${title}</strong>${extra}<small>${text}</small></span><b data-size></b></label>`;\r\n\r\nexport function mountPostDownload({host}){\r\n const worker=navigator.serviceWorker;\r\n if(!worker||!globalThis.caches||!host)return null;\r\n const menu=document.createElement('dialog'),bar=document.createElement('section'),settings=document.createElement('section'),note=document.createElement('p');\r\n menu.id='downloadsMenu';menu.className='downloads-menu';menu.setAttribute('aria-labelledby','downloadsTitle');menu.setAttribute('aria-describedby','downloadsText');\r\nconst status='<p role=\"status\" data-text></p><progress max=\"1\" value=\"0\" aria-label=\"Download progress\"></progress><span data-bytes></span><button type=\"button\" data-toggle></button><button type=\"button\" data-update hidden>Update Coach to continue downloads</button>';\r\n menu.innerHTML='<div class=\"downloads-page\"><h2 id=\"downloadsTitle\">Downloads</h2><p id=\"downloadsText\">Save the complete public content library for offline use in one resumable download. Groups are selected by default; clear any you do not want on this device. You can change this any time in Settings.</p><p class=\"hint\" data-cellular hidden>You’re on mobile data. Wi‑Fi is best for big downloads.</p><p class=\"hint\" data-network hidden>You’re offline. The complete package is selected and will start when you reconnect.</p><p class=\"hint\" data-save-data hidden>Data Saver is on. The complete package is selected; tap Download selected when you want to start.</p><fieldset data-groups><legend>Complete content package</legend></fieldset><section data-packs></section></div>'\r\n  +'<footer class=\"downloads-footer\"><div class=\"downloads-status\">'+status+'</div><p data-total></p><div class=\"actions\"><button type=\"button\" class=\"main-action\" data-download>Download selected</button><button type=\"button\" data-later>Not now</button></div></footer>';\r\n bar.className='full-download-bar';bar.setAttribute('aria-label','MyR5 downloads');bar.hidden=true;\r\n settings.className='full-download-settings';settings.setAttribute('aria-labelledby','fullDownloadSettingsTitle');\r\n bar.innerHTML=status+'<button type=\"button\" data-hide aria-label=\"Hide download status\">Hide</button>';\r\n settings.innerHTML='<h3 id=\"fullDownloadSettingsTitle\">Downloads</h3><button type=\"button\" data-open>Choose downloads</button>'+status;\r\n note.className='body-download-note';note.setAttribute('role','status');note.setAttribute('popover','manual');note.hidden=true;\r\n host.append(settings);document.body.append(menu,bar,note);\r\n const list=menu.querySelector('[data-groups]'),packsHost=menu.querySelector('[data-packs]'),menuStatus=menu.querySelector('.downloads-status');\r\n // Settings reaches the same menu (the pod Settings dialog, when this page has one).\r\n const podSettings=document.getElementById('settings'),entry=document.createElement('div');\r\n if(podSettings){entry.className='settings-fields downloads-entry';entry.innerHTML='<button type=\"button\" data-open>Downloads</button>';const before=podSettings.querySelector('.settings-group,.settings-actions');before?before.before(entry):podSettings.append(entry);}\r\n // Account-bound, signed optional packets live beside (not inside) the anonymous package groups.\r\n // Do not even add their controls to the anonymous page: mount them only after the same-origin\r\n // account bridge publishes a stable owner, and remove them again as soon as that owner clears.\r\n let sectionControls=null,sectionEpoch=0,mountedOwner=null;\r\n const sectionOwner=value=>typeof value?.user?.id==='string'?value.user.id:null;\r\n const clearSections=()=>{++sectionEpoch;sectionControls?.dispose();sectionControls=null;mountedOwner=null;};\r\n const mountSections=async account=>{\r\n  const owner=sectionOwner(account),run=++sectionEpoch;if(!owner)return;mountedOwner=owner;\r\n  try{\r\n   const {mountPostDownloadSections}=await import('./modules/materials/post-download-ui.mjs');\r\n   if(run!==sectionEpoch||sectionOwner(window.myr5AuthenticatedAccount)!==owner)return;\r\n   sectionControls=mountPostDownloadSections({host:packsHost,account:window.myr5AuthenticatedAccount});\r\n   if(!sectionControls)mountedOwner=null;\r\n  }catch(error){if(run===sectionEpoch)mountedOwner=null;console.warn('Extra offline packs unavailable',error);}\r\n };\r\n // The section UI receives account updates itself; polling the same owner must not dispose it.\r\n const sectionsReady=event=>{if(mountedOwner&&sectionOwner(event.detail)===mountedOwner)return;clearSections();void mountSections(event.detail);};\r\n const sectionsCleared=()=>clearSections();\r\n window.addEventListener('myr5:account-ready',sectionsReady);window.addEventListener('myr5:account-cleared',sectionsCleared);\r\n void mountSections(window.myr5AuthenticatedAccount);\r\n // Any part of the app (e.g. the ship scene, when its pack isn't installed yet) can open the menu,\r\n // optionally pointing at one group (a scene without its Starter art: 'starter', picked for them) or one\r\n // signed section's button.\r\n // due(): the first-open Downloads menu is open or about to open, so other first-screen popups wait their turn.\r\n window.myr5Packs=Object.freeze({due:()=>wantMenu||menu.open,open(sectionId){\r\n  openMenu(false);\r\n  const id=typeof sectionId==='string'&&/^[a-z0-9-]+$/.test(sectionId)?sectionId:null,group=id&&list.querySelector(`[data-group=\"${id}\"]`);\r\n  if(group&&!group.disabled){group.checked=true;sync();}\r\n  const target=group||(id&&sectionControls?.panel?.querySelector(`[data-actions] [data-sections~=\"${id}\"]`));\r\n  if(target){target.scrollIntoView({block:'center',behavior:'smooth'});target.focus({preventScroll:true});}\r\n  return !!target;\r\n }});\r\n\r\n let plan=null,phase='checking',message='',got=0,controller=null,wantMenu=false,autoMenu=false,firstPick=false,restorePortal=false,doneTimer=0,progress=null;\r\n const busy=()=>document.body.dataset.cameraWorkout==='true'||document.body.dataset.tracking==='true'||document.body.dataset.screen==='rest'||BUSY.includes(window.myr5TestState?.phase);\r\n const installedApp=()=>navigator.standalone===true||globalThis.matchMedia?.('(display-mode: standalone)').matches===true;\r\n const saveDataRequested=()=>navigator.connection?.saveData===true;\r\n if(installedApp()&&!read(localStorage,INSTALLED_SEEN)){write(localStorage,INSTALL_PENDING,'1');write(localStorage,INSTALLED_SEEN,'1');}\r\n // A ?panel= or #route deep link came for one thing; nothing auto-opens over it (the quilt portal waits the same way).\r\n const deepLinked=()=>new URLSearchParams(location.search).has('panel')||!!window.myr5Routes?.hashRoute?.();\r\n const idle=()=>!busy()&&!document.hidden&&!document.querySelector('dialog[open]');\r\n const cellular=()=>navigator.connection?.type==='cellular'||navigator.connection?.saveData===true;\r\n // null: the whole package (a download chosen before the menu existed, or Everything).\r\n function chosen(){if(read(localStorage,INSTALL_PENDING)==='1')return null;try{const list=JSON.parse(read(localStorage,CHOSEN));if(Array.isArray(list))return list;}catch{}return read(localStorage,STATE)?null:[];}\r\n const boxes=()=>[...list.querySelectorAll('[data-group]')];\r\n function paint(){\r\n  const total=plan?.total||0,left=Math.max(0,(plan?.remaining||0)-got),done=total-left;\r\n  const text=phase==='done'?(total?'Ready offline. Your downloads work without a connection.':'MyR5 works with what’s on this phone. Choose downloads for more offline.'):phase==='downloading'?'Downloading your picks…':phase==='paused'?'Download paused.':phase==='error'||phase==='stale'?message:phase==='checking'?'Checking this device…':`${mb(left)} of your picks still to download.`;\r\n  const toggle=phase==='downloading'?'Pause':phase==='paused'||phase==='error'?'Resume':phase==='ready'?`Download ${mb(left)}`:'';\r\n  for(const box of [bar,settings,menuStatus]){\r\n   const active=['downloading','paused','error','stale'].includes(phase)&&total>0;\r\n   box.querySelector('[data-text]').textContent=text;box.querySelector('progress').value=total?done/total:0;box.querySelector('progress').hidden=!active;\r\n   box.querySelector('[data-bytes]').textContent=active?`${mb(done)} of ${mb(total)}`:'';\r\n   const button=box.querySelector('[data-toggle]');button.hidden=!toggle;button.textContent=toggle;box.querySelector('[data-update]').hidden=phase!=='stale';\r\n  }\r\n  menuStatus.hidden=!['checking','downloading','paused','error','stale'].includes(phase);\r\n  if(menu.open)sync();\r\n }\r\n // The menu: one toggle and size per group; Extra coach bodies splits by workout section.\r\n function renderMenu(){\r\n  const groups=plan?.groups||{},sizes=id=>groups[id];\r\n  const bodies=SECTIONS.filter(section=>sizes(section.id));\r\n  const current=new Map(boxes().map(box=>[box.dataset.group,box.checked])),expanded=menu.open&&!!list.querySelector('details')?.open;\r\n  const rendered=new Set();\r\n  // A re-render keeps keyboard focus on the same row (e.g. the Starter row a scene asked for).\r\n  const focused=list.contains(document.activeElement)&&document.activeElement.dataset,refocus=focused&&(focused.group?`[data-group=\"${focused.group}\"]`:focused.all?`[data-all=\"${focused.all}\"]`:null);\r\n  list.querySelectorAll('.download-row,.download-bodies').forEach(node=>node.remove());\r\n  for(const [id,title,text] of GROUPS){\r\n   if(id==='bodies'){\r\n    if(!bodies.length)continue;\r\n    const wrap=document.createElement('div');wrap.className='download-bodies';\r\n    wrap.innerHTML=row('*bodies',title,text)+'<details><summary>By workout section</summary>'+bodies.map(section=>row(section.id,section.name,section.row?`${sizes(section.id).files} bodies`:`${sizes(section.id).files} bodies, open to everyone`,'<em data-lock hidden>Locked · preview</em>')).join('')+'</details>';\r\n    wrap.querySelector('details').open=expanded;list.append(wrap);for(const section of bodies)rendered.add(section.id);continue;\r\n   }\r\n   if(sizes(id)){list.insertAdjacentHTML('beforeend',row(id,title,text,id==='coach'||id==='starter'?'<em>Recommended</em>':''));rendered.add(id);}\r\n  }\r\n  // New release groups still appear under the full-package toggle even before this copy gains curated labels.\r\n  for(const id of Object.keys(groups))if(!rendered.has(id)){\r\n   const title=id.split('-').map(part=>part.charAt(0).toUpperCase()+part.slice(1)).join(' ');\r\n   list.insertAdjacentHTML('beforeend',row(id,title,'Additional public content included in the complete offline package.'));\r\n   rendered.add(id);\r\n  }\r\n  if(Object.keys(groups).length>1)list.insertAdjacentHTML('afterbegin',row('*everything','Complete public content package','Every public group, including Vault worlds and their assets.','<em>Recommended</em>'));\r\n  // A re-render while the menu is up (a fresher plan) keeps what the user has toggled so far.\r\n  const picked=chosen(),kept=menu.open?current:null;\r\n  for(const box of boxes()){\r\n   const info=sizes(box.dataset.group),label=box.closest('label');label.dataset.saved=String(!info.remaining);\r\n   box.checked=!info.remaining||(kept?.has(box.dataset.group)?kept.get(box.dataset.group):firstPick?true:!picked||picked.includes(box.dataset.group));\r\n   label.querySelector('[data-size]').textContent=!info.remaining?'Saved':info.remaining<info.total?`${mb(info.remaining)} left`:mb(info.total);\r\n  }\r\n  paintLocks();sync();\r\n  if(refocus)list.querySelector(refocus)?.focus({preventScroll:true});\r\n }\r\n function paintLocks(){\r\n  if(progress)for(const section of SECTIONS){const badge=list.querySelector(`[data-group=\"${section.id}\"]`)?.closest('label').querySelector('[data-lock]');if(badge)badge.hidden=!sectionLocked(section.row,progress);}\r\n }\r\n const saved=box=>box.closest('label').dataset.saved==='true',left=box=>plan?.groups?.[box.dataset.group]?.remaining||0;\r\n function sync(){\r\n  const all=boxes(),busyNow=!!controller;\r\n  for(const box of all)box.disabled=busyNow||saved(box);\r\n  for(const [name,members] of [['bodies',all.filter(box=>box.dataset.group.startsWith('bodies-'))],['everything',all]]){\r\n   const parent=list.querySelector(`[data-all=\"${name}\"]`);if(!parent)continue;\r\n   const on=members.filter(box=>box.checked).length,size=members.reduce((sum,box)=>sum+left(box),0);\r\n   parent.checked=on===members.length;parent.indeterminate=on>0&&on<members.length;parent.disabled=busyNow||!size;\r\n   parent.closest('label').querySelector('[data-size]').textContent=size?mb(size):'Saved';\r\n  }\r\n  const selected=all.filter(box=>box.checked&&!saved(box)).reduce((sum,box)=>sum+left(box),0);\r\n  menu.querySelector('[data-total]').textContent=busyNow?'':selected?`Selected: ${mb(selected)}`:'Nothing new selected.';\r\n  const download=menu.querySelector('[data-download]');download.disabled=busyNow||phase==='stale'||!selected||!navigator.onLine;download.hidden=busyNow||phase==='stale';\r\n }\r\n list.addEventListener('change',event=>{\r\n  const all=event.target.dataset.all;\r\n  if(all)for(const box of boxes())if(!box.disabled&&(all==='everything'||box.dataset.group.startsWith('bodies-')))box.checked=event.target.checked;\r\n  sync();\r\n });\r\n const portalUp=()=>!!window.myr5Portal&&!window.myr5Portal.disposed&&document.getElementById('portalHome')?.hidden===false;\r\n function openMenu(auto){\r\n  if(menu.open)return;\r\n  // Shown once: the first open marks it seen (and picks the recommended group); Settings reopens it.\r\n  const installPending=read(localStorage,INSTALL_PENDING)==='1';\r\n  autoMenu=auto;firstPick=auto&&(firstPick||installPending||!read(localStorage,SEEN)&&!chosen()?.length);\r\n  if(installPending)write(localStorage,CHOSEN,null);\r\n  const autoPackage=auto&&firstPick&&(installedApp()||installPending)&&navigator.onLine&&!saveDataRequested();\r\n  menu.returnValue='';if(auto)write(localStorage,SEEN,'1');\r\n  // Its own screen, never a modal over the quilt: the portal steps aside and comes back after.\r\n  restorePortal=portalUp();if(restorePortal)window.myr5Portal.hide();\r\n  menu.querySelector('[data-cellular]').hidden=!cellular();menu.querySelector('[data-network]').hidden=navigator.onLine;menu.querySelector('[data-save-data]').hidden=!saveDataRequested();menu.querySelector('[data-later]').textContent=auto?'Not now':'Close';\r\n  renderMenu();paint();menu.showModal();menu.querySelector('.downloads-page').scrollTop=0;\r\n  menu.querySelector(auto&&!menu.querySelector('[data-download]').disabled?'[data-download]':'[data-later]').focus();\r\n  // A fresh installed-app launch or appinstalled event starts the complete public package online.\r\n  // Browser visitors and Data Saver users keep the selected package but wait for the user's action;\r\n  // signed owner-scoped packs are mounted separately below.\r\n   if(autoPackage)queueMicrotask(()=>{if(menu.open&&!controller)void start();});\r\n  import('./battle-pass.mjs').then(({loadProgress})=>{progress=loadProgress();paintLocks();},()=>{});\r\n  // Sizes change as bodies download on demand; show the worker's current count.\r\n  if(plan&&!controller)ask().then(fresh=>{if(controller)return;plan=fresh;got=0;paint();if(menu.open)renderMenu();},()=>{});\r\n }\r\n menu.querySelector('[data-download]').onclick=()=>{\r\n  const all=boxes(),picked=all.filter(box=>box.checked).map(box=>box.dataset.group);\r\n  write(localStorage,INSTALL_PENDING,null);\r\n  write(localStorage,CHOSEN,picked.length===all.length?null:JSON.stringify(picked));\r\n  menu.close('download');void start();\r\n };\r\n // \"Not now\" (the first-open label) really pauses the auto-started package: the bar keeps Resume. Plain \"Close\" (menu opened from Settings) leaves a running download alone.\r\n menu.querySelector('[data-later]').onclick=()=>{if(autoMenu&&controller)controller.abort();menu.close('later');};\r\n menu.addEventListener('close',()=>{\r\n  if(menu.returnValue==='busy'){wantMenu=autoMenu;restorePortal=false;return;}\r\n  // First open: the quilt waited for this menu (app.mjs skips it while a dialog is open).\r\n  if(restorePortal)window.myr5Portal?.show?.();\r\n  // Not just \"not mounted yet\": the mount can finish (window.myr5Portal set, still hidden) while this\r\n  // menu was open, since shouldShow() only gets one check, at mount time, and this menu wasn't open\r\n  // yet then. Always route through the shared opener; it no-ops fast when already mounted (#risk 1).\r\n  else if(autoMenu&&window.coachPlan&&!deepLinked())void window.myr5Menus?.portal?.({shouldShow:idle});\r\n  restorePortal=false;autoMenu=false;\r\n });\r\n for(const button of [settings,entry].map(node=>node.querySelector('[data-open]')).filter(Boolean))button.onclick=()=>openMenu(false);\r\n\r\n function ask(adopt=false){\r\n  return new Promise((resolve,reject)=>{\r\n   const channel=new MessageChannel(),timer=setTimeout(()=>reject(say('Coach is busy. Try again.')),60000);\r\n   channel.port1.onmessage=({data})=>{clearTimeout(timer);data?.error?reject(say('Could not check the download. Try again.')):resolve(data);};\r\n   if(!worker.controller){clearTimeout(timer);reject(say('Reload MyR5 to continue the download.'));return;}\r\n   worker.controller.postMessage({type:'PACKAGE_PLAN',adopt,groups:chosen()??undefined},[channel.port2]);\r\n  });\r\n }\r\n async function save(asset,signal){\r\n  const cache=await caches.open(asset.cache||plan.cache);\r\n  for(let attempt=1;;attempt++){\r\n   let responseAccepted=false;\r\n   try{\r\n    // HTML may be rewritten in transit by edge security products; the worker allows that too.\r\n    const response=await fetch(asset.url,{cache:'no-cache',headers:{'x-myr5-package':'1'},signal,...(asset.url.endsWith('.html')?{}:{integrity:asset.integrity})});\r\n    if(!response.ok)throw Error('HTTP '+response.status);\r\n    responseAccepted=true;\r\n    await cache.put(asset.key||asset.url,response);return;\r\n   }catch(error){\r\n    if(signal.aborted||error.name==='QuotaExceededError')throw error;\r\n    if(attempt===3){\r\n     if(!responseAccepted&&await newerReleaseAvailable(signal)&&!signal.aborted)throw Object.assign(Error('A newer Coach release is live. Update Coach to continue downloads; saved files and choices are kept.'),{code:'stale_release'});\r\n     throw error;\r\n    }\r\n    await new Promise(resolve=>setTimeout(resolve,1500*attempt));\r\n   }\r\n  }\r\n }\r\n async function newerReleaseAvailable(signal){\r\n  if(signal.aborted)return false;\r\n  const probe=new AbortController(),abort=()=>probe.abort();\r\n  const timer=setTimeout(abort,5000);\r\n  if(signal.aborted)abort();else signal.addEventListener('abort',abort,{once:true});\r\n  try{\r\n   const response=await fetch('/api/releases/current',{cache:'no-store',credentials:'omit',signal:probe.signal});\r\n   if(signal.aborted||probe.signal.aborted)return false;\r\n   if(!response.ok)return false;\r\n   const current=await response.json();\r\n   if(signal.aborted||probe.signal.aborted)return false;\r\n   return typeof current?.id==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(current.id)&&current.id!==RELEASE.id;\r\n  }catch{return false;}finally{clearTimeout(timer);signal.removeEventListener('abort',abort);}\r\n }\r\n async function start(){\r\n  if(controller)return;\r\n  controller=new AbortController();const {signal}=controller;\r\n  write(localStorage,STATE,'on');phase='downloading';message='';bar.hidden=false;paint();\r\n  navigator.storage?.persist?.().catch(()=>{});\r\n  try{\r\n   // Pass 1 saves the picked groups and the voice manifest; pass 2 the voice clips that manifest names.\r\n   for(let pass=0;;pass++){\r\n    plan=await ask(true);got=0;paint();\r\n    if(!plan.missing.length)break;\r\n    if(pass===3)throw say('Download stopped. It continues where it left off.');\r\n    const {quota=0,usage=0}=await navigator.storage?.estimate?.().catch(()=>({}))||{};\r\n    if(quota&&quota-usage<plan.remaining)throw say(`Not enough free space. MyR5 needs ${mb(plan.remaining)}.`);\r\n    for(const asset of plan.missing){await save(asset,signal);got+=asset.bytes;paint();}\r\n   }\r\n   phase='done';write(localStorage,INSTALL_PENDING,null);bar.hidden=false;clearTimeout(doneTimer);doneTimer=0;\r\n  }catch(error){\r\n   if(signal.aborted){phase='paused';write(localStorage,STATE,'paused');}\r\n   else if(error.code==='stale_release'){phase='stale';message=error.message;}\r\n   else{phase='error';message=error.shown?error.message:error.name==='QuotaExceededError'?'Not enough free space. Free some up, then resume.':'Download stopped. Check your connection; it continues where it left off.';}\r\n  // Keep saved bytes against this plan until the next worker plan replaces both plan and got.\r\n  }finally{controller=null;paint();if(menu.open)renderMenu();else if(phase==='error'&&idle())openMenu(false);}\r\n }\r\n for(const box of [bar,settings,menuStatus])box.querySelector('[data-toggle]').onclick=()=>controller?controller.abort():void start();\r\n for(const box of [bar,settings,menuStatus])box.querySelector('[data-update]').onclick=()=>{\r\n  // Recovery is a user action: stop the old release's request, leave its verified cache alone,\r\n  // and let the normal recovery page coordinate activation with any active workout clients.\r\n  controller?.abort();\r\n  if(menu.open)menu.close('stale-update');\r\n  window.open('/repair-coach','_blank','noopener,noreferrer');\r\n };\r\n bar.querySelector('[data-hide]').onclick=()=>{bar.hidden=true;};\r\n // A roster body, or a portal scene's Starter art, that isn't on this phone downloads by itself when it's\r\n // needed (sw.js). The note is a popover so it also shows over a scene's dialog; never over a workout.\r\n // Offline, a scene without its Starter art shows its own placeholder, so only a body says it's missing.\r\n const pending=new Map();let noteTimer=0;\r\n const showNote=text=>{note.textContent=text;note.hidden=!text||busy();try{note.hidden?note.hidePopover():note.showPopover();}catch{}};\r\n worker.addEventListener?.('message',({data})=>{\r\n  const starter=data?.type==='STARTER_DOWNLOAD';\r\n  if(data?.type!=='BODY_DOWNLOAD'&&!starter)return;\r\n  clearTimeout(noteTimer);\r\n  if(data.state==='start')pending.set(data.url,starter);else pending.delete(data.url);\r\n  const missing=data.state==='unavailable'&&!starter;\r\n  showNote(missing?'This body isn’t on this phone yet. Connect to the internet to download it.':!pending.size?'':[...pending.values()].every(Boolean)?'Downloading…':'Downloading this body…');\r\n  if(missing)noteTimer=setTimeout(()=>showNote(''),6000);\r\n });\r\n // Nothing appears over a workout or camera-only mode; the menu waits until the app is idle.\r\n const ticker=setInterval(()=>{\r\n  if(menu.open&&busy())menu.close('busy');\r\n   if(note.textContent)showNote(note.textContent);\r\n  if(wantMenu&&!deepLinked()&&idle()){wantMenu=false;openMenu(true);}\r\n  if(phase==='done'&&!bar.hidden&&!doneTimer&&idle())doneTimer=setTimeout(()=>{bar.hidden=true;},6000);\r\n },1000);\r\n window.addEventListener('online',()=>{if(read(localStorage,STATE)==='on'&&['ready','error'].includes(phase)&&!saveDataRequested())void start();});\r\n window.addEventListener('online',()=>{\r\n  if(menu.open){menu.querySelector('[data-network]').hidden=true;sync();}\r\n  if(read(localStorage,INSTALL_PENDING)==='1'){\r\n   write(localStorage,CHOSEN,null);\r\n   if(menu.open&&!saveDataRequested()){firstPick=true;renderMenu();void start();}\r\n   else if(!menu.open)wantMenu=true;\r\n  }\r\n });\r\n window.addEventListener('offline',()=>{if(menu.open){menu.querySelector('[data-network]').hidden=false;sync();}});\r\n const installedEvent=()=>{write(localStorage,INSTALL_PENDING,'1');write(localStorage,SEEN,null);wantMenu=true;if(menu.open){firstPick=true;write(localStorage,CHOSEN,null);renderMenu();if(navigator.onLine&&!saveDataRequested())void start();}};\r\n window.addEventListener('appinstalled',installedEvent);\r\n window.addEventListener('pagehide',event=>{if(!event.persisted){clearInterval(ticker);window.removeEventListener('myr5:account-ready',sectionsReady);window.removeEventListener('myr5:account-cleared',sectionsCleared);window.removeEventListener('appinstalled',installedEvent);clearSections();}});\r\n (async()=>{\r\n  // A first visit is controlled once the core install activates; its menu can open then.\r\n  if(!worker.controller)await new Promise(resolve=>worker.addEventListener?.('controllerchange',resolve,{once:true}));\r\n  if(read(localStorage,INSTALL_PENDING)==='1')write(localStorage,CHOSEN,null);\r\n  try{plan=await ask();}catch(error){phase='error';message=error.message;paint();return;}\r\n  phase=plan.remaining?'ready':'done';paint();if(menu.open)renderMenu();\r\n  const state=read(localStorage,STATE);\r\n  if(state)write(localStorage,SEEN,'1');\r\n  // Resume an already-started package after a reload, or fetch an update's changed files.\r\n  if(plan.remaining&&state==='on'&&navigator.onLine&&!saveDataRequested())return void start();\r\n  if(plan.remaining&&state==='paused'){phase='paused';bar.hidden=false;paint();return;}\r\n  // A deep link (?panel=) came for one thing; like the quilt, the menu waits for a plain open.\r\n  if(!plan.remaining)write(localStorage,INSTALL_PENDING,null);\r\n  if((!read(localStorage,SEEN)||read(localStorage,INSTALL_PENDING)==='1')&&!deepLinked()&&Object.values(plan.groups||{}).some(group=>group.remaining))wantMenu=true;\r\n })();\r\n}\r\n","privacy.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>MYR5 Coach privacy</title><link rel=\"icon\" href=\"/icons/myr5-alien-192.png\"><link rel=\"stylesheet\" href=\"/signin.css\"><style>main{width:min(100% - 40px,740px)}h2{margin-top:32px;font-size:22px}a{color:#dfb7ff}li{margin:8px 0;line-height:1.5}</style></head><body><main><a class=\"brand\" href=\"/install\"><img src=\"/icons/myr5-alien-192.png\" alt=\"MYR5\"><span>MYR5</span></a><h1>MYR5 Coach privacy</h1><p>Updated October 6, 2026. This page describes the MYR5 Coach web app at myr5.mominc.online, operated by MYR5 (independent app). MOM Inc. is a fictional character from <a href=\"https://mominc.online\">mominc.online</a>, not the operator.</p><h2>Age</h2>\r\n<p>MYR5 Coach is intended for people aged 13 and over. It is not directed to children under 13, and we do not knowingly collect personal information from them. If you believe a child under 13 has an account, contact us below and we will delete it.</p>\r\n<h2>Signing in</h2><p>Clerk handles sign-in, email verification codes and login sessions. If you choose Google, the requested information is your basic profile, email address and account identity. This Coach login does not request access to your Gmail messages, Drive files or YouTube account. Coach uses a verified account identifier to keep your saved records separate from other users.</p><p>If you choose to connect an existing Coach to a new login, the app records the connection after you sign in to both accounts.</p><h2>What Coach saves</h2><p>Information you submit may include your goal, session length, movement limits, optional setup answers, character appearance, workout records, meals and nutrition entries, and reminder preferences. These records are stored online so they can be restored on another device. If you enable notifications, the app also stores the device's push subscription and your schedule and time zone.</p><p>Local coaching and its workout history can stay on this device. Signing in does not automatically upload guest workout history. When account import is enabled, importing that history requires an explicit choice; the original device history remains local. Imported history does not earn competitive ranking or workout rewards.</p><h2>Gala run records</h2><p>A ranked run saves its start time, completed game milestones, chosen DJ name and three-character moniker, and app-receipt status. A temporary installation cookie carries your private run invitation for up to seven days. Your DJ name and completion time appear on the shared Gala board only after you choose Join the rankings. Run records are separate from your Coach account; contact MYR5 below to remove a published run. A hashed network identifier limits repeated run creation.</p><h2>Your training crew</h2><p>Connecting with an invite code shares your name, saved Gala character appearance and best completed set for each exercise with that friend. Each account can connect two friends. This does not share email addresses, meals, goals, setup answers or camera images. Invite codes work once and expire after seven days; you can cancel an unused invite. Either person can remove a connection to stop future access. Deleting Coach data removes your crew connections and invites.</p><h2>Your camera and photos</h2><p>All camera and pose processing stays on your phone; nothing from the camera is uploaded. Workout camera analysis and food-photo recognition run in your browser. The Coach app does not upload the camera video or selected food photo to its account database. Workout results and the meal details you confirm are saved when you submit them. Recognition software and models are downloaded from external hosting services, which receive ordinary network request information.</p><h2>Storage and service providers</h2><p>Coach uses browser storage and cookies for sign-in, settings, offline files and setup transfers. Its online app and data storage use OpenAI Sites and Cloudflare. Clerk and its email providers deliver authentication; Google handles Google sign-in. Device push services deliver notifications when enabled. These services receive information needed to provide their functions and may process technical and security logs.</p><p>A temporary installation transfer expires after one hour. Your saved Coach account, appearance and workout history are separate from that temporary transfer and remain available until you clear the saved data.</p><h2>Your choices</h2><p>In Coach's account settings, use <strong>Download my data</strong> to export your saved records or <strong>Delete Coach data</strong> to remove the app's saved Coach records and reminders. Clearing Coach data does not delete your Google, ChatGPT or Clerk login account; the login connection can remain. You can turn off notifications and camera access in your device or browser settings. Clearing browser storage removes local copies.</p><p>Account deletion and device-local deletion are separate. Deleting online Coach data leaves your local guest workout history on this device. Coach retains a minimal account identifier, data-generation number and deletion receipts to prevent delayed requests from restoring deleted data. Reminder-service deletion can remain pending while that service is unavailable; already-dispatched notifications or email cannot be recalled. After deletion is confirmed, you can make a new explicit import choice when importing is enabled. Retrying an older deletion does not erase newer account data.</p><p>For privacy questions or help removing a login account and associated connection records, contact <a href=\"mailto:ianmyersrocks97@gmail.com\">ianmyersrocks97@gmail.com</a>.</p><h2>Provider information</h2><p><a href=\"https://clerk.com/legal/privacy\">Clerk privacy policy</a> · <a href=\"https://policies.google.com/privacy\">Google privacy policy</a> · <a href=\"https://openai.com/policies/privacy-policy/\">OpenAI privacy policy</a> · <a href=\"https://www.cloudflare.com/privacypolicy/\">Cloudflare privacy policy</a></p><a class=\"back\" href=\"/install\">Back to Coach</a></main></body></html>\r\n","progression-guide.mjs":"﻿// User-facing rules come from the same constants as workout progression.\r\nimport {HOLD_RECOVERY_SECONDS,WORKOUT_REST_SECONDS,PREPARATION_REPS,SECOND_PREPARATION_TEMPO_SECONDS,SPRINT_ROUNDS,SPRINT_SECONDS,SPRINT_REST_SECONDS,COSMETIC_LEVEL_COUNT,DAILY_TRIO_BONUS} from './progression-rules.mjs';\r\nexport const GUIDE=[\r\n ['train','Train','BUILD YOUR PERFORMANCE. EARN YOUR COACH.',[\r\n  ['Holds',`Active holding earns XP in completed 15-second blocks. Pause or break the pose to recover for ${HOLD_RECOVERY_SECONDS} seconds. Rest earns no exercise XP. A break resets the uninterrupted attempt; earned XP stays. Hold 5 uninterrupted minutes to unlock the coach at that difficulty, and 10 uninterrupted minutes for gold. Change difficulty to start a new uninterrupted attempt.`],\r\n  ['Working sets',`Follow the easy ${PREPARATION_REPS}-rep preparation set, rest ${WORKOUT_REST_SECONDS} seconds, then do ${PREPARATION_REPS} harder preparation reps at ${SECOND_PREPARATION_TEMPO_SECONDS} seconds per full rep. Rest ${WORKOUT_REST_SECONDS} seconds before the working set. Only the working set earns XP and appears in history. Aim for a controlled challenging set; finish when you need to stop. 8 and 12 reps unlock weapon milestones; 15 reps unlock the coach. XP stops after 30 reps.`],\r\n  ['Recovery','One rep working set per muscle group per day. Holds and reps may train the same group on the same day. After two consecutive days training a muscle group, take a day off that group while its boss recovers.'],\r\n  ['Cardio',`Warm up before sprinting. Complete ${SPRINT_ROUNDS} rounds of ${SPRINT_SECONDS}-second sprints and ${SPRINT_REST_SECONDS}-second rests. Gentle cardio earns slower XP. Five sprint rounds or five active minutes of gentle cardio unlock the matching difficulty’s cardio coach.`],\r\n  ['Choose your level','Exercises show Easy, Medium, Hard or Expert. You can select any level; rewards reflect what you perform. Inspect Achievements for each real coach, weapon family and ship requirement.']]],\r\n ['weapons','Weapons','TEN GROUPS. TWENTY WEAPONS.',[\r\n  ['Difficulty blocks','Every weapon has 20 earned tiers: Easy 1–5, Medium 6–10, Hard 11–15 and Expert 16–20. Higher difficulty performance can jump directly into its block.'],\r\n  ['Holds','Hold 1 uninterrupted minute for the first tier in the block, 3 minutes for the second and 5 minutes for a coach clear. Repeat a 5-minute clear to add another tier. A 10-minute uninterrupted hold completes that block and earns the golden coach.'],\r\n  ['Reps','Complete 8 reps for the first tier in the difficulty block, 12 for the second and 15 for a coach clear. Repeat the working-set clear on another eligible day to add a tier.'],\r\n  ['Ships','Complete Expert performance in the ship’s specified group and exercise type: 5 uninterrupted hold minutes or 15 working reps. Exact requirements appear under Achievements → Ships.']]],\r\n ['rewards','XP & packs','250 COSMETIC LEVELS.',[\r\n  ['Cosmetic progression',`Workout XP advances ${COSMETIC_LEVEL_COUNT} levels of packs, colors, palettes, textures and finishes. Exercise performance unlocks coaches, weapons and ships. Each earned coach adds 25% to workout XP; those bonuses add together.`],\r\n  ['Meditation',`Complete meditation to double all workout XP earned that local day, including XP earned before the meditation session. Workout + meditation + food grants a separate ${DAILY_TRIO_BONUS} XP once that day. The ${DAILY_TRIO_BONUS} XP bonus is not doubled.`],\r\n  ['Rest victories','Defeat the first boss during rest timers each local day to earn one uncommon pack. Defeat five that day to earn one legendary pack as well. Each reward is granted once per day. Rest defeats do not unlock coaches.'],\r\n  ['Coach characters','Every coach unlocks its matching 64-bit character at the same time. Customize its colors in the War Room mirror. Coach characters do not wear clothing.']]],\r\n ['combat','Damage','YOUR STREAK IS YOUR POWER.',[\r\n  ['Every hit','10 × consecutive login days × weapon damage level. Starter damage level is 1; earned weapon tiers reach 20, giving damage level 21.'],\r\n  ['Daily damage boost','Finish the full breathing session for ×100 damage that combat day. Five login days with damage level 3 gives 150 damage, or 15,000 with breathing. Combat streaks and this damage boost use UTC days. Cosmetic daily XP uses local days.'],\r\n  ['Specials','Earn specials at tiers 4, 8, 12, 16 and 20. One shared cooldown prevents switching weapons to skip the wait. Team strikes change the animation; the damage formula stays the same.']]],\r\n ['breathing','Meditation','THREE MINUTES. DAILY XP DOUBLED.',[\r\n  ['Start in the still room','Open Meditation and start the three-minute session. Follow a comfortable breathing pace.'],\r\n  ['Finish the session','Paused time, closed rooms and hidden tabs do not count. Completion doubles today’s workout XP once; repeating meditation does not stack the multiplier. Meditation coaches unlock after 3, 6, 9 and 12 separate completed days.']]],\r\n ['rooms','Side rooms','OFF DUTY. STILL IN THE POD.',[\r\n  ['Rest arena','After the timer reaches zero, three seconds without a tap ends rest. Keep tapping to stay. Rest attacks earn no workout XP, but the first and fifth boss defeats of the day earn cosmetic packs.'],\r\n  ['Helping Hand','Customize your hand from your avatar. Every third hand-assisted hit triggers a team strike.'],\r\n  ['Meditation arcade','Keep tapping the meditating character to discover Tub Flight. Its minigame rewards do not replace a meditation session.'],\r\n  ['Gala & War Room','Your verified account keeps performance ownership in sync. War Room access still requires the completed Gala run and app installation.']]],\r\n ['reminders','Reminders','MOM WILL FOLLOW UP.',[\r\n  ['Choose the pressure','Set one, two or three messages per day. Missed scheduled training days make the next message firmer. Gentle tone, pause, frequency and quiet hours remain under your control.'],\r\n  ['Connect this device','Allow notifications on each device. On iPhone, add Coach to your home screen first. The live sender works while Coach is closed; local previews do not send notifications.'],\r\n  ['App updates','Updates download while connected and install when the app is idle. Older installs may need Update now once. A What’s new notice appears after releases.']]]\r\n];\r\n","progression-rules.mjs":"// Confirmed workout philosophy. Shared pure rules for client, local history and server.\r\n// Counts are active exercise time/repetitions, never rest or camera wall-clock time.\r\nexport const PROGRESSION_VERSION=2;\r\n// Every XP number below is the original (x1) design value times XP_SCALE. Level NUMBERS are unchanged:\r\n// unlocks key on level, seconds, reps and rounds, never on absolute XP.\r\nexport const XP_SCALE=10;\r\n// Arcade bonus XP may add at most this share of a session's exercise base XP (before multipliers).\r\nexport const BONUS_XP_SHARE=0.1;\r\n// The one bonus clamp, shared by the client (finish) and the server (importedPerformanceXp).\r\n// Absent, garbage or negative -> 0; anything else is floored and capped at the share of the base.\r\nexport function clampBonusXp(raw,base){const n=typeof raw==='number'&&Number.isFinite(raw)&&raw>0?Math.floor(raw):0;return Math.min(n,Math.floor(Math.max(0,Number(base)||0)*BONUS_XP_SHARE));}\r\nexport const DIFFICULTIES=Object.freeze(['easy','medium','hard','expert']);\r\nconst scaled=rows=>Object.freeze(rows.map(r=>Object.freeze(r.map(n=>n*XP_SCALE))));\r\nexport const HOLD_XP_PER_MINUTE=scaled([[4,8,16],[8,12,20],[12,16,24],[16,20,28]]);\r\nexport const REP_XP=scaled([[1,2,4],[2,3,5],[3,4,6],[4,5,7]]);\r\nexport const HOLD_BLOCK_SECONDS=15,HOLD_TARGET_SECONDS=600,HOLD_CAP_SECONDS=1800;\r\nexport const HOLD_RECOVERY_SECONDS=15,WORKOUT_REST_SECONDS=30;\r\nexport const GOLD_HOLD_SECONDS=600,REP_CAP=30;\r\nexport const PREPARATION_REPS=3,SECOND_PREPARATION_TEMPO_SECONDS=5;\r\nexport const SPRINT_ROUNDS=5,SPRINT_SECONDS=15,SPRINT_REST_SECONDS=45;\r\nexport const MAX_CONSECUTIVE_TRAINING_DAYS=2;\r\nexport const PACK_SIZES=Object.freeze({uncommon:1,rare:2,legendary:3,secret:3});\r\nexport const COSMETIC_PACK_ODDS=Object.freeze({\r\n uncommon:Object.freeze({color:90,'64-bit':7,texture:3}),\r\n rare:Object.freeze({color:80,'64-bit':15,texture:5}),\r\n legendary:Object.freeze({color:70,'64-bit':20,texture:10}),\r\n // Secret packs come only from secret achievements: legendary's size and 64-bit chance, double its texture chance (10 -> 20).\r\n secret:Object.freeze({color:60,'64-bit':20,texture:20}),\r\n});\r\nexport const DAILY_MEDITATION_MULTIPLIER=2,DAILY_TRIO_BONUS=500*XP_SCALE;\r\nexport const BENCHMARK=Object.freeze({sessions:120,activeMinutes:30,expertXpPerMinute:28*XP_SCALE,meditationMultiplier:DAILY_MEDITATION_MULTIPLIER,trioBonus:DAILY_TRIO_BONUS});\r\nexport const COSMETIC_XP_TARGET=BENCHMARK.sessions*(BENCHMARK.activeMinutes*BENCHMARK.expertXpPerMinute*BENCHMARK.meditationMultiplier+BENCHMARK.trioBonus);\r\nexport const SPRINT_ROUND_XP=BENCHMARK.expertXpPerMinute*SPRINT_SECONDS/60,GENTLE_BLOCK_XP=XP_SCALE;\r\nexport const COSMETIC_LEVEL_COUNT=250;\r\nconst transitions=COSMETIC_LEVEL_COUNT-1,firstCost=40,baseTarget=COSMETIC_XP_TARGET/XP_SCALE;\r\n// Increasing per-level costs, exact 261,600 XP endpoint with meditation and all-three\r\n// completion on each benchmark training day. Additive coach bonuses\r\n// deliberately accelerate this conservative benchmark; achievements never require XP.\r\n// Built at the original scale then multiplied, so every threshold is exactly XP_SCALE x the old one.\r\nexport const COSMETIC_LEVEL_XP=Object.freeze(Array.from({length:COSMETIC_LEVEL_COUNT},(_,n)=>\r\n XP_SCALE*(firstCost*n+Math.floor((baseTarget-firstCost*transitions)*n*(n-1)/(transitions*(transitions-1))))\r\n));\r\n\r\nfunction nonnegative(value,name){if(!Number.isFinite(value)||value<0)throw RangeError(`Invalid ${name}.`);return value;}\r\nfunction difficultyIndex(value){\r\n const index=typeof value==='string'?DIFFICULTIES.indexOf(value):value;\r\n if(!Number.isInteger(index)||index<0||index>=DIFFICULTIES.length)throw RangeError('Invalid difficulty.');\r\n return index;\r\n}\r\nexport function coachXpMultiplier(unlockedCoaches=0){\r\n if(!Number.isSafeInteger(unlockedCoaches)||unlockedCoaches<0)throw RangeError('Invalid unlocked coach count.');\r\n return 1+unlockedCoaches*.25;\r\n}\r\nexport function holdRate(difficulty,activeSeconds){\r\n nonnegative(activeSeconds,'active time');\r\n return HOLD_XP_PER_MINUTE[difficultyIndex(difficulty)][activeSeconds<60?0:activeSeconds<180?1:2];\r\n}\r\nexport function extendedHoldMultiplier(continuousSeconds){\r\n nonnegative(continuousSeconds,'continuous time');\r\n return continuousSeconds>=1200?2:continuousSeconds>=900?1.5:continuousSeconds>=600?1.25:1;\r\n}\r\n/** Completed blocks only. `from` is already credited active time: no rounding on\r\n * pause/restart. The owner carries unfinished blocks across breaks in the session.\r\n * Continuous time is a separate attempt clock, supplied by the session controller. */\r\nexport function holdXp({difficulty,from=0,to,continuousAtFrom=0,unlockedCoaches=0}={}){\r\n nonnegative(from,'credited active time');nonnegative(to,'active time');nonnegative(continuousAtFrom,'continuous time');\r\n const index=difficultyIndex(difficulty),multiplier=coachXpMultiplier(unlockedCoaches);\r\n const end=Math.min(HOLD_CAP_SECONDS,to),start=Math.min(HOLD_CAP_SECONDS,from);\r\n if(end<start)throw RangeError('Active time cannot move backwards.');\r\n let xp=0;\r\n for(let block=Math.floor(start/HOLD_BLOCK_SECONDS);block<Math.floor(end/HOLD_BLOCK_SECONDS);block++){\r\n  const activeStart=block*HOLD_BLOCK_SECONDS;\r\n  // The block began before `from` when a controller samples a partial block.\r\n  const continuousStart=Math.max(0,continuousAtFrom+activeStart-from);\r\n  xp+=holdRate(index,activeStart)/4*extendedHoldMultiplier(continuousStart)*multiplier;\r\n }\r\n return xp;\r\n}\r\nexport function repRate(difficulty,rep){\r\n if(!Number.isInteger(rep)||rep<1)throw RangeError('Invalid repetition.');\r\n const rates=REP_XP[difficultyIndex(difficulty)];\r\n if(rep>REP_CAP)return 0;\r\n const base=rates[rep<8?0:rep<12?1:2];\r\n return base*(rep>25?2:rep>20?1.5:rep>15?1.25:1);\r\n}\r\nexport function repXp({difficulty,from=0,to,unlockedCoaches=0,preparation=false}={}){\r\n difficultyIndex(difficulty);\r\n if(!Number.isSafeInteger(from)||!Number.isSafeInteger(to)||from<0||to<from)throw RangeError('Invalid repetition range.');\r\n const multiplier=coachXpMultiplier(unlockedCoaches);if(preparation)return 0;\r\n let xp=0;for(let rep=from+1;rep<=Math.min(REP_CAP,to);rep++)xp+=repRate(difficulty,rep)*multiplier;\r\n return xp;\r\n}\r\nexport function performanceMilestones(kind,value){\r\n nonnegative(value,'performance');\r\n if(kind==='hold')return {weapon1:value>=60,weapon2:value>=180,coach:value>=300,golden:value>=GOLD_HOLD_SECONDS,special:value>=GOLD_HOLD_SECONDS};\r\n if(kind==='reps')return {weapon1:value>=8,weapon2:value>=12,coach:value>=15,golden:false,special:false};\r\n throw RangeError('Unknown performance kind.');\r\n}\r\nexport function performanceWeaponTier(difficulty,repeatedCompletions=0){\r\n const index=difficultyIndex(difficulty);\r\n if(!Number.isSafeInteger(repeatedCompletions)||repeatedCompletions<0)throw RangeError('Invalid repeat count.');\r\n return Math.min(20,index*5+Math.min(5,repeatedCompletions));\r\n}\r\nexport function cosmeticLevel(xp){\r\n nonnegative(xp,'XP');let index=0;\r\n while(index<COSMETIC_LEVEL_XP.length-1&&xp>=COSMETIC_LEVEL_XP[index+1])index++;\r\n const max=index===COSMETIC_LEVEL_XP.length-1;\r\n return {level:index+1,xp,floor:COSMETIC_LEVEL_XP[index],next:max?null:COSMETIC_LEVEL_XP[index+1],\r\n  into:max?0:xp-COSMETIC_LEVEL_XP[index],need:max?0:COSMETIC_LEVEL_XP[index+1]-COSMETIC_LEVEL_XP[index],max};\r\n}\r\n","public-access.mjs":"// Public shell download policy. Anyone with the installed app can enter every\r\n// optional room (Ian, v61 correction: no second Coach Army gate); optional\r\n// editor/pocket assets are only kept out of the first install precache.\r\nexport const OPTIONAL_PRECACHE_PREFIXES = Object.freeze(['/handborne/','/war-room','/warroom','/character-editor/','/editor/','/pocket-hardware.css','/hardware-launch.css','/pod/hardware.css','/pod/hardware.mjs','/pod/whiteboard.css']);\r\n// Still read by the War Room lane (war-room/war-room.mjs); nothing outside it gates on this.\r\nexport function coachArmyComplete(account){\r\n const entitlement=account?.entitlements?.coachArmy;\r\n return entitlement?.status==='completed'&&Number.isSafeInteger(entitlement.completedAt)&&entitlement.completedAt>0;\r\n}\r\nexport function filterInitialPrecache(files){return files.filter(file=>!OPTIONAL_PRECACHE_PREFIXES.some(prefix=>file===prefix||file.startsWith(prefix)));}\r\n","public-entry.mjs":"// Deferred bootstrap for optional editor documents. Open to guests and every\r\n// account (no Coach Army gate); account-owned saves still go through the APIs.\r\n(function () {\r\n  // Vite's dev client can evaluate an external script after currentScript has\r\n  // cleared; the tag remains the unambiguous contract for this document.\r\n  const script = document.currentScript || document.querySelector('script[data-entry][data-module]');\r\n  if (!script?.dataset.entry || !script.dataset.module) return;\r\n  // Keep this file usable as a classic external script; Vite otherwise\r\n  // rewrites import() into module syntax before the browser executes it.\r\n  (new Function('path', 'return import(path)'))(script.dataset.module);\r\n})();\r\n","push-subscribe.mjs":"// Shared by every pushManager subscribe caller (launch.mjs, armie-letters-client.mjs).\r\n// R7-VAPID-ROTATE: release 7 moves reminders to a Cloudflare Worker with a NEW VAPID\r\n// keypair; the old one can't be read back. A subscription made under the old key\r\n// looks \"existing\" to the browser, so callers used to just reuse it -- and every push\r\n// to that phone then failed silently. Compare the subscribed key's bytes to the\r\n// server's current public key and resubscribe when they differ.\r\nexport const fromBase64 = text => Uint8Array.from(atob(text.replace(/-/g, '+').replace(/_/g, '/').padEnd(Math.ceil(text.length / 4) * 4, '=')), c => c.charCodeAt(0));\r\n\r\nfunction sameKey(existingKey, key) {\r\n if (!existingKey) return false;\r\n const x = new Uint8Array(existingKey);\r\n return x.length === key.length && x.every((v, i) => v === key[i]);\r\n}\r\n\r\n// True when this device's subscription was made under a different VAPID key (before the Cloudflare\r\n// move), so pushes to it fail. An unknown key (browser doesn't expose it) is not treated as stale.\r\nexport const staleSubscription = (subscription, publicKeyBase64) => {\r\n const existingKey = subscription?.options?.applicationServerKey;\r\n return !!existingKey && !!publicKeyBase64 && !sameKey(existingKey, fromBase64(publicKeyBase64));\r\n};\r\n\r\n// Returns {subscription, fresh}. fresh is true when a new browser subscription was\r\n// just created (no prior subscription, or the prior one was for a stale key and got\r\n// unsubscribed) -- callers use it to decide whether to roll back on a failed server\r\n// registration, same as the old `!existing` check.\r\nexport async function subscribePush(registration, publicKeyBase64) {\r\n const key = fromBase64(publicKeyBase64);\r\n const existing = await registration.pushManager.getSubscription();\r\n if (existing) {\r\n  if (sameKey(existing.options?.applicationServerKey, key)) return {subscription: existing, fresh: false};\r\n  await existing.unsubscribe();\r\n }\r\n const subscription = await registration.pushManager.subscribe({userVisibleOnly: true, applicationServerKey: key});\r\n return {subscription, fresh: true};\r\n}\r\n","quick-setup-form.mjs":"import {FIELDS,missingFields} from './onboarding-domain.mjs?v=quick-install-v1';\r\nimport {withQuickDefaults} from './quick-setup.mjs';\r\nconst node=(tag,text)=>{const el=document.createElement(tag);if(text)el.textContent=text;return el;};\r\nexport function mountQuickSetup(host,initial,{save,label='Start my coach',changed=()=>{}}){\r\n const data=withQuickDefaults(initial),form=node('form');form.className='setup-form quick-setup';\r\n const controls={};\r\n for(const key of ['goal','sessionMinutes','limits']){\r\n  const field=FIELDS.find(f=>f.key===key),label=node('label',key==='goal'?'Goal':key==='sessionMinutes'?'Minutes per session':'Any injuries or movement limits?');let input;\r\n  if(key==='goal'){input=node('select');input.append(new Option('Choose your goal',''));for(const value of field.options)input.append(new Option(value,value));}\r\n  else if(key==='sessionMinutes'){input=node('input');input.type='number';input.min=1;input.max=180;input.step=1;input.inputMode='numeric';}\r\n  else{input=node('textarea');input.rows=2;input.maxLength=2000;input.placeholder='None, or describe your limits.';}\r\n  input.name=key;input.required=key!=='limits';input.value=key==='limits'?data.answers.armie?.q3||'':data.profile[key]??'';controls[key]=input;label.append(input);form.append(label);\r\n  if(key==='limits'){\r\n    const noLimitsBtn=node('button','No limits');noLimitsBtn.type='button';noLimitsBtn.className='no-limits-btn';\r\n    const sync=()=>{const on=/^none\\.?$/i.test(input.value.trim());noLimitsBtn.setAttribute('aria-pressed',String(on));noLimitsBtn.textContent=on?'✓ No limits':'No limits';noLimitsBtn.style.outline=on?'2px solid #b8e9cf':'';};\r\n    noLimitsBtn.addEventListener('click',()=>{input.value=/^none\\.?$/i.test(input.value.trim())?'':'None';paint();});input.addEventListener('input',sync);form.addEventListener('input',sync);noLimitsBtn.addEventListener('click',sync);sync();\r\n    label.append(noLimitsBtn);\r\n  }\r\n }\r\n const status=node('p');status.role='status';const button=node('button',label);button.type='submit';button.className='setup-submit';form.append(status,button);host.replaceChildren(form);\r\n function collect(){data.profile.goal=controls.goal.value;data.profile.sessionMinutes=controls.sessionMinutes.value===''?null:Number(controls.sessionMinutes.value);data.answers.armie??={};data.answers.armie.q3=controls.limits.value.trim();return data;}\r\n function paint(){collect();const missing=missingFields(data);button.disabled=missing.length>0;status.textContent=missing.length?'': 'You’re ready.';changed(structuredClone(data));}\r\n form.addEventListener('input',paint);form.addEventListener('change',paint);\r\n form.onsubmit=async event=>{event.preventDefault();collect();if(missingFields(data).length||!form.reportValidity())return;button.disabled=true;status.textContent='Starting your coach…';try{await save(structuredClone(data));}catch(error){status.textContent=error.message;button.disabled=false;}};\r\n paint();return {form,collect};\r\n}\r\n","quick-setup.mjs":"import {withOfficeDefaults} from './office-domain.mjs';\r\nexport const QUICK_REQUIRED_FIELDS=['goal','sessionMinutes'];\r\nexport function withQuickDefaults(initial){\r\n const data=initial.entryRoute==='office'?withOfficeDefaults(initial):structuredClone(initial);\r\n data.setupMode='quick';data.profile??={};data.answers??={};\r\n const defaults={name:'You',coach:data.appearance?.['myr5-recipe-v1']?.coach||'supportive',trainingStyle:'Gradual progression',guidance:'Balanced',restSeconds:'60',trainingTime:'17:00',timezone:'UTC',reminderTone:'gentle',reminderDays:'3'};\r\n for(const [key,value] of Object.entries(defaults))if(data.profile[key]==null||data.profile[key]==='')data.profile[key]=value;\r\n if(data.profile.exercises==null||Array.isArray(data.profile.exercises)&&!data.profile.exercises.length)data.profile.exercises=['squat','pushup','tree','warrior','horse','boxing','jogging','jumping'];\r\n return data;\r\n}\r\n","receive-coach.mjs":"import {WEBSITE} from './onboarding-domain.mjs';\r\nexport function receiveCoach(store){\r\n const source=window.opener;if(!source)return Promise.reject(Error('Return to the final website setup and tap Unlock again. Keep that page open while Coach loads.'));\r\n return new Promise((resolve,reject)=>{let interval,timer;\r\n  const cleanup=()=>{clearInterval(interval);clearTimeout(timer);window.removeEventListener('message',message);};\r\n  function message(event){if(event.origin!==WEBSITE||event.source!==source||event.data?.type!=='myr5:coach-transfer')return;try{const v=event.data.profile,raw=JSON.stringify(v);if(!v||new TextEncoder().encode(raw).length>55000)throw Error('This transfer is too large.');store(raw);source.postMessage({type:'myr5:coach-received'},WEBSITE);cleanup();resolve(v);}catch(e){cleanup();reject(e);}}\r\n  window.addEventListener('message',message);const ready=()=>source.postMessage({type:'myr5:ready-for-coach'},WEBSITE);interval=setInterval(ready,700);timer=setTimeout(()=>{cleanup();reject(Error('Return to the website and tap Unlock again. Your saved answers are still there.'));},120000);ready();\r\n });\r\n}\r\n","recover.html":"<!doctype html>\r\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><meta http-equiv=\"refresh\" content=\"0;url=/repair-coach\"><title>Repair Coach</title></head><body><p><a href=\"/repair-coach\">Repair and update Coach</a></p></body></html>\r\n","recovery-page.mjs":"// This page has no module, sign-in, or cached-page dependency.\r\nexport const RECOVERY_HTML=String.raw`<!doctype html>\r\n<html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Repair Coach</title>\r\n<style>body{margin:0;min-height:100svh;display:grid;place-items:center;background:#241c35;color:#fff7de;font:17px/1.6 system-ui,sans-serif}main{max-width:420px;padding:32px;text-align:center}img{width:160px;height:160px;object-fit:contain}progress{display:block;width:100%;height:14px;accent-color:#edc866}button,a{font:inherit}button{padding:12px 24px;min-height:48px;background:#edc866;border:0;border-radius:8px;color:#241c35}a{color:#fff7de}button[hidden]{display:none}</style></head>\r\n<body><main><img src=\"/icons/myr5-alien-192.png\" alt=\"MYR5 Coach\"><h1>Repairing Coach</h1><progress id=\"progress\" max=\"100\" aria-label=\"Coach download\"></progress><p id=\"status\" role=\"status\">Connecting to the update…</p><p id=\"instructions\">Keep this page open while Coach downloads. Your saved progress stays here.</p><button id=\"retry\" hidden>Try again</button><noscript><p>Open this link in Chrome or Safari with JavaScript enabled.</p></noscript></main>\r\n<script>\r\n(()=>{'use strict';\r\nconst status=document.getElementById('status'),retry=document.getElementById('retry'),meter=document.getElementById('progress'),sw=navigator.serviceWorker;\r\nlet currentWorker;\r\nconst waitingMessage='Update downloaded. Waiting for your Coach session to finish safely. No browser tabs need to be closed.';\r\nlet preparedUpdate=null;\r\nsw?.addEventListener('message',event=>{\r\n if(event.data?.type==='UPDATE_SAFETY_CHECK'){preparedUpdate=event.data.id;event.ports[0]?.postMessage({safe:true,protocol:2,id:preparedUpdate});return;}\r\n if(event.data?.type==='UPDATE_CONFIRM'){event.ports[0]?.postMessage({safe:preparedUpdate===event.data.id,protocol:2,id:preparedUpdate});return;}\r\n if(event.data?.type==='UPDATE_ABORT'){if(preparedUpdate===event.data.id)preparedUpdate=null;return;}\r\n if(event.data?.type!=='OFFLINE_PROGRESS'||event.source!==currentWorker)return;\r\n const p=event.data;if(!p.totalBytes)return;\r\n const percent=Math.min(99,Math.floor(100*p.bytes/p.totalBytes));meter.value=percent;\r\n status.textContent='Saving Coach on this device: '+percent+'% · '+p.files+' of '+p.totalFiles+' files. Large models can take a few minutes.';\r\n});\r\nfunction state(worker,allowed){return new Promise((resolve,reject)=>{\r\n const finish=error=>{clearTimeout(timer);worker.removeEventListener('statechange',check);error?reject(error):resolve();};\r\n const check=()=>{if(allowed.includes(worker.state))finish();else if(worker.state==='redundant')finish(Error('The download did not finish. Check your connection and free space, then try again.'));};\r\n const timer=setTimeout(()=>finish(Error('The download is taking longer than expected. Check your connection, then try again.')),20*60*1000);\r\n worker.addEventListener('statechange',check);check();\r\n});}\r\nfunction activate(worker){return new Promise((resolve,reject)=>{\r\n const channel=new MessageChannel();\r\n const finish=(error,result)=>{clearTimeout(timer);channel.port1.close();error?reject(error):resolve(result);};\r\n const timer=setTimeout(()=>finish(Error(waitingMessage)),20000);\r\n channel.port1.onmessage=event=>{\r\n  if(event.data?.activated)return finish(null,true);\r\n  if(['close_clients','busy'].includes(event.data?.reason))return finish(null,false);\r\n  finish(Error(waitingMessage));\r\n };\r\n try{worker.postMessage({type:'PREPARE_UPDATE'},[channel.port2]);}catch(error){finish(error);}\r\n});}\r\nasync function update(){\r\n retry.hidden=true;meter.removeAttribute('value');status.textContent='Connecting to the update…';\r\n try{\r\n  if(!sw)throw Error('Open this repair link in Chrome, Edge, or Safari.');\r\n  const reg=await sw.register('/sw.js',{updateViaCache:'none'});await reg.update();\r\n  const worker=reg.installing||reg.waiting||reg.active;if(!worker)throw Error('Coach could not start downloading. Try again while online.');\r\n  currentWorker=worker;worker.postMessage({type:'OFFLINE_STATUS'});\r\n  status.textContent='Downloading the complete Coach app. Large models can take a few minutes.';\r\n  await state(worker,['installed','activating','activated']);\r\n  if(reg.waiting){\r\n   status.textContent='Preparing the update…';\r\n   if(!await activate(reg.waiting)){\r\n    currentWorker=null;meter.value=100;status.textContent=waitingMessage;\r\n    document.getElementById('instructions').textContent='Finish your workout first. If your installed Coach is an older version, swipe Coach away once from Android Recent apps. Leave this page open; it will finish automatically. Your saved progress stays here.';\r\n    setTimeout(update,5000);return;\r\n   }\r\n  }\r\n  await state(worker,['activated']);\r\n  meter.value=100;status.textContent='Coach is ready. Opening your app…';\r\n  location.replace('/pose.html?panel=install&update=repaired');\r\n }catch(error){status.textContent=error.message;retry.hidden=false;}\r\n}\r\nretry.onclick=update;update();\r\n})();\r\n</script></body></html>`;\r\n","release-build.mjs":"// Generated by the production build from app content.\nexport const BUILD_ID='154a6b54d26261797b45';\n","release-info.mjs":"import {BUILD_ID} from './release-build.mjs';\r\nexport const RELEASE=Object.freeze({id:'2026-10-16-release-33-'+BUILD_ID,title:'Release 33: Vault opens every time, treadmill Cool Cardio, full workout switchboard, one achievements flight, body-locked auras + hand trails',date:'2026-10-16',url:'https://myr5.mominc.online/repair-coach',notes:[\r\n \"Vault and every 3D room open every time on iPhone.\",\r\n \"Cool Cardio works on a treadmill: bob to run, arms up to jump, crouch to slide, lean to steer.\",\r\n \"FULL workout: plug in sections, flip the level ladder, run a shuffled circuit.\",\r\n \"Achievements and the XP flight are one page with hyperjump.\",\r\n \"Finish a workout, a meditation and a food log to unlock every coach and style.\",\r\n \"Auras stick to your body; punches leave light trails and impact sparks.\"\r\n]});\r\n","release-trust/materials/coach-ships-biomes/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 9912720,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"f2765764fd81bb0ee68dcecbb8f24b3fb3d7215fa4602568fcbbdf75af525af8\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"b4affce9fb7cf2ea06e9adaa695953b25a9b03fadaa0ffc6492c9da0862d68b3\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"3e958e6d00361b1c63fe31befa1182b23723b4fd0787820777368f6f8066c1ed\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"2eae71fda821496c23ae0a8d39b06b18b67aba93d6e2b31e1bcc511833402e8b\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"6680544f0f81efb648448e647ef59e10eb1197c3ef59df7ee190ba3b87015cb7\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"e6fc194be9547f028642ab1ce14eb774b0699d70727183124475b482a7af96c8\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"701ce69f570b6285c27b56d6c7214c5df80965a8308ccf1f27e2fde48c6ea721\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"158ca3547a802f1c24a036d320f4b8d8e7db1040215feb322214281c545275ed\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"8a43506ead05071e5002aded3891f544f5ab026e49e094cbbfcb2800f0defd01\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 475536,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"e6dbedf1a406342412dff2be6780f1f9e3bab889e3e25de059e50c3516b2af53\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/supportive.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/supportive.glb\",\r\n      \"sha256\": \"2770e0aa51d2cf262db2762700f4f3567cd34e44d0619f0628eae3bffdf06f09\"\r\n    },\r\n    {\r\n      \"bytes\": 10461352,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"23402097030897ba7bb7bf107333aa36c5b73ff63db64c6a942511b9aa221bfc\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"436d8a9b042e45d07a40efb65376a415a62537f1c3e9c9e422c24ca86e565ab4\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"1a9df385796255e38dbb2b64d7d7f755bfe97b5b1087610aa1e3cf71cb940bff\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"8e69ea4b69f2bb16ec7c6bd06ea667ed50c44317fbb5c9ec90ea719ec3cf1cfc\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"4af9dc6357edce143f179b64efb03f6af94cf606bebedde214a0aab3340a0389\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"628483d904c68b3745eb90409fb3e303e5424688f75c83354a150be01d347166\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"e376840ce2bd710cd1ba257ae5511ddfc1c546e54e8316c658ca1cc8f86ece60\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"9103062f012725e0dc02b74755385d9b5d6b4a29bb7f77d6b0254f1a8c7da895\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"e64648862e68b8e694585d8ec7567d500984d18522dc8bc48e318e7ba8478fb8\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1024168,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"cc579137cb1a17c074f4ede489f1dc5b01dafcdefed09e2c987d6164aa6c0268\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/direct.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/direct.glb\",\r\n      \"sha256\": \"d3757906634a3b2d056147270fbb95f37516853a6ac3f668bc1fd181dc1d36db\"\r\n    },\r\n    {\r\n      \"bytes\": 10085068,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"ab377a2aad7f469a5c3afd842a48ea865b1e1bcfcd39dae1bd21a325b394afc1\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"7cdd1c509d9e8d7f277f0e908376e14ffa4c37c8092a3e826738e4b0aac786d0\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"5189b144571bb13e7217de84a93e4c73cec45deb597404691f42f766410a5f24\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"43e598b8f7de4a741cd488a9dd1478e527974682d442e5bacb519f1a068759f0\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"3e25e7d1dc59e3de576e57ed694726676d4ff8b2afdfec1312c3c32caedc272a\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"cd87eae6a9046c8256f786c7a81f938e5d82953cce1b46f6aef16db9c5a96f51\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"f9676b44b771f8ca43c3c3a6412ac1044baac7e644091409b48a9f7006e06936\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"f864c5d0715bce027271713a3dcb0f6de59027db712ace5a0a730614f34d6a45\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"69ce1b9e4924a1afe26990aa059ad5c54b68d0656aac387a84540f41b0fcfe73\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 647884,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"1aaf24e13307eeb56bbf4a25ae1d7144ecd1bafb653fbe67a6235c898ae3f59b\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/analytical.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/analytical.glb\",\r\n      \"sha256\": \"0bed9d9a447f75dd126cb315c449d763048034902422ad6ac7629b3803dc241f\"\r\n    },\r\n    {\r\n      \"bytes\": 9944576,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"9d74ff2aa3b7c6ca4d3ca2783c549eb656148d7adf5bb73a6675172dbf1abffb\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"523a462a353592c0c7b6a873eccf2797a86434854c629fb17f397ae59ca94d60\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"792768fc8a5a6c195574c9bbe2d8a1f090adf3179e5c763ecadd4e49dc25952d\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"d04a2f1f31c2689559b0453598f85e8d7689bdc803a146f4ba68345866eafa39\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"d7a4bdee82b8090a50ed30e1c1a3ab7fbe2e674154c6bb88ea0e15e455793f81\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"02c48c3047662315d7055ef0117fb0e6ebd4be71ecda45e5b6dbd58669c06e96\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"c02451b26910974d90899e3736a9c3a1252936caa4fc6b525559324f39092d3d\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"e1b6db796df886a5a1528bbea35ba6ee1eee00a78522d05fe99d8b3a05e220ac\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"1eff2bf1af9eb6323702464eb7cd7c4d5f39191ae1c04307427d59844b98913f\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 507392,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"f9cca59d2cf2cc70adc847966253c615051e72617a429963ad1734c84dbdd927\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/playful.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/playful.glb\",\r\n      \"sha256\": \"c53d74da8e12b7676cf6d06d5526938d26da05d07dd4b38af74fae845137e4df\"\r\n    },\r\n    {\r\n      \"bytes\": 10341060,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"edd56ada4921456d02d13140cabcf4b25226a11804c775c94bd1605f5fe34015\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"447b925eb3541f4e4001c0078c3727451fd0f34e4a2934f9317c328ecf5512b8\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"fc36e092cf490f839661bff0b173654298648fd15b7754328d820e666386c5cd\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"046ccf0a8443348a653ac8c57ee7c0872feb1a8222313c26d362c27196d5e14e\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"9eacf012e5d03d0162a9c5cc3238d2c34788ab771c1f52df412eda05c4794a3f\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"f34a37a4c104db9f6796edd5d557f349fa58fd6d95d5fdc7549d7c3793c5f621\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"44f3eca0cc0ae08f9d81a60ff7bc1fc3ba2a19e54a84caa8a91ecffeda1b5cc8\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"c70c3cd2cf3169050114cb79cdc1710f9757b8575022de3febf841d28ef4f040\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"e0fc194e241215d4bd1f934afacd27c1d40ce8d52e8f34cec22160b57b4c32a6\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 903876,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"2bd20a3d8f1503bd67769f1165b1784418ebeb687581ae97d244ba420089595d\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/calm.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/calm.glb\",\r\n      \"sha256\": \"2288a2f10b1a0affc007870f70bf25c1223c00a3d21dcbd28a7262677b78b404\"\r\n    },\r\n    {\r\n      \"bytes\": 10315084,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"ca9d75894c972695ded6bc30603a44d1ab36a31f7b3ceb10da33e723373f7d60\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"72eab6b8bb19667b1cc03812b5eefa6292bde2b0932ea8d59d8f17ad46ab1618\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"9cf1c6820e32c2ac6d6ef328b613d5ea1e681ead2a11daeb4d65c60033682c8d\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 3,\r\n          \"offset\": 3145728,\r\n          \"sha256\": \"9df28c76b385a2a370037b771dc74de41a7531af2a5dea471dcca37166e17782\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 4,\r\n          \"offset\": 4194304,\r\n          \"sha256\": \"25b2914bf6fbd69a75794549d0ebf5431e493ba7c01ce7beccbb47d3224d4be2\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 5,\r\n          \"offset\": 5242880,\r\n          \"sha256\": \"0031f0120d939a91453bd523959d8af96b99b2ea873fb9e174e0c7a1afee12f3\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 6,\r\n          \"offset\": 6291456,\r\n          \"sha256\": \"f866f71f191290d1b74d9eecec3d35984e1b737daa3b1ff0aa9f57780a91799c\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 7,\r\n          \"offset\": 7340032,\r\n          \"sha256\": \"1ef9efa4fa4f36d7abc5cdf495c697120c0c8602a89ae965bddfc49af5cb2f2b\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 8,\r\n          \"offset\": 8388608,\r\n          \"sha256\": \"e5a7c0f9f04959c3b01454e987ed90f0bef4e6b250a6363cd9534c560b90c072\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        },\r\n        {\r\n          \"bytes\": 877900,\r\n          \"index\": 9,\r\n          \"offset\": 9437184,\r\n          \"sha256\": \"b62bdd8d7ca73c5782879c040797ff523a64bb21ecce083f44b7747fb5836f68\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/mom.glb\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/ships/mom.glb\",\r\n      \"sha256\": \"1deb2c0afd574bed329a401b723eeefcb5025b7a9eaf13d5dbaf6c46930ed4d6\"\r\n    },\r\n    {\r\n      \"bytes\": 277137,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 277137,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"53e26dfbfbe97a5ddd78f12b846f00ec191fd547aef7a5763953beb18bd79c44\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/coach-ships-biomes/1.0.0/biomes.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/biomes.m5bundle\",\r\n      \"sha256\": \"53e26dfbfbe97a5ddd78f12b846f00ec191fd547aef7a5763953beb18bd79c44\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"coach-ships-biomes\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"l1EbETMJXruyyKCTrGYBr6rlr3mAS2YUmFXlnzDcqTMhMV+SXhsizYHEF6RdWTEwIE8/4pn2kkXzDuj5EssABA==\"\r\n}\r\n","release-trust/materials/track-arms/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 1122666,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"c92098d11ba3535c4765abdce87f4d2cf0e3deba5f5c5664e9e3983b2ead58de\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-arms/1.0.0/arms.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 74090,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"bf7e003b9e3bd59411cf16a8442e7054e8c0e7648e1425a1439f0998a053b9d5\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-arms/1.0.0/arms.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/arms.m5bundle\",\r\n      \"sha256\": \"ff0cf7e43a688e74a6a32a9d6fc73e6f9557dea3ed85ce0cce7910716d1476b4\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-arms\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"mcmu2PmtFbyozhlFOQFCmdXUQlYIlomts1hJIOctyUwiYEB/MOXacIGZa6ynr71/QgOsFjvlhctd/QbsjbmhCg==\"\r\n}\r\n","release-trust/materials/track-cardio/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 1537805,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"eb01e9f223b96013cad792777daef229c731973b7d3b61c48cb1257ffd73c1c0\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-cardio/1.0.0/cardio.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 489229,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"4086ce291e2c25c07662e9d66d00fe013ac874d85cd3a63c39756fe74f1ad284\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-cardio/1.0.0/cardio.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/cardio.m5bundle\",\r\n      \"sha256\": \"9c8c59d696df833daa99cfccf29a5e0975d1953228d322ac0439b60770feea3b\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-cardio\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"WNRFA+XchdvXXYRykgF0QK3CTXIU0kFdSjt/ZBibt3piWo1H9jmN7rGdL7+na6bveJjYdR4eDzRFVKi4qdMKAA==\"\r\n}\r\n","release-trust/materials/track-chest/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 843781,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 843781,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"c76d08541a42ccf4f47cb52beea0396665ec7d77c36c61a61905f59ba9bf0c25\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-chest/1.0.0/chest.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/chest.m5bundle\",\r\n      \"sha256\": \"c76d08541a42ccf4f47cb52beea0396665ec7d77c36c61a61905f59ba9bf0c25\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-chest\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"6uZXXkvQaUcNHbK80w1xds9KVQh0yXK39u+sFcrcoUbsJY+wmcOGWki0hiE5lCW39PXoBNn+jCdillGEQYfFAA==\"\r\n}\r\n","release-trust/materials/track-glutes/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 2546727,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"340512fd3d3e666ddc5ea5f30ff0a483cd32becab2edd486eb78dd9586c54506\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-glutes/1.0.0/glutes.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"34d360b648b5dc563bd2dcd3f5c3f44f1b1ad2b3e89b8ec35f9d3f4b4ee65842\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-glutes/1.0.0/glutes.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 449575,\r\n          \"index\": 2,\r\n          \"offset\": 2097152,\r\n          \"sha256\": \"887e931765526a6d1f5ce47a6f85c313a96888255090d39698ac9d09130e76e5\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-glutes/1.0.0/glutes.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/glutes.m5bundle\",\r\n      \"sha256\": \"6728e3c20116b189ad8c486cc48ef861bf28d02270fc9e8dda6960dc82bf97a7\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-glutes\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"6fqedheEUjwSQdkVE17DU31DKSX0H9S0xhZ9Tpb/L7JmJFcyFLgF8TBrq7gmbizRw2O+WftrHwyHGO4w94YRDw==\"\r\n}\r\n","release-trust/materials/track-martial-arts/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 1350733,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"8395e377d42d370e53f9e9082841aa53bb25a4f7f43b73771863c1a0515e4fd7\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-martial-arts/1.0.0/martial-arts.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 302157,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"f0721d49614af71174d30d2da1122eb5820d1fdf09fbdfe2ce3786f1c8307265\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-martial-arts/1.0.0/martial-arts.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/martial-arts.m5bundle\",\r\n      \"sha256\": \"654966fa10024710dc47e3618f68003b5ee0c07ee23c870f2d93adc0ed31854e\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-martial-arts\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"pVrwyRilcqn0LefqKa10WvIAym7Eb5pNy9NxRywZcnHNiM0I6LnnOAb6X4PJbL+xek6OM5IfYy6jm099xG7cCg==\"\r\n}\r\n","release-trust/materials/track-meditation/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 1584210,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"eb2dd5f0aa842b621e58d3e03fa61b42c195b8257f9f31c08c8989998712f2e0\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-meditation/1.0.0/meditation.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 535634,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"23dd1c83aaff02d52bc1d7edf962110635bff6fc49e6a5ca8f168c8f33b2b3e0\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-meditation/1.0.0/meditation.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/meditation.m5bundle\",\r\n      \"sha256\": \"cbffbd9b31a524cafd879ae27dcad5f3aace3bd9b7f99fa7ea44cb644015b7bb\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-meditation\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"oq8iPBwBYr3VMV1/Ufa03kwtM4Aanh4GgSqjk54joFOfmtxfpPmK8Pm7m29BCRIj0izSuYGWhE0zF2ftAzY/Dw==\"\r\n}\r\n","release-trust/materials/track-quads/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 1227707,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 1048576,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"96732979bd4e29d4a5a620a2cb7507c0e568d30c6c963db3cd231b554b59be79\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-quads/1.0.0/quads.m5bundle\"\r\n        },\r\n        {\r\n          \"bytes\": 179131,\r\n          \"index\": 1,\r\n          \"offset\": 1048576,\r\n          \"sha256\": \"0bce54b9701d11ff7e2ad975506719f8c6cd3ce39af09fff2c87f97783c13b96\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-quads/1.0.0/quads.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/quads.m5bundle\",\r\n      \"sha256\": \"928026875a70613d3ddf7d727d6a83e08ca6be869cc2959c78c341d14eef7a9e\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-quads\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"j/NP4pr2/Mehe3oEZ1KWgz5PEBJei0W5TDptODUCuitsCckGSVb9y/tBXDaJSdbe00q3NRG48EENeU9vURe3Aw==\"\r\n}\r\n","release-trust/materials/track-yoga/chunk-manifest.json":"{\r\n  \"assets\": [\r\n    {\r\n      \"bytes\": 950844,\r\n      \"chunks\": [\r\n        {\r\n          \"bytes\": 950844,\r\n          \"index\": 0,\r\n          \"offset\": 0,\r\n          \"sha256\": \"e9452dbc7d6425a687945fcacd173ba6f958fee183aab01e7596d4a6aa679b8e\",\r\n          \"url\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials/track-yoga/1.0.0/yoga.m5bundle\"\r\n        }\r\n      ],\r\n      \"path\": \"assets/yoga.m5bundle\",\r\n      \"sha256\": \"e9452dbc7d6425a687945fcacd173ba6f958fee183aab01e7596d4a6aa679b8e\"\r\n    }\r\n  ],\r\n  \"keyId\": \"mom-material-production-v1\",\r\n  \"packId\": \"track-yoga\",\r\n  \"schema\": \"mom-material-chunks-v1\",\r\n  \"version\": \"1.0.0\",\r\n  \"signature\": \"Y6ZQRTG3JiJE2mKIvtwjp370WC/eScHXaNUxKAARpIKOkPN4XVYEQf4mg0VI04XKI5ZfTMW5EAzPTWvzqvewAA==\"\r\n}\r\n","release-trust/public-build.json":"{\r\n  \"$comment\": [\r\n    \"Public build-time trust for release builds (scripts/build.mjs). Public verification values only:\",\r\n    \"the private signing key never goes here or in the build env (build.mjs throws if it is set).\",\r\n    \"An env var with the same name overrides a value here; null leaves it unset.\",\r\n    \"MYR5_MATERIAL_*: Ed25519 public key + commit-pinned raw host for the creature-skin and ship/biome\",\r\n    \"post-download sections. The nine signed manifests are in materials/<section>/chunk-manifest.json;\",\r\n    \"the build verifies each against this key before copying it to /materials/. Recovered 2026-09-26\",\r\n    \"from Codex's release 2 build (site-b0dea68, 22 Sep); later Sites builds, incl. live v65, dropped them.\",\r\n    \"PUBLIC_EXPANSION_SIGNING_JWK: no expansion key has ever been published (null in every release).\"\r\n  ],\r\n  \"MYR5_MATERIAL_PUBLIC_SIGNING_JWK\": {\"kty\":\"OKP\",\"crv\":\"Ed25519\",\"x\":\"nfofxCZW0Pz9o2_6d2AGnwL7EA3CsA52NlF1vMcFnDY\"},\r\n  \"MYR5_MATERIALS_BASE_URL\": \"https://raw.githubusercontent.com/MomInc-MBS/coach-app/1c49652e0e16d0b89818d32a0748bee98b8f1418/materials\",\r\n  \"MYR5_MATERIAL_SITE_MANIFESTS\": \"release-trust\",\r\n  \"PUBLIC_EXPANSION_SIGNING_JWK\": null\r\n}\r\n","reminder-controls.mjs":"import {TONES,CADENCES,CADENCE_LABELS,reminderMessage} from './reminder-settings.mjs';\r\nexport function mountReminderControls(){\r\n const $=id=>document.getElementById(id),form=$('reminderForm'),dial=$('toneDial'),slider=$('consistencySlider');\r\n let index=1,drag=null;\r\n function render(){\r\n  const tone=TONES[index],days=CADENCES[Number(slider.value)];\r\n  form.elements.tone.value=tone;form.elements.daysPerWeek.value=days;\r\n  dial.setAttribute('aria-valuenow',index);dial.setAttribute('aria-valuetext',tone);dial.style.setProperty('--turn',`${(index-1)*110}deg`);\r\n  $('toneValue').textContent=tone[0].toUpperCase()+tone.slice(1);$('reminderPreview').textContent=reminderMessage(form.elements.kind.value,tone);\r\n  $('consistencyValue').textContent=CADENCE_LABELS[days];slider.setAttribute('aria-valuetext',CADENCE_LABELS[days]);slider.style.setProperty('--fill',`${Number(slider.value)/3*100}%`);\r\n  $('gentlerTone').disabled=index===0;$('cheekierTone').disabled=index===2;\r\n }\r\n const change=value=>{index=Math.max(0,Math.min(2,value));render();};\r\n $('gentlerTone').onclick=()=>change(index-1);$('cheekierTone').onclick=()=>change(index+1);\r\n dial.onkeydown=e=>{const actions={ArrowLeft:index-1,ArrowDown:index-1,ArrowRight:index+1,ArrowUp:index+1,Home:0,End:2};if(Object.hasOwn(actions,e.key)){e.preventDefault();change(actions[e.key]);}};\r\n dial.onpointerdown=e=>{if(e.button!==0)return;drag={x:e.clientX,y:e.clientY,index,id:e.pointerId};dial.setPointerCapture(e.pointerId);dial.focus();};\r\n dial.onpointermove=e=>{if(drag?.id===e.pointerId)change(drag.index+Math.round(((e.clientX-drag.x)-(e.clientY-drag.y))/40));};\r\n dial.onpointerup=dial.onpointercancel=dial.onlostpointercapture=()=>{drag=null;};\r\n slider.oninput=render;form.elements.kind.addEventListener('change',render);\r\n render();\r\n return {load(tone='direct',days=7){index=Math.max(0,TONES.indexOf(tone));slider.value=Math.max(0,CADENCES.indexOf(days));render();}};\r\n}\r\n","reminder-live.mjs":"import {scheduledDay} from './reminder-settings.mjs';\r\nconst formatters=new Map();\r\nfunction localParts(now,timezone){if(!formatters.has(timezone))formatters.set(timezone,new Intl.DateTimeFormat('en-CA',{timeZone:timezone,year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit',hourCycle:'h23'}));const parts=Object.fromEntries(formatters.get(timezone).formatToParts(now).map(p=>[p.type,p.value]));return {day:`${parts.year}-${parts.month}-${parts.day}`,time:`${parts.hour}:${parts.minute}`};}\r\nexport function quietReminder(r){const a=r.quiet_start,b=r.quiet_end,t=r.time;return a!==b&&(a<b?t>=a&&t<b:t>=a||t<b);}\r\nexport function nextReminderAt(r,now=Date.now()){\r\n if(!r.enabled||quietReminder(r))return null;\r\n const today=localParts(now,r.timezone).day;\r\n for(let day=0;day<9;day++){\r\n  const date=new Date(Date.parse(today+'T12:00:00Z')+day*86400000).toISOString().slice(0,10);if(!scheduledDay(date,r.days_per_week??7))continue;\r\n  const target=Date.parse(date+'T'+r.time+':00Z');let guess=target;\r\n  for(let i=0;i<3;i++){const local=localParts(guess,r.timezone);guess+=target-Date.parse(local.day+'T'+local.time+':00Z');}\r\n  // Validate the wall time; a spring-forward gap must not become a different hour.\r\n  const candidates=[guess-3600000,guess,guess+3600000].filter(t=>{const p=localParts(t,r.timezone);return p.day===date&&p.time===r.time&&t>now-600000;}).sort((a,b)=>a-b);\r\n  if(candidates.length)return candidates[0];\r\n }\r\n return null;\r\n}\r\nexport function reminderCountdown(time,now=Date.now()){if(time==null)return '';const seconds=Math.ceil((time-now)/1000);if(seconds<=0)return 'Scheduled now';if(seconds<60)return `In ${seconds}s`;if(seconds<3600)return `In ${Math.ceil(seconds/60)} min`;if(seconds<86400)return `In ${Math.floor(seconds/3600)}h ${Math.ceil((seconds%3600)/60)}m`;return `In ${Math.ceil(seconds/86400)} days`;}\r\nexport function mountLiveReminders({refresh,read,getAccount,deviceReady=()=>true}){\r\n const status=document.getElementById('reminderLiveStatus'),panel=document.getElementById('remindersPanel');let rows=[],schedule=[],busy=false,stopped=false,lastRead=0;\r\n function update(items){rows=items;schedule=items.map(r=>({r,next:nextReminderAt(r)}));render();}\r\n function render(){\r\n  if(!panel.open||document.hidden)return;\r\n  const now=Date.now();for(const entry of schedule)if(entry.next!=null&&entry.next<=now-600000)entry.next=nextReminderAt(entry.r,now);\r\n  for(const {r,next}of schedule){const label=document.getElementById('reminder-next-'+r.id);if(label)label.textContent=!r.enabled?'Paused':quietReminder(r)?'This time is inside quiet hours':reminderCountdown(next,now);}\r\n  const account=getAccount(),on=document.getElementById('notificationSwitch').getAttribute('aria-checked')==='true';\r\n  const fresh=account&&Date.now()-account.syncedAt<90000;\r\n  const connected=navigator.onLine&&fresh&&account?.push?.configured&&account?.push?.schedulerActive&&on&&deviceReady();\r\n  status.dataset.state=connected?'live':'waiting';\r\n  const next=schedule.filter(x=>x.next!=null).sort((a,b)=>a.next-b.next)[0];\r\n  status.textContent=!navigator.onLine?'Offline · reminders resume when connected':!account?'Sign in to receive reminders':account.push.environment==='preview'?'Local preview · notifications run in the live app':!fresh?'Checking the reminder connection…':!account.push.configured?'Notification service is unavailable':!account.push.schedulerActive?'Reminder sender is reconnecting':!on?'Turn on notifications for this device':!deviceReady()?'Reconnecting this device…':!rows.some(r=>r.enabled)?'Connected · save or enable a reminder':next?`Live · ${next.r.kind} · ${reminderCountdown(next.next,now)}`:'Connected · choose a time outside quiet hours';\r\n }\r\n async function sync(){if(stopped||busy||document.hidden||!panel.open)return;busy=true;try{await refresh();await read();lastRead=Date.now();}finally{busy=false;render();}}\r\n const timer=setInterval(()=>{render();if(Date.now()-lastRead>=15000)sync();},1000);\r\n window.addEventListener('online',sync);window.addEventListener('offline',render);document.addEventListener('visibilitychange',sync);\r\n window.addEventListener('pagehide',()=>{stopped=true;clearInterval(timer);});\r\n return {update,sync,render};\r\n}\r\n","reminder-plan.mjs":"import {scheduledDay} from './reminder-settings.mjs';\r\nexport const MAX_DAILY_MESSAGES=3;\r\nexport function missedTrainingDays(status,now,daysPerWeek=7){\r\n if(!status||!Number.isSafeInteger(status.startedDay))return 0;\r\n const today=Math.floor(now/86400000),last=Number.isSafeInteger(status.lastCompletedDay)?status.lastCompletedDay:status.startedDay-1;\r\n let missed=0;for(let day=Math.max(last+1,status.startedDay,today-30);day<today;day++)if(scheduledDay(new Date(day*86400000).toISOString().slice(0,10),daysPerWeek))missed++;\r\n return missed;\r\n}\r\nexport function coachReminder(missed,tone='cheeky'){\r\n if(tone==='gentle')return missed?'Your pod is still here. Return with one comfortable set.':'A small session counts. Visit your pod when you’re ready.';\r\n if(missed>=7)return 'MOM is done waiting. Your arsenal is collecting dust. One steady set. Make your comeback.';\r\n if(missed>=3)return 'MOM is disappointed in that empty training log. Report to the pod. One set gets you moving again.';\r\n if(missed>=1)return 'You missed training. MOM noticed. Your next weapon upgrade is still waiting. Report to the pod.';\r\n return 'POD CHECK. Your weapon will not upgrade itself. One steady set. Log your category day.';\r\n}\r\n","reminder-settings.mjs":"export const TONES=['gentle','direct','cheeky'];\r\nexport const CADENCES=[1,3,5,7];\r\nexport const DAYS={1:[1],3:[1,3,5],5:[1,2,3,4,5],7:[0,1,2,3,4,5,6]};\r\nexport const CADENCE_LABELS={1:'Once a week · Monday',3:'3 days a week · Mon, Wed, Fri',5:'Weekdays · Monday–Friday',7:'Every day'};\r\nconst messages={\r\n gentle:{workout:'A little movement, at your pace. MOM is here when you are ready.',meal:'Take a moment to log your meal. One small check-in is enough.',water:'A gentle nudge to take a water break.',motivation:'You do not have to do everything today. One small step counts.'},\r\n direct:{workout:'Time for your workout. Your coach is ready.',meal:'Pause and log your meal.',water:'Time for a water break.',motivation:'A small step counts. Move at your own pace.'},\r\n cheeky:{workout:'MOM has warmed up her encouragement. Your turn to move, darling.',meal:'Your meal has a story. MOM would like the short version. Log it, darling.',water:'Your water is waiting. Very patient. Unlike MOM.',motivation:'MOM believes in you. Embarrassingly much. Time for one small step.'}\r\n};\r\nexport function reminderMessage(kind,tone='direct'){return messages[TONES.includes(tone)?tone:'direct'][kind]||messages.direct.motivation;}\r\nexport function scheduledDay(day,daysPerWeek=7){const weekday=new Date(day+'T12:00:00Z').getUTCDay();return (DAYS[daysPerWeek]||DAYS[7]).includes(weekday);}\r\n","rest-boss-rewards.mjs":"﻿import {performanceOwner,localDay} from './performance-progress.mjs';\r\nimport {grantUnlock,isGranted} from './unlock-ledger.mjs';\r\nexport const REST_BOSS_REWARDS_KEY='myr5-rest-boss-rewards-v1';\r\nexport const REST_BOSS_PACKS=Object.freeze([{count:1,tier:'uncommon'},{count:5,tier:'legendary'}]);\r\nexport function captureRestBossContext({storage=globalThis.localStorage,account=globalThis.myr5AuthenticatedAccount??null,day=localDay()}={}){\r\n const captured=account?structuredClone(account):null;return {storage,account:captured,owner:performanceOwner(storage,captured),day};\r\n}\r\nfunction context(options={}){return options.owner?options:captureRestBossContext(options);}\r\nfunction key(c){return `${REST_BOSS_REWARDS_KEY}/${encodeURIComponent(c.owner)}`;}\r\nfunction read(c){try{const value=JSON.parse(c.storage.getItem(key(c))||'{}');return value?.version===1&&value.days&&typeof value.days==='object'?value:{version:1,days:{}};}catch{return {version:1,days:{}};}}\r\nfunction dayIds(data,day){const values=data.days[day];return Array.isArray(values)?[...new Set(values.filter(x=>typeof x==='string'&&x.length<=256))]:[];}\r\nexport function restBossPackId(day,tier){return `reward-pack:${tier}:rest-boss-v1:${day}`;}\r\nexport function hasRestBossDefeat(id,options={}){const c=context(options),data=read(c);return Object.keys(data.days).some(day=>dayIds(data,day).includes(id));}\r\nexport function readRestBossRewards(options={}){const c=context(options),ids=dayIds(read(c),c.day);return {owner:c.owner,day:c.day,count:ids.length,defeatIds:ids,packs:REST_BOSS_PACKS.map(p=>({...p,id:restBossPackId(c.day,p.tier),earned:ids.length>=p.count,granted:isGranted('reward-pack',restBossPackId(c.day,p.tier),{account:c.account})}))};}\r\n/** Captured owner and day are passed by the actual rest encounter. Replaying an\r\n * encounter repairs a missing grant, but never counts the defeat again. */\r\nexport function recordRestBossDefeat(defeatId,options={}){\r\n if(typeof defeatId!=='string'||!defeatId||defeatId.length>256)throw RangeError('Invalid rest boss encounter.');\r\n const c=context(options);if(!/^\\d{4}-\\d{2}-\\d{2}$/.test(c.day))throw RangeError('Invalid rest boss day.');\r\n const data=read(c),ids=dayIds(data,c.day),already=Object.keys(data.days).some(day=>dayIds(data,day).includes(defeatId));if(!already){ids.push(defeatId);data.days[c.day]=ids;try{c.storage.setItem(key(c),JSON.stringify(data));}catch{return {recorded:false,granted:[],...readRestBossRewards(c)};}}\r\n const granted=[];for(const p of REST_BOSS_PACKS)if(ids.length>=p.count){const id=restBossPackId(c.day,p.tier);if(grantUnlock('reward-pack',id,{account:c.account}))granted.push({kind:'reward-pack',id,tier:p.tier});}\r\n const result={...readRestBossRewards(c),recorded:!already,granted};if((!already||granted.length)&&typeof window!=='undefined')window.dispatchEvent(new CustomEvent('myr5:rest-boss-rewards',{detail:result}));return result;\r\n}\r\n\r\nexport function recordRestBossDefeatExclusive(id,options={}){const c=context(options),locks=globalThis.navigator?.locks;return locks?.request?locks.request(key(c),()=>recordRestBossDefeat(id,c)):Promise.resolve(recordRestBossDefeat(id,c));}\r\n","reward-pack-ui.mjs":"import {COACHES} from './performance-catalog.mjs';\r\nimport PALETTES from './creature/source/creator/palettes.json' with {type:'json'};\r\nimport {openRewardPackExclusive,unopenedPacks,PACK_SIZES,packSize} from './reward-packs.mjs';\n\r\n// The pack is just a tile: a 64x64 pixel tile in its tier colour, then the item it awarded. Both popups are\r\n// modal <dialog> (top layer) so the portal's background inerting never swallows it, and it presents itself\r\n// once per pack per page load when one is waiting; the small launcher button reopens packs left for Later.\r\nconst CSS=`\r\n.reward-pack-launch[hidden]{display:none}\r\n.reward-pack-launch{position:fixed;right:16px;bottom:calc(var(--myr5-bar,0px) + 18px + env(safe-area-inset-bottom,0px));z-index:9000;display:flex;align-items:center;gap:8px;border:2px solid var(--pack);border-radius:12px;background:#21182f;color:#fff4bd;padding:6px 12px 6px 6px;font:800 14px system-ui;box-shadow:0 8px 30px #0009;cursor:pointer}\r\n.reward-pack-launch canvas{width:32px;height:32px;image-rendering:pixelated}\r\n.reward-pack-dialog{width:min(calc(100vw - 32px),380px);max-height:calc(100dvh - 32px);margin:auto;padding:0;border:0;background:none;color:#fff7df;font:500 16px/1.4 system-ui;overflow:visible}\r\n.reward-pack-dialog::backdrop{background:#090717e8}\r\n.reward-pack-card{overflow:auto;max-height:calc(100dvh - 32px);box-sizing:border-box;text-align:center;border:2px solid var(--pack);border-radius:20px;background:radial-gradient(circle at 50% 30%,color-mix(in srgb,var(--pack) 26%,#21152e),#13101e 73%);box-shadow:0 0 55px color-mix(in srgb,var(--pack) 35%,transparent);padding:18px 18px 20px}\r\n.reward-pack-card h2{margin:4px 0 0;font:900 24px/1.1 system-ui;text-transform:uppercase;letter-spacing:.04em}.reward-pack-card .eyebrow{margin:0;color:var(--pack);font:800 12px system-ui;letter-spacing:.2em;text-transform:uppercase}\r\n.reward-pack-tile{display:block;margin:14px auto 10px;width:min(56vw,192px);height:min(56vw,192px);image-rendering:pixelated;filter:drop-shadow(0 10px 8px #000a)}\r\n.reward-pack-dialog.opened .reward-pack-tile{animation:pack-flip .45s ease-out}\r\n.reward-pack-result{min-height:64px;margin:0 0 14px}.reward-pack-result strong{display:block;color:var(--pack);font-size:22px;line-height:1.2}.reward-pack-result small{display:block;opacity:.85;text-transform:uppercase;letter-spacing:.12em;font-size:12px;margin-top:4px}\r\n.reward-pack-swatches{display:flex;justify-content:center;gap:6px;margin-top:8px}.reward-pack-swatches i{width:26px;height:26px;border:2px solid #fff7df;border-radius:4px}\r\n.reward-pack-actions{display:flex;gap:9px;justify-content:center}.reward-pack-actions button{min-height:44px;border:2px solid var(--pack);border-radius:12px;background:var(--pack);color:#15101c;font:800 15px system-ui;padding:8px 18px;cursor:pointer}.reward-pack-actions button.secondary{background:transparent;color:#fff7df}\r\n.reward-pack-actions button:focus-visible,.reward-pack-launch:focus-visible{outline:3px solid white;outline-offset:3px}\r\n@keyframes pack-flip{0%{transform:scale(1)}40%{transform:scale(1.12) rotateY(90deg);filter:brightness(2)}100%{transform:scale(1)}}\r\n.reward-pack-launch[data-tier=secret],.reward-pack-dialog[data-tier=secret] .reward-pack-card{border-color:transparent;background:linear-gradient(#21182f,#21182f) padding-box,linear-gradient(120deg,#3ff5ff,#b388ff,#ff4bd8,#ffd36a,#3ff5ff) border-box;background-size:auto,300% 100%;animation:pack-iri 5s linear infinite}\r\n.reward-pack-dialog[data-tier=secret] .reward-pack-card{background:radial-gradient(circle at 50% 30%,#3a2160,#13101e 73%) padding-box,linear-gradient(120deg,#3ff5ff,#b388ff,#ff4bd8,#ffd36a,#3ff5ff) border-box;background-size:auto,300% 100%}\r\n.reward-pack-launch[data-tier=secret] canvas,.reward-pack-dialog[data-tier=secret] .reward-pack-tile{animation:pack-hue 6s linear infinite}\r\n@keyframes pack-iri{to{background-position:0 0,-300% 0}}@keyframes pack-hue{50%{filter:hue-rotate(60deg) drop-shadow(0 10px 8px #000a)}}\r\n@media(prefers-reduced-motion:reduce){.reward-pack-dialog.opened .reward-pack-tile,.reward-pack-launch[data-tier=secret],.reward-pack-dialog[data-tier=secret] .reward-pack-card,.reward-pack-launch[data-tier=secret] canvas,.reward-pack-dialog[data-tier=secret] .reward-pack-tile{animation:none}}\r\n`;\r\nexport const TIER_COLORS=Object.freeze({uncommon:'#76e356',rare:'#4bafff',legendary:'#ff9c36',secret:'#b388ff'});\r\nexport const tierOf=id=>{const tier=String(id).startsWith('reward-pack:')?String(id).split(':')[1]:'uncommon';return Object.hasOwn(TIER_COLORS,tier)?tier:'uncommon';};\r\nconst CATEGORY={color:'Colour palette','64-bit':'64-bit pixel finish',texture:'Texture'};\r\n// What the tile says about an opened pack: the actual item, what kind it is, and its colours when it is a palette.\r\nexport function rewardSummary(opened){\r\n const rewards=opened?.rewards|| (opened?.reward?[opened.reward]:[]);\r\n const reward=rewards[0]||{};\r\n // A single colour (pool items carry `hex`; a hex id is itself one) shows one swatch the way a palette shows its bands.\r\n const single=reward.kind==='color'?[/^#[0-9a-f]{6}$/i.test(reward.id)?reward.id:reward.hex].filter(Boolean):[];\r\n const colors=reward.kind==='palette'?PALETTES.find(item=>item.id===reward.id)?.colors||[]:single;\r\n const detail=reward.kind==='boss-skin'?'64-bit boss skin':reward.kind==='color'?'Colour':reward.kind==='palette'?'Colour palette':CATEGORY[reward.category||opened?.category]||'Cosmetic';\r\n return {title:reward.name||'Collection complete',detail,colors,rewards};\r\n}\r\n// Determine the reveal treatment from the persisted rewards. Secret packs keep\r\n// their established holographic treatment; boss skins with no cosmetic colour\r\n// keep the original pack-tier fallback.\r\nexport function rewardRevealType(opened,fallback='uncommon'){\r\n if(opened?.tier==='secret'||fallback==='secret')return 'secret';\r\n const rewards=opened?.rewards||(opened?.reward?[opened.reward]:[]);\r\n if(rewards.some(reward=>reward.kind==='texture'||reward.category==='texture'))return 'texture';\r\n const colors=rewards.reduce((n,reward)=>n+(reward.kind==='palette'?(PALETTES.find(item=>item.id===reward.id)?.colors?.length||2):reward.kind==='color'?1:0),0);\r\n if(colors>1)return 'multiple-colors';\r\n if(colors===1)return 'single-color';\r\n return 'cosmetic';\r\n}\r\nexport const rewardRevealTier=(opened,fallback='uncommon')=>({texture:'legendary','multiple-colors':'rare','single-color':'uncommon',secret:'secret'})[rewardRevealType(opened,fallback)]||(TIER_COLORS[fallback]?fallback:'uncommon');\r\nconst REWARD_COLORS=Object.freeze({texture:TIER_COLORS.legendary,'multiple-colors':TIER_COLORS.rare,'single-color':TIER_COLORS.uncommon});\r\nconst shade=(hex,amount)=>{const n=parseInt(hex.slice(1),16),c=[n>>16,n>>8&255,n&255].map(v=>Math.max(0,Math.min(255,Math.round(v+amount))));return '#'+c.map(v=>v.toString(16).padStart(2,'0')).join('');};\r\n// A 64x64 bevelled pixel tile in the tier colour. Unopened: a pixel \"?\" glyph. Opened: the awarded palette's\r\n// colours as bands (or a pixel star for skins/textures), so the tile itself shows what came out.\r\nexport function drawTierTile(ctx,tier,{colors=[],opened=false}={}){\r\n const base=TIER_COLORS[tier]||TIER_COLORS.uncommon,rect=(x,y,w,h,color)=>{ctx.fillStyle=color;ctx.fillRect(x,y,w,h);};\r\n ctx.clearRect(0,0,64,64);\r\n rect(0,0,64,64,shade(base,-120));rect(2,2,60,60,shade(base,70));rect(4,4,58,58,shade(base,-70));rect(4,4,56,56,base);\r\n rect(8,8,48,48,shade(base,-40));rect(10,10,44,44,shade(base,-95));\r\n if(opened&&colors.length){const band=Math.floor(44/colors.length);colors.forEach((color,i)=>rect(10,10+i*band,44,i===colors.length-1?44-i*band:band,color));}\r\n else{\r\n  const ink=opened?'#fff7df':shade(base,90),px=(x,y)=>rect(12+x*4,12+y*4,4,4,ink);\r\n  const glyph=opened?['....#.....','....#.....','...###....','#########.','.#######..','..#####...','..##.##...','.##...##..','.#.....#..','..........']:['..#####...','.##...##..','.##...##..','.....##...','....##....','....##....','..........','....##....','....##....','..........'];\r\n  glyph.forEach((row,y)=>[...row].forEach((cell,x)=>{if(cell==='#')px(x,y);}));\r\n }\r\n rect(4,4,56,2,shade(base,110));rect(4,4,2,56,shade(base,110));\r\n // Secret: an iridescent bevel, cyan/violet/magenta/gold pixels round the frame (CSS hue-rotates it on screen).\r\n if(tier==='secret'){const hues=['#3ff5ff','#b388ff','#ff4bd8','#ffd36a'];for(let i=0;i<14;i++){const c=hues[i%4],o=2+i*4;rect(o,2,4,2,c);rect(60,o,2,4,c);rect(62-o-4,60,4,2,hues[(i+2)%4]);rect(2,62-o-4,2,4,hues[(i+2)%4]);}}\r\n}\r\n// What an opened pack unlocked, as the plain items the reveal card (and the dialog's own result area) list.\r\nexport const unlocked=opened=>rewardSummary(opened).rewards.map(reward=>{const item=rewardSummary({reward,category:reward.category}),coach=COACHES.find(entry=>entry.id===reward.coachId)?.label||'your coach',detail=['color','palette','texture'].includes(reward.kind)?`${item.detail} for Original MYR5 and ${coach}`:`${item.detail} for ${coach}`;return {...reward,title:item.title,detail,colors:item.colors};});\r\nexport function mountRewardPacks(){\r\n const style=document.createElement('style');style.textContent=CSS;document.head.append(style);\r\n const launch=document.createElement('button');launch.type='button';launch.className='reward-pack-launch';launch.hidden=true;launch.innerHTML='<canvas width=\"64\" height=\"64\" aria-hidden=\"true\"></canvas><span></span>';document.body.append(launch);\r\n const overlay=document.createElement('dialog');overlay.className='reward-pack-dialog';overlay.setAttribute('aria-labelledby','pack-title');overlay.innerHTML='<section class=\"reward-pack-card\"><p class=\"eyebrow\">MYR5 • REWARD DROP</p><h2 id=\"pack-title\"></h2><canvas class=\"reward-pack-tile\" width=\"64\" height=\"64\" role=\"img\"></canvas><div class=\"reward-pack-result\" role=\"status\" aria-live=\"polite\"></div><div class=\"reward-pack-actions\"><button type=\"button\" data-open>Open pack</button><button type=\"button\" class=\"secondary\" data-close>Later</button></div></section>';document.body.append(overlay);\r\n const tile=overlay.querySelector('.reward-pack-tile'),result=overlay.querySelector('.reward-pack-result'),open=overlay.querySelector('[data-open]'),close=overlay.querySelector('[data-close]');let current=null,presentTimer=0;const presented=new Set();\r\n const available=()=>unopenedPacks();\r\n function update(){\r\n  const ids=available(),count=ids.length;\r\n  launch.hidden=!count||overlay.open;if(launch.hidden)return;\r\n  const tier=tierOf(ids[0]);launch.style.setProperty('--pack',TIER_COLORS[tier]);launch.dataset.tier=tier;drawTierTile(launch.querySelector('canvas').getContext('2d'),tier);\r\n  launch.querySelector('span').textContent=`${count} reward pack${count===1?'':'s'}`;\r\n  const bar=document.getElementById('coachDock')?.getBoundingClientRect();launch.style.bottom=bar?.height?Math.max(18,innerHeight-bar.top+12)+'px':'';\r\n }\r\n // Present a waiting pack by itself, once per pack per page load, but never over a camera set.\r\n function present(){\r\n  clearTimeout(presentTimer);const id=available().find(id=>!presented.has(id));if(!id||overlay.open)return;\r\n  if(document.body.dataset.tracking==='true'||document.body.dataset.cameraWorkout==='true'){presentTimer=setTimeout(present,1500);return;}\r\n  if(document.querySelector('dialog[open]:not(.reward-pack-dialog)')){presentTimer=setTimeout(present,500);return;}\r\n  // The starter quilt only appears when no dialog is open: let it come up first (up to 5 s after launch).\r\n  if(document.getElementById('portalHome')?.hidden!==false&&performance.now()<5000){presentTimer=setTimeout(present,250);return;}\r\n  presented.add(id);show(id);\r\n }\r\n function hide(){if(overlay.open)overlay.close();}\r\n function select(id){\r\n  current={kind:'reward-pack',id,tier:tierOf(id)};overlay.classList.remove('opened');overlay.style.setProperty('--pack',TIER_COLORS[current.tier]);overlay.dataset.tier=current.tier;\r\n  overlay.querySelector('h2').textContent=`${current.tier} pack`;tile.setAttribute('aria-label',`${current.tier} pack tile`);drawTierTile(tile.getContext('2d'),current.tier);\r\n  {const n=packSize(current);result.textContent=`${n} coach cosmetic${n===1?'':'s'} inside. Tap to open.`;};open.hidden=false;close.textContent='Later';\r\n }\r\n let pods=null;const preload=()=>pods??=import('./drop-pod-opening.mjs').catch(()=>null);\r\n function show(id){select(id);preload();launch.hidden=true;overlay.showModal();open.focus();}\r\n launch.onclick=()=>{const id=available()[0];if(id)show(id);};close.onclick=hide;overlay.addEventListener('close',()=>{current=null;update();});\r\n\r\n function render(opened){\r\n  const summary=rewardSummary(opened),revealType=rewardRevealType(opened,current.tier),revealTier=rewardRevealTier(opened,current.tier),revealColor=REWARD_COLORS[revealType]||TIER_COLORS[current.tier];overlay.dataset.tier=current.tier;overlay.dataset.rewardType=revealType;overlay.style.setProperty('--pack',revealColor);drawTierTile(tile.getContext('2d'),revealTier,{colors:summary.colors,opened:true});tile.setAttribute('aria-label',`${summary.title}, ${summary.detail}`);\r\n  overlay.classList.remove('opened');void tile.offsetWidth;overlay.classList.add('opened');\r\n  result.replaceChildren();\r\n  if(!summary.rewards.length)result.textContent='All cosmetics for your unlocked coaches are collected.';\r\n  for(const item of unlocked(opened)){\r\n   const title=document.createElement('strong'),kind=document.createElement('small');title.textContent=`${item.title} unlocked!`;kind.textContent=item.detail;result.append(title,kind);\r\n   if(item.colors.length){const swatches=document.createElement('div');swatches.className='reward-pack-swatches';for(const color of item.colors){const chip=document.createElement('i');chip.style.background=color;swatches.append(chip);}result.append(swatches);}\r\n  }\r\n  open.hidden=true;close.textContent='Done';close.focus();\r\n }\r\n // Open pack starts the full-screen drop-pod sequence; the pack is opened when the pod is tapped, and Open another moves to the next waiting pack.\r\n const sequence=pending=>{let openedResult=null;return {tier:pending.tier,hasNext:()=>available().some(id=>id!==pending.id),onExit:hide,revealType:()=>rewardRevealType(openedResult,pending.tier),revealTier:()=>rewardRevealTier(openedResult,pending.tier),revealColor:()=>REWARD_COLORS[rewardRevealType(openedResult,pending.tier)]||TIER_COLORS[pending.tier],\r\n  open:async()=>{const opened=await openRewardPackExclusive(pending);if(!opened)return null;openedResult=opened;if(current===pending)render(opened);return unlocked(opened);},\r\n  onNext:()=>{const id=available().find(id=>id!==pending.id);if(!id)return null;select(id);return sequence(current);}};\r\n };\r\n open.onclick=async()=>{\r\n  if(!current)return;const pending=current,module=await preload();if(current!==pending)return;\r\n  if(module){module.playDropPod(sequence(pending));return;}\r\n  // The sequence module could not load (offline without the update): fall back to the plain tile.\r\n  open.disabled=true;let opened;try{opened=await openRewardPackExclusive(pending);}finally{open.disabled=false;}if(current!==pending)return;if(!opened){result.textContent='Could not save this pack. Try again.';return;}\r\n  render(opened);\r\n };\r\n const onGrant=event=>{if(event.detail?.granted?.some(item=>item.kind==='reward-pack')){update();present();}};\r\n const onReady=event=>{update();present();};\n const onCleared=()=>{clearTimeout(presentTimer);hide();update();};\r\n window.addEventListener('myr5:performance-progress',update);window.addEventListener('myr5:battle-pass',onGrant);window.addEventListener('myr5:account-ready',onReady);window.addEventListener('myr5:account-cleared',onCleared);update();\r\n return ()=>{clearTimeout(presentTimer);hide();window.removeEventListener('myr5:performance-progress',update);window.removeEventListener('myr5:battle-pass',onGrant);window.removeEventListener('myr5:account-ready',onReady);window.removeEventListener('myr5:account-cleared',onCleared);launch.remove();overlay.remove();style.remove();};\r\n}\r\n","reward-packs.mjs":"// Packs contain coach-specific cosmetics. Rolls are committed before grants so a\r\n// retry repairs interrupted storage without rerolling or duplicating rewards.\r\nimport {colourRewardPool,textureRewardPool} from './battle-pass-rewards.mjs';\r\nimport * as ledger from './unlock-ledger.mjs';\r\nimport * as store from './creature/source/creator/unlock-store.ts';\r\nimport {unlockedCoachIds,performanceOwner,coachAccess} from './performance-progress.mjs';\r\nimport {PACK_SIZES,COSMETIC_PACK_ODDS} from './progression-rules.mjs';\r\nexport const PACK_ODDS=COSMETIC_PACK_ODDS;\r\nexport {PACK_SIZES};\r\n// Achievement Vault packs (id `reward-pack:secret:vault-<goal>`) are holographic secret packs with no 64-bit items (colour 75 / texture 25).\r\n// Size follows the goal's tier (legendary 3, rare 2; its first slot is then a texture). vault-store notes the goal tier at grant time so the\r\n// core never imports the vault goal list.\r\nexport const VAULT_PACK=Object.freeze({rare:2,legendary:3,odds:Object.freeze({secret:Object.freeze({color:75,'64-bit':0})})});\r\nexport const isVaultPack=item=>String(item?.id).includes(':vault-');\r\nconst VT_KEY='myr5-vault-pack-tier-v1';\r\nexport const noteVaultPack=(id,tier)=>{try{const d=JSON.parse(localStorage.getItem(VT_KEY)||'{}');if(d[id]!==tier){d[id]=tier;localStorage.setItem(VT_KEY,JSON.stringify(d));}}catch{/* private mode */}};\r\nconst vaultSize=id=>{try{return VAULT_PACK[JSON.parse(localStorage.getItem(VT_KEY)||'{}')[id]]||VAULT_PACK.rare;}catch{return VAULT_PACK.rare;}};\r\nexport const packSize=item=>isVaultPack(item)?vaultSize(item.id):PACK_SIZES[item.tier];\r\nconst KEY='myr5-opened-reward-packs-v2';\r\nconst ownerKey=()=>`${KEY}/${encodeURIComponent(performanceOwner())}`;\r\nconst safeRead=()=>{try{const data=JSON.parse(localStorage.getItem(ownerKey())||'{}');return data&&typeof data==='object'&&!Array.isArray(data)?data:{};}catch{return {};}};\r\nconst save=data=>{try{localStorage.setItem(ownerKey(),JSON.stringify(data));return true;}catch{return false;}};\r\nexport const packItem=(tier,id)=>({kind:'reward-pack',id,name:`${tier[0].toUpperCase()+tier.slice(1)} Pack`,tier,line:`Open for ${packSize({id,tier})} coach cosmetic${packSize({id,tier})===1?'':'s'}.`});\r\nconst unit=random=>{const value=random();if(!Number.isFinite(value))throw RangeError('Invalid random value.');return Math.min(1-Number.EPSILON,Math.max(0,value));};\r\nexport function rollCategory(tier,random=Math.random,table=PACK_ODDS){\r\n const odds=table[tier];if(!odds)throw Error('Unknown pack tier');\r\n const roll=unit(random)*100;\r\n return roll<odds.color?'color':roll<odds.color+odds['64-bit']?'64-bit':'texture';\r\n}\r\nconst pools={color:colourRewardPool(),texture:textureRewardPool()};\r\nexport function setTexturePool(items){pools.texture=items.filter(item=>item.kind==='texture').map(({kind,id,name})=>({kind,id,name}));}\r\nconst identity=reward=>store.cosmeticId(reward.coachId,reward.id);\r\nexport const hasCosmetic=reward=>reward.kind==='boss-skin'?ledger.isGranted('boss-skin',identity(reward)):store.isGranted(reward.kind,reward.id,reward.coachId);\r\nconst categoryPool=(category,coaches)=>coaches.flatMap(coachId=>category==='64-bit'?[{kind:'boss-skin',id:`${coachId}-skin`,name:'64-bit Pixel Finish',coachId}]:pools[category].map(item=>({...item,coachId})));\r\nexport function remainingCosmetics({coaches=unlockedCoachIds()}={}){\r\n const owned=[...new Set(coaches)].filter(coach=>coachAccess(coach));\r\n const grants=Object.fromEntries(['color','palette','texture'].map(kind=>[kind,new Set(store.ownerGrantedIds(kind))]));grants['boss-skin']=new Set(ledger.grantedIds('boss-skin'));\r\n return ['color','64-bit','texture'].flatMap(category=>categoryPool(category,owned).map(reward=>({...reward,category}))).filter(reward=>!grants[reward.kind].has(identity(reward)));\r\n}\r\nconst rewardsOf=opened=>opened?.rewards|| (opened?.reward?[{...opened.reward,category:opened.category}]:[]);\r\nexport const openedPack=id=>{\r\n const current=safeRead();if(current[id])return current[id];\r\n // Earlier one-item packs keep their saved roll; migrate it onto the saved coach.\r\n try{const owner=globalThis.myr5AuthenticatedAccount?.user?.id;if(!owner)return null;const legacy=JSON.parse(localStorage.getItem(`myr5-opened-reward-packs-v1/${owner}`)||'{}')[id];if(!legacy?.reward)return null;const preferred=store.currentCosmeticCoach(),coaches=unlockedCoachIds(),coachId=coaches.includes(preferred)?preferred:coaches[0];if(!coachId)return null;const reward={...legacy.reward,...(legacy.reward.kind==='boss-skin'?{id:`${coachId}-skin`}:{}),coachId,category:legacy.category};const result={...legacy,reward,rewards:[reward],legacy:true};return save({...current,[id]:result})?result:null;}catch{return null;}\r\n};\r\nexport const unopenedPacks=()=>ledger.grantedIds('reward-pack').filter(id=>{const opened=openedPack(id);return !opened||rewardsOf(opened).some(reward=>!hasCosmetic(reward));});\r\nfunction grantReward(reward){\r\n if(!coachAccess(reward.coachId))return false;\r\n if(reward.kind==='boss-skin')ledger.grantUnlock(reward.kind,identity(reward));\r\n else store.grantUnlock(reward.kind,reward.id,reward.coachId);\r\n return hasCosmetic(reward);\r\n}\r\nexport function openRewardPack(item,{random=Math.random}={}){\r\n if(item?.kind!=='reward-pack'||!PACK_ODDS[item.tier]||!ledger.isGranted('reward-pack',item.id))return null;\r\n const previous=openedPack(item.id);\r\n if(previous)return rewardsOf(previous).every(grantReward)?previous:null;\r\n const coaches=unlockedCoachIds().filter(coach=>coachAccess(coach));if(!coaches.length)return null;\r\n const rewards=[];const selected=new Set(),unowned=remainingCosmetics({coaches});\r\n const vault=isVaultPack(item);\r\n for(let slot=0;slot<packSize(item);slot++){\r\n  const rolled=vault&&vaultSize(item.id)===VAULT_PACK.legendary&&slot===0?'texture':rollCategory(item.tier,random,vault?VAULT_PACK.odds:PACK_ODDS);\r\n  // Preserve category odds until that category is exhausted; then award another\r\n  // unowned category rather than a duplicate while the collection is incomplete.\r\n  const order=[rolled,...['color','64-bit','texture'].filter(category=>category!==rolled&&!(vault&&category==='64-bit'))];\r\n  let category=rolled,choices=[];\r\n  for(const candidate of order){const available=unowned.filter(reward=>reward.category===candidate&&!selected.has(identity(reward)+':'+reward.kind));if(available.length){category=candidate;choices=available;break;}}\r\n  if(!choices.length)break; // Complete collection: do not manufacture duplicates.\r\n  const reward={...choices[Math.floor(unit(random)*choices.length)],category};\r\n  selected.add(identity(reward)+':'+reward.kind);rewards.push(reward);\r\n  // A non-original coach's material reward also unlocks that material on MYR5.\r\n  // Reserve the inherited MYR5 slot for this pack so it cannot roll twice.\r\n  if(reward.coachId!=='myr5'&&reward.kind!=='boss-skin')selected.add(store.cosmeticId('myr5',reward.id)+':'+reward.kind);\r\n }\r\n const result={tier:item.tier,rewards,category:rewards[0]?.category||'complete',reward:rewards[0]||null,complete:rewards.length===0};\r\n const current=safeRead();if(current[item.id])return current[item.id];\r\n if(!save({...current,[item.id]:result}))return null;\r\n return rewards.every(grantReward)?result:null;\r\n}\r\n// Cross-tab UI openings serialize the saved roll and grant repair when Web Locks\r\n// are available. The synchronous primitive also remains useful offline/in tests.\r\nexport async function openRewardPackExclusive(item,options={}){\r\n try{const owner=performanceOwner(),run=()=>performanceOwner()===owner?openRewardPack(item,options):null;\r\n return await (globalThis.navigator?.locks?.request?globalThis.navigator.locks.request(`${KEY}/${owner}/${item?.id}`,run):run());}catch{return null;}\r\n}\r\n// The final cosmetic level is a collection completion reward. Only currently\r\n// unlocked coaches qualify; coaches earned later remain collectible afterwards.\r\nexport function completeCosmeticCollection(){\r\n const remaining=remainingCosmetics();\r\n const materials=remaining.filter(reward=>reward.kind!=='boss-skin'),skins=remaining.filter(reward=>reward.kind==='boss-skin');\r\n store.grantUnlocks(materials);ledger.grantUnlocks('boss-skin',skins.map(identity));\r\n const ungranted=remainingCosmetics().length;return {granted:remaining.length-ungranted,remaining:ungranted};\r\n}\r\nexport function grantDailyPack({date=new Date(),account=globalThis.myr5AuthenticatedAccount}={}){\n // Legacy callers stay harmless. Existing earned packs remain owned.\n return null;\n}\r\n","robot-audio.mjs":"// Every spoken cue uses the approved voice pack, including compound sentences.\r\nimport {BUILD_ID} from './release-build.mjs';\r\nimport {coachFetch,coachOnline} from './coach-net.mjs';\r\nexport const VOICE_MANIFEST='/voice/manifest.json?v='+BUILD_ID;\r\nexport const VOICE_CACHE='myr5-voice-approved-v2';\r\n// Local playback treatments of approved clips; no OS voice or network speech service.\r\nexport const COACH_VOICE_VARIANTS=Object.freeze({\r\n robot:{label:'Robot',rate:1,detune:0,filter:null},\r\n clear:{label:'Clear',rate:1.04,detune:0,filter:'clear'},\r\n warm:{label:'Warm',rate:.96,detune:-250,filter:'warm'},\r\n light:{label:'Light',rate:1.10,detune:250,filter:'light'}\r\n});\r\nexport const DEFAULT_COACH_VOICE='robot';\r\nexport function voicePhrases(text,phrases){\r\n text=text.trim();if(phrases[text])return [text];\r\n const parts=(text.match(/[^.!?]+[.!?]+(?:\\s|$)|[^.!?]+$/g)||[]).map(s=>s.trim()).filter(Boolean);\r\n return parts.length&&parts.every(s=>phrases[s])?parts:[];\r\n}\r\nexport class RobotAudio {\r\n constructor(onMode=()=>{}){this.onMode=onMode;this.context=null;this.cache=new Map();this.cacheBytes=0;this.current=null;this.generation=0;this.variant=DEFAULT_COACH_VOICE;}\r\n setVariant(id){if(!COACH_VOICE_VARIANTS[id])return false;this.variant=id;return true;}\r\n get mode(){return COACH_VOICE_VARIANTS[this.variant]?.label??COACH_VOICE_VARIANTS[DEFAULT_COACH_VOICE].label;}\r\n unlock(){const Context=globalThis.AudioContext||globalThis.webkitAudioContext;if(!Context)return false;try{this.context??=new Context();if(this.context.state==='suspended')this.context.resume().catch(()=>{});return true;}catch{return false;}}\r\n stop(){this.generation++;const current=this.current;this.current=null;if(current){current.abort?.abort();try{current.source?.stop();}catch{}current.finish?.();}this.onMode('Voice: '+this.mode);}\r\n async play(text){\r\n  if(!this.unlock())return false;\r\n  const run=++this.generation,abort=new AbortController();this.current={abort};\r\n  try{\r\n   const got=this.manifest?null:await coachFetch(VOICE_MANIFEST,{signal:abort.signal},{timeoutMs:5000,local:true});\r\n   if(got){if(!got.ok)throw Error('Voice pack unavailable');this.manifest=got.data;}\r\n   const manifest=await this.manifest,parts=voicePhrases(text,manifest.phrases);\r\n   if(!parts.length)throw Error('No approved clip');\r\n   for(const phrase of parts){\r\n    if(run!==this.generation)return true;\r\n    let buffer=this.cache.get(phrase);\r\n    if(!buffer){\r\n     const clip=await coachFetch(manifest.phrases[phrase],{signal:abort.signal},{timeoutMs:5000,parse:'arrayBuffer',local:true});\r\n     if(!clip.ok)throw Error('Voice unavailable');const data=clip.data;if(run!==this.generation)return true;\r\n     buffer=await this.context.decodeAudioData(data);if(run!==this.generation)return true;\r\n     const bytes=buffer.length*buffer.numberOfChannels*4;\r\n     while(this.cache.size&&this.cacheBytes+bytes>12*1024*1024){const key=this.cache.keys().next().value,old=this.cache.get(key);this.cacheBytes-=old.length*old.numberOfChannels*4;this.cache.delete(key);}\r\n     this.cache.set(phrase,buffer);this.cacheBytes+=bytes;\r\n    }\r\n    if(this.context.state!=='running'){this.onMode('Tap Test voice to enable sound');this.current=null;return false;}\r\n     const profile=COACH_VOICE_VARIANTS[this.variant]??COACH_VOICE_VARIANTS[DEFAULT_COACH_VOICE];\r\n     const source=this.context.createBufferSource();source.buffer=buffer;if(source.playbackRate)source.playbackRate.value=profile.rate;if(source.detune)source.detune.value=profile.detune;\r\n     const nodes=this.makeVoiceChain(profile),chain=[source,...nodes,this.context.destination];\r\n     for(let i=0;i<chain.length-1;i++)chain[i].connect(chain[i+1]);\r\n     this.onMode('Voice: '+profile.label);\r\n     await new Promise(resolve=>{let done=false;const finish=()=>{if(done)return;done=true;source.disconnect();nodes.forEach(node=>node.disconnect());if(run===this.generation)this.current={abort};resolve();};this.current={source,abort,finish};source.onended=finish;source.start();});\r\n   }\r\n   if(run===this.generation)this.current=null;return true;\r\n  }catch{if(run===this.generation){this.current=null;this.onMode(coachOnline()?'Voice unavailable · captions on':'Offline · captions on, voice returns when you reconnect');return false;}return true;}\r\n }\r\n makeVoiceChain(profile){\r\n  const ctx=this.context,chain=[];\r\n  if(!profile.filter)return chain;\r\n  if(typeof ctx.createBiquadFilter!=='function')return chain;\r\n  const filter=(type,frequency,gain=0,q=0.7)=>{const node=ctx.createBiquadFilter();node.type=type;node.frequency.value=frequency;node.Q.value=q;if(node.gain)node.gain.value=gain;chain.push(node);};\r\n  if(profile.filter==='robot'){\r\n   filter('bandpass',1450,0,0.75);\r\n   if(ctx.createWaveShaper){const shaper=ctx.createWaveShaper();shaper.curve=Float32Array.from({length:257},(_,i)=>{const x=i/128-1;return Math.tanh(2.2*x);});shaper.oversample='2x';chain.push(shaper);}\r\n  }else if(profile.filter==='warm'){\r\n   filter('lowshelf',220,3.5);filter('highshelf',3600,-2.5);\r\n  }else if(profile.filter==='light'){\r\n   filter('highpass',115);filter('highshelf',2400,3);\r\n  }else{\r\n   filter('highpass',75);filter('peaking',2800,1.5,0.8);\r\n  }\r\n  return chain;\r\n }\r\n}\r\n","robot-speech.cjs":"// Local formant speech. No model download, cloud service, microphone, or GPU.\r\nconst {execFile}=require('node:child_process');\r\nconst fs=require('node:fs');\r\nconst ENGINE='C:/Program Files/eSpeak NG/espeak-ng.exe';\r\n// Keep the synthetic timbre, but retain sentence stress and avoid choppy word gaps.\r\nconst PROFILE={voice:'en-us',wordsPerMinute:125,pitch:52,pitchRange:38,wordGap:1};\r\nconst cache=new Map(),pending=new Map();let cacheBytes=0;\r\nconst MAX_CACHE=12*1024*1024;\r\nfunction synthesize(text){\r\n if(typeof text!=='string'||!text.trim()||text.length>600||/[\\x00-\\x08\\x0b-\\x1f]/.test(text))return Promise.reject(new Error('Invalid speech text'));\r\n text=text.trim();if(cache.has(text))return Promise.resolve(cache.get(text));if(pending.has(text))return pending.get(text);\r\n if(pending.size>=4)return Promise.reject(new Error('Speech busy'));\r\n const task=new Promise((resolve,reject)=>{\r\n  // Arguments are passed without a shell. Text is never interpreted as markup.\r\n  const args=['--stdout','-b','1','-v',PROFILE.voice,'-s',String(PROFILE.wordsPerMinute),'-p',String(PROFILE.pitch),'-P',String(PROFILE.pitchRange),'-g',String(PROFILE.wordGap),'--stdin'];\r\n  const child=execFile(ENGINE,args,{encoding:'buffer',windowsHide:true,timeout:5000,maxBuffer:5*1024*1024},(error,wav)=>{\r\n   if(error)return reject(new Error('Robot voice unavailable'));\r\n   if(wav.length<44||wav.toString('ascii',0,4)!=='RIFF')return reject(new Error('Invalid speech audio'));\r\n   // eSpeak's stdout uses streaming placeholder sizes; give phone decoders exact sizes.\r\n   wav.writeUInt32LE(wav.length-8,4);let found=false;\r\n   for(let offset=12;offset+8<=wav.length;){const size=wav.readUInt32LE(offset+4);if(wav.toString('ascii',offset,offset+4)==='data'){wav.writeUInt32LE(wav.length-offset-8,offset+4);found=true;break;}offset+=8+size+(size%2);}\r\n   if(!found)return reject(new Error('Missing speech samples'));\r\n   while(cache.size&&cacheBytes+wav.length>MAX_CACHE){const key=cache.keys().next().value;cacheBytes-=cache.get(key).length;cache.delete(key);}\r\n   cache.set(text,wav);cacheBytes+=wav.length;resolve(wav);\r\n  });\r\n  child.stdin.on('error',()=>{});child.stdin.end(text,'utf8');\r\n }).finally(()=>pending.delete(text));\r\n pending.set(text,task);return task;\r\n}\r\nmodule.exports={synthesize,PROFILE,available:()=>fs.existsSync(ENGINE)};\r\n","rope.mjs":"// Tiny verlet rope for the FULL workout power cables. Pure maths, no DOM.\r\n// TUNING KNOBS -- real phones need tuning; change only here.\r\nexport const ROPE={\r\n segments:14,        // points per cable\r\n gravityScale:2600,  // px/s^2 at a full 1.0 gravity vector\r\n damping:.97,        // velocity kept per step (lower = heavier air)\r\n iterations:8,       // constraint passes per step\r\n stiffness:.9,       // 0..1 how hard each pass pulls segments back to length\r\n sway:.07,           // idle sway (fraction of gravity) when no tilt reading exists\r\n swayHz:.45,\r\n fanDeg:8,           // loose cables fan out in two rings, this many degrees apart, from straight down toward the left\r\n looseLength:100,     // px of a loose cable\r\n looseStagger:70,    // extra px on every other cable so plugs do not stack\r\n plugSlack:1.06,     // plugged cable length = distance * this (it sags under gravity)\r\n slackSpread:.025,   // extra slack per cable (i%5) so the bundle in the gutter fans out a little\r\n gutter:64,          // px of the right-hand cord channel plugged cables live in\r\n settleSteps:90,     // steps run at once for the static (reduced motion) pose\r\n};\r\n\r\nexport function makeRope(ax,ay,length,n=ROPE.segments){\r\n return {length,pts:Array.from({length:n},(_,i)=>{const y=ay+length*i/(n-1);return {x:ax,y,px:ax,py:y};})};\r\n}\r\n\r\n/** One step. g = {gx,gy} (unit-ish, +y down). anchor pinned; end pinned when given (plugged / dragged). */\r\nexport function stepRope(rope,dt,g,{anchor,end=null,length=rope.length}={},knobs=ROPE){\r\n const p=rope.pts,n=p.length;rope.length=length;const seg=length/(n-1),ax=g.gx*knobs.gravityScale*dt*dt,ay=g.gy*knobs.gravityScale*dt*dt;\r\n for(let i=1;i<n;i++){const q=p[i],vx=(q.x-q.px)*knobs.damping,vy=(q.y-q.py)*knobs.damping;q.px=q.x;q.py=q.y;q.x+=vx+ax;q.y+=vy+ay;}\r\n const pin=()=>{Object.assign(p[0],{x:anchor.x,y:anchor.y,px:anchor.x,py:anchor.y});if(end)Object.assign(p[n-1],{x:end.x,y:end.y,px:end.x,py:end.y});};\r\n pin();\r\n for(let it=0;it<knobs.iterations;it++){\r\n  for(let i=0;i<n-1;i++){\r\n   const a=p[i],b=p[i+1],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1e-6,k=(d-seg)/d*knobs.stiffness;\r\n   const wa=i===0?0:1,wb=i===n-2&&end?0:1,w=wa+wb;if(!w)continue;\r\n   a.x+=dx*k*wa/w;a.y+=dy*k*wa/w;b.x-=dx*k*wb/w;b.y-=dy*k*wb/w;\r\n  }\r\n  pin();\r\n }\r\n return p;\r\n}\r\n\r\n/** Rotate a gravity vector by deg degrees (per-cable fan). */\r\nexport const rotate=(g,deg)=>{const a=deg*Math.PI/180,c=Math.cos(a),s=Math.sin(a);return {gx:g.gx*c-g.gy*s,gy:g.gx*s+g.gy*c};};\r\n\r\n/** Smooth SVG path through the points (quadratic midpoints). */\r\nexport function ropePath(pts){\r\n let d=`M${pts[0].x.toFixed(1)} ${pts[0].y.toFixed(1)}`;\r\n for(let i=1;i<pts.length-1;i++){const m={x:(pts[i].x+pts[i+1].x)/2,y:(pts[i].y+pts[i+1].y)/2};d+=`Q${pts[i].x.toFixed(1)} ${pts[i].y.toFixed(1)} ${m.x.toFixed(1)} ${m.y.toFixed(1)}`;}\r\n const l=pts[pts.length-1];return d+`L${l.x.toFixed(1)} ${l.y.toFixed(1)}`;\r\n}\r\n","scheduler/service.mjs":"import {runReminders,subscriptionInput} from '../server/push.mjs';\r\nimport {reminderInput,fail} from '../server/domain.mjs';\r\nimport {emailSubscription,emailLinkAction,runReleaseEmails} from '../server/release-email.mjs';\r\nimport {syncTrainingStatus} from '../server/reminder-plan.mjs';\r\nimport {runReleasePush} from '../server/release-push.mjs';\r\nimport {epochFencedBatch,reconcileRemoteEpoch} from '../server/remote-epochs.mjs';\r\nimport {remoteAccountDeletionStatements} from '../server/remote-deletion-data.mjs';\r\nimport {remoteAccountOperation} from '../server/remote-account-operations.mjs';\r\nimport {validatedReminderProof} from '../server/remote-reminders.mjs';\r\n\r\nconst json=(data,status=200)=>new Response(JSON.stringify(data),{status,headers:{'Content-Type':'application/json','Cache-Control':'no-store'}});\r\nasync function authorized(request,env){\r\n const token=request.headers.get('Authorization')||'';if(!env.REMINDER_SERVICE_TOKEN||token.length>200)return false;\r\n const hash=value=>crypto.subtle.digest('SHA-256',new TextEncoder().encode(value));\r\n const [a,b]=await Promise.all([hash(token),hash(`Bearer ${env.REMINDER_SERVICE_TOKEN}`)]);\r\n let diff=0;const left=new Uint8Array(a),right=new Uint8Array(b);for(let i=0;i<left.length;i++)diff|=left[i]^right[i];return diff===0;\r\n}\r\nasync function body(request){const text=await request.text();if(text.length>60000)fail('Too much reminder data.',413);try{return JSON.parse(text);}catch{fail('Invalid reminder data.');}}\r\nfunction proofFromHeaders(request,user){\r\n const epoch=request.headers.get('X-Coach-Data-Epoch'),through=request.headers.get('X-Coach-Deleted-Through');\r\n if(epoch===null||through===null)throw Object.assign(Error('Account generation is required.'),{status:428,code:'epoch_required'});\r\n if(!/^[1-9][0-9]*$/.test(epoch)||!/^(0|[1-9][0-9]*)$/.test(through))fail('Invalid account generation.',422);\r\n return validatedReminderProof(user,{ownerId:user,currentDataEpoch:Number(epoch),deletedThroughEpoch:Number(through)});\r\n}\r\nasync function importExisting(request,env,user,proof){\r\n const input=await body(request);if(!Array.isArray(input.reminders)||input.reminders.length>16||!Array.isArray(input.subscriptions)||input.subscriptions.length>32)fail('Invalid reminder import.');\r\n const database=env.DB,key='import:'+JSON.stringify([user,proof.currentDataEpoch]);\r\n const priorKey=proof.currentDataEpoch===1?'import:'+user:key;\r\n if(await database.prepare('SELECT value FROM system WHERE key=? OR key=?').bind(key,priorKey).first())return {imported:true};\r\n const statements=[];\r\n for(const row of input.reminders){\r\n  const r=reminderInput({id:row.id,kind:row.kind,time:row.time,timezone:row.timezone,enabled:!!row.enabled,quietStart:row.quiet_start,quietEnd:row.quiet_end,tone:row.tone,daysPerWeek:row.days_per_week});\r\n  statements.push(database.prepare('INSERT INTO reminders(id,user_id,kind,time,timezone,enabled,quiet_start,quiet_end,tone,days_per_week) SELECT ?,?,?,?,?,?,?,?,?,? WHERE NOT EXISTS(SELECT 1 FROM system WHERE key=? OR key=?) ON CONFLICT(id) DO NOTHING').bind(r.id,user,r.kind,r.time,r.timezone,r.enabled,r.quietStart,r.quietEnd,r.tone,r.daysPerWeek,key,priorKey));\r\n }\r\n for(const item of input.subscriptions){const s=subscriptionInput(item);statements.push(database.prepare('INSERT INTO subscriptions(endpoint,user_id,data,created_at) SELECT ?,?,?,? WHERE NOT EXISTS(SELECT 1 FROM system WHERE key=? OR key=?) ON CONFLICT(endpoint) DO NOTHING').bind(s.endpoint,user,JSON.stringify(s),Date.now(),key,priorKey));}\r\n statements.push(database.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO NOTHING').bind(key,String(Date.now())));\r\n await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:proof.currentDataEpoch,now:Date.now(),statements});return {imported:true};\r\n}\r\nexport default {\r\n async fetch(request,env){\r\n  try{\r\n   const url=new URL(request.url),path=url.pathname,method=request.method;\r\n   if(path==='/health'&&method==='GET'){const tick=await env.DB.prepare(\"SELECT value FROM system WHERE key='scheduler_tick'\").first();return json({ok:true,service:'MYR5 reminders',configured:!!env.VAPID_PRIVATE_KEY&&!!env.VAPID_PUBLIC_KEY,schedulerActive:!!tick&&Date.now()-Number(tick.value)<300000});}\r\n   if(!await authorized(request,env))return json({error:'Unauthorized.'},401);\r\n   if(path==='/internal/status'&&method==='GET'){const tick=await env.DB.prepare(\"SELECT value FROM system WHERE key='scheduler_tick'\").first();return json({configured:!!env.VAPID_PRIVATE_KEY&&!!env.VAPID_PUBLIC_KEY,publicKey:env.VAPID_PUBLIC_KEY||null,schedulerActive:!!tick&&Date.now()-Number(tick.value)<300000,lastRun:tick?Number(tick.value):null});}\r\n   // Token actions atomically match the currently stored unique token. No pseudo-owner epoch.\r\n   if(/^\\/internal\\/release-email\\/(confirm|unsubscribe)$/.test(path)&&method==='POST'){const input=await body(request);return json(await emailLinkAction(env,path.split('/').at(-1),input.token));}\r\n   const user=request.headers.get('X-Coach-User');if(!user||user.length>512||user.trim()!==user||/[\\r\\n]/.test(user))return json({error:'Missing account.'},401);\r\n   const allowed=(path==='/internal/account-reconcile'&&method==='POST')||(path==='/internal/training-status'&&method==='POST')||(path==='/internal/import'&&method==='POST')||(path==='/api/updates/subscription'&&['GET','POST','DELETE'].includes(method))||(path==='/api/reminders'&&['GET','POST'].includes(method))||(path==='/api/reminders/plan'&&['GET','PUT'].includes(method))||(/^\\/api\\/reminders\\/[a-f0-9-]{36}$/.test(path)&&['PUT','PATCH','DELETE'].includes(method))||(/^\\/api\\/push\\/(subscribe|unsubscribe|test)$/.test(path)&&method==='POST')||(path==='/api/export'&&method==='GET');\r\n   if(!allowed)return json({error:'Not found.'},404);\r\n   const proof=proofFromHeaders(request,user),ack=await reconcileRemoteEpoch(env.DB,{...proof,now:Date.now(),deletions:remoteAccountDeletionStatements(env.DB,user)});\r\n   if(path==='/internal/account-reconcile')return json({ownerId:ack.ownerId,currentDataEpoch:ack.currentDataEpoch,deletedThroughEpoch:ack.deletedThroughEpoch});\r\n   if(ack.currentDataEpoch!==proof.currentDataEpoch)throw Object.assign(Error('Account generation changed.'),{status:409,code:'target_epoch_mismatch'});\r\n   if(path==='/internal/training-status')return json(await syncTrainingStatus(env.DB,user,await body(request),Date.now(),{dataEpoch:proof.currentDataEpoch}));\r\n   if(path==='/internal/import')return json(await importExisting(request,env,user,proof));\r\n   if(path==='/api/updates/subscription')return json(await emailSubscription(env,user,method,method==='POST'?await body(request):{},Date.now(),{dataEpoch:proof.currentDataEpoch}));\r\n   return json(await remoteAccountOperation(request,env,user,proof.currentDataEpoch));\r\n  }catch(error){\r\n   const status=error.status||(error.code==='target_epoch_mismatch'?409:error.code==='remote_epoch_busy'?503:500);\r\n   return json({error:status===500?'Could not complete the reminder request.':error.message,...(typeof error.code==='string'?{code:error.code}:{})},status);\r\n  }\r\n },\r\n // Scheduled senders retain their captured source epoch through claims and callbacks.\r\n async scheduled(event,env,ctx){\r\n  ctx.waitUntil((async()=>{const result=await runReminders(env);if(result.failed)throw Error(`${result.failed} reminder deliveries failed`);})());\r\n  ctx.waitUntil((async()=>{const result=await runReleaseEmails(env);if(result.failed)throw Error(`${result.failed} release email deliveries failed`);})());\r\n  ctx.waitUntil((async()=>{const result=await runReleasePush(env);if(result.failed)throw Error(`${result.failed} update notification deliveries failed`);})());\r\n }\r\n};\r\n","scheduler/worker.mjs":"// Kept as the stable scheduler entry point for older setup instructions.\r\nexport {default} from './service.mjs';\r\n","scheduler/wrangler.jsonc":"{\r\n\t\"name\": \"myr5-coach-reminders\",\r\n\t\"main\": \"service.mjs\",\r\n\t\"compatibility_date\": \"2026-05-15\",\r\n\t\"triggers\": {\r\n\t\t\"crons\": []\r\n\t},\r\n\t\"vars\": {\r\n\t\t\"VAPID_SUBJECT\": \"https://myr5-coach.ianmyersrocks97.chatgpt.site\",\r\n\t\t\"RELEASE_ORIGIN\": \"https://myr5.mominc.online\",\r\n\t\t\"RELEASE_EMAIL_FROM\": \"dispatch@mominc.online\"\r\n\t},\r\n\t\"observability\": {\r\n\t\t\"enabled\": true\r\n\t},\r\n\t\"account_id\": \"f35c131b47d223ae301a8b577d6e2d59\",\r\n\t\"workers_dev\": true,\r\n\t\"preview_urls\": false,\r\n\t\"d1_databases\": [\r\n\t\t{\r\n\t\t\t\"binding\": \"DB\",\r\n\t\t\t\"database_name\": \"myr5-coach-reminders\",\r\n\t\t\t\"database_id\": \"3edf94f0-2175-41d1-9b4f-98e9cfe95945\"\r\n\t\t}\r\n\t]\r\n}\r\n","scoreboard-domain.mjs":"import {GROUP_EXERCISES} from './exercise-library.mjs';\r\nexport const GROUP_INKS={chest:'#a32b49',legs:'#2356a0',hips:'#754094',core:'#21715c',shoulders:'#95460e',balance:'#326d30',yoga:'#76458b',stances:'#374a7d',boxing:'#a33125',cardio:'#086e7c'};\r\nexport const scoreUnit=exercise=>exercise.kind==='hold'?'sec held':exercise.kind==='pace'?'sec active':exercise.kind==='steps'?'knee lifts':'reps';\r\nexport const displayScore=value=>Number.isFinite(value)?String(Math.floor(value)):'—';\r\nexport function comparisonRows(group,members=[]){\r\n return (GROUP_EXERCISES[group]||[]).slice().reverse().map(exercise=>{\r\n  const values=Array.from({length:3},(_,slot)=>{const record=members[slot]?.items?.find(item=>item.mode===exercise.id);return record&&record.sets>0&&Number.isFinite(Number(record.best))?Math.floor(Number(record.best)):null;});\r\n  const maximum=Math.max(1,...values.filter(v=>v!==null));\r\n  return {exercise,unit:scoreUnit(exercise),bars:values.map((value,slot)=>{const rank=value===null?null:1+values.filter(v=>v!==null&&v>value).length;return {slot,value,rank,medal:rank===1?'gold':rank===2?'silver':rank===3?'bronze':null,height:value===null?0:Math.max(0,value)/maximum*100};})};\r\n });\r\n}\r\n","scoreboard.css":"/* Extend the existing dry-erase board and its marker controls. */\r\n#accountPanel{width:min(1060px,calc(100vw - 22px));--marker:#a32b49;padding-bottom:22px;scroll-padding-bottom:120px}\r\n#accountPanel [hidden]{display:none!important}#accountPanel h2{font-size:clamp(30px,5vw,43px)}\r\n#accountPanel .crew-invites{padding:0 0 18px;margin:0 0 18px;border-bottom:2px solid #82919f70}#accountPanel .crew-invites h3{font:28px/1.2 BoardHand2,cursive;color:#304663;margin:0 0 12px}\r\n.scoreboard-crew{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin:8px 0 12px}.crew-place{display:flex;align-items:center;flex-direction:column;min-width:0;gap:5px;padding:10px 5px;background:#e5e9eb66;border:1px dashed #7e8f9e;border-radius:5px}\r\n.crew-head{height:72px;width:72px;display:grid;place-items:center;border:2px solid #778d9c;border-radius:5px;background:#e7deed;color:#61768a;font:32px/1 Arial,sans-serif;flex:none}.crew-head canvas{width:64px;height:64px;image-rendering:pixelated}.crew-place strong{font:700 16px/1.3 Arial,sans-serif;color:#2e3e56;overflow-wrap:anywhere;text-align:center}.crew-place-label{font:13px/1.3 Arial,sans-serif;color:#536373}\r\n#accountPanel .crew-remove{font:14px/1.2 Arial,sans-serif;min-height:44px;border:0;box-shadow:none;background:transparent;text-decoration:underline;padding:5px;color:#80503d}\r\n#accountPanel #crewInviteControls summary{font:21px/1.4 BoardHand0,cursive;min-height:44px;padding:5px 0}#accountPanel #crewInviteControls p{font:16px/1.5 Arial,sans-serif}#accountPanel #crewInviteControls button{font:16px/1.3 Arial,sans-serif;margin:6px 7px 8px 0}#accountPanel #crewInviteControls label{font:16px/1.4 Arial,sans-serif}#accountPanel #crewInviteControls input{font:16px/1.5 monospace;width:100%;padding:12px 8px;min-height:44px}#crewJoinForm{margin:15px 0 8px;border-top:1px solid #9ba7b6;padding-top:14px}#accountPanel #crewStatus{font:15px/1.5 Arial,sans-serif;margin:8px 0 0}#crewStatus:empty{display:none}\r\n#accountPanel .progress-summary{padding-bottom:12px}#accountPanel #accountLevel{font-size:25px}#accountPanel #accountSets{font-size:18px}\r\n.scoreboard-heading{display:flex;align-items:center;justify-content:space-between;gap:15px;flex-wrap:wrap;border-bottom:3px solid var(--marker);margin-top:22px;padding-bottom:12px;color:var(--marker)}#accountPanel .scoreboard-heading h3{margin:0;font:36px/1.1 BoardHand2,cursive;color:var(--marker)}#accountPanel #scoreboardSubtitle{margin:4px 0 0;font:16px/1.4 Arial,sans-serif;color:var(--marker)}.medal-key{display:flex;gap:7px;flex-wrap:wrap}.medal-key span{font:700 12px/1.3 Arial,sans-serif;padding:5px 7px;border:1px solid #87919b;border-radius:3px;color:#253240}.medal-key [data-medal=gold]{background:#e7c666}.medal-key [data-medal=silver]{background:#d2dde3}.medal-key [data-medal=bronze]{background:#cd9b78}\r\n#boardCanvas{position:relative}#accountPanel #workoutList{display:block;position:relative;color:var(--marker);min-height:220px}#accountPanel #recordsStatus{font:14px/1.5 Arial,sans-serif;margin:10px 0}\r\n.score-axis{font:700 14px/1.5 Arial,sans-serif;color:var(--marker);text-transform:uppercase;letter-spacing:.6px}#accountPanel .score-caption{font:13px/1.5 Arial,sans-serif;color:#596878;margin:4px 0 12px}\r\n.score-row{display:grid;grid-template-columns:minmax(100px,1.1fr) minmax(0,2fr);gap:15px;align-items:center;padding:15px 0 14px;border-bottom:2px solid color-mix(in srgb,var(--marker) 25%,transparent)}.score-exercise{border-left:3px solid var(--marker);padding-left:10px}.score-level{font:700 12px/1.4 Arial,sans-serif;letter-spacing:.8px}.score-exercise h4{font:24px/1.1 BoardHand2,cursive;color:var(--marker);margin:6px 0}.score-unit{font:13px/1.4 Arial,sans-serif;color:#536373}\r\n.score-pillars{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px;align-self:stretch}.score-pillar{display:flex;flex-direction:column;text-align:center;min-width:0;color:#344352}.score-value{font:700 24px/1.2 BoardHand2,cursive;font-variant-numeric:tabular-nums;color:var(--marker)}.pillar-track{height:72px;display:flex;align-items:flex-end;justify-content:center;background:repeating-linear-gradient(to top,transparent 0 23px,#9eabb92a 23px 24px);border-bottom:2px solid var(--marker);margin-top:5px}.pillar-bar{display:block;width:min(45px,90%);height:var(--bar-height);border:2px solid #795923;border-bottom:0;border-radius:5px 3px 0 0;background:repeating-linear-gradient(-15deg,#e0b74f 0 4px,#efd282 4px 7px);box-shadow:inset 3px 0 #fff4bd7a,3px 0 #674c3126}\r\n[data-medal=silver] .pillar-bar{background:repeating-linear-gradient(-15deg,#a9bbc8 0 4px,#d5e0e5 4px 7px);border-color:#536b7d;box-shadow:inset 3px 0 #f8ffff7a,3px 0 #41586b26}[data-medal=bronze] .pillar-bar{background:repeating-linear-gradient(-15deg,#b67848 0 4px,#d6a780 4px 7px);border-color:#704328;box-shadow:inset 3px 0 #ffe0b87a,3px 0 #63392126}[data-medal=empty] .pillar-bar{height:6px;width:70%;background:transparent;border:1px dashed #8a9daa;border-bottom:0;box-shadow:none}\r\n.pillar-rank{font:700 11px/1.4 Arial,sans-serif;text-transform:capitalize;margin-top:6px;color:#52606d}.pillar-name{font:13px/1.35 Arial,sans-serif;overflow-wrap:anywhere;margin-top:3px}#accountPanel .score-tie-note{font:13px/1.5 Arial,sans-serif;margin:12px 0;color:#596878}\r\n#accountPanel .marker-tray{height:auto;min-height:98px;position:sticky;bottom:-22px;margin:25px -10px -22px;padding:12px 10px 8px;display:flex;align-items:stretch;justify-content:flex-start;gap:9px;overflow-x:auto;overscroll-behavior-x:contain;pointer-events:auto;z-index:4;scrollbar-width:thin;background:linear-gradient(#c4cece,#f0f2ea 32%,#c4cece 35%,#929fa4);border-top:3px solid #74868e;box-shadow:0 -5px 14px #27343a25;scroll-padding:10px}\r\n#accountPanel .board-marker{flex:0 0 82px;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:10px;background:transparent;border:2px solid transparent;box-shadow:none;border-radius:5px;padding:7px 4px;min-height:78px;color:#243a49;touch-action:manipulation}#accountPanel .board-marker[aria-pressed=true]{border-color:var(--pen-ink);background:#ffffffb5}.marker-label{font:700 13px/1.25 Arial,sans-serif;max-width:84px;text-align:center}.marker-body{height:15px;width:68px;border:1px solid #66737c;border-left:12px solid var(--pen-ink);border-right:10px solid var(--pen-ink);border-radius:4px;background:linear-gradient(#fff,#d1d8d8);box-shadow:0 3px 3px #243b4866;position:relative;transform:rotate(-5deg);display:block}.marker-eraser{position:absolute;left:-12px;top:-2px;height:17px;width:9px;border:1px solid #415164;border-radius:3px;background:repeating-linear-gradient(#49555d 0 2px,#7e8b8c 2px 3px)}.marker-tip{position:absolute;right:-16px;top:4px;width:7px;height:5px;background:var(--pen-ink);border-radius:0 3px 3px 0}\r\n#accountPanel .marker-tray .marker-body i{transform:none;box-shadow:none}.marker-tray .marker-eraser{display:block}.marker-tray .marker-tip{display:block}\r\n#scoreboardMarkers i.marker-eraser{position:absolute;left:-12px;right:auto;top:-2px;height:17px;width:9px;border:1px solid #415164;border-radius:3px;background:repeating-linear-gradient(#49555d 0 2px,#7e8b8c 2px 3px)}#scoreboardMarkers i.marker-tip{position:absolute;right:-16px;left:auto;top:4px;width:7px;height:5px;border:0;background:var(--pen-ink);border-radius:0 3px 3px 0}\r\n#boardMovingPen{position:absolute;z-index:3;top:0;left:0;width:85px;height:19px;background:linear-gradient(#fff,#d1d8d8);border:1px solid #536674;border-left:12px solid var(--pen-ink);border-right:10px solid var(--pen-ink);border-radius:4px;pointer-events:none;filter:drop-shadow(2px 4px 2px #21374944);transform-origin:50% 50%}#boardMovingPen .marker-eraser{height:21px;left:-13px;top:-2px}\r\n.board-erasing #workoutList{animation:board-wipe .38s ease-in both}.board-erasing #boardMovingPen{animation:pen-erase .38s ease-in both}.board-drawing #workoutList{animation:board-reveal .44s steps(8,end) both}.board-drawing #boardMovingPen{animation:pen-scribble .44s linear both}\r\n@keyframes board-wipe{from{clip-path:inset(0)}to{clip-path:inset(0 0 0 100%)}}\r\n@keyframes board-reveal{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0)}}\r\n@keyframes pen-erase{0%{transform:translate(var(--pen-from-x),var(--pen-from-y)) rotate(175deg)}25%{left:0;top:8%;transform:rotate(175deg)}60%{left:45%;top:40%;transform:rotate(190deg)}100%{left:85%;top:75%;transform:rotate(175deg)}}\r\n@keyframes pen-scribble{0%{left:0;top:5%;transform:rotate(-25deg)}20%{left:18%;top:78%;transform:rotate(20deg)}40%{left:35%;top:12%;transform:rotate(-25deg)}60%{left:50%;top:80%;transform:rotate(20deg)}80%{left:66%;top:15%;transform:rotate(-25deg)}100%{left:85%;top:75%;transform:rotate(20deg)}}\r\n@media(min-width:800px){.score-row{grid-template-columns:240px minmax(0,1fr)}.pillar-track{height:90px}.score-pillars{gap:28px}.pillar-bar{width:62px}.score-exercise h4{font-size:27px}#accountPanel .board-marker{flex:1 0 73px}.scoreboard-crew{gap:22px}.crew-place{flex-flow:row wrap;justify-content:center;column-gap:12px}.crew-place-label{flex-basis:100%;text-align:center}}\r\n@media(max-width:420px){#accountPanel header{min-height:100px}#accountPanel .progress-eyebrow{font-size:12px}#accountPanel h2{font-size:30px}.score-row{grid-template-columns:94px minmax(0,1fr);gap:8px}.score-exercise{padding-left:6px}.score-exercise h4{font-size:21px}.score-pillars{gap:5px}.pillar-name{font-size:12px}.scoreboard-crew{gap:6px}.crew-head{width:62px;height:62px}.crew-head canvas{width:58px;height:58px}.crew-place strong{font-size:14px}.crew-place-label{font-size:12px}.medal-key span{font-size:12px}.scoreboard-heading{gap:10px}}\r\n@media(prefers-reduced-motion:reduce){#accountPanel .board-erasing,#accountPanel .board-drawing,#accountPanel #workoutList,#boardMovingPen{animation:none!important}#boardMovingPen{display:none!important}}\r\n","scoreboard.mjs":"import {FOCUS_GROUPS} from './exercise-library.mjs';\r\nimport {GROUP_INKS,comparisonRows,displayScore} from './scoreboard-domain.mjs';\r\nconst $=id=>document.getElementById(id);\r\nconst element=(tag,className,text)=>{const node=document.createElement(tag);if(className)node.className=className;if(text!=null)node.textContent=text;return node;};\r\nexport function mountScoreboard({api,getAccount}){\r\n const container=$('workoutList'),panel=$('accountPanel'),tray=$('scoreboardMarkers');\r\n panel.classList.add('classroom-panel');\r\n const classroomHost=element('div','classroom-host');classroomHost.dataset.roomHost='';panel.querySelector('header')?.after(classroomHost);\r\n const classroomStyle=element('link');classroomStyle.rel='stylesheet';classroomStyle.href='/modules/rooms/classroom.css';document.head.append(classroomStyle);\r\n let room=null,roomEpoch=0;\r\n async function openClassroom(){if(!panel.open||room)return;const epoch=++roomEpoch;panel.dataset.room='loading';try{const {mountClassroom}=await import('./modules/rooms/classroom.mjs');if(epoch!==roomEpoch||!panel.open)return;room=mountClassroom(panel,{host:classroomHost});room.setDesks(deskNodes());}catch(error){if(epoch!==roomEpoch)return;delete panel.dataset.room;classroomHost.replaceChildren();const offer=element('button','','Download classroom');offer.type='button';offer.onclick=()=>window.myr5Packs?.open?.('room-scoreboard');classroomHost.append(offer);panel.dispatchEvent(new CustomEvent('myr5:classroom-board',{bubbles:true}));console.warn('Classroom unavailable',error);}}\r\n const classroomObserver=new MutationObserver(()=>{if(panel.open)void openClassroom();});classroomObserver.observe(panel,{attributes:true,attributeFilter:['open']});\r\n let selected='chest',members=[],loaded=false,requestNumber=0,animationNumber=0,animationTimers=[],pendingInvite=null,crewSignature='';\r\n function clearAnimation(){animationTimers.forEach(clearTimeout);animationTimers=[];panel.classList.remove('board-erasing','board-drawing');$('boardMovingPen').hidden=true;}\r\n function renderGraph(){\r\n  container.replaceChildren();const group=FOCUS_GROUPS.find(g=>g.id===selected);panel.style.setProperty('--marker',GROUP_INKS[selected]);\r\n  $('scoreboardGroup').textContent=group.name;$('scoreboardSubtitle').textContent=group.description;\r\n  for(const pen of tray.children){pen.setAttribute('aria-pressed',String(pen.dataset.group===selected));}\r\n  const axis=element('div','score-axis','↑ Exercise level');const caption=element('p','score-caption','Best completed set · bar heights compare people within each row');container.append(axis,caption);\r\n  for(const row of comparisonRows(selected,members)){\r\n   const section=element('section','score-row');section.setAttribute('aria-label',`Level ${row.exercise.difficulty}: ${row.exercise.name}`);\r\n   const label=element('div','score-exercise');label.append(element('span','score-level',`LV ${String(row.exercise.difficulty).padStart(2,'0')}`),element('h4','',row.exercise.name),element('span','score-unit',row.unit));\r\n   const pillars=element('div','score-pillars');\r\n   for(const bar of row.bars){const person=members[bar.slot],name=bar.slot===0?'You':person?.name||`Friend ${bar.slot}`;const pillar=element('div','score-pillar');pillar.dataset.medal=bar.medal||'empty';pillar.setAttribute('aria-label',`${name}: ${bar.value===null?(person?'no completed set':'not connected'):`${displayScore(bar.value)} ${row.unit}, ${bar.medal}`}`);\r\n    const value=element('strong','score-value',displayScore(bar.value)),track=element('div','pillar-track'),ink=element('i','pillar-bar');ink.style.setProperty('--bar-height',bar.height+'%');ink.setAttribute('aria-hidden','true');track.append(ink);\r\n    pillar.append(value,track,element('span','pillar-rank',bar.medal?`${bar.rank} · ${bar.medal}`:person?'No set':'Open place'),element('span','pillar-name',name));pillars.append(pillar);\r\n   }\r\n   section.append(label,pillars);container.append(section);\r\n  }\r\n }\r\n function select(group,button){\r\n  if(group===selected&&loaded)return;selected=group;const sequence=++animationNumber;clearAnimation();\r\n  window.dispatchEvent(new Event('myr5:whiteboard-redraw'));\r\n  if(matchMedia('(prefers-reduced-motion: reduce)').matches){renderGraph();return;}\r\n  const pen=$('boardMovingPen');pen.hidden=false;pen.style.setProperty('--pen-ink',GROUP_INKS[group]);\r\n  const from=button.getBoundingClientRect(),to=$('boardCanvas').getBoundingClientRect();pen.style.setProperty('--pen-from-x',`${from.left+from.width/2-to.left}px`);pen.style.setProperty('--pen-from-y',`${from.top-to.top}px`);\r\n  panel.classList.add('board-erasing');\r\n  animationTimers.push(setTimeout(()=>{if(sequence!==animationNumber)return;renderGraph();panel.classList.remove('board-erasing');panel.classList.add('board-drawing');},380));\r\n  animationTimers.push(setTimeout(()=>{if(sequence===animationNumber)clearAnimation();},820));\r\n }\r\n for(const group of FOCUS_GROUPS){const pen=element('button','board-marker');pen.type='button';pen.dataset.group=group.id;pen.style.setProperty('--pen-ink',GROUP_INKS[group.id]);pen.setAttribute('aria-label',`${group.name} scoreboard`);pen.setAttribute('aria-controls','boardCanvas');pen.setAttribute('aria-pressed',String(group.id===selected));const body=element('span','marker-body');body.setAttribute('aria-hidden','true');body.append(element('i','marker-eraser'),element('i','marker-tip'));pen.append(body,element('span','marker-label',group.name));pen.onclick=()=>select(group.id,pen);tray.append(pen);}\r\n function localGala(){try{return JSON.parse(localStorage.getItem('mominc-avatar-v1'));}catch{return null;}}\r\n function drawHead(slot,person){\r\n  const frame=element('div','crew-head');if(!person){frame.textContent='+';frame.setAttribute('aria-hidden','true');return frame;}\r\n  const saved=person.avatar||(slot===0?localGala():null);\r\n  if(!saved||!window.GalaAvatar){frame.textContent='?';frame.setAttribute('aria-label','No saved Gala look');return frame;}\r\n  try{const look=window.GalaAvatar.normalize(saved),source=document.createElement('canvas'),head=document.createElement('canvas');head.width=64;head.height=64;head.setAttribute('role','img');head.setAttribute('aria-label',`${slot===0?'Your':person.name+'’s'} Gala character head`);\r\n   const paint=blink=>{window.GalaAvatar.draw(source,look,{base:false,weapon:false,companion:false,prop:false,blink});const ctx=head.getContext('2d');ctx.imageSmoothingEnabled=false;ctx.clearRect(0,0,64,64);ctx.drawImage(source,8,0,48,40,0,5,64,54);};\r\n   paint(false);frame.append(head);\r\n   // Blink every 3-6 s per head; the chain ends itself once the head is no longer in the page.\r\n   const later=()=>setTimeout(()=>{if(!head.isConnected)return;paint(true);setTimeout(()=>{paint(false);later();},120);},3000+Math.random()*3000);later();\r\n  }catch{frame.textContent='?';frame.setAttribute('aria-label','No saved Gala look');}\r\n  return frame;\r\n }\r\n function renderCrew(){const signature=JSON.stringify(members.map(({name,link,avatar})=>({name,link,avatar})))+(localStorage.getItem('mominc-avatar-v1')||'');if(signature===crewSignature)return;crewSignature=signature;$('scoreboardCrew').replaceChildren();for(let slot=0;slot<3;slot++){const person=members[slot],card=element('div','crew-place');card.append(drawHead(slot,person),element('strong','',slot===0?(person?.name||'You'):person?.name||`Friend ${slot}`),element('span','crew-place-label',slot===0?'Your place':person?'Connected':'Invite a friend'));if(person?.link){const remove=element('button','crew-remove','Remove');remove.type='button';remove.setAttribute('aria-label',`Stop sharing with ${person.name}`);remove.onclick=()=>action(remove,async()=>{await api('/api/scoreboard/friends/'+encodeURIComponent(person.link),'DELETE');await refresh();$('crewStatus').textContent='Friend removed. Sharing has stopped.';});card.append(remove);}$('scoreboardCrew').append(card);}$('createCrewInvite').disabled=members.length>=3;$('crewJoin').disabled=members.length>=3;room?.setDesks(deskNodes());}\r\n function deskNodes(){return [1,2].map(slot=>{const person=members[slot];if(person){const figure=element('figure');figure.append(drawHead(slot,person),element('figcaption','',person.name||`Friend ${slot}`));return figure;}const pick=element('button');pick.type='button';pick.setAttribute('aria-label',`Pick a friend for desk ${slot}`);pick.append(element('b','','+'),element('span','','Pick friends'));pick.onclick=pickFriends;return pick;});}\r\n function pickFriends(){room?.showBoard();if($('accountContent').hidden){$('signIn').focus();return;}const controls=$('crewInviteControls');controls.open=true;controls.scrollIntoView({block:'center'});controls.querySelector('summary').focus({preventScroll:true});}\r\n async function action(button,fn){button.disabled=true;try{await fn();}catch(error){$('crewStatus').textContent=error.message;}finally{button.disabled=members.length>=3&&['createCrewInvite','crewJoin'].includes(button.id);}}\r\n $('createCrewInvite').onclick=()=>action($('createCrewInvite'),async()=>{const result=await api('/api/scoreboard/invite','POST',{consent:true});pendingInvite=result.code;$('crewInviteCode').value=result.code;$('crewInviteOutput').hidden=false;$('revokeCrewInvite').hidden=false;$('crewStatus').textContent='Code ready. Share it with one friend. It expires in seven days.';});\r\n $('copyCrewInvite').onclick=async()=>{try{await navigator.clipboard.writeText(pendingInvite||$('crewInviteCode').value);$('crewStatus').textContent='Invite code copied. Your friend can enter it in their scoreboard.';}catch{$('crewInviteCode').focus();$('crewInviteCode').select();$('crewStatus').textContent='Code selected. Use Copy to share it.';}};\r\n $('revokeCrewInvite').onclick=()=>action($('revokeCrewInvite'),async()=>{await api('/api/scoreboard/invite','DELETE');pendingInvite=null;$('crewInviteOutput').hidden=true;$('revokeCrewInvite').hidden=true;$('crewStatus').textContent='Invite cancelled.';});\r\n $('crewJoinForm').onsubmit=event=>{event.preventDefault();action($('crewJoin'),async()=>{await api('/api/scoreboard/join','POST',{code:$('crewJoinCode').value,consent:true});void import('./modules/vault/vault-store.mjs').then(m=>m.bump('scoreboard-link')).catch(()=>{});$('crewJoinCode').value='';await refresh();$('crewStatus').textContent='Connected. Your names, Gala looks and best sets are shared.';});};\r\n async function refresh(){if(!getAccount())return;const user=getAccount().user.id,epoch=getAccount().dataEpoch,number=++requestNumber;container.setAttribute('aria-busy','true');$('recordsStatus').textContent='Updating the board…';try{const result=await api('/api/scoreboard');if(number!==requestNumber||getAccount()?.user.id!==user||getAccount()?.dataEpoch!==epoch||result.targetAccountId!==user||result.dataEpoch!==epoch)return;members=result.members;loaded=true;renderCrew();renderGraph();$('revokeCrewInvite').hidden=!result.inviteExpiresAt;if(!result.inviteExpiresAt){pendingInvite=null;$('crewInviteOutput').hidden=true;}$('recordsStatus').textContent=members[0]?.items.length?`Updated ${new Date(result.updatedAt).toLocaleTimeString([],{hour:'numeric',minute:'2-digit'})}`:'Finish a set to put your first record on the board.';}catch(error){if(number===requestNumber)$('recordsStatus').textContent=`Board could not refresh. ${error.message}`;}finally{if(number===requestNumber)container.removeAttribute('aria-busy');}}\r\n function clear(){++requestNumber;++animationNumber;clearAnimation();members=[];loaded=false;crewSignature='';pendingInvite=null;$('crewInviteOutput').hidden=true;$('crewInviteCode').value='';renderCrew();renderGraph();}\r\n panel.addEventListener('close',()=>{++animationNumber;clearAnimation();++roomEpoch;room?.dispose();room=null;delete panel.dataset.room;delete panel.dataset.roomView;});\r\n const timer=setInterval(()=>{if(panel.open&&!document.hidden&&loaded)refresh();},30000);window.addEventListener('pagehide',()=>{clearInterval(timer);clearAnimation();});\r\n window.addEventListener('myr5:account-progress',()=>{if(panel.open&&loaded)refresh();});\r\n renderCrew();renderGraph();return {refresh,clear};\r\n}\r\n","scripts/actual-dj-preview.mjs":"import {createServer} from 'node:http';\r\nimport {readFile} from 'node:fs/promises';\r\nimport {resolve,extname,sep} from 'node:path';\r\nimport {fileURLToPath} from 'node:url';\r\nconst project=fileURLToPath(new URL('../',import.meta.url));\r\nconst html='<!doctype html><html lang=\"en\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>actual.dj / MYR5 preview</title><link rel=\"stylesheet\" href=\"/spotify-terminal.css\"><link rel=\"stylesheet\" href=\"/actual-dj.css\"><body style=\"background:#100b18\"><button id=\"open\" style=\"padding:20px;margin:30px\">Open actual.dj</button><script type=\"module\">import{initSpotifyTerminal}from\"/spotify-terminal.mjs\";const dj=window.djPreview=initSpotifyTerminal({getAccount:()=>null});document.getElementById(\"open\").addEventListener(\"click\",()=>dj.open());dj.open();</script></body></html>';\r\nconst types={'.html':'text/html','.mjs':'text/javascript','.js':'text/javascript','.css':'text/css','.json':'application/json','.webmanifest':'application/manifest+json','.m4a':'audio/mp4','.wav':'audio/wav','.mp3':'audio/mpeg','.webp':'image/webp','.png':'image/png','.jpg':'image/jpeg','.svg':'image/svg+xml','.glb':'model/gltf-binary','.bin':'application/octet-stream','.wasm':'application/wasm','.woff2':'font/woff2','.ttf':'font/ttf'};\r\nexport function sendFile(req,res,data,type){\r\n res.setHeader('Content-Type',type);res.setHeader('Accept-Ranges','bytes');\r\n // HTTP ranges apply to GET; HEAD reports the same full representation without a body.\r\n const range=req.method==='GET'?req.headers.range:null;\r\n if(range){\r\n  const match=range.match(/^bytes=(\\d*)-(\\d*)$/i);let start,end;\r\n  if(match&&(match[1]||match[2])){\r\n   if(match[1]){start=Number(match[1]);end=match[2]?Number(match[2]):data.length-1;}\r\n   else{const suffix=Number(match[2]);start=suffix>0?Math.max(0,data.length-suffix):data.length;end=data.length-1;}\r\n  }\r\n  if(!Number.isSafeInteger(start)||!Number.isSafeInteger(end)||start<0||start>=data.length||end<start){res.writeHead(416,{'Content-Range':`bytes */${data.length}`,'Content-Length':'0'});res.end();return;}\r\n  end=Math.min(end,data.length-1);\r\n  res.writeHead(206,{'Content-Range':`bytes ${start}-${end}/${data.length}`,'Content-Length':String(end-start+1)});res.end(data.subarray(start,end+1));return;\r\n }\r\n res.setHeader('Content-Length',String(data.length));res.end(req.method==='HEAD'?undefined:data);\r\n}\r\nexport function createDJPreviewServer({root=project}={}){\r\n return createServer(async(req,res)=>{res.setHeader('Cache-Control','no-store');\r\n  const path=new URL(req.url,'http://preview').pathname;\r\n  if(path==='/'||path==='/actual-dj-preview'){res.setHeader('Content-Type','text/html');res.end(html);return;}\r\n  if(path.startsWith('/api/')){res.writeHead(401,{'Content-Type':'application/json'});res.end('{\"error\":\"Sign in on the live MYR5 app to use account controls.\"}');return;}\r\n  try{const decoded=decodeURIComponent(path),file=resolve(root,'.'+decoded);if(!file.startsWith(resolve(root)+sep)||decoded.split('/').some(p=>p.startsWith('.'))||/^\\/(server|scripts|tests|node_modules|release-trust)\\//.test(decoded)||!types[extname(file)])throw Error();const data=await readFile(file);sendFile(req,res,data,types[extname(file)]);}catch{res.writeHead(404);res.end('Not found');}\r\n });\r\n}\r\nif(process.argv[1]&&resolve(process.argv[1])===fileURLToPath(import.meta.url)){\r\n const server=createDJPreviewServer({root:process.env.ACTUAL_DJ_PREVIEW_ROOT||project}),port=Number(process.env.ACTUAL_DJ_PREVIEW_PORT)||18905;\r\n server.listen(port,'127.0.0.1',()=>console.log(`actual.dj preview: http://127.0.0.1:${port}/actual-dj-preview`));\r\n}\r\n","scripts/assets.mjs":"import {readFile,writeFile,mkdir} from 'node:fs/promises';\r\nimport {createHash} from 'node:crypto';\r\nimport {build} from 'esbuild';\r\n// Keep Three.js out of the eager launch bundle; the Food panel loads it on demand.\r\nexport async function ensureThreeVendor(){\r\n await mkdir('vendor/three',{recursive:true});\r\n await build({entryPoints:['node_modules/three/build/three.module.js'],bundle:false,minify:true,format:'esm',outfile:'vendor/three/three.module.js',logLevel:'silent'});\r\n await build({entryPoints:['node_modules/three/examples/jsm/loaders/GLTFLoader.js'],bundle:true,minify:true,format:'esm',external:['three'],outfile:'vendor/three/GLTFLoader.js',logLevel:'silent'});\r\n await build({entryPoints:['node_modules/three/examples/jsm/libs/meshopt_decoder.module.js'],bundle:false,minify:true,format:'esm',outfile:'vendor/three/meshopt_decoder.module.js',logLevel:'silent'});\r\n}\r\nconst revision='40911d5761c2e8167664c3416fb37580246c74b9';\r\nconst files=[['myr5.glb','1593467f0aa641119d56f28b2a98af3877fe08ec'],['anatomy.glb','1035a26eb090e8a0436495a3c62839ad67a718b6'],['hands-v2.glb','83713fc5689b8e78ced779fcb5435d14b04d4c7a']];\r\nconst blobId=bytes=>createHash('sha1').update(`blob ${bytes.length}\\0`).update(bytes).digest('hex');\r\nexport async function ensureHandAssets(){\r\n const path='handborne/models/family-20.glb',expected='e77adfca6536a7221d9006048717a8f4fce0552e';\r\n await mkdir('handborne/models',{recursive:true});\r\n let bytes;try{bytes=await readFile(path);}catch{\r\n  const url='https://raw.githubusercontent.com/MomInc-MBS/mominc-mbs.github.io/b625d640418dddf988ce5a028a0a0a10da87fd32/handborne/models/family-20.glb';\r\n  const response=await fetch(url);if(!response.ok)throw Error(`Could not download the Fluffy hand model: ${response.status}`);bytes=Buffer.from(await response.arrayBuffer());\r\n }\r\n if(blobId(bytes)!==expected)throw Error('Fluffy hand model content check failed.');\r\n await writeFile(path,bytes);\r\n}\r\nexport async function ensureAssets(){await mkdir('creature/models',{recursive:true});for(const [name,expected]of files){const path=`creature/models/${name}`;let bytes;try{bytes=await readFile(path);}catch{if(name==='hands-v2.glb')throw Error('Restore the authored hands-v2.glb from the project source.');const url=`https://raw.githubusercontent.com/MomInc-MBS/mominc-mbs.github.io/${revision}/tv/assets/armie-intro/myr5/models/${name}`;const response=await fetch(url);if(!response.ok)throw Error(`Could not download ${name}: ${response.status}`);bytes=Buffer.from(await response.arrayBuffer());}if(blobId(bytes)!==expected)throw Error(`Model content check failed: ${name}`);await writeFile(path,bytes);}}\r\n","scripts/build-creature-skin-manifests.mjs":"// Builds the additive creature-skin runtime catalog and optional-pack asset manifest\r\n// from the two immutable handoff manifests. Texture bytes remain in plan/assets-inbox.\r\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\r\nimport { dirname, join, resolve } from 'node:path';\r\nimport { pathToFileURL } from 'node:url';\r\n\r\nconst PACKETS = [\r\n  { dir: 'forged-realms', packetId: 'coach-creature-forged-realms-v1' },\r\n  { dir: 'celestial-rift', packetId: 'coach-creature-celestial-rift-v1' },\r\n];\r\nconst TRACKS = new Set(['chest','quads','glutes','arms','yoga','martial-arts','cardio','meditation']);\r\nconst HEX = /^[a-f0-9]{64}$/;\r\n\r\nexport async function buildCreatureSkinManifests({ root = process.cwd(), outputDir = root, catalogPath = join(outputDir, 'creature-skins.json') } = {}) {\r\n  const base = join(root, 'plan/assets-inbox/creature-skins');\r\n  const collections = [], ids = new Set();\r\n  for (const packet of PACKETS) {\r\n    const sourcePath = join(base, packet.dir, 'source-manifest.json');\r\n    const source = JSON.parse(await readFile(sourcePath, 'utf8'));\r\n    if (source.packetId !== packet.packetId || !Array.isArray(source.items)) throw new Error(`Invalid packet manifest: ${packet.packetId}`);\r\n    collections.push({ id: source.items[0]?.collection, packetId: source.packetId, displayName: source.displayName, description: source.description, runtimeNotes: source.runtimeNotes });\r\n    for (const item of source.items) {\r\n      if (!item.id?.startsWith('creature-') || ids.has(item.id)) throw new Error(`Duplicate or non-namespaced creature skin id: ${item.id}`);\r\n      if (!TRACKS.has(item.track) || ![1,2,3].includes(item.collectionSlot) || item.collection !== collections.at(-1).id) throw new Error(`Invalid track/collection for ${item.id}`);\r\n      ids.add(item.id);\r\n      for (const [map, info] of Object.entries(item.maps)) {\r\n        if (!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(info.file||'') || info.file.includes('..') || !Number.isSafeInteger(info.bytes) || info.bytes<1 || !HEX.test(info.sha256)) throw new Error(`Invalid ${map} metadata for ${item.id}`);\r\n      }\r\n    }\r\n  }\r\n  if (ids.size !== 48) throw new Error(`Expected 48 unique creature skins; found ${ids.size}`);\r\n  const catalog = { schemaVersion: 1, additive: true, colorSpace: { basecolor: 'srgb', tintMask: 'srgb', normal: 'linear', roughness: 'linear', height: 'linear', ao: 'linear', metalness: 'linear', opacity: 'linear', emissive: 'srgb' }, normalConvention: 'OpenGL +Y', tinting: 'tint-mask multiplied by selected creature palette', collections };\r\n  // Preserve complete source metadata, including source URLs, CC0 attribution, and original checksums.\r\n  catalog.skins = [];\r\n  for (const packet of PACKETS) {\r\n    const source = JSON.parse(await readFile(join(base, packet.dir, 'source-manifest.json'), 'utf8'));\r\n    catalog.skins.push(...source.items.map(item => ({ ...item, runtime: { unlock: { level: [1, 3, 5][item.collectionSlot - 1], track: item.track }, pack: `track-${item.track}`, bundle: `assets/${item.track}.m5bundle`, maps: Object.fromEntries(Object.entries(item.maps).map(([name, map]) => [name, { entry: `${item.id}/${name}`, bytes: map.bytes, sha256: map.sha256 }])) } })));\r\n  }\r\n  await mkdir(outputDir, { recursive: true });\r\n  await mkdir(dirname(catalogPath), { recursive: true });\r\n  await writeFile(catalogPath, JSON.stringify(catalog, null, 2) + '\\n');\r\n  return { skins: ids.size, outputDir: resolve(outputDir) };\r\n}\r\n\r\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\r\n  const outArg = process.argv.find(x => x.startsWith('--out='));\r\n  console.log(JSON.stringify(await buildCreatureSkinManifests({ outputDir: outArg ? resolve(outArg.slice(6)) : process.cwd() }), null, 2));\r\n}\r\n","scripts/build-food-fdc.mjs":"// One-off: maps each of the 101 Food-101 scanner labels to a USDA FoodData Central food and writes\r\n// food/nutrition-fdc.json ({label: {fdcId,description,servingName,servingG,kcal,proteinG,fatG,carbsG,\r\n// vitamins}}). Run with: node scripts/build-food-fdc.mjs\r\n//\r\n// Source data: FDC's bulk CSV downloads (Survey/FNDDS, SR Legacy, Foundation) instead of the rate-limited\r\n// (10 req/window) DEMO_KEY search API -- one download covers all 101 labels. Cached in FDC_CACHE_DIR\r\n// (default: an OS temp folder) so re-runs are instant.\r\n//\r\n// ponytail: hand-rolled `\",\"`-boundary CSV split (unescaping \"\" -> \") instead of a csv-parser dependency.\r\n// These bulk files never nest a literal `\",\"` inside a field (checked on 2026 vintage files). Swap in a\r\n// real parser if a future USDA release breaks that assumption.\r\nimport {existsSync} from 'node:fs';\r\nimport {mkdir, readFile, writeFile, readdir} from 'node:fs/promises';\r\nimport {tmpdir} from 'node:os';\r\nimport {join} from 'node:path';\r\nimport {spawnSync} from 'node:child_process';\r\n\r\nconst CACHE_DIR = process.env.FDC_CACHE_DIR || join(tmpdir(), 'myr5-fdc-cache');\r\nconst DATASETS = [\r\n // priority order: FNDDS (\"as eaten\" dishes) first, per the brief -- suits mixed dishes like pad thai.\r\n {key: 'survey', zip: 'FoodData_Central_survey_food_csv_2024-10-31.zip'},\r\n {key: 'sr_legacy', zip: 'FoodData_Central_sr_legacy_food_csv_2018-04.zip'},\r\n {key: 'foundation', zip: 'FoodData_Central_foundation_food_csv_2026-04-30.zip'},\r\n];\r\nconst FDC_BASE = 'https://fdc.nal.usda.gov/fdc-datasets/';\r\n\r\n// The 101 Food-101 labels, in the model's own order (confirmed against the ethz/food101 HF dataset\r\n// metadata; also what food-worker.mjs emits after replaceAll('_',' ')).\r\nconst LABELS = ['apple_pie', 'baby_back_ribs', 'baklava', 'beef_carpaccio', 'beef_tartare', 'beet_salad', 'beignets', 'bibimbap', 'bread_pudding', 'breakfast_burrito', 'bruschetta', 'caesar_salad', 'cannoli', 'caprese_salad', 'carrot_cake', 'ceviche', 'cheesecake', 'cheese_plate', 'chicken_curry', 'chicken_quesadilla', 'chicken_wings', 'chocolate_cake', 'chocolate_mousse', 'churros', 'clam_chowder', 'club_sandwich', 'crab_cakes', 'creme_brulee', 'croque_madame', 'cup_cakes', 'deviled_eggs', 'donuts', 'dumplings', 'edamame', 'eggs_benedict', 'escargots', 'falafel', 'filet_mignon', 'fish_and_chips', 'foie_gras', 'french_fries', 'french_onion_soup', 'french_toast', 'fried_calamari', 'fried_rice', 'frozen_yogurt', 'garlic_bread', 'gnocchi', 'greek_salad', 'grilled_cheese_sandwich', 'grilled_salmon', 'guacamole', 'gyoza', 'hamburger', 'hot_and_sour_soup', 'hot_dog', 'huevos_rancheros', 'hummus', 'ice_cream', 'lasagna', 'lobster_bisque', 'lobster_roll_sandwich', 'macaroni_and_cheese', 'macarons', 'miso_soup', 'mussels', 'nachos', 'omelette', 'onion_rings', 'oysters', 'pad_thai', 'paella', 'pancakes', 'panna_cotta', 'peking_duck', 'pho', 'pizza', 'pork_chop', 'poutine', 'prime_rib', 'pulled_pork_sandwich', 'ramen', 'ravioli', 'red_velvet_cake', 'risotto', 'samosa', 'sashimi', 'scallops', 'seaweed_salad', 'shrimp_and_grits', 'spaghetti_bolognese', 'spaghetti_carbonara', 'spring_rolls', 'steak', 'strawberry_shortcake', 'sushi', 'tacos', 'takoyaki', 'tiramisu', 'tuna_tartare', 'waffles'].map(s => s.replaceAll('_', ' '));\r\n\r\n// Query overrides for labels where a plain word match picks a bad FDC entry. The first 12 are the\r\n// existing aliases already hand-picked for the SR28 fuzzy search in nutrition.mjs -- reused here so\r\n// both lookup paths agree on what these dishes mean.\r\nconst QUERY = {\r\n 'french fries': 'potato french fries', 'ice cream': 'ice creams', 'hamburger': 'hamburger',\r\n 'hot dog': 'frankfurter', 'grilled salmon': 'salmon cooked', 'grilled cheese sandwich': 'sandwich cheese',\r\n 'macaroni and cheese': 'macaroni cheese', 'steak': 'beef steak cooked', 'french toast': 'french toast',\r\n 'fried rice': 'rice fried', 'sashimi': 'fish raw', 'omelette': 'egg omelet',\r\n // additional overrides found by inspecting two automated passes against the bulk CSVs (see the report\r\n // for which of these are close substitutes rather than an exact FDC match -- cannoli, macarons, poutine,\r\n // risotto and takoyaki have no FDC entry at all in Survey/SR Legacy/Foundation).\r\n 'escargots': 'snails cooked', 'foie gras': 'goose liver pate', 'cheese plate': 'cheese cheddar',\r\n 'spaghetti bolognese': 'spaghetti with meat sauce', 'spaghetti carbonara': 'pasta cream sauce meat restaurant',\r\n 'huevos rancheros': 'huevos rancheros', 'peking duck': 'duck peking style', 'prime rib': 'beef prime rib roasted',\r\n 'club sandwich': 'club sandwich', 'croque madame': 'sandwich egg cheese ham', 'cup cakes': 'cupcake',\r\n 'red velvet cake': 'red velvet cake', 'panna cotta': 'custard', 'shrimp and grits': 'shrimp and grits',\r\n 'beef carpaccio': 'beef carpaccio raw', 'tuna tartare': 'tuna raw', 'beef tartare': 'tartare',\r\n 'baby back ribs': 'pork ribs barbecued', 'filet mignon': 'beef steak lean cooked', 'pork chop': 'pork chop fat eaten',\r\n 'beet salad': 'beets fresh cooked', 'seaweed salad': 'seaweed pickled',\r\n 'fried calamari': 'squid fried', 'lobster roll sandwich': 'lobster salad', 'pulled pork sandwich': 'pulled pork barbecue sauce',\r\n 'caprese salad': 'mozzarella tomato basil oil vinegar dressing', 'lobster bisque': 'soup bisque',\r\n 'spring rolls': 'egg roll meatless', 'gyoza': 'wonton dumpling pot sticker fried', 'donuts': 'doughnut nfs',\r\n 'pizza': 'pizza cheese restaurant fast food', 'fish and chips': 'fish cod fried',\r\n // no FDC entry anywhere in these three datasets for these five -- nearest defensible single-food proxy:\r\n 'risotto': 'rice white cooked', 'poutine': 'potato french fries nfs', 'takoyaki': 'octopus',\r\n 'cannoli': 'cream puff eclair custard filled', 'macarons': 'cookie meringue',\r\n};\r\n// Labels with no real FDC entry for the dish itself -- QUERY above points them at the closest single-food\r\n// stand-in; flag that plainly regardless of the word-coverage score (which will read 1.0 since the query\r\n// was written to match the stand-in, not the dish).\r\nconst KNOWN_PROXY = new Set(['risotto', 'poutine', 'takoyaki', 'cannoli', 'macarons', 'beef carpaccio', 'shrimp and grits', 'fish and chips']);\r\n\r\nconst STOPWORDS = new Set(['and', 'with', 'the', 'a', 'of', 'in', 'style', 'ns', 'as', 'to', 'or', 'raw', 'cooked']);\r\nconst norm = s => s.normalize('NFD').replace(/[̀-ͯ]/g, '').toLowerCase();\r\nconst words = text => norm(text).replace(/[^a-z0-9 ]/g, ' ').split(/\\s+/).filter(w => w.length > 1 && !STOPWORDS.has(w)).map(w => w.replace(/(ies)$/, 'y').replace(/s$/, ''));\r\n\r\n// --- tiny CSV reader: fields are always fully quoted and never contain the 4-char sequence `\",\"`. ---\r\n// A handful of Foundation lab-sample rows have a stray embedded newline inside the description (verified\r\n// against the 2026-04-30 dump, e.g. fdc_id 321829); a line-based split turns one such row into two ragged\r\n// ones. We drop rows that don't match the header's column count rather than reconstructing them -- they're\r\n// obscure lab-sample records no Food-101 label would ever match anyway.\r\nfunction parseCsv(text) {\r\n const lines = text.split(/\\r?\\n/);\r\n if (lines.at(-1) === '') lines.pop();\r\n const rows = lines.map(line => line.slice(1, -1).split('\",\"').map(f => f.replace(/\"\"/g, '\"')));\r\n const cols = rows[0].length;\r\n return rows.filter(r => r.length === cols);\r\n}\r\nasync function readCsv(path) { return parseCsv(await readFile(path, 'utf8')); }\r\n\r\nasync function ensureDataset({key, zip}) {\r\n const zipPath = join(CACHE_DIR, zip);\r\n const extractDir = join(CACHE_DIR, key);\r\n if (existsSync(extractDir)) return findCsvRoot(extractDir);\r\n await mkdir(CACHE_DIR, {recursive: true});\r\n if (!existsSync(zipPath)) {\r\n  console.log(`Downloading ${zip}...`);\r\n  const res = await fetch(FDC_BASE + zip);\r\n  if (!res.ok) throw new Error(`${zip}: HTTP ${res.status}`);\r\n  await writeFile(zipPath, Buffer.from(await res.arrayBuffer()));\r\n }\r\n await mkdir(extractDir, {recursive: true});\r\n const unzip = spawnSync('unzip', ['-oq', zipPath, '-d', extractDir]);\r\n if (unzip.status !== 0) throw new Error(`unzip ${zip} failed: ${unzip.stderr}`);\r\n return findCsvRoot(extractDir);\r\n}\r\nasync function findCsvRoot(dir) {\r\n const entries = await readdir(dir, {withFileTypes: true});\r\n const sub = entries.find(e => e.isDirectory());\r\n return sub ? join(dir, sub.name) : dir;\r\n}\r\n\r\nasync function loadDataset(spec) {\r\n const root = await ensureDataset(spec);\r\n const [foodRows, nutrientRows, portionRows, nutrientDictRows, measureUnitRows] = await Promise.all(\r\n  ['food.csv', 'food_nutrient.csv', 'food_portion.csv', 'nutrient.csv', 'measure_unit.csv'].map(f => readCsv(join(root, f)))\r\n );\r\n const foods = new Map(); // fdcId -> {description, dataType}\r\n for (const [fdcId, dataType, description] of foodRows.slice(1)) foods.set(fdcId, {description, dataType});\r\n const measureUnits = new Map();\r\n for (const [id, name] of measureUnitRows.slice(1)) measureUnits.set(id, name);\r\n // nutrient.csv: id,name,unit_name,nutrient_nbr,rank -- we key by nutrient_nbr (the stable USDA number).\r\n const nutrientIdByNumber = new Map();\r\n for (const [id, , , nbr] of nutrientDictRows.slice(1)) nutrientIdByNumber.set(nbr, id);\r\n return {foods, measureUnits, nutrientRows: nutrientRows.slice(1), portionRows: portionRows.slice(1), nutrientIdByNumber};\r\n}\r\n\r\n// USDA nutrient numbers we need, and (for vitamins) the %DV table -- mirrors food/pyramid-tiles.mjs's\r\n// VITAMIN_DV so the top-2-by-%DV pick here matches what that screen would compute at runtime.\r\nconst MACRO_NBR = {kcal: '208', proteinG: '203', fatG: '204', carbsG: '205'};\r\nconst VITAMIN_NBR = {vitaminA: '320', vitaminC: '401', vitaminD: '328', vitaminE: '323', vitaminB12: '418', folate: '417'};\r\nconst VITAMIN_DV = {vitaminA: 900, vitaminC: 90, vitaminD: 20, vitaminE: 15, vitaminB12: 2.4, folate: 400};\r\nconst VITAMIN_NAME = {vitaminA: 'Vitamin A', vitaminC: 'Vitamin C', vitaminD: 'Vitamin D', vitaminE: 'Vitamin E', vitaminB12: 'Vitamin B12', folate: 'Folate'};\r\nconst VITAMIN_UNIT = {vitaminA: 'µg RAE', vitaminC: 'mg', vitaminD: 'µg', vitaminE: 'mg', vitaminB12: 'µg', folate: 'µg'};\r\n\r\nfunction scoreCandidate(queryWords, description) {\r\n const descWords = words(description);\r\n const matched = queryWords.filter(w => descWords.includes(w)).length;\r\n const coverage = matched / queryWords.length;\r\n return {coverage, length: descWords.length};\r\n}\r\n\r\nfunction bestMatch(dataset, queryWords) {\r\n let best = null;\r\n for (const [fdcId, {description}] of dataset.foods) {\r\n  const {coverage, length} = scoreCandidate(queryWords, description);\r\n  if (coverage === 0) continue;\r\n  if (!best || coverage > best.coverage || (coverage === best.coverage && length < best.length)) {\r\n   best = {fdcId, description, coverage, length};\r\n  }\r\n }\r\n return best;\r\n}\r\n\r\n// Every usable (nonzero gram, nameable) FDC portion row for a food, in the dataset's own seq_num order.\r\nfunction rawPortions(dataset, fdcId) {\r\n const rows = dataset.portionRows.filter(r => r[1] === fdcId).sort((a, b) => Number(a[2] || 0) - Number(b[2] || 0));\r\n const out = [];\r\n for (const row of rows) {\r\n  const [, , , amount, measureUnitId, portionDescription, modifier, gramWeight] = row;\r\n  const grams = Number(gramWeight);\r\n  if (!Number.isFinite(grams) || grams <= 0) continue;\r\n  let name = portionDescription && portionDescription !== 'Quantity not specified' ? portionDescription : '';\r\n  // `modifier` is usually free text (\"serving\") but sometimes carries a bare measure_unit_id reference\r\n  // code (e.g. \"90000\") instead, typically paired with an empty portion_description -- skip those as\r\n  // unlabeled rather than showing the raw code.\r\n  if (!name && modifier && !/^\\d+$/.test(modifier)) name = amount ? `${amount} ${modifier}` : modifier;\r\n  if (!name) { const unit = dataset.measureUnits.get(measureUnitId); if (unit && unit !== 'undetermined') name = amount ? `${amount} ${unit}` : unit; }\r\n  if (name) out.push({name: name.trim(), servingG: grams});\r\n }\r\n return out;\r\n}\r\n\r\n// A photo is of a plated meal, not a lab reference amount -- FDC's *first* portion is often a garnish-size\r\n// or whole-recipe outlier (french fries \"1 fry\" 5 g, chocolate mousse \"1 recipe yield\" 808 g). Rule (per\r\n// conductor review): drop portions that read as a crumb/garnish/whole-batch unit unless that leaves\r\n// nothing; from what's left, take whichever is closest to a 150 g plate by log distance (log distance\r\n// treats \"half of 150\" and \"double 150\" as equally far, which a plain gram difference would not); if\r\n// everything left is still under 60 g (sushi, wings, dumplings, mussels...), report N of that single unit\r\n// instead (N = round(150/unit), capped at 12) rather than one unrealistic bite.\r\nconst EXCLUDE_PORTION_RE = /recipe|yield|miniature|bite|tiny|fry\\b|chip\\b|pod\\b|tbsp|tablespoon|teaspoon|cracker-size/i;\r\nconst DIP_LABELS = new Set(['guacamole', 'hummus']); // a dip is eaten a couple tablespoons at a time, not by the cup\r\nfunction closestByLogDistance(list, targetG) {\r\n return list.reduce((best, p) => {\r\n  const d = Math.abs(Math.log(p.servingG) - Math.log(targetG));\r\n  return !best || d < best.d ? {...p, d} : best;\r\n }, null);\r\n}\r\nfunction pluralizeUnit(name) {\r\n const m = /^1\\s+([a-zA-Z][a-zA-Z ]*)$/.exec(name); // \"1 cookie\" -> \"cookie\"; anything fancier stays \"pieces\"\r\n if (!m) return null;\r\n const noun = m[1];\r\n if (/^oz$/i.test(noun)) return noun; // abbreviated units (FDC's \"1 oz\") don't take an 's'\r\n if (/[^aeiou]y$/i.test(noun)) return noun.slice(0, -1) + 'ies'; // patty -> patties, not pattys\r\n return /[sxz]$|[cs]h$/i.test(noun) ? noun + 'es' : noun + 's';\r\n}\r\nfunction pickPortion(dataset, fdcId, label) {\r\n const all = rawPortions(dataset, fdcId);\r\n if (!all.length) return null;\r\n if (DIP_LABELS.has(label)) {\r\n  const tbsp = all.find(p => /tablespoon|tbsp/i.test(p.name));\r\n  if (tbsp) return {servingName: `2 ${tbsp.name.replace(/^1\\s+/, '')}`, servingG: round(tbsp.servingG * 2, 0), rule: 'dip: 2x tablespoon portion'};\r\n  const closest = closestByLogDistance(all, 30);\r\n  return {servingName: closest.name, servingG: closest.servingG, rule: 'dip: closest to 30 g'};\r\n }\r\n const kept = all.filter(p => !EXCLUDE_PORTION_RE.test(p.name));\r\n const candidates = kept.length ? kept : all;\r\n const prefix = kept.length ? '' : 'no non-excluded portion; ';\r\n if (candidates.every(p => p.servingG < 60)) {\r\n  const unit = candidates[0];\r\n  const n = Math.min(12, Math.max(1, Math.round(150 / unit.servingG)));\r\n  const name = n === 1 ? unit.name : `${n} ${pluralizeUnit(unit.name) || 'pieces'}`;\r\n  return {servingName: name, servingG: round(n * unit.servingG, 0), rule: `${prefix}small units only, x${n} (${unit.servingG} g each)`};\r\n }\r\n const closest = closestByLogDistance(candidates, 150);\r\n return {servingName: closest.name, servingG: closest.servingG, rule: `${prefix}closest to 150 g`};\r\n}\r\n\r\nfunction nutrientAmountPer100g(dataset, fdcId, nutrientNbr) {\r\n // Foundation/SR Legacy food_nutrient.csv key nutrient_id by nutrient.csv's internal id (e.g. 1008 for\r\n // Energy); Survey/FNDDS's food_nutrient.csv keys it by the raw USDA nutrient number instead (208). No\r\n // id/nbr collide (checked), so matching either is safe and dataset-agnostic.\r\n const nutrientId = dataset.nutrientIdByNumber.get(nutrientNbr);\r\n const row = dataset.nutrientRows.find(r => r[1] === fdcId && (r[2] === nutrientId || r[2] === nutrientNbr));\r\n return row ? Number(row[3]) : null;\r\n}\r\n\r\nfunction round(v, d = 1) { const m = 10 ** d; return Math.round(v * m) / m; }\r\n\r\nasync function buildEntry(label, datasets) {\r\n const overrideQuery = QUERY[label] || label;\r\n const queryWords = words(overrideQuery);\r\n let picked = null, dataset = null;\r\n for (const ds of datasets) {\r\n  const candidate = bestMatch(ds, queryWords);\r\n  if (candidate && candidate.coverage === 1) { picked = candidate; dataset = ds; break; }\r\n  if (candidate && (!picked || candidate.coverage > picked.coverage)) { picked = candidate; dataset = ds; }\r\n }\r\n if (!picked) return {label, entry: null, note: 'no FDC match at all'};\r\n const {fdcId, description, coverage} = picked;\r\n const portion = pickPortion(dataset, fdcId, label);\r\n const servingG = portion?.servingG ?? 100;\r\n const servingName = portion?.servingName ?? '100 g';\r\n const scale = servingG / 100;\r\n const macros = {};\r\n for (const [key, nbr] of Object.entries(MACRO_NBR)) {\r\n  const per100 = nutrientAmountPer100g(dataset, fdcId, nbr);\r\n  macros[key] = per100 == null ? null : round(per100 * scale, key === 'kcal' ? 0 : 1);\r\n }\r\n const vitaminPcts = [];\r\n for (const [key, nbr] of Object.entries(VITAMIN_NBR)) {\r\n  const per100 = nutrientAmountPer100g(dataset, fdcId, nbr);\r\n  if (per100 == null) continue;\r\n  const amount = round(per100 * scale, 2);\r\n  const pct = amount / VITAMIN_DV[key];\r\n  if (pct > 0) vitaminPcts.push({key, amount, pct});\r\n }\r\n vitaminPcts.sort((a, b) => b.pct - a.pct);\r\n const vitamins = vitaminPcts.slice(0, 2).map(v => ({name: VITAMIN_NAME[v.key], amount: v.amount, unit: VITAMIN_UNIT[v.key]}));\r\n const notes = [];\r\n if (!portion) notes.push('fell back to 100 g (no usable FDC portion)');\r\n if (coverage < 1 || KNOWN_PROXY.has(label)) notes.push(`approximate match only (word coverage ${coverage.toFixed(2)}) -- no exact FDC entry for this dish`);\r\n return {\r\n  label,\r\n  entry: {fdcId: Number(fdcId), description, servingName, servingG, ...macros, vitamins},\r\n  note: notes.join('; ') || null,\r\n  coverage, dataset: dataset.key, portionRule: portion?.rule ?? 'no FDC portion at all',\r\n };\r\n}\r\n\r\nconst datasets = [];\r\nfor (const spec of DATASETS) { console.log(`Loading ${spec.key}...`); datasets.push({key: spec.key, ...await loadDataset(spec)}); }\r\n\r\nconst result = {};\r\nconst fallbacks = [];\r\nconst report = [];\r\nfor (const label of LABELS) {\r\n const {entry, note, coverage, dataset, portionRule} = await buildEntry(label, datasets);\r\n if (!entry) { fallbacks.push(`${label}: NO MATCH`); continue; }\r\n result[label] = entry;\r\n report.push(`${label.padEnd(28)} -> [${dataset}] fdc:${entry.fdcId} \"${entry.description}\" (coverage ${coverage.toFixed(2)}, ${entry.servingName}, ${entry.servingG} g, ${entry.kcal} kcal) [${portionRule}]`);\r\n if (note) fallbacks.push(`${label}: ${note}`);\r\n}\r\n\r\nconsole.log(report.join('\\n'));\r\nconsole.log('\\n--- fallbacks / notes ---');\r\nconsole.log(fallbacks.length ? fallbacks.join('\\n') : '(none)');\r\nconsole.log(`\\n${Object.keys(result).length} / ${LABELS.length} labels resolved.`);\r\n\r\nawait mkdir('food', {recursive: true});\r\nawait writeFile('food/nutrition-fdc.json', JSON.stringify(result, null, 1) + '\\n');\r\nconsole.log('Wrote food/nutrition-fdc.json');\r\n","scripts/build-hand.mjs":"import {spawnSync} from 'node:child_process';\r\nimport {readFile,writeFile,cp} from 'node:fs/promises';\r\nconst source=new URL('../handborne/source/',import.meta.url);\r\n// One authoritative implementation for both editors. This also catches accidental drift.\r\nfor(const name of ['material-language.ts','material-patterns.ts','material-refinement.ts','palette-finishes.ts','palettes.json']){\r\n await cp(new URL('../creature/source/creator/'+name,import.meta.url),new URL('app/'+name,source));\r\n}\r\nconst result=spawnSync(process.execPath,['scripts/build-embedded.mjs'],{cwd:source,stdio:'inherit'});\r\nif(result.status!==0)throw Error('Hand customizer build failed.');\r\nconst out=new URL('dist/embedded/',source),target=new URL('../handborne/',import.meta.url);\r\nawait cp(new URL('assets/',out),new URL('assets/',target),{recursive:true});\r\nawait cp(new URL('companion.mjs',out),new URL('companion.mjs',target));\r\nawait cp(new URL('unlock-bridge.mjs',out),new URL('unlock-bridge.mjs',target));\r\nconst built=await readFile(new URL('index.html',out),'utf8');\r\nconst js=built.match(/src=\"([^\"]+\\.js)\"/)?.[1],css=built.match(/href=\"([^\"]+\\.css)\"/)?.[1];\r\nif(!js||!css)throw Error('Hand build entrypoints missing.');\r\nlet index=await readFile(new URL('index.html',target),'utf8');\r\nindex=index.replace(/data-module=\"[^\"]+\"/,`data-module=\"${js}\"`).replace(/href=\"\\/handborne\\/assets\\/[^\\\"]+\\.css\"/,`href=\"${css}\"`);\r\nawait writeFile(new URL('index.html',target),index);\r\nconsole.log('Hand customizer shares current Coach materials.');\r\n","scripts/build-optional-packs.mjs":"// Rank 2b: builds optional-art packs from plan/assets-inbox/ + asset-manifest.json\r\n// (paths are given as arguments; this script never assumes the plan repo's\r\n// location) into the /packs/<pack-id>/<version>/... + /packs/index.json layout,\r\n// signed with the EXISTING pack-catalog mechanism (packs/catalog-trust.mjs,\r\n// packs/catalog-config.mjs — the same Ed25519 catalog scheme\r\n// scripts/provision-pack-catalog-keys.mjs provisions as a GitHub secret).\r\n//\r\n// Never reads/prints/copies the real signing key: a key file path only ever\r\n// flows into crypto.createPrivateKey/sign, never into a log line, and this\r\n// script never writes one to disk. With no key, it produces an unsigned dry\r\n// run and says so plainly — the output cannot pass verifyPackCatalog().\r\nimport { createHash, createPrivateKey, createPublicKey, sign as edSign } from 'node:crypto';\r\nimport { existsSync } from 'node:fs';\r\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\r\nimport { basename, extname, join } from 'node:path';\r\nimport { pathToFileURL } from 'node:url';\r\nimport {\r\n  PACK_CATALOG_PROTOCOL, PACK_CATALOG_SCHEMA, PACK_ASSET_MAX_BYTES, PACK_TOTAL_MAX_BYTES,\r\n  canonicalCatalogPayload, verifyPackCatalog,\r\n} from '../packs/catalog-trust.mjs';\r\nimport { productionCatalogKeyring } from '../packs/catalog-config.mjs';\r\nimport { PACK_HOST_BASE_URL } from '../packs/pack-host-config.mjs';\r\n\r\nconst DEFAULT_VERSION = '1.0.0';\r\nconst DEFAULT_MIN_APP_VERSION = '1.0.0';\r\nconst SPDX_ORIGINAL = 'LicenseRef-MomInc-Original';\r\n\r\nexport class PackSizeError extends Error {}\r\n\r\nexport const sha256Hex = bytes => createHash('sha256').update(bytes).digest('hex');\r\n\r\nfunction concatBytes(chunks) {\r\n  const out = new Uint8Array(chunks.reduce((n, c) => n + c.byteLength, 0));\r\n  let offset = 0;\r\n  for (const chunk of chunks) { out.set(chunk, offset); offset += chunk.byteLength; }\r\n  return out;\r\n}\r\n\r\nexport async function loadAssetManifest(manifestPath) {\r\n  const parsed = JSON.parse(await readFile(manifestPath, 'utf8'));\r\n  if (!Array.isArray(parsed.assets)) throw new Error(`${manifestPath} is missing an \"assets\" array`);\r\n  return parsed;\r\n}\r\n\r\n/**\r\n * Splits manifest entries into ones whose file exists in assets-inbox\r\n * (`found`, with bytes/sha256 computed) and ones that don't yet (`pending`,\r\n * e.g. the \"status\": \"template\" placeholder that ships with an empty inbox).\r\n */\r\nexport async function resolveAssets(manifest, inboxDir) {\r\n  const found = [], pending = [];\r\n  for (const entry of manifest.assets) {\r\n    const filePath = join(inboxDir, entry.filename);\r\n    if (!existsSync(filePath)) { pending.push(entry); continue; }\r\n    const data = await readFile(filePath);\r\n    found.push({ ...entry, bytes: data.byteLength, sha256: sha256Hex(data), data });\r\n  }\r\n  return { found, pending };\r\n}\r\n\r\nfunction groupByPack(assets) {\r\n  const packs = new Map();\r\n  for (const asset of assets) {\r\n    if (!asset.pack) throw new Error(`asset \"${asset.filename}\" has no \"pack\" id in asset-manifest.json`);\r\n    if (!packs.has(asset.pack)) packs.set(asset.pack, []);\r\n    packs.get(asset.pack).push(asset);\r\n  }\r\n  return packs;\r\n}\r\n\r\nconst spdxFor = license => (!license || license === 'original') ? SPDX_ORIGINAL : license;\r\n\r\n/**\r\n * Builds one pack: content-addressed asset files, a pack-lifecycle-shaped\r\n * manifest.json (the shape packs/pack-lifecycle.mjs downloads and verifies\r\n * against), and the catalog entry pack-license-surface.mjs / catalog-state.mjs\r\n * expect inside /packs/index.json. Throws PackSizeError if any asset or the\r\n * pack total is over the existing catalog's own caps (packs/catalog-trust.mjs\r\n * PACK_ASSET_MAX_BYTES / PACK_TOTAL_MAX_BYTES) rather than emit an\r\n * unverifiable catalog silently.\r\n */\r\nexport function buildPack({ packId, version = DEFAULT_VERSION, assets, minAppVersion = DEFAULT_MIN_APP_VERSION, fallbackId = 'builtin:none', baseUrl = PACK_HOST_BASE_URL }) {\r\n  const oversized = assets.filter(a => a.bytes > PACK_ASSET_MAX_BYTES);\r\n  if (oversized.length) throw new PackSizeError(`pack \"${packId}\": ${oversized.length} asset(s) exceed the ${PACK_ASSET_MAX_BYTES}-byte catalog cap: ${oversized.map(a => `${a.filename} (${a.bytes}B)`).join(', ')}`);\r\n\r\n  const manifestAssets = assets.map(asset => ({ path: `packs/${packId}/${version}/assets/${asset.sha256}${extname(asset.filename)}`, bytes: asset.bytes, sha256: asset.sha256 }));\r\n  const packManifest = { packId, version, minAppVersion, sha256: sha256Hex(concatBytes(assets.map(a => a.data))), assets: manifestAssets };\r\n  const manifestBytes = new TextEncoder().encode(JSON.stringify(packManifest));\r\n  const manifestHash = sha256Hex(manifestBytes);\r\n  const manifestPath = `/packs/${packId}/${version}/manifest.${manifestHash}.json`;\r\n\r\n  const dependencies = assets.map((asset, i) => ({\r\n    name: basename(asset.filename, extname(asset.filename)),\r\n    version,\r\n    path: `/${manifestAssets[i].path}`,\r\n    bytes: asset.bytes,\r\n    sha256: asset.sha256,\r\n    spdx: spdxFor(asset.license),\r\n    sourceUrl: /^https:\\/\\//.test(asset.source || '') ? asset.source : `${baseUrl}/${manifestAssets[i].path}`,\r\n    attribution: asset.owner || 'MOM INC',\r\n  }));\r\n  const totalBytes = manifestBytes.byteLength + dependencies.reduce((sum, d) => sum + d.bytes, 0);\r\n  if (totalBytes > PACK_TOTAL_MAX_BYTES) throw new PackSizeError(`pack \"${packId}\": total ${totalBytes}B exceeds the ${PACK_TOTAL_MAX_BYTES}-byte catalog cap`);\r\n\r\n  return {\r\n    catalogEntry: { packId, version, fallbackId, manifest: { path: manifestPath, bytes: manifestBytes.byteLength, sha256: manifestHash }, dependencies, totalBytes },\r\n    files: [...assets.map((a, i) => ({ path: manifestAssets[i].path, data: a.data })), { path: `packs/${packId}/${version}/manifest.${manifestHash}.json`, data: manifestBytes }],\r\n  };\r\n}\r\n\r\nexport function deriveKeyId(privateKeyJwk, keyring) {\r\n  const publicJwk = createPublicKey(createPrivateKey({ key: privateKeyJwk, format: 'jwk' })).export({ format: 'jwk' });\r\n  const match = keyring.find(entry => entry.publicKey.x === publicJwk.x);\r\n  if (!match) throw new Error('signing key does not match any entry in the production keyring (packs/catalog-keys.generated.mjs) — wrong key file?');\r\n  return match.keyId;\r\n}\r\n\r\nexport function signCatalog(unsignedCatalog, privateKeyJwk, keyId) {\r\n  const candidate = { ...unsignedCatalog, keyId, alg: 'Ed25519', signature: '' };\r\n  const signature = edSign(null, Buffer.from(canonicalCatalogPayload(candidate)), createPrivateKey({ key: privateKeyJwk, format: 'jwk' })).toString('base64');\r\n  return { ...candidate, signature };\r\n}\r\n\r\n/**\r\n * Full build: reads the manifest + inbox, builds every declared pack,\r\n * writes /packs/<id>/<version>/... plus /packs/index.json under outDir, and\r\n * signs the catalog only if keyPath is given (env var or CLI argument) —\r\n * otherwise returns an explicit unsigned dry run. The private key file's\r\n * *contents* are read only to sign in-memory; they are never logged, never\r\n * copied into outDir, and never returned in the result.\r\n */\r\nexport async function buildOptionalPacks({ manifestPath, inboxDir, outDir, keyPath, generation = 1, writeManifest = false, keyring = productionCatalogKeyring() }) {\r\n  const manifest = await loadAssetManifest(manifestPath);\r\n  const { found, pending } = await resolveAssets(manifest, inboxDir);\r\n  const grouped = groupByPack(found);\r\n\r\n  const packs = [], errors = [];\r\n  for (const [packId, assets] of grouped) {\r\n    try { packs.push(buildPack({ packId, version: manifest.packVersions?.[packId] ?? DEFAULT_VERSION, assets })); }\r\n    catch (error) { errors.push({ packId, message: error.message }); }\r\n  }\r\n\r\n  for (const pack of packs) for (const file of pack.files) {\r\n    const target = join(outDir, file.path);\r\n    await mkdir(join(target, '..'), { recursive: true });\r\n    await writeFile(target, file.data);\r\n  }\r\n\r\n  let catalog = { schema: PACK_CATALOG_SCHEMA, protocol: PACK_CATALOG_PROTOCOL, generation, publishedAt: Date.now(), packs: packs.map(p => p.catalogEntry) };\r\n  let signed = false, keyId = null, verified = null;\r\n  if (keyPath) {\r\n    const jwk = JSON.parse(await readFile(keyPath, 'utf8')); // never logged, never persisted\r\n    keyId = deriveKeyId(jwk, keyring);\r\n    catalog = signCatalog(catalog, jwk, keyId);\r\n    signed = true;\r\n    verified = await verifyPackCatalog(catalog, keyring);\r\n  } else {\r\n    catalog = { ...catalog, keyId: null, alg: 'Ed25519', signature: null, dryRun: true };\r\n  }\r\n  await mkdir(join(outDir, 'packs'), { recursive: true });\r\n  await writeFile(join(outDir, 'packs', 'index.json'), JSON.stringify(catalog, null, 2) + '\\n');\r\n\r\n  if (writeManifest && found.length) {\r\n    const byFilename = new Map(found.map(a => [a.filename, a]));\r\n    manifest.assets = manifest.assets.map(entry => byFilename.has(entry.filename) ? { ...entry, bytes: byFilename.get(entry.filename).bytes, sha256: byFilename.get(entry.filename).sha256 } : entry);\r\n    await writeFile(manifestPath, JSON.stringify(manifest, null, 2));\r\n  }\r\n\r\n  const sizes = packs.map(p => ({ packId: p.catalogEntry.packId, version: p.catalogEntry.version, assets: p.catalogEntry.dependencies.length, totalBytes: p.catalogEntry.totalBytes }));\r\n  return { signed, keyId, verified, packs: sizes, pendingAssets: pending.map(p => p.filename), errors, outDir };\r\n}\r\n\r\nasync function main() {\r\n  const args = Object.fromEntries(process.argv.slice(2).map(arg => { const [k, ...v] = arg.replace(/^--/, '').split('='); return [k, v.join('=') || true]; }));\r\n  const manifestPath = args.manifest || process.env.MYR5_PACK_ASSET_MANIFEST;\r\n  const inboxDir = args.inbox || process.env.MYR5_PACK_ASSETS_INBOX;\r\n  const outDir = args.out || process.env.MYR5_PACK_OUT_DIR;\r\n  const keyPath = args.key || process.env.MYR5_PACK_CATALOG_SIGNING_KEY_FILE || null;\r\n  if (!manifestPath || !inboxDir || !outDir) throw new Error('usage: node build-optional-packs.mjs --manifest=<asset-manifest.json> --inbox=<assets-inbox dir> --out=<output dir> [--key=<private jwk file>] [--generation=N] [--write-manifest]');\r\n  const result = await buildOptionalPacks({ manifestPath, inboxDir, outDir, keyPath, generation: args.generation ? Number(args.generation) : 1, writeManifest: Boolean(args['write-manifest']) });\r\n  console.log(JSON.stringify(result, null, 2));\r\n  if (!result.signed) console.log('\\nUNSIGNED DRY RUN — no key file was given, so /packs/index.json has signature:null and will NOT pass verifyPackCatalog(). Pass --key=<path-to-private-jwk> (never commit that file) to produce a real signed catalog.');\r\n  if (result.pendingAssets.length) console.log(`\\n${result.pendingAssets.length} manifest entr${result.pendingAssets.length === 1 ? 'y' : 'ies'} not yet in assets-inbox, skipped: ${result.pendingAssets.join(', ')}`);\r\n  if (result.errors.length) { console.log(`\\n${result.errors.length} pack(s) failed to build:`); for (const e of result.errors) console.log(`  - ${e.packId}: ${e.message}`); }\r\n}\r\n\r\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) await main();\r\n","scripts/build-post-download-sections.mjs":"// Deterministic builder for per-track resumable post-download sections.\r\n// It writes content bundles and unsigned chunk-manifest templates outside core/Sites.\r\nimport { createHash } from 'node:crypto';\r\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\r\nimport { dirname, join, resolve } from 'node:path';\r\nimport { pathToFileURL } from 'node:url';\r\nimport { parseMaterialsBaseUrl } from './material-release.mjs';\r\n\r\nconst MAP_ORDER = ['basecolor','normal','roughness','height','metalness','tintMask','ao','opacity','emissive','preview'];\r\nconst hash = bytes => createHash('sha256').update(bytes).digest('hex');\r\n\r\nfunction makeBundle(entries) {\r\n  const index = Object.create(null);\r\n  let offset = 0;\r\n  for (const [name, bytes] of entries) { if(!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(name)||name.includes('..')||Object.hasOwn(index,name)||!bytes.byteLength)throw new Error('unsafe or duplicate bundle entry');index[name] = { offset, bytes: bytes.byteLength, sha256: hash(bytes) }; offset += bytes.byteLength; }\r\n  const header = Buffer.from(JSON.stringify(index));\r\n  const prefix = Buffer.alloc(4); prefix.writeUInt32BE(header.byteLength);\r\n  return Buffer.concat([prefix, header, ...entries.map(([, bytes]) => bytes)]);\r\n}\r\n\r\nasync function chunkRecord(bytes, { path, url, chunkBytes }) {\r\n  const chunks = [];\r\n  for (let offset = 0, index = 0; offset < bytes.byteLength; offset += chunkBytes, index++) {\r\n    const data = bytes.subarray(offset, Math.min(offset + chunkBytes, bytes.byteLength));\r\n    chunks.push({ index, offset, bytes: data.byteLength, sha256: hash(data), url });\r\n  }\r\n  return { path, bytes: bytes.byteLength, sha256: hash(bytes), chunks };\r\n}\r\n\r\nexport async function buildPostDownloadSections({ root = process.cwd(), outputDir = join(root, 'plan/assets-inbox/post-download-sections'), baseUrl = process.env.MYR5_MATERIALS_BASE_URL, chunkBytes = 1024 * 1024, materialize = true } = {}) {\r\n  if (!Number.isInteger(chunkBytes) || chunkBytes < 1 || chunkBytes > 1024 * 1024) throw new Error('chunk size must obey the 1 MiB chunk-delivery policy');\r\n  baseUrl=parseMaterialsBaseUrl(baseUrl).baseUrl;\r\n  const output = resolve(outputDir), generated = [];\r\n  const sections = [];\r\n  const sourcePackets = await Promise.all(['forged-realms','celestial-rift'].map(async packet => ({\r\n    packet,\r\n    root: join(root, `plan/assets-inbox/creature-skins/${packet}`),\r\n    items: JSON.parse(await readFile(join(root, `plan/assets-inbox/creature-skins/${packet}/source-manifest.json`), 'utf8')).items,\r\n  })));\r\n  const trackNames = [...new Set(sourcePackets.flatMap(packet => packet.items.map(item => item.track)))].sort();\r\n  const expectedTracks=['arms','cardio','chest','glutes','martial-arts','meditation','quads','yoga'];\r\n  if(JSON.stringify(trackNames)!==JSON.stringify(expectedTracks))throw new Error('expected exactly eight known track packets');\r\n  const ids=new Set();for(const source of sourcePackets)for(const item of source.items){if(!/^creature-[a-z0-9-]+$/.test(item.id)||ids.has(item.id)||![1,2,3].includes(item.collectionSlot))throw new Error('invalid source skin identity');ids.add(item.id);}\r\n  if(ids.size!==48)throw new Error('expected exactly 48 source skins');\r\n  for (const track of trackNames) {\r\n    const packId = `track-${track}`, packDir = join(output, packId), entries = [];\r\n    for (const source of sourcePackets) {\r\n      for (const item of source.items.filter(row => row.track === track).sort((a,b) => a.collectionSlot - b.collectionSlot)) {\r\n        for (const map of MAP_ORDER) {\r\n          const meta = item.maps[map];\r\n          if (!meta) continue;\r\n          if(!/^[A-Za-z0-9][A-Za-z0-9._/-]*$/.test(meta.file||'')||meta.file.includes('..'))throw new Error('unsafe source texture path');\r\n          const bytes = await readFile(join(source.root, meta.file));\r\n          if (bytes.byteLength !== meta.bytes || hash(bytes) !== meta.sha256) throw new Error(`source packet checksum mismatch: ${item.id}/${map}`);\r\n          entries.push([`${item.id}/${map}`, bytes]);\r\n        }\r\n      }\r\n    }\r\n    const bundle = makeBundle(entries), rel = `assets/${track}.m5bundle`;\r\n    if(materialize){await mkdir(dirname(join(packDir, rel)), { recursive: true });await writeFile(join(packDir, rel), bundle);}\r\n    const url = `${baseUrl}/${packId}/1.0.0/${track}.m5bundle`;\r\n    const assets = [await chunkRecord(bundle, { path: rel, url, chunkBytes })];\r\n    sections.push(unsignedSection({ packId, assets }));\r\n    generated.push({ id: packId, assets: assets.length, bytes: bundle.byteLength, directory: packDir });\r\n  }\r\n\r\n  // Stage the six scene ships and fold all 24 tiny biome plates into one indexed asset.\r\n  const shipRoot = join(root, 'plan/assets-inbox/ships'), shipPackDir = join(output, 'coach-ships-biomes');\r\n  const shipAssets = [];\r\n  for (const ship of ['supportive','direct','analytical','playful','calm','mom']) {\r\n    const bytes = await readFile(join(shipRoot, `${ship}.glb`));\r\n    const rel = `assets/ships/${ship}.glb`;\r\n    if(materialize){await mkdir(dirname(join(shipPackDir, rel)), { recursive: true });await writeFile(join(shipPackDir, rel), bytes);}\r\n    shipAssets.push(await chunkRecord(bytes, { path: rel, url: `${baseUrl}/coach-ships-biomes/1.0.0/${ship}.glb`, chunkBytes }));\r\n  }\r\n  const biomeRoot = join(root, 'plan/assets-inbox/biomes'), biomeFiles = ['original','patch','fold','lattice','wax','fungi','glass','bristle','cork','coral','metal','feather','moss','stormcloud','frost','ember','shadow','dragon','spring','vine','chitin','puff','rock','shag'].map(name => `${name}.webp`);\r\n  const biomeEntries = [];\r\n  for (const filename of biomeFiles) biomeEntries.push([filename, await readFile(join(biomeRoot, filename))]);\r\n  const biomeBundle = makeBundle(biomeEntries), biomePath = 'assets/biomes.m5bundle';\r\n  if(materialize){await mkdir(dirname(join(shipPackDir, biomePath)), { recursive: true });await writeFile(join(shipPackDir, biomePath), biomeBundle);}\r\n  shipAssets.push(await chunkRecord(biomeBundle, { path: biomePath, url: `${baseUrl}/coach-ships-biomes/1.0.0/biomes.m5bundle`, chunkBytes }));\r\n  sections.push(unsignedSection({ packId: 'coach-ships-biomes', assets: shipAssets }));\r\n  generated.push({ id: 'coach-ships-biomes', assets: shipAssets.length, bytes: shipAssets.reduce((n,a)=>n+a.bytes,0), directory: shipPackDir });\r\n\r\n  for (const section of sections) {\r\n    const dir = join(output, section.packId);\r\n    await mkdir(dir, { recursive: true });\r\n    await writeFile(join(dir, 'chunk-manifest.unsigned.json'), JSON.stringify(section, null, 2) + '\\n');\r\n    await writeFile(join(dir, 'section.json'), JSON.stringify({ id: section.packId, delivery: 'resumable-verified-chunks', signed: false, activation: 'blocked-until-signed-and-hosted', bytes: section.assets.reduce((n,a)=>n+a.bytes,0), assets: section.assets.map(a=>a.path) }, null, 2) + '\\n');\r\n  }\r\n  return { signed: false, activation: 'blocked-until-signed-and-hosted', sections: generated };\r\n}\r\n\r\nfunction unsignedSection({ packId, assets }) {\r\n  return { schema: 'mom-material-chunks-v1', packId, version: '1.0.0', keyId: 'mom-material-production-v1', assets, signature: '' };\r\n}\r\n\r\nexport function unpackBundle(value) {\r\n  const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);\r\n  if (bytes.byteLength < 4) throw new Error('truncated bundle header');\r\n  const length = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength).getUint32(0);\r\n  if (length < 2 || length > bytes.byteLength - 4) throw new Error('invalid bundle index length');\r\n  const index = JSON.parse(new TextDecoder().decode(bytes.subarray(4, 4 + length)));\r\n  const contentStart = 4 + length, output = new Map();\r\n  for (const [name, entry] of Object.entries(index)) {\r\n    if (!Number.isSafeInteger(entry.offset) || !Number.isSafeInteger(entry.bytes) || entry.offset < 0 || entry.bytes < 0 || contentStart + entry.offset + entry.bytes > bytes.byteLength) throw new Error(`invalid bundle range: ${name}`);\r\n    const item = bytes.slice(contentStart + entry.offset, contentStart + entry.offset + entry.bytes);\r\n    if (hash(item) !== entry.sha256) throw new Error(`bundle entry digest mismatch: ${name}`);\r\n    output.set(name, item);\r\n  }\r\n  return output;\r\n}\r\n\r\nif (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {\r\n  const arg = name => process.argv.find(x => x.startsWith(`--${name}=`))?.slice(name.length + 3);\r\n  console.log(JSON.stringify(await buildPostDownloadSections({ outputDir: arg('out') || undefined, baseUrl: arg('base-url') || undefined, materialize: !process.argv.includes('--metadata-only') }), null, 2));\r\n}\r\n","scripts/build-pyramid-scanner.py":"# Pyramid food scanner GLB: preserve the authored mesh (ratio 1.0), split dials, add screens + lens.\r\n# Run: blender -b -P scripts/build-pyramid-scanner.py -- food/pyramid-scanner.glb\r\n# Do not decimate or quantize this scanner; its controls and sculpted body stay at authored resolution.\r\nimport bpy, bmesh, math, json, sys, hashlib\r\nfrom mathutils import Vector\r\nfrom mathutils.geometry import intersect_line_plane\r\nSRC=r\"C:/Users/ianmy/Downloads/pyramid+nutrition+robot+3d+model.glb\"\r\nOUT=sys.argv[sys.argv.index('--')+1]\r\nRATIO=float(sys.argv[sys.argv.index('--')+2]) if len(sys.argv)>sys.argv.index('--')+2 else 1.0\r\nif RATIO != 1.0:\r\n    raise ValueError('Quality-preserving pyramid build requires decimation ratio 1.0')\r\nwith open(SRC,'rb') as source_file:\r\n    print('PYRAMID_SOURCE_SHA256',hashlib.sha256(source_file.read()).hexdigest())\r\nKNOB_R=0.046\r\nS=1.15/800  # ortho_scale / px, matches render.py\r\nSCREENS={  # name box nudged right to cover the bezel\r\n  # view-0 pixel boxes (x0,y0,x1,y1) of the baked screens\r\n 'screen_name':(350,240,461,318),'screen_calories':(320,339,395,400),'screen_protein':(403,339,480,400),\r\n 'screen_fat':(286,418,352,490),'screen_carbs':(366,418,435,490),'screen_vitamins':(446,418,514,490)}\r\nLENS=(0,400,128)\r\n# dial cap centres + axes (Blender coords), measured head-on in dial.py/prof.py\r\nDIALS=[((0.2539,-0.1033,0.4261),(0.845,-0.34,0.414)),((-0.2497,-0.0937,0.4257),(-0.877,-0.289,0.385)),((0.1157,0.2132,0.4222),(0.133,0.895,0.426))]\r\n\r\nbpy.ops.wm.read_factory_settings(use_empty=True)\r\nbpy.ops.import_scene.gltf(filepath=SRC)\r\nsc=bpy.context.scene\r\nbody=[o for o in sc.objects if o.type=='MESH'][0]; body.name='body'\r\nbpy.context.view_layer.objects.active=body; body.select_set(True)\r\nbpy.ops.object.transform_apply(location=True,rotation=True,scale=True)\r\nm=body.modifiers.new('d','DECIMATE'); m.ratio=RATIO; bpy.ops.object.modifier_apply(modifier='d')\r\ndg=bpy.context.evaluated_depsgraph_get()\r\n\r\ndef ray(view,px,py):\r\n    r=math.radians(view); loc=Vector((2*math.sin(r),-2*math.cos(r),0.55))\r\n    fwd=(Vector((0,0,0.49))-loc).normalized(); right=fwd.cross(Vector((0,0,1))).normalized(); up=right.cross(fwd)\r\n    return loc+right*(px-400)*S+up*(400-py)*S, fwd\r\ndef hit(view,px,py):\r\n    o,d=ray(view,px,py); h,p,n,*_=sc.ray_cast(dg,o,d)\r\n    assert h,(view,px,py); return p,n\r\ngl=lambda v:[round(v.x,5),round(v.z,5),round(-v.y,5)]  # Blender Z-up -> glTF Y-up\r\n\r\n# screens: plane from interior hits, corners = corner rays hitting that plane, lifted 2mm\r\nfor name,(x0,y0,x1,y1) in SCREENS.items():\r\n    x0,y0,x1,y1=x0-3,y0-3,x1+3,y1+3\r\n    pts=[hit(0,x0+(x1-x0)*fx,y0+(y1-y0)*fy) for fx in (.25,.5,.75) for fy in (.25,.5,.75)]\r\n    c=sum((p for p,_ in pts),Vector())/len(pts); n=sum((q for _,q in pts),Vector()).normalized()\r\n    c=c+n*0.005\r\n    corners=[intersect_line_plane(o,o+d,c,n) for o,d in (ray(0,x,y) for x,y in ((x0,y1),(x1,y1),(x1,y0),(x0,y0)))]\r\n    # push any body geometry in front of the screen (raised apple, bezel lips) 1mm behind it\r\n    e1=corners[1]-corners[0]; e2=corners[3]-corners[0]\r\n    for v in body.data.vertices:\r\n        d=v.co-corners[0]; u=d.dot(e1)/e1.length_squared; w=d.dot(e2)/e2.length_squared; h=(v.co-c).dot(n)\r\n        if 0.03<u<0.97 and 0.03<w<0.97 and -0.001<h<0.03: v.co-=n*(h+0.001)\r\n    me=bpy.data.meshes.new(name); me.from_pydata([v-c for v in corners],[],[(0,1,2,3)])\r\n    uv=me.uv_layers.new(); [setattr(uv.data[i],'uv',t) for i,t in enumerate(((0,0),(1,0),(1,1),(0,1)))]\r\n    mat=bpy.data.materials.get('screen') or bpy.data.materials.new('screen'); me.materials.append(mat)\r\n    ob=bpy.data.objects.new(name,me); ob.location=c; sc.collection.objects.link(ob)\r\n    ob['normal']=gl(n)\r\n\r\np,n=hit(*LENS); lens=bpy.data.objects.new('lens',None); lens.location=p; lens['normal']=gl(n); lens['radius']=0.03\r\nsc.collection.objects.link(lens)\r\n\r\n# dials: split faces inside a cylinder around each dial normal\r\nfound=[(Vector(c),Vector(n).normalized()) for c,n in DIALS]\r\nbpy.context.view_layer.objects.active=body\r\nfor i,(c,n) in enumerate(found):\r\n    bpy.ops.object.mode_set(mode='EDIT'); bm=bmesh.from_edit_mesh(body.data)\r\n    for f in bm.faces: f.select=False\r\n    def inside(v):\r\n        d=v.co-c; a=d.dot(n); return -0.016<a<0.012 and (d-n*a).length<KNOB_R\r\n    for f in bm.faces:\r\n        if all(inside(v) for v in f.verts): f.select=True\r\n    bmesh.update_edit_mesh(body.data); bpy.ops.mesh.separate(type='SELECTED'); bpy.ops.object.mode_set(mode='OBJECT')\r\n    k=[o for o in bpy.context.selected_objects if o is not body][0]; k.name=f'knob_{i}'; k.select_set(False)\r\n    k.data.transform(__import__('mathutils').Matrix.Translation(-c)); k.location=c\r\n    k['axis']=gl(n); body.select_set(True)\r\nprint('KNOBS',len(found),[gl(c) for c,_ in found])\r\nbpy.ops.object.select_all(action='SELECT')\r\nbpy.ops.export_scene.gltf(filepath=OUT,export_format='GLB',export_extras=True,export_yup=True,use_selection=False)\r\n","scripts/build-shader-effects.mjs":"// Rebuild the locally served MIT runtime; no account or runtime CDN is required.\r\nimport {build} from 'esbuild';\r\nimport {mkdir,readFile,writeFile} from 'node:fs/promises';\r\nimport {createRequire} from 'node:module';\r\nimport {dirname,resolve} from 'node:path';\r\nimport {createHash} from 'node:crypto';\r\nconst require=createRequire(import.meta.url);\r\nconst search=process.env.SHADER_BUILD_NODE_PATH ? [process.env.SHADER_BUILD_NODE_PATH] : [];\r\nconst core=require.resolve('shaders/core',{paths:[resolve('.'),...search]});\r\nconst root=resolve(dirname(core),'../..');\r\nconst entry=resolve(root,'dist/js/index.js');\r\nconst pkg=JSON.parse(await readFile(resolve(root,'package.json'),'utf8'));\r\nif(pkg.version!=='4.0.4')throw Error('Expected the reviewed shaders4.0.4 runtime.');\r\nconst {outputFiles:[output]}=await build({stdin:{contents:`export {createShader} from ${JSON.stringify(entry)};`,resolveDir:root},bundle:true,format:'esm',target:'es2022',minify:true,write:false,legalComments:'eof'});\r\nawait mkdir('vendor/shaders',{recursive:true});\r\nawait writeFile('vendor/shaders/runtime.mjs',output.contents);\r\nawait writeFile('vendor/shaders/LICENSE',await readFile(resolve(root,'LICENSE')));\r\nawait writeFile('vendor/shaders/version.json',JSON.stringify({package:'shaders',version:pkg.version,license:pkg.license,source:'https://github.com/shader-effects-inc/shaders',sha256:createHash('sha256').update(output.contents).digest('hex')}));\r\n","scripts/build-starter-ship.py":"# Starter ship GLB for Original MYR5: initialScene(fresh recipe) picks 'supportive' (coach 'supportive').\r\n# run: blender -b -P scripts/build-starter-ship.py -- D:/coach-merge/creature/models/ships/supportive.glb pod/worlds/starter/supportive.glb 0.04 512\r\n# Decimates the Tripo mesh, shrinks textures (colour TEX px, normal/metal-rough TEX/2) and exports WebP textures\r\n# (EXT_texture_webp, which GLTFLoader reads natively). Node, mesh and material names are kept as imported.\r\n# The other starter files are plain encodes/copies (PIL): pod/worlds/great-wall.webp = great-wall.png at WebP q90 m6;\r\n# pod/worlds/starter/<wonder>.webp = plan/assets-inbox/backgrounds/clean/<wonder>.webp unchanged.\r\nimport bpy, bmesh, sys\r\nSRC, OUT, RATIO, TEX = (lambda a: (a[0], a[1], float(a[2]), int(a[3])))(sys.argv[sys.argv.index('--') + 1:])\r\n\r\nbpy.ops.wm.read_factory_settings(use_empty=True)\r\nbpy.ops.import_scene.gltf(filepath=SRC)\r\nfor ob in [o for o in bpy.context.scene.objects if o.type == 'MESH']:\r\n    bpy.context.view_layer.objects.active = ob\r\n    # weld the split seams first: open seam boundaries stop decimate collapsing below ~9k tris\r\n    bm = bmesh.new(); bm.from_mesh(ob.data); bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=1e-6); bm.to_mesh(ob.data); bm.free()\r\n    m = ob.modifiers.new('decimate', 'DECIMATE'); m.ratio = RATIO; m.use_collapse_triangulate = True\r\n    bpy.ops.object.modifier_apply(modifier=m.name)\r\n    print('TRIS', ob.name, len(ob.data.polygons))\r\ncolour = {n.image.name for mat in bpy.data.materials if mat.node_tree for n in mat.node_tree.nodes\r\n          if n.type == 'TEX_IMAGE' and n.image and any(l.to_socket.name == 'Base Color' for l in n.outputs[0].links)}\r\nfor img in bpy.data.images:\r\n    size = TEX if img.name in colour else TEX // 2\r\n    if img.size[0] > size: img.scale(size, size)\r\n    print('IMAGE', img.name, tuple(img.size))\r\nbpy.ops.export_scene.gltf(filepath=OUT, export_format='GLB', export_yup=True, export_image_format='WEBP', export_image_quality=80)\r\n","scripts/build.mjs":"import './build-hand.mjs';\r\nimport './build-shader-effects.mjs';\r\nimport {build} from 'vite';\r\nimport {resolve,sep} from 'node:path';\r\nimport {optimizeModels} from './optimize-glb.mjs';\r\nimport {sites} from '@openai/sites-vite-plugin';\r\nimport {mkdir,cp,readdir,readFile,writeFile,unlink,rm} from 'node:fs/promises';\r\nimport {deploymentSize,WORKERS_FILE_LIMIT,WORKERS_FILE_BYTES} from './deployment-size.mjs';\r\nimport {omitDuplicateCoachIcon} from './icon-stage.mjs';\r\nimport {ensureAssets,ensureHandAssets,ensureThreeVendor} from './assets.mjs';\r\nimport {ensureMediapipe} from './mediapipe.mjs';\r\nimport {build as bundleEditor} from 'esbuild';\r\nimport {gzipSync} from 'node:zlib';\r\n// All app pages share the vendored Three core; addons remain bundled by esbuild.\r\nconst vendoredThree={name:'vendored-three',setup(build){build.onResolve({filter:/^three$/},()=>({path:'three',external:true}));}};\r\nimport {prepareReleaseBuild} from './release-build.mjs';\r\nimport {writeOfflineWorker} from './offline-assets.mjs';\r\nimport {sourceOffer} from './source-offer.mjs';\r\nimport {packNutrition} from './pack-nutrition.mjs';\r\nimport {assertMaterialTrustShipped,copySignedMaterialManifests,loadMaterialPublicBuildConfig} from './material-release.mjs';\r\n// Public release trust is committed in release-trust/public-build.json; an env var of the same name overrides it.\r\nfor(const [key,value] of Object.entries(JSON.parse(await readFile('release-trust/public-build.json','utf8'))))if(!key.startsWith('$')&&value!==null)process.env[key]??=typeof value==='string'?value:JSON.stringify(value);\r\nconst publicExpansionKey=process.env.PUBLIC_EXPANSION_SIGNING_JWK ? JSON.parse(process.env.PUBLIC_EXPANSION_SIGNING_JWK) : null;\r\nif(publicExpansionKey && !(publicExpansionKey.kty==='OKP' && publicExpansionKey.crv==='Ed25519' && typeof publicExpansionKey.x==='string' && /^[A-Za-z0-9_-]{43}$/.test(publicExpansionKey.x) && !/^A+$/.test(publicExpansionKey.x))) throw new Error('PUBLIC_EXPANSION_SIGNING_JWK must be a non-placeholder Ed25519 public JWK');\r\nif(process.env.MYR5_MATERIAL_SIGNING_PRIVATE_JWK)throw new Error('Do not expose a private material signing key to the Sites build.');\r\nconst materialRelease=loadMaterialPublicBuildConfig(),materialManifestSource=process.env.MYR5_MATERIAL_SITE_MANIFESTS;\r\nif(materialRelease.configured&&!materialManifestSource)throw new Error('MYR5_MATERIAL_SITE_MANIFESTS is required when material release trust is configured.');\r\nif(!materialRelease.configured&&materialManifestSource)throw new Error('Signed material manifests cannot be copied without matching public trust and immutable host configuration.');\r\nawait ensureAssets();\r\nawait ensureHandAssets();\r\nawait ensureThreeVendor();\r\nawait ensureMediapipe();\r\nawait bundleEditor({entryPoints:['./creature/source/editor.ts'],bundle:true,format:'esm',target:'es2022',minify:true,sourcemap:true,outfile:'creature/assets/editor.js',plugins:[vendoredThree],define:materialRelease.defines});\r\n// The app viewer must use the same recipe catalog and materials as the editor.\r\nawait bundleEditor({entryPoints:['./creature/source/phone.ts'],bundle:true,format:'esm',target:'es2022',minify:true,sourcemap:true,outfile:'creature/assets/phone.js',plugins:[vendoredThree],define:materialRelease.defines});\r\nawait bundleEditor({entryPoints:['./creature/source/reward-preview.ts'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'creature/assets/reward-preview.js',plugins:[vendoredThree],define:materialRelease.defines});\r\n// The War Room's Gala character bay reuses the cage room and its Draco loader, so it is bundled like the editor.\r\nawait bundleEditor({entryPoints:['./creature/source/war-room-gala.ts'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'war-room/gala-bay.js',plugins:[vendoredThree]});\r\nawait bundleEditor({entryPoints:['./creature/source/war-room-coaches.ts'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'war-room/coach-sprites.js'}); // R26: the pod's home character (lazy)\r\nawait bundleEditor({entryPoints:['./weapon-training.mjs'],bundle:true,format:'iife',globalName:'MYR5Training',target:'es2022',minify:true,outfile:'workout-tracks.js'});\r\nawait bundleEditor({entryPoints:['./local-coach/browser-runtime.mjs'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'local-coach-runtime.mjs'});\r\nconst releaseBuild=await prepareReleaseBuild();\r\nawait bundleEditor({entryPoints:['./app.mjs'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'app-runtime.mjs',external:['https://*','./modules/coach-world/view.mjs','./local-coach-runtime.mjs','./arcade/slice/camera-slice.mjs','./arcade/runner/runner.mjs','./arcade/workout-effects.mjs','./arcade/hold/camera-hold.mjs','./arcade/hold/blizzard.mjs','./arcade/power/camera-power.mjs','./arcade/power/power.mjs','./arcade/power/retained-power.mjs','./arcade/power/avatar-power.mjs','./arcade/quest-progress-reporter.mjs','./creature/assets/phone.js','./modules/portal/portal-entry.mjs','./modules/ships/ship-view.mjs','./modules/ships/ship-intro.mjs','./modules/vault/vault-store.mjs','./modules/vault/vault-banner.mjs','./modules/vault/vault-door.mjs','./modules/vault/vault-hall.mjs','./modules/vault/vault-goals.mjs','./modules/vault/quest-progress.mjs','../modules/vault/quest-progress.mjs'],plugins:[vendoredThree],define:materialRelease.defines});\r\nawait bundleEditor({entryPoints:['./launch.mjs'],bundle:true,format:'esm',target:'es2022',minify:true,outfile:'launch-runtime.mjs',external:['three','three/addons/loaders/GLTFLoader.js','/handborne/companion.mjs','./nutrition-data.mjs','./local-coach-runtime.mjs','./food/pyramid-scanner.mjs','./drop-pod-opening.mjs','./modules/rooms/classroom.mjs','./modules/vault/vault-store.mjs'],define:materialRelease.defines});\r\nawait build({configFile:false,plugins:[sites()],build:{outDir:'dist/server',ssr:'server/cloudflare.mjs',target:'es2022',minify:true,rollupOptions:{output:{entryFileNames:'index.js',inlineDynamicImports:true}},ssrEmitAssets:false},ssr:{noExternal:true}});\r\nawait mkdir('dist/client',{recursive:true});\r\nawait rm('dist/client/materials',{recursive:true,force:true});\r\nfor(const entry of await readdir('.',{withFileTypes:true})){if(entry.isFile()&&/\\.(html|css|mjs|webmanifest)$/.test(entry.name))await cp(entry.name,`dist/client/${entry.name}`);}\r\nawait cp('workout-tracks.js','dist/client/workout-tracks.js');\r\n// Crawler files (robots/sitemap/llms) are served as static assets; never precached.\r\nfor(const file of ['robots.txt','sitemap.xml','llms.txt'])await cp(file,`dist/client/${file}`);\r\nconsole.log('Packed nutrition bytes removed:',await packNutrition());\r\nfor(const folder of ['pod','creature','models','icons','handborne','arcade','modules','packs','war-room','food','vendor','reward-assets','audio','pods'])await cp(folder,`dist/client/${folder}`,{recursive:true,filter:(p)=>!/[\\\\/]source[\\\\/].*node_modules(?:[\\\\/]|$)/.test(p)});\r\n// Legacy Coach 512 URL is aliased by the Worker and service worker.\r\nawait omitDuplicateCoachIcon('dist/client');\r\nif(materialRelease.configured){\r\n await copySignedMaterialManifests({sourceDir:materialManifestSource,siteRoot:'dist/client',baseUrl:process.env.MYR5_MATERIALS_BASE_URL,publicJwk:materialRelease.publicJwk});\r\n const configPath='dist/client/modules/materials/material-config.mjs';let config=await readFile(configPath,'utf8');\r\n config=config.replace(/export const BUILT_PUBLIC_MATERIAL_SIGNING_JWK = [^;]+;/,`export const BUILT_PUBLIC_MATERIAL_SIGNING_JWK = ${JSON.stringify(materialRelease.publicJwk)};`).replace(/export const BUILT_MATERIAL_RESOURCE_POLICY = [^;]+;/,`export const BUILT_MATERIAL_RESOURCE_POLICY = ${JSON.stringify(materialRelease.policy)};`);\r\n await writeFile(configPath,config);\r\n}\r\nawait assertMaterialTrustShipped('dist/client');\r\n// Achievement Vault: its raw modules reach .ts sources (unlock-store) that production strips, so bundle them in place (lazy, never core:\r\n// offline-assets VAULT). Splitting shares one store between door/hall; app-runtime/launch-runtime keep the store external so it is not inlined.\r\nawait bundleEditor({entryPoints:['modules/vault/vault-store.mjs','modules/vault/vault-banner.mjs','modules/vault/vault-door.mjs','modules/vault/vault-hall.mjs','modules/vault/quest-progress.mjs'],bundle:true,splitting:true,format:'esm',target:'es2022',minify:true,outdir:'dist/client/modules/vault',allowOverwrite:true,outExtension:{'.js':'.mjs'},external:['three','three/*','../portal/*','../../drop-pod-opening.mjs'],chunkNames:'chunk-[hash]'});\r\n// Authoring projects remain in the published source repository, not the app bundle.\r\nfor(const folder of ['creature/source','handborne/source']){const target=resolve('dist/client',folder);if(!target.startsWith(resolve('dist/client')+sep))throw Error('Invalid staging path');await rm(target,{recursive:true,force:true});}\r\n// Keep debugger-only maps in the open-source repository,\r\n// but not in the deployable static archive. Runtime code does not request them.\r\nfor(const path of [\r\n 'dist/client/handborne/assets/hand-entry-B7K7J180.js',\r\n 'dist/client/handborne/assets/hand-entry-BySRDxUO.css',\r\n 'dist/client/handborne/assets/GLTFExporter-CL_WC7Dc.js',\r\n 'dist/client/handborne/assets/OBJExporter-J3SdsgWZ.js',\r\n 'dist/client/creature/assets/chunk-2X4UOJKI.js',\r\n 'dist/client/creature/assets/chunk-FY3X2IKC.js',\r\n 'dist/client/creature/assets/chunk-QUSSDQTX.js',\r\n 'dist/client/creature/assets/chunk-2X4UOJKI.js.map',\r\n 'dist/client/creature/assets/chunk-FY3X2IKC.js.map',\r\n 'dist/client/creature/assets/chunk-QUSSDQTX.js.map',\r\n 'dist/client/creature/assets/editor.js.map',\r\n 'dist/client/creature/assets/phone.js.map',\r\n])await unlink(path);\r\nconsole.log('Model bytes saved:',await optimizeModels('dist/client/creature/models')+await optimizeModels('dist/client/handborne/models'));\r\n// The source configuration is intentionally empty. Only a validated public\r\n// verification JWK may be embedded in a release; signing material is never read.\r\nconst expansionConfigPath='dist/client/modules/new/expansion-config.mjs';\r\nawait writeFile(expansionConfigPath,(await readFile('modules/new/expansion-config.mjs','utf8')).replace('export const BUILT_PUBLIC_EXPANSION_SIGNING_JWK = null;',`export const BUILT_PUBLIC_EXPANSION_SIGNING_JWK = ${JSON.stringify(publicExpansionKey)};`));\r\n// Publish only the current voice pack, excluding obsolete clips and source masters.\r\nconst voiceManifest=JSON.parse(await readFile('voice/manifest.json','utf8'));\r\nawait mkdir('dist/client/voice',{recursive:true});\r\nfor(const entry of await readdir('dist/client/voice',{withFileTypes:true}))if(entry.isFile()&&/\\.(wav|mp3|json)$/.test(entry.name))await unlink('dist/client/voice/'+entry.name);\r\nawait cp('voice/manifest.json','dist/client/voice/manifest.json');\r\nfor(const url of new Set(Object.values(voiceManifest.phrases)))await cp('.'+url,'dist/client'+url);\r\nlet pose=(await readFile('pose.html','utf8')).replaceAll('startup-recovery-1',releaseBuild).replaceAll('rest-flow-1',releaseBuild);\r\n// One stylesheet in production: concatenate the <link rel=stylesheet> files in document order (every url() in them is absolute).\r\nconst cssLinks=[...pose.matchAll(/<link[^>]*rel=\"stylesheet\"[^>]*href=\"([^\"?]+)[^\"]*\"[^>]*>/g)];\r\nconst cssHrefs=cssLinks.map(m=>m[1]);\r\nawait writeFile('dist/client/app.css',(await Promise.all(cssHrefs.map(h=>readFile('.'+h,'utf8')))).join('\\n'));\r\nfor(const m of cssLinks)pose=pose.replace(m[0],'');\r\npose=pose.replace('<link rel=\"manifest\"',`<link rel=\"stylesheet\" href=\"/app.css?v=${releaseBuild}\"><link rel=\"manifest\"`);\r\nawait writeFile('dist/client/pose.html',pose);await writeFile('dist/client/index.html',pose);await cp('LICENSE','dist/client/LICENSE');\r\nawait writeOfflineWorker('dist/client',releaseBuild);\r\n// The AGPL source offer travels with the app, with no runtime secrets or user records (scripts/source-offer.mjs).\r\n// ponytail: two copies; /source.json is the Settings link, the Account panel (launch-shell.mjs) still links the .gz.\r\nconst sources=JSON.stringify(await sourceOffer());\r\nawait writeFile('dist/client/source.json',sources);await writeFile('dist/client/source.json.gz',gzipSync(sources,{level:9}));\r\nconst {files,payloadBytes,largest}=await deploymentSize('dist');\r\nconsole.log(`Workers limits: ${files} / ${WORKERS_FILE_LIMIT} files; largest ${largest.bytes} / ${WORKERS_FILE_BYTES} bytes (${largest.path}); ${payloadBytes} total bytes.`);\r\nconsole.log('Coach build ready.');\r\n","scripts/check-food.mjs":"import {pipeline,env} from '@huggingface/transformers';\r\nimport {mkdir,writeFile} from 'node:fs/promises';\r\nenv.cacheDir='../food-model-cache';\r\nconst model=await pipeline('image-classification','onnx-community/swin-finetuned-food101-ONNX',{device:'cpu',dtype:'q8',revision:'e5e50bfc6425aa546f3b4421ca8bd79d0dd610b8'});\r\nconst datasetUrl='https://datasets-server.huggingface.co/first-rows?dataset=ethz%2Ffood101&config=default&split=validation';\r\nconst response=await fetch(datasetUrl);if(!response.ok)throw Error(`Food fixture service: ${response.status}`);const data=await response.json();\r\nconst fixtures=data.rows.slice(0,2).map(x=>({source:datasetUrl,image:x.row.image.src,expected:data.features.find(f=>f.name==='label').type.names[x.row.label]}));\r\nfor(const offset of [5000,12500,20000]){const source=`https://datasets-server.huggingface.co/rows?dataset=ethz%2Ffood101&config=default&split=validation&offset=${offset}&length=1`;const d=await(await fetch(source)).json();fixtures.push({source,image:d.rows[0].row.image.src,expected:d.features.find(f=>f.name==='label').type.names[d.rows[0].row.label]});}\r\nfixtures.push({source:'https://huggingface.co/Xenova/clip-vit-base-patch32',image:'https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/tiger.jpg',expected:'non-food'});\r\nconst results=[];for(const f of fixtures){const result=await model(f.image,{top_k:4});results.push({expected:f.expected,top:result.slice(0,4),source:f.source});console.log(JSON.stringify(results.at(-1)));}\r\nawait writeFile('../food-recognition-check.json',JSON.stringify(results,null,2));\r\n","scripts/colour-census.mjs":"// R18 G2: count every hex across palettes.json + SIMPLE_COLORS + LEGACY_COLORS; the top 15 are the free colours. Ties keep first appearance (SIMPLE, LEGACY, then palettes).\r\nimport {build} from 'esbuild';\r\nglobalThis.localStorage={getItem:()=>null,setItem(){}};\r\nconst out=await build({stdin:{contents:\"export {COLORS,PALETTES} from './creature/source/creator/materials-registry';\",resolveDir:process.cwd(),loader:'ts'},bundle:true,format:'esm',platform:'neutral',mainFields:['module','main'],write:false,target:'es2022'});\r\nconst {COLORS,PALETTES}=await import('data:text/javascript;base64,'+Buffer.from(out.outputFiles[0].text).toString('base64'));\r\nfunction census(){\r\n const n=new Map();\r\n const add=h=>n.set(h.toLowerCase(),(n.get(h.toLowerCase())||0)+1);\r\n for(const c of COLORS)[c.primary,c.secondary,c.accent].forEach(add);\r\n for(const p of PALETTES)p.colors.forEach(add);\r\n return [...n].sort((a,b)=>b[1]-a[1]);\r\n}\r\n\r\nfor(const [h,c] of census().slice(0,15))console.log(h,c);\r\n","scripts/deployment-size.mjs":"import {readdir,stat} from 'node:fs/promises';\r\nimport {join} from 'node:path';\r\n\r\n// Cloudflare Workers static assets: 20,000 files per version (Free plan; Paid is 100,000)\r\n// and 25 MiB per file. There is no total-size cap, unlike the old 256 MiB Sites archive.\r\nexport const WORKERS_FILE_LIMIT=20000,WORKERS_FILE_BYTES=25*1024*1024;\r\n\r\n// Walk the whole dist tree (client assets plus the server bundle) after the build.\r\nexport async function deploymentSize(directory='dist',{fileLimit=WORKERS_FILE_LIMIT,fileBytes=WORKERS_FILE_BYTES}={}){\r\n let files=0,payloadBytes=0,largest={path:null,bytes:0};\r\n async function walk(path){for(const entry of await readdir(path,{withFileTypes:true})){const child=join(path,entry.name);if(entry.isDirectory())await walk(child);else if(entry.isFile()){const {size}=await stat(child);files++;payloadBytes+=size;if(size>largest.bytes)largest={path:child,bytes:size};}else throw new Error(`Non-regular deployment entry: ${child}`);}}\r\n await walk(directory);\r\n if(files>fileLimit)throw new Error(`Too many files for Workers: ${files} / ${fileLimit}.`);\r\n if(largest.bytes>fileBytes)throw new Error(`File too large for Workers: ${largest.path} is ${largest.bytes} / ${fileBytes} bytes.`);\r\n return {files,payloadBytes,largest};\r\n}\r\n","scripts/dev.mjs":"import {createServer} from 'vite';\r\nimport {build as bundleStartup} from 'esbuild';\r\nawait bundleStartup({entryPoints:['./creature/source/phone.ts','./creature/source/editor.ts','./creature/source/reward-preview.ts'],bundle:true,format:'esm',target:'es2022',outdir:'creature/assets'});\r\nawait bundleStartup({entryPoints:['./app.mjs'],bundle:true,format:'esm',target:'es2022',outfile:'app-runtime.mjs',external:['https://*','./modules/coach-world/view.mjs']});\r\nawait bundleStartup({entryPoints:['./launch.mjs'],bundle:true,format:'esm',target:'es2022',outfile:'launch-runtime.mjs',external:['./food/pyramid-scanner.mjs','./drop-pod-opening.mjs','/handborne/companion.mjs']});\nimport {sites} from '@openai/sites-vite-plugin';\r\nimport {Miniflare} from 'miniflare';\r\nimport {readFile,readdir} from 'node:fs/promises';\r\nimport {ensureHandAssets,ensureThreeVendor} from './assets.mjs';\r\nimport {ensureMediapipe} from './mediapipe.mjs';\r\nawait ensureHandAssets();\r\nawait ensureThreeVendor();\r\nawait ensureMediapipe();\r\nconst mf=new Miniflare({modules:true,script:'export default {fetch(){return new Response(\"ok\")}}',d1Databases:['DB'],d1Persist:'.wrangler/local-db'});\r\nconst DB=await mf.getD1Database('DB');\r\nawait DB.prepare('CREATE TABLE IF NOT EXISTS _local_migrations (name TEXT PRIMARY KEY)').run();\r\nfor(const name of (await readdir('drizzle')).filter(n=>n.endsWith('.sql')).sort()){if(await DB.prepare('SELECT name FROM _local_migrations WHERE name=?').bind(name).first())continue;const statements=(await readFile(`drizzle/${name}`,'utf8')).split('--> statement-breakpoint').map(s=>s.trim()).filter(Boolean);await DB.batch(statements.map(s=>DB.prepare(s)));await DB.prepare('INSERT INTO _local_migrations(name) VALUES(?)').bind(name).run();}\r\nconst server=await createServer({configFile:false,plugins:[sites(),{name:'coach-api',configureServer(server){return()=>server.middlewares.use(async(req,res,next)=>{if(!req.url.startsWith('/api/')&&req.url!=='/health')return next();try{const chunks=[];for await(const chunk of req)chunks.push(chunk);const request=new Request(`http://${req.headers.host}${req.url}`,{method:req.method,headers:req.headers,body:['GET','HEAD'].includes(req.method)?undefined:Buffer.concat(chunks)});const {default:worker}=await server.ssrLoadModule('/server/worker.mjs');const result=await worker.fetch(request,{DB,LOCAL_PREVIEW:true});res.writeHead(result.status,Object.fromEntries(result.headers));res.end(Buffer.from(await result.arrayBuffer()));}catch{res.writeHead(500);res.end('Local request failed');}})}}],server:{host:'127.0.0.1',port:Number(process.env.COACH_DEV_PORT)||5195,strictPort:true},appType:'mpa'});\r\nawait server.listen();server.printUrls();\r\nprocess.on('SIGINT',async()=>{await server.close();await mf.dispose();process.exit();});\r\n","scripts/encode-voice.mjs":"// Phone-friendly copies of the approved masters; no pitch or tempo changes.\r\nimport {readFile,writeFile,stat} from 'node:fs/promises';\r\nimport {execFile} from 'node:child_process';\r\nimport {promisify} from 'node:util';\r\nconst exec=promisify(execFile),engine=process.env.MYR5_FFMPEG||'ffmpeg';\r\nconst manifest=JSON.parse(await readFile('voice/manifest.json','utf8'));\r\nlet bytes=0,done=0;const entries=Object.entries(manifest.phrases);\r\nfor(const [text,url]of entries){\r\n const output=url.replace(/\\.wav$/,'.mp3');\r\n if(url!==output)await exec(engine,['-hide_banner','-loglevel','error','-y','-threads','1','-i','.'+url,'-c:a','libmp3lame','-q:a','3','-ac','1','.'+output],{windowsHide:true});\r\n manifest.phrases[text]=output;bytes+=(await stat('.'+output)).size;if(++done%300===0)console.log(`${done}/${entries.length} compact voice clips ready.`);\r\n}\r\nmanifest.bytes=bytes;manifest.format='mp3';await writeFile('voice/manifest.json',JSON.stringify(manifest));console.log(`Voice download: ${Math.round(bytes/1024/1024)} MB.`);\r\n","scripts/export-world-sprites.mjs":"// Export ORIGINAL MYR5 art into the existing Piskel editor format; no new editor.\r\nimport {mkdir,writeFile} from 'node:fs/promises';\r\nimport {deflateSync} from 'node:zlib';\r\nimport {rasterSprite,ART_KINDS,ART_DIRECTION} from '../modules/coach-world/pixel-art.mjs';\r\nconst out=new URL('../modules/coach-world/art/',import.meta.url);await mkdir(out,{recursive:true});\r\nfunction crc32(bytes){let crc=-1;for(const b of bytes){crc^=b;for(let i=0;i<8;i++)crc=(crc>>>1)^((crc&1)?0xedb88320:0);}return (crc^-1)>>>0;}\r\nfunction chunk(type,data){const header=Buffer.alloc(4);header.writeUInt32BE(data.length);const body=Buffer.concat([Buffer.from(type),data]),crc=Buffer.alloc(4);crc.writeUInt32BE(crc32(body));return Buffer.concat([header,body,crc]);}\r\nfunction png(width,height,rgba){const ihdr=Buffer.alloc(13);ihdr.writeUInt32BE(width);ihdr.writeUInt32BE(height,4);ihdr[8]=8;ihdr[9]=6;const rows=Buffer.alloc(height*(width*4+1));for(let y=0;y<height;y++)rgba.copy(rows,y*(width*4+1)+1,y*width*4,(y+1)*width*4);return Buffer.concat([Buffer.from([137,80,78,71,13,10,26,10]),chunk('IHDR',ihdr),chunk('IDAT',deflateSync(rows)),chunk('IEND',Buffer.alloc(0))]);}\r\nconst manifest={version:1,size:64,kinds:ART_KINDS,variants:5,factions:{}};\r\nfor(const faction of Object.keys(ART_DIRECTION)){\r\n const frames=[];for(let variant=0;variant<5;variant++)for(const kind of ART_KINDS)frames.push(rasterSprite(faction,kind,variant));\r\n const rgba=Buffer.alloc(frames.length*64*64*4),width=frames.length*64;\r\n for(let f=0;f<frames.length;f++){const sprite=frames[f];for(let y=0;y<64;y++)for(let x=0;x<64;x++){const n=sprite.pixels[y*64+x],c=sprite.palette[n],offset=(y*width+f*64+x)*4;if(n){rgba[offset]=parseInt(c.slice(1,3),16);rgba[offset+1]=parseInt(c.slice(3,5),16);rgba[offset+2]=parseInt(c.slice(5,7),16);rgba[offset+3]=255;}}}\r\n const image=png(width,64,rgba);await writeFile(new URL(`${faction}.png`,out),image);\r\n const file={modelVersion:2,piskel:{name:`MYR5 ${faction}`,description:'Original 64x64 sprites. Frames: 13 kinds per tier, five tiers. Upper-left light; one-cell outline. Export a selected frame as PNG and import with scripts/import-world-sprite.py.',fps:1,height:64,width:64,layers:[JSON.stringify({name:'Architecture and props',opacity:1,frameCount:frames.length,chunks:[{layout:frames.map((_,i)=>[i]),base64PNG:'data:image/png;base64,'+image.toString('base64')}]})],hiddenFrames:[]}};\r\n await writeFile(new URL(`${faction}.piskel`,out),JSON.stringify(file));manifest.factions[faction]={...ART_DIRECTION[faction],png:`${faction}.png`,source:`${faction}.piskel`,frames:frames.map((s,i)=>({kind:s.kind,variant:s.variant,frame:[i*64,0,64,64]}))};\r\n}\r\nawait writeFile(new URL('manifest.json',out),JSON.stringify(manifest,null,2)+'\\n');console.log('Exported seven editable Piskel sources and PNG sheets (455 sprites).');\r\n","scripts/icon-stage.mjs":"import {unlink} from 'node:fs/promises';\r\nimport {join} from 'node:path';\r\nexport async function omitDuplicateCoachIcon(root){try{await unlink(join(root,'icons','coach-512.png'));}catch(error){if(error?.code!=='ENOENT')throw error;}}\r\n","scripts/icons.mjs":"import sharp from 'sharp';\r\nimport {mkdir,copyFile} from 'node:fs/promises';\r\nawait mkdir('icons',{recursive:true});\r\n// Resize the original MYR5 artwork without redrawing or cropping it.\r\nconst source='icons/myr5-original.png',background='#21172f';\r\nasync function icon(size,name,ratio=.9){\r\n const edge=Math.round(size*ratio),pad=Math.floor((size-edge)/2);\r\n const art=await sharp(source).resize(edge,edge,{fit:'contain',background}).png().toBuffer();\r\n await sharp({create:{width:size,height:size,channels:3,background}}).composite([{input:art,left:pad,top:pad}]).removeAlpha().png().toFile('icons/'+name);\r\n}\r\nfor(const size of [192,512]){await icon(size,`myr5-alien-${size}.png`);await copyFile(`icons/myr5-alien-${size}.png`,`icons/coach-${size}.png`);}\r\nawait icon(180,'myr5-alien-apple.png');\r\nawait icon(512,'myr5-alien-maskable.png',.76);\r\n","scripts/import-world-sprite.py":"\"\"\"Import a selected 64x64 PNG frame from Piskel/Pixelorama into live sprite data.\r\nUsage: python scripts/import-world-sprite.py chest hq 0 edited.png\r\nRequires Pillow (already available in the studio Python environment).\r\n\"\"\"\r\nimport json, sys\r\nfrom pathlib import Path\r\nfrom PIL import Image\r\nroot=Path(__file__).resolve().parents[1]\r\nfaction,kind,tier,path=sys.argv[1:]\r\nassert faction in ('chest','quads','glutes','arms-shoulders','yoga','martial-arts','cardio')\r\nassert kind in ('hq','hall','building','ship','resource','shop','node','rubble','crew','production','expedition','foundation','drop')\r\nassert tier in ('0','1','2','3','4')\r\nim=Image.open(path).convert('RGBA')\r\nassert im.size==(64,64), 'Export a selected 64x64 frame, without resizing.'\r\ncolors=['#00000000']; pixels=[]\r\nfor r,g,b,a in im.getdata():\r\n    assert a in (0,255), 'Use hard alpha and disable antialiasing.'\r\n    c=f'#{r:02x}{g:02x}{b:02x}' if a else '#00000000'\r\n    if c not in colors: colors.append(c)\r\n    pixels.append(colors.index(c))\r\nassert len(colors)<=256, 'Use at most 255 visible colors.'\r\ntarget=root/'modules/coach-world/pixel-overrides.mjs'\r\ntext=target.read_text(encoding='utf-8')\r\ndata=json.loads(text.split('Object.freeze(',1)[1].rsplit(');',1)[0])\r\ndata[f'{faction}/{kind}/{tier}']={'palette':colors,'pixels':pixels}\r\ntarget.write_text('// Pixel-editor imports; regenerate sheets with scripts/export-world-sprites.mjs.\\nexport const SPRITE_OVERRIDES=Object.freeze('+json.dumps(data,separators=(',',':'))+');\\n',encoding='utf-8')\r\nprint('Imported',faction,kind,tier,'; reload the app to see the edited sprite.')\r\n","scripts/material-release.mjs":"import { createHash, createPrivateKey, createPublicKey, sign } from 'node:crypto';\r\nimport { mkdir, readFile, writeFile, readdir } from 'node:fs/promises';\r\nimport { dirname, join, resolve, sep } from 'node:path';\r\nimport { pathToFileURL } from 'node:url';\r\nimport { isDeepStrictEqual } from 'node:util';\r\nimport { canonicalChunkPayload, DEFAULT_LOCAL_RESOURCE_POLICY, validateChunkManifest, verifyChunkManifest } from '../modules/materials/chunk-delivery.mjs';\r\n\r\nexport const MATERIAL_SECTION_IDS=Object.freeze(['track-arms','track-cardio','track-chest','track-glutes','track-martial-arts','track-meditation','track-quads','track-yoga','coach-ships-biomes']);\r\nconst SHA=/^[a-f0-9]{40}$/;\r\nconst safeSegment=value=>typeof value==='string'&&/^[A-Za-z0-9_.-]{1,100}$/.test(value)&&value!=='.'&&value!=='..';\r\n\r\n/** Only a full commit object ID is accepted: branch and movable tag names are not immutable pins. */\r\nexport function parseMaterialsBaseUrl(value){\r\n let url;try{url=new URL(value);}catch{throw new Error('MYR5_MATERIALS_BASE_URL must be a commit-pinned raw.githubusercontent.com URL.');}\r\n const match=url.pathname.match(/^\\/([^/]+)\\/([^/]+)\\/([a-f0-9]{40})\\/materials$/);\r\n if(url.origin!=='https://raw.githubusercontent.com'||!match||!safeSegment(match[1])||!safeSegment(match[2])||!SHA.test(match[3])||url.username||url.password||url.search||url.hash)throw new Error('MYR5_MATERIALS_BASE_URL must be https://raw.githubusercontent.com/<owner>/<repo>/<40-char-commit>/materials.');\r\n return Object.freeze({baseUrl:url.href.replace(/\\/$/,''),trustedOrigins:Object.freeze([url.origin]),allowedProtocols:Object.freeze(['https:']),pathPrefix:`/${match[1]}/${match[2]}/${match[3]}/materials/`});\r\n}\r\n\r\nexport function publicJwkFromPrivate(input){\r\n let value;try{value=typeof input==='string'?JSON.parse(input):input;}catch{throw new Error('Material signing key must be an Ed25519 private JWK.');}\r\n if(!value||value.kty!=='OKP'||value.crv!=='Ed25519'||typeof value.d!=='string'||!/^[A-Za-z0-9_-]{43}$/.test(value.d)||typeof value.x!=='string'||!/^[A-Za-z0-9_-]{43}$/.test(value.x))throw new Error('Material signing key must be an Ed25519 private JWK.');\r\n try{const privateKey=createPrivateKey({key:value,format:'jwk'}),derived=createPublicKey(privateKey).export({format:'jwk'});if(derived.x!==value.x)throw new Error();return Object.freeze({kty:'OKP',crv:'Ed25519',x:derived.x});}catch{throw new Error('Material signing key is invalid.');}\r\n}\r\n\r\nexport function loadMaterialPublicBuildConfig(env=process.env){\r\n const rawKey=env.MYR5_MATERIAL_PUBLIC_SIGNING_JWK,base=env.MYR5_MATERIALS_BASE_URL;\r\n if(!rawKey&&!base)return Object.freeze({configured:false,defines:Object.freeze({}),policy:null,publicJwk:null});\r\n if(!rawKey||!base)throw new Error('Set both MYR5_MATERIAL_PUBLIC_SIGNING_JWK and MYR5_MATERIALS_BASE_URL, or neither.');\r\n const host=parseMaterialsBaseUrl(base);let key;try{key=JSON.parse(rawKey);}catch{throw new Error('MYR5_MATERIAL_PUBLIC_SIGNING_JWK must be a public Ed25519 JWK.');}\r\n if(!key||key.kty!=='OKP'||key.crv!=='Ed25519'||typeof key.x!=='string'||!/^[A-Za-z0-9_-]{43}$/.test(key.x)||'d'in key||Object.keys(key).some(field=>!['kty','crv','x','alg','use','key_ops','ext'].includes(field))||(key.key_ops&&(!Array.isArray(key.key_ops)||key.key_ops.some(op=>op!=='verify'))))throw new Error('MYR5_MATERIAL_PUBLIC_SIGNING_JWK must be a public Ed25519 JWK without private fields.');\r\n const publicJwk=Object.freeze({kty:'OKP',crv:'Ed25519',x:key.x}),policy=Object.freeze({trustedOrigins:host.trustedOrigins,allowedProtocols:host.allowedProtocols,pathPrefix:host.pathPrefix});\r\n return Object.freeze({configured:true,publicJwk,policy,defines:Object.freeze({__MYR5_MATERIAL_PUBLIC_JWK__:JSON.stringify(publicJwk),__MYR5_MATERIAL_RESOURCE_POLICY__:JSON.stringify(policy)})});\r\n}\r\n\r\nconst safeOutput=(root,path)=>{const full=resolve(path),base=resolve(root);if(full===base||!full.startsWith(base+sep))throw new Error('Output path must be a dedicated child directory.');return full;};\r\nconst digest=bytes=>createHash('sha256').update(bytes).digest('hex');\r\nconst expectedPaths=id=>id==='coach-ships-biomes'?['supportive','direct','analytical','playful','calm','mom'].map(ship=>`assets/ships/${ship}.glb`).concat('assets/biomes.m5bundle'):[`assets/${id.slice(6)}.m5bundle`];\r\nfunction validateSectionInventory(manifest,host){\r\n const expected=expectedPaths(manifest.packId).sort(),actual=manifest.assets.map(asset=>asset.path).sort();\r\n if(JSON.stringify(actual)!==JSON.stringify(expected))throw new Error(`Section asset inventory mismatch: ${manifest.packId}.`);\r\n for(const asset of manifest.assets){const filename=asset.path.split('/').at(-1),expectedUrl=`${host.baseUrl}/${manifest.packId}/1.0.0/${filename}`;if(asset.chunks.some(chunk=>chunk.url!==expectedUrl))throw new Error(`Section asset URL mismatch: ${manifest.packId}/${asset.path}.`);}\r\n}\r\n\r\n/** Signs all nine manifests, stages host bytes without overwriting conflicts, and stages only manifests for Sites. */\r\nexport async function signAndStageMaterialSections({inputDir,hostRoot,siteRoot,baseUrl,privateJwk,keyId='mom-material-production-v1'}={}){\r\n if(!inputDir||!hostRoot||!siteRoot||!privateJwk)throw new Error('Input, host stage, Site manifest stage, and signing key are required.');\r\n const host=parseMaterialsBaseUrl(baseUrl),input=resolve(inputDir),hostOut=resolve(hostRoot),siteOut=resolve(siteRoot);\r\n const inside=(parent,child)=>child===parent||child.startsWith(parent+sep);\r\n if(inside(input,hostOut)||inside(input,siteOut)||inside(hostOut,siteOut)||inside(siteOut,hostOut))throw new Error('Input, host stage, and Site manifest stage must be separate directory trees.');\r\n if(hostOut.split(sep).some(part=>['dist','client'].includes(part.toLowerCase())))throw new Error('Raw-host asset staging must remain outside deployable Sites directories.');\r\n await mkdir(hostOut,{recursive:true});await mkdir(siteOut,{recursive:true});if((await readdir(siteOut)).length)throw new Error('Site manifest staging must be an empty dedicated directory.');\r\n if(!/^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$/.test(keyId))throw new Error('Material key ID is invalid.');\r\n const publicJwk=publicJwkFromPrivate(privateJwk),privateKey=createPrivateKey({key:typeof privateJwk==='string'?JSON.parse(privateJwk):privateJwk,format:'jwk'}),policy={...DEFAULT_LOCAL_RESOURCE_POLICY,...host};\r\n const sectionSummaries=[];\r\n for(const id of MATERIAL_SECTION_IDS){\r\n  const dir=join(input,id);let manifest;try{manifest=JSON.parse(await readFile(join(dir,'chunk-manifest.unsigned.json'),'utf8'));}catch{throw new Error(`Missing unsigned manifest for ${id}.`);}\r\n  if(manifest.schema!=='mom-material-chunks-v1'||manifest.packId!==id||manifest.version!=='1.0.0'||!Array.isArray(manifest.assets)||!manifest.assets.length)throw new Error(`Unsigned manifest identity mismatch for ${id}.`);\r\n  manifest.keyId=keyId;manifest.signature='';validateChunkManifest(manifest,policy);validateSectionInventory(manifest,host);\r\n  const hostedPaths=new Set();for(const asset of manifest.assets){\r\n   const urls=new Set(asset.chunks.map(chunk=>chunk.url));if(urls.size!==1)throw new Error(`Asset URLs must resolve to one immutable file: ${id}/${asset.path}`);\r\n   const url=new URL([...urls][0]),expectedPrefix=`${host.baseUrl}/${id}/1.0.0/`,filename=decodeURIComponent(url.pathname.split('/').at(-1)||'');\r\n   if(url.origin!==host.trustedOrigins[0]||!url.href.startsWith(expectedPrefix)||url.search||url.hash)throw new Error(`Chunk URL escapes the configured immutable host: ${id}/${asset.path}`);\r\n   const bytes=await readFile(join(dir,asset.path));if(bytes.byteLength!==asset.bytes||await digest(bytes)!==asset.sha256)throw new Error(`Asset bytes do not match manifest: ${id}/${asset.path}`);\r\n   for(const chunk of asset.chunks)if(await digest(bytes.subarray(chunk.offset,chunk.offset+chunk.bytes))!==chunk.sha256)throw new Error(`Asset chunk hash mismatch: ${id}/${asset.path}/${chunk.index}`);\r\n   if(!safeSegment(filename)||url.pathname!==`${host.pathPrefix}${id}/1.0.0/${filename}`)throw new Error(`Chunk URL has an unsafe asset path: ${id}/${asset.path}`);\r\n   if(hostedPaths.has(url.pathname))throw new Error(`Two assets map to one hosted path: ${id}/${url.pathname}`);hostedPaths.add(url.pathname);\r\n   const destination=safeOutput(hostOut,join(hostOut,'materials',id,'1.0.0',filename));await mkdir(dirname(destination),{recursive:true});\r\n   try{const hosted=await readFile(destination);if(!hosted.equals(bytes))throw new Error(`Existing raw-host file differs from the signed source: ${id}/${filename}`);}catch(error){if(error?.code!=='ENOENT')throw error;await writeFile(destination,bytes,{flag:'wx'});}\r\n  }\r\n  // Publish only authenticated wire-format fields, never arbitrary input metadata.\r\n  manifest=JSON.parse(canonicalChunkPayload(manifest));manifest.signature=sign(null,Buffer.from(canonicalChunkPayload(manifest)),privateKey).toString('base64');\r\n  await verifyChunkManifest(manifest,publicJwk,policy);validateSectionInventory(manifest,host);\r\n  const siteManifest=safeOutput(siteOut,join(siteOut,'materials',id,'chunk-manifest.json'));await mkdir(dirname(siteManifest),{recursive:true});await writeFile(siteManifest,JSON.stringify(manifest,null,2)+'\\n');\r\n  sectionSummaries.push({id,assets:manifest.assets.length,bytes:manifest.assets.reduce((n,a)=>n+a.bytes,0)});\r\n }\r\n return Object.freeze({signed:true,publicJwk,policy,sections:Object.freeze(sectionSummaries)});\r\n}\r\n\r\nexport async function copySignedMaterialManifests({sourceDir,siteRoot,baseUrl,publicJwk}={}){\r\n if(!sourceDir||!siteRoot||!publicJwk)throw new Error('Signed manifest source, Site root, and public trust key are required.');\r\n if(publicJwk.kty!=='OKP'||publicJwk.crv!=='Ed25519'||typeof publicJwk.x!=='string'||!/^[A-Za-z0-9_-]{43}$/.test(publicJwk.x)||'d'in publicJwk)throw new Error('Signed manifest copy requires a public Ed25519 verification key.');\r\n const host=parseMaterialsBaseUrl(baseUrl),source=resolve(sourceDir),site=resolve(siteRoot),inside=(parent,child)=>child===parent||child.startsWith(parent+sep);\r\n if(inside(site,source))throw new Error('Signed manifests must be staged outside the Sites archive.');\r\n const policy={...DEFAULT_LOCAL_RESOURCE_POLICY,...host},copied=[];\r\n for(const id of MATERIAL_SECTION_IDS){\r\n  const path=join(source,'materials',id,'chunk-manifest.json');let manifest,bytes;try{bytes=await readFile(path);manifest=JSON.parse(bytes.toString('utf8'));}catch{throw new Error(`Missing signed Site manifest for ${id}.`);}\r\n  if(manifest.packId!==id||manifest.version!=='1.0.0'||!manifest.signature)throw new Error(`Signed manifest identity mismatch for ${id}.`);\r\n  await verifyChunkManifest(manifest,publicJwk,policy);validateSectionInventory(manifest,host);\r\n  if(!isDeepStrictEqual(manifest,{...JSON.parse(canonicalChunkPayload(manifest)),signature:manifest.signature}))throw new Error(`Signed manifest contains unauthenticated metadata: ${id}.`);\r\n  const destination=safeOutput(site,join(site,'materials',id,'chunk-manifest.json'));await mkdir(dirname(destination),{recursive:true});await writeFile(destination,bytes);copied.push(id);\r\n }\r\n return Object.freeze(copied);\r\n}\r\n\r\n/** Live shipped a bundle whose trust define was never set, so skins failed silently. Refuse that build. */\r\nexport async function assertMaterialTrustShipped(siteRoot){\r\n const manifests=await readdir(join(siteRoot,'materials')).catch(error=>{if(error?.code==='ENOENT')return [];throw error;});\r\n if(!manifests.length)return;\r\n for(const entry of await readdir(siteRoot,{recursive:true,withFileTypes:true}))if(entry.isFile()&&/\\.m?js$/.test(entry.name)){\r\n  const path=join(entry.parentPath,entry.name);\r\n  if(/(?:^|[\\\\/])(?:source|node_modules)[\\\\/]/.test(path))continue;\r\n  if((await readFile(path,'utf8')).includes('__MYR5_MATERIAL_PUBLIC_JWK__'))throw new Error(`Signed material manifests ship in ${siteRoot}/materials, but ${path} has no material public key (__MYR5_MATERIAL_PUBLIC_JWK__ is undefined), so skins and textures would not load. Keep release-trust/public-build.json (or set MYR5_MATERIAL_PUBLIC_SIGNING_JWK) and pass materialRelease.defines to every bundle that imports modules/materials.`);\r\n }\r\n}\r\n\r\nasync function stdinSecret(){if(process.stdin.isTTY)throw new Error('Provide the signing JWK through MYR5_MATERIAL_SIGNING_PRIVATE_JWK or stdin.');let text='';for await(const chunk of process.stdin)text+=chunk;if(!text.trim())throw new Error('Signing JWK input is empty.');return text.trim();}\r\nif(process.argv[1]&&import.meta.url===pathToFileURL(process.argv[1]).href){\r\n try{const inputDir=process.env.MYR5_POST_DOWNLOAD_INPUT_DIR,hostRoot=process.env.MYR5_MATERIAL_HOST_STAGE_DIR,siteRoot=process.env.MYR5_MATERIAL_SITE_MANIFESTS,baseUrl=process.env.MYR5_MATERIALS_BASE_URL,secret=process.env.MYR5_MATERIAL_SIGNING_PRIVATE_JWK??await stdinSecret();const result=await signAndStageMaterialSections({inputDir,hostRoot,siteRoot,baseUrl,privateJwk:secret,keyId:process.env.MYR5_MATERIAL_SIGNING_KEY_ID||undefined});process.stdout.write(JSON.stringify(result)+'\\n');}\r\n catch(error){process.stderr.write(`${error.message}\\n`);process.exitCode=1;}\r\n}\r\n","scripts/mechanical-grimoire-poster.cjs":"#!/usr/bin/env node\r\n/**\r\n * Re-render the 2D fallback poster pod/worlds/boards/cogs-poster.webp\r\n * from the final 3D board at rest.\r\n */\r\n\r\nconst path = require('node:path');\r\nconst fs = require('node:fs').promises;\r\nconst sharp = require('sharp');\r\n\r\nconst PORT = '5197';\r\nconst TARGET_WIDTH = 1024;\r\nconst VIEWPORT = { width: 1400, height: 1900, deviceScaleFactor: 1 };\r\nconst URL = `http://127.0.0.1:${PORT}`;\r\nconst OUTPUT_PATH = path.join(__dirname, '..', 'pod', 'worlds', 'boards', 'cogs-poster.webp');\r\n\r\nasync function main() {\r\n  // Set environment and start preview server in-process\r\n  process.env.MYR5_GRIMOIRE_PORT = PORT;\r\n  const server = require('./mechanical-grimoire-preview.cjs');\r\n\r\n  // Wait briefly for server to start\r\n  await new Promise(r => setTimeout(r, 100));\r\n\r\n  let browser, page;\r\n  try {\r\n    // Launch playwright\r\n    const { chromium } = require('playwright');\r\n    browser = await chromium.launch();\r\n    page = await browser.newPage();\r\n\r\n    // Set viewport\r\n    await page.setViewportSize(VIEWPORT);\r\n\r\n    // Navigate\r\n    await page.goto(URL, { waitUntil: 'networkidle' });\r\n\r\n    // Wait until window.board exists, window.errors.length === 0, plus 1500 ms\r\n    await page.waitForFunction(() => {\r\n      return window.board && window.errors.length === 0;\r\n    }, { timeout: 10000 });\r\n\r\n    await new Promise(r => setTimeout(r, 1500));\r\n\r\n    // Screenshot the #board canvas element\r\n    const boardElement = await page.$('#board');\r\n    if (!boardElement) {\r\n      throw new Error('#board element not found');\r\n    }\r\n\r\n    const screenshot = await boardElement.screenshot({ type: 'png' });\r\n\r\n    // Convert to webp with sharp, resize to width 1024 keeping aspect\r\n    const sharpImage = sharp(screenshot);\r\n    const metadata = await sharpImage.metadata();\r\n    const originalWidth = metadata.width;\r\n    const originalHeight = metadata.height;\r\n    const newHeight = Math.round((TARGET_WIDTH / originalWidth) * originalHeight);\r\n\r\n    const webpBuffer = await sharpImage\r\n      .resize(TARGET_WIDTH, newHeight, {\r\n        fit: 'fill',\r\n        withoutEnlargement: false,\r\n      })\r\n      .webp({ quality: 82 })\r\n      .toBuffer();\r\n\r\n    // Write output\r\n    await fs.writeFile(OUTPUT_PATH, webpBuffer);\r\n\r\n    // Report\r\n    const stats = await fs.stat(OUTPUT_PATH);\r\n    console.log(`Poster regenerated: ${TARGET_WIDTH}x${newHeight} (${stats.size} bytes)`);\r\n\r\n  } finally {\r\n    if (page) await page.close();\r\n    if (browser) await browser.close();\r\n    process.exit(0);\r\n  }\r\n}\r\n\r\nmain().catch(err => {\r\n  console.error('Error:', err);\r\n  process.exit(1);\r\n});\r\n","scripts/mechanical-grimoire-preview.cjs":"// Local review harness: node scripts/mechanical-grimoire-preview.cjs\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..');\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Mechanical grimoire review</title><style>\r\n*{box-sizing:border-box}body{margin:0;background:#090d11;color:#dce5eb;font:14px system-ui}main{display:flex;align-items:center;justify-content:center;gap:32px;min-height:100vh;padding:24px}#board{width:min(66vw,570px);height:calc(100vh - 48px);max-height:880px;position:relative;background:radial-gradient(ellipse,#284050,#090d11 65%)}aside{width:240px}h1{font-size:24px}p{line-height:1.6;color:#94a6b4}label{display:flex;align-items:center;justify-content:space-between;margin:18px 0}button,select{background:#263943;border:1px solid #3f5665;color:#dce5eb;border-radius:6px;padding:10px;margin:4px 0;width:100%}#status{font-size:12px}@media(max-width:650px){main{padding:8px;gap:8px;flex-direction:column}#board{width:100%;height:70vh}aside{width:100%}h1,p{display:none}}\r\n</style><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><main><div id=\"board\"></div><aside><h1>Mechanical grimoire</h1><p>Drag along a shape to turn its gear train. Complete it to release the metal assembly.</p><label>Mechanism <input aria-label=\"Mechanism colour\" id=\"mechanism\" type=\"color\" value=\"#c59a56\"></label><label>Back wall <input aria-label=\"Back wall colour\" id=\"backplate\" type=\"color\" value=\"#263943\"></label><select id=\"shape\" aria-label=\"Shape\"></select><label>Progress <input aria-label=\"Progress\" id=\"progress\" type=\"range\" min=\"0\" max=\"1\" step=\"0.01\" value=\"0\"></label><button id=\"trace\">Trace selected shape</button><button id=\"release\">Release selected shape</button><button id=\"reset\">Reset assemblies</button><p id=\"status\">Loading existing models…</p></aside></main><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';import {cogs} from '/modules/portal/portal-board-cogs.mjs';import {mechanicalPaths} from '/modules/portal/portal-mechanical-layout.mjs';import {SHAPES,fromFrame} from '/modules/portal/portal-shapes.mjs';import {portalWindow} from '/modules/portal/portal-apertures.mjs';\r\nconst host=document.querySelector('#board'),status=document.querySelector('#status');window.errors=[];window.addEventListener('error',e=>errors.push(e.message));\r\ntry{window.board=await createGlbBoard(host,{effect:cogs});board.setTint('#c59a56');board.setBackplateTint('#263943');status.textContent='Ready — drag the metal contours';\r\ndocument.querySelector('#mechanism').oninput=e=>board.setTint(e.target.value);document.querySelector('#backplate').oninput=e=>board.setBackplateTint(e.target.value);\r\nconst select=document.querySelector('#shape');[...Object.keys(SHAPES).filter(id=>id!=='line'),'line-lr','line-rl','line-down'].forEach(id=>select.add(new Option(id,id)));const polys=()=>{const id=select.value,templates=id.startsWith('line-')?[SHAPES.line[id==='line-down'?0:1]]:SHAPES[id];return templates.map(p=>p.points.map(([u,v])=>fromFrame(u,v,cogs.frame)));};const aperture=()=>{const f=board.faceRect(),F=cogs.frame,rect={left:F.x0*f.width,top:F.y0*f.height,width:(F.x1-F.x0)*f.width,height:(F.y1-F.y0)*f.height},id=select.value==='cross'?'rect':select.value==='hdiamond'?'vdiamond':select.value;return portalWindow(id,rect).pts.map(([x,y])=>[x/f.width,y/f.height]);};\r\nwindow.traceShape=async()=>{board.heal();const f=board.faceRect();for(const poly of polys()){board.press(99,f.left+poly[0][0]*f.width,f.top+poly[0][1]*f.height);for(let i=1;i<poly.length;i++){const a=poly[i-1],b=poly[i];for(let j=1;j<=8;j++){board.press(99,f.left+(a[0]+(b[0]-a[0])*j/8)*f.width,f.top+(a[1]+(b[1]-a[1])*j/8)*f.height);await new Promise(r=>setTimeout(r,12));}}board.release(99);}};\r\nwindow.cogsProgress=(i,p)=>cogs.progress(i,p);const prog=document.querySelector('#progress');prog.oninput=()=>mechanicalPaths().forEach((p,i)=>{if(p.id===select.value)cogs.progress(i,+prog.value);});\r\ndocument.querySelector('#trace').onclick=traceShape;document.querySelector('#release').onclick=async()=>{await board.cut(aperture(),'#c59a56',1100);status.textContent='Released '+select.value;};document.querySelector('#reset').onclick=()=>{board.heal();status.textContent='Assemblies reset';};\r\nhost.style.touchAction='none';host.onpointerdown=e=>{host.setPointerCapture(e.pointerId);board.press(e.pointerId,e.clientX,e.clientY);};host.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))board.press(e.pointerId,e.clientX,e.clientY);};host.onpointerup=host.onpointercancel=e=>board.release(e.pointerId);\r\n}catch(e){status.textContent=e.stack;errors.push(e.stack);}\r\n</script></body></html>`;\r\nhttp.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');const data=await fs.readFile(file);res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css','.html':'text/html; charset=utf-8'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(Number(process.env.MYR5_GRIMOIRE_PORT)||5198,'127.0.0.1',function(){console.log('Mechanical preview http://127.0.0.1:'+this.address().port);});\r\n","scripts/mediapipe.mjs":"// R9-OFFLINE: the pose tracker is served same-origin from /vendor/mediapipe/<version>/ so a camera\r\n// workout opened once online also runs offline. These are the exact files live used from the CDNs,\r\n// each checked by sha256, downloaded once into vendor/mediapipe/ (gitignored). Same file in both apps.\r\nimport {createHash} from 'node:crypto';\r\nimport {mkdir,readFile,writeFile} from 'node:fs/promises';\r\nimport {dirname} from 'node:path';\r\nexport const MEDIAPIPE_VERSION='0.10.14';\r\nconst npm=`https://cdn.jsdelivr.net/npm/@mediapipe/tasks-vision@${MEDIAPIPE_VERSION}/`,model='https://storage.googleapis.com/mediapipe-models/pose_landmarker/pose_landmarker_lite/float16/1/';\r\nconst FILES={\r\n 'vision_bundle.mjs':[npm,'e77f281f9619150d937023c355bae170e9120e3b9e43f1e23a2a7bee07197669'],\r\n 'wasm/vision_wasm_internal.js':[npm,'9440cf0cc0cea21800e31581ec32aeedcc5fbf9df4509796bbc7d3f99e52ab9c'],\r\n 'wasm/vision_wasm_internal.wasm':[npm,'f82a8e6c05e08a44cc9f9e7ec5f845935bcbb1b1500ebe8c2f4812fb4e2917dc'],\r\n // Browsers without WebAssembly SIMD (Safari before 16.4) fetch these instead.\r\n 'wasm/vision_wasm_nosimd_internal.js':[npm,'abe9b6fbeaf86fcb53a5edce3926c82ccb0619e18fed4d9d9ce561ee7f55e054'],\r\n 'wasm/vision_wasm_nosimd_internal.wasm':[npm,'38b61feab2fd7934e05cbe9f68baa308978a5e3b7f85c1913bb8ae89b8ef8b97'],\r\n 'pose_landmarker_lite.task':[model,'59929e1d1ee95287735ddd833b19cf4ac46d29bc7afddbbf6753c459690d574a'],\r\n};\r\nconst sha256=bytes=>createHash('sha256').update(bytes).digest('hex');\r\nexport async function ensureMediapipe(root=`vendor/mediapipe/${MEDIAPIPE_VERSION}`){\r\n for(const [name,[base,expected]] of Object.entries(FILES)){\r\n  const path=`${root}/${name}`;let bytes=await readFile(path).catch(()=>null);\r\n  if(bytes&&sha256(bytes)===expected)continue;\r\n  const response=await fetch(base+name);if(!response.ok)throw Error(`Could not download MediaPipe ${name}: ${response.status}`);\r\n  bytes=Buffer.from(await response.arrayBuffer());if(sha256(bytes)!==expected)throw Error(`MediaPipe content check failed: ${name}`);\r\n  await mkdir(dirname(path),{recursive:true});await writeFile(path,bytes);\r\n }\r\n}\r\n","scripts/music-loops.py":"\"\"\"Offline tool: cut Ian's six songs into seamless 8-bar loops -> audio/music/*.m4a + manifest.json + report.\r\nRun: python scripts/music-loops.py   (needs numpy, scipy, ffmpeg; sources in .vault/music-src)\r\nMethod: tempo/bar grid from beat analysis (hand-checked start s0, bpm0 per song), then a small search around (start, length)\r\nfor the quietest seam (log-mel jump across the wrap, ranked against every interior point), with the reverb tail folded onto the head.\r\nEncodes AAC-LC .m4a (iOS-safe) and verifies the decode length.\"\"\"\r\nimport numpy as np, scipy.io.wavfile as wav, subprocess, json, os, sys, pathlib\r\nfrom scipy.signal import stft\r\nROOT = pathlib.Path(__file__).resolve().parent.parent\r\nFF = os.environ.get('FFMPEG', r'C:/Users/ianmy/AppData/Local/Microsoft/WinGet/Packages/Gyan.FFmpeg_Microsoft.Winget.Source_8wekyb3d8bbwe/ffmpeg-9.0-full_build/bin/ffmpeg')\r\nSR = 44100\r\n# name: (start s0 [s], bpm0, tempo tolerance, note). 8 bars of 4/4 = 32 beats.\r\nSONGS = {\r\n 'hey-man-idk': (0.62, 104.3, .012, 'music begins 0.6 s; level drops at 19.0 s'),\r\n 'guarded-gate': (0.04, 120.0, .0, '120 bpm grid fits cleanly for 8 bars (16 s); music keeps playing after bar 8'),\r\n 'daemon-time': (0.62, 90.7, .012, 'grid phase 0.6 s, ~91 bpm throughout the body'),\r\n 'sick-with-science': (0.04, 140.5, .012, 'drop at 13.7 s'),\r\n 'laboratory-violence': (0.0, 120.0, .0, 'drop at 15.98 s = 8 bars at 120'),\r\n 'main-theme-one': (2.0, 120.0, .0, '2 s count-in clicks then music; self-similar at +16 s'),\r\n}\r\ndef decode(path):\r\n    p = subprocess.run([FF, '-v', 'error', '-i', str(path), '-f', 'f32le', '-ac', '2', '-ar', str(SR), '-'], capture_output=True, check=True)\r\n    return np.frombuffer(p.stdout, np.float32).reshape(-1, 2).copy()\r\ndef mel(x, n=1024):\r\n    f, t, S = stft(x.mean(1), SR, nperseg=n, noverlap=n - 256, boundary=None, padded=False)\r\n    e = np.geomspace(60, 9000, 33); M = np.abs(S)\r\n    return np.log1p(np.array([M[(f >= a) & (f < b)].sum(0) for a, b in zip(e[:-1], e[1:])]) * 20)\r\ndef rms_db(x): return 20 * np.log10(np.sqrt((x.astype(np.float64) ** 2).mean()) + 1e-9)\r\ndef fold(x, s, L):\r\n    \"\"\"loop = x[s:s+L] with the decaying tail x[s+L:s+L+T] added onto its head.\"\"\"\r\n    body = x[s:s + L].copy(); tail = x[s + L:]\r\n    ref = np.sqrt((body.mean(1) ** 2).mean()); T = 0\r\n    if len(tail):\r\n        env = np.sqrt(np.convolve(tail.mean(1) ** 2, np.ones(441) / 441, 'same'))\r\n        below = np.where(env < ref * .08)[0]\r\n        T = int(below[0]) if len(below) else len(tail)\r\n    T = int(min(T, 3 * SR, len(tail), L // 3))\r\n    if len(tail) > 4410 and (np.sqrt((tail[:4410].mean(1) ** 2).mean()) > ref * .6 or T > int(1.5 * SR)):\r\n        # the music keeps playing past bar 8 (no decaying tail): continue the waveform and crossfade into the head\r\n        k = min(int(.06 * SR), len(tail)); t = np.linspace(0, np.pi / 2, k, dtype=np.float32)[:, None]\r\n        body[:k] = body[:k] * np.sin(t) + tail[:k] * np.cos(t); return body, k\r\n    if T > 0:\r\n        w = np.ones(T, np.float32); k = min(T, int(.25 * SR)) if T < 2 * SR else int(.6 * SR)\r\n        w[-k:] = np.cos(np.linspace(0, np.pi / 2, k)) ** 2\r\n        body[:T] += tail[:T] * w[:, None]\r\n    return body, T\r\ndef seam_stats(y):\r\n    \"\"\"Jump across the wrap vs the same measure at every interior hop. Lower percentile = smoother seam.\"\"\"\r\n    z = np.concatenate([y, y]); n = len(y); h = 256; W = 4\r\n    M = mel(z)\r\n    def jump(c):\r\n        i = c // h; a = M[:, i - W - 3:i - 3].mean(1); b = M[:, i + 1:i + 1 + W].mean(1); return np.linalg.norm(a - b)\r\n    cuts = np.array([int(round(n * k / 32)) for k in range(4, 32, 4)])  # the 7 interior bar lines (the wrap is a bar line too)\r\n    inner = np.array([jump(c) for c in cuts]); seam = jump(n)\r\n    pct = float((inner < seam).mean() * 100)\r\n    k = int(.005 * SR); rj = abs(rms_db(y[-k:]) - rms_db(y[:k]))\r\n    step = float(np.abs(y[0] - y[-1]).max()); typ = float(np.abs(np.diff(y, axis=0)).mean() * 6)\r\n    return {'melJumpPercentile': round(pct, 1), 'melJump': round(float(seam), 3), 'barLineMedianJump': round(float(np.median(inner)), 3), 'rmsJump5msDb': round(float(rj), 2), 'sampleStep': round(step, 4), 'typicalStep6x': round(typ, 4)}\r\ndef search(x, s0, bpm0, tol):\r\n    L0 = 32 * 60 / bpm0; best = None\r\n    for ds in np.arange(-0.02, 0.0201, 0.01):\r\n        for dl in (np.linspace(-tol, tol, 9) if tol else [0]):\r\n            s = int(round((s0 + ds) * SR)); L = int(round(L0 * (1 + dl) * SR))\r\n            if s < 0 or s + L > len(x): continue\r\n            y, T = fold(x, s, L); st = seam_stats(y)\r\n            cost = st['melJumpPercentile'] + st['rmsJump5msDb'] * 4 + abs(dl) * 1500 + abs(ds) * 200\r\n            if best is None or cost < best[0]: best = (cost, s, L, T, st, 32 * 60 * SR / L)\r\n    return best\r\ndef main():\r\n    only = set(sys.argv[1:]); out = ROOT / 'audio' / 'music'; out.mkdir(parents=True, exist_ok=True)\r\n    chk = ROOT / '.vault' / 'audio-check'; chk.mkdir(parents=True, exist_ok=True); (ROOT / '.vault' / 'tmp').mkdir(exist_ok=True)\r\n    manifest = {'version': 1, 'sampleRate': SR, 'bars': 8, 'tracks': {}}; rows = []\r\n    for name, (s0, bpm0, tol, note) in SONGS.items():\r\n        if only and name not in only: continue\r\n        x = decode(ROOT / '.vault' / 'music-src' / f'{name}.mp3')\r\n        cost, s, L, T, st, bpm = search(x, s0, bpm0, tol)\r\n        y, _ = fold(x, s, L)\r\n        peak = np.abs(y).max(); rms = np.sqrt((y ** 2).mean()); g = min(.10 / rms, .89 / peak); y = (y * g).astype(np.float32)\r\n        tmp = ROOT / '.vault' / 'tmp' / f'{name}.loop.wav'; wav.write(tmp, SR, (np.clip(y, -1, 1) * 32767).astype(np.int16))\r\n        m4a = out / f'{name}.m4a'\r\n        subprocess.run([FF, '-v', 'error', '-y', '-i', str(tmp), '-c:a', 'aac', '-b:a', '112k', '-movflags', '+faststart', str(m4a)], check=True)\r\n        d = subprocess.run([FF, '-v', 'error', '-i', str(m4a), '-f', 'f32le', '-ac', '2', '-ar', str(SR), '-'], capture_output=True, check=True).stdout\r\n        dec = np.frombuffer(d, np.float32).reshape(-1, 2); frames = len(y)\r\n        three = np.concatenate([dec[:frames] if len(dec) >= frames else y] * 3)\r\n        wav.write(chk / f'{name}-x3.wav', SR, (np.clip(three, -1, 1) * 32767).astype(np.int16))\r\n        manifest['tracks'][name] = {'url': f'/audio/music/{name}.m4a', 'bpm': round(bpm, 2), 'bars': 8, 'beats': 32, 'frames': frames, 'loopStart': 0, 'loopEnd': round(frames / SR, 6), 'duration': round(frames / SR, 6), 'sourceStart': round(s / SR, 4), 'tailFolded': round(T / SR, 3), 'bytes': m4a.stat().st_size, 'decodedFrames': int(len(dec))}\r\n        rows.append((name, round(bpm, 2), round(frames / SR, 3), round(s / SR, 3), round(T / SR, 2), st, m4a.stat().st_size, int(len(dec)) - frames, note))\r\n        print(rows[-1], flush=True)\r\n    if not only:\r\n        (out / 'manifest.json').write_text(json.dumps(manifest, indent=1))\r\n        r = ['# Music loop report', '', 'Tempo/bars come from onset-grid fits plus level drops (see scripts/music-loops.py). Seam pct = share of the 7 interior bar lines whose spectral jump is SMALLER than the wrap (the wrap is a bar line, so a bar-line-sized jump is expected: under ~70 = as smooth as a normal bar line, 100 = rougher than every one). Nobody could listen: judge by ear with `.vault/audio-check/*-x3.wav`.', '',\r\n             '| song | bpm | bars | loop s | source start s | tail folded s | seam pct | mel jump (seam / typical) | rms jump 5ms dB | m4a bytes | decode len - frames | note |', '|---|---|---|---|---|---|---|---|---|---|---|---|']\r\n        for n, b, d, s, t, st, by, dl, note in rows:\r\n            r.append(f\"| {n} | {b} | 8 | {d} | {s} | {t} | {st['melJumpPercentile']} | {st['melJump']} / {st['barLineMedianJump']} | {st['rmsJump5msDb']} | {by} | {dl} | {note} |\")\r\n        (ROOT / '.vault' / 'audio-report.md').write_text('\\n'.join(r) + '\\n')\r\nmain()\r\n","scripts/music-reloop.py":"\"\"\"Direct seam search for songs whose tempo grid is unreliable (hey-man-idk, guarded-gate).\r\nFor each start s the 0.2 s of audio around s (pre 0.1 s + post 0.1 s) is cross-correlated with the whole song: a peak at lag L means\r\nthe music at s+L looks (waveform-wise, so beat phase included) like the music at s, i.e. x[s+L] can follow x[s+L-1]... Loop = x[s:s+L]\r\nwith a 40 ms equal-power crossfade of the continuation x[s+L:s+L+k] into the head. Usage: python scripts/music-reloop.py name [lo hi]\"\"\"\r\nimport sys, numpy as np, scipy.io.wavfile as wav, subprocess, json, pathlib\r\nfrom scipy.signal import fftconvolve\r\nsys.argv_save = sys.argv; src = open(pathlib.Path(__file__).with_name('music-loops.py'), encoding='utf-8').read().replace(\"\\nmain()\\n\", \"\\n\")\r\nns = {'__file__': str(pathlib.Path(__file__).with_name('music-loops.py'))}; exec(src, ns)\r\nSR = 44100; ROOT = ns['ROOT']; FF = ns['FF']\r\ndef search(x, s_lo, s_hi, L_lo, L_hi, pre=.1, post=.1):\r\n    m = x.mean(1).astype(np.float64); n = len(m); res = []\r\n    csq = np.concatenate([[0], np.cumsum(m ** 2)])\r\n    for s in np.arange(s_lo, s_hi, .005):\r\n        a = int(s * SR); lo, hi = a - int(pre * SR), a + int(post * SR)\r\n        if lo < 0: continue\r\n        t = m[lo:hi]; te = (t ** 2).sum()\r\n        c = fftconvolve(m, t[::-1], 'valid')            # c[i] = sum m[i:i+len]*t\r\n        i = np.arange(len(c)); en = csq[i + len(t)] - csq[i]\r\n        ncc = c / np.sqrt(en * te + 1e-12)\r\n        for L in range(int(L_lo * SR), min(int(L_hi * SR), len(c) - 1 - a + lo)):\r\n            pass\r\n        idx = np.arange(lo + int(L_lo * SR), min(lo + int(L_hi * SR), len(ncc)))\r\n        if len(idx) == 0: continue\r\n        j = idx[np.argmax(ncc[idx])]; res.append((float(ncc[j]), s, (j - lo) / SR))\r\n    res.sort(reverse=True); return res\r\ndef build(x, s, L, k=int(.04 * SR)):\r\n    a = int(round(s * SR)); n = int(round(L * SR)); body = x[a:a + n].copy(); tail = x[a + n:a + n + k]\r\n    k = len(tail); t = np.linspace(0, np.pi / 2, k, dtype=np.float32)[:, None]\r\n    body[:k] = body[:k] * np.sin(t) + tail * np.cos(t); return body\r\nCUTS = {'hey-man-idk': (0.585, 10.1893, '8 bars at ~188.4 bpm; flux-pattern repeat found by direct search (the old 105 bpm grid was wrong)'),\r\n        'guarded-gate': (0.075, 15.8284, 'direct waveform seam search near 8 bars; music continues past the loop, so the head is crossfaded with the continuation')}\r\ndef main():\r\n    name = sys.argv[1]; s, L, note = CUTS[name]; scripts = ns\r\n    x = scripts['decode'](ROOT / '.vault' / 'music-src' / f'{name}.mp3')\r\n    y = build(x, s, L); st = scripts['seam_stats'](y)\r\n    peak = np.abs(y).max(); rms = np.sqrt((y ** 2).mean()); y = (y * min(.10 / rms, .89 / peak)).astype(np.float32)\r\n    tmp = ROOT / '.vault' / 'tmp' / f'{name}.loop.wav'; wav.write(tmp, SR, (np.clip(y, -1, 1) * 32767).astype(np.int16))\r\n    m4a = ROOT / 'audio' / 'music' / f'{name}.m4a'\r\n    subprocess.run([FF, '-v', 'error', '-y', '-i', str(tmp), '-c:a', 'aac', '-b:a', '112k', '-movflags', '+faststart', str(m4a)], check=True)\r\n    dec = np.frombuffer(subprocess.run([FF, '-v', 'error', '-i', str(m4a), '-f', 'f32le', '-ac', '2', '-ar', str(SR), '-'], capture_output=True, check=True).stdout, np.float32).reshape(-1, 2)\r\n    frames = len(y); three = np.concatenate([dec[:frames]] * 3)\r\n    chk = ROOT / '.vault' / 'audio-check'; w3 = chk / f'{name}-x3.wav'; wav.write(w3, SR, (np.clip(three, -1, 1) * 32767).astype(np.int16))\r\n    mp = ROOT / 'audio' / 'music' / 'manifest.json'; man = json.loads(mp.read_text())\r\n    man['tracks'][name].update({'bpm': round(32 * 60 / L, 2), 'frames': frames, 'loopEnd': round(frames / SR, 6), 'duration': round(frames / SR, 6), 'sourceStart': round(s, 4), 'tailFolded': 0.04, 'bytes': m4a.stat().st_size, 'decodedFrames': int(len(dec))})\r\n    mp.write_text(json.dumps(man, indent=1))\r\n    print(name, 'bpm', round(32 * 60 / L, 2), 'loop', round(L, 4), 'bytes', m4a.stat().st_size, 'dec-frames', len(dec) - frames, st)\r\nmain()\r\n","scripts/octave.cjs":"const {execFile}=require('node:child_process');\r\nconst fs=require('node:fs');\r\nconst PROCESSOR=process.env.MYR5_FFMPEG||'ffmpeg';\r\nfunction repairWave(wav){\r\n if(wav.length<44||wav.toString('ascii',0,4)!=='RIFF')throw Error('Invalid speech audio');\r\n wav.writeUInt32LE(wav.length-8,4);\r\n for(let offset=12;offset+8<=wav.length;){const size=wav.readUInt32LE(offset+4);if(wav.toString('ascii',offset,offset+4)==='data'){wav.writeUInt32LE(wav.length-offset-8,offset+4);return wav;}offset+=8+size+(size%2);}\r\n throw Error('Missing speech samples');\r\n}\r\nfunction lowerOctave(input){return new Promise((resolve,reject)=>{\r\n const child=execFile(PROCESSOR,['-hide_banner','-loglevel','error','-threads','1','-f','wav','-i','pipe:0','-af','rubberband=pitch=0.8908987181:tempo=1:formant=preserved:pitchq=quality,highpass=f=50,equalizer=f=2600:t=q:w=1.2:g=-2,lowpass=f=7200,alimiter=limit=0.95','-ac','1','-ar','22050','-c:a','pcm_s16le','-f','wav','pipe:1'],{encoding:'buffer',windowsHide:true,timeout:7000,maxBuffer:8*1024*1024},(error,output,stderr)=>{if(error){reject(Error('Deep robot voice unavailable: '+error.message+' '+String(stderr)));return;}try{resolve(repairWave(output));}catch(e){reject(e);}});\r\n child.stdin.on('error',()=>{});child.stdin.end(input);\r\n});}\r\nmodule.exports={lowerOctave,repairWave,available:()=>fs.existsSync(PROCESSOR)};\r\n","scripts/offline-assets.mjs":"import {createHash} from 'node:crypto';\r\nimport {createReadStream} from 'node:fs';\r\nimport {readdir,readFile,writeFile,stat} from 'node:fs/promises';\r\nimport {join,posix} from 'node:path';\r\nimport {fileURLToPath} from 'node:url';\r\nimport {build} from 'esbuild';\r\n\r\nconst folders=['pod','creature','models','icons','handborne','arcade','war-room','food','vendor','modules','audio','pods','reward-assets'];\r\n// D34: core precache holds only what a first run needs (sign-in/onboarding, home, a camera or manual\r\n// workout with its counter, updates/recovery, the offline shell). Core is every root, /icons/ or /pod/\r\n// file that the first-run pages name, directly or through other core files. The scan is conservative:\r\n// any path string counts. Bundled sources that no page requests, and everything else, ship in the\r\n// post-download package (sw.js OPTIONAL_ASSETS): fetched on demand online, offline once downloaded.\r\nconst CORE_ENTRIES=['/pose.html','/index.html','/onboarding.html','/signin.html','/install.html','/privacy.html','/manifest.webmanifest'];\r\n// W2-2O (#136): the portal experience's heavy art is ONE optional \"Starter\" download, never core: the quilt\r\n// texture, the pyramid model, the starter ship + six wonders, the still-room backdrop and the achievements\r\n// art (everything in pod/worlds/). Their small code (modules/portal, the ship view, the pyramid scanner,\r\n// the GLTF loader) stays core, so each scene opens offline and shows its own placeholder.\r\n// R9-OFFLINE: the pinned pose tracker (vendor/mediapipe, scripts/mediapipe.mjs) is Starter too, so camera workouts run offline.\r\nexport const STARTER=/^\\/(?:pod\\/worlds\\/|food\\/pyramid-scanner\\.glb$|vendor\\/mediapipe\\/)/;\r\nexport const BOARDS=/^\\/pod\\/worlds\\/boards\\//;\r\n// Achievement Vault: lazy code and art, never core (the hall's roster GLBs are fetched on demand).\r\nexport const VAULT=/^\\/(?:modules\\/vault\\/|pod\\/worlds\\/vault\\/)/;\r\nconst TUNNELS=/^\\/modules\\/portal\\/portal-tunnel-(?:ice|grass|cogs|jelly|wood|pond)\\.mjs$/;\r\nexport const SCOREBOARD_ROOM=/^\\/(?:pod\\/rooms\\/classroom-(?:wall|desks)\\.glb|modules\\/rooms\\/classroom\\.(?:mjs|css))$/;\r\nexport const REMINDERS_ROOM=/^\\/(?:pod\\/rooms\\/console\\.(?:glb|webp)|modules\\/rooms\\/reminders-computer\\.css)$/;\r\n// W4-4E (D47): the customizer cage and the Draco decoder only it needs. Never core; the customizer stays 2D without it.\r\nexport const CAGE_ROOM=/^\\/pod\\/rooms\\/cage\\//;\r\n// Page music (six AAC loops + manifest) is optional Music. These raw DJ authoring\r\n// modules are also optional: production Coach statically bundles them in core\r\n// launch-runtime.mjs. Keep their standalone source route without duplicating\r\n// first-run bytes; genuine runtime CSS, visualizer vendors and Hand assets retain\r\n// their existing groups.\r\nexport const MUSIC=/^\\/(?:audio\\/music\\/|actual-dj(?:-providers|-hand|-playlist)?\\.mjs$)/;\r\n// Each grimoire's art: its GLB board (cogs: its folder), its flat poster (portal.mjs's base layer) and its tunnel effect.\r\nconst GRIMOIRE_ART={ice:'ice\\\\.glb',grass:'(?:grass|flower)\\\\.glb',cogs:'cogs/.+',jelly:'jelly\\\\.glb',wood:'wood\\\\.glb',pond:'(?!)'}; // pond is procedural: just its poster and tunnel\r\nconst GRIMOIRE_GROUPS=Object.entries(GRIMOIRE_ART).map(([id,art])=>['grimoire-'+id,new RegExp(`^/(?:pod/worlds/boards/(?:${art}|${id}-poster\\\\.webp)|modules/portal/portal-tunnel-${id}\\\\.mjs)$`)]);\r\n// Named by first-run code, but used only by deferrable features that already cope without them:\r\n// food reference search (2.6 MB) and Records handwriting fonts (swap).\r\n// The production pages use the generated runtime bundles; source entries remain published for dev/source tools,\r\n// but are not downloaded in addition to those bundles. The conservative URL scanner also sees their names in comments.\r\nconst DEFERRED=/^\\/(?:app\\.mjs$|launch\\.mjs$|nutrition-data\\.mjs$|pod\\/fonts\\/|food\\/drgf-paper-character\\.png$)/;\r\nconst coreFolder=url=>!url.slice(1).includes('/')||/^\\/(?:audio|icons|modules\\/portal|modules\\/ships|food|vendor\\/three)\\//.test(url)||url.startsWith('/pod/')&&!/\\.(?:glb|gltf|bin)$/i.test(url);\r\nconst reference=/(?:\\.{1,2}\\/|\\/)?[\\w@][\\w\\-./@]*\\.(?:html|css|mjs|js|webmanifest|json|mp3|ogg|wav|png|jpe?g|webp|avif|gif|svg|ico|glb|gltf|bin|woff2?|ttf|otf)\\b/g;\r\nconst runtime=/\\.(?:html|css|mjs|js|webmanifest|json|mp3|m4a|ogg|wav|png|jpe?g|webp|avif|gif|svg|ico|glb|gltf|bin|wasm|task|woff2?|ttf|otf)$/i;\r\nconst excluded=new Set(['sw.js','source.json','source.json.gz','package.json','package-lock.json','recover.html','recovery-page.mjs','about.html']);\r\n\r\nasync function identify(root,path){\r\n const hash=createHash('sha256');\r\n for await(const chunk of createReadStream(join(root,path)))hash.update(chunk);\r\n return {url:'/'+path,integrity:'sha256-'+hash.digest('base64'),bytes:(await stat(join(root,path))).size};\r\n}\r\nasync function coreClosure(root,urls,template){\r\n const core=new Set(),queue=[...CORE_ENTRIES];\r\n try{for(const [ref] of (await readFile(template,'utf8')).matchAll(reference))queue.push(ref);}catch(error){if(error.code!=='ENOENT')throw error;}\r\n while(queue.length){\r\n  const url=queue.shift();\r\n if(core.has(url)||!urls.has(url)||!coreFolder(url)||DEFERRED.test(url)||STARTER.test(url)||BOARDS.test(url)||VAULT.test(url)||TUNNELS.test(url)||SCOREBOARD_ROOM.test(url)||REMINDERS_ROOM.test(url)||CAGE_ROOM.test(url)||MUSIC.test(url))continue;\r\n  core.add(url);\r\n  if(/\\.(?:html|css|mjs|js|webmanifest|json)$/.test(url))for(const [ref] of (await readFile(join(root,url),'utf8')).matchAll(reference))\r\n   queue.push(ref.startsWith('/')?ref:posix.join(posix.dirname(url),ref),'/'+ref.replace(/^\\.\\//,''));\r\n }\r\n return core;\r\n}\r\n// The voice clips (not core) are listed with their identities inside the voice manifest, whose own\r\n// identity is in the package list; `contains` is the byte total of the clips it names.\r\nexport async function identifyVoice(root){\r\n let manifest;try{manifest=JSON.parse(await readFile(join(root,'voice/manifest.json'),'utf8'));}catch(error){if(error.code==='ENOENT')return;throw error;}\r\n manifest.files=[];for(const url of new Set(Object.values(manifest.phrases)))manifest.files.push(await identify(root,url.slice(1)));\r\n await writeFile(join(root,'voice/manifest.json'),JSON.stringify(manifest));\r\n}\r\n\r\n// The group manifest: the Downloads menu picks the post-download package by group; every optional file\r\n// carries one. First match wins; whatever is left (regular coach models, customizer, exercise demos, app\r\n// screens) is \"Your coach\". Roster bodies never join it: each goes to its workout section from\r\n// track-placements.ts (#102), or the bodies' Starter section when it has no placement.\r\n// \"starter\" (W2-2O) is the portal experience's art. Vault code and art remain optional public assets,\r\n// grouped into the same integrity-checked post-download package as the rest of the library.\r\n// Each grimoire device downloads its own board art and tunnel effect together. Quilt stays Starter.\r\nconst GROUPS=[\r\n ...GRIMOIRE_GROUPS,\r\n ['room-scoreboard',SCOREBOARD_ROOM],\r\n ['room-reminders',REMINDERS_ROOM],\r\n ['room-cage',CAGE_ROOM],\r\n ['music',MUSIC],\r\n ['vault',VAULT],\r\n ['starter',STARTER],\r\n ['drop-pods',/^\\/(?:pods|reward-assets)\\//],\r\n ['voices',/^\\/voice\\//],\r\n ['hand',/^\\/handborne\\//],\r\n // The meshopt decoder is the pyramid's alone (release 5): core here through the pyramid scanner (W2-2O keeps the scenes'\r\n // code core), and with Food should it ever leave core. GLTFLoader is shared (hologram, ships, pyramid): core (coreFolder).\r\n ['food',/^\\/(?:food\\/|vendor\\/three\\/meshopt_decoder\\.module\\.js$|nutrition-data\\.mjs$|food-live\\.css$|meal-)/],\r\n ['meditation',/^\\/(?:meditation|breathing)/],\r\n ['games',/^\\/(?:arcade|war-room)\\//],\r\n];\r\nconst ROSTER_BODY=/^\\/creature\\/models\\/roster\\/[^/]+\\.glb$/;\r\nlet placements;\r\nexport function bodySections(){\r\n placements??=build({entryPoints:[fileURLToPath(new URL('../creature/source/creator/track-placements.ts',import.meta.url))],bundle:true,write:false,format:'esm',platform:'neutral',logLevel:'silent'})\r\n  .then(({outputFiles:[out]})=>import('data:text/javascript;base64,'+Buffer.from(out.text).toString('base64')))\r\n  .then(({TRACK_PLACEMENTS})=>new Map(TRACK_PLACEMENTS.map(p=>['/'+p.sourceAsset,p.tracks[0]])));\r\n return placements;\r\n}\r\nexport const groupOf=(url,sections)=>ROSTER_BODY.test(url)?'bodies-'+(sections.get(url)??'starter'):GROUPS.find(([,test])=>test.test(url))?.[0]??'coach';\r\n\r\n// PackLifecycle bytes are outside both inventories.\r\nexport async function offlineInventory(root,template='sw.js'){\r\n const assets=[];\r\n async function walk(path){\r\n  for(const entry of await readdir(join(root,path),{withFileTypes:true})){\r\n   if(entry.name.startsWith('.')||entry.name==='source')continue;\r\n   const name=path+'/'+entry.name;\r\n   if(entry.isDirectory())await walk(name);\r\n   else if(entry.isFile()&&runtime.test(entry.name))assets.push(await identify(root,name));\r\n  }\r\n }\r\n for(const entry of await readdir(root,{withFileTypes:true}))if(entry.isFile()&&!excluded.has(entry.name)&&runtime.test(entry.name))assets.push(await identify(root,entry.name));\r\n for(const folder of folders)try{await walk(folder);}catch(error){if(error.code!=='ENOENT')throw error;}\r\n const core=await coreClosure(root,new Set(assets.map(a=>a.url)),template);\r\n try{const {files}=JSON.parse(await readFile(join(root,'voice/manifest.json'),'utf8'));if(Array.isArray(files))assets.push({...await identify(root,'voice/manifest.json'),contains:files.reduce((sum,file)=>sum+file.bytes,0)});}catch(error){if(error.code!=='ENOENT')throw error;}\r\n assets.sort((a,b)=>a.url.localeCompare(b.url));\r\n const sections=await bodySections();\r\n return {core:assets.filter(a=>core.has(a.url)),optional:assets.filter(a=>!core.has(a.url)).map(a=>({...a,group:groupOf(a.url,sections)}))};\r\n}\r\n\r\nexport async function offlineAssets(root){return (await offlineInventory(root)).core;}\r\n\r\nexport async function writeOfflineWorker(root,buildId,template='sw.js'){\r\n await identifyVoice(root);\r\n const {core:assets,optional}=await offlineInventory(root,template);\r\n for(const required of ['/pose.html','/app-runtime.mjs','/launch-bootstrap.mjs','/launch-runtime.mjs','/local-coach-runtime.mjs','/onboarding.html','/onboarding.mjs','/workout-tracks.js','/pod/gala-weapons.js','/pod/gala-avatar.js','/pod/gala-performer.js','/pod/dj-identity.js']){\r\n  if(!assets.some(asset=>asset.url===required&&asset.bytes>0))throw Error('Missing offline Coach asset: '+required);\r\n }\r\n const source=await readFile(template,'utf8');\r\n if(!source.includes('/* OFFLINE_ASSETS */ []'))throw Error('Offline worker template is missing its asset marker.');\r\n await writeFile(join(root,'sw.js'),source.replace(/^const SHELL='[^']*'/,`const SHELL='myr5-shell-${buildId}'`).replace('/* OFFLINE_ASSETS */ []',JSON.stringify(assets)).replace('/* OPTIONAL_ASSETS */ []',JSON.stringify(optional)));\r\n const mib=list=>(list.reduce((sum,asset)=>sum+asset.bytes+(asset.contains||0),0)/1048576).toFixed(1);\r\n const groups=Object.entries(Object.groupBy(optional,a=>a.group)).map(([id,list])=>`${id} ${list.length}/${mib(list)}`).join(', ');\r\n console.log(`Offline Coach core: ${assets.length} files, ${mib(assets)} MiB. Complete public content package: ${optional.length} entries, ${mib(optional)} MiB (groups, files/MiB: ${groups}).`);\r\n return assets;\r\n}\r\n","scripts/optimize-glb.mjs":"import {readFile,writeFile,readdir} from 'node:fs/promises';\r\nimport {join} from 'node:path';\r\nimport {createHash} from 'node:crypto';\r\nimport {MeshoptEncoder,MeshoptDecoder} from 'meshoptimizer';\r\nimport sharp from 'sharp';\r\n// Shrinks a GLB without changing what a loader gets back, so code that reads vertices, samples\r\n// triangles or finds nodes by name behaves exactly as with the authored file. Vertex, index, skin and\r\n// animation data move into EXT_meshopt_compression with no quantization, filters or reordering, and\r\n// index buffers use INDICES mode (TRIANGLES mode rotates each triangle's corners): every accessor\r\n// decodes to its original bytes, checked here before anything is written. The glTF JSON is kept\r\n// (names, transforms, materials); only buffer views move, and identical ones share bytes (this\r\n// replaces the old compaction pass). PNG textures become lossless WebP only when the decoded pixels\r\n// match and it is smaller; JPEGs stay JPEG (re-encoding them loses detail).\r\n// ponytail: lossless only. Rounding normals to 16 bits (exponential filter) saves ~15 MiB more but moved\r\n// sub-pixel detail on sculpted styles (iris fibres) in the before/after frames; quantizing positions or\r\n// normals breaks the customizer (sculpting, computeVertexNormals, eye placement).\r\n// Loaders of these files need setMeshoptDecoder (creature/source/creator/assemble.ts, handborne).\r\nconst SIZE={5120:1,5121:1,5122:2,5123:2,5125:4,5126:4},COUNT={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16};\r\nconst align=n=>n+3&~3;\r\n\r\nexport async function optimizeGLB(input){\r\n if(input.readUInt32LE(0)!==0x46546c67||input.readUInt32LE(4)!==2)throw Error('Expected GLB 2');\r\n const jsonLength=input.readUInt32LE(12),doc=JSON.parse(input.subarray(20,20+jsonLength));\r\n if(doc.extensionsUsed?.includes('EXT_meshopt_compression')||doc.buffers?.length!==1||doc.buffers[0].uri)return input;\r\n const bin=input.subarray(28+jsonLength,28+jsonLength+input.readUInt32LE(20+jsonLength));\r\n await MeshoptEncoder.ready;await MeshoptDecoder.ready;\r\n // How each buffer view is read: by element size (vertices, skins, animation) or as indices.\r\n const use=new Map(),skip=new Set();\r\n for(const a of doc.accessors||[]){\r\n  if(a.sparse){skip.add(a.sparse.indices.bufferView);skip.add(a.sparse.values.bufferView);}\r\n  if(a.bufferView==null)continue;const u=use.get(a.bufferView)??{sizes:new Set()};u.sizes.add(SIZE[a.componentType]*COUNT[a.type]);u.component=SIZE[a.componentType];use.set(a.bufferView,u);\r\n }\r\n for(const mesh of doc.meshes||[])for(const p of mesh.primitives)if(p.indices!=null&&doc.accessors[p.indices].bufferView!=null)use.get(doc.accessors[p.indices].bufferView).index=true;\r\n const images=new Map((doc.images||[]).map((image,i)=>[image.bufferView,i]));\r\n const chunks=[],seen=new Map();let size=0,fallback=0,packed=0,webps=0;\r\n const put=bytes=>{const key=createHash('sha256').update(bytes).digest('base64');if(!seen.has(key)){seen.set(key,size);chunks.push(bytes,Buffer.alloc(align(bytes.length)-bytes.length));size+=align(bytes.length);}return seen.get(key);};\r\n for(const [i,view] of (doc.bufferViews||[]).entries()){\r\n  let bytes=bin.subarray(view.byteOffset||0,(view.byteOffset||0)+view.byteLength);\r\n  const u=use.get(i),image=images.get(i);\r\n  if(u&&!skip.has(i)&&!view.extensions&&!(u.index&&u.sizes.size>1)){\r\n   const mode=u.index?'INDICES':'ATTRIBUTES',stride=u.index?u.component:view.byteStride??(u.sizes.size===1?[...u.sizes][0]:4);\r\n   if((u.index?stride===2||stride===4:stride%4===0&&stride<=256)&&view.byteLength%stride===0){\r\n    const count=view.byteLength/stride,source=new Uint8Array(bytes),out=MeshoptEncoder.encodeGltfBuffer(source,count,stride,mode);\r\n    const back=new Uint8Array(count*stride);MeshoptDecoder.decodeGltfBuffer(back,count,stride,out,mode,'NONE');\r\n    if(!Buffer.from(back).equals(source))throw Error(`Buffer view ${i} did not decode to its original bytes.`);\r\n    if(out.length<view.byteLength){\r\n     view.extensions={EXT_meshopt_compression:{buffer:0,byteOffset:put(Buffer.from(out)),byteLength:out.length,byteStride:stride,mode,count}};\r\n     view.buffer=1;view.byteOffset=fallback;fallback=align(fallback+view.byteLength);packed++;continue;\r\n    }\r\n   }\r\n  }\r\n  if(image!=null&&doc.images[image].mimeType==='image/png'){\r\n   const out=await sharp(bytes).webp({lossless:true,exact:true,effort:6}).toBuffer();\r\n   const [a,b]=await Promise.all([bytes,out].map(x=>sharp(x).ensureAlpha().raw().toBuffer()));\r\n   if(out.length<bytes.length&&a.equals(b)){\r\n    bytes=out;doc.images[image].mimeType='image/webp';webps++;\r\n    for(const t of doc.textures||[])if(t.source===image){delete t.source;t.extensions={...t.extensions,EXT_texture_webp:{source:image}};}\r\n   }\r\n  }\r\n  view.byteOffset=put(bytes);\r\n }\r\n const used=new Set(doc.extensionsUsed),required=new Set(doc.extensionsRequired);\r\n doc.buffers=[{byteLength:size}];\r\n if(packed){doc.buffers.push({byteLength:fallback,extensions:{EXT_meshopt_compression:{fallback:true}}});used.add('EXT_meshopt_compression');required.add('EXT_meshopt_compression');}\r\n if(webps){used.add('EXT_texture_webp');required.add('EXT_texture_webp');}\r\n if(used.size)doc.extensionsUsed=[...used];if(required.size)doc.extensionsRequired=[...required];\r\n let json=Buffer.from(JSON.stringify(doc));json=Buffer.concat([json,Buffer.alloc(align(json.length)-json.length,32)]);\r\n const body=Buffer.concat(chunks),head=Buffer.alloc(28);\r\n head.writeUInt32LE(0x46546c67,0);head.writeUInt32LE(2,4);head.writeUInt32LE(28+json.length+body.length,8);head.writeUInt32LE(json.length,12);head.writeUInt32LE(0x4e4f534a,16);\r\n head.writeUInt32LE(body.length,20);head.writeUInt32LE(0x004e4942,24);\r\n return Buffer.concat([head.subarray(0,20),json,head.subarray(20),body]);\r\n}\r\n\r\n// Rewrites every GLB under root in place (the build runs this on its dist copy); returns bytes saved.\r\nexport async function optimizeModels(root){let saved=0;for(const entry of await readdir(root,{withFileTypes:true})){const path=join(root,entry.name);if(entry.isDirectory())saved+=await optimizeModels(path);else if(entry.name.endsWith('.glb')){const input=await readFile(path),out=await optimizeGLB(input);if(out.length<input.length){await writeFile(path,out);saved+=input.length-out.length;}}}return saved;}\r\n","scripts/pack-nutrition.mjs":"import {readFile,writeFile} from 'node:fs/promises';\r\nimport {resolve} from 'node:path';\r\nimport {pathToFileURL} from 'node:url';\r\n\r\n// The USDA source remains readable in the repository and the AGPL source offer.\r\n// Only the deployed copy stores its repeated object keys once, then restores\r\n// the exact object array when the optional Food list is opened.\r\nexport async function packNutrition(source='nutrition-data.mjs',target='dist/client/nutrition-data.mjs'){\r\n const records=(await import(pathToFileURL(resolve(source)).href)).default;\r\n if(!Array.isArray(records)||!records.length)throw Error('Nutrition source has no rows.');\r\n const keys=Object.keys(records[0]),signature=keys.join('\\0');\r\n for(const row of records)if(Object.keys(row).join('\\0')!==signature)throw Error('Nutrition source columns differ between rows.');\r\n const rows=records.map(row=>keys.map(key=>row[key]));\r\n const header=(await readFile(source,'utf8')).split(/\\r?\\n/).slice(0,3).join('\\n');\r\n const module=`${header}\\n// Packed deploy copy; scripts/pack-nutrition.mjs verifies a uniform source schema.\\nexport default (()=>{const keys=${JSON.stringify(keys)},rows=${JSON.stringify(rows)},out=new Array(rows.length);for(let j=0;j<rows.length;j++){const item={};for(let i=0;i<keys.length;i++)item[keys[i]]=rows[j][i];out[j]=item;}return out;})();\\n`;\r\n await writeFile(target,module);\r\n return (await readFile(source)).length-Buffer.byteLength(module);\r\n}\r\n","scripts/package-weapon-review.mjs":"import {readFile,writeFile,mkdir} from 'node:fs/promises';\r\nimport {resolve,dirname} from 'node:path';\r\nimport {build} from 'esbuild';\r\nconst output=resolve(process.argv[2]||'../../outputs/Weapon-Lab.html');\r\nconst js=await build({entryPoints:['pod/weapon-review.mjs'],bundle:true,format:'iife',target:'es2022',write:false,minify:true});\r\nconst weapons=await readFile('pod/gala-weapons.js','utf8');\r\nconst training=await readFile('workout-tracks.js','utf8');\r\nconst world=(await readFile('pod/worlds/great-wall.webp')).toString('base64');\r\nconst css=(await readFile('pod/weapon-review.css','utf8')).replace(\"url('worlds/great-wall.webp')\",`url('data:image/webp;base64,${world}')`);\r\nconst html=(await readFile('pod/weapon-review.html','utf8'))\r\n .replace('<link rel=\"stylesheet\" href=\"weapon-review.css\">',`<style>${css}</style>`)\r\n .replace('href=\"../pose.html\"','href=\"https://myr5.mominc.online/pose.html\"')\r\n .replace('<script src=\"/workout-tracks.js\"></script>',`<script>${training}</script>`)\r\n .replace('<script src=\"gala-weapons.js\"></script>',`<script>${weapons.replaceAll('</script','<\\\\/script')}</script>`)\r\n .replace('<script type=\"module\" src=\"weapon-review.mjs\"></script>',`<script>${js.outputFiles[0].text.replaceAll('</script','<\\\\/script')}</script>`);\r\nawait mkdir(dirname(output),{recursive:true});await writeFile(output,html);console.log('Self-contained weapon review saved.');\r\n","scripts/pose-samples.mjs":"// Turns a ?recordPose=1 recording into a k-NN samples file and a replay fixture.\r\n//   node scripts/pose-samples.mjs <recording.json> [--reps N] [--use]\r\n//     Writes tests/fixtures/pose-replay/<name>.replay.json (+ <name>.samples.json beside it) and prints how the\r\n//     rules and the k-NN counted. --use moves the samples to pose-samples/<exercise>.samples.json and registers\r\n//     them in pose-samples.mjs, so the app counts that exercise with the k-NN.\r\n//   node scripts/pose-samples.mjs --example\r\n//     Rebuilds the synthetic squat example (tests/pose-fixtures.mjs) in tests/fixtures/pose-replay.\r\nimport {readFile,writeFile,readdir,mkdir,rm} from 'node:fs/promises';\r\nimport {basename} from 'node:path';\r\nimport {fileURLToPath} from 'node:url';\r\nimport {MovementSession,MOVEMENTS,features} from '../movement-engine.mjs';\r\nimport {embed,EMBED_LANDMARKS} from '../pose-classifier.mjs';\r\nconst root=new URL('../',import.meta.url),fixtures=new URL('tests/fixtures/pose-replay/',root),registry=new URL('pose-samples/',root);\r\nconst MAX_BYTES=50*1024,PER_CLASS=100;\r\nconst round=(v,d=3)=>Math.round(v*10**d)/10**d;\r\nconst evenly=(list,n)=>list.length<=n?list:Array.from({length:n},(_,i)=>list[Math.floor(i*list.length/n)]);\r\n// Replay frames keep only the landmarks counting uses; the rest come back invisible.\r\nconst points=frame=>{const p=Array.from({length:27},()=>({x:0,y:0,visibility:0}));frame.forEach(([x,y,visibility],i)=>{p[EMBED_LANDMARKS[i]]={x,y,visibility};});return p;};\r\n// World landmarks (metres, recorded since R9) feed the rules' toward-camera angles; older recordings replay 2D.\r\nconst worldPoints=w=>{if(!w)return null;const p=Array(27).fill(null);w.forEach(([x,y,z],i)=>{p[EMBED_LANDMARKS[i]]={x,y,z};});return p;};\r\nexport function replay(fixture,options={}){\r\n const session=new MovementSession(fixture.exercise,options);\r\n for(const [t,frame,world] of fixture.frames)session.update(points(frame),t,fixture.aspect,worldPoints(world));\r\n return session.count;\r\n}\r\nexport function convert(recording,{reps=null}={}){\r\n const {exercise,aspect=1,frames,labels=[]}=recording;\r\n if(MOVEMENTS[exercise]?.kind!=='reps')throw new Error(`${exercise} is not a rep exercise; the k-NN only counts reps.`);\r\n const t0=frames[0][0],compact=frames.map(([t,p,w])=>[Math.round(t-t0),EMBED_LANDMARKS.map(i=>[round(p[i][0]),round(p[i][1]),round(p[i][2],2)]),...w?[EMBED_LANDMARKS.map(i=>w[i].map(v=>round(v,4)))]:[]]);\r\n const labelled=compact.flatMap(([t,frame])=>{const label=labels.find(l=>t+t0>=l.from&&t+t0<=l.to)?.label;return label?[{label,f:features(points(frame),aspect)}]:[];});\r\n // Landmarks clear in 90% of the labelled frames are required; a side view only needs its near side.\r\n const need=EMBED_LANDMARKS.filter(i=>labelled.filter(({f})=>f.visible([i])&&f.p[i].visibility>=.6).length>=.9*labelled.length);\r\n if(![11,23].every(i=>need.includes(i))&&![12,24].every(i=>need.includes(i)))throw new Error('No clear shoulder and hip in the labelled frames. Record again with the body in view.');\r\n const byLabel={};for(const {label,f} of labelled)if(f.visible(need))(byLabel[label]??=[]).push(embed(f.p).map(v=>round(v)));\r\n if(!byLabel.up?.length||!byLabel.down?.length)throw new Error('The recording needs both \"up\" and \"down\" labels.');\r\n const samples={exercise,need,samples:Object.entries(byLabel).flatMap(([label,list])=>evenly(list,PER_CLASS).map(e=>[label,e]))};\r\n if(JSON.stringify(samples).length>MAX_BYTES)throw new Error('Samples file over 50 KB.');\r\n const fixture={exercise,aspect,reps,rules:0,knn:0,frames:compact};\r\n fixture.rules=replay(fixture,{samples:null});fixture.knn=replay(fixture,{samples});\r\n return {samples,fixture};\r\n}\r\nasync function register(){\r\n const files=(await readdir(registry).catch(()=>[])).filter(n=>n.endsWith('.samples.json')).sort();\r\n await writeFile(new URL('pose-samples.mjs',root),['// Generated by scripts/pose-samples.mjs from pose-samples/*.samples.json. Do not edit by hand.','// Exercises listed here count reps with the k-NN pose classifier; every other exercise uses the rules.',\r\n  ...files.map((n,i)=>`import s${i} from './pose-samples/${n}' with {type:'json'};`),`export default {${files.map((n,i)=>`${JSON.stringify(n.replace('.samples.json',''))}:s${i}`).join(',')}};`,''].join('\\n'));\r\n}\r\nasync function main(args){\r\n const example=args.includes('--example'),use=args.includes('--use'),reps=args.includes('--reps')?Number(args[args.indexOf('--reps')+1]):null;\r\n const file=args.find(a=>!a.startsWith('--')&&a!==String(reps));\r\n const recording=example?(await import('../tests/pose-fixtures.mjs')).syntheticRecording():JSON.parse(await readFile(file,'utf8'));\r\n const {samples,fixture}=convert(recording,{reps:example?6:reps});\r\n const name=example?'squat-synthetic':basename(file,'.json').replace(/^recordPose-/,'');\r\n await mkdir(fixtures,{recursive:true});\r\n await writeFile(new URL(name+'.replay.json',fixtures),JSON.stringify(fixture)+'\\n');\r\n if(use){\r\n  await mkdir(registry,{recursive:true});await writeFile(new URL(samples.exercise+'.samples.json',registry),JSON.stringify(samples)+'\\n');\r\n  await rm(new URL(name+'.samples.json',fixtures),{force:true});await register();\r\n  // Other replays of this exercise count with the registered samples: re-lock their k-NN counts.\r\n  for(const other of (await readdir(fixtures)).filter(n=>n.endsWith('.replay.json')&&n!==name+'.replay.json')){\r\n   const url=new URL(other,fixtures),old=JSON.parse(await readFile(url,'utf8'));\r\n   if(old.exercise!==samples.exercise||(await readdir(fixtures)).includes(other.replace('.replay.json','.samples.json')))continue;\r\n   old.knn=replay(old,{samples});await writeFile(url,JSON.stringify(old)+'\\n');\r\n  }\r\n }else await writeFile(new URL(name+'.samples.json',fixtures),JSON.stringify(samples)+'\\n');\r\n console.log(`${samples.exercise}: ${samples.samples.length} samples, needs landmarks ${samples.need.join(' ')}. Rules counted ${fixture.rules}, k-NN counted ${fixture.knn}${reps===null&&!example?'':`, you did ${fixture.reps}`}.`);\r\n console.log(use?`k-NN now counts ${samples.exercise} in the app. Run npm test, then commit pose-samples/ and the replay.`:`Replay saved as tests/fixtures/pose-replay/${name}.replay.json. Add --use to count ${samples.exercise} with the k-NN in the app.`);\r\n}\r\nif(process.argv[1]===fileURLToPath(import.meta.url))main(process.argv.slice(2)).catch(error=>{console.error(error.message);process.exit(1);});\r\n","scripts/prepare-sound-assets.py":"\"\"\"Rebuild the CC0 sound pack from the attributed masters in plan/assets-inbox/audio.\r\n\r\nRequires Python 3 and ffmpeg/ffprobe. The two original generated waveforms are CC0.\r\nAll paths and edit recipes are retained in audio/sfx/manifest.json for reproducibility.\r\n\"\"\"\r\nimport array\r\nimport hashlib\r\nimport html\r\nimport json\r\nimport math\r\nimport pathlib\r\nimport random\r\nimport struct\r\nimport subprocess\r\nimport wave\r\n\r\nROOT = pathlib.Path(__file__).resolve().parents[1]\r\nMASTERS = ROOT / 'plan/assets-inbox/audio'\r\nOUT = ROOT / 'audio/sfx'\r\nOUT.mkdir(parents=True, exist_ok=True)\r\nSOURCES = {\r\n    'interface': ('Kenney', 'https://kenney.nl/assets/interface-sounds'),\r\n    'impact': ('Kenney', 'https://kenney.nl/assets/impact-sounds'),\r\n    'mechanical': ('qubodup', 'https://opengameart.org/content/7-mechanical-clicks-and-buzzes'),\r\n    'ice': ('bart', 'https://opengameart.org/content/ice-spells'),\r\n    'jelly': ('Independent.nu', 'https://opengameart.org/content/8-wet-squish-slurp-impacts'),\r\n    'water': ('ezwa', 'https://opengameart.org/content/6-short-water-splashes'),\r\n    'waves': ('transitking', 'https://opengameart.org/content/water-waves'),\r\n    'grass': ('qubodup', 'https://opengameart.org/content/20-rustles-dry-leaves'),\r\n    'cloth': ('Iochi Glaucus', 'https://opengameart.org/content/fabric-rustling'),\r\n    'wind': ('Luke.RUSTLTD', 'https://opengameart.org/content/wind1'),\r\n    'hum': ('LEGIT Audio', 'https://opengameart.org/content/the-shop'),\r\n    'portal': ('Ogrebane', 'https://opengameart.org/content/teleport-spell'),\r\n    'original': ('MOM Inc.', '/source.json'),\r\n}\r\n\r\n\r\ndef generated(name, duration, sample):\r\n    path = MASTERS / (name + '.wav')\r\n    with wave.open(str(path), 'wb') as f:\r\n        f.setnchannels(1)\r\n        f.setsampwidth(2)\r\n        f.setframerate(24000)\r\n        frames = bytearray()\r\n        for n in range(int(duration * 24000)):\r\n            t = n / 24000\r\n            envelope = min(1, t / .012, (duration - t) / .04)\r\n            frames.extend(struct.pack('<h', int(max(-1, min(1, sample(t) * envelope)) * 24000)))\r\n        f.writeframes(frames)\r\n\r\n\r\nrng = random.Random(21)\r\ngenerated('dialup-original', 1.8, lambda t:\r\n          .19 * math.sin(2 * math.pi * (350 if t < .35 else 1050 if t < .7 else 2100) * t)\r\n          + .1 * math.sin(2 * math.pi * (440 if t < .35 else 1650) * t)\r\n          + (rng.uniform(-.05, .05) if t > .7 else 0))\r\ngenerated('crt-original', .12, lambda t:\r\n          rng.uniform(-.2, .2) * math.exp(-t * 55)\r\n          + .08 * math.sin(2 * math.pi * 180 * t) * math.exp(-t * 40))\r\n\r\n# Original UI foley and synthesis, dedicated to CC0 by MOM Inc.\r\ngenerated('bloop-original', .22, lambda t: .3*math.sin(2*math.pi*(260*t-340*t*t))*math.exp(-t*16))\r\ngenerated('signal-original', .35, lambda t: .18*math.sin(2*math.pi*(660 if t<.14 else 880)*t) if t<.08 or .18<t<.26 else 0)\r\ngenerated('electric-original', .25, lambda t: rng.uniform(-.22,.22)+.018*math.sin(2*math.pi*110*t))\r\ngenerated('whiteboard-original', .9, lambda t: rng.uniform(-.3,.3)*(1 if t<.34 else .05 if t<.4 else .5 if int((t-.4)/.06)%2==0 else .12))\r\nSOURCES['waterfall'] = ('kurt', 'https://opengameart.org/content/stream-sounds')\r\n\r\n# cue, filename, source/master, provenance key, maximum duration, extra filter, seek\r\nEDITS = [\r\n    ('mechanical', 'mechanical-click-1', 'mechanical/mechanical/mechanical_button-01.flac', 'mechanical', .4, '', 0),\r\n    ('mechanical', 'mechanical-click-2', 'mechanical/mechanical/mechanical_clicks-05.flac', 'mechanical', .42, '', 0),\r\n    ('switch', 'metal-switch-1', 'kenney-interface/Audio/switch_001.ogg', 'interface', .4, '', 0),\r\n    ('switch', 'metal-switch-2', 'kenney-interface/Audio/toggle_001.ogg', 'interface', .4, '', 0),\r\n    ('ice', 'ice-crack-1', 'ice/ice.wav', 'ice', .85, '', 0),\r\n    ('ice', 'ice-crack-2', 'ice/coldsnap.wav', 'ice', .85, '', .1),\r\n    ('jelly', 'jelly-squish-1', 'squish/impsplat/impactsplat07.mp3.flac', 'jelly', .55, '', 0),\r\n    ('jelly', 'jelly-squish-2', 'squish/impsplat/impactsplat08.mp3.flac', 'jelly', .66, '', 0),\r\n    ('water', 'water-splash-1', 'splash/ezwa-water_splash/water_splash-02.flac', 'water', .42, '', 0),\r\n    ('water', 'water-splash-2', 'splash/ezwa-water_splash/water_splash-03.flac', 'water', .72, '', 0),\r\n    ('water-slosh', 'water-slosh', 'water-slosh.flac', 'waves', 2.5, 'lowpass=f=2500,', 0),\r\n    ('grass', 'grass-rustle-1', 'leaves/rustle/rustle01.flac', 'grass', .7, 'lowpass=f=4000,', 0),\r\n    ('grass', 'grass-rustle-2', 'leaves/rustle/rustle02.flac', 'grass', .7, 'lowpass=f=4000,', 0),\r\n    ('grass-tinkle', 'grass-tinkle', 'kenney-interface/Audio/glass_001.ogg', 'interface', .6, '', 0),\r\n    ('quilt', 'cloth-rustle-1', 'cloth.ogg', 'cloth', .65, 'lowpass=f=4000,', .5),\r\n    ('quilt', 'cloth-rustle-2', 'cloth.ogg', 'cloth', .65, 'lowpass=f=4000,', 2),\r\n    ('wood', 'wood-tap-1', 'kenney-impact/Audio/impactWood_light_000.ogg', 'impact', .45, '', 0),\r\n    ('wood', 'wood-tap-2', 'kenney-impact/Audio/impactWood_light_001.ogg', 'impact', .45, '', 0),\r\n    ('wood-scrape', 'wood-scrape', 'wood/wood_impact/crack01.mp3.flac', 'wood', .65, 'lowpass=f=3000,', 0),\r\n    ('cogs', 'cogs-ratchet-1', 'kenney-impact/Audio/impactMetal_light_000.ogg', 'impact', .4, '', 0),\r\n    ('cogs', 'cogs-ratchet-2', 'kenney-impact/Audio/impactMetal_light_001.ogg', 'impact', .4, '', 0),\r\n    ('crt', 'crt-tap', 'crt-original.wav', 'original', .12, '', 0),\r\n    ('transit', 'portal-transit', 'teleport.wav', 'portal', 2, '', 0),\r\n    ('dialup', 'dialup', 'dialup-original.wav', 'original', 1.8, '', 0),\r\n    ('pod-hum', 'pod-hum', 'shop/TheShopCollection_convenience_store_drinks_fridge_drone.wav', 'hum', 12, 'highpass=f=50,lowpass=f=1100,', 1),\r\n    ('whiteboard', 'whiteboard-erase-marker', 'whiteboard-original.wav', 'original', .9, 'highpass=f=300,lowpass=f=4200,', 0),\r\n    ('electric', 'electric-static', 'electric-original.wav', 'original', .25, 'highpass=f=1400,lowpass=f=4200,', 0),\r\n    ('bloop', 'menu-bloop', 'bloop-original.wav', 'original', .22, '', 0),\r\n    ('signal', 'signal-beeps', 'signal-original.wav', 'original', .35, '', 0),\r\n    ('waterfall', 'meditation-waterfall', 'stream-waterfall/stream-waterfall/waterfall1.ogg', 'waterfall', 12, 'highpass=f=80,lowpass=f=5500,', 1),\r\n    ('breeze', 'gentle-breeze', 'wind.wav', 'wind', 12, 'lowpass=f=2300,', 2),\r\n]\r\nSOURCES['wood'] = ('Independent.nu', 'https://opengameart.org/content/35-wooden-crackshitsdestructions')\r\nmanifest = {'version': 1, 'license': 'CC0-1.0 AND CC-BY-3.0', 'cues': {}, 'assets': [], 'sources': []}\r\nfor cue, name, master, provenance, duration, filter_prefix, seek in EDITS:\r\n    source = MASTERS / master\r\n    target = OUT / (name + '.mp3')\r\n    # Normalize masters once; category/interaction gains are controlled by the mixer.\r\n    filters = filter_prefix + 'loudnorm=I=-22:TP=-3:LRA=7'\r\n    if duration < 5:\r\n        filters += ',afade=t=in:st=0:d=0.004'\r\n        filters += f',afade=t=out:st={max(0,duration-.035)}:d=0.035'\r\n    decode = ['ffmpeg', '-hide_banner', '-loglevel', 'error', '-ss', str(seek),\r\n              '-i', str(source), '-t', str(duration), '-af', filters, '-ar', '24000', '-ac', '1']\r\n    if duration >= 5:\r\n        # Make a cyclic overlap: the output starts after the head, then its tail\r\n        # blends into that head. The next loop continues at the adjacent sample,\r\n        # without a recurring fade-to-silence or a discontinuous hard cut.\r\n        samples = array.array('f')\r\n        samples.frombytes(subprocess.check_output(decode + ['-f', 'f32le', '-']))\r\n        overlap = 12000\r\n        blend = array.array('f', (samples[-overlap+i] * (1-i/overlap)\r\n                                 + samples[i] * (i/overlap) for i in range(overlap)))\r\n        cyclic = samples[overlap:-overlap] + blend\r\n        subprocess.run(['ffmpeg', '-hide_banner', '-loglevel', 'error', '-y',\r\n                        '-f', 'f32le', '-ar', '24000', '-ac', '1', '-i', 'pipe:0',\r\n                        '-codec:a', 'libmp3lame', '-b:a', '64k', str(target)],\r\n                       input=cyclic.tobytes(), check=True)\r\n    else:\r\n        subprocess.run(decode + ['-y', '-codec:a', 'libmp3lame', '-b:a', '64k', str(target)], check=True)\r\n    url = '/audio/sfx/' + target.name\r\n    manifest['cues'].setdefault(cue, []).append(url)\r\n    manifest['assets'].append({'url': url, 'source': provenance, 'master': master,\r\n                              'seek': seek, 'maxSeconds': duration, 'filters': filters,\r\n                              'loopCrossfadeSeconds': .5 if duration >= 5 else None,\r\n                              'sha256': hashlib.sha256(target.read_bytes()).hexdigest(),\r\n                              'masterSha256': hashlib.sha256(source.read_bytes()).hexdigest(),\r\n                              'bytes': target.stat().st_size})\r\nmanifest['cues']['dial'] = manifest['cues']['mechanical']\r\nmanifest['cues']['lever'] = manifest['cues']['switch']\r\nfor key, (author, url) in SOURCES.items():\r\n    if any(a['source'] == key for a in manifest['assets']):\r\n        manifest['sources'].append({'id': key, 'author': author, 'url': url, 'license': 'CC-BY-3.0' if key == 'waterfall' else 'CC0-1.0'})\r\n(OUT / 'manifest.json').write_text(json.dumps(manifest, indent=2) + '\\n', encoding='utf-8')\r\nitems = ''.join(f'<li>{html.escape(s[\"author\"])} — <a href=\"{html.escape(s[\"url\"])}\">{html.escape(s[\"id\"])}</a> ({html.escape(s[\"license\"])})</li>' for s in manifest['sources'])\r\n(OUT / 'credits.html').write_text('<!doctype html><html lang=\"en\"><meta charset=\"utf-8\">'\r\n    '<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Sound credits</title>'\r\n    '<style>body{font:18px system-ui;max-width:48rem;margin:3rem auto;padding:1rem;background:#101821;color:#e9f0f7}a{color:#9ee4ff}li{margin:1rem 0}</style>'\r\n    '<h1>Sound credits</h1><p>Effects are released under '\r\n    '<a href=\"https://creativecommons.org/publicdomain/zero/1.0/\">CC0 1.0</a>. '\r\n    'The meditation waterfall is adapted from Stream Sounds by kurt, licensed under <a href=\"https://creativecommons.org/licenses/by/3.0/\">CC BY 3.0</a>, trimmed, filtered, normalized and crossfaded into a loop. Other effects are CC0. Material recordings were edited into short cues; wind, teleport, dial-up and CRT effects include sound design. '\r\n    'Coach voices are local variants of the existing eSpeak NG generated clips. '\r\n    'The app code remains under its existing AGPL license.</p><ul>' + items + '</ul>'\r\n    '<p><a href=\"manifest.json\">Asset provenance and checksums</a> · <a href=\"/source.json\">App source</a> · <a href=\"/pose\">Back to Coach</a></p></html>', encoding='utf-8')\r\nprint(f'Prepared {len(manifest[\"assets\"])} openly licensed clips, {sum(a[\"bytes\"] for a in manifest[\"assets\"]):,} bytes.')\r\n","scripts/provision-pack-catalog-keys.mjs":"import {generateKeyPairSync,createHash} from 'node:crypto';\r\nimport {existsSync,mkdirSync,readFileSync,renameSync,rmSync,writeFileSync} from 'node:fs';\r\nimport {dirname,join} from 'node:path';\r\nimport {spawnSync} from 'node:child_process';\r\n\r\nconst repository=process.env.MYR5_GITHUB_REPOSITORY||'MomInc-MBS/coach-app';\r\nconst activeSecret='PACK_CATALOG_SIGNING_PRIVATE_JWK';\r\nconst output=new URL('../packs/catalog-keys.generated.mjs',import.meta.url);\r\nconst current=readFileSync(output,'utf8');\r\nif(!current.includes('PUBLIC_PACK_CATALOG_KEYS=Object.freeze([])'))throw Error('Catalog keys are already provisioned. Use the documented dual-key rotation procedure instead of replacing them.');\r\n\r\nfunction keyPair(){\r\n return generateKeyPairSync('ed25519',{publicKeyEncoding:{format:'jwk'},privateKeyEncoding:{format:'jwk'}});\r\n}\r\nfunction fingerprint(key){return createHash('sha256').update(Buffer.from(key.x,'base64url')).digest('hex');}\r\nfunction run(command,args,options={}){\r\n const result=spawnSync(command,args,{encoding:'utf8',windowsHide:true,...options});\r\n if(result.status!==0)throw Error((result.stderr||result.stdout||command+' failed').trim());\r\n return result;\r\n}\r\n\r\nconst active=keyPair(),recovery=keyPair();\r\nconst activeFingerprint=fingerprint(active.publicKey),recoveryFingerprint=fingerprint(recovery.publicKey);\r\nconst stamp=new Date().toISOString().slice(0,10);\r\nconst activeId=`myr5-pack-release-${stamp}-${activeFingerprint.slice(0,12)}`;\r\nconst recoveryId=`myr5-pack-recovery-${stamp}-${recoveryFingerprint.slice(0,12)}`;\r\n\r\nrun('gh',['secret','set',activeSecret,'--repo',repository],{\r\n input:JSON.stringify(active.privateKey),\r\n env:{...process.env,GH_PROMPT_DISABLED:'1'}\r\n});\r\n\r\nconst recoveryRoot=join(process.env.LOCALAPPDATA||dirname(process.env.USERPROFILE||process.cwd()),'MYR5','catalog-keys');\r\nconst recoveryPath=join(recoveryRoot,`${recoveryId}.jwk.dpapi`);\r\nif(existsSync(recoveryPath))throw Error('The recovery-key destination already exists.');\r\nmkdirSync(recoveryRoot,{recursive:true});\r\nconst powershell=join(process.env.SystemRoot||'C:\\\\Windows','System32','WindowsPowerShell','v1.0','powershell.exe');\r\nconst protect=[\r\n '$destination=$env:MYR5_RECOVERY_PATH',\r\n '$plaintext=[Console]::In.ReadToEnd()',\r\n \"Add-Type -AssemblyName 'System.Security'\",\r\n '$bytes=[Text.Encoding]::UTF8.GetBytes($plaintext)',\r\n \"$entropy=[Text.Encoding]::UTF8.GetBytes('MYR5 pack catalog recovery v1')\",\r\n '$cipher=[Security.Cryptography.ProtectedData]::Protect($bytes,$entropy,[Security.Cryptography.DataProtectionScope]::CurrentUser)',\r\n '[IO.File]::WriteAllBytes($destination,$cipher)'\r\n].join(';');\r\ntry{\r\n run(powershell,['-NoLogo','-NoProfile','-NonInteractive','-Command',protect],{\r\n  input:JSON.stringify(recovery.privateKey),\r\n  env:{...process.env,MYR5_RECOVERY_PATH:recoveryPath}\r\n });\r\n}catch(error){\r\n try{rmSync(recoveryPath,{force:true});}catch{}\r\n throw error;\r\n}\r\n\r\nconst entry=(keyId,role,publicKey)=>({keyId,role,protocols:[1],publicKey:{kty:'OKP',crv:'Ed25519',x:publicKey.x,ext:true}});\r\nconst keys=[entry(activeId,'release',active.publicKey),entry(recoveryId,'recovery',recovery.publicKey)];\r\nconst source=`// Generated by scripts/provision-pack-catalog-keys.mjs. Private keys never belong in this repository.\\nexport const PUBLIC_PACK_CATALOG_KEYS=Object.freeze(${JSON.stringify(keys,null,2)}.map(entry=>Object.freeze({...entry,protocols:Object.freeze(entry.protocols),publicKey:Object.freeze(entry.publicKey)})));\\n`;\r\nconst temporary=new URL('../packs/.catalog-keys.generated.tmp',import.meta.url);\r\nwriteFileSync(temporary,source,{encoding:'utf8',flag:'wx'});\r\nrenameSync(temporary,output);\r\n\r\nconsole.log(JSON.stringify({\r\n repository,\r\n active:{keyId:activeId,fingerprint:`sha256:${activeFingerprint}`,secret:activeSecret},\r\n recovery:{keyId:recoveryId,fingerprint:`sha256:${recoveryFingerprint}`,encryptedPath:recoveryPath},\r\n publicKeyring:new URL('../packs/catalog-keys.generated.mjs',import.meta.url).pathname\r\n},null,2));\r\n","scripts/r21-preview.cjs":"// Local Release 21 review; read-only API fixtures, no account or production writes.\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..');\r\nconst types={'.html':'text/html; charset=utf-8','.css':'text/css','.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.wasm':'application/wasm','.webp':'image/webp','.png':'image/png'};\r\nhttp.createServer(async(req,res)=>{\r\n const pathname=new URL(req.url,'http://local').pathname;\r\n if(pathname==='/__blank__'){res.setHeader('Content-Type','text/html');res.end('<!doctype html><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Release 21 review</title>');return;}\r\n if(pathname.startsWith('/api/')){res.writeHead(pathname==='/api/auth/config'||pathname==='/api/gala/leaderboard'?200:401,{'Content-Type':'application/json'});res.end(JSON.stringify(pathname==='/api/auth/config'?{enabled:false}:pathname==='/api/gala/leaderboard'?{items:[]}:{error:'Local guest preview'}));return;}\r\n try{const file=path.resolve(root,'.'+decodeURIComponent(pathname.endsWith('/')?pathname+'index.html':pathname));if(!file.startsWith(root+path.sep))throw Error('outside preview');res.setHeader('Content-Type',types[path.extname(file)]||'application/octet-stream');res.end(await fs.readFile(file));}catch{res.writeHead(404);res.end();}\r\n}).listen(Number(process.env.MYR5_R21_PORT)||5203,'127.0.0.1',function(){console.log('Release 21 review http://127.0.0.1:'+this.address().port);});\r\n","scripts/release-build.mjs":"import {createHash} from 'node:crypto';\r\nimport {createReadStream} from 'node:fs';\r\nimport {readdir,writeFile} from 'node:fs/promises';\r\nimport {join} from 'node:path';\r\n\r\n// Stable content identity makes every changed deployment discoverable, even\r\n// when a release-note edit or manual service-worker version bump is forgotten.\r\nexport async function releaseBuildId(root='.'){\r\n const hash=createHash('sha256');\r\n async function add(path){hash.update(path+'\\0');for await(const chunk of createReadStream(join(root,path)))hash.update(chunk);hash.update('\\0');}\r\n async function walk(path){for(const entry of (await readdir(join(root,path),{withFileTypes:true})).sort((a,b)=>a.name.localeCompare(b.name))){if(entry.isSymbolicLink()||entry.name.startsWith('.')||['node_modules','dist'].includes(entry.name))continue;const name=path+'/'+entry.name;if(entry.isDirectory())await walk(name);else if(entry.isFile())await add(name);}}\r\n for(const entry of (await readdir(root,{withFileTypes:true})).sort((a,b)=>a.name.localeCompare(b.name)))if(entry.isFile()&&!['release-build.mjs','launch-runtime.mjs','app-runtime.mjs'].includes(entry.name)&&/\\.(html|css|mjs|js|webmanifest|json)$/.test(entry.name))await add(entry.name);\r\n for(const folder of ['server','db','scripts','scheduler','pod','creature','models','icons','handborne','arcade','voice','local-coach','modules','packs','war-room','food','vendor','audio'])try{await walk(folder);}catch(error){if(error.code!=='ENOENT')throw error;}\r\n return hash.digest('hex').slice(0,20);\r\n}\r\nexport async function prepareReleaseBuild(root='.'){\r\n const id=await releaseBuildId(root);\r\n await writeFile(join(root,'release-build.mjs'),`// Generated by the production build from app content.\\nexport const BUILD_ID='${id}';\\n`);\r\n return id;\r\n}\r\n","scripts/render-route-voice.mjs":"import {readFile,writeFile,mkdir,stat} from 'node:fs/promises';\r\nimport {createHash} from 'node:crypto';\r\nimport {createRequire} from 'node:module';\r\nimport {execFile} from 'node:child_process';\r\nimport {promisify} from 'node:util';\r\nimport {ROUTE_LINES} from '../workout-route.mjs';\r\nconst {synthesize,PROFILE}=createRequire(import.meta.url)('./robot-speech.cjs'),exec=promisify(execFile);\r\nconst manifest=JSON.parse(await readFile('voice/manifest.json','utf8')),profile={...PROFILE,filter:'rubberband-preserved-formants-eq-v1'};\r\nconst phrases=[...Object.values(ROUTE_LINES),...[ROUTE_LINES.advance,ROUTE_LINES.max,ROUTE_LINES.limit].map(line=>line+' '+ROUTE_LINES.rest)];\r\nawait mkdir('../voice-work',{recursive:true});\r\nfor(const text of phrases){\r\n const hash=createHash('sha256').update(JSON.stringify(profile)+'\\n'+text).digest('hex').slice(0,24),output=`voice/${hash}.mp3`;\r\n try{await stat(output);}catch{const input=`../voice-work/${hash}.wav`;await writeFile(input,await synthesize(text));await exec(process.env.MYR5_FFMPEG||'ffmpeg',['-hide_banner','-loglevel','error','-y','-threads','1','-i',input,'-c:a','libmp3lame','-q:a','3','-ac','1',output],{windowsHide:true});}\r\n manifest.phrases[text]='/'+output;\r\n}\r\nmanifest.bytes=(await Promise.all(Object.values(manifest.phrases).map(async url=>(await stat('.'+url)).size))).reduce((a,b)=>a+b,0);\r\nawait writeFile('voice/manifest.json',JSON.stringify(manifest));console.log(`${phrases.length} workout challenge clips ready in the existing robot voice.`);\r\n","scripts/render-voice.mjs":"// Rebuild the approved Coach voice; filenames include its complete sound profile.\r\nimport {readFile,mkdir,writeFile} from 'node:fs/promises';\r\nimport {createHash} from 'node:crypto';\r\nimport {createRequire} from 'node:module';\r\nimport {EXERCISES} from '../exercise-library.mjs';\r\nconst require=createRequire(import.meta.url),{synthesize,PROFILE}=require('./robot-speech.cjs');\r\nconst previous=JSON.parse(await readFile('voice/manifest.json','utf8'));\r\nconst phrases=new Set(Object.keys(previous.phrases));\r\nfor(const file of ['coach.mjs','menu.mjs','app.mjs','movement-engine.mjs','movement-rules.mjs','pod/pod.mjs','pod/encouragement.mjs','coach-profile.mjs','office-domain.mjs']){\r\n const code=await readFile(file,'utf8');for(const m of code.matchAll(/'([^'\\n]{3,600})'/g)){\r\n  const text=m[1];if(/^[A-Za-z]/.test(text)&&/[ .!?]/.test(text)&&!/[<>{}=\\[\\]\\/]/.test(text)&&!text.includes(' · '))phrases.add(text);\r\n }\r\n}\r\nfor(const m of Object.values(EXERCISES))for(const text of [m.name,m.name+' selected.',m.name+' example.',m.name+'? Hold thumbs up to confirm.',m.hint])phrases.add(text);\r\nfor(let n=1;n<=200;n++)phrases.add(String(n));\r\nfor(let n=10;n<=600;n+=10){phrases.add(`${n} seconds.`);phrases.add(`${n} seconds left.`);phrases.add(`${n} seconds. Keep your own pace.`);}\r\nphrases.add('MOM believes in you. One. Two. Three.');\r\nfor(const text of [...phrases])for(const sentence of text.match(/[^.!?]+[.!?]+(?:\\s|$)|[^.!?]+$/g)||[])if(sentence.trim())phrases.add(sentence.trim());\r\nconst soundProfile={...PROFILE,filter:'rubberband-preserved-formants-eq-v1'};\r\nawait mkdir('voice',{recursive:true});\r\nconst manifest={version:2,profile:soundProfile,engine:'eSpeak NG + Rubber Band',license:previous.license,phrases:{}};\r\nlet total=0,completed=0;const queue=[...phrases];\r\nasync function render(){while(queue.length){const text=queue.shift(),filename=createHash('sha256').update(JSON.stringify(soundProfile)+'\\n'+text).digest('hex').slice(0,24)+'.wav';let wav;\r\n try{wav=await readFile('voice/'+filename);}catch{wav=await synthesize(text);await writeFile('voice/'+filename,wav);}\r\n manifest.phrases[text]='/voice/'+filename;total+=wav.length;if(++completed%100===0)console.log(`${completed}/${phrases.size} approved voice clips ready.`);\r\n}}\r\nawait render();\r\nmanifest.bytes=total;await writeFile('voice/manifest.json',JSON.stringify(manifest));console.log(`${completed} approved clips; ${Math.round(total/1024/1024)} MB.`);\r\n","scripts/robot-speech.cjs":"// Local formant speech. No model download, cloud service, microphone, or GPU.\r\nconst {execFile}=require('node:child_process');\r\nconst fs=require('node:fs');\r\nconst octave=require('./octave.cjs');\r\nconst ENGINE='C:/Program Files/eSpeak NG/espeak-ng.exe';\r\n// Keep the synthetic timbre, but retain sentence stress and avoid choppy word gaps.\r\nconst PROFILE={voice:'en-us',wordsPerMinute:125,pitch:52,pitchRange:45,wordGap:0,pitchRatio:2**(-2/12)};\r\nconst cache=new Map(),pending=new Map();let cacheBytes=0;\r\nconst MAX_CACHE=12*1024*1024;\r\nfunction synthesize(text){\r\n if(typeof text!=='string'||!text.trim()||text.length>600||/[\\x00-\\x08\\x0b-\\x1f]/.test(text))return Promise.reject(new Error('Invalid speech text'));\r\n text=text.trim();if(cache.has(text))return Promise.resolve(cache.get(text));if(pending.has(text))return pending.get(text);\r\n if(pending.size>=4)return Promise.reject(new Error('Speech busy'));\r\n const task=new Promise((resolve,reject)=>{\r\n  // Arguments are passed without a shell. Text is never interpreted as markup.\r\n  const args=['--stdout','-b','1','-v',PROFILE.voice,'-s',String(PROFILE.wordsPerMinute),'-p',String(PROFILE.pitch),'-P',String(PROFILE.pitchRange),'-g',String(PROFILE.wordGap),'--stdin'];\r\n  const child=execFile(ENGINE,args,{encoding:'buffer',windowsHide:true,timeout:5000,maxBuffer:5*1024*1024},async(error,wav)=>{\r\n   if(error)return reject(new Error('Robot voice unavailable'));\r\n   if(wav.length<44||wav.toString('ascii',0,4)!=='RIFF')return reject(new Error('Invalid speech audio'));\r\n   // eSpeak's stdout uses streaming placeholder sizes; give phone decoders exact sizes.\r\n   wav.writeUInt32LE(wav.length-8,4);let found=false;\r\n   for(let offset=12;offset+8<=wav.length;){const size=wav.readUInt32LE(offset+4);if(wav.toString('ascii',offset,offset+4)==='data'){wav.writeUInt32LE(wav.length-offset-8,offset+4);found=true;break;}offset+=8+size+(size%2);}\r\n   if(!found)return reject(new Error('Missing speech samples'));\r\n   try{wav=await octave.lowerOctave(wav);}catch(error){reject(error);return;}\r\n   while(cache.size&&cacheBytes+wav.length>MAX_CACHE){const key=cache.keys().next().value;cacheBytes-=cache.get(key).length;cache.delete(key);}\r\n   cache.set(text,wav);cacheBytes+=wav.length;resolve(wav);\r\n  });\r\n  child.stdin.on('error',()=>{});child.stdin.end(text+'\\n','utf8');\r\n }).finally(()=>pending.delete(text));\r\n pending.set(text,task);return task;\r\n}\r\nmodule.exports={synthesize,PROFILE,available:()=>fs.existsSync(ENGINE)&&octave.available()};\r\n","scripts/shader-preview.mjs":"import {createServer} from 'node:http';\r\nimport {readFile,stat} from 'node:fs/promises';\r\nimport {resolve,extname,sep} from 'node:path';\r\nimport {fileURLToPath} from 'node:url';\r\nconst types={'.html':'text/html','.js':'text/javascript','.mjs':'text/javascript','.css':'text/css','.json':'application/json','.webp':'image/webp','.png':'image/png','.jpg':'image/jpeg','.svg':'image/svg+xml','.glb':'model/gltf-binary','.bin':'application/octet-stream','.wasm':'application/wasm','.m4a':'audio/mp4','.mp3':'audio/mpeg','.woff2':'font/woff2','.ttf':'font/ttf','.webmanifest':'application/manifest+json'};\r\nexport function previewServer(root){\r\n root=resolve(root);\r\n return createServer(async(req,res)=>{\r\n  res.setHeader('Cache-Control','no-store');\r\n  const path=decodeURIComponent(new URL(req.url,'http://preview').pathname);\r\n  if(path.startsWith('/api/')){const config=path==='/api/auth/config';res.writeHead(config?200:401,{'Content-Type':'application/json'});res.end(JSON.stringify(config?{enabled:false}:{error:'Sign in on the live app'}));return;}\r\n  try{\r\n   let file=resolve(root,'.'+path);if(!file.startsWith(root+sep)&&file!==root)throw Error();\r\n   if(path.split('/').some(part=>part.startsWith('.'))||/^\\/(?:scripts|server|tests|node_modules|release-trust)(?:\\/|$)/.test(path))throw Error();\r\n   if((await stat(file)).isDirectory())file=resolve(file,'index.html');\r\n   const body=await readFile(file);res.writeHead(200,{'Content-Type':types[extname(file)]||'application/octet-stream'});res.end(req.method==='HEAD'?undefined:body);\r\n  }catch{res.writeHead(404);res.end('Not found');}\r\n });\r\n}\r\nif(process.argv[1]&&resolve(process.argv[1])===fileURLToPath(import.meta.url)){\r\n const root=process.argv[2]||'dist/client',port=Number(process.argv[3])||18941;\r\n previewServer(root).listen(port,'127.0.0.1',()=>console.log(`Shader preview http://127.0.0.1:${port}`));\r\n}\r\n","scripts/source-offer.mjs":"import {readdir,readFile} from 'node:fs/promises';\r\nimport {join} from 'node:path';\r\n\r\n// The AGPL source offer: the authored source needed to rebuild and run this release.\r\n// Never secrets or private material (plan/, env files, *.dpapi, private keys), tests,\r\n// build outputs or media (the app already serves its media).\r\nconst ROOTS=['server','db','scripts','scheduler','pod','local-coach','modules','creature','handborne','war-room','food','packs','arcade','drizzle','release-trust','audio'];\r\nconst GENERATED=new Set(['app-runtime.mjs','launch-runtime.mjs','local-coach-runtime.mjs','nutrition-data.mjs','workout-tracks.js','war-room/gala-bay.js','handborne/companion.mjs']);\r\nconst offered=path=>(path==='LICENSE'||/\\.(mjs|js|cjs|ts|tsx|py|html|css|json|jsonc|sql|webmanifest)$/.test(path))&&!GENERATED.has(path)&&!/(^|\\/)(assets|node_modules|dist|plan|tests)\\/|(^|\\/)\\.|\\.dpapi$|secret|\\.env|\\.dev\\.vars/i.test(path);\r\nconst PRIVATE_KEY=/-----BEGIN [A-Z ]*PRIVATE KEY-----|\"d\"\\s*:\\s*\"[A-Za-z0-9_-]{40,}\"/;\r\nconst SKIP_DIRECTORIES=new Set(['assets','node_modules','dist','plan','tests']);\r\nconst REUSED_SOURCES=['vendor/bitchord/LICENSE','vendor/bitchord/NOTICE','vendor/butterchurn/butterchurn-2.6.7.min.js','vendor/butterchurn/presets-2.4.7.min.js','vendor/butterchurn/LICENSE.engine','vendor/butterchurn/LICENSE.presets','vendor/butterchurn/README.md'];\r\n\r\nexport async function sourceOffer(root='.'){\r\n const paths=(await readdir(root)).filter(offered);\r\n async function walk(folder){\r\n  for(const entry of await readdir(join(root,folder),{withFileTypes:true})){\r\n   if(entry.isSymbolicLink())continue;\r\n   const path=`${folder}/${entry.name}`;\r\n   if(entry.isDirectory()){if(!entry.name.startsWith('.')&&!SKIP_DIRECTORIES.has(entry.name))await walk(path);}\r\n   else if(entry.isFile()&&offered(path))paths.push(path);\r\n  }\r\n }\r\n for(const folder of ROOTS)await walk(folder);\r\n paths.push(...REUSED_SOURCES);\r\n paths.push('vendor/shaders/runtime.mjs','vendor/shaders/LICENSE');\r\n const sources={};\r\n for(const path of paths.sort()){sources[path]=await readFile(join(root,path),'utf8');if(PRIVATE_KEY.test(sources[path]))throw new Error(`The source offer would publish a private key: ${path}`);}\r\n return sources;\r\n}\r\n","scripts/vault-audio-preview.cjs":"// Browser check for page music: node scripts/vault-audio-preview.cjs  (serves the worktree on :8910, drives Chromium)\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=8910;\r\nconst types={'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.m4a':'audio/mp4','.mp3':'audio/mpeg','.html':'text/html'};\r\nconst html=`<!doctype html><html><body><div id=\"portalHome\" hidden></div><button id=\"b\">tap</button><script type=\"module\">\r\nimport {mountPageMusic} from '/audio/page-music.mjs';import {physicalSound} from '/audio/physical-sound.mjs';\r\nphysicalSound.mount();window.physicalSound=physicalSound;window.route='';window.myr5Routes={current:()=>window.route};window.m=mountPageMusic();window.ready=true;\r\n</script></body></html>`;\r\nconst server=http.createServer(async(req,res)=>{const u=new URL(req.url,'http://l');if(u.pathname==='/'){res.setHeader('Content-Type','text/html');return res.end(html);}\r\n try{const f=path.join(root,decodeURIComponent(u.pathname));if(!f.startsWith(root))throw 0;const b=await fs.readFile(f);res.setHeader('Content-Type',types[path.extname(f)]||'application/octet-stream');res.end(b);}catch{res.statusCode=404;res.end('no');}});\r\nasync function main(){\r\n await new Promise(r=>server.listen(PORT,r));\r\n const {chromium}=require('playwright');const browser=await chromium.launch({args:['--autoplay-policy=no-user-gesture-required']});\r\n const page=await browser.newPage();const errors=[];page.on('pageerror',e=>errors.push(e.message));page.on('console',m=>{if(m.type()==='error'||m.type()==='warning')errors.push(m.text());});\r\n await page.goto(`http://localhost:${PORT}/`);await page.waitForFunction(()=>window.ready);\r\n const out={};const wait=ms=>page.waitForTimeout(ms);\r\n out.beforeGesture=await page.evaluate(()=>m.state());\r\n await page.click('#b');await wait(2500);\r\n out.afterGesture=await page.evaluate(()=>m.state());\r\n out.fadeLog=await page.evaluate(()=>m.log.filter(l=>l.what==='fade-in').map(l=>({to:l.v1,dur:+(l.t1-l.t0).toFixed(3)})));\r\n out.bedLog=await page.evaluate(()=>m.log.filter(l=>l.what==='bed').map(l=>({dur:+(l.t1-l.t0).toFixed(3)})));\r\n // decoded length must equal the manifest frames (priming/padding trimmed by the decoder)\r\n out.frames=await page.evaluate(async()=>{const man=await (await fetch('/audio/music/manifest.json')).json();const ctx=physicalSound.context,r={};for(const [n,t] of Object.entries(man.tracks)){const b=await ctx.decodeAudioData(await (await fetch(t.url)).arrayBuffer());r[n]={decoded:b.length,expected:t.frames,sr:b.sampleRate};}return r;});\r\n // grimoire theme: 35 % over 5 s\r\n await page.evaluate(()=>{document.getElementById('portalHome').hidden=false;window.dispatchEvent(new CustomEvent('myr5:route'));});await wait(1500);\r\n out.portalFade=await page.evaluate(()=>({now:m.current(),fades:m.log.filter(l=>l.what==='fade-in').map(l=>({to:l.v1,dur:+(l.t1-l.t0).toFixed(3)})).pop()}));\r\n // same track across routes does not restart\r\n const before=await page.evaluate(()=>m.log.length);await page.evaluate(()=>{window.route='settings';window.dispatchEvent(new CustomEvent('myr5:route'));});await wait(300);\r\n out.noRestart=await page.evaluate(n=>m.log.length===n,before);\r\n // classroom: cut and resume\r\n await page.evaluate(()=>{window.route='scoreboard';document.getElementById('portalHome').hidden=true;window.dispatchEvent(new CustomEvent('myr5:route'));});await wait(1500);\r\n const cut=await page.evaluate(()=>{window.dispatchEvent(new CustomEvent('myr5:music-cut'));return m.state();});\r\n await wait(1200);\r\n const res=await page.evaluate(()=>{const off=m.state().cut.offset;window.dispatchEvent(new CustomEvent('myr5:music-resume'));return {off,playing:m.current()};});\r\n out.cutResume={track:cut.cut&&cut.cut.name,cutOffset:cut.cut&&+cut.cut.offset.toFixed(3),resumed:res.playing,stateAfterCut:cut.playing};\r\n // mute and hidden\r\n await page.evaluate(()=>physicalSound.setMuted(true));await wait(300);\r\n out.mutedMasterGain=await page.evaluate(()=>m.state().muted);\r\n out.errors=errors;console.log(JSON.stringify(out,null,1));await browser.close();server.close();\r\n}\r\nmain().catch(e=>{console.error(e);process.exit(1);});\r\n","scripts/vault-int-e2e.cjs":"// Integration e2e on the BUILT app: node scripts/vault-int-e2e.cjs  (serves dist/client, 375x812 touch). Shots -> .vault/shots/int-*.png\r\nconst {chromium}=require('../node_modules/playwright'),http=require('node:http'),fs=require('node:fs'),path=require('node:path'),assert=require('node:assert/strict');\r\nconst root=path.resolve(__dirname,'../dist/client'),shots=path.resolve(__dirname,'../.vault/shots/');\r\nconst T={'.html':'text/html','.js':'text/javascript','.mjs':'text/javascript','.css':'text/css','.json':'application/json','.webmanifest':'application/manifest+json','.png':'image/png','.webp':'image/webp','.m4a':'audio/mp4','.glb':'model/gltf-binary'};\r\nconst srv=http.createServer((req,res)=>{const p=new URL(req.url,'http://l').pathname;if(p.startsWith('/api/')){res.writeHead(p==='/api/auth/config'?200:401,{'Content-Type':'application/json'});return res.end(JSON.stringify(p==='/api/auth/config'?{enabled:false}:{error:'x'}));}\r\n const f=path.resolve(root,'.'+(p==='/'?'/pose.html':p));if(!f.startsWith(root)||!fs.existsSync(f)||fs.statSync(f).isDirectory()){res.writeHead(404);return res.end();}res.writeHead(200,{'Content-Type':T[path.extname(f)]||'application/octet-stream'});fs.createReadStream(f).pipe(res);});\r\n(async()=>{await new Promise(r=>srv.listen(0,'127.0.0.1',r));const base='http://127.0.0.1:'+srv.address().port;\r\n const b=await chromium.launch({args:['--use-gl=angle','--use-angle=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']});\r\n const ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:2,serviceWorkers:'block',reducedMotion:'reduce'});\r\n await ctx.addInitScript(()=>{Object.defineProperty(navigator,'standalone',{configurable:true,value:true});localStorage.myr5Debug='1';});\r\n await ctx.addInitScript(()=>{const get=Storage.prototype.getItem,d=new Date(),day=`${d.getFullYear()}-${String(d.getMonth()+1).padStart(2,'0')}-${String(d.getDate()).padStart(2,'0')}`;Storage.prototype.getItem=function(k){return String(k).startsWith('myr5-how-to-play-day-v1/')?day:get.call(this,k);};});\r\n const seedP=await ctx.newPage();await seedP.goto(base+'/onboarding.html');\r\n const {completeCoach}=await import('../tests/onboarding-fixture.mjs');\r\n await seedP.evaluate(async intake=>{const {openLocalCoach}=await import('/local-coach-runtime.mjs');const repo=await openLocalCoach();await repo.forOwner(repo.guestOwnerId).saveSetup(intake,{startDay:'2026-09-21'});repo.close();},completeCoach());await seedP.close();\r\n const p=await ctx.newPage(),errs=[];p.on('console',m=>{if(m.type()==='error')errs.push(m.text());});p.on('pageerror',e=>errs.push('pageerror '+e.message));\r\n const shot=async n=>{await p.waitForTimeout(900);await p.screenshot({path:shots+'/int-'+n+'.png'});console.log('shot',n);};\r\n const step=async(n,f)=>{try{await f();console.log('OK  ',n);}catch(e){console.log('FAIL',n,e.message.split('\\n')[0]);}};\r\n await p.goto(base+'/pose.html');await p.waitForFunction(()=>window.myr5TestState?.phase==='idle'&&!!document.querySelector('.coach-dock'),null,{timeout:60000});\r\n await p.evaluate(()=>window.myr5Menus.portal());await p.waitForFunction(()=>document.getElementById('portalHome')?.hidden===false);await shot('01-portal');\r\n await step('music armed on first tap',async()=>{await p.mouse.click(5,5);await p.waitForTimeout(1500);console.log('music',JSON.stringify(await p.evaluate(()=>window.myr5Music?.state())));});\r\n await step('ice: real 10 taps',async()=>{await p.evaluate(()=>myr5Portal.board('ice'));await p.waitForTimeout(4000);await shot('02a-ice-board');\r\n  await p.evaluate(()=>[...document.querySelectorAll('button')].find(b=>/Got it/.test(b.textContent))?.click());await p.waitForTimeout(500);for(let i=0;i<10;i++){await p.touchscreen.tap(187,300);await p.waitForTimeout(450);}\r\n  await p.waitForSelector('#portalVaultDoor',{timeout:8000});await shot('02b-ice-door-poster');\r\n  console.log('ice secret',await p.evaluate(()=>!!JSON.parse(localStorage.getItem(Object.keys(localStorage).find(k=>k.startsWith('myr5-vault-v1/')))||'{}').secrets?.ice));});\r\n await step('other five secrets',async()=>{for(const id of ['pond','jelly','grass','wood','quilt'])await p.evaluate(id=>myr5Portal.secret(id),id);await p.waitForTimeout(500);\r\n  console.log('secrets',await p.evaluate(()=>Object.keys(JSON.parse(localStorage.getItem(Object.keys(localStorage).find(k=>k.startsWith('myr5-vault-v1/'))))?.secrets||{})));await shot('02c-door-poster');});\r\n await step('tap poster -> vault route',async()=>{await p.click('#portalVaultDoor');await p.waitForFunction(()=>document.getElementById('vaultPanel')?.open&&document.getElementById('vaultPanel')._vault,null,{timeout:30000});await p.waitForTimeout(1500);await shot('03-vault-door');\r\n  console.log(JSON.stringify(await p.evaluate(()=>{const i=document.getElementById('vaultPanel')._vault.info();return {head:i.view.head,lines:i.view.lines,foot:i.view.foot};})));});\r\n const info=()=>p.evaluate(()=>document.getElementById('vaultPanel')._vault.info()),P=(u,v)=>p.evaluate(([u,v])=>document.getElementById('vaultPanel')._vault.project(u,v),[u,v]);\r\n const drag=async(pts,hold)=>{const a=await P(...pts[0]);await p.mouse.move(a.x,a.y);await p.mouse.down();for(const q of pts.slice(1)){const c=await P(...q);await p.mouse.move(c.x,c.y,{steps:3});}if(!hold)await p.mouse.up();};\r\n const ring=(c,R,a0,a1,n)=>Array.from({length:n+1},(_,i)=>{const a=a0+(a1-a0)*i/n;return [c[0]+Math.sin(a)*R,c[1]-Math.cos(a)*R];});\r\n await step('knob detent',async()=>{const a=(await info()).view.id;await drag(ring([.5,.455],.07,0,Math.PI/6+.12,4));const c=(await info()).view.id;assert.notEqual(a,c);console.log(a,'->',c);await shot('04-knob');});\r\n await step('flywheel opens',async()=>{await drag(ring([.5,.72],.12,0,Math.PI*2.05,40));await p.waitForTimeout(2500);assert.equal((await info()).open,1);await shot('05-open');});\r\n await step('usb port -> hall',async()=>{const sc=await p.evaluate(()=>document.getElementById('vaultPanel')._vault.projectWorld(0,0,-.2));await p.mouse.click(sc.x,sc.y);await p.waitForFunction(()=>window.myr5Hall,null,{timeout:60000});await p.waitForTimeout(4000);await shot('06-hall');});\r\n await step('statue 1 card',async()=>{await p.evaluate(()=>myr5Hall.go(6*1-4.8));await p.waitForTimeout(6000);console.log(JSON.stringify(await p.evaluate(()=>myr5Hall.debug())));await shot('07-statue1-card');});\r\n await step('earn + sweep',async()=>{const id=await p.evaluate(async()=>{const g=await import('/modules/vault/vault-goals.mjs');return g.GOALS[0].id;});await p.evaluate(id=>myr5Vault.earn(id),id);await p.waitForTimeout(300);await shot('08a-sweep');await p.waitForTimeout(2000);await shot('08-earned');});\r\n await step('open pack -> holographic drop pod',async()=>{await p.waitForSelector('[data-pack]',{timeout:5000});await p.click('[data-pack]');await p.waitForSelector('dialog.drop-pod[data-tier=secret]',{timeout:8000});await shot('09a-pod-sky');await p.waitForTimeout(7000);await shot('09b-pod-landed');\r\n  await p.click('[data-hit]');await p.waitForTimeout(4000);await shot('09c-pod-reveal');console.log('reveal',(await p.textContent('.drop-pod-card')).replace(/\\s+/g,' ').slice(0,200));await p.click('[data-exit]');await p.waitForTimeout(800);await shot('09d-card-after');});\r\n await step('hall end + secrets',async()=>{await p.evaluate(()=>myr5Hall.jump(6*50));await p.waitForTimeout(2500);await shot('10-hall-end');for(const id of ['wood','quilt','ice'])await p.evaluate(id=>myr5Portal.secret(id),id);await p.waitForTimeout(500);});\r\n console.log('hall-end counter',await p.evaluate(()=>JSON.stringify(myr5Vault.state?.())));\r\n console.log(JSON.stringify(errs));console.log('console errors',JSON.stringify(errs.filter(e=>!/Failed to load resource/.test(e))),'(raw',errs.length,')');\r\n await b.close();srv.close();})();\r\n","scripts/vault-l1-preview.cjs":"// Vault L1 (pond secret) review harness: node scripts/vault-l1-preview.cjs  (serves :8902) then drives it with Playwright\r\n// when run with --shots (writes .vault/shots/l1-*.png). Debug hooks: pond.forceBig(), pond.debug().\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),port=Number(process.env.VAULT_L1_PORT)||8902;\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>html,body{margin:0;height:100%;background:#06110f;overflow:hidden}#board{position:absolute;inset:0 15px 100px 15px;touch-action:none}</style><script>\r\n// virtual clock: rAF callbacks only run inside advance(ms) so slow software-GL screenshots cannot skew the hold timing\r\n(()=>{let V=performance.now(),q=[];performance.now=()=>V;window.requestAnimationFrame=cb=>{q.push(cb);return q.length;};window.cancelAnimationFrame=()=>{};\r\nwindow.advance=ms=>{const end=V+ms;while(V<end){V+=1000/30;const c=q;q=[];for(const f of c)f(V);}};})();\r\n</script><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><div id=\"board\"></div><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';import {pond} from '/modules/portal/portal-board-pond.mjs';\r\nwindow.errors=[];window.secrets=0;window.addEventListener('error',e=>errors.push(e.message));window.addEventListener('myr5:portal-secret',e=>{secrets++;window.secretBoard=e.detail.board;});\r\nconst host=document.querySelector('#board');window.pond=pond;\r\ntry{window.board=await createGlbBoard(host,{effect:pond});\r\nconst rel=e=>{const r=host.getBoundingClientRect();return [e.clientX-r.left,e.clientY-r.top];};\r\nhost.onpointerdown=e=>{host.setPointerCapture(e.pointerId);board.press(e.pointerId,...rel(e));};host.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))board.press(e.pointerId,...rel(e));};host.onpointerup=host.onpointercancel=e=>board.release(e.pointerId);\r\nwindow.bigXY=()=>{const f=board.faceRect(),b=pond.debug().big;const r=host.getBoundingClientRect();return [r.left+f.left+b.x*f.width,r.top+f.top+b.y*f.width];};\r\nwindow.ready=true;}catch(e){errors.push(e.stack);}\r\n</script></body></html>`;\r\nconst server=http.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');const data=await fs.readFile(file);res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(port,'127.0.0.1',()=>console.log('Vault L1 preview http://127.0.0.1:'+port));\r\nif(process.argv.includes('--shots'))(async()=>{\r\n const {chromium}=require('playwright'),sleep=ms=>new Promise(r=>setTimeout(r,ms));await fs.mkdir(path.join(root,'.vault/shots'),{recursive:true});\r\n const b=await chromium.launch({channel:'msedge',headless:true,args:['--enable-webgl','--ignore-gpu-blocklist','--use-gl=angle','--use-angle=swiftshader']}),ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:1}),pg=await ctx.newPage();\r\n const logs=[];pg.on('console',m=>logs.push(m.type()+': '+m.text()));pg.on('pageerror',e=>logs.push('pageerror: '+e.message));\r\n await pg.goto('http://127.0.0.1:'+port+'/');await pg.waitForFunction(()=>window.ready||window.errors.length,null,{timeout:60000});\r\n const shot=n=>pg.screenshot({path:path.join(root,'.vault/shots/l1-'+n+'.png')}),dbg=()=>pg.evaluate(()=>{const d=pond.debug();return {sec:d.sec,phase:d.phase,e:d.an&&+d.an.e.toFixed(2),pitch:d.an&&+d.an.pitch.toFixed(2)};});\r\n const adv=async ms=>{for(;ms>0;ms-=200)await pg.evaluate(m=>advance(m),Math.min(200,ms));},start=async()=>{await pg.evaluate(()=>pond.forceBig());await adv(1800);};\r\n // 1) full hold: shots at 0 / .7 / 1.4 / 2.0 s of hold, then the splash\r\n await start();await shot('0-big');let [x,y]=await pg.evaluate(()=>bigXY());await pg.mouse.move(x,y);await pg.mouse.down();await adv(34);\r\n for(const [t,n] of [[0,'0'],[700,'0.7'],[700,'1.4'],[400,'1.8']]){await adv(t);await shot('hold-'+n);console.log('hold',n,await dbg());}\r\n for(const [t,n] of [[100,'splash-a'],[250,'splash-b'],[250,'splash-c'],[400,'splash-d'],[500,'splash-e']]){await adv(t);await shot(n);console.log(n,await dbg());}\r\n await pg.mouse.up();await adv(1500);console.log('after splash',await dbg(),'secrets',await pg.evaluate(()=>[secrets,secretBoard]));await shot('after');\r\n // 2) early lift -> bored\r\n await start();[x,y]=await pg.evaluate(()=>bigXY());await pg.mouse.move(x,y);await pg.mouse.down();await adv(1100);await pg.mouse.up();\r\n for(const [t,n] of [[150,'a'],[600,'b'],[700,'c'],[900,'d'],[1500,'e']]){await adv(t);await shot('bored-'+n);console.log('bored',n,await dbg());}\r\n await adv(3000);console.log('bored end',await dbg(),'secrets',await pg.evaluate(()=>secrets));\r\n // 3) press elsewhere while big: no secret\r\n await start();await pg.mouse.move(40,60);await pg.mouse.down();await adv(2300);console.log('miss',await dbg(),'secrets',await pg.evaluate(()=>secrets));await pg.mouse.up();\r\n console.log('errors',await pg.evaluate(()=>errors),logs.filter(l=>!/^log|^info|^debug/.test(l)));await b.close();server.close();\r\n})().catch(e=>{console.error(e);process.exit(1);});\r\n","scripts/vault-l2-preview.cjs":"// Lane L2 (wood secret) harness: node scripts/vault-l2-preview.cjs [shots]\r\n// Serves a page mounting the wood board on :8903; with `shots` it drives it with Playwright (375x812 touch) and\r\n// writes .vault/shots/l2-*.png, then exits.\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=Number(process.env.VAULT_L2_PORT)||8903;\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>\r\n*{box-sizing:border-box}html,body{margin:0;height:100%;background:#140c06;overflow:hidden}#board{position:absolute;left:15px;right:15px;top:0;bottom:103px;touch-action:none}\r\n</style><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><div id=\"board\"></div><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';import {wood} from '/modules/portal/portal-board-wood.mjs';\r\nwindow.errors=[];window.secrets=[];window.addEventListener('error',e=>errors.push(e.message));window.addEventListener('myr5:portal-secret',e=>secrets.push(e.detail));\r\nconst host=document.querySelector('#board');\r\ntry{window.wood=wood;window.board=await createGlbBoard(host,{effect:wood});board.setTint('#d9a15a');window.ready=true;}catch(e){errors.push(e.stack);}\r\nhost.onpointerdown=e=>{host.setPointerCapture(e.pointerId);board.press(e.pointerId,e.clientX,e.clientY);};\r\nhost.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))board.press(e.pointerId,e.clientX,e.clientY);};\r\nhost.onpointerup=host.onpointercancel=e=>{window.claimed=(board.claims||wood.claims)(e.pointerId);board.release(e.pointerId);};\r\n</script></body></html>`;\r\nconst types={'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css'};\r\nconst server=http.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}\r\n try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');const data=await fs.readFile(file);res.setHeader('Content-Type',types[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}});\r\nserver.listen(PORT,'127.0.0.1',()=>{console.log('Wood secret preview http://127.0.0.1:'+PORT);if(process.argv[2]==='shots')shots().then(()=>process.exit(0),e=>{console.error(e);process.exit(1);});});\r\n\r\nasync function shots(){\r\n const {chromium}=require('playwright'),browser=await chromium.launch({args:['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']});\r\n const page=await (await browser.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:1})).newPage(),logs=[];\r\n page.on('console',m=>{if(['error','warning'].includes(m.type()))logs.push(m.type()+': '+m.text());});\r\n await page.goto('http://127.0.0.1:'+PORT+'/');await page.waitForFunction('window.ready||window.errors.length',null,{timeout:30000});\r\n console.log('errors',await page.evaluate('errors'));\r\n const snap=n=>page.screenshot({path:path.join(root,'.vault/shots/l2-'+n+'.png')}),wait=ms=>page.waitForTimeout(ms);\r\n // face quadrant: top-left area; scrub in x. Mouse = pointer events, same path as touch.\r\n // Scrub through the board API exactly as portal.mjs does (board.press with client coords): legs of 26 px, ~330 ms apart.\r\n await page.evaluate(()=>{window.scrubTo=async(legs,{x0=60,y0=170,leg=26,gap=200}={})=>{const sleep=ms=>new Promise(r=>setTimeout(r,ms));\r\n  board.press(1,x0,y0);for(let k=0;k<legs;k++){for(let j=1;j<=2;j++){board.press(1,x0+(k%2?leg-leg/2*j:leg/2*j),y0+(k%3)*4);await sleep(gap/2);}if(window.stopWhenFire&&myr5Wood.state().stage==='fire')break;}};});\r\n await page.evaluate('scrubTo(6)');await snap('1-heat-a');console.log('rs',JSON.stringify(await page.evaluate('myr5Wood.state().rs.claimId')));await page.evaluate(()=>{window.stopWhenFire=true;return scrubTo(10);});await snap('1-heat-b');await page.evaluate('myr5Wood.stage||0');if((await page.evaluate('myr5Wood.state().stage'))!=='fire'){console.log('software GL too slow for a real 8-reversal scrub; using the debug hook for fire');await page.evaluate('myr5Wood.fire()');}await wait(300);\r\n console.log('heat',JSON.stringify(await page.evaluate('myr5Wood.state().heat')));\r\n console.log('claimed during scrub',await page.evaluate('myr5Wood.state().rs.claimId'));\r\n await page.evaluate('board.release(1)');console.log('claims after lift',await page.evaluate('(board.claims||wood.claims)(1)'),await page.evaluate('myr5Wood.state().stage'));\r\n for(const [n,p] of [['2-fire-start',.25],['3-fire',.6],['4-fire-full',1]]){await page.evaluate(`myr5Wood.pose('fire',${p})`);await wait(n==='4-fire-full'?3500:2500);await snap(n);}\r\n await page.mouse.click(260,520);await wait(500);await page.evaluate('myr5Wood.adv(200)');await wait(1500);await snap('5-steam');\r\n // Software GL runs ~3 fps, so freeze time (debug hook) to photograph each stage.\r\n for(const [n,st,p] of [['6-ash','ash',1],['7-crumble-a','crumble',.3],['8-crumble-b','crumble',.55],['9-crumble-c','crumble',.8],['10-gone','crumble',1]]){await page.evaluate(`myr5Wood.pose('${st}',${p})`);await wait(2200);await snap(n);}\r\n console.log('secrets',JSON.stringify(await page.evaluate('secrets')),'errors',JSON.stringify(await page.evaluate('errors')),'console',JSON.stringify(logs.slice(0,8)));\r\n await browser.close();\r\n}\r\n","scripts/vault-l3-preview.cjs":"// L3 Crystal ice secret preview: node scripts/vault-l3-preview.cjs\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..');\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>L3 Ice secret</title><style>\r\n*{box-sizing:border-box}body{margin:0;background:#000}#board{width:375px;height:812px;position:relative;touch-action:none}\r\n</style></head><body><div id=\"board\"></div><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';\r\nimport {ice} from '/modules/portal/portal-board-ice.mjs';\r\nconst host=document.querySelector('#board');\r\n// manual clock (software GL frames take ~300 ms, which would break a 600 ms tap chain): time only moves when skip(ms) says so; rAF timestamps follow it\r\nlet vt=1000;performance.now=()=>vt;window.skip=ms=>{vt+=ms;};const raf=window.requestAnimationFrame.bind(window);window.requestAnimationFrame=cb=>raf(()=>cb(vt));\r\nwindow.errors=[];window.secrets=0;window.addEventListener('error',e=>errors.push(e.message));\r\nwindow.addEventListener('myr5:portal-secret',()=>window.secrets++);\r\ntry{\r\n const board=window.board=await createGlbBoard(host,{effect:ice});\r\n host.style.background=board.background; // the real portal host paints the board background; a black host is just the harness\r\n host.onpointerdown=e=>{board.press(e.pointerId,e.clientX,e.clientY);window.downClaim=ice.claims(e.pointerId);};\r\n host.onpointermove=e=>{if(e.buttons)board.press(e.pointerId,e.clientX,e.clientY);};\r\n host.onpointerup=host.onpointercancel=e=>{window.lastClaim=ice.claims(e.pointerId);board.release(e.pointerId);};\r\n window.tap=async(x,y,hold=60)=>{const o={pointerId:7,clientX:x,clientY:y,bubbles:true,buttons:1};host.dispatchEvent(new PointerEvent('pointerdown',o));skip(hold);await new Promise(r=>setTimeout(r,350));host.dispatchEvent(new PointerEvent('pointerup',{...o,buttons:0}));};\r\n const pts=[[190,560],[110,430],[270,480],[150,650],[250,650],[120,540],[280,600],[190,450],[200,700],[190,580]];\r\n window.chain=async n=>{window.claimLog=[];for(let i=0;i<n;i++){await tap(...pts[i]);claimLog.push(window.lastClaim);skip(100);await new Promise(r=>setTimeout(r,350));}}; // software GL: each frame blocks ~300 ms, so taps are naturally ~400 ms apart\r\n window.ready=true;\r\n}catch(e){errors.push(e.stack);}\r\n</script></body></html>`;\r\nhttp.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');const data=await fs.readFile(file);res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css','.html':'text/html; charset=utf-8'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(Number(process.env.MYR5_L3_PORT)||8904,'127.0.0.1',function(){console.log('L3 Ice preview: http://127.0.0.1:'+this.address().port);});\r\n","scripts/vault-l3-shots.cjs":"// node scripts/vault-l3-shots.cjs  (preview must be running on 8904): taps the crystal 10 times and screenshots each stage.\r\nconst {chromium}=require('playwright');\r\n(async()=>{\r\n const b=await chromium.launch(),ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true}),pg=await ctx.newPage();\r\n const logs=[];pg.on('console',m=>/error|warn/i.test(m.type())&&logs.push(m.text()));pg.on('pageerror',e=>logs.push(String(e)));\r\n await pg.goto('http://127.0.0.1:'+(process.env.MYR5_L3_PORT||8904)+'/');await pg.waitForFunction('window.ready||window.errors.length',null,{timeout:30000});\r\n console.log('errors',await pg.evaluate('errors'));\r\n const shot=n=>pg.screenshot({path:`.vault/shots/l3-${n}.png`});\r\n for(let i=0;i<14;i++){await pg.evaluate('tap(190,560)');await pg.evaluate('skip(900)');} // warm the lazy crack-frame cache so the real run is not jank-bound\r\n await shot('01-initial');\r\n await pg.evaluate('chain(3)');await pg.evaluate('skip(400)');await pg.waitForTimeout(500);await shot('02-after-3-taps');await pg.evaluate('skip(2500)').then(()=>pg.waitForTimeout(700));\r\n await pg.evaluate('chain(9)');await pg.evaluate('skip(400)');await pg.waitForTimeout(500);await shot('03-after-9-taps');console.log('claims 1-9',await pg.evaluate('claimLog'));await pg.evaluate('skip(2500)').then(()=>pg.waitForTimeout(700));\r\n await pg.evaluate('chain(10)');\r\n for(const n of ['04a-shatter-0','04b-shatter-1','04c-shatter-2']){await pg.evaluate('skip(110)');await pg.waitForTimeout(700);await shot(n);}\r\n await pg.evaluate('skip(1500)');await pg.waitForTimeout(900);await shot('05-empty-face');\r\n console.log('secrets',await pg.evaluate('secrets'));\r\n await pg.evaluate('board.heal()');await pg.waitForTimeout(300);await shot('06-healed');\r\n console.log('console problems',logs);await b.close();\r\n})();\r\n","scripts/vault-l4-preview.cjs":"// Quilt vault-secret review harness: node scripts/vault-l4-preview.cjs [--shoot]  (port 8904; / = bare board, /portal = full portal)\r\n// --shoot drives real two-finger touches with Playwright and saves .vault/shots/l4-*.png\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),port=Number(process.env.VAULT_L4_PORT)||8904;\r\nconst map='<script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script>';\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>*{box-sizing:border-box}body{margin:0;background:#17111e}#board{width:100vw;height:100vh;position:relative;touch-action:none}</style>${map}</head><body><div id=\"board\"></div><script type=\"module\">\r\nimport {createQuiltBoardGL,QUILT_SECRET} from '/modules/portal/portal-board.mjs';\r\nconst raf=requestAnimationFrame.bind(window);window.requestAnimationFrame=cb=>window.__slow?setTimeout(()=>raf(cb),120):raf(cb);QUILT_SECRET.ms2=120000;QUILT_SECRET.ms1=60000;window.errors=[];window.secrets=0;addEventListener('error',e=>errors.push(e.message));addEventListener('myr5:portal-secret',e=>secrets++);\r\nconst host=document.querySelector('#board');\r\ntry{const b=window.board=await createQuiltBoardGL(host);window.claimed={};\r\nhost.onpointerdown=e=>{host.setPointerCapture(e.pointerId);b.press(e.pointerId,e.clientX,e.clientY);};host.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))b.press(e.pointerId,e.clientX,e.clientY);};host.onpointerup=host.onpointercancel=e=>{b.release(e.pointerId);claimed[e.pointerId]=b.claims(e.pointerId);};\r\nwindow.ready=true;}catch(e){errors.push(e.stack);window.ready=true;}\r\n</script></body></html>`;\r\nconst portalHtml=`<!doctype html><style>body{margin:0}</style><button id=\"background\">Coach</button><nav class=\"coach-dock\"></nav>${map}`;\r\nconst srv=http.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'||url.pathname==='/portal'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(url.pathname==='/'?html:portalHtml);return;}try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');let data=await fs.readFile(file);if(file.endsWith('.ts'))data=(await require('esbuild').transform(data.toString(),{loader:'ts'})).code;res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.png':'image/png','.ts':'text/javascript','.css':'text/css'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(port,'127.0.0.1',async()=>{\r\n console.log('Quilt preview http://127.0.0.1:'+port);\r\n if(!process.argv.includes('--shoot'))return;\r\n const {chromium}=require('playwright'),b=await chromium.launch({args:['--use-gl=swiftshader','--enable-unsafe-swiftshader']});\r\n await fs.mkdir(path.join(root,'.vault/shots'),{recursive:true});\r\n const open=async(url,wait)=>{const ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:1}),p=await ctx.newPage();p.on('console',m=>{if(/error|warn/i.test(m.type()))console.log('console:',m.text());});p.on('pageerror',e=>console.log('pageerror',e.message));await p.goto(url);await p.waitForFunction(wait,null,{timeout:60000});return [ctx,p];};\r\n // ---- bare board, real two-finger touches\r\n let [ctx,p]=await open('http://127.0.0.1:'+port+'/',()=>window.ready);\r\n const shot=n=>p.screenshot({path:path.join(root,'.vault/shots/l4-'+n+'.png')}),sleep=ms=>p.waitForTimeout(ms),cdp=await ctx.newCDPSession(p);\r\n const touch=(type,pts)=>cdp.send('Input.dispatchTouchEvent',{type,touchPoints:pts});\r\n const face=await p.evaluate(()=>board.quiltRect()),at=(fx,fy)=>[Math.round(face.left+face.width*fx),Math.round(face.top+face.height*fy)];\r\n const state=()=>p.evaluate(()=>({phase:board.secretDebug.state().phase,p:+board.secretDebug.state().p.toFixed(2),vis:board.secretDebug.vis().map(v=>+v.toFixed(2)),secrets,errors,claimed}));\r\n const pts=(a,dx,dy)=>a.map(([fx,fy],i)=>({x:at(fx,fy)[0]+dx,y:at(fx,fy)[1]+dy,id:i+1}));\r\n const drag=async(a,dx,dy,steps=8,hold=false)=>{await touch('touchStart',pts(a,0,0));for(let i=1;i<=steps;i++){await touch('touchMove',pts(a,dx*i/steps,dy*i/steps));await sleep(30);}if(!hold)await touch('touchEnd',[]);};\r\n const S1=[[.25,.85],[.75,.85]],S2=[[.3,.1],[.3,.35]];\r\n console.log('flat',JSON.stringify(await state()));await shot('0-flat');\r\n await drag(S1,0,-face.height*.28,8,true);await sleep(600);await shot('1a-step1-early');console.log('early1',JSON.stringify(await state()));\r\n await touch('touchEnd',[]);await sleep(900);console.log('fell back',JSON.stringify(await state()));\r\n await drag(S1,0,-face.height*.455,10,true);await sleep(600);await shot('1-step1-middrag');console.log('mid1',JSON.stringify(await state()));\r\n await touch('touchEnd',[]);await sleep(900);await shot('2-step1-done');console.log('done1',JSON.stringify(await state()));\r\n await drag(S2,face.width*.3,0,8,true);await sleep(600);await shot('3a-step2-early');\r\n await touch('touchEnd',[]);await sleep(900);console.log('fell back 2',JSON.stringify(await state()));\r\n await drag(S2,face.width*.52,0,10,true);await sleep(600);await shot('3-step2-middrag');console.log('mid2',JSON.stringify(await state()));\r\n await p.evaluate(()=>{window.__slow=true;});await touch('touchEnd',[]);await sleep(500);await shot('4-step2-done');console.log('done2',JSON.stringify(await state()));\r\n await shot('5-slide-off-a');await shot('5-slide-off-b');await p.evaluate(()=>{window.__slow=false;});await sleep(1200);await shot('5-slide-off-end');console.log('slid',JSON.stringify(await state()));\r\n await p.evaluate(()=>board.heal());await sleep(300);await shot('6-healed');console.log('healed',JSON.stringify(await state()));\r\n await ctx.close();\r\n\r\n // ---- fold angles via the debug hook (real reducer): step 1 and 2 held at 30, 90, 150 degrees\r\n [ctx,p]=await open('http://127.0.0.1:'+port+'/',()=>window.ready);\r\n await p.evaluate(()=>{});const hold=async(step,deg,name)=>{await p.evaluate(([s,d])=>board.secretDebug.fold(s,d/180,false),[step,deg]);await sleep(900);await p.screenshot({path:path.join(root,'.vault/shots/l4-'+name+'.png')});await p.evaluate(()=>board.secretDebug.cancel());};\r\n for(const d of [30,90,120,150]){await hold(1,d,'a1-step1-'+d);await sleep(700);}\r\n await p.evaluate(()=>board.secretDebug.fold(1,1,true));await sleep(1200);\r\n for(const d of [30,90,120,150]){await hold(2,d,'a2-step2-'+d);await sleep(700);}\r\n await p.evaluate(()=>{window.__slow=true;board.secretDebug.fold(2,1,true);});for(let k=0;k<6;k++){await sleep(350);console.log('bundle',k,JSON.stringify(await p.evaluate(()=>board.secretDebug.vis())));await p.screenshot({path:path.join(root,'.vault/shots/l4-a3-bundle'+k+'.png')});}\r\n await ctx.close();\r\n // ---- full portal: secret -> door poster\r\n [ctx,p]=await open('http://127.0.0.1:'+port+'/portal',()=>true);\r\n await p.evaluate(async()=>{window.__went=[];window.myr5Routes={go:id=>window.__went.push(id)};const {openQuiltPortal}=await import('/modules/portal/portal-entry.mjs');window.portal=await openQuiltPortal();window.portal.show();});\r\n await p.waitForFunction(()=>document.getElementById('portalHome')?.hidden===false,null,{timeout:30000});\r\n await p.waitForFunction(()=>window.portal.current().secretDebug,null,{timeout:60000});await sleep(1500);\r\n const cdp2=await ctx.newCDPSession(p),t2=(type,pts)=>cdp2.send('Input.dispatchTouchEvent',{type,touchPoints:pts});\r\n const f2=await p.evaluate(()=>window.portal.current().quiltRect()),a2=(fx,fy)=>[Math.round(f2.left+f2.width*fx),Math.round(f2.top+f2.height*fy)];\r\n const mv=async(a,dx,dy)=>{const P=k=>a.map(([fx,fy],i)=>({x:a2(fx,fy)[0]+dx*k,y:a2(fx,fy)[1]+dy*k,id:i+1}));await t2('touchStart',P(0));for(let k=1;k<=8;k++){await t2('touchMove',P(k/8));await sleep(30);}await t2('touchEnd',[]);};\r\n await mv(S1,0,-f2.height*.4);await sleep(1200);await mv(S2,f2.width*.5,0);\r\n await p.waitForSelector('#portalVaultDoor',{timeout:15000});await sleep(900);await p.screenshot({path:path.join(root,'.vault/shots/l4-7-door-poster.png')});\r\n console.log('portal',JSON.stringify(await p.evaluate(()=>({door:!!document.getElementById('portalVaultDoor'),store:Object.keys(localStorage).filter(k=>k.startsWith('myr5-vault-v1/')).map(k=>JSON.parse(localStorage[k]).secrets)}))));\r\n await b.close();srv.close();\r\n});\r\n","scripts/vault-l5-preview.cjs":"// Vault L5 (grass alien/UFO secret) review harness.\r\n//   node scripts/vault-l5-preview.cjs          serve http://127.0.0.1:8905 (open it, drag from the purple cap to the ship)\r\n//   node scripts/vault-l5-preview.cjs shoot    serve + drive it with Playwright, shots -> .vault/shots/l5-*.png\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=Number(process.env.VAULT_L5_PORT)||8905;\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Grass secret</title><style>\r\n*{box-sizing:border-box}html,body{margin:0;height:100%;background:#0b150a;overflow:hidden}#host{position:fixed;left:15px;right:15px;top:70px;bottom:103px;touch-action:none}#host canvas{width:100%;height:100%}</style>\r\n<script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><div id=\"host\"></div><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';import {grass,SECRET} from '/modules/portal/portal-board-grass.mjs';\r\nwindow.SECRET=SECRET;window.errors=[];window.secretFired=0;window.addEventListener('error',e=>errors.push(e.message));window.addEventListener('myr5:portal-secret',e=>{secretFired++;window.secretDetail=e.detail;});\r\nconst host=document.querySelector('#host');\r\ntry{window.board=await createGlbBoard(host,{effect:grass});window.ready=true;\r\nhost.onpointerdown=e=>{host.setPointerCapture(e.pointerId);board.press(e.pointerId,e.clientX,e.clientY);};\r\nhost.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))board.press(e.pointerId,e.clientX,e.clientY);};\r\nhost.onpointerup=host.onpointercancel=e=>{window.lastClaim=window.myr5GrassSecret.claims(e.pointerId);board.release(e.pointerId);};\r\n}catch(e){errors.push(e.stack);window.ready=true;}\r\n</script></body></html>`;\r\nconst mime={'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css','.html':'text/html; charset=utf-8'};\r\nconst server=http.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}\r\n try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');res.setHeader('Content-Type',mime[path.extname(file)]||'application/octet-stream');res.end(await fs.readFile(file));}catch{res.writeHead(404);res.end();}});\r\nserver.listen(PORT,'127.0.0.1',()=>{console.log('Grass secret preview http://127.0.0.1:'+PORT);if(process.argv[2]==='shoot')shoot().then(()=>process.exit(0),e=>{console.error(e);process.exit(1);});});\r\n\r\nasync function shoot(){\r\n const {chromium}=require('playwright'),out=path.join(root,'.vault','shots');await fs.mkdir(out,{recursive:true});\r\n const browser=await chromium.launch({args:['--use-angle=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']});\r\n const ctx=await browser.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:2}),page=await ctx.newPage();\r\n const logs=[];page.on('console',m=>{if(/error|warn/i.test(m.type()))logs.push(m.text());});page.on('pageerror',e=>logs.push(String(e)));\r\n await page.goto(`http://127.0.0.1:${PORT}/`);await page.waitForFunction('window.ready',null,{timeout:60000});\r\n const wait=ms=>page.waitForTimeout(ms),shot=async(n,clip)=>page.screenshot({path:path.join(out,`l5-${n}.png`),...(clip?{clip}:{})}),state=()=>page.evaluate('window.myr5GrassSecret&&window.myr5GrassSecret.state()');\r\n const f=await page.evaluate('(()=>{const r=board.faceRect();return {l:r.left,t:r.top,w:r.width,h:r.height}})()');\r\n const P=(u,v)=>[f.l+u*f.w,f.t+v*f.h],start=P(.1,.085),ship=P(.9,.915);\r\n await wait(800);await shot('01-idle');\r\n await shot('02-idle-alien-zoom',{x:start[0]-45,y:start[1]-45,width:90,height:90});await shot('03-idle-ufo-zoom',{x:ship[0]-60,y:ship[1]-60,width:110,height:110});\r\n // drag along the straight line in ~14 px strokes (a real finger), pausing at fractions\r\n const lerp=k=>[start[0]+(ship[0]-start[0])*k,start[1]+(ship[1]-start[1])*k],len=Math.hypot(ship[0]-start[0],ship[1]-start[1]);\r\n async function dragTo(k0,k1,ms=16){const n=Math.ceil(len*(k1-k0)/14);for(let i=1;i<=n;i++){const p=lerp(k0+(k1-k0)*i/n);await page.mouse.move(p[0],p[1]);await wait(ms);}}\r\n await page.mouse.move(...start);await page.mouse.down();await dragTo(0,.02);await page.evaluate('SECRET.gapMs=30000');await dragTo(.02,.4,45);await wait(150);await shot('04-following-line');\r\n await dragTo(.4,.55,45);await page.evaluate('SECRET.gapMs=3000');await wait(100);\r\n await page.mouse.up();const claim1=await page.evaluate('window.lastClaim');await wait(1500);const st1=await state();await shot('05-waiting-at-gap');\r\n await wait(2300);const st2=await state();await shot('06-after-3s-reset');\r\n console.log('claim at lift:',claim1,'| gap state phase/pos/len:',st1.phase,st1.pos.toFixed(2),st1.len.toFixed(2),'| after 3s:',st2.phase,'resets',st2.resets);\r\n // full line\r\n await page.mouse.move(...start);await page.mouse.down();await dragTo(0,1,40);await wait(120);\r\n await page.mouse.up();\r\n const tt=Date.now();await page.waitForFunction(\"window.myr5GrassSecret.state().phase==='done'\",null,{timeout:40000});console.log('real run reached done in',Date.now()-tt,'ms after lift; fired',await page.evaluate('window.secretFired'));\r\n const poses=[['board',.5],['fly',.3],['fly',.7],['crack',.45],['crack',1],['split',.3],['split',.6],['done',0]];\r\n for(const [ph,k] of poses){await page.evaluate(`myr5GrassSecret.freeze('${ph}',${k})`);await wait(500);await shot(`07-${ph}-${k}`);}\r\n await wait(400);const fired=await page.evaluate('[window.secretFired,window.secretDetail]'),errs=await page.evaluate('window.errors');\r\n console.log('portal-secret fired:',JSON.stringify(fired),'| page errors:',JSON.stringify(errs),'| console:',JSON.stringify(logs.slice(0,5)));\r\n await browser.close();server.close();\r\n}\r\n","scripts/vault-l6-preview.cjs":"// Jelly vault-secret review harness: node scripts/vault-l6-preview.cjs [--shoot]  (port 8906)\r\n// --shoot drives a held finger with Playwright and saves .vault/shots/l6-*.png\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),port=Number(process.env.VAULT_L6_PORT)||8906;\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style>*{box-sizing:border-box}body{margin:0;background:#0d160a}#board{width:100vw;height:100vh;position:relative;touch-action:none}</style><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><div id=\"board\"></div><script type=\"module\">\r\nimport {createGlbBoard} from '/modules/portal/portal-board-glb.mjs';import {jelly} from '/modules/portal/portal-board-jelly.mjs';\r\nwindow.errors=[];window.secrets=0;addEventListener('error',e=>errors.push(e.message));addEventListener('myr5:portal-secret',e=>secrets++);\r\nconst host=document.querySelector('#board');\r\ntry{window.board=await createGlbBoard(host,{effect:jelly});window.jelly=jelly;\r\nhost.onpointerdown=e=>{host.setPointerCapture(e.pointerId);board.press(e.pointerId,e.clientX,e.clientY);};host.onpointermove=e=>{if(host.hasPointerCapture(e.pointerId))board.press(e.pointerId,e.clientX,e.clientY);};host.onpointerup=host.onpointercancel=e=>{window.lastClaim=jelly.claims(e.pointerId);board.release(e.pointerId);};\r\nwindow.ready=true;}catch(e){errors.push(e.stack);window.ready=true;}\r\n</script></body></html>`;\r\nconst srv=http.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}try{const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');const data=await fs.readFile(file);res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(port,'127.0.0.1',async()=>{\r\n console.log('Jelly preview http://127.0.0.1:'+port);\r\n if(!process.argv.includes('--shoot'))return;\r\n const {chromium}=require('playwright'),b=await chromium.launch({args:['--use-gl=swiftshader','--enable-unsafe-swiftshader']}),ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:1}),p=await ctx.newPage();\r\n p.on('console',m=>{if(/error|warn/i.test(m.type()))console.log('console:',m.text());});\r\n await p.addInitScript(()=>{const r=performance.now.bind(performance);performance.now=()=>window.__pin??r();const raf=requestAnimationFrame.bind(window);window.requestAnimationFrame=cb=>raf(()=>cb(performance.now()));});\r\n await p.goto('http://127.0.0.1:'+port+'/');await p.waitForFunction(()=>window.ready,null,{timeout:60000});\r\n const shot=n=>p.screenshot({path:path.join(root,'.vault/shots/l6-'+n+'.png')}),sleep=ms=>p.waitForTimeout(ms);\r\n await fs.mkdir(path.join(root,'.vault/shots'),{recursive:true});\r\n const cdp=await ctx.newCDPSession(p);\r\n const touch=(type,pts)=>cdp.send('Input.dispatchTouchEvent',{type,touchPoints:pts});\r\n const at={x:80,y:650,id:1};\r\n // fake clock: the effect reads performance.now(), so pin it to press+target and let swiftshader render at its own pace\r\n const pin=async(ms)=>p.evaluate(m=>{window.__pin=window.__t0+m;board.resume();},ms);\r\n await touch('touchStart',[at]);await p.evaluate(()=>{window.__t0=performance.now();});\r\n const at_=async(sec,n)=>{await pin(sec*1000);await sleep(1500);await shot(n);};\r\n await at_(2,'2s');await at_(4,'4s');await at_(5,'5s');await at_(6,'6s');await at_(6.4,'boil');await at_(6.7,'door-rising');await at_(7.1,'door-up');await at_(9,'door-calm');\r\n console.log('state',JSON.stringify(await p.evaluate(()=>({secrets,errors}))));\r\n await touch('touchEnd',[]);\r\n // lift early: hold 3 s, lift, look 0.3 s later and 1.5 s later\r\n await p.evaluate(()=>{window.secrets=0;});\r\n await p.reload();await p.waitForFunction(()=>window.ready);\r\n await touch('touchStart',[at]);await p.evaluate(()=>{window.__t0=performance.now();});\r\n await pin(6600);await sleep(1500);await shot('lift-before');\r\n await touch('touchEnd',[]);await p.evaluate(()=>{window.__t0=window.__pin;});await pin(450);await sleep(1500);await shot('lift-subsiding');await pin(900);await sleep(1500);await shot('lift-after');\r\n console.log('early-lift',JSON.stringify(await p.evaluate(()=>({secrets,errors}))));\r\n await b.close();srv.close();\r\n});\r\n","scripts/vault-l7-poster.cjs":"// Renders pod/worlds/vault/door-poster.webp (a still of the closed door, <=120 KB): node scripts/vault-l7-poster.cjs\r\nconst {chromium}=require('../node_modules/playwright'),{spawn}=require('node:child_process'),fs=require('node:fs'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=process.env.MYR5_VAULT_PORT||8907;\r\n(async()=>{\r\n const srv=spawn(process.execPath,[path.join(__dirname,'vault-l7-preview.cjs')],{env:{...process.env,MYR5_VAULT_PORT:PORT},stdio:'ignore'});await new Promise(r=>setTimeout(r,800));\r\n const b=await chromium.launch({args:['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']}),page=await(await b.newContext({viewport:{width:375,height:812},deviceScaleFactor:2})).newPage();\r\n try{\r\n  await page.goto('http://127.0.0.1:'+PORT+'/');await page.waitForFunction(()=>window.ready,null,{timeout:90000});await page.waitForTimeout(2500);\r\n  const tl=await page.evaluate(()=>vault.projectWorld(-.67,.67,.03)),br=await page.evaluate(()=>vault.projectWorld(.67,-.67,.03));\r\n  const png=await page.screenshot({clip:{x:tl.x,y:tl.y,width:br.x-tl.x,height:br.y-tl.y}});\r\n  const b64=await page.evaluate(async d=>{const bm=await createImageBitmap(await (await fetch('data:image/png;base64,'+d)).blob()),c=document.createElement('canvas');c.width=bm.width;c.height=bm.height;c.getContext('2d').drawImage(bm,0,0);\r\n   for(const q of [.82,.7,.55]){const blob=await new Promise(r=>c.toBlob(r,'image/webp',q));if(blob.size<=115000||q===.55){const u=new Uint8Array(await blob.arrayBuffer());let s='';for(let i=0;i<u.length;i+=8192)s+=String.fromCharCode(...u.subarray(i,i+8192));return btoa(s);}}},png.toString('base64'));\r\n  const out=path.join(root,'pod/worlds/vault/door-poster.webp');fs.mkdirSync(path.dirname(out),{recursive:true});fs.writeFileSync(out,Buffer.from(b64,'base64'));console.log(out,fs.statSync(out).size,'bytes');\r\n }finally{await b.close();srv.kill();}\r\n})().catch(e=>{console.error(e);process.exit(1)});\r\n","scripts/vault-l7-preview.cjs":"// Local review harness for the vault door: node scripts/vault-l7-preview.cjs  (MYR5_VAULT_PORT, default 8907)\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..');\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>Vault door</title><style>html,body{margin:0;height:100%;background:#171020;overflow:hidden}#host{position:fixed;inset:0}</style>\r\n<script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script></head><body><div id=\"host\"></div><script type=\"module\">\r\nimport {mountVaultDoor} from '/modules/vault/vault-door.mjs';\r\nwindow.errors=[];addEventListener('error',e=>errors.push(e.message));addEventListener('unhandledrejection',e=>errors.push(String(e.reason)));\r\nconst GOALS=[\r\n {id:'still-pond',tier:'rare',title:'Still Water',clue:'The koi that fills the pond is not afraid of you.',test:s=>!!s.earned?.['still-pond'],progress:()=>null},\r\n {id:'fire-starter',tier:'rare',title:'Tinder',clue:'Where the wood is dry, rub it the wrong way until it sulks.',test:s=>!!s.earned?.['fire-starter']},\r\n {id:'shares',tier:'rare',title:'Show And Tell',clue:'Pass the secret to five friends on five different days.',test:()=>false,progress:()=>({have:3,need:5})},\r\n {id:'door-open',tier:'rare',title:'Open Sesame',clue:'Turn the great wheel once, and the wall will answer.',test:()=>true},\r\n {id:'all-six',tier:'legendary',title:'Six Of Six',clue:'Every board keeps a secret. Learn them all.',test:()=>false,progress:()=>({have:2,need:6})},\r\n];\r\nconst state={earned:{}};\r\nif(location.search.includes('real')){await (await import('/modules/vault/vault-door.mjs')).openVault();window.ready=true;}else{\r\nwindow.vault=await mountVaultDoor(document.getElementById('host'),{goals:GOALS,read:()=>state,onEnter:()=>{window.entered=(window.entered||0)+1}});\r\nwindow.ready=true;}\r\n</script></body></html>`;\r\nhttp.createServer(async(req,res)=>{const url=new URL(req.url,'http://local');if(url.pathname==='/'){res.setHeader('Content-Type','text/html; charset=utf-8');res.end(html);return;}try{if(url.pathname==='/modules/vault/vault-hall.mjs'&&!require('node:fs').existsSync(path.join(root,'modules/vault/vault-hall.mjs'))){res.setHeader('Content-Type','text/javascript');res.end('export const enterHall=()=>{window.hallEntered=1};');return;}const file=path.resolve(root,'.'+decodeURIComponent(url.pathname));if(!file.startsWith(root+path.sep))throw Error('outside root');let data=await fs.readFile(file);if(file.endsWith('.ts')){data=(await require('esbuild').transform(data.toString(),{loader:'ts',format:'esm'})).code;res.setHeader('Content-Type','text/javascript');res.end(data);return;}res.setHeader('Content-Type',({'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.png':'image/png','.css':'text/css'})[path.extname(file)]||'application/octet-stream');res.end(data);}catch{res.writeHead(404);res.end();}}).listen(Number(process.env.MYR5_VAULT_PORT)||8907,'127.0.0.1',function(){console.log('Vault door preview http://127.0.0.1:'+this.address().port);});\r\n","scripts/vault-l7-shots.cjs":"// Drives the vault-door preview at 375x812 touch and asserts the L7 behaviours: node scripts/vault-l7-shots.cjs\r\n// Starts scripts/vault-l7-preview.cjs itself. Shots -> .vault/shots/L7-*.png, poster -> pod/worlds/vault/door-poster.webp\r\nconst {chromium}=require('../node_modules/playwright'),{spawn}=require('node:child_process'),fs=require('node:fs'),path=require('node:path'),assert=require('node:assert/strict');\r\nconst root=path.resolve(__dirname,'..'),PORT=process.env.MYR5_VAULT_PORT||8907;\r\n(async()=>{\r\n const srv=spawn(process.execPath,[path.join(__dirname,'vault-l7-preview.cjs')],{env:{...process.env,MYR5_VAULT_PORT:PORT},stdio:'ignore'});await new Promise(r=>setTimeout(r,800));\r\n fs.mkdirSync(path.join(root,'.vault/shots'),{recursive:true});\r\n const b=await chromium.launch({args:['--use-gl=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']}),ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:2}),page=await ctx.newPage();\r\n const logs=[];page.on('console',m=>{if(m.type()==='error'&&!/404/.test(m.text()))logs.push(m.text())});page.on('pageerror',e=>logs.push('pageerror '+e.message));\r\n try{\r\n  await page.goto('http://127.0.0.1:'+PORT+'/');await page.waitForFunction(()=>window.ready||window.errors.length,null,{timeout:90000});\r\n  assert.deepEqual(await page.evaluate(()=>window.errors),[]);\r\n  const info=()=>page.evaluate(()=>vault.info()),P=(u,v)=>page.evaluate(([u,v])=>vault.project(u,v),[u,v]);\r\n  const shot=async n=>{await page.waitForTimeout(1800);await page.screenshot({path:path.join(root,'.vault/shots/L7-'+n+'.png')});};\r\n  const drag=async(pts,hold=false)=>{const a=await P(...pts[0]);await page.mouse.move(a.x,a.y);await page.mouse.down();for(const q of pts.slice(1)){const p=await P(...q);await page.mouse.move(p.x,p.y,{steps:3});}if(!hold)await page.mouse.up();};\r\n  const ring=(c,R,a0,a1,n)=>Array.from({length:n+1},(_,i)=>{const a=a0+(a1-a0)*i/n;return [c[0]+Math.sin(a)*R,c[1]-Math.cos(a)*R];});\r\n  await shot('01-idle');\r\n  let i0=await info();assert.equal(i0.shadows,false,'shadows off when idle');assert.equal(i0.awake,false,'no free-running RAF');\r\n  // finger drives gears / pipes / lights / weld\r\n  const wp=Array.from({length:15},(_,i)=>[.12+i*.025,.82+Math.sin(i/2)*.05]);\r\n  const a=await P(...wp[0]);await page.mouse.move(a.x,a.y);await page.mouse.down();for(const q of wp.slice(1)){const p=await P(...q);await page.mouse.move(p.x,p.y,{steps:2});}\r\n  await page.waitForTimeout(150);await page.screenshot({path:path.join(root,'.vault/shots/L7-02-finger.png')});assert.equal((await info()).shadows,true,'shadows on while touched');await page.mouse.up();\r\n  // knob: +30deg steps goals forward in order, wraps; -30deg steps back\r\n  const K=[.5,.455],ids=[];const idx=async()=>(await info()).view.id;\r\n  ids.push(await idx());\r\n  await drag(ring(K,.07,0,Math.PI/6+.12,4));ids.push(await idx());await shot('03-crt-a');\r\n  await drag(ring(K,.07,0,Math.PI/6+.12,4));ids.push(await idx());await shot('04-crt-b');\r\n  await drag(ring(K,.07,0,-(Math.PI/6+.12),4));ids.push(await idx());\r\n  console.log('goal order',ids.join(' > '));\r\n  assert.deepEqual(ids,['still-pond','fire-starter','shares','fire-starter']);\r\n  await drag(ring(K,.07,0,-(Math.PI/6+.12),4));await drag(ring(K,.07,0,-(Math.PI/6+.12),4));assert.equal(await idx(),'all-six','wraps backwards');await shot('05-crt-c');\r\n  // flywheel: half turn held, then released (springs back), then a full turn opens\r\n  const F=[.5,.72];\r\n  await drag(ring(F,.12,0,Math.PI,18),true);await page.waitForTimeout(300);await page.screenshot({path:path.join(root,'.vault/shots/L7-06-fly-half.png')});\r\n  const half=await info();assert.ok(half.progress>.45&&half.progress<.55,'half turn '+half.progress);assert.equal(half.open,0);await page.mouse.up();\r\n  await page.waitForTimeout(2500);assert.ok((await info()).progress<.05,'unfinished turn springs back');\r\n  await drag(ring(F,.12,0,Math.PI*2.05,40));await page.waitForTimeout(1500);await shot('07-open');\r\n  const op=await info();assert.equal(op.open,1,'door fully open');assert.equal(op.awake,true,'hint ring pulses for a few seconds');await page.waitForTimeout(7000);const op2=await info();assert.equal(op2.shadows,false,'asleep after the pulse');assert.equal(op2.awake,false);\r\n  const sc=await page.evaluate(()=>vault.projectWorld(0,0,-.2));await page.mouse.click(sc.x,sc.y);await page.waitForTimeout(450);\r\n  await page.screenshot({path:path.join(root,'.vault/shots/L7-08-mid-dolly.png')});await page.waitForTimeout(1800);\r\n  await page.screenshot({path:path.join(root,'.vault/shots/L7-09-purple-fill.png')});\r\n  assert.equal(await page.evaluate(()=>window.entered),1,'port tap calls enter');\r\n  assert.equal((await info()).awake,false,'dolly ends asleep');\r\n  // the real route: openVault() with the real vault-goals / vault-store\r\n  await page.goto('http://127.0.0.1:'+PORT+'/?real=1');await page.waitForFunction(()=>window.ready||window.errors.length,null,{timeout:90000});\r\n  assert.deepEqual(await page.evaluate(()=>window.errors),[]);const rv=await page.evaluate(()=>document.getElementById('vaultPanel')._vault.info().view);console.log('real route CRT',JSON.stringify(rv));assert.ok(/^GOAL 01\\//.test(rv.head));\r\n  assert.deepEqual(logs,[]);console.log('L7 browser checks passed');\r\n }finally{await b.close();srv.kill();}\r\n})().catch(e=>{console.error(e);process.exit(1)});\r\n","scripts/vault-l8-preview.cjs":"// Hall review harness: node scripts/vault-l8-preview.cjs (port 8908). Uses the real vault modules; open /?debug for myr5Hall hooks.\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=Number(process.env.VAULT_L8_PORT)||8908;\r\nconst html=`<!doctype html><meta name=viewport content=\"width=device-width,initial-scale=1\"><body style=\"margin:0;background:#000\"><script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\",\"three/addons/loaders/GLTFLoader.js\":\"/vendor/three/GLTFLoader.js\",\"three/addons/libs/meshopt_decoder.module.js\":\"/vendor/three/meshopt_decoder.module.js\"}}</script><script type=module>window.errors=[];addEventListener('error',e=>errors.push(e.message));\r\nawait import('/modules/vault/vault-store.mjs');const m=await import('/modules/vault/vault-hall.mjs');window.hall=m;window.go=()=>m.enterHall();document.body.insertAdjacentHTML('beforeend','<button id=go style=\"position:fixed;top:40%;left:30%;z-index:99\">enter</button>');go.onclick=()=>m.enterHall();</script>`;\r\nconst mime={'.mjs':'text/javascript','.js':'text/javascript','.json':'application/json','.glb':'model/gltf-binary','.webp':'image/webp','.css':'text/css','.ts':'text/javascript'};\r\nconst server=http.createServer(async(req,res)=>{const u=new URL(req.url,'http://l');if(u.pathname==='/'){res.setHeader('Content-Type','text/html');return res.end(html);}\r\n try{const f=path.resolve(root,'.'+decodeURIComponent(u.pathname));if(!f.startsWith(root+path.sep))throw 0;let d=await fs.readFile(f);if(f.endsWith('.ts'))d=require('node:module').stripTypeScriptTypes(d.toString());res.setHeader('Content-Type',mime[path.extname(f)]||'application/octet-stream');res.end(d);}\r\n catch{res.writeHead(404);res.end();}});\r\nmodule.exports={server,PORT};\r\nif(require.main===module)server.listen(PORT,'127.0.0.1',()=>console.log('hall preview http://127.0.0.1:'+PORT));\r\n","scripts/vault-l8-shots.cjs":"const {server,PORT}=require('./vault-l8-preview.cjs'),{chromium}=require('playwright'),out=require('node:path').resolve(__dirname,'../.vault/shots/');\r\n(async()=>{await new Promise(r=>server.listen(PORT,'127.0.0.1',r));const b=await chromium.launch({args:['--use-gl=angle','--use-angle=swiftshader','--enable-unsafe-swiftshader','--ignore-gpu-blocklist']});\r\nconst p=await (await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:2})).newPage();const errs=[];p.on('console',m=>m.type()==='error'&&errs.push(m.text()));p.on('pageerror',e=>errs.push(String(e)));\r\nconst shot=n=>p.screenshot({path:out+'/l8-'+n+'.png'}),dbg=()=>p.evaluate(()=>myr5Hall.debug()),wait=ms=>p.waitForTimeout(ms),S=k=>6*(k+1)-4.8;\r\nawait p.goto(`http://127.0.0.1:${PORT}/?debug`);await p.waitForFunction(()=>window.go,null,{timeout:15000}).catch(()=>console.log(errs));\r\nconst ids=await p.evaluate(async()=>{const g=await import('/modules/vault/vault-goals.mjs');return g.GOALS.map(x=>x.id);});console.log('goals',ids.length,ids.at(-1));\r\nconsole.log('pre-errs',JSON.stringify(errs));await p.evaluate(()=>{myr5Vault.reset();window.go();});\r\nawait p.waitForFunction(()=>window.myr5Hall,null,{timeout:30000}).catch(()=>console.log('nohall',JSON.stringify(errs)));for(const [n,t] of [['25',.8],['50',1.6],['75',2.4]]){await p.evaluate(t=>myr5Hall.at(t),t);await wait(500);await shot('1-transition-'+n);}await p.evaluate(()=>myr5Hall.at(-1));await wait(3500);await shot('2-start');\r\nawait p.evaluate(s=>myr5Hall.go(s),S(0));await wait(5000);console.log(JSON.stringify(await dbg()));await shot('3-locked-card');\r\nawait p.evaluate(id=>myr5Vault.earn(id),ids[0]);await wait(250);await shot('4a-earn-sweep');await wait(1800);await shot('4-earned-card');\r\nconsole.log('pack btn',await p.evaluate(()=>!!document.querySelector('[data-pack]')));\r\nif(await p.$('[data-pack]')){await p.click('[data-pack]');await wait(1200);await shot('4b-pack-opened');}\r\nfor(const k of [1,2,3]){await p.evaluate(s=>myr5Hall.jump(s),S(k));await wait(1800);await shot('5-statue'+(k+1));}\r\nawait p.evaluate(()=>myr5Hall.jump(6*40));await wait(2500);console.log(JSON.stringify(await dbg()));await shot('6-far');\r\nconsole.log('errors',JSON.stringify(errs));await b.close();server.close();})();\r\n","scripts/vault-tub-preview.cjs":"// Tub flight endless review harness. node scripts/vault-tub-preview.cjs shoot  -> .vault/shots/tub-*.png\r\nconst http=require('node:http'),fs=require('node:fs/promises'),path=require('node:path');\r\nconst root=path.resolve(__dirname,'..'),PORT=Number(process.env.VAULT_TUB_PORT)||8921;\r\nconst html=`<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><link rel=\"stylesheet\" href=\"/arcade/tub-flight/style.css\"><style>body{margin:0;padding:10px;background:#164743}</style></head><body><main id=\"g\"></main><script type=\"module\">\r\nimport {mountTubFlight} from '/arcade/tub-flight/game.mjs';window.errors=[];addEventListener('error',e=>errors.push(e.message));window.fuelCalls=0;\r\nwindow.h=mountTubFlight(document.getElementById('g'),{autoFuel:true,onComplete:()=>fuelCalls++});\r\nwindow.bot=true;const g=h.game;setInterval(()=>{if(!bot||g.phase!=='running')return;const p=g.pipes.find(p=>p.x+44>69);const t=p?p.gap+8:210;if(g.y>t&&g.velocity>0)g.flap();},8);\r\n</script></body></html>`;\r\nconst mime={'.mjs':'text/javascript','.css':'text/css'};\r\nconst server=http.createServer(async(req,res)=>{const u=new URL(req.url,'http://l');if(u.pathname==='/'){res.setHeader('Content-Type','text/html');res.end(html);return;}\r\n try{const f=path.resolve(root,'.'+u.pathname);if(!f.startsWith(root+path.sep))throw 0;res.setHeader('Content-Type',mime[path.extname(f)]||'application/octet-stream');res.end(await fs.readFile(f));}catch{res.writeHead(404);res.end();}});\r\nserver.listen(PORT,'127.0.0.1',()=>{if(process.argv[2]==='shoot')shoot().then(()=>process.exit(0),e=>{console.error(e);process.exit(1);});else console.log('http://127.0.0.1:'+PORT);});\r\nasync function shoot(){\r\n const {chromium}=require('playwright'),out=path.join(root,'.vault','shots');await fs.mkdir(out,{recursive:true});\r\n const b=await chromium.launch(),ctx=await b.newContext({viewport:{width:375,height:812},hasTouch:true,deviceScaleFactor:2}),page=await ctx.newPage();\r\n const logs=[];page.on('console',m=>{if(/error|warn/i.test(m.type()))logs.push(m.text());});page.on('pageerror',e=>logs.push(String(e)));\r\n await page.goto(`http://127.0.0.1:${PORT}/`);await page.waitForFunction('window.h');\r\n const shot=n=>page.screenshot({path:path.join(out,`tub-${n}.png`)}),sc=()=>page.evaluate('h.game.score');\r\n const until=n=>page.waitForFunction(`h.game.score>=${n}||h.game.phase==='crashed'`,null,{timeout:120000,polling:20});\r\n await page.evaluate('localStorage.clear()');await page.reload();await page.waitForFunction('window.h');\r\n await shot('1-start');\r\n await page.evaluate('h.game.flap();document.querySelector(\"canvas\").dispatchEvent(new Event(\"pointerdown\"))');\r\n await until(5);await page.evaluate('h.pause()');console.log('mid',await sc());await shot('2-mid5');await page.click('[data-pause]');\r\n await until(8);await page.waitForTimeout(300);console.log('fuel',await sc(),await page.evaluate('[fuelCalls,localStorage.getItem(\"mbs-fuel-flight-v1\"),h.game.phase]'));await shot('3-fuel-toast');\r\n await until(16);await page.evaluate('h.pause()');console.log('mid16',await sc(),await page.evaluate('h.game.pipes[0].half'));await shot('4-mid16');\r\n await page.click('[data-pause]');await page.evaluate('bot=false');await page.waitForFunction(\"h.game.phase==='crashed'\",null,{timeout:20000});await page.waitForTimeout(150);\r\n console.log('crash',await page.evaluate('[h.game.score,localStorage.getItem(\"mbs-tub-best-v1\"),localStorage.getItem(\"myr5-vault-pending\")]'));await shot('5-crash');\r\n await page.click('[data-retry]');await shot('6-retry');console.log('errors',logs,await page.evaluate('errors'));await b.close();}\r\n","scripts/workout-tracking-research.mjs":"// Read-only synthetic research probes. Does not change production modules.\r\nimport {MovementSession,features,MOVEMENTS} from '../movement-engine.mjs';\r\nimport {evaluateMovement} from '../movement-rules.mjs';\r\nimport {ENGINE,LIBRARY} from '../tests/pose-fixtures.mjs';\r\nimport {PoseClassifier} from '../pose-classifier.mjs';\r\nimport {convert} from './pose-samples.mjs';\r\nimport {syntheticRecording} from '../tests/pose-fixtures.mjs';\r\nimport {execFileSync} from 'node:child_process';\r\n\r\nconst clone=p=>p.map(v=>({...v}));\r\nfunction tree(){const p=ENGINE.standing();Object.assign(p[25],{x:.25,y:.60});return p;}\r\nfunction hold(mode,pose,{missing=null,from=2000,to=2400}={}){\r\n const session=new MovementSession(mode,{samples:null});\r\n for(let t=0;t<=5000;t+=50){let p=clone(pose());if(missing&&t>=from&&t<to)p=missing(p);session.update(p,t);}\r\n return {seconds:session.totalHold,continuous:session.hold,message:session.message};\r\n}\r\nconst obscure=p=>p.map((v,i)=>({...v,visibility:[11,12,13,14,15,16,23,24,25,26].includes(i)?0:v.visibility}));\r\nconst results={source:execFileSync('git',['rev-parse','HEAD'],{encoding:'utf8'}).trim(),syntheticOnly:true,hold:[],cadence:[]};\r\nfor(const [mode,pose] of [['tree',tree],['high-plank',()=>LIBRARY.floor()]]){\r\n for(const [label,missing] of [['continuous',null],['missing-joints',obscure],['no-pose',()=>null]]){\r\n  results.hold.push({mode,scenario:label,...hold(mode,pose,{missing})});\r\n }\r\n}\r\nconst floor=LIBRARY.floor(),handsKnees=clone(floor);\r\nfor(const i of [25,26])Object.assign(handsKnees[i],{x:.5,y:.8});\r\nconst cropped=p=>p.map((v,i)=>({...v,...([25,26].includes(i)?{y:1.2,visibility:0}:{})}));\r\nresults.plankAmbiguity={visible:evaluateMovement(features(handsKnees),MOVEMENTS['high-plank']),cropped:evaluateMovement(features(cropped(handsKnees)),MOVEMENTS['high-plank'])};\r\nfunction count(fps,period,offset){\r\n const r=new MovementSession('squat',{samples:null}),a=ENGINE.standing(),b=ENGINE.squat(),n=10,end=3+n*period;\r\n for(let t=offset/fps;t<end+2;t+=1/fps){const k=t<3||t>=end?0:(1-Math.cos(2*Math.PI*(t-3)/period))/2;\r\n  r.update(a.map((v,i)=>({...v,x:v.x+(b[i].x-v.x)*k,y:v.y+(b[i].y-v.y)*k})),t*1000);\r\n }\r\n return r.count;\r\n}\r\nfor(const fps of [1.4,1.5,1.6,2,2.5,4,8,15,30])for(const period of [1,1.5,2,3,4]){\r\n const counts=Array.from({length:40},(_,i)=>count(fps,period,i/40));\r\n results.cadence.push({fps,secondsPerRep:period,expected:10,min:Math.min(...counts),max:Math.max(...counts),mean:counts.reduce((a,b)=>a+b,0)/counts.length,exact:counts.filter(n=>n===10).length,phases:40});\r\n}\r\nconst {samples}=convert(syntheticRecording()),knn=new PoseClassifier(samples),p=ENGINE.standing();\r\nconst gate=points=>features(points).visible(knn.need);\r\nconst crop=p.map((v,i)=>({...v,...([25,26].includes(i)?{y:1.2,visibility:0}:{})}));\r\nresults.knn={required:knn.need,standing:{gate:gate(p),votes:knn.classify(features(p).p)},kneesCropped:{gate:gate(crop),votes:knn.classify(features(crop).p)}};\r\nconsole.log(JSON.stringify(results,null,2));\r\n","serve.cjs":"// Launcher for the local Pixel adaptation of Ian's MYR5 pose demo.\r\n// It serves the test HTML and its license. Rep milestones are acknowledged without\r\n// writing cards to the ship console. No camera frames are received or stored.\r\nconst http = require('node:http');\r\nconst fs = require('node:fs');\r\nconst speech=require('./robot-speech.cjs');\r\nconst source = require('node:path').join(__dirname, 'pose.html');\r\nconst port = Number(process.env.MYR5_PORT || 8816);\r\nconst publicOrigin = process.env.MYR5_PUBLIC_ORIGIN || '';\r\nif (publicOrigin) {\r\n  const parsed = new URL(publicOrigin);\r\n  if (parsed.protocol !== 'https:' || parsed.origin !== publicOrigin) {\r\n    throw new Error('MYR5_PUBLIC_ORIGIN must be an exact HTTPS origin without a trailing slash.');\r\n  }\r\n}\r\nconst allowedOrigins = new Set([`http://localhost:${port}`, `http://127.0.0.1:${port}`, publicOrigin].filter(Boolean));\r\nlet cameraInfo=null;\r\n\r\nif (!fs.existsSync(source)) {\r\n  console.error('The existing MYR5 pose demo was not found at: ' + source);\r\n  process.exit(1);\r\n}\r\n\r\nconst server = http.createServer((req, res) => {\r\n  const path = new URL(req.url, 'http://localhost:' + port).pathname;\r\n  res.setHeader('Cache-Control', 'no-store');\r\n  res.setHeader('X-Content-Type-Options', 'nosniff');\r\n  res.setHeader('X-Robots-Tag', 'noindex, nofollow');\r\n  if(path==='/speech'){\r\n    if(req.method!=='POST'){res.writeHead(405);res.end();return;}\r\n    if(req.headers.origin&&!allowedOrigins.has(req.headers.origin)){req.resume();res.writeHead(403);res.end();return;}\r\n    let body='';req.on('data',chunk=>{body+=chunk;if(body.length>4096)req.destroy();});\r\n    req.on('end',async()=>{let text;try{text=JSON.parse(body).text;if(typeof text!=='string'||!text.trim()||text.length>600)throw new Error();}catch{res.writeHead(400);res.end();return;}\r\n      try{const wav=await speech.synthesize(text);if(!res.destroyed){res.writeHead(200,{'Content-Type':'audio/wav','Content-Length':wav.length});res.end(wav);}}\r\n      catch{if(!res.destroyed){res.writeHead(503);res.end('Speech unavailable');}}\r\n    });return;\r\n  }\r\n  if(path==='/camera-info'){\r\n    if(req.method==='GET'){res.writeHead(200,{'Content-Type':'application/json'});res.end(JSON.stringify(cameraInfo&&Date.now()-cameraInfo.receivedAt<300000?cameraInfo:null));return;}\r\n    if(req.method==='POST'){\r\n      if(req.headers.origin&&!allowedOrigins.has(req.headers.origin)){req.resume();res.writeHead(403);res.end();return;}\r\n      let body='';req.on('data',chunk=>{body+=chunk;if(body.length>12000)req.destroy();});\r\n      req.on('end',()=>{try{const input=JSON.parse(body);const str=v=>String(v??'').slice(0,180),num=v=>Number.isFinite(v)?v:null;cameraInfo={receivedAt:Date.now(),version:str(input.version),label:str(input.label),facing:str(input.facing),width:num(input.width),height:num(input.height),zoom:{supported:!!input.zoom?.supported,applied:!!input.zoom?.applied,min:num(input.zoom?.min),max:num(input.zoom?.max),zoom:num(input.zoom?.zoom)},lenses:Array.isArray(input.lenses)?input.lenses.slice(0,20).map(str):[]};res.writeHead(204);res.end();}catch{res.writeHead(400);res.end();}});return;\r\n    }\r\n    res.writeHead(405);res.end();return;\r\n  }\r\n  // MYR5 companion files use one shared renderer in the editor and phone view.\r\n  if((req.method==='GET'||req.method==='HEAD')&&['/pod/pod.css','/pod/pod.mjs','/pod/set-flow.mjs','/pod/encouragement.mjs','/pod/identity.mjs','/pod/gala-avatar.js','/pod/mom-inc-mark.png'].includes(path)){\r\n    const file=require('node:path').join(__dirname,path.slice(1)),type=path.endsWith('.css')?'text/css; charset=utf-8':path.endsWith('.png')?'image/png':'text/javascript; charset=utf-8';\r\n    fs.readFile(file,(error,data)=>{if(error){res.writeHead(404);res.end();return;}res.writeHead(200,{'Content-Type':type,'Content-Length':data.length});res.end(req.method==='HEAD'?undefined:data);});return;\r\n  }\r\n  if ((req.method === 'GET' || req.method === 'HEAD') && path.startsWith('/creature/')) {\r\n    const paths=require('node:path'),root=paths.join(__dirname,'creature');\r\n    let relative;try{relative=decodeURIComponent(path.slice('/creature/'.length));}catch{res.writeHead(400);res.end();return;}\r\n    const file=paths.resolve(root,relative||'index.html');\r\n    if(!file.startsWith(root+paths.sep)){res.writeHead(404);res.end();return;}\r\n    const types={'.html':'text/html; charset=utf-8','.js':'text/javascript; charset=utf-8','.css':'text/css; charset=utf-8','.glb':'model/gltf-binary','.json':'application/json','.map':'application/json','.md':'text/plain; charset=utf-8','.txt':'text/plain; charset=utf-8'};\r\n    fs.stat(file,(error,stat)=>{if(error||!stat.isFile()){res.writeHead(404);res.end();return;}res.writeHead(200,{'Content-Type':types[paths.extname(file)]||'application/octet-stream','Content-Length':stat.size});if(req.method==='HEAD')res.end();else fs.createReadStream(file).pipe(res);});return;\r\n  }\r\n  if (req.method === 'GET' && path === '/health') {\r\n    res.writeHead(200, { 'Content-Type': 'application/json' });\r\n    res.end(JSON.stringify({ name: 'myr5-pixel-movement-test', sourceExists: fs.existsSync(source), phoneLinkConfigured: !!publicOrigin, speechAvailable: speech.available() }));\r\n    return;\r\n  }\r\n  if (req.method === 'POST' && path === '/cmd') {\r\n    req.resume();\r\n    res.writeHead(204);\r\n    res.end();\r\n    return;\r\n  }\r\n  if (req.method === 'GET' && ['/app.mjs','/movement-engine.mjs','/menu.mjs','/hand-controls.mjs','/hand-gesture.mjs','/exercise-gestures.mjs','/gesture-controls.mjs','/coach.mjs','/robot-audio.mjs','/demo-poses.mjs','/hologram.mjs','/camera.mjs','/menu.css','/models/squat.glb','/models/pushup.glb'].includes(path)) {\r\n    fs.readFile(require('node:path').join(__dirname,path.slice(1)),(error,data)=>{\r\n      if(error){res.writeHead(500,{'Content-Type':'text/plain'});res.end('Test module could not be loaded.');return;}\r\n      const type=path.endsWith('.css')?'text/css; charset=utf-8':path.endsWith('.glb')?'model/gltf-binary':'text/javascript; charset=utf-8';\r\n      res.writeHead(200,{'Content-Type':type});res.end(data);\r\n    });\r\n    return;\r\n  }\r\n  if (req.method === 'GET' && path === '/LICENSE') {\r\n    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });\r\n    fs.createReadStream(require('node:path').join(__dirname, 'LICENSE')).pipe(res);\r\n    return;\r\n  }\r\n  if ((req.method === 'GET' || req.method === 'HEAD') && (path === '/' || path === '/pose.html')) {\r\n    fs.readFile(source, (error, data) => {\r\n      if (error) {\r\n        res.writeHead(500, { 'Content-Type': 'text/plain' });\r\n        res.end('Could not read the local pose demo.');\r\n        return;\r\n      }\r\n      res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });\r\n      res.end(req.method === 'HEAD' ? undefined : data);\r\n    });\r\n    return;\r\n  }\r\n  res.writeHead(404, { 'Content-Type': 'text/plain' });\r\n  res.end('Not found');\r\n});\r\n\r\nserver.on('error', async error => {\r\n  if (error.code === 'EADDRINUSE') {\r\n    try {\r\n      const response = await fetch('http://127.0.0.1:' + port + '/health', { signal: AbortSignal.timeout(1500) });\r\n      const health = await response.json();\r\n      if (health.name === 'myr5-pixel-movement-test') {\r\n        console.log('The MYR5 phone test is already running.');\r\n        console.log('Phone address after forwarding: http://localhost:' + port + '/pose.html');\r\n        return;\r\n      }\r\n    } catch {}\r\n  }\r\n  console.error('Could not start the MYR5 phone test: ' + error.message);\r\n  process.exitCode = 1;\r\n});\r\n\r\nserver.listen(port, '127.0.0.1', () => {\r\n  console.log('MYR5 phone movement test is ready.');\r\n  if (publicOrigin) console.log('Phone test link: ' + publicOrigin + '/pose.html');\r\n  console.log('In desktop Chrome: chrome://inspect/#devices');\r\n  console.log('Forward phone port 8816 to localhost:8816.');\r\n  console.log('On your phone: http://localhost:8816/pose.html');\r\n  console.log('Keep this process running. Press Ctrl+C to stop it.');\r\n});\r\n","server/account-data-epochs.mjs":"// Primary-D1 foundation only. A route must supply an authenticated canonical\r\n// owner and its own owner-bound statements; this module performs no remote I/O.\r\nexport class AccountDataEpochError extends Error {\r\n constructor(code, message=code, options){super(message,options);this.name='AccountDataEpochError';this.code=code;}\r\n}\r\nconst fail=code=>{throw new AccountDataEpochError(code);};\r\nconst owner=value=>{if(typeof value!=='string'||!value||value.length>512||value.trim()!==value)fail('invalid-owner');return value;};\r\nconst safeEpoch=value=>{if(!Number.isSafeInteger(value)||value<1)fail('invalid-epoch');return value;};\r\nconst safeTime=value=>{if(!Number.isSafeInteger(value)||value<0)fail('invalid-time');return value;};\r\nconst provision=(database,ownerId,now)=>database.prepare('INSERT INTO account_data_epochs(owner_id,epoch,updated_at) VALUES(?,1,?) ON CONFLICT(owner_id) DO NOTHING').bind(ownerId,now);\r\n\r\n// One SQL statement gives a coherent snapshot when another deletion commits.\r\n// Missing rows mean untouched legacy epoch 1, never a deletion confirmation.\r\nexport async function inspectAccountDataEpoch(database,ownerId){\r\n ownerId=owner(ownerId);\r\n const row=await database.prepare('SELECT e.epoch, (SELECT MAX(d.deleted_epoch) FROM account_data_deletions d WHERE d.owner_id=e.owner_id) AS deleted_through_epoch FROM account_data_epochs e WHERE e.owner_id=?').bind(ownerId).first();\r\n if(!row)return {ownerId,currentDataEpoch:1,deletedThroughEpoch:0};\r\n const currentDataEpoch=safeEpoch(row.epoch),deletedThroughEpoch=row.deleted_through_epoch??0;\r\n if(!Number.isSafeInteger(deletedThroughEpoch)||deletedThroughEpoch<0||deletedThroughEpoch!==currentDataEpoch-1)fail('epoch-history-corrupt');\r\n return {ownerId,currentDataEpoch,deletedThroughEpoch};\r\n}\r\nexport async function readAccountDataEpoch(database,ownerId,now){\r\n ownerId=owner(ownerId);now=safeTime(now);\r\n await provision(database,ownerId,now).run();\r\n return inspectAccountDataEpoch(database,ownerId);\r\n}\r\n\r\n// Keep every primary data deletion in this same batch. A zero-row SELECT is\r\n// NOT a guard: the receipt's NOT NULL constraint aborts the entire transaction.\r\n// Receipts/epoch tombstones must never be included in the supplied deletions.\r\nexport async function deleteAccountDataAtEpoch(database,{ownerId,expectedDataEpoch,now,deletions}){\r\n ownerId=owner(ownerId);expectedDataEpoch=safeEpoch(expectedDataEpoch);now=safeTime(now);\r\n if(expectedDataEpoch===Number.MAX_SAFE_INTEGER)fail('epoch-overflow');\r\n if(!Array.isArray(deletions))fail('invalid-deletions');\r\n const observed=await inspectAccountDataEpoch(database,ownerId);\r\n if(expectedDataEpoch>observed.currentDataEpoch)fail('epoch-mismatch');\r\n if(expectedDataEpoch<observed.currentDataEpoch)return {...observed,alreadyDeleted:true};\r\n try{\r\n  await database.batch([\r\n   provision(database,ownerId,now),\r\n   database.prepare('INSERT INTO account_data_deletions(owner_id,deleted_epoch,deleted_at) VALUES(?,(SELECT epoch FROM account_data_epochs WHERE owner_id=? AND epoch=?),?)').bind(ownerId,ownerId,expectedDataEpoch,now),\r\n   database.prepare('UPDATE account_data_epochs SET epoch=epoch+1,updated_at=? WHERE owner_id=? AND epoch=?').bind(now,ownerId,expectedDataEpoch),\r\n   ...deletions,\r\n  ]);\r\n  return {ownerId,currentDataEpoch:expectedDataEpoch+1,deletedThroughEpoch:expectedDataEpoch,alreadyDeleted:false};\r\n }catch(error){\r\n  const current=await inspectAccountDataEpoch(database,ownerId);\r\n  if(current.currentDataEpoch>expectedDataEpoch)return {...current,alreadyDeleted:true};\r\n  if(current.currentDataEpoch<expectedDataEpoch)fail('epoch-mismatch');\r\n  throw error;\r\n }\r\n}\r\n","server/account-readiness.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {remoteReminders,reminderService} from './remote-reminders.mjs';\r\nimport {syncTrainingStatus} from './reminder-plan.mjs';\r\nconst healthKey='readiness:reminders';\r\nexport const trainingReadinessKey=owner=>'readiness:training:'+JSON.stringify(owner);\r\nconst valid=value=>value&&Number.isSafeInteger(value.startedAt)&&value.startedAt>=0&&typeof value.observationId==='string'&&['ready','unavailable'].includes(value.state);\r\nconst validPush=push=>push&&typeof push.configured==='boolean'&&typeof push.schedulerActive==='boolean'&&(push.publicKey===null||typeof push.publicKey==='string');\r\nasync function read(database,key){\r\n const row=await database.prepare('SELECT value FROM system WHERE key=?').bind(key).first();\r\n try{const value=JSON.parse(row?.value??'null');return valid(value)?value:null;}catch{return null;}\r\n}\r\n// Cache access is optional; only these cache keys are allowed to fail open.\r\nconst optionalRead=async(database,key)=>{try{return await read(database,key);}catch{return null;}};\r\nfunction write(database,key,value){\r\n return database.prepare(\"INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value WHERE CASE WHEN json_valid(system.value)=0 THEN 1 WHEN json_type(system.value,'$.startedAt')!='integer' OR json_type(system.value,'$.startedAt') IS NULL OR json_type(system.value,'$.observationId')!='text' OR json_type(system.value,'$.observationId') IS NULL OR json_extract(system.value,'$.startedAt')<0 OR coalesce(json_extract(system.value,'$.state') IN ('ready','unavailable'),0)=0 THEN 1 ELSE json_extract(system.value,'$.startedAt')<json_extract(excluded.value,'$.startedAt') OR (json_extract(system.value,'$.startedAt')=json_extract(excluded.value,'$.startedAt') AND json_extract(system.value,'$.observationId')<json_extract(excluded.value,'$.observationId')) END\").bind(key,JSON.stringify(value));\r\n}\r\nconst view=(value,now)=>value?{...value,state:now-value.startedAt>300000?'stale':value.state}:{state:'unknown',checkedAt:null};\r\nexport async function readAccountReadiness(database,owner,epoch,now=Date.now()){\r\n const [health,training]=await Promise.all([optionalRead(database,healthKey),optionalRead(database,trainingReadinessKey(owner))]);\r\n const safeHealth=health?{...health}:null;if(safeHealth&&!validPush(safeHealth.push))delete safeHealth.push;\r\n return {reminders:view(safeHealth,now),training:view(training?.dataEpoch===epoch?training:null,now)};\r\n}\r\nexport async function refreshReminderHealth(database,env,owner,{now=Date.now(),observationId=crypto.randomUUID()}={}){\r\n let value={startedAt:now,observationId,checkedAt:null,state:'unavailable'};\r\n try{\r\n  const push=await reminderService(env,owner,'/internal/status');if(!validPush(push))throw Error('Invalid reminder health.');\r\n  value={...value,state:'ready',checkedAt:Date.now(),push:{configured:push.configured,publicKey:push.publicKey,schedulerActive:push.schedulerActive}};\r\n }catch{\r\n  const previous=await optionalRead(database,healthKey);\r\n  if(validPush(previous?.push))value={...value,push:previous.push,lastSuccessAt:previous.state==='ready'?previous.checkedAt:previous.lastSuccessAt??null};\r\n }\r\n try{await write(database,healthKey,value).run();}catch{/* Health result remains usable even when its optional cache is unavailable. */}\r\n return value;\r\n}\r\nexport async function refreshTrainingReadiness(database,env,owner,proof,training,{now=Date.now(),observationId=crypto.randomUUID()}={}){\r\n const value={startedAt:now,observationId,checkedAt:null,dataEpoch:proof.currentDataEpoch,state:'unavailable'};\r\n try{\r\n  if(remoteReminders(env))await reminderService(env,owner,'/internal/training-status','POST',training,proof);\r\n  else await syncTrainingStatus(database,owner,training,now,{dataEpoch:proof.currentDataEpoch});\r\n  value.state='ready';value.checkedAt=Date.now();\r\n }catch{\r\n  const previous=await optionalRead(database,trainingReadinessKey(owner));\r\n  if(previous?.dataEpoch===proof.currentDataEpoch)value.lastSuccessAt=previous.state==='ready'?previous.checkedAt:previous.lastSuccessAt??null;\r\n }\r\n // Even a failure observation may never recreate a deleted user's cache.\r\n await epochFencedBatch(database,{ownerId:owner,expectedDataEpoch:proof.currentDataEpoch,now,statements:[write(database,trainingReadinessKey(owner),value)]});\r\n return value;\r\n}\r\nexport function scheduleAccountReadiness(ctx,database,env,owner,proof,training){\r\n if(typeof ctx?.waitUntil!=='function')return;\r\n const now=Date.now();\r\n if(remoteReminders(env))ctx.waitUntil(Promise.resolve().then(()=>refreshReminderHealth(database,env,owner,{now})).catch(()=>{}));\r\n ctx.waitUntil(Promise.resolve().then(()=>refreshTrainingReadiness(database,env,owner,proof,training,{now})).catch(()=>{}));\r\n}\r\n","server/armie-push.mjs":"// Turns a fired D12 Armie letter into a Web Push send, reusing the EXISTING\r\n// push infrastructure (sendPush in server/push.mjs) -- no changes to\r\n// push.mjs. The in-app inbox is the source of truth (D23); this call is only\r\n// the \"you have mail\" nudge, and its failure must never lose the letter (the\r\n// letter is already written to the inbox independently of whether this\r\n// succeeds -- see armie-letters-client.mjs).\r\nimport {sendPush} from './push.mjs';\r\nimport {pickArmieLetter} from '../armie-letters.mjs';\r\n\r\nexport function armiePushPayload(date, letterId) {\r\n const letter = pickArmieLetter(letterId, date);\r\n if (!letter) return null;\r\n return {title: letter.header, body: letter.lines.join(' '), tag: `myr5-armie-${date}-${letterId}`, url: '/pose.html?panel=armie', kind: 'myr5-armie-letter'};\r\n}\r\n\r\nexport async function sendArmieLetterPush(env, sub, date, letterId, options) {\r\n const payload = armiePushPayload(date, letterId);\r\n if (!payload) return null;\r\n return sendPush(env, sub, payload, options);\r\n}\r\n","server/armie-scheduler.mjs":"// D12/D23 catch-up sender: pushes any fired Armie letter to users who have a\r\n// push subscription but haven't opened the app (so nothing called\r\n// combatProgress for them today). Mirrors the shape of runReminders()\r\n// (server/push.mjs).\r\n//\r\n// Runs from server/worker.mjs scheduled() through runArmieLetterPushes (R8),\r\n// which dedups on drizzle/0021 armie_letter_deliveries(user_id, day, letter_id).\r\n// `alreadySent`/`markSent`/`send` stay injectable for tests/armie-scheduler.test.mjs.\r\nimport {dayAt} from '../combat.mjs';\r\nimport {evaluateStreakHistory} from '../streak-forgiveness.mjs';\r\nimport {sendArmieLetterPush} from './armie-push.mjs';\r\nimport {db} from './db.mjs';\r\n\r\nconst staleError = error => ['stale_delivery', 'target_epoch_mismatch'].includes(error?.code);\r\n\r\nexport async function runArmieLetterScheduler(env, database, {now = Date.now(), alreadySent, markSent, send = sendArmieLetterPush} = {}) {\r\n const day = dayAt(now);\r\n // evaluateStreakHistory fires nothing unless today is kept, so only today's users matter (this runs every minute).\r\n const users = (await database.prepare('SELECT DISTINCT user_id FROM login_days WHERE day=?').bind(day).all()).results;\r\n let sent = 0, failed = 0;\r\n for (const {user_id: user} of users) {\r\n  const subs = (await database.prepare('SELECT * FROM subscriptions WHERE user_id=?').bind(user).all()).results;\r\n  if (!subs.length) continue;\r\n  const epochRow = await database.prepare('SELECT epoch FROM account_data_epochs WHERE owner_id=?').bind(user).first();\r\n  const dataEpoch = epochRow?.epoch ?? 1;\r\n  const days = (await database.prepare('SELECT day FROM login_days WHERE user_id=? AND day<=?').bind(user, day).all()).results;\r\n  const history = evaluateStreakHistory(days.map(row => row.day), day);\r\n  for (const dayResult of history) {\r\n   for (const letterId of dayResult.lettersFired) {\r\n    if (await alreadySent(user, dayResult.date, letterId)) continue;\r\n    let delivered = false;\r\n    for (const s of subs) {\r\n     try {\r\n      await send(env, JSON.parse(s.data), dayResult.date, letterId, {ownerId: user, dataEpoch, subscriptionData: s.data, subscriptionCreatedAt: s.created_at});\r\n      delivered = true; sent++;\r\n     } catch (error) { if (!staleError(error)) failed++; }\r\n    }\r\n    if (delivered) await markSent(user, dayResult.date, letterId);\r\n   }\r\n  }\r\n }\r\n return {sent, failed};\r\n}\r\n\r\n// Claims (user, day, letter) before sending, so each letter pushes at most once per user, even across\r\n// overlapping cron runs. ponytail: a failed push is not retried; the in-app inbox still has the letter (D23).\r\nexport async function runArmieLetterPushes(env, {now = Date.now(), send} = {}) {\r\n if (!env.VAPID_PRIVATE_KEY) return {sent: 0, failed: 0, configured: false};\r\n const database = db(env);\r\n const claimedBefore = async (user, day, letterId) => !(await database.prepare('INSERT INTO armie_letter_deliveries(user_id,day,letter_id,sent_at) VALUES(?,?,?,?) ON CONFLICT DO NOTHING').bind(user, day, letterId, now).run()).meta.changes;\r\n return runArmieLetterScheduler(env, database, {now, alreadySent: claimedBefore, markSent: async () => {}, ...(send ? {send} : {})});\r\n}\r\n","server/auth.mjs":"import {verifyToken} from '@clerk/backend';\r\nimport {fail} from './domain.mjs';\r\nexport function authConfig(env){return {enabled:!!(env.CLERK_PUBLISHABLE_KEY&&env.CLERK_JWT_KEY&&env.CLERK_FRONTEND_URL&&env.CLERK_AUTHORIZED_PARTIES),publishableKey:env.CLERK_PUBLISHABLE_KEY||null,frontend:env.CLERK_FRONTEND_URL||null};}\r\nexport async function identity(request,env){\r\n  // A custom-domain Worker receives caller-controlled forwarded headers. When\n  // Clerk is configured, legacy identity requires an explicitly trusted proxy.\n  const trustLegacy=env.LOCAL_PREVIEW===true||env.TRUST_LEGACY_AUTH_HEADERS==='true'||!authConfig(env).enabled;\n  const legacy=trustLegacy?request.headers.get('oai-authenticated-user-id'):null;\n  if(!request.headers.has('Authorization'))return {legacy,clerk:null,email:request.headers.get('oai-authenticated-user-email')||'Your account'};\r\n  if(!authConfig(env).enabled||!/^Bearer \\S+$/.test(request.headers.get('Authorization')))fail('Sign in to Coach again.',401);\r\n  try{\r\n    // Only explicit bearer sessions are accepted here. Browser cookies remain\r\n    // Clerk's responsibility; the app never guesses an identity from an email.\r\n    const parties=env.CLERK_AUTHORIZED_PARTIES.split(',').filter(Boolean);\r\n    const claims=await verifyToken(request.headers.get('Authorization').slice(7),{jwtKey:env.CLERK_JWT_KEY,authorizedParties:parties});\r\n    if(typeof claims.sub!=='string'||!claims.sub.startsWith('user_')||typeof claims.sid!=='string'||!claims.sid.startsWith('sess_')||claims.iss!==env.CLERK_FRONTEND_URL||!parties.includes(claims.azp)||claims.sts==='pending')fail('Sign in to Coach again.',401);\r\n    return {legacy,clerk:claims.sub,email:'Your Mom Inc account'};\r\n  }catch{fail('Sign in to Coach again.',401);}\r\n}\r\nexport async function accountOwner(database,id){\r\n  if(id.clerk){await database.prepare('INSERT INTO account_identities(clerk_id,owner_id,created_at) VALUES(?,?,?) ON CONFLICT(clerk_id) DO NOTHING').bind(id.clerk,'clerk:'+id.clerk,Date.now()).run();return (await database.prepare('SELECT owner_id FROM account_identities WHERE clerk_id=?').bind(id.clerk).first()).owner_id;}\r\n  if(!id.legacy)fail('Sign in to save your progress.',401);return id.legacy;\r\n}\r\nexport async function linkLegacy(database,id){\r\n  if(!id.clerk||!id.legacy)fail('Sign in to both accounts to reconnect your saved Coach.',401);\r\n  // Unique keys make concurrent linking deterministic and prevent two logins\r\n  // from claiming the same Coach. Existing separate accounts are not merged.\r\n  try{await database.prepare('INSERT INTO account_identities(clerk_id,owner_id,created_at) VALUES(?,?,?) ON CONFLICT(clerk_id) DO NOTHING').bind(id.clerk,id.legacy,Date.now()).run();}catch{fail('This Coach is already connected to another login. Continue with ChatGPT to access it.',409);}\r\n  const row=await database.prepare('SELECT owner_id FROM account_identities WHERE clerk_id=?').bind(id.clerk).first();\r\n  if(row?.owner_id!==id.legacy)fail('This login already has a separate Coach. Continue with ChatGPT to keep using your original Coach.',409);\r\n  return {linked:true};\r\n}\r\n","server/cloudflare.mjs":"import worker from './worker.mjs';\r\nimport music from '../audio/music/manifest.json' with {type:'json'};\r\n// Only the published, bounded music files need byte serving; other assets keep their existing route.\r\nconst musicBytes=new Map(Object.values(music.tracks).map(track=>[track.url,track.bytes]));\r\nfunction matchingRangeValidator(value,headers){\r\n if(!value)return true;\r\n if(value.startsWith('\"')||value.startsWith('W/'))return !value.startsWith('W/')&&value===headers.get('etag');\r\n const date=Date.parse(value),modified=Date.parse(headers.get('last-modified'));\r\n return Number.isFinite(date)&&Number.isFinite(modified)&&value===headers.get('last-modified');\r\n}\r\n// Single-range parsing follows scripts/actual-dj-preview.mjs, including suffix and end clamping.\r\nexport async function musicRangeResponse(request,response,size){\r\n if(response.status!==200)return response;\r\n if(!Number.isSafeInteger(size)||size<=0||size>1024*1024)return new Response('Music asset exceeds byte-serving bounds',{status:502});\r\n const reader=response.body?.getReader(),chunks=[];let length=0;\r\n if(reader)try{while(true){const {done,value}=await reader.read();if(done)break;length+=value.byteLength;if(length>size){await reader.cancel();return new Response('Music asset size mismatch',{status:502});}chunks.push(value);}}finally{reader.releaseLock();}\r\n if(length!==size)return new Response('Music asset size mismatch',{status:502});\r\n const bytes=new Uint8Array(size);let offset=0;for(const chunk of chunks){bytes.set(chunk,offset);offset+=chunk.byteLength;}\r\n const headers=new Headers(response.headers);headers.delete('content-encoding');headers.delete('content-range');headers.set('accept-ranges','bytes');headers.set('content-length',String(size));\r\n if(request.method==='HEAD')return new Response(null,{status:200,headers});\r\n const range=request.headers.get('range');\r\n if(!range||!matchingRangeValidator(request.headers.get('if-range'),headers))return new Response(bytes,{headers});\r\n const match=range.match(/^bytes=(\\d*)-(\\d*)$/i);let start,end;\r\n if(match&&(match[1]||match[2])){\r\n  if(match[1]){start=Number(match[1]);end=match[2]?Number(match[2]):size-1;}\r\n  else{const suffix=Number(match[2]);start=suffix>0?Math.max(0,size-suffix):size;end=size-1;}\r\n }\r\n if(!Number.isSafeInteger(start)||!Number.isSafeInteger(end)||start<0||start>=size||end<start){headers.set('content-range',`bytes */${size}`);headers.set('content-length','0');return new Response(null,{status:416,headers});}\r\n end=Math.min(end,size-1);headers.set('content-range',`bytes ${start}-${end}/${size}`);headers.set('content-length',String(end-start+1));\r\n return new Response(bytes.subarray(start,end+1),{status:206,headers});\r\n}\r\n// Public Cloudflare Workers entry (the build bundles this, not worker.mjs).\r\n// OpenAI Sites injected oai-authenticated-user-* after its own ChatGPT sign-in; on a\r\n// public Worker any caller can send them, so trusting them is account takeover.\r\n// They are dropped here, leaving identity to a verified Clerk bearer token (auth.mjs).\r\n// Tests and the local dev server (Sites mock sign-in) still call worker.mjs directly.\r\nexport default {\r\n ...worker,\r\n async fetch(request,env,ctx){\r\n  const headers=new Headers(request.headers);\r\n  for(const name of [...headers.keys()])if(name.startsWith('oai-authenticated-user-'))headers.delete(name);\r\n  const clean=new Request(request,{headers}),size=musicBytes.get(new URL(request.url).pathname);\r\n  if(size&&env.ASSETS&&['GET','HEAD'].includes(request.method)){\r\n   // ASSETS is an in-process binding, so this does not re-enter the public Worker route.\r\n   // Fetch the complete representation for slicing, never a conditional or partial response.\r\n   for(const name of ['range','if-range','if-none-match','if-modified-since','if-match','if-unmodified-since'])headers.delete(name);\r\n   headers.set('accept-encoding','identity');\r\n   return musicRangeResponse(clean,await env.ASSETS.fetch(new Request(request,{method:'GET',headers})),size);\r\n  }\r\n  return worker.fetch(clean,env,ctx);\r\n },\r\n};\r\n","server/coach-army-epochs.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nexport function coachEpoch(value=1){\r\n if(!Number.isSafeInteger(value)||value<1)throw Object.assign(Error('Invalid Coach Army generation.'),{status:422,code:'invalid_account_epoch'});\r\n return value;\r\n}\r\nexport function coachConflict(){throw Object.assign(Error('Coach Army state changed. Refresh before retrying.'),{status:409,code:'coach_army_conflict'});}\r\n// Each predicate is fixed SQL supplied by the owning helper, never request SQL.\r\nexport const requireCoachRow=(db,owner,select,values)=>db.prepare(`UPDATE account_data_epochs SET epoch=CASE WHEN EXISTS(${select}) THEN epoch ELSE NULL END WHERE owner_id=?`).bind(...values,owner);\r\nexport async function coachBatch(db,owner,epoch,now,statements){\r\n try{return await epochFencedBatch(db,{ownerId:owner,expectedDataEpoch:coachEpoch(epoch),now,statements});}\r\n catch(error){if(error.code==='target_epoch_mismatch')throw Object.assign(error,{status:409});throw error;}\r\n}\r\n","server/coach-army-runs.mjs":"import {fail} from './domain.mjs';\r\nimport {coachEpoch,coachBatch,coachConflict,requireCoachRow} from './coach-army-epochs.mjs';\r\nexport const COACH_ARMY_STAGES=['djscratch','goon','lilboyfriend','corgi','hand','armie'];\r\nconst eventId=value=>typeof value==='string'&&/^[A-Za-z0-9._:-]{1,200}$/.test(value);\r\nasync function safe(db,run){const events=(await db.prepare('SELECT stage FROM coach_army_run_events WHERE run_id=? ORDER BY sequence').bind(run.id).all()).results;return {id:run.id,targetAccountId:run.account_id,dataEpoch:run.data_epoch,startedAt:run.started_at,completedAt:run.completed_at,completed:run.completed_at!=null,stages:events.map(e=>e.stage)};}\r\nasync function row(db,id,owner){const run=await db.prepare('SELECT * FROM coach_army_runs WHERE id=? AND account_id=?').bind(id,owner).first();if(!run)fail('Coach Army run not found.',404);return run;}\r\nexport async function startCoachArmyRun(db,owner,now=Date.now(),{dataEpoch=1}={}){\r\n const epoch=coachEpoch(dataEpoch),id=crypto.randomUUID();await coachBatch(db,owner,epoch,now,[db.prepare('INSERT INTO coach_army_runs(id,account_id,started_at,updated_at,data_epoch) VALUES(?,?,?,?,?)').bind(id,owner,now,now,epoch)]);return safe(db,await row(db,id,owner));\r\n}\r\nexport async function readCoachArmyRun(db,id,owner){return safe(db,await row(db,id,owner));}\r\nfunction assertOrigin(run,dataEpoch){if(dataEpoch!==undefined&&coachEpoch(dataEpoch)!==run.data_epoch)coachConflict();}\r\nfunction eventStatements(db,run,event,now){\r\n const {eventId:id,sequence,stage,source}=event,owner=run.account_id,epoch=run.data_epoch;\r\n const statements=[\r\n  requireCoachRow(db,owner,'SELECT 1 FROM coach_army_runs WHERE id=? AND account_id=? AND data_epoch=? AND completed_at IS NULL',[run.id,owner,epoch]),\r\n  requireCoachRow(db,owner,'SELECT 1 WHERE (SELECT COALESCE(MAX(sequence),0) FROM coach_army_run_events WHERE run_id=?)=?',[run.id,sequence-1]),\r\n  db.prepare('INSERT INTO coach_army_run_events(event_id,run_id,account_id,sequence,stage,source,received_at,data_epoch) VALUES(?,?,?,?,?,?,?,?)').bind(id,run.id,owner,sequence,stage,source,now,epoch),\r\n  db.prepare('UPDATE coach_army_runs SET updated_at=? WHERE id=?').bind(now,run.id)\r\n ];\r\n if(source==='verifier'&&stage==='armie'){\r\n  statements.push(requireCoachRow(db,owner,\"SELECT 1 WHERE (SELECT count(*) FROM coach_army_run_events WHERE run_id=? AND source='verifier' AND data_epoch=?)=6\",[run.id,epoch]));\r\n  const completionId=`coach-army-run:${run.id}`;\r\n  statements.push(db.prepare('UPDATE coach_army_runs SET completed_at=?,completion_event_id=?,updated_at=? WHERE id=?').bind(now,completionId,now,run.id));\r\n  statements.push(db.prepare(\"INSERT INTO coach_army_completion_outbox(event_id,run_id,account_id,completed_at,status,updated_at,data_epoch) VALUES(?,?,?,?,'pending',?,?)\").bind(completionId,run.id,owner,now,now,epoch));\r\n }\r\n return statements;\r\n}\r\nasync function writeEvent(db,event,now){\r\n const {runId,accountId,eventId:id,sequence,stage,source,dataEpoch}=event;\r\n if(!eventId(id)||!Number.isSafeInteger(sequence)||sequence<1||stage!==COACH_ARMY_STAGES[sequence-1]||!['browser','verifier'].includes(source))fail('Invalid Coach Army progress event.',409);\r\n const run=await row(db,runId,accountId);assertOrigin(run,dataEpoch);\r\n async function replay(){\r\n  const old=await db.prepare('SELECT * FROM coach_army_run_events WHERE event_id=?').bind(id).first();\r\n  if(!old)return false;\r\n  if(old.run_id!==runId||old.account_id!==accountId||old.sequence!==sequence||old.stage!==stage||old.source!==source||old.data_epoch!==run.data_epoch)coachConflict();\r\n  await coachBatch(db,accountId,run.data_epoch,now,[]);return true;\r\n }\r\n if(await replay())return {run:await safe(db,run),replay:true};\r\n if(run.completed_at!=null)coachConflict();\r\n const previous=await db.prepare('SELECT COALESCE(MAX(sequence),0) AS n FROM coach_army_run_events WHERE run_id=?').bind(runId).first();\r\n if(sequence!==previous.n+1)fail('Coach Army progress is out of order.',409);\r\n try{await coachBatch(db,accountId,run.data_epoch,now,eventStatements(db,run,event,now));}\r\n catch(error){if(error.code==='target_epoch_mismatch')throw error;if(await replay())return {run:await readCoachArmyRun(db,runId,accountId),replay:true};coachConflict();}\r\n return {run:await readCoachArmyRun(db,runId,accountId),replay:false,...(source==='browser'?{evidence:'pending_verifier'}:stage==='armie'?{outbox:'pending'}:{})};\r\n}\r\nexport const recordBrowserCoachArmyEvent=(db,input,owner,now)=>writeEvent(db,{...input,accountId:owner,source:'browser'},now);\r\n// An omitted external producer epoch denotes legacy epoch 1, never the run's new generation.\r\nexport const recordVerifiedCoachArmyEvent=(db,input,now)=>writeEvent(db,{...input,dataEpoch:coachEpoch(input.dataEpoch),source:'verifier'},now);\r\n\r\nconst DJ_SEQUENCE=Object.freeze([['bass',8],['treble',3],['volume',7],['tempo',9]]);\r\nconst challengeView=(c,run)=>({id:c.id,expiresAt:c.expires_at,nextStep:c.next_step,targetAccountId:run.account_id,dataEpoch:run.data_epoch,steps:DJ_SEQUENCE.map(([key,value])=>({key,value}))});\r\nexport async function startDjscratchChallenge(db,runId,owner,now=Date.now(),{dataEpoch}={}){\r\n const run=await row(db,runId,owner);assertOrigin(run,dataEpoch);if(run.completed_at!=null)coachConflict();\r\n const active=await db.prepare(\"SELECT * FROM coach_army_djscratch_challenges WHERE run_id=? AND account_id=? AND status='active' AND expires_at>? ORDER BY created_at DESC LIMIT 1\").bind(runId,owner,now).first();\r\n if(active){await coachBatch(db,owner,run.data_epoch,now,[]);return challengeView(active,run);}\r\n const id=crypto.randomUUID(),expiresAt=now+600000;\r\n await coachBatch(db,owner,run.data_epoch,now,[\r\n  requireCoachRow(db,owner,'SELECT 1 FROM coach_army_runs WHERE id=? AND account_id=? AND data_epoch=? AND completed_at IS NULL',[runId,owner,run.data_epoch]),\r\n  db.prepare(\"UPDATE coach_army_djscratch_challenges SET status='superseded',updated_at=? WHERE run_id=? AND account_id=? AND status='active'\").bind(now,runId,owner),\r\n  db.prepare(\"INSERT INTO coach_army_djscratch_challenges(id,run_id,account_id,expires_at,next_step,status,created_at,updated_at,data_epoch) VALUES(?,?,?,?,0,'active',?,?,?)\").bind(id,runId,owner,expiresAt,now,now,run.data_epoch)\r\n ]);\r\n return challengeView({id,expires_at:expiresAt,next_step:0},run);\r\n}\r\nexport async function recordDjscratchControl(db,{runId,challengeId,key,value,dataEpoch},owner,now=Date.now()){\r\n if(!eventId(challengeId)||!DJ_SEQUENCE.some(([k])=>k===key)||!Number.isSafeInteger(value)||value<0||value>10)fail('Invalid DJ Scratch control evidence.');\r\n const run=await row(db,runId,owner);assertOrigin(run,dataEpoch);\r\n const c=await db.prepare('SELECT * FROM coach_army_djscratch_challenges WHERE id=? AND run_id=? AND account_id=?').bind(challengeId,runId,owner).first();if(!c)fail('DJ Scratch challenge not found.',404);\r\n if(c.data_epoch!==run.data_epoch)coachConflict();\r\n await coachBatch(db,owner,c.data_epoch,now,[]);\r\n if(c.expires_at<=now)fail('DJ Scratch challenge expired.',409);\r\n const answer=(extra)=>readCoachArmyRun(db,runId,owner).then(run=>({run,...extra}));\r\n if(c.status==='completed')return answer({replay:true,accepted:true,complete:true,nextStep:4});\r\n if(c.status!=='active')coachConflict();\r\n const step=c.next_step,[expectedKey,expectedValue]=DJ_SEQUENCE[step]||[];\r\n if(key!==expectedKey||value!==expectedValue){const replay=DJ_SEQUENCE.slice(0,step).some(([k,v])=>k===key&&v===value);return answer({accepted:replay,replay,complete:false,nextStep:step});}\r\n const next=step+1;\r\n const statements=[\r\n  requireCoachRow(db,owner,\"SELECT 1 FROM coach_army_djscratch_challenges WHERE id=? AND account_id=? AND status='active' AND next_step=? AND data_epoch=? AND expires_at>?\",[challengeId,owner,step,c.data_epoch,now]),\r\n  db.prepare(\"UPDATE coach_army_djscratch_challenges SET next_step=?,status=?,completed_at=?,updated_at=? WHERE id=?\").bind(next,next===4?'completed':'active',next===4?now:null,now,challengeId)\r\n ];\r\n if(next===4)statements.push(...eventStatements(db,run,{eventId:`djscratch:${challengeId}`,sequence:1,stage:'djscratch',source:'verifier'},now));\r\n try{await coachBatch(db,owner,c.data_epoch,now,statements);}\r\n catch(error){if(error.code==='target_epoch_mismatch')throw error;const latest=await db.prepare('SELECT next_step,status FROM coach_army_djscratch_challenges WHERE id=?').bind(challengeId).first();if(latest?.next_step>step)return answer({accepted:true,replay:true,complete:latest.status==='completed',nextStep:latest.next_step});coachConflict();}\r\n return answer({accepted:true,replay:false,complete:next===4,nextStep:next});\r\n}\r\nexport async function deliverCoachArmyOutbox(db,env,now=Date.now()){\r\n if(!env.COACH_ARMY_ENTITLEMENT_URL||!env.COACH_ARMY_ENTITLEMENT_TOKEN)return {attempted:0,delivered:0,configured:false};\r\n const rows=(await db.prepare(\"SELECT * FROM coach_army_completion_outbox WHERE status='pending' ORDER BY updated_at LIMIT 25\").all()).results;\r\n let delivered=0;\r\n for(const item of rows){\r\n  try{\r\n   await coachBatch(db,item.account_id,item.data_epoch,now,[]);\r\n   const response=await fetch(env.COACH_ARMY_ENTITLEMENT_URL,{method:'POST',redirect:'error',signal:AbortSignal.timeout(5000),headers:{'Content-Type':'application/json','Authorization':`Bearer ${env.COACH_ARMY_ENTITLEMENT_TOKEN}`},body:JSON.stringify({eventType:'coach_army.completed',eventId:item.event_id,accountId:item.account_id,completedAt:item.completed_at,dataEpoch:item.data_epoch})});\r\n   if(!response.ok)throw Error(`Entitlement receiver returned ${response.status}.`);\r\n   const ack=(await coachBatch(db,item.account_id,item.data_epoch,now,[db.prepare(\"UPDATE coach_army_completion_outbox SET status='delivered',attempts=attempts+1,last_error=NULL,delivered_at=?,updated_at=? WHERE event_id=? AND data_epoch=? AND status='pending'\").bind(now,now,item.event_id,item.data_epoch)]))[0];\r\n   if(ack.meta.changes===1)delivered++;\r\n  }catch(error){\r\n   if(error.code==='target_epoch_mismatch')continue;\r\n   try{await coachBatch(db,item.account_id,item.data_epoch,now,[db.prepare('UPDATE coach_army_completion_outbox SET attempts=attempts+1,last_error=?,updated_at=? WHERE event_id=? AND data_epoch=?').bind('Delivery failed; retry pending.',now,item.event_id,item.data_epoch)]);}\r\n   catch(ackError){if(ackError.code!=='target_epoch_mismatch')throw ackError;}\r\n  }\r\n }\r\n return {attempted:rows.length,delivered,configured:true};\r\n}\r\n","server/combat.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {dayAt,DAY_MS,BREATHING_MS} from '../combat.mjs';\r\nimport {evaluateStreakHistory} from '../streak-forgiveness.mjs';\r\nimport {fail,uuid} from './domain.mjs';\r\n\r\nexport async function combatProgress(database,user,now=Date.now(),{recordLogin=true,dataEpoch=1}={}){\r\n const day=dayAt(now);\r\n if(recordLogin)await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('INSERT INTO login_days(user_id,day,logged_at) VALUES(?,?,?) ON CONFLICT(user_id,day) DO NOTHING').bind(user,day,now)]});\r\n // Earlier completed workouts are evidence of a signed-in day. No other\r\n // historical logins are invented when introducing streak tracking.\r\n const days=(await database.prepare(`SELECT day FROM login_days WHERE user_id=? AND day<=? UNION SELECT CAST(completed_at/86400000 AS INTEGER) AS day FROM workouts WHERE user_id=? AND source='server' AND completed_at IS NOT NULL AND completed_at<? ORDER BY day DESC`).bind(user,day,user,(day+1)*DAY_MS).all()).results;\r\n const breathing=await database.prepare('SELECT id FROM breathing_sessions WHERE user_id=? AND completed_at>=? AND completed_at<? LIMIT 1').bind(user,day*DAY_MS,(day+1)*DAY_MS).first();\r\n // D12 forgiveness detail (forgivenWeeksInARow, milestones, fired Armie letter\r\n // ids) comes from the same evaluator combat.mjs loginStreak() uses.\r\n const history=evaluateStreakHistory(days.map(row=>row.day),day);\r\n const latest=history.at(-1)||{streak:0,forgivenWeeksInARow:0,forgivenessAvailableThisWeek:true,auraMilestone:null,lettersFired:[]};\r\n // A letter can fire on a day nothing else called in on (e.g. the day of a\r\n // forgiven miss). pendingLetters carries any fired in the last 35 days so a\r\n // reopen after a gap still delivers them; the inbox dedupes by (date, letter\r\n // id), so re-seeing an already-delivered one here is a no-op.\r\n // ponytail: bounded recompute each call, not a persisted \"already sent\"\r\n // cursor -- fine at this data scale, revisit if per-user history gets huge.\r\n const pendingLetters=history.filter(d=>d.lettersFired.length&&dayAt(Date.parse(d.date))>=day-35).flatMap(d=>d.lettersFired.map(id=>({date:d.date,id})));\r\n return {day,loginStreak:latest.streak,forgivenWeeksInARow:latest.forgivenWeeksInARow,forgivenessAvailableThisWeek:latest.forgivenessAvailableThisWeek,auraMilestone:latest.auraMilestone,lettersFired:latest.lettersFired,pendingLetters,breathingCompleted:!!breathing};\r\n}\r\nexport async function startBreathing(database,user,now=Date.now(),{dataEpoch=1}={}){\r\n const recent=await database.prepare('SELECT id,started_at FROM breathing_sessions WHERE user_id=? AND completed_at IS NULL AND started_at>? ORDER BY started_at DESC LIMIT 1').bind(user,now-5000).first();\r\n if(recent){await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[]});return {id:recent.id,startedAt:recent.started_at,durationMs:BREATHING_MS};}\r\n const id=crypto.randomUUID();\r\n await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('INSERT INTO breathing_sessions(id,user_id,started_at) VALUES(?,?,?)').bind(id,user,now)]});\r\n return {id,startedAt:now,durationMs:BREATHING_MS};\r\n}\r\nexport async function completeBreathing(database,user,value,now=Date.now(),{dataEpoch=1}={}){\r\n const id=uuid(value.id),session=await database.prepare('SELECT * FROM breathing_sessions WHERE id=? AND user_id=?').bind(id,user).first();\r\n if(!session)fail('Breathing session not found.',404);\r\n if(session.completed_at==null){\r\n  const elapsed=now-session.started_at;\r\n  if(elapsed<BREATHING_MS||elapsed>2*60*60*1000||!Number.isFinite(value.activeMs)||value.activeMs<BREATHING_MS||value.activeMs>elapsed+1000)fail('Finish the full three-minute breathing session first.');\r\n\r\n }\r\n await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[\r\n  database.prepare('UPDATE breathing_sessions SET completed_at=? WHERE id=? AND user_id=? AND completed_at IS NULL').bind(now,id,user),\r\n  database.prepare('INSERT INTO login_days(user_id,day,logged_at) VALUES(?,?,?) ON CONFLICT(user_id,day) DO NOTHING').bind(user,dayAt(now),now),\r\n ]});\r\n return combatProgress(database,user,now,{recordLogin:false});\r\n}\r\n","server/db.mjs":"export const db=env=>{if(!env.DB)throw Object.assign(new Error('Account storage is not connected yet.'),{status:503});return env.DB;};\r\n","server/domain.mjs":"import {TONES,CADENCES,scheduledDay} from '../reminder-settings.mjs';\r\nimport {EXERCISES} from '../exercise-library.mjs';\r\nexport const MODES={...Object.fromEntries(Object.values(EXERCISES).map(m=>[m.id,m.kind==='hold'||m.kind==='pace'?[15,20,30,45,60]:[5,10,15,20]])),squat:[5,10,15,20],pushup:[5,10,15,20],tree:[15,20,30,45,60],warrior:[15,20,30,45,60],horse:[15,20,30,45,60],boxing:[30,60,90,120,180],jogging:[20,40,60,100],jumping:[5,10,15,20]};\r\nexport const KINDS={workout:'Time for your workout. Your coach is ready.',meal:'Pause and log your meal.',water:'Time for a water break.',motivation:'A small step counts. Move at your own pace.'};\r\nexport function fail(message,status=400){throw Object.assign(new Error(message),{status});}\r\nexport const cleanText=(v,max=160)=>typeof v==='string'&&v.trim().length&&v.trim().length<=max?v.trim():fail('Please check the highlighted information.');\r\nexport const uuid=v=>typeof v==='string'&&/^[a-f0-9-]{36}$/.test(v)?v:fail('Invalid record.');\r\nexport function nutrition(v,max=20000){if(v==null||v==='')return null;return typeof v==='number'&&Number.isFinite(v)&&v>=0&&v<=max?v:fail('Check the nutrition amounts.');}\r\nexport function mealInput(v){const eatenAt=cleanText(v.eatenAt,40);if(!/^\\d{4}-\\d\\d-\\d\\dT/.test(eatenAt)||!Number.isFinite(Date.parse(eatenAt)))fail('Choose a valid meal time.');if(v.micros!=null&&(typeof v.micros!=='object'||Array.isArray(v.micros)))fail('Invalid micronutrients.');const micros=Object.fromEntries(['calcium','iron','magnesium','potassium','sodium','zinc','vitaminA','vitaminC','vitaminD','vitaminE','vitaminB12','folate'].map(k=>[k,nutrition(v.micros?.[k],2000000)]));return {id:uuid(v.id),name:cleanText(v.name),portion:cleanText(v.portion,120),calories:nutrition(v.calories),protein:nutrition(v.protein),carbs:nutrition(v.carbs),fat:nutrition(v.fat),micros,nutritionSource:v.nutritionSource==null?null:cleanText(v.nutritionSource,120),eatenAt:new Date(eatenAt).toISOString()};}\r\nexport function reminderInput(v){const tone=v.tone??'direct',daysPerWeek=v.daysPerWeek??7;if(!TONES.includes(tone))fail('Choose gentle, direct or cheeky.');if(!CADENCES.includes(daysPerWeek))fail('Choose 1, 3, 5 or 7 reminder days.');if(!Object.hasOwn(KINDS,v.kind))fail('Choose a reminder type.');for(const k of ['time','quietStart','quietEnd'])if(typeof v[k]!=='string'||!/^([01]\\d|2[0-3]):[0-5]\\d$/.test(v[k]))fail('Choose a valid reminder time.');try{new Intl.DateTimeFormat('en',{timeZone:v.timezone}).format();}catch{fail('Choose a valid time zone.');}return {id:uuid(v.id),tone,daysPerWeek,kind:v.kind,time:v.time,timezone:v.timezone,enabled:v.enabled===true?1:0,quietStart:v.quietStart,quietEnd:v.quietEnd};}\r\nexport function localTime(now,timezone){const p=Object.fromEntries(new Intl.DateTimeFormat('en-CA',{timeZone:timezone,year:'numeric',month:'2-digit',day:'2-digit',hour:'2-digit',minute:'2-digit',hourCycle:'h23'}).formatToParts(new Date(now)).map(x=>[x.type,x.value]));return {day:`${p.year}-${p.month}-${p.day}`,time:`${p.hour}:${p.minute}`};}\r\nconst minutes=s=>Number(s.slice(0,2))*60+Number(s.slice(3));\r\nexport function isDue(r,now){if(!r.enabled)return false;const l=localTime(now,r.timezone),a=minutes(r.quiet_start),b=minutes(r.quiet_end),t=minutes(l.time);if(!scheduledDay(l.day,r.days_per_week??7))return false;if(a!==b&&(a<b?t>=a&&t<b:t>=a||t<b))return false;const delta=t-minutes(r.time);return delta>=0&&delta<10?l.day:false;}\r\nexport function progress(count){return {completedSets:count,xp:count*25,level:1+Math.floor(count/4),unlocks:{shieldBreak:count>=196,ember:count>=4,arc:count>=16,frost:count>=36}};}\r\nexport function validateCompletion(w,input,now){const elapsed=(now-w.started_at)/1000,kind=EXERCISES[w.mode]?.kind,min=['hold','pace'].includes(kind)?w.goal:Math.max(2,w.goal*.3);if(elapsed<min||elapsed>7200)fail('This set expired or finished too quickly. Begin a new set.');if(!Number.isFinite(input.value)||input.value<w.goal||input.value>100000)fail('Complete the selected goal first.');if(kind==='pace'&&(!Number.isFinite(input.active)||input.active<w.goal))fail('Hand movement is needed to complete this round.');return true;}\r\n","server/entitlements.mjs":"import {fail} from './domain.mjs';\r\nimport {coachEpoch,coachBatch,coachConflict,requireCoachRow} from './coach-army-epochs.mjs';\r\nconst validId=v=>typeof v==='string'&&v.length>0&&v.length<=200&&v.trim()===v;\r\nfunction validate(event){\r\n if(!event||event.eventType!=='coach_army.completed'||!validId(event.eventId)||!validId(event.accountId)||!Number.isSafeInteger(event.completedAt)||event.completedAt<1)fail('Invalid Coach Army completion event.');\r\n return coachEpoch(event.dataEpoch);\r\n}\r\nfunction completionStatements(db,event,epoch,now){\r\n return [\r\n  db.prepare(`INSERT INTO coach_army_completions(event_id,user_id,completed_at,received_at,data_epoch) VALUES(?,?,?,?,?) ON CONFLICT(event_id) DO UPDATE SET completed_at=CASE WHEN coach_army_completions.user_id=excluded.user_id AND coach_army_completions.completed_at=excluded.completed_at AND coach_army_completions.data_epoch=excluded.data_epoch THEN coach_army_completions.completed_at ELSE NULL END`).bind(event.eventId,event.accountId,event.completedAt,now,epoch),\r\n  db.prepare(`INSERT INTO account_entitlements(user_id,coach_army_status,coach_army_completed_at,coach_army_event_id,updated_at,data_epoch) VALUES(?,'completed',?,?,?,?) ON CONFLICT(user_id) DO UPDATE SET coach_army_status='completed',coach_army_completed_at=MIN(COALESCE(account_entitlements.coach_army_completed_at,excluded.coach_army_completed_at),excluded.coach_army_completed_at),coach_army_event_id=CASE WHEN account_entitlements.coach_army_status='completed' THEN account_entitlements.coach_army_event_id ELSE excluded.coach_army_event_id END,updated_at=excluded.updated_at,data_epoch=excluded.data_epoch`).bind(event.accountId,event.completedAt,event.eventId,now,epoch)\r\n ];\r\n}\r\nasync function completionIdentity(db,event,epoch){\r\n const old=await db.prepare('SELECT * FROM coach_army_completions WHERE event_id=?').bind(event.eventId).first();\r\n if(old&&(old.user_id!==event.accountId||old.completed_at!==event.completedAt||old.data_epoch!==epoch))coachConflict();\r\n}\r\nconst result=(db,owner)=>db.prepare('SELECT coach_army_status AS status,coach_army_completed_at AS completedAt,coach_army_event_id AS eventId,data_epoch AS dataEpoch,user_id AS targetAccountId FROM account_entitlements WHERE user_id=?').bind(owner).first();\r\n// Missing producer epoch is the fixed legacy generation 1, never current-on-arrival.\r\nexport async function recordCoachArmyCompletion(db,event,now=Date.now()){\r\n const epoch=validate(event);await completionIdentity(db,event,epoch);\r\n try{await coachBatch(db,event.accountId,epoch,now,completionStatements(db,event,epoch,now));}\r\n catch(error){await completionIdentity(db,event,epoch);throw error;}\r\n return result(db,event.accountId);\r\n}\r\n\r\nexport async function readEntitlements(database,user){\r\n  const row=await database.prepare('SELECT coach_army_status AS status,coach_army_completed_at AS completedAt,coach_army_event_id AS eventId FROM account_entitlements WHERE user_id=?').bind(user).first();\r\n  const packs=await database.prepare(\"SELECT pack_id AS packId, granted_at AS grantedAt FROM account_pack_entitlements WHERE user_id=? AND status='owned' ORDER BY pack_id\").bind(user).all();\r\n  return {coachArmy:row?.status==='completed'&&Number.isSafeInteger(Number(row.completedAt))?{status:'completed',completedAt:Number(row.completedAt)}:null,ownedPacks:(packs.results||[]).filter(pack=>typeof pack.packId==='string'&&Number.isSafeInteger(Number(pack.grantedAt))).map(pack=>({packId:pack.packId,status:'owned',grantedAt:Number(pack.grantedAt)}))};\r\n}\r\n\r\n\r\nconst randomToken=()=>Array.from(crypto.getRandomValues(new Uint8Array(32)),b=>b.toString(16).padStart(2,'0')).join('');\r\nconst sha256=async value=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(value))),b=>b.toString(16).padStart(2,'0')).join('');\r\nexport async function createCoachArmyBinding(db,{runId,accountId,eventId,completedAt,dataEpoch},now=Date.now()){\r\n const epoch=validate({eventType:'coach_army.completed',accountId,eventId,completedAt,dataEpoch});if(!validId(runId))fail('Invalid Coach Army binding.');\r\n const run=await db.prepare('SELECT completed_at FROM gala_runs WHERE id=?').bind(runId).first();\r\n if(!run?.completed_at||run.completed_at>completedAt)fail('Coach Army run is not authoritatively complete.',409);\r\n const existing=await db.prepare('SELECT * FROM coach_army_bindings WHERE event_id=?').bind(eventId).first();\r\n if(existing){\r\n  if(existing.run_id!==runId||existing.account_id!==accountId||existing.completed_at!==completedAt||existing.data_epoch!==epoch)coachConflict();\r\n  await coachBatch(db,accountId,epoch,now,[]);\r\n  return {bindingId:existing.binding_id,claimToken:null,expiresAt:existing.expires_at,claimed:existing.claimed_at!=null,targetAccountId:accountId,dataEpoch:epoch};\r\n }\r\n const bindingId=crypto.randomUUID(),claimToken=randomToken(),expiresAt=now+300000;\r\n await coachBatch(db,accountId,epoch,now,[\r\n  requireCoachRow(db,accountId,'SELECT 1 FROM gala_runs WHERE id=? AND completed_at IS NOT NULL AND completed_at<=?',[runId,completedAt]),\r\n  db.prepare('INSERT INTO coach_army_bindings(binding_id,run_id,account_id,event_id,claim_hash,completed_at,expires_at,created_at,data_epoch) VALUES(?,?,?,?,?,?,?,?,?)').bind(bindingId,runId,accountId,eventId,await sha256(claimToken),completedAt,expiresAt,now,epoch)\r\n ]);\r\n return {bindingId,claimToken,expiresAt,claimed:false,targetAccountId:accountId,dataEpoch:epoch};\r\n}\r\nexport async function claimCoachArmyBinding(db,{bindingId,claimToken,accountId,dataEpoch},now=Date.now()){\r\n if(!validId(bindingId)||typeof claimToken!=='string'||!validId(accountId))fail('Invalid Coach Army claim.');\r\n const known=await db.prepare('SELECT * FROM coach_army_bindings WHERE binding_id=?').bind(bindingId).first();\r\n if(!known||known.account_id!==accountId)fail('Coach Army binding does not belong to this account.',403);\r\n if(known.claimed_at!=null)fail('Coach Army binding was already claimed.',409);\r\n if(known.expires_at<=now)fail('Coach Army binding expired.',410);\r\n if(known.claim_hash!==await sha256(claimToken))fail('Invalid Coach Army claim.',401);\r\n const epoch=coachEpoch(known.data_epoch);if(dataEpoch!==undefined&&coachEpoch(dataEpoch)!==epoch)coachConflict();\r\n const event={eventType:'coach_army.completed',eventId:known.event_id,accountId,completedAt:known.completed_at,dataEpoch:epoch};\r\n await completionIdentity(db,event,epoch);\r\n await coachBatch(db,accountId,epoch,now,[\r\n  requireCoachRow(db,accountId,'SELECT 1 FROM coach_army_bindings WHERE binding_id=? AND account_id=? AND claim_hash=? AND claimed_at IS NULL AND expires_at>? AND data_epoch=?',[bindingId,accountId,known.claim_hash,now,epoch]),\r\n  db.prepare('UPDATE coach_army_bindings SET claimed_at=? WHERE binding_id=?').bind(now,bindingId),\r\n  ...completionStatements(db,event,epoch,now)\r\n ]);\r\n return result(db,accountId);\r\n}\r\n","server/gala.mjs":"import {fail} from './domain.mjs';\r\nconst checkpoints={djscratch:'dj_at',goon:'gala_at',lilboyfriend:'lil_at',corgi:'corgi_at',hand:'hand_at',armie:'armie_at'};\r\nconst hash=async text=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(text))),b=>b.toString(16).padStart(2,'0')).join('');\r\nconst safe=row=>({id:row.id,startedAt:row.started_at,completedAt:row.completed_at,durationMs:row.duration_ms,installedAt:row.installed_at,joinedAt:row.joined_at,djName:row.dj_name,moniker:row.moniker,completed:Object.entries(checkpoints).filter(([,column])=>row[column]!=null).map(([name])=>name)});\r\nexport function galaName(value){const base=String(value?.base||'').trim(),moniker=String(value?.moniker||'').trim().toUpperCase();if(!/^[A-Z0-9 ]{2,48}$/i.test(base)||!/^[A-Z0-9]{3}$/.test(moniker))fail('Choose a DJ name and a three-character moniker.');return {name:`${base} · ${moniker}`,moniker};}\r\nexport async function galaApi(request,database,readBody){\r\n const url=new URL(request.url),origin=request.headers.get('Origin'),self=url.origin,allowed=origin===self||origin==='https://mominc.online'||origin==='https://www.mominc.online'||(!origin&&request.method==='GET');\r\n const response=(data,status=200)=>new Response(JSON.stringify(data),{status,headers:{'Content-Type':'application/json','Cache-Control':'no-store','X-Content-Type-Options':'nosniff','Vary':'Origin',...(allowed&&origin?{'Access-Control-Allow-Origin':origin,'Access-Control-Allow-Methods':'GET, POST, OPTIONS','Access-Control-Allow-Headers':'Content-Type, Authorization'}:{})}});\r\n try{\r\n  if(request.method==='OPTIONS')return allowed?new Response(null,{status:204,headers:{'Access-Control-Allow-Origin':origin,'Access-Control-Allow-Methods':'GET, POST, OPTIONS','Access-Control-Allow-Headers':'Content-Type, Authorization','Vary':'Origin'}}):response({error:'Open this from MOM Inc.'},403);\r\n  const path=url.pathname,method=request.method,now=Date.now();\r\n  if(path==='/api/gala/install-draft'){\r\n   if((method==='POST'&&origin!==self)||(origin&&origin!==self))fail('Open this from Coach.',403);\r\n   let id,token;\r\n   if(method==='POST'){const data=await readBody(request);id=data.id;token=data.token;}\r\n   else if(method==='GET'){const saved=request.headers.get('Cookie')?.split(';').map(x=>x.trim()).find(x=>x.startsWith('__Host-gala-run='))?.split('=')[1];[id,token]=(saved||'').split('.');if(!saved)return response({data:null});}\r\n   else fail('Action unavailable.',405);\r\n   if(!/^[0-9a-f-]{36}$/.test(id||'')||!/^[a-f0-9]{64}$/.test(token||''))fail('Invalid Gala invitation.');\r\n   const row=await database.prepare('SELECT * FROM gala_runs WHERE id=? AND token_hash=?').bind(id,await hash(token)).first();if(!row)fail('Run not found.',404);\r\n   const result=response({data:{version:1,id,token}});if(method==='POST')result.headers.set('Set-Cookie',`__Host-gala-run=${id}.${token}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=604800`);return result;\r\n  }\r\n  if(path==='/api/gala/leaderboard'&&method==='GET'){\r\n   const rows=await database.prepare('SELECT dj_name AS djName,moniker,duration_ms AS durationMs,joined_at AS joinedAt FROM gala_runs WHERE joined_at IS NOT NULL ORDER BY duration_ms ASC,joined_at ASC LIMIT 100').all();\r\n   return response({items:rows.results.map((row,i)=>({...row,rank:i+1}))});\r\n  }\r\n  if(!allowed)fail('Open this action from MOM Inc or Coach.',403);\r\n  if(path==='/api/gala/runs'&&method==='POST'){\r\n   const creator=await hash(request.headers.get('CF-Connecting-IP')||'local');\r\n   const recent=await database.prepare('SELECT COUNT(*) AS total FROM gala_runs WHERE creator=? AND started_at>?').bind(creator,now-3600000).first();if(recent.total>=12)fail('Please wait before starting another ranked run.',429);\r\n   const id=crypto.randomUUID(),token=Array.from(crypto.getRandomValues(new Uint8Array(32)),b=>b.toString(16).padStart(2,'0')).join('');\r\n   await database.prepare('INSERT INTO gala_runs(id,token_hash,creator,started_at) VALUES(?,?,?,?)').bind(id,await hash(token),creator,now).run();\r\n   return response({id,token,startedAt:now},201);\r\n  }\r\n  const match=path.match(/^\\/api\\/gala\\/runs\\/([0-9a-f-]{36})(?:\\/(checkpoint|install|join|moniker))?$/i);if(!match)fail('Run not found.',404);\r\n  const token=request.headers.get('Authorization')?.replace(/^Bearer /,'');if(!token||!/^[a-f0-9]{64}$/.test(token))fail('Open the run on the device where you started it.',401);\r\n  const row=await database.prepare('SELECT * FROM gala_runs WHERE id=? AND token_hash=?').bind(match[1],await hash(token)).first();if(!row)fail('Run not found.',404);\r\n  if(!match[2]&&method==='GET')return response(safe(row));\r\n  if(method!=='POST')fail('Action unavailable.',405);\r\n  const data=await readBody(request);\r\n  if(match[2]==='checkpoint'){\r\n   if(row.joined_at)return response(safe(row));\r\n   const column=checkpoints[data.stage];if(!column)fail('Unknown run milestone.');\r\n   if(data.stage==='djscratch'){\r\n    const name=galaName(data);if(row.dj_at&&row.dj_name!==name.name)fail('Your DJ identity is already attached to this run.',409);\r\n    await database.prepare('UPDATE gala_runs SET dj_at=COALESCE(dj_at,?),dj_name=?,moniker=? WHERE id=?').bind(now,name.name,name.moniker,row.id).run();\r\n   }else{\r\n    if(data.stage==='armie'&&(!row.dj_at||!row.lil_at||!row.corgi_at||!row.gala_at||!row.hand_at))fail('Finish all four character pages, including the Gala, and your hand before Coach Armie.',409);\r\n    await database.prepare(`UPDATE gala_runs SET ${column}=COALESCE(${column},?) WHERE id=?`).bind(now,row.id).run();\r\n   }\r\n   await database.prepare('UPDATE gala_runs SET completed_at=?,duration_ms=?-started_at WHERE id=? AND completed_at IS NULL AND dj_at IS NOT NULL AND gala_at IS NOT NULL AND lil_at IS NOT NULL AND corgi_at IS NOT NULL AND hand_at IS NOT NULL AND armie_at IS NOT NULL').bind(now,now,row.id).run();\r\n  }else if(match[2]==='moniker'){\r\n   if(!row.dj_at||row.joined_at)fail('Change your moniker before joining the rankings.',409);\r\n   const next=galaName({base:row.dj_name.split(' · ')[0],moniker:data.moniker}),duplicate=await database.prepare('SELECT id FROM gala_runs WHERE public_name=? AND id<>?').bind(next.name.toUpperCase(),row.id).first();\r\n   if(duplicate)fail('That name and moniker are taken. Try another three characters.',409);\r\n   await database.prepare('UPDATE gala_runs SET dj_name=?,moniker=? WHERE id=? AND joined_at IS NULL').bind(next.name,next.moniker,row.id).run();\r\n  }else if(match[2]==='install'){\r\n   if(origin!==self||data.installed!==true)fail('Open the installed MYR5 app to save your run.',403);\r\n   await database.prepare('UPDATE gala_runs SET installed_at=COALESCE(installed_at,?) WHERE id=?').bind(now,row.id).run();\r\n  }else if(match[2]==='join'){\r\n   if(data.confirm!==true)fail('Choose Join the rankings to show your DJ name and time.');\r\n   if(!row.completed_at||!row.installed_at)fail('Complete DJ Scratch, the Gala and Armie, then get the app.',409);\r\n   if(!row.joined_at){\r\n    const nameKey=row.dj_name.toUpperCase(),duplicate=await database.prepare('SELECT id FROM gala_runs WHERE public_name=? AND id<>?').bind(nameKey,row.id).first();\r\n    if(duplicate)fail('That DJ name and moniker are already on the board. This run stays saved on your device.',409);\r\n    try{await database.prepare('UPDATE gala_runs SET joined_at=?,public_name=? WHERE id=? AND joined_at IS NULL').bind(now,nameKey,row.id).run();}catch(error){if(/UNIQUE constraint/i.test(error.message))fail('That DJ name and moniker are already on the board.',409);throw error;}\r\n   }\r\n  }\r\n  return response(safe(await database.prepare('SELECT * FROM gala_runs WHERE id=?').bind(row.id).first()));\r\n }catch(error){if(!error.status)console.error('Gala request failed',error.message);return response({error:error.status?error.message:'The Gala terminal could not connect. Try again.'},error.status||500);}\r\n}\r\n","server/install-draft.mjs":"import {validIncomingCoach} from '../pending-coach.mjs';\r\nimport {fail} from './domain.mjs';\r\nconst COOKIE='__Host-coach-install',LIFETIME=3600000;\r\nconst hash=async value=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(value))),b=>b.toString(16).padStart(2,'0')).join('');\r\nconst tokenFrom=request=>request.headers.get('Cookie')?.split(';').map(v=>v.trim()).find(v=>v.startsWith(COOKIE+'='))?.slice(COOKIE.length+1)||'';\r\nconst cookie=(token,age=3600)=>`${COOKIE}=${token}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age=${age}`;\r\nconst json=(data,header)=>new Response(JSON.stringify(data),{headers:{'Content-Type':'application/json','Cache-Control':'no-store','X-Content-Type-Options':'nosniff',...(header?{'Set-Cookie':header}:{})}});\r\nexport async function installDraft(request,database,readBody,now=Date.now()){\r\n const token=tokenFrom(request),key=/^[a-f0-9]{64}$/.test(token)?await hash(token):null;\r\n if(request.method==='GET'){\r\n  const row=key?await database.prepare('SELECT data FROM install_drafts WHERE token_hash=? AND expires_at>?').bind(key,now).first():null;\r\n  return json({data:row?JSON.parse(row.data):null});\r\n }\r\n if(request.method==='DELETE'){\r\n  if(key)await database.prepare('DELETE FROM install_drafts WHERE token_hash=?').bind(key).run();\r\n  return json({cleared:true},cookie('',0));\r\n }\r\n if(request.method!=='POST')fail('Method not allowed.',405);\r\n const {data}=await readBody(request),raw=JSON.stringify(data);\r\n if(!validIncomingCoach(data))fail('Return to the creature studio and choose your coach again.');\r\n if(new TextEncoder().encode(raw).length>55000)fail('Your saved coach is too large.',413);\r\n const creator=await hash(request.headers.get('CF-Connecting-IP')||'local');\r\n const next=Array.from(crypto.getRandomValues(new Uint8Array(32)),b=>b.toString(16).padStart(2,'0')).join('');\r\n const results=await database.batch([\r\n  database.prepare('DELETE FROM install_drafts WHERE expires_at<=? OR token_hash=?').bind(now,key||''),\r\n  database.prepare('INSERT INTO install_drafts(token_hash,data,creator,expires_at) SELECT ?,?,?,? WHERE (SELECT COUNT(*) FROM install_drafts WHERE creator=?)<20 RETURNING token_hash').bind(await hash(next),raw,creator,now+LIFETIME,creator)\r\n ]);\r\n if(!results[1].results?.length)fail('Please wait before preparing another coach.',429);\r\n // Safari copies first-party cookies into newly installed apps; personal answers stay out of URLs.\r\n return json({ready:true},cookie(next));\r\n}\r\n","server/onboarding.mjs":"import {inspectAccountDataEpoch} from './account-data-epochs.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {validateOnboarding,dailyTargets,calendarDay} from '../onboarding-domain.mjs';\r\nexport async function readOnboarding(database,user,now=Date.now()){\r\n const row=await database.prepare('SELECT data,start_day,completed_at,revision FROM onboarding WHERE user_id=?').bind(user).first();\r\n if(!row)return null;const data=JSON.parse(row.data);return {data,startDay:row.start_day,completedAt:row.completed_at,revision:row.revision,targets:dailyTargets(data.profile,row.start_day,now)};\r\n}\r\nexport async function saveOnboarding(database,user,input,now=Date.now(),{dataEpoch=1}={}){\r\n if(!Number.isSafeInteger(input.revision)||input.revision<0)throw Object.assign(Error('Refresh your coach settings before saving.'),{status:400});\r\n const data=validateOnboarding(input.data),appearance=Object.fromEntries(Object.entries(data.appearance).map(([k,v])=>[k,JSON.stringify(v)])),token=crypto.randomUUID();\r\n const writes=await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[\r\n  database.prepare('INSERT INTO onboarding(user_id,data,start_day,completed_at,updated_at,revision,write_token) SELECT ?,?,?,?,?,1,? WHERE ?=0 OR EXISTS(SELECT 1 FROM onboarding WHERE user_id=?) ON CONFLICT(user_id) DO UPDATE SET data=excluded.data,updated_at=excluded.updated_at,revision=onboarding.revision+1,write_token=excluded.write_token WHERE onboarding.revision=? RETURNING revision').bind(user,JSON.stringify(data),calendarDay(now,data.profile.timezone),now,now,token,input.revision,user,input.revision),\r\n  database.prepare(\"INSERT INTO profiles(user_id,data,revision,updated_at) SELECT ?,?,1,? WHERE EXISTS(SELECT 1 FROM onboarding WHERE user_id=? AND write_token=?) ON CONFLICT(user_id) DO UPDATE SET data=json_patch(profiles.data,excluded.data),revision=profiles.revision+1,updated_at=excluded.updated_at\").bind(user,JSON.stringify(appearance),now,user,token)\r\n ]});\r\n // A stale request writes neither the onboarding row nor its appearance snapshot.\r\n if(!writes[0].results?.length)throw Object.assign(Error('Coach settings changed on another device. Refresh before saving again.'),{status:409});\r\n const onboarding=await readOnboarding(database,user,now);\r\n if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==dataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});\r\n return {onboarding,appearance};\r\n}\r\n","server/performance-progress.mjs":"import {EXERCISES} from '../exercise-library.mjs';\r\nimport {exerciseDifficulty} from '../performance-catalog.mjs';\r\nimport {holdXp,repXp,GENTLE_BLOCK_XP} from '../progression-rules.mjs';\r\nimport {importedPerformanceXp} from '../performance-import-codec.mjs';\r\nimport {validateImportSnapshot} from '../workout-import-codec.mjs';\r\nimport {readPerformanceProgress,recordPerformanceSession,recordDailyActivity,workoutEligibility,choosePerformancePaths} from '../performance-progress.mjs';\r\nimport {CHOOSABLE_TRACKS} from '../performance-catalog.mjs';\r\nimport {inspectAccountDataEpoch} from './account-data-epochs.mjs';\r\n\r\nexport function performanceDay(timestamp,timezone='UTC'){\r\n const parts=new Intl.DateTimeFormat('en-US',{timeZone:timezone,year:'numeric',month:'2-digit',day:'2-digit'}).formatToParts(new Date(timestamp));\r\n return ['year','month','day'].map(type=>parts.find(p=>p.type===type).value).join('-');\r\n}\r\n/** Request-local derivation from authenticated durable records. Client XP,\r\n * claimed ownership, cosmetic level and coach bonuses never authorize rewards. */\r\nexport function deriveAccountPerformance({workouts=[],breathing=[],meals=[],timezone='UTC',paths=[]}={}){\r\n const cache=new Map(),options={owner:'server-derivation',storage:{getItem:k=>cache.get(k)??null,setItem:(k,v)=>cache.set(k,v)}};\r\n if(paths.length)choosePerformancePaths(paths,options);\r\n const activities=[...breathing.filter(b=>Number.isSafeInteger(b.completed_at)).map(b=>({time:b.completed_at,kind:'meditation',id:b.id})),...meals.map(m=>({time:Date.parse(m.eaten_at),kind:'food',id:m.id})).filter(m=>Number.isFinite(m.time)),...workouts.filter(w=>Number.isSafeInteger(w.completed_at)).map(w=>({time:w.completed_at,kind:'workout',row:w}))].sort((a,b)=>a.time-b.time||String(a.id??a.row.id).localeCompare(String(b.id??b.row.id)));\r\n for(const activity of activities){const day=performanceDay(activity.time,timezone);if(activity.kind!=='workout'){recordDailyActivity(activity.kind,{day,id:activity.id},options);continue;}\r\n  const w=activity.row,e=EXERCISES[w.mode];if(!e)continue;\r\n  let record;\r\n  if(w.performance_snapshot){try{const snapshot=validateImportSnapshot(JSON.parse(w.performance_snapshot));if(!snapshot.performance||snapshot.mode!==w.mode||snapshot.clientWorkoutId!==(w.client_workout_id??w.id)||snapshot.value!==w.value||snapshot.activeSeconds!==w.active||snapshot.completedAt!==w.completed_at)continue;const p=snapshot.performance;record={...p,id:w.client_workout_id??w.id,mode:w.mode,value:snapshot.value,activeSeconds:snapshot.activeSeconds,xpBase:importedPerformanceXp(snapshot),day};}catch{continue;}}\r\n  else if(w.source==='server'){\r\n   const difficulty=exerciseDifficulty(w.mode),kind=e.kind==='hold'?'hold':e.kind==='reps'&&e.group!=='cardio'?'reps':'gentle',active=Math.max(0,Math.min(1800,Number(w.active)||0)),value=Math.max(0,Number(w.value)||0);\r\n   let xpBase=kind==='reps'?repXp({difficulty,to:Math.floor(value)}):kind==='gentle'?Math.floor(active/15)*GENTLE_BLOCK_XP:0;\r\n   if(kind==='hold')for(let start=0;start+15<=active;start+=15)xpBase+=holdXp({difficulty,from:start,to:start+15,continuousAtFrom:0});\r\n   record={id:w.id,mode:w.mode,kind,difficulty,value,activeSeconds:active,maxContinuousSeconds:0,perDifficultyContinuous:{},xpBase,day};\r\n  }else continue;\r\n  if(record.xpBase<=0||!workoutEligibility(record.mode,{...options,day,kind:record.kind}).allowed)continue;\r\n  recordPerformanceSession(record,options);\r\n }\r\n return readPerformanceProgress(options);\r\n}\r\nexport async function readAccountPerformance(database,user,timezone){\r\n if(!timezone){const row=await database.prepare('SELECT data FROM onboarding WHERE user_id=?').bind(user).first();try{timezone=JSON.parse(row?.data||'{}').profile?.timezone||'UTC';}catch{timezone='UTC';}}\r\n const epoch=(await inspectAccountDataEpoch(database,user)).currentDataEpoch;\r\n const [workouts,breathing,meals,choice]=await Promise.all([\r\n  database.prepare('SELECT id,mode,source,client_workout_id,value,active,completed_at,performance_snapshot FROM workouts WHERE user_id=? AND completed_at IS NOT NULL ORDER BY completed_at,id').bind(user).all(),\r\n  database.prepare('SELECT id,completed_at FROM breathing_sessions WHERE user_id=? AND completed_at IS NOT NULL').bind(user).all(),\r\n  database.prepare('SELECT id,eaten_at FROM meals WHERE user_id=?').bind(user).all(),\r\n  database.prepare('SELECT paths FROM workout_path_choices WHERE user_id=? AND data_epoch=?').bind(user,epoch).first(),\r\n ]);\r\n let paths=[];if(choice){try{paths=JSON.parse(choice.paths);}catch{}if(!Array.isArray(paths)||paths.length!==2||new Set(paths).size!==2||!paths.every(id=>CHOOSABLE_TRACKS.includes(id)))throw Error('Stored workout path choice is invalid.');}\r\n const performance=deriveAccountPerformance({workouts:workouts.results,breathing:breathing.results,meals:meals.results,timezone,paths});\n const bonus=await database.prepare('SELECT COALESCE(SUM(xp),0) AS xp FROM world_drop_claims WHERE owner=? AND epoch=?').bind(user,epoch).first();\n performance.worldBonusXp=Number(bonus?.xp)||0;performance.totalXp+=performance.worldBonusXp;return performance;\n}\r\n","server/push.mjs":"import {buildPushPayload} from '@block65/webcrypto-web-push';\r\nimport {db} from './db.mjs';\r\nimport {reminderMessage} from '../reminder-settings.mjs';\r\nimport {isDue,fail} from './domain.mjs';\r\nimport {claimNotificationSlot} from './reminder-plan.mjs';\r\nimport {missedTrainingDays,coachReminder} from '../reminder-plan.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nexport function subscriptionInput(v){let url;try{url=new URL(v.endpoint);}catch{fail('Invalid notification subscription.');}const host=url.hostname;if(url.protocol!=='https:'||url.port||url.username||url.password||!(host==='fcm.googleapis.com'||host==='updates.push.services.mozilla.com'||host.endsWith('.push.services.mozilla.com')||host==='web.push.apple.com'||host.endsWith('.notify.windows.com')))fail('This notification provider is not supported.');for(const [k,size] of [['p256dh',87],['auth',22]])if(typeof v.keys?.[k]!=='string'||!new RegExp(`^[A-Za-z0-9_-]{${size}}={0,2}$`).test(v.keys[k]))fail('Invalid notification keys.');return {endpoint:url.href,keys:v.keys,expirationTime:null};}\r\nconst stale=()=>Object.assign(Error('Notification generation changed.'),{code:'stale_delivery',status:409});\r\nconst staleError=error=>['stale_delivery','target_epoch_mismatch'].includes(error?.code);\r\nexport async function sendPush(env,sub,message,{ttl=600,ownerId,dataEpoch,subscriptionData,subscriptionCreatedAt}={}){\r\n if(typeof ownerId!=='string'||!ownerId||!Number.isSafeInteger(dataEpoch)||dataEpoch<1||typeof subscriptionData!=='string'||!Number.isSafeInteger(subscriptionCreatedAt)||subscriptionCreatedAt<0)throw stale();\r\n const database=db(env),payload=await buildPushPayload({data:JSON.stringify(message),options:{ttl}},sub,{subject:env.VAPID_SUBJECT,publicKey:env.VAPID_PUBLIC_KEY,privateKey:env.VAPID_PRIVATE_KEY});\r\n const current=await database.prepare('SELECT s.endpoint FROM subscriptions s LEFT JOIN account_data_epochs e ON e.owner_id=s.user_id WHERE s.endpoint=? AND s.user_id=? AND s.data=? AND s.created_at=? AND COALESCE(e.epoch,1)=?').bind(sub.endpoint,ownerId,subscriptionData,subscriptionCreatedAt,dataEpoch).first();\r\n if(!current)throw stale();\r\n const result=await fetch(sub.endpoint,{...payload,redirect:'manual',signal:AbortSignal.timeout(15000)});\r\n if(result.status===404||result.status===410){\r\n  try{await epochFencedBatch(database,{ownerId,expectedDataEpoch:dataEpoch,now:Date.now(),statements:[database.prepare('DELETE FROM subscriptions WHERE endpoint=? AND user_id=? AND data=? AND created_at=?').bind(sub.endpoint,ownerId,subscriptionData,subscriptionCreatedAt)]});}\r\n  catch(error){if(!staleError(error))throw error;}\r\n }\r\n if(!result.ok)throw Error('Notification service did not accept delivery.');return result.status;\r\n}\r\nexport async function runReminders(env,now=Date.now()){\r\n const database=db(env);await database.prepare(\"INSERT INTO system(key,value) VALUES('scheduler_tick',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value\").bind(String(now)).run();\r\n if(!env.VAPID_PRIVATE_KEY)return {sent:0,configured:false};\r\n const rows=(await database.prepare('SELECT r.*,COALESCE(e.epoch,1) AS data_epoch FROM reminders r LEFT JOIN account_data_epochs e ON e.owner_id=r.user_id WHERE r.enabled=1').all()).results;let sent=0,failed=0;\r\n for(const r of rows){\r\n  const day=isDue(r,now);if(!day)continue;\r\n  const subs=(await database.prepare('SELECT * FROM subscriptions WHERE user_id=?').bind(r.user_id).all()).results;\r\n  if(!subs.length)continue;\r\n  try{if(!await claimNotificationSlot(database,r.user_id,day,r.id,{dataEpoch:r.data_epoch,now,requireReminder:true}))continue;}catch(error){if(staleError(error))continue;throw error;}\r\n  let training=null;try{const status=await database.prepare('SELECT value FROM system WHERE key=?').bind('training:'+r.user_id).first();training=status?JSON.parse(status.value):null;}catch{}\r\n  const message=r.kind==='workout'?coachReminder(missedTrainingDays(training,now,r.days_per_week),r.tone):reminderMessage(r.kind,r.tone);\r\n  const commit=statements=>epochFencedBatch(database,{ownerId:r.user_id,expectedDataEpoch:r.data_epoch,now,statements});\r\n  for(const s of subs){\r\n   let claimed;\r\n   try{\r\n    const results=await commit([database.prepare(\"INSERT INTO deliveries(reminder_id,day,endpoint,status,updated_at) SELECT ?,?,?,'sending',? WHERE EXISTS(SELECT 1 FROM reminders WHERE id=? AND user_id=? AND enabled=1) AND EXISTS(SELECT 1 FROM subscriptions WHERE endpoint=? AND user_id=? AND data=? AND created_at=?) ON CONFLICT(reminder_id,day,endpoint) DO UPDATE SET status='sending',updated_at=excluded.updated_at WHERE deliveries.status!='sent' AND deliveries.updated_at<? RETURNING reminder_id\").bind(r.id,day,s.endpoint,now,r.id,r.user_id,s.endpoint,r.user_id,s.data,s.created_at,now-120000)]);\r\n    claimed=results[0].results?.length>0;\r\n   }catch(error){if(staleError(error))continue;throw error;}\r\n   if(!claimed)continue;\r\n   let deliveryStatus='sent';\r\n   try{await sendPush(env,JSON.parse(s.data),{title:'MOM // POD CHECK',body:message,tag:`${r.id}-${day}`,url:`/pose.html?panel=${r.kind==='meal'?'meals':'reminders'}`,kind:'reminder-'+r.kind},{ownerId:r.user_id,dataEpoch:r.data_epoch,subscriptionData:s.data,subscriptionCreatedAt:s.created_at});sent++;}\r\n   catch(error){if(staleError(error))continue;failed++;deliveryStatus='failed';}\r\n   try{await commit([database.prepare('UPDATE deliveries SET status=?,updated_at=? WHERE reminder_id=? AND day=? AND endpoint=? AND updated_at=? AND EXISTS(SELECT 1 FROM subscriptions WHERE endpoint=? AND user_id=? AND data=? AND created_at=?)').bind(deliveryStatus,now,r.id,day,s.endpoint,now,s.endpoint,r.user_id,s.data,s.created_at)]);}catch(error){if(!staleError(error))throw error;}\r\n  }\r\n }\r\n await database.prepare('DELETE FROM deliveries WHERE updated_at<?').bind(now-35*86400000).run();await database.prepare(\"DELETE FROM system WHERE key LIKE 'notify-budget:%' AND substr(key,-10)<?\").bind(new Date(now-35*86400000).toISOString().slice(0,10)).run();return {sent,failed,configured:true};\r\n}\r\n","server/release-email.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {RELEASE} from '../release-info.mjs';\r\nimport {fail} from './domain.mjs';\r\n\r\nconst DAY=86400000;\r\nconst hash=async value=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(value))),x=>x.toString(16).padStart(2,'0')).join('');\r\nconst token=()=>crypto.randomUUID().replaceAll('-','')+crypto.randomUUID().replaceAll('-','');\r\nconst escape=value=>String(value).replace(/[&<>\"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));\r\nexport const emailConfigured=env=>(!!env.EMAIL?.send||!!env.RESEND_API_KEY)&&/^[^\\s<>@]+@[^\\s<>@]+\\.[^\\s<>@]+$/.test(env.RELEASE_EMAIL_FROM||'')&&/^https:\\/\\//.test(env.RELEASE_ORIGIN||'');\r\nexport function emailInput(value){const email=typeof value==='string'?value.trim().toLowerCase():'';if(email.length>254||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?\\.[a-z]{2,63}$/.test(email))fail('Enter a valid email address.');return email;}\r\nfunction link(env,action,value){return new URL(`/api/updates/${action}?token=${value}`,env.RELEASE_ORIGIN).href;}\r\nasync function mail(env,email,subject,text,html,unsubscribe){\r\n const content={subject,text,html,...(unsubscribe?{headers:{'List-Unsubscribe':`<${unsubscribe}>`,'List-Unsubscribe-Post':'List-Unsubscribe=One-Click'}}:{})};\r\n if(env.EMAIL?.send)return env.EMAIL.send({from:{email:env.RELEASE_EMAIL_FROM,name:'MOM Dispatch'},to:email,...content});\r\n const response=await fetch('https://api.resend.com/emails',{method:'POST',redirect:'manual',signal:AbortSignal.timeout(15000),headers:{'Authorization':`Bearer ${env.RESEND_API_KEY}`,'Content-Type':'application/json','Idempotency-Key':`coach-${await hash(email+subject+text)}`},body:JSON.stringify({from:`MOM Dispatch <${env.RELEASE_EMAIL_FROM}>`,to:[email],...content})});\r\n if(!response.ok)throw new Error('Email provider did not accept the message.');\r\n const result=await response.json();if(!result.id)throw new Error('Email provider returned no message ID.');return {messageId:result.id};\r\n}\r\nexport async function emailSubscription(env,user,method,input={},now=Date.now(),{dataEpoch=1}={}){\r\n const db=env.DB;\r\n const commit=statements=>epochFencedBatch(db,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements});\r\n const first=async statement=>(await commit([statement]))[0].results?.[0]??null;\r\n if(method==='GET'){const row=await db.prepare('SELECT email,enabled,confirmed_at FROM release_subscribers WHERE user_id=?').bind(user).first();return {configured:emailConfigured(env),email:row?.email||null,enabled:!!row?.enabled,confirmedAt:row?.confirmed_at||null};}\r\n if(method==='DELETE'){await commit([db.prepare('DELETE FROM release_subscribers WHERE user_id=?').bind(user),db.prepare('DELETE FROM release_deliveries WHERE user_id=?').bind(user)]);return {enabled:false};}\r\n if(method!=='POST')fail('Method not allowed.',405);\r\n if(!emailConfigured(env))fail('Email delivery is not connected yet. In-app updates are available now.',503);\r\n const email=emailInput(input.email),existing=await db.prepare('SELECT * FROM release_subscribers WHERE user_id=?').bind(user).first();\r\n if(existing?.email===email&&existing.enabled)return {message:'Release emails are already on.',enabled:true};\r\n // Atomic limits survive concurrent requests and apply to both account and destination.\r\n for(const key of [`release-email-user:${user}`,`release-email-address:${await hash(email)}`]){\r\n  const claim=await first(db.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value WHERE CAST(system.value AS INTEGER)<? RETURNING key').bind(key,String(now),now-3600000));\r\n  if(!claim)fail('Please wait an hour before requesting another confirmation email.',429);\r\n }\r\n const hour=Math.floor(now/3600000),global=await first(db.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=CAST(system.value AS INTEGER)+1 WHERE CAST(system.value AS INTEGER)<30 RETURNING value').bind(`release-email-hour:${hour}`,'1'));\r\n if(!global)fail('Email confirmation is busy. Please try again later.',429);\r\n const confirm=token(),unsubscribe=token(),confirmHash=await hash(confirm);\r\n await commit([db.prepare('INSERT INTO release_subscribers(user_id,email,enabled,confirm_hash,expires_at,unsubscribe_token,updated_at,confirmed_at,last_release) VALUES(?,?,0,?,?,?,?,NULL,?) ON CONFLICT(user_id) DO UPDATE SET email=excluded.email,enabled=0,confirm_hash=excluded.confirm_hash,expires_at=excluded.expires_at,unsubscribe_token=excluded.unsubscribe_token,updated_at=excluded.updated_at,confirmed_at=NULL,last_release=excluded.last_release').bind(user,email,confirmHash,now+DAY,unsubscribe,now,RELEASE.id)]);\r\n const current=await db.prepare('SELECT s.user_id FROM release_subscribers s LEFT JOIN account_data_epochs e ON e.owner_id=s.user_id WHERE s.user_id=? AND s.confirm_hash=? AND COALESCE(e.epoch,1)=?').bind(user,confirmHash,dataEpoch).first();if(!current)throw Object.assign(Error('Account generation changed.'),{status:409,code:'target_epoch_mismatch'});\r\n const confirmUrl=link(env,'confirm',confirm),stopUrl=link(env,'unsubscribe',unsubscribe);\r\n try {await mail(env,email,'MOM Dispatch · Confirm your transmission channel',`MOM here. Your training pod is ready to receive transmissions. Confirm your email to hear when a Coach app update is ready:\\n${confirmUrl}\\n\\nThis link expires in 24 hours. If you did not request this, ignore this email.\\nCancel: ${stopUrl}`,`<p>MOM here. Your training pod is ready to receive transmissions. Confirm your email to hear when a Coach app update is ready.</p><p><a href=\"${escape(confirmUrl)}\">Confirm update emails</a></p><p>This link expires in 24 hours. If you did not request this, ignore this email.</p><p><a href=\"${escape(stopUrl)}\">Cancel</a></p>`,stopUrl);}\r\n catch{try{await commit([db.prepare('DELETE FROM release_subscribers WHERE user_id=? AND confirm_hash=?').bind(user,confirmHash)]);}catch(error){if(error.code!=='target_epoch_mismatch')throw error;}fail('The confirmation email could not be sent. Please try again later.',503);}\r\n return {message:'Check your inbox and confirm your email. Release emails stay off until you confirm.',enabled:false};\r\n}\r\nexport async function emailLinkAction(env,action,value,now=Date.now()){\r\n if(!/^[a-f0-9]{64}$/.test(value||''))fail('This email link is invalid.',400);\r\n if(action==='unsubscribe'){await env.DB.prepare('DELETE FROM release_subscribers WHERE unsubscribe_token=?').bind(value).run();return {message:'Update emails are off. You can close this page.'};}\r\n if(action!=='confirm')fail('Not found.',404);\r\n const row=await env.DB.prepare('UPDATE release_subscribers SET enabled=1,confirmed_at=?,confirm_hash=NULL,expires_at=NULL,updated_at=?,last_release=? WHERE confirm_hash=? AND expires_at>? RETURNING user_id').bind(now,now,RELEASE.id,await hash(value),now).first();\r\n if(!row)fail('This confirmation link has expired or was already used. Open Coach to request another.',410);\r\n return {message:'Your email is confirmed. We’ll email you when a new app update is ready.'};\r\n}\r\nexport function emailLinkPage(action,value,message){\r\n const valid=/^[a-f0-9]{64}$/.test(value||''),title=action==='confirm'?'Confirm app update emails':'Stop app update emails';\r\n const form=valid&&!message?`<form method=\"post\"><button>${action==='confirm'?'Confirm email':'Stop update emails'}</button></form>`:'';\r\n return new Response(`<!doctype html><html lang=\"en\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><title>${title} · MYR5 Coach</title><style>body{font:18px system-ui;max-width:36rem;margin:12vh auto;padding:24px;background:#f5f3eb;color:#252820}button,a{font:inherit}button{padding:14px 22px;border:0;border-radius:12px;background:#304c32;color:white;cursor:pointer}a{color:#304c32}</style><h1>${title}</h1><p>${escape(message||(valid?'Choose below to save your email preference.':'This email link is invalid.'))}</p>${form}<p><a href=\"/pose.html?panel=install\">Open Coach</a></p></html>`,{status:valid?200:400,headers:{'Content-Type':'text/html; charset=utf-8','Cache-Control':'no-store','Referrer-Policy':'no-referrer','X-Content-Type-Options':'nosniff','Content-Security-Policy':\"default-src 'none'; style-src 'unsafe-inline'; form-action 'self'; base-uri 'none'; frame-ancestors 'none'\"}});\r\n}\r\nexport async function runReleaseEmails(env,now=Date.now()){\r\n if(!emailConfigured(env))return {configured:false,sent:0,failed:0};\r\n // Deploying the sender ahead of the app must never announce an unpublished build.\r\n const live=await fetch(new URL('/api/releases/current',env.RELEASE_ORIGIN),{redirect:'manual',signal:AbortSignal.timeout(10000),headers:{'Cache-Control':'no-cache'}});\r\n if(!live.ok||(await live.json()).id!==RELEASE.id)return {sent:0,failed:0,waitingForPublication:true};\r\n const rows=(await env.DB.prepare('SELECT s.*,COALESCE(e.epoch,1) AS data_epoch FROM release_subscribers s LEFT JOIN account_data_epochs e ON e.owner_id=s.user_id WHERE enabled=1 AND confirmed_at IS NOT NULL AND (last_release IS NULL OR last_release!=?) AND NOT EXISTS (SELECT 1 FROM release_deliveries d WHERE d.user_id=s.user_id AND d.release_id=?) LIMIT 10').bind(RELEASE.id,RELEASE.id).all()).results;\r\n let sent=0,failed=0;\r\n for(const row of rows){\r\n  const commit=statements=>epochFencedBatch(env.DB,{ownerId:row.user_id,expectedDataEpoch:row.data_epoch,now,statements});\r\n  let claim;\r\n  try{claim=(await commit([env.DB.prepare(\"INSERT INTO release_deliveries(user_id,release_id,status,updated_at) SELECT user_id,?,'claimed',? FROM release_subscribers WHERE user_id=? AND enabled=1 AND unsubscribe_token=? ON CONFLICT(user_id,release_id) DO NOTHING RETURNING user_id\").bind(RELEASE.id,now,row.user_id,row.unsubscribe_token)]))[0].results?.[0];}\r\n  catch(error){if(error.code==='target_epoch_mismatch')continue;throw error;}\r\n  if(!claim)continue;\r\n  const current=await env.DB.prepare('SELECT s.email FROM release_subscribers s LEFT JOIN account_data_epochs e ON e.owner_id=s.user_id WHERE s.user_id=? AND s.enabled=1 AND s.unsubscribe_token=? AND COALESCE(e.epoch,1)=?').bind(row.user_id,row.unsubscribe_token,row.data_epoch).first();\r\n  if(!current)continue;\r\n  const stopUrl=link(env,'unsubscribe',row.unsubscribe_token),appUrl=new URL('/pose.html?panel=install',env.RELEASE_ORIGIN).href;\r\n  let deliveryStatus='sent';\r\n  try {\r\n   await mail(env,row.email,`MOM Dispatch · Your training pod has an upgrade`,`TRANSMISSION FROM MOM\\n\\nYour training pod has an upgrade.\\n${RELEASE.title}\\n\\n${RELEASE.notes.join('\\n')}\\n\\nOpen Coach to update: ${appUrl}\\n\\nYou opened this channel for Coach app updates. Unsubscribe: ${stopUrl}`,`<p>MOM DISPATCH</p><h1>Your training pod has an upgrade.</h1><h2>${escape(RELEASE.title)}</h2><ul>${RELEASE.notes.map(n=>`<li>${escape(n)}</li>`).join('')}</ul><p><a href=\"${escape(appUrl)}\">Open Coach to update</a></p><p>You opened this channel for Coach app updates. <a href=\"${escape(stopUrl)}\">Unsubscribe</a>.</p>`,stopUrl);\r\n   sent++;\r\n  }catch{failed++;deliveryStatus='failed';}\r\n  const updates=[env.DB.prepare('UPDATE release_deliveries SET status=?,updated_at=? WHERE user_id=? AND release_id=? AND updated_at=? AND EXISTS(SELECT 1 FROM release_subscribers WHERE user_id=? AND unsubscribe_token=?)').bind(deliveryStatus,now,row.user_id,RELEASE.id,now,row.user_id,row.unsubscribe_token)];\r\n  if(deliveryStatus==='sent')updates.push(env.DB.prepare('UPDATE release_subscribers SET last_release=? WHERE user_id=? AND unsubscribe_token=?').bind(RELEASE.id,row.user_id,row.unsubscribe_token));\r\n  try{await commit(updates);}catch(error){if(error.code!=='target_epoch_mismatch')throw error;}\r\n }\r\n // Delivery claims are retained after uncertain sends so the next tick cannot duplicate mail.\r\n await env.DB.batch([env.DB.prepare('DELETE FROM release_subscribers WHERE enabled=0 AND updated_at<?').bind(now-7*DAY),env.DB.prepare(\"DELETE FROM system WHERE key LIKE 'release-email-%' AND ((key LIKE 'release-email-hour:%' AND CAST(substr(key,20) AS INTEGER)<?) OR (key NOT LIKE 'release-email-hour:%' AND CAST(value AS INTEGER)<?))\").bind(Math.floor((now-2*DAY)/3600000),now-2*DAY)]);\r\n return {configured:true,sent,failed};\r\n}\r\n","server/release-push.mjs":"import {db} from './db.mjs';\r\nimport {sendPush} from './push.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nconst stale=error=>['target_epoch_mismatch','stale_delivery'].includes(error?.code);\r\nexport async function runReleasePush(env,now=Date.now(),published=null){ // published: the main Worker passes RELEASE (a Worker can't fetch its own custom domain)\r\n if(!env.RELEASE_ORIGIN||!env.VAPID_PUBLIC_KEY||!env.VAPID_PRIVATE_KEY)return {sent:0,failed:0,configured:false};\r\n const startedAt=Date.now(),origin=new URL(env.RELEASE_ORIGIN);\r\n if(origin.protocol!=='https:'||origin.username||origin.password)throw Error('Invalid release origin.');\r\n let release=published;\r\n if(!release){const response=await fetch(new URL('/api/releases/current',origin).href,{redirect:'manual',cache:'no-store',signal:AbortSignal.timeout(15000)});\r\n if(!response.ok)throw Error('Could not check the published Coach release.');\r\n release=await response.json();}if(typeof release?.id!=='string'||!/^[-a-zA-Z0-9_.]{1,200}$/.test(release.id)||typeof release.title!=='string'||!release.title.trim())throw Error('Invalid published Coach release.');\r\n const database=db(env),retryBefore=now-120000;\r\n const rows=(await database.prepare(\"SELECT s.endpoint,s.user_id,s.data,s.created_at,COALESCE(e.epoch,1) AS data_epoch FROM subscriptions s LEFT JOIN account_data_epochs e ON e.owner_id=s.user_id LEFT JOIN release_push_deliveries d ON d.endpoint=s.endpoint AND d.release_id=? WHERE d.endpoint IS NULL OR (d.status!='sent' AND d.updated_at<?) ORDER BY s.created_at,s.endpoint LIMIT 50\").bind(release.id,retryBefore).all()).results;\r\n let sent=0,failed=0;\r\n for(const row of rows){\r\n  const claimAt=now+Date.now()-startedAt,commit=statements=>epochFencedBatch(database,{ownerId:row.user_id,expectedDataEpoch:row.data_epoch,now:claimAt,statements});\r\n  let claim;\r\n  try{claim=(await commit([database.prepare(\"INSERT INTO release_push_deliveries(endpoint,release_id,status,updated_at) SELECT endpoint,?,'sending',? FROM subscriptions WHERE endpoint=? AND user_id=? AND data=? AND created_at=? ON CONFLICT(endpoint,release_id) DO UPDATE SET status='sending',updated_at=excluded.updated_at WHERE release_push_deliveries.status!='sent' AND release_push_deliveries.updated_at<? RETURNING endpoint\").bind(release.id,claimAt,row.endpoint,row.user_id,row.data,row.created_at,claimAt-120000)]))[0].results?.[0];}\r\n  catch(error){if(stale(error))continue;throw error;}\r\n  if(!claim)continue;\r\n  let deliveryStatus='sent';\r\n  try{\r\n   await sendPush(env,JSON.parse(row.data),{kind:'app-update',title:'Coach update ready to download',body:'A new version of MYR5 Coach is ready. Tap to download the update.',tag:'myr5-update-'+release.id,url:'/pose.html?panel=install&update='+encodeURIComponent(release.id)},{ttl:86400,ownerId:row.user_id,dataEpoch:row.data_epoch,subscriptionData:row.data,subscriptionCreatedAt:row.created_at});sent++;\r\n  }catch(error){if(stale(error))continue;failed++;deliveryStatus='failed';}\r\n  try{await commit([database.prepare('UPDATE release_push_deliveries SET status=?,updated_at=? WHERE endpoint=? AND release_id=? AND updated_at=? AND EXISTS(SELECT 1 FROM subscriptions WHERE endpoint=? AND user_id=? AND data=? AND created_at=?)').bind(deliveryStatus,claimAt,row.endpoint,release.id,claimAt,row.endpoint,row.user_id,row.data,row.created_at)]);}\r\n  catch(error){if(!stale(error))throw error;}\r\n }\r\n await database.prepare('DELETE FROM release_push_deliveries WHERE release_id!=? AND updated_at<?').bind(release.id,now-90*86400000).run();\r\n const result={sent,failed,configured:true,releaseId:release.id};await database.prepare(\"INSERT INTO system(key,value) VALUES('release_push_tick',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value\").bind(JSON.stringify({...result,checkedAt:now})).run();return result;\r\n}\r\n","server/reminder-plan.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {reminderInput,fail} from './domain.mjs';\r\nexport async function readCoachPlan(database,user){const row=await database.prepare('SELECT value FROM system WHERE key=?').bind('coach-plan:'+user).first();if(!row)return {enabled:false,count:3,times:['09:00','14:00','19:00'],tone:'cheeky',ids:[]};try{return JSON.parse(row.value);}catch{return {enabled:false,count:3,times:['09:00','14:00','19:00'],tone:'cheeky',ids:[]};}}\r\nexport async function saveCoachPlan(database,user,input,{dataEpoch=1}={}){\r\n if(!Number.isInteger(input.count)||input.count<1||input.count>3||!Array.isArray(input.times)||input.times.length!==input.count||new Set(input.times).size!==input.count)fail('Choose one to three different reminder times.');\r\n const prior=await readCoachPlan(database,user),ids=Array.from({length:input.count},(_,i)=>prior.ids?.[i]||crypto.randomUUID());\r\n const rows=input.times.map((time,index)=>reminderInput({id:ids[index],kind:'workout',time,timezone:input.timezone,enabled:input.enabled===true,quietStart:input.quietStart||'22:00',quietEnd:input.quietEnd||'07:00',tone:input.tone||'cheeky',daysPerWeek:input.daysPerWeek??7}));\r\n const plan={enabled:input.enabled===true,count:rows.length,times:rows.map(r=>r.time),timezone:rows[0].timezone,quietStart:rows[0].quietStart,quietEnd:rows[0].quietEnd,tone:rows[0].tone,daysPerWeek:rows[0].daysPerWeek,ids};\r\n const statements=(prior.ids||[]).filter(id=>!ids.includes(id)).map(id=>database.prepare('DELETE FROM reminders WHERE id=? AND user_id=?').bind(id,user));\r\n for(const r of rows)statements.push(database.prepare('INSERT INTO reminders(id,user_id,kind,time,timezone,enabled,quiet_start,quiet_end,tone,days_per_week) VALUES(?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO UPDATE SET time=excluded.time,timezone=excluded.timezone,enabled=excluded.enabled,quiet_start=excluded.quiet_start,quiet_end=excluded.quiet_end,tone=excluded.tone,days_per_week=excluded.days_per_week WHERE reminders.user_id=excluded.user_id').bind(r.id,user,r.kind,r.time,r.timezone,r.enabled,r.quietStart,r.quietEnd,r.tone,r.daysPerWeek));\r\n statements.push(database.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value').bind('coach-plan:'+user,JSON.stringify(plan)));await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now:Date.now(),statements});return plan;\r\n}\r\nexport async function syncTrainingStatus(database,user,input,now=Date.now(),{dataEpoch=1}={}){\r\n const today=Math.floor(now/86400000);if(!Number.isSafeInteger(input.startedDay)||input.startedDay<0||input.startedDay>today||(input.lastCompletedDay!=null&&(!Number.isSafeInteger(input.lastCompletedDay)||input.lastCompletedDay<input.startedDay||input.lastCompletedDay>today)))fail('Invalid training status.');\r\n const statement=database.prepare(\"INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=json_object('startedDay',min(json_extract(system.value,'$.startedDay'),json_extract(excluded.value,'$.startedDay')),'lastCompletedDay',nullif(max(coalesce(json_extract(system.value,'$.lastCompletedDay'),-1),coalesce(json_extract(excluded.value,'$.lastCompletedDay'),-1)),-1),'syncedAt',max(json_extract(system.value,'$.syncedAt'),json_extract(excluded.value,'$.syncedAt')))\").bind('training:'+user,JSON.stringify({startedDay:input.startedDay,lastCompletedDay:input.lastCompletedDay??null,syncedAt:now}));await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[statement]});return {synced:true};\r\n}\r\nexport async function claimNotificationSlot(database,user,day,reminder,{dataEpoch=1,now=Date.now(),requireReminder=false}={}){\r\n const key=`notify-budget:${user}:${day}`;\r\n const statement=database.prepare(\"INSERT INTO system(key,value) SELECT ?,json_array(?) WHERE ?=0 OR EXISTS(SELECT 1 FROM reminders WHERE id=? AND user_id=? AND enabled=1) ON CONFLICT(key) DO UPDATE SET value=CASE WHEN EXISTS(SELECT 1 FROM json_each(system.value) WHERE value=?) THEN system.value ELSE json_insert(system.value,'$[#]',?) END WHERE json_array_length(system.value)<3 OR EXISTS(SELECT 1 FROM json_each(system.value) WHERE value=?) RETURNING key\").bind(key,reminder,requireReminder?1:0,reminder,user,reminder,reminder,reminder);\r\n return (await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[statement]}))[0].results.length>0;\r\n}\r\n","server/remote-account-operations.mjs":"import {reminderInput,uuid,cleanText,fail} from './domain.mjs';\r\nimport {readCoachPlan,saveCoachPlan} from './reminder-plan.mjs';\r\nimport {subscriptionInput,sendPush} from './push.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\n\r\n// Explicit request write sets. Scheduler authenticates and reconciles proof first.\r\nexport async function remoteAccountOperation(request,env,user,dataEpoch,now=Date.now()){\r\n const database=env.DB,path=new URL(request.url).pathname,method=request.method;\r\n const commit=statements=>epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements});\r\n const first=async statement=>(await commit([statement]))[0].results?.[0]??null;\r\n const body=async()=>{const text=await request.text();if(text.length>60000)fail('Too much reminder data.',413);try{return JSON.parse(text);}catch{fail('Invalid reminder data.');}};\r\n if(path==='/api/reminders/plan'&&method==='GET')return readCoachPlan(database,user);\r\n if(path==='/api/reminders/plan'&&method==='PUT')return saveCoachPlan(database,user,await body(),{dataEpoch});\r\n if(path==='/api/reminders'&&method==='GET')return {items:(await database.prepare('SELECT * FROM reminders WHERE user_id=? ORDER BY time').bind(user).all()).results};\r\n if(path==='/api/reminders'&&method==='POST'){\r\n  const v=reminderInput(await body());\r\n  const n=await database.prepare('SELECT count(*) AS n FROM reminders WHERE user_id=?').bind(user).first();if(n.n>=16)fail('Keep up to 16 reminders. Remove one before adding another.');\r\n  await commit([database.prepare('INSERT INTO reminders(id,user_id,kind,time,timezone,enabled,quiet_start,quiet_end,tone,days_per_week) VALUES(?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO NOTHING').bind(v.id,user,v.kind,v.time,v.timezone,v.enabled,v.quietStart,v.quietEnd,v.tone,v.daysPerWeek)]);return {saved:true};\r\n }\r\n if(/^\\/api\\/reminders\\/[a-f0-9-]{36}$/.test(path)){\r\n  const id=uuid(path.split('/').at(-1));\r\n  if(method==='DELETE'){await commit([database.prepare('DELETE FROM reminders WHERE id=? AND user_id=?').bind(id,user)]);return {deleted:true};}\r\n  if(method==='PUT'){\r\n   const v=reminderInput({...await body(),id});\r\n   const saved=await first(database.prepare('UPDATE reminders SET kind=?,time=?,timezone=?,enabled=?,quiet_start=?,quiet_end=?,tone=?,days_per_week=? WHERE id=? AND user_id=? RETURNING id').bind(v.kind,v.time,v.timezone,v.enabled,v.quietStart,v.quietEnd,v.tone,v.daysPerWeek,id,user));\r\n   if(!saved)fail('Reminder not found.',404);return {saved:true};\r\n  }\r\n  if(method==='PATCH'){\r\n   const v=await body();if(typeof v.enabled!=='boolean')fail('Choose on or off.');\r\n   const saved=await first(database.prepare('UPDATE reminders SET enabled=? WHERE id=? AND user_id=? RETURNING id').bind(v.enabled?1:0,id,user));\r\n   if(!saved)fail('Reminder not found.',404);return {enabled:v.enabled};\r\n  }\r\n }\r\n if(path==='/api/push/subscribe'&&method==='POST'){\r\n  if(!env.VAPID_PRIVATE_KEY)fail('Notification sending is not connected yet.',503);\r\n  const s=subscriptionInput(await body()),data=JSON.stringify(s);\r\n  const prior=await database.prepare('SELECT user_id,data FROM subscriptions WHERE endpoint=?').bind(s.endpoint).first();\r\n  // Atomic compare-and-set preserves prior endpoint reassignment semantics without\r\n  // letting a delayed read overwrite a different intervening subscription.\r\n  const saved=await first(database.prepare('INSERT INTO subscriptions(endpoint,user_id,data,created_at) VALUES(?,?,?,?) ON CONFLICT(endpoint) DO UPDATE SET user_id=excluded.user_id,data=excluded.data,created_at=excluded.created_at WHERE subscriptions.user_id=? AND subscriptions.data=? RETURNING endpoint').bind(s.endpoint,user,data,now,prior?.user_id??'',prior?.data??''));\r\n  if(!saved)throw Object.assign(Error('Subscription changed. Try again.'),{status:409,code:'subscription_changed'});return {subscribed:true};\r\n }\r\n if(path==='/api/push/unsubscribe'&&method==='POST'){\r\n  const v=await body();await commit([database.prepare('DELETE FROM subscriptions WHERE endpoint=? AND user_id=?').bind(cleanText(v.endpoint,2048),user)]);return {unsubscribed:true};\r\n }\r\n if(path==='/api/push/test'&&method==='POST'){\r\n  const v=await body(),s=await database.prepare('SELECT data,created_at FROM subscriptions WHERE endpoint=? AND user_id=?').bind(cleanText(v.endpoint,2048),user).first();\r\n  if(!s)fail('Enable notifications on this device first.');const key='test:'+user;\r\n  const claimed=await first(database.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value WHERE CAST(system.value AS INTEGER)<=? RETURNING key').bind(key,String(now),now-30000));\r\n  if(!claimed)fail('Wait 30 seconds between test reminders.',429);\r\n  await sendPush(env,JSON.parse(s.data),{title:'MYR5 Coach',body:'Your phone is connected to Coach reminders.',url:'/pose.html?panel=reminders',tag:'myr5-test'},{ownerId:user,dataEpoch,subscriptionData:s.data,subscriptionCreatedAt:s.created_at});return {accepted:true};\r\n }\r\n if(path==='/api/export'&&method==='GET'){\r\n  const data={};for(const table of ['reminders','subscriptions'])data[table]=(await database.prepare(`SELECT * FROM ${table} WHERE user_id=?`).bind(user).all()).results;return data;\r\n }\r\n fail('Not found.',404);\r\n}\r\n","server/remote-deletion-data.mjs":"// Trusted owner-bound statements; run only inside reconcileRemoteEpoch's batch.\r\nexport function remoteAccountDeletionStatements(db,user){\r\n return [\r\n  db.prepare('DELETE FROM deliveries WHERE endpoint IN (SELECT endpoint FROM subscriptions WHERE user_id=?) OR reminder_id IN (SELECT id FROM reminders WHERE user_id=?)').bind(user,user),\r\n  ...['reminders','subscriptions','release_subscribers','release_deliveries'].map(table=>db.prepare(`DELETE FROM ${table} WHERE user_id=?`).bind(user)),\r\n  ...['test:','training:','coach-plan:','release-email-user:'].map(prefix=>db.prepare('DELETE FROM system WHERE key=?').bind(prefix+user)),\r\n  // Explicit legacy markers are retained to prevent old bootstrap imports.\r\n  db.prepare(\"DELETE FROM system WHERE substr(key,1,14)='notify-budget:' AND substr(key,-11,1)=':' AND substr(key,15,length(key)-25)=?\").bind(user),\r\n ];\r\n}\r\n","server/remote-epochs.mjs":"// PROPOSAL: transaction proof primitives only, not HTTP integration or auth.\r\n// All statements supplied by callers MUST be owner-bound trusted SQL.\r\nexport class RemoteEpochError extends Error {\r\n constructor(code){super(code);this.code=code;this.name='RemoteEpochError';}\r\n}\r\nconst fail=code=>{throw new RemoteEpochError(code);};\r\nfunction validate(owner,epoch,now){\r\n if(typeof owner!=='string'||!owner||owner.length>512||owner.trim()!==owner)fail('invalid_owner');\r\n if(!Number.isSafeInteger(epoch)||epoch<1)fail('invalid_epoch');\r\n if(!Number.isSafeInteger(now)||now<0)fail('invalid_time');\r\n}\r\nconst provision=(db,owner,now)=>db.prepare('INSERT INTO account_data_epochs(owner_id,epoch,updated_at) VALUES(?,1,?) ON CONFLICT(owner_id) DO NOTHING').bind(owner,now);\r\n// NOT NULL violation fails the *whole batch*, unlike an ineffective zero-row guard.\r\nconst guard=(db,owner,epoch)=>db.prepare('UPDATE account_data_epochs SET epoch=CASE WHEN epoch=? THEN epoch ELSE NULL END WHERE owner_id=?').bind(epoch,owner);\r\nexport async function epochFencedBatch(db,{ownerId,expectedDataEpoch,now,statements}){\r\n validate(ownerId,expectedDataEpoch,now);if(!Array.isArray(statements))fail('invalid_statements');\r\n try{\r\n  const result=await db.batch([provision(db,ownerId,now),guard(db,ownerId,expectedDataEpoch),...statements]);\r\n  return result.slice(2);\r\n }catch(error){\r\n  const row=await db.prepare('SELECT epoch FROM account_data_epochs WHERE owner_id=?').bind(ownerId).first();\r\n  if((row?.epoch??1)!==expectedDataEpoch)fail('target_epoch_mismatch');\r\n  throw error;\r\n }\r\n}\r\n// A caller must authenticate the primary service and derive this proof from its\r\n// retained D1 receipts. Client headers/body are NOT acceptable proof authority.\r\nexport async function reconcileRemoteEpoch(db,{ownerId,currentDataEpoch,deletedThroughEpoch,now,deletions}){\r\n validate(ownerId,currentDataEpoch,now);\r\n if(deletedThroughEpoch!==currentDataEpoch-1||!Array.isArray(deletions))fail('invalid_proof');\r\n for(let attempt=0;attempt<4;attempt++){\r\n  const row=await db.prepare('SELECT epoch FROM account_data_epochs WHERE owner_id=?').bind(ownerId).first();\r\n  const observed=row?.epoch??1;\r\n  if(observed>=currentDataEpoch)return {ownerId,currentDataEpoch:observed,deletedThroughEpoch:observed-1,reconciled:false};\r\n  try{\r\n   await db.batch([\r\n    provision(db,ownerId,now),guard(db,ownerId,observed),\r\n    ...deletions,\r\n    db.prepare('UPDATE account_data_epochs SET epoch=?,updated_at=? WHERE owner_id=?').bind(currentDataEpoch,now,ownerId),\r\n    db.prepare('INSERT INTO account_data_deletions(owner_id,deleted_epoch,deleted_at) VALUES(?,?,?)').bind(ownerId,deletedThroughEpoch,now),\r\n   ]);\r\n   return {ownerId,currentDataEpoch,deletedThroughEpoch,reconciled:true};\r\n  }catch(error){\r\n   const latest=await db.prepare('SELECT epoch FROM account_data_epochs WHERE owner_id=?').bind(ownerId).first();\r\n   if((latest?.epoch??1)===observed)throw error; // Actual data-deletion error, not a CAS race.\r\n  }\r\n }\r\n fail('remote_epoch_busy');\r\n}\r\n","server/remote-reminders.mjs":"import {db} from './db.mjs';\r\nimport {fail} from './domain.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nexport const remoteReminders=env=>!!env.REMINDER_SERVICE_ORIGIN;\r\nexport function validatedReminderProof(user,proof){\r\n if(!proof||proof.ownerId!==user||typeof user!=='string'||!user||user.length>512||user.trim()!==user||/[\\r\\n]/.test(user)||!Number.isSafeInteger(proof.currentDataEpoch)||proof.currentDataEpoch<1||proof.deletedThroughEpoch!==proof.currentDataEpoch-1)fail('Invalid account generation.',422);\r\n return {ownerId:user,currentDataEpoch:proof.currentDataEpoch,deletedThroughEpoch:proof.deletedThroughEpoch};\r\n}\r\nexport async function reminderService(env,user,path,method='GET',data,proof){\r\n if(!env.REMINDER_SERVICE_TOKEN)fail('The reminder service is not connected.',503);\r\n const origin=new URL(env.REMINDER_SERVICE_ORIGIN);\r\n if(origin.protocol!=='https:'||origin.pathname!=='/'||origin.username||origin.password)fail('Invalid reminder service configuration.',503);\r\n // Global status and unique-token actions do not carry an account proof.\r\n const unscoped=path==='/internal/status'||path.startsWith('/internal/release-email/');\r\n const captured=unscoped?null:validatedReminderProof(user,proof);\r\n const headers={'Authorization':`Bearer ${env.REMINDER_SERVICE_TOKEN}`,'X-Coach-User':user,'Content-Type':'application/json',...(captured?{'X-Coach-Data-Epoch':String(captured.currentDataEpoch),'X-Coach-Deleted-Through':String(captured.deletedThroughEpoch)}:{})};\r\n let response;\r\n try{response=await fetch(new URL(path,origin),{method,headers,body:data===undefined?undefined:JSON.stringify(data),redirect:'manual',signal:AbortSignal.timeout(5000)});}\r\n catch{fail('The reminder service is temporarily unavailable. Please try again.',503);}\r\n if(response.status>=300&&response.status<400)fail('The reminder service returned an unexpected redirect.',503);\r\n if(!response.headers.get('content-type')?.includes('application/json'))fail('The reminder service is temporarily unavailable.',503);\r\n let result;try{result=await response.json();}catch{fail('The reminder service is temporarily unavailable.',503);}\r\n if(!response.ok)throw Object.assign(Error(result.error||'Could not save your reminder. Please try again.'),{status:response.status,...(typeof result.code==='string'?{code:result.code}:{})});\r\n return result;\r\n}\r\nexport async function reconcileReminderAccount(env,user,proof){\r\n const captured=validatedReminderProof(user,proof);\r\n const result=await reminderService(env,user,'/internal/account-reconcile','POST',undefined,captured);\r\n const acknowledged=validatedReminderProof(user,result);\r\n if(acknowledged.currentDataEpoch<captured.currentDataEpoch)fail('Reminder deletion is still pending.',503);\r\n return acknowledged;\r\n}\r\nexport function queueReminderReconciliation(database,user,currentDataEpoch,now){\r\n const proof=validatedReminderProof(user,{ownerId:user,currentDataEpoch,deletedThroughEpoch:currentDataEpoch-1});\r\n return database.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO UPDATE SET value=excluded.value').bind('remote-deletion:'+user,JSON.stringify(proof));\r\n}\r\nexport async function attemptReminderReconciliation(env,user,proof){\r\n if(!remoteReminders(env))return {status:'not_configured'};\r\n try{\r\n  const ack=await reconcileReminderAccount(env,user,proof);\r\n  await db(env).prepare(\"DELETE FROM system WHERE key=? AND json_extract(value,'$.currentDataEpoch')<=?\").bind('remote-deletion:'+user,ack.currentDataEpoch).run();\r\n  return {status:'reconciled'};\r\n }catch{return {status:'pending'};}\r\n}\r\nexport async function ensureReminderMigration(env,user,proof){\r\n const captured=validatedReminderProof(user,proof),database=db(env),key='reminders_remote:'+JSON.stringify([user,captured.currentDataEpoch]);\r\n if(await database.prepare('SELECT value FROM system WHERE key=?').bind(key).first())return;\r\n const reminders=(await database.prepare('SELECT * FROM reminders WHERE user_id=?').bind(user).all()).results;\r\n const subscriptions=(await database.prepare('SELECT data FROM subscriptions WHERE user_id=?').bind(user).all()).results.map(s=>JSON.parse(s.data));\r\n await reminderService(env,user,'/internal/import','POST',{reminders,subscriptions},captured);\r\n await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:captured.currentDataEpoch,now:Date.now(),statements:[database.prepare('INSERT INTO system(key,value) VALUES(?,?) ON CONFLICT(key) DO NOTHING').bind(key,String(Date.now()))]});\r\n}\r\n","server/scoreboard.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {fail,cleanText} from './domain.mjs';\r\nconst hash=async value=>Array.from(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(value))),b=>b.toString(16).padStart(2,'0')).join('');\r\nconst codeValue=value=>typeof value==='string'?value.replace(/[\\s-]/g,'').toLowerCase():'';\r\nconst connections=(database,user)=>database.prepare('SELECT id,CASE WHEN user_a=? THEN user_b ELSE user_a END AS friend FROM scoreboard_links WHERE user_a=? OR user_b=? ORDER BY created_at,id').bind(user,user,user).all();\r\nasync function scores(database,user){return (await database.prepare(`SELECT mode,COUNT(*) AS sets,MAX(value) AS best FROM workouts WHERE user_id=? AND source='server' AND competitive_status='accepted' AND completed_at IS NOT NULL GROUP BY mode`).bind(user).all()).results;}\r\nexport function sharedGala(profile){try{const raw=JSON.parse(JSON.parse(profile||'{}')['mominc-avatar-v1']||'null');if(raw?.schema!=='mominc-avatar'||raw.version!==1||!Number.isInteger(raw.dye)||raw.dye<0||raw.dye>9)return null;const parts={};for(const key of ['body','skin','face','hair','facial','headwear','neck','torso','shoulders','arms','hands','legs','feet','held','back','base','pet']){const value=raw.parts?.[key]??0;if(!Number.isInteger(value)||value<0||value>39)return null;parts[key]=value;}return {schema:'mominc-avatar',version:1,name:'',dye:raw.dye,parts};}catch{return null;}}\r\nasync function member(database,user,link=null){const row=await database.prepare('SELECT data FROM onboarding WHERE user_id=?').bind(user).first(),profile=await database.prepare('SELECT data FROM profiles WHERE user_id=?').bind(user).first();let name='Crew member';try{name=JSON.parse(row?.data||'{}').profile?.name||name;}catch{}return {name:String(name).slice(0,60),link,avatar:sharedGala(profile?.data),items:await scores(database,user)};}\r\nexport async function scoreboardApi(database,user,path,method,input={},now=Date.now(),{dataEpoch=1}={}){\r\n if(path==='/api/scoreboard'&&method==='GET'){\r\n  const links=(await connections(database,user)).results;\r\n  const members=await Promise.all([member(database,user),...links.map(l=>member(database,l.friend,l.id))]);\r\n  const invite=await database.prepare('SELECT expires_at FROM scoreboard_invites WHERE owner_id=? AND expires_at>?').bind(user,now).first();\r\n  return {members,inviteExpiresAt:invite?.expires_at??null,updatedAt:now};\r\n }\r\n if(path==='/api/scoreboard/invite'&&method==='POST'){\r\n  if(input.consent!==true)fail('Choose to share your name and best sets with a friend.');\r\n  if((await connections(database,user)).results.length>=2)fail('Your two friend places are full. Remove a friend to invite someone else.',409);\r\n  const code=Array.from(crypto.getRandomValues(new Uint8Array(12)),b=>b.toString(16).padStart(2,'0')).join('');\r\n  const saved=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('INSERT INTO scoreboard_invites(owner_id,token_hash,created_at,expires_at) VALUES(?,?,?,?) ON CONFLICT(owner_id) DO UPDATE SET token_hash=excluded.token_hash,created_at=excluded.created_at,expires_at=excluded.expires_at WHERE scoreboard_invites.created_at<=? RETURNING owner_id').bind(user,await hash(code),now,now+7*86400000,now-60000)]}))[0].results[0];\r\n  if(!saved)fail('Wait a minute before replacing your invite code.',429);\r\n  return {code:code.match(/.{6}/g).join('-').toUpperCase(),expiresAt:now+7*86400000};\r\n }\r\n if(path==='/api/scoreboard/invite'&&method==='DELETE'){\r\n  await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('DELETE FROM scoreboard_invites WHERE owner_id=?').bind(user)]});return {revoked:true};\r\n }\r\n if(path==='/api/scoreboard/join'&&method==='POST'){\r\n  if(input.consent!==true)fail('Choose to share your name and best sets with this friend.');\r\n  const code=codeValue(input.code);if(!/^[a-f0-9]{24}$/.test(code))fail('Enter the full invite code from your friend.');\r\n  const rate=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare(\"INSERT INTO system(key,value) VALUES(?,json_object('since',?,'count',1)) ON CONFLICT(key) DO UPDATE SET value=CASE WHEN json_extract(system.value,'$.since')<? THEN excluded.value ELSE json_set(system.value,'$.count',json_extract(system.value,'$.count')+1) END WHERE json_extract(system.value,'$.since')<? OR json_extract(system.value,'$.count')<20 RETURNING key\").bind(`scoreboard-join:${user}`,now,now-3600000,now-3600000)]}))[0].results[0];\r\n  if(!rate)fail('Too many attempts. Try again in an hour.',429);\r\n  const tokenHash=await hash(code),invite=await database.prepare('SELECT owner_id FROM scoreboard_invites WHERE token_hash=? AND expires_at>?').bind(tokenHash,now).first();\r\n  if(!invite)fail('That invite expired or was used. Ask your friend for a new code.',404);\r\n  if(invite.owner_id===user)fail('That is your own code. Enter a friend’s code.');\r\n  const [a,b]=[user,invite.owner_id].sort(),id=crypto.randomUUID();\r\n  // Capacity, token consumption and membership are one transaction, including concurrent joins.\r\n  const [insert]=await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[\r\n   database.prepare('INSERT INTO scoreboard_links(id,user_a,user_b,created_at) SELECT ?,?,?,? WHERE EXISTS(SELECT 1 FROM scoreboard_invites WHERE token_hash=? AND expires_at>?) AND (SELECT COUNT(*) FROM scoreboard_links WHERE user_a=? OR user_b=?)<2 AND (SELECT COUNT(*) FROM scoreboard_links WHERE user_a=? OR user_b=?)<2 ON CONFLICT(user_a,user_b) DO NOTHING RETURNING id').bind(id,a,b,now,tokenHash,now,a,a,b,b),\r\n   database.prepare('DELETE FROM scoreboard_invites WHERE token_hash=? AND EXISTS(SELECT 1 FROM scoreboard_links WHERE id=?)').bind(tokenHash,id)\r\n  ]});\r\n  if(!insert.results.length)fail('Already connected, or one of your boards is full. Refresh your board.',409);\r\n  return {connected:true};\r\n }\r\n if(path.startsWith('/api/scoreboard/friends/')&&method==='DELETE'){\r\n  const id=cleanText(path.split('/').at(-1),50);const removed=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('DELETE FROM scoreboard_links WHERE id=? AND (user_a=? OR user_b=?) RETURNING id').bind(id,user,user)]}))[0].results[0];\r\n  if(!removed)fail('Friend connection not found.',404);return {removed:true};\r\n }\r\n fail('Not found.',404);\r\n}\r\nexport async function exportScoreboard(database,user){return {connections:(await connections(database,user)).results.map(({id})=>({id})),invite:(await database.prepare('SELECT created_at,expires_at FROM scoreboard_invites WHERE owner_id=?').bind(user).first())??null};}\r\nexport function deleteScoreboard(database,user){return [database.prepare('DELETE FROM scoreboard_links WHERE user_a=? OR user_b=?').bind(user,user),database.prepare('DELETE FROM scoreboard_invites WHERE owner_id=?').bind(user),database.prepare('DELETE FROM system WHERE key=?').bind(`scoreboard-join:${user}`)];}\r\n","server/spotify.mjs":"import {SPOTIFY_SCOPES,spotifyNowPlaying,spotifyPlaylist,spotifyTrack,spotifyDevice} from '../spotify-domain.mjs';\r\nimport {inspectAccountDataEpoch} from './account-data-epochs.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\n\r\nconst API='https://api.spotify.com/v1';\r\nconst ACCOUNTS='https://accounts.spotify.com';\r\nconst json=(value,status=200,extra={})=>new Response(JSON.stringify(value),{status,headers:{'Content-Type':'application/json','Cache-Control':'no-store','X-Content-Type-Options':'nosniff',...extra}});\r\nconst error=(message,status=400,code='spotify_error')=>Object.assign(new Error(message),{status,code});\r\nconst bytes=n=>crypto.getRandomValues(new Uint8Array(n));\r\nconst b64=b=>btoa(String.fromCharCode(...b)).replace(/\\+/g,'-').replace(/\\//g,'_').replace(/=+$/,'');\r\nconst from64=s=>Uint8Array.from(atob(s.replace(/-/g,'+').replace(/_/g,'/')+'='.repeat((4-s.length%4)%4)),c=>c.charCodeAt(0));\r\nconst hash=async s=>b64(new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(s))));\r\nconst secret=async env=>{\r\n  if(!env.SPOTIFY_TOKEN_KEY||env.SPOTIFY_TOKEN_KEY.length<32)throw error('Spotify token encryption is not configured.',503,'spotify_unconfigured');\r\n  return crypto.subtle.importKey('raw',await crypto.subtle.digest('SHA-256',new TextEncoder().encode(env.SPOTIFY_TOKEN_KEY)),'AES-GCM',false,['encrypt','decrypt']);\r\n};\r\nconst encrypt=async(env,value)=>{const iv=bytes(12),cipher=await crypto.subtle.encrypt({name:'AES-GCM',iv},await secret(env),new TextEncoder().encode(value));return `${b64(iv)}.${b64(new Uint8Array(cipher))}`;};\r\nconst decrypt=async(env,value)=>{const [iv,cipher]=String(value).split('.');return new TextDecoder().decode(await crypto.subtle.decrypt({name:'AES-GCM',iv:from64(iv)},await secret(env),from64(cipher)));};\r\nconst config=env=>{\r\n  if(!env.SPOTIFY_CLIENT_ID||!env.SPOTIFY_REDIRECT_URI)throw error('Spotify connection is not configured.',503,'spotify_unconfigured');\r\n  const uri=new URL(env.SPOTIFY_REDIRECT_URI);\r\n  if(uri.pathname!=='/api/spotify/callback'||!['https:','http:'].includes(uri.protocol))throw error('Spotify redirect URI is invalid.',503,'spotify_unconfigured');\r\n  return uri;\r\n};\r\nconst cookie=(value,request)=>`spotify_oauth=${value}; Path=/api/spotify/callback; HttpOnly; SameSite=Lax; Max-Age=${value?600:0}${new URL(request.url).protocol==='https:'?'; Secure':''}`;\r\nconst cookieValue=request=>request.headers.get('Cookie')?.match(/(?:^|;\\s*)spotify_oauth=([A-Za-z0-9_-]{32,128})(?:;|$)/)?.[1]||null;\r\nconst noStoreRedirect=(to,request,clear=false)=>new Response(null,{status:303,headers:{Location:to,'Cache-Control':'no-store',...(clear?{'Set-Cookie':cookie('',request)}:{})}});\r\nconst safeResult=(kind,request)=>noStoreRedirect(`/pose.html?panel=spotify&spotify=${kind}`,request,true);\r\nconst postToken=async(env,form)=>{\r\n  const response=await fetch(`${ACCOUNTS}/api/token`,{method:'POST',headers:{'Content-Type':'application/x-www-form-urlencoded'},body:new URLSearchParams({...form,client_id:env.SPOTIFY_CLIENT_ID}),signal:AbortSignal.timeout(15000)});\r\n  const data=await response.json().catch(()=>({}));\r\n  if(!response.ok)throw error(data.error==='invalid_grant'?'Spotify authorization expired. Connect again.':'Spotify authorization is unavailable.',response.status===429?429:502,data.error==='invalid_grant'?'spotify_reconnect':'spotify_upstream');\r\n  if(!data.access_token||!data.expires_in)throw error('Spotify authorization returned incomplete data.',502,'spotify_upstream');\r\n  return data;\r\n};\r\n\r\n// This callback is the sole route that runs before the app's normal account identity check.\r\n// State is consumed atomically; the separate HttpOnly cookie binds the redirect to its starter.\r\nexport async function spotifyCallback(request,env,database) {\r\n  try {\r\n    config(env);await secret(env);\r\n    if(request.method!=='GET')return json({error:'Method not allowed.'},405);\r\n    const u=new URL(request.url),state=u.searchParams.get('state'),proof=cookieValue(request);\r\n    if(!state||!proof||!await validState(database,state,proof))return safeResult(state&&!proof&&await stateExists(database,state)?'browser':'expired',request);\r\n    const row=await database.prepare('DELETE FROM spotify_oauth_states WHERE state_hash=? AND cookie_hash=? AND expires_at>? RETURNING user_id,verifier_enc,data_epoch').bind(await hash(state),await hash(proof),Date.now()).first();\r\n    if(!row)return safeResult('expired',request);\r\n    if(u.searchParams.has('error'))return safeResult('denied',request);\r\n    const code=u.searchParams.get('code');if(!code)return safeResult('expired',request);\r\n    const token=await postToken(env,{grant_type:'authorization_code',code,redirect_uri:env.SPOTIFY_REDIRECT_URI,code_verifier:await decrypt(env,row.verifier_enc)});\r\n    if(!token.refresh_token)return safeResult('failed',request);\r\n    const me=await fetch(`${API}/me`,{headers:{Authorization:`Bearer ${token.access_token}`},signal:AbortSignal.timeout(15000)});\r\n    // Development-mode apps answer 403 for any Spotify account not on the dashboard user allowlist.\r\n    if(me.status===403)return safeResult('notlisted',request);\r\n    if(!me.ok)return safeResult('failed',request);\r\n    const profile=await me.json();if(!profile.id)return safeResult('failed',request);\r\n    await epochFencedBatch(database,{ownerId:row.user_id,expectedDataEpoch:row.data_epoch,now:Date.now(),statements:[database.prepare(`INSERT INTO spotify_connections(user_id,spotify_user_id,display_name,access_token_enc,refresh_token_enc,expires_at,scopes,data_epoch,updated_at) VALUES(?,?,?,?,?,?,?,?,?)\r\n      ON CONFLICT(user_id) DO UPDATE SET spotify_user_id=excluded.spotify_user_id,display_name=excluded.display_name,access_token_enc=excluded.access_token_enc,refresh_token_enc=excluded.refresh_token_enc,expires_at=excluded.expires_at,scopes=excluded.scopes,data_epoch=excluded.data_epoch,updated_at=excluded.updated_at`)\r\n      .bind(row.user_id,profile.id,profile.display_name||profile.id,await encrypt(env,token.access_token),await encrypt(env,token.refresh_token),Date.now()+token.expires_in*1000,token.scope||SPOTIFY_SCOPES,row.data_epoch,Date.now())]});\r\n    return safeResult('connected',request);\r\n  } catch {return safeResult('failed',request);}\r\n}\r\nasync function validState(database,state,proof){\r\n  if(!/^[A-Za-z0-9_-]{32,128}$/.test(state))return false;\r\n  const row=await database.prepare('SELECT 1 AS ok FROM spotify_oauth_states WHERE state_hash=? AND cookie_hash=? AND expires_at>?').bind(await hash(state),await hash(proof),Date.now()).first();\r\n  return !!row;\r\n}\r\n// A real state with no cookie means the return landed in a different browser jar (iOS Home Screen app vs Safari).\r\nasync function stateExists(database,state){\r\n  if(!/^[A-Za-z0-9_-]{32,128}$/.test(state))return false;\r\n  return !!await database.prepare('SELECT 1 AS ok FROM spotify_oauth_states WHERE state_hash=? AND expires_at>?').bind(await hash(state),Date.now()).first();\r\n}\r\nasync function connection(database,user){const proof=await inspectAccountDataEpoch(database,user);return database.prepare('SELECT * FROM spotify_connections WHERE user_id=? AND data_epoch=?').bind(user,proof.currentDataEpoch).first();}\r\nasync function access(env,database,user){\r\n  let row=await connection(database,user);if(!row)throw error('Connect Spotify first.',409,'spotify_disconnected');\r\n  if(row.expires_at>Date.now()+60000)return decrypt(env,row.access_token_enc);\r\n  let token;\r\n  try{token=await postToken(env,{grant_type:'refresh_token',refresh_token:await decrypt(env,row.refresh_token_enc)});}\r\n  catch(e){if(e.code==='spotify_reconnect')try{await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:row.data_epoch,now:Date.now(),statements:[database.prepare('DELETE FROM spotify_connections WHERE user_id=? AND data_epoch=? AND refresh_token_enc=?').bind(user,row.data_epoch,row.refresh_token_enc)]});}catch{}throw e;}\r\n  await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:row.data_epoch,now:Date.now(),statements:[database.prepare('UPDATE spotify_connections SET access_token_enc=?,refresh_token_enc=?,expires_at=?,updated_at=? WHERE user_id=? AND data_epoch=?')\r\n    .bind(await encrypt(env,token.access_token),token.refresh_token?await encrypt(env,token.refresh_token):row.refresh_token_enc,Date.now()+token.expires_in*1000,Date.now(),user,row.data_epoch)]});\r\n  return token.access_token;\r\n}\r\nasync function spotifyFetch(env,database,user,path,{method='GET',body}={}){\r\n  const readEpoch=(await inspectAccountDataEpoch(database,user)).currentDataEpoch;\r\n  const response=await fetch(API+path,{method,headers:{Authorization:`Bearer ${await access(env,database,user)}`,...(body?{'Content-Type':'application/json'}:{})},...(body?{body:JSON.stringify(body)}:{}),signal:AbortSignal.timeout(15000)});\r\n  if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==readEpoch)throw error('Account data changed.',409,'target_epoch_mismatch');\r\n  if(response.status===204||response.status===202)return null;\r\n  if(response.status===429)throw error('Spotify is busy. Try again shortly.',429,'spotify_rate_limited');\r\n  if(response.status===403)throw error('Spotify Premium or app access is needed for this control.',403,'spotify_restricted');\r\n  if(response.status===404)throw error('Open Spotify on a device, then try this control.',409,'spotify_no_device');\r\n  if(response.status===401)throw error('Spotify session expired. Reconnect Spotify.',401,'spotify_reconnect');\r\n  if(!response.ok)throw error('Spotify is temporarily unavailable.',502,'spotify_upstream');\r\n  return response.json().catch(()=>null);\r\n}\r\nasync function readBody(request){\r\n  if(!request.headers.get('Content-Type')?.startsWith('application/json'))throw error('Send JSON.',415);\r\n  const length=Number(request.headers.get('Content-Length')||0);if(length>2048)throw error('Request too large.',413);\r\n  const text=await request.text();if(text.length>2048)throw error('Request too large.',413);\r\n  try{return JSON.parse(text);}catch{throw error('Invalid request.');}\r\n}\r\nfunction pageOffset(u,allowed){\r\n  for(const key of u.searchParams.keys())if(!allowed.includes(key))throw error('Invalid query.');\r\n  const raw=u.searchParams.get('offset');if(raw===null)return 0;\r\n  if(!/^(0|[1-9][0-9]{0,5})$/.test(raw))throw error('Choose a valid offset.');\r\n  const offset=Number(raw);if(!Number.isSafeInteger(offset)||offset>100000)throw error('Choose a valid offset.');\r\n  return offset;\r\n}\r\nconst onlyKeys=(input,keys)=>input&&typeof input==='object'&&!Array.isArray(input)&&Object.keys(input).every(key=>keys.includes(key))&&keys.every(key=>Object.hasOwn(input,key));\r\nconst spotifyId=value=>typeof value==='string'&&/^[A-Za-z0-9]{10,32}$/.test(value);\r\nexport async function spotifyApi(request,env,database,user){\r\n  try{\r\n    config(env);await secret(env);\r\n    const u=new URL(request.url),p=u.pathname,m=request.method;\r\n    if(!user)throw error('Sign in to Coach.',401,'unauthorized');\r\n    if(!['GET','HEAD'].includes(m)&&request.headers.get('Origin')!==u.origin)throw error('Open this action from Coach.',403,'origin_required');\r\n    let writeEpoch=null;\r\n    if(!['GET','HEAD'].includes(m)){\r\n      const expected=request.headers.get('X-Expected-Data-Epoch');\r\n      if(request.headers.get('X-Target-Account')!==user||!expected||!/^[1-9][0-9]*$/.test(expected))throw error('Refresh account details before connecting Spotify.',428,'account_assertion_required');\r\n      writeEpoch=Number(expected);\r\n      if(!Number.isSafeInteger(writeEpoch)||(await inspectAccountDataEpoch(database,user)).currentDataEpoch!==writeEpoch)throw error('Account data changed.',409,'target_epoch_mismatch');\r\n    }\r\n    if(p==='/api/spotify/status'&&m==='GET'){\r\n      const row=await connection(database,user);\r\n      return json({configured:true,connected:!!row,account:row?{name:row.display_name,id:row.spotify_user_id}:null});\r\n    }\r\n    if(p==='/api/spotify/connect'&&m==='POST'){\r\n      const state=b64(bytes(32)),proof=b64(bytes(32)),verifier=b64(bytes(64)),challenge=await hash(verifier);\r\n      await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:writeEpoch,now:Date.now(),statements:[\r\n        database.prepare('DELETE FROM spotify_oauth_states WHERE user_id=? OR expires_at<?').bind(user,Date.now()),\r\n        database.prepare('INSERT INTO spotify_oauth_states(state_hash,cookie_hash,user_id,verifier_enc,data_epoch,expires_at) VALUES(?,?,?,?,?,?)')\r\n          .bind(await hash(state),await hash(proof),user,await encrypt(env,verifier),writeEpoch,Date.now()+600000),\r\n      ]});\r\n      const auth=new URL(`${ACCOUNTS}/authorize`);\r\n      auth.search=new URLSearchParams({client_id:env.SPOTIFY_CLIENT_ID,response_type:'code',redirect_uri:env.SPOTIFY_REDIRECT_URI,scope:SPOTIFY_SCOPES,state,code_challenge_method:'S256',code_challenge:challenge}).toString();\r\n      return json({url:auth.href},200,{'Set-Cookie':cookie(proof,request)});\r\n    }\r\n    if(p==='/api/spotify/disconnect'&&m==='POST'){\r\n      await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:writeEpoch,now:Date.now(),statements:[database.prepare('DELETE FROM spotify_connections WHERE user_id=?').bind(user),database.prepare('DELETE FROM spotify_oauth_states WHERE user_id=?').bind(user)]});\r\n      return json({connected:false});\r\n    }\r\n    if(p==='/api/spotify/now-playing'&&m==='GET')return json({nowPlaying:spotifyNowPlaying(await spotifyFetch(env,database,user,'/me/player'))});\r\n    if(p==='/api/spotify/search'&&m==='GET'){\r\n      for(const key of u.searchParams.keys())if(!['q','offset'].includes(key))throw error('Invalid query.');\r\n      const q=u.searchParams.get('q');if(typeof q!=='string'||!q.trim()||q.length>200)throw error('Enter a valid search.');\r\n      const offset=pageOffset(u,['q','offset']),data=await spotifyFetch(env,database,user,`/search?${new URLSearchParams({q:q.trim(),type:'track',limit:'10',offset:String(offset)})}`);\r\n      return json({items:(data?.tracks?.items||[]).map(spotifyTrack).filter(Boolean),total:Number(data?.tracks?.total)||0,offset});\r\n    }\r\n    if(p==='/api/spotify/queue'&&m==='GET'){\r\n      if(u.search)return json({error:'Invalid query.'},400);\r\n      const data=await spotifyFetch(env,database,user,'/me/player/queue');\r\n      return json({items:(data?.queue||[]).map(spotifyTrack).filter(Boolean)});\r\n    }\r\n    if(p==='/api/spotify/devices'&&m==='GET'){\r\n      if(u.search)return json({error:'Invalid query.'},400);\r\n      const data=await spotifyFetch(env,database,user,'/me/player/devices');\r\n      return json({items:(data?.devices||[]).map(spotifyDevice)});\r\n    }\r\n    if(p==='/api/spotify/playlist-tracks'&&m==='GET'){\r\n      for(const key of u.searchParams.keys())if(!['playlistId','offset'].includes(key))throw error('Invalid query.');\r\n      const playlistId=u.searchParams.get('playlistId');if(!spotifyId(playlistId))throw error('Choose a valid playlist.',422);\r\n      const offset=pageOffset(u,['playlistId','offset']),data=await spotifyFetch(env,database,user,`/playlists/${encodeURIComponent(playlistId)}/items?limit=50&offset=${offset}`);\r\n      return json({items:(data?.items||[]).map(entry=>spotifyTrack(entry?.item??entry?.track)).filter(Boolean),total:Number(data?.total)||0,offset});\r\n    }\r\n    if(p==='/api/spotify/playlists'&&m==='GET'){\r\n      const offset=Math.max(0,Math.min(1000,Number.parseInt(u.searchParams.get('offset')||'0',10)||0));\r\n      const data=await spotifyFetch(env,database,user,`/me/playlists?limit=20&offset=${offset}`);\r\n      return json({items:(data?.items||[]).map(spotifyPlaylist),total:Number(data?.total)||0,offset});\r\n    }\r\n    if(p==='/api/spotify/playback'&&m==='POST'){\r\n      const input=await readBody(request),action=input?.action;\r\n      if(!['pause','resume','next','previous','playlist','seek','volume','shuffle','repeat','track','queue','transfer'].includes(action))throw error('Unknown playback control.',422);\r\n      let path='/me/player/',method='POST',body;\r\n      if(action==='pause'){path+='pause';method='PUT';}\r\n      if(action==='resume'){path+='play';method='PUT';}\r\n      if(action==='next')path+='next';\r\n      if(action==='previous')path+='previous';\r\n      if(action==='playlist'){\r\n        if(!onlyKeys(input,['action','playlistId'])||!spotifyId(input.playlistId))throw error('Choose a valid playlist.',422);\r\n        path+='play';method='PUT';body={context_uri:`spotify:playlist:${input.playlistId}`};\r\n      }\r\n      if(action==='seek'){\r\n        if(!onlyKeys(input,['action','positionMs'])||!Number.isSafeInteger(input.positionMs)||input.positionMs<0||input.positionMs>86400000)throw error('Choose a valid playback position.',422);\r\n        path+=`seek?position_ms=${input.positionMs}`;method='PUT';\r\n      }\r\n      if(action==='volume'){\r\n        if(!onlyKeys(input,['action','volumePercent'])||!Number.isInteger(input.volumePercent)||input.volumePercent<0||input.volumePercent>100)throw error('Choose a valid volume.',422);\r\n        path+=`volume?volume_percent=${input.volumePercent}`;method='PUT';\r\n      }\r\n      if(action==='shuffle'){\r\n        if(!onlyKeys(input,['action','enabled'])||typeof input.enabled!=='boolean')throw error('Choose a valid shuffle setting.',422);\r\n        path+=`shuffle?state=${input.enabled}`;method='PUT';\r\n      }\r\n      if(action==='repeat'){\r\n        if(!onlyKeys(input,['action','mode'])||!['off','context','track'].includes(input.mode))throw error('Choose a valid repeat mode.',422);\r\n        path+=`repeat?state=${input.mode}`;method='PUT';\r\n      }\r\n      if(action==='track'||action==='queue'){\r\n        if(!onlyKeys(input,['action','trackId'])||!spotifyId(input.trackId))throw error('Choose a valid track.',422);\r\n        const uri=`spotify:track:${input.trackId}`;\r\n        if(action==='track'){path+='play';method='PUT';body={uris:[uri]};}\r\n        else{path+=`queue?uri=${encodeURIComponent(uri)}`;method='POST';}\r\n      }\r\n      if(action==='transfer'){\r\n        if(!onlyKeys(input,['action','deviceId'])||typeof input.deviceId!=='string'||!/^[A-Za-z0-9_-]{1,128}$/.test(input.deviceId))throw error('Choose a valid device.',422);\r\n        path='/me/player';method='PUT';body={device_ids:[input.deviceId],play:true};\r\n      }\r\n      if(['pause','resume','next','previous'].includes(action)&&!onlyKeys(input,['action']))throw error('Invalid playback control.',422);\r\n      await spotifyFetch(env,database,user,path,{method,body});return json({ok:true});\r\n    }\r\n    return json({error:'Not found.'},404);\r\n  }catch(e){if(e.code==='target_epoch_mismatch')return json({error:'Account data changed.',code:e.code},409);return json({error:e.status?e.message:'Spotify is unavailable.',code:e.code||'spotify_error'},e.status||500);}\r\n}\r\n","server/war-room.mjs":"import {readAccountPerformance} from './performance-progress.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {fail} from './domain.mjs';\r\n\r\n// These are the existing Gala family ids.  A selection is presentation data,\r\n// not an entitlement: this service never creates XP, tiers, or rewards.\r\nconst WEAPONS=new Set(['rapier','greatsword','dagger','sabre','axe','hammer','mace','flail','spear','trident','halberd','scythe','bow','crossbow','chakram','gauntlets','staff','wand','tome','cannon']);\r\nconst id=value=>typeof value==='string'&&/^[A-Za-z0-9_-]{1,80}$/.test(value);\r\nconst json=value=>JSON.stringify(value);\r\nconst parse=(value,fallback)=>{try{const parsed=JSON.parse(value);return parsed&&typeof parsed==='object'?parsed:fallback;}catch{return fallback;}};\r\nconst weapon=value=>{\r\n if(!value||typeof value!=='object'||!WEAPONS.has(value.type)||!Number.isInteger(value.tier)||value.tier<0||value.tier>20)fail('Choose a valid Gala weapon.');\r\n return {type:value.type,tier:value.tier};\r\n};\r\nconst recipe=value=>{\r\n if(!value||typeof value!=='object'||!id(value.id)||typeof value.name!=='string'||value.name.trim().length<1||value.name.trim().length>80||typeof value.data!=='string'||value.data.length<1||value.data.length>30000)fail('Choose a valid saved recipe.');\r\n return {id:value.id,name:value.name.trim(),data:value.data};\r\n};\r\n// Persisted rows are untrusted. Ignore malformed entries so an old or\r\n// interrupted save cannot prevent the owner from opening the War Room.\r\nconst storedWeapon=value=>{try{return weapon(value);}catch{return {type:'rapier',tier:0};}};\r\nconst storedRecipes=value=>{\r\n const parsed=parse(value,[]),items=Array.isArray(parsed)?parsed:[],seen=new Set(),valid=[];\r\n for(const item of items){try{const safe=recipe(item);if(!seen.has(safe.id)){seen.add(safe.id);valid.push(safe);}}catch{}if(valid.length===20)break;}\r\n return valid;\r\n};\r\nasync function current(database,user){\r\n return (await database.prepare('SELECT loadout,recipes,revision,updated_at FROM war_room_arsenals WHERE user_id=?').bind(user).first())||{loadout:json({type:'rapier',tier:0}),recipes:'[]',revision:0,updated_at:null};\r\n}\r\nconst safe=row=>({loadout:storedWeapon(parse(row.loadout,{type:'rapier',tier:0})),recipes:storedRecipes(row.recipes),revision:Number.isSafeInteger(Number(row.revision))&&Number(row.revision)>=0?Number(row.revision):0,updatedAt:row.updated_at==null?null:Number.isFinite(Number(row.updated_at))?Number(row.updated_at):null});\r\nasync function save(database,user,previous,next,now,dataEpoch){\r\n const result=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[database.prepare('INSERT INTO war_room_arsenals(user_id,loadout,recipes,revision,updated_at) VALUES(?,?,?,?,?) ON CONFLICT(user_id) DO UPDATE SET loadout=excluded.loadout,recipes=excluded.recipes,revision=war_room_arsenals.revision+1,updated_at=excluded.updated_at WHERE war_room_arsenals.revision=? RETURNING revision,updated_at').bind(user,json(next.loadout),json(next.recipes),1,now,previous.revision)]}))[0].results[0];\r\n if(!result)fail('War Room changed on another device. Refresh before saving.',409);\r\n return {...next,revision:Number(result.revision),updatedAt:Number(result.updated_at)};\r\n}\r\nexport async function warRoomApi(database,user,path,method,input,now=Date.now(),{dataEpoch=1}={}){\r\n const row=await current(database,user),state=safe(row);\r\n if(path==='/api/war-room'&&method==='GET')return {state};\r\n if(path==='/api/war-room/loadout'&&method==='PUT'){\r\n  if(!Number.isSafeInteger(input?.revision)||input.revision!==state.revision)fail('War Room changed on another device. Refresh before saving.',409);\r\n  const selected=weapon(input.loadout),performance=await readAccountPerformance(database,user);if(selected.tier>(performance.weapons[selected.type]??0)&&!(selected.type===state.loadout.type&&selected.tier<=state.loadout.tier))fail('Earn this weapon tier through its workout milestones.',403);\r\n  return {state:await save(database,user,state,{...state,loadout:selected},now,dataEpoch)};\r\n }\r\n if(path==='/api/war-room/recipes'&&method==='POST'){\r\n  if(!Number.isSafeInteger(input?.revision)||input.revision!==state.revision)fail('War Room changed on another device. Refresh before saving.',409);\r\n  const item=recipe(input.recipe);if(state.recipes.some(existing=>existing.id===item.id))fail('That recipe id already exists.',409);if(state.recipes.length>=20)fail('Keep up to 20 saved recipes.');\r\n  return {state:await save(database,user,state,{...state,recipes:[...state.recipes,item]},now,dataEpoch)};\r\n }\r\n if(path==='/api/war-room/import/profile'&&method==='POST'){\r\n  if(!Number.isSafeInteger(input?.revision)||input.revision!==state.revision)fail('War Room changed on another device. Refresh before importing.',409);\r\n  // This is deliberately opt-in and reads only the authenticated owner's\r\n  // established profile. Cookies, IPs, and an arbitrary supplied owner id can\r\n  // never claim a legacy Gala save.\r\n  const profile=await database.prepare('SELECT data FROM profiles WHERE user_id=?').bind(user).first();\r\n  const saved=parse(profile?.data,{}),avatar=parse(saved['mominc-avatar-v1'],{}),next={...state};\r\n  if(avatar.weapon){try{const legacy=weapon(avatar.weapon);const performance=await readAccountPerformance(database,user);if(legacy.tier<=(performance.weapons[legacy.type]??0)||legacy.type===state.loadout.type&&legacy.tier<=state.loadout.tier)next.loadout=legacy;}catch{/* malformed legacy appearance is ignored */}}\r\n  const legacyRecipe=saved['myr5-recipe-v1'];\r\n  if(typeof legacyRecipe==='string'&&legacyRecipe.length>0&&legacyRecipe.length<=30000&&!next.recipes.some(item=>item.id==='legacy-myr5'))next.recipes=[...next.recipes,{id:'legacy-myr5',name:'Imported MYR5 recipe',data:legacyRecipe}];\r\n  if(JSON.stringify(next.loadout)===JSON.stringify(state.loadout)&&JSON.stringify(next.recipes)===JSON.stringify(state.recipes))fail('No validated legacy War Room data is available for this account.',404);\r\n  return {state:await save(database,user,state,next,now,dataEpoch),imported:true};\r\n }\r\n const match=path.match(/^\\/api\\/war-room\\/recipes\\/([A-Za-z0-9_-]{1,80})$/);\r\n if(match&&method==='DELETE'){\r\n  if(!Number.isSafeInteger(input?.revision)||input.revision!==state.revision)fail('War Room changed on another device. Refresh before saving.',409);\r\n  const recipes=state.recipes.filter(item=>item?.id!==match[1]);if(recipes.length===state.recipes.length)fail('Recipe not found.',404);\r\n  return {state:await save(database,user,state,{...state,recipes},now,dataEpoch)};\r\n }\r\n fail('War Room action unavailable.',405);\r\n}\r\n","server/worker.mjs":"import {spotifyApi,spotifyCallback} from './spotify.mjs';\r\nimport {saveWorkoutPaths} from './workout-paths.mjs';\r\nimport {readAccountPerformance} from './performance-progress.mjs';\r\nimport {readAccountReadiness,scheduleAccountReadiness,refreshReminderHealth,trainingReadinessKey} from './account-readiness.mjs';\r\nimport {remoteAccountOperation} from './remote-account-operations.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {AccountDataEpochError,inspectAccountDataEpoch,deleteAccountDataAtEpoch} from './account-data-epochs.mjs';\r\nimport {importWorkout,WorkoutImportError} from './workout-import.mjs';\r\nimport {readExerciseRoute,assertRoundAvailable,completeRound,maximumRoundGoal} from './workout-route.mjs';\r\nimport {scoreboardApi,exportScoreboard,deleteScoreboard} from './scoreboard.mjs';\r\nimport {authConfig,identity,accountOwner,linkLegacy} from './auth.mjs';\r\nimport {galaApi} from './gala.mjs';\r\nimport {installDraft} from './install-draft.mjs';\r\nimport {readOnboarding,saveOnboarding} from './onboarding.mjs';\r\nimport {db} from './db.mjs';\r\nimport {remoteReminders,reminderService,ensureReminderMigration,queueReminderReconciliation,attemptReminderReconciliation} from './remote-reminders.mjs';\r\nimport {MODES,uuid,cleanText,fail,mealInput,progress,} from './domain.mjs';\r\nimport {runReminders} from './push.mjs';\r\nimport {runArmieLetterPushes} from './armie-scheduler.mjs';\r\nimport {runReleasePush} from './release-push.mjs';\r\nimport {RELEASE} from '../release-info.mjs';\r\nimport {trainingFromDaily} from '../weapon-training.mjs';\r\nimport {combatProgress,startBreathing,completeBreathing} from './combat.mjs';\r\nimport {circuitProgress} from '../circuit.mjs';\r\nimport {syncTrainingStatus} from './reminder-plan.mjs';\r\nimport {emailSubscription,emailLinkAction,emailLinkPage} from './release-email.mjs';\r\nimport {readEntitlements,recordCoachArmyCompletion,createCoachArmyBinding,claimCoachArmyBinding} from './entitlements.mjs';\r\nimport {startCoachArmyRun,readCoachArmyRun,recordBrowserCoachArmyEvent,recordVerifiedCoachArmyEvent,startDjscratchChallenge,recordDjscratchControl,deliverCoachArmyOutbox} from './coach-army-runs.mjs';\r\nimport {warRoomApi} from './war-room.mjs';\r\nimport {worldApi,worldDeletionStatements,settleDueWorldSectors} from './world-api.mjs';\r\nimport {exportWorldDrops} from './world-drops.mjs';\r\nimport {RECOVERY_HTML} from '../recovery-page.mjs';\r\nconst json=(data,status=200)=>new Response(JSON.stringify(data),{status,headers:{'Content-Type':'application/json','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}});\r\nasync function body(request){if(!request.headers.get('content-type')?.startsWith('application/json'))fail('Send JSON.',415);const reader=request.body?.getReader();if(!reader)fail('Empty request.');const chunks=[];let size=0;for(;;){const {done,value}=await reader.read();if(done)break;size+=value.byteLength;if(size>60000){await reader.cancel();fail('Request too large.',413);}chunks.push(value);}const bytes=new Uint8Array(size);let offset=0;for(const c of chunks){bytes.set(c,offset);offset+=c.byteLength;}let v;try{v=JSON.parse(new TextDecoder().decode(bytes));}catch{fail('Invalid request.');}if(!v||typeof v!=='object'||Array.isArray(v))fail('Invalid request.');return v;}\r\nasync function count(database,user){return Number((await database.prepare(`SELECT count(*) AS total FROM workouts WHERE user_id=? AND source='server' AND completed_at IS NOT NULL`).bind(user).first()).total);}\r\nasync function workoutProgress(database,user,now=Date.now(),includeCombat=true,onboarding=null,{recordLogin=true}={}){const rows=(await database.prepare(`SELECT mode,CAST(completed_at/86400000 AS INTEGER) AS day,COUNT(*) AS sets FROM workouts WHERE user_id=? AND source='server' AND completed_at IS NOT NULL GROUP BY mode,day`).bind(user).all()).results;const legacy=progress(rows.reduce((sum,row)=>sum+Number(row.sets),0)),performance=await readAccountPerformance(database,user,onboarding?.data?.profile?.timezone||'UTC');return {performance,exerciseRoute:await readExerciseRoute(database,user,onboarding,now),...legacy,unlocks:progress(Math.max(legacy.completedSets,Object.keys(performance.sessions).length)).unlocks,activeDays:new Set(rows.map(row=>row.day)).size,trainingVersion:1,training:trainingFromDaily(rows),trainingStatus:{startedDay:rows.length?rows.reduce((value,r)=>Math.min(value,r.day),Infinity):Math.floor(now/86400000),lastCompletedDay:rows.length?rows.reduce((value,r)=>Math.max(value,r.day),-Infinity):null},...(includeCombat?{combat:await combatProgress(database,user,now,{recordLogin}),circuit:await dailyCircuitProgress(database,user,rows,now)}:{})};}\r\n// Daily circuit (Rank 6, D15): reuses the same mode+day rows already fetched above, plus two\r\n// small distinct-day scans over breathing_sessions/meals (mirrors combatProgress's breathing\r\n// query -- UTC day, same as the rest of this file's daily-cap logic).\r\nasync function dailyCircuitProgress(database,user,rows,now){\r\n const [breathingDays,mealDays]=await Promise.all([\r\n  database.prepare(`SELECT DISTINCT CAST(completed_at/86400000 AS INTEGER) AS day FROM breathing_sessions WHERE user_id=? AND completed_at IS NOT NULL`).bind(user).all(),\r\n  database.prepare(`SELECT DISTINCT CAST(strftime('%s',eaten_at) AS INTEGER)/86400 AS day FROM meals WHERE user_id=?`).bind(user).all(),\r\n ]);\r\n return circuitProgress(rows,breathingDays.results.map(r=>r.day),mealDays.results.map(r=>r.day),Math.floor(now/86400000));\r\n}\r\nasync function api(request,env,ctx){const u=new URL(request.url),p=u.pathname,method=request.method;\r\n if(p==='/api/workouts/import'&&(method!=='POST'||env.WORKOUT_IMPORTS_ENABLED!=='true'))return json({error:'Not found.'},404);\r\n const database=db(env);\r\n if(p==='/api/spotify/callback'&&method==='GET')return spotifyCallback(request,env,database);\r\n if(p.startsWith('/api/gala/'))return galaApi(request,database,body);\r\n if(p==='/api/integrations/coach-army/completion'&&method==='POST'){\r\n  if(!env.COACH_ARMY_COMPLETION_SECRET||request.headers.get('Authorization')!==`Bearer ${env.COACH_ARMY_COMPLETION_SECRET}`)fail('Unauthorized.',401);\r\n  return json({entitlements:await recordCoachArmyCompletion(database,await body(request))});\r\n }\r\n if(p==='/api/integrations/coach-army/binding'&&method==='POST'){\r\n  if(!env.COACH_ARMY_COMPLETION_SECRET||request.headers.get('Authorization')!==`Bearer ${env.COACH_ARMY_COMPLETION_SECRET}`)fail('Unauthorized.',401);\r\n  return json({binding:await createCoachArmyBinding(database,await body(request))});\r\n }\r\n if(p==='/api/integrations/coach-army/run-events'&&method==='POST'){\r\n  if(!env.COACH_ARMY_COMPLETION_SECRET||request.headers.get('Authorization')!==`Bearer ${env.COACH_ARMY_COMPLETION_SECRET}`)fail('Unauthorized.',401);\r\n  const result=await recordVerifiedCoachArmyEvent(database,await body(request),Date.now());\r\n  return json({run:result.run,accepted:true,outbox:result.outbox||null});\r\n }\r\n if(p==='/api/releases/current'&&method==='GET')return json(RELEASE);\r\n if(['/api/updates/confirm','/api/updates/unsubscribe'].includes(p)){\r\n  const action=p.split('/').at(-1),token=u.searchParams.get('token');\r\n  if(method==='GET')return emailLinkPage(action,token);\r\n  if(method!=='POST')fail('Method not allowed.',405);\r\n  if(action==='confirm'&&request.headers.get('Origin')!==u.origin)fail('Confirm from the email link page.',403);\r\n  if(!/^[a-f0-9]{64}$/.test(token||''))fail('This email link is invalid.');\r\n  const result=remoteReminders(env)?await reminderService(env,'email-link',`/internal/release-email/${action}`,'POST',{token}):await emailLinkAction(env,action,token);\r\n  return emailLinkPage(action,token,result.message);\r\n }\r\n if(p==='/api/cron'&&method==='POST'){if(!env.CRON_SECRET||request.headers.get('Authorization')!==`Bearer ${env.CRON_SECRET}`)fail('Unauthorized.',401);if(remoteReminders(env))fail('The independent reminder service owns scheduling.',409);return json(await runReminders(env));}\r\n if(!['GET','HEAD'].includes(method)&&request.headers.get('Origin')!==u.origin)fail('Open this action from Coach.',403);\r\n if(p==='/api/auth/config'&&method==='GET')return json(authConfig(env));\r\n if(p==='/api/auth/link'&&method==='POST'){const v=await body(request);if(v.confirm!==true)fail('Confirm the account connection.');return json(await linkLegacy(database,await identity(request,env)));}\r\n if(p==='/api/install-draft')return installDraft(request,database,body);\r\n const id=await identity(request,env),user=await accountOwner(database,id),now=Date.now();\r\n // World homes and social state require a verified bearer identity on the public\r\n // Worker. Legacy forwarded headers are permitted only in our local test host.\r\n if((p==='/api/world'||p.startsWith('/api/world/'))&&!id.clerk&&env.LOCAL_PREVIEW!==true)fail('Sign in to your Mom Inc account to use the shared world.',401);\r\n if(p.startsWith('/api/spotify/'))return spotifyApi(request,env,database,user);\r\n if(p==='/api/performance/paths'&&method==='POST')return json(await saveWorkoutPaths(request,database,user,body));\r\n const accountReadProof=p==='/api/account'&&method==='GET'?await inspectAccountDataEpoch(database,user):null;\r\n const reminderRequest=p==='/api/updates/subscription'||p==='/api/reminders'||p.startsWith('/api/reminders/')||p.startsWith('/api/push/');\r\n const primaryWrite=(p==='/api/profile'&&method==='PUT')||(p==='/api/onboarding'&&method==='PUT')||(p==='/api/goals'&&method==='POST')||(p.startsWith('/api/goals/')&&method==='PATCH')||(p==='/api/meals'&&method==='POST')||(p.startsWith('/api/meals/')&&method==='DELETE')||(['/api/breathing/start','/api/breathing/complete'].includes(p)&&method==='POST');\r\n const socialWrite=!['GET','HEAD'].includes(method)&&(p.startsWith('/api/war-room/')||p.startsWith('/api/scoreboard/')||p==='/api/world'||p.startsWith('/api/world/'));\r\n let workoutWriteProof=null;\r\n if((method==='POST'&&p.startsWith('/api/coach-army/'))||socialWrite||primaryWrite||(method==='POST'&&['/api/workouts/start','/api/workouts/complete'].includes(p))||(reminderRequest&&!['GET','HEAD'].includes(method))){\r\n  const target=request.headers.get('X-Target-Account'),rawEpoch=request.headers.get('X-Expected-Data-Epoch');\r\n  if(target===null||rawEpoch===null)throw Object.assign(Error('Refresh account details before saving.'),{status:428,code:'account_assertion_required'});\r\n  if(target!==user)throw Object.assign(Error('Account changed.'),{status:409,code:'target_mismatch'});\r\n  if(!/^[1-9][0-9]*$/.test(rawEpoch)||!Number.isSafeInteger(Number(rawEpoch)))throw Object.assign(Error('Invalid account generation.'),{status:422,code:'invalid_account_epoch'});\r\n  workoutWriteProof=await inspectAccountDataEpoch(database,user);\r\n  if(workoutWriteProof.currentDataEpoch!==Number(rawEpoch))throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});\r\n }\r\n const reminderProof=reminderRequest?(workoutWriteProof||await inspectAccountDataEpoch(database,user)):null;\r\n if(p==='/api/world'||p.startsWith('/api/world/')){\r\n  if(env.REMINDER_INTERNAL===true)fail('Not found.',404);\r\n  const proof=workoutWriteProof||await inspectAccountDataEpoch(database,user);\r\n  const result=await worldApi(request,database,user,p,method,['GET','HEAD'].includes(method)?{}:await body(request),now,{dataEpoch:proof.currentDataEpoch});\r\n  if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==proof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});\r\n  return json(result);\r\n }\r\n const exportProof=p==='/api/export'?await inspectAccountDataEpoch(database,user):null;\r\n const onboarding=env.REMINDER_INTERNAL===true?null:await readOnboarding(database,user,now);\r\n if(p==='/api/workouts/import'&&method==='POST'){\r\n  if(request.headers.get('X-Target-Account')!==user)throw Object.assign(Error('target_mismatch'),{status:409,code:'target_mismatch'});\r\n  const input=await body(request);\r\n  try{\r\n   const result=await importWorkout(database,{ownerId:user,targetAccountId:request.headers.get('X-Target-Account'),idempotencyKey:request.headers.get('Idempotency-Key'),body:input,now});\r\n   return json({workout:result.workout,receipt:result.receipt},result.status);\r\n  }catch(error){\r\n   if(error instanceof WorkoutImportError){if(error.status===400)error.status=422;throw error;}\r\n   throw Object.assign(Error('Import temporarily unavailable.'),{status:503,code:'import_unavailable'});\r\n  }\r\n }\r\n if(p==='/api/war-room'&&method==='GET'){const proof=await inspectAccountDataEpoch(database,user),room=await warRoomApi(database,user,p,method,null,now);if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==proof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});return json({...room,targetAccountId:user,dataEpoch:proof.currentDataEpoch});}\r\n if(p==='/api/war-room/loadout'&&method==='PUT')return json(await warRoomApi(database,user,p,method,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch}));\r\n if(p==='/api/war-room/recipes'&&method==='POST')return json(await warRoomApi(database,user,p,method,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch}));\r\n if(p==='/api/war-room/import/profile'&&method==='POST')return json(await warRoomApi(database,user,p,method,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch}));\r\n if(/^\\/api\\/war-room\\/recipes\\/[A-Za-z0-9_-]{1,80}$/.test(p)&&method==='DELETE')return json(await warRoomApi(database,user,p,method,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch}));\r\n if(p==='/api/coach-army/runs'&&method==='POST')return json({run:await startCoachArmyRun(database,user,now,{dataEpoch:workoutWriteProof.currentDataEpoch})},201);\r\n const coachArmyRun=p.match(/^\\/api\\/coach-army\\/runs\\/([0-9a-f-]{36})(?:\\/events)?$/i);\r\n if(coachArmyRun&&method==='GET'&&!p.endsWith('/events'))return json({run:await readCoachArmyRun(database,coachArmyRun[1],user)});\r\n if(coachArmyRun&&method==='POST'&&p.endsWith('/events')){const result=await recordBrowserCoachArmyEvent(database,{...(await body(request)),runId:coachArmyRun[1],dataEpoch:workoutWriteProof.currentDataEpoch},user,now);return json({run:result.run,accepted:true,evidence:result.evidence||null,replay:result.replay});}\r\n const djscratch=p.match(/^\\/api\\/coach-army\\/runs\\/([0-9a-f-]{36})\\/djscratch(?:\\/controls)?$/i);\r\n if(djscratch&&method==='POST'&&!p.endsWith('/controls'))return json({challenge:await startDjscratchChallenge(database,djscratch[1],user,now,{dataEpoch:workoutWriteProof.currentDataEpoch})});\r\n if(djscratch&&method==='POST'&&p.endsWith('/controls'))return json(await recordDjscratchControl(database,{...(await body(request)),runId:djscratch[1],dataEpoch:workoutWriteProof.currentDataEpoch},user,now));\r\n if(p==='/api/coach-army/claim'&&method==='POST')return json({entitlements:await claimCoachArmyBinding(database,{...(await body(request)),accountId:user,dataEpoch:workoutWriteProof.currentDataEpoch},now)});\r\n if(p==='/api/scoreboard'||p.startsWith('/api/scoreboard/')){const proof=workoutWriteProof||await inspectAccountDataEpoch(database,user),result=await scoreboardApi(database,user,p,method,method==='POST'?await body(request):{},now,{dataEpoch:proof.currentDataEpoch});if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==proof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});return json({...result,targetAccountId:user,dataEpoch:proof.currentDataEpoch});}\r\n if(p==='/api/updates/subscription'){const input=method==='POST'?await body(request):{};return json(remoteReminders(env)?await reminderService(env,user,p,method,method==='POST'?input:undefined,reminderProof):await emailSubscription(env,user,method,input,now,{dataEpoch:reminderProof.currentDataEpoch}));}\r\n if(p==='/api/onboarding'&&method==='PUT')return json(await saveOnboarding(database,user,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch}));\r\n if(env.REMINDER_INTERNAL!==true&&!onboarding&&method!=='GET'&&(p==='/api/workouts/start'||p.startsWith('/api/breathing/')||p==='/api/meals'||p.startsWith('/api/reminders')||p==='/api/push/subscribe'))fail('Answer the three setup questions to start Coach.',403);\r\n if(p==='/api/reminders'||p.startsWith('/api/reminders/')||p.startsWith('/api/push/')){if(remoteReminders(env)){await ensureReminderMigration(env,user,reminderProof);return json(await reminderService(env,user,p,method,['POST','PUT','PATCH'].includes(method)?await body(request):undefined,reminderProof));}return json(await remoteAccountOperation(request,env,user,reminderProof.currentDataEpoch,now));}\r\n if(p==='/api/account/readiness'&&method==='GET'){\r\n  // Optional observations only; this response is never account authority.\r\n  const proof=await inspectAccountDataEpoch(database,user);\r\n  let push,health=null;\r\n  if(remoteReminders(env)){health=await refreshReminderHealth(database,env,user);push={configured:false,publicKey:null,schedulerActive:false,...health.push,status:health.state};}\r\n  else {const tick=await database.prepare(\"SELECT value FROM system WHERE key='scheduler_tick'\").first();push={configured:!!env.VAPID_PUBLIC_KEY,publicKey:env.VAPID_PUBLIC_KEY||null,schedulerActive:!!tick&&now-Number(tick.value)<300000,status:'ready'};}\r\n  const readiness=await readAccountReadiness(database,user,proof.currentDataEpoch);\r\n  if(health&&(!Number.isSafeInteger(readiness.reminders.startedAt)||health.startedAt>readiness.reminders.startedAt||(health.startedAt===readiness.reminders.startedAt&&health.observationId>=readiness.reminders.observationId)))readiness.reminders=health;\r\n  if(readiness.reminders.push)push={...readiness.reminders.push,status:readiness.reminders.state};\r\n  if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==proof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});\r\n  return json({targetAccountId:user,dataEpoch:proof.currentDataEpoch,readiness,push:{...push,environment:env.LOCAL_PREVIEW?'preview':'live'},checkedAt:Date.now()});\r\n }\r\n if(p==='/api/account'&&method==='GET'){\r\n  const [profile,total,tick,entitlements]=await Promise.all([database.prepare('SELECT * FROM profiles WHERE user_id=?').bind(user).first(),workoutProgress(database,user,now,env.REMINDER_INTERNAL!==true,onboarding,{recordLogin:false}),database.prepare(\"SELECT value FROM system WHERE key='scheduler_tick'\").first(),readEntitlements(database,user)]);\r\n  let push={configured:!!env.VAPID_PUBLIC_KEY,publicKey:env.VAPID_PUBLIC_KEY||null,schedulerActive:!!tick&&now-Number(tick.value)<300000};\r\n  if(remoteReminders(env)){\r\n   push={configured:false,publicKey:null,schedulerActive:false,status:'pending'};\r\n\r\n   if(typeof ctx?.waitUntil==='function'){\r\n    const queued=await database.prepare('SELECT value FROM system WHERE key=?').bind(`remote-deletion:${user}`).first();\r\n    if(queued)ctx.waitUntil(Promise.resolve().then(()=>attemptReminderReconciliation(env,user,JSON.parse(queued.value))).catch(()=>{}));\r\n   }\r\n  }\r\n  // Epoch was captured before onboarding/profile/progress reads; a concurrent\r\n  // deletion makes this mixed read unsuitable for a fresh account snapshot.\r\n  const current=await inspectAccountDataEpoch(database,user);\r\n  if(current.currentDataEpoch!==accountReadProof.currentDataEpoch)throw Object.assign(Error('Account data changed. Refresh to continue.'),{status:409,code:'account_epoch_changed'});\r\n  const readiness=await readAccountReadiness(database,user,accountReadProof.currentDataEpoch,now);\r\n  if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==accountReadProof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'account_epoch_changed'});\r\n  if(remoteReminders(env)&&readiness.reminders.push)push={...readiness.reminders.push,status:readiness.reminders.state};\r\n  scheduleAccountReadiness(ctx,database,env,user,accountReadProof,total.trainingStatus);\r\n  return json({user:{id:user,email:id.email,provider:id.clerk?'clerk':'chatgpt'},dataEpoch:accountReadProof.currentDataEpoch,deletionEvidence:accountReadProof,profile:profile?JSON.parse(profile.data):{},revision:profile?.revision||0,onboarding,progress:total,entitlements,readiness,push:{...push,environment:env.LOCAL_PREVIEW?'preview':'live'},syncedAt:now});\r\n }\r\n if(p==='/api/goals'&&method==='GET')return json({items:(await database.prepare('SELECT id,title,note,status,created_at,updated_at FROM goals WHERE user_id=? ORDER BY updated_at DESC').bind(user).all()).results});\r\n if(p==='/api/goals'&&method==='POST'){const v=await body(request),title=cleanText(v.title,160),note=v.note==null||v.note===''?'':cleanText(v.note,1000);if(!title)fail('Add a title for this goal.');const id=uuid(v.id||crypto.randomUUID());await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare('INSERT INTO goals(id,user_id,title,note,status,created_at,updated_at) VALUES(?,?,?,?,?,?,?)').bind(id,user,title,note,'active',now,now)]});return json({saved:true,id});}\r\n if(p.startsWith('/api/goals/')&&method==='PATCH'){const id=uuid(p.split('/').at(-1)),v=await body(request),changes=[];if(v.title!==undefined){const title=cleanText(v.title,160);if(!title)fail('Add a title for this goal.');changes.push(['title',title]);}if(v.note!==undefined)changes.push(['note',v.note===''?'':cleanText(v.note,1000)]);if(v.status!==undefined){if(!['active','completed','archived'].includes(v.status))fail('Choose active, completed, or archived.');changes.push(['status',v.status]);}if(!changes.length)fail('Nothing to save.');const sets=changes.map(([key])=>`${key}=?`).join(','),saved=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare(`UPDATE goals SET ${sets},updated_at=? WHERE id=? AND user_id=? RETURNING id`).bind(...changes.map(([,value])=>value),now,id,user)]}))[0].results[0];if(!saved)fail('Goal not found.',404);return json({saved:true});}\r\n if(p==='/api/profile'&&method==='PUT'){const v=await body(request);if(!Number.isSafeInteger(v.revision)||!v.data||typeof v.data!=='object'||Array.isArray(v.data))fail('Invalid profile.');const allowed=['myr5-recipe-v1','myr5-motion-v1','mominc-avatar-v1','myr5-pod-power-v1','handborne-recipe-v4','mbs-dj-identity-v1'];const safe={};for(const k of allowed){if(v.data[k]!=null){if(typeof v.data[k]!=='string'||v.data[k].length>30000)fail('Appearance is too large.');safe[k]=v.data[k];}}const result=(await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare('INSERT INTO profiles(user_id,data,revision,updated_at) VALUES(?,?,1,?) ON CONFLICT(user_id) DO UPDATE SET data=excluded.data,revision=profiles.revision+1,updated_at=excluded.updated_at WHERE profiles.revision=? RETURNING revision').bind(user,JSON.stringify(safe),now,v.revision)]}))[0].results[0];if(!result)fail('Appearance changed on another device. Restore it before saving again.',409);return json(result);}\r\n if(env.REMINDER_INTERNAL!==true&&p==='/api/breathing/start'&&method==='POST'){const ticket=await startBreathing(database,user,now,{dataEpoch:workoutWriteProof.currentDataEpoch});if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==workoutWriteProof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});return json({...ticket,targetAccountId:user,dataEpoch:workoutWriteProof.currentDataEpoch});}\r\n if(env.REMINDER_INTERNAL!==true&&p==='/api/breathing/complete'&&method==='POST'){const combat=await completeBreathing(database,user,await body(request),now,{dataEpoch:workoutWriteProof.currentDataEpoch});if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==workoutWriteProof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});return json({combat,targetAccountId:user,dataEpoch:workoutWriteProof.currentDataEpoch});}\r\n if(p==='/api/workouts/start'&&method==='POST'){const v=await body(request);if(!Object.hasOwn(MODES,v.mode)||(!Number.isSafeInteger(v.goal)||v.goal<1||v.goal>await maximumRoundGoal(database,user,v.mode,onboarding.targets.goals[v.mode]??0)))fail('Choose a valid exercise and goal.');await assertRoundAvailable(database,user,v.mode,onboarding?.data?.profile?.timezone||'UTC',now);const recent=await database.prepare(`SELECT count(*) AS n FROM workouts WHERE user_id=? AND source='server' AND started_at>?`).bind(user,now-60000).first();if(recent.n>=12)fail('Please wait a moment before starting again.',429);const id=crypto.randomUUID();await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare(`INSERT INTO workouts(id,user_id,mode,goal,started_at) VALUES(?,?,?,?,?)`).bind(id,user,v.mode,v.goal,now)]});return json({id,startedAt:now,targetAccountId:user,dataEpoch:workoutWriteProof.currentDataEpoch});}\r\n if(p==='/api/workouts/complete'&&method==='POST'){const v=await body(request),id=uuid(v.id),w=await database.prepare(`SELECT * FROM workouts WHERE id=? AND user_id=? AND source='server'`).bind(id,user).first();if(!w)fail('Workout not found.',404);await completeRound(database,user,w,v,onboarding?.data?.profile?.timezone||'UTC',now,{dataEpoch:workoutWriteProof.currentDataEpoch});const progress=await workoutProgress(database,user,now,env.REMINDER_INTERNAL!==true,onboarding,{recordLogin:false});if(remoteReminders(env))try{await reminderService(env,user,'/internal/training-status','POST',progress.trainingStatus,workoutWriteProof);}catch{}else await syncTrainingStatus(database,user,progress.trainingStatus,now,{dataEpoch:workoutWriteProof.currentDataEpoch});if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==workoutWriteProof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'target_epoch_mismatch'});return json({progress,targetAccountId:user,dataEpoch:workoutWriteProof.currentDataEpoch});}\r\n if(p==='/api/workouts'&&method==='GET')return json({items:(await database.prepare('SELECT id,mode,goal,value,completed_at FROM workouts WHERE user_id=? AND completed_at IS NOT NULL ORDER BY completed_at DESC LIMIT 100').bind(user).all()).results});\r\n if(p==='/api/achievements'&&method==='GET')return json({items:(await database.prepare('SELECT mode,COUNT(*) AS sets,MAX(value) AS best,SUM(value) AS total FROM workouts WHERE user_id=? AND completed_at IS NOT NULL GROUP BY mode').bind(user).all()).results});\r\n if(p==='/api/meals'&&method==='GET')return json({items:(await database.prepare('SELECT * FROM meals WHERE user_id=? ORDER BY eaten_at DESC LIMIT 100').bind(user).all()).results});\r\n if(p==='/api/meals'&&method==='POST'){const v=mealInput(await body(request));await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare('INSERT INTO meals(id,user_id,name,portion,calories,protein,carbs,fat,micros,nutrition_source,eaten_at,created_at) VALUES(?,?,?,?,?,?,?,?,?,?,?,?) ON CONFLICT(id) DO NOTHING').bind(v.id,user,v.name,v.portion,v.calories,v.protein,v.carbs,v.fat,JSON.stringify(v.micros),v.nutritionSource,v.eatenAt,now)]});return json({saved:true});}\r\n if(p.startsWith('/api/meals/')&&method==='DELETE'){await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:workoutWriteProof.currentDataEpoch,now,statements:[database.prepare('DELETE FROM meals WHERE id=? AND user_id=?').bind(uuid(p.split('/').at(-1)),user)]});return json({deleted:true});}\r\n  if(p==='/api/export'&&method==='GET'){const tables=['workout_path_choices','profiles','onboarding','workouts','meals','reminders','goals','war_room_arsenals'].filter(t=>t!=='onboarding'||env.REMINDER_INTERNAL!==true);const data={spotify_connections:(await database.prepare('SELECT spotify_user_id,display_name,scopes,data_epoch,updated_at FROM spotify_connections WHERE user_id=?').bind(user).all()).results};for(const table of tables)data[table]=(await database.prepare(`SELECT * FROM ${table} WHERE user_id=?`).bind(user).all()).results;if(remoteReminders(env)){await ensureReminderMigration(env,user,exportProof);data.reminders=(await reminderService(env,user,'/api/reminders','GET',undefined,exportProof)).items;data.releaseEmails=await reminderService(env,user,'/api/updates/subscription','GET',undefined,exportProof);}if(env.REMINDER_INTERNAL!==true){\r\n for(const table of ['account_entitlements','account_pack_entitlements','coach_army_completions'])data[table]=(await database.prepare(`SELECT * FROM ${table} WHERE user_id=?`).bind(user).all()).results;\r\n for(const table of ['coach_army_runs','coach_army_run_events','coach_army_completion_outbox','coach_army_djscratch_challenges'])data[table]=(await database.prepare(`SELECT * FROM ${table} WHERE account_id=?`).bind(user).all()).results;\r\n data.coach_army_bindings=(await database.prepare('SELECT binding_id,run_id,account_id,event_id,completed_at,expires_at,claimed_at,created_at,data_epoch FROM coach_army_bindings WHERE account_id=?').bind(user).all()).results;\r\n data.worldDrops=await exportWorldDrops(database,user);data.scoreboard=await exportScoreboard(database,user);data.combat=await combatProgress(database,user,now,{recordLogin:false});for(const table of ['login_days','breathing_sessions'])data[table]=(await database.prepare(`SELECT * FROM ${table} WHERE user_id=?`).bind(user).all()).results;}if(!remoteReminders(env))data.releaseEmails=await emailSubscription(env,user,'GET');data.deletionEvidence=exportProof;data.deletionReceipts=(await database.prepare('SELECT owner_id,deleted_epoch,deleted_at FROM account_data_deletions WHERE owner_id=? ORDER BY deleted_epoch').bind(user).all()).results;data.workoutImports=(await database.prepare('SELECT i.* FROM workout_imports i JOIN workouts w ON w.id=i.workout_id WHERE w.user_id=?').bind(user).all()).results;data.competitiveDecisions=(await database.prepare('SELECT d.* FROM competitive_decisions d JOIN workouts w ON w.id=d.workout_id WHERE w.user_id=?').bind(user).all()).results;if((await inspectAccountDataEpoch(database,user)).currentDataEpoch!==exportProof.currentDataEpoch)throw Object.assign(Error('Account data changed.'),{status:409,code:'account_epoch_changed'});return json(data);}\r\n  if(p==='/api/account'&&method==='DELETE'){\r\n   const target=request.headers.get('X-Target-Account');\r\n   if(target===null)throw Object.assign(Error('Refresh account details before deleting.'),{status:428,code:'account_target_required'});\r\n   if(target!==user)throw Object.assign(Error('Account changed. Refresh before deleting.'),{status:409,code:'target_mismatch'});\r\n   const v=await body(request);\r\n   if(!Object.hasOwn(v,'expectedDataEpoch'))throw Object.assign(Error('Refresh account details before deleting.'),{status:428,code:'account_epoch_required'});\r\n   if(!Number.isSafeInteger(v.expectedDataEpoch)||v.expectedDataEpoch<1||v.expectedDataEpoch>=Number.MAX_SAFE_INTEGER||Object.keys(v).some(key=>!['confirm','expectedDataEpoch'].includes(key)))throw Object.assign(Error('Invalid account deletion request.'),{status:422,code:'invalid_account_epoch'});\r\n   if(v.confirm!=='DELETE')fail('Type DELETE to clear your Coach data.');\r\n   let proof;\r\n   try{proof=await deleteAccountDataAtEpoch(database,{ownerId:user,expectedDataEpoch:v.expectedDataEpoch,now,deletions:[...(env.REMINDER_INTERNAL===true?[]:worldDeletionStatements(database,user)),database.prepare('DELETE FROM system WHERE key=?').bind(trainingReadinessKey(user)),...(env.REMINDER_INTERNAL===true?[]:deleteScoreboard(database,user)),database.prepare('DELETE FROM deliveries WHERE endpoint IN (SELECT endpoint FROM subscriptions WHERE user_id=?) OR reminder_id IN (SELECT id FROM reminders WHERE user_id=?)').bind(user,user),database.prepare('DELETE FROM coach_army_djscratch_challenges WHERE account_id=?').bind(user),database.prepare('DELETE FROM coach_army_bindings WHERE account_id=?').bind(user),database.prepare('DELETE FROM coach_army_completion_outbox WHERE account_id=?').bind(user),database.prepare('DELETE FROM coach_army_run_events WHERE account_id=?').bind(user),database.prepare('DELETE FROM coach_army_runs WHERE account_id=?').bind(user),...['test:','training:','coach-plan:'].map(prefix=>database.prepare('DELETE FROM system WHERE key=?').bind(prefix+user)),database.prepare('DELETE FROM system WHERE substr(key,1,length(key)-10)=?').bind('notify-budget:'+user+':'),...['spotify_connections','spotify_oauth_states','workout_path_choices','profiles','onboarding','workouts','meals','reminders','goals','war_room_arsenals','subscriptions','release_subscribers','release_deliveries','login_days','armie_letter_deliveries','breathing_sessions','account_entitlements','account_pack_entitlements','coach_army_completions'].filter(t=>!['onboarding','login_days','breathing_sessions'].includes(t)||env.REMINDER_INTERNAL!==true).map(t=>database.prepare(`DELETE FROM ${t} WHERE user_id=?`).bind(user)),...(remoteReminders(env)?[queueReminderReconciliation(database,user,v.expectedDataEpoch+1,now)]:[])]});}\r\n   catch(error){if(error instanceof AccountDataEpochError&&error.code==='epoch-mismatch')throw Object.assign(Error('Account data changed. Refresh before deleting.'),{status:409,code:'target_epoch_mismatch'});throw error;}\r\n   const remote=remoteReminders(env)?await attemptReminderReconciliation(env,user,proof):{status:'not_configured'};\r\n   return json({deleted:!proof.alreadyDeleted,deletedEpoch:v.expectedDataEpoch,...proof,dataEpoch:proof.currentDataEpoch,deletionEvidence:{ownerId:proof.ownerId,currentDataEpoch:proof.currentDataEpoch,deletedThroughEpoch:proof.deletedThroughEpoch},remote});\r\n  }\r\n return json({error:'Not found.'},404);\r\n}\r\nexport default {\r\n async fetch(request,env,ctx){try{const url=new URL(request.url);if(url.pathname==='/repair-coach')return new Response(RECOVERY_HTML,{headers:{'Content-Type':'text/html; charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}});if(url.pathname.startsWith('/api/'))return await api(request,env,ctx);if(url.pathname==='/health'){let reminders=null;if(remoteReminders(env)){try{const status=await reminderService(env,'health','/internal/status');reminders={available:true,configured:status.configured,schedulerActive:status.schedulerActive};}catch{reminders={available:false,configured:false,schedulerActive:false};}}else{const tick=await db(env).prepare(\"SELECT value FROM system WHERE key='scheduler_tick'\").first().catch(()=>null),age=tick?Math.floor((Date.now()-Number(tick.value))/1000):null;reminders={mode:'worker-cron',lastTickAgeS:age,active:age!==null&&age<300};}return json({ok:true,app:'MYR5 Coach',reminders});}if(url.pathname==='/')return Response.redirect(new URL('/pose.html',url),302);if(url.pathname==='/icons/coach-512.png'&&env.ASSETS){const canonical=new URL(url);canonical.pathname='/icons/myr5-alien-512.png';return env.ASSETS.fetch(new Request(canonical,request));}if(env.ASSETS)return env.ASSETS.fetch(request);return new Response('Not found',{status:404});}catch(e){if(e.code==='target_epoch_mismatch'&&!e.status)e.status=409;if(!e.status)console.error('Coach request failed',e.message);return json({error:e.status?e.message:'Could not complete this request. Please try again.',...(e.status&&e.code?{code:e.code}:{})},e.status||500);}},\r\n async scheduled(event,env,ctx){if(!remoteReminders(env)){ctx.waitUntil(runReminders(env));ctx.waitUntil(runArmieLetterPushes(env));ctx.waitUntil(runReleasePush(env,Date.now(),RELEASE).catch(e=>console.error('Release push failed',e.message)));}if(env.REMINDER_INTERNAL!==true)ctx.waitUntil(settleDueWorldSectors(db(env)).catch(e=>console.error('World maintenance failed',e.message)));ctx.waitUntil(deliverCoachArmyOutbox(db(env),env));}\r\n};\r\n","server/workout-import.mjs":"import {WorkoutImportCodecError,validateImportSnapshot,fingerprintImportSnapshot,importIdempotencyKey,canonicalImportKey} from '../workout-import-codec.mjs';\r\nimport {readAccountDataEpoch,inspectAccountDataEpoch} from './account-data-epochs.mjs';\r\n\r\nexport class WorkoutImportError extends Error {\r\n constructor(code,status=400){super(code);this.name='WorkoutImportError';this.code=code;this.status=status;}\r\n}\r\nconst fail=(code,status)=>{throw new WorkoutImportError(code,status);};\r\nfunction requestBody(raw){\r\n try{\r\n  if(!raw||typeof raw!=='object'||Array.isArray(raw)||![Object.prototype,null].includes(Object.getPrototypeOf(raw)))fail('invalid_workout_import');\r\n  const descriptors=Object.getOwnPropertyDescriptors(raw),keys=['digestVersion','targetDataEpoch','snapshot','fingerprint'];\r\n  if(Reflect.ownKeys(descriptors).length!==keys.length||keys.some(key=>!descriptors[key]||!Object.hasOwn(descriptors[key],'value')||!descriptors[key].enumerable))fail('invalid_workout_import');\r\n  return Object.fromEntries(keys.map(key=>[key,descriptors[key].value]));\r\n }catch{fail('invalid_workout_import');}\r\n}\r\nfunction response(row,status){\r\n const {id,user_id,mode,goal,started_at,completed_at,value,active,source,client_workout_id,competitive_status}=row;\r\n return {status,workout:{id,user_id,mode,goal,started_at,completed_at,value,active,source,client_workout_id,competitive_status},\r\n  receipt:{targetAccountId:user_id,targetDataEpoch:row.account_data_epoch,digestVersion:row.digest_version,fingerprint:row.fingerprint,idempotencyKey:row.idempotency_key}};\r\n}\r\nconst lookup=(database,ownerId,clientWorkoutId)=>database.prepare(`\r\n SELECT w.*,i.idempotency_key,i.fingerprint,i.digest_version,i.account_data_epoch,COALESCE(e.epoch,1) AS current_data_epoch\r\n FROM workouts w LEFT JOIN workout_imports i ON i.workout_id=w.id\r\n LEFT JOIN account_data_epochs e ON e.owner_id=w.user_id\r\n WHERE w.user_id=? AND w.client_workout_id=?`).bind(ownerId,clientWorkoutId).first();\r\nfunction compare(row,request){\r\n if(row.current_data_epoch!==request.targetDataEpoch)fail('target_epoch_mismatch',409);\r\n if(row.source!=='guest_import'||row.competitive_status!=='not_eligible'||row.fingerprint!==request.fingerprint||row.idempotency_key!==request.idempotencyKey||row.digest_version!==request.digestVersion||row.account_data_epoch!==request.targetDataEpoch)fail('fingerprint_conflict',409);\r\n}\r\n\r\n// This helper does not authenticate requests. The caller must gate the route,\r\n// validate origin/auth, and supply its canonical authenticated owner. The target\r\n// assertion is only a consistency check and cannot select another owner.\r\nexport async function importWorkout(database,{ownerId,targetAccountId,idempotencyKey,body,now=Date.now()}){\r\n if(typeof ownerId!=='string'||!ownerId||ownerId.length>512||ownerId.trim()!==ownerId||/[\\u0000-\\u001f\\u007f]/.test(ownerId))fail('invalid_authenticated_owner',500);\r\n if(targetAccountId!==ownerId)fail('target_account_mismatch',409);\r\n if(!Number.isSafeInteger(now)||now<0)fail('invalid_server_time',500);\r\n let request;\r\n try{\r\n  const input=requestBody(body),snapshot=validateImportSnapshot(input.snapshot);\r\n  const keyInput={digestVersion:input.digestVersion,targetAccountId:ownerId,targetDataEpoch:input.targetDataEpoch,clientWorkoutId:snapshot.clientWorkoutId,fingerprint:input.fingerprint};\r\n  canonicalImportKey(keyInput);\r\n  if(typeof idempotencyKey!=='string'||!(/^[0-9a-f]{64}$/).test(idempotencyKey))fail('invalid_idempotency_key');\r\n  const fingerprint=await fingerprintImportSnapshot(snapshot,input.digestVersion);\r\n  if(fingerprint!==input.fingerprint)fail('invalid_fingerprint');\r\n  if(await importIdempotencyKey(keyInput)!==idempotencyKey)fail('invalid_idempotency_key');\r\n  request={snapshot,digestVersion:input.digestVersion,targetDataEpoch:input.targetDataEpoch,fingerprint,idempotencyKey};\r\n }catch(error){if(error instanceof WorkoutImportCodecError)fail(error.code,error.code==='crypto_unavailable'?500:400);throw error;}\r\n const {snapshot}=request;\r\n const prior=await lookup(database,ownerId,snapshot.clientWorkoutId);\r\n if(prior){compare(prior,request);return response(prior,200);}\r\n\r\n // Version 1 adds no age/freshness or goal-completion policy beyond the pinned\r\n // codec. Partial personal history remains valid and never becomes authoritative.\r\n await readAccountDataEpoch(database,ownerId,now);\r\n const id=globalThis.crypto.randomUUID();\r\n await database.batch([\r\n  database.prepare(`INSERT INTO workouts(id,user_id,mode,goal,started_at,completed_at,value,active,source,client_workout_id,competitive_status,performance_snapshot)\r\n   SELECT ?,?,?,?,?,?,?,?,'guest_import',?,NULL,? FROM account_data_epochs WHERE owner_id=? AND epoch=?\r\n   ON CONFLICT(user_id,client_workout_id) WHERE client_workout_id IS NOT NULL DO NOTHING`).bind(id,ownerId,snapshot.mode,snapshot.goal,snapshot.startedAt,snapshot.completedAt,snapshot.value,snapshot.activeSeconds,snapshot.clientWorkoutId,snapshot.performance?JSON.stringify(snapshot):null,ownerId,request.targetDataEpoch),\r\n  database.prepare(`INSERT INTO workout_imports(workout_id,idempotency_key,fingerprint,digest_version,account_data_epoch,created_at)\r\n   SELECT id,?,?,?,?,? FROM workouts WHERE id=? AND user_id=?`).bind(request.idempotencyKey,request.fingerprint,request.digestVersion,request.targetDataEpoch,now,id,ownerId),\r\n\r\n ]);\r\n const persisted=await lookup(database,ownerId,snapshot.clientWorkoutId);\r\n if(!persisted){\r\n  const epoch=await inspectAccountDataEpoch(database,ownerId);\r\n  if(epoch.currentDataEpoch!==request.targetDataEpoch)fail('target_epoch_mismatch',409);\r\n  fail('import_not_persisted',500);\r\n }\r\n compare(persisted,request);\r\n return response(persisted,persisted.id===id?201:200);\r\n}\r\n","server/workout-paths.mjs":"import {CHOOSABLE_TRACKS} from '../performance-catalog.mjs';\r\nimport {inspectAccountDataEpoch} from './account-data-epochs.mjs';\r\nimport {epochFencedBatch} from './remote-epochs.mjs';\r\n\r\nconst fail=(message,status,code)=>{throw Object.assign(Error(message),{status,code});};\r\nconst samePair=(a,b)=>a.length===2&&b.length===2&&a.every(id=>b.includes(id));\r\n\r\n/** An authenticated account's one-time path choice. The server stores only path IDs;\r\n * all coach access is reconstructed from the canonical catalogue and earned history. */\r\nexport async function saveWorkoutPaths(request,database,user,readBody){\r\n if(request.method!=='POST')fail('Method not allowed.',405,'method_not_allowed');\r\n if(request.headers.get('Origin')!==new URL(request.url).origin)fail('Open this action from Coach.',403,'origin_mismatch');\r\n const target=request.headers.get('X-Target-Account'),rawEpoch=request.headers.get('X-Expected-Data-Epoch');\r\n if(!target||!rawEpoch)fail('Refresh account details before saving.',428,'account_assertion_required');\r\n if(target!==user)fail('Account changed.',409,'target_mismatch');\r\n if(!/^[1-9][0-9]*$/.test(rawEpoch)||!Number.isSafeInteger(Number(rawEpoch)))fail('Invalid account generation.',422,'invalid_account_epoch');\r\n const epoch=Number(rawEpoch),proof=await inspectAccountDataEpoch(database,user);\r\n if(proof.currentDataEpoch!==epoch)fail('Account data changed.',409,'target_epoch_mismatch');\r\n const value=await readBody(request),paths=value.paths;\r\n if(!Array.isArray(paths)||paths.length!==2||new Set(paths).size!==2||!paths.every(id=>CHOOSABLE_TRACKS.includes(id)))fail('Choose exactly two workout paths.',422,'invalid_paths');\r\n const now=Date.now();\r\n try{\r\n  await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:epoch,now,statements:[database.prepare(`INSERT INTO workout_path_choices(user_id,data_epoch,paths,created_at) VALUES(?,?,?,?)\r\n   ON CONFLICT(user_id) DO UPDATE SET data_epoch=excluded.data_epoch,paths=excluded.paths,created_at=excluded.created_at\r\n   WHERE workout_path_choices.data_epoch<>excluded.data_epoch`).bind(user,epoch,JSON.stringify(paths),now)]});\r\n }catch(error){if(error.code==='target_epoch_mismatch')fail('Account data changed.',409,'target_epoch_mismatch');throw error;}\r\n const row=await database.prepare('SELECT paths FROM workout_path_choices WHERE user_id=? AND data_epoch=?').bind(user,epoch).first();\r\n let saved;try{saved=JSON.parse(row?.paths);}catch{}\r\n if(!Array.isArray(saved)||!samePair(paths,saved))fail('Workout paths were already chosen.',409,'paths_already_chosen');\r\n return {paths:saved};\r\n}\r\n","server/workout-route.mjs":"import {epochFencedBatch} from './remote-epochs.mjs';\r\nimport {EXERCISES} from '../exercise-library.mjs';\r\nimport {DAILY_ROUND_LIMIT,exerciseFamily,makeExerciseRoute,routeDay} from '../workout-route.mjs';\r\nimport {fail,validateCompletion} from './domain.mjs';\r\n\r\nexport function workoutDayBounds(now,timezone='UTC'){\r\n const day=routeDay(now,timezone);\r\n // Find local midnight by calendar date; DST days need not be 24 hours long.\r\n function boundary(low,high,after){while(high-low>1){const mid=Math.floor((low+high)/2);if(after(routeDay(mid,timezone)))high=mid;else low=mid;}return high;}\r\n return {day,start:boundary(now-36*3600000,now,d=>d>=day),end:boundary(now,now+36*3600000,d=>d>day)};\r\n}\r\nconst familyModes=mode=>[...Object.values(EXERCISES).filter(m=>m.group===exerciseFamily(mode)).map(m=>m.id),...(exerciseFamily(mode)==='cardio'?['jumping']:[])];\r\nexport async function readExerciseRoute(database,user,onboarding,now=Date.now()){\r\n const timezone=onboarding?.data?.profile?.timezone||'UTC',{day,start,end}=workoutDayBounds(now,timezone);\r\n const [history,today]=await Promise.all([\r\n  database.prepare(`SELECT mode,sets,value FROM (SELECT mode,value,COUNT(*) OVER (PARTITION BY mode) AS sets,ROW_NUMBER() OVER (PARTITION BY mode ORDER BY completed_at DESC,id DESC) AS recent FROM workouts WHERE user_id=? AND source='server' AND completed_at IS NOT NULL) WHERE recent=1`).bind(user).all(),\r\n  database.prepare(`SELECT mode,COUNT(*) AS sets FROM workouts WHERE user_id=? AND source='server' AND completed_at>=? AND completed_at<? GROUP BY mode`).bind(user,start,end).all()\r\n ]);\r\n return makeExerciseRoute(history.results,today.results,{day,timezone,goals:onboarding?.targets?.goals});\r\n}\r\nexport async function assertRoundAvailable(database,user,mode,timezone,now){\r\n const {start,end}=workoutDayBounds(now,timezone),modes=familyModes(mode);\r\n const count=await database.prepare(`SELECT COUNT(*) AS n FROM workouts WHERE user_id=? AND source='server' AND mode IN (${modes.map(()=>'?').join(',')}) AND completed_at>=? AND completed_at<?`).bind(user,...modes,start,end).first();\r\n if(count.n>=DAILY_ROUND_LIMIT)fail('Five rounds completed for this exercise family today. Choose another family or come back tomorrow.',409);\r\n}\r\nexport async function maximumRoundGoal(database,user,mode,personalGoal=0){\r\n const previous=await database.prepare(`SELECT value FROM workouts WHERE user_id=? AND source='server' AND mode=? AND completed_at IS NOT NULL ORDER BY completed_at DESC,id DESC LIMIT 1`).bind(user,mode).first();\r\n return Math.max(600,personalGoal,previous?Math.floor(Number(previous.value))+1:0);\r\n}\r\nexport async function completeRound(database,user,workout,input,timezone,now,{dataEpoch=1}={}){\r\n if(workout.completed_at==null)validateCompletion(workout,input,now);\r\n const {start,end}=workoutDayBounds(now,timezone),modes=familyModes(workout.mode);\r\n // The limit and completion are one atomic write, including competing devices.\r\n const statement=database.prepare(`UPDATE workouts SET completed_at=?,value=?,active=? WHERE id=? AND user_id=? AND source='server' AND completed_at IS NULL AND (SELECT COUNT(*) FROM workouts WHERE user_id=? AND source='server' AND mode IN (${modes.map(()=>'?').join(',')}) AND completed_at>=? AND completed_at<?)<? RETURNING id`).bind(now,input.value,Number.isFinite(input.active)?input.active:0,workout.id,user,user,...modes,start,end,DAILY_ROUND_LIMIT);\r\n const results=await epochFencedBatch(database,{ownerId:user,expectedDataEpoch:dataEpoch,now,statements:[statement,\r\n  database.prepare(\"INSERT INTO login_days(user_id,day,logged_at) SELECT user_id,?,? FROM workouts WHERE id=? AND user_id=? AND source='server' AND completed_at IS NOT NULL ON CONFLICT(user_id,day) DO NOTHING\").bind(Math.floor(now/86400000),now,workout.id,user),\r\n ]});\r\n const saved=results[0].results?.[0];\r\n if(!saved){const existing=await database.prepare(`SELECT completed_at FROM workouts WHERE id=? AND user_id=? AND source='server'`).bind(workout.id,user).first();if(existing?.completed_at==null)throw Object.assign(Error('Five rounds completed for this exercise family today. This extra round was not added.'),{status:409,code:'daily_round_limit'});}\r\n}\r\n","server/world-api.mjs":"import {newBase,advanceBase,applyBaseAction,normalizeBase} from '../modules/coach-world/state.mjs';\nimport {GROUP_TO_FACTION,FACTIONS,NPC_ITEMS,SHIP_IDS,hangarShipTier} from '../modules/coach-world/catalog.mjs';\nimport * as geography from '../modules/coach-world/sites.mjs';\r\nimport {readAccountPerformance} from './performance-progress.mjs';\r\nimport {sectorAt,neighbors,cellToLatLng,cellToBoundary,containsPoint} from '../modules/coach-world/geo.mjs';\r\nimport {isValidCell,getResolution} from '../modules/coach-world/vendor/h3.mjs';\r\nimport {EXERCISES} from '../exercise-library.mjs';\nimport {worldDropsApi,worldDropDeletionStatements} from './world-drops.mjs';\nexport const WORLD_RULES=Object.freeze({version:1,windowMs:1800000,graceMs:21600000,conversionMs:21600000,healingMs:86400000,influenceMs:259200000,walkDwellMs:90000});\r\nexport class WorldError extends Error{constructor(code,status=409){super(code);this.code=code;this.status=status;}}\r\nconst fail=(code,status)=>{throw new WorldError(code,status);};\r\nconst uuid=()=>crypto.randomUUID();\r\nconst stmt=(db,sql,...args)=>db.prepare(sql).bind(...args);\r\nconst first=(db,sql,...args)=>stmt(db,sql,...args).first();\r\nconst all=async(db,sql,...args)=>(await stmt(db,sql,...args).all()).results;\r\nconst day=now=>new Date(now).toISOString().slice(0,10);\r\nconst json=JSON.stringify;\r\nconst sites=()=>geography.WORLD_SITES;\r\nconst sectors=()=>geography.WORLD_SECTORS;\r\nconst siteById=id=>sites().find(s=>s.id===id);\r\nconst sectorById=id=>{const known=geography.SECTOR_BY_ID[id];if(known)return known;if(!isValidCell(id)||getResolution(id)!==10)return null;const [latitude,longitude]=cellToLatLng(id),ring=cellToBoundary(id,true);ring.push([...ring[0]]);return {id,siteId:null,kind:'territory',latitude,longitude,neighbors:neighbors(id),outpostFactions:FACTIONS.map(f=>f.id),polygon:ring,polygonGeoJSON:{type:'Polygon',coordinates:[ring]}};};\r\nconst enabledSite=(id,now)=>{const s=siteById(id);if(!s||s.enabled===false||!(geography.isSiteOpen?.(s,now)??true))fail('public_site_closed');return s;};\r\nconst assert=(db,condition,args=[])=>stmt(db,`INSERT INTO world_assertions(id,ok) VALUES(?,CASE WHEN ${condition} THEN 1 ELSE NULL END)`,uuid(),...args);\r\nconst epochGuard=(db,owner,epoch)=>assert(db,'EXISTS(SELECT 1 FROM account_data_epochs WHERE owner_id=? AND epoch=?)',[owner,epoch]);\r\nconst baseGuard=(db,row)=>assert(db,'EXISTS(SELECT 1 FROM world_bases WHERE owner=? AND epoch=? AND revision=?)',[row.owner,row.epoch,row.revision]);\r\nconst sectorGuard=(db,row)=>assert(db,'EXISTS(SELECT 1 FROM world_sectors WHERE id=? AND revision=? AND generation=? AND enabled=1)',[row.id,row.revision,row.generation]);\r\nasync function atomic(db,guards,writes){await db.batch([...guards,...writes,stmt(db,'DELETE FROM world_assertions')]);}\r\nasync function fingerprint(v){return [...new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(json(v))))].map(v=>v.toString(16).padStart(2,'0')).join('');}\r\nfunction snapshot(row,now){const base=advanceBase(JSON.parse(row.base),now);base.launchCharge=row.charge;return {targetAccountId:row.owner,dataEpoch:row.epoch,revision:row.revision,serverTime:now,base,publicId:row.public_id};}\nasync function ownSnapshot(db,row,now){\n const own=snapshot(row,now),home=own.base.home;\n const territory=home?await first(db,'SELECT controller,phase FROM world_sectors WHERE id=? AND enabled=1',sectorAt(home.latitude,home.longitude)):null;\n own.environment={faction:territory?.controller||own.base.faction,phase:territory?.phase||'stable',source:territory?.controller?'territory':'civilization'};\n return own;\n}\nasync function provision(db,user,epoch,now){\r\n if(typeof user!=='string'||!user||!Number.isSafeInteger(epoch)||epoch<1)fail('world_account_required',401);\r\n const current=await first(db,'SELECT epoch FROM account_data_epochs WHERE owner_id=?',user);if((current?.epoch??1)!==epoch)fail('world_epoch_mismatch');\r\n const base=newBase(user,now);\r\n await atomic(db,[assert(db,'COALESCE((SELECT epoch FROM account_data_epochs WHERE owner_id=?),1)=?',[user,epoch])],[stmt(db,'INSERT INTO account_data_epochs(owner_id,epoch,updated_at) VALUES(?,1,?) ON CONFLICT DO NOTHING',user,now),stmt(db,'INSERT INTO world_bases(owner,epoch,public_id,revision,base,charge,created_at) VALUES(?,?,?,1,?,0,?) ON CONFLICT(owner) DO NOTHING',user,epoch,uuid(),json(base),now)]);\r\n const row=await first(db,'SELECT * FROM world_bases WHERE owner=? AND epoch=?',user,epoch);if(!row)fail('world_epoch_mismatch');return row;\r\n}\r\nfunction deploymentGuard(db,sector,faction){if(sector.kind==='territory')return assert(db,'1=1');if(sector.controller===faction)return assert(db,'1=1');const def=sectorById(sector.id);if(def?.outpostFactions?.includes(faction))return assert(db,'1=1');const ns=def?.neighbors??[];return assert(db,ns.length?`EXISTS(SELECT 1 FROM world_sectors WHERE id IN (${ns.map(()=>'?').join(',')}) AND controller=? AND enabled=1)`:'0=1',ns.length?[...ns,faction]:[]);}\r\nfunction saveBase(db,row,base,charge=row.charge){return stmt(db,'UPDATE world_bases SET base=?,charge=?,revision=revision+1 WHERE owner=? AND epoch=? AND revision=?',json(base),charge,row.owner,row.epoch,row.revision);}\r\nconst seeded=new WeakMap();\r\nasync function seed(db,now){if(seeded.has(db))return seeded.get(db);const rows=sectors();if(!rows.length)return;const pending=db.batch(rows.map(s=>stmt(db,'INSERT INTO world_sectors(id,site_id,latitude,longitude,controller,changed_at,conflict_at,enabled) VALUES(?,?,?,?,?,?,?,?) ON CONFLICT DO NOTHING',s.id,s.siteId,s.latitude,s.longitude,s.faction??s.controller??'chest',now,now,s.enabled===false?0:1)));seeded.set(db,pending);try{await pending;}catch(e){seeded.delete(db);throw e;}}\r\nconst distance=(a,b)=>{const r=Math.PI/180,p=(b.latitude-a.latitude)*r,q=(b.longitude-a.longitude)*r;return 12742000*Math.asin(Math.min(1,Math.sqrt(Math.sin(p/2)**2+Math.cos(a.latitude*r)*Math.cos(b.latitude*r)*Math.sin(q/2)**2)));};\r\nfunction validFix(input,now){if(![input.latitude,input.longitude,input.accuracy,input.sampledAt].every(Number.isFinite)||Math.abs(input.latitude)>90||Math.abs(input.longitude)>180||input.accuracy<0||input.accuracy>25||now-input.sampledAt>15000||input.sampledAt>now+1000)fail('world_gps_fix_rejected',400);}\r\nasync function locate(input,now){const found=await geography.locatePublicSector?.(input.latitude,input.longitude,input.accuracy,now);return found??{status:'outside'};}\r\nconst appearance=base=>({version:base.version,faction:base.faction,buildings:base.buildings,ships:base.ships,selectedShip:base.selectedShip});\r\nasync function canDeploy(db,sector,faction){if(sector.kind==='territory')return true;if(sector.controller===faction)return true;const definition=sectorById(sector.id);if(definition?.outpostFactions?.includes(faction))return true;const neighbors=definition?.neighbors??[];if(!neighbors.length)return false;const found=await first(db,`SELECT 1 AS ok FROM world_sectors WHERE id IN (${neighbors.map(()=>'?').join(',')}) AND controller=? AND enabled=1`,...neighbors,faction);return !!found;}\r\nasync function influenceState(db,sector,cutoff){const rows=await all(db,'SELECT faction,SUM(points) AS points FROM world_influence WHERE sector_id=? AND COALESCE(effective_at,accepted_at)<=? AND expires_at>? GROUP BY faction',sector.id,cutoff,cutoff);return Object.fromEntries(rows.map(r=>[r.faction,r.points]));}\r\nasync function maybeWindow(db,sector,now,extraFaction,extraPoints=1){const scores=await influenceState(db,sector,now);scores[extraFaction]=(scores[extraFaction]??0)+extraPoints;if(sector.closes_at||sector.grace_until>now)return stmt(db,\"UPDATE world_sectors SET revision=revision+1,phase=CASE WHEN ? IS NOT controller THEN 'warzone' ELSE phase END,conflict_at=CASE WHEN ? IS NOT controller THEN ? ELSE conflict_at END WHERE id=?\",extraFaction,extraFaction,now,sector.id);const eligible=Object.entries(scores).some(([f,p])=>f!==sector.controller&&p>=3&&p-(scores[sector.controller]??0)>=2);return eligible?stmt(db,\"UPDATE world_sectors SET closes_at=?,pause_until=NULL,phase='warzone',conflict_at=?,revision=revision+1 WHERE id=?\",now+WORLD_RULES.windowMs,now,sector.id):stmt(db,\"UPDATE world_sectors SET phase=CASE WHEN ? IS NOT controller THEN 'warzone' ELSE phase END,conflict_at=CASE WHEN ? IS NOT controller THEN ? ELSE conflict_at END,revision=revision+1 WHERE id=?\",extraFaction,extraFaction,now,sector.id);}\r\nexport async function settleDueWorldSectors(db,now=Date.now()){\r\n await seed(db,now);let settled=0;\r\n await db.batch([stmt(db,'DELETE FROM world_walks WHERE updated_at<?',now-86400000),stmt(db,'DELETE FROM world_presence WHERE updated_at<?',now-86400000),stmt(db,'DELETE FROM world_friend_codes WHERE expires_at<?',now)]);\r\n for(const e of await all(db,\"SELECT * FROM world_encounters WHERE (status='pending' AND expires_at<=?) OR (status='admitted' AND due_at<=?) LIMIT 40\",now,now))try{await settleEncounter(db,e,now);}catch{}\r\n const due=await all(db,'SELECT * FROM world_sectors WHERE closes_at IS NOT NULL AND closes_at<=? AND COALESCE(pause_until,closes_at)<=? LIMIT 40',now,now);\r\n for(const s of due){const scores=await influenceState(db,s,s.closes_at),rank=Object.entries(scores).sort((a,b)=>b[1]-a[1]);let winner=s.controller;if(rank[0]&&rank[0][1]>=3&&rank[0][1]-(rank[1]?.[1]??0)>=2&&await canDeploy(db,s,rank[0][0]))winner=rank[0][0];\r\n if(s.kind==='hub'&&(!siteById(s.site_id)?.enabled||!geography.isSiteOpen(siteById(s.site_id),now)))winner=s.controller;\r\n const changed=winner!==s.controller;\r\n try{await atomic(db,[sectorGuard(db,s),...(changed?[deploymentGuard(db,s,winner)]:[])],[stmt(db,\"UPDATE world_sectors SET controller=?,closes_at=NULL,pause_until=NULL,generation=generation+1,revision=revision+1,grace_until=?,phase=?,changed_at=?,conflict_at=? WHERE id=?\",winner,changed?now+WORLD_RULES.graceMs:s.grace_until,changed?'converting':'warzone',changed?now:s.changed_at,now,s.id)]);settled++;}catch{/* another worker settled the generation */}}\r\n // Only quiet areas heal. A rival receipt updates conflict_at and resets the clock.\r\n await stmt(db,\"UPDATE world_sectors SET phase=CASE WHEN ?-MAX(changed_at,conflict_at)>=? THEN 'stable' WHEN ?-MAX(changed_at,conflict_at)>=? THEN 'healing' ELSE phase END,revision=revision+1 WHERE controller IS NOT NULL AND closes_at IS NULL AND phase<>'stable' AND ?-MAX(changed_at,conflict_at)>=?\",now,WORLD_RULES.conversionMs+WORLD_RULES.healingMs,now,WORLD_RULES.conversionMs,now,WORLD_RULES.conversionMs).run();return {settled};\r\n}\r\nasync function reconcile(db,row,now){\r\n const deletion=await first(db,'SELECT MAX(deleted_at) AS at FROM account_data_deletions WHERE owner_id=?',row.owner);\r\n const records=await all(db,'SELECT id,mode,source,competitive_status,goal,started_at,completed_at,value,active FROM workouts WHERE user_id=? AND completed_at IS NOT NULL AND completed_at>=? AND NOT EXISTS(SELECT 1 FROM world_sources ws WHERE ws.owner=? AND ws.epoch=? AND ws.source_id=workouts.id) ORDER BY completed_at,id LIMIT 500',row.owner,Math.max(now-30*86400000,(deletion?.at??-1)+1),row.owner,row.epoch);\r\n const existing=await all(db,'SELECT * FROM world_sources WHERE owner=? AND epoch=?',row.owner,row.epoch),known=new Set(existing.map(r=>r.source_id));\r\n const grants=await all(db,'SELECT day,track FROM world_grants WHERE owner=? AND epoch=?',row.owner,row.epoch),grantKeys=new Set(grants.map(g=>g.day+'/'+g.track));\r\n const reservation=await first(db,\"SELECT COALESCE(SUM(CASE WHEN a=? THEN a_reserved ELSE b_reserved END),0) AS n FROM world_encounters WHERE (a=? OR b=?) AND status IN ('pending','admitted')\",row.owner,row.owner,row.owner);\r\n const capacity=Math.max(0,10-reservation.n);\r\n const base=advanceBase(JSON.parse(row.base),now),writes=[];let charge=row.charge,accepted=0;\r\n const prior=existing.filter(s=>s.decision==='accepted');\r\n for(const w of records){if(known.has(w.id))continue;const exercise=EXERCISES[w.mode],track=GROUP_TO_FACTION[exercise?.group],d=day(w.completed_at),elapsed=(w.completed_at-w.started_at)/1000;\r\n let reason='accepted';if(w.source!=='server')reason='guest_import';else if(w.competitive_status==='not_eligible')reason='source_not_eligible';else if(!exercise||!track)reason='unknown_mode';else if(!Number.isSafeInteger(w.completed_at)||!Number.isSafeInteger(w.started_at)||w.completed_at>now||elapsed<2||elapsed>7200||!Number.isFinite(w.active)||w.active<0||w.active>elapsed+1||!Number.isFinite(w.value)||w.value<=0||w.value<w.goal||w.value>100000)reason='invalid_completion';else if(['hold','pace'].includes(exercise.kind)&&(w.active<60||w.value>elapsed+1))reason='insufficient_active';else if(exercise.kind==='reps'&&w.value<5)reason='insufficient_reps';\r\n const prev=n=>day(w.completed_at-n*86400000);if(reason==='accepted'&&prior.some(g=>g.track===track&&g.day===prev(1))&&prior.some(g=>g.track===track&&g.day===prev(2)))reason='recovery';\r\n if(reason==='accepted'&&exercise.kind==='reps'&&prior.some(g=>g.track===track&&g.day===d))reason='daily_working_set';\r\n writes.push(stmt(db,'INSERT INTO world_sources(owner,epoch,source_id,decision,day,track) VALUES(?,?,?,?,?,?)',row.owner,row.epoch,w.id,reason,d,track??null));\r\n if(reason!=='accepted')continue;prior.push({track,day:d});accepted++;\r\n const key=d+'/'+track;if(grantKeys.has(key))continue;const daily=[...grantKeys].filter(k=>k.startsWith(d+'/')).length;if(daily>=3)continue;grantKeys.add(key);\r\n writes.push(stmt(db,'INSERT INTO world_grants(owner,epoch,day,track) VALUES(?,?,?,?)',row.owner,row.epoch,d,track));base.materials[track]=(base.materials[track]??0)+10;base.rewardDays[d]??=[];base.rewardDays[d].push(track);if(daily===0&&w.completed_at>=now-86400000)charge=Math.min(capacity,charge+1);\r\n }\r\n const meals=await all(db,'SELECT id,eaten_at,created_at FROM meals WHERE user_id=? AND created_at>=? ORDER BY created_at LIMIT 100',row.owner,Math.max(now-30*86400000,(deletion?.at??-1)+1));\r\n const breathing=await all(db,'SELECT id,completed_at FROM breathing_sessions WHERE user_id=? AND completed_at>=? ORDER BY completed_at LIMIT 100',row.owner,Math.max(now-30*86400000,(deletion?.at??-1)+1));\r\n for(const activity of [...meals.map(v=>({id:'food:'+v.id,kind:'food',at:Date.parse(v.eaten_at)})),...breathing.map(v=>({id:'meditation:'+v.id,kind:'meditation',at:v.completed_at}))]){if(known.has(activity.id)||!Number.isSafeInteger(activity.at)||activity.at>now||activity.at<now-30*86400000)continue;const d=day(activity.at);writes.push(stmt(db,'INSERT INTO world_sources(owner,epoch,source_id,decision,day,track) VALUES(?,?,?,?,?,NULL)',row.owner,row.epoch,activity.id,'care',d));const flags=base.careDays[d]??={};if(!flags[activity.kind]){flags[activity.kind]=true;const key=activity.kind==='food'?'rations':'calmTokens';base[key]++;}}\r\n const personal=await readAccountPerformance(db,row.owner);base.coachAccess=[...new Set([...base.coachAccess,...personal.coaches])];let hash=0;for(const c of base.seed)hash=(Math.imul(hash,31)+c.charCodeAt(0))>>>0;for(const id of personal.ships??[])if(SHIP_IDS.includes(id)&&id!=='supportive'){const tier=hangarShipTier(base.buildings.hangar.level);if(Object.hasOwn(base.ships,id))base.ships[id].tier=Math.max(base.ships[id].tier,tier);else base.ships[id]={tier,variant:(hash+SHIP_IDS.indexOf(id))%4};}\n return {base,charge,writes,result:{accepted,policyVersion:WORLD_RULES.version}};\r\n}\r\nfunction presenceGuard(db,p,now){return assert(db,'EXISTS(SELECT 1 FROM world_presence WHERE owner=? AND epoch=? AND site_id=? AND seq=? AND updated_at=? AND updated_at>=?)',[p.owner,p.epoch,p.site_id,p.seq,p.updated_at,now-15000]);}\r\nfunction encounterGuard(db,e){return assert(db,'EXISTS(SELECT 1 FROM world_encounters WHERE id=? AND status=? AND revision=? AND a_reserved=? AND b_reserved=?)',[e.id,e.status,e.revision,e.a_reserved,e.b_reserved]);}\r\nasync function partyRows(db,e){return Promise.all([first(db,'SELECT * FROM world_bases WHERE owner=? AND epoch=?',e.a,e.ae),first(db,'SELECT * FROM world_bases WHERE owner=? AND epoch=?',e.b,e.be)]);}\r\nfunction refundStatements(db,e){return [stmt(db,'UPDATE world_bases SET charge=MIN(10,charge+?),revision=revision+1 WHERE owner=? AND epoch=?',e.a_reserved,e.a,e.ae),stmt(db,'UPDATE world_bases SET charge=MIN(10,charge+?),revision=revision+1 WHERE owner=? AND epoch=?',e.b_reserved,e.b,e.be),stmt(db,\"UPDATE world_encounters SET status='cancelled',a_reserved=0,b_reserved=0,revision=revision+1 WHERE id=?\",e.id)];}\r\nasync function settleEncounter(db,e,now){\r\n if(!['pending','admitted'].includes(e.status))return e;\r\n const expired=e.status==='pending'&&e.expires_at<=now;\r\n if(!expired&&!(e.status==='admitted'&&e.due_at<=now))return e;\r\n const [a,b]=await partyRows(db,e);if(!a||!b)return e;\r\n const guards=[epochGuard(db,e.a,e.ae),epochGuard(db,e.b,e.be),baseGuard(db,a),baseGuard(db,b),encounterGuard(db,e)];\r\n if(expired){await atomic(db,guards,refundStatements(db,e));return first(db,'SELECT * FROM world_encounters WHERE id=?',e.id);}\r\n const sector=await first(db,'SELECT * FROM world_sectors WHERE id=?',e.sector_id),open=siteById(e.site_id);\r\n if(!sector||sector.generation!==e.generation||!sector.enabled||!open||open.enabled===false){await atomic(db,guards,refundStatements(db,e));return first(db,'SELECT * FROM world_encounters WHERE id=?',e.id);}\r\n // Deterministic simulation from persisted earned buildings, pinned factions, and encounter seed.\r\n const strength=r=>Object.values(normalizeBase(JSON.parse(r.base)).buildings).reduce((n,v)=>n+Math.max(0,Number(v.level)||0),0);\n const sa=strength(a),sb=strength(b),aWins=sa===sb?(parseInt((await fingerprint(e.id)).slice(0,8),16)%2===0):sa>sb,winner=aWins?a:b,faction=aWins?e.faction_a:e.faction_b;\r\n if(!Number.isSafeInteger(e.admitted_at)||e.admitted_at>e.due_at||e.admitted_at>now){await atomic(db,guards,refundStatements(db,e));return first(db,'SELECT * FROM world_encounters WHERE id=?',e.id);}\r\n const effectiveAt=e.admitted_at;\r\n const receiptId='battle:'+e.id,already=await first(db,\"SELECT id FROM world_influence WHERE owner=? AND epoch=? AND day=? AND sector_id=? AND kind='battle'\",winner.owner,winner.epoch,day(effectiveAt),sector.id),writes=[];\r\n guards.push(sectorGuard(db,sector));\r\n if(!already&&sector.grace_until<=now&&await canDeploy(db,sector,faction)){\r\n guards.push(deploymentGuard(db,sector,faction));\r\n writes.push(stmt(db,\"INSERT INTO world_influence(id,owner,epoch,day,sector_id,faction,kind,points,accepted_at,effective_at,expires_at) VALUES(?,?,?,?,?,?,'battle',3,?,?,?)\",receiptId,winner.owner,winner.epoch,day(effectiveAt),sector.id,faction,now,effectiveAt,effectiveAt+WORLD_RULES.influenceMs));\r\n const window=await maybeWindow(db,sector,now,faction,3);if(window)writes.push(window);\r\n }\r\n writes.push(stmt(db,\"UPDATE world_encounters SET status='settled',winner=?,a_reserved=0,b_reserved=0,revision=revision+1 WHERE id=?\",winner.public_id,e.id));\r\n await atomic(db,guards,writes);return first(db,'SELECT * FROM world_encounters WHERE id=?',e.id);\r\n}\r\nfunction encounterDTO(e,user){if(!e||![e.a,e.b].includes(user))fail('world_encounter_not_found',404);return {id:e.id,status:e.status,revision:e.revision,siteId:e.site_id,sectorId:e.sector_id,meetingAnchor:JSON.parse(e.anchor),expiresAt:e.expires_at,dueAt:e.due_at,admittedAt:e.admitted_at,winner:e.winner,role:e.a===user?'inviter':'invitee'};}\r\nasync function settleOwnEncounters(db,user,now){for(const e of await all(db,\"SELECT * FROM world_encounters WHERE (a=? OR b=?) AND status IN ('pending','admitted') LIMIT 20\",user,user))try{await settleEncounter(db,e,now);}catch(error){if(error instanceof WorldError)throw error;/* contested CAS: next tick retries */}}\r\nasync function privateBase(db,user,publicId,now){\r\n const target=await first(db,'SELECT * FROM world_bases WHERE public_id=?',publicId);if(!target)return {fog:true};if(target.owner===user)return snapshot(target,now);\r\n const permission=await first(db,'SELECT location FROM world_friends WHERE a=? AND b=?',target.owner,user);\r\n const battle=permission?null:await first(db,\"SELECT id FROM world_encounters WHERE ((a=? AND b=?) OR (a=? AND b=?)) AND (status='admitted' OR (status='settled' AND due_at>=?)) ORDER BY due_at DESC LIMIT 1\",target.owner,user,user,target.owner,now-3600000);\r\n if(!permission&&!battle)return {fog:true};const base=normalizeBase(JSON.parse(target.base)),response={publicId:target.public_id,revision:target.revision,base:appearance(base),scope:permission?'friend':'encounter'};\n if(permission?.location===1&&base.home)response.home=base.home;return response;\r\n}\r\nasync function mapDTO(db,user,now,request){await seed(db,now);await settleDueWorldSectors(db,now);const params=new URL(request.url).searchParams;const hasLat=params.has('latitude'),hasLng=params.has('longitude');if(hasLat!==hasLng)fail('world_map_center_required',400);const latitude=hasLat?Number(params.get('latitude')):36.1699,longitude=hasLng?Number(params.get('longitude')):-115.1398,radius=params.has('radius')?Number(params.get('radius')):5000,cursor=params.get('cursor')??'';\r\n if(!Number.isFinite(latitude)||Math.abs(latitude)>90||!Number.isFinite(longitude)||Math.abs(longitude)>180||!Number.isFinite(radius)||radius<100||radius>5000||cursor&&(!isValidCell(cursor)||getResolution(cursor)!==10))fail('world_map_query_invalid',400);\r\n const latDelta=radius/111000,lngDelta=Math.min(180,latDelta/Math.max(.001,Math.cos(latitude*Math.PI/180))),west=longitude-lngDelta,east=longitude+lngDelta;let longitudeSql='longitude BETWEEN ? AND ?',longitudeArgs=[west,east];if(west < -180){longitudeSql='(longitude>=? OR longitude<=?)';longitudeArgs=[west+360,east];}else if(east>180){longitudeSql='(longitude>=? OR longitude<=?)';longitudeArgs=[west,east-360];}\r\n const rows=await all(db,`SELECT * FROM world_sectors WHERE enabled=1 AND latitude BETWEEN ? AND ? AND ${longitudeSql} AND id>? ORDER BY id LIMIT 513`,Math.max(-90,latitude-latDelta),Math.min(90,latitude+latDelta),...longitudeArgs,cursor);const publicSectors=rows.slice(0,512),query={latitude,longitude,radius,limit:512,truncated:rows.length>512,nextCursor:rows.length>512?publicSectors.at(-1).id:null};\r\n const friends=[];for(const p of await all(db,'SELECT b.public_id,b.base,f.location FROM world_friends f JOIN world_bases b ON b.owner=f.a WHERE f.b=?',user)){const base=normalizeBase(JSON.parse(p.base));const friend={publicId:p.public_id,base:appearance(base)};if(p.location===1&&base.home)friend.home=base.home;friends.push(friend);}\n return {serverTime:now,sites:sites().filter(s=>s.enabled!==false).map(s=>({...s})),sectors:publicSectors.map(s=>({id:s.id,siteId:s.site_id,kind:s.kind,latitude:s.latitude,longitude:s.longitude,polygonGeoJSON:sectorById(s.id)?.polygonGeoJSON,polygon:sectorById(s.id)?.polygon,initialPatchId:sectorById(s.id)?.initialPatchId,outpostFactions:sectorById(s.id)?.outpostFactions,controller:s.controller,revision:s.revision,generation:s.generation,closesAt:s.closes_at,graceUntil:s.grace_until,phase:s.phase,changedAt:s.changed_at,conflictAt:s.conflict_at,conversionProgress:Math.min(1,Math.max(0,(now-Math.max(s.changed_at,s.conflict_at))/WORLD_RULES.conversionMs))})),friends,query,geometryEpoch:2,rules:WORLD_RULES};\r\n}\r\nasync function walkCommand(db,row,input,now){\r\n const base=advanceBase(JSON.parse(row.base),now),guards=[],writes=[];let result={};\r\n if(input.type==='walk-start'){\r\n if(input.confirmLawfulWalking!==true)fail('world_lawful_walking_confirmation_required',400);\r\n const old=await first(db,'SELECT * FROM world_walks WHERE owner=?',row.owner);if(old&&now-old.updated_at<30000)fail('world_walk_already_active');\r\n const sessionId=uuid(),nonce=uuid();writes.push(stmt(db,'INSERT INTO world_walks(owner,epoch,id,nonce,seq,state,updated_at) VALUES(?,?,?,?,0,?,?) ON CONFLICT(owner) DO UPDATE SET epoch=excluded.epoch,id=excluded.id,nonce=excluded.nonce,seq=0,state=excluded.state,updated_at=excluded.updated_at',row.owner,row.epoch,sessionId,nonce,json({issuedAt:now,lawfulWalking:true}),now));result={sessionId,nonce};\r\n }else{\r\n const session=await first(db,'SELECT * FROM world_walks WHERE owner=? AND epoch=? AND id=?',row.owner,row.epoch,input.sessionId);if(!session||input.nonce!==session.nonce)fail('world_walk_session_mismatch');if(now-session.updated_at>60000&&input.type!=='walk-stop')fail('world_walk_session_expired');\r\n guards.push(assert(db,'EXISTS(SELECT 1 FROM world_walks WHERE owner=? AND epoch=? AND id=? AND seq=? AND nonce=?)',[row.owner,row.epoch,session.id,session.seq,session.nonce]));\r\n if(input.type==='walk-stop'){writes.push(stmt(db,'DELETE FROM world_walks WHERE owner=?',row.owner),stmt(db,'DELETE FROM world_presence WHERE owner=?',row.owner));result={stopped:true};}\r\n else{\r\n validFix(input,now);if(!Number.isSafeInteger(input.seq)||input.seq!==session.seq+1||input.sampledAt<session.updated_at-15000)fail('world_walk_sequence');\r\n const prior=JSON.parse(session.state);if(input.sampledAt<(prior.issuedAt??session.updated_at)||input.sampledAt<=(prior.sampledAt??-1))fail('world_walk_fix_before_challenge');const fix={latitude:input.latitude,longitude:input.longitude,accuracy:input.accuracy};\r\n const dt=prior.lastAt?(now-prior.lastAt)/1000:0,travel=prior.last?distance(prior.last,fix):0;\r\n if(dt>0&&Math.max(0,travel-input.accuracy-(prior.last?.accuracy??0))/dt>3.5)fail('world_walk_impossible_speed');\r\n const publicLocation=await locate(input,now),containingPark=sites().find(site=>containsPoint(site.geometry,input.latitude,input.longitude));const location=containingPark&&!geography.isSiteOpen(containingPark,now)?{status:'closed',sectorId:sectorAt(input.latitude,input.longitude),siteId:containingPark.id}:publicLocation.status==='inside'||publicLocation.status==='ambiguous'?publicLocation:{status:'inside',sectorId:sectorAt(input.latitude,input.longitude),siteId:null};const inside=location.status==='inside',same=inside&&prior.sectorId===location.sectorId&&dt>0&&dt<=25;\r\n if(prior.lawfulWalking!==true)fail('world_lawful_walking_confirmation_required',400);\r\n const next={lawfulWalking:true,issuedAt:prior.issuedAt??session.updated_at,sampledAt:input.sampledAt,sectorId:inside?location.sectorId:null,firstAt:same?prior.firstAt:now,reports:same?prior.reports+1:1,movement:same?(prior.movement??0):0,last:fix,lastAt:now,anchor:same?(prior.anchor??prior.last):fix};\r\n // Distance is measured from a stable anchor, never a sum of GPS jitter.\r\n if(same&&distance(next.anchor,fix)>Math.max(12,fix.accuracy+next.anchor.accuracy)){next.movement+=Math.max(0,distance(next.anchor,fix)-Math.max(fix.accuracy,next.anchor.accuracy));next.anchor=fix;}\r\n writes.push(stmt(db,'UPDATE world_walks SET seq=?,state=?,updated_at=? WHERE owner=?',input.seq,json(next),now,row.owner));\r\n result={status:inside?'tracking':location.status,sectorId:inside?location.sectorId:null,dwellMs:now-next.firstAt,movement:next.movement,credited:false};\r\n if(inside){\r\n const isHub=publicLocation.status==='inside';if(isHub)enabledSite(publicLocation.siteId,now);\r\n let sector=await first(db,'SELECT * FROM world_sectors WHERE id=?',location.sectorId);if(sector&&!sector.enabled)fail('world_sector_unavailable');\r\n const definition=sectorById(location.sectorId);if(!definition)fail('world_sector_unavailable');\r\n const provisional=!sector;sector??={id:location.sectorId,site_id:null,kind:'territory',controller:null,revision:1,generation:1,closes_at:null,pause_until:null,grace_until:0,phase:'warzone',changed_at:now,conflict_at:now,enabled:1,latitude:definition.latitude,longitude:definition.longitude};\r\n if(!provisional)guards.push(sectorGuard(db,sector));\r\n if(isHub)writes.push(stmt(db,'INSERT INTO world_presence(owner,epoch,site_id,seq,latitude,longitude,accuracy,updated_at) VALUES(?,?,?,?,?,?,?,?) ON CONFLICT(owner) DO UPDATE SET epoch=excluded.epoch,site_id=excluded.site_id,seq=excluded.seq,latitude=excluded.latitude,longitude=excluded.longitude,accuracy=excluded.accuracy,updated_at=excluded.updated_at',row.owner,row.epoch,publicLocation.siteId,input.seq,input.latitude,input.longitude,input.accuracy,now));else writes.push(stmt(db,'DELETE FROM world_presence WHERE owner=?',row.owner));\r\n result.siteId=isHub?publicLocation.siteId:null;result.kind=sector.kind;result.territoryOnly=!isHub;\r\n const exists=await first(db,\"SELECT 1 AS ok FROM world_influence WHERE owner=? AND epoch=? AND day=? AND sector_id=? AND kind='walk'\",row.owner,row.epoch,day(now),sector.id);\r\n const counts=await first(db,\"SELECT COUNT(*) AS daily,SUM(CASE WHEN accepted_at>? THEN 1 ELSE 0 END) AS hourly FROM world_influence WHERE owner=? AND epoch=? AND day=? AND kind='walk'\",now-3600000,row.owner,row.epoch,day(now));\r\n if(!exists&&now-next.firstAt>=WORLD_RULES.walkDwellMs&&next.reports>=6&&next.movement>=40&&counts.daily<12&&(counts.hourly??0)<4&&(sector.controller===base.faction||sector.grace_until<=now)&&await canDeploy(db,sector,base.faction)){\r\n if(provisional){guards.push(assert(db,'NOT EXISTS(SELECT 1 FROM world_sectors WHERE id=?)',[sector.id]));writes.push(stmt(db,\"INSERT INTO world_sectors(id,site_id,kind,latitude,longitude,controller,revision,generation,phase,changed_at,conflict_at) VALUES(?,NULL,'territory',?,?,NULL,1,1,'warzone',?,?)\",sector.id,definition.latitude,definition.longitude,now,now));}\r\n guards.push(deploymentGuard(db,sector,base.faction));\r\n guards.push(assert(db,\"(SELECT COUNT(*) FROM world_influence WHERE owner=? AND epoch=? AND day=? AND kind='walk')<12 AND (SELECT COUNT(*) FROM world_influence WHERE owner=? AND epoch=? AND accepted_at>? AND kind='walk')<4\",[row.owner,row.epoch,day(now),row.owner,row.epoch,now-3600000]));\r\n writes.push(stmt(db,\"INSERT INTO world_influence(id,owner,epoch,day,sector_id,faction,kind,points,accepted_at,expires_at) VALUES(?,?,?,?,?,?,'walk',1,?,?)\",uuid(),row.owner,row.epoch,day(now),sector.id,base.faction,now,now+WORLD_RULES.influenceMs));const window=await maybeWindow(db,sector,now,base.faction);if(window)writes.push(window);result.credited=true;\r\n }\r\n }else writes.push(stmt(db,'DELETE FROM world_presence WHERE owner=?',row.owner));\r\n }\r\n }\r\n return {base,charge:row.charge,guards,writes,result};\r\n}\r\nasync function socialCommand(db,row,input,now){\r\n const base=advanceBase(JSON.parse(row.base),now),guards=[],writes=[];let charge=row.charge,result={};\r\n if(input.type==='friend-invite'){const code=uuid();writes.push(stmt(db,'INSERT INTO world_friend_codes(code,owner,epoch,expires_at) VALUES(?,?,?,?)',code,row.owner,row.epoch,now+86400000));result={code,expiresAt:now+86400000};}\r\n if(input.type==='friend-accept'){\r\n const invitation=await first(db,'SELECT * FROM world_friend_codes WHERE code=? AND expires_at>?',input.code,now);if(!invitation||invitation.owner===row.owner)fail('world_friend_code_invalid');\r\n guards.push(epochGuard(db,invitation.owner,invitation.epoch),assert(db,'EXISTS(SELECT 1 FROM world_friend_codes WHERE code=? AND owner=? AND epoch=? AND expires_at>?)',[input.code,invitation.owner,invitation.epoch,now]));\r\n writes.push(stmt(db,'INSERT INTO world_friends(a,b,location) VALUES(?,?,0) ON CONFLICT DO NOTHING',row.owner,invitation.owner),stmt(db,'INSERT INTO world_friends(a,b,location) VALUES(?,?,0) ON CONFLICT DO NOTHING',invitation.owner,row.owner),stmt(db,'DELETE FROM world_friend_codes WHERE code=?',input.code));result={connected:true};\r\n }\r\n if(['friend-revoke','friend-location'].includes(input.type)){\r\n const target=await first(db,'SELECT owner FROM world_bases WHERE public_id=?',input.publicId);if(!target)fail('world_friend_not_found',404);\r\n if(input.type==='friend-revoke'){writes.push(stmt(db,'DELETE FROM world_friends WHERE (a=? AND b=?) OR (a=? AND b=?)',row.owner,target.owner,target.owner,row.owner));result={revoked:true};}\r\n else{writes.push(stmt(db,'UPDATE world_friends SET location=? WHERE a=? AND b=?',input.shareLocation===true?1:0,row.owner,target.owner));result={shareLocation:input.shareLocation===true};}\r\n }\r\n if(input.type==='encounter-invite'){\r\n enabledSite(input.siteId,now);const target=await first(db,'SELECT * FROM world_bases WHERE public_id=?',input.targetPublicId);if(!target||target.owner===row.owner)fail('world_opponent_unavailable');\r\n const [pa,pb]=await Promise.all([first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=? AND site_id=?',row.owner,row.epoch,input.siteId),first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=? AND site_id=?',target.owner,target.epoch,input.siteId)]);\r\n if(!pa||!pb||pa.updated_at<now-15000||pb.updated_at<now-15000||distance(pa,pb)+pa.accuracy+pb.accuracy>80)fail('world_both_players_must_be_nearby');\r\n const la=await locate({...pa,sampledAt:pa.updated_at},now),lb=await locate({...pb,sampledAt:pb.updated_at},now);if(la.status!=='inside'||lb.status!=='inside'||la.sectorId!==lb.sectorId)fail('world_same_public_sector_required');\r\n const sector=await first(db,'SELECT * FROM world_sectors WHERE id=? AND enabled=1',la.sectorId);if(!sector)fail('world_sector_unavailable');if(sector.closes_at&&sector.closes_at<=now)fail('world_capture_window_closed');if(charge<1)fail('world_launch_charge_required');\r\n const busy=await first(db,\"SELECT id FROM world_encounters WHERE (a IN (?,?) OR b IN (?,?)) AND status IN ('pending','admitted')\",row.owner,target.owner,row.owner,target.owner);if(busy)fail('world_encounter_already_active');\r\n guards.push(epochGuard(db,target.owner,target.epoch),baseGuard(db,target),presenceGuard(db,pa,now),presenceGuard(db,pb,now),sectorGuard(db,sector),assert(db,\"NOT EXISTS(SELECT 1 FROM world_encounters WHERE (a IN (?,?) OR b IN (?,?)) AND status IN ('pending','admitted'))\",[row.owner,target.owner,row.owner,target.owner]));\r\n if(input.confirmPublicPath!==true||!input.meetingAnchor)fail('world_public_path_confirmation_required',400);const anchor=input.meetingAnchor;if(!Number.isFinite(anchor.latitude)||!Number.isFinite(anchor.longitude)||Math.abs(anchor.latitude)>90||Math.abs(anchor.longitude)>180)fail('world_meeting_anchor_invalid',400);const anchorLocation=await locate({...anchor,accuracy:Math.max(pa.accuracy,pb.accuracy)},now);if(anchorLocation.status!=='inside'||anchorLocation.sectorId!==sector.id||distance(pa,anchor)+pa.accuracy>60||distance(pb,anchor)+pb.accuracy>60)fail('world_meeting_anchor_not_nearby');\r\n const id=uuid();writes.push(stmt(db,\"INSERT INTO world_encounters(id,a,ae,b,be,site_id,anchor,sector_id,generation,status,revision,a_reserved,b_reserved,expires_at,faction_a,faction_b) VALUES(?,?,?,?,?,?,?,?,?,'pending',1,1,0,?,?,?)\",id,row.owner,row.epoch,target.owner,target.epoch,input.siteId,json(anchor),sector.id,sector.generation,now+120000,base.faction,JSON.parse(target.base).faction));charge--;result={encounter:{id,status:'pending',expiresAt:now+120000}};\r\n }\r\n if(['encounter-accept','encounter-cancel'].includes(input.type)){\r\n const e=await first(db,'SELECT * FROM world_encounters WHERE id=?',input.encounterId);if(!e||![e.a,e.b].includes(row.owner))fail('world_encounter_not_found',404);if(!['pending','admitted'].includes(e.status))fail('world_encounter_terminal');\r\n const [a,b]=await partyRows(db,e);if(!a||!b)fail('world_opponent_unavailable');const other=row.owner===e.a?b:a;\r\n guards.push(epochGuard(db,other.owner,other.epoch),baseGuard(db,other),encounterGuard(db,e));\r\n if(input.type==='encounter-cancel'){\r\n const ownRefund=row.owner===e.a?e.a_reserved:e.b_reserved,otherRefund=row.owner===e.a?e.b_reserved:e.a_reserved;charge=Math.min(10,charge+ownRefund);\r\n writes.push(stmt(db,'UPDATE world_bases SET charge=MIN(10,charge+?),revision=revision+1 WHERE owner=? AND epoch=?',otherRefund,other.owner,other.epoch),stmt(db,\"UPDATE world_encounters SET status='cancelled',a_reserved=0,b_reserved=0,revision=revision+1 WHERE id=?\",e.id));result={encounter:{id:e.id,status:'cancelled'}};\r\n }else{\r\n if(e.b!==row.owner||e.status!=='pending'||e.expires_at<=now)fail('world_encounter_not_accepting');if(charge<1)fail('world_launch_charge_required');enabledSite(e.site_id,now);\r\n const pa=await first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=?',a.owner,a.epoch),pb=await first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=?',b.owner,b.epoch);\r\n if(!pa||!pb||pa.site_id!==e.site_id||pb.site_id!==e.site_id||pa.updated_at<now-15000||pb.updated_at<now-15000||distance(pa,pb)+pa.accuracy+pb.accuracy>80)fail('world_both_players_must_be_nearby');\r\n const la=await locate({...pa,sampledAt:pa.updated_at},now),lb=await locate({...pb,sampledAt:pb.updated_at},now);if(la.status!=='inside'||lb.status!=='inside'||la.sectorId!==e.sector_id||lb.sectorId!==e.sector_id)fail('world_same_public_sector_required');\r\n const anchor=JSON.parse(e.anchor);if(distance(pa,anchor)+pa.accuracy>60||distance(pb,anchor)+pb.accuracy>60)fail('world_meeting_anchor_not_nearby');\r\n const sector=await first(db,'SELECT * FROM world_sectors WHERE id=? AND enabled=1',e.sector_id);if(sector?.closes_at&&sector.closes_at<=now)fail('world_capture_window_closed');if(!sector||sector.generation!==e.generation||JSON.parse(a.base).faction!==e.faction_a||base.faction!==e.faction_b)fail('world_encounter_state_changed');\r\n guards.push(presenceGuard(db,pa,now),presenceGuard(db,pb,now),sectorGuard(db,sector),assert(db,\"EXISTS(SELECT 1 FROM world_encounters WHERE id=? AND status='pending' AND expires_at>?)\",[e.id,now]),assert(db,'EXISTS(SELECT 1 FROM world_sectors WHERE id=? AND (closes_at IS NULL OR closes_at>?))',[sector.id,now]));charge--;\r\n writes.push(stmt(db,\"UPDATE world_encounters SET status='admitted',b_reserved=1,due_at=?,admitted_at=?,revision=revision+1 WHERE id=?\",now+30000,now,e.id));\r\n if(sector.closes_at&&!sector.pause_until)writes.push(stmt(db,'UPDATE world_sectors SET pause_until=closes_at+120000,revision=revision+1 WHERE id=?',sector.id));\r\n result={encounter:{id:e.id,status:'admitted',dueAt:now+30000}};\r\n }\r\n }\r\n return {base,charge,guards,writes,result};\r\n}\r\nasync function shopCommand(db,row,input,now){\r\n const base=advanceBase(JSON.parse(row.base),now),p=await first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=? AND site_id=?',row.owner,row.epoch,input.siteId);\r\n enabledSite(input.siteId,now);if(!p||p.updated_at<now-15000)fail('world_visit_nearby_required');const guards=[presenceGuard(db,p,now)],writes=[];const item=input.type==='visit'?'visit':input.itemId;\r\n const cosmetic=NPC_ITEMS.find(i=>i.id===item);if(!['visit','ration','calm-token'].includes(item)&&!cosmetic)fail('world_shop_item_unknown',400);if(cosmetic&&base.inventory[item])fail('world_shop_already_owned');\r\n const already=await first(db,'SELECT 1 AS ok FROM world_visits WHERE owner=? AND epoch=? AND day=? AND site_id=? AND item_id=?',row.owner,row.epoch,day(now),input.siteId,item);if(already)fail('world_daily_shop_limit');\r\n if(item!=='visit'){const track=base.faction,cost=cosmetic?.cost??5;if((base.materials[track]??0)<cost)fail('world_shop_materials_required');base.materials[track]-=cost;if(cosmetic)base.inventory[item]=true;else{const key=item==='ration'?'rations':'calmTokens';base[key]=(base[key]??0)+1;}}\r\n writes.push(stmt(db,'INSERT INTO world_visits(owner,epoch,day,site_id,item_id) VALUES(?,?,?,?,?)',row.owner,row.epoch,day(now),input.siteId,item));return {base,charge:row.charge,guards,writes,result:{visited:true,itemId:item}};\r\n}\r\nexport async function worldApi(request,db,user,path,method,input={},now=Date.now(),{dataEpoch=1}={}){\r\n if(!Number.isSafeInteger(now)||now<0)fail('world_invalid_time',400);\r\n let row=await provision(db,user,dataEpoch,now);\n if(path==='/api/world/drops')return worldDropsApi(request,db,row,method,input,now);\n if(method==='GET'){\r\n if(path==='/api/world/map')return mapDTO(db,user,now,request);\r\n if(path.startsWith('/api/world/bases/'))return privateBase(db,user,decodeURIComponent(path.slice('/api/world/bases/'.length)),now);\r\n if(path.startsWith('/api/world/encounters/')){const e=await first(db,'SELECT * FROM world_encounters WHERE id=?',decodeURIComponent(path.slice('/api/world/encounters/'.length)));if(!e||![e.a,e.b].includes(user))fail('world_encounter_not_found',404);return {serverTime:now,encounter:encounterDTO(await settleEncounter(db,e,now),user)};}\r\n if(path!=='/api/world')fail('world_route_not_found',404);\n return ownSnapshot(db,row,now);\n }\r\n if(method!=='POST'||path!=='/api/world')fail('world_route_not_found',404);\r\n if(typeof input.type!=='string'||input.type.length>40)fail('world_command_required',400);\r\n if(typeof input.id!=='string'||!/^[A-Za-z0-9:_-]{1,100}$/.test(input.id)||request.headers.get('Idempotency-Key')!==input.id)fail('world_idempotency_key_required',400);\r\n const hash=await fingerprint(input),readReplay=()=>first(db,'SELECT * FROM world_requests WHERE owner=? AND epoch=? AND id=?',user,dataEpoch,input.id);\r\n let receipt=await readReplay();if(receipt){if(receipt.hash!==hash)fail('world_idempotency_payload_conflict');return JSON.parse(receipt.response);}\r\n if(!Number.isSafeInteger(input.revision)||input.revision!==row.revision)fail('world_revision_conflict');\r\n await seed(db,now);\r\n let command;\r\n if(input.type==='reconcile')command=await reconcile(db,row,now);\r\n else if(input.type.startsWith('walk-'))command=await walkCommand(db,row,input,now);\r\n else if(input.type.startsWith('friend-')||input.type.startsWith('encounter-'))command=await socialCommand(db,row,input,now);\r\n else if(['visit','purchase'].includes(input.type))command=await shopCommand(db,row,input,now);\r\n else if(input.type==='tick')command={base:advanceBase(JSON.parse(row.base),now),charge:row.charge,writes:[],result:{tick:true}};\r\n else{\r\n if(input.type==='faction'){\r\n const old=JSON.parse(row.base);if(now-(old.factionChangedAt??0)<7*86400000&&old.factionChangedAt)fail('world_faction_cooldown');\r\n const active=await first(db,\"SELECT id FROM world_encounters WHERE (a=? OR b=?) AND status IN ('pending','admitted')\",user,user);if(active)fail('world_encounter_active');\r\n }\r\n const actionBase=advanceBase(JSON.parse(row.base),now),guards=[];let sharedMissionAuthorized=false;\n if(input.type==='launch-expedition'&&actionBase.expedition?.shared){const mission=actionBase.expedition;enabledSite(mission.siteId,now);const p=await first(db,'SELECT * FROM world_presence WHERE owner=? AND epoch=? AND site_id=?',user,dataEpoch,mission.siteId);if(!p||p.updated_at<now-15000)fail('world_shared_expedition_requires_fresh_hub');guards.push(presenceGuard(db,p,now));sharedMissionAuthorized=true;}\n try{command={base:applyBaseAction({...actionBase,launchCharge:row.charge},input,{now,sharedMissionAuthorized}),charge:row.charge,guards,writes:[],result:{type:input.type}};}catch(e){if(e instanceof RangeError)fail(e.message,400);throw e;}\n }\r\n const projected={...row,base:json(command.base),charge:command.charge,revision:row.revision+1},response={...await ownSnapshot(db,projected,now),result:command.result};\n try{await atomic(db,[epochGuard(db,user,dataEpoch),baseGuard(db,row),...(command.guards??[])],[...(command.writes??[]),saveBase(db,row,command.base,command.charge),stmt(db,'INSERT INTO world_requests(owner,epoch,id,hash,response) VALUES(?,?,?,?,?)',user,dataEpoch,input.id,hash,json(response))]);}\r\n catch(error){receipt=await readReplay();if(receipt){if(receipt.hash!==hash)fail('world_idempotency_payload_conflict');return JSON.parse(receipt.response);}const epoch=await first(db,'SELECT epoch FROM account_data_epochs WHERE owner_id=?',user);if(epoch?.epoch!==dataEpoch)fail('world_epoch_mismatch');const latest=await first(db,'SELECT revision FROM world_bases WHERE owner=?',user);if(latest?.revision!==row.revision)fail('world_revision_conflict');if(String(error.message).includes('world_assertions'))fail('world_state_conflict');throw error;}\r\n if(input.type==='tick'){await settleOwnEncounters(db,user,now);await settleDueWorldSectors(db,now);}\r\n return response;\r\n}\r\n// Called inside the primary epoch-increment/deletion batch. Refund surviving\r\n// reservations first, then erase personal rows. Earned anonymous control persists.\r\nexport function worldDeletionStatements(db,user){return [\n ...worldDropDeletionStatements(db,user),\n stmt(db,`UPDATE world_bases SET charge=MIN(10,charge+COALESCE((SELECT SUM(CASE WHEN e.a=world_bases.owner THEN e.a_reserved ELSE e.b_reserved END) FROM world_encounters e WHERE (e.a=? OR e.b=?) AND e.status IN ('pending','admitted') AND ((e.a=world_bases.owner AND e.ae=world_bases.epoch) OR (e.b=world_bases.owner AND e.be=world_bases.epoch))),0)),revision=revision+1 WHERE owner<>? AND owner IN (SELECT a FROM world_encounters WHERE b=? UNION SELECT b FROM world_encounters WHERE a=?)`,user,user,user,user,user),\r\n stmt(db,\"UPDATE world_encounters SET status='cancelled',a_reserved=0,b_reserved=0,revision=revision+1 WHERE (a=? OR b=?) AND status IN ('pending','admitted')\",user,user),\r\n ...['world_requests','world_sources','world_grants','world_friend_codes','world_walks','world_presence','world_influence','world_visits'].map(t=>stmt(db,`DELETE FROM ${t} WHERE owner=?`,user)),\r\n stmt(db,'DELETE FROM world_friends WHERE a=? OR b=?',user,user),stmt(db,'DELETE FROM world_encounters WHERE a=? OR b=?',user,user),stmt(db,'DELETE FROM world_bases WHERE owner=?',user),\r\n ];}\r\n","server/world-drops.mjs":"import {DROP_KINDS,DROP_RULES,gymCircuitReward,dropDistance} from '../modules/coach-world/location-drop-rules.mjs';\r\nimport {readAccountPerformance} from './performance-progress.mjs';\r\nconst stmt=(db,sql,...args)=>db.prepare(sql).bind(...args),first=(db,sql,...args)=>stmt(db,sql,...args).first(),all=async(db,sql,...args)=>(await stmt(db,sql,...args).all()).results;\r\nconst fail=(code,status=409)=>{throw Object.assign(Error(code),{code,status});},uuid=()=>crypto.randomUUID();\r\nconst assert=(db,condition,args=[])=>stmt(db,`INSERT INTO world_assertions(id,ok) VALUES(?,CASE WHEN ${condition} THEN 1 ELSE NULL END)`,uuid(),...args);\r\nasync function hash(value){return [...new Uint8Array(await crypto.subtle.digest('SHA-256',new TextEncoder().encode(JSON.stringify(value))))].map(v=>v.toString(16).padStart(2,'0')).join('');}\r\nconst ownRows=(db,table,row)=>all(db,`SELECT * FROM ${table} WHERE owner=? AND epoch=?`,row.owner,row.epoch);\r\nfunction validFix(fix,now,issuedAt=0){if(![fix.latitude,fix.longitude,fix.accuracy,fix.sampledAt].every(Number.isFinite)||Math.abs(fix.latitude)>90||Math.abs(fix.longitude)>180||fix.accuracy<0||fix.accuracy>DROP_RULES.maxAccuracy||now-fix.sampledAt>15000||fix.sampledAt>now+1000||fix.sampledAt<issuedAt)fail('drop_fresh_accurate_gps_required',400);}\r\nfunction near(fix,location){if(dropDistance(fix,location)+fix.accuracy>DROP_RULES.radiusMeters)fail('drop_move_closer');}\r\nasync function snapshot(db,row,now){\r\n const [locations,claims,performance]=await Promise.all([ownRows(db,'world_drop_locations',row),all(db,'SELECT id,kind,claimed_at,xp,reward FROM world_drop_claims WHERE owner=? AND epoch=? ORDER BY claimed_at,id',row.owner,row.epoch),readAccountPerformance(db,row.owner)]);\r\n const last=Object.fromEntries(DROP_KINDS.map(kind=>[kind,Math.max(0,...claims.filter(c=>c.kind===kind).map(c=>c.claimed_at))]));\r\n return {targetAccountId:row.owner,dataEpoch:row.epoch,serverTime:now,locations:locations.map(l=>({kind:l.kind,latitude:l.latitude,longitude:l.longitude,version:l.version,availableAt:last[l.kind]?last[l.kind]+DROP_RULES.cooldownMs:now})),claims:claims.map(c=>({id:c.id,kind:c.kind,claimedAt:c.claimed_at,...JSON.parse(c.reward)})),gymReward:gymCircuitReward(performance)};\r\n}\r\nexport async function worldDropsApi(request,db,row,method,input,now){\r\n if(method==='GET')return snapshot(db,row,now);if(method!=='POST')fail('drop_method_not_allowed',405);\r\n if(typeof input.id!=='string'||!/^[A-Za-z0-9:_-]{1,100}$/.test(input.id)||request.headers.get('Idempotency-Key')!==input.id)fail('drop_idempotency_key_required',400);\r\n if(!DROP_KINDS.includes(input.kind)||!['set-location','remove-location','start-claim','sample-claim'].includes(input.type))fail('drop_command_invalid',400);\r\n const fingerprint=await hash({path:'world/drops',input}),replay=()=>first(db,'SELECT * FROM world_requests WHERE owner=? AND epoch=? AND id=?',row.owner,row.epoch,input.id),receipt=await replay();if(receipt){if(receipt.hash!==fingerprint)fail('drop_idempotency_payload_conflict');return JSON.parse(receipt.response);}\r\n const guards=[assert(db,'EXISTS(SELECT 1 FROM account_data_epochs WHERE owner_id=? AND epoch=?)',[row.owner,row.epoch])],writes=[];let result={};\r\n const location=await first(db,'SELECT * FROM world_drop_locations WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind);\r\n const locationGuard=()=>location?assert(db,'EXISTS(SELECT 1 FROM world_drop_locations WHERE owner=? AND epoch=? AND kind=? AND version=?)',[row.owner,row.epoch,input.kind,location.version]):assert(db,'NOT EXISTS(SELECT 1 FROM world_drop_locations WHERE owner=? AND epoch=? AND kind=?)',[row.owner,row.epoch,input.kind]);\r\n guards.push(locationGuard());\r\n if(input.type==='set-location'){\r\n  if(input.confirmPrivateLocation!==true||input.confirmAccessible!==true)fail('drop_location_consent_required',400);validFix(input,now);\r\n  if(location&&now-location.updated_at<3600000)fail('drop_location_change_cooldown');\r\n  writes.push(stmt(db,'INSERT INTO world_drop_locations(owner,epoch,kind,latitude,longitude,version,updated_at) VALUES(?,?,?,?,?,?,?) ON CONFLICT(owner,epoch,kind) DO UPDATE SET latitude=excluded.latitude,longitude=excluded.longitude,version=excluded.version,updated_at=excluded.updated_at',row.owner,row.epoch,input.kind,input.latitude,input.longitude,uuid(),now),stmt(db,'DELETE FROM world_drop_challenges WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind));result={saved:true,kind:input.kind};\r\n }else if(input.type==='remove-location'){\r\n  writes.push(stmt(db,'DELETE FROM world_drop_locations WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind),stmt(db,'DELETE FROM world_drop_challenges WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind));result={removed:true,kind:input.kind};\r\n }else{\r\n  if(!location)fail('drop_location_required');\r\n  guards.push(assert(db,'NOT EXISTS(SELECT 1 FROM world_drop_claims WHERE owner=? AND epoch=? AND kind=? AND claimed_at>?)',[row.owner,row.epoch,input.kind,now-DROP_RULES.cooldownMs]));\r\n  const priorClaim=await first(db,'SELECT claimed_at FROM world_drop_claims WHERE owner=? AND epoch=? AND kind=? ORDER BY claimed_at DESC LIMIT 1',row.owner,row.epoch,input.kind);if(priorClaim&&now-priorClaim.claimed_at<DROP_RULES.cooldownMs)fail('drop_cache_recharging');\r\n  if(input.type==='start-claim'){\r\n   validFix(input,now);near(input,location);const id=uuid(),nonce=uuid();writes.push(stmt(db,'INSERT INTO world_drop_challenges(owner,epoch,kind,id,nonce,location_version,issued_at,expires_at,first_at,first_sample,last_sample,seq) VALUES(?,?,?,?,?,?,?,?,NULL,NULL,NULL,0) ON CONFLICT(owner,epoch,kind) DO UPDATE SET id=excluded.id,nonce=excluded.nonce,location_version=excluded.location_version,issued_at=excluded.issued_at,expires_at=excluded.expires_at,first_at=NULL,first_sample=NULL,last_sample=NULL,seq=0',row.owner,row.epoch,input.kind,id,nonce,location.version,now,now+DROP_RULES.challengeMs));result={challenge:{id,nonce,expiresAt:now+DROP_RULES.challengeMs},kind:input.kind};\r\n  }else{\r\n   const challenge=await first(db,'SELECT * FROM world_drop_challenges WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind);if(!challenge||challenge.id!==input.challengeId||challenge.nonce!==input.nonce||challenge.location_version!==location.version||challenge.expires_at<now)fail('drop_challenge_expired');\r\n   validFix(input,now,challenge.issued_at);near(input,location);if(!Number.isSafeInteger(input.seq)||input.seq!==challenge.seq+1||input.sampledAt<=(challenge.last_sample??-1))fail('drop_sequence_rejected');\r\n   guards.push(assert(db,'EXISTS(SELECT 1 FROM world_drop_challenges WHERE owner=? AND epoch=? AND kind=? AND id=? AND nonce=? AND seq=? AND location_version=? AND expires_at>=?)',[row.owner,row.epoch,input.kind,challenge.id,challenge.nonce,challenge.seq,location.version,now]));\r\n   if(challenge.first_at!=null&&now-challenge.first_at>=DROP_RULES.dwellMs&&input.sampledAt-challenge.first_sample>=DROP_RULES.dwellMs){\r\n    const quote=input.kind==='gym'?gymCircuitReward(await readAccountPerformance(db,row.owner)):null;if(quote&&!quote.eligible)fail('drop_complete_a_phone_workout_first');\r\n    const id=uuid(),tier=input.kind==='gym'?'secret':'uncommon',packs=Array.from({length:quote?.secretPacks??1},(_,i)=>`reward-pack:${tier}:world-${input.kind}:${id}:${i+1}`),reward={xp:quote?.xp??0,packs,...(quote?{circuit:quote}:{})};\r\n    writes.push(stmt(db,'INSERT INTO world_drop_claims(owner,epoch,id,kind,claimed_at,xp,reward) VALUES(?,?,?,?,?,?,?)',row.owner,row.epoch,id,input.kind,now,reward.xp,JSON.stringify(reward)),stmt(db,'DELETE FROM world_drop_challenges WHERE owner=? AND epoch=? AND kind=?',row.owner,row.epoch,input.kind));result={claimed:true,kind:input.kind,claim:{id,claimedAt:now,...reward}};\r\n   }else{\r\n    writes.push(stmt(db,'UPDATE world_drop_challenges SET first_at=COALESCE(first_at,?),first_sample=COALESCE(first_sample,?),last_sample=?,seq=? WHERE owner=? AND epoch=? AND kind=?',now,input.sampledAt,input.sampledAt,input.seq,row.owner,row.epoch,input.kind));result={claimed:false,kind:input.kind,dwellMs:challenge.first_at==null?0:now-challenge.first_at};\r\n   }\r\n  }\r\n }\r\n const response={targetAccountId:row.owner,dataEpoch:row.epoch,serverTime:now,result};\r\n try{await db.batch([...guards,...writes,stmt(db,'INSERT INTO world_requests(owner,epoch,id,hash,response) VALUES(?,?,?,?,?)',row.owner,row.epoch,input.id,fingerprint,JSON.stringify(response)),stmt(db,'DELETE FROM world_assertions')]);}\r\n catch(error){const saved=await replay();if(saved){if(saved.hash!==fingerprint)fail('drop_idempotency_payload_conflict');return JSON.parse(saved.response);}const epoch=await first(db,'SELECT epoch FROM account_data_epochs WHERE owner_id=?',row.owner);if(epoch?.epoch!==row.epoch)fail('world_epoch_mismatch');if(String(error.message).includes('world_assertions')||String(error.message).includes('UNIQUE'))fail('drop_state_changed');throw error;}\r\n return response;\r\n}\r\nexport function worldDropDeletionStatements(db,owner){return ['world_drop_locations','world_drop_challenges','world_drop_claims'].map(table=>stmt(db,`DELETE FROM ${table} WHERE owner=?`,owner));}\r\nexport async function exportWorldDrops(db,owner){return {locations:(await all(db,'SELECT kind,latitude,longitude,updated_at FROM world_drop_locations WHERE owner=?',owner)),claims:(await all(db,'SELECT kind,claimed_at,xp,reward FROM world_drop_claims WHERE owner=?',owner))};}\r\n","settings-crt.css":"/* W2-2P (#137): TV site's CRT tube glass, ported to the Settings terminal screen only — never the\r\n   bezel (border/box-shadow/corner bolts) or the SATCOM top / BUILD bottom strips that\r\n   settings-frame.css (#107, lane 2L) owns. Geometry (position/size) is written inline by\r\n   settings-crt.mjs from the live screen rect; this file only styles what's drawn inside it.\r\n   Curve = a bigger tube corner radius + a stronger four-edge vignette + a soft convex highlight\r\n   band near the top + a thin inner shadow so the glass reads as recessed into the bezel, ported\r\n   from site-hint tv/tv.css .glass + .phosphor + .glare (border-radius, inset shadow,\r\n   scanline+vignette gradient, glare gradient). Conductor pass (2026-09-23) on 0a450a2: the first\r\n   cut was too faint and left a seam where the overlay stopped short of the real screen edge —\r\n   settings-crt.mjs now insets only by the border width so this sits flush; the corner bolts read\r\n   fine under the vignette's own corner darkening. Both layers are pointer-events:none overlays;\r\n   see settings-crt.mjs for why. */\r\n.crt-screen{position:fixed;pointer-events:none;z-index:6;overflow:hidden;border-radius:26px/20px;\r\n box-shadow:inset 0 0 0 1px #00000080,inset 0 0 10px 2px #00000070}\r\n.crt-screen>div{position:absolute;inset:0}\r\n.crt-vignette{\r\n background:\r\n  /* soft convex highlight band near the top — the tube's bulge catching light */\r\n  linear-gradient(180deg,#ffffff2e 0%,#ffffff12 12%,transparent 30%),\r\n  radial-gradient(ellipse 60% 40% at 24% 10%,#ffffff26,transparent 55%),\r\n  /* four-edge falloff: corners and edges read darker than the centre */\r\n  radial-gradient(ellipse 75% 70% at 50% 50%,transparent 42%,#000000b3 100%);\r\n}\r\n.crt-scanlines{\r\n /* ~3px period, ~1.5px dark line: visible at 1x per the conductor's crop check */\r\n background-image:repeating-linear-gradient(#000 0 1.5px,transparent 1.5px 3px);\r\n opacity:.22;animation:crt-roll 9s linear infinite;\r\n}\r\n@keyframes crt-roll{to{background-position-y:12px}}\r\n@media(prefers-reduced-motion:reduce){.crt-scanlines{animation:none}}\r\n/* optional: one soft band rolling slowly down the tube, on top of the fine scanlines */\r\n.crt-scan-band{\r\n background-image:linear-gradient(180deg,transparent,#9dffb01a 45%,transparent 90%);\r\n background-size:100% 45%;background-repeat:no-repeat;\r\n animation:crt-band-roll 7s linear infinite;\r\n}\r\n@keyframes crt-band-roll{0%{background-position-y:-45%}100%{background-position-y:145%}}\r\n@media(prefers-reduced-motion:reduce){.crt-scan-band{animation:none;opacity:0}}\r\n\r\n.crt-touch-layer{position:fixed;pointer-events:none;z-index:7;overflow:hidden;border-radius:26px/20px}\r\n/* the touch spot: ported from site-hint tv/tv.css .press (a growing radial spot at the touch\r\n   point, springy release) — recoloured for green phosphor instead of the site's purple/gold glass:\r\n   a darker soft centre (low opacity, not black) inside a brighter green bulge ring, alpha-blended\r\n   (no mix-blend-mode:screen — that can only lighten, so it read as a black hole instead of a lens). */\r\n.settings-touch-mark{\r\n position:absolute;width:88px;height:88px;margin:-44px 0 0 -44px;border-radius:50%;\r\n background:radial-gradient(circle,#03150d66 0 16%,#9dffb01f 26%,#9dffb080 38%,#9dffb01f 52%,transparent 68%);\r\n animation:settings-touch-pulse .5s ease-out forwards;\r\n}\r\n@keyframes settings-touch-pulse{0%{transform:scale(.25);opacity:0}30%{opacity:.9}100%{transform:scale(1);opacity:0}}\r\n@media(prefers-reduced-motion:reduce){.settings-touch-mark{animation:none;opacity:0}}\r\n","settings-crt.mjs":"// W2-2P (#137): TV touch effect + CRT curve + scan lines on the Settings terminal screen only —\r\n// never the bezel (border/box-shadow/corner bolts) or the SATCOM top / BUILD bottom strips that\r\n// settings-frame.css (#107, lane 2L) owns. Two pointer-events:none overlays are appended as the\r\n// LAST children of #settings: a dialog shown via showModal() renders in the browser's \"top layer\",\r\n// and everything painted there — including these position:fixed descendants — stays layered above\r\n// the rest of the page and above the dialog's own earlier children, so this doesn't need its own\r\n// z-index arms race with the app.\r\n//\r\n// \"Screen rect\" = the dialog's own box, inset from its border (clears the bezel) and from the top\r\n// strip's bottom edge / bottom strip's top edge (clears the labels + BUILD strip). #settings scrolls\r\n// (.terminal-menu; overflow:auto), with the top strip scrolling away and the bottom strip pinned via\r\n// position:sticky, so the rect is recomputed on open, resize and scroll rather than measured once.\r\n//\r\n// Touch effect: ported from site-hint tv/tv.js:173-207 \"press into the glass\" (tv.css .press /\r\n// .press-layer) — the growing radial glass-touch spot only. The site's screen-wide scale/sink\r\n// (tv.js grow(), scaling #screen toward the touch point) is skipped: #settings is full of real\r\n// controls, and the brief calls for a pure overlay that never blocks or delays the tap underneath,\r\n// so nothing about the dialog itself moves.\r\n// ponytail: single CSS keyframe instead of the site's rAF hold-tracking loop — good enough for a\r\n// tap; add hold-based growth (mirroring tv.js grow()) if Ian wants press-and-hold sizing later.\r\n//\r\n// Conductor pass on 0a450a2: the first cut inset the overlay by the border width PLUS 8px to clear\r\n// the corner bolts, which left a visible seam — a strip of plain dialog background between the real\r\n// screen edge and the vignette's own (darker) edge. Insetting by the border width only makes the\r\n// overlay meet the screen edge cleanly, at the cost of the vignette's corner darkening sitting over\r\n// the bolts near the very corner — an acceptable trade since that's what buys the flush edge.\r\n\r\nexport function mountSettingsCrt(settings){\r\n const screen=document.createElement('div');screen.className='crt-screen';screen.setAttribute('aria-hidden','true');\r\n screen.innerHTML='<div class=\"crt-vignette\"></div><div class=\"crt-scanlines\"></div><div class=\"crt-scan-band\"></div>';\r\n const touch=document.createElement('div');touch.className='crt-touch-layer';touch.setAttribute('aria-hidden','true');\r\n settings.append(screen,touch);\r\n\r\n function place(){\r\n  const r=settings.getBoundingClientRect();\r\n  if(!r.width){screen.style.width=touch.style.width='0px';return;}\r\n  const inset=parseFloat(getComputedStyle(settings).borderTopWidth)||0;\r\n  const top=settings.querySelector('.satcom-top')?.getBoundingClientRect()??{bottom:r.top+inset};\r\n  const bottom=settings.querySelector('.satcom-bottom')?.getBoundingClientRect()??{top:r.bottom-inset};\r\n  const left=r.left+inset,right=r.right-inset;\r\n  const y0=Math.max(top.bottom,r.top+inset),y1=Math.min(bottom.top,r.bottom-inset);\r\n  for(const el of [screen,touch]){\r\n   el.style.left=left+'px';el.style.top=y0+'px';\r\n   el.style.width=Math.max(0,right-left)+'px';el.style.height=Math.max(0,y1-y0)+'px';\r\n  }\r\n }\r\n place();\r\n // Scroll/resize fire many times a frame: one place() (3 rect reads + 4 writes) per frame at most.\r\n let queued=0;const queue=()=>{queued||=requestAnimationFrame(()=>{queued=0;place();});};\r\n document.getElementById('openSettings')?.addEventListener('click',queue);\r\n settings.addEventListener('scroll',queue,{passive:true});\r\n addEventListener('resize',queue);\r\n\r\n settings.addEventListener('pointerdown',event=>{\r\n  if(event.target.closest('.satcom-strip'))return;\r\n  const r=touch.getBoundingClientRect();\r\n  if(!r.width||event.clientX<r.left||event.clientX>r.right||event.clientY<r.top||event.clientY>r.bottom)return;\r\n  const mark=document.createElement('span');mark.className='settings-touch-mark';\r\n  mark.style.left=(event.clientX-r.left)+'px';mark.style.top=(event.clientY-r.top)+'px';\r\n  touch.append(mark);\r\n  const remove=()=>mark.remove();\r\n  mark.addEventListener('animationend',remove);\r\n  setTimeout(remove,700); // reduced motion fires no animationend; this still cleans it up\r\n },{passive:true});\r\n}\r\n","settings-frame.css":"/* #107/#120: a military-satcom frame usable on any dialog (mountSatcomFrame in coach-hub.mjs) --\r\n   Settings (#settings), the Install panel (#installPanel) and the full-screen Downloads menu\r\n   (#downloadsMenu). Decoration only — corner bezel, a SATCOM status strip on top and a BUILD/clock\r\n   strip on the bottom. The dialog's own items, their order and their behaviour are untouched. */\r\n.satcom-frame{\r\n border:3px solid #47523f!important;\r\n box-shadow:7px 7px 0 #030806,inset 0 0 0 3px #10160e,inset 0 0 0 4px #6b9e6c66!important;\r\n}\r\n.satcom-frame h2{text-shadow:0 0 6px #6fae6f99}\r\n/* Faint CRT scanlines. A ::before is never matched by the locked theme's `html[...] *` kill switch,\r\n   so this keeps animating there without any JS — see satcom-radar below for the same trick. */\r\n.satcom-frame::before{\r\n content:'';position:absolute;inset:0;z-index:5;pointer-events:none;border-radius:inherit;\r\n background-image:repeating-linear-gradient(#000 0 1px,transparent 1px 3px);\r\n opacity:.08;animation:satcom-scan 7s linear infinite;\r\n}\r\n@media(prefers-reduced-motion:reduce){.satcom-frame::before{animation:none}}\r\n\r\n.satcom-strip{display:flex;align-items:center;gap:8px;padding:7px 0;font:700 .7rem/1.3 ui-monospace,SFMono-Regular,Consolas,monospace;letter-spacing:.08em;text-transform:uppercase;color:#9be8a3;text-shadow:0 0 4px #4f9b57}\r\n.satcom-top{border-bottom:1px solid #3e5b41;margin-bottom:10px}\r\n/* #settings has the UA dialog:modal default overflow:auto, so it's the scrolling container the long\r\n   settings list scrolls inside; stick the BUILD/clock strip to its bottom so it's never below the\r\n   fold (risk 5) — sticky needs its own background or the scrolled content shows through underneath. */\r\n/* pointer-events:none: sticky, so it sits over whatever scrolls underneath it (risk: a longer\r\n   dialog's own controls, e.g. Install's Copy link, land under it) -- nothing inside is interactive. */\r\n.satcom-bottom{border-top:1px solid #3e5b41;margin-top:14px;justify-content:space-between;position:sticky;bottom:0;background:linear-gradient(140deg,#392640,#1c1426 65%);pointer-events:none}\r\n.satcom-sat{width:16px;height:16px;flex:none;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round}\r\n.satcom-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\r\n.satcom-label em{font-style:normal;color:#ffbe5c}\r\n.satcom-top.locked .satcom-label em{color:#9dffb0}\r\n.satcom-bars{display:flex;align-items:flex-end;gap:2px;flex:none}\r\n.satcom-bars i{display:block;width:3px;background:#3e5b41;opacity:.35}\r\n.satcom-bars i:nth-child(1){height:5px}.satcom-bars i:nth-child(2){height:8px}.satcom-bars i:nth-child(3){height:11px}.satcom-bars i:nth-child(4){height:14px}\r\n.satcom-top.locked .satcom-bars i{background:#9dffb0;opacity:1}\r\n@keyframes satcom-blink{0%,100%{opacity:.2}50%{opacity:1}}\r\n@keyframes satcom-flash{0%{box-shadow:inset 0 0 0 999px #9dffb033}100%{box-shadow:inset 0 0 0 999px transparent}}\r\n@keyframes satcom-scan{0%{background-position-y:0}100%{background-position-y:12px}}\r\n@keyframes satcom-spin{to{transform:rotate(1turn)}}\r\n\r\n.satcom-clock{font-variant-numeric:tabular-nums;flex:none}\r\n.satcom-build{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right}\r\n.satcom-radar{position:relative;flex:none;width:15px;height:15px;border-radius:50%;border:1px solid #3e5b41;overflow:hidden}\r\n.satcom-radar::before{content:'';position:absolute;inset:2px;border:1px solid #2b4230;border-radius:50%}\r\n.satcom-radar::after{content:'';position:absolute;inset:0;border-radius:50%;background:conic-gradient(from 0deg,#9dffb0cc,transparent 30%);animation:satcom-spin 4s linear infinite}\r\n@media(prefers-reduced-motion:reduce){.satcom-radar::after{animation:none}}\r\n\r\n.satcom-bolt{position:absolute;width:14px;height:14px;border-color:#6b9e6c;pointer-events:none}\r\n.satcom-bolt::after{content:'';position:absolute;width:5px;height:5px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#cfead0,#5b7a5c 70%);box-shadow:0 0 0 1px #253524}\r\n.satcom-bolt-tl{top:6px;left:6px;border-top:2px solid;border-left:2px solid}\r\n.satcom-bolt-tl::after{top:-1px;left:-1px}\r\n.satcom-bolt-tr{top:6px;right:6px;border-top:2px solid;border-right:2px solid}\r\n.satcom-bolt-tr::after{top:-1px;right:-1px}\r\n.satcom-bolt-bl{bottom:6px;left:6px;border-bottom:2px solid;border-left:2px solid}\r\n.satcom-bolt-bl::after{bottom:-1px;left:-1px}\r\n.satcom-bolt-br{bottom:6px;right:6px;border-bottom:2px solid;border-right:2px solid}\r\n.satcom-bolt-br::after{bottom:-1px;right:-1px}\r\n\r\n@media(max-width:380px){.satcom-strip{font-size:.62rem}}\r\n/* The Downloads menu is full screen with no padding of its own, so the frame would sit on the glass's\r\n   edges and rounded corners (the clock's first digit ran under the bottom-left bolt): pull the bolts in\r\n   from the corners and pad both strips clear of them. */\r\n.downloads-menu .satcom-strip{padding-left:max(32px,env(safe-area-inset-left));padding-right:max(32px,env(safe-area-inset-right))}\r\n.downloads-menu .satcom-top{margin-bottom:0;padding-top:max(9px,env(safe-area-inset-top))}\r\n.downloads-menu .satcom-top+.downloads-page{padding-top:16px} /* the strip already clears the notch */\r\n.downloads-menu .satcom-bottom{margin-top:0;padding-bottom:max(9px,env(safe-area-inset-bottom))}\r\n.downloads-menu .satcom-bolt-tl,.downloads-menu .satcom-bolt-tr{top:max(10px,env(safe-area-inset-top))}\r\n.downloads-menu .satcom-bolt-bl,.downloads-menu .satcom-bolt-br{bottom:max(10px,env(safe-area-inset-bottom))}\r\n.downloads-menu .satcom-bolt-tl,.downloads-menu .satcom-bolt-bl{left:max(10px,env(safe-area-inset-left))}\r\n.downloads-menu .satcom-bolt-tr,.downloads-menu .satcom-bolt-br{right:max(10px,env(safe-area-inset-right))}\r\n","shader-aurora.mjs":"// Pure placement recipes. The shared manager owns canvases, GPU support and lifecycle.\r\n// Props checked against shaders' Aurora definition; two curtains stay fixed because\r\n// curtainCount is a compile-time prop. Existing room/portrait art remains underneath.\r\nconst canvasStyle = {\r\n  position: 'absolute',\r\n  top: '0',\r\n  left: '0',\r\n  width: '100%',\r\n  height: '42%',\r\n  zIndex: '0',\r\n  pointerEvents: 'none',\r\n  imageRendering: 'auto',\r\n  transform: 'none',\r\n  objectFit: 'fill',\r\n  maxWidth: 'none',\r\n};\r\n\r\nfunction meditationActive(host) {\r\n  const dialog = host?.closest?.('.meditation-panel');\r\n  const scene = host?.closest?.('[data-meditation-scene]');\r\n  if (!dialog?.open || scene?.hidden || host?.isConnected === false) return false;\r\n  if (['breathing-paused', 'snorting', 'blacking-out'].some(name => dialog.classList.contains(name))) return false;\r\n  // The released scene uses a waterfall backdrop for every day's wonder.\r\n  // Add only ambient sky light; the backdrop and grayscale reveal remain intact.\r\n  return true;\r\n}\r\n\r\nfunction meditationComponents() {\r\n  return [{\r\n    type: 'Aurora',\r\n    props: {\r\n      colorA: '#a533f8', colorB: '#76dfb0', colorC: '#479bc4',\r\n      intensity: 35, curtainCount: 2, speed: 1.2,\r\n      waviness: 35, rayDensity: 16, height: 95,\r\n      center: { x: .5, y: .05 }, seed: 5,\r\n    },\r\n  }];\r\n}\r\n\r\nfunction portraitActive(host) {\r\n  return !!host?.querySelector?.('#avatar') && host.isConnected !== false && !host.closest?.('[hidden]');\r\n}\r\n\r\nfunction portraitComponents() {\r\n  return [{\r\n    type: 'Aurora',\r\n    props: {\r\n      colorA: '#713150', colorB: '#cbb4e7', colorC: '#d7b56c',\r\n      intensity: 40, curtainCount: 2, speed: .8,\r\n      waviness: 28, rayDensity: 12, height: 85,\r\n      center: { x: .5, y: .03 }, seed: 5,\r\n    },\r\n  }];\r\n}\r\n\r\nexport const auroraTargets = [\r\n  {\r\n    selector: '.meditation-panel .meditation-far',\r\n    name: 'aurora', priority: 10, opacity: .25,\r\n    style: { ...canvasStyle },\r\n    active: meditationActive,\r\n    components: meditationComponents,\r\n  },\r\n  {\r\n    selector: '.atelier .portrait',\r\n    name: 'aurora', priority: 10, opacity: .25,\r\n    style: { ...canvasStyle, height: '78%' },\r\n    active: portraitActive,\r\n    components: portraitComponents,\r\n  },\r\n];\r\n","shader-effects.css":"/* The shader is decorative; native artwork, text and touch targets stay in front. */\r\ncanvas.shaders-layer{position:absolute!important;pointer-events:none!important;image-rendering:auto!important;object-fit:fill!important;max-width:none!important;filter:none;display:block}\r\ncanvas.shaders-layer[data-shader-effect=\"hologram\"]{mix-blend-mode:screen}\r\n.meditation-far>.shaders-layer{filter:grayscale(1)!important;mix-blend-mode:screen;transition:filter 2.5s ease}\r\n.meditation-colour .meditation-far>.shaders-layer{filter:none!important}\r\n.ship-header>.shaders-layer{border-radius:inherit}\r\n.ship-header>a,.ship-header>button{position:relative;z-index:1}\r\n#holoStage{isolation:isolate}\r\n#holoStage>canvas:not(.shaders-layer){z-index:1}\r\n.portrait>.shaders-layer{z-index:0!important;filter:none!important}\r\n.dj .logobar,.reward-pack-card{position:relative}\r\n.dj .logobar>.shaders-layer{mix-blend-mode:screen}\r\n.drop-pod-card>.shaders-layer,.reward-pack-card>.shaders-layer,.creature-skin-reward>.shaders-layer{mix-blend-mode:screen}\r\n.cage-bays{position:relative;isolation:isolate}\r\n.cage-bays>button{position:relative;z-index:1}\r\n.gala-bay-stage{isolation:isolate}\r\n.gala-bay-stage>canvas:not(.shaders-layer){z-index:1}\r\n.design-studio .hand-canvas>.shaders-layer{mix-blend-mode:screen}\r\n.design-studio .hand-canvas>canvas:not(.shaders-layer){position:relative;z-index:1}\r\n@media(prefers-reduced-motion:reduce){canvas.shaders-layer{display:none!important}}\r\n","shader-effects.mjs":"// Decorative WebGPU effects. The existing artwork remains the immediate fallback.\r\nexport function startShaderEffects({targets, loadRuntime = () => import('/vendor/shaders/runtime.mjs')} = {}) {\r\n  const reduced = matchMedia('(prefers-reduced-motion: reduce)');\r\n  let spent = new WeakMap();\r\n  const failed = new WeakMap(), exhausted = new Set();\r\n  let current = null, timer = 0, stopped = false, epoch = 0, runtime, owner=null;\r\n  const canRun = () => !stopped && !document.hidden && !reduced.matches && !!navigator.gpu && !document.getElementById('mbs-game-loading') &&\r\n    document.body.dataset.cameraWorkout !== 'true' && document.body.dataset.tracking !== 'true';\r\n  function visible(host) {\r\n    if (!host.isConnected || host.closest('[hidden], [inert]')) return false;\r\n    const dialog = host.closest('dialog');\r\n    if (dialog && !dialog.open) return false;\r\n    const modal = [...document.querySelectorAll('dialog[open]')].at(-1);\r\n    if (modal && !modal.contains(host)) return false;\r\n    const tv = host.closest('#tv');\r\n    if(tv && tv.dataset.state!=='on')return false;\r\n    const style = getComputedStyle(host), rect = host.getBoundingClientRect();\r\n    return style.display !== 'none' && style.visibility !== 'hidden' && Number(style.opacity) !== 0 &&\r\n      rect.width > 1 && rect.height > 1 && rect.bottom > 0 && rect.right > 0 && rect.top < innerHeight && rect.left < innerWidth;\r\n  }\r\n  function mark(map, host, target) {\r\n    const names = map.get(host) || new Set(); names.add(target); map.set(host, names);\r\n  }\r\n  function destroy() {\r\n    epoch++;\r\n    if (!current) return;\r\n    clearTimeout(current.timeout);\r\n    current.resize?.disconnect();\r\n    current.shader?.destroy();\r\n    current.canvas.remove();\r\n    current = null;\r\n  }\r\n  function candidates() {\r\n    for(const entry of exhausted) if(!entry.host.isConnected || !entry.host.matches(entry.target.selector) || (entry.target.active && !entry.target.active(entry.host))) {\r\n      spent.get(entry.host)?.delete(entry.target); exhausted.delete(entry);\r\n    }\r\n    const list = [];\r\n    for (const target of targets || []) for (const host of document.querySelectorAll(target.selector)) {\r\n      const active = !target.active || target.active(host);\r\n      if (!active) { spent.get(host)?.delete(target); failed.get(host)?.delete(target); continue; }\r\n      if (!spent.get(host)?.has(target) && !failed.get(host)?.has(target) && visible(host)) list.push({target, host});\r\n    }\r\n    return list.sort((a,b) => (b.target.priority || 0) - (a.target.priority || 0));\r\n  }\r\n  function resize(entry) {\r\n    if (!entry.shader || !entry.canvas.isConnected) return;\r\n    const {width,height} = entry.canvas.getBoundingClientRect();\r\n    // Explicit bounded dimensions keep decorative surfaces inexpensive on high-DPR phones.\r\n    const scale = Math.min(1, 600 / Math.max(1,width), 400 / Math.max(1,height)) / Math.max(1,devicePixelRatio || 1);\r\n    const cssWidth=entry.canvas.style.width, cssHeight=entry.canvas.style.height;\r\n    entry.shader.resize(Math.max(1,Math.round(width*scale)), Math.max(1,Math.round(height*scale)));\r\n    entry.canvas.style.width=cssWidth; entry.canvas.style.height=cssHeight;\r\n  }\r\n  async function mount({target, host}) {\r\n    const canvas = document.createElement('canvas');\r\n    canvas.className = 'shaders-layer'; canvas.dataset.shader = target.name; canvas.dataset.shaderEffect=target.name;\r\n    canvas.setAttribute('aria-hidden','true');\r\n    Object.assign(canvas.style, {position:'absolute',inset:'0',width:'100%',height:'100%',pointerEvents:'none',opacity:String(target.opacity ?? .35),zIndex:'0',...target.style});\r\n    host.append(canvas);\r\n    const entry = current = {host,target,canvas,shader:null};\r\n    const request = ++epoch;\r\n    try {\r\n      runtime ||= loadRuntime();\r\n      const {createShader} = await runtime;\r\n      if (request !== epoch || !canRun() || !visible(host) || (target.active && !target.active(host))) {\r\n        if (current === entry) destroy(); return;\r\n      }\r\n      const shader = await createShader(canvas,{components:target.components(host)},{disableTelemetry:true,observeElement:false,onError:()=>{\r\n        setTimeout(()=>{if(current===entry && entry.shader?.getFailureReason?.()){mark(failed,host,target);destroy();schedule();}},0);\r\n      }});\r\n      if (request !== epoch || !canRun() || !visible(host) || (target.active && !target.active(host))) {\r\n        shader.destroy(); if (current === entry) destroy(); return;\r\n      }\r\n      if (shader.getFailureReason?.()) { shader.destroy(); mark(failed,host,target); destroy(); return; }\r\n      entry.shader = shader; resize(entry);\r\n      entry.resize = new ResizeObserver(() => resize(entry)); entry.resize.observe(host);\r\n      if (target.durationMs) entry.timeout = setTimeout(() => { mark(spent,host,target); exhausted.add({host,target}); if (current === entry) destroy(); schedule(); },target.durationMs);\r\n    } catch {\r\n      mark(failed,host,target);\r\n      if (current === entry) destroy();\r\n    }\r\n  }\r\n  function sync() {\r\n    timer = 0;\r\n    if (!canRun()) { destroy(); return; }\r\n    const next = candidates()[0];\r\n    if (current && next?.host === current.host && next.target === current.target) return;\r\n    destroy(); if (next) void mount(next);\r\n  }\r\n  function schedule() {\r\n    if (!stopped && !timer) timer = setTimeout(sync,80);\r\n  }\r\n  const observer = new MutationObserver(records=>{\r\n    for(const entry of exhausted) for(const record of records) if(record.target.contains?.(entry.host) &&\r\n      (record.attributeName==='data-phase' || record.attributeName==='open' ||\r\n        (record.attributeName==='class' && record.target.matches('.reward-pack-dialog') && !String(record.oldValue).split(/\\s+/).includes('opened')))) {\r\n      spent.get(entry.host)?.delete(entry.target);exhausted.delete(entry);break;\r\n    }\r\n    schedule();\r\n  });\r\n  observer.observe(document.body,{subtree:true,childList:true,attributes:true,attributeOldValue:true,attributeFilter:['open','hidden','inert','class','data-state','data-phase','data-screen','data-camera-workout','data-tracking','data-wonder']});\r\n  const events = ['scroll','resize','visibilitychange','pageshow'];\r\n  for (const type of events) window.addEventListener(type,schedule,{passive:true,capture:true});\r\n  reduced.addEventListener('change',schedule);\r\n  const clear = () => { spent=new WeakMap(); exhausted.clear(); destroy(); schedule(); };\r\n  const account = event => {const next=`${event.detail?.user?.id || ''}/${event.detail?.dataEpoch ?? ''}`;if(next!==owner){owner=next;clear();}};\r\n  window.addEventListener('myr5:account-cleared',clear);\r\n  window.addEventListener('myr5:account-ready',account);\r\n  function dispose() {\r\n    stopped = true; clearTimeout(timer); timer = 0; destroy(); observer.disconnect();\r\n    for (const type of events) window.removeEventListener(type,schedule,true);\r\n    reduced.removeEventListener('change',schedule);\r\n    window.removeEventListener('myr5:account-cleared',clear);\r\n    window.removeEventListener('myr5:account-ready',account);\r\n    window.removeEventListener('pagehide',hide);\r\n  }\r\n  const hide = () => { clearTimeout(timer); timer=0; destroy(); };\r\n  window.addEventListener('pagehide',hide); schedule();\r\n  return {dispose,refresh:schedule};\r\n}\r\n","shader-entry.mjs":"import {startShaderEffects} from './shader-effects.mjs';\r\nimport {auroraTargets} from './shader-aurora.mjs';\r\nimport {hologramTargets} from './shader-hologram.mjs';\r\nimport {sparkleTargets} from './shader-sparkle.mjs';\r\nstartShaderEffects({targets:[...auroraTargets,...hologramTargets,...sparkleTargets]});\r\n","shader-hologram.mjs":"// Decorative recipes for shaders 4.0.4 Hologram. The shared manager owns canvases\r\n// and lifecycle; exercise/hand Three.js models and controls stay in their hosts.\r\n// SDF names/fields checked against the npm package's analytic shape resolver:\r\n// ellipseSDF / roundedRectSDF use radius (half-width), height and rounding.\r\nconst available = host => !!host?.isConnected && !host.closest('[hidden], [aria-hidden=\"true\"]') &&\r\n  (!host.closest('dialog') || host.closest('dialog').open);\r\n\r\nconst projection = (color, shape) => [{\r\n  type: 'Hologram',\r\n  props: {\r\n    color, shape: JSON.stringify(shape), scale: 3,\r\n    center: {x: .5, y: .5}, brightness: .8, fill: .12,\r\n    edgeGlow: .6, edgeSoftness: .03, depthLines: .12, depthScale: 12,\r\n    scanlines: .18, scanlineScale: 60, scanlineSpeed: .2,\r\n    sweep: .025, flicker: 0, distortion: 0, grain: .05, speed: .25,\r\n  },\r\n}];\r\nconst plate = {type: 'roundedRectSDF', radius: .44, height: .1, rounding: .04};\r\nconst pedestal = {type: 'ellipseSDF', radius: .44, height: .07};\r\n\r\nexport const hologramTargets = [\r\n  {\r\n    selector: 'body[data-screen=\"pod\"] > .ship-header, #portalWorkoutHome > .ship-header',\r\n    name: 'hologram', priority: 20, opacity: .24,\r\n    // A small plate accent in the open centre, clear of the brand and Settings.\r\n    style: {top: '5px', left: 'calc(50% - 56px)', width: '112px', height: '30px', zIndex: '0'},\r\n    active: host => available(host) &&\r\n      (!!host.closest('#portalWorkoutHome') || host.ownerDocument?.body?.dataset.screen === 'pod'),\r\n    components: () => projection('#b877ed', plate),\r\n  },\r\n  {\r\n    selector: '#hologramPanel #holoStage',\r\n    name: 'hologram', priority: 20, opacity: .3,\r\n    // Small projection light in the stage margin, clear of the figure and setup controls.\r\n    style: {bottom: 'auto', top: '12px', left: '12px', width: '64px', height: '32px', zIndex: '0'},\r\n    active: host => available(host) && !!host.closest('#hologramPanel') &&\r\n      !!host.closest('dialog')?.open,\r\n    components: () => projection('#9afae4', pedestal),\r\n  },\r\n  {\r\n    selector: '.war-room .gala-bay-stage',\r\n    name: 'hologram', priority: 20, opacity: .24,\r\n    style: {bottom: 'auto', top: '80px', left: '12px', width: '64px', height: '32px', zIndex: '2'},\r\n    active: host => available(host) && !!host.closest('.war-room'),\r\n    components: () => projection('#ff9a1f', plate),\r\n  },\r\n  {\r\n    // The current hand customizer owns the model and floor. Keep a projection\r\n    // light in its empty upper corner, clear of the hand and bottom view tools.\r\n    selector: '.design-studio .viewport-panel .hand-canvas',\r\n    name: 'hologram', priority: 20, opacity: .28,\r\n    style: {inset: 'auto', top: '12px', right: '12px', width: '64px', height: '32px', zIndex: '2'},\r\n    active: host => available(host) && !!host.closest('.design-studio') &&\r\n      !!host.querySelector('canvas:not([data-shader-effect])') &&\r\n      !host.closest('.hand-viewer-wrap')?.querySelector('.model-status'),\r\n    components: () => projection('#78ffdc', pedestal),\r\n  },\r\n];\r\n","shader-sparkle.mjs":"// Sparkle filters its shader children, not the DOM beneath its canvas. These small\r\n// ornaments supply their own bright Star art; rewards, tiles and text stay intact.\r\n// Verified against shader-effects-inc/shaders packages/core/src/shaders/{Sparkle,Star}.\r\nconst TIER_COLORS = Object.freeze({\r\n  uncommon: '#76e356', rare: '#4bafff', legendary: '#ff9c36', secret: '#b388ff',\r\n});\r\n\r\nconst tierColor = host => TIER_COLORS[host?.closest?.('[data-tier]')?.dataset?.tier] || '#ffe39a';\r\nconst hasUnlock = host => [...(host?.querySelectorAll?.('strong') || [])]\r\n  .some(item => / unlocked!$/.test(item.textContent || ''));\r\nconst openedDialog = (host, selector) => host?.closest?.(selector)?.open === true;\r\n\r\nfunction ornament(color, seed = 0) {\r\n  return [{\r\n    type: 'Sparkle',\r\n    id: 'reward-sparkle',\r\n    props: {\r\n      size: 16, intensity: 2.2, threshold: .45, expand: 0,\r\n      rayLength: 2, colorize: .65, speed: .65, seed,\r\n    },\r\n    children: [{\r\n      type: 'Star', id: 'reward-sparkle-art',\r\n      props: {color, center: {x: .5, y: .5}, radius: .42, sides: 4, innerRatio: .18},\r\n    }],\r\n  }];\r\n}\r\n\r\nconst cornerStyle = Object.freeze({\r\n  position: 'absolute', inset: 'auto', top: '12px', right: '12px',\r\n  width: '56px', height: '56px', pointerEvents: 'none', zIndex: '1',\r\n});\r\n\r\n// The shared manager owns visibility, camera/reduced-motion guards, GPU setup,\r\n// timeouts and cleanup. These descriptors never grant, clear or persist rewards.\r\nexport const sparkleTargets = [\r\n  {\r\n    selector: '.drop-pod[data-phase=\"reveal\"] .drop-pod-card',\r\n    name: 'sparkle', priority: 50, opacity: .6, durationMs: 2200,\r\n    style: {...cornerStyle, top: '4px', right: '4px',width:'40px',height:'40px'},\r\n    active: host => openedDialog(host, '.drop-pod') &&\r\n      host.closest('.drop-pod').dataset?.phase === 'reveal' && hasUnlock(host),\r\n    components: host => ornament(tierColor(host)),\r\n  },\r\n  {\r\n    // A canvas cannot visibly host another canvas. Mount in the surrounding card\r\n    // and put the ornament beside the existing 2D reward tile instead.\r\n    selector: '.reward-pack-dialog.opened .reward-pack-card',\r\n    name: 'sparkle', priority: 50, opacity: .6, durationMs: 2200,\r\n    style: {...cornerStyle, top: '84px'},\r\n    active: host => openedDialog(host, '.reward-pack-dialog.opened') &&\r\n      !host.ownerDocument?.querySelector?.('.drop-pod[open]') &&\r\n      hasUnlock(host.querySelector?.('.reward-pack-result')),\r\n    components: host => ornament(tierColor(host), 1),\r\n  },\r\n  {\r\n    selector: '.creature-skin-reward',\r\n    name: 'sparkle', priority: 50, opacity: .6, durationMs: 2200,\r\n    style: {...cornerStyle, top: '-16px', right: '-8px', width: '44px', height: '44px'},\r\n    active: host => !!host?.querySelector?.('li'),\r\n    components: () => ornament('#ffe39a', 2),\r\n  },\r\n  {\r\n    selector: '.dj .logobar',\r\n    name: 'sparkle', priority: 50, opacity: .6, durationMs: 2200,\r\n    style: {...cornerStyle, top: '15%', left: '4%', right: 'auto', width: '80px', height: '80px'},\r\n    active: host => !!host?.querySelector?.('img'),\r\n    components: () => ornament('#fff4bd', 3),\r\n  },\r\n];\r\n\r\n// Existing .lcd-card.done nodes do not identify a newly banked unlock. A future\r\n// transition signal can opt them in without replaying old saved achievements.\r\n","signin.css":":root{font-family:system-ui,sans-serif;color:#f7efff;background:#160e20;color-scheme:dark}*{box-sizing:border-box}body{margin:0;min-height:100svh;background:radial-gradient(ellipse at 50% 0,#48235b,transparent 65%),#160e20}main{width:min(100% - 32px,440px);margin:0 auto;padding:32px 0 48px}.brand{display:flex;align-items:center;gap:12px;font-weight:750;font-size:20px;color:inherit;text-decoration:none}.brand img{width:56px;height:56px;border-radius:15px}h1{font-size:32px;line-height:1.15;margin:28px 0 12px}p{color:#d5c5df;line-height:1.5}button,.secondary{display:block;width:100%;font:inherit;font-weight:650;text-align:center;padding:14px 18px;border:1px solid #83579b;border-radius:12px;background:#ba82ec;color:#1c1026;cursor:pointer;text-decoration:none;margin:10px 0}.secondary{background:#291b35;color:#f7efff}button:disabled{opacity:.6;cursor:wait}details{margin-top:24px;border-top:1px solid #654576;padding-top:18px}summary{cursor:pointer;font-size:14px}.back{display:inline-block;color:#d6b4ee;margin-top:26px;font-size:14px}#loginStatus:empty{display:none}#login{margin-top:22px}#login .cl-rootBox,#login .cl-cardBox{width:100%}[hidden]{display:none!important}\r\n","signin.html":"<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\"><meta name=\"theme-color\" content=\"#241231\"><title>Sign in · MYR5 Coach</title><link rel=\"icon\" href=\"/icons/myr5-alien-192.png\"><link rel=\"apple-touch-icon\" href=\"/icons/myr5-alien-apple.png\"><link rel=\"stylesheet\" href=\"/signin.css\"></head><body><main><a class=\"brand\" href=\"/install\"><img src=\"/icons/myr5-alien-192.png\" alt=\"MYR5\"><span>Mom Inc</span></a><h1>Sign in</h1><p id=\"intro\">Save your progress.</p><p id=\"loginStatus\" role=\"status\">Connecting…</p><div id=\"login\"></div><section id=\"connected\" hidden><p id=\"who\"></p><button id=\"continue\">Continue to Coach</button><button id=\"switchAccount\" class=\"secondary\">Use another account</button></section><button id=\"retry\" hidden>Retry login</button><p><a class=\"back\" href=\"/privacy.html\">Privacy</a></p><a class=\"back\" href=\"/install\">Back to install</a></main><script type=\"module\" src=\"/signin.mjs\"></script></body></html>\r\n","signin.mjs":"import {authTransitions} from './auth-transition.mjs';\r\nimport {loadLogin, authSettings} from './auth-client.mjs';\r\nimport {safeReturn} from './auth-paths.mjs';\r\n\r\nconst $ = id => document.getElementById(id);\r\nconst params = new URLSearchParams(location.search);\r\nconst returnTo = safeReturn(params.get('return_to'));\r\nconst here = '/signin.html?return_to=' + encodeURIComponent(returnTo);\r\n\r\nlet currentClerk = null;\r\nlet currentListener = null;\r\nlet pendingLogin = false;\r\n\r\nfunction error(e) {\r\n  $('loginStatus').textContent = e.message || 'Login could not connect. Please retry.';\r\n  $('retry').hidden = false;\r\n}\r\n\r\nasync function startLogin({ fresh = false } = {}) {\r\n  if (pendingLogin) return;\r\n  pendingLogin = true;\r\n  $('retry').hidden = true;\r\n  $('loginStatus').textContent = 'Connecting...';\r\n  try {\r\n    const config = await authSettings({ force: fresh });\r\n    if (!config.enabled) {\r\n      authTransitions().invalidate();\r\n      localStorage.removeItem('myr5-login-provider');\r\n      error(Error('Sign-in is not available here yet.'));\r\n      return;\r\n    }\r\n    if (!config.frontend || !config.publishableKey) {\r\n      error(Error('Invalid Clerk configuration: frontend or publishableKey missing.'));\r\n      return;\r\n    }\r\n    if (fresh) {\r\n      if (currentClerk && typeof currentClerk.unmountSignIn === 'function') {\r\n        try { currentClerk.unmountSignIn($('login')); } catch (_) {}\r\n      }\r\n      if (currentListener) {\r\n        try { currentListener(); } catch (_) {}\r\n        currentListener = null;\r\n      }\r\n      currentClerk = null;\r\n    }\r\n    if (!currentClerk) {\r\n      currentClerk = await loadLogin();\r\n    }\r\n\r\n    const show = () => {\r\n      $('loginStatus').textContent = '';\r\n      if (currentClerk.user) {\r\n        $('login').hidden = true;\r\n        $('connected').hidden = false;\r\n        $('who').textContent =\r\n          'Signed in as ' +\r\n          (currentClerk.user.primaryEmailAddress?.emailAddress || 'your Mom Inc account');\r\n      } else {\r\n        $('login').hidden = false;\r\n        $('connected').hidden = true;\r\n      }\r\n    };\r\n\r\n    if (!currentClerk.user) {\r\n      $('login').hidden = false;\r\n      $('connected').hidden = true;\r\n      currentClerk.mountSignIn($('login'), {\r\n        routing: 'hash',\r\n        forceRedirectUrl: here,\r\n        signUpForceRedirectUrl: here,\r\n        appearance: { variables: { colorPrimary: '#9561c5', borderRadius: '12px' } }\r\n      });\r\n    }\r\n\r\n    if (typeof currentClerk.addListener === 'function') {\r\n      if (currentListener) {\r\n        try { currentListener(); } catch (_) {}\r\n      }\r\n      currentListener = currentClerk.addListener(show);\r\n    }\r\n\r\n    $('continue').onclick = async () => {\r\n      const button = $('continue');\r\n      button.disabled = true;\r\n      try {\r\n        const transitions = authTransitions();\r\n        transitions.invalidate();\r\n        const ticket = transitions.capture();\r\n        transitions.assertCurrent(ticket);\r\n        localStorage.setItem('myr5-login-provider', 'clerk');\r\n        transitions.invalidate();\r\n        location.assign(returnTo);\r\n      } catch (e) {\r\n        error(e);\r\n        button.disabled = false;\r\n      }\r\n    };\r\n\r\n    $('switchAccount').onclick = async () => {\r\n      try {\r\n        authTransitions().invalidate();\r\n        if (currentClerk && typeof currentClerk.signOut === 'function') {\r\n          await currentClerk.signOut();\r\n        }\r\n        localStorage.removeItem('myr5-login-provider');\r\n        location.replace(here);\r\n      } catch (e) {\r\n        error(e);\r\n      }\r\n    };\r\n\r\n  } catch (e) {\r\n    error(e);\r\n  } finally {\r\n    pendingLogin = false;\r\n\r\n  }\r\n}\r\n\r\n$('retry').onclick = () => startLogin({ fresh: true });\r\nstartLogin({ fresh: true });\r\n","space-rocks.mjs":"// The constellation's dark lit-rim asteroids, shared by the board's drift layers and the flight game's targets.\r\nconst rand=(a,b)=>a+Math.random()*(b-a);\r\nexport const asteroid=(r0,r1)=>({r:rand(r0,r1),rot:rand(0,7),vr:rand(-.3,.3),verts:Array.from({length:8},()=>rand(.55,1))});\r\nfunction poly(ctx,cx,cy,r,rot,verts){\r\n ctx.beginPath();\r\n verts.forEach((v,i)=>{const a=rot+i/verts.length*Math.PI*2,x=cx+Math.cos(a)*r*v,y=cy+Math.sin(a)*r*v;i?ctx.lineTo(x,y):ctx.moveTo(x,y);});\r\n ctx.closePath();\r\n}\r\n// Irregular dark polygon with a lit rim (a directional gradient stroke) — cheap stand-in for a lit asteroid.\r\nexport function rock(ctx,cx,cy,r,rot,verts,alpha){\r\n const g=ctx.createLinearGradient(cx-r,cy-r,cx+r*.2,cy+r*.2);\r\n g.addColorStop(0,'rgba(255,255,255,.6)');g.addColorStop(1,'rgba(255,255,255,0)');\r\n ctx.globalAlpha=alpha;ctx.strokeStyle=g;ctx.lineWidth=1.2;poly(ctx,cx,cy,r,rot,verts);ctx.fillStyle='#0c0818';ctx.fill();ctx.stroke();ctx.globalAlpha=1;\r\n}\r\n","spotify-domain.mjs":"// Spotify-facing values are deliberately reduced to fields the terminal displays.\r\nexport const SPOTIFY_SCOPES = [\r\n  'user-read-private', 'user-read-currently-playing', 'user-read-playback-state',\r\n  'user-modify-playback-state', 'playlist-read-private', 'playlist-read-collaborative',\r\n].join(' ');\r\n\r\nexport function spotifyJamLink(value) {\r\n  try {\r\n    const u = new URL(String(value).trim());\r\n    if (u.protocol !== 'https:' || !['spotify.link', 'open.spotify.com'].includes(u.hostname)) return null;\r\n    if (u.username || u.password || u.port || u.hash) return null;\r\n    if (u.hostname === 'open.spotify.com' && !/^\\/socialsession\\/[A-Za-z0-9]+\\/?$/.test(u.pathname)) return null;\r\n    if (u.hostname === 'spotify.link' && !/^\\/[A-Za-z0-9]+\\/?$/.test(u.pathname)) return null;\r\n    return u.href;\r\n  } catch { return null; }\r\n}\r\n\r\nexport function spotifyPlaylist(item) {\r\n  return {id:item?.id||'',name:item?.name||'Untitled playlist',tracks:Number(item?.items?.total??item?.tracks?.total??0),image:item?.images?.[0]?.url||null,url:item?.external_urls?.spotify||null};\r\n}\r\n\r\nexport function spotifyTrack(item) {\r\n  if(!item||typeof item!=='object')return null;\r\n  return {id:typeof item.id==='string'?item.id:null,name:item.name||'Unknown track',artists:(item.artists||[]).map(a=>a?.name).filter(Boolean),album:item.album?.name||null,image:item.album?.images?.[0]?.url||null,url:item.external_urls?.spotify||null,durationMs:Number(item.duration_ms)||0,uri:item.uri||(item.id?`spotify:track:${item.id}`:null)};\r\n}\r\n\r\nexport function spotifyDevice(item) {\r\n  return {id:item?.id||null,name:item?.name||'Unknown device',active:!!item?.is_active,restricted:!!item?.is_restricted,volumePercent:Number.isInteger(item?.volume_percent)?item.volume_percent:null,supportsVolume:!!item?.supports_volume};\r\n}\r\n\r\nexport function spotifyNowPlaying(data) {\r\n  const item=data?.item,base={playing:!!data?.is_playing,progressMs:Number(data?.progress_ms)||0,durationMs:Number(item?.duration_ms)||0,device:data?.device?.name||null,deviceId:data?.device?.id||null,volumePercent:Number.isInteger(data?.device?.volume_percent)?data.device.volume_percent:null,shuffle:!!data?.shuffle_state,repeat:['off','context','track'].includes(data?.repeat_state)?data.repeat_state:'off'};\r\n  return {...base,track:item?spotifyTrack(item):null,bpm:null};\r\n}\r\n\r\n// Tempo is only active when a provider actually supplies a measured value.\r\nexport function handPulse(tempo,progressMs=0) {\r\n  if (!Number.isFinite(tempo)||tempo<=0||tempo>400) return null;\r\n  let movement=tempo;\r\n  if(movement>=30) movement/=Math.max(1,Math.floor(movement/30));\r\n  while(movement<30) movement*=2;\r\n  const period=60000/movement;\r\n  return {movementBpm:movement,periodMs:period,phase:((progressMs%period)+period)%period/period};\r\n}\r\n","spotify-return.mjs":"export function spotifyReturnMessage(result){\r\n  return ({denied:'Spotify connection was cancelled. Tap Connect Spotify to try again.',expired:'Spotify sign in expired. Tap Connect Spotify to start again.',failed:'Spotify could not finish connecting. Tap Connect Spotify to try again.',\r\n    browser:'Spotify finished in a different browser than Coach. On iPhone, open Coach in Safari (not the Home Screen app), then tap Connect Spotify again.',\r\n    notlisted:'Spotify accepted your sign in, but this Spotify account is not on the Coach test list yet. Ask Ian to add your Spotify email, then tap Connect Spotify.',\r\n    incomplete:'Spotify sign in did not finish. If it stopped at the terms page, tap Agree there, or open Coach in Safari and tap Connect Spotify again.'})[result]||null;\r\n}\r\n","spotify-terminal.css":".spotify-terminal{width:min(760px,calc(100vw - 20px));max-width:760px;max-height:calc(100dvh - 20px);padding:0;border:2px solid #e96920;border-radius:18px;background:#120c09;color:#ffcf92;box-shadow:0 0 0 5px #2c160c,0 22px 80px #000d, inset 0 0 35px #f672221c;font:14px/1.4 ui-monospace,SFMono-Regular,Consolas,monospace}\r\n.spotify-terminal::backdrop{background:#030201df;backdrop-filter:blur(6px)}\r\n.sp-deck-hardware{position:relative;display:flex;align-items:center;justify-content:space-between;height:154px;margin:12px 0 18px;padding:12px 28px;border:2px solid #87817c;border-bottom:6px solid #281e1b;border-radius:14px;background:linear-gradient(130deg,#c8b4a921,transparent 38%,#ffc47e12 72%,transparent),repeating-linear-gradient(0deg,#ffffff05 0 1px,transparent 1px 3px),linear-gradient(150deg,#40352f,#16130f 65%,#33231c);box-shadow:inset 0 2px #fff7,inset 0 -4px #0009,0 9px 15px #0009}.sp-platter{position:relative;width:124px;height:124px;border:7px solid #262020;border-radius:50%;background:repeating-radial-gradient(circle,#121012 0 2px,#34303a 2px 3px);box-shadow:0 0 0 3px #8e8581,0 6px 9px #000b,inset 0 0 18px #000}.sp-platter:after{content:'';position:absolute;inset:34%;border:2px solid #c48943;border-radius:50%;background:#f2a24f;box-shadow:0 0 8px #f18931}.sp-platter i{position:absolute;inset:49%;border-radius:50%;background:#f4e0c3;z-index:1}.sp-tonearm{position:absolute;left:137px;top:20px;width:min(26%,150px);height:10px;border:2px solid #9a9699;border-radius:8px;background:linear-gradient(#e6d9ca,#6d6264);transform:rotate(22deg);transform-origin:right center;box-shadow:1px 3px 5px #000}.sp-tonearm:after{content:'';position:absolute;left:-8px;top:-5px;width:18px;height:18px;border-radius:4px;background:#d18c45;box-shadow:0 1px 4px #000}.sp-deck-leds{display:flex;flex-direction:column;gap:10px;margin-left:auto;padding:10px 12px;border:1px solid #6b513b;border-radius:6px;background:#0b0909}.sp-deck-leds b{display:flex;align-items:center;gap:8px;color:#bd9f83;font-size:9px;letter-spacing:.1em}.sp-deck-leds b:before{content:'';width:9px;height:9px;border-radius:50%;background:#e98933;box-shadow:0 0 7px #e98933}\r\n.spotify-terminal *{box-sizing:border-box}.spotify-terminal button,.spotify-terminal a{font:inherit}.spotify-terminal button{min-height:42px;border:1px solid #f68539;border-radius:6px;background:#31170e;color:#ffbd79;cursor:pointer;box-shadow:inset 0 1px #ffd29833,0 3px #100906}.spotify-terminal button:hover,.spotify-terminal a:hover{background:#50210e;color:#fff2d8}.spotify-terminal button:active{transform:translateY(2px);box-shadow:inset 0 2px #100906}.spotify-terminal :focus-visible{outline:2px solid #fff0b8;outline-offset:3px}.spotify-terminal [hidden]{display:none!important}\r\n.sp-shell{display:grid;grid-template-rows:auto minmax(0,1fr) auto;min-height:min(780px,calc(100dvh - 20px))}.sp-top{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:18px 22px 14px;border-bottom:2px solid #80330f;background:linear-gradient(115deg,#3f1709,#160e0b 75%)}.sp-label{display:block;font-size:11px;font-weight:700;letter-spacing:.15em;color:#f1853e}.sp-top h2{margin:0;font-size:clamp(23px,5vw,36px);line-height:1;letter-spacing:.09em;color:#ffb45c;text-shadow:0 0 14px #f77d2a88}.sp-top .sp-close{min-width:44px;font-size:24px}.sp-screen{overflow-y:auto;padding:18px 22px 42px;background:repeating-linear-gradient(0deg,#0000 0 3px,#0003 3px 4px),radial-gradient(ellipse at 50% 0,#5b250e66,transparent 65%)}.sp-screen>section{margin:0 0 20px;padding:16px;border:1px solid #77401e;border-radius:10px;background:#170d09d9;box-shadow:inset 0 0 20px #0005,0 0 15px #c65a1b13}.sp-status{min-height:20px;margin:0 0 16px;color:#ffd096;letter-spacing:.08em}.sp-account{display:flex;align-items:center;gap:12px;flex-wrap:wrap}.sp-account-name{margin-right:auto;color:#ffe3ba}.sp-account-actions{display:flex;gap:8px}.sp-account-actions button{padding:6px 12px}.sp-track{display:grid;grid-template-columns:76px minmax(0,1fr);gap:14px;align-items:center;margin:14px 0}.sp-art,.sp-playlist-art{display:grid;place-items:center;overflow:hidden;border:1px solid #a75827;border-radius:6px;background:#29130c;color:#e9883e;font-size:30px}.sp-art{width:76px;height:76px}.sp-art img,.sp-playlist-art img{width:100%;height:100%;object-fit:cover}.sp-track strong,.sp-track span{display:block;overflow-wrap:anywhere}.sp-title{font-size:19px;color:#ffe1ad}.sp-artist{color:#eeb17f}.sp-progress{display:flex;align-items:center;gap:10px}.sp-progress-bar{flex:1;min-width:0;height:9px;accent-color:#ff982f}.sp-time{white-space:nowrap;font-size:11px}.sp-controls{display:flex;justify-content:center;gap:8px;margin:16px 0}.sp-controls button{min-width:64px;padding:6px 12px}.sp-device{margin:8px 0 0;color:#ba8b69;font-size:11px}.sp-hand{display:grid;grid-template-columns:1fr minmax(120px,200px);align-items:center;gap:4px 16px}.sp-hand .sp-label,.sp-hand-status{grid-column:1}.sp-hand-mount{grid-column:2;grid-row:1/3;width:100%;height:150px;display:grid;place-items:center}.sp-hand-mount img{max-width:100%;max-height:100%;object-fit:contain;filter:drop-shadow(0 0 15px #ff8a3180)}.sp-hand-mount canvas{max-width:100%;max-height:100%}.sp-hand-mount.sp-beating{animation:sp-hand-beat var(--sp-beat-ms) ease-in-out var(--sp-phase-ms) infinite}.sp-hand-status{margin:0;color:#d9a174;font-size:11px}.sp-jam p{margin:8px 0 12px}.sp-open-spotify{display:inline-block;padding:9px 12px;border:1px solid #e57b2a;border-radius:6px;color:#ffd5a4;text-decoration:none}.sp-jam-form{margin-top:15px}.sp-jam-form label{display:block;margin:0 0 5px;font-size:11px}.sp-jam-form>div{display:flex;gap:8px}.sp-jam-form input{min-width:0;flex:1;min-height:42px;padding:8px;border:1px solid #a75827;border-radius:6px;background:#0b0706;color:#ffe2bd;font:inherit}.sp-jam-form button{padding:7px 12px}.sp-jam-status{min-height:16px;color:#ffae73;font-size:11px}.sp-playlist-heading{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.sp-count{color:#c58c63;font-size:11px}.sp-playlist-list{list-style:none;padding:0;margin:0}.sp-playlist{display:grid;grid-template-columns:52px minmax(0,1fr) auto;gap:10px;align-items:center;padding:8px 0;border-top:1px solid #5a2b15}.sp-playlist-art{width:52px;height:52px;font-size:20px}.sp-playlist-info{min-width:0}.sp-playlist-info strong,.sp-playlist-info small{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sp-playlist-info strong{color:#ffe1ad}.sp-playlist-info small{color:#b98b68}.sp-playlist-play{padding:5px 10px}.sp-more{display:block;width:100%;margin-top:12px}.sp-shell footer{padding:9px 20px;border-top:1px solid #743211;color:#a87553;text-align:center;font-size:10px;letter-spacing:.07em}\r\n@keyframes sp-hand-beat{0%,100%{transform:translateY(0) rotate(-2deg)}20%{transform:translateY(-9px) rotate(2deg)}50%{transform:translateY(0) rotate(-2deg)}}\r\n@media(max-width:540px){.sp-shell{min-height:calc(100dvh - 20px)}.sp-top{padding:12px}.sp-screen{padding:12px 12px 36px}.sp-screen>section{padding:12px}.sp-deck-hardware{height:120px;padding:8px}.sp-platter{width:95px;height:95px}.sp-tonearm{left:91px;top:12px;width:75px}.sp-deck-leds{gap:5px;padding:6px}.sp-hand{grid-template-columns:1fr 115px}.sp-hand-mount{height:120px}.sp-controls button{min-width:50px;padding:5px}.sp-jam-form>div{flex-wrap:wrap}.sp-jam-form button{width:100%}.sp-account-actions{width:100%}.sp-account-actions button{flex:1}}\r\n@media(prefers-reduced-motion:reduce){.sp-hand-mount.sp-beating{animation:none}.spotify-terminal button{transition:none}}\r\n/* The transparent hand hovers over the small physical controller at the end of the records. */\r\n.sp-screen>section.sp-hand{position:relative;display:block;min-height:255px;padding:0;border:0;background:none;box-shadow:none}\r\n.sp-hand>.sp-label,.sp-hand>.sp-hand-status{position:relative;z-index:2;max-width:45%;font-size:10px}\r\n.sp-hand .sp-hand-mount{position:absolute;z-index:2;right:5%;top:-12px;width:65%;height:190px;pointer-events:none;background:none}\r\n.sp-hand .sp-deck-hardware{position:absolute;left:4%;right:4%;bottom:0;height:105px;margin:0;padding:12px 18px;transform:perspective(500px) rotateX(14deg);background:linear-gradient(145deg,#5b5551,#19181b);border-radius:18px}\r\n.sp-hand .sp-platter{box-sizing:border-box;width:90px;height:90px;margin:0;padding:0;min-width:0;min-height:0;cursor:pointer}\r\n.sp-hand .sp-tonearm{left:98px;top:16px;width:55px}\r\n.sp-mixer{display:flex;align-items:center;gap:14px;margin-left:auto}\r\n.sp-hand .sp-knob{position:relative;width:26px;height:26px;min-width:0;min-height:0;padding:0;border:3px ridge #918e86;border-radius:50%;background:radial-gradient(circle at 35% 30%,#737778,#27272b);box-shadow:0 3px 5px #0009}\r\n.sp-hand .sp-knob:after{content:'';position:absolute;top:1px;left:9px;width:2px;height:8px;background:#ffb568;transform:rotate(-20deg)}\r\n.sp-hand .sp-fader{position:relative;width:18px;height:64px;min-width:0;min-height:0;padding:0;border:2px inset #696562;border-radius:4px;background:#09090a}\r\n.sp-hand .sp-fader:after{content:'';position:absolute;left:-5px;right:-5px;top:25px;height:11px;border:1px solid #efcf9f;background:linear-gradient(#d7b482,#786650);border-radius:2px}\r\n.sp-hand .sp-deck-leds{margin-left:10px;padding:5px;font-size:7px}\r\n@media(max-width:400px){.sp-mixer{gap:8px}.sp-hand .sp-deck-leds{display:none}}\r\n\r\n/* The DJ hand stays above the lower-right corner while the records scroll. */\r\n.sp-shell{position:relative;height:min(780px,calc(100dvh - 20px));min-height:0;overflow:hidden}\r\n.sp-shell>.sp-hand-mount{position:absolute;right:10px;bottom:calc(30px + env(safe-area-inset-bottom));top:auto;z-index:4;width:clamp(130px,25vw,190px);height:190px;overflow:hidden;pointer-events:none;background:none}\r\n.sp-shell>.sp-hand-mount canvas{width:100%;height:100%;display:block}\r\n.sp-shell>.sp-hand-mount img{width:100%;height:125%;max-height:none;object-fit:cover;object-position:center top;align-self:start}\r\n.sp-screen>section.sp-hand{min-height:150px}\r\n@media(max-width:540px){.sp-shell{height:calc(100dvh - 20px);min-height:0}.sp-shell>.sp-hand-mount{width:135px;height:170px;right:6px;bottom:calc(32px + env(safe-area-inset-bottom))}}\r\n","spotify-terminal.mjs":"import {spotifyJamLink} from './spotify-domain.mjs';\r\nimport {signInPath} from './auth-paths.mjs';\r\nimport {spotifyReturnMessage} from './spotify-return.mjs';\r\nimport {mountActualDJ} from './actual-dj.mjs';\r\n\r\nconst make=(tag,className,text)=>{const el=document.createElement(tag);if(className)el.className=className;if(text!=null)el.textContent=text;return el;};\r\nconst fmt=ms=>`${Math.floor((ms||0)/60000)}:${String(Math.floor(((ms||0)%60000)/1000)).padStart(2,'0')}`;\r\n\r\n// request(path, options) must be the app's authenticated fetch bridge and return a Response.\r\n// The bridge owns Clerk/ChatGPT session headers; this module never sees OAuth tokens.\r\nexport function initSpotifyTerminal({request=fetch,getAccount=()=>window.myr5AuthenticatedAccount}={}) {\r\n  let dialog=document.getElementById('spotifyPanel'),abort=null,poll=null,playing=false,disposed=false,connected=false,playlistOffset=0,playlistTotal=0;\r\n  if(!dialog){dialog=make('dialog','spotify-terminal');dialog.id='spotifyPanel';document.body.append(dialog);}\r\n  dialog.innerHTML=`<div class=\"sp-shell\"><header class=\"sp-top\"><div><h2>DJ TERMINAL</h2></div><button class=\"sp-close\" type=\"button\" aria-label=\"Close DJ terminal\">×</button></header><div class=\"sp-screen\"><p class=\"sp-status\" role=\"status\" aria-live=\"polite\">Checking Spotify connection…</p><section class=\"sp-account\"><span class=\"sp-label\">ACCOUNT LINK</span><strong class=\"sp-account-name\">OFFLINE</strong><div class=\"sp-account-actions\"><button class=\"sp-connect\" type=\"button\">Connect Spotify</button><button class=\"sp-disconnect\" type=\"button\" hidden>Disconnect</button></div></section><section class=\"sp-now\"><span class=\"sp-label\">ON THE DECK</span><div class=\"sp-track\"><div class=\"sp-art\" aria-hidden=\"true\">♫</div><div><strong class=\"sp-title\">No track playing</strong><span class=\"sp-artist\">Open Spotify on a device to begin.</span></div></div><div class=\"sp-progress\"><progress class=\"sp-progress-bar\" max=\"1\" value=\"0\"></progress><span class=\"sp-time\">0:00 / 0:00</span></div><div class=\"sp-controls\"><button data-action=\"previous\" aria-label=\"Previous track\">◂◂</button><button data-action=\"pause\" class=\"sp-pause\">PAUSE</button><button data-action=\"resume\" class=\"sp-resume\">PLAY</button><button data-action=\"next\" aria-label=\"Next track\">▸▸</button></div><p class=\"sp-device\">Spotify Connect controls require Premium and an active device.</p></section><section class=\"sp-hand\"><span class=\"sp-label\">PLAYBACK CONTROLS</span></section><section class=\"sp-jam\"><span class=\"sp-label\">LISTEN WITH FRIENDS</span><p>Start a Jam in Spotify, then share its invitation link here.</p><a class=\"sp-open-spotify\" href=\"https://open.spotify.com/\" target=\"_blank\" rel=\"noopener noreferrer\">OPEN SPOTIFY ↗</a><form class=\"sp-jam-form\"><label for=\"spJamLink\">Jam invitation link</label><div><input id=\"spJamLink\" type=\"url\" inputmode=\"url\" placeholder=\"https://spotify.link/…\" autocomplete=\"off\"><button type=\"submit\">OPEN JAM</button></div></form><p class=\"sp-jam-status\" aria-live=\"polite\"></p></section><section class=\"sp-playlists\"><div class=\"sp-playlist-heading\"><span class=\"sp-label\">YOUR PLAYLISTS</span><span class=\"sp-count\"></span></div><ol class=\"sp-playlist-list\"></ol><button class=\"sp-more\" type=\"button\" hidden>LOAD MORE ↓</button></section></div><footer>SPOTIFY PLAYBACK STAYS ON YOUR DEVICE // MYR5 DJ BOOTH</footer></div>`;\r\n  const $=s=>dialog.querySelector(s),status=message=>{$('.sp-status').textContent=message;};\r\n  const seekLabel=make('label','dj-spotify-seek','SEEK '),seekControl=make('input');seekControl.type='range';seekControl.min='0';seekControl.max='1';seekControl.step='1000';seekControl.value='0';seekControl.setAttribute('aria-label','Spotify track position');seekLabel.append(seekControl);$('.sp-progress').after(seekLabel);\r\n  const volumeLabel=make('label','dj-spotify-volume','VOLUME '),volumeControl=make('input');volumeControl.type='range';volumeControl.min='0';volumeControl.max='100';volumeControl.step='1';volumeControl.value='50';volumeControl.setAttribute('aria-label','Spotify device volume');volumeLabel.append(volumeControl);$('.sp-controls').after(volumeLabel);\r\n  const signIn=make('a','sp-sign-in','SIGN IN TO COACH');signIn.href=signInPath(location.pathname+location.search+location.hash);signIn.hidden=true;$('.sp-account-actions').append(signIn);\r\n  const PENDING='myr5.spotifyPending',store=(fn)=>{try{return fn(localStorage);}catch{return null;}};\r\n  const pendingFresh=()=>Date.now()-Number(store(l=>l.getItem(PENDING))||0)<15*60000;\r\n  let returnResult=new URLSearchParams(location.search).get('spotify'),connectBusy=false,loadRevision=0;\r\n  const accountAvailable=()=>!!getAccount()?.user?.id;\r\n\r\n  // Keep the physical playback controls alongside the Spotify records.\r\n  $('.sp-playlists').after($('.sp-hand'));\r\n  const deck=make('div','sp-deck-hardware');deck.innerHTML='<button type=\"button\" class=\"sp-platter\" data-action=\"resume\" aria-label=\"Play\"><i></i></button><div class=\"sp-tonearm\" aria-hidden=\"true\"></div><div class=\"sp-mixer\"><button type=\"button\" class=\"sp-knob\" data-action=\"previous\" aria-label=\"Previous track\"></button><button type=\"button\" class=\"sp-knob\" data-action=\"next\" aria-label=\"Next track\"></button><button type=\"button\" class=\"sp-fader\" data-action=\"pause\" aria-label=\"Pause\"></button></div><div class=\"sp-deck-leds\" aria-hidden=\"true\"><b>POWER</b><b>STEREO</b><b>ON AIR</b></div>';\r\n  $('.sp-hand').append(deck);\r\n  const fetchJSON=async(path,options={})=>{const headers=new Headers(options.headers),account=getAccount(),owner=account?.user?.id,epoch=account?.dataEpoch,signal=abort?.signal;if(!['GET','HEAD'].includes((options.method||'GET').toUpperCase())){if(!owner||!Number.isSafeInteger(epoch))throw Error('Sign in to Coach before connecting Spotify.');headers.set('X-Target-Account',owner);headers.set('X-Expected-Data-Epoch',String(epoch));}const response=await request(path,{credentials:'same-origin',cache:'no-store',...options,headers,signal});const data=await response.json();if(signal?.aborted||getAccount()?.user?.id!==owner||getAccount()?.dataEpoch!==epoch)throw new DOMException('Spotify account changed.','AbortError');if(!response.ok)throw Object.assign(Error(data.error||'Spotify is unavailable.'),{code:data.code,status:response.status});return data;};\r\n  function stop(){loadRevision++;clearTimeout(poll);poll=null;abort?.abort();abort=null;}\r\n  function showNow(now){\r\n    playing=!!now.playing;\r\n    actualDJ.spotifyPlaying(playing);\r\n    const track=now.track;$('.sp-title').textContent=track?.name||'No track playing';$('.sp-artist').textContent=track?track.artists.join(', ')||'Unknown artist':'Open Spotify on a device to begin.';\r\n    $('.sp-art').replaceChildren();if(track?.image){const img=make('img');img.src=track.image;img.alt='';img.loading='lazy';$('.sp-art').append(img);}else $('.sp-art').textContent='♫';\r\n    const duration=Math.max(1,now.durationMs||1);$('.sp-progress-bar').max=duration;$('.sp-progress-bar').value=Math.min(duration,now.progressMs||0);$('.sp-time').textContent=`${fmt(now.progressMs)} / ${fmt(now.durationMs)}`;\r\n    seekControl.max=duration;if(document.activeElement!==seekControl)seekControl.value=Math.min(duration,now.progressMs||0);seekControl.disabled=!now.track;\r\n    volumeControl.disabled=!Number.isFinite(now.volumePercent);if(Number.isFinite(now.volumePercent)&&document.activeElement!==volumeControl)volumeControl.value=now.volumePercent;\r\n    $('.sp-pause').hidden=!now.playing;$('.sp-resume').hidden=!!now.playing;\r\n    $('.sp-device').textContent=now.device?`Playing on ${now.device}. Spotify Premium is required for remote control.`:'Spotify Connect controls require Premium and an active device.';\r\n    const label=document.getElementById('spotifyNowPlayingLabel');if(label)label.textContent=track?`${track.name} — ${track.artists.join(', ')}`:'actual.dj';\r\n  }\r\n  async function refreshNow(){if(!dialog.open||!connected||document.hidden)return;const revision=loadRevision;try{const data=await fetchJSON('/api/spotify/now-playing');if(revision!==loadRevision||!dialog.open)return;showNow(data.nowPlaying);status(data.nowPlaying.playing?'LIVE FROM SPOTIFY':'CONNECTED // WAITING FOR PLAYBACK');}catch(e){if(revision!==loadRevision||!dialog.open||e.name==='AbortError')return;status(e.message);if(e.code==='spotify_reconnect'||e.code==='spotify_disconnected'){connected=false;actualDJ.spotifyState(false);}}finally{if(revision===loadRevision&&dialog.open&&!disposed&&connected)poll=setTimeout(refreshNow,10000);}}\r\n  async function loadPlaylists(reset=false){const revision=loadRevision;if(reset){playlistOffset=0;playlistTotal=0;$('.sp-playlist-list').replaceChildren();}const data=await fetchJSON(`/api/spotify/playlists?offset=${playlistOffset}`);if(revision!==loadRevision||!dialog.open)return;playlistTotal=data.total;for(const item of data.items){const li=make('li','sp-playlist');const art=make('span','sp-playlist-art');if(item.image){const img=make('img');img.src=item.image;img.alt='';img.loading='lazy';art.append(img);}else art.textContent='♫';const label=make('span','sp-playlist-info');label.append(make('strong','',item.name),make('small','',`${item.tracks} tracks`));const play=make('button','sp-playlist-play','PLAY ▸');play.type='button';play.dataset.playlist=item.id;play.setAttribute('aria-label',`Play ${item.name}`);li.append(art,label,play);$('.sp-playlist-list').append(li);}playlistOffset+=data.items.length;$('.sp-count').textContent=`${Math.min(playlistOffset,playlistTotal)} / ${playlistTotal}`;$('.sp-more').hidden=playlistOffset>=playlistTotal||!data.items.length;}\r\n  async function load(){const result=returnResult,revision=++loadRevision;signIn.hidden=accountAvailable();if(!accountAvailable()){connected=false;actualDJ.spotifyState(false);$('.sp-connect').hidden=true;$('.sp-disconnect').hidden=true;$('.sp-now').hidden=true;$('.sp-playlists').hidden=true;status('Sign in to Coach to connect your Spotify account.');return;}try{status('CHECKING ACCOUNT LINK…');const data=await fetchJSON('/api/spotify/status');if(revision!==loadRevision||!dialog.open)return;connected=data.connected;actualDJ.spotifyState(connected);if(connected)store(l=>l.removeItem(PENDING));$('.sp-account-name').textContent=data.account?.name||'NOT CONNECTED';$('.sp-connect').hidden=connected;$('.sp-disconnect').hidden=!connected;$('.sp-now').hidden=!connected;$('.sp-playlists').hidden=!connected;if(!connected){const pending=!result&&pendingFresh();store(l=>l.removeItem(PENDING));status(spotifyReturnMessage(result||(pending?'incomplete':null))||'CONNECT YOUR SPOTIFY ACCOUNT');showNow({track:null,progressMs:0,durationMs:0});return;}status('CONNECTED TO SPOTIFY');await Promise.all([refreshNow(),loadPlaylists(true)]);}catch(e){if(revision===loadRevision&&dialog.open&&e.name!=='AbortError')status(e.message);}}\r\n  async function action(name,playlistId,payload={}){const revision=loadRevision;try{if(['resume','track','playlist','transfer'].includes(name))actualDJ.spotifyStarting();status('SENDING TO SPOTIFY…');await fetchJSON('/api/spotify/playback',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({action:name,...payload,...(playlistId?{playlistId}:{})})});if(revision!==loadRevision||!dialog.open)return false;if(name==='pause'){playing=false;actualDJ.spotifyPlaying(false);}else if(['resume','track','playlist','transfer'].includes(name)){playing=true;actualDJ.spotifyPlaying(true);}void import('./modules/vault/vault-store.mjs').then(m=>m.bump('dj-session')).catch(()=>{});clearTimeout(poll);poll=setTimeout(refreshNow,1000);return true;}catch(e){if(revision===loadRevision&&dialog.open&&e.name!=='AbortError')status(e.message);return false;}}\r\n  const actualDJ=mountActualDJ({dialog,spotifyJSON:fetchJSON,spotifyAction:(name,payload)=>action(name,null,payload)});\r\n  seekControl.addEventListener('change',()=>void action('seek',null,{positionMs:Math.round(Number(seekControl.value))}));\r\n  volumeControl.addEventListener('change',()=>void action('volume',null,{volumePercent:Number(volumeControl.value)}));\r\n  const open=()=>{if(disposed)return null;if(!dialog.open){abort=new AbortController();dialog.showModal();void load();}return dialog;};\r\n  $('.sp-close').addEventListener('click',()=>dialog.close());dialog.addEventListener('close',()=>{if(!dialog.open)stop();});\r\n  $('.sp-connect').addEventListener('click',async()=>{if(connectBusy)return;connectBusy=true;$('.sp-connect').disabled=true;status('OPENING SPOTIFY SIGN IN...');try{const data=await fetchJSON('/api/spotify/connect',{method:'POST'});if(!dialog.open)return;store(l=>l.setItem(PENDING,String(Date.now())));location.assign(data.url);}catch(e){if(dialog.open)status(e.message);}finally{connectBusy=false;$('.sp-connect').disabled=false;}});\r\n  $('.sp-disconnect').addEventListener('click',async()=>{try{await fetchJSON('/api/spotify/disconnect',{method:'POST'});connected=false;stop();abort=new AbortController();await load();}catch(e){status(e.message);}});\r\n  $('.sp-controls').addEventListener('click',e=>{const button=e.target.closest('[data-action]');if(button)void action(button.dataset.action);});\r\n  deck.addEventListener('click',e=>{const button=e.target.closest('[data-action]');if(button)void action(button.dataset.action);});\r\n  $('.sp-playlist-list').addEventListener('click',e=>{const button=e.target.closest('[data-playlist]');if(button)void action('playlist',button.dataset.playlist);});\r\n  $('.sp-more').addEventListener('click',()=>{void loadPlaylists().catch(e=>status(e.message));});\r\n  $('.sp-jam-form').addEventListener('submit',e=>{e.preventDefault();const link=spotifyJamLink($('#spJamLink').value);if(!link){$('.sp-jam-status').textContent='Enter a Spotify Jam invitation link.';return;}$('.sp-jam-status').textContent='Opening Jam in Spotify…';window.open(link,'_blank','noopener,noreferrer');});\r\n  const onVisible=()=>{if(document.hidden&&dialog.open)dialog.close();else if(!document.hidden&&!dialog.open&&!returnResult&&pendingFresh()&&accountAvailable())open();};document.addEventListener('visibilitychange',onVisible);\r\n  const onPageHide=()=>{if(dialog.open)dialog.close();};window.addEventListener('pagehide',onPageHide);\r\n  const onAccountCleared=()=>{stop();actualDJ.spotifyState(false);$('.sp-playlist-list').replaceChildren();showNow({track:null});$('.sp-account-name').textContent='NOT CONNECTED';if(dialog.open)dialog.close();connected=false;const label=document.getElementById('spotifyNowPlayingLabel');if(label)label.textContent='actual.dj';};\r\n  window.addEventListener('myr5:account-cleared',onAccountCleared);\r\n  const onHeader=event=>{if(event.target.closest?.('#spotifyNowPlayingOpen'))open();};document.addEventListener('click',onHeader);\r\n  window.myr5Menus={...window.myr5Menus,spotify:open};\r\n  // Account initialization may clear an anonymous shell before restoring the signed-in account.\r\n  // Keep the OAuth result until that restoration has completed, then reopen the terminal.\r\n  const onAccountReady=()=>{queueMicrotask(()=>{\r\n    if(disposed||!accountAvailable())return;\r\n    if(returnResult){const params=new URLSearchParams(location.search);params.delete('spotify');history.replaceState(history.state,'',location.pathname+(params.size?`?${params}`:'')+location.hash);actualDJ.showSpotify();if(!dialog.open)open();else void load();returnResult=null;}\r\n    else if(dialog.open)void load();\r\n    else if(pendingFresh())open();\r\n  });};\r\n  window.addEventListener('myr5:account-ready',onAccountReady);\r\n  if(returnResult)queueMicrotask(()=>{if(accountAvailable())onAccountReady();else open();});\r\n  return {open,dispose(){actualDJ.dispose();disposed=true;stop();window.removeEventListener('myr5:account-ready',onAccountReady);document.removeEventListener('visibilitychange',onVisible);window.removeEventListener('pagehide',onPageHide);window.removeEventListener('myr5:account-cleared',onAccountCleared);document.removeEventListener('click',onHeader);if(window.myr5Menus?.spotify===open)delete window.myr5Menus.spotify;dialog.remove();}};\r\n}\r\n","standalone-account-context.mjs":"// Standalone pages obtain ownership only from a verified account read. They do\r\n// not treat device appearance, a cached ID or a login-provider flag as identity.\r\nimport {authFetch} from './auth-client.mjs';\r\nimport {mergeVerifiedPerformance} from './performance-progress.mjs';\r\nimport {authTransitions} from './auth-transition.mjs';\r\nexport function createStandaloneAccountContext({request=authFetch,transitions=authTransitions(),target=globalThis.window??globalThis,timeoutMs=8000}={}){\r\n let active=null,generation=0,disposed=false;\r\n const emit=(name,detail)=>{const event=new Event(name);if(detail!==undefined)Object.defineProperty(event,'detail',{value:detail});target.dispatchEvent?.(event);};\r\n function clear(){generation++;active=null;target.myr5AuthenticatedAccount=null;target.coachEntitlements=null;target.coachProgress=null;emit('myr5:account-cleared');}\r\n clear();const unsubscribe=transitions.subscribe(clear);\r\n async function read({ticket=transitions.capture()}={}){\r\n  const current=++generation,controller=new AbortController();let timer;\r\n  const deadline=new Promise((_,reject)=>{timer=setTimeout(()=>{controller.abort();reject(Object.assign(Error('Account service timed out.'),{code:'account_timeout'}));},timeoutMs);});\r\n  try{\r\n   const response=await Promise.race([request('/api/account?core=1',{signal:AbortSignal.any([ticket.signal,controller.signal]),credentials:'same-origin',cache:'no-store'}),deadline]);\r\n   transitions.assertCurrent(ticket);if(disposed||current!==generation)return null;\r\n   if(!response.ok||response.redirected||!response.headers?.get('content-type')?.includes('application/json'))throw Error('Verified account unavailable.');\r\n   const account=await Promise.race([response.json(),deadline]);transitions.assertCurrent(ticket);\r\n   if(disposed||current!==generation)return null;\r\n   if(typeof account?.user?.id!=='string'||!account.user.id||account.user.id.length>128||!Number.isSafeInteger(account.dataEpoch)||account.dataEpoch<1)throw Error('Invalid verified account.');\r\n   if(active&&(active.user.id!==account.user.id||active.dataEpoch!==account.dataEpoch)){transitions.invalidate();return null;}\r\n   mergeVerifiedPerformance(account);active=account;target.myr5AuthenticatedAccount=account;target.coachEntitlements=account.entitlements??null;target.coachProgress=account.progress??null;emit('myr5:account-ready',account);return account;\r\n  }catch{\r\n   if(!disposed&&current===generation&&transitions.isCurrent(ticket))clear();return null;\r\n  }finally{clearTimeout(timer);controller.abort();}\r\n }\r\n async function refresh(){try{return await read({ticket:transitions.beginRefresh()});}catch{if(!disposed)clear();return null;}}\r\n return {read,refresh,clear,get account(){return active;},dispose(){disposed=true;generation++;unsubscribe?.();}};\r\n}\r\n","streak-forgiveness.mjs":"// D12 streak/forgiveness rules (see DECISIONS.md D12, \"D12 detailed rules\" R1-R7,\r\n// and \"D12 letters\" table). This is the ONE place that implements those rules —\r\n// combat.mjs's loginStreak() delegates here instead of re-deriving them; do not\r\n// add a second streak calculation anywhere else.\r\n//\r\n// Input: an ordered array of day records `{date, status, timezone?}` where\r\n// `date` is that day's LOCAL calendar date as 'YYYY-MM-DD' (R1: already resolved\r\n// by the caller using the timezone recorded for that day — this module does no\r\n// timezone math of its own, it just groups by calendar date) and `status` is\r\n// 'kept' or 'missed'. `timezone` is accepted and ignored by the date math (it\r\n// exists so callers can carry it through for their own records); a repeated\r\n// `date` (R2, e.g. a day that repeats after crossing back over the date line)\r\n// is folded into a single day, keeping the first entry seen for that date.\r\n//\r\n// Output: one result per unique day, in input order:\r\n//   { date, streak, forgivenWeeksInARow, forgivenessAvailableThisWeek,\r\n//     auraMilestone, lettersFired }\r\n// matching plan/muse/streak-test-vectors.json's expectedAfterEachDay shape.\r\n\r\nconst FORGIVE_BY_START_COUNT = ['forgive-1', 'forgive-2', 'forgive-3-limit'];\r\n\r\nconst toUTCDate = ds => { const [y, m, d] = ds.split('-').map(Number); return new Date(Date.UTC(y, m - 1, d)); };\r\nconst isoDate = dt => dt.toISOString().slice(0, 10);\r\n// Monday-start week key for a local calendar date (R2).\r\nconst weekOf = ds => { const dt = toUTCDate(ds); dt.setUTCDate(dt.getUTCDate() - (dt.getUTCDay() + 6) % 7); return isoDate(dt); };\r\nconst isSunday = ds => toUTCDate(ds).getUTCDay() === 0;\r\n\r\nexport function evaluateStreakDays(days) {\r\n let streak = 0, cnt = 0, forgivenThisWeek = false, brokeThisWeek = false, cntStartWeek = 0, curWeek = null;\r\n const seen = new Set(), out = [];\r\n for (const day of days) {\r\n  const ds = day.date;\r\n  if (seen.has(ds)) continue;\r\n  seen.add(ds);\r\n  const week = weekOf(ds);\r\n  if (week !== curWeek) { curWeek = week; forgivenThisWeek = false; brokeThisWeek = false; cntStartWeek = cnt; }\r\n  const letters = [];\r\n  let keptOrForgiven = false;\r\n  if (day.status === 'kept') {\r\n   streak += 1; keptOrForgiven = true;\r\n  } else {\r\n   // R4: forgiven only if nothing forgiven yet this week, the 3-week limit\r\n   // hasn't been hit, and the streak hasn't already broken this week (R4c).\r\n   const forgivable = !forgivenThisWeek && cnt < 3 && !brokeThisWeek;\r\n   if (forgivable) {\r\n    streak += 1; forgivenThisWeek = true; keptOrForgiven = true;\r\n    const letter = FORGIVE_BY_START_COUNT[cntStartWeek];\r\n    if (letter) letters.push(letter);\r\n   } else {\r\n    letters.push(cnt === 3 && !forgivenThisWeek && !brokeThisWeek ? 'streak-broken-after-limit' : 'streak-broken');\r\n    streak = 0; cnt = 0; brokeThisWeek = true;\r\n   }\r\n  }\r\n  // R7: aura milestone on a kept-or-forgiven day whose streak is a positive multiple of 5.\r\n  const auraMilestone = (keptOrForgiven && streak > 0 && streak % 5 === 0) ? streak : null;\r\n  if (auraMilestone === 5 || auraMilestone === 10 || auraMilestone === 15) letters.push(`milestone-${auraMilestone}`);\r\n  if (isSunday(ds)) {\r\n   // R5: forgivenWeeksInARow only changes at week end.\r\n   if (brokeThisWeek) cnt = 0;\r\n   else if (forgivenThisWeek) cnt += 1;\r\n   else { const hadCount = cnt > 0; cnt = 0; if (hadCount) letters.push('forgive-restored'); }\r\n   if (cnt === 3) letters.push('forgive-off-warning');\r\n  }\r\n  // R6, reported after every day (its Sunday value already reflects the week-end update above).\r\n  const forgivenessAvailableThisWeek = !forgivenThisWeek && cnt < 3 && !brokeThisWeek;\r\n  out.push({ date: ds, streak, forgivenWeeksInARow: cnt, forgivenessAvailableThisWeek, auraMilestone, lettersFired: letters });\r\n }\r\n return out;\r\n}\r\n\r\n// Adapter for the account server's login_days rows (integer day numbers, UTC,\r\n// same as combat.mjs dayAt). Returns one result per day from the account's\r\n// first known day through `today` -- the full history, because a letter (e.g.\r\n// a forgiven miss) fires on the day it happens even if nothing calls in again\r\n// until days later. Empty when `today` itself is not a kept day.\r\n// ponytail: login_days has no timezone column yet, so each UTC day number is\r\n// treated as the local date (R1/R2 not yet per-user). Upgrade path: record the\r\n// device timezone with each login and pass real local dates to\r\n// evaluateStreakDays instead of calling this.\r\nexport function evaluateStreakHistory(dayNumbers, today) {\r\n const kept = new Set(dayNumbers.map(Number));\r\n if (!kept.has(today)) return [];\r\n const records = [];\r\n for (let d = Math.min(today, ...kept); d <= today; d++) records.push({ date: isoDate(new Date(d * 86400000)), status: kept.has(d) ? 'kept' : 'missed' });\r\n return evaluateStreakDays(records);\r\n}\r\n","sw.js":"const SHELL='myr5-shell-22d1026e5a1d6f2441dd',VOICE='myr5-voice-approved-v2';\r\n// Filled from the complete production asset inventory, with content identities.\r\nconst ASSETS=/* OFFLINE_ASSETS */ [];\r\n// D34 post-download package: every other deployed runtime file, each tagged with its Downloads-menu\r\n// group (scripts/offline-assets.mjs). Fetched on demand into a small LRU until the user downloads its\r\n// group into this release's own package cache. A roster body fetched on demand is kept there too.\r\nconst OPTIONAL_ASSETS=/* OPTIONAL_ASSETS */ [];\r\nconst BUILD=SHELL.slice('myr5-shell-'.length);\r\nconst OPTIONAL='myr5-optional-'+BUILD,OPTIONAL_LIMIT=64*1024*1024;\r\nconst PACKAGE='myr5-package-'+BUILD,PACKAGE_INDEX='/__myr5_package__';\r\nconst OPTIONAL_BY_URL=new Map(OPTIONAL_ASSETS.map(asset=>[asset.url,asset]));\r\nlet optionalWrite=Promise.resolve();\r\nasync function saveOptional(asset,response){\r\n if(asset.bytes>OPTIONAL_LIMIT)return;\r\n const copy=response.clone();\r\n const write=optionalWrite.then(async()=>{\r\n  const cache=await caches.open(OPTIONAL),keys=await cache.keys();\r\n  let used=keys.reduce((sum,key)=>sum+(OPTIONAL_BY_URL.get(new URL(key.url).pathname)?.bytes??0),0);\r\n  if(await cache.match(asset.url))return;\r\n  for(const key of keys){if(used+asset.bytes<=OPTIONAL_LIMIT)break;used-=OPTIONAL_BY_URL.get(new URL(key.url).pathname)?.bytes??0;await cache.delete(key);}\r\n  await cache.put(asset.url,copy);\r\n });\r\n optionalWrite=write.catch(()=>{});return optionalWrite;\r\n}\r\nconst INDEX='/__myr5_offline_assets__';\r\n// Every shell and package cache records what it holds (url and integrity). A file is reused across\r\n// releases only when its integrity is unchanged, so a package is never half old and half new.\r\nconst indexes=new Map();\r\nfunction cacheIndex(name){\r\n if(!indexes.has(name))indexes.set(name,caches.open(name).then(cache=>cache.match(name.startsWith('myr5-shell-')?INDEX:PACKAGE_INDEX)).then(saved=>saved.json()).then(list=>new Map(list.map(asset=>[asset.url,asset.integrity])),()=>new Map()));\r\n return indexes.get(name);\r\n}\r\nasync function localCopy(asset,lru=true){\r\n for(const name of await caches.keys())if(name!==PACKAGE&&/^myr5-(?:shell|package)-/.test(name)&&(await cacheIndex(name)).get(asset.url)===asset.integrity){\r\n  const hit=await caches.match(asset.url,{cacheName:name});if(hit)return {name,hit};\r\n }\r\n const hit=lru&&await caches.match(asset.url,{cacheName:OPTIONAL});return hit&&{name:OPTIONAL,hit};\r\n}\r\nconst sri=async body=>'sha256-'+btoa(String.fromCharCode(...new Uint8Array(await crypto.subtle.digest('SHA-256',body))));\r\nasync function packageCache(){\r\n const cache=await caches.open(PACKAGE);\r\n if(!await cache.match(PACKAGE_INDEX))await cache.put(PACKAGE_INDEX,new Response(JSON.stringify(OPTIONAL_ASSETS),{headers:{'Content-Type':'application/json'}}));\r\n return cache;\r\n}\r\nconst size=list=>list.reduce((sum,asset)=>sum+asset.bytes+(asset.contains||0),0);\r\n// What the chosen groups still need from the network, plus every group's size and what it still\r\n// misses (the Downloads menu). No group list (older pages) means the whole package. Unchanged files\r\n// already on the device (older package, older shell) are moved in first, whatever their group; the\r\n// on-demand LRU (64 MiB, kept for people who never asked for a group) is adopted only for a chosen\r\n// group, once the user has chosen to download.\r\nasync function packagePlan(adopt,groups){\r\n const cache=await packageCache(),chosen=Array.isArray(groups)?new Set(groups):null,wanted=asset=>!chosen||chosen.has(asset.group);\r\n const have=new Set((await cache.keys()).map(key=>new URL(key.url).pathname)),missing=[],sizes={};let total=0;\r\n for(const asset of OPTIONAL_ASSETS){\r\n  const group=sizes[asset.group]??={files:0,total:0,remaining:0};let need=[];\r\n  if(asset.contains!==undefined)need=await voiceMissing(asset);\r\n  else if(!have.has(asset.url)){\r\n   const copy=await localCopy(asset,adopt&&wanted(asset));\r\n   if(!copy)need=[asset];\r\n   else{await cache.put(asset.url,copy.hit);if(!copy.name.startsWith('myr5-shell-'))await(await caches.open(copy.name)).delete(asset.url);}\r\n  }\r\n  group.files++;group.total+=size([asset]);group.remaining+=size(need);\r\n  if(wanted(asset)){total+=size([asset]);missing.push(...need);}\r\n }\r\n // Older packages are spent once the chosen groups are complete; this release's LRU still serves\r\n // groups nobody chose, until every group is here.\r\n const complete=Object.values(sizes).every(group=>!group.remaining);\r\n if(!missing.length)for(const name of await caches.keys())if(name!==PACKAGE&&(name.startsWith('myr5-package-')||name.startsWith('myr5-optional-')&&(name!==OPTIONAL||complete)))await caches.delete(name);\r\n return {type:'PACKAGE_PLAN',cache:PACKAGE,total,missing,remaining:size(missing),groups:sizes};\r\n}\r\n// Voice clips live in the update-stable voice cache. Their identities come from this release's\r\n// verified voice manifest; until that is saved, the manifest itself is what is missing.\r\nasync function voiceMissing(entry){\r\n const voice=await caches.open(VOICE),key=entry.url+'?v='+BUILD,saved=await voice.match(key);\r\n let files;try{const body=await saved.arrayBuffer();if(await sri(body)===entry.integrity)files=JSON.parse(new TextDecoder().decode(body)).files;}catch{}\r\n if(!Array.isArray(files))return [{...entry,cache:VOICE,key}];\r\n const have=new Set((await voice.keys()).map(request=>request.url));\r\n return files.filter(file=>!have.has(new URL(file.url,self.location.origin).href)).map(file=>({...file,cache:VOICE}));\r\n}\r\nlet planning=Promise.resolve();\r\nconst ASSET_BY_URL=new Map(ASSETS.map(asset=>[asset.url,asset]));\r\nconst downloadProgress={type:'OFFLINE_PROGRESS',files:0,totalFiles:ASSETS.length,bytes:0,totalBytes:ASSETS.reduce((n,a)=>n+a.bytes,0)};\r\nasync function reportDownload(){\r\n for(const client of await self.clients.matchAll?.({type:'window',includeUncontrolled:true})||[])try{client.postMessage(downloadProgress);}catch{}\r\n}\r\n\r\nfunction assetPath(path){\r\n if(path==='/'||path==='/index.html'||path==='/index')return '/pose.html';\r\n if(path==='/icons/coach-512.png')return '/icons/myr5-alien-512.png';\r\n if(ASSET_BY_URL.has(path)||OPTIONAL_BY_URL.has(path))return path;\r\n const html=path.endsWith('/')?path+'index.html':path+'.html';\r\n if(ASSET_BY_URL.has(html)||OPTIONAL_BY_URL.has(html))return html;\r\n return path+'/index.html';\r\n}\r\nfunction offlineResponse(response){\r\n // Sites serves /pose.html through its clean /pose URL. A fetched response\r\n // retains redirected=true even after CacheStorage saves it. Chrome rejects\r\n // that response for a navigation whose redirect mode is manual (ERR_FAILED).\r\n // Keep the verified bytes, but give the offline page its own response.\r\n const headers=new Headers(response.headers);\r\n headers.delete('content-encoding');headers.delete('content-length');\r\n return new Response(response.body,{status:response.status,statusText:response.statusText,headers});\r\n}\r\n// Music stays cached as a verified complete file. Slice only the response sent to the media element.\r\n// Same single-range semantics as scripts/actual-dj-preview.mjs; no provider audio is intercepted.\r\nasync function musicResponse(request,response,asset){\r\n if(!/^\\/audio\\/music\\/[^/]+\\.m4a$/.test(asset.url)||response.status!==200)return response;\r\n const size=asset.bytes;if(!Number.isSafeInteger(size)||size<=0||size>1024*1024)return new Response('Music asset exceeds byte-serving bounds',{status:502});\r\n const reader=response.body?.getReader(),chunks=[];let length=0;\r\n if(reader)try{while(true){const {done,value}=await reader.read();if(done)break;length+=value.byteLength;if(length>size){await reader.cancel();return new Response('Music asset size mismatch',{status:502});}chunks.push(value);}}finally{reader.releaseLock();}\r\n if(length!==size)return new Response('Music asset size mismatch',{status:502});\r\n const bytes=new Uint8Array(size);let offset=0;for(const chunk of chunks){bytes.set(chunk,offset);offset+=chunk.byteLength;}\r\n const headers=new Headers(response.headers);headers.delete('content-encoding');headers.delete('content-range');headers.set('accept-ranges','bytes');headers.set('content-length',String(size));\r\n if(request.method==='HEAD')return new Response(null,{headers});\r\n const range=request.headers.get('range'),validator=request.headers.get('if-range');\r\n const date=Date.parse(validator),modified=Date.parse(headers.get('last-modified'));\r\n const matches=!validator||(validator.startsWith('\"')?validator===headers.get('etag'):!validator.startsWith('W/')&&Number.isFinite(date)&&Number.isFinite(modified)&&validator===headers.get('last-modified'));\r\n if(!range||!matches)return new Response(bytes,{headers});\r\n const match=range.match(/^bytes=(\\d*)-(\\d*)$/i);let start,end;\r\n if(match&&(match[1]||match[2])){\r\n  if(match[1]){start=Number(match[1]);end=match[2]?Number(match[2]):size-1;}\r\n  else{const suffix=Number(match[2]);start=suffix>0?Math.max(0,size-suffix):size;end=size-1;}\r\n }\r\n if(!Number.isSafeInteger(start)||!Number.isSafeInteger(end)||start<0||start>=size||end<start){headers.set('content-range',`bytes */${size}`);headers.set('content-length','0');return new Response(null,{status:416,headers});}\r\n end=Math.min(end,size-1);headers.set('content-range',`bytes ${start}-${end}/${size}`);headers.set('content-length',String(end-start+1));\r\n return new Response(bytes.subarray(start,end+1),{status:206,headers});\r\n}\r\nasync function downloadAsset(asset){\r\n // Edge security products can rewrite HTML in transit. Keep integrity strict for\r\n // executable and binary assets, but allow those harmless HTML transformations.\r\n const html=new URL(asset.url,self.location.origin).pathname.endsWith('.html');\r\n const response=await fetch(new Request(new URL(asset.url,self.location.origin),{cache:'reload',...(html?{}:{integrity:asset.integrity})}));\r\n const destination=response.url?new URL(response.url):null;\r\n const redirectedElsewhere=response.redirected&&(!destination||destination.origin!==self.location.origin||assetPath(destination.pathname)!==assetPath(asset.url));\r\n if(!response.ok||redirectedElsewhere||/^\\/audio\\/music\\/[^/]+\\.m4a$/.test(asset.url)&&response.status!==200)throw Error('Could not save Coach asset: '+asset.url);\r\n return offlineResponse(response);\r\n}\r\nasync function installAssets(){\r\n if(!ASSETS.length)throw Error('Build Coach before installing its offline assets.');\r\n const cache=await caches.open(SHELL),previous=[];\r\n for(const name of (await caches.keys()).reverse()){\r\n  if(!name.startsWith('myr5-shell-')||name===SHELL)continue;\r\n  const old=await caches.open(name),saved=await old.match(INDEX);\r\n  if(saved)try{previous.push({cache:old,files:new Map((await saved.json()).map(asset=>[asset.url,asset.integrity]))});}catch{}\r\n }\r\n let next=0,failed=false;\r\n const results=await Promise.allSettled(Array.from({length:4},async()=>{\r\n  while(!failed&&next<ASSETS.length){\r\n   const asset=ASSETS[next++];\r\n   try{\r\n    let response;\r\n    for(const old of previous)if(old.files.get(asset.url)===asset.integrity){response=await old.cache.match(asset.url);if(response?.ok)break;response=null;}\r\n    await cache.put(asset.url,response?offlineResponse(response):await downloadAsset(asset));\r\n    downloadProgress.files++;downloadProgress.bytes+=asset.bytes;await reportDownload();\r\n   }catch(error){failed=true;throw error;}\r\n  }\r\n }));\r\n const failure=results.find(result=>result.status==='rejected');\r\n try{\r\n  if(failure)throw failure.reason;\r\n  await cache.put(INDEX,new Response(JSON.stringify(ASSETS),{headers:{'Content-Type':'application/json'}}));\r\n }catch(error){await caches.delete(SHELL);throw error;}\r\n}\r\nself.addEventListener('install',event=>event.waitUntil(installAssets()));\r\n// skipWaiting() only activates once the old worker has finished its in-flight fetches, and a coach model\r\n// downloading on a phone can hold it for minutes. Pages stay frozen for the update only this long; after\r\n// that they are released (UPDATE_ABORT) and the update lands by itself once the old worker is idle.\r\nconst ACTIVATION_WAIT=8000;let markActivated;const activation=new Promise(resolve=>markActivated=resolve);\r\nself.addEventListener('activate',event=>{markActivated(true);event.waitUntil((async()=>{\r\n const names=await caches.keys();let previous=null;\r\n for(const name of [...names].reverse())if(name.startsWith('myr5-shell-')&&name!==SHELL&&await(await caches.open(name)).match(INDEX)){previous=name;break;}\r\n for(const name of names){\r\n  if(name.startsWith('myr5-shell-')&&name!==SHELL&&name!==previous)await caches.delete(name);\r\n  if(name.startsWith('myr5-optional-')&&name!==OPTIONAL&&name!=='myr5-optional-'+previous?.slice('myr5-shell-'.length))await caches.delete(name);\r\n }\r\n // Keep the newest older package until this release's package is complete (its files move over).\r\n for(const name of names.filter(name=>name.startsWith('myr5-package-')&&name!==PACKAGE).slice(0,-1))await caches.delete(name);\r\n const voice=await caches.open(VOICE);\r\n for(const key of await voice.keys()){const url=new URL(key.url);if(url.pathname==='/voice/manifest.json'&&url.searchParams.get('v')!==BUILD)await voice.delete(key);}\r\n await self.clients.claim();\r\n})());});\r\nlet updateAttempt=null;\r\nfunction updateReply(client,type,id){return new Promise(resolve=>{\r\n const channel=new MessageChannel();let done=false;\r\n const finish=value=>{if(done)return;done=true;clearTimeout(timer);channel.port1.close();resolve(value?.safe===true&&value.protocol===2&&value.id===id);};\r\n const timer=setTimeout(()=>finish(null),4000);\r\n channel.port1.onmessage=event=>finish(event.data);\r\n try{client.postMessage({type,id},[channel.port2]);}catch{finish(null);}\r\n});}\r\nasync function prepareUpdate(source){\r\n const clients=await self.clients.matchAll({type:'window',includeUncontrolled:true});\r\n if(!source?.id||!clients.some(client=>client.id===source.id))return {activated:false,reason:'busy'};\r\n const id=crypto.randomUUID();let activated=false;\r\n try{\r\n  if(!(await Promise.all(clients.map(client=>updateReply(client,'UPDATE_SAFETY_CHECK',id)))).every(Boolean))return {activated:false,reason:'busy'};\r\n  if(!(await Promise.all(clients.map(client=>updateReply(client,'UPDATE_CONFIRM',id)))).every(Boolean))return {activated:false,reason:'busy'};\r\n  // New or navigated windows must take part in their own fresh preparation.\r\n  const current=await self.clients.matchAll({type:'window',includeUncontrolled:true});\r\n  if(current.length!==clients.length||current.some(client=>!clients.some(old=>old.id===client.id&&old.url===client.url)))return {activated:false,reason:'busy'};\r\n  // Not awaited: Chromium resolves skipWaiting() only when activation starts, WebKit at once.\r\n  self.skipWaiting().catch(()=>{});\r\n  if(!await Promise.race([activation,new Promise(resolve=>setTimeout(()=>resolve(!self.registration.waiting),ACTIVATION_WAIT))]))return {activated:false,reason:'busy'};\r\n  activated=true;return {activated:true};\r\n }finally{if(!activated)for(const client of clients)try{client.postMessage({type:'UPDATE_ABORT',id});}catch{}}\r\n}\r\nself.addEventListener('message',event=>{\r\n if(event.data?.type==='OFFLINE_STATUS'){event.source?.postMessage(downloadProgress);return;}\r\n if(event.data?.type==='PACKAGE_PLAN'){\r\n  const plan=planning.then(()=>packagePlan(event.data.adopt===true,event.data.groups));planning=plan.catch(()=>{});\r\n  event.waitUntil(plan.then(value=>event.ports[0]?.postMessage(value),()=>event.ports[0]?.postMessage({type:'PACKAGE_PLAN',error:true})));return;\r\n }\r\n if(event.data?.type!=='PREPARE_UPDATE')return;\r\n if(updateAttempt){event.ports[0]?.postMessage({activated:false,reason:'busy'});return;}\r\n updateAttempt=prepareUpdate(event.source).catch(()=>({activated:false,reason:'busy'}));\r\n event.waitUntil(updateAttempt.then(result=>event.ports[0]?.postMessage(result)).finally(()=>{updateAttempt=null;}));\r\n});\r\nself.addEventListener('fetch',event=>{\r\n const request=event.request,url=new URL(request.url);\r\n if((request.method!=='GET'&&!(request.method==='HEAD'&&/^\\/audio\\/music\\/[^/]+\\.m4a$/.test(url.pathname)))||url.origin!==self.location.origin||url.pathname.startsWith('/api/')||url.pathname.includes('with-chatgpt')||url.pathname==='/callback'||url.pathname.startsWith('/signin')||url.pathname.startsWith('/source.json')||url.pathname==='/repair-coach'||url.pathname==='/recover'||url.pathname==='/recover.html'||request.headers.has('x-myr5-package'))return;\r\n if(url.pathname.startsWith('/voice/')){\r\n  event.respondWith((async()=>{const cache=await caches.open(VOICE),cached=await cache.match(request);if(cached)return cached;const response=await fetch(request);if(response.ok&&!response.redirected)await cache.put(request,response.clone());return response;})());return;\r\n }\r\n // Canonical paths also cover release query strings and customizer directory\r\n // links. Cached art is returned immediately, without a network revalidation.\r\n const path=assetPath(url.pathname);\r\n const asset=ASSET_BY_URL.get(path)||OPTIONAL_BY_URL.get(path);\r\n if(!asset)return;\r\n const optional=OPTIONAL_BY_URL.has(path),body=asset.group?.startsWith('bodies-'),kept=body||asset.group==='starter';\r\n // A roster body, or a portal scene's Starter art (W2-2O), that isn't on the device yet: fetched alone and\r\n // kept in the package; its page shows \"Downloading…\", or says it's missing when offline (post-download.mjs).\r\n const tell=state=>kept&&event.clientId&&event.waitUntil(self.clients.get(event.clientId).then(client=>client?.postMessage({type:body?'BODY_DOWNLOAD':'STARTER_DOWNLOAD',url:path,state}),()=>{}));\r\n event.respondWith((async()=>{\r\n  // Opening a cache creates it, so the package cache is only read by name here.\r\n  const cached=optional?await caches.match(path,{cacheName:PACKAGE})||(await localCopy(asset))?.hit:await(await caches.open(SHELL)).match(path);\r\n  if(cached)return musicResponse(request,offlineResponse(cached),asset);\r\n  tell('start');\r\n  let response;\r\n  try{response=await downloadAsset(asset);}catch{\r\n   tell('unavailable');\r\n   // Never mix an unverified new executable into an older installed shell.\r\n   return new Response('This resource is unavailable. Reconnect or update Coach.',{status:503});\r\n  }\r\n  if(kept){const copy=response.clone();event.waitUntil(packageCache().then(cache=>cache.put(path,copy)).catch(()=>{}).then(()=>tell('done')));}\r\n  else if(optional)event.waitUntil(saveOptional(asset,response));else try{await(await caches.open(SHELL)).put(path,response.clone());}catch{}\r\n  return musicResponse(request,response,asset);\r\n })());\r\n});\r\nself.addEventListener('push',event=>{\r\n let data={title:'MYR5 Coach',body:'Your coach has a reminder.',url:'/pose.html'};try{data={...data,...event.data.json()};}catch{}\r\n event.waitUntil((async()=>{\r\n  // D23: an Armie letter push is never shown during camera-only mode or\r\n  // mid-set. The busy window holds it and shows it when the set ends\r\n  // (armie-letters-client.mjs); the letter itself already lives in the inbox.\r\n  if(data.kind==='myr5-armie-letter'){\r\n   for(const client of await self.clients.matchAll({type:'window',includeUncontrolled:true}))\r\n    if(await clientAnswers(client,'ARMIE_NOTIFY_CHECK',reply=>reply?.blocked===true)){client.postMessage({type:'ARMIE_LETTER_HELD',letter:data});return;}\r\n  }\r\n  return self.registration.showNotification(String(data.title).slice(0,80),{body:String(data.body).slice(0,200),icon:'/icons/myr5-alien-192.png',badge:'/icons/myr5-alien-192.png',tag:data.tag||'myr5-reminder',data:{url:data.url,kind:data.kind},...(data.kind==='app-update'?{actions:[{action:'download',title:'Download update'}]}:{}),renotify:false});\r\n })());\r\n});\r\nfunction clientAnswers(client,type,accept){\r\n return new Promise(resolve=>{\r\n  const channel=new MessageChannel();\r\n  const finish=handled=>{clearTimeout(timer);channel.port1.close();resolve(handled);};\r\n  const timer=setTimeout(()=>finish(false),1000);\r\n  channel.port1.onmessage=event=>finish(accept(event.data));\r\n  try{client.postMessage({type},[channel.port2]);}catch{finish(false);}\r\n });\r\n}\r\nasync function offerUpdate(client){\r\n if(await clientAnswers(client,'APP_UPDATE_AVAILABLE',data=>data?.handled===true))return true;\r\n // Older working pages do not acknowledge APP_UPDATE_AVAILABLE. Their safety\r\n // reply still proves they are alive, including a busy workout answering false.\r\n return clientAnswers(client,'UPDATE_SAFETY_CHECK',data=>typeof data?.safe==='boolean');\r\n}\r\n// W2-2A (#18): a reminder opens its route in the app: meal -> #food, workout -> #workout. Older ?panel= links\r\n// (other reminders, the test push) map to the same routes; anything else opens unchanged.\r\nconst NOTIFY_ROUTES={'reminder-meal':'food','reminder-workout':'workout'},PANEL_ROUTES={meals:'food',reminders:'reminders',account:'scoreboard',history:'history',install:'install'};\r\nfunction routeUrl(url,kind){\r\n if(!['/pose.html','/pose','/'].includes(url.pathname))return url;\r\n const route=NOTIFY_ROUTES[kind]||PANEL_ROUTES[url.searchParams.get('panel')];if(!route)return url;\r\n const routed=new URL('/pose.html',url);url.searchParams.forEach((value,key)=>{if(key!=='panel')routed.searchParams.set(key,value);});routed.hash=route;return routed;\r\n}\r\nself.addEventListener('notificationclick',event=>{event.notification.close();event.waitUntil((async()=>{\r\n let url;try{url=new URL(event.notification.data?.url||'/pose.html',self.location.origin);}catch{return;}\r\n if(url.origin!==self.location.origin)return;\r\n const update=event.notification.data?.kind==='app-update',all=await self.clients.matchAll({type:'window',includeUncontrolled:true});\r\n if(update){\r\n  // An old or failed page can accept postMessage without displaying anything.\r\n  // Open independent recovery if it cannot acknowledge the update. Leave the\r\n  // existing window and any unsaved workout or form intact.\r\n  for(const client of all)if(new URL(client.url).origin===url.origin&&['/pose.html','/pose','/'].includes(new URL(client.url).pathname)){\r\n   await client.focus();if(await offerUpdate(client))return;\r\n  }\r\n  return self.clients.openWindow(new URL('/repair-coach',self.location.origin).href);\r\n }\r\n url=routeUrl(url,event.notification.data?.kind);\r\n for(const client of all)if(new URL(client.url).origin===url.origin){await client.navigate(url.href);return client.focus();}\r\n return self.clients.openWindow(url.href);\r\n})());});\r\n","unlock-gate.mjs":"// \"Why is this locked\" sheet + the one-time celebration. The rule itself is unlockStatus() in performance-progress.mjs.\r\nimport {readPerformanceProgress,unlockStatus} from './performance-progress.mjs';\r\nexport const UNLOCK_SEEN_KEY='myr5-all-unlocked-seen-v1';\r\nexport const UNLOCK_MESSAGE='Finish a workout, a meditation and a food log to unlock every coach and workout style.';\r\nconst STYLE='position:fixed;inset:auto 12px 12px 12px;z-index:99999;margin:0;max-width:none;border:1px solid #6cf;border-radius:16px;background:#101828;color:#fff;padding:16px;font:15px system-ui;box-shadow:0 8px 40px #000a';\r\nconst ITEMS=[['workout','Workout (Cool Cardio counts)'],['meditation','Meditation'],['food','Food log']];\r\nlet sheet;\r\nexport function showUnlockGate({onCardio}={}){\r\n const status=unlockStatus(readPerformanceProgress());\r\n sheet?.remove();sheet=document.createElement('dialog');sheet.id='unlockGate';sheet.setAttribute('style',STYLE);\r\n const p=document.createElement('p');p.textContent=UNLOCK_MESSAGE;p.setAttribute('role','status');\r\n const ul=document.createElement('ul');ul.style.cssText='list-style:none;padding:0;margin:8px 0';\r\n for(const [key,label] of ITEMS){const li=document.createElement('li');li.dataset.item=key;li.dataset.done=String(status[key]);li.textContent=`${status[key]?'\\u2713':'\\u25CB'} ${label}`;ul.append(li);}\r\n const row=document.createElement('div');row.style.cssText='display:flex;gap:8px';\r\n const cardio=document.createElement('button');cardio.type='button';cardio.dataset.gate='cardio';cardio.textContent='Play Cool Cardio';\r\n const close=document.createElement('button');close.type='button';close.textContent='Close';\r\n cardio.onclick=()=>{sheet.close();onCardio?.();};close.onclick=()=>sheet.close();\r\n row.append(cardio,close);sheet.append(p,ul,row);document.body.append(sheet);sheet.showModal();\r\n}\r\n/** Celebrate once, the first time progress flips to fully unlocked (silent for already-unlocked saves). */\r\nexport function watchUnlock(storage=globalThis.localStorage){\r\n const check=()=>{try{if(!unlockStatus(readPerformanceProgress()).done||storage.getItem(UNLOCK_SEEN_KEY))return;storage.setItem(UNLOCK_SEEN_KEY,'1');celebrate();}catch{}};\r\n addEventListener('myr5:performance-progress',check);\r\n}\r\nfunction celebrate(){\r\n const t=document.createElement('div');t.id='unlockToast';t.setAttribute('role','status');t.setAttribute('style',STYLE.replace('border-radius:16px','border-radius:16px;text-align:center'));\r\n t.textContent='\\u2728 Everything unlocked: all coaches, workout styles and movements!';document.body.append(t);setTimeout(()=>t.remove(),5000);\r\n}\r\n","unlock-ledger.mjs":"// Global battle-pass ledger (rank 6b) for the items unlock-store.ts doesn't hold: weapons, pets,\r\n// boss looks, specials, auras, Food bonuses (D32). Textures/colours/palettes stay in unlock-store.ts. Same API\r\n// shape as unlock-store.ts, one localStorage key, not per-coach (unlocks are global).\r\nimport {performanceOwner} from './performance-progress.mjs';\r\nimport {markPending,markPendingMany,ACCOUNT_SCOPED_LEDGER_KINDS} from './unlock-pending.mjs';\r\nexport {ACCOUNT_SCOPED_LEDGER_KINDS};\r\nexport const LEDGER_KEY='myr5-battle-pass-ledger-v1';\r\nexport const LEDGER_KINDS=Object.freeze(['weapon','pet','boss-texture','boss-skin','boss-unlock','special','aura','bonus','creature-skin','ship','reward-pack']);\r\n\r\nfunction read(){\r\n try{\r\n  const d=JSON.parse(localStorage.getItem(LEDGER_KEY)||'{}');\r\n  return Object.fromEntries(LEDGER_KINDS.map(k=>[k,Array.isArray(d[k])?d[k]:[]]));\r\n }catch{return Object.fromEntries(LEDGER_KINDS.map(k=>[k,[]]));}\r\n}\r\n\r\nconst accountKinds=new Set([...ACCOUNT_SCOPED_LEDGER_KINDS,'boss-skin']);\r\nconst ownerKey=({account=globalThis.myr5AuthenticatedAccount}={})=>{\r\n try{\r\n const id=typeof account==='string'?account:account?.user?.id;\r\n return typeof id==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(id)?`${LEDGER_KEY}/account/${id}${typeof account==='object'&&account?.dataEpoch!=null?`/epoch/${encodeURIComponent(String(account.dataEpoch))}`:''}`:`${LEDGER_KEY}/guest/${encodeURIComponent(performanceOwner(globalThis.localStorage,account))}`;\r\n }catch{return null;}\r\n};\r\nfunction accountRead(options){try{const key=ownerKey(options);if(!key)return {};const data=JSON.parse(localStorage.getItem(key)||'{}');return data&&typeof data==='object'&&!Array.isArray(data)?data:{};}catch{return {};}}\r\nexport const grantedIds=(kind,options)=>{const value=(accountKinds.has(kind)?accountRead(options):read())[kind];return Array.isArray(value)?value:[];};\r\nexport const isGranted=(kind,id,options)=>grantedIds(kind,options).includes(id);\r\n/** Idempotent: true only the first time `id` is granted for `kind`. */\r\nexport function grantUnlock(kind,id,options){\r\n if(accountKinds.has(kind)){\r\n  const key=ownerKey(options);if(!key)return false;\r\n  const data=accountRead(options),ids=Array.isArray(data[kind])?data[kind]:[];\r\n  if(ids.includes(id))return false;data[kind]=[...ids,id];\r\n  try{localStorage.setItem(key,JSON.stringify(data));}catch{return false;}\r\n  markPending(kind,id,options);return true;\r\n }\r\n const store=read();\r\n if(!store[kind]||store[kind].includes(id))return false;\r\n store[kind].push(id);\r\n try{localStorage.setItem(LEDGER_KEY,JSON.stringify(store));}catch{return false;}\r\n markPending(kind,id);\r\n return true;\r\n}\r\n\r\n/** Batch grants are used for collection completion; one storage write per kind. */\r\nexport function grantUnlocks(kind,ids,options){\r\n if(!LEDGER_KINDS.includes(kind)||!Array.isArray(ids))return 0;\r\n const key=accountKinds.has(kind)?ownerKey(options):LEDGER_KEY;if(!key)return 0;\r\n const data=accountKinds.has(kind)?accountRead(options):read(),known=new Set(data[kind]||[]),added=[];\r\n for(const id of ids)if(typeof id==='string'&&id&&!known.has(id)){known.add(id);added.push(id);}\r\n if(!added.length)return 0;data[kind]=[...known];\r\n try{localStorage.setItem(key,JSON.stringify(data));}catch{return 0;}\r\n markPendingMany(added.map(id=>({kind,id})),options);return added.length;\r\n}\r\n","unlock-pending.mjs":"// Grant-time \"new\" markers behind the unlock sparkle (unlock-seen.mjs). A grant that just succeeded marks its one item\r\n// pending; viewing clears it. Grants that predate this record have no marker, so they stay quiet. No imports, so the\r\n// ledger and unlock-store can both use it without a cycle. Scope mirrors the ledger: account kinds per account, rest per device.\r\nimport {performanceOwner} from './performance-progress.mjs';\r\nexport const PENDING_KEY='myr5-unlock-pending-v1';\r\nexport const ACCOUNT_SCOPED_LEDGER_KINDS=Object.freeze(['creature-skin','ship','reward-pack']);\r\nconst accountKinds=new Set([...ACCOUNT_SCOPED_LEDGER_KINDS,'texture','color','palette','boss-skin']);\r\nconst keyOf=(kind,{account=globalThis.myr5AuthenticatedAccount}={})=>{\r\n if(!accountKinds.has(kind))return PENDING_KEY;\r\n try{\r\n const id=typeof account==='string'?account:account?.user?.id;\r\n return typeof id==='string'&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(id)?`${PENDING_KEY}/account/${id}${typeof account==='object'&&account?.dataEpoch!=null?`/epoch/${encodeURIComponent(String(account.dataEpoch))}`:''}`:`${PENDING_KEY}/guest/${encodeURIComponent(performanceOwner(globalThis.localStorage,account))}`;\r\n }catch{return null;}\r\n};\r\nconst read=key=>{try{const d=JSON.parse(localStorage.getItem(key)||'{}');return d&&typeof d==='object'&&!Array.isArray(d)?d:{};}catch{return {};}};\r\nconst idsOf=(data,kind)=>Array.isArray(data[kind])?data[kind]:[];\r\n\r\nexport const isPending=(kind,id,options)=>{const key=keyOf(kind,options);return !!key&&idsOf(read(key),kind).includes(id);};\r\nfunction update(kind,options,change){\r\n const key=keyOf(kind,options);if(!key)return;\r\n const data=read(key),ids=idsOf(data,kind),next=change(ids);\r\n if(next===ids)return;\r\n try{localStorage.setItem(key,JSON.stringify({...data,[kind]:next}));}catch{/* storage unavailable: the item just isn't sparkled */}\r\n}\r\nexport function markPendingMany(entries,options){\r\n const records=new Map();\r\n for(const {kind,id} of entries){const key=keyOf(kind,options);if(!key)continue;\r\n  let record=records.get(key);if(!record){record={data:read(key),known:new Map()};records.set(key,record);}\r\n  if(!record.known.has(kind)){record.data[kind]=[...idsOf(record.data,kind)];record.known.set(kind,new Set(record.data[kind]));}\r\n  const known=record.known.get(kind);if(!known.has(id)){known.add(id);record.data[kind].push(id);}\r\n }\r\n for(const [key,record] of records)try{localStorage.setItem(key,JSON.stringify(record.data));}catch{}\r\n}\r\nexport const markPending=(kind,id,options)=>update(kind,options,ids=>ids.includes(id)?ids:[...ids,id]);\r\nexport const clearPending=(kind,id,options)=>update(kind,options,ids=>ids.includes(id)?ids.filter(x=>x!==id):ids);\r\n\r\n// Items unlocked by derived state (no grant call, e.g. body Species from section completion): the first call per kind\r\n// only snapshots what is already unlocked (no historical flood); later calls mark just the ids added since. Device-scoped.\r\nexport const BASELINE_KEY='myr5-unlock-baseline-v1';\r\nexport function noteUnlocked(kind,ids){\r\n const data=read(BASELINE_KEY),known=Array.isArray(data[kind])?data[kind]:null,fresh=known?ids.filter(id=>!known.includes(id)):ids;\r\n if(known&&!fresh.length)return;\r\n try{localStorage.setItem(BASELINE_KEY,JSON.stringify({...data,[kind]:[...(known||[]),...fresh]}));}catch{return;}\r\n if(known)for(const id of fresh)markPending(kind,id);\r\n}\r\n","unlock-seen.mjs":"// Sparkle for newly unlocked items: an item is \"new\" only while its grant-time pending marker (unlock-pending.mjs)\r\n// is set, so grants that existed before this shipped never sparkle. Viewing clears the marker. It never grants or\r\n// gates anything: callers decide an item is unlocked, this only remembers that it was looked at.\r\nimport {isPending,clearPending} from './unlock-pending.mjs';\r\n\r\n/** True when this item was granted since the feature shipped and has not been viewed. */\r\nexport const isUnseen=isPending;\r\n\r\nconst STYLE='[data-sparkle]::after{content:\"\\\\2726\" / \"New\";color:#ffd23a;font-size:.85em;margin-left:.3em;text-shadow:0 0 4px #ffd23a;animation:myr5-sparkle 1.4s ease-in-out infinite alternate}'+\r\n 'button[data-sparkle]{position:relative}button[data-color][data-sparkle]::after{position:absolute;top:1px;right:3px;margin:0}'+\r\n '@keyframes myr5-sparkle{to{opacity:.45}}@media (prefers-reduced-motion:reduce){[data-sparkle]::after{animation:none}}';\r\nfunction ensureStyle(doc){\r\n if(doc.getElementById('myr5-sparkle-style'))return;\r\n const style=doc.createElement('style');style.id='myr5-sparkle-style';style.textContent=STYLE;doc.head.append(style);\r\n}\r\n\r\n/** Records the item as viewed and clears every sparkle showing it. */\r\nexport function markSeen(kind,id,options){\r\n clearPending(kind,id,options);\r\n for(const el of globalThis.document?.querySelectorAll('[data-sparkle]')||[])if(el.dataset.sparkle===`${kind}:${id}`){\r\n  delete el.dataset.sparkle;\r\n  if(el.tagName==='OPTION'&&el.textContent.startsWith('✦ '))el.textContent=el.textContent.slice(2);\r\n }\r\n}\r\n\r\n// Keep each badge visible long enough to notice. Time outside the viewport or in a hidden tab never counts.\r\nconst DWELL_MS=1500;\r\nfunction afterVisibleDwell(el,seen,active=()=>!!el.dataset.sparkle){\r\n if(typeof IntersectionObserver!=='function')return;\r\n const doc=el.ownerDocument;let inView=false,timer=null;\r\n const cancel=()=>{if(timer!==null){clearTimeout(timer);timer=null;}};\r\n const schedule=()=>{if(timer!==null||!inView||doc.visibilityState!=='visible'||!active())return;\r\n  timer=setTimeout(()=>{timer=null;if(inView&&el.isConnected&&doc.visibilityState==='visible'&&active()){io.disconnect();doc.removeEventListener('visibilitychange',onVisibility);seen();}},DWELL_MS);\r\n };\r\n const onVisibility=()=>{if(doc.visibilityState!=='visible')cancel();else schedule();};\r\n const io=new IntersectionObserver(entries=>{\r\n  if(!el.isConnected){cancel();io.disconnect();doc.removeEventListener('visibilitychange',onVisibility);return;}\r\n  inView=entries.some(e=>e.isIntersecting&&e.intersectionRatio>=.6);\r\n  if(inView)schedule();else cancel();\r\n },{threshold:[.6]});\r\n doc.addEventListener('visibilitychange',onVisibility);io.observe(el);\r\n}\r\n\r\n/** Sparkles `el` if unseen. It clears after 1.5s on screen, or immediately on click/focus. */\r\nexport function sparkle(el,kind,id,options){\r\n if(!isUnseen(kind,id,options))return false;\r\n ensureStyle(el.ownerDocument);\r\n el.dataset.sparkle=`${kind}:${id}`;\r\n const seen=()=>markSeen(kind,id,options);\r\n el.addEventListener('click',seen,{once:true});el.addEventListener('focus',seen,{once:true});\r\n afterVisibleDwell(el,seen);\r\n return true;\r\n}\r\n\r\n/** <option> variant: a closed dropdown shows nothing, so the item counts as viewed once it is picked (watchSelect). */\r\nexport function sparkleOption(option,kind,id,options){\r\n if(!isUnseen(kind,id,options))return false;\r\n ensureStyle(option.ownerDocument);\r\n option.dataset.sparkle=`${kind}:${id}`;option.textContent='✦ '+option.textContent;\r\n return true;\r\n}\r\nconst markSelected=(select,options)=>{\r\n const tag=select.selectedOptions[0]?.dataset.sparkle,at=tag?.indexOf(':');\r\n if(tag)markSeen(tag.slice(0,at),tag.slice(at+1),options);\r\n};\r\n/** Picking an option views it; so does the select showing it on screen (a lone ship or skin can't be \"picked\"). */\r\nexport function watchSelect(select,options){\r\n select.addEventListener('change',()=>markSelected(select,options));\r\n afterVisibleDwell(select,()=>markSelected(select,options),()=>!!select.selectedOptions[0]?.dataset.sparkle);\r\n}\r\n","update-policy.mjs":"export const UPDATE_IDLE_MS=15000;\r\nexport const RELEASE_SEEN_KEY='myr5-release-seen-v1';\r\n\r\nexport function safeToUpdate({tracking=false,rest=false,dialog=false,editing=false,hidden=false,online=true,lastInteraction=0,now=Date.now(),automatic=true}={}){\r\n return !tracking&&!rest&&!dialog&&!editing&&!hidden&&online&&(!automatic||now-lastInteraction>=UPDATE_IDLE_MS);\r\n}\r\n\r\nexport function releaseNotice(storage,id){\r\n let seen=false;\r\n try{seen=storage.getItem(RELEASE_SEEN_KEY)===id;}catch{}\r\n return {get visible(){return !seen;},dismiss(){seen=true;try{storage.setItem(RELEASE_SEEN_KEY,id);}catch{}}};\r\n}\r\n\r\nexport function requestActivation(worker,{timeout=10000}={}){\r\n return new Promise((resolve,reject)=>{\r\n  const channel=new MessageChannel();\r\n  const finish=(error)=>{clearTimeout(timer);channel.port1.close();error?reject(error):resolve();};\r\n  const timer=setTimeout(()=>finish(Error('Coach is still preparing the update. It will retry automatically.')),timeout);\r\n  channel.port1.onmessage=event=>finish(event.data?.activated?null:Error('Coach is waiting for another session to finish saving. It will retry automatically.'));\r\n  try{worker.postMessage({type:'PREPARE_UPDATE'},[channel.port2]);}catch(error){finish(error);}\r\n });\r\n}\r\n","update-session.mjs":"// A prepared page keeps its workout lease until activation or an explicit abort.\r\n// Only an explicit abort releases it early (app-updates.mjs aborts when its barrier times out).\r\nexport function createUpdateParticipant({canPrepare,acquire,save,freeze,reload}){\r\n let held=null,preparing=null;\r\n function abort(id){if(held?.id!==id)return;const item=held;held=null;item.release();item.thaw?.();}\r\n async function message(data){\r\n  const id=data?.id;if(typeof id!=='string'||!id)return {safe:false};\r\n  if(data.type==='UPDATE_ABORT'){abort(id);return {safe:false};}\r\n  if(data.type==='UPDATE_CONFIRM')return {safe:held?.id===id&&held.ready===true,protocol:2,id};\r\n  if(data.type!=='UPDATE_SAFETY_CHECK')return {safe:false};\r\n  if(held)return {safe:held.id===id&&held.ready===true,protocol:2,id};\r\n  if(preparing||!canPrepare())return {safe:false};\r\n  const release=acquire();if(!release)return {safe:false};\r\n  const item={id,release,ready:false,thaw:null};held=item;\r\n  try{\r\n   item.thaw=freeze(id);preparing=Promise.resolve().then(save);await preparing;\r\n   if(held!==item)return {safe:false};item.ready=true;\r\n   return {safe:true,protocol:2,id};\r\n  }catch{abort(id);return {safe:false};}finally{preparing=null;}\r\n }\r\n return {message,get prepared(){return !!held?.ready;},activated(){if(held?.ready){reload();return true;}return false;}};\r\n}\r\n","vendor/bitchord/LICENSE":"                    GNU GENERAL PUBLIC LICENSE\r\n                       Version 3, 29 June 2007\r\n\r\n Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\n                            Preamble\r\n\r\n  The GNU General Public License is a free, copyleft license for\r\nsoftware and other kinds of works.\r\n\r\n  The licenses for most software and other practical works are designed\r\nto take away your freedom to share and change the works.  By contrast,\r\nthe GNU General Public License is intended to guarantee your freedom to\r\nshare and change all versions of a program--to make sure it remains free\r\nsoftware for all its users.  We, the Free Software Foundation, use the\r\nGNU General Public License for most of our software; it applies also to\r\nany other work released this way by its authors.  You can apply it to\r\nyour programs, too.\r\n\r\n  When we speak of free software, we are referring to freedom, not\r\nprice.  Our General Public Licenses are designed to make sure that you\r\nhave the freedom to distribute copies of free software (and charge for\r\nthem if you wish), that you receive source code or can get it if you\r\nwant it, that you can change the software or use pieces of it in new\r\nfree programs, and that you know you can do these things.\r\n\r\n  To protect your rights, we need to prevent others from denying you\r\nthese rights or asking you to surrender the rights.  Therefore, you have\r\ncertain responsibilities if you distribute copies of the software, or if\r\nyou modify it: responsibilities to respect the freedom of others.\r\n\r\n  For example, if you distribute copies of such a program, whether\r\ngratis or for a fee, you must pass on to the recipients the same\r\nfreedoms that you received.  You must make sure that they, too, receive\r\nor can get the source code.  And you must show them these terms so they\r\nknow their rights.\r\n\r\n  Developers that use the GNU GPL protect your rights with two steps:\r\n(1) assert copyright on the software, and (2) offer you this License\r\ngiving you legal permission to copy, distribute and/or modify it.\r\n\r\n  For the developers' and authors' protection, the GPL clearly explains\r\nthat there is no warranty for this free software.  For both users' and\r\nauthors' sake, the GPL requires that modified versions be marked as\r\nchanged, so that their problems will not be attributed erroneously to\r\nauthors of previous versions.\r\n\r\n  Some devices are designed to deny users access to install or run\r\nmodified versions of the software inside them, although the manufacturer\r\ncan do so.  This is fundamentally incompatible with the aim of\r\nprotecting users' freedom to change the software.  The systematic\r\npattern of such abuse occurs in the area of products for individuals to\r\nuse, which is precisely where it is most unacceptable.  Therefore, we\r\nhave designed this version of the GPL to prohibit the practice for those\r\nproducts.  If such problems arise substantially in other domains, we\r\nstand ready to extend this provision to those domains in future versions\r\nof the GPL, as needed to protect the freedom of users.\r\n\r\n  Finally, every program is threatened constantly by software patents.\r\nStates should not allow patents to restrict development and use of\r\nsoftware on general-purpose computers, but in those that do, we wish to\r\navoid the special danger that patents applied to a free program could\r\nmake it effectively proprietary.  To prevent this, the GPL assures that\r\npatents cannot be used to render the program non-free.\r\n\r\n  The precise terms and conditions for copying, distribution and\r\nmodification follow.\r\n\r\n                       TERMS AND CONDITIONS\r\n\r\n  0. Definitions.\r\n\r\n  \"This License\" refers to version 3 of the GNU General Public License.\r\n\r\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\r\nworks, such as semiconductor masks.\r\n\r\n  \"The Program\" refers to any copyrightable work licensed under this\r\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\r\n\"recipients\" may be individuals or organizations.\r\n\r\n  To \"modify\" a work means to copy from or adapt all or part of the work\r\nin a fashion requiring copyright permission, other than the making of an\r\nexact copy.  The resulting work is called a \"modified version\" of the\r\nearlier work or a work \"based on\" the earlier work.\r\n\r\n  A \"covered work\" means either the unmodified Program or a work based\r\non the Program.\r\n\r\n  To \"propagate\" a work means to do anything with it that, without\r\npermission, would make you directly or secondarily liable for\r\ninfringement under applicable copyright law, except executing it on a\r\ncomputer or modifying a private copy.  Propagation includes copying,\r\ndistribution (with or without modification), making available to the\r\npublic, and in some countries other activities as well.\r\n\r\n  To \"convey\" a work means any kind of propagation that enables other\r\nparties to make or receive copies.  Mere interaction with a user through\r\na computer network, with no transfer of a copy, is not conveying.\r\n\r\n  An interactive user interface displays \"Appropriate Legal Notices\"\r\nto the extent that it includes a convenient and prominently visible\r\nfeature that (1) displays an appropriate copyright notice, and (2)\r\ntells the user that there is no warranty for the work (except to the\r\nextent that warranties are provided), that licensees may convey the\r\nwork under this License, and how to view a copy of this License.  If\r\nthe interface presents a list of user commands or options, such as a\r\nmenu, a prominent item in the list meets this criterion.\r\n\r\n  1. Source Code.\r\n\r\n  The \"source code\" for a work means the preferred form of the work\r\nfor making modifications to it.  \"Object code\" means any non-source\r\nform of a work.\r\n\r\n  A \"Standard Interface\" means an interface that either is an official\r\nstandard defined by a recognized standards body, or, in the case of\r\ninterfaces specified for a particular programming language, one that\r\nis widely used among developers working in that language.\r\n\r\n  The \"System Libraries\" of an executable work include anything, other\r\nthan the work as a whole, that (a) is included in the normal form of\r\npackaging a Major Component, but which is not part of that Major\r\nComponent, and (b) serves only to enable use of the work with that\r\nMajor Component, or to implement a Standard Interface for which an\r\nimplementation is available to the public in source code form.  A\r\n\"Major Component\", in this context, means a major essential component\r\n(kernel, window system, and so on) of the specific operating system\r\n(if any) on which the executable work runs, or a compiler used to\r\nproduce the work, or an object code interpreter used to run it.\r\n\r\n  The \"Corresponding Source\" for a work in object code form means all\r\nthe source code needed to generate, install, and (for an executable\r\nwork) run the object code and to modify the work, including scripts to\r\ncontrol those activities.  However, it does not include the work's\r\nSystem Libraries, or general-purpose tools or generally available free\r\nprograms which are used unmodified in performing those activities but\r\nwhich are not part of the work.  For example, Corresponding Source\r\nincludes interface definition files associated with source files for\r\nthe work, and the source code for shared libraries and dynamically\r\nlinked subprograms that the work is specifically designed to require,\r\nsuch as by intimate data communication or control flow between those\r\nsubprograms and other parts of the work.\r\n\r\n  The Corresponding Source need not include anything that users\r\ncan regenerate automatically from other parts of the Corresponding\r\nSource.\r\n\r\n  The Corresponding Source for a work in source code form is that\r\nsame work.\r\n\r\n  2. Basic Permissions.\r\n\r\n  All rights granted under this License are granted for the term of\r\ncopyright on the Program, and are irrevocable provided the stated\r\nconditions are met.  This License explicitly affirms your unlimited\r\npermission to run the unmodified Program.  The output from running a\r\ncovered work is covered by this License only if the output, given its\r\ncontent, constitutes a covered work.  This License acknowledges your\r\nrights of fair use or other equivalent, as provided by copyright law.\r\n\r\n  You may make, run and propagate covered works that you do not\r\nconvey, without conditions so long as your license otherwise remains\r\nin force.  You may convey covered works to others for the sole purpose\r\nof having them make modifications exclusively for you, or provide you\r\nwith facilities for running those works, provided that you comply with\r\nthe terms of this License in conveying all material for which you do\r\nnot control copyright.  Those thus making or running the covered works\r\nfor you must do so exclusively on your behalf, under your direction\r\nand control, on terms that prohibit them from making any copies of\r\nyour copyrighted material outside their relationship with you.\r\n\r\n  Conveying under any other circumstances is permitted solely under\r\nthe conditions stated below.  Sublicensing is not allowed; section 10\r\nmakes it unnecessary.\r\n\r\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\r\n\r\n  No covered work shall be deemed part of an effective technological\r\nmeasure under any applicable law fulfilling obligations under article\r\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\r\nsimilar laws prohibiting or restricting circumvention of such\r\nmeasures.\r\n\r\n  When you convey a covered work, you waive any legal power to forbid\r\ncircumvention of technological measures to the extent such circumvention\r\nis effected by exercising rights under this License with respect to\r\nthe covered work, and you disclaim any intention to limit operation or\r\nmodification of the work as a means of enforcing, against the work's\r\nusers, your or third parties' legal rights to forbid circumvention of\r\ntechnological measures.\r\n\r\n  4. Conveying Verbatim Copies.\r\n\r\n  You may convey verbatim copies of the Program's source code as you\r\nreceive it, in any medium, provided that you conspicuously and\r\nappropriately publish on each copy an appropriate copyright notice;\r\nkeep intact all notices stating that this License and any\r\nnon-permissive terms added in accord with section 7 apply to the code;\r\nkeep intact all notices of the absence of any warranty; and give all\r\nrecipients a copy of this License along with the Program.\r\n\r\n  You may charge any price or no price for each copy that you convey,\r\nand you may offer support or warranty protection for a fee.\r\n\r\n  5. Conveying Modified Source Versions.\r\n\r\n  You may convey a work based on the Program, or the modifications to\r\nproduce it from the Program, in the form of source code under the\r\nterms of section 4, provided that you also meet all of these conditions:\r\n\r\n    a) The work must carry prominent notices stating that you modified\r\n    it, and giving a relevant date.\r\n\r\n    b) The work must carry prominent notices stating that it is\r\n    released under this License and any conditions added under section\r\n    7.  This requirement modifies the requirement in section 4 to\r\n    \"keep intact all notices\".\r\n\r\n    c) You must license the entire work, as a whole, under this\r\n    License to anyone who comes into possession of a copy.  This\r\n    License will therefore apply, along with any applicable section 7\r\n    additional terms, to the whole of the work, and all its parts,\r\n    regardless of how they are packaged.  This License gives no\r\n    permission to license the work in any other way, but it does not\r\n    invalidate such permission if you have separately received it.\r\n\r\n    d) If the work has interactive user interfaces, each must display\r\n    Appropriate Legal Notices; however, if the Program has interactive\r\n    interfaces that do not display Appropriate Legal Notices, your\r\n    work need not make them do so.\r\n\r\n  A compilation of a covered work with other separate and independent\r\nworks, which are not by their nature extensions of the covered work,\r\nand which are not combined with it such as to form a larger program,\r\nin or on a volume of a storage or distribution medium, is called an\r\n\"aggregate\" if the compilation and its resulting copyright are not\r\nused to limit the access or legal rights of the compilation's users\r\nbeyond what the individual works permit.  Inclusion of a covered work\r\nin an aggregate does not cause this License to apply to the other\r\nparts of the aggregate.\r\n\r\n  6. Conveying Non-Source Forms.\r\n\r\n  You may convey a covered work in object code form under the terms\r\nof sections 4 and 5, provided that you also convey the\r\nmachine-readable Corresponding Source under the terms of this License,\r\nin one of these ways:\r\n\r\n    a) Convey the object code in, or embodied in, a physical product\r\n    (including a physical distribution medium), accompanied by the\r\n    Corresponding Source fixed on a durable physical medium\r\n    customarily used for software interchange.\r\n\r\n    b) Convey the object code in, or embodied in, a physical product\r\n    (including a physical distribution medium), accompanied by a\r\n    written offer, valid for at least three years and valid for as\r\n    long as you offer spare parts or customer support for that product\r\n    model, to give anyone who possesses the object code either (1) a\r\n    copy of the Corresponding Source for all the software in the\r\n    product that is covered by this License, on a durable physical\r\n    medium customarily used for software interchange, for a price no\r\n    more than your reasonable cost of physically performing this\r\n    conveying of source, or (2) access to copy the\r\n    Corresponding Source from a network server at no charge.\r\n\r\n    c) Convey individual copies of the object code with a copy of the\r\n    written offer to provide the Corresponding Source.  This\r\n    alternative is allowed only occasionally and noncommercially, and\r\n    only if you received the object code with such an offer, in accord\r\n    with subsection 6b.\r\n\r\n    d) Convey the object code by offering access from a designated\r\n    place (gratis or for a charge), and offer equivalent access to the\r\n    Corresponding Source in the same way through the same place at no\r\n    further charge.  You need not require recipients to copy the\r\n    Corresponding Source along with the object code.  If the place to\r\n    copy the object code is a network server, the Corresponding Source\r\n    may be on a different server (operated by you or a third party)\r\n    that supports equivalent copying facilities, provided you maintain\r\n    clear directions next to the object code saying where to find the\r\n    Corresponding Source.  Regardless of what server hosts the\r\n    Corresponding Source, you remain obligated to ensure that it is\r\n    available for as long as needed to satisfy these requirements.\r\n\r\n    e) Convey the object code using peer-to-peer transmission, provided\r\n    you inform other peers where the object code and Corresponding\r\n    Source of the work are being offered to the general public at no\r\n    charge under subsection 6d.\r\n\r\n  A separable portion of the object code, whose source code is excluded\r\nfrom the Corresponding Source as a System Library, need not be\r\nincluded in conveying the object code work.\r\n\r\n  A \"User Product\" is either (1) a \"consumer product\", which means any\r\ntangible personal property which is normally used for personal, family,\r\nor household purposes, or (2) anything designed or sold for incorporation\r\ninto a dwelling.  In determining whether a product is a consumer product,\r\ndoubtful cases shall be resolved in favor of coverage.  For a particular\r\nproduct received by a particular user, \"normally used\" refers to a\r\ntypical or common use of that class of product, regardless of the status\r\nof the particular user or of the way in which the particular user\r\nactually uses, or expects or is expected to use, the product.  A product\r\nis a consumer product regardless of whether the product has substantial\r\ncommercial, industrial or non-consumer uses, unless such uses represent\r\nthe only significant mode of use of the product.\r\n\r\n  \"Installation Information\" for a User Product means any methods,\r\nprocedures, authorization keys, or other information required to install\r\nand execute modified versions of a covered work in that User Product from\r\na modified version of its Corresponding Source.  The information must\r\nsuffice to ensure that the continued functioning of the modified object\r\ncode is in no case prevented or interfered with solely because\r\nmodification has been made.\r\n\r\n  If you convey an object code work under this section in, or with, or\r\nspecifically for use in, a User Product, and the conveying occurs as\r\npart of a transaction in which the right of possession and use of the\r\nUser Product is transferred to the recipient in perpetuity or for a\r\nfixed term (regardless of how the transaction is characterized), the\r\nCorresponding Source conveyed under this section must be accompanied\r\nby the Installation Information.  But this requirement does not apply\r\nif neither you nor any third party retains the ability to install\r\nmodified object code on the User Product (for example, the work has\r\nbeen installed in ROM).\r\n\r\n  The requirement to provide Installation Information does not include a\r\nrequirement to continue to provide support service, warranty, or updates\r\nfor a work that has been modified or installed by the recipient, or for\r\nthe User Product in which it has been modified or installed.  Access to a\r\nnetwork may be denied when the modification itself materially and\r\nadversely affects the operation of the network or violates the rules and\r\nprotocols for communication across the network.\r\n\r\n  Corresponding Source conveyed, and Installation Information provided,\r\nin accord with this section must be in a format that is publicly\r\ndocumented (and with an implementation available to the public in\r\nsource code form), and must require no special password or key for\r\nunpacking, reading or copying.\r\n\r\n  7. Additional Terms.\r\n\r\n  \"Additional permissions\" are terms that supplement the terms of this\r\nLicense by making exceptions from one or more of its conditions.\r\nAdditional permissions that are applicable to the entire Program shall\r\nbe treated as though they were included in this License, to the extent\r\nthat they are valid under applicable law.  If additional permissions\r\napply only to part of the Program, that part may be used separately\r\nunder those permissions, but the entire Program remains governed by\r\nthis License without regard to the additional permissions.\r\n\r\n  When you convey a copy of a covered work, you may at your option\r\nremove any additional permissions from that copy, or from any part of\r\nit.  (Additional permissions may be written to require their own\r\nremoval in certain cases when you modify the work.)  You may place\r\nadditional permissions on material, added by you to a covered work,\r\nfor which you have or can give appropriate copyright permission.\r\n\r\n  Notwithstanding any other provision of this License, for material you\r\nadd to a covered work, you may (if authorized by the copyright holders of\r\nthat material) supplement the terms of this License with terms:\r\n\r\n    a) Disclaiming warranty or limiting liability differently from the\r\n    terms of sections 15 and 16 of this License; or\r\n\r\n    b) Requiring preservation of specified reasonable legal notices or\r\n    author attributions in that material or in the Appropriate Legal\r\n    Notices displayed by works containing it; or\r\n\r\n    c) Prohibiting misrepresentation of the origin of that material, or\r\n    requiring that modified versions of such material be marked in\r\n    reasonable ways as different from the original version; or\r\n\r\n    d) Limiting the use for publicity purposes of names of licensors or\r\n    authors of the material; or\r\n\r\n    e) Declining to grant rights under trademark law for use of some\r\n    trade names, trademarks, or service marks; or\r\n\r\n    f) Requiring indemnification of licensors and authors of that\r\n    material by anyone who conveys the material (or modified versions of\r\n    it) with contractual assumptions of liability to the recipient, for\r\n    any liability that these contractual assumptions directly impose on\r\n    those licensors and authors.\r\n\r\n  All other non-permissive additional terms are considered \"further\r\nrestrictions\" within the meaning of section 10.  If the Program as you\r\nreceived it, or any part of it, contains a notice stating that it is\r\ngoverned by this License along with a term that is a further\r\nrestriction, you may remove that term.  If a license document contains\r\na further restriction but permits relicensing or conveying under this\r\nLicense, you may add to a covered work material governed by the terms\r\nof that license document, provided that the further restriction does\r\nnot survive such relicensing or conveying.\r\n\r\n  If you add terms to a covered work in accord with this section, you\r\nmust place, in the relevant source files, a statement of the\r\nadditional terms that apply to those files, or a notice indicating\r\nwhere to find the applicable terms.\r\n\r\n  Additional terms, permissive or non-permissive, may be stated in the\r\nform of a separately written license, or stated as exceptions;\r\nthe above requirements apply either way.\r\n\r\n  8. Termination.\r\n\r\n  You may not propagate or modify a covered work except as expressly\r\nprovided under this License.  Any attempt otherwise to propagate or\r\nmodify it is void, and will automatically terminate your rights under\r\nthis License (including any patent licenses granted under the third\r\nparagraph of section 11).\r\n\r\n  However, if you cease all violation of this License, then your\r\nlicense from a particular copyright holder is reinstated (a)\r\nprovisionally, unless and until the copyright holder explicitly and\r\nfinally terminates your license, and (b) permanently, if the copyright\r\nholder fails to notify you of the violation by some reasonable means\r\nprior to 60 days after the cessation.\r\n\r\n  Moreover, your license from a particular copyright holder is\r\nreinstated permanently if the copyright holder notifies you of the\r\nviolation by some reasonable means, this is the first time you have\r\nreceived notice of violation of this License (for any work) from that\r\ncopyright holder, and you cure the violation prior to 30 days after\r\nyour receipt of the notice.\r\n\r\n  Termination of your rights under this section does not terminate the\r\nlicenses of parties who have received copies or rights from you under\r\nthis License.  If your rights have been terminated and not permanently\r\nreinstated, you do not qualify to receive new licenses for the same\r\nmaterial under section 10.\r\n\r\n  9. Acceptance Not Required for Having Copies.\r\n\r\n  You are not required to accept this License in order to receive or\r\nrun a copy of the Program.  Ancillary propagation of a covered work\r\noccurring solely as a consequence of using peer-to-peer transmission\r\nto receive a copy likewise does not require acceptance.  However,\r\nnothing other than this License grants you permission to propagate or\r\nmodify any covered work.  These actions infringe copyright if you do\r\nnot accept this License.  Therefore, by modifying or propagating a\r\ncovered work, you indicate your acceptance of this License to do so.\r\n\r\n  10. Automatic Licensing of Downstream Recipients.\r\n\r\n  Each time you convey a covered work, the recipient automatically\r\nreceives a license from the original licensors, to run, modify and\r\npropagate that work, subject to this License.  You are not responsible\r\nfor enforcing compliance by third parties with this License.\r\n\r\n  An \"entity transaction\" is a transaction transferring control of an\r\norganization, or substantially all assets of one, or subdividing an\r\norganization, or merging organizations.  If propagation of a covered\r\nwork results from an entity transaction, each party to that\r\ntransaction who receives a copy of the work also receives whatever\r\nlicenses to the work the party's predecessor in interest had or could\r\ngive under the previous paragraph, plus a right to possession of the\r\nCorresponding Source of the work from the predecessor in interest, if\r\nthe predecessor has it or can get it with reasonable efforts.\r\n\r\n  You may not impose any further restrictions on the exercise of the\r\nrights granted or affirmed under this License.  For example, you may\r\nnot impose a license fee, royalty, or other charge for exercise of\r\nrights granted under this License, and you may not initiate litigation\r\n(including a cross-claim or counterclaim in a lawsuit) alleging that\r\nany patent claim is infringed by making, using, selling, offering for\r\nsale, or importing the Program or any portion of it.\r\n\r\n  11. Patents.\r\n\r\n  A \"contributor\" is a copyright holder who authorizes use under this\r\nLicense of the Program or a work on which the Program is based.  The\r\nwork thus licensed is called the contributor's \"contributor version\".\r\n\r\n  A contributor's \"essential patent claims\" are all patent claims\r\nowned or controlled by the contributor, whether already acquired or\r\nhereafter acquired, that would be infringed by some manner, permitted\r\nby this License, of making, using, or selling its contributor version,\r\nbut do not include claims that would be infringed only as a\r\nconsequence of further modification of the contributor version.  For\r\npurposes of this definition, \"control\" includes the right to grant\r\npatent sublicenses in a manner consistent with the requirements of\r\nthis License.\r\n\r\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\r\npatent license under the contributor's essential patent claims, to\r\nmake, use, sell, offer for sale, import and otherwise run, modify and\r\npropagate the contents of its contributor version.\r\n\r\n  In the following three paragraphs, a \"patent license\" is any express\r\nagreement or commitment, however denominated, not to enforce a patent\r\n(such as an express permission to practice a patent or covenant not to\r\nsue for patent infringement).  To \"grant\" such a patent license to a\r\nparty means to make such an agreement or commitment not to enforce a\r\npatent against the party.\r\n\r\n  If you convey a covered work, knowingly relying on a patent license,\r\nand the Corresponding Source of the work is not available for anyone\r\nto copy, free of charge and under the terms of this License, through a\r\npublicly available network server or other readily accessible means,\r\nthen you must either (1) cause the Corresponding Source to be so\r\navailable, or (2) arrange to deprive yourself of the benefit of the\r\npatent license for this particular work, or (3) arrange, in a manner\r\nconsistent with the requirements of this License, to extend the patent\r\nlicense to downstream recipients.  \"Knowingly relying\" means you have\r\nactual knowledge that, but for the patent license, your conveying the\r\ncovered work in a country, or your recipient's use of the covered work\r\nin a country, would infringe one or more identifiable patents in that\r\ncountry that you have reason to believe are valid.\r\n\r\n  If, pursuant to or in connection with a single transaction or\r\narrangement, you convey, or propagate by procuring conveyance of, a\r\ncovered work, and grant a patent license to some of the parties\r\nreceiving the covered work authorizing them to use, propagate, modify\r\nor convey a specific copy of the covered work, then the patent license\r\nyou grant is automatically extended to all recipients of the covered\r\nwork and works based on it.\r\n\r\n  A patent license is \"discriminatory\" if it does not include within\r\nthe scope of its coverage, prohibits the exercise of, or is\r\nconditioned on the non-exercise of one or more of the rights that are\r\nspecifically granted under this License.  You may not convey a covered\r\nwork if you are a party to an arrangement with a third party that is\r\nin the business of distributing software, under which you make payment\r\nto the third party based on the extent of your activity of conveying\r\nthe work, and under which the third party grants, to any of the\r\nparties who would receive the covered work from you, a discriminatory\r\npatent license (a) in connection with copies of the covered work\r\nconveyed by you (or copies made from those copies), or (b) primarily\r\nfor and in connection with specific products or compilations that\r\ncontain the covered work, unless you entered into that arrangement,\r\nor that patent license was granted, prior to 28 March 2007.\r\n\r\n  Nothing in this License shall be construed as excluding or limiting\r\nany implied license or other defenses to infringement that may\r\notherwise be available to you under applicable patent law.\r\n\r\n  12. No Surrender of Others' Freedom.\r\n\r\n  If conditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License.  If you cannot convey a\r\ncovered work so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you may\r\nnot convey it at all.  For example, if you agree to terms that obligate you\r\nto collect a royalty for further conveying from those to whom you convey\r\nthe Program, the only way you could satisfy both those terms and this\r\nLicense would be to refrain entirely from conveying the Program.\r\n\r\n  13. Use with the GNU Affero General Public License.\r\n\r\n  Notwithstanding any other provision of this License, you have\r\npermission to link or combine any covered work with a work licensed\r\nunder version 3 of the GNU Affero General Public License into a single\r\ncombined work, and to convey the resulting work.  The terms of this\r\nLicense will continue to apply to the part which is the covered work,\r\nbut the special requirements of the GNU Affero General Public License,\r\nsection 13, concerning interaction through a network will apply to the\r\ncombination as such.\r\n\r\n  14. Revised Versions of this License.\r\n\r\n  The Free Software Foundation may publish revised and/or new versions of\r\nthe GNU General Public License from time to time.  Such new versions will\r\nbe similar in spirit to the present version, but may differ in detail to\r\naddress new problems or concerns.\r\n\r\n  Each version is given a distinguishing version number.  If the\r\nProgram specifies that a certain numbered version of the GNU General\r\nPublic License \"or any later version\" applies to it, you have the\r\noption of following the terms and conditions either of that numbered\r\nversion or of any later version published by the Free Software\r\nFoundation.  If the Program does not specify a version number of the\r\nGNU General Public License, you may choose any version ever published\r\nby the Free Software Foundation.\r\n\r\n  If the Program specifies that a proxy can decide which future\r\nversions of the GNU General Public License can be used, that proxy's\r\npublic statement of acceptance of a version permanently authorizes you\r\nto choose that version for the Program.\r\n\r\n  Later license versions may give you additional or different\r\npermissions.  However, no additional obligations are imposed on any\r\nauthor or copyright holder as a result of your choosing to follow a\r\nlater version.\r\n\r\n  15. Disclaimer of Warranty.\r\n\r\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\r\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\r\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\r\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\r\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\r\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\r\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r\n\r\n  16. Limitation of Liability.\r\n\r\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\r\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\r\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\r\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\r\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\r\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\r\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\r\nSUCH DAMAGES.\r\n\r\n  17. Interpretation of Sections 15 and 16.\r\n\r\n  If the disclaimer of warranty and limitation of liability provided\r\nabove cannot be given local legal effect according to their terms,\r\nreviewing courts shall apply local law that most closely approximates\r\nan absolute waiver of all civil liability in connection with the\r\nProgram, unless a warranty or assumption of liability accompanies a\r\ncopy of the Program in return for a fee.\r\n\r\n                     END OF TERMS AND CONDITIONS\r\n\r\n            How to Apply These Terms to Your New Programs\r\n\r\n  If you develop a new program, and you want it to be of the greatest\r\npossible use to the public, the best way to achieve this is to make it\r\nfree software which everyone can redistribute and change under these terms.\r\n\r\n  To do so, attach the following notices to the program.  It is safest\r\nto attach them to the start of each source file to most effectively\r\nstate the exclusion of warranty; and each file should have at least\r\nthe \"copyright\" line and a pointer to where the full notice is found.\r\n\r\n    <one line to give the program's name and a brief idea of what it does.>\r\n    Copyright (C) <year>  <name of author>\r\n\r\n    This program is free software: you can redistribute it and/or modify\r\n    it under the terms of the GNU General Public License as published by\r\n    the Free Software Foundation, either version 3 of the License, or\r\n    (at your option) any later version.\r\n\r\n    This program is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU General Public License for more details.\r\n\r\n    You should have received a copy of the GNU General Public License\r\n    along with this program.  If not, see <https://www.gnu.org/licenses/>.\r\n\r\nAlso add information on how to contact you by electronic and paper mail.\r\n\r\n  If the program does terminal interaction, make it output a short\r\nnotice like this when it starts in an interactive mode:\r\n\r\n    <program>  Copyright (C) <year>  <name of author>\r\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\r\n    This is free software, and you are welcome to redistribute it\r\n    under certain conditions; type `show c' for details.\r\n\r\nThe hypothetical commands `show w' and `show c' should show the appropriate\r\nparts of the General Public License.  Of course, your program's commands\r\nmight be different; for a GUI interface, you would use an \"about box\".\r\n\r\n  You should also get your employer (if you work as a programmer) or school,\r\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\r\nFor more information on this, and how to apply and follow the GNU GPL, see\r\n<https://www.gnu.org/licenses/>.\r\n\r\n  The GNU General Public License does not permit incorporating your program\r\ninto proprietary programs.  If your program is a subroutine library, you\r\nmay consider it more useful to permit linking proprietary applications with\r\nthe library.  If this is what you want to do, use the GNU Lesser General\r\nPublic License instead of this License.  But first, please read\r\n<https://www.gnu.org/licenses/why-not-lgpl.html>.\r\n","vendor/bitchord/NOTICE":"BitChord playback gain helpers\r\nSource: https://github.com/kushagrasinghx/BitChord\r\nRevision: 2c599a6cd7a195227a11dab5769f88da8fd08194\r\nOrigin: app/src/main/java/com/music/bitchord/playback/CrossfadeController.kt\r\nMYR5 adaptation: actual-dj-engine.mjs riseGain / fallGain (JavaScript port).\r\nCopyright and license: upstream contributors, GPL-3.0. See LICENSE.\r\nThe remaining native Android playback and analysis stack is not bundled here.\r\n","vendor/butterchurn/LICENSE.engine":"MIT License\n\nCopyright (c) 2013-2018 Jordan Berg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","vendor/butterchurn/LICENSE.presets":"MIT License\n\nCopyright (c) 2013-2018 Jordan Berg\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","vendor/butterchurn/README.md":"# Vendored Butterchurn\r\n\r\nUnmodified official npm distributables, downloaded 2026-10-09 using `npm pack --ignore-scripts`. No package.json or lockfile changes.\r\n\r\n- Engine: butterchurn **2.6.7**, `lib/butterchurn.min.js` → `butterchurn-2.6.7.min.js`.\r\n  Source: https://github.com/jberg/butterchurn\r\n  Archive: https://registry.npmjs.org/butterchurn/-/butterchurn-2.6.7.tgz\r\n  npm integrity: `sha512-BJiRA8L0L2+84uoG2SSfkp0kclBuN+vQKf217pK7pMlwEO2ZEg3MtO2/o+l8Qpr8Nbejg8tmL1ZHD1jmhiaaqg==`\r\n  Vendored SHA256: `4e67421bc18d48fac4a6ff4e69e2778f770737fbdd4e323438da154085b4818d`.\r\n- Presets: butterchurn-presets **2.4.7**, `lib/butterchurnPresets.min.js` → `presets-2.4.7.min.js`.\r\n  Source: https://github.com/jberg/butterchurn-presets\r\n  Archive: https://registry.npmjs.org/butterchurn-presets/-/butterchurn-presets-2.4.7.tgz\r\n  npm integrity: `sha512-4MdM8ripz/VfH1BCldrIKdAc/1ryJFBDvqlyow6Ivo1frwj0H3duzvSMFC7/wIjAjxb1QpwVHVqGqS9uAFKhpg==`\r\n  Vendored SHA256: `136c746836aef6dff8a1f6a93ede48c7bbe4da27d2f44de6b59ebc56ffefca10`.\r\n\r\nBoth upstream packages use MIT. Their complete original notices travel in LICENSE.engine and LICENSE.presets. Preset author names remain in the preset names and runtime status. No upstream rendering or equation code was modified.\r\n\r\nThe wrapper lazy-loads both UMD scripts. WebGL2 is required; it reports an error if unavailable. It connects actual audio only, via Butterchurn's native AudioNode input or its supported render(audioLevels) waveform input when switching AudioContexts. Input gain controls waveform sensitivity and does not change audible mix volume. Source labels preserve MYR5 mix versus microphone.\r\n\r\nThirty FPS, 1.5 maximum pixel ratio and 32×24 internal mesh limit mobile GPU cost. Reduced motion disables preset morphing and lowers rendering to twelve FPS; preset animations and audio-reactive shape changes remain. This is reduced animation, not a claim of flash-safety certification.\r\n\r\nScene selectors are original preset families, not literal standalone spectrum/scope meters. Each family has three real alternate looks. The palette control selects another supplied preset rather than claiming an unsupported recoloring API. Label it **Alternate look** in UI.\r\n\r\nPrimary presets: orbit = Flexi - mindblob mix; tunnel = martin - glass corridor; spectrum = Geiss - Thumb Drum; scope = Eo.S. + Phat - cubetrace - v2; trails = Zylot - Paint Spill (Music Reactive Paint Mix). All fifteen preset names are declared in the wrapper and selected unchanged from the supplied bank.\r\n\r\nButterchurn 2.6.7 compiles preset equations using new Function. A strict production CSP requires an explicit compatible policy; this wrapper does not weaken the site's policy. Official source documentation: https://github.com/jberg/butterchurn#usage\r\n","vendor/butterchurn/butterchurn-2.6.7.min.js":"!function(t,e){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(\"butterchurn\",[],e):\"object\"==typeof exports?exports.butterchurn=e():t.butterchurn=e()}(window,function(){return function(t){var e={};function i(s){if(e[s])return e[s].exports;var r=e[s]={i:s,l:!1,exports:{}};return t[s].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,s){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:s})},i.r=function(t){\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(t,\"__esModule\",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&\"object\"==typeof t&&t&&t.__esModule)return t;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,\"default\",{enumerable:!0,value:t}),2&e&&\"string\"!=typeof t)for(var r in t)i.d(s,r,function(e){return t[e]}.bind(null,r));return s},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,\"a\",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p=\"\",i(i.s=5)}([function(t,e,i){var s;void 0===(s=function(){return{baseVals:{gammaadj:1.25,wave_g:.5,mv_x:12,warpscale:1,brighten:0,mv_y:9,wave_scale:1,echo_alpha:0,additivewave:0,sx:1,sy:1,warp:.01,red_blue:0,wave_mode:0,wave_brighten:0,wrap:0,zoomexp:1,fshader:0,wave_r:.5,echo_zoom:1,wave_smoothing:.75,warpanimspeed:1,wave_dots:0,wave_x:.5,wave_y:.5,zoom:1,solarize:0,modwavealphabyvolume:0,dx:0,cx:.5,dy:0,darken_center:0,cy:.5,invert:0,bmotionvectorson:0,rot:0,modwavealphaend:.95,wave_mystery:-.2,decay:.9,wave_a:1,wave_b:.5,rating:5,modwavealphastart:.75,darken:0,echo_orient:0,ib_r:.5,ib_g:.5,ib_b:.5,ib_a:0,ib_size:0,ob_r:.5,ob_g:.5,ob_b:.5,ob_a:0,ob_size:0,mv_dx:0,mv_dy:0,mv_a:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_l:0},init_eqs:function(){return{}},frame_eqs:function(t){return t.rkeys=[\"warp\"],t.zoom=1.01+.02*t.treb_att,t.warp=.15+.25*t.bass_att,t},pixel_eqs:function(t){return t.warp=t.warp+.15*t.rad,t},waves:[{baseVals:{a:1,enabled:0,b:1,g:1,scaling:1,samples:512,additive:0,usedots:0,spectrum:0,r:1,smoothing:.5,thick:0,sep:0},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t},point_eqs:\"\"},{baseVals:{a:1,enabled:0,b:1,g:1,scaling:1,samples:512,additive:0,usedots:0,spectrum:0,r:1,smoothing:.5,thick:0,sep:0},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t},point_eqs:\"\"},{baseVals:{a:1,enabled:0,b:1,g:1,scaling:1,samples:512,additive:0,usedots:0,spectrum:0,r:1,smoothing:.5,thick:0,sep:0},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t},point_eqs:\"\"},{baseVals:{a:1,enabled:0,b:1,g:1,scaling:1,samples:512,additive:0,usedots:0,spectrum:0,r:1,smoothing:.5,thick:0,sep:0},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t},point_eqs:\"\"}],shapes:[{baseVals:{r2:0,a:1,enabled:0,b:0,tex_ang:0,thickoutline:0,g:0,textured:0,g2:1,tex_zoom:1,additive:0,border_a:.1,border_b:1,b2:0,a2:0,r:1,border_g:1,rad:.1,x:.5,y:.5,ang:0,sides:4,border_r:1},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t}},{baseVals:{r2:0,a:1,enabled:0,b:0,tex_ang:0,thickoutline:0,g:0,textured:0,g2:1,tex_zoom:1,additive:0,border_a:.1,border_b:1,b2:0,a2:0,r:1,border_g:1,rad:.1,x:.5,y:.5,ang:0,sides:4,border_r:1},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t}},{baseVals:{r2:0,a:1,enabled:0,b:0,tex_ang:0,thickoutline:0,g:0,textured:0,g2:1,tex_zoom:1,additive:0,border_a:.1,border_b:1,b2:0,a2:0,r:1,border_g:1,rad:.1,x:.5,y:.5,ang:0,sides:4,border_r:1},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t}},{baseVals:{r2:0,a:1,enabled:0,b:0,tex_ang:0,thickoutline:0,g:0,textured:0,g2:1,tex_zoom:1,additive:0,border_a:.1,border_b:1,b2:0,a2:0,r:1,border_g:1,rad:.1,x:.5,y:.5,ang:0,sides:4,border_r:1},init_eqs:function(t){return t.rkeys=[],t},frame_eqs:function(t){return t}}],warp:\"shader_body {\\nret = texture2D(sampler_main, uv).rgb;\\nret -= 0.004;\\n}\\n\",comp:\"shader_body {\\nret = texture2D(sampler_main, uv).rgb;\\nret *= hue_shader;\\n}\\n\"}}.apply(e,[]))||(t.exports=s)},function(t,e,i){\"use strict\";{const t=(t,e)=>{var i=\"function\"==typeof e,s=\"function\"==typeof e,r=\"function\"==typeof e;Object.defineProperty(Math,t,{configurable:i,enumerable:r,writable:s,value:e})};t(\"DEG_PER_RAD\",Math.PI/180),t(\"RAD_PER_DEG\",180/Math.PI);const e=new Float32Array(1);t(\"scale\",function(t,e,i,s,r){return 0===arguments.length?NaN:Number.isNaN(t)||Number.isNaN(e)||Number.isNaN(i)||Number.isNaN(s)||Number.isNaN(r)?NaN:t===1/0||t===-1/0?t:(t-e)*(r-s)/(i-e)+s}),t(\"fscale\",function(t,i,s,r,a){return e[0]=Math.scale(t,i,s,r,a),e[0]}),t(\"clamp\",function(t,e,i){return Math.min(i,Math.max(e,t))}),t(\"radians\",function(t){return t*Math.DEG_PER_RAD}),t(\"degrees\",function(t){return t*Math.RAD_PER_DEG})}},function(t,e){window.sqr=function(t){return t*t},window.sqrt=function(t){return Math.sqrt(Math.abs(t))},window.log10=function(t){return Math.log(t)*Math.LOG10E},window.sign=function(t){return t>0?1:t<0?-1:0},window.rand=function(t){var e=Math.floor(t);return e<1?Math.random():Math.random()*e},window.randint=function(t){return Math.floor(rand(t))},window.bnot=function(t){return Math.abs(t)<1e-5?1:0},window.pow=function(t,e){var i,s=Math.pow(t,e);return i=s,!isFinite(i)||isNaN(i)?0:s},window.div=function(t,e){return 0===e?0:t/e},window.mod=function(t,e){return 0===e?0:Math.floor(t)%Math.floor(e)},window.bitor=function(t,e){return Math.floor(t)|Math.floor(e)},window.bitand=function(t,e){return Math.floor(t)&Math.floor(e)},window.sigmoid=function(t,e){var i=1+Math.exp(-t*e);return Math.abs(i)>1e-5?1/i:0},window.bor=function(t,e){return Math.abs(t)>1e-5||Math.abs(e)>1e-5?1:0},window.band=function(t,e){return Math.abs(t)>1e-5&&Math.abs(e)>1e-5?1:0},window.equal=function(t,e){return Math.abs(t-e)<1e-5?1:0},window.above=function(t,e){return t>e?1:0},window.below=function(t,e){return t<e?1:0},window.ifcond=function(t,e,i){return Math.abs(t)>1e-5?e:i},window.memcpy=function(t,e,i,s){var r=e,a=i,h=s;return a<0&&(h+=a,r-=a,a=0),r<0&&(h+=r,a-=r,r=0),h>0&&t.copyWithin(r,a,h),e}},,,function(t,e,i){\"use strict\";i.r(e);i(1),i(2);function s(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var r=function(){function t(e,i){var s=arguments.length>2&&void 0!==arguments[2]&&arguments[2];!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.samplesIn=e,this.samplesOut=i,this.equalize=s,this.NFREQ=2*i,this.equalize&&this.initEqualizeTable(),this.initBitRevTable(),this.initCosSinTable()}var e,i,r;return e=t,(i=[{key:\"initEqualizeTable\",value:function(){this.equalizeArr=new Float32Array(this.samplesOut);for(var t=1/this.samplesOut,e=0;e<this.samplesOut;e++)this.equalizeArr[e]=-.02*Math.log((this.samplesOut-e)*t)}},{key:\"initBitRevTable\",value:function(){this.bitrevtable=new Uint16Array(this.NFREQ);for(var t=0;t<this.NFREQ;t++)this.bitrevtable[t]=t;for(var e=0,i=0;i<this.NFREQ;i++){if(e>i){var s=this.bitrevtable[i];this.bitrevtable[i]=this.bitrevtable[e],this.bitrevtable[e]=s}for(var r=this.NFREQ>>1;r>=1&&e>=r;)e-=r,r>>=1;e+=r}}},{key:\"initCosSinTable\",value:function(){for(var t=2,e=0;t<=this.NFREQ;)e+=1,t<<=1;this.cossintable=[new Float32Array(e),new Float32Array(e)],t=2;for(var i=0;t<=this.NFREQ;){var s=-2*Math.PI/t;this.cossintable[0][i]=Math.cos(s),this.cossintable[1][i]=Math.sin(s),i+=1,t<<=1}}},{key:\"timeToFrequencyDomain\",value:function(t){for(var e=new Float32Array(this.NFREQ),i=new Float32Array(this.NFREQ),s=0;s<this.NFREQ;s++){var r=this.bitrevtable[s];r<this.samplesIn?e[s]=t[r]:e[s]=0,i[s]=0}for(var a=2,h=0;a<=this.NFREQ;){for(var o=this.cossintable[0][h],n=this.cossintable[1][h],l=1,m=0,u=a>>1,g=0;g<u;g++){for(var c=g;c<this.NFREQ;c+=a){var A=c+u,f=l*e[A]-m*i[A],d=l*i[A]+m*e[A];e[A]=e[c]-f,i[A]=i[c]-d,e[c]+=f,i[c]+=d}var v=l;l=v*o-m*n,m=m*o+v*n}a<<=1,h+=1}var p=new Float32Array(this.samplesOut);if(this.equalize)for(var _=0;_<this.samplesOut;_++)p[_]=this.equalizeArr[_]*Math.sqrt(e[_]*e[_]+i[_]*i[_]);else for(var x=0;x<this.samplesOut;x++)p[x]=Math.sqrt(e[x]*e[x]+i[x]*i[x]);return p}}])&&s(e.prototype,i),r&&s(e,r),t}();function a(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var h=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.numSamps=512,this.fftSize=2*this.numSamps,this.fft=new r(this.fftSize,512,!0),e&&(this.audioContext=e,this.audible=e.createDelay(),this.analyser=e.createAnalyser(),this.analyser.smoothingTimeConstant=0,this.analyser.fftSize=this.fftSize,this.audible.connect(this.analyser),this.analyserL=e.createAnalyser(),this.analyserL.smoothingTimeConstant=0,this.analyserL.fftSize=this.fftSize,this.analyserR=e.createAnalyser(),this.analyserR.smoothingTimeConstant=0,this.analyserR.fftSize=this.fftSize,this.splitter=e.createChannelSplitter(2),this.audible.connect(this.splitter),this.splitter.connect(this.analyserL,0),this.splitter.connect(this.analyserR,1)),this.timeByteArray=new Uint8Array(this.fftSize),this.timeByteArrayL=new Uint8Array(this.fftSize),this.timeByteArrayR=new Uint8Array(this.fftSize),this.timeArray=new Int8Array(this.fftSize),this.timeByteArraySignedL=new Int8Array(this.fftSize),this.timeByteArraySignedR=new Int8Array(this.fftSize),this.tempTimeArrayL=new Int8Array(this.fftSize),this.tempTimeArrayR=new Int8Array(this.fftSize),this.timeArrayL=new Int8Array(this.numSamps),this.timeArrayR=new Int8Array(this.numSamps)}var e,i,s;return e=t,(i=[{key:\"sampleAudio\",value:function(){this.analyser.getByteTimeDomainData(this.timeByteArray),this.analyserL.getByteTimeDomainData(this.timeByteArrayL),this.analyserR.getByteTimeDomainData(this.timeByteArrayR),this.processAudio()}},{key:\"updateAudio\",value:function(t,e,i){this.timeByteArray.set(t),this.timeByteArrayL.set(e),this.timeByteArrayR.set(i),this.processAudio()}},{key:\"processAudio\",value:function(){for(var t=0,e=0,i=0;t<this.fftSize;t++)this.timeArray[t]=this.timeByteArray[t]-128,this.timeByteArraySignedL[t]=this.timeByteArrayL[t]-128,this.timeByteArraySignedR[t]=this.timeByteArrayR[t]-128,this.tempTimeArrayL[t]=.5*(this.timeByteArraySignedL[t]+this.timeByteArraySignedL[i]),this.tempTimeArrayR[t]=.5*(this.timeByteArraySignedR[t]+this.timeByteArraySignedR[i]),t%2==0&&(this.timeArrayL[e]=this.tempTimeArrayL[t],this.timeArrayR[e]=this.tempTimeArrayR[t],e+=1),i=t;this.freqArray=this.fft.timeToFrequencyDomain(this.timeArray),this.freqArrayL=this.fft.timeToFrequencyDomain(this.timeByteArraySignedL),this.freqArrayR=this.fft.timeToFrequencyDomain(this.timeByteArraySignedR)}},{key:\"connectAudio\",value:function(t){t.connect(this.audible)}},{key:\"disconnectAudio\",value:function(t){t.disconnect(this.audible)}}])&&a(e.prototype,i),s&&a(e,s),t}();function o(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var n=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.audio=e;var i=(this.audio.audioContext?this.audio.audioContext.sampleRate:44100)/this.audio.fftSize,s=Math.clamp(Math.round(20/i)-1,0,this.audio.numSamps-1),r=Math.clamp(Math.round(320/i)-1,0,this.audio.numSamps-1),a=Math.clamp(Math.round(2800/i)-1,0,this.audio.numSamps-1),h=Math.clamp(Math.round(11025/i)-1,0,this.audio.numSamps-1);this.starts=[s,r,a],this.stops=[r,a,h],this.val=new Float32Array(3),this.imm=new Float32Array(3),this.att=new Float32Array(3),this.avg=new Float32Array(3),this.longAvg=new Float32Array(3),this.att.fill(1),this.avg.fill(1),this.longAvg.fill(1)}var e,i,s;return e=t,s=[{key:\"isFiniteNumber\",value:function(t){return Number.isFinite(t)&&!Number.isNaN(t)}},{key:\"adjustRateToFPS\",value:function(t,e,i){return Math.pow(t,e/i)}}],(i=[{key:\"updateAudioLevels\",value:function(e,i){if(this.audio.freqArray.length>0){var s=e;!t.isFiniteNumber(s)||s<15?s=15:s>144&&(s=144),this.imm.fill(0);for(var r=0;r<3;r++)for(var a=this.starts[r];a<this.stops[r];a++)this.imm[r]+=this.audio.freqArray[a];for(var h=0;h<3;h++){var o=void 0;o=this.imm[h]>this.avg[h]?.2:.5,o=t.adjustRateToFPS(o,30,s),this.avg[h]=this.avg[h]*o+this.imm[h]*(1-o),o=i<50?.9:.992,o=t.adjustRateToFPS(o,30,s),this.longAvg[h]=this.longAvg[h]*o+this.imm[h]*(1-o),this.longAvg[h]<.001?(this.val[h]=1,this.att[h]=1):(this.val[h]=this.imm[h]/this.longAvg[h],this.att[h]=this.avg[h]/this.longAvg[h])}}}},{key:\"bass\",get:function(){return this.val[0]}},{key:\"bass_att\",get:function(){return this.att[0]}},{key:\"mid\",get:function(){return this.val[1]}},{key:\"mid_att\",get:function(){return this.att[1]}},{key:\"treb\",get:function(){return this.val[2]}},{key:\"treb_att\",get:function(){return this.att[2]}}])&&o(e.prototype,i),s&&o(e,s),t}(),l=i(0),m=i.n(l);function u(t){return function(t){if(Array.isArray(t)){for(var e=0,i=new Array(t.length);e<t.length;e++)i[e]=t[e];return i}}(t)||function(t){if(Symbol.iterator in Object(t)||\"[object Arguments]\"===Object.prototype.toString.call(t))return Array.from(t)}(t)||function(){throw new TypeError(\"Invalid attempt to spread non-iterable instance\")}()}function g(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var c=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t)}var e,i,s;return e=t,s=[{key:\"atan2\",value:function(t,e){var i=Math.atan2(t,e);return i<0&&(i+=2*Math.PI),i}},{key:\"cloneVars\",value:function(t){return Object.assign({},t)}},{key:\"range\",value:function(t,e){return void 0===e?u(Array(t).keys()):Array.from({length:e-t},function(e,i){return i+t})}},{key:\"pick\",value:function(t,e){for(var i={},s=0;s<e.length;s++){var r=e[s];i[r]=t[r]}return i}},{key:\"omit\",value:function(t,e){for(var i=Object.assign({},t),s=0;s<e.length;s++){delete i[e[s]]}return i}}],(i=null)&&g(e.prototype,i),s&&g(e,s),t}();function A(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var f=function(){function t(e,i,s){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.preset=e,this.texsizeX=s.texsizeX,this.texsizeY=s.texsizeY,this.mesh_width=s.mesh_width,this.mesh_height=s.mesh_height,this.aspectx=s.aspectx,this.aspecty=s.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.qs=c.range(1,33).map(function(t){return\"q\".concat(t)}),this.ts=c.range(1,9).map(function(t){return\"t\".concat(t)}),this.regs=c.range(100).map(function(t){return t<10?\"reg0\".concat(t):\"reg\".concat(t)}),this.initializeEquations(i)}var e,i,s;return e=t,(i=[{key:\"initializeEquations\",value:function(t){this.runVertEQs=\"\"!==this.preset.pixel_eqs,this.mdVSQInit=null,this.mdVSRegs=null,this.mdVSFrame=null,this.mdVSUserKeys=null,this.mdVSFrameMap=null,this.mdVSShapes=null,this.mdVSUserKeysShapes=null,this.mdVSFrameMapShapes=null,this.mdVSWaves=null,this.mdVSUserKeysWaves=null,this.mdVSFrameMapWaves=null,this.mdVSQAfterFrame=null,this.gmegabuf=new Array(1048576).fill(0);var e={frame:t.frame,time:t.time,fps:t.fps,bass:t.bass,bass_att:t.bass_att,mid:t.mid,mid_att:t.mid_att,treb:t.treb,treb_att:t.treb_att,meshx:this.mesh_width,meshy:this.mesh_height,aspectx:this.invAspectx,aspecty:this.invAspecty,pixelsx:this.texsizeX,pixelsy:this.texsizeY,gmegabuf:this.gmegabuf};this.mdVS=Object.assign({},this.preset.baseVals,e),this.mdVS.megabuf=new Array(1048576).fill(0),this.mdVS.rand_start=new Float32Array([Math.random(),Math.random(),Math.random(),Math.random()]),this.mdVS.rand_preset=new Float32Array([Math.random(),Math.random(),Math.random(),Math.random()]);var i=this.qs.concat(this.regs,Object.keys(this.mdVS)),s=this.preset.init_eqs(c.cloneVars(this.mdVS));this.mdVSQInit=c.pick(s,this.qs),this.mdVSRegs=c.pick(s,this.regs);var r=c.pick(s,Object.keys(c.omit(s,i)));if(r.megabuf=s.megabuf,r.gmegabuf=s.gmegabuf,this.mdVSFrame=this.preset.frame_eqs(Object.assign({},this.mdVS,this.mdVSQInit,this.mdVSRegs,r)),this.mdVSUserKeys=Object.keys(c.omit(this.mdVSFrame,i)),this.mdVSFrameMap=c.pick(this.mdVSFrame,this.mdVSUserKeys),this.mdVSQAfterFrame=c.pick(this.mdVSFrame,this.qs),this.mdVSRegs=c.pick(this.mdVSFrame,this.regs),this.mdVSWaves=[],this.mdVSTWaveInits=[],this.mdVSUserKeysWaves=[],this.mdVSFrameMapWaves=[],this.preset.waves&&this.preset.waves.length>0)for(var a=0;a<this.preset.waves.length;a++){var h=this.preset.waves[a],o=h.baseVals;if(0!==o.enabled){var n=Object.assign({},o,e),l=this.qs.concat(this.ts,this.regs,Object.keys(n));Object.assign(n,this.mdVSQAfterFrame,this.mdVSRegs),n.megabuf=new Array(1048576).fill(0),h.init_eqs&&(n=h.init_eqs(n),this.mdVSRegs=c.pick(n,this.regs),Object.assign(n,o)),this.mdVSWaves.push(n),this.mdVSTWaveInits.push(c.pick(n,this.ts)),this.mdVSUserKeysWaves.push(Object.keys(c.omit(n,l))),this.mdVSFrameMapWaves.push(c.pick(n,this.mdVSUserKeysWaves[a]))}else this.mdVSWaves.push({}),this.mdVSTWaveInits.push({}),this.mdVSUserKeysWaves.push([]),this.mdVSFrameMapWaves.push({})}if(this.mdVSShapes=[],this.mdVSTShapeInits=[],this.mdVSUserKeysShapes=[],this.mdVSFrameMapShapes=[],this.preset.shapes&&this.preset.shapes.length>0)for(var m=0;m<this.preset.shapes.length;m++){var u=this.preset.shapes[m],g=u.baseVals;if(0!==g.enabled){var A=Object.assign({},g,e),f=this.qs.concat(this.ts,this.regs,Object.keys(A));Object.assign(A,this.mdVSQAfterFrame,this.mdVSRegs),A.megabuf=new Array(1048576).fill(0),u.init_eqs&&(A=u.init_eqs(A),this.mdVSRegs=c.pick(A,this.regs),Object.assign(A,g)),this.mdVSShapes.push(A),this.mdVSTShapeInits.push(c.pick(A,this.ts)),this.mdVSUserKeysShapes.push(Object.keys(c.omit(A,f))),this.mdVSFrameMapShapes.push(c.pick(A,this.mdVSUserKeysShapes[m]))}else this.mdVSShapes.push({}),this.mdVSTShapeInits.push({}),this.mdVSUserKeysShapes.push([]),this.mdVSFrameMapShapes.push({})}}},{key:\"updatePreset\",value:function(t,e){this.preset=t,this.initializeEquations(e)}},{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty}},{key:\"runFrameEquations\",value:function(t){this.mdVSFrame=Object.assign({},this.mdVS,this.mdVSQInit,this.mdVSFrameMap,t),this.mdVSFrame=this.preset.frame_eqs(this.mdVSFrame),this.mdVSFrameMap=c.pick(this.mdVSFrame,this.mdVSUserKeys),this.mdVSQAfterFrame=c.pick(this.mdVSFrame,this.qs)}}])&&A(e.prototype,i),s&&A(e,s),t}();function d(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var v=/uniform sampler2D sampler_(?:.+?);/g,p=/uniform sampler2D sampler_(.+?);/,_=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t)}var e,i,s;return e=t,s=[{key:\"getShaderParts\",value:function(t){var e=t.indexOf(\"shader_body\");if(t&&e>-1){var i=t.substring(0,e),s=t.substring(e),r=s.indexOf(\"{\"),a=s.lastIndexOf(\"}\");return[i,s.substring(r+1,a)]}return[\"\",t]}},{key:\"getFragmentFloatPrecision\",value:function(t){return t.getShaderPrecisionFormat(t.FRAGMENT_SHADER,t.HIGH_FLOAT).precision>0?\"highp\":t.getShaderPrecisionFormat(t.FRAGMENT_SHADER,t.MEDIUM_FLOAT).precision>0?\"mediump\":\"lowp\"}},{key:\"getUserSamplers\",value:function(t){var e=[],i=t.match(v);if(i&&i.length>0)for(var s=0;s<i.length;s++){var r=i[s].match(p);if(r&&r.length>0){var a=r[1];e.push({sampler:a})}}return e}}],(i=null)&&d(e.prototype,i),s&&d(e,s),t}();function x(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var b=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t)}var e,i,s;return e=t,s=[{key:\"smoothWave\",value:function(t,e,i){for(var s,r=arguments.length>3&&void 0!==arguments[3]&&arguments[3],a=0,h=0,o=1,n=0;n<i-1;n++){s=o,o=Math.min(i-1,n+2);for(var l=0;l<3;l++)e[3*a+l]=t[3*n+l];if(r)for(var m=0;m<3;m++)e[3*(a+1)+m]=.5*(-.15*t[3*h+m]+1.15*t[3*n+m]+1.15*t[3*s+m]+-.15*t[3*o+m]);else{for(var u=0;u<2;u++)e[3*(a+1)+u]=.5*(-.15*t[3*h+u]+1.15*t[3*n+u]+1.15*t[3*s+u]+-.15*t[3*o+u]);e[3*(a+1)+2]=0}h=n,a+=2}for(var g=0;g<3;g++)e[3*a+g]=t[3*(i-1)+g]}},{key:\"smoothWaveAndColor\",value:function(t,e,i,s,r){for(var a,h=arguments.length>5&&void 0!==arguments[5]&&arguments[5],o=0,n=0,l=1,m=0;m<r-1;m++){a=l,l=Math.min(r-1,m+2);for(var u=0;u<3;u++)i[3*o+u]=t[3*m+u];if(h)for(var g=0;g<3;g++)i[3*(o+1)+g]=.5*(-.15*t[3*n+g]+1.15*t[3*m+g]+1.15*t[3*a+g]+-.15*t[3*l+g]);else{for(var c=0;c<2;c++)i[3*(o+1)+c]=.5*(-.15*t[3*n+c]+1.15*t[3*m+c]+1.15*t[3*a+c]+-.15*t[3*l+c]);i[3*(o+1)+2]=0}for(var A=0;A<4;A++)s[4*o+A]=e[4*m+A],s[4*(o+1)+A]=e[4*m+A];n=m,o+=2}for(var f=0;f<3;f++)i[3*o+f]=t[3*(r-1)+f];for(var d=0;d<4;d++)s[4*o+d]=e[4*(r-1)+d]}}],(i=null)&&x(e.prototype,i),s&&x(e,s),t}();function T(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var E=function(){function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e;this.positions=new Float32Array(1536),this.positions2=new Float32Array(1536),this.oldPositions=new Float32Array(1536),this.oldPositions2=new Float32Array(1536),this.smoothedPositions=new Float32Array(3069),this.smoothedPositions2=new Float32Array(3069),this.color=[0,0,0,1],this.texsizeX=i.texsizeX,this.texsizeY=i.texsizeY,this.aspectx=i.aspectx,this.aspecty=i.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader(),this.vertexBuf=this.gl.createBuffer()}var e,i,s;return e=t,s=[{key:\"processWaveform\",value:function(t,e){var i=[],s=e.wave_scale/128,r=e.wave_smoothing,a=s*(1-r);i.push(t[0]*s);for(var h=1;h<t.length;h++)i.push(t[h]*a+i[h-1]*r);return i}}],(i=[{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aPos;\\n                                      uniform vec2 thickOffset;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos + vec3(thickOffset, 0.0), 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      out vec4 fragColor;\\n                                      uniform vec4 u_color;\\n                                      void main(void) {\\n                                        fragColor = u_color;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLoc=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.colorLoc=this.gl.getUniformLocation(this.shaderProgram,\"u_color\"),this.thickOffsetLoc=this.gl.getUniformLocation(this.shaderProgram,\"thickOffset\")}},{key:\"generateWaveform\",value:function(e,i,s,r,a){var h=a.wave_a,o=(a.bass+a.mid+a.treb)/3;if(o>-.01&&h>.001&&s.length>0){var n=t.processWaveform(s,a),l=t.processWaveform(r,a),m=Math.floor(a.wave_mode)%8,u=Math.floor(a.old_wave_mode)%8,g=2*a.wave_x-1,c=2*a.wave_y-1;this.numVert=0,this.oldNumVert=0;for(var A=e&&m!==u?2:1,f=0;f<A;f++){var d=0===f?m:u,v=a.wave_mystery;0!==d&&1!==d&&4!==d||!(v<-1||v>1)||(v=.5*v+.5,v-=Math.floor(v),v=2*(v=Math.abs(v))-1);var p=void 0,_=void 0,x=void 0;if(0===f?(_=this.positions,x=this.positions2):(_=this.oldPositions,x=this.oldPositions2),h=a.wave_a,0===d){if(a.modwavealphabyvolume>0){var T=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/T}h=Math.clamp(h,0,1);for(var E=1/((p=Math.floor(n.length/2)+1)-1),P=Math.floor((n.length-p)/2),R=0;R<p-1;R++){var L=.5+.4*l[R+P]+v,S=R*E*2*Math.PI+.2*a.time;if(R<p/10){var y=R/(.1*p);L=(1-(y=.5-.5*Math.cos(y*Math.PI)))*(.5+.4*l[R+p+P]+v)+L*y}_[3*R+0]=L*Math.cos(S)*this.aspecty+g,_[3*R+1]=L*Math.sin(S)*this.aspectx+c,_[3*R+2]=0}_[3*(p-1)+0]=_[0],_[3*(p-1)+1]=_[1],_[3*(p-1)+2]=0}else if(1===d){if(h*=1.25,a.modwavealphabyvolume>0){var w=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/w}h=Math.clamp(h,0,1),p=Math.floor(n.length/2);for(var U=0;U<p;U++){var M=.53+.43*l[U]+v,F=.5*n[U+32]*Math.PI+2.3*a.time;_[3*U+0]=M*Math.cos(F)*this.aspecty+g,_[3*U+1]=M*Math.sin(F)*this.aspectx+c,_[3*U+2]=0}}else if(2===d){if(this.texsizeX<1024?h*=.09:this.texsizeX>=1024&&this.texsizeX<2048?h*=.11:h*=.13,a.modwavealphabyvolume>0){var q=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/q}h=Math.clamp(h,0,1),p=n.length;for(var z=0;z<n.length;z++)_[3*z+0]=l[z]*this.aspecty+g,_[3*z+1]=n[(z+32)%n.length]*this.aspectx+c,_[3*z+2]=0}else if(3===d){if(this.texsizeX<1024?h*=.15:this.texsizeX>=1024&&this.texsizeX<2048?h*=.22:h*=.33,h*=1.3,h*=a.treb*a.treb,a.modwavealphabyvolume>0){var B=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/B}h=Math.clamp(h,0,1),p=n.length;for(var C=0;C<n.length;C++)_[3*C+0]=l[C]*this.aspecty+g,_[3*C+1]=n[(C+32)%n.length]*this.aspectx+c,_[3*C+2]=0}else if(4===d){if(a.modwavealphabyvolume>0){var D=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/D}h=Math.clamp(h,0,1),(p=n.length)>this.texsizeX/3&&(p=Math.floor(this.texsizeX/3));for(var V=1/p,I=Math.floor((n.length-p)/2),X=.45+.5*(.5*v+.5),k=1-X,N=0;N<p;N++){var O=2*N*V+(g-1)+.44*l[(N+25+I)%n.length],W=.47*n[N+I]+c;N>1&&(O=O*k+X*(2*_[3*(N-1)+0]-_[3*(N-2)+0]),W=W*k+X*(2*_[3*(N-1)+1]-_[3*(N-2)+1])),_[3*N+0]=O,_[3*N+1]=W,_[3*N+2]=0}}else if(5===d){if(this.texsizeX<1024?h*=.09:this.texsizeX>=1024&&this.texsizeX<2048?h*=.11:h*=.13,a.modwavealphabyvolume>0){var Q=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/Q}h=Math.clamp(h,0,1);var Y=Math.cos(.3*a.time),G=Math.sin(.3*a.time);p=n.length;for(var H=0;H<n.length;H++){var j=(H+32)%n.length,K=l[H]*n[j]+n[H]*l[j],J=l[H]*l[H]-n[j]*n[j];_[3*H+0]=(K*Y-J*G)*(this.aspecty+g),_[3*H+1]=(K*G+J*Y)*(this.aspectx+c),_[3*H+2]=0}}else if(6===d||7===d){if(a.modwavealphabyvolume>0){var Z=a.modwavealphaend-a.modwavealphastart;h*=(o-a.modwavealphastart)/Z}h=Math.clamp(h,0,1),(p=Math.floor(n.length/2))>this.texsizeX/3&&(p=Math.floor(this.texsizeX/3));for(var $=Math.floor((n.length-p)/2),tt=.5*Math.PI*v,et=Math.cos(tt),it=Math.sin(tt),st=[g*Math.cos(tt+.5*Math.PI)-3*et,g*Math.cos(tt+.5*Math.PI)+3*et],rt=[g*Math.sin(tt+.5*Math.PI)-3*it,g*Math.sin(tt+.5*Math.PI)+3*it],at=0;at<2;at++)for(var ht=0;ht<4;ht++){var ot=void 0,nt=!1;switch(ht){case 0:st[at]>1.1&&(ot=(1.1-st[1-at])/(st[at]-st[1-at]),nt=!0);break;case 1:st[at]<-1.1&&(ot=(-1.1-st[1-at])/(st[at]-st[1-at]),nt=!0);break;case 2:rt[at]>1.1&&(ot=(1.1-rt[1-at])/(rt[at]-rt[1-at]),nt=!0);break;case 3:rt[at]<-1.1&&(ot=(-1.1-rt[1-at])/(rt[at]-rt[1-at]),nt=!0)}if(nt){var lt=st[at]-st[1-at],mt=rt[at]-rt[1-at];st[at]=st[1-at]+lt*ot,rt[at]=rt[1-at]+mt*ot}}et=(st[1]-st[0])/p,it=(rt[1]-rt[0])/p;var ut=Math.atan2(it,et),gt=Math.cos(ut+.5*Math.PI),ct=Math.sin(ut+.5*Math.PI);if(6===d)for(var At=0;At<p;At++){var ft=n[At+$];_[3*At+0]=st[0]+et*At+.25*gt*ft,_[3*At+1]=rt[0]+it*At+.25*ct*ft,_[3*At+2]=0}else if(7===d){for(var dt=Math.pow(.5*c+.5,2),vt=0;vt<p;vt++){var pt=n[vt+$];_[3*vt+0]=st[0]+et*vt+gt*(.25*pt+dt),_[3*vt+1]=rt[0]+it*vt+ct*(.25*pt+dt),_[3*vt+2]=0}for(var _t=0;_t<p;_t++){var xt=l[_t+$];x[3*_t+0]=st[0]+et*_t+gt*(.25*xt-dt),x[3*_t+1]=rt[0]+it*_t+ct*(.25*xt-dt),x[3*_t+2]=0}}}0===f?(this.positions=_,this.positions2=x,this.numVert=p,this.alpha=h):(this.oldPositions=_,this.oldPositions2=x,this.oldNumVert=p,this.oldAlpha=h)}var bt=.5-.5*Math.cos(i*Math.PI),Tt=1-bt;this.oldNumVert>0&&(h=bt*this.alpha+Tt*this.oldAlpha);var Et=Math.clamp(a.wave_r,0,1),Pt=Math.clamp(a.wave_g,0,1),Rt=Math.clamp(a.wave_b,0,1);if(0!==a.wave_brighten){var Lt=Math.max(Et,Pt,Rt);Lt>.01&&(Et/=Lt,Pt/=Lt,Rt/=Lt)}if(this.color=[Et,Pt,Rt,h],this.oldNumVert>0)if(7===m){for(var St=(this.oldNumVert-1)/(2*this.numVert),yt=0;yt<this.numVert;yt++){var wt=yt*St,Ut=Math.floor(wt),Mt=wt-Ut,Ft=this.oldPositions[3*Ut+0]*(1-Mt)+this.oldPositions[3*(Ut+1)+0]*Mt,qt=this.oldPositions[3*Ut+1]*(1-Mt)+this.oldPositions[3*(Ut+1)+1]*Mt;this.positions[3*yt+0]=this.positions[3*yt+0]*bt+Ft*Tt,this.positions[3*yt+1]=this.positions[3*yt+1]*bt+qt*Tt,this.positions[3*yt+2]=0}for(var zt=0;zt<this.numVert;zt++){var Bt=(zt+this.numVert)*St,Ct=Math.floor(Bt),Dt=Bt-Ct,Vt=this.oldPositions[3*Ct+0]*(1-Dt)+this.oldPositions[3*(Ct+1)+0]*Dt,It=this.oldPositions[3*Ct+1]*(1-Dt)+this.oldPositions[3*(Ct+1)+1]*Dt;this.positions2[3*zt+0]=this.positions2[3*zt+0]*bt+Vt*Tt,this.positions2[3*zt+1]=this.positions2[3*zt+1]*bt+It*Tt,this.positions2[3*zt+2]=0}}else if(7===u){for(var Xt=this.numVert/2,kt=(this.oldNumVert-1)/Xt,Nt=0;Nt<Xt;Nt++){var Ot=Nt*kt,Wt=Math.floor(Ot),Qt=Ot-Wt,Yt=this.oldPositions[3*Wt+0]*(1-Qt)+this.oldPositions[3*(Wt+1)+0]*Qt,Gt=this.oldPositions[3*Wt+1]*(1-Qt)+this.oldPositions[3*(Wt+1)+1]*Qt;this.positions[3*Nt+0]=this.positions[3*Nt+0]*bt+Yt*Tt,this.positions[3*Nt+1]=this.positions[3*Nt+1]*bt+Gt*Tt,this.positions[3*Nt+2]=0}for(var Ht=0;Ht<Xt;Ht++){var jt=Ht*kt,Kt=Math.floor(jt),Jt=jt-Kt,Zt=this.oldPositions2[3*Kt+0]*(1-Jt)+this.oldPositions2[3*(Kt+1)+0]*Jt,$t=this.oldPositions2[3*Kt+1]*(1-Jt)+this.oldPositions2[3*(Kt+1)+1]*Jt;this.positions2[3*Ht+0]=this.positions[3*(Ht+Xt)+0]*bt+Zt*Tt,this.positions2[3*Ht+1]=this.positions[3*(Ht+Xt)+1]*bt+$t*Tt,this.positions2[3*Ht+2]=0}}else for(var te=(this.oldNumVert-1)/this.numVert,ee=0;ee<this.numVert;ee++){var ie=ee*te,se=Math.floor(ie),re=ie-se,ae=this.oldPositions[3*se+0]*(1-re)+this.oldPositions[3*(se+1)+0]*re,he=this.oldPositions[3*se+1]*(1-re)+this.oldPositions[3*(se+1)+1]*re;this.positions[3*ee+0]=this.positions[3*ee+0]*bt+ae*Tt,this.positions[3*ee+1]=this.positions[3*ee+1]*bt+he*Tt,this.positions[3*ee+2]=0}for(var oe=0;oe<this.numVert;oe++)this.positions[3*oe+1]=-this.positions[3*oe+1];if(this.smoothedNumVert=2*this.numVert-1,b.smoothWave(this.positions,this.smoothedPositions,this.numVert),7===m||7===u){for(var ne=0;ne<this.numVert;ne++)this.positions2[3*ne+1]=-this.positions2[3*ne+1];b.smoothWave(this.positions2,this.smoothedPositions2,this.numVert)}return!0}return!1}},{key:\"drawBasicWaveform\",value:function(t,e,i,s,r){if(this.generateWaveform(t,e,i,s,r)){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.smoothedPositions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLoc),this.gl.uniform4fv(this.colorLoc,this.color);var a=1;0===r.wave_thick&&0===r.wave_dots||(a=4),0!==r.additivewave?this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE):this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA);for(var h=0!==r.wave_dots?this.gl.POINTS:this.gl.LINE_STRIP,o=0;o<a;o++){0===o?this.gl.uniform2fv(this.thickOffsetLoc,[0,0]):1===o?this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,0]):2===o?this.gl.uniform2fv(this.thickOffsetLoc,[0,2/this.texsizeY]):3===o&&this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,2/this.texsizeY]),this.gl.drawArrays(h,0,this.smoothedNumVert)}if(7===Math.floor(r.wave_mode)%8){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.smoothedPositions2,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLoc);for(var n=0;n<a;n++){0===n?this.gl.uniform2fv(this.thickOffsetLoc,[0,0]):1===n?this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,0]):2===n?this.gl.uniform2fv(this.thickOffsetLoc,[0,2/this.texsizeY]):3===n&&this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,2/this.texsizeY]),this.gl.drawArrays(h,0,this.smoothedNumVert)}}}}}])&&T(e.prototype,i),s&&T(e,s),t}();function P(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var R=function(){function t(e,i,s){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.index=e,this.gl=i;this.pointsData=[new Float32Array(512),new Float32Array(512)],this.positions=new Float32Array(1536),this.colors=new Float32Array(2048),this.smoothedPositions=new Float32Array(3069),this.smoothedColors=new Float32Array(4092),this.texsizeX=s.texsizeX,this.texsizeY=s.texsizeY,this.mesh_width=s.mesh_width,this.mesh_height=s.mesh_height,this.aspectx=s.aspectx,this.aspecty=s.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.positionVertexBuf=this.gl.createBuffer(),this.colorVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      uniform float uSize;\\n                                      uniform vec2 thickOffset;\\n                                      in vec3 aPos;\\n                                      in vec4 aColor;\\n                                      out vec4 vColor;\\n                                      void main(void) {\\n                                        vColor = aColor;\\n                                        gl_PointSize = uSize;\\n                                        gl_Position = vec4(aPos + vec3(thickOffset, 0.0), 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      in vec4 vColor;\\n                                      out vec4 fragColor;\\n                                      void main(void) {\\n                                        fragColor = vColor;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.aColorLocation=this.gl.getAttribLocation(this.shaderProgram,\"aColor\"),this.sizeLoc=this.gl.getUniformLocation(this.shaderProgram,\"uSize\"),this.thickOffsetLoc=this.gl.getUniformLocation(this.shaderProgram,\"thickOffset\")}},{key:\"generateWaveform\",value:function(t,e,i,s,r,a,h,o){if(0!==h.baseVals.enabled&&t.length>0){var n=Object.assign({},a.mdVSWaves[this.index],a.mdVSFrameMapWaves[this.index],a.mdVSQAfterFrame,a.mdVSTWaveInits[this.index],r),l=h.frame_eqs(n);Object.prototype.hasOwnProperty.call(l,\"samples\")?this.samples=l.samples:this.samples=512,this.samples>512&&(this.samples=512),this.samples=Math.floor(this.samples);var m=Math.floor(l.sep),u=l.scaling,g=l.spectrum,A=l.smoothing,f=l.usedots,d=l.r,v=l.g,p=l.b,_=l.a,x=a.mdVS.wave_scale;if(this.samples-=m,this.samples>=2||0!==f&&this.samples>=1){var T=0!==g,E=(T?.15:.004)*u*x,P=T?i:t,R=T?s:e,L=T?0:Math.floor((512-this.samples)/2-m/2),S=T?0:Math.floor((512-this.samples)/2+m/2),y=T?(512-m)/this.samples:1,w=Math.pow(.98*A,.5),U=1-w;this.pointsData[0][0]=P[L],this.pointsData[1][0]=R[S];for(var M=1;M<this.samples;M++){var F=P[Math.floor(M*y+L)],q=R[Math.floor(M*y+S)];this.pointsData[0][M]=F*U+this.pointsData[0][M-1]*w,this.pointsData[1][M]=q*U+this.pointsData[1][M-1]*w}for(var z=this.samples-2;z>=0;z--)this.pointsData[0][z]=this.pointsData[0][z]*U+this.pointsData[0][z+1]*w,this.pointsData[1][z]=this.pointsData[1][z]*U+this.pointsData[1][z+1]*w;for(var B=0;B<this.samples;B++)this.pointsData[0][B]*=E,this.pointsData[1][B]*=E;for(var C=0;C<this.samples;C++){var D=this.pointsData[0][C],V=this.pointsData[1][C];l.sample=C/(this.samples-1),l.value1=D,l.value2=V,l.x=.5+D,l.y=.5+V,l.r=d,l.g=v,l.b=p,l.a=_,\"\"!==h.point_eqs&&(l=h.point_eqs(l));var I=(2*l.x-1)*this.invAspectx,X=(-2*l.y+1)*this.invAspecty,k=l.r,N=l.g,O=l.b,W=l.a;this.positions[3*C+0]=I,this.positions[3*C+1]=X,this.positions[3*C+2]=0,this.colors[4*C+0]=k,this.colors[4*C+1]=N,this.colors[4*C+2]=O,this.colors[4*C+3]=W*o}var Q=a.mdVSUserKeysWaves[this.index],Y=c.pick(l,Q);return a.mdVSFrameMapWaves[this.index]=Y,this.mdVSWaveFrame=l,0===f&&b.smoothWaveAndColor(this.positions,this.colors,this.smoothedPositions,this.smoothedColors,this.samples),!0}}return!1}},{key:\"drawCustomWaveform\",value:function(t,e,i,s,r,a,h,o){if(o&&this.generateWaveform(e,i,s,r,a,h,o,t)){this.gl.useProgram(this.shaderProgram);var n,l,m,u=0!==this.mdVSWaveFrame.usedots,g=0!==this.mdVSWaveFrame.thick,c=0!==this.mdVSWaveFrame.additive;u?(n=this.positions,l=this.colors,m=this.samples):(n=this.smoothedPositions,l=this.smoothedColors,m=2*this.samples-1),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,n,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.colorVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,l,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aColorLocation);var A=1;u?g?this.gl.uniform1f(this.sizeLoc,2+(this.texsizeX>=1024?1:0)):this.gl.uniform1f(this.sizeLoc,1+(this.texsizeX>=1024?1:0)):(this.gl.uniform1f(this.sizeLoc,1),g&&(A=4)),c?this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE):this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA);for(var f=u?this.gl.POINTS:this.gl.LINE_STRIP,d=0;d<A;d++){0===d?this.gl.uniform2fv(this.thickOffsetLoc,[0,0]):1===d?this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,0]):2===d?this.gl.uniform2fv(this.thickOffsetLoc,[0,2/this.texsizeY]):3===d&&this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,2/this.texsizeY]),this.gl.drawArrays(f,0,m)}}}}])&&P(e.prototype,i),s&&P(e,s),t}();function L(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var S=function(){function t(e,i,s){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.index=e,this.gl=i;this.positions=new Float32Array(309),this.colors=new Float32Array(412),this.uvs=new Float32Array(206),this.borderPositions=new Float32Array(306),this.texsizeX=s.texsizeX,this.texsizeY=s.texsizeY,this.mesh_width=s.mesh_width,this.mesh_height=s.mesh_height,this.aspectx=s.aspectx,this.aspecty=s.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.positionVertexBuf=this.gl.createBuffer(),this.colorVertexBuf=this.gl.createBuffer(),this.uvVertexBuf=this.gl.createBuffer(),this.borderPositionVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader(),this.createBorderShader(),this.mainSampler=this.gl.createSampler(),i.samplerParameteri(this.mainSampler,i.TEXTURE_MIN_FILTER,i.LINEAR_MIPMAP_LINEAR),i.samplerParameteri(this.mainSampler,i.TEXTURE_MAG_FILTER,i.LINEAR),i.samplerParameteri(this.mainSampler,i.TEXTURE_WRAP_S,i.REPEAT),i.samplerParameteri(this.mainSampler,i.TEXTURE_WRAP_T,i.REPEAT)}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aPos;\\n                                      in vec4 aColor;\\n                                      in vec2 aUv;\\n                                      out vec4 vColor;\\n                                      out vec2 vUv;\\n                                      void main(void) {\\n                                        vColor = aColor;\\n                                        vUv = aUv;\\n                                        gl_Position = vec4(aPos, 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      uniform sampler2D uTexture;\\n                                      uniform float uTextured;\\n                                      in vec4 vColor;\\n                                      in vec2 vUv;\\n                                      out vec4 fragColor;\\n                                      void main(void) {\\n                                        if (uTextured != 0.0) {\\n                                          fragColor = texture(uTexture, vUv) * vColor;\\n                                        } else {\\n                                          fragColor = vColor;\\n                                        }\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.aColorLocation=this.gl.getAttribLocation(this.shaderProgram,\"aColor\"),this.aUvLocation=this.gl.getAttribLocation(this.shaderProgram,\"aUv\"),this.texturedLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTextured\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\")}},{key:\"createBorderShader\",value:function(){this.borderShaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aBorderPos;\\n                                      uniform vec2 thickOffset;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aBorderPos +\\n                                                           vec3(thickOffset, 0.0), 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      out vec4 fragColor;\\n                                      uniform vec4 uBorderColor;\\n                                      void main(void) {\\n                                        fragColor = uBorderColor;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.borderShaderProgram,t),this.gl.attachShader(this.borderShaderProgram,e),this.gl.linkProgram(this.borderShaderProgram),this.aBorderPosLoc=this.gl.getAttribLocation(this.borderShaderProgram,\"aBorderPos\"),this.uBorderColorLoc=this.gl.getUniformLocation(this.borderShaderProgram,\"uBorderColor\"),this.thickOffsetLoc=this.gl.getUniformLocation(this.shaderProgram,\"thickOffset\")}},{key:\"drawCustomShape\",value:function(t,e,i,s,r){if(0!==s.baseVals.enabled){this.setupShapeBuffers(i.mdVSFrame);for(var a=Object.assign({},i.mdVSShapes[this.index],i.mdVSFrameMapShapes[this.index],i.mdVSQAfterFrame,i.mdVSTShapeInits[this.index],e),h=c.cloneVars(a),o=Math.clamp(a.num_inst,1,1024),n=0;n<o;n++){a.instance=n,a.x=h.x,a.y=h.y,a.rad=h.rad,a.ang=h.ang,a.r=h.r,a.g=h.g,a.b=h.b,a.a=h.a,a.r2=h.r2,a.g2=h.g2,a.b2=h.b2,a.a2=h.a2,a.border_r=h.border_r,a.border_g=h.border_g,a.border_b=h.border_b,a.border_a=h.border_a,a.thickoutline=h.thickoutline,a.textured=h.textured,a.tex_zoom=h.tex_zoom,a.tex_ang=h.tex_ang,a.additive=h.additive;var l=s.frame_eqs(a),m=l.sides;m=Math.clamp(m,3,100),m=Math.floor(m);var u=l.rad,g=l.ang,A=2*l.x-1,f=-2*l.y+1,d=l.r,v=l.g,p=l.b,_=l.a,x=l.r2,b=l.g2,T=l.b2,E=l.a2,P=l.border_r,R=l.border_g,L=l.border_b,S=l.border_a;this.borderColor=[P,R,L,S*t];var y=l.thickoutline,w=l.textured,U=l.tex_zoom,M=l.tex_ang,F=l.additive,q=this.borderColor[3]>0,z=Math.abs(w)>=1,B=Math.abs(y)>=1,C=Math.abs(F)>=1;this.positions[0]=A,this.positions[1]=f,this.positions[2]=0,this.colors[0]=d,this.colors[1]=v,this.colors[2]=p,this.colors[3]=_*t,z&&(this.uvs[0]=.5,this.uvs[1]=.5);for(var D=.25*Math.PI,V=1;V<=m+1;V++){var I=2*((V-1)/m)*Math.PI,X=I+g+D;if(this.positions[3*V+0]=A+u*Math.cos(X)*this.aspecty,this.positions[3*V+1]=f+u*Math.sin(X),this.positions[3*V+2]=0,this.colors[4*V+0]=x,this.colors[4*V+1]=b,this.colors[4*V+2]=T,this.colors[4*V+3]=E*t,z){var k=I+M+D;this.uvs[2*V+0]=.5+.5*Math.cos(k)/U*this.aspecty,this.uvs[2*V+1]=.5+.5*Math.sin(k)/U}q&&(this.borderPositions[3*(V-1)+0]=this.positions[3*V+0],this.borderPositions[3*(V-1)+1]=this.positions[3*V+1],this.borderPositions[3*(V-1)+2]=this.positions[3*V+2])}this.mdVSShapeFrame=l,this.drawCustomShapeInstance(r,m,z,q,B,C)}var N=i.mdVSUserKeysShapes[this.index],O=c.pick(this.mdVSShapeFrame,N);i.mdVSFrameMapShapes[this.index]=O}}},{key:\"setupShapeBuffers\",value:function(t){this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.DYNAMIC_DRAW),this.gl.vertexAttribPointer(this.aPosLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.colorVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.colors,this.gl.DYNAMIC_DRAW),this.gl.vertexAttribPointer(this.aColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aColorLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.uvVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.uvs,this.gl.DYNAMIC_DRAW),this.gl.vertexAttribPointer(this.aUvLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aUvLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.borderPositionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.borderPositions,this.gl.DYNAMIC_DRAW),this.gl.vertexAttribPointer(this.aBorderPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aBorderPosLoc);var e=0!==t.wrap?this.gl.REPEAT:this.gl.CLAMP_TO_EDGE;this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_S,e),this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_T,e)}},{key:\"drawCustomShapeInstance\",value:function(t,e,i,s,r,a){this.gl.useProgram(this.shaderProgram);var h=new Float32Array(this.positions.buffer,0,3*(e+2));this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,h),this.gl.vertexAttribPointer(this.aPosLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLocation);var o=new Float32Array(this.colors.buffer,0,4*(e+2));if(this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.colorVertexBuf),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,o),this.gl.vertexAttribPointer(this.aColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aColorLocation),i){var n=new Float32Array(this.uvs.buffer,0,2*(e+2));this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.uvVertexBuf),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,n),this.gl.vertexAttribPointer(this.aUvLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aUvLocation)}if(this.gl.uniform1f(this.texturedLoc,i?1:0),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.bindSampler(0,this.mainSampler),this.gl.uniform1i(this.textureLoc,0),a?this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE):this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_FAN,0,e+2),s){this.gl.useProgram(this.borderShaderProgram);var l=new Float32Array(this.borderPositions.buffer,0,3*(e+1));this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.borderPositionVertexBuf),this.gl.bufferSubData(this.gl.ARRAY_BUFFER,0,l),this.gl.vertexAttribPointer(this.aBorderPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aBorderPosLoc),this.gl.uniform4fv(this.uBorderColorLoc,this.borderColor);for(var m=r?4:1,u=0;u<m;u++){0===u?this.gl.uniform2fv(this.thickOffsetLoc,[0,0]):1===u?this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,0]):2===u?this.gl.uniform2fv(this.thickOffsetLoc,[0,2/this.texsizeY]):3===u&&this.gl.uniform2fv(this.thickOffsetLoc,[2/this.texsizeX,2/this.texsizeY]),this.gl.drawArrays(this.gl.LINE_STRIP,0,e+1)}}}}])&&L(e.prototype,i),s&&L(e,s),t}();function y(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var w=function(){function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.positions=new Float32Array(72),this.aspectx=i.aspectx,this.aspecty=i.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader(),this.vertexBuf=this.gl.createBuffer()}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aPos;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      out vec4 fragColor;\\n                                      uniform vec4 u_color;\\n                                      void main(void) {\\n                                        fragColor = u_color;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLoc=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.colorLoc=this.gl.getUniformLocation(this.shaderProgram,\"u_color\")}},{key:\"addTriangle\",value:function(t,e,i,s){this.positions[t+0]=e[0],this.positions[t+1]=e[1],this.positions[t+2]=e[2],this.positions[t+3]=i[0],this.positions[t+4]=i[1],this.positions[t+5]=i[2],this.positions[t+6]=s[0],this.positions[t+7]=s[1],this.positions[t+8]=s[2]}},{key:\"generateBorder\",value:function(t,e,i){if(e>0&&t[3]>0){var s=i/2,r=e/2+s,a=2*s,h=2*s,o=2*r,n=2*r,l=[-1+a,-1+n,0],m=[-1+a,1-n,0],u=[-1+o,1-n,0],g=[-1+o,-1+n,0];return this.addTriangle(0,g,m,l),this.addTriangle(9,g,u,m),l=[1-a,-1+n,0],m=[1-a,1-n,0],u=[1-o,1-n,0],g=[1-o,-1+n,0],this.addTriangle(18,l,m,g),this.addTriangle(27,m,u,g),l=[-1+a,-1+h,0],m=[-1+a,n-1,0],u=[1-a,n-1,0],g=[1-a,-1+h,0],this.addTriangle(36,g,m,l),this.addTriangle(45,g,u,m),l=[-1+a,1-h,0],m=[-1+a,1-n,0],u=[1-a,1-n,0],g=[1-a,1-h,0],this.addTriangle(54,l,m,g),this.addTriangle(63,m,u,g),!0}return!1}},{key:\"drawBorder\",value:function(t,e,i){this.generateBorder(t,e,i)&&(this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLoc),this.gl.uniform4fv(this.colorLoc,t),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLES,0,this.positions.length/3))}}])&&y(e.prototype,i),s&&y(e,s),t}();function U(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var M=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.aspectx=i.aspectx,this.aspecty=i.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.generatePositions(),this.colors=new Float32Array([0,0,0,3/32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]),this.positionVertexBuf=this.gl.createBuffer(),this.colorVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.generatePositions()}},{key:\"generatePositions\",value:function(){this.positions=new Float32Array([0,0,0,-.05*this.aspecty,0,0,0,-.05,0,.05*this.aspecty,0,0,0,.05,0,-.05*this.aspecty,0,0])}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aPos;\\n                                      in vec4 aColor;\\n                                      out vec4 vColor;\\n                                      void main(void) {\\n                                        vColor = aColor;\\n                                        gl_Position = vec4(aPos, 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      in vec4 vColor;\\n                                      out vec4 fragColor;\\n                                      void main(void) {\\n                                        fragColor = vColor;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.aColorLocation=this.gl.getAttribLocation(this.shaderProgram,\"aColor\")}},{key:\"drawDarkenCenter\",value:function(t){0!==t.darken_center&&(this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.colorVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.colors,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aColorLocation),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_FAN,0,this.positions.length/3))}}])&&U(e.prototype,i),s&&U(e,s),t}();function F(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var q=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.maxX=64,this.maxY=48,this.positions=new Float32Array(this.maxX*this.maxY*2*3),this.texsizeX=i.texsizeX,this.texsizeY=i.texsizeY,this.mesh_width=i.mesh_width,this.mesh_height=i.mesh_height,this.positionVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      in vec3 aPos;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 1.0);\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      out vec4 fragColor;\\n                                      uniform vec4 u_color;\\n                                      void main(void) {\\n                                        fragColor = u_color;\\n                                      }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.aPosLoc=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.colorLoc=this.gl.getUniformLocation(this.shaderProgram,\"u_color\")}},{key:\"getMotionDir\",value:function(t,e,i){var s,r,a=Math.floor(i*this.mesh_height),h=i*this.mesh_height-a,o=Math.floor(e*this.mesh_width),n=e*this.mesh_width-o,l=o+1,m=a+1,u=this.mesh_width+1;return s=t[2*(a*u+o)+0]*(1-n)*(1-h),r=t[2*(a*u+o)+1]*(1-n)*(1-h),s+=t[2*(a*u+l)+0]*n*(1-h),r+=t[2*(a*u+l)+1]*n*(1-h),s+=t[2*(m*u+o)+0]*(1-n)*h,r+=t[2*(m*u+o)+1]*(1-n)*h,[s+=t[2*(m*u+l)+0]*n*h,1-(r+=t[2*(m*u+l)+1]*n*h)]}},{key:\"generateMotionVectors\",value:function(t,e){var i=t.mv_a,s=Math.floor(t.mv_x),r=Math.floor(t.mv_y);if(i>.001&&s>0&&r>0){var a=t.mv_x-s,h=t.mv_y-r;s>this.maxX&&(s=this.maxX,a=0),r>this.maxY&&(r=this.maxY,h=0);var o=t.mv_dx,n=t.mv_dy,l=t.mv_l,m=1/this.texsizeX;this.numVecVerts=0;for(var u=0;u<r;u++){var g=(u+.25)/(r+h+.25-1);if((g-=n)>1e-4&&g<.9999)for(var c=0;c<s;c++){var A=(c+.25)/(s+a+.25-1);if((A+=o)>1e-4&&A<.9999){var f=this.getMotionDir(e,A,g),d=f[0],v=f[1],p=d-A,_=v-g;p*=l,_*=l;var x=Math.sqrt(p*p+_*_);x<m&&x>1e-8?(p*=x=m/x,_*=x):(p=m,p=m);var b=2*A-1,T=2*g-1,E=2*(d=A+p)-1,P=2*(v=g+_)-1;this.positions[3*this.numVecVerts+0]=b,this.positions[3*this.numVecVerts+1]=T,this.positions[3*this.numVecVerts+2]=0,this.positions[3*(this.numVecVerts+1)+0]=E,this.positions[3*(this.numVecVerts+1)+1]=P,this.positions[3*(this.numVecVerts+1)+2]=0,this.numVecVerts+=2}}}if(this.numVecVerts>0)return this.color=[t.mv_r,t.mv_g,t.mv_b,i],!0}return!1}},{key:\"drawMotionVectors\",value:function(t,e){this.generateMotionVectors(t,e)&&(this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.aPosLoc,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.aPosLoc),this.gl.uniform4fv(this.colorLoc,this.color),this.gl.lineWidth(1),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.LINES,0,this.numVecVerts))}}])&&F(e.prototype,i),s&&F(e,s),t}();function z(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var B=function(){function t(e,i,s){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.noise=i,this.image=s,this.texsizeX=r.texsizeX,this.texsizeY=r.texsizeY,this.mesh_width=r.mesh_width,this.mesh_height=r.mesh_height,this.aspectx=r.aspectx,this.aspecty=r.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.buildPositions(),this.indexBuf=e.createBuffer(),this.positionVertexBuf=this.gl.createBuffer(),this.warpUvVertexBuf=this.gl.createBuffer(),this.warpColorVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader(),this.mainSampler=this.gl.createSampler(),this.mainSamplerFW=this.gl.createSampler(),this.mainSamplerFC=this.gl.createSampler(),this.mainSamplerPW=this.gl.createSampler(),this.mainSamplerPC=this.gl.createSampler(),e.samplerParameteri(this.mainSampler,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSampler,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSampler,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSampler,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_MIN_FILTER,e.NEAREST_MIPMAP_NEAREST),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_MAG_FILTER,e.NEAREST),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_MIN_FILTER,e.NEAREST_MIPMAP_NEAREST),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_MAG_FILTER,e.NEAREST),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)}var e,i,s;return e=t,(i=[{key:\"buildPositions\",value:function(){for(var t=this.mesh_width,e=this.mesh_height,i=t+1,s=e+1,r=2/t,a=2/e,h=[],o=0;o<s;o++)for(var n=o*a-1,l=0;l<i;l++){var m=l*r-1;h.push(m,-n,0)}for(var u=[],g=0;g<e;g++)for(var c=0;c<t;c++){var A=c+i*g,f=c+i*(g+1),d=c+1+i*(g+1),v=c+1+i*g;u.push(A,f,v),u.push(f,d,v)}this.vertices=new Float32Array(h),this.indices=new Uint16Array(u)}},{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.buildPositions()}},{key:\"createShader\",value:function(){var t,e,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"\";if(0===i.length)t=\"ret = texture(sampler_main, uv).rgb * decay;\",e=\"\";else{var s=_.getShaderParts(i);e=s[0],t=s[1]}t=(t=t.replace(/texture2D/g,\"texture\")).replace(/texture3D/g,\"texture\"),this.userTextures=_.getUserSamplers(e),this.shaderProgram=this.gl.createProgram();var r=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(r,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      const vec2 halfmad = vec2(0.5);\\n                                      in vec2 aPos;\\n                                      in vec2 aWarpUv;\\n                                      in vec4 aWarpColor;\\n                                      out vec2 uv;\\n                                      out vec2 uv_orig;\\n                                      out vec4 vColor;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 0.0, 1.0);\\n                                        uv_orig = aPos * halfmad + halfmad;\\n                                        uv = aWarpUv;\\n                                        vColor = aWarpColor;\\n                                      }\")),this.gl.compileShader(r);var a=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(a,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      precision mediump sampler3D;\\n\\n                                      in vec2 uv;\\n                                      in vec2 uv_orig;\\n                                      in vec4 vColor;\\n                                      out vec4 fragColor;\\n                                      uniform sampler2D sampler_main;\\n                                      uniform sampler2D sampler_fw_main;\\n                                      uniform sampler2D sampler_fc_main;\\n                                      uniform sampler2D sampler_pw_main;\\n                                      uniform sampler2D sampler_pc_main;\\n                                      uniform sampler2D sampler_blur1;\\n                                      uniform sampler2D sampler_blur2;\\n                                      uniform sampler2D sampler_blur3;\\n                                      uniform sampler2D sampler_noise_lq;\\n                                      uniform sampler2D sampler_noise_lq_lite;\\n                                      uniform sampler2D sampler_noise_mq;\\n                                      uniform sampler2D sampler_noise_hq;\\n                                      uniform sampler2D sampler_pw_noise_lq;\\n                                      uniform sampler3D sampler_noisevol_lq;\\n                                      uniform sampler3D sampler_noisevol_hq;\\n                                      uniform float time;\\n                                      uniform float decay;\\n                                      uniform vec2 resolution;\\n                                      uniform vec4 aspect;\\n                                      uniform vec4 texsize;\\n                                      uniform vec4 texsize_noise_lq;\\n                                      uniform vec4 texsize_noise_mq;\\n                                      uniform vec4 texsize_noise_hq;\\n                                      uniform vec4 texsize_noise_lq_lite;\\n                                      uniform vec4 texsize_noisevol_lq;\\n                                      uniform vec4 texsize_noisevol_hq;\\n\\n                                      uniform float bass;\\n                                      uniform float mid;\\n                                      uniform float treb;\\n                                      uniform float vol;\\n                                      uniform float bass_att;\\n                                      uniform float mid_att;\\n                                      uniform float treb_att;\\n                                      uniform float vol_att;\\n\\n                                      uniform float frame;\\n                                      uniform float fps;\\n\\n                                      uniform vec4 _qa;\\n                                      uniform vec4 _qb;\\n                                      uniform vec4 _qc;\\n                                      uniform vec4 _qd;\\n                                      uniform vec4 _qe;\\n                                      uniform vec4 _qf;\\n                                      uniform vec4 _qg;\\n                                      uniform vec4 _qh;\\n\\n                                      #define q1 _qa.x\\n                                      #define q2 _qa.y\\n                                      #define q3 _qa.z\\n                                      #define q4 _qa.w\\n                                      #define q5 _qb.x\\n                                      #define q6 _qb.y\\n                                      #define q7 _qb.z\\n                                      #define q8 _qb.w\\n                                      #define q9 _qc.x\\n                                      #define q10 _qc.y\\n                                      #define q11 _qc.z\\n                                      #define q12 _qc.w\\n                                      #define q13 _qd.x\\n                                      #define q14 _qd.y\\n                                      #define q15 _qd.z\\n                                      #define q16 _qd.w\\n                                      #define q17 _qe.x\\n                                      #define q18 _qe.y\\n                                      #define q19 _qe.z\\n                                      #define q20 _qe.w\\n                                      #define q21 _qf.x\\n                                      #define q22 _qf.y\\n                                      #define q23 _qf.z\\n                                      #define q24 _qf.w\\n                                      #define q25 _qg.x\\n                                      #define q26 _qg.y\\n                                      #define q27 _qg.z\\n                                      #define q28 _qg.w\\n                                      #define q29 _qh.x\\n                                      #define q30 _qh.y\\n                                      #define q31 _qh.z\\n                                      #define q32 _qh.w\\n\\n                                      uniform vec4 slow_roam_cos;\\n                                      uniform vec4 roam_cos;\\n                                      uniform vec4 slow_roam_sin;\\n                                      uniform vec4 roam_sin;\\n\\n                                      uniform float blur1_min;\\n                                      uniform float blur1_max;\\n                                      uniform float blur2_min;\\n                                      uniform float blur2_max;\\n                                      uniform float blur3_min;\\n                                      uniform float blur3_max;\\n\\n                                      uniform float scale1;\\n                                      uniform float scale2;\\n                                      uniform float scale3;\\n                                      uniform float bias1;\\n                                      uniform float bias2;\\n                                      uniform float bias3;\\n\\n                                      uniform vec4 rand_frame;\\n                                      uniform vec4 rand_preset;\\n\\n                                      float PI = \").concat(Math.PI,\";\\n\\n                                      \").concat(e,\"\\n\\n                                      void main(void) {\\n                                        vec3 ret;\\n                                        float rad = length(uv_orig - 0.5);\\n                                        float ang = atan(uv_orig.x - 0.5, uv_orig.y - 0.5);\\n\\n                                        \").concat(t,\"\\n\\n                                        fragColor = vec4(ret, 1.0) * vColor;\\n                                      }\")),this.gl.compileShader(a),this.gl.attachShader(this.shaderProgram,r),this.gl.attachShader(this.shaderProgram,a),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.warpUvLocation=this.gl.getAttribLocation(this.shaderProgram,\"aWarpUv\"),this.warpColorLocation=this.gl.getAttribLocation(this.shaderProgram,\"aWarpColor\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_main\"),this.textureFWLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_fw_main\"),this.textureFCLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_fc_main\"),this.texturePWLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pw_main\"),this.texturePCLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pc_main\"),this.blurTexture1Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur1\"),this.blurTexture2Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur2\"),this.blurTexture3Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur3\"),this.noiseLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_lq\"),this.noiseMQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_mq\"),this.noiseHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_hq\"),this.noiseLQLiteLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_lq_lite\"),this.noisePointLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pw_noise_lq\"),this.noiseVolLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noisevol_lq\"),this.noiseVolHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noisevol_hq\"),this.decayLoc=this.gl.getUniformLocation(this.shaderProgram,\"decay\"),this.texsizeLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize\"),this.texsizeNoiseLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_lq\"),this.texsizeNoiseMQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_mq\"),this.texsizeNoiseHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_hq\"),this.texsizeNoiseLQLiteLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_lq_lite\"),this.texsizeNoiseVolLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noisevol_lq\"),this.texsizeNoiseVolHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noisevol_hq\"),this.resolutionLoc=this.gl.getUniformLocation(this.shaderProgram,\"resolution\"),this.aspectLoc=this.gl.getUniformLocation(this.shaderProgram,\"aspect\"),this.bassLoc=this.gl.getUniformLocation(this.shaderProgram,\"bass\"),this.midLoc=this.gl.getUniformLocation(this.shaderProgram,\"mid\"),this.trebLoc=this.gl.getUniformLocation(this.shaderProgram,\"treb\"),this.volLoc=this.gl.getUniformLocation(this.shaderProgram,\"vol\"),this.bassAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"bass_att\"),this.midAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"mid_att\"),this.trebAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"treb_att\"),this.volAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"vol_att\"),this.timeLoc=this.gl.getUniformLocation(this.shaderProgram,\"time\"),this.frameLoc=this.gl.getUniformLocation(this.shaderProgram,\"frame\"),this.fpsLoc=this.gl.getUniformLocation(this.shaderProgram,\"fps\"),this.blur1MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur1_min\"),this.blur1MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur1_max\"),this.blur2MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur2_min\"),this.blur2MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur2_max\"),this.blur3MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur3_min\"),this.blur3MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur3_max\"),this.scale1Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale1\"),this.scale2Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale2\"),this.scale3Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale3\"),this.bias1Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias1\"),this.bias2Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias2\"),this.bias3Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias3\"),this.randPresetLoc=this.gl.getUniformLocation(this.shaderProgram,\"rand_preset\"),this.randFrameLoc=this.gl.getUniformLocation(this.shaderProgram,\"rand_frame\"),this.qaLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qa\"),this.qbLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qb\"),this.qcLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qc\"),this.qdLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qd\"),this.qeLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qe\"),this.qfLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qf\"),this.qgLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qg\"),this.qhLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qh\"),this.slowRoamCosLoc=this.gl.getUniformLocation(this.shaderProgram,\"slow_roam_cos\"),this.roamCosLoc=this.gl.getUniformLocation(this.shaderProgram,\"roam_cos\"),this.slowRoamSinLoc=this.gl.getUniformLocation(this.shaderProgram,\"slow_roam_sin\"),this.roamSinLoc=this.gl.getUniformLocation(this.shaderProgram,\"roam_sin\");for(var h=0;h<this.userTextures.length;h++){var o=this.userTextures[h];o.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_\".concat(o.sampler))}}},{key:\"updateShader\",value:function(t){this.createShader(t)}},{key:\"bindBlurVals\",value:function(t,e){var i=t[0],s=t[1],r=t[2],a=e[0],h=e[1],o=e[2],n=a-i,l=i,m=h-s,u=s,g=o-r,c=r;this.gl.uniform1f(this.blur1MinLoc,i),this.gl.uniform1f(this.blur1MaxLoc,a),this.gl.uniform1f(this.blur2MinLoc,s),this.gl.uniform1f(this.blur2MaxLoc,h),this.gl.uniform1f(this.blur3MinLoc,r),this.gl.uniform1f(this.blur3MaxLoc,o),this.gl.uniform1f(this.scale1Loc,n),this.gl.uniform1f(this.scale2Loc,m),this.gl.uniform1f(this.scale3Loc,g),this.gl.uniform1f(this.bias1Loc,l),this.gl.uniform1f(this.bias2Loc,u),this.gl.uniform1f(this.bias3Loc,c)}},{key:\"renderQuadTexture\",value:function(t,e,i,s,r,a,h,o,n,l){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuf),this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.indices,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertices,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.warpUvVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,n,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.warpUvLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.warpUvLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.warpColorVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,l,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.warpColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.warpColorLocation);var m=0!==o.wrap?this.gl.REPEAT:this.gl.CLAMP_TO_EDGE;this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_S,m),this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_T,m),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(0,this.mainSampler),this.gl.uniform1i(this.textureLoc,0),this.gl.activeTexture(this.gl.TEXTURE1),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(1,this.mainSamplerFW),this.gl.uniform1i(this.textureFWLoc,1),this.gl.activeTexture(this.gl.TEXTURE2),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(2,this.mainSamplerFC),this.gl.uniform1i(this.textureFCLoc,2),this.gl.activeTexture(this.gl.TEXTURE3),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(3,this.mainSamplerPW),this.gl.uniform1i(this.texturePWLoc,3),this.gl.activeTexture(this.gl.TEXTURE4),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(4,this.mainSamplerPC),this.gl.uniform1i(this.texturePCLoc,4),this.gl.activeTexture(this.gl.TEXTURE5),this.gl.bindTexture(this.gl.TEXTURE_2D,i),this.gl.uniform1i(this.blurTexture1Loc,5),this.gl.activeTexture(this.gl.TEXTURE6),this.gl.bindTexture(this.gl.TEXTURE_2D,s),this.gl.uniform1i(this.blurTexture2Loc,6),this.gl.activeTexture(this.gl.TEXTURE7),this.gl.bindTexture(this.gl.TEXTURE_2D,r),this.gl.uniform1i(this.blurTexture3Loc,7),this.gl.activeTexture(this.gl.TEXTURE8),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQ),this.gl.uniform1i(this.noiseLQLoc,8),this.gl.activeTexture(this.gl.TEXTURE9),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexMQ),this.gl.uniform1i(this.noiseMQLoc,9),this.gl.activeTexture(this.gl.TEXTURE10),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexHQ),this.gl.uniform1i(this.noiseHQLoc,10),this.gl.activeTexture(this.gl.TEXTURE11),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQLite),this.gl.uniform1i(this.noiseLQLiteLoc,11),this.gl.activeTexture(this.gl.TEXTURE12),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQ),this.gl.bindSampler(12,this.noise.noiseTexPointLQ),this.gl.uniform1i(this.noisePointLQLoc,12),this.gl.activeTexture(this.gl.TEXTURE13),this.gl.bindTexture(this.gl.TEXTURE_3D,this.noise.noiseTexVolLQ),this.gl.uniform1i(this.noiseVolLQLoc,13),this.gl.activeTexture(this.gl.TEXTURE14),this.gl.bindTexture(this.gl.TEXTURE_3D,this.noise.noiseTexVolHQ),this.gl.uniform1i(this.noiseVolHQLoc,14);for(var u=0;u<this.userTextures.length;u++){var g=this.userTextures[u];this.gl.activeTexture(this.gl.TEXTURE15+u),this.gl.bindTexture(this.gl.TEXTURE_2D,this.image.getTexture(g.sampler)),this.gl.uniform1i(g.textureLoc,15+u)}this.gl.uniform1f(this.decayLoc,o.decay),this.gl.uniform2fv(this.resolutionLoc,[this.texsizeX,this.texsizeY]),this.gl.uniform4fv(this.aspectLoc,[this.aspectx,this.aspecty,this.invAspectx,this.invAspecty]),this.gl.uniform4fv(this.texsizeLoc,[this.texsizeX,this.texsizeY,1/this.texsizeX,1/this.texsizeY]),this.gl.uniform4fv(this.texsizeNoiseLQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseMQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseHQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseLQLiteLoc,[32,32,1/32,1/32]),this.gl.uniform4fv(this.texsizeNoiseVolLQLoc,[32,32,1/32,1/32]),this.gl.uniform4fv(this.texsizeNoiseVolHQLoc,[32,32,1/32,1/32]),this.gl.uniform1f(this.bassLoc,o.bass),this.gl.uniform1f(this.midLoc,o.mid),this.gl.uniform1f(this.trebLoc,o.treb),this.gl.uniform1f(this.volLoc,(o.bass+o.mid+o.treb)/3),this.gl.uniform1f(this.bassAttLoc,o.bass_att),this.gl.uniform1f(this.midAttLoc,o.mid_att),this.gl.uniform1f(this.trebAttLoc,o.treb_att),this.gl.uniform1f(this.volAttLoc,(o.bass_att+o.mid_att+o.treb_att)/3),this.gl.uniform1f(this.timeLoc,o.time),this.gl.uniform1f(this.frameLoc,o.frame),this.gl.uniform1f(this.fpsLoc,o.fps),this.gl.uniform4fv(this.randPresetLoc,o.rand_preset),this.gl.uniform4fv(this.randFrameLoc,new Float32Array([Math.random(),Math.random(),Math.random(),Math.random()])),this.gl.uniform4fv(this.qaLoc,new Float32Array([o.q1||0,o.q2||0,o.q3||0,o.q4||0])),this.gl.uniform4fv(this.qbLoc,new Float32Array([o.q5||0,o.q6||0,o.q7||0,o.q8||0])),this.gl.uniform4fv(this.qcLoc,new Float32Array([o.q9||0,o.q10||0,o.q11||0,o.q12||0])),this.gl.uniform4fv(this.qdLoc,new Float32Array([o.q13||0,o.q14||0,o.q15||0,o.q16||0])),this.gl.uniform4fv(this.qeLoc,new Float32Array([o.q17||0,o.q18||0,o.q19||0,o.q20||0])),this.gl.uniform4fv(this.qfLoc,new Float32Array([o.q21||0,o.q22||0,o.q23||0,o.q24||0])),this.gl.uniform4fv(this.qgLoc,new Float32Array([o.q25||0,o.q26||0,o.q27||0,o.q28||0])),this.gl.uniform4fv(this.qhLoc,new Float32Array([o.q29||0,o.q30||0,o.q31||0,o.q32||0])),this.gl.uniform4fv(this.slowRoamCosLoc,[.5+.5*Math.cos(.005*o.time),.5+.5*Math.cos(.008*o.time),.5+.5*Math.cos(.013*o.time),.5+.5*Math.cos(.022*o.time)]),this.gl.uniform4fv(this.roamCosLoc,[.5+.5*Math.cos(.3*o.time),.5+.5*Math.cos(1.3*o.time),.5+.5*Math.cos(5*o.time),.5+.5*Math.cos(20*o.time)]),this.gl.uniform4fv(this.slowRoamSinLoc,[.5+.5*Math.sin(.005*o.time),.5+.5*Math.sin(.008*o.time),.5+.5*Math.sin(.013*o.time),.5+.5*Math.sin(.022*o.time)]),this.gl.uniform4fv(this.roamSinLoc,[.5+.5*Math.sin(.3*o.time),.5+.5*Math.sin(1.3*o.time),.5+.5*Math.sin(5*o.time),.5+.5*Math.sin(20*o.time)]),this.bindBlurVals(a,h),t?this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA):this.gl.disable(this.gl.BLEND),this.gl.drawElements(this.gl.TRIANGLES,this.indices.length,this.gl.UNSIGNED_SHORT,0),t||this.gl.enable(this.gl.BLEND)}}])&&z(e.prototype,i),s&&z(e,s),t}();function C(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var D=function(){function t(e,i,s){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.noise=i,this.image=s,this.mesh_width=r.mesh_width,this.mesh_height=r.mesh_height,this.texsizeX=r.texsizeX,this.texsizeY=r.texsizeY,this.aspectx=r.aspectx,this.aspecty=r.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.compWidth=32,this.compHeight=24,this.buildPositions(),this.indexBuf=e.createBuffer(),this.positionVertexBuf=this.gl.createBuffer(),this.compColorVertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader(),this.mainSampler=this.gl.createSampler(),this.mainSamplerFW=this.gl.createSampler(),this.mainSamplerFC=this.gl.createSampler(),this.mainSamplerPW=this.gl.createSampler(),this.mainSamplerPC=this.gl.createSampler(),e.samplerParameteri(this.mainSampler,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSampler,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSampler,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSampler,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSamplerFW,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_MAG_FILTER,e.LINEAR),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerFC,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_MIN_FILTER,e.NEAREST_MIPMAP_NEAREST),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_MAG_FILTER,e.NEAREST),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.mainSamplerPW,e.TEXTURE_WRAP_T,e.REPEAT),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_MIN_FILTER,e.NEAREST_MIPMAP_NEAREST),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_MAG_FILTER,e.NEAREST),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.samplerParameteri(this.mainSamplerPC,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)}var e,i,s;return e=t,s=[{key:\"generateHueBase\",value:function(t){for(var e=new Float32Array([1,1,1,1,1,1,1,1,1,1,1,1]),i=0;i<4;i++){e[3*i+0]=.6+.3*Math.sin(30*t.time*.0143+3+21*i+t.rand_start[3]),e[3*i+1]=.6+.3*Math.sin(30*t.time*.0107+1+13*i+t.rand_start[1]),e[3*i+2]=.6+.3*Math.sin(30*t.time*.0129+6+9*i+t.rand_start[2]);for(var s=Math.max(e[3*i],e[3*i+1],e[3*i+2]),r=0;r<3;r++)e[3*i+r]=e[3*i+r]/s,e[3*i+r]=.5+.5*e[3*i+r]}return e}}],(i=[{key:\"buildPositions\",value:function(){for(var t=this.compWidth,e=this.compHeight,i=t+1,s=e+1,r=2/t,a=2/e,h=[],o=0;o<s;o++)for(var n=o*a-1,l=0;l<i;l++){var m=l*r-1;h.push(m,-n,0)}for(var u=[],g=0;g<e;g++)for(var c=0;c<t;c++){var A=c+i*g,f=c+i*(g+1),d=c+1+i*(g+1),v=c+1+i*g;u.push(A,f,v),u.push(f,d,v)}this.vertices=new Float32Array(h),this.indices=new Uint16Array(u)}},{key:\"updateGlobals\",value:function(t){this.mesh_width=t.mesh_width,this.mesh_height=t.mesh_height,this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.buildPositions()}},{key:\"createShader\",value:function(){var t,e,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:\"\";if(0===i.length)t=\"float orient_horiz = mod(echo_orientation, 2.0);\\n                        float orient_x = (orient_horiz != 0.0) ? -1.0 : 1.0;\\n                        float orient_y = (echo_orientation >= 2.0) ? -1.0 : 1.0;\\n                        vec2 uv_echo = ((uv - 0.5) *\\n                                        (1.0 / echo_zoom) *\\n                                        vec2(orient_x, orient_y)) + 0.5;\\n\\n                        ret = mix(texture(sampler_main, uv).rgb,\\n                                  texture(sampler_main, uv_echo).rgb,\\n                                  echo_alpha);\\n\\n                        ret *= gammaAdj;\\n\\n                        if(fShader >= 1.0) {\\n                          ret *= hue_shader;\\n                        } else if(fShader > 0.001) {\\n                          ret *= (1.0 - fShader) + (fShader * hue_shader);\\n                        }\\n\\n                        if(brighten != 0) ret = sqrt(ret);\\n                        if(darken != 0) ret = ret*ret;\\n                        if(solarize != 0) ret = ret * (1.0 - ret) * 4.0;\\n                        if(invert != 0) ret = 1.0 - ret;\",e=\"\";else{var s=_.getShaderParts(i);e=s[0],t=s[1]}t=(t=t.replace(/texture2D/g,\"texture\")).replace(/texture3D/g,\"texture\"),this.userTextures=_.getUserSamplers(e),this.shaderProgram=this.gl.createProgram();var r=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(r,\"#version 300 es\\n                                      const vec2 halfmad = vec2(0.5);\\n                                      in vec2 aPos;\\n                                      in vec4 aCompColor;\\n                                      out vec2 vUv;\\n                                      out vec4 vColor;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 0.0, 1.0);\\n                                        vUv = aPos * halfmad + halfmad;\\n                                        vColor = aCompColor;\\n                                      }\"),this.gl.compileShader(r);var a=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(a,\"#version 300 es\\n                                      precision \".concat(this.floatPrecision,\" float;\\n                                      precision highp int;\\n                                      precision mediump sampler2D;\\n                                      precision mediump sampler3D;\\n\\n                                      vec3 lum(vec3 v){\\n                                          return vec3(dot(v, vec3(0.32,0.49,0.29)));\\n                                      }\\n\\n                                      in vec2 vUv;\\n                                      in vec4 vColor;\\n                                      out vec4 fragColor;\\n                                      uniform sampler2D sampler_main;\\n                                      uniform sampler2D sampler_fw_main;\\n                                      uniform sampler2D sampler_fc_main;\\n                                      uniform sampler2D sampler_pw_main;\\n                                      uniform sampler2D sampler_pc_main;\\n                                      uniform sampler2D sampler_blur1;\\n                                      uniform sampler2D sampler_blur2;\\n                                      uniform sampler2D sampler_blur3;\\n                                      uniform sampler2D sampler_noise_lq;\\n                                      uniform sampler2D sampler_noise_lq_lite;\\n                                      uniform sampler2D sampler_noise_mq;\\n                                      uniform sampler2D sampler_noise_hq;\\n                                      uniform sampler2D sampler_pw_noise_lq;\\n                                      uniform sampler3D sampler_noisevol_lq;\\n                                      uniform sampler3D sampler_noisevol_hq;\\n\\n                                      uniform float time;\\n                                      uniform float gammaAdj;\\n                                      uniform float echo_zoom;\\n                                      uniform float echo_alpha;\\n                                      uniform float echo_orientation;\\n                                      uniform int invert;\\n                                      uniform int brighten;\\n                                      uniform int darken;\\n                                      uniform int solarize;\\n                                      uniform vec2 resolution;\\n                                      uniform vec4 aspect;\\n                                      uniform vec4 texsize;\\n                                      uniform vec4 texsize_noise_lq;\\n                                      uniform vec4 texsize_noise_mq;\\n                                      uniform vec4 texsize_noise_hq;\\n                                      uniform vec4 texsize_noise_lq_lite;\\n                                      uniform vec4 texsize_noisevol_lq;\\n                                      uniform vec4 texsize_noisevol_hq;\\n\\n                                      uniform float bass;\\n                                      uniform float mid;\\n                                      uniform float treb;\\n                                      uniform float vol;\\n                                      uniform float bass_att;\\n                                      uniform float mid_att;\\n                                      uniform float treb_att;\\n                                      uniform float vol_att;\\n\\n                                      uniform float frame;\\n                                      uniform float fps;\\n\\n                                      uniform vec4 _qa;\\n                                      uniform vec4 _qb;\\n                                      uniform vec4 _qc;\\n                                      uniform vec4 _qd;\\n                                      uniform vec4 _qe;\\n                                      uniform vec4 _qf;\\n                                      uniform vec4 _qg;\\n                                      uniform vec4 _qh;\\n\\n                                      #define q1 _qa.x\\n                                      #define q2 _qa.y\\n                                      #define q3 _qa.z\\n                                      #define q4 _qa.w\\n                                      #define q5 _qb.x\\n                                      #define q6 _qb.y\\n                                      #define q7 _qb.z\\n                                      #define q8 _qb.w\\n                                      #define q9 _qc.x\\n                                      #define q10 _qc.y\\n                                      #define q11 _qc.z\\n                                      #define q12 _qc.w\\n                                      #define q13 _qd.x\\n                                      #define q14 _qd.y\\n                                      #define q15 _qd.z\\n                                      #define q16 _qd.w\\n                                      #define q17 _qe.x\\n                                      #define q18 _qe.y\\n                                      #define q19 _qe.z\\n                                      #define q20 _qe.w\\n                                      #define q21 _qf.x\\n                                      #define q22 _qf.y\\n                                      #define q23 _qf.z\\n                                      #define q24 _qf.w\\n                                      #define q25 _qg.x\\n                                      #define q26 _qg.y\\n                                      #define q27 _qg.z\\n                                      #define q28 _qg.w\\n                                      #define q29 _qh.x\\n                                      #define q30 _qh.y\\n                                      #define q31 _qh.z\\n                                      #define q32 _qh.w\\n\\n                                      uniform vec4 slow_roam_cos;\\n                                      uniform vec4 roam_cos;\\n                                      uniform vec4 slow_roam_sin;\\n                                      uniform vec4 roam_sin;\\n\\n                                      uniform float blur1_min;\\n                                      uniform float blur1_max;\\n                                      uniform float blur2_min;\\n                                      uniform float blur2_max;\\n                                      uniform float blur3_min;\\n                                      uniform float blur3_max;\\n\\n                                      uniform float scale1;\\n                                      uniform float scale2;\\n                                      uniform float scale3;\\n                                      uniform float bias1;\\n                                      uniform float bias2;\\n                                      uniform float bias3;\\n\\n                                      uniform vec4 rand_frame;\\n                                      uniform vec4 rand_preset;\\n\\n                                      uniform float fShader;\\n\\n                                      float PI = \").concat(Math.PI,\";\\n\\n                                      \").concat(e,\"\\n\\n                                      void main(void) {\\n                                        vec3 ret;\\n                                        vec2 uv = vUv;\\n                                        vec2 uv_orig = vUv;\\n                                        uv.y = 1.0 - uv.y;\\n                                        uv_orig.y = 1.0 - uv_orig.y;\\n                                        float rad = length(uv - 0.5);\\n                                        float ang = atan(uv.x - 0.5, uv.y - 0.5);\\n                                        vec3 hue_shader = vColor.rgb;\\n\\n                                        \").concat(t,\"\\n\\n                                        fragColor = vec4(ret, vColor.a);\\n                                      }\")),this.gl.compileShader(a),this.gl.attachShader(this.shaderProgram,r),this.gl.attachShader(this.shaderProgram,a),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.compColorLocation=this.gl.getAttribLocation(this.shaderProgram,\"aCompColor\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_main\"),this.textureFWLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_fw_main\"),this.textureFCLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_fc_main\"),this.texturePWLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pw_main\"),this.texturePCLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pc_main\"),this.blurTexture1Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur1\"),this.blurTexture2Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur2\"),this.blurTexture3Loc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_blur3\"),this.noiseLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_lq\"),this.noiseMQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_mq\"),this.noiseHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_hq\"),this.noiseLQLiteLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noise_lq_lite\"),this.noisePointLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_pw_noise_lq\"),this.noiseVolLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noisevol_lq\"),this.noiseVolHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_noisevol_hq\"),this.timeLoc=this.gl.getUniformLocation(this.shaderProgram,\"time\"),this.gammaAdjLoc=this.gl.getUniformLocation(this.shaderProgram,\"gammaAdj\"),this.echoZoomLoc=this.gl.getUniformLocation(this.shaderProgram,\"echo_zoom\"),this.echoAlphaLoc=this.gl.getUniformLocation(this.shaderProgram,\"echo_alpha\"),this.echoOrientationLoc=this.gl.getUniformLocation(this.shaderProgram,\"echo_orientation\"),this.invertLoc=this.gl.getUniformLocation(this.shaderProgram,\"invert\"),this.brightenLoc=this.gl.getUniformLocation(this.shaderProgram,\"brighten\"),this.darkenLoc=this.gl.getUniformLocation(this.shaderProgram,\"darken\"),this.solarizeLoc=this.gl.getUniformLocation(this.shaderProgram,\"solarize\"),this.texsizeLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize\"),this.texsizeNoiseLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_lq\"),this.texsizeNoiseMQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_mq\"),this.texsizeNoiseHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_hq\"),this.texsizeNoiseLQLiteLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noise_lq_lite\"),this.texsizeNoiseVolLQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noisevol_lq\"),this.texsizeNoiseVolHQLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize_noisevol_hq\"),this.resolutionLoc=this.gl.getUniformLocation(this.shaderProgram,\"resolution\"),this.aspectLoc=this.gl.getUniformLocation(this.shaderProgram,\"aspect\"),this.bassLoc=this.gl.getUniformLocation(this.shaderProgram,\"bass\"),this.midLoc=this.gl.getUniformLocation(this.shaderProgram,\"mid\"),this.trebLoc=this.gl.getUniformLocation(this.shaderProgram,\"treb\"),this.volLoc=this.gl.getUniformLocation(this.shaderProgram,\"vol\"),this.bassAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"bass_att\"),this.midAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"mid_att\"),this.trebAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"treb_att\"),this.volAttLoc=this.gl.getUniformLocation(this.shaderProgram,\"vol_att\"),this.frameLoc=this.gl.getUniformLocation(this.shaderProgram,\"frame\"),this.fpsLoc=this.gl.getUniformLocation(this.shaderProgram,\"fps\"),this.blur1MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur1_min\"),this.blur1MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur1_max\"),this.blur2MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur2_min\"),this.blur2MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur2_max\"),this.blur3MinLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur3_min\"),this.blur3MaxLoc=this.gl.getUniformLocation(this.shaderProgram,\"blur3_max\"),this.scale1Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale1\"),this.scale2Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale2\"),this.scale3Loc=this.gl.getUniformLocation(this.shaderProgram,\"scale3\"),this.bias1Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias1\"),this.bias2Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias2\"),this.bias3Loc=this.gl.getUniformLocation(this.shaderProgram,\"bias3\"),this.randPresetLoc=this.gl.getUniformLocation(this.shaderProgram,\"rand_preset\"),this.randFrameLoc=this.gl.getUniformLocation(this.shaderProgram,\"rand_frame\"),this.fShaderLoc=this.gl.getUniformLocation(this.shaderProgram,\"fShader\"),this.qaLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qa\"),this.qbLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qb\"),this.qcLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qc\"),this.qdLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qd\"),this.qeLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qe\"),this.qfLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qf\"),this.qgLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qg\"),this.qhLoc=this.gl.getUniformLocation(this.shaderProgram,\"_qh\"),this.slowRoamCosLoc=this.gl.getUniformLocation(this.shaderProgram,\"slow_roam_cos\"),this.roamCosLoc=this.gl.getUniformLocation(this.shaderProgram,\"roam_cos\"),this.slowRoamSinLoc=this.gl.getUniformLocation(this.shaderProgram,\"slow_roam_sin\"),this.roamSinLoc=this.gl.getUniformLocation(this.shaderProgram,\"roam_sin\");for(var h=0;h<this.userTextures.length;h++){var o=this.userTextures[h];o.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"sampler_\".concat(o.sampler))}}},{key:\"updateShader\",value:function(t){this.createShader(t)}},{key:\"bindBlurVals\",value:function(t,e){var i=t[0],s=t[1],r=t[2],a=e[0],h=e[1],o=e[2],n=a-i,l=i,m=h-s,u=s,g=o-r,c=r;this.gl.uniform1f(this.blur1MinLoc,i),this.gl.uniform1f(this.blur1MaxLoc,a),this.gl.uniform1f(this.blur2MinLoc,s),this.gl.uniform1f(this.blur2MaxLoc,h),this.gl.uniform1f(this.blur3MinLoc,r),this.gl.uniform1f(this.blur3MaxLoc,o),this.gl.uniform1f(this.scale1Loc,n),this.gl.uniform1f(this.scale2Loc,m),this.gl.uniform1f(this.scale3Loc,g),this.gl.uniform1f(this.bias1Loc,l),this.gl.uniform1f(this.bias2Loc,u),this.gl.uniform1f(this.bias3Loc,c)}},{key:\"generateCompColors\",value:function(e,i,s){for(var r=t.generateHueBase(i),a=this.compWidth+1,h=this.compHeight+1,o=new Float32Array(a*h*4),n=0,l=0;l<h;l++)for(var m=0;m<a;m++){for(var u=m/this.compWidth,g=l/this.compHeight,c=[1,1,1],A=0;A<3;A++)c[A]=r[0+A]*u*g+r[3+A]*(1-u)*g+r[6+A]*u*(1-g)+r[9+A]*(1-u)*(1-g);var f=1;if(e){u*=this.mesh_width+1,g*=this.mesh_height+1,u=Math.clamp(u,0,this.mesh_width-1),g=Math.clamp(g,0,this.mesh_height-1);var d=Math.floor(u),v=Math.floor(g),p=u-d,_=g-v;f=s[4*(v*(this.mesh_width+1)+d)+3]*(1-p)*(1-_)+s[4*(v*(this.mesh_width+1)+(d+1))+3]*p*(1-_)+s[4*((v+1)*(this.mesh_width+1)+d)+3]*(1-p)*_+s[4*((v+1)*(this.mesh_width+1)+(d+1))+3]*p*_}o[n+0]=c[0],o[n+1]=c[1],o[n+2]=c[2],o[n+3]=f,n+=4}return o}},{key:\"renderQuadTexture\",value:function(t,e,i,s,r,a,h,o,n){var l=this.generateCompColors(t,o,n);this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuf),this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.indices,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertices,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.compColorVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,l,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.compColorLocation,4,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.compColorLocation);var m=0!==o.wrap?this.gl.REPEAT:this.gl.CLAMP_TO_EDGE;this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_S,m),this.gl.samplerParameteri(this.mainSampler,this.gl.TEXTURE_WRAP_T,m),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(0,this.mainSampler),this.gl.uniform1i(this.textureLoc,0),this.gl.activeTexture(this.gl.TEXTURE1),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(1,this.mainSamplerFW),this.gl.uniform1i(this.textureFWLoc,1),this.gl.activeTexture(this.gl.TEXTURE2),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(2,this.mainSamplerFC),this.gl.uniform1i(this.textureFCLoc,2),this.gl.activeTexture(this.gl.TEXTURE3),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(3,this.mainSamplerPW),this.gl.uniform1i(this.texturePWLoc,3),this.gl.activeTexture(this.gl.TEXTURE4),this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.bindSampler(4,this.mainSamplerPC),this.gl.uniform1i(this.texturePCLoc,4),this.gl.activeTexture(this.gl.TEXTURE5),this.gl.bindTexture(this.gl.TEXTURE_2D,i),this.gl.uniform1i(this.blurTexture1Loc,5),this.gl.activeTexture(this.gl.TEXTURE6),this.gl.bindTexture(this.gl.TEXTURE_2D,s),this.gl.uniform1i(this.blurTexture2Loc,6),this.gl.activeTexture(this.gl.TEXTURE7),this.gl.bindTexture(this.gl.TEXTURE_2D,r),this.gl.uniform1i(this.blurTexture3Loc,7),this.gl.activeTexture(this.gl.TEXTURE8),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQ),this.gl.uniform1i(this.noiseLQLoc,8),this.gl.activeTexture(this.gl.TEXTURE9),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexMQ),this.gl.uniform1i(this.noiseMQLoc,9),this.gl.activeTexture(this.gl.TEXTURE10),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexHQ),this.gl.uniform1i(this.noiseHQLoc,10),this.gl.activeTexture(this.gl.TEXTURE11),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQLite),this.gl.uniform1i(this.noiseLQLiteLoc,11),this.gl.activeTexture(this.gl.TEXTURE12),this.gl.bindTexture(this.gl.TEXTURE_2D,this.noise.noiseTexLQ),this.gl.bindSampler(12,this.noise.noiseTexPointLQ),this.gl.uniform1i(this.noisePointLQLoc,12),this.gl.activeTexture(this.gl.TEXTURE13),this.gl.bindTexture(this.gl.TEXTURE_3D,this.noise.noiseTexVolLQ),this.gl.uniform1i(this.noiseVolLQLoc,13),this.gl.activeTexture(this.gl.TEXTURE14),this.gl.bindTexture(this.gl.TEXTURE_3D,this.noise.noiseTexVolHQ),this.gl.uniform1i(this.noiseVolHQLoc,14);for(var u=0;u<this.userTextures.length;u++){var g=this.userTextures[u];this.gl.activeTexture(this.gl.TEXTURE15+u),this.gl.bindTexture(this.gl.TEXTURE_2D,this.image.getTexture(g.sampler)),this.gl.uniform1i(g.textureLoc,15+u)}this.gl.uniform1f(this.timeLoc,o.time),this.gl.uniform1f(this.gammaAdjLoc,o.gammaadj),this.gl.uniform1f(this.echoZoomLoc,o.echo_zoom),this.gl.uniform1f(this.echoAlphaLoc,o.echo_alpha),this.gl.uniform1f(this.echoOrientationLoc,o.echo_orient),this.gl.uniform1i(this.invertLoc,o.invert),this.gl.uniform1i(this.brightenLoc,o.brighten),this.gl.uniform1i(this.darkenLoc,o.darken),this.gl.uniform1i(this.solarizeLoc,o.solarize),this.gl.uniform2fv(this.resolutionLoc,[this.texsizeX,this.texsizeY]),this.gl.uniform4fv(this.aspectLoc,[this.aspectx,this.aspecty,this.invAspectx,this.invAspecty]),this.gl.uniform4fv(this.texsizeLoc,new Float32Array([this.texsizeX,this.texsizeY,1/this.texsizeX,1/this.texsizeY])),this.gl.uniform4fv(this.texsizeNoiseLQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseMQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseHQLoc,[256,256,1/256,1/256]),this.gl.uniform4fv(this.texsizeNoiseLQLiteLoc,[32,32,1/32,1/32]),this.gl.uniform4fv(this.texsizeNoiseVolLQLoc,[32,32,1/32,1/32]),this.gl.uniform4fv(this.texsizeNoiseVolHQLoc,[32,32,1/32,1/32]),this.gl.uniform1f(this.bassLoc,o.bass),this.gl.uniform1f(this.midLoc,o.mid),this.gl.uniform1f(this.trebLoc,o.treb),this.gl.uniform1f(this.volLoc,(o.bass+o.mid+o.treb)/3),this.gl.uniform1f(this.bassAttLoc,o.bass_att),this.gl.uniform1f(this.midAttLoc,o.mid_att),this.gl.uniform1f(this.trebAttLoc,o.treb_att),this.gl.uniform1f(this.volAttLoc,(o.bass_att+o.mid_att+o.treb_att)/3),this.gl.uniform1f(this.frameLoc,o.frame),this.gl.uniform1f(this.fpsLoc,o.fps),this.gl.uniform4fv(this.randPresetLoc,o.rand_preset),this.gl.uniform4fv(this.randFrameLoc,new Float32Array([Math.random(),Math.random(),Math.random(),Math.random()])),this.gl.uniform1f(this.fShaderLoc,o.fshader),this.gl.uniform4fv(this.qaLoc,new Float32Array([o.q1||0,o.q2||0,o.q3||0,o.q4||0])),this.gl.uniform4fv(this.qbLoc,new Float32Array([o.q5||0,o.q6||0,o.q7||0,o.q8||0])),this.gl.uniform4fv(this.qcLoc,new Float32Array([o.q9||0,o.q10||0,o.q11||0,o.q12||0])),this.gl.uniform4fv(this.qdLoc,new Float32Array([o.q13||0,o.q14||0,o.q15||0,o.q16||0])),this.gl.uniform4fv(this.qeLoc,new Float32Array([o.q17||0,o.q18||0,o.q19||0,o.q20||0])),this.gl.uniform4fv(this.qfLoc,new Float32Array([o.q21||0,o.q22||0,o.q23||0,o.q24||0])),this.gl.uniform4fv(this.qgLoc,new Float32Array([o.q25||0,o.q26||0,o.q27||0,o.q28||0])),this.gl.uniform4fv(this.qhLoc,new Float32Array([o.q29||0,o.q30||0,o.q31||0,o.q32||0])),this.gl.uniform4fv(this.slowRoamCosLoc,[.5+.5*Math.cos(.005*o.time),.5+.5*Math.cos(.008*o.time),.5+.5*Math.cos(.013*o.time),.5+.5*Math.cos(.022*o.time)]),this.gl.uniform4fv(this.roamCosLoc,[.5+.5*Math.cos(.3*o.time),.5+.5*Math.cos(1.3*o.time),.5+.5*Math.cos(5*o.time),.5+.5*Math.cos(20*o.time)]),this.gl.uniform4fv(this.slowRoamSinLoc,[.5+.5*Math.sin(.005*o.time),.5+.5*Math.sin(.008*o.time),.5+.5*Math.sin(.013*o.time),.5+.5*Math.sin(.022*o.time)]),this.gl.uniform4fv(this.roamSinLoc,[.5+.5*Math.sin(.3*o.time),.5+.5*Math.sin(1.3*o.time),.5+.5*Math.sin(5*o.time),.5+.5*Math.sin(20*o.time)]),this.bindBlurVals(a,h),t?this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA):this.gl.disable(this.gl.BLEND),this.gl.drawElements(this.gl.TRIANGLES,this.indices.length,this.gl.UNSIGNED_SHORT,0),t||this.gl.enable(this.gl.BLEND)}}])&&C(e.prototype,i),s&&C(e,s),t}();function V(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var I=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.textureRatio=i.textureRatio,this.texsizeX=i.texsizeX,this.texsizeY=i.texsizeY,this.positions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.vertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.useFXAA()?this.createFXAAShader():this.createShader()}var e,i,s;return e=t,(i=[{key:\"useFXAA\",value:function(){return this.textureRatio<=1}},{key:\"updateGlobals\",value:function(t){this.textureRatio=t.textureRatio,this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.gl.deleteProgram(this.shaderProgram),this.useFXAA()?this.createFXAAShader():this.createShader()}},{key:\"createFXAAShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n       const vec2 halfmad = vec2(0.5);\\n       in vec2 aPos;\\n       out vec2 v_rgbM;\\n       out vec2 v_rgbNW;\\n       out vec2 v_rgbNE;\\n       out vec2 v_rgbSW;\\n       out vec2 v_rgbSE;\\n       uniform vec4 texsize;\\n       void main(void) {\\n         gl_Position = vec4(aPos, 0.0, 1.0);\\n\\n         v_rgbM = aPos * halfmad + halfmad;\\n         v_rgbNW = v_rgbM + (vec2(-1.0, -1.0) * texsize.zx);\\n         v_rgbNE = v_rgbM + (vec2(1.0, -1.0) * texsize.zx);\\n         v_rgbSW = v_rgbM + (vec2(-1.0, 1.0) * texsize.zx);\\n         v_rgbSE = v_rgbM + (vec2(1.0, 1.0) * texsize.zx);\\n       }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 v_rgbM;\\n       in vec2 v_rgbNW;\\n       in vec2 v_rgbNE;\\n       in vec2 v_rgbSW;\\n       in vec2 v_rgbSE;\\n       out vec4 fragColor;\\n       uniform vec4 texsize;\\n       uniform sampler2D uTexture;\\n\\n       #ifndef FXAA_REDUCE_MIN\\n         #define FXAA_REDUCE_MIN   (1.0/ 128.0)\\n       #endif\\n       #ifndef FXAA_REDUCE_MUL\\n         #define FXAA_REDUCE_MUL   (1.0 / 8.0)\\n       #endif\\n       #ifndef FXAA_SPAN_MAX\\n         #define FXAA_SPAN_MAX     8.0\\n       #endif\\n\\n       void main(void) {\\n         vec4 color;\\n         vec3 rgbNW = textureLod(uTexture, v_rgbNW, 0.0).xyz;\\n         vec3 rgbNE = textureLod(uTexture, v_rgbNE, 0.0).xyz;\\n         vec3 rgbSW = textureLod(uTexture, v_rgbSW, 0.0).xyz;\\n         vec3 rgbSE = textureLod(uTexture, v_rgbSE, 0.0).xyz;\\n         vec3 rgbM  = textureLod(uTexture, v_rgbM, 0.0).xyz;\\n         vec3 luma = vec3(0.299, 0.587, 0.114);\\n         float lumaNW = dot(rgbNW, luma);\\n         float lumaNE = dot(rgbNE, luma);\\n         float lumaSW = dot(rgbSW, luma);\\n         float lumaSE = dot(rgbSE, luma);\\n         float lumaM  = dot(rgbM,  luma);\\n         float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));\\n         float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));\\n\\n         mediump vec2 dir;\\n         dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\\n         dir.y =  ((lumaNW + lumaSW) - (lumaNE + lumaSE));\\n\\n         float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *\\n                               (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);\\n\\n         float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);\\n         dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),\\n                   max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\\n                   dir * rcpDirMin)) * texsize.zw;\\n\\n         vec3 rgbA = 0.5 * (\\n             textureLod(uTexture, v_rgbM + dir * (1.0 / 3.0 - 0.5), 0.0).xyz +\\n             textureLod(uTexture, v_rgbM + dir * (2.0 / 3.0 - 0.5), 0.0).xyz);\\n         vec3 rgbB = rgbA * 0.5 + 0.25 * (\\n             textureLod(uTexture, v_rgbM + dir * -0.5, 0.0).xyz +\\n             textureLod(uTexture, v_rgbM + dir * 0.5, 0.0).xyz);\\n\\n         float lumaB = dot(rgbB, luma);\\n         if ((lumaB < lumaMin) || (lumaB > lumaMax))\\n           color = vec4(rgbA, 1.0);\\n         else\\n           color = vec4(rgbB, 1.0);\\n\\n         fragColor = color;\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\"),this.texsizeLoc=this.gl.getUniformLocation(this.shaderProgram,\"texsize\")}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n       const vec2 halfmad = vec2(0.5);\\n       in vec2 aPos;\\n       out vec2 uv;\\n       void main(void) {\\n         gl_Position = vec4(aPos, 0.0, 1.0);\\n         uv = aPos * halfmad + halfmad;\\n       }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 uv;\\n       out vec4 fragColor;\\n       uniform sampler2D uTexture;\\n\\n       void main(void) {\\n         fragColor = vec4(texture(uTexture, uv).rgb, 1.0);\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\")}},{key:\"renderQuadTexture\",value:function(t){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.uniform1i(this.textureLoc,0),this.useFXAA()&&this.gl.uniform4fv(this.texsizeLoc,new Float32Array([this.texsizeX,this.texsizeY,1/this.texsizeX,1/this.texsizeY])),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4)}}])&&V(e.prototype,i),s&&V(e,s),t}();function X(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var k=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.positions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.vertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n       const vec2 halfmad = vec2(0.5);\\n       in vec2 aPos;\\n       out vec2 uv;\\n       void main(void) {\\n         gl_Position = vec4(aPos, 0.0, 1.0);\\n         uv = aPos * halfmad + halfmad;\\n       }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 uv;\\n       out vec4 fragColor;\\n       uniform sampler2D uTexture;\\n\\n       void main(void) {\\n         fragColor = vec4(texture(uTexture, uv).rgb, 1.0);\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\")}},{key:\"renderQuadTexture\",value:function(t){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.uniform1i(this.textureLoc,0),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4)}}])&&X(e.prototype,i),s&&X(e,s),t}();function N(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var O=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.blurLevel=i;var s=[4,3.8,3.5,2.9,1.9,1.2,.7,.3],r=s[0]+s[1]+s[2]+s[3],a=s[4]+s[5]+s[6]+s[7],h=0+(s[2]+s[3])/r*2,o=2+(s[6]+s[7])/a*2;this.wds=new Float32Array([r,a,h,o]),this.wDiv=1/(2*(r+a)),this.positions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.vertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      const vec2 halfmad = vec2(0.5);\\n                                      in vec2 aPos;\\n                                      out vec2 uv;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 0.0, 1.0);\\n                                        uv = aPos * halfmad + halfmad;\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 uv;\\n       out vec4 fragColor;\\n       uniform sampler2D uTexture;\\n       uniform vec4 texsize;\\n       uniform float ed1;\\n       uniform float ed2;\\n       uniform float ed3;\\n       uniform vec4 wds;\\n       uniform float wdiv;\\n\\n       void main(void) {\\n         float w1 = wds[0];\\n         float w2 = wds[1];\\n         float d1 = wds[2];\\n         float d2 = wds[3];\\n\\n         vec2 uv2 = uv.xy;\\n\\n         vec3 blur =\\n           ( texture(uTexture, uv2 + vec2(0.0, d1 * texsize.w) ).xyz\\n           + texture(uTexture, uv2 + vec2(0.0,-d1 * texsize.w) ).xyz) * w1 +\\n           ( texture(uTexture, uv2 + vec2(0.0, d2 * texsize.w) ).xyz\\n           + texture(uTexture, uv2 + vec2(0.0,-d2 * texsize.w) ).xyz) * w2;\\n\\n         blur.xyz *= wdiv;\\n\\n         float t = min(min(uv.x, uv.y), 1.0 - max(uv.x, uv.y));\\n         t = sqrt(t);\\n         t = ed1 + ed2 * clamp(t * ed3, 0.0, 1.0);\\n         blur.xyz *= t;\\n\\n         fragColor = vec4(blur, 1.0);\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\"),this.texsizeLocation=this.gl.getUniformLocation(this.shaderProgram,\"texsize\"),this.ed1Loc=this.gl.getUniformLocation(this.shaderProgram,\"ed1\"),this.ed2Loc=this.gl.getUniformLocation(this.shaderProgram,\"ed2\"),this.ed3Loc=this.gl.getUniformLocation(this.shaderProgram,\"ed3\"),this.wdsLocation=this.gl.getUniformLocation(this.shaderProgram,\"wds\"),this.wdivLoc=this.gl.getUniformLocation(this.shaderProgram,\"wdiv\")}},{key:\"renderQuadTexture\",value:function(t,e,i){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.uniform1i(this.textureLoc,0);var s=0===this.blurLevel?e.b1ed:0;this.gl.uniform4fv(this.texsizeLocation,[i[0],i[1],1/i[0],1/i[1]]),this.gl.uniform1f(this.ed1Loc,1-s),this.gl.uniform1f(this.ed2Loc,s),this.gl.uniform1f(this.ed3Loc,5),this.gl.uniform4fv(this.wdsLocation,this.wds),this.gl.uniform1f(this.wdivLoc,this.wDiv),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4)}}])&&N(e.prototype,i),s&&N(e,s),t}();function W(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var Q=function(){function t(e,i){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.blurLevel=i;var s=[4,3.8,3.5,2.9,1.9,1.2,.7,.3],r=s[0]+s[1],a=s[2]+s[3],h=s[4]+s[5],o=s[6]+s[7],n=0+2*s[1]/r,l=2+2*s[3]/a,m=4+2*s[5]/h,u=6+2*s[7]/o;this.ws=new Float32Array([r,a,h,o]),this.ds=new Float32Array([n,l,m,u]),this.wDiv=.5/(r+a+h+o),this.positions=new Float32Array([-1,-1,1,-1,-1,1,1,1]),this.vertexBuf=this.gl.createBuffer(),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n                                      const vec2 halfmad = vec2(0.5);\\n                                      in vec2 aPos;\\n                                      out vec2 uv;\\n                                      void main(void) {\\n                                        gl_Position = vec4(aPos, 0.0, 1.0);\\n                                        uv = aPos * halfmad + halfmad;\\n                                      }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 uv;\\n       out vec4 fragColor;\\n       uniform sampler2D uTexture;\\n       uniform vec4 texsize;\\n       uniform float scale;\\n       uniform float bias;\\n       uniform vec4 ws;\\n       uniform vec4 ds;\\n       uniform float wdiv;\\n\\n       void main(void) {\\n         float w1 = ws[0];\\n         float w2 = ws[1];\\n         float w3 = ws[2];\\n         float w4 = ws[3];\\n         float d1 = ds[0];\\n         float d2 = ds[1];\\n         float d3 = ds[2];\\n         float d4 = ds[3];\\n\\n         vec2 uv2 = uv.xy;\\n\\n         vec3 blur =\\n           ( texture(uTexture, uv2 + vec2( d1 * texsize.z,0.0) ).xyz\\n           + texture(uTexture, uv2 + vec2(-d1 * texsize.z,0.0) ).xyz) * w1 +\\n           ( texture(uTexture, uv2 + vec2( d2 * texsize.z,0.0) ).xyz\\n           + texture(uTexture, uv2 + vec2(-d2 * texsize.z,0.0) ).xyz) * w2 +\\n           ( texture(uTexture, uv2 + vec2( d3 * texsize.z,0.0) ).xyz\\n           + texture(uTexture, uv2 + vec2(-d3 * texsize.z,0.0) ).xyz) * w3 +\\n           ( texture(uTexture, uv2 + vec2( d4 * texsize.z,0.0) ).xyz\\n           + texture(uTexture, uv2 + vec2(-d4 * texsize.z,0.0) ).xyz) * w4;\\n\\n         blur.xyz *= wdiv;\\n         blur.xyz = blur.xyz * scale + bias;\\n\\n         fragColor = vec4(blur, 1.0);\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\"),this.texsizeLocation=this.gl.getUniformLocation(this.shaderProgram,\"texsize\"),this.scaleLoc=this.gl.getUniformLocation(this.shaderProgram,\"scale\"),this.biasLoc=this.gl.getUniformLocation(this.shaderProgram,\"bias\"),this.wsLoc=this.gl.getUniformLocation(this.shaderProgram,\"ws\"),this.dsLocation=this.gl.getUniformLocation(this.shaderProgram,\"ds\"),this.wdivLoc=this.gl.getUniformLocation(this.shaderProgram,\"wdiv\")}},{key:\"getScaleAndBias\",value:function(t,e){var i,s,r=[1,1,1],a=[0,0,0];return r[0]=1/(e[0]-t[0]),a[0]=-t[0]*r[0],i=(t[1]-t[0])/(e[0]-t[0]),s=(e[1]-t[0])/(e[0]-t[0]),r[1]=1/(s-i),a[1]=-i*r[1],i=(t[2]-t[1])/(e[1]-t[1]),s=(e[2]-t[1])/(e[1]-t[1]),r[2]=1/(s-i),a[2]=-i*r[2],{scale:r[this.blurLevel],bias:a[this.blurLevel]}}},{key:\"renderQuadTexture\",value:function(t,e,i,s,r){this.gl.useProgram(this.shaderProgram),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.positions,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.uniform1i(this.textureLoc,0);var a=this.getScaleAndBias(i,s),h=a.scale,o=a.bias;this.gl.uniform4fv(this.texsizeLocation,[r[0],r[1],1/r[0],1/r[1]]),this.gl.uniform1f(this.scaleLoc,h),this.gl.uniform1f(this.biasLoc,o),this.gl.uniform4fv(this.wsLoc,this.ws),this.gl.uniform4fv(this.dsLocation,this.ds),this.gl.uniform1f(this.wdivLoc,this.wDiv),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawArrays(this.gl.TRIANGLE_STRIP,0,4)}}])&&W(e.prototype,i),s&&W(e,s),t}();function Y(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var G=function(){function t(e,i,s){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.blurLevel=e,this.blurRatios=i,this.gl=s,this.texsizeX=r.texsizeX,this.texsizeY=r.texsizeY,this.anisoExt=this.gl.getExtension(\"EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\"),this.blurHorizontalFrameBuffer=this.gl.createFramebuffer(),this.blurVerticalFrameBuffer=this.gl.createFramebuffer(),this.blurHorizontalTexture=this.gl.createTexture(),this.blurVerticalTexture=this.gl.createTexture(),this.setupFrameBufferTextures(),this.blurHorizontal=new Q(s,this.blurLevel,r),this.blurVertical=new O(s,this.blurLevel,r)}var e,i,s;return e=t,(i=[{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.setupFrameBufferTextures()}},{key:\"getTextureSize\",value:function(t){var e=Math.max(this.texsizeX*t,16);e=16*Math.floor((e+3)/16);var i=Math.max(this.texsizeY*t,16);return[e,i=4*Math.floor((i+3)/4)]}},{key:\"setupFrameBufferTextures\",value:function(){var t=this.blurLevel>0?this.blurRatios[this.blurLevel-1]:[1,1],e=this.blurRatios[this.blurLevel],i=this.getTextureSize(t[1]),s=this.getTextureSize(e[0]);this.bindFrameBufferTexture(this.blurHorizontalFrameBuffer,this.blurHorizontalTexture,s);var r=s,a=this.getTextureSize(e[1]);this.bindFrameBufferTexture(this.blurVerticalFrameBuffer,this.blurVerticalTexture,a),this.horizontalTexsizes=[i,s],this.verticalTexsizes=[r,a]}},{key:\"bindFrambufferAndSetViewport\",value:function(t,e){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,t),this.gl.viewport(0,0,e[0],e[1])}},{key:\"bindFrameBufferTexture\",value:function(t,e,i){if(this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,i[0],i[1],0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,new Uint8Array(i[0]*i[1]*4)),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.anisoExt){var s=this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.gl.texParameterf(this.gl.TEXTURE_2D,this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT,s)}this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,t),this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER,this.gl.COLOR_ATTACHMENT0,this.gl.TEXTURE_2D,e,0)}},{key:\"renderBlurTexture\",value:function(t,e,i,s){this.bindFrambufferAndSetViewport(this.blurHorizontalFrameBuffer,this.horizontalTexsizes[1]),this.blurHorizontal.renderQuadTexture(t,e,i,s,this.horizontalTexsizes[0]),this.gl.bindTexture(this.gl.TEXTURE_2D,this.blurHorizontalTexture),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.bindFrambufferAndSetViewport(this.blurVerticalFrameBuffer,this.verticalTexsizes[1]),this.blurVertical.renderQuadTexture(this.blurHorizontalTexture,e,this.verticalTexsizes[0]),this.gl.bindTexture(this.gl.TEXTURE_2D,this.blurVerticalTexture),this.gl.generateMipmap(this.gl.TEXTURE_2D)}}])&&Y(e.prototype,i),s&&Y(e,s),t}();function H(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var j=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.anisoExt=this.gl.getExtension(\"EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\"),this.noiseTexLQ=this.gl.createTexture(),this.noiseTexLQLite=this.gl.createTexture(),this.noiseTexMQ=this.gl.createTexture(),this.noiseTexHQ=this.gl.createTexture(),this.noiseTexVolLQ=this.gl.createTexture(),this.noiseTexVolHQ=this.gl.createTexture(),this.nTexArrLQ=t.createNoiseTex(256,1),this.nTexArrLQLite=t.createNoiseTex(32,1),this.nTexArrMQ=t.createNoiseTex(256,4),this.nTexArrHQ=t.createNoiseTex(256,8),this.nTexArrVolLQ=t.createNoiseVolTex(32,1),this.nTexArrVolHQ=t.createNoiseVolTex(32,4),this.bindTexture(this.noiseTexLQ,this.nTexArrLQ,256,256),this.bindTexture(this.noiseTexLQLite,this.nTexArrLQLite,32,32),this.bindTexture(this.noiseTexMQ,this.nTexArrMQ,256,256),this.bindTexture(this.noiseTexHQ,this.nTexArrHQ,256,256),this.bindTexture3D(this.noiseTexVolLQ,this.nTexArrVolLQ,32,32,32),this.bindTexture3D(this.noiseTexVolHQ,this.nTexArrVolHQ,32,32,32),this.noiseTexPointLQ=this.gl.createSampler(),e.samplerParameteri(this.noiseTexPointLQ,e.TEXTURE_MIN_FILTER,e.NEAREST_MIPMAP_NEAREST),e.samplerParameteri(this.noiseTexPointLQ,e.TEXTURE_MAG_FILTER,e.NEAREST),e.samplerParameteri(this.noiseTexPointLQ,e.TEXTURE_WRAP_S,e.REPEAT),e.samplerParameteri(this.noiseTexPointLQ,e.TEXTURE_WRAP_T,e.REPEAT)}var e,i,s;return e=t,s=[{key:\"fCubicInterpolate\",value:function(t,e,i,s,r){var a=r*r,h=s-i-t+e;return h*(r*a)+(t-e-h)*a+(i-t)*r+e}},{key:\"dwCubicInterpolate\",value:function(e,i,s,r,a){for(var h=[],o=0;o<4;o++){var n=t.fCubicInterpolate(e[o]/255,i[o]/255,s[o]/255,r[o]/255,a);n=Math.clamp(n,0,1),h[o]=255*n}return h}},{key:\"createNoiseVolTex\",value:function(e,i){for(var s=e*e*e,r=new Uint8Array(4*s),a=i>1?216:256,h=.5*a,o=0;o<s;o++)r[4*o+0]=Math.floor(Math.random()*a+h),r[4*o+1]=Math.floor(Math.random()*a+h),r[4*o+2]=Math.floor(Math.random()*a+h),r[4*o+3]=Math.floor(Math.random()*a+h);var n=e*e,l=e;if(i>1){for(var m=0;m<e;m+=i)for(var u=0;u<e;u+=i)for(var g=0;g<e;g++)if(g%i!=0){for(var c=Math.floor(g/i)*i+e,A=m*n+u*l,f=[],d=[],v=[],p=[],_=0;_<4;_++)f[_]=r[4*A+(c-i)%e*4+_],d[_]=r[4*A+c%e*4+_],v[_]=r[4*A+(c+i)%e*4+_],p[_]=r[4*A+(c+2*i)%e*4+_];for(var x=g%i/i,b=t.dwCubicInterpolate(f,d,v,p,x),T=0;T<4;T++){r[m*n*4+u*l*4+(4*g+T)]=b[T]}}for(var E=0;E<e;E+=i)for(var P=0;P<e;P++)for(var R=0;R<e;R++)if(R%i!=0){for(var L=Math.floor(R/i)*i+e,S=E*n,y=[],w=[],U=[],M=[],F=0;F<4;F++){var q=4*P+4*S+F;y[F]=r[(L-i)%e*l*4+q],w[F]=r[L%e*l*4+q],U[F]=r[(L+i)%e*l*4+q],M[F]=r[(L+2*i)%e*l*4+q]}for(var z=R%i/i,B=t.dwCubicInterpolate(y,w,U,M,z),C=0;C<4;C++){r[R*l*4+(4*P+4*S+C)]=B[C]}}for(var D=0;D<e;D++)for(var V=0;V<e;V++)for(var I=0;I<e;I++)if(I%i!=0){for(var X=V*l,k=Math.floor(I/i)*i+e,N=[],O=[],W=[],Q=[],Y=0;Y<4;Y++){var G=4*D+4*X+Y;N[Y]=r[(k-i)%e*n*4+G],O[Y]=r[k%e*n*4+G],W[Y]=r[(k+i)%e*n*4+G],Q[Y]=r[(k+2*i)%e*n*4+G]}for(var H=V%i/i,j=t.dwCubicInterpolate(N,O,W,Q,H),K=0;K<4;K++){r[I*n*4+(4*D+4*X+K)]=j[K]}}}return r}},{key:\"createNoiseTex\",value:function(e,i){for(var s=e*e,r=new Uint8Array(4*s),a=i>1?216:256,h=.5*a,o=0;o<s;o++)r[4*o+0]=Math.floor(Math.random()*a+h),r[4*o+1]=Math.floor(Math.random()*a+h),r[4*o+2]=Math.floor(Math.random()*a+h),r[4*o+3]=Math.floor(Math.random()*a+h);if(i>1){for(var n=0;n<e;n+=i)for(var l=0;l<e;l++)if(l%i!=0){for(var m=Math.floor(l/i)*i+e,u=n*e,g=[],c=[],A=[],f=[],d=0;d<4;d++)g[d]=r[4*u+(m-i)%e*4+d],c[d]=r[4*u+m%e*4+d],A[d]=r[4*u+(m+i)%e*4+d],f[d]=r[4*u+(m+2*i)%e*4+d];for(var v=l%i/i,p=t.dwCubicInterpolate(g,c,A,f,v),_=0;_<4;_++)r[n*e*4+4*l+_]=p[_]}for(var x=0;x<e;x++)for(var b=0;b<e;b++)if(b%i!=0){for(var T=Math.floor(b/i)*i+e,E=[],P=[],R=[],L=[],S=0;S<4;S++)E[S]=r[(T-i)%e*e*4+4*x+S],P[S]=r[T%e*e*4+4*x+S],R[S]=r[(T+i)%e*e*4+4*x+S],L[S]=r[(T+2*i)%e*e*4+4*x+S];for(var y=b%i/i,w=t.dwCubicInterpolate(E,P,R,L,y),U=0;U<4;U++)r[b*e*4+4*x+U]=w[U]}}return r}}],(i=[{key:\"bindTexture\",value:function(t,e,i,s){if(this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,i,s,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.anisoExt){var r=this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.gl.texParameterf(this.gl.TEXTURE_2D,this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT,r)}}},{key:\"bindTexture3D\",value:function(t,e,i,s,r){if(this.gl.bindTexture(this.gl.TEXTURE_3D,t),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1),this.gl.texImage3D(this.gl.TEXTURE_3D,0,this.gl.RGBA,i,s,r,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.gl.generateMipmap(this.gl.TEXTURE_3D),this.gl.texParameteri(this.gl.TEXTURE_3D,this.gl.TEXTURE_WRAP_S,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_3D,this.gl.TEXTURE_WRAP_T,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_3D,this.gl.TEXTURE_WRAP_R,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_3D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_3D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.anisoExt){var a=this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.gl.texParameterf(this.gl.TEXTURE_3D,this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT,a)}}}])&&H(e.prototype,i),s&&H(e,s),t}();function K(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var J=function(){function t(e){var i=this;!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.anisoExt=this.gl.getExtension(\"EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\"),this.samplers={},this.clouds2Image=new Image,this.clouds2Image.onload=function(){i.samplers.clouds2=i.gl.createTexture(),i.bindTexture(i.samplers.clouds2,i.clouds2Image,128,128)},this.clouds2Image.src=\"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/4RP+RXhpZgAASUkqAAgAAAAJAA8BAgAGAAAAegAAABABAgAVAAAAgAAAABIBAwABAAAAAQAAABoBBQABAAAAoAAAABsBBQABAAAAqAAAACgBAwABAAAAAgAAADIBAgAUAAAAsAAAABMCAwABAAAAAQAAAGmHBAABAAAAxAAAAGYFAABDYW5vbgBDYW5vbiBQb3dlclNob3QgUzExMAAAAAAAAAAAAAAAAEgAAAABAAAASAAAAAEAAAAyMDAyOjAxOjE5IDE3OjMzOjIwABsAmoIFAAEAAABWAwAAnYIFAAEAAABeAwAAAJAHAAQAAAAwMjEwA5ACABQAAAAOAgAABJACABQAAAAiAgAAAZEHAAQAAAABAgMAApEFAAEAAAA+AwAAAZIKAAEAAABGAwAAApIFAAEAAABOAwAABJIKAAEAAABmAwAABZIFAAEAAABuAwAABpIFAAEAAAB2AwAAB5IDAAEAAAAFAAAACZIDAAEAAAAAAAAACpIFAAEAAAB+AwAAfJIHAJoBAACGAwAAhpIHAAgBAAA2AgAAAKAHAAQAAAAwMTAwAaADAAEAAAABAAAAAqAEAAEAAACAAAAAA6AEAAEAAACAAAAABaAEAAEAAAAwBQAADqIFAAEAAAAgBQAAD6IFAAEAAAAoBQAAEKIDAAEAAAACAAAAF6IDAAEAAAACAAAAAKMHAAEAAAADAAAAAAAAADIwMDI6MDE6MTkgMTc6MzM6MjAAMjAwMjowMToxOSAxNzozMzoyMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAQAAACoBAAAgAAAAuAAAACAAAAABAAAAgAIAAEgAAAAKAAAA/////wMAAACK+AIAAAABAL8BAADoAwAArQAAACAAAAAMAAEAAwAmAAAAHAQAAAIAAwAEAAAAaAQAAAMAAwAEAAAAcAQAAAQAAwAaAAAAeAQAAAAAAwAGAAAArAQAAAAAAwAEAAAAuAQAAAYAAgAgAAAAwAQAAAcAAgAYAAAA4AQAAAgABAABAAAAkc4UAAkAAgAgAAAA+AQAABAABAABAAAAAAAJAQ0AAwAEAAAAGAUAAAAAAABMAAIAAAAFAAAAAAAAAAQAAAABAAAAAQAAAAAAAAAAAAAAAwABAAEwAAD/////WgGtACAAYgC4AP//AAAAAAAAAAAAAP//SABABkAGAgCtANMAngAAAAAAAAAAADQAAACPAEYBtQAqAfT/AgABAAEAAAAAAAAAAAAEMAAAAAAAAAAAvwEAALgAJwEAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAElNRzpQb3dlclNob3QgUzExMCBKUEVHAAAAAAAAAAAARmlybXdhcmUgVmVyc2lvbiAxLjAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAMgAuQC5AABqGADOAAAAgE8SAJsAAAAEAAEAAgAEAAAAUjk4AAIABwAEAAAAMDEwMAEQAwABAAAAQAYAAAIQAwABAAAAsAQAAAAAAAAGAAMBAwABAAAABgAAABoBBQABAAAAtAUAABsBBQABAAAAvAUAACgBAwABAAAAAgAAAAECBAABAAAA9AUAAAICBAABAAAAuA0AAAAAAAC0AAAAAQAAALQAAAABAAAAaM5qp6ps7vXbS52etpVdo/tuYZ2wtrDFXnrx1HK+braKpineV1+3VFWVteo72Poc/9j/2wCEAAkGBggGBQkIBwgKCQkLDRYPDQwMDRwTFRAWIR0jIiEcIB8kKTQsJCcxJx4fLT0tMTY3Ojo6Iio/RD44QjM3OTYBCQkJDAoMFAwMFA8KCgoPGhoKChoaTxoaGhoaT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT//AABEIAHgAoAMBIQACEQEDEQH/xAGiAAABBQEBAQEBAQAAAAAAAAAAAQIDBAUGBwgJCgsQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+gEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoLEQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIygQgUQpGhscEJIzNS8BVictEKFiQ04SXxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqCg4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2dri4+Tl5ufo6ery8/T19vf4+fr/2gAMAwEAAhEDEQA/AOdCcU4R11HMSLHTxFTAXy6PLxQIUJTglIDo9KtbWzjScNvnK/gtao1FkycjaO1ebWvOWvyR307RjZfM5zXoraacTW3DtkyD1PrWathui39q66cmoK+60OacU5O2xA8ZQlT2qBkrdfmYsiZMUwpxVCImXNRMntTERlaaRg0CN5Y8iniOszUlWOniOgQhj5o2UwDZS7KBFmAuoCnIAq69wUjIHPHWuaok5HTBtIqrbzXCMyAEDqCarPvGV6Yqlbb+Xch337kBTOd1RNHxgCrc+xKgNWAPxyD2qCWMAY7g81UJ83yJlGxCy4qJlzWqMyMpTClAjoxCUbDCniP2rK5qOVKkEdMA8ummPmgA2Vd0m1S4vMTIXjUEtjtUzdotrdLQcFeSXQfcQqJ2y/GaZL5fkhE5Y9TXPFt2Zu7K6IUinVWVW+XvjvSNCsceScsa0k1067kRT69NisY8mnC2YoWA4qL2KtcglyjcVVdd78daqnK3zImr/IheFgTkdKiZK6ou6MJKxGyUwrTJOxmjaS2WYqwjLHbnp9KBaeeB5MbZxzXLGVlfotzpcdbdXsQiKniOtSBfLppjoTE0NMdPiYxElSRmiSurAnZiSMTzmmKSDmpUdCpS1NvT0TUoHEjpGQcYC8n3qM6MJdxgYuF46VyyfI2ui6nQlzJPq+hDPo0qcKNz/wB0U54Es7co/wAzkcgdAamU01ZbtjUWnrsjDn+dzxiqpjYHK1aZDHJGQmM9ahe2zk+lbU5WZlOOhWZKjKV1nOddYTPLpptjztbcB2NTBXibaSUOOma4IWt+h2y3/Uj8rmlEdbJmLQpTjpTNlNCYnl00x1RI0x00x4oARd6tmPIPtW1o+uf2fGd+GORlcdffNZVaaqRt1NKc+R36HQxWsWoqbmGQ/MMkg4rL1bSdi5UV5fM4ys9LHfZNXXU599Lkd+FNMbSzGPmHNb85lyFaS32HgUx8pGcqK2g72M5aGY8fPSomSvRRwndafZfYtRCzL8rHFaPiPTTHKlxHGEjKhTj1ryKU/wB4uzR6dSPuPujF2YIzTxHxXamtuxyNPfuIY+KYY6okDHg4pHQIMsQKLhYhV0dtq8mr6aQ8loZRy390DNZVKqgr92aQpczKcd8+nXefLHAwVI6028nt7mTzIY/KJ5IB4qI3UuZO6fxIuSTjy21WzLmjXs9rKFidgM/dzxXTJeRECC5ZN5XPWscVTTlePxM0oS0s9kUriaIEiIKAPzrFup/3uBzmopU3fUqc0isTEQWftVWZ0dPlWuqNNr0RhKafqzOlh6mq7x12RZytHqssMcwSfy0wwyDuxRq2oCew8gxjdx1HT3rx6Uby9GenUdkc/wCSpPzdaV4WVeFJru226nLv8iFVc/eXFKYsCqi7omSIjHzS3EKSRZBJbHNOWwRMp4WjO/O0Z4NWUubuGParnafSsXFS0ZonYRo/Pwzcmk8gL0FbQgkjOUncfFK9sSU4JpkkzO+7Jz9atRV7mbk7WHpczAcOT9aUqzgu3Ud6lxSd1oylJvRkMgDZJJzVSTK9KqKJbIGJqJlzWiViG7nfW1/ZK8XJUDqT0q9q08V2sRiL5HAG35SD3Bryaalzps9KduWyKt1pjWoXzG2uRnkcCs+8ee2YKJUbIzx0Iq/bXemiRPs7IY15Ey7m+TA5BrPuNUDIyCMDnhs81rz3SsZ8tmXbFDe2DTKVzHwyk8n6Vl3944Zo04A7jvT9pp5oOTX1Mp5GVsnmtG21aEQKkikFRj604SFKJOmpWrHAYr9RUjMGXKcg9xW0WmYyTREwNN281qZkqphQRwacCMYPHvUPUpCPGhXORmqU0fNEXqEkV2j9qjKVoQa+GAALE47VPDezRYUOdo7V5CkelY0pb+eayOJt4PG1uSKxpEkQkkmp0T9StX8hnm5GCM1GUBzVXsIj+deFYge1NMTueuapyJURr2jMvTmqclq4PK4ohMJRIhGwNadgLolUjDMvcVtz217GfLc2PsuSQQdw7Uw2pU/MCK6FU6eWhg4afmWLeKFkZJcg9mFRzac8MSyMRhumKnns7PZvQOS6utLblaRMLyR9KhkhVVBDZzV21TFeysVXWoiK1MjttV8O/YWyXVgegFZRsTu4FeHdp2e63PWSvqupZtrbadpHFPnst4xgVDlqUkUX03ax7VEbNd3ByapSbFYDYKw4PPpTv7LdT0wRVq703J0XkBtlU7Sy7qje1yMMtJpoaaZWbTCZOB+FdVo+n/ZrRXaEh/pwacptxEo2ZZfRBLmQNskY8g1lXmm3VsS4IZaaxDvZ9NifZK35mUZbp7odD6jGK3jcotogmgUrWsp3tZ2sTGO+nqZr3Flco6JEEdc7eetLDoElxEH81Vz0FbQrOEby9530MZUlJ+7ppqOOgRxDMrqcdumaqz6Xa55YJnphqaxE5PRadgdGKWr17nd+cl4VFzGHAq0NEspRuRNp9K5vYxm3e6b2ZvzuK027CroNsPvLz6iql7oICFkOQO1RPCuMbp3a3Q41ruzWj2MG604xZJrInQoSVHPrXPB3NZEYlm6bM0gup0+SQttPXmt42W25DuRTW7ht6qXX1qxZSSSttZcqPWrjJPfXuiWrbGgFiADHBxW9p1z5dv8AvW3J2B7VbUeXuQnK/kM+0SyTt5GSg/ic8VUv7xpodrDn26Gs5wj0+LqXGT67dDFWLEhfkGo5nklyrE4qlC9vwJcrFRbJVl3GtO1njhTqQR61u4StYyU1civ7sSLtAJ981kSLnPJrelHlRhVlzM7yLTdTtJuu9Qe3NdBbGUorMFJxz2NcFPnUrWO2XK4lsdKCARg13bmBSurCGU4aMtn0qjJ4Xt3YnP0GK4pYbmk+X3bGyq2WvvFKTw5IpIRAR61Fc+Gttvvfn1GOlYeynHVq1uprzxfzKcCW1mdroXU8YIqQR2KA7AxPUgDGKiz3TKutjPnjic74jtB9TzT4p58Bc7yOm6tItrfoQ0mWEubtZf367l7DtUqq1w24gKg6kDpW0FFrm7Gc207dynKqqzAoOehFVmhLdFJ/CumKtuYN9gGnzuPlibmoXs5VJBXkH1qlVjtdEezlvYimtJEXLow/CqErIDWkZp7WZEotbnrsTkjrmphz1rGDutdToloxaK0EMkU9VGSKRDIQd4A9MVm+ZS0+F7selvPoNDuHw3T2oJWUlWH50r3Vn1HtqjG1LSmVS6DdzxxWQ+nTSTcghjXBKPs3Z/I6IvmV/vK7aWYptsp2jua0LG3tllLQZkK8dO9C95227g9FfcmuFnnUrtyF9BUthHhfLkjO0n14zXToo2WhiruV2JqFtFGNyxoSPUVztzrdzBJhdoVewFZJ8zs3dLY0a5dVu9yCTxLKUPyDd2NZE+tXDyF84J74rSMEiJSbKFxqFxMpDyuQe2azpN3dj+dbRlbYzkr7nvCJkYxsP95eDUqxyA584t7EVnTi+j5fLoaSa66+ZOM45orqMgooAYwqNhis5DQ0yMBio2Zm7ZrNu+5VrDNizPsdFI9CKjNrDCuEiCZ6kcVlKEd7fMtSe34DY2jV8YKknvzTLqUQcs+PwqJuyuVHU5TWtVeaX5coq/dGaxpLxpUw4zjvRFKwSepAF85SUGcdRVeaJh/DiqvZ2JsZ86sDz0qBo2xu/hq0yLHvy9KeK2pkvcdRWogpM0AIaYwqJAhNq1FcPKoHlIHHesZNqPu6vsWtXrou5HuK5YLzjjNZ1/c3YiIUZX+8vauec36LqbRivV9DNivriYlWOdo6HmrxleWIBgDx3HSpaugvZmDqFuWYgwKSPQVlsjxIym3BUgjmoXa+xT7lSOzd3PkAq3YZpby8vVASeNendBzWukt+nUz22Jo7S2v4A3lFGxzg1Rm0l4m+UMVPqKlSa03Q2k9T/9n4qqwQ2C6FUcJKhVwpbQ1vCsihOUlK0km1lS0VoSE2qiF4TrpDJE0aZJK5EgBF7pQGeoyWHrHyLxlrwklpeaZbWWmyFkkIa43/2P/bAEMAAgEBAQEBAgEBAQICAgICBAMCAgICBQQEAwQGBQYGBgUGBgYHCQgGBwkHBgYICwgJCgoKCgoGCAsMCwoMCQoKCv/bAEMBAgICAgICBQMDBQoHBgcKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCv/AABEIAIAAgAMBIgACEQEDEQH/xAAeAAACAwEAAwEBAAAAAAAAAAAGBwQFCAMBAgkACv/EADcQAAEDAwMDAgUDAgYCAwAAAAECAwQFBhEAEiEHMUETUQgiMmFxFIGRFaEjQlKxwdEW8ReCov/EABsBAAICAwEAAAAAAAAAAAAAAAUGAwQBAgcA/8QAMREAAgEDAwMCBQMDBQAAAAAAAQIDAAQRBRIhMUFRE3EiYYGRwaHR4QYU8BUjMnKx/9oADAMBAAIRAxEAPwDNEamJCR8v9tT4dJ3Zwn+2rSHStzaVBvOrSDShnBTpvDYpbIBqsi0QKRn0+QO2uwpJQQCjRFEpR8D+2uj1LIXjb/bWwfmtNvFDqaWE/LsHfXZFNB/y6uVU75uUjj7a6NwMfMEfjWd3Fa0f/DB0mtK7KpIum8KgUxqQ+0pmE2EqMlzOQFA/5MgZ/J1q2L1glUxsPtIbbitNpW80EgbwSO+PGsWWjUqhRZy/0Tqkh1OFgH78aaKLzm0i28SnlLddYwk+wGdJH9QafJd3QLtkdh4802aNeRwWxCjBHU+aA/iosex//ktysdPnN8SpAOymM/M1IUo7/wD6k8jS8uTpxPthCJL3yuJSFKGOwPY50wavS7gnU3+vro7i4QXkyA3naoc86FrhnVGqpQl1SvTI5QVZzycHR6zkmiiSMvkLwSevtQe7WJ5HcLyeRS/q0BHqLc9NIKjyB50Pz6cEkkj+2j2qUlDRWfrJSQEgdjqqRbKKkVMJe2uBO5KSngn20SW9t1OC1DjaTsMhaBKhBCWt23A841QVGnBaiQ3n86O67TGWigR1bsg7hjkHPnVFNiJSgpIyc8DRBDxVRhjigmVAAP041CcaW2rcgYI9tE82n5PCedVkqAUkgJ1uQDUXfFaZplIUMsqb2kHke2rGNSylf0g8+2j2rWvRZtbjvxXY7EV14tuymdxzknCiD9hnge+oU+110+WtoLS4hKylDiBwoe/+2gkVysgB80akhZCQao4lMCk528jXRykKJ3bfxq8jUopABT31KXSRn6NS7sVFjihNVM+Y5T24zr1FPIVt26I3aUoEkA9+2uCqaUuDKdShs1oQM0bVvpPAtizaDUKLKVIVUYaZcxTrQSpl4jBQPOE/7k6rK1QUU213PUmJVLeWG4zTSgoff8Ht/Op1239WbjjNqqMgKDLKW0hCQkAJAHYceNC8aprVNbW+nKErG7nxnnGlyG3vJcvIckHP8f4KNyz20QCxjqP4rlFq98KoZs5ptxmKuQQ4kZBK/PPtjx21U3NbopREMhKlgfOQex9taAhdK3uofT7/AMo6eUh2PBElXqOyn0bFKT9XJOQRuHccg6BKn0RvByUUyqI+pxbZWnCchSQcZyOMZxzqs97E5IwFweR3z86nS0dFByWyOD2x8qULduuOOfIwVcZOBquqaEUV9t1EMBQz3HjTz6c9OpUibLl1aKGIsMelIekfKncoHAB8nj9tK/qfDpiqu9Hp3KWyQCR3++q7XStcel4FSiAiLf5pTVmEhcl1aOQok8e+h2bTVBZJGD99HAYnQZKxCYSXHRt3LQFAZ+x17XBbjT0VpLURKNqcFwJ5Ufvpms9VUuEfvQC609gpZaWMqAcnjzxqslQwBx+2jGr0ZyI6WHmsKx/OqaXTu4KfxjxpgBDDNBDuU1t2HUKReHSW0yqB6D9NEhh+Q0jIWvcFBC/bgkhX3I8al1mQ5ULdj0gUeKw2zIW6hbKDuJICeSSf9I0c/Bn0Pi3xcL1o1iSmP6chKz6qcjaPlPB78Ej99D9etp63K1OtySfUMSU4zuAwCUqIz++Nc70q8huB6SHLJz9yaeNQt3hbe3Rhj7AUJMUc8fJru5S0+n9HI99EcOkFxO5ScY9hr2k0hIbPy+PbTCX3UEA2mg1ym7gfl51Hk0rCdwbOilVLUkkFGvC6SVEkI/IOrAkAqBlNBbkJQQQnODxqK7TFIPKNGTtFZS4d+AAMnOvU2dPqEN6bAhuuMxwPWdbbJSjPbJ8aw9xFEMk4FeSOSQ4UZqNY/V26LLpj1qR5CjT5K8uhP1oJKclJJ4+ka2DZLVgdROlbVDtKII9wohsKeDxG8Mn/AD4BI2naPPdWsxdOennSm511K27kulcCqlgKpUpxQ9FSwPpV7A++ovTq+Lw6IdUGJcSWmQuG56DjbUrc082T9IUONvn/AI0rana2msB1tjtlX4vG79x2/wDaYLO4udM2mcZjbjzinj1f6PXNEtfDtIYjts8+nETj1FEY3qz3JwNZJvGw566u4n0FbiTu419Ird6o2r18oaWnIiYr8mKlT0dXdteSCArGCMAY/wCNKq8ehtl2tMcl1LY8+SpSGkjsOcE/9aRrbULm0maKZfiHamiW1huI1dDxWGHOmU9tkPyIpSM5STqGKHBTIEea2VJB5GtFXzCob812AkIbUjgADHGgWo9OY7Sf1jrjYDhJQpRxxpktbidjlxig08MSjC81nbqPSKe3Wj/Twop9IbwrsFew0HzaeE8lPfTav+22WqissELUSd2DxjQRVKQGx8qPyddMsJA1qgz2pDvEK3LH519dunnRiPZfXiDc8OoxUU1x8IdUy6NqwrIBx3wSM6B/jNsG2aZ1fdlW5LbWJ0Rtx5pAyW1425J7HIAOmjYxrN8yqTb9UoEanKXT0h+ey8lTrxGcKScZRn2PnzpWdXKVKYvqo0559+U7EfLSJMiOW3HAnspSTnx57Ec65F/TyYuid3IGDjx710nV2zAo28Z/X2pVU+2JMJrZIVk9xrg6xDkLWww8lS0n5kA8jRo7NtiAwpF0SVNEK+YIQdwGq9u16ImOzWqO8l1qWne24MHI/wCD9jpvhugGEakEDrzS/Lb7gXYYJ+VCS6c5HUHkJ+dJyCR2OudJpEya86zGirce27m/TTnGOSSPbV7dM2FRkw0uOMqEuQWfkeSVIUMd0jkdxqM4HqK8qR6oZ9MEOlRxgeQdXBcJIp2HmqZt3jcFhxShvufX6ZWQuS84SlZJaSOMZ9tMzpz8RVmUmy5do120UuNPJBSyklG5eACSR3yB2++ll1F6rW69WZKItHTIUUFDD7rpGxefqwO478atrNtyFeVoR6o84gPeotC1NEDJB4PbQie3W/X02PGc9aKRTf2R3gVUXJRH59xuVSgRzGZcXuQ2CcIB8DXWHClMOIdlLKlA5yfHPfRk1bbkOElp9e5aBtzjwO2qmpNMxspTjPuPGjVnZpGB5FCLq7eQkY4o+HXyRYtowaBY4ALMlt5ySpeVhSQNwPH0nAI9hka6TPiakXWt2Rcqn23HUkrDaApJXwMjz7/zpRyWSpzcPOplOghLaHZLSi2VYCgNYk0PT2G5kyx79+awurXoOA3HjtVjWqgqq1FdVUVqbWCGyDhQOPOhK6KnV3VoVJdWG0AhAHkaNJUQrpbcVLSAVnd6iOVHuMaFrnp0tpKv1BJUgYIOpLeKFTtA6cVFNNKRknrzQLV5sV1agWjz/mPfQjVYSFLUWxx4zorqsBwun5cA6qJEEkH7edGIY1iHw0NkdpDzWvLB+KW9rXr0OpN1x55tbXpTQtsbkoOAQkqBwQBweccadHTfrT0wrFz1K5ruuWfOcl00x4s2SylTsde0JCl+OEgpBHP2GsvVG0ajCfUw7CIKDjKRqw6eyKjb9cbdMcPNKc2vMujhSc9jri6Tw+myrhdwwSPFdSaNyyk84OaPut/WO1oTkuzG6PFmul8LYrDBO5SMHIVu5UVcfg9u+l1Gvup0+lLRb0v/AA8ENtvEkNk8naNEd4dNl1J1+tNx0oU4srS0Owz4GfGltMo1VgTDGfWpKEqzwO+orW8WIARtgit5oC+d65BoaqIqqpSprkle71crKlHg50fdVevFq31ZdPt+NbyoU+PT249RloUNstaCT6pAAwo55P2Gh1+lSnt7CmS5nJScarUWstThbciFWOT8vYaIJqWcFjyPzVVrME4A4oErdLE1tamV5JOQfY6pqZeN22Sp1mkVd5lLowtKF8HTjh2HBfaSEIBJByPbQ/cnRhLzS5cTJOSSlQ7a2ttYEUmCaxNp5kTIFD1rfEHekScluoTjKaUseo2/yQnzg+NNinTqPdba36FN9cJA9RJGFJJ5wRpNW/02nTa81SGYpLrrwQkbfJONao6f/C3UunPTxd5Sn1LefdQlUb0+R3IP8aY7bW0jnRC3/LigdxpfqRMwHSl2/RH23Ni2SD7EauaRa1RlUaRLjxS4iMAp7YeQCcZx5AP8Z0aVyg0RgNvSZxafWfodSBzjjj+PxrzRK43aFX/Rwq9CccqLKmlNMvhRJIKcKT7j799GG1ZJIvhI3ePahY0x1k+LO3zS+juvtOBpvCcqHJAONV931CVP+R2GhWVY3oRjb/Gn51R6ET0Uin1i0LUHomIgyW2RvWF4PJH1DPck+4xxxpS3ZR61Zlddi16gNtnaU+m4nKT9xrW3vYL0BoSN3jIzxWJbSazOJQdv1xSlrFLbSokg5OqWRBSXDuIH50dVKmVCrOLMOEpz8J7aoa9Z1w0Vaf6tRZLBcA9NLjJG7PI/9aPRyDAVjzQhkJOQOK+lfxU/DzTVXM2enFkf4D6C4+7FbKxu85OcD8AaTUH4erjaeLrNGcSsKwpBbP8AbWtOiV5zKnVG00SptyUrOFpS8FA/YjPGnW3QrdrITOcpLaXQQTubwQR7++uKLok12zehIBz0I4x8iD+mK6h/qKQKokQnjrnmsCu9MJ8ajpZqNLWktpwoKTpe3TZtDZlrUI+1e3JCm+M6+md1dN7VuuCqPPpTW8NkNrQkAg447ayz1t6Ff0FMh5qlrKjnZhPnGhGqaZe6RIDL8St0I/Pir9nfW98pAGCOx/FZFbpkB2oKQ5BbbU2rAUrhK/tqxj2pa8qQp+tPMw1hISyMEpd57HGcHnPtgak3h0/uKbP/AEkeI6CFH6UEYOqef0lvNcb1XZDoWk7kJUrnOtreSHgsRXnVyOBXpd67Jst8xKdHMtfqAKLY+VQ8lKh3/OuUe2oVxRjPpAzv5LDn1t/Y++ulF6e1y9YZtp9paKgw5hlwpJ9XOePznU/p70tvqgXO8K3EfZEMFBTggLXgkDH7dtEi9hM2w4WqoFzGu5cmudk9B4NWvmImcoRGluBTkoJ4SnI5/OtnMdO2rdZgVKt1mNJgtsJERQQPTkYCRtxyO2SSeTu1nqk3TETV4dKVFTGUtwpkGQsJSnHPCjxp41S9alWbWVY1syI7UVhLf6mXJeAbYHOTvP8AqHAAz286llsrV1TEmfwKhW5uFZspj8mqjq58PfTe6KC7Vo8KNGU2hS1ORlggr5OMDkcax3UulMFfUVuO5MUhppe5DxPbHOONa2u2NVKBSlMUCVNkMuR0plPvpAaWvn6M4OPzpL1C3pcOovOymwXSFbVBOdufI/71pY288UpEDllPT81m5nieMGVQDUTqj1OrNm2221bF3PrdRGLLxaePJ5899DvTLqJROq9VpznVGC++mG2WnGwCQ8rOAT5z7/jXpUbcW+46mpI3kqyk9+NelvvtWe4h2nx0ZQ4CpJT3HnTFp2n3CpvHXnnoaDXt/AW2k8ccdRTerNsdGbepiq7SbPZSQz6qmxFUSkHt4IHP99KK7OtdlxnltsUKS4VEpfadOAMdsfcHVldvVKtVOkriQ3VRy4r/ABdijhQHYY8aUldil1TinkBSl87jotpmj78tdkk/9iaGX+rCMhbYAD2FfTe1PgzqHT+7UXJatwF6M1IC22ivDm0HI5Hn99Puh0+RTssKqLzzeMpTJBKk/bJ1CtaWzMbJizUOBBIWE5BB/BAP76vmySnn++hul6faxH14iefnkfT5e+aLXl1O/wDtv2+VedVdx04TlMtoajFS1FCvXZ3ZSe+PY41aaj1GK7LjlEd703ByheOx0VuohNAVxmqcTbJAaD698P3TisQZDDVDbZfeOQ+ngpP/AFoJY+Du3xUkzKrLalsDOWcFOD+f402Y9MqzVLdaqNS9V8kltxJIIGOBqPGl1OBGcDzO9RPClL57HQKXR9JkZXaDZx24+4HFEEvrxAVWTPv+M1k7qf03c6UXG5Kt+2W3S0slmSpsgd+/PfA/31VT+rw5XV7Tgxqi9HLzsh5IWXMA4wk8Jz/61qfqf0ypfUSkqnMtgzWo69iSTySOBrOVT+Fy8H6k2xVqTIbS4fmf2ZShOlG+0xrOUqyZU9CBnj+KN214J1BBwR1FI+5axbN0SRL9L0pTqgXGkNYQhWPA0QWv0pvrqJRAqgz5amow/wAJv1fkGMnsfHJ0Vv8ASGj9La+5Vbzt+XLisglpLUc7XecABXj8nTHoTFTdsaIbcguUlh0BSWW1J3ZcAyFecD/nWbRTI/pxnbjz+1YuJPTTe4z7UtbWoF2XPOYtepy1L/TIUpwOOhKUJQMq559j/Oqu+qXW4tYcRS6bMQzKQENMrQcqTjgcDkeR9tN+2enl4Wncypj8OO+AMu5SpaCnIzyPOrvrrU6bS7f/AFKKm1FfWgpSoqSTvxnA9iNMM+orZlSoDADH17mg8Nm90DklST+nYVmdfQq/6q4hX9CDKXRu3PvISEjPcjOf7Z1X3T0BlW/SHKtU7jhD0nQhxDIUoJ9yTjxnwNBV/dYep9r3K8+xXpYCuEoWtQBTnjH2Ol31P+IPqddDCI8utO7UIx6bR2p/cDv++rKanqbspVlA9v3qBtPsVBDBif8APFMWtWPSqdTnahIuultpwfSbmv8ApKUARhQye2Of20lbs6o2bDkriqrsJWxW0rbVuSr99ANzXLXZ29dSlur+XlS3CdLyvRW1rWsOg55I76MWupyoT6jbvpihtxp8LD4Bj61/RJHoRq8ZmNWFvJWyrcxIjultxP7juNXdEoJouRFqT7rSvqTJXuOffOvaIT6YBJOBxnU9ogpwBjVbTrSDAkxyMc9/5q7NcSOSvbxXtr9r9r920ZqrXhYBSQdQJjQIJx+dTVup7ajSNqknPtqCcAx1lTg5qllPvxcltwj8agSnqpIQSEuqB7nB51dqYjlRLo75BP2xquu+ZckWnoNqw0StqgH2lOYUUeQPzoHM/pRM7E4HYDJ+1EEw7hRxnueB96rabFcqrkmPJa9UNoBLK+x+bng9+NU9woj0+Utb1vtObAMteiR6ae+5I8du+plWqFah0t5VKbEV1xW4uuIO5IA4Bz986z71mvbqpRbmTUaqX429sNhyO4r03BnIWOfIxn8aA3N9CsigDnyen3olFayFDk0665W4Eq1v69HlyC00raWmlBSkKzwSPtwceQdYw+L3rDWLhqggJQ41FiI2RcnBWc/MtQAABJ8eO2tAWXcl2/p3WX3S4pwpVuWySl3I/wD1pQ9erfrM2c+0i3I8sFBcQtMTkI7c7e3PvoZNcPHcCQjj371aiCPGUB5rLNfviqyKYiTU2VrbQdiXHBnIz21CqNq1WpwUzaPDMhtxsLCmkZwD747aOLwgXNHt522avZjQiLWHEEp+dsDcBt9uSM/jVFRLZ6vWBSZF2dNHZSIzzKm5jbRStSRzwUkHgZznHfVxLkyLxgH9DVdo1j6nIpK31QaoylfqMEEDCgBoHl0OU7HVUm2VpS3wpvGc8d9ak6WVGL1IdnW51Ht6NMmuO+ozMGGHMEYKSBhJAPIOO5OfGqC//h1doNVcnUOnThGUopKS0HAoc9iO/wDHjUqak0bGNxz+lQtbK3xrX//Z\",this.emptyImage=new Image,this.emptyImage.onload=function(){i.samplers.empty=i.gl.createTexture(),i.bindTexture(i.samplers.empty,i.emptyImage,1,1)},this.emptyImage.src=\"data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=\"}var e,i,s;return e=t,(i=[{key:\"bindTexture\",value:function(t,e,i,s){if(this.gl.bindTexture(this.gl.TEXTURE_2D,t),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,i,s,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.REPEAT),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.anisoExt){var r=this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.gl.texParameterf(this.gl.TEXTURE_2D,this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT,r)}}},{key:\"loadExtraImages\",value:function(t){var e=this;Object.keys(t).forEach(function(i){var s=t[i],r=s.data,a=s.width,h=s.height;if(!e.samplers[i]){var o=new Image;o.onload=function(){e.samplers[i]=e.gl.createTexture(),e.bindTexture(e.samplers[i],o,a,h)},o.src=r}})}},{key:\"getTexture\",value:function(t){var e=this.samplers[t];return e||this.samplers.clouds2}}])&&K(e.prototype,i),s&&K(e,s),t}();function Z(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var $=function(){function t(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.texsizeX=i.texsizeX,this.texsizeY=i.texsizeY,this.aspectx=i.aspectx,this.aspecty=i.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.buildPositions(),this.textTexture=this.gl.createTexture(),this.indexBuf=e.createBuffer(),this.positionVertexBuf=this.gl.createBuffer(),this.vertexBuf=this.gl.createBuffer(),this.canvas=document.createElement(\"canvas\"),this.canvas.width=this.texsizeX,this.canvas.height=this.texsizeY,this.context2D=this.canvas.getContext(\"2d\"),this.floatPrecision=_.getFragmentFloatPrecision(this.gl),this.createShader()}var e,i,s;return e=t,(i=[{key:\"generateTitleTexture\",value:function(t){this.context2D.clearRect(0,0,this.texsizeX,this.texsizeY),this.fontSize=Math.floor(this.texsizeX/256*16),this.fontSize=Math.max(this.fontSize,6),this.context2D.font=\"italic \".concat(this.fontSize,\"px Times New Roman\");var e=t,i=this.context2D.measureText(e).width;if(i>this.texsizeX){var s=this.texsizeX/i*.91;e=\"\".concat(e.substring(0,Math.floor(e.length*s)),\"...\"),i=this.context2D.measureText(e).width}this.context2D.fillStyle=\"#FFFFFF\",this.context2D.fillText(e,(this.texsizeX-i)/2,this.texsizeY/2);var r=new Uint8Array(this.context2D.getImageData(0,0,this.texsizeX,this.texsizeY).data.buffer);this.gl.pixelStorei(this.gl.UNPACK_FLIP_Y_WEBGL,!0),this.gl.bindTexture(this.gl.TEXTURE_2D,this.textTexture),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.texsizeX,this.texsizeY,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,r),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.bindTexture(this.gl.TEXTURE_2D,null)}},{key:\"updateGlobals\",value:function(t){this.texsizeX=t.texsizeX,this.texsizeY=t.texsizeY,this.aspectx=t.aspectx,this.aspecty=t.aspecty,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.canvas.width=this.texsizeX,this.canvas.height=this.texsizeY}},{key:\"buildPositions\",value:function(){for(var t=[],e=0;e<8;e++)for(var i=e*(2/7)-1,s=0;s<16;s++){var r=s*(2/15)-1;t.push(r,-i,0)}for(var a=[],h=0;h<7;h++)for(var o=0;o<15;o++){var n=o+16*h,l=o+16*(h+1),m=o+1+16*(h+1),u=o+1+16*h;a.push(n,l,u),a.push(l,m,u)}this.vertices=new Float32Array(t),this.indices=new Uint16Array(a)}},{key:\"createShader\",value:function(){this.shaderProgram=this.gl.createProgram();var t=this.gl.createShader(this.gl.VERTEX_SHADER);this.gl.shaderSource(t,\"#version 300 es\\n       const vec2 halfmad = vec2(0.5);\\n       in vec2 aPos;\\n       in vec2 aUv;\\n       out vec2 uv_orig;\\n       out vec2 uv;\\n       void main(void) {\\n         gl_Position = vec4(aPos, 0.0, 1.0);\\n         uv_orig = aPos * halfmad + halfmad;\\n         uv = aUv;\\n       }\"),this.gl.compileShader(t);var e=this.gl.createShader(this.gl.FRAGMENT_SHADER);this.gl.shaderSource(e,\"#version 300 es\\n       precision \".concat(this.floatPrecision,\" float;\\n       precision highp int;\\n       precision mediump sampler2D;\\n\\n       in vec2 uv_orig;\\n       in vec2 uv;\\n       out vec4 fragColor;\\n       uniform sampler2D uTexture;\\n       uniform float textColor;\\n\\n       void main(void) {\\n         fragColor = texture(uTexture, uv) * vec4(textColor);\\n       }\")),this.gl.compileShader(e),this.gl.attachShader(this.shaderProgram,t),this.gl.attachShader(this.shaderProgram,e),this.gl.linkProgram(this.shaderProgram),this.positionLocation=this.gl.getAttribLocation(this.shaderProgram,\"aPos\"),this.uvLocation=this.gl.getAttribLocation(this.shaderProgram,\"aUv\"),this.textureLoc=this.gl.getUniformLocation(this.shaderProgram,\"uTexture\"),this.textColorLoc=this.gl.getUniformLocation(this.shaderProgram,\"textColor\")}},{key:\"generateUvs\",value:function(t,e,i){for(var s=[],r=0;r<8;r++)for(var a=0;a<16;a++){var h=2*(a/15)-1,o=2*(.75*(r/7-.5)+.5)-1;t>=1&&(o+=1/this.texsizeY),s.push(h,e?o:-o)}for(var n=Math.max(0,1-1.5*t),l=1.3*Math.pow(n,1.8),m=0;m<8;m++)for(var u=0;u<16;u++){var g=16*m+u;s[g]+=.07*l*Math.sin(.31*i.time+.39*s[g]-1.94*s[g+1]),s[g]+=.044*l*Math.sin(.81*i.time-1.91*s[g]+.27*s[g+1]),s[g]+=.061*l*Math.sin(1.31*i.time+.61*s[g]+.74*s[g+1]),s[g+1]+=.061*l*Math.sin(.37*i.time+1.83*s[g]+.69*s[g+1]),s[g+1]+=.07*l*Math.sin(.67*i.time+.42*s[g]-1.39*s[g+1]),s[g+1]+=.087*l*Math.sin(1.07*i.time+3.55*s[g]+.89*s[g+1])}for(var c=1.01/(Math.pow(t,.21)+.01),A=0;A<s.length/2;A++)s[2*A]*=c,s[2*A+1]*=c*this.invAspecty,s[2*A]=(s[2*A]+1)/2,s[2*A+1]=(s[2*A+1]+1)/2;return new Float32Array(s)}},{key:\"renderTitle\",value:function(t,e,i){this.gl.useProgram(this.shaderProgram);var s=this.generateUvs(t,e,i);this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER,this.indexBuf),this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER,this.indices,this.gl.STATIC_DRAW),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.positionVertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,this.vertices,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.positionLocation,3,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.positionLocation),this.gl.bindBuffer(this.gl.ARRAY_BUFFER,this.vertexBuf),this.gl.bufferData(this.gl.ARRAY_BUFFER,s,this.gl.STATIC_DRAW),this.gl.vertexAttribPointer(this.uvLocation,2,this.gl.FLOAT,!1,0,0),this.gl.enableVertexAttribArray(this.uvLocation),this.gl.activeTexture(this.gl.TEXTURE0),this.gl.bindTexture(this.gl.TEXTURE_2D,this.textTexture),this.gl.uniform1i(this.textureLoc,0),this.gl.uniform1f(this.textColorLoc,Math.pow(t,.3)),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA),this.gl.drawElements(this.gl.TRIANGLES,this.indices.length,this.gl.UNSIGNED_SHORT,0)}}])&&Z(e.prototype,i),s&&Z(e,s),t}();function tt(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var et=function(){function t(e){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.mesh_width=e.mesh_width,this.mesh_height=e.mesh_height,this.aspectx=e.aspectx,this.aspecty=e.aspecty,this.vertInfoA=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)),this.vertInfoC=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)),this.createBlendPattern()}var e,i,s;return e=t,s=[{key:\"resizeMatrixValues\",value:function(t,e,i,s,r){for(var a=new Float32Array((s+1)*(r+1)),h=0,o=0;o<r+1;o++)for(var n=0;n<s+1;n++){var l=n/r,m=o/s;l*=e+1,m*=i+1,l=Math.clamp(l,0,e-1),m=Math.clamp(m,0,i-1);var u=Math.floor(l),g=Math.floor(m),c=l-u,A=m-g,f=t[g*(e+1)+u],d=t[g*(e+1)+(u+1)],v=t[(g+1)*(e+1)+u],p=t[(g+1)*(e+1)+(u+1)];a[h]=f*(1-c)*(1-A)+d*c*(1-A)+v*(1-c)*A+p*c*A,h+=1}return a}}],(i=[{key:\"updateGlobals\",value:function(e){var i=this.mesh_width,s=this.mesh_height;this.mesh_width=e.mesh_width,this.mesh_height=e.mesh_height,this.aspectx=e.aspectx,this.aspecty=e.aspecty,this.mesh_width===i&&this.mesh_height===s||(this.vertInfoA=t.resizeMatrixValues(this.vertInfoA,i,s,this.mesh_width,this.mesh_height),this.vertInfoC=t.resizeMatrixValues(this.vertInfoC,i,s,this.mesh_width,this.mesh_height))}},{key:\"genPlasma\",value:function(t,e,i,s,r){var a=Math.floor((t+e)/2),h=Math.floor((i+s)/2),o=this.vertInfoC[i*(this.mesh_width+1)+t],n=this.vertInfoC[i*(this.mesh_width+1)+e],l=this.vertInfoC[s*(this.mesh_width+1)+t],m=this.vertInfoC[s*(this.mesh_width+1)+e];s-i>=2&&(0===t&&(this.vertInfoC[h*(this.mesh_width+1)+t]=.5*(o+l)+(2*Math.random()-1)*r*this.aspecty),this.vertInfoC[h*(this.mesh_width+1)+e]=.5*(n+m)+(2*Math.random()-1)*r*this.aspecty),e-t>=2&&(0===i&&(this.vertInfoC[i*(this.mesh_width+1)+a]=.5*(o+n)+(2*Math.random()-1)*r*this.aspectx),this.vertInfoC[s*(this.mesh_width+1)+a]=.5*(l+m)+(2*Math.random()-1)*r*this.aspectx),s-i>=2&&e-t>=2&&(o=this.vertInfoC[h*(this.mesh_width+1)+t],n=this.vertInfoC[h*(this.mesh_width+1)+e],l=this.vertInfoC[i*(this.mesh_width+1)+a],m=this.vertInfoC[s*(this.mesh_width+1)+a],this.vertInfoC[h*(this.mesh_width+1)+a]=.25*(l+m+o+n)+(2*Math.random()-1)*r,this.genPlasma(t,a,i,h,.5*r),this.genPlasma(a,e,i,h,.5*r),this.genPlasma(t,a,h,s,.5*r),this.genPlasma(a,e,h,s,.5*r))}},{key:\"createBlendPattern\",value:function(){var t=1+Math.floor(3*Math.random());if(0===t)for(var e=0,i=0;i<=this.mesh_height;i++)for(var s=0;s<=this.mesh_width;s++)this.vertInfoA[e]=1,this.vertInfoC[e]=0,e+=1;else if(1===t)for(var r=6.28*Math.random(),a=Math.cos(r),h=Math.sin(r),o=.1+.2*Math.random(),n=1/o,l=0,m=0;m<=this.mesh_height;m++)for(var u=m/this.mesh_height*this.aspecty,g=0;g<=this.mesh_width;g++){var c=(g/this.mesh_width*this.aspectx-.5)*a+(u-.5)*h+.5;c=(c-.5)/Math.sqrt(2)+.5,this.vertInfoA[l]=n*(1+o),this.vertInfoC[l]=n*c-n,l+=1}else if(2===t){var A=.12+.13*Math.random(),f=1/A;this.vertInfoC[0]=Math.random(),this.vertInfoC[this.mesh_width]=Math.random(),this.vertInfoC[this.mesh_height*(this.mesh_width+1)]=Math.random(),this.vertInfoC[this.mesh_height*(this.mesh_width+1)+this.mesh_width]=Math.random(),this.genPlasma(0,this.mesh_width,0,this.mesh_height,.25);for(var d=this.vertInfoC[0],v=this.vertInfoC[0],p=0,_=0;_<=this.mesh_height;_++)for(var x=0;x<=this.mesh_width;x++)d>this.vertInfoC[p]&&(d=this.vertInfoC[p]),v<this.vertInfoC[p]&&(v=this.vertInfoC[p]),p+=1;var b=1/(v-d);p=0;for(var T=0;T<=this.mesh_height;T++)for(var E=0;E<=this.mesh_width;E++){var P=(this.vertInfoC[p]-d)*b;this.vertInfoA[p]=f*(1+A),this.vertInfoC[p]=f*P-f,p+=1}}else if(3===t)for(var R=.02+.14*Math.random()+.34*Math.random(),L=1/R,S=2*Math.floor(2*Math.random())-1,y=0,w=0;w<=this.mesh_height;w++)for(var U=(w/this.mesh_height-.5)*this.aspecty,M=0;M<=this.mesh_width;M++){var F=(M/this.mesh_width-.5)*this.aspectx,q=1.41421*Math.sqrt(F*F+U*U);-1===S&&(q=1-q),this.vertInfoA[y]=L*(1+R),this.vertInfoC[y]=L*q-L,y+=1}}}])&&tt(e.prototype,i),s&&tt(e,s),t}();function it(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var st=function(){function t(e,i,s){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.gl=e,this.audio=i,this.frameNum=0,this.fps=30,this.time=0,this.presetTime=0,this.lastTime=performance.now(),this.timeHist=[0],this.timeHistMax=120,this.blending=!1,this.blendStartTime=0,this.blendProgress=0,this.blendDuration=0,this.width=s.width||1200,this.height=s.height||900,this.mesh_width=s.meshWidth||48,this.mesh_height=s.meshHeight||36,this.pixelRatio=s.pixelRatio||window.devicePixelRatio||1,this.textureRatio=s.textureRatio||1,this.outputFXAA=s.outputFXAA||!1,this.texsizeX=this.width*this.pixelRatio*this.textureRatio,this.texsizeY=this.height*this.pixelRatio*this.textureRatio,this.aspectx=this.texsizeY>this.texsizeX?this.texsizeX/this.texsizeY:1,this.aspecty=this.texsizeX>this.texsizeY?this.texsizeY/this.texsizeX:1,this.invAspectx=1/this.aspectx,this.invAspecty=1/this.aspecty,this.qs=c.range(1,33).map(function(t){return\"q\".concat(t)}),this.ts=c.range(1,9).map(function(t){return\"t\".concat(t)}),this.regs=c.range(0,100).map(function(t){return t<10?\"reg0\".concat(t):\"reg\".concat(t)}),this.blurRatios=[[.5,.25],[.125,.125],[.0625,.0625]],this.audioLevels=new n(this.audio),this.prevFrameBuffer=this.gl.createFramebuffer(),this.targetFrameBuffer=this.gl.createFramebuffer(),this.prevTexture=this.gl.createTexture(),this.targetTexture=this.gl.createTexture(),this.compFrameBuffer=this.gl.createFramebuffer(),this.compTexture=this.gl.createTexture(),this.anisoExt=this.gl.getExtension(\"EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"MOZ_EXT_texture_filter_anisotropic\")||this.gl.getExtension(\"WEBKIT_EXT_texture_filter_anisotropic\"),this.bindFrameBufferTexture(this.prevFrameBuffer,this.prevTexture),this.bindFrameBufferTexture(this.targetFrameBuffer,this.targetTexture),this.bindFrameBufferTexture(this.compFrameBuffer,this.compTexture);var r={pixelRatio:this.pixelRatio,textureRatio:this.textureRatio,texsizeX:this.texsizeX,texsizeY:this.texsizeY,mesh_width:this.mesh_width,mesh_height:this.mesh_height,aspectx:this.aspectx,aspecty:this.aspecty};this.noise=new j(e),this.image=new J(e),this.warpShader=new B(e,this.noise,this.image,r),this.compShader=new D(e,this.noise,this.image,r),this.outputShader=new I(e,r),this.prevWarpShader=new B(e,this.noise,this.image,r),this.prevCompShader=new D(e,this.noise,this.image,r),this.numBlurPasses=0,this.blurShader1=new G(0,this.blurRatios,e,r),this.blurShader2=new G(1,this.blurRatios,e,r),this.blurShader3=new G(2,this.blurRatios,e,r),this.blurTexture1=this.blurShader1.blurVerticalTexture,this.blurTexture2=this.blurShader2.blurVerticalTexture,this.blurTexture3=this.blurShader3.blurVerticalTexture,this.basicWaveform=new E(e,r),this.customWaveforms=c.range(4).map(function(t){return new R(t,e,r)}),this.customShapes=c.range(4).map(function(t){return new S(t,e,r)}),this.prevCustomWaveforms=c.range(4).map(function(t){return new R(t,e,r)}),this.prevCustomShapes=c.range(4).map(function(t){return new S(t,e,r)}),this.darkenCenter=new M(e,r),this.innerBorder=new w(e,r),this.outerBorder=new w(e,r),this.motionVectors=new q(e,r),this.titleText=new $(e,r),this.blendPattern=new et(r),this.resampleShader=new k(e),this.supertext={startTime:-1},this.warpUVs=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)*2),this.warpColor=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)*4),this.gl.clearColor(0,0,0,1),this.blankPreset=m.a;var a={frame:0,time:0,fps:45,bass:1,bass_att:1,mid:1,mid_att:1,treb:1,treb_att:1};this.preset=m.a,this.prevPreset=this.preset,this.presetEquationRunner=new f(this.preset,a,r),this.prevPresetEquationRunner=new f(this.prevPreset,a,r),this.regVars=this.presetEquationRunner.mdVSRegs}var e,i,s;return e=t,s=[{key:\"getHighestBlur\",value:function(t){return/sampler_blur3/.test(t)?3:/sampler_blur2/.test(t)?2:/sampler_blur1/.test(t)?1:0}},{key:\"mixFrameEquations\",value:function(t,e,i){var s=.5-.5*Math.cos(t*Math.PI),r=1-s,a=c.cloneVars(e);return a.decay=s*e.decay+r*i.decay,a.wave_a=s*e.wave_a+r*i.wave_a,a.wave_r=s*e.wave_r+r*i.wave_r,a.wave_g=s*e.wave_g+r*i.wave_g,a.wave_b=s*e.wave_b+r*i.wave_b,a.wave_x=s*e.wave_x+r*i.wave_x,a.wave_y=s*e.wave_y+r*i.wave_y,a.wave_mystery=s*e.wave_mystery+r*i.wave_mystery,a.ob_size=s*e.ob_size+r*i.ob_size,a.ob_r=s*e.ob_r+r*i.ob_r,a.ob_g=s*e.ob_g+r*i.ob_g,a.ob_b=s*e.ob_b+r*i.ob_b,a.ob_a=s*e.ob_a+r*i.ob_a,a.ib_size=s*e.ib_size+r*i.ib_size,a.ib_r=s*e.ib_r+r*i.ib_r,a.ib_g=s*e.ib_g+r*i.ib_g,a.ib_b=s*e.ib_b+r*i.ib_b,a.ib_a=s*e.ib_a+r*i.ib_a,a.mv_x=s*e.mv_x+r*i.mv_x,a.mv_y=s*e.mv_y+r*i.mv_y,a.mv_dx=s*e.mv_dx+r*i.mv_dx,a.mv_dy=s*e.mv_dy+r*i.mv_dy,a.mv_l=s*e.mv_l+r*i.mv_l,a.mv_r=s*e.mv_r+r*i.mv_r,a.mv_g=s*e.mv_g+r*i.mv_g,a.mv_b=s*e.mv_b+r*i.mv_b,a.mv_a=s*e.mv_a+r*i.mv_a,a.echo_zoom=s*e.echo_zoom+r*i.echo_zoom,a.echo_alpha=s*e.echo_alpha+r*i.echo_alpha,a.echo_orient=s*e.echo_orient+r*i.echo_orient,a.wave_dots=s<.5?i.wave_dots:e.wave_dots,a.wave_thick=s<.5?i.wave_thick:e.wave_thick,a.additivewave=s<.5?i.additivewave:e.additivewave,a.wave_brighten=s<.5?i.wave_brighten:e.wave_brighten,a.darken_center=s<.5?i.darken_center:e.darken_center,a.gammaadj=s<.5?i.gammaadj:e.gammaadj,a.wrap=s<.5?i.wrap:e.wrap,a.invert=s<.5?i.invert:e.invert,a.brighten=s<.5?i.brighten:e.brighten,a.darken=s<.5?i.darken:e.darken,a.solarize=s<.5?i.brighten:e.solarize,a.b1n=s*e.b1n+r*i.b1n,a.b2n=s*e.b2n+r*i.b2n,a.b3n=s*e.b3n+r*i.b3n,a.b1x=s*e.b1x+r*i.b1x,a.b2x=s*e.b2x+r*i.b2x,a.b3x=s*e.b3x+r*i.b3x,a.b1ed=s*e.b1ed+r*i.b1ed,a}},{key:\"getBlurValues\",value:function(t){var e=t.b1n,i=t.b2n,s=t.b3n,r=t.b1x,a=t.b2x,h=t.b3x;if(r-e<.1){var o=.5*(e+r);e=o-.05,r=o-.05}if((a=Math.min(r,a))-(i=Math.max(e,i))<.1){var n=.5*(i+a);i=n-.05,a=n-.05}if((h=Math.min(a,h))-(s=Math.max(i,s))<.1){var l=.5*(s+h);s=l-.05,h=l-.05}return{blurMins:[e,i,s],blurMaxs:[r,a,h]}}}],(i=[{key:\"loadPreset\",value:function(e,i){this.blendPattern.createBlendPattern(),this.blending=!0,this.blendStartTime=this.time,this.blendDuration=i,this.blendProgress=0,this.prevPresetEquationRunner=this.presetEquationRunner,this.prevPreset=this.preset,this.preset=e,this.preset.baseVals.old_wave_mode=this.prevPreset.baseVals.wave_mode,this.presetTime=this.time;var s={frame:this.frameNum,time:this.time,fps:this.fps,bass:this.audioLevels.bass,bass_att:this.audioLevels.bass_att,mid:this.audioLevels.mid,mid_att:this.audioLevels.mid_att,treb:this.audioLevels.treb,treb_att:this.audioLevels.treb_att},r={pixelRatio:this.pixelRatio,textureRatio:this.textureRatio,texsizeX:this.texsizeX,texsizeY:this.texsizeY,mesh_width:this.mesh_width,mesh_height:this.mesh_height,aspectx:this.aspectx,aspecty:this.aspecty};this.presetEquationRunner=new f(this.preset,s,r),this.regVars=this.presetEquationRunner.mdVSRegs;var a=this.prevWarpShader;this.prevWarpShader=this.warpShader,this.warpShader=a;var h=this.prevCompShader;this.prevCompShader=this.compShader,this.compShader=h;var o=this.preset.warp.trim(),n=this.preset.comp.trim();this.warpShader.updateShader(o),this.compShader.updateShader(n),0===o.length?this.numBlurPasses=0:this.numBlurPasses=t.getHighestBlur(o),0!==n.length&&(this.numBlurPasses=Math.max(this.numBlurPasses,t.getHighestBlur(n)))}},{key:\"loadExtraImages\",value:function(t){this.image.loadExtraImages(t)}},{key:\"setRendererSize\",value:function(t,e,i){var s=this.texsizeX,r=this.texsizeY;if(this.width=t,this.height=e,this.mesh_width=i.meshWidth||this.mesh_width,this.mesh_height=i.meshHeight||this.mesh_height,this.pixelRatio=i.pixelRatio||this.pixelRatio,this.textureRatio=i.textureRatio||this.textureRatio,this.texsizeX=t*this.pixelRatio*this.textureRatio,this.texsizeY=e*this.pixelRatio*this.textureRatio,this.aspectx=this.texsizeY>this.texsizeX?this.texsizeX/this.texsizeY:1,this.aspecty=this.texsizeX>this.texsizeY?this.texsizeY/this.texsizeX:1,this.texsizeX!==s||this.texsizeY!==r){var a=this.gl.createTexture();this.bindFrameBufferTexture(this.targetFrameBuffer,a),this.bindFrambufferAndSetViewport(this.targetFrameBuffer,this.texsizeX,this.texsizeY),this.resampleShader.renderQuadTexture(this.targetTexture),this.targetTexture=a,this.bindFrameBufferTexture(this.prevFrameBuffer,this.prevTexture),this.bindFrameBufferTexture(this.compFrameBuffer,this.compTexture)}this.updateGlobals(),this.frameNum>0&&this.renderToScreen()}},{key:\"setInternalMeshSize\",value:function(t,e){this.mesh_width=t,this.mesh_height=e,this.updateGlobals()}},{key:\"setOutputAA\",value:function(t){this.outputFXAA=t}},{key:\"updateGlobals\",value:function(){var t={pixelRatio:this.pixelRatio,textureRatio:this.textureRatio,texsizeX:this.texsizeX,texsizeY:this.texsizeY,mesh_width:this.mesh_width,mesh_height:this.mesh_height,aspectx:this.aspectx,aspecty:this.aspecty};this.presetEquationRunner.updateGlobals(t),this.prevPresetEquationRunner.updateGlobals(t),this.warpShader.updateGlobals(t),this.prevWarpShader.updateGlobals(t),this.compShader.updateGlobals(t),this.prevCompShader.updateGlobals(t),this.outputShader.updateGlobals(t),this.blurShader1.updateGlobals(t),this.blurShader2.updateGlobals(t),this.blurShader3.updateGlobals(t),this.basicWaveform.updateGlobals(t),this.customWaveforms.forEach(function(e){return e.updateGlobals(t)}),this.customShapes.forEach(function(e){return e.updateGlobals(t)}),this.prevCustomWaveforms.forEach(function(e){return e.updateGlobals(t)}),this.prevCustomShapes.forEach(function(e){return e.updateGlobals(t)}),this.darkenCenter.updateGlobals(t),this.innerBorder.updateGlobals(t),this.outerBorder.updateGlobals(t),this.motionVectors.updateGlobals(t),this.titleText.updateGlobals(t),this.blendPattern.updateGlobals(t),this.warpUVs=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)*2),this.warpColor=new Float32Array((this.mesh_width+1)*(this.mesh_height+1)*4)}},{key:\"calcTimeAndFPS\",value:function(t){var e;if(t)e=t;else{var i=performance.now();((e=(i-this.lastTime)/1e3)>1||e<0||this.frame<2)&&(e=1/30),this.lastTime=i}this.time+=1/this.fps,this.blending&&(this.blendProgress=(this.time-this.blendStartTime)/this.blendDuration,this.blendProgress>1&&(this.blending=!1));var s=this.timeHist[this.timeHist.length-1]+e;this.timeHist.push(s),this.timeHist.length>this.timeHistMax&&this.timeHist.shift();var r=this.timeHist.length/(s-this.timeHist[0]);if(Math.abs(r-this.fps)>3&&this.frame>this.timeHistMax)this.fps=r;else{this.fps=.93*this.fps+(1-.93)*r}}},{key:\"runPixelEquations\",value:function(t,e,i,s){for(var r=this.mesh_width,a=this.mesh_height,h=r+1,o=a+1,n=this.time*e.warpanimspeed,l=1/e.warpscale,m=11.68+4*Math.cos(1.413*n+10),u=8.77+3*Math.cos(1.113*n+7),g=10.54+3*Math.cos(1.233*n+3),A=11.49+4*Math.cos(.933*n+5),f=0/this.texsizeX,d=0/this.texsizeY,v=this.aspectx,p=this.aspecty,_=c.cloneVars(e),x=0,b=0,T=0;T<o;T++)for(var E=0;E<h;E++){var P=E/r*2-1,R=T/a*2-1,L=Math.sqrt(P*P*v*v+R*R*p*p);if(i){var S=void 0;S=T===a/2&&E===r/2?0:c.atan2(R*p,P*v),_.x=.5*P*v+.5,_.y=-.5*R*p+.5,_.rad=L,_.ang=S,_.zoom=e.zoom,_.zoomexp=e.zoomexp,_.rot=e.rot,_.warp=e.warp,_.cx=e.cx,_.cy=e.cy,_.dx=e.dx,_.dy=e.dy,_.sx=e.sx,_.sy=e.sy,_=t.pixel_eqs(_)}var y=_.warp,w=_.zoom,U=_.zoomexp,M=_.cx,F=_.cy,q=_.sx,z=_.sy,B=_.dx,C=_.dy,D=_.rot,V=1/Math.pow(w,Math.pow(U,2*L-1)),I=.5*P*v*V+.5,X=.5*-R*p*V+.5;I=(I-M)/q+M,X=(X-F)/z+F,0!==y&&(I+=.0035*y*Math.sin(.333*n+l*(P*m-R*A)),X+=.0035*y*Math.cos(.375*n-l*(P*g+R*u)),I+=.0035*y*Math.cos(.753*n-l*(P*u-R*g)),X+=.0035*y*Math.sin(.825*n+l*(P*m+R*A)));var k=I-M,N=X-F,O=Math.cos(D),W=Math.sin(D);if(I=k*O-N*W+M,X=k*W+N*O+F,I=((I-=B)-.5)/v+.5,X=((X-=C)-.5)/p+.5,I+=f,X+=d,s){var Q=this.blendPattern.vertInfoA[x/2]*this.blendProgress+this.blendPattern.vertInfoC[x/2];Q=Math.clamp(Q,0,1),this.warpUVs[x]=this.warpUVs[x]*Q+I*(1-Q),this.warpUVs[x+1]=this.warpUVs[x+1]*Q+X*(1-Q),this.warpColor[b+0]=1,this.warpColor[b+1]=1,this.warpColor[b+2]=1,this.warpColor[b+3]=Q}else this.warpUVs[x]=I,this.warpUVs[x+1]=X,this.warpColor[b+0]=1,this.warpColor[b+1]=1,this.warpColor[b+2]=1,this.warpColor[b+3]=1;x+=2,b+=4}this.mdVSVertex=_}},{key:\"bindFrambufferAndSetViewport\",value:function(t,e,i){this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,t),this.gl.viewport(0,0,e,i)}},{key:\"bindFrameBufferTexture\",value:function(t,e){if(this.gl.bindTexture(this.gl.TEXTURE_2D,e),this.gl.pixelStorei(this.gl.UNPACK_ALIGNMENT,1),this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,this.texsizeX,this.texsizeY,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,new Uint8Array(this.texsizeX*this.texsizeY*4)),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_S,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_WRAP_T,this.gl.CLAMP_TO_EDGE),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MIN_FILTER,this.gl.LINEAR_MIPMAP_LINEAR),this.gl.texParameteri(this.gl.TEXTURE_2D,this.gl.TEXTURE_MAG_FILTER,this.gl.LINEAR),this.anisoExt){var i=this.gl.getParameter(this.anisoExt.MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.gl.texParameterf(this.gl.TEXTURE_2D,this.anisoExt.TEXTURE_MAX_ANISOTROPY_EXT,i)}this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,t),this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER,this.gl.COLOR_ATTACHMENT0,this.gl.TEXTURE_2D,e,0)}},{key:\"render\",value:function(){var e=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},s=i.audioLevels,r=i.elapsedTime;this.calcTimeAndFPS(r),this.frameNum+=1,s?this.audio.updateAudio(s.timeByteArray,s.timeByteArrayL,s.timeByteArrayR):this.audio.sampleAudio(),this.audioLevels.updateAudioLevels(this.fps,this.frameNum);var a={frame:this.frameNum,time:this.time,fps:this.fps,bass:this.audioLevels.bass,bass_att:this.audioLevels.bass_att,mid:this.audioLevels.mid,mid_att:this.audioLevels.mid_att,treb:this.audioLevels.treb,treb_att:this.audioLevels.treb_att,meshx:this.mesh_width,meshy:this.mesh_height,aspectx:this.invAspectx,aspecty:this.invAspecty,pixelsx:this.texsizeX,pixelsy:this.texsizeY},h=Object.assign({},a);h.gmegabuf=this.prevPresetEquationRunner.gmegabuf,a.gmegabuf=this.presetEquationRunner.gmegabuf,Object.assign(a,this.regVars),this.presetEquationRunner.runFrameEquations(a);var o,n=this.presetEquationRunner.mdVSFrame;this.runPixelEquations(this.presetEquationRunner.preset,n,this.presetEquationRunner.runVertEQs,!1),Object.assign(this.regVars,c.pick(this.mdVSVertex,this.regs)),Object.assign(a,this.regVars),this.blending?(this.prevPresetEquationRunner.runFrameEquations(h),this.runPixelEquations(this.prevPresetEquationRunner.preset,this.prevPresetEquationRunner.mdVSFrame,this.prevPresetEquationRunner.runVertEQs,!0),o=t.mixFrameEquations(this.blendProgress,n,this.prevPresetEquationRunner.mdVSFrame)):o=n;var l=this.targetTexture;this.targetTexture=this.prevTexture,this.prevTexture=l;var m=this.targetFrameBuffer;this.targetFrameBuffer=this.prevFrameBuffer,this.prevFrameBuffer=m,this.gl.bindTexture(this.gl.TEXTURE_2D,this.prevTexture),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.bindFrambufferAndSetViewport(this.targetFrameBuffer,this.texsizeX,this.texsizeY),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.enable(this.gl.BLEND),this.gl.blendEquation(this.gl.FUNC_ADD),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA);var u=t.getBlurValues(o),g=u.blurMins,A=u.blurMaxs;this.blending?(this.prevWarpShader.renderQuadTexture(!1,this.prevTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,g,A,this.prevPresetEquationRunner.mdVSFrame,this.warpUVs,this.warpColor),this.warpShader.renderQuadTexture(!0,this.prevTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,g,A,o,this.warpUVs,this.warpColor)):this.warpShader.renderQuadTexture(!1,this.prevTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,g,A,n,this.warpUVs,this.warpColor),this.numBlurPasses>0&&(this.blurShader1.renderBlurTexture(this.targetTexture,n,g,A),this.numBlurPasses>1&&(this.blurShader2.renderBlurTexture(this.blurTexture1,n,g,A),this.numBlurPasses>2&&this.blurShader3.renderBlurTexture(this.blurTexture2,n,g,A)),this.bindFrambufferAndSetViewport(this.targetFrameBuffer,this.texsizeX,this.texsizeY)),this.motionVectors.drawMotionVectors(o,this.warpUVs),this.preset.shapes&&this.preset.shapes.length>0&&this.customShapes.forEach(function(t,i){t.drawCustomShape(e.blending?e.blendProgress:1,a,e.presetEquationRunner,e.preset.shapes[i],e.prevTexture)}),this.preset.waves&&this.preset.waves.length>0&&this.customWaveforms.forEach(function(t,i){t.drawCustomWaveform(e.blending?e.blendProgress:1,e.audio.timeArrayL,e.audio.timeArrayR,e.audio.freqArrayL,e.audio.freqArrayR,a,e.presetEquationRunner,e.preset.waves[i])}),this.blending&&(this.prevPreset.shapes&&this.prevPreset.shapes.length>0&&this.prevCustomShapes.forEach(function(t,i){t.drawCustomShape(1-e.blendProgress,h,e.prevPresetEquationRunner,e.prevPreset.shapes[i],e.prevTexture)}),this.prevPreset.waves&&this.prevPreset.waves.length>0&&this.prevCustomWaveforms.forEach(function(t,i){t.drawCustomWaveform(1-e.blendProgress,e.audio.timeArrayL,e.audio.timeArrayR,e.audio.freqArrayL,e.audio.freqArrayR,h,e.prevPresetEquationRunner,e.prevPreset.waves[i])})),this.basicWaveform.drawBasicWaveform(this.blending,this.blendProgress,this.audio.timeArrayL,this.audio.timeArrayR,o),this.darkenCenter.drawDarkenCenter(o);var f=[o.ob_r,o.ob_g,o.ob_b,o.ob_a];this.outerBorder.drawBorder(f,o.ob_size,0);var d=[o.ib_r,o.ib_g,o.ib_b,o.ib_a];if(this.innerBorder.drawBorder(d,o.ib_size,o.ob_size),this.supertext.startTime>=0){var v=(this.time-this.supertext.startTime)/this.supertext.duration;v>=1&&this.titleText.renderTitle(v,!0,a)}this.globalVars=a,this.mdVSFrame=n,this.mdVSFrameMixed=o,this.renderToScreen()}},{key:\"renderToScreen\",value:function(){this.outputFXAA?this.bindFrambufferAndSetViewport(this.compFrameBuffer,this.texsizeX,this.texsizeY):this.bindFrambufferAndSetViewport(null,this.width,this.height),this.gl.clear(this.gl.COLOR_BUFFER_BIT),this.gl.enable(this.gl.BLEND),this.gl.blendEquation(this.gl.FUNC_ADD),this.gl.blendFunc(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA);var e=t.getBlurValues(this.mdVSFrameMixed),i=e.blurMins,s=e.blurMaxs;if(this.blending?(this.prevCompShader.renderQuadTexture(!1,this.targetTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,i,s,this.prevPresetEquationRunner.mdVSFrame,this.warpColor),this.compShader.renderQuadTexture(!0,this.targetTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,i,s,this.mdVSFrameMixed,this.warpColor)):this.compShader.renderQuadTexture(!1,this.targetTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,i,s,this.mdVSFrame,this.warpColor),this.supertext.startTime>=0){var r=(this.time-this.supertext.startTime)/this.supertext.duration;this.titleText.renderTitle(r,!1,this.globalVars),r>=1&&(this.supertext.startTime=-1)}this.outputFXAA&&(this.gl.bindTexture(this.gl.TEXTURE_2D,this.compTexture),this.gl.generateMipmap(this.gl.TEXTURE_2D),this.bindFrambufferAndSetViewport(null,this.width,this.height),this.outputShader.renderQuadTexture(this.compTexture))}},{key:\"launchSongTitleAnim\",value:function(t){this.supertext={startTime:this.time,duration:1.7},this.titleText.generateTitleTexture(t)}},{key:\"toDataURL\",value:function(){var e=this,i=new Uint8Array(this.texsizeX*this.texsizeY*4),s=this.gl.createFramebuffer(),r=this.gl.createTexture();this.bindFrameBufferTexture(s,r);var a=t.getBlurValues(this.mdVSFrameMixed),h=a.blurMins,o=a.blurMaxs;this.compShader.renderQuadTexture(!1,this.targetTexture,this.blurTexture1,this.blurTexture2,this.blurTexture3,h,o,this.mdVSFrame,this.warpColor),this.gl.readPixels(0,0,this.texsizeX,this.texsizeY,this.gl.RGBA,this.gl.UNSIGNED_BYTE,i),Array.from({length:this.texsizeY},function(t,s){return i.slice(s*e.texsizeX*4,(s+1)*e.texsizeX*4)}).forEach(function(t,s){return i.set(t,(e.texsizeY-s-1)*e.texsizeX*4)});var n=document.createElement(\"canvas\");n.width=this.texsizeX,n.height=this.texsizeY;var l=n.getContext(\"2d\"),m=l.createImageData(this.texsizeX,this.texsizeY);return m.data.set(i),l.putImageData(m,0,0),this.gl.deleteTexture(r),this.gl.deleteFramebuffer(s),n.toDataURL()}},{key:\"warpBufferToDataURL\",value:function(){var t=new Uint8Array(this.texsizeX*this.texsizeY*4);this.gl.bindFramebuffer(this.gl.FRAMEBUFFER,this.targetFrameBuffer),this.gl.readPixels(0,0,this.texsizeX,this.texsizeY,this.gl.RGBA,this.gl.UNSIGNED_BYTE,t);var e=document.createElement(\"canvas\");e.width=this.texsizeX,e.height=this.texsizeY;var i=e.getContext(\"2d\"),s=i.createImageData(this.texsizeX,this.texsizeY);return s.data.set(t),i.putImageData(s,0,0),e.toDataURL()}}])&&it(e.prototype,i),s&&it(e,s),t}();function rt(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}var at=function(){function t(e,i,s){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t),this.audio=new h(e);var r=i.getContext(\"webgl2\",{alpha:!1,antialias:!1,depth:!1,stencil:!1,premultipliedAlpha:!1});this.baseValsDefaults={decay:.98,gammaadj:2,echo_zoom:2,echo_alpha:0,echo_orient:0,red_blue:0,brighten:0,darken:0,wrap:1,darken_center:0,solarize:0,invert:0,fshader:0,b1n:0,b2n:0,b3n:0,b1x:1,b2x:1,b3x:1,b1ed:.25,wave_mode:0,additivewave:0,wave_dots:0,wave_thick:0,wave_a:.8,wave_scale:1,wave_smoothing:.75,wave_mystery:0,modwavealphabyvolume:0,modwavealphastart:.75,modwavealphaend:.95,wave_r:1,wave_g:1,wave_b:1,wave_x:.5,wave_y:.5,wave_brighten:1,mv_x:12,mv_y:9,mv_dx:0,mv_dy:0,mv_l:.9,mv_r:1,mv_g:1,mv_b:1,mv_a:1,warpanimspeed:1,warpscale:1,zoomexp:1,zoom:1,rot:0,cx:.5,cy:.5,dx:0,dy:0,warp:1,sx:1,sy:1,ob_size:.01,ob_r:0,ob_g:0,ob_b:0,ob_a:0,ib_size:.01,ib_r:.25,ib_g:.25,ib_b:.25,ib_a:0},this.shapeBaseValsDefaults={enabled:0,sides:4,additive:0,thickoutline:0,textured:0,num_inst:1,tex_zoom:1,tex_ang:0,x:.5,y:.5,rad:.1,ang:0,r:1,g:0,b:0,a:1,r2:0,g2:1,b2:0,a2:0,border_r:1,border_g:1,border_b:1,border_a:.1},this.waveBaseValsDefaults={enabled:0,samples:512,sep:0,scaling:1,smoothing:.5,r:1,g:1,b:1,a:1,spectrum:0,usedots:0,thick:0,additive:0},this.renderer=new st(r,this.audio,s)}var e,i,s;return e=t,(i=[{key:\"connectAudio\",value:function(t){this.audioNode=t,this.audio.connectAudio(t)}},{key:\"disconnectAudio\",value:function(t){this.audio.disconnectAudio(t)}},{key:\"loadPreset\",value:function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=Object.assign({},t);i.baseVals=Object.assign({},this.baseValsDefaults,i.baseVals);for(var s=0;s<i.shapes.length;s++)i.shapes[s].baseVals=Object.assign({},this.shapeBaseValsDefaults,i.shapes[s].baseVals);for(var r=0;r<i.waves.length;r++)i.waves[r].baseVals=Object.assign({},this.waveBaseValsDefaults,i.waves[r].baseVals);if(\"function\"!=typeof i.init_eqs){i.init_eqs=new Function(\"a\",\"\".concat(i.init_eqs_str,\" return a;\")),i.frame_eqs=new Function(\"a\",\"\".concat(i.frame_eqs_str,\" return a;\")),i.pixel_eqs_str&&\"\"!==i.pixel_eqs_str?i.pixel_eqs=new Function(\"a\",\"\".concat(i.pixel_eqs_str,\" return a;\")):i.pixel_eqs=\"\";for(var a=0;a<i.shapes.length;a++)0!==i.shapes[a].baseVals.enabled&&(i.shapes[a]=Object.assign({},i.shapes[a],{init_eqs:new Function(\"a\",\"\".concat(i.shapes[a].init_eqs_str,\" return a;\")),frame_eqs:new Function(\"a\",\"\".concat(i.shapes[a].frame_eqs_str,\" return a;\"))}));for(var h=0;h<i.waves.length;h++)if(0!==i.waves[h].baseVals.enabled){var o={init_eqs:new Function(\"a\",\"\".concat(i.waves[h].init_eqs_str,\" return a;\")),frame_eqs:new Function(\"a\",\"\".concat(i.waves[h].frame_eqs_str,\" return a;\"))};i.waves[h].point_eqs_str&&\"\"!==i.waves[h].point_eqs_str?o.point_eqs=new Function(\"a\",\"\".concat(i.waves[h].point_eqs_str,\" return a;\")):o.point_eqs=\"\",i.waves[h]=Object.assign({},i.waves[h],o)}}this.renderer.loadPreset(i,e)}},{key:\"loadExtraImages\",value:function(t){this.renderer.loadExtraImages(t)}},{key:\"setRendererSize\",value:function(t,e){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.renderer.setRendererSize(t,e,i)}},{key:\"setInternalMeshSize\",value:function(t,e){this.renderer.setInternalMeshSize(t,e)}},{key:\"setOutputAA\",value:function(t){this.renderer.setOutputAA(t)}},{key:\"render\",value:function(t){this.renderer.render(t)}},{key:\"launchSongTitleAnim\",value:function(t){this.renderer.launchSongTitleAnim(t)}},{key:\"toDataURL\",value:function(){return this.renderer.toDataURL()}},{key:\"warpBufferToDataURL\",value:function(){return this.renderer.warpBufferToDataURL()}}])&&rt(e.prototype,i),s&&rt(e,s),t}();function ht(t,e){for(var i=0;i<e.length;i++){var s=e[i];s.enumerable=s.enumerable||!1,s.configurable=!0,\"value\"in s&&(s.writable=!0),Object.defineProperty(t,s.key,s)}}i.d(e,\"default\",function(){return ot});var ot=function(){function t(){!function(t,e){if(!(t instanceof e))throw new TypeError(\"Cannot call a class as a function\")}(this,t)}var e,i,s;return e=t,s=[{key:\"createVisualizer\",value:function(t,e,i){return new at(t,e,i)}}],(i=null)&&ht(e.prototype,i),s&&ht(e,s),t}()}])});\n//# sourceMappingURL=butterchurn.min.js.map","vendor/butterchurn/presets-2.4.7.min.js":"!function(a,e){\"object\"==typeof exports&&\"object\"==typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(\"butterchurnPresets\",[],e):\"object\"==typeof exports?exports.butterchurnPresets=e():a.butterchurnPresets=e()}(\"undefined\"!=typeof self?self:this,function(){return function(a){var e={};function t(r){if(e[r])return e[r].exports;var n=e[r]={i:r,l:!1,exports:{}};return a[r].call(n.exports,n,n.exports,t),n.l=!0,n.exports}return t.m=a,t.c=e,t.d=function(a,e,r){t.o(a,e)||Object.defineProperty(a,e,{configurable:!1,enumerable:!0,get:r})},t.n=function(a){var e=a&&a.__esModule?function(){return a.default}:function(){return a};return t.d(e,\"a\",e),e},t.o=function(a,e){return Object.prototype.hasOwnProperty.call(a,e)},t.p=\"\",t(t.s=165)}([function(a,e,t){a.exports=!t(5)(function(){return 7!=Object.defineProperty({},\"a\",{get:function(){return 7}}).a})},function(a,e){a.exports=function(a){return\"object\"==typeof a?null!==a:\"function\"==typeof a}},function(a,e){var t=a.exports=\"undefined\"!=typeof window&&window.Math==Math?window:\"undefined\"!=typeof self&&self.Math==Math?self:Function(\"return this\")();\"number\"==typeof __g&&(__g=t)},function(a,e){var t=a.exports={version:\"2.5.3\"};\"number\"==typeof __e&&(__e=t)},function(a,e,t){var r=t(15),n=t(16),_=t(18),s=Object.defineProperty;e.f=t(0)?Object.defineProperty:function(a,e,t){if(r(a),e=_(e,!0),r(t),n)try{return s(a,e,t)}catch(a){}if(\"get\"in t||\"set\"in t)throw TypeError(\"Accessors not supported!\");return\"value\"in t&&(a[e]=t.value),a}},function(a,e){a.exports=function(a){try{return!!a()}catch(a){return!0}}},function(a,e,t){\"use strict\";e.__esModule=!0,e.default=function(a,e){if(!(a instanceof e))throw new TypeError(\"Cannot call a class as a function\")}},function(a,e,t){\"use strict\";e.__esModule=!0;var r,n=t(8),_=(r=n)&&r.__esModule?r:{default:r};e.default=function(){function a(a,e){for(var t=0;t<e.length;t++){var r=e[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),(0,_.default)(a,r.key,r)}}return function(e,t,r){return t&&a(e.prototype,t),r&&a(e,r),e}}()},function(a,e,t){a.exports={default:t(9),__esModule:!0}},function(a,e,t){t(10);var r=t(3).Object;a.exports=function(a,e,t){return r.defineProperty(a,e,t)}},function(a,e,t){var r=t(11);r(r.S+r.F*!t(0),\"Object\",{defineProperty:t(4).f})},function(a,e,t){var r=t(2),n=t(3),_=t(12),s=t(14),v=function(a,e,t){var m,i,p,b=a&v.F,l=a&v.G,x=a&v.S,o=a&v.P,d=a&v.B,u=a&v.W,c=l?n:n[e]||(n[e]={}),y=c.prototype,h=l?r:x?r[e]:(r[e]||{}).prototype;for(m in l&&(t=e),t)(i=!b&&h&&void 0!==h[m])&&m in c||(p=i?h[m]:t[m],c[m]=l&&\"function\"!=typeof h[m]?t[m]:d&&i?_(p,r):u&&h[m]==p?function(a){var e=function(e,t,r){if(this instanceof a){switch(arguments.length){case 0:return new a;case 1:return new a(e);case 2:return new a(e,t)}return new a(e,t,r)}return a.apply(this,arguments)};return e.prototype=a.prototype,e}(p):o&&\"function\"==typeof p?_(Function.call,p):p,o&&((c.virtual||(c.virtual={}))[m]=p,a&v.R&&y&&!y[m]&&s(y,m,p)))};v.F=1,v.G=2,v.S=4,v.P=8,v.B=16,v.W=32,v.U=64,v.R=128,a.exports=v},function(a,e,t){var r=t(13);a.exports=function(a,e,t){if(r(a),void 0===e)return a;switch(t){case 1:return function(t){return a.call(e,t)};case 2:return function(t,r){return a.call(e,t,r)};case 3:return function(t,r,n){return a.call(e,t,r,n)}}return function(){return a.apply(e,arguments)}}},function(a,e){a.exports=function(a){if(\"function\"!=typeof a)throw TypeError(a+\" is not a function!\");return a}},function(a,e,t){var r=t(4),n=t(19);a.exports=t(0)?function(a,e,t){return r.f(a,e,n(1,t))}:function(a,e,t){return a[e]=t,a}},function(a,e,t){var r=t(1);a.exports=function(a){if(!r(a))throw TypeError(a+\" is not an object!\");return a}},function(a,e,t){a.exports=!t(0)&&!t(5)(function(){return 7!=Object.defineProperty(t(17)(\"div\"),\"a\",{get:function(){return 7}}).a})},function(a,e,t){var r=t(1),n=t(2).document,_=r(n)&&r(n.createElement);a.exports=function(a){return _?n.createElement(a):{}}},function(a,e,t){var r=t(1);a.exports=function(a,e){if(!r(a))return a;var t,n;if(e&&\"function\"==typeof(t=a.toString)&&!r(n=t.call(a)))return n;if(\"function\"==typeof(t=a.valueOf)&&!r(n=t.call(a)))return n;if(!e&&\"function\"==typeof(t=a.toString)&&!r(n=t.call(a)))return n;throw TypeError(\"Can't convert object to primitive value\")}},function(a,e){a.exports=function(a,e){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:e}}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.42,decay:1,echo_zoom:.999823,echo_alpha:.5,echo_orient:1,wave_mode:5,wave_thick:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001185,wave_scale:.325446,wave_smoothing:.9,modwavealphastart:.5,modwavealphaend:1,warpanimspeed:2.630064,warpscale:3.209168,zoomexp:1.000158,dx:1e-5,dy:1e-5,warp:.01,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.005,ob_a:.5,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:.1,mv_x:6.4,mv_y:4.8,mv_l:5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.thresh=0;a.dx_r=0;a.dy_r=0;a.tg1=0;a.tg2=0;a.tg3=0;a.six=0;\",frame_eqs_str:\"a.wave_r=.5+.5*Math.sin(1.6*a.time);a.wave_g=.5+.5*Math.sin(4.1*a.time);a.wave_b=-1+(1-a.wave_r+1-a.wave_g);a.warp=2;a.ob_r+=a.wave_b*above(Math.sin(.1*a.time),0);a.ob_b+=a.wave_g*above(Math.sin(.1*a.time),0);a.ob_g+=a.wave_r*above(Math.sin(.1*a.time),0);a.ob_r+=a.wave_g*below(Math.sin(.1*a.time),0);a.ob_b+=a.wave_r*below(Math.sin(.1*a.time),0);a.ob_g+=a.wave_b*below(Math.sin(.1*a.time),0);\",pixel_eqs_str:\"a.thresh=2*above(a.bass_att,a.thresh)+(1-above(a.bass_att,a.thresh))*(.96*(a.thresh-1.3)+1.3);a.dx_r=.05*equal(a.thresh,2)*Math.sin(5*a.time)+(1-equal(a.thresh,2))*a.dx_r;a.dy_r=.056*equal(a.thresh,2)*Math.sin(6*a.time)+(1-equal(a.thresh,2))*a.dy_r;a.tg1=Math.abs(Math.sin(a.time));a.tg2=22*above(a.tg1,.75)+12*below(a.tg1,.25)+18*above(a.tg1,.25)*below(a.tg1,.5)+12*above(a.tg1,.5)*below(a.tg1,.75);a.tg3=.00001<Math.abs(equal(a.thresh,2))?a.tg2:a.tg3;a.six=Math.sin(a.x);a.dx+=\\na.dx_r*Math.sin(Math.abs(a.tg3*a.y))*Math.sin(a.time);a.dy+=a.dy_r*Math.sin(Math.abs(a.tg3*a.x))*Math.cos(a.time);a.dx+=a.dx_r*pow(a.rad,2*a.y)*Math.sin(a.time);a.dy+=a.dy_r*pow(a.rad,2*a.x)*Math.sin(a.time);a.zoom-=.0825*pow(a.rad,6*a.x)*Math.cos(6*a.ang);a.rot-=.039375*Math.sin(1.25*a.time)*pow(a.rad,a.x)*Math.sin(1.45*a.time)*Math.sin(a.time);\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:1,echo_orient:1,wave_mode:5,wave_brighten:0,wave_a:.001,wave_scale:1.447722,wave_smoothing:.5,modwavealphastart:.5,modwavealphaend:1,fshader:1,dx:1e-5,dy:1e-5,warp:.01,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.015,ob_a:1,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:0,mv_y:0,mv_l:1,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.pfdx_r=0;a.pfthresh=0;a.thresh=0;a.ladder=0;a.q1=0;a.leafset=0;a.dy_r=0;a.pfdy_r=0;a.leaf=0;a.dx_r=0;a.q2=0;a.q3=0;a.leafset=3;\",frame_eqs_str:\"a.wave_r=.5+.5*Math.sin(1.6*a.time);a.wave_g=.5+.5*Math.sin(4.1*a.time);a.wave_b=-1+(1-a.wave_r+1-a.wave_g);a.warp=0;a.pfthresh=3*above(a.bass_att,a.pfthresh)+(1-above(a.bass_att,a.pfthresh))*(.96*(a.pfthresh-1.3)+1.3);a.pfdx_r=.015*equal(a.pfthresh,3)*Math.sin(5*a.time)+(1-equal(a.pfthresh,3))*a.pfdx_r;a.pfdy_r=.015*equal(a.pfthresh,3)*Math.sin(6*a.time)+(1-equal(a.pfthresh,3))*a.pfdy_r;a.q1=a.wave_r;a.q2=a.wave_g;a.q3=a.wave_b;a.ob_r=1-.75*Math.abs(a.q1);a.ob_g=1-.75*Math.abs(a.q2);\\na.ob_b=1-.75*Math.abs(a.q3);a.echo_zoom+=Math.min(Math.max(.75,50*a.pfdx_r),1);a.echo_orient+=16*a.pfdy_r;a.dx+=15.1*a.pfdx_r;a.dy+=15.1*a.pfdy_r;a.ob_size+=.005*a.bass_att;a.ib_a-=Math.min(.5,.5-Math.abs(a.dx+a.dy));\",pixel_eqs_str:\"a.thresh=2*above(a.bass_att,a.thresh)+(1-above(a.bass_att,a.thresh))*(.96*(a.thresh-1.3)+1.3);a.dx_r=.015*equal(a.thresh,2)*Math.sin(5*a.time)+(1-equal(a.thresh,2))*a.dx_r;a.dy_r=.015*equal(a.thresh,2)*Math.sin(6*a.time)+(1-equal(a.thresh,2))*a.dy_r;a.ladder=Math.abs(Math.sin(1*a.time));a.leaf=5*below(a.ladder,.2)+8*above(a.ladder,.2)*below(a.ladder,.4)+12*above(a.ladder,.4)*below(a.ladder,.6)+18*above(a.ladder,.6)*below(a.ladder,.8)+24*above(a.ladder,.8);a.leafset=.00001<Math.abs(equal(a.thresh,\\n2))?a.leaf:a.leafset;a.zoom+=.05*(.75-Math.cos(a.leafset*a.rad))*(1-a.rad);a.zoom-=Math.abs(.05*(.75-Math.cos(4*a.rad)));\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:.96,echo_zoom:.99663,echo_orient:1,wave_mode:2,wave_dots:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.011726,wave_smoothing:.9,warpanimspeed:.010284,warpscale:.01,warp:.01,wave_r:.5,wave_g:.4,wave_b:.3,ob_size:0,ob_r:.11,ob_b:.1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:64,mv_y:48,mv_l:5,mv_r:0,mv_g:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:32,additive:1,rad:.194774,r:0,b:1,a:1e-6,r2:.63,g2:.7,b2:1,a2:.07,border_a:0},init_eqs_str:\"a.lens_scale=0;a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.pos_scale=0;a.cubesize=0;a.xq=0;a.sang=0;a.flip=0;a.zq=0;a.tm=0;a.zp=0;a.q2=0;a.sample=0;a.q8=0;a.flip=1;\",frame_eqs_str:\"a.flip=-a.flip;a.lens_scale=.5*a.flip+.5;a.lens_scale=1+2.4*a.lens_scale;a.pos_scale=.00001<Math.abs(equal(a.flip,-1))?.5:a.lens_scale;a.t1=.25*a.q1;a.sample=1;a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.tm=4*a.q1+4*a.sample;a.xp=Math.sin(a.tm)*Math.cos(3*a.tm)*.5+.5;a.yp=Math.sin(1.1*a.tm)*Math.sin(4.1*a.tm)*.5+.5;a.zp=Math.sin(2.9*a.tm)*Math.cos(1.77*a.tm)*.5+.5;a.xp=div(Math.floor(a.xp*a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(Math.floor(a.yp*a.cubesize),\\na.cubesize)-.5+a.fix;a.zp=div(Math.floor(a.zp*a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp*a.sang+a.zp*a.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(-a.xp,a.zp)*a.pos_scale+.5;a.y=div(-a.yp,a.zp)*a.pos_scale*1.333+.5;a.rad=a.rad*(1+div(a.q8,\\n3))*a.lens_scale;\"},{baseVals:{enabled:1,sides:6,rad:.043785,r:.3,g:.6,b:1,g2:0,b2:1,border_a:0},init_eqs_str:\"a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.cubesize=0;a.xq=0;a.sang=0;a.zq=0;a.tm=0;a.zp=0;a.q2=0;a.sample=0;a.q8=0;\",frame_eqs_str:\"a.t1=.25*a.q1;a.sample=1;a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.tm=4*a.q1+4*a.sample;a.xp=Math.sin(a.tm)*Math.cos(3*a.tm)*.5+.5;a.yp=Math.sin(1.1*a.tm)*Math.sin(4.1*a.tm)*.5+.5;a.zp=Math.sin(2.9*a.tm)*Math.cos(1.77*a.tm)*.5+.5;a.xp=div(Math.floor(a.xp*a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(Math.floor(a.yp*a.cubesize),a.cubesize)-.5+a.fix;a.zp=div(Math.floor(a.zp*a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);\\na.xq=a.xp*a.sang+a.zp*a.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(a.xp,a.zp)+.5;a.y=1.333*div(a.yp,a.zp)+.5;a.a=Math.min(a.a+div(a.q8,2),1);a.r=Math.min(a.r*(1+a.q8),1);a.g=Math.min(a.g*(1+a.q8),1);a.r2=Math.min(div(a.q8,2),1);a.g2=Math.min(div(a.q8,4),1);a.rad*=1+div(a.q8,7);\"},{baseVals:{enabled:1,sides:36,rad:.284278,r:0,a:0,r2:.23,g2:.54,b2:1,a2:.05,border_g:.8,border_b:.4,border_a:.45},init_eqs_str:\"a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.cubesize=0;a.xq=0;a.sang=0;a.zq=0;a.tm=0;a.zp=0;a.q2=0;a.sample=0;a.q8=0;\",frame_eqs_str:\"a.t1=.25*a.q1;a.sample=1;a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.tm=4*a.q1+4*a.sample;a.xp=Math.sin(a.tm)*Math.cos(3*a.tm)*.5+.5;a.yp=Math.sin(1.1*a.tm)*Math.sin(4.1*a.tm)*.5+.5;a.zp=Math.sin(2.9*a.tm)*Math.cos(1.77*a.tm)*.5+.5;a.xp=div(Math.floor(a.xp*a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(Math.floor(a.yp*a.cubesize),a.cubesize)-.5+a.fix;a.zp=div(Math.floor(a.zp*a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);\\na.xq=a.xp*a.sang+a.zp*a.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(a.xp,a.zp)+.5;a.y=1.333*div(a.yp,a.zp)+.5;a.a2=Math.min(a.a2*(1+div(a.q8,2)),1);a.r2=Math.min(a.r2*(1+div(a.q8,4)),1);a.g2=Math.min(a.g2*(1+div(a.q8,3)),1);a.border_a=Math.min(a.border_a*(1+a.q8),1);\"},{baseVals:{enabled:1,sides:6,additive:1,rad:.158045,r:.3,g:.6,b:1,a:.140001,r2:.4,g2:.5,b2:1,border_a:0},init_eqs_str:\"a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.cubesize=0;a.xq=0;a.sang=0;a.zq=0;a.tm=0;a.zp=0;a.q2=0;a.sample=0;a.q8=0;\",frame_eqs_str:\"a.t1=.25*a.q1;a.sample=1;a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.tm=4*a.q1+4*a.sample;a.xp=Math.sin(a.tm)*Math.cos(3*a.tm)*.5+.5;a.yp=Math.sin(1.1*a.tm)*Math.sin(4.1*a.tm)*.5+.5;a.zp=Math.sin(2.9*a.tm)*Math.cos(1.77*a.tm)*.5+.5;a.xp=div(Math.floor(a.xp*a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(Math.floor(a.yp*a.cubesize),a.cubesize)-.5+a.fix;a.zp=div(Math.floor(a.zp*a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);\\na.xq=a.xp*a.sang+a.zp*a.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(a.xp,a.zp)+.5;a.y=1.333*div(a.yp,a.zp)+.5;a.a=Math.min(a.a*a.q8,1);a.rad*=1+a.q8;\"}],waves:[{baseVals:{enabled:1,thick:1,additive:1,r:.05,g:.09},init_eqs_str:\"a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.cubesize=0;a.xq=0;a.sang=0;a.zq=0;a.ang=0;a.tm=0;a.zp=0;a.q2=0;\",frame_eqs_str:\"a.t1=.25*a.q1;\",point_eqs_str:\"a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.tm=4*a.q1+4*a.sample;a.xp=Math.sin(a.tm)*Math.cos(3*a.tm)*.5+.5;a.yp=Math.sin(1.1*a.tm)*Math.sin(4.1*a.tm)*.5+.5;a.zp=Math.sin(2.9*a.tm)*Math.cos(1.77*a.tm)*.5+.5;a.xp=div(Math.floor(a.xp*a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(Math.floor(a.yp*a.cubesize),a.cubesize)-.5+a.fix;a.zp=div(Math.floor(a.zp*a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp*a.sang+a.zp*\\na.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(a.xp,a.zp)+.5;a.y=1.333*div(a.yp,a.zp)+.5;\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,usedots:1,thick:1},init_eqs_str:\"a.cang=0;a.n=0;a.yq=0;a.xp=0;a.fix=0;a.yp=0;a.t1=0;a.q1=0;a.cubesize=0;a.xq=0;a.sang=0;a.zq=0;a.ang=0;a.zp=0;a.q2=0;\",frame_eqs_str:\"a.t1=.25*a.q1;\",point_eqs_str:\"a.n=6.283*a.sample;a.cubesize=a.q2;a.fix=.5*div(1,a.cubesize);a.xp=div(randint(a.cubesize),a.cubesize)-.5+a.fix;a.yp=div(randint(a.cubesize),a.cubesize)-.5+a.fix;a.zp=div(randint(a.cubesize),a.cubesize)-.5+a.fix;a.ang=a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp*a.sang+a.zp*a.cang;a.yq=a.yp;a.zq=a.xp*a.cang-a.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.ang=.75*a.t1;a.sang=Math.sin(a.ang);a.cang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sang+a.zp*a.cang;a.zq=a.yp*a.cang-\\na.zp*a.sang;a.xp=a.xq;a.yp=a.yq;a.zp=a.zq;a.zp+=2;a.x=div(a.xp,a.zp)+.5;a.y=1.333*div(a.yp,a.zp)+.5;\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.q1=0;a.beat=0;a.vol=0;a.bc=0;a.size=0;a.q2=0;a.trigger=0;a.q7=0;a.mtime=0;a.q8=0;a.mv_x=64;a.mv_y=48;a.nut=0;a.stp=0;a.stq=0;a.rtp=0;a.rtq=0;a.wvr=0;a.decay=0;a.dcsp=0;a.size=4;a.bc=0;\",frame_eqs_str:\"a.decay=.95;a.zoom=1.005;a.vol=.25*(a.bass+a.mid+a.treb);a.vol*=a.vol;a.q8=a.vol;a.mtime+=.01*a.vol*div(75,a.fps);a.q7=a.mtime;a.monitor=div(512,8);a.warp=0;a.q1=.9*a.mtime;a.beat=above(a.vol,1);a.bc=Math.max(a.bc,0);a.bc=.00001<Math.abs(equal(a.bc,0))?a.bc+a.beat:a.bc-div(div(1,a.fps),4);a.trigger=equal(a.bc,1);a.monitor=a.size;a.size+=a.trigger;a.size=.00001<Math.abs(above(a.size,10))?4:a.size;a.q2=Math.floor(a.size);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:5,decay:.95,echo_zoom:1.006596,echo_orient:1,wave_mode:2,wave_dots:1,wave_brighten:0,wave_a:.019788,wave_scale:.011726,wave_smoothing:.9,warpanimspeed:.010284,warpscale:.01,fshader:1,warp:.01,wave_r:.5,wave_g:.4,wave_b:.3,ob_size:0,ob_r:.11,ob_b:.1,ib_size:.005,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:31.999994,mv_y:24.000004,mv_dx:.02,mv_dy:-.02,mv_l:1,mv_r:.49,mv_g:.48,mv_b:.300001,mv_a:0},shapes:[{baseVals:{enabled:1,textured:1,rad:1.670888,tex_ang:.942478,tex_zoom:.534261,g:1,b:1,r2:1,b2:1,a2:1,border_a:.17},init_eqs_str:\"a.flux=0;a.q5=0;a.fluxs=0;a.advflux=0;a.q3=0;a.adv=0;a.advs=0;\",frame_eqs_str:\"a.flux=9*a.q5;a.fluxs=Math.max(a.flux,0);a.fluxs=Math.min(a.fluxs,1);a.advflux=a.q3*a.fluxs+-a.q3*(1-a.fluxs);a.adv+=a.advflux;a.advs=div(a.adv,256);a.ang=a.advs;a.rad=1.671+div(a.q3,25);\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:3,x:.59,rad:.444842,r:0,r2:.1,g2:.05,border_a:0},init_eqs_str:\"a.rotator=0;a.dir=0;a.mover=0;a.dir=3;a.mover=0;a.rotator=.255;\",frame_eqs_str:\"a.ang=a.rotator;a.x=.00001<Math.abs(equal(a.dir,1))?1-a.mover:.00001<Math.abs(equal(a.dir,1.5))?.15:.00001<Math.abs(equal(a.dir,2))?0:.00001<Math.abs(equal(a.dir,2.5))?0:.00001<Math.abs(equal(a.dir,3))?0+a.mover:.00001<Math.abs(equal(a.dir,3.5))?1:(equal(a.dir,4),1);a.y=.00001<Math.abs(equal(a.dir,1))?1:.00001<Math.abs(equal(a.dir,1.5))?1:.00001<Math.abs(equal(a.dir,2))?1-a.mover:.00001<Math.abs(equal(a.dir,2.5))?0:.00001<Math.abs(equal(a.dir,3))?0:.00001<Math.abs(equal(a.dir,\\n3.5))?0:.00001<Math.abs(equal(a.dir,4))?0+a.mover:1;a.mover=.00001<Math.abs(equal(a.dir,1))?a.mover+.005:.00001<Math.abs(equal(a.dir,1.5))?0:.00001<Math.abs(equal(a.dir,2))?a.mover+.005:.00001<Math.abs(equal(a.dir,2.5))?0:.00001<Math.abs(equal(a.dir,3))?a.mover+.005:.00001<Math.abs(equal(a.dir,3.5))?0:.00001<Math.abs(equal(a.dir,4))?a.mover+.005:0;a.dir=.00001<Math.abs(equal(a.dir,1))?.00001<Math.abs(above(a.mover,.995))?1.5:a.dir:.00001<Math.abs(equal(a.dir,1.5))?.00001<Math.abs(below(a.rotator,\\n-1.29))?2:a.dir:.00001<Math.abs(equal(a.dir,2))?.00001<Math.abs(above(a.mover,.995))?2.5:a.dir:.00001<Math.abs(equal(a.dir,2.5))?.00001<Math.abs(below(a.rotator,-2.85))?3:a.dir:.00001<Math.abs(equal(a.dir,3))?.00001<Math.abs(above(a.mover,.995))?3.5:a.dir:.00001<Math.abs(equal(a.dir,3.5))?.00001<Math.abs(below(a.rotator,-4.44))?4:a.dir:.00001<Math.abs(equal(a.dir,4))?.00001<Math.abs(above(a.mover,.995))?4.5:a.dir:.00001<Math.abs(equal(a.dir,4.5))?.00001<Math.abs(below(a.rotator,-5.94))?1:a.dir:a.dir;\\na.rotator=.00001<Math.abs(equal(a.dir,1.5))?.00001<Math.abs(above(a.rotator,-1.31))?a.rotator-.05:a.rotator:.00001<Math.abs(equal(a.dir,2))?-1.3:.00001<Math.abs(equal(a.dir,2.5))?.00001<Math.abs(above(a.rotator,-2.87))?a.rotator-.05:a.rotator:.00001<Math.abs(equal(a.dir,3))?-2.86:.00001<Math.abs(equal(a.dir,3.5))?.00001<Math.abs(above(a.rotator,-4.46))?a.rotator-.05:a.rotator:.00001<Math.abs(equal(a.dir,4))?-4.45:.00001<Math.abs(equal(a.dir,4.5))?.00001<Math.abs(above(a.rotator,-5.97))?a.rotator-\\n.05:a.rotator:.00001<Math.abs(equal(a.dir,4))?-5.96:.26;a.b=above(a.mid,1.5);a.r2=above(a.mid,1.5);a.g2=above(a.mid,1.5);a.b2=above(a.mid,1.5);\"},{baseVals:{enabled:1,sides:3,additive:1,x:.84,r:.98,g:1,b:.98,a:.3,g2:.09,border_a:0},init_eqs_str:\"a.q1=0;\",frame_eqs_str:\"a.x=.4*Math.sin(div(a.time,2))+.5;a.y=.4*Math.sin(a.time)+.5;a.rad=div(a.q1*a.q1,2);a.ang=4*a.q1;a.r=.7+.5*Math.sin(div(a.time,2));a.g=.7+.5*Math.sin(div(a.time,2)+2);a.b=.7+.5*Math.sin(div(a.time,2)+4);\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.speedinv=0;a.q1=0;a.q5=0;a.flux=0;a.q4=0;a.q2=0;a.qb=0;a.speed=0;a.qc=0;a.q3=0;a.qa=0;a.mv_x=64;a.mv_y=48;a.nut=0;a.stp=0;a.stq=0;a.rtp=0;a.rtq=0;a.wvr=0;a.decay=0;a.dcsp=0;a.q1=0;a.q2=0;a.q3=0;\",frame_eqs_str:\"a.decay=1;a.zoom=1;a.speed=.8;a.speedinv=1-a.speed;a.q1=a.qa*a.speed+a.bass*a.speedinv;a.q2=a.qb*a.speed+a.mid*a.speedinv;a.q3=a.qc*a.speed+a.treb*a.speedinv;a.qa=a.q1;a.qb=a.q2;a.qc=a.q3;a.flux=Math.sin(div(a.time,2));a.q4=.5*a.flux+.5;a.q5=a.flux;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.21,decay:.96,echo_zoom:.99663,echo_orient:1,wave_mode:2,wave_dots:1,wave_brighten:0,brighten:1,invert:1,wave_a:.001,wave_scale:.011726,wave_smoothing:.9,warpanimspeed:.037492,warpscale:.014889,warp:.033004,wave_r:.5,wave_g:.4,wave_b:.3,ob_size:.055,ob_r:1,ob_g:1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:0,mv_y:43.199997,mv_l:1,mv_g:.91,mv_b:.71,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,r:.1,b:.7},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.r1=0;a.g2=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.r2=0;a.ang=0;a.sinang=0;a.tm=0;a.b2=0;a.t2=0;a.zp=0;a.g1=0;a.t4=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5);a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.xq=a.xp;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.3;a.ang=3.14+1.5*\\nMath.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*Math.cos(a.tm)-.5;\\na.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=a.a;a.b+=.3*pow(1-a.sample,2);a.r1=a.t1;a.g1=a.t2;a.b1=a.t3;a.r2=a.t4;a.g2=a.t5;a.b2=a.t6;a.r=a.r1*a.flip+a.r2*(1-a.flip);a.g=a.g1*a.flip+a.g2*(1-a.flip);a.b=a.b1*a.flip+a.b2*(1-a.flip);\"},{baseVals:{enabled:1,r:.2,b:.6},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.r1=0;a.g2=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.r2=0;a.ang=0;a.sinang=0;a.tm=0;a.b2=0;a.t2=0;a.zp=0;a.g1=0;a.t4=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5)+.1;a.yp=-a.yp;a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.3;\\na.ang=3.14+1.5*Math.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*Math.cos(a.tm)-\\n.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=a.a;a.b+=.3*pow(1-a.sample,2);a.r1=a.t1;a.g1=a.t2;a.b1=a.t3;a.r2=a.t4;a.g2=a.t5;a.b2=a.t6;a.r=a.r1*a.flip+a.r2*(1-a.flip);a.g=a.g1*a.flip+a.g2*(1-a.flip);a.b=a.b1*a.flip+a.b2*(1-a.flip);\"},{baseVals:{enabled:1,usedots:1,thick:1,additive:1,g:.6,b:.1},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.t8=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.ang=0;a.sinang=0;a.tm=0;a.t2=0;a.zp=0;a.t4=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;a.t8=Math.floor(2*Math.sin(2*a.time)+3);\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5);a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.xq=a.xp;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm+1;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.3;a.ang=3.14+\\n1.5*Math.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*Math.cos(a.tm)-\\n.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=above(Math.sin(128*a.tm*a.t8),0);a.r=a.t4;a.g=a.t5;a.b=a.t6;\"},{baseVals:{enabled:1,usedots:1,thick:1,additive:1,g:.3,b:.1},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.t8=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.ang=0;a.sinang=0;a.tm=0;a.t2=0;a.zp=0;a.t4=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;a.t8=Math.floor(2*Math.sin(2*a.time)+3);\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5)+.1;a.yp=-a.yp;a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm+1;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=\\n.3;a.ang=3.14+1.5*Math.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*\\nMath.cos(a.tm)-.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=a.a;a.a*=above(Math.sin(128*a.tm*a.t8),0);a.r=a.t4;a.g=a.t5;a.b=a.t6;\"}],init_eqs_str:'a.meanbass_att=0;a.q1=0;a[\"var\"]=0;a.flip=0;a.lastbeat=0;a.beatrate=0;a.mode=0;a.peakbass_att=0;a.beatcounter=0;a.att=0;a.volume=0;a.beat=0;a.vol=0;a.mtime=0;a.q8=0;a.mv_x=64;a.mv_y=48;a.nut=0;a.stp=0;a.stq=0;a.rtp=0;a.rtq=0;a.wvr=0;a.decay=0;a.dcsp=0;a.warp=0;',frame_eqs_str:\"a.volume=.3*(a.bass+a.mid+a.att);a.beatrate=equal(a.beatrate,0)+(1-equal(a.beatrate,0))*(below(a.volume,.01)+(1-below(a.volume,.01))*a.beatrate);a.lastbeat+=equal(a.lastbeat,0)*a.time;a.meanbass_att=.1*(9*a.meanbass_att+a.bass_att);a.peakbass_att=Math.max(a.bass_att,a.peakbass_att);a.beatrate=Math.max(.00001<Math.abs(a.beat)?.00001<Math.abs(below(a.time-a.lastbeat,2*a.beatrate))?.1*(9*a.beatrate+a.time-a.lastbeat):a.beatrate:a.beatrate,.1);a.peakbass_att=a.beat*a.bass_att+(1-\\na.beat)*a.peakbass_att*(.95*above(a.time-a.lastbeat,2*a.beatrate)+.995*(1-above(a.time-a.lastbeat,2*a.beatrate)));a.lastbeat=a.beat*a.time+(1-a.beat)*a.lastbeat;a.peakbass_att=Math.max(a.peakbass_att,1.1*a.meanbass_att);a.beat=above(a.volume,.8)*below(a.peakbass_att-a.bass_att,.05*a.peakbass_att)*above(a.time-a.lastbeat,.1+.5*(a.beatrate-.1));a.beatcounter+=a.beat;a.mode=.00001<Math.abs(a.beat*equal(mod(a.beatcounter,2),0))?1-a.mode:a.mode;a.flip=2*a.mode-1;a.monitor=a.flip;a.q8=a.flip;a.decay=1;\\na.zoom=1.002;a.vol=.25*(a.bass_att+a.mid_att+a.treb_att);a.vol*=a.vol;a.mtime+=.1*a.vol*a.flip*div(55,a.fps);a.q1=.4*a.mtime;a.warp=0;\",pixel_eqs_str:'a[\"var\"]=Math.tan(a.time)*a.treb*a.treb;a.zoom=1+div(a.rad,40)+div(a[\"var\"],40);',warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.999,echo_zoom:1.006596,echo_alpha:.5,echo_orient:3,wave_mode:2,additivewave:1,wave_dots:1,wave_thick:1,wave_a:4.099998,wave_scale:1.18647,wave_smoothing:.63,wave_mystery:-.2,modwavealphastart:.71,modwavealphaend:1.28,warpscale:1.331,zoom:.999514,warp:.01,wave_r:.3,wave_g:.6,ob_size:.005,ob_r:.4999,ob_b:1,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:.2,mv_r:0,mv_g:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.new_mid=0;a.q6=0;a.q1=0;a.q5=0;a.treb_c=0;a.vol_att=0;a.zoome=0;a.mid_c=0;a.new_treb=0;a.q4=0;a.rad_cycle=0;a.vol_c=0;a.bass_c=0;a.rote=0;a.vol=0;a.new_bass=0;a.q2=0;a.q3=0;a.q7=0;a.q8=0;\",frame_eqs_str:\"a.vol_att=.25*a.treb_att+.25*a.mid_att+div(.25*a.bass_att+.5*Math.sin(a.vol),a.vol);a.vol=a.bass+a.treb+a.mid;a.new_bass=.25*a.bass+.5*Math.sin(.25*a.bass_att);a.new_treb=.25*a.treb+.5*Math.sin(.25*a.treb_att);a.new_mid=.25*a.mid+.4*Math.sin(.25*a.mid_att);a.bass_c=a.q1-Math.sin(bitand(a.bass_att,.54*a.time));a.treb_c=a.q2-Math.sin(bitand(a.treb_att,.44*a.time));a.mid_c=a.q3-Math.sin(bitand(a.mid_att,.24*a.time));a.vol_c=a.q4-Math.sin(bitand(a.vol_att,.64*a.time));a.q1=Math.sin(bitand(a.bass-\\na.new_bass,.63*a.time));a.q2=Math.sin(bitand(a.treb-a.new_treb,.43*a.time));a.q3=Math.sin(bitand(a.mid-a.new_mid,.23*a.time));a.q4=Math.sin(bitand(a.vol,.65*a.time));a.q5=a.bass_c;a.q6=a.treb_c;a.q7=a.mid_c;a.q8=a.vol_c;a.wave_mystery=a.bass_att-1;a.wave_r+=.2*Math.sin(.43*a.time);a.wave_b-=.2*Math.sin(.54*a.time);a.wave_g-=.4*Math.sin(.34*a.time);a.ob_a=0;\",pixel_eqs_str:\"a.rad_cycle=a.rad*a.rad*a.x*60*a.rad*Math.sin(a.q6);a.rote=a.rot+.1*Math.sin(a.rad_cycle*Math.sin(3.14*a.rad))+.01*Math.sin(a.q1)*Math.tan(a.rad);a.zoome=a.zoom+.1*Math.sin(3.14*a.rad*Math.sin(3.14*a.ang)*Math.sin(a.q2)-a.rote);a.zoom=a.zoome+.05*Math.sin(3.14*a.rad*a.q2)*Math.sin(a.q4);a.rot=a.rote*a.rad+div(div(a.ang,2)*Math.sin(a.q3)*Math.sin(3.14*a.ang*Math.sin(a.q3)*Math.sin(a.q4)),2)+.1*Math.sin(3.14*a.ang)*Math.sin(a.q1);\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,decay:1,echo_zoom:1,wave_mode:1,wave_brighten:0,wave_a:1,wave_scale:.504218,wave_mystery:.24,warpanimspeed:9.8608,warpscale:16.2174,zoomexp:1.503744,zoom:1.0201,warp:.819544,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.005,ob_a:.2,ib_size:.005,ib_r:0,ib_g:0,ib_b:0,ib_a:.06,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.xpos=0;a.yamptarg=0;a.ydir=0;a.zoom_exp=0;a.yaccel=0;a.xamptarg=0;a.xamp=0;a.xspeed=0;a.ypos=0;a.xaccel=0;a.att=0;a.vol=0;a.yamp=0;a.xdir=0;a.yspeed=0;\",frame_eqs_str:\"a.dx=-.0005;a.dy=-.0005;a.vol=div(a.bass+a.mid+a.att,6);a.xamptarg=.00001<Math.abs(equal(mod(a.frame,15),0))?Math.min(.5*a.vol*a.bass_att,.5):a.xamptarg;a.xamp+=.5*(a.xamptarg-a.xamp);a.xdir=.00001<Math.abs(above(Math.abs(a.xpos),a.xamp))?-sign(a.xpos):.00001<Math.abs(below(Math.abs(a.xspeed),.1))?2*above(a.xpos,0)-1:a.xdir;a.xaccel=a.xdir*a.xamp-a.xpos-.055*a.xspeed*below(Math.abs(a.xpos),a.xamp);a.xspeed=a.xspeed+a.xdir*a.xamp-a.xpos-.055*a.xspeed*below(Math.abs(a.xpos),a.xamp);\\na.xpos+=.001*a.xspeed;a.wave_x=a.xpos+.5;a.yamptarg=.00001<Math.abs(equal(mod(a.frame,15),0))?Math.min(.3*a.vol*a.treb_att,.5):a.yamptarg;a.yamp+=.5*(a.yamptarg-a.yamp);a.ydir=.00001<Math.abs(above(Math.abs(a.ypos),a.yamp))?-sign(a.ypos):.00001<Math.abs(below(Math.abs(a.yspeed),.1))?2*above(a.ypos,0)-1:a.ydir;a.yaccel=a.ydir*a.yamp-a.ypos-.055*a.yspeed*below(Math.abs(a.ypos),a.yamp);a.yspeed=a.yspeed+a.ydir*a.yamp-a.ypos-.055*a.yspeed*below(Math.abs(a.ypos),a.yamp);a.ypos+=.001*a.yspeed;a.wave_y=\\na.ypos+.5;a.wave_r+=.35*(.6*Math.sin(.98*a.time)+.4*Math.sin(1.047*a.time));a.wave_g+=.35*(.6*Math.sin(.835*a.time)+.4*Math.sin(1.081*a.time));a.wave_b+=.35*(.6*Math.sin(.814*a.time)+.4*Math.sin(1.011*a.time));a.rot+=.03*(.6*Math.sin(.381*a.time)+.4*Math.sin(.479*a.time));a.cx+=.41*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.41*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.wave_mystery+=.15*(.6*Math.sin(.629*a.time)+.4*Math.sin(1.826*a.time));a.warp*=a.vol;a.zoom-=.02*a.zoom*\\na.bass_att;a.zoom_exp=1.5*(.6*Math.sin(.381*a.time)+.4*Math.sin(.479*a.time));a.ob_a=1-2*a.vol;a.monitor=a.zoom_exp;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_brighten:0,darken:1,wave_a:.002,wave_scale:.14,wave_smoothing:0,wave_mystery:-.84,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_g:0,wave_b:.6,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:23,textured:1,rad:.72143,tex_ang:.62832,tex_zoom:.0402,g:1,b:1,a:.9,r2:.9,b2:1,a2:.3,border_a:0},init_eqs_str:\"a.vis=0;a.q27=0;a.q22=0;\",frame_eqs_str:\"a.vis=div(bnot(mod(a.q27,8))*a.q22,2);a.vis=Math.min(a.vis,1);a.a=div(a.vis,2);a.a2=div(a.vis,2);a.tex_zoom=1;a.rad=.3*a.vis;\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:5,additive:1,num_inst:4,x:.9,rad:.24732,tex_zoom:.40839,g:.6,a:.4,g2:0,b2:.6,border_a:0},init_eqs_str:\"a.blue=0;a.ampl=0;a.steps=0;a.k1=0;a.q24=0;a.green=0;a.red=0;a.trig=0;a.q27=0;a.q28=0;\",frame_eqs_str:\"a.steps=a.q28+1;a.steps=4;a.ampl=.2;a.x=.5+a.ampl*Math.cos(6.28*(div(a.q27,a.steps)+div(a.instance,4)));a.y=.5+a.ampl*Math.sin(6.28*(div(a.q27,a.steps)+div(a.instance,4)));a.a=.4;a.a2=0;a.trig=a.q24*bnot(mod(a.q27,4));a.red=bnot(a.trig)*a.red+div(randint(100),100)*a.trig;a.green=bnot(a.trig)*a.green+div(randint(100),100)*a.trig;a.blue=bnot(a.trig)*a.blue+div(randint(100),100)*a.trig;a.k1=div(a.instance,a.num_inst);a.r=a.red*a.k1;a.g=a.green*(1-a.k1);a.b=4*a.blue*a.k1*(1-a.k1);\\na.r=a.red;a.g=a.green;a.b=a.blue;a.r2=a.r;a.b2=a.b;a.g2=a.g;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.px=0;a.index2=0;a.speed_=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q13=0;a.q15=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.py=0;a.movz=0;a.trel=0;a.q9=0;a.rott=0;a.vol__=0;a.is_beat=0;a.k1=0;a.q24=0;a.vx=0;a.dec_slow=0;a.q11=0;a.q10=0;a.vy=0;a.vz=0;a.q4=0;a.dir=0;a.q16=0;a.p2=0;a.avg=0;a.trig=0;a.beat=0;a.q17=0;a.vol=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.speed=0;a.q3=0;a.t0=0;a.vol_=0;a.q7=0;a.q28=0;a.q20=0;a.q8=0;a.ang0=0;a.speed_=1;a.vx=0;a.vy=0;a.vz=0;a.trel=0;a.p1=0;a.dir=0;a.ang0=\\n0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.96,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.5);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,16);a.index2=mod(a.index2+a.is_beat*bnot(a.index),8);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q24=a.is_beat;a.vol=a.bass_att+a.mid_att+\\na.treb_att;a.vol_=a.dec_med*a.vol_+(1-a.dec_med)*a.vol;a.vol__=a.dec_med*a.vol__+(1-a.dec_med)*a.vol_;a.q27=a.index+1;a.q28=a.index2+1;a.k1=a.is_beat*equal(mod(a.index,4),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.trig=a.q24*bnot(mod(a.index,8));a.vx=a.vx*bnot(a.trig)+a.trig*(div(randint(100),100)-.5);a.vy=a.vy*bnot(a.trig)+a.trig*(div(randint(100),100)-.5);a.vz=a.vz*bnot(a.trig)+\\na.trig*(div(randint(100),100)-.5);a.q10=.2+a.vy*a.vy*4;a.q11=.5*Math.cos(div(a.time,9))+.3;a.speed=Math.min(a.vol_-a.vol__+.5,1);a.speed=Math.max(a.speed,-.5);a.speed_=bnot(a.trig)*a.speed_+a.trig*a.speed;a.movz+=div(1,a.fps)*a.speed_;a.q9=a.movz;a.q12=2*Math.min(a.q22,6);a.trig=bnot(mod(a.index,4))*a.q24;a.dir=bnot(a.trig)*a.dir+a.trig*(randint(10)-5);a.trel+=div(.2,a.fps)*a.dir;a.q5=Math.cos(a.trel);a.q6=Math.sin(a.trel+0*a.q27*mod(a.q28,2));a.q7=-a.q6;a.q8=a.q5;a.px=a.px*a.dec_med+(1-a.dec_med)*\\na.vx;a.py=a.py*a.dec_med+(1-a.dec_med)*a.vy;a.q15=div(a.px,3);a.q16=div(a.py,3);a.q13=Math.min(2,1+Math.abs(8*a.px*a.py));a.ang0=a.ang0*a.dec_med+a.vz*(1-a.dec_med);a.q17=2*a.ang0;a.zoom=1.1;a.rot=.2*Math.sin(bnot(mod(a.q28,2))*a.q28);a.dx=0;a.monitor=a.q11;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 uv6_1;\\n  vec2 uv1_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (uv - 0.5);\\n  float x_4;\\n  x_4 = (abs(tmpvar_3.x) - abs(tmpvar_3.y));\\n  float tmpvar_5;\\n  tmpvar_5 = (18.0 * sqrt((x_4 * x_4)));\\n  uv1_2 = (tmpvar_3 - (clamp (\\n    ((sin(tmpvar_5) / cos(tmpvar_5)) * normalize(tmpvar_3))\\n  , vec2(-3.0, -3.0), vec2(3.0, 3.0)) / 60.0));\\n  uv6_1 = (0.4 * cos((\\n    (uv1_2 * 4.0)\\n   * q28)));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (((texture (sampler_main, \\n    ((uv1_2 * (q11 + (q10 * tmpvar_5))) + 0.5)\\n  ).xyz + \\n    (vec3((0.006 / sqrt(dot (uv6_1, uv6_1)))) * (1.0 + roam_cos).xyz)\\n  ) * 0.99) - 0.025);\\n  ret = tmpvar_6.xyz;\\n }\",comp:\"float xlat_mutableang2;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutableuv2;\\n shader_body { \\n  vec2 uv_1;\\n  vec3 ret1_3;\\n  uv_1 = ((uv - 0.5) * aspect.xy);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q15;\\n  tmpvar_4.y = q16;\\n  uv_1 = (uv_1 + tmpvar_4);\\n  mat2 tmpvar_5;\\n  tmpvar_5[uint(0)] = _qb.xy;\\n  tmpvar_5[1u] = _qb.zw;\\n  uv_1 = (uv_1 * tmpvar_5);\\n  float tmpvar_6;\\n  float tmpvar_7;\\n  tmpvar_7 = (min (abs(\\n    (uv_1.y / uv_1.x)\\n  ), 1.0) / max (abs(\\n    (uv_1.y / uv_1.x)\\n  ), 1.0));\\n  float tmpvar_8;\\n  tmpvar_8 = (tmpvar_7 * tmpvar_7);\\n  tmpvar_8 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_8) + 0.05368138) * tmpvar_8) - 0.1173503)\\n     * tmpvar_8) + 0.1938925) * tmpvar_8) - 0.3326756)\\n   * tmpvar_8) + 0.9999793) * tmpvar_7);\\n  tmpvar_8 = (tmpvar_8 + (float(\\n    (abs((uv_1.y / uv_1.x)) > 1.0)\\n  ) * (\\n    (tmpvar_8 * -2.0)\\n   + 1.570796)));\\n  tmpvar_6 = (tmpvar_8 * sign((uv_1.y / uv_1.x)));\\n  if ((abs(uv_1.x) > (1e-08 * abs(uv_1.y)))) {\\n    if ((uv_1.x < 0.0)) {\\n      if ((uv_1.y >= 0.0)) {\\n        tmpvar_6 += 3.141593;\\n      } else {\\n        tmpvar_6 = (tmpvar_6 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_6 = (sign(uv_1.y) * 1.570796);\\n  };\\n  xlat_mutablers0.x = ((tmpvar_6 / 3.1416) * 2.0);\\n  xlat_mutablers0.y = (0.03 / sqrt(dot (uv_1, uv_1)));\\n  ret1_3 = vec3(0.0, 0.0, 0.0);\\n  for (int n_2 = 0; n_2 <= 10; n_2++) {\\n    float tmpvar_9;\\n    tmpvar_9 = fract((-(q9) + (\\n      float(n_2)\\n     / 10.0)));\\n    xlat_mutableang2 = (((q1 * 3.14) * float(n_2)) / 10.0);\\n    float tmpvar_10;\\n    tmpvar_10 = cos(xlat_mutableang2);\\n    float tmpvar_11;\\n    tmpvar_11 = sin(xlat_mutableang2);\\n    mat2 tmpvar_12;\\n    tmpvar_12[uint(0)].x = tmpvar_10;\\n    tmpvar_12[uint(0)].y = -(tmpvar_11);\\n    tmpvar_12[1u].x = tmpvar_11;\\n    tmpvar_12[1u].y = tmpvar_10;\\n    xlat_mutableuv2 = (uv_1 * ((q13 * tmpvar_9) * tmpvar_12));\\n    ret1_3 = max (ret1_3, (texture (sampler_main, (xlat_mutableuv2 + 0.5)).xyz * (1.0 - tmpvar_9)));\\n  };\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 1.0;\\n  tmpvar_13.xyz = ((ret1_3 * 2.0) + ((\\n    (bass_att * xlat_mutablers0.y)\\n   * texture (sampler_main, \\n    ((uv_1 * q12) + vec2(0.5, 0.0))\\n  ).yzx) * clamp (\\n    (1.0 - (ret1_3 * 32.0))\\n  , 0.0, 1.0)));\\n  ret = tmpvar_13.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.965,echo_zoom:1.483827,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,wave_brighten:0,wrap:0,darken_center:1,darken:1,wave_a:.001,wave_scale:1.285751,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:.01,warpscale:1.470245,zoomexp:4.778023,zoom:.998162,warp:.01,sx:1.001828,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.005,ob_r:1,ob_g:.5,ob_b:.5,ob_a:1,ib_size:.5,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:4.800001,mv_dx:.4,mv_l:1,mv_r:0,mv_g:.5,mv_a:.1},shapes:[{baseVals:{enabled:1,sides:3,additive:1,thickoutline:1,textured:1,x:1,y:.59,rad:.559231,ang:3.39292,tex_zoom:100,r:0,g:1,b:1,g2:0,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"\",frame_eqs_str:\"a.x=.1*Math.sin(div(a.time,10))+.5+.1*a.treb_att;\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:6,textured:1,x:.3,y:.7,rad:1.089252,ang:.816814,tex_ang:3.141592,tex_zoom:.504215,g:1,b:1,r2:1,b2:1,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:1,sides:3,textured:1,rad:.284278,ang:3.141593,tex_ang:4.900885,tex_zoom:2.987755,g:1,b:1,r2:.95,b2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:'a[\"var\"]=0;',frame_eqs_str:'a.ang=div(a.time,10);a.tex_zoom=3.4+.03*a.bass;a[\"var\"]=above(a.bass_att,.7);a.a=a[\"var\"];a.a2=a[\"var\"];a.border_a=a[\"var\"];'}],waves:[{baseVals:{enabled:1,usedots:1,thick:1,additive:1,r:0,a:.06},init_eqs_str:\"a.px=0;a.xoffset2=0;a.py=0;a.xoffset1=0;a.pheight=0;a.pphase=0;a.yspout=0;a.pphase2=0;a.xspout=0;a.lrorient=0;a.yheight=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.xspout=.5;a.yspout=-.01;a.pphase=9999*a.sample*a.sample*.0001;a.pphase2=.1+.01*mod(3349*a.sample*a.sample,100);a.pheight=.002*mod(9893*a.sample,100);a.yheight=.01*mod(1231*a.sample*a.sample,100);a.r=.01*mod(5454*a.sample,100)*Math.abs(Math.sin(.25*a.time));a.g=.01*mod(9954*a.sample,100);a.xoffset1=Math.cos(a.time*a.pphase2+a.pphase)*a.pheight;a.xoffset2=-1*Math.cos(a.time*a.pphase2+a.pphase)*a.pheight;a.lrorient=.00001<Math.abs(below(Math.cos(a.time*a.pphase2+a.pphase),Math.cos((a.time-\\n.1)*a.pphase2+a.pphase)))?0:1;a.px=.00001<Math.abs(equal(a.lrorient,0))?a.xspout-a.pheight+a.xoffset1:a.xspout+a.pheight-a.xoffset2;a.py=a.yspout+Math.abs(Math.sin(a.time*a.pphase2+a.pphase))*a.yheight;a.x=a.px;a.y=a.py;\"},{baseVals:{enabled:1,usedots:1,thick:1,additive:1,r:0},init_eqs_str:\"a.pphase=0;a.pheight=0;a.xspout=0;a.yspout=0;a.px=0;a.py=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.pphase=5671*a.sample*Math.cos(.0001*a.time);a.pheight=.005*mod(7654*a.sample,100)*Math.sin(.2*a.time);a.xspout=.00001<Math.abs(below(Math.abs(Math.sin(.2*a.time)),.005))?.3+.01*randint(40):a.xspout;a.yspout=.00001<Math.abs(below(Math.abs(Math.sin(.2*a.time)),.005))?.3+.01*randint(40):a.yspout;a.px=a.xspout+Math.cos(a.time+a.pphase)*a.pheight;a.py=a.yspout+Math.sin(a.time+a.pphase)*a.pheight;a.x=a.px;a.y=a.py;a.a=Math.abs(.3*Math.sin(.2*a.time)+.1*a.treb_att);a.r=2*a.treb;\\n\"},{baseVals:{enabled:1,thick:1,additive:1,b:0},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.yr=0;a.xs=0;a.yp=0;a.xr=0;a.q1=0;a.xq=0;a.flip=0;a.ca=0;a.ys=0;a.sa=0;a.zq=0;a.phs=0;a.ang=0;a.tm=0;a.zp=0;a.zr=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+4*a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=(.1*a.flip-.05)*a.sample;a.zp=0;a.ang=20*a.tm+.4*Math.sin(76*a.tm+4*a.time);a.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.xr=a.xp*a.sa+a.yp*a.ca;a.yr=a.xp*a.ca-a.yp*a.sa;a.zr=a.zp;a.xp=a.xr;a.yp=a.yr+.05+.2*(.5*Math.sin(a.tm)+.5)+.05;a.zp=a.zr;a.ang=Math.sin(2*a.tm);a.xq=a.xp;a.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.yq=a.yp*a.sa+a.zp*a.ca;a.zq=a.yp*a.ca-a.zp*a.sa;a.ang=8*a.tm;\\na.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.xp=a.xq*a.sa+a.yq*a.ca;a.yp=a.xq*a.ca-a.yq*a.sa;a.zp=a.zq;a.zp-=.3;a.ang=3.14+2.5*Math.sin(2*a.tm-.5);a.xq=a.xp;a.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.yq=a.yp*a.sa+a.zp*a.ca;a.zq=a.yp*a.ca-a.zp*a.sa;a.ang=-1+Math.cos(3*a.tm+.5);a.xp=a.xq*a.sa+a.yq*a.ca;a.yp=a.xq*a.ca-a.yq*a.sa;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(1*a.tm)-1.05;a.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.xq=a.xp*a.sa+a.zp*a.ca;a.yq=a.yp;a.zq=a.xp*a.ca-a.zp*a.sa;a.ang=Math.cos(a.tm);\\na.xp=a.xq;a.sa=Math.sin(a.ang);a.ca=Math.cos(a.ang);a.yp=a.yq*a.ca-a.zq*a.sa;a.zp=a.yq*a.sa+a.zq*a.ca;a.zp+=1.5;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=1-a.sample;\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.vol=0;a.mtime=0;a.q1=0;\",frame_eqs_str:\"a.decay=.999;a.wrap=Math.sin(10*a.time);a.mv_dx=a.bass;a.ib_a=.005;a.vol=.25*(a.bass+a.mid+a.treb);a.vol*=a.vol;a.mtime+=.01*a.vol*div(55,a.fps);a.q1=.5*a.time;\",pixel_eqs_str:\"a.zoom=1.005-div(a.rad,100);a.rot=div(a.rad,600);a.sy=-1;\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1.006596,echo_alpha:.5,additivewave:1,wave_thick:1,wave_brighten:0,wrap:0,wave_a:4.099998,wave_scale:.01,wave_smoothing:.63,wave_mystery:-.4,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.999513,warp:.01,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.005,ob_r:.01,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:.5,mv_r:.35,mv_g:.35,mv_b:.35,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.q8=0;a.oldq8=0;\",frame_eqs_str:\"a.ob_r=.5+.5*Math.sin(2*a.time);a.ob_g=.5+.5*Math.sin(1.23*a.time);a.ob_b=.5+.5*Math.sin(1.321*a.time);a.wave_a=0;a.q8=a.oldq8+.003*div(pow(1.2*a.bass+.4*a.bass_att+.1*a.treb+.1*a.treb_att+.1*a.mid+.1*a.mid_att,6),a.fps);a.oldq8=a.q8;a.warp=0;\",pixel_eqs_str:\"a.rot=.1*(a.rad+Math.cos(5+5*Math.sin(1.211*a.q8)*a.x-.5)-Math.sin((5+5*Math.sin(.973*a.q8))*a.y-.5));a.dx=.005*(Math.cos(5+5*Math.sin(1.311*a.q8)*a.x-.5)-Math.sin((5+5*Math.sin(.9431*a.q8))*a.y-.5));a.dy=.005*(Math.cos(5+5*Math.sin(1.021*a.q8)*a.x-.5)-Math.sin((5+5*Math.sin(.987*a.q8))*a.y-.5));a.zoom=1-.005*(a.rad+Math.cos(5+5*Math.sin(.943*a.q8)*a.x-.5)-Math.sin((5+5*Math.sin(1.0961*a.q8))*a.y-.5));\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:1,echo_zoom:1,wave_mode:7,additivewave:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:100,wave_scale:.438649,wave_smoothing:.5,modwavealphastart:.5,modwavealphaend:1,zoomexp:.999996,fshader:1,dx:1e-5,dy:1e-5,warp:.01,wave_y:.976,ob_size:.005,ob_r:.4,ob_g:.3,ob_a:1,ib_r:1,ib_g:.6,ib_b:0,ib_a:1,mv_x:24.959999,mv_y:19.199999,mv_l:.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.q1=0;a.thresh=0;a.dx_r=0;a.dy_r=0;\",frame_eqs_str:\"a.warp=0;a.wave_r=.5+.5*Math.sin(.894*a.time);a.wave_g=.5+.5*Math.sin(1.14*a.time);a.wave_b=.5+.5*Math.sin(3-a.bass_att);a.thresh=2*above(a.bass_att,a.thresh)+(1-above(a.bass_att,a.thresh))*((a.thresh-1.3)*(.9+.1*Math.sin(2.8*a.time))+1.3);a.dx_r=.004*equal(a.thresh,2)*Math.sin(5*a.time)+(1-equal(a.thresh,2))*a.dx_r;a.dy_r=.004*equal(a.thresh,2)*Math.sin(6*a.time)+(1-equal(a.thresh,2))*a.dy_r;a.q1=a.thresh;a.dx=1.1*a.dx_r;a.dy=1.1*a.dy_r;a.dx+=.00001<Math.abs(above(a.bass,1.35))?\\n31*a.dx_r:0;a.dy=.00001<Math.abs(above(a.bass,1.3))?0:a.dy;a.decay=.995+.004*Math.sin(.369*a.time)+.001*Math.sin(1.54*a.time);\",pixel_eqs_str:\"a.zoom-=.01*a.q1*a.rad;a.zoomexp=1+.2*(a.rad-.2*a.q1);a.sx-=Math.cos(a.y*(6.28+3.14*Math.sin(a.time)))*(.009+.003*Math.sin(2.18*a.time))*Math.sin(.3*a.time);a.rot=.001*Math.sin(3.14*a.x)*Math.sin(.67*a.time);\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.94,echo_zoom:.9998,echo_alpha:.4999,echo_orient:3,wave_mode:1,additivewave:1,wave_dots:1,wave_brighten:0,wave_a:1.254574,wave_scale:.45029,wave_smoothing:0,zoomexp:1.008151,zoom:.659411,warp:.01,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.005,ob_r:1,ob_a:1,ib_size:.005,ib_r:0,ib_g:0,ib_b:0,ib_a:.9,mv_x:64,mv_y:48,mv_l:0,mv_r:0,mv_g:.7,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.bblock=0;a.grid=0;a.q6=0;a.q1=0;a.q5=0;a.tth=0;a.tblock=0;a.bpulse=0;a.pulse=0;a.mblock=0;a.q4=0;a.mpulse=0;a.mod_state=0;a.bth=0;a.mres=0;a.tpulse=0;a.tres=0;a.le=0;a.ccl=0;a.q2=0;a.bres=0;a.q3=0;a.mth=0;a.q7=0;a.q8=0;\",frame_eqs_str:\"a.warp=0;a.le=1.5+2*Math.sin(a.bass_att);a.bpulse=band(above(a.le,a.bth),above(a.le-a.bth,a.bblock));a.bblock=a.le-a.bth;a.bth=.00001<Math.abs(above(a.le,a.bth))?a.le+div(114,a.le+10)-7.407:a.bth+div(.07*a.bth,a.bth-12)+.1*below(a.bth,2.7)*(2.7-a.bth);a.bth=.00001<Math.abs(above(a.bth,6))?6:a.bth;a.bres=a.bpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.bpulse)*a.bres;a.le=1.5+2*Math.sin(a.treb_att);a.tpulse=band(above(a.le,a.tth),above(a.le-a.tth,a.tblock));a.tblock=a.le-a.tth;a.tth=\\n.00001<Math.abs(above(a.le,a.tth))?a.le+div(114,a.le+10)-7.407:a.tth+div(.07*a.tth,a.tth-12)+.1*below(a.tth,2.7)*(2.7-a.tth);a.tth=.00001<Math.abs(above(a.tth,6))?6:a.tth;a.tres=a.tpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.tpulse)*a.tres;a.le=1.5+2*Math.sin(a.mid_att);a.mpulse=band(above(a.le,a.mth),above(a.le-a.mth,a.mblock));a.mblock=a.le-a.mth;a.mth=.00001<Math.abs(above(a.le,a.mth))?a.le+div(114,a.le+10)-7.407:a.mth+div(.07*a.mth,a.mth-12)+.1*below(a.mth,2.7)*(2.7-a.mth);a.mth=.00001<Math.abs(above(a.mth,\\n6))?6:a.mth;a.mres=a.mpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.mpulse)*a.mres;a.pulse=.00001<Math.abs(above(Math.abs(a.pulse),3.14))?-3.14:a.pulse+.003*(a.bth+a.mth+a.tth);a.q1=a.bres;a.q2=a.tres;a.q3=a.mres;a.q4=Math.sin(a.pulse);a.mod_state=(above(a.q1,0)+above(a.q2,0)+above(a.q3,0))*(1+above(a.q4,0));a.ccl=a.ccl+a.tpulse+a.mpulse-a.bpulse;a.q5=Math.cos(a.pulse*(.5+.1*a.mod_state));a.q6=Math.sin(a.pulse*(.5+pow(.25,a.mod_state)));a.q7=a.mod_state;a.q8=a.ccl;a.ob_r=.5+.5*Math.cos(a.q1+a.q7);a.ob_g=\\n.5+.5*Math.cos(3.14*a.q2+a.q7);a.ob_b=.5+.5*Math.cos(2*a.q3+Math.sin(.0816*a.time));a.ib_size=.025+.02*a.q2;a.ob_size=.03+.02*a.q3-.002*a.q7;a.wave_r=.5+.5*Math.sin(a.q1*a.q7+2.183*a.time);a.wave_g=.5+.5*Math.sin(3*a.q2+1.211*a.time);a.wave_b=.5+.5*Math.sin(a.q3+1.541*a.time);a.ob_a=.8+.2*a.q2;a.zoom+=.01*a.q4;\",pixel_eqs_str:\"a.grid=mod(pow(2*Math.sin(a.rad*a.q6*a.q2+a.x*a.y*a.q6*a.q3),1+mod(a.q7,5)),2);a.rot=bnot(a.grid)+a.grid*a.q4;a.sx+=.003*Math.sin((a.q2+.5)*a.x);a.sy+=.003*Math.sin((a.q1+3.4)*a.y);a.zoom+=.11*Math.cos(3.14*a.rad)*a.q4;\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:.96,echo_zoom:2.216266,echo_alpha:.78,wave_mode:5,additivewave:1,wave_dots:1,wave_brighten:0,brighten:1,wave_a:1.254574,wave_scale:.931011,wave_smoothing:0,zoomexp:1.0081,fshader:.4,zoom:.820774,cx:.4999,warp:.01,sx:.999998,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.005,ob_r:1,ob_a:1,ib_size:.005,ib_r:0,ib_g:0,ib_b:0,ib_a:.9,mv_x:0,mv_y:0,mv_l:.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.bblock=0;a.grid=0;a.q6=0;a.snee=0;a.q1=0;a.q5=0;a.tth=0;a.tblock=0;a.bpulse=0;a.pulse=0;a.mblock=0;a.q4=0;a.snur=0;a.mpulse=0;a.mod_state=0;a.bth=0;a.mres=0;a.tpulse=0;a.tres=0;a.le=0;a.ccl=0;a.q2=0;a.bres=0;a.q3=0;a.mth=0;a.q7=0;a.q8=0;\",frame_eqs_str:\"a.warp=0;a.le=1.5+2*Math.sin(a.bass_att);a.bpulse=band(above(a.le,a.bth),above(a.le-a.bth,a.bblock));a.bblock=a.le-a.bth;a.bth=.00001<Math.abs(above(a.le,a.bth))?a.le+div(114,a.le+10)-7.407:a.bth+div(.07*a.bth,a.bth-12)+.1*below(a.bth,2.7)*(2.7-a.bth);a.bth=.00001<Math.abs(above(a.bth,6))?6:a.bth;a.bres=a.bpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.bpulse)*a.bres;a.le=1.5+2*Math.sin(a.treb_att);a.tpulse=band(above(a.le,a.tth),above(a.le-a.tth,a.tblock));a.tblock=a.le-a.tth;a.tth=\\n.00001<Math.abs(above(a.le,a.tth))?a.le+div(114,a.le+10)-7.407:a.tth+div(.07*a.tth,a.tth-12)+.1*below(a.tth,2.7)*(2.7-a.tth);a.tth=.00001<Math.abs(above(a.tth,6))?6:a.tth;a.tres=a.tpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.tpulse)*a.tres;a.le=1.5+2*Math.sin(a.mid_att);a.mpulse=band(above(a.le,a.mth),above(a.le-a.mth,a.mblock));a.mblock=a.le-a.mth;a.mth=.00001<Math.abs(above(a.le,a.mth))?a.le+div(114,a.le+10)-7.407:a.mth+div(.07*a.mth,a.mth-12)+.1*below(a.mth,2.7)*(2.7-a.mth);a.mth=.00001<Math.abs(above(a.mth,\\n6))?6:a.mth;a.mres=a.mpulse*Math.sin(a.pulse+.5*a.le)+bnot(a.mpulse)*a.mres;a.pulse=.00001<Math.abs(above(Math.abs(a.pulse),3.14))?-3.14:a.pulse+.003*(a.bth+a.mth+a.tth);a.q1=a.bres;a.q2=a.tres;a.q3=a.mres;a.q4=Math.sin(a.pulse);a.mod_state=(above(a.q1,0)+above(a.q2,0)+above(a.q3,0))*(1+above(a.q4,0));a.ccl=a.ccl+a.tpulse+a.mpulse-a.bpulse;a.q5=Math.cos(a.pulse*(.5+.1*a.mod_state));a.q6=Math.sin(a.pulse*(.5+pow(.25,a.mod_state)));a.q7=a.mod_state;a.q8=a.ccl;a.ob_r=.5+.5*Math.cos(a.q1+a.q7);a.ob_g=\\n.5+.5*Math.cos(3.14*a.q2+a.q7);a.ob_b=.5+.5*Math.cos(2*a.q3+Math.sin(.0816*a.time));a.ib_size=.025+.02*a.q2;a.ob_size=.03+.02*a.q3-.002*a.q7;a.wave_r=.5+.5*Math.sin(a.q1*a.q7+2.183*a.time);a.wave_g=.5+.5*Math.sin(3*a.q2+1.211*a.time);a.wave_b=.5+.5*Math.sin(a.q3+1.541*a.time);a.ob_a=.8+.2*a.q2;a.rot=1;a.cx+=.05*a.q4;a.cy+=.05*a.q5;a.zoom=.95+.05*a.q6;\",pixel_eqs_str:\"a.snee=bnot(above(Math.sin(a.ang)-a.x,.5)*above(a.q2,0)+above(a.y-Math.cos(a.ang),.5)*above(a.q1,0));a.snur=bnot(below(a.x,.5)*above(a.q3,0)+below(a.y,.5)*below(a.q7,4));a.grid=Math.sin(sigmoid(Math.sin(6.28*a.y*a.q2),Math.sin(6.28*a.x*a.q6))*(10+a.q7));a.zoom=a.zoom+.02*Math.cos(2*a.rad+a.rad*a.q2)*sign(a.snee)-.04*Math.sin(3.14*a.rad*a.q3-3.14*Math.cos(3.14*a.rad*a.snur-3.14*a.q6));a.sx=.00001<Math.abs(below(a.x,.5)*below(a.y,.5))?a.sx+.2*a.q4*a.snur:1+.1*a.q2*a.grid;a.sy=\\n.00001<Math.abs(below(a.x,.5)*below(a.y,.5))?a.sy+.2*a.q5*a.snee:1+.1*a.q2*a.grid;\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:4.990001,decay:1,echo_zoom:10.784553,wave_mode:7,additivewave:1,wave_dots:1,wave_brighten:0,wrap:0,wave_a:.997938,wave_scale:1.990516,wave_smoothing:0,wave_mystery:-1,modwavealphastart:.5,modwavealphaend:1,warpscale:.999998,zoomexp:.999985,fshader:1,zoom:.9999,dy:1e-5,warp:.01,wave_r:.400001,wave_g:.4,wave_y:1,ob_size:0,ob_r:.300001,ob_g:1,ob_b:.3,ob_a:.100001,ib_size:.005,ib_r:0,ib_g:0,ib_b:0,ib_a:.5,mv_x:8.960042,mv_y:12.960033,mv_dx:-.26,mv_dy:.44,mv_l:5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"},{baseVals:{},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"\"}],init_eqs_str:\"a.maxdbass=0;a.f=0;a.ttan1=0;a.avgbass=0;a.dbass=0;a.q1=0;a.prevavgbass=0;a.amt=0;a.cheat=0;a.totx=0;a.flip=0;a.lastbeat=0;a.ttan2=0;a.bpm=0;a.pctg=0;a.prevrot=0;a.interval=0;a.q4=0;a.pbass=0;a.toty=0;a.beat=0;a.vol=0;a.q2=0;a.dist=0;a.lastflip=0;a.prevvol=0;a.q3=0;a.isleftytonosy=0;a.sure=0;a.flip=-1;\",frame_eqs_str:\"a.warp=0;a.decay=1;a.vol=div(.75*(a.bass_att+a.mid_att+a.treb_att),3)+.25*a.prevvol;a.prevavgbass=a.avgbass;a.avgbass+=.01*(a.bass-a.avgbass);a.q4=Math.max(1.001*a.avgbass-.999*a.prevavgbass,0);a.q4=Math.min(a.q4,.006);a.sure=.00001<Math.abs(equal(a.sure,0))?.6:a.sure;a.interval=.00001<Math.abs(equal(a.interval,0))?40:a.interval;a.lastbeat=.00001<Math.abs(equal(a.lastbeat,0))?a.frame-a.fps:a.lastbeat;a.dbass=div(a.bass-a.pbass,a.fps);a.beat=above(a.dbass,.6*a.maxdbass)*above(a.frame-\\na.lastbeat,div(a.fps,3));a.sure=.00001<Math.abs(a.beat*below(Math.abs(a.frame-(a.interval+a.lastbeat)),div(a.fps,5)))?Math.min(.095+a.sure,1):a.beat*(a.sure-.095)+(1-a.beat)*a.sure*.9996;a.sure=Math.max(.5,a.sure);a.cheat=.00001<Math.abs(above(a.frame,a.lastbeat+a.interval+Math.floor(div(a.fps,10)))*above(a.sure,.91))?1:a.cheat;a.beat=.00001<Math.abs(a.cheat)?1:a.beat;a.sure=.00001<Math.abs(a.cheat)?.95*a.sure:a.sure;a.maxdbass=Math.max(.999*a.maxdbass,a.dbass);a.maxdbass=Math.max(.012,a.maxdbass);\\na.maxdbass=Math.min(.02,a.maxdbass);a.interval=.00001<Math.abs(a.beat)?a.frame-a.lastbeat:a.interval;a.lastbeat=.00001<Math.abs(a.beat)?a.frame-a.cheat*Math.floor(div(a.fps,10)):a.lastbeat;a.cheat=0;a.pbass=a.bass;a.lastflip=.00001<Math.abs(above(div(a.bass,a.avgbass),2)*above(a.frame-a.lastflip,100)*a.beat)?a.frame:a.lastflip;a.flip=.00001<Math.abs(equal(a.frame,a.lastflip))?Math.abs(a.flip)-1:a.flip;a.wave_mystery=a.flip;a.ob_size=div(.08*below(a.frame-a.lastbeat,div(a.fps,8))*(a.frame-a.lastbeat),\\na.fps);a.f=Math.abs(Math.cos(div(a.time,8)+.54+Math.sin(div(a.time,3)+1.075)));a.ob_r=1*a.f+(1-a.f);a.ob_g=.3*a.f+(1-a.f);a.ob_b=.3*a.f+.3*(1-a.f);a.f=div(a.frame-a.lastbeat,a.interval);a.f*=above(a.f,.8)*below(a.f,1);a.f=Math.max(0,a.f);a.f=Math.min(a.f,1);a.wave_g=.4+.6*a.f;a.wave_b=.4+.6*(1-a.f);a.q1=div(3.1416*(a.wave_mystery+1),2);a.q2=.25*Math.cos(a.time+Math.abs(2*Math.sin(2*a.time+2.311)*(a.vol-a.amt))*Math.sin(7.45*a.time+.876));a.q3=-a.q2;a.amt+=.05*(a.vol-a.amt);a.prevvol=a.vol;a.bpm+=\\n.01*(div(60*a.fps,a.interval)-a.bpm);a.monitor=0*a.pctg+1*a.bpm;\",pixel_eqs_str:\"a.x-=.5;a.y=-(a.y-.5);a.ttan1=Math.tan(a.q1+1.5708)*(a.x-a.q3)-a.y+a.q2;a.ttan2=Math.tan(a.q1+1.5708);a.isleftytonosy=above(a.ttan1*sign(3.1416-a.q1),0);a.dist=div(Math.abs(a.ttan1),sqrt(a.ttan2*a.ttan2+1));a.totx=div(.5*Math.cos(a.q1)*sign(a.isleftytonosy-.5)*sqr(a.dist),.5-a.q2);a.toty=div(-.5*Math.sin(a.q1)*sign(a.isleftytonosy-.5)*sqr(a.dist),.5-a.q2);a.dx+=a.totx;a.dy+=a.toty;a.prevrot=a.q1;a.zoom=1-div(25*a.q4*sqrt(pow(.5-a.dist,3)),Math.abs(.5-a.q2));\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:.997,echo_zoom:.996629,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001185,wave_scale:.01,wave_smoothing:.27,wave_mystery:-.38,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.999514,warp:.01,ob_size:0,ob_r:.01,ob_a:1,ib_size:0,ib_r:1,ib_g:1,ib_b:1,ib_a:1,mv_x:64,mv_y:48,mv_l:.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0},shapes:[{baseVals:{enabled:1,sides:3,rad:.34,ang:.53,r:.56,g:.36,r2:.9,a2:.5,border_a:0},init_eqs_str:\"a.angle=0;a.bassspin=0;a.q1=0;a.q2=0;a.bassspin=0;a.angle=0;\",frame_eqs_str:\"a.ang=a.angle;a.bassspin=.00001<Math.abs(above(.05*a.bass,a.bassspin))?a.bassspin+.001:a.bassspin-.001;a.bassspin*=above(a.bassspin,0);a.angle+=a.bassspin;a.r=.3*a.bass;a.g=.3*a.treb;a.b=.3*a.mid;a.r2=.8+.2*Math.sin(1.2*a.time);a.g2=.8+.2*Math.sin(.9777*a.time);a.b2=.8+.2*Math.sin(.7005*a.time);a.border_a=1*above(a.bass+a.treb+a.mid,5);a.x=.5+a.q1;a.y=.5+a.q2;\"},{baseVals:{enabled:1,sides:100,additive:1,textured:1,rad:.108073,g:1,b:1,r2:1,b2:1,a2:1,border_a:0},init_eqs_str:\"a.bassspin=0;a.xpos=0;a.ypos=0;a.q1=0;a.q2=0;a.bassspin=0;a.xpos=.25;a.ypos=.25;\",frame_eqs_str:\"a.bassspin=.00001<Math.abs(above(.05*a.bass,a.bassspin))?a.bassspin+.001:a.bassspin-.001;a.bassspin*=above(a.bassspin,0);a.xpos+=a.bassspin;a.ypos+=a.bassspin;a.x=.5+a.q1+.13*Math.sin(a.xpos);a.y=.5+a.q2+.18*Math.cos(a.ypos);\"},{baseVals:{enabled:1,sides:29,additive:1,textured:1,rad:.105693,g:1,b:1,r2:1,b2:1,a2:1,border_a:0},init_eqs_str:\"a.bassspin=0;a.xpos=0;a.ypos=0;a.q1=0;a.q2=0;a.bassspin=0;a.xpos=2.3;a.ypos=2.3;\",frame_eqs_str:\"a.bassspin=.00001<Math.abs(above(.05*a.bass,a.bassspin))?a.bassspin+.001:a.bassspin-.001;a.bassspin*=above(a.bassspin,0);a.xpos+=a.bassspin;a.ypos+=a.bassspin;a.x=.5+a.q1+.13*Math.sin(a.xpos);a.y=.5+a.q2+.18*Math.cos(a.ypos);\"},{baseVals:{enabled:1,sides:100,additive:1,textured:1,rad:.091434,g:1,b:1,r2:1,b2:1,a2:1,border_a:0},init_eqs_str:\"a.bassspin=0;a.xpos=0;a.ypos=0;a.q1=0;a.q2=0;a.bassspin=0;a.xpos=4.5;a.ypos=4.5;\",frame_eqs_str:\"a.bassspin=.00001<Math.abs(above(.05*a.bass,a.bassspin))?a.bassspin+.001:a.bassspin-.001;a.bassspin*=above(a.bassspin,0);a.xpos+=a.bassspin;a.ypos+=a.bassspin;a.x=.5+a.q1+.13*Math.sin(a.xpos);a.y=.5+a.q2+.18*Math.cos(a.ypos);\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.xpos=0;a.yamptarg=0;a.ydir=0;a.q1=0;a.yaccel=0;a.xamptarg=0;a.xamp=0;a.xspeed=0;a.ypos=0;a.xaccel=0;a.att=0;a.vol=0;a.q2=0;a.yamp=0;a.xdir=0;a.yspeed=0;\",frame_eqs_str:\"a.warp=0;a.decay=.92;a.vol=div(a.bass+a.mid+a.att,6);a.xamptarg=.00001<Math.abs(equal(mod(a.frame,15),0))?Math.min(.5*a.vol*a.bass_att,.5):a.xamptarg;a.xamp+=.5*(a.xamptarg-a.xamp);a.xdir=.00001<Math.abs(above(Math.abs(a.xpos),a.xamp))?-sign(a.xpos):.00001<Math.abs(below(Math.abs(a.xspeed),.1))?2*above(a.xpos,0)-1:a.xdir;a.xaccel=a.xdir*a.xamp-a.xpos-.055*a.xspeed*below(Math.abs(a.xpos),a.xamp);a.xspeed=a.xspeed+a.xdir*a.xamp-a.xpos-.055*a.xspeed*below(Math.abs(a.xpos),a.xamp);\\na.xpos+=.001*a.xspeed;a.yamptarg=.00001<Math.abs(equal(mod(a.frame,15),0))?Math.min(.3*a.vol*a.treb_att,.5):a.yamptarg;a.yamp+=.5*(a.yamptarg-a.yamp);a.ydir=.00001<Math.abs(above(Math.abs(a.ypos),a.yamp))?-sign(a.ypos):.00001<Math.abs(below(Math.abs(a.yspeed),.1))?2*above(a.ypos,0)-1:a.ydir;a.yaccel=a.ydir*a.yamp-a.ypos-.055*a.yspeed*below(Math.abs(a.ypos),a.yamp);a.yspeed=a.yspeed+a.ydir*a.yamp-a.ypos-.055*a.yspeed*below(Math.abs(a.ypos),a.yamp);a.ypos+=.001*a.yspeed;a.q1=a.ypos;a.q2=a.xpos;\",pixel_eqs_str:\"a.zoom+=a.q1*a.q2*2;a.rot=10+a.rad*a.treb*.1;\",warp:\"\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:3,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wrap:0,darken_center:1,solarize:1,wave_a:.001,zoom:.97,rot:-6.27999,warp:52e-5,wave_r:0,wave_g:0,wave_b:0,ob_r:1,ob_g:1,ob_b:1,mv_r:.8,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,textured:1,x:.25,y:.75,rad:4.44708,tex_zoom:.22746,r:0,a:.1,g2:0,a2:.2,border_r:0,border_g:0,border_a:0},init_eqs_str:\"a.q1=0;a.tex_capture=0;a.q3=0;a.tex_saw=.4;\",frame_eqs_str:\"a.ang=.2*a.q1;a.tex_capture=above(a.q3,1);a.tex_zoom=.6;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,smoothing:0},init_eqs_str:\"a.q1=0;a.speed=0;a.v=0;a.xs=0;a.ys=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.q1=0;a.speed=.8*a.bass_att;a.v=1E6*a.sample+a.value2*a.bass*.1;a.xs+=Math.sin(a.v)*a.speed*Math.atan(1.51*a.v);a.ys+=Math.sin(a.v)*a.speed*Math.atan(10*a.v);a.x=.5+.5*Math.sin(.1*a.xs)*Math.cos(.2*a.time+a.xs);a.y=.5+.5*Math.sin(.12*a.ys)*Math.cos(.1*a.time+a.xs);a.x=.8*a.x+.1;a.y=.8*a.y+.1;a.r=.5*Math.sin(1.22*a.time)+.6;a.g=.4+.4*Math.sin(1.307*a.time+2*a.y);a.b=.4+.4*Math.sin(1.959*a.time+2*a.x);a.xs=.00001<Math.abs(above(a.xs,1E3))?0:a.xs;a.ys=.00001<Math.abs(above(a.ys,\\n1E3))?0:a.ys;\"},{baseVals:{enabled:1,thick:1,smoothing:0},init_eqs_str:\"a.q1=0;a.speed=0;a.v=0;a.xs=0;a.ys=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.q1=0;a.speed=.8*a.bass_att;a.v=1E6*a.sample+a.value2*a.bass*.1;a.xs+=Math.sin(a.v)*a.speed*Math.atan(1.51*a.v);a.ys+=Math.sin(a.v)*a.speed*Math.atan(10*a.v);a.x=.5+.5*Math.sin(.1*a.xs)*Math.cos(.2*a.time+a.xs);a.y=.5+.5*Math.sin(.14*a.ys)*Math.cos(.1*a.time+a.xs);a.x=.8*a.x+.1;a.y=.8*a.y+.1;a.x=.6*a.x+.2;a.y=.6*a.y+.2;a.r=.5*Math.sin(1.322*a.time)+.6;a.g=.4+.4*Math.sin(1.5407*a.time+2*a.y);a.b=.4+.4*Math.sin(1.759*a.time+2*a.x);a.xs=.00001<Math.abs(above(a.xs,1E3))?0:a.xs;\\na.ys=.00001<Math.abs(above(a.ys,1E3))?0:a.ys;\"},{baseVals:{enabled:1,thick:1,smoothing:0},init_eqs_str:\"a.q1=0;a.speed=0;a.v=0;a.xs=0;a.ys=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.q1=0;a.speed=.8*a.bass_att;a.v=1E6*a.sample+a.value2*a.bass*.1;a.xs+=Math.sin(a.v)*a.speed*Math.atan(1.51*a.v);a.ys+=Math.sin(a.v)*a.speed*Math.atan(10*a.v);a.x=.5+.5*Math.sin(.1*a.xs)*Math.cos(.2*a.time+a.xs);a.y=.5+.5*Math.sin(.14*a.ys)*Math.cos(.1*a.time+a.xs);a.x=.8*a.x+.1;a.y=.8*a.y+.1;a.x=.25*a.x+.375;a.y=.25*a.y+.375;a.r=.5*Math.sin(1.622*a.time)+.6;a.g=.4+.4*Math.sin(1.2407*a.time+2*a.y);a.b=.4+.4*Math.sin(1.359*a.time+2*a.x);a.xs=.00001<Math.abs(above(a.xs,1E3))?\\n0:a.xs;a.ys=.00001<Math.abs(above(a.ys,1E3))?0:a.ys;\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.basstime=0;a.stickybit=0;a.volavg2=0;a.q1=0;a.decay_r=0;a.sample1=0;a.difftime=0;a.diff=0;a.decay_b=0;a.edge=0;a.volavg=0;a.bit2=0;a.vol=0;a.q2=0;a.q3=0;a.basssum=0;a.decay_g=0;a.sample2=0;\",frame_eqs_str:\"a.basstime+=.03*a.bass;a.q1=4*a.basstime;a.basstime=.00001<Math.abs(below(a.basstime,1E3))?1E3:a.basstime;a.basstime+=.03*a.bass_att;a.vol=pow(a.bass+a.mid+a.treb,2);a.basssum=a.vol;a.stickybit=mod(a.time,2);a.volavg+=a.vol*equal(a.stickybit,1);a.sample1+=equal(a.stickybit,1);a.volavg2+=a.vol*equal(a.stickybit,0);a.sample2+=equal(a.stickybit,0);a.edge=bnot(equal(a.bit2,a.stickybit));a.volavg-=a.volavg*a.edge*a.stickybit;a.volavg2-=a.volavg2*a.edge*equal(a.stickybit,0);a.sample1-=\\na.sample1*a.edge*a.stickybit;a.sample2-=a.sample2*a.edge*equal(a.stickybit,0);a.diff=.00001<Math.abs(equal(a.stickybit,1))?div(a.basssum,div(a.volavg2,a.sample2)):0;a.diff=.00001<Math.abs(equal(a.stickybit,0))?div(a.basssum,div(a.volavg,a.sample1)):a.diff;a.q3=a.diff;a.bit2=mod(a.time,2);a.difftime+=.03*a.diff;a.q2=a.difftime;a.difftime=.00001<Math.abs(above(a.difftime,2E3))?0:a.difftime;a.monitor=3.14*Math.abs(Math.cos(a.time));a.mv_a=above(a.diff,10);\",pixel_eqs_str:\"a.zoom=1+.05*a.q3*a.rad;a.decay_r=.2*a.rad*Math.sin(.35*a.q2)+.85+.1*Math.sin(a.q2);a.decay_g=.2*a.rad*Math.sin(.5*a.q2)+.85+.1*Math.sin(.7*a.q2);a.decay_b=.2*a.rad*Math.sin(.4*a.q2)+.85+.1*Math.sin(.8*a.q2);a.rot=0;\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (vec2(1.0, 0.0) * texsize.z);\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (vec2(0.0, 1.0) * texsize.z);\\n  ret_1 = (((\\n    (texture (sampler_main, (uv + tmpvar_2)).xyz + texture (sampler_main, (uv + tmpvar_2)).xyz)\\n   * 0.5) + (\\n    (texture (sampler_main, (uv + tmpvar_3)).xyz + texture (sampler_main, (uv + tmpvar_3)).xyz)\\n   * 0.5)) - texture (sampler_main, ((\\n    (uv - 0.5)\\n   * 0.9) + 0.5)).xyz);\\n  ret_1 = (ret_1 - 0.4);\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = ret_1;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = ((0.5 - uv) + 0.5);\\n  ret_1 = (mix (texture (sampler_main, uv).xyz, texture (sampler_main, tmpvar_2).xyz, vec3(0.5, 0.5, 0.5)) * 2.0);\\n  ret_1 = (((\\n    ((texture (sampler_blur3, uv).xyz * scale3) + bias3)\\n   * 2.0) + (\\n    ((texture (sampler_blur3, tmpvar_2).xyz * scale3) + bias3)\\n   * 2.0)) + ret_1);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_1;\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.07,decay:.95,echo_zoom:1,echo_alpha:.5,echo_orient:1,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,brighten:1,darken:1,invert:1,wave_a:4.1,wave_scale:1.286,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.99951,warp:.01,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.5,ob_r:.01,ib_size:.26,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,spectrum:1,thick:1},init_eqs_str:\"a.xang=0;a.fov=0;a.yang=0;a.my=0;a.oz=0;a.ayang=0;a.mz=0;a.oy=0;a.mod=0;a.azang=0;a.mx=0;a.vol=0;a.sp=0;a.zang=0;a.axang=0;a.ox=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.sp=1607.68*a.sample;a.vol=.33*(a.bass_att+a.mid_att+a.treb_att);a.vol=.2+.5*(a.value1+a.value2);a.vol=.2;a.mod=.00001<Math.abs(below(a.mid_att,1.8))?a.mid_att+.2:2;a.ox=.5*Math.sin(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.oy=(a.sample-0)*a.mod;a.oz=.5*Math.cos(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.xang=.672*a.time;a.axang=0;a.yang=-1.351*a.time;a.ayang=0;a.zang=-.401*a.time;a.azang=0;a.fov=.6+.2*Math.sin(a.time);a.fov=.5;a.mx=a.ox*Math.cos(a.zang)-a.oy*Math.sin(a.zang);a.my=\\na.ox*Math.sin(a.zang)+a.oy*Math.cos(a.zang);a.ox=a.mx;a.oy=a.my;a.mx=a.ox*Math.cos(a.yang)+a.oz*Math.sin(a.yang);a.mz=-a.ox*Math.sin(a.yang)+a.oz*Math.cos(a.yang);a.ox=a.mx;a.oz=a.mz;a.my=a.oy*Math.cos(a.xang)-a.oz*Math.sin(a.xang);a.mz=a.oy*Math.sin(a.xang)+a.oz*Math.cos(a.xang);a.oy=a.my;a.oz=a.mz;a.oz=Math.abs(a.oz)-2;a.x=div(a.ox*a.fov,a.oz)+.5;a.x=.75*(a.x-.5)+.5;a.y=div(a.oy*a.fov,a.oz)+.5;a.r=1+Math.sin(a.sp);a.b=.5+.5*Math.sin(1.57*a.sample);a.g=.5+.5*Math.cos(1.57*a.sample);a.a=.5+.25*(a.oz+\\n2);\"},{baseVals:{enabled:1,spectrum:1,thick:1},init_eqs_str:\"a.xang=0;a.fov=0;a.yang=0;a.my=0;a.oz=0;a.ayang=0;a.mz=0;a.oy=0;a.mod=0;a.azang=0;a.mx=0;a.vol=0;a.sp=0;a.zang=0;a.axang=0;a.ox=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.sp=1607.68*a.sample;a.vol=.33*(a.bass_att+a.mid_att+a.treb_att);a.vol=.2+.5*(a.value1+a.value2);a.vol=.2;a.mod=.00001<Math.abs(below(a.bass_att,1.8))?a.bass_att+.2:2;a.ox=.5*Math.sin(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.oy=(a.sample-0)*a.mod;a.oz=.5*Math.cos(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.xang=-.321*a.time;a.axang=0;a.yang=1.531*a.time;a.ayang=0;a.zang=-.101*a.time;a.azang=0;a.fov=.6+.2*Math.sin(a.time);a.fov=.5;a.mx=a.ox*Math.cos(a.zang)-a.oy*Math.sin(a.zang);a.my=\\na.ox*Math.sin(a.zang)+a.oy*Math.cos(a.zang);a.ox=a.mx;a.oy=a.my;a.mx=a.ox*Math.cos(a.yang)+a.oz*Math.sin(a.yang);a.mz=-a.ox*Math.sin(a.yang)+a.oz*Math.cos(a.yang);a.ox=a.mx;a.oz=a.mz;a.my=a.oy*Math.cos(a.xang)-a.oz*Math.sin(a.xang);a.mz=a.oy*Math.sin(a.xang)+a.oz*Math.cos(a.xang);a.oy=a.my;a.oz=a.mz;a.oz=Math.abs(a.oz)-2;a.x=div(a.ox*a.fov,a.oz)+.5;a.x=.75*(a.x-.5)+.5;a.y=div(a.oy*a.fov,a.oz)+.5;a.g=1+Math.sin(a.sp);a.r=.5+.5*Math.sin(1.57*a.sample);a.b=.5+.5*Math.cos(1.57*a.sample);a.a=.5+.25*(a.oz+\\n2);\"},{baseVals:{enabled:1,spectrum:1,thick:1},init_eqs_str:\"a.xang=0;a.fov=0;a.yang=0;a.my=0;a.oz=0;a.ayang=0;a.mz=0;a.oy=0;a.mod=0;a.azang=0;a.mx=0;a.vol=0;a.sp=0;a.zang=0;a.axang=0;a.ox=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.sp=1607.68*a.sample;a.vol=.33*(a.bass_att+a.mid_att+a.treb_att);a.vol=.2+.5*(a.value1+a.value2);a.vol=.2;a.mod=.00001<Math.abs(below(a.treb_att,1.8))?a.treb_att+.2:2;a.ox=.5*Math.sin(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.oy=(a.sample-0)*a.mod;a.oz=.5*Math.cos(a.sp)*Math.sin(3.14*a.sample)*a.vol;a.xang=.221*a.time;a.axang=0;a.yang=-.411*a.time;a.ayang=0;a.zang=1.201*a.time;a.azang=0;a.fov=.6+.2*Math.sin(a.time);a.fov=.5;a.mx=a.ox*Math.cos(a.zang)-a.oy*Math.sin(a.zang);a.my=\\na.ox*Math.sin(a.zang)+a.oy*Math.cos(a.zang);a.ox=a.mx;a.oy=a.my;a.mx=a.ox*Math.cos(a.yang)+a.oz*Math.sin(a.yang);a.mz=-a.ox*Math.sin(a.yang)+a.oz*Math.cos(a.yang);a.ox=a.mx;a.oz=a.mz;a.my=a.oy*Math.cos(a.xang)-a.oz*Math.sin(a.xang);a.mz=a.oy*Math.sin(a.xang)+a.oz*Math.cos(a.xang);a.oy=a.my;a.oz=a.mz;a.oz=Math.abs(a.oz)-2;a.x=div(a.ox*a.fov,a.oz)+.5;a.x=.75*(a.x-.5)+.5;a.y=div(a.oy*a.fov,a.oz)+.5;a.b=1+Math.sin(a.sp);a.g=.5+.5*Math.sin(1.57*a.sample);a.r=.5+.5*Math.cos(1.57*a.sample);a.a=.5+.25*(a.oz+\\n2);\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.it=0;a.radm=0;a.mod=0;\",frame_eqs_str:\"a.wave_a=0;\",pixel_eqs_str:\"a.it=.3*Math.sin(.2*a.time);a.radm=.5*a.rad;a.rot=.02*Math.sin(20*(a.radm+a.it));a.mod=Math.sin(5*a.ang);a.mod*=a.mod*a.mod*a.mod*a.mod;a.zoom=1+Math.abs(.01*a.mod);a.zoom*=Math.min(1.05,Math.max(1,Math.max(a.bass,a.treb)));\",warp:\" shader_body { \\n  vec3 xfer_1;\\n  vec3 ret_2;\\n  vec4 tmpvar_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv - 0.5);\\n  tmpvar_3 = texture (sampler_main, (tmpvar_4 + 0.5));\\n  ret_2 = (tmpvar_3.xyz / ((tmpvar_3.x + tmpvar_3.y) + tmpvar_3.z));\\n  ret_2 = texture (sampler_main, ((tmpvar_4 * dot (ret_2, vec3(1.0, 0.975, 0.95))) + 0.5)).xyz;\\n  vec3 tmpvar_5;\\n  tmpvar_5 = clamp (((ret_2 - 0.05) * 99.0), 0.0, 1.0);\\n  xfer_1.x = tmpvar_5.x;\\n  xfer_1.yz = (tmpvar_5.yz * clamp ((\\n    (0.1 - ret_2.xy)\\n   * 99.0), 0.0, 1.0));\\n  ret_2 = (ret_2 + (vec3(-0.014, 0.014, 0.0) * tmpvar_5.xxx));\\n  ret_2 = (ret_2 + (vec3(0.0, -0.08, 0.08) * xfer_1.yyy));\\n  ret_2 = (ret_2 + (vec3(0.0, 0.0, -0.02) * xfer_1.zzz));\\n  ret_2 = (ret_2 + (vec3(5.0, 15.0, 40.0) * (\\n    (texture (sampler_noise_lq, (((uv_orig * texsize.xy) * texsize_noise_lq.zw) + rand_frame.xy)).xyz - 0.5)\\n   / 256.0)));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_2;\\n  ret = tmpvar_6.xyz;\\n }\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:2,gammaadj:1,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wave_a:.001,wave_scale:.958,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:30.965,warpscale:2.572,zoom:1.00901,warp:54e-5,wave_r:0,wave_g:0,wave_b:0,mv_x:25.6,mv_y:9.6,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dx_residual=0;a.dy_residual=0;a.bass_thresh=0;a.rg=0;a.q9=0;\",frame_eqs_str:\"a.wave_r=.85+.25*Math.sin(.437*a.time+1);a.wave_g=.85+.25*Math.sin(.544*a.time+2);a.wave_b=.85+.25*Math.sin(.751*a.time+3);a.rot+=.01*(.6*Math.sin(.381*a.time)+.4*Math.sin(.579*a.time));a.cx+=.21*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.21*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.003*(.6*Math.sin(.234*a.time)+.4*Math.sin(.277*a.time));a.dy+=.003*(.6*Math.sin(.284*a.time)+.4*Math.sin(.247*a.time));a.decay-=.01*equal(mod(a.frame,6),0);a.dx+=\\na.dx_residual;a.dy+=a.dy_residual;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.96*(a.bass_thresh-1.3)+1.3);a.dx_residual=.016*equal(a.bass_thresh,2.13)*Math.sin(7*a.time)+(1-equal(a.bass_thresh,2.13))*a.dx_residual;a.dy_residual=.012*equal(a.bass_thresh,2.13)*Math.sin(9*a.time)+(1-equal(a.bass_thresh,2.13))*a.dy_residual;a.wave_x-=7*a.dx_residual;a.wave_y-=7*a.dy_residual;a.wave_mystery=.03*a.time;a.rg=Math.max(.77*a.rg,.02+.5*Math.min(2,1.3*Math.max(0,a.mid_att-\\n1)));a.q9=a.rg;a.zoom+=.1*a.q9;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = texture (sampler_main, uv).xyz;\\n  ret_1 = (ret_1 + ((ret_1 - \\n    ((((\\n      (texture (sampler_blur1, uv).xyz * scale1)\\n     + bias1) * 0.3) + ((\\n      (texture (sampler_blur2, uv).xyz * scale2)\\n     + bias2) * 0.4)) + (((texture (sampler_blur3, uv).xyz * scale3) + bias3) * 0.3))\\n  ) * 0.3));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 122.0) * (\\n    (clamp ((treb_att - 1.0), 0.0, 1.0) * 0.4)\\n   + 0.3)));\\n  ret_1 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.2, 0.2, 0.2));\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\",comp:\"vec2 xlat_mutabledz;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutableuv3;\\n shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.y = 0.0;\\n  tmpvar_1.x = texsize.z;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = 0.0;\\n  tmpvar_2.y = texsize.w;\\n  vec2 uv_3;\\n  float inten_4;\\n  float dist_5;\\n  vec2 uv1_6;\\n  vec3 ret_7;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_9;\\n  tmpvar_9 = (time / 18.0);\\n  dist_5 = (1.0 - fract((0.25 + tmpvar_9)));\\n  inten_4 = ((sqrt(dist_5) * (1.0 - dist_5)) * 4.0);\\n  uv_3 = (tmpvar_8 * aspect.yx);\\n  xlat_mutableuv3 = (vec2(0.51, 0.55) + (uv_3 * dist_5));\\n  xlat_mutabledz.x = (inten_4 * ((2.0 * \\n    dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29))\\n  ) - (2.0 * \\n    dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29))\\n  )));\\n  xlat_mutabledz.y = (inten_4 * ((2.0 * \\n    dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29))\\n  ) - (2.0 * \\n    dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29))\\n  )));\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (texture (sampler_main, xlat_mutableuv3).xyz * inten_4));\\n  dist_5 = (1.0 - fract((0.5 + tmpvar_9)));\\n  inten_4 = ((sqrt(dist_5) * (1.0 - dist_5)) * 4.0);\\n  uv_3 = (tmpvar_8 * aspect.yx);\\n  xlat_mutableuv3 = (vec2(0.49, 0.55) + (uv_3 * dist_5));\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_4));\\n  dist_5 = (1.0 - fract((0.75 + tmpvar_9)));\\n  inten_4 = ((sqrt(dist_5) * (1.0 - dist_5)) * 4.0);\\n  uv_3 = (tmpvar_8 * aspect.yx);\\n  xlat_mutableuv3 = (vec2(0.51, 0.55) + (uv_3 * dist_5));\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_4));\\n  dist_5 = (1.0 - fract((1.0 + tmpvar_9)));\\n  inten_4 = ((sqrt(dist_5) * (1.0 - dist_5)) * 4.0);\\n  uv_3 = (tmpvar_8 * aspect.yx);\\n  xlat_mutableuv3 = (vec2(0.49, 0.55) + (uv_3 * dist_5));\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_1)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_4 * (\\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 + tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n   - \\n    (2.0 * dot (texture (sampler_main, (xlat_mutableuv3 - tmpvar_2)).xyz, vec3(0.32, 0.49, 0.29)))\\n  )));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_4));\\n  xlat_mutabledz = (xlat_mutabledz * (0.5 + rand_preset.z));\\n  vec2 tmpvar_10;\\n  tmpvar_10 = (2.0 * (rand_preset.xy - 0.5));\\n  uv1_6 = (4.0 * tmpvar_8);\\n  vec2 tmpvar_11;\\n  tmpvar_11 = sin(((uv1_6 + xlat_mutabledz) + tmpvar_10));\\n  vec2 tmpvar_12;\\n  tmpvar_12 = sin(((uv1_6 + \\n    (xlat_mutabledz * 1.4)\\n  ) + tmpvar_10));\\n  vec2 tmpvar_13;\\n  tmpvar_13 = sin(((uv1_6 + \\n    (xlat_mutabledz * 1.8)\\n  ) + tmpvar_10));\\n  vec3 tmpvar_14;\\n  tmpvar_14.x = inversesqrt(dot (tmpvar_11, tmpvar_11));\\n  tmpvar_14.y = inversesqrt(dot (tmpvar_12, tmpvar_12));\\n  tmpvar_14.z = inversesqrt(dot (tmpvar_13, tmpvar_13));\\n  ret_7 = (((\\n    (tmpvar_14 * ((vec3(0.01, 0.01, 0.01) * (1.0 + \\n      (rand_preset.xyz / 2.0)\\n    )) * (0.5 + rand_preset.y)))\\n   * \\n    ((((rand_preset.x - 0.5) * 4.0) * xlat_mutableret1) + (8.0 * (1.0 + rand_preset)).xyz)\\n  ) - (xlat_mutableret1.x * 0.5)) + ((xlat_mutableret1.y + xlat_mutableret1.z) / 3.0));\\n  ret_7 = (ret_7 - ((slow_roam_sin.wzy * roam_cos.zxy) * 0.4));\\n  ret_7 = (ret_7 * (1.0 + ret_7));\\n  vec4 tmpvar_15;\\n  tmpvar_15.w = 1.0;\\n  tmpvar_15.xyz = ret_7;\\n  ret = tmpvar_15.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.995,echo_zoom:1,echo_orient:1,wave_mode:5,wave_brighten:0,wrap:0,wave_a:100,wave_scale:.721,wave_smoothing:.5,modwavealphastart:.5,modwavealphaend:1,fshader:1,dx:1e-5,dy:1e-5,warp:.01,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:0,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:0,mv_y:0,mv_l:1,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.thresh=0;a.dx_r=0;a.dy_r=0;a.xs=0;\",frame_eqs_str:\"a.wave_r=.5+.5*Math.sin(6*a.time);a.wave_g=.5+.5*Math.sin(4.1*a.time);a.wave_b=-1+(1-a.wave_r+1-a.wave_g);a.warp=0;\",pixel_eqs_str:\"a.thresh=2*above(a.bass_att,a.thresh)+(1-above(a.bass_att,a.thresh))*(.96*(a.thresh-1.3)+1.3);a.dx_r=.015*equal(a.thresh,2)*Math.sin(5*a.time)+(1-equal(a.thresh,2))*a.dx_r;a.dy_r=.015*equal(a.thresh,2)*Math.sin(6*a.time)+(1-equal(a.thresh,2))*a.dy_r;a.xs=above(Math.sin(12*a.dx_r*a.bass),0)*a.dy_r*Math.sin(2*a.rad)+below(Math.sin(12*a.dx_r*a.bass),0)*Math.cos(a.time)*a.dx_r*Math.sin(.6*a.rad);a.zoom+=Math.abs(12*a.xs);a.rot+=5*a.xs*Math.cos(1-a.xs*a.rad*12*a.dx_r);a.dx+=a.dx_r;\\na.dy+=a.dy_r;\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (vec2(1280.0, 1024.0) * texsize.zw);\\n  float tmpvar_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv + vec2(0.005, 0.0));\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - vec2(0.005, 0.0));\\n  tmpvar_4 = (((\\n    (texture (sampler_blur2, tmpvar_5).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_6).xyz * scale2)\\n   + bias2)).x * tmpvar_3.x);\\n  float tmpvar_7;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (uv + vec2(0.0, 0.005));\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (uv - vec2(0.0, 0.005));\\n  tmpvar_7 = (((\\n    (texture (sampler_blur2, tmpvar_8).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_9).xyz * scale2)\\n   + bias2)).x * tmpvar_3.y);\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4;\\n  tmpvar_10.y = tmpvar_7;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = (((\\n    (texture (sampler_blur2, tmpvar_5).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_6).xyz * scale2)\\n   + bias2)).x * tmpvar_3.x);\\n  tmpvar_11.y = (((\\n    (texture (sampler_blur2, tmpvar_8).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_9).xyz * scale2)\\n   + bias2)).x * tmpvar_3.y);\\n  ret_2.x = texture (sampler_fw_main, ((uv - (tmpvar_10 * 0.01)) + (tmpvar_11 * 0.003))).x;\\n  vec4 tmpvar_12;\\n  tmpvar_12 = texture (sampler_blur3, uv);\\n  ret_2.x = (ret_2.x + ((ret_2.x - \\n    ((tmpvar_12.xyz * scale3) + bias3)\\n  .x) * 0.1));\\n  ret_2.x = (ret_2.x + 0.004);\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = tmpvar_7;\\n  tmpvar_13.y = -(tmpvar_4);\\n  my_uv_1 = (uv + ((tmpvar_13 * 0.05) * (1.2 - \\n    ((tmpvar_12.xyz * scale3) + bias3)\\n  .y)));\\n  ret_2.z = texture (sampler_fw_main, my_uv_1).z;\\n  vec2 x_14;\\n  x_14 = (my_uv_1 - uv);\\n  ret_2.z = (ret_2.z + ((\\n    ((ret_2.z - ((texture (sampler_blur1, uv).xyz * scale1) + bias1).z) * sqrt(dot (x_14, x_14)))\\n   * 180.0) / sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  )));\\n  ret_2.z = (ret_2.z * 0.8);\\n  ret_2.z = (ret_2.z + 0.004);\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = -(tmpvar_7);\\n  tmpvar_15.y = tmpvar_4;\\n  my_uv_1 = (tmpvar_15 * 0.045);\\n  vec2 tmpvar_16;\\n  tmpvar_16.x = (((\\n    (texture (sampler_blur2, (uv + vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (uv - vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2)).y * tmpvar_3.x);\\n  tmpvar_16.y = (((\\n    (texture (sampler_blur2, (uv + vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (uv - vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2)).y * tmpvar_3.y);\\n  my_uv_1 = (my_uv_1 + (uv - (tmpvar_16 * 0.03)));\\n  ret_2.y = texture (sampler_fw_main, my_uv_1).y;\\n  ret_2.y = (ret_2.y + ((\\n    (ret_2.y - ((texture (sampler_blur3, my_uv_1).xyz * scale3) + bias3).y)\\n   * 0.1) + 0.01));\\n  vec4 tmpvar_17;\\n  tmpvar_17.w = 1.0;\\n  tmpvar_17.xyz = ret_2;\\n  ret = tmpvar_17.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = texture (sampler_main, uv).xyz;\\n  ret_1 = (ret_1 * hue_shader);\\n  vec3 tmpvar_2;\\n  tmpvar_2 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.5, 1.0, 0.1));\\n  ret_1 = tmpvar_2;\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = tmpvar_2;\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.998,echo_zoom:1.421,wave_mode:7,additivewave:1,modwavealphabyvolume:1,darken_center:1,wave_a:1.193,wave_scale:1.489,wave_smoothing:0,modwavealphastart:.87,modwavealphaend:1.09,warpscale:3.138,zoom:1.003,warp:.09218,wave_r:.5,wave_g:.5,wave_b:.5,wave_x:.6,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.t2=0;\",frame_eqs_str:\"a.wave_r+=.365*(.6*Math.sin(4.437*a.time)+.4*Math.sin(3.97*a.time));a.wave_g+=.365*(.6*Math.sin(4.344*a.time)+.4*Math.sin(3.841*a.time));a.wave_b+=.365*(.6*Math.sin(4.251*a.time)+.4*Math.sin(3.055*a.time));a.rot+=.02*(.6*Math.sin(.181*a.time)+.09*Math.sin(-.279*a.time));a.zoom+=.025*(.6*Math.sin(.3131*a.time+2)+.4*Math.sin(-.479*a.time+4));a.decay-=.01*equal(mod(a.frame,6),0);a.t2=6*a.time;a.wave_x=.5+.2*(.6*Math.sin(.374*a.t2)+.4*Math.sin(.294*a.t2));a.wave_y=.5+.2*(.6*Math.sin(.393*\\na.t2)+.4*Math.sin(.223*a.t2));\",pixel_eqs_str:\"a.dx=0;a.dy=0;a.dx+=2*div(Math.cos(29.37*a.y-1.9*a.time),a.pixelsx);a.dy+=2*div(Math.cos(33.21*a.x-1.7*a.time),a.pixelsy);a.dx+=1.5*div(Math.cos(77.55*a.y-2.1*a.time),a.pixelsx);a.dy+=1.5*div(Math.cos(78.32*a.x-2.4*a.time),a.pixelsy);\",warp:\" shader_body { \\n  vec2 dxy_1;\\n  dxy_1.x = cos(((154.56 * uv_orig.y) - time));\\n  dxy_1.y = cos(((154.56 * uv_orig.x) - time));\\n  float tmpvar_2;\\n  tmpvar_2 = (time * 5.0);\\n  dxy_1.x = (dxy_1.x + cos((\\n    (412.16 * uv_orig.y)\\n   - tmpvar_2)));\\n  dxy_1.y = (dxy_1.y + cos((\\n    (412.16 * uv_orig.x)\\n   - tmpvar_2)));\\n  dxy_1.y = (dxy_1.y + 0.15);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = (max (texture (sampler_fw_main, (uv + \\n    (dxy_1 * texsize.zw)\\n  )).xyz, (texture (sampler_main, uv_orig).xyz * 0.8)) - 0.004);\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = ((texture (sampler_main, uv).xyz * 0.8) + ((\\n    (texture (sampler_blur1, uv).xyz * scale1)\\n   + bias1) * 0.7));\\n  ret = tmpvar_1.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.9,echo_zoom:1.169,wave_mode:2,additivewave:1,wave_dots:1,wave_thick:1,wave_a:.274,wave_scale:2.827,wave_smoothing:.09,modwavealphastart:.83,modwavealphaend:1.31,warpscale:3.138,zoom:.993,warp:54e-5,wave_r:.5,wave_g:.5,wave_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dx_residual=0;a.dy_residual=0;a.bass_thresh=0;\",frame_eqs_str:\"a.wave_r=.85+.25*Math.sin(.437*a.time+1);a.wave_g=.85+.25*Math.sin(.544*a.time+2);a.wave_b=.85+.25*Math.sin(.751*a.time+3);a.rot+=.01*(.6*Math.sin(.381*a.time)+.4*Math.sin(.579*a.time));a.cx+=.21*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.21*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.003*(.6*Math.sin(.234*a.time)+.4*Math.sin(.277*a.time));a.dy+=.003*(.6*Math.sin(.284*a.time)+.4*Math.sin(.247*a.time));a.decay-=.01*equal(mod(a.frame,6),0);a.dx+=\\na.dx_residual;a.dy+=a.dy_residual;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.96*(a.bass_thresh-1.3)+1.3);a.dx_residual=.016*equal(a.bass_thresh,2.13)*Math.sin(7*a.time)+(1-equal(a.bass_thresh,2.13))*a.dx_residual;a.dy_residual=.012*equal(a.bass_thresh,2.13)*Math.sin(9*a.time)+(1-equal(a.bass_thresh,2.13))*a.dy_residual;a.wave_x-=7*a.dx_residual;a.wave_y-=7*a.dy_residual;a.wave_mystery=.03*a.time;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = (tmpvar_2.xyz + ((tmpvar_2.xyz - \\n    ((texture (sampler_blur1, uv).xyz * scale1) + bias1)\\n  ) * 0.2));\\n  ret_1 = (ret_1 - 0.02);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_1;\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_main, uv).xyz * 1.15);\\n  ret = tmpvar_1.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,additivewave:1,wave_brighten:0,wave_a:.001,wave_scale:.01,wave_smoothing:.63,wave_mystery:-1,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:30.965,warpscale:2.572,zoom:1.00901,warp:54e-5,wave_r:.65,wave_g:.65,wave_b:.65,mv_x:12.8,mv_y:9.6,mv_l:1,mv_g:.91,mv_b:.71,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,additive:1,rad:.49138,r:0,g:1,b:1,border_a:0},init_eqs_str:\"a.q4=0;a.q5=0;\",frame_eqs_str:\"a.x=.5+a.q4;a.y=.5+a.q5;a.a=a.bass_att+a.mid_att+a.treb_att;a.a*=.25;a.a=a.a*a.a*1.5;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dx_residual=0;a.dy_residual=0;a.bass_thresh=0;\",frame_eqs_str:\"a.wave_r=.85+.25*Math.sin(.437*a.time+1);a.wave_g=.85+.25*Math.sin(.544*a.time+2);a.wave_b=.85+.25*Math.sin(.751*a.time+3);a.rot+=.01*(.6*Math.sin(.381*a.time)+.4*Math.sin(.579*a.time));a.cx+=.21*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.21*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.003*(.6*Math.sin(.234*a.time)+.4*Math.sin(.277*a.time));a.dy+=.003*(.6*Math.sin(.284*a.time)+.4*Math.sin(.247*a.time));a.decay-=.01*equal(mod(a.frame,6),0);a.dx+=\\na.dx_residual;a.dy+=a.dy_residual;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.96*(a.bass_thresh-1.3)+1.3);a.dx_residual=.016*equal(a.bass_thresh,2.13)*Math.sin(7*a.time)+(1-equal(a.bass_thresh,2.13))*a.dx_residual;a.dy_residual=.012*equal(a.bass_thresh,2.13)*Math.sin(9*a.time)+(1-equal(a.bass_thresh,2.13))*a.dy_residual;a.wave_x-=7*a.dx_residual;a.wave_y-=7*a.dy_residual;a.wave_mystery=.03*a.time;a.zoom+=.005*(.6*Math.sin(.1934*a.time+3)+.4*Math.sin(.307*\\na.time+9));a.zoom+=.2*Math.max(0,a.bass_att-1.1);a.warp+=.5*Math.max(0,a.treb-1.1);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = (tmpvar_2.xyz + ((tmpvar_2.xyz - \\n    ((texture (sampler_blur2, uv).xyz * scale2) + bias2)\\n  ) * 0.6));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 12.0) * clamp (\\n    (treb_att - 1.0)\\n  , 0.0, 1.0)));\\n  vec3 tmpvar_3;\\n  tmpvar_3 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.04, 0.04, 0.04));\\n  ret_1 = tmpvar_3;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = tmpvar_3;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec3 N_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (vec2(1.0, 0.0) * texsize.zw);\\n  N_1.x = ((texture (sampler_main, (uv_orig + tmpvar_3)).xyz - texture (sampler_main, (uv_orig - tmpvar_3)).xyz).x * 0.8);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (vec2(0.0, 1.0) * texsize.zw);\\n  N_1.y = ((texture (sampler_main, (uv_orig + tmpvar_4)).xyz - texture (sampler_main, (uv_orig - tmpvar_4)).xyz).x * 0.8);\\n  N_1.x = (N_1.x + ((\\n    ((texture (sampler_blur1, (uv_orig + tmpvar_3)).xyz * scale1) + bias1)\\n   - \\n    ((texture (sampler_blur1, (uv_orig - tmpvar_3)).xyz * scale1) + bias1)\\n  ).x * 0.2));\\n  N_1.y = (N_1.y + ((\\n    ((texture (sampler_blur1, (uv_orig + tmpvar_4)).xyz * scale1) + bias1)\\n   - \\n    ((texture (sampler_blur1, (uv_orig - tmpvar_4)).xyz * scale1) + bias1)\\n  ).x * 0.2));\\n  N_1.z = -0.077;\\n  vec3 tmpvar_5;\\n  tmpvar_5 = normalize(N_1);\\n  N_1 = tmpvar_5;\\n  vec3 tmpvar_6;\\n  tmpvar_6.z = -0.8;\\n  tmpvar_6.x = q9;\\n  tmpvar_6.y = q10;\\n  vec3 tmpvar_7;\\n  tmpvar_7.z = 0.0;\\n  tmpvar_7.xy = ((uv_orig * 2.0) - 1.0);\\n  vec3 tmpvar_8;\\n  tmpvar_8 = normalize((tmpvar_6 - tmpvar_7));\\n  vec3 tmpvar_9;\\n  tmpvar_9 = normalize((tmpvar_7 - vec3(0.0, 0.0, 1.0)));\\n  ret_2 = (vec3(clamp (dot (tmpvar_5, tmpvar_8), 0.0, 1.0)) * vec3(1.2, 0.9, 0.7));\\n  ret_2 = (ret_2 * normalize((\\n    (texture (sampler_blur3, uv_orig).xyz * scale3)\\n   + bias3).yzx));\\n  ret_2 = (ret_2 + (pow (\\n    clamp (dot (normalize((tmpvar_9 + \\n      ((2.0 * tmpvar_5) * dot (tmpvar_9, tmpvar_5))\\n    )), tmpvar_8), 0.0, 1.0)\\n  , 32.0) * 0.5));\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = ret_2;\\n  ret = tmpvar_10.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:1,echo_zoom:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.535239,wave_smoothing:0,wave_mystery:-.48,modwavealphastart:1,modwavealphaend:1.1,warpscale:3.138,fshader:1,zoom:1.023,warp:.122616,wave_g:.65,wave_b:0,mv_x:6.4,mv_y:48,mv_dx:.5,mv_dy:.5,mv_l:5,mv_r:.013716,mv_g:.872347,mv_b:.522466,mv_a:0},shapes:[{baseVals:{enabled:1,thickoutline:1,textured:1,rad:.746302,tex_zoom:.942039,g:1,b:1,r2:1,b2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.val=0;\",frame_eqs_str:\"a.ang=.5*Math.sin(a.time)+.5;a.val=3;a.a2=.33*a.val;a.a=.33*a.val;a.rad=.4*Math.cos(.3*a.time)+.65;a.x=.25*Math.sin(.25*a.time)+.5;a.y=.25*Math.cos(.45*a.time)+.5;\"},{baseVals:{enabled:1,thickoutline:1,textured:1,rad:.746302,tex_zoom:.942039,g:1,b:1,r2:1,b2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.val=0;\",frame_eqs_str:\"a.ang=.5*Math.cos(.3*a.time)+.5;a.val=3;a.a2=.33*a.val;a.a=.33*a.val;a.rad=.4*Math.sin(.3*a.time)+.65;a.x=.25*Math.cos(.25*a.time)+.5;a.y=.25*Math.sin(.45*a.time)+.5;\"},{baseVals:{enabled:1,thickoutline:1,rad:.364564,r:0,g2:0,a2:1,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.h2=0;a.vr=0;a.vg=0;a.vb=0;a.dist=0;a.maat=0;\",frame_eqs_str:\"a.h2+=.8*above(a.treb,1.32)*.9;a.vr=.5*Math.sin(.8*a.h2)+.5;a.vg=.5*Math.sin(.5*a.h2)+.5;a.vb=.5*Math.sin(.1*a.h2)+.5;a.g=a.vg;a.r=a.vr;a.b=a.vb;a.g2=a.g;a.r2=a.r;a.b2=a.b;a.dist=.01*mod(a.frame,100);a.maat+=above(a.bass_att,1.5);a.maat*=below(a.maat,16);a.x=.00001<Math.abs(below(a.maat,8))?.00001<Math.abs(below(a.maat,4))?a.dist:1-a.dist:a.x;a.y=.00001<Math.abs(above(a.maat,8))?.00001<Math.abs(above(a.maat,4))?a.dist:1-a.dist:a.y;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dx_residual=0;a.dy_residual=0;a.bass_thresh=0;\",frame_eqs_str:\"a.wave_r=1;a.wave_g=0;a.wave_b=0;a.wave_r=sqrt(a.wave_r);a.wave_g=sqrt(a.wave_g);a.wave_b=sqrt(a.wave_b);a.rot+=.01*(.6*Math.sin(.381*a.time)+.4*Math.sin(.579*a.time));a.cx+=.21*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.21*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.003*(.6*Math.sin(.234*a.time)+.4*Math.sin(.277*a.time));a.dy+=.003*(.6*Math.sin(.284*a.time)+.4*Math.sin(.247*a.time));a.decay-=.01*equal(mod(a.frame,6),0);a.dx+=a.dx_residual;a.dy+=\\na.dy_residual;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.96*(a.bass_thresh-1.3)+1.3);a.dx_residual=.016*equal(a.bass_thresh,2.13)*Math.sin(7*a.time)+(1-equal(a.bass_thresh,2.13))*a.dx_residual;a.dy_residual=.012*equal(a.bass_thresh,2.13)*Math.sin(9*a.time)+(1-equal(a.bass_thresh,2.13))*a.dy_residual;a.wave_x-=7*a.dx_residual;a.wave_y-=7*a.dy_residual;a.wave_mystery=.03*a.time;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_main, (uv + (\\n    (texture (sampler_main, (uv + texsize.zw)).xy - 0.37)\\n   * 0.03))).xyz - 0.004);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.05 + (0.9 * uv));\\n  ret_2 = (abs((\\n    ((texture (sampler_blur1, uv_1).xyz * scale1) + bias1)\\n   - texture (sampler_main, uv_1).xyz)) * 6.0);\\n  ret_2 = (ret_2 * 1.333);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_2;\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.7,echo_zoom:1.16936,wave_mode:2,wave_dots:1,wave_brighten:0,wave_a:.001,wave_scale:.011726,wave_smoothing:.9,zoom:.999902,warp:.01,wave_r:.5,wave_g:.4,wave_b:.3,ob_size:.0065,ib_size:.26,mv_x:0,mv_y:43.199997,mv_l:1,mv_g:.91,mv_b:.71,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,r:.1,b:.7},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.r1=0;a.g2=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.r2=0;a.ang=0;a.sinang=0;a.tm=0;a.b2=0;a.t2=0;a.zp=0;a.g1=0;a.t4=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5);a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.xq=a.xp;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.3;a.ang=3.14+1.5*\\nMath.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*Math.cos(a.tm)-.5;\\na.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=a.a;a.b+=.3*pow(1-a.sample,2);a.r1=a.t1;a.g1=a.t2;a.b1=a.t3;a.r2=a.t4;a.g2=a.t5;a.b2=a.t6;a.r=a.r1*a.flip+a.r2*(1-a.flip);a.g=a.g1*a.flip+a.g2*(1-a.flip);a.b=a.b1*a.flip+a.b2*(1-a.flip);\"},{baseVals:{enabled:1,r:.2,b:.6},init_eqs_str:\"a.n=0;a.yq=0;a.xp=0;a.t5=0;a.xs=0;a.yp=0;a.t1=0;a.q1=0;a.cosang=0;a.r1=0;a.g2=0;a.xq=0;a.t3=0;a.flip=0;a.t6=0;a.ys=0;a.zq=0;a.phs=0;a.r2=0;a.ang=0;a.sinang=0;a.tm=0;a.b2=0;a.t2=0;a.zp=0;a.g1=0;a.t4=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.t1=.5*Math.sin(a.time)+.5;a.t2=.5*Math.sin(a.time+2.1)+.5;a.t3=.5*Math.sin(a.time+4.2)+.5;a.t4=.5*Math.sin(a.time+1.1)+.5;a.t5=.5*Math.sin(a.time+3.1)+.5;a.t6=.5*Math.sin(a.time+5.2)+.5;\",point_eqs_str:\"a.n=6.283*a.sample;a.phs=.2*-a.sample;a.tm=a.q1+a.phs;a.flip+=1;a.flip*=below(a.flip,2);a.xp=0;a.yp=.1*a.flip+.2*(.5*Math.sin(a.tm)+.5)+.1;a.yp=-a.yp;a.zp=0;a.ang=.5*Math.sin(2*a.tm)+.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.yq=a.yp;a.zq=a.zp;a.ang=8*a.tm;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.3;\\na.ang=3.14+1.5*Math.sin(2*a.tm-.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp;a.yq=a.yp*a.sinang+a.zp*a.cosang;a.zq=a.yp*a.cosang-a.zp*a.sinang;a.ang=-1+Math.cos(3.1*a.tm+.5);a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq*a.sinang+a.yq*a.cosang;a.yp=a.xq*a.cosang-a.yq*a.sinang;a.zp=a.zq;a.zp-=.35;a.ang=1.75*Math.cos(2.3*a.tm)-1.05;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xq=a.xp*a.sinang+a.zp*a.cosang;a.yq=a.yp;a.zq=a.xp*a.cosang-a.zp*a.sinang;a.ang=.5*Math.cos(a.tm)-\\n.5;a.sinang=Math.sin(a.ang);a.cosang=Math.cos(a.ang);a.xp=a.xq;a.yp=a.yq*a.cosang-a.zq*a.sinang;a.zp=a.yq*a.sinang+a.zq*a.cosang;a.zp+=2;a.xs=div(a.xp,a.zp);a.ys=div(a.yp,a.zp);a.x=a.xs+.5;a.y=1.3*a.ys+.5;a.a=.00001<Math.abs(equal(a.q8,1))?1-a.sample:a.sample;a.a*=a.a;a.b+=.3*pow(1-a.sample,2);a.r1=a.t1;a.g1=a.t2;a.b1=a.t3;a.r2=a.t4;a.g2=a.t5;a.b2=a.t6;a.r=a.r1*a.flip+a.r2*(1-a.flip);a.g=a.g1*a.flip+a.g2*(1-a.flip);a.b=a.b1*a.flip+a.b2*(1-a.flip);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.movement=0;a.q1=0;\",frame_eqs_str:\"a.movement=a.movement+.01*(a.bass+a.bass_att)+.001*pow(a.bass+1,3);a.q1=a.movement;a.monitor=a.q1;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = texture (sampler_main, uv).xyz;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (normalize((uv - uv_orig)) * texsize.zw);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 0.0;\\n  tmpvar_3.xyz = ret_1;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 0.0;\\n  tmpvar_4.xyz = max (tmpvar_3, (texture (sampler_main, (uv - tmpvar_2)) * 0.9)).xyz;\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 0.0;\\n  tmpvar_5.xyz = max (tmpvar_4, (texture (sampler_main, (uv + tmpvar_2)) * 0.97)).xyz;\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 0.0;\\n  tmpvar_6.xyz = max (tmpvar_5, (texture (sampler_main, (uv + \\n    (tmpvar_2 * 2.0)\\n  )) * 0.97)).xyz;\\n  ret_1 = (max (tmpvar_6, (texture (sampler_main, \\n    (uv + (tmpvar_2 * 3.0))\\n  ) * 0.9)).xyz * 0.92);\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = ret_1;\\n  ret = tmpvar_7.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.05 + (0.9 * uv));\\n  ret_2 = (abs((\\n    ((texture (sampler_blur1, uv_1).xyz * scale1) + bias1)\\n   - texture (sampler_main, uv_1).xyz)) * 6.0);\\n  ret_2 = (ret_2 * 1.333);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_2;\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1,echo_orient:3,wave_mode:1,wave_thick:1,wrap:0,darken_center:1,wave_a:.3,wave_scale:.881,wave_smoothing:.5,wave_mystery:-1,warpscale:2.853,zoomexp:3.6,zoom:1.02109,rot:-.16,warp:.309,wave_r:.6,wave_g:.6,wave_b:.6,wave_y:.47,mv_l:1.75},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q8=0;a.oldq8=0;\",frame_eqs_str:\"a.wave_r+=.4*(.6*Math.sin(.933*a.time)+.4*Math.sin(1.045*a.time));a.wave_g+=.4*(.6*Math.sin(.9*a.time)+.4*Math.sin(.956*a.time));a.wave_b+=.4*(.6*Math.sin(.91*a.time)+.4*Math.sin(.92*a.time));a.q8=a.oldq8+(.00001<Math.abs(above(a.bass+a.bass_att,1.8))?a.q8+.0005*pow(a.bass+a.bass_att-1,9):0);a.oldq8=a.q8;a.monitor=a.q8;a.zoom+=.023*(.6*Math.sin(.339*a.q8)+.4*Math.sin(.276*a.q8));a.rot+=.03*(.6*Math.sin(.381*a.q8)+.4*Math.sin(.579*a.q8));a.mv_r=a.wave_r;a.mv_b=a.wave_b;a.mv_g=\\na.wave_g;a.mv_x=1.25;a.mv_y=1.25;a.mv_dx=.1*Math.sin(1.1*a.time);a.mv_dy=.1*Math.cos(1.112*a.time);\",pixel_eqs_str:\"a.rot+=div(1,10*(a.rad+.2+.1*Math.sin(a.q8)));\",warp:\"\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1 = texture (sampler_main, uv);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = (tmpvar_1.xyz * (1.0 + (\\n    (abs((fract(\\n      (tmpvar_1.xyz * 8.0)\\n    ) - 0.5)) - 0.25)\\n   * 0.4)));\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:2.001,decay:.95,echo_zoom:.9996,wave_mode:1,wrap:0,wave_a:3.072644,wave_scale:1.285746,wave_smoothing:0,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.999513,warp:.0101,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.005,ob_a:.8,ib_size:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"\",frame_eqs_str:\"a.wave_r+=.5*Math.sin(1.13*a.time);a.wave_g+=.5*Math.sin(1.23*a.time);a.wave_b+=.5*Math.sin(1.33*a.time);\",pixel_eqs_str:\"a.zoom+=.05*(Math.sin(6*a.ang)+.3*Math.sin(Math.sin(2*a.time*Math.sin(a.time)*a.rad))-.1*Math.cos(a.rad));a.rot+=.5*Math.sin(.5-a.rad)*Math.cos(.02*(.5-a.rad)+a.time);a.sx+=.01*(.99-a.rad)*Math.sin(.733*a.time)*below(Math.sin(a.time),0);a.sy+=.01*(.99-a.rad)*Math.cos(.953*a.time)*above(Math.sin(a.time),0);a.zoom-=.05*(1-a.rad)*below(a.rad,.5);\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_main, (uv + (\\n    (texture (sampler_main, (uv + texsize.zw)).xy - 0.37)\\n   * 0.03))).xyz - 0.004);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.03 + (0.94 * uv));\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 0.7);\\n  ret_2 = (texture (sampler_main, (uv_1 + (tmpvar_3 * vec2(3.5, 0.0)))).xyz * 3.0);\\n  ret_2 = (ret_2 + (texture (sampler_main, (uv_1 + \\n    (tmpvar_3 * vec2(0.0, 3.5))\\n  )).xyz * 3.0));\\n  ret_2 = (ret_2 + (texture (sampler_main, (uv_1 + \\n    (tmpvar_3 * vec2(0.0, -3.5))\\n  )).xyz * -2.0));\\n  ret_2 = (ret_2 + (texture (sampler_main, (uv_1 + \\n    (tmpvar_3 * vec2(-3.5, 0.0))\\n  )).xyz * -2.0));\\n  ret_2 = (ret_2 / 2.0);\\n  ret_2 = (ret_2 * (1.0 + (0.15 * \\n    ((texture (sampler_noise_lq, (rand_frame.xy + (\\n      (uv_1 * texsize.xy)\\n     * texsize_noise_lq.zw))).xxx * 2.0) - 1.0)\\n  )));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = pow (ret_2, vec3(0.5, 0.8, 1.0));\\n  ret_2 = tmpvar_4;\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = tmpvar_4;\\n  ret = tmpvar_5.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:.97,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:2,wave_brighten:0,wrap:0,wave_a:100,wave_scale:.797,wave_smoothing:.5,modwavealphastart:.5,modwavealphaend:1,dx:1e-5,dy:1e-5,warp:.01,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.005,ob_a:1,ib_r:0,ib_g:0,ib_b:0,ib_a:.1,mv_x:0,mv_y:0,mv_l:1,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.thresh=0;a.dx_r=0;a.dy_r=0;\",frame_eqs_str:\"a.warp=0;a.ob_r=a.ob_r+.8*Math.sin(1.1*a.time)+1.1*Math.cos(2*a.time);a.ob_b=a.ob_b+.9*Math.sin(1.2*a.time)+Math.cos(1.5*a.time);a.ob_g=a.ob_g+.7*Math.sin(a.time)+Math.sin(.4*a.time);a.wave_r=Math.abs(a.ob_r+.2);a.wave_g=Math.abs(a.ob_g+.2);a.wave_b=Math.abs(a.ob_b+.2);a.ib_b=a.ib_b+.44*Math.cos(1.5*a.time)+.7*Math.tan(a.time);a.ib_g+=2*Math.sin(a.time*a.bass_att);a.ib_r=a.ib_r+.8*Math.sin(1.2*a.time)+1.3*Math.cos(1.8*a.time);\",pixel_eqs_str:\"a.thresh=2*above(a.bass_att,a.thresh)+(1-above(a.bass_att,a.thresh))*(.96*(a.thresh-1.3)+1.3);a.dx_r=.015*equal(a.thresh,2)*Math.sin(5*a.time)+(1-equal(a.thresh,2))*a.dx_r;a.dy_r=.015*equal(a.thresh,2)*Math.sin(6*a.time)+(1-equal(a.thresh,2))*a.dy_r;a.zoom+=.07*a.treb*Math.abs(Math.sin(a.time*a.rad))*(.3-a.rad);a.dy+=a.dy_r*below(a.rad,.5-.2*a.time);a.dx+=a.dx_r*below(a.rad,.5-.2*a.time);a.rot+=.7*a.bass_att*Math.sin(Math.abs(a.dx_r*(1-a.rad)*2*a.time+Math.cos(12*a.rad)))*.2;\\n\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = (tmpvar_2.xyz + ((tmpvar_2.xyz - \\n    ((texture (sampler_blur1, uv).xyz * scale1) + bias1)\\n  ) * 0.3));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    (texture (sampler_noise_lq, ((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 0.1))).xyz - 0.5)\\n   / 256.0) * 28.0));\\n  vec3 tmpvar_3;\\n  tmpvar_3 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.04, 0.04, 0.04));\\n  ret_1 = tmpvar_3;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = tmpvar_3;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\"\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,additivewave:1,modwavealphabyvolume:1,wave_a:.009,wave_scale:2.713,wave_smoothing:0,modwavealphastart:1.2,modwavealphaend:1.2,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.44,wave_g:.4,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:3,additive:1,num_inst:175,rad:.20065,ang:.75398,tex_ang:3.14159,tex_zoom:.99979,r:0,g2:0,border_r:.01,border_g:0,border_a:1},init_eqs_str:\"a.my_z=0;a.d=0;a.y3=0;a.z2=0;a.y1=0;a.w=0;a.q12=0;a.w2=0;a.x1=0;a.q13=0;a.q15=0;a.dy1=0;a.zoom=0;a.p=0;a.q5=0;a.dz1=0;a.z3=0;a.w3=0;a.my_x=0;a.x3=0;a.my_y=0;a.q11=0;a.dd=0;a.q4=0;a.yy1=0;a.q16=0;a.w1=0;a.x2=0;a.q17=0;a.l=0;a.y2=0;a.dx1=0;a.zz1=0;a.q14=0;a.z1=0;a.q3=0;a.q32=0;a.xx1=0;\",frame_eqs_str:\"a.xx1=.00001<Math.abs(equal(a.instance,0))?a.q11:a.xx1;a.yy1=.00001<Math.abs(equal(a.instance,0))?a.q12:a.yy1;a.zz1=.00001<Math.abs(equal(a.instance,0))?a.q13:a.zz1;a.dx1=a.q14*(a.yy1-a.xx1);a.dy1=a.xx1*(a.q15-a.zz1)-a.yy1;a.dz1=a.xx1*a.yy1-a.q16*a.zz1;a.dd=sqrt(a.dx1*a.dx1+a.dy1*a.dy1+a.dz1*a.dz1);a.xx1+=div(a.q17*a.dx1,a.dd);a.yy1+=div(a.q17*a.dy1,a.dd);a.zz1+=div(a.q17*a.dz1,a.dd);a.my_x=.1*a.xx1;a.my_y=.1*a.yy1;a.my_z=.1*a.zz1-3;a.d=4.75;a.zoom=.55+.25*Math.sin(.5*a.q32);\\na.w1=a.q3;a.w2=a.q4;a.w3=a.q5;a.x1=Math.cos(a.w1)*a.my_x+Math.sin(a.w1)*a.my_y;a.y1=-Math.sin(a.w1)*a.my_x+Math.cos(a.w1)*a.my_y;a.z1=a.my_z;a.x2=Math.cos(a.w2)*a.x1+Math.sin(a.w2)*a.z1;a.z2=-Math.sin(a.w2)*a.x1+Math.cos(a.w2)*a.z1;a.y2=a.y1;a.y3=Math.cos(a.w3)*a.y2+Math.sin(a.w3)*a.z2;a.z3=-Math.sin(a.w3)*a.y2+Math.cos(a.w3)*a.z2;a.x3=a.x2;a.l=sqrt(a.x3*a.x3+a.y3*a.y3);a.w=Math.atan2(a.x3,a.y3);a.p=Math.tan(Math.asin(1)+Math.atan2(a.d+a.z3,a.l));a.d=sqrt(a.x3*a.x3+a.y3*a.y3+(a.z3+a.d)*(a.z3+a.d));\\na.my_x=a.zoom*Math.sin(a.w)*a.p;a.my_y=a.zoom*Math.cos(a.w)*a.p;a.x=.5+a.my_x;a.y=.5+a.my_y;a.rad=div(a.rad,a.d);a.ang-=div(a.instance,a.num_inst)*Math.asin(1)*8;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q13=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.movz=0;a.trel=0;a.q9=0;a.rott=0;a.vol__=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.trel_=0;a.vx=0;a.dec_slow=0;a.q11=0;a.q10=0;a.vy=0;a.q4=0;a.dir=0;a.dir_=0;a.p2=0;a.avg=0;a.trig=0;a.beat=0;a.vol=0;a.p1=0;a.peak=0;a.dec_fast=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.vol_=0;a.q7=0;a.q28=0;a.q20=0;a.q8=0;a.step=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.96,div(30,a.fps));a.dec_fast=pow(.6,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,0+a.avg+a.peak)*above(a.time,a.t0+.1);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,16);a.index2=mod(a.index2+a.is_beat*bnot(a.index),8);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q24=a.is_beat;\\na.vol=a.bass_att+a.mid_att+a.treb_att;a.vol_=a.dec_med*a.vol_+(1-a.dec_med)*a.vol;a.vol__=a.dec_med*a.vol__+(1-a.dec_med)*a.vol_;a.q27=a.index+1;a.q28=a.index2+1;a.q23=a.q22-div(.1,a.q22);a.q23=Math.max(a.q23,1);a.k1=a.is_beat*equal(mod(a.index,8),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_fast*a.p2+(1-a.dec_fast)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.trig=a.q24*bnot(mod(a.index,2));a.vx=a.vx*bnot(a.trig)+a.trig*(div(Math.floor(randint(100)),\\n100)-.5);a.vy=a.vy*bnot(a.trig)+a.trig*(div(Math.floor(randint(100)),100)-.5);a.q10=.2+a.vy*a.vy*2;a.q11=div(Math.sin(div(a.time,9)),2)+.4;a.movz-=div(1,a.fps)*(.3+a.vx);a.q9=a.movz;a.q12=2*Math.min(a.q22,6);a.q13=Math.min(2,1+Math.abs(8*a.vy*a.vx));a.dir_=a.bass-1;a.trig=bnot(mod(a.index,4))*a.q24;a.dir=bnot(a.trig)*a.dir+a.trig*(Math.floor(randint(10))-5);a.trel+=div(.1,a.fps)*a.dir;a.trel_=a.dec_med*a.trel_+(1-a.dec_med)*a.trel;a.q5=Math.cos(a.trel_);a.q6=Math.sin(a.trel_+0*a.q27*mod(a.q28,2));\\na.q7=-a.q6;a.q8=a.q5;a.zoom=1.02;a.rot=.5*Math.sin(bnot(mod(a.q28,2))*a.q28);a.rot=0*Math.sin(div(a.time,3));a.dx=0;a.monitor=a.q11;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = ((uv * texsize.xy) * 0.08);\\n  vec3 tmpvar_2;\\n  tmpvar_2 = (texture (sampler_main, (uv - (\\n    ((sin(tmpvar_1) / cos(tmpvar_1)) * texsize.zw)\\n   * 3.0))).xyz + (vec3(dot (texture (sampler_noise_lq, \\n    ((((texsize.xy * texsize_noise_lq.zw).x * uv) * 0.02) + (0.1 * rand_frame).xy)\\n  ), vec4(0.32, 0.49, 0.29, 0.0))) / 30.0));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ((mix (tmpvar_2, \\n    (1.0 - tmpvar_2.zyx)\\n  , vec3(0.01, 0.01, 0.01)) - 0.03) - (0.2 * pow (\\n    (1.0 - rad)\\n  , 18.0)));\\n  ret = tmpvar_3.xyz;\\n }\",comp:\"vec3 xlat_mutableneu;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutablerss;\\nvec2 xlat_mutableuv2;\\n shader_body { \\n  vec2 uv_1;\\n  vec2 ofs_2;\\n  vec3 ret1_3;\\n  uv_1 = ((uv - 0.5) * aspect.xy);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q5;\\n  tmpvar_4.y = q6;\\n  uv_1 = (uv_1 + (tmpvar_4 / 4.0));\\n  mat2 tmpvar_5;\\n  tmpvar_5[uint(0)] = _qb.xy;\\n  tmpvar_5[1u] = _qb.zw;\\n  uv_1 = (uv_1 * tmpvar_5);\\n  float tmpvar_6;\\n  float tmpvar_7;\\n  tmpvar_7 = (min (abs(\\n    (uv_1.y / uv_1.x)\\n  ), 1.0) / max (abs(\\n    (uv_1.y / uv_1.x)\\n  ), 1.0));\\n  float tmpvar_8;\\n  tmpvar_8 = (tmpvar_7 * tmpvar_7);\\n  tmpvar_8 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_8) + 0.05368138) * tmpvar_8) - 0.1173503)\\n     * tmpvar_8) + 0.1938925) * tmpvar_8) - 0.3326756)\\n   * tmpvar_8) + 0.9999793) * tmpvar_7);\\n  tmpvar_8 = (tmpvar_8 + (float(\\n    (abs((uv_1.y / uv_1.x)) > 1.0)\\n  ) * (\\n    (tmpvar_8 * -2.0)\\n   + 1.570796)));\\n  tmpvar_6 = (tmpvar_8 * sign((uv_1.y / uv_1.x)));\\n  if ((abs(uv_1.x) > (1e-08 * abs(uv_1.y)))) {\\n    if ((uv_1.x < 0.0)) {\\n      if ((uv_1.y >= 0.0)) {\\n        tmpvar_6 += 3.141593;\\n      } else {\\n        tmpvar_6 = (tmpvar_6 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_6 = (sign(uv_1.y) * 1.570796);\\n  };\\n  xlat_mutablers0.x = (((tmpvar_6 / 3.1416) * 6.0) * q28);\\n  xlat_mutablers0.y = inversesqrt(dot (uv_1, uv_1));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = (xlat_mutablers0.x + (q9 * 8.0));\\n  tmpvar_9.y = (xlat_mutablers0.y + ((q9 * q28) * 4.0));\\n  xlat_mutablerss = (tmpvar_9 / 12.0);\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = q5;\\n  tmpvar_10.y = q6;\\n  ofs_2 = (0.1 * tmpvar_10.yx);\\n  float tmpvar_11;\\n  float tmpvar_12;\\n  tmpvar_12 = -(q9);\\n  tmpvar_11 = fract(tmpvar_12);\\n  mat2 tmpvar_13;\\n  tmpvar_13[uint(0)].x = 1.0;\\n  tmpvar_13[uint(0)].y = -0.0;\\n  tmpvar_13[1u].x = 0.0;\\n  tmpvar_13[1u].y = 1.0;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_11)\\n   * tmpvar_13)) * aspect.yx);\\n  vec2 tmpvar_14;\\n  tmpvar_14 = fract(((xlat_mutableuv2 + 0.5) + ofs_2));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_14).xyz + ((texture (sampler_blur1, tmpvar_14).xyz * scale1) + bias1));\\n  ret1_3 = max (vec3(0.0, 0.0, 0.0), ((xlat_mutableneu * \\n    (1.0 - (tmpvar_11 * tmpvar_11))\\n  ) * 2.0));\\n  float tmpvar_15;\\n  tmpvar_15 = fract((tmpvar_12 + 0.3333333));\\n  mat2 tmpvar_16;\\n  tmpvar_16[uint(0)].x = -0.4990803;\\n  tmpvar_16[uint(0)].y = -0.8665558;\\n  tmpvar_16[1u].x = 0.8665558;\\n  tmpvar_16[1u].y = -0.4990803;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_15)\\n   * tmpvar_16)) * aspect.yx);\\n  vec2 tmpvar_17;\\n  tmpvar_17 = fract(((xlat_mutableuv2 + 0.5) + ofs_2));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_17).xyz + ((texture (sampler_blur1, tmpvar_17).xyz * scale1) + bias1));\\n  ret1_3 = max (ret1_3, ((xlat_mutableneu * \\n    (1.0 - (tmpvar_15 * tmpvar_15))\\n  ) * 2.0));\\n  float tmpvar_18;\\n  tmpvar_18 = fract((tmpvar_12 + 0.6666667));\\n  mat2 tmpvar_19;\\n  tmpvar_19[uint(0)].x = -0.5018377;\\n  tmpvar_19[uint(0)].y = 0.8649619;\\n  tmpvar_19[1u].x = -0.8649619;\\n  tmpvar_19[1u].y = -0.5018377;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_18)\\n   * tmpvar_19)) * aspect.yx);\\n  vec2 tmpvar_20;\\n  tmpvar_20 = fract(((xlat_mutableuv2 + 0.5) + ofs_2));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_20).xyz + ((texture (sampler_blur1, tmpvar_20).xyz * scale1) + bias1));\\n  ret1_3 = max (ret1_3, ((xlat_mutableneu * \\n    (1.0 - (tmpvar_18 * tmpvar_18))\\n  ) * 2.0));\\n  float tmpvar_21;\\n  tmpvar_21 = fract((tmpvar_12 + 1.0));\\n  mat2 tmpvar_22;\\n  tmpvar_22[uint(0)].x = 0.9999949;\\n  tmpvar_22[uint(0)].y = 0.003185092;\\n  tmpvar_22[1u].x = -0.003185092;\\n  tmpvar_22[1u].y = 0.9999949;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_21)\\n   * tmpvar_22)) * aspect.yx);\\n  vec2 tmpvar_23;\\n  tmpvar_23 = fract(((xlat_mutableuv2 + 0.5) + ofs_2));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_23).xyz + ((texture (sampler_blur1, tmpvar_23).xyz * scale1) + bias1));\\n  ret1_3 = max (ret1_3, ((xlat_mutableneu * \\n    (1.0 - (tmpvar_21 * tmpvar_21))\\n  ) * 2.0));\\n  vec2 tmpvar_24;\\n  tmpvar_24.x = (ret1_3.x + ret1_3.z);\\n  tmpvar_24.y = (ret1_3.x - ret1_3.y);\\n  vec4 tmpvar_25;\\n  tmpvar_25.w = 1.0;\\n  tmpvar_25.xyz = ((ret1_3 + (\\n    ((bass_att * 0.004) / sqrt(dot (uv_1, uv_1)))\\n   * roam_sin).xyz) + ((2.0 * \\n    (bass_att * ((texture (sampler_blur1, fract(\\n      (xlat_mutablerss + (tmpvar_24 / 2.0))\\n    )).xyz * scale1) + bias1).zxy)\\n  ) * clamp (\\n    (1.0 - (ret1_3 * 4.0))\\n  , 0.0, 1.0)));\\n  ret = tmpvar_25.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.14,decay:1,echo_zoom:1,wave_mode:6,wave_thick:1,wave_brighten:0,wrap:0,darken:1,wave_a:1.17,wave_scale:.797,wave_smoothing:0,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoomexp:.9995,zoom:.9998,rot:.02,dy:-.008,warp:.01,sx:1.0098,wave_r:.5,wave_g:.5,wave_b:.5,wave_x:.9,ob_size:.005,ob_a:.8,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:44.8,mv_y:38.4,mv_l:5,mv_g:.91,mv_b:.71,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q12=0;a.q18=0;a.q6=0;a.bass_thresh=0;a.wg=0;a.q11=0;a.q10=0;a.wb=0;a.q17=0;a.vol=0;a.q2=0;a.q3=0;a.wr=0;a.q7=0;a.q8=0;\",frame_eqs_str:\"a.wave_r+=.3*Math.sin(50*a.vol);a.wave_b+=.3*Math.sin(20*a.vol);a.wave_g+=.5*Math.sin(35*a.vol);a.q8=a.wave_r;a.q7=a.wave_b;a.q6=a.wave_g;a.wr=.5+.4*(.6*Math.sin(1.1*a.time)+.4*Math.sin(.8*a.time));a.wb=.5+.4*(.6*Math.sin(1.6*a.time)+.4*Math.sin(.5*a.time));a.wg=.5+.4*(.6*Math.sin(1.34*a.time)+.4*Math.sin(.4*a.time));a.monitor=a.wg;a.q10=a.wr;a.q11=a.wb;a.q12=a.wg;a.q18=.007*Math.sin(.1*a.time);a.q17=-.007*Math.sin(.254*a.time);a.q2=a.bass_thresh;a.vol=.25*(a.bass+a.mid+a.treb);\\na.vol*=a.vol;a.q3=a.vol;a.warp=0;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 noise3_1;\\n  vec3 tmpvar_2;\\n  tmpvar_2 = (texture (sampler_main, uv).xyz + ((texture (sampler_blur1, uv).xyz * scale1) + bias1));\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (0.5 + ((\\n    (uv - vec2(0.0, 1.0))\\n   - 0.5) * (1.0 + \\n    (tmpvar_2.y * 0.03)\\n  )));\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (tmpvar_3.x + pow (tmpvar_2.x, 0.0));\\n  tmpvar_4.y = (tmpvar_3.y + pow (tmpvar_2.x, 0.005));\\n  noise3_1 = (texture (sampler_noise_lq, ((\\n    (uv_orig * texsize.xy)\\n   * texsize_noise_lq.zw) + rand_frame.xy)).xyz * fract(q15));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (noise3_1 * (vec3(1.0, 1.0, 1.0) - vec3(fract(\\n    (q3 * 0.5)\\n  ))));\\n  noise3_1 = tmpvar_5;\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_main, fract(tmpvar_4));\\n  vec3 tmpvar_7;\\n  tmpvar_7.x = q10;\\n  tmpvar_7.y = q11;\\n  tmpvar_7.z = q12;\\n  vec3 tmpvar_8;\\n  tmpvar_8 = mix (tmpvar_5, tmpvar_7, tmpvar_6.xxx);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = (tmpvar_6.xyz + clamp ((\\n    (tmpvar_6.yzx * tmpvar_8.zxy)\\n   - \\n    (tmpvar_6.zxy * tmpvar_8.yzx)\\n  ), 0.0, 1.0));\\n  ret = tmpvar_9.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (texture (sampler_main, (uv - tmpvar_2)).xyz - texture (sampler_main, (uv + tmpvar_2)).xyz).x;\\n  tmpvar_4.y = (texture (sampler_main, (uv - tmpvar_3)).xyz - texture (sampler_main, (uv + tmpvar_3)).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    ((uv - 0.5) * 2.0)\\n  )) - tmpvar_4);\\n  float tmpvar_5;\\n  tmpvar_5 = clamp ((0.04 / sqrt(\\n    dot (uv1_1, uv1_1)\\n  )), 0.0, 1.0);\\n  uv1_1 = ((0.3 * cos(\\n    (uv1_1 * 12.0)\\n  )) - (9.0 * tmpvar_4));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (tmpvar_5 + ((texture (sampler_main, uv).xyz * 12.0) * vec3(clamp (\\n    (0.04 / sqrt(dot (uv1_1, uv1_1)))\\n  , 0.0, 1.0))));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.14,decay:1,echo_zoom:1,wave_mode:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.179,wave_smoothing:0,wave_mystery:.3,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoomexp:.8195,zoom:1.0697,dy:.006,warp:.01,sx:.9996,wave_g:0,wave_b:0,ob_a:.8,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:0,mv_y:0,mv_l:1,mv_g:.91,mv_b:.71,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q12=0;a.q18=0;a.q6=0;a.q5=0;a.bass_thresh=0;a.wg=0;a.q11=0;a.q10=0;a.wb=0;a.q17=0;a.vol=0;a.q2=0;a.q3=0;a.wr=0;a.q7=0;a.mtime=0;a.q8=0;\",frame_eqs_str:\"a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.91*(a.bass_thresh-1.3)+1.3);a.wave_r=.5+.5*(.6*Math.sin(1.3*a.time)+.4*Math.sin(.98*a.time));a.wave_b=.5+.5*(.6*Math.sin(1.1*a.time)+.4*Math.sin(.78*a.time));a.wave_g=.5+.5*(.6*Math.sin(1.2*a.time)+.4*Math.sin(.6*a.time));a.q8=a.wave_r;a.q7=a.wave_b;a.q6=a.wave_g;a.wr=.5+.4*(.6*Math.sin(.2*a.time)+.4*Math.sin(.8*a.time));a.wb=.5+.4*(.6*Math.sin(.377*a.time)+.4*Math.sin(.5*a.time));a.wg=.5+\\n.4*(.6*Math.sin(.7*a.time)+.4*Math.sin(.4*a.time));a.q10=a.wr;a.q11=a.wb;a.q12=a.wg;a.q10=.8;a.q11=.2;a.q12=.1;a.q18=.01*Math.sin(.1*a.mtime);a.q17=-.01*Math.sin(.254*a.mtime);a.q2=a.bass_thresh;a.vol=.25*(a.bass+a.mid+a.treb);a.vol*=a.vol;a.q3=a.vol;a.q5=.5*a.vol;a.mtime+=.01*a.vol;a.q2=.25*a.mtime;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 noise2_1;\\n  vec3 ret_2;\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, uv).xyz * scale1) + bias1) + texture (sampler_main, uv).xyz);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (0.5 + ((uv - 0.5) * (1.0 + \\n    (tmpvar_3.y * 0.05)\\n  )));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (tmpvar_4.x + pow (tmpvar_3.x, q17));\\n  tmpvar_5.y = (tmpvar_4.y + pow (tmpvar_3.x, q18));\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_fc_main, fract(tmpvar_5));\\n  vec3 tmpvar_7;\\n  tmpvar_7.x = q10;\\n  tmpvar_7.y = q11;\\n  tmpvar_7.z = q12;\\n  noise2_1 = (texture (sampler_noise_lq, ((\\n    (uv_orig * texsize.xy)\\n   * texsize_noise_lq.zw) + rand_frame.xy)).xyz + ((tmpvar_7 * vec3(rad)) * vol));\\n  vec3 a_8;\\n  a_8 = (1.0 - tmpvar_6.xyz);\\n  ret_2 = (tmpvar_6.xyz + (0.3 * clamp (\\n    ((a_8.yzx * noise2_1.zxy) - (a_8.zxy * noise2_1.yzx))\\n  , 0.0, 1.0)));\\n  ret_2 = (ret_2 * 0.97);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = ret_2;\\n  ret = tmpvar_9.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = (texture (sampler_main, uv).xyz * vec3(0.9, 0.3, 0.5));\\n  ret_1 = (ret_1 * 1.34);\\n  ret_1 = (ret_1 * ret_1);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.28,decay:.8,echo_zoom:1,echo_orient:3,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,brighten:1,wave_a:.001,wave_scale:1.286,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,zoomexp:3.04777,zoom:1.0173,warp:.01605,wave_g:.65,wave_b:.65,ob_size:0,ob_a:1,mv_x:64,mv_y:48,mv_l:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,additive:1,g:0,b:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.8);\"},{baseVals:{enabled:1,thick:1,additive:1,r:0,g:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.05*a.bass;a.ma-=3.1415*above(a.mid,1)*.05*a.mid;a.mx+=.0001*Math.cos(a.ma);a.my+=.0001*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.1);\"},{baseVals:{enabled:1,thick:1,additive:1,r:0,b:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.mid,1)*.01*a.mid;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0004*Math.cos(a.ma);a.my+=.0004*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.3);\"},{baseVals:{enabled:1,thick:1,additive:1,g:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,.5)*.02*a.bass;a.ma-=3.1415*above(a.treb,.5)*.02*a.treb;a.mx+=.0008*Math.cos(a.ma);a.my+=.0008*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.2);\"}],init_eqs_str:\"a.z=0;a.w=0;a.d_x=0;a.q25=0;a.index=0;a.q12=0;a.q18=0;a.q13=0;a.q15=0;a.q29=0;a.dt=0;a.q1=0;a.dec_med=0;a.dm=0;a.mm=0;a.tt=0;a.is_beat=0;a.q31=0;a.q23=0;a.q24=0;a.dec_slow=0;a.q11=0;a.q16=0;a.q26=0;a.avg=0;a.r=0;a.db=0;a.beat=0;a.q17=0;a.d_y=0;a.peak=0;a.bb=0;a.q27=0;a.q14=0;a.t0=0;a.q32=0;a.q28=0;a.q30=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,2);a.d_x=.00001<Math.abs(a.is_beat)?.001*(randint(2E3)-1E3):a.d_x;a.d_y=.00001<Math.abs(a.is_beat)?.001*(randint(2E3)-1E3):a.d_y;a.r=\\n.00001<Math.abs(a.is_beat)?.001*(randint(2E3)-1E3):a.r;a.z=.00001<Math.abs(a.is_beat)?.001*randint(1E3):a.z;a.zoom=1.03+.06*a.z;a.rot=.06*a.r;a.dx=.01*a.d_x;a.dy=.01*a.d_y;a.q1=1;a.q23=div(randint(1E3),1E3);a.q24=div(randint(1E3),1E3);a.q25=6.28*div(randint(1E3),1E3);a.q26=a.q25-3.14;a.q27=div(randint(1E3),12E3)+.04;a.q28=div(randint(1E3),1E3);a.q29=div(randint(1E3),1E3);a.q30=6.28*div(randint(1E3),1E3);a.q31=a.q30-3.14;a.q32=div(randint(1E3),14E3)+.04;a.db=.98*a.db+.2*a.bass;a.bb+=.1*a.db;a.dt=.98*\\na.dt+.2*a.treb;a.tt+=.1*a.dt;a.dm=.98*a.dm+.2*a.mid;a.mm+=.1*a.dm;a.w=.1*(a.bb-a.tt);a.q11=Math.sin(a.w);a.q12=Math.cos(a.w);a.q13=.5+.25*Math.sin(.1*(a.bb-a.mm));a.q14=.5+.25*Math.sin(.1*(a.tt-a.mm));a.q15=4;a.q16=.06;a.q17=Math.sin(-a.w);a.q18=Math.cos(-a.w);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.x;\\n  tmpvar_5.y = tmpvar_4.x;\\n  vec2 tmpvar_6;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = mix (uv_orig, uv, vec2(0.1, 0.1));\\n  tmpvar_6 = (tmpvar_7 + ((tmpvar_5 * texsize.zw) * 2.0));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_3.y;\\n  tmpvar_8.y = tmpvar_4.y;\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (mix (uv_orig, uv, vec2(0.3, 0.3)) + ((tmpvar_8 * texsize.zw) * 2.0));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_3.z;\\n  tmpvar_10.y = tmpvar_4.z;\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (tmpvar_7 + ((tmpvar_10 * texsize.zw) * 2.0));\\n  ret_1.x = (texture (sampler_main, tmpvar_6).x - ((texture (sampler_main, tmpvar_6).xyz - \\n    ((texture (sampler_blur3, tmpvar_6).xyz * scale3) + bias3)\\n  ).x * 0.01));\\n  ret_1.y = (texture (sampler_main, tmpvar_9).y - ((texture (sampler_main, tmpvar_9).xyz - \\n    ((texture (sampler_blur3, tmpvar_9).xyz * scale3) + bias3)\\n  ).y * 0.01));\\n  ret_1.z = (texture (sampler_main, tmpvar_11).z - ((texture (sampler_main, tmpvar_11).xyz - \\n    ((texture (sampler_blur3, tmpvar_11).xyz * scale3) + bias3)\\n  ).z * 0.01));\\n  ret_1 = (ret_1 + (-0.004 + (\\n    (texture (sampler_noise_lq, (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 1.2)) + rand_frame.xy)).xyz - 0.5)\\n   * 0.1)));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ret_1;\\n  ret = tmpvar_12.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_3.y;\\n  tmpvar_6.y = tmpvar_4.y;\\n  ret_1 = (mix (vec3(0.2, 0.0, 0.1), vec3(0.8, 0.6, 0.0), texture (sampler_main, (uv - \\n    (tmpvar_5 * 0.2)\\n  )).yyy) * ((\\n    (-(tmpvar_3.y) + tmpvar_4.y)\\n   + 1.0) + (\\n    (-(tmpvar_3.z) + tmpvar_4.z)\\n   * 2.0)));\\n  vec3 tmpvar_7;\\n  tmpvar_7 = mix (mix (ret_1, vec3(0.3, 0.0, 0.8), vec3((\\n    ((texture (sampler_blur1, (uv - (tmpvar_6 * 0.04))).xyz * scale1) + bias1)\\n  .x * 1.4))), vec3(1.0, 0.9, 0.4), texture (sampler_main, uv).zzz);\\n  ret_1 = tmpvar_7;\\n  vec4 tmpvar_8;\\n  tmpvar_8.w = 1.0;\\n  tmpvar_8.xyz = tmpvar_7;\\n  ret = tmpvar_8.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:1,gammaadj:1,decay:1,echo_zoom:1,wrap:0,darken_center:1,brighten:1,darken:1,wave_a:.001,warpanimspeed:.141,warpscale:14.497,zoom:.99951,warp:.75055,wave_r:0,wave_g:0,wave_b:0,ob_size:.5,ob_r:.01,ib_size:.26,mv_a:0},shapes:[{baseVals:{enabled:1,sides:6,rad:.17809,ang:.26,tex_zoom:.39711,g:.7,b:.6,r2:.4,g2:0,a2:1,border_a:0},init_eqs_str:\"a.q3=0;\",frame_eqs_str:\"a.x=.11+.22*randint(5);a.y=.1+.16*mod(2*a.time,6);a.b=.6+.3*a.q3;a.g=.7+.2*a.q3;a.r=.7;a.g2=.3*a.g;a.r2=.3*a.r;a.b2=.3*a.b;\"},{baseVals:{enabled:1,sides:6,additive:1,rad:.17809,ang:.26,tex_zoom:.99999,g:1,b:.4,a:.5,r2:.2,g2:0,b2:.3,a2:.6,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.q3=0;\",frame_eqs_str:\"a.x=.11+.22*randint(5);a.y=.1+.16*mod(2*a.time,6);a.b=.6+.3*a.q3;a.g=.7+.2*a.q3;a.r=.7;a.g2=.3*a.g;a.r2=.3*a.r;a.b2=.3*a.b;\"},{baseVals:{enabled:1,sides:6,textured:1,rad:.17633,ang:.26,tex_zoom:1.19615,r2:1,b2:1,a2:.2,border_r:0,border_g:0,border_b:0,border_a:.2},init_eqs_str:\"a.q3=0;a.q4=0;a.q5=0;a.q1=0;\",frame_eqs_str:\"a.x=.22*randint(6);a.y=.18+.16*mod(2*a.time,5);a.g=1.5*a.q3;a.r=1.3*a.q4;a.b=1.7*a.q5;a.tex_ang=-a.q1;a.tex_zoom=2+Math.sin(a.q1);\"},{baseVals:{enabled:1,sides:6,textured:1,rad:.16284,ang:.26,r2:.8,g2:.8,b2:.8,a2:.2,border_r:0,border_g:0,border_b:0,border_a:.2},init_eqs_str:\"a.q3=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.x=.11+.22*randint(5);a.y=.1+.16*mod(2*a.time,6);a.r=.3*a.q3;a.b=.2*a.q2;a.g=.1*a.q1;a.tex_ang=a.q1;a.tex_zoom=2+1.2*Math.sin(1.5*a.q1);\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.q12=0;a.w2=0;a.ref_ang=0;a.x1=0;a.vx3=0;a.q13=0;a.q6=0;a.q1=0;a.q5=0;a.q9=0;a.vx1=0;a.vx4=0;a.x3=0;a.q11=0;a.q10=0;a.q4=0;a.vy4=0;a.bounce=0;a.x4=0;a.w1=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.vy1=0;a.q2=0;a.q14=0;a.v1=0;a.vx2=0;a.q3=0;a.y4=0;a.q7=0;a.vy3=0;a.v2=0;a.q8=0;a.x1=.5;a.x2=.51;a.y2=1;a.y1=.7;a.x3=.8;a.y3=.5;a.x4=.2;a.y4=.5;a.ax1=0;a.ay1=0;a.ax2=0;a.ay2=0;a.ax3=0;a.ay3=0;a.vx1=0;a.vx2=0;\",frame_eqs_str:\"a.sx=1+.01*mod(8*a.bass,8)*equal(mod(a.time,Math.floor(24-2*a.bass)),0);a.sy=1+.01*mod(8*a.mid,8)*equal(mod(a.time,12+Math.floor(24-2*a.bass)),0);a.zoom=.99;a.wave_a=0;a.r=.12+.004*Math.max(a.bass_att,a.treb_att);a.bounce=below(a.y1,a.r);a.y1+=a.vy1;a.vy1=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy1)+.1*(a.r-a.y1):a.vy1-div(.0036,a.fps);a.bounce=below(a.x1,a.r);a.x1+=a.vx1;a.vx1=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx1)+.1*(a.r-a.x1):a.vx1;a.bounce=above(a.x1,1-a.r);a.vx1=\\n.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx1)+.04*(1-a.r-a.x1):a.vx1;a.bounce=below(a.y2,a.r);a.y2+=a.vy2;a.vy2=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy2)+.1*(a.r-a.y2):a.vy2-div(.0036,a.fps);a.bounce=below(a.x2,a.r);a.x2+=a.vx2;a.vx2=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx2)+.1*(a.r-a.x2):a.vx2;a.bounce=above(a.x2,1-a.r);a.vx2=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx2)+.1*(1-a.r-a.x2):a.vx2;a.bounce=below(a.y3,a.r);a.y3+=a.vy3;a.vy3=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy3)+.1*(a.r-\\na.y3):a.vy3-div(.0036,a.fps);a.bounce=below(a.x3,a.r);a.x3+=a.vx3;a.vx3=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx3)+.1*(a.r-a.x3):a.vx3;a.bounce=above(a.x3,1-a.r);a.vx3=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx3)+.1*(1-a.r-a.x3):a.vx3;a.bounce=below(a.y4,a.r);a.y4+=a.vy4;a.vy4=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy4)+.1*(a.r-a.y4):a.vy4-div(.0036,a.fps);a.bounce=below(a.x4,a.r);a.x4+=a.vx4;a.vx4=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx4)+.1*(a.r-a.x4):a.vx4;a.bounce=above(a.x4,1-a.r);\\na.vx4=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx4)+.1*(1-a.r-a.x4):a.vx4;a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x2-a.vx2)+sqr(a.y1+a.vy1-a.y2-a.vy2)),2*a.r);a.ref_ang=Math.atan2(a.x2-a.x1,a.y2-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx2,a.vy2);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;\\na.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy2;a.bounce=\\nbelow(sqrt(sqr(a.x1+a.vx1-a.x3-a.vx3)+sqr(a.y1+a.vy1-a.y3-a.vy3)),2*a.r);a.ref_ang=Math.atan2(a.x3-a.x1,a.y3-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx3,a.vy3);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+\\nMath.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy3;a.bounce=below(sqrt(sqr(a.x2+a.vx2-a.x3-a.vx3)+sqr(a.y2+a.vy2-a.y3-a.vy3)),2*a.r);a.ref_ang=\\nMath.atan2(a.x3-a.x2,a.y3-a.y2)+Math.asin(1);a.v1=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.v2=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.w1=Math.atan2(a.vx2,a.vy2);a.w2=Math.atan2(a.vx3,a.vy3);a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy2;\\na.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy3;a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x4-a.vx4)+sqr(a.y1+a.vy1-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x1,a.y4-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=\\nsqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx4,a.vy4);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+\\nMath.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy4;a.bounce=below(sqrt(sqr(a.x2+a.vx2-a.x4-a.vx4)+sqr(a.y2+a.vy2-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x2,a.y4-a.y2)+Math.asin(1);a.v1=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.v2=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx2,a.vy2);a.w2=Math.atan2(a.vx4,a.vy4);a.vx2=.00001<\\nMath.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy2;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?\\nMath.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy4;a.bounce=below(sqrt(sqr(a.x3+a.vx3-a.x4-a.vx4)+sqr(a.y3+a.vy3-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x3,a.y4-a.y3)+Math.asin(1);a.v1=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.v2=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx3,a.vy3);a.w2=Math.atan2(a.vx4,a.vy4);a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*\\na.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy3;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-\\na.ref_ang-Math.asin(1)):a.vy4;a.q1=a.aspectx;a.q2=a.aspecty;a.q3=a.x1;a.q4=a.y1;a.q5=a.r;a.q6=a.x2;a.q7=a.y2;a.q8=a.r;a.q9=a.x3;a.q10=a.y3;a.q11=a.r;a.q12=a.x4;a.q13=a.y4;a.q14=a.r;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1.z = (texture (sampler_main, uv).z * 0.5);\\n  vec2 tmpvar_2;\\n  tmpvar_2 = ((uv_orig * texsize.xy) * texsize_noise_lq.zw);\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 4.0);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  tmpvar_4.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  ret_1.y = texture (sampler_fw_main, clamp ((uv_orig + (\\n    (tmpvar_4 * texsize.zw)\\n   * 4.0)), 0.0, 1.0)).y;\\n  ret_1.y = (ret_1.y + ((\\n    (ret_1 - ((texture (sampler_blur1, uv_orig).xyz * scale1) + bias1))\\n  .y * 0.025) + -0.014));\\n  ret_1.y = (ret_1.y + ((texture (sampler_noise_lq, tmpvar_2).y - 0.5) * 0.02));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  tmpvar_5.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  ret_1.x = ((texture (sampler_main, (uv - \\n    ((tmpvar_5 * texsize.zw) * 4.0)\\n  )).x - (ret_1.y * 0.01)) + 0.004);\\n  ret_1.x = (ret_1.x + ((\\n    (texture (sampler_noise_lq, tmpvar_2).x - 0.5)\\n   * 0.01) + (ret_1.z * 0.14)));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_1;\\n  ret = tmpvar_6.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.x = q3;\\n  tmpvar_1.y = q4;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = q6;\\n  tmpvar_2.y = q7;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q9;\\n  tmpvar_3.y = q10;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q12;\\n  tmpvar_4.y = q13;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (texsize.zw * 1.2);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (texture (sampler_main, (uv + (vec2(1.0, 0.0) * tmpvar_5))).xyz - texture (sampler_main, (uv - (vec2(1.0, 0.0) * tmpvar_5))).xyz);\\n  vec3 tmpvar_7;\\n  tmpvar_7 = (texture (sampler_main, (uv + (vec2(0.0, 1.0) * tmpvar_5))).xyz - texture (sampler_main, (uv - (vec2(0.0, 1.0) * tmpvar_5))).xyz);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_8.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_9;\\n  x_9 = ((uv - (tmpvar_8 * 8.0)) - (1.0 - tmpvar_1));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_10.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_11;\\n  x_11 = ((uv - (tmpvar_10 * 8.0)) - (1.0 - tmpvar_2));\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_12.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_13;\\n  x_13 = ((uv - (tmpvar_12 * 8.0)) - (1.0 - tmpvar_3));\\n  vec2 tmpvar_14;\\n  tmpvar_14.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_14.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_15;\\n  x_15 = ((uv - (tmpvar_14 * 8.0)) - (1.0 - tmpvar_4));\\n  vec4 tmpvar_16;\\n  tmpvar_16.w = 1.0;\\n  tmpvar_16.xyz = (mix (texture (sampler_main, uv).xyz, max (\\n    max ((vec3((1.0 - pow (\\n      sqrt(dot (x_9, x_9))\\n    , 0.2))) * vec3(2.0, 1.0, -1.0)), (vec3((1.0 - pow (\\n      sqrt(dot (x_11, x_11))\\n    , 0.2))) * vec3(2.0, -1.0, 1.0)))\\n  , \\n    max ((vec3((1.0 - pow (\\n      sqrt(dot (x_13, x_13))\\n    , 0.2))) * vec3(-1.0, 1.0, 2.0)), (vec3((1.0 - pow (\\n      sqrt(dot (x_15, x_15))\\n    , 0.2))) * vec3(1.0, -1.0, 2.0)))\\n  ), vec3(0.5, 0.5, 0.5)) * 1.25);\\n  ret = tmpvar_16.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.995,echo_zoom:1.007,echo_orient:3,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,wave_a:.001,wave_scale:.958,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:.05,ob_g:.1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:25.6,mv_y:9.6,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.look=0;a.n=0;a.reg26=0;a.w=0;a.uvx0=0;a.reg34=0;a.reg28=0;a.reg23=0;a.q25=0;a.angchg=0;a.reg20=0;a.reg15=0;a.reg10=0;a.h3=0;a.q12=0;a.v3=0;a.q18=0;a.q22=0;a.q21=0;a.diry=0;a.q13=0;a.q6=0;a.posx=0;a.fps_=0;a.reg25=0;a.bt=0;a.uvx=0;a.q1=0;a.travel=0;a.posz=0;a.q5=0;a.q9=0;a.dirz=0;a.dec_s=0;a.reg16=0;a.v=0;a.slow=0;a.reg36=0;a.mm=0;a.h2=0;a.reg22=0;a.tt=0;a.uvy=0;a.rotz=0;a.bm=0;a.ly=0;a.dist_=0;a.q23=0;a.q24=0;a.reg24=0;a.cran0=0;a.ran2=0;a.q11=0;a.q10=0;a.reg14=0;a.posy=0;\\na.reg31=0;a.dirx=0;a.q4=0;a.start=0;a.reg12=0;a.reg13=0;a.c2=0;a.reg37=0;a.s3=0;a.yslope=0;a.lampy=0;a.q16=0;a.xslope=0;a.q26=0;a.reg38=0;a.reg35=0;a.reg11=0;a.mt=0;a.tx=0;a.avg=0;a.uvz=0;a.c3=0;a.uvy0=0;a.mx=0;a.reg27=0;a.mn=0;a.q19=0;a.beat=0;a.q17=0;a.reg32=0;a.lx=0;a.reg21=0;a.uvz0=0;a.len=0;a.reg18=0;a.reg30=0;a.bb=0;a.q2=0;a.q27=0;a.slen=0;a.q14=0;a.dist=0;a.h1=0;a.reg17=0;a.v1=0;a.speed=0;a.q3=0;a.s1=0;a.t0=0;a.s2=0;a.ran1=0;a.reg33=0;a.q7=0;a.ds=0;a.q28=0;a.lampx=0;a.ty=0;a.c1=0;a.v2=0;a.q20=\\n0;a.q8=0;a.avg=.01;a.q7=.25;a.q8=randint(2)-1;a.q16=1+randint(2);a.q18=randint(.8)+.1;a.q30=1;a.q31=128;a.start=1;a.travel=0;a.rotz=0;a.look=0;a.slow=0;a.t0=a.time+3;a.lampx=.5;a.lampy=.5;a.cran0=randint(1);for(var b=a.n=0;1E4>b;b++)a.gmegabuf[Math.floor(a.n)]=0,a.n+=1;for(b=a.n=0;1E4>b;b++)a.megabuf[Math.floor(a.n)]=0,a.n+=1;a.trelx=0;a.trely=0;a.trelz=0;a.reg20=1;a.reg21=0;a.reg22=0;a.reg23=0;a.reg24=1;a.reg25=0;a.reg26=0;a.reg27=0;a.reg28=1;b=0;do{b+=1;var c;a.ran1=div(randint(800),100);a.ran2=\\ndiv(randint(800),100);a.ran3=div(randint(800),100);a.posx=randint(5)-2;a.posy=randint(5)-2;a.posz=randint(5)-2;a.c1=Math.cos(a.ran1);a.c2=Math.cos(a.ran2);a.c3=Math.cos(a.ran3);a.s1=Math.sin(a.ran1);a.s2=Math.sin(a.ran2);a.s3=Math.sin(a.ran3);a.reg20=a.c2*a.c1;a.reg21=a.c2*a.s1;a.reg22=-a.s2;a.reg23=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg24=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg25=a.s3*a.c2;a.reg26=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg27=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg28=a.c3*a.c2;a.dist=.001;var d=0;do{d+=1;a.uvx=div(a.reg26*\\na.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:\\n.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):\\na.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.05;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(c)&&1048576>d);d=.06>a.dist?1:0}while(.00001<Math.abs(d)&&1048576>b);\",frame_eqs_str:\"a.fps_=0*a.fps_+1*(.00001<Math.abs(25>=a.fps?1:0)?a.fps:25+.5*(a.fps-25));a.dec_s=1-div(.06*30,a.fps_);a.beat=a.time>a.t0+3?1:0;a.t0=.00001<Math.abs(a.beat)?a.time:a.t0;a.speed=div(Math.min(.2,a.dist_-.02)*(1+2*a.avg)*(1-0*a.slow)*.7,a.q7);a.ds=a.ds*a.dec_s+div((1-a.dec_s)*a.speed*.25,a.fps_);a.rotz=.00001<Math.abs(.00001>Math.abs(a.rotz-0)?1:0)?a.beat*(randint(100)<20*a.travel?1:0)*(div(randint(10),10)-.3):bnot(a.beat*(30>randint(100)?1:0))*a.rotz;a.slow=.00001<Math.abs(bnot(a.slow))?\\na.beat*(6>randint(1E3*a.avg)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.look=.00001<Math.abs(bnot(a.look))?a.beat*(12>randint(1E3*a.speed)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.lx=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.lx;a.ly=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.ly;a.lampx=a.lampx*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.lx:.5);a.lampy=a.lampy*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.ly:.5);a.q1=a.lampx;a.q2=a.lampy;a.dirx=a.reg26;a.diry=a.reg27;a.dirz=\\na.reg28;a.posx+=a.ds*a.dirx;a.posy+=a.ds*a.diry;a.posz+=a.ds*a.dirz;a.q4=a.posx;a.q5=a.posy;a.q6=a.posz;a.angchg=(.2-a.dist_)*(.2>a.dist_?1:0)*2;a.travel=.00001<Math.abs(0<a.angchg?1:0)?0:a.travel+a.ds;a.v1=a.v1*a.dec_s+(1-a.dec_s)*a.rotz*a.ds;a.v2=a.v2*a.dec_s+div((1-a.dec_s)*a.angchg*a.xslope,a.fps_);a.v3=a.v3*a.dec_s+(1-a.dec_s)*(div(a.angchg*a.yslope,a.fps_)+2*a.v1*Math.sin(.1*a.time));a.reg30=a.reg20;a.reg31=a.reg21;a.reg32=a.reg22;a.reg33=a.reg23;a.reg34=a.reg24;a.reg35=a.reg25;a.reg36=a.reg26;\\na.reg37=a.reg27;a.reg38=a.reg28;a.n=0;for(var b=a.avg=0;5>b;b++){a.n+=1;a.ran1=div(randint(100),100);a.ran2=div(randint(100),200)-.25;a.tx=Math.cos(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.ty=Math.sin(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.c1=Math.cos(a.v1);a.c2=Math.cos(a.v2+a.ty);a.c3=Math.cos(a.v3+a.tx);a.s1=Math.sin(a.v1);a.s2=Math.sin(a.v2+a.ty);a.s3=Math.sin(a.v3+a.tx);a.reg10=a.c2*a.c1;a.reg11=a.c2*a.s1;a.reg12=-a.s2;a.reg13=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg14=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg15=a.s3*\\na.c2;a.reg16=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg17=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg18=a.c3*a.c2;a.reg20=a.reg30;a.reg21=a.reg31;a.reg22=a.reg32;a.reg23=a.reg33;a.reg24=a.reg34;a.reg25=a.reg35;a.reg26=a.reg36;a.reg27=a.reg37;a.reg28=a.reg38;a.q20=a.reg10*a.reg20+a.reg11*a.reg23+a.reg12*a.reg26;a.q21=a.reg10*a.reg21+a.reg11*a.reg24+a.reg12*a.reg27;a.q22=a.reg10*a.reg22+a.reg11*a.reg25+a.reg12*a.reg28;a.q23=a.reg13*a.reg20+a.reg14*a.reg23+a.reg15*a.reg26;a.q24=a.reg13*a.reg21+a.reg14*a.reg24+a.reg15*a.reg27;\\na.q25=a.reg13*a.reg22+a.reg14*a.reg25+a.reg15*a.reg28;a.q26=a.reg16*a.reg20+a.reg17*a.reg23+a.reg18*a.reg26;a.q27=a.reg16*a.reg21+a.reg17*a.reg24+a.reg18*a.reg27;a.q28=a.reg16*a.reg22+a.reg17*a.reg25+a.reg18*a.reg28;a.reg20=a.q20;a.reg21=a.q21;a.reg22=a.q22;a.reg23=a.q23;a.reg24=a.q24;a.reg25=a.q25;a.reg26=a.q26;a.reg27=a.q27;a.reg28=a.q28;a.dist=.002;var c,d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;\\na.uvx=8*(div(a.uvx,8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?\\n-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.1;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<\\nMath.abs(c)&&1048576>d);a.megabuf[Math.floor(a.n)]=a.megabuf[Math.floor(a.n)]*a.dec_s+(1-a.dec_s)*a.dist;a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5))}a.n=0;for(b=a.avg=0;5>b;b++)a.n+=1,a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5));a.xslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[1]-a.megabuf[3]),-3),3);a.yslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[4]-a.megabuf[2]),-3),3);a.monitor=a.avg;a.dist_=a.dist_*a.dec_s+(1-a.dec_s)*a.dist;a.q10=a.ds*a.q7;a.q14=Math.abs(a.ds)+2*(Math.abs(a.v1)+\\nMath.abs(a.v2)+Math.abs(a.v3))+div(1,255)+.05*a.start;a.q19=.6+.4*Math.sin(.02*a.time+6*a.cran0);a.start*=.9;a.q11=a.v1;a.q12=a.v2;a.q13=a.v3;a.monitor=a.q16;a.bb=.99*a.bb+.02*a.bass;a.mm=.99*a.mm+.02*a.mid;a.tt=.99*a.tt+.02*a.treb;a.mx=Math.max(Math.max(a.bb,a.mm),a.tt);a.mn=Math.min(Math.min(a.bb,a.mm),a.tt);a.h1=div(a.bb-a.mn,a.mx-a.mn);a.h2=div(a.mm-a.mn,a.mx-a.mn);a.h3=div(a.tt-a.mn,a.mx-a.mn);a.v=div(.1333,a.fps);a.bm+=(a.h1-a.h2)*a.v;a.mt+=(a.h2-a.h3)*a.v;a.bt+=(a.h1-a.h3)*a.v;a.w=2*a.bm;a.q3=\\nMath.sin(a.w);a.q9=Math.cos(a.w);a.q17=a.bm;a.q18=a.mt;a.q19=a.bt;\",pixel_eqs_str:\"a.warp=0;a.zoom=1;a.dx=div(-a.q12,a.q16)*(1+0*pow(a.x-.5,2));a.dy=div(a.q13,a.q16)*(1+0*pow(a.y-.5,2));a.rot=a.q11;\",warp:\"float sustain;\\nfloat xlat_mutabledist;\\nfloat xlat_mutablestruc;\\nvec2 xlat_mutableuv1;\\nvec3 xlat_mutableuv2;\\n shader_body { \\n  mat3 tmpvar_1;\\n  tmpvar_1[uint(0)].x = q20;\\n  tmpvar_1[uint(0)].y = q23;\\n  tmpvar_1[uint(0)].z = q26;\\n  tmpvar_1[1u].x = q21;\\n  tmpvar_1[1u].y = q24;\\n  tmpvar_1[1u].z = q27;\\n  tmpvar_1[2u].x = q22;\\n  tmpvar_1[2u].y = q25;\\n  tmpvar_1[2u].z = q28;\\n  vec3 tmpvar_2;\\n  tmpvar_2.x = q4;\\n  tmpvar_2.y = q5;\\n  tmpvar_2.z = q6;\\n  sustain = (1.0123 - q14);\\n  vec2 uv_3;\\n  vec3 ret_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv - 0.5);\\n  xlat_mutableuv1 = ((tmpvar_5 * aspect.xy) * q16);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_pc_main, uv);\\n  uv_3 = ((tmpvar_5 * (1.0 - \\n    (q10 / (1.0 - ((tmpvar_6.z + \\n      (0.003921569 * tmpvar_6.y)\\n    ) + (q10 * 0.7))))\\n  )) + 0.5);\\n  vec4 tmpvar_7;\\n  tmpvar_7 = fract((8.0 * texture (sampler_noise_lq, (uv_3 + rand_frame.yz))));\\n  xlat_mutabledist = tmpvar_7.x;\\n  if ((tmpvar_7.y > 0.2)) {\\n    vec3 tmpvar_8;\\n    tmpvar_8 = (tmpvar_7.xyz - vec3(0.4, 0.5, 0.5));\\n    vec2 uvi_9;\\n    uvi_9 = ((tmpvar_8.zy * 0.003) + uv_3);\\n    vec2 pix_10;\\n    vec4 nb2_11;\\n    vec4 nb_12;\\n    vec2 x_13;\\n    x_13 = (uvi_9 - 0.5);\\n    pix_10 = (texsize.zw * (1.0 + (\\n      sqrt(dot (x_13, x_13))\\n     * 8.0)));\\n    float tmpvar_14;\\n    tmpvar_14 = (q10 * 0.7);\\n    vec4 tmpvar_15;\\n    tmpvar_15 = texture (sampler_pc_main, (uvi_9 - pix_10));\\n    nb_12.x = (1.0 - ((tmpvar_15.z + \\n      (0.003921569 * tmpvar_15.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_16;\\n    tmpvar_16 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(1.0, -1.0))));\\n    nb_12.y = (1.0 - ((tmpvar_16.z + \\n      (0.003921569 * tmpvar_16.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_17;\\n    tmpvar_17 = texture (sampler_pc_main, (uvi_9 + pix_10));\\n    nb_12.z = (1.0 - ((tmpvar_17.z + \\n      (0.003921569 * tmpvar_17.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_18;\\n    tmpvar_18 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(-1.0, 1.0))));\\n    nb_12.w = (1.0 - ((tmpvar_18.z + \\n      (0.003921569 * tmpvar_18.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_19;\\n    tmpvar_19 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(0.0, -1.0))));\\n    nb2_11.x = (1.0 - ((tmpvar_19.z + \\n      (0.003921569 * tmpvar_19.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_20;\\n    tmpvar_20 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(1.0, 0.0))));\\n    nb2_11.y = (1.0 - ((tmpvar_20.z + \\n      (0.003921569 * tmpvar_20.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_21;\\n    tmpvar_21 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(0.0, 1.0))));\\n    nb2_11.z = (1.0 - ((tmpvar_21.z + \\n      (0.003921569 * tmpvar_21.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_22;\\n    tmpvar_22 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(-1.0, 0.0))));\\n    nb2_11.w = (1.0 - ((tmpvar_22.z + \\n      (0.003921569 * tmpvar_22.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_23;\\n    tmpvar_23 = min (nb_12, nb2_11);\\n    nb_12.zw = tmpvar_23.zw;\\n    nb_12.xy = min (tmpvar_23.xy, tmpvar_23.zw);\\n    xlat_mutabledist = (min (nb_12.x, nb_12.y) + ((0.008 * tmpvar_8.x) * abs(tmpvar_8.y)));\\n  };\\n  vec4 tmpvar_24;\\n  tmpvar_24 = texture (sampler_pc_main, uv_3);\\n  float tmpvar_25;\\n  tmpvar_25 = min (xlat_mutabledist, (1.0 - (\\n    (tmpvar_24.z + (0.003921569 * tmpvar_24.y))\\n   + \\n    (q10 * 0.7)\\n  )));\\n  xlat_mutabledist = tmpvar_25;\\n  float tmpvar_26;\\n  tmpvar_26 = (tmpvar_25 + pow (tmpvar_25, 3.0));\\n  vec3 tmpvar_27;\\n  tmpvar_27.xy = (xlat_mutableuv1 * tmpvar_26);\\n  tmpvar_27.z = tmpvar_26;\\n  xlat_mutableuv2 = (((tmpvar_27 / q7) * tmpvar_1) + tmpvar_2);\\n  xlat_mutableuv2 = ((fract(\\n    ((xlat_mutableuv2 / 8.0) + 0.5)\\n  ) - 0.5) * 8.0);\\n  float li_28;\\n  vec3 zz0_29;\\n  vec3 zz_30;\\n  zz0_29 = (xlat_mutableuv2 + q8);\\n  li_28 = 0.0;\\n  zz_30 = ((2.0 * clamp (xlat_mutableuv2, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - xlat_mutableuv2);\\n  float tmpvar_31;\\n  tmpvar_31 = dot (zz_30, zz_30);\\n  if ((tmpvar_31 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_31 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_31);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_32;\\n  tmpvar_32 = dot (zz_30, zz_30);\\n  if ((tmpvar_32 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_32 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_32);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_33;\\n  tmpvar_33 = dot (zz_30, zz_30);\\n  if ((tmpvar_33 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_33 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_33);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_34;\\n  tmpvar_34 = dot (zz_30, zz_30);\\n  if ((tmpvar_34 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_34 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_34);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_35;\\n  tmpvar_35 = dot (zz_30, zz_30);\\n  if ((tmpvar_35 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_35 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_35);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_36;\\n  tmpvar_36 = dot (zz_30, zz_30);\\n  if ((tmpvar_36 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_36 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_36);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_37;\\n  tmpvar_37 = dot (zz_30, zz_30);\\n  if ((tmpvar_37 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_37 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_37);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_38;\\n  tmpvar_38 = dot (zz_30, zz_30);\\n  if ((tmpvar_38 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_38 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_38);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  vec4 tmpvar_39;\\n  tmpvar_39.xyz = zz_30;\\n  tmpvar_39.w = li_28;\\n  float tmpvar_40;\\n  tmpvar_40 = sqrt(dot (zz_30, zz_30));\\n  xlat_mutablestruc = (sqrt(dot (tmpvar_39.xyw, tmpvar_39.xyw)) / 24.0);\\n  vec4 tmpvar_41;\\n  tmpvar_41 = texture (sampler_pc_main, uv_3);\\n  float tmpvar_42;\\n  float tmpvar_43;\\n  tmpvar_43 = (q10 * 0.7);\\n  tmpvar_42 = ((log(\\n    (1.0 + (tmpvar_40 / 24.0))\\n  ) * 0.02) * (1.0 - (1.0 - \\n    ((tmpvar_41.z + (0.003921569 * tmpvar_41.y)) + tmpvar_43)\\n  )));\\n  float tmpvar_44;\\n  vec4 tmpvar_45;\\n  tmpvar_45 = texture (sampler_pc_main, uv_3);\\n  tmpvar_44 = (1.0 - ((tmpvar_45.z + \\n    (0.003921569 * tmpvar_45.y)\\n  ) + tmpvar_43));\\n  if ((((tmpvar_25 <= tmpvar_44) && (tmpvar_40 < 24.0)) && (tmpvar_25 > 0.005))) {\\n    ret_4.x = (((1.0 - sustain) * xlat_mutablestruc) + (sustain * mix (texture (sampler_main, uv_3).xyz, \\n      ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1)\\n    , vec3(\\n      (q14 * 4.0)\\n    )).x));\\n    float x_46;\\n    x_46 = ((1.0 - tmpvar_25) * 255.0);\\n    float ip_47;\\n    ip_47 = float(int(x_46));\\n    vec2 tmpvar_48;\\n    tmpvar_48.x = (x_46 - ip_47);\\n    tmpvar_48.y = (ip_47 / 255.0);\\n    ret_4.yz = tmpvar_48;\\n  } else {\\n    vec3 tmpvar_49;\\n    tmpvar_49.y = 0.0;\\n    tmpvar_49.x = sustain;\\n    tmpvar_49.z = (1.0 - tmpvar_42);\\n    vec3 tmpvar_50;\\n    tmpvar_50.xy = vec2(0.003921569, 0.0);\\n    tmpvar_50.z = (q14 / 6.0);\\n    ret_4 = ((texture (sampler_fc_main, uv_3).xyz * tmpvar_49) - tmpvar_50);\\n  };\\n  vec4 tmpvar_51;\\n  tmpvar_51.w = 1.0;\\n  tmpvar_51.xyz = ret_4;\\n  ret = tmpvar_51.xyz;\\n }\",comp:\"vec2 xlat_mutabled;\\nvec3 xlat_mutabledx;\\nvec3 xlat_mutabledy;\\n shader_body { \\n  vec3 ret_1;\\n  xlat_mutabled = (texsize.zw * 1.5);\\n  xlat_mutabledx = (texture (sampler_main, (uv_orig + (vec2(1.0, 0.0) * xlat_mutabled))).xyz - texture (sampler_main, (uv_orig - (vec2(1.0, 0.0) * xlat_mutabled))).xyz);\\n  xlat_mutabledy = (texture (sampler_main, (uv_orig + (vec2(0.0, 1.0) * xlat_mutabled))).xyz - texture (sampler_main, (uv_orig - (vec2(0.0, 1.0) * xlat_mutabled))).xyz);\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = xlat_mutabledx.y;\\n  tmpvar_2.y = xlat_mutabledy.y;\\n  vec2 x_3;\\n  x_3 = (tmpvar_2 * 8.0);\\n  ret_1 = (((texture (sampler_main, uv).x * \\n    (1.0 - sqrt(dot (x_3, x_3)))\\n  ) * pow (hue_shader, vec3(6.0, 6.0, 6.0))) * 1.4);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = xlat_mutabledx.z;\\n  tmpvar_4.y = xlat_mutabledy.z;\\n  vec2 x_5;\\n  x_5 = (tmpvar_4 * 4.0);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = mix (ret_1, vec3(1.0, 1.0, 1.0), vec3(sqrt(dot (x_5, x_5))));\\n  ret_1 = tmpvar_6;\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = tmpvar_6;\\n  ret = tmpvar_7.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.9,echo_zoom:1.169,echo_orient:1,wave_mode:5,additivewave:1,wave_a:0,wave_scale:.9,wave_smoothing:.63,wave_mystery:1,modwavealphastart:2,modwavealphaend:2,warpscale:2.853,rot:.006,warp:0,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.005,mv_x:0,mv_y:48,mv_dx:-.941,mv_dy:.426,mv_l:5,mv_r:.316,mv_g:.078,mv_b:.942,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:100,textured:1,rad:.78903,ang:.62832,tex_zoom:1.02009,r:0,g:1,b:1,r2:.7,b2:1,border_a:0},init_eqs_str:\"a.vx=0;a.vy=0;\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.y3=0;a.y1=0;a.xx=0;a.res=0;a.q12=0;a.x1=0;a.vx3=0;a.q13=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.c_x=0;a.c_y=0;a.q9=0;a.d1=0;a.v=0;a.si1=0;a.vx4=0;a.diff=0;a.x3=0;a.q23=0;a.q24=0;a.d2=0;a.q11=0;a.q10=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.dir=0;a.x4=0;a.r=0;a.x2=0;a.beat=0;a.vol=0;a.vy2=0;a.y2=0;a.size=0;a.q2=0;a.q14=0;a.si2=0;a.vx2=0;a.q3=0;a.yy=0;a.y4=0;a.q7=0;a.vy3=0;a.strength=0;a.xx1=0;a.velocity=0;a.q8=0;a.c_x=.5;a.c_y=.5;\",frame_eqs_str:\"a.sx=1+.01*mod(8*a.bass,8)*equal(mod(a.time,Math.floor(24-2*a.bass)),0);a.sy=1+.01*mod(8*a.mid,8)*equal(mod(a.time,12+Math.floor(24-2*a.bass)),0);a.q1=a.aspectx;a.q2=a.aspecty;a.rot=0;a.zoom=1;a.warp=0;a.vol=8*a.bass+4*a.mid+2*a.treb;a.vol*=above(a.vol,17);a.monitor=a.vol;a.beat=above(a.vol,a.res);a.diff=(1-a.beat)*a.diff+a.beat*(a.vol-a.res);a.res=a.beat*(a.vol+2*a.diff)+(1-a.beat)*(a.res-div(60*(.04*a.diff+.12),a.fps));a.res=Math.max(0,a.res);a.monitor=a.res;a.r=.00001<Math.abs(a.beat)?\\n.0001*(randint(200)-100):a.r;a.rot=a.r;a.c_x=.00001<Math.abs(a.beat)?.5+.005*(randint(200)-100):a.c_x;a.c_y=.00001<Math.abs(a.beat)?.5+.005*(randint(200)-100):a.c_y;a.q23=a.c_x;a.q24=a.c_y;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+1.5*a.yy1;a.dt=div(.03,a.fps);a.vx2=a.vx2*(1-2*a.dt)+10*a.dt*(a.x1+a.x3-2*a.x2);a.vy2=a.vy2*(1-2*a.dt)+a.dt*(10*(a.y1+a.y3-2*a.y2)-.5);a.vx3=a.vx3*(1-2*a.dt)+10*a.dt*(a.x2+a.x4-2*a.x3);a.vy3=\\na.vy3*(1-2*a.dt)+a.dt*(10*(a.y2+a.y4-2*a.y3)-.5);a.vx4=a.vx4*(1-2*a.dt)+10*a.dt*(a.x3-a.x4);a.vy4=a.vy4*(1-2*a.dt)+a.dt*(10*(a.y3-a.y4)-.5);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:.5*Math.abs(a.vx2);a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:.5*-Math.abs(a.vx2);a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:.5*Math.abs(a.vx3);a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:.5*-Math.abs(a.vx3);a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:\\n.5*Math.abs(a.vx4);a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:.5*-Math.abs(a.vx4);a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:.5*Math.abs(a.vy2);a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:.5*-Math.abs(a.vy2);a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:.5*Math.abs(a.vy3);a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:.5*-Math.abs(a.vy3);a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:.5*Math.abs(a.vy4);a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:.5*-Math.abs(a.vy4);a.q1=a.x1;a.q2=a.x2;a.q3=a.x3;a.q4=a.x4;a.q5=\\na.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.q9=div(1,a.aspectx);a.q10=div(1,a.aspecty);a.q11=a.aspectx;a.q12=a.aspecty;a.q13=.8*sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.q14=Math.atan2(a.vx4,a.vy4);\",pixel_eqs_str:\"a.d=pow(sqrt(sqr(a.x-a.q3)+sqr(a.y-a.q4)),2)-0;a.v=.03;a.dx=a.v*(a.x-a.q23)*a.d;a.dy=a.v*(a.y-a.q24)*a.d;a.x=.5+(a.x-.5)*a.q11;a.y=.5+(a.y-.5)*a.q12;a.dir=-a.q14+Math.asin(1);a.velocity=a.q13;a.strength=100;a.size=.07;a.xx=a.q4;a.yy=1-a.q8;a.x1=a.xx+Math.cos(a.dir+1.5708)*a.size;a.y1=a.yy-Math.sin(a.dir+1.5708)*a.size;a.x2=a.xx-Math.cos(a.dir+1.5708)*a.size;a.y2=a.yy+Math.sin(a.dir+1.5708)*a.size;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.size;a.si1=1-div(1,\\n1+pow(2,100*-a.d1));a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.size;a.si2=1-div(1,1+pow(2,100*-a.d2));a.dx+=(a.si1*Math.sin(a.y1-a.y)*a.d1-a.si2*Math.sin(a.y2-a.y)*a.d2)*a.strength*a.velocity;a.dy+=(-a.si1*Math.sin(a.x1-a.x)*a.d1+a.si2*Math.sin(a.x2-a.x)*a.d2)*a.strength*a.velocity;\",warp:\"vec2 xlat_mutabled;\\nvec3 xlat_mutabledx;\\nvec3 xlat_mutabledy;\\n shader_body { \\n  vec3 ret_1;\\n  vec3 tmpvar_2;\\n  tmpvar_2 = (texture (sampler_noise_lq, ((\\n    (uv_orig * texsize.xy)\\n   * texsize_noise_lq.zw) + rand_frame.xy)).xyz - 0.5);\\n  xlat_mutabled = (texsize.zw * 4.0);\\n  xlat_mutabledx = (((texture (sampler_blur1, \\n    (uv_orig + (vec2(1.0, 0.0) * xlat_mutabled))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_orig - (vec2(1.0, 0.0) * xlat_mutabled))\\n  ).xyz * scale1) + bias1));\\n  xlat_mutabledy = (((texture (sampler_blur1, \\n    (uv_orig + (vec2(0.0, 1.0) * xlat_mutabled))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_orig - (vec2(0.0, 1.0) * xlat_mutabled))\\n  ).xyz * scale1) + bias1));\\n  xlat_mutabled = uv;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = xlat_mutabledx.y;\\n  tmpvar_3.y = xlat_mutabledy.y;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = xlat_mutabledx.z;\\n  tmpvar_4.y = xlat_mutabledy.z;\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_main, uv_orig);\\n  ret_1.y = ((texture (sampler_main, (uv - \\n    ((tmpvar_3 * texsize.zw) * 6.0)\\n  )).y - 0.008) + ((1.0 - tmpvar_5.x) * 0.018));\\n  ret_1.z = ((texture (sampler_main, (uv - \\n    ((tmpvar_4 * texsize.zw) * 6.0)\\n  )).z - 0.008) + (tmpvar_5.x * 0.018));\\n  ret_1.x = texture (sampler_fc_main, (uv + ((tmpvar_2.xy * texsize.zw) * 0.5))).x;\\n  ret_1.x = (ret_1.x + ((\\n    (ret_1.x - ((texture (sampler_blur3, uv).xyz * scale3) + bias3).x)\\n   * 0.15) + (tmpvar_2 * 0.0042)).x);\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_1;\\n  ret = tmpvar_6.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.x = q3;\\n  tmpvar_1.y = q4;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = q6;\\n  tmpvar_2.y = q7;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q9;\\n  tmpvar_3.y = q10;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q12;\\n  tmpvar_4.y = q13;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (texsize.zw * 1.25);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (texture (sampler_main, (uv + (vec2(1.0, 0.0) * tmpvar_5))).xyz - texture (sampler_main, (uv - (vec2(1.0, 0.0) * tmpvar_5))).xyz);\\n  vec3 tmpvar_7;\\n  tmpvar_7 = (texture (sampler_main, (uv + (vec2(0.0, 1.0) * tmpvar_5))).xyz - texture (sampler_main, (uv - (vec2(0.0, 1.0) * tmpvar_5))).xyz);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_8.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_9;\\n  x_9 = ((uv - (tmpvar_8 * 8.0)) - tmpvar_1);\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_10.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_11;\\n  x_11 = ((uv - (tmpvar_10 * 8.0)) - tmpvar_2);\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_12.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_13;\\n  x_13 = ((uv - (tmpvar_12 * 8.0)) - tmpvar_3);\\n  vec2 tmpvar_14;\\n  tmpvar_14.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_14.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec2 x_15;\\n  x_15 = ((uv - (tmpvar_14 * 8.0)) - tmpvar_4);\\n  vec4 tmpvar_16;\\n  tmpvar_16.w = 1.0;\\n  tmpvar_16.xyz = mix (texture (sampler_main, uv).xyz, max (max (\\n    (vec3((1.0 - pow (sqrt(\\n      dot (x_9, x_9)\\n    ), 0.2))) * vec3(2.0, 1.0, -1.0))\\n  , \\n    (vec3((1.0 - pow (sqrt(\\n      dot (x_11, x_11)\\n    ), 0.2))) * vec3(2.0, -1.0, 1.0))\\n  ), max (\\n    (vec3((1.0 - pow (sqrt(\\n      dot (x_13, x_13)\\n    ), 0.2))) * vec3(-1.0, 1.0, 2.0))\\n  , \\n    (vec3((1.0 - pow (sqrt(\\n      dot (x_15, x_15)\\n    ), 0.2))) * vec3(1.0, -1.0, 2.0))\\n  )), vec3(0.5, 0.5, 0.5));\\n  ret = tmpvar_16.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.955,echo_zoom:.997,echo_alpha:.5,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wave_a:.001,wave_scale:.49,wave_smoothing:0,modwavealphastart:.71,modwavealphaend:1.3,warpscale:16.016,zoomexp:11.56276,fshader:1,zoom:1.05971,warp:.13126,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:0,ob_a:1,ib_size:0,mv_x:64,mv_y:48,mv_l:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:14,additive:1,num_inst:126,rad:.0303,tex_ang:.62832,r:0,b:1,g2:0,b2:1,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.8);\"},{baseVals:{enabled:1,sides:14,additive:1,num_inst:128,rad:.03,tex_ang:.62832,r:0,b:1,g2:0,b2:1,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.05*a.bass;a.ma-=3.1415*above(a.mid,1)*.05*a.mid;a.mx+=.0001*Math.cos(a.ma);a.my+=.0001*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.1);\"},{baseVals:{enabled:1,sides:14,additive:1,num_inst:32,rad:.0297,tex_ang:.62832,r:0,b:1,g2:0,b2:1,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.mid,1)*.01*a.mid;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0004*Math.cos(a.ma);a.my+=.0004*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.3);\"},{baseVals:{enabled:1,sides:14,additive:1,num_inst:16,rad:.0303,tex_ang:.62832,r:0,b:1,g2:0,b2:1,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,.5)*.02*a.bass;a.ma-=3.1415*above(a.treb,.5)*.02*a.treb;a.mx+=.0008*Math.cos(a.ma);a.my+=.0008*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.2);\"}],waves:[{baseVals:{enabled:1,thick:1,additive:1,scaling:2.0231,smoothing:0,r:0,b:0},init_eqs_str:\"a.d=0;a.tt2=0;a.res=0;a.tt1=0;a.diff=0;a.tt3=0;a.beat=0;a.vol=0;a.m=0;a.monitor=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.vol=8*a.bass+5*a.mid+3*a.treb;a.m=.97*a.m+.08*a.vol;a.monitor=a.vol;a.beat=above(a.vol,a.res)*above(a.vol,a.m)*above(a.vol,16);a.diff=(1-a.beat)*a.diff+a.beat*(a.vol-a.res);a.res=a.beat*(a.vol+.04*a.m)+(1-a.beat)*(a.res-div(60*(.1+.02*a.diff),a.fps));a.res=Math.max(0,a.res);a.a=a.beat;\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.5+a.d*a.sample*(1-a.sample)*4;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.xx=0;a.si3=0;a.q12=0;a.t1=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.q9=0;a.d1=0;a.si1=0;a.vx4=0;a.grav=0;a.x3=0;a.d2=0;a.q11=0;a.q10=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.m1=0;a.spring=0;a.si2=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=10;a.grav=.5;a.resist=1;a.bounce=.75;a.dt=.0005*div(60,a.fps);a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-\\na.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*\\na.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<\\nMath.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q1=a.x1;a.q2=a.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.q9=div(1,a.aspectx);a.q10=div(1,a.aspecty);a.zoom=1;a.r=.96*a.r+(a.x1-.5);a.rot=.1*a.r;a.q12=Math.atan2(a.vx4,a.vy4);a.q11=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.zoom=1.001;a.rot=0;a.warp=.2;a.wave_a=0;\",pixel_eqs_str:\"a.dir=-a.q12+Math.asin(1);a.b1=.1;a.m1=25*a.q11;a.t1=.05;a.xx=a.q4;a.yy=1-a.q8;a.x1=a.xx+Math.cos(a.dir+1.5708)*a.b1;a.y1=a.yy-Math.sin(a.dir+1.5708)*a.b1;a.x2=a.xx-Math.cos(a.dir+1.5708)*a.b1;a.y2=a.yy+Math.sin(a.dir+1.5708)*a.b1;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.b1;a.si1=1-div(1,1+pow(2,1E3*-a.d1));a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.b1;a.si2=1-div(1,1+pow(2,1E3*-a.d2));a.si3=0*-pow(a.q5,3);a.dx=2*(a.si1*Math.sin(a.y1-a.y)*a.m1*\\na.d1-a.si2*Math.sin(a.y2-a.y)*a.m1*a.d2+a.si3*Math.cos(a.dir)*a.t1);a.dy=2*(-a.si1*Math.sin(a.x1-a.x)*a.m1*a.d1+a.si2*Math.sin(a.x2-a.x)*a.m1*a.d2-a.si3*Math.sin(a.dir)*a.t1);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv + ((tmpvar_5 * texsize.zw) * 4.0));\\n  ret_1.z = (((texture (sampler_main, tmpvar_6).z - \\n    ((texture (sampler_main, tmpvar_6).z - ((texture (sampler_blur3, tmpvar_6).xyz * scale3) + bias3).z) * 0.02)\\n  ) - 0.008) + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * texsize_noise_lq.zw) + rand_frame.xy)\\n  ).xyz - 0.5) * 0.1)).x;\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_3.x;\\n  tmpvar_7.y = tmpvar_4.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = ((0.5 + (uv - 0.5)) - (tmpvar_7 * texsize.zw));\\n  ret_1.x = texture (sampler_main, tmpvar_8).x;\\n  ret_1.x = (ret_1.x + ((\\n    (ret_1.x - ((texture (sampler_blur3, tmpvar_8).xyz * scale3) + bias3))\\n  .x * 0.4) + 0.006));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_3.x;\\n  tmpvar_9.y = tmpvar_4.x;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_3.y;\\n  tmpvar_10.y = tmpvar_4.y;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = tmpvar_3.z;\\n  tmpvar_11.y = tmpvar_4.z;\\n  ret_1.y = texture (sampler_fc_main, (((uv - \\n    ((tmpvar_9 * texsize.zw) * 8.0)\\n  ) + (\\n    (tmpvar_10 * texsize.zw)\\n   * 4.0)) + ((tmpvar_11 * texsize.zw) * 8.0))).y;\\n  ret_1.y = (ret_1.y * (1.0 + (ret_1.x * 0.1)));\\n  ret_1.y = (ret_1.y - (0.004 + (\\n    clamp (ret_1.z, 0.0, 1.0)\\n   * 0.012)));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ret_1;\\n  ret = tmpvar_12.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 4.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_3.y;\\n  tmpvar_6.y = tmpvar_4.y;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = ((uv - (tmpvar_5 * 0.1)) + (tmpvar_6 * 0.06));\\n  vec4 tmpvar_8;\\n  tmpvar_8 = texture (sampler_main, uv);\\n  ret_1 = (((\\n    ((texture (sampler_blur2, tmpvar_7).xyz * scale2) + bias2)\\n  .x * \\n    clamp ((1.0 - tmpvar_8.z), 0.0, 1.0)\\n  ) * pow (hue_shader.yxz, vec3(8.0, 8.0, 8.0))) * 3.0);\\n  ret_1 = (mix (ret_1, (\\n    pow (hue_shader.yzx, vec3(8.0, 8.0, 8.0))\\n   * 1.4), vec3((\\n    (texture (sampler_main, tmpvar_7).x * 0.8)\\n   + \\n    ((texture (sampler_blur1, tmpvar_7).xyz * scale1) + bias1)\\n  .x))) * clamp ((1.0 - \\n    (((texture (sampler_blur1, uv).xyz * scale1) + bias1).y * 4.0)\\n  ), 0.0, 1.0));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_3.y;\\n  tmpvar_9.y = tmpvar_4.y;\\n  vec3 tmpvar_10;\\n  vec3 tmpvar_11;\\n  tmpvar_11 = pow (hue_shader, vec3(8.0, 8.0, 8.0));\\n  tmpvar_10 = mix (mix (ret_1, vec3(1.0, 1.0, 1.0), (\\n    (tmpvar_11 * texture (sampler_main, clamp ((uv - (tmpvar_9 * 2.0)), 0.0, 1.0)).z)\\n   * 1.2)), (tmpvar_11.zxy * 1.8), tmpvar_8.yyy);\\n  ret_1 = tmpvar_10;\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = tmpvar_10;\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.9,echo_zoom:1.169,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,wave_a:1.413,wave_scale:.418,wave_smoothing:0,wave_mystery:-.66,modwavealphastart:2,modwavealphaend:2,warpanimspeed:.626,warpscale:1.331,zoomexp:1.00001,zoom:.99951,warp:.08925,wave_r:0,wave_g:0,wave_x:.24,wave_y:.44,ob_size:.5,ob_r:.01,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_a:0},shapes:[{baseVals:{enabled:1,additive:1,rad:.0277,ang:6.03186,tex_ang:6.03186,tex_zoom:.6839,g:1,r2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.an=0;a.q6=0;a.q4=0;a.q5=0;a.q3=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.an+=a.q6;a.ang=.5*a.an;a.x=a.q4;a.y=a.q5;a.rad=a.q3*sqrt(2);a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:1,additive:1,rad:.0277,ang:6.03186,tex_ang:6.03186,tex_zoom:.6839,g:1,r2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.an=0;a.q9=0;a.q7=0;a.q8=0;a.q3=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.an+=a.q9;a.ang=.5*a.an;a.x=a.q7;a.y=a.q8;a.rad=a.q3*sqrt(2);a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:1,additive:1,rad:.0277,ang:6.03186,tex_ang:6.03186,tex_zoom:.6839,b:1,r2:1,g2:0,b2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.an=0;a.q12=0;a.q10=0;a.q11=0;a.q3=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.an+=a.q12;a.ang=.5*a.an;a.x=a.q10;a.y=a.q11;a.rad=a.q3*sqrt(2);a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,additive:1,scaling:2.0231,smoothing:0,r:0},init_eqs_str:\"a.d=0;a.tt2=0;a.res=0;a.tt1=0;a.diff=0;a.tt3=0;a.beat=0;a.vol=0;a.m=0;a.monitor=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.vol=8*a.bass+5*a.mid+3*a.treb;a.m=.97*a.m+.08*a.vol;a.monitor=a.vol;a.beat=above(a.vol,a.res)*above(a.vol,a.m)*above(a.vol,16);a.diff=(1-a.beat)*a.diff+a.beat*(a.vol-a.res);a.res=a.beat*(a.vol+.04*a.m)+(1-a.beat)*(a.res-div(60*(.1+.02*a.diff),a.fps));a.res=Math.max(0,a.res);a.a=a.beat;\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.5+a.d*a.sample*(1-a.sample)*2;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.q12=0;a.w2=0;a.ref_ang=0;a.du=0;a.x1=0;a.vx3=0;a.q13=0;a.q6=0;a.q1=0;a.q5=0;a.q9=0;a.vx1=0;a.mult=0;a.x3=0;a.q11=0;a.q10=0;a.ang2=0;a.dv=0;a.vr3=0;a.vr2=0;a.q4=0;a.bounce=0;a.vr=0;a.v2r=0;a.w1=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.vy1=0;a.q2=0;a.q14=0;a.dist=0;a.vr1=0;a.v1=0;a.vx2=0;a.q3=0;a.q7=0;a.vy3=0;a.v2=0;a.q8=0;a.x1=.5;a.y1=.6;a.x2=.5;a.y2=.4;a.x3=.5;a.y3=.2;a.vr1=.0001;a.vr2=0;a.vr3=0;a.vx1=0;a.vx2=0;a.vx3=0;\",frame_eqs_str:\"a.zoom=1;a.warp=0;a.wave_a=0;a.r=.03+.004*(a.bass_att+a.treb_att);a.monitor=a.aspecty;a.vr=Math.sin(a.vr1)*a.r;a.bounce=below(a.y1,a.r-.5*(a.aspectx-1));a.y1+=a.vy1;a.vy1=.00001<Math.abs(a.bounce)?.96*Math.abs(a.vy1)+.1*(a.r-a.y1-.5*(a.aspectx-1)):a.vy1-div(.018,a.fps);a.vx1=.00001<Math.abs(a.bounce)?a.vx1+.15*(a.vr-a.vx1):a.vx1;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vx1-a.vr):a.vr;a.vr1=Math.asin(div(a.vr,a.r));a.bounce=above(a.x1,1-a.r+.5*(a.aspecty-1));a.vx1=.00001<Math.abs(a.bounce)?\\n.96*-Math.abs(a.vx1)+.1*(1-a.r-a.x1+.5*(a.aspecty-1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?a.vy1+.15*(a.vr-a.vy1):a.vy1;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vy1-a.vr):a.vr;a.vr1=Math.asin(div(a.vr,a.r));a.bounce=below(a.x1,a.r-.5*(a.aspecty-1));a.x1+=a.vx1;a.vx1=.00001<Math.abs(a.bounce)?.96*Math.abs(a.vx1)+.1*(a.r-a.x1-.5*(a.aspecty-1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?a.vy1+.15*(-a.vr-a.vy1):a.vy1;a.vr=.00001<Math.abs(a.bounce)?a.vr-.85*(a.vy1+a.vr):a.vr;a.vr1=Math.asin(div(a.vr,a.r));\\na.vr=Math.sin(a.vr2)*a.r;a.bounce=below(a.y2,a.r-.5*(a.aspectx-1));a.y2+=a.vy2;a.vy2=.00001<Math.abs(a.bounce)?.96*Math.abs(a.vy2)+.1*(a.r-a.y2-.5*(a.aspectx-1)):a.vy2-div(.018,a.fps);a.vx2=.00001<Math.abs(a.bounce)?a.vx2+.15*(a.vr-a.vx2):a.vx2;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vx2-a.vr):a.vr;a.vr2=Math.asin(div(a.vr,a.r));a.bounce=above(a.x2,1-a.r+.5*(a.aspecty-1));a.vx2=.00001<Math.abs(a.bounce)?.96*-Math.abs(a.vx2)+.1*(1-a.r-a.x2+.5*(a.aspecty-1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?\\na.vy2+.15*(a.vr-a.vy2):a.vy2;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vy2-a.vr):a.vr;a.vr2=Math.asin(div(a.vr,a.r));a.bounce=below(a.x2,a.r-.5*(a.aspecty-1));a.x2+=a.vx2;a.vx2=.00001<Math.abs(a.bounce)?.96*Math.abs(a.vx2)+.1*(a.r-a.x2-.5*(a.aspecty-1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?a.vy2+.15*(-a.vr-a.vy2):a.vy2;a.vr=.00001<Math.abs(a.bounce)?a.vr-.85*(a.vy2+a.vr):a.vr;a.vr2=Math.asin(div(a.vr,a.r));a.vr=Math.sin(a.vr3)*a.r;a.bounce=below(a.y3,a.r-.5*(a.aspectx-1));a.y3+=a.vy3;a.vy3=.00001<\\nMath.abs(a.bounce)?.96*Math.abs(a.vy3)+.1*(a.r-a.y3-.5*(a.aspectx-1)):a.vy3-div(.018,a.fps);a.vx3=.00001<Math.abs(a.bounce)?a.vx3+.15*(a.vr-a.vx3):a.vx3;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vx3-a.vr):a.vr;a.vr3=Math.asin(div(a.vr,a.r));a.bounce=above(a.x3,1-a.r+.5*(a.aspecty-1));a.vx3=.00001<Math.abs(a.bounce)?.96*-Math.abs(a.vx3)+.1*(1-a.r-a.x3+.5*(a.aspecty-1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?a.vy3+.15*(a.vr-a.vy3):a.vy3;a.vr=.00001<Math.abs(a.bounce)?a.vr+.85*(a.vy3-a.vr):a.vr;a.vr3=\\nMath.asin(div(a.vr,a.r));a.bounce=below(a.x3,a.r-.5*(a.aspecty-1));a.x3+=a.vx3;a.vx3=.00001<Math.abs(a.bounce)?.96*Math.abs(a.vx3)+.1*(a.r-a.x3-.5*(a.aspecty-1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?a.vy3+.15*(-a.vr-a.vy3):a.vy3;a.vr=.00001<Math.abs(a.bounce)?a.vr-.85*(a.vy3+a.vr):a.vr;a.vr3=Math.asin(div(a.vr,a.r));a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x2-a.vx2)+sqr(a.y1+a.vy1-a.y2-a.vy2)),2*a.r);a.bounce*=below(sqrt(sqr(a.x1+a.vx1-a.x2-a.vx2)+sqr(a.y1+a.vy1-a.y2-a.vy2)),sqrt(sqr(a.x1-a.x2)+sqr(a.y1-\\na.y2)));a.ref_ang=Math.atan2(a.x2-a.x1,a.y2-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx2,a.vy2);a.vr=Math.sin(a.vr1)*a.r;a.v2r=Math.sin(a.vr2)*a.r;a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?\\nMath.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.v2r-a.vr-Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+\\n.1*(a.v2r-a.vr-Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy2;a.vr=.00001<Math.abs(a.bounce)?a.vr+.9*(Math.cos(a.w1-a.ref_ang)*(a.v1-a.v2)-a.vr):a.vr;a.vr1=Math.asin(div(a.vr,a.r));a.v2r=.00001<Math.abs(a.bounce)?a.v2r+.9*(Math.cos(a.w2-a.ref_ang)*(a.v2-a.v1)-a.v2r):a.v2r;a.vr2=Math.asin(div(a.v2r,a.r));a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x3-a.vx3)+sqr(a.y1+a.vy1-a.y3-a.vy3)),2*a.r);a.bounce*=below(sqrt(sqr(a.x1+\\na.vx1-a.x3-a.vx3)+sqr(a.y1+a.vy1-a.y3-a.vy3)),sqrt(sqr(a.x1-a.x3)+sqr(a.y1-a.y3)));a.ref_ang=Math.atan2(a.x3-a.x1,a.y3-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx3,a.vy3);a.vr=Math.sin(a.vr1)*a.r;a.v2r=Math.sin(a.vr3)*a.r;a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.sin(a.ref_ang+Math.asin(1))*a.v2*\\nMath.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.v2r-a.vr-Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx3;\\na.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.v2r-a.vr-Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy3;a.vr=.00001<Math.abs(a.bounce)?a.vr+.9*(Math.cos(a.w1-a.ref_ang)*(a.v1-a.v2)-a.vr):a.vr;a.vr1=Math.asin(div(a.vr,a.r));a.v2r=.00001<Math.abs(a.bounce)?a.v2r+.9*(Math.cos(a.w2-a.ref_ang)*(a.v2-a.v1)-a.v2r):a.v2r;a.vr3=Math.asin(div(a.v2r,a.r));a.bounce=below(sqrt(sqr(a.x3+\\na.vx3-a.x2-a.vx2)+sqr(a.y3+a.vy3-a.y2-a.vy2)),2*a.r);a.bounce*=below(sqrt(sqr(a.x2+a.vx2-a.x3-a.vx3)+sqr(a.y2+a.vy2-a.y3-a.vy3)),sqrt(sqr(a.x2-a.x3)+sqr(a.y2-a.y3)));a.ref_ang=Math.atan2(a.x2-a.x3,a.y2-a.y3)+Math.asin(1);a.v1=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.v2=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.w1=Math.atan2(a.vx3,a.vy3);a.w2=Math.atan2(a.vx2,a.vy2);a.vr=Math.sin(a.vr3)*a.r;a.v2r=Math.sin(a.vr2)*a.r;a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.sin(a.ref_ang)*\\na.v1*Math.cos(a.w1-a.ref_ang))+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.v2r-Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy3;a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.v2r-a.vr-Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.sin(a.ref_ang+\\nMath.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.v2r-a.vr-Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy2;a.vr=.00001<Math.abs(a.bounce)?a.vr+.9*(Math.cos(a.w1-a.ref_ang)*(a.v1-a.v2)-a.vr):a.vr;a.vr3=Math.asin(div(a.vr,a.r));a.v2r=.00001<Math.abs(a.bounce)?a.v2r+.9*(Math.cos(a.w2-a.ref_ang)*(a.v2-a.v1)-a.v2r):a.v2r;\\na.vr2=Math.asin(div(a.v2r,a.r));a.q1=a.aspectx;a.q2=a.aspecty;a.q3=2*a.r;a.q4=a.x1;a.q5=a.y1;a.q6=a.vr1;a.q7=a.x2;a.q8=a.y2;a.q9=a.vr2;a.q10=a.x3;a.q11=a.y3;a.q12=a.vr3;a.q13=Math.atan2(div(a.x1+a.x2+a.x3,3)-.5,div(a.y1+a.y2+a.y3,3)-.5);a.q14=.2*sigmoid(sqrt(sqr(div(a.x1+a.x2+a.x3,3)-.5)+sqr(div(a.y1+a.y2+a.y3,3)-.5)),2);\",pixel_eqs_str:\"a.du=2*a.x-1-div(2*(a.q4+a.q7+a.q10-1.5),3);a.dv=2*a.y-1+div(2*(a.q5+a.q8+a.q11-1.5),3);a.dist=sqrt(a.du*a.du+a.dv*a.dv);a.ang2=Math.atan2(a.du,a.dv);a.mult=.4*Math.sin(.05*a.dist)*a.q14;a.dx=a.mult*Math.sin(2*a.ang2+a.q13)*a.aspectx;a.dy=a.mult*Math.cos(2*a.ang2+a.q13)*a.aspecty;\",warp:\" shader_body { \\n  float n_1;\\n  vec3 ret_2;\\n  vec4 tmpvar_3;\\n  tmpvar_3 = texture (sampler_pw_main, uv);\\n  ret_2 = tmpvar_3.xyz;\\n  n_1 = (clamp ((texture (sampler_pw_main, \\n    (uv + texsize.zw)\\n  ).x * 999.0), 0.0, 1.0) + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(1.0, 0.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(1.0, -1.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(0.0, 1.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(0.0, -1.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(-1.0, 1.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv + (texsize.zw * vec2(-1.0, 0.0)))\\n  ).x * 999.0), 0.0, 1.0));\\n  n_1 = (n_1 + clamp ((texture (sampler_pw_main, \\n    (uv - texsize.zw)\\n  ).x * 999.0), 0.0, 1.0));\\n  if ((n_1 < 1.9)) {\\n    ret_2 = (tmpvar_3.xyz - 0.4);\\n  };\\n  if ((n_1 > 3.1)) {\\n    ret_2 = (ret_2 - 0.4);\\n  };\\n  bool tmpvar_4;\\n  if ((ret_2.x < 0.1)) {\\n    tmpvar_4 = (abs((n_1 - 3.0)) < 0.5);\\n  } else {\\n    tmpvar_4 = bool(0);\\n  };\\n  if (tmpvar_4) {\\n    ret_2 = (ret_2 + 0.4);\\n  };\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ret_2;\\n  ret = tmpvar_5.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret2_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 8.0);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1)).y;\\n  tmpvar_4.y = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1)).y;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv + (tmpvar_4 * 0.55));\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_blur3, uv);\\n  ret_2 = (vec3((0.25 * dot (\\n    clamp ((2.0 * ((tmpvar_6.xyz * scale3) + bias3)), 0.0, 1.0)\\n  , vec3(0.32, 0.49, 0.29)))) - (0.8 * dot (\\n    clamp (((20.0 * (\\n      (0.6 * ((texture (sampler_blur2, uv).xyz * scale2) + bias2))\\n     - 0.01)) - 2.0), 0.0, 1.0)\\n  , vec3(0.32, 0.49, 0.29))));\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_blur1, uv);\\n  ret_2 = (ret_2 + dot (clamp (\\n    ((30.0 * ((texture (sampler_main, uv).xyz + \\n      (((tmpvar_7.xyz * scale1) + bias1) * 0.15)\\n    ) - 0.01)) - 2.0)\\n  , 0.0, 1.0), vec3(0.32, 0.49, 0.29)));\\n  ret_2 = (ret_2 + 1.0);\\n  vec3 tmpvar_8;\\n  tmpvar_8 = mix (ret_2, (ret_2 * (\\n    ((texture (sampler_blur3, tmpvar_5).xyz * scale3) + bias3)\\n   - \\n    ((texture (sampler_blur1, tmpvar_5).xyz * scale1) + bias1)\\n  )), pow (hue_shader, ret_2));\\n  ret2_1 = (vec3((-0.5 * dot (\\n    ((texture (sampler_blur3, tmpvar_5).xyz * scale3) + bias3)\\n  , vec3(0.32, 0.49, 0.29)))) + (0.8 * (\\n    (texture (sampler_blur1, tmpvar_5).xyz * scale1)\\n   + bias1)));\\n  ret2_1 = (ret2_1 - (0.9 * texture (sampler_main, tmpvar_5).xyz));\\n  ret2_1 = (ret2_1 - 1.5);\\n  vec3 tmpvar_9;\\n  tmpvar_9 = mix (ret2_1, (ret2_1 * (\\n    ((tmpvar_6.xyz * scale3) + bias3)\\n   - \\n    ((tmpvar_7.xyz * scale1) + bias1)\\n  )), pow (hue_shader.zxy, tmpvar_8));\\n  ret2_1 = tmpvar_9;\\n  vec3 tmpvar_10;\\n  tmpvar_10 = abs((tmpvar_8 - tmpvar_9));\\n  ret_2 = (tmpvar_10 * tmpvar_10);\\n  ret_2 = (ret_2 * 1.15);\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = ret_2;\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1,decay:.9,echo_zoom:1,wave_brighten:0,wrap:0,wave_a:.001,wave_scale:5.715,wave_smoothing:.9,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.162,warpscale:5.582,zoomexp:.32104,zoom:.9901,warp:.11563,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,textured:1,rad:.05343,tex_zoom:12.77228,g:1,b:1,a:0,r2:1,b2:1,a2:1,border_g:0,border_a:0},init_eqs_str:\"a.vx=0;a.vy=0;\",frame_eqs_str:\"\"},{baseVals:{enabled:1,sides:100,textured:1,y:.75,rad:.46753,g:1,b:1,r2:1,b2:1,border_a:0},init_eqs_str:\"a.w=0;a.q1=0;\",frame_eqs_str:\"a.w=4*-Math.atan2(.5,a.q1)+4*Math.asin(1);a.ang=a.w;a.x=.5+.19*Math.sin(a.w);a.y=.5+.26*Math.cos(a.w);\"},{baseVals:{enabled:1,sides:100,textured:1,y:.75,rad:.46753,g:1,b:1,r2:1,b2:1,border_a:0},init_eqs_str:\"a.w=0;a.q1=0;\",frame_eqs_str:\"a.w=4*-Math.atan2(.5,a.q1)+4*Math.asin(1)+div(2*Math.asin(1),3);a.ang=a.w;a.x=.5+.19*Math.sin(a.w);a.y=.5+.26*Math.cos(a.w);\"},{baseVals:{enabled:1,sides:100,textured:1,y:.75,rad:.46753,g:1,b:1,r2:1,b2:1,border_a:0},init_eqs_str:\"a.w=0;a.q1=0;\",frame_eqs_str:\"a.w=4*-Math.atan2(.5,a.q1)+4*Math.asin(1)-div(2*Math.asin(1),3);a.ang=a.w;a.x=.5+.19*Math.sin(a.w);a.y=.5+.26*Math.cos(a.w);\"}],waves:[{baseVals:{enabled:1,usedots:1,thick:1,additive:1,scaling:2.44415,smoothing:0},init_eqs_str:\"a.d=0;a.n=0;a.y1=0;a.xx=0;a.z=0;a.w=0;a.t5=0;a.t1=0;a.x1=0;a.cl3=0;a.j3=0;a.cl2=0;a.zoom=0;a.j=0;a.cl1=0;a.t8=0;a.v=0;a.t3=0;a.t6=0;a.pi3=0;a.t7=0;a.c2=0;a.j2=0;a.s3=0;a.t=0;a.k=0;a.zz=0;a.c3=0;a.t2=0;a.bb=0;a.s1=0;a.s2=0;a.t4=0;a.yy=0;a.c=0;a.c1=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.t1=0;a.v=.01;a.j+=.01*a.bass;a.j2+=.01*a.mid_att;a.j3+=.01*a.treb_att;a.t2=a.j;a.t3=a.j2;a.t4=a.j3;a.k=.99*a.k+div(10*a.mid,a.fps);a.t5=-a.k;a.cl1=a.cl1-.0005-.003*a.bass;a.cl1=.00001<Math.abs(above(a.cl1,1))?0:a.cl1;a.cl1=.00001<Math.abs(below(a.cl1,0))?1:a.cl1;a.t8=a.cl1;a.cl2=a.cl2+.0001+.001*a.mid-.0005*a.bass-.0005*a.treb;a.cl2=.00001<Math.abs(above(a.cl2,1))?0:a.cl2;a.cl2=.00001<Math.abs(below(a.cl2,0))?1:a.cl2;a.t7=a.cl2;a.cl3=a.cl3+.0001+.001*a.treb-.0005*a.bass-.0005*\\na.mid;a.cl3=.00001<Math.abs(above(a.cl3,1))?0:a.cl3;a.cl3=.00001<Math.abs(below(a.cl3,0))?1:a.cl3;a.t6=a.cl3;\",point_eqs_str:\"a.xx=div(mod(983624912364*a.sample,1E7)+100,1E7);a.yy=div(mod(1896575575*a.xx,1E7)+100,1E7);a.zz=div(mod(58652340875*a.yy,1E7)+100,1E7);a.d=sqrt(sqr(a.xx)+sqr(a.yy)+sqr(a.zz));a.zz=a.zz+a.t8-(.00001<Math.abs(above(a.zz+a.t8,1))?1:0)-.5;a.xx=a.xx+a.t7-(.00001<Math.abs(above(a.xx+a.t7,1))?1:0)-.5;a.yy=a.yy+a.t6-(.00001<Math.abs(above(a.yy+a.t6,1))?1:0)-.5;a.v=.001;a.w=1;a.bb=a.d*a.d*.5;a.n=.3;a.s1=Math.sin(Math.sin(a.t2*a.w+a.bb)*a.n);a.s2=Math.sin(Math.sin(a.t3*a.w+a.bb)*a.n);\\na.s3=Math.sin(Math.sin(a.t4*a.w+a.bb)*a.n);a.c1=Math.cos(Math.sin(a.t2*a.w+a.bb)*a.n);a.c2=Math.cos(Math.sin(a.t3*a.w+a.bb)*a.n);a.c3=Math.cos(Math.sin(a.t4*a.w+a.bb)*a.n);a.z=(a.c3*a.s1*a.c2+a.s3*a.s2)*a.xx-(a.c3*a.s1*a.s2-a.s3*a.c2)*a.yy+a.c3*a.c1*a.zz;a.x1=a.c1*a.c2*a.xx+a.c1*a.s2*a.yy-a.s1*a.zz;a.y1=(a.s3*a.s1*a.c2-a.c3*a.s2)*a.xx+(a.s3*a.s1*a.s2+a.c3*a.c2)*a.yy+a.s3*a.c1*a.zz;a.zoom=.5*div(1,a.z+.5);a.x=.5+a.zoom*a.x1+0*Math.sin(.1*a.time);a.y=.5+a.zoom*a.y1+0*Math.cos(.16801*a.time);a.pi3=2.0941239;\\na.t=2*a.z+1*a.t2;a.c=3;a.r=Math.sin(a.t)*a.c;a.g=Math.sin(a.t+a.pi3)*a.c;a.b=Math.sin(a.t-a.pi3)*a.c;a.r=.00001<Math.abs(above(a.r,1))?1:a.r;a.r=.00001<Math.abs(below(a.r,0))?0:a.r;a.g=.00001<Math.abs(above(a.g,1))?1:a.g;a.g=.00001<Math.abs(below(a.g,0))?0:a.g;a.b=.00001<Math.abs(above(a.b,1))?1:a.b;a.b=.00001<Math.abs(below(a.b,0))?0:a.b;a.a=-a.z+.7;\"},{baseVals:{enabled:1,thick:1,scaling:2.44415,smoothing:0,a:.05},init_eqs_str:\"a.t8=0;a.q1=0;a.pi3=0;a.t=0;a.q4=0;a.q6=0;a.c=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.t8=1;\",point_eqs_str:\"a.t8=-a.t8;a.y=.48*a.sample;a.x=.5+.04*a.t8-a.t8*a.sample*.02+(sqr(2*a.sample-1)-1)*a.q1*.5;a.pi3=2.0941239;a.t=10*-(a.q4-a.q6)+a.sample*Math.asin(1)*4.01;a.c=9;a.r=Math.sin(a.t)*a.c;a.g=Math.sin(a.t+a.pi3)*a.c;a.b=Math.sin(a.t-a.pi3)*a.c;a.r=.00001<Math.abs(above(a.r,1))?1:a.r;a.r=.00001<Math.abs(below(a.r,0))?0:a.r;a.g=.00001<Math.abs(above(a.g,1))?1:a.g;a.g=.00001<Math.abs(below(a.g,0))?0:a.g;a.b=.00001<Math.abs(above(a.b,1))?1:a.b;a.b=.00001<Math.abs(below(a.b,0))?0:a.b;\\n\"},{baseVals:{enabled:1,samples:49,scaling:2.44415,smoothing:0,r:0,g:0,b:0},init_eqs_str:\"a.t8=0;a.q1=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.t8=1;\",point_eqs_str:\"a.t8=-1;a.y=.48*a.sample;a.x=.5+.04*a.t8-a.t8*a.sample*.02+(sqr(2*a.sample-1)-1)*a.q1*.5;\"},{baseVals:{enabled:1,samples:49,scaling:2.44415,smoothing:0,r:0,g:0,b:0},init_eqs_str:\"a.t8=0;a.q1=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.t8=1;\",point_eqs_str:\"a.t8=1;a.y=.48*a.sample;a.x=.5+.04*a.t8-a.t8*a.sample*.02+(sqr(2*a.sample-1)-1)*a.q1*.5;\"}],init_eqs_str:\"a.d=0;a.vt=0;a.q6=0;a.q1=0;a.q5=0;a.vb=0;a.q9=0;a.v=0;a.mm=0;a.tt=0;a.q4=0;a.bb=0;a.q2=0;a.q3=0;a.vvm=0;a.vvb=0;a.vm=0;a.vvt=0;a.x1=0;a.y1=0;\",frame_eqs_str:\"a.zoom=1;a.q1=.1*(a.bass-a.treb);a.vvb=.00001<Math.abs(below(a.vvb,0))?0:a.vvb;a.vvm=.00001<Math.abs(below(a.vvm,0))?0:a.vvm;a.vvt=.00001<Math.abs(below(a.vvt,0))?0:a.vvt;a.vb=.85*a.vb+(1-a.vb)*pow(a.bass,2)*.001;a.vvb=.95*a.vvb+(1-a.vvb)*a.vb*.2;a.vm=.85*a.vm+(1-a.vm)*pow(a.mid,2)*.01;a.vvm=.95*a.vvm+(1-a.vvm)*a.vm*.2;a.vt=.85*a.vt+(1-a.vt)*pow(a.treb,2)*.001;a.vvt=.95*a.vvt+(1-a.vvt)*a.vt*.2;a.q1=(a.vvb-a.vvt)*a.vvm;a.q2=a.vvm;a.q3=a.vvt;a.v=.2;a.d=0;a.bb=a.bb+a.vvb*a.v-a.d;\\na.mm=a.mm+a.vvm*a.v-a.d;a.tt=a.tt+a.vvt*a.v-a.d;a.q4=a.bb;a.q5=a.mm;a.q6=a.tt;a.q4=.00001<Math.abs(above(Math.abs(a.q1),.02))?.99:1;a.q9=.5+.5*Math.sin(.14*a.time);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_fc_main, uv) * q4).xyz;\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.x = 0.5;\\n  tmpvar_1.y = (1.0 - q9);\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (uv_orig - tmpvar_1);\\n  float tmpvar_3;\\n  tmpvar_3 = (3.0 / tmpvar_2.y);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = ((tmpvar_2.x * tmpvar_3) * q9);\\n  tmpvar_4.y = (tmpvar_3 * q9);\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_main, fract(((1.0 - \\n    abs(((fract(\\n      ((tmpvar_2 + vec2(0.5, 1.0)) * 0.5)\\n    ) * 2.0) - 1.0))\\n  ) - (\\n    ((texture (sampler_noise_hq, ((tmpvar_4 * 0.05) + (vec2(0.1, -0.05) * time))) - 0.5) * float(int((tmpvar_2.y > 0.0))))\\n  .xy * 0.025))));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (((tmpvar_5.xyz * tmpvar_5.xyz) * 1.4) - 0.04);\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.56,decay:1,echo_zoom:.362,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.599,wave_smoothing:0,wave_mystery:-.5,modwavealphastart:2,modwavealphaend:2,warpscale:.107,zoomexp:.1584,fshader:1,warp:.01,wave_r:.51,wave_g:.5,ob_size:0,ob_a:1,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:.5,mv_r:0,mv_g:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.y3=0;a.y1=0;a.xx=0;a.s=0;a.t1=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.v=0;a.vx4=0;a.mm=0;a.tt=0;a.grav=0;a.x3=0;a.xx2=0;a.q4=0;a.a=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.r=0;a.x2=0;a.mx=0;a.mn=0;a.vy2=0;a.y2=0;a.bb=0;a.q2=0;a.m1=0;a.spring=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.vy3=0;a.xx1=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.ib_r=.3*Math.sin(5*a.time)+.7;a.ib_g=.3*Math.sin(4*a.time)+.3;a.ib_b=.5*Math.sin(4*div(a.time,3))+.5;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=10;a.grav=.5;a.resist=1;a.bounce=.75;a.dt=.0002*div(60,a.fps);a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-\\n2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-a.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<\\nMath.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*a.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?\\na.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q4=a.x4;a.q8=a.y4;a.q1=a.aspectx;a.q2=a.aspecty;a.zoom=1;a.warp=0;a.bb=.99*a.bb+.02*a.bass;a.mm=.99*a.mm+.02*a.mid;a.tt=.99*a.tt+.02*a.treb;a.mx=Math.max(Math.max(a.bb,a.mm),a.tt);a.mn=Math.min(Math.min(a.bb,a.mm),a.tt);a.ob_r=div(a.bb-a.mn,a.mx-a.mn);a.ob_b=div(a.mm-a.mn,a.mx-a.mn);a.ob_g=div(a.tt-a.mn,a.mx-a.mn);a.q6=Math.atan2(a.vx4,\\na.vy4);a.q5=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.a=.95*a.a+a.q5;a.s=.9*a.s+a.a;a.q3=.1*a.s;a.monitor=a.s;a.wave_a=0;\",pixel_eqs_str:\"a.x=.5+(a.x-.5)*a.q1;a.y=.5+(a.y-.5)*a.q2;a.dir=-a.q6+0*Math.asin(1);a.b1=.1;a.m1=25*a.q5;a.t1=.05;a.xx=a.q4;a.yy=1-a.q8;a.dx=0;a.dy=0;a.d=sqrt((a.x-a.xx)*(a.x-a.xx)+(a.y-a.yy)*(a.y-a.yy));a.r=.05;a.v=-35*a.q5;a.dx=a.v*Math.sin(a.dir)*(a.r-a.d)*(1-sigmoid(a.d-a.r,200))*a.q2;a.dy=a.v*Math.cos(a.dir)*(a.r-a.d)*(1-sigmoid(a.d-a.r,200))*a.q1;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  tmpvar_1.xyz = ((texture (sampler_main, clamp (\\n    (uv - (((vec2(0.0, 32.0) * texsize.zw) * dot (\\n      (tmpvar_2.xyz - 0.35)\\n    , vec3(0.32, 0.49, 0.29))) * (dot (tmpvar_2.xyz, vec3(0.32, 0.49, 0.29)) - 0.4)))\\n  , 0.0, 1.0)).xyz - 0.0011) + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 1.5)) + rand_frame.xy)\\n  ) - 0.5) * 0.0038).xyz);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (texture (sampler_main, (uv - tmpvar_2)).xyz - texture (sampler_main, (uv + tmpvar_2)).xyz).x;\\n  tmpvar_4.y = (texture (sampler_main, (uv - tmpvar_3)).xyz - texture (sampler_main, (uv + tmpvar_3)).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    ((uv - 0.5) * 2.0)\\n  )) - tmpvar_4);\\n  float tmpvar_5;\\n  tmpvar_5 = clamp ((0.04 / sqrt(\\n    dot (uv1_1, uv1_1)\\n  )), 0.0, 1.0);\\n  uv1_1 = ((0.3 * cos(\\n    (uv1_1 * 12.0)\\n  )) - (9.0 * tmpvar_4));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (tmpvar_5 + ((texture (sampler_main, uv).xyz * 12.0) * vec3(clamp (\\n    (0.04 / sqrt(dot (uv1_1, uv1_1)))\\n  , 0.0, 1.0))));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,modwavealphabyvolume:1,wave_a:.207,wave_scale:.397,wave_smoothing:0,wave_mystery:.24,modwavealphaend:1.17,warpscale:16.016,zoomexp:11.56276,zoom:1.05971,warp:.13126,ob_size:.005,ob_a:1,ib_size:0,mv_x:64,mv_y:48,mv_l:0,mv_r:.35,mv_g:.35,mv_b:.35,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.cx1=0;a.y3=0;a.y1=0;a.cy1=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.v=0;a.vx4=0;a.grav=0;a.x3=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.spring=0;a.vx2=0;a.q3=0;a.resist=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.q8=0;\",frame_eqs_str:\"a.decay=1;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+1.5*(a.xx1-a.xx2);a.y1=.5+a.yy1;a.spring=18;a.grav=1;a.resist=5;a.bounce=.9;a.dt=.0003;a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-a.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-\\na.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*a.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*\\na.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q1=a.x1;a.q2=\\na.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.q6=Math.atan2(a.vx4,a.vy4);a.q5=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.zoom=1.001;a.rot=0;a.warp=.2;a.wave_a=0;\",pixel_eqs_str:\"a.r=.2;a.cx1=a.q4;a.cy1=a.q5;a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.dir=-(a.r*a.r-a.d*a.d)*a.q3;a.x1=.00001<Math.abs(above(a.d,a.r))?0:Math.sin(a.y-a.cy1)*a.dir;a.y1=.00001<Math.abs(above(a.d,a.r))?0:-Math.sin(a.x-a.cx1)*a.dir;a.v=1;a.dx=a.x1*a.v;a.dy=a.y1*a.v;\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.5 + ((uv - 0.5) * 1.002));\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 8.0);\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_4.x;\\n  tmpvar_6.y = tmpvar_5.x;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = fract(((0.5 + \\n    (uv_1 - 0.5)\\n  ) - (tmpvar_6 * texsize.zw)));\\n  ret_2.x = texture (sampler_main, tmpvar_7).x;\\n  ret_2.x = (ret_2.x + ((\\n    (ret_2.x - ((texture (sampler_blur2, tmpvar_7).xyz * scale2) + bias2))\\n  .x * 0.4) + 0.006));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_5.x;\\n  tmpvar_8.y = -(tmpvar_4.x);\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_4.z;\\n  tmpvar_9.y = tmpvar_5.z;\\n  ret_2.z = max ((clamp (\\n    (((texture (sampler_blur1, uv_1).xyz * scale1) + bias1).x - 0.3)\\n  , 0.0, 1.0) * 2.0), (texture (sampler_fc_main, (\\n    (uv_1 - ((tmpvar_8 * texsize.zw) * 8.0))\\n   + \\n    ((tmpvar_9 * texsize.zw) * 4.0)\\n  )).z - 0.008));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4.y;\\n  tmpvar_10.y = tmpvar_5.y;\\n  ret_2.y = max (ret_2.x, (texture (sampler_fc_main, (uv_1 + \\n    (tmpvar_10 * texsize.zw)\\n  )).y - 0.016));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = ret_2;\\n  ret = tmpvar_11.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 6.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = dot (tmpvar_3, vec3(0.32, 0.49, 0.29));\\n  tmpvar_5.y = dot (tmpvar_4, vec3(0.32, 0.49, 0.29));\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - (0.25 * tmpvar_5));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = dot (tmpvar_3, vec3(0.32, 0.49, 0.29));\\n  tmpvar_7.y = dot (tmpvar_4, vec3(0.32, 0.49, 0.29));\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (uv + (0.25 * tmpvar_7));\\n  ret_1 = ((0.8 * (\\n    (texture (sampler_blur3, tmpvar_6).xyz * scale3)\\n   + bias3)) - ((texture (sampler_blur1, tmpvar_6).xyz * scale1) + bias1));\\n  ret_1 = (ret_1 + (0.6 * (\\n    (texture (sampler_blur1, uv).xyz * scale1)\\n   + bias1)));\\n  ret_1 = (ret_1 - ((\\n    (texture (sampler_blur2, tmpvar_8).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur1, tmpvar_8).xyz * scale1)\\n   + bias1)));\\n  ret_1 = (ret_1 + ((1.2 * texture (sampler_main, tmpvar_8).xyz) + (0.15 * \\n    ((texture (sampler_blur1, tmpvar_8).xyz * scale1) + bias1)\\n  )));\\n  ret_1 = (ret_1 + 1.0);\\n  float tmpvar_9;\\n  tmpvar_9 = dot (ret_1, vec3(0.32, 0.49, 0.29));\\n  ret_1 = (mix (vec3(tmpvar_9), (\\n    (0.75 * vec3(tmpvar_9))\\n   * \\n    dot ((((0.6 * \\n      ((texture (sampler_blur3, tmpvar_6).xyz * scale3) + bias3)\\n    ) - (0.7 * texture (sampler_main, uv).xyz)) - (0.3 * (\\n      (texture (sampler_blur1, tmpvar_8).xyz * scale1)\\n     + bias1))), vec3(0.32, 0.49, 0.29))\\n  ), pow (hue_shader, vec3(tmpvar_9))) * 0.9);\\n  ret_1 = (ret_1 * ret_1);\\n  vec3 tmpvar_10;\\n  tmpvar_10 = sqrt(ret_1);\\n  ret_1 = tmpvar_10;\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = tmpvar_10;\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1,wave_thick:1,wrap:0,wave_a:.004,wave_scale:9.731,wave_smoothing:0,wave_mystery:1,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.442,warpscale:7.315,zoomexp:1.50374,warp:.08563,wave_y:.04,ob_size:0,ob_g:1,ob_a:1,ib_size:0,ib_r:1,ib_g:0,ib_b:.75,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:3,additive:1,num_inst:400,rad:.16283,tex_zoom:.73458,g:1,b:1,a:.5,g2:0,border_a:0},init_eqs_str:\"a.bending=0;a.ppo=0;a.index=0;a.i3=0;a.dir=0;a.i4=0;a.size=0;a.q2=0;a.q32=0;a.sample=0;a.i3=0;a.i4=0;\",frame_eqs_str:\"a.i3=.00001<Math.abs(equal(a.instance,0))?0:a.i3;a.i4=.00001<Math.abs(equal(a.instance,0))?0:a.i4;a.ppo=8;a.index=a.i4*a.q32;a.sample=mod(a.i3,a.ppo);a.size=40*a.gmegabuf[Math.floor(a.index+4)];a.x=a.gmegabuf[Math.floor(a.index)];a.y=a.gmegabuf[Math.floor(a.index+1)];a.ang=a.gmegabuf[Math.floor(a.index+9)];a.rad=.05*a.size;a.r=a.gmegabuf[Math.floor(a.index+5)];a.g=a.gmegabuf[Math.floor(a.index+6)];a.b=a.gmegabuf[Math.floor(a.index+7)];a.sample=div(a.sample,a.ppo);a.bending=\\n5*a.gmegabuf[Math.floor(a.index+12)]+5*a.gmegabuf[Math.floor(a.index+10)];a.dir=-a.ang+(a.sample-.4)*a.bending;a.ang=1.5*Math.asin(1)-a.dir+.05*a.bending;a.x+=.06*(a.sample-.3)*Math.cos(a.dir)*a.size+Math.sin(a.dir)*a.size*a.bending*.01;a.y+=.06*(a.sample-.3)*Math.sin(a.dir)*a.size-Math.cos(a.dir)*a.size*a.bending*.01;a.x=.5+div(a.x-.5,a.q2);a.rad=1.5*a.rad-.05*a.sample*a.size;a.i3+=1;a.i4=.00001<Math.abs(equal(mod(a.i3,a.ppo),0))?a.i4+1:a.i4;\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:1,samples:65,spectrum:1,usedots:1,thick:1,additive:1,scaling:.33408,smoothing:0,a:0},init_eqs_str:\"a.d=0;a.q32=0;a.t8=0;a.t1=0;a.t2=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.t8=1;a.t1=.5;a.t2=.9;\",point_eqs_str:\"a.d=0;a.y=.2+a.value1+a.value2;a.x=.9-.8*a.sample;a.gmegabuf[Math.floor((64*a.sample-1)*a.q32+14)]=a.value1+a.value2;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.fric=0;a.d=0;a.nliststart=0;a.w=0;a.random=0;a.index2=0;a.index=0;a.w2=0;a.rotatefactor=0;a.ref_ang=0;a.smaller=0;a.dt=0;a.q1=0;a.j=0;a.v=0;a.count=0;a.shock=0;a.nn=0;a.vrr=0;a.check=0;a.gravity=0;a.vr2=0;a.direction=0;a.bouncefactor=0;a.smallestfind=0;a.distance=0;a.bounce=0;a.vr=0;a.vv1=0;a.vv2=0;a.vrr2=0;a.w1=0;a.attributes=0;a.i=0;a.m2=0;a.hit=0;a.q2=0;a.m1=0;a.h=0;a.v1=0;a.acceleration=0;a.findindex=0;a.friction=0;a.pi2=0;a.sample=0;a.v2=0;a.dampening=0;for(var b=a.i=\\n0;1048576>b;b++)a.gmegabuf[Math.floor(a.i)]=0,a.i+=1;a.count=50;a.attributes=32;a.nliststart=24;a.minradius=.004;a.maxradius=.04;a.v=0;for(b=a.index=0;b<a.count;b++)a.gmegabuf[Math.floor(a.index*a.attributes)]=div(randint(1E3),1E3),a.gmegabuf[Math.floor(a.index*a.attributes+1)]=div(randint(1E3),1E3),a.gmegabuf[Math.floor(a.index*a.attributes+2)]=a.v*(div(randint(1E3),1E3)-.5),a.gmegabuf[Math.floor(a.index*a.attributes+3)]=a.v*(div(randint(1E3),1E3)-.5),a.gmegabuf[Math.floor(a.index*a.attributes+4)]=\\na.minradius+div((a.maxradius-a.minradius)*(a.index+1),a.count),a.gmegabuf[Math.floor(a.index*a.attributes+5)]=0,a.gmegabuf[Math.floor(a.index*a.attributes+6)]=1,a.gmegabuf[Math.floor(a.index*a.attributes+7)]=1,a.gmegabuf[Math.floor(a.index*a.attributes+8)]=pow(a.gmegabuf[Math.floor(a.index*a.attributes+4)],3),a.gmegabuf[Math.floor(a.index*a.attributes+9)]=div(4*Math.asin(1)*randint(1E3),1E3),a.gmegabuf[Math.floor(a.index*a.attributes+10)]=0,a.gmegabuf[Math.floor(a.index*a.attributes+13)]=div(a.index,\\na.count-1),a.gmegabuf[Math.floor(a.index*a.attributes+14)]=0,a.index+=1;a.q30=a.nliststart;a.q31=a.count;a.q32=a.attributes;\",frame_eqs_str:\"a.dt=div(1,a.fps);a.warp=0;a.zoom=1;a.wave_a=0;a.gravity=0*a.dt;a.dampening=0;a.friction=2048*a.dt;a.shock=.002;a.pi2=Math.asin(1);a.nn=3;a.check=2;a.bouncefactor=.1;a.rotatefactor=0;a.h=.5*(a.aspecty-1);a.w=.5*(a.aspectx-1);a.index=0;for(var c=a.index2=0;c<a.count;c++){a.random=div(randint(1E3),1E3);a.sample=a.gmegabuf[Math.floor(a.index+13)];a.gmegabuf[Math.floor(a.index+11)]=.92*a.gmegabuf[Math.floor(a.index+11)]-4*a.gmegabuf[Math.floor(a.index+12)]*a.dt+2*(a.random-.5)*\\na.dt*a.gmegabuf[Math.floor(a.index+14)];a.gmegabuf[Math.floor(a.index+12)]+=60*a.gmegabuf[Math.floor(a.index+11)]*a.dt;a.v=sqrt(sqr(a.gmegabuf[Math.floor(a.index+2)])+sqr(a.gmegabuf[Math.floor(a.index+3)]));a.fric=Math.max(0,1-sqr(a.v*a.friction)-2*a.v);a.gmegabuf[Math.floor(a.index+2)]*=a.fric;a.gmegabuf[Math.floor(a.index+3)]*=a.fric;a.gmegabuf[Math.floor(a.index+10)]=a.gmegabuf[Math.floor(a.index+10)]*a.fric+a.v*a.gmegabuf[Math.floor(a.index+12)]*0;a.acceleration=0*a.random+.003*Math.abs(a.gmegabuf[Math.floor(a.index+\\n11)]);a.direction=a.gmegabuf[Math.floor(a.index+9)]-a.pi2;a.gmegabuf[Math.floor(a.index+2)]+=Math.sin(a.direction)*a.acceleration;a.gmegabuf[Math.floor(a.index+3)]+=Math.cos(a.direction)*a.acceleration;a.gmegabuf[Math.floor(a.index)]+=60*a.gmegabuf[Math.floor(a.index+2)]*a.dt;a.gmegabuf[Math.floor(a.index+1)]+=60*a.gmegabuf[Math.floor(a.index+3)]*a.dt;a.gmegabuf[Math.floor(a.index+9)]+=.5*a.gmegabuf[Math.floor(a.index+10)];a.gmegabuf[Math.floor(a.index+3)]-=a.gravity;a.vr=Math.sin(a.gmegabuf[Math.floor(a.index+\\n10)])*a.gmegabuf[Math.floor(a.index+4)];a.bounce=above(a.gmegabuf[Math.floor(a.index+1)],1-a.gmegabuf[Math.floor(a.index+4)]+a.w);a.gmegabuf[Math.floor(a.index+2)]=.00001<Math.abs(a.bounce)?a.gmegabuf[Math.floor(a.index+2)]+(a.vr+a.gmegabuf[Math.floor(a.index+2)])*a.rotatefactor:a.gmegabuf[Math.floor(a.index+2)];a.gmegabuf[Math.floor(a.index+3)]=.00001<Math.abs(a.bounce)?-Math.abs(a.gmegabuf[Math.floor(a.index+3)])*a.dampening-a.shock:a.gmegabuf[Math.floor(a.index+3)];a.vr=.00001<Math.abs(a.bounce)?\\na.vr-(a.gmegabuf[Math.floor(a.index+2)]+a.vr)*(1-a.rotatefactor):a.vr;a.bounce=below(a.gmegabuf[Math.floor(a.index+1)],a.gmegabuf[Math.floor(a.index+4)]-a.w);a.gmegabuf[Math.floor(a.index+2)]=.00001<Math.abs(a.bounce)?a.gmegabuf[Math.floor(a.index+2)]+(a.vr-a.gmegabuf[Math.floor(a.index+2)])*a.rotatefactor:a.gmegabuf[Math.floor(a.index+2)];a.gmegabuf[Math.floor(a.index+3)]=.00001<Math.abs(a.bounce)?Math.abs(a.gmegabuf[Math.floor(a.index+3)])*a.dampening+a.shock:a.gmegabuf[Math.floor(a.index+3)];a.vr=\\n.00001<Math.abs(a.bounce)?a.vr+(a.gmegabuf[Math.floor(a.index+2)]-a.vr)*(1-a.rotatefactor):a.vr;a.bounce=above(a.gmegabuf[Math.floor(a.index)],1-a.gmegabuf[Math.floor(a.index+4)]+a.h);a.gmegabuf[Math.floor(a.index+2)]=.00001<Math.abs(a.bounce)?-Math.abs(a.gmegabuf[Math.floor(a.index+2)])*a.dampening-a.shock:a.gmegabuf[Math.floor(a.index+2)];a.gmegabuf[Math.floor(a.index+3)]=.00001<Math.abs(a.bounce)?a.gmegabuf[Math.floor(a.index+3)]+(a.vr-a.gmegabuf[Math.floor(a.index+3)])*a.rotatefactor:a.gmegabuf[Math.floor(a.index+\\n3)];a.vr=.00001<Math.abs(a.bounce)?a.vr+(a.gmegabuf[Math.floor(a.index+3)]-a.vr)*(1-a.rotatefactor):a.vr;a.bounce=below(a.gmegabuf[Math.floor(a.index)],a.gmegabuf[Math.floor(a.index+4)]-a.h);a.gmegabuf[Math.floor(a.index+2)]=.00001<Math.abs(a.bounce)?Math.abs(a.gmegabuf[Math.floor(a.index+2)])*a.dampening+a.shock:a.gmegabuf[Math.floor(a.index+2)];a.gmegabuf[Math.floor(a.index+3)]=.00001<Math.abs(a.bounce)?a.gmegabuf[Math.floor(a.index+3)]-(a.vr+a.gmegabuf[Math.floor(a.index+3)])*a.rotatefactor:a.gmegabuf[Math.floor(a.index+\\n3)];a.vr=.00001<Math.abs(a.bounce)?a.vr-(a.gmegabuf[Math.floor(a.index+3)]+a.vr)*(1-a.rotatefactor):a.vr;a.gmegabuf[Math.floor(a.index+10)]=Math.asin(div(a.vr,a.gmegabuf[Math.floor(a.index+4)]));a.i=0;for(var b=a.j=0;b<a.count;b++)a.d=sqrt(sqr(a.gmegabuf[Math.floor(a.index)]-a.gmegabuf[Math.floor(a.i)])+sqr(a.gmegabuf[Math.floor(a.index+1)]-a.gmegabuf[Math.floor(a.i+1)])),a.d=.00001<Math.abs(equal(a.d,0))?10:a.d,a.d-=.5*(a.gmegabuf[Math.floor(a.index+4)]+a.gmegabuf[Math.floor(a.i+4)]),a.megabuf[Math.floor(a.j)]=\\na.i,a.megabuf[Math.floor(a.j+1)]=a.d,a.j+=2,a.i+=a.attributes;for(b=a.i=0;b<a.nn;b++){a.j=a.i;a.smallestfind=10;a.findindex=-1;for(var d=0;d<a.count-a.j;d++)a.distance=a.megabuf[Math.floor(2*a.j+1)],a.smaller=above(a.smallestfind,a.distance),a.smallestfind=.00001<Math.abs(a.smaller)?a.distance:a.smallestfind,a.findindex=.00001<Math.abs(a.smaller)?2*a.j:a.findindex,a.j+=1;a.j=a.megabuf[Math.floor(2*a.i)];a.d=a.megabuf[Math.floor(2*a.i+1)];a.megabuf[Math.floor(2*a.i)]=a.megabuf[Math.floor(a.findindex)];\\na.megabuf[Math.floor(2*a.i+1)]=a.megabuf[Math.floor(a.findindex+1)];a.megabuf[Math.floor(a.findindex)]=a.j;a.megabuf[Math.floor(a.findindex+1)]=a.d;a.i+=1}for(b=a.i=0;b<a.nn;b++)a.gmegabuf[Math.floor(a.index+a.nliststart+a.i)]=a.megabuf[Math.floor(2*a.i)],a.i+=1;for(b=a.i=0;b<a.check;b++)a.index2=a.megabuf[Math.floor(a.i)],a.hit=below(sqrt(sqr(a.gmegabuf[Math.floor(a.index)]-a.gmegabuf[Math.floor(a.index2)])+sqr(a.gmegabuf[Math.floor(a.index+1)]-a.gmegabuf[Math.floor(a.index2+1)])),a.gmegabuf[Math.floor(a.index+\\n4)]+a.gmegabuf[Math.floor(a.index2+4)])*above(sqrt(sqr(a.gmegabuf[Math.floor(a.index)]-a.gmegabuf[Math.floor(a.index2)])+sqr(a.gmegabuf[Math.floor(a.index+1)]-a.gmegabuf[Math.floor(a.index2+1)])),sqrt(sqr(a.gmegabuf[Math.floor(a.index+0)]-a.gmegabuf[Math.floor(a.index2+0)]+a.gmegabuf[Math.floor(a.index+2)]-a.gmegabuf[Math.floor(a.index2+2)])+sqr(a.gmegabuf[Math.floor(a.index+1)]-a.gmegabuf[Math.floor(a.index2+1)]+a.gmegabuf[Math.floor(a.index+3)]-a.gmegabuf[Math.floor(a.index2+3)]))),a.ref_ang=Math.atan2(a.gmegabuf[Math.floor(a.index2)]-\\na.gmegabuf[Math.floor(a.index)],a.gmegabuf[Math.floor(a.index2+1)]-a.gmegabuf[Math.floor(a.index+1)])+a.pi2,a.v1=sqrt(sqr(a.gmegabuf[Math.floor(a.index+2)])+sqr(a.gmegabuf[Math.floor(a.index+3)])),a.v2=sqrt(sqr(a.gmegabuf[Math.floor(a.index2+2)])+sqr(a.gmegabuf[Math.floor(a.index2+3)])),a.w1=Math.atan2(a.gmegabuf[Math.floor(a.index+2)],a.gmegabuf[Math.floor(a.index+3)]),a.w2=Math.atan2(a.gmegabuf[Math.floor(a.index2+2)],a.gmegabuf[Math.floor(a.index2+3)]),a.vr2=Math.sin(a.gmegabuf[Math.floor(a.index2+\\n10)])*a.gmegabuf[Math.floor(a.index2+4)],a.m1=a.gmegabuf[Math.floor(a.index+8)],a.m2=a.gmegabuf[Math.floor(a.index2+8)],a.vv1=div((a.m1-a.m2)*a.v1+2*a.m2*a.v2,a.m1+a.m2),a.vv2=div((a.m2-a.m1)*a.v2+2*a.m1*a.v1,a.m1+a.m2),a.vrr=div((a.m1-a.m2)*a.vr+2*a.m2*a.vr2,a.m1+a.m2),a.vrr2=div((a.m2-a.m1)*a.vr2+2*a.m1*a.vr,a.m1+a.m2),a.gmegabuf[Math.floor(a.index+2)]=.00001<Math.abs(a.hit)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.vr2-Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))+Math.cos(a.ref_ang)*\\na.vv1*Math.sin(a.w2-a.ref_ang):a.gmegabuf[Math.floor(a.index+2)],a.gmegabuf[Math.floor(a.index+3)]=.00001<Math.abs(a.hit)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+.1*(a.vr-a.vr2-Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang))-Math.sin(a.ref_ang)*a.vv1*Math.sin(a.w2-a.ref_ang):a.gmegabuf[Math.floor(a.index+3)],a.gmegabuf[Math.floor(a.index2+2)]=.00001<Math.abs(a.hit)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.vr2-a.vr-Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))+Math.cos(a.ref_ang)*\\na.vv2*Math.sin(a.w1-a.ref_ang):a.gmegabuf[Math.floor(a.index2+2)],a.gmegabuf[Math.floor(a.index2+3)]=.00001<Math.abs(a.hit)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+.1*(a.vr2-a.vr-Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang))-Math.sin(a.ref_ang)*a.vv2*Math.sin(a.w1-a.ref_ang):a.gmegabuf[Math.floor(a.index2+3)],a.vr=.00001<Math.abs(a.hit)?a.vr+(Math.cos(a.w1-a.ref_ang)*(a.v1-a.v2)-a.vr):a.vr,a.gmegabuf[Math.floor(a.index+10)]=Math.asin(div(a.vr,a.gmegabuf[Math.floor(a.index+4)])),a.vr2=\\n.00001<Math.abs(a.hit)?a.vr2+(Math.cos(a.w2-a.ref_ang)*(a.v2-a.v1)-a.vr2):a.vr2,a.gmegabuf[Math.floor(a.index2+10)]=Math.asin(div(a.vr2,a.gmegabuf[Math.floor(a.index2+4)])),a.i+=2;a.index+=a.attributes}a.q1=a.aspectx;a.q2=a.aspecty;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1.z = (texture (sampler_main, uv).z * 0.5);\\n  vec2 tmpvar_2;\\n  tmpvar_2 = ((uv_orig * texsize.xy) * texsize_noise_lq.zw);\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 4.0);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  tmpvar_4.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  ret_1.y = texture (sampler_fw_main, clamp ((uv_orig + (\\n    (tmpvar_4 * texsize.zw)\\n   * 4.0)), 0.0, 1.0)).y;\\n  ret_1.y = (ret_1.y + ((\\n    (ret_1 - ((texture (sampler_blur1, uv_orig).xyz * scale1) + bias1))\\n  .y * 0.025) + -0.014));\\n  ret_1.y = (ret_1.y + ((texture (sampler_noise_lq, tmpvar_2).y - 0.5) * 0.02));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(1.0, 0.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  tmpvar_5.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv_orig + (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_orig - (vec2(0.0, 1.0) * tmpvar_3))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  ret_1.x = ((texture (sampler_main, (uv - \\n    ((tmpvar_5 * texsize.zw) * 4.0)\\n  )).x - (ret_1.y * 0.01)) + 0.004);\\n  ret_1.x = (ret_1.x + ((\\n    (texture (sampler_noise_lq, tmpvar_2).x - 0.5)\\n   * 0.01) + (ret_1.z * 0.14)));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_1;\\n  ret = tmpvar_6.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 4.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1) + bias1)\\n  )) * 0.5).y;\\n  tmpvar_3.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1) + bias1)\\n  )) * 0.5).y;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv - ((tmpvar_3 * texsize.zw) * 128.0));\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_main, uv);\\n  ret_1 = (((\\n    ((texture (sampler_blur2, tmpvar_4).xyz * scale2) + bias2)\\n  .x * \\n    clamp ((1.0 - tmpvar_5.y), 0.0, 1.0)\\n  ) * pow (hue_shader.yxz, vec3(8.0, 8.0, 8.0))) * 3.0);\\n  ret_1 = (mix (mix (ret_1, \\n    (pow (hue_shader.yzx, vec3(8.0, 8.0, 8.0)) * 1.4)\\n  , vec3(\\n    ((texture (sampler_main, tmpvar_4).x * 0.8) + ((texture (sampler_blur1, tmpvar_4).xyz * scale1) + bias1).x)\\n  )), vec3(1.0, 1.0, 1.0), (\\n    (pow (hue_shader, vec3(8.0, 8.0, 8.0)) * texture (sampler_main, clamp (uv, 0.0, 1.0)).y)\\n   * 1.2)) * clamp ((1.0 - tmpvar_5.z), 0.0, 1.0));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_1;\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.995,echo_zoom:1.007,echo_orient:3,wave_thick:1,modwavealphabyvolume:1,wave_a:.9,wave_scale:2.997,wave_smoothing:0,wave_mystery:-.5,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.274,warpscale:7.98,zoom:.99951,warp:.20929,wave_r:.02,wave_g:.02,wave_b:0,ob_size:.5,ob_r:1,ob_g:.12,ob_b:1,ob_a:.37,ib_size:0,ib_a:1,mv_x:0,mv_y:0,mv_l:5,mv_a:0,b1ed:.2},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.w=0;a.h3=0;a.q12=0;a.q6=0;a.bt=0;a.q1=0;a.q5=0;a.startx=0;a.v=0;a.mm=0;a.h2=0;a.tt=0;a.bm=0;a.q11=0;a.q10=0;a.q4=0;a.a=0;a.mt=0;a.b=0;a.mx=0;a.mn=0;a.bb=0;a.q2=0;a.starty=0;a.h1=0;a.q3=0;a.q7=0;a.x1=0;a.y1=.001;a.z1=0;\",frame_eqs_str:\"a.zoom=1;a.wave_a=0;a.startx=.3;a.starty=.3;a.a=.55;a.b=.05;a.d=.09;a.q1=a.aspectx;a.q2=a.aspecty;a.q5=a.a;a.q6=a.b;a.q7=a.d;a.bb=.99*a.bb+.02*a.bass;a.mm=.99*a.mm+.02*a.mid;a.tt=.99*a.tt+.02*a.treb;a.mx=Math.max(Math.max(a.bb,a.mm),a.tt);a.mn=Math.min(Math.min(a.bb,a.mm),a.tt);a.h1=div(a.bb-a.mn,a.mx-a.mn);a.h2=div(a.mm-a.mn,a.mx-a.mn);a.h3=div(a.tt-a.mn,a.mx-a.mn);a.v=div(.1333,a.fps);a.bm+=(a.h1-a.h2)*a.v;a.mt+=(a.h2-a.h3)*a.v;a.bt+=(a.h1-a.h3)*a.v;a.w=2*a.bm;a.q3=Math.sin(a.w);\\na.q4=Math.cos(a.w);a.q10=a.bm;a.q11=a.mt;a.q12=a.bt;\",pixel_eqs_str:\"a.x=.5+(a.x-.51)*a.q1;a.y=.5-(a.y-.5)*a.q2;a.dx=a.x*(1-a.x)-div(a.q5*a.x*a.y,a.x+a.q6);a.dy=-a.q7*a.y*(1-div(a.y,a.x));a.dx=div(.02*-a.dx,a.q1);a.dy=div(.02*-a.dy,a.q2);\",warp:\" shader_body { \\n  vec2 my_uv2_1;\\n  vec2 dz_2;\\n  vec3 ret_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (texsize.zw * 4.0);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = ((2.0 * (\\n    (texture (sampler_blur1, (uv + (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (uv - (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)));\\n  vec3 tmpvar_6;\\n  tmpvar_6 = ((2.0 * (\\n    (texture (sampler_blur1, (uv + (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (uv - (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_5.x;\\n  tmpvar_7.y = tmpvar_6.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (tmpvar_7 * texsize.zw);\\n  ret_3.x = (texture (sampler_fw_main, (uv - tmpvar_8)).x - ((\\n    (texture (sampler_blur3, uv).xyz * scale3)\\n   + bias3).x - (\\n    (texture (sampler_blur1, (uv + tmpvar_8)).xyz * scale1)\\n   + bias1).x));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_5.y;\\n  tmpvar_9.y = tmpvar_6.y;\\n  dz_2 = (-(tmpvar_9) * texsize.zw);\\n  ret_3.y = ((texture (sampler_fw_main, (uv - dz_2)).y - 0.06) - ((\\n    ((texture (sampler_blur2, uv).xyz * scale2) + bias2)\\n  .y - \\n    ((texture (sampler_blur1, (uv + dz_2)).xyz * scale1) + bias1)\\n  .y) * 1.3));\\n  vec2 tmpvar_10;\\n  tmpvar_10 = ((uv_orig - 0.5) * (1.8 - (\\n    (bass_att - treb_att)\\n   * 0.015)));\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = ((tmpvar_10.x * tmpvar_10.x) - (tmpvar_10.y * tmpvar_10.y));\\n  tmpvar_11.y = ((2.0 * tmpvar_10.x) * tmpvar_10.y);\\n  my_uv2_1 = (tmpvar_11 + vec2(0.28, 0.4));\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = ((2.0 * (\\n    (texture (sampler_blur1, (my_uv2_1 + (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (my_uv2_1 - (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale1)\\n   + bias1))).z;\\n  tmpvar_12.y = ((2.0 * (\\n    (texture (sampler_blur1, (my_uv2_1 + (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (my_uv2_1 - (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale1)\\n   + bias1))).z;\\n  dz_2 = (tmpvar_12 * texsize.zw);\\n  ret_3.z = (texture (sampler_main, clamp ((my_uv2_1 + dz_2), 0.0, 1.0)).z - 0.014);\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 1.0;\\n  tmpvar_13.xyz = ret_3;\\n  ret = tmpvar_13.xyz;\\n }\",comp:\" shader_body { \\n  vec3 dy_1;\\n  vec3 dx_2;\\n  vec2 mirror_uv_3;\\n  vec3 ret_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = ((uv - 0.5) * aspect.xy);\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = ((q4 * tmpvar_5.x) - (q3 * tmpvar_5.y));\\n  tmpvar_6.y = ((q3 * tmpvar_5.x) + (q4 * tmpvar_5.y));\\n  vec2 tmpvar_7;\\n  tmpvar_7 = (0.5 - (tmpvar_6 * 2.0));\\n  vec2 numerator_8;\\n  numerator_8 = (tmpvar_7 - vec2(0.0, 0.5));\\n  vec2 denominator_9;\\n  denominator_9 = (tmpvar_7 - vec2(1.0, 0.5));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = ((numerator_8.x * denominator_9.x) + (numerator_8.y * denominator_9.y));\\n  tmpvar_10.y = ((numerator_8.y * denominator_9.x) - (numerator_8.x * denominator_9.y));\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (((tmpvar_10 / \\n    ((denominator_9.x * denominator_9.x) + (denominator_9.y * denominator_9.y))\\n  ) + 0.5) - vec2(0.5, 0.5));\\n  float tmpvar_12;\\n  tmpvar_12 = sqrt(dot (tmpvar_11, tmpvar_11));\\n  float tmpvar_13;\\n  float tmpvar_14;\\n  tmpvar_14 = (min (abs(\\n    (tmpvar_11.x / tmpvar_11.y)\\n  ), 1.0) / max (abs(\\n    (tmpvar_11.x / tmpvar_11.y)\\n  ), 1.0));\\n  float tmpvar_15;\\n  tmpvar_15 = (tmpvar_14 * tmpvar_14);\\n  tmpvar_15 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_15) + 0.05368138) * tmpvar_15) - 0.1173503)\\n     * tmpvar_15) + 0.1938925) * tmpvar_15) - 0.3326756)\\n   * tmpvar_15) + 0.9999793) * tmpvar_14);\\n  tmpvar_15 = (tmpvar_15 + (float(\\n    (abs((tmpvar_11.x / tmpvar_11.y)) > 1.0)\\n  ) * (\\n    (tmpvar_15 * -2.0)\\n   + 1.570796)));\\n  tmpvar_13 = (tmpvar_15 * sign((tmpvar_11.x / tmpvar_11.y)));\\n  if ((abs(tmpvar_11.y) > (1e-08 * abs(tmpvar_11.x)))) {\\n    if ((tmpvar_11.y < 0.0)) {\\n      if ((tmpvar_11.x >= 0.0)) {\\n        tmpvar_13 += 3.141593;\\n      } else {\\n        tmpvar_13 = (tmpvar_13 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_13 = (sign(tmpvar_11.x) * 1.570796);\\n  };\\n  vec2 tmpvar_16;\\n  tmpvar_16.x = (tmpvar_13 * 0.1591549);\\n  tmpvar_16.y = tmpvar_12;\\n  vec2 tmpvar_17;\\n  tmpvar_17.x = ((tmpvar_16.x * 2.0) + q11);\\n  tmpvar_17.y = ((0.3 * log(tmpvar_12)) + q12);\\n  vec2 tmpvar_18;\\n  tmpvar_18 = (0.5 + (0.5 - abs(\\n    ((fract((tmpvar_17 * 0.5)) * 2.0) - 1.0)\\n  )));\\n  vec2 tmpvar_19;\\n  tmpvar_19 = (texsize.zw * 3.0);\\n  vec3 tmpvar_20;\\n  tmpvar_20 = ((2.0 * (\\n    (texture (sampler_blur1, (tmpvar_18 + (vec2(1.0, 0.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (tmpvar_18 - (vec2(1.0, 0.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)));\\n  vec3 tmpvar_21;\\n  tmpvar_21 = ((2.0 * (\\n    (texture (sampler_blur1, (tmpvar_18 + (vec2(0.0, 1.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (tmpvar_18 - (vec2(0.0, 1.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)));\\n  vec2 tmpvar_22;\\n  tmpvar_22.x = tmpvar_20.x;\\n  tmpvar_22.y = tmpvar_21.x;\\n  mirror_uv_3 = (tmpvar_18 + ((tmpvar_22 * texsize.zw) * 4.0));\\n  ret_4 = ((mix (ret_4, vec3(1.0, 1.0, 1.0), \\n    ((((texture (sampler_blur1, mirror_uv_3).xyz * scale1) + bias1).x * (1.0 - (\\n      (texture (sampler_blur2, mirror_uv_3).xyz * scale2)\\n     + bias2).x)) * (pow (hue_shader, vec3(4.0, 4.0, 4.0)) * 1.4))\\n  ) * texture (sampler_main, mirror_uv_3).xxx) + ((\\n    (1.0 - texture (sampler_main, mirror_uv_3).x)\\n   * \\n    ((texture (sampler_blur1, mirror_uv_3).xyz * scale1) + bias1)\\n  .x) * vec3(3.0, 3.0, 3.0)));\\n  vec2 tmpvar_23;\\n  tmpvar_23.x = tmpvar_20.x;\\n  tmpvar_23.y = tmpvar_21.x;\\n  mirror_uv_3 = (mirror_uv_3 - ((tmpvar_23 * texsize.zw) * 24.0));\\n  dx_2 = ((2.0 * (\\n    (texture (sampler_blur1, (mirror_uv_3 + (vec2(1.0, 0.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (mirror_uv_3 - (vec2(1.0, 0.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)));\\n  dy_1 = ((2.0 * (\\n    (texture (sampler_blur1, (mirror_uv_3 + (vec2(0.0, 1.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)) - (2.0 * (\\n    (texture (sampler_blur1, (mirror_uv_3 - (vec2(0.0, 1.0) * tmpvar_19))).xyz * scale1)\\n   + bias1)));\\n  vec2 tmpvar_24;\\n  tmpvar_24.x = -(dx_2.y);\\n  tmpvar_24.y = dy_1.y;\\n  vec2 tmpvar_25;\\n  tmpvar_25 = (tmpvar_24 * 0.25);\\n  vec3 tmpvar_26;\\n  tmpvar_26 = mix (ret_4, vec3(1.0, 1.0, 1.0), (mix (vec3(1.0, 0.7, 0.2), vec3(0.15, 0.0, 0.5), vec3(\\n    ((((\\n      ((mirror_uv_3.x * 0.8) - mirror_uv_3.y)\\n     + 0.75) + tmpvar_25.x) + tmpvar_25.y) - 0.1)\\n  )) * texture (sampler_main, mirror_uv_3).y));\\n  vec2 tmpvar_27;\\n  vec2 tmpvar_28;\\n  tmpvar_28 = ((0.5 + (\\n    (uv - 0.5)\\n   * aspect.wz)) - vec2(0.5, 0.5));\\n  vec2 tmpvar_29;\\n  tmpvar_29.x = ((q4 * tmpvar_28.x) - (q3 * tmpvar_28.y));\\n  tmpvar_29.y = ((q3 * tmpvar_28.x) + (q4 * tmpvar_28.y));\\n  tmpvar_27 = (vec2(0.5, 0.5) + tmpvar_29);\\n  mirror_uv_3 = tmpvar_27.yx;\\n  vec2 tmpvar_30;\\n  tmpvar_30 = (vec2(1.0, 0.0) * texsize.zw);\\n  dx_2 = ((2.0 * texture (sampler_main, (tmpvar_27.yx + tmpvar_30)).xyz) - (2.0 * texture (sampler_main, (tmpvar_27.yx - tmpvar_30)).xyz));\\n  vec2 tmpvar_31;\\n  tmpvar_31 = (vec2(0.0, 1.0) * texsize.zw);\\n  dy_1 = ((2.0 * texture (sampler_main, (tmpvar_27.yx + tmpvar_31)).xyz) - (2.0 * texture (sampler_main, (tmpvar_27.yx - tmpvar_31)).xyz));\\n  vec2 tmpvar_32;\\n  tmpvar_32.x = dx_2.z;\\n  tmpvar_32.y = dy_1.z;\\n  vec3 tmpvar_33;\\n  tmpvar_33 = mix (tmpvar_26, vec3(0.9, 0.9, 1.0), vec3((1.0 - texture (sampler_main, (tmpvar_27.yx - tmpvar_32)).z)));\\n  ret_4 = tmpvar_33;\\n  vec4 tmpvar_34;\\n  tmpvar_34.w = 1.0;\\n  tmpvar_34.xyz = tmpvar_33;\\n  ret = tmpvar_34.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.995,echo_zoom:1.007,echo_orient:3,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,wave_a:1.413,wave_scale:.418,wave_smoothing:0,wave_mystery:-.66,modwavealphastart:2,modwavealphaend:2,warpanimspeed:.626,warpscale:8.642,zoomexp:7.10084,zoom:.99951,warp:.09014,wave_r:0,wave_g:0,wave_x:.24,wave_y:.44,ob_size:0,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:48,additive:1,rad:.0277,ang:6.03186,tex_ang:6.03186,tex_zoom:.6839,r:0,g:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.q3=0;a.q4=0;a.q5=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.x=a.q3;a.y=a.q4;a.rad=a.q5;a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:1,sides:48,additive:1,rad:.0277,ang:6.03186,tex_ang:6.03186,tex_zoom:.6839,r:0,b:1,g2:0,b2:1,a2:1,border_r:0,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.q6=0;a.q7=0;a.q8=0;a.q2=0;a.q1=0;\",frame_eqs_str:\"a.x=a.q6;a.y=a.q7;a.rad=a.q8;a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,additive:1,scaling:2.0231,smoothing:0,g:0,b:0},init_eqs_str:\"a.d=0;a.tt2=0;a.res=0;a.tt1=0;a.diff=0;a.tt3=0;a.beat=0;a.vol=0;a.m=0;a.monitor=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.vol=8*a.bass+5*a.mid+3*a.treb;a.m=.97*a.m+.08*a.vol;a.monitor=a.vol;a.beat=above(a.vol,a.res)*above(a.vol,a.m)*above(a.vol,16);a.diff=(1-a.beat)*a.diff+a.beat*(a.vol-a.res);a.res=a.beat*(a.vol+.04*a.m)+(1-a.beat)*(a.res-div(60*(.1+.02*a.diff),a.fps));a.res=Math.max(0,a.res);a.a=a.beat;\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.5+a.d*a.sample*(1-a.sample)*2;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.xx=0;a.q12=0;a.w2=0;a.ref_ang=0;a.q18=0;a.x1=0;a.vx3=0;a.q13=0;a.q15=0;a.q6=0;a.q1=0;a.q5=0;a.q9=0;a.d1=0;a.si1=0;a.vx1=0;a.vx4=0;a.x3=0;a.d2=0;a.q11=0;a.q10=0;a.q4=0;a.vy4=0;a.dir=0;a.bounce=0;a.q16=0;a.x4=0;a.w1=0;a.r=0;a.x2=0;a.q17=0;a.vy2=0;a.y2=0;a.vy1=0;a.q2=0;a.m1=0;a.q14=0;a.si2=0;a.v1=0;a.vx2=0;a.q3=0;a.yy=0;a.y4=0;a.q7=0;a.vy3=0;a.v2=0;a.b1=0;a.q8=0;a.x1=.5;a.x2=.51;a.y2=.9;a.y1=.7;a.x3=.8;a.y3=.5;a.x4=.2;a.y4=.5;a.ax1=0;a.ay1=0;a.ax2=0;a.ay2=0;a.ax3=\\n0;a.ay3=0;a.vx1=0;a.vx2=0;\",frame_eqs_str:\"a.zoom=1.002;a.warp=.2;a.wave_a=0;a.r=.04+.008*Math.max(a.bass_att,a.treb_att);a.bounce=below(a.y1,a.r);a.y1+=a.vy1;a.vy1=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy1)+.1*(a.r-a.y1):a.vy1-div(.018,a.fps);a.bounce=below(a.x1,a.r);a.x1+=a.vx1;a.vx1=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx1)+.1*(a.r-a.x1):a.vx1;a.bounce=above(a.x1,1-a.r);a.vx1=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx1)+.04*(1-a.r-a.x1):a.vx1;a.bounce=below(a.y2,a.r);a.y2+=a.vy2;a.vy2=.00001<Math.abs(a.bounce)?\\n.94*Math.abs(a.vy2)+.1*(a.r-a.y2):a.vy2-div(.018,a.fps);a.bounce=below(a.x2,a.r);a.x2+=a.vx2;a.vx2=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx2)+.1*(a.r-a.x2):a.vx2;a.bounce=above(a.x2,1-a.r);a.vx2=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx2)+.1*(1-a.r-a.x2):a.vx2;a.bounce=below(a.y3,a.r);a.y3+=a.vy3;a.vy3=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy3)+.1*(a.r-a.y3):a.vy3-div(.018,a.fps);a.bounce=below(a.x3,a.r);a.x3+=a.vx3;a.vx3=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx3)+.1*(a.r-a.x3):a.vx3;\\na.bounce=above(a.x3,1-a.r);a.vx3=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx3)+.1*(1-a.r-a.x3):a.vx3;a.bounce=below(a.y4,a.r);a.y4+=a.vy4;a.vy4=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vy4)+.1*(a.r-a.y4):a.vy4-div(.018,a.fps);a.bounce=below(a.x4,a.r);a.x4+=a.vx4;a.vx4=.00001<Math.abs(a.bounce)?.94*Math.abs(a.vx4)+.1*(a.r-a.x4):a.vx4;a.bounce=above(a.x4,1-a.r);a.vx4=.00001<Math.abs(a.bounce)?.94*-Math.abs(a.vx4)+.1*(1-a.r-a.x4):a.vx4;a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x2-a.vx2)+sqr(a.y1+a.vy1-a.y2-\\na.vy2)),2*a.r);a.ref_ang=Math.atan2(a.x2-a.x1,a.y2-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx2,a.vy2);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-\\nMath.asin(1)):a.vy1;a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy2;a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x3-a.vx3)+sqr(a.y1+a.vy1-a.y3-a.vy3)),2*a.r);a.ref_ang=Math.atan2(a.x3-a.x1,a.y3-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*\\na.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx3,a.vy3);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-\\na.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy3;a.bounce=below(sqrt(sqr(a.x2+a.vx2-a.x3-a.vx3)+sqr(a.y2+a.vy2-a.y3-a.vy3)),2*a.r);a.ref_ang=Math.atan2(a.x3-a.x2,a.y3-a.y2)+Math.asin(1);a.v1=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.v2=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.w1=Math.atan2(a.vx2,a.vy2);a.w2=Math.atan2(a.vx3,\\na.vy3);a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy2;a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=\\n.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy3;a.bounce=below(sqrt(sqr(a.x1+a.vx1-a.x4-a.vx4)+sqr(a.y1+a.vy1-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x1,a.y4-a.y1)+Math.asin(1);a.v1=sqrt(a.vx1*a.vx1+a.vy1*a.vy1);a.v2=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx1,a.vy1);a.w2=Math.atan2(a.vx4,a.vy4);a.vx1=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+\\nMath.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx1;a.vy1=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy1;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+\\nMath.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy4;a.bounce=below(sqrt(sqr(a.x2+a.vx2-a.x4-a.vx4)+sqr(a.y2+a.vy2-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x2,a.y4-a.y2)+Math.asin(1);a.v1=sqrt(a.vx2*a.vx2+a.vy2*a.vy2);a.v2=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx2,a.vy2);a.w2=Math.atan2(a.vx4,a.vy4);a.vx2=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx2;a.vy2=.00001<\\nMath.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy2;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy4;a.bounce=below(sqrt(sqr(a.x3+\\na.vx3-a.x4-a.vx4)+sqr(a.y3+a.vy3-a.y4-a.vy4)),2*a.r);a.ref_ang=Math.atan2(a.x4-a.x3,a.y4-a.y3)+Math.asin(1);a.v1=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);a.v2=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.w1=Math.atan2(a.vx3,a.vy3);a.w2=Math.atan2(a.vx4,a.vy4);a.vx3=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vx3;a.vy3=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v1*Math.cos(a.w1-a.ref_ang)+Math.cos(a.ref_ang+\\nMath.asin(1))*a.v2*Math.cos(a.w2-a.ref_ang-Math.asin(1)):a.vy3;a.vx4=.00001<Math.abs(a.bounce)?Math.sin(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.sin(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vx4;a.vy4=.00001<Math.abs(a.bounce)?Math.cos(a.ref_ang)*a.v2*Math.cos(a.w2-a.ref_ang)+Math.cos(a.ref_ang+Math.asin(1))*a.v1*Math.cos(a.w1-a.ref_ang-Math.asin(1)):a.vy4;a.q1=a.aspectx;a.q2=a.aspecty;a.q3=a.x1;a.q4=a.y1;a.q5=2*a.r;a.q6=a.x2;a.q7=a.y2;a.q8=2*a.r;a.q9=a.x3;a.q10=a.y3;\\na.q11=2*a.r;a.q12=a.x4;a.q13=a.y4;a.q14=2*a.r;a.q15=Math.atan2(a.vx4,a.vy4);a.q16=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.q17=Math.atan2(a.vx3,a.vy3);a.q18=sqrt(a.vx3*a.vx3+a.vy3*a.vy3);\",pixel_eqs_str:\"a.x=.5+(a.x-.5)*a.q2;a.y=.5+(a.y-.5)*a.q1;a.dir=-a.q15+Math.asin(1);a.b1=.075;a.m1=25*a.q16;a.xx=a.q12;a.yy=1-a.q13;a.x1=a.xx-Math.sin(a.dir)*a.b1;a.y1=a.yy-Math.cos(a.dir)*a.b1;a.x2=a.xx+Math.sin(a.dir)*a.b1;a.y2=a.yy+Math.cos(a.dir)*a.b1;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.b1;a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.b1;a.si1=sigmoid(-a.d1,1E3);a.si2=sigmoid(-a.d2,1E3);a.dx=3*(a.si1*Math.sin(a.y1-a.y)*a.m1*a.d1-a.si2*Math.sin(a.y2-a.y)*\\na.m1*a.d2)*a.q1;a.dy=3*(-a.si1*Math.sin(a.x1-a.x)*a.m1*a.d1+a.si2*Math.sin(a.x2-a.x)*a.m1*a.d2)*a.q2;a.dir=-a.q17+Math.asin(1);a.m1=25*a.q18;a.xx=a.q9;a.yy=1-a.q10;a.x1=a.xx-Math.sin(a.dir)*a.b1;a.y1=a.yy-Math.cos(a.dir)*a.b1;a.x2=a.xx+Math.sin(a.dir)*a.b1;a.y2=a.yy+Math.cos(a.dir)*a.b1;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.b1;a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.b1;a.si1=sigmoid(-a.d1,1E3);a.si2=sigmoid(-a.d2,1E3);a.dx+=3*(a.si1*Math.sin(a.y1-a.y)*a.m1*\\na.d1-a.si2*Math.sin(a.y2-a.y)*a.m1*a.d2)*a.q1;a.dy+=3*(-a.si1*Math.sin(a.x1-a.x)*a.m1*a.d1+a.si2*Math.sin(a.x2-a.x)*a.m1*a.d2)*a.q2;\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv + ((tmpvar_5 * texsize.zw) * 4.0));\\n  ret_1.z = (((texture (sampler_main, tmpvar_6).z - \\n    ((texture (sampler_main, tmpvar_6).z - ((texture (sampler_blur3, tmpvar_6).xyz * scale3) + bias3).z) * 0.02)\\n  ) - 0.008) + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * texsize_noise_lq.zw) + rand_frame.xy)\\n  ).xyz - 0.5) * 0.1)).x;\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_3.x;\\n  tmpvar_7.y = tmpvar_4.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = ((0.5 + (uv - 0.5)) - (tmpvar_7 * texsize.zw));\\n  ret_1.x = texture (sampler_main, tmpvar_8).x;\\n  ret_1.x = (ret_1.x + ((\\n    (ret_1.x - ((texture (sampler_blur3, tmpvar_8).xyz * scale3) + bias3))\\n  .x * 0.4) + 0.006));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_3.x;\\n  tmpvar_9.y = tmpvar_4.x;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_3.y;\\n  tmpvar_10.y = tmpvar_4.y;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = tmpvar_3.z;\\n  tmpvar_11.y = tmpvar_4.z;\\n  ret_1.y = texture (sampler_fc_main, (((uv - \\n    ((tmpvar_9 * texsize.zw) * 8.0)\\n  ) + (\\n    (tmpvar_10 * texsize.zw)\\n   * 4.0)) + ((tmpvar_11 * texsize.zw) * 8.0))).y;\\n  ret_1.y = (ret_1.y * (1.0 + (ret_1.x * 0.1)));\\n  ret_1.y = (ret_1.y - (0.004 + (\\n    clamp (ret_1.z, 0.0, 1.0)\\n   * 0.04)));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ret_1;\\n  ret = tmpvar_12.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 4.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_3.y;\\n  tmpvar_6.y = tmpvar_4.y;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = ((uv - (tmpvar_5 * 0.1)) + (tmpvar_6 * 0.06));\\n  vec4 tmpvar_8;\\n  tmpvar_8 = texture (sampler_main, uv);\\n  ret_1 = (((\\n    ((texture (sampler_blur2, tmpvar_7).xyz * scale2) + bias2)\\n  .x * \\n    clamp ((1.0 - tmpvar_8.z), 0.0, 1.0)\\n  ) * pow (hue_shader.yxz, vec3(8.0, 8.0, 8.0))) * 3.0);\\n  ret_1 = (mix (ret_1, (\\n    pow (hue_shader.yzx, vec3(8.0, 8.0, 8.0))\\n   * 1.4), vec3((\\n    (texture (sampler_main, tmpvar_7).x * 0.8)\\n   + \\n    ((texture (sampler_blur1, tmpvar_7).xyz * scale1) + bias1)\\n  .x))) * clamp ((1.0 - \\n    (((texture (sampler_blur1, uv).xyz * scale1) + bias1).y * 4.0)\\n  ), 0.0, 1.0));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_3.y;\\n  tmpvar_9.y = tmpvar_4.y;\\n  vec3 tmpvar_10;\\n  vec3 tmpvar_11;\\n  tmpvar_11 = pow (hue_shader, vec3(8.0, 8.0, 8.0));\\n  tmpvar_10 = mix (mix (ret_1, vec3(1.0, 1.0, 1.0), (\\n    (tmpvar_11 * texture (sampler_main, clamp ((uv - (tmpvar_9 * 2.0)), 0.0, 1.0)).z)\\n   * 1.2)), (tmpvar_11.zxy * 1.8), tmpvar_8.yyy);\\n  ret_1 = tmpvar_10;\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = tmpvar_10;\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.5,echo_zoom:1.03,wave_brighten:0,wrap:0,wave_a:.001,wave_scale:.01,wave_smoothing:0,modwavealphastart:1,modwavealphaend:1,warpscale:.107,zoomexp:4.28632,fshader:1,warp:.01743,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ob_g:1,ob_a:1,ib_size:0,ib_r:1,ib_g:1,ib_b:1,ib_a:1,mv_x:64,mv_y:48,mv_l:5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:100,textured:1,rad:.789,ang:.6283,tex_zoom:1.17257,r:0,g:1,border_a:0},init_eqs_str:\"a.an=0;a.vx=0;a.vy=0;\",frame_eqs_str:\"a.rad=.65+.1*a.bass;a.an=.99*a.an+.1*(a.bass-a.treb);a.ang=.1*a.an+.6;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:495,sep:4,spectrum:1,thick:1,additive:1,scaling:100,smoothing:1,r:0,g:.04,b:0,a:.99},init_eqs_str:\"a.my_z=0;a.d=0;a.n=0;a.y3=0;a.z2=0;a.y1=0;a.w=0;a.t5=0;a.w2=0;a.t1=0;a.x1=0;a.q6=0;a.zoom=0;a.p=0;a.q1=0;a.q5=0;a.t8=0;a.z3=0;a.w3=0;a.t3=0;a.my_x=0;a.x3=0;a.t6=0;a.my_y=0;a.pi=0;a.q4=0;a.t7=0;a.rd=0;a.w1=0;a.x2=0;a.t2=0;a.l=0;a.y2=0;a.q2=0;a.z1=0;a.q3=0;a.t4=0;a.t2=0;a.t3=0;a.t4=0;a.ab=1;\",frame_eqs_str:\"a.t1=a.q1;a.t2=a.q2;a.t3=a.q3;a.t4=a.q4;a.t5=a.q5;a.t6=a.q6;a.t8=.07;a.t7=1;\",point_eqs_str:\"a.t7=-a.t7;a.pi=Math.asin(1);a.n=180;a.rd=.075;a.my_x=.5*Math.sin(a.sample*a.pi*4+(a.t7+1)*a.t8)+Math.cos(a.sample*a.pi*a.n)*a.rd*Math.sin(a.sample*a.pi*4+(a.t7+1)*a.t8);a.my_y=.5*Math.cos(a.sample*a.pi*4+(a.t7+1)*a.t8)+Math.cos(a.sample*a.pi*a.n)*a.rd*Math.cos(a.sample*a.pi*4+(a.t7+1)*a.t8);a.my_z=Math.sin(a.sample*a.pi*a.n)*a.rd;a.d=1.4;a.zoom=.65;a.w1=a.q2;a.w2=a.q3;a.w3=a.q4;a.x1=Math.cos(a.w1)*a.my_x+Math.sin(a.w1)*a.my_y;a.y1=-Math.sin(a.w1)*a.my_x+Math.cos(a.w1)*a.my_y;\\na.z1=a.my_z;a.x2=Math.cos(a.w2)*a.x1+Math.sin(a.w2)*a.z1;a.z2=-Math.sin(a.w2)*a.x1+Math.cos(a.w2)*a.z1;a.y2=a.y1;a.y3=Math.cos(a.w3)*a.y2+Math.sin(a.w3)*a.z2;a.z3=-Math.sin(a.w3)*a.y2+Math.cos(a.w3)*a.z2;a.x3=a.x2;a.l=sqrt(a.x3*a.x3+a.y3*a.y3);a.w=Math.atan2(a.x3,a.y3);a.p=Math.tan(Math.asin(1)+Math.atan2(a.d+a.z3,a.l));a.d=sqrt(a.x3*a.x3+a.y3*a.y3+(a.z3+a.d)*(a.z3+a.d));a.my_x=a.zoom*Math.sin(a.w)*a.p;a.my_y=a.zoom*Math.cos(a.w)*a.p;a.x=.5+a.my_x;a.y=.5+a.my_y;a.b=-a.z3+.5;a.b=.5*Math.min(1,Math.max(0,\\na.b));a.r=1-2*a.b;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.n=0;a.n2=0;a.j3=0;a.q1=0;a.q5=0;a.n1=0;a.q9=0;a.v=0;a.q10=0;a.q4=0;a.j2=0;a.k=0;a.j1=0;a.q2=0;a.q3=0;a.x1=0;a.y1=0;\",frame_eqs_str:\"a.q1=0;a.v=.4;a.j1=.95*a.j1+sqr(4*a.bass)*a.v;a.j2=.95*a.j2+sqr(4*a.mid)*a.v;a.j3=.95*a.j3+sqr(4*a.treb)*a.v;a.n+=.0052*a.j1;a.n1+=.0052*a.j2;a.n2+=.0052*a.j3;a.q2=.01*a.n;a.q3=.01*a.n1;a.q4=.01*a.n2;a.k=.99*a.k+sqr(2*a.mid_att);a.q5=0*a.k;a.zoom=1.0016;a.warp=0;a.rot=-0;a.q9=a.aspectx;a.q10=a.aspecty;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 4.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (((texture (sampler_blur2, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale2) + bias2)).z;\\n  tmpvar_3.y = -(((\\n    (texture (sampler_blur2, (uv + (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (uv - (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale2)\\n   + bias2)).z);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv + ((tmpvar_3 * texsize.zw) * 60.0));\\n  vec2 x_5;\\n  x_5 = (tmpvar_4 - uv);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_main, uv);\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_blur1, uv);\\n  ret_1.z = (((texture (sampler_main, tmpvar_4).z + \\n    (((tmpvar_6.z - (\\n      (tmpvar_7.xyz * scale1)\\n     + bias1).z) * 200.0) * sqrt(dot (x_5, x_5)))\\n  ) * 0.96) - 0.02);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1)).y;\\n  tmpvar_8.y = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1)).y;\\n  ret_1.y = ((texture (sampler_main, (uv_orig + \\n    ((tmpvar_8 * texsize.zw) * 6.0)\\n  )).y + (\\n    (tmpvar_6.y - ((tmpvar_7.xyz * scale1) + bias1).y)\\n   * 0.1)) - 0.016);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = ret_1;\\n  ret = tmpvar_9.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.z;\\n  tmpvar_5.y = tmpvar_4.z;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_3.y;\\n  tmpvar_6.y = tmpvar_4.y;\\n  ret_1 = (mix (vec3(0.2, 0.0, 0.1), vec3(0.8, 0.6, 0.0), texture (sampler_main, (uv - \\n    (tmpvar_5 * 0.2)\\n  )).yyy) * ((\\n    (-(tmpvar_3.y) + tmpvar_4.y)\\n   + 1.0) + (\\n    (-(tmpvar_3.z) + tmpvar_4.z)\\n   * 2.0)));\\n  vec3 tmpvar_7;\\n  tmpvar_7 = mix (mix (ret_1, vec3(0.2, 0.0, 0.4), vec3((\\n    ((texture (sampler_blur1, (uv - (tmpvar_6 * 0.04))).xyz * scale1) + bias1)\\n  .x * 1.4))), vec3(1.0, 0.9, 0.8), texture (sampler_main, uv).zzz);\\n  ret_1 = tmpvar_7;\\n  vec4 tmpvar_8;\\n  tmpvar_8.w = 1.0;\\n  tmpvar_8.xyz = tmpvar_7;\\n  ret = tmpvar_8.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:1,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wave_a:2.789,wave_scale:.292,wave_smoothing:0,wave_mystery:.12,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.01,warpscale:100,zoomexp:.92178,zoom:.9901,warp:.01,wave_g:0,ob_size:0,ob_r:.2,ob_a:.1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:100,additive:1,thickoutline:1,x:.43,y:.42,rad:.15799,ang:.1885,tex_zoom:.87865,r:0,g:1,g2:0,border_a:0},init_eqs_str:\"a.q4=0;a.q8=0;\",frame_eqs_str:\"a.x=a.q4;a.y=a.q8;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.xx=0;a.si3=0;a.t1=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.d1=0;a.si1=0;a.vx4=0;a.grav=0;a.x3=0;a.d2=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.m1=0;a.spring=0;a.si2=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.b1=0;a.q8=0;a.x1=.9;a.y1=.5;a.x2=.5;a.y2=.5;a.x3=.5;a.y3=.5;a.x4=.5;a.y4=.5;\",frame_eqs_str:\"a.decay=1;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+a.xx1-a.xx2;a.y1=.5+a.yy1;a.spring=18;a.grav=1;a.resist=.2;a.bounce=.9;a.dt=.0003;a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-a.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*\\na.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*a.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*\\na.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q1=a.x1;a.q2=\\na.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.zoom=1.004;a.q6=Math.atan2(a.vx4,a.vy4);a.q5=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);\",pixel_eqs_str:\"a.dir=-a.q6+Math.asin(1);a.b1=.08;a.m1=45*a.q5;a.t1=.5;a.xx=.5+div(a.q4-.5,a.aspectx);a.yy=1-(.5+div(a.q8-.5,a.aspecty));a.x1=a.xx+Math.cos(a.dir+1.5708)*a.b1;a.y1=a.yy-Math.sin(a.dir+1.5708)*a.b1;a.x2=a.xx-Math.cos(a.dir+1.5708)*a.b1;a.y2=a.yy+Math.sin(a.dir+1.5708)*a.b1;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.b1;a.si1=1-div(1,1+pow(2,100*-a.d1));a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.b1;a.si2=1-div(1,1+pow(2,100*-a.d2));a.si3=0*-pow(a.q5,\\n3);a.dx=div(2*(a.si1*Math.sin(a.y1-a.y)*a.m1*a.d1-a.si2*Math.sin(a.y2-a.y)*a.m1*a.d2+a.si3*Math.cos(a.dir)*a.t1),a.aspectx);a.dy=div(2*(-a.si1*Math.sin(a.x1-a.x)*a.m1*a.d1+a.si2*Math.sin(a.x2-a.x)*a.m1*a.d2-a.si3*Math.sin(a.dir)*a.t1),a.aspecty);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1)).x;\\n  tmpvar_3.y = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1)).x;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv - ((tmpvar_3 * texsize.zw) * 0.5));\\n  ret_1.x = texture (sampler_fw_main, tmpvar_4).x;\\n  ret_1.x = (ret_1.x + ((\\n    (ret_1.x - ((texture (sampler_blur3, tmpvar_4).xyz * scale3) + bias3).x)\\n   * 0.2) - 0.004));\\n  ret_1.y = ((texture (sampler_fw_main, uv_orig).y * 0.98) - 0.004);\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ret_1;\\n  ret = tmpvar_5.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = (texsize.zw * 4.0);\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1)).x;\\n  tmpvar_2.y = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1)).x;\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = mix ((vec3(0.0, 0.0, 1.0) * texture (sampler_main, uv).x), vec3(1.0, 0.0, 0.0), texture (sampler_main, (uv - tmpvar_2)).yyy);\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:1,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,wave_thick:1,wave_brighten:0,wrap:0,wave_a:.004,wave_scale:.01,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.137,warpscale:13.125,zoom:.99951,warp:.99213,wave_y:.04,ob_size:.015,ob_r:.1,ob_g:.25,ob_a:1,ib_size:0,ib_b:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,rad:.02015,tex_ang:.12566,tex_zoom:1.51878,r:0,a:.1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.q12=0;a.x1=0;a.vx3=0;a.q13=0;a.q15=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.q9=0;a.vx4=0;a.x3=0;a.q11=0;a.q10=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.q16=0;a.x4=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.q14=0;a.vx2=0;a.q3=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.q8=0;\",frame_eqs_str:\"a.warp=0;a.wave_a=0;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+1.5*a.yy1;a.dt=div(.03,a.fps);a.vx2=a.vx2*(1-2*a.dt)+10*a.dt*(a.x1+a.x3-2*a.x2);a.vy2=a.vy2*(1-2*a.dt)+a.dt*(10*(a.y1+a.y3-2*a.y2)-.5);a.vx3=a.vx3*(1-2*a.dt)+10*a.dt*(a.x2+a.x4-2*a.x3);a.vy3=a.vy3*(1-2*a.dt)+a.dt*(10*(a.y2+a.y4-2*a.y3)-.5);a.vx4=a.vx4*(1-2*a.dt)+10*a.dt*(a.x3-a.x4);a.vy4=a.vy4*(1-2*a.dt)+a.dt*(10*(a.y3-a.y4)-.5);a.x2+=\\na.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:.5*Math.abs(a.vx2);a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:.5*-Math.abs(a.vx2);a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:.5*Math.abs(a.vx3);a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:.5*-Math.abs(a.vx3);a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:.5*Math.abs(a.vx4);a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:.5*-Math.abs(a.vx4);a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:.5*Math.abs(a.vy2);\\na.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:.5*-Math.abs(a.vy2);a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:.5*Math.abs(a.vy3);a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:.5*-Math.abs(a.vy3);a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:.5*Math.abs(a.vy4);a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:.5*-Math.abs(a.vy4);a.q1=a.x1;a.q2=a.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.q9=div(1,a.aspectx);a.q10=div(1,a.aspecty);a.q11=a.aspectx;a.q12=a.aspecty;a.q13=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);\\na.q14=Math.atan2(a.vx4,a.vy4);a.q15=Math.sin(a.q14);a.q16=Math.cos(a.q14);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 my_uv_2;\\n  vec3 ret_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q4;\\n  tmpvar_4.y = (1.0 - q8);\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = -(q15);\\n  tmpvar_5.y = q16;\\n  vec2 domain_6;\\n  vec2 uv_rot_7;\\n  domain_6 = (uv - tmpvar_4);\\n  domain_6 = (domain_6 * aspect.xy);\\n  float tmpvar_8;\\n  tmpvar_8 = (1.0/((1.0 + exp(\\n    ((sqrt(dot (domain_6, domain_6)) - 0.07) * 50.0)\\n  ))));\\n  domain_6 = (domain_6 + ((tmpvar_5 * q13) * (aspect.wz * tmpvar_8)));\\n  float tmpvar_9;\\n  tmpvar_9 = sin(tmpvar_8);\\n  float tmpvar_10;\\n  tmpvar_10 = cos(tmpvar_8);\\n  uv_rot_7.x = ((tmpvar_10 * domain_6.x) - (tmpvar_9 * domain_6.y));\\n  uv_rot_7.y = ((tmpvar_9 * domain_6.x) + (tmpvar_10 * domain_6.y));\\n  uv_rot_7 = (uv_rot_7 * aspect.zw);\\n  uv_rot_7 = (uv_rot_7 + tmpvar_4);\\n  uv_1 = (clamp ((tmpvar_4 + \\n    ((uv_rot_7 - tmpvar_4) * mix (1.0, 4.0, tmpvar_8))\\n  ), 0.0, 1.0) + (texsize.zw * vec2(0.0, 0.15)));\\n  vec2 tmpvar_11;\\n  tmpvar_11 = mix (uv_orig, uv_1, vec2(0.2, 0.2));\\n  uv_1 = tmpvar_11;\\n  vec2 tmpvar_12;\\n  tmpvar_12 = (vec2(1280.0, 1024.0) * texsize.zw);\\n  float tmpvar_13;\\n  tmpvar_13 = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.005, 0.0))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.005, 0.0))).xyz * scale2)\\n   + bias2)).x * tmpvar_12.x);\\n  float tmpvar_14;\\n  tmpvar_14 = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.0, 0.005))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.0, 0.005))).xyz * scale2)\\n   + bias2)).x * tmpvar_12.y);\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = tmpvar_13;\\n  tmpvar_15.y = tmpvar_14;\\n  vec2 tmpvar_16;\\n  tmpvar_16.x = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.005, 0.0))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.005, 0.0))).xyz * scale2)\\n   + bias2)).x * tmpvar_12.x);\\n  tmpvar_16.y = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.0, 0.005))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.0, 0.005))).xyz * scale2)\\n   + bias2)).x * tmpvar_12.y);\\n  ret_3.x = texture (sampler_fw_main, ((tmpvar_11 - (tmpvar_15 * 0.006)) + (tmpvar_16 * 0.003))).x;\\n  ret_3.x = (ret_3.x + ((ret_3.x - \\n    ((texture (sampler_blur3, tmpvar_11).xyz * scale3) + bias3)\\n  .x) * 0.1));\\n  ret_3.x = (ret_3.x + 0.004);\\n  vec2 tmpvar_17;\\n  tmpvar_17.x = tmpvar_14;\\n  tmpvar_17.y = -(tmpvar_13);\\n  my_uv_2 = (uv_orig + ((tmpvar_17 * 0.05) * (1.2 - \\n    ((texture (sampler_blur3, uv_orig).xyz * scale3) + bias3)\\n  .y)));\\n  ret_3.z = texture (sampler_fw_main, my_uv_2).z;\\n  vec2 x_18;\\n  x_18 = (my_uv_2 - uv_orig);\\n  ret_3.z = (ret_3.z + ((\\n    ((ret_3.z - ((texture (sampler_blur1, uv_orig).xyz * scale1) + bias1).z) * sqrt(dot (x_18, x_18)))\\n   * 180.0) / sqrt(\\n    dot (tmpvar_12, tmpvar_12)\\n  )));\\n  ret_3.z = (ret_3.z * 0.85);\\n  ret_3.z = (ret_3.z + 0.008);\\n  vec2 tmpvar_19;\\n  tmpvar_19.x = -(tmpvar_14);\\n  tmpvar_19.y = tmpvar_13;\\n  my_uv_2 = (tmpvar_19 * 0.045);\\n  vec2 tmpvar_20;\\n  tmpvar_20.x = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2)).y * tmpvar_12.x);\\n  tmpvar_20.y = (((\\n    (texture (sampler_blur2, (tmpvar_11 + vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (tmpvar_11 - vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2)).y * tmpvar_12.y);\\n  my_uv_2 = (my_uv_2 + (tmpvar_11 - (tmpvar_20 * 0.03)));\\n  ret_3.y = texture (sampler_fw_main, my_uv_2).y;\\n  ret_3.y = (ret_3.y + ((\\n    (ret_3.y - ((texture (sampler_blur3, my_uv_2).xyz * scale3) + bias3).y)\\n   * 0.1) + 0.03));\\n  vec4 tmpvar_21;\\n  tmpvar_21.w = 1.0;\\n  tmpvar_21.xyz = ret_3;\\n  ret = tmpvar_21.xyz;\\n }\",comp:\" shader_body { \\n  vec2 dz_1;\\n  vec3 dy_2;\\n  vec3 dx_3;\\n  vec2 d_4;\\n  vec3 ret_5;\\n  vec2 tmpvar_6;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = (vec2(1.0, 0.0) * texsize.zw);\\n  tmpvar_6.x = (texture (sampler_main, (uv + tmpvar_7)).xyz - texture (sampler_main, (uv - tmpvar_7)).xyz).y;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (vec2(0.0, 1.0) * texsize.zw);\\n  tmpvar_6.y = (texture (sampler_main, (uv + tmpvar_8)).xyz - texture (sampler_main, (uv - tmpvar_8)).xyz).y;\\n  d_4 = (texsize.zw * 2.0);\\n  dx_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * d_4))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * d_4))\\n  ).xyz * scale1) + bias1));\\n  dy_2 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * d_4))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * d_4))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = dx_3.y;\\n  tmpvar_9.y = dy_2.y;\\n  dz_1 = ((tmpvar_6 * 3.0) + tmpvar_9);\\n  ret_5 = (vec3(((\\n    pow ((sqrt(dot (dz_1, dz_1)) * 0.8), 0.7)\\n   + \\n    (((texture (sampler_blur2, uv).xyz * scale2) + bias2).y * 0.4)\\n  ) - 0.1)) * vec3(0.3, 0.5, 0.7));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = dx_3.x;\\n  tmpvar_10.y = dy_2.x;\\n  vec3 tmpvar_11;\\n  tmpvar_11 = mix (mix (ret_5, vec3(0.2, 0.1, 0.0), vec3((texture (sampler_main, \\n    (uv + ((tmpvar_10 * texsize.zw) * 18.0))\\n  ).x * 6.0))), vec3(1.0, 1.0, 1.0), texture (sampler_main, uv).zzz);\\n  ret_5 = tmpvar_11;\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = tmpvar_11;\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,wave_thick:1,wave_brighten:0,wave_a:.004,wave_scale:.267,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpscale:16.016,zoomexp:11.56276,zoom:1.05971,warp:.13126,wave_y:.04,ob_size:0,ob_a:1,ib_size:0,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,rad:.01,tex_ang:.12566,tex_zoom:1.51878,g:.99,b:1,a:.1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.v=0;a.t=0;a.q12=0;a.q13=0;a.q11=div(.5,Math.asin(1));\",frame_eqs_str:\"a.zoom=1;a.v=.9*a.v+.04*(a.bass-a.treb);a.t+=.01*a.v;a.q12=.1*a.time+a.t;a.q13=.25+.01*(a.bass_att-a.treb_att);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec2 d_2;\\n  vec3 ret_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (texsize.zw * 4.0);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur1, \\n    fract((uv + (vec2(1.0, 0.0) * tmpvar_4)))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    fract((uv - (vec2(1.0, 0.0) * tmpvar_4)))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (((texture (sampler_blur1, \\n    fract((uv + (vec2(0.0, 1.0) * tmpvar_4)))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    fract((uv - (vec2(0.0, 1.0) * tmpvar_4)))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_7;\\n  tmpvar_7 = ((texture (sampler_blur1, uv).xyz * scale1) + bias1);\\n  d_2 = -(tmpvar_4);\\n  float tmpvar_8;\\n  tmpvar_8 = (d_2 * 4.0).x;\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_5.y;\\n  tmpvar_9.y = tmpvar_6.y;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_5.x;\\n  tmpvar_10.y = tmpvar_6.x;\\n  vec2 tmpvar_11;\\n  tmpvar_11 = ((uv - (tmpvar_9 * d_2)) - (tmpvar_10 * tmpvar_8));\\n  ret_3.y = texture (sampler_fc_main, (tmpvar_11 - floor(tmpvar_11))).y;\\n  ret_3.y = (ret_3.y + ((\\n    (ret_3.y - tmpvar_7.y)\\n   * 0.042) + -0.0075));\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = tmpvar_5.x;\\n  tmpvar_12.y = tmpvar_6.x;\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = tmpvar_5.z;\\n  tmpvar_13.y = tmpvar_6.z;\\n  my_uv_1 = ((uv - (tmpvar_12 * d_2)) - (tmpvar_13 * tmpvar_8));\\n  ret_3.x = texture (sampler_fc_main, (my_uv_1 - floor(my_uv_1))).x;\\n  ret_3.x = (ret_3.x + ((\\n    (ret_3.x - tmpvar_7.x)\\n   * 0.042) + -0.0075));\\n  vec2 tmpvar_14;\\n  tmpvar_14.x = tmpvar_5.z;\\n  tmpvar_14.y = tmpvar_6.z;\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = tmpvar_5.y;\\n  tmpvar_15.y = tmpvar_6.y;\\n  my_uv_1 = ((uv - (tmpvar_14 * d_2)) - (tmpvar_15 * tmpvar_8));\\n  ret_3.z = texture (sampler_fc_main, (my_uv_1 - floor(my_uv_1))).z;\\n  ret_3.z = (ret_3.z + ((\\n    (ret_3.z - tmpvar_7.z)\\n   * 0.042) + -0.0075));\\n  vec4 tmpvar_16;\\n  tmpvar_16.w = 1.0;\\n  tmpvar_16.xyz = ret_3;\\n  ret = tmpvar_16.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  uv_1 = uv;\\n  vec3 ret_2;\\n  float tmpvar_3;\\n  tmpvar_3 = -(q12);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = ((uv - 0.5) * aspect.wz);\\n  float tmpvar_5;\\n  float tmpvar_6;\\n  tmpvar_6 = (min (abs(\\n    (tmpvar_4.x / tmpvar_4.y)\\n  ), 1.0) / max (abs(\\n    (tmpvar_4.x / tmpvar_4.y)\\n  ), 1.0));\\n  float tmpvar_7;\\n  tmpvar_7 = (tmpvar_6 * tmpvar_6);\\n  tmpvar_7 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_7) + 0.05368138) * tmpvar_7) - 0.1173503)\\n     * tmpvar_7) + 0.1938925) * tmpvar_7) - 0.3326756)\\n   * tmpvar_7) + 0.9999793) * tmpvar_6);\\n  tmpvar_7 = (tmpvar_7 + (float(\\n    (abs((tmpvar_4.x / tmpvar_4.y)) > 1.0)\\n  ) * (\\n    (tmpvar_7 * -2.0)\\n   + 1.570796)));\\n  tmpvar_5 = (tmpvar_7 * sign((tmpvar_4.x / tmpvar_4.y)));\\n  if ((abs(tmpvar_4.y) > (1e-08 * abs(tmpvar_4.x)))) {\\n    if ((tmpvar_4.y < 0.0)) {\\n      if ((tmpvar_4.x >= 0.0)) {\\n        tmpvar_5 += 3.141593;\\n      } else {\\n        tmpvar_5 = (tmpvar_5 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_5 = (sign(tmpvar_4.x) * 1.570796);\\n  };\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = ((tmpvar_5 * q11) - tmpvar_3);\\n  tmpvar_8.y = (((q13 * \\n    log(sqrt(dot (tmpvar_4, tmpvar_4)))\\n  ) + (tmpvar_5 * q11)) + tmpvar_3);\\n  uv_1 = (0.5 + (0.5 - abs(\\n    ((fract((tmpvar_8 * 0.5)) * 2.0) - 1.0)\\n  )));\\n  vec4 tmpvar_9;\\n  tmpvar_9 = texture (sampler_main, uv_1);\\n  ret_2 = (vec3(dot (tmpvar_9.xyz, vec3(0.32, 0.49, 0.29))) * mix (vec3(1.0, 1.0, 1.0), vec3(0.2, 0.5, 1.0), tmpvar_9.xxx));\\n  ret_2 = (ret_2 * 2.0);\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = ret_2;\\n  ret = tmpvar_10.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,wave_thick:1,wave_brighten:0,wrap:0,wave_a:.004,wave_scale:.242,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.88,warpscale:9.181,zoomexp:.65309,zoom:.87866,warp:.04914,wave_y:.04,ob_size:.05,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,y:.04,rad:.01,tex_ang:.12566,tex_zoom:1.51878,r:0,a:0,g2:0,b2:.01,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,additive:1,scaling:2.0231,smoothing:0,r:0,b:0},init_eqs_str:\"a.tt3=0;a.tt2=0;a.tt1=0;a.d=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.r=1;a.g=0;a.b=1;\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.6+a.d*a.sample*(1-a.sample)*2;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.c_inv_i=0;a.translation_x=0;a.q12=0;a.a_i=0;a.a_r=0;a.q18=0;a.q13=0;a.scale=0;a.q15=0;a.c_inv_r=0;a.angle=0;a.q11=0;a.bcad_r=0;a.b_r=0;a.q16=0;a.bcad_i=0;a.q17=0;a.q14=0;a.translation_y=0;a.translation_v=0;a.b_i=0;a.translation_u=0;a.x1=.9;a.y1=.5;a.x2=.5;a.y2=.5;a.x3=.5;a.y3=.5;a.x4=.5;a.y4=.5;\",frame_eqs_str:\"a.zoom=1;a.scale=1;a.angle=.1*a.time;a.translation_x=0;a.translation_y=.12;a.a_r=Math.cos(a.angle)*a.scale;a.a_i=Math.sin(a.angle)*a.scale;a.b_r=a.translation_x;a.b_i=a.translation_y;a.scale=1.6;a.angle=0;a.translation_u=0;a.translation_v=0;a.q15=Math.cos(a.angle)*a.scale;a.q16=Math.sin(a.angle)*a.scale;a.q17=a.translation_u;a.q18=a.translation_v;a.c_inv_r=div(a.q15,a.q15*a.q15+a.q16*a.q16);a.c_inv_i=div(a.q16,a.q15*a.q15+a.q16*a.q16);a.q11=a.a_r*a.c_inv_r-a.a_i*a.c_inv_i;a.q12=\\na.a_r*a.c_inv_i-a.a_i*a.c_inv_r;a.bcad_r=a.b_r*a.q15-a.b_i*a.q16-(a.a_r*a.q17-a.a_i*a.q18);a.bcad_i=a.b_r*a.q16-a.b_i*a.q15-(a.a_r*a.q18-a.a_i*a.q17);a.q13=a.bcad_r*a.c_inv_r-a.bcad_i*a.c_inv_i;a.q14=a.bcad_r*a.c_inv_i-a.bcad_i*a.c_inv_r;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  float conway_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (((\\n    ((texture (sampler_blur2, (uv + vec2(0.02, 0.0))).xyz * scale2) + bias2)\\n   - \\n    ((texture (sampler_blur2, (uv - vec2(0.02, 0.0))).xyz * scale2) + bias2)\\n  ).y * 1280.0) * texsize.z);\\n  tmpvar_3.y = (((\\n    ((texture (sampler_blur2, (uv + vec2(0.0, 0.02))).xyz * scale2) + bias2)\\n   - \\n    ((texture (sampler_blur2, (uv - vec2(0.0, 0.02))).xyz * scale2) + bias2)\\n  ).y * 1024.0) * texsize.w);\\n  ret_2.y = texture (sampler_pc_main, (uv - (tmpvar_3 * 0.004))).y;\\n  ret_2.y = (ret_2.y + ((\\n    ((ret_2.y - ((texture (sampler_blur1, uv).xyz * scale1) + bias1).y) - 0.1)\\n   * 0.1) + 0.02));\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (vec2(0.0, 1.0) * texsize.zw);\\n  ret_2.z = (texture (sampler_fc_main, (uv - tmpvar_4)).z - 0.004);\\n  conway_1 = (texture (sampler_pw_main, (uv_orig - texsize.zw)).x + texture (sampler_pw_main, (uv_orig + (vec2(0.0, -1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(1.0, -1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(-1.0, 0.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(1.0, 0.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(-1.0, 1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + tmpvar_4)).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + texsize.zw)).x);\\n  conway_1 = (conway_1 - fract(conway_1));\\n  float tmpvar_5;\\n  tmpvar_5 = clamp (texture (sampler_pc_main, uv_orig).x, 0.0, 1.0);\\n  ret_2.x = (clamp ((1.0 - \\n    abs((conway_1 - 3.0))\\n  ), 0.0, 1.0) * (1.0 - tmpvar_5));\\n  ret_2.x = (ret_2.x + (clamp (\\n    max ((1.0 - abs((conway_1 - 2.0))), (1.0 - abs((conway_1 - 3.0))))\\n  , 0.0, 1.0) * tmpvar_5));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret_2;\\n  ret = tmpvar_6.xyz;\\n }\",comp:\" shader_body { \\n  vec2 moebius_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q11;\\n  tmpvar_3.y = q12;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q17;\\n  tmpvar_4.y = q18;\\n  vec2 tmpvar_5;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - 0.5);\\n  tmpvar_5 = (tmpvar_6 * aspect.xy);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = ((tmpvar_5.x * q15) - (tmpvar_5.y * q16));\\n  tmpvar_7.y = ((tmpvar_5.x * q16) - (tmpvar_5.y * q15));\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (tmpvar_7 + tmpvar_4);\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = ((q13 * tmpvar_8.x) + (q14 * tmpvar_8.y));\\n  tmpvar_9.y = ((q14 * tmpvar_8.x) - (q13 * tmpvar_8.y));\\n  moebius_1 = (((tmpvar_9 / \\n    ((tmpvar_8.x * tmpvar_8.x) + (tmpvar_8.y * tmpvar_8.y))\\n  ) + tmpvar_3) * 0.5);\\n  float tmpvar_10;\\n  tmpvar_10 = sqrt(dot (moebius_1, moebius_1));\\n  moebius_1 = (0.5 + ((\\n    (1.0 - abs(((\\n      fract((moebius_1 * 0.5))\\n     * 2.0) - 1.0)))\\n   - 0.5) * 0.95));\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (0.5 + (tmpvar_6 * 0.2));\\n  ret_2 = (texture (sampler_main, tmpvar_11).z * vec3(0.4, 0.0, 0.7));\\n  ret_2 = (mix (ret_2, vec3(0.0, 1.0, 1.0), vec3(clamp (texture (sampler_fc_main, moebius_1).y, 0.0, 1.0))) * (1.4 - pow (\\n    (tmpvar_10 * 0.8)\\n  , 0.3)));\\n  vec3 tmpvar_12;\\n  tmpvar_12 = mix (mix (mix (ret_2, vec3(4.0, 1.0, 0.0), vec3(\\n    ((clamp ((texture (sampler_fc_main, tmpvar_11).y - texture (sampler_pc_main, tmpvar_11).y), 0.0, 1.0) * 4.0) * (tmpvar_10 * tmpvar_10))\\n  )), vec3(-4.0, -4.0, -4.0), texture (sampler_main, tmpvar_11).xxx), vec3(2.0, 2.0, 2.0), vec3((texture (sampler_pc_main, tmpvar_11).x * 0.75)));\\n  ret_2 = tmpvar_12;\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 1.0;\\n  tmpvar_13.xyz = tmpvar_12;\\n  ret = tmpvar_13.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:1,gammaadj:1.28,decay:.8,echo_zoom:1,echo_orient:3,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,brighten:1,wave_a:.001,wave_scale:1.286,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:.01,warpscale:100,zoomexp:.92178,zoom:.9901,warp:.01,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.005,ob_g:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.y3=0;a.y1=0;a.xx=0;a.s=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.v=0;a.vx4=0;a.grav=0;a.x3=0;a.q11=0;a.q10=0;a.xx2=0;a.q4=0;a.a=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.spring=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.vy3=0;a.xx1=0;a.v2=0;a.q8=0;a.x1=.9;a.y1=.5;a.x2=.5;a.y2=.5;a.x3=.5;a.y3=.5;a.x4=.5;a.y4=.5;\",frame_eqs_str:\"a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=10;a.grav=.5;a.resist=1;a.bounce=.75;a.dt=.0001*div(60,a.fps);a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-\\na.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*\\na.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<\\nMath.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q4=a.x4;a.q8=a.y4;a.q1=a.aspectx;a.q2=a.aspecty;a.q10=a.x1;a.q11=a.y1;a.zoom=1;a.warp=0;a.q6=Math.atan2(a.vx4,a.vy4);a.q5=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.a=.95*a.a+a.q5;a.s=.9*a.s+a.a;a.q3=.1*a.s;a.monitor=a.s;a.wave_a=0;\",pixel_eqs_str:\"a.x=.5+(a.x-.5)*a.q1;a.y=.5+(a.y-.5)*a.q2;a.xx=a.q4;a.yy=1-a.q8;a.dx=0;a.dy=0;a.d=sqrt((a.x-a.xx)*(a.x-a.xx)+(a.y-a.yy)*(a.y-a.yy));a.r=.1;a.v=20;a.v2=a.q5;a.dx=(a.v*(Math.sin(a.y-a.yy)*(a.d-a.r)-(a.x-a.xx)*(a.d-div(a.r,2)))+Math.cos(a.dir)*a.v2)*(1-sigmoid(a.d-a.r,120));a.dy=(-a.v*(Math.sin(a.x-a.xx)*(a.d-a.r)+(a.y-a.yy)*(a.d-div(a.r,2)))-Math.sin(a.dir)*a.v2)*(1-sigmoid(a.d-a.r,120));\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = mix (uv_orig, uv, vec2(2.0, 2.0));\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 2.0);\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (tmpvar_2 + (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (tmpvar_2 - (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur1, \\n    (tmpvar_2 + (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (tmpvar_2 - (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_4.x;\\n  tmpvar_6.y = tmpvar_5.x;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = (tmpvar_2 + ((tmpvar_6 * texsize.zw) * 8.0));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_4.y;\\n  tmpvar_8.y = tmpvar_5.y;\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (tmpvar_2 + ((tmpvar_8 * texsize.zw) * 8.0));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4.z;\\n  tmpvar_10.y = tmpvar_5.z;\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (tmpvar_2 + ((tmpvar_10 * texsize.zw) * 8.0));\\n  ret_1.x = (texture (sampler_main, tmpvar_7).x - ((texture (sampler_main, tmpvar_7).xyz - \\n    ((texture (sampler_blur3, tmpvar_7).xyz * scale3) + bias3)\\n  ).x * 0.02));\\n  ret_1.y = (texture (sampler_main, tmpvar_9).y - ((texture (sampler_main, tmpvar_9).xyz - \\n    ((texture (sampler_blur3, tmpvar_9).xyz * scale3) + bias3)\\n  ).y * 0.02));\\n  ret_1.z = (texture (sampler_main, tmpvar_11).z - ((texture (sampler_main, tmpvar_11).xyz - \\n    ((texture (sampler_blur3, tmpvar_11).xyz * scale3) + bias3)\\n  ).z * 0.02));\\n  ret_1 = (ret_1 + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 1.2)) + rand_frame.xy)\\n  ).xyz - 0.5) * 0.04));\\n  ret_1 = (ret_1 - ((ret_1.yzx * 0.1) - 0.02));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ret_1;\\n  ret = tmpvar_12.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = (texsize.zw * 8.0);\\n  vec3 tmpvar_2;\\n  tmpvar_2 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_1))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q4;\\n  tmpvar_4.y = (1.0 - q8);\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_2.y;\\n  tmpvar_5.y = tmpvar_3.y;\\n  vec2 x_6;\\n  x_6 = ((uv - (tmpvar_5 * 2.0)) - tmpvar_4);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_2.x;\\n  tmpvar_7.y = tmpvar_3.x;\\n  vec2 x_8;\\n  x_8 = ((uv - (tmpvar_7 * 2.0)) - tmpvar_4);\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_2.z;\\n  tmpvar_9.y = tmpvar_3.z;\\n  vec2 x_10;\\n  x_10 = ((uv - (tmpvar_9 * 2.0)) - tmpvar_4);\\n  vec3 tmpvar_11;\\n  tmpvar_11.x = (1.1 - pow (sqrt(\\n    dot (x_8, x_8)\\n  ), 0.2));\\n  tmpvar_11.y = (1.1 - pow (sqrt(\\n    dot (x_6, x_6)\\n  ), 0.2));\\n  tmpvar_11.z = (1.1 - pow (sqrt(\\n    dot (x_10, x_10)\\n  ), 0.2));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ((tmpvar_11 * texture (sampler_main, uv).xyz) * 2.4);\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:1,echo_zoom:1,echo_orient:2,wave_mode:1,wave_thick:1,wave_brighten:0,wrap:0,wave_a:.004,wave_scale:.01,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpanimspeed:1.311,warpscale:8.311,zoomexp:5.20652,warp:.13291,wave_y:.04,ob_size:.005,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:0,mv_y:0,mv_l:1,mv_g:.91,mv_b:.71,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:100,additive:1,thickoutline:1,y:.75,rad:.07493,tex_zoom:.73458,g:1,g2:0,border_a:0},init_eqs_str:\"a.q4=0;a.q8=0;a.vx=0;\",frame_eqs_str:\"a.x=a.q4;a.y=a.q8;\"},{baseVals:{enabled:1,sides:100,additive:1,thickoutline:1,textured:1,x:.7,y:.3,rad:.6623,ang:2.45044,tex_zoom:.74934,g:.1,b:.1,r2:1,g2:.1,b2:.1,a2:1,border_a:0},init_eqs_str:\"a.d=0;a.xx=0;a.q4=0;a.yy=0;a.q8=0;a.aang=0;a.xx=.5;a.yy=.4;\",frame_eqs_str:\"a.d=sqrt(sqr(a.xx-a.q4)+sqr(a.yy-a.q8));a.xx=.00001<Math.abs(below(a.d,.15))?.4+div(randint(200),1E3):a.xx;a.yy=.00001<Math.abs(below(a.d,.15))?.3+div(randint(400),1E3):a.yy;a.aang=.00001<Math.abs(below(a.d,.12))?div(randint(1E3),1E3):a.aang;a.ang=4*a.aang*Math.asin(1);a.x=a.xx;a.y=a.yy;\"},{baseVals:{enabled:1,sides:100,additive:1,thickoutline:1,textured:1,x:.43,y:.6,rad:1.16781,ang:5.96903,tex_zoom:.67165,r2:1,g2:0,a2:1,border_a:0},init_eqs_str:\"a.d=0;a.xx=0;a.q4=0;a.yy=0;a.q8=0;a.aang=0;a.xx=.5;a.yy=.4;\",frame_eqs_str:\"a.d=sqrt(sqr(a.xx-a.q4)+sqr(a.yy-a.q8));a.xx=.00001<Math.abs(below(a.d,.15))?.4+div(randint(200),1E3):a.xx;a.yy=.00001<Math.abs(below(a.d,.15))?.3+div(randint(400),1E3):a.yy;a.aang=.00001<Math.abs(below(a.d,.12))?div(randint(1E3),1E3):a.aang;a.ang=4*a.aang*Math.asin(1);a.x=a.xx;a.y=a.yy;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.spx3=0;a.x1=0;a.vx3=0;a.q6=0;a.spy2=0;a.dt=0;a.spy3=0;a.q1=0;a.q5=0;a.spx2=0;a.vx4=0;a.spx4=0;a.grav=0;a.x3=0;a.ry4=0;a.xx2=0;a.q4=0;a.spy4=0;a.yy1=0;a.vy4=0;a.bounce=0;a.x4=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.spring=0;a.vx2=0;a.q3=0;a.resist=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.q8=0;a.x1=0;a.y1=0;\",frame_eqs_str:\"a.decay=.25;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=50;a.grav=2;a.resist=5;a.bounce=.75;a.dt=div(.009,a.fps);a.spx2=(a.x1+a.x3-2*a.x2)*a.spring;a.spy2=(a.y1+a.y3-2*a.y2)*a.spring;a.spx3=(a.x2+a.x4-2*a.x3)*a.spring;a.spy3=(a.y2+a.y4-2*a.y3)*a.spring;a.spx4=(a.x3-a.x4)*a.spring;a.spy4=(a.y3-a.y4)*a.spring;a.vx2=a.vx2*\\n(1-a.resist*a.dt)+a.dt*a.spx2;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*(a.spy2-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*a.spx3;a.vy3=a.vy3*(1-a.resist*a.dt)+a.dt*(a.spy3-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*a.spx4;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*(a.spy4-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,.1))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,.9))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,\\n.1))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,.9))?a.vx3:-Math.abs(a.vx3)*a.bounce;a.vx4=.00001<Math.abs(above(a.x4,.1))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,.9))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*\\na.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q1=a.x1;a.q2=a.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.monitor=a.ry4;a.zoom=1.0004;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec3 ret_2;\\n  float tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur2, \\n    (uv + vec2(0.005, 0.0))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    (uv - vec2(0.005, 0.0))\\n  ).xyz * scale2) + bias2)).y;\\n  float tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur2, \\n    (uv + vec2(0.0, 0.005))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    (uv - vec2(0.0, 0.005))\\n  ).xyz * scale2) + bias2)).y;\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3;\\n  tmpvar_5.y = tmpvar_4;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - (tmpvar_5 * 0.01));\\n  ret_2.y = texture (sampler_fc_main, (tmpvar_6 - floor(tmpvar_6))).y;\\n  ret_2.y = (ret_2.y + ((ret_2.y - \\n    ((texture (sampler_blur3, (tmpvar_6 - floor(tmpvar_6))).xyz * scale3) + bias3)\\n  .y) * 0.1));\\n  vec2 tmpvar_7;\\n  tmpvar_7 = floor(uv);\\n  ret_2.y = (ret_2.y + (0.006 - (\\n    ((texture (sampler_blur3, (uv - tmpvar_7)).xyz * scale3) + bias3)\\n  .x * 5.0)));\\n  ret_2.y = ret_2.y;\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = -(tmpvar_4);\\n  tmpvar_8.y = tmpvar_3;\\n  my_uv_1 = (tmpvar_8 * 0.05);\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = (((texture (sampler_blur2, \\n    (uv + vec2(0.01, 0.0))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    (uv - vec2(0.01, 0.0))\\n  ).xyz * scale2) + bias2)).z;\\n  tmpvar_9.y = (((texture (sampler_blur2, \\n    (uv + vec2(0.0, 0.01))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    (uv - vec2(0.0, 0.01))\\n  ).xyz * scale2) + bias2)).z;\\n  my_uv_1 = (my_uv_1 + (uv - (tmpvar_9 * 0.005)));\\n  ret_2.z = texture (sampler_fw_main, (my_uv_1 - floor(my_uv_1))).z;\\n  ret_2.z = (ret_2.z + ((ret_2.z - \\n    ((texture (sampler_blur3, (my_uv_1 - floor(my_uv_1))).xyz * scale3) + bias3)\\n  .z) * 0.13));\\n  ret_2.z = (ret_2.z * 0.95);\\n  ret_2.z = (ret_2.z + ((0.03 - \\n    ((texture (sampler_blur3, (uv - tmpvar_7)).xyz * scale3) + bias3)\\n  .x) - (texture (sampler_main, \\n    (my_uv_1 - floor(my_uv_1))\\n  ).y * 0.05)));\\n  ret_2.x = (texture (sampler_main, uv_orig).x - 0.3);\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = ret_2;\\n  ret = tmpvar_10.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 8.0);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_blur1, \\n    (uv + (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(1.0, 0.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv + (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv - (vec2(0.0, 1.0) * tmpvar_2))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.y;\\n  tmpvar_5.y = tmpvar_4.y;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv + (tmpvar_5 * 0.1));\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_main, uv);\\n  ret_1 = (((\\n    ((texture (sampler_blur2, tmpvar_6).xyz * scale2) + bias2)\\n  .x * \\n    clamp ((1.0 - tmpvar_7.z), 0.0, 1.0)\\n  ) * pow (hue_shader.yxz, vec3(8.0, 8.0, 8.0))) * 3.0);\\n  ret_1 = (mix (ret_1, (\\n    pow (hue_shader.yzx, vec3(8.0, 8.0, 8.0))\\n   * 1.4), vec3((\\n    (texture (sampler_main, tmpvar_6).x * 0.8)\\n   + \\n    ((texture (sampler_blur1, tmpvar_6).xyz * scale1) + bias1)\\n  .x))) * clamp ((1.0 - \\n    (((texture (sampler_blur1, uv).xyz * scale1) + bias1).y * 4.0)\\n  ), 0.0, 1.0));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_3.y;\\n  tmpvar_8.y = tmpvar_4.y;\\n  vec3 tmpvar_9;\\n  vec3 tmpvar_10;\\n  tmpvar_10 = pow (hue_shader, vec3(8.0, 8.0, 8.0));\\n  tmpvar_9 = mix (mix (ret_1, vec3(1.0, 1.0, 1.0), (\\n    (tmpvar_10 * texture (sampler_main, clamp ((uv - (tmpvar_8 * 0.04)), 0.0, 1.0)).z)\\n   * 1.2)), (tmpvar_10.zxy * 1.8), tmpvar_7.yyy);\\n  ret_1 = tmpvar_9;\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = tmpvar_9;\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.56,decay:1,echo_zoom:.362,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.599,wave_smoothing:0,wave_mystery:-.5,modwavealphastart:2,modwavealphaend:2,warpscale:.107,zoomexp:.1584,fshader:1,warp:.01,wave_r:.51,wave_g:.5,ob_size:0,ob_a:1,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:.5,mv_r:0,mv_g:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.y3=0;a.y1=0;a.xx=0;a.s=0;a.q12=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.v=0;a.vx4=0;a.mm=0;a.tt=0;a.grav=0;a.x3=0;a.xx2=0;a.q4=0;a.a=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.t=0;a.r=0;a.x2=0;a.mx=0;a.mn=0;a.vy2=0;a.y2=0;a.bb=0;a.q2=0;a.spring=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.vy3=0;a.xx1=0;a.q8=0;a.q11=div(.5,Math.asin(1));\",frame_eqs_str:\"a.ib_r=.3*Math.sin(5*a.time)+.7;a.ib_g=.3*Math.sin(4*a.time)+.3;a.ib_b=.5*Math.sin(4*div(a.time,3))+.5;a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+3*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=25;a.grav=1.1;a.resist=1;a.bounce=.85;a.dt=.0002*div(60,a.fps);a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-\\n2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-a.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<\\nMath.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*a.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?\\na.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<Math.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q4=a.x4;a.q8=a.y4;a.q1=a.aspectx;a.q2=a.aspecty;a.zoom=1;a.warp=0;a.bb=.99*a.bb+.02*a.bass;a.mm=.99*a.mm+.02*a.mid;a.tt=.99*a.tt+.02*a.treb;a.mx=Math.max(Math.max(a.bb,a.mm),a.tt);a.mn=Math.min(Math.min(a.bb,a.mm),a.tt);a.ob_r=div(a.bb-a.mn,a.mx-a.mn);a.ob_b=div(a.mm-a.mn,a.mx-a.mn);a.ob_g=div(a.tt-a.mn,a.mx-a.mn);a.q6=Math.atan2(a.vx4,\\na.vy4);a.q5=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.a=.95*a.a+a.q5;a.s=.9*a.s+a.a;a.q3=.1*a.s;a.t+=div(.1,a.fps);a.t=.00001<Math.abs(above(a.t,2))?a.t-2:a.t;a.q12=-a.t;a.monitor=a.t;a.wave_a=0;\",pixel_eqs_str:\"a.x=.5+(a.x-.5)*a.q1;a.y=.5+(a.y-.5)*a.q2;a.dir=-a.q6+0*Math.asin(1);a.xx=a.q4;a.yy=1-a.q8;a.dx=0;a.dy=0;a.d=sqrt((a.x-a.xx)*(a.x-a.xx)+(a.y-a.yy)*(a.y-a.yy));a.r=.08;a.v=-15*a.q5;a.dx=a.v*Math.sin(a.dir)*(a.r-a.d)*(1-sigmoid(a.d-a.r,200))*a.q2;a.dy=a.v*Math.cos(a.dir)*(a.r-a.d)*(1-sigmoid(a.d-a.r,200))*a.q1;\",warp:\" shader_body { \\n  vec3 tmpvar_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  tmpvar_1 = vec3((((tmpvar_2.x + tmpvar_2.y) + tmpvar_2.z) * 0.33333));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ((texture (sampler_main, clamp (\\n    (uv - ((vec2(0.0, 0.0168) * (tmpvar_1 - 0.35).xy) * (tmpvar_1 - 0.4).xy))\\n  , 0.0, 1.0)).xyz - 0.001) + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 2.0)) + rand_frame.xy)\\n  ) - 0.5) * 0.04).xyz);\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = ((uv - 0.5).yx * aspect.zw);\\n  float tmpvar_2;\\n  float tmpvar_3;\\n  tmpvar_3 = (min (abs(\\n    (tmpvar_1.x / tmpvar_1.y)\\n  ), 1.0) / max (abs(\\n    (tmpvar_1.x / tmpvar_1.y)\\n  ), 1.0));\\n  float tmpvar_4;\\n  tmpvar_4 = (tmpvar_3 * tmpvar_3);\\n  tmpvar_4 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_4) + 0.05368138) * tmpvar_4) - 0.1173503)\\n     * tmpvar_4) + 0.1938925) * tmpvar_4) - 0.3326756)\\n   * tmpvar_4) + 0.9999793) * tmpvar_3);\\n  tmpvar_4 = (tmpvar_4 + (float(\\n    (abs((tmpvar_1.x / tmpvar_1.y)) > 1.0)\\n  ) * (\\n    (tmpvar_4 * -2.0)\\n   + 1.570796)));\\n  tmpvar_2 = (tmpvar_4 * sign((tmpvar_1.x / tmpvar_1.y)));\\n  if ((abs(tmpvar_1.y) > (1e-08 * abs(tmpvar_1.x)))) {\\n    if ((tmpvar_1.y < 0.0)) {\\n      if ((tmpvar_1.x >= 0.0)) {\\n        tmpvar_2 += 3.141593;\\n      } else {\\n        tmpvar_2 = (tmpvar_2 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_2 = (sign(tmpvar_1.x) * 1.570796);\\n  };\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (tmpvar_2 * q11);\\n  tmpvar_5.y = (((0.5 * \\n    log(sqrt(dot (tmpvar_1, tmpvar_1)))\\n  ) - (tmpvar_2 * q11)) + q12);\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = pow (texture (sampler_main, (0.5 + (\\n    (0.5 - abs(((\\n      fract((tmpvar_5 * 0.5))\\n     * 2.0) - 1.0)))\\n   * vec2(0.96, 1.0)))).xyz, vec3(0.618034, 0.618034, 0.618034));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,wave_thick:1,wave_brighten:0,wave_a:.004,wave_scale:.01,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.01,warpscale:100,zoomexp:.24298,zoom:.9901,warp:.01,wave_y:.04,ob_size:0,ob_g:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,rad:.01,tex_ang:.12566,tex_zoom:1.51878,r:.05,a:.1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.x1=.9;a.y1=.5;a.x2=.5;a.y2=.5;a.x3=.5;a.y3=.5;a.x4=.5;a.y4=.5;\",frame_eqs_str:\"a.zoom=1;a.warp=0;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (0.02 * aspect.zw);\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur2, \\n    ((uv + (vec2(1.0, 0.0) * tmpvar_3)) - floor((uv + (vec2(1.0, 0.0) * tmpvar_3))))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    ((uv - (vec2(1.0, 0.0) * tmpvar_3)) - floor((uv - (vec2(1.0, 0.0) * tmpvar_3))))\\n  ).xyz * scale2) + bias2));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur2, \\n    ((uv + (vec2(0.0, 1.0) * tmpvar_3)) - floor((uv + (vec2(0.0, 1.0) * tmpvar_3))))\\n  ).xyz * scale2) + bias2) - ((texture (sampler_blur2, \\n    ((uv - (vec2(0.0, 1.0) * tmpvar_3)) - floor((uv - (vec2(0.0, 1.0) * tmpvar_3))))\\n  ).xyz * scale2) + bias2));\\n  vec3 tmpvar_6;\\n  tmpvar_6 = ((texture (sampler_blur1, uv).xyz * scale1) + bias1);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_4.y;\\n  tmpvar_7.y = tmpvar_5.y;\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_5.x;\\n  tmpvar_8.y = -(tmpvar_4.x);\\n  vec2 tmpvar_9;\\n  tmpvar_9 = ((uv - (tmpvar_7 * vec2(0.01, 0.01))) - (tmpvar_8 * -0.02));\\n  ret_2.y = texture (sampler_fc_main, (tmpvar_9 - floor(tmpvar_9))).y;\\n  ret_2.y = (ret_2.y + ((\\n    (ret_2.y - tmpvar_6.y)\\n   * 0.02) + 0.005));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4.x;\\n  tmpvar_10.y = tmpvar_5.x;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = tmpvar_5.z;\\n  tmpvar_11.y = -(tmpvar_4.z);\\n  my_uv_1 = ((uv - (tmpvar_10 * vec2(0.01, 0.01))) - (tmpvar_11 * -0.02));\\n  ret_2.x = texture (sampler_fc_main, (my_uv_1 - floor(my_uv_1))).x;\\n  ret_2.x = (ret_2.x + ((\\n    (ret_2.x - tmpvar_6.x)\\n   * 0.02) + 0.005));\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = tmpvar_4.z;\\n  tmpvar_12.y = tmpvar_5.z;\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = tmpvar_5.y;\\n  tmpvar_13.y = -(tmpvar_4.y);\\n  my_uv_1 = ((uv - (tmpvar_12 * vec2(0.01, 0.01))) - (tmpvar_13 * -0.02));\\n  ret_2.z = texture (sampler_fc_main, (my_uv_1 - floor(my_uv_1))).z;\\n  ret_2.z = (ret_2.z + ((\\n    (ret_2.z - tmpvar_6.z)\\n   * 0.02) + 0.005));\\n  vec4 tmpvar_14;\\n  tmpvar_14.w = 1.0;\\n  tmpvar_14.xyz = ret_2;\\n  ret = tmpvar_14.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv2_1;\\n  vec3 ret_2;\\n  uv2_1 = (uv + (vec2(1.0, 0.0) * texsize.zw));\\n  float tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(-1.0, 0.0) * texsize.zw));\\n  float tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(0.0, 1.0) * texsize.zw));\\n  float tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(0.0, -1.0) * texsize.zw));\\n  vec3 tmpvar_6;\\n  tmpvar_6.z = 0.14;\\n  tmpvar_6.x = (tmpvar_3 - tmpvar_4);\\n  tmpvar_6.y = (tmpvar_5 - ((\\n    (texture (sampler_main, uv2_1).xyz + (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4))\\n   + \\n    (((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2) * 0.15)\\n  ) + (\\n    ((texture (sampler_blur3, uv2_1).xyz * scale3) + bias3)\\n   * 0.1)).x);\\n  ret_2 = (0.5 + (0.5 * normalize(tmpvar_6)));\\n  vec2 x_7;\\n  x_7 = (ret_2.xy - 0.5);\\n  ret_2 = (ret_2 * clamp ((\\n    sqrt(dot (x_7, x_7))\\n   * 5.0), 0.0, 1.0));\\n  ret_2 = ret_2.xxy;\\n  ret_2 = (ret_2 + 1.15);\\n  ret_2 = (ret_2 * mix (ret_2, (ret_2 * \\n    (((texture (sampler_blur3, uv).xyz * scale3) + bias3) - ((texture (sampler_blur1, uv).xyz * scale1) + bias1))\\n  ), pow (hue_shader.zxy, ret_2)));\\n  ret_2 = (ret_2 * ret_2);\\n  vec4 tmpvar_8;\\n  tmpvar_8.w = 1.0;\\n  tmpvar_8.xyz = ret_2;\\n  ret = tmpvar_8.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1,echo_alpha:.5,wave_thick:1,wave_brighten:0,wrap:0,wave_a:.004,wave_scale:.242,wave_smoothing:0,wave_mystery:-.44,modwavealphastart:1,modwavealphaend:1,warpanimspeed:.397,warpscale:15.099,zoomexp:.65309,zoom:.87866,warp:.04027,wave_y:.04,ob_size:0,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,thickoutline:1,y:.04,rad:.01,tex_ang:.12566,tex_zoom:1.51878,r:0,a:0,g2:0,b2:.01,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,additive:1,scaling:2.0231,smoothing:0,r:0,b:0},init_eqs_str:\"a.tt3=0;a.tt2=0;a.tt1=0;a.d=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.r=1;a.g=0;a.b=1;\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.6+a.d*a.sample*(1-a.sample)*2;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.c_inv_i=0;a.translation_x=0;a.q12=0;a.a_i=0;a.a_r=0;a.q18=0;a.q13=0;a.scale=0;a.q15=0;a.c_inv_r=0;a.angle=0;a.q11=0;a.bcad_r=0;a.b_r=0;a.q16=0;a.bcad_i=0;a.q17=0;a.q14=0;a.translation_y=0;a.translation_v=0;a.b_i=0;a.translation_u=0;a.x1=.9;a.y1=.5;a.x2=.5;a.y2=.5;a.x3=.5;a.y3=.5;a.x4=.5;a.y4=.5;\",frame_eqs_str:\"a.zoom=.998;a.scale=1;a.angle=.02*a.time;a.translation_x=0;a.translation_y=.12;a.a_r=Math.cos(a.angle)*a.scale;a.a_i=Math.sin(a.angle)*a.scale;a.b_r=a.translation_x;a.b_i=a.translation_y;a.scale=1;a.angle=0*Math.sin(.1337*a.time);a.translation_u=0;a.translation_v=-.2;a.q15=Math.cos(a.angle)*a.scale;a.q16=Math.sin(a.angle)*a.scale;a.q17=a.translation_u;a.q18=a.translation_v;a.c_inv_r=div(a.q15,a.q15*a.q15+a.q16*a.q16);a.c_inv_i=div(a.q16,a.q15*a.q15+a.q16*a.q16);a.q11=a.a_r*\\na.c_inv_r-a.a_i*a.c_inv_i;a.q12=a.a_r*a.c_inv_i-a.a_i*a.c_inv_r;a.bcad_r=a.b_r*a.q15-a.b_i*a.q16-(a.a_r*a.q17-a.a_i*a.q18);a.bcad_i=a.b_r*a.q16-a.b_i*a.q15-(a.a_r*a.q18-a.a_i*a.q17);a.q13=a.bcad_r*a.c_inv_r-a.bcad_i*a.c_inv_i;a.q14=a.bcad_r*a.c_inv_i-a.bcad_i*a.c_inv_r;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  float conway_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (((\\n    ((texture (sampler_blur2, (uv + vec2(0.02, 0.0))).xyz * scale2) + bias2)\\n   - \\n    ((texture (sampler_blur2, (uv - vec2(0.02, 0.0))).xyz * scale2) + bias2)\\n  ).y * 1280.0) * texsize.z);\\n  tmpvar_3.y = (((\\n    ((texture (sampler_blur2, (uv + vec2(0.0, 0.02))).xyz * scale2) + bias2)\\n   - \\n    ((texture (sampler_blur2, (uv - vec2(0.0, 0.02))).xyz * scale2) + bias2)\\n  ).y * 1024.0) * texsize.w);\\n  ret_2.y = texture (sampler_pc_main, (uv - (tmpvar_3 * 0.004))).y;\\n  ret_2.y = (ret_2.y + ((\\n    ((ret_2.y - ((texture (sampler_blur1, uv).xyz * scale1) + bias1).y) - 0.1)\\n   * 0.1) + 0.02));\\n  ret_2.z = (texture (sampler_fc_main, (0.5 + (\\n    (uv - 0.5)\\n   * 0.992))).z - 0.004);\\n  conway_1 = (texture (sampler_pw_main, (uv_orig - texsize.zw)).x + texture (sampler_pw_main, (uv_orig + (vec2(0.0, -1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(1.0, -1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(-1.0, 0.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(1.0, 0.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(-1.0, 1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + (vec2(0.0, 1.0) * texsize.zw))).x);\\n  conway_1 = (conway_1 + texture (sampler_pw_main, (uv_orig + texsize.zw)).x);\\n  conway_1 = (conway_1 - fract(conway_1));\\n  float tmpvar_4;\\n  tmpvar_4 = clamp (texture (sampler_pc_main, uv_orig).x, 0.0, 1.0);\\n  ret_2.x = (clamp ((1.0 - \\n    abs((conway_1 - 3.0))\\n  ), 0.0, 1.0) * (1.0 - tmpvar_4));\\n  ret_2.x = (ret_2.x + (clamp (\\n    max ((1.0 - abs((conway_1 - 2.0))), (1.0 - abs((conway_1 - 3.0))))\\n  , 0.0, 1.0) * tmpvar_4));\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ret_2;\\n  ret = tmpvar_5.xyz;\\n }\",comp:\" shader_body { \\n  vec2 moebius_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q11;\\n  tmpvar_3.y = q12;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q17;\\n  tmpvar_4.y = q18;\\n  vec2 tmpvar_5;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - 0.5);\\n  tmpvar_5 = (tmpvar_6 * aspect.xy);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = ((tmpvar_5.x * q15) - (tmpvar_5.y * q16));\\n  tmpvar_7.y = ((tmpvar_5.x * q16) - (tmpvar_5.y * q15));\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (tmpvar_7 + tmpvar_4);\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = ((q13 * tmpvar_8.x) + (q14 * tmpvar_8.y));\\n  tmpvar_9.y = ((q14 * tmpvar_8.x) - (q13 * tmpvar_8.y));\\n  moebius_1 = (((tmpvar_9 / \\n    ((tmpvar_8.x * tmpvar_8.x) + (tmpvar_8.y * tmpvar_8.y))\\n  ) + tmpvar_3) * 0.5);\\n  float tmpvar_10;\\n  tmpvar_10 = sqrt(dot (moebius_1, moebius_1));\\n  moebius_1 = (0.5 + ((\\n    (1.0 - abs(((\\n      fract((moebius_1 * 0.5))\\n     * 2.0) - 1.0)))\\n   - 0.5) * 0.99));\\n  vec3 tmpvar_11;\\n  tmpvar_11 = mix (mix (mix (\\n    mix (mix ((mix (ret_2, vec3(0.2, 0.6, 1.0), vec3(\\n      (texture (sampler_pc_main, moebius_1).y * 2.0)\\n    )) * (vec3(1.0, 1.0, 1.0) - vec3(\\n      ((((texture (sampler_blur1, \\n        (0.5 + (tmpvar_6 * 0.5))\\n      ).xyz * scale1) + bias1).y * 2.0) * tmpvar_10)\\n    ))), vec3(1.0, 1.0, 1.0), texture (sampler_pc_main, moebius_1).xxx), vec3(4.0, 1.0, 0.0), vec3(clamp (((texture (sampler_pc_main, \\n      (0.5 + (tmpvar_6 * 0.2))\\n    ).y * 2.0) * (\\n      (tmpvar_10 * tmpvar_10)\\n     * tmpvar_10)), 0.0, 1.0)))\\n  , vec3(0.1, 0.0, 0.0), vec3(\\n    clamp ((((texture (sampler_blur1, \\n      (0.5 + (tmpvar_6 * 0.2))\\n    ).xyz * scale1) + bias1).x * 12.0), 0.0, 1.0)\\n  )), (vec3(0.5, 0.8, 1.0) * texture (sampler_pc_main, uv).z), vec3((\\n    clamp ((((texture (sampler_blur1, \\n      (0.5 + (tmpvar_6 * 0.2))\\n    ).xyz * scale1) + bias1).x * 4.0), 0.0, 1.0)\\n   * 1.4))), vec3(1.0, 1.0, 1.0), texture (sampler_pc_main, (0.5 + (tmpvar_6 * 0.2))).xxx);\\n  ret_2 = tmpvar_11;\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = tmpvar_11;\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.56,decay:1,echo_zoom:.362,echo_orient:1,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.286,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,fshader:1,zoom:1.004,warp:.19788,sx:.99967,sy:.9999,wave_g:.65,wave_b:.65,ob_size:0,ob_a:1,mv_x:64,mv_y:48,mv_l:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1,r:0,g:.3,b:.75},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.8);\"},{baseVals:{enabled:1,thick:1,r:0,b:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.05*a.bass;a.ma-=3.1415*above(a.mid,1)*.05*a.mid;a.mx+=.0001*Math.cos(a.ma);a.my+=.0001*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.1);\"},{baseVals:{enabled:1,thick:1,g:.5,b:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.mid,1)*.01*a.mid;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0004*Math.cos(a.ma);a.my+=.0004*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.3);\"},{baseVals:{enabled:1,thick:1,r:.4,g:0,b:.6},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,.5)*.02*a.bass;a.ma-=3.1415*above(a.treb,.5)*.02*a.treb;a.mx+=.0008*Math.cos(a.ma);a.my+=.0008*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.2);\"}],init_eqs_str:\"a.du=0;a.q1=0;a.mm=0;a.tt=0;a.mult=0;a.ang2=0;a.dv=0;a.mx=0;a.mn=0;a.bb=0;a.q2=0;a.dist=0;\",frame_eqs_str:\"a.wave_r+=.2*(.6*Math.sin(.98*a.time)+.4*Math.sin(1.047*a.time));a.wave_g+=.2*(.6*Math.sin(.835*a.time)+.4*Math.sin(1.081*a.time));a.wave_b+=.2*(.6*Math.sin(.814*a.time)+.4*Math.sin(1.011*a.time));a.q1=2*a.cx-1+.6*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.q2=2*a.cy-1+.6*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.warp=0;a.zoom=1;a.bb=.99*a.bb+.02*a.bass;a.mm=.99*a.mm+.02*a.mid;a.tt=.99*a.tt+.02*a.treb;a.mx=Math.max(Math.max(a.bb,a.mm),a.tt);a.mn=Math.min(Math.min(a.bb,\\na.mm),a.tt);a.ob_r=div(a.bb-a.mn,a.mx-a.mn);a.ob_b=div(a.mm-a.mn,a.mx-a.mn);a.ob_g=div(a.tt-a.mn,a.mx-a.mn);\",pixel_eqs_str:\"a.du=2*a.x-1-a.q1;a.dv=2*a.y-1-a.q2;a.dist=sqrt(a.du*a.du+a.dv*a.dv);a.ang2=Math.atan2(a.du,a.dv)+.15*a.time;a.mult=.05*Math.sin(.05*a.dist);a.dx=a.mult*Math.sin(2*a.ang2-1.5);a.dy=a.mult*Math.cos(2*a.ang2-1.5);\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  tmpvar_1.xyz = ((texture (sampler_main, clamp (\\n    (uv - (((vec2(0.0, 64.0) * texsize.zw) * dot (\\n      (tmpvar_2.xyz - 0.35)\\n    , vec3(0.32, 0.49, 0.29))) * (dot (tmpvar_2.xyz, vec3(0.32, 0.49, 0.29)) - 0.4)))\\n  , 0.0, 1.0)).xyz - 0.0011) + ((texture (sampler_noise_lq, \\n    (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 1.5)) + rand_frame.xy)\\n  ) - 0.5) * 0.0038).xyz);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (texture (sampler_main, (uv - tmpvar_2)).xyz - texture (sampler_main, (uv + tmpvar_2)).xyz).x;\\n  tmpvar_4.y = (texture (sampler_main, (uv - tmpvar_3)).xyz - texture (sampler_main, (uv + tmpvar_3)).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    ((uv - 0.5) * 2.0)\\n  )) - tmpvar_4);\\n  float tmpvar_5;\\n  tmpvar_5 = clamp ((0.04 / sqrt(\\n    dot (uv1_1, uv1_1)\\n  )), 0.0, 1.0);\\n  uv1_1 = ((0.3 * cos(\\n    (uv1_1 * 12.0)\\n  )) - (9.0 * tmpvar_4));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (tmpvar_5 + ((texture (sampler_main, uv).xyz * 12.0) * vec3(clamp (\\n    (0.04 / sqrt(dot (uv1_1, uv1_1)))\\n  , 0.0, 1.0))));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.56,decay:1,echo_zoom:.362,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.599,wave_smoothing:0,wave_mystery:-.5,modwavealphastart:2,modwavealphaend:2,warpscale:.107,zoomexp:.1584,fshader:1,warp:.01,wave_r:.51,wave_g:.5,ob_size:0,ob_a:1,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:.5,mv_r:0,mv_g:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.cx1=0;a.y3=0;a.y1=0;a.cy1=0;a.x1=0;a.x3=0;a.dir=0;a.r=0;a.x2=0;a.y2=0;\",frame_eqs_str:\"a.ib_r=.3*Math.sin(5*a.time)+.7;a.ib_g=.3*Math.sin(4*a.time)+.3;a.ib_b=.5*Math.sin(4*div(a.time,3))+.5;a.wave_r=1-a.ib_r;a.wave_g=1-a.ib_g;a.wave_b=1-a.ib_b;a.wave_x=.5+.3*Math.sin(3*a.time);a.wave_y=.5+.3*Math.cos(2.187*a.time);\",pixel_eqs_str:\"a.r=div(a.bass,4);a.cx1=.5+.2*Math.sin(.618*a.time);a.cy1=.5+.2*Math.cos(1.618*a.time);a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.dir=a.bass*(a.r*a.r-a.d*a.d)*.3;a.x1=.00001<Math.abs(above(a.d,a.r))?0:Math.sin(a.y-a.cy1)*a.dir;a.y1=.00001<Math.abs(above(a.d,a.r))?0:-Math.sin(a.x-a.cx1)*a.dir;a.cx1=.5+.3*Math.sin(2.618*a.time);a.cy1=.5+.3*Math.cos(3.14*a.time);a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.dir=-a.mid*(a.r*a.r-a.d*a.d)*.3;a.x2=.00001<\\nMath.abs(above(a.d,a.r))?0:Math.sin(a.y-a.cy1)*a.dir;a.y2=.00001<Math.abs(above(a.d,a.r))?0:-Math.sin(a.x-a.cx1)*a.dir;a.cx1=.5+.4*Math.sin(2.618*-a.time);a.cy1=.5+.4*Math.cos(1.14*-a.time);a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.dir=-a.treb*(a.r*a.r-a.d*a.d)*.3;a.x3=.00001<Math.abs(above(a.d,a.r))?0:Math.sin(a.y-a.cy1)*a.dir;a.y3=.00001<Math.abs(above(a.d,a.r))?0:-Math.sin(a.x-a.cx1)*a.dir;a.dx=a.x1+a.x2+a.x3;a.dy=a.y1+a.y2+a.y3;\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 2.0)) + rand_frame.xy);\\n  uv_1 = (uv + ((texture (sampler_noise_lq, tmpvar_2).xy - 0.5) * texsize.zw));\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = bass;\\n  tmpvar_3.y = treb;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = (texture (sampler_main, (uv_1 + (\\n    (texture (sampler_main, (mix (uv_1, uv_orig, vec2(-1.0, -1.0)) + texsize.zw)).xy - 0.4)\\n   * \\n    (-0.004 + (0.04 * clamp ((tmpvar_3 - 1.0), 0.0, 1.0)))\\n  ))).xyz - (0.0008 + (\\n    (texture (sampler_noise_lq, tmpvar_2) - 0.5)\\n   * 0.02)).xyz);\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (texture (sampler_main, (uv - tmpvar_2)).xyz - texture (sampler_main, (uv + tmpvar_2)).xyz).x;\\n  tmpvar_4.y = (texture (sampler_main, (uv - tmpvar_3)).xyz - texture (sampler_main, (uv + tmpvar_3)).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    ((uv - 0.5) * 2.0)\\n  )) - tmpvar_4);\\n  float tmpvar_5;\\n  tmpvar_5 = clamp ((0.04 / sqrt(\\n    dot (uv1_1, uv1_1)\\n  )), 0.0, 1.0);\\n  uv1_1 = ((0.3 * cos(\\n    (uv1_1 * 12.0)\\n  )) - (9.0 * tmpvar_4));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = (tmpvar_5 + ((texture (sampler_main, uv).xyz * 12.0) * vec3(clamp (\\n    (0.04 / sqrt(dot (uv1_1, uv1_1)))\\n  , 0.0, 1.0))));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,decay:1,echo_zoom:1,echo_alpha:.5,echo_orient:3,invert:1,wave_a:.001,warpanimspeed:100,warpscale:.01,zoomexp:1.14947,warp:0,sx:.9901,sy:.9901,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ob_r:1,ob_g:1,ob_b:1,ib_r:1,ib_g:1,ib_b:1,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:100,g:1,b:1,r2:1,b2:1,border_a:0},init_eqs_str:\"a.q4=0;a.q3=0;a.xx=0;a.yy=0;a.radi=0;a.q1=0;\",frame_eqs_str:\"a.a=above(a.q4,1E3-div(9E3,a.fps))&&above(a.q3,1.5)?1:0;a.a2=above(a.q4,1E3)&&above(a.q3,1.5)?1:0;a.xx=(above(a.q4,1E3-div(3,a.fps)),.01*randint(100));a.yy=.00001<Math.abs(above(a.q4,1E3-div(3,a.fps)))?.01*randint(100):.01*randint(70)+.15;a.radi=.00001<Math.abs(above(a.q4,1E3-div(3,a.fps)))?.333*sqrt(a.q3)+.15:.4*sqrt(a.q3);a.rad=a.radi;a.x=a.xx;a.y=a.yy;a.r=.5*Math.sin(1.22*a.q1)+.6;a.g=.45+.45*Math.sin(1.307*a.q1);a.b=.45+.45*Math.sin(1.959*a.q1);a.r2=.5*Math.sin(1.622*a.q1)+\\n.6;a.g2=.45+.45*Math.sin(1.507*a.q1);a.b2=.45+.45*Math.sin(1.6559*a.q1);\"}],waves:[{baseVals:{enabled:1,spectrum:1,thick:1,a:.42},init_eqs_str:\"a.zs=0;a.speed=0;a.q3=0;a.q29=0;a.q30=0;a.q4=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.zs=.00001<Math.abs(below(a.zs,-9.42478))?0:a.zs;a.zs=.00001<Math.abs(above(a.zs,9.42478))?0:a.zs;a.speed=.0025*Math.floor(Math.tan(pow(a.q3,.667)))*(1.5708*Math.atan(a.bass)+1.5708*Math.atan(a.mid)+1.5708*Math.atan(a.treb));a.zs+=a.speed;a.x=.5+(.18+.005*pow(a.q3,1.25))*Math.cos(a.zs*Math.asin(1)*100);a.y=.5+(.18+.005*pow(a.q3,1.25))*Math.sin(a.zs*Math.asin(1)*100);.00001<Math.abs(above(a.mid+a.treb,2*a.bass))?a.r=.3-Math.abs(.33*Math.sin(1-a.q29*a.bass*a.bass)):a.r=.7+Math.abs(.33*\\nMath.sin(1-a.q29*a.bass*a.bass));.00001<Math.abs(above(a.bass+a.treb,2*a.mid))?a.g=.3-Math.abs(.33*Math.sin(1-a.q30*a.mid*a.mid)):a.g=.7+Math.abs(.33*Math.sin(1-a.q30*a.mid*a.mid));.00001<Math.abs(below(a.mid+a.bass,2*a.treb))?a.b=.3-Math.abs(.33*Math.sin(1-a.q3*a.treb*a.treb)):a.b=.7+Math.abs(.33*Math.sin(1-a.q3*a.treb*a.treb));a.a=.175+.0007*a.q4;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.foo_r=0;a.maxs=0;a.n=0;a.ampl=0;a.bd_minbpm=0;a.im=0;a.basstime=0;a.bd_mean=0;a.timediff=0;a.bd_src=0;a.bass_residual=0;a.bd_slot=0;a.bd_b=0;a.bd_oct=0;a.tcos=0;a.stickybit=0;a.bd_arg=0;a.old_treb_flop=0;a.quali=0;a.q12=0;a.foo_b=0;a.bass_flop=0;a.q22=0;a.q21=0;a.volavg2=0;a.q13=0;a.q15=0;a.q29=0;a.dt=0;a.bd_pk=0;a.maxo=0;a.bd_m=0;a.q1=0;a.bd_cos=0;a.q5=0;a.foo_g=0;a.treb_flop=0;a.sample1=0;a.bass_thresh=0;a.difftime=0;a.dec_s=0;a.old_bass_flop=0;a.bd_exc=0;a.dec_xs=0;a.kraft=\\n0;a.diff=0;a.treb_thresh=0;a.bd_ampl=0;a.bd_mid_=0;a.maxind=0;a.edge=0;a.tsin=0;a.re0=0;a.testi=0;a.ec_steps=0;a.creep=0;a.q31=0;a.bpm=0;a.q23=0;a.q24=0;a.pulse=0;a.q11=0;a.bd_bass_=0;a.bd_tab0=0;a.pv_beat=0;a.bass_changed=0;a.show=0;a.mid_thresh=0;a.dec_m=0;a.q4=0;a.im0=0;a.bd_spo=0;a.mid_changed=0;a.entropy=0;a.test0=0;a.bd_nres=0;a.bd_bass=0;a.maxa=0;a.volavg=0;a.feder=0;a.q16=0;a.bd_recsz=0;a.old_mid_flop=0;a.mid_residual=0;a.bit2=0;a.tstart=0;a.bd_omega=0;a.bd_treb_=0;a.beatsin=0;a.bd_tabptr=\\n0;a.bd_treb=0;a.treb_residual=0;a.q19=0;a.beat=0;a.vol=0;a.bd_mid=0;a.chaos=0;a.bd_dat0=0;a.prog=0;a.mid_flop=0;a.re=0;a.bd_t=0;a.beatcos=0;a.q2=0;a.time_st=0;a.q14=0;a.treb_changed=0;a.bd_maxbpm=0;a.bd_qual=0;a.vol2=0;a.q3=0;a.t0=0;a.vol_=0;a.m=0;a.oct=0;a.quad=0;a.q32=0;a.basssum=0;a.creepo=0;a.q28=0;a.bd_sin=0;a.sample2=0;a.q30=0;a.change=0;a.beatct=0;a.q20=0;a.q8=0;a.bd_finc=0;for(var b=a.index=0;2E5>b;b++)a.megabuf[Math.floor(a.index)]=0,a.gmegabuf[Math.floor(a.index)]=0,a.index+=1;a.tstart=\\na.time;a.bd_recsz=8;a.bd_oct=4;a.bd_spo=30;a.bd_finc=pow(2,div(1,a.bd_spo));a.bd_nres=a.bd_oct*a.bd_spo;a.bd_minbpm=20;a.bd_maxbpm=pow(2,a.bd_oct)*a.bd_minbpm;a.bd_dat0=1E5;a.bd_tab0=a.bd_dat0+a.bd_nres*a.bd_recsz*3;a.reg00=a.bd_minbpm;a.reg01=a.bd_maxbpm;a.reg02=a.bd_recsz;a.reg03=a.bd_nres;a.reg05=a.bd_finc;a.reg06=a.bd_dat0;a.reg07=a.bd_mp0;a.time_st=0;a.timediff=1;\",frame_eqs_str:\"a.dt=Math.min(div(1,a.fps),.1);a.dec_m=1-4*a.dt;a.dec_s=1-a.dt;a.dec_xs=1-div(a.dt,6);a.t0=a.time-a.tstart;a.bd_b=a.bass;a.bd_bass_=a.bd_bass_*a.dec_m+(1-a.dec_m)*a.bd_b;a.bd_bass=a.bd_b-a.bd_bass_;a.bd_m=a.mid;a.bd_mid_=a.bd_mid_*a.dec_m+(1-a.dec_m)*a.bd_m;a.bd_mid=a.bd_m-a.bd_mid_;a.bd_t=a.treb;a.bd_treb_=a.bd_treb_*a.dec_m+(1-a.dec_m)*a.bd_t;a.bd_treb=a.bd_t-a.bd_treb_;a.n=0;a.bpm=a.bd_minbpm;for(var b=0;b<a.bd_nres;b++)a.gmegabuf[Math.floor(5E4+a.n*a.bd_recsz)]=0,a.bd_arg=\\ndiv(a.bpm,60)*a.t0*6.283,a.gmegabuf[Math.floor(a.bd_tab0+a.n*a.bd_recsz)]=a.bpm,a.bpm*=a.bd_finc,a.n+=1;for(b=a.bd_src=0;3>b;b++){a.bd_exc=a.bd_bass*(.00001>Math.abs(a.bd_src-0)?1:0)+a.bd_mid*(.00001>Math.abs(a.bd_src-1)?1:0)+a.bd_treb*(.00001>Math.abs(a.bd_src-2)?1:0);for(var c=a.oct=0;c<a.bd_oct;c++){a.bd_slot=0;a.bd_pk=0;for(var d=a.bd_mean=0;d<a.bd_spo;d++){a.bd_tabptr=a.bd_tab0+(a.oct*a.bd_spo+a.bd_slot)*a.bd_recsz;a.n=a.bd_dat0+(a.bd_nres*a.bd_src+a.oct*a.bd_spo+a.bd_slot)*a.bd_recsz;a.bpm=\\na.gmegabuf[Math.floor(a.bd_tabptr)];a.bd_omega=6.283*div(a.bpm,60);a.feder=sqr(a.bd_omega);a.gmegabuf[Math.floor(a.n+4)]=a.gmegabuf[Math.floor(a.n+2)];a.gmegabuf[Math.floor(a.n+1)]*=1-.5*a.dt*sqrt(div(a.bpm,300));a.ec_steps=2*Math.floor(1+div(a.bpm,50));for(var e=0;e<a.ec_steps;e++)a.kraft=a.bd_exc-a.feder*a.gmegabuf[Math.floor(a.n+2)],a.gmegabuf[Math.floor(a.n+1)]+=div(a.kraft*a.dt,a.ec_steps),a.gmegabuf[Math.floor(a.n+2)]+=div(a.gmegabuf[Math.floor(a.n+1)]*a.dt,a.ec_steps);a.beatcos=a.gmegabuf[Math.floor(a.n+\\n1)];a.beatsin=a.gmegabuf[Math.floor(a.n+2)]*a.bd_omega;a.quad=sqrt(pow(a.beatsin,2)+pow(a.beatcos,2));a.gmegabuf[Math.floor(a.n)]=.8*a.gmegabuf[Math.floor(a.n)]+.2*a.quad;a.bd_ampl=a.gmegabuf[Math.floor(a.n)];a.bd_mean+=a.bd_ampl;.00001<Math.abs(a.bd_ampl>a.bd_pk?1:0)?a.bd_pk=a.bd_ampl:0;a.bd_slot+=1}a.bd_slot=0;a.bd_qual=pow(div(a.bd_pk,a.bd_mean)*a.bd_spo-1,1);a.gmegabuf[Math.floor(2*(a.bd_src*a.bd_oct+a.oct))]=a.bd_qual;for(d=0;d<a.bd_spo;d++)a.m=5E4+(a.bd_slot+0*a.oct*a.bd_spo)*a.bd_recsz,a.n=\\na.bd_dat0+(a.bd_nres*a.bd_src+a.oct*a.bd_spo+a.bd_slot)*a.bd_recsz,a.gmegabuf[Math.floor(a.m)]+=div(a.bd_qual*a.gmegabuf[Math.floor(a.n)],12),a.bd_slot+=1;a.oct+=1}a.bd_src+=1}a.bd_slot=0;a.maxind=0;a.bd_pk=0;for(b=a.bd_mean=0;b<a.bd_spo;b++)a.m=5E4+a.bd_slot*a.bd_recsz,a.gmegabuf[Math.floor(a.m)]=pow(a.gmegabuf[Math.floor(a.m)],1),a.bd_mean+=a.gmegabuf[Math.floor(a.m)],.00001<Math.abs(a.gmegabuf[Math.floor(a.m)]>a.bd_pk?1:0)?(a.bd_pk=a.gmegabuf[Math.floor(a.m)],a.maxind=a.bd_slot):0,a.bd_slot+=1;\\na.quali=div(a.bd_pk,a.bd_mean)*a.bd_spo-1;for(b=a.n=0;150>b;b++)a.gmegabuf[Math.floor(50+a.n)]*=0,a.n+=1;a.bd_src=0;a.tsin=0;for(b=a.tcos=0;3>b;b++){for(c=a.oct=0;c<a.bd_oct;c++)a.n=a.bd_dat0+(a.bd_nres*a.bd_src+a.oct*a.bd_spo+a.maxind)*a.bd_recsz,a.bd_tabptr=a.bd_tab0+(a.oct*a.bd_spo+a.maxind)*a.bd_recsz,a.bpm=a.gmegabuf[Math.floor(a.bd_tabptr)],a.im=a.gmegabuf[Math.floor(a.n+1)],a.re=6.283*div(a.gmegabuf[Math.floor(a.n+2)]*a.bpm,60),a.bd_cos=Math.cos(6.28*div(a.bpm,60)*a.time),a.bd_sin=-Math.sin(6.28*\\ndiv(a.bpm,60)*a.time),a.re0=a.re*a.bd_cos+a.im*a.bd_sin,a.im0=-a.re*a.bd_sin+a.im*a.bd_cos,a.bd_qual=a.gmegabuf[Math.floor(2*(a.bd_src*a.bd_oct+a.oct))],a.gmegabuf[Math.floor(50+4*a.oct)]+=a.bd_qual*a.im0,a.gmegabuf[Math.floor(4*a.oct+51)]+=a.bd_qual*a.re0,a.gmegabuf[Math.floor(4*a.oct+52)]+=a.bd_qual,a.gmegabuf[100]+=a.bd_qual*a.im0,a.gmegabuf[101]+=a.bd_qual*a.re0,a.re=a.bd_cos*a.re0+a.bd_sin*a.im0,a.im=-a.bd_cos*a.im0+a.bd_sin*a.re0,a.tsin+=5*a.im,a.oct+=1;a.bd_src+=1}a.q30=a.tsin;a.vol=a.bass_att+\\na.mid_att+a.treb_att;a.vol_=.95*a.vol_+.05*a.vol;a.q29=a.vol-a.vol_;a.bd_src=0;a.maxo=0;a.maxs=0;for(b=a.maxa=0;3>b;b++){a.oct=1;for(c=0;c<a.bd_oct-1;c++)a.n=a.bd_dat0+(a.bd_nres*a.bd_src+a.oct*a.bd_spo+a.maxind)*a.bd_recsz,a.bd_qual=a.gmegabuf[Math.floor(2*(a.bd_src*a.bd_oct+a.oct))],a.ampl=div(a.bd_qual,1+a.oct*div(a.maxind,a.bd_oct)*0),.00001<Math.abs(a.ampl>a.maxa?1:0)?(a.maxa=a.ampl,a.maxs=a.bd_src,a.maxo=a.oct):0,a.oct+=1;a.bd_src+=1}a.q28=pow(4*a.bd_qual,1.5);a.q31=a.q28;.00001<Math.abs(above(a.q28,\\n50))?a.q28=pow(5*Math.sin(.5*a.bd_qual),2):0;a.testi=a.bd_nres*a.maxs+a.bd_spo*a.maxo+a.maxind;.00001<Math.abs(bor(a.beat&&.00001>Math.abs(a.prog-0)?1:0,2>Math.abs(a.testi-a.test0)?1:0))?a.test0=a.testi:0;a.n=a.bd_dat0+a.test0*a.bd_recsz;a.creep=a.gmegabuf[Math.floor(a.n+1)];a.beat=(0<a.creep?1:0)*(0>a.creepo?1:0);a.beatct=.00001<Math.abs(a.change)?0:a.beatct+a.beat;a.prog=mod(a.prog+a.beat,8);a.creepo=a.creep;a.show=.00001<Math.abs(a.beat)?1:.5*a.show;a.q4=1E3*div(a.gmegabuf[Math.floor(a.n+1)],a.gmegabuf[Math.floor(a.n)]);\\na.q2=a.prog;.00001<Math.abs(a.beat)?(a.timediff=a.time-a.time_st,a.time_st=a.time):a.timediff=a.timediff;.00001<Math.abs(below(a.timediff,.0625))?a.timediff=.0625:a.timediff=a.timediff;a.q8=a.timediff;a.monitor=a.q8;a.q24=a.bd_maxbpm;a.old_bass_flop=a.bass_flop;a.old_treb_flop=a.treb_flop;a.old_mid_flop=a.mid_flop;a.chaos=.9+.1*Math.sin(a.pulse);a.entropy=.00001<Math.abs(equal(a.pulse,-20))?1+a.bass_flop+a.treb_flop+a.mid_flop+.002*a.q4:a.entropy;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-\\nabove(a.bass_att,a.bass_thresh))*((a.bass_thresh-1.6)*a.chaos+1.6);a.bass_flop=Math.abs(a.bass_flop-equal(a.bass_thresh,2));a.treb_thresh=2*above(a.treb_att,a.treb_thresh)+(1-above(a.treb_att,a.treb_thresh))*((a.treb_thresh-1.6)*a.chaos+1.6);a.treb_flop=Math.abs(a.treb_flop-equal(a.treb_thresh,2));a.mid_thresh=2*above(a.mid_att,a.mid_thresh)+(1-above(a.mid_att,a.mid_thresh))*((a.mid_thresh-1.6)*a.chaos+1.6);a.mid_flop=Math.abs(a.mid_flop-equal(a.mid_thresh,2));a.bass_changed=bnot(equal(a.old_bass_flop,\\na.bass_flop));a.mid_changed=bnot(equal(a.old_mid_flop,a.mid_flop));a.treb_changed=bnot(equal(a.old_treb_flop,a.treb_flop));a.bass_residual=a.bass_changed*Math.sin(1.5*a.pulse)+bnot(a.bass_changed)*a.bass_residual;a.treb_residual=a.treb_changed*Math.sin(1.5*a.pulse)+bnot(a.treb_changed)*a.treb_residual;a.mid_residual=a.mid_changed*Math.sin(1.5*a.pulse)+bnot(a.mid_changed)*a.mid_residual;a.pulse=.00001<Math.abs(above(Math.abs(a.pulse),20))?-20:a.pulse+.018*(a.bass_thresh+a.mid_thresh+a.treb_thresh);\\na.q11=a.mid_residual;a.q12=a.bass_residual;a.q13=a.treb_residual;a.q14=Math.sin(a.pulse);a.q15=Math.cos(a.pulse*(.5+.1*a.entropy));a.q16=Math.sin(a.pulse*(.5+pow(.25,a.entropy)));a.ob_r=Math.sin(1.0785*a.time+a.q16);a.ob_b=Math.sin(.8445*a.time+a.q15);a.ob_g=Math.sin(.413*a.time+a.q14);a.ib_r=Math.cos(.6*a.time+.1*a.q11);a.ib_b=Math.cos(1.4055*a.time+.1*a.q12);a.ib_g=Math.cos(.833*a.time+.1*a.q13);a.ib_size=.05+.03*a.q12;a.ob_size=.03+.02*Math.sin(2.321*a.time+.2*a.q12);a.ob_a=.6+.4*a.q13;a.ib_a=\\n.9+.1*Math.sin(.3*a.q12+a.q14+.5*a.q11);a.rot=0;a.basstime+=div(3*a.q29,a.fps);a.q1=a.basstime;a.basstime=.00001<Math.abs(below(a.basstime,-1E4))?0:a.basstime;a.basstime=.00001<Math.abs(above(a.basstime,1E4))?0:a.basstime;a.basstime+=div(.75*a.bass_att,a.fps);a.vol2=pow(a.bass+a.mid+a.treb,2);a.basssum=a.vol2;a.stickybit=mod(a.time,2);a.volavg+=a.vol2*equal(a.stickybit,1);a.sample1+=equal(a.stickybit,1);a.volavg2+=a.vol2*equal(a.stickybit,0);a.sample2+=equal(a.stickybit,0);a.edge=bnot(equal(a.bit2,\\na.stickybit));a.volavg-=a.volavg*a.edge*a.stickybit;a.volavg2-=a.volavg2*a.edge*equal(a.stickybit,0);a.sample1-=a.sample1*a.edge*a.stickybit;a.sample2-=a.sample2*a.edge*equal(a.stickybit,0);a.diff=.00001<Math.abs(equal(a.stickybit,1))?div(a.basssum,div(a.volavg2,a.sample2)):0;a.diff=.00001<Math.abs(equal(a.stickybit,0))?div(a.basssum,div(a.volavg,a.sample1)):a.diff;a.q3=a.diff;a.pv_beat=.2*a.pv_beat*sqrt(div(a.fps,30))+div(.0001*(a.bass_att*a.bass_att+a.mid_att*a.mid_att+a.treb_att*a.treb_att)*a.q4,\\nsqrt(a.q8));a.q32=a.pv_beat;a.monitor=a.q32;a.bit2=mod(a.time,2);a.difftime+=.03*a.diff;a.q2=a.difftime;a.warp=.005*(a.bass*a.bass+a.mid*a.mid+a.treb*a.treb);a.foo_r=Math.sin(.34313*a.q1);a.foo_g=Math.sin(.3675*a.q1);a.foo_b=Math.sin(.55095*a.q1);.00001<Math.abs(above(a.foo_r,a.foo_g)&&above(a.foo_r,a.foo_b)?1:0)?a.q23=1:a.q23=0;.00001<Math.abs(above(a.foo_g,a.foo_r)&&above(a.foo_g,a.foo_b)?1:0)?a.q21=1:a.q21=0;.00001<Math.abs(above(a.foo_b,a.foo_r)&&above(a.foo_b,a.foo_g)?1:0)?a.q22=1:a.q22=0;.00001<\\nMath.abs(equal(a.q11+a.q12+a.q13,0))?a.q22=1:0;a.q5=div(30,a.fps);a.q19=50;a.q20=1;.00001<Math.abs(above(a.q31,14))?a.q19=100:a.q19=a.q19;.00001<Math.abs(above(a.q31,50))?a.q19=500:a.q19=a.q19;.00001<Math.abs(above(a.q3,2))?a.q19=.5+10*a.q8:a.q19=a.q19;\",pixel_eqs_str:\".00001<Math.abs(a.q32>1.2*sqrt(a.bass_att)?1:0)?(a.rot=.00001<Math.abs(above(a.q14,0))?.2*a.rad*a.q15:Math.tan(.001*a.rad*a.q4),a.zoom=.00001<Math.abs(above(a.q12,1.5))?a.zoom+(1-a.zoom)*a.rot*Math.cos(3.14*a.rad*a.q12):.00001<Math.abs(above(a.q13,2)*above(a.x,.5+.5*a.q15))?a.zoom+(1-a.zoom)*Math.sin(a.q11*a.rot*3.14):a.zoom+(1-a.zoom)*Math.cos(3*a.rad*a.q16),a.dx=above(a.q11,0)*Math.sin(.5*a.rad*a.q12),a.dy=above(a.q13,0)*Math.sin(.5*a.rad*a.q13)):(a.zoom=a.q19,a.zoomexp=a.q20,\\na.rot=0);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_pw_main, uv_orig);\\n  ret_1 = ((texture (sampler_blur1, tmpvar_2.xy).xyz * scale1) + bias1);\\n  vec3 tmpvar_3;\\n  tmpvar_3 = vec3((((1.0 - ret_1.x) * (1.0 - ret_1.y)) * (1.0 - ret_1.z)));\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (((texsize.zw * q5) * -3.0) * ((\\n    pow (tmpvar_3, vec3(0.333, 0.333, 0.333))\\n   + \\n    ((((0.5 * tmpvar_3) * (\\n      (texture (sampler_blur2, ret_1.xx).xyz * scale2)\\n     + bias2)) * ((texture (sampler_blur2, ret_1.yy).xyz * scale2) + bias2)) * ((texture (sampler_blur2, ret_1.zz).xyz * scale2) + bias2))\\n  ) + (\\n    ((0.25 * ((texture (sampler_blur3, ret_1.xx).xyz * scale3) + bias3)) * ((texture (sampler_blur3, ret_1.yy).xyz * scale3) + bias3))\\n   * \\n    ((texture (sampler_blur3, ret_1.xx).xyz * scale3) + bias3)\\n  )).xy);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur1, \\n    (uv_orig + (vec2(1.0, 0.0) * tmpvar_4))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_orig - (vec2(1.0, 0.0) * tmpvar_4))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (((texture (sampler_blur1, \\n    (uv_orig + (vec2(0.0, 1.0) * tmpvar_4))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_orig - (vec2(0.0, 1.0) * tmpvar_4))\\n  ).xyz * scale1) + bias1));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_5.x;\\n  tmpvar_7.y = tmpvar_6.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_5.y;\\n  tmpvar_8.y = tmpvar_6.y;\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_5.z;\\n  tmpvar_9.y = tmpvar_6.z;\\n  vec2 tmpvar_10;\\n  tmpvar_10 = (uv_orig + ((\\n    (((tmpvar_7 * q21) + (tmpvar_8 * q22)) + (tmpvar_9 * q23))\\n   * texsize.zw) * 6.0));\\n  ret_1 = ((texture (sampler_main, tmpvar_10).xyz + (\\n    (texture (sampler_main, uv).xyz - ((texture (sampler_blur1, uv).xyz * scale1) + bias1))\\n   * 0.1)) - ((0.00015 * q28) * (\\n    ((((\\n      (texture (sampler_main, tmpvar_10).x * texture (sampler_main, tmpvar_10).y)\\n     * texture (sampler_main, tmpvar_10).z) / (2.0 * q8)) + ((\\n      sqrt(treb)\\n     * texture (sampler_main, tmpvar_10).x) * texture (sampler_main, tmpvar_10).y)) + ((sqrt(mid) * texture (sampler_main, tmpvar_10).x) * texture (sampler_main, tmpvar_10).z))\\n   + \\n    ((sqrt(bass) * texture (sampler_main, tmpvar_10).y) * texture (sampler_main, tmpvar_10).z)\\n  )));\\n  ret_1.x = mix (ret_1.x, (1.01 * texture (sampler_pc_main, tmpvar_10).x), (bass_att * 0.05));\\n  ret_1.y = mix (ret_1.y, (1.01 * texture (sampler_pc_main, tmpvar_10).y), (mid_att * 0.05));\\n  ret_1.z = mix (ret_1.z, (1.01 * texture (sampler_pc_main, tmpvar_10).z), (treb_att * 0.05));\\n  ret_1 = (ret_1 + ((\\n    (pow (q3, 1.2) - 0.25)\\n   * 0.00667) * tmpvar_2).xyz);\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 0.0;\\n  tmpvar_11.xyz = ret_1;\\n  vec3 tmpvar_12;\\n  tmpvar_12 = mix (tmpvar_11, texture (sampler_pc_main, uv), vec4(float((\\n    (q32 * sqrt(((\\n      ((1.0 - ret_1.x) * (1.0 - ret_1.y))\\n     + \\n      ((1.0 - ret_1.x) * (1.0 - ret_1.z))\\n    ) + (\\n      (1.0 - ret_1.y)\\n     * \\n      (1.0 - ret_1.z)\\n    ))))\\n   > 1.333)))).xyz;\\n  ret_1 = tmpvar_12;\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 1.0;\\n  tmpvar_13.xyz = tmpvar_12;\\n  ret = tmpvar_13.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = mix (texture (sampler_main, uv).xyz, texture (sampler_main, ((0.5 - uv) + 0.5)).xyz, vec3(0.5, 0.5, 0.5));\\n  ret_1 = (1.0 - ((ret_1 * \\n    (1.0 - ret_1)\\n  ) * 4.0));\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:.925,echo_zoom:1.007,echo_orient:3,wave_brighten:0,brighten:1,darken:1,solarize:1,wave_a:.001,wave_scale:.01,wave_smoothing:0,modwavealphastart:1,modwavealphaend:1,warpanimspeed:1.459,warpscale:2.007,fshader:1,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:5,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,textured:1,rad:.789,ang:.6283,tex_zoom:1.17257,r:0,g:1,border_a:0},init_eqs_str:\"a.an=0;a.vx=0;a.vy=0;\",frame_eqs_str:\"a.rad=.65+.1*a.bass;a.an=.99*a.an+.1*(a.bass-a.treb);a.ang=.1*a.an+.6;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:495,sep:4,spectrum:1,thick:1,additive:1,scaling:100,smoothing:1,r:0,g:.04,b:0,a:.99},init_eqs_str:\"a.my_z=0;a.d=0;a.n=0;a.y3=0;a.z2=0;a.y1=0;a.w=0;a.t5=0;a.w2=0;a.t1=0;a.x1=0;a.q6=0;a.zoom=0;a.p=0;a.q1=0;a.q5=0;a.t8=0;a.z3=0;a.w3=0;a.t3=0;a.my_x=0;a.x3=0;a.t6=0;a.my_y=0;a.pi=0;a.q4=0;a.t7=0;a.rd=0;a.w1=0;a.x2=0;a.t2=0;a.l=0;a.y2=0;a.q2=0;a.z1=0;a.q3=0;a.t4=0;a.t2=0;a.t3=0;a.t4=0;a.ab=1;\",frame_eqs_str:\"a.t1=a.q1;a.t2=a.q2;a.t3=a.q3;a.t4=a.q4;a.t5=a.q5;a.t6=a.q6;a.t8=.07;a.t7=1;\",point_eqs_str:\"a.t7=-a.t7;a.pi=Math.asin(1);a.n=180;a.rd=.075;a.my_x=.5*Math.sin(a.sample*a.pi*4+(a.t7+1)*a.t8)+Math.cos(a.sample*a.pi*a.n)*a.rd*Math.sin(a.sample*a.pi*4+(a.t7+1)*a.t8);a.my_y=.5*Math.cos(a.sample*a.pi*4+(a.t7+1)*a.t8)+Math.cos(a.sample*a.pi*a.n)*a.rd*Math.cos(a.sample*a.pi*4+(a.t7+1)*a.t8);a.my_z=Math.sin(a.sample*a.pi*a.n)*a.rd;a.d=1.4;a.zoom=.65;a.w1=a.q2;a.w2=a.q3;a.w3=a.q4;a.x1=Math.cos(a.w1)*a.my_x+Math.sin(a.w1)*a.my_y;a.y1=-Math.sin(a.w1)*a.my_x+Math.cos(a.w1)*a.my_y;\\na.z1=a.my_z;a.x2=Math.cos(a.w2)*a.x1+Math.sin(a.w2)*a.z1;a.z2=-Math.sin(a.w2)*a.x1+Math.cos(a.w2)*a.z1;a.y2=a.y1;a.y3=Math.cos(a.w3)*a.y2+Math.sin(a.w3)*a.z2;a.z3=-Math.sin(a.w3)*a.y2+Math.cos(a.w3)*a.z2;a.x3=a.x2;a.l=sqrt(a.x3*a.x3+a.y3*a.y3);a.w=Math.atan2(a.x3,a.y3);a.p=Math.tan(Math.asin(1)+Math.atan2(a.d+a.z3,a.l));a.d=sqrt(a.x3*a.x3+a.y3*a.y3+(a.z3+a.d)*(a.z3+a.d));a.my_x=a.zoom*Math.sin(a.w)*a.p;a.my_y=a.zoom*Math.cos(a.w)*a.p;a.x=.5+a.my_x;a.y=.5+a.my_y;a.b=-a.z3+.5;a.b=.5*Math.min(1,Math.max(0,\\na.b));a.r=1-2*a.b;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q29=0;a.q1=0;a.dec_med=0;a.rott=0;a.is_beat=0;a.q31=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.p3=0;a.q3=0;a.t0=0;a.q28=0;a.q30=0;a.q20=0;a.p4=0;a.step=0;a.step=0;\",frame_eqs_str:\"a.dec_med=pow(.7,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,-2+a.avg+a.peak)*above(a.time,a.t0+.1);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,16);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass_att+\\na.mid_att+a.treb_att;a.q27=a.index+1;a.q28=a.index2;a.q29=2*(mod(a.index,2)-.5);a.k1=a.is_beat*equal(mod(a.index,2),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,8);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.step+=a.q24;a.p3=a.p3*a.dec_slow+(1-a.dec_slow)*a.step;a.q30=a.step;a.p4=a.dec_slow*a.p4+(1-a.dec_slow)*a.q27;a.q31=a.p4;a.q12=a.time-a.t0;a.monitor=a.q12;a.zoom=1;a.rot=-0;a.dx=0;\",pixel_eqs_str:\"a.zoom=1.3;\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 uv6_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_4;\\n  tmpvar_4 = (((q29 * 2.0) * sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  )) + (rand_frame * 64.0)).x;\\n  uv_1 = (uv + (clamp (\\n    ((sin(tmpvar_4) / cos(tmpvar_4)) * normalize(tmpvar_3))\\n  , vec2(-2.0, -2.0), vec2(2.0, 2.0)) / 20.0));\\n  uv6_2 = (0.4 * sin((tmpvar_3 * 22.0)));\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = (((q24 * \\n    (((texture (sampler_main, uv_1).xyz - (\\n      ((texture (sampler_blur1, fract(uv_1)).xyz * scale1) + bias1)\\n     * 0.04)) + (0.15 * (vec3(\\n      (0.1 / sqrt(dot (uv6_2, uv6_2)))\\n    ) * roam_cos.xyz))) - 0.02)\\n  ) * 0.98) + ((1.0 - q24) * texture (sampler_main, uv_orig).xyz));\\n  ret = tmpvar_5.xyz;\\n }\",comp:\"uniform sampler2D sampler_rand00;\\n shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1 = texture (sampler_main, uv);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ((texture (sampler_rand00, (0.4 + \\n    (0.6 * tmpvar_1.xy)\\n  )) * tmpvar_1.z) * 3.0).xyz;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:2,gammaadj:2.7,wave_mode:1,modwavealphabyvolume:1,wave_a:2.707,wave_scale:1.025,wave_smoothing:.1,modwavealphastart:.77,modwavealphaend:1.01,warpscale:1.331,zoom:1.014,warp:.21786,wave_r:.65,wave_g:.65,wave_b:.65,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"\",frame_eqs_str:\"a.wave_r+=.35*(.6*Math.sin(3.98*a.time)+.4*Math.sin(11.047*a.time));a.wave_g+=.35*(.6*Math.sin(.835*a.time)+.4*Math.sin(1.081*a.time));a.wave_b+=.35*(.6*Math.sin(.814*a.time)+.4*Math.sin(1.011*a.time));a.cx+=.11*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.11*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.005*(.6*Math.sin(.173*a.time)+.4*Math.sin(.223*a.time));a.decay-=.01*equal(mod(a.frame,20),0);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_main, (uv + (\\n    (texture (sampler_main, (mix (uv, uv_orig, vec2(-1.0, -1.0)) + texsize.zw)).xy - 0.37)\\n   * 0.01))).xyz - 0.004);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1 = texture (sampler_main, uv);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = mix (vec3(dot (tmpvar_1.xyz, vec3(0.3333, 0.3333, 0.3333))), tmpvar_1.xyz, vec3(3.0, 3.0, 3.0));\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.9,echo_zoom:1.16936,wave_mode:7,modwavealphabyvolume:1,wave_a:0,wave_scale:1.015009,wave_smoothing:.522,modwavealphastart:.83,modwavealphaend:1.31,warpscale:3.138,zoom:1.009006,warp:536e-6,wave_r:.5,wave_g:.5,wave_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dx_residual=0;a.dy_residual=0;a.bass_thresh=0;\",frame_eqs_str:\"a.wave_r=.85+.25*Math.sin(.437*a.time+1);a.wave_g=.85+.25*Math.sin(.544*a.time+2);a.wave_b=.85+.25*Math.sin(.751*a.time+3);a.rot+=.01*(.6*Math.sin(.381*a.time)+.4*Math.sin(.579*a.time));a.cx+=.21*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.cy+=.21*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.dx+=.003*(.6*Math.sin(.234*a.time)+.4*Math.sin(.277*a.time));a.dy+=.003*(.6*Math.sin(.284*a.time)+.4*Math.sin(.247*a.time));a.decay-=.01*equal(mod(a.frame,6),0);a.dx+=\\na.dx_residual;a.dy+=a.dy_residual;a.bass_thresh=2*above(a.bass_att,a.bass_thresh)+(1-above(a.bass_att,a.bass_thresh))*(.96*(a.bass_thresh-1.3)+1.3);a.dx_residual=.016*equal(a.bass_thresh,2.13)*Math.sin(7*a.time)+(1-equal(a.bass_thresh,2.13))*a.dx_residual;a.dy_residual=.012*equal(a.bass_thresh,2.13)*Math.sin(9*a.time)+(1-equal(a.bass_thresh,2.13))*a.dy_residual;a.wave_x-=7*a.dx_residual;a.wave_y-=7*a.dy_residual;a.wave_mystery=.03*a.time;a.zoom+=.005*(.6*Math.sin(.1934*a.time+3)+.4*Math.sin(.307*\\na.time+9));a.zoom+=.4*Math.max(0,a.bass_att-1.1);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = texture (sampler_main, uv).xyz;\\n  ret_1 = (ret_1 + ((ret_1 - \\n    ((texture (sampler_blur2, uv).xyz * scale2) + bias2)\\n  ) * 0.3));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 122.0) * clamp (\\n    (treb_att - 1.0)\\n  , 0.0, 1.0)));\\n  ret_1 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.2, 0.2, 0.2));\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = (texture (sampler_main, uv).xyz + ((\\n    (texture (sampler_blur1, uv).xyz * scale1)\\n   + bias1) * 0.4));\\n  vec3 tmpvar_2;\\n  tmpvar_2 = pow (ret_1, vec3(0.5, 0.8, 1.7));\\n  ret_1 = tmpvar_2;\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = tmpvar_2;\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,wave_mode:6,additivewave:1,wave_dots:1,wave_thick:1,wave_brighten:0,wave_a:100,wave_scale:3.63,wave_smoothing:.9,wave_mystery:-.3,modwavealphastart:1.15,modwavealphaend:1.55,warpscale:1.331,zoom:.96971,warp:0,wave_r:.6,wave_g:.6,wave_b:.6,mv_x:64,mv_y:48,mv_l:0,mv_r:.35,mv_g:.35,mv_b:.35,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.decay_rate=0;a.q6=0;a.rot_sum=0;a.q1=0;a.q5=0;a.prev_beat=0;a.is_beat=0;a.min_att=0;a.beat=0;a.decay_to=0;a.rot_sim=0;a.q2=0;a.q3=0;a.beat_level=0;a.rot_sum=0;a.q2=.07+.00004*randint(1E3)+.00003*randint(1E3);a.q3=1.035+.06*(randint(1E3)+randint(1E3)+randint(1E3))*.000333;\",frame_eqs_str:\"a.wave_r+=.5*(.6*Math.sin(1.98*a.time)+.4*Math.sin(3.047*a.time));a.wave_g+=.5*(.6*Math.sin(2.835*a.time)+.4*Math.sin(2.081*a.time));a.wave_b+=.5*(.6*Math.sin(3.814*a.time)+.4*Math.sin(1.011*a.time));a.cx=.5;a.cy=.5;a.rot=a.q2;a.zoom=a.zoom-1+a.q3;a.rot_sum+=a.rot;a.q1=-a.rot_sum;a.q5=Math.cos(a.rot_sum);a.q6=Math.sin(a.rot_sim);a.monitor=a.q2;a.min_att=2.5;a.decay_to=.8;a.decay_rate=pow(.999,a.fps);a.beat=div(a.bass,Math.max(a.min_att,a.bass_att));a.beat=Math.max(a.beat,div(a.mid,\\nMath.max(a.min_att,a.mid_att)));a.beat=Math.max(a.beat,div(a.treb,Math.max(a.min_att,a.treb_att)));a.beat=Math.max(a.beat,(a.prev_beat-a.decay_to)*a.decay_rate+a.decay_to);a.beat_level=24*(a.beat-a.prev_beat-.02);a.is_beat=above(a.beat_level,.5);a.prev_beat=a.beat;a.wave_a=a.beat_level;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_pw_main, uv).xyz - 0.004);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 uv2_2;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * (min (aspect.x, aspect.y) * 0.8));\\n  uv_1 = (uv_1 * aspect.xy);\\n  float tmpvar_3;\\n  tmpvar_3 = sin(q1);\\n  float tmpvar_4;\\n  tmpvar_4 = cos(q1);\\n  uv2_2.x = ((uv_1.x * tmpvar_4) - (uv_1.y * tmpvar_3));\\n  uv2_2.y = ((uv_1.x * tmpvar_3) + (uv_1.y * tmpvar_4));\\n  uv2_2 = (uv2_2 * aspect.zw);\\n  uv2_2 = (uv2_2 + 0.5);\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = (abs((\\n    (texture (sampler_main, uv2_2).xyz * 2.65)\\n   + \\n    (((texture (sampler_blur1, uv2_2).xyz * scale1) + bias1) * -2.0)\\n  )) * 1.5);\\n  ret = tmpvar_5.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.9,echo_zoom:1.16936,wave_mode:5,additivewave:1,wave_a:0,wave_scale:.899719,wave_smoothing:.63,wave_mystery:1,modwavealphastart:2,modwavealphaend:2,warpscale:2.593743,zoom:1.00496,warp:.278033,sx:.999666,sy:.9999,wave_r:.65,wave_g:.65,wave_b:.65,mv_x:0,mv_y:48,mv_dx:-.941273,mv_dy:.426319,mv_l:5,mv_r:.315997,mv_g:.078173,mv_b:.941976,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.du=0;a.q1=0;a.rg=0;a.q9=0;a.mult=0;a.ang2=0;a.dv=0;a.q4=0;a.q2=0;a.dist=0;a.q3=0;a.rg=0;\",frame_eqs_str:\"a.wave_r+=.35*(.6*Math.sin(.98*a.time)+.4*Math.sin(1.047*a.time));a.wave_g+=.35*(.6*Math.sin(.835*a.time)+.4*Math.sin(1.081*a.time));a.wave_b+=.35*(.6*Math.sin(.814*a.time)+.4*Math.sin(1.011*a.time));a.q1=2*a.cx-1+.52*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.q2=2*a.cy-1+.52*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));a.q3=2*a.cx-1+.52*(.6*Math.sin(.174*-a.time)+.4*Math.sin(.364*a.time));a.q4=2*a.cy-1+.52*(.6*Math.sin(.234*a.time)+.4*Math.sin(.271*-a.time));\\na.decay-=.01*equal(mod(a.frame,5),0);a.rg=Math.max(.95*a.rg,.3+.5*Math.min(2,1.3*Math.max(0,a.mid_att-1)));a.q9=a.rg;\",pixel_eqs_str:\"a.du=2*a.x-1-a.q1;a.dv=2*a.y-1-a.q2;a.dist=sqrt(a.du*a.du+a.dv*a.dv);a.ang2=Math.atan2(a.du,a.dv);a.mult=div(.008,a.dist+.4);a.dx=a.mult*Math.sin(a.ang2-1.5);a.dy=a.mult*Math.cos(a.ang2-1.5);a.du=2*a.x-1-a.q3;a.dv=2*a.y-1-a.q4;a.dist=sqrt(a.du*a.du+a.dv*a.dv);a.ang2=Math.atan2(a.du,a.dv);a.mult=div(.008,a.dist+.4);a.dx+=a.mult*Math.sin(a.ang2+1.5);a.dy+=a.mult*Math.cos(a.ang2+1.5);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = mix (uv_orig, uv, vec2(q9));\\n  ret_1 = texture (sampler_main, tmpvar_2).xyz;\\n  ret_1 = (ret_1 + ((ret_1 - \\n    ((texture (sampler_blur1, tmpvar_2).xyz * scale1) + bias1)\\n  ) * 0.3));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 122.0) * clamp (\\n    (treb_att - 1.0)\\n  , 0.0, 1.0)));\\n  ret_1 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.2, 0.2, 0.2));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_1;\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (0.3 + (0.4 * vec3(dot (texture (sampler_main, uv).xyz, vec3(0.32, 0.49, 0.29)))));\\n  ret = tmpvar_1.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.9,echo_zoom:1.169,echo_orient:1,wave_mode:5,additivewave:1,wave_a:0,wave_scale:.9,wave_smoothing:.63,wave_mystery:1,modwavealphastart:2,modwavealphaend:2,warpscale:1.331,zoom:1.004,warp:.19788,sx:.99967,sy:.9999,wave_r:.65,wave_g:.65,wave_b:.65,mv_x:0,mv_y:48,mv_dx:-.941,mv_dy:.426,mv_l:5,mv_r:.316,mv_g:.078,mv_b:.942,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.du=0;a.q1=0;a.dv=0;a.q2=0;a.dist=0;a.ang2=0;a.mult=0;\",frame_eqs_str:\"a.wave_r+=.2*(.6*Math.sin(.98*a.time)+.4*Math.sin(1.047*a.time));a.wave_g+=.2*(.6*Math.sin(.835*a.time)+.4*Math.sin(1.081*a.time));a.wave_b+=.2*(.6*Math.sin(.814*a.time)+.4*Math.sin(1.011*a.time));a.q1=2*a.cx-1+.6*(.6*Math.sin(.374*a.time)+.4*Math.sin(.294*a.time));a.q2=2*a.cy-1+.6*(.6*Math.sin(.393*a.time)+.4*Math.sin(.223*a.time));\",pixel_eqs_str:\"a.du=2*a.x-1-a.q1;a.dv=2*a.y-1-a.q2;a.dist=sqrt(a.du*a.du+a.dv*a.dv);a.ang2=Math.atan2(a.du,a.dv)+.15*a.time;a.mult=.65*Math.sin(.05*a.dist);a.dx=a.mult*Math.sin(2*a.ang2-1.5);a.dy=a.mult*Math.cos(2*a.ang2-1.5);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = (tmpvar_2.xyz + ((tmpvar_2.xyz - \\n    ((texture (sampler_blur2, uv).xyz * scale2) + bias2)\\n  ) * 0.3));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 122.0) * clamp (\\n    (treb_att - 1.0)\\n  , 0.0, 1.0)));\\n  vec3 tmpvar_3;\\n  tmpvar_3 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.2, 0.2, 0.2));\\n  ret_1 = tmpvar_3;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = tmpvar_3;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv2_1;\\n  vec3 ret_2;\\n  uv2_1 = (uv + (vec2(1.0, 0.0) * texsize.zw));\\n  float tmpvar_3;\\n  tmpvar_3 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(-1.0, 0.0) * texsize.zw));\\n  float tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(0.0, 1.0) * texsize.zw));\\n  float tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_main, uv2_1).xyz + \\n    (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4)\\n  ) + (\\n    ((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2)\\n   * 0.15)) + ((\\n    (texture (sampler_blur3, uv2_1).xyz * scale3)\\n   + bias3) * 0.1)).x;\\n  uv2_1 = (uv + (vec2(0.0, -1.0) * texsize.zw));\\n  vec3 tmpvar_6;\\n  tmpvar_6.z = 0.14;\\n  tmpvar_6.x = (tmpvar_3 - tmpvar_4);\\n  tmpvar_6.y = (tmpvar_5 - ((\\n    (texture (sampler_main, uv2_1).xyz + (((texture (sampler_blur1, uv2_1).xyz * scale1) + bias1) * 0.4))\\n   + \\n    (((texture (sampler_blur2, uv2_1).xyz * scale2) + bias2) * 0.15)\\n  ) + (\\n    ((texture (sampler_blur3, uv2_1).xyz * scale3) + bias3)\\n   * 0.1)).x);\\n  ret_2 = (0.5 + (0.5 * normalize(tmpvar_6)));\\n  vec2 x_7;\\n  x_7 = (ret_2.xy - 0.5);\\n  ret_2 = (ret_2 * clamp ((\\n    sqrt(dot (x_7, x_7))\\n   * 5.0), 0.0, 1.0));\\n  ret_2 = ret_2.xxy;\\n  ret_2 = (ret_2 + 1.15);\\n  ret_2 = (ret_2 * mix (ret_2, (ret_2 * \\n    (((texture (sampler_blur3, uv).xyz * scale3) + bias3) - ((texture (sampler_blur1, uv).xyz * scale1) + bias1))\\n  ), pow (hue_shader.yxz, ret_2)));\\n  ret_2 = (ret_2 * ret_2);\\n  vec4 tmpvar_8;\\n  tmpvar_8.w = 1.0;\\n  tmpvar_8.xyz = ret_2;\\n  ret = tmpvar_8.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:2.4,decay:1,echo_zoom:.997,echo_alpha:.5,echo_orient:3,wave_mode:2,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.28,wave_smoothing:.9,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:2.599,warpscale:.01,zoomexp:.99817,zoom:.86978,warp:.01,sy:1.0017,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ob_r:1,ob_g:1,ob_b:1,ib_size:.04,ib_r:0,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:.5,mv_r:.35,mv_g:.35,mv_b:.35,mv_a:.2},shapes:[{baseVals:{enabled:1,sides:20,additive:1,textured:1,rad:1.99867,tex_zoom:.49486,g:1,b:1,a:.75,r2:1,b2:1,a2:1,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.ang2=0;a.redsine=0;a.greensine=0;a.bluesine=0;a.redif=0;a.greenif=0;a.blueif=0;a.decay=.1;\",frame_eqs_str:\"a.sx=1;a.sy=1;a.redsine=.5+.15*a.bass*Math.sin(3*a.time);a.greensine=.5+.15*a.mid*Math.sin(2*a.time);a.bluesine=.5+.15*a.treb*Math.sin(a.time);a.redif=.9*(.00001<Math.abs(above(a.bass,1.2))?a.redsine:.00001<Math.abs(above(a.redif,.95))?0:.98*a.redif);a.greenif=.8*(.00001<Math.abs(above(a.mid,1.2))?a.greensine:.00001<Math.abs(above(a.greenif,.95))?0:.8*a.greenif);a.blueif=.8*(.00001<Math.abs(above(a.treb,1.2))?a.bluesine:.00001<Math.abs(above(a.blueif,.95))?0:.8*a.blueif);a.ib_r=\\na.redif;a.ib_g=a.greenif;a.ib_b=a.blueif;\",pixel_eqs_str:\"a.ang2=Math.sin(3*a.ang+a.time+.05*Math.sin(a.time*above(a.mid_att,1.2)));a.rot=1.2*a.ang2;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (((texture (sampler_blur1, uv).xyz * scale1) + bias1) - texture (sampler_main, uv).xyz);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = (mix (texture (sampler_main, uv).xyz, texture (sampler_main, (\\n    (vec2(-1.003, 1.003) * (uv - 0.5))\\n   + 0.5)).xyz, vec3(0.5, 0.5, 0.5)) * 2.4);\\n  ret_1 = (ret_1 * ret_1);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1,decay:.995,echo_zoom:1,echo_alpha:.5,echo_orient:1,wave_mode:6,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,wave_a:.001,wave_scale:2.103,wave_smoothing:.54,wave_mystery:.38,modwavealphastart:.81,modwavealphaend:1.4,warpscale:1.331,warp:.01,wave_r:0,wave_g:0,wave_b:0,ob_size:.005,ob_a:1,ib_size:.005,ib_a:1,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:14,num_inst:78,x:.6,rad:.02217,tex_zoom:60.80383,g:1,b:1,a:.9,g2:0,a2:1,border_g:.59,border_a:1},init_eqs_str:\"a.fov=0;a.arg=0;a.t1=0;a.posx=0;a.trel=0;a.yl=0;a.k1=0;a.posy=0;a.xl=0;a.time2=0;a.q19=0;a.t2=0;a.yw=0;a.dist=0;a.xw=0;a.speed=0;a.t1=div(Math.floor(randint(10)),10);a.t2=.2+div(Math.floor(randint(8)),10);\",frame_eqs_str:\"a.speed=.02;a.trel=Math.floor(a.time*a.speed)-a.time*a.speed+1;a.k1=div(a.instance,a.num_inst);a.k1-=Math.floor(a.k1);a.dist=1.4-a.k1;a.fov=.1;a.arg=a.dist-.02*a.time;a.posx=div(a.fov,a.dist)*(Math.sin(13*a.arg)+.2*Math.sin(332*a.dist));a.posy=div(a.fov,a.dist)*(Math.cos(36*a.arg)+.2*Math.sin(332*a.dist));a.xl=.5+a.posx;a.yl=.5+a.posy;a.time2=div(a.time,4)+Math.cos(a.instance);a.xw=.5+.5*(Math.sin(14*a.arg)+.02*Math.cos(1131*a.arg));a.yw=a.time2-Math.floor(a.time2);a.x=.00001<\\nMath.abs(bnot(a.q19))?a.xl:a.xw;a.y=.00001<Math.abs(bnot(a.q19))?a.yl:a.yw;a.ang=a.time*Math.sin(44*a.k1)*12;a.a=a.t1;a.border_a=0;a.a2=a.t2;a.rad=div(.01,a.dist);a.r=.5+.3*Math.sin(a.instance+a.arg);a.b=.5+.3*Math.sin(a.instance-2+a.arg);a.g=.5+.3*Math.sin(2*a.instance+a.arg);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.mq29=0;a.cthr=0;a.mq1=0;a.q25=0;a.q12=0;a.q22=0;a.q21=0;a.q13=0;a.q29=0;a.mq31=0;a.mq21=0;a.mq24=0;a.oldq8=0;a.chng=0;a.mq28=0;a.mq23=0;a.q31=0;a.q23=0;a.q24=0;a.q11=0;a.atime=0;a.q26=0;a.mq27=0;a.mq25=0;a.mq22=0;a.vol=0;a.mq26=0;a.q27=0;a.q28=0;a.q8=0;a.q8=0;\",frame_eqs_str:\"a.chng=Math.sin(.5*a.time);a.cthr=.9999;a.mq21=.00001<Math.abs(above(a.chng,a.cthr))?randint(3):a.mq21;a.mq22=.00001<Math.abs(above(a.chng,a.cthr))?randint(3):a.mq22;a.mq23=.00001<Math.abs(above(a.chng,a.cthr))?randint(3):a.mq23;a.mq24=.00001<Math.abs(above(a.chng,a.cthr))?randint(2):a.mq24;a.mq25=.00001<Math.abs(above(a.chng,a.cthr))?randint(2):a.mq25;a.mq26=.00001<Math.abs(above(a.chng,a.cthr))?randint(2):a.mq26;a.mq27=.00001<Math.abs(above(a.chng,a.cthr))?randint(1):a.mq27;\\na.mq28=.00001<Math.abs(above(a.chng,a.cthr))?randint(1):a.mq28;a.mq29=.00001<Math.abs(above(a.chng,a.cthr))?.3*randint(1):a.mq29;a.mq31=.00001<Math.abs(above(a.chng,a.cthr))?.3*randint(1):a.mq31;a.monitor=a.chng;a.q21=a.mq21;a.q22=a.mq22;a.q23=a.mq23;a.q24=a.mq24;a.q25=a.mq25;a.q26=a.mq26;a.q27=a.mq27;a.q28=a.mq28;a.q29=a.mq29;a.q31=a.mq31;a.monitor=a.mq1;a.vol=a.bass+a.treb+a.mid;a.atime+=a.vol;a.q11=.4+.4*Math.sin(.006*a.atime);a.q12=.4+.4*Math.cos(.00613828348*a.atime);a.q13=.4+.4*Math.sin(.00598593455*\\na.atime);a.monitor=a.q13;a.warp=0;a.q8=a.oldq8+.0003*div(pow(1+1.2*a.bass+.4*a.bass_att+.1*a.treb+.1*a.treb_att+.1*a.mid+.1*a.mid_att,6),a.fps);a.oldq8=a.q8;a.wave_r=.5+.5*Math.sin(1.123*a.q8);a.wave_g=.5+.5*Math.sin(1.576*a.q8);a.wave_b=.5+.5*Math.cos(1.465*a.q8);a.ib_a=.2*a.bass;\",pixel_eqs_str:\"a.dx=a.dx+.008*Math.sin((2*a.y-1)*a.meshx)+.008*Math.sin((2*a.y-1)*a.meshx*1.3333);a.dy=a.dy+.008*Math.cos((2*a.x-1)*a.meshx*1.3333)+.008*Math.cos((2*a.x-1)*a.meshx);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = tmpvar_2.xyz;\\n  vec4 tmpvar_3;\\n  tmpvar_3 = texture (sampler_noisevol_hq, (((vec3(0.05, 0.05, 0.0) * uv.xyy) * (\\n    (q27 * texsize.xyy)\\n   * texsize_noisevol_hq.zww)) + ((time * vec3(0.0, 0.0, 1.0)) * q29)));\\n  if (((tmpvar_2.x > (q21 * q13)) && (tmpvar_2.x <= (q24 * q11)))) {\\n    ret_1.y = (tmpvar_2.y - (tmpvar_3.x * 0.5));\\n  };\\n  if (((ret_1.y > (q22 * q11)) && (ret_1.y <= (q25 * q12)))) {\\n    ret_1.z = (tmpvar_2.z - (tmpvar_3.y * 0.5));\\n  };\\n  if (((ret_1.z > (q23 * q12)) && (ret_1.z <= (q26 * q13)))) {\\n    ret_1.x = (tmpvar_2.x - (tmpvar_3.z * 0.5));\\n  };\\n  ret_1 = (ret_1 + ((ret_1 - \\n    ((texture (sampler_blur1, uv).xyz * scale1) + bias1)\\n  ) * 0.2));\\n  ret_1 = (ret_1 - 0.02);\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = ret_1;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.05 + (0.9 * uv));\\n  vec4 tmpvar_3;\\n  tmpvar_3 = texture (sampler_main, uv_1);\\n  ret_2 = tmpvar_3.xyz;\\n  vec4 tmpvar_4;\\n  tmpvar_4 = texture (sampler_noisevol_hq, (((vec3(0.05, 0.05, 0.0) * uv_1.xyy) * (\\n    (q28 * texsize.xyy)\\n   * texsize_noisevol_hq.zww)) + ((time * vec3(0.0, 0.0, 1.0)) * q31)));\\n  if (((tmpvar_3.x > (q26 * q13)) && (tmpvar_3.x <= (q23 * q11)))) {\\n    ret_2.z = (tmpvar_3.z - (tmpvar_4.x * 0.5));\\n  };\\n  if (((tmpvar_3.y > (q25 * q11)) && (tmpvar_3.y <= (q22 * q12)))) {\\n    ret_2.x = (tmpvar_3.x - (tmpvar_4.y * 0.5));\\n  };\\n  if (((ret_2.z > (q24 * q12)) && (ret_2.z <= (q21 * q13)))) {\\n    ret_2.y = (tmpvar_3.y - (tmpvar_4.z * 0.5));\\n  };\\n  ret_2 = (abs((\\n    ((texture (sampler_blur1, uv_1).xyz * scale1) + bias1)\\n   - ret_2)) * 6.0);\\n  ret_2 = (ret_2 * 1.333);\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ret_2;\\n  ret = tmpvar_5.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.157,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.9995,warp:.009,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:.5,ob_r:.01,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_a:0,b1x:.7,b1ed:0},shapes:[{baseVals:{enabled:1,sides:14,num_inst:512,rad:.1026,tex_ang:.62832,r2:1,g2:0,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;a.r_border=0;a.g_border=0;a.b_border=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.rad=div(a.bass+a.treb,100);a.a=above(a.bass+a.mid+a.treb,.8);a.r=div(Math.floor(randint(100)),100);a.g=div(Math.floor(randint(100)),\\n100);a.b=div(Math.floor(randint(100)),100);a.r2=div(Math.floor(randint(100)),100);a.g2=div(Math.floor(randint(100)),100);a.b2=div(Math.floor(randint(100)),100);a.r_border=div(Math.floor(randint(100)),100);a.g_border=div(Math.floor(randint(100)),100);a.b_border=div(Math.floor(randint(100)),100);\"},{baseVals:{enabled:1,sides:23,num_inst:1024,rad:.10262,ang:.43982,tex_ang:.62832,a:.5,r2:1,g2:0,a2:.5,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;a.r_border=0;a.g_border=0;a.b_border=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.05*a.bass;a.ma-=3.1415*above(a.mid,1)*.05*a.mid;a.mx+=.0001*Math.cos(a.ma);a.my+=.0001*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.rad=div(a.bass+a.treb,75);a.a=above(a.bass+a.mid+a.treb,.1);a.r=div(Math.floor(randint(100)),100);a.g=div(Math.floor(randint(100)),\\n100);a.b=div(Math.floor(randint(100)),100);a.r2=div(Math.floor(randint(100)),100);a.g2=div(Math.floor(randint(100)),100);a.b2=div(Math.floor(randint(100)),100);a.r_border=div(Math.floor(randint(100)),100);a.g_border=div(Math.floor(randint(100)),100);a.b_border=div(Math.floor(randint(100)),100);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.n=0;a.z=0;a.n2=0;a.q25=0;a.w2=0;a.q22=0;a.q21=0;a.q29=0;a.j3=0;a.q1=0;a.n1=0;a.v=0;a.w3=0;a.q31=0;a.q23=0;a.q24=0;a.pi=0;a.pi2inv=0;a.j2=0;a.w1=0;a.zz=0;a.vol=0;a.j1=0;a.q27=0;a.maskangle=0;a.q3=0;a.q32=0;a.q28=0;a.q30=0;a.q20=0;a.mtime=0;a.x1=2;a.y1=2;a.z1=2;\",frame_eqs_str:\"a.d=20;a.z=4;a.zz=1+0*a.bass_att;a.pi=2*Math.asin(1);a.pi2inv=div(.5,a.pi);a.maskangle=Math.asin(div(1,a.d));a.q32=a.maskangle;a.q31=a.d;a.q30=a.z;a.q29=a.pi2inv;a.q28=a.pi;a.q27=div(1,a.zz);a.v=.4;a.j1=.95*a.j1+sqr(4*a.bass)*a.v;a.j2=.95*a.j2+sqr(4*a.mid)*a.v;a.j3=.95*a.j3+sqr(4*a.treb)*a.v;a.n+=.0152*a.j1;a.n1+=.0152*a.j2;a.n2+=.0152*a.j3;a.vol=.25*(a.bass+a.mid+a.treb);a.vol=a.vol;a.q3=a.vol;a.mtime+=.01*a.vol;a.q1=a.mtime;a.zoom+=.015*a.vol;a.w1=.01*a.n;a.w2=.01*a.n1;a.w3=\\n.01*a.n2;a.q20=Math.cos(a.w1);a.q21=Math.sin(a.w1);a.q22=Math.cos(a.w2);a.q23=Math.sin(a.w2);a.q24=Math.cos(a.w3);a.q25=Math.sin(a.w3);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = (((uv_orig * texsize.xy) * (texsize_noise_lq.zw * 1.5)) + rand_frame.xy);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ((texture (sampler_main, (\\n    mix (uv_orig, uv, vec2(((dot (texture (sampler_main, \\n      mix (uv_orig, uv, vec2(4.0, 4.0))\\n    ).xyz, vec3(0.32, 0.49, 0.29)) - dot (\\n      ((texture (sampler_blur2, mix (uv_orig, uv, vec2(-12.0, -12.0))).xyz * scale2) + bias2)\\n    , vec3(0.32, 0.49, 0.29))) * 12.0)))\\n   + \\n    (((texture (sampler_noise_lq, tmpvar_1) - 0.5).xy * texsize.zw) * 0.5)\\n  )).xyz + (\\n    (texture (sampler_noise_lq, tmpvar_1) - 0.5)\\n   * 0.006).xyz) + -0.0006);\\n  ret = tmpvar_2.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret2_2;\\n  vec2 uv2_3;\\n  vec3 ret_4;\\n  uv2_3.y = uv.y;\\n  uv2_3.x = (1.0 - uv.x);\\n  uv2_3 = (0.5 + ((uv2_3 - 0.5) * 0.98));\\n  uv_1 = (0.5 + ((uv - 0.5) * 0.98));\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (texsize.zw * 4.0);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(1.0, 0.0) * tmpvar_5))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(1.0, 0.0) * tmpvar_5))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_7;\\n  tmpvar_7 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(0.0, 1.0) * tmpvar_5))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(0.0, 1.0) * tmpvar_5))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_8;\\n  tmpvar_8.z = 0.0;\\n  tmpvar_8.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_8.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  vec4 tmpvar_9;\\n  tmpvar_9 = texture (sampler_noisevol_hq, ((vec3(0.05, 0.05, 0.0) * (\\n    ((uv_1.xyy + (tmpvar_8 * 0.5)) * texsize.xyy)\\n   * texsize_noisevol_hq.zww)) + (vec3(0.0, 0.0, 0.2) * time)));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = dot (tmpvar_6, vec3(0.32, 0.49, 0.29));\\n  tmpvar_10.y = dot (tmpvar_7, vec3(0.32, 0.49, 0.29));\\n  uv_1 = (uv_1 - (tmpvar_10 * 0.04));\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = dot (((\\n    (texture (sampler_blur1, (uv2_3 + (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (uv2_3 - (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  tmpvar_11.y = dot (((\\n    (texture (sampler_blur1, (uv2_3 + (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (uv2_3 - (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  uv2_3 = (uv2_3 - (tmpvar_11 * 0.04));\\n  ret_4 = (abs((\\n    ((texture (sampler_main, uv_1).xyz + ((texture (sampler_blur1, uv_1).xyz * scale1) + bias1)) - ((texture (sampler_blur2, uv_1).xyz * scale2) + bias2))\\n   - \\n    ((texture (sampler_blur3, uv_1).xyz * scale3) + bias3)\\n  )) * (dot (tmpvar_9, vec4(0.32, 0.49, 0.29, 0.0)) * 3.0));\\n  ret2_2 = (abs((\\n    ((texture (sampler_main, uv2_3).xyz + ((texture (sampler_blur1, uv2_3).xyz * scale1) + bias1)) - ((texture (sampler_blur2, uv2_3).xyz * scale2) + bias2))\\n   - \\n    ((texture (sampler_blur3, uv2_3).xyz * scale3) + bias3)\\n  )) * (dot (tmpvar_9, vec4(0.32, 0.49, 0.29, 0.0)) * 3.0));\\n  ret2_2 = (0.5 - pow (ret2_2, vec3(0.5, 0.5, 0.5)));\\n  ret_4 = (pow (ret_4, vec3(0.5, 0.5, 0.5)) - (0.3 - ret2_2));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = ret_4;\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:4,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken_center:1,darken:1,wave_a:.001,wave_scale:.527429,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:.442,warpscale:.498,zoom:.9999,warp:.01,sx:.9999,wave_r:.8,wave_g:.49,ob_size:0,ob_r:1,ob_g:1,ob_b:1,ob_a:.05,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,thickoutline:1,textured:1,x:.26,y:.2,rad:.393173,tex_zoom:1.392831,r:0,g:.55,b:.5,a:.9,g2:.4,b2:.4,border_r:.3,border_g:.7,border_b:.8,border_a:.2},init_eqs_str:\"a.g0=0;a.y0=0;a.q1=0;a.x0=0;a.q24=0;a.q26=0;a.r0=0;a.trig=0;a.q2=0;a.b0=0;a.rad0=0;\",frame_eqs_str:\"a.trig=a.q24;a.textured=1;a.x0=a.x0*bnot(a.trig)+a.trig*(.2+div(randint(100),200));a.y0=a.y0*bnot(a.trig)+a.trig*(.2+div(randint(100),200));a.x0+=div(.03*a.q1*(3+a.q26),a.fps);a.y0+=div(.03*a.q2*(3+a.q26),a.fps);a.x0-=Math.floor(a.x0);a.y0-=Math.floor(a.y0);a.tex_ang=a.time;a.ang=a.time*a.q2;a.x=a.x0;a.y=a.y0;a.rad0=a.rad0*bnot(a.trig)+div(a.trig*randint(100),200);a.rad=a.rad0;a.r0=a.r0*bnot(a.trig)+div(a.trig*randint(10),10);a.b0=a.b0*bnot(a.trig)+div(a.trig*randint(10),10);\\na.g0=a.g0*bnot(a.trig)+div(a.trig*randint(10),10);a.border_r=a.r0;a.border_g=a.g0;a.border_b=a.b0;a.r=a.r0;a.b=a.b0;a.g=a.g0;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.rm=0;a.ampl=0;a.index2=0;a.index=0;a.q18=0;a.q22=0;a.q21=0;a.movex=0;a.q1=0;a.dec_med=0;a.index3=0;a.trel=0;a.rott=0;a.ava=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.mov=0;a.avg=0;a.movez=0;a.q19=0;a.beat=0;a.q17=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.movey=0;a.q3=0;a.t0=0;a.q28=0;a.q30=0;a.q20=0;a.dirx=1;\",frame_eqs_str:\"a.dec_med=pow(.6,div(30,a.fps));a.dec_slow=pow(.9,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),4);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.q20=a.avg;a.q21=\\na.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.ava=a.ava*a.dec_slow+a.q26*(1-a.dec_slow);a.k1=a.is_beat*equal(mod(a.index,2),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,2);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.q27=8-a.index;a.q28=.5+div(Math.sin(div(a.time,7)),10);a.rm=Math.min(a.q26-1.5*a.ava,2);a.mov=a.is_beat*a.rm+(1-a.is_beat)*a.mov;a.movez+=div(.4,a.fps)*a.mov;a.q30=a.movez;a.ampl=\\ndiv(a.q26,8);a.movex+=div(.2,a.fps)*Math.sin(a.rott);a.movey+=div(.2,a.fps)*Math.cos(a.rott);a.q18=a.movex;a.q19=a.movey;a.trel=a.trel+div(1,a.fps)+a.q24;a.q17=2*Math.sin(div(a.trel,4));\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 uv6_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_4;\\n  tmpvar_4 = (((q28 * 2.0) * sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  )) + (rand_frame * 64.0)).x;\\n  uv_1 = (uv + (clamp (\\n    ((sin(tmpvar_4) / cos(tmpvar_4)) * normalize(tmpvar_3))\\n  , vec2(-16.0, -16.0), vec2(16.0, 16.0)) / 20.0));\\n  uv6_2 = (0.4 * sin((tmpvar_3 * 12.0)));\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = (((q24 * \\n    (((texture (sampler_main, uv_1).xyz - (\\n      ((texture (sampler_blur1, fract(uv_1)).xyz * scale1) + bias1)\\n     * 0.04)) + (0.15 * (vec3(\\n      (0.1 / sqrt(dot (uv6_2, uv6_2)))\\n    ) * roam_cos.xyz))) - 0.04)\\n  ) * 0.98) + ((1.0 - q24) * texture (sampler_main, uv_orig).xyz));\\n  ret = tmpvar_5.xyz;\\n }\",comp:\"vec3 xlat_mutableneu;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutablers2;\\n shader_body { \\n  vec2 uv_1;\\n  float inten_3;\\n  float dist_4;\\n  float ang2_5;\\n  vec2 uv2_6;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * aspect.xy);\\n  dist_4 = 1.0;\\n  inten_3 = 1.0;\\n  xlat_mutableret1 = vec3(0.0, 0.0, 0.0);\\n  for (float n_2 = 0.0; n_2 <= 4.0; n_2 += 1.0) {\\n    vec2 uv3_7;\\n    ang2_5 = ((6.28 * n_2) / 4.0);\\n    float tmpvar_8;\\n    tmpvar_8 = cos(ang2_5);\\n    float tmpvar_9;\\n    tmpvar_9 = sin(ang2_5);\\n    uv2_6.x = ((uv_1.x * tmpvar_8) - (uv_1.y * tmpvar_9));\\n    uv2_6.y = ((uv_1.x * tmpvar_9) + (uv_1.y * tmpvar_8));\\n    uv2_6 = (uv2_6 * aspect.yx);\\n    dist_4 = (1.0 - fract((\\n      (0.25 * n_2)\\n     + q30)));\\n    inten_3 = ((sqrt(dist_4) * (1.0 - dist_4)) * 4.0);\\n    vec2 tmpvar_10;\\n    tmpvar_10.x = tmpvar_8;\\n    tmpvar_10.y = tmpvar_9;\\n    uv3_7 = (fract((\\n      ((3.0 * uv2_6) * dist_4)\\n     + \\n      (0.3 * q27)\\n    )) + (q17 * tmpvar_10));\\n    xlat_mutableneu = (texture (sampler_main, uv3_7).xyz - ((texture (sampler_blur2, \\n      ((uv3_7 * 1.02) * q1)\\n    ).xyz * scale2) + bias2));\\n    xlat_mutableneu = (xlat_mutableneu * vec3(greaterThanEqual (xlat_mutableneu, vec3(0.0, 0.0, 0.0))));\\n    xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_3));\\n  };\\n  xlat_mutablers2 = ((0.4 * cos(\\n    ((uv_1 * 13.0) + time)\\n  )) - dot (xlat_mutableret1, vec3(0.32, 0.49, 0.29)));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = (xlat_mutableret1 + ((\\n    ((0.05 / sqrt(dot (xlat_mutablers2, xlat_mutablers2))) * q26)\\n   / 4.0) * hue_shader));\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:7,wave_dots:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.39158,wave_scale:.01,wave_smoothing:.504,wave_mystery:-1,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:.7,wave_g:0,ob_r:1,ob_g:1,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:5,additive:1,x:.9,rad:.22613,g:.6,g2:0,b2:.4,a2:.3,border_a:0},init_eqs_str:\"a.dx=0;a.dy=0;a.q22=0;a.q24=0;a.t_rel=5*a.time;a.t1=Math.floor(a.t_rel);\",frame_eqs_str:\"a.dx=div(randint(1E3),1E3)-.5;a.dy=div(randint(1E3),1E3)-.5;a.x=.5+a.dx*(1-div(a.q22,4));a.y=.5+a.dy*(1-div(a.q22,4));a.ang=a.time;a.a=1;a.rad=.1*a.q24+.08+div(a.q22,40);\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:256,spectrum:1,usedots:1,scaling:.5033,g:.6,b:.4},init_eqs_str:\"a.xang=0;a.ampl=0;a.fov=0;a.t1=0;a.yang=0;a.my=0;a.oz=0;a.t_rel=0;a.mz=0;a.q26=0;a.oy=0;a.mx=0;a.zang=0;a.t_abs=0;a.ox=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.t_abs=a.sample;a.t_rel=a.sample-div(a.time,1);a.ampl=a.time;a.ox=10*a.ampl*Math.sin(68*a.t_abs);a.oy=10*a.ampl*Math.cos(28*a.t_abs);a.oz=10*a.ampl*Math.cos(128*a.t_abs);a.r=1;a.g=.5;a.b=1;a.a=div(a.q26,18);a.xang=a.t1;a.yang=2*a.t1;a.zang=a.t1;a.fov=.12;a.mx=a.ox*Math.cos(a.zang)-a.oy*Math.sin(a.zang);a.my=a.ox*Math.sin(a.zang)+a.oy*Math.cos(a.zang);a.ox=a.mx;a.oy=a.my;a.mx=a.ox*Math.cos(a.yang)+a.oz*Math.sin(a.yang);a.mz=-a.ox*Math.sin(a.yang)+a.oz*Math.cos(a.yang);a.ox=\\na.mx;a.oz=a.mz;a.my=a.oy*Math.cos(a.xang)-a.oz*Math.sin(a.xang);a.mz=a.oy*Math.sin(a.xang)+a.oz*Math.cos(a.xang);a.oy=a.my;a.oz=a.mz;a.oz-=6;a.x=div(a.ox*a.fov,a.oz)+.5;a.y=div(a.oy*a.fov,a.oz)+.5;\"},{baseVals:{enabled:1},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"a.a=Math.max(Math.sin(div(a.time,8))-.5,0);a.r=.4;a.g=.2;a.b=.7;a.x=a.sample+.01*Math.cos(243*a.sample+a.time);a.y=.5+.5*Math.sin(div(a.time,13))+.02*Math.sin(143*a.sample);a.a=.7;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index4=0;a.index=0;a.q22=0;a.q21=0;a.q29=0;a.q1=0;a.dec_med=0;a.index3=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.t_rel=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.movez=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q28=0;a.q20=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),4);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.q20=a.avg;a.q21=\\na.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_slow*a.p2+(1-a.dec_slow)*a.p1;a.rott=div(3.14159265359*a.p2,2);a.q27=8-a.index;a.q28=.5+div(Math.sin(div(a.time,7)),10);a.q29=a.index4;a.mv_a=.2;a.t_rel=div(a.time,3);a.wave_a=Math.max(Math.sin(div(a.time,8))-.5,0);a.wave_a=0;a.wave_x=.5+.5*Math.sin(div(a.time,13));a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.movez+=div(.3,a.fps);\\na.q29=a.movez;a.zoom=1;a.rot=0;a.dx=.003;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = (((uv - vec2(0.5, 0.5)) * texsize.xy) * 0.03);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ((0.99 * texture (sampler_main, (uv + \\n    (((clamp (\\n      (sin(tmpvar_1) / cos(tmpvar_1))\\n    , vec2(-12.0, -12.0), vec2(12.0, 12.0)) * cos(\\n      (tmpvar_1.yx * tmpvar_1.yx)\\n    )) * texsize.zw) * 12.0)\\n  )).xyz) - 0.01);\\n  ret = tmpvar_2.xyz;\\n }\",comp:\"vec3 xlat_mutableret1;\\nvec2 xlat_mutableuv2;\\n shader_body { \\n  vec2 uv_1;\\n  float inten_2;\\n  float dist_3;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * aspect.xy);\\n  dist_3 = (1.0 - fract((0.25 + q29)));\\n  inten_2 = (sqrt(dist_3) * (1.0 - (dist_3 * dist_3)));\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (texture (sampler_main, fract(\\n    (((2.0 * uv_1) * dist_3) + 0.5)\\n  )).xyz * inten_2));\\n  xlat_mutableuv2.x = -(uv_1.y);\\n  xlat_mutableuv2.y = uv_1.x;\\n  dist_3 = (1.0 - fract((0.5 + q29)));\\n  inten_2 = (sqrt(dist_3) * (1.0 - (dist_3 * dist_3)));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, fract(\\n    (((2.0 * xlat_mutableuv2) * dist_3) + 0.5)\\n  )).xyz * inten_2));\\n  dist_3 = (1.0 - fract((0.75 + q29)));\\n  inten_2 = (sqrt(dist_3) * (1.0 - (dist_3 * dist_3)));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, fract(\\n    (((2.0 * uv_1) * dist_3) + 0.5)\\n  )).xyz * inten_2));\\n  xlat_mutableuv2.x = -(uv_1.y);\\n  xlat_mutableuv2.y = uv_1.x;\\n  dist_3 = (1.0 - fract((1.0 + q29)));\\n  inten_2 = (sqrt(dist_3) * (1.0 - (dist_3 * dist_3)));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, fract(\\n    (((2.0 * xlat_mutableuv2) * dist_3) + 0.5)\\n  )).xyz * inten_2));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = (xlat_mutableret1 * 3.0);\\n  ret = tmpvar_4.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.980001,decay:.5,echo_zoom:.952379,echo_alpha:.5,echo_orient:3,wave_mode:4,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.391579,wave_scale:1.575857,wave_smoothing:.45,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:.5,wave_g:.79,ob_size:0,ob_a:.8,ib_size:.26,mv_x:31.999998,mv_y:24.000004,mv_l:.05,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,textured:1,rad:.545996,ang:2.199115,tex_ang:.502655,tex_zoom:2.02311,g:1,b:.9,a:.6,r2:.8,g2:.8,b2:.8,a2:.6,border_b:0,border_a:.7},init_eqs_str:\"a.q29=0;a.q22=0;a.q23=0;a.q24=0;\",frame_eqs_str:\"a.tex_ang=1+Math.sin(div(a.time,9));a.rad=a.q29;a.tex_zoom=2+Math.sin(div(a.time,17));a.additive=div(a.q22,6);a.textured=1-bnot(a.q23)*a.q24;\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:100,x:.503,rad:.01,tex_zoom:.609857,g:.1,a:.9,r2:1,b2:1,border_r:.5,border_g:.5,border_b:.5,border_a:0},init_eqs_str:\"a.q21=0;\",frame_eqs_str:\"a.x=.5+div(randint(10),25);a.y=.5+div(randint(10),25);a.ang=randint(6);a.r=div(randint(4),3);a.g=div(randint(4),3);a.b=div(randint(4),3);a.r2=a.b;a.g2=a.r;a.b2=a.g;a.a=Math.min(div(a.q21,2),.9);a.rad=div(a.a,9);a.a=.5;a.a2=.8;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index=0;a.copy=0;a.q22=0;a.q21=0;a.grid=0;a.q29=0;a.q1=0;a.dec_med=0;a.str=0;a.index3=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.go=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.movez=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.p3=0;a.q3=0;a.t0=0;a.rot1=0;a.q28=0;a.q30=0;a.q20=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,4);a.index2=mod(a.index2+a.is_beat*bnot(a.index),4);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.q20=a.avg;a.q21=\\na.beat;a.q22=Math.max(a.peak,4);a.q23=a.index;a.q24=a.is_beat;a.q26=Math.max(a.bass+a.mid+a.treb,3);a.go=a.go*a.dec_slow+(1-a.dec_slow)*equal(a.index2,2);a.movez+=div(3*(1+.3*a.q26),a.fps)*a.go;a.q30=a.movez;a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.p3=a.dec_med*a.p3+(1-a.dec_med)*a.p2;a.rott=div(3.1416*a.p3,2);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.str=a.str*a.dec_slow+(1-a.dec_slow)*a.index3;a.q27=4-a.str;\\na.grid=a.grid*a.dec_med+(1-a.dec_med)*equal(a.index2,2)*bnot(a.index);a.mv_a=.6*a.grid;a.rot1=a.dec_med*a.rot1+(1-a.dec_med)*bnot(a.index2);a.q28=a.rot1;a.copy=a.copy*a.dec_slow+(1-a.dec_slow)*a.index3;a.q29=.3*a.copy;\",pixel_eqs_str:\"a.dx=.02*a.q28;a.rot=.04*a.q2;a.zoom=.96+.1*Math.sin(div(a.time,7));\",warp:\" shader_body { \\n  vec2 zz_1;\\n  mat2 tmpvar_2;\\n  tmpvar_2[uint(0)] = _qa.xy;\\n  tmpvar_2[1u] = _qa.zw;\\n  zz_1 = (((\\n    (uv - vec2(0.5, 0.5))\\n   * texsize.xy) * 0.01) * tmpvar_2);\\n  zz_1 = -(zz_1.yx);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ((texture (sampler_main, (uv + \\n    (((clamp (\\n      (sin(zz_1.yx) / cos(zz_1.yx))\\n    , vec2(-8.0, -8.0), vec2(8.0, 8.0)) * cos(\\n      (4.0 * zz_1)\\n    )) * texsize.zw) * 16.0)\\n  )).xyz * 0.99) - 0.01);\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv3_1;\\n  vec2 uv2_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_4;\\n  tmpvar_4 = (0.1 / (sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  ) + 0.1));\\n  vec2 tmpvar_5;\\n  float tmpvar_6;\\n  tmpvar_6 = (ang / 3.14);\\n  tmpvar_5.x = tmpvar_6;\\n  tmpvar_5.y = (q27 * tmpvar_4);\\n  uv2_2.y = (tmpvar_5.y + (0.1 * q30));\\n  uv2_2.x = (tmpvar_6 + (0.2 * time));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_6;\\n  tmpvar_7.y = (4.0 * tmpvar_4);\\n  uv3_1.y = (tmpvar_7.y - (0.2 * q30));\\n  uv3_1.x = tmpvar_7.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = fract(uv3_1);\\n  uv3_1 = tmpvar_8;\\n  float tmpvar_9;\\n  tmpvar_9 = clamp ((1.0 - (4.0 * rad)), 0.0, 1.0);\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = (((\\n    (3.0 * max (((2.0 * texture (sampler_main, uv2_2).xyz) + texture (sampler_main, tmpvar_8).xyz), ((2.0 * \\n      ((texture (sampler_blur2, fract(uv2_2)).xyz * scale2) + bias2)\\n    ) + (\\n      (texture (sampler_blur2, fract(tmpvar_8)).xyz * scale2)\\n     + bias2))))\\n   * rad) + (\\n    ((uv.y * pow ((1.0 - rad), 8.0)) * roam_cos)\\n  .xyz * tmpvar_9)) + ((tmpvar_9 * 2.0) * (\\n    (texture (sampler_blur1, fract(uv)).xyz * scale1)\\n   + bias1)));\\n  ret = tmpvar_10.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:6,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,darken_center:1,darken:1,wave_a:.001,wave_scale:.236,wave_smoothing:0,wave_mystery:-.64,modwavealphastart:.81,modwavealphaend:1.4,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_b:.6,ob_size:.005,ob_a:.8,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:18,num_inst:4,x:.83,rad:.14349,tex_ang:3.76991,tex_zoom:5.27784,r:0,g:1,b:1,a:.5,r2:1,g2:.2,b2:1,border_b:0,border_a:0},init_eqs_str:\"a.d=0;a.k1=0;a.q22=0;a.q27=0;a.r0=0;a.q24=0;a.g0=0;a.b0=0;\",frame_eqs_str:\"a.d=.3+.2*div(mod(a.frame,8),8);a.k1=6.28*div(a.instance,a.num_inst);a.d=.3+div(a.q22,8);a.x=.5+a.d*Math.cos(a.k1);a.y=.5+a.d*Math.sin(a.k1);a.a=Math.min(1,.2+div(.8*a.q22,2)*mod(a.q27,2));a.a2=0;a.r=.6+.4*Math.sin(div(a.time,4)+1.56);a.b=.6+.4*Math.sin(div(a.time,4)+3.14);a.g=.6+.4*Math.sin(div(a.time,4));a.r0=a.r0*bnot(a.q24)+(.5+.5*Math.sin(a.time))*a.q24;a.g0=a.g0*bnot(a.q24)+(.5+.5*Math.sin(1.7*a.time))*a.q24;a.b0=div(2-a.r0-a.g0,2);a.r=a.r0;a.b=a.b0;a.g=a.g0;a.r2=1-a.g;\\na.g2=1-a.b;a.b2=1-a.r;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:128,scaling:.89152,smoothing:0},init_eqs_str:\"a.q22=0;a.q27=0;a.q24=0;a.t1=0;a.t2=0;a.r0=0;a.g0=0;\",frame_eqs_str:\"a.t1=a.t1*bnot(a.q24)+(.5+.5*Math.sin(a.time))*a.q24;a.t2=a.t2*bnot(a.q24)+(.5+.5*Math.sin(1.7*a.time))*a.q24;\",point_eqs_str:\"a.x=a.sample;a.y=.5;a.a=a.q22*mod(a.q27+1,2);a.a=div(a.q24*mod(a.q27+1,2),2)+0;a.r=a.t1;a.b=a.t2;a.g=div(2-a.r0-a.g0,2);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.speed_=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q13=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.movz=0;a.trel=0;a.q9=0;a.rott=0;a.spg=0;a.vol__=0;a.is_beat=0;a.q31=0;a.k1=0;a.q24=0;a.vx=0;a.dec_slow=0;a.vy=0;a.vz=0;a.q4=0;a.dir=0;a.p2=0;a.avg=0;a.trig=0;a.beat=0;a.q17=0;a.vol=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.speed=0;a.q3=0;a.t0=0;a.vol_=0;a.q7=0;a.q28=0;a.q30=0;a.q20=0;a.q8=0;a.ang0=0;a.speed_=1;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.96,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.1);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,12);a.index2=mod(a.index2+a.is_beat*bnot(a.index),8);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q24=a.is_beat;a.vol=div(a.bass_att+a.mid_att+\\na.treb_att,2);a.vol_=a.dec_med*a.vol_+(1-a.dec_med)*a.vol;a.vol__=a.dec_med*a.vol__+(1-a.dec_med)*a.vol_;a.q27=a.index+1;a.q28=a.index2+2;a.k1=a.is_beat*equal(mod(a.index,4),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.trig=a.q24*bnot(mod(a.index,8));a.vx=a.vx*bnot(a.trig)+a.trig*(div(randint(100),100)-.5);a.vy=a.vy*bnot(a.trig)+a.trig*(div(randint(100),100)-.5);a.vz=a.vz*bnot(a.trig)+\\na.trig*(div(randint(100),100)-.5);a.speed=Math.min(a.vol_-a.vol__+.5,1);a.speed=Math.max(a.speed,-.5);a.speed_=bnot(a.trig)*a.speed_+a.trig*a.speed;a.spg=a.dec_med*a.spg+(1-a.dec_med)*a.speed_;a.movz+=div(1,a.fps)*(a.speed_+div(0*a.vol_,6));a.q9=a.movz;a.q12=2*Math.min(a.q22,6);a.q13=2*Math.sin(div(a.movz,3)-div(a.time,11));a.trig=bnot(mod(a.index,4))*a.q24;a.dir=bnot(a.trig)*a.dir+a.trig*(randint(10)-5);a.trel+=div(.1,a.fps)*a.dir;a.q5=Math.cos(a.trel-a.movz);a.q6=Math.sin(div(a.trel,2)-a.movz);\\na.q7=-a.q6;a.q8=a.q5;a.ang0=a.ang0*a.dec_med+a.vz*(1-a.dec_med);a.q17=2*a.ang0;a.q30=.2*Math.sin(div(a.time,8));a.q31=.5+.5*Math.sin(div(a.time,3.3));a.zoom=1;a.rot=0;a.dx=0;a.monitor=a.q28;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"vec3 xlat_mutablemus;\\n shader_body { \\n  vec2 d_1;\\n  vec2 uv6_2;\\n  vec2 uv1_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv - 0.5);\\n  uv1_3 = tmpvar_4;\\n  uv6_2 = tmpvar_4;\\n  float x_5;\\n  x_5 = (abs(tmpvar_4.x) - abs(tmpvar_4.y));\\n  float tmpvar_6;\\n  tmpvar_6 = (12.0 * sqrt((x_5 * x_5)));\\n  vec2 tmpvar_7;\\n  tmpvar_7 = normalize(tmpvar_4);\\n  d_1 = tmpvar_7;\\n  float tmpvar_8;\\n  tmpvar_8 = (float(mod (q28, 2.0)));\\n  if ((tmpvar_8 == 0.0)) {\\n    d_1 = ((q1 * tmpvar_7) - (q2 / tmpvar_7));\\n  };\\n  uv1_3 = (tmpvar_4 + ((-0.06 * \\n    dot (((texture (sampler_blur1, uv).xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29))\\n  ) * normalize(tmpvar_4)));\\n  uv1_3 = (uv1_3 - (clamp (\\n    ((sin(tmpvar_6) / cos(tmpvar_6)) * d_1)\\n  , vec2(-4.0, -4.0), vec2(4.0, 4.0)) / 60.0));\\n  uv6_2 = (0.4 * cos((\\n    (uv1_3 * 2.0)\\n   * q28)));\\n  xlat_mutablemus = (clamp (vec3((0.0006 / \\n    (sqrt(dot (uv6_2, uv6_2)) - (0.002 * (q27 + (8.0 * q28))))\\n  )), 0.0, 1.0) * q31);\\n  xlat_mutablemus = (xlat_mutablemus * (1.0 + roam_cos).xyz);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = ((0.4 * (\\n    ((texture (sampler_main, ((uv1_3 * \\n      (0.8 + (0.2 * tmpvar_6))\\n    ) + 0.5)).xyz + xlat_mutablemus) * 0.95)\\n   - 0.025)) + (0.6 * texture (sampler_main, uv_orig)).xyz);\\n  ret = tmpvar_9.xyz;\\n }\",comp:\"vec3 xlat_mutableneu;\\nvec3 xlat_mutableret2;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutablerss;\\nvec2 xlat_mutableuv2;\\n shader_body { \\n  vec2 uv_1;\\n  vec2 ofs_2;\\n  vec3 ret1_3;\\n  vec2 uv5_4;\\n  uv_1 = ((uv - 0.5) * aspect.xy);\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = q5;\\n  tmpvar_5.y = q6;\\n  uv_1 = (uv_1 + (tmpvar_5 / 4.0));\\n  uv5_4 = uv_1;\\n  mat2 tmpvar_6;\\n  tmpvar_6[uint(0)] = _qb.xy;\\n  tmpvar_6[1u] = _qb.zw;\\n  uv_1 = (uv_1 * tmpvar_6);\\n  float tmpvar_7;\\n  float tmpvar_8;\\n  tmpvar_8 = (min (abs(\\n    (uv5_4.y / uv5_4.x)\\n  ), 1.0) / max (abs(\\n    (uv5_4.y / uv5_4.x)\\n  ), 1.0));\\n  float tmpvar_9;\\n  tmpvar_9 = (tmpvar_8 * tmpvar_8);\\n  tmpvar_9 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_9) + 0.05368138) * tmpvar_9) - 0.1173503)\\n     * tmpvar_9) + 0.1938925) * tmpvar_9) - 0.3326756)\\n   * tmpvar_9) + 0.9999793) * tmpvar_8);\\n  tmpvar_9 = (tmpvar_9 + (float(\\n    (abs((uv5_4.y / uv5_4.x)) > 1.0)\\n  ) * (\\n    (tmpvar_9 * -2.0)\\n   + 1.570796)));\\n  tmpvar_7 = (tmpvar_9 * sign((uv5_4.y / uv5_4.x)));\\n  if ((abs(uv5_4.x) > (1e-08 * abs(uv5_4.y)))) {\\n    if ((uv5_4.x < 0.0)) {\\n      if ((uv5_4.y >= 0.0)) {\\n        tmpvar_7 += 3.141593;\\n      } else {\\n        tmpvar_7 = (tmpvar_7 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_7 = (sign(uv5_4.y) * 1.570796);\\n  };\\n  xlat_mutablers0.x = (((tmpvar_7 / 3.1416) * 6.0) * q28);\\n  float tmpvar_10;\\n  tmpvar_10 = (1.5 / sqrt(dot (uv_1, uv_1)));\\n  xlat_mutablers0.y = tmpvar_10;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = (xlat_mutablers0.x + (q9 * 4.0));\\n  tmpvar_11.y = (tmpvar_10 + ((q9 * q28) * 4.0));\\n  xlat_mutablerss = (tmpvar_11 / 12.0);\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = q5;\\n  tmpvar_12.y = q6;\\n  ofs_2 = (0.1 * tmpvar_12.yx);\\n  float tmpvar_13;\\n  float tmpvar_14;\\n  tmpvar_14 = -(q9);\\n  tmpvar_13 = fract(tmpvar_14);\\n  mat2 tmpvar_15;\\n  tmpvar_15[uint(0)].x = 1.0;\\n  tmpvar_15[uint(0)].y = -0.0;\\n  tmpvar_15[1u].x = 0.0;\\n  tmpvar_15[1u].y = 1.0;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_13)\\n   * tmpvar_15)) * aspect.yx);\\n  xlat_mutableneu = (3.0 * texture (sampler_main, fract((\\n    (xlat_mutableuv2 + 0.5)\\n   + ofs_2)))).xyz;\\n  ret1_3 = max (vec3(0.0, 0.0, 0.0), (xlat_mutableneu * (1.0 - \\n    (tmpvar_13 * tmpvar_13)\\n  )));\\n  float tmpvar_16;\\n  tmpvar_16 = fract((tmpvar_14 + 0.3333333));\\n  mat2 tmpvar_17;\\n  tmpvar_17[uint(0)].x = -0.4990803;\\n  tmpvar_17[uint(0)].y = -0.8665558;\\n  tmpvar_17[1u].x = 0.8665558;\\n  tmpvar_17[1u].y = -0.4990803;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_16)\\n   * tmpvar_17)) * aspect.yx);\\n  xlat_mutableneu = (3.0 * texture (sampler_main, fract((\\n    (xlat_mutableuv2 + 0.5)\\n   + ofs_2)))).xyz;\\n  ret1_3 = max (ret1_3, (xlat_mutableneu * (1.0 - \\n    (tmpvar_16 * tmpvar_16)\\n  )));\\n  float tmpvar_18;\\n  tmpvar_18 = fract((tmpvar_14 + 0.6666667));\\n  mat2 tmpvar_19;\\n  tmpvar_19[uint(0)].x = -0.5018377;\\n  tmpvar_19[uint(0)].y = 0.8649619;\\n  tmpvar_19[1u].x = -0.8649619;\\n  tmpvar_19[1u].y = -0.5018377;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_18)\\n   * tmpvar_19)) * aspect.yx);\\n  xlat_mutableneu = (3.0 * texture (sampler_main, fract((\\n    (xlat_mutableuv2 + 0.5)\\n   + ofs_2)))).xyz;\\n  ret1_3 = max (ret1_3, (xlat_mutableneu * (1.0 - \\n    (tmpvar_18 * tmpvar_18)\\n  )));\\n  float tmpvar_20;\\n  tmpvar_20 = fract((tmpvar_14 + 1.0));\\n  mat2 tmpvar_21;\\n  tmpvar_21[uint(0)].x = 0.9999949;\\n  tmpvar_21[uint(0)].y = 0.003185092;\\n  tmpvar_21[1u].x = -0.003185092;\\n  tmpvar_21[1u].y = 0.9999949;\\n  xlat_mutableuv2 = ((uv_1 * (\\n    (q13 * tmpvar_20)\\n   * tmpvar_21)) * aspect.yx);\\n  xlat_mutableneu = (3.0 * texture (sampler_main, fract((\\n    (xlat_mutableuv2 + 0.5)\\n   + ofs_2)))).xyz;\\n  ret1_3 = max (ret1_3, (xlat_mutableneu * (1.0 - \\n    (tmpvar_20 * tmpvar_20)\\n  )));\\n  vec2 tmpvar_22;\\n  tmpvar_22.x = (ret1_3.x + ret1_3.z);\\n  tmpvar_22.y = (ret1_3.x - ret1_3.y);\\n  xlat_mutableret2 = (((\\n    (texture (sampler_blur1, fract((xlat_mutablerss + (tmpvar_22 / 2.0)))).xyz * scale1)\\n   + bias1) / tmpvar_10) * 12.0);\\n  vec4 tmpvar_23;\\n  tmpvar_23.w = 1.0;\\n  tmpvar_23.xyz = ((ret1_3 + (\\n    ((bass_att * 0.004) / sqrt(dot (uv_1, uv_1)))\\n   * roam_sin).xyz) + (sqrt(xlat_mutableret2.zxy) * clamp (\\n    (1.0 - (ret1_3 * 4.0))\\n  , 0.0, 1.0)));\\n  ret = tmpvar_23.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:2,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.958,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ob_g:.1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:25.6,mv_y:9.6,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.n=0;a.reg26=0;a.uvx0=0;a.reg34=0;a.reg28=0;a.reg23=0;a.q25=0;a.angchg=0;a.reg20=0;a.reg15=0;a.reg10=0;a.q12=0;a.v3=0;a.q22=0;a.q21=0;a.diry=0;a.q13=0;a.q6=0;a.posx=0;a.fps_=0;a.reg25=0;a.uvx=0;a.q1=0;a.travel=0;a.posz=0;a.q5=0;a.movz=0;a.dirz=0;a.dec_s=0;a.reg16=0;a.slow=0;a.reg36=0;a.reg22=0;a.uvy=0;a.rotz=0;a.dist_=0;a.q23=0;a.q24=0;a.reg24=0;a.cran0=0;a.vx=0;a.ran2=0;a.q11=0;a.q10=0;a.reg14=0;a.posy=0;a.vy=0;a.vz=0;a.reg31=0;a.dirx=0;a.dec_m=0;a.q4=0;a.start=0;a.reg12=\\n0;a.reg13=0;a.c2=0;a.reg37=0;a.s3=0;a.yslope=0;a.q16=0;a.xslope=0;a.q26=0;a.reg38=0;a.reg35=0;a.reg11=0;a.tx=0;a.avg=0;a.uvz=0;a.c3=0;a.uvy0=0;a.reg27=0;a.q19=0;a.beat=0;a.q17=0;a.vol=0;a.reg32=0;a.reg21=0;a.uvz0=0;a.len=0;a.reg18=0;a.reg30=0;a.q27=0;a.slen=0;a.q14=0;a.dist=0;a.reg17=0;a.v1=0;a.speed=0;a.s1=0;a.t0=0;a.s2=0;a.ran1=0;a.reg33=0;a.q7=0;a.ds=0;a.q28=0;a.ty=0;a.c1=0;a.v2=0;a.q20=0;a.q8=0;a.avg=.01;a.q7=.2;a.q8=div(randint(200),100)-1;a.q16=1.2;a.q18=randint(.8)+.1;a.q17=2.6;a.start=1;a.travel=\\n0;a.rotz=0;a.look=0;a.slow=0;a.t0=a.time+3;a.lampx=.5;a.lampy=.5;a.cran0=randint(1);for(var b=a.n=0;1E4>b;b++)a.gmegabuf[Math.floor(a.n)]=0,a.n+=1;for(b=a.n=0;1E4>b;b++)a.megabuf[Math.floor(a.n)]=0,a.n+=1;a.trelx=0;a.trely=0;a.trelz=0;a.reg20=1;a.reg21=0;a.reg22=0;a.reg23=0;a.reg24=1;a.reg25=0;a.reg26=0;a.reg27=0;a.reg28=1;b=0;do{b+=1;var c;a.ran1=div(randint(800),100);a.ran2=div(randint(800),100);a.ran3=div(randint(800),100);a.posx=randint(10)-5;a.posy=randint(10)-5;a.posz=randint(10)-5;a.c1=Math.cos(a.ran1);\\na.c2=Math.cos(a.ran2);a.c3=Math.cos(a.ran3);a.s1=Math.sin(a.ran1);a.s2=Math.sin(a.ran2);a.s3=Math.sin(a.ran3);a.reg20=a.c2*a.c1;a.reg21=a.c2*a.s1;a.reg22=-a.s2;a.reg23=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg24=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg25=a.s3*a.c2;a.reg26=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg27=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg28=a.c3*a.c2;a.dist=.001;var d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,\\n8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=\\na.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)*a.q17+a.uvx0,a.uvy=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)*a.q17+a.uvy0,a.uvz=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)*a.q17+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.05;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(c)&&\\n1048576>d);d=.06>a.dist?1:0}while(.00001<Math.abs(d)&&1048576>b);\",frame_eqs_str:\"a.fps_=0*a.fps_+1*(.00001<Math.abs(25>=a.fps?1:0)?a.fps:25+.5*(a.fps-25));a.dec_s=1-div(.03*30,a.fps_);a.dec_m=1-div(3,a.fps_);a.beat=a.time>a.t0+3?1:0;a.t0=.00001<Math.abs(a.beat)?a.time:a.t0;a.speed=div(Math.min(.2,a.dist_-.02)*(1+2*a.avg)*(1-0*a.slow)*.1,a.q7);a.ds=a.ds*a.dec_s+div((1-a.dec_s)*a.speed*.4,a.fps_);a.rotz=.00001<Math.abs(2<a.travel?1:0)?.5:0;a.vol=a.vol*a.dec_m+div((1-a.dec_m)*(a.bass_att+a.mid_att+a.treb_att),4);a.q1=div(a.vol,2)+.3;a.dirx=a.reg26;a.diry=a.reg27;\\na.dirz=a.reg28;a.posx+=a.ds*a.dirx;a.posy+=a.ds*a.diry;a.posz+=a.ds*a.dirz;a.q4=a.posx;a.q5=a.posy;a.q6=a.posz;a.angchg=(.1-a.dist_)*(.1>a.dist_?1:0);a.travel=.00001<Math.abs(0<a.angchg?1:0)?0:a.travel+a.ds;a.v1=a.v1*a.dec_s+div((1-a.dec_s)*a.rotz*a.ds,2);a.v2=a.v2*a.dec_s+div((1-a.dec_s)*a.angchg*a.xslope,a.fps_);a.v3=a.v3*a.dec_s+(1-a.dec_s)*(div(a.angchg*a.yslope,a.fps_)+2*a.v1*Math.sin(.1*a.time));a.reg30=a.reg20;a.reg31=a.reg21;a.reg32=a.reg22;a.reg33=a.reg23;a.reg34=a.reg24;a.reg35=a.reg25;\\na.reg36=a.reg26;a.reg37=a.reg27;a.reg38=a.reg28;a.n=0;for(var b=a.avg=0;5>b;b++){a.n+=1;a.ran1=div(randint(100),100);a.ran2=div(randint(100),200)-.25;a.tx=Math.cos(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.ty=Math.sin(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.c1=Math.cos(a.v1);a.c2=Math.cos(a.v2+a.ty);a.c3=Math.cos(a.v3+a.tx);a.s1=Math.sin(a.v1);a.s2=Math.sin(a.v2+a.ty);a.s3=Math.sin(a.v3+a.tx);a.reg10=a.c2*a.c1;a.reg11=a.c2*a.s1;a.reg12=-a.s2;a.reg13=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg14=a.s3*a.s2*a.s1+a.c3*\\na.c1;a.reg15=a.s3*a.c2;a.reg16=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg17=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg18=a.c3*a.c2;a.reg20=a.reg30;a.reg21=a.reg31;a.reg22=a.reg32;a.reg23=a.reg33;a.reg24=a.reg34;a.reg25=a.reg35;a.reg26=a.reg36;a.reg27=a.reg37;a.reg28=a.reg38;a.q20=a.reg10*a.reg20+a.reg11*a.reg23+a.reg12*a.reg26;a.q21=a.reg10*a.reg21+a.reg11*a.reg24+a.reg12*a.reg27;a.q22=a.reg10*a.reg22+a.reg11*a.reg25+a.reg12*a.reg28;a.q23=a.reg13*a.reg20+a.reg14*a.reg23+a.reg15*a.reg26;a.q24=a.reg13*a.reg21+a.reg14*a.reg24+\\na.reg15*a.reg27;a.q25=a.reg13*a.reg22+a.reg14*a.reg25+a.reg15*a.reg28;a.q26=a.reg16*a.reg20+a.reg17*a.reg23+a.reg18*a.reg26;a.q27=a.reg16*a.reg21+a.reg17*a.reg24+a.reg18*a.reg27;a.q28=a.reg16*a.reg22+a.reg17*a.reg25+a.reg18*a.reg28;a.reg20=a.q20;a.reg21=a.q21;a.reg22=a.q22;a.reg23=a.q23;a.reg24=a.q24;a.reg25=a.q25;a.reg26=a.q26;a.reg27=a.q27;a.reg28=a.q28;a.dist=.002;var c,d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=\\na.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>\\na.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)*a.q17+a.uvx0,a.uvy=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)*a.q17+a.uvy0,a.uvz=(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)*a.q17+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.1;c=(.6>a.dist?1:0)*(30<a.len?\\n1:0)}while(.00001<Math.abs(c)&&1048576>d);a.megabuf[Math.floor(a.n)]=a.megabuf[Math.floor(a.n)]*a.dec_s+(1-a.dec_s)*a.dist;a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5))}a.n=0;for(b=a.avg=0;5>b;b++)a.n+=1,a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5));a.xslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[1]-a.megabuf[3]),-3),3);a.yslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[4]-a.megabuf[2]),-3),3);a.monitor=a.avg;a.dist_=a.dist_*a.dec_s+(1-a.dec_s)*a.dist;a.q10=a.ds*a.q7;a.q14=Math.abs(a.ds)+\\n2*(Math.abs(a.v1)+Math.abs(a.v2)+Math.abs(a.v3))+.05*a.start;a.q19=.6+.4*Math.sin(.02*a.time+6*a.cran0);a.start*=.9;a.warp=0;a.zoom=1;a.dx=div(-a.v2,a.q16);a.dy=div(a.v3,a.q16);a.rot=a.v1;a.vx-=div(a.v2,a.q16);a.vy+=div(a.v3,a.q16);a.vz+=a.v1;a.q11=a.vx;a.q12=a.vy;a.movz+=a.ds;a.q13=a.movz;a.monitor=a.q13;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"float sustain;\\nfloat ffac;\\nfloat xlat_mutabledist;\\nfloat xlat_mutablelimit;\\nfloat xlat_mutablestruc;\\nvec2 xlat_mutableuv1;\\nvec3 xlat_mutableuv2;\\n shader_body { \\n  mat3 tmpvar_1;\\n  tmpvar_1[uint(0)].x = q20;\\n  tmpvar_1[uint(0)].y = q23;\\n  tmpvar_1[uint(0)].z = q26;\\n  tmpvar_1[1u].x = q21;\\n  tmpvar_1[1u].y = q24;\\n  tmpvar_1[1u].z = q27;\\n  tmpvar_1[2u].x = q22;\\n  tmpvar_1[2u].y = q25;\\n  tmpvar_1[2u].z = q28;\\n  vec3 tmpvar_2;\\n  tmpvar_2.x = q4;\\n  tmpvar_2.y = q5;\\n  tmpvar_2.z = q6;\\n  sustain = (0.98 - q14);\\n  ffac = q17;\\n  vec2 uv_3;\\n  uv_3 = (((uv - 0.5) * (1.0 - \\n    (q10 / (1.0 - ((texture (sampler_blur1, uv).xyz * scale1) + bias1).z))\\n  )) + 0.5);\\n  xlat_mutableuv1 = (((uv_orig - 0.5) * aspect.xy) * q16);\\n  vec4 tmpvar_4;\\n  tmpvar_4 = fract((8.0 * texture (sampler_noise_lq, (uv_3 + rand_frame.yz))));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = tmpvar_4.xyz;\\n  if ((tmpvar_4.y > (0.4 * rad))) {\\n    vec3 tmpvar_6;\\n    tmpvar_6 = (tmpvar_4.xyz - vec3(0.5, 0.5, 0.5));\\n    vec4 nb2_7;\\n    vec4 nb_8;\\n    vec2 tmpvar_9;\\n    tmpvar_9 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 - texsize.zw)).yz)\\n     + vec2(0.5, 0.5))));\\n    nb_8.x = (1.0 - (tmpvar_9.y + (0.015625 * \\n      (tmpvar_9.x - 0.5)\\n    )));\\n    vec2 tmpvar_10;\\n    tmpvar_10 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(1.0, -1.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb_8.y = (1.0 - (tmpvar_10.y + (0.015625 * \\n      (tmpvar_10.x - 0.5)\\n    )));\\n    vec2 tmpvar_11;\\n    tmpvar_11 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + texsize.zw)).yz)\\n     + vec2(0.5, 0.5))));\\n    nb_8.z = (1.0 - (tmpvar_11.y + (0.015625 * \\n      (tmpvar_11.x - 0.5)\\n    )));\\n    vec2 tmpvar_12;\\n    tmpvar_12 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(-1.0, 1.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb_8.w = (1.0 - (tmpvar_12.y + (0.015625 * \\n      (tmpvar_12.x - 0.5)\\n    )));\\n    vec2 tmpvar_13;\\n    tmpvar_13 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(0.0, -1.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb2_7.x = (1.0 - (tmpvar_13.y + (0.015625 * \\n      (tmpvar_13.x - 0.5)\\n    )));\\n    vec2 tmpvar_14;\\n    tmpvar_14 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(1.0, 0.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb2_7.y = (1.0 - (tmpvar_14.y + (0.015625 * \\n      (tmpvar_14.x - 0.5)\\n    )));\\n    vec2 tmpvar_15;\\n    tmpvar_15 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(0.0, 1.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb2_7.z = (1.0 - (tmpvar_15.y + (0.015625 * \\n      (tmpvar_15.x - 0.5)\\n    )));\\n    vec2 tmpvar_16;\\n    tmpvar_16 = (0.0078125 * floor((\\n      (128.0 * texture (sampler_pc_main, (uv_3 + (texsize.zw * vec2(-1.0, 0.0)))).yz)\\n     + vec2(0.5, 0.5))));\\n    nb2_7.w = (1.0 - (tmpvar_16.y + (0.015625 * \\n      (tmpvar_16.x - 0.5)\\n    )));\\n    vec4 tmpvar_17;\\n    tmpvar_17 = min (nb_8, nb2_7);\\n    nb_8.zw = tmpvar_17.zw;\\n    nb_8.xy = min (tmpvar_17.xy, tmpvar_17.zw);\\n    xlat_mutabledist = (min (nb_8.x, nb_8.y) + ((0.006 * tmpvar_6.x) * abs(tmpvar_6.y)));\\n  } else {\\n    xlat_mutabledist = tmpvar_5.x;\\n  };\\n  vec2 tmpvar_18;\\n  tmpvar_18 = (0.0078125 * floor((\\n    (128.0 * texture (sampler_pc_main, uv_3).yz)\\n   + vec2(0.5, 0.5))));\\n  xlat_mutabledist = (min (xlat_mutabledist, (1.0 - \\n    (tmpvar_18.y + (0.015625 * (tmpvar_18.x - 0.5)))\\n  )) - (q10 * 0.8));\\n  xlat_mutablelimit = (15.0 + (10.0 * xlat_mutabledist));\\n  vec3 tmpvar_19;\\n  tmpvar_19.xy = (xlat_mutableuv1 * xlat_mutabledist);\\n  tmpvar_19.z = xlat_mutabledist;\\n  xlat_mutableuv2 = (((tmpvar_19 / q7) * tmpvar_1) + tmpvar_2);\\n  xlat_mutableuv2 = ((fract(\\n    ((xlat_mutableuv2 / 8.0) + 0.5)\\n  ) - 0.5) * 8.0);\\n  int iterations_21;\\n  vec3 zz0_22;\\n  vec3 zz_23;\\n  zz_23 = xlat_mutableuv2;\\n  zz0_22 = (xlat_mutableuv2 + q8);\\n  iterations_21 = int((8.0 - float(\\n    (xlat_mutabledist > 0.8)\\n  )));\\n  for (int n_20 = 0; n_20 <= iterations_21; n_20++) {\\n    zz_23 = ((2.0 * clamp (zz_23, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_23);\\n    zz_23 = (zz_23 * (clamp (\\n      max ((0.25 / dot (zz_23, zz_23)), 0.25)\\n    , 0.0, 1.0) * 4.0));\\n    zz_23 = ((ffac * zz_23) + zz0_22);\\n  };\\n  xlat_mutablestruc = (sqrt(dot (zz_23.xz, zz_23.xz)) / xlat_mutablelimit);\\n  vec2 tmpvar_24;\\n  tmpvar_24 = (0.0078125 * floor((\\n    (128.0 * vec2((1.0 - xlat_mutabledist)))\\n   + vec2(0.5, 0.5))));\\n  vec2 tmpvar_25;\\n  tmpvar_25.x = ((64.0 * (\\n    (1.0 - xlat_mutabledist)\\n   - tmpvar_24.x)) + 0.5);\\n  tmpvar_25.y = tmpvar_24.x;\\n  vec3 tmpvar_26;\\n  float tmpvar_27;\\n  tmpvar_27 = (q14 * 2.0);\\n  tmpvar_26.x = (((1.0 - sustain) * xlat_mutablestruc) + (sustain * mix (texture (sampler_main, uv_3).xyz, \\n    ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1)\\n  , vec3(tmpvar_27)).x));\\n  tmpvar_26.yz = tmpvar_25;\\n  vec3 tmpvar_28;\\n  tmpvar_28.y = 1.0;\\n  tmpvar_28.x = sustain;\\n  tmpvar_28.z = 1.0;\\n  vec3 tmpvar_29;\\n  tmpvar_29.y = 0.0;\\n  tmpvar_29.x = 0.003921569;\\n  tmpvar_29.z = (0.01568628 * (0.2 + rad));\\n  vec4 tmpvar_30;\\n  tmpvar_30.w = 1.0;\\n  tmpvar_30.xyz = mix (tmpvar_26, ((\\n    mix (texture (sampler_main, uv_3).xyz, ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1), vec3(tmpvar_27))\\n   * tmpvar_28) - tmpvar_29), vec3(clamp ((\\n    sqrt(dot (zz_23, zz_23))\\n   - xlat_mutablelimit), 0.0, 1.0)));\\n  ret = tmpvar_30.xyz;\\n }\",comp:\"float xlat_mutableinten;\\nfloat xlat_mutabletmp;\\nvec2 xlat_mutableuv1;\\nvec2 xlat_mutableuv2;\\nfloat xlat_mutablez;\\n shader_body { \\n  float t_rel_2;\\n  vec3 ret1_3;\\n  float struc_4;\\n  xlat_mutableuv1 = ((uv * aspect.xy) - vec2(0.5, 0.5));\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_main, uv);\\n  float tmpvar_6;\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_blur1, uv);\\n  tmpvar_6 = mix (min ((1.0 - tmpvar_5.z), (1.0 - \\n    ((texture (sampler_blur2, uv).xyz * scale2) + bias2)\\n  .z)), (1.0 - (\\n    (tmpvar_7.xyz * scale1)\\n   + bias1).z), 0.5);\\n  struc_4 = ((mix (tmpvar_5.xyz, \\n    ((tmpvar_7.xyz * scale1) + bias1)\\n  , vec3(tmpvar_6)).x * (1.0 - tmpvar_6)) * tmpvar_6);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = q11;\\n  tmpvar_8.y = q12;\\n  xlat_mutableuv2 = ((xlat_mutableuv1 * 0.2) - (tmpvar_8 * 0.2));\\n  vec2 uvi_9;\\n  uvi_9 = (xlat_mutableuv2 * 4.0);\\n  float zv_10;\\n  zv_10 = (0.008 * time);\\n  xlat_mutabletmp = clamp (dot ((texture (sampler_noise_hq, \\n    (xlat_mutableuv2 + (0.03 * ((\\n      (dot (texture (sampler_noise_hq, uvi_9), vec4(0.32, 0.49, 0.29, 0.0)) + (dot (texture (sampler_noise_hq, (\\n        (uvi_9 * 2.0)\\n       + zv_10)), vec4(0.32, 0.49, 0.29, 0.0)) / 2.0))\\n     + \\n      (dot (texture (sampler_noise_hq, ((uvi_9 * 4.0) + (2.0 * zv_10))), vec4(0.32, 0.49, 0.29, 0.0)) / 4.0)\\n    ) + (\\n      dot (texture (sampler_noise_hq, ((uvi_9 * 8.0) + (4.0 * zv_10))), vec4(0.32, 0.49, 0.29, 0.0))\\n     / 8.0))))\\n  ) - 0.4), vec4(0.32, 0.49, 0.29, 0.0)), 0.0, 1.0);\\n  float tmpvar_11;\\n  tmpvar_11 = clamp ((pow (xlat_mutabletmp, 1.2) * sign(xlat_mutabletmp)), 0.0, 1.0);\\n  xlat_mutabletmp = tmpvar_11;\\n  vec3 tmpvar_12;\\n  tmpvar_12.xy = vec2(0.1, 0.1);\\n  tmpvar_12.z = (1.2 - uv.y);\\n  ret1_3 = ((tmpvar_12 + 0.07) + ((\\n    clamp (((tmpvar_6 * 2.0) - 1.5), 0.0, 1.0)\\n   * tmpvar_11) * 4.0));\\n  t_rel_2 = (q13 * 6.0);\\n  for (int n_1 = 1; n_1 <= 3; n_1++) {\\n    xlat_mutablez = (1.0 - fract((\\n      (float(n_1) / 3.0)\\n     - \\n      (fract(-(t_rel_2)) / 3.0)\\n    )));\\n    xlat_mutableinten = (((1.0 - xlat_mutablez) * xlat_mutablez) * 2.0);\\n    vec2 tmpvar_13;\\n    tmpvar_13.x = q11;\\n    tmpvar_13.y = q12;\\n    xlat_mutableuv2 = (((xlat_mutablez * xlat_mutableuv1) / 4.0) - (tmpvar_13 / 6.0));\\n    vec2 uvi_14;\\n    uvi_14 = (xlat_mutableuv2 * 4.0);\\n    float zv_15;\\n    zv_15 = (0.008 * time);\\n    xlat_mutabletmp = clamp (dot ((\\n      (texture (sampler_noise_hq, (xlat_mutableuv2 + (0.03 * (\\n        ((dot (texture (sampler_noise_hq, uvi_14), vec4(0.32, 0.49, 0.29, 0.0)) + (dot (texture (sampler_noise_hq, \\n          ((uvi_14 * 2.0) + zv_15)\\n        ), vec4(0.32, 0.49, 0.29, 0.0)) / 2.0)) + (dot (texture (sampler_noise_hq, (\\n          (uvi_14 * 4.0)\\n         + \\n          (2.0 * zv_15)\\n        )), vec4(0.32, 0.49, 0.29, 0.0)) / 4.0))\\n       + \\n        (dot (texture (sampler_noise_hq, ((uvi_14 * 8.0) + (4.0 * zv_15))), vec4(0.32, 0.49, 0.29, 0.0)) / 8.0)\\n      )))) - (xlat_mutablez * 0.5))\\n     - 0.3), vec4(0.32, 0.49, 0.29, 0.0)), 0.0, 1.0);\\n    xlat_mutabletmp = (((\\n      clamp ((xlat_mutabletmp * sign(xlat_mutabletmp)), 0.0, 1.0)\\n     * xlat_mutableinten) * q1) * 2.0);\\n    ret1_3 = (((ret1_3 + \\n      ((vec3(4.0, 3.0, 0.8) * q1) * struc_4)\\n    ) * clamp (\\n      (1.0 - xlat_mutabletmp)\\n    , 0.0, 1.0)) + xlat_mutabletmp);\\n  };\\n  vec4 tmpvar_16;\\n  tmpvar_16.w = 1.0;\\n  tmpvar_16.xyz = (1.0 - exp((-1.6 * ret1_3)));\\n  ret = tmpvar_16.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,additivewave:1,wave_dots:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.527,wave_smoothing:0,wave_mystery:.6,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_g:.49,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b2x:.6,b3x:.4,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:5,additive:1,num_inst:256,x:.26,y:.2,rad:.39317,tex_zoom:.9355,g2:0,a2:.2,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.n=0;a.w=0;a.high=0;a.q12=0;a.arg=0;a.q13=0;a.y0=0;a.flen=0;a.x0=0;a.k1=0;a.q11=0;a.z0=0;a.exc=0;a.p2=0;a.p1=0;a.a0=0;a.q2=0;a.slen=0;a.q14=0;a.q3=0;a.q32=0;a.rad0=0;\",frame_eqs_str:\"a.n=a.instance;a.flen=a.reg00;a.slen=div(a.reg00,2);a.z0=10;a.y0=div(a.gmegabuf[Math.floor(2E3+a.n+a.flen)],a.z0);a.x0=div(a.gmegabuf[Math.floor(2E3+a.n)],a.z0);a.a0=a.gmegabuf[Math.floor(a.n+1E4)];a.k1=div(a.instance,a.num_inst)-.5;a.x=.5+a.x0+Math.sin(8*a.k1*Math.sin(.07*a.q12))*Math.sin(.13*a.q11)*a.q3*.7;a.y=.5+a.q32*(a.y0+Math.sin(8*a.k1*Math.sin(.1*a.q14))*Math.sin(.2*a.q13)*a.q3*.7);a.arg=div(a.q2,8);a.high=Math.exp(-500*pow(a.arg+.5-div(a.instance,a.num_inst),2));a.high+=\\nMath.exp(-500*pow(-a.arg+.5-div(a.instance,a.num_inst),2));a.exc=sqrt(pow(a.x-.5,2)+pow(a.y-.5,2));a.rad0=above(a.z0,0)*Math.min(.1,div(a.a0,60))+.005;a.rad0=a.rad0*(1+2*a.exc)*(1+a.high);a.p1=.5+div(Math.sin(a.q12),2);a.p2=.5+div(Math.sin(1.4*a.q13),2);a.exc=pow(a.x-a.p1,2)+pow(a.y-a.p2,2);a.rad=Math.min(a.rad0*(1+div(.004*a.q3,Math.abs(a.exc))),1);a.a=Math.min(8*a.a0+.4,1);a.k1=5*div(a.instance,a.num_inst)+a.high;a.w=1-Math.exp(div(-a.treb_att,2)-.5);a.g=a.w+(1-a.w)*Math.sin(a.k1);a.r=a.w+(1-a.w)*\\nMath.sin(a.k1-div(6.28,3));a.b=a.w+(1-a.w)*Math.sin(a.k1-div(12.56,3));a.a2=div(a.a,4);a.g2=0*a.g;a.b2=0*a.b;a.r2=0*a.r;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,sep:120,spectrum:1,additive:1,scaling:7.52386,smoothing:0,r:0,a:.7},init_eqs_str:\"a.flen=0;a.n=0;a.vol=0;a.chg=0;a.dec=0;a.q1=0;a.q2=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.flen=a.reg00;a.n=Math.floor(a.sample*a.flen);a.vol=(a.value1+a.value2)*(1+div(.1,a.sample+.03));a.chg=Math.min(Math.max(a.vol-a.gmegabuf[Math.floor(a.n)],-1),1);a.dec=.00001<Math.abs(0<a.chg?1:0)?1-.3*a.chg:1+.2*a.chg;a.chg=a.q1-a.q2;a.dec=.94-Math.abs(a.chg)*(.00001<Math.abs(0<a.chg?1:0)?.2:.1);a.dec=Math.min(Math.max(a.dec,0),1);a.gmegabuf[Math.floor(a.n)]=a.gmegabuf[Math.floor(a.n)]*a.dec+a.vol*(1-a.dec);a.dec=div(a.q2,4);a.dec=Math.max(Math.min(a.dec,1),.1);a.gmegabuf[Math.floor(a.n)]=\\na.gmegabuf[Math.floor(a.n)]*a.dec+a.gmegabuf[Math.floor(a.n+(.8>a.q2?1:0))]*(1-a.dec);a.gmegabuf[Math.floor(a.n+1E4)]=.2*a.gmegabuf[Math.floor(a.n+1E4)]+div(.8*a.vol,3);a.a=0;a.x=a.sample;a.y=.2+.23*a.gmegabuf[Math.floor(a.n+0)];\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.n=0;a.sw2=0;a.in1=0;a.q12=0;a.q13=0;a.sw3=0;a.dif=0;a.q1=0;a.lev3=0;a.flen=0;a.lev4=0;a.in2=0;a.lev1=0;a.k1=0;a.q11=0;a.ofs=0;a.dec_m=0;a.i=0;a.k=0;a.m2=0;a.vol=0;a.q2=0;a.slen=0;a.m1=0;a.q14=0;a.sw1=0;a.lev2=0;a.q3=0;a.reg00=0;a.vol_=0;a.dec=0;a.q32=0;a.sw4=0;for(var b=a.n=0;5E4>b;b++)a.gmegabuf[Math.floor(a.n)]=0,a.megabuf[Math.floor(a.n)]=0,a.n+=1;a.sw1=randint(8);a.sw2=randint(8);a.sw3=randint(8);a.sw4=randint(8);\",frame_eqs_str:\"a.flen=512;a.reg00=a.flen;a.slen=div(a.flen,2);a.dec_m=pow(.94,div(30,a.fps));a.n=0;for(var b=a.vol=0;b<a.slen;b++)a.vol+=div(pow(a.gmegabuf[Math.floor(a.n)],2),a.flen),a.n+=1;a.vol=div(sqrt(a.vol),2);a.vol_=a.vol_*a.dec_m+(1-a.dec_m)*a.vol;a.lev1=a.lev1*a.dec_m+(1-a.dec_m)*a.gmegabuf[1];a.lev2=a.lev2*a.dec_m+(1-a.dec_m)*a.gmegabuf[20];a.lev3=a.lev3*a.dec_m+(1-a.dec_m)*a.gmegabuf[50];a.lev4=a.lev4*a.dec_m+(1-a.dec_m)*a.gmegabuf[100];a.sw1+=div(0<a.lev1-a.gmegabuf[1]?1:0,a.fps);\\na.sw2+=div(0<a.lev2-a.gmegabuf[20]?1:0,a.fps);a.sw3+=div(0<a.lev3-a.gmegabuf[50]?1:0,a.fps);a.sw4+=div(0<a.lev4-a.gmegabuf[100]?1:0,a.fps);a.dif=16*(1+Math.sin(div(a.sw3,4)))+2;a.ofs=8*Math.sin(div(a.sw2,3));a.n=0;a.k1=0*a.frame;for(b=0;b<a.slen;b++)a.m1=mod(a.n,a.slen),a.m2=mod(a.n+a.ofs,a.slen),a.k=mod(a.m1+a.dif,a.slen),a.i=mod(a.slen+a.m2-a.dif,a.slen),a.in1=1.2*div(a.gmegabuf[Math.floor(a.m1)]-a.gmegabuf[Math.floor(a.k)],pow(a.vol_+.03,.8)),a.in2=1.2*div(a.gmegabuf[Math.floor(a.m2)]-a.gmegabuf[Math.floor(a.i)],\\npow(a.vol_+.03,.8)),a.dec=.00001<Math.abs(pow(a.gmegabuf[Math.floor(2E3+a.n)],2)+pow(a.gmegabuf[Math.floor(2E3+a.flen+a.n)],2)>a.in1*a.in1+a.in2*a.in2?1:0)?.8:.94,a.dec=pow(a.dec,div(30,a.fps)),a.gmegabuf[Math.floor(2E3+a.n)]=a.gmegabuf[Math.floor(2E3+a.n)]*a.dec+(1-a.dec)*a.in1,a.gmegabuf[Math.floor(2E3+a.flen+a.n)]=a.gmegabuf[Math.floor(2E3+a.flen+a.n)]*a.dec+(1-a.dec)*a.in2,a.n+=1;a.q1=div(a.bass+a.treb+a.mid,3);a.q2=div(a.bass_att+a.treb_att+a.mid_att,3);a.q3=a.vol_;a.q11=a.sw1;a.q12=a.sw2;a.q13=\\na.sw3;a.q14=a.sw4;a.rot=0;a.zoom=.98;a.warp=.3;a.rot=0;a.q32=a.aspecty;a.monitor=a.dif;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = ((texture (sampler_main, uv).xyz * clamp (\\n    (q1 - 0.8)\\n  , 0.0, 1.0)) * 0.92);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = (texture (sampler_main, uv).xyz + ((texture (sampler_blur2, uv).xyz * scale2) + bias2));\\n  ret_1 = (ret_1 + ((0.8 * \\n    (hue_shader - 0.8)\\n  ) * (1.0 - uv.y)));\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:4,additivewave:1,wave_dots:1,modwavealphabyvolume:1,darken:1,wave_a:.33064,wave_scale:.897961,wave_smoothing:.108,wave_mystery:.1,modwavealphastart:.72,modwavealphaend:1.28,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:.5,wave_b:.5,wave_y:.54,ob_r:1,ob_g:1,ob_b:1,ib_size:.26,mv_x:24.799994,mv_dy:.16,mv_l:1.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:352,usedots:1,additive:1,scaling:.038558,smoothing:.2,g:0},init_eqs_str:\"a.t02=0;a.q1=0;a.ratio=0;a.ampl=0;a.x1=0;a.y1=0;\",frame_eqs_str:\"a.q1=a.bass_att;\",point_eqs_str:\"a.r=Math.abs(Math.sin(div(a.frame,38)));a.g=.5*Math.abs(Math.cos(div(a.frame,45)));a.b=.5*Math.abs(Math.sin(div(a.frame,133)));a.a=.3;a.t02+=div(a.q1,10);a.ratio=Math.sin(div(a.frame,49));a.ampl=.01+.4*sqr(Math.sin(div(a.frame,18))*Math.cos(div(a.frame,123)));a.x1=div(a.r-.5,15)+.5+a.ampl*Math.sin(6.28*a.sample);a.y1=div(a.b-.5,15)+.5+a.ampl*Math.cos(6.28*a.sample);a.x=a.x1+.2*(a.ampl+a.ratio)*Math.sin(6.28*a.sample*a.ratio*7.3);a.y=a.y1+.2*(a.ampl+a.ratio)*Math.cos(37.68*a.sample);\\n\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.q25=0;a.index=0;a.q18=0;a.q22=0;a.q21=0;a.q29=0;a.q6=0;a.movex=0;a.q1=0;a.dec_med=0;a.q5=0;a.index3=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.mov=0;a.avg=0;a.beat=0;a.p1=0;a.dx1=0;a.peak=0;a.q2=0;a.q27=0;a.clear=0;a.p3=0;a.q3=0;a.t0=0;a.rot1=0;a.q32=0;a.q28=0;a.q20=0;a.clear=.5;\",frame_eqs_str:\"a.dec_med=pow(.96,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,4);a.index2=mod(a.index2+a.is_beat*bnot(a.index),8);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.q20=a.avg;a.q21=\\na.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.p3=a.dec_med*a.p3+(1-a.dec_med)*a.p2;a.rott=div(3.1416*a.p3,4);a.rot1+=a.q26;a.q25=.01*a.rot1;a.q27=8-a.index;a.q28=a.index3;a.dx1=a.dec_med*a.dx1+(1-a.dec_med)*bnot(a.index2);a.q29=a.dx1;a.monitor=a.q29;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.q5=1.5*Math.cos(div(a.time,9));a.q6=.5*Math.sin(div(a.time,\\n7));a.clear=a.clear*a.dec_med+1-a.dec_med;a.q32=a.clear;a.mov=bnot(a.q24)*a.movex+(div(randint(100),100)-50)*a.q2;a.movex+=div(.2,a.fps)*a.q2;a.q18=a.movex;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 uv6_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_3;\\n  tmpvar_3 = (rand_frame * 64.0).x;\\n  uv6_1 = (0.5 * cos((\\n    ((tmpvar_2 * mat2(0.7, -0.7, 0.7, 0.7)) * 17.0)\\n   + \\n    (rand_frame * 6.0)\\n  .xy)));\\n  float x_4;\\n  x_4 = (uv6_1.x + uv6_1.y);\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ((0.147 * (\\n    (texture (sampler_main, (uv + clamp ((\\n      (sin(tmpvar_3) / cos(tmpvar_3))\\n     * \\n      normalize(tmpvar_2)\\n    ), vec2(-8.0, -8.0), vec2(8.0, 8.0)))).xyz + (0.15 * (vec3((0.01 / \\n      sqrt((x_4 * x_4))\\n    )) * roam_cos.xyz)))\\n   - 0.02)) + ((0.85 * \\n    (texture (sampler_main, uv_orig).xyz - 0.002)\\n  ) * q32));\\n  ret = tmpvar_5.xyz;\\n }\",comp:\"vec2 xlat_mutabledz;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutableuv3;\\nvec2 xlat_mutableuv4;\\n shader_body { \\n  vec2 uv_1;\\n  float inten_2;\\n  float dist_3;\\n  vec3 ret_4;\\n  uv_1 = (uv - 0.5);\\n  float tmpvar_5;\\n  tmpvar_5 = (time / 2.0);\\n  dist_3 = (1.0 - fract(tmpvar_5));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 2.0);\\n  vec2 tmpvar_6;\\n  tmpvar_6.y = 0.4;\\n  tmpvar_6.x = q18;\\n  xlat_mutableuv3 = (((2.0 * uv_1) * dist_3) + tmpvar_6);\\n  vec2 tmpvar_7;\\n  tmpvar_7.y = 0.0;\\n  tmpvar_7.x = texsize.z;\\n  vec2 tmpvar_8;\\n  tmpvar_8.y = 0.0;\\n  tmpvar_8.x = texsize.z;\\n  xlat_mutabledz.x = (inten_2 * dot ((texture (sampler_main, \\n    (xlat_mutableuv3 + tmpvar_7)\\n  ).xyz - texture (sampler_main, \\n    (xlat_mutableuv3 - tmpvar_8)\\n  ).xyz), vec3(0.32, 0.49, 0.29)));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = 0.0;\\n  tmpvar_9.y = texsize.w;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = 0.0;\\n  tmpvar_10.y = texsize.w;\\n  xlat_mutabledz.y = (inten_2 * dot ((texture (sampler_main, \\n    (xlat_mutableuv3 + tmpvar_9)\\n  ).xyz - texture (sampler_main, \\n    (xlat_mutableuv3 - tmpvar_10)\\n  ).xyz), vec3(0.32, 0.49, 0.29)));\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (texture (sampler_main, xlat_mutableuv3).xyz * inten_2));\\n  dist_3 = (1.0 - fract((0.3333333 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 2.0);\\n  vec2 tmpvar_11;\\n  tmpvar_11.y = 0.4;\\n  tmpvar_11.x = q18;\\n  xlat_mutableuv3 = (((2.0 * uv_1) * dist_3) + tmpvar_11);\\n  vec2 tmpvar_12;\\n  tmpvar_12.y = 0.0;\\n  tmpvar_12.x = texsize.z;\\n  vec2 tmpvar_13;\\n  tmpvar_13.y = 0.0;\\n  tmpvar_13.x = texsize.z;\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_12)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_13)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  vec2 tmpvar_14;\\n  tmpvar_14.x = 0.0;\\n  tmpvar_14.y = texsize.w;\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = 0.0;\\n  tmpvar_15.y = texsize.w;\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_14)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_15)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_2));\\n  dist_3 = (1.0 - fract((0.6666667 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 2.0);\\n  vec2 tmpvar_16;\\n  tmpvar_16.y = 0.4;\\n  tmpvar_16.x = q18;\\n  xlat_mutableuv3 = (((2.0 * uv_1) * dist_3) + tmpvar_16);\\n  vec2 tmpvar_17;\\n  tmpvar_17.y = 0.0;\\n  tmpvar_17.x = texsize.z;\\n  vec2 tmpvar_18;\\n  tmpvar_18.y = 0.0;\\n  tmpvar_18.x = texsize.z;\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_17)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_18)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  vec2 tmpvar_19;\\n  tmpvar_19.x = 0.0;\\n  tmpvar_19.y = texsize.w;\\n  vec2 tmpvar_20;\\n  tmpvar_20.x = 0.0;\\n  tmpvar_20.y = texsize.w;\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_19)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_20)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_2));\\n  dist_3 = (1.0 - fract((1.0 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 2.0);\\n  vec2 tmpvar_21;\\n  tmpvar_21.y = 0.4;\\n  tmpvar_21.x = q18;\\n  xlat_mutableuv3 = (((2.0 * uv_1) * dist_3) + tmpvar_21);\\n  vec2 tmpvar_22;\\n  tmpvar_22.y = 0.0;\\n  tmpvar_22.x = texsize.z;\\n  vec2 tmpvar_23;\\n  tmpvar_23.y = 0.0;\\n  tmpvar_23.x = texsize.z;\\n  xlat_mutabledz.x = (xlat_mutabledz.x + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_22)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_23)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  vec2 tmpvar_24;\\n  tmpvar_24.x = 0.0;\\n  tmpvar_24.y = texsize.w;\\n  vec2 tmpvar_25;\\n  tmpvar_25.x = 0.0;\\n  tmpvar_25.y = texsize.w;\\n  xlat_mutabledz.y = (xlat_mutabledz.y + (inten_2 * dot (\\n    (texture (sampler_main, (xlat_mutableuv3 + tmpvar_24)).xyz - texture (sampler_main, (xlat_mutableuv3 - tmpvar_25)).xyz)\\n  , vec3(0.32, 0.49, 0.29))));\\n  xlat_mutableret1 = max (xlat_mutableret1, (texture (sampler_main, xlat_mutableuv3).xyz * inten_2));\\n  uv_1 = (uv_1 + xlat_mutabledz);\\n  vec2 tmpvar_26;\\n  tmpvar_26.x = q5;\\n  tmpvar_26.y = q6;\\n  xlat_mutableuv4 = (uv_1 - (0.4 * tmpvar_26));\\n  float tmpvar_27;\\n  tmpvar_27 = (0.1 * clamp ((1.0/(\\n    (abs(uv_1.y) + 0.1)\\n  )), 0.0, 12.0));\\n  vec2 tmpvar_28;\\n  tmpvar_28.x = (uv_1.x * tmpvar_27);\\n  tmpvar_28.y = tmpvar_27;\\n  vec3 tmpvar_29;\\n  tmpvar_29.xy = vec2(0.0, 0.0);\\n  tmpvar_29.z = clamp ((1.0 - (3.0 * uv_1.y)), 0.0, 1.0);\\n  ret_4 = (vec3(0.0, 0.1, 0.1) + (0.1 * tmpvar_29));\\n  ret_4 = (ret_4 + (vec3(dot (texture (sampler_noise_hq, \\n    (tmpvar_28 + (0.1 * time))\\n  ), vec4(0.32, 0.49, 0.29, 0.0))) * (\\n    (clamp ((1.0 - (12.0 * uv_1.y)), 0.0, 1.0) * 0.1)\\n   / \\n    (0.05 + sqrt(dot (xlat_mutableuv4, xlat_mutableuv4)))\\n  )));\\n  ret_4 = (ret_4 + ((0.4 * xlat_mutableret1) + (xlat_mutableret1 * q22)));\\n  vec4 tmpvar_30;\\n  tmpvar_30.w = 1.0;\\n  tmpvar_30.xyz = ret_4;\\n  ret = tmpvar_30.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:2,modwavealphabyvolume:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:20.944651,wave_smoothing:0,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:.99,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,textured:1,y:.47,rad:.24057,tex_zoom:.14057,g:.3,b:.5,g2:0,b2:.3,a2:1,border_b:0,border_a:0},init_eqs_str:\"a.q24=0;\",frame_eqs_str:\"a.x=.5;a.y=.5;a.a=a.q24;a.a2=a.q24;\"},{baseVals:{enabled:1,sides:100,additive:1,thickoutline:1,rad:.05134,tex_zoom:.12288,r:.3,g:.2,b:.2,a:.7,g2:0,border_r:0,border_g:.5,border_b:.5,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.r=.5+.3*Math.sin(a.time);a.g=.5+.3*Math.sin(div(a.time,1.5));a.b=.5+.3*Math.sin(div(a.time,3.7));a.r2=0;a.b2=0;a.g2=0;a.a=.05;a.a2=0;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:100,thick:1,scaling:.045052,smoothing:.1,a:.6},init_eqs_str:\"a.k1=0;a.dy=0;a.dx=0;a.t2=0;a.q24=0;a.q27=0;\",frame_eqs_str:\"a.t2=.45+div(randint(10),100);\",point_eqs_str:\"a.k1=bnot(mod(100*a.sample+a.time,2));a.dy=.015*above(Math.sin(11*a.sample),0)+.008*above(Math.sin(a.time+74*a.sample),0)+.008*above(Math.sin(a.time+128*a.sample),0);a.dx=.01*above(Math.sin(27*a.sample),0)+.01*above(Math.sin(a.time+134*a.sample),0);a.x=.2*(a.sample-.5)+.5+a.dx;a.y=a.t2+a.dy;a.a=a.q24*a.k1*bnot(mod(a.q27,4));a.r=.6;a.g=0;a.b=.6;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.dec_xlow=0;a.index2=0;a.speed_=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.q9=0;a.movx=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q10=0;a.tilt_=0;a.q4=0;a.peakx=0;a.dir__=0;a.dir=0;a.dir_=0;a.movy=0;a.q26=0;a.maxp=0;a.p2=0;a.avg=0;a.trig=0;a.beat=0;a.p1=0;a.peak=0;a.tilt=0;a.q2=0;a.q27=0;a.speed=0;a.q3=0;a.t0=0;a.q7=0;a.q20=0;a.q8=0;a.xk=0;\",frame_eqs_str:\"a.dec_med=pow(.8,div(30,a.fps));a.dec_slow=pow(.95,div(30,a.fps));a.dec_xlow=pow(.995,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,16);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=\\na.index;a.q24=a.is_beat;a.q26=a.bass_att+a.mid_att+a.treb_att;a.q27=a.index+1;a.peakx=above(a.q22,1.5*a.maxp);a.maxp=Math.max(a.maxp,a.q22);a.maxp*=a.dec_xlow;a.k1=a.is_beat*equal(mod(a.index,3),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.trig=a.q24*bnot(mod(a.index,4));a.dir=a.dir+div(a.trig*a.q26*(div(randint(100),100)-.5),2)+a.peakx;a.dir_=a.dir_*a.dec_slow+a.dir*(1-a.dec_slow);\\na.dir__=a.dir__*a.dec_slow+a.dir_*(1-a.dec_slow);a.q5=Math.cos(a.dir__);a.q6=Math.sin(a.dir__);a.speed=a.speed*bnot(a.trig)+div(a.trig*a.q26*5,a.fps);a.speed_=a.speed_*a.dec_slow+a.speed*(1-a.dec_slow);a.movx+=a.speed_*a.q6;a.movy+=a.speed_*a.q5;a.q7=a.movx;a.q8=a.movy;a.tilt=a.dir-a.dir__;a.tilt_=a.dec_slow*a.tilt_+(1-a.dec_slow)*a.tilt;a.monitor=a.maxp;a.q9=Math.cos(a.tilt_*a.speed_);a.q10=Math.sin(a.tilt_*a.speed_);a.q12=a.time;\",pixel_eqs_str:\"a.zoom=1.3;\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 uv6_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_4;\\n  tmpvar_4 = ((2.0 * sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  )) + (rand_frame * 64.0)).x;\\n  uv_1 = (uv + (clamp (\\n    ((sin(tmpvar_4) / cos(tmpvar_4)) * normalize(tmpvar_3))\\n  , vec2(-2.0, -2.0), vec2(2.0, 2.0)) / 20.0));\\n  uv6_2 = (0.4 * sin((tmpvar_3 * 22.0)));\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = (((q24 * \\n    (((texture (sampler_main, uv_1).xyz - (\\n      ((texture (sampler_blur1, fract(uv_1)).xyz * scale1) + bias1)\\n     * 0.04)) + (0.15 * (vec3(\\n      (0.1 / sqrt(dot (uv6_2, uv6_2)))\\n    ) * roam_cos.xyz))) - 0.02)\\n  ) * 0.98) + ((1.0 - q24) * texture (sampler_main, uv_orig).xyz));\\n  ret = tmpvar_5.xyz;\\n }\",comp:\"vec3 xlat_mutableret1;\\nvec2 xlat_mutablers;\\n shader_body { \\n  vec2 uv1_1;\\n  mat2 tmpvar_2;\\n  tmpvar_2[uint(0)].x = q9;\\n  tmpvar_2[uint(0)].y = -(q10);\\n  tmpvar_2[1u].x = q10;\\n  tmpvar_2[1u].y = q9;\\n  uv1_1 = (((uv_orig - 0.5) * aspect.xy) * tmpvar_2);\\n  uv1_1 = (uv1_1 * aspect.yx);\\n  float tmpvar_3;\\n  tmpvar_3 = (3.0 / abs(uv1_1.y));\\n  xlat_mutablers.x = (uv1_1.x * tmpvar_3);\\n  xlat_mutablers.y = (tmpvar_3 / 2.0);\\n  mat2 tmpvar_4;\\n  tmpvar_4[uint(0)].x = q5;\\n  tmpvar_4[uint(0)].y = -(q6);\\n  tmpvar_4[1u].x = q6;\\n  tmpvar_4[1u].y = q5;\\n  xlat_mutablers = (tmpvar_4 * xlat_mutablers);\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = q7;\\n  tmpvar_5.y = q8;\\n  xlat_mutablers = (xlat_mutablers + tmpvar_5);\\n  xlat_mutableret1 = ((texture (sampler_blur1, fract(\\n    (xlat_mutablers / 12.0)\\n  )).xyz * scale1) + bias1);\\n  vec2 tmpvar_6;\\n  tmpvar_6.y = 0.0;\\n  tmpvar_6.x = q5;\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = (((xlat_mutableret1 * 32.0) / tmpvar_3) + ((\\n    ((q22 * sqrt(tmpvar_3)) / 4.0)\\n   * \\n    sin(((uv1_1 - q12) * q27))\\n  .x) * texture (sampler_main, (\\n    (((4.0 * xlat_mutableret1) / tmpvar_3).xy + ((uv1_1 / 2.0) / (0.5 + abs(uv1_1.y))))\\n   + tmpvar_6)).xyz));\\n  ret = tmpvar_7.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.98,decay:.5,echo_zoom:.952,echo_alpha:.5,echo_orient:3,wave_mode:5,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.474,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.8,wave_g:.49,ob_size:0,ob_a:.3,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1x:.8,b1ed:0},shapes:[{baseVals:{enabled:1,sides:7,additive:1,num_inst:1024,rad:.04896,tex_ang:1.00531,tex_zoom:1.53117,r:0,g:1,b:1,a:0,g2:0,border_b:0,border_a:0},init_eqs_str:\"a.max_age=0;a.n=0;a.x0=0;a.y0=0;a.z0=0;a.rad0=0;\",frame_eqs_str:\"a.max_age=a.reg00;a.n=12*a.instance;a.x0=a.gmegabuf[Math.floor(a.n)];a.y0=a.gmegabuf[Math.floor(a.n+1)];a.z0=a.gmegabuf[Math.floor(a.n+2)];.00001<Math.abs(-100>a.z0?1:0)?(a.rad=0,a.gmegabuf[Math.floor(a.n+8)]=a.max_age):(a.rad0=div(pow(1-div(a.gmegabuf[Math.floor(a.n+8)],a.max_age),.2),a.z0)*a.gmegabuf[Math.floor(a.n+7)]+.01,a.rad=.032*Math.abs(a.rad0),a.x=.5+div(a.x0,a.z0),a.y=.5+div(a.y0,a.z0));a.a=1;a.a2=.2;a.g=.8;a.g2=0;a.b=.2*(3<randint(10)?1:0)+.2*(0>a.z0?1:0);a.b2=0;\\n\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:160,sep:20,usedots:1,additive:1,scaling:7.858,smoothing:.1,r:.2,g:.3,a:.6},init_eqs_str:\"a.q32=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.x=div(randint(100),100);a.y=.5-div(1-.7,a.q32)-.15*(div(randint(100),100)-.5);a.a=.15;a.r=0;a.b=1;a.g=0;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:'a.max_age=0;a.ind2=0;a.n=0;a.free=0;a.high=0;a.index=0;a.tht=0;a.v00=0;a.yobf=0;a.dt=0;a.y0=0;a.q1=0;a.dec_med=0;a.q5=0;a.ran1_=0;a[\"new\"]=0;a.push=0;a.new1=0;a.is_beat=0;a.q24=0;a.vol_alt=0;a.dec_slow=0;a.ran2=0;a.ind1=0;a.q10=0;a.v0=0;a.med=0;a.beat=0;a.vol=0;a.peak=0;a.dec_fast=0;a.q27=0;a.bass1=0;a.q3=0;a.t0=0;a.vol_=0;a.dec=0;a.m=0;a.ran1=0;a.q32=0;a.phi=0;a.air=0;a.max_age=4.5;a.reg00=a.max_age;for(var b=a.n=0;12288>b;b++)a.gmegabuf[Math.floor(a.n)]=a.max_age-1+randint(2),\\na.n+=1;a.q9=2*(randint(25)-10);a.q3=div(randint(100),100);a.q4=div(randint(100),100);',frame_eqs_str:'a.dec_fast=1-div(8.8,a.fps);a.dec_med=1-div(6,a.fps);a.dec_slow=1-div(1.6,a.fps);a.vol=div(a.bass+a.med+a.treb,3);a.vol_=a.vol_*a.dec_slow+(1-a.dec_slow)*a.vol;a.beat=a.vol;a.is_beat=above(a.beat,1+4*a.peak)*above(a.time,a.t0+.2);a.t0=.00001<Math.abs(a.is_beat)?a.time:a.t0;a.peak=.00001<Math.abs(a.is_beat)?a.beat:a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,1024);a.ind1=a.ind1*a.dec_med+(1-a.dec_fast)*a.index;a.ind2=a.ind2*a.dec_med+(1-a.dec_fast)*a.ind1;a.q27=a.ind2;a.q24=\\na.is_beat;a.ran1=.00001<Math.abs(a.is_beat)?div(randint(100),100)-.5:a.ran1;a.ran2=.00001<Math.abs(a.is_beat)?div(randint(100),50)+1:a.ran2;a.ran1_=a.dec_med*a.ran1_+(1-a.dec_med)*a.ran1;a.high=2.9<a.ran2?1:0;a.q5=a.ran1_;a.n=0;a.push=Math.max(0,a.vol-a.vol_alt)*a.vol_;a.air=.1*a.dt;a.dt=div(1,a.fps);a.v00=pow(a.push,.25)+.4;a.free=512;a[\"new\"]=0;a.y0=-.68;a.yobf=a.y0+.1;for(var b=0;512>b;b++)a.megabuf[Math.floor(a.n)]=a.gmegabuf[Math.floor(a.n)],a.megabuf[Math.floor(a.n+1)]=a.gmegabuf[Math.floor(a.n+\\n1)],a.megabuf[Math.floor(a.n+2)]=a.gmegabuf[Math.floor(a.n+2)],.00001<Math.abs(a.gmegabuf[Math.floor(a.n+8)]>a.max_age?1:0)?.00001<Math.abs(band(a.push>=10*a.dt*bnot(a.high)?1:0,200>a[\"new\"]?1:0))?(--a.free,a[\"new\"]+=1,a.tht=div(randint(100),500)*(1+1.5*a.high),a.phi=randint(12),a.v0=a.v00*(1+div(randint(10),40)),a.gmegabuf[Math.floor(a.n)]=1.7*a.ran1,a.gmegabuf[Math.floor(a.n+1)]=a.y0+2.2*a.high,a.gmegabuf[Math.floor(a.n+2)]=2,a.gmegabuf[Math.floor(a.n+3)]=a.v0*Math.sin(a.tht)*Math.cos(a.phi),a.gmegabuf[Math.floor(a.n+\\n4)]=a.v0*Math.cos(4*a.tht)*(1-1.5*a.high),a.gmegabuf[Math.floor(a.n+5)]=a.v0*Math.sin(a.tht)*Math.sin(a.phi)*1.5*a.vol,a.gmegabuf[Math.floor(a.n+7)]=0,a.gmegabuf[Math.floor(a.n+8)]=div(randint(100),100)):0:(--a.free,a.gmegabuf[Math.floor(a.n)]+=a.gmegabuf[Math.floor(a.n+3)]*a.dt,a.gmegabuf[Math.floor(a.n+1)]+=a.gmegabuf[Math.floor(a.n+4)]*a.dt,a.gmegabuf[Math.floor(a.n+2)]+=a.gmegabuf[Math.floor(a.n+5)]*a.dt,a.gmegabuf[Math.floor(a.n+3)]*=1-a.air,a.gmegabuf[Math.floor(a.n+4)]*=1-a.air,a.gmegabuf[Math.floor(a.n+\\n4)]-=.8*a.dt,a.gmegabuf[Math.floor(a.n+5)]*=1-a.air,a.gmegabuf[Math.floor(a.n+7)]=(a.gmegabuf[Math.floor(a.n+1)]>a.yobf?1:0)*Math.min(1,18*(a.gmegabuf[Math.floor(a.n+1)]-a.yobf)),.00001<Math.abs(band(a.gmegabuf[Math.floor(a.n+1)]<a.yobf?1:0,0>a.gmegabuf[Math.floor(a.n+4)]?1:0))?a.gmegabuf[8]=a.max_age:0,a.gmegabuf[Math.floor(a.n+8)]+=a.dt),a.n+=12;for(b=a.n=0;512>b;b++)a.m=6132+a.n,a.gmegabuf[Math.floor(a.m)]=div(a.gmegabuf[Math.floor(a.n)]+a.megabuf[Math.floor(a.n)],2),a.gmegabuf[Math.floor(a.m+\\n1)]=div(a.gmegabuf[Math.floor(a.n+1)]+a.megabuf[Math.floor(a.n+1)],2),a.gmegabuf[Math.floor(a.m+2)]=div(a.gmegabuf[Math.floor(a.n+2)]+a.megabuf[Math.floor(a.n+2)],2),a.gmegabuf[Math.floor(a.m+7)]=a.gmegabuf[Math.floor(a.n+7)],a.gmegabuf[Math.floor(a.m+8)]=a.gmegabuf[Math.floor(a.n+8)],a.n+=12;a.dec=.00001<Math.abs(a.bass>a.bass1?1:0)?.5:.9;a.bass1=a.bass1*a.dec+a.bass*(1-a.dec);a.q1=Math.min(1,Math.max(0,a.bass1-1.5)*Math.abs(a.q3-.5)*3);a.q10=Math.max(a.vol_-.1,.1);a.vol_alt=a.vol;a.q32=a.aspecty;\\na.new1=.00001<Math.abs(0<a[\"new\"]?1:0)?a[\"new\"]:a.new1;a.monitor=a.new1;',pixel_eqs_str:\"a.dy=-.007*a.y;a.warp=0;a.rot=div(.025*Math.sin(a.q27+7*a.x+0*a.y)*.2,Math.abs(a.y-.7)+.1)*a.q10;a.zoom=1.003+.2*Math.max(0,a.y-.7);\",warp:\"vec2 ver;\\nfloat xlat_mutablecloud;\\nvec2 xlat_mutabledz;\\nvec2 xlat_mutableuv1;\\nvec2 xlat_mutableuv2;\\nfloat xlat_mutablez;\\n shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.y = 0.0;\\n  tmpvar_1.x = texsize.z;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = 0.0;\\n  tmpvar_2.y = texsize.w;\\n  ver = (tmpvar_2 * 2.0);\\n  vec3 ret_3;\\n  xlat_mutabledz.x = (2.0 * dot (vec3((texture (sampler_main, \\n    (uv + tmpvar_1)\\n  ).z - texture (sampler_main, \\n    (uv - tmpvar_1)\\n  ).z)), vec3(0.32, 0.49, 0.29)));\\n  xlat_mutabledz.y = (2.0 * dot (vec3((texture (sampler_main, \\n    (uv + ver)\\n  ).z - texture (sampler_main, \\n    (uv - ver)\\n  ).z)), vec3(0.32, 0.49, 0.29)));\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = q3;\\n  tmpvar_4.y = (0.4 + (q4 * 0.4));\\n  xlat_mutableuv1 = (uv_orig - tmpvar_4);\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_main, uv_orig);\\n  xlat_mutablez = ((0.8 * (xlat_mutableuv1.y - 0.4)) - (mix (tmpvar_5.x, \\n    ((texture (sampler_blur1, uv_orig).xyz * scale1) + bias1)\\n  .x, 0.5) * 0.03));\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = (xlat_mutableuv1.x * xlat_mutablez);\\n  tmpvar_6.y = xlat_mutablez;\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = 0.0;\\n  tmpvar_7.y = (-(time) * 0.014);\\n  xlat_mutableuv2 = (tmpvar_6 + tmpvar_7);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = 0.0;\\n  tmpvar_8.y = (time * 0.004);\\n  vec2 uvi_9;\\n  uvi_9 = ((xlat_mutableuv2 * 1.5) + tmpvar_8);\\n  float zv_10;\\n  zv_10 = (0.002 * time);\\n  xlat_mutablecloud = (1.0 - (1.5 * abs(\\n    (texture (sampler_noise_hq, ((xlat_mutableuv2 + (0.07 * \\n      abs((((\\n        (dot (texture (sampler_noise_hq, uvi_9), vec4(0.32, 0.49, 0.29, 0.0)) + (dot (texture (sampler_noise_hq, (\\n          (uvi_9 * 2.0)\\n         + zv_10)), vec4(0.32, 0.49, 0.29, 0.0)) / 2.0))\\n       + \\n        (dot (texture (sampler_noise_hq, ((uvi_9 * 4.0) + zv_10)), vec4(0.32, 0.49, 0.29, 0.0)) / 4.0)\\n      ) + (\\n        dot (texture (sampler_noise_hq, ((uvi_9 * 8.0) + zv_10)), vec4(0.32, 0.49, 0.29, 0.0))\\n       / -8.0)) - 1.0))\\n    )) / 2.0)) - 0.5)\\n  ))).x;\\n  xlat_mutablecloud = (xlat_mutablecloud * clamp ((\\n    (texture (sampler_noise_hq, (xlat_mutableuv2 * vec2(2.0, 0.5))).x + 0.5)\\n   - \\n    (3.0 * abs(xlat_mutableuv2.x))\\n  ), 0.0, 1.0));\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = 0.0;\\n  tmpvar_11.y = ((-0.01 * time) * (0.125 * float(\\n    int((8.0 * pow (xlat_mutablecloud, 4.0)))\\n  )));\\n  float tmpvar_12;\\n  tmpvar_12 = (texture (sampler_noise_hq, (18.0 * (\\n    (xlat_mutableuv2 + (0.05 * xlat_mutablecloud))\\n   + tmpvar_11))) - 0.75).x;\\n  xlat_mutablecloud = (xlat_mutablecloud * (1.0 + (\\n    (0.2 * tmpvar_12)\\n   * \\n    (xlat_mutablecloud * xlat_mutablecloud)\\n  )));\\n  ret_3.x = ((0.3 * xlat_mutablecloud) + (0.7 * tmpvar_5.xyz)).x;\\n  xlat_mutableuv1 = (uv - vec2(0.0, 0.71));\\n  vec4 tmpvar_13;\\n  tmpvar_13 = texture (sampler_blur1, uv);\\n  float tmpvar_14;\\n  tmpvar_14 = clamp (((12.0 * \\n    (((10.0 * xlat_mutableuv1.y) + ((\\n      (tmpvar_13.xyz * scale1)\\n     + bias1).x / 2.0)) - 1.0)\\n  ) + tmpvar_12), 0.0, 1.0);\\n  xlat_mutableuv1 = (uv - 0.7);\\n  ret_3.z = (((\\n    ((((4.0 * tmpvar_14) * (1.0 - tmpvar_14)) * clamp ((tmpvar_5.x - 0.2), 0.0, 1.0)) + texture (sampler_main, (uv + (xlat_mutabledz * 0.003))).z)\\n   - \\n    (0.03 * sqrt(dot (xlat_mutabledz, xlat_mutabledz)))\\n  ) - (\\n    pow (((tmpvar_13.xyz * scale1) + bias1).z, 8.0)\\n   * 0.2)) - 0.01);\\n  ret_3.y = (texture (sampler_main, mix (uv, uv_orig, vec2(0.5, 0.5))).y * (0.85 - (0.2 * \\n    ((tmpvar_13.xyz * scale1) + bias1)\\n  .y)));\\n  ret_3.x = (ret_3.x + ((texture (sampler_noise_lq, \\n    (2.0 * xlat_mutableuv2)\\n  ) * 0.08) * clamp (\\n    (1.0 - (3.0 * ret_3.x))\\n  , 0.0, 1.0)).x);\\n  vec4 tmpvar_15;\\n  tmpvar_15.w = 1.0;\\n  tmpvar_15.xyz = ret_3;\\n  ret = tmpvar_15.xyz;\\n }\",comp:\"float dunk;\\nfloat xlat_mutablenoise;\\nvec2 xlat_mutablers;\\nvec2 xlat_mutablers0;\\nfloat xlat_mutablesmask;\\nfloat xlat_mutablesmoke;\\nvec2 xlat_mutableuv1;\\nfloat xlat_mutablez;\\n shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.y = 0.0;\\n  tmpvar_1.x = texsize.z;\\n  dunk = ((rand_preset.x * 0.3) + 0.1);\\n  vec2 uv_2;\\n  vec3 ret_3;\\n  uv_2 = (uv + (texsize.zw / 2.0));\\n  xlat_mutableuv1 = (uv_2 - vec2(0.0, 0.7));\\n  xlat_mutablesmask = (((10.0 * xlat_mutableuv1.y) + (\\n    ((texture (sampler_blur1, uv_2).xyz * scale1) + bias1)\\n  .x / 2.0)) - 1.0);\\n  float tmpvar_4;\\n  tmpvar_4 = clamp (((2.0 * xlat_mutablesmask) + 0.3), 0.0, 1.0);\\n  xlat_mutablenoise = ((3.0 * (1.0 - tmpvar_4)) * texture (sampler_noise_lq, ((xlat_mutableuv1 * 1.5) + (rand_frame * 0.2).xy)).x);\\n  float tmpvar_5;\\n  tmpvar_5 = clamp (((12.0 * xlat_mutablesmask) + (xlat_mutablenoise / 2.0)), 0.0, 1.0);\\n  xlat_mutablez = ((0.35 / xlat_mutableuv1.y) + (xlat_mutablenoise / 2.0));\\n  xlat_mutablers0.x = (xlat_mutableuv1.x * xlat_mutablez);\\n  xlat_mutablers0.y = xlat_mutablez;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = (xlat_mutablers0.x + (time / 4.0));\\n  tmpvar_6.y = (xlat_mutablez + (time * 0.21));\\n  xlat_mutablers = (tmpvar_6 * tmpvar_5);\\n  float t_7;\\n  t_7 = ((texture (sampler_main, uv_2).x - dunk) * (1.0 - (tmpvar_5 * \\n    pow (uv_2.y, 4.0)\\n  )));\\n  float tmpvar_8;\\n  tmpvar_8 = clamp (((1.2 * t_7) - 0.2), 0.0, 1.0);\\n  t_7 = tmpvar_8;\\n  vec3 tmpvar_9;\\n  tmpvar_9.x = tmpvar_8;\\n  tmpvar_9.y = (tmpvar_8 * tmpvar_8);\\n  tmpvar_9.z = pow (tmpvar_8, 8.0);\\n  vec3 tmpvar_10;\\n  tmpvar_10 = clamp ((tmpvar_9 / vec3(0.8, 0.8, 0.8)), 0.0, 1.0);\\n  float t_11;\\n  t_11 = ((texture (sampler_blur2, (uv_2 + 0.03)).xyz * scale2) + bias2).x;\\n  float tmpvar_12;\\n  tmpvar_12 = clamp (((1.2 * t_11) - 0.2), 0.0, 1.0);\\n  t_11 = tmpvar_12;\\n  vec3 tmpvar_13;\\n  tmpvar_13.x = tmpvar_12;\\n  tmpvar_13.y = (tmpvar_12 * tmpvar_12);\\n  tmpvar_13.z = pow (tmpvar_12, 8.0);\\n  vec3 tmpvar_14;\\n  tmpvar_14 = clamp ((tmpvar_13 / vec3(0.8, 0.8, 0.8)), 0.0, 1.0);\\n  ret_3 = ((tmpvar_10 * (tmpvar_10 * \\n    (3.0 - (2.0 * tmpvar_10))\\n  )) + ((\\n    (((1.0 - texture (sampler_main, uv_2).x) * (1.0 - tmpvar_5)) * abs((texture (sampler_main, (uv_2 - tmpvar_1)).x - texture (sampler_main, (uv_2 + tmpvar_1)).x)))\\n   * \\n    (tmpvar_14 * (tmpvar_14 * (3.0 - (2.0 * tmpvar_14))))\\n  ) * q9));\\n  xlat_mutablesmoke = ((texture (sampler_blur1, uv_2).xyz * scale1) + bias1).z;\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = uv_2.x;\\n  tmpvar_15.y = ((0.85 - xlat_mutableuv1.y) + ((\\n    ((texture (sampler_noise_hq, xlat_mutablers) + texture (sampler_noise_hq, ((xlat_mutablers / 4.0) - (time / 8.0)))) - 1.0)\\n  .x * 0.2) * q10));\\n  float t_16;\\n  t_16 = ((texture (sampler_main, tmpvar_15).x + texture (sampler_main, tmpvar_15).y) - dunk);\\n  float tmpvar_17;\\n  tmpvar_17 = clamp (((1.2 * t_16) - 0.2), 0.0, 1.0);\\n  t_16 = tmpvar_17;\\n  vec3 tmpvar_18;\\n  tmpvar_18.x = tmpvar_17;\\n  tmpvar_18.y = (tmpvar_17 * tmpvar_17);\\n  tmpvar_18.z = pow (tmpvar_17, 8.0);\\n  vec3 tmpvar_19;\\n  tmpvar_19 = clamp ((tmpvar_18 / vec3(0.8, 0.8, 0.8)), 0.0, 1.0);\\n  ret_3 = (ret_3 + ((\\n    (tmpvar_19 * (tmpvar_19 * (3.0 - (2.0 * tmpvar_19))))\\n   * tmpvar_5) * 0.85));\\n  float tmpvar_20;\\n  tmpvar_20 = ((3.6 * tmpvar_4) * (1.0 - tmpvar_4));\\n  ret_3 = (ret_3 * (clamp (\\n    (1.0 - (xlat_mutablesmoke * (1.0 - tmpvar_20)))\\n  , 0.0, 1.0) * clamp (\\n    (1.0 - (tmpvar_20 * float((rand_preset.x > 0.5))))\\n  , 0.0, 1.0)));\\n  vec3 tmpvar_21;\\n  tmpvar_21.z = 0.0;\\n  tmpvar_21.xy = (((texture (sampler_blur3, uv_2).xyz * scale3) + bias3).xy * vec2(3.0, 5.0));\\n  ret_3 = (ret_3 + ((xlat_mutablesmoke * \\n    dot (tmpvar_21, vec3(0.32, 0.49, 0.29))\\n  ) * vec3(1.0, 0.84, 0.62)));\\n  float tmpvar_22;\\n  tmpvar_22 = clamp (((1.2 * \\n    clamp (texture (sampler_main, uv_2).y, 0.0, 1.0)\\n  ) - 0.2), 0.0, 1.0);\\n  vec3 tmpvar_23;\\n  tmpvar_23.x = tmpvar_22;\\n  tmpvar_23.y = (tmpvar_22 * tmpvar_22);\\n  tmpvar_23.z = pow (tmpvar_22, 8.0);\\n  vec3 tmpvar_24;\\n  tmpvar_24 = clamp ((tmpvar_23 / vec3(0.8, 0.8, 0.8)), 0.0, 1.0);\\n  ret_3 = (ret_3 + (tmpvar_24 * (tmpvar_24 * \\n    (3.0 - (2.0 * tmpvar_24))\\n  )));\\n  float tmpvar_25;\\n  tmpvar_25 = clamp (0.52, 0.0, 1.0);\\n  vec3 tmpvar_26;\\n  tmpvar_26.x = tmpvar_25;\\n  tmpvar_26.y = (tmpvar_25 * tmpvar_25);\\n  tmpvar_26.z = pow (tmpvar_25, 8.0);\\n  vec3 tmpvar_27;\\n  tmpvar_27 = clamp ((tmpvar_26 / vec3(0.8, 0.8, 0.8)), 0.0, 1.0);\\n  vec3 tmpvar_28;\\n  tmpvar_28 = mix (clamp (ret_3, 0.0, 1.0), (tmpvar_27 * (tmpvar_27 * \\n    (3.0 - (2.0 * tmpvar_27))\\n  )), vec3((pow (\\n    ((1.0 - uv_2.y) - ((uv_2.x - 0.5) * (q3 - 0.5)))\\n  , 4.0) * q1)));\\n  ret_3 = tmpvar_28;\\n  vec4 tmpvar_29;\\n  tmpvar_29.w = 1.0;\\n  tmpvar_29.xyz = tmpvar_28;\\n  ret = tmpvar_29.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.698,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:0,ob_g:.1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:25.6,mv_y:9.6,mv_l:5,mv_g:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.n=0;a.maxbpm=0;a.reg26=0;a.maxind1=0;a.uvx0=0;a.cosb_=0;a.reg34=0;a.num_res=0;a.reg28=0;a.reg23=0;a.q25=0;a.angchg=0;a.reg20=0;a.reg15=0;a.reg10=0;a.sinb_=0;a.index=0;a.quali=0;a.v3=0;a.q18=0;a.q22=0;a.q21=0;a.diry=0;a.q6=0;a.posx=0;a.dt=0;a.reg25=0;a.mean=0;a.uvx=0;a.q1=0;a.posz=0;a.q5=0;a.reg52=0;a.dt1=0;a.dec_f=0;a.dirz=0;a.dec_s=0;a.reg16=0;a.bt2=0;a.reg36=0;a.minbpm=0;a.reg22=0;a.uvy=0;a.rotz=0;a.cosb=0;a.omega=0;a.dist_=0;a.ec_steps=0;a.bpm=0;a.q23=0;a.q24=0;a.reg24=\\n0;a.ran2=0;a.pi=0;a.q10=0;a.reg14=0;a.sinb=0;a.reg53=0;a.posy=0;a.reg31=0;a.dirx=0;a.dec_m=0;a.q4=0;a.start=0;a.reg12=0;a.reg13=0;a.v2p=0;a.c2=0;a.reg37=0;a.ex=0;a.s3=0;a.yslope=0;a.q16=0;a.xslope=0;a.q26=0;a.reg38=0;a.v3p=0;a.reg35=0;a.p2=0;a.mov=0;a.reg11=0;a.tx=0;a.avg=0;a.bt1=0;a.beatsin=0;a.uvz=0;a.c3=0;a.uvy0=0;a.reg27=0;a.q19=0;a.q17=0;a.vol=0;a.reg32=0;a.reg21=0;a.uvz0=0;a.len=0;a.reg18=0;a.beatcos=0;a.reg30=0;a.q2=0;a.b1y=0;a.q27=0;a.bri=0;a.slen=0;a.q14=0;a.dist=0;a.trel1=0;a.p3=0;a.reg17=\\n0;a.v1=0;a.speed=0;a.vol2=0;a.q3=0;a.s1=0;a.vol_=0;a.dec=0;a.s2=0;a.quad=0;a.b2y=0;a.ran1=0;a.q32=0;a.reg33=0;a.q7=0;a.ds=0;a.q28=0;a.ty=0;a.excite=0;a.c1=0;a.v2=0;a.q20=0;a.p4=0;a.q8=0;a.maxvol=0;for(var b=a.n=0;2E4>b;b++)a.megabuf[Math.floor(a.n)]=0,a.gmegabuf[Math.floor(a.n)]=0,a.n+=1;a.minbpm=30;a.maxbpm=230;a.num_res=100;for(b=a.index=0;b<a.num_res;b++)a.n=12*a.index,a.bpm=a.minbpm*pow(div(a.maxbpm,a.minbpm),div(a.index,a.num_res)),a.gmegabuf[Math.floor(a.n)]=a.bpm,a.index+=1;a.pi=3.1416;a.octave=\\ndiv(a.num_res*Math.log(2),Math.log(div(a.maxbpm,a.minbpm)));a.q7=.15;a.q8=.2+randint(1);a.q16=1.6;a.start=1;a.travel=0;a.rotz=0;a.t0=a.time+3;a.cran0=randint(1);a.trelx=0;a.trely=0;a.trelz=0;a.reg20=1;a.reg21=0;a.reg22=0;a.reg23=0;a.reg24=1;a.reg25=0;a.reg26=0;a.reg27=0;a.reg28=1;b=0;do{b+=1;var c;a.ran1=randint(8);a.ran2=randint(8);a.ran3=randint(8);a.posx=randint(8);a.posy=randint(8);a.posz=randint(8);a.c1=Math.cos(a.ran1);a.c2=Math.cos(a.ran2);a.c3=Math.cos(a.ran3);a.s1=Math.sin(a.ran1);a.s2=Math.sin(a.ran2);\\na.s3=Math.sin(a.ran3);a.reg20=a.c2*a.c1;a.reg21=a.c2*a.s1;a.reg22=-a.s2;a.reg23=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg24=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg25=a.s3*a.c2;a.reg26=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg27=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg28=a.c3*a.c2;a.dist=.001;var d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=1+2*(div(a.uvx,4)+30.5-Math.floor(div(a.uvx,4)+30.5)-.5);a.uvy=2+2*(div(a.uvy,4)+30.5-Math.floor(div(a.uvy,\\n4)+30.5)-.5);a.uvz=3+2*(div(a.uvz,4)+30.5-Math.floor(div(a.uvz,4)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:\\n.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.05;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(c)&&1048576>d);d=.06>a.dist?1:0}while(.00001<Math.abs(d)&&1048576>b);\",frame_eqs_str:\"a.dt=Math.min(div(1,a.fps),.1);a.dec_f=.8;a.dec_m=1-4*a.dt;a.dec_s=1-a.dt;a.vol=div(a.bass+div(a.mid,2)+a.treb,3);a.vol_=a.vol_*a.dec_m+(1-a.dec_m)*a.vol;a.dec=a.dec_s;a.vol2=a.vol2*a.dec+(1-a.dec)*Math.min(3,a.vol);a.maxvol=.00001<Math.abs(a.vol>a.maxvol?1:0)?a.vol:a.maxvol*a.dec_s;a.excite=a.vol-a.vol_;a.index=0;a.maxind1=0;for(var b=a.mean=0;b<a.num_res;b++){a.n=12*a.index;a.omega=div(2*a.gmegabuf[Math.floor(a.n)]*a.pi,60);a.gmegabuf[Math.floor(a.n+1)]*=1-.25*a.dt;a.ec_steps=\\nMath.floor(10*a.dt*a.omega)+1;a.dt1=div(a.dt,a.ec_steps);a.ex=a.excite;for(var c=0;c<a.ec_steps;c++)a.gmegabuf[Math.floor(a.n+1)]+=(a.ex-sqr(a.omega)*a.gmegabuf[Math.floor(a.n+2)])*a.dt1,a.gmegabuf[Math.floor(a.n+2)]+=a.gmegabuf[Math.floor(a.n+1)]*a.dt1;a.beatcos=a.gmegabuf[Math.floor(a.n+1)];a.beatsin=a.gmegabuf[Math.floor(a.n+2)]*a.omega;a.quad=sqrt(pow(a.beatsin,2)+pow(a.beatcos,2));a.mean+=div(a.quad,a.num_res);a.gmegabuf[Math.floor(a.n+3)]=a.gmegabuf[Math.floor(a.n+3)]*a.dec_m+a.quad*(1-a.dec_m);\\n.00001<Math.abs(a.gmegabuf[Math.floor(a.n+3)]>a.gmegabuf[Math.floor(12*a.maxind1+3)]?1:0)?a.maxind1=a.index:0;a.index+=1}a.quali=div(a.gmegabuf[Math.floor(12*a.maxind1+3)],a.mean);a.bpm=a.minbpm*pow(div(a.maxbpm,a.minbpm),div(a.maxind1,a.num_res));.00001<Math.abs(160<a.bpm?1:0)?a.bpm/=2:0;a.trel1+=(div(a.bpm,60)*a.pi+a.excite*a.cosb)*(.7<a.maxvol?1:0)*a.dt;a.q32=a.trel1;a.speed=div((.15+.25*a.dist_)*(1+a.avg),a.q7)*(.34+.34*a.vol_)*(a.q8+.8);a.ds=a.ds*a.dec_s+(1-a.dec_s)*a.speed*.25*a.dt;a.rotz=.8*\\npow(Math.sin(div(a.time,12)),5);a.dirx=a.reg26;a.diry=a.reg27;a.dirz=a.reg28;a.posx+=a.ds*a.dirx;a.posy+=a.ds*a.diry;a.posz+=a.ds*a.dirz;a.q4=a.posx;a.q5=a.posy;a.q6=a.posz;a.angchg=Math.max(0,.4-a.dist_);a.v1=a.v1*a.dec_m+(1-a.dec_m)*a.rotz*a.ds;a.dec=1-3*a.dt;a.v2p=a.v2p*a.dec+(1-a.dec)*(a.angchg*a.xslope+.02*a.p2)*a.dt;a.v3p=a.v3p*a.dec+(1-a.dec)*(a.angchg*a.yslope+.02*a.p3)*a.dt;a.v2=a.v2*a.dec+(1-a.dec)*a.v2p;a.v3=a.v3*a.dec+(1-a.dec)*a.v3p;a.p3=sign(a.v3);a.p4=sign(a.v2);a.reg30=a.reg20;a.reg31=\\na.reg21;a.reg32=a.reg22;a.reg33=a.reg23;a.reg34=a.reg24;a.reg35=a.reg25;a.reg36=a.reg26;a.reg37=a.reg27;a.reg38=a.reg28;a.n=0;for(b=a.avg=0;5>b;b++){a.n+=1;a.ran1=div(randint(100),100);a.ran2=div(randint(100),200)-.25;a.tx=Math.cos(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.ty=Math.sin(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.c1=Math.cos(a.v1);a.c2=Math.cos(a.v2+a.ty);a.c3=Math.cos(a.v3+a.tx);a.s1=Math.sin(a.v1);a.s2=Math.sin(a.v2+a.ty);a.s3=Math.sin(a.v3+a.tx);a.reg10=a.c2*a.c1;a.reg11=a.c2*a.s1;a.reg12=\\n-a.s2;a.reg13=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg14=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg15=a.s3*a.c2;a.reg16=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg17=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg18=a.c3*a.c2;a.reg20=a.reg30;a.reg21=a.reg31;a.reg22=a.reg32;a.reg23=a.reg33;a.reg24=a.reg34;a.reg25=a.reg35;a.reg26=a.reg36;a.reg27=a.reg37;a.reg28=a.reg38;a.q20=a.reg10*a.reg20+a.reg11*a.reg23+a.reg12*a.reg26;a.q21=a.reg10*a.reg21+a.reg11*a.reg24+a.reg12*a.reg27;a.q22=a.reg10*a.reg22+a.reg11*a.reg25+a.reg12*a.reg28;a.q23=a.reg13*a.reg20+\\na.reg14*a.reg23+a.reg15*a.reg26;a.q24=a.reg13*a.reg21+a.reg14*a.reg24+a.reg15*a.reg27;a.q25=a.reg13*a.reg22+a.reg14*a.reg25+a.reg15*a.reg28;a.q26=a.reg16*a.reg20+a.reg17*a.reg23+a.reg18*a.reg26;a.q27=a.reg16*a.reg21+a.reg17*a.reg24+a.reg18*a.reg27;a.q28=a.reg16*a.reg22+a.reg17*a.reg25+a.reg18*a.reg28;a.reg20=a.q20;a.reg21=a.q21;a.reg22=a.q22;a.reg23=a.q23;a.reg24=a.q24;a.reg25=a.q25;a.reg26=a.q26;a.reg27=a.q27;a.reg28=a.q28;a.dist=.002;var d;c=0;do{c+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*\\na.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=1+2*(div(a.uvx,4)+30.5-Math.floor(div(a.uvx,4)+30.5)-.5);a.uvy=2+2*(div(a.uvy,4)+30.5-Math.floor(div(a.uvy,4)+30.5)-.5);a.uvz=3+2*(div(a.uvz,4)+30.5-Math.floor(div(a.uvz,4)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(d=0;8>d;d++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?\\n1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*\\na.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.1;d=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(d)&&1048576>c);a.megabuf[Math.floor(a.n)]=a.megabuf[Math.floor(a.n)]*a.dec_s+(1-a.dec_s)*a.dist;a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5))}a.n=0;for(b=a.avg=0;5>b;b++)a.n+=1,a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5));a.xslope=Math.min(Math.max(8*(a.megabuf[1]-a.megabuf[3]),-2),2);a.yslope=Math.min(Math.max(8*(a.megabuf[4]-a.megabuf[2]),-2),2);a.dist_=a.dist_*a.dec_m+(1-a.dec_m)*a.dist;\\na.q10=a.ds*a.q7;a.q14=Math.abs(a.ds)+2*(Math.abs(a.v1)+Math.abs(a.v2)+Math.abs(a.v3))+div(1,255)+0*a.start;a.start*=.9;a.reg52=-a.v2;a.reg53=a.v3;a.warp=0;a.zoom=1;a.rot=a.v1;a.sinb=Math.sin(a.trel1);a.cosb=Math.cos(a.trel1);a.bt1=0>a.sinb*a.sinb_?1:0;a.bt2=0>a.cosb*a.cosb_?1:0;.00001<Math.abs(a.bt1)?(a.b1x=randint(2)-1,a.b1y=randint(2)-1):0;.00001<Math.abs(a.bt2)?(a.b2x=randint(2)-1,a.b2y=randint(2)-1):0;a.sinb_=a.sinb;a.cosb_=a.cosb;a.bri=.012*a.vol2*sqrt(div(100,a.bpm))+.01*a.excite;a.mov=div(sqrt(a.v3*\\na.v3+a.v2*a.v2),a.dt);a.q1=a.b1x*Math.abs(a.b1x);a.q2=a.b1y*Math.abs(a.b1y);a.q17=.4*a.b2x;a.q18=.4*a.b2y;a.len=pow(a.q1,2)+pow(a.q2,2);a.q3=pow(a.sinb,2)*a.bri*(1+4*a.len)*Math.max(0,1-5*a.mov);a.q19=pow(a.cosb,2)*a.bri*1.2;a.monitor=a.q8;\",pixel_eqs_str:\"a.warp=0;a.zoom=1;a.tx=Math.tan(.9*(2*a.x-1));a.ty=Math.tan(.9*(2*a.y-1));a.dx=div(a.reg52,a.q16)*(1+.5*Math.abs(a.tx));a.dy=div(a.reg53,a.q16)*(1+.5*Math.abs(a.ty));a.dx+=a.reg53*a.ty*(a.x-.5);a.dy+=a.reg52*a.tx*(a.y-.5);\",warp:\"float sustain;\\nfloat pix;\\nvec3 mod1;\\nfloat xlat_mutabledist;\\nfloat xlat_mutablestruc;\\nvec2 xlat_mutableuv1;\\nvec3 xlat_mutableuv2;\\n shader_body { \\n  mat3 tmpvar_1;\\n  tmpvar_1[uint(0)].x = q20;\\n  tmpvar_1[uint(0)].y = q23;\\n  tmpvar_1[uint(0)].z = q26;\\n  tmpvar_1[1u].x = q21;\\n  tmpvar_1[1u].y = q24;\\n  tmpvar_1[1u].z = q27;\\n  tmpvar_1[2u].x = q22;\\n  tmpvar_1[2u].y = q25;\\n  tmpvar_1[2u].z = q28;\\n  vec3 tmpvar_2;\\n  tmpvar_2.x = q4;\\n  tmpvar_2.y = q5;\\n  tmpvar_2.z = q6;\\n  sustain = (0.97 - q14);\\n  pix = (texsize.z * 2.0);\\n  mod1 = (rand_preset.xyz - 0.5);\\n  vec2 uv_3;\\n  vec3 ret_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv - 0.5);\\n  xlat_mutableuv1 = ((tmpvar_5 * aspect.xy) * q16);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_pw_main, uv);\\n  uv_3 = ((tmpvar_5 * (1.0 - \\n    (q10 / (1.0 - (tmpvar_6.z + (0.003921569 * tmpvar_6.y))))\\n  )) + 0.5);\\n  vec4 tmpvar_7;\\n  tmpvar_7 = fract((8.0 * texture (sampler_noise_lq, (uv_3 + rand_frame.yz))));\\n  xlat_mutabledist = tmpvar_7.x;\\n  if ((tmpvar_7.y > 0.16)) {\\n    vec4 nb2_8;\\n    vec4 nb_9;\\n    vec4 tmpvar_10;\\n    tmpvar_10 = texture (sampler_pw_main, (uv_3 + vec2(-(pix))));\\n    nb_9.x = (1.0 - (tmpvar_10.z + (0.003921569 * tmpvar_10.y)));\\n    vec4 tmpvar_11;\\n    tmpvar_11 = texture (sampler_pw_main, (uv_3 + (pix * vec2(1.0, -1.0))));\\n    nb_9.y = (1.0 - (tmpvar_11.z + (0.003921569 * tmpvar_11.y)));\\n    vec4 tmpvar_12;\\n    tmpvar_12 = texture (sampler_pw_main, (uv_3 + vec2(pix)));\\n    nb_9.z = (1.0 - (tmpvar_12.z + (0.003921569 * tmpvar_12.y)));\\n    vec4 tmpvar_13;\\n    tmpvar_13 = texture (sampler_pw_main, (uv_3 + (pix * vec2(-1.0, 1.0))));\\n    nb_9.w = (1.0 - (tmpvar_13.z + (0.003921569 * tmpvar_13.y)));\\n    vec4 tmpvar_14;\\n    tmpvar_14 = texture (sampler_pw_main, (uv_3 + (pix * vec2(0.0, -1.0))));\\n    nb2_8.x = (1.0 - (tmpvar_14.z + (0.003921569 * tmpvar_14.y)));\\n    vec4 tmpvar_15;\\n    tmpvar_15 = texture (sampler_pw_main, (uv_3 + (pix * vec2(1.0, 0.0))));\\n    nb2_8.y = (1.0 - (tmpvar_15.z + (0.003921569 * tmpvar_15.y)));\\n    vec4 tmpvar_16;\\n    tmpvar_16 = texture (sampler_pw_main, (uv_3 + (pix * vec2(0.0, 1.0))));\\n    nb2_8.z = (1.0 - (tmpvar_16.z + (0.003921569 * tmpvar_16.y)));\\n    vec4 tmpvar_17;\\n    tmpvar_17 = texture (sampler_pw_main, (uv_3 + (pix * vec2(-1.0, 0.0))));\\n    nb2_8.w = (1.0 - (tmpvar_17.z + (0.003921569 * tmpvar_17.y)));\\n    vec4 tmpvar_18;\\n    tmpvar_18 = min (nb_9, nb2_8);\\n    nb_9.zw = tmpvar_18.zw;\\n    nb_9.xy = min (tmpvar_18.xy, tmpvar_18.zw);\\n    xlat_mutabledist = ((min (nb_9.x, nb_9.y) + (\\n      (0.006 * (tmpvar_7.xyz - 0.5).x)\\n     * tmpvar_7.y)) - (q10 * 0.5));\\n  };\\n  float theta_19;\\n  theta_19 = (xlat_mutabledist * 1.35);\\n  float theta_20;\\n  theta_20 = (xlat_mutabledist * 1.35);\\n  vec3 tmpvar_21;\\n  tmpvar_21.xy = (xlat_mutableuv1 * ((\\n    sin(theta_19)\\n   / \\n    cos(theta_19)\\n  ) / 1.35));\\n  tmpvar_21.z = ((sin(theta_20) / cos(theta_20)) / 1.35);\\n  xlat_mutableuv2 = (((tmpvar_21 / q7) * tmpvar_1) + tmpvar_2);\\n  xlat_mutableuv2 = (((\\n    fract(((xlat_mutableuv2 / 4.0) + 0.5))\\n   - 0.5) * 2.0) + vec3(1.0, 2.0, 3.0));\\n  vec3 zz0_23;\\n  vec3 zz_24;\\n  zz_24 = xlat_mutableuv2;\\n  zz0_23 = (xlat_mutableuv2 + q8);\\n  for (int n_22 = 0; n_22 <= 8; n_22++) {\\n    zz_24 = ((2.0 * clamp (zz_24, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_24);\\n    zz_24 = (zz_24 * max ((1.0/(\\n      dot (zz_24, zz_24)\\n    )), 1.0));\\n    zz_24 = ((2.6 * zz_24) + zz0_23);\\n  };\\n  vec4 tmpvar_25;\\n  tmpvar_25.w = 0.0;\\n  tmpvar_25.xyz = zz_24;\\n  float tmpvar_26;\\n  tmpvar_26 = sqrt(dot (zz_24, zz_24));\\n  vec4 tmpvar_27;\\n  tmpvar_27.w = 0.0;\\n  tmpvar_27.xyz = mod1;\\n  xlat_mutablestruc = ((1.0 - (\\n    (1.4 * dot (tmpvar_25, tmpvar_27))\\n   / 40.0)) - (xlat_mutabledist * 0.3));\\n  if (((tmpvar_26 < 40.0) && (xlat_mutabledist > (0.04 * \\n    (1.0 - rad)\\n  )))) {\\n    ret_4.x = mix (xlat_mutablestruc, texture (sampler_main, uv_3).x, sustain);\\n    float x_28;\\n    x_28 = ((1.0 - xlat_mutabledist) * 255.0);\\n    float ip_29;\\n    ip_29 = float(int(x_28));\\n    vec2 tmpvar_30;\\n    tmpvar_30.x = (x_28 - ip_29);\\n    tmpvar_30.y = (ip_29 / 255.0);\\n    ret_4.yz = tmpvar_30;\\n  } else {\\n    ret_4 = ((texture (sampler_fc_main, uv_3) * sustain) - 0.003921569).xyz;\\n  };\\n  vec4 tmpvar_31;\\n  tmpvar_31.w = 1.0;\\n  tmpvar_31.xyz = ret_4;\\n  ret = tmpvar_31.xyz;\\n }\",comp:\"float xlat_mutablecross1;\\nvec2 xlat_mutabledz1;\\nfloat xlat_mutablerdist;\\nvec2 xlat_mutableuv0;\\nvec2 xlat_mutableuv4;\\nvec2 xlat_mutableuva;\\nvec2 xlat_mutableuvb;\\n shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1.x = q1;\\n  tmpvar_1.y = q2;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = q17;\\n  tmpvar_2.y = q18;\\n  vec2 uv_3;\\n  vec3 ret_4;\\n  uv_3 = (uv + (texsize.zw / 2.0));\\n  xlat_mutableuv0 = uv_3;\\n  vec2 uvi_5;\\n  uvi_5 = (uv_3 + vec2(0.002, 0.0));\\n  float tmpvar_6;\\n  tmpvar_6 = mix (((texture (sampler_blur1, uvi_5).xyz * scale1) + bias1).x, texture (sampler_main, uvi_5).x, 0.1);\\n  vec2 uvi_7;\\n  uvi_7 = (uv_3 - vec2(0.002, 0.0));\\n  float tmpvar_8;\\n  tmpvar_8 = mix (((texture (sampler_blur1, uvi_7).xyz * scale1) + bias1).x, texture (sampler_main, uvi_7).x, 0.1);\\n  xlat_mutabledz1.x = ((tmpvar_6 * float(\\n    (tmpvar_6 > 0.02)\\n  )) - (tmpvar_8 * float(\\n    (tmpvar_8 > 0.02)\\n  )));\\n  vec2 uvi_9;\\n  uvi_9 = (uv_3 + vec2(0.0, 0.002));\\n  float tmpvar_10;\\n  tmpvar_10 = mix (((texture (sampler_blur1, uvi_9).xyz * scale1) + bias1).x, texture (sampler_main, uvi_9).x, 0.1);\\n  vec2 uvi_11;\\n  uvi_11 = (uv_3 - vec2(0.0, 0.002));\\n  float tmpvar_12;\\n  tmpvar_12 = mix (((texture (sampler_blur1, uvi_11).xyz * scale1) + bias1).x, texture (sampler_main, uvi_11).x, 0.1);\\n  xlat_mutabledz1.y = ((tmpvar_10 * float(\\n    (tmpvar_10 > 0.02)\\n  )) - (tmpvar_12 * float(\\n    (tmpvar_12 > 0.02)\\n  )));\\n  uv_3 = (uv_3 + (xlat_mutabledz1 * 0.26));\\n  xlat_mutablerdist = ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1).z;\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 0.0;\\n  tmpvar_13.xyz = texture (sampler_noise_hq, vec2(((xlat_mutablerdist * 0.05) + (time * 0.02)))).xyz;\\n  vec4 tmpvar_14;\\n  tmpvar_14 = mix (tmpvar_13, roam_sin, vec4(0.5, 0.5, 0.5, 0.5));\\n  xlat_mutableuv4 = (uv_3 - 0.4);\\n  xlat_mutableuva = ((xlat_mutableuv4 - tmpvar_1) - ((\\n    ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1)\\n  .x * 0.4) * float(\\n    (xlat_mutablerdist > 0.2)\\n  )));\\n  xlat_mutableuvb = ((xlat_mutableuv4 - tmpvar_2) - ((\\n    (texture (sampler_blur1, uv_3).xyz * scale1)\\n   + bias1).x * 0.4));\\n  float angle_15;\\n  float tmpvar_16;\\n  tmpvar_16 = abs(xlat_mutableuva.x);\\n  if ((xlat_mutableuva.y >= 0.0)) {\\n    angle_15 = (1.0 - ((xlat_mutableuva.y - tmpvar_16) / (xlat_mutableuva.y + tmpvar_16)));\\n  } else {\\n    angle_15 = (3.0 - ((xlat_mutableuva.y + tmpvar_16) / (tmpvar_16 - xlat_mutableuva.y)));\\n  };\\n  float tmpvar_17;\\n  if ((xlat_mutableuva.x < 0.0)) {\\n    tmpvar_17 = -(angle_15);\\n  } else {\\n    tmpvar_17 = angle_15;\\n  };\\n  xlat_mutablecross1 = ((pow (\\n    sin((3.141593 * (tmpvar_17 + (5.1 * q20))))\\n  , 1.5) + (xlat_mutablerdist / 2.0)) + 0.1);\\n  vec3 tmpvar_18;\\n  tmpvar_18 = vec3((((1.0/(\\n    dot (xlat_mutableuva, xlat_mutableuva)\\n  )) / xlat_mutablecross1) * q3));\\n  vec3 tmpvar_19;\\n  tmpvar_19 = vec3(((1.0/(dot (xlat_mutableuvb, xlat_mutableuvb))) * q19));\\n  ret_4 = (clamp ((1.0 - \\n    (2.0 * xlat_mutablerdist)\\n  ), 0.0, 1.0) * ((\\n    (tmpvar_18 * tmpvar_14.xyz)\\n   + \\n    (tmpvar_19 * (1.0 - tmpvar_14.xyz))\\n  ) + 0.1));\\n  ret_4 = (ret_4 + (clamp (\\n    (2.0 * xlat_mutablerdist)\\n  , 0.0, 1.0) * (\\n    (tmpvar_18 * tmpvar_14.zyx)\\n   + \\n    (tmpvar_19 * (1.0 - tmpvar_14.zyx))\\n  )));\\n  ret_4 = (ret_4 + ((\\n    (texture (sampler_blur1, xlat_mutableuv0).xyz * scale1)\\n   + bias1).x * 0.05));\\n  ret_4 = (1.0 - exp(-(ret_4)));\\n  vec4 tmpvar_20;\\n  tmpvar_20.w = 1.0;\\n  tmpvar_20.xyz = ret_4;\\n  ret = tmpvar_20.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:2,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:5,wave_dots:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:1.169162,wave_smoothing:0,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:.99,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:0,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b2x:.3,b1ed:0},shapes:[{baseVals:{enabled:1,sides:53,rad:.05408,tex_ang:1.00531,tex_zoom:1.531168,r:.2,g:.7,g2:0,a2:1,border_b:0,border_a:0},init_eqs_str:\"a.q24=0;a.rad0=0;\",frame_eqs_str:\"a.x=.5;a.y=.5;a.a=a.q24;a.a2=0;a.a=0;a.rad0=bnot(a.q24)*a.rad0+div(randint(10),50)*a.q24;a.rad=a.rad0;a.b=0;a.r=div(randint(10),10);a.g=1;a.a2=a.q24;\"},{baseVals:{enabled:1,sides:44,textured:1,x:.7,rad:.2173,tex_zoom:3.277448,g:1,b:.5,r2:1,b2:1,a2:1,border_r:.5,border_g:.5,border_b:0},init_eqs_str:\"a.rot0=0;a.q1=0;a.posx=0;a.q24=0;a.posy=0;a.rad0=0;\",frame_eqs_str:\"a.textured=1;a.rot0+=div(1,a.fps)*a.q1;a.posx=(1-a.q24)*a.posx+a.q24*(.3+div(randint(100),200));a.posy=(1-a.q24)*a.posy+a.q24*(.3+div(randint(100),200));a.rad0=(1-a.q24)*a.rad0+a.q24*(.05+div(randint(100),300));a.rad=a.rad0;a.x=a.posx;a.y=a.posy;a.ang=a.rot0;\"},{baseVals:{enabled:1,sides:63,x:.503,rad:.038857,tex_zoom:2.2233,g:.1,r2:1,b2:1,a2:.7,border_a:0},init_eqs_str:\"a.rot0=0;a.q2=0;a.posx=0;a.q24=0;a.posy=0;a.rad0=0;a.q26=0;\",frame_eqs_str:\"a.textured=1;a.rot0+=div(.1,a.fps)*a.q2;a.posx=(1-a.q24)*a.posx+a.q24*(.3+div(randint(100),200));a.posy=(1-a.q24)*a.posy+a.q24*(.3+div(randint(100),200));a.rad0=(1-a.q24)*a.rad0+a.q24*(.05+div(randint(100),400));a.rad=a.rad0;a.x=a.posx+a.q26;a.y=a.posy;a.ang=a.rot0;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.q25=0;a.index=0;a.q22=0;a.q21=0;a.q29=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.rott=0;a.is_beat=0;a.q31=0;a.q23=0;a.k1=0;a.q24=0;a.t_rel=0;a.dec_slow=0;a.q10=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.p3=0;a.q3=0;a.t0=0;a.q7=0;a.ds=0;a.q28=0;a.q30=0;a.q20=0;a.p4=0;a.q8=0;\",frame_eqs_str:\"a.dec_med=pow(.7,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.beat=a.bass+a.mid+a.treb;a.beat*=a.beat;a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2*a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;\\na.q23=a.index;a.q24=a.is_beat;a.q26=a.bass_att+a.mid_att+a.treb_att+3;a.q27=a.index+1;a.q28=a.index2;a.q29=a.index2;a.monitor=a.q29;a.k1=a.is_beat*equal(mod(a.index,2),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.q5=Math.cos(div(a.time,17));a.q6=Math.sin(div(a.time,17));a.q7=-a.q2;a.q8=a.q1;a.ds=a.ds*a.dec_med+a.q24*(1-a.dec_med);a.q25=a.q24;a.q10=a.q22+3;a.t_rel=8*a.time;a.p3=\\na.p3*a.dec_med+(1-a.dec_med)*(100*a.index+0*a.q26);a.q30=a.p3;a.p4=a.dec_med*a.p4+(1-a.dec_med)*a.q27;a.q31=a.p4;a.zoom=1.1+.2*a.q1;a.warp=0;a.ob_size=.01;a.ob_r=.9;a.ob_g=1;a.ob_b=0;a.ob_a=.2*Math.sin(div(a.time,7));\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_3;\\n  tmpvar_3 = (sqrt(dot (tmpvar_2, tmpvar_2)) + (rand_frame * 13.0)).x;\\n  uv_1 = (uv + (clamp (\\n    ((sin(tmpvar_3) / cos(tmpvar_3)) / normalize(tmpvar_2))\\n  , vec2(-2.0, -2.0), vec2(2.0, 2.0)) / 16.0));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = ((q24 * (\\n    ((texture (sampler_main, uv_1).xyz + ((0.1 * vec3(\\n      ((q1 * cos((uv_1.x * 44.0))) - cos((uv_1.y * 82.0)))\\n    )) * (1.0 + texture (sampler_noise_lq, \\n      ((uv_1 / 16.0) + (time / 100.0))\\n    )).xyz)) * 0.98)\\n   - 0.025)) + ((1.0 - q24) * texture (sampler_main, uv_orig).xyz));\\n  ret = tmpvar_4.xyz;\\n }\",comp:\"vec2 xlat_mutabledz;\\nvec3 xlat_mutableneu;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutableuv3;\\n shader_body { \\n  vec2 uv2_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  xlat_mutabledz.x = dot ((texture (sampler_main, (uv + tmpvar_2)).xyz - texture (sampler_main, (uv - tmpvar_2)).xyz), vec3(0.32, 0.49, 0.29));\\n  xlat_mutabledz.y = dot ((texture (sampler_main, (uv + tmpvar_3)).xyz - texture (sampler_main, (uv - tmpvar_3)).xyz), vec3(0.32, 0.49, 0.29));\\n  uv2_1 = (uv - 0.5);\\n  vec2 tmpvar_4;\\n  tmpvar_4.y = 0.0;\\n  float tmpvar_5;\\n  tmpvar_5 = (time / 8.0);\\n  tmpvar_4.x = tmpvar_5;\\n  float tmpvar_6;\\n  tmpvar_6 = (q27 * 2.0);\\n  xlat_mutableuv3 = (((tmpvar_6 * uv2_1) * 0.1) + tmpvar_4);\\n  xlat_mutableuv3 = (fract(xlat_mutableuv3) * aspect.yx);\\n  xlat_mutableuv3 = ((0.1 * cos(\\n    (22.0 * xlat_mutableuv3)\\n  )) + (18.0 * xlat_mutabledz));\\n  float tmpvar_7;\\n  tmpvar_7 = clamp ((0.02 / sqrt(\\n    dot (xlat_mutableuv3, xlat_mutableuv3)\\n  )), 0.0, 1.0);\\n  vec4 tmpvar_8;\\n  tmpvar_8 = (1.0 + roam_cos);\\n  xlat_mutableneu = ((0.1 * vec3(tmpvar_7)) + ((0.45 * \\n    dot (vec3(tmpvar_7), vec3(0.32, 0.49, 0.29))\\n  ) * tmpvar_8).xyz);\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (xlat_mutableneu * 1.252262));\\n  vec2 tmpvar_9;\\n  tmpvar_9.y = 0.0;\\n  tmpvar_9.x = tmpvar_5;\\n  xlat_mutableuv3 = (((tmpvar_6 * uv2_1) * 0.1) + tmpvar_9);\\n  xlat_mutableuv3 = (fract(xlat_mutableuv3) * aspect.yx);\\n  xlat_mutableuv3 = ((0.1 * cos(\\n    (22.0 * xlat_mutableuv3)\\n  )) + (18.0 * xlat_mutabledz));\\n  float tmpvar_10;\\n  tmpvar_10 = clamp ((0.02 / sqrt(\\n    dot (xlat_mutableuv3, xlat_mutableuv3)\\n  )), 0.0, 1.0);\\n  xlat_mutableneu = ((0.1 * vec3(tmpvar_10)) + ((0.45 * \\n    dot (vec3(tmpvar_10), vec3(0.32, 0.49, 0.29))\\n  ) * tmpvar_8).xyz);\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * 1.252262));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = (xlat_mutableret1 + clamp ((\\n    (texture (sampler_main, uv).xyz * 4.0)\\n   * \\n    (0.2 + xlat_mutableret1)\\n  ), 0.0, 1.0));\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:6,wave_thick:1,modwavealphabyvolume:1,darken:1,wave_a:.001,wave_scale:.159809,wave_smoothing:.45,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,wave_y:.9,ob_r:1,ob_g:1,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1x:.6999,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index=0;a.q22=0;a.q21=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.movez=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q32=0;a.q7=0;a.q20=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.k1=a.is_beat*equal(a.index,0);a.p1=\\na.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_slow*a.p2+(1-a.dec_slow)*a.p1;a.rott=div(3.1416*a.p2,4);a.q27=a.index+1;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.zoom=1;a.rot=-0*a.index;a.q32=pow(.996,div(30,a.fps));a.q5=div(Math.sin(div(a.time,11))+1,5);a.movez+=div(.06,a.fps)*(1.1+a.q1);a.q6=a.movez;a.q7=.005*Math.sin(div(a.time,15));\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"vec3 xlat_mutablenoise;\\nvec2 xlat_mutablers;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutableuv1;\\n shader_body { \\n  vec3 copy_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = 0.5;\\n  tmpvar_2.y = q5;\\n  xlat_mutableuv1 = (uv - tmpvar_2);\\n  float tmpvar_3;\\n  tmpvar_3 = (1.0/(xlat_mutableuv1.y));\\n  xlat_mutablers0.x = (xlat_mutableuv1.x * tmpvar_3);\\n  xlat_mutablers0.y = tmpvar_3;\\n  xlat_mutablers.x = xlat_mutablers0.x;\\n  xlat_mutablers.y = (tmpvar_3 + (time * 0.3));\\n  xlat_mutablenoise = (vec3(dot (texture (sampler_pw_noise_lq, (xlat_mutablers / 63.0)), vec4(0.32, 0.49, 0.29, 0.0))) * (dot (texture (sampler_pw_noise_lq, \\n    (xlat_mutablers / 12.0)\\n  ), vec4(0.32, 0.49, 0.29, 0.0)) + 0.5));\\n  xlat_mutablenoise = (xlat_mutablenoise * (clamp (\\n    ((10.0 * xlat_mutablenoise) - 8.0)\\n  , 0.0, 1.0) * clamp (\\n    (2.0 / tmpvar_3)\\n  , 0.0, 1.0)));\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = uv.x;\\n  tmpvar_4.y = (uv.y - (0.024 / tmpvar_3));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = uv.x;\\n  tmpvar_5.y = (uv.y - (0.012 / tmpvar_3));\\n  copy_1 = (texture (sampler_main, tmpvar_4).xyz + texture (sampler_main, tmpvar_5).xyz);\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = uv.x;\\n  tmpvar_6.y = (uv.y - (0.006 / tmpvar_3));\\n  copy_1 = (copy_1 + texture (sampler_main, tmpvar_6).xyz);\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = ((xlat_mutablenoise + (\\n    (((copy_1 / 3.0) * (1.0 + slow_roam_cos).xyz) / 2.0)\\n   * 0.99)) - 0.005);\\n  ret = tmpvar_7.xyz;\\n }\",comp:\"vec3 xlat_mutablecont;\\nvec3 xlat_mutableneu;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutablers2;\\n shader_body { \\n  vec2 uv_1;\\n  float inten_2;\\n  float dist_3;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * aspect.xy);\\n  dist_3 = (1.0 - fract(q6));\\n  inten_2 = ((dist_3 * (1.0 - dist_3)) * 6.0);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = fract(((uv_1 * dist_3) + 0.55));\\n  xlat_mutableneu = texture (sampler_main, tmpvar_4).xyz;\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (xlat_mutableneu * inten_2));\\n  xlat_mutablecont = max (vec3(0.0, 0.0, 0.0), ((\\n    -(texture (sampler_main, tmpvar_4).xyz)\\n   + \\n    ((texture (sampler_blur1, (tmpvar_4 + q7)).xyz * scale1) + bias1)\\n  ) * inten_2));\\n  dist_3 = (1.0 - fract((0.5 + q6)));\\n  inten_2 = ((dist_3 * (1.0 - dist_3)) * 6.0);\\n  vec2 tmpvar_5;\\n  tmpvar_5 = fract(((uv_1 * dist_3) + 0.55));\\n  xlat_mutableneu = texture (sampler_main, tmpvar_5).xyz;\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_2));\\n  xlat_mutablecont = max (xlat_mutablecont, ((\\n    -(texture (sampler_main, tmpvar_5).xyz)\\n   + \\n    ((texture (sampler_blur1, (tmpvar_5 + q7)).xyz * scale1) + bias1)\\n  ) * inten_2));\\n  dist_3 = (1.0 - fract((1.0 + q6)));\\n  inten_2 = ((dist_3 * (1.0 - dist_3)) * 6.0);\\n  vec2 tmpvar_6;\\n  tmpvar_6 = fract(((uv_1 * dist_3) + 0.55));\\n  xlat_mutableneu = texture (sampler_main, tmpvar_6).xyz;\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_2));\\n  xlat_mutablecont = max (xlat_mutablecont, ((\\n    -(texture (sampler_main, tmpvar_6).xyz)\\n   + \\n    ((texture (sampler_blur1, (tmpvar_6 + q7)).xyz * scale1) + bias1)\\n  ) * inten_2));\\n  vec2 tmpvar_7;\\n  tmpvar_7.y = 5.0;\\n  tmpvar_7.x = (time / 12.0);\\n  xlat_mutablers2 = ((0.1 * cos(\\n    ((uv_1 * 3.0) + tmpvar_7)\\n  )) + (0.1 * xlat_mutableret1).xy);\\n  vec4 tmpvar_8;\\n  tmpvar_8.w = 1.0;\\n  tmpvar_8.xyz = (((-0.1 * xlat_mutableret1) + (\\n    (clamp ((0.005 / sqrt(\\n      dot (xlat_mutablers2, xlat_mutablers2)\\n    )), 0.0, 1.0) * vec3(18.0, 16.2, 10.8))\\n   * \\n    (0.2 + (0.3 * xlat_mutableret1))\\n  )) + ((\\n    dot (xlat_mutablecont, vec3(0.32, 0.49, 0.29))\\n   * \\n    (1.0 + slow_roam_cos)\\n  ) / 2.0).xyz);\\n  ret = tmpvar_8.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:6,wave_dots:1,modwavealphabyvolume:1,darken:1,wave_a:.001,wave_scale:1.740724,wave_smoothing:.45,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_g:.99,ob_size:0,ob_r:1,ob_b:1,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index4=0;a.index=0;a.q22=0;a.q21=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.index3=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.t_rel=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.movez=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.p3=0;a.q3=0;a.t0=0;a.q7=0;a.q28=0;a.q30=0;a.q20=0;a.q8=0;a.p3=0;a.t_rel=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),4);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.monitor=a.index4;\\na.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass_att+a.mid_att+a.treb_att+1;a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.p3=a.dec_med*a.p3+(1-a.dec_med)*a.p2;a.rott=div(3.14159265359*a.p3,2);a.q27=8-a.index;a.q28=a.index2+1;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.t_rel+=div(.6,a.fps)*a.q1*a.q1;a.q5=Math.cos(a.t_rel);a.q6=Math.sin(a.t_rel);a.q7=-a.q6;a.q8=a.q5;a.movez+=div(div(.6,\\na.fps),(1.4-a.q5)*(1.4-a.q5));a.q30=a.movez;a.zoom=1;\",pixel_eqs_str:\"a.dx=div(0*a.q28,8);\",warp:\"vec3 xlat_mutablenoise;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutablers;\\n shader_body { \\n  float z_1;\\n  mat2 tmpvar_2;\\n  tmpvar_2[uint(0)] = _qb.xy;\\n  tmpvar_2[1u] = _qb.zw;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = ((uv * tmpvar_2) - 0.5);\\n  float tmpvar_4;\\n  tmpvar_4 = (0.4 / abs(tmpvar_3.y));\\n  xlat_mutablers.x = (tmpvar_3.x * tmpvar_4);\\n  xlat_mutablers.y = (tmpvar_4 + q30);\\n  vec4 tmpvar_5;\\n  tmpvar_5 = texture (sampler_pw_noise_lq, (xlat_mutablers / 32.0));\\n  xlat_mutablenoise = (tmpvar_5.xyz * vec3(greaterThanEqual (tmpvar_5.xyz, vec3(0.9, 0.9, 0.9))));\\n  xlat_mutablenoise = (xlat_mutablenoise * (1.0 + (0.5 * \\n    (dot (texture (sampler_noise_hq, (16.0 * xlat_mutablers)), vec4(0.32, 0.49, 0.29, 0.0)) - 0.5)\\n  )));\\n  xlat_mutableret1 = xlat_mutablenoise;\\n  z_1 = (1.2 / abs(tmpvar_3.y));\\n  xlat_mutablers.x = (tmpvar_3.x * z_1);\\n  xlat_mutablers.y = (z_1 + q30);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_pw_noise_lq, (xlat_mutablers / 32.0));\\n  xlat_mutablenoise = (tmpvar_6.xyz * vec3(greaterThanEqual (tmpvar_6.xyz, vec3(0.9, 0.9, 0.9))));\\n  xlat_mutableret1 = (xlat_mutableret1 + xlat_mutablenoise);\\n  z_1 = (0.4 / abs(tmpvar_3.x));\\n  xlat_mutablers.y = (tmpvar_3.y * z_1);\\n  xlat_mutablers.x = (z_1 + q30);\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_pw_noise_lq, (xlat_mutablers / 32.0));\\n  xlat_mutablenoise = (tmpvar_7.xyz * vec3(greaterThanEqual (tmpvar_7.xyz, vec3(0.9, 0.9, 0.9))));\\n  xlat_mutablenoise = (xlat_mutablenoise * (1.0 + (0.5 * \\n    (dot (texture (sampler_noise_hq, (16.0 * xlat_mutablers)), vec4(0.32, 0.49, 0.29, 0.0)) - 0.5)\\n  )));\\n  xlat_mutableret1 = (xlat_mutableret1 + xlat_mutablenoise);\\n  z_1 = (1.2 / abs(tmpvar_3.x));\\n  xlat_mutablers.y = (tmpvar_3.y * z_1);\\n  xlat_mutablers.x = (z_1 + q30);\\n  vec4 tmpvar_8;\\n  tmpvar_8 = texture (sampler_pw_noise_lq, (xlat_mutablers / 32.0));\\n  xlat_mutablenoise = (tmpvar_8.xyz * vec3(greaterThanEqual (tmpvar_8.xyz, vec3(0.9, 0.9, 0.9))));\\n  xlat_mutableret1 = (xlat_mutableret1 + xlat_mutablenoise);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = xlat_mutableret1;\\n  ret = tmpvar_9.xyz;\\n }\",comp:\"uniform sampler2D sampler_clouds2;\\n shader_body { \\n  vec2 uv_1;\\n  vec2 uv1_2;\\n  uv_1 = (uv * aspect.xy);\\n  vec2 tmpvar_3;\\n  tmpvar_3.y = 0.0;\\n  tmpvar_3.x = texsize.z;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = 0.0;\\n  tmpvar_4.y = texsize.w;\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (dot (texture (sampler_main, (uv_1 - tmpvar_3)).xyz, vec3(0.32, 0.49, 0.29)) - dot (texture (sampler_main, (uv_1 + tmpvar_3)).xyz, vec3(0.32, 0.49, 0.29)));\\n  tmpvar_5.y = (dot (texture (sampler_main, (uv_1 - tmpvar_4)).xyz, vec3(0.32, 0.49, 0.29)) - dot (texture (sampler_main, (uv_1 + tmpvar_4)).xyz, vec3(0.32, 0.49, 0.29)));\\n  uv1_2 = ((0.3 * sin(\\n    ((uv_1 + (0.02 * time)) * 6.0)\\n  )) + (0.2 * tmpvar_5));\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_clouds2, (uv_orig + tmpvar_5));\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = (((-2.0 * \\n    (0.1 * texture (sampler_main, uv_1))\\n  .xyz) + (\\n    clamp (((0.004 * q26) / sqrt(dot (uv1_2, uv1_2))), 0.0, 1.0)\\n   * vec3(1.0, 0.8, 0.4))) + (0.4 * (tmpvar_6.xyz + \\n    (dot (tmpvar_6.xyz, vec3(0.32, 0.49, 0.29)) - 0.7)\\n  )));\\n  ret = tmpvar_7.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.780001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:5,wave_dots:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:5.552,wave_smoothing:.504,wave_mystery:-1,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_g:0,wave_b:0,ob_size:.06,ob_r:1,ob_g:1,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1x:.6999,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:5,additive:1,x:.9,rad:.22613,g:.6,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.x=.05+div(randint(900),1E3);a.y=.05+div(randint(900),1E3);a.ang=div(randint(320),100);\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.ready=0;a.index2=0;a.index4=0;a.index=0;a.q22=0;a.q21=0;a.sp0=0;a.q29=0;a.q1=0;a.dec_med=0;a.q5=0;a.index3=0;a.rott=0;a.is_beat=0;a.q31=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.go=0;a.q4=0;a.is_beat2=0;a.q26=0;a.p2=0;a.avg=0;a.movez=0;a.q19=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q32=0;a.q28=0;a.q30=0;a.q20=0;a.index4=randint(2);a.index3=randint(4);\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,4);a.index2=mod(a.index2+a.is_beat*bnot(a.index),4);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),4);a.index4=mod(a.index4+\\na.is_beat*bnot(a.index)*bnot(a.index2)*bnot(a.index3),2);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.ready=a.is_beat*bnot(a.ready)+bnot(a.is_beat2)*a.ready;a.is_beat2=a.ready*above(a.time,a.t0+.2);a.q19=a.is_beat2;a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.14159265359*a.p2,2);a.q27=a.index+1;a.q28=a.index2+1;a.q29=4*a.index3+1;a.q30=a.index4;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);\\na.q3=-a.q2;a.q4=a.q1;a.sp0=a.dec_slow*a.sp0+(a.q24+.05)*(1-a.dec_slow);a.go=a.go*a.dec_med+(1-a.dec_med)*(1-bnot(a.index2+a.index3));a.movez+=div(.015*30,a.fps)*a.go;a.q31=a.movez;a.q32=.5+.02*Math.sin(div(a.time,5));a.q5=mod(a.index4,2);a.zoom=1;a.rot=0;a.dx=.05*Math.max(Math.sin(div(a.time,9.7))-.95,0);a.dy=.002*(1-a.go);a.rot=50*(a.dx-a.dy);\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = ((uv * texsize.xy) * 0.03);\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = (cos((tmpvar_1.y * q1)) * sin(-(tmpvar_1.y)));\\n  tmpvar_2.y = (sin(tmpvar_1.x) * cos((tmpvar_1.y * q2)));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ((texture (sampler_main, (uv - \\n    ((tmpvar_2 * texsize.zw) * 18.0)\\n  )).xyz * 0.99) - 0.01);\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec3 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv).xyz;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = (texture (sampler_main, (uv - vec2(0.001, 0.0))).xyz - texture (sampler_main, (uv + vec2(0.001, 0.0))).xyz).x;\\n  tmpvar_3.y = (texture (sampler_main, (uv - vec2(0.0, 0.001))).xyz - texture (sampler_main, (uv + vec2(0.0, 0.001))).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    ((uv - 0.5) + 1.8)\\n  )) - (2.0 * tmpvar_3));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = (0.8 * ((0.3 * \\n    dot (tmpvar_2, vec3(0.32, 0.49, 0.29))\\n  ) + (\\n    (22.0 * clamp ((0.01 / sqrt(\\n      dot (uv1_1, uv1_1)\\n    )), 0.0, 1.0))\\n   * \\n    (tmpvar_2 + 0.1)\\n  )));\\n  ret = tmpvar_4.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,wrap:0,darken:1,wave_a:.001,wave_scale:.958,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:.05,ob_g:.1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:25.6,mv_y:9.6,mv_l:0,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.look=0;a.n=0;a.reg26=0;a.uvx0=0;a.reg34=0;a.reg28=0;a.reg23=0;a.q25=0;a.angchg=0;a.reg20=0;a.reg15=0;a.reg10=0;a.q12=0;a.v3=0;a.q22=0;a.q21=0;a.diry=0;a.q13=0;a.q6=0;a.posx=0;a.fps_=0;a.reg25=0;a.uvx=0;a.q1=0;a.travel=0;a.posz=0;a.q5=0;a.dirz=0;a.dec_s=0;a.reg16=0;a.slow=0;a.reg36=0;a.reg22=0;a.uvy=0;a.rotz=0;a.ly=0;a.dist_=0;a.q23=0;a.q24=0;a.reg24=0;a.cran0=0;a.ran2=0;a.q11=0;a.q10=0;a.reg14=0;a.posy=0;a.reg31=0;a.dirx=0;a.q4=0;a.start=0;a.reg12=0;a.reg13=0;a.c2=0;a.reg37=\\n0;a.s3=0;a.yslope=0;a.lampy=0;a.q16=0;a.xslope=0;a.q26=0;a.reg38=0;a.reg35=0;a.reg11=0;a.tx=0;a.avg=0;a.uvz=0;a.c3=0;a.uvy0=0;a.reg27=0;a.q19=0;a.beat=0;a.reg32=0;a.lx=0;a.reg21=0;a.uvz0=0;a.len=0;a.reg18=0;a.reg30=0;a.q2=0;a.q27=0;a.slen=0;a.q14=0;a.dist=0;a.reg17=0;a.v1=0;a.speed=0;a.s1=0;a.t0=0;a.s2=0;a.ran1=0;a.reg33=0;a.q7=0;a.ds=0;a.q28=0;a.lampx=0;a.ty=0;a.c1=0;a.v2=0;a.q20=0;a.q8=0;a.avg=.01;a.q7=.25;a.q8=randint(2)-1;a.q16=1+randint(2);a.q18=randint(.8)+.1;a.q30=1;a.q31=128;a.start=1;a.travel=\\n0;a.rotz=0;a.look=0;a.slow=0;a.t0=a.time+3;a.lampx=.5;a.lampy=.5;a.cran0=randint(1);for(var b=a.n=0;1E4>b;b++)a.gmegabuf[Math.floor(a.n)]=0,a.n+=1;for(b=a.n=0;1E4>b;b++)a.megabuf[Math.floor(a.n)]=0,a.n+=1;a.trelx=0;a.trely=0;a.trelz=0;a.reg20=1;a.reg21=0;a.reg22=0;a.reg23=0;a.reg24=1;a.reg25=0;a.reg26=0;a.reg27=0;a.reg28=1;b=0;do{b+=1;var c;a.ran1=div(randint(800),100);a.ran2=div(randint(800),100);a.ran3=div(randint(800),100);a.posx=randint(5)-2;a.posy=randint(5)-2;a.posz=randint(5)-2;a.c1=Math.cos(a.ran1);\\na.c2=Math.cos(a.ran2);a.c3=Math.cos(a.ran3);a.s1=Math.sin(a.ran1);a.s2=Math.sin(a.ran2);a.s3=Math.sin(a.ran3);a.reg20=a.c2*a.c1;a.reg21=a.c2*a.s1;a.reg22=-a.s2;a.reg23=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg24=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg25=a.s3*a.c2;a.reg26=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg27=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg28=a.c3*a.c2;a.dist=.001;var d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,\\n8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=\\na.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.05;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(c)&&1048576>\\nd);d=.06>a.dist?1:0}while(.00001<Math.abs(d)&&1048576>b);\",frame_eqs_str:\"a.fps_=0*a.fps_+1*(.00001<Math.abs(25>=a.fps?1:0)?a.fps:25+.5*(a.fps-25));a.dec_s=1-div(.06*30,a.fps_);a.beat=a.time>a.t0+3?1:0;a.t0=.00001<Math.abs(a.beat)?a.time:a.t0;a.speed=div(Math.min(.2,a.dist_-.02)*(1+2*a.avg)*(1-0*a.slow)*.7,a.q7);a.ds=a.ds*a.dec_s+div((1-a.dec_s)*a.speed*.25,a.fps_);a.rotz=.00001<Math.abs(.00001>Math.abs(a.rotz-0)?1:0)?a.beat*(randint(100)<20*a.travel?1:0)*(div(randint(10),10)-.3):bnot(a.beat*(30>randint(100)?1:0))*a.rotz;a.slow=.00001<Math.abs(bnot(a.slow))?\\na.beat*(6>randint(1E3*a.avg)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.look=.00001<Math.abs(bnot(a.look))?a.beat*(12>randint(1E3*a.speed)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.lx=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.lx;a.ly=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.ly;a.lampx=a.lampx*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.lx:.5);a.lampy=a.lampy*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.ly:.5);a.q1=a.lampx;a.q2=a.lampy;a.dirx=a.reg26;a.diry=a.reg27;a.dirz=\\na.reg28;a.posx+=a.ds*a.dirx;a.posy+=a.ds*a.diry;a.posz+=a.ds*a.dirz;a.q4=a.posx;a.q5=a.posy;a.q6=a.posz;a.angchg=(.2-a.dist_)*(.2>a.dist_?1:0)*2;a.travel=.00001<Math.abs(0<a.angchg?1:0)?0:a.travel+a.ds;a.v1=a.v1*a.dec_s+(1-a.dec_s)*a.rotz*a.ds;a.v2=a.v2*a.dec_s+div((1-a.dec_s)*a.angchg*a.xslope,a.fps_);a.v3=a.v3*a.dec_s+(1-a.dec_s)*(div(a.angchg*a.yslope,a.fps_)+2*a.v1*Math.sin(.1*a.time));a.reg30=a.reg20;a.reg31=a.reg21;a.reg32=a.reg22;a.reg33=a.reg23;a.reg34=a.reg24;a.reg35=a.reg25;a.reg36=a.reg26;\\na.reg37=a.reg27;a.reg38=a.reg28;a.n=0;for(var b=a.avg=0;5>b;b++){a.n+=1;a.ran1=div(randint(100),100);a.ran2=div(randint(100),200)-.25;a.tx=Math.cos(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.ty=Math.sin(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.c1=Math.cos(a.v1);a.c2=Math.cos(a.v2+a.ty);a.c3=Math.cos(a.v3+a.tx);a.s1=Math.sin(a.v1);a.s2=Math.sin(a.v2+a.ty);a.s3=Math.sin(a.v3+a.tx);a.reg10=a.c2*a.c1;a.reg11=a.c2*a.s1;a.reg12=-a.s2;a.reg13=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg14=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg15=a.s3*\\na.c2;a.reg16=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg17=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg18=a.c3*a.c2;a.reg20=a.reg30;a.reg21=a.reg31;a.reg22=a.reg32;a.reg23=a.reg33;a.reg24=a.reg34;a.reg25=a.reg35;a.reg26=a.reg36;a.reg27=a.reg37;a.reg28=a.reg38;a.q20=a.reg10*a.reg20+a.reg11*a.reg23+a.reg12*a.reg26;a.q21=a.reg10*a.reg21+a.reg11*a.reg24+a.reg12*a.reg27;a.q22=a.reg10*a.reg22+a.reg11*a.reg25+a.reg12*a.reg28;a.q23=a.reg13*a.reg20+a.reg14*a.reg23+a.reg15*a.reg26;a.q24=a.reg13*a.reg21+a.reg14*a.reg24+a.reg15*a.reg27;\\na.q25=a.reg13*a.reg22+a.reg14*a.reg25+a.reg15*a.reg28;a.q26=a.reg16*a.reg20+a.reg17*a.reg23+a.reg18*a.reg26;a.q27=a.reg16*a.reg21+a.reg17*a.reg24+a.reg18*a.reg27;a.q28=a.reg16*a.reg22+a.reg17*a.reg25+a.reg18*a.reg28;a.reg20=a.q20;a.reg21=a.q21;a.reg22=a.q22;a.reg23=a.q23;a.reg24=a.q24;a.reg25=a.q25;a.reg26=a.q26;a.reg27=a.q27;a.reg28=a.q28;a.dist=.002;var c,d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;\\na.uvx=8*(div(a.uvx,8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?\\n-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.1;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<\\nMath.abs(c)&&1048576>d);a.megabuf[Math.floor(a.n)]=a.megabuf[Math.floor(a.n)]*a.dec_s+(1-a.dec_s)*a.dist;a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5))}a.n=0;for(b=a.avg=0;5>b;b++)a.n+=1,a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5));a.xslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[1]-a.megabuf[3]),-3),3);a.yslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[4]-a.megabuf[2]),-3),3);a.monitor=a.avg;a.dist_=a.dist_*a.dec_s+(1-a.dec_s)*a.dist;a.q10=a.ds*a.q7;a.q14=Math.abs(a.ds)+2*(Math.abs(a.v1)+\\nMath.abs(a.v2)+Math.abs(a.v3))+div(1,255)+.05*a.start;a.q19=.6+.4*Math.sin(.02*a.time+6*a.cran0);a.start*=.9;a.q11=a.v1;a.q12=a.v2;a.q13=a.v3;a.monitor=a.q16;\",pixel_eqs_str:\"a.warp=0;a.zoom=1;a.dx=div(-a.q12,a.q16)*(1+0*pow(a.x-.5,2));a.dy=div(a.q13,a.q16)*(1+0*pow(a.y-.5,2));a.rot=a.q11;\",warp:\"float sustain;\\nfloat xlat_mutabledist;\\nfloat xlat_mutablestruc;\\nvec2 xlat_mutableuv1;\\nvec3 xlat_mutableuv2;\\n shader_body { \\n  mat3 tmpvar_1;\\n  tmpvar_1[uint(0)].x = q20;\\n  tmpvar_1[uint(0)].y = q23;\\n  tmpvar_1[uint(0)].z = q26;\\n  tmpvar_1[1u].x = q21;\\n  tmpvar_1[1u].y = q24;\\n  tmpvar_1[1u].z = q27;\\n  tmpvar_1[2u].x = q22;\\n  tmpvar_1[2u].y = q25;\\n  tmpvar_1[2u].z = q28;\\n  vec3 tmpvar_2;\\n  tmpvar_2.x = q4;\\n  tmpvar_2.y = q5;\\n  tmpvar_2.z = q6;\\n  sustain = (0.98 - q14);\\n  vec2 uv_3;\\n  vec3 ret_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv - 0.5);\\n  xlat_mutableuv1 = ((tmpvar_5 * aspect.xy) * q16);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_pc_main, uv);\\n  uv_3 = ((tmpvar_5 * (1.0 - \\n    (q10 / (1.0 - ((tmpvar_6.z + \\n      (0.003921569 * tmpvar_6.y)\\n    ) + (q10 * 0.7))))\\n  )) + 0.5);\\n  vec4 tmpvar_7;\\n  tmpvar_7 = fract((8.0 * texture (sampler_noise_lq, (uv_3 + rand_frame.yz))));\\n  xlat_mutabledist = tmpvar_7.x;\\n  if ((tmpvar_7.y > 0.2)) {\\n    vec3 tmpvar_8;\\n    tmpvar_8 = (tmpvar_7.xyz - vec3(0.4, 0.5, 0.5));\\n    vec2 uvi_9;\\n    uvi_9 = ((tmpvar_8.zy * 0.003) + uv_3);\\n    vec2 pix_10;\\n    vec4 nb2_11;\\n    vec4 nb_12;\\n    vec2 x_13;\\n    x_13 = (uvi_9 - 0.5);\\n    pix_10 = (texsize.zw * (1.0 + (\\n      sqrt(dot (x_13, x_13))\\n     * 8.0)));\\n    float tmpvar_14;\\n    tmpvar_14 = (q10 * 0.7);\\n    vec4 tmpvar_15;\\n    tmpvar_15 = texture (sampler_pc_main, (uvi_9 - pix_10));\\n    nb_12.x = (1.0 - ((tmpvar_15.z + \\n      (0.003921569 * tmpvar_15.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_16;\\n    tmpvar_16 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(1.0, -1.0))));\\n    nb_12.y = (1.0 - ((tmpvar_16.z + \\n      (0.003921569 * tmpvar_16.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_17;\\n    tmpvar_17 = texture (sampler_pc_main, (uvi_9 + pix_10));\\n    nb_12.z = (1.0 - ((tmpvar_17.z + \\n      (0.003921569 * tmpvar_17.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_18;\\n    tmpvar_18 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(-1.0, 1.0))));\\n    nb_12.w = (1.0 - ((tmpvar_18.z + \\n      (0.003921569 * tmpvar_18.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_19;\\n    tmpvar_19 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(0.0, -1.0))));\\n    nb2_11.x = (1.0 - ((tmpvar_19.z + \\n      (0.003921569 * tmpvar_19.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_20;\\n    tmpvar_20 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(1.0, 0.0))));\\n    nb2_11.y = (1.0 - ((tmpvar_20.z + \\n      (0.003921569 * tmpvar_20.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_21;\\n    tmpvar_21 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(0.0, 1.0))));\\n    nb2_11.z = (1.0 - ((tmpvar_21.z + \\n      (0.003921569 * tmpvar_21.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_22;\\n    tmpvar_22 = texture (sampler_pc_main, (uvi_9 + (pix_10 * vec2(-1.0, 0.0))));\\n    nb2_11.w = (1.0 - ((tmpvar_22.z + \\n      (0.003921569 * tmpvar_22.y)\\n    ) + tmpvar_14));\\n    vec4 tmpvar_23;\\n    tmpvar_23 = min (nb_12, nb2_11);\\n    nb_12.zw = tmpvar_23.zw;\\n    nb_12.xy = min (tmpvar_23.xy, tmpvar_23.zw);\\n    xlat_mutabledist = (min (nb_12.x, nb_12.y) + ((0.008 * tmpvar_8.x) * abs(tmpvar_8.y)));\\n  };\\n  vec4 tmpvar_24;\\n  tmpvar_24 = texture (sampler_pc_main, uv_3);\\n  float tmpvar_25;\\n  tmpvar_25 = min (xlat_mutabledist, (1.0 - (\\n    (tmpvar_24.z + (0.003921569 * tmpvar_24.y))\\n   + \\n    (q10 * 0.7)\\n  )));\\n  xlat_mutabledist = tmpvar_25;\\n  float tmpvar_26;\\n  tmpvar_26 = (tmpvar_25 + pow (tmpvar_25, 3.0));\\n  vec3 tmpvar_27;\\n  tmpvar_27.xy = (xlat_mutableuv1 * tmpvar_26);\\n  tmpvar_27.z = tmpvar_26;\\n  xlat_mutableuv2 = (((tmpvar_27 / q7) * tmpvar_1) + tmpvar_2);\\n  xlat_mutableuv2 = ((fract(\\n    ((xlat_mutableuv2 / 8.0) + 0.5)\\n  ) - 0.5) * 8.0);\\n  float li_28;\\n  vec3 zz0_29;\\n  vec3 zz_30;\\n  zz0_29 = (xlat_mutableuv2 + q8);\\n  li_28 = 0.0;\\n  zz_30 = ((2.0 * clamp (xlat_mutableuv2, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - xlat_mutableuv2);\\n  float tmpvar_31;\\n  tmpvar_31 = dot (zz_30, zz_30);\\n  if ((tmpvar_31 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_31 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_31);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_32;\\n  tmpvar_32 = dot (zz_30, zz_30);\\n  if ((tmpvar_32 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_32 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_32);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_33;\\n  tmpvar_33 = dot (zz_30, zz_30);\\n  if ((tmpvar_33 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_33 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_33);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_34;\\n  tmpvar_34 = dot (zz_30, zz_30);\\n  if ((tmpvar_34 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_34 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_34);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_35;\\n  tmpvar_35 = dot (zz_30, zz_30);\\n  if ((tmpvar_35 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_35 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_35);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_36;\\n  tmpvar_36 = dot (zz_30, zz_30);\\n  if ((tmpvar_36 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_36 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_36);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_37;\\n  tmpvar_37 = dot (zz_30, zz_30);\\n  if ((tmpvar_37 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_37 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_37);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  zz_30 = ((2.0 * clamp (zz_30, vec3(-1.0, -1.0, -1.0), vec3(1.0, 1.0, 1.0))) - zz_30);\\n  float tmpvar_38;\\n  tmpvar_38 = dot (zz_30, zz_30);\\n  if ((tmpvar_38 <= 0.25)) {\\n    zz_30 = (zz_30 * 4.0);\\n    li_28 = 24.0;\\n  } else {\\n    if ((tmpvar_38 <= 1.0)) {\\n      zz_30 = (zz_30 / tmpvar_38);\\n    };\\n  };\\n  zz_30 = ((2.6 * zz_30) + zz0_29);\\n  vec4 tmpvar_39;\\n  tmpvar_39.xyz = zz_30;\\n  tmpvar_39.w = li_28;\\n  float tmpvar_40;\\n  tmpvar_40 = sqrt(dot (zz_30, zz_30));\\n  xlat_mutablestruc = (sqrt(dot (tmpvar_39.xyw, tmpvar_39.xyw)) / 24.0);\\n  vec4 tmpvar_41;\\n  tmpvar_41 = texture (sampler_pc_main, uv_3);\\n  float tmpvar_42;\\n  float tmpvar_43;\\n  tmpvar_43 = (q10 * 0.7);\\n  tmpvar_42 = ((log(\\n    (1.0 + (tmpvar_40 / 24.0))\\n  ) * 0.02) * (1.0 - (1.0 - \\n    ((tmpvar_41.z + (0.003921569 * tmpvar_41.y)) + tmpvar_43)\\n  )));\\n  float tmpvar_44;\\n  vec4 tmpvar_45;\\n  tmpvar_45 = texture (sampler_pc_main, uv_3);\\n  tmpvar_44 = (1.0 - ((tmpvar_45.z + \\n    (0.003921569 * tmpvar_45.y)\\n  ) + tmpvar_43));\\n  if ((((tmpvar_25 <= tmpvar_44) && (tmpvar_40 < 24.0)) && (tmpvar_25 > 0.005))) {\\n    ret_4.x = (((1.0 - sustain) * xlat_mutablestruc) + (sustain * mix (texture (sampler_main, uv_3).xyz, \\n      ((texture (sampler_blur1, uv_3).xyz * scale1) + bias1)\\n    , vec3(\\n      (q14 * 4.0)\\n    )).x));\\n    float x_46;\\n    x_46 = ((1.0 - tmpvar_25) * 255.0);\\n    float ip_47;\\n    ip_47 = float(int(x_46));\\n    vec2 tmpvar_48;\\n    tmpvar_48.x = (x_46 - ip_47);\\n    tmpvar_48.y = (ip_47 / 255.0);\\n    ret_4.yz = tmpvar_48;\\n  } else {\\n    vec3 tmpvar_49;\\n    tmpvar_49.y = 0.0;\\n    tmpvar_49.x = sustain;\\n    tmpvar_49.z = (1.0 - tmpvar_42);\\n    vec3 tmpvar_50;\\n    tmpvar_50.xy = vec2(0.003921569, 0.0);\\n    tmpvar_50.z = (q14 / 6.0);\\n    ret_4 = ((texture (sampler_fc_main, uv_3).xyz * tmpvar_49) - tmpvar_50);\\n  };\\n  vec4 tmpvar_51;\\n  tmpvar_51.w = 1.0;\\n  tmpvar_51.xyz = ret_4;\\n  ret = tmpvar_51.xyz;\\n }\",comp:\" shader_body { \\n  vec3 tmpvar_1;\\n  tmpvar_1.x = q4;\\n  tmpvar_1.y = q5;\\n  tmpvar_1.z = q6;\\n  mat3 tmpvar_2;\\n  tmpvar_2[uint(0)].x = q20;\\n  tmpvar_2[uint(0)].y = q23;\\n  tmpvar_2[uint(0)].z = q26;\\n  tmpvar_2[1u].x = q21;\\n  tmpvar_2[1u].y = q24;\\n  tmpvar_2[1u].z = q27;\\n  tmpvar_2[2u].x = q22;\\n  tmpvar_2[2u].y = q25;\\n  tmpvar_2[2u].z = q28;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q1;\\n  tmpvar_3.y = q2;\\n  vec2 uv_4;\\n  vec3 ret_5;\\n  uv_4 = (((uv - 0.5) * 0.9) + 0.5);\\n  vec3 tmpvar_6;\\n  tmpvar_6.xy = ((uv_4 - 0.5) * min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - \\n    ((texture (sampler_blur2, uv_4).xyz * scale2) + bias2)\\n  .z)));\\n  tmpvar_6.z = min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - (\\n    (texture (sampler_blur2, uv_4).xyz * scale2)\\n   + bias2).z));\\n  float tmpvar_7;\\n  tmpvar_7 = clamp ((abs(\\n    ((1.0 - ((texture (sampler_blur2, uv_4).xyz * scale2) + bias2).z) - clamp ((1.0 - (\\n      (texture (sampler_blur2, tmpvar_3).xyz * scale2)\\n     + bias2).z), 0.1, 0.4))\\n  ) + 0.2), 0.0, 1.0);\\n  float tmpvar_8;\\n  tmpvar_8 = clamp (((1.0 - \\n    exp(-(((texture (sampler_blur1, uv_4).xyz * scale1) + bias1).x))\\n  ) - 0.2), 0.0, 1.0);\\n  ret_5 = ((mix (texture (sampler_main, uv_4).xyz, \\n    ((texture (sampler_blur1, uv_4).xyz * scale1) + bias1)\\n  , vec3(tmpvar_7)).x * (0.2 + \\n    ((1.0 - tmpvar_7) * (1.0 - min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - \\n      ((texture (sampler_blur2, uv_4).xyz * scale2) + bias2)\\n    .z))))\\n  )) * (1.0 + (0.5 * \\n    sin((((tmpvar_6 / q7) * tmpvar_2) + tmpvar_1))\\n  )));\\n  vec3 tmpvar_9;\\n  tmpvar_9.xy = vec2(0.0, 1.0);\\n  tmpvar_9.z = (tmpvar_8 * 3.0);\\n  ret_5 = (mix (ret_5, tmpvar_9, vec3(tmpvar_8)) + ((\\n    pow ((1.0 - mix (texture (sampler_main, uv_4).xyz, (\\n      (texture (sampler_blur1, uv_4).xyz * scale1)\\n     + bias1), vec3(0.8, 0.8, 0.8)).z), 3.0)\\n   * \\n    (0.5 + (0.5 * slow_roam_cos))\\n  ) * q19).xyz);\\n  ret_5 = (1.0 - exp((-2.0 * ret_5)));\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = ret_5;\\n  ret = tmpvar_10.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,wave_mode:7,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.958178,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,ob_r:.3999,ob_a:.2,ib_size:0,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:100,additive:1,x:.26,y:.2,rad:.393173,tex_zoom:.9355,r:0,g:.55,b:.5,g2:.4,b2:.4,a2:.07,border_r:.3,border_g:.7,border_b:.8,border_a:0},init_eqs_str:\"a.g0=0;a.y0=0;a.q1=0;a.x0=0;a.q24=0;a.q26=0;a.r0=0;a.trig=0;a.q2=0;a.b0=0;a.rad0=0;\",frame_eqs_str:\"a.trig=a.q24;a.x0=a.x0*bnot(a.trig)+a.trig*(.5+div(randint(100),200));a.y0=a.y0*bnot(a.trig)+a.trig*(.5+div(randint(100),200));a.x0+=div(.1*a.q1*(3+a.q26),a.fps);a.y0+=div(.1*a.q2*(3+a.q26),a.fps);a.x0-=Math.floor(a.x0);a.y0-=Math.floor(a.y0);a.tex_ang=a.time;a.tex_zoom=a.q1;a.ang=div(a.time,100)*a.q2;a.x=a.x0;a.y=a.y0;a.rad0=a.rad0*bnot(a.trig)+a.trig*(.04+div(randint(100),1E3));a.rad=a.rad0;a.r0=bnot(a.trig)*a.r0+div(a.trig*randint(10),10);a.g0=bnot(a.trig)*a.g0+div(a.trig*\\nrandint(10),10);a.b0=bnot(a.trig)*a.b0+div(a.trig*randint(10),10);a.r=a.r0;a.b=a.b0;a.g=a.g0;a.r2=0;a.b2=0;a.g2=0;a.a=1;a.a2=.3;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index4=0;a.index=0;a.q22=0;a.q21=0;a.q1=0;a.dec_med=0;a.index3=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q11=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q28=0;a.q20=0;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),3);a.monitor=a.index4;\\na.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.q11=Math.min(a.q22,3);a.k1=a.is_beat*equal(a.index,0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.14159265359*a.p2,2);a.q27=8-a.index;a.q28=a.index2;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.zoom=1+.02*a.q1;a.rot=.01*a.q2;a.dx=0*a.index;a.wave_a=0;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\"float xlat_mutabledx;\\nfloat xlat_mutabledy;\\nvec2 xlat_mutableuv2;\\nvec2 xlat_mutablezz;\\n shader_body { \\n  vec2 uv_1;\\n  vec3 crisp_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3.y = 0.0;\\n  tmpvar_3.x = texsize.w;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = 0.0;\\n  tmpvar_4.y = texsize.z;\\n  xlat_mutablezz = ((uv * texsize.xy) * 0.01);\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (cos((xlat_mutablezz.y * q1)) * sin(-(xlat_mutablezz.y)));\\n  tmpvar_5.y = (sin(xlat_mutablezz.x) * cos((xlat_mutablezz.y * q2)));\\n  uv_1 = (uv - ((tmpvar_5 * texsize.zw) * (8.0 + \\n    (6.0 * q11)\\n  )));\\n  xlat_mutableuv2 = (((uv_1 / 2.0) * q27) / 4.0);\\n  xlat_mutabledx = dot ((texture (sampler_main, (xlat_mutableuv2 + tmpvar_3)).xyz - texture (sampler_main, (xlat_mutableuv2 - tmpvar_3)).xyz), vec3(0.32, 0.49, 0.29));\\n  xlat_mutabledy = dot ((texture (sampler_main, (xlat_mutableuv2 + tmpvar_4)).xyz - texture (sampler_main, (xlat_mutableuv2 - tmpvar_4)).xyz), vec3(0.32, 0.49, 0.29));\\n  float tmpvar_6;\\n  tmpvar_6 = (0.15 + (0.1 * q28));\\n  vec2 tmpvar_7;\\n  tmpvar_7 = (xlat_mutableuv2 + (time / 100.0));\\n  xlat_mutabledx = (xlat_mutabledx + (tmpvar_6 * (texture (sampler_noise_hq, tmpvar_7).x - 0.5)));\\n  xlat_mutabledy = (xlat_mutabledy + (tmpvar_6 * (texture (sampler_noise_hq, tmpvar_7).y - 0.5)));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = xlat_mutabledx;\\n  tmpvar_8.y = xlat_mutabledy;\\n  xlat_mutablezz = tmpvar_8;\\n  crisp_2 = (texture (sampler_main, (uv_1 + (tmpvar_8 * 0.04))).xyz + texture (sampler_main, uv_1).xyz);\\n  crisp_2 = (crisp_2 * 0.5);\\n  crisp_2 = (crisp_2 + ((0.05 * \\n    (0.9 + (0.1 * roam_cos))\\n  .xyz) - (\\n    sqrt(dot (tmpvar_8, tmpvar_8))\\n   * 0.3)));\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = ((crisp_2 * 0.97) - 0.015);\\n  ret = tmpvar_9.xyz;\\n }\",comp:\"vec2 xlat_mutabledz;\\nvec3 xlat_mutableneu;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutableuv3;\\n shader_body { \\n  vec2 uv2_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = texsize.z;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = 0.0;\\n  tmpvar_3.y = texsize.w;\\n  xlat_mutabledz.x = dot ((texture (sampler_main, (uv + tmpvar_2)).xyz - texture (sampler_main, (uv - tmpvar_2)).xyz), vec3(0.32, 0.49, 0.29));\\n  xlat_mutabledz.y = dot ((texture (sampler_main, (uv + tmpvar_3)).xyz - texture (sampler_main, (uv - tmpvar_3)).xyz), vec3(0.32, 0.49, 0.29));\\n  uv2_1 = (uv - 0.5);\\n  xlat_mutableuv3 = ((0.2 * uv2_1) + 0.5);\\n  float tmpvar_4;\\n  tmpvar_4 = (time / 2.0);\\n  xlat_mutableuv3 = ((0.2 * cos(\\n    ((42.0 * fract(xlat_mutableuv3)) + tmpvar_4)\\n  )) + (99.0 * xlat_mutabledz));\\n  float tmpvar_5;\\n  tmpvar_5 = clamp ((0.01 / sqrt(\\n    dot (xlat_mutableuv3, xlat_mutableuv3)\\n  )), 0.0, 1.0);\\n  xlat_mutableneu = ((0.1 * vec3(tmpvar_5)) + (0.9 * dot (vec3(tmpvar_5), vec3(0.32, 0.49, 0.29))));\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (xlat_mutableneu * 1.252262));\\n  xlat_mutableuv3 = ((0.2 * uv2_1) + 0.5);\\n  xlat_mutableuv3 = ((0.2 * cos(\\n    ((42.0 * fract(xlat_mutableuv3)) + tmpvar_4)\\n  )) + (99.0 * xlat_mutabledz));\\n  float tmpvar_6;\\n  tmpvar_6 = clamp ((0.01 / sqrt(\\n    dot (xlat_mutableuv3, xlat_mutableuv3)\\n  )), 0.0, 1.0);\\n  xlat_mutableneu = ((0.1 * vec3(tmpvar_6)) + (0.9 * dot (vec3(tmpvar_6), vec3(0.32, 0.49, 0.29))));\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * 1.252262));\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = (xlat_mutableret1 + clamp ((\\n    (16.0 * ((0.5 * texture (sampler_main, (uv + \\n      (0.1 * xlat_mutabledz)\\n    )).xyz) + 0.01))\\n   * \\n    (0.1 + xlat_mutableret1)\\n  ), 0.0, 1.0));\\n  ret = tmpvar_7.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:4,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.527,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.8,wave_g:.49,ob_size:.015,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b2x:.3,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:506,sep:116,spectrum:1,thick:1,scaling:1.07408,smoothing:0,a:.7},init_eqs_str:\"a.n=0;a.m=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.n=Math.floor((a.reg00+.5)*a.sample);a.m=30001+div(a.n,div(a.reg00,a.reg01));a.gmegabuf[Math.floor(a.m)]=a.value1+a.value2;a.x=a.gmegabuf[Math.floor(1E4+a.n)];a.y=a.gmegabuf[Math.floor(15E3+a.n)];a.a=a.gmegabuf[Math.floor(2E4+a.n)];a.b=Math.min(Math.max(a.gmegabuf[Math.floor(25E3+a.n)],0),1);a.r=1-a.b;a.g=.5;\"},{baseVals:{enabled:1,samples:506,thick:1,scaling:.89152,smoothing:.82},init_eqs_str:\"a.n=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.n=Math.floor((a.reg00+.5)*a.sample)+a.reg00;a.x=a.gmegabuf[Math.floor(1E4+a.n)];a.y=a.gmegabuf[Math.floor(15E3+a.n)];a.a=a.gmegabuf[Math.floor(2E4+a.n)];a.b=Math.min(Math.max(a.gmegabuf[Math.floor(25E3+a.n)],0),1);a.r=1-a.b;a.g=.5;\"},{baseVals:{enabled:1,samples:506,thick:1,scaling:.89152,smoothing:.82},init_eqs_str:\"a.n=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.n=Math.floor((a.reg00+.5)*a.sample)+2*a.reg00;a.x=a.gmegabuf[Math.floor(1E4+a.n)];a.y=a.gmegabuf[Math.floor(15E3+a.n)];a.a=a.gmegabuf[Math.floor(2E4+a.n)];a.b=Math.min(Math.max(a.gmegabuf[Math.floor(25E3+a.n)],0),1);a.r=1-a.b;a.g=.5;\"},{baseVals:{enabled:1,samples:506,spectrum:1,thick:1},init_eqs_str:\"a.n=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.n=Math.floor((a.reg00-.5)*a.sample)+3*a.reg00;a.x=a.gmegabuf[Math.floor(1E4+a.n)];a.y=a.gmegabuf[Math.floor(15E3+a.n)];a.a=a.gmegabuf[Math.floor(2E4+a.n)];a.b=Math.min(Math.max(a.gmegabuf[Math.floor(25E3+a.n)],0),1);a.r=1-a.b;a.g=.5;\"}],init_eqs_str:\"a.xang=0;a.fov=0;a.hell=0;a.cbeat=0;a.index2=0;a.bindex=0;a.ran4=0;a.index=0;a.dec_v=0;a.yang=0;a.q29=0;a.q6=0;a.amp_=0;a.xlen=0;a.smooth=0;a.q1=0;a.dec_med=0;a.sum=0;a.q5=0;a.dec_f=0;a.trely=0;a.flen=0;a.reg01=0;a.my=0;a.oz=0;a.imag=0;a.is_beat=0;a.yind=0;a.oy0a=0;a.dec_slow=0;a.ran2=0;a.ind=0;a.z0=0;a.ylen=0;a.real=0;a.ran4_=0;a.ran3=0;a.q4=0;a.mz=0;a.oy0=0;a.amp=0;a.tc0=0;a.oy=0;a.avg=0;a.mx=0;a.vol=0;a.ran2_=0;a.peak=0;a.decc=0;a.q2=0;a.bd_bt=0;a.zang=0;a.q3=0;a.reg00=0;\\na.trelz=0;a.q32=0;a.ran3_=0;a.q28=0;a.trelx=0;a.q30=0;a.ox=0;a.xind=0;for(var b=a.index=0;7E4>b;b++)a.megabuf[Math.floor(a.index)]=0,a.gmegabuf[Math.floor(a.index)]=0,a.index+=1;a.zang=1;a.yang=0;a.zang=2;\",frame_eqs_str:\"a.xlen=45;a.ylen=45;a.flen=30;a.reg00=div(a.xlen*a.ylen,4);a.reg01=div(a.reg00,4);a.dec_med=1-div(.06*30,a.fps);a.dec_slow=1-div(.6,a.fps);a.dec_f=pow(.8,div(30,a.fps));a.q30=a.dec_slow;a.smooth=Math.max(1,pow(6,div(a.fps,30))-2);a.cbeat=a.bass+a.mid+a.treb;a.decc=.00001<Math.abs(a.vol>a.cbeat?1:0)?.8:a.dec_med;a.vol=a.vol*a.decc+(1-a.decc)*a.cbeat;a.avg=a.avg*a.dec_slow+a.cbeat*(1-a.dec_slow);a.is_beat=above(a.cbeat,1.5*a.avg)*above(a.time,a.tc0+.2);a.tc0=.00001<Math.abs(bor(a.is_beat,\\na.bd_bt))?a.time:a.tc0;a.peak=.00001<Math.abs(a.is_beat)?a.cbeat:a.peak*a.dec_med;a.ind=0;a.sum=0;a.amp=.01;for(var b=0;b<a.reg01;b++)a.sum+=div(a.gmegabuf[Math.floor(a.ind+3E4)],a.reg01),a.amp+=pow(a.gmegabuf[Math.floor(a.ind+3E4)],2),a.ind+=1;a.ind=0;a.amp_=a.amp_*a.dec_med+600*div((1-a.dec_med)*sqrt(a.amp),a.reg01);for(b=0;b<a.reg01;b++)a.megabuf[Math.floor(a.ind+3E4)]=div(a.gmegabuf[Math.floor(a.ind+3E4)]-a.sum,a.amp_),a.ind+=1;for(b=a.index2=0;b<a.flen;b++){a.index=0;a.real=0;for(var c=a.imag=\\n0;c<a.flen;c++)a.real+=Math.cos(6.28*div(a.index,a.flen)*a.index2)*a.megabuf[Math.floor(div(a.index*a.reg01,8)+30002)],a.imag+=Math.sin(6.28*div(a.index,a.flen)*a.index2)*a.megabuf[Math.floor(div(a.index*a.reg01,8)+30002)],a.index+=1;a.megabuf[Math.floor(1E4+a.index2)]=a.megabuf[Math.floor(1E4+a.index2)]*a.dec_f+a.real;a.megabuf[Math.floor(15E3+a.index2)]=a.megabuf[Math.floor(15E3+a.index2)]*a.dec_f+a.imag;a.index2+=1}a.ind=1;for(b=0;b<div(a.flen,2);b++){a.cx=a.megabuf[Math.floor(1E4+a.ind)];a.cy=\\na.megabuf[Math.floor(15E3+a.ind)];a.yind=-1;for(c=0;3>c;c++){a.xind=-1;for(var d=0;3>d;d++)a.ox=mod((a.cx+.5)*a.xlen+a.xind,a.xlen),a.oy=mod((a.cy+.5)*a.ylen+a.yind,a.ylen),a.amp=3*(a.cx*a.cx+a.cy*a.cy),a.megabuf[Math.floor(a.oy*a.ylen+a.ox)]-=div(div(60,a.fps)*sqrt(a.amp)*above(a.amp,.02),1+a.xind*a.xind+a.yind*a.yind),a.xind+=1;a.yind+=1}a.ind+=1}for(b=a.yind=0;b<a.ylen;b++){for(c=a.xind=0;c<a.xlen;c++)a.megabuf[Math.floor(a.yind*a.ylen+a.xind+5E3)]=a.dec_med*(div(a.gmegabuf[Math.floor(a.yind*a.ylen+\\nmod(a.xind+1,a.xlen))]+a.gmegabuf[Math.floor(a.yind*a.ylen+mod(a.xlen+a.xind-1,a.xlen))]+a.gmegabuf[Math.floor(mod(a.yind+1,a.ylen)*a.ylen+a.xind)]+a.gmegabuf[Math.floor(mod(a.yind+a.ylen-1,a.ylen)*a.ylen+a.xind)]+a.gmegabuf[Math.floor(a.yind*a.ylen+a.xind)]*a.smooth*4,2+2*a.smooth)-a.megabuf[Math.floor(a.yind*a.ylen+a.xind)]),a.xind+=1;a.yind+=1}a.bindex+=a.is_beat;.00001<Math.abs(a.is_beat&&.00001>Math.abs(mod(a.bindex,4)-0)?1:0)?a.ran2=div(randint(100)-30,60):0;.00001<Math.abs(a.is_beat&&.00001>\\nMath.abs(mod(a.bindex,4)-2)?1:0)?a.ran3=div(randint(100)-30,60):0;.00001<Math.abs(a.is_beat&&.00001>Math.abs(mod(a.bindex,6)-2)?1:0)?a.ran4=div(randint(100)-30,60):0;a.dec_v=Math.min(Math.max(0,1-div(8*a.vol,a.fps)),a.dec_slow);a.ran2_=a.ran2_*a.dec_v+(1-a.dec_v)*a.ran2;a.ran3_=a.ran3_*a.dec_v+(1-a.dec_v)*a.ran3;a.ran4_=a.ran4_*a.dec_v+(1-a.dec_v)*a.ran4;a.trelx+=div(div(a.ran2_,a.fps),7);a.trely+=div(div(a.ran3_,a.fps),2);a.trelz+=div(div(a.ran4_,a.fps),6);a.zang=6*Math.sin(a.trelz);a.xang=6*Math.sin(div(a.zang,\\n5)+a.trelx);a.yang=6*Math.sin(0*div(a.zang,3)+a.trely);a.q1=Math.cos(a.xang);a.q2=Math.sin(a.xang);a.q3=Math.cos(a.yang);a.q4=Math.sin(a.yang);a.q5=Math.cos(a.zang);a.q6=Math.sin(a.zang);a.fov=1;for(b=a.yind=0;b<a.ylen;b++){for(c=a.xind=0;c<a.xlen;c++)a.ind=a.yind*a.ylen+a.xind,a.megabuf[Math.floor(a.ind)]=a.gmegabuf[Math.floor(a.ind)],a.gmegabuf[Math.floor(a.ind)]=a.megabuf[Math.floor(a.ind+5E3)],a.oz=a.yind-div(a.ylen,2),a.ox=.00001<Math.abs(bnot(mod(a.yind,2)))?a.xind:a.xlen-a.xind-1,a.oy0a=div(a.oy0+\\na.oy0a,2.5),a.oy=a.gmegabuf[Math.floor(a.yind*a.ylen+a.ox)],a.oy0=a.oy,a.ox-=div(a.xlen,2),a.mx=a.ox*a.q5-a.oy*a.q6,a.my=a.ox*a.q6+a.oy*a.q5,a.ox=a.mx,a.oy=a.my,a.mx=a.ox*a.q3+a.oz*a.q4,a.mz=-a.ox*a.q4+a.oz*a.q3,a.ox=a.mx,a.oz=a.mz,a.my=a.oy*a.q1-a.oz*a.q2,a.mz=a.oy*a.q2+a.oz*a.q1,a.z0=90+40*Math.sin(14*a.trelz),a.oy=a.my,a.oz=a.mz+a.z0,a.gmegabuf[Math.floor(1E4+a.ind)]=div(a.fov*a.ox,a.oz)+.5,a.gmegabuf[Math.floor(15E3+a.ind)]=div(a.fov*a.oy,a.oz)+.5,a.hell=Math.max(Math.min(.5+div(a.oy0,4),1),.1),\\na.gmegabuf[Math.floor(2E4+a.ind)]=Math.max(Math.min(a.hell*(.5+.1*(a.oy0a-a.oy0)),1),.1),a.gmegabuf[Math.floor(25E3+a.ind)]=div(a.oy0,16)+.5,a.xind+=1;a.yind+=1}a.q29=div(50*a.fov,a.z0);a.q32=a.aspecty;a.q28=Math.min(div(a.vol,3)-.3,1);a.monitor=a.is_beat;\",pixel_eqs_str:\"a.rot=0;a.zoom=1.1;a.warp=0;a.dy=.02;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = vec3(0.0, 0.0, 0.0);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\"vec3 xlat_mutablecol;\\n shader_body { \\n  vec2 uv_1;\\n  uv_1 = uv;\\n  int iter_3;\\n  vec3 ret_4;\\n  ret_4 = texture (sampler_main, uv).xyz;\\n  iter_3 = int((clamp (q29, 0.0, 1.0) * 8.0));\\n  for (int n_2 = 1; n_2 < iter_3; n_2++) {\\n    vec2 tmpvar_5;\\n    tmpvar_5.y = 0.0;\\n    tmpvar_5.x = float(n_2);\\n    vec2 tmpvar_6;\\n    tmpvar_6.y = 0.0;\\n    tmpvar_6.x = float(n_2);\\n    ret_4 = max (max (ret_4, texture (sampler_main, (uv_1 - \\n      (texsize.zw * tmpvar_5)\\n    )).xyz), texture (sampler_main, (uv_1 + (texsize.zw * tmpvar_6))).xyz);\\n  };\\n  float tmpvar_7;\\n  tmpvar_7 = clamp ((1.0 - (2.0 * \\n    dot (ret_4, vec3(0.32, 0.49, 0.29))\\n  )), 0.0, 1.0);\\n  float tmpvar_8;\\n  float tmpvar_9;\\n  tmpvar_9 = (uv.x - 0.5);\\n  tmpvar_8 = (0.5 / ((\\n    (uv.y + ((tmpvar_9 * 1.4) * (q5 * q3)))\\n   - 0.4) + (0.3 * q4)));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = (tmpvar_8 * tmpvar_9);\\n  tmpvar_10.y = tmpvar_8;\\n  vec3 tmpvar_11;\\n  tmpvar_11.x = q2;\\n  tmpvar_11.y = q4;\\n  tmpvar_11.z = q6;\\n  xlat_mutablecol = (0.5 + (0.5 * tmpvar_11));\\n  float x_12;\\n  x_12 = ((uv.x - (\\n    dot (ret_4, vec3(0.32, 0.49, 0.29))\\n   * 5.0)) + 0.5);\\n  ret_4 = (ret_4 * (q28 + (\\n    ((6.0 * (0.05 / sqrt(\\n      (x_12 * x_12)\\n    ))) * (1.0 + xlat_mutablecol))\\n   / 2.0)));\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = q1;\\n  tmpvar_13.y = (q3 + time);\\n  float tmpvar_14;\\n  tmpvar_14 = (((\\n    (texture (sampler_noise_lq, (tmpvar_10 + tmpvar_13)).x * tmpvar_7)\\n   * \\n    float((tmpvar_8 > 0.0))\\n  ) * 0.2) * min (1.0, (1.0/(tmpvar_8))));\\n  ret_4 = (ret_4 + tmpvar_14);\\n  ret_4 = (ret_4 + ((\\n    (sin((12.0 * q2)) * tmpvar_7)\\n   * tmpvar_14) * dot (\\n    (12.0 * ((texture (sampler_blur1, (tmpvar_10 - vec2(-0.5, 0.3))).xyz * scale1) + bias1))\\n  , vec3(0.32, 0.49, 0.29))));\\n  ret_4 = (ret_4 + ((\\n    ((0.5 / abs(tmpvar_8)) * normalize(xlat_mutablecol))\\n   * \\n    float((tmpvar_8 < 0.0))\\n  ) * tmpvar_7));\\n  vec4 tmpvar_15;\\n  tmpvar_15.w = 1.0;\\n  tmpvar_15.xyz = ret_4;\\n  ret = tmpvar_15.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1.980001,decay:.5,echo_zoom:.999998,echo_alpha:.5,echo_orient:3,modwavealphabyvolume:1,darken:1,wave_a:.001,wave_scale:10.437056,wave_smoothing:.45,wave_mystery:.08,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.4595,warpscale:2.0067,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:.99,ob_size:0,ob_r:1,ob_g:1,ob_b:1,ib_size:0,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.4999,mv_g:.4999,mv_b:.4999,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,rad:.048958,tex_ang:1.00531,tex_zoom:1.531168,r:.5,g:1,b:.9,r2:.83,g2:.93,b2:.8,a2:1,border_b:0,border_a:0},init_eqs_str:\"a.trel=0;a.q20=0;a.q28=0;a.q26=0;\",frame_eqs_str:\"a.trel=div(a.time,2)+a.q20;a.x=.5+Math.sin(2*a.trel);a.y=.5+Math.cos(1.3*a.trel+div(a.q28,3));a.a=div(a.q26,4)+.2;\"},{baseVals:{enabled:0}},{baseVals:{enabled:1,x:.503,rad:.038857,tex_zoom:.609857,g:.1,a:.9,r2:1,b2:1,border_r:.5,border_g:.5,border_b:.5,border_a:0},init_eqs_str:\"a.is_beat=0;a.t0=0;a.q21=0;\",frame_eqs_str:\"a.x=div(randint(10),10);a.y=div(randint(10),10);a.r=div(randint(4),3);a.g=div(randint(4),3);a.b=div(randint(4),3);a.is_beat=above(a.time,a.t0+.03);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.a=Math.min(div(a.q21,2),.9)*a.is_beat;a.rad=div(a.a*a.a,3);\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,sep:120,additive:1,scaling:.891519,smoothing:.82,a:.6},init_eqs_str:\"a.k1=0;a.k2=0;a.xi=0;a.yi=0;a.dx=0;a.dy=0;a.q22=0;a.t2=0;a.t1=1+.3*(.01*randint(101)-.01*randint(101));a.t2=1+.3*(.01*randint(101)-.01*randint(101));a.t3=1+.3*(.01*randint(101)-.01*randint(101));a.t4=1+.3*(.01*randint(101)-.01*randint(101));a.t5=1+.3*(.01*randint(101)-.01*randint(101));a.t6=1+.3*(.01*randint(101)-.01*randint(101));a.t7=1+.3*(.01*randint(101)-.01*randint(101));a.t8=1+.3*(.01*randint(101)-.01*randint(101));\",frame_eqs_str:\"a.t2+=a.bass_att;\",point_eqs_str:\"a.k1=mod(100*a.sample,8);a.k2=bnot(a.k1);a.xi=a.value1*a.k2+a.xi*(1-a.k2);a.yi=a.value2*(1-a.k2)+a.yi*a.k2;a.dx=.99*a.dx+a.xi;a.dy=.99*a.dy+a.yi;a.x=.5+div(a.xi,2);a.y=.5+div(a.yi,2);a.a=div(a.q22,8);a.a=Math.min(a.a,.2);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index=0;a.q22=0;a.q21=0;a.fade=0;a.q1=0;a.dec_med=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q32=0;a.q20=0;a.fade=.5;\",frame_eqs_str:\"a.dec_med=pow(.9,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.q26=a.bass+a.mid+a.treb;a.k1=a.is_beat*equal(a.index,0);a.p1=\\na.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.14159265358*a.p2,2);a.q27=a.index+1;a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.zoom=1;a.rot=-0*a.index;a.fade=a.fade*a.dec_med+pow(.996,div(30,a.fps))*(1-a.dec_med);a.q32=a.fade;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 zz_1;\\n  mat2 tmpvar_2;\\n  tmpvar_2[uint(0)] = _qa.xy;\\n  tmpvar_2[1u] = _qa.zw;\\n  zz_1 = (((\\n    (uv - vec2(0.5, 0.5))\\n   * texsize.xy) * (0.015 * q27)) * tmpvar_2);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = (((q32 * texture (sampler_main, \\n    (uv + ((clamp (\\n      (sin(zz_1) / cos(zz_1))\\n    , vec2(-20.0, -20.0), vec2(20.0, 20.0)) * texsize.zw) * 8.0))\\n  ).xyz) + (\\n    (0.03 * texture (sampler_noise_lq, ((uv * 0.3) + (0.01 * rand_frame).xy)))\\n  .xyz * \\n    (1.0 - ((texture (sampler_blur1, uv).xyz * scale1) + bias1))\\n  )) - 0.02);\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1 = texture (sampler_main, uv);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ((tmpvar_1.xyz + clamp (\\n    (3.0 * (((texture (sampler_blur1, \\n      (uv - (0.01 * tmpvar_1.xyz).xy)\\n    ).xyz * scale1) + bias1) - vec3(0.1, 0.1, 0.2)))\\n  , 0.0, 1.0)) * 1.3);\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:.952,echo_alpha:.5,echo_orient:3,wave_mode:6,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:2.103,wave_smoothing:.54,wave_mystery:.38,modwavealphastart:.81,modwavealphaend:1.4,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:0,wave_g:0,wave_b:0,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:1,sides:16,thickoutline:1,textured:1,num_inst:3,x:.73,rad:.29466,tex_zoom:1.87511,r:.7,g:.7,b:1,g2:0,border_b:0,border_a:0},init_eqs_str:\"a.trig=0;a.q25=0;a.x0=0;a.y0=0;\",frame_eqs_str:\"a.trig=a.q25;a.a=.8*a.trig;a.a2=0;a.x0=a.x0*bnot(a.trig)+div(a.trig*randint(100),100);a.y0=a.y0*bnot(a.trig)+div(a.trig*randint(100),100);a.tex_ang=randint(20);a.rad=.1+div(randint(10),8);a.x=a.x0;a.y=a.y0;a.r=.7+.3*Math.sin(div(a.time,12));a.b=.7+.3*Math.sin(div(a.time,15));a.g=.7+.3*Math.sin(div(a.time,8));a.r2=a.r;a.b2=a.b;a.g2=a.g;\"},{baseVals:{enabled:1,sides:36,thickoutline:1,textured:1,num_inst:4,x:.3,rad:.05429,ang:1.25664,tex_ang:.37699,tex_zoom:1.02841,g:.7,b:.5,r2:1,g2:0,border_g:.59,border_b:0,border_a:0},init_eqs_str:\"a.q31=0;a.q32=0;a.q30=0;\",frame_eqs_str:\"a.x=a.q31;a.y=a.q32;a.rad=.06;a.tex_ang=a.time;a.a=a.q30;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q25=0;a.index=0;a.q12=0;a.q22=0;a.q21=0;a.q15=0;a.q29=0;a.q6=0;a.dec_med=0;a.q5=0;a.mindev=0;a.trel=0;a.t0a=0;a.mov1=0;a.vis=0;a.is_beat=0;a.q31=0;a.q23=0;a.q24=0;a.dec_slow=0;a.q11=0;a.hpeak=0;a.q10=0;a.sdev=0;a.med=0;a.spb=0;a.dir=0;a.spb_=0;a.q16=0;a.rota=0;a.q19=0;a.vol=0;a.peak=0;a.trig1=0;a.wamp=0;a.speed=0;a.t0=0;a.vol_=0;a.q32=0;a.q7=0;a.wamp_=0;a.q30=0;a.q20=0;a.q8=0;a.t0a=a.time;a.t0=a.time+.5;a.spb_=.5;a.volb=.5;a.volx=.5;a.vol_=1;a.index=0;a.mov1=0;a.sdev=.1;a.wamp_=\\n.1;\",frame_eqs_str:\"a.dec_med=pow(.8,div(30,a.fps));a.dec_slow=pow(.95,div(30,a.fps));a.vol=div(a.bass+a.med+a.treb,1.5);a.vol_=a.vol_*a.dec_slow+(1-a.dec_slow)*a.vol;a.is_beat=above(a.vol,a.vol_+2*a.peak)*above(a.time,a.t0+.45*a.spb_);a.t0a=.00001<Math.abs(a.is_beat)?a.t0:a.t0a;a.t0=.00001<Math.abs(a.is_beat)?a.time:a.t0;a.peak=.00001<Math.abs(a.is_beat)?a.vol:a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,128);a.spb=Math.min(a.t0-a.t0a+.01,2);a.spb_=.00001<Math.abs(a.is_beat)?.9*a.spb_+.1*a.spb:\\na.spb_;a.q20=a.vol_;a.q21=above(a.vol,2.7*a.vol_);a.q22=Math.max(0,a.peak-0)+.01;a.hpeak=a.hpeak*a.dec_med+(1-a.dec_med)*a.q21;a.q23=a.hpeak*(1+randint(8));a.q24=a.is_beat;a.q25=div(a.q22*(1+randint(8)),8);a.mindev=Math.min(Math.min(Math.abs(a.spb-a.spb_),Math.abs(2*a.spb-a.spb_)),Math.abs(a.spb-2*a.spb_));a.sdev=.00001<Math.abs(a.is_beat)?.8*a.sdev+.2*pow(a.mindev+.02,2):a.sdev;a.speed=div(div(1,a.fps),a.spb_);a.trel+=a.speed;a.q10=a.trel;a.wamp=Math.min(div(.001,a.sdev),.15);a.wamp_=a.wamp_*a.dec_slow+\\n(1-a.dec_slow)*a.wamp;a.q11=Math.sin(div(a.trel,2))*a.wamp_;a.q12=div(a.wamp_,2);a.rota=2*a.wamp_*Math.sin(div(a.trel,3));a.q5=Math.cos(a.rota);a.q6=Math.sin(a.rota);a.q7=-a.q6;a.q8=a.q5;a.q15=.05*-Math.sin(.5*a.trel);a.q16=div(Math.cos(a.trel)*a.wamp_,2);a.q19=.1*Math.sin(div(a.trel,12));a.trig1=bnot(a.vis)*bnot(randint(100*a.fps));a.vis=.00001<Math.abs(a.trig1)?1:a.vis*below(a.mov1,1);a.q30=a.vis;a.mov1=.00001<Math.abs(a.vis)?a.mov1+div(2*a.speed,a.fps):-1;a.dir=.00001<Math.abs(a.trig1)?randint(100):\\na.dir;a.q31=.5+.5*Math.cos(a.dir)*a.mov1;a.q32=.5+.5*Math.sin(a.dir)*a.mov1;a.q29=2+Math.sin(div(a.time,17));a.monitor=a.wamp;\",pixel_eqs_str:\"a.zoom=1+.02*a.rad*a.q20;a.dy=-0;a.warp=.1;a.dx=0;\",warp:\"mat2 ofs;\\nvec2 xlat_mutableuv2;\\nfloat xlat_mutablezv;\\n shader_body { \\n  mat2 tmpvar_1;\\n  tmpvar_1[uint(0)].x = texsize.z;\\n  tmpvar_1[uint(0)].y = 0.0;\\n  tmpvar_1[1u].x = 0.0;\\n  tmpvar_1[1u].y = texsize.w;\\n  ofs = (tmpvar_1 * 4.0);\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = ((uv.x - 0.5) + q19);\\n  tmpvar_2.y = (uv.y - 0.5);\\n  vec2 v_3;\\n  v_3.x = ofs[0].x;\\n  v_3.y = ofs[1].x;\\n  vec2 v_4;\\n  v_4.x = ofs[0].x;\\n  v_4.y = ofs[1].x;\\n  vec2 v_5;\\n  v_5.x = ofs[0].y;\\n  v_5.y = ofs[1].y;\\n  vec2 v_6;\\n  v_6.x = ofs[0].y;\\n  v_6.y = ofs[1].y;\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = (texture (sampler_main, (uv + v_3)) - texture (sampler_main, (uv - v_4))).z;\\n  tmpvar_7.y = (texture (sampler_main, (uv + v_5)) - texture (sampler_main, (uv - v_6))).z;\\n  xlat_mutablezv = (time * 0.08);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = (0.02 * time);\\n  tmpvar_8.y = (-0.05 * time);\\n  xlat_mutableuv2 = ((3.0 * tmpvar_2) + tmpvar_8);\\n  vec3 tmpvar_9;\\n  tmpvar_9.xy = xlat_mutableuv2;\\n  tmpvar_9.z = xlat_mutablezv;\\n  vec3 tmpvar_10;\\n  tmpvar_10.xy = (xlat_mutableuv2 * vec2(2.0, 2.0));\\n  tmpvar_10.z = (xlat_mutablezv * 2.0);\\n  vec3 tmpvar_11;\\n  tmpvar_11.xy = (xlat_mutableuv2 * vec2(4.0, 4.0));\\n  tmpvar_11.z = (xlat_mutablezv * 3.0);\\n  vec3 tmpvar_12;\\n  tmpvar_12.xy = (xlat_mutableuv2 * vec2(8.0, 8.0));\\n  tmpvar_12.z = (xlat_mutablezv * 7.0);\\n  xlat_mutableuv2 = (tmpvar_2 + ((\\n    (((texture (sampler_noisevol_hq, tmpvar_9).z + (texture (sampler_noisevol_hq, tmpvar_10).z / 2.0)) + (texture (sampler_noisevol_hq, tmpvar_11).z / 4.0)) + (texture (sampler_noisevol_hq, tmpvar_12).z / 8.0))\\n   - 1.0) * 0.1));\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 1.0;\\n  tmpvar_13.xyz = (((\\n    (((0.2 + (\\n      (((1.0 + bass_att) * 0.01) / sqrt(dot (xlat_mutableuv2, xlat_mutableuv2)))\\n     * \\n      (1.0 + normalize(slow_roam_cos))\\n    .xyz)) + ((rand_preset.z - 0.5) * xlat_mutableuv2.y)) * 0.1)\\n   / 2.0) + (texture (sampler_main, \\n    (uv - (0.02 * tmpvar_7))\\n  ).xyz * 0.9)) - 0.01);\\n  ret = tmpvar_13.xyz;\\n }\",comp:\"float xlat_mutablerain;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutablers;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutableuv1;\\nfloat xlat_mutablewater;\\nfloat xlat_mutablez;\\n shader_body { \\n  vec2 uv_1;\\n  mat2 tmpvar_2;\\n  tmpvar_2[uint(0)] = _qb.xy;\\n  tmpvar_2[1u] = _qb.zw;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q15;\\n  tmpvar_3.y = q16;\\n  uv_1 = (((\\n    (((uv - 0.5) * tmpvar_2) * 0.7)\\n   * aspect.xy) + 0.5) + tmpvar_3);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = 0.5;\\n  tmpvar_4.y = ((q11 + 0.6) + (q12 * (\\n    sin(((uv_1.x * 6.0) + q10))\\n   * \\n    cos(((uv_1.y * 8.0) + (time * 0.6)))\\n  )));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (uv_1.x * 4.0);\\n  tmpvar_5.y = uv_1.y;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = (uv_1.x * 4.0);\\n  tmpvar_6.y = uv_1.y;\\n  xlat_mutablerain = (texture (sampler_noise_lq, ((tmpvar_5 * 0.2) - time)).x + texture (sampler_noise_lq, ((tmpvar_6 * 0.5) - time)).x);\\n  float tmpvar_7;\\n  tmpvar_7 = (time / 4.0);\\n  xlat_mutablerain = (xlat_mutablerain * clamp ((\\n    (q20 / 2.0)\\n   - \\n    abs(sin(((uv.x / 4.0) - tmpvar_7)))\\n  ), 0.0, 1.0));\\n  xlat_mutableuv1 = ((uv_1 - tmpvar_4) + (xlat_mutablerain * 0.01));\\n  vec3 tmpvar_8;\\n  tmpvar_8.x = xlat_mutableuv1.y;\\n  tmpvar_8.y = (xlat_mutableuv1.x * 2.0);\\n  tmpvar_8.z = (time * 0.2);\\n  xlat_mutableuv1 = (xlat_mutableuv1 + ((texture (sampler_noisevol_hq, tmpvar_8) * \\n    (0.5 - abs(xlat_mutableuv1.y))\\n  ).x * 0.05));\\n  float tmpvar_9;\\n  tmpvar_9 = clamp ((128.0 * xlat_mutableuv1.y), 0.0, 1.0);\\n  xlat_mutablez = (0.4 / xlat_mutableuv1.y);\\n  xlat_mutablers0.x = (xlat_mutableuv1.x * xlat_mutablez);\\n  xlat_mutablers0.y = xlat_mutablez;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = (xlat_mutablers0.x + tmpvar_7);\\n  tmpvar_10.y = (xlat_mutablez + (time * 4.0));\\n  xlat_mutablers = (tmpvar_10 * tmpvar_9);\\n  xlat_mutablewater = (texture (sampler_noise_hq, xlat_mutablers) + texture (sampler_noise_hq, ((xlat_mutablers / 4.0) - (time / 8.0)))).x;\\n  xlat_mutablewater = (xlat_mutablewater - 1.0);\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = (xlat_mutableuv1.x + 0.5);\\n  tmpvar_11.y = abs((0.5 - xlat_mutableuv1.y));\\n  xlat_mutableret1 = (((texture (sampler_main, uv_1).xyz * \\n    (1.0 - tmpvar_9)\\n  ) + (\\n    ((texture (sampler_main, (tmpvar_11 - (0.2 * xlat_mutablewater))).xyz * tmpvar_9) * pow ((1.0/(xlat_mutablez)), 0.2))\\n   * \\n    (2.0 - rand_preset.y)\\n  )) + ((\\n    (((0.25 + rand_preset.y) * (1.0 + (rand_preset.x * xlat_mutablewater))) * tmpvar_9)\\n   / xlat_mutablez) * vec3(0.0, 0.1, 0.1)));\\n  xlat_mutableret1 = (xlat_mutableret1 + (0.06 * xlat_mutablerain));\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 1.0;\\n  tmpvar_12.xyz = (1.0 - exp((\\n    (-(pow (xlat_mutableret1, vec3(1.5, 1.5, 1.5))) * 8.0)\\n   * \\n    (1.0 + (q23 * 4.0))\\n  )));\\n  ret = tmpvar_12.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:.952,echo_alpha:.5,echo_orient:3,wave_mode:4,additivewave:1,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.527,wave_smoothing:.45,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.8,wave_g:.49,ob_size:.015,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:12,additive:1,num_inst:571,x:.26,y:.2,rad:.39317,tex_zoom:.9355,g2:0,a2:.2,border_g:0,border_b:0,border_a:0},init_eqs_str:\"a.px=0;a.fov=0;a.q12=0;a.copy=0;a.q18=0;a.tht=0;a.q15=0;a.flim=0;a.q1=0;a.q5=0;a.py=0;a.mov1=0;a.vis=0;a.oz=0;a.k1=0;a.q11=0;a.z0=0;a.q10=0;a.copies=0;a.v0=0;a.q4=0;a.burst=0;a.oy=0;a.rota=0;a.q19=0;a.q17=0;a.spur=0;a.q2=0;a.q14=0;a.rotmode=0;a.q3=0;a.t0=0;a.phi=0;a.ox=0;\",frame_eqs_str:\"a.mov1=a.q1;a.rotmode=a.q3;a.burst=a.q10;a.copies=a.q14;a.copy=div(mod(a.instance,a.copies),a.copies);a.k1=div(Math.floor(div(a.instance,a.copies))*a.copies,a.num_inst);a.k1=div(Math.floor(a.k1*a.burst),a.burst)+div(a.k1,a.burst);a.mov1=a.mov1+a.k1-a.copy*a.q2;a.mov1-=Math.floor(a.mov1);a.rotmode-=a.copy*a.q4;a.rota=a.mov1*a.rotmode*a.q5*2;a.mov1=a.mov1*(1-a.rotmode)+a.rotmode*(.5+.025*a.k1);a.mov1=pow(a.mov1,.9);a.tht=Math.sin(a.k1*a.k1*123.2)*(.2+0*a.rotmode);a.phi=1613.3*\\na.k1+a.rota;a.v0=(1+.3*Math.cos(13234.7*a.k1))*a.q5;a.z0=div(a.q18,a.q5);a.t0=.4;a.spur=(a.mov1-a.t0)*above(a.mov1-a.t0,0)*a.q15;a.py=a.spur*Math.sin(6.28*a.copy);a.px=a.spur*Math.cos(6.28*a.copy);a.fov=2*a.z0;a.ox=(a.mov1-a.q19)*a.v0*Math.sin(a.tht)*Math.cos(a.phi);a.oy=a.mov1*a.v0*(1-a.mov1)*Math.cos(2*a.tht)-.25;a.oz=a.mov1*a.v0*Math.sin(a.tht)*Math.sin(a.phi);a.ox=a.ox+(a.k1-.5)*a.q17+a.px;a.oy-=a.py;a.oz+=3*a.py;a.rad=div(.025*a.z0,a.oz+a.z0)*(1-.5*a.mov1);a.x=.5+div(a.fov*a.ox,a.oz+a.z0);a.y=\\n.5+div(a.fov*a.oy,a.oz+a.z0);a.vis=above(a.mov1,a.q11)*below(a.mov1,a.q12)*above(a.oz,-a.z0);a.a=div(.7*a.vis,sqrt(a.copies))*(1+above(a.spur,0));a.a2=0;a.g=a.flim;\"},{baseVals:{enabled:1,sides:13,additive:1,num_inst:212,x:.65,y:.38,rad:1.26467,tex_zoom:.73678,g:1,a:.3,r2:1,g2:0,border_r:.5,border_g:.5,border_b:0,border_a:0},init_eqs_str:\"a.mov2=0;a.q25=0;a.copy=0;a.tht=0;a.q29=0;a.trel=0;a.mov1=0;a.oz=0;a.k1=0;a.z0=0;a.copies=0;a.k2=0;a.oy=0;a.stray=0;a.q27=0;a.size0=0;a.phase=0;a.t0=0;a.phi=0;a.ox=0;\",frame_eqs_str:\"a.trel=a.q25;a.copies=1;a.copy=div(mod(a.instance,a.copies),a.copies);a.k1=div(Math.floor(div(a.instance,a.copies))*a.copies,a.num_inst);a.k2=a.k1+.5;a.trel=a.trel;a.t0=.5;a.phase=above(a.trel,a.t0);a.mov1=bnot(a.phase)*(a.t0-a.trel+.01*a.k1);a.mov2=a.phase*(a.trel-a.t0);a.stray=1.2-a.phase;a.tht=3.14*Math.sin(1234.2*a.k1+a.time*bnot(a.phase))*a.stray;a.phi=3245.1*a.k1;a.size0=.02;a.ox=a.mov1*a.q27+Math.sin(a.tht)*Math.cos(a.phi)*(a.size0+a.mov2*(2+a.k1));a.oy=12*a.mov1+div(Math.cos(a.tht)*\\n(a.size0+4*a.mov2*a.k2)*(1-a.mov2*a.k2),2);a.oz=8*a.mov1+Math.sin(a.tht)*Math.sin(a.phi)*(a.size0+2*a.mov2*(2+a.k1));a.z0=1;a.rad=div(div(.03,a.oz+a.z0),1+div(a.trel*randint(100),50));a.x=.5+div(a.ox,a.oz+a.z0);a.y=a.q29+.2+div(a.oy,a.oz+a.z0);a.a=.1*bnot(a.phase)+a.phase*Math.max(0,1-0*a.mov2)*above(a.oz+a.z0,0)*.8;\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.stop=0;a.q25=0;a.index=0;a.q12=0;a.q18=0;a.q22=0;a.q21=0;a.q13=0;a.q15=0;a.q29=0;a.q6=0;a.q1=0;a.dec_med=0;a.q5=0;a.vshift=0;a.lo=0;a.xtime=0;a.t0a=0;a.mov1=0;a.is_beat=0;a.q31=0;a.q23=0;a.q24=0;a.dec_slow=0;a.q11=0;a.hpeak=0;a.q10=0;a.copies=0;a.q4=0;a.med=0;a.hi=0;a.vs0=0;a.bursts=0;a.spb_=0;a.volb=0;a.q16=0;a.q26=0;a.q19=0;a.q17=0;a.vol=0;a.peak=0;a.spur=0;a.q2=0;a.q27=0;a.q14=0;a.rotmode=0;a.wind=0;a.tmp=0;a.xbase=0;a.speed=0;a.q3=0;a.t0=0;a.vol_=0;a.q32=0;a.spread=0;\\na.q28=0;a.q30=0;a.q20=0;a.volx=0;a.t0a=a.time;a.t0=a.time+.5;a.spb_=.5;a.volb=.5;a.volx=.5;a.vol_=1;a.index=0;a.mov1=0;\",frame_eqs_str:\"a.dec_med=pow(.85,div(30,a.fps));a.dec_slow=pow(.95,div(30,a.fps));a.vol=div(a.bass+a.med+a.treb,1.5);a.vol_=a.vol_*a.dec_slow+(1-a.dec_slow)*a.vol;a.is_beat=above(a.vol,.1+a.vol_+2*a.peak)*above(a.time,a.t0+.45*a.spb_);a.t0a=.00001<Math.abs(a.is_beat)?a.t0:a.t0a;a.t0=.00001<Math.abs(a.is_beat)?a.time:a.t0;a.peak=.00001<Math.abs(a.is_beat)?a.vol:a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,128);a.spb_=.00001<Math.abs(a.is_beat)?.9*a.spb_+.1*Math.min(a.t0-a.t0a+.01,2):a.spb_;\\na.q20=a.vol_;a.q21=above(a.vol,2.7*a.vol_);a.q22=Math.max(0,a.peak-0)+.01;a.hpeak=a.hpeak*a.dec_med+(1-a.dec_med)*a.q21;a.q23=a.hpeak*(1+randint(8));a.q24=a.is_beat;a.volb=bnot(a.q24)*a.volb+a.q24*a.vol_;a.volx+=div(.2,a.fps)*Math.max(Math.min(a.volb-a.volx,1),-1)*bnot(a.rotmode);a.rotmode=Math.max(Math.min(4*Math.sin(div(a.mov1,2.4)-1.5)-3,1),0);a.stop=(.00001<Math.abs(bnot(a.stop))?bnot(mod(a.index,24)):below(a.lo,1))*bnot(a.rotmode);a.spread=.00001<Math.abs(below(a.lo,1))?a.spread:div(randint(2)*\\nrandint(12),20);a.copies=.00001<Math.abs(below(a.lo,1))?a.copies:3+randint(2)*randint(8);a.spur=.00001<Math.abs(below(a.lo,1))?a.spur:.1*above(a.copies,5);a.bursts=.00001<Math.abs(below(a.lo,1))?a.bursts:1+randint(2)*randint(6);a.xbase=.00001<Math.abs(below(a.lo,1))?a.xbase:randint(2)*(div(randint(10),10)-.5);a.vs0=.00001<Math.abs(a.is_beat*bnot(mod(a.index,77)))?div(randint(5),4)-.7:a.vs0;a.vshift+=div(3,a.fps)*Math.max(Math.min(a.vs0-a.vshift,.04),-.04);a.speed=div(div(.15,a.fps),a.spb_);a.tmp=\\na.mov1;a.mov1+=a.speed;a.q2=a.mov1-a.tmp;a.q1=a.mov1;a.tmp=a.rotmode;a.q3=a.rotmode;a.q4=a.rotmode-a.tmp;a.tmp=a.volx;a.q5=a.volx;a.q6=a.q5-a.tmp;a.q10=a.bursts;a.lo=.00001<Math.abs(a.stop)?a.lo+a.speed:0;a.hi=.00001<Math.abs(above(a.lo,1))?0:a.hi+a.speed;a.q11=a.lo;a.q12=a.hi;a.q13=0*sqrt(a.q22);a.q14=a.copies;a.q15=a.spur*(1-a.rotmode);a.q16=0;a.q17=a.spread*(1-a.rotmode);a.q18=div(1,Math.min(Math.max(10*Math.sin(div(a.mov1,2)),1),4));a.q19=a.xbase;a.xtime=.00001<Math.abs(a.stop*a.q21*above(a.xtime,\\n2))?0:a.xtime+div(.2,a.fps);a.q25=a.xtime;a.q26=.00001<Math.abs(below(a.xtime,.55))?pow(32,512*-sqr(a.xtime-.55)):pow(2,3*-sqr(a.xtime-.55));a.q27=4*Math.sin(div(a.time,29));a.wind+=div(.5,a.fps)*(a.volx-1.5);a.q28=a.wind;a.q29=a.vshift;a.q30=Math.max(Math.sin(div(a.mov1,2.2))*Math.sin(div(a.time,7)),0)+a.q26;a.q31=2*a.q5-2+Math.sin(div(a.time,17));a.q32=3+2*Math.sin(div(a.time,27));a.monitor=a.vshift;\",pixel_eqs_str:\"a.zoom=1;a.dy=-0;a.warp=0;\",warp:\"mat2 ofs;\\nfloat xlat_mutablegreen;\\nfloat xlat_mutablek1;\\nfloat xlat_mutablered;\\nvec2 xlat_mutableuv2;\\nfloat xlat_mutablewave;\\nfloat xlat_mutablezv;\\n shader_body { \\n  mat2 tmpvar_1;\\n  tmpvar_1[uint(0)].x = texsize.z;\\n  tmpvar_1[uint(0)].y = 0.0;\\n  tmpvar_1[1u].x = 0.0;\\n  tmpvar_1[1u].y = texsize.w;\\n  ofs = (tmpvar_1 * 4.0);\\n  float delta_2;\\n  float ky_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (uv.x - 0.5);\\n  tmpvar_4.y = ((uv.y - 0.5) + q29);\\n  vec2 v_5;\\n  v_5.x = ofs[0].x;\\n  v_5.y = ofs[1].x;\\n  vec2 v_6;\\n  v_6.x = ofs[0].x;\\n  v_6.y = ofs[1].x;\\n  vec2 v_7;\\n  v_7.x = ofs[0].y;\\n  v_7.y = ofs[1].y;\\n  vec2 v_8;\\n  v_8.x = ofs[0].y;\\n  v_8.y = ofs[1].y;\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = (texture (sampler_main, (uv + v_5)) - texture (sampler_main, (uv - v_6))).x;\\n  tmpvar_9.y = (texture (sampler_main, (uv + v_7)) - texture (sampler_main, (uv - v_8))).x;\\n  xlat_mutablered = (0.5 * texture (sampler_main, (uv - (0.004 * tmpvar_9))).x);\\n  xlat_mutablered = (xlat_mutablered + (0.5 * texture (sampler_main, uv).x));\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4.x;\\n  tmpvar_10.y = (0.0078125 * (float(\\n    int((tmpvar_4.y * 128.0))\\n  ) + abs(\\n    (fract((tmpvar_4.y * 128.0)) - 0.5)\\n  )));\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (tmpvar_10 * 4.0);\\n  ky_3 = clamp ((-0.5 - tmpvar_11.y), 0.0, 1.0);\\n  xlat_mutablek1 = (abs((\\n    fract((tmpvar_11.x * 2.0))\\n   - 0.5)) * 8.0);\\n  xlat_mutablek1 = (xlat_mutablek1 - sign(xlat_mutablek1));\\n  delta_2 = (0.1 + (rand_preset * 0.05)).x;\\n  xlat_mutablek1 = (xlat_mutablek1 - ((\\n    (4.0 * sign(xlat_mutablek1))\\n   * ky_3) * ky_3));\\n  ky_3 = clamp ((ky_3 - delta_2), 0.0, 1.0);\\n  xlat_mutablek1 = (xlat_mutablek1 - ((\\n    (8.0 * sign(xlat_mutablek1))\\n   * ky_3) * ky_3));\\n  ky_3 = clamp ((ky_3 - delta_2), 0.0, 1.0);\\n  xlat_mutablek1 = (xlat_mutablek1 - ((\\n    (12.0 * sign(xlat_mutablek1))\\n   * ky_3) * ky_3));\\n  ky_3 = clamp ((ky_3 - delta_2), 0.0, 1.0);\\n  xlat_mutablek1 = (xlat_mutablek1 - ((\\n    (16.0 * sign(xlat_mutablek1))\\n   * ky_3) * ky_3));\\n  ky_3 = clamp ((ky_3 - delta_2), 0.0, 1.0);\\n  float tmpvar_12;\\n  tmpvar_12 = clamp (xlat_mutablek1, -1.6, 1.6);\\n  xlat_mutablek1 = tmpvar_12;\\n  xlat_mutablegreen = (cos((tmpvar_12 * 2.0)) - 0.1);\\n  xlat_mutablewave = ((sin(\\n    ((q1 * 8.0) - (uv.x * 6.0))\\n  ) / 2.0) * q3);\\n  xlat_mutablewave = ((xlat_mutablewave * float(\\n    (xlat_mutablewave >= 0.0)\\n  )) + (q30 * 0.02));\\n  xlat_mutablered = (xlat_mutablered + ((\\n    (xlat_mutablewave / abs(sin((\\n      (1.0/(tmpvar_12))\\n     + \\n      (q1 / 8.0)\\n    ))))\\n   * xlat_mutablegreen) * ky_3));\\n  xlat_mutablezv = ((time * 0.08) + (0.2 * sin(\\n    ((uv * 16.0) + time)\\n  ))).x;\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = q28;\\n  tmpvar_13.y = (0.2 * time);\\n  xlat_mutableuv2 = ((tmpvar_4 * 2.0) + tmpvar_13);\\n  vec3 tmpvar_14;\\n  tmpvar_14.xy = xlat_mutableuv2;\\n  tmpvar_14.z = xlat_mutablezv;\\n  vec3 tmpvar_15;\\n  tmpvar_15.xy = (xlat_mutableuv2 * vec2(2.0, 2.0));\\n  tmpvar_15.z = (xlat_mutablezv * 2.0);\\n  vec3 tmpvar_16;\\n  tmpvar_16.xy = (xlat_mutableuv2 * vec2(4.0, 4.0));\\n  tmpvar_16.z = (xlat_mutablezv * 3.0);\\n  vec3 tmpvar_17;\\n  tmpvar_17.xy = (xlat_mutableuv2 * vec2(8.0, 8.0));\\n  tmpvar_17.z = (xlat_mutablezv * 7.0);\\n  xlat_mutableuv2 = (tmpvar_4 + ((\\n    ((texture (sampler_noisevol_hq, tmpvar_14).z + (texture (sampler_noisevol_hq, tmpvar_15).z / 2.0)) + (texture (sampler_noisevol_hq, tmpvar_16).z / 4.0))\\n   + \\n    (texture (sampler_noisevol_hq, tmpvar_17).z / 8.0)\\n  ) * 0.1));\\n  vec3 tmpvar_18;\\n  tmpvar_18.x = xlat_mutablered;\\n  tmpvar_18.y = xlat_mutablegreen;\\n  tmpvar_18.z = ((1.0 + xlat_mutableuv2.y) * sqrt(dot (xlat_mutableuv2, xlat_mutableuv2)));\\n  vec4 tmpvar_19;\\n  tmpvar_19.w = 1.0;\\n  tmpvar_19.xyz = ((tmpvar_18 * 0.8) - 0.005);\\n  ret = tmpvar_19.xyz;\\n }\",comp:\"float trel;\\nfloat vshift;\\nvec3 xlat_mutableret1;\\nvec2 xlat_mutablers;\\nvec2 xlat_mutablers0;\\nfloat xlat_mutablesmoke;\\nfloat xlat_mutablesmoke2;\\nvec2 xlat_mutableuv_l;\\nfloat xlat_mutablew;\\nfloat xlat_mutablez;\\n shader_body { \\n  trel = (time / 2.0);\\n  vshift = (0.5 - q29);\\n  vec2 tmpvar_1;\\n  tmpvar_1.x = rand_preset.x;\\n  tmpvar_1.y = ((-0.1 - (rand_preset.y / 2.0)) + vshift);\\n  vec2 tmpvar_2;\\n  tmpvar_2.y = 0.0;\\n  tmpvar_2.x = (0.005 * time);\\n  xlat_mutableuv_l = (uv + tmpvar_2);\\n  vec2 tmpvar_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (uv - 0.5);\\n  tmpvar_3 = sin(((\\n    (tmpvar_4 * aspect.xy)\\n   + 0.5) - (tmpvar_1 * aspect.xy)));\\n  vec2 tmpvar_5;\\n  tmpvar_5 = fract(uv);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = vec3((texture (sampler_fc_main, tmpvar_5).x + (2.0 * (\\n    (texture (sampler_blur2, tmpvar_5).xyz * scale2)\\n   + bias2).x)));\\n  vec3 tmpvar_7;\\n  tmpvar_7.x = tmpvar_6.x;\\n  tmpvar_7.y = pow (tmpvar_6.x, 2.1);\\n  tmpvar_7.z = pow (tmpvar_6.x, 4.0);\\n  xlat_mutablew = ((uv.y - (\\n    ((dot (texture (sampler_noise_hq, vec2((xlat_mutableuv_l.x / 6.0))), vec4(0.32, 0.49, 0.29, 0.0)) + uv.x) - 0.5)\\n   / 4.0)) - vshift);\\n  xlat_mutablez = (0.2 / xlat_mutablew);\\n  float tmpvar_8;\\n  tmpvar_8 = clamp ((-0.2 - (\\n    (8.0 * q5)\\n   * xlat_mutablew)), 0.0, 1.0);\\n  xlat_mutablers0.x = (((uv.x - 0.5) * (1.0 + \\n    abs(xlat_mutablez)\\n  )) * 2.0);\\n  xlat_mutablers0.y = xlat_mutablez;\\n  xlat_mutablers0 = (xlat_mutablers0 * ((4.0 * \\n    float((xlat_mutablez <= 0.0))\\n  ) + 1.0));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = 0.0;\\n  tmpvar_9.y = (1.5 + xlat_mutablew);\\n  vec2 x_10;\\n  x_10 = (xlat_mutablers0 - tmpvar_9);\\n  float tmpvar_11;\\n  tmpvar_11 = ((q26 / sqrt(\\n    dot (x_10, x_10)\\n  )) / 4.0);\\n  xlat_mutablers0 = (xlat_mutablers0 * (1.0 + (tmpvar_11 * tmpvar_11)));\\n  xlat_mutablers.x = (xlat_mutablers0 * 2.0).x;\\n  xlat_mutablers.y = (xlat_mutablers0.y + (trel * 0.5));\\n  float tmpvar_12;\\n  tmpvar_12 = (texture (sampler_main, uv).y * tmpvar_8);\\n  vec3 tmpvar_13;\\n  tmpvar_13.xy = (xlat_mutablers * 2.0);\\n  tmpvar_13.z = (0.2 * trel);\\n  float tmpvar_14;\\n  tmpvar_14 = dot (((\\n    ((2.0 * clamp ((texture (sampler_noisevol_hq, \\n      (tmpvar_13 * float((xlat_mutablez >= 0.0)))\\n    ) - 0.2), 0.0, 1.0)).xyz * clamp ((texture (sampler_noise_hq, (xlat_mutablers / 16.0)) - 0.5), 0.0, 1.0).x)\\n   / \\n    sqrt(abs(xlat_mutablez))\\n  ) + tmpvar_11), vec3(0.32, 0.49, 0.29));\\n  vec3 tmpvar_15;\\n  tmpvar_15.x = tmpvar_14;\\n  tmpvar_15.y = pow (tmpvar_14, 2.1);\\n  tmpvar_15.z = pow (tmpvar_14, 6.0);\\n  xlat_mutableret1 = (((\\n    ((uv.y * (1.0 + q23)) + (0.1 / sqrt(dot (tmpvar_3, tmpvar_3))))\\n   * vec3(0.1, 0.1, 0.2)) * tmpvar_8) + (clamp (tmpvar_15, 0.0, 1.0) * (1.0 - \\n    clamp ((-1.0 - (12.0 * xlat_mutablew)), 0.0, 1.0)\\n  )));\\n  xlat_mutableret1 = (xlat_mutableret1 * clamp ((1.0 - \\n    (tmpvar_12 * 8.0)\\n  ), 0.0, 1.0));\\n  vec4 tmpvar_16;\\n  tmpvar_16 = texture (sampler_main, fract((tmpvar_4 + 0.5)));\\n  xlat_mutablesmoke = (tmpvar_16.z * (tmpvar_16.z * q5));\\n  xlat_mutableret1 = (xlat_mutableret1 * clamp ((1.0 - \\n    ((xlat_mutablesmoke * q32) * tmpvar_8)\\n  ), 0.0, 1.0));\\n  xlat_mutablesmoke2 = (texture (sampler_main, ((tmpvar_4 / 2.0) + 0.5)).z * q30);\\n  xlat_mutableret1 = (xlat_mutableret1 + (clamp (tmpvar_7, 0.0, 1.0) - (\\n    ((xlat_mutablez * clamp ((xlat_mutablesmoke + \\n      (xlat_mutablew * q31)\\n    ), 0.0, 1.0)) * vec3(1.0, 0.4, 0.1))\\n   * tmpvar_8)));\\n  float tmpvar_17;\\n  tmpvar_17 = clamp (((\\n    (tmpvar_12 * xlat_mutablez)\\n   * xlat_mutablez) / 16.0), 0.0, 1.0);\\n  vec3 tmpvar_18;\\n  tmpvar_18.x = tmpvar_17;\\n  tmpvar_18.y = pow (tmpvar_17, 2.1);\\n  tmpvar_18.z = pow (tmpvar_17, 6.0);\\n  xlat_mutableret1 = (xlat_mutableret1 + clamp (tmpvar_18, 0.0, 1.0));\\n  xlat_mutableret1 = (xlat_mutableret1 * clamp ((\\n    (((dot (texture (sampler_noise_mq, vec2(\\n      ((xlat_mutableuv_l.x / 4.0) + (0.02 * trel))\\n    )), vec4(0.32, 0.49, 0.29, 0.0)) / 6.0) - uv.y) + 0.8)\\n   * 32.0), 0.0, 1.0));\\n  vec3 tmpvar_19;\\n  tmpvar_19.x = xlat_mutablesmoke2;\\n  tmpvar_19.y = pow (xlat_mutablesmoke2, 2.1);\\n  tmpvar_19.z = pow (xlat_mutablesmoke2, 6.0);\\n  xlat_mutableret1 = ((xlat_mutableret1 * clamp (\\n    (1.0 - xlat_mutablesmoke2)\\n  , 0.0, 1.0)) + clamp (tmpvar_19, 0.0, 1.0));\\n  vec4 tmpvar_20;\\n  tmpvar_20.w = 1.0;\\n  tmpvar_20.xyz = (1.0 - exp((\\n    -(xlat_mutableret1)\\n   * 2.0)));\\n  ret = tmpvar_20.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:6,wave_thick:1,modwavealphabyvolume:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.527,wave_smoothing:.09,modwavealphastart:0,modwavealphaend:1.32,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.8,wave_g:.49,ob_a:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:1.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0,b2x:.7,b1ed:0},shapes:[{baseVals:{enabled:1,sides:12,num_inst:1024,rad:.03632,tex_ang:1.00531,tex_zoom:1.53117,b:1,a:0,g2:0,border_b:0,border_a:0},init_eqs_str:\"a.fov=0;a.n=0;a.x0=0;a.y0=0;a.z0=0;a.q32=0;a.t1=0;\",frame_eqs_str:\"a.fov=a.reg03;a.n=a.instance*a.reg00;a.x0=a.gmegabuf[Math.floor(a.n)];a.y0=a.gmegabuf[Math.floor(a.n+1)];a.z0=a.gmegabuf[Math.floor(a.n+2)]+a.reg02;a.x=div(a.x0,a.z0)*a.fov+.5;a.y=div(a.y0,a.z0)*a.q32*a.fov+.5;a.r=a.gmegabuf[Math.floor(a.n+3)];a.g=a.gmegabuf[Math.floor(a.n+4)];a.b=a.gmegabuf[Math.floor(a.n+5)];a.r2=div(a.r,2);a.g2=div(a.g,2);a.b2=div(a.b2,2);a.a=div(a.instance,1024);a.a2=.5*a.a;a.rad=Math.min(div(.02,a.z0),.5)*(0<a.z0?1:0)*2.5*sqrt(a.a);a.rad*=a.gmegabuf[Math.floor(a.n+\\n6)];--a.t1;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,scaling:2.15542,smoothing:.2,r:0,a:.7},init_eqs_str:\"a.fov=0;a.n=0;a.t1=0;a.x0=0;a.y0=0;a.z0=0;a.k1=0;a.t2=0;\",frame_eqs_str:\"a.t1=1023;a.t2=0;\",point_eqs_str:\"a.fov=a.reg03;a.n=a.t1*a.reg00;a.x0=a.gmegabuf[Math.floor(a.n)];a.y0=a.gmegabuf[Math.floor(a.n+1)];a.z0=a.gmegabuf[Math.floor(a.n+2)]+a.reg02;a.x=div(a.x0,a.z0)*a.fov+.5;a.y=div(a.y0,a.z0)*a.fov+.5;a.a=Math.max(0,div(a.t1,1024));a.k1=a.reg01+a.t1;a.r=a.gmegabuf[Math.floor(a.n+3)];a.g=a.gmegabuf[Math.floor(a.n+4)];a.b=a.gmegabuf[Math.floor(a.n+5)];a.a=div(div(a.t1,1024)*(.5<=a.z0?1:0),2);--a.t1;a.gmegabuf[Math.floor(1E4+a.t2)]=Math.abs(a.value1+a.value2);a.t2+=1;\"},{baseVals:{enabled:1,scaling:.89152,smoothing:.82,r:0,a:.1},init_eqs_str:\"a.fov=0;a.n=0;a.t1=0;a.x0=0;a.y0=0;a.z0=0;\",frame_eqs_str:\"a.t1=512;\",point_eqs_str:\"a.fov=a.reg03;a.n=a.t1*a.reg00;a.x0=a.gmegabuf[Math.floor(a.n)];a.y0=a.gmegabuf[Math.floor(a.n+1)];a.z0=a.gmegabuf[Math.floor(a.n+2)]+a.reg02;a.x=div(a.x0,a.z0)*a.fov+.5;a.y=div(a.y0,a.z0)*a.fov+.5;a.r=a.gmegabuf[Math.floor(a.n+3)];a.g=a.gmegabuf[Math.floor(a.n+4)];a.b=a.gmegabuf[Math.floor(a.n+5)];a.a=div(div(a.t1,1024)*(.5<=a.z0?1:0),2);--a.t1;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:'a.xang=0;a.n=0;a.fov=0;a.index2=0;a.ran9=0;a.ran5_=0;a.right=0;a.ran4=0;a.index=0;a.q12=0;a.yang=0;a.q6=0;a.y0=0;a.ran8=0;a.q1=0;a.r1=0;a.q5=0;a.ran1_=0;a.points=0;a.dt1=0;a.dec_f=0;a.x0=0;a[\"new\"]=0;a.dec_s=0;a.k3=0;a.reg01=0;a.my=0;a.oz=0;a.is_beat=0;a.k1=0;a.ran2=0;a.q11=0;a.z0=0;a.q10=0;a.ran4_=0;a.ran9_=0;a.ran3=0;a.ran5=0;a.dec_m=0;a.ran7=0;a.k2=0;a.mz=0;a.ran8_=0;a.ddy=0;a.ran6=0;a.dec2=0;a.ran6_=0;a.oy=0;a.rsum=0;a.mx=0;a.beat=0;a.vol=0;a.ran2_=0;a.peak=0;a.ddx=0;a.q2=\\n0;a.zang=0;a.trel1=0;a.ran7_=0;a.t0=0;a.dec=0;a.m=0;a.ran1=0;a.q32=0;a.ran3_=0;a.left=0;a.pk=0;a.recsize=0;a.ox=0;a.zofs=0;for(var b=a.index=0;1E5>b;b++)a.megabuf[Math.floor(a.index)]=0,a.gmegabuf[Math.floor(a.index)]=0,a.index+=1;a.recsize=8;a.reg00=a.recsize;a.points=1024;a.reg01=0;a.zofs=1+2*div(randint(100),100);a.reg02=a.zofs;a.fov=.3;a.reg03=a.fov;',frame_eqs_str:'a.dec_f=pow(.3,div(30,a.fps));a.dec_m=pow(.85,div(30,a.fps));a.dec_s=pow(.95,div(30,a.fps));a.beat=a.bass+a.mid+a.treb-(a.bass_att+a.mid_att+a.treb_att)+(a.bass+a.mid+a.treb);a.beat/=3;a.peak=a.peak*a.dec_m+(1-a.dec_m)*pow(a.beat-1,1)*(1<a.beat?1:0)*4;a.is_beat=above(a.beat,1)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),8);.00001<Math.abs(a.is_beat)?(a.ran1=div(randint(100),50)-\\n1,a.ran2=div(randint(100),50)-1,a.ran3=div(randint(100),50)-1):0;a.ran1_=a.dec_m*a.ran1_+(1-a.dec_m)*a.ran1;a.ran2_=a.dec_m*a.ran2_+(1-a.dec_m)*a.ran2;a.ran3_=a.dec_m*a.ran3_+(1-a.dec_m)*a.ran3;a.rsum=sqrt(a.ran1_*a.ran1_+a.ran2_*a.ran2_+a.ran3_*a.ran3_);.00001<Math.abs(a.is_beat*(.00001>Math.abs(a.index-2)?1:0))?(a.ran4=div(randint(100),50)-1,a.ran5=div(randint(100),50)-1,a.ran6=div(randint(100),50)-1):0;a.ran4_=a.dec_m*a.ran4_+(1-a.dec_m)*a.ran4;a.ran5_=a.dec_m*a.ran5_+(1-a.dec_m)*a.ran5;a.ran6_=\\na.dec_m*a.ran6_+(1-a.dec_m)*a.ran6;.00001<Math.abs(a.is_beat*(.00001>Math.abs(a.index-6)?1:0))?(a.ran7=div(randint(100),50)-1,a.ran8=div(randint(100),50)-1,a.ran9=div(randint(100),50)-1):0;a.ran7_=a.dec_m*a.ran7_+(1-a.dec_m)*a.ran7;a.ran8_=a.dec_m*a.ran8_+(1-a.dec_m)*a.ran8;a.ran9_=a.dec_m*a.ran9_+(1-a.dec_m)*a.ran9;a.pk=sqrt(a.peak+.1);a[\"new\"]=Math.floor(12*(a.ran4-a.ran5)*a.pk-div(12*(a.ran3-a.ran1),a.pk));a[\"new\"]=Math.max(Math.min(a[\"new\"],20),2);a.reg01+=a[\"new\"];a.dec=a.dec_m;a.n=a.recsize*\\na.points;a.m=0;a.dt1=div(div(.00001<Math.abs(0<a.ran1?1:0)?4*a.pk:div(4,a.pk),a.fps)*a[\"new\"],6);a.vol=Math.max(a.ran1+a.ran2,.2)*a.pk*2;for(var b=0;b<a[\"new\"];b++)a.trel1+=a.dt1,a.x0=a.x0*a.dec+(1-a.dec)*(Math.sin(a.trel1+6*a.ran3)*a.vol+a.ran1),a.y0=a.y0*a.dec+(1-a.dec)*(Math.sin(a.trel1+6*a.ran2)*a.vol+a.ran2),a.z0=a.z0*a.dec+(1-a.dec)*(Math.sin(a.trel1+6*a.ran1)*a.vol+a.ran3),a.gmegabuf[Math.floor(a.n)]=a.x0,a.gmegabuf[Math.floor(a.n+1)]=a.y0,a.gmegabuf[Math.floor(a.n+2)]=a.z0,a.gmegabuf[Math.floor(a.n+\\n3)]=div(div(a.ran1_,a.rsum),3)+.5,a.gmegabuf[Math.floor(a.n+4)]=div(div(a.ran2_,a.rsum),3)+.5,a.gmegabuf[Math.floor(a.n+5)]=div(div(a.ran3_,a.rsum),3)+.5,a.gmegabuf[Math.floor(a.n+6)]=0*a.gmegabuf[Math.floor(1E4+a.m)]+1,a.n+=a.recsize,a.m+=1;for(b=a.n=0;b<a.recsize*a.points;b++)a.gmegabuf[Math.floor(a.n)]=a.gmegabuf[Math.floor(a.n+a[\"new\"]*a.recsize)],a.n+=1;a.xang=div(a.ran4_,a.fps);a.yang=div(a.ran5_,a.fps);a.zang=div(a.ran6_,a.fps);a.ddx=Math.min(Math.max(a.ddx+div(a.yang,a.fps),-1),1);a.ddy=Math.min(Math.max(a.ddy+\\ndiv(a.xang,a.fps),-1),1);a.q1=2*a.ddx;a.q2=2*a.ddy;for(b=a.n=0;b<a.points;b++)a.ox=a.gmegabuf[Math.floor(a.n)],a.oy=a.gmegabuf[Math.floor(a.n+1)],a.oz=a.gmegabuf[Math.floor(a.n+2)],a.mx=a.ox*Math.cos(a.zang)-a.oy*Math.sin(a.zang),a.my=a.ox*Math.sin(a.zang)+a.oy*Math.cos(a.zang),a.ox=a.mx,a.oy=a.my,a.mx=a.ox*Math.cos(a.yang)+a.oz*Math.sin(a.yang),a.mz=-a.ox*Math.sin(a.yang)+a.oz*Math.cos(a.yang),a.ox=a.mx,a.oz=a.mz,a.my=a.oy*Math.cos(a.xang)-a.oz*Math.sin(a.xang),a.mz=a.oy*Math.sin(a.xang)+a.oz*Math.cos(a.xang),\\na.oy=a.my,a.oz=a.mz,a.gmegabuf[Math.floor(a.n)]=a.ox,a.gmegabuf[Math.floor(a.n+1)]=a.oy,a.gmegabuf[Math.floor(a.n+2)]=a.oz,a.n+=a.recsize;a.k1=div(div(a.ran7_,a.fps),2);a.k2=div(div(a.ran8_,a.fps),2);a.k3=div(Math.abs(a.ran9_),a.fps);a.dec=.4+.6*a.ran5_;a.dec2=1-a.dec;a.r1=.5+.3*a.ran4_;for(b=a.n=0;b<a.points-1;b++)a.m=a.n*a.recsize,a.left=mod(a.n-1+a.points,a.points)*a.recsize,a.right=mod(a.n+1+a.points,a.points)*a.recsize,a.gmegabuf[Math.floor(a.m)]=a.dec*a.gmegabuf[Math.floor(a.m)]+a.dec2*(a.gmegabuf[Math.floor(a.left)]*\\na.r1+a.gmegabuf[Math.floor(a.right)]*(1-a.r1)+a.k1),a.gmegabuf[Math.floor(a.m+1)]=a.dec*a.gmegabuf[Math.floor(a.m+1)]+a.dec2*(a.gmegabuf[Math.floor(a.left+1)]*a.r1+a.gmegabuf[Math.floor(a.right+1)]*(1-a.r1)+a.k2),a.n+=1;a.m=mod(a.frame,a.points);a.m=Math.max(0,Math.floor(1024+200*(a.t0-a.time)));a.n=a.m*a.recsize;a.q5=div(a.gmegabuf[Math.floor(a.n)],a.gmegabuf[Math.floor(a.n+2)]+a.zofs)*a.fov;a.q6=div(-a.gmegabuf[Math.floor(a.n+1)],a.gmegabuf[Math.floor(a.n+2)]+a.zofs)*a.fov;a.q10=sqrt(a.gmegabuf[Math.floor(a.n+\\n3)]);a.q11=sqrt(a.gmegabuf[Math.floor(a.n+4)]);a.q12=sqrt(a.gmegabuf[Math.floor(a.n+5)]);a.monitor=a.m;a.q32=a.aspecty;',pixel_eqs_str:\"a.rot=0;a.zoom=1;a.warp=0;a.dy=0;a.dx=-0;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = vec3(0.0, 0.0, 0.0);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\"float xlat_mutablesmask;\\nvec2 xlat_mutableuv1;\\nvec2 xlat_mutableuv2;\\nvec2 xlat_mutableuv3;\\nvec2 xlat_mutableuv4;\\n shader_body { \\n  float flash_1;\\n  float dist_2;\\n  float stars_3;\\n  vec3 ret_4;\\n  xlat_mutableuv1 = ((uv - 0.5) * aspect.xy);\\n  float tmpvar_5;\\n  tmpvar_5 = (0.1 * time);\\n  float tmpvar_6;\\n  tmpvar_6 = (0.2 * rad);\\n  dist_2 = ((1.0 - fract(\\n    (0.3333333 + tmpvar_5)\\n  )) * (1.0 - tmpvar_6));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = q1;\\n  tmpvar_7.y = q2;\\n  xlat_mutableuv3 = (xlat_mutableuv1 + tmpvar_7);\\n  xlat_mutableuv4 = ((32.0 * dist_2) * xlat_mutableuv3);\\n  xlat_mutablesmask = (texture (sampler_pw_noise_lq, (xlat_mutableuv4 / 256.0)).y - 0.9);\\n  vec2 tmpvar_8;\\n  tmpvar_8 = abs((fract(xlat_mutableuv4) - 0.5));\\n  stars_3 = max (0.0, clamp ((\\n    (1.0 - dist_2)\\n   * \\n    ((0.1 / sqrt(dot (tmpvar_8, tmpvar_8))) * xlat_mutablesmask)\\n  ), 0.0, 1.0));\\n  dist_2 = ((1.0 - fract(\\n    (0.6666667 + tmpvar_5)\\n  )) * (1.0 - tmpvar_6));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = q1;\\n  tmpvar_9.y = q2;\\n  xlat_mutableuv3 = (xlat_mutableuv1 + tmpvar_9);\\n  xlat_mutableuv4 = ((32.0 * dist_2) * xlat_mutableuv3);\\n  xlat_mutablesmask = (texture (sampler_pw_noise_lq, (xlat_mutableuv4 / 256.0)).y - 0.9);\\n  vec2 tmpvar_10;\\n  tmpvar_10 = abs((fract(xlat_mutableuv4) - 0.5));\\n  stars_3 = (stars_3 + max (stars_3, clamp (\\n    ((1.0 - dist_2) * ((0.1 / sqrt(\\n      dot (tmpvar_10, tmpvar_10)\\n    )) * xlat_mutablesmask))\\n  , 0.0, 1.0)));\\n  dist_2 = ((1.0 - fract(\\n    (1.0 + tmpvar_5)\\n  )) * (1.0 - tmpvar_6));\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = q1;\\n  tmpvar_11.y = q2;\\n  xlat_mutableuv3 = (xlat_mutableuv1 + tmpvar_11);\\n  xlat_mutableuv4 = ((32.0 * dist_2) * xlat_mutableuv3);\\n  xlat_mutablesmask = (texture (sampler_pw_noise_lq, (xlat_mutableuv4 / 256.0)).y - 0.9);\\n  vec2 tmpvar_12;\\n  tmpvar_12 = abs((fract(xlat_mutableuv4) - 0.5));\\n  stars_3 = (stars_3 + max (stars_3, clamp (\\n    ((1.0 - dist_2) * ((0.1 / sqrt(\\n      dot (tmpvar_12, tmpvar_12)\\n    )) * xlat_mutablesmask))\\n  , 0.0, 1.0)));\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = q5;\\n  tmpvar_13.y = q6;\\n  xlat_mutableuv2 = (xlat_mutableuv1 - tmpvar_13);\\n  float tmpvar_14;\\n  tmpvar_14 = ((0.01 / sqrt(\\n    dot (xlat_mutableuv2, xlat_mutableuv2)\\n  )) * min (3.0, (\\n    ((mid - 0.5) * float((mid > 0.5)))\\n   * 2.0)));\\n  flash_1 = tmpvar_14;\\n  float angle_15;\\n  float tmpvar_16;\\n  tmpvar_16 = abs(xlat_mutableuv2.x);\\n  if ((xlat_mutableuv2.y >= 0.0)) {\\n    angle_15 = (1.0 - ((xlat_mutableuv2.y - tmpvar_16) / (xlat_mutableuv2.y + tmpvar_16)));\\n  } else {\\n    angle_15 = (3.0 - ((xlat_mutableuv2.y + tmpvar_16) / (tmpvar_16 - xlat_mutableuv2.y)));\\n  };\\n  angle_15 = (angle_15 * 0.25);\\n  float tmpvar_17;\\n  if ((xlat_mutableuv2.x < 0.0)) {\\n    tmpvar_17 = -(angle_15);\\n  } else {\\n    tmpvar_17 = angle_15;\\n  };\\n  flash_1 = (tmpvar_14 * (tmpvar_14 / (\\n    abs((fract((\\n      (3.0 * tmpvar_17)\\n     + \\n      (time * 2.0)\\n    )) - 0.5))\\n   + 0.18)));\\n  vec3 tmpvar_18;\\n  tmpvar_18 = max ((texture (sampler_main, uv).xyz * 2.0), ((\\n    (texture (sampler_blur2, uv).xyz * scale2)\\n   + bias2) * 2.0));\\n  vec2 tmpvar_19;\\n  tmpvar_19 = sin(xlat_mutableuv3);\\n  ret_4 = (clamp ((0.025 / \\n    sqrt(dot (tmpvar_19, tmpvar_19))\\n  ), 0.0, 1.0) * vec3(0.4, 0.1, 1.0));\\n  ret_4 = (ret_4 + clamp ((stars_3 * stars_3), 0.0, 1.0));\\n  ret_4 = (ret_4 * clamp ((1.0 - \\n    (2.0 * dot (tmpvar_18, vec3(0.32, 0.49, 0.29)))\\n  ), 0.0, 1.0));\\n  ret_4 = (ret_4 + tmpvar_18);\\n  vec3 tmpvar_20;\\n  tmpvar_20.x = q10;\\n  tmpvar_20.y = q11;\\n  tmpvar_20.z = q12;\\n  ret_4 = (ret_4 + ((2.0 * \\n    clamp (flash_1, 0.0, 1.0)\\n  ) * tmpvar_20));\\n  vec4 tmpvar_21;\\n  tmpvar_21.w = 1.0;\\n  tmpvar_21.xyz = ret_4;\\n  ret = tmpvar_21.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,additivewave:1,wave_thick:1,modwavealphabyvolume:1,darken:1,wave_a:.001,wave_scale:.133,wave_smoothing:0,wave_mystery:-1,modwavealphastart:1,modwavealphaend:1.3,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.015,ob_b:1,ib_size:.26,mv_a:0,b2x:.3,b1ed:0},shapes:[{baseVals:{enabled:1,sides:40,thickoutline:1,rad:.06623,tex_zoom:1.79845,r:0,a:.1,g2:0,border_b:0,border_a:0},init_eqs_str:\"a.vol=0;a.bob=0;a.border_1=0;a.ro=0;a.sp=0;a.red=0;a.spi=0;a.tm=0;a.bob=1.5;a.ro=0;a.red=randint(20);\",frame_eqs_str:\"a.vol=1+.2*div(a.bass_att+a.treb_att+a.mid_att,3);a.bob=a.bob*above(a.bob,.01)-.01+(1-above(a.bob,.01));a.bob=.4+.4*Math.sin(.8*a.time);a.bob*=a.vol;a.border_1=.4;a.sides=30;a.ro+=.02;a.ang=a.ro;a.sp=.025*a.red;a.spi=.5-a.sp;a.tm=.1*a.time;a.border_r=.5+a.sp*Math.sin(.6*a.tm)+a.spi*Math.cos(1.46*a.tm);a.border_g=.5+a.sp*Math.sin(1.294*a.tm)+a.spi*Math.cos(.87*a.tm);a.border_b=.5+a.sp*Math.sin(1.418*a.tm)+a.spi*Math.cos(.76*a.tm);\"},{baseVals:{enabled:1,sides:40,additive:1,num_inst:4,g:1,b:1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.x=.5+.225*Math.sin(.7*div(a.time,a.instance));a.y=.5+.3*Math.cos(.7*div(a.time,a.instance));a.x-=.4*a.x*Math.sin(a.time);a.y-=.4*a.y*Math.cos(a.time);a.rad*=a.mid_att;a.r=.5+.5*Math.sin(.5*a.frame);a.b=.5+.5*Math.sin(.5*a.frame+2.094);a.g=.5+.5*Math.sin(.5*a.frame+4.188);\"},{baseVals:{enabled:1,sides:40,additive:1,g:1,b:1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.x=.5+.5*(.3*Math.sin(1.1*a.time)+.7*Math.sin(.5*a.time));a.x=.5+.225*Math.sin(a.time+2.09);a.y=.5+.3*Math.cos(a.time+2.09);a.rad*=a.bass_att;a.r=.5+.5*Math.sin(.5*a.frame);a.b=.5+.5*Math.sin(.5*a.frame+2.094);a.g=.5+.5*Math.sin(.5*a.frame+4.188);\"},{baseVals:{enabled:1,sides:40,additive:1,num_inst:5,rad:.07419,g:1,b:1,g2:0,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.x=.5+.225*Math.sin(div(a.time,a.instance));a.y=.5+.3*Math.cos(div(a.time,a.instance));a.x+=.4*a.x*Math.sin(a.time);a.y+=.4*a.y*Math.cos(a.time);a.rad*=a.treb_att;a.r=.5+.5*Math.sin(.5*a.frame);a.b=.5+.5*Math.sin(.5*a.frame+2.094);a.g=.5+.5*Math.sin(.5*a.frame+4.188);\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.index=0;a.q22=0;a.q21=0;a.q1=0;a.dec_med=0;a.ps=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.dec_slow=0;a.q4=0;a.q26=0;a.p2=0;a.avg=0;a.beat=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.q28=0;a.q20=0;\",frame_eqs_str:\"a.dec_med=pow(.7,div(30,a.fps));a.dec_slow=pow(.99,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.2+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.q20=a.avg;a.q21=a.beat;a.q22=a.peak;a.ps=.9*a.ps+.1*a.q22;a.q23=a.ps;a.q24=a.is_beat;\\na.q26=a.bass_att+a.mid_att+a.treb_att;a.q27=a.index+1;a.q28=a.index2;a.k1=a.is_beat*equal(mod(a.index,2),0);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,4);a.q1=Math.cos(a.rott);a.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;\",pixel_eqs_str:\"a.zoom=1.05;\",warp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (uv - vec2(0.5, 0.5));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 0.0;\\n  vec4 tmpvar_4;\\n  tmpvar_4 = texture (sampler_blur1, uv);\\n  tmpvar_3.xyz = ((tmpvar_4.xyz * scale1) + bias1);\\n  float tmpvar_5;\\n  tmpvar_5 = (dot (tmpvar_3, roam_sin) * 16.0);\\n  mat2 tmpvar_6;\\n  tmpvar_6[uint(0)].x = cos(tmpvar_5);\\n  tmpvar_6[uint(0)].y = -(sin(tmpvar_5));\\n  tmpvar_6[1u].x = sin(tmpvar_5);\\n  tmpvar_6[1u].y = cos(tmpvar_5);\\n  uv_1 = ((tmpvar_2 + (\\n    (0.2 * dot (((tmpvar_4.xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29)))\\n   * \\n    (tmpvar_2 * tmpvar_6)\\n  )) - 0.5);\\n  vec2 tmpvar_7;\\n  tmpvar_7 = ((uv_1 * texsize.xy) * 0.02);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = (cos((tmpvar_7.y * q1)) * sin(-(tmpvar_7.y)));\\n  tmpvar_8.y = (sin(tmpvar_7.x) * cos((tmpvar_7.y * q2)));\\n  uv_1 = (uv_1 - ((tmpvar_8 * texsize.zw) * 12.0));\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = ((texture (sampler_main, uv_1).xyz * 0.98) - 0.02);\\n  ret = tmpvar_9.xyz;\\n }\",comp:\"vec3 xlat_mutableret1;\\nvec2 xlat_mutablers;\\nvec2 xlat_mutableuv1;\\nfloat xlat_mutablez;\\n shader_body { \\n  xlat_mutableuv1 = (uv - 0.5);\\n  xlat_mutablez = (0.2 / abs(xlat_mutableuv1.y));\\n  xlat_mutablers.x = (xlat_mutableuv1.x * xlat_mutablez);\\n  xlat_mutablers.y = ((xlat_mutablez / 2.0) + (time * 4.0));\\n  vec4 tmpvar_1;\\n  tmpvar_1 = texture (sampler_noise_hq, xlat_mutablers);\\n  xlat_mutableret1 = ((tmpvar_1.xyz * vec3(\\n    greaterThanEqual (tmpvar_1.xyz, vec3(0.0, 0.0, 0.0))\\n  )) - 0.6);\\n  float tmpvar_2;\\n  tmpvar_2 = clamp ((128.0 * xlat_mutableuv1.y), 0.0, 1.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3 = fract(((\\n    (xlat_mutableuv1 * (1.0 - abs(xlat_mutableuv1.x)))\\n   - 0.5) - (\\n    (xlat_mutableret1 * 0.05)\\n   * tmpvar_2).xy));\\n  float x_4;\\n  x_4 = (tmpvar_3.y - 0.52);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (texture (sampler_main, tmpvar_3) + ((0.02 / \\n    (0.02 + sqrt((x_4 * x_4)))\\n  ) * slow_roam_sin)).xyz;\\n  xlat_mutableret1 = tmpvar_5;\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (32.0 * ((\\n    (uv * mat2(0.6, -0.8, 0.8, 0.6))\\n   + \\n    (tmpvar_5 * 0.1)\\n  .xy) + (time / 64.0)));\\n  vec2 tmpvar_7;\\n  tmpvar_7 = abs((fract(tmpvar_6) - 0.5));\\n  vec3 tmpvar_8;\\n  tmpvar_8 = clamp (((0.25 / \\n    sqrt(dot (tmpvar_7, tmpvar_7))\\n  ) * vec3((texture (sampler_pw_noise_lq, \\n    (tmpvar_6 / 256.0)\\n  ).y - 0.9))), 0.0, 1.0);\\n  vec4 tmpvar_9;\\n  tmpvar_9.w = 1.0;\\n  tmpvar_9.xyz = (tmpvar_5 + ((\\n    (tmpvar_8.x * tmpvar_8.x)\\n   + \\n    ((rand_preset * (0.5 - uv.y)).xyz * vec3(0.0, 0.0, 1.0))\\n  ) * (1.0 - tmpvar_2)));\\n  ret = tmpvar_9.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:2,gammaadj:1.98,decay:.5,echo_zoom:1,echo_alpha:.5,echo_orient:3,wave_mode:3,wave_thick:1,wrap:0,darken:1,wave_a:100,wave_scale:.282,wave_smoothing:.9,wave_mystery:1,warpanimspeed:1.459,warpscale:2.007,zoom:.9999,warp:.01,sx:.9999,wave_r:.5,wave_g:.5,wave_b:.5,ob_size:.05,ob_g:.1,ob_b:1,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_a:0,b1ed:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,spectrum:1,thick:1,scaling:.2248},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.r=a.bass;a.g=a.treb;a.b=.5;\",point_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.8);\"},{baseVals:{enabled:1,spectrum:1,thick:1,scaling:.2743},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;\",frame_eqs_str:\"a.r=a.bass;a.g=a.treb;a.b=.5;\",point_eqs_str:\"a.ma+=3.1415*above(a.mid,1)*.01*a.mid;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0004*Math.cos(a.ma);a.my+=.0004*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.a=above(a.bass+a.mid+a.treb,.3);\"},{baseVals:{enabled:1,thick:1,scaling:2.0231,smoothing:0},init_eqs_str:\"a.d=0;a.tt2=0;a.res=0;a.tt1=0;a.diff=0;a.tt3=0;a.beat=0;a.vol=0;a.m=0;a.monitor=0;a.t2=0;a.t3=0;a.t4=0;a.cl=0;\",frame_eqs_str:\"a.vol=8*a.bass+5*a.mid+3*a.treb;a.m=.97*a.m+.08*a.vol;a.monitor=a.vol;a.beat=above(a.vol,a.res)*above(a.vol,a.m)*above(a.vol,16);a.diff=(1-a.beat)*a.diff+a.beat*(a.vol-a.res);a.res=a.beat*(a.vol+.04*a.m)+(1-a.beat)*(a.res-div(60*(.1+.02*a.diff),a.fps));a.res=Math.max(0,a.res);\",point_eqs_str:\"a.tt3=.6*a.tt3+1*a.value1;a.tt2=.7*a.tt2+.2*a.tt3;a.tt1=.8*a.tt1+.1*a.tt2;a.d=.9*a.d+.2*a.tt1;a.y=.5+a.d*a.sample*(1-a.sample)*2;a.x=-.05+1.1*a.sample;\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.look=0;a.n=0;a.reg26=0;a.uvx0=0;a.reg34=0;a.reg28=0;a.reg23=0;a.q25=0;a.angchg=0;a.reg20=0;a.reg15=0;a.reg10=0;a.q12=0;a.v3=0;a.q22=0;a.q21=0;a.diry=0;a.q13=0;a.q6=0;a.posx=0;a.fps_=0;a.reg25=0;a.uvx=0;a.q1=0;a.travel=0;a.posz=0;a.q5=0;a.dirz=0;a.dec_s=0;a.reg16=0;a.slow=0;a.reg36=0;a.reg22=0;a.uvy=0;a.rotz=0;a.ly=0;a.dist_=0;a.q23=0;a.q24=0;a.reg24=0;a.cran0=0;a.ran2=0;a.q11=0;a.q10=0;a.reg14=0;a.posy=0;a.reg31=0;a.dirx=0;a.q4=0;a.start=0;a.reg12=0;a.reg13=0;a.c2=0;a.reg37=\\n0;a.s3=0;a.yslope=0;a.lampy=0;a.q16=0;a.xslope=0;a.q26=0;a.reg38=0;a.reg35=0;a.reg11=0;a.tx=0;a.avg=0;a.uvz=0;a.c3=0;a.uvy0=0;a.reg27=0;a.q19=0;a.beat=0;a.reg32=0;a.lx=0;a.reg21=0;a.uvz0=0;a.len=0;a.reg18=0;a.reg30=0;a.q2=0;a.q27=0;a.slen=0;a.q14=0;a.dist=0;a.reg17=0;a.v1=0;a.speed=0;a.s1=0;a.t0=0;a.s2=0;a.ran1=0;a.reg33=0;a.q7=0;a.ds=0;a.q28=0;a.lampx=0;a.ty=0;a.c1=0;a.v2=0;a.q20=0;a.q8=0;a.avg=.01;a.q7=.25;a.q8=randint(2)-1;a.q16=1+randint(2);a.q18=randint(.8)+.1;a.q30=1;a.q31=128;a.start=1;a.travel=\\n0;a.rotz=0;a.look=0;a.slow=0;a.t0=a.time+3;a.lampx=.5;a.lampy=.5;a.cran0=randint(1);for(var b=a.n=0;1E4>b;b++)a.gmegabuf[Math.floor(a.n)]=0,a.n+=1;for(b=a.n=0;1E4>b;b++)a.megabuf[Math.floor(a.n)]=0,a.n+=1;a.trelx=0;a.trely=0;a.trelz=0;a.reg20=1;a.reg21=0;a.reg22=0;a.reg23=0;a.reg24=1;a.reg25=0;a.reg26=0;a.reg27=0;a.reg28=1;b=0;do{b+=1;var c;a.ran1=div(randint(800),100);a.ran2=div(randint(800),100);a.ran3=div(randint(800),100);a.posx=randint(5)-2;a.posy=randint(5)-2;a.posz=randint(5)-2;a.c1=Math.cos(a.ran1);\\na.c2=Math.cos(a.ran2);a.c3=Math.cos(a.ran3);a.s1=Math.sin(a.ran1);a.s2=Math.sin(a.ran2);a.s3=Math.sin(a.ran3);a.reg20=a.c2*a.c1;a.reg21=a.c2*a.s1;a.reg22=-a.s2;a.reg23=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg24=a.s3*a.s2*a.s1+a.c3*a.c1;a.reg25=a.s3*a.c2;a.reg26=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg27=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg28=a.c3*a.c2;a.dist=.001;var d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;a.uvy+=a.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,\\n8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<Math.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=\\na.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.05;c=(.6>a.dist?1:0)*(30<a.len?1:0)}while(.00001<Math.abs(c)&&1048576>\\nd);d=.06>a.dist?1:0}while(.00001<Math.abs(d)&&1048576>b);\",frame_eqs_str:\"a.wave_a=0;a.fps_=0*a.fps_+1*(.00001<Math.abs(25>=a.fps?1:0)?a.fps:25+.5*(a.fps-25));a.dec_s=1-div(.06*30,a.fps_);a.beat=a.time>a.t0+3?1:0;a.t0=.00001<Math.abs(a.beat)?a.time:a.t0;a.speed=div(Math.min(.2,a.dist_-.02)*(1+2*a.avg)*(1-0*a.slow)*.7,a.q7);a.ds=a.ds*a.dec_s+div((1-a.dec_s)*a.speed*.25,a.fps_);a.rotz=.00001<Math.abs(.00001>Math.abs(a.rotz-0)?1:0)?a.beat*(randint(100)<20*a.travel?1:0)*(div(randint(10),10)-.3):bnot(a.beat*(30>randint(100)?1:0))*a.rotz;a.slow=.00001<\\nMath.abs(bnot(a.slow))?a.beat*(6>randint(1E3*a.avg)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.look=.00001<Math.abs(bnot(a.look))?a.beat*(12>randint(1E3*a.speed)?1:0):bnot(a.beat*(50>randint(100)?1:0));a.lx=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.lx;a.ly=.00001<Math.abs(a.beat)?div(randint(150),200)+.15:a.ly;a.lampx=a.lampx*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.lx:.5);a.lampy=a.lampy*a.dec_s+(1-a.dec_s)*(.00001<Math.abs(a.look)?a.ly:.5);a.q1=a.lampx;a.q2=a.lampy;a.dirx=a.reg26;\\na.diry=a.reg27;a.dirz=a.reg28;a.posx+=a.ds*a.dirx;a.posy+=a.ds*a.diry;a.posz+=a.ds*a.dirz;a.q4=a.posx;a.q5=a.posy;a.q6=a.posz;a.angchg=(.2-a.dist_)*(.2>a.dist_?1:0)*2;a.travel=.00001<Math.abs(0<a.angchg?1:0)?0:a.travel+a.ds;a.v1=a.v1*a.dec_s+(1-a.dec_s)*a.rotz*a.ds;a.v2=a.v2*a.dec_s+div((1-a.dec_s)*a.angchg*a.xslope,a.fps_);a.v3=a.v3*a.dec_s+(1-a.dec_s)*(div(a.angchg*a.yslope,a.fps_)+2*a.v1*Math.sin(.1*a.time));a.reg30=a.reg20;a.reg31=a.reg21;a.reg32=a.reg22;a.reg33=a.reg23;a.reg34=a.reg24;a.reg35=\\na.reg25;a.reg36=a.reg26;a.reg37=a.reg27;a.reg38=a.reg28;a.n=0;for(var b=a.avg=0;5>b;b++){a.n+=1;a.ran1=div(randint(100),100);a.ran2=div(randint(100),200)-.25;a.tx=Math.cos(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.ty=Math.sin(1.57*a.n+a.ran2)*(4>=a.n?1:0)*a.ran1;a.c1=Math.cos(a.v1);a.c2=Math.cos(a.v2+a.ty);a.c3=Math.cos(a.v3+a.tx);a.s1=Math.sin(a.v1);a.s2=Math.sin(a.v2+a.ty);a.s3=Math.sin(a.v3+a.tx);a.reg10=a.c2*a.c1;a.reg11=a.c2*a.s1;a.reg12=-a.s2;a.reg13=a.s3*a.s2*a.c1-a.c3*a.s1;a.reg14=a.s3*a.s2*\\na.s1+a.c3*a.c1;a.reg15=a.s3*a.c2;a.reg16=a.c3*a.s2*a.c1+a.s3*a.s1;a.reg17=a.c3*a.s2*a.s1-a.s3*a.c1;a.reg18=a.c3*a.c2;a.reg20=a.reg30;a.reg21=a.reg31;a.reg22=a.reg32;a.reg23=a.reg33;a.reg24=a.reg34;a.reg25=a.reg35;a.reg26=a.reg36;a.reg27=a.reg37;a.reg28=a.reg38;a.q20=a.reg10*a.reg20+a.reg11*a.reg23+a.reg12*a.reg26;a.q21=a.reg10*a.reg21+a.reg11*a.reg24+a.reg12*a.reg27;a.q22=a.reg10*a.reg22+a.reg11*a.reg25+a.reg12*a.reg28;a.q23=a.reg13*a.reg20+a.reg14*a.reg23+a.reg15*a.reg26;a.q24=a.reg13*a.reg21+a.reg14*\\na.reg24+a.reg15*a.reg27;a.q25=a.reg13*a.reg22+a.reg14*a.reg25+a.reg15*a.reg28;a.q26=a.reg16*a.reg20+a.reg17*a.reg23+a.reg18*a.reg26;a.q27=a.reg16*a.reg21+a.reg17*a.reg24+a.reg18*a.reg27;a.q28=a.reg16*a.reg22+a.reg17*a.reg25+a.reg18*a.reg28;a.reg20=a.q20;a.reg21=a.q21;a.reg22=a.q22;a.reg23=a.q23;a.reg24=a.q24;a.reg25=a.q25;a.reg26=a.q26;a.reg27=a.q27;a.reg28=a.q28;a.dist=.002;var c,d=0;do{d+=1;a.uvx=div(a.reg26*a.dist,a.q7);a.uvy=div(a.reg27*a.dist,a.q7);a.uvz=div(a.reg28*a.dist,a.q7);a.uvx+=a.posx;\\na.uvy+=a.posy;a.uvz+=a.posz;a.uvx=8*(div(a.uvx,8)+30.5-Math.floor(div(a.uvx,8)+30.5)-.5);a.uvy=8*(div(a.uvy,8)+30.5-Math.floor(div(a.uvy,8)+30.5)-.5);a.uvz=8*(div(a.uvz,8)+30.5-Math.floor(div(a.uvz,8)+30.5)-.5);a.uvx0=a.uvx+a.q8;a.uvy0=a.uvy+a.q8;a.uvz0=a.uvz+a.q8;for(c=0;8>c;c++)a.uvx=.00001<Math.abs(1<a.uvx?1:0)?2-a.uvx:.00001<Math.abs(-1>a.uvx?1:0)?-2-a.uvx:a.uvx,a.uvy=.00001<Math.abs(1<a.uvy?1:0)?2-a.uvy:.00001<Math.abs(-1>a.uvy?1:0)?-2-a.uvy:a.uvy,a.uvz=.00001<Math.abs(1<a.uvz?1:0)?2-a.uvz:.00001<\\nMath.abs(-1>a.uvz?1:0)?-2-a.uvz:a.uvz,a.slen=a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz,a.uvx=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvx:.00001<Math.abs(1>a.slen?1:0)?div(a.uvx,a.slen):a.uvx)+a.uvx0,a.uvy=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvy:.00001<Math.abs(1>a.slen?1:0)?div(a.uvy,a.slen):a.uvy)+a.uvy0,a.uvz=2.6*(.00001<Math.abs(.25>a.slen?1:0)?4*a.uvz:.00001<Math.abs(1>a.slen?1:0)?div(a.uvz,a.slen):a.uvz)+a.uvz0;a.len=sqrt(a.uvx*a.uvx+a.uvy*a.uvy+a.uvz*a.uvz);a.dist*=1.1;c=(.6>a.dist?1:0)*(30<\\na.len?1:0)}while(.00001<Math.abs(c)&&1048576>d);a.megabuf[Math.floor(a.n)]=a.megabuf[Math.floor(a.n)]*a.dec_s+(1-a.dec_s)*a.dist;a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5))}a.n=0;for(b=a.avg=0;5>b;b++)a.n+=1,a.avg+=Math.abs(div(a.megabuf[Math.floor(a.n)],5));a.xslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[1]-a.megabuf[3]),-3),3);a.yslope=Math.min(Math.max(div(2,a.avg)*(a.megabuf[4]-a.megabuf[2]),-3),3);a.monitor=a.avg;a.dist_=a.dist_*a.dec_s+(1-a.dec_s)*a.dist;a.q10=a.ds*a.q7;a.q14=Math.abs(a.ds)+\\n2*(Math.abs(a.v1)+Math.abs(a.v2)+Math.abs(a.v3))+div(1,255)+.05*a.start;a.q19=.6+.4*Math.sin(.02*a.time+6*a.cran0);a.start*=.9;a.q11=a.v1;a.q12=a.v2;a.q13=a.v3;a.monitor=a.q16;\",pixel_eqs_str:\"a.warp=0;a.zoom=1;a.dx=div(-a.q12,a.q16)*(1+0*pow(a.x-.5,2));a.dy=div(a.q13,a.q16)*(1+0*pow(a.y-.5,2));a.rot=a.q11;\",warp:\" shader_body { \\n  float dy_1;\\n  float dx_2;\\n  vec3 ret_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = ((uv * texsize.xy) * texsize_noise_lq.zw);\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (texsize.zw * 4.0);\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  tmpvar_6.y = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  )).y * 0.5);\\n  ret_3.y = texture (sampler_fw_main, clamp ((uv + (\\n    (tmpvar_6 * texsize.zw)\\n   * 4.0)), 0.0, 1.0)).y;\\n  ret_3.y = (ret_3.y + ((\\n    (ret_3 - ((texture (sampler_blur1, uv).xyz * scale1) + bias1))\\n  .y * 0.025) + -0.01));\\n  ret_3.y = (ret_3.y + ((texture (sampler_noise_lq, tmpvar_4).y - 0.5) * 0.02));\\n  dx_2 = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(1.0, 0.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  )).z * 0.5);\\n  dy_1 = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv - (vec2(0.0, 1.0) * tmpvar_5))).xyz * scale1) + bias1)\\n  )).z * 0.5);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = dx_2;\\n  tmpvar_7.y = dy_1;\\n  ret_3.z = ((texture (sampler_main, (uv - \\n    ((tmpvar_7 * texsize.zw) * 4.0)\\n  )).z - (ret_3.y * 0.01)) + 0.004);\\n  ret_3.z = (ret_3.z + ((texture (sampler_noise_lq, tmpvar_4).y - 0.5) * 0.01));\\n  dx_2 = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (tmpvar_5 * vec2(1.0, 0.0)))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv + (tmpvar_5 * vec2(-1.0, 0.0)))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  dy_1 = (((2.0 * \\n    ((texture (sampler_blur1, (uv + (tmpvar_5 * vec2(0.0, 1.0)))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv + (tmpvar_5 * vec2(0.0, -1.0)))).xyz * scale1) + bias1)\\n  )).x * 0.5);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = dx_2;\\n  tmpvar_8.y = dy_1;\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (tmpvar_8 * texsize.zw);\\n  vec2 domain_10;\\n  domain_10 = (uv - (tmpvar_9 * 2.5));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 0.0;\\n  tmpvar_11.xyz = max (vec4(0.0, 0.0, 0.0, 0.0), texture (sampler_fc_main, (domain_10 + (texsize.zw * vec2(-1.0, 0.0))))).xyz;\\n  vec4 tmpvar_12;\\n  tmpvar_12.w = 0.0;\\n  tmpvar_12.xyz = max (tmpvar_11, texture (sampler_fc_main, (domain_10 + (texsize.zw * vec2(0.0, -1.0))))).xyz;\\n  vec4 tmpvar_13;\\n  tmpvar_13.w = 0.0;\\n  tmpvar_13.xyz = max (tmpvar_12, texture (sampler_fc_main, domain_10)).xyz;\\n  vec4 tmpvar_14;\\n  tmpvar_14.w = 0.0;\\n  tmpvar_14.xyz = max (tmpvar_13, texture (sampler_fc_main, (domain_10 + (texsize.zw * vec2(0.0, 1.0))))).xyz;\\n  ret_3.x = ((max (tmpvar_14, texture (sampler_fc_main, \\n    (domain_10 + (texsize.zw * vec2(1.0, 0.0)))\\n  )).x + (\\n    (texture (sampler_main, (uv + (tmpvar_9 * 4.0))).x - ((texture (sampler_blur1, (uv + \\n      (tmpvar_9 * 4.0)\\n    )).xyz * scale1) + bias1).x)\\n   * 0.206)) - 0.09);\\n  vec4 tmpvar_15;\\n  tmpvar_15.w = 1.0;\\n  tmpvar_15.xyz = ret_3;\\n  ret = tmpvar_15.xyz;\\n }\",comp:\"float xlat_mutablelamp;\\nvec2 xlat_mutablers0;\\nvec2 xlat_mutablerss;\\nvec2 xlat_mutableuv1;\\n shader_body { \\n  vec3 tmpvar_1;\\n  tmpvar_1.x = q4;\\n  tmpvar_1.y = q5;\\n  tmpvar_1.z = q6;\\n  mat3 tmpvar_2;\\n  tmpvar_2[uint(0)].x = q20;\\n  tmpvar_2[uint(0)].y = q23;\\n  tmpvar_2[uint(0)].z = q26;\\n  tmpvar_2[1u].x = q21;\\n  tmpvar_2[1u].y = q24;\\n  tmpvar_2[1u].z = q27;\\n  tmpvar_2[2u].x = q22;\\n  tmpvar_2[2u].y = q25;\\n  tmpvar_2[2u].z = q28;\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = q1;\\n  tmpvar_3.y = q2;\\n  vec2 uv_4;\\n  vec3 dots_5;\\n  vec3 ret_6;\\n  vec2 tmpvar_7;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (uv - 0.5);\\n  tmpvar_7 = (0.5 + (tmpvar_8 * vec2(1.1, 0.81)));\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (uv - vec2(0.5, 0.5));\\n  uv_4 = (tmpvar_8 * aspect.xy);\\n  float tmpvar_10;\\n  float tmpvar_11;\\n  tmpvar_11 = (min (abs(\\n    (uv_4.y / uv_4.x)\\n  ), 1.0) / max (abs(\\n    (uv_4.y / uv_4.x)\\n  ), 1.0));\\n  float tmpvar_12;\\n  tmpvar_12 = (tmpvar_11 * tmpvar_11);\\n  tmpvar_12 = (((\\n    ((((\\n      ((((-0.01213232 * tmpvar_12) + 0.05368138) * tmpvar_12) - 0.1173503)\\n     * tmpvar_12) + 0.1938925) * tmpvar_12) - 0.3326756)\\n   * tmpvar_12) + 0.9999793) * tmpvar_11);\\n  tmpvar_12 = (tmpvar_12 + (float(\\n    (abs((uv_4.y / uv_4.x)) > 1.0)\\n  ) * (\\n    (tmpvar_12 * -2.0)\\n   + 1.570796)));\\n  tmpvar_10 = (tmpvar_12 * sign((uv_4.y / uv_4.x)));\\n  if ((abs(uv_4.x) > (1e-08 * abs(uv_4.y)))) {\\n    if ((uv_4.x < 0.0)) {\\n      if ((uv_4.y >= 0.0)) {\\n        tmpvar_10 += 3.141593;\\n      } else {\\n        tmpvar_10 = (tmpvar_10 - 3.141593);\\n      };\\n    };\\n  } else {\\n    tmpvar_10 = (sign(uv_4.y) * 1.570796);\\n  };\\n  xlat_mutablers0.x = ((tmpvar_10 / 3.1416) * 2.0);\\n  xlat_mutablers0.y = (0.02 / sqrt(dot (uv_4, uv_4)));\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = xlat_mutablers0.x;\\n  tmpvar_13.y = (xlat_mutablers0.y + time);\\n  xlat_mutablerss = (tmpvar_13 * mat2(0.7, -0.7, 0.7, 0.7));\\n  vec4 tmpvar_14;\\n  tmpvar_14 = vec4(greaterThanEqual ((texture (sampler_pw_noise_lq, \\n    (xlat_mutablerss / 32.0)\\n  ) - 0.7), vec4(0.0, 0.0, 0.0, 0.0)));\\n  vec2 tmpvar_15;\\n  tmpvar_15 = abs((fract(\\n    (xlat_mutablerss * 8.0)\\n  ) - 0.5));\\n  vec2 tmpvar_16;\\n  tmpvar_16.x = (xlat_mutablers0.x * 2.0);\\n  tmpvar_16.y = (xlat_mutablers0.y + (time / 2.0));\\n  xlat_mutablerss = (tmpvar_16 * mat2(0.7, -0.7, 0.7, 0.7));\\n  vec4 tmpvar_17;\\n  tmpvar_17 = vec4(greaterThanEqual ((texture (sampler_pw_noise_lq, \\n    (xlat_mutablerss / 32.0)\\n  ) - 0.7), vec4(0.0, 0.0, 0.0, 0.0)));\\n  vec2 tmpvar_18;\\n  tmpvar_18 = abs((fract(\\n    (xlat_mutablerss * 8.0)\\n  ) - 0.5));\\n  xlat_mutablerss = tmpvar_18;\\n  dots_5 = (vec3((clamp (\\n    (0.04 / sqrt(dot (tmpvar_15, tmpvar_15)))\\n  , 0.0, 1.0) * tmpvar_14.x)) + (clamp (\\n    (0.04 / sqrt(dot (tmpvar_18, tmpvar_18)))\\n  , 0.0, 1.0) * tmpvar_17.x));\\n  dots_5 = (dots_5 * clamp ((0.04 / \\n    abs((0.01 / xlat_mutablers0.y))\\n  ), 0.0, 1.0));\\n  dots_5 = (dots_5 * (dots_5 * 2.0));\\n  vec2 tmpvar_19;\\n  tmpvar_19.x = -((tmpvar_9.y * -1024.0));\\n  tmpvar_19.y = (tmpvar_9.x * -1024.0);\\n  vec2 tmpvar_20;\\n  tmpvar_20.x = tmpvar_19.x;\\n  tmpvar_20.y = -(tmpvar_19.y);\\n  uv_4 = (vec2(-100.0, 100.0) * (tmpvar_20 / (\\n    (tmpvar_19.x * tmpvar_19.x)\\n   + \\n    (tmpvar_19.y * tmpvar_19.y)\\n  )).yx);\\n  uv_4 = (0.5 + ((\\n    (1.0 - abs(((\\n      fract((mix ((0.5 + \\n        ((tmpvar_7 - 0.5) * 2.0)\\n      ), (uv_4 + 0.5), vec2(0.5, 0.5)) * 0.5))\\n     * 2.0) - 1.0)))\\n   - 0.5) * 0.98));\\n  uv_4 = (((uv_4 - 0.5) * 0.9) + 0.5);\\n  xlat_mutableuv1 = ((uv_4 - tmpvar_3) * aspect.xy);\\n  float tmpvar_21;\\n  tmpvar_21 = min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - (\\n    (texture (sampler_blur2, uv_4).xyz * scale2)\\n   + bias2).z));\\n  vec3 tmpvar_22;\\n  tmpvar_22.xy = ((uv_4 - 0.5) * min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - \\n    ((texture (sampler_blur2, uv_4).xyz * scale2) + bias2)\\n  .z)));\\n  tmpvar_22.z = min ((1.0 - texture (sampler_main, uv_4).z), (1.0 - (\\n    (texture (sampler_blur2, uv_4).xyz * scale2)\\n   + bias2).z));\\n  float tmpvar_23;\\n  tmpvar_23 = clamp ((abs(\\n    ((1.0 - ((texture (sampler_blur2, uv_4).xyz * scale2) + bias2).z) - clamp ((1.0 - (\\n      (texture (sampler_blur2, tmpvar_3).xyz * scale2)\\n     + bias2).z), 0.1, 0.4))\\n  ) + 0.2), 0.0, 1.0);\\n  vec3 tmpvar_24;\\n  tmpvar_24 = mix (texture (sampler_main, uv_4).xyz, ((texture (sampler_blur1, uv_4).xyz * scale1) + bias1), vec3(tmpvar_23));\\n  float tmpvar_25;\\n  tmpvar_25 = clamp (((1.0 - \\n    exp(-(((texture (sampler_blur1, uv_4).xyz * scale1) + bias1).x))\\n  ) - 0.2), 0.0, 1.0);\\n  ret_6 = ((tmpvar_24.x * (0.2 + \\n    ((1.0 - tmpvar_23) * (1.0 - tmpvar_21))\\n  )) * (1.0 + (0.5 * \\n    sin((((tmpvar_22 / q7) * tmpvar_2) + tmpvar_1))\\n  )));\\n  vec3 tmpvar_26;\\n  tmpvar_26.xy = vec2(0.0, 1.0);\\n  tmpvar_26.z = (tmpvar_25 * 3.0);\\n  vec3 tmpvar_27;\\n  tmpvar_27 = mix (ret_6, tmpvar_26, vec3(tmpvar_25));\\n  xlat_mutablelamp = (((\\n    clamp ((1.0 - (4.0 * sqrt(\\n      dot (xlat_mutableuv1, xlat_mutableuv1)\\n    ))), 0.0, 1.0)\\n   * tmpvar_24.x) * clamp (\\n    (1.0 - (2.0 * mix (tmpvar_21, (1.0 - \\n      ((texture (sampler_blur1, uv_4).xyz * scale1) + bias1)\\n    .z), 0.2)))\\n  , 0.0, 1.0)) * 1.8);\\n  ret_6 = (tmpvar_27 + ((1.0 - \\n    dot (tmpvar_27, vec3(0.32, 0.49, 0.29))\\n  ) * xlat_mutablelamp));\\n  ret_6 = (1.0 - exp((-2.0 * ret_6)));\\n  ret_6 = (ret_6 + (dots_5 * (1.0 + ret_6)));\\n  vec4 tmpvar_28;\\n  tmpvar_28.w = 1.0;\\n  tmpvar_28.xyz = ret_6;\\n  ret = tmpvar_28.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,wave_mode:4,additivewave:1,wave_dots:1,modwavealphabyvolume:1,wave_a:.331,wave_scale:.898,wave_smoothing:.108,wave_mystery:.1,modwavealphastart:.72,modwavealphaend:1.28,zoom:1.3345,wave_r:0,wave_g:.5,wave_b:.5,wave_y:.54,mv_x:24.8,mv_dy:.16,mv_l:1.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,samples:352,usedots:1,additive:1,scaling:.03856,smoothing:.2,g:0},init_eqs_str:\"a.t02=0;a.q1=0;a.ratio=0;a.ampl=0;a.x1=0;a.y1=0;\",frame_eqs_str:\"a.q1=a.bass_att;\",point_eqs_str:\"a.r=Math.abs(Math.sin(div(a.frame,38)));a.g=.5*Math.abs(Math.cos(div(a.frame,45)));a.b=.5*Math.abs(Math.sin(div(a.frame,133)));a.a=.3;a.t02+=div(a.q1,10);a.ratio=Math.sin(div(a.frame,49));a.ampl=.01+.4*sqr(Math.sin(div(a.frame,18))*Math.cos(div(a.frame,123)));a.x1=div(a.r-.5,15)+.5+a.ampl*Math.sin(6.28*a.sample);a.y1=div(a.b-.5,15)+.5+a.ampl*Math.cos(6.28*a.sample);a.x=a.x1+.2*(a.ampl+a.ratio)*Math.sin(6.28*a.sample*a.ratio*7.3);a.y=a.y1+.2*(a.ampl+a.ratio)*Math.cos(37.68*a.sample);\\n\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.oldshift=0;a.shift=0;a.normalframez=0;a.crash=0;a.nex=0;a.rshift=0;a.q1=0;a.zoom1=0;\",frame_eqs_str:\"a.dx=0;a.oldshift=a.shift;a.normalframez+=1;a.shift=above(a.bass_att,1)*above(a.treb_att,.9);a.crash=Math.abs(a.oldshift-a.shift);a.nex=1*equal(a.rshift,0)+2*equal(a.rshift,1);a.rshift=.00001<Math.abs(a.crash)?a.nex:a.rshift;a.monitor=a.rshift;a.wave_r=div(Math.floor(randint(200)),200);a.wave_g=div(Math.floor(randint(200)),200);a.wave_b=div(Math.floor(randint(200)),200);a.warp=0;a.q1=above(a.bass_att,1.3);a.zoom1=a.zoom+.15-.3*mod(a.normalframez,2);a.zoom=.00001<Math.abs(a.shift)?\\na.zoom1:1;a.rot=a.rot-.1+.1*a.rshift;\",pixel_eqs_str:\"a.dy=.007*-below(a.y,.4)+.007*above(a.y,.6);\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = ((texture (sampler_main, (uv_orig + \\n    ((uv - uv_orig) * dot (texture (sampler_main, uv).xyz, vec3(0.32, 0.49, 0.29)))\\n  )).xyz * 0.99) - 0.002);\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = (texture (sampler_main, uv).xyz * 2.0);\\n  ret_1 = (ret_1 * (1.0 - ret_1));\\n  ret_1 = (((1.0 - \\n    pow (clamp (ret_1, 0.0, 1.0), vec3(0.5, 0.5, 0.5))\\n  ) * 1.5) - 0.75);\\n  vec4 tmpvar_2;\\n  tmpvar_2.w = 1.0;\\n  tmpvar_2.xyz = ret_1;\\n  ret = tmpvar_2.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,decay:1,echo_zoom:1,echo_orient:3,wave_mode:1,wrap:0,darken_center:1,wave_a:.001,zoom:.97,rot:-6.27999,warp:52e-5,wave_r:0,wave_g:0,wave_b:0,ob_r:1,ob_g:1,ob_b:1,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,textured:1,rad:.49849,g:1,b:1,a:.7,r2:1,g2:0,b2:1,a2:.7,border_a:0},init_eqs_str:\"a.q2=0;a.tex_capture=0;a.q3=0;\",frame_eqs_str:\"a.r2=.5+.5*Math.sin(.35*a.q2);a.g2=.5+.5*Math.sin(.578*a.q2);a.b2=.5+.5*Math.sin(.689*a.q2);a.ang=a.q2;a.tex_capture=above(a.q3,2);\"},{baseVals:{enabled:1,sides:100,textured:1,rad:.74218,g:1,b:1,a:.6,r2:1,g2:0,b2:1,a2:.6,border_a:0},init_eqs_str:\"a.q2=0;a.tex_capture=0;a.q3=0;\",frame_eqs_str:\"a.r2=.5+.5*Math.sin(.45*a.q2);a.g2=.5+.5*Math.sin(.678*a.q2);a.b2=.5+.5*Math.sin(.689*a.q2);a.ang=1.05*-a.q2;a.tex_capture=above(a.q3,2);\"},{baseVals:{enabled:1,sides:100,textured:1,rad:1.00035,g:1,b:1,a:.5,r2:1,g2:0,b2:1,a2:.5,border_a:0},init_eqs_str:\"a.q2=0;a.tex_capture=0;a.q3=0;\",frame_eqs_str:\"a.r2=.5+.5*Math.sin(.45*a.q2);a.g2=.5+.5*Math.sin(.578*a.q2);a.b2=.5+.5*Math.sin(.789*a.q2);a.ang=.899*a.q2;a.tex_capture=above(a.q3,2);\"},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,sep:1,spectrum:1,thick:1,additive:1},init_eqs_str:\"a.xx=0;a.s=0;a.xs=0;a.ss=0;a.q1=0;a.xd=0;a.zd=0;a.v=0;a.yx=0;a.angle2=0;a.zs=0;a.angle=0;a.ys=0;a.xn=0;a.yd=0;a.angle3=0;a.yn=0;a.u=0;a.zx=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.u=3.14159*Math.cos(.1*a.q1);a.v=6.28318*Math.cos(.015*a.q1);a.s=314*a.sample;a.ss=6280*a.sample;a.xs=(.3+.1*Math.cos(a.s))*Math.cos(a.ss)*.2*Math.cos(a.v);a.ys=(.3+.1*Math.cos(a.s))*Math.sin(a.ss)*6*a.u;a.zs=.1*Math.sin(a.s)*Math.sin(a.v);a.angle=.1*a.q1;a.yx=a.ys*Math.cos(a.angle)-a.zs*Math.sin(a.angle);a.zx=a.ys*Math.sin(a.angle)+a.zs*Math.cos(a.angle);a.xx=a.xs;a.angle2=.11*a.q1;a.xd=a.xx*Math.cos(a.angle2)-a.zx*Math.sin(a.angle2);a.zd=a.xx*Math.sin(a.angle2)+a.zx*Math.cos(a.angle2);\\na.yd=a.yx;a.angle3=.15*a.q1;a.xn=a.xd*Math.cos(a.angle3)-a.yd*Math.sin(a.angle3);a.yn=a.xd*Math.sin(a.angle3)+a.yd*Math.cos(a.angle3);a.zd=a.zd;a.x=a.xn*a.zd*.3+.5;a.y=a.yn*a.zd*.36+.5;a.r=.5+.5*Math.sin(1.2*a.q1+a.x+a.x);a.g=.5+.5*Math.sin(1.5*a.q1+a.x+a.y);a.b=.5+.5*Math.sin(1.36*a.q1+a.y+a.y);\"},{baseVals:{enabled:1,sep:1,spectrum:1,thick:1,additive:1},init_eqs_str:\"a.xx=0;a.s=0;a.xs=0;a.ss=0;a.q1=0;a.xd=0;a.zd=0;a.v=0;a.yx=0;a.angle2=0;a.zs=0;a.angle=0;a.ys=0;a.xn=0;a.yd=0;a.angle3=0;a.yn=0;a.u=0;a.zx=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.u=3.14159*Math.cos(.1*a.q1);a.v=6.28318*Math.cos(.015*a.q1);a.s=314*a.sample;a.ss=6280*a.sample;a.xs=(.3+.1*Math.cos(a.s))*Math.cos(a.ss)*.2*Math.cos(a.v);a.ys=(.3+.1*Math.cos(a.s))*Math.sin(a.ss)*6*a.u;a.zs=.1*Math.sin(a.s)*Math.sin(a.v);a.angle=.1*a.q1;a.yx=a.ys*Math.cos(a.angle)-a.zs*Math.sin(a.angle);a.zx=a.ys*Math.sin(a.angle)+a.zs*Math.cos(a.angle);a.xx=a.xs;a.angle2=.13*a.q1;a.xd=a.xx*Math.cos(a.angle2)-a.zx*Math.sin(a.angle2);a.zd=a.xx*Math.sin(a.angle2)+a.zx*Math.cos(a.angle2);\\na.yd=a.yx;a.angle3=.16*a.q1;a.xn=a.xd*Math.cos(a.angle3)-a.yd*Math.sin(a.angle3);a.yn=a.xd*Math.sin(a.angle3)+a.yd*Math.cos(a.angle3);a.zd=a.zd;a.x=a.xn*a.zd*.3+.5;a.y=a.yn*a.zd*.36+.5;a.r=.5+.5*Math.sin(1.2*a.q1+a.x+a.x);a.g=.5+.5*Math.sin(1.5*a.q1+a.x+a.y);a.b=.5+.5*Math.sin(1.36*a.q1+a.y+a.y);\"},{baseVals:{enabled:1,sep:1,spectrum:1,thick:1,additive:1},init_eqs_str:\"a.xx=0;a.s=0;a.xs=0;a.ss=0;a.q1=0;a.xd=0;a.zd=0;a.v=0;a.yx=0;a.angle2=0;a.zs=0;a.angle=0;a.ys=0;a.xn=0;a.yd=0;a.angle3=0;a.yn=0;a.u=0;a.zx=0;\",frame_eqs_str:\"\",point_eqs_str:\"a.u=3.14159*Math.cos(.1*a.q1);a.v=6.28318*Math.cos(.015*a.q1);a.s=314*a.sample;a.ss=6280*a.sample;a.xs=(.3+.1*Math.cos(a.s))*Math.cos(a.ss)*.2*Math.cos(a.v);a.ys=(.3+.1*Math.cos(a.s))*Math.sin(a.ss)*6*a.u;a.zs=.1*Math.sin(a.s)*Math.sin(a.v);a.angle=.1*a.q1;a.yx=a.ys*Math.cos(a.angle)-a.zs*Math.sin(a.angle);a.zx=a.ys*Math.sin(a.angle)+a.zs*Math.cos(a.angle);a.xx=a.xs;a.angle2=.16*a.q1;a.xd=a.xx*Math.cos(a.angle2)-a.zx*Math.sin(a.angle2);a.zd=a.xx*Math.sin(a.angle2)+a.zx*Math.cos(a.angle2);\\na.yd=a.yx;a.angle3=.16*a.q1;a.xn=a.xd*Math.cos(a.angle3)-a.yd*Math.sin(a.angle3);a.yn=a.xd*Math.sin(a.angle3)+a.yd*Math.cos(a.angle3);a.zd=a.zd;a.x=a.xn*a.zd*.3+.5;a.y=a.yn*a.zd*.36+.5;a.r=.5+.5*Math.sin(1.2*a.q1+a.x+a.x);a.g=.5+.5*Math.sin(1.5*a.q1+a.x+a.y);a.b=.5+.5*Math.sin(1.36*a.q1+a.y+a.y);\"},{baseVals:{enabled:0}}],init_eqs_str:\"a.basstime=0;a.stickybit=0;a.volavg2=0;a.q1=0;a.decay_r=0;a.sample1=0;a.difftime=0;a.diff=0;a.decay_b=0;a.edge=0;a.volavg=0;a.bit2=0;a.vol=0;a.q2=0;a.q3=0;a.basssum=0;a.decay_g=0;a.sample2=0;\",frame_eqs_str:\"a.basstime+=.03*a.bass;a.q1=4*a.basstime;a.basstime=.00001<Math.abs(below(a.basstime,1E3))?1E3:a.basstime;a.basstime+=.03*a.bass_att;a.vol=pow(a.bass+a.mid+a.treb,2);a.basssum=a.vol;a.stickybit=mod(a.time,2);a.volavg+=a.vol*equal(a.stickybit,1);a.sample1+=equal(a.stickybit,1);a.volavg2+=a.vol*equal(a.stickybit,0);a.sample2+=equal(a.stickybit,0);a.edge=bnot(equal(a.bit2,a.stickybit));a.volavg-=a.volavg*a.edge*a.stickybit;a.volavg2-=a.volavg2*a.edge*equal(a.stickybit,0);a.sample1-=\\na.sample1*a.edge*a.stickybit;a.sample2-=a.sample2*a.edge*equal(a.stickybit,0);a.diff=.00001<Math.abs(equal(a.stickybit,1))?div(a.basssum,div(a.volavg2,a.sample2)):0;a.diff=.00001<Math.abs(equal(a.stickybit,0))?div(a.basssum,div(a.volavg,a.sample1)):a.diff;a.q3=a.diff;a.bit2=mod(a.time,2);a.difftime+=.03*a.diff;a.q2=a.difftime;a.difftime=.00001<Math.abs(above(a.difftime,2E3))?0:a.difftime;a.monitor=3.14*Math.abs(Math.cos(a.time));a.mv_a=above(a.diff,10);\",pixel_eqs_str:\"a.zoom=1+.05*a.q3*a.rad;a.decay_r=.2*a.rad*Math.sin(.35*a.q2)+.85+.1*Math.sin(a.q2);a.decay_g=.2*a.rad*Math.sin(.5*a.q2)+.85+.1*Math.sin(.7*a.q2);a.decay_b=.2*a.rad*Math.sin(.4*a.q2)+.85+.1*Math.sin(.8*a.q2);a.rot=0;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_fc_main, uv).xyz * (0.8 + (q3 * 0.1)));\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = (texture (sampler_main, uv).xyz * 2.0);\\n  ret = tmpvar_1.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1,decay:1,echo_zoom:1.007,echo_alpha:.5,echo_orient:1,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_a:.1,wave_scale:3.815,wave_smoothing:.9,modwavealphastart:0,modwavealphaend:1.1,zoom:1.0099,warp:.04177,wave_r:.65,wave_g:.65,ob_size:.007,ib_size:.26,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0},shapes:[{baseVals:{enabled:1,sides:3,x:.37,rad:6.81129,ang:3.64425,r:0,a:.5,g2:0,a2:.5,border_a:1},init_eqs_str:\"a.q1=0;a.t1=0;a.t1=.01*randint(100);a.t2=.01*randint(100);\",frame_eqs_str:\"a.ang=a.q1*(.303+.01*a.t1);a.r=Math.min(1,Math.max(0,.1*Math.sin(.417*a.time+1)));a.g=Math.min(1,Math.max(0,.1*Math.sin(.391*a.time+2)));a.b=Math.min(1,Math.max(0,.1*Math.sin(.432*a.time+4)));a.r2=Math.min(1,Math.max(0,a.r2+.02*Math.sin(.657*a.time+3)));a.g2=Math.min(1,Math.max(0,a.g2+.02*Math.sin(.737*a.time+5)));a.b2=Math.min(1,Math.max(0,a.b2+.02*Math.sin(.884*a.time+6)));a.additive=.5+.15*(a.bass+a.bass_att);\"},{baseVals:{enabled:1,sides:100,additive:1,textured:1,x:.37,rad:.89796,ang:3.64425,g:1,b:1,a:.5,g2:0,a2:1,border_a:0},init_eqs_str:\"a.q1=0;a.t1=0;a.t1=.01*randint(100);a.t2=.01*randint(100);\",frame_eqs_str:\"a.x+=.07*Math.sin(.15*a.q1+3);a.y+=.03*Math.sin(.19*a.q1+1);a.tex_ang=a.q1*(.01+.0001*a.t1);a.r=Math.min(1,Math.max(0,a.r+.01*Math.sin(.0417*a.time+1)));a.g=Math.min(1,Math.max(0,a.g+.01*Math.sin(.391*a.time+2)));a.b=Math.min(1,Math.max(0,a.b+.01*Math.sin(.432*a.time+4)));a.r2=Math.min(1,Math.max(0,a.r2+.01*Math.sin(.457*a.time+3)));a.g2=Math.min(1,Math.max(0,a.g2+.01*Math.sin(.0437*a.time+5)));a.b2=Math.min(1,Math.max(0,a.b2+.01*Math.sin(.484*a.time+6)));\"},{baseVals:{enabled:1,sides:100,additive:1,textured:1,x:.67,y:.43,rad:.51386,ang:4.20974,g:1,b:1,g2:0,a2:1,border_a:0},init_eqs_str:\"a.q1=0;a.t1=0;a.t2=0;a.t1=.01*randint(100);a.t2=.01*randint(100);\",frame_eqs_str:\"a.x+=.05*Math.sin(.017*a.q1);a.y+=.09*Math.sin(.013*a.q1);a.tex_ang=a.q1*(.02+.0001*a.t1);a.rad*=.9+.2*a.t2;a.r=Math.min(1,Math.max(0,a.r+.01*Math.sin(.417*a.time+1)));a.g=Math.min(1,Math.max(0,a.g+.01*Math.sin(.391*a.time+2)));a.b=Math.min(1,Math.max(0,a.b+.01*Math.sin(.432*a.time+4)));a.r2=Math.min(1,Math.max(0,a.r2+.01*Math.sin(.457*a.time+3)));a.g2=Math.min(1,Math.max(0,a.g2+.01*Math.sin(.437*a.time+5)));a.b2=Math.min(1,Math.max(0,a.b2+.01*Math.sin(.484*a.time+6)));\"},{baseVals:{enabled:1,sides:100,additive:1,textured:1,rad:.22298,r:.6,g:.8,b:1,g2:0,a2:1,border_a:0},init_eqs_str:\"a.q1=0;\",frame_eqs_str:\"a.x+=.08*Math.sin(.25*a.q1);a.y+=.1*Math.sin(.5*a.q1+2);a.ang=a.time;\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.movement=0;a.q1=0;\",frame_eqs_str:\"a.movement=a.movement+.1*Math.max(0,a.bass+a.bass_att-2)+.15*pow(a.bass,3)+.005;a.q1=a.movement;a.monitor=a.q1;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv);\\n  ret_1 = (tmpvar_2.xyz + ((tmpvar_2.xyz - \\n    ((texture (sampler_blur1, uv).xyz * scale1) + bias1)\\n  ) * 0.5));\\n  ret_1 = (ret_1 * 0.9);\\n  ret_1 = (ret_1 + ((\\n    ((texture (sampler_noise_lq, ((\\n      (uv_orig * texsize.xy)\\n     * \\n      (texsize_noise_lq.zw * 0.4)\\n    ) + rand_frame.xy)).xyz - 0.5) / 256.0)\\n   * 12.0) * clamp (\\n    (treb_att - 1.0)\\n  , 0.0, 1.0)));\\n  vec3 tmpvar_3;\\n  tmpvar_3 = mix (ret_1, vec3(dot (ret_1, vec3(0.32, 0.49, 0.29))), vec3(0.08, 0.08, 0.08));\\n  ret_1 = tmpvar_3;\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = tmpvar_3;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 uv3_2;\\n  vec2 uv2_3;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * aspect.xy);\\n  uv2_3.x = ((uv_1.x * -0.497265) - (uv_1.y * 0.8675987));\\n  uv2_3.y = ((uv_1.x * 0.8675987) + (uv_1.y * -0.497265));\\n  uv3_2.x = ((uv_1.x * -0.5000263) - (uv_1.y * -0.8660102));\\n  uv3_2.y = ((uv_1.x * -0.8660102) + (uv_1.y * -0.5000263));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = max (max (texture (sampler_main, (uv_1 + 0.5)).xyz, texture (sampler_main, (uv2_3 + 0.5)).xyz), texture (sampler_main, (uv3_2 + 0.5)).xyz);\\n  ret = tmpvar_4.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.49,decay:.5,echo_zoom:1.002,echo_alpha:.5,echo_orient:1,wave_mode:7,additivewave:1,modwavealphabyvolume:1,wave_brighten:0,wave_a:.001,wave_scale:1.157,wave_smoothing:.63,modwavealphastart:.71,modwavealphaend:1.3,warpscale:16.016,zoomexp:11.56276,fshader:1,zoom:1.05971,warp:.13126,wave_r:.65,wave_g:.65,wave_b:.65,ob_size:0,ob_a:1,ib_size:0,mv_x:64,mv_y:48,mv_l:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:14,num_inst:512,rad:.1026,tex_ang:.62832,r2:1,g2:0,a2:1,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;a.r_border=0;a.g_border=0;a.b_border=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.01*a.bass;a.ma-=3.1415*above(a.treb,1)*.01*a.treb;a.mx+=.0002*Math.cos(a.ma);a.my+=.0002*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.rad=div(a.bass+a.treb,30);a.a=above(a.bass+a.mid+a.treb,.8);a.r=div(Math.floor(randint(100)),100);a.g=div(Math.floor(randint(100)),\\n100);a.b=div(Math.floor(randint(100)),100);a.r2=div(Math.floor(randint(100)),100);a.g2=div(Math.floor(randint(100)),100);a.b2=div(Math.floor(randint(100)),100);a.r_border=div(Math.floor(randint(100)),100);a.g_border=div(Math.floor(randint(100)),100);a.b_border=div(Math.floor(randint(100)),100);\"},{baseVals:{enabled:1,sides:23,num_inst:1024,rad:.10262,ang:.43982,tex_ang:.62832,a:.5,r2:1,g2:0,a2:.5,border_a:0},init_eqs_str:\"a.ma=0;a.mx=0;a.my=0;a.r_border=0;a.g_border=0;a.b_border=0;\",frame_eqs_str:\"a.ma+=3.1415*above(a.bass,1)*.05*a.bass;a.ma-=3.1415*above(a.mid,1)*.05*a.mid;a.mx+=.0001*Math.cos(a.ma);a.my+=.0001*Math.sin(a.ma);a.mx=.00001<Math.abs(above(a.mx,.9))?.9-a.mx:a.mx;a.my=.00001<Math.abs(above(a.my,.9))?.9-a.my:a.my;a.mx=.00001<Math.abs(below(a.mx,.1))?.9+a.mx:a.mx;a.my=.00001<Math.abs(below(a.my,.1))?.9+a.my:a.my;a.x=a.mx;a.y=a.my;a.rad=div(a.bass+a.treb,25);a.a=above(a.bass+a.mid+a.treb,.1);a.r=div(Math.floor(randint(100)),100);a.g=div(Math.floor(randint(100)),\\n100);a.b=div(Math.floor(randint(100)),100);a.r2=div(Math.floor(randint(100)),100);a.g2=div(Math.floor(randint(100)),100);a.b2=div(Math.floor(randint(100)),100);a.r_border=div(Math.floor(randint(100)),100);a.g_border=div(Math.floor(randint(100)),100);a.b_border=div(Math.floor(randint(100)),100);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.y3=0;a.y1=0;a.xx=0;a.q12=0;a.x1=0;a.vx3=0;a.q6=0;a.dt=0;a.q1=0;a.q5=0;a.q9=0;a.d1=0;a.si1=0;a.vx4=0;a.grav=0;a.x3=0;a.d2=0;a.q11=0;a.q10=0;a.xx2=0;a.q4=0;a.yy1=0;a.vy4=0;a.dir=0;a.bounce=0;a.x4=0;a.r=0;a.x2=0;a.vy2=0;a.y2=0;a.q2=0;a.m1=0;a.spring=0;a.si2=0;a.vx2=0;a.q3=0;a.resist=0;a.yy=0;a.y4=0;a.q7=0;a.vy3=0;a.xx1=0;a.b1=0;a.q8=0;\",frame_eqs_str:\"a.xx1=.9*a.xx1+.01*a.bass;a.xx2=.9*a.xx2+.01*a.treb;a.yy1=.94*a.yy1+.0075*(a.treb+a.bass);a.x1=.5+2*(a.xx1-a.xx2);a.y1=.4+a.yy1;a.x1=Math.max(0,Math.min(1,a.x1));a.y1=Math.max(0,Math.min(1,a.y1));a.spring=10;a.grav=.5;a.resist=1;a.bounce=.75;a.dt=.0005*div(60,a.fps);a.vx2=a.vx2*(1-a.resist*a.dt)+a.dt*(a.x1+a.x3-2*a.x2)*a.spring;a.vy2=a.vy2*(1-a.resist*a.dt)+a.dt*((a.y1+a.y3-2*a.y2)*a.spring-a.grav);a.vx3=a.vx3*(1-a.resist*a.dt)+a.dt*(a.x2+a.x4-2*a.x3)*a.spring;a.vy3=a.vy3*(1-\\na.resist*a.dt)+a.dt*((a.y2+a.y4-2*a.y3)*a.spring-a.grav);a.vx4=a.vx4*(1-a.resist*a.dt)+a.dt*(a.x3-a.x4)*a.spring;a.vy4=a.vy4*(1-a.resist*a.dt)+a.dt*((a.y3-a.y4)*a.spring-a.grav);a.x2+=a.vx2;a.y2+=a.vy2;a.x3+=a.vx3;a.y3+=a.vy3;a.x4+=a.vx4;a.y4+=a.vy4;a.vx2=.00001<Math.abs(above(a.x2,0))?a.vx2:Math.abs(a.vx2)*a.bounce;a.vx2=.00001<Math.abs(below(a.x2,1))?a.vx2:-Math.abs(a.vx2)*a.bounce;a.vx3=.00001<Math.abs(above(a.x3,0))?a.vx3:Math.abs(a.vx3)*a.bounce;a.vx3=.00001<Math.abs(below(a.x3,1))?a.vx3:-Math.abs(a.vx3)*\\na.bounce;a.vx4=.00001<Math.abs(above(a.x4,0))?a.vx4:Math.abs(a.vx4)*a.bounce;a.vx4=.00001<Math.abs(below(a.x4,1))?a.vx4:-Math.abs(a.vx4)*a.bounce;a.vy2=.00001<Math.abs(above(a.y2,0))?a.vy2:Math.abs(a.vy2)*a.bounce;a.vy2=.00001<Math.abs(below(a.y2,1))?a.vy2:-Math.abs(a.vy2)*a.bounce;a.vy3=.00001<Math.abs(above(a.y3,0))?a.vy3:Math.abs(a.vy3)*a.bounce;a.vy3=.00001<Math.abs(below(a.y3,1))?a.vy3:-Math.abs(a.vy3)*a.bounce;a.vy4=.00001<Math.abs(above(a.y4,0))?a.vy4:Math.abs(a.vy4)*a.bounce;a.vy4=.00001<\\nMath.abs(below(a.y4,1))?a.vy4:-Math.abs(a.vy4)*a.bounce;a.q1=a.x1;a.q2=a.x2;a.q3=a.x3;a.q4=a.x4;a.q5=a.y1;a.q6=a.y2;a.q7=a.y3;a.q8=a.y4;a.q9=div(1,a.aspectx);a.q10=div(1,a.aspecty);a.zoom=1;a.r=.96*a.r+(a.x1-.5);a.rot=.1*a.r;a.q12=Math.atan2(a.vx4,a.vy4);a.q11=sqrt(a.vx4*a.vx4+a.vy4*a.vy4);a.zoom=1.001;a.rot=0;a.warp=.2;a.wave_a=0;\",pixel_eqs_str:\"a.dir=-a.q12+Math.asin(1);a.b1=.1;a.m1=25*a.q11;a.xx=a.q4;a.yy=1-a.q8;a.x1=a.xx-Math.sin(a.dir)*a.b1;a.y1=a.yy-Math.cos(a.dir)*a.b1;a.x2=a.xx+Math.sin(a.dir)*a.b1;a.y2=a.yy+Math.cos(a.dir)*a.b1;a.d1=sqrt((a.x1-a.x)*(a.x1-a.x)+(a.y1-a.y)*(a.y1-a.y))-2*a.b1;a.d2=sqrt((a.x2-a.x)*(a.x2-a.x)+(a.y2-a.y)*(a.y2-a.y))-2*a.b1;a.si1=sigmoid(-a.d1,1E3);a.si2=sigmoid(-a.d2,1E3);a.dx=2*(a.si1*Math.sin(a.y1-a.y)*a.m1*a.d1-a.si2*Math.sin(a.y2-a.y)*a.m1*a.d2);a.dy=2*(-a.si1*Math.sin(a.x1-a.x)*\\na.m1*a.d1+a.si2*Math.sin(a.x2-a.x)*a.m1*a.d2);\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = mix (uv_orig, uv, vec2(0.3, 0.3));\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 3.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = dot (((\\n    (texture (sampler_blur1, (tmpvar_1 + (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (tmpvar_1 - (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  tmpvar_3.y = dot (((\\n    (texture (sampler_blur1, (tmpvar_1 + (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (tmpvar_1 - (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = (texture (sampler_fc_main, (tmpvar_1 + (\\n    (tmpvar_3 * texsize.zw)\\n   * 9.0))) - 0.01).xyz;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret3_2;\\n  vec3 ret_3;\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (((uv - 0.5) * vec2(-1.0, 1.0)) + 0.5);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = abs(((texture (sampler_main, uv).xyz * \\n    clamp ((((\\n      (texture (sampler_blur2, uv).xyz * scale2)\\n     + bias2) * 2.8) - 0.13), 0.0, 1.0)\\n  ) - (texture (sampler_main, tmpvar_4).xyz * \\n    clamp ((((\\n      (texture (sampler_blur2, tmpvar_4).xyz * scale2)\\n     + bias2) * 2.8) - 0.13), 0.0, 1.0)\\n  )));\\n  ret3_2 = (tmpvar_5 * sqrt(tmpvar_5));\\n  ret3_2 = (ret3_2 * vec3(0.9, 1.6, 2.3));\\n  ret3_2 = (ret3_2 * 3.0);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = pow (ret3_2, (1.0 - ret3_2));\\n  ret3_2 = tmpvar_6;\\n  uv_1 = (uv * 2.0);\\n  vec2 tmpvar_7;\\n  tmpvar_7 = floor((fract(\\n    (uv_1 * 0.5)\\n  ) * 2.0));\\n  uv_1 = ((fract(uv_1) * (1.0 - tmpvar_7)) + (tmpvar_7 * fract(\\n    (1.0 - uv_1)\\n  )));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = rad;\\n  tmpvar_8.y = uv_1.y;\\n  uv_1 = tmpvar_8;\\n  vec2 tmpvar_9;\\n  tmpvar_9 = ((0.5 - tmpvar_8.yx) + 0.5);\\n  ret_3 = (texture (sampler_main, tmpvar_8.yx).xyz * clamp ((\\n    (((texture (sampler_blur2, tmpvar_8.yx).xyz * scale2) + bias2) * 2.8)\\n   - 0.13), 0.0, 1.0));\\n  vec3 tmpvar_10;\\n  tmpvar_10 = mix (ret_3, (texture (sampler_main, tmpvar_9).xyz * clamp (\\n    ((((texture (sampler_blur2, tmpvar_9).xyz * scale2) + bias2) * 2.8) - 0.13)\\n  , 0.0, 1.0)), vec3(0.5, 0.5, 0.5));\\n  ret_3 = (tmpvar_10 * tmpvar_10);\\n  ret_3 = (ret_3 * vec3(0.9, 1.6, 2.3));\\n  ret_3 = (ret_3 * 3.0);\\n  ret_3 = (max (tmpvar_6, (0.8 * vec3(\\n    (0.5 * dot (ret_3, vec3(0.32, 0.49, 0.29)))\\n  ))) - (roam_sin.xyz * roam_cos.zxy));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = ret_3;\\n  ret = tmpvar_11.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:0,gammaadj:1.35,decay:1,echo_zoom:2.144269,echo_alpha:.31,echo_orient:3,wave_mode:7,wave_brighten:0,wrap:0,wave_a:4.1,wave_scale:5.552,wave_smoothing:.504,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.999514,cx:-1,warp:.72142,sy:.980296,wave_g:0,wave_b:0,ob_size:.5,ob_r:1,ib_size:.5,ib_r:1,ib_g:0,ib_b:0,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:1,sides:5,textured:1,rad:.98608,tex_ang:3.14159,tex_zoom:.999794,g:1,b:1,r2:1,b2:1,a2:1,border_a:0},init_eqs_str:\"\",frame_eqs_str:\"a.ang=Math.sin(div(a.time,65));\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.bl=0;a.tic=0;a.swi=0;a.q6=0;a.it=0;a.q1=0;a.q5=0;a.bvb=0;a.itar=0;a.mid_avg=0;a.tin=0;a.bass_avg=0;a.vav=0;a.rate=0;a.bd=0;a.q4=0;a.cha=0;a.ra=0;a.treb_avg=0;a.ul=0;a.db=0;a.gv=0;a.q2=0;a.iter=0;a.q3=0;a.vm=0;a.cma=0;a.cm=0;a.rb=0;\",frame_eqs_str:\"a.bl=3.8;a.ul=7.9;a.rate=11.9;a.cha=.01;a.gv=.00001<Math.abs(above(a.gv,a.bl))?.00001<Math.abs(below(a.gv,a.ul))?.00001<Math.abs(above(a.fps,a.rate))?a.gv+a.cha:a.gv-a.cha:a.ul-.1:a.bl+.1;a.monitor=a.gv;a.wave_a=0;a.tic=Math.min(a.time-a.tin,1);a.tin=a.time;a.ra=10;a.treb_avg=a.tic*(a.treb_avg*(div(1,a.tic)-a.ra)+a.ra*a.treb);a.mid_avg=a.tic*(a.mid_avg*(div(1,a.tic)-a.ra)+a.ra*a.mid);a.bass_avg=a.tic*(a.bass_avg*(div(1,a.tic)-a.ra)+a.ra*a.bass);a.rb=1;a.vav=a.tic*(a.vav*(div(1,\\na.tic)-a.rb)+a.rb*(a.bass+a.treb+a.mid)*.33333);a.q1=a.treb_avg;a.q2=a.mid_avg;a.q3=a.bass_avg;a.db=a.bass-a.bass_avg;a.it=(a.it+a.tic)*below(a.it,1);a.rb=.5*div(1,a.tic);a.bvb=a.tic*(a.bass*a.rb+(div(1,a.tic)-a.rb)*a.bvb);a.bd=a.bass-a.bvb;a.vm=a.vm-a.tic+a.swi;a.swi=above(a.bd-a.vm,0);a.q4=1-a.swi;a.cm=.00001<Math.abs(above(a.iter,30)+equal(a.time,0))?randint(3)+1:a.cm;a.iter=(a.iter+a.tic)*(1-above(a.iter,30));a.q5=.00001<Math.abs(equal(a.cm,0))?3:a.cm;a.cma=.00001<Math.abs(above(a.itar,5)+equal(a.time,\\n0))?Math.floor(5*a.vav):a.cma;a.itar=(a.itar+a.tic)*(1-above(a.itar,5));a.q6=Math.floor(5*a.vav);a.decay=.97;a.zoom=1.01;a.sx=1;a.sy=1;\",pixel_eqs_str:\"a.warp=a.bass;\",warp:\" shader_body { \\n  vec3 ret_1;\\n  ret_1 = ((texture (sampler_main, uv_orig).xyz * vec3(0.97, 1.0, 0.97)) - vec3(0.03, 0.0, 0.03));\\n  vec4 tmpvar_2;\\n  tmpvar_2 = texture (sampler_blur1, uv_orig);\\n  ret_1.z = (ret_1.z + ((\\n    (tmpvar_2.xyz * scale1)\\n   + bias1).z * 0.45));\\n  ret_1.x = (ret_1.x + ((\\n    ((tmpvar_2.xyz * scale1) + bias1)\\n  .z * 0.05) + (\\n    ((texture (sampler_blur3, uv_orig).xyz * scale3) + bias3)\\n  .z * 0.05)));\\n  ret_1.z = (ret_1.z - ret_1.x);\\n  ret_1.y = clamp (texture (sampler_pw_main, uv_orig).y, 0.0, 1.0);\\n  ret_1 = (ret_1 * 0.98);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ret_1;\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret_1;\\n  vec3 tmpvar_2;\\n  tmpvar_2.z = 0.0;\\n  tmpvar_2.xy = texsize.zw;\\n  vec3 tmpvar_3;\\n  tmpvar_3 = (tmpvar_2 * 2.5);\\n  ret_1 = (texture (sampler_main, uv).xyz * 0.5);\\n  ret_1 = (ret_1 + (vec3(3.4, 2.38, 1.02) * (\\n    dot (((texture (sampler_blur1, (uv + tmpvar_3.xz)).xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29))\\n   - \\n    dot (((texture (sampler_blur1, (uv - tmpvar_3.xz)).xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29))\\n  )));\\n  ret_1 = (ret_1 + (vec3(0.68, 1.7, 2.38) * (\\n    dot (((texture (sampler_blur1, (uv + tmpvar_3.zy)).xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29))\\n   - \\n    dot (((texture (sampler_blur1, (uv - tmpvar_3.zy)).xyz * scale1) + bias1), vec3(0.32, 0.49, 0.29))\\n  )));\\n  ret_1 = (ret_1 * 1.5);\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = ret_1;\\n  ret = tmpvar_4.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:2.05,decay:.99,echo_zoom:1.008,echo_alpha:.5,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.625,wave_scale:1.187,wave_smoothing:0,modwavealphastart:.71,modwavealphaend:1.3,warpanimspeed:1.459,warpscale:2.007,fshader:.19,zoom:.9999,warp:.01,sx:.9999,wave_r:.5,wave_g:.5,wave_b:.5,ob_r:1,ob_g:1,ob_b:1,ib_size:.26,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:.5},shapes:[{baseVals:{enabled:1,sides:9,thickoutline:1,textured:1,rad:.12566,ang:3.39292,tex_ang:.3768,tex_zoom:.32473,g:1,b:1,r2:1,b2:1,a2:1,border_r:.03,border_g:.67,border_b:.79,border_a:1},init_eqs_str:\"a.q1=0;a.q2=0;a.q3=0;\",frame_eqs_str:\"a.x+=.13*Math.sin(.9*a.time);a.y+=.16*Math.sin(.5*a.time);a.border_r=a.q1;a.border_b=a.q2;a.border_g=a.q3;\"},{baseVals:{enabled:1,sides:3,thickoutline:1,rad:.12572,a2:1,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.q1=0;a.q2=0;a.q3=0;\",frame_eqs_str:\"a.rad=a.rad-.2+.2*a.bass_att;a.r=a.r+.25*Math.sin(1.1*a.time)+.2*Math.sin(.25*a.time);a.g=a.g+.25*Math.cos(1.5*a.time)+.22*Math.cos(.24*a.time);a.b=a.b+.25*Math.sin(.6*a.time)+.27*Math.cos(.7*a.time);a.r2=1-Math.abs(a.r);a.g2=1-Math.abs(a.g);a.b2=1-Math.abs(a.b);a.ang+=3*Math.abs(Math.tan(1*a.time));a.x=a.x+.14*Math.cos(a.time)+.2*Math.sin(.42*a.time);a.y=a.y+.16*Math.sin(1.2*a.time)+.15*Math.sin(.8*a.time)+.21*Math.cos(.45*a.time);a.border_r=a.q1;a.border_b=a.q2;a.border_g=\\na.q3;\"},{baseVals:{enabled:1,ang:.03,r:.21,g:.44,b:.23,r2:.18,b2:.11,a2:1,border_r:.15,border_g:.4,border_b:.48,border_a:1},init_eqs_str:\"a.q1=0;a.q2=0;a.q3=0;\",frame_eqs_str:\"a.ang=2.4*a.time;a.x=.5+.22*Math.cos(3.3*a.time)+.14*Math.cos(1.2*a.time);a.y=.5+.26*Math.sin(3.1*a.time)+.13*Math.sin(1.7*a.time);a.r=.5+.5*Math.sin(1.013*a.time+5);a.g=.5+.5*Math.sin(1.063*a.time+2);a.b=.5+.5*Math.sin(1.054*a.time+1);a.r2=.5+.5*Math.sin(1.085*a.time+3);a.g2=.5+.5*Math.sin(1.056*a.time+1);a.b2=.5+.5*Math.sin(1.038*a.time+4);a.border_r=a.q1;a.border_b=a.q2;a.border_g=a.q3;\"},{baseVals:{enabled:1,sides:5,x:.51,y:.49,rad:.09986,ang:.06283,a2:1,border_r:.46,border_g:.28,border_b:.54,border_a:1},init_eqs_str:\"a.q4=0;a.q1=0;a.q2=0;a.q3=0;\",frame_eqs_str:\"a.x=.5+.07*Math.cos(.5*a.q4)+.31*Math.sin(3.5*a.time);a.y=.5+.07*Math.sin(.5*a.q4)+.31*Math.cos(3.5*a.time);a.r=.5+.5*Math.sin(1.013*a.time+2);a.g=.5+.5*Math.sin(.863*a.time+3);a.b=.5+.5*Math.sin(1.054*a.time+1);a.r2=.5+.5*Math.sin(1.185*a.time+3);a.g2=.5+.5*Math.sin(1.356*a.time+2);a.b2=.5+.5*Math.sin(.738*a.time+4);a.border_r=a.q1;a.border_b=a.q2;a.border_g=a.q3;\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.index2=0;a.xk=0;a.kiss=0;a.sw=0;a.yk=0;a.index=0;a.q22=0;a.q21=0;a.q29=0;a.q6=0;a.dt=0;a.y0=0;a.q1=0;a.dec_med=0;a.q5=0;a.index3=0;a.q9=0;a.x0=0;a.ax=0;a.rott=0;a.is_beat=0;a.q23=0;a.k1=0;a.q24=0;a.vx=0;a.dec_slow=0;a.q10=0;a.vy=0;a.q4=0;a.k2=0;a.q26=0;a.ay=0;a.p2=0;a.avg=0;a.beat=0;a.vol=0;a.p1=0;a.peak=0;a.q2=0;a.q27=0;a.q3=0;a.t0=0;a.m=0;a.q7=0;a.q28=0;a.v2=0;a.q20=0;a.q8=0;a.vol=0;a.p1=0;a.vx=.2;a.vy=-.1;a.kx=0;a.ky=0;\",frame_eqs_str:\"a.dec_med=pow(.96,div(30,a.fps));a.dec_slow=pow(.999,div(30,a.fps));a.beat=Math.max(Math.max(a.bass,a.mid),a.treb);a.avg=a.avg*a.dec_slow+a.beat*(1-a.dec_slow);a.is_beat=above(a.beat,.5+a.avg+a.peak)*above(a.time,a.t0+.2);a.t0=a.is_beat*a.time+(1-a.is_beat)*a.t0;a.peak=a.is_beat*a.beat+(1-a.is_beat)*a.peak*a.dec_med;a.index=mod(a.index+a.is_beat,8);a.index2=mod(a.index2+a.is_beat*bnot(a.index),2);a.index3=mod(a.index3+a.is_beat*bnot(a.index)*bnot(a.index2),2);a.q20=a.avg;a.q21=\\na.beat;a.q22=a.peak;a.q23=a.index;a.q24=a.is_beat;a.vol=a.bass_att+a.treb_att;a.v2=a.v2*a.dec_med+a.vol*(1-a.dec_med);a.q26=Math.max(Math.atan(a.vol-a.v2),0);a.q27=a.index+1;a.sw=a.sw*a.dec_med+(1-a.dec_med)*mod(a.index2,2);a.q28=a.sw;a.kiss=a.kiss*a.dec_med+(1-a.dec_med)*bnot(a.index2)*below(a.index,4);a.q29=a.kiss;a.k1=a.is_beat*bnot(a.index);a.k2=a.is_beat*bnot(a.index);a.p1=a.k1*(a.p1+1)+(1-a.k1)*a.p1;a.p2=a.dec_med*a.p2+(1-a.dec_med)*a.p1;a.rott=div(3.1416*a.p2,2);a.monitor=a.k1;a.q1=Math.cos(a.rott);\\na.q2=Math.sin(a.rott);a.q3=-a.q2;a.q4=a.q1;a.q5=Math.cos(div(a.time,4));a.q6=-Math.sin(div(a.time,4));a.q7=-a.q6;a.q8=a.q5;a.zoom=1;a.rot=-0;a.dt=div(3,a.fps);a.m=1;a.x0=0;a.y0=0;a.ax=div(-(a.xk-a.x0),a.m)+div(sign(a.vx+.001)*a.dt*a.bass,40);a.ay=div(-(a.yk-a.y0),a.m)+div(sign(a.vy+.001)*a.dt*a.treb,40);a.monitor=a.index3;a.vx=a.vx*a.dec_slow+a.ax*a.dt;a.vy=a.vy*a.dec_slow+a.ay*a.dt;a.xk+=a.vx*a.dt;a.yk+=a.vy*a.dt;a.q9=a.xk;a.q10=a.yk;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = ((uv * texsize.xy) * 0.08);\\n  vec3 tmpvar_2;\\n  tmpvar_2 = (texture (sampler_main, (uv - (\\n    ((sin(tmpvar_1) / cos(tmpvar_1)) * texsize.zw)\\n   * 3.0))).xyz + (vec3(dot (texture (sampler_noise_lq, \\n    ((((texsize.xy * texsize_noise_lq.zw).x * uv) * 0.02) + (0.1 * rand_frame).xy)\\n  ), vec4(0.32, 0.49, 0.29, 0.0))) / 30.0));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = ((mix (tmpvar_2, \\n    (1.0 - tmpvar_2.zyx)\\n  , vec3(0.01, 0.01, 0.01)) - 0.03) - (0.2 * pow (\\n    (1.0 - rad)\\n  , 18.0)));\\n  ret = tmpvar_3.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = cos(((uv.y * texsize.y) / 2.0));\\n  tmpvar_2.y = sin(((uv.x * texsize.x) / 2.0));\\n  uv_1 = (uv + ((2.0 * texsize.zw) * tmpvar_2));\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = (1.4 * pow ((\\n    clamp (((texture (sampler_blur1, uv_1).xyz * scale1) + bias1), 0.0, 1.0)\\n   * \\n    (texture (sampler_pc_main, uv_1).xyz - ((texture (sampler_blur3, uv_1).xyz * scale3) + bias3))\\n  ), vec3(0.5, 0.5, 0.5)));\\n  ret = tmpvar_3.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:4,gammaadj:1.98,echo_zoom:2.448,echo_alpha:.5,wave_thick:1,wrap:0,wave_a:3.645,wave_scale:1.951,wave_smoothing:.5,wave_mystery:-.5,warpscale:2.853,zoomexp:2.1,zoom:1.025,warp:1.29077,wave_g:0,wave_b:0,ob_size:0,ob_a:1,ib_size:0,ib_r:0,ib_g:0,ib_b:0,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:100,rad:.13518,g2:0,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.q8=0;\",frame_eqs_str:\"a.x=.3+.05*Math.sin(.89*a.q8);a.y=.4-.05*Math.cos(.77*a.q8);a.r=.25+.25*Math.sin(.7679*a.time);a.g=.25+.25*Math.sin(.8079*a.time);a.b=.25+.25*Math.sin(.7339*a.time);a.r2=.25+.25*Math.sin(.6979*a.time);a.g2=.25+.25*Math.sin(.849*a.time);a.b2=.25+.25*Math.sin(.8079*a.time);\"},{baseVals:{enabled:1,sides:100,rad:.06623,g2:0,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.q8=0;\",frame_eqs_str:\"a.x=.3-.05*Math.sin(.7089*a.q8);a.y=.4+.05*Math.cos(.5077*a.q8);a.r=.25+.25*Math.sin(.6479*a.time);a.g=.25+.25*Math.sin(.5079*a.time);a.b=.25+.25*Math.sin(.9339*a.time);a.r2=.25+.25*Math.sin(.779*a.time);a.g2=.25+.25*Math.sin(.707*a.time);a.b2=.25+.25*Math.sin(.747*a.time);\"},{baseVals:{enabled:1,sides:100,rad:.03646,g2:0,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.q8=0;\",frame_eqs_str:\"a.x=.3+.05*Math.sin(.679*a.q8);a.y=.4-.05*Math.cos(.877*a.q8);a.r=.25+.25*Math.sin(.5679*a.time);a.g=.25+.25*Math.sin(.4079*a.time);a.b=.25+.25*Math.sin(1.1339*a.time);a.r2=.25+.25*Math.sin(.9979*a.time);a.g2=.25+.25*Math.sin(.891*a.time);a.b2=.25+.25*Math.sin(.713*a.time);\"},{baseVals:{enabled:1,sides:100,rad:.0122,g2:0,a2:1,border_r:0,border_g:0,border_b:0,border_a:1},init_eqs_str:\"a.q8=0;\",frame_eqs_str:\"a.x=.3+.05*Math.sin(.916*a.q8);a.y=.4-.05*Math.cos(.977*a.q8);a.r=.25+.25*Math.sin(1.1679*a.time);a.g=.25+.25*Math.sin(1.18079*a.time);a.b=.25+.25*Math.sin(1.17339*a.time);a.r2=.25+.25*Math.sin(1.16979*a.time);a.g2=.25+.25*Math.sin(1.1849*a.time);a.b2=.25+.25*Math.sin(1.81079*a.time);\"}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.myrad=0;a.q25=0;a.q12=0;a.q18=0;a.q22=0;a.q21=0;a.vt=0;a.q13=0;a.q15=0;a.q29=0;a.q6=0;a.q1=0;a.myx=0;a.q5=0;a.vb=0;a.q9=0;a.myy=0;a.oldq8=0;a.q31=0;a.q23=0;a.q24=0;a.q11=0;a.q10=0;a.q4=0;a.q16=0;a.mybass=0;a.q26=0;a.rd=0;a.q19=0;a.q17=0;a.q2=0;a.q27=0;a.q14=0;a.q3=0;a.vvm=0;a.q32=0;a.vvb=0;a.q7=0;a.q28=0;a.vm=0;a.q30=0;a.q20=0;a.vvt=0;a.q8=0;\",frame_eqs_str:\"a.vb=.95*a.vb+(1-a.vb)*pow(a.bass_att,2)*.02;a.vvb=.95*a.vvb+(1-a.vvb)*a.vb*.01;a.vm=.95*a.vm+(1-a.vm)*pow(a.mid_att,2)*.02;a.vvm=.95*a.vvm+(1-a.vvm)*a.vm*.01;a.vt=.95*a.vt+(1-a.vt)*pow(a.treb_att,2)*.02;a.vvt=.95*a.vvt+(1-a.vvt)*a.vt*.01;a.vvb=Math.min(1,Math.max(0,a.vvb));a.vvm=Math.min(1,Math.max(0,a.vvm));a.vvt=Math.min(1,Math.max(0,a.vvt));a.q1=2*a.vvb;a.q2=2*a.vvm;a.q3=2*a.vvt;a.q4=5*(a.q1+a.q2+a.q3);a.q5=5*(a.q1+a.q2+a.q3);a.q6=5*(a.q1+a.q2+a.q3);a.q7=5*(a.q1+a.q2+a.q3);\\na.q8=5*(a.q1+a.q2+a.q3);a.q9=5*(a.q1+a.q2+a.q3);a.q10=5*(a.q1+a.q2+a.q3);a.q11=5*(a.q1+a.q2+a.q3);a.q12=5*(a.q1+a.q2+a.q3);a.q13=5*(a.q1+a.q2+a.q3);a.q14=5*(a.q1+a.q2+a.q3);a.q15=5*(a.q1+a.q2+a.q3);a.q16=5*(a.q1+a.q2+a.q3);a.q17=5*(a.q1+a.q2+a.q3);a.q18=5*(a.q1+a.q2+a.q3);a.q19=5*(a.q1+a.q2+a.q3);a.q20=5*(a.q1+a.q2+a.q3);a.q21=5*(a.q1+a.q2+a.q3);a.q22=5*(a.q1+a.q2+a.q3);a.q23=5*(a.q1+a.q2+a.q3);a.q24=5*(a.q1+a.q2+a.q3);a.q25=5*(a.q1+a.q2+a.q3);a.q26=5*(a.q1+a.q2+a.q3);a.q27=5*(a.q1+a.q2+a.q3);a.q28=\\n5*(a.q1+a.q2+a.q3);a.q29=5*(a.q1+a.q2+a.q3);a.q30=5*(a.q1+a.q2+a.q3);a.q31=5*(a.q1+a.q2+a.q3);a.q32=5*(a.q1+a.q2+a.q3);a.warp=0;a.rot=0;a.cx=.5;a.cy=.5;a.q1=.5+.1*Math.sin(a.time);a.q2=.5-.1*Math.cos(a.time);a.wave_a=0;a.decay=.95;a.q1=.5+.1*Math.sin(a.q8);a.q2=.5;a.q8=a.oldq8+.003*div(pow(1+1.2*a.bass+.4*a.bass_att+.1*a.treb+.1*a.treb_att+.1*a.mid+.1*a.mid_att,6),a.fps);a.oldq8=a.q8;a.mybass+=.01*(a.bass+a.bass_att);a.zoom=1.09;a.q1=.5+0*Math.sin(.12*a.q8);a.q2=.5-0*Math.cos(.177*a.q8);\",pixel_eqs_str:\"a.myx=1.1*(a.x-a.q1);a.myy=1.1*(a.y-a.q2);a.myrad=a.myx*a.myx+a.myy*a.myy;a.dx=(.5+.02*Math.sin(a.q8))*div(a.myy,a.myrad+1);a.dy=-(.5+.02*Math.sin(.897*a.q8))*div(a.myx,a.myrad+1);a.rd=a.bass*a.rad;a.rot=div(a.rd,10);a.sy=1.02+div(a.rad,10);a.sx=a.sy-a.myrad;\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = ((uv_orig - 0.5) * vec2(1.81, 1.81));\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = ((tmpvar_1.x * tmpvar_1.x) - (tmpvar_1.y * tmpvar_1.y));\\n  tmpvar_2.y = ((2.0 * tmpvar_1.x) * tmpvar_1.y);\\n  vec4 tmpvar_3;\\n  tmpvar_3.w = 1.0;\\n  tmpvar_3.xyz = (texture (sampler_fc_main, (tmpvar_2 + vec2(0.448, 0.701))) - 0.004).xyz;\\n  ret = tmpvar_3.xyz;\\n }\",comp:\"vec3 xlat_mutableneu;\\nvec3 xlat_mutableret1;\\n shader_body { \\n  vec2 uv_1;\\n  float inten_2;\\n  float dist_3;\\n  vec2 uv2_4;\\n  uv_1 = (uv - 0.5);\\n  uv_1 = (uv_1 * aspect.xy);\\n  float tmpvar_5;\\n  tmpvar_5 = (time / 2.0);\\n  dist_3 = (1.0 - fract(tmpvar_5));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 8.0);\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = q1;\\n  tmpvar_6.y = q2;\\n  vec2 tmpvar_7;\\n  tmpvar_7 = fract(((\\n    ((3.0 * uv_1) * dist_3)\\n   + 0.5) + (tmpvar_6 * 0.05)));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_7).xyz - ((texture (sampler_blur1, \\n    (tmpvar_7 + 0.003)\\n  ).xyz * scale1) + bias1));\\n  xlat_mutableret1 = max (vec3(0.0, 0.0, 0.0), (xlat_mutableneu * inten_2));\\n  uv2_4.x = ((uv_1.x * -0.4990803) - (uv_1.y * 0.8665558));\\n  uv2_4.y = ((uv_1.x * 0.8665558) + (uv_1.y * -0.4990803));\\n  dist_3 = (1.0 - fract((0.3333333 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 8.0);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = q1;\\n  tmpvar_8.y = q2;\\n  vec2 tmpvar_9;\\n  tmpvar_9 = fract(((\\n    ((3.0 * uv2_4) * dist_3)\\n   + 0.5) + (tmpvar_8 * 0.05)));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_9).xyz - ((texture (sampler_blur1, \\n    (tmpvar_9 + 0.003)\\n  ).xyz * scale1) + bias1));\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_2));\\n  uv2_4.x = ((uv_1.x * -0.5018377) - (uv_1.y * -0.8649619));\\n  uv2_4.y = ((uv_1.x * -0.8649619) + (uv_1.y * -0.5018377));\\n  dist_3 = (1.0 - fract((0.6666667 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 8.0);\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = q1;\\n  tmpvar_10.y = q2;\\n  vec2 tmpvar_11;\\n  tmpvar_11 = fract(((\\n    ((3.0 * uv2_4) * dist_3)\\n   + 0.5) + (tmpvar_10 * 0.05)));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_11).xyz - ((texture (sampler_blur1, \\n    (tmpvar_11 + 0.003)\\n  ).xyz * scale1) + bias1));\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_2));\\n  uv2_4.x = ((uv_1.x * 0.9999949) - (uv_1.y * -0.003185092));\\n  uv2_4.y = ((uv_1.x * -0.003185092) + (uv_1.y * 0.9999949));\\n  dist_3 = (1.0 - fract((1.0 + tmpvar_5)));\\n  inten_2 = ((sqrt(dist_3) * (1.0 - dist_3)) * 8.0);\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = q1;\\n  tmpvar_12.y = q2;\\n  vec2 tmpvar_13;\\n  tmpvar_13 = fract(((\\n    ((3.0 * uv2_4) * dist_3)\\n   + 0.5) + (tmpvar_12 * 0.05)));\\n  xlat_mutableneu = (texture (sampler_main, tmpvar_13).xyz - ((texture (sampler_blur1, \\n    (tmpvar_13 + 0.003)\\n  ).xyz * scale1) + bias1));\\n  xlat_mutableret1 = max (xlat_mutableret1, (xlat_mutableneu * inten_2));\\n  vec4 tmpvar_14;\\n  tmpvar_14.w = 1.0;\\n  tmpvar_14.xyz = (xlat_mutableret1 * 4.0);\\n  ret = tmpvar_14.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:5,gammaadj:1,decay:1,echo_zoom:1,echo_orient:1,wave_thick:1,wave_brighten:0,wrap:0,brighten:1,wave_a:.401,wave_scale:3.177,wave_smoothing:0,wave_mystery:-.4,modwavealphastart:1,modwavealphaend:1,warpanimspeed:2.289,warpscale:5.472,zoomexp:.01,zoom:.9901,warp:1.8566,ob_size:.005,ob_a:1,ib_size:0,ib_r:1,ib_g:0,ib_b:0,ib_a:1,mv_x:64,mv_y:48,mv_l:0,mv_b:0,mv_a:0},shapes:[{baseVals:{enabled:1,sides:12,additive:1,num_inst:512,y:.55,rad:.034,tex_zoom:.7874,g:.45,g2:0,border_a:0},init_eqs_str:\"a.my_z=0;a.d=0;a.y3=0;a.z2=0;a.y1=0;a.w=0;a.w2=0;a.t1=0;a.x1=0;a.rnd2=0;a.zoom=0;a.p=0;a.q1=0;a.q5=0;a.z3=0;a.w3=0;a.t3=0;a.my_x=0;a.x3=0;a.wv=0;a.my_y=0;a.q4=0;a.t=0;a.w1=0;a.i=0;a.x2=0;a.t2=0;a.l=0;a.y2=0;a.rnd4=0;a.wh=0;a.q2=0;a.z1=0;a.rnd3=0;a.rnd1=0;a.q3=0;a.t4=0;a.started=0;a.t1=.412;a.t2=.4563;a.t3=.6452;a.t4=.2565;\",frame_eqs_str:\"a.rnd1=.00001<Math.abs(equal(a.instance,0))?a.t1:a.rnd1;a.rnd2=.00001<Math.abs(equal(a.instance,0))?a.t2:a.rnd2;a.rnd3=.00001<Math.abs(equal(a.instance,0))?a.t3:a.rnd3;a.rnd4=.00001<Math.abs(equal(a.instance,0))?a.t4:a.rnd4;a.rnd1=4*a.rnd1*(1-a.rnd1);a.rnd2=4*a.rnd2*(1-a.rnd2);a.rnd3=4*a.rnd3*(1-a.rnd3);a.rnd4=4*a.rnd4*(1-a.rnd4);a.t=.6;a.t=a.rnd1+a.time*a.t-Math.floor(a.rnd1+a.time*a.t);a.t+=.1*a.rnd2;a.wh=a.rnd4*Math.asin(1)*4;a.wv=.25+.1*a.rnd3;a.d=1.4;a.zoom=1;a.l=1;a.w1=\\na.q3;a.w2=a.q4;a.w3=a.q5;a.i=a.instance;a.my_x=a.t*Math.cos(a.wh)*Math.sin(a.wv)*a.l;a.my_y=(-.5+(a.t-.75)*(a.t-.75))*Math.cos(a.wv)*a.l;a.my_z=a.t*Math.sin(a.wh)*Math.sin(a.wv)*a.l;a.x1=Math.cos(a.w1)*a.my_x+Math.sin(a.w1)*a.my_y;a.y1=-Math.sin(a.w1)*a.my_x+Math.cos(a.w1)*a.my_y;a.z1=a.my_z;a.x2=Math.cos(a.w2)*a.x1+Math.sin(a.w2)*a.z1;a.z2=-Math.sin(a.w2)*a.x1+Math.cos(a.w2)*a.z1;a.y2=a.y1;a.y3=Math.cos(a.w3)*a.y2+Math.sin(a.w3)*a.z2;a.z3=-Math.sin(a.w3)*a.y2+Math.cos(a.w3)*a.z2;a.x3=a.x2;a.l=sqrt(a.x3*\\na.x3+a.y3*a.y3);a.w=Math.atan2(a.x3,a.y3);a.p=Math.tan(Math.asin(1)+Math.atan2(a.d+a.z3,a.l));a.d=sqrt(a.x3*a.x3+a.y3*a.y3+(a.z3+a.d)*(a.z3+a.d));a.rad=div(a.rad,a.d);a.my_x=a.zoom*Math.sin(a.w)*a.p;a.my_y=a.zoom*Math.cos(a.w)*a.p;a.x=.5+a.my_x;a.y=.5+a.my_y;a.x=.5+div(a.x-.5,a.q2);a.y=.5+div(a.y-.5,a.q1);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q1=0;a.q2=0;a.b=0;a.m=0;a.t=0;a.q3=0;a.q4=0;a.q5=0;\",frame_eqs_str:\"a.wave_a=0;a.q1=a.aspectx;a.q2=a.aspecty;a.b+=a.bass*a.bass*.85;a.m+=a.mid*a.mid*.85;a.t+=a.treb*a.treb*.85;a.q3=.012*a.b;a.q4=.012*a.m;a.q5=.012*a.t;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec3 ret_2;\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (vec2(1280.0, 1024.0) * texsize.zw);\\n  float tmpvar_4;\\n  vec2 tmpvar_5;\\n  tmpvar_5 = (uv + vec2(0.005, 0.0));\\n  vec2 tmpvar_6;\\n  tmpvar_6 = (uv - vec2(0.005, 0.0));\\n  tmpvar_4 = (((\\n    (texture (sampler_blur2, tmpvar_5).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_6).xyz * scale2)\\n   + bias2)).x * tmpvar_3.x);\\n  float tmpvar_7;\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (uv + vec2(0.0, 0.005));\\n  vec2 tmpvar_9;\\n  tmpvar_9 = (uv - vec2(0.0, 0.005));\\n  tmpvar_7 = (((\\n    (texture (sampler_blur2, tmpvar_8).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_9).xyz * scale2)\\n   + bias2)).x * tmpvar_3.y);\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4;\\n  tmpvar_10.y = tmpvar_7;\\n  vec2 tmpvar_11;\\n  tmpvar_11.x = (((\\n    (texture (sampler_blur2, tmpvar_5).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_6).xyz * scale2)\\n   + bias2)).x * tmpvar_3.x);\\n  tmpvar_11.y = (((\\n    (texture (sampler_blur2, tmpvar_8).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, tmpvar_9).xyz * scale2)\\n   + bias2)).x * tmpvar_3.y);\\n  ret_2.x = texture (sampler_fw_main, ((uv - (tmpvar_10 * 0.01)) + (tmpvar_11 * 0.003))).x;\\n  vec4 tmpvar_12;\\n  tmpvar_12 = texture (sampler_blur3, uv);\\n  ret_2.x = (ret_2.x + ((ret_2.x - \\n    ((tmpvar_12.xyz * scale3) + bias3)\\n  .x) * 0.1));\\n  ret_2.x = (ret_2.x + 0.004);\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = tmpvar_7;\\n  tmpvar_13.y = -(tmpvar_4);\\n  my_uv_1 = (uv + ((tmpvar_13 * 0.05) * (1.2 - \\n    ((tmpvar_12.xyz * scale3) + bias3)\\n  .y)));\\n  ret_2.z = texture (sampler_fw_main, my_uv_1).z;\\n  vec2 x_14;\\n  x_14 = (my_uv_1 - uv);\\n  ret_2.z = (ret_2.z + ((\\n    ((ret_2.z - ((texture (sampler_blur1, uv).xyz * scale1) + bias1).z) * sqrt(dot (x_14, x_14)))\\n   * 180.0) / sqrt(\\n    dot (tmpvar_3, tmpvar_3)\\n  )));\\n  ret_2.z = (ret_2.z * 0.8);\\n  ret_2.z = (ret_2.z + 0.004);\\n  vec2 tmpvar_15;\\n  tmpvar_15.x = -(tmpvar_7);\\n  tmpvar_15.y = tmpvar_4;\\n  my_uv_1 = (tmpvar_15 * 0.045);\\n  vec2 tmpvar_16;\\n  tmpvar_16.x = (((\\n    (texture (sampler_blur2, (uv + vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (uv - vec2(0.01, 0.0))).xyz * scale2)\\n   + bias2)).y * tmpvar_3.x);\\n  tmpvar_16.y = (((\\n    (texture (sampler_blur2, (uv + vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2) - (\\n    (texture (sampler_blur2, (uv - vec2(0.0, 0.01))).xyz * scale2)\\n   + bias2)).y * tmpvar_3.y);\\n  my_uv_1 = (my_uv_1 + (uv - (tmpvar_16 * 0.03)));\\n  ret_2.y = texture (sampler_fw_main, my_uv_1).y;\\n  ret_2.y = (ret_2.y + ((\\n    (ret_2.y - ((texture (sampler_blur3, my_uv_1).xyz * scale3) + bias3).y)\\n   * 0.1) + 0.01));\\n  vec4 tmpvar_17;\\n  tmpvar_17.w = 1.0;\\n  tmpvar_17.xyz = ret_2;\\n  ret = tmpvar_17.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec3 tmpvar_2;\\n  tmpvar_2 = texture (sampler_main, uv).xyz;\\n  vec2 tmpvar_3;\\n  tmpvar_3.y = 0.0;\\n  tmpvar_3.x = texsize.z;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = 0.0;\\n  tmpvar_4.y = texsize.w;\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (texture (sampler_main, (uv - tmpvar_3)).xyz - texture (sampler_main, (uv + tmpvar_3)).xyz).x;\\n  tmpvar_5.y = (texture (sampler_main, (uv - tmpvar_4)).xyz - texture (sampler_main, (uv + tmpvar_4)).xyz).x;\\n  uv1_1 = ((0.3 * cos(\\n    (((uv - 0.5) * 2.0) + 1.7)\\n  )) - (2.0 * tmpvar_5));\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ((-(tmpvar_2) / 4.0) + ((6.0 * vec3(\\n    clamp ((0.03 / sqrt(dot (uv1_1, uv1_1))), 0.0, 1.0)\\n  )) * (-0.08 + tmpvar_2)));\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:2,decay:.99,wave_brighten:0,wave_a:1,wave_scale:.01,wave_mystery:-.2,warpanimspeed:3.434,warpscale:1.295,zoom:1.025,warp:.11284,wave_r:0,wave_g:0,wave_b:0,ob_size:.005,ob_b:1,ob_a:1,mv_x:64,mv_y:48,mv_l:5,mv_g:0,mv_b:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.d=0;a.cx1=0;a.y3=0;a.y1=0;a.cy1=0;a.q25=0;a.q12=0;a.q18=0;a.x1=0;a.q22=0;a.q21=0;a.vt=0;a.q13=0;a.q15=0;a.q29=0;a.q6=0;a.q1=0;a.q5=0;a.vb=0;a.q9=0;a.x3=0;a.q31=0;a.q23=0;a.q24=0;a.q11=0;a.q10=0;a.q4=0;a.dir=0;a.q16=0;a.q26=0;a.x2=0;a.q19=0;a.q17=0;a.y2=0;a.q2=0;a.q27=0;a.q14=0;a.q3=0;a.vvm=0;a.q32=0;a.vvb=0;a.q7=0;a.q28=0;a.vm=0;a.q30=0;a.q20=0;a.vvt=0;a.q8=0;\",frame_eqs_str:\"a.vb=.95*a.vb+(1-a.vb)*pow(a.bass_att,2)*.02;a.vvb=.95*a.vvb+(1-a.vvb)*a.vb*.01;a.vm=.95*a.vm+(1-a.vm)*pow(a.mid_att,2)*.02;a.vvm=.95*a.vvm+(1-a.vvm)*a.vm*.01;a.vt=.95*a.vt+(1-a.vt)*pow(a.treb_att,2)*.02;a.vvt=.95*a.vvt+(1-a.vvt)*a.vt*.01;a.vvb=Math.min(1,Math.max(0,a.vvb));a.vvm=Math.min(1,Math.max(0,a.vvm));a.vvt=Math.min(1,Math.max(0,a.vvt));a.q1=10*(a.vvb+a.vvm+a.vvt);a.q2=10*(a.vvb+a.vvm+a.vvt);a.q3=10*(a.vvb+a.vvm+a.vvt);a.q4=10*(a.vvb+a.vvm+a.vvt);a.q5=10*(a.vvb+a.vvm+\\na.vvt);a.q6=10*(a.vvb+a.vvm+a.vvt);a.q7=10*(a.vvb+a.vvm+a.vvt);a.q8=10*(a.vvb+a.vvm+a.vvt);a.q9=10*(a.vvb+a.vvm+a.vvt);a.q10=10*(a.vvb+a.vvm+a.vvt);a.q11=10*(a.vvb+a.vvm+a.vvt);a.q12=10*(a.vvb+a.vvm+a.vvt);a.q13=10*(a.vvb+a.vvm+a.vvt);a.q14=10*(a.vvb+a.vvm+a.vvt);a.q15=10*(a.vvb+a.vvm+a.vvt);a.q16=10*(a.vvb+a.vvm+a.vvt);a.q17=10*(a.vvb+a.vvm+a.vvt);a.q18=10*(a.vvb+a.vvm+a.vvt);a.q19=10*(a.vvb+a.vvm+a.vvt);a.q20=10*(a.vvb+a.vvm+a.vvt);a.q21=10*(a.vvb+a.vvm+a.vvt);a.q22=10*(a.vvb+a.vvm+a.vvt);a.q23=\\n10*(a.vvb+a.vvm+a.vvt);a.q24=10*(a.vvb+a.vvm+a.vvt);a.q25=10*(a.vvb+a.vvm+a.vvt);a.q26=10*(a.vvb+a.vvm+a.vvt);a.q27=10*(a.vvb+a.vvm+a.vvt);a.q28=10*(a.vvb+a.vvm+a.vvt);a.q29=10*(a.vvb+a.vvm+a.vvt);a.q30=10*(a.vvb+a.vvm+a.vvt);a.q31=10*(a.vvb+a.vvm+a.vvt);a.q32=10*(a.vvb+a.vvm+a.vvt);a.zoom=.995;a.wave_a=0;a.mv_g=.45+.3*Math.sin(1.33*a.time)+.25*Math.sin(a.treb);a.mv_r=.45+.3*Math.sin(1.13*a.time)+.0825*(a.bass+a.treb+a.mid);a.mv_b=.45+.3*Math.sin(1.23*a.time)+.25*Math.sin(a.bass);a.mv_dx=.1*Math.sin(.1*\\na.time);a.mv_dy=.13*Math.cos(.084*a.time);a.mv_x=64-Math.floor(32*(Math.sin(1.5*a.time)+1));a.mv_y=48-Math.floor(22*(Math.cos(1.5*a.time)+1));a.monitor=a.mv_y;\",pixel_eqs_str:\"a.cx1=.5+.2*Math.sin(.618*a.time);a.cy1=.5+.2*Math.cos(1.618*a.time);a.dir=a.bass;a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.x1=.00001<Math.abs(above(a.d,.3))?0:.05*Math.sin(a.y-a.cy1)*a.dir;a.y1=.00001<Math.abs(above(a.d,.3))?0:.05*-Math.sin(a.x-a.cx1)*a.dir;a.cx1=.5+.3*Math.sin(2.618*a.time);a.cy1=.5+.3*Math.cos(3.14*a.time);a.dir=2*-a.mid;a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.x2=.00001<Math.abs(above(a.d,.2))?0:.05*Math.sin(a.y-a.cy1)*\\na.dir;a.y2=.00001<Math.abs(above(a.d,.2))?0:.05*-Math.sin(a.x-a.cx1)*a.dir;a.cx1=.5+.4*Math.sin(2.618*-a.time);a.cy1=.5+.4*Math.cos(1.14*-a.time);a.dir=3*a.treb;a.d=sqrt((a.x-a.cx1)*(a.x-a.cx1)+(a.y-a.cy1)*(a.y-a.cy1));a.x3=.00001<Math.abs(above(a.d,.1))?0:.05*Math.sin(a.y-a.cy1)*a.dir;a.y3=.00001<Math.abs(above(a.d,.1))?0:.05*-Math.sin(a.x-a.cx1)*a.dir;a.dx=a.dx+a.x1+a.x2+a.x3;a.dy=a.dy+a.y1+a.y2+a.y3;\",warp:\" shader_body { \\n  vec2 tmpvar_1;\\n  tmpvar_1 = mix (uv_orig, uv, vec2(0.3, 0.3));\\n  vec2 tmpvar_2;\\n  tmpvar_2 = (texsize.zw * 3.0);\\n  vec2 tmpvar_3;\\n  tmpvar_3.x = dot (((\\n    (texture (sampler_blur1, (tmpvar_1 + (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (tmpvar_1 - (vec2(1.0, 0.0) * tmpvar_2))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  tmpvar_3.y = dot (((\\n    (texture (sampler_blur1, (tmpvar_1 + (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1)\\n   + bias1) - (\\n    (texture (sampler_blur1, (tmpvar_1 - (vec2(0.0, 1.0) * tmpvar_2))).xyz * scale1)\\n   + bias1)), vec3(0.32, 0.49, 0.29));\\n  vec4 tmpvar_4;\\n  tmpvar_4.w = 1.0;\\n  tmpvar_4.xyz = (texture (sampler_fc_main, (tmpvar_1 + (\\n    (tmpvar_3 * texsize.zw)\\n   * 9.0))) - 0.01).xyz;\\n  ret = tmpvar_4.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv_1;\\n  vec3 ret_2;\\n  uv_1 = (0.5 + ((uv - 0.5) * 0.98));\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (texsize.zw * 4.0);\\n  vec3 tmpvar_4;\\n  tmpvar_4 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(1.0, 0.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((texture (sampler_blur1, \\n    (uv_1 + (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1) - ((texture (sampler_blur1, \\n    (uv_1 - (vec2(0.0, 1.0) * tmpvar_3))\\n  ).xyz * scale1) + bias1));\\n  vec3 tmpvar_6;\\n  tmpvar_6.z = 0.0;\\n  tmpvar_6.x = dot (tmpvar_4, vec3(0.32, 0.49, 0.29));\\n  tmpvar_6.y = dot (tmpvar_5, vec3(0.32, 0.49, 0.29));\\n  vec4 tmpvar_7;\\n  tmpvar_7 = texture (sampler_noisevol_hq, ((vec3(0.05, 0.05, 0.0) * (\\n    ((uv_1.xyy + (tmpvar_6 * 0.5)) * texsize.xyy)\\n   * texsize_noisevol_hq.zww)) + (vec3(0.0, 0.0, 0.2) * time)));\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = dot (tmpvar_4, vec3(0.32, 0.49, 0.29));\\n  tmpvar_8.y = dot (tmpvar_5, vec3(0.32, 0.49, 0.29));\\n  uv_1 = (uv_1 - (tmpvar_8 * 0.04));\\n  ret_2 = (abs((\\n    ((texture (sampler_main, uv_1).xyz + ((texture (sampler_blur1, uv_1).xyz * scale1) + bias1)) - ((texture (sampler_blur2, uv_1).xyz * scale2) + bias2))\\n   - \\n    ((texture (sampler_blur3, uv_1).xyz * scale3) + bias3)\\n  )) * (dot (tmpvar_7, vec4(0.32, 0.49, 0.29, 0.0)) * 3.0));\\n  vec3 tmpvar_9;\\n  tmpvar_9 = pow (ret_2, vec3(0.5, 0.5, 0.5));\\n  ret_2 = tmpvar_9;\\n  vec4 tmpvar_10;\\n  tmpvar_10.w = 1.0;\\n  tmpvar_10.xyz = tmpvar_9;\\n  ret = tmpvar_10.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,echo_zoom:1,wave_mode:1,wave_thick:1,wrap:0,invert:1,wave_scale:.5,wave_smoothing:.45,warpanimspeed:2.217,warpscale:100,zoomexp:100,zoom:1.01,warp:1.25946,wave_r:0,wave_g:0,wave_b:0,ob_r:1,ob_g:1,ob_b:1,ob_a:1,ib_r:1,ib_g:1,ib_b:1,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q1=0;\",frame_eqs_str:\"a.q1=.0003*pow(1.2+1*a.bass+.4*a.bass_att+.1*a.treb+.1*a.treb_att+.1*a.mid+.1*a.mid_att,6);a.monitor=a.q1;a.wave_r+=.5*Math.sin(1.13*a.time);a.wave_g+=.5*Math.sin(1.23*a.time);a.wave_b+=.5*Math.sin(1.33*a.time);a.ob_r+=Math.sin(2.26*a.time);a.ob_g+=Math.sin(2.46*a.time);a.ob_b+=Math.sin(2.66*a.time);\",pixel_eqs_str:\"a.zoom+=.125*Math.sin(a.q1);a.rot+=div(.25*Math.sin(100*a.fps)*a.q1,2);a.zoom-=.05*Math.sin(a.rad);a.rot+=.05*Math.sin(5*a.fps);\",warp:\" shader_body { \\n  vec3 ret_1;\\n  vec2 tmpvar_2;\\n  tmpvar_2 = fract(uv);\\n  vec2 tmpvar_3;\\n  tmpvar_3 = (((uv_orig * texsize.xy) * texsize_noise_lq.zw) + rand_frame.xy);\\n  vec2 tmpvar_4;\\n  tmpvar_4 = (texsize.zw * 12.0);\\n  vec3 tmpvar_5;\\n  tmpvar_5 = (((2.0 * \\n    ((texture (sampler_blur3, (uv_orig + (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale3) + bias3)\\n  ) - (2.0 * \\n    ((texture (sampler_blur3, (uv_orig - (vec2(1.0, 0.0) * tmpvar_4))).xyz * scale3) + bias3)\\n  )) * 0.5);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = (((2.0 * \\n    ((texture (sampler_blur3, (uv_orig + (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale3) + bias3)\\n  ) - (2.0 * \\n    ((texture (sampler_blur3, (uv_orig - (vec2(0.0, 1.0) * tmpvar_4))).xyz * scale3) + bias3)\\n  )) * 0.5);\\n  ret_1.x = ((texture (sampler_fc_main, tmpvar_2).x - (\\n    (((texture (sampler_blur3, tmpvar_2).xyz * scale3) + bias3) - texture (sampler_fc_main, tmpvar_2).xyz)\\n  .x * 0.1)) - 0.035);\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_5.x;\\n  tmpvar_7.y = tmpvar_6.x;\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_5.y;\\n  tmpvar_8.y = tmpvar_6.y;\\n  ret_1.y = (((texture (sampler_fc_main, \\n    (((uv_orig + (\\n      ((texture (sampler_noise_lq, tmpvar_3).xy - 0.5) * texsize.zw)\\n     * 4.0)) - ((tmpvar_7 * texsize.zw) * 4.0)) + ((tmpvar_8 * texsize.zw) * 8.0))\\n  ).y + \\n    ((texture (sampler_noise_lq, tmpvar_3).xyz - 0.5) * 0.1)\\n  ) - 0.012) + (texture (sampler_pc_main, uv_orig).z * 0.2)).x;\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_6.x;\\n  tmpvar_9.y = -(tmpvar_5.x);\\n  vec2 tmpvar_10;\\n  tmpvar_10 = ((uv_orig + (\\n    ((texture (sampler_noise_lq, tmpvar_3).xy - 0.5) * texsize.zw)\\n   * 2.0)) + ((tmpvar_9 * texsize.zw) * 64.0));\\n  ret_1.z = (((\\n    (texture (sampler_fc_main, tmpvar_10).z + ((texture (sampler_fc_main, tmpvar_10).z - (\\n      (texture (sampler_blur2, tmpvar_10).xyz * scale2)\\n     + bias2).z) * 0.2))\\n   + \\n    (texture (sampler_noise_lq, tmpvar_3).xyz * 0.1)\\n  ) - (\\n    (texture (sampler_blur3, uv_orig).xyz * scale3)\\n   + bias3).x) - (clamp (\\n    (1.0 - ((texture (sampler_blur2, uv_orig).xyz * scale2) + bias2).x)\\n  , 0.0, 1.0) * 0.04)).x;\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = ret_1;\\n  ret = tmpvar_11.xyz;\\n }\",comp:\"vec2 xlat_mutabled;\\nvec3 xlat_mutabledx;\\nvec3 xlat_mutabledy;\\n shader_body { \\n  vec3 ret_1;\\n  xlat_mutabled = (texsize.zw * 1.5);\\n  xlat_mutabledx = (texture (sampler_main, (uv_orig + (vec2(1.0, 0.0) * xlat_mutabled))).xyz - texture (sampler_main, (uv_orig - (vec2(1.0, 0.0) * xlat_mutabled))).xyz);\\n  xlat_mutabledy = (texture (sampler_main, (uv_orig + (vec2(0.0, 1.0) * xlat_mutabled))).xyz - texture (sampler_main, (uv_orig - (vec2(0.0, 1.0) * xlat_mutabled))).xyz);\\n  vec2 tmpvar_2;\\n  tmpvar_2.x = xlat_mutabledx.y;\\n  tmpvar_2.y = xlat_mutabledy.y;\\n  vec2 x_3;\\n  x_3 = (tmpvar_2 * 8.0);\\n  ret_1 = (((texture (sampler_main, uv).x * \\n    (1.0 - sqrt(dot (x_3, x_3)))\\n  ) * pow (hue_shader, vec3(6.0, 6.0, 6.0))) * 1.4);\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = xlat_mutabledx.z;\\n  tmpvar_4.y = xlat_mutabledy.z;\\n  vec2 x_5;\\n  x_5 = (tmpvar_4 * 4.0);\\n  vec3 tmpvar_6;\\n  tmpvar_6 = mix (ret_1, vec3(1.0, 1.0, 1.0), vec3(sqrt(dot (x_5, x_5))));\\n  ret_1 = tmpvar_6;\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = tmpvar_6;\\n  ret = tmpvar_7.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1.3,decay:1,echo_zoom:1.75,echo_alpha:.15,echo_orient:3,wave_mode:1,wave_dots:1,darken:1,wave_scale:.5,wave_smoothing:.9,warp:.01,mv_l:5},shapes:[{baseVals:{enabled:1,sides:100,border_a:0},init_eqs_str:\"a.q1=0;\",frame_eqs_str:\"a.r+=Math.sin(.339*a.time);a.g+=Math.sin(.369*a.time);a.b+=Math.sin(.399*a.time);a.r2+=Math.sin(.113*a.time);a.g2+=Math.sin(.123*a.time);a.b2+=Math.sin(.133*a.time);a.rad=div(a.q1,3);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"a.q1=0;\",frame_eqs_str:\"a.q1=.0003*pow(1+1.2*a.bass+.4*a.bass_att+.1*a.treb+.1*a.treb_att+.1*a.mid+.1*a.mid_att,6);a.mv_a=a.q1;a.mv_x+=Math.sin(a.time);a.mv_y+=Math.cos(a.time);a.mv_dx+=1.25*Math.sin(8*a.fps);a.mv_dy+=1.35*Math.sin(8*a.fps);a.mv_r+=Math.sin(.565*a.time);a.mv_g+=Math.sin(.615*a.time);a.mv_b+=Math.sin(.665*a.time);a.wave_r+=.5*Math.sin(1.13*a.time);a.wave_g+=.5*Math.sin(1.23*a.time);a.wave_b+=.5*Math.sin(1.33*a.time);\",pixel_eqs_str:\"a.zoom+=.0125*a.q1;a.rot+=.025*Math.sin(10*a.fps)*a.q1;a.warp=0;\",warp:\" shader_body { \\n  vec2 my_uv_1;\\n  vec3 ret_2;\\n  vec3 tmpvar_3;\\n  tmpvar_3 = ((640.0 * texsize.z) * ((2.0 * \\n    ((texture (sampler_blur2, (uv + vec2(0.01, 0.0))).xyz * scale2) + bias2)\\n  ) - (2.0 * \\n    ((texture (sampler_blur2, (uv - vec2(0.01, 0.0))).xyz * scale2) + bias2)\\n  )));\\n  vec3 tmpvar_4;\\n  tmpvar_4 = ((512.0 * texsize.w) * ((2.0 * \\n    ((texture (sampler_blur2, (uv + vec2(0.0, 0.01))).xyz * scale2) + bias2)\\n  ) - (2.0 * \\n    ((texture (sampler_blur2, (uv - vec2(0.0, 0.01))).xyz * scale2) + bias2)\\n  )));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = tmpvar_3.y;\\n  tmpvar_5.y = tmpvar_4.y;\\n  vec2 tmpvar_6;\\n  tmpvar_6.x = tmpvar_3.x;\\n  tmpvar_6.y = tmpvar_4.x;\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = tmpvar_4.y;\\n  tmpvar_7.y = -(tmpvar_3.y);\\n  vec2 tmpvar_8;\\n  tmpvar_8 = (uv - ((\\n    ((tmpvar_5 * 0.3) + (tmpvar_6 * 0.1))\\n   + \\n    (tmpvar_7 * 0.01)\\n  ) * 0.01));\\n  ret_2.x = texture (sampler_fw_main, (tmpvar_8 - floor(tmpvar_8))).x;\\n  ret_2.x = (ret_2.x + ((\\n    (2.0 * ret_2.x)\\n   - \\n    (2.0 * ((texture (sampler_blur1, tmpvar_8).xyz * scale1) + bias1).x)\\n  ) * 0.25));\\n  vec2 tmpvar_9;\\n  tmpvar_9.x = tmpvar_3.y;\\n  tmpvar_9.y = tmpvar_4.y;\\n  vec2 tmpvar_10;\\n  tmpvar_10.x = tmpvar_4.x;\\n  tmpvar_10.y = -(tmpvar_3.y);\\n  my_uv_1 = ((uv - (tmpvar_9 * 0.01)) + (tmpvar_10 * 0.001));\\n  ret_2.y = texture (sampler_fw_main, (my_uv_1 - floor(my_uv_1))).y;\\n  ret_2.y = (ret_2.y + ((\\n    ((2.0 * ret_2.y) - (2.0 * ((texture (sampler_blur3, my_uv_1).xyz * scale3) + bias3).y))\\n   * 0.025) + 0.01));\\n  vec4 tmpvar_11;\\n  tmpvar_11.w = 1.0;\\n  tmpvar_11.xyz = ret_2;\\n  ret = tmpvar_11.xyz;\\n }\",comp:\"vec2 xlat_mutablefactorA;\\n shader_body { \\n  vec2 uv_1;\\n  vec2 dz_2;\\n  vec3 dy_3;\\n  vec3 dx_4;\\n  vec2 d_5;\\n  vec3 ret_6;\\n  xlat_mutablefactorA = (uv - vec2(0.5, 0.5));\\n  vec2 tmpvar_7;\\n  tmpvar_7.x = -((xlat_mutablefactorA.y * -1024.0));\\n  tmpvar_7.y = (xlat_mutablefactorA.x * -1024.0);\\n  vec2 tmpvar_8;\\n  tmpvar_8.x = tmpvar_7.x;\\n  tmpvar_8.y = -(tmpvar_7.y);\\n  uv_1 = (vec2(-100.0, 100.0) * (tmpvar_8 / (\\n    (tmpvar_7.x * tmpvar_7.x)\\n   + \\n    (tmpvar_7.y * tmpvar_7.y)\\n  )).yx);\\n  uv_1 = (0.5 + ((\\n    (1.0 - abs(((\\n      fract((mix ((0.5 + \\n        (((0.5 + (\\n          (uv - 0.5)\\n         * vec2(1.1, 0.81))) - 0.5) * 2.0)\\n      ), (uv_1 + 0.5), vec2(0.5, 0.5)) * 0.5))\\n     * 2.0) - 1.0)))\\n   - 0.5) * 0.98));\\n  vec2 tmpvar_9;\\n  vec2 tmpvar_10;\\n  tmpvar_10 = (vec2(1.0, 0.0) * texsize.zw);\\n  tmpvar_9.x = (texture (sampler_main, (uv_1 + tmpvar_10)).xyz - texture (sampler_main, (uv_1 - tmpvar_10)).xyz).y;\\n  vec2 tmpvar_11;\\n  tmpvar_11 = (vec2(0.0, 1.0) * texsize.zw);\\n  tmpvar_9.y = (texture (sampler_main, (uv_1 + tmpvar_11)).xyz - texture (sampler_main, (uv_1 - tmpvar_11)).xyz).y;\\n  d_5 = (texsize.zw * 2.0);\\n  dx_4 = (((2.0 * \\n    ((texture (sampler_blur1, (uv_1 + (vec2(1.0, 0.0) * d_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_1 - (vec2(1.0, 0.0) * d_5))).xyz * scale1) + bias1)\\n  )) * 0.5);\\n  dy_3 = (((2.0 * \\n    ((texture (sampler_blur1, (uv_1 + (vec2(0.0, 1.0) * d_5))).xyz * scale1) + bias1)\\n  ) - (2.0 * \\n    ((texture (sampler_blur1, (uv_1 - (vec2(0.0, 1.0) * d_5))).xyz * scale1) + bias1)\\n  )) * 0.5);\\n  vec2 tmpvar_12;\\n  tmpvar_12.x = dx_4.y;\\n  tmpvar_12.y = dy_3.y;\\n  dz_2 = ((tmpvar_9 * 3.0) + tmpvar_12);\\n  ret_6 = (vec3(((\\n    pow ((sqrt(dot (dz_2, dz_2)) * 0.8), 0.7)\\n   + \\n    (((texture (sampler_blur2, uv_1).xyz * scale2) + bias2).y * 0.4)\\n  ) - 0.1)) * vec3(0.3, 0.5, 0.7));\\n  vec2 tmpvar_13;\\n  tmpvar_13.x = dx_4.x;\\n  tmpvar_13.y = dy_3.x;\\n  vec3 tmpvar_14;\\n  tmpvar_14 = mix (mix (ret_6, vec3(0.2, 0.1, 0.0), vec3((texture (sampler_main, \\n    (uv_1 + ((tmpvar_13 * texsize.zw) * 18.0))\\n  ).x * 6.0))), vec3(1.0, 1.0, 1.0), texture (sampler_main, uv_1).zzz);\\n  ret_6 = tmpvar_14;\\n  vec4 tmpvar_15;\\n  tmpvar_15.w = 1.0;\\n  tmpvar_15.xyz = tmpvar_14;\\n  ret = tmpvar_15.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,wave_mode:2,wrap:0,wave_a:.001,wave_scale:5.819,wave_mystery:-.38,wave_r:.5,wave_g:.5,wave_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1,thick:1},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"a.y=a.sample;a.x=.003*(a.value1+a.value2);a.a=.1*(a.value1+a.value2);a.r=.5+.3*Math.sin(10*a.sample+a.time);a.g=.5+.3*Math.cos(10*a.sample-1.334*a.time);a.b=.5+.3*Math.sin(10*a.sample+.998*a.time);\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"\",frame_eqs_str:\"a.warp=0;a.wave_r=a.wave_r+.4*Math.sin(.333*a.time)+.2*a.bass_att;a.wave_g=a.wave_g+.4*Math.sin(.555*a.time)+.2*a.treb_att;a.wave_b=a.wave_b+.4*Math.sin(.444*a.time)+.2*a.mid_att;\",pixel_eqs_str:\"\",pixel_eqs:\"\",warp:\" shader_body { \\n  vec2 muv_1;\\n  vec3 ret_2;\\n  float tmpvar_3;\\n  tmpvar_3 = (2.0 * bass_att);\\n  muv_1.x = (uv.x - ((\\n    ((0.01 * cos((\\n      (uv.x * (5.0 + tmpvar_3))\\n     + time))) + (0.01 * cos((\\n      (uv.y * (5.0 + tmpvar_3))\\n     + time))))\\n   * 0.5) * treb_att));\\n  float tmpvar_4;\\n  tmpvar_4 = (2.0 * mid_att);\\n  muv_1.y = (uv.y + ((\\n    ((0.01 * sin((\\n      (uv.x * (5.0 + tmpvar_4))\\n     + time))) - (0.01 * cos((\\n      (uv.y * (5.0 + tmpvar_4))\\n     + time))))\\n   * 0.5) * bass_att));\\n  vec3 tmpvar_5;\\n  tmpvar_5 = ((texture (sampler_blur2, muv_1).xyz * scale2) + bias2);\\n  vec4 tmpvar_6;\\n  tmpvar_6 = texture (sampler_pw_main, muv_1);\\n  ret_2.x = (tmpvar_6.x + (tmpvar_5.x * (bass_att * 0.05)));\\n  ret_2.y = (tmpvar_6.y + (tmpvar_5.y * (treb_att * 0.05)));\\n  ret_2.z = (tmpvar_6.z + (tmpvar_5.z * (mid_att * 0.05)));\\n  if ((ret_2.x > 0.9)) {\\n    ret_2.x = 0.0;\\n  };\\n  if ((ret_2.y > 0.9)) {\\n    ret_2.y = 0.0;\\n  };\\n  if ((ret_2.z > 0.9)) {\\n    ret_2.z = 0.0;\\n  };\\n  vec4 tmpvar_7;\\n  tmpvar_7.w = 1.0;\\n  tmpvar_7.xyz = ret_2;\\n  ret = tmpvar_7.xyz;\\n }\",comp:\" shader_body { \\n  vec3 ret1_1;\\n  vec2 uv1_2;\\n  vec3 ret_3;\\n  vec4 tmpvar_4;\\n  tmpvar_4 = texture (sampler_main, uv);\\n  ret_3 = (tmpvar_4.xyz * (0.6 + (0.3 * \\n    sin(((uv.x * 10.0) + time))\\n  )));\\n  vec2 tmpvar_5;\\n  tmpvar_5.x = (texture (sampler_main, (uv - vec2(0.001, 0.0))).xyz - texture (sampler_main, (uv + vec2(0.001, 0.0))).xyz).x;\\n  tmpvar_5.y = (texture (sampler_main, (uv - vec2(0.0, 0.001))).xyz - texture (sampler_main, (uv + vec2(0.0, 0.001))).xyz).x;\\n  uv1_2 = ((0.5 * cos(\\n    (((uv - 0.5) * 1.5) + 1.6)\\n  )) - (3.0 * tmpvar_5));\\n  ret1_1 = ((0.3 * dot (tmpvar_4.xyz, vec3(0.32, 0.49, 0.29))) + ((\\n    clamp ((0.01 / sqrt(dot (uv1_2, uv1_2))), 0.0, 1.0)\\n   * \\n    mix (vec3(dot (((texture (sampler_blur2, uv).xyz * scale2) + bias2), vec3(0.32, 0.49, 0.29))), ret_3, pow (ret_3, vec3((0.05 + (mid_att * 0.03)))))\\n  ) * (\\n    (4.0 + bass)\\n   + \\n    (mid + treb_att)\\n  )));\\n  ret_3 = ret1_1;\\n  vec4 tmpvar_6;\\n  tmpvar_6.w = 1.0;\\n  tmpvar_6.xyz = ret1_1;\\n  ret = tmpvar_6.xyz;\\n }\"}},function(a,e){a.exports={baseVals:{rating:3,gammaadj:1,decay:.997,echo_zoom:.997,echo_orient:1,wave_thick:1,wave_brighten:0,darken:1,wave_a:.001,wave_scale:.01,wave_smoothing:.27,wave_mystery:-.38,modwavealphastart:.71,modwavealphaend:1.3,warpscale:1.331,zoom:.99951,warp:.01,ob_size:.5,ob_r:.01,ib_size:.26,ib_r:1,ib_g:1,ib_b:1,mv_x:64,mv_y:48,mv_l:.85,mv_r:.5,mv_g:.5,mv_b:.5,mv_a:0},shapes:[{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],waves:[{baseVals:{enabled:1},init_eqs_str:\"\",frame_eqs_str:\"\",point_eqs_str:\"a.x=.5+.2*a.bass*Math.sin(20*a.sample*a.time*a.treb);a.y=.5+.2*a.bass*Math.cos(20*a.sample*a.time*a.treb);a.r=1+.5*Math.sin(.1*a.sample+10*a.time*a.bass);a.g=1+.5*Math.sin(2*a.sample+50*a.time*a.treb);a.b=1+.5*Math.sin(5*a.sample+20*a.time*a.mid);a.a=a.r;\"},{baseVals:{enabled:0}},{baseVals:{enabled:0}},{baseVals:{enabled:0}}],init_eqs_str:\"\",frame_eqs_str:\"a.warp=0;a.decay=.92;\",pixel_eqs_str:\"a.zoom+=.03*a.bass_att*a.bass_att*a.rad;a.rot+=a.rad*bitand(-2.5,5*Math.cos(a.time))*.01;\",warp:\" shader_body { \\n  vec4 tmpvar_1;\\n  tmpvar_1.w = 1.0;\\n  tmpvar_1.xyz = texture (sampler_main, uv).xyz;\\n  ret = tmpvar_1.xyz;\\n }\",comp:\" shader_body { \\n  vec2 uv1_1;\\n  vec3 ret_2;\\n  vec3 tmpvar_3;\\n  tmpvar_3 = texture (sampler_main, uv).xyz;\\n  vec2 tmpvar_4;\\n  tmpvar_4.x = (texture (sampler_main, (uv - vec2(0.001, 0.0))).xyz - texture (sampler_main, (uv + vec2(0.001, 0.0))).xyz).x;\\n  tmpvar_4.y = (texture (sampler_main, (uv - vec2(0.0, 0.001))).xyz - texture (sampler_main, (uv + vec2(0.0, 0.001))).xyz).x;\\n  uv1_1 = ((0.5 * cos(\\n    (((uv - 0.5) * 1.5) + 1.6)\\n  )) - (3.0 * tmpvar_4));\\n  ret_2 = (0.8 * ((0.3 * \\n    dot (tmpvar_3, vec3(0.32, 0.49, 0.29))\\n  ) + (\\n    (clamp ((0.01 / sqrt(\\n      dot (uv1_1, uv1_1)\\n    )), 0.0, 1.0) * tmpvar_3)\\n   * \\n    ((4.0 + bass) + (mid + treb_att))\\n  )));\\n  ret_2 = (ret_2 * 0.77);\\n  vec4 tmpvar_5;\\n  tmpvar_5.w = 1.0;\\n  tmpvar_5.xyz = ret_2;\\n  ret = tmpvar_5.xyz;\\n }\"}},,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,function(a,e,t){\"use strict\";Object.defineProperty(e,\"__esModule\",{value:!0});var r=_(t(6)),n=_(t(7));function _(a){return a&&a.__esModule?a:{default:a}}var s={};s[\"$$$ Royal - Mashup (197)\"]=t(35),s[\"$$$ Royal - Mashup (220)\"]=t(36),s[\"$$$ Royal - Mashup (431)\"]=t(37),s[\"_Aderrasi - Wanderer in Curved Space - mash0000 - faclempt kibitzing meshuggana schmaltz (Geiss color mix)\"]=t(38),s[\"_Geiss - Artifact 01\"]=t(39),s[\"_Geiss - Desert Rose 2\"]=t(40),s[\"_Geiss - untitled\"]=t(41),s._Mig_049=t(42),s._Mig_085=t(43),s[\"_Rovastar + Geiss - Hurricane Nightmare (Posterize Mix)\"]=t(44),s[\"Aderrasi + Geiss - Airhandler (Kali Mix) - Canvas Mix\"]=t(45),s[\"Aderrasi - Potion of Spirits\"]=t(20),s[\"Aderrasi - Songflower (Moss Posy)\"]=t(21),s[\"Aderrasi - Storm of the Eye (Thunder) - mash0000 - quasi pseudo meta concentrics\"]=t(46),s[\"An AdamFX n Martin Infusion 2 flexi - Why The Sky Looks Diffrent Today - AdamFx n Martin Infusion - Tack Tile Disfunction B\"]=t(47),s[\"cope + martin - mother-of-pearl\"]=t(48),s[\"Cope - The Neverending Explosion of Red Liquid Fire\"]=t(49),s[\"Eo.S. + Phat - cubetrace - v2\"]=t(22),s[\"Eo.S. + Zylot - skylight (Stained Glass Majesty mix)\"]=t(23),s[\"Eo.S. - glowsticks v2 05 and proton lights (+Krash′s beat code) _Phat_remix02b\"]=t(24),s[\"fiShbRaiN + Flexi - witchcraft 2.0\"]=t(50),s[\"flexi + amandio c - organic [random mashup]\"]=t(51),s[\"flexi + amandio c - organic12-3d-2.milk\"]=t(52),s[\"Flexi + amandio c - piercing 05 - Kopie (2) - Kopie\"]=t(53),s[\"flexi + fishbrain - neon mindblob grafitti\"]=t(54),s[\"flexi + geiss - pogo cubes vs. tokamak vs. game of life [stahls jelly 4.5 finish]\"]=t(55),s[\"Flexi + Martin - astral projection\"]=t(56),s[\"Flexi + Martin - cascading decay swing\"]=t(57),s[\"Flexi + stahlregen - jelly showoff parade\"]=t(58),s[\"Flexi - alien fish pond\"]=t(59),s[\"Flexi - area 51\"]=t(60),s[\"flexi - bouncing balls [double mindblob neon mix]\"]=t(61),s[\"Flexi - infused with the spiral\"]=t(62),s[\"Flexi - mindblob [shiny mix]\"]=t(63),s[\"Flexi - mindblob mix\"]=t(64),s[\"flexi - mom, why the sky looks different today\"]=t(65),s[\"flexi - patternton, district of media, capitol of the united abstractions of fractopia\"]=t(66),s[\"Flexi - predator-prey-spirals\"]=t(67),s[\"Flexi - smashing fractals [acid etching mix]\"]=t(68),s[\"flexi - swing out on the spiral\"]=t(69),s[\"Flexi - truly soft piece of software - this is generic texturing (Jelly) \"]=t(70),s[\"flexi - what is the matrix\"]=t(71),s[\"Flexi, fishbrain, Geiss + Martin - tokamak witchery\"]=t(72),s[\"Flexi, martin + geiss - dedicated to the sherwin maxawow\"]=t(73),s[\"Fumbling_Foo & Flexi, Martin, Orb, Unchained - Star Nova v7b\"]=t(74),s[\"Geiss + Flexi + Martin - disconnected\"]=t(75),s[\"Geiss - Cauldron - painterly 2 (saturation remix)\"]=t(76),s[\"Geiss - Reaction Diffusion 2\"]=t(77),s[\"Geiss - Spiral Artifact\"]=t(78),s[\"Geiss - Thumb Drum\"]=t(79),s[\"Geiss, Flexi + Stahlregen - Thumbdrum Tokamak [crossfiring aftermath jelly mashup]\"]=t(80),s[\"Goody - The Wild Vort\"]=t(81),s[\"high-altitude basket unraveling - singh grooves nitrogen argon nz+\"]=t(82),s[\"Idiot - Star Of Annon\"]=t(25),s[\"Krash + Illusion - Spiral Movement\"]=t(26),s[\"martin + flexi - diamond cutter [prismaticvortex.com] - camille - i wish i wish i wish i was constrained\"]=t(83),s[\"Martin - acid wiring\"]=t(84),s[\"martin - angel flight\"]=t(85),s[\"martin - another kind of groove\"]=t(86),s[\"martin - bombyx mori\"]=t(87),s[\"martin - castle in the air\"]=t(88),s[\"martin - chain breaker\"]=t(89),s[\"Martin - charisma\"]=t(90),s[\"martin - disco mix 4\"]=t(91),s[\"martin - extreme heat\"]=t(92),s[\"martin - frosty caves 2\"]=t(93),s[\"martin - fruit machine\"]=t(94),s[\"martin - ghost city\"]=t(95),s[\"martin - glass corridor\"]=t(96),s[\"martin - infinity (2010 update)\"]=t(27),s[\"Martin - liquid arrows\"]=t(97),s[\"martin - mandelbox explorer - high speed demo version\"]=t(98),s[\"martin - mucus cervix\"]=t(99),s[\"Martin - QBikal - Surface Turbulence IIb\"]=t(100),s[\"martin - reflections on black tiles\"]=t(101),s[\"martin - stormy sea (2010 update)\"]=t(102),s[\"martin - The Bridge of Khazad-Dum\"]=t(103),s[\"martin - witchcraft reloaded\"]=t(104),s[\"martin [shadow harlequins shape code] - fata morgana\"]=t(105),s[\"martin, flexi, fishbrain + sto - enterstate [random mashup]\"]=t(106),s[\"Milk Artist At our Best - FED - SlowFast Ft AdamFX n Martin - HD CosmoFX\"]=t(107),s[\"ORB - Waaa\"]=t(108),s[\"Phat+fiShbRaiN+Eo.S_Mandala_Chasers_remix\"]=t(28),s[\"Rovastar + Loadus + Geiss - FractalDrop (Triple Mix)\"]=t(109),s[\"Rovastar - Oozing Resistance\"]=t(29),s[\"sawtooth grin roam\"]=t(110),s[\"shifter - dark tides bdrv mix 2\"]=t(111),s[\"suksma - heretical crosscut playpen\"]=t(112),s[\"suksma - Rovastar - Sunflower Passion (Enlightment Mix)_Phat_edit + flexi und martin shaders - circumflex in character classes in regular expression\"]=t(113),s[\"suksma - uninitialized variabowl (hydroponic chronic)\"]=t(114),s[\"suksma - vector exp 1 - couldn′t not\"]=t(115),s[\"TonyMilkdrop - Leonardo Da Vinci's Balloon [Flexi - merry-go-round + techstyle]\"]=t(116),s[\"TonyMilkdrop - Magellan's Nebula [Flexi - you enter first + multiverse]\"]=t(117),s[\"Unchained & Rovastar - Wormhole Pillars (Hall of Shadows mix)\"]=t(30),s[\"Unchained - Rewop\"]=t(31),s[\"Unchained - Unified Drag 2\"]=t(32),s[\"yin - 191 - Temporal singularities\"]=t(33),s[\"Zylot - Paint Spill (Music Reactive Paint Mix)\"]=t(118),s[\"Zylot - Star Ornament\"]=t(34),s[\"Zylot - True Visionary (Final Mix)\"]=t(119);var v=function(){function a(){(0,r.default)(this,a)}return(0,n.default)(a,null,[{key:\"getPresets\",value:function(){return s}}]),a}();e.default=v,a.exports=v}])});","vendor/shaders/LICENSE":"MIT License\n\nCopyright (c) 2026 Shader Effects Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","vendor/shaders/runtime.mjs":"var Kd=class extends Error{reason;constructor(e,t,s){super(t??`[gpu] WebGPU unavailable (${e})`),this.name=\"GpuUnavailableError\",this.reason=e,s?.cause!==void 0&&(this.cause=s.cause)}};function Cy(e){return!!e&&typeof e==\"object\"&&e.name===\"GpuUnavailableError\"&&typeof e.reason==\"string\"}var D5=null;function Cf(){if(D5!==null)return D5;let e=globalThis.__SHADERS_DEBUG__;if(e!=null)return!!e;try{if(typeof localStorage<\"u\"&&localStorage.getItem(\"shaders:debug\")===\"1\")return!0}catch{}return!1}var L5=!1;function U5(){L5=!0}function Mf(...e){(Cf()||L5)&&console.error(...e)}function di(...e){Cf()&&console.warn(...e)}function Sr(...e){Cf()&&console.error(...e)}function O5(){return typeof navigator<\"u\"&&!!navigator.gpu}var Pf=null;function G5(){return Pf||(Pf=(async()=>{if(!O5())return{supported:!1,reason:\"unsupported\"};try{return await navigator.gpu.requestAdapter({powerPreference:\"high-performance\"})?{supported:!0}:{supported:!1,reason:\"no-adapter\"}}catch(e){return Sr(\"[gpu] adapter probe threw:\",e),{supported:!1,reason:\"no-adapter\"}}})(),Pf)}var $W=new Set([\"unsupported\",\"no-adapter\",\"no-device\",\"out-of-memory\",\"gpu-error\"]),Py=null;function F5(e){Py||!$W.has(e)||(Py=e)}function I5(){return Py}function Gr(e,t){let s=e.length;Array.isArray(e[0])||(e=[e]),Array.isArray(t[0])||(t=t.map(i=>[i]));let r=t[0].length,o=t[0].map((i,l)=>t.map(c=>c[l])),a=e.map(i=>o.map(l=>{let c=0;if(!Array.isArray(i)){for(let d of l)c+=i*d;return c}for(let d=0;d<i.length;d++)c+=i[d]*(l[d]||0);return c}));return s===1&&(a=a[0]),r===1?a.map(i=>i[0]):a}function Zp(e){return Dl(e)===\"string\"}function Dl(e){return(Object.prototype.toString.call(e).match(/^\\[object\\s+(.*?)\\]$/)[1]||\"\").toLowerCase()}function Gf(e,{precision:t,unit:s}){return Ll(e)?\"none\":G6(e,t)+(s??\"\")}function Ll(e){return Number.isNaN(e)||e instanceof Number&&e?.none}function uo(e){return Ll(e)?0:e}function G6(e,t){if(e===0)return 0;let s=~~e,r=0;s&&t&&(r=~~Math.log10(Math.abs(s))+1);let o=10**(t-r);return Math.floor(e*o+.5)/o}var XW={deg:1,grad:.9,rad:180/Math.PI,turn:360};function F6(e){if(!e)return;e=e.trim();let t=/^([a-z]+)\\((.+?)\\)$/i,s=/^-?[\\d.]+$/,r=/%|deg|g?rad|turn$/,o=/\\/?\\s*(none|[-\\w.]+(?:%|deg|g?rad|turn)?)/g,a=e.match(t);if(a){let i=[];return a[2].replace(o,(l,c)=>{let d=c.match(r),u=c;if(d){let p=d[0],_=u.slice(0,-p.length);p===\"%\"?(u=new Number(_/100),u.type=\"<percentage>\"):(u=new Number(_*XW[p]),u.type=\"<angle>\",u.unit=p)}else s.test(u)?(u=new Number(u),u.type=\"<number>\"):u===\"none\"&&(u=new Number(NaN),u.none=!0);l.startsWith(\"/\")&&(u=u instanceof Number?u:new Number(u),u.alpha=!0),typeof u==\"object\"&&u instanceof Number&&(u.raw=c),i.push(u)}),{name:a[1].toLowerCase(),rawName:a[1],rawArgs:a[2],args:i}}}function I6(e){return e[e.length-1]}function jp(e,t,s){return isNaN(e)?t:isNaN(t)?e:e+(t-e)*s}function Y6(e,t,s){return(s-e)/(t-e)}function $y(e,t,s){return jp(t[0],t[1],Y6(e[0],e[1],s))}function W6(e){return e.map(t=>t.split(\"|\").map(s=>{s=s.trim();let r=s.match(/^(<[a-z]+>)\\[(-?[.\\d]+),\\s*(-?[.\\d]+)\\]?$/);if(r){let o=new String(r[1]);return o.range=[+r[2],+r[3]],o}return s}))}function q6(e,t,s){return Math.max(Math.min(s,t),e)}function Wf(e,t){return Math.sign(e)===Math.sign(t)?e:-e}function ui(e,t){return Wf(Math.abs(e)**t,e)}function Xy(e,t){return t===0?0:e/t}function V6(e,t,s=0,r=e.length){for(;s<r;){let o=s+r>>1;e[o]<t?s=o+1:r=o}return s}var HW=Object.freeze({__proto__:null,bisectLeft:V6,clamp:q6,copySign:Wf,interpolate:jp,interpolateInv:Y6,isNone:Ll,isString:Zp,last:I6,mapRange:$y,multiplyMatrices:Gr,parseCoordGrammar:W6,parseFunction:F6,serializeNumber:Gf,skipNone:uo,spow:ui,toPrecision:G6,type:Dl,zdiv:Xy}),jW=class{add(e,t,s){if(typeof arguments[0]!=\"string\"){for(var e in arguments[0])this.add(e,arguments[0][e],arguments[1]);return}(Array.isArray(e)?e:[e]).forEach(function(r){this[r]=this[r]||[],t&&this[r][s?\"unshift\":\"push\"](t)},this)}run(e,t){this[e]=this[e]||[],this[e].forEach(function(s){s.call(t&&t.context?t.context:t,t)})}},Ul=new jW,on={gamut_mapping:\"css\",precision:5,deltaE:\"76\",verbose:globalThis?.process?.env?.NODE_ENV?.toLowerCase()!==\"test\",warn:function(t){this.verbose&&globalThis?.console?.warn?.(t)}},fa={D50:[.3457/.3585,1,.2958/.3585],D65:[.3127/.329,1,.3583/.329]};function Gy(e){return Array.isArray(e)?e:fa[e]}function Ff(e,t,s,r={}){if(e=Gy(e),t=Gy(t),!e||!t)throw new TypeError(`Missing white point to convert ${e?\"\":\"from\"}${!e&&!t?\"/\":\"\"}${t?\"\":\"to\"}`);if(e===t)return s;let o={W1:e,W2:t,XYZ:s,options:r};if(Ul.run(\"chromatic-adaptation-start\",o),o.M||(o.W1===fa.D65&&o.W2===fa.D50?o.M=[[1.0479297925449969,.022946870601609652,-.05019226628920524],[.02962780877005599,.9904344267538799,-.017073799063418826],[-.009243040646204504,.015055191490298152,.7518742814281371]]:o.W1===fa.D50&&o.W2===fa.D65&&(o.M=[[.955473421488075,-.02309845494876471,.06325924320057072],[-.0283697093338637,1.0099953980813041,.021041441191917323],[.012314014864481998,-.020507649298898964,1.330365926242124]])),Ul.run(\"chromatic-adaptation-end\",o),o.M)return Gr(o.M,o.XYZ);throw new TypeError(\"Only Bradford CAT with white points D50 and D65 supported for now.\")}var KW=new Set([\"<number>\",\"<percentage>\",\"<angle>\"]);function Y5(e,t,s,r){return Object.entries(e.coords).map(([o,a],i)=>{let l=t.coordGrammar[i],c=r[i],d=c?.type,u;if(c.none?u=l.find(f=>KW.has(f)):u=l.find(f=>f==d),!u){let f=a.name||o;throw new TypeError(`${d??c.raw} not allowed for ${f} in ${s}()`)}let p=u.range;d===\"<percentage>\"&&(p||=[0,1]);let _=a.range||a.refRange;return p&&_&&(r[i]=$y(p,_,r[i])),u})}function N6(e,{meta:t}={}){let s={str:String(e)?.trim()};if(Ul.run(\"parse-start\",s),s.color)return s.color;if(s.parsed=F6(s.str),s.parsed){let r=s.parsed.name;if(r===\"color\"){let o=s.parsed.args.shift(),a=o.startsWith(\"--\")?o.substring(2):`--${o}`,i=[o,a],l=s.parsed.rawArgs.indexOf(\"/\")>0?s.parsed.args.pop():1;for(let u of Ht.all){let p=u.getFormat(\"color\");if(p&&(i.includes(p.id)||p.ids?.filter(_=>i.includes(_)).length)){let _=Object.keys(u.coords).map((h,g)=>s.parsed.args[g]||0),f;return p.coordGrammar&&(f=Y5(u,p,\"color\",_)),t&&Object.assign(t,{formatId:\"color\",types:f}),p.id.startsWith(\"--\")&&!o.startsWith(\"--\")&&on.warn(`${u.name} is a non-standard space and not currently supported in the CSS spec. Use prefixed color(${p.id}) instead of color(${o}).`),o.startsWith(\"--\")&&!p.id.startsWith(\"--\")&&on.warn(`${u.name} is a standard space and supported in the CSS spec. Use color(${p.id}) instead of prefixed color(${o}).`),{spaceId:u.id,coords:_,alpha:l}}}let c=\"\",d=o in Ht.registry?o:a;if(d in Ht.registry){let u=Ht.registry[d].formats?.color?.id;u&&(c=`Did you mean color(${u})?`)}throw new TypeError(`Cannot parse color(${o}). `+(c||\"Missing a plugin?\"))}else for(let o of Ht.all){let a=o.getFormat(r);if(a&&a.type===\"function\"){let i=1;(a.lastAlpha||I6(s.parsed.args).alpha)&&(i=s.parsed.args.pop());let l=s.parsed.args,c;return a.coordGrammar&&(c=Y5(o,a,r,l)),t&&Object.assign(t,{formatId:a.name,types:c}),{spaceId:o.id,coords:l,alpha:i}}}}else for(let r of Ht.all)for(let o in r.formats){let a=r.formats[o];if(a.type!==\"custom\"||a.test&&!a.test(s.str))continue;let i=a.parse(s.str);if(i)return i.alpha??=1,t&&(t.formatId=o),i}throw new TypeError(`Could not parse ${e} as a color. Missing a plugin?`)}function xs(e){if(Array.isArray(e))return e.map(xs);if(!e)throw new TypeError(\"Empty color reference\");Zp(e)&&(e=N6(e));let t=e.space||e.spaceId;return t instanceof Ht||(e.space=Ht.get(t)),e.alpha===void 0&&(e.alpha=1),e}var QW=75e-6,Ht=class $n{constructor(t){this.id=t.id,this.name=t.name,this.base=t.base?$n.get(t.base):null,this.aliases=t.aliases,this.base&&(this.fromBase=t.fromBase,this.toBase=t.toBase);let s=t.coords??this.base.coords;for(let r in s)\"name\"in s[r]||(s[r].name=r);this.coords=s,this.white=Gy(t.white??this.base.white??\"D65\"),this.formats=t.formats??{};for(let r in this.formats){let o=this.formats[r];o.type||=\"function\",o.name||=r}this.formats.color?.id||(this.formats.color={...this.formats.color??{},id:t.cssId||this.id}),t.gamutSpace?this.gamutSpace=t.gamutSpace===\"self\"?this:$n.get(t.gamutSpace):this.isPolar?this.gamutSpace=this.base:this.gamutSpace=this,this.gamutSpace.isUnbounded&&(this.inGamut=(r,o)=>!0),this.referred=t.referred,Object.defineProperty(this,\"path\",{value:ZW(this).reverse(),writable:!1,enumerable:!0,configurable:!0}),Ul.run(\"colorspace-init-end\",this)}inGamut(t,{epsilon:s=QW}={}){if(!this.equals(this.gamutSpace))return t=this.to(this.gamutSpace,t),this.gamutSpace.inGamut(t,{epsilon:s});let r=Object.values(this.coords);return t.every((o,a)=>{let i=r[a];if(i.type!==\"angle\"&&i.range){if(Number.isNaN(o))return!0;let[l,c]=i.range;return(l===void 0||o>=l-s)&&(c===void 0||o<=c+s)}return!0})}get isUnbounded(){return Object.values(this.coords).every(t=>!(\"range\"in t))}get cssId(){return this.formats?.color?.id||this.id}get isPolar(){for(let t in this.coords)if(this.coords[t].type===\"angle\")return!0;return!1}getFormat(t){if(typeof t==\"object\")return t=W5(t,this),t;let s;return t===\"default\"?s=Object.values(this.formats)[0]:s=this.formats[t],s?(s=W5(s,this),s):null}equals(t){return t?this===t||this.id===t||this.id===t.id:!1}to(t,s){if(arguments.length===1){let l=xs(t);[t,s]=[l.space,l.coords]}if(t=$n.get(t),this.equals(t))return s;s=s.map(l=>Number.isNaN(l)?0:l);let r=this.path,o=t.path,a,i;for(let l=0;l<r.length&&r[l].equals(o[l]);l++)a=r[l],i=l;if(!a)throw new Error(`Cannot convert between color spaces ${this} and ${t}: no connection space was found`);for(let l=r.length-1;l>i;l--)s=r[l].toBase(s);for(let l=i+1;l<o.length;l++)s=o[l].fromBase(s);return s}from(t,s){if(arguments.length===1){let r=xs(t);[t,s]=[r.space,r.coords]}return t=$n.get(t),t.to(this,s)}toString(){return`${this.name} (${this.id})`}getMinCoords(){let t=[];for(let s in this.coords){let r=this.coords[s],o=r.range||r.refRange;t.push(o?.min??0)}return t}static registry={};static get all(){return[...new Set(Object.values($n.registry))]}static register(t,s){if(arguments.length===1&&(s=arguments[0],t=s.id),s=this.get(s),this.registry[t]&&this.registry[t]!==s)throw new Error(`Duplicate color space registration: '${t}'`);if(this.registry[t]=s,arguments.length===1&&s.aliases)for(let r of s.aliases)this.register(r,s);return s}static get(t,...s){if(!t||t instanceof $n)return t;if(Dl(t)===\"string\"){let r=$n.registry[t.toLowerCase()];if(!r)throw new TypeError(`No color space found with id = \"${t}\"`);return r}if(s.length)return $n.get(...s);throw new TypeError(`${t} is not a valid color space`)}static resolveCoord(t,s){let r=Dl(t),o,a;if(r===\"string\"?t.includes(\".\")?[o,a]=t.split(\".\"):[o,a]=[,t]:Array.isArray(t)?[o,a]=t:(o=t.space,a=t.coordId),o=$n.get(o),o||(o=s),!o)throw new TypeError(`Cannot resolve coordinate reference ${t}: No color space specified and relative references are not allowed here`);if(r=Dl(a),r===\"number\"||r===\"string\"&&a>=0){let c=Object.entries(o.coords)[a];if(c)return{space:o,id:c[0],index:a,...c[1]}}o=$n.get(o);let i=a.toLowerCase(),l=0;for(let c in o.coords){let d=o.coords[c];if(c.toLowerCase()===i||d.name?.toLowerCase()===i)return{space:o,id:c,index:l,...d};l++}throw new TypeError(`No \"${a}\" coordinate found in ${o.name}. Its coordinates are: ${Object.keys(o.coords).join(\", \")}`)}static DEFAULT_FORMAT={type:\"functions\",name:\"color\"}};function ZW(e){let t=[e];for(let s=e;s=s.base;)t.push(s);return t}function W5(e,{coords:t}={}){if(e.coords&&!e.coordGrammar){e.type||=\"function\",e.name||=\"color\",e.coordGrammar=W6(e.coords);let s=Object.entries(t).map(([r,o],a)=>{let i=e.coordGrammar[a][0],l=o.range||o.refRange,c=i.range,d=\"\";return i==\"<percentage>\"?(c=[0,100],d=\"%\"):i==\"<angle>\"&&(d=\"deg\"),{fromRange:l,toRange:c,suffix:d}});e.serializeCoords=(r,o)=>r.map((a,i)=>{let{fromRange:l,toRange:c,suffix:d}=s[i];return l&&c&&(a=$y(l,c,a)),a=Gf(a,{precision:o,unit:d}),a})}return e}var Ho=new Ht({id:\"xyz-d65\",name:\"XYZ D65\",coords:{x:{name:\"X\"},y:{name:\"Y\"},z:{name:\"Z\"}},white:\"D65\",formats:{color:{ids:[\"xyz-d65\",\"xyz\"]}},aliases:[\"xyz\"]}),Oa=class extends Ht{constructor(e){e.coords||(e.coords={r:{range:[0,1],name:\"Red\"},g:{range:[0,1],name:\"Green\"},b:{range:[0,1],name:\"Blue\"}}),e.base||(e.base=Ho),e.toXYZ_M&&e.fromXYZ_M&&(e.toBase??=t=>{let s=Gr(e.toXYZ_M,t);return this.white!==this.base.white&&(s=Ff(this.white,this.base.white,s)),s},e.fromBase??=t=>(t=Ff(this.base.white,this.white,t),Gr(e.fromXYZ_M,t))),e.referred??=\"display\",super(e)}};function Jp(e,t){return e=xs(e),!t||e.space.equals(t)?e.coords.slice():(t=Ht.get(t),t.from(e))}function sn(e,t){e=xs(e);let{space:s,index:r}=Ht.resolveCoord(t,e.space);return Jp(e,s)[r]}function Hy(e,t,s){return e=xs(e),t=Ht.get(t),e.coords=t.to(e.space,s),e}Hy.returns=\"color\";function Ni(e,t,s){if(e=xs(e),arguments.length===2&&Dl(arguments[1])===\"object\"){let r=arguments[1];for(let o in r)Ni(e,o,r[o])}else{typeof s==\"function\"&&(s=s(sn(e,t)));let{space:r,index:o}=Ht.resolveCoord(t,e.space),a=Jp(e,r);a[o]=s,Hy(e,r,a)}return e}Ni.returns=\"color\";var jy=new Ht({id:\"xyz-d50\",name:\"XYZ D50\",white:\"D50\",base:Ho,fromBase:e=>Ff(Ho.white,\"D50\",e),toBase:e=>Ff(\"D50\",Ho.white,e)}),JW=216/24389,q5=24/116,Ef=24389/27,My=fa.D50,rn=new Ht({id:\"lab\",name:\"Lab\",coords:{l:{refRange:[0,100],name:\"Lightness\"},a:{refRange:[-125,125]},b:{refRange:[-125,125]}},white:My,base:jy,fromBase(e){let t=e.map((s,r)=>s/My[r]).map(s=>s>JW?Math.cbrt(s):(Ef*s+16)/116);return[116*t[1]-16,500*(t[0]-t[1]),200*(t[1]-t[2])]},toBase(e){let t=[];return t[1]=(e[0]+16)/116,t[0]=e[1]/500+t[1],t[2]=t[1]-e[2]/200,[t[0]>q5?Math.pow(t[0],3):(116*t[0]-16)/Ef,e[0]>8?Math.pow((e[0]+16)/116,3):e[0]/Ef,t[2]>q5?Math.pow(t[2],3):(116*t[2]-16)/Ef].map((s,r)=>s*My[r])},formats:{lab:{coords:[\"<number> | <percentage>\",\"<number> | <percentage>[-1,1]\",\"<number> | <percentage>[-1,1]\"]}}});function pi(e){return(e%360+360)%360}function eq(e,t){if(e===\"raw\")return t;let[s,r]=t.map(pi),o=r-s;return e===\"increasing\"?o<0&&(r+=360):e===\"decreasing\"?o>0&&(s+=360):e===\"longer\"?-180<o&&o<180&&(o>0?s+=360:r+=360):e===\"shorter\"&&(o>180?s+=360:o<-180&&(r+=360)),[s,r]}var Kp=new Ht({id:\"lch\",name:\"LCH\",coords:{l:{refRange:[0,100],name:\"Lightness\"},c:{refRange:[0,150],name:\"Chroma\"},h:{refRange:[0,360],type:\"angle\",name:\"Hue\"}},base:rn,fromBase(e){let[t,s,r]=e,o,a=.02;return Math.abs(s)<a&&Math.abs(r)<a?o=NaN:o=Math.atan2(r,s)*180/Math.PI,[t,Math.sqrt(s**2+r**2),pi(o)]},toBase(e){let[t,s,r]=e;return s<0&&(s=0),isNaN(r)&&(r=0),[t,s*Math.cos(r*Math.PI/180),s*Math.sin(r*Math.PI/180)]},formats:{lch:{coords:[\"<number> | <percentage>\",\"<number> | <percentage>\",\"<number> | <angle>\"]}}}),V5=25**7,If=Math.PI,N5=180/If,Qd=If/180;function $5(e){let t=e*e;return t*t*t*e}function $6(e,t,{kL:s=1,kC:r=1,kH:o=1}={}){[e,t]=xs([e,t]);let[a,i,l]=rn.from(e),c=Kp.from(rn,[a,i,l])[1],[d,u,p]=rn.from(t),_=Kp.from(rn,[d,u,p])[1];c<0&&(c=0),_<0&&(_=0);let f=$5((c+_)/2),h=.5*(1-Math.sqrt(f/(f+V5))),g=(1+h)*i,y=(1+h)*u,b=Math.sqrt(g**2+l**2),x=Math.sqrt(y**2+p**2),P=g===0&&l===0?0:Math.atan2(l,g),C=y===0&&p===0?0:Math.atan2(p,y);P<0&&(P+=2*If),C<0&&(C+=2*If),P*=N5,C*=N5;let E=d-a,R=x-b,U=C-P,L=P+C,k=Math.abs(U),D;b*x===0?D=0:k<=180?D=U:U>180?D=U-360:U<-180?D=U+360:on.warn(\"the unthinkable has happened\");let O=2*Math.sqrt(x*b)*Math.sin(D*Qd/2),F=(a+d)/2,q=(b+x)/2,Y=$5(q),V;b*x===0?V=L:k<=180?V=L/2:L<360?V=(L+360)/2:V=(L-360)/2;let X=(F-50)**2,Q=1+.015*X/Math.sqrt(20+X),te=1+.045*q,J=1;J-=.17*Math.cos((V-30)*Qd),J+=.24*Math.cos(2*V*Qd),J+=.32*Math.cos((3*V+6)*Qd),J-=.2*Math.cos((4*V-63)*Qd);let oe=1+.015*q*J,le=30*Math.exp(-1*((V-275)/25)**2),se=2*Math.sqrt(Y/(Y+V5)),Te=-1*Math.sin(2*le*Qd)*se,de=(E/(s*Q))**2;return de+=(R/(r*te))**2,de+=(O/(o*oe))**2,de+=Te*(R/(r*te))*(O/(o*oe)),Math.sqrt(de)}var tq=[[.819022437996703,.3619062600528904,-.1288737815209879],[.0329836539323885,.9292868615863434,.0361446663506424],[.0481771893596242,.2642395317527308,.6335478284694309]],sq=[[1.2268798758459243,-.5578149944602171,.2813910456659647],[-.0405757452148008,1.112286803280317,-.0717110580655164],[-.0763729366746601,-.4214933324022432,1.5869240198367816]],rq=[[.210454268309314,.7936177747023054,-.0040720430116193],[1.9779985324311684,-2.42859224204858,.450593709617411],[.0259040424655478,.7827717124575296,-.8086757549230774]],oq=[[1,.3963377773761749,.2158037573099136],[1,-.1055613458156586,-.0638541728258133],[1,-.0894841775298119,-1.2914855480194092]],tu=new Ht({id:\"oklab\",name:\"Oklab\",coords:{l:{refRange:[0,1],name:\"Lightness\"},a:{refRange:[-.4,.4]},b:{refRange:[-.4,.4]}},white:\"D65\",base:Ho,fromBase(e){return Gr(rq,Gr(tq,e).map(t=>Math.cbrt(t)))},toBase(e){return Gr(sq,Gr(oq,e).map(t=>t**3))},formats:{oklab:{coords:[\"<percentage> | <number>\",\"<number> | <percentage>[-1,1]\",\"<number> | <percentage>[-1,1]\"]}}});function Fy(e,t){[e,t]=xs([e,t]);let[s,r,o]=tu.from(e),[a,i,l]=tu.from(t),c=s-a,d=r-i,u=o-l;return Math.sqrt(c**2+d**2+u**2)}var aq=75e-6;function Wc(e,t,{epsilon:s=aq}={}){e=xs(e),t||(t=e.space),t=Ht.get(t);let r=e.coords;return t!==e.space&&(r=t.from(e)),t.inGamut(r,{epsilon:s})}function su(e){return{space:e.space,coords:e.coords.slice(),alpha:e.alpha}}function X6(e,t,s=\"lab\"){s=Ht.get(s);let r=s.from(e),o=s.from(t);return Math.sqrt(r.reduce((a,i,l)=>{let c=o[l];return isNaN(i)||isNaN(c)?a:a+(c-i)**2},0))}function nq(e,t){return X6(e,t,\"lab\")}var X5=Math.PI/180;function iq(e,t,{l:s=2,c:r=1}={}){[e,t]=xs([e,t]);let[o,a,i]=rn.from(e),[,l,c]=Kp.from(rn,[o,a,i]),[d,u,p]=rn.from(t),_=Kp.from(rn,[d,u,p])[1];l<0&&(l=0),_<0&&(_=0);let f=o-d,h=l-_,g=a-u,y=i-p,b=g**2+y**2-h**2,x=.511;o>=16&&(x=.040975*o/(1+.01765*o));let P=.0638*l/(1+.0131*l)+.638,C;Number.isNaN(c)&&(c=0),c>=164&&c<=345?C=.56+Math.abs(.2*Math.cos((c+168)*X5)):C=.36+Math.abs(.4*Math.cos((c+35)*X5));let E=Math.pow(l,4),R=Math.sqrt(E/(E+1900)),U=P*(R*C+1-R),L=(f/(s*x))**2;return L+=(h/(r*P))**2,L+=b/U**2,Math.sqrt(L)}var H5=203,Ky=new Ht({id:\"xyz-abs-d65\",cssId:\"--xyz-abs-d65\",name:\"Absolute XYZ D65\",coords:{x:{refRange:[0,9504.7],name:\"Xa\"},y:{refRange:[0,1e4],name:\"Ya\"},z:{refRange:[0,10888.3],name:\"Za\"}},base:Ho,fromBase(e){return e.map(t=>Math.max(t*H5,0))},toBase(e){return e.map(t=>Math.max(t/H5,0))}}),kf=1.15,Bf=.66,j5=2610/2**14,lq=2**14/2610,K5=3424/2**12,Q5=2413/2**7,Z5=2392/2**7,cq=1.7*2523/2**5,J5=2**5/(1.7*2523),zf=-.56,Ey=16295499532821565e-27,dq=[[.41478972,.579999,.014648],[-.20151,1.120649,.0531008],[-.0166008,.2648,.6684799]],uq=[[1.9242264357876067,-1.0047923125953657,.037651404030618],[.35031676209499907,.7264811939316552,-.06538442294808501],[-.09098281098284752,-.3127282905230739,1.5227665613052603]],pq=[[.5,.5,0],[3.524,-4.066708,.542708],[.199076,1.096799,-1.295875]],mq=[[1,.1386050432715393,.05804731615611886],[.9999999999999999,-.1386050432715393,-.05804731615611886],[.9999999999999998,-.09601924202631895,-.8118918960560388]],H6=new Ht({id:\"jzazbz\",name:\"Jzazbz\",coords:{jz:{refRange:[0,1],name:\"Jz\"},az:{refRange:[-.5,.5]},bz:{refRange:[-.5,.5]}},base:Ky,fromBase(e){let[t,s,r]=e,[o,a,i]=Gr(pq,Gr(dq,[kf*t-(kf-1)*r,Bf*s-(Bf-1)*t,r]).map(function(l){return((K5+Q5*(l/1e4)**j5)/(1+Z5*(l/1e4)**j5))**cq}));return[(1+zf)*o/(1+zf*o)-Ey,a,i]},toBase(e){let[t,s,r]=e,[o,a,i]=Gr(uq,Gr(mq,[(t+Ey)/(1+zf-zf*(t+Ey)),s,r]).map(function(c){return 1e4*((K5-c**J5)/(Z5*c**J5-Q5))**lq})),l=(o+(kf-1)*i)/kf;return[l,(a+(Bf-1)*l)/Bf,i]},formats:{color:{coords:[\"<number> | <percentage>\",\"<number> | <percentage>[-1,1]\",\"<number> | <percentage>[-1,1]\"]}}}),Iy=new Ht({id:\"jzczhz\",name:\"JzCzHz\",coords:{jz:{refRange:[0,1],name:\"Jz\"},cz:{refRange:[0,1],name:\"Chroma\"},hz:{refRange:[0,360],type:\"angle\",name:\"Hue\"}},base:H6,fromBase(e){let[t,s,r]=e,o,a=2e-4;return Math.abs(s)<a&&Math.abs(r)<a?o=NaN:o=Math.atan2(r,s)*180/Math.PI,[t,Math.sqrt(s**2+r**2),pi(o)]},toBase(e){return[e[0],e[1]*Math.cos(e[2]*Math.PI/180),e[1]*Math.sin(e[2]*Math.PI/180)]}});function _q(e,t){[e,t]=xs([e,t]);let[s,r,o]=Iy.from(e),[a,i,l]=Iy.from(t),c=s-a,d=r-i;Number.isNaN(o)&&Number.isNaN(l)?(o=0,l=0):Number.isNaN(o)?o=l:Number.isNaN(l)&&(l=o);let u=o-l,p=2*Math.sqrt(r*i)*Math.sin(u/2*(Math.PI/180));return Math.sqrt(c**2+d**2+p**2)}var j6=3424/4096,K6=2413/128,Q6=2392/128,e6=2610/16384,fq=2523/32,vq=16384/2610,t6=32/2523,hq=[[.3592832590121217,.6976051147779502,-.035891593232029],[-.1920808463704993,1.100476797037432,.0753748658519118],[.0070797844607479,.0748396662186362,.8433265453898765]],gq=[[2048/4096,2048/4096,0],[6610/4096,-13613/4096,7003/4096],[17933/4096,-17390/4096,-543/4096]],yq=[[.9999999999999998,.0086090370379328,.111029625003026],[.9999999999999998,-.0086090370379328,-.1110296250030259],[.9999999999999998,.5600313357106791,-.3206271749873188]],bq=[[2.0701522183894223,-1.3263473389671563,.2066510476294053],[.3647385209748072,.6805660249472273,-.0453045459220347],[-.0497472075358123,-.0492609666966131,1.1880659249923042]],Yy=new Ht({id:\"ictcp\",name:\"ICTCP\",coords:{i:{refRange:[0,1],name:\"I\"},ct:{refRange:[-.5,.5],name:\"CT\"},cp:{refRange:[-.5,.5],name:\"CP\"}},base:Ky,fromBase(e){return xq(Gr(hq,e))},toBase(e){return Gr(bq,Aq(e))}});function xq(e){return Gr(gq,e.map(function(t){return((j6+K6*(t/1e4)**e6)/(1+Q6*(t/1e4)**e6))**fq}))}function Aq(e){return Gr(yq,e).map(function(t){return 1e4*(Math.max(t**t6-j6,0)/(K6-Q6*t**t6))**vq})}function wq(e,t){[e,t]=xs([e,t]);let[s,r,o]=Yy.from(e),[a,i,l]=Yy.from(t);return 720*Math.sqrt((s-a)**2+.25*(r-i)**2+(o-l)**2)}var Tq=fa.D65,Z6=.42,s6=1/Z6,ky=2*Math.PI,J6=[[.401288,.650173,-.051461],[-.250268,1.204414,.045854],[-.002079,.048952,.953127]],Sq=[[1.8620678550872327,-1.0112546305316843,.14918677544445175],[.38752654323613717,.6214474419314753,-.008973985167612518],[-.015841498849333856,-.03412293802851557,1.0499644368778496]],Pq=[[460,451,288],[460,-891,-261],[460,-220,-6300]],Cq={dark:[.8,.525,.8],dim:[.9,.59,.9],average:[1,.69,1]},Yc={h:[20.14,90,164.25,237.53,380.14],e:[.8,.7,1,1.2,.8],H:[0,100,200,300,400]},Mq=180/Math.PI,r6=Math.PI/180;function ew(e,t){return e.map(s=>{let r=ui(t*Math.abs(s)*.01,Z6);return 400*Wf(r,s)/(r+27.13)})}function Eq(e,t){let s=100/t*27.13**s6;return e.map(r=>{let o=Math.abs(r);return Wf(s*ui(o/(400-o),s6),r)})}function kq(e){let t=pi(e);t<=Yc.h[0]&&(t+=360);let s=V6(Yc.h,t)-1,[r,o]=Yc.h.slice(s,s+2),[a,i]=Yc.e.slice(s,s+2),l=Yc.H[s],c=(t-r)/a;return l+100*c/(c+(o-t)/i)}function Bq(e){let t=(e%400+400)%400,s=Math.floor(.01*t);t=t%100;let[r,o]=Yc.h.slice(s,s+2),[a,i]=Yc.e.slice(s,s+2);return pi((t*(i*r-a*o)-100*r*i)/(t*(i-a)-100*i))}function tw(e,t,s,r,o){let a={};a.discounting=o,a.refWhite=e,a.surround=r;let i=e.map(f=>f*100);a.la=t,a.yb=s;let l=i[1],c=Gr(J6,i);r=Cq[a.surround];let d=r[0];a.c=r[1],a.nc=r[2];let u=(1/(5*a.la+1))**4;a.fl=u*a.la+.1*(1-u)*(1-u)*Math.cbrt(5*a.la),a.flRoot=a.fl**.25,a.n=a.yb/l,a.z=1.48+Math.sqrt(a.n),a.nbb=.725*a.n**-.2,a.ncb=a.nbb;let p=o?1:Math.max(Math.min(d*(1-1/3.6*Math.exp((-a.la-42)/92)),1),0);a.dRgb=c.map(f=>jp(1,l/f,p)),a.dRgbInv=a.dRgb.map(f=>1/f);let _=ew(c.map((f,h)=>f*a.dRgb[h]),a.fl);return a.aW=a.nbb*(2*_[0]+_[1]+.05*_[2]),a}var o6=tw(Tq,64/Math.PI*.2,20,\"average\",!1);function Wy(e,t){if(!(e.J!==void 0^e.Q!==void 0))throw new Error(\"Conversion requires one and only one: 'J' or 'Q'\");if(!(e.C!==void 0^e.M!==void 0^e.s!==void 0))throw new Error(\"Conversion requires one and only one: 'C', 'M' or 's'\");if(!(e.h!==void 0^e.H!==void 0))throw new Error(\"Conversion requires one and only one: 'h' or 'H'\");if(e.J===0||e.Q===0)return[0,0,0];let s=0;e.h!==void 0?s=pi(e.h)*r6:s=Bq(e.H)*r6;let r=Math.cos(s),o=Math.sin(s),a=0;e.J!==void 0?a=ui(e.J,1/2)*.1:e.Q!==void 0&&(a=.25*t.c*e.Q/((t.aW+4)*t.flRoot));let i=0;e.C!==void 0?i=e.C/a:e.M!==void 0?i=e.M/t.flRoot/a:e.s!==void 0&&(i=4e-4*e.s**2*(t.aW+4)/t.c);let l=ui(i*Math.pow(1.64-Math.pow(.29,t.n),-.73),10/9),c=.25*(Math.cos(s+2)+3.8),d=t.aW*ui(a,2/t.c/t.z),u=5e4/13*t.nc*t.ncb*c,p=d/t.nbb,_=23*(p+.305)*Xy(l,23*u+l*(11*r+108*o));return Gr(Sq,Eq(Gr(Pq,[p,_*r,_*o]).map(f=>f*1/1403),t.fl).map((f,h)=>f*t.dRgbInv[h])).map(f=>f/100)}function sw(e,t){let s=ew(Gr(J6,e.map(g=>g*100)).map((g,y)=>g*t.dRgb[y]),t.fl),r=s[0]+(-12*s[1]+s[2])/11,o=(s[0]+s[1]-2*s[2])/9,a=(Math.atan2(o,r)%ky+ky)%ky,i=.25*(Math.cos(a+2)+3.8),l=ui(5e4/13*t.nc*t.ncb*Xy(i*Math.sqrt(r**2+o**2),s[0]+s[1]+1.05*s[2]+.305),.9)*Math.pow(1.64-Math.pow(.29,t.n),.73),c=ui(t.nbb*(2*s[0]+s[1]+.05*s[2])/t.aW,.5*t.c*t.z),d=100*ui(c,2),u=4/t.c*c*(t.aW+4)*t.flRoot,p=l*c,_=p*t.flRoot,f=pi(a*Mq),h=kq(f);return{J:d,C:p,h:f,s:50*ui(t.c*l/(t.aW+4),1/2),Q:u,M:_,H:h}}var zq=new Ht({id:\"cam16-jmh\",cssId:\"--cam16-jmh\",name:\"CAM16-JMh\",coords:{j:{refRange:[0,100],name:\"J\"},m:{refRange:[0,105],name:\"Colorfulness\"},h:{refRange:[0,360],type:\"angle\",name:\"Hue\"}},base:Ho,fromBase(e){let t=sw(e,o6);return[t.J,t.M,t.h]},toBase(e){return Wy({J:e[0],M:e[1],h:e[2]},o6)}}),Rq=fa.D65,Dq=216/24389,rw=24389/27;function Lq(e){return 116*(e>Dq?Math.cbrt(e):(rw*e+16)/116)-16}function qy(e){return e>8?Math.pow((e+16)/116,3):e/rw}function Uq(e,t){let[s,r,o]=e,a=[],i=0;if(o===0)return[0,0,0];let l=qy(o);o>0?i=.00379058511492914*o**2+.608983189401032*o+.9155088574762233:i=9514440756550361e-21*o**2+.08693057439788597*o-21.928975842194614;let c=2e-12,d=15,u=0,p=1/0;for(;u<=d;){a=Wy({J:i,C:r,h:s},t);let _=Math.abs(a[1]-l);if(_<p){if(_<=c)return a;p=_}i=i-(a[1]-l)*i/(2*a[1]),u+=1}return Wy({J:i,C:r,h:s},t)}function Oq(e,t){let s=Lq(e[1]);if(s===0)return[0,0,0];let r=sw(e,Qy);return[pi(r.h),r.C,s]}var Qy=tw(Rq,200/Math.PI*qy(50),qy(50)*100,\"average\",!1),Qp=new Ht({id:\"hct\",name:\"HCT\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},c:{refRange:[0,145],name:\"Colorfulness\"},t:{refRange:[0,100],name:\"Tone\"}},base:Ho,fromBase(e){return Oq(e)},toBase(e){return Uq(e,Qy)},formats:{color:{id:\"--hct\",coords:[\"<number> | <angle>\",\"<percentage> | <number>\",\"<percentage> | <number>\"]}}}),Gq=Math.PI/180,a6=[1,.007,.0228];function n6(e){e[1]<0&&(e=Qp.fromBase(Qp.toBase(e)));let t=Math.log(Math.max(1+a6[2]*e[1]*Qy.flRoot,1))/a6[2],s=e[0]*Gq,r=t*Math.cos(s),o=t*Math.sin(s);return[e[2],r,o]}function Fq(e,t){[e,t]=xs([e,t]);let[s,r,o]=n6(Qp.from(e)),[a,i,l]=n6(Qp.from(t));return Math.sqrt((s-a)**2+(r-i)**2+(o-l)**2)}var ru={deltaE76:nq,deltaECMC:iq,deltaE2000:$6,deltaEJz:_q,deltaEITP:wq,deltaEOK:Fy,deltaEHCT:Fq};function Iq(e){let t=e?Math.floor(Math.log10(Math.abs(e))):0;return Math.max(parseFloat(`1e${t-2}`),1e-6)}var i6={hct:{method:\"hct.c\",jnd:2,deltaEMethod:\"hct\",blackWhiteClamp:{}},\"hct-tonal\":{method:\"hct.c\",jnd:0,deltaEMethod:\"hct\",blackWhiteClamp:{channel:\"hct.t\",min:0,max:100}}};function Ol(e,{method:t=on.gamut_mapping,space:s=void 0,deltaEMethod:r=\"\",jnd:o=2,blackWhiteClamp:a={}}={}){if(e=xs(e),Zp(arguments[1])?s=arguments[1]:s||(s=e.space),s=Ht.get(s),Wc(e,s,{epsilon:0}))return e;let i;if(t===\"css\")i=Yq(e,{space:s});else{if(t!==\"clip\"&&!Wc(e,s)){Object.prototype.hasOwnProperty.call(i6,t)&&({method:t,jnd:o,deltaEMethod:r,blackWhiteClamp:a}=i6[t]);let l=$6;if(r!==\"\"){for(let d in ru)if(\"deltae\"+r.toLowerCase()===d.toLowerCase()){l=ru[d];break}}let c=Ol(Or(e,s),{method:\"clip\",space:s});if(l(e,c)>o){if(Object.keys(a).length===3){let b=Ht.resolveCoord(a.channel),x=sn(Or(e,b.space),b.id);if(Ll(x)&&(x=0),x>=a.max)return Or({space:\"xyz-d65\",coords:fa.D65},e.space);if(x<=a.min)return Or({space:\"xyz-d65\",coords:[0,0,0]},e.space)}let d=Ht.resolveCoord(t),u=d.space,p=d.id,_=Or(e,u);_.coords.forEach((b,x)=>{Ll(b)&&(_.coords[x]=0)});let f=(d.range||d.refRange)[0],h=Iq(o),g=f,y=sn(_,p);for(;y-g>h;){let b=su(_);b=Ol(b,{space:s,method:\"clip\"}),l(_,b)-o<h?g=sn(_,p):y=sn(_,p),Ni(_,p,(g+y)/2)}i=Or(_,s)}else i=c}else i=Or(e,s);if(t===\"clip\"||!Wc(i,s,{epsilon:0})){let l=Object.values(s.coords).map(c=>c.range||[]);i.coords=i.coords.map((c,d)=>{let[u,p]=l[d];return u!==void 0&&(c=Math.max(u,c)),p!==void 0&&(c=Math.min(c,p)),c})}}return s!==e.space&&(i=Or(i,e.space)),e.coords=i.coords,e}Ol.returns=\"color\";var l6={WHITE:{space:tu,coords:[1,0,0]},BLACK:{space:tu,coords:[0,0,0]}};function Yq(e,{space:t}={}){e=xs(e),t||(t=e.space),t=Ht.get(t);let o=Ht.get(\"oklch\");if(t.isUnbounded)return Or(e,t);let a=Or(e,o),i=a.coords[0];if(i>=1){let h=Or(l6.WHITE,t);return h.alpha=e.alpha,Or(h,t)}if(i<=0){let h=Or(l6.BLACK,t);return h.alpha=e.alpha,Or(h,t)}if(Wc(a,t,{epsilon:0}))return Or(a,t);function l(h){let g=Or(h,t),y=Object.values(t.coords);return g.coords=g.coords.map((b,x)=>{if(\"range\"in y[x]){let[P,C]=y[x].range;return q6(P,b,C)}return b}),g}let c=0,d=a.coords[1],u=!0,p=su(a),_=l(p),f=Fy(_,p);if(f<.02)return _;for(;d-c>1e-4;){let h=(c+d)/2;if(p.coords[1]=h,u&&Wc(p,t,{epsilon:0}))c=h;else if(_=l(p),f=Fy(_,p),f<.02){if(.02-f<1e-4)break;u=!1,c=h}else d=h}return _}function Or(e,t,{inGamut:s}={}){e=xs(e),t=Ht.get(t);let r=t.from(e),o={space:t,coords:r,alpha:e.alpha};return s&&(o=Ol(o,s===!0?void 0:s)),o}Or.returns=\"color\";function Hp(e,{precision:t=on.precision,format:s=\"default\",inGamut:r=!0,...o}={}){let a;e=xs(e);let i=s;s=e.space.getFormat(s)??e.space.getFormat(\"default\")??Ht.DEFAULT_FORMAT;let l=e.coords.slice();if(r||=s.toGamut,r&&!Wc(e)&&(l=Ol(su(e),r===!0?void 0:r).coords),s.type===\"custom\")if(o.precision=t,s.serialize)a=s.serialize(l,e.alpha,o);else throw new TypeError(`format ${i} can only be used to parse colors, not for serialization`);else{let c=s.name||\"color\";s.serializeCoords?l=s.serializeCoords(l,t):t!==null&&(l=l.map(_=>Gf(_,{precision:t})));let d=[...l];if(c===\"color\"){let _=s.id||s.ids?.[0]||e.space.id;d.unshift(_)}let u=e.alpha;t!==null&&(u=Gf(u,{precision:t}));let p=e.alpha>=1||s.noAlpha?\"\":`${s.commas?\",\":\" /\"} ${u}`;a=`${c}(${d.join(s.commas?\", \":\" \")}${p})`}return a}var qf=new Oa({id:\"rec2020-linear\",cssId:\"--rec2020-linear\",name:\"Linear REC.2020\",white:\"D65\",toXYZ_M:[[.6369580483012914,.14461690358620832,.1688809751641721],[.2627002120112671,.6779980715188708,.05930171646986196],[0,.028072693049087428,1.060985057710791]],fromXYZ_M:[[1.716651187971268,-.355670783776392,-.25336628137366],[-.666684351832489,1.616481236634939,.0157685458139111],[.017639857445311,-.042770613257809,.942103121235474]]}),Rf=1.09929682680944,c6=.018053968510807,ow=new Oa({id:\"rec2020\",name:\"REC.2020\",base:qf,toBase(e){return e.map(function(t){return t<c6*4.5?t/4.5:Math.pow((t+Rf-1)/Rf,1/.45)})},fromBase(e){return e.map(function(t){return t>=c6?Rf*Math.pow(t,.45)-(Rf-1):4.5*t})}}),aw=new Oa({id:\"p3-linear\",cssId:\"--display-p3-linear\",name:\"Linear P3\",white:\"D65\",toXYZ_M:[[.4865709486482162,.26566769316909306,.1982172852343625],[.2289745640697488,.6917385218365064,.079286914093745],[0,.04511338185890264,1.043944368900976]],fromXYZ_M:[[2.493496911941425,-.9313836179191239,-.40271078445071684],[-.8294889695615747,1.7626640603183463,.023624685841943577],[.03584583024378447,-.07617238926804182,.9568845240076872]]}),Wq=[[.41239079926595934,.357584339383878,.1804807884018343],[.21263900587151027,.715168678767756,.07219231536073371],[.01933081871559182,.11919477979462598,.9505321522496607]],bo=[[3.2409699419045226,-1.537383177570094,-.4986107602930034],[-.9692436362808796,1.8759675015077202,.04155505740717559],[.05563007969699366,-.20397695888897652,1.0569715142428786]],nw=new Oa({id:\"srgb-linear\",name:\"Linear sRGB\",white:\"D65\",toXYZ_M:Wq,fromXYZ_M:bo}),d6={aliceblue:[240/255,248/255,1],antiquewhite:[250/255,235/255,215/255],aqua:[0,1,1],aquamarine:[127/255,1,212/255],azure:[240/255,1,1],beige:[245/255,245/255,220/255],bisque:[1,228/255,196/255],black:[0,0,0],blanchedalmond:[1,235/255,205/255],blue:[0,0,1],blueviolet:[138/255,43/255,226/255],brown:[165/255,42/255,42/255],burlywood:[222/255,184/255,135/255],cadetblue:[95/255,158/255,160/255],chartreuse:[127/255,1,0],chocolate:[210/255,105/255,30/255],coral:[1,127/255,80/255],cornflowerblue:[100/255,149/255,237/255],cornsilk:[1,248/255,220/255],crimson:[220/255,20/255,60/255],cyan:[0,1,1],darkblue:[0,0,139/255],darkcyan:[0,139/255,139/255],darkgoldenrod:[184/255,134/255,11/255],darkgray:[169/255,169/255,169/255],darkgreen:[0,100/255,0],darkgrey:[169/255,169/255,169/255],darkkhaki:[189/255,183/255,107/255],darkmagenta:[139/255,0,139/255],darkolivegreen:[85/255,107/255,47/255],darkorange:[1,140/255,0],darkorchid:[153/255,50/255,204/255],darkred:[139/255,0,0],darksalmon:[233/255,150/255,122/255],darkseagreen:[143/255,188/255,143/255],darkslateblue:[72/255,61/255,139/255],darkslategray:[47/255,79/255,79/255],darkslategrey:[47/255,79/255,79/255],darkturquoise:[0,206/255,209/255],darkviolet:[148/255,0,211/255],deeppink:[1,20/255,147/255],deepskyblue:[0,191/255,1],dimgray:[105/255,105/255,105/255],dimgrey:[105/255,105/255,105/255],dodgerblue:[30/255,144/255,1],firebrick:[178/255,34/255,34/255],floralwhite:[1,250/255,240/255],forestgreen:[34/255,139/255,34/255],fuchsia:[1,0,1],gainsboro:[220/255,220/255,220/255],ghostwhite:[248/255,248/255,1],gold:[1,215/255,0],goldenrod:[218/255,165/255,32/255],gray:[128/255,128/255,128/255],green:[0,128/255,0],greenyellow:[173/255,1,47/255],grey:[128/255,128/255,128/255],honeydew:[240/255,1,240/255],hotpink:[1,105/255,180/255],indianred:[205/255,92/255,92/255],indigo:[75/255,0,130/255],ivory:[1,1,240/255],khaki:[240/255,230/255,140/255],lavender:[230/255,230/255,250/255],lavenderblush:[1,240/255,245/255],lawngreen:[124/255,252/255,0],lemonchiffon:[1,250/255,205/255],lightblue:[173/255,216/255,230/255],lightcoral:[240/255,128/255,128/255],lightcyan:[224/255,1,1],lightgoldenrodyellow:[250/255,250/255,210/255],lightgray:[211/255,211/255,211/255],lightgreen:[144/255,238/255,144/255],lightgrey:[211/255,211/255,211/255],lightpink:[1,182/255,193/255],lightsalmon:[1,160/255,122/255],lightseagreen:[32/255,178/255,170/255],lightskyblue:[135/255,206/255,250/255],lightslategray:[119/255,136/255,153/255],lightslategrey:[119/255,136/255,153/255],lightsteelblue:[176/255,196/255,222/255],lightyellow:[1,1,224/255],lime:[0,1,0],limegreen:[50/255,205/255,50/255],linen:[250/255,240/255,230/255],magenta:[1,0,1],maroon:[128/255,0,0],mediumaquamarine:[102/255,205/255,170/255],mediumblue:[0,0,205/255],mediumorchid:[186/255,85/255,211/255],mediumpurple:[147/255,112/255,219/255],mediumseagreen:[60/255,179/255,113/255],mediumslateblue:[123/255,104/255,238/255],mediumspringgreen:[0,250/255,154/255],mediumturquoise:[72/255,209/255,204/255],mediumvioletred:[199/255,21/255,133/255],midnightblue:[25/255,25/255,112/255],mintcream:[245/255,1,250/255],mistyrose:[1,228/255,225/255],moccasin:[1,228/255,181/255],navajowhite:[1,222/255,173/255],navy:[0,0,128/255],oldlace:[253/255,245/255,230/255],olive:[128/255,128/255,0],olivedrab:[107/255,142/255,35/255],orange:[1,165/255,0],orangered:[1,69/255,0],orchid:[218/255,112/255,214/255],palegoldenrod:[238/255,232/255,170/255],palegreen:[152/255,251/255,152/255],paleturquoise:[175/255,238/255,238/255],palevioletred:[219/255,112/255,147/255],papayawhip:[1,239/255,213/255],peachpuff:[1,218/255,185/255],peru:[205/255,133/255,63/255],pink:[1,192/255,203/255],plum:[221/255,160/255,221/255],powderblue:[176/255,224/255,230/255],purple:[128/255,0,128/255],rebeccapurple:[102/255,51/255,153/255],red:[1,0,0],rosybrown:[188/255,143/255,143/255],royalblue:[65/255,105/255,225/255],saddlebrown:[139/255,69/255,19/255],salmon:[250/255,128/255,114/255],sandybrown:[244/255,164/255,96/255],seagreen:[46/255,139/255,87/255],seashell:[1,245/255,238/255],sienna:[160/255,82/255,45/255],silver:[192/255,192/255,192/255],skyblue:[135/255,206/255,235/255],slateblue:[106/255,90/255,205/255],slategray:[112/255,128/255,144/255],slategrey:[112/255,128/255,144/255],snow:[1,250/255,250/255],springgreen:[0,1,127/255],steelblue:[70/255,130/255,180/255],tan:[210/255,180/255,140/255],teal:[0,128/255,128/255],thistle:[216/255,191/255,216/255],tomato:[1,99/255,71/255],turquoise:[64/255,224/255,208/255],violet:[238/255,130/255,238/255],wheat:[245/255,222/255,179/255],white:[1,1,1],whitesmoke:[245/255,245/255,245/255],yellow:[1,1,0],yellowgreen:[154/255,205/255,50/255]},u6=Array(3).fill(\"<percentage> | <number>[0, 255]\"),p6=Array(3).fill(\"<number>[0, 255]\"),ou=new Oa({id:\"srgb\",name:\"sRGB\",base:nw,fromBase:e=>e.map(t=>{let s=t<0?-1:1,r=t*s;return r>.0031308?s*(1.055*r**(1/2.4)-.055):12.92*t}),toBase:e=>e.map(t=>{let s=t<0?-1:1,r=t*s;return r<=.04045?t/12.92:s*((r+.055)/1.055)**2.4}),formats:{rgb:{coords:u6},rgb_number:{name:\"rgb\",commas:!0,coords:p6,noAlpha:!0},color:{},rgba:{coords:u6,commas:!0,lastAlpha:!0},rgba_number:{name:\"rgba\",commas:!0,coords:p6},hex:{type:\"custom\",toGamut:!0,test:e=>/^#([a-f0-9]{3,4}){1,2}$/i.test(e),parse(e){e.length<=5&&(e=e.replace(/[a-f0-9]/gi,\"$&$&\"));let t=[];return e.replace(/[a-f0-9]{2}/gi,s=>{t.push(parseInt(s,16)/255)}),{spaceId:\"srgb\",coords:t.slice(0,3),alpha:t.slice(3)[0]}},serialize:(e,t,{collapse:s=!0}={})=>{t<1&&e.push(t),e=e.map(o=>Math.round(o*255));let r=s&&e.every(o=>o%17===0);return\"#\"+e.map(o=>r?(o/17).toString(16):o.toString(16).padStart(2,\"0\")).join(\"\")}},keyword:{type:\"custom\",test:e=>/^[a-z]+$/i.test(e),parse(e){e=e.toLowerCase();let t={spaceId:\"srgb\",coords:null,alpha:1};if(e===\"transparent\"?(t.coords=d6.black,t.alpha=0):t.coords=d6[e],t.coords)return t}}}}),iw=new Oa({id:\"p3\",cssId:\"display-p3\",name:\"P3\",base:aw,fromBase:ou.fromBase,toBase:ou.toBase});on.display_space=ou;var qq;if(typeof CSS<\"u\"&&CSS.supports)for(let e of[rn,ow,iw]){let t=Hp({space:e,coords:e.getMinCoords(),alpha:1});if(CSS.supports(\"color\",t)){on.display_space=e;break}}function Vq(e,{space:t=on.display_space,...s}={}){let r=Hp(e,s);if(typeof CSS>\"u\"||CSS.supports(\"color\",r)||!on.display_space)r=new String(r),r.color=e;else{let o=e;if((e.coords.some(Ll)||Ll(e.alpha))&&!(qq??=CSS.supports(\"color\",\"hsl(none 50% 50%)\"))&&(o=su(e),o.coords=o.coords.map(uo),o.alpha=uo(o.alpha),r=Hp(o,s),CSS.supports(\"color\",r)))return r=new String(r),r.color=o,r;o=Or(o,t),r=new String(Hp(o,s)),r.color=o}return r}function Nq(e,t){return e=xs(e),t=xs(t),e.space===t.space&&e.alpha===t.alpha&&e.coords.every((s,r)=>s===t.coords[r])}function Gl(e){return sn(e,[Ho,\"y\"])}function lw(e,t){Ni(e,[Ho,\"y\"],t)}function $q(e){Object.defineProperty(e.prototype,\"luminance\",{get(){return Gl(this)},set(t){lw(this,t)}})}var Xq=Object.freeze({__proto__:null,getLuminance:Gl,register:$q,setLuminance:lw});function Hq(e,t){e=xs(e),t=xs(t);let s=Math.max(Gl(e),0),r=Math.max(Gl(t),0);return r>s&&([s,r]=[r,s]),(s+.05)/(r+.05)}var jq=.56,Kq=.57,Qq=.62,Zq=.65,m6=.022,Jq=1.414,eV=.1,tV=5e-4,sV=1.14,_6=.027,rV=1.14;function f6(e){return e>=m6?e:e+(m6-e)**Jq}function Zd(e){let t=e<0?-1:1,s=Math.abs(e);return t*Math.pow(s,2.4)}function oV(e,t){t=xs(t),e=xs(e);let s,r,o,a,i,l;t=Or(t,\"srgb\"),[a,i,l]=t.coords;let c=Zd(a)*.2126729+Zd(i)*.7151522+Zd(l)*.072175;e=Or(e,\"srgb\"),[a,i,l]=e.coords;let d=Zd(a)*.2126729+Zd(i)*.7151522+Zd(l)*.072175,u=f6(c),p=f6(d),_=p>u;return Math.abs(p-u)<tV?r=0:_?(s=p**jq-u**Kq,r=s*sV):(s=p**Zq-u**Qq,r=s*rV),Math.abs(r)<eV?o=0:r>0?o=r-_6:o=r+_6,o*100}function aV(e,t){e=xs(e),t=xs(t);let s=Math.max(Gl(e),0),r=Math.max(Gl(t),0);r>s&&([s,r]=[r,s]);let o=s+r;return o===0?0:(s-r)/o}var nV=5e4;function iV(e,t){e=xs(e),t=xs(t);let s=Math.max(Gl(e),0),r=Math.max(Gl(t),0);return r>s&&([s,r]=[r,s]),r===0?nV:(s-r)/r}function lV(e,t){e=xs(e),t=xs(t);let s=sn(e,[rn,\"l\"]),r=sn(t,[rn,\"l\"]);return Math.abs(s-r)}var cV=216/24389,v6=24/116,Df=24389/27,By=fa.D65,Vy=new Ht({id:\"lab-d65\",name:\"Lab D65\",coords:{l:{refRange:[0,100],name:\"Lightness\"},a:{refRange:[-125,125]},b:{refRange:[-125,125]}},white:By,base:Ho,fromBase(e){let t=e.map((s,r)=>s/By[r]).map(s=>s>cV?Math.cbrt(s):(Df*s+16)/116);return[116*t[1]-16,500*(t[0]-t[1]),200*(t[1]-t[2])]},toBase(e){let t=[];return t[1]=(e[0]+16)/116,t[0]=e[1]/500+t[1],t[2]=t[1]-e[2]/200,[t[0]>v6?Math.pow(t[0],3):(116*t[0]-16)/Df,e[0]>8?Math.pow((e[0]+16)/116,3):e[0]/Df,t[2]>v6?Math.pow(t[2],3):(116*t[2]-16)/Df].map((s,r)=>s*By[r])},formats:{\"lab-d65\":{coords:[\"<number> | <percentage>\",\"<number> | <percentage>[-1,1]\",\"<number> | <percentage>[-1,1]\"]}}}),zy=Math.pow(5,.5)*.5+.5;function dV(e,t){e=xs(e),t=xs(t);let s=sn(e,[Vy,\"l\"]),r=sn(t,[Vy,\"l\"]),o=Math.abs(Math.pow(s,zy)-Math.pow(r,zy)),a=Math.pow(o,1/zy)*Math.SQRT2-40;return a<7.5?0:a}var Of=Object.freeze({__proto__:null,contrastAPCA:oV,contrastDeltaPhi:dV,contrastLstar:lV,contrastMichelson:aV,contrastWCAG21:Hq,contrastWeber:iV});function uV(e,t,s={}){Zp(s)&&(s={algorithm:s});let{algorithm:r,...o}=s;if(!r){let a=Object.keys(Of).map(i=>i.replace(/^contrast/,\"\")).join(\", \");throw new TypeError(`contrast() function needs a contrast algorithm. Please specify one of: ${a}`)}e=xs(e),t=xs(t);for(let a in Of)if(\"contrast\"+r.toLowerCase()===a.toLowerCase())return Of[a](e,t,o);throw new TypeError(`Unknown contrast algorithm: ${r}`)}function Vf(e){let[t,s,r]=Jp(e,Ho),o=t+15*s+3*r;return[4*t/o,9*s/o]}function cw(e){let[t,s,r]=Jp(e,Ho),o=t+s+r;return[t/o,s/o]}function pV(e){Object.defineProperty(e.prototype,\"uv\",{get(){return Vf(this)}}),Object.defineProperty(e.prototype,\"xy\",{get(){return cw(this)}})}var mV=Object.freeze({__proto__:null,register:pV,uv:Vf,xy:cw});function Xp(e,t,s={}){Zp(s)&&(s={method:s});let{method:r=on.deltaE,...o}=s;for(let a in ru)if(\"deltae\"+r.toLowerCase()===a.toLowerCase())return ru[a](e,t,o);throw new TypeError(`Unknown deltaE method: ${r}`)}function _V(e,t=.25){return Ni(e,[Ht.get(\"oklch\",\"lch\"),\"l\"],s=>s*(1+t))}function fV(e,t=.25){return Ni(e,[Ht.get(\"oklch\",\"lch\"),\"l\"],s=>s*(1-t))}var vV=Object.freeze({__proto__:null,darken:fV,lighten:_V});function dw(e,t,s=.5,r={}){return[e,t]=[xs(e),xs(t)],Dl(s)===\"object\"&&([s,r]=[.5,s]),em(e,t,r)(s)}function uw(e,t,s={}){let r;Zy(e)&&([r,s]=[e,t],[e,t]=r.rangeArgs.colors);let{maxDeltaE:o,deltaEMethod:a,steps:i=2,maxSteps:l=1e3,...c}=s;r||([e,t]=[xs(e),xs(t)],r=em(e,t,c));let d=Xp(e,t),u=o>0?Math.max(i,Math.ceil(d/o)+1):i,p=[];if(l!==void 0&&(u=Math.min(u,l)),u===1)p=[{p:.5,color:r(.5)}];else{let _=1/(u-1);p=Array.from({length:u},(f,h)=>{let g=h*_;return{p:g,color:r(g)}})}if(o>0){let _=p.reduce((f,h,g)=>{if(g===0)return 0;let y=Xp(h.color,p[g-1].color,a);return Math.max(f,y)},0);for(;_>o;){_=0;for(let f=1;f<p.length&&p.length<l;f++){let h=p[f-1],g=p[f],y=(g.p+h.p)/2,b=r(y);_=Math.max(_,Xp(b,h.color),Xp(b,g.color)),p.splice(f,0,{p:y,color:r(y)}),f++}}}return p=p.map(_=>_.color),p}function em(e,t,s={}){if(Zy(e)){let[c,d]=[e,t];return em(...c.rangeArgs.colors,{...c.rangeArgs.options,...d})}let{space:r,outputSpace:o,progression:a,premultiplied:i}=s;e=xs(e),t=xs(t),e=su(e),t=su(t);let l={colors:[e,t],options:s};if(r?r=Ht.get(r):r=Ht.registry[on.interpolationSpace]||e.space,o=o?Ht.get(o):r,e=Or(e,r),t=Or(t,r),e=Ol(e),t=Ol(t),r.coords.h&&r.coords.h.type===\"angle\"){let c=s.hue=s.hue||\"shorter\",d=[r,\"h\"],[u,p]=[sn(e,d),sn(t,d)];isNaN(u)&&!isNaN(p)?u=p:isNaN(p)&&!isNaN(u)&&(p=u),[u,p]=eq(c,[u,p]),Ni(e,d,u),Ni(t,d,p)}return i&&(e.coords=e.coords.map(c=>c*e.alpha),t.coords=t.coords.map(c=>c*t.alpha)),Object.assign(c=>{c=a?a(c):c;let d=e.coords.map((_,f)=>{let h=t.coords[f];return jp(_,h,c)}),u=jp(e.alpha,t.alpha,c),p={space:r,coords:d,alpha:u};return i&&(p.coords=p.coords.map(_=>_/u)),o!==r&&(p=Or(p,o)),p},{rangeArgs:l})}function Zy(e){return Dl(e)===\"function\"&&!!e.rangeArgs}on.interpolationSpace=\"lab\";function hV(e){e.defineFunction(\"mix\",dw,{returns:\"color\"}),e.defineFunction(\"range\",em,{returns:\"function<color>\"}),e.defineFunction(\"steps\",uw,{returns:\"array<color>\"})}var gV=Object.freeze({__proto__:null,isRange:Zy,mix:dw,range:em,register:hV,steps:uw}),pw=new Ht({id:\"hsl\",name:\"HSL\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},s:{range:[0,100],name:\"Saturation\"},l:{range:[0,100],name:\"Lightness\"}},base:ou,fromBase:e=>{let t=Math.max(...e),s=Math.min(...e),[r,o,a]=e,[i,l,c]=[NaN,0,(s+t)/2],d=t-s;if(d!==0){switch(l=c===0||c===1?0:(t-c)/Math.min(c,1-c),t){case r:i=(o-a)/d+(o<a?6:0);break;case o:i=(a-r)/d+2;break;case a:i=(r-o)/d+4}i=i*60}return l<0&&(i+=180,l=Math.abs(l)),i>=360&&(i-=360),[i,l*100,c*100]},toBase:e=>{let[t,s,r]=e;t=t%360,t<0&&(t+=360),s/=100,r/=100;function o(a){let i=(a+t/30)%12,l=s*Math.min(r,1-r);return r-l*Math.max(-1,Math.min(i-3,9-i,1))}return[o(0),o(8),o(4)]},formats:{hsl:{coords:[\"<number> | <angle>\",\"<percentage>\",\"<percentage>\"]},hsla:{coords:[\"<number> | <angle>\",\"<percentage>\",\"<percentage>\"],commas:!0,lastAlpha:!0}}}),mw=new Ht({id:\"hsv\",name:\"HSV\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},s:{range:[0,100],name:\"Saturation\"},v:{range:[0,100],name:\"Value\"}},base:pw,fromBase(e){let[t,s,r]=e;s/=100,r/=100;let o=r+s*Math.min(r,1-r);return[t,o===0?0:200*(1-r/o),100*o]},toBase(e){let[t,s,r]=e;s/=100,r/=100;let o=r*(1-s/2);return[t,o===0||o===1?0:(r-o)/Math.min(o,1-o)*100,o*100]},formats:{color:{id:\"--hsv\",coords:[\"<number> | <angle>\",\"<percentage> | <number>\",\"<percentage> | <number>\"]}}}),yV=new Ht({id:\"hwb\",name:\"HWB\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},w:{range:[0,100],name:\"Whiteness\"},b:{range:[0,100],name:\"Blackness\"}},base:mw,fromBase(e){let[t,s,r]=e;return[t,r*(100-s)/100,100-r]},toBase(e){let[t,s,r]=e;s/=100,r/=100;let o=s+r;if(o>=1)return[t,0,s/o*100];let a=1-r;return[t,(a===0?0:1-s/a)*100,a*100]},formats:{hwb:{coords:[\"<number> | <angle>\",\"<percentage> | <number>\",\"<percentage> | <number>\"]}}}),_w=new Oa({id:\"a98rgb-linear\",cssId:\"--a98-rgb-linear\",name:\"Linear Adobe\\xAE 98 RGB compatible\",white:\"D65\",toXYZ_M:[[.5766690429101305,.1855582379065463,.1882286462349947],[.29734497525053605,.6273635662554661,.07529145849399788],[.02703136138641234,.07068885253582723,.9913375368376388]],fromXYZ_M:[[2.0415879038107465,-.5650069742788596,-.34473135077832956],[-.9692436362808795,1.8759675015077202,.04155505740717557],[.013444280632031142,-.11836239223101838,1.0151749943912054]]}),bV=new Oa({id:\"a98rgb\",cssId:\"a98-rgb\",name:\"Adobe\\xAE 98 RGB compatible\",base:_w,toBase:e=>e.map(t=>Math.pow(Math.abs(t),563/256)*Math.sign(t)),fromBase:e=>e.map(t=>Math.pow(Math.abs(t),256/563)*Math.sign(t))}),fw=new Oa({id:\"prophoto-linear\",cssId:\"--prophoto-rgb-linear\",name:\"Linear ProPhoto\",white:\"D50\",base:jy,toXYZ_M:[[.7977666449006423,.13518129740053308,.0313477341283922],[.2880748288194013,.711835234241873,8993693872564e-17],[0,0,.8251046025104602]],fromXYZ_M:[[1.3457868816471583,-.25557208737979464,-.05110186497554526],[-.5446307051249019,1.5082477428451468,.02052744743642139],[0,0,1.2119675456389452]]}),xV=1/512,AV=16/512,wV=new Oa({id:\"prophoto\",cssId:\"prophoto-rgb\",name:\"ProPhoto\",base:fw,toBase(e){return e.map(t=>t<AV?t/16:t**1.8)},fromBase(e){return e.map(t=>t>=xV?t**(1/1.8):16*t)}}),TV=new Ht({id:\"oklch\",name:\"Oklch\",coords:{l:{refRange:[0,1],name:\"Lightness\"},c:{refRange:[0,.4],name:\"Chroma\"},h:{refRange:[0,360],type:\"angle\",name:\"Hue\"}},white:\"D65\",base:tu,fromBase(e){let[t,s,r]=e,o,a=2e-4;return Math.abs(s)<a&&Math.abs(r)<a?o=NaN:o=Math.atan2(r,s)*180/Math.PI,[t,Math.sqrt(s**2+r**2),pi(o)]},toBase(e){let[t,s,r]=e,o,a;return isNaN(r)?(o=0,a=0):(o=s*Math.cos(r*Math.PI/180),a=s*Math.sin(r*Math.PI/180)),[t,o,a]},formats:{oklch:{coords:[\"<percentage> | <number>\",\"<number> | <percentage>[0,1]\",\"<number> | <angle>\"]}}}),vw=fa.D65,SV=216/24389,h6=24389/27,[g6,y6]=Vf({space:Ho,coords:vw}),hw=new Ht({id:\"luv\",name:\"Luv\",coords:{l:{refRange:[0,100],name:\"Lightness\"},u:{refRange:[-215,215]},v:{refRange:[-215,215]}},white:vw,base:Ho,fromBase(e){let t=[uo(e[0]),uo(e[1]),uo(e[2])],s=t[1],[r,o]=Vf({space:Ho,coords:t});if(!Number.isFinite(r)||!Number.isFinite(o))return[0,0,0];let a=s<=SV?h6*s:116*Math.cbrt(s)-16;return[a,13*a*(r-g6),13*a*(o-y6)]},toBase(e){let[t,s,r]=e;if(t===0||Ll(t))return[0,0,0];s=uo(s),r=uo(r);let o=s/(13*t)+g6,a=r/(13*t)+y6,i=t<=8?t/h6:Math.pow((t+16)/116,3);return[i*(9*o/(4*a)),i,i*((12-3*o-20*a)/(4*a))]},formats:{color:{id:\"--luv\",coords:[\"<number> | <percentage>\",\"<number> | <percentage>[-1,1]\",\"<number> | <percentage>[-1,1]\"]}}}),Jy=new Ht({id:\"lchuv\",name:\"LChuv\",coords:{l:{refRange:[0,100],name:\"Lightness\"},c:{refRange:[0,220],name:\"Chroma\"},h:{refRange:[0,360],type:\"angle\",name:\"Hue\"}},base:hw,fromBase(e){let[t,s,r]=e,o,a=.02;return Math.abs(s)<a&&Math.abs(r)<a?o=NaN:o=Math.atan2(r,s)*180/Math.PI,[t,Math.sqrt(s**2+r**2),pi(o)]},toBase(e){let[t,s,r]=e;return s<0&&(s=0),isNaN(r)&&(r=0),[t,s*Math.cos(r*Math.PI/180),s*Math.sin(r*Math.PI/180)]},formats:{color:{id:\"--lchuv\",coords:[\"<number> | <percentage>\",\"<number> | <percentage>\",\"<number> | <angle>\"]}}}),PV=216/24389,CV=24389/27,b6=bo[0][0],x6=bo[0][1],Ry=bo[0][2],A6=bo[1][0],w6=bo[1][1],Dy=bo[1][2],T6=bo[2][0],S6=bo[2][1],Ly=bo[2][2];function Jd(e,t,s){let r=t/(Math.sin(s)-e*Math.cos(s));return r<0?1/0:r}function Yf(e){let t=Math.pow(e+16,3)/1560896,s=t>PV?t:e/CV,r=s*(284517*b6-94839*Ry),o=s*(838422*Ry+769860*x6+731718*b6),a=s*(632260*Ry-126452*x6),i=s*(284517*A6-94839*Dy),l=s*(838422*Dy+769860*w6+731718*A6),c=s*(632260*Dy-126452*w6),d=s*(284517*T6-94839*Ly),u=s*(838422*Ly+769860*S6+731718*T6),p=s*(632260*Ly-126452*S6);return{r0s:r/a,r0i:o*e/a,r1s:r/(a+126452),r1i:(o-769860)*e/(a+126452),g0s:i/c,g0i:l*e/c,g1s:i/(c+126452),g1i:(l-769860)*e/(c+126452),b0s:d/p,b0i:u*e/p,b1s:d/(p+126452),b1i:(u-769860)*e/(p+126452)}}function P6(e,t){let s=t/360*Math.PI*2,r=Jd(e.r0s,e.r0i,s),o=Jd(e.r1s,e.r1i,s),a=Jd(e.g0s,e.g0i,s),i=Jd(e.g1s,e.g1i,s),l=Jd(e.b0s,e.b0i,s),c=Jd(e.b1s,e.b1i,s);return Math.min(r,o,a,i,l,c)}var MV=new Ht({id:\"hsluv\",name:\"HSLuv\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},s:{range:[0,100],name:\"Saturation\"},l:{range:[0,100],name:\"Lightness\"}},base:Jy,gamutSpace:ou,fromBase(e){let[t,s,r]=[uo(e[0]),uo(e[1]),uo(e[2])],o;return t>99.9999999?(o=0,t=100):t<1e-8?(o=0,t=0):o=s/P6(Yf(t),r)*100,[r,o,t]},toBase(e){let[t,s,r]=[uo(e[0]),uo(e[1]),uo(e[2])],o;return r>99.9999999?(r=100,o=0):r<1e-8?(r=0,o=0):o=P6(Yf(r),t)/100*s,[r,o,t]},formats:{color:{id:\"--hsluv\",coords:[\"<number> | <angle>\",\"<percentage> | <number>\",\"<percentage> | <number>\"]}}});bo[0][0];bo[0][1];bo[0][2];bo[1][0];bo[1][1];bo[1][2];bo[2][0];bo[2][1];bo[2][2];function eu(e,t){return Math.abs(t)/Math.sqrt(Math.pow(e,2)+1)}function C6(e){let t=eu(e.r0s,e.r0i),s=eu(e.r1s,e.r1i),r=eu(e.g0s,e.g0i),o=eu(e.g1s,e.g1i),a=eu(e.b0s,e.b0i),i=eu(e.b1s,e.b1i);return Math.min(t,s,r,o,a,i)}var EV=new Ht({id:\"hpluv\",name:\"HPLuv\",coords:{h:{refRange:[0,360],type:\"angle\",name:\"Hue\"},s:{range:[0,100],name:\"Saturation\"},l:{range:[0,100],name:\"Lightness\"}},base:Jy,gamutSpace:\"self\",fromBase(e){let[t,s,r]=[uo(e[0]),uo(e[1]),uo(e[2])],o;return t>99.9999999?(o=0,t=100):t<1e-8?(o=0,t=0):o=s/C6(Yf(t))*100,[r,o,t]},toBase(e){let[t,s,r]=[uo(e[0]),uo(e[1]),uo(e[2])],o;return r>99.9999999?(r=100,o=0):r<1e-8?(r=0,o=0):o=C6(Yf(r))/100*s,[r,o,t]},formats:{color:{id:\"--hpluv\",coords:[\"<number> | <angle>\",\"<percentage> | <number>\",\"<percentage> | <number>\"]}}}),M6=203,E6=2610/2**14,kV=2**14/2610,BV=2523/2**5,k6=2**5/2523,B6=3424/2**12,z6=2413/2**7,R6=2392/2**7,zV=new Oa({id:\"rec2100pq\",cssId:\"rec2100-pq\",name:\"REC.2100-PQ\",base:qf,toBase(e){return e.map(function(t){return(Math.max(t**k6-B6,0)/(z6-R6*t**k6))**kV*1e4/M6})},fromBase(e){return e.map(function(t){let s=Math.max(t*M6/1e4,0);return((B6+z6*s**E6)/(1+R6*s**E6))**BV})}}),D6=.17883277,L6=.28466892,U6=.55991073,Uy=3.7743,RV=new Oa({id:\"rec2100hlg\",cssId:\"rec2100-hlg\",name:\"REC.2100-HLG\",referred:\"scene\",base:qf,toBase(e){return e.map(function(t){return t<=.5?t**2/3*Uy:(Math.exp((t-U6)/D6)+L6)/12*Uy})},fromBase(e){return e.map(function(t){return t/=Uy,t<=1/12?Math.sqrt(3*t):D6*Math.log(12*t-L6)+U6})}}),gw={};Ul.add(\"chromatic-adaptation-start\",e=>{e.options.method&&(e.M=yw(e.W1,e.W2,e.options.method))});Ul.add(\"chromatic-adaptation-end\",e=>{e.M||(e.M=yw(e.W1,e.W2,e.options.method))});function Nf({id:e,toCone_M:t,fromCone_M:s}){gw[e]=arguments[0]}function yw(e,t,s=\"Bradford\"){let r=gw[s],[o,a,i]=Gr(r.toCone_M,e),[l,c,d]=Gr(r.toCone_M,t),u=Gr([[l/o,0,0],[0,c/a,0],[0,0,d/i]],r.toCone_M);return Gr(r.fromCone_M,u)}Nf({id:\"von Kries\",toCone_M:[[.40024,.7076,-.08081],[-.2263,1.16532,.0457],[0,0,.91822]],fromCone_M:[[1.8599363874558397,-1.1293816185800916,.21989740959619328],[.3611914362417676,.6388124632850422,-6370596838649899e-21],[0,0,1.0890636230968613]]});Nf({id:\"Bradford\",toCone_M:[[.8951,.2664,-.1614],[-.7502,1.7135,.0367],[.0389,-.0685,1.0296]],fromCone_M:[[.9869929054667121,-.14705425642099013,.15996265166373122],[.4323052697233945,.5183602715367774,.049291228212855594],[-.00852866457517732,.04004282165408486,.96848669578755]]});Nf({id:\"CAT02\",toCone_M:[[.7328,.4296,-.1624],[-.7036,1.6975,.0061],[.003,.0136,.9834]],fromCone_M:[[1.0961238208355142,-.27886900021828726,.18274517938277307],[.4543690419753592,.4735331543074117,.07209780371722911],[-.009627608738429355,-.00569803121611342,1.0153256399545427]]});Nf({id:\"CAT16\",toCone_M:[[.401288,.650173,-.051461],[-.250268,1.204414,.045854],[-.002079,.048952,.953127]],fromCone_M:[[1.862067855087233,-1.0112546305316845,.14918677544445172],[.3875265432361372,.6214474419314753,-.008973985167612521],[-.01584149884933386,-.03412293802851557,1.0499644368778496]]});Object.assign(fa,{A:[1.0985,1,.35585],C:[.98074,1,1.18232],D55:[.95682,1,.92149],D75:[.94972,1,1.22638],E:[1,1,1],F2:[.99186,1,.67393],F7:[.95041,1,1.08747],F11:[1.00962,1,.6435]});fa.ACES=[.32168/.33767,1,.34065/.33767];var bw=new Oa({id:\"acescg\",cssId:\"--acescg\",name:\"ACEScg\",coords:{r:{range:[0,65504],name:\"Red\"},g:{range:[0,65504],name:\"Green\"},b:{range:[0,65504],name:\"Blue\"}},referred:\"scene\",white:fa.ACES,toXYZ_M:[[.6624541811085053,.13400420645643313,.1561876870049078],[.27222871678091454,.6740817658111484,.05368951740793705],[-.005574649490394108,.004060733528982826,1.0103391003129971]],fromXYZ_M:[[1.6410233796943257,-.32480329418479,-.23642469523761225],[-.6636628587229829,1.6153315916573379,.016756347685530137],[.011721894328375376,-.008284441996237409,.9883948585390215]]}),Lf=2**-16,Oy=-.35828683,Uf=(Math.log2(65504)+9.72)/17.52,DV=new Oa({id:\"acescc\",cssId:\"--acescc\",name:\"ACEScc\",coords:{r:{range:[Oy,Uf],name:\"Red\"},g:{range:[Oy,Uf],name:\"Green\"},b:{range:[Oy,Uf],name:\"Blue\"}},referred:\"scene\",base:bw,toBase(e){let t=-.3013698630136986;return e.map(function(s){return s<=t?(2**(s*17.52-9.72)-Lf)*2:s<Uf?2**(s*17.52-9.72):65504})},fromBase(e){return e.map(function(t){return t<=0?(Math.log2(Lf)+9.72)/17.52:t<Lf?(Math.log2(Lf+t*.5)+9.72)/17.52:(Math.log2(t)+9.72)/17.52})}}),O6=Object.freeze({__proto__:null,A98RGB:bV,A98RGB_Linear:_w,ACEScc:DV,ACEScg:bw,CAM16_JMh:zq,HCT:Qp,HPLuv:EV,HSL:pw,HSLuv:MV,HSV:mw,HWB:yV,ICTCP:Yy,JzCzHz:Iy,Jzazbz:H6,LCH:Kp,LCHuv:Jy,Lab:rn,Lab_D65:Vy,Luv:hw,OKLCH:TV,OKLab:tu,P3:iw,P3_Linear:aw,ProPhoto:wV,ProPhoto_Linear:fw,REC_2020:ow,REC_2020_Linear:qf,REC_2100_HLG:RV,REC_2100_PQ:zV,XYZ_ABS_D65:Ky,XYZ_D50:jy,XYZ_D65:Ho,sRGB:ou,sRGB_Linear:nw}),va=class Ua{constructor(...t){let s;t.length===1&&(s=xs(t[0]));let r,o,a;s?(r=s.space||s.spaceId,o=s.coords,a=s.alpha):[r,o,a]=t,Object.defineProperty(this,\"space\",{value:Ht.get(r),writable:!1,enumerable:!0,configurable:!0}),this.coords=o?o.slice():[0,0,0],this.alpha=a>1||a===void 0?1:a<0?0:a;for(let i=0;i<this.coords.length;i++)this.coords[i]===\"NaN\"&&(this.coords[i]=NaN);for(let i in this.space.coords)Object.defineProperty(this,i,{get:()=>this.get(i),set:l=>this.set(i,l)})}get spaceId(){return this.space.id}clone(){return new Ua(this.space,this.coords,this.alpha)}toJSON(){return{spaceId:this.spaceId,coords:this.coords,alpha:this.alpha}}display(...t){let s=Vq(this,...t);return s.color=new Ua(s.color),s}static get(t,...s){return t instanceof Ua?t:new Ua(t,...s)}static defineFunction(t,s,r=s){let{instance:o=!0,returns:a}=r,i=function(...l){let c=s(...l);if(a===\"color\")c=Ua.get(c);else if(a===\"function<color>\"){let d=c;c=function(...u){let p=d(...u);return Ua.get(p)},Object.assign(c,d)}else a===\"array<color>\"&&(c=c.map(d=>Ua.get(d)));return c};t in Ua||(Ua[t]=i),o&&(Ua.prototype[t]=function(...l){return i(this,...l)})}static defineFunctions(t){for(let s in t)Ua.defineFunction(s,t[s],t[s])}static extend(t){if(t.register)t.register(Ua);else for(let s in t)Ua.defineFunction(s,t[s])}};va.defineFunctions({get:sn,getAll:Jp,set:Ni,setAll:Hy,to:Or,equals:Nq,inGamut:Wc,toGamut:Ol,distance:X6,toString:Hp});Object.assign(va,{util:HW,hooks:Ul,WHITES:fa,Space:Ht,spaces:Ht.registry,parse:N6,defaults:on});for(let e of Object.keys(O6))Ht.register(O6[e]);for(let e in Ht.registry)Ny(e,Ht.registry[e]);Ul.add(\"colorspace-init-end\",e=>{Ny(e.id,e),e.aliases?.forEach(t=>{Ny(t,e)})});function Ny(e,t){let s=e.replace(/-/g,\"_\");Object.defineProperty(va.prototype,s,{get(){let r=this.getAll(e);return typeof Proxy>\"u\"?r:new Proxy(r,{has:(o,a)=>{try{return Ht.resolveCoord([t,a]),!0}catch{}return Reflect.has(o,a)},get:(o,a,i)=>{if(a&&typeof a!=\"symbol\"&&!(a in o)){let{index:l}=Ht.resolveCoord([t,a]);if(l>=0)return o[l]}return Reflect.get(o,a,i)},set:(o,a,i,l)=>{if(a&&typeof a!=\"symbol\"&&!(a in o)||a>=0){let{index:c}=Ht.resolveCoord([t,a]);if(c>=0)return o[c]=i,this.setAll(e,o),!0}return Reflect.set(o,a,i,l)}})},set(r){this.setAll(e,r)},configurable:!0,enumerable:!0})}va.extend(ru);va.extend({deltaE:Xp});Object.assign(va,{deltaEMethods:ru});va.extend(vV);va.extend({contrast:uV});va.extend(mV);va.extend(Xq);va.extend(gV);va.extend(Of);var xw=\"p3-linear\",Aw=e=>{xw=e},rs=e=>e?1:-1;function LV(e){try{let t=new va(e),s=xw===\"srgb\"?\"srgb-linear\":\"p3-linear\",r=t.to(s).coords,o=Number(t.alpha);return{r:Number.isFinite(r?.[0])?r[0]:0,g:Number.isFinite(r?.[1])?r[1]:0,b:Number.isFinite(r?.[2])?r[2]:0,a:Number.isFinite(o)?o:1}}catch{return{r:0,g:0,b:0,a:0}}}var ce=e=>LV(e),Xe=e=>{let t=.5,s=.5,r=(a,i=!1)=>{if(typeof a==\"number\")return a;if(typeof a==\"object\"&&a!==null)return a.value;let l=a.toLowerCase().trim();if(i){if(l===\"top\")return 0;if(l===\"bottom\")return 1;if(l===\"center\")return .5}else{if(l===\"left\")return 0;if(l===\"right\")return 1;if(l===\"center\")return .5}return console.warn(`Invalid position value: ${a}. Defaulting to center.`),.5};if(typeof e==\"string\"){let a=e.toLowerCase().trim().split(/\\s+/);a.includes(\"left\")?t=0:a.includes(\"right\")?t=1:(a.includes(\"center\")||a.length===1&&(a[0]===\"top\"||a[0]===\"bottom\"))&&(t=.5),a.includes(\"top\")?s=0:a.includes(\"bottom\")?s=1:(a.includes(\"center\")||a.length===1&&(a[0]===\"left\"||a[0]===\"right\"))&&(s=.5),a.length===1&&a[0]===\"center\"&&(t=.5,s=.5)}else typeof e==\"object\"&&e!==null?(t=r(e.x,!1),s=r(e.y,!0)):console.warn(`Invalid position value provided: ${e}. Defaulting to center.`);let o=1-s;return{x:t,y:o}},cs=e=>{if(typeof e==\"number\")return(e%360+360)%360;let t=e.toLowerCase().trim();switch(t){case\"to right\":return 0;case\"to bottom\":return 90;case\"to left\":return 180;case\"to top\":return 270;case\"to bottom right\":case\"to right bottom\":return 45;case\"to bottom left\":case\"to left bottom\":return 135;case\"to top left\":case\"to left top\":return 225;case\"to top right\":case\"to right top\":return 315;case\"from left\":return 0;case\"from top\":return 90;case\"from right\":return 180;case\"from bottom\":return 270;case\"from top left\":return 45;case\"from top right\":return 135;case\"from bottom right\":return 225;case\"from bottom left\":return 315;default:let s=t.match(/^(-?\\d*\\.?\\d+)(deg|rad|turn)?$/);if(s){let[,r,o=\"deg\"]=s,a=parseFloat(r);switch(o){case\"deg\":return(a%360+360)%360;case\"rad\":return(a*180/Math.PI%360+360)%360;case\"turn\":return(a*360%360+360)%360;default:return(a%360+360)%360}}return console.warn(`Invalid angle value: ${e}. Defaulting to 0 degrees.`),0}},Fr=e=>{let t={stretch:0,transparent:1,mirror:2,wrap:3}[e.toLowerCase()];return t===void 0?(console.warn(`Invalid edge mode: ${e}. Defaulting to 'stretch'.`),0):t},ww=e=>({outside:0,center:1,inside:2})[e?.toLowerCase()]??1,dt=[{label:\"Linear RGB\",value:\"linear\"},{label:\"OKLCh\",value:\"oklch\"},{label:\"OKLAB\",value:\"oklab\"},{label:\"HSL\",value:\"hsl\"},{label:\"HSV\",value:\"hsv\"},{label:\"LCH\",value:\"lch\"}],at=e=>{let t={linear:0,oklch:1,oklab:2,hsl:3,hsv:4,lch:5}[e.toLowerCase()];return t===void 0?(console.warn(`Invalid color space mode: ${e}. Defaulting to 'linear'.`),0):t};var UV=Object.defineProperty,ko=e=>{let t={};for(var s in e)UV(t,s,{get:e[s],enumerable:!0});return t};function an(e){typeof Symbol[e]>\"u\"&&Object.defineProperty(Symbol,e,{value:Symbol.for(`Symbol.${e}`),writable:!1,enumerable:!1,configurable:!1})}function Tw(e,t){return typeof e?.[t]==\"function\"}function ju(e,t,s,r){let o=jo.deferOperation;return Tw(e,s)&&(o=e[s](e,t)),o===jo.deferOperation&&Tw(t,s)&&(o=t[s](e,t)),o===jo.deferOperation?r(e,t):o}var OV=(e,t)=>e+t;function GV(e,t){return(typeof e==\"number\"||typeof e==\"string\")&&(typeof t==\"number\"||typeof t==\"string\")?e+t:ju(e,t,jo.plus,OV)}var FV=(e,t)=>e-t;function IV(e,t){return typeof e==\"number\"&&typeof t==\"number\"?e-t:ju(e,t,jo.minus,FV)}var YV=(e,t)=>e*t;function WV(e,t){return typeof e==\"number\"&&typeof t==\"number\"?e*t:ju(e,t,jo.star,YV)}var qV=(e,t)=>e/t;function VV(e,t){return typeof e==\"number\"&&typeof t==\"number\"?e/t:ju(e,t,jo.slash,qV)}var NV=(e,t)=>e**t;function $V(e,t){return typeof e==\"number\"&&typeof t==\"number\"?e**t:ju(e,t,jo.starStar,NV)}var XV=(e,t)=>e%t;function HV(e,t){return typeof e==\"number\"&&typeof t==\"number\"?e%t:ju(e,t,jo.percent,XV)}var jo=(an(\"deferOperation\"),an(\"operatorPlus\"),an(\"operatorMinus\"),an(\"operatorStar\"),an(\"operatorSlash\"),an(\"operatorStarStar\"),an(\"operatorPercent\"),an(\"operatorEqEq\"),an(\"operatorPrePlusPlus\"),an(\"operatorPreMinusMinus\"),an(\"operatorPostPlusPlus\"),an(\"operatorPostMinusMinus\"),an(\"operatorPreMinus\"),globalThis.__tsover_add=GV,globalThis.__tsover_sub=IV,globalThis.__tsover_mul=WV,globalThis.__tsover_div=VV,globalThis.__tsover_pow=$V,globalThis.__tsover_mod=HV,{deferOperation:Symbol.deferOperation,plus:Symbol.operatorPlus,minus:Symbol.operatorMinus,star:Symbol.operatorStar,slash:Symbol.operatorSlash,starStar:Symbol.operatorStarStar,percent:Symbol.operatorPercent,eqEq:Symbol.operatorEqEq,prePlusPlus:Symbol.operatorPrePlusPlus,preMinusMinus:Symbol.operatorPreMinusMinus,postPlusPlus:Symbol.operatorPostPlusPlus,postMinusMinus:Symbol.operatorPostMinusMinus,preMinus:Symbol.operatorPreMinus}),fh=!1,Lx=!1,Bo=\"0.12.3\",ve=Symbol(`typegpu:${Bo}:$internal`),He=Symbol(`typegpu:${Bo}:$soul`),Ka=Symbol(`typegpu:${Bo}:$gpuValueOf`),Mo=Symbol(`typegpu:${Bo}:$getNameForward`),ya=Symbol(`typegpu:${Bo}:$providing`),tc=Symbol(`typegpu:${Bo}:$ownSnippet`),Ws=Symbol(`typegpu:${Bo}:$resolve`),Ux=Symbol(`typegpu:${Bo}:$cast`),mo=Symbol(`typegpu:${Bo}:$gpuCallable`),Ku=Symbol(`typegpu:${Bo}:$repr`);`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;`${Bo}`;function _s(e){return!!e?.[ve]}var zr={[ve]:{},type:\"void\",toString(){return\"void\"}},jV=[\"bool\",\"f32\",\"f16\",\"i32\",\"u32\",\"u16\",\"vec2f\",\"vec2h\",\"vec2i\",\"vec2u\",\"vec2<bool>\",\"vec3f\",\"vec3h\",\"vec3i\",\"vec3u\",\"vec3<bool>\",\"vec4f\",\"vec4h\",\"vec4i\",\"vec4u\",\"vec4<bool>\",\"mat2x2f\",\"mat3x3f\",\"mat4x4f\",\"struct\",\"array\",\"ptr\",\"atomic\",\"decorated\",\"abstractInt\",\"abstractFloat\",\"void\",\"texture_1d\",\"texture_storage_1d\",\"texture_2d\",\"texture_storage_2d\",\"texture_multisampled_2d\",\"texture_depth_2d\",\"texture_depth_multisampled_2d\",\"texture_2d_array\",\"texture_storage_2d_array\",\"texture_depth_2d_array\",\"texture_cube\",\"texture_depth_cube\",\"texture_cube_array\",\"texture_depth_cube_array\",\"texture_3d\",\"texture_storage_3d\",\"texture_external\",\"sampler\",\"sampler_comparison\"];function Jo(e){let t=e;return _s(t)&&typeof t.kind==\"string\"&&t.kind.startsWith(\"vec\")}function KV(e){return Jo(e)&&e.kind.includes(\"b\")}function QV(e){let t=e;return _s(t)&&typeof t.type==\"string\"&&t.type.startsWith(\"vec2\")}function ZV(e){let t=e;return _s(t)&&typeof t.type==\"string\"&&t.type.startsWith(\"vec3\")}function JV(e){let t=e;return _s(t)&&typeof t.type==\"string\"&&t.type.startsWith(\"vec4\")}function js(e){return QV(e)||ZV(e)||JV(e)}function Ox(e){return js(e)&&e.type.includes(\"b\")}function Kn(e){let t=e;return _s(t)&&typeof t.kind?.startsWith==\"function\"&&t.kind.startsWith(\"mat\")}function CC(e){return _s(e)&&e?.type===\"mat2x2f\"}function MC(e){return _s(e)&&e?.type===\"mat3x3f\"}function eN(e){return _s(e)&&e?.type===\"mat4x4f\"}function xi(e){return CC(e)||MC(e)||eN(e)}function EC(e){return _s(e)&&[\"abstractInt\",\"i32\",\"u32\"].includes(e?.type)}function tN(e){return js(e)&&EC(e.primitive)}function Sw(e){return Jo(e)&&[\"vec2f\",\"vec3f\",\"vec4f\"].includes(e.kind)}function q1(e){return Jo(e)&&/[iu]$/.test(e.kind)}function kC(e){return Jo(e)&&/[u]$/.test(e.kind)}function Td(e){return _s(e)&&jV.includes(e?.type)}function io(e){return _s(e)&&e?.type===\"array\"}function _r(e){return _s(e)&&e?.type===\"struct\"}function ta(e){return _s(e)&&e?.type===\"ptr\"}function vh(e){return _s(e)&&e?.type===\"atomic\"}function BC(e){return _s(e)&&e?.type===\"@align\"}function zC(e){return _s(e)&&e?.type===\"@size\"}function RC(e){return _s(e)&&e?.type===\"@location\"}function sN(e){return _s(e)&&e?.type===\"@builtin\"}function gl(e){return _s(e)&&e?.type===\"decorated\"}function hh(e){return _s(e)&&e.type===\"void\"}function ql(e){return _s(e)&&e.type===\"bool\"}function tb(e){let t=e?.type;return _s(e)&&(t===\"abstractInt\"||t===\"abstractFloat\"||t===\"f32\"||t===\"f16\"||t===\"i32\"||t===\"u32\")}function Gx(e){let t=e?.type;return _s(e)&&(t===\"f16\"||t===\"vec2h\"||t===\"vec3h\"||t===\"vec4h\")}var rN=[\"abstractInt\",\"abstractFloat\",\"f32\",\"f16\",\"i32\",\"u32\",\"bool\"];function jn(e){return!_s(e)||rN.includes(e?.type)}function gh(e){return e.schema}var oN=[\"deprecated\",\"suspicious\",\"fallback\",\"precision-loss\",\"implicit-conversion\",\"webgpu-feature-missing\",\"webgpu-limits-exceeded\",\"locations-mismatched\",\"log-limit-exceeded\",\"external-omitted\",\"uniform-schema-misaligned\"],aN=class{#e;#t;#s=new WeakMap;constructor(e){e?this.#e=[\"webgpu-feature-missing\",\"webgpu-limits-exceeded\",\"locations-mismatched\",\"log-limit-exceeded\",\"external-omitted\"]:this.#e=oN,this.#t=new Set(this.#e)}disable(e){this.#t.delete(e)}reset(){this.#t=new Set(this.#e)}warn(e,...t){this.#t.has(e)&&console.warn(`\\u26A0\\uFE0F [${e}] `,...t)}warnOnce(e,t,s,...r){if(!this.#t.has(e))return;let o=this.#s.get(t);o||(o=new Set,this.#s.set(t,o));let a=`${e}:${s}`;o.has(a)||(o.add(a),this.warn(e,...r))}},DC=new aN(!(fh||Lx)),rr=DC,LC=DC;function pn(e){if(Array.isArray(e))return`[${e.map(pn).join(\", \")}]`;let t=String(e);if(t!==\"[object Object]\")return t;try{return JSON.stringify(e)}catch(s){return rr.warn(\"suspicious\",\"Error parsing JSON:\",s),\"<invalid json>\"}}function sb(e){return Jo(e)||Kn(e)?e.toString():Array.isArray(e)?`[${e.map(sb).join(\", \")}]`:e&&typeof e==\"object\"?`{ ${Object.entries(e).map(([t,s])=>`${t}: ${sb(s)}`).join(\", \")} }`:String(e)}function nN(e){let t={};for(let[s,r]of Object.entries(e))Object.defineProperty(t,s,{get:r,enumerable:!0});return t}function iN(e){if(e.v===1){let t=e.externals;return{...e,externals:typeof t==\"function\"?t:()=>t}}if(e.v===2){let t=nN(e?.externals);return{...e,externals:()=>t}}throw new Error(`Unrecognized TypeGPU metadata format: ${pn(e)}`)}var UC=\"0.12.3\",cl=globalThis;cl.__TYPEGPU_VERSION__!==void 0&&console.warn(`Found duplicate TypeGPU version. First was ${cl.__TYPEGPU_VERSION__}, this one is ${UC}. This may cause unexpected behavior.`);cl.__TYPEGPU_VERSION__=UC;cl.__TYPEGPU_AUTONAME__=(e,t)=>Su(e)&&_s(e)&&!ct(e)?e.$name(t):e;var V1=new WeakMap;function Su(e){return!!e?.$name}function OC(e){return!!e?.[Mo]}function GC(e){return e?.[He]}function ct(e){return OC(e)?ct(e[Mo]):V1.get(e)??GC(e)?.label??cl.__TYPEGPU_META__?.get(e)?.name}function es(e,t){if(OC(e)){es(e[Mo],t);return}V1.set(e,t);let s=GC(e);s&&(s.label=t)}var Pw=new WeakMap;function Fx(e){let t=cl.__TYPEGPU_META__?.get(e);if(t){cl.__TYPEGPU_META__?.delete(e);let s=iN(t);Pw.set(e,s),t.name&&V1.get(e)===void 0&&V1.set(e,t.name)}return Pw.get(e)}function Pu(e){return typeof e==\"function\"&&!!Fx(e)}var Ix=(fh||Lx)&&{get enabled(){return!!cl.__TYPEGPU_MEASURE_PERF__},record(e,t){let s=cl.__TYPEGPU_PERF_RECORDS__??=new Map,r=s.get(e);r||(r=[],s.set(e,r)),r.push(t)}}||void 0,e0=\"Invariant failed\";function kr(e,t){if(e)return;if(!fh&&!Lx)throw new Error(e0);let s=typeof t==\"function\"?t():t,r=s?`${e0}: ${s}`:e0;throw new Error(r)}var fu=class rb extends Error{cause;trace;constructor(t,s){let r=s.map(o=>`- ${Pu(o)?`fn*:${ct(o)}`:o}`);r.length>20&&(r=[...r.slice(0,11),\"...\",...r.slice(-10)]),super(`Resolution of the following tree failed:\n${r.join(`\n`)}: ${t&&typeof t==\"object\"&&\"message\"in t?t.message:t}`),this.cause=t,this.trace=s,Object.setPrototypeOf(this,rb.prototype)}appendToTrace(t){let s=[t,...this.trace];return new rb(this.cause,s)}},Cw=class ob extends Error{cause;trace;constructor(t,s){let r=s.map(o=>`- ${o}`);r.length>20&&(r=[...r.slice(0,11),\"...\",...r.slice(-10)]),super(`Execution of the following tree failed:\n${r.join(`\n`)}: ${t&&typeof t==\"object\"&&\"message\"in t?t.message:t}`),this.cause=t,this.trace=s,Object.setPrototypeOf(this,ob.prototype)}appendToTrace(t){let s=[t,...this.trace];return new ob(this.cause,s)}},lN=class FC extends Error{slot;constructor(t){super(`Missing value for '${t}'`),this.slot=t,Object.setPrototypeOf(this,FC.prototype)}},cN=class IC extends Error{constructor(t){super(`Buffer '${ct(t)??\"<unnamed>\"}' is not bindable as a uniform. Use .$usage('uniform') to allow it.`),Object.setPrototypeOf(this,IC.prototype)}},dN=class YC extends Error{constructor(t){super(`Missing bind groups for layouts: '${[...t].map(s=>ct(s)??\"<unnamed>\").join(\", \")}'. Please provide it using pipeline.with(bindGroup).(...)`),Object.setPrototypeOf(this,YC.prototype)}},uN=class WC extends Error{constructor(t){super(`Missing vertex buffers for layouts: '${[...t].map(s=>ct(s)??\"<unnamed>\").join(\", \")}'. Please provide it using pipeline.with(layout, buffer).(...)`),Object.setPrototypeOf(this,WC.prototype)}},Mw=class qC extends Error{constructor(t){super(t),Object.setPrototypeOf(this,qC.prototype)}},Ew=class VC extends Error{constructor(t){super(t),Object.setPrototypeOf(this,VC.prototype)}},jt=class NC extends Error{constructor(t){super(t),Object.setPrototypeOf(this,NC.prototype)}},jr=class $C extends Error{constructor(t,s){super(`Unsupported data types: ${t.map(r=>r.type).join(\", \")}. Supported types are: ${s.map(r=>r.type).join(\", \")}.`),Object.setPrototypeOf(this,$C.prototype)}},r_=class XC extends Error{constructor(t,s){super(`Cannot convert value '${t}' to type ${s.type} because of the Finite Math Assumption (see: https://www.w3.org/TR/WGSL/#finite-math-assumption)`),Object.setPrototypeOf(this,XC.prototype)}},HC=[\"uint8\",\"uint8x2\",\"uint8x4\",\"sint8\",\"sint8x2\",\"sint8x4\",\"unorm8\",\"unorm8x2\",\"unorm8x4\",\"snorm8\",\"snorm8x2\",\"snorm8x4\",\"uint16\",\"uint16x2\",\"uint16x4\",\"sint16\",\"sint16x2\",\"sint16x4\",\"unorm16\",\"unorm16x2\",\"unorm16x4\",\"snorm16\",\"snorm16x2\",\"snorm16x4\",\"float16\",\"float16x2\",\"float16x4\",\"float32\",\"float32x2\",\"float32x3\",\"float32x4\",\"uint32\",\"uint32x2\",\"uint32x3\",\"uint32x4\",\"sint32\",\"sint32x2\",\"sint32x3\",\"sint32x4\",\"unorm10-10-10-2\",\"unorm8x4-bgra\"],pN={f32:\"float32\",vec2f:\"float32x2\",vec3f:\"float32x3\",vec4f:\"float32x4\",f16:\"float16\",vec2h:\"float16x2\",vec4h:\"float16x4\",u32:\"uint32\",vec2u:\"uint32x2\",vec3u:\"uint32x3\",vec4u:\"uint32x4\",i32:\"sint32\",vec2i:\"sint32x2\",vec3i:\"sint32x3\",vec4i:\"sint32x4\"};function _n(e){return gl(e)||vc(e)?e.inner:e}function $c(e){return ta(e)?e.inner:e}var mN=[\"unstruct\",\"disarray\",\"loose-decorated\",...HC];function yh(e){return _s(e)&&mN.includes(e?.type)}function Sd(e){return _s(e)&&e?.type===\"disarray\"}function ki(e){return _s(e)&&e?.type===\"unstruct\"}function vc(e){return _s(e)&&e?.type===\"loose-decorated\"}function Tm(e){return e.attribs?.find(BC)?.params[0]}function _N(e){return e.attribs?.find(zC)?.params[0]}function sc(e){return e.attribs?.find(RC)?.params[0]}function o_(e){return Td(e)||yh(e)}var Ns=Symbol(\"UNKNOWN\"),jC=class{matrix;constructor(e){this.matrix=e}};function fN(e){return e===\"runtime\"||e===\"constant\"?e:\"runtime\"}function gi(e){return!(e.origin===\"runtime\"||e.origin===\"constant\")}var vN={uniform:{space:\"uniform\",access:\"read\"},readonly:{space:\"storage\",access:\"read\"},mutable:{space:\"storage\",access:\"read-write\"},workgroup:{space:\"workgroup\",access:\"read-write\"},private:{space:\"private\",access:\"read-write\"},function:{space:\"function\",access:\"read-write\"},\"local-def\":{space:\"function\",access:\"read-write\"}},a_=class{value;dataType;origin;possibleSideEffects;constructor(e,t,s,r){this.value=e,this.dataType=t,this.origin=s,this.possibleSideEffects=r}};function n_(e){return e instanceof a_}function fm(e){return tb(e.dataType)}function Je(e,t,s,r=!0){if(fh&&n_(e))throw new Error(\"Cannot nest snippets\");return new a_(e,_n(t),s,r)}function Yx(e,t){return new a_(t.value,e,t.origin,t.possibleSideEffects)}function KC(e,t){return new a_(e,t.dataType,t.origin,t.possibleSideEffects)}function hN(e,t){return new a_(t.value,t.dataType,t.origin,e)}function gN(e){return hN(!1,e)}function ab(e){return e?.resourceType===\"slot\"}function nb(e){return e?.resourceType===\"lazy\"}function S1(e){return e?.[ya]!==void 0}function Qu(e){return e?.resourceType===\"accessor\"}function Zu(e){return e?.resourceType===\"mutable-accessor\"}var Ju=class{type=\"normal\"},yN=class{type=\"codegen\"},bN=class{type=\"simulate\";buffers;vars;constructor(e,t){this.buffers=e,this.vars=t}};function QC(e){return!!e?.[Ws]}function bh(e){return e?.[tc]}function N1(e){return!!e?.[mo]}function xN(e){return!!e?.[Ux]}function qr(e){return(typeof e.value!=\"string\"||e.dataType===Ns)&&bh(e.value)===void 0}function AN(e){return typeof e==\"number\"||typeof e==\"boolean\"||QC(e)||Td(e)||ab(e)||nb(e)||S1(e)}function ol(e){return!!e&&typeof e==\"object\"&&\"getMappedRange\"in e&&\"mapAsync\"in e}function Fm(e){return e.resourceType===\"buffer\"}function ZC(e){return!!e.usableAsUniform}function $1(e){return!!e?.usableAsStorage}var P1=!1;function wN(e){if(P1)return e();try{return P1=!0,e()}finally{P1=!1}}function X1(){return P1}var Zc;function JC(e,t){if(Zc===e)return t();let s=Zc;Zc=e;try{return t()}finally{Zc=s}}function _d(){return Zc}var eM=new Ju;function kw(){return Zc?.mode??eM}function xh(){return Zc?.mode.type===\"codegen\"}function Ne(e,...t){let s=_d();function r(a){return n_(a)?s.resolveSnippet(a).value:a}let o=\"\";for(let a=0;a<e.length;++a){o+=e[a];let i=t[a];Array.isArray(i)?o+=i.filter(l=>l!==void 0).map(r).join(\", \"):i&&(o+=r(i))}return o}function tM(e){return Ah(\"function\",e,\"read-write\")}function Ah(e,t,s,r=!1){return{[ve]:{},type:\"ptr\",addressSpace:e,inner:t,access:s,implicit:r,toString:()=>`ptr<${e}, ${t}, ${s}>`}}function Wx(e,t){let s=vN[e];if(s)return Ah(s.space,t,s.access)}function sM(e){return Ah(e.addressSpace,e.inner,e.access,!0)}function TN(e){return Ah(e.addressSpace,e.inner,e.access,!1)}var SN=(()=>{let e=(t=>PN(t));return es(e,\"ref\"),e.toString=()=>\"ref\",e[ve]=!0,e[mo]={call(t,[s]){if(s.origin===\"argument\")throw new jt(Ne`d.ref(${s}) is illegal, cannot take a reference of an argument. Copy the value first, and take a reference of the copy.`);if(s.origin===\"constant-immutable-def\"||s.origin===\"runtime-immutable-def\"){let o=t.resolve(s.dataType).value;throw new jt(Ne`d.ref(${s}) is illegal, cannot take a reference to a constant.\n-----\n- Try 'd.ref(${o}(${s}));' instead to create a new referencable value.\n-----`)}if(gi(s)&&jn(s.dataType)){let o=t.resolve(s.dataType).value;throw new jt(Ne`d.ref(${s}) is illegal, cannot take a reference to a scalar value.\n-----\n- Try 'd.ref(${o}(${s}));' instead to create a new referencable scalar.\n-----`)}if(ta(s.dataType))return Yx(TN(s.dataType),s);let r=Wx(s.origin,s.dataType);return Je(new Ji(s,r),r??Ns,\"runtime\",s.possibleSideEffects)}},e})();function rM(e){return e?.[ve]?.type===\"ref\"}function PN(e){let t={[ve]:{type:\"ref\"},get $(){return e},set $(s){if(s&&typeof s==\"object\")for(let r of Object.keys(s))e[r]=s[r];else e=s}};if(e==null)throw new Error(\"Cannot create a ref from undefined or null\");return typeof e==\"object\"?new Proxy(t,{get(s,r){return r in s?s[r]:e[r]},set(s,r,o){return r===ve?!1:Reflect.set(r===\"$\"?t:e,r,o)}}):t}var Ji=class{[ve];snippet;#e;constructor(e,t){this[ve]=!0,this.snippet=e,this.#e=t}get[tc](){if(!this.#e)throw new Error(Ne`Cannot take a reference of ${this.snippet}`);return Je(this,this.#e,this.snippet.origin,this.snippet.possibleSideEffects)}[Ws](){if(!this.#e)throw new Error(Ne`Cannot take a reference of ${this.snippet}`);return Je(Ne`(&${this.snippet})`,this.#e,this.snippet.origin,this.snippet.possibleSideEffects)}};function qx(e){if(!ta(e.dataType))return e;let t=e.dataType.inner;return e.value instanceof Ji?Je(Ne`${e.value.snippet}`,t,e.origin,e.possibleSideEffects):Je(Ne`(*${e})`,t,e.origin,e.possibleSideEffects)}function rc(e,t){let s=e;return xN(s)?s[Ux](t):typeof s!=\"function\"?t:t===void 0?s():s(t)}function oM(e,t,s){if(!N1(t))return s;let r=t;return s===void 0||s.value===void 0?r[mo].call(e,[]):r[mo].call(e,[s])}function Im(e,t){throw new Error(`Failed to handle ${e} at ${t}`)}function aM(e,t){kr(_r(e.dataType)||ki(e.dataType),\"Expected snippet type to be struct/unstruct.\");let s=e.dataType.propTypes[t];if(s)return s=_n(s),Je(Ne`${e}.${t}`,s,e.origin,e.possibleSideEffects)}var Vx={rank:Number.POSITIVE_INFINITY,action:\"none\"};function H1(e,t){let s=_n(e),r=_n(t);if(s.type===r.type)return s.type===\"struct\"&&s!==r?{rank:1,action:\"cast\",targetType:t}:{rank:0,action:\"none\"};if(s.type===\"abstractFloat\"){if(r.type===\"f32\")return{rank:1,action:\"none\"};if(r.type===\"f16\")return{rank:2,action:\"none\"}}if(s.type===\"abstractInt\"){if(r.type===\"i32\")return{rank:3,action:\"none\"};if(r.type===\"u32\")return{rank:4,action:\"none\"};if(r.type===\"abstractFloat\")return{rank:5,action:\"none\"};if(r.type===\"f32\")return{rank:6,action:\"none\"};if(r.type===\"f16\")return{rank:7,action:\"none\"}}return js(s)&&js(r)&&s.type[3]===r.type[3]?H1(s.primitive,r.primitive):xi(s)&&xi(r)&&s.type[3]===r.type[3]?{rank:0,action:\"none\"}:Vx}function CN(e,t){let s=_n(e),r=_n(t);if(ta(s)&&s.implicit&&H1(s.inner,r).rank<Number.POSITIVE_INFINITY)return{rank:0,action:\"deref\"};if(ta(r)&&H1(s,r.inner).rank<Number.POSITIVE_INFINITY)return{rank:1,action:\"ref\"};let o={f32:0,f16:1,i32:2,u32:3,bool:4};if(s.type in o&&r.type in o){let a=s.type,i=r.type;if(a!==i){let l=o[a];return{rank:o[i]<l?10:20,action:\"cast\",targetType:r}}}if((s.type===\"u32\"||s.type===\"i32\")&&r.type===\"abstractFloat\")return{rank:1,action:\"cast\",targetType:r.concretized};if(s.type===\"abstractFloat\"){if(r.type===\"i32\")return{rank:2,action:\"cast\",targetType:r};if(r.type===\"u32\")return{rank:3,action:\"cast\",targetType:r}}return Vx}function MN(e,t,s){let r=H1(e,t);return r.rank<Number.POSITIVE_INFINITY?r:s?CN(e,t):Vx}function ib(e,t,s){let r;for(let a of t){let i=a,l=[],c=0;for(let d of e){let u=MN(d,a,s);if(c+=u.rank,u.rank===Number.POSITIVE_INFINITY)break;l.push(u),u.action===\"cast\"&&(i=u.targetType)}c<(r?.sum??Number.POSITIVE_INFINITY)&&(r={type:i,details:l,sum:c})}if(!r)return;let o=r.details.map((a,i)=>({sourceIndex:i,action:a.action,...a.action===\"cast\"&&{targetType:a.targetType}}));return{targetType:r.type,actions:o,hasImplicitConversions:o.some(a=>a.action===\"cast\")}}function Nx(e,t){if(e.length===0)return;let s=[...new Set((t||e).map(_n))],r=ib(e,s,!1);if(r)return r;let o=ib(e,s,!0);if(o)return o}function EN(e,t,s,r){if(s.action===\"none\")return r===t.dataType?t:Yx(r,t);switch(s.action){case\"ref\":return Je(new Ji(t,r),r,t.origin,t.possibleSideEffects);case\"deref\":return qx(t);case\"cast\":if(_r(t.dataType)&&_r(r)){let o=ct(t.dataType)??\"<unnamed>\",a=ct(r)??\"<unnamed>\";if(t.possibleSideEffects)throw new Error(`Cannot resolve struct cast from '${o}' to '${a}'. Store the value to a variable first, then cast it.`);let i=Object.entries(r.propTypes).map(([c,d])=>{let u=aM(t,c);if(!u)throw new Error(`Cannot auto-convert struct '${o}' to '${a}' because the property '${c}' is missing.`);let p=Nl(e,[u],[d]);if(!p||!p[0])throw new Error(`Cannot auto-convert struct '${o}' to '${a}' because type '${ct(u.dataType)??\"<unnamed>\"}' is not convertible to '${ct(_n(d))??\"<unnamed>\"}'.`);return p[0]}),l=e.resolve(r).value;return Je(`${l}(${i.map(c=>c.value).join(\", \")})`,r,\"runtime\",!1)}return oM(e,r,t);default:Im(s.action,\"applyActionToSnippet\")}}function sa(e,t){if(e.some(r=>r===Ns))return;let s=Nx(e,t);if(s)return e.map(r=>js(r)||xi(r)?r:s.targetType)}function wh(e,t){if(e.some(r=>r===Ns))return;let s=ib(e,[...new Set((t||e).map(_n))],!1);if(s)return e.map(r=>js(r)||xi(r)?r:s.targetType)}function Nl(e,t,s,r=!0){let o=t.map(i=>i.dataType);if(o.some(i=>i===Ns))return;kr(!(Array.isArray(s)&&s.length===0),\"Internal error, expected 'restrictTo' to not be an empty array.\");let a=Nx(o,s);if(a)return r&&a.hasImplicitConversions&&rr.warn(\"implicit-conversion\",`Implicit conversions from [\n${t.map(i=>`  ${e.resolveSnippet(i).value}: ${pn(i.dataType)}`).join(`,\n`)}\n] to ${a.targetType.type} are supported, but not recommended.\nConsider using explicit conversions instead.`),t.map((i,l)=>{let c=a.actions[l];return kr(c,\"Action should not be undefined\"),EN(e,i,c,a.targetType)})}function Ga(e,t,s,r=!0){let o=Array.isArray(s)?s:[s],{value:a,dataType:i,origin:l,possibleSideEffects:c}=t;if(o.length===1){let u=o[0];if(u===i)return Je(a,u,l,c);if(i===Ns)return e.resolveSnippet(Je(a,u,l,c))}let d=Nl(e,[t],o,r);if(d)return d[0];throw new jt(`Cannot convert value of type '${String(i)}' to any of the target types: [${o.map(u=>u.type).join(\", \")}]`)}function Bw(e,t,s){return Object.entries(t.propTypes).map(([r,o])=>{let a=s[r];if(!a)throw new Error(`Missing property ${r}`);return Nl(e,[a],[o])?.[0]??a})}function Pd(e){let t=((...s)=>e.normalImpl(...s));return es(t,e.name),t.toString=()=>e.name,t[mo]={get strictSignature(){},call(s,r){let o=e.argTypes(...r.map(l=>ta(l.dataType)&&l.dataType.implicit?l.dataType.inner:l.dataType)),a=r.map((l,c)=>{let d=o[c];if(!d)throw new Error(\"Function called with invalid arguments\");return Ga(s,l,d,!1)}),i;if(a.every(l=>qr(l))){s.pushMode(new Ju);try{i=Je(e.normalImpl(...a.map(l=>l.value)),e.schema(),\"constant\")}finally{s.popMode(\"normal\")}}else i=e.codegenImpl(s,a);return r.some(l=>l.possibleSideEffects)?i:gN(i)}},t}var kN=Pd({name:\"bool\",schema:()=>ys,argTypes:e=>e?[e]:[],normalImpl(e=!1){if(typeof e==\"boolean\")return e;if(typeof e==\"number\"){if(!Number.isFinite(e))throw new r_(e,ys);return!!e}throw new Error(`Invalid argument type for 'd.bool'. Got '${typeof e}', expected number or boolean`)},codegenImpl:(e,[t])=>{if(t===void 0)return e.gen.typeInstantiation(ys,[]);if(ql(t.dataType)||fm(t))return e.gen.typeInstantiation(ys,[t]);throw t.dataType===Ns?new jt(\"Unknown argument type for 'd.bool'.\"):new jr([t.dataType],[ys,M,j,n,Vr])}}),ys=Object.assign(kN,{[ve]:{},type:\"bool\"}),BN=Pd({name:\"u32\",schema:()=>M,argTypes:e=>e?[e]:[],normalImpl(e){if(e===void 0)return 0;if(typeof e==\"boolean\")return e?1:0;if(!Number.isFinite(e))throw new r_(e,M);if(!Number.isInteger(e)){let t=Math.trunc(e);return t<0?0:t>4294967295?4294967295:t}return(e&4294967295)>>>0},codegenImpl:(e,[t])=>e.gen.typeInstantiation(M,t?[t]:[])}),M=Object.assign(BN,{[ve]:{},type:\"u32\"}),zN=Pd({name:\"i32\",schema:()=>j,argTypes:e=>e?[e]:[],normalImpl(e){if(e===void 0)return 0;if(typeof e==\"boolean\")return e?1:0;if(!Number.isFinite(e))throw new r_(e,j);return e|0},codegenImpl:(e,[t])=>e.gen.typeInstantiation(j,t?[t]:[])}),vve={[ve]:{},type:\"u16\"},j=Object.assign(zN,{[ve]:{},type:\"i32\"}),RN=Pd({name:\"f32\",schema:()=>n,argTypes:e=>e?[e]:[],normalImpl(e){if(e===void 0)return 0;if(typeof e==\"boolean\")return e?1:0;if(!Number.isFinite(e))throw new r_(e,n);return Math.fround(e)},codegenImpl:(e,[t])=>e.gen.typeInstantiation(n,t?[t]:[])}),n=Object.assign(RN,{[ve]:{},type:\"f32\"}),nM=new ArrayBuffer(4),DN=new Float32Array(nM),LN=new Uint32Array(nM);function j1(e){DN[0]=e;let t=LN[0],s=t>>>31&1,r=t>>>23&255,o=t&8388607;if(r===255)return s<<15|31744|(o?512:0);if(r=r-127+15,r<=0){if(r<-10)return s<<15;let c=o|8388608,d=14-r,u=c>>>d-1&1,p=c&(1<<d-1)-1?1:0,_=c>>>d;return u&(p|_&1)&&(_+=1),s<<15|_}if(r>=31)return s<<15|31744;let a=o>>>12&1,i=o&4095?1:0,l=o>>>13;return a&(i|l&1)&&(l+=1),l===1024&&(l=0,++r,r>=31)?s<<15|31744:s<<15|r<<10|l}function $x(e){let t=e&32768?-1:1,s=e>>10&31,r=e&1023;return s===0?r?t*r*2**-24:t*0:s===31?r?NaN:t===1?Number.POSITIVE_INFINITY:Number.NEGATIVE_INFINITY:t*(1+r/1024)*2**(s-15)}function UN(e){return $x(j1(e))}var ON=Pd({name:\"f16\",schema:()=>Vr,argTypes:e=>e?[e]:[],normalImpl(e){if(e===void 0)return 0;if(typeof e==\"boolean\")return e?1:0;if(!Number.isFinite(e))throw new r_(e,Vr);return UN(e)},codegenImpl:(e,[t])=>e.gen.typeInstantiation(Vr,t?[t]:[])}),Vr=Object.assign(ON,{[ve]:{},type:\"f16\"}),i_={[ve]:{},type:\"abstractInt\",toString(){return\"abstractInt\"},concretized:j},fd={[ve]:{},type:\"abstractFloat\",toString(){return\"abstractFloat\"},concretized:n};function Ai(e){return e>=2**63||e<-(2**63)?Je(e,fd,\"constant\",!1):Number.isInteger(e)?(Number.isSafeInteger(e)||rr.warn(\"precision-loss\",`The integer ${e} exceeds the safe integer range and may have lost precision.`),Je(e,i_,\"constant\",!1)):Je(e,fd,\"constant\",!1)}function dn(e){return e.type===\"abstractFloat\"?n:e.type===\"abstractInt\"?j:e}function GN(e){return Yx(dn(e.dataType),e)}function Ya(e){if(n_(e))return e;if(rM(e))throw new Error(\"Cannot use refs (d.ref(...)) from the outer scope.\");let t=bh(e);return t||(Jo(e)||Kn(e)?Je(e,gh(e),\"constant\",!1):typeof e==\"number\"?Ai(e):typeof e==\"boolean\"?Je(e,ys,\"constant\",!1):Je(e,Ns,\"constant\",!1))}var Sm=class{[ve]=!0;type;elements;constructor(e,t){this.type=e,this.elements=t}toString(){return\"ArrayExpression\"}[Ws](e){for(let t of this.elements)if(gi(t)&&!jn(t.dataType)){let s=e.resolveSnippet(t).value,r=e.resolve(dn(t.dataType)).value;throw new jt(`'${s}' reference cannot be used in an array constructor.\n-----\nTry '${r}(${s})' or 'arrayOf(${r}, count)([...])' to copy the value instead.\n-----`)}return e.gen.typeInstantiation(this.type,this.elements)}};function Tn(e){let t=((...s)=>e(...s));return t.toString=()=>\"comptime\",t[Mo]=e,t[mo]={call(s,r){if(!r.every(o=>qr(o)))throw new jt(`Called comptime function with runtime-known values: ${r.filter(o=>!qr(o)).map(o=>`'${o.value}'`).join(\", \")}`);s.pushMode(new Ju);try{return Ya(e(...r.map(o=>o.value)))}finally{s.popMode()}}},t.$name=s=>(es(e,s),t),Object.defineProperty(t,ve,{value:{isComptime:!0}}),t}var vo=class extends Error{constructor(e){super(e),this.name=this.constructor.name}};function je(e){let t=((...s)=>{if(typeof e.normalImpl==\"string\")throw new vo(e.normalImpl);return e.normalImpl(...s)});return e.name&&es(t,e.name),t.toString=()=>e.name??\"<unknown>\",t[mo]={get strictSignature(){return typeof e.signature!=\"function\"?e.signature:void 0},call(s,r){let{argTypes:o,returnType:a}=typeof e.signature==\"function\"?e.signature(...r.map(d=>ta(d.dataType)&&d.dataType.implicit?d.dataType.inner:d.dataType)):e.signature,i=r.map((d,u)=>{let p=o[u];if(!p)throw new Error(\"Function called with invalid arguments\");return Ga(s,d,p,!e.ignoreImplicitCastWarning)});if(!e.noComptime&&i.every(d=>qr(d))&&typeof e.normalImpl==\"function\"){s.pushMode(new Ju);try{return Je(e.normalImpl(...i.map(d=>d.value)),a,\"constant\",e.sideEffects)}catch(d){if(!(d instanceof vo))throw d}finally{s.popMode(\"normal\")}}let l=e.sideEffects||r.some(d=>d.possibleSideEffects),c=dn(a);return Je(e.codegenImpl(s,i,c),c,\"runtime\",l)}},t}var $i=[\"x\",\"y\",\"z\",\"w\"],Xi=[\"r\",\"g\",\"b\",\"a\"],yi=class Nc extends Array{static#e=(()=>{for(let t=0;t<4;t++)for(let s=0;s<4;s++)for(let r=0;r<4;r++)for(let o=0;o<4;o++){let a=`${$i[t]}${$i[s]}${$i[r]}${$i[o]}`,i=`${Xi[t]}${Xi[s]}${Xi[r]}${Xi[o]}`;Object.defineProperty(Nc.prototype,a,{get(){return new this._Vec4(this[t],this[s],this[r],this[o])}}),Object.defineProperty(Nc.prototype,i,{get(){return new this._Vec4(this[t],this[s],this[r],this[o])}})}for(let t=0;t<4;t++)for(let s=0;s<4;s++)for(let r=0;r<4;r++){let o=`${$i[t]}${$i[s]}${$i[r]}`,a=`${Xi[t]}${Xi[s]}${Xi[r]}`;Object.defineProperty(Nc.prototype,o,{get(){return new this._Vec3(this[t],this[s],this[r])}}),Object.defineProperty(Nc.prototype,a,{get(){return new this._Vec3(this[t],this[s],this[r])}})}for(let t=0;t<4;t++)for(let s=0;s<4;s++){let r=`${$i[t]}${$i[s]}`,o=`${Xi[t]}${Xi[s]}`;Object.defineProperty(Nc.prototype,r,{get(){return new this._Vec2(this[t],this[s])}}),Object.defineProperty(Nc.prototype,o,{get(){return new this._Vec2(this[t],this[s])}})}})();castElement(){return this[ve].elementSchema}[Ws](t){let s=gh(this);return this.every(r=>!r)?t.gen.typeInstantiation(s,[]):this.every(r=>this[0]===r)?t.gen.typeInstantiation(s,[Ai(this[0])]):t.gen.typeInstantiation(s,this.map(r=>Ai(r)))}toString(){return`${this.kind}(${this.join(\", \")})`}},l_=class extends yi{e0;e1;constructor(e,t){super(2),this.e0=this.castElement()(e),this.e1=this.castElement()(t??e)}get 0(){return this.e0}get 1(){return this.e1}set 0(e){this.e0=this.castElement()(e)}set 1(e){this.e1=this.castElement()(e)}get x(){return this[0]}get y(){return this[1]}set x(e){this[0]=this.castElement()(e)}set y(e){this[1]=this.castElement()(e)}get r(){return this[0]}get g(){return this[1]}set r(e){this[0]=this.castElement()(e)}set g(e){this[1]=this.castElement()(e)}},c_=class extends yi{e0;e1;e2;constructor(e,t,s){super(3),this.e0=this.castElement()(e),this.e1=this.castElement()(t??e),this.e2=this.castElement()(s??e)}get 0(){return this.e0}get 1(){return this.e1}get 2(){return this.e2}set 0(e){this.e0=this.castElement()(e)}set 1(e){this.e1=this.castElement()(e)}set 2(e){this.e2=this.castElement()(e)}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}set x(e){this[0]=this.castElement()(e)}set y(e){this[1]=this.castElement()(e)}set z(e){this[2]=this.castElement()(e)}get r(){return this[0]}get g(){return this[1]}get b(){return this[2]}set r(e){this[0]=this.castElement()(e)}set g(e){this[1]=this.castElement()(e)}set b(e){this[2]=this.castElement()(e)}},d_=class extends yi{e0;e1;e2;e3;constructor(e,t,s,r){super(4),this.e0=this.castElement()(e),this.e1=this.castElement()(t??e),this.e2=this.castElement()(s??e),this.e3=this.castElement()(r??e)}get 0(){return this.e0}get 1(){return this.e1}get 2(){return this.e2}get 3(){return this.e3}set 0(e){this.e0=this.castElement()(e)}set 1(e){this.e1=this.castElement()(e)}set 2(e){this.e2=this.castElement()(e)}set 3(e){this.e3=this.castElement()(e)}get x(){return this[0]}get y(){return this[1]}get z(){return this[2]}get w(){return this[3]}set x(e){this[0]=e}set y(e){this[1]=e}set z(e){this[2]=e}set w(e){this[3]=e}get r(){return this[0]}get g(){return this[1]}get b(){return this[2]}get a(){return this[3]}set r(e){this[0]=e}set g(e){this[1]=e}set b(e){this[2]=e}set a(e){this[3]=e}},Xx=class iM extends l_{get[ve](){return{elementSchema:n}}get kind(){return\"vec2f\"}get _Vec2(){return iM}get _Vec3(){return Zx}get _Vec4(){return r3}},Hx=class lM extends l_{get[ve](){return{elementSchema:Vr}}get kind(){return\"vec2h\"}get _Vec2(){return lM}get _Vec3(){return Jx}get _Vec4(){return o3}},jx=class cM extends l_{get[ve](){return{elementSchema:j}}get kind(){return\"vec2i\"}get _Vec2(){return cM}get _Vec3(){return e3}get _Vec4(){return a3}},Kx=class dM extends l_{get[ve](){return{elementSchema:M}}get kind(){return\"vec2u\"}get _Vec2(){return dM}get _Vec3(){return t3}get _Vec4(){return n3}},Qx=class uM extends l_{get[ve](){return{elementSchema:ys}}get kind(){return\"vec2<bool>\"}get _Vec2(){return uM}get _Vec3(){return s3}get _Vec4(){return i3}},Zx=class pM extends c_{get[ve](){return{elementSchema:n}}get kind(){return\"vec3f\"}get _Vec2(){return Xx}get _Vec3(){return pM}get _Vec4(){return r3}},Jx=class mM extends c_{get[ve](){return{elementSchema:Vr}}get kind(){return\"vec3h\"}get _Vec2(){return Hx}get _Vec3(){return mM}get _Vec4(){return o3}},e3=class _M extends c_{get[ve](){return{elementSchema:j}}get kind(){return\"vec3i\"}get _Vec2(){return jx}get _Vec3(){return _M}get _Vec4(){return a3}},t3=class fM extends c_{get[ve](){return{elementSchema:M}}get kind(){return\"vec3u\"}get _Vec2(){return Kx}get _Vec3(){return fM}get _Vec4(){return n3}},s3=class vM extends c_{get[ve](){return{elementSchema:ys}}get kind(){return\"vec3<bool>\"}get _Vec2(){return Qx}get _Vec3(){return vM}get _Vec4(){return i3}},r3=class hM extends d_{get[ve](){return{elementSchema:n}}get kind(){return\"vec4f\"}get _Vec2(){return Xx}get _Vec3(){return Zx}get _Vec4(){return hM}},o3=class gM extends d_{get[ve](){return{elementSchema:Vr}}get kind(){return\"vec4h\"}get _Vec2(){return Hx}get _Vec3(){return Jx}get _Vec4(){return gM}},a3=class yM extends d_{get[ve](){return{elementSchema:j}}get kind(){return\"vec4i\"}get _Vec2(){return jx}get _Vec3(){return e3}get _Vec4(){return yM}},n3=class bM extends d_{get[ve](){return{elementSchema:M}}get kind(){return\"vec4u\"}get _Vec2(){return Kx}get _Vec3(){return t3}get _Vec4(){return bM}},i3=class xM extends d_{get[ve](){return{elementSchema:ys}}get kind(){return\"vec4<bool>\"}get _Vec2(){return Qx}get _Vec3(){return s3}get _Vec4(){return xM}},ps=Ca(Xx,n),To=Ca(Hx,Vr),ir=Ca(jx,j),$s=Ca(Kx,M),Wa=Ca(Qx,ys),Zs=Ca(Zx,n),Pa=Ca(Jx,Vr),Br=Ca(e3,j),Ps=Ca(t3,M),qa=Ca(s3,ys),qt=Ca(r3,n),So=Ca(o3,Vr),sr=Ca(a3,j),Is=Ca(n3,M),Va=Ca(i3,ys),FN={vec2f:ps,vec2h:To,vec2i:ir,vec2u:$s,\"vec2<bool>\":Wa,vec3f:Zs,vec3h:Pa,vec3i:Br,vec3u:Ps,\"vec3<bool>\":qa,vec4f:qt,vec4h:So,vec4i:sr,vec4u:Is,\"vec4<bool>\":Va};function Ca(e,t){let{kind:s,length:r}=new e,o=r,i=Pd({name:s,schema:()=>l,argTypes:(...c)=>c.map(d=>js(d)?d:t),normalImpl:(...c)=>{let d=Array.from({length:c.length}),u=0;for(let p of c)if(typeof p==\"number\"||typeof p==\"boolean\")d[u++]=p;else for(let _=0;_<p.length;++_)d[u++]=p[_];if(d.length<=1||d.length===o)return new e(...d);throw new Error(`'${s}' constructor called with invalid number of arguments.`)},codegenImpl:(c,d)=>c.gen.typeInstantiation(l,d)}),l=Object.assign(i,{[ve]:{},type:s,primitive:t,componentCount:o,[Ku]:void 0});return e.prototype.schema=l,l}var bu=class{};function l3(e){let t=Pd({name:e.type,schema:()=>s,normalImpl:(...r)=>{let o=[];for(let a of r)if(typeof a==\"number\")o.push(a);else for(let i=0;i<a.length;++i)o.push(a[i]);if(o.length!==0&&o.length!==e.columns*e.rows)throw new Error(`'${e.type}' constructor called with invalid number of arguments.`);for(let a=o.length;a<e.columns*e.rows;++a)o.push(0);return new e.MatImpl(...o)},argTypes:(...r)=>r.map(o=>js(o)?o:n),codegenImpl:(r,o)=>r.gen.typeInstantiation(s,o)}),s=Object.assign(t,{[ve]:{},type:e.type,primitive:n,identity:jN[e.columns],translation:e.columns===4?KN:void 0,scaling:e.columns===4?QN:void 0,rotationX:e.columns===4?ZN:void 0,rotationY:e.columns===4?JN:void 0,rotationZ:e.columns===4?e$:void 0});return e.MatImpl.prototype.schema=s,s}var zw=[0,1,2,3],IN=class extends bu{[ve]=!0;columns;length=4;constructor(...e){super(),this.columns=[this.makeColumn(e[0],e[1]),this.makeColumn(e[2],e[3])]}get 0(){return this.columns[0].x}get 1(){return this.columns[0].y}get 2(){return this.columns[1].x}get 3(){return this.columns[1].y}set 0(e){this.columns[0].x=e}set 1(e){this.columns[0].y=e}set 2(e){this.columns[1].x=e}set 3(e){this.columns[1].y=e}*[Symbol.iterator](){yield this[0],yield this[1],yield this[2],yield this[3]}[Ws](e){return e.gen.typeInstantiation(yl,zw.map(t=>Ai(this[t])))}toString(){return`${this.kind}(${zw.map(e=>this[e]).join(\", \")})`}},YN=class extends IN{kind=\"mat2x2f\";makeColumn(e,t){return ps(e,t)}},Rw=[0,1,2,4,5,6,8,9,10],WN=class extends bu{[ve]=!0;columns;length=12;constructor(...e){super(),this.columns=[this.makeColumn(e[0],e[1],e[2]),this.makeColumn(e[3],e[4],e[5]),this.makeColumn(e[6],e[7],e[8])]}get 0(){return this.columns[0].x}get 1(){return this.columns[0].y}get 2(){return this.columns[0].z}get 3(){return 0}get 4(){return this.columns[1].x}get 5(){return this.columns[1].y}get 6(){return this.columns[1].z}get 7(){return 0}get 8(){return this.columns[2].x}get 9(){return this.columns[2].y}get 10(){return this.columns[2].z}get 11(){return 0}set 0(e){this.columns[0].x=e}set 1(e){this.columns[0].y=e}set 2(e){this.columns[0].z=e}set 3(e){}set 4(e){this.columns[1].x=e}set 5(e){this.columns[1].y=e}set 6(e){this.columns[1].z=e}set 7(e){}set 8(e){this.columns[2].x=e}set 9(e){this.columns[2].y=e}set 10(e){this.columns[2].z=e}set 11(e){}*[Symbol.iterator](){for(let e=0;e<12;e++)yield this[e]}[Ws](e){return e.gen.typeInstantiation(bl,Rw.map(t=>Ai(this[t])))}toString(){return`${this.kind}(${Rw.map(e=>this[e]).join(\", \")})`}},qN=class extends WN{kind=\"mat3x3f\";makeColumn(e,t,s){return Zs(e,t,s)}},Dw=Array.from({length:16},(e,t)=>t),VN=class extends bu{[ve]=!0;columns;constructor(...e){super(),this.columns=[this.makeColumn(e[0],e[1],e[2],e[3]),this.makeColumn(e[4],e[5],e[6],e[7]),this.makeColumn(e[8],e[9],e[10],e[11]),this.makeColumn(e[12],e[13],e[14],e[15])]}length=16;get 0(){return this.columns[0].x}get 1(){return this.columns[0].y}get 2(){return this.columns[0].z}get 3(){return this.columns[0].w}get 4(){return this.columns[1].x}get 5(){return this.columns[1].y}get 6(){return this.columns[1].z}get 7(){return this.columns[1].w}get 8(){return this.columns[2].x}get 9(){return this.columns[2].y}get 10(){return this.columns[2].z}get 11(){return this.columns[2].w}get 12(){return this.columns[3].x}get 13(){return this.columns[3].y}get 14(){return this.columns[3].z}get 15(){return this.columns[3].w}set 0(e){this.columns[0].x=e}set 1(e){this.columns[0].y=e}set 2(e){this.columns[0].z=e}set 3(e){this.columns[0].w=e}set 4(e){this.columns[1].x=e}set 5(e){this.columns[1].y=e}set 6(e){this.columns[1].z=e}set 7(e){this.columns[1].w=e}set 8(e){this.columns[2].x=e}set 9(e){this.columns[2].y=e}set 10(e){this.columns[2].z=e}set 11(e){this.columns[2].w=e}set 12(e){this.columns[3].x=e}set 13(e){this.columns[3].y=e}set 14(e){this.columns[3].z=e}set 15(e){this.columns[3].w=e}*[Symbol.iterator](){for(let e=0;e<16;e++)yield this[e]}[Ws](e){return e.gen.typeInstantiation(Eo,Dw.map(t=>Ai(this[t])))}toString(){return`${this.kind}(${Dw.map(e=>this[e]).join(\", \")})`}},NN=class extends VN{kind=\"mat4x4f\";makeColumn(e,t,s,r){return qt(e,t,s,r)}},$N=Tn(()=>yl(1,0,0,1)).$name(\"identity2\"),XN=Tn(()=>bl(1,0,0,0,1,0,0,0,1)).$name(\"identity3\"),HN=Tn(()=>Eo(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)).$name(\"identity4\"),jN={2:$N,3:XN,4:HN},KN=je({name:\"translation4\",normalImpl:e=>Eo(1,0,0,0,0,1,0,0,0,0,1,0,e.x,e.y,e.z,1),get signature(){return{argTypes:[Zs],returnType:Eo}},codegenImpl:(e,[t])=>Ne`mat4x4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, ${t}.x, ${t}.y, ${t}.z, 1)`,sideEffects:!1}),QN=je({name:\"scaling4\",normalImpl:e=>Eo(e.x,0,0,0,0,e.y,0,0,0,0,e.z,0,0,0,0,1),get signature(){return{argTypes:[Zs],returnType:Eo}},codegenImpl:(e,[t])=>Ne`mat4x4f(${t}.x, 0, 0, 0, 0, ${t}.y, 0, 0, 0, 0, ${t}.z, 0, 0, 0, 0, 1)`,sideEffects:!1}),ZN=je({name:\"rotationX4\",normalImpl:e=>Eo(1,0,0,0,0,Math.cos(e),Math.sin(e),0,0,-Math.sin(e),Math.cos(e),0,0,0,0,1),get signature(){return{argTypes:[n],returnType:Eo}},codegenImpl:(e,[t])=>Ne`mat4x4f(1, 0, 0, 0, 0, cos(${t}), sin(${t}), 0, 0, -sin(${t}), cos(${t}), 0, 0, 0, 0, 1)`,sideEffects:!1}),JN=je({name:\"rotationY4\",normalImpl:e=>Eo(Math.cos(e),0,-Math.sin(e),0,0,1,0,0,Math.sin(e),0,Math.cos(e),0,0,0,0,1),get signature(){return{argTypes:[n],returnType:Eo}},codegenImpl:(e,[t])=>Ne`mat4x4f(cos(${t}), 0, -sin(${t}), 0, 0, 1, 0, 0, sin(${t}), 0, cos(${t}), 0, 0, 0, 0, 1)`,sideEffects:!1}),e$=je({name:\"rotationZ4\",normalImpl:e=>Eo(Math.cos(e),Math.sin(e),0,0,-Math.sin(e),Math.cos(e),0,0,0,0,1,0,0,0,0,1),get signature(){return{argTypes:[n],returnType:Eo}},codegenImpl:(e,[t])=>Ne`mat4x4f(cos(${t}), sin(${t}), 0, 0, -sin(${t}), cos(${t}), 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)`,sideEffects:!1}),yl=l3({type:\"mat2x2f\",rows:2,columns:2,MatImpl:YN}),bl=l3({type:\"mat3x3f\",rows:3,columns:3,MatImpl:qN}),Eo=l3({type:\"mat4x4f\",rows:4,columns:4,MatImpl:NN});var t$=(e,t,s)=>{if(e===t)return 0;let r=AM((s-e)/(t-e),0,1);return r*r*(3-2*r)},AM=(e,t,s)=>Math.min(Math.max(t,e),s),c3=new ArrayBuffer(4),wM=new Float32Array(c3),d3=new Uint32Array(c3),s$=new Int32Array(c3);function fi(e){return d3[0]=e,wM[0]}function vi(e){return d3[0]=e,s$[0]}function hi(e){return wM[0]=e,d3[0]}var Lw=e=>Math.sqrt(e.x**2+e.y**2),Uw=e=>Math.sqrt(e.x**2+e.y**2+e.z**2),Ow=e=>Math.sqrt(e.x**2+e.y**2+e.z**2+e.w**2),$f=(e,t)=>e.x*t.x+e.y*t.y,Xf=(e,t)=>e.x*t.x+e.y*t.y+e.z*t.z,Hf=(e,t)=>e.x*t.x+e.y*t.y+e.z*t.z+e.w*t.w,Gw=e=>(t,s)=>$s(e(t.x,s.x),e(t.y,s.y)),Fw=e=>(t,s)=>Ps(e(t.x,s.x),e(t.y,s.y),e(t.z,s.z)),Iw=e=>(t,s)=>Is(e(t.x,s.x),e(t.y,s.y),e(t.z,s.z),e(t.w,s.w)),Yw=e=>(t,s)=>ir(e(t.x,s.x),e(t.y,s.y)),Ww=e=>(t,s)=>Br(e(t.x,s.x),e(t.y,s.y),e(t.z,s.z)),qw=e=>(t,s)=>sr(e(t.x,s.x),e(t.y,s.y),e(t.z,s.z),e(t.w,s.w)),$a={all:{\"vec2<bool>\":e=>e.x&&e.y,\"vec3<bool>\":e=>e.x&&e.y&&e.z,\"vec4<bool>\":e=>e.x&&e.y&&e.z&&e.w},length:{vec2f:Lw,vec2h:Lw,vec3f:Uw,vec3h:Uw,vec4f:Ow,vec4h:Ow},mulMxM:{mat2x2f:(e,t)=>{let s=e.columns,r=t.columns;return yl(s[0].x*r[0].x+s[1].x*r[0].y,s[0].y*r[0].x+s[1].y*r[0].y,s[0].x*r[1].x+s[1].x*r[1].y,s[0].y*r[1].x+s[1].y*r[1].y)},mat3x3f:(e,t)=>{let s=e.columns,r=t.columns;return bl(s[0].x*r[0].x+s[1].x*r[0].y+s[2].x*r[0].z,s[0].y*r[0].x+s[1].y*r[0].y+s[2].y*r[0].z,s[0].z*r[0].x+s[1].z*r[0].y+s[2].z*r[0].z,s[0].x*r[1].x+s[1].x*r[1].y+s[2].x*r[1].z,s[0].y*r[1].x+s[1].y*r[1].y+s[2].y*r[1].z,s[0].z*r[1].x+s[1].z*r[1].y+s[2].z*r[1].z,s[0].x*r[2].x+s[1].x*r[2].y+s[2].x*r[2].z,s[0].y*r[2].x+s[1].y*r[2].y+s[2].y*r[2].z,s[0].z*r[2].x+s[1].z*r[2].y+s[2].z*r[2].z)},mat4x4f:(e,t)=>{let s=e.columns,r=t.columns;return Eo(s[0].x*r[0].x+s[1].x*r[0].y+s[2].x*r[0].z+s[3].x*r[0].w,s[0].y*r[0].x+s[1].y*r[0].y+s[2].y*r[0].z+s[3].y*r[0].w,s[0].z*r[0].x+s[1].z*r[0].y+s[2].z*r[0].z+s[3].z*r[0].w,s[0].w*r[0].x+s[1].w*r[0].y+s[2].w*r[0].z+s[3].w*r[0].w,s[0].x*r[1].x+s[1].x*r[1].y+s[2].x*r[1].z+s[3].x*r[1].w,s[0].y*r[1].x+s[1].y*r[1].y+s[2].y*r[1].z+s[3].y*r[1].w,s[0].z*r[1].x+s[1].z*r[1].y+s[2].z*r[1].z+s[3].z*r[1].w,s[0].w*r[1].x+s[1].w*r[1].y+s[2].w*r[1].z+s[3].w*r[1].w,s[0].x*r[2].x+s[1].x*r[2].y+s[2].x*r[2].z+s[3].x*r[2].w,s[0].y*r[2].x+s[1].y*r[2].y+s[2].y*r[2].z+s[3].y*r[2].w,s[0].z*r[2].x+s[1].z*r[2].y+s[2].z*r[2].z+s[3].z*r[2].w,s[0].w*r[2].x+s[1].w*r[2].y+s[2].w*r[2].z+s[3].w*r[2].w,s[0].x*r[3].x+s[1].x*r[3].y+s[2].x*r[3].z+s[3].x*r[3].w,s[0].y*r[3].x+s[1].y*r[3].y+s[2].y*r[3].z+s[3].y*r[3].w,s[0].z*r[3].x+s[1].z*r[3].y+s[2].z*r[3].z+s[3].z*r[3].w,s[0].w*r[3].x+s[1].w*r[3].y+s[2].w*r[3].z+s[3].w*r[3].w)}},mulMxV:{mat2x2f:(e,t)=>{let s=e.columns;return ps(s[0].x*t.x+s[1].x*t.y,s[0].y*t.x+s[1].y*t.y)},mat3x3f:(e,t)=>{let s=e.columns;return Zs(s[0].x*t.x+s[1].x*t.y+s[2].x*t.z,s[0].y*t.x+s[1].y*t.y+s[2].y*t.z,s[0].z*t.x+s[1].z*t.y+s[2].z*t.z)},mat4x4f:(e,t)=>{let s=e.columns;return qt(s[0].x*t.x+s[1].x*t.y+s[2].x*t.z+s[3].x*t.w,s[0].y*t.x+s[1].y*t.y+s[2].y*t.z+s[3].y*t.w,s[0].z*t.x+s[1].z*t.y+s[2].z*t.z+s[3].z*t.w,s[0].w*t.x+s[1].w*t.y+s[2].w*t.z+s[3].w*t.w)}},mulVxM:{mat2x2f:(e,t)=>{let s=t.columns;return ps(e.x*s[0].x+e.y*s[0].y,e.x*s[1].x+e.y*s[1].y)},mat3x3f:(e,t)=>{let s=t.columns;return Zs(e.x*s[0].x+e.y*s[0].y+e.z*s[0].z,e.x*s[1].x+e.y*s[1].y+e.z*s[1].z,e.x*s[2].x+e.y*s[2].y+e.z*s[2].z)},mat4x4f:(e,t)=>{let s=t.columns;return qt(e.x*s[0].x+e.y*s[0].y+e.z*s[0].z+e.w*s[0].w,e.x*s[1].x+e.y*s[1].y+e.z*s[1].z+e.w*s[1].w,e.x*s[2].x+e.y*s[2].y+e.z*s[2].z+e.w*s[2].w,e.x*s[3].x+e.y*s[3].y+e.z*s[3].z+e.w*s[3].w)}},dot:{vec2f:$f,vec2h:$f,vec2i:$f,vec2u:$f,vec3f:Xf,vec3h:Xf,vec3i:Xf,vec3u:Xf,vec4f:Hf,vec4h:Hf,vec4i:Hf,vec4u:Hf},cross:{vec3f:(e,t)=>Zs(e.y*t.z-e.z*t.y,e.z*t.x-e.x*t.z,e.x*t.y-e.y*t.x),vec3h:(e,t)=>Pa(e.y*t.z-e.z*t.y,e.z*t.x-e.x*t.z,e.x*t.y-e.y*t.x)},bitShiftLeft:{vec2i:Yw((e,t)=>e<<t),vec2u:Gw((e,t)=>e<<t),vec3i:Ww((e,t)=>e<<t),vec3u:Fw((e,t)=>e<<t),vec4i:qw((e,t)=>e<<t),vec4u:Iw((e,t)=>e<<t)},bitShiftRight:{vec2i:Yw((e,t)=>e>>t),vec2u:Gw((e,t)=>e>>>t),vec3i:Ww((e,t)=>e>>t),vec3u:Fw((e,t)=>e>>>t),vec4i:qw((e,t)=>e>>t),vec4u:Iw((e,t)=>e>>>t)},bitcastU32toF32:{vec2u:e=>ps(fi(e.x),fi(e.y)),vec3u:e=>Zs(fi(e.x),fi(e.y),fi(e.z)),vec4u:e=>qt(fi(e.x),fi(e.y),fi(e.z),fi(e.w))},bitcastU32toI32:{vec2u:e=>ir(vi(e.x),vi(e.y)),vec3u:e=>Br(vi(e.x),vi(e.y),vi(e.z)),vec4u:e=>sr(vi(e.x),vi(e.y),vi(e.z),vi(e.w))},bitcastF32toU32:{vec2f:e=>$s(hi(e.x),hi(e.y)),vec3f:e=>Ps(hi(e.x),hi(e.y),hi(e.z)),vec4f:e=>Is(hi(e.x),hi(e.y),hi(e.z),hi(e.w))}},r$={vec2f:Wa,vec2h:Wa,vec2i:Wa,vec2u:Wa,\"vec2<bool>\":Wa,vec3f:qa,vec3h:qa,vec3i:qa,vec3u:qa,\"vec3<bool>\":qa,vec4f:Va,vec4h:Va,vec4i:Va,vec4u:Va,\"vec4<bool>\":Va},lb={...FN,mat2x2f:yl,mat3x3f:bl,mat4x4f:Eo};function o$(e,t){let s=e===\"boolean\"?r$:lb;if(t in s)return s[t];throw new Error(`No corresponding vector/matrix type for '${t}' kind in '${e}' mode.`)}function a$(e){return e.kind.startsWith(\"vec\")?e:e.columns.flat()}function TM(e,t,s){let r=t.map(n$);if(r.every(c=>c===\"boolean\"||c===\"number\"))return e(...t);let o=r[0];kr(o,\"Expected kind of the first argument to be present.\");let a=o$(s,o),i=t.map(a$),l=i[0]?.length;return kr(l!==void 0,\"Expected constructor to have at least one argument.\"),a(...Array.from({length:l},(c,d)=>e(...i.map(u=>u[d]))))}function Bs(e,t){return TM(e,t,\"first\")}function Th(e,t){return TM(e,t,\"boolean\")}function n$(e){return typeof e==\"number\"?\"number\":typeof e==\"boolean\"?\"boolean\":e.kind}function u3(e){let[t,s]=e;if(typeof t==\"number\"&&Jo(s)){let r=lb[s.kind];return[r(t),s]}else if(Jo(t)&&typeof s==\"number\"){let r=lb[t.kind];return[t,r(s)]}return[t,s]}var Vw=e=>\"primitive\"in e?e.primitive:e,p3=e=>(t,s)=>{let{restrict:r}=e??{},o=u=>{throw r?new jr([t,s],r):new Error(`Cannot apply operator to ${t.type} and ${s.type}: ${u}`)};if(e?.noMat&&(xi(t)||xi(s)))return o(\"matrices not supported\");let a=js(t)||xi(t),i=js(s)||xi(s);if(!a&&!i){let u=sa([t,s],r);return u?{argTypes:u,returnType:u[0]}:o(\"incompatible scalar types\")}if(a&&i)return e?.matVecProduct&&js(t)!==js(s)?{argTypes:[t,s],returnType:js(t)?t:s}:t.type!==s.type?o(\"operands must have the same type\"):{argTypes:[t,s],returnType:t};let[l,c]=a?[s,t]:[t,s],d=sa([l],[Vw(c)]);return d?{argTypes:a?[t,d[0]]:[d[0],s],returnType:c}:o(`scalar not convertible to ${Vw(c).type}`)},SM=p3(),i$=p3({matVecProduct:!0}),PM=p3({noMat:!0,restrict:[n,Vr,fd]});function CM(e,t){if(typeof e==\"number\"&&typeof t==\"number\")return e+t;if(typeof e==\"number\"&&Jo(t))return Bs(s=>e+s,[t]);if(Jo(e)&&typeof t==\"number\")return Bs(s=>s+t,[e]);if(Jo(e)&&Jo(t)||Kn(e)&&Kn(t))return Bs((s,r)=>s+r,[e,t]);throw new Error(\"Add/Sub called with invalid arguments.\")}var al=je({name:\"add\",signature:SM,normalImpl:CM,codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"+\",s),sideEffects:!1});function l$(e,t){return CM(e,MM(-1,t))}var As=je({name:\"sub\",signature:SM,normalImpl:l$,codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"-\",s),sideEffects:!1});function MM(e,t){if(typeof e==\"number\"&&typeof t==\"number\")return e*t;if(typeof e==\"number\"&&(Jo(t)||Kn(t)))return Bs(s=>e*s,[t]);if((Jo(e)||Kn(e))&&typeof t==\"number\")return Bs(s=>s*t,[e]);if(Jo(e)&&Jo(t))return Bs((s,r)=>s*r,[e,t]);if(Sw(e)&&Kn(t))return $a.mulVxM[t.kind](e,t);if(Kn(e)&&Sw(t))return $a.mulMxV[e.kind](e,t);if(Kn(e)&&Kn(t))return $a.mulMxM[e.kind](e,t);throw new Error(\"Mul called with invalid arguments.\")}var ra=je({name:\"mul\",signature:i$,normalImpl:MM,codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"*\",s),sideEffects:!1});function c$(e,t){return Bs((s,r)=>s/r,u3([e,t]))}var cb=je({name:\"div\",signature:PM,normalImpl:c$,codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"/\",s),ignoreImplicitCastWarning:!0,sideEffects:!1}),An=je({name:\"mod\",signature:PM,normalImpl:((e,t)=>Bs((s,r)=>s%r,u3([e,t]))),codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"%\",s),sideEffects:!1});function d$(e){return Bs(t=>-t,[e])}var Nw=je({name:\"neg\",signature:e=>({argTypes:[e],returnType:e}),normalImpl:d$,codegenImpl:(e,[t])=>Ne`-(${t})`,sideEffects:!1}),EM={vec2i:$s,vec2u:$s,vec3i:Ps,vec3u:Ps,vec4i:Is,vec4u:Is},kM=(e,t)=>{let s=sa([e],[ir,Br,sr,$s,Ps,Is])?.[0];if(!s||!js(s))throw new jr([e],[ir,Br,sr,$s,Ps,Is]);let r=s.componentCount,o=r===2?$s:r===3?Ps:Is,a=sa([t],[M,o])?.[0];if(!a)throw new jr([t],[M,o]);return{argTypes:[s,a],returnType:s}};function u$(e,t){if(q1(e)&&kC(t)&&e.length==t.length)return $a.bitShiftLeft[e.kind](e,t);if(q1(e)&&typeof t==\"number\"){let s=EM[e.kind](t);return $a.bitShiftLeft[e.kind](e,s)}throw new Error(\"'bitShiftLeft' called with invalid arguments, expected: left-hand side to be an integer vector, right-hand side to be a number or unsigned integer vector of the same arity as the left-hand side.\")}var p$=je({name:\"bitShiftLeft\",signature:kM,normalImpl:u$,codegenImpl:(e,[t,s])=>{if(js(t.dataType)&&!js(s.dataType)){let r=t.dataType.componentCount,o=r===2?$s:r===3?Ps:Is;return e.gen.emitBinaryOp(t,\"<<\",e.gen.typeInstantiation(o,[s]))}return e.gen.emitBinaryOp(t,\"<<\",s)},sideEffects:!1});function m$(e,t){if(q1(e)&&kC(t)&&e.length==t.length)return $a.bitShiftRight[e.kind](e,t);if(q1(e)&&typeof t==\"number\"){let s=EM[e.kind](t);return $a.bitShiftRight[e.kind](e,s)}throw new Error(\"'bitShiftRight' called with invalid arguments, expected: left-hand side to be an integer vector, right-hand side to be a number or unsigned integer vector of the same arity as the left-hand side.\")}var db={add:al,sub:As,mul:ra,div:cb,mod:An,bitShiftLeft:p$,bitShiftRight:je({name:\"bitShiftRight\",signature:kM,normalImpl:m$,codegenImpl:(e,[t,s])=>{if(js(t.dataType)&&!js(s.dataType)){let r=t.dataType.componentCount,o=r===2?$s:r===3?Ps:Is;return e.gen.emitBinaryOp(t,\">>\",e.gen.typeInstantiation(o,[s]))}return e.gen.emitBinaryOp(t,\">>\",s)},sideEffects:!1})},m3=class{lhs;operator;constructor(e,t){this.lhs=e,this.operator=t}};function _$(e){return e instanceof m3}function mi(e,t,s){let r=db[t];Object.defineProperty(e.prototype,s,{value:r});function o(a){return r(this,a)}Object.defineProperty(e.prototype,t,{get(){return xh()?new m3(this,r):o}})}var $w=!1;function qo(){$w||($w=!0,mi(yi,\"add\",jo.plus),mi(bu,\"add\",jo.plus),mi(yi,\"sub\",jo.minus),mi(bu,\"sub\",jo.minus),mi(yi,\"mul\",jo.star),mi(bu,\"mul\",jo.star),mi(yi,\"div\",jo.slash),mi(yi,\"mod\",jo.percent),mi(yi,\"bitShiftLeft\",Symbol()),mi(yi,\"bitShiftRight\",Symbol()))}var _3=new Set([\"alias\",\"break\",\"case\",\"const\",\"const_assert\",\"continue\",\"continuing\",\"default\",\"diagnostic\",\"discard\",\"else\",\"enable\",\"false\",\"fn\",\"for\",\"if\",\"let\",\"loop\",\"override\",\"requires\",\"return\",\"struct\",\"switch\",\"true\",\"var\",\"while\",\"NULL\",\"Self\",\"abstract\",\"active\",\"alignas\",\"alignof\",\"as\",\"asm\",\"asm_fragment\",\"async\",\"attribute\",\"auto\",\"await\",\"become\",\"cast\",\"catch\",\"class\",\"co_await\",\"co_return\",\"co_yield\",\"coherent\",\"column_major\",\"common\",\"compile\",\"compile_fragment\",\"concept\",\"const_cast\",\"consteval\",\"constexpr\",\"constinit\",\"crate\",\"debugger\",\"decltype\",\"delete\",\"demote\",\"demote_to_helper\",\"do\",\"dynamic_cast\",\"enum\",\"explicit\",\"export\",\"extends\",\"extern\",\"external\",\"fallthrough\",\"filter\",\"final\",\"finally\",\"friend\",\"from\",\"fxgroup\",\"get\",\"goto\",\"groupshared\",\"highp\",\"impl\",\"implements\",\"import\",\"inline\",\"instanceof\",\"interface\",\"layout\",\"lowp\",\"macro\",\"macro_rules\",\"match\",\"mediump\",\"meta\",\"mod\",\"module\",\"move\",\"mut\",\"mutable\",\"namespace\",\"new\",\"nil\",\"noexcept\",\"noinline\",\"nointerpolation\",\"non_coherent\",\"noncoherent\",\"noperspective\",\"null\",\"nullptr\",\"of\",\"operator\",\"package\",\"packoffset\",\"partition\",\"pass\",\"patch\",\"pixelfragment\",\"precise\",\"precision\",\"premerge\",\"priv\",\"protected\",\"pub\",\"public\",\"readonly\",\"ref\",\"regardless\",\"register\",\"reinterpret_cast\",\"require\",\"resource\",\"restrict\",\"self\",\"set\",\"shared\",\"sizeof\",\"smooth\",\"snorm\",\"static\",\"static_assert\",\"static_cast\",\"std\",\"subroutine\",\"super\",\"target\",\"template\",\"this\",\"thread_local\",\"throw\",\"trait\",\"try\",\"type\",\"typedef\",\"typeid\",\"typename\",\"typeof\",\"union\",\"unless\",\"unorm\",\"unsafe\",\"unsized\",\"use\",\"using\",\"varying\",\"virtual\",\"volatile\",\"wgsl\",\"where\",\"with\",\"writeonly\",\"yield\",\"sampler\",\"uniform\",\"storage\"]),f$=new Set([\"array\",\"bool\",\"f16\",\"f32\",\"i32\",\"u32\",\"mat2x2\",\"mat2x3\",\"mat2x4\",\"mat3x2\",\"mat3x3\",\"mat3x4\",\"mat4x2\",\"mat4x3\",\"mat4x4\",\"vec2\",\"vec3\",\"vec4\",\"bitcast\",\"all\",\"any\",\"select\",\"arrayLength\",\"abs\",\"acos\",\"acosh\",\"asin\",\"asinh\",\"atan\",\"atanh\",\"atan2\",\"ceil\",\"clamp\",\"cos\",\"cosh\",\"countLeadingZeros\",\"countOneBits\",\"countTrailingZeros\",\"cross\",\"degrees\",\"determinant\",\"distance\",\"dot\",\"dot4U8Packed\",\"dot4I8Packed\",\"exp\",\"exp2\",\"extractBits\",\"faceForward\",\"firstLeadingBit\",\"firstTrailingBit\",\"floor\",\"fma\",\"fract\",\"frexp\",\"insertBits\",\"inverseSqrt\",\"ldexp\",\"length\",\"log\",\"log2\",\"max\",\"min\",\"mix\",\"modf\",\"normalize\",\"pow\",\"quantizeToF16\",\"radians\",\"reflect\",\"refract\",\"reverseBits\",\"round\",\"saturate\",\"sign\",\"sin\",\"sinh\",\"smoothstep\",\"sqrt\",\"step\",\"tan\",\"tanh\",\"transpose\",\"trunc\",\"dpdx\",\"dpdxCoarse\",\"dpdxFine\",\"dpdy\",\"dpdyCoarse\",\"dpdyFine\",\"fwidth\",\"fwidthCoarse\",\"fwidthFine\",\"textureDimensions\",\"textureGather\",\"textureGatherCompare\",\"textureLoad\",\"textureNumLayers\",\"textureNumLevels\",\"textureNumSamples\",\"textureSample\",\"textureSampleBias\",\"textureSampleCompare\",\"textureSampleCompareLevel\",\"textureSampleGrad\",\"textureSampleLevel\",\"textureSampleBaseClampToEdge\",\"textureStore\",\"atomicLoad\",\"atomicStore\",\"atomicAdd\",\"atomicSub\",\"atomicMax\",\"atomicMin\",\"atomicAnd\",\"atomicOr\",\"atomicXor\",\"atomicExchange\",\"atomicCompareExchangeWeak\",\"pack4x8snorm\",\"pack4x8unorm\",\"pack4xI8\",\"pack4xU8\",\"pack4xI8Clamp\",\"pack4xU8Clamp\",\"pack2x16snorm\",\"pack2x16unorm\",\"pack2x16float\",\"unpack4x8snorm\",\"unpack4x8unorm\",\"unpack4xI8\",\"unpack4xU8\",\"unpack2x16snorm\",\"unpack2x16unorm\",\"unpack2x16float\",\"storageBarrier\",\"textureBarrier\",\"workgroupBarrier\",\"workgroupUniformLoad\",\"subgroupAdd\",\"subgroupExclusiveAdd\",\"subgroupInclusiveAdd\",\"subgroupAll\",\"subgroupAnd\",\"subgroupAny\",\"subgroupBallot\",\"subgroupBroadcast\",\"subgroupBroadcastFirst\",\"subgroupElect\",\"subgroupMax\",\"subgroupMin\",\"subgroupMul\",\"subgroupExclusiveMul\",\"subgroupInclusiveMul\",\"subgroupOr\",\"subgroupShuffle\",\"subgroupShuffleDown\",\"subgroupShuffleUp\",\"subgroupShuffleXor\",\"subgroupXor\",\"quadBroadcast\",\"quadSwapDiagonal\",\"quadSwapX\",\"quadSwapY\"]);function v$(e){if(e){let t=e.replaceAll(/\\s/g,\"_\").replaceAll(/[^\\w]/g,\"\");return Sh(t).success?t:\"item\"}return\"item\"}function Sh(e){return e===\"_\"||e===\"\"?{success:!1,error:\"Identifiers cannot be equal to '' or '_'\"}:/\\s/.test(e)?{success:!1,error:\"Identifiers cannot contain whitespace.\"}:e.startsWith(\"__\")?{success:!1,error:\"Identifiers cannot start with double underscores.\"}:/^(([_\\p{XID_Start}][\\p{XID_Continue}]+)|([\\p{XID_Start}]))$/u.test(e)?{success:!0}:{success:!1,error:\"Not compliant with WGSL guidelines.\"}}function BM(e){let t=Sh(e);return t.success?_3.has(e)?{success:!1,error:\"Identifiers cannot start with reserved keywords.\"}:{success:!0}:t}function gt(e){return Ph(e,!1)}function Fo(e){return Ph(e,!0)}function Ph(e,t){Object.keys(e).forEach(r=>{let o=BM(r);if(!o.success)throw new Error(`Invalid property key '${r}'${o.error?`: ${o.error}`:\"\"}`)});let s=r=>Object.fromEntries(Object.entries(e).map(([o,a])=>[o,rc(a,r?.[o])]));return Object.setPrototypeOf(s,h$),s.propTypes=e,Object.defineProperty(s,ve,{value:{isAbstruct:t}}),s}var h$={type:\"struct\",$name(e){return es(this,e),this},toString(){return`struct:${ct(this)??\"<unnamed>\"}`}},Co=(e,t)=>{let s=t-1,r=~s;return(e&s)===0?e:(e&r)+t},ws=class{[ve]={};type;[mo];constructor(e){this.type=e,this[mo]={call:(t,[s])=>oM(t,dl[this.type],s)}}[Ux](e){return rc(dl[this.type],e)}},dl={uint8:M,uint8x2:$s,uint8x4:Is,sint8:j,sint8x2:ir,sint8x4:sr,unorm8:n,unorm8x2:ps,unorm8x4:qt,snorm8:n,snorm8x2:ps,snorm8x4:qt,uint16:M,uint16x2:$s,uint16x4:Is,sint16:j,sint16x2:ir,sint16x4:sr,unorm16:n,unorm16x2:ps,unorm16x4:qt,snorm16:n,snorm16x2:ps,snorm16x4:qt,float16:n,float16x2:ps,float16x4:qt,float32:n,float32x2:ps,float32x3:Zs,float32x4:qt,uint32:M,uint32x2:$s,uint32x3:Ps,uint32x4:Is,sint32:j,sint32x2:ir,sint32x3:Br,sint32x4:sr,\"unorm10-10-10-2\":qt,\"unorm8x4-bgra\":qt},zM=new Set(Object.keys(dl)),hve=new ws(\"uint8\"),gve=new ws(\"uint8x2\"),yve=new ws(\"uint8x4\"),bve=new ws(\"sint8\"),xve=new ws(\"sint8x2\"),Ave=new ws(\"sint8x4\"),wve=new ws(\"unorm8\"),Tve=new ws(\"unorm8x2\"),Sve=new ws(\"unorm8x4\"),Pve=new ws(\"snorm8\"),Cve=new ws(\"snorm8x2\"),Mve=new ws(\"snorm8x4\"),Eve=new ws(\"uint16\"),kve=new ws(\"uint16x2\"),Bve=new ws(\"uint16x4\"),zve=new ws(\"sint16\"),Rve=new ws(\"sint16x2\"),Dve=new ws(\"sint16x4\"),Lve=new ws(\"unorm16\"),Uve=new ws(\"unorm16x2\"),Ove=new ws(\"unorm16x4\"),Gve=new ws(\"snorm16\"),Fve=new ws(\"snorm16x2\"),Ive=new ws(\"snorm16x4\"),Yve=new ws(\"float16\"),Wve=new ws(\"float16x2\"),qve=new ws(\"float16x4\"),Vve=new ws(\"float32\"),Nve=new ws(\"float32x2\"),$ve=new ws(\"float32x3\"),Xve=new ws(\"float32x4\"),Hve=new ws(\"uint32\"),jve=new ws(\"uint32x2\"),Kve=new ws(\"uint32x3\"),Qve=new ws(\"uint32x4\"),Zve=new ws(\"sint32\"),Jve=new ws(\"sint32x2\"),ehe=new ws(\"sint32x3\"),the=new ws(\"sint32x4\"),she=new ws(\"unorm10-10-10-2\"),rhe=new ws(\"unorm8x4-bgra\");function g$(e){return _s(e)&&zM.has(e?.type)}var y$={f32:4,f16:2,i32:4,u32:4,bool:4,u16:2,vec2f:8,vec2h:4,vec2i:8,vec2u:8,\"vec2<bool>\":8,vec3f:16,vec3h:8,vec3i:16,vec3u:16,\"vec3<bool>\":16,vec4f:16,vec4h:8,vec4i:16,vec4u:16,\"vec4<bool>\":16,mat2x2f:8,mat3x3f:16,mat4x4f:16,atomic:4};function b$(e){let t=e?.type,s=y$[t];if(s!==void 0)return s;if(_r(e))return Object.values(e.propTypes).map(xr).reduce((r,o)=>r>o?r:o);if(io(e))return xr(e.elementType);if(ki(e)){let r=Object.values(e.propTypes)[0];return r?Tm(r)??1:1}if(Sd(e))return Tm(e.elementType)??1;if(gl(e)||vc(e))return Tm(e)??xr(e.inner);if(zM.has(t))return 1;throw new Error(`Cannot determine alignment of data: ${pn(e)}`)}function x$(e){if(ki(e)){let t=Object.values(e.propTypes)[0];return t?wn(t):1}return Sd(e)?wn(e.elementType):vc(e)?Tm(e)??wn(e.inner):Tm(e)??1}var Xw=new WeakMap,Hw=new WeakMap;function xr(e){let t=Xw.get(e);return t===void 0&&(t=b$(e),Xw.set(e,t)),t}function wn(e){let t=Hw.get(e);return t===void 0&&(t=x$(e),Hw.set(e,t)),t}var A$={bool:4,f32:4,f16:2,i32:4,u32:4,u16:2,vec2f:8,vec2h:4,vec2i:8,vec2u:8,\"vec2<bool>\":8,vec3f:12,vec3h:6,vec3i:12,vec3u:12,\"vec3<bool>\":12,vec4f:16,vec4h:8,vec4i:16,vec4u:16,\"vec4<bool>\":16,mat2x2f:16,mat3x3f:48,mat4x4f:64,uint8:1,uint8x2:2,uint8x4:4,sint8:1,sint8x2:2,sint8x4:4,unorm8:1,unorm8x2:2,unorm8x4:4,snorm8:1,snorm8x2:2,snorm8x4:4,uint16:2,uint16x2:4,uint16x4:8,sint16:2,sint16x2:4,sint16x4:8,unorm16:2,unorm16x2:4,unorm16x4:8,snorm16:2,snorm16x2:4,snorm16x4:8,float16:2,float16x2:4,float16x4:8,float32:4,float32x2:8,float32x3:12,float32x4:16,uint32:4,uint32x2:8,uint32x3:12,uint32x4:16,sint32:4,sint32x2:8,sint32x3:12,sint32x4:16,\"unorm10-10-10-2\":4,\"unorm8x4-bgra\":4,atomic:4};function w$(e){let t=0,s=0,r=!0,o=!1;for(let i of Object.values(e.propTypes)){if(Number.isNaN(t))throw new Error(\"Only the last property of a struct can be unbounded\");let l=t;t=Co(t,xr(i));let c=l!==t,d=vd(i);if(t+=d.size,Number.isNaN(t)&&i.type!==\"array\")throw new Error(\"Cannot nest unbounded struct within another struct\");o||(!c&&d.isContiguous?s+=d.size:(o=!0,r=!1,c||(s+=d.longestContiguousPrefix)))}let a=Co(t,xr(e));return{isContiguous:t===a&&r,size:a,longestContiguousPrefix:s}}function T$(e){let t=0,s=0,r=!0,o=!1;for(let a of Object.values(e.propTypes)){let i=wn(a),l=t;t=Co(t,i);let c=l!==t;c&&(r=!1);let d=vd(a);t+=d.size,!o&&(!c&&d.isContiguous?s+=d.size:(o=!0,r=!1,c||(s+=d.longestContiguousPrefix)))}return{isContiguous:r,size:t,longestContiguousPrefix:s}}function S$(e){let t=e.elementType,s=vd(t),r=s.size,o=Co(r,xr(t)),a=!(o>r)&&s.isContiguous,i=e.elementCount===0?NaN:e.elementCount*o,l;return a?l=i:l=s.longestContiguousPrefix,{size:i,isContiguous:a,longestContiguousPrefix:l}}function P$(e){let t=e.elementType,s=vd(t),r=s.size,o=Co(r,wn(t)),a=!(o>r)&&s.isContiguous,i=e.elementCount*o,l;return a?l=i:l=s.longestContiguousPrefix,{size:i,isContiguous:a,longestContiguousPrefix:l}}function vd(e){let t=A$[e.type];if(t!==void 0)return{isContiguous:e.type!==\"mat3x3f\",size:t,longestContiguousPrefix:e.type===\"mat3x3f\"?12:t};if(_r(e))return w$(e);if(ki(e))return T$(e);if(io(e))return S$(e);if(Sd(e))return P$(e);if(gl(e)||vc(e)){let s=_N(e),r=vd(_n(e));return s?{isContiguous:s===r.size&&r.isContiguous,size:s,longestContiguousPrefix:r.longestContiguousPrefix}:vd(e.inner)}throw new Error(`Cannot determine memory layout of data: ${e}`)}var jw=new WeakMap;function f3(e,t){let s=jw.get(e);return s===void 0&&(s=vd(e),jw.set(e,s)),s[t]}function ds(e){return f3(e,\"size\")}function Kw(e){return ds(e)}var Fe=Tn(((e,t)=>{if(gl(e)&&!e.attribs.every(RC))throw new Error(\"Arrays cannot hold decorated types other than @location. Wrap it in a struct instead, e.g. d.arrayOf(d.struct({ value: d.align(16, d.u32) }), n).\");return t===void 0?Tn(s=>Qw(e,s)):Qw(e,t)})).$name(\"arrayOf\");function Qw(e,t){let s=r=>{if(r&&r.length!==t)throw new Error(`Array schema of ${t} elements of type ${e.type} called with ${r.length} argument(s).`);return Array.from({length:t},(o,a)=>rc(e,r?.[a]))};if(Object.setPrototypeOf(s,C$),Number.isNaN(ds(e)))throw new Error(\"Cannot nest runtime sized arrays.\");if(s.elementType=e,!Number.isInteger(t)||t<0)throw new Error(`Cannot create array schema with invalid element count: ${t}.`);return s.elementCount=t,s}var C$={[ve]:!0,type:\"array\",toString(){return`arrayOf(${String(this.elementType)}, ${this.elementCount})`}};function M$(e){if(\"multisampled\"in e){if(e.multisampled){if(e.dimension===\"2d\")return k$(e.sampleType);throw new Error(`Multisampled textures only support '2d' dimension, got '${e.dimension}'`)}switch(e.dimension){case\"1d\":return E$(e.sampleType);case\"2d\":return Zt(e.sampleType);case\"2d-array\":return B$(e.sampleType);case\"3d\":return D$(e.sampleType);case\"cube\":return z$(e.sampleType);case\"cube-array\":return R$(e.sampleType);default:throw new Error(`Unsupported texture dimension: '${e.dimension}'`)}}if(!(\"access\"in e))throw new Error(\"Descriptor is neither a sampled nor a storage texture\");switch(e.dimension){case\"1d\":return L$(e.format,e.access);case\"2d\":return zt(e.format,e.access);case\"2d-array\":return U$(e.format,e.access);case\"3d\":return O$(e.format,e.access);default:throw new Error(`Unsupported storage texture dimension: '${e.dimension}'`)}}function Cd(e,t){let s=e.startsWith(\"texture_depth\")?[\"depth\",\"float\",\"unfilterable-float\"]:t.sampleType.type===\"i32\"?[\"sint\"]:t.sampleType.type===\"u32\"?[\"uint\"]:[\"float\",\"unfilterable-float\"];return{[ve]:{},[Ku]:void 0,type:e,bindingSampleType:s,...t}}function Ch(e,t){return{[ve]:{},[Ku]:void 0,type:e,...t}}var Zw=new Map,u_={\"write-only\":\"write\",\"read-only\":\"read\",\"read-write\":\"read_write\"};function Cn(e,t){let s=Zw.get(e);return s||(s=t(),Zw.set(e,s)),s}function E$(e){let t=e||n;return Cn(`texture_1d<${t.type}>`,()=>Cd(\"texture_1d\",{dimension:\"1d\",sampleType:t,multisampled:!1}))}function Zt(e){let t=e||n;return Cn(`texture_2d<${t.type}>`,()=>Cd(\"texture_2d\",{dimension:\"2d\",sampleType:t,multisampled:!1}))}function k$(e){let t=e||n;return Cn(`texture_multisampled_2d<${t.type}>`,()=>Cd(\"texture_multisampled_2d\",{dimension:\"2d\",sampleType:t,multisampled:!0}))}function B$(e){let t=e||n;return Cn(`texture_2d_array<${t.type}>`,()=>Cd(\"texture_2d_array\",{dimension:\"2d-array\",sampleType:t,multisampled:!1}))}function z$(e){let t=e||n;return Cn(`texture_cube<${t.type}>`,()=>Cd(\"texture_cube\",{dimension:\"cube\",sampleType:t,multisampled:!1}))}function R$(e){let t=e||n;return Cn(`texture_cube_array<${t.type}>`,()=>Cd(\"texture_cube_array\",{dimension:\"cube-array\",sampleType:t,multisampled:!1}))}function D$(e){let t=e||n;return Cn(`texture_3d<${t.type}>`,()=>Cd(\"texture_3d\",{dimension:\"3d\",sampleType:t,multisampled:!1}))}function L$(e,t){let s=t||\"write-only\";return Cn(`texture_storage_1d<${e}, ${u_[s]}>`,()=>Ch(\"texture_storage_1d\",{dimension:\"1d\",format:e,access:s}))}function zt(e,t){let s=t||\"write-only\";return Cn(`texture_storage_2d<${e}, ${u_[s]}>`,()=>Ch(\"texture_storage_2d\",{dimension:\"2d\",format:e,access:s}))}function U$(e,t){let s=t||\"write-only\";return Cn(`texture_storage_2d_array<${e}, ${u_[s]}>`,()=>Ch(\"texture_storage_2d_array\",{dimension:\"2d-array\",format:e,access:s}))}function O$(e,t){let s=t||\"write-only\";return Cn(`texture_storage_3d<${e}, ${u_[s]}>`,()=>Ch(\"texture_storage_3d\",{dimension:\"3d\",format:e,access:s}))}function RM(){return Cn(\"texture_external\",()=>({[ve]:{},[Ku]:void 0,type:\"texture_external\",dimension:\"2d\"}))}function DM(e){return!!e[ve]&&typeof e.multisampled==\"boolean\"}function C1(e){return!!e[ve]&&typeof e.format==\"string\"&&typeof e.access==\"string\"}function G$(e){return!!e[ve]&&e.type===\"texture_external\"}function v3(){return{[ve]:{},type:\"sampler\",[Ku]:void 0}}function LM(){return{[ve]:{},type:\"sampler_comparison\",[Ku]:void 0}}function F$(e){return!!e[ve]&&e.type===\"sampler\"}function I$(e){return!!e[ve]&&e.type===\"sampler_comparison\"}var ohe=Tn(((e,t)=>t===void 0?s=>Jw(e,s):Jw(e,t))).$name(\"disarrayOf\");function Jw(e,t){let s=r=>{if(r&&r.length!==t)throw new Error(`Disarray schema of ${t} elements of type ${e.type} called with ${r.length} argument(s).`);return Array.from({length:t},(o,a)=>rc(e,r?.[a]))};if(Object.setPrototypeOf(s,Y$),s.elementType=e,!Number.isInteger(t)||t<0)throw new Error(`Cannot create disarray schema with invalid element count: ${t}.`);return s.elementCount=t,s}var Y$={[ve]:!0,type:\"disarray\",toString(){return`disarrayOf(${this.elementType}, ${this.elementCount})`}};var ahe={[ve]:!0,type:\"unstruct\",$name(e){return es(this,e),this},toString(){return`unstruct:${ct(this)??\"<unnamed>\"}`}};function lo(e){return new W$(e)}var W$=class{[ve]={};type=\"atomic\";inner;constructor(e){this.inner=e}};function Mh(e,t){return gl(e)?new e7(e.inner,[t,...e.attribs]):vc(e)?new t7(e.inner,[t,...e.attribs]):yh(e)?new t7(e,[t]):new e7(e,[t])}function UM(e,t){return Mh(t,{[ve]:!0,type:\"@align\",params:[e]})}function OM(e,t){return Mh(t,{[ve]:!0,type:\"@size\",params:[e]})}function ub(e,t){return Mh(t,{[ve]:!0,type:\"@location\",params:[e]})}function wi(e){return(gl(e)||vc(e))&&e.attribs.find(sN)!==void 0}function Ym(e){return!gl(e)&&!vc(e)?\"\":e.attribs.map(t=>t.params.length===0?`${t.type} `:`${t.type}(${t.params.join(\", \")}) `).join(\"\")}var GM=class{[ve]={};inner;attribs;constructor(e,t){this.inner=e,this.attribs=t;let s=t.find(BC)?.params[0],r=t.find(zC)?.params[0];if(s!==void 0){if(s<=0)throw new Error(`Custom data alignment must be a positive number, got: ${s}.`);if(Math.log2(s)%1!==0)throw new Error(`Alignment has to be a power of 2, got: ${s}.`);if(Td(this.inner)&&s%xr(this.inner)!==0)throw new Error(`Custom alignment has to be a multiple of the standard data alignment. Got: ${s}, expected multiple of: ${xr(this.inner)}.`)}if(r!==void 0){if(r<ds(this.inner))throw new Error(`Custom data size cannot be smaller then the standard data size. Got: ${r}, expected at least: ${ds(this.inner)}.`);if(r<=0)throw new Error(`Custom data size must be a positive number. Got: ${r}.`)}}},e7=class extends GM{[ve]={};type=\"decorated\"},t7=class extends GM{[ve]={};type=\"loose-decorated\"};function FM(e){return f3(e,\"isContiguous\")}function IM(e){return f3(e,\"longestContiguousPrefix\")}var YM=Object.defineProperty,q$=(e,t,s)=>t in e?YM(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s,V$=(e,t)=>{for(var s in t)YM(e,s,{get:t[s],enumerable:!0})},Ls=(e,t,s)=>q$(e,typeof t!=\"symbol\"?t+\"\":t,s);V$({},{BufferReader:()=>ep,BufferWriter:()=>Md,MaxValue:()=>ao,Measurer:()=>Nr,UnresolvedReferenceError:()=>Xc,ValidationError:()=>Eh,arrayOf:()=>j$,bool:()=>Q$,byte:()=>sX,chars:()=>vX,concat:()=>bX,dynamicArrayOf:()=>AX,f16:()=>pX,f32:()=>_X,f32Array:()=>GX,f64Array:()=>FX,generic:()=>gX,genericEnum:()=>yX,i16:()=>oX,i16Array:()=>UX,i32:()=>lX,i32Array:()=>OX,i8:()=>eX,i8Array:()=>LX,keyed:()=>SX,object:()=>hX,optional:()=>CX,string:()=>Z$,tupleOf:()=>kX,u16:()=>nX,u16Array:()=>RX,u32:()=>dX,u32Array:()=>DX,u8:()=>$M,u8Array:()=>BX,u8ClampedArray:()=>zX});var Xc=class WM extends Error{constructor(t){super(t),Object.setPrototypeOf(this,WM.prototype)}},Eh=class qM extends Error{constructor(t){super(t),Object.setPrototypeOf(this,qM.prototype)}},N$=class{constructor(){Ls(this,\"size\",NaN),Ls(this,\"unbounded\",this),Ls(this,\"isUnbounded\",!0)}add(){return this}fork(){return this}},$$=new N$,Nr=class VM{constructor(){Ls(this,\"size\",0),Ls(this,\"unbounded\",$$),Ls(this,\"isUnbounded\",!1)}add(t){return this.size+=t,this}fork(){let t=new VM;return t.size=this.size,t}},ao=Symbol(\"The biggest (in amount of bytes needed) value a schema can represent\"),Vo=class{constructor(){Ls(this,\"__unwrapped\")}resolveReferences(e){}seekProperty(e,t){return null}},X$=class{constructor(e){this.key=e}},Pm={STRING:\"string\",ENUM:\"enum\"},H$=class extends Vo{constructor(e,t){super(),this._unstableElementSchema=e,this.length=t,Ls(this,\"elementSchema\"),this.elementSchema=e}resolveReferences(e){this.elementSchema=e.resolve(this._unstableElementSchema)}write(e,t){if(t.length!==this.length)throw new Eh(`Expected array of length ${this.length}, got ${t.length}`);for(let s of t)this.elementSchema.write(e,s)}read(e){let t=[];for(let s=0;s<this.length;++s)t.push(this.elementSchema.read(e));return t}get maxSize(){return this.elementSchema.measure(ao).size*this.length}measure(e,t=new Nr){for(let s=0;s<this.length;++s)this.elementSchema.measure(e===ao?ao:e[s],t);return t}};function j$(e,t){return new H$(e,t)}var K$=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",1)}read(e){return e.readBool()}write(e,t){e.writeBool(t)}measure(e,t=new Nr){return t.add(1)}},Q$=new K$,NM=class vm extends Vo{static get _encoder(){return vm._cachedEncoder||(vm._cachedEncoder=new TextEncoder),vm._cachedEncoder}read(t){return t.readString()}write(t,s){t.writeString(s)}measure(t,s=new Nr){if(t===ao)return s.unbounded;let r=vm._encoder.encode(t);return s.add(r.byteLength+1)}};Ls(NM,\"_cachedEncoder\");var Z$=new NM,J$=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",1)}read(e){return e.readInt8()}write(e,t){e.writeInt8(t)}measure(e,t=new Nr){return t.add(1)}},eX=new J$,tX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",1)}read(e){return e.readUint8()}write(e,t){e.writeUint8(t)}measure(e,t=new Nr){return t.add(1)}},$M=new tX,sX=$M,rX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",2)}read(e){return e.readInt16()}write(e,t){e.writeInt16(t)}measure(e,t=new Nr){return t.add(2)}},oX=new rX,aX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",2)}read(e){return e.readUint16()}write(e,t){e.writeUint16(t)}measure(e,t=new Nr){return t.add(2)}},nX=new aX,iX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",4)}read(e){return e.readInt32()}write(e,t){e.writeInt32(t)}measure(e,t=new Nr){return t.add(4)}},lX=new iX,cX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",4)}read(e){return e.readUint32()}write(e,t){e.writeUint32(t)}measure(e,t=new Nr){return t.add(4)}},dX=new cX,uX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",2)}read(e){return e.readFloat16()}write(e,t){e.writeFloat16(t)}measure(e,t=new Nr){return t.add(2)}},pX=new uX,mX=class extends Vo{constructor(){super(...arguments),Ls(this,\"maxSize\",4)}read(e){return e.readFloat32()}write(e,t){e.writeFloat32(t)}measure(e,t=new Nr){return t.add(4)}},_X=new mX,fX=class extends Vo{constructor(e){super(),this.length=e}write(e,t){if(t.length!==this.length)throw new Eh(`Expected char-string of length ${this.length}, got ${t.length}`);for(let s=0;s<t.length;++s)e.writeUint8(t.charCodeAt(s))}read(e){let t=\"\";for(let s=0;s<this.length;++s)t+=String.fromCharCode(e.readByte());return t}measure(e,t=new Nr){return t.add(this.length)}};function vX(e){return new fX(e)}function $l(e){return Object.entries(e)}function XM(e,t){let s={};for(let[r,o]of $l(t))s[r]=e.resolve(o);return s}var h3=class extends Vo{constructor(e){super(),this._properties=e,Ls(this,\"properties\"),this.properties=e}resolveReferences(e){this.properties=XM(e,this._properties)}write(e,t){for(let[s,r]of $l(this.properties))r.write(e,t[s])}read(e){let t={};for(let[s,r]of $l(this.properties))t[s]=r.read(e);return t}get maxSize(){let e=new Nr;for(let t of Object.values(this.properties))t.measure(ao,e);return e.size}measure(e,t=new Nr){for(let[s,r]of $l(this.properties))r.measure(e===ao?ao:e[s],t);return t}seekProperty(e,t){let s=0;for(let[r,o]of $l(this.properties)){if(r===t)return{bufferOffset:s,schema:o};s+=o.measure(e).size}return null}};function hX(e){return new h3(e)}var HM=class extends Vo{constructor(e,t,s){super(),this.keyedBy=e,this._subTypeMap=s,Ls(this,\"_baseObject\"),Ls(this,\"subTypeMap\"),this._baseObject=new h3(t),this.subTypeMap=s}resolveReferences(e){this._baseObject.resolveReferences(e),this.subTypeMap=XM(e,this._subTypeMap)}write(e,t){let s=t.type,r=this.subTypeMap[s]||null;if(r===null)throw new Error(`Unknown sub-type '${s.toString()}' in among '${JSON.stringify(Object.keys(this.subTypeMap))}'`);this.keyedBy===Pm.ENUM?e.writeUint8(t.type):e.writeString(t.type),this._baseObject.write(e,t);for(let[o,a]of $l(r.properties))a.write(e,t[o])}read(e){let t=this.keyedBy===Pm.ENUM?e.readByte():e.readString(),s=this.subTypeMap[t]||null;if(s===null)throw new Error(`Unknown sub-type '${t}' in among '${JSON.stringify(Object.keys(this.subTypeMap))}'`);let r=this._baseObject.read(e);if(r.type=t,s!==null)for(let[o,a]of $l(s.properties))r[o]=a.read(e);return r}measure(e,t=new Nr){if(this._baseObject.measure(e,t),this.keyedBy===Pm.ENUM)t.add(1);else if(e!==ao)t.add(e.type.length+1);else return t.unbounded;if(e===ao){let s=Object.values(this.subTypeMap).map(r=>{let o=t.fork();for(let a of Object.values(r.properties))a.measure(ao,o);return[r,o.size]}).reduce((r,o)=>r[1]>o[1]?r:o)[0];for(let r of Object.values(s.properties))r.measure(ao,t)}else{let s=e.type,r=this.subTypeMap[s]||null;if(r===null)throw new Error(`Unknown sub-type '${s.toString()}', expected one of '${JSON.stringify(Object.keys(this.subTypeMap))}'`);for(let[o,a]of $l(r.properties))a.measure(e[o],t)}return t}};function gX(e,t){return new HM(Pm.STRING,e,t)}function yX(e,t){return new HM(Pm.ENUM,e,t)}function bX(e){return new h3(Object.fromEntries(e.flatMap(({properties:t})=>Object.entries(t))))}var xX=class extends Vo{constructor(e){super(),this._unstableElementType=e,Ls(this,\"elementType\"),this.elementType=e}resolveReferences(e){this.elementType=e.resolve(this._unstableElementType)}write(e,t){e.writeUint32(t.length);for(let s of t)this.elementType.write(e,s)}read(e){let t=[],s=e.readUint32();for(let r=0;r<s;++r)t.push(this.elementType.read(e));return t}get maxSize(){return this.measure(ao).size}measure(e,t=new Nr){if(e===ao)return t.unbounded;t.add(4);for(let s of e)this.elementType.measure(s,t);return t}seekProperty(e,t){if(typeof t==\"symbol\")return null;let s=Number.parseInt(String(t),10);if(Number.isNaN(s))return null;if(e===ao)return{bufferOffset:this.elementType.measure(ao).size*s,schema:this.elementType};if(s>=e.length)return null;let r=new Nr;for(let o=0;o<s;++o)this.elementType.measure(e[o],r);return{bufferOffset:r.size,schema:this.elementType}}};function AX(e){return new xX(e)}var jM=class{constructor(e){Ls(this,\"__unwrapped\"),Ls(this,\"ref\"),this.ref=new X$(e)}resolveReferences(){throw new Xc(\"Tried to resolve a reference directly. Do it through a RefResolver instead.\")}read(){throw new Xc(\"Tried to read a reference directly. Resolve it instead.\")}write(){throw new Xc(\"Tried to write a reference directly. Resolve it instead.\")}measure(){throw new Xc(\"Tried to measure size of a reference directly. Resolve it instead.\")}seekProperty(){throw new Xc(\"Tried to seek property of a reference directly. Resolve it instead.\")}},wX=class{constructor(){Ls(this,\"registry\",{})}hasKey(e){return this.registry[e]!==void 0}register(e,t){this.registry[e]=t}resolve(e){if(e instanceof jM){let t=e.ref.key;if(this.registry[t]!==void 0)return this.registry[t];throw new Xc(`Couldn't resolve reference to ${t}. Unknown key.`)}return e.resolveReferences(this),e}},TX=class{constructor(e,t){this.key=e,Ls(this,\"__unwrapped\"),Ls(this,\"__keyDefinition\"),Ls(this,\"innerType\"),this.innerType=t(new jM(e)),this.resolveReferences(new wX)}resolveReferences(e){e.hasKey(this.key)||(e.register(this.key,this.innerType),this.innerType.resolveReferences(e))}read(e){return this.innerType.read(e)}write(e,t){this.innerType.write(e,t)}get maxSize(){return this.measure(ao).size}measure(e,t=new Nr){return this.innerType.measure(e,t)}seekProperty(e,t){return this.innerType.seekProperty(e,t)}};function SX(e,t){return new TX(e,t)}var PX=class extends Vo{constructor(e){super(),this._innerUnstableSchema=e,Ls(this,\"innerSchema\"),this.innerSchema=e}resolveReferences(e){this.innerSchema=e.resolve(this._innerUnstableSchema)}write(e,t){t!=null?(e.writeBool(!0),this.innerSchema.write(e,t)):e.writeBool(!1)}read(e){if(e.readBool())return this.innerSchema.read(e)}get maxSize(){return this.measure(ao).size}measure(e,t=new Nr){return e!==void 0&&this.innerSchema.measure(e,t),t.add(1)}};function CX(e){return new PX(e)}function MX(e,t){return t.map(s=>e.resolve(s))}var EX=class extends Vo{constructor(e){super(),this._unstableSchemas=e,Ls(this,\"schemas\"),this.schemas=e}resolveReferences(e){this.schemas=MX(e,this._unstableSchemas)}write(e,t){if(t.length!==this.schemas.length)throw new Eh(`Expected tuple of length ${this.schemas.length}, got ${t.length}`);for(let s=0;s<this.schemas.length;++s)this.schemas[s].write(e,t[s])}read(e){let t=[];for(let s=0;s<this.schemas.length;++s)t.push(this.schemas[s].read(e));return t}get maxSize(){return this.measure(ao).size}measure(e,t=new Nr){for(let s=0;s<this.schemas.length;++s)this.schemas[s].measure(e===ao?ao:e[s],t);return t}};function kX(e){return new EX(e)}var xl=class extends Vo{constructor(e,t){super(),this.length=e,this._arrayConstructor=t,Ls(this,\"byteLength\"),this.byteLength=e*t.BYTES_PER_ELEMENT}write(e,t){e.writeSlice(t)}read(e){let t=new ArrayBuffer(this.byteLength),s=new this._arrayConstructor(t,0,this.length);return e.readSlice(s,0,this.byteLength),s}measure(e,t=new Nr){return t.add(this.byteLength)}},BX=e=>new xl(e,Uint8Array),zX=e=>new xl(e,Uint8ClampedArray),RX=e=>new xl(e,Uint16Array),DX=e=>new xl(e,Uint32Array),LX=e=>new xl(e,Int8Array),UX=e=>new xl(e,Int16Array),OX=e=>new xl(e,Int32Array),GX=e=>new xl(e,Float32Array),FX=e=>new xl(e,Float64Array);function IX(){let e=new Uint8Array(4),t=new Uint32Array(e.buffer);return t[0]=1,e[0]===0}function g3(){return IX()?\"big\":\"little\"}function y3(e){let t=0,s=e;return s&&\"buffer\"in s&&\"byteOffset\"in s&&(t+=s.byteOffset,s=s.buffer),{buffer:s,byteOffset:t,byteLength:e.byteLength}}var KM=class{constructor(e,t){Ls(this,\"dataView\"),Ls(this,\"littleEndian\"),Ls(this,\"needsByteSwap\"),Ls(this,\"byteOffset\",0),Ls(this,\"endianness\");let{byteOffset:s=0,endianness:r=\"system\"}=t??{};this.byteOffset=s;let o=g3();this.endianness=r===\"system\"?o:r,this.littleEndian=this.endianness===\"little\",this.needsByteSwap=this.endianness!==o;let a=y3(e);this.byteOffset+=a.byteOffset,this.dataView=new DataView(a.buffer)}get currentByteOffset(){return this.byteOffset}seekTo(e){this.byteOffset=e}skipBytes(e){this.byteOffset+=e}},ep=class extends KM{constructor(){super(...arguments),Ls(this,\"_cachedTextDecoder\")}get _textDecoder(){return this._cachedTextDecoder||(this._cachedTextDecoder=new TextDecoder(void 0,{fatal:!0})),this._cachedTextDecoder}readBool(){return this.dataView.getUint8(this.byteOffset++)!==0}readByte(){return this.dataView.getUint8(this.byteOffset++)}readInt8(){return this.dataView.getInt8(this.byteOffset++)}readUint8(){return this.dataView.getUint8(this.byteOffset++)}readInt16(){let e=this.dataView.getInt16(this.byteOffset,this.littleEndian);return this.byteOffset+=2,e}readUint16(){let e=this.dataView.getUint16(this.byteOffset,this.littleEndian);return this.byteOffset+=2,e}readInt32(){let e=this.dataView.getInt32(this.byteOffset,this.littleEndian);return this.byteOffset+=4,e}readUint32(){let e=this.dataView.getUint32(this.byteOffset,this.littleEndian);return this.byteOffset+=4,e}readFloat16(){let e=this.dataView.getFloat16(this.byteOffset,this.littleEndian);return this.byteOffset+=2,e}readFloat32(){let e=this.dataView.getFloat32(this.byteOffset,this.littleEndian);return this.byteOffset+=4,e}readString(){let e=0;for(;this.byteOffset+e<this.dataView.byteLength&&this.dataView.getUint8(this.byteOffset+e++)!==0;);let t=this._textDecoder.decode(new Uint8Array(this.dataView.buffer,this.byteOffset,e-1));return this.byteOffset+=e,t}readSlice(e,t,s){let r=y3(e),o=new Uint8Array(r.buffer,r.byteOffset+t),a=e.BYTES_PER_ELEMENT;if(this.needsByteSwap&&a>1)for(let i=0;i<s;i+=a)for(let l=a-1;l>=0;l--)o[i+l]=this.dataView.getUint8(this.byteOffset++);else o.set(new Uint8Array(this.dataView.buffer,this.byteOffset,s)),this.byteOffset+=s}},Md=class extends KM{constructor(){super(...arguments),Ls(this,\"_cachedTextEncoder\")}get _textEncoder(){return this._cachedTextEncoder||(this._cachedTextEncoder=new TextEncoder),this._cachedTextEncoder}writeBool(e){this.dataView.setUint8(this.byteOffset++,e?1:0)}writeByte(e){this.dataView.setUint8(this.byteOffset++,e)}writeInt8(e){this.dataView.setInt8(this.byteOffset++,e)}writeUint8(e){this.dataView.setUint8(this.byteOffset++,e)}writeInt16(e){this.dataView.setInt16(this.byteOffset,e,this.littleEndian),this.byteOffset+=2}writeUint16(e){this.dataView.setUint16(this.byteOffset,e,this.littleEndian),this.byteOffset+=2}writeInt32(e){this.dataView.setInt32(this.byteOffset,e,this.littleEndian),this.byteOffset+=4}writeUint32(e){this.dataView.setUint32(this.byteOffset,e,this.littleEndian),this.byteOffset+=4}writeFloat16(e){this.dataView.setFloat16(this.byteOffset,e,this.littleEndian),this.byteOffset+=2}writeFloat32(e){this.dataView.setFloat32(this.byteOffset,e,this.littleEndian),this.byteOffset+=4}writeString(e){let t=this._textEncoder.encodeInto(e,new Uint8Array(this.dataView.buffer,this.byteOffset));this.byteOffset+=t.written,this.dataView.setUint8(this.byteOffset++,0)}writeSlice(e){let t=y3(e),s=new Uint8Array(t.buffer,t.byteOffset,t.byteLength),r=e.BYTES_PER_ELEMENT;if(this.needsByteSwap&&r>1)for(let o=0;o<s.length;o+=r)for(let a=r-1;a>=0;a--)this.dataView.setUint8(this.byteOffset++,s[o+a]);else new Uint8Array(this.dataView.buffer,this.byteOffset).set(s),this.byteOffset+=s.length}};function YX(e,t){let s=\"size\"in e?e.size:e.currentByteOffset,r=t-1,o=s&r;\"skipBytes\"in e?e.skipBytes(t-o&r):e.add(t-o&r)}var wo=YX,s7=new WeakMap;function kh(e){let t=s7.get(e);if(t)return t;let s=new Nr,r={},o;for(let a in e.propTypes){let i=e.propTypes[a];if(i===void 0)throw new Error(`Property ${a} is undefined in struct`);let l=s.size;wo(s,ki(e)?wn(i):xr(i)),o&&(o.padding=s.size-l);let c=ds(i);r[a]={offset:s.size,size:c},o=r[a],s.add(c)}return o&&(o.padding=Co(ds(e),xr(e))-s.size),s7.set(e,r),r}var oc=Symbol(\"indirectOffset\"),ac=Symbol(\"indirectContiguous\");function WX(e){return typeof e==\"object\"&&e!==null&&oc in e&&ac in e}function hm(e,t){return{[oc]:e,[ac]:t}}function b3(e,t){if(t===oc)return e[oc];if(t===ac)return e[ac]}function x3(e,t,s=ds(e)){let r=_n(e),o=js(r)?r.componentCount:void 0;if(o!==void 0){let a=ds(r.primitive);return VX(hm(t,s),a,o)}return _r(r)?$X(r,hm(t,s)):io(r)?NX(r,hm(t,s)):hm(t,s)}function qX(e,t=0){return x3(e,t,ds(e))}function VX(e,t,s){let r=e[oc];return new Proxy(e,{get(o,a){let i=b3(o,a);if(i!==void 0)return i;let l=a===\"x\"||a===\"0\"?0:a===\"y\"||a===\"1\"?1:a===\"z\"||a===\"2\"?2:a===\"w\"||a===\"3\"?3:-1;if(l<0||l>=s)return;let c=l*t,d=Math.max(0,o[ac]-c);return hm(r+c,d)}})}function NX(e,t){let s=e.elementType,r=ds(s),o=Co(r,xr(s)),a=o>r;return new Proxy(t,{get(i,l){let c=b3(i,l);if(c!==void 0)return c;if(l===\"length\")return e.elementCount;if(typeof l!=\"string\")return;let d=Number(l);if(!Number.isInteger(d)||d<0||d>=e.elementCount)return;let u=d*o,p=FM(s)?Math.max(0,i[ac]-u):r+IM(s),_=a?Math.min(p,r):p;return x3(s,i[oc]+u,_)}})}function $X(e,t){let s=kh(e),r=e.propTypes,o=Object.keys(r),a=new Map,i=0;for(let l=0;l<o.length;l++){let c=o[l];if(!c)continue;let d=r[c];if(!d)continue;let u=s[c],p=u.padding??0,_=FM(d);if(!(l===o.length-1||p>0||!_))continue;let f=u.offset+(_?u.size:IM(d));for(let h=i;h<=l;h++){let g=o[h];if(!g)continue;let y=s[g];a.set(g,{offset:y.offset,runEnd:f})}i=l+1}return new Proxy(t,{get(l,c){let d=b3(l,c);if(d!==void 0)return d;if(typeof c!=\"string\")return;let u=a.get(c);if(!u)return;let p=Math.max(0,l[ac]-u.offset),_=Math.max(0,u.runEnd-u.offset),f=r[c];if(f)return x3(f,l[oc]+u.offset,ds(e)===u.runEnd?p:_)}})}function XX(e){let t=_n(e);if(_r(t)){let s=kh(t),r=t.propTypes,o=Object.keys(r);for(let a=0;a<o.length;a++){let i=o[a];if(!i)continue;let l=s[i],c=l.padding??0,d=l.offset+l.size;if(a===o.length-1||c>0)return d}return 0}if(io(t)){let s=t.elementType,r=ds(s),o=Co(r,xr(s)),a=ds(e);return Number.isFinite(a)?o>r?r:a:r}return ds(e)}function M1(e,t){if(!t)return{offset:0,contiguous:XX(e)};let s=t(qX(e));if(WX(s))return{offset:s[oc],contiguous:s[ac]};throw new Error(\"memoryLayoutOf: accessor did not return a schema element. Make sure the accessor navigates to a field or element of the schema (e.g. `(s) => s.position.x`).\")}function po(e,t){return Mh(e,{[ve]:!0,type:\"@builtin\",params:[t]})}var Qo={vertexIndex:po(M,\"vertex_index\"),instanceIndex:po(M,\"instance_index\"),clipDistances:po(Fe(M,8),\"clip_distances\"),position:po(qt,\"position\"),frontFacing:po(ys,\"front_facing\"),fragDepth:po(n,\"frag_depth\"),primitiveIndex:po(M,\"primitive_index\"),sampleIndex:po(M,\"sample_index\"),sampleMask:po(M,\"sample_mask\"),localInvocationId:po(Ps,\"local_invocation_id\"),localInvocationIndex:po(M,\"local_invocation_index\"),globalInvocationId:po(Ps,\"global_invocation_id\"),globalInvocationIndex:po(M,\"global_invocation_index\"),workgroupId:po(Ps,\"workgroup_id\"),workgroupIndex:po(M,\"workgroup_index\"),numWorkgroups:po(Ps,\"num_workgroups\"),subgroupInvocationId:po(M,\"subgroup_invocation_id\"),subgroupSize:po(M,\"subgroup_size\"),subgroupId:po(M,\"subgroup_id\"),numSubgroups:po(M,\"num_subgroups\")};var nhe=(qo(),Wa),m=(qo(),ps),ihe=(qo(),To),nc=(qo(),ir),fe=(qo(),$s),lhe=(qo(),qa),A=(qo(),Zs),che=(qo(),Pa),dhe=(qo(),Br),id=(qo(),Ps),uhe=(qo(),Va),S=(qo(),qt),phe=(qo(),So),mhe=(qo(),sr),_he=(qo(),Is),fhe=(qo(),yl),tp=(qo(),bl),vhe=(qo(),Eo);function HX(e){return e?.[Ka]}function A3(e,t={}){let s=0,r=new Set;return Object.fromEntries(Object.entries(e??{}).map(([o,a])=>{let i=sc(a);if(i!==void 0){if(r.has(i))throw new Error(\"Duplicate custom location attributes found\");r.add(i)}return[o,a]}).map(([o,a])=>{if(wi(a))return[o,a];if(sc(a)!==void 0)return[o,a];if(t[o])return[o,ub(t[o],a)];for(;r.has(s);)s++;return[o,ub(s++,a)]}))}function QM(e,t={}){let s=[],r={};for(let[o,a]of Object.entries(e))wi(a)?s.push({schemaKey:o,type:a}):r[o]=a;return{dataSchema:Object.keys(r).length>0?Ph(A3(r,t),!1):void 0,positionalArgs:s}}function jX(e){let t=A3(e);return{dataSchema:void 0,positionalArgs:Object.entries(t).map(([s,r])=>({schemaKey:s,type:r}))}}function p_(e,t={}){return o_(e)?hh(e)||wi(e)||sc(e)!==void 0?e:ub(0,e):Ph(A3(e,t),!1)}var ti=class{#e;#t;#s;#r;#o;#a;constructor(e,t,s){this.#e=e,this.#a=t,this.#t={},this.#r=s,this.#s=new Set}accessProp(e){let t=this.#e[e]??this.#a;if(t)return this.provideProp(e,t)}provideProp(e,t){let s=this.#t[e];if(!s){let r=e.replaceAll(\"$\",\"\");if(this.#s.has(r))throw new Error(`Property name '${r}' causes naming clashes. Choose a different name.`);let o=BM(r);if(!o.success)throw new Error(`Invalid property key '${e}'${o.error?`: ${o.error}`:\"\"}`);this.#s.add(r),s={prop:r,type:t},this.#t[e]=s}return s}get completeStruct(){if(!this.#o){this.#o=p_(Object.fromEntries(Object.values(this.#t).map(t=>[t.prop,t.type])),this.#r);let e=ct(this);e&&es(this.#o,e)}return this.#o}[Ws](e){return e.resolve(this.completeStruct)}toString(){return`auto-struct:${ct(this)??\"<unnamed>\"}`}};ti.prototype[ve]={};ti.prototype.type=\"auto-struct\";var ZM=class{[ve]={};type=\"entry-input-router\";structArg;positionalArgsMap;constructor(e,t){this.structArg=e,this.positionalArgsMap=new Map(t.map(s=>[s.schemaKey,s.arg]))}toString(){return\"entry-input-router\"}accessProp(e){let t=this.positionalArgsMap.get(e);if(t)return t();let s=this.structArg?.();if(s&&_r(s.dataType))return{target:s,prop:e}}},KX=[\"vec2f\",\"vec3f\",\"vec4f\",\"vec2h\",\"vec3h\",\"vec4h\",\"vec2i\",\"vec3i\",\"vec4i\",\"vec2u\",\"vec3u\",\"vec4u\",\"mat2x2f\",\"mat3x3f\",\"mat4x4f\"],QX={f:{1:n,2:ps,3:Zs,4:qt},h:{1:Vr,2:To,3:Pa,4:So},i:{1:j,2:ir,3:Br,4:sr},u:{1:M,2:$s,3:Ps,4:Is},b:{1:ys,2:Wa,3:qa,4:Va}};function Cu(e,t){if(KX.includes(e.dataType.type)&&t in db){let r=db[t];return Je(new m3(e,r),Ns,e.origin,e.possibleSideEffects)}if(io(e.dataType)&&t===\"length\")return e.dataType.elementCount===0?Je(Ne`arrayLength(&${e})`,M,\"runtime\",e.possibleSideEffects):Ai(e.dataType.elementCount);if(xi(e.dataType)&&t===\"columns\")return Je(new jC(e),Ns,e.origin,e.possibleSideEffects);if(_r(e.dataType)||ki(e.dataType))return aM(e,t);if(e.dataType instanceof ti){let r=e.dataType.accessProp(t);return r?Je(Ne`${e}.${r.prop}`,r.type,\"argument\",e.possibleSideEffects):void 0}if(e.dataType instanceof ZM){let r=e.dataType.accessProp(t);return n_(r)?r:r?Cu(r.target,r.prop):void 0}if(ta(e.dataType)){let r=qx(e);return t===\"$\"?r:Cu(r,t)}if(js(e.dataType)&&t===\"kind\")return Je(e.dataType.type,Ns,\"constant\",!1);let s=t.length;if(js(e.dataType)&&s>=1&&s<=4&&/^[xyzw]+$|^[rgba]+$/.test(t)){let r=QX[e.dataType.type.includes(\"bool\")?\"b\":e.dataType.type[4]][s];return r?Je(qr(e)?e.value[t]:Ne`${e}.${t}`,r,s===1?e.origin:e.origin===\"constant\"||e.origin===\"constant-immutable-def\"?\"constant\":\"runtime\",e.possibleSideEffects):void 0}if(qr(e)||e.dataType===Ns){let r=e.value[t];return Su(r)&&ct(r)===void 0&&es(r,t),Ya(r)}}var r7={mat2x2f:ps,mat3x3f:Zs,mat4x4f:qt};function Bh(e,t){let s=typeof t==\"number\"?Ya(t):t;if(io(e.dataType)||Sd(e.dataType)){let r=e.dataType.elementType,o;return e.origin===\"constant-immutable-def\"?o=s.origin===\"constant\"||s.origin===\"constant-immutable-def\"?\"constant-immutable-def\":\"runtime-immutable-def\":e.origin===\"constant\"?o=s.origin===\"constant\"||s.origin===\"constant-immutable-def\"?\"constant\":\"runtime\":o=e.origin,e.value instanceof Sm&&qr(s)?e.value.elements[s.value]:Je(qr(e)&&qr(s)?e.value[s.value]:Ne`${e}[${s}]`,r,o,e.possibleSideEffects||s.possibleSideEffects)}if(js(e.dataType))return Je(qr(e)&&qr(s)?e.value[s.value]:Ne`${e}[${s}]`,e.dataType.primitive,e.origin,e.possibleSideEffects||s.possibleSideEffects);if(ta(e.dataType))return Bh(qx(e),s);if(e.value instanceof jC){let r=r7[e.value.matrix.dataType.type];return Je(Ne`${e.value.matrix}[${s}]`,r,e.origin,e.possibleSideEffects||s.possibleSideEffects)}if(e.dataType.type in r7)throw new Error(\"The only way of accessing matrix elements in TypeGPU functions is through the 'columns' property.\");if(qr(e)&&qr(s))return Ya(e.value[s.value]);if(_r(e.dataType)&&qr(s)&&typeof s.value==\"string\")return Cu(e,s.value)}var Mu={get(e,t){if(t in e)return Reflect.get(e,t);if(t===\"toString\"||t===Symbol.toStringTag||t===Symbol.toPrimitive)return()=>e.toString();if(typeof t==\"symbol\")return;let s=bh(e),r=Number(t);if(!Number.isNaN(r)){let a=Bh(s,r);return a?new Proxy({[ve]:!0,[Ws]:i=>i.resolveSnippet(a),[tc]:a,toString:()=>`${String(e)}[${t}]`},Mu):void 0}let o=Cu(s,String(t));if(o)return new Proxy({[ve]:!0,[Ws]:a=>a.resolveSnippet(o),[tc]:o,toString:()=>`${String(e)}.${t}`},Mu)}};function K1(e){let t=e;for(;;){let s=HX(t);if(!s)break;t=s}return t}function Bi(e,t){return Object.defineProperty(e,Ka,{get(){if(\"get\"in t.codegenMode)return t.codegenMode.get.apply(this);let s=this;return new Proxy({[ve]:!0,get[tc](){if(!(\"getBaseSnippet\"in t.codegenMode))throw new Error(\"Expected 'getBaseSnippet' to be defined.\");return t.codegenMode.getBaseSnippet.apply(s,[this])},[Ws]:r=>r.resolve(s),toString:()=>`${s.toString()}.$`},Mu)}}),Object.defineProperty(e,\"$\",{get(){let s=kw();return s.type===\"codegen\"?this[Ka]:s.type===\"simulate\"?t.simulateMode?.get?t.simulateMode.get.apply(this,[s]):t.normalMode.get.apply(this):s.type===\"normal\"?t.normalMode.get.apply(this):Im(s,\"makeDereferenceable.ts#$ (get)\")},set(s){let r=kw();if(r.type===\"normal\"){if(!t.normalMode.set)throw new Error(`'${this.toString()}' cannot be set in normal mode`);t.normalMode.set.apply(this,[s]);return}if(r.type===\"simulate\"){if(t.simulateMode?.set)t.simulateMode.set.apply(this,[r,s]);else if(t.normalMode.set)t.normalMode.set.apply(this,[s]);else throw new Error(`'${this.toString()}' cannot be set in simulate mode`);return}if(r.type===\"codegen\")throw new Error(\"Unreachable makeDerefenceable.ts#$ (set)\");return Im(r,\"makeDereferenceable.ts#$ (set)\")}}),e}function Al(e,t){return _s(e)||Object.defineProperty(e,ve,{value:!0,writable:!0}),Object.defineProperty(e,\"toString\",{value(){return t.asString.apply(this)}}),Object.defineProperty(e,Ws,{value(s){return t.resolve.apply(this,[s])}}),e}function w3(e,t){if(!o_(e)){if(!Array.isArray(t))throw new Error(`Expected an array value for a partially-applied array schema, but received: ${typeof t}.`);return new o7(e(t.length),t)}return new o7(e,t)}function JM(e){let t=Reflect.ownKeys(e);for(let s of t){let r=e[s];(r&&typeof r==\"object\"||typeof r==\"function\")&&JM(r)}return Object.freeze(e)}var o7=class E1{[He];static#e=void(E1.prototype[ve]={},E1.prototype.resourceType=\"const\",Bi(Al(E1.prototype,{asString(){return`const:${ct(this)??\"<unnamed>\"}`},resolve(t){let s=t.makeUniqueIdentifier(ct(this),\"global\");return t.gen.declareGlobalConst({id:s,dataType:this.dataType,init:Je(this[He].value,this.dataType,\"constant\")})}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.dataType,\"constant-immutable-def\",!1)}},normalMode:{get(){return this[He].value}}}));constructor(t,s){this[He]={type:\"const\",dataType:t,value:s&&typeof s==\"object\"?JM(s):s,label:void 0}}get dataType(){return this[He].dataType}$name(t){return es(this,t),this}};function ZX(e){return AN(e)||yh(e)||Pu(e)}function a7(e){let t=e.pluginProvided??e.userProvided??{},s=Object.defineProperties({},Object.getOwnPropertyDescriptors(t));for(let r of[e.args,e.out].filter(o=>o!==void 0))for(let[o,a]of Object.entries(r)){if(o in s&&s[o]!==a)throw new Error(`Key '${o}' appears in externals despite already being used for argument/return type. Please rename this external.`);s[o]=a}return s}function JX(e,t,s){let r=[...e.matchAll(/:\\s*(?<arg>.*?)\\s*[,)]/g)].map(a=>a?.[1]),o=Object.fromEntries(t.flatMap((a,i)=>{let l=r?.[i];return _r(a)&&l!==void 0?[[l,a]]:[]}));s.setExternals(\"args\",o)}function eE(e,t,s){let r=e.match(/->\\s(?<output>[\\w\\d_]+)\\s{/),o=r?r[1]?.trim():void 0;_r(t)&&o&&!/\\s/g.test(o)&&s.setExternals(\"out\",{[o]:t})}var n7=/([$_\\p{XID_Start}][$\\p{XID_Continue}]*)/u,eH=new RegExp(`(${n7.source})(\\\\.${n7.source})*`,\"ug\"),tH=new RegExp(`(?<![\\\\p{XID_Continue}\\\\$.])${eH.source}(?![\\\\p{XID_Continue}\\\\$])`,\"ug\");function zh(e,t,s){let r=Object.keys(t);if(r.length===0)return s;let o=r.find(a=>a.includes(\".\"));if(o)throw new Error(`External key '${o}' contains invalid character '.'`);return s.replaceAll(tH,a=>{let i=a.split(\".\");if(!Object.hasOwn(t,i.at(0)))return a;let l=t,c=\"\";for(let[d,u]of i.entries()){if(l=l[u],ZX(l)||typeof l==\"string\"){c=i.slice(d+1).map(p=>`.${p}`).join(\"\"),Su(l)&&ct(l)===void 0&&es(l,i.slice(0,d+1).join(\"_\"));break}if(typeof l!=\"object\"||l===null||d===i.length-1)return rr.warn(\"external-omitted\",`During resolution, the external '${i.slice(0,d+1).join(\".\")}' has been omitted. Only TGPU resources, 'use gpu' functions, primitives, and plain JS objects can be used as externals.`),a}return e.resolve(l).value+c})}var sH=class{[ve]=!0;#e;constructor(e){this.#e=e}[Ws](){return Je(this.#e,Ns,\"runtime\",!0)}},T3=new Set([`\n`,\"\\v\",\"\\f\",\"\\r\",\"\\x85\",\"\\u2028\",\"\\u2029\"]),tE=new Set([...T3,\" \",\"\t\",\"\\u200E\",\"\\u200F\"]);function rH(e){let{strippedCode:t,argRange:s}=oH(e),r=new sE(t);r.consume(\"(\");let o=[];for(;!r.isAt(\")\");){let i=[];for(;r.isAt(\"@\");)r.parseUntil(i7,l7),r.consume(\")\"),i.push(r.lastParsed);r.parseUntil(aH);let l=r.lastParsed,c;r.isAt(\":\")&&(r.consume(\":\"),r.parseUntil(nH,lH),c=r.lastParsed),o.push({identifier:l,attributes:i,type:c}),r.isAt(\",\")&&r.consume(\",\")}r.consume(\")\");let a;if(r.isAt(\"->\")){r.consume(\"->\");let i=[];for(;r.isAt(\"@\");)r.parseUntil(i7,l7),r.consume(\")\"),i.push(r.lastParsed);a={type:r.str.slice(r.pos),attributes:i}}return{args:o,ret:a,range:{begin:s[0],end:s[1]}}}function oH(e){let t=new sE(e),s=\"\",r;for(;!t.isFinished();){if(t.isAt(tE)){t.advanceBy(1);continue}if(t.isAt(\"//\")){t.consume(\"//\"),t.parseUntil(T3),t.advanceBy(1);continue}if(t.isAt(\"/*\")){t.parseUntil(iH,cH),t.consume(\"*/\");continue}if(t.isAt(\"{\"))return{strippedCode:s,argRange:[r,t.pos]};t.isAt(\"(\")&&r===void 0&&(r=t.pos),r!==void 0&&(s+=t.str[t.pos]),t.advanceBy(1)}throw new Error(\"Invalid wgsl code!\")}var sE=class{str;#e;#t;constructor(e){this.str=e,this.#t=0}get pos(){return this.#t}get lastParsed(){if(this.#e===void 0)throw new Error(\"Parse was not called yet!\");return this.str.slice(this.#e,this.pos)}isFinished(){return this.#t>=this.str.length}isAt(e){if(typeof e==\"string\"){for(let t=0;t<e.length;t++)if(this.str[this.#t+t]!==e[t])return!1;return!0}for(let t of e)if(this.isAt(t))return!0;return!1}parseUntil(e,t){this.#e=this.#t;let s=0;for(;this.#t<this.str.length;){if(t&&this.isAt(t[0])&&(s+=1),t&&this.isAt(t[1])&&(s-=1),s===0&&this.isAt(e))return this.#t;this.#t+=1}throw new Error(\"Reached the end of the string without finding a match!\")}advanceBy(e){this.#t+=e}consume(e){if(!this.isAt(e))throw new Error(`Expected '${e}' at position ${this.#t}, but found '${this.str.slice(this.#t,this.#t+e.length)}'`);this.advanceBy(e.length)}},i7=new Set([\")\"]),aH=new Set([\":\",\",\",\")\"]),nH=new Set([\",\",\")\"]),iH=new Set([\"*/\"]),l7=[\"(\",\")\"],lH=[\"<\",\">\"],cH=[\"/*\",\"*/\"];function Ed(e,t,s){let r={};return{[Mo]:typeof e==\"function\"?e:void 0,setExternals(o,a){if(o===\"userProvided\"&&\"userProvided\"in r)throw new Error(\"Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.\");if(r[o]=a,r.userProvided&&r.pluginProvided)throw new Error(\"Cannot call '$uses' on functions whose metadata was provided by unplugin-typegpu.\")},resolve(o,a,i,l){let c=\"\";t===\"compute\"?c=`@compute @workgroup_size(${s?.join(\", \")}) `:t===\"vertex\"?c=\"@vertex \":t===\"fragment\"&&(c=\"@fragment \");let d=o.makeUniqueIdentifier(ct(this),\"global\");if(typeof e==\"string\"){if(!i)throw new Error(\"Explicit return type is required for string implementation\");if(l){for(let P of l.positionalArgs){let C=Sh(P.schemaKey);if(!C.success)throw new Error(`Invalid argument name \"${P.schemaKey}\"${C.error?`: ${C.error}`:\"\"}`);if(o.isIdentifierBanned(P.schemaKey))throw new Error(`Invalid argument name \"${P.schemaKey}\", the identifier is a reserved keyword.`)}this.setExternals(\"args\",{in:Object.fromEntries(l.positionalArgs.map(P=>[P.schemaKey,new sH(P.schemaKey)]))})}let y=zh(o,a7(r),e),b=\"\",x=\"\";if(t!==\"normal\"&&l){let{dataSchema:P,positionalArgs:C}=l,E=[];P&&c7(\"in\",y)&&E.push(`in: ${o.resolve(P).value}`);for(let L of C){let k=L.schemaKey;c7(k,y)&&E.push(`${Ym(L.type)}${k}: ${o.resolve(L.type).value}`)}let R=`(${E.join(\", \")})`,U=Td(i)?Ym(i):\"\";b=`${R}${i!==zr?_r(i)?` -> ${o.resolve(i).value} `:` -> ${U!==\"\"?U:\"@location(0)\"} ${o.resolve(i).value} `:\" \"}`,x=y}else{let P=rH(y);if(P.args.length!==a.length)throw new Error(`WGSL implementation has ${P.args.length} arguments, while the shell has ${a.length} arguments.`);b=`(${P.args.map((C,E)=>`${C.identifier}: ${d7(o,`parameter ${C.identifier}`,C.type,a[E])}`).join(\", \")})${i===zr?\" \":` -> ${d7(o,\"return type\",P.ret?.type,i)} `}`,x=y.slice(P.range.end)}return o.addDeclaration(`${c}fn ${d}${b}${x}`,d),Je(d,i,\"runtime\")}let u=Fx(e),p=u?.externals();p&&this.setExternals(\"pluginProvided\",p);let _=u?.ast;if(!_)throw new Error(\"Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)\");let f=_.params[1];f&&f.type===\"i\"&&t!==\"normal\"&&this.setExternals(\"out\",{[f.name]:_n(i)});let{code:h,returnType:g}=o.resolveFunction({functionType:t,name:d,workgroupSize:s,argTypes:a,entryInput:l,params:_.params,returnType:i,body:_.body,externalMap:a7(r)});return o.addDeclaration(h,d),Je(d,g,\"runtime\")}}}function c7(e,t){return new RegExp(`\\\\b${e}\\\\b`).test(t)}function d7(e,t,s,r){let o=e.resolve(r).value.replace(/\\s/g,\"\");if(!s)return o;let a=s.replace(/\\s/g,\"\");if(a!==o)throw new Error(`Type mismatch between TGPU shell and WGSL code string: ${t}, JS type \"${o}\", WGSL type \"${a}\".`);return s}function Rh(e,...t){return dH(e)?uH(e,...t):e}function dH(e){return Array.isArray(e)&&\"raw\"in e&&Array.isArray(e.raw)&&e.raw.every(t=>typeof t==\"string\")}function uH(e,...t){return e.slice(1).reduce((s,r,o)=>`${s}${t[o]}${r}`,e[0])}function nr(e,t){if(typeof e==\"function\")return oE(e,[]);let s=e,r={[ve]:!0,argTypes:s,returnType:t??zr};return Object.assign((a,...i)=>pH(r,Rh(a,...i)),r)}function pb(e){return _s(e)&&e?.resourceType===\"function\"}function mb(e){return _s(e)&&e?.resourceType===\"generic-function\"}function rE([e,t]){return`${ct(e)??\"<unnamed>\"}=${t}`}function pH(e,t){let s=[],r;mb(t)?(s=t[ya]?.pairs??[],r=t[ve].inner):r=t;let o=Ed(r,\"normal\"),a={shell:e,resourceType:\"function\",[ve]:{implementation:r},$uses(c){return o.setExternals(\"userProvided\",c),this},[Mo]:o,$name(c){return es(this,c),this},with:Tn((c,d)=>_b(l,[[Qu(c)||Zu(c)?c.slot:c,d]])),[Ws](c){return typeof r==\"string\"&&(JX(r,e.argTypes,o),eE(r,e.returnType,o)),o.resolve(c,e.argTypes,e.returnType)}},i=je({name:void 0,noComptime:!0,signature:{argTypes:e.argTypes,returnType:e.returnType},normalImpl:(...c)=>wN(()=>{try{if(typeof r==\"string\")throw new Error(\"Cannot execute on the CPU functions constructed with raw WGSL\");let d=c.map((p,_)=>rc(e.argTypes[_],p)),u=r(...d);return rc(e.returnType,u)}catch(d){throw d instanceof Cw?d.appendToTrace(l):new Cw(d,[l])}}),codegenImpl:(c,d)=>c.withResetIndentLevel(()=>Ne`${c.resolve(l).value}(${d})`),sideEffects:!0}),l=Object.assign(i,a);return Object.defineProperty(l,\"toString\",{value(){return`fn:${ct(o)??\"<unnamed>\"}`}}),s.length>0?_b(l,s):l}function _b(e,t){let s={resourceType:\"function\",shell:e.shell,[ve]:{implementation:e[ve].implementation},[ya]:{inner:e,pairs:t},$uses(i){return e.$uses(i),this},$name(i){return es(this,i),this},with:Tn((i,l)=>{let c=Qu(i)||Zu(i)?i.slot:i;return _b(e,[...t,[c,l]])})},r=je({name:void 0,noComptime:!0,signature:{argTypes:e.shell.argTypes,returnType:e.shell.returnType},normalImpl:e,codegenImpl:(i,l)=>i.withResetIndentLevel(()=>Ne`${i.resolve(o).value}(${l})`),sideEffects:!0}),o=Object.assign(r,s);Object.defineProperty(o,\"toString\",{value(){return`fn:${ct(this)??\"<unnamed>\"}[${t.map(rE).join(\", \")}]`}});let a=ct(e);return a&&es(o,a),o}function oE(e,t){let s={[ve]:{inner:e},resourceType:\"generic-function\",[ya]:t.length>0?{inner:e,pairs:t}:void 0,$name(i){return es(this,i),ct(e)||es(e,i),this},[Ws](i){return i.resolve(e)},with(i,l){let c=Qu(i)||Zu(i)?i.slot:i;return oE(e,[...t,[c,l]])}},o=Object.assign((...i)=>e(...i),s),a=ct(e);return a&&es(o,a),Object.defineProperty(o,\"toString\",{value(){let i=ct(o)??\"<unnamed>\";return t.length>0?`fn*:${i}[${t.map(rE).join(\", \")}]`:`fn*:${i}`}}),o}var mH={block:0,binaryExpr:1,assignmentExpr:2,logicalExpr:3,unaryExpr:4,numericLiteral:5,call:6,memberAccess:7,indexAccess:8,return:10,if:11,let:12,const:13,for:14,while:15,continue:16,break:17,forOf:18,arrayExpr:100,preUpdate:101,postUpdate:102,stringLiteral:103,objectExpr:104,conditionalExpr:105},gm={identifier:\"i\",destructuredObject:\"d\"},aE=ko({FuncParameterType:()=>gm,NodeTypeCatalog:()=>mH}),S3=e=>({argTypes:[e],returnType:e}),P3=(...e)=>{let t=sa(e)??e;return{argTypes:t,returnType:t[0]}},Rs=e=>(...t)=>{let s=sa(t,e);if(!s)throw new jr(t,e);return{argTypes:s,returnType:s[0]}};function nE(e){return(t,...s)=>{let r=t;for(let o of s)r=e(r,o);return r}}function iE(e){return(t,[s,...r])=>{let o=Ne`${s}`;for(let a of r)o=Ne`${e}(${o}, ${a})`;return o}}var _H=[n,Vr,fd],Wm=[ps,Zs,qt,To,Pa,So],zs=[..._H,...Wm],fH=[j,M],vH=[ir,Br,sr,$s,Ps,Is],ul=[...fH,...vH];function hH(e){return Bs(Math.abs,[e])}var re=je({name:\"abs\",signature:S3,normalImpl:hH,codegenImpl:(e,[t])=>Ne`abs(${t})`,sideEffects:!1});function gH(e){return Bs(Math.acos,[e])}var yH=je({name:\"acos\",signature:Rs(zs),normalImpl:gH,codegenImpl:(e,[t])=>Ne`acos(${t})`,sideEffects:!1});function bH(e){return Bs(Math.acosh,[e])}var xH=je({name:\"acosh\",signature:Rs(zs),normalImpl:bH,codegenImpl:(e,[t])=>Ne`acosh(${t})`,sideEffects:!1});function AH(e){return Bs(Math.asin,[e])}var fb=je({name:\"asin\",signature:Rs(zs),normalImpl:AH,codegenImpl:(e,[t])=>Ne`asin(${t})`,sideEffects:!1});function wH(e){return Bs(Math.asinh,[e])}var TH=je({name:\"asinh\",signature:Rs(zs),normalImpl:wH,codegenImpl:(e,[t])=>Ne`asinh(${t})`,sideEffects:!1});function SH(e){return Bs(Math.atan,[e])}var PH=je({name:\"atan\",signature:Rs(zs),normalImpl:SH,codegenImpl:(e,[t])=>Ne`atan(${t})`,sideEffects:!1});function CH(e){return Bs(Math.atanh,[e])}var MH=je({name:\"atanh\",signature:Rs(zs),normalImpl:CH,codegenImpl:(e,[t])=>Ne`atanh(${t})`,sideEffects:!1});function EH(e,t){return Bs(Math.atan2,[e,t])}var Xt=je({name:\"atan2\",signature:Rs(zs),normalImpl:EH,codegenImpl:(e,[t,s])=>Ne`atan2(${t}, ${s})`,sideEffects:!1});function kH(e){return Bs(Math.ceil,[e])}var nl=je({name:\"ceil\",signature:Rs(zs),normalImpl:kH,codegenImpl:(e,[t])=>Ne`ceil(${t})`,sideEffects:!1});function BH(e,t,s){return Bs(AM,[e,t,s])}var G=je({name:\"clamp\",signature:P3,normalImpl:BH,codegenImpl:(e,[t,s,r])=>Ne`clamp(${t}, ${s}, ${r})`,sideEffects:!1});function zH(e){return Bs(Math.cos,[e])}var pe=je({name:\"cos\",signature:Rs(zs),normalImpl:zH,codegenImpl:(e,[t])=>Ne`cos(${t})`,sideEffects:!1});function RH(e){return Bs(Math.cosh,[e])}var DH=je({name:\"cosh\",signature:Rs(zs),normalImpl:RH,codegenImpl:(e,[t])=>Ne`cosh(${t})`,sideEffects:!1}),LH=je({name:\"countLeadingZeros\",signature:Rs(ul),normalImpl:\"CPU implementation for countLeadingZeros not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`countLeadingZeros(${t})`,sideEffects:!1});je({name:\"countOneBits\",signature:Rs(ul),normalImpl:\"CPU implementation for countOneBits not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`countOneBits(${t})`,sideEffects:!1});je({name:\"countTrailingZeros\",signature:Rs(ul),normalImpl:\"CPU implementation for countTrailingZeros not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`countTrailingZeros(${t})`,sideEffects:!1});var u7=je({name:\"cross\",signature:Rs([Zs,Pa]),normalImpl:(e,t)=>$a.cross[e.kind](e,t),codegenImpl:(e,[t,s])=>Ne`cross(${t}, ${s})`,sideEffects:!1});function UH(e){if(typeof e==\"number\")return e*180/Math.PI;throw new vo(\"CPU implementation for degrees on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}je({name:\"degrees\",signature:Rs(zs),normalImpl:UH,codegenImpl:(e,[t])=>Ne`degrees(${t})`,sideEffects:!1});je({name:\"determinant\",signature:e=>{if(!(e.type===\"mat2x2f\"||e.type===\"mat3x3f\"||e.type===\"mat4x4f\"))throw new jr([e],[yl,bl,Eo]);return{argTypes:[e],returnType:n}},normalImpl:\"CPU implementation for determinant not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`determinant(${t})`,sideEffects:!1});function OH(e,t){return typeof e==\"number\"&&typeof t==\"number\"?Math.abs(e-t):he(As(e,t))}je({name:\"distance\",signature:(...e)=>{let t=sa(e,zs);if(!t)throw new jr(e,zs);return{argTypes:t,returnType:Gx(t[0])?Vr:n}},normalImpl:OH,codegenImpl:(e,[t,s])=>Ne`distance(${t}, ${s})`,sideEffects:!1});var Se=je({name:\"dot\",signature:(...e)=>({argTypes:e,returnType:e[0].primitive}),normalImpl:(e,t)=>$a.dot[e.kind](e,t),codegenImpl:(e,[t,s])=>Ne`dot(${t}, ${s})`,sideEffects:!1});je({name:\"dot4U8Packed\",signature:{argTypes:[M,M],returnType:M},normalImpl:\"CPU implementation for dot4U8Packed not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s])=>Ne`dot4U8Packed(${t}, ${s})`,sideEffects:!1});je({name:\"dot4I8Packed\",signature:{argTypes:[M,M],returnType:j},normalImpl:\"CPU implementation for dot4I8Packed not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s])=>Ne`dot4I8Packed(${t}, ${s})`,sideEffects:!1});function GH(e){return Bs(Math.exp,[e])}var Tt=je({name:\"exp\",signature:Rs(zs),normalImpl:GH,codegenImpl:(e,[t])=>Ne`exp(${t})`,sideEffects:!1});function FH(e){return Bs(t=>2**t,[e])}var Ia=je({name:\"exp2\",signature:Rs(zs),normalImpl:FH,codegenImpl:(e,[t])=>Ne`exp2(${t})`,sideEffects:!1}),p7=je({name:\"extractBits\",signature:(e,t,s)=>{let r=sa([e],ul)?.[0];if(!r)throw new jr([e],ul);return{argTypes:[r,M,M],returnType:r}},normalImpl:\"CPU implementation for extractBits not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s,r])=>Ne`extractBits(${t}, ${s}, ${r})`,sideEffects:!1});je({name:\"faceForward\",signature:Rs(Wm),normalImpl:\"CPU implementation for faceForward not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s,r])=>Ne`faceForward(${t}, ${s}, ${r})`,sideEffects:!1});je({name:\"firstLeadingBit\",signature:S3,normalImpl:\"CPU implementation for firstLeadingBit not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`firstLeadingBit(${t})`,sideEffects:!1});je({name:\"firstTrailingBit\",signature:Rs(ul),normalImpl:\"CPU implementation for firstTrailingBit not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`firstTrailingBit(${t})`,sideEffects:!1});function IH(e){return Bs(Math.floor,[e])}var ie=je({name:\"floor\",signature:Rs(zs),normalImpl:IH,codegenImpl:(e,[t])=>Ne`floor(${t})`,sideEffects:!1});function YH(e,t,s){if(typeof e==\"number\")return e*t+s;throw new vo(\"CPU implementation for fma on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}je({name:\"fma\",signature:Rs(zs),normalImpl:YH,codegenImpl:(e,[t,s,r])=>Ne`fma(${t}, ${s}, ${r})`,sideEffects:!1});function WH(e){return Bs(t=>t-Math.floor(t),[e])}var Re=je({name:\"fract\",signature:Rs(zs),normalImpl:WH,codegenImpl:(e,[t])=>Ne`fract(${t})`,sideEffects:!1}),qH={f32:Fo({fract:n,exp:j}),f16:Fo({fract:Vr,exp:j}),abstractFloat:Fo({fract:fd,exp:i_}),vec2f:Fo({fract:ps,exp:ir}),vec3f:Fo({fract:Zs,exp:Br}),vec4f:Fo({fract:qt,exp:sr}),vec2h:Fo({fract:To,exp:ir}),vec3h:Fo({fract:Pa,exp:Br}),vec4h:Fo({fract:So,exp:sr})};je({name:\"frexp\",normalImpl:\"CPU implementation for frexp not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",signature:e=>{let t=qH[e.type];if(!t)throw new jr([e],zs);return{argTypes:[e],returnType:t}},codegenImpl:(e,[t])=>Ne`frexp(${t})`,sideEffects:!1});je({name:\"insertBits\",signature:(e,t,s,r)=>{let o=sa([e,t],ul);if(!o)throw new jr([e,t],ul);return{argTypes:[...o,M,M],returnType:o[0]}},normalImpl:\"CPU implementation for insertBits not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s,r,o])=>Ne`insertBits(${t}, ${s}, ${r}, ${o})`,sideEffects:!1});function VH(e){if(typeof e==\"number\")return 1/Math.sqrt(e);throw new vo(\"CPU implementation for inverseSqrt on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}je({name:\"inverseSqrt\",signature:Rs(zs),normalImpl:VH,codegenImpl:(e,[t])=>Ne`inverseSqrt(${t})`,sideEffects:!1});je({name:\"ldexp\",signature:(e,t)=>{switch(e.type){case\"abstractFloat\":return{argTypes:[e,i_],returnType:e};case\"f32\":case\"f16\":return{argTypes:[e,j],returnType:e};case\"vec2f\":case\"vec2h\":return{argTypes:[e,ir],returnType:e};case\"vec3f\":case\"vec3h\":return{argTypes:[e,Br],returnType:e};case\"vec4f\":case\"vec4h\":return{argTypes:[e,sr],returnType:e};default:throw new Error(`Unsupported data type for ldexp: ${e.type}. Supported types are abstractFloat, f32, f16, vec2f, vec2h, vec3f, vec3h, vec4f, vec4h.`)}},normalImpl:\"CPU implementation for ldexp not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s])=>Ne`ldexp(${t}, ${s})`,sideEffects:!1});function NH(e){return typeof e==\"number\"?Math.abs(e):$a.length[e.kind](e)}var he=je({name:\"length\",signature:e=>{let t=sa([e],zs);if(!t)throw new jr([e],zs);return{argTypes:t,returnType:Gx(t[0])?Vr:n}},normalImpl:NH,codegenImpl:(e,[t])=>Ne`length(${t})`,sideEffects:!1});function $H(e){return Bs(Math.log,[e])}var XH=je({name:\"log\",signature:Rs(zs),normalImpl:$H,codegenImpl:(e,[t])=>Ne`log(${t})`,sideEffects:!1});function HH(e){return Bs(Math.log2,[e])}var vb=je({name:\"log2\",signature:Rs(zs),normalImpl:HH,codegenImpl:(e,[t])=>Ne`log2(${t})`,sideEffects:!1});function jH(e,t){return Bs(Math.max,[e,t])}var B=je({name:\"max\",signature:P3,normalImpl:nE(jH),codegenImpl:iE(\"max\"),sideEffects:!1});function KH(e,t){return Bs(Math.min,[e,t])}var ye=je({name:\"min\",signature:P3,normalImpl:nE(KH),codegenImpl:iE(\"min\"),sideEffects:!1});function QH(e,t,s){return Bs((r,o,a)=>r*(1-a)+o*a,[e,...u3([t,s])])}var K=je({name:\"mix\",signature:(e,t,s)=>{if(e.type.startsWith(\"vec\")&&!s.type.startsWith(\"vec\")){let o=sa([s],[e.primitive]);if(!o)throw new jr([s],[e.primitive]);return{argTypes:[e,t,o[0]],returnType:e}}let r=sa([e,t,s],zs);if(!r)throw new jr([e,t,s],zs);return{argTypes:r,returnType:r[0]}},normalImpl:QH,codegenImpl:(e,[t,s,r])=>Ne`mix(${t}, ${s}, ${r})`,sideEffects:!1}),ZH={f32:Fo({fract:n,whole:n}),f16:Fo({fract:Vr,whole:Vr}),abstractFloat:Fo({fract:fd,whole:fd}),vec2f:Fo({fract:ps,whole:ps}),vec3f:Fo({fract:Zs,whole:Zs}),vec4f:Fo({fract:qt,whole:qt}),vec2h:Fo({fract:To,whole:To}),vec3h:Fo({fract:Pa,whole:Pa}),vec4h:Fo({fract:So,whole:So})};je({name:\"modf\",signature:e=>{let t=ZH[e.type];if(!t)throw new Error(`Unsupported data type for modf: ${e.type}. Supported types are f32, f16, abstractFloat, vec2f, vec3f, vec4f, vec2h, vec3h, vec4h.`);return{argTypes:[e],returnType:t}},normalImpl:\"CPU implementation for modf not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`modf(${t})`,sideEffects:!1});var vs=je({name:\"normalize\",signature:Rs(Wm),normalImpl:e=>{let t=he(e);return Bs(s=>s/t,[e])},codegenImpl:(e,[t])=>Ne`normalize(${t})`,sideEffects:!1});function JH(e,t){return Bs((s,r)=>s**r,[e,t])}var vt=je({name:\"pow\",signature:Rs(zs),normalImpl:JH,codegenImpl:(e,[t,s])=>Ne`pow(${t}, ${s})`,sideEffects:!1});je({name:\"quantizeToF16\",signature:e=>{let t=[ps,Zs,qt,n],s=sa([e],t)?.[0];if(!s)throw new jr([e],t);return{argTypes:[s],returnType:s}},normalImpl:\"CPU implementation for quantizeToF16 not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`quantizeToF16(${t})`,sideEffects:!1});function ej(e){if(typeof e==\"number\")return e*Math.PI/180;throw new vo(\"CPU implementation for radians on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}var m7=je({name:\"radians\",signature:Rs(zs),normalImpl:ej,codegenImpl:(e,[t])=>Ne`radians(${t})`,sideEffects:!1});je({name:\"reflect\",signature:(...e)=>{let t=sa(e,Wm);if(!t)throw new jr(e,Wm);return{argTypes:t,returnType:t[0]}},normalImpl:(e,t)=>As(e,ra(2*Se(t,e),t)),codegenImpl:(e,[t,s])=>Ne`reflect(${t}, ${s})`,sideEffects:!1});je({name:\"refract\",normalImpl:\"CPU implementation for refract not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t,s,r])=>Ne`refract(${t}, ${s}, ${r})`,signature:(e,t,s)=>({argTypes:[e,t,Gx(e)?Vr:n],returnType:e}),sideEffects:!1});je({name:\"reverseBits\",signature:Rs(ul),normalImpl:\"CPU implementation for reverseBits not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`reverseBits(${t})`,sideEffects:!1});function tj(e){if(typeof e==\"number\"){let t=Math.floor(e);return e===t+.5?t%2===0?t:t+1:Math.round(e)}throw new vo(\"CPU implementation for round on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}var Ut=je({name:\"round\",signature:Rs(zs),normalImpl:tj,codegenImpl:(e,[t])=>Ne`round(${t})`,sideEffects:!1});function sj(e){if(typeof e==\"number\")return Math.max(0,Math.min(1,e));throw new vo(\"CPU implementation for saturate on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}je({name:\"saturate\",signature:Rs(zs),normalImpl:sj,codegenImpl:(e,[t])=>e.gen.emitCall(\"saturate\",[],[t]),sideEffects:!1});function rj(e){return Bs(Math.sign,[e])}var no=je({name:\"sign\",signature:e=>{let t=[...zs,j,ir,Br,sr],s=sa([e],t)?.[0];if(!s)throw new jr([e],t);return{argTypes:[s],returnType:s}},normalImpl:rj,codegenImpl:(e,[t])=>Ne`sign(${t})`,sideEffects:!1});function oj(e){return Bs(Math.sin,[e])}var ae=je({name:\"sin\",signature:Rs(zs),normalImpl:oj,codegenImpl:(e,[t])=>Ne`sin(${t})`,sideEffects:!1});function aj(e){return Bs(Math.sinh,[e])}var nj=je({name:\"sinh\",signature:Rs(zs),normalImpl:aj,codegenImpl:(e,[t])=>Ne`sinh(${t})`,sideEffects:!1});function ij(e,t,s){return Bs(t$,[e,t,s])}var be=je({name:\"smoothstep\",signature:Rs(zs),normalImpl:ij,codegenImpl:(e,[t,s,r])=>Ne`smoothstep(${t}, ${s}, ${r})`,sideEffects:!1});function lj(e){return Bs(Math.sqrt,[e])}var Ue=je({name:\"sqrt\",signature:Rs(zs),normalImpl:lj,codegenImpl:(e,[t])=>Ne`sqrt(${t})`,sideEffects:!1});function cj(e,t){if(typeof e==\"number\")return e<=t?1:0;throw new vo(\"CPU implementation for step on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}var Et=je({name:\"step\",signature:Rs(zs),normalImpl:cj,codegenImpl:(e,[t,s])=>Ne`step(${t}, ${s})`,sideEffects:!1});function dj(e){if(typeof e==\"number\")return Math.tan(e);throw new vo(\"CPU implementation for tan on vectors not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\")}var hb=je({name:\"tan\",signature:Rs(zs),normalImpl:dj,codegenImpl:(e,[t])=>Ne`tan(${t})`,sideEffects:!1});function uj(e){return Bs(Math.tanh,[e])}var pj=je({name:\"tanh\",signature:Rs(zs),normalImpl:uj,codegenImpl:(e,[t])=>Ne`tanh(${t})`,sideEffects:!1});function mj(e){let t=gh(e)(),s=e.columns,r=t.columns;if(s.length===2)r[0][0]=s[0][0],r[0][1]=s[1][0],r[1][0]=s[0][1],r[1][1]=s[1][1];else if(s.length===3){r[0][0]=s[0][0],r[0][1]=s[1][0],r[0][2]=s[2][0],r[1][0]=s[0][1],r[1][1]=s[1][1],r[1][2]=s[2][1];let o=r[2];o[0]=s[0][2],o[1]=s[1][2],o[2]=s[2][2]}else if(s.length===4){r[0][0]=s[0][0],r[0][1]=s[1][0],r[0][2]=s[2][0],r[0][3]=s[3][0],r[1][0]=s[0][1],r[1][1]=s[1][1],r[1][2]=s[2][1],r[1][3]=s[3][1];let o=r[2];o[0]=s[0][2],o[1]=s[1][2],o[2]=s[2][2],o[3]=s[3][2];let a=r[3];a[0]=s[0][3],a[1]=s[1][3],a[2]=s[2][3],a[3]=s[3][3]}else Im(s,\"std/numeric.ts#cpuTranspose\");return t}je({name:\"transpose\",signature:S3,normalImpl:mj,codegenImpl:(e,[t])=>Ne`transpose(${t})`,sideEffects:!1});var _j=je({name:\"trunc\",signature:Rs(zs),normalImpl:\"CPU implementation for trunc not implemented yet. Please submit an issue at https://github.com/software-mansion/TypeGPU/issues\",codegenImpl:(e,[t])=>Ne`trunc(${t})`,sideEffects:!1});function fj(e,t){if(typeof e!=\"number\"||typeof t!=\"number\")throw new Error(\"std.intdiv called with invalid arguments.\");return Math.trunc(Math.trunc(e)/Math.trunc(t))}je({name:\"intdiv\",signature:(e,t)=>{let s=sa([e,t],[M,j]);if(!s)throw new jr([e,t],[M,j,i_]);return{argTypes:s,returnType:s[0]}},normalImpl:fj,codegenImpl:(e,[t,s])=>e.gen.emitBinaryOp(t,\"/\",s),sideEffects:!1});function Q1(e){return Jo(e)||Kn(e)?gh(e)(e):Array.isArray(e)?e.map(Q1):typeof e==\"object\"&&e!==null?Object.fromEntries(Object.entries(e).map(([t,s])=>[t,Q1(s)])):e}je({name:\"copy\",signature:e=>({argTypes:[e],returnType:e}),normalImpl:Q1,codegenImpl(e,[t]){return Ne`${t}`},sideEffects:!1});function sp(e){return e.type.includes(\"2\")?Wa:e.type.includes(\"3\")?qa:Va}var vj=je({name:\"allEq\",signature:(...e)=>({argTypes:e,returnType:ys}),normalImpl:(e,t)=>M3(m_(e,t)),codegenImpl:(e,[t,s])=>Ne`all(${t} == ${s})`,sideEffects:!1}),m_=(e,t)=>Th((s,r)=>s===r,[e,t]),hj=je({name:\"eq\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:m_,codegenImpl:(e,[t,s])=>Ne`(${t} == ${s})`,sideEffects:!1}),gj=je({name:\"ne\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:(e,t)=>Io(m_(e,t)),codegenImpl:(e,[t,s])=>Ne`(${t} != ${s})`,sideEffects:!1}),Dh=(e,t)=>Th((s,r)=>s<r,[e,t]),yj=je({name:\"lt\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:Dh,codegenImpl:(e,[t,s])=>Ne`(${t} < ${s})`,sideEffects:!1}),qm=je({name:\"le\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:(e,t)=>C3(Dh(e,t),m_(e,t)),codegenImpl:(e,[t,s])=>Ne`(${t} <= ${s})`,sideEffects:!1}),bj=je({name:\"gt\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:(e,t)=>lE(Io(Dh(e,t)),Io(m_(e,t))),codegenImpl:(e,[t,s])=>Ne`(${t} > ${s})`,sideEffects:!1}),gb=je({name:\"ge\",signature:(...e)=>({argTypes:e,returnType:sp(e[0])}),normalImpl:(e,t)=>Io(Dh(e,t)),codegenImpl:(e,[t,s])=>Ne`(${t} >= ${s})`,sideEffects:!1});function Io(e){if(typeof e==\"boolean\")return!e;if(!KV(e))throw new Error(\"'std.not' requires a boolean or boolean vector.\");switch(e.length){case 2:return Wa(Io(e.x),Io(e.y));case 3:return qa(Io(e.x),Io(e.y),Io(e.z));case 4:return Va(Io(e.x),Io(e.y),Io(e.z),Io(e.w))}}var xj=je({name:\"not\",signature:e=>{if(!ql(e)&&!Ox(e))throw new jr([e],[ys,Wa,qa,Va]);return{argTypes:[e],returnType:e}},normalImpl:Io,codegenImpl:(e,[t])=>Ne`!(${t})`,sideEffects:!1}),C3=(e,t)=>Th((s,r)=>s||r,[e,t]);je({name:\"or\",signature:(...e)=>({argTypes:e,returnType:e[0]}),normalImpl:C3,codegenImpl:(e,[t,s])=>Ne`(${t} | ${s})`,sideEffects:!1});var lE=(e,t)=>Io(C3(Io(e),Io(t)));je({name:\"and\",signature:(...e)=>({argTypes:e,returnType:e[0]}),normalImpl:lE,codegenImpl:(e,[t,s])=>Ne`(${t} & ${s})`,sideEffects:!1});var M3=e=>$a.all[e.kind](e),Aj=je({name:\"all\",signature:(...e)=>({argTypes:e,returnType:ys}),normalImpl:M3,codegenImpl:(e,[t])=>Ne`all(${t})`,sideEffects:!1});je({name:\"any\",signature:(...e)=>({argTypes:e,returnType:ys}),normalImpl:e=>!M3(Io(e)),codegenImpl:(e,[t])=>Ne`any(${t})`,sideEffects:!1});je({name:\"isCloseTo\",signature:(...e)=>({argTypes:e,returnType:ys}),normalImpl:(e,t,s=.01)=>{let r=Th((o,a)=>Math.abs(o-a)<s,[e,t]);return typeof r==\"boolean\"?r:Aj(r)},codegenImpl:(e,[t,s,r=Je(.01,n,\"constant\",!1)])=>fm(t)&&fm(s)?Ne`(abs(f32(${t}) - f32(${s})) <= ${r})`:!fm(t)&&!fm(s)?Ne`all(abs(${t} - ${s}) <= (${t} - ${t}) + ${r})`:\"false\",sideEffects:!1});function wj(e,t,s){return typeof s==\"boolean\"?Q1(s?t:e):Bs((r,o,a)=>a?o:r,[e,t,s])}var k1=[n,Vr,j,M,ys,ps,Zs,qt,To,Pa,So,ir,Br,sr,$s,Ps,Is,Wa,qa,Va],N=je({name:\"select\",signature:(e,t,s)=>{let[r,o]=sa([e,t],k1)??[e,t];return{argTypes:[r,o,s],returnType:r}},normalImpl:wj,codegenImpl:(e,[t,s,r])=>{let o=e.gen.emitCall(\"select\",[],[t,s,r]);if(!k1.includes(t.dataType)||!k1.includes(s.dataType))throw new Error(`'${o}' is invalid, std.select requires both branches to be either scalars or vectors.`);if(t.dataType!==s.dataType){let a=e.resolve(t.dataType),i=e.resolve(s.dataType);throw new Error(`'${o}' is invalid, std.select requires both branches to be the same type, got [${a.value}, ${i.value}].`)}return o},sideEffects:!1});function Lh(e){return typeof e?.format==\"string\"}function Tj(e,t){let s=[];if(o_(e)){if(!Lh(t))throw new Error(\"Shader expected a single attribute, not a record of attributes to be passed in.\");return s.push(t._layout),{usedVertexLayouts:s,bufferDefinitions:[{arrayStride:t._layout.stride,stepMode:t._layout.stepMode,attributes:[{format:t.format,offset:t.offset,shaderLocation:sc(e)??0}]}]}}let r=[],o=new WeakMap,a=0;for(let[i,l]of Object.entries(e)){if(wi(l))continue;let c=t[i];if(!c)throw new Error(`An attribute by the name of '${i}' was not provided to the shader.`);let d=c._layout,u=o.get(d);u||(s.push(d),u=[],r.push({arrayStride:d.stride,stepMode:d.stepMode,attributes:u}),o.set(d,u)),a=sc(l)??a,u.push({format:c.format,offset:c.offset,shaderLocation:a++})}return{usedVertexLayouts:s,bufferDefinitions:r}}var Sj=[\"bool\",\"f32\",\"f16\",\"i32\",\"u32\",\"vec2f\",\"vec3f\",\"vec4f\",\"vec2h\",\"vec3h\",\"vec4h\",\"vec2i\",\"vec3i\",\"vec4i\",\"vec2u\",\"vec3u\",\"vec4u\",\"vec2<bool>\",\"vec3<bool>\",\"vec4<bool>\",\"mat2x2f\",\"mat3x3f\",\"mat4x4f\",\"texture_external\"];function Pj(e){return Sj.includes(e.type)}function yb(e,[t,s]){return`  ${Ym(s)}${t}: ${e.resolve(s).value},\n`}function Cj(e,t){if(t[ve].isAbstruct)throw new Error(\"Cannot resolve abstract struct types to WGSL.\");let s=e.makeUniqueIdentifier(ct(t),\"global\");return e.addDeclaration(`struct ${s} {\n${Object.entries(t.propTypes).map(r=>yb(e,r)).join(\"\")}}`,s),s}function Mj(e,t){let s=e.makeUniqueIdentifier(ct(t),\"global\");return e.addDeclaration(`struct ${s} {\n${Object.entries(t.propTypes).map(r=>Lh(r[1])?yb(e,[r[0],dl[r[1].format]]):yb(e,r)).join(\"\")}\n}`,s),s}function Ej(e,t){let s=e.resolve(t.elementType).value;return t.elementCount===0?`array<${s}>`:`array<${s}, ${t.elementCount}>`}function kj(e,t){let s=e.resolve(Lh(t.elementType)?dl[t.elementType.format]:t.elementType).value;return t.elementCount===0?`array<${s}>`:`array<${s}, ${t.elementCount}>`}function cE(e,t){if(yh(t))return t.type===\"unstruct\"?Mj(e,t):t.type===\"disarray\"?kj(e,t):t.type===\"loose-decorated\"?e.resolve(Lh(t.inner)?dl[t.inner.format]:t.inner).value:e.resolve(dl[t.type]).value;if(Pj(t))return t.type;if(t.type===\"struct\")return Cj(e,t);if(t.type===\"array\")return Ej(e,t);if(t.type===\"atomic\")return`atomic<${cE(e,t.inner)}>`;if(t.type===\"decorated\")return e.resolve(t.inner).value;if(t.type===\"ptr\")return t.addressSpace===\"storage\"?`ptr<storage, ${e.resolve(t.inner).value}, ${t.access===\"read-write\"?\"read_write\":t.access}>`:`ptr<${t.addressSpace}, ${e.resolve(t.inner).value}>`;if(t.type===\"abstractInt\"||t.type===\"abstractFloat\"||t.type===\"void\"||t.type===\"u16\")throw new Error(`${t.type} has no representation in WGSL`);if(C1(t))return`${t.type}<${t.format}, ${u_[t.access]}>`;if(DM(t))return t.type.startsWith(\"texture_depth\")?t.type:`${t.type}<${t.sampleType.type}>`;if(I$(t)||F$(t))return t.type;Im(t,\"resolveData\")}var dE=class{[ve]=!0;snippet;constructor(e){this.snippet=e}[Ws](e){return e.resolveSnippet(this.snippet)}},uE=(()=>{function e(s){return s}let t=e;return es(t,\"unroll\"),t.toString=()=>\"unroll\",t[ve]=!0,t[mo]={call(s,[r]){return KC(new dE(r),r)}},t})(),_7=new Map([[Math.abs,re],[Math.acos,yH],[Math.acosh,xH],[Math.asin,fb],[Math.asinh,TH],[Math.atan,PH],[Math.atan2,Xt],[Math.atanh,MH],[Math.ceil,nl],[Math.cos,pe],[Math.cosh,DH],[Math.exp,Tt],[Math.floor,ie],[Math.fround,n],[Math.clz32,LH],[Math.trunc,_j],[Math.log,XH],[Math.log2,vb],[Math.pow,vt],[Math.sign,no],[Math.sin,ae],[Math.sinh,nj],[Math.sqrt,Ue],[Math.tan,hb],[Math.tanh,pj],[Math.max,B],[Math.min,ye]]),Bj=()=>[console.log,console.debug,console.info,console.warn,console.error,console.clear],f7=e=>ta(e)&&io(e.inner)?e.inner.elementCount:0,zj=je({name:\"arrayLength\",signature:e=>{let t=ta(e)?e:tM(e);return{argTypes:[t],returnType:f7(t)>0?i_:M}},normalImpl:e=>rM(e)?e.$.length:e.length,codegenImpl(e,[t]){let s=f7(t.dataType);return s>0?`${s}`:e.gen.emitCall(\"arrayLength\",[],[t])},sideEffects:!1});Tn((e,t,s=1)=>{if(t===void 0&&(t=e,e=0),!Number.isInteger(e))throw new Error(`'start' must be an integer, got ${e}`);if(!Number.isInteger(t))throw new Error(`'end' must be an integer, got ${t}`);if(!Number.isInteger(s)||s===0)throw new Error(`'step' must be a non-zero integer, got ${s}`);let r=[];if(r.start=e,r.end=t,r.step=s,Math.sign(s)!==Math.sign(t-e))return r;if(s>0)for(let o=e;o<t;o+=s)r.push(o);if(s<0)for(let o=e;o>t;o+=s)r.push(o);return r});function bb(e){return Array.isArray(e)&&\"start\"in e&&\"end\"in e&&\"step\"in e}function Rj(e){return e.origin===\"constant-immutable-def\"?\"const\":\"let\"}function v7(e,t){let s=Bh(e,t);if(!s)throw new jt(\"`for ... of ...` loops only support array or vector iterables\");return s}function Dj(e,t){let s=e.dataType;if(s===Ns)throw new jt(Ne`The elements in iterable ${t} are of unknown type`);if(jn(e.dataType)||e.origin===\"runtime\"||e.origin===\"constant\"||e.origin===\"constant-immutable-def\"||e.origin===\"runtime-immutable-def\")return s;if(!ta(s)){let r=Wx(e.origin,dn(s));kr(r!==void 0,`Creating pointer type from origin ${e.origin}`),s=r}return sM(s)}function Lj(e,t,s=!1){let{value:r,dataType:o}=t;if(bb(r)){let{start:i,end:l,step:c}=r,d=[i,l,c].every(u=>u>=0)?M:j;return{start:Je(i,d,\"constant\",!1),end:Je(l,d,\"constant\",!1),step:Je(c,d,\"constant\",!1),comparison:c<0?\">\":\"<\"}}if(!s&&!gi(t))throw new Error(\"`for ... of ...` loops only support std.range or iterables stored in variables.\\n-----\\nYou can wrap iterable with `tgpu.unroll(...)`. If iterable is known at comptime, the loop will be unrolled.\\n-----\");let a={start:Je(0,M,\"constant\",!1),step:Je(1,M,\"constant\",!1),comparison:\"<\"};if(io(o))return{...a,end:o.elementCount>0?Je(o.elementCount,M,\"constant\",!1):zj[mo].call(e,[t])};if(js(o))return{...a,end:Je(o.componentCount,M,\"constant\",!1)};if(s){if(Array.isArray(r))return{...a,end:Je(r.length,M,\"constant\",!1)};if(r instanceof Sm)return{...a,end:Je(r.elements.length,M,\"constant\",!1)}}throw new jt(\"`for ... of ...` loops only support array or vector iterables\")}var{NodeTypeCatalog:as}=aE;function ur(e){return mE(e)?Ko(e,\"\"):Qi(e,\"\")}function Qi(e,t){if(mE(e))return`${t}${Ko(e,t)};`;if(e[0]===as.block)return`{\n${e[1].map(s=>Qi(s,t+\"  \")).join(`\n`)}\n${t}}`;if(e[0]===as.return)return`${t}return${e[1]===void 0?\"\":` ${Ko(e[1],\"\")}`};`;if(e[0]===as.if){let s=`${t}if (${Ko(e[1],t)}) ${Qi(e[2],t)}`;return e[3]!==void 0?`${s} else ${Qi(e[3],t)}`:s}if(e[0]===as.let)return e[2]!==void 0?`${t}let ${e[1]} = ${Ko(e[2],t)};`:`${t}let ${e[1]};`;if(e[0]===as.const)return e[2]!==void 0?`${t}const ${e[1]} = ${Ko(e[2],t)};`:`${t}const ${e[1]};`;if(e[0]===as.for){let s=e[1]?Qi(e[1],\"\"):\";\",r=e[2]?Ko(e[2],t):\"\",o=e[3]?Qi(e[3],\"\"):\"\",a=Qi(e[4],t);return`${t}for (${s} ${r}; ${o.slice(0,-1)}) ${a}`}if(e[0]===as.while)return`${t}while (${Ko(e[1],t)}) ${Qi(e[2],t)}`;if(e[0]===as.continue)return`${t}continue;`;if(e[0]===as.break)return`${t}break;`;if(e[0]===as.forOf)return`${t}for (${e[1][0]===as.const?\"const\":\"let\"} ${e[1][1]} of ${Ko(e[2],t)}) ${Qi(e[3],t)}`;pE(e)}function Ko(e,t){if(typeof e==\"string\")return e;if(typeof e==\"boolean\")return`${e}`;if(e[0]===as.numericLiteral)return e[1];if(e[0]===as.stringLiteral)return JSON.stringify(e[1]);if(e[0]===as.arrayExpr)return`[${e[1].map(s=>Ko(s,t)).join(\", \")}]`;if(e[0]===as.binaryExpr)return`${nn(e[1],t)} ${e[2]} ${nn(e[3],t)}`;if(e[0]===as.assignmentExpr)return`${Ko(e[1],t)} ${e[2]} ${Ko(e[3],t)}`;if(e[0]===as.logicalExpr)return`${nn(e[1],t)} ${e[2]} ${nn(e[3],t)}`;if(e[0]===as.unaryExpr){let s=e[1].length>1?\" \":\"\";return`${e[1]}${s}${nn(e[2],t)}`}if(e[0]===as.call)return`${nn(e[1],t)}(${e[2].map(s=>Ko(s,t)).join(\", \")})`;if(e[0]===as.memberAccess)return Array.isArray(e[1])&&e[1][0]===as.numericLiteral?`(${Ko(e[1],t)}).${e[2]}`:`${nn(e[1],t)}.${e[2]}`;if(e[0]===as.indexAccess)return`${nn(e[1],t)}[${Ko(e[2],t)}]`;if(e[0]===as.preUpdate)return`${e[1]}${nn(e[2],t)}`;if(e[0]===as.postUpdate)return`${nn(e[2],t)}${e[1]}`;if(e[0]===as.objectExpr)return`{ ${Object.entries(e[1]).map(([s,r])=>`${s}: ${Ko(r,t)}`).join(\", \")} }`;if(e[0]===as.conditionalExpr)return`${nn(e[1],t)} ? ${nn(e[2],t)} : ${nn(e[3],t)}`;pE(e)}function pE(e){throw new Error(`'${JSON.stringify(e)}' was not handled by the stringify function.`)}function mE(e){return typeof e==\"string\"||typeof e==\"boolean\"||e[0]===as.numericLiteral||e[0]===as.stringLiteral||e[0]===as.arrayExpr||e[0]===as.binaryExpr||e[0]===as.assignmentExpr||e[0]===as.logicalExpr||e[0]===as.unaryExpr||e[0]===as.call||e[0]===as.memberAccess||e[0]===as.indexAccess||e[0]===as.preUpdate||e[0]===as.postUpdate||e[0]===as.objectExpr||e[0]===as.conditionalExpr}var Uj=[as.memberAccess,as.indexAccess,as.call,as.arrayExpr,as.stringLiteral,as.numericLiteral];function nn(e,t){let s=Ko(e,t);return typeof e==\"string\"||typeof e==\"boolean\"||Uj.includes(e[0])?s:`(${s})`}var{NodeTypeCatalog:Fs}=aE,Oj=[\"==\",\"!=\",\"===\",\"!==\",\"<\",\"<=\",\">\",\">=\",\"<<\",\">>\",\">>>\",\"+\",\"-\",\"*\",\"/\",\"%\",\"|\",\"^\",\"&\"],Gj=[\"&&\",\"||\",\"==\",\"!=\",\"===\",\"!==\",\"<\",\"<=\",\">\",\">=\"],Fj={\"===\":hj.toString(),\"!==\":gj.toString(),\"<\":yj.toString(),\"<=\":qm.toString(),\">\":bj.toString(),\">=\":gb.toString()},Ij=[\"<<\",\">>\",\"<<=\",\">>=\",\">>>\",\">>>=\"],Yj={\"===\":\"==\",\"!==\":\"!=\",\">>>\":\">>\",get in(){throw new Error(\"The `in` operator is unsupported in TypeGPU functions.\")},get instanceof(){throw new Error(\"The `instanceof` operator is unsupported in TypeGPU functions.\")},get\"|>\"(){throw new Error(\"The `|>` operator is unsupported in TypeGPU functions.\")},get\"??\"(){throw new Error(\"The `??` operator is unsupported in TypeGPU functions.\")},\">>>=\":\">>=\",get\"**=\"(){throw new Error(\"The `**=` operator is unsupported in TypeGPU functions.\")},get\"??=\"(){throw new Error(\"The `??=` operator is unsupported in TypeGPU functions.\")},get\"&&=\"(){throw new Error(\"The `&&=` operator is unsupported in TypeGPU functions.\")},get\"||=\"(){throw new Error(\"The `||=` operator is unsupported in TypeGPU functions.\")}};function h7(e,t,s){return s?Gj.includes(t)?ys:t===\"=\"?s:e:t===\"!\"?ys:e}var Wj={\"-\":Nw[mo].call.bind(Nw),void:()=>Je(void 0,zr,\"constant\",!1),\"!\":(e,[t])=>{if(t===void 0)throw new Error(\"The unary operator `!` expects 1 argument, but 0 were provided.\");if(qr(t))return Je(!t.value,ys,\"constant\",!1);let s=e.resolveSnippet(t).value;if(!ql(t.dataType))throw new jt(`Unary operator ! requires boolean operand. Got ${String(t.dataType)}.${Ox(t.dataType)?` For component-wise negation, use 'std.${xj.toString()}'.`:\"\"}`);return Je(`!(${s})`,ys,\"runtime\",t.possibleSideEffects)}},qj={\"+\":al[mo].call.bind(al),\"-\":As[mo].call.bind(As),\"*\":ra[mo].call.bind(ra),\"/\":cb[mo].call.bind(cb),\"**\":vt[mo].call.bind(vt)},g7={private:\"private\",workgroup:\"workgroup\",uniform:\"uniform\",mutable:\"storage, read_write\",readonly:\"storage, read\"},t0=2,Vj=class _E{#e=void 0;#t=[];static#s=_E.prototype.languageKey=\"wgsl\";initGenerator(t){if(this.#e!==void 0)throw new Error(\"Cannot initialize shader generators twice. Create one generator per resolution.\");this.#e=t}get ctx(){if(!this.#e)throw new Error(\"WGSL Generator has not yet been initialized. Please call initialize(ctx) before using the generator.\");return this.#e}_block([t,s],r,o){this.ctx.pushBlockScope();try{if(o){let d=Object.fromEntries(Object.entries(o).map(([u,p])=>[u,Ya(p)]));this.ctx.setBlockExternals(d)}let a=\"\",i=!1,l;this.ctx.indent();for(let d of s){let u=this._statement(d);if(u.code.length>0&&(a+=`${u.code}\n`),i||=u.definesInNearestScope??!1,u.endsWithControlFlow!==void 0){l=u.endsWithControlFlow;break}}this.ctx.dedent();let c=r&&!i;return this.ctx.blockDepth===t0&&(a=a.replace(/[ ]*return\\s*;\\s*$/u,\"\")),a===\"\"?{code:\"\",endsWithControlFlow:l,definesInNearestScope:!1}:c?{code:this.ctx.getDedented(a.trim()),endsWithControlFlow:l,definesInNearestScope:i}:{code:`{\n${a}${this.ctx.pre}}`,endsWithControlFlow:l,definesInNearestScope:!1}}finally{this.ctx.popBlockScope()}}_blockStatement(t,s){let{code:r,...o}=this._block(t,!0,s);return r===\"\"?{...o,code:\"\"}:{...o,code:`${this.ctx.pre}${r}`}}refVariable(t,s){let r=this.ctx.makeUniqueIdentifier(t,\"block\"),o=tM(s),a=Je(new Ji(Je(r,s,\"function\",!1),o),o,\"function\",!1);return this.ctx.defineVariable(t,a),r}_emitVarDecl(t,s,r,o){return`${this.ctx.pre}${t} ${s} = ${o};`}_identifier(t){if(!t)throw new Error(\"Cannot resolve an empty identifier\");if(t===\"undefined\")return Je(void 0,zr,\"constant\",!1);let s=this.ctx.getById(t);if(!s)throw new Error(`Identifier ${t} not found`);return s}_callShellless(t,s){let r=mb(t),o=r?t[ya]?.pairs??[]:[],a=r?t[ve].inner:t;return this.ctx.withRenamed(a,ct(t),()=>this.ctx.withSlots(o,()=>{let i=this.ctx.shelllessRepo.get(a,s);if(!i)return;let l=s.map((c,d)=>{let u=i.argTypes[d];return Ga(this.ctx,c,u,!1)});return this.ctx.withResetIndentLevel(()=>{let c=this.ctx.resolve(i);return Je(Ne`${c.value}(${l})`,c.dataType,\"runtime\")})}))}_typedExpression(t,s){let r=this.ctx.expectedType;this.ctx.expectedType=s;try{let o=this._expression(t);return s instanceof ti?o:Ga(this.ctx,o,s)}finally{this.ctx.expectedType=r}}_expression(t){if(typeof t==\"string\")return this._identifier(t);if(typeof t==\"boolean\")return Je(t,ys,\"constant\",!1);if(t[0]===Fs.logicalExpr){let[s,r,o,a]=t,i=this._expression(r);if(qr(i)){let u=ql(this.ctx.expectedType);if(!(o===\"&&\"?i.value:!i.value))return u?Je(o===\"||\",ys,\"constant\",!1):Ya(i.value);let p=this._expression(a);if(qr(p)){let _=Ya(p.value);return u?Ga(this.ctx,_,ys,!1):_}if(p.dataType===Ns)throw new jt(`Right-hand side of '${o}' is of unknown type`);return u?Ga(this.ctx,p,ys,!1):p}let l=this._expression(a);if(i.dataType===Ns)throw new jt(`Left-hand side of '${o}' is of unknown type`);if(!qr(l)&&l.dataType===Ns)throw new jt(`Right-hand side of '${o}' is of unknown type`);if(!ql(i.dataType)||!ql(l.dataType))throw new jt(`Logical expression '${o}' requires boolean operands. Got '${String(i.dataType)}' and '${String(l.dataType)}'.`);let c=this.ctx.resolveSnippet(i).value,d=this.ctx.resolveSnippet(l).value;return Je(`(${c} ${o} ${d})`,ys,\"runtime\",i.possibleSideEffects||l.possibleSideEffects)}if(t[0]===Fs.binaryExpr||t[0]===Fs.assignmentExpr){let[s,r,o,a]=t,i=this._expression(r),l=this._expression(a);if(l.value instanceof Ji)throw new jt(Ne`Cannot assign a ref to an existing variable '${ur(r)}', define a new variable instead.`);if(o===\"==\")throw new Error(\"Please use the === operator instead of ==\");if(o===\"!=\")throw new Error(\"Please use the !== operator instead of !=\");let c=Fj[o];if(c&&qr(i)&&qr(l)){let f=i.value,h=l.value;switch(o){case\"===\":return Je(f===h,ys,\"constant\",!1);case\"!==\":return Je(f!==h,ys,\"constant\",!1)}if(typeof f!=\"number\"||typeof h!=\"number\")throw new jt(`Comparison '${o}' requires numeric operands.${js(i.dataType)&&js(l.dataType)?` For component-wise comparison, use 'std.${c}'.`:\"\"}`);switch(o){case\"<\":return Je(f<h,ys,\"constant\",!1);case\"<=\":return Je(f<=h,ys,\"constant\",!1);case\">\":return Je(f>h,ys,\"constant\",!1);case\">=\":return Je(f>=h,ys,\"constant\",!1)}}if(i.dataType===Ns)throw new jt(`Left-hand side of '${o}' is of unknown type`);if(l.dataType===Ns)throw new jt(`Right-hand side of '${o}' is of unknown type`);let d=qj[o];if(d)return d(this.ctx,[i,l]);let u,p;if(Ij.includes(o)){let f=i.dataType;if(!EC(f)&&!tN(f))throw new jt(`Expression: ${ur(t)}\nLeft-hand side of '${o}' must be an integer or vector of integers.\nGot ${this.ctx.resolve(f).value}.`);let h=js(f)?f.primitive:f;if([\">>>\",\">>>=\"].includes(o)&&h.type!==\"u32\")throw new jt(`Expression: ${ur(t)}\nLeft-hand side of '${o}' must be an unsigned integer or vector of unsigned integers.\nGot ${this.ctx.resolve(f).value}.\nUse ${o.slice(1)} instead.`);[\">>\",\">>=\"].includes(o)&&h.type===\"u32\"&&rr.warn(\"deprecated\",`\nExpression: ${ur(t)}\nUsing u32 or vecN<u32> as left-hand side of ${o} is deprecated.\nUse >${o} instead.`);let g;if(js(f)){let y=f.componentCount;g=y===2?$s:y===3?Ps:Is}else g=M;p=Ga(this.ctx,l,g,!1),u=i}else{let f=s===Fs.assignmentExpr?[i.dataType]:void 0;[u,p]=Nl(this.ctx,[i,l],f)??[i,l]}let _=h7(u.dataType,o,p.dataType);if(s===Fs.assignmentExpr&&(y7(u,t),this.tryMarkModified(r),o===\"=\"&&gi(l)&&!jn(l.dataType)))throw new jt(`'${ur(t)}' is invalid, because references cannot be assigned.\n-----\nTry '${ur(r)} = ${this.ctx.resolve($c(l.dataType)).value}(${ur(a)})' to copy the value instead.\n-----`);if(c){let f=[\"===\",\"!==\"].includes(o);if(!(tb(u.dataType)&&tb(p.dataType)||f&&ql(u.dataType)&&ql(p.dataType))){let h=js(u.dataType)&&js(p.dataType);throw new jt(`Comparison '${o}' requires numeric${f?\" or boolean\":\"\"} operands. Got '${String(u.dataType)}' and '${String(p.dataType)}'.${h?` For component-wise comparison, use 'std.${c}'.`:\"\"}`)}}return Je(this.emitBinaryOp(u,Yj[o]??o,p),_,\"runtime\",s===Fs.assignmentExpr||i.possibleSideEffects||l.possibleSideEffects)}if(t[0]===Fs.postUpdate)throw new Error(`'${ur(t)}' is invalid because update is only allowed as a statement.`);if(t[0]===Fs.unaryExpr){let[s,r,o]=t,a=this._expression(o),i=Wj[r];if(i)return i(this.ctx,[a]);let l=this.ctx.resolveSnippet(a).value,c=h7(a.dataType,r);return Je(`${r}${l}`,c,\"runtime\",a.possibleSideEffects)}if(t[0]===Fs.memberAccess){let[s,r,o]=t,a=Cu(this._expression(r),o);if(!a)throw new Error(`Property '${o}' not found on '${ur(r)}'`);return a}if(t[0]===Fs.indexAccess){let[s,r,o]=t,a=this._expression(r),i=this._expression(o),l=Bh(a,Nl(this.ctx,[i],[M,j],!1)?.[0]??i);if(!l)throw new Error(`Index access '${ur(t)}' is invalid. If the value is an array, to address this, consider one of the following approaches: (1) declare the array using 'tgpu.const', (2) store the array in a buffer, or (3) define the array within the GPU function scope.`);return l}if(t[0]===Fs.numericLiteral){let s=typeof t[1]==\"string\"?Ai($j(t[1])):Ai(t[1]);return kr(s,`Expected ${ur(t)} to be valid numeric literal`),s}if(t[0]===Fs.call){let[s,r,o]=t,a=this._expression(r),i=_7.has(a.value)?Je(_7.get(a.value),Ns,\"runtime\",a.possibleSideEffects):a;if(Bj().includes(i.value))return this.ctx.generateLog(i.value,o.map(d=>this._expression(d)));if(_r(i.value)){if(o.length>1)throw new jt(\"Struct schemas should always be called with at most 1 argument\");if(!o[0])return Je(`${this.ctx.resolve(i.value).value}()`,i.value,\"runtime\",!1);let d=this._typedExpression(o[0],i.value);return Je(this.ctx.resolveSnippet(d).value,i.value,\"runtime\",d.possibleSideEffects)}if(io(i.value)){if(o.length>1)throw new jt(\"Array schemas should always be called with at most 1 argument\");if(!o[0])return this.typeInstantiation(i.value,[]);let d=this._typedExpression(o[0],i.value);return d.value instanceof Sm?this.typeInstantiation(i.value,d.value.elements):Je(this.ctx.resolveSnippet(d).value,i.value,\"runtime\",d.possibleSideEffects)}if(i.value===w3)throw new Error(\"Constants cannot be defined within TypeGPU function scope. To address this, move the constant definition outside the function scope.\");if(_$(i.value)){if(!o[0])throw new jt(`An infix operator '${ct(i.value.operator)}' was called without any arguments`);let d=Ya(i.value.lhs),u=this._expression(o[0]);return i.value.operator[mo].call(this.ctx,[d,u])}if((i.value===SN||i.value===uE)&&o[0]&&this.tryMarkModified(o[0]),N1(i.value)){let d=i.value[mo],u=d.strictSignature,p;u?p=o.map((_,f)=>{let h=u.argTypes[f];if(!h)throw new jt(`Call '${ur(t)}' is invalid since the function expected fewer arguments`);return this._typedExpression(_,h)}):p=o.map(_=>this._expression(_));try{return d.call(this.ctx,p)}catch(_){throw _ instanceof fu?_:new fu(_,[{toString:()=>`fn:${ct(i.value)}`}])}}if(!_s(i.value)||mb(i.value)){let d=o.map(p=>this._expression(p)),u=this._callShellless(i.value,d);if(u)return u}let l=Object.getOwnPropertyNames(Math).find(d=>Math[d]===i.value);if(l)throw new Error(`Unsupported Math functionality 'Math.${l}()'. Use an std alternative, or implement the function manually.`);let c=Object.getOwnPropertyNames(console).find(d=>console[d]===i.value);throw c?new Error(`Unsupported console functionality 'console.${c}()'.`):new Error(`Function '${ct(i.value)??String(i.value)}' is not marked with the 'use gpu' directive and cannot be used in a shader`)}if(t[0]===Fs.objectExpr){let s=t[1],r=this.ctx.expectedType;if(r instanceof ti){let o=Object.fromEntries(Object.entries(s).map(([l,c])=>{let d=r.accessProp(l),u;if(d)u=this._typedExpression(c,d.type);else{if(u=this._expression(c),u.dataType===Ns)throw new jt(Ne`Property ${l} in object literal has a value of unknown type: '${u}'`);d=r.provideProp(l,$c(dn(u.dataType)))}return[d.prop,u]})),a=r.completeStruct,i=Bw(this.ctx,a,o);return Je(Ne`${this.ctx.resolve(r).value}(${i})`,a,\"runtime\")}if(_r(r)){let o=Object.fromEntries(Object.entries(r.propTypes).map(([i,l])=>{let c=s[i];if(c===void 0)throw new jt(`Missing property ${i} in object literal for struct ${r}`);return[i,this._typedExpression(c,l)]})),a=Bw(this.ctx,r,o);return Je(Ne`${this.ctx.resolve(r).value}(${a})`,r,\"runtime\",a.some(i=>i.possibleSideEffects))}throw new jt(`No target type could be inferred for object '${ur(t)}', please wrap the object in the corresponding schema.`)}if(t[0]===Fs.arrayExpr){let[s,r]=t,o=this.ctx.expectedType,a,i;if(io(o)){if(a=o.elementType,i=r.map(d=>this._typedExpression(d,a)),i.length!==o.elementCount)throw new jt(`Cannot create value of type '${o}' from an array of length: ${i.length}`)}else{let d=r.map(p=>this._expression(p));if(d.length===0)throw new jt(\"Cannot infer the type of an empty array literal.\");let u=Nl(this.ctx,d);if(!u)throw new jt(`Values '${ur(t)}' cannot be automatically converted to a common type. Consider wrapping the array in an appropriate schema`);i=u,a=dn(i[0]?.dataType)}let l=Fe(a,i.length),c=i.every(d=>d.origin===\"constant\");return Je(new Sm(l,i),l,c?\"constant\":\"runtime\",i.some(d=>d.possibleSideEffects))}if(t[0]===Fs.conditionalExpr){let[s,r,o,a]=t,i=this._expression(r);if(qr(i))return i.value?this._expression(o):this._expression(a);{let l=Ga(this.ctx,i,ys,!1),c=this._expression(o),d=this._expression(a),[u,p]=Nl(this.ctx,[c,d],k1)??[];if(!u||!p||c.possibleSideEffects||d.possibleSideEffects||gi(c)&&!jn(c.dataType)||gi(d)&&!jn(d.dataType))throw new Error(`Ternary operator '${ur(t)}' is invalid. For more complex branching, please use 'std.select' or if/else statements.`);return Je(Ne`select(${p}, ${u}, ${l})`,u.dataType,\"runtime\",i.possibleSideEffects)}}if(t[0]===Fs.stringLiteral)return Je(t[1],Ns,\"constant\",!1);if(t[0]===Fs.preUpdate)throw new Error(\"Cannot use pre-updates in TypeGPU functions.\");Nj(t)}declareGlobalConst(t){let s=this.ctx.resolve(t.dataType).value,r=this.ctx.resolveSnippet(t.init).value;return this.ctx.addDeclaration(`const ${t.id}: ${s} = ${r};`,t.id),Je(t.id,t.dataType,\"constant-immutable-def\")}declareGlobalVar(t){let s=\"\";return t.group!==void 0&&(s+=`@group(${t.group}) `),t.binding!==void 0&&(s+=`@binding(${t.binding}) `),t.scope in g7?s+=`var<${g7[t.scope]}> `:s+=\"var \",s+=`${t.id}: ${this.ctx.resolve(t.dataType).value}`,this.ctx.addDeclaration(t.init?`${s} = ${this.ctx.resolveSnippet(t.init).value};`:`${s};`,t.id),Je(t.id,t.dataType,t.scope)}functionDefinition(t){kr(this.ctx.blockDepth===t0-1,`Expecting exactly ${t0-1} block(s) before going into the first function block scope`);let s=this._block(t.body,!1),r=this.ctx.topFunctionScope;kr(r,\"Expected function scope to be present\");let o=Object.fromEntries([...r.placeholderForVariable.entries()].map(([d,u])=>[u,r.modifiedVariables.has(d)?\"var\":\"let\"]));if(Object.keys(o).length>0){let d=new RegExp(Object.keys(o).join(\"|\"),\"gi\");s.code=s.code.replace(d,u=>o[u]??\"#ERR\")}let a=t.determineReturnType(),i=t.args.filter(d=>d.used||t.functionType===\"normal\").map(d=>`${Ym(d.decoratedType)}${d.name}: ${this.ctx.resolve(d.decoratedType).value}`).join(\", \"),l=a.type!==\"void\"?`(${i}) -> ${Ym(a)}${this.ctx.resolve(a).value} `:`(${i}) `,c=\"\";if(t.functionType===\"compute\"){if(!t.workgroupSize)throw new Error(\"Compute shaders must have a workgroup size\");c=`@compute @workgroup_size(${t.workgroupSize.join(\", \")}) `}else t.functionType===\"vertex\"?c=\"@vertex \":t.functionType===\"fragment\"&&(c=\"@fragment \");return`${c}fn ${t.name}${l}${s.code||\"{}\"}`}emitTypeAnnotation(t){return cE(this.ctx,t)}typeInstantiation(t,s){return s.length===1&&s[0]?.dataType===t?Je(Ne`${s[0]}`,t,fN(s[0].origin),s[0].possibleSideEffects):Je(Ne`${this.ctx.resolve(t).value}(${s})`,t,\"runtime\",s.some(r=>r.possibleSideEffects))}numericLiteral(t,s){if(!Number.isFinite(t))throw new Error(`Value '${t}' (${s.type}) cannot be resolved due to WGSL's Finite Math Assumption (see: https://www.w3.org/TR/WGSL/#finite-math-assumption). This value might be a result of a comptime-evaluated operation.`);if(s.type===\"abstractInt\")return Je(`${t}`,s,\"constant\",!1);if(s.type===\"u32\")return Je(`${t}u`,s,\"constant\",!1);if(s.type===\"i32\")return Je(`${t}i`,s,\"constant\",!1);let r=t.toExponential(),o=s.type===\"abstractFloat\"&&Number.isInteger(t)?`${t}.`:`${t}`,a=r.length<o.length?r:o;return s.type===\"f32\"?Je(`${a}f`,s,\"constant\",!1):s.type===\"f16\"?Je(`${a}h`,s,\"constant\",!1):Je(a,s,\"constant\",!1)}emitCall(t,s,r){let o=s.map(i=>this.ctx.resolveSnippet(i).value).join(\", \"),a=r.map(i=>this.ctx.resolveSnippet(i).value).join(\", \");return o.length>0?`${t}<${o}>(${a})`:`${t}(${a})`}emitBinaryOp(t,s,r){let o=this.ctx.resolveSnippet(t).value,a=this.ctx.resolveSnippet(r).value;return Oj.includes(s)?`(${o} ${s} ${a})`:`${o} ${s} ${a}`}_return(t){let s=t[1];if(s!==void 0){let r=this.ctx.topFunctionReturnType,o=r?this._typedExpression(s,r):this._expression(s);if(o.value===void 0&&hh(o.dataType))return this.ctx.reportReturnType(zr),`${this.ctx.pre}return;`;if(o.value instanceof Ji)throw new jt(`Cannot return '${ur(s)}' because it is a d.ref`);if(o.origin===\"argument\"&&!jn(o.dataType)&&this.ctx.topFunctionScope?.functionType===\"normal\")throw new jt(`'${ur(t)}' is invalid, cannot return references to arguments. Copy the argument before returning it.`);if(!r&&gi(o)&&!jn(o.dataType)&&o.origin!==\"local-def\"){let a=ur(s),i=this.ctx.resolve($c(o.dataType)).value;throw new jt(`'return ${a};' is invalid, cannot return references.\n-----\nTry 'return ${i}(${a});' instead.\n-----`)}return o=Ga(this.ctx,o,$c(o.dataType),!1),kr(o.dataType!==Ns,\"Return type should be known\"),this.ctx.reportReturnType(o.dataType),Ne`${this.ctx.pre}return ${o};`}return this.ctx.reportReturnType(zr),`${this.ctx.pre}return;`}_letStatement(t){let[s,r,o]=t;if(o===void 0)throw new Error(`'${ur(t)}' is invalid because all variables need initializers.`);let a=this._expression(o);if(a.value instanceof Ji){let f=ur(o);throw new jt(`'let ${r} = ${f}' is invalid, cannot initialize 'let' variables with d.ref()\n-----\n- Try 'const ${r} = ${f}'.\n-----`)}let i=a.dataType;if(i===Ns){let f=ur(o);throw new jt(`'let ${r} = ${f}' is invalid, cannot determine WGSL type of '${f}'\n-----\n- Try using or defining a schema that matches your desired value the most, and wrap the value with it: 'let ${r} = Schema(${f})'\n-----`)}if(gi(a)&&!jn(a.dataType)){let f=ur(o),h=this.ctx.resolve($c(a.dataType)).value;throw new jt(`'let ${r} = ${f}' is invalid, because references cannot be assigned to 'let' variable declarations.\n-----\n- Try 'let ${r} = ${h}(${f})' if you need to reassign '${r}' later\n- Try 'const ${r} = ${f}' if you won't reassign '${r}' later.\n-----`)}let l=dn(i),c=Je(this.ctx.makeUniqueIdentifier(r,\"block\"),l,\"local-def\",!1);this.ctx.defineVariable(r,c);let d=Ga(this.ctx,a,i,!1),u=this.ctx.resolveSnippet(d).value,p=this.ctx.topFunctionScope;kr(p,`Expected function scope to be present for ${r}`);let _=`#VAR_${p.placeholderForVariable.size}#`;return p.placeholderForVariable.set(c,_),{code:this._emitVarDecl(_,c.value,l,u),definesInNearestScope:!0}}_constStatement(t){let[s,r,o]=t;if(o===void 0)throw new Error(`'${ur(t)}' is invalid because all variables need initializers.`);let a=this._expression(o);if(a.value instanceof Ji){if(a.dataType!==Ns)throw new jt(\"Cannot store d.ref() in a variable if it references another value. Copy the value passed into d.ref() instead.\");let g=a.value.snippet,y=this.refVariable(r,dn(g.dataType));return{code:Ne`${this.ctx.pre}var ${y} = ${Ga(this.ctx,g,g.dataType,!1)};`,definesInNearestScope:!0}}let i=jn(a.dataType),l=\"local-def\",c=\"<deferred>\",d=a.dataType;if(d===Ns){let g=ur(o);throw new jt(`'const ${r} = ${g}' is invalid, cannot determine WGSL type of '${g}'\n-----\n- Try using or defining a schema that matches your desired value the most, and wrap the value with it: 'const ${r} = Schema(${g})'\n-----`)}if(a.origin===\"argument\")c=\"let\",l=i?\"local-def\":\"argument\";else if(a.origin===\"constant-immutable-def\")c=\"const\",l=\"constant-immutable-def\";else if(a.origin===\"runtime-immutable-def\")c=\"let\",l=\"runtime-immutable-def\";else if(i)c=a.origin===\"constant\"?\"const\":\"let\",l=\"local-def\";else if(!gi(a))c=\"<deferred>\",l=\"local-def\";else return this._aliasConstStatement(r,o,a);let u=dn(d),p=Je(this.ctx.makeUniqueIdentifier(r,\"block\"),u,l,!1);this.ctx.defineVariable(r,p);let _=Ga(this.ctx,a,d,!1),f=this.ctx.resolveSnippet(_).value,h;if(c===\"<deferred>\"){let g=this.ctx.topFunctionScope;kr(g,`Expected function scope to be present for ${r}`),h=`#VAR_${g.placeholderForVariable.size}#`,g.placeholderForVariable.set(p,h)}else h=c;return{code:this._emitVarDecl(h,p.value,u,f),definesInNearestScope:!0}}_aliasConstStatement(t,s,r){let o=r.dataType;if(!ta(o)){let d=Wx(r.origin,dn(o));kr(d!==void 0,`Creating pointer type from origin ${r.origin}`),o=d}o=sM(o),this.tryMarkModified(s);let a=dn(o),i=Je(this.ctx.makeUniqueIdentifier(t,\"block\"),a,r.origin,!1);this.ctx.defineVariable(t,i);let l=Ga(this.ctx,r,o,!1),c=this.ctx.resolveSnippet(l).value;return{code:this._emitVarDecl(\"let\",i.value,a,c),definesInNearestScope:!0}}_statement(t){if(typeof t==\"string\"){let o=this._identifier(t),a=o.value!==void 0&&o.value!==null?this.ctx.resolveSnippet(o).value:\"\";return{code:a?`${this.ctx.pre}${a};`:\"\",definesInNearestScope:!1}}if(typeof t==\"boolean\")return{code:`${this.ctx.pre}${t?\"true\":\"false\"};`,definesInNearestScope:!1};if(t[0]===Fs.return)return{code:this._return(t),endsWithControlFlow:\"return\",definesInNearestScope:!1};if(t[0]===Fs.if){let[o,a,i,l]=t,c=this._typedExpression(a,ys);if(typeof c.value==\"boolean\"){let p=c.value?i:l;return p===void 0?{code:\"\",definesInNearestScope:!1}:(Array.isArray(p)||(p=qc(p)),p[0]===Fs.block&&p[1].length===1&&p[1][0][0]===Fs.if?this._statement(p[1][0]):p[0]===Fs.if?this._statement(p):this._blockStatement(qc(p)))}let d=this._block(qc(i),!1),u=l?this._block(qc(l),!1).code:void 0;return u?{code:Ne`\\\n${this.ctx.pre}if (${c}) ${d.code||\"{}\"}\n${this.ctx.pre}else ${u}`,definesInNearestScope:!1}:{code:Ne`${this.ctx.pre}if (${c}) ${d.code||\"{}\"}`,definesInNearestScope:!1}}if(t[0]===Fs.let)return this._letStatement(t);if(t[0]===Fs.const)return this._constStatement(t);if(t[0]===Fs.block)return this._blockStatement(t);if(t[0]===Fs.for){let[o,a,i,l,c]=t,d=this.#t;this.#t=[];try{this.ctx.pushBlockScope();let[u,p,_]=this.ctx.withResetIndentLevel(()=>[a?this._statement(a).code:void 0,i?this._typedExpression(i,ys):void 0,l?this._statement(l).code:void 0]),f=u?u.slice(0,-1):\"\",h=_?_.slice(0,-1):\"\",g=this._block(qc(c),!1).code;return{code:Ne`${this.ctx.pre}for (${f}; ${p}; ${h}) ${g||\"{}\"}`,definesInNearestScope:!1}}finally{this.#t=d,this.ctx.popBlockScope()}}if(t[0]===Fs.while){let o=this.#t;this.#t=[];try{let[a,i,l]=t,c=this._typedExpression(i,ys),d=this.ctx.resolveSnippet(c).value,u=this._block(qc(l),!1).code;return{code:`${this.ctx.pre}while (${d}) ${u||\"{}\"}`,definesInNearestScope:!1}}finally{this.#t=o}}if(t[0]===Fs.forOf){let[o,a,i,l]=t;if(a[0]!==Fs.const)throw new jt(\"Only `for (const ... of ... )` loops are supported\");this.tryMarkModified(i);let c=!1,d=this.#t;try{this.ctx.pushBlockScope();let u=this._expression(i),p=u.value instanceof dE,_=p?u.value.snippet:u,f=Lj(this.ctx,_,p),h=a[1],g=qc(l);if(p){if(!qr(f.end))throw new Error(\"Cannot unroll loop. Length of iterable is unknown at comptime.\");let P=f.end.value;if(P===0)return{code:\"\",definesInNearestScope:!1};let{value:C}=_,E=bb(C)?C.map(D=>Ya(D)):C instanceof Sm?C.elements:Array.from({length:P},(D,O)=>v7(_,Je(O,M,\"constant\"))),R=E[0];if(!gi(R)&&!jn(R.dataType))throw new jt(`Cannot unroll '${ur(i)}'. The elements of iterable are constructed in place but are not value types.`);let U=\"\",L,k=!1;for(let D=0;D<E.length;D++){let O=E[D];this.#t=[...d,D];let F=this._blockStatement(g,{[h]:O});if(k||=F.definesInNearestScope,U+=`${this.ctx.pre}// unrolled iteration ${this.#t.map(q=>`#${q}`).join(\" / \")}\n${F.code}\n`,F.endsWithControlFlow!==void 0){L=F.endsWithControlFlow;break}}return{code:`${U}${this.ctx.pre}// ---`,endsWithControlFlow:L,definesInNearestScope:k}}this.#t=[];let y=this.ctx.makeUniqueIdentifier(\"i\",\"block\"),b=Ne`${this.ctx.pre}for (var ${y} = ${f.start}; ${y} ${f.comparison} ${f.end}; ${y} += ${f.step})`,x=\"\";if(bb(_.value))x=this._block(g,!1,{[h]:Je(y,f.start.dataType,\"runtime\",!1)}).code;else{this.ctx.indent(),c=!0;let P=this.ctx.makeUniqueIdentifier(h,\"block\"),C=v7(_,Je(y,M,\"runtime\")),E=Rj(C),R=Dj(C,_);x=`{\n${Ne`${this.ctx.pre}${E} ${P} = ${Ga(this.ctx,C,R,!1)};`}\n${this._blockStatement(g,{[h]:Je(P,R,C.origin,!1)}).code}\n`,this.ctx.dedent(),x+=`${this.ctx.pre}}`,c=!1}return{code:Ne`${b} ${x.trim()||\"{}\"}`,definesInNearestScope:!1}}finally{c&&this.ctx.dedent(),this.#t=d,this.ctx.popBlockScope()}}if(t[0]===Fs.postUpdate){let[o,a,i]=t,l=this._expression(i),c=this.ctx.resolveSnippet(l).value;return y7(l,t),this.tryMarkModified(i),{code:`${this.ctx.pre}${c}${a};`,definesInNearestScope:!1}}if(t[0]===Fs.continue){if(this.#t.length>0)throw new jt(\"Cannot unroll loop containing `continue`\");return{code:`${this.ctx.pre}continue;`,endsWithControlFlow:\"continue\",definesInNearestScope:!1}}if(t[0]===Fs.break){if(this.#t.length>0)throw new jt(\"Cannot unroll loop containing `break`\");return{code:`${this.ctx.pre}break;`,endsWithControlFlow:\"break\",definesInNearestScope:!1}}let s=this._expression(t),r=s.value!==void 0&&s.value!==null?this.ctx.resolveSnippet(s).value:\"\";return{code:r?`${this.ctx.pre}${r};`:\"\",definesInNearestScope:!1}}tryMarkModified(t){if(!t)return;let s=Xj(t);if(s!==void 0){let r=this.ctx.getById(s),o=this.ctx.topFunctionScope;r&&o&&o.placeholderForVariable.has(r)&&o.modifiedVariables.add(r)}}};function y7(e,t){if(e.origin===\"constant\"||e.origin===\"constant-immutable-def\"||e.origin===\"runtime-immutable-def\")throw qr(e)?new jt(`'${ur(t)}' is invalid, because the left side is defined outside of the shader, and therefore is immutable during its execution. Try using tgpu.privateVar or buffers.`):new jt(`'${ur(t)}' is invalid, because the left side is a constant.`);if(e.origin===\"uniform\")throw new jt(`'${ur(t)}' is invalid, because uniform buffers cannot be mutated.`);if(e.origin===\"readonly\")throw new jt(`'${ur(t)}' is invalid, because readonly buffers cannot be mutated.`);if(e.origin===\"argument\")throw new jt(`'${ur(t)}' is invalid, because non-pointer arguments cannot be mutated.`)}function Nj(e){throw new Error(`'${pn(e)}' was not handled by the WGSL generator.`)}function $j(e){return/^0x[0-9a-f]+$/i.test(e)?Number.parseInt(e):/^0b[01]+$/i.test(e)?Number.parseInt(e.slice(2),2):Number.parseFloat(e)}function qc(e){return typeof e!=\"object\"||e[0]!==Fs.block?[Fs.block,[e]]:e}function Xj(e){let t=e;for(;Array.isArray(t)&&(t[0]===Fs.memberAccess||t[0]===Fs.indexAccess);)t=t[1];if(typeof t==\"string\")return t}var Hj=(()=>{try{return new Function(\"return true\"),!0}catch{return!1}})(),b7=new WeakMap,x7=!1,jf={u32:\"u32\",vec2u:\"u32\",vec3u:\"u32\",vec4u:\"u32\",u16:\"u16\",i32:\"i32\",vec2i:\"i32\",vec3i:\"i32\",vec4i:\"i32\",f32:\"f32\",vec2f:\"f32\",vec3f:\"f32\",vec4f:\"f32\",f16:\"f16\",vec2h:\"f16\",vec3h:\"f16\",vec4h:\"f16\",mat2x2f:\"f32\",mat3x3f:\"f32\",mat4x4f:\"f32\"},jj={uint8:\"u8\",uint8x2:\"u8\",uint8x4:\"u8\",sint8:\"i8\",sint8x2:\"i8\",sint8x4:\"i8\",unorm8:\"u8\",unorm8x2:\"u8\",unorm8x4:\"u8\",snorm8:\"i8\",snorm8x2:\"i8\",snorm8x4:\"i8\",uint16:\"u16\",uint16x2:\"u16\",uint16x4:\"u16\",sint16:\"i16\",sint16x2:\"i16\",sint16x4:\"i16\",unorm16:\"u16\",unorm16x2:\"u16\",unorm16x4:\"u16\",snorm16:\"i16\",snorm16x2:\"i16\",snorm16x4:\"i16\",float16:\"f16\",float16x2:\"f16\",float16x4:\"f16\",float32:\"f32\",float32x2:\"f32\",float32x3:\"f32\",float32x4:\"f32\",uint32:\"u32\",uint32x2:\"u32\",uint32x3:\"u32\",uint32x4:\"u32\",sint32:\"i32\",sint32x2:\"i32\",sint32x3:\"i32\",sint32x4:\"i32\"},Kf={u32:\"setUint32\",i32:\"setInt32\",f32:\"setFloat32\",u16:\"setUint16\",i16:\"setInt16\",f16:\"setFloat16\",u8:\"setUint8\",i8:\"setInt8\"},Kj={unorm8:e=>`Math.round(${e} * 255)`,unorm8x2:e=>`Math.round(${e} * 255)`,unorm8x4:e=>`Math.round(${e} * 255)`,snorm8:e=>`Math.round(${e} * 127)`,snorm8x2:e=>`Math.round(${e} * 127)`,snorm8x4:e=>`Math.round(${e} * 127)`,unorm16:e=>`Math.round(${e} * 65535)`,unorm16x2:e=>`Math.round(${e} * 65535)`,unorm16x4:e=>`Math.round(${e} * 65535)`,snorm16:e=>`Math.round(${e} * 32767)`,snorm16x2:e=>`Math.round(${e} * 32767)`,snorm16x4:e=>`Math.round(${e} * 32767)`},A7={\"unorm10-10-10-2\":{writeFunction:\"setUint32\",generator:(e,t)=>`output.setUint32(${e}, ((${t}.x*1023&0x3FF)<<22)|((${t}.y*1023&0x3FF)<<12)|((${t}.z*1023&0x3FF)<<2)|(${t}.w*3&3), littleEndian);\n`},\"unorm8x4-bgra\":{writeFunction:\"setUint8\",generator:(e,t)=>[\"z\",\"y\",\"x\",\"w\"].map((s,r)=>`output.setUint8((${e} + ${r}), Math.round(${t}.${s} * 255), littleEndian);\n`).join(\"\")}};function w7(e,t,s,r=0,o=!1){let a=(c,d,u)=>o?`if (${d} < endOffset) { output.${c}(${d}, ${u}, littleEndian); }\n`:`output.${c}(${d}, ${u}, littleEndian);\n`,i=(c,d)=>o?`if (${c} < endOffset) {\n${d}}\n`:d;function l(c,d,u,p){let _=[\"i\",\"j\",\"k\"][p]||`i${p}`;if(vh(c)||gl(c))return l(c.inner,d,u,p);if(_r(c)||ki(c))return Object.entries(kh(c)).map(([h,g])=>{let y=c.propTypes[h];return y?l(y,`(${d} + ${g.offset})`,`${u}.${h}`,p):\"\"}).join(\"\");if(io(c)||Sd(c)){if(c.elementCount===0)throw new Error(\"Cannot write using a runtime-sized schema.\");let h=Co(ds(c.elementType),xr(c)),g=c.elementCount*h,y=o?`Math.min(${u}.byteLength, Math.max(0, endOffset - (${d})))`:`Math.min(${u}.byteLength, ${g})`,b=`if (ArrayBuffer.isView(${u})) {\n`;return b+=`  new Uint8Array(output.buffer).set(new Uint8Array(${u}.buffer, ${u}.byteOffset, ${y}), output.byteOffset + (${d}));\n`,b+=`} else {\n`,b+=`for (let ${_} = 0; ${_} < ${c.elementCount}; ${_}++) {\n`,o&&(b+=`if ((${d} + ${_} * ${h}) >= endOffset) return;\n`),b+=l(c.elementType,`(${d} + ${_} * ${h})`,`${u}[${_}]`,p+1),b+=`}\n`,b+=`}\n`,b}if(js(c)){if(Ox(c))throw new Error(\"Compiled writers do not support boolean vectors\");let h=jf[c.type],g=ds(c.primitive),y=Kf[h];return Array.from({length:c.componentCount},(b,x)=>a(y,`(${d} + ${x*g})`,`${u}[${x}]`)).join(\"\")}if(xi(c)){let h=Kf[jf[c.type]],g=CC(c)?2:MC(c)?3:4,y=Co(g*4,8),b=[\"x\",\"y\",\"z\",\"w\"],x=y/4;return Array.from({length:g*g},(P,C)=>{let E=Math.floor(C/g),R=C%g,U=E*g+R,L=E*x+R;return a(h,`(${d} + ${E*y+R*4})`,`ArrayBuffer.isView(${u}) ? ${u}[${L}] : Array.isArray(${u}) ? ${u}[${U}] : ${u}.columns[${E}].${b[R]}`)}).join(\"\")}if(g$(c)){let h=c.type;if(h in A7){let R=A7[h];return i(`(${d})`,R.generator(d,u))}let g=jj[h],y=Kf[g],b=dl[h],x=js(b)?b.componentCount:1,P=g===\"u8\"||g===\"i8\"?1:g===\"u16\"||g===\"i16\"||g===\"f16\"?2:4,C=[\"x\",\"y\",\"z\",\"w\"],E=Kj[h];return Array.from({length:x},(R,U)=>{let L=x===1?u:`${u}.${C[U]}`,k=E?E(L):L;return a(y,`(${d} + ${U*P})`,k)}).join(\"\")}if(!Object.hasOwn(jf,c.type))throw new Error(`Primitive ${c.type} is unsupported by compiled writer`);let f=jf[c.type];return a(Kf[f],d,u)}return l(e,t,s,r)}function E3(e){if(!Hj){x7||(rr.warn(\"fallback\",\"This environment does not allow eval - using default writer as fallback\"),x7=!0);return}let t=b7.get(e);if(t)return t;try{let s=w7(e,\"offset\",\"value\",0,!1),r=`if (offset > 0 || endOffset < output.byteLength) {\n${w7(e,\"offset\",\"value\",0,!0)}} else {\n${s}}\n`,o=new Function(\"output\",\"offset\",\"value\",\"littleEndian=true\",\"endOffset=output.byteLength\",r);return b7.set(e,o),o}catch(s){rr.warn(\"fallback\",`Failed to compile writer for schema: ${e}\nReason: ${s instanceof Error?s.message:String(s)}\nFalling back to default writer`)}}function xo(e,t){e.writeUint16(j1(t))}function Ao(e){return $x(e.readUint16())}var pu={bool(){throw new Error(\"Booleans are not host-shareable\")},f32(e,t,s){e.writeFloat32(s)},f16(e,t,s){xo(e,s)},i32(e,t,s){e.writeInt32(s)},u32(e,t,s){e.writeUint32(s)},u16(e,t,s){e.writeUint16(s)},vec2f(e,t,s){e.writeFloat32(s[0]),e.writeFloat32(s[1])},vec2h(e,t,s){xo(e,s[0]),xo(e,s[1])},vec2i(e,t,s){e.writeInt32(s[0]),e.writeInt32(s[1])},vec2u(e,t,s){e.writeUint32(s[0]),e.writeUint32(s[1])},\"vec2<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},vec3f(e,t,s){e.writeFloat32(s[0]),e.writeFloat32(s[1]),e.writeFloat32(s[2])},vec3h(e,t,s){xo(e,s[0]),xo(e,s[1]),xo(e,s[2])},vec3i(e,t,s){e.writeInt32(s[0]),e.writeInt32(s[1]),e.writeInt32(s[2])},vec3u(e,t,s){e.writeUint32(s[0]),e.writeUint32(s[1]),e.writeUint32(s[2])},\"vec3<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},vec4f(e,t,s){e.writeFloat32(s[0]),e.writeFloat32(s[1]),e.writeFloat32(s[2]),e.writeFloat32(s[3])},vec4h(e,t,s){xo(e,s[0]),xo(e,s[1]),xo(e,s[2]),xo(e,s[3])},vec4i(e,t,s){e.writeInt32(s[0]),e.writeInt32(s[1]),e.writeInt32(s[2]),e.writeInt32(s[3])},vec4u(e,t,s){e.writeUint32(s[0]),e.writeUint32(s[1]),e.writeUint32(s[2]),e.writeUint32(s[3])},\"vec4<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},mat2x2f(e,t,s){for(let r=0;r<s.length;++r)e.writeFloat32(s[r])},mat3x3f(e,t,s){for(let r=0;r<s.length;++r)e.writeFloat32(s[r])},mat4x4f(e,t,s){for(let r=0;r<s.length;++r)e.writeFloat32(s[r])},struct(e,t,s){let r=xr(t);wo(e,r);for(let[o,a]of Object.entries(t.propTypes))wo(e,xr(a)),Z1(e,a,s[o]);wo(e,r)},array(e,t,s){if(t.elementCount===0)throw new Error(\"Cannot write using a runtime-sized schema.\");let r=xr(t);wo(e,r);let o=e.currentByteOffset;for(let a=0;a<Math.min(t.elementCount,s.length);a++)wo(e,r),Z1(e,t.elementType,s[a]);e.seekTo(o+ds(t))},ptr(){throw new Error(\"Pointers are not host-shareable\")},atomic(e,t,s){pu[t.inner.type]?.(e,t,s)},decorated(e,t,s){wo(e,wn(t));let r=e.currentByteOffset;pu[t.inner?.type]?.(e,t.inner,s),e.seekTo(r+ds(t))},uint8(e,t,s){e.writeUint8(s)},uint8x2(e,t,s){e.writeUint8(s.x),e.writeUint8(s.y)},uint8x4(e,t,s){e.writeUint8(s.x),e.writeUint8(s.y),e.writeUint8(s.z),e.writeUint8(s.w)},sint8(e,t,s){e.writeInt8(s)},sint8x2(e,t,s){e.writeInt8(s.x),e.writeInt8(s.y)},sint8x4(e,t,s){e.writeInt8(s.x),e.writeInt8(s.y),e.writeInt8(s.z),e.writeInt8(s.w)},unorm8(e,t,s){e.writeUint8(Math.round(s*255))},unorm8x2(e,t,s){e.writeUint8(Math.round(s.x*255)),e.writeUint8(Math.round(s.y*255))},unorm8x4(e,t,s){e.writeUint8(Math.round(s.x*255)),e.writeUint8(Math.round(s.y*255)),e.writeUint8(Math.round(s.z*255)),e.writeUint8(Math.round(s.w*255))},snorm8(e,t,s){e.writeInt8(Math.round(s*127))},snorm8x2(e,t,s){e.writeInt8(Math.round(s.x*127)),e.writeInt8(Math.round(s.y*127))},snorm8x4(e,t,s){e.writeInt8(Math.round(s.x*127)),e.writeInt8(Math.round(s.y*127)),e.writeInt8(Math.round(s.z*127)),e.writeInt8(Math.round(s.w*127))},uint16(e,t,s){e.writeUint16(s)},uint16x2(e,t,s){e.writeUint16(s.x),e.writeUint16(s.y)},uint16x4(e,t,s){e.writeUint16(s.x),e.writeUint16(s.y),e.writeUint16(s.z),e.writeUint16(s.w)},sint16(e,t,s){e.writeInt16(s)},sint16x2(e,t,s){e.writeInt16(s.x),e.writeInt16(s.y)},sint16x4(e,t,s){e.writeInt16(s.x),e.writeInt16(s.y),e.writeInt16(s.z),e.writeInt16(s.w)},unorm16(e,t,s){e.writeUint16(s*65535)},unorm16x2(e,t,s){e.writeUint16(s.x*65535),e.writeUint16(s.y*65535)},unorm16x4(e,t,s){e.writeUint16(s.x*65535),e.writeUint16(s.y*65535),e.writeUint16(s.z*65535),e.writeUint16(s.w*65535)},snorm16(e,t,s){e.writeInt16(Math.round(s*32767))},snorm16x2(e,t,s){e.writeInt16(Math.round(s.x*32767)),e.writeInt16(Math.round(s.y*32767))},snorm16x4(e,t,s){e.writeInt16(Math.round(s.x*32767)),e.writeInt16(Math.round(s.y*32767)),e.writeInt16(Math.round(s.z*32767)),e.writeInt16(Math.round(s.w*32767))},float16(e,t,s){xo(e,s)},float16x2(e,t,s){xo(e,s.x),xo(e,s.y)},float16x4(e,t,s){xo(e,s.x),xo(e,s.y),xo(e,s.z),xo(e,s.w)},float32(e,t,s){e.writeFloat32(s)},float32x2(e,t,s){e.writeFloat32(s.x),e.writeFloat32(s.y)},float32x3(e,t,s){e.writeFloat32(s.x),e.writeFloat32(s.y),e.writeFloat32(s.z)},float32x4(e,t,s){e.writeFloat32(s.x),e.writeFloat32(s.y),e.writeFloat32(s.z),e.writeFloat32(s.w)},uint32(e,t,s){e.writeUint32(s)},uint32x2(e,t,s){e.writeUint32(s.x),e.writeUint32(s.y)},uint32x3(e,t,s){e.writeUint32(s.x),e.writeUint32(s.y),e.writeUint32(s.z)},uint32x4(e,t,s){e.writeUint32(s.x),e.writeUint32(s.y),e.writeUint32(s.z),e.writeUint32(s.w)},sint32(e,t,s){e.writeInt32(s)},sint32x2(e,t,s){e.writeInt32(s.x),e.writeInt32(s.y)},sint32x3(e,t,s){e.writeInt32(s.x),e.writeInt32(s.y),e.writeInt32(s.z)},sint32x4(e,t,s){e.writeInt32(s.x),e.writeInt32(s.y),e.writeInt32(s.z),e.writeInt32(s.w)},\"unorm10-10-10-2\"(e,t,s){let r=0;r|=(s.x*1023&1023)<<22,r|=(s.y*1023&1023)<<12,r|=(s.z*1023&1023)<<2,r|=s.w*3&3,e.writeUint32(r)},\"unorm8x4-bgra\"(e,t,s){e.writeUint8(s.z*255),e.writeUint8(s.y*255),e.writeUint8(s.x*255),e.writeUint8(s.w*255)},disarray(e,t,s){let r=xr(t);wo(e,r);let o=e.currentByteOffset;for(let a=0;a<Math.min(t.elementCount,s.length);a++)wo(e,r),pu[t.elementType?.type]?.(e,t.elementType,s[a]);e.seekTo(o+ds(t))},unstruct(e,t,s){let r=t.propTypes;for(let[o,a]of Object.entries(r))pu[a.type]?.(e,a,s[o])},\"loose-decorated\"(e,t,s){wo(e,wn(t));let r=e.currentByteOffset,o=pu[t.inner?.type];return o?.(e,t.inner,s),e.seekTo(r+ds(t)),s}};function Z1(e,t,s){if(ArrayBuffer.isView(s)){let o=s,a=ds(t);o.byteLength!==a&&rr.warn(\"suspicious\",`TypedArray size mismatch: schema expects ${a} bytes, got ${o.byteLength}. `+(o.byteLength<a?\"Data truncated.\":\"Excess ignored.\"));let i=e.currentByteOffset;e.writeSlice(new Uint8Array(o.buffer,o.byteOffset,Math.min(o.byteLength,a))),e.seekTo(i+a);return}let r=pu[t.type];if(!r)throw new Error(`Cannot write data of type '${t.type}'.`);r(e,t,s)}var Qj={bool(){throw new Error(\"Booleans are not host-shareable\")},f32(e){return e.readFloat32()},f16(e){return Ao(e)},i32(e){return e.readInt32()},u32(e){return e.readUint32()},u16(e){return e.readUint16()},vec2f(e){return ps(e.readFloat32(),e.readFloat32())},vec3f(e){return Zs(e.readFloat32(),e.readFloat32(),e.readFloat32())},vec4f(e){return qt(e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32())},vec2h(e){return To(Ao(e),Ao(e))},vec3h(e){return Pa(Ao(e),Ao(e),Ao(e))},vec4h(e){return So(Ao(e),Ao(e),Ao(e),Ao(e))},vec2i(e){return ir(e.readInt32(),e.readInt32())},vec3i(e){return Br(e.readInt32(),e.readInt32(),e.readInt32())},vec4i(e){return sr(e.readInt32(),e.readInt32(),e.readInt32(),e.readInt32())},vec2u(e){return $s(e.readUint32(),e.readUint32())},vec3u(e){return Ps(e.readUint32(),e.readUint32(),e.readUint32())},vec4u(e){return Is(e.readUint32(),e.readUint32(),e.readUint32(),e.readUint32())},\"vec2<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},\"vec3<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},\"vec4<bool>\"(){throw new Error(\"Booleans are not host-shareable\")},mat2x2f(e){return yl(e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32())},mat3x3f(e){let t=()=>{let s=e.readFloat32();return e.readFloat32(),s};return bl(e.readFloat32(),e.readFloat32(),t(),e.readFloat32(),e.readFloat32(),t(),e.readFloat32(),e.readFloat32(),t())},mat4x4f(e){return Eo(e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32())},struct(e,t){let s=xr(t);wo(e,s);let r={},o=t.propTypes;for(let[a,i]of Object.entries(o))wo(e,xr(i)),r[a]=Wl(e,i);return wo(e,s),r},array(e,t){if(t.elementCount===0)throw new Error(\"Cannot read using a runtime-sized schema.\");let s=xr(t),r=[];for(let o=0;o<t.elementCount;o++){wo(e,s);let a=t.elementType,i=Wl(e,a);r.push(i)}return wo(e,s),r},ptr(){throw new Error(\"Pointers are not host-shareable\")},atomic(e,t){return Wl(e,t.inner)},decorated(e,t){wo(e,wn(t));let s=e.currentByteOffset,r=Wl(e,t.inner);return e.seekTo(s+ds(t)),r},uint8:e=>e.readUint8(),uint8x2:e=>$s(e.readUint8(),e.readUint8()),uint8x4:e=>Is(e.readUint8(),e.readUint8(),e.readUint8(),e.readUint8()),sint8:e=>e.readInt8(),sint8x2:e=>ir(e.readInt8(),e.readInt8()),sint8x4:e=>sr(e.readInt8(),e.readInt8(),e.readInt8(),e.readInt8()),unorm8:e=>e.readUint8()/255,unorm8x2:e=>ps(e.readUint8()/255,e.readUint8()/255),unorm8x4:e=>qt(e.readUint8()/255,e.readUint8()/255,e.readUint8()/255,e.readUint8()/255),snorm8:e=>e.readInt8()/127,snorm8x2:e=>ps(e.readInt8()/127,e.readInt8()/127),snorm8x4:e=>qt(e.readInt8()/127,e.readInt8()/127,e.readInt8()/127,e.readInt8()/127),uint16:e=>e.readUint16(),uint16x2:e=>$s(e.readUint16(),e.readUint16()),uint16x4:e=>Is(e.readUint16(),e.readUint16(),e.readUint16(),e.readUint16()),sint16:e=>e.readInt16(),sint16x2:e=>ir(e.readInt16(),e.readInt16()),sint16x4:e=>sr(e.readInt16(),e.readInt16(),e.readInt16(),e.readInt16()),unorm16:e=>e.readUint16()/65535,unorm16x2:e=>ps(e.readUint16()/65535,e.readUint16()/65535),unorm16x4:e=>qt(e.readUint16()/65535,e.readUint16()/65535,e.readUint16()/65535,e.readUint16()/65535),snorm16:e=>e.readInt16()/32767,snorm16x2:e=>ps(e.readInt16()/32767,e.readInt16()/32767),snorm16x4:e=>qt(e.readInt16()/32767,e.readInt16()/32767,e.readInt16()/32767,e.readInt16()/32767),float16(e){return Ao(e)},float16x2:e=>ps(Ao(e),Ao(e)),float16x4:e=>qt(Ao(e),Ao(e),Ao(e),Ao(e)),float32:e=>e.readFloat32(),float32x2:e=>ps(e.readFloat32(),e.readFloat32()),float32x3:e=>Zs(e.readFloat32(),e.readFloat32(),e.readFloat32()),float32x4:e=>qt(e.readFloat32(),e.readFloat32(),e.readFloat32(),e.readFloat32()),uint32:e=>e.readUint32(),uint32x2:e=>$s(e.readUint32(),e.readUint32()),uint32x3:e=>Ps(e.readUint32(),e.readUint32(),e.readUint32()),uint32x4:e=>Is(e.readUint32(),e.readUint32(),e.readUint32(),e.readUint32()),sint32:e=>e.readInt32(),sint32x2:e=>ir(e.readInt32(),e.readInt32()),sint32x3:e=>Br(e.readInt32(),e.readInt32(),e.readInt32()),sint32x4:e=>sr(e.readInt32(),e.readInt32(),e.readInt32(),e.readInt32()),\"unorm10-10-10-2\"(e){let t=e.readUint32();return qt((t>>22)/1023,(t>>12&1023)/1023,(t>>2&1023)/1023,(t&3)/3)},\"unorm8x4-bgra\"(e){let t=e.readByte()/255,s=e.readByte()/255;return qt(e.readByte()/255,s,t,e.readByte()/255)},unstruct(e,t){let s={},r=t.propTypes;for(let[o,a]of Object.entries(r))s[o]=Wl(e,a);return s},disarray(e,t){let s=xr(t),r=[];for(let o=0;o<t.elementCount;o++)wo(e,s),r.push(Wl(e,t.elementType));return wo(e,s),r},\"loose-decorated\"(e,t){wo(e,wn(t));let s=e.currentByteOffset,r=Wl(e,t.inner);return e.seekTo(s+ds(t)),r}};function Wl(e,t){let s=Qj[t.type];if(!s)throw new Error(`Cannot read data of type '${t.type}'.`);return s(e,t)}var Zj=g3();function fE(e,t,s){let r=ds(t),o=e?.startOffset??0,a;io(t)&&Array.isArray(s)?a=s.length*Co(ds(t.elementType),xr(t.elementType)):(ArrayBuffer.isView(s)||s instanceof ArrayBuffer)&&(a=s.byteLength);let i=a!==void 0?Math.min(o+a,r):void 0;return{startOffset:o,endOffset:e?.endOffset??i??r}}function s0(e,t,s,r){let{startOffset:o,endOffset:a}=fE(r,t,s);if(s instanceof ArrayBuffer||ArrayBuffer.isView(s)){let u=s instanceof ArrayBuffer?new Uint8Array(s):new Uint8Array(s.buffer,s.byteOffset,s.byteLength),p=a-o;u.byteLength!==p&&rr.warn(\"suspicious\",`Buffer size mismatch: expected ${p} bytes, got ${u.byteLength}. `+(u.byteLength<p?\"Data truncated.\":\"Excess ignored.\"));let _=Math.min(u.byteLength,p);new Uint8Array(e).set(u.subarray(0,_),o);return}let i=new DataView(e),l=Zj===\"little\",c=E3(t);if(c)try{c(i,o,s,l,a);return}catch(u){rr.warn(\"fallback\",`Error when using compiled writer for data type '${t.type}' (${ct(t)??\"unnamed\"}) - this is likely a bug, please submit an issue at https://github.com/software-mansion/TypeGPU/issues\nUsing fallback writer instead.`,u)}let d=new Md(e);d.seekTo(o),Z1(d,t,s)}function r0(e,t){return Wl(new ep(e),t)}function xb(e,t){if(t==null)return t;if(_r(e)||ki(e)){let s={},r=t;for(let o of Object.keys(e.propTypes)){let a=e.propTypes[o],i=r[o];i!==void 0&&a&&(s[o]=xb(a,i))}return s}if(io(e)||Sd(e)){let s=e,r={};for(let{idx:o,value:a}of t)r[o]=xb(s.elementType,a);return r}return t}var Jj=g3()===\"little\";function vE(e,t,s){let r=ds(e);if(r===0||t===void 0||t===null)return[];let o=s??new ArrayBuffer(r),a=new Md(o),i=new DataView(o),l=[];function c(p,_,f,h){if(_==null)return;if(_r(p)||ki(p)){let b=kh(p);for(let[x,P]of Object.entries(b)){let C=_[x],E=p.propTypes[x];C!==void 0&&E&&c(E,C,f+P.offset,P.padding??h)}return}if(io(p)||Sd(p)){let b=p,x=Co(ds(b.elementType),xr(b.elementType)),P=x-ds(b.elementType);if(ArrayBuffer.isView(_)){let E=Math.min(_.byteLength,b.elementCount*x);new Uint8Array(o,f,E).set(new Uint8Array(_.buffer,_.byteOffset,E)),l.push({start:f,end:f+E,padding:h});return}if(Array.isArray(_)){for(let E=0;E<Math.min(b.elementCount,_.length);E++)c(b.elementType,_[E],f+E*x,P);return}let C=_;for(let E of Object.keys(C)){let R=Number(E);Number.isNaN(R)||c(b.elementType,C[E],f+R*x,P)}return}let g=ds(p),y=E3(p);y?y(i,f,_,Jj,f+g):(a.seekTo(f),Z1(a,p,_)),l.push({start:f,end:f+g,padding:h})}c(e,t,0);let d=[],u=null;for(let p of l)u&&p.start===u.end+(u.padding??0)?u={start:u.start,end:p.end,padding:p.padding}:(u&&d.push({gpuOffset:u.start,data:new Uint8Array(o,u.start,u.end-u.start).slice()}),u=p);return u&&d.push({gpuOffset:u.start,data:new Uint8Array(o,u.start,u.end-u.start).slice()}),d}function eK(e,t,s){let r=vE(t,s,e),o=new Uint8Array(e);for(let{data:a,gpuOffset:i}of r)o.set(a,i)}var T7=class hE extends Error{constructor(t){super(`Resource '${ct(t)??\"<unnamed>\"}' cannot be bound as 'storage'. Use .$usage('storage') to allow it.`),Object.setPrototypeOf(this,hE.prototype)}};function __(e){return e instanceof ld}function tK(e){return __(e)&&e.resourceType===\"uniform\"}function sK(e){return __(e)&&e.resourceType===\"mutable\"}function rK(e){return __(e)&&e.resourceType===\"readonly\"}var ld=class Ab{[He];[Mo];resourceType;static#e=void(Ab.prototype[ve]=!0,Bi(Al(Ab.prototype,{asString(){return`${this.resourceType}BufferBinding:${ct(this)??\"<unnamed>\"}`},resolve(t){let s=this.buffer.dataType,r=t.makeUniqueIdentifier(ct(this),\"global\"),{group:o,binding:a}=t.allocateFixedEntry(this.resourceType===\"uniform\"?{uniform:s}:{storage:s,access:this.resourceType},this.buffer);return t.gen.declareGlobalVar({group:o,binding:a,scope:this.resourceType,id:r,dataType:s,init:void 0})}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.buffer.dataType,this.resourceType,!1)}},simulateMode:{get(t){return t.buffers.has(this.buffer)||t.buffers.set(this.buffer,rc(this.buffer.dataType,this.buffer.initial)),t.buffers.get(this.buffer)},set(t,s){t.buffers.set(this.buffer,s)}},normalMode:{get(){throw new Ew(X1()?`Cannot access ${String(this.buffer)}. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation`:\".$ is inaccessible during normal JS execution. Try `.read()`\")},set(){throw new Ew(X1()?`Cannot access ${String(this.buffer)}. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation`:\".$ is inaccessible during normal JS execution. Try `.write()`\")}}}));constructor(t,s){this.resourceType=t,this[Mo]=s,this[He]={type:t,buffer:s,label:void 0}}get buffer(){return this[He].buffer}$name(t){return es(this,t),this}write(t,s){this.buffer.write(t,s)}writePartial(t){this.buffer.writePartial(t)}patch(t){this.buffer.patch(t)}read(){return this.buffer.read()}},S7=new WeakMap;function oK(e){if(!$1(e))throw new Error(`Cannot call as('mutable') on ${e}, as it is not allowed to be used as storage. To allow it, call .$usage('storage') when creating the buffer.`);let t=S7.get(e);return t||(t=new ld(\"mutable\",e),S7.set(e,t)),t}var P7=new WeakMap;function aK(e){if(!$1(e))throw new Error(`Cannot call as('readonly') on ${e}, as it is not allowed to be used as storage. To allow it, call .$usage('storage') when creating the buffer.`);let t=P7.get(e);return t||(t=new ld(\"readonly\",e),P7.set(e,t)),t}var C7=new WeakMap;function nK(e){if(!ZC(e))throw new Error(`Cannot call as('uniform') on ${e}, as it is not allowed to be used as a uniform. To allow it, call .$usage('uniform') when creating the buffer.`);let t=C7.get(e);return t||(t=new ld(\"uniform\",e),C7.set(e,t)),t}function gE(e,t){let s=Object.values(e).flatMap(a=>Object.values(a.entries)).filter(a=>a!==null),r=s.filter(a=>\"uniform\"in a).length,o=s.filter(a=>\"storage\"in a).length;r>t.maxUniformBuffersPerShaderStage&&rr.warn(\"webgpu-limits-exceeded\",`Total number of uniform buffers (${r}) exceeds maxUniformBuffersPerShaderStage (${t.maxUniformBuffersPerShaderStage}). Consider:\n1. Grouping some of the uniforms into one using 'd.struct',\n2. Increasing the limit when requesting a device or creating a root.`),o>t.maxStorageBuffersPerShaderStage&&rr.warn(\"webgpu-limits-exceeded\",`Total number of storage buffers (${o}) exceeds maxStorageBuffersPerShaderStage (${t.maxStorageBuffersPerShaderStage}).`)}function iK(e){return _r(e)||io(e)?Co(xr(e),16):xr(e)}function wb(e){if(io(e)){wb(e.elementType);let t=Co(ds(e.elementType),xr(e.elementType));t%16!==0&&rr.warn(\"uniform-schema-misaligned\",`Schema '${ct(e.elementType)??\"<unnamed>\"}' is used in an array in a uniform buffer, and its stride (${t}) is not a multiple of 16.\nThis is not portable (see https://www.w3.org/TR/WGSL/#address-space-layout-constraints), and will break on some devices.\nTo address this, put the element schema in a struct and wrap the prop in 'd.align(16, ...)', or use a different schema like 'vec4f'.`)}if(_r(e)){Object.values(e.propTypes).forEach(wb),Object.entries(e.propTypes).forEach(([s,r])=>{let o=M1(e,i=>i[s]).offset,a=iK(r);o%a&&rr.warn(\"uniform-schema-misaligned\",`Schema '${ct(e)??\"<unnamed>\"}' is used in a uniform buffer, and its property '${s}' does not meet required alignment (offset is ${o}, required alignment is ${a}).\nThis is not portable (see https://www.w3.org/TR/WGSL/#address-space-layout-constraints), and will break on some devices.\nTo address this, wrap the property '${s}' in 'd.align(${a}, ...)'.`)});let t=Object.keys(e.propTypes);for(let s=0;s<t.length-1;s++){let r=t[s],o=t[s+1];kr(r&&o);let a=e.propTypes[r];if(kr(a),!_r(a))continue;let i=Co(ds(a),16),l=M1(e,d=>d[r]).offset,c=M1(e,d=>d[o]).offset-l;i>c&&rr.warn(\"uniform-schema-misaligned\",`Schema '${ct(e)??\"<unnamed>\"}' is used in a uniform buffer, and the difference between memory offsets of '${r}' and '${o}' props (${c}) is less than recommended (${i}).\nThis is not portable (see https://www.w3.org/TR/WGSL/#address-space-layout-constraints), and will break on some devices.\nTo address this, wrap the '${r}' prop in 'd.size(${i}, ...)'.`)}}}var lK={uniform:nK,mutable:oK,readonly:aK};function Qf(e,t,s){return Td(t)?new M7(e,t,s):new M7(e,t,s,[\"storage\",\"uniform\"])}var M7=class{[ve];[He];resourceType=\"buffer\";#e;#t=!1;#s;get#r(){return this.#s??=new ArrayBuffer(ds(this.dataType))}#o;#a;#i;initial;usableAsUniform=!1;usableAsStorage=!1;usableAsVertex=!1;usableAsIndex=!1;usableAsIndirect=!1;constructor(e,t,s,r){this[He]={type:\"buffer\",device:e.device,dataType:t,flags:GPUBufferUsage.COPY_DST|GPUBufferUsage.COPY_SRC,usages:[],raw:void 0,label:void 0},this.#i=r,ol(s)?(this.#e=!1,this[He].raw=s):(this.#e=!0,typeof s==\"function\"?this.#a=s:this.initial=s),this[ve]={root:e,materialize:()=>{if(this.#t)throw new Error(\"This buffer has been destroyed\");let o=this[He];return o.raw||(o.raw=o.device.createBuffer({size:ds(o.dataType),usage:o.flags,mappedAtCreation:!!this.initial||!!this.#a,label:ct(this)??\"<unnamed>\"}),(this.initial||this.#a)&&(this.#a?this.#a(this):this.initial&&s0(this.#n(),this.dataType,this.initial),this.#l())),o.raw}}}get dataType(){return this[He].dataType}get flags(){return this[He].flags}set flags(e){this[He].flags=e}get buffer(){return this[ve].materialize()}get destroyed(){return this.#t}get arrayBuffer(){return this.buffer.mapState===\"mapped\"?this.#n():this.#r}#n(){let e=this[He].raw;if(!e||e.mapState!==\"mapped\")throw new Error(\"Buffer is not mapped.\");return this.#o??=e.getMappedRange(),this.#o}#l(){let e=this[He].raw;!e||e.mapState!==\"mapped\"||(this.#o=void 0,e.unmap())}$name(e){es(this,e);let t=this[He].raw;return t&&(t.label=e),this}$usage(...e){for(let t of e){if(this.#i?.includes(t))throw new Error(`Buffer of type ${this.dataType.type} cannot be used as ${t}`);t===\"uniform\"&&wb(this.dataType),this.flags|=t===\"uniform\"?GPUBufferUsage.UNIFORM:0,this.flags|=t===\"storage\"?GPUBufferUsage.STORAGE:0,this.flags|=t===\"vertex\"?GPUBufferUsage.VERTEX:0,this.flags|=t===\"index\"?GPUBufferUsage.INDEX:0,this.flags|=t===\"indirect\"?GPUBufferUsage.INDIRECT:0,this.usableAsUniform=this.usableAsUniform||t===\"uniform\",this.usableAsStorage=this.usableAsStorage||t===\"storage\",this.usableAsVertex=this.usableAsVertex||t===\"vertex\",this.usableAsIndex=this.usableAsIndex||t===\"index\",this.usableAsIndirect=this.usableAsIndirect||t===\"indirect\",this[He].usages.includes(t)||this[He].usages.push(t)}return this}$addFlags(e){if(!this.#e)throw new Error(\"Cannot add flags to a buffer that is not managed by TypeGPU.\");return e&GPUBufferUsage.MAP_READ?(this.flags=GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ,this):e&GPUBufferUsage.MAP_WRITE?(this.flags=GPUBufferUsage.COPY_SRC|GPUBufferUsage.MAP_WRITE,this):(this.flags|=e,this)}compileWriter(){E3(this.dataType)}write(e,t){let s=this.buffer;if(s.mapState===\"mapped\"){let i=this.#n();if(e instanceof ArrayBuffer&&e===i)return;s0(i,this.dataType,e,t);return}e instanceof ArrayBuffer&&e===this.#r||s0(this.#r,this.dataType,e,t);let{startOffset:r,endOffset:o}=fE(t,this.dataType,e),a=o-r;this[He].device.queue.writeBuffer(s,r,this.#r,r,a)}writePartial(e){this.patch(xb(this.dataType,e))}patch(e){let t=this.buffer;if(t.mapState===\"mapped\")eK(this.#n(),this.dataType,e);else{let s=vE(this.dataType,e,this.#r);for(let{data:r,gpuOffset:o}of s)this[He].device.queue.writeBuffer(t,o,r)}}clear(e){let t=this.buffer;if(e){e[ve].rawEncoder.clearBuffer(t);return}if(t.mapState===\"mapped\"){new Uint8Array(this.#n()).fill(0);return}let s=this[He].device.createCommandEncoder();s.clearBuffer(t),this[He].device.queue.submit([s.finish()])}copyFrom(e,t){if(this.buffer.mapState===\"mapped\")throw new Error(\"Cannot copy to a mapped buffer.\");let s=ds(this.dataType);if(t){t[ve].rawEncoder.copyBufferToBuffer(e.buffer,0,this.buffer,0,s);return}let r=this[He].device.createCommandEncoder();r.copyBufferToBuffer(e.buffer,0,this.buffer,0,s),this[He].device.queue.submit([r.finish()])}async read(){let e=this.buffer;if(e.mapState===\"mapped\")return r0(this.#n(),this.dataType);if(e.usage&GPUBufferUsage.MAP_READ){await e.mapAsync(GPUMapMode.READ);let o=r0(this.#n(),this.dataType);return this.#l(),o}let t=this[He].device.createBuffer({size:ds(this.dataType),usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ}),s=this[He].device.createCommandEncoder();s.copyBufferToBuffer(e,0,t,0,ds(this.dataType)),this[He].device.queue.submit([s.finish()]),await t.mapAsync(GPUMapMode.READ,0,ds(this.dataType));let r=r0(t.getMappedRange(),this.dataType);return t.unmap(),t.destroy(),r}as(e){return lK[e](this)}destroy(){this.#t||(this.#t=!0,this.#o=void 0,this.#e&&this[He].raw?.destroy())}toString(){return`buffer:${ct(this)??\"<unnamed>\"}`}},yE=class Tb{bindings;constructor(t){this.bindings=t}with(t,s){return new Tb([...this.bindings,[Qu(t)||Zu(t)?t.slot:t,s]])}pipe(t){let s=t(this);return new Tb([...this.bindings,...s.bindings])}};function*cK(e){let t=0;for(;;)e.has(t)||(yield t),t++}function dK(e,t){return new xE(v3(),e,t)}function uK(e,t){return new xE(LM(),e,t)}function k3(e){let t=e;return t?.resourceType===\"sampler\"&&!!t[ve]}function B3(e){let t=e;return t?.resourceType===\"sampler-comparison\"&&!!t[ve]}var pK=class bE{[ve]={materialize:void 0};resourceType;schema;#e;static#t=Bi(Al(bE.prototype,{asString(){return`${this.resourceType}:${ct(this)??\"<unnamed>\"}`},resolve(t){let s=t.makeUniqueIdentifier(ct(this),\"global\"),r=t.allocateLayoutEntry(this.#e.layout);return t.addDeclaration(`@group(${r}) @binding(${this.#e.idx}) var ${s}: ${t.resolve(this.schema).value};`,s),Je(s,this.schema,\"handle\")}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.schema,\"handle\",!1)}},normalMode:{get(){throw new Error(\"Direct access to sampler values is possible only as part of a compute dispatch or draw call.\")}}});constructor(t,s){this.schema=t,this.#e=s,this.resourceType=t.type===\"sampler_comparison\"?\"sampler-comparison\":\"sampler\",es(this,s.key)}},xE=class AE{[ve];[He];resourceType;schema;#e;static#t=Bi(Al(AE.prototype,{asString(){return`${this.resourceType}:${ct(this)??\"<unnamed>\"}`},resolve(t){let s=t.makeUniqueIdentifier(ct(this),\"global\"),{group:r,binding:o}=t.allocateFixedEntry(this.schema.type===\"sampler_comparison\"?{sampler:\"comparison\"}:{sampler:this.#e?\"filtering\":\"non-filtering\"},this);return t.addDeclaration(`@group(${r}) @binding(${o}) var ${s}: ${t.resolve(this.schema).value};`,s),Je(s,this.schema,\"handle\")}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.schema,\"handle\",!1)}},normalMode:{get(){throw new Error(\"Direct access to sampler values is possible only as part of a compute dispatch or draw call.\")}}});constructor(t,s,r){this.schema=t,this.resourceType=t.type===\"sampler_comparison\"?\"sampler-comparison\":\"sampler\",this[He]={type:this.resourceType,device:r.device,props:s,raw:void 0,label:void 0},this[ve]={root:r,materialize:()=>{let o=this[He];return o.raw||(o.raw=o.device.createSampler({...o.props,label:ct(this)??\"<unnamed>\"})),o.raw}},this.#e=s.minFilter===\"linear\"||s.magFilter===\"linear\"||s.mipmapFilter===\"linear\"}$name(t){return es(this,t),this}},mK=class{resourceType=\"external-texture\";[ve]=!0;schema;#e;constructor(e,t){this.schema=e,this.#e=t,es(this,t.key)}[Ws](e){let t=e.makeUniqueIdentifier(ct(this),\"global\"),s=e.allocateLayoutEntry(this.#e.layout);return e.addDeclaration(`@group(${s}) @binding(${this.#e.idx}) var ${t}: ${e.resolve(this.schema).value};`,t),Je(t,RM(),\"handle\")}get[Ka](){let e=this.schema;return new Proxy({[ve]:!0,get[tc](){return Je(this,e,\"handle\",!1)},[Ws]:t=>t.resolve(this),toString:()=>`textureExternal:${ct(this)??\"<unnamed>\"}.$`},Mu)}get $(){if(xh())return this[Ka];throw new Error(\"Direct access to texture views values is possible only as part of a compute dispatch or draw call. Try .read() or .write() instead\")}toString(){return`textureExternal:${ct(this)??\"<unnamed>\"}`}},_K={channelType:n,vectorType:qt,sampleTypes:[\"depth\",\"unfilterable-float\"],texelSize:\"non-copyable\"},fK={channelType:n,vectorType:qt,sampleTypes:[\"depth\",\"unfilterable-float\"],texelSize:2},vK={channelType:n,vectorType:qt,sampleTypes:[\"depth\",\"unfilterable-float\"],texelSize:4},hK={channelType:M,vectorType:Is,sampleTypes:[\"uint\"],texelSize:1},E7=new Map;function f_(e){let t=E7.get(e);return t===void 0&&(t=gK(e),E7.set(e,t)),t}function gK(e){let t=xK(e),s=yK(e),r=e.includes(\"stencil\");return{channelType:t,vectorType:t===M?Is:t===j?sr:qt,texelSize:AK(e),sampleTypes:wK(e),canRenderAttachment:bK(e),...s&&{depthAspect:s},...r&&{stencilAspect:hK}}}function yK(e){if(e===\"depth16unorm\")return fK;if(e===\"depth32float\"||e===\"depth32float-stencil8\")return vK;if(e===\"depth24plus\"||e===\"depth24plus-stencil8\")return _K}function bK(e){return!(e.startsWith(\"bc\")||e.startsWith(\"etc2\")||e.startsWith(\"eac\")||e.startsWith(\"astc\")||e===\"rgb9e5ufloat\")}function xK(e){return e===\"stencil8\"||e.includes(\"uint\")?M:e.includes(\"sint\")?j:n}function AK(e){let[,t,s]=e.match(/^(rgba|bgra|rg|r)(8|16|32)/)??[];return t&&s?t.length*Number(s)/8:e===\"stencil8\"?1:e===\"depth16unorm\"?2:e===\"depth32float\"?4:e===\"depth32float-stencil8\"?5:e===\"depth24plus\"||e===\"depth24plus-stencil8\"?\"non-copyable\":/^(bc[14]-|etc2-rgb8|eac-r11)/.test(e)?8:/^(bc|astc-|etc2-rgba|eac-rg)/.test(e)?16:4}function wK(e){return e===\"stencil8\"?[\"uint\"]:e.includes(\"uint\")?[\"uint\"]:e.includes(\"sint\")?[\"sint\"]:e.includes(\"depth\")?[\"depth\",\"unfilterable-float\"]:/^(r|rg|rgba)16(u|s)norm$/.test(e)?[\"unfilterable-float\"]:[\"float\",\"unfilterable-float\"]}var TK=new Set([\"r32float\",\"rg32float\",\"rgba32float\"]);function SK(e,t){return TK.has(t)&&!e.features.has(\"float32-filterable\")?[\"unfilterable-float\"]:f_(t).sampleTypes}function wE(e){let{videoWidth:t,videoHeight:s}=e;if(t&&s)return{width:t,height:s};let{naturalWidth:r,naturalHeight:o}=e;if(r&&o)return{width:r,height:o};let{codedWidth:a,codedHeight:i}=e;if(a&&i)return{width:a,height:i};let{width:l,height:c}=e;if(l&&c)return{width:l,height:c};throw new Error(\"Cannot determine dimensions of the provided image source.\")}var PK=`\nstruct VertexOutput {\n  @builtin(position) pos: vec4f,\n  @location(0) uv: vec2f,\n}\n\n@vertex\nfn vs_main(@builtin(vertex_index) i: u32) -> VertexOutput {\n  const pos = array(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n  const uv = array(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));\n  return VertexOutput(vec4f(pos[i], 0, 1), uv[i]);\n}`,CK=`\n@group(0) @binding(0) var src: texture_2d<f32>;\n@group(0) @binding(1) var samp: sampler;\n\n@fragment\nfn fs_main(@location(0) uv: vec2f) -> @location(0) vec4f {\n  return textureSample(src, samp, uv);\n}`,MK=`\n@group(0) @binding(0) var src: texture_2d<f32>;\n@group(0) @binding(1) var samp: sampler;\n\n@fragment\nfn fs_main(@location(0) uv: vec2f) -> @location(0) vec4f {\n  let r = textureGather(0, src, samp, uv);\n  let g = textureGather(1, src, samp, uv);\n  let b = textureGather(2, src, samp, uv);\n  let a = textureGather(3, src, samp, uv);\n  return vec4f(dot(r, vec4f(0.25)), dot(g, vec4f(0.25)), dot(b, vec4f(0.25)), dot(a, vec4f(0.25)));\n}`,Sb=new WeakMap;function EK(e){let t=Sb.get(e);return t||(t={vertexModule:e.createShaderModule({code:PK}),filterableResources:new Map,layoutResources:new Map},Sb.set(e,t)),t}function kK(e,t,s){let r=EK(e),o=r.filterableResources.get(t);o||(o={fragmentModule:e.createShaderModule({code:t?CK:MK}),sampler:e.createSampler(t?{magFilter:\"linear\",minFilter:\"linear\"}:{})},r.filterableResources.set(t,o));let a=`${t}:${s}`,i=r.layoutResources.get(a);if(!i){let l=e.createBindGroupLayout({entries:[{binding:0,visibility:GPUShaderStage.FRAGMENT,texture:{sampleType:s}},{binding:1,visibility:GPUShaderStage.FRAGMENT,sampler:{type:t?\"filtering\":\"non-filtering\"}}]});i={bindGroupLayout:l,pipelineLayout:e.createPipelineLayout({bindGroupLayouts:[l]})},r.layoutResources.set(a,i)}return{vertexModule:r.vertexModule,...o,...i}}function TE(e){let{device:t,source:s,destination:r,format:o,filterable:a,sampleType:i}=e,l=kK(t,a,i),c=t.createRenderPipeline({layout:l.pipelineLayout,vertex:{module:l.vertexModule},fragment:{module:l.fragmentModule,targets:[{format:o}]},primitive:{topology:\"triangle-list\"}}),d=t.createBindGroup({layout:l.bindGroupLayout,entries:[{binding:0,resource:s},{binding:1,resource:l.sampler}]}),u=!e.encoder,p=e.encoder??t.createCommandEncoder(),_=p.beginRenderPass({colorAttachments:[{view:r,loadOp:\"clear\",storeOp:\"store\"}]});_.setPipeline(c),_.setBindGroup(0,d),_.draw(3),_.end(),u&&t.queue.submit([p.finish()])}function BK(e){Sb.delete(e)}function SE(e,t,s){let r=f_(t),o=SK(e,t),a=o.includes(\"float\"),i=o.includes(\"unfilterable-float\");if(!a&&!i)throw new Error(`Cannot ${s} for format '${t}': only float formats are supported.`);if(!r.canRenderAttachment)throw new Error(`Cannot ${s} for format '${t}': format does not support render attachments.`);return{filterable:a,sampleType:a?\"float\":\"unfilterable-float\"}}function zK(e,t,s=0,r){if(t.dimension!==\"2d\")throw new Error(\"Mipmap generation only supports 2D textures.\");let{filterable:o,sampleType:a}=SE(e,t.format,\"generate mipmaps\"),i=r??t.mipLevelCount-s;for(let l=0;l<t.depthOrArrayLayers;l++)for(let c=s;c<s+i-1;c++){let d=u=>({dimension:\"2d\",baseMipLevel:u,mipLevelCount:1,baseArrayLayer:l,arrayLayerCount:1});TE({device:e,source:t.createView(d(c)),destination:t.createView(d(c+1)),format:t.format,filterable:o,sampleType:a})}}function RK(e,t,s,r=0){if(t.dimension!==\"2d\")throw new Error(\"Resampling only supports 2D textures.\");let{filterable:o}=SE(e,t.format,\"resample\"),{width:a,height:i}=wE(s),l=e.createTexture({size:[a,i],format:\"rgba8unorm\",usage:GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.COPY_DST|GPUTextureUsage.RENDER_ATTACHMENT});e.queue.copyExternalImageToTexture({source:s},{texture:l},[a,i]);let c=e.createTexture({size:[t.width,t.height],format:t.format,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC}),d=e.createCommandEncoder();TE({device:e,source:l.createView(),destination:c.createView(),format:t.format,filterable:o,sampleType:\"float\",encoder:d}),d.copyTextureToTexture({texture:c},{texture:t,origin:{x:0,y:0,z:r}},{width:t.width,height:t.height,depthOrArrayLayers:1}),e.queue.submit([d.finish()]),l.destroy(),c.destroy()}function DK(e){return{dimension:e.dimension??\"2d\",sampleType:f_(e.format).channelType,multisampled:(e.sampleCount??1)!==1}}function LK(e,t,s){return new UK(e,t,s)}function Vm(e){return e?.resourceType===\"texture\"&&!!e[ve]}function Eu(e){return e?.resourceType===\"texture-view\"&&!!e[ve]}var UK=class{[ve];[He];resourceType=\"texture\";usableAsSampled=!1;usableAsStorage=!1;usableAsRender=!1;#e;#t=!1;#s;constructor(e,t,s){this.#s=s===void 0,this[He]={type:\"texture\",device:t.device,props:e,flags:GPUTextureUsage.COPY_DST|GPUTextureUsage.COPY_SRC,flagsOverridden:!1,usages:[],raw:s,label:void 0},this.#e=f_(e.format),this[ve]={root:t,materialize:()=>{if(this.#t)throw new Error(\"This texture has been destroyed\");let r=this[He];if(!r.raw){let o=r.props;r.raw=(globalThis.__TYPEGPU_AUTONAME__??(a=>a))(r.device.createTexture({label:ct(this)??\"<unnamed>\",format:o.format,size:o.size,usage:r.flags,dimension:o.dimension??\"2d\",viewFormats:o.viewFormats??[],mipLevelCount:o.mipLevelCount??1,sampleCount:o.sampleCount??1}),\"raw\")}return r.raw}}}get props(){return this[He].props}$name(e){return es(this,e),this}$usage(...e){let t=this[He];if(t.flagsOverridden)throw new Error(\"Cannot call $usage() after $overrideFlags().\");let s=e.includes(\"storage\"),r=e.includes(\"sampled\"),o=e.includes(\"render\"),a=e.includes(\"transient\"),i=(r?GPUTextureUsage.TEXTURE_BINDING:0)|(s?GPUTextureUsage.STORAGE_BINDING:0),l=GPUTextureUsage.TRANSIENT_ATTACHMENT|GPUTextureUsage.RENDER_ATTACHMENT,c=t.flags|i|(o?GPUTextureUsage.RENDER_ATTACHMENT:0),d=a||!!(t.flags&GPUTextureUsage.TRANSIENT_ATTACHMENT),u=!!(c&(GPUTextureUsage.TEXTURE_BINDING|GPUTextureUsage.STORAGE_BINDING));if(d&&u)throw new Error(\"Transient texture usage cannot be combined with 'sampled' or 'storage'.\");t.flags=a?l:c,this.usableAsStorage||=s,this.usableAsSampled||=r,this.usableAsRender||=o||a;for(let p of e)t.usages.includes(p)||t.usages.push(p);return this}$overrideFlags(e){let t=this[He];return t.flags=e,t.flagsOverridden=!0,this.usableAsSampled=!0,this.usableAsStorage=!0,this.usableAsRender=!0,this}createView(e,t){return e===\"render\"?new GK(this,t):new OK(e??M$(DK(this.props)),this,t)}#r(e=0){let t=2**e,[s,r,o]=[Math.max(1,Math.floor((this.props.size[0]??1)/t)),Math.max(1,Math.floor((this.props.size[1]??1)/t)),Math.max(1,Math.floor((this.props.size[2]??1)/t))],a=this.#e.texelSize;if(a===\"non-copyable\")throw new Error(`Cannot clear texture with format '${this.props.format}': this format does not support copy operations.`);this[He].device.queue.writeTexture({texture:this[ve].materialize(),mipLevel:e},new Uint8Array(s*r*o*a),{bytesPerRow:a*s,rowsPerImage:r},[s,r,o])}clear(e=\"all\"){if(e===\"all\"){let t=this.props.mipLevelCount??1;for(let s=0;s<t;s++)this.#r(s)}else this.#r(e)}generateMipmaps(e=0,t){if(!this.usableAsRender)throw new Error(\"generateMipmaps called without specifying 'render' usage. Add it via the $usage('render') method.\");let s=t??(this.props.mipLevelCount??1)-e;if(s<=1){rr.warn(\"suspicious\",`generateMipmaps is a no-op: would generate ${s} mip levels (base: ${e}, total: ${this.props.mipLevelCount??1})`);return}if(e>=(this.props.mipLevelCount??1))throw new Error(`Base mip level ${e} is out of range. Texture has ${this.props.mipLevelCount??1} mip levels.`);zK(this[He].device,this[ve].materialize(),e,s)}write(e,t=0){if(e instanceof ArrayBuffer||ArrayBuffer.isView(e)){this.#o(e,typeof t==\"number\"?t:0);return}if(!this.usableAsRender)throw new Error(\"texture.write(...) with image sources requires 'render' usage. Add it via the $usage('render') method.\");let s=typeof t==\"number\"?void 0:t,r=this.props.dimension??\"2d\";if(!Array.isArray(e)){this.#a(e,r===\"3d\"?0:void 0,s);return}let o=this.props.size[2]??1;e.length>o&&rr.warn(\"suspicious\",`Too many image sources provided. Expected ${o} layers, got ${e.length}. Extra sources will be ignored.`);for(let a=0;a<Math.min(e.length,o);a++){let i=e[a];i&&this.#a(i,a,s)}}#o(e,t){let s=Math.max(1,this.props.size[0]>>t),r=Math.max(1,(this.props.size[1]??1)>>t),o=Math.max(1,(this.props.size[2]??1)>>t),a=this.#e.texelSize;if(a===\"non-copyable\")throw new Error(`Cannot write to texture with format '${this.props.format}': this format does not support copy operations.`);let i=s*r*o*a,l=e.byteLength??e.byteLength;if(l!==i)throw new Error(`Buffer size mismatch. Expected ${i} bytes for mip level ${t}, got ${l} bytes.`);this[He].device.queue.writeTexture({texture:this[ve].materialize(),mipLevel:t},\"buffer\"in e?e.buffer:e,{bytesPerRow:a*s,rowsPerImage:r},[s,r,o])}#a(e,t,s){let r=this.props.size[0],o=this.props.size[1]??1,{width:a,height:i}=wE(e);if(a!==r||i!==o){if(s?.fit!==\"stretch\")throw new Error(`Texture write source size ${a}x${i} does not match target size ${r}x${o}. Pass fit: 'stretch' to resize explicitly.`);RK(this[He].device,this[ve].materialize(),e,t);return}this[He].device.queue.copyExternalImageToTexture({source:e},{texture:this[ve].materialize(),...t!==void 0&&{origin:{x:0,y:0,z:t}}},t!==void 0?[r,o,1]:this.props.size)}copyFrom(e){if(e.props.format!==this.props.format)throw new Error(`Texture format mismatch. Source texture has format ${e.props.format}, target texture has format ${this.props.format}`);if(e.props.size[0]!==this.props.size[0]||(e.props.size[1]??1)!==(this.props.size[1]??1)||(e.props.size[2]??1)!==(this.props.size[2]??1))throw new Error(`Texture size mismatch. Source texture has size ${e.props.size.join(\"x\")}, target texture has size ${this.props.size.join(\"x\")}`);let t=this[He].device.createCommandEncoder();t.copyTextureToTexture({texture:e[ve].materialize()},{texture:this[ve].materialize()},e.props.size),this[He].device.queue.submit([t.finish()])}toString(){return`${this.resourceType}:${ct(this)??\"<unnamed>\"}`}get destroyed(){return this.#t}destroy(){this.#t||(this.#t=!0,this.#s&&this[He].raw?.destroy())}},OK=class{[ve];[He];resourceType=\"texture-view\";constructor(e,t,s){this[He]={type:\"texture-view\",texture:t,schema:e,descriptor:s,raw:void 0,label:void 0},this[ve]={unwrap:()=>{let r=this[He];if(!r.raw){let o=r.schema,a=C1(o)?o.format:r.texture.props.format;r.raw=(globalThis.__TYPEGPU_AUTONAME__??(i=>i))(r.texture[ve].materialize().createView({...r.descriptor,label:ct(this)??\"<unnamed>\",format:r.descriptor?.format??a,dimension:o.dimension}),\"raw\")}return r.raw},format:s?.format??(C1(e)?e.format:t.props.format),aspect:s?.aspect}}get schema(){return this[He].schema}$name(e){return es(this,e),this[He].raw&&(this[He].raw.label=e),this}get[Ka](){let e=this.schema;return new Proxy({[ve]:!0,get[tc](){return Je(this,e,\"handle\",!1)},[Ws]:t=>t.resolve(this),toString:()=>`${this.toString()}.$`},Mu)}get $(){if(xh())return this[Ka];throw new Error(\"Direct access to texture view values is possible only as part of a compute dispatch or draw call. Try .read() or .write() instead\")}get size(){return this[He].texture.props.size}toString(){return`textureView:${ct(this)??\"<unnamed>\"}`}[Ws](e){let t=e.makeUniqueIdentifier(ct(this),\"global\"),{group:s,binding:r}=e.allocateFixedEntry(C1(this.schema)?{storageTexture:this.schema}:{texture:this.schema,sampleType:this[He].descriptor?.sampleType??this.schema.bindingSampleType[0]},this);return e.gen.declareGlobalVar({group:s,binding:r,id:t,dataType:this.schema,scope:\"handle\",init:void 0})}},k7=class{[ve]={unwrap:void 0};resourceType=\"texture-view\";#e;schema;constructor(e,t){this.schema=e,this.#e=t,es(this,t.key)}toString(){return`textureView:${ct(this)??\"<unnamed>\"}`}[Ws](e){let t=e.makeUniqueIdentifier(ct(this),\"global\"),s=e.allocateLayoutEntry(this.#e.layout);return e.addDeclaration(`@group(${s}) @binding(${this.#e.idx}) var ${t}: ${e.resolve(this.schema).value};`,t),Je(t,this.schema,\"handle\")}get[Ka](){let e=this.schema;return new Proxy({[ve]:!0,get[tc](){return Je(this,e,\"handle\",!1)},[Ws]:t=>t.resolve(this),toString:()=>`${this.toString()}.$`},Mu)}get $(){if(xh())return this[Ka];throw new Error(`Accessed view '${ct(this)??\"<unnamed>\"}' outside of codegen mode. Direct access to texture views values is possible only as part of a compute dispatch or draw call. Try .read() or .write() instead`)}$name(e){return es(this,e),this}},GK=class{[ve];[He];resourceType=\"texture-view\";constructor(e,t={}){this[He]={type:\"texture-view\",texture:e,schema:\"render\",descriptor:t,raw:void 0,label:void 0},this[ve]={unwrap:()=>e[ve].materialize().createView({label:ct(this)??\"<unnamed>\",...this.descriptor}),format:t.format??e.props.format,aspect:t.aspect}}get descriptor(){return this[He].descriptor??{}}};function FK(e){return!!e?.usableAsSampled}var IK=class PE extends Error{constructor(t){super(`Resource '${ct(t)??\"<unnamed>\"}' cannot be bound as 'sampled'. Use .$usage('sampled') to allow it.`),Object.setPrototypeOf(this,PE.prototype)}},B7=class Pb{[ve];usage;dataType;#e;static#t=void(Pb.prototype.resourceType=\"laid-out-buffer\",Bi(Al(Pb.prototype,{asString(){return`${this.usage}:${ct(this)??\"<unnamed>\"}`},resolve(t){let s=t.makeUniqueIdentifier(ct(this),\"global\"),r=t.allocateLayoutEntry(this.#e.layout);return t.gen.declareGlobalVar({group:r,binding:this.#e.idx,scope:this.usage,id:s,dataType:this.dataType,init:void 0})}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.dataType,this.usage,!1)}},normalMode:{get(){throw new Error(\"Direct access to buffer values is possible only as part of a compute dispatch or draw call. Try .read() or .write() instead\")}}}));constructor(t,s,r){this[ve]={dataType:s},this.usage=t,this.dataType=s,this.#e=r,es(this,r.key)}};function CE(e){return new WK({...e})}function Uh(e){return!!e&&e.resourceType===\"bind-group-layout\"}function ic(e){return!!e&&e.resourceType===\"bind-group\"}var YK=class ME extends Error{constructor(t,s){super(`Bind group '${t??\"<unnamed>\"}' is missing a required binding '${s}'`),Object.setPrototypeOf(this,ME.prototype)}},z7=[\"compute\",\"fragment\"],tm=[\"compute\",\"vertex\",\"fragment\"],WK=class{[ve];[He];resourceType=\"bind-group-layout\";$={};entries;get[Ka](){return this.$}constructor(e){this.entries=e,this[ve]=[];let t={};this[He]={type:\"bind-group-layout\",entries:t,index:void 0,label:void 0};let s=0;for(let[r,o]of Object.entries(e)){if(o===null){t[r]=null,s++;continue}let a={layout:this,key:r,idx:s},i;if(t[r]=o,\"uniform\"in o&&(i=new B7(\"uniform\",o.uniform,a)),\"storage\"in o){let l=\"type\"in o.storage?o.storage:o.storage(0);i=new B7(o.access??\"readonly\",l,a),t[r]={...o,storage:l}}\"texture\"in o&&(i=new k7(o.texture,a)),\"storageTexture\"in o&&(i=new k7(o.storageTexture,a)),\"externalTexture\"in o&&(i=new mK(o.externalTexture,a)),\"sampler\"in o&&(i=new pK(o.sampler===\"comparison\"?LM():v3(),a)),kr(i!==void 0,\"Internal error, expected item to be defined\"),Object.defineProperty(this.$,r,{get:()=>i.$}),this[ve].push(i),s++}}toString(){return`bindGroupLayout:${ct(this)??\"<unnamed>\"}`}get index(){return this[He].index}$name(e){return es(this,e),this}$idx(e){return this[He].index=e,this}unwrap(e){return e.device.createBindGroupLayout({label:ct(this)??\"<unnamed>\",entries:Object.values(this.entries).map((t,s)=>{if(t===null)return null;let r=t.visibility,o={binding:s,visibility:0};if(\"uniform\"in t)r=r??tm,o.buffer={type:\"uniform\"};else if(\"storage\"in t)r=r??(t.access===\"mutable\"?z7:tm),o.buffer={type:t.access===\"mutable\"?\"storage\":\"read-only-storage\"};else if(\"sampler\"in t)r=r??tm,o.sampler={type:t.sampler};else if(\"texture\"in t){r=r??tm;let{multisampled:a,dimension:i,bindingSampleType:l}=t.texture;o.texture={sampleType:t.sampleType??l[0],viewDimension:i,multisampled:a}}else if(\"storageTexture\"in t){r=r??z7;let{dimension:a,access:i,format:l}=t.storageTexture;o.storageTexture={access:i,format:l,viewDimension:a}}else\"externalTexture\"in t&&(r=r??tm,o.externalTexture={});return r?.includes(\"compute\")&&(o.visibility|=GPUShaderStage.COMPUTE),r?.includes(\"vertex\")&&(o.visibility|=GPUShaderStage.VERTEX),r?.includes(\"fragment\")&&(o.visibility|=GPUShaderStage.FRAGMENT),o}).filter(t=>t!==null)})}},EE=class{[ve];[He];resourceType=\"bind-group\";#e;constructor(e,t,s,r){if(this.#e=s,this[He]={type:\"bind-group\",device:e?.device,layout:t,raw:r,label:void 0},this[ve]={materialize:()=>{let o=this[He];return o.raw||(kr(e,\"Cannot unwrap a bind group created outside of a root.\"),o.raw=e.unwrap(this)),o.raw}},!r){for(let o of Object.keys(t.entries))if(t.entries[o]!==null&&!(o in s))throw new YK(ct(t),o)}}get layout(){return this[He].layout}get entries(){return this.#e}unwrap(e){let t=this[He].raw;return t||e.device.createBindGroup({label:ct(this.layout)??\"<unnamed>\",layout:e.unwrap(this.layout),entries:Object.entries(this.layout.entries).map(([s,r],o)=>{if(r===null)return null;let a=this.entries[s];if(a===void 0)throw new Error(`'${s}' is a resource required to populate bind group layout '${ct(this.layout)??\"<unnamed>\"}'.`);if(\"uniform\"in r){let i;if(Fm(a)){if(!ZC(a))throw new cN(a);i={buffer:e.unwrap(a)}}else tK(a)?i={buffer:e.unwrap(a)}:i={buffer:a};return{binding:o,resource:i}}if(\"storage\"in r){let i;if(Fm(a)){if(!$1(a))throw new T7(a);i={buffer:e.unwrap(a)}}else sK(a)||rK(a)?(kr(r.access===\"mutable\"==(a.resourceType===\"mutable\"),\"Invalid buffer access mode.\"),i={buffer:e.unwrap(a)}):i={buffer:a};return{binding:o,resource:i}}if(\"texture\"in r){let i;if(Vm(a)){if(!FK(a))throw new IK(a);i=e.unwrap(a.createView(r.texture))}else Eu(a)?i=e.unwrap(a):i=a;return{binding:o,resource:i}}if(\"storageTexture\"in r){let i;if(Vm(a)){if(!$1(a))throw new T7(a);i=e.unwrap(a.createView(r.storageTexture))}else Eu(a)?i=e.unwrap(a):i=a;return{binding:o,resource:i}}if(\"sampler\"in r)return B3(a)||k3(a)?{binding:o,resource:e.unwrap(a)}:{binding:o,resource:a};if(\"externalTexture\"in r)return{binding:o,resource:a};throw new Error(`Malformed bind group entry: ${pn(a)}`)}).filter(s=>s!==null)})}};function v_(e){return new qK(e)}var qK=class{[ve]=!0;[He];resourceType=\"slot\";constructor(e=void 0){this[He]={type:\"slot\",defaultValue:e,label:void 0}}get defaultValue(){return this[He].defaultValue}$name(e){return es(this,e),this}areEqual(e,t){return Object.is(e,t)}toString(){return`slot:${ct(this)??\"<unnamed>\"}`}get[Ka](){let e=_d();if(!e)throw new Error(\"Cannot access tgpu.slot's value outside of resolution.\");return K1(e.unwrap(this))}get $(){return this[Ka]}},rp=v_(null);function Oh(e,t){return new BE(\"private\",e,t)}function kE(e){return new BE(\"workgroup\",e)}var BE=class zE{[He];static#e=(()=>{let t=zE.prototype;t.resourceType=\"var\",t[ve]={},Bi(Al(t,{asString(){return`var:${ct(this)??\"<unnamed>\"}`},resolve(s){let r=s.makeUniqueIdentifier(ct(this),\"global\"),o=this[He].initialValue?Je(this[He].initialValue,this[He].dataType,\"constant\"):void 0;return s.gen.declareGlobalVar({scope:this[He].scope,id:r,dataType:this[He].dataType,init:o})}}),{codegenMode:{getBaseSnippet(s){return Je(s,this[He].dataType,this[He].scope,!1)}},simulateMode:{get(s){return s.vars[this[He].scope].has(this)||s.vars[this[He].scope].set(this,this[He].initialValue),s.vars[this[He].scope].get(this)},set(s,r){s.vars[this[He].scope].set(this,r)}},normalMode:{get(){throw new Mw(X1()?`Cannot access variable '${ct(this)??\"<unnamed>\"}'. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation`:\"TypeGPU variables are inaccessible during normal JS execution. If you wanted to simulate GPU behavior, try `tgpu.simulate()`\")},set(s){throw new Mw(X1()?`Cannot access variable ${ct(this)??\"<unnamed>\"}. TypeGPU functions that depends on GPU resources need to be part of a compute dispatch, draw call or simulation`:\"TypeGPU variables are inaccessible during normal JS execution. If you wanted to simulate GPU behavior, try `tgpu.simulate()`\")}}})})();constructor(t,s,r){this[He]={type:\"var\",scope:t,dataType:s,initialValue:r,label:void 0}}$name(t){return es(this,t),this}},RE=Oh(M,0).$name(\"dataBlockIndex\"),DE=Oh(M,0).$name(\"dataByteIndex\"),LE=v_().$name(\"dataBuffer\"),VK=nr([],M)`() {\n  let i = dataByteIndex;\n  dataByteIndex = dataByteIndex + 1u;\n  return i;\n}`.$uses({dataByteIndex:DE}).$name(\"nextByteIndex\"),Pt=\"dataBuffer[dataBlockIndex].serializedData[nextByteIndex()]\",UE={f32:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([n])`(n) {\n  ${Pt} = bitcast<u32>(n);\n}`,\"f32\"),f16:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Vr])`(n) {\n  ${Pt} = pack2x16float(vec2f(f32(n), 0.0));\n}`,\"f16\"),i32:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([j])`(n) {\n  ${Pt} = bitcast<u32>(n);\n}`,\"i32\"),u32:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([M])`(n) {\n  ${Pt} = n;\n}`,\"u32\"),bool:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([ys])`(b) {\n  ${Pt} = u32(b);\n}`,\"bool\"),vec2f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([ps])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n}`,\"vec2f\"),vec3f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Zs])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n  ${Pt} = bitcast<u32>(v.z);\n}`,\"vec3f\"),vec4f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([qt])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n  ${Pt} = bitcast<u32>(v.z);\n  ${Pt} = bitcast<u32>(v.w);\n}`,\"vec4f\"),vec2h:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([To])`(v) {\n  ${Pt} = pack2x16float(vec2f(f32(v.x), f32(v.y)));\n}`,\"vec2h\"),vec3h:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Pa])`(v) {\n  ${Pt} = pack2x16float(vec2f(f32(v.x), f32(v.y)));\n  ${Pt} = pack2x16float(vec2f(f32(v.z), 0.0));\n}`,\"vec3h\"),vec4h:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([So])`(v) {\n  ${Pt} = pack2x16float(vec2f(f32(v.x), f32(v.y)));\n  ${Pt} = pack2x16float(vec2f(f32(v.z), f32(v.w)));\n}`,\"vec4h\"),vec2i:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([ir])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n}`,\"vec2i\"),vec3i:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Br])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n  ${Pt} = bitcast<u32>(v.z);\n}`,\"vec3i\"),vec4i:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([sr])`(v) {\n  ${Pt} = bitcast<u32>(v.x);\n  ${Pt} = bitcast<u32>(v.y);\n  ${Pt} = bitcast<u32>(v.z);\n  ${Pt} = bitcast<u32>(v.w);\n}`,\"vec4i\"),vec2u:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([$s])`(v) {\n  ${Pt} = v.x;\n  ${Pt} = v.y;\n}`,\"vec2u\"),vec3u:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Ps])`(v) {\n  ${Pt} = v.x;\n  ${Pt} = v.y;\n  ${Pt} = v.z;\n}`,\"vec3u\"),vec4u:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Is])`(v) {\n  ${Pt} = v.x;\n  ${Pt} = v.y;\n  ${Pt} = v.z;\n  ${Pt} = v.w;\n}`,\"vec4u\"),\"vec2<bool>\":nr([Wa])`(v) {\n  ${Pt} = u32(v.x);\n  ${Pt} = u32(v.y);\n}`,\"vec3<bool>\":nr([qa])`(v) {\n  ${Pt} = u32(v.x);\n  ${Pt} = u32(v.y);\n  ${Pt} = u32(v.z);\n}`,\"vec4<bool>\":nr([Va])`(v) {\n  ${Pt} = u32(v.x);\n  ${Pt} = u32(v.y);\n  ${Pt} = u32(v.z);\n  ${Pt} = u32(v.w);\n}`,mat2x2f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([yl])`(m) {\n  ${Pt} = bitcast<u32>(m[0][0]);\n  ${Pt} = bitcast<u32>(m[0][1]);\n  ${Pt} = bitcast<u32>(m[1][0]);\n  ${Pt} = bitcast<u32>(m[1][1]);\n}`,\"mat2x2f\"),mat3x3f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([bl])`(m) {\n  ${Pt} = bitcast<u32>(m[0][0]);\n  ${Pt} = bitcast<u32>(m[0][1]);\n  ${Pt} = bitcast<u32>(m[0][2]);\n  ${Pt} = 0u;\n  ${Pt} = bitcast<u32>(m[1][0]);\n  ${Pt} = bitcast<u32>(m[1][1]);\n  ${Pt} = bitcast<u32>(m[1][2]);\n  ${Pt} = 0u;\n  ${Pt} = bitcast<u32>(m[2][0]);\n  ${Pt} = bitcast<u32>(m[2][1]);\n  ${Pt} = bitcast<u32>(m[2][2]);\n  ${Pt} = 0u;\n}`,\"mat3x3f\"),mat4x4f:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(nr([Eo])`(m) {\n  ${Pt} = bitcast<u32>(m[0][0]);\n  ${Pt} = bitcast<u32>(m[0][1]);\n  ${Pt} = bitcast<u32>(m[0][2]);\n  ${Pt} = bitcast<u32>(m[0][3]);\n  ${Pt} = bitcast<u32>(m[1][0]);\n  ${Pt} = bitcast<u32>(m[1][1]);\n  ${Pt} = bitcast<u32>(m[1][2]);\n  ${Pt} = bitcast<u32>(m[1][3]);\n  ${Pt} = bitcast<u32>(m[2][0]);\n  ${Pt} = bitcast<u32>(m[2][1]);\n  ${Pt} = bitcast<u32>(m[2][2]);\n  ${Pt} = bitcast<u32>(m[2][3]);\n  ${Pt} = bitcast<u32>(m[3][0]);\n  ${Pt} = bitcast<u32>(m[3][1]);\n  ${Pt} = bitcast<u32>(m[3][2]);\n  ${Pt} = bitcast<u32>(m[3][3]);\n}`,\"mat4x4f\")};for(let[e,t]of Object.entries(UE))t.$name(`serialize${e[0].toLocaleUpperCase()}${e.slice(1)}`).$uses({dataBlockIndex:RE,nextByteIndex:VK,dataBuffer:LE});function OE(e){return`(${e.map((t,s)=>`_arg_${s}`).join(\", \")})`}function GE(e,t){let s=UE[e.type];if(s)return s.with(LE,t);if(_r(e)){let r=Object.keys(e.propTypes),o=FE(Object.values(e.propTypes),t);return nr([e])`(arg) {\\n  propsSerializer(${r.map(a=>`arg.${a}`).join(\", \")});\\n}`.$uses({propsSerializer:o}).$name(`${ct(e)??\"struct\"}Serializer`)}if(io(e)){let r=e.elementType,o=e.elementCount,a=GE(r,t);return nr([e])`(arg) {\\n${Array.from({length:o},(i,l)=>`  elementSerializer(arg[${l}]);`).join(`\n`)}\\n}`.$uses({elementSerializer:a}).$name(\"arraySerializer\")}throw new Error(`Cannot serialize data of type ${e.type}`)}function FE(e,t){let s={};return(globalThis.__TYPEGPU_AUTONAME__??(r=>r))(nr(e),\"shell\")`${OE(e)} {\\n${e.map((r,o)=>(s[`serializer${o}`]=GE(r,t),`  serializer${o}(_arg_${o});`)).join(`\n`)}\\n}`.$uses(s).$name(\"compoundSerializer\")}function NK(e,t,s,r,o){let a=t.map(ds).reduce((c,d)=>c+d,0);if(a>o.logSizeLimit)throw new Error(`Logged data needs to fit in ${o.logSizeLimit} bytes (one of the logs requires ${a} bytes). Consider increasing the limit by passing appropriate options to tgpu.init().`);let i=FE(t,s).$name(`log${e}serializer`),l=OE(t);return nr(t)`${l} {\n  dataBlockIndex = atomicAdd(&indexBuffer, 1);\n  if (dataBlockIndex >= ${o.logCountLimit}) {\n    return;\n  }\n  dataBuffer[dataBlockIndex].id = ${e};\n  dataByteIndex = 0;\n\n  compoundSerializer${l};\n}`.$uses({indexBuffer:r,dataBuffer:s,dataBlockIndex:RE,dataByteIndex:DE,compoundSerializer:i}).$name(`log${e}`)}var $K={logCountLimit:64,logSizeLimit:252,messagePrefix:\" GPU \"},IE=Je(\"/* console.log() */\",zr,\"runtime\"),XK=class{get logResources(){}generateLog(){return rr.warn(\"fallback\",\"'console.log' is only supported when resolving pipelines.\"),IE}},HK=class{#e;#t;#s=1;#r;#o;constructor(e){this.#e={...$K,...e[ve].logOptions},this.#t=new Map;let t=gt({id:M,serializedData:Fe(M,Math.ceil(this.#e.logSizeLimit/4))}).$name(\"SerializedLogData\");this.#o=e.createMutable(Fe(t,this.#e.logCountLimit)).$name(\"dataBuffer\"),this.#r=e.createMutable(lo(M)).$name(\"indexBuffer\")}generateLog(e,t,s){if(rp.$===\"vertex\")return rr.warn(\"suspicious\",\"'console' operations are not supported in vertex shaders.\"),IE;let r=this.#s++,o=s.map(c=>{if(c.dataType===Ns)return c;let d=Nl(e,[c],[$c(c.dataType)])?.[0];return kr(d,`Internal error. Expected type ${c.dataType} to be convertible to ${$c(c.dataType)}`),d}).map(GN),a=o.filter(c=>c.dataType!==Ns),i=NK(r,a.map(c=>c.dataType),this.#o,this.#r,this.#e),l=Je(Ne`${e.resolve(i).value}(${a})`,zr,\"runtime\");return this.#t.set(r,{op:t,argTypes:o.map(c=>c?.dataType===Ns?c?.value:c?.dataType)}),l}get logResources(){return this.#s===1?void 0:{dataBuffer:this.#o,indexBuffer:this.#r,options:this.#e,logIdToMeta:this.#t}}};function jK(e){return e?.resourceType===\"shellless-impl\"}function KK(e,t){let s=Ed(t,\"normal\");return{[ve]:!0,[Mo]:s,resourceType:\"shellless-impl\",argTypes:e,[Ws](r){return s.resolve(r,e,void 0)},toString(){return`fn*:${ct(s)??\"<unnamed>\"}(${e.map(r=>r.toString()).join(\", \")})`}}}var QK=new RegExp(`[${[...tE].join(\"\")}]+`,\"ug\"),R7=/[.\\p{XID_Continue}]/u;function D7(e){let t=JK(e).split(QK).filter(r=>r!==\"\"),s=\"\";for(let r=0;r<t.length;r++){let o=t[r],a=t[r+1];kr(o),s+=o,ZK(o,a)&&(s+=\" \")}return s}function ZK(e,t){if(t===void 0)return!1;let s=e.at(-1),r=t.at(0);return kr(s?.length===1&&r?.length===1,\"Expected tokens during minification to not be empty.\"),!!(R7.test(s)&&R7.test(r)||[\"//\",\"/*\",\"*/\"].includes(`${s}${r}`))}function JK(e){let t=\"\",s=0,r=0;for(;r<e.length;){if(e.startsWith(\"//\",r)){for(t+=`${e.slice(s,r)} `,r+=2;r<e.length&&!T3.has(e.charAt(r));)r+=1;s=r;continue}if(e.startsWith(\"/*\",r)){t+=`${e.slice(s,r)} `;let o=1;for(r+=2;r<e.length&&o>0;)e.startsWith(\"/*\",r)?(o+=1,r+=2):e.startsWith(\"*/\",r)?(o-=1,r+=2):r+=1;if(o>0)throw new SyntaxError(\"Block comment opening without corresponding closing found during minification.\");s=r;continue}if(e.startsWith(\"*/\",r))throw new SyntaxError(\"Block comment closing without corresponding opening found during minification.\");r+=1}return t+e.slice(s)}var Cb=\"#CATCHALL#\",eQ=class{_stack=[];_itemDepth=0;get itemDepth(){return this._itemDepth}get topItem(){let e=this._stack[this._stack.length-1];if(!e||e.type!==\"item\")throw new Error(\"Internal error, expected item layer to be on top.\");return e}get topFunctionScope(){return this._stack.findLast(e=>e.type===\"functionScope\")}get topBlockScope(){return this._stack.findLast(e=>e.type===\"blockScope\")}get blockDepth(){let e=0;for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"functionScope\")break;s?.type===\"blockScope\"&&e++}return e}pushItem(){this._itemDepth++,this._stack.push({type:\"item\",usedSlots:new Set})}pushSlotBindings(e){this._stack.push({type:\"slotBinding\",bindingMap:new WeakMap(e)})}pushFunctionScope(e,t,s,r){let o={type:\"functionScope\",functionType:e,argAccess:t,returnType:s,externalMap:r,reportedReturnTypes:new Set,placeholderForVariable:new Map,modifiedVariables:new Set};return this._stack.push(o),o}pushBlockScope(){this._stack.push({type:\"blockScope\",takenLocalIdentifiers:new Set,declarations:new Map,externals:new Map})}pop(e){let t=this._stack[this._stack.length-1];if(!t||e&&t.type!==e)throw new Error(`Internal error, expected a ${e} layer to be on top.`);let s=this._stack.pop();return e===\"item\"&&this._itemDepth--,s}readSlot(e){for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"item\")s.usedSlots.add(e);else if(s?.type===\"slotBinding\"){let r=s.bindingMap.get(e);if(r!==void 0)return r}else if(!(s?.type===\"functionScope\"||s?.type===\"blockScope\"))throw new Error(\"Unknown layer type.\")}return e.defaultValue}getSnippetById(e){for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"functionScope\"){let r=s.argAccess[e];if(r)return r();if(Object.hasOwn(s.externalMap,e)){let o=s.externalMap[e];return Su(o)&&ct(o)===void 0&&es(o,e.replaceAll(\".\",\"_\")),Ya(o)}return}if(s?.type===\"blockScope\"){let r=s.declarations.get(e)??s.externals.get(e);if(r!==void 0)return r}}}isIdentifierTakenLocally(e){for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"functionScope\")return!1;if(s?.type===\"blockScope\"&&s.takenLocalIdentifiers.has(e))return!0}return!1}isIdentifierTakenInCallStack(e){for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"blockScope\"&&s.takenLocalIdentifiers.has(e))return!0}return!1}defineBlockVariable(e,t){if(t.dataType===Ns)throw Error(`Tried to define variable '${e}' of unknown type`);for(let s=this._stack.length-1;s>=0;--s){let r=this._stack[s];if(r?.type===\"blockScope\"){r.declarations.set(e,t);return}}throw new Error(\"No block scope found to define a variable in.\")}setBlockExternals(e){for(let t=this._stack.length-1;t>=0;--t){let s=this._stack[t];if(s?.type===\"blockScope\"){Object.entries(e).forEach(([r,o])=>{s.externals.set(r,o)});return}}throw new Error(\"No block scope found to set externals in.\")}clearBlockExternals(){for(let e=this._stack.length-1;e>=0;--e){let t=this._stack[e];if(t?.type===\"blockScope\"){t.externals.clear();return}}throw new Error(\"No block scope found to clear externals in.\")}},Cm=[\"\",\"  \",\"    \",\"      \",\"        \",\"          \",\"            \",\"              \",\"                \"],o0=Cm.length-1,tQ=class{identLevel=0;get pre(){return Cm[this.identLevel]??Cm[o0].repeat(this.identLevel/o0)+Cm[this.identLevel%o0]}indent(){let e=this.pre;return this.identLevel++,e}dedent(){return this.identLevel--,this.pre}withResetLevel(e){let t=this.identLevel;this.identLevel=0;try{return e()}finally{this.identLevel=t}}};function au(e,t,s=\"argument\"){let r=!1;return{name:e,access:()=>(r=!0,Je(e,t,s,!1)),decoratedType:t,get used(){return r}}}function L7(e,t){return()=>{let s=e();if(s)return Cu(s,t)}}var YE=class{#e;_indentController=new tQ;_itemStateStack=new eQ;#t=[];_declarations=[];_varyingLocations;#s=new WeakSet;#r;gen;get varyingLocations(){return this._varyingLocations}[ve]={itemStateStack:this._itemStateStack};bindGroupLayoutsToPlaceholderMap=new Map;_nextFreeLayoutPlaceholderIdx=0;fixedBindings=[];enableExtensions;expectedType;#o=0;constructor(e){this.enableExtensions=e.enableExtensions,this.#r=e.root?new HK(e.root):new XK,this.#e=e.namespace[ve],this.gen=e.shaderGenerator??new Vj,this.gen.initGenerator(this)}isIdentifierBanned(e){return _3.has(e)}isIdentifierTaken(e,t){return this.#e.takenGlobalIdentifiers.has(e)||(t===\"block\"?this._itemStateStack.isIdentifierTakenLocally(e):this._itemStateStack.isIdentifierTakenInCallStack(e))}makeUniqueIdentifier(e=\"item\",t){if(t===\"block\"&&Sh(e).success&&!this.isIdentifierTaken(e,t))return this.reserveIdentifier(e,\"block\"),e;let s=v$(e),r=0,o=this.#e.strategy===\"random\",a=o?`${s}_${this.#o++}`:s;for(;this.isIdentifierTaken(a,t);)a=o?`${s}_${this.#o++}`:`${s}_${++r}`;return this.reserveIdentifier(a,t),a}reserveIdentifier(e,t){if(t===\"block\"){let s=this._itemStateStack.topBlockScope;if(s){s.takenLocalIdentifiers.add(e);return}}this.#e.takenGlobalIdentifiers.add(e)}get pre(){return this._indentController.pre}get topFunctionScope(){return this._itemStateStack.topFunctionScope}get topFunctionReturnType(){let e=this._itemStateStack.topFunctionScope;return kr(e,\"Internal error, expected function scope to be present.\"),e.returnType}get shelllessRepo(){return this.#e.shelllessRepo}get blockDepth(){return this._itemStateStack.blockDepth}indent(){return this._indentController.indent()}dedent(){return this._indentController.dedent()}getDedented(e){return e.replaceAll(`\n${Cm[1]}`,`\n`)}withResetIndentLevel(e){return this._indentController.withResetLevel(e)}getById(e){let t=this._itemStateStack.getSnippetById(e);return t===void 0?null:t}defineVariable(e,t){this._itemStateStack.defineBlockVariable(e,t)}reportReturnType(e){let t=this._itemStateStack.topFunctionScope;kr(t,\"Internal error, expected function scope to be present.\"),t.reportedReturnTypes.add(e)}pushBlockScope(){this._itemStateStack.pushBlockScope()}popBlockScope(){this._itemStateStack.pop(\"blockScope\")}setBlockExternals(e){this._itemStateStack.setBlockExternals(e)}clearBlockExternals(){this._itemStateStack.clearBlockExternals()}generateLog(e,t){return this.#r.generateLog(this,e,t)}get logResources(){return this.#r.logResources}resolveFunction(e){try{let t=this._itemStateStack.pushFunctionScope(e.functionType,{},e.returnType,e.externalMap);this._itemStateStack.pushBlockScope();let s=[];if(e.entryInput){let{dataSchema:a,positionalArgs:i}=e.entryInput,l=e.params[0],c=a?au(this.makeUniqueIdentifier(\"_arg_0\",\"block\"),a):void 0;if(c&&s.push(c),l?.type===gm.destructuredObject)for(let{name:d,alias:u}of l.props){let p=i.find(_=>_.schemaKey===d);if(p){let _=au(this.makeUniqueIdentifier(u,\"block\"),p.type);s.push(_),t.argAccess[u]=_.access}else c&&(t.argAccess[u]=L7(c.access,d))}else if(l?.type===gm.identifier){let d=[];for(let p of i){let _=au(this.makeUniqueIdentifier(p.schemaKey,\"block\"),p.type);s.push(_),d.push({schemaKey:p.schemaKey,arg:_.access})}let u=new ZM(c?.access,d);t.argAccess[l.name]=()=>Je(\"N/A\",u,\"argument\")}else for(let d of i){let u=this.makeUniqueIdentifier(`_arg_${d.schemaKey}`,\"block\"),p=au(u,d.type);s.push(p),t.argAccess[u]=p.access}}else for(let[a,i]of e.argTypes.entries()){let l=e.params[a],c=ta(i)?i.addressSpace===\"storage\"?i.access===\"read\"?\"readonly\":\"mutable\":i.addressSpace:\"argument\";switch(l?.type){case gm.identifier:{let d=au(this.makeUniqueIdentifier(l.name,\"block\"),i,c);s.push(d),t.argAccess[l.name]=d.access;break}case gm.destructuredObject:{let d=au(this.makeUniqueIdentifier(`_arg_${a}`,\"block\"),i,c);s.push(d);for(let{name:u,alias:p}of l.props)t.argAccess[p]=L7(d.access,u);break}case void 0:i instanceof ti||s.push({name:this.makeUniqueIdentifier(`_arg_${a}`,\"block\"),access:()=>{throw new Error(\"Unreachable: Accessing an argument that wasn't named in the function signature\")},decoratedType:i,used:!1})}}let r,o=this.gen.functionDefinition({functionType:e.functionType,name:e.name,workgroupSize:e.workgroupSize,args:s,body:e.body,determineReturnType:()=>{if(r)return r;if(r=e.returnType,r instanceof ti&&(_r(t.reportedReturnTypes.values().next().value)?r=r.completeStruct:r=void 0),!r){let a=[...t.reportedReturnTypes];if(a.length===0)r=zr;else{let i=Nx(a);i&&!i.hasImplicitConversions&&(r=i.targetType)}if(!r)throw new Error(`Expected function to have a single return type, got [${a.join(\", \")}]. Cast explicitly to the desired type.`);r=dn(r),(e.functionType===\"vertex\"||e.functionType===\"fragment\")&&(r=p_(r))}return r}});if(!r)throw new Error(\"Failed to determine return type\");return{code:o,returnType:r}}finally{this._itemStateStack.pop(\"blockScope\"),this._itemStateStack.pop(\"functionScope\")}}addDeclaration(e,t){this._declarations.push({name:t,code:e})}get declarations(){return this._declarations}allocateLayoutEntry(e){let t=this.bindGroupLayoutsToPlaceholderMap,s=t.get(e);return s||(s=`#BIND_GROUP_LAYOUT_${this._nextFreeLayoutPlaceholderIdx++}#`,t.set(e,s)),s}allocateFixedEntry(e,t){let s=this.fixedBindings.length;return this.fixedBindings.push({layoutEntry:e,resource:t}),{group:Cb,binding:s}}readSlot(e){let t=this._itemStateStack.readSlot(e);if(t===void 0)throw new lN(e);return t}withSlots(e,t){if(e.length===0)return t();this._itemStateStack.pushSlotBindings(e);try{return t()}finally{this._itemStateStack.pop(\"slotBinding\")}}withVaryingLocations(e,t){this._varyingLocations=e;try{return t()}finally{this._varyingLocations=void 0}}withRenamed(e,t,s){if(!t)return s();let r=ct(e);try{return es(e,t),s()}finally{r&&es(e,r)}}unwrap(e){if(S1(e))return this.withRenamed(e[ya].inner,ct(e),()=>this.withSlots(e[ya].pairs,()=>this.unwrap(e[ya].inner)));let t=e;for(;;)if(ab(t))t=this.readSlot(t);else if(nb(t))t=this._getOrCompute(t);else break;return t}_getOrCompute(e){let t=this.#e.memoizedLazy.get(e)??[];this._itemStateStack.pushItem();try{for(let o of t)if([...o.slotToValueMap.entries()].every(([a,i])=>a.areEqual(this._itemStateStack.readSlot(a),i)))return o.result;this.pushMode(new Ju);let s;try{s=e[ve].compute()}finally{this.popMode(\"normal\")}let r=new Map;for(let o of this._itemStateStack.topItem.usedSlots)r.set(o,this._itemStateStack.readSlot(o));return t.push({slotToValueMap:r,result:s}),this.#e.memoizedLazy.set(e,t),s}catch(s){throw s instanceof fu?s.appendToTrace(e):new fu(s,[e])}finally{this._itemStateStack.pop(\"item\")}}_getOrInstantiate(e){let t=this.#e.memoizedResolves.get(e)??[];this._itemStateStack.pushItem();try{for(let o of t)if([...o.slotToValueMap.entries()].every(([a,i])=>a.areEqual(this._itemStateStack.readSlot(a),i)))return o.result;let s;if(o_(e))s=Je(this.gen.emitTypeAnnotation(e),zr,\"runtime\");else if(nb(e)||ab(e))s=this.resolve(this.unwrap(e));else if(QC(e))s=e[Ws](this);else if(Pu(e)){let o=this.#e.shelllessRepo.get(e,void 0);if(!o)throw new Error(`Couldn't resolve ${e.name}. Make sure it's a function that accepts no arguments, or call it from another TypeGPU function.`);return this.withResetIndentLevel(()=>this.resolve(o))}else throw new TypeError(`Unresolvable internal value: ${pn(e)}`);let r=new Map;for(let o of this._itemStateStack.topItem.usedSlots)r.set(o,this._itemStateStack.readSlot(o));return t.push({slotToValueMap:r,result:s}),this.#e.memoizedResolves.set(e,t),s}catch(s){throw s instanceof fu?s.appendToTrace(e):new fu(s,[e])}finally{this._itemStateStack.pop(\"item\")}}resolve(e,t){if(typeof e==\"string\"){if(!t||t===Ns)throw new Error(`Strings cannot be injected into WGSL directly (tried to inject '${e}'). Look for TypeGPU APIs that cover your use-case, or resort to using tgpu['~unstable'].rawCodeSnippet for raw code injection.`);return Je(e,t,\"runtime\")}if((pb(e)||jK(e))&&!S1(e)){if(this.#s.has(e)&&!this.#e.memoizedResolves.has(e))throw new Error(`Recursive function ${e} detected. Recursion is not allowed on the GPU.`);this.#s.add(e)}if(S1(e))return this.withRenamed(e[ya].inner,ct(e),()=>this.withSlots(e[ya].pairs,()=>this.resolve(e[ya].inner,t)));if(_s(e)||Pu(e)){if(this._itemStateStack.itemDepth===0)try{this.pushMode(new yN);let s=JC(this,()=>this._getOrInstantiate(e));return Je(`${this._declarations.map(r=>r.code).join(`\n\n`)}${s.value}`,zr,\"runtime\")}finally{this.popMode(\"codegen\")}return this._getOrInstantiate(e)}if(typeof e==\"number\"){let s=t??Ai(e).dataType;return kr(s!==Ns,\"Schema has to be known for resolving numbers\"),this.gen.numericLiteral(e,s)}if(typeof e==\"boolean\")return Je(e?\"true\":\"false\",ys,\"constant\",!1);if(t&&io(t)){if(!Array.isArray(e))throw new jt(`Cannot coerce ${e} into value of type '${t}'`);if(t.elementCount!==e.length)throw new jt(`Cannot create value of type '${t}' from an array of length: ${e.length}`);return this.gen.typeInstantiation(t,e.map(s=>Je(s,t.elementType,\"runtime\")))}if(t&&_r(t))return this.gen.typeInstantiation(t,Object.entries(t.propTypes).map(([s,r])=>Je(e[s],r,\"runtime\")));throw new jt(`Value ${pn(e)} is not resolvable${t&&t!==Ns?` to type ${pn(t)}`:\"\"}`)}resolveSnippet(e){return KC(this.resolve(e.value,e.dataType).value,e)}pushMode(e){this.#t.push(e)}popMode(e){let t=this.#t.pop();e!==void 0&&kr(t?.type===e,\"Unexpected mode\")}get mode(){return this.#t[this.#t.length-1]??eM}};function Gh(e,t){let s=new YE(t),r=(t.config?s.withSlots(t.config(new yE([])).bindings,()=>s.resolve(e)):s.resolve(e)).value,o=s.bindGroupLayoutsToPlaceholderMap,a=[],i=cK(new Set([...o.keys()].map(_=>_.index).filter(_=>_!==void 0))),l=s.fixedBindings.map((_,f)=>[String(f),_.layoutEntry]),c=[],d=()=>{let _=i.next().value,f=(globalThis.__TYPEGPU_AUTONAME__??(h=>h))(CE(Object.fromEntries(l)),\"catchallLayout\");return a[_]=f,r=r.replaceAll(Cb,String(_)),c.push([Cb,String(_)]),[_,new EE(t.root,f,Object.fromEntries(s.fixedBindings.map((h,g)=>[String(g),h.resource])))]},u=l.length>0?d():void 0;for(let[_,f]of o.entries()){let h=_.index??i.next().value;a[h]=_,r=r.replaceAll(f,String(h)),c.push([f,String(h)])}t.enableExtensions&&t.enableExtensions.length>0&&(r=`${t.enableExtensions.map(_=>`enable ${_};`).join(`\n`)}\n\n${r}`);let p=s.declarations.map(({name:_,code:f})=>({name:_,code:c.reduce((h,[g,y])=>h.replaceAll(g,y),f)}));return t.minify&&(r=D7(r),p=p.map(_=>({..._,code:D7(_.code)}))),{code:r,declarations:p,usedBindGroupLayouts:a,catchall:u,logResources:s.logResources}}function WE(e,t,s){return e.flatMap((r,o)=>{let a=t&&o===t[0]?t[1]:s?.get(r);return a?[[r,a]]:[]})}function sQ(e,t){return e.flatMap(s=>{let r=t?.get(s);return r?[[s,r]]:[]})}var rQ={dispatchWorkgroupsIndirect:\"3 x u32\",drawIndirect:\"4 x u32\",drawIndexedIndirect:\"3 x u32, i32, u32\"};function U7(e,t,s,r){if(t+s>e)throw new Error(`Buffer too small for ${r}. Required: ${s} bytes at offset ${t}, but buffer is only ${e} bytes.`);if(t%4!==0)throw new Error(`Indirect buffer offset must be a multiple of 4. Got: ${t}`)}function ku(e,t,s,r){if(ol(e)){let i=typeof t==\"number\"?t:t?.offset??0;return U7(e.size,i,s,r),i}let{offset:o,contiguous:a}=t?typeof t==\"number\"?{offset:t,contiguous:s}:t:M1(e.dataType);return U7(ds(e.dataType),o,s,r),a<s&&rr.warn(\"suspicious\",`${r}: Starting at offset ${o}, only ${a} contiguous bytes are available before padding. '${r}' requires ${s} bytes (${rQ[r]}). Reading across padding may result in undefined behavior.`),o}var J1=[M,$s,Ps,Is];je({name:\"bitcastU32toF32\",normalImpl:(e=>typeof e==\"number\"?fi(e):$a.bitcastU32toF32[e.kind](e)),codegenImpl:(e,[t],s)=>e.gen.emitCall(\"bitcast\",[Ya(s)],[t]),signature:(...e)=>{let t=wh(e,J1);if(!t)throw new jr(e,J1);return{argTypes:t,returnType:js(t[0])?t[0].type===\"vec2u\"?ps:t[0].type===\"vec3u\"?Zs:qt:n}},sideEffects:!1});je({name:\"bitcastU32toI32\",normalImpl:(e=>typeof e==\"number\"?vi(e):$a.bitcastU32toI32[e.kind](e)),codegenImpl:(e,[t],s)=>e.gen.emitCall(\"bitcast\",[Ya(s)],[t]),signature:(...e)=>{let t=wh(e,J1);if(!t)throw new jr(e,J1);return{argTypes:t,returnType:js(t[0])?t[0].type===\"vec2u\"?ir:t[0].type===\"vec3u\"?Br:sr:j}},sideEffects:!1});var O7=[n,ps,Zs,qt];je({name:\"bitcastF32toU32\",normalImpl:(e=>typeof e==\"number\"?hi(e):$a.bitcastF32toU32[e.kind](e)),codegenImpl:(e,[t],s)=>e.gen.emitCall(\"bitcast\",[Ya(s)],[t]),signature:(...e)=>{let t=wh(e,O7);if(!t)throw new jr(e,O7);return{argTypes:t,returnType:js(t[0])?t[0].type===\"vec2f\"?$s:t[0].type===\"vec3f\"?Ps:Is:M}},sideEffects:!1});var Zf=new ArrayBuffer(16),Jf={f32:new Float32Array(Zf),u32:new Uint32Array(Zf),i32:new Int32Array(Zf),u16:new Uint16Array(Zf)};function oQ(e,t){if(typeof e==\"number\")t[0]=e;else for(let s=0;s<e.length;s++)t[s]=e[s]}function aQ(e,t){if(typeof e==\"number\")t[0]=j1(e);else for(let s=0;s<e.length;s++)t[s]=j1(e[s])}function nQ(e,t){let s=\"componentCount\"in t?t.componentCount:1,r=[];for(let o=0;o<s;o++)r.push(e[o]);return t(...r)}function iQ(e,t){let s=\"componentCount\"in t?t.componentCount:1,r=[];for(let o=0;o<s;o++)r.push($x(e[o]));return t(...r)}var lQ=(e,t)=>{let s=\"primitive\"in e?e.primitive:e,r=\"primitive\"in t?t.primitive:t;return o=>(s.type===\"f16\"?aQ(o,Jf.u16):oQ(o,Jf[s.type]),r.type===\"f16\"?iQ(Jf.u16,t):nQ(Jf[r.type],t))};function Qt(e,t){return je({name:\"bitcast\",normalImpl:lQ(e,t),codegenImpl:(s,[r])=>s.gen.emitCall(\"bitcast\",[Ya(t)],[r]),signature:s=>{let r=wh([s],[e]);if(!r)throw new jr([s],[e]);return{argTypes:r,returnType:t}},sideEffects:!1})}var G7={f16:{f16:Qt(Vr,Vr)},f32:{f32:Qt(n,n),i32:Qt(n,j),u32:Qt(n,M),vec2h:Qt(n,To)},i32:{f32:Qt(j,n),i32:Qt(j,j),u32:Qt(j,M),vec2h:Qt(j,To)},u32:{f32:Qt(M,n),i32:Qt(M,j),u32:Qt(M,M),vec2h:Qt(M,To)},vec2h:{f32:Qt(To,n),i32:Qt(To,j),u32:Qt(To,M),vec2h:Qt(To,To)},vec3h:{vec3h:Qt(Pa,Pa)},vec2f:{vec2f:Qt(ps,ps),vec2i:Qt(ps,ir),vec2u:Qt(ps,$s),vec4h:Qt(ps,So)},vec2i:{vec2f:Qt(ir,ps),vec2i:Qt(ir,ir),vec2u:Qt(ir,$s),vec4h:Qt(ir,So)},vec2u:{vec2f:Qt($s,ps),vec2i:Qt($s,ir),vec2u:Qt($s,$s),vec4h:Qt($s,So)},vec4h:{vec2f:Qt(So,ps),vec2i:Qt(So,ir),vec2u:Qt(So,$s),vec4h:Qt(So,So)},vec3f:{vec3f:Qt(Zs,Zs),vec3i:Qt(Zs,Br),vec3u:Qt(Zs,Ps)},vec3i:{vec3f:Qt(Br,Zs),vec3i:Qt(Br,Br),vec3u:Qt(Br,Ps)},vec3u:{vec3f:Qt(Ps,Zs),vec3i:Qt(Ps,Br),vec3u:Qt(Ps,Ps)},vec4f:{vec4f:Qt(qt,qt),vec4i:Qt(qt,sr),vec4u:Qt(qt,Is)},vec4i:{vec4f:Qt(sr,qt),vec4i:Qt(sr,sr),vec4u:Qt(sr,Is)},vec4u:{vec4f:Qt(Is,qt),vec4i:Qt(Is,sr),vec4u:Qt(Is,Is)}};function cQ(e,t){if(\"type\"in e&&e.type in G7){let s=G7[e.type];if(\"type\"in t&&t.type in s)return s[t.type]}throw new Error(`Incorrect bitcast from ${ct(e)} to ${ct(t)}.`)}var qE=Tn(cQ),dQ=je({name:\"unpack2x16float\",normalImpl:e=>{let t=new ArrayBuffer(4);new Md(t).writeUint32(e);let s=new ep(t);return ps(Ao(s),Ao(s))},signature:{argTypes:[M],returnType:ps},codegenImpl:(e,[t])=>Ne`unpack2x16float(${t})`,sideEffects:!1});je({name:\"pack2x16float\",normalImpl:e=>{let t=new ArrayBuffer(4),s=new Md(t);return xo(s,e.x),xo(s,e.y),M(new ep(t).readUint32())},signature:{argTypes:[ps],returnType:M},codegenImpl:(e,[t])=>Ne`pack2x16float(${t})`,sideEffects:!1});je({name:\"unpack4x8unorm\",normalImpl:e=>{let t=new ArrayBuffer(4);new Md(t).writeUint32(e);let s=new ep(t);return qt(s.readUint8()/255,s.readUint8()/255,s.readUint8()/255,s.readUint8()/255)},signature:{argTypes:[M],returnType:qt},codegenImpl:(e,[t])=>Ne`unpack4x8unorm(${t})`,sideEffects:!1});je({name:\"pack4x8unorm\",normalImpl:e=>{let t=new ArrayBuffer(4),s=new Md(t);return s.writeUint8(e.x*255),s.writeUint8(e.y*255),s.writeUint8(e.z*255),s.writeUint8(e.w*255),M(new ep(t).readUint32())},signature:{argTypes:[qt],returnType:M},codegenImpl:(e,[t])=>Ne`pack4x8unorm(${t})`,sideEffects:!1});var ks=e=>qE(M,n)(e??0),_i=e=>qE(M,j)(e??0),nu=e=>dQ(e??0),uQ={f32:e=>ks(e[0]),f16:e=>nu(e[0]).x,i32:e=>_i(e[0]),u32:e=>e[0]??0,bool:e=>!!e[0],vec2f:e=>ps(ks(e[0]),ks(e[1])),vec3f:e=>Zs(ks(e[0]),ks(e[1]),ks(e[2])),vec4f:e=>qt(ks(e[0]),ks(e[1]),ks(e[2]),ks(e[3])),vec2h(e){let t=nu(e[0]);return To(t.x,t.y)},vec3h(e){let t=nu(e[0]),s=nu(e[1]);return Pa(t.x,t.y,s.x)},vec4h(e){let t=nu(e[0]),s=nu(e[1]);return So(t.x,t.y,s.x,s.y)},vec2i:e=>ir(_i(e[0]),_i(e[1])),vec3i:e=>Br(_i(e[0]),_i(e[1]),_i(e[2])),vec4i:e=>sr(_i(e[0]),_i(e[1]),_i(e[2]),_i(e[3])),vec2u:e=>$s(e[0]??0,e[1]??0),vec3u:e=>Ps(e[0]??0,e[1]??0,e[2]??0),vec4u:e=>Is(e[0]??0,e[1]??0,e[2]??0,e[3]??0),\"vec2<bool>\":e=>Wa(!!e[0],!!e[1]),\"vec3<bool>\":e=>qa(!!e[0],!!e[1],!!e[2]),\"vec4<bool>\":e=>Va(!!e[0],!!e[1],!!e[2],!!e[3]),mat2x2f:e=>yl(ks(e[0]),ks(e[1]),ks(e[2]),ks(e[3])),mat3x3f:e=>bl(ks(e[0]),ks(e[1]),ks(e[2]),ks(e[4]),ks(e[5]),ks(e[6]),ks(e[8]),ks(e[9]),ks(e[10])),mat4x4f:e=>Eo(ks(e[0]),ks(e[1]),ks(e[2]),ks(e[3]),ks(e[4]),ks(e[5]),ks(e[6]),ks(e[7]),ks(e[8]),ks(e[9]),ks(e[10]),ks(e[11]),ks(e[12]),ks(e[13]),ks(e[14]),ks(e[15]))};function pQ(e,t){let s=uQ[t.type];if(s)return s(e);if(_r(t)){let r=Object.keys(t.propTypes),o=Mb(e,Object.values(t.propTypes));return Object.fromEntries(r.map((a,i)=>[a,o[i]]))}if(io(t)){let r=t.elementType,o=t.elementCount;return Mb(e,Array.from({length:o},()=>r))}throw new Error(`Cannot deserialize data of type ${t.type}`)}function Mb(e,t){let s=0;return t.map(r=>{if(!Td(r))return r;let o=Math.ceil(ds(r)/4),a=pQ(e.subarray(s,s+o),r);return s+=o,a})}function mQ(e,t){return Mb(e,t).map(sb)}function _Q(e){let{indexBuffer:t,dataBuffer:s,logIdToMeta:r,options:o}=e;s.read().then(a=>{a.filter(i=>i.id).forEach(({id:i,serializedData:l})=>{let{argTypes:c,op:d}=r.get(i),u=mQ(new Uint32Array(l),c);u.length===0&&u.push(\"\"),d.bind(console)(`%c${o.messagePrefix}%c ${u[0]}`,\"background: #936ff5; color: white;\",\"color: inherit; background: none\",...u.slice(1))})}),t.read().then(a=>{a>o.logCountLimit&&rr.warn(\"log-limit-exceeded\",`Log count limit per dispatch (${o.logCountLimit}) exceeded by ${a-o.logCountLimit} calls. Consider increasing the limit by passing appropriate options to tgpu.init().`)}),s.buffer.clear(),t.buffer.clear()}function fQ(e,t,s,r){return new vQ(e,t,s,r)}function z3(e){let t=e;return t?.resourceType===\"query-set\"&&!!t[ve]}var vQ=class{resourceType=\"query-set\";#e;#t=!1;#s=!0;#r=void 0;#o=void 0;[He];[ve];constructor(e,t,s,r){this.#e=!r,this[He]={type:\"query-set\",device:e.device,queryType:t,count:s,raw:r,label:void 0};let o=this;this[ve]={get readBuffer(){return o.#r||(o.#r=o[He].device.createBuffer({size:o.count*BigUint64Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})),o.#r},get resolveBuffer(){return o.#o||(o.#o=o[He].device.createBuffer({size:o.count*BigUint64Array.BYTES_PER_ELEMENT,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC})),o.#o},materialize:()=>{if(this.#t)throw new Error(\"This QuerySet has been destroyed.\");let a=this[He];return a.raw||(a.raw=a.device.createQuerySet({type:a.queryType,count:a.count})),a.raw}}}get type(){return this[He].queryType}get count(){return this[He].count}get querySet(){return this[ve].materialize()}get destroyed(){return this.#t}get available(){return this.#s}$name(e){es(this,e);let t=this[He].raw;return t&&(t.label=e),this}resolve(){if(this.#t)throw new Error(\"This QuerySet has been destroyed.\");if(!this.#s)throw new Error(\"This QuerySet is busy resolving or reading.\");let e=this[He].device.createCommandEncoder();e.resolveQuerySet(this.querySet,0,this.count,this[ve].resolveBuffer,0),this[He].device.queue.submit([e.finish()])}async read(){if(!this.#o)throw new Error(\"QuerySet must be resolved before reading.\");this.#s=!1;try{let e=this[He].device.createCommandEncoder();e.copyBufferToBuffer(this[ve].resolveBuffer,0,this[ve].readBuffer,0,this.count*BigUint64Array.BYTES_PER_ELEMENT),this[He].device.queue.submit([e.finish()]);let t=this[ve].readBuffer;await t.mapAsync(GPUMapMode.READ);let s=new BigUint64Array(t.getMappedRange().slice());return t.unmap(),Array.from(s)}finally{this.#s=!0}}destroy(){this.#t||(this.#t=!0,this[He].raw&&this.#e&&this[He].raw.destroy(),this.#r?.destroy(),this.#o?.destroy(),this.#r=this.#o=void 0)}};function VE(e,t,s){return e.timestampWrites?{...e,performanceCallback:t}:{...e,performanceCallback:t,timestampWrites:{querySet:s,beginningOfPassWriteIndex:0,endOfPassWriteIndex:1}}}function NE(e,t,s){if(!s.enabledFeatures.has(\"timestamp-query\"))throw new Error('Timestamp writes require the \"timestamp-query\" feature to be enabled on GPU device.');let r={querySet:t.querySet};return t.beginningOfPassWriteIndex!==void 0&&(r.beginningOfPassWriteIndex=t.beginningOfPassWriteIndex),t.endOfPassWriteIndex!==void 0&&(r.endOfPassWriteIndex=t.endOfPassWriteIndex),{...e,timestampWrites:r}}var F7=new WeakMap;async function hQ(e,t){if(!e.available)return;let s=await e.read();for(let{priors:r,callback:o}of t){let a=s[r.timestampWrites?.beginningOfPassWriteIndex??0],i=s[r.timestampWrites?.endOfPassWriteIndex??1];if(a===void 0||i===void 0)throw new Error(\"QuerySet did not return valid timestamps.\");await o(a,i)}}function gQ(e,t){let s=t.timestampWrites?.querySet,r=t.performanceCallback;if(!s)throw new Error(\"Cannot dispatch workgroups with performance callback without a query set.\");if(!z3(s))throw new Error(\"Performance callback with raw GPUQuerySet is not supported. Use TgpuQuerySet instead.\");let o=e[ve];if(o.adopted)return!1;let{root:a}=o;o.beforeFinish.set(s,c=>{c.resolveQuerySet(a.unwrap(s),0,s.count,s[ve].resolveBuffer,0)});let i=F7.get(e);i||(i=new Map,F7.set(e,i));let l=i.get(s);if(!l){let c=[];l=c,i.set(s,c),o.afterSubmit.set(s,()=>{i.delete(s),hQ(s,c)})}return l.some(c=>c.priors===t)?rr.warnOnce(\"suspicious\",s,\"repeated-timed-execution\",\"Repeated executions of a timed pipeline within one command encoder write to the same query set indices, so the performance callback reports only the last execution.\"):l.push({priors:t,callback:r}),!0}var yQ=class{bindGroups=new Map;vertexBuffers=new Map;currentPipeline;indexBuffer;stencilReference;appliedStencilReference=0;version=0;rawAccessed=!1},bQ=class{bindGroups=new Map;currentPipeline;version=0;rawAccessed=!1};function $E(e,t,s){ic(t)?e.bindGroups.set(t.layout,t):e.bindGroups.set(t,s),e.version++}function XE(e,t){let{priors:s}=t[ve];if(e.currentPipeline=t,s.bindGroupLayoutMap)for(let[r,o]of s.bindGroupLayoutMap)e.bindGroups.set(r,o);if(s.vertexLayoutMap)for(let[r,o]of s.vertexLayoutMap)e.vertexBuffers.set(r,{buffer:o,offset:void 0,size:void 0});s.indexBuffer&&(e.indexBuffer=s.indexBuffer),s.stencilReference!==void 0&&(e.stencilReference=s.stencilReference),e.version++}function HE(e,t){let{priors:s}=t[ve];if(e.currentPipeline=t,s.bindGroupLayoutMap)for(let[r,o]of s.bindGroupLayoutMap)e.bindGroups.set(r,o);e.version++}function xQ(e,t,s){let{buffer:r,indexFormat:o,offsetBytes:a,sizeBytes:i}=s;Fm(r)?e.setIndexBuffer(t.unwrap(r),o,a,i):e.setIndexBuffer(r,o,a,i)}function jE(e,t,s,r,o){let a=new Set(s);if(s.forEach((i,l)=>{if(r&&l===r[0])e.setBindGroup(l,t.unwrap(r[1])),a.delete(i);else{let c=o(i);c!==void 0&&(a.delete(i),ic(c)?e.setBindGroup(l,t.unwrap(c)):e.setBindGroup(l,c))}}),a.size>0)throw new dN(a)}function AQ(e,t,s,r){let o=new Set;if(s.forEach((a,i)=>{let l=r(a);!l||!l.buffer?o.add(a):Fm(l.buffer)?e.setVertexBuffer(i,t.unwrap(l.buffer),l.offset,l.size):e.setVertexBuffer(i,l.buffer,l.offset,l.size)}),o.size>0)throw new uN(o)}function wQ(e,t,s,r){let o=s[ve].core.unwrap();e.setPipeline(o.pipeline),jE(e,t,o.usedBindGroupLayouts,o.catchall,a=>r.bindGroups.get(a)),AQ(e,t,o.usedVertexLayouts,a=>r.vertexBuffers.get(a)),r.indexBuffer!==void 0&&xQ(e,t,r.indexBuffer),typeof e.setStencilReference==\"function\"&&r.stencilReference!==void 0&&(r.rawAccessed||r.stencilReference!==r.appliedStencilReference)&&(e.setStencilReference(r.stencilReference),r.appliedStencilReference=r.stencilReference)}function TQ(e,t,s,r){let o=s[ve].core.unwrap();e.setPipeline(o.pipeline),jE(e,t,o.usedBindGroupLayouts,o.catchall,a=>r.bindGroups.get(a))}function KE(e){if(!e)throw new Error(\"No index buffer is set. Call pipeline.withIndexBuffer or pass.setIndexBuffer before drawing indexed geometry.\")}function I7(e,t){rr.warnOnce(\"suspicious\",e,t,`${t} is ignored when recording into a raw GPUCommandEncoder, since there is no submission to report after. Use root['~unstable'].createCommandEncoder() instead.`)}function QE(e,t){return!e||e[ve].adopted?!1:(e[ve].afterSubmit.set(t,()=>_Q(t)),!0)}function ZE(e,t,s,r){s&&!QE(e,s)&&I7(t,\"Shader console.log output\"),r.performanceCallback&&!gQ(e,r)&&I7(t,\"The performance callback\"),r.encoder===void 0&&e.submit()}var SQ={render:{into:\"drawing into a render pass\",intoRaw:\"drawing into a raw render pass\",begin:\"beginRenderPass\"},compute:{into:\"dispatching into a compute pass\",intoRaw:\"dispatching into a raw compute pass\",begin:\"beginComputePass\"}};function JE(e,t,s,r,o,a=!1){let i=SQ[o];a&&rr.warnOnce(\"suspicious\",e,\"attachments\",`Pipeline-level attachments are ignored when ${i.into}. Pass \\`colorAttachments\\` and \\`depthStencilAttachment\\` to encoder.${i.begin} instead.`),s&&rr.warnOnce(\"suspicious\",e,\"timestampWrites\",`Pipeline-level timestamp writes are ignored when ${i.into}. Pass \\`timestampWrites\\` to encoder.${i.begin} instead.`),r&&!QE(t,r)&&rr.warnOnce(\"suspicious\",e,\"logs\",`Shader console.log output is ignored when ${i.intoRaw} encoder, since there is no submission to read it back after.`)}function Eb(e,t,s,r,o,a=!1){let{state:i,rawPass:l}=t,{core:c,priors:d}=s[ve];i.currentPipeline!==s&&XE(i,s),r&&KE(i.indexBuffer);let u=c.unwrap();a||JE(c,t.owner,!!d.timestampWrites,u.logResources,\"render\",!!d.colorAttachment||!!d.depthStencilAttachment),(i.rawAccessed||t.appliedVersion!==i.version)&&(wQ(l,e,s,i),t.appliedVersion=i.version),o(l)}function kb(e,t,s,r,o=!1){let{state:a,rawPass:i}=t,{core:l,priors:c}=s[ve];a.currentPipeline!==s&&HE(a,s);let d=l.unwrap();o||JE(l,t.owner,!!c.timestampWrites,d.logResources,\"compute\"),(a.rawAccessed||t.appliedVersion!==a.version)&&(TQ(i,e,s,a),t.appliedVersion=a.version),r(i)}function PQ(e){let t=e;return t?.resourceType===\"compute-pipeline\"&&_s(t)}function CQ(e){let t=e;return t?.resourceType===\"render-pipeline\"&&_s(t)}function MQ(e){return CQ(e)||PQ(e)}function R3(e){let t=e;return t?.resourceType===\"command-encoder\"&&_s(t)}function ek(e){let t=e;return(t?.resourceType===\"render-pass\"||t?.resourceType===\"render-bundle-encoder\")&&_s(t)}function tk(e){let t=e;return t?.resourceType===\"compute-pass\"&&_s(t)}function EQ(e){return typeof e?.getCurrentTexture==\"function\"}function sk(e){let t=e;return!_s(t)&&typeof t?.beginRenderPass==\"function\"&&typeof t?.beginComputePass==\"function\"}function kQ(e){let t=e;return!_s(t)&&typeof t?.dispatchWorkgroups==\"function\"&&t?.beginRenderPass===void 0}function BQ(e){let t=e;return!_s(t)&&typeof t?.executeBundles==\"function\"&&typeof t?.draw==\"function\"}function zQ(e){let t=e;return!_s(t)&&typeof t?.draw==\"function\"&&typeof t?.finish==\"function\"&&t?.executeBundles===void 0&&t?.beginRenderPass===void 0&&t?.dispatchWorkgroups===void 0}function a0(e,t){return Vm(t)?e.unwrap(t).createView():Eu(t)?e.unwrap(t):EQ(t)?t.getCurrentTexture().createView():t}function rk(e,t){let{querySet:s,beginningOfPassWriteIndex:r,endOfPassWriteIndex:o}=t,a={querySet:z3(s)?e.unwrap(s):s};return r!==void 0&&(a.beginningOfPassWriteIndex=r),o!==void 0&&(a.endOfPassWriteIndex=o),a}function RQ(e,t){let{rawEncoder:s,root:r}=e[ve],o={};return t?.label!==void 0&&(o.label=t.label),t?.timestampWrites!==void 0&&(o.timestampWrites=rk(r,t.timestampWrites)),new ok(r,s.beginComputePass(o),e)}function DQ(e,t){let s=new ok(e,t,void 0);return s[ve].state.rawAccessed=!0,s}var ok=class{[ve];resourceType=\"compute-pass\";#e;constructor(e,t,s){this.#e=e,this[ve]={rawPass:t,state:new bQ,owner:s,appliedVersion:void 0}}#t(e){let t=this[ve],s=t.state.currentPipeline;if(!s)throw new Error(\"Cannot dispatch without a call to pass.setPipeline\");kb(this.#e,t,s,e)}setPipeline(e){HE(this[ve].state,e)}setBindGroup(e,t){$E(this[ve].state,e,t)}dispatchWorkgroups(e,t,s){this.#t(r=>r.dispatchWorkgroups(e,t,s))}dispatchWorkgroupsIndirect(e,t){let s=ol(e)?e:e.buffer,r=ku(e,t,12,\"dispatchWorkgroupsIndirect\");this.#t(o=>o.dispatchWorkgroupsIndirect(s,r))}end(){this[ve].rawPass.end()}};function LQ(e){let t,s=\"all\";if(Vm(e)?t=e.props.format:Eu(e)&&(t=e[ve].format,s=e[ve].aspect??\"all\"),t!==void 0)return{hasDepth:t.includes(\"depth\")&&s!==\"stencil-only\",hasStencil:t.includes(\"stencil\")&&s!==\"depth-only\"}}function UQ(e,t){let s={...e,view:t},r=LQ(e.view);if(r===void 0&&(e.depthLoadOp!==void 0||e.depthStoreOp!==void 0||e.stencilLoadOp!==void 0||e.stencilStoreOp!==void 0))return s;let{hasDepth:o,hasStencil:a}=r??{hasDepth:!0,hasStencil:!1};return o&&!e.depthReadOnly&&(s.depthLoadOp??=\"clear\",s.depthStoreOp??=\"store\",s.depthClearValue??=1),a&&!e.stencilReadOnly&&(s.stencilLoadOp??=\"clear\",s.stencilStoreOp??=\"store\"),s}function OQ(e,t){let{rawEncoder:s,root:r}=e[ve],o={colorAttachments:(t.colorAttachments===void 0?[]:Array.isArray(t.colorAttachments)?t.colorAttachments:[t.colorAttachments]).map(a=>{if(a===null)return null;let i={...a,loadOp:a.loadOp??\"clear\",storeOp:a.storeOp??\"store\",view:a0(r,a.view)};return a.resolveTarget!==void 0&&(i.resolveTarget=a0(r,a.resolveTarget)),i})};return t.label!==void 0&&(o.label=t.label),t.depthStencilAttachment!==void 0&&(o.depthStencilAttachment=UQ(t.depthStencilAttachment,a0(r,t.depthStencilAttachment.view))),t.occlusionQuerySet!==void 0&&(o.occlusionQuerySet=z3(t.occlusionQuerySet)?r.unwrap(t.occlusionQuerySet):t.occlusionQuerySet),t.timestampWrites!==void 0&&(o.timestampWrites=rk(r,t.timestampWrites)),t.maxDrawCount!==void 0&&(o.maxDrawCount=t.maxDrawCount),new ak(r,s.beginRenderPass(o),e)}function GQ(e,t){return new IQ(e,e.device.createRenderBundleEncoder(t),void 0)}function FQ(e,t){let s=typeof t.executeBundles==\"function\"?new ak(e,t,void 0):new D3(e,t,void 0);return s[ve].state.rawAccessed=!0,s}var D3=class{[ve];resourceType=\"render-bundle-encoder\";#e;constructor(e,t,s){this.#e=e,this[ve]={rawPass:t,state:new yQ,owner:s,appliedVersion:void 0}}#t(e,t){let s=this[ve],r=s.state.currentPipeline;if(!r)throw new Error(\"Cannot draw without a call to pass.setPipeline\");Eb(this.#e,s,r,e,t)}setPipeline(e){XE(this[ve].state,e)}setBindGroup(e,t){$E(this[ve].state,e,t)}setVertexBuffer(e,t,s,r){let{state:o}=this[ve];o.vertexBuffers.set(e,{buffer:t,offset:s,size:r}),o.version++}setIndexBuffer(e,t,s,r){let{state:o}=this[ve];o.indexBuffer={buffer:e,indexFormat:t,offsetBytes:s,sizeBytes:r},o.version++}draw(e,t,s,r){this.#t(!1,o=>o.draw(e,t,s,r))}drawIndexed(e,t,s,r,o){this.#t(!0,a=>a.drawIndexed(e,t,s,r,o))}drawIndirect(e,t){let s=ol(e)?e:e.buffer,r=ku(e,t,16,\"drawIndirect\");this.#t(!1,o=>o.drawIndirect(s,r))}drawIndexedIndirect(e,t){let s=ol(e)?e:e.buffer,r=ku(e,t,20,\"drawIndexedIndirect\");this.#t(!0,o=>o.drawIndexedIndirect(s,r))}},IQ=class extends D3{resourceType=\"render-bundle-encoder\";finish(e){return this[ve].rawPass.finish(e)}},ak=class extends D3{resourceType=\"render-pass\";setViewport(e,t,s,r,o,a){this[ve].rawPass.setViewport(e,t,s,r,o,a)}setScissorRect(e,t,s,r){this[ve].rawPass.setScissorRect(e,t,s,r)}setBlendConstant(e){this[ve].rawPass.setBlendConstant(e)}setStencilReference(e){let{state:t}=this[ve];t.stencilReference=e,t.version++}beginOcclusionQuery(e){this[ve].rawPass.beginOcclusionQuery(e)}endOcclusionQuery(){this[ve].rawPass.endOcclusionQuery()}executeBundles(e){let t=this[ve];t.rawPass.executeBundles(e),t.appliedVersion=void 0}end(){this[ve].rawPass.end()}};function L3(e,t){return new ik(e,e.device.createCommandEncoder(t),!1)}function nk(e,t){return new ik(e,t,!0)}var ik=class{[ve];resourceType=\"command-encoder\";constructor(e,t,s){this[ve]={rawEncoder:t,root:e,adopted:s,beforeFinish:new Map,afterSubmit:new Map}}beginRenderPass(e){return OQ(this,e)}beginComputePass(e){return RQ(this,e)}#e(){let{rawEncoder:e,beforeFinish:t}=this[ve];for(let s of t.values())s(e);t.clear()}submit(){let{rawEncoder:e,root:t,afterSubmit:s}=this[ve];this.#e(),t.device.queue.submit([e.finish()]);for(let r of s.values())r();s.clear()}finish(e){let{rawEncoder:t,root:s,afterSubmit:r}=this[ve];return this.#e(),r.size>0&&rr.warnOnce(\"suspicious\",s,\"finishWithPendingWork\",\"Shader console.log output and performance callbacks do not fire for command buffers produced by encoder.finish(). Use encoder.submit() instead.\"),t.finish(e)}},lk=[\"f16\",\"clip_distances\",\"dual_source_blending\",\"subgroups\",\"primitive_index\"],ck={f16:\"shader-f16\",clip_distances:\"clip-distances\",dual_source_blending:\"dual-source-blending\",subgroups:\"subgroups\",primitive_index:\"primitive-index\"};function Bb(e,t){return e.type!==t.type?!1:ta(e)&&ta(t)?e.access===t.access&&e.addressSpace===t.addressSpace&&e.implicit===t.implicit&&Bb(e.inner,t.inner):io(e)&&io(t)?e.elementCount===t.elementCount&&Bb(e.elementType,t.elementType):_r(e)&&_r(t)?e===t:!0}var YQ=class{cache=new Map;get(e,t){let s=Fx(e);if(!s)return;if(!t&&s.ast.params.length>0)throw new Error(`Cannot resolve '${ct(e)}' directly, because it expects arguments. Either call it from another function, or wrap it in a shell`);let r=(t??[]).map((i,l)=>{if(i.value instanceof Ji){if(i.dataType===Ns)throw new jt(\"d.ref() created with primitive types must be stored in a variable before use\");return i.dataType}if(i.dataType===Ns)throw new Error(`Passed illegal value ${i.value} as the #${l} argument to ${ct(e)??\"<unnamed>\"}(...)\nShellless functions can only accept arguments representing WGSL resources: constructible WGSL types, d.refs, samplers or texture views.\nRemember, that arguments such as samplers, texture views, accessors, slots etc. should be dereferenced via '.$' first.`);let c=dn(i.dataType);return ta(c)&&c.implicit&&(c=c.inner),c}),o=this.cache.get(e);if(o){let i=o.find(l=>l.argTypes.length===r.length&&l.argTypes.every((c,d)=>Bb(c,r[d])));if(i)return i}else o=[],this.cache.set(e,o);let a=KK(r,e);return o.push(a),a}},WQ=class{[ve];constructor(e){this[ve]={strategy:e,takenGlobalIdentifiers:new Set([..._3,...f$]),shelllessRepo:new YQ,memoizedResolves:new WeakMap,memoizedLazy:new WeakMap}}};function op(e){let{names:t=\"strict\"}=e??{};return new WQ(t)}var qQ=new Set([\"bindGroupLayoutMap\",\"vertexLayoutMap\",\"indexBuffer\",\"stencilReference\",\"timestampWrites\",\"performanceCallback\"]);function dk(e){return Object.keys(e).filter(t=>!qQ.has(t)&&e[t]!==void 0)}var uk=class{#e;#t;measureResolve(e){let t=performance.mark(\"typegpu:resolution:start\"),s=e();return this.#e=performance.measure(\"typegpu:resolution\",{start:t.name}),this.#t=s.code.length,s}measureCompile(e){(async()=>{let t=performance.mark(\"typegpu:compile-start\");await e.queue.onSubmittedWorkDone();let s=performance.measure(\"typegpu:compiled\",{start:t.name});Ix?.record(\"resolution\",{resolveDuration:this.#e?.duration,compileDuration:s.duration,wgslSize:this.#t})})()}},pk=class{measureResolve(e){return e()}measureCompile(){}};function VQ(e,t,s){return new NQ(new $Q(e,t,s),{})}var NQ=class mk{[ve];[He];resourceType=\"compute-pipeline\";[Mo];constructor(t,s){this[He]={type:\"compute-pipeline\",device:t.root.device,raw:void 0,label:void 0},this[ve]={core:t,priors:s,root:t.root,materialize:()=>{let r=this[He];if(!r.raw){let o=t.unwrap();r.raw=o.pipeline,r.usedBindGroupLayouts=o.usedBindGroupLayouts,r.bindGroups=WE(o.usedBindGroupLayouts,o.catchall,s.bindGroupLayoutMap),r.timestampWrites=s.timestampWrites,r.performanceCallback=s.performanceCallback,r.nonTransferablePriors=dk(s)}return r.raw}},this[Mo]=t}[Ws](t){return t.resolve(this[ve].core)}toString(){return`computePipeline:${ct(this)??\"<unnamed>\"}`}#e(t){let{core:s,priors:r}=this[ve];return new mk(s,{...r,...t})}with(t,s){let r=this[ve];if(tk(t))return this.#e({pass:t,encoder:void 0});if(R3(t))return this.#e({pass:void 0,encoder:t});if(kQ(t))return this.#e({pass:DQ(r.root,t),encoder:void 0});if(sk(t))return this.#e({pass:void 0,encoder:nk(r.root,t)});if(ic(t)||Uh(t)){let[o,a]=ic(t)?[t.layout,t]:[t,s];return this.#e({bindGroupLayoutMap:new Map([...r.priors.bindGroupLayoutMap??[],[o,a]])})}throw new Error(\"Unsupported value passed into .with()\")}withPerformanceCallback(t){let s=this[ve];if(s.priors.timestampWrites)return this.#e({performanceCallback:t});let r=s.core.performanceCallbackQuerySet;return r?this.#e(VE(s.priors,t,r)):(rr.warn(\"webgpu-feature-missing\",\"Performance callback cannot be used because the timestamp-query feature is not enabled on the root.\"),this)}withTimestampWrites(t){let s=this[ve];return this.#e(NE(s.priors,t,s.root))}dispatchWorkgroups(t,s,r){this.#t(o=>o.dispatchWorkgroups(t,s,r))}dispatchWorkgroupsIndirect(t,s){let r=ol(t)?t:t.buffer,o=ku(t,s,12,\"dispatchWorkgroupsIndirect\");this.#t(a=>a.dispatchWorkgroupsIndirect(r,o))}initAsync(){return this[ve].core.initAsync()}initSync(){this[ve].core.initSync()}#t(t){let{core:s,priors:r,root:o}=this[ve];if(r.pass){kb(o,r.pass[ve],this,t);return}let a=r.encoder??L3(o),i=a.beginComputePass({label:ct(s)??\"<unnamed>\",timestampWrites:r.timestampWrites});kb(o,i[ve],this,t,!0),i.end(),ZE(a,s,s.unwrap().logResources,r)}$name(t){return es(this,t),this}},$Q=class _k{[ve]=!0;root;#e;#t;#s;#r;#o;#a;constructor(t,s,r){this.root=t,this.#r=s,this.#o=r,this.#e=Ix?.enabled?new uk:new pk}static precompiled(t,s){let r=new _k(t,[],void 0);return r.#s=s,r}[Ws](t){let s=this.#o;return s?t.withSlots(this.#r,()=>(t.resolve(s.compute),Je(\"\",zr,\"runtime\"))):Je(\"\",zr,\"runtime\")}toString(){return\"computePipelineCore\"}get performanceCallbackQuerySet(){if(this.root.enabledFeatures.has(\"timestamp-query\"))return this.#a??=(globalThis.__TYPEGPU_AUTONAME__??(t=>t))(this.root.createQuerySet(\"timestamp\",2),\"performanceCallbackQuerySet\")}initAsync(){if(this.#s!==void 0)return Promise.resolve();if(this.#t===void 0){let t=this.root.device,{resolutionResult:s,module:r}=this.resolveAndCreateShaderModule(),{usedBindGroupLayouts:o,catchall:a,logResources:i}=s;this.#t=t.createComputePipelineAsync({label:ct(this)??\"<unnamed>\",layout:t.createPipelineLayout({label:`${ct(this)??\"<unnamed>\"} - Pipeline Layout`,bindGroupLayouts:o.map(l=>this.root.unwrap(l))}),compute:{module:r}}).then(l=>{this.#s={pipeline:l,usedBindGroupLayouts:o,catchall:a,logResources:i},this.#e.measureCompile(t)}).finally(()=>{this.#t=void 0})}return this.#t}initSync(){if(this.#s!==void 0)return;if(this.#t!==void 0)throw new Error(\"'pipeline.initAsync()' was called and is not yet resolved.\");let t=this.root.device,{resolutionResult:s,module:r}=this.resolveAndCreateShaderModule(),{usedBindGroupLayouts:o,catchall:a,logResources:i}=s;this.#s={pipeline:(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(t.createComputePipeline({label:ct(this)??\"<unnamed>\",layout:t.createPipelineLayout({label:`${ct(this)??\"<unnamed>\"} - Pipeline Layout`,bindGroupLayouts:o.map(l=>this.root.unwrap(l))}),compute:{module:r}}),\"pipeline\"),usedBindGroupLayouts:o,catchall:a,logResources:i},this.#e.measureCompile(t)}unwrap(){return this.initSync(),this.#s}resolveAndCreateShaderModule(){let t=this.root.device,s=lk.filter(c=>this.root.enabledFeatures.has(ck[c])),r=op({names:this.root.nameRegistrySetting}),o=this.#e.measureResolve(()=>Gh(this,{namespace:r,minify:this.root.minify,enableExtensions:s,shaderGenerator:this.root.shaderGeneratorClass?new this.root.shaderGeneratorClass:void 0,root:this.root})),{code:a,usedBindGroupLayouts:i,catchall:l}=o;return l!==void 0&&i[l[0]]?.$name(`${ct(this)??\"<unnamed>\"} - Automatic Bind Group & Layout`),gE(i,t.limits),{resolutionResult:o,module:t.createShaderModule({label:`${ct(this)??\"<unnamed>\"} - Shader`,code:a})}}},XQ={$vertexIndex:Qo.vertexIndex,$instanceIndex:Qo.instanceIndex},HQ={$clipDistances:Qo.clipDistances,$position:Qo.position},jQ={$position:Qo.position,$frontFacing:Qo.frontFacing,$primitiveIndex:Qo.primitiveIndex,$sampleIndex:Qo.sampleIndex,$sampleMask:Qo.sampleMask,$subgroupInvocationId:Qo.subgroupInvocationId,$subgroupSize:Qo.subgroupSize},KQ={$fragDepth:Qo.fragDepth,$sampleMask:Qo.sampleMask},U3=class{#e;autoIn;autoOut;constructor(e,t,s){ct(e)||es(e,\"fragmentFn\"),this.#e=Ed(e,\"fragment\"),this.autoIn=new ti({...jQ,...t},void 0,s),es(this.autoIn,\"FragmentIn\"),this.autoOut=new ti(KQ,qt),es(this.autoOut,\"FragmentOut\")}toString(){return\"autoFragmentFn\"}[Ws](e){return e.withSlots([[rp,\"fragment\"]],()=>this.#e.resolve(e,[this.autoIn],this.autoOut))}};U3.prototype[ve]=!0;U3.prototype.resourceType=\"auto-fragment-fn\";var O3=class{#e;autoIn;autoOut;constructor(e,t,s){ct(e)||es(e,\"vertexFn\"),this.#e=Ed(e,\"vertex\"),this.autoIn=new ti({...XQ,...t},void 0,s),es(this.autoIn,\"VertexIn\"),this.autoOut=new ti(HQ,void 0),es(this.autoOut,\"VertexOut\")}toString(){return\"autoVertexFn\"}[Ws](e){return e.withSlots([[rp,\"vertex\"]],()=>this.#e.resolve(e,[this.autoIn],this.autoOut))}};O3.prototype[ve]=!0;O3.prototype.resourceType=\"auto-vertex-fn\";function fk(e,t=\"vertex\"){return new QQ(e,t)}function vk(e){return e?.resourceType===\"vertex-layout\"}var zb=Symbol(\"defaultAttribEntry\");function B1(e,t,s,r,o){if(gl(t)||vc(t)){let a=sc(t);return a!==void 0&&(r[o??zb]=a),B1(e,t.inner,Co(s,wn(t)),r)}if(_r(t)){let a=s,i=t.propTypes;return Object.fromEntries(Object.entries(i).map(([l,c])=>{a=Co(a,xr(c));let d=[l,B1(e,c,a,r,l)];return a+=ds(c),d}))}if(ki(t)){let a=s,i=t.propTypes;return Object.fromEntries(Object.entries(i).map(([l,c])=>{a=Co(a,wn(c));let d=[l,B1(e,c,a,r,l)];return a+=ds(c),d}))}if(\"type\"in t&&typeof t.type==\"string\"){if(HC.includes(t.type))return{_layout:e,format:t.type,offset:s};let a=pN[t.type];if(a)return{_layout:e,format:a,offset:s}}throw new Error(`Unsupported data used in vertex layout: ${String(t)}`)}var QQ=class{[ve]=!0;[He];resourceType=\"vertex-layout\";stride;attrib;schemaForCount;#e={};constructor(e,t){this.schemaForCount=e;let s=e(0);this[He]={type:\"vertex-layout\",schema:s,stepMode:t,label:void 0},this.stride=Co(ds(s.elementType),xr(s)),this.attrib=B1(this,s.elementType,0,this.#e)}get stepMode(){return this[He].stepMode}get vertexLayout(){if(this.#e[zb]!==void 0){if(typeof this.attrib.format!=\"string\"||typeof this.attrib.offset!=\"number\")throw new Error(\"Single attribute vertex layouts must have a format and offset.\");return{arrayStride:this.stride,stepMode:this.stepMode,attributes:[{format:this.attrib.format,offset:this.attrib.offset,shaderLocation:this.#e[zb]}]}}if(!Object.keys(this.attrib).every(e=>this.#e[e]!==void 0))throw new Error(\"All attributes must have custom locations in order to unwrap a vertex layout.\");return{arrayStride:this.stride,stepMode:this.stepMode,attributes:Object.entries(this.attrib).map(([e,t])=>({format:t.format,offset:t.offset,shaderLocation:this.#e[e]}))}}$name(e){return es(this,e),this}};function ZQ(e){return!!e?.view}function JQ(e,t){if(hh(e)||wi(e))return[];if(_r(e)){let s=[];for(let r of Object.keys(e.propTypes)){let o=e.propTypes[r];if(wi(o))continue;let a=t[r];if(!a)throw new Error(`A color attachment by the name of '${r}' was not provided to the shader.`);s.push(a)}return s}if(!ZQ(t))throw new Error(\"Expected a single color attachment, not a record.\");return[t]}function eZ(e,t){let s;if(hh(e)||wi(e))return[null];if(_r(e)){let o=[];for(let a of Object.keys(e.propTypes)){let i=e.propTypes[a];if(wi(i))continue;let l=t[a];o.push({...l,format:l?.format??(s??=navigator.gpu.getPreferredCanvasFormat())})}return o}let r=t;return[{...r,format:r?.format??(s??=navigator.gpu.getPreferredCanvasFormat())}]}function tZ(e){return new sZ(new rZ(e),{})}var sZ=class hk{[ve];[He];resourceType=\"render-pipeline\";[Mo];constructor(t,s){this[He]={type:\"render-pipeline\",device:t.options.root.device,raw:void 0,label:void 0},this[ve]={core:t,priors:s,root:t.options.root,materialize:()=>{let r=this[He];if(!r.raw){let o=t.unwrap();r.raw=o.pipeline,r.usedBindGroupLayouts=o.usedBindGroupLayouts,r.usedVertexLayouts=o.usedVertexLayouts,r.fragmentOut=o.fragmentOut,r.bindGroups=WE(o.usedBindGroupLayouts,o.catchall,s.bindGroupLayoutMap),r.vertexBuffers=sQ(o.usedVertexLayouts,s.vertexLayoutMap),r.indexBuffer=s.indexBuffer,r.stencilReference=s.stencilReference,r.timestampWrites=s.timestampWrites,r.performanceCallback=s.performanceCallback,r.nonTransferablePriors=dk(s)}return r.raw}},this[Mo]=t}[Ws](t){return t.resolve(this[ve].core)}toString(){return`renderPipeline:${ct(this)??\"<unnamed>\"}`}$name(t){return es(this,t),this}#e(t){let{core:s,priors:r}=this[ve];return new hk(s,{...r,...t})}with(t,s){let r=this[ve];if(ek(t))return this.#e({pass:t,encoder:void 0});if(R3(t))return this.#e({pass:void 0,encoder:t});if(BQ(t)||zQ(t))return this.#e({pass:FQ(r.root,t),encoder:void 0});if(sk(t))return this.#e({pass:void 0,encoder:nk(r.root,t)});if(ic(t)||Uh(t)){let[o,a]=ic(t)?[t.layout,t]:[t,s];return this.#e({bindGroupLayoutMap:new Map([...r.priors.bindGroupLayoutMap??[],[o,a]])})}if(vk(t))return this.#e({vertexLayoutMap:new Map([...r.priors.vertexLayoutMap??[],[t,s]])});throw new Error(\"Unsupported value passed into .with()\")}withPerformanceCallback(t){let s=this[ve];if(s.priors.timestampWrites)return this.#e({performanceCallback:t});let r=s.core.performanceCallbackQuerySet;return r?this.#e(VE(s.priors,t,r)):(rr.warn(\"webgpu-feature-missing\",\"Performance callback cannot be used because the timestamp-query feature is not enabled on the root.\"),this)}withTimestampWrites(t){let s=this[ve];return this.#e(NE(s.priors,t,s.root))}withColorAttachment(t){return this.#e({colorAttachment:t})}withDepthStencilAttachment(t){return this.#e({depthStencilAttachment:t})}withStencilReference(t){return this.#e({stencilReference:t})}withIndexBuffer(t,s,r,o){if(ol(t)){if(typeof s!=\"string\")throw new Error(\"If a GPUBuffer is passed, indexFormat must be provided.\");return this.#e({indexBuffer:{buffer:t,indexFormat:s,offsetBytes:r,sizeBytes:o}})}let a={u32:\"uint32\",u16:\"uint16\"},i=t.dataType.elementType;return this.#e({indexBuffer:{buffer:t,indexFormat:a[i.type],offsetBytes:s!==void 0?s*ds(i):void 0,sizeBytes:o!==void 0?o*ds(i):void 0}})}initAsync(){return this[ve].core.initAsync()}initSync(){this[ve].core.initSync()}get hasIndexBuffer(){return this[ve].priors.indexBuffer!==void 0}#t(){let{core:t,priors:s}=this[ve],{fragmentOut:r}=t.unwrap();return{label:ct(t)??\"<unnamed>\",colorAttachments:r?JQ(r,s.colorAttachment??{}):[],depthStencilAttachment:s.depthStencilAttachment,timestampWrites:s.timestampWrites}}#s(t,s){let{core:r,priors:o,root:a}=this[ve];if(o.pass){Eb(a,o.pass[ve],this,t,s);return}t&&KE(o.indexBuffer);let i=o.encoder??L3(a),l=i.beginRenderPass(this.#t());Eb(a,l[ve],this,t,s,!0),l.end(),ZE(i,r,r.unwrap().logResources,o)}draw(t,s,r,o){this.#s(!1,a=>a.draw(t,s,r,o))}drawIndexed(t,s,r,o,a){this.#s(!0,i=>i.drawIndexed(t,s,r,o,a))}drawIndirect(t,s){let r=ol(t)?t:t.buffer,o=ku(t,s,16,\"drawIndirect\");this.#s(!1,a=>a.drawIndirect(r,o))}drawIndexedIndirect(t,s){let r=ol(t)?t:t.buffer,o=ku(t,s,20,\"drawIndexedIndirect\");this.#s(!0,a=>a.drawIndexedIndirect(r,o))}},rZ=class gk{[ve]=!0;options;#e;#t;#s;#r;#o;#a;constructor(t){this.options=t,this.#e=Ix?.enabled?new uk:new pk}static precompiled(t,s){let r=new gk({root:t,slotBindings:[],descriptor:void 0});return r.#s=s,r}[Ws](t){let{slotBindings:s}=this.options,{vertex:r,fragment:o,attribs:a={}}=this.options.descriptor??{};if(!r)return Je(\"\",zr,\"runtime\");this.#r=void 0,this.#o=void 0;let i=oZ(r?.shell?.out,o?.shell?.in,ct(r)??\"<unnamed>\",ct(o)??\"<unnamed>\");return t.withVaryingLocations(i,()=>t.withSlots(s,()=>{let l;if(typeof r==\"function\"){let c=new O3(r,Object.fromEntries(Object.entries(a).map(([d,u])=>[d,dl[u.format]])),i);t.resolve(c),this.#r=c.autoIn.completeStruct.propTypes,l=c.autoOut.completeStruct}else l=t.resolve(r).dataType;if(o)if(typeof o==\"function\"){let c=Object.fromEntries(Object.entries(l.propTypes).filter(([,d])=>!wi(d)));this.#o=t.resolve(new U3(o,c,i)).dataType}else t.resolve(o);return Je(\"\",zr,\"runtime\")}))}toString(){return\"renderPipelineCore\"}get performanceCallbackQuerySet(){if(this.options.root.enabledFeatures.has(\"timestamp-query\"))return this.#a??=(globalThis.__TYPEGPU_AUTONAME__??(t=>t))(this.options.root.createQuerySet(\"timestamp\",2),\"performanceCallbackQuerySet\")}initAsync(){if(this.#s!==void 0)return Promise.resolve();if(this.#t===void 0){let t=this.options.root.device,{resolutionResult:s,descriptor:r,connectedAttribs:o,fragmentOut:a}=this.resolveAndCreateShaderModule(),{usedBindGroupLayouts:i,catchall:l,logResources:c}=s;this.#t=t.createRenderPipelineAsync(r).then(d=>{this.#s={pipeline:d,usedBindGroupLayouts:i,catchall:l,logResources:c,usedVertexLayouts:o.usedVertexLayouts,fragmentOut:a},this.#e.measureCompile(t)}).finally(()=>{this.#t=void 0})}return this.#t}initSync(){if(this.#s!==void 0)return;if(this.#t!==void 0)throw new Error(\"'pipeline.initAsync()' was called and is not yet resolved.\");let t=this.options.root.device,{resolutionResult:s,descriptor:r,connectedAttribs:o,fragmentOut:a}=this.resolveAndCreateShaderModule(),{usedBindGroupLayouts:i,catchall:l,logResources:c}=s;this.#s={pipeline:(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(t.createRenderPipeline(r),\"pipeline\"),usedBindGroupLayouts:i,catchall:l,logResources:c,usedVertexLayouts:o.usedVertexLayouts,fragmentOut:a},this.#e.measureCompile(t)}unwrap(){return this.initSync(),this.#s}resolveAndCreateShaderModule(){let{root:t,descriptor:s}=this.options;if(!s)throw new Error(\"Precompiled pipelines are never resolved again.\");let r=t.device,o=lk.filter(C=>t.enabledFeatures.has(ck[C])),a=op({names:t.nameRegistrySetting}),i=this.#e.measureResolve(()=>Gh(this,{namespace:a,minify:t.minify,enableExtensions:o,shaderGenerator:t.shaderGeneratorClass?new t.shaderGeneratorClass:void 0,root:t})),{code:l,usedBindGroupLayouts:c,catchall:d}=i;d!==void 0&&c[d[0]]?.$name(`${ct(this)??\"<unnamed>\"} - Automatic Bind Group & Layout`),gE(c,r.limits);let u=r.createShaderModule({label:`${ct(this)??\"<unnamed>\"} - Shader`,code:l}),{vertex:p,fragment:_,attribs:f={},targets:h}=s,g=Tj(p?.shell?.in??this.#r??{},f),y=_?.shell?.returnType??this.#o,b=y?eZ(y,h):[null],x={layout:r.createPipelineLayout({label:`${ct(this)??\"<unnamed>\"} - Pipeline Layout`,bindGroupLayouts:c.map(C=>t.unwrap(C))}),vertex:{module:u,buffers:g.bufferDefinitions}},P=ct(this);return P!==void 0&&(x.label=P),s.fragment&&(x.fragment={module:u,targets:b}),s.primitive&&(Td(s.primitive.stripIndexFormat)?x.primitive={...s.primitive,stripIndexFormat:{u32:\"uint32\",u16:\"uint16\"}[s.primitive.stripIndexFormat.type]}:x.primitive=s.primitive),s.depthStencil&&(x.depthStencil=s.depthStencil),s.multisample&&(x.multisample=s.multisample),{resolutionResult:i,descriptor:x,connectedAttribs:g,fragmentOut:y}}};function oZ(e={},t={},s,r){let o={},a=new Set;function i(c,d){o[c]=d,a.add(d)}for(let[c,d]of Object.entries(e)){let u=sc(d);u!==void 0&&i(c,u)}for(let[c,d]of Object.entries(t)){let u=sc(d);u!==void 0&&(o[c]===void 0?i(c,u):o[c]!==u&&rr.warn(\"locations-mismatched\",`Mismatched location between vertexFn (${s}) output (${o[c]}) and fragmentFn (${r}) input (${u}) for the key \"${c}\", using the location set on vertex output.`))}let l=0;for(let c of Object.keys(e??{}))if(!(wi(e[c])||o[c]!==void 0)){for(;a.has(l);)l++;i(c,l)}return o}var Y7=class{#e=new WeakMap;#t;constructor(e){this.#t=e}getOrMake(e,...t){if(this.#e.has(e))return this.#e.get(e);let s=this.#t(e,...t);return this.#e.set(e,s),s}};function G3(e){let t={argTypes:Object.values(e.in??{}),returnType:zr,workgroupSize:e.workgroupSize,entryPoint:\"compute\"},s=QM(e.in??{});return Object.assign((o,...a)=>aZ(t,e.workgroupSize,Rh(o,...a),s),t)}function aZ(e,t,s,r){let o=Ed(s,\"compute\",t);return{shell:e,$uses(a){return o.setExternals(\"userProvided\",a),this},[ve]:!0,[Mo]:o,$name(a){return es(this,a),this},[Ws](a){return a.withSlots([[rp,\"compute\"]],()=>o.resolve(a,[],e.returnType,r))},toString(){return`computeFn:${ct(o)??\"<unnamed>\"}`}}}function nZ(e){if(e.includes(0))throw new Error(\"Size and workgroupSize cannot contain zeroes.\");return Ps(e[0]??1,e[1]??1,e[2]??1)}var iZ=[Ps(1,1,1),Ps(256,1,1),Ps(16,16,1),Ps(8,8,4)],lZ=class z1{resourceType=\"guarded-compute-pipeline\";[He];#e;#t;constructor(t,s,r,o){this.#e=t,this.#t=Ps(),this[He]={type:\"guarded-compute-pipeline\",device:t.device,pipeline:s,sizeUniform:r,workgroupSize:o,label:void 0}}with(t){if(!ic(t))throw new Error(\"Guarded pipelines only accept bind groups in .with(). To record into passes or encoders, use a regular compute pipeline.\");return new z1(this.#e,this[He].pipeline.with(t),this[He].sizeUniform,this[He].workgroupSize)}withPerformanceCallback(t){return new z1(this.#e,this[He].pipeline.withPerformanceCallback(t),this[He].sizeUniform,this[He].workgroupSize)}withTimestampWrites(t){return new z1(this.#e,this[He].pipeline.withTimestampWrites(t),this[He].sizeUniform,this[He].workgroupSize)}dispatchThreads(...t){let s=nZ(t),r=nl(Zs(s).div(Zs(this[He].workgroupSize)));vj(s,this.#t)||(this.#t=s,this[He].sizeUniform.write(s)),this[He].pipeline.dispatchWorkgroups(r.x,r.y,r.z)}initAsync(){return this[He].pipeline.initAsync()}initSync(){this[He].pipeline.initSync()}get pipeline(){return this[He].pipeline}get sizeUniform(){return this[He].sizeUniform}[ve]=!0;get[Mo](){return this[He].pipeline}$name(t){return es(this,t),this}},cZ=class Rb{#e;#t;constructor(t,s){this.#e=t,this.#t=s}with(t,s){return new Rb(this.#e,[...this.#t,[Qu(t)||Zu(t)?t.slot:t,s]])}createComputePipeline(t){return VQ(this.#e(),this.#t,t)}createRenderPipeline(t){return tZ({root:this.#e(),slotBindings:this.#t,descriptor:t})}createGuardedComputePipeline(t){let s=this.#e();if(t.length>=4)throw new Error(\"Guarded compute callback only supports up to three dimensions.\");let r=iZ[t.length],o=nr([M,M,M])(t);ct(o)===void 0&&o.$name(\"wrappedCallback\");let a=(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(s.createUniform(Ps),\"sizeUniform\"),i=(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(G3({workgroupSize:r,in:{id:Qo.globalInvocationId}})`{\n  if (any(in.id >= sizeUniform)) {\n    return;\n  }\n  wrappedCallback(in.id.x, in.id.y, in.id.z);\n}`.$uses({sizeUniform:a,wrappedCallback:o}),\"mainCompute\");return new lZ(s,this.createComputePipeline({compute:i}),a,r)}pipe(t){let s=t(new yE([]));return new Rb(this.#e,[...this.#t,...s.bindings])}},yk=class extends cZ{\"~unstable\";resourceType=\"root\";[He];device;nameRegistrySetting;shaderGeneratorClass;#e=new Y7(e=>e.unwrap(this));#t=new Y7(e=>e.unwrap(this));#s;[ve];constructor(e,t,s,r,o,a){super(()=>this,[]),this.device=e,this.nameRegistrySetting=t,this.#s=r,this.shaderGeneratorClass=a,this[\"~unstable\"]=this,this[He]={type:\"root\",device:e,nameRegistrySetting:t,logOptions:o,minify:s,nonTransferablePriors:a?[\"shaderGeneratorClass\"]:void 0,label:void 0},this[ve]={logOptions:o}}configureContext(e){let t=e.canvas.getContext(\"webgpu\");if(!t)throw new Error(\"Unable to initialize 'webgpu' context on the provided canvas.\");return t.configure({...e,device:this.device,format:e.format??navigator.gpu.getPreferredCanvasFormat()}),t}get enabledFeatures(){return new Set(this.device.features)}get minify(){return this[He].minify}createBuffer(e,t){return Qf(this,e,t)}createUniform(e,t){return new ld(\"uniform\",Qf(this,e,t).$usage(\"uniform\"))}createMutable(e,t){return new ld(\"mutable\",Qf(this,e,t).$usage(\"storage\"))}createReadonly(e,t){return new ld(\"readonly\",Qf(this,e,t).$usage(\"storage\"))}createQuerySet(e,t,s){return fQ(this,e,t,s)}createBindGroup(e,t){return new EE(this,e,t)}destroy(){BK(this.device),this.#s&&this.device.destroy()}createTexture(e){return LK(e,this)}createSampler(e){return dK(e,this)}createComparisonSampler(e){return uK(e,this)}unwrap(e){if(R3(e))return e[ve].rawEncoder;if(ek(e)||tk(e))return e[ve].state.rawAccessed=!0,e[ve].rawPass;if(Uh(e))return this.#e.getOrMake(e);if(ic(e))return this.#t.getOrMake(e);if(__(e))return e.buffer.buffer;if(Eu(e)){if(!e[ve].unwrap)throw new Error(\"Cannot unwrap laid-out texture view as it has no underlying resource.\");return e[ve].unwrap()}if(vk(e))return e.vertexLayout;let t=e[ve];if(t?.materialize)return t.materialize();throw k3(e)||B3(e)?new Error(\"Cannot unwrap laid-out sampler.\"):new Error(`Unknown resource type: ${pn(e)}`)}createCommandEncoder(e){return L3(this,e)}createRenderBundleEncoder(e){return GQ(this,e)}};async function dZ(e){let{adapter:t,device:s,unstable_names:r=\"strict\",unstable_minify:o=!1,unstable_logOptions:a,unstable_shaderGeneratorClass:i}=e??{},{optionalFeatures:l,...c}=s??{};if(!navigator.gpu)throw new Error(\"WebGPU is not supported by this browser.\");let d=await navigator.gpu.requestAdapter(t);if(!d)throw new Error(\"Could not find a compatible GPU\");let u=[];for(let p of c.requiredFeatures??[]){if(!d.features.has(p))throw new Error(`Requested feature \"${p}\" is not supported by the adapter.`);u.push(p)}for(let p of l??[])d.features.has(p)?u.push(p):rr.warn(\"webgpu-feature-missing\",`Optional feature \"${p}\" is not supported by the adapter.`);return new yk(await d.requestDevice({...c,requiredFeatures:u}),r,o,!0,a??{},i)}function uZ(e){let{device:t,unstable_names:s=\"strict\",unstable_minify:r=!1,unstable_logOptions:o,unstable_shaderGeneratorClass:a}=e??{};return new yk(t,s,r,!1,o??{},a)}function bk(e,t){return new pZ(e,t)}function xk(e,t){return new mZ(e,t)}function F3(e){let t=_d(),s=K1(t.unwrap(e.slot));for(;typeof s==\"function\"&&!pb(s)&&!N1(s)&&!Pu(s);)s=s(),n_(s)&&(s=s.value);let r=bh(s);if(r)return r;if(N1(s))return s[mo].call(t,[]);if(pb(s)||Pu(s)){let o=t.resolve(s);return t.withResetIndentLevel(()=>Je(`${o.value}()`,e.schema,\"runtime\",o.possibleSideEffects))}t.pushMode(new Ju);try{return Je(rc(e.schema,s),e.schema,\"constant\",!1)}finally{t.popMode(\"normal\")}}var Ak=class Db{[Mo];[He];slot;static#e=void(Db.prototype[ve]=!0,Al(Db.prototype,{asString(){return`${this.resourceType}:${ct(this)??\"<unnamed>\"}`},resolve(t){return t.resolveSnippet(F3(this))}}));constructor(t,s,r=void 0){this[He]={type:t,schema:o_(s)?s:s(0),defaultValue:r,label:void 0},this.slot=v_(r),this[Mo]=this.slot}get schema(){return this[He].schema}get defaultValue(){return this[He].defaultValue}$name(t){return es(this,t),this.defaultValue&&typeof this.defaultValue==\"function\"&&!ct(this.defaultValue)&&es(this.defaultValue,t),this}},pZ=class Lb extends Ak{static#e=void(Lb.prototype.resourceType=\"accessor\",Bi(Lb.prototype,{codegenMode:{get(){return F3(this)}},normalMode:{get(){throw new Error(\"`tgpu.accessor` relies on GPU resources and cannot be accessed outside of a compute dispatch or draw call. Use `tgpu.slot` for non-WGSL values instead.\")}}}));constructor(t,s=void 0){super(\"accessor\",t,s)}},mZ=class Ub extends Ak{static#e=void(Ub.prototype.resourceType=\"mutable-accessor\",Bi(Ub.prototype,{codegenMode:{get(){return F3(this)}},normalMode:{get(){throw new Error(\"`tgpu.mutableAccessor` relies on GPU resources and cannot be accessed outside of a compute dispatch or draw call. Use `tgpu.slot` for non-WGSL values instead.\")}}}));constructor(t,s=void 0){super(\"mutable-accessor\",t,s)}};function Ob(e,t){return Array.isArray(e)?vZ(e,t):fZ(e)}function _Z(e,t){return Array.isArray(e)?Ob(e,t).code:Ob(e).code}function fZ(e){let{template:t,externals:s,unstable_shaderGenerator:r,names:o=\"strict\",unstable_minify:a,config:i,enableExtensions:l}=e;t||rr.warn(\"deprecated\",\"Calling resolve with an empty template is deprecated and will soon return an empty string. Consider using the 'tgpu.resolve(resolvableArray, options)' API instead.\");let c={[ve]:!0,[Ws](u){return Je(zh(u,s,t??\"\"),zr,\"runtime\")},toString:()=>\"<root>\"},d=wk(Object.values(s));return Gh(c,{namespace:typeof o==\"string\"?op({names:o}):o,minify:a??d?.minify??!1,enableExtensions:l,shaderGenerator:r,config:i,root:d})}function vZ(e,t){let{unstable_shaderGenerator:s,names:r=\"strict\",unstable_minify:o,config:a,enableExtensions:i}=t??{},l={[ve]:!0,[Ws](d){for(let u of e)if(Uh(u))for(let p of Object.values(u[ve]))d.resolve(p);else d.resolve(u);return Je(\"\",zr,\"runtime\")},toString:()=>\"<root>\"},c=wk(e);return Gh(l,{namespace:typeof r==\"string\"?op({names:r}):r,minify:o??c?.minify??!1,enableExtensions:i,shaderGenerator:s,config:a,root:c})}function wk(e){let t=new Map;for(let s of e){let r=Gb(s);if(r){let o=t.get(r)??new Set;t.set(r,o),o.add(s)}}if(t.size>1){let s=[...t.values()].map((r,o)=>`root ${o+1}: ${[...r].map(a=>ct(a)??\"<unnamed>\").join(\", \")}`).join(\"; \");throw new Error(`Found resources originating from different roots in a single resolve (${s}).`)}return[...t.keys()][0]}function Gb(e){if(MQ(e)||Fm(e)||Vm(e)||k3(e)||B3(e))return e[ve].root;if(__(e))return Gb(e.buffer);if(Eu(e))return Gb(e?.[He]?.texture)}function Tk(e){if(_d())throw new Error(\"Cannot create tgpu.lazy objects during shader resolution.\");return new hZ(e,void 0)}var hZ=class R1{[ve];[ya];static#e=void(R1.prototype.resourceType=\"lazy\",Bi(Al(R1.prototype,{asString:()=>\"lazy\",resolve(t){throw new Error(\"Unreachable, is never resolved directly\")}}),{codegenMode:{get(){return this.#t()}},normalMode:{get(){return this.#t()}}}));constructor(t,s){this[ve]={compute:t},this[ya]=s}get[Ka](){let t=_d();if(!t)throw new Error(\"Cannot access tgpu.lazy's value outside of resolution.\");return K1(t.unwrap(this))}get $(){return this[Ka]}#t(){let t=_d();if(!t)throw new Error(\"Cannot access tgpu.lazy's value outside of resolution.\");return K1(t.unwrap(this))}with(t,s){return new R1(this[ve].compute.bind(this),{inner:this[ya]?.inner??this,pairs:[...this[ya]?.pairs??[],[Qu(t)||Zu(t)?t.slot:t,s]]})}};function Sk(e){let t={in:e.in,out:e.out,returnType:p_(e.out),entryPoint:\"fragment\"};return Object.assign((r,...o)=>gZ(t,Rh(r,...o)),t)}function gZ(e,t){let s=Ed(t,\"fragment\"),r=e.returnType;return typeof t==\"string\"&&eE(t,r,s),{shell:e,outputType:r,$uses(o){return s.setExternals(\"userProvided\",o),this},[ve]:!0,[Mo]:s,$name(o){return es(this,o),Su(r)&&r.$name(`${o}_Output`),this},[Ws](o){let a=QM(e.in??{},o.varyingLocations??{});return a.dataSchema&&Su(a.dataSchema)&&a.dataSchema.$name(`${ct(this)??\"\"}_Input`),typeof t==\"string\"&&s.setExternals(\"out\",{Out:r}),o.withSlots([[rp,\"fragment\"]],()=>s.resolve(o,[],e.returnType,a))},toString(){return`fragmentFn:${ct(s)??\"<unnamed>\"}`}}}function Fh(e){if(Object.keys(e.out).length===0)throw new Error(\"A vertexFn output cannot be empty since it must include the 'position' builtin.\");let t={in:e.in,out:e.out,argTypes:e.in&&Object.keys(e.in).length!==0?[p_(e.in)]:[],entryPoint:\"vertex\"};return Object.assign((r,...o)=>yZ(t,Rh(r,...o)),t)}function yZ(e,t){let s=Ed(t,\"vertex\"),r=jX(e.in??{});return{shell:e,$uses(o){return s.setExternals(\"userProvided\",o),this},[ve]:!0,[Mo]:s,$name(o){return es(this,o),this},[Ws](o){let a=p_(e.out,o.varyingLocations).$name(`${ct(this)??\"\"}_Output`);return typeof t==\"string\"&&s.setExternals(\"out\",{Out:a}),o.withSlots([[rp,\"vertex\"]],()=>s.resolve(o,[],a,r))},toString(){return`vertexFn:${ct(s)??\"<unnamed>\"}`}}}function bZ(e){return new xZ(e)}var xZ=class{[ve]=!0;#e;#t;constructor(e){this.#t=e}$uses(e){if(this.#e!==void 0)throw new Error(\"Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.\");return this.#e=e,this}[Ws](e){let t=zh(e,this.#e??{},this.#t);return e.addDeclaration(t),Je(\"\",zr,\"constant\")}toString(){return`declare: ${this.#t}`}};function AZ(e,t,s=\"runtime\",r=!0){return new wZ(e,t,s,r)}var wZ=class Fb{dataType;origin;possibleSideEffects;#e;#t;static#s=void(Fb.prototype[ve]=!0,Bi(Al(Fb.prototype,{asString(){return`raw(${String(this.dataType)}): \"${this.#e}\"`},resolve(t){return Je(zh(t,this.#t??{},this.#e),this.dataType,this.origin,this.possibleSideEffects)}}),{codegenMode:{getBaseSnippet(t){return Je(t,this.dataType,this.origin,this.possibleSideEffects)}},normalMode:{get(){throw new Error(\"Raw code snippets can only be used on the GPU.\")}}}));constructor(t,s,r,o){this.dataType=s,this.origin=r,this.possibleSideEffects=o,this.#e=t}$uses(t){if(this.#t!==void 0)throw new Error(\"Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.\");return this.#t=t,this}};function TZ(e){let t=_d()??new YE({minify:!1,namespace:op()}),s=[1,1,1],r=[1,1,1],o=[s[0]*r[0],s[1]*r[1],s[2]*r[2]],a=new Map,i=Array.from({length:s[0]},()=>Array.from({length:s[1]},()=>Array.from({length:s[2]},()=>new Map))),l=Array.from({length:o[0]},()=>Array.from({length:o[1]},()=>Array.from({length:o[2]},()=>new Map))),c=Array.from({length:o[0]},(d,u)=>Array.from({length:o[1]},(p,_)=>Array.from({length:o[2]},(f,h)=>{let g=Math.floor(u/r[0]),y=Math.floor(_/r[1]),b=Math.floor(h/r[2]);return new bN(a,{private:l[u][_][h],workgroup:i[g][y][b]})})));t.pushMode(c[0][0][0]);try{return{value:JC(t,e),buffers:a,privateVars:l,workgroupVars:i}}finally{t.popMode(\"simulate\")}}var SZ=ko({accessor:()=>zZ,comptime:()=>CZ,computeFn:()=>MZ,const:()=>PZ,declare:()=>bZ,derived:()=>DZ,fn:()=>EZ,fragmentFn:()=>kZ,mutableAccessor:()=>RZ,namespace:()=>op,privateVar:()=>UZ,rawCodeSnippet:()=>AZ,simulate:()=>TZ,slot:()=>LZ,vertexFn:()=>BZ,vertexLayout:()=>GZ,workgroupVar:()=>OZ}),PZ=w3,CZ=Tn,MZ=G3,EZ=nr,kZ=Sk,BZ=Fh,zZ=bk,RZ=xk,DZ=Tk,LZ=v_,UZ=Oh,OZ=kE,GZ=fk,FZ=ko({accessor:()=>bk,bindGroupLayout:()=>CE,comptime:()=>Tn,computeFn:()=>G3,const:()=>w3,fn:()=>nr,fragmentFn:()=>Sk,init:()=>dZ,initFromDevice:()=>uZ,lazy:()=>Tk,mutableAccessor:()=>xk,privateVar:()=>Oh,resolve:()=>_Z,resolveWithContext:()=>Ob,slot:()=>v_,unroll:()=>uE,vertexFn:()=>Fh,vertexLayout:()=>fk,workgroupVar:()=>kE,\"~unstable\":()=>SZ});je({name:\"workgroupBarrier\",normalImpl:\"workgroupBarrier is a no-op outside of CODEGEN mode.\",signature:{argTypes:[],returnType:zr},codegenImpl:()=>\"workgroupBarrier()\",sideEffects:!0});je({name:\"storageBarrier\",normalImpl:\"storageBarrier is a no-op outside of CODEGEN mode.\",signature:{argTypes:[],returnType:zr},codegenImpl:()=>\"storageBarrier()\",sideEffects:!0});je({name:\"textureBarrier\",normalImpl:\"textureBarrier is a no-op outside of CODEGEN mode.\",signature:{argTypes:[],returnType:zr},codegenImpl:()=>\"textureBarrier()\",sideEffects:!0});var wl=\"Atomic operations are not supported outside of CODEGEN mode.\",ba=je({name:\"atomicLoad\",normalImpl:wl,signature:e=>{if(!vh(e))throw new Error(`Invalid atomic type: ${pn(e)}`);return{argTypes:[e],returnType:e.inner}},codegenImpl:(e,[t])=>Ne`atomicLoad(&${t})`,sideEffects:!0}),IZ=e=>{if(!vh(e))throw new Error(`Invalid atomic type: ${pn(e)}`);return{argTypes:[e,e.inner.type===\"u32\"?M:j],returnType:zr}},kd=e=>{if(!vh(e))throw new Error(`Invalid atomic type: ${pn(e)}`);let t=e.inner.type===\"u32\"?M:j;return{argTypes:[e,t],returnType:t}},xa=je({name:\"atomicStore\",normalImpl:wl,signature:IZ,codegenImpl:(e,[t,s])=>Ne`atomicStore(&${t}, ${s})`,sideEffects:!0}),wa=je({name:\"atomicAdd\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicAdd(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicSub\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicSub(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicMax\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicMax(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicMin\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicMin(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicAnd\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicAnd(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicOr\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicOr(&${t}, ${s})`,sideEffects:!0});je({name:\"atomicXor\",normalImpl:wl,signature:kd,codegenImpl:(e,[t,s])=>Ne`atomicXor(&${t}, ${s})`,sideEffects:!0});var Tl=\"Derivative builtins are not allowed on the CPU\",Bu=je({name:\"dpdx\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdx(${t})`,sideEffects:!1});je({name:\"dpdxCoarse\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdxCoarse(${t})`,sideEffects:!1});je({name:\"dpdxFine\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdxFine(${t})`,sideEffects:!1});var zu=je({name:\"dpdy\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdy(${t})`,sideEffects:!1});je({name:\"dpdyCoarse\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdyCoarse(${t})`,sideEffects:!1});je({name:\"dpdyFine\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`dpdyFine(${t})`,sideEffects:!1});var mr=je({name:\"fwidth\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`fwidth(${t})`,sideEffects:!1});je({name:\"fwidthCoarse\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`fwidthCoarse(${t})`,sideEffects:!1});je({name:\"fwidthFine\",normalImpl:Tl,signature:e=>({argTypes:[e],returnType:e}),codegenImpl:(e,[t])=>Ne`fwidthFine(${t})`,sideEffects:!1});function h_(e){return e.filter(t=>t!==void 0)}function YZ(e,t,s,r,o){throw new vo(\"Texture sampling relies on GPU resources and cannot be executed outside of a draw call\")}je({name:\"textureSample\",normalImpl:YZ,codegenImpl:(e,t)=>e.gen.emitCall(\"textureSample\",[],h_(t)),signature:(...e)=>({argTypes:e,returnType:e[0].type.startsWith(\"texture_depth\")?n:qt}),sideEffects:!1});function WZ(e,t,s,r,o,a){throw new vo(\"Texture sampling with bias relies on GPU resources and cannot be executed outside of a draw call\")}je({name:\"textureSampleBias\",normalImpl:WZ,codegenImpl:(e,t)=>e.gen.emitCall(\"textureSampleBias\",[],h_(t)),signature:(...e)=>({argTypes:e,returnType:qt}),sideEffects:!1});function qZ(e,t,s,r,o,a){throw new vo(\"Texture sampling relies on GPU resources and cannot be executed outside of a draw call\")}var Xl=je({name:\"textureSampleLevel\",normalImpl:qZ,codegenImpl:(e,t)=>e.gen.emitCall(\"textureSampleLevel\",[],h_(t)),signature:(...e)=>({argTypes:e,returnType:e[0].type.startsWith(\"texture_depth\")?n:qt}),sideEffects:!1});function VZ(e,t,s){throw new vo(\"`textureLoad` relies on GPU resources and cannot be executed outside of a draw call\")}var Ye=je({name:\"textureLoad\",normalImpl:VZ,codegenImpl:(e,t)=>e.gen.emitCall(\"textureLoad\",[],h_(t)),signature:(...e)=>{let t=e[0];if(DM(t)){let r=t.type.startsWith(\"texture_depth\"),o=t.sampleType;return{argTypes:e,returnType:r?n:o.type===\"f32\"?qt:o.type===\"u32\"?Is:sr}}if(G$(t))return{argTypes:e,returnType:qt};let s=t.format;return{argTypes:e,returnType:f_(s).vectorType}},sideEffects:!1});function NZ(e,t,s,r){throw new vo(\"`textureStore` relies on GPU resources and cannot be executed outside of a draw call\")}var lt=je({name:\"textureStore\",normalImpl:NZ,codegenImpl:(e,t)=>Ne`textureStore(${t})`,signature:(...e)=>({argTypes:e,returnType:zr}),sideEffects:!0});function $Z(e,t){throw new vo(\"`textureDimensions` relies on GPU resources and cannot be executed outside of a draw call\")}var Ti=je({name:\"textureDimensions\",normalImpl:$Z,codegenImpl:(e,t)=>e.gen.emitCall(\"textureDimensions\",[],h_(t)),signature:(...e)=>{let t=e[0].dimension;return t===\"1d\"?{argTypes:e,returnType:M}:t===\"3d\"?{argTypes:e,returnType:Ps}:{argTypes:e,returnType:$s}},sideEffects:!1}),XZ=(...e)=>{throw new Error(\"Texture gather relies on GPU resources and cannot be executed outside of a draw call\")},HZ={f32:qt,i32:sr,u32:Is};je({name:\"textureGather\",normalImpl:XZ,codegenImpl:(e,t)=>Ne`textureGather(${t})`,signature:(...e)=>{if(e[0].type.startsWith(\"texture\")){let[i,l,c,d,...u]=e;return{argTypes:i.type===\"texture_depth_2d_array\"||i.type===\"texture_depth_cube_array\"?[i,l,c,[M,j],...u]:e,returnType:qt}}let[t,s,r,o,...a]=e;return{argTypes:s.type===\"texture_2d_array\"||s.type===\"texture_cube_array\"?[[M,j],s,r,o,[M,j],...a]:[[M,j],s,r,o,...a],returnType:HZ[s.sampleType.type]}},sideEffects:!1});function jZ(e,t,s,r,o,a){throw new vo(\"Texture comparison sampling relies on GPU resources and cannot be executed outside of a draw call\")}je({name:\"textureSampleCompare\",normalImpl:jZ,codegenImpl:(e,t)=>Ne`textureSampleCompare(${t})`,signature:(...e)=>({argTypes:e,returnType:n}),sideEffects:!1});function KZ(e,t,s,r,o,a){throw new vo(\"Texture comparison sampling with level relies on GPU resources and cannot be executed outside of a draw call\")}je({name:\"textureSampleCompareLevel\",normalImpl:KZ,codegenImpl:(e,t)=>Ne`textureSampleCompareLevel(${t})`,signature:(...e)=>({argTypes:e,returnType:n}),sideEffects:!1});function QZ(e,t,s){throw new vo(\"Texture sampling with base clamp to edge is not supported outside of GPU mode.\")}function ZZ(e,t,s,r,o,a,i){throw new vo(\"Texture sampling with gradients relies on GPU resources and cannot be executed outside of a draw call\")}je({name:\"textureSampleGrad\",normalImpl:ZZ,codegenImpl:(e,t)=>Ne`textureSampleGrad(${t})`,signature:(...e)=>({argTypes:e,returnType:qt}),sideEffects:!1});je({name:\"textureSampleBaseClampToEdge\",normalImpl:QZ,codegenImpl:(e,t)=>Ne`textureSampleBaseClampToEdge(${t})`,signature:(...e)=>({argTypes:e,returnType:qt}),sideEffects:!1});var w=FZ,e1=\"uniforms\";function Pk(e){return e.replace(/[^a-zA-Z0-9_]/g,\"_\")}var JZ=new Set([\"alias\",\"break\",\"case\",\"const\",\"const_assert\",\"continue\",\"continuing\",\"default\",\"diagnostic\",\"discard\",\"else\",\"enable\",\"false\",\"fn\",\"for\",\"if\",\"let\",\"loop\",\"override\",\"requires\",\"return\",\"struct\",\"switch\",\"true\",\"var\",\"while\",\"NULL\",\"Self\",\"abstract\",\"active\",\"alignas\",\"alignof\",\"as\",\"asm\",\"asm_fragment\",\"async\",\"attribute\",\"auto\",\"await\",\"become\",\"cast\",\"catch\",\"class\",\"co_await\",\"co_return\",\"co_yield\",\"coherent\",\"column_major\",\"common\",\"compile\",\"compile_fragment\",\"concept\",\"const_cast\",\"consteval\",\"constexpr\",\"constinit\",\"crate\",\"debugger\",\"decltype\",\"delete\",\"demote\",\"demote_to_helper\",\"do\",\"dynamic_cast\",\"enum\",\"explicit\",\"export\",\"extends\",\"extern\",\"external\",\"fallthrough\",\"filter\",\"final\",\"finally\",\"friend\",\"from\",\"fxgroup\",\"get\",\"goto\",\"groupshared\",\"highp\",\"impl\",\"implements\",\"import\",\"inline\",\"instanceof\",\"interface\",\"layout\",\"lowp\",\"macro\",\"macro_rules\",\"match\",\"mediump\",\"meta\",\"mod\",\"module\",\"move\",\"mut\",\"mutable\",\"namespace\",\"new\",\"nil\",\"noexcept\",\"noinline\",\"nointerpolation\",\"non_coherent\",\"noncoherent\",\"noperspective\",\"null\",\"nullptr\",\"of\",\"operator\",\"package\",\"packoffset\",\"partition\",\"pass\",\"patch\",\"pixelfragment\",\"precise\",\"precision\",\"premerge\",\"priv\",\"protected\",\"pub\",\"public\",\"readonly\",\"ref\",\"regardless\",\"register\",\"reinterpret_cast\",\"require\",\"resource\",\"restrict\",\"self\",\"set\",\"shared\",\"sizeof\",\"smooth\",\"snorm\",\"static\",\"static_assert\",\"static_cast\",\"std\",\"subroutine\",\"super\",\"target\",\"template\",\"this\",\"thread_local\",\"throw\",\"trait\",\"try\",\"type\",\"typedef\",\"typeid\",\"typename\",\"typeof\",\"union\",\"unless\",\"unorm\",\"unsafe\",\"unsized\",\"use\",\"using\",\"varying\",\"virtual\",\"volatile\",\"wgsl\",\"where\",\"with\",\"writeonly\",\"yield\",\"sampler\",\"uniform\",\"storage\"]);function eJ(e){let t=Pk(e);return JZ.has(t)?`${t}_`:t}function Hn(e){return`n_${Pk(e)}`}function Ib(e){return e===\"vec2\"?2:e===\"vec3\"?3:4}function Ck(e){let t=e.type;return t===\"vec2f\"||t===\"vec2i\"||t===\"vec2u\"?\"vec2\":t===\"vec3f\"||t===\"vec3i\"||t===\"vec3u\"?\"vec3\":t===\"vec4f\"||t===\"vec4i\"||t===\"vec4u\"?\"vec4\":\"scalar\"}function tJ(e){return e.type===\"array\"}function Mk(e){if(typeof e==\"number\"||typeof e==\"boolean\")return n;if(e&&typeof e==\"object\"){let t=e.kind;if(typeof t==\"string\"){if(t.startsWith(\"vec2\"))return m;if(t.startsWith(\"vec3\"))return A;if(t.startsWith(\"vec4\"))return S}if(Array.isArray(e))return Fe(n,e.length||1);let s=e;if(\"w\"in s)return S;if(\"z\"in s)return A;if(\"x\"in s&&\"y\"in s)return m}return Array.isArray(e)?Fe(n,e.length||1):n}function Yb(e,t){let s=e;if(s&&typeof s==\"object\"&&\"data\"in s&&!(\"x\"in s)&&(s=s.data),typeof s==\"number\")return new Array(t).fill(s);if(s instanceof Ek)return s.toArray().slice(0,t);if(Array.isArray(s))return W7(s,t);if(s&&typeof s==\"object\"){let r=s;if(\"x\"in r){let o=[r.x,r.y??0];return t>=3&&o.push(r.z??0),t>=4&&o.push(r.w??0),o.slice(0,t)}if(typeof r.length==\"number\")return W7(Array.from(r),t)}throw new Error(`[uniformStore] cannot coerce value to a ${t}-component vector: ${String(e)}`)}function W7(e,t){let s=e.slice(0,t);for(;s.length<t;)s.push(0);return s}function q7(e){let t=e;if(t&&typeof t==\"object\"&&\"data\"in t&&(t=t.data),typeof t==\"number\")return t;if(typeof t==\"boolean\")return t?1:-1;let s=Number(t);return Number.isFinite(s)?s:0}var V7=new Set;function sJ(e){if(e==null)return!0;let t=typeof e;if(t===\"number\"||t===\"boolean\"||t===\"string\")return!0;if(t!==\"object\")return!1;if(Array.isArray(e))return!0;let s=e;return!!(typeof s.kind==\"string\"&&s.kind.startsWith(\"vec\")||\"x\"in s&&\"y\"in s||typeof s.length==\"number\"||\"data\"in s)}var Ek=class{constructor(e){this.handle=e}get n(){return this.handle._componentCount}component(e){return this.handle._mirror[e]??0}write(e,t){this.handle._mirror[e]=t,this.handle._enqueue()}get x(){return this.component(0)}set x(e){this.write(0,e)}get y(){return this.component(1)}set y(e){this.write(1,e)}get z(){return this.component(2)}set z(e){this.write(2,e)}get w(){return this.component(3)}set w(e){this.write(3,e)}get r(){return this.component(0)}set r(e){this.write(0,e)}get g(){return this.component(1)}set g(e){this.write(1,e)}get b(){return this.component(2)}set b(e){this.write(2,e)}get a(){return this.component(3)}set a(e){this.write(3,e)}copy(e){let t=Yb(e,this.n);for(let s=0;s<this.n;s++)this.handle._mirror[s]=t[s];return this.handle._enqueue(),this}set(...e){for(let t=0;t<this.n&&t<e.length;t++)this.handle._mirror[t]=e[t];return this.handle._enqueue(),this}toArray(){return this.handle._mirror.slice(0,this.n)}},si=class{gpuPath;accessorPath;transform;cpu;schema;_componentCount;_mirror;_raw;_kind;_view;_sink;constructor(e){this._sink=e.sink,this.gpuPath=e.gpuPath,this.accessorPath=`${e.gpuPath[0]}.${e.gpuPath[1]}`,this.transform=e.transform,this.cpu=e.cpu??!1,this.schema=e.schema,this._kind=this.cpu||!e.schema?\"scalar\":Ck(e.schema),this._componentCount=this._kind===\"scalar\"?1:Ib(this._kind),this.cpu?(this._mirror=[],this._raw=e.initial):this._kind===\"scalar\"?this._mirror=[q7(e.initial)]:(this._mirror=Yb(e.initial,this._componentCount),this._view=new Ek(this))}_enqueue(){this.cpu||this._sink.markScalar(this)}_patchValue(){return this._kind===\"scalar\"?this._mirror[0]:this._mirror.slice(0,this._componentCount)}get value(){return this.cpu?this._raw:this._kind===\"scalar\"?this._mirror[0]:this._view}set value(e){if(this.cpu){this._raw=e;return}if(this._kind===\"scalar\")this._mirror[0]=q7(e);else{let t=Yb(e,this._componentCount);for(let s=0;s<this._componentCount;s++)this._mirror[s]=t[s]}this._enqueue()}setFromRaw(e){if(this.cpu){this._raw=e;return}this.value=this.transform?this.transform(e):e}setComponents(...e){if(this.cpu||this._kind===\"scalar\"){e.length&&(this.value=e[0]);return}for(let t=0;t<this._componentCount&&t<e.length;t++)this._mirror[t]=e[t];this._enqueue()}},Nm=class{gpuPath;accessorPath;transform;schema;length;elementKind;_mirror;_sink;constructor(e){this._sink=e.sink,this.gpuPath=e.gpuPath,this.accessorPath=`${e.gpuPath[0]}.${e.gpuPath[1]}`,this.transform=e.transform,this.schema=e.schema,this.length=e.schema.elementCount,this.elementKind=Ck(e.schema.elementType),this._mirror=e.initial?e.initial.slice():new Array(this.flatLength).fill(0)}get flatLength(){return this.length*(this.elementKind===\"scalar\"?1:Ib(this.elementKind))}get array(){return this._mirror}set array(e){e!==this._mirror&&(this._mirror=e.slice()),this._sink.markArray(this,\"all\")}setElement(e,t){this._mirror[e]=t,this._sink.markArray(this,e)}get componentsPerElement(){return this.elementKind===\"scalar\"?1:Ib(this.elementKind)}_wholeArray(){let e=this._mirror.slice(0,this.flatLength),t=this.componentsPerElement;if(t===1)return e;let s=[];for(let r=0;r<this.length;r++)s.push(e.slice(r*t,(r+1)*t));return s}_elementAt(e){return this._mirror[e]}_elementTuple(e){let t=this.componentsPerElement;return this._mirror.slice(e*t,(e+1)*t)}},rJ=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({time:n,deltaTime:n,frame:n,viewportSize:m,logicalViewportSize:m,aspect:n,pointer:m,pointerActive:n}),\"SystemUniforms\"),oJ={time:0,deltaTime:0,frame:0,viewportSize:[1,1],logicalViewportSize:[1,1],aspect:1,pointer:[.5,.5],pointerActive:0};function kk(e,t={}){let s=t.systemSchema??rJ,r={...oJ,...t.systemInitial??{}},o=new Map,a=new Map,i={},l=s,c=!1,d=new Set,u=new Map,p=new Map,_={markScalar(x){d.add(x)},markArray(x,P){if(P===\"all\"){u.set(x,\"all\");return}let C=u.get(x);C!==\"all\"&&(C?C.add(P):u.set(x,new Set([P])))}},f;function h(x,P){let C={},E={};for(let R of P){let U=eJ(R.name),L=R.transform?R.transform(R.initial):R.initial,k=R.cpu??typeof L==\"string\";if(R.transform&&!k&&!sJ(L)&&!V7.has(R.transform)&&(V7.add(R.transform),console.warn(`[gpu] prop transform for \"${R.name}\" returned a non-packable value \\u2014 the uniform field will be NaN. A prop transform must return a number, boolean, vector, or array (or a string for cpu-only props).`,L)),k){C[R.name]=new si({sink:_,gpuPath:[x,U],initial:L,transform:R.transform,cpu:!0});continue}let D=L&&typeof L==\"object\"&&\"data\"in L?L.data:L,O=R.schema??Mk(D);if(E[U]=O,tJ(O)){let F=new Nm({sink:_,gpuPath:[x,U],schema:O,initial:R.initial,transform:R.transform});C[R.name]=F}else{let F=new si({sink:_,gpuPath:[x,U],schema:O,initial:L,transform:R.transform});C[R.name]=F}}return{handles:C,struct:(globalThis.__TYPEGPU_AUTONAME__??(R=>R))(gt(E),\"struct\")}}function g(){if(f)throw new Error(\"[uniformStore] cannot register fields after finalize()\")}function y(){let x={};for(let[P,C]of a)x[P]=b(C,P);return x._sys=b(i,\"_sys\"),x}function b(x,P){let C={};for(let E of Object.values(x))E instanceof Nm?C[E.gpuPath[1]]=E._wholeArray():E.cpu||(C[E.gpuPath[1]]=E._patchValue());if(P)for(let E of p.get(P)??[])C[E]=0;return C}return{get schema(){return f?.schema},get layout(){return f?.layout},get buffer(){return f?.buffer},get bindGroup(){return f?.bindGroup},get systemHandles(){return i},defineNode(x,P){g();let C=Hn(x),{handles:E,struct:R}=h(C,P);return o.set(C,R),a.set(C,E),E},defineSystem(x){if(g(),x&&x.length){let P=h(\"_sys\",x);i=P.handles,l=P.struct}else{let P=h(\"_sys\",Object.entries(s.propTypes).map(([C,E])=>({name:C,schema:E,initial:r[C]??0})));i=P.handles,l=P.struct}return c=!0,i},finalize(){if(f)return f;c||this.defineSystem();let x=(D,O)=>{if(Object.keys(O.propTypes).length===0){let Y=[\"_pad0\",\"_pad1\",\"_pad2\",\"_pad3\"];return p.set(D,Y),gt(Object.fromEntries(Y.map(V=>[V,n])))}let F=O,q=[];for(;Kw(F)%16!==0;){let Y=`_pad${q.length}`;for(;Y in O.propTypes;)Y=`_${Y}`;q.push(Y);let V={...O.propTypes};for(let X of q)V[X]=n;F=(globalThis.__TYPEGPU_AUTONAME__??(X=>X))(gt(V),\"padded\")}return q.length&&p.set(D,q),F},P={};for(let[D,O]of o)P[D]=x(D,O);P._sys=x(\"_sys\",l);let C=(globalThis.__TYPEGPU_AUTONAME__??(D=>D))(gt(P),\"combined\"),E=Kw(C),R=e.device?.limits?.maxUniformBufferBindingSize,U=typeof R==\"number\"&&R>0?R:65536;if(E>U)throw new Kd(\"limit-exceeded\",`[gpu] this composition needs ${E} bytes of uniform data across ${o.size} nodes, but the device caps a uniform binding at ${U} bytes. Reduce the number of layers.`);let L=(globalThis.__TYPEGPU_AUTONAME__??(D=>D))(e.createBuffer(C).$usage(\"uniform\"),\"buffer\"),k=(globalThis.__TYPEGPU_AUTONAME__??(D=>D))(w.bindGroupLayout({[e1]:{uniform:C}}),\"layout\");return f={schema:C,layout:k,buffer:L,bindGroup:e.createBindGroup(k,{[e1]:L}),uniformEntryKey:e1},this.writeAll(),f},flush(){if(!f||d.size===0&&u.size===0)return;let x={},P=C=>x[C]??={};for(let C of d)P(C.gpuPath[0])[C.gpuPath[1]]=C._patchValue();for(let[C,E]of u){let R=P(C.gpuPath[0]);if(E===\"all\")R[C.gpuPath[1]]=C._wholeArray();else if(C.componentsPerElement===1){let U={};for(let L of E)U[L]=C._elementAt(L);R[C.gpuPath[1]]=U}else{let U=C.componentsPerElement,L={};for(let k of E){let D=Math.floor(k/U);L[D]=C._elementTuple(D)}R[C.gpuPath[1]]=L}}f.buffer.patch(x),d.clear(),u.clear()},writeAll(){f&&(f.buffer.write(y()),d.clear(),u.clear())},gpuAccessor(x,P=\"layout\"){return`${P}.$.${e1}.${x.accessorPath}`},destroy(){f?.buffer.destroy?.(),f=void 0,o.clear(),a.clear(),d.clear(),u.clear(),p.clear()}}}function Bk(e,t){if(e instanceof Nm){Array.isArray(t)&&(e.array=t);return}e.setFromRaw(t)}var bt=Math.PI/180;180/Math.PI;var Wo=Math.PI,Jt=Math.PI*2,Po=Jt,ev=Math.PI/2,lc=Math.sqrt(3),aJ=2.3999632297286535,ha=w.fn([M,j],M)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t<<M(s)|t>>M(__tsover_sub(j(32),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"k\"}],body:[0,[[10,[1,[1,\"x\",\"<<\",[6,\"d.u32\",[\"k\"]]],\"|\",[1,\"x\",\">>\",[6,\"d.u32\",[[1,[6,\"d.i32\",[[5,\"32\"]]],\"-\",\"k\"]]]]]]]]},externals:{\"d.u32\":()=>M,\"d.i32\":()=>j}})&&e.f)({})),Ru=w.fn([M,M,M],M)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=t,a=s,i=r;return i=i^a,i=__tsover_sub(i,ha(a,j(14))),o=o^i,o=__tsover_sub(o,ha(i,j(11))),a=a^o,a=__tsover_sub(a,ha(o,j(25))),i=i^a,i=__tsover_sub(i,ha(a,j(16))),o=o^i,o=__tsover_sub(o,ha(i,j(4))),a=a^o,a=__tsover_sub(a,ha(o,j(14))),i=i^a,i=__tsover_sub(i,ha(a,j(24))),i}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"a0\"},{type:\"i\",name:\"b0\"},{type:\"i\",name:\"c0\"}],body:[0,[[12,\"a\",\"a0\"],[12,\"b\",\"b0\"],[12,\"c\",\"c0\"],[2,\"c\",\"=\",[1,\"c\",\"^\",\"b\"]],[2,\"c\",\"=\",[1,\"c\",\"-\",[6,\"mxRotl32\",[\"b\",[6,\"d.i32\",[[5,\"14\"]]]]]]],[2,\"a\",\"=\",[1,\"a\",\"^\",\"c\"]],[2,\"a\",\"=\",[1,\"a\",\"-\",[6,\"mxRotl32\",[\"c\",[6,\"d.i32\",[[5,\"11\"]]]]]]],[2,\"b\",\"=\",[1,\"b\",\"^\",\"a\"]],[2,\"b\",\"=\",[1,\"b\",\"-\",[6,\"mxRotl32\",[\"a\",[6,\"d.i32\",[[5,\"25\"]]]]]]],[2,\"c\",\"=\",[1,\"c\",\"^\",\"b\"]],[2,\"c\",\"=\",[1,\"c\",\"-\",[6,\"mxRotl32\",[\"b\",[6,\"d.i32\",[[5,\"16\"]]]]]]],[2,\"a\",\"=\",[1,\"a\",\"^\",\"c\"]],[2,\"a\",\"=\",[1,\"a\",\"-\",[6,\"mxRotl32\",[\"c\",[6,\"d.i32\",[[5,\"4\"]]]]]]],[2,\"b\",\"=\",[1,\"b\",\"^\",\"a\"]],[2,\"b\",\"=\",[1,\"b\",\"-\",[6,\"mxRotl32\",[\"a\",[6,\"d.i32\",[[5,\"14\"]]]]]]],[2,\"c\",\"=\",[1,\"c\",\"^\",\"b\"]],[2,\"c\",\"=\",[1,\"c\",\"-\",[6,\"mxRotl32\",[\"b\",[6,\"d.i32\",[[5,\"24\"]]]]]]],[10,\"c\"]]]},externals:{mxRotl32:()=>ha,\"d.i32\":()=>j}})&&e.f)({})),Du=3735928559,sm=w.fn([j,j],M)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=M(2),o=__tsover_add(__tsover_add(M(Du),r<<M(2)),M(13));return Ru(__tsover_add(o,M(t)),__tsover_add(o,M(s)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"len\",[6,\"d.u32\",[[5,\"2\"]]]],[13,\"seed\",[1,[1,[6,\"d.u32\",[\"DEADBEEF\"]],\"+\",[1,\"len\",\"<<\",[6,\"d.u32\",[[5,\"2\"]]]]],\"+\",[6,\"d.u32\",[[5,\"13\"]]]]],[13,\"a\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"x\"]]]],[13,\"b\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"y\"]]]],[10,[6,\"mxBjfinal\",[\"a\",\"b\",\"seed\"]]]]]},externals:{\"d.u32\":()=>M,DEADBEEF:()=>Du,mxBjfinal:()=>Ru}})&&e.f)({})),cn=w.fn([j,j,j],M)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=M(3),a=__tsover_add(__tsover_add(M(Du),o<<M(2)),M(13));return Ru(__tsover_add(a,M(t)),__tsover_add(a,M(s)),__tsover_add(a,M(r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"z\"}],body:[0,[[13,\"len\",[6,\"d.u32\",[[5,\"3\"]]]],[13,\"seed\",[1,[1,[6,\"d.u32\",[\"DEADBEEF\"]],\"+\",[1,\"len\",\"<<\",[6,\"d.u32\",[[5,\"2\"]]]]],\"+\",[6,\"d.u32\",[[5,\"13\"]]]]],[13,\"a\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"x\"]]]],[13,\"b\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"y\"]]]],[13,\"c\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"z\"]]]],[10,[6,\"mxBjfinal\",[\"a\",\"b\",\"c\"]]]]]},externals:{\"d.u32\":()=>M,DEADBEEF:()=>Du,mxBjfinal:()=>Ru}})&&e.f)({})),t1=w.fn([j,j,j,j],M)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=M(4),i=__tsover_add(__tsover_add(M(Du),a<<M(2)),M(13)),l=__tsover_add(i,M(t)),c=__tsover_add(i,M(s)),d=__tsover_add(i,M(r));return l=__tsover_sub(l,d),l=l^ha(d,j(4)),d=__tsover_add(d,c),c=__tsover_sub(c,l),c=c^ha(l,j(6)),l=__tsover_add(l,d),d=__tsover_sub(d,c),d=d^ha(c,j(8)),c=__tsover_add(c,l),l=__tsover_sub(l,d),l=l^ha(d,j(16)),d=__tsover_add(d,c),c=__tsover_sub(c,l),c=c^ha(l,j(19)),l=__tsover_add(l,d),d=__tsover_sub(d,c),d=d^ha(c,j(4)),c=__tsover_add(c,l),l=__tsover_add(l,M(o)),Ru(l,c,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"z\"},{type:\"i\",name:\"xx\"}],body:[0,[[13,\"len\",[6,\"d.u32\",[[5,\"4\"]]]],[13,\"seed\",[1,[1,[6,\"d.u32\",[\"DEADBEEF\"]],\"+\",[1,\"len\",\"<<\",[6,\"d.u32\",[[5,\"2\"]]]]],\"+\",[6,\"d.u32\",[[5,\"13\"]]]]],[12,\"a\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"x\"]]]],[12,\"b\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"y\"]]]],[12,\"c\",[1,\"seed\",\"+\",[6,\"d.u32\",[\"z\"]]]],[2,\"a\",\"=\",[1,\"a\",\"-\",\"c\"]],[2,\"a\",\"=\",[1,\"a\",\"^\",[6,\"mxRotl32\",[\"c\",[6,\"d.i32\",[[5,\"4\"]]]]]]],[2,\"c\",\"=\",[1,\"c\",\"+\",\"b\"]],[2,\"b\",\"=\",[1,\"b\",\"-\",\"a\"]],[2,\"b\",\"=\",[1,\"b\",\"^\",[6,\"mxRotl32\",[\"a\",[6,\"d.i32\",[[5,\"6\"]]]]]]],[2,\"a\",\"=\",[1,\"a\",\"+\",\"c\"]],[2,\"c\",\"=\",[1,\"c\",\"-\",\"b\"]],[2,\"c\",\"=\",[1,\"c\",\"^\",[6,\"mxRotl32\",[\"b\",[6,\"d.i32\",[[5,\"8\"]]]]]]],[2,\"b\",\"=\",[1,\"b\",\"+\",\"a\"]],[2,\"a\",\"=\",[1,\"a\",\"-\",\"c\"]],[2,\"a\",\"=\",[1,\"a\",\"^\",[6,\"mxRotl32\",[\"c\",[6,\"d.i32\",[[5,\"16\"]]]]]]],[2,\"c\",\"=\",[1,\"c\",\"+\",\"b\"]],[2,\"b\",\"=\",[1,\"b\",\"-\",\"a\"]],[2,\"b\",\"=\",[1,\"b\",\"^\",[6,\"mxRotl32\",[\"a\",[6,\"d.i32\",[[5,\"19\"]]]]]]],[2,\"a\",\"=\",[1,\"a\",\"+\",\"c\"]],[2,\"c\",\"=\",[1,\"c\",\"-\",\"b\"]],[2,\"c\",\"=\",[1,\"c\",\"^\",[6,\"mxRotl32\",[\"b\",[6,\"d.i32\",[[5,\"4\"]]]]]]],[2,\"b\",\"=\",[1,\"b\",\"+\",\"a\"]],[2,\"a\",\"=\",[1,\"a\",\"+\",[6,\"d.u32\",[\"xx\"]]]],[10,[6,\"mxBjfinal\",[\"a\",\"b\",\"c\"]]]]]},externals:{\"d.u32\":()=>M,DEADBEEF:()=>Du,mxRotl32:()=>ha,\"d.i32\":()=>j,mxBjfinal:()=>Ru}})&&e.f)({})),Hl=w.fn([M],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_div(n(t),n(4294967295))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"bits\"}],body:[0,[[10,[1,[6,\"d.f32\",[\"bits\"]],\"/\",[6,\"d.f32\",[[5,\"4294967295\"]]]]]]]},externals:{\"d.f32\":()=>n}})&&e.f)({})),Jc=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(__tsover_mul(__tsover_mul(t,t),t),__tsover_add(__tsover_mul(t,__tsover_sub(__tsover_mul(t,6),15)),10))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[1,[1,[1,\"t\",\"*\",\"t\"],\"*\",\"t\"],\"*\",[1,[1,\"t\",\"*\",[1,[1,\"t\",\"*\",[5,\"6\"]],\"-\",[5,\"15\"]]],\"+\",[5,\"10\"]]]]]]},externals:{}})&&e.f)({})),rm=w.fn([M,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=t&M(7),a=N(r,s,o<M(4)),i=__tsover_mul(2,N(s,r,o<M(4))),l=N(a,-a,(o&M(1))!==M(0)),c=N(i,-i,(o&M(2))!==M(0));return __tsover_add(l,c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"hash\"},{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"h\",[1,\"hash\",\"&\",[6,\"d.u32\",[[5,\"7\"]]]]],[13,\"u\",[6,\"std.select\",[\"y\",\"x\",[1,\"h\",\"<\",[6,\"d.u32\",[[5,\"4\"]]]]]]],[13,\"v\",[1,[5,\"2\"],\"*\",[6,\"std.select\",[\"x\",\"y\",[1,\"h\",\"<\",[6,\"d.u32\",[[5,\"4\"]]]]]]]],[13,\"uu\",[6,\"std.select\",[\"u\",[4,\"-\",\"u\"],[1,[1,\"h\",\"&\",[6,\"d.u32\",[[5,\"1\"]]]],\"!==\",[6,\"d.u32\",[[5,\"0\"]]]]]]],[13,\"vv\",[6,\"std.select\",[\"v\",[4,\"-\",\"v\"],[1,[1,\"h\",\"&\",[6,\"d.u32\",[[5,\"2\"]]]],\"!==\",[6,\"d.u32\",[[5,\"0\"]]]]]]],[10,[1,\"uu\",\"+\",\"vv\"]]]]},externals:{\"d.u32\":()=>M,\"std.select\":()=>N}})&&e.f)({})),Hi=w.fn([M,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=t&M(15),i=N(r,s,a<M(8)),l=N(N(o,s,a===M(12)||a===M(14)),r,a<M(4)),c=N(i,-i,(a&M(1))!==M(0)),d=N(l,-l,(a&M(2))!==M(0));return __tsover_add(c,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"hash\"},{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"z\"}],body:[0,[[13,\"h\",[1,\"hash\",\"&\",[6,\"d.u32\",[[5,\"15\"]]]]],[13,\"u\",[6,\"std.select\",[\"y\",\"x\",[1,\"h\",\"<\",[6,\"d.u32\",[[5,\"8\"]]]]]]],[13,\"inner\",[6,\"std.select\",[\"z\",\"x\",[3,[1,\"h\",\"===\",[6,\"d.u32\",[[5,\"12\"]]]],\"||\",[1,\"h\",\"===\",[6,\"d.u32\",[[5,\"14\"]]]]]]]],[13,\"v\",[6,\"std.select\",[\"inner\",\"y\",[1,\"h\",\"<\",[6,\"d.u32\",[[5,\"4\"]]]]]]],[13,\"uu\",[6,\"std.select\",[\"u\",[4,\"-\",\"u\"],[1,[1,\"h\",\"&\",[6,\"d.u32\",[[5,\"1\"]]]],\"!==\",[6,\"d.u32\",[[5,\"0\"]]]]]]],[13,\"vv\",[6,\"std.select\",[\"v\",[4,\"-\",\"v\"],[1,[1,\"h\",\"&\",[6,\"d.u32\",[[5,\"2\"]]]],\"!==\",[6,\"d.u32\",[[5,\"0\"]]]]]]],[10,[1,\"uu\",\"+\",\"vv\"]]]]},externals:{\"d.u32\":()=>M,\"std.select\":()=>N}})&&e.f)({})),N7=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(.6616,t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[10,[1,[5,\"0.6616\"],\"*\",\"v\"]]]]},externals:{}})&&e.f)({})),$7=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(.982,t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[10,[1,[5,\"0.982\"],\"*\",\"v\"]]]]},externals:{}})&&e.f)({})),X7=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_sub(1,a);return __tsover_add(__tsover_mul(__tsover_sub(1,i),__tsover_add(__tsover_mul(t,l),__tsover_mul(s,a))),__tsover_mul(i,__tsover_add(__tsover_mul(r,l),__tsover_mul(o,a))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v0\"},{type:\"i\",name:\"v1\"},{type:\"i\",name:\"v2\"},{type:\"i\",name:\"v3\"},{type:\"i\",name:\"s\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"s1\",[1,[5,\"1\"],\"-\",\"s\"]],[10,[1,[1,[1,[5,\"1\"],\"-\",\"t\"],\"*\",[1,[1,\"v0\",\"*\",\"s1\"],\"+\",[1,\"v1\",\"*\",\"s\"]]],\"+\",[1,\"t\",\"*\",[1,[1,\"v2\",\"*\",\"s1\"],\"+\",[1,\"v3\",\"*\",\"s\"]]]]]]]},externals:{}})&&e.f)({})),H7=w.fn([n,n,n,n,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=__tsover_sub(1,d),f=__tsover_sub(1,u),h=__tsover_sub(1,p);return __tsover_add(__tsover_mul(h,__tsover_add(__tsover_mul(f,__tsover_add(__tsover_mul(t,_),__tsover_mul(s,d))),__tsover_mul(u,__tsover_add(__tsover_mul(r,_),__tsover_mul(o,d))))),__tsover_mul(p,__tsover_add(__tsover_mul(f,__tsover_add(__tsover_mul(a,_),__tsover_mul(i,d))),__tsover_mul(u,__tsover_add(__tsover_mul(l,_),__tsover_mul(c,d))))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v0\"},{type:\"i\",name:\"v1\"},{type:\"i\",name:\"v2\"},{type:\"i\",name:\"v3\"},{type:\"i\",name:\"v4\"},{type:\"i\",name:\"v5\"},{type:\"i\",name:\"v6\"},{type:\"i\",name:\"v7\"},{type:\"i\",name:\"s\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"r\"}],body:[0,[[13,\"s1\",[1,[5,\"1\"],\"-\",\"s\"]],[13,\"t1\",[1,[5,\"1\"],\"-\",\"t\"]],[13,\"r1\",[1,[5,\"1\"],\"-\",\"r\"]],[10,[1,[1,\"r1\",\"*\",[1,[1,\"t1\",\"*\",[1,[1,\"v0\",\"*\",\"s1\"],\"+\",[1,\"v1\",\"*\",\"s\"]]],\"+\",[1,\"t\",\"*\",[1,[1,\"v2\",\"*\",\"s1\"],\"+\",[1,\"v3\",\"*\",\"s\"]]]]],\"+\",[1,\"r\",\"*\",[1,[1,\"t1\",\"*\",[1,[1,\"v4\",\"*\",\"s1\"],\"+\",[1,\"v5\",\"*\",\"s\"]]],\"+\",[1,\"t\",\"*\",[1,[1,\"v6\",\"*\",\"s1\"],\"+\",[1,\"v7\",\"*\",\"s\"]]]]]]]]]},externals:{}})&&e.f)({})),j7=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=j(ie(t.x)),r=j(ie(t.y)),o=__tsover_sub(t.x,n(s)),a=__tsover_sub(t.y,n(r)),i=Jc(o),l=Jc(a);return N7(X7(rm(sm(s,r),o,a),rm(sm(__tsover_add(s,j(1)),r),__tsover_sub(o,1),a),rm(sm(s,__tsover_add(r,j(1))),o,__tsover_sub(a,1)),rm(sm(__tsover_add(s,j(1)),__tsover_add(r,j(1))),__tsover_sub(o,1),__tsover_sub(a,1)),i,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"X\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"Y\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[13,\"fx\",[1,[7,\"p\",\"x\"],\"-\",[6,\"d.f32\",[\"X\"]]]],[13,\"fy\",[1,[7,\"p\",\"y\"],\"-\",[6,\"d.f32\",[\"Y\"]]]],[13,\"u\",[6,\"mxFade\",[\"fx\"]]],[13,\"v\",[6,\"mxFade\",[\"fy\"]]],[13,\"result\",[6,\"mxBilerp\",[[6,\"mxGradientFloat2\",[[6,\"mxHashInt1\",[\"X\",\"Y\"]],\"fx\",\"fy\"]],[6,\"mxGradientFloat2\",[[6,\"mxHashInt1\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],\"Y\"]],[1,\"fx\",\"-\",[5,\"1\"]],\"fy\"]],[6,\"mxGradientFloat2\",[[6,\"mxHashInt1\",[\"X\",[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],\"fx\",[1,\"fy\",\"-\",[5,\"1\"]]]],[6,\"mxGradientFloat2\",[[6,\"mxHashInt1\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],[1,\"fx\",\"-\",[5,\"1\"]],[1,\"fy\",\"-\",[5,\"1\"]]]],\"u\",\"v\"]]],[10,[6,\"mxGradientScale2d\",[\"result\"]]]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.f32\":()=>n,mxFade:()=>Jc,mxBilerp:()=>X7,mxGradientFloat2:()=>rm,mxHashInt1:()=>sm,mxGradientScale2d:()=>N7}})&&e.f)({})),K7=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=j(ie(t.x)),r=j(ie(t.y)),o=j(ie(t.z)),a=__tsover_sub(t.x,n(s)),i=__tsover_sub(t.y,n(r)),l=__tsover_sub(t.z,n(o)),c=Jc(a),d=Jc(i),u=Jc(l);return $7(H7(Hi(cn(s,r,o),a,i,l),Hi(cn(__tsover_add(s,j(1)),r,o),__tsover_sub(a,1),i,l),Hi(cn(s,__tsover_add(r,j(1)),o),a,__tsover_sub(i,1),l),Hi(cn(__tsover_add(s,j(1)),__tsover_add(r,j(1)),o),__tsover_sub(a,1),__tsover_sub(i,1),l),Hi(cn(s,r,__tsover_add(o,j(1))),a,i,__tsover_sub(l,1)),Hi(cn(__tsover_add(s,j(1)),r,__tsover_add(o,j(1))),__tsover_sub(a,1),i,__tsover_sub(l,1)),Hi(cn(s,__tsover_add(r,j(1)),__tsover_add(o,j(1))),a,__tsover_sub(i,1),__tsover_sub(l,1)),Hi(cn(__tsover_add(s,j(1)),__tsover_add(r,j(1)),__tsover_add(o,j(1))),__tsover_sub(a,1),__tsover_sub(i,1),__tsover_sub(l,1)),c,d,u))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"X\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"Y\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[13,\"Z\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"z\"]]]]]],[13,\"fx\",[1,[7,\"p\",\"x\"],\"-\",[6,\"d.f32\",[\"X\"]]]],[13,\"fy\",[1,[7,\"p\",\"y\"],\"-\",[6,\"d.f32\",[\"Y\"]]]],[13,\"fz\",[1,[7,\"p\",\"z\"],\"-\",[6,\"d.f32\",[\"Z\"]]]],[13,\"u\",[6,\"mxFade\",[\"fx\"]]],[13,\"v\",[6,\"mxFade\",[\"fy\"]]],[13,\"w\",[6,\"mxFade\",[\"fz\"]]],[13,\"result\",[6,\"mxTrilerp\",[[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[\"X\",\"Y\",\"Z\"]],\"fx\",\"fy\",\"fz\"]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],\"Y\",\"Z\"]],[1,\"fx\",\"-\",[5,\"1\"]],\"fy\",\"fz\"]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[\"X\",[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],\"Z\"]],\"fx\",[1,\"fy\",\"-\",[5,\"1\"]],\"fz\"]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],\"Z\"]],[1,\"fx\",\"-\",[5,\"1\"]],[1,\"fy\",\"-\",[5,\"1\"]],\"fz\"]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[\"X\",\"Y\",[1,\"Z\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],\"fx\",\"fy\",[1,\"fz\",\"-\",[5,\"1\"]]]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],\"Y\",[1,\"Z\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],[1,\"fx\",\"-\",[5,\"1\"]],\"fy\",[1,\"fz\",\"-\",[5,\"1\"]]]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[\"X\",[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],[1,\"Z\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],\"fx\",[1,\"fy\",\"-\",[5,\"1\"]],[1,\"fz\",\"-\",[5,\"1\"]]]],[6,\"mxGradientFloat3\",[[6,\"mxHashInt2\",[[1,\"X\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],[1,\"Y\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]],[1,\"Z\",\"+\",[6,\"d.i32\",[[5,\"1\"]]]]]],[1,\"fx\",\"-\",[5,\"1\"]],[1,\"fy\",\"-\",[5,\"1\"]],[1,\"fz\",\"-\",[5,\"1\"]]]],\"u\",\"v\",\"w\"]]],[10,[6,\"mxGradientScale3d\",[\"result\"]]]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.f32\":()=>n,mxFade:()=>Jc,mxTrilerp:()=>H7,mxGradientFloat3:()=>Hi,mxHashInt2:()=>cn,mxGradientScale3d:()=>$7}})&&e.f)({})),Q7=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=j(ie(t.x)),r=j(ie(t.y));return A(Hl(cn(s,r,j(0))),Hl(cn(s,r,j(1))),Hl(cn(s,r,j(2))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"ix\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"iy\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[10,[6,\"d.vec3f\",[[6,\"mxBitsTo01\",[[6,\"mxHashInt2\",[\"ix\",\"iy\",[6,\"d.i32\",[[5,\"0\"]]]]]]],[6,\"mxBitsTo01\",[[6,\"mxHashInt2\",[\"ix\",\"iy\",[6,\"d.i32\",[[5,\"1\"]]]]]]],[6,\"mxBitsTo01\",[[6,\"mxHashInt2\",[\"ix\",\"iy\",[6,\"d.i32\",[[5,\"2\"]]]]]]]]]]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.vec3f\":()=>A,mxBitsTo01:()=>Hl,mxHashInt2:()=>cn}})&&e.f)({})),Z7=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=j(ie(t.x)),r=j(ie(t.y)),o=j(ie(t.z));return A(Hl(t1(s,r,o,j(0))),Hl(t1(s,r,o,j(1))),Hl(t1(s,r,o,j(2))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"ix\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"iy\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[13,\"iz\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"z\"]]]]]],[10,[6,\"d.vec3f\",[[6,\"mxBitsTo01\",[[6,\"mxHashInt3\",[\"ix\",\"iy\",\"iz\",[6,\"d.i32\",[[5,\"0\"]]]]]]],[6,\"mxBitsTo01\",[[6,\"mxHashInt3\",[\"ix\",\"iy\",\"iz\",[6,\"d.i32\",[[5,\"1\"]]]]]]],[6,\"mxBitsTo01\",[[6,\"mxHashInt3\",[\"ix\",\"iy\",\"iz\",[6,\"d.i32\",[[5,\"2\"]]]]]]]]]]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.vec3f\":()=>A,mxBitsTo01:()=>Hl,mxHashInt3:()=>t1}})&&e.f)({})),J7=w.fn([m,j,j,j,j,n,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=Q7(m(n(__tsover_add(s,o)),n(__tsover_add(r,a)))),d=m(c.x,c.y);d=al(ra(As(d,.5),i),.5);let u=As(al(m(n(s),n(r)),d),t);return l===j(2)?__tsover_add(re(u.x),re(u.y)):l===j(3)?B(re(u.x),re(u.y)):Se(u,u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"xoff\"},{type:\"i\",name:\"yoff\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"metric\"}],body:[0,[[13,\"tmp\",[6,\"mxCellNoiseVec3_2d\",[[6,\"d.vec2f\",[[6,\"d.f32\",[[1,\"x\",\"+\",\"xoff\"]]],[6,\"d.f32\",[[1,\"y\",\"+\",\"yoff\"]]]]]]]],[12,\"off\",[6,\"d.vec2f\",[[7,\"tmp\",\"x\"],[7,\"tmp\",\"y\"]]]],[2,\"off\",\"=\",[6,\"std.add\",[[6,\"std.mul\",[[6,\"std.sub\",[\"off\",[5,\"0.5\"]]],\"jitter\"]],[5,\"0.5\"]]]],[13,\"cellpos\",[6,\"std.add\",[[6,\"d.vec2f\",[[6,\"d.f32\",[\"x\"]],[6,\"d.f32\",[\"y\"]]]],\"off\"]]],[13,\"diff\",[6,\"std.sub\",[\"cellpos\",\"p\"]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"2\"]]]],[0,[[10,[1,[6,\"std.abs\",[[7,\"diff\",\"x\"]]],\"+\",[6,\"std.abs\",[[7,\"diff\",\"y\"]]]]]]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"3\"]]]],[0,[[10,[6,\"std.max\",[[6,\"std.abs\",[[7,\"diff\",\"x\"]]],[6,\"std.abs\",[[7,\"diff\",\"y\"]]]]]]]]],[10,[6,\"std.dot\",[\"diff\",\"diff\"]]]]]},externals:{mxCellNoiseVec3_2d:()=>Q7,\"d.vec2f\":()=>m,\"d.f32\":()=>n,\"std.add\":()=>al,\"std.mul\":()=>ra,\"std.sub\":()=>As,\"d.i32\":()=>j,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.dot\":()=>Se}})&&e.f)({})),eT=w.fn([A,j,j,j,j,j,j,n,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=Z7(A(n(__tsover_add(s,a)),n(__tsover_add(r,i)),n(__tsover_add(o,l))));u=al(ra(As(u,.5),c),.5);let p=As(al(A(n(s),n(r),n(o)),u),t);return d===j(2)?__tsover_add(__tsover_add(re(p.x),re(p.y)),re(p.z)):d===j(3)?B(B(re(p.x),re(p.y)),re(p.z)):Se(p,p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"z\"},{type:\"i\",name:\"xoff\"},{type:\"i\",name:\"yoff\"},{type:\"i\",name:\"zoff\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"metric\"}],body:[0,[[12,\"off\",[6,\"mxCellNoiseVec3_3d\",[[6,\"d.vec3f\",[[6,\"d.f32\",[[1,\"x\",\"+\",\"xoff\"]]],[6,\"d.f32\",[[1,\"y\",\"+\",\"yoff\"]]],[6,\"d.f32\",[[1,\"z\",\"+\",\"zoff\"]]]]]]]],[2,\"off\",\"=\",[6,\"std.add\",[[6,\"std.mul\",[[6,\"std.sub\",[\"off\",[5,\"0.5\"]]],\"jitter\"]],[5,\"0.5\"]]]],[13,\"cellpos\",[6,\"std.add\",[[6,\"d.vec3f\",[[6,\"d.f32\",[\"x\"]],[6,\"d.f32\",[\"y\"]],[6,\"d.f32\",[\"z\"]]]],\"off\"]]],[13,\"diff\",[6,\"std.sub\",[\"cellpos\",\"p\"]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"2\"]]]],[0,[[10,[1,[1,[6,\"std.abs\",[[7,\"diff\",\"x\"]]],\"+\",[6,\"std.abs\",[[7,\"diff\",\"y\"]]]],\"+\",[6,\"std.abs\",[[7,\"diff\",\"z\"]]]]]]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"3\"]]]],[0,[[10,[6,\"std.max\",[[6,\"std.max\",[[6,\"std.abs\",[[7,\"diff\",\"x\"]]],[6,\"std.abs\",[[7,\"diff\",\"y\"]]]]],[6,\"std.abs\",[[7,\"diff\",\"z\"]]]]]]]]],[10,[6,\"std.dot\",[\"diff\",\"diff\"]]]]]},externals:{mxCellNoiseVec3_3d:()=>Z7,\"d.vec3f\":()=>A,\"d.f32\":()=>n,\"std.add\":()=>al,\"std.mul\":()=>ra,\"std.sub\":()=>As,\"d.i32\":()=>j,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.dot\":()=>Se}})&&e.f)({})),tT=w.fn([m,n,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=j(ie(t.x)),a=j(ie(t.y)),i=m(__tsover_sub(t.x,n(o)),__tsover_sub(t.y,n(a))),l=n(1e6);for(let c=-1;c<=1;c++)for(let d=-1;d<=1;d++){let u=J7(i,c,d,o,a,s,r);l=ye(l,u)}return r===j(0)&&(l=Ue(l)),l}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"metric\"}],body:[0,[[13,\"X\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"Y\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[13,\"localpos\",[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"-\",[6,\"d.f32\",[\"X\"]]],[1,[7,\"p\",\"y\"],\"-\",[6,\"d.f32\",[\"Y\"]]]]]],[12,\"sqdist\",[6,\"d.f32\",[[5,\"1000000\"]]]],[14,[12,\"x\",[4,\"-\",[5,\"1\"]]],[1,\"x\",\"<=\",[5,\"1\"]],[102,\"++\",\"x\"],[0,[[14,[12,\"y\",[4,\"-\",[5,\"1\"]]],[1,\"y\",\"<=\",[5,\"1\"]],[102,\"++\",\"y\"],[0,[[13,\"dist\",[6,\"mxWorleyDistance2d\",[\"localpos\",\"x\",\"y\",\"X\",\"Y\",\"jitter\",\"metric\"]]],[2,\"sqdist\",\"=\",[6,\"std.min\",[\"sqdist\",\"dist\"]]]]]]]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"0\"]]]],[0,[[2,\"sqdist\",\"=\",[6,\"std.sqrt\",[\"sqdist\"]]]]]],[10,\"sqdist\"]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.vec2f\":()=>m,\"d.f32\":()=>n,mxWorleyDistance2d:()=>J7,\"std.min\":()=>ye,\"std.sqrt\":()=>Ue}})&&e.f)({})),sT=w.fn([A,n,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=j(ie(t.x)),a=j(ie(t.y)),i=j(ie(t.z)),l=A(__tsover_sub(t.x,n(o)),__tsover_sub(t.y,n(a)),__tsover_sub(t.z,n(i))),c=n(1e6);for(let d=-1;d<=1;d++)for(let u=-1;u<=1;u++)for(let p=-1;p<=1;p++){let _=eT(l,d,u,p,o,a,i,s,r);c=ye(c,_)}return r===j(0)&&(c=Ue(c)),c}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"metric\"}],body:[0,[[13,\"X\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"x\"]]]]]],[13,\"Y\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"y\"]]]]]],[13,\"Z\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"p\",\"z\"]]]]]],[13,\"localpos\",[6,\"d.vec3f\",[[1,[7,\"p\",\"x\"],\"-\",[6,\"d.f32\",[\"X\"]]],[1,[7,\"p\",\"y\"],\"-\",[6,\"d.f32\",[\"Y\"]]],[1,[7,\"p\",\"z\"],\"-\",[6,\"d.f32\",[\"Z\"]]]]]],[12,\"sqdist\",[6,\"d.f32\",[[5,\"1000000\"]]]],[14,[12,\"x\",[4,\"-\",[5,\"1\"]]],[1,\"x\",\"<=\",[5,\"1\"]],[102,\"++\",\"x\"],[0,[[14,[12,\"y\",[4,\"-\",[5,\"1\"]]],[1,\"y\",\"<=\",[5,\"1\"]],[102,\"++\",\"y\"],[0,[[14,[12,\"z\",[4,\"-\",[5,\"1\"]]],[1,\"z\",\"<=\",[5,\"1\"]],[102,\"++\",\"z\"],[0,[[13,\"dist\",[6,\"mxWorleyDistance3d\",[\"localpos\",\"x\",\"y\",\"z\",\"X\",\"Y\",\"Z\",\"jitter\",\"metric\"]]],[2,\"sqdist\",\"=\",[6,\"std.min\",[\"sqdist\",\"dist\"]]]]]]]]]]]],[11,[1,\"metric\",\"===\",[6,\"d.i32\",[[5,\"0\"]]]],[0,[[2,\"sqdist\",\"=\",[6,\"std.sqrt\",[\"sqdist\"]]]]]],[10,\"sqdist\"]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,\"d.vec3f\":()=>A,\"d.f32\":()=>n,mxWorleyDistance3d:()=>eT,\"std.min\":()=>ye,\"std.sqrt\":()=>Ue}})&&e.f)({})),la=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return j7(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"mxPerlinNoiseFloat2\",[\"p\"]]]]]},externals:{mxPerlinNoiseFloat2:()=>j7}})&&e.f)({})),Na=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return K7(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"mxPerlinNoiseFloat3\",[\"p\"]]]]]},externals:{mxPerlinNoiseFloat3:()=>K7}})&&e.f)({})),I3=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return tT(t,s,j(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"jitter\"}],body:[0,[[10,[6,\"mxWorleyNoiseFloat2\",[\"p\",\"jitter\",[6,\"d.i32\",[[5,\"1\"]]]]]]]]},externals:{mxWorleyNoiseFloat2:()=>tT,\"d.i32\":()=>j}})&&e.f)({}));w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return sT(t,s,j(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"jitter\"}],body:[0,[[10,[6,\"mxWorleyNoiseFloat3\",[\"p\",\"jitter\",[6,\"d.i32\",[[5,\"1\"]]]]]]]]},externals:{mxWorleyNoiseFloat3:()=>sT,\"d.i32\":()=>j}})&&e.f)({}));var rT=w.fn([n],M)(\"(x: f32) -> u32 { return bitcast<u32>(x); }\"),Lu=w.fn([m],fe)(\"(v: vec2f) -> vec2u { return bitcast<vec2u>(v); }\"),tv=w.fn([A],id)(\"(v: vec3f) -> vec3u { return bitcast<vec3u>(v); }\"),Sn=n(4294967295),Xs=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=rT(__tsover_mul(t,3141592653));return __tsover_div(n(__tsover_mul(__tsover_mul(s,s),M(3141592653))),Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint1\",[[1,\"p\",\"*\",[5,\"3141592653\"]]]]],[10,[1,[6,\"d.f32\",[[1,[1,\"u\",\"*\",\"u\"],\"*\",[6,\"d.u32\",[[5,\"3141592653\"]]]]]],\"/\",\"U32\"]]]]},externals:{floatBitsToUint1:()=>rT,\"d.f32\":()=>n,\"d.u32\":()=>M,U32:()=>Sn}})&&e.f)({})),Ys=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Lu(t.mul(m(141421356,2718281828)));return __tsover_div(n(__tsover_mul(s.x^s.y,M(3141592653))),Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint2\",[[6,[7,\"p\",\"mul\"],[[6,\"d.vec2f\",[[5,\"141421356\"],[5,\"2718281828\"]]]]]]]],[10,[1,[6,\"d.f32\",[[1,[1,[7,\"u\",\"x\"],\"^\",[7,\"u\",\"y\"]],\"*\",[6,\"d.u32\",[[5,\"3141592653\"]]]]]],\"/\",\"U32\"]]]]},externals:{floatBitsToUint2:()=>Lu,\"d.vec2f\":()=>m,\"d.f32\":()=>n,\"d.u32\":()=>M,U32:()=>Sn}})&&e.f)({})),Pr=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Lu(t.mul(m(141421356,2718281828))),r=s.x^s.y,o=ra(fe(r,r),fe(3141592653,1618033988));return m(n(o.x),n(o.y)).div(Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint2\",[[6,[7,\"p\",\"mul\"],[[6,\"d.vec2f\",[[5,\"141421356\"],[5,\"2718281828\"]]]]]]]],[13,\"h\",[1,[7,\"u\",\"x\"],\"^\",[7,\"u\",\"y\"]]],[13,\"prod\",[6,\"std.mul\",[[6,\"d.vec2u\",[\"h\",\"h\"]],[6,\"d.vec2u\",[[5,\"3141592653\"],[5,\"1618033988\"]]]]]],[10,[6,[7,[6,\"d.vec2f\",[[6,\"d.f32\",[[7,\"prod\",\"x\"]]],[6,\"d.f32\",[[7,\"prod\",\"y\"]]]]],\"div\"],[\"U32\"]]]]]},externals:{floatBitsToUint2:()=>Lu,\"d.vec2f\":()=>m,\"std.mul\":()=>ra,\"d.vec2u\":()=>fe,\"d.f32\":()=>n,U32:()=>Sn}})&&e.f)({})),nJ=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Lu(t.mul(m(141421356,2718281828))),r=s.x^s.y,o=ra(id(r,r,r),id(1732050807,2645751311,3316624790));return A(n(o.x),n(o.y),n(o.z)).div(Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint2\",[[6,[7,\"p\",\"mul\"],[[6,\"d.vec2f\",[[5,\"141421356\"],[5,\"2718281828\"]]]]]]]],[13,\"h\",[1,[7,\"u\",\"x\"],\"^\",[7,\"u\",\"y\"]]],[13,\"prod\",[6,\"std.mul\",[[6,\"d.vec3u\",[\"h\",\"h\",\"h\"]],[6,\"d.vec3u\",[[5,\"1732050807\"],[5,\"2645751311\"],[5,\"3316624790\"]]]]]],[10,[6,[7,[6,\"d.vec3f\",[[6,\"d.f32\",[[7,\"prod\",\"x\"]]],[6,\"d.f32\",[[7,\"prod\",\"y\"]]],[6,\"d.f32\",[[7,\"prod\",\"z\"]]]]],\"div\"],[\"U32\"]]]]]},externals:{floatBitsToUint2:()=>Lu,\"d.vec2f\":()=>m,\"std.mul\":()=>ra,\"d.vec3u\":()=>id,\"d.vec3f\":()=>A,\"d.f32\":()=>n,U32:()=>Sn}})&&e.f)({})),Wb=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=tv(t.mul(A(141421356,2718281828,1618033988)));return __tsover_div(n(__tsover_mul(s.x^s.y^s.z,M(3141592653))),Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint3\",[[6,[7,\"p\",\"mul\"],[[6,\"d.vec3f\",[[5,\"141421356\"],[5,\"2718281828\"],[5,\"1618033988\"]]]]]]]],[10,[1,[6,\"d.f32\",[[1,[1,[1,[7,\"u\",\"x\"],\"^\",[7,\"u\",\"y\"]],\"^\",[7,\"u\",\"z\"]],\"*\",[6,\"d.u32\",[[5,\"3141592653\"]]]]]],\"/\",\"U32\"]]]]},externals:{floatBitsToUint3:()=>tv,\"d.vec3f\":()=>A,\"d.f32\":()=>n,\"d.u32\":()=>M,U32:()=>Sn}})&&e.f)({})),ei=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=tv(t.mul(A(141421356,2718281828,1618033988))),r=s.x^s.y^s.z,o=ra(id(r,r,r),id(1732050807,2645751311,3316624790));return A(n(o.x),n(o.y),n(o.z)).div(Sn)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"u\",[6,\"floatBitsToUint3\",[[6,[7,\"p\",\"mul\"],[[6,\"d.vec3f\",[[5,\"141421356\"],[5,\"2718281828\"],[5,\"1618033988\"]]]]]]]],[13,\"h\",[1,[1,[7,\"u\",\"x\"],\"^\",[7,\"u\",\"y\"]],\"^\",[7,\"u\",\"z\"]]],[13,\"prod\",[6,\"std.mul\",[[6,\"d.vec3u\",[\"h\",\"h\",\"h\"]],[6,\"d.vec3u\",[[5,\"1732050807\"],[5,\"2645751311\"],[5,\"3316624790\"]]]]]],[10,[6,[7,[6,\"d.vec3f\",[[6,\"d.f32\",[[7,\"prod\",\"x\"]]],[6,\"d.f32\",[[7,\"prod\",\"y\"]]],[6,\"d.f32\",[[7,\"prod\",\"z\"]]]]],\"div\"],[\"U32\"]]]]]},externals:{floatBitsToUint3:()=>tv,\"d.vec3f\":()=>A,\"std.mul\":()=>ra,\"d.vec3u\":()=>id,\"d.f32\":()=>n,U32:()=>Sn}})&&e.f)({})),Aa=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=t.sub(s),o=r.mul(r).mul(As(3,r.mul(2)));return K(K(Ys(s),Ys(s.add(m(1,0))),o.x),K(Ys(s.add(m(0,1))),Ys(s.add(m(1,1))),o.x),o.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f0\",[6,[7,\"p\",\"sub\"],[\"i\"]]],[13,\"f\",[6,[7,[6,[7,\"f0\",\"mul\"],[\"f0\"]],\"mul\"],[[6,\"std.sub\",[[5,\"3\"],[6,[7,\"f0\",\"mul\"],[[5,\"2\"]]]]]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[[6,\"hash12\",[\"i\"]],[6,\"hash12\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]]]]]],[7,\"f\",\"x\"]]],[6,\"std.mix\",[[6,\"hash12\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]]]]]],[6,\"hash12\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]],[7,\"f\",\"x\"]]],[7,\"f\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.sub\":()=>As,\"std.mix\":()=>K,hash12:()=>Ys,\"d.vec2f\":()=>m}})&&e.f)({})),om=w.fn([m,m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(r,o);return Se(vs(Pr(t.add(a)).sub(.5)),s.sub(a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"},{type:\"i\",name:\"f\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[13,\"o\",[6,\"d.vec2f\",[\"ox\",\"oy\"]]],[10,[6,\"std.dot\",[[6,\"std.normalize\",[[6,[7,[6,\"hash22\",[[6,[7,\"i\",\"add\"],[\"o\"]]]],\"sub\"],[[5,\"0.5\"]]]]],[6,[7,\"f\",\"sub\"],[\"o\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.dot\":()=>Se,\"std.normalize\":()=>vs,hash22:()=>Pr}})&&e.f)({})),Hc=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=t.sub(s),o=r.mul(r).mul(r).mul(r.mul(r.mul(6).sub(15)).add(10)),a=om(s,r,0,0),i=om(s,r,1,0),l=om(s,r,0,1),c=om(s,r,1,1);return __tsover_add(__tsover_mul(K(K(a,i,o.x),K(l,c,o.x),o.y),.7),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f\",[6,[7,\"p\",\"sub\"],[\"i\"]]],[13,\"u\",[6,[7,[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[5,\"6\"]]],\"sub\"],[[5,\"15\"]]]]],\"add\"],[[5,\"10\"]]]]]],[13,\"a\",[6,\"perlinGrad2\",[\"i\",\"f\",[5,\"0\"],[5,\"0\"]]]],[13,\"b\",[6,\"perlinGrad2\",[\"i\",\"f\",[5,\"1\"],[5,\"0\"]]]],[13,\"c\",[6,\"perlinGrad2\",[\"i\",\"f\",[5,\"0\"],[5,\"1\"]]]],[13,\"dd\",[6,\"perlinGrad2\",[\"i\",\"f\",[5,\"1\"],[5,\"1\"]]]],[10,[1,[1,[6,\"std.mix\",[[6,\"std.mix\",[\"a\",\"b\",[7,\"u\",\"x\"]]],[6,\"std.mix\",[\"c\",\"dd\",[7,\"u\",\"x\"]]],[7,\"u\",\"y\"]]],\"*\",[5,\"0.7\"]],\"+\",[5,\"0.5\"]]]]]},externals:{\"std.floor\":()=>ie,perlinGrad2:()=>om,\"std.mix\":()=>K}})&&e.f)({})),Si=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=Re(t),o=r.mul(r).mul(r).mul(r.mul(r.mul(6).sub(15)).add(10)),a=r.mul(r).mul(r.mul(r.sub(2)).add(1)).mul(30),i=Pr(s.add(m(0,0))).mul(2).sub(1),l=Pr(s.add(m(1,0))).mul(2).sub(1),c=Pr(s.add(m(0,1))).mul(2).sub(1),d=Pr(s.add(m(1,1))).mul(2).sub(1),u=Se(i,r.sub(m(0,0))),p=Se(l,r.sub(m(1,0))),_=Se(c,r.sub(m(0,1))),f=Se(d,r.sub(m(1,1))),h=__tsover_add(__tsover_sub(__tsover_sub(u,p),_),f),g=__tsover_add(__tsover_add(__tsover_add(u,__tsover_mul(o.x,__tsover_sub(p,u))),__tsover_mul(o.y,__tsover_sub(_,u))),__tsover_mul(__tsover_mul(o.x,o.y),h)),y=i.add(l.sub(i).mul(o.x)).add(c.sub(i).mul(o.y)).add(i.sub(l).sub(c).add(d).mul(__tsover_mul(o.x,o.y))).add(a.mul(m(o.y,o.x).mul(h).add(m(p,_)).sub(u)));return A(g,y.x,y.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f\",[6,\"std.fract\",[\"p\"]]],[13,\"u\",[6,[7,[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[5,\"6\"]]],\"sub\"],[[5,\"15\"]]]]],\"add\"],[[5,\"10\"]]]]]],[13,\"du\",[6,[7,[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[6,[7,\"f\",\"sub\"],[[5,\"2\"]]]]],\"add\"],[[5,\"1\"]]]]],\"mul\"],[[5,\"30\"]]]],[13,\"ga\",[6,[7,[6,[7,[6,\"hash22\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]]]]],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]],[13,\"gb\",[6,[7,[6,[7,[6,\"hash22\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]]]]]],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]],[13,\"gc\",[6,[7,[6,[7,[6,\"hash22\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]]]]]],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]],[13,\"gd\",[6,[7,[6,[7,[6,\"hash22\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]],[13,\"va\",[6,\"std.dot\",[\"ga\",[6,[7,\"f\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]]]]]],[13,\"vb\",[6,\"std.dot\",[\"gb\",[6,[7,\"f\",\"sub\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]]]]]]],[13,\"vc\",[6,\"std.dot\",[\"gc\",[6,[7,\"f\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]]]]]]],[13,\"vd\",[6,\"std.dot\",[\"gd\",[6,[7,\"f\",\"sub\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]]],[13,\"k\",[1,[1,[1,\"va\",\"-\",\"vb\"],\"-\",\"vc\"],\"+\",\"vd\"]],[13,\"value\",[1,[1,[1,\"va\",\"+\",[1,[7,\"u\",\"x\"],\"*\",[1,\"vb\",\"-\",\"va\"]]],\"+\",[1,[7,\"u\",\"y\"],\"*\",[1,\"vc\",\"-\",\"va\"]]],\"+\",[1,[1,[7,\"u\",\"x\"],\"*\",[7,\"u\",\"y\"]],\"*\",\"k\"]]],[13,\"deriv\",[6,[7,[6,[7,[6,[7,[6,[7,\"ga\",\"add\"],[[6,[7,[6,[7,\"gb\",\"sub\"],[\"ga\"]],\"mul\"],[[7,\"u\",\"x\"]]]]],\"add\"],[[6,[7,[6,[7,\"gc\",\"sub\"],[\"ga\"]],\"mul\"],[[7,\"u\",\"y\"]]]]],\"add\"],[[6,[7,[6,[7,[6,[7,[6,[7,\"ga\",\"sub\"],[\"gb\"]],\"sub\"],[\"gc\"]],\"add\"],[\"gd\"]],\"mul\"],[[1,[7,\"u\",\"x\"],\"*\",[7,\"u\",\"y\"]]]]]],\"add\"],[[6,[7,\"du\",\"mul\"],[[6,[7,[6,[7,[6,[7,[6,\"d.vec2f\",[[7,\"u\",\"y\"],[7,\"u\",\"x\"]]],\"mul\"],[\"k\"]],\"add\"],[[6,\"d.vec2f\",[\"vb\",\"vc\"]]]],\"sub\"],[\"va\"]]]]]]],[10,[6,\"d.vec3f\",[\"value\",[7,\"deriv\",\"x\"],[7,\"deriv\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,hash22:()=>Pr,\"d.vec2f\":()=>m,\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),am=w.fn([S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.mul(t.mul(34).add(1));return s.sub(ie(s.div(289)).mul(289))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"}],body:[0,[[13,\"xx\",[6,[7,\"x\",\"mul\"],[[6,[7,[6,[7,\"x\",\"mul\"],[[5,\"34\"]]],\"add\"],[[5,\"1\"]]]]]],[10,[6,[7,\"xx\",\"sub\"],[[6,[7,[6,\"std.floor\",[[6,[7,\"xx\",\"div\"],[[5,\"289\"]]]]],\"mul\"],[[5,\"289\"]]]]]]]]},externals:{\"std.floor\":()=>ie}})&&e.f)({})),iJ=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=t.sub(s),o=r.mul(r).mul(As(3,r.mul(2))),a=S(s.x,s.x,s.y,s.y).add(S(0,1,0,1)),i=am(S(a.x,a.y,a.x,a.y)),l=am(S(i.x,i.y,i.x,i.y).add(S(a.z,a.z,a.w,a.w))).add(S(s.z,s.z,s.z,s.z)),c=am(l),d=am(l.add(1)),u=K(Re(c.mul(.02439024)),Re(d.mul(.02439024)),S(o.z)),p=K(m(u.x,u.z),m(u.y,u.w),m(o.x));return K(p.x,p.y,o.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"a\",[6,\"std.floor\",[\"p\"]]],[13,\"d0\",[6,[7,\"p\",\"sub\"],[\"a\"]]],[13,\"sd\",[6,[7,[6,[7,\"d0\",\"mul\"],[\"d0\"]],\"mul\"],[[6,\"std.sub\",[[5,\"3\"],[6,[7,\"d0\",\"mul\"],[[5,\"2\"]]]]]]]],[13,\"b\",[6,[7,[6,\"d.vec4f\",[[7,\"a\",\"x\"],[7,\"a\",\"x\"],[7,\"a\",\"y\"],[7,\"a\",\"y\"]]],\"add\"],[[6,\"d.vec4f\",[[5,\"0\"],[5,\"1\"],[5,\"0\"],[5,\"1\"]]]]]],[13,\"k1\",[6,\"perm4\",[[6,\"d.vec4f\",[[7,\"b\",\"x\"],[7,\"b\",\"y\"],[7,\"b\",\"x\"],[7,\"b\",\"y\"]]]]]],[13,\"k2\",[6,[7,[6,\"perm4\",[[6,[7,[6,\"d.vec4f\",[[7,\"k1\",\"x\"],[7,\"k1\",\"y\"],[7,\"k1\",\"x\"],[7,\"k1\",\"y\"]]],\"add\"],[[6,\"d.vec4f\",[[7,\"b\",\"z\"],[7,\"b\",\"z\"],[7,\"b\",\"w\"],[7,\"b\",\"w\"]]]]]]],\"add\"],[[6,\"d.vec4f\",[[7,\"a\",\"z\"],[7,\"a\",\"z\"],[7,\"a\",\"z\"],[7,\"a\",\"z\"]]]]]],[13,\"k3\",[6,\"perm4\",[\"k2\"]]],[13,\"k4\",[6,\"perm4\",[[6,[7,\"k2\",\"add\"],[[5,\"1\"]]]]]],[13,\"o1\",[6,\"std.fract\",[[6,[7,\"k3\",\"mul\"],[[5,\"0.02439024\"]]]]]],[13,\"o2\",[6,\"std.fract\",[[6,[7,\"k4\",\"mul\"],[[5,\"0.02439024\"]]]]]],[13,\"o3\",[6,\"std.mix\",[\"o1\",\"o2\",[6,\"d.vec4f\",[[7,\"sd\",\"z\"]]]]]],[13,\"o4\",[6,\"std.mix\",[[6,\"d.vec2f\",[[7,\"o3\",\"x\"],[7,\"o3\",\"z\"]]],[6,\"d.vec2f\",[[7,\"o3\",\"y\"],[7,\"o3\",\"w\"]]],[6,\"d.vec2f\",[[7,\"sd\",\"x\"]]]]]],[10,[6,\"std.mix\",[[7,\"o4\",\"x\"],[7,\"o4\",\"y\"],[7,\"sd\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.sub\":()=>As,\"d.vec4f\":()=>S,perm4:()=>am,\"std.fract\":()=>Re,\"std.mix\":()=>K,\"d.vec2f\":()=>m}})&&e.f)({})),ji=w.fn([A,A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=A(r,o,a);return Se(s.sub(i),vs(ei(t.add(i)).sub(.5)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"},{type:\"i\",name:\"f\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"},{type:\"i\",name:\"oz\"}],body:[0,[[13,\"o\",[6,\"d.vec3f\",[\"ox\",\"oy\",\"oz\"]]],[10,[6,\"std.dot\",[[6,[7,\"f\",\"sub\"],[\"o\"]],[6,\"std.normalize\",[[6,[7,[6,\"hash33\",[[6,[7,\"i\",\"add\"],[\"o\"]]]],\"sub\"],[[5,\"0.5\"]]]]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.dot\":()=>Se,\"std.normalize\":()=>vs,hash33:()=>ei}})&&e.f)({})),mu=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=t.sub(s),o=r.mul(r).mul(r).mul(r.mul(r.mul(6).sub(15)).add(10)),a=ji(s,r,0,0,0),i=ji(s,r,1,0,0),l=ji(s,r,0,1,0),c=ji(s,r,1,1,0),d=ji(s,r,0,0,1),u=ji(s,r,1,0,1),p=ji(s,r,0,1,1),_=ji(s,r,1,1,1),f=K(K(a,i,o.x),K(l,c,o.x),o.y),h=K(K(d,u,o.x),K(p,_,o.x),o.y);return __tsover_add(__tsover_mul(K(f,h,o.z),.7),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f\",[6,[7,\"p\",\"sub\"],[\"i\"]]],[13,\"u\",[6,[7,[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[5,\"6\"]]],\"sub\"],[[5,\"15\"]]]]],\"add\"],[[5,\"10\"]]]]]],[13,\"a0\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[13,\"b0\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"1\"],[5,\"0\"],[5,\"0\"]]]],[13,\"c0\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"0\"],[5,\"1\"],[5,\"0\"]]]],[13,\"d0\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"1\"],[5,\"1\"],[5,\"0\"]]]],[13,\"a1\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]],[13,\"b1\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"1\"],[5,\"0\"],[5,\"1\"]]]],[13,\"c1\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"0\"],[5,\"1\"],[5,\"1\"]]]],[13,\"d1\",[6,\"perlinGrad3\",[\"i\",\"f\",[5,\"1\"],[5,\"1\"],[5,\"1\"]]]],[13,\"z0\",[6,\"std.mix\",[[6,\"std.mix\",[\"a0\",\"b0\",[7,\"u\",\"x\"]]],[6,\"std.mix\",[\"c0\",\"d0\",[7,\"u\",\"x\"]]],[7,\"u\",\"y\"]]]],[13,\"z1\",[6,\"std.mix\",[[6,\"std.mix\",[\"a1\",\"b1\",[7,\"u\",\"x\"]]],[6,\"std.mix\",[\"c1\",\"d1\",[7,\"u\",\"x\"]]],[7,\"u\",\"y\"]]]],[10,[1,[1,[6,\"std.mix\",[\"z0\",\"z1\",[7,\"u\",\"z\"]]],\"*\",[5,\"0.7\"]],\"+\",[5,\"0.5\"]]]]]},externals:{\"std.floor\":()=>ie,perlinGrad3:()=>ji,\"std.mix\":()=>K}})&&e.f)({})),nm=w.fn([m,m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return ae(__tsover_add(__tsover_mul(r,Se(t,Pr(s.add(m(a,i))))),o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"i\"},{type:\"i\",name:\"freq\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[10,[6,\"std.sin\",[[1,[1,\"freq\",\"*\",[6,\"std.dot\",[\"p\",[6,\"hash22\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[\"ox\",\"oy\"]]]]]]]]],\"+\",\"phase\"]]]]]]},externals:{\"std.sin\":()=>ae,\"std.dot\":()=>Se,hash22:()=>Pr,\"d.vec2f\":()=>m}})&&e.f)({})),lJ=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=ie(t),a=t.sub(o),i=a.mul(a).mul(As(3,a.mul(2)));return K(K(nm(t,o,s,r,0,0),nm(t,o,s,r,1,0),i.x),K(nm(t,o,s,r,0,1),nm(t,o,s,r,1,1),i.x),i.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"freq\"},{type:\"i\",name:\"phase\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f0\",[6,[7,\"p\",\"sub\"],[\"i\"]]],[13,\"f\",[6,[7,[6,[7,\"f0\",\"mul\"],[\"f0\"]],\"mul\"],[[6,\"std.sub\",[[5,\"3\"],[6,[7,\"f0\",\"mul\"],[[5,\"2\"]]]]]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[[6,\"gaborGrain\",[\"p\",\"i\",\"freq\",\"phase\",[5,\"0\"],[5,\"0\"]]],[6,\"gaborGrain\",[\"p\",\"i\",\"freq\",\"phase\",[5,\"1\"],[5,\"0\"]]],[7,\"f\",\"x\"]]],[6,\"std.mix\",[[6,\"gaborGrain\",[\"p\",\"i\",\"freq\",\"phase\",[5,\"0\"],[5,\"1\"]]],[6,\"gaborGrain\",[\"p\",\"i\",\"freq\",\"phase\",[5,\"1\"],[5,\"1\"]]],[7,\"f\",\"x\"]]],[7,\"f\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.sub\":()=>As,\"std.mix\":()=>K,gaborGrain:()=>nm}})&&e.f)({})),Uu=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=m(Hc(t.add(m(.1,0))),Hc(t.add(m(0,.1)))),r=m(Hc(t.sub(m(.1,0))),Hc(t.sub(m(0,.1))));return s.sub(r).div(.1).mul(.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"a\",[6,\"d.vec2f\",[[6,\"perlin12\",[[6,[7,\"p\",\"add\"],[[6,\"d.vec2f\",[[5,\"0.1\"],[5,\"0\"]]]]]]],[6,\"perlin12\",[[6,[7,\"p\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0.1\"]]]]]]]]]],[13,\"b\",[6,\"d.vec2f\",[[6,\"perlin12\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.1\"],[5,\"0\"]]]]]]],[6,\"perlin12\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0.1\"]]]]]]]]]],[10,[6,[7,[6,[7,[6,[7,\"a\",\"sub\"],[\"b\"]],\"div\"],[[5,\"0.1\"]]],\"mul\"],[[5,\"0.5\"]]]]]]},externals:{\"d.vec2f\":()=>m,perlin12:()=>Hc}})&&e.f)({})),sv=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t.add(m(.1,0)),o=t.add(m(0,.1)),a=t.sub(m(.1,0)),i=t.sub(m(0,.1)),l=m(mu(A(r.x,r.y,s)),mu(A(o.x,o.y,s))),c=m(mu(A(a.x,a.y,s)),mu(A(i.x,i.y,s)));return l.sub(c).div(.1).mul(.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"z\"}],body:[0,[[13,\"pax\",[6,[7,\"p\",\"add\"],[[6,\"d.vec2f\",[[5,\"0.1\"],[5,\"0\"]]]]]],[13,\"pay\",[6,[7,\"p\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0.1\"]]]]]],[13,\"pbx\",[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.1\"],[5,\"0\"]]]]]],[13,\"pby\",[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0.1\"]]]]]],[13,\"a\",[6,\"d.vec2f\",[[6,\"perlin13\",[[6,\"d.vec3f\",[[7,\"pax\",\"x\"],[7,\"pax\",\"y\"],\"z\"]]]],[6,\"perlin13\",[[6,\"d.vec3f\",[[7,\"pay\",\"x\"],[7,\"pay\",\"y\"],\"z\"]]]]]]],[13,\"b\",[6,\"d.vec2f\",[[6,\"perlin13\",[[6,\"d.vec3f\",[[7,\"pbx\",\"x\"],[7,\"pbx\",\"y\"],\"z\"]]]],[6,\"perlin13\",[[6,\"d.vec3f\",[[7,\"pby\",\"x\"],[7,\"pby\",\"y\"],\"z\"]]]]]]],[10,[6,[7,[6,[7,[6,[7,\"a\",\"sub\"],[\"b\"]],\"div\"],[[5,\"0.1\"]]],\"mul\"],[[5,\"0.5\"]]]]]]},externals:{\"d.vec2f\":()=>m,perlin13:()=>mu,\"d.vec3f\":()=>A}})&&e.f)({})),cJ=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=n(0),a=n(1),i=n(0),l=m(t.x,t.y);for(let c=0;c<4;c++){let d=l.mul(a),u=Re(ie(d).mul(m(123.34,233.53)));u=u.add(Se(u,u.add(23.234)));let p=__tsover_mul(Re(__tsover_mul(u.x,u.y)),1e3),_=Re(d).sub(.5),f=pe(p),h=ae(p),g=m(__tsover_sub(__tsover_mul(_.x,f),__tsover_mul(_.y,h)),__tsover_add(__tsover_mul(_.x,h),__tsover_mul(_.y,f)));o=__tsover_add(o,__tsover_div(__tsover_mul(ae(__tsover_add(__tsover_mul(g.x,10),s)),be(.25,0,Se(g,g))),a)),l=m(__tsover_sub(__tsover_mul(l.x,.54),__tsover_mul(l.y,.84)),__tsover_add(__tsover_mul(l.x,.84),__tsover_mul(l.y,.54))).add(n(c)),i=__tsover_add(i,__tsover_div(1,a)),a=__tsover_mul(a,r)}return __tsover_div(o,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"scale\"}],body:[0,[[12,\"dsum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"s\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"m\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"pp\",[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"y\"]]]],[14,[12,\"idx\",[5,\"0\"]],[1,\"idx\",\"<\",[5,\"4\"]],[102,\"++\",\"idx\"],[0,[[13,\"q0\",[6,[7,\"pp\",\"mul\"],[\"s\"]]],[12,\"g\",[6,\"std.fract\",[[6,[7,[6,\"std.floor\",[\"q0\"]],\"mul\"],[[6,\"d.vec2f\",[[5,\"123.34\"],[5,\"233.53\"]]]]]]]],[2,\"g\",\"=\",[6,[7,\"g\",\"add\"],[[6,\"std.dot\",[\"g\",[6,[7,\"g\",\"add\"],[[5,\"23.234\"]]]]]]]],[13,\"a\",[1,[6,\"std.fract\",[[1,[7,\"g\",\"x\"],\"*\",[7,\"g\",\"y\"]]]],\"*\",[5,\"1000\"]]],[13,\"qc\",[6,[7,[6,\"std.fract\",[\"q0\"]],\"sub\"],[[5,\"0.5\"]]]],[13,\"ca\",[6,\"std.cos\",[\"a\"]]],[13,\"sa\",[6,\"std.sin\",[\"a\"]]],[13,\"q\",[6,\"d.vec2f\",[[1,[1,[7,\"qc\",\"x\"],\"*\",\"ca\"],\"-\",[1,[7,\"qc\",\"y\"],\"*\",\"sa\"]],[1,[1,[7,\"qc\",\"x\"],\"*\",\"sa\"],\"+\",[1,[7,\"qc\",\"y\"],\"*\",\"ca\"]]]]],[2,\"dsum\",\"=\",[1,\"dsum\",\"+\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"q\",\"x\"],\"*\",[5,\"10\"]],\"+\",\"phase\"]]],\"*\",[6,\"std.smoothstep\",[[5,\"0.25\"],[5,\"0\"],[6,\"std.dot\",[\"q\",\"q\"]]]]],\"/\",\"s\"]]],[2,\"pp\",\"=\",[6,[7,[6,\"d.vec2f\",[[1,[1,[7,\"pp\",\"x\"],\"*\",[5,\"0.54\"]],\"-\",[1,[7,\"pp\",\"y\"],\"*\",[5,\"0.84\"]]],[1,[1,[7,\"pp\",\"x\"],\"*\",[5,\"0.84\"]],\"+\",[1,[7,\"pp\",\"y\"],\"*\",[5,\"0.54\"]]]]],\"add\"],[[6,\"d.f32\",[\"idx\"]]]]],[2,\"m\",\"=\",[1,\"m\",\"+\",[1,[5,\"1\"],\"/\",\"s\"]]],[2,\"s\",\"=\",[1,\"s\",\"*\",\"scale\"]]]]],[10,[1,\"dsum\",\"/\",\"m\"]]]]},externals:{\"d.f32\":()=>n,\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.floor\":()=>ie,\"std.dot\":()=>Se,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.smoothstep\":()=>be}})&&e.f)({})),dJ=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=n(0);for(let r=0;r<9;r++){let o=n(r),a=ie(__tsover_div(o,3)),i=__tsover_sub(o,__tsover_mul(a,3));s=__tsover_add(s,Ys(t.add(m(__tsover_sub(i,1),__tsover_sub(a,1)))))}return __tsover_add(__tsover_mul(.9,__tsover_sub(__tsover_mul(1.125,Ys(t)),__tsover_div(s,8))),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[12,\"v\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",[5,\"9\"]],[102,\"++\",\"k\"],[0,[[13,\"fk\",[6,\"d.f32\",[\"k\"]]],[13,\"row\",[6,\"std.floor\",[[1,\"fk\",\"/\",[5,\"3\"]]]]],[13,\"col\",[1,\"fk\",\"-\",[1,\"row\",\"*\",[5,\"3\"]]]],[2,\"v\",\"=\",[1,\"v\",\"+\",[6,\"hash12\",[[6,[7,\"p\",\"add\"],[[6,\"d.vec2f\",[[1,\"col\",\"-\",[5,\"1\"]],[1,\"row\",\"-\",[5,\"1\"]]]]]]]]]]]]],[10,[1,[1,[5,\"0.9\"],\"*\",[1,[1,[5,\"1.125\"],\"*\",[6,\"hash12\",[\"p\"]]],\"-\",[1,\"v\",\"/\",[5,\"8\"]]]],\"+\",[5,\"0.5\"]]]]]},externals:{\"d.f32\":()=>n,\"std.floor\":()=>ie,hash12:()=>Ys,\"d.vec2f\":()=>m}})&&e.f)({})),oT=w.fn([nc],j)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=j(0),r=t.x,o=t.y;for(let a=256;a>0;a=a>>1){let i=j(a),l=N(j(0),j(1),(r&i)>0),c=N(j(0),j(1),(o&i)>0),d=l<<1|l^c;s=__tsover_add(s,__tsover_mul(__tsover_mul(i,i),d));let u=__tsover_sub(j(1),c),p=__tsover_mul(r^o,u)^__tsover_mul(j(__tsover_sub(a,1)),l&u);r=r^p,o=o^p}return s}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[12,\"i\",[6,\"d.i32\",[[5,\"0\"]]]],[12,\"px\",[7,\"p\",\"x\"]],[12,\"py\",[7,\"p\",\"y\"]],[14,[12,\"s\",[5,\"256\"]],[1,\"s\",\">\",[5,\"0\"]],[2,\"s\",\"=\",[1,\"s\",\">>\",[5,\"1\"]]],[0,[[13,\"S\",[6,\"d.i32\",[\"s\"]]],[13,\"rx\",[6,\"std.select\",[[6,\"d.i32\",[[5,\"0\"]]],[6,\"d.i32\",[[5,\"1\"]]],[1,[1,\"px\",\"&\",\"S\"],\">\",[5,\"0\"]]]]],[13,\"ry\",[6,\"std.select\",[[6,\"d.i32\",[[5,\"0\"]]],[6,\"d.i32\",[[5,\"1\"]]],[1,[1,\"py\",\"&\",\"S\"],\">\",[5,\"0\"]]]]],[13,\"dq\",[1,[1,\"rx\",\"<<\",[5,\"1\"]],\"|\",[1,\"rx\",\"^\",\"ry\"]]],[2,\"i\",\"=\",[1,\"i\",\"+\",[1,[1,\"S\",\"*\",\"S\"],\"*\",\"dq\"]]],[13,\"oneMinusRy\",[1,[6,\"d.i32\",[[5,\"1\"]]],\"-\",\"ry\"]],[13,\"rhs\",[1,[1,[1,\"px\",\"^\",\"py\"],\"*\",\"oneMinusRy\"],\"^\",[1,[6,\"d.i32\",[[1,\"s\",\"-\",[5,\"1\"]]]],\"*\",[1,\"rx\",\"&\",\"oneMinusRy\"]]]],[2,\"px\",\"=\",[1,\"px\",\"^\",\"rhs\"]],[2,\"py\",\"=\",[1,\"py\",\"^\",\"rhs\"]]]]],[10,\"i\"]]]},externals:{\"d.i32\":()=>j,\"std.select\":()=>N}})&&e.f)({}));w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=oT(nc(j(t.x),j(t.y)))&j(262143);return Re(__tsover_mul(.6180339887498949,n(s)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"idx\",[1,[6,\"hilbertEncode512\",[[6,\"d.vec2i\",[[6,\"d.i32\",[[7,\"p\",\"x\"]]],[6,\"d.i32\",[[7,\"p\",\"y\"]]]]]]],\"&\",[6,\"d.i32\",[[5,\"262143\"]]]]],[10,[6,\"std.fract\",[[1,[5,\"0.6180339887498949\"],\"*\",[6,\"d.f32\",[\"idx\"]]]]]]]]},externals:{hilbertEncode512:()=>oT,\"d.vec2i\":()=>nc,\"d.i32\":()=>j,\"std.fract\":()=>Re,\"d.f32\":()=>n}})&&e.f)({}));var aT=w.fn([m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=ie(t),i=t.sub(a),l=ie(__tsover_mul(ae(__tsover_mul(a.x,51024)),3104)),c=ie(__tsover_mul(ae(__tsover_mul(a.y,1324)),554)),d=__tsover_add(l,c),u=i.mul(2).sub(1);u=u.mul(pe(d)).add(m(-u.y,u.x).mul(ae(d))),u=u.add(ae(__tsover_sub(l,c))),u=u.mul(.5).add(.5);let p=__tsover_mul(__tsover_add(ae(__tsover_add(l,__tsover_mul(u.y,Math.PI))),ae(__tsover_add(c,__tsover_mul(u.y,Math.PI)))),.2),_=re(__tsover_add(__tsover_sub(u.x,.5),p));_=__tsover_sub(.5,__tsover_mul(_,__tsover_div(s,o))),_=__tsover_mul(be(-2,__tsover_add(__tsover_mul(mr(_),1.5),16),_),12);let f=__tsover_add(__tsover_mul(ae(__tsover_add(r,__tsover_mul(Ys(a),6.2831853))),.5),.5);return __tsover_mul(__tsover_mul(_,u.y),f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"f\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"thickness\"}],body:[0,[[13,\"seed0\",[6,\"std.floor\",[\"uv\"]]],[13,\"lo\",[6,[7,\"uv\",\"sub\"],[\"seed0\"]]],[13,\"sx\",[6,\"std.floor\",[[1,[6,\"std.sin\",[[1,[7,\"seed0\",\"x\"],\"*\",[5,\"51024\"]]]],\"*\",[5,\"3104\"]]]]],[13,\"sy\",[6,\"std.floor\",[[1,[6,\"std.sin\",[[1,[7,\"seed0\",\"y\"],\"*\",[5,\"1324\"]]]],\"*\",[5,\"554\"]]]]],[13,\"ss\",[1,\"sx\",\"+\",\"sy\"]],[12,\"u2\",[6,[7,[6,[7,\"lo\",\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]],[2,\"u2\",\"=\",[6,[7,[6,[7,\"u2\",\"mul\"],[[6,\"std.cos\",[\"ss\"]]]],\"add\"],[[6,[7,[6,\"d.vec2f\",[[4,\"-\",[7,\"u2\",\"y\"]],[7,\"u2\",\"x\"]]],\"mul\"],[[6,\"std.sin\",[\"ss\"]]]]]]],[2,\"u2\",\"=\",[6,[7,\"u2\",\"add\"],[[6,\"std.sin\",[[1,\"sx\",\"-\",\"sy\"]]]]]],[2,\"u2\",\"=\",[6,[7,[6,[7,\"u2\",\"mul\"],[[5,\"0.5\"]]],\"add\"],[[5,\"0.5\"]]]],[13,\"WAVYNESS\",[5,\"0.2\"]],[13,\"sVal\",[1,[1,[6,\"std.sin\",[[1,\"sx\",\"+\",[1,[7,\"u2\",\"y\"],\"*\",\"Math.PI\"]]]],\"+\",[6,\"std.sin\",[[1,\"sy\",\"+\",[1,[7,\"u2\",\"y\"],\"*\",\"Math.PI\"]]]]],\"*\",\"WAVYNESS\"]],[12,\"x\",[6,\"std.abs\",[[1,[1,[7,\"u2\",\"x\"],\"-\",[5,\"0.5\"]],\"+\",\"sVal\"]]]],[2,\"x\",\"=\",[1,[5,\"0.5\"],\"-\",[1,\"x\",\"*\",[1,\"f\",\"/\",\"thickness\"]]]],[2,\"x\",\"=\",[1,[6,\"std.smoothstep\",[[4,\"-\",[5,\"2\"]],[1,[1,[6,\"std.fwidth\",[\"x\"]],\"*\",[5,\"1.5\"]],\"+\",[5,\"16\"]],\"x\"]],\"*\",[5,\"12\"]]],[13,\"pulse\",[1,[1,[6,\"std.sin\",[[1,\"time\",\"+\",[1,[6,\"hash12\",[\"seed0\"]],\"*\",[5,\"6.2831853\"]]]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[10,[1,[1,\"x\",\"*\",[7,\"u2\",\"y\"]],\"*\",\"pulse\"]]]]},externals:{\"std.floor\":()=>ie,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"d.vec2f\":()=>m,\"Math.PI\":()=>Math.PI,\"std.abs\":()=>re,\"std.smoothstep\":()=>be,\"std.fwidth\":()=>mr,hash12:()=>Ys}})&&e.f)({})),uJ=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=n(0),a=m(t.x,t.y),i=__tsover_div(1,he(mr(t)));for(let l=0;l<8;l++)o=B(o,aT(a,i,s,r)),a=m(__tsover_add(a.x,__tsover_mul(a.y,.7)),__tsover_add(__tsover_mul(a.x,-.7),a.y)).sub(12.31);return o}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"thickness\"}],body:[0,[[12,\"scratches\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"p\",[6,\"d.vec2f\",[[7,\"uv\",\"x\"],[7,\"uv\",\"y\"]]]],[13,\"f\",[1,[5,\"1\"],\"/\",[6,\"std.length\",[[6,\"std.fwidth\",[\"uv\"]]]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"8\"]],[102,\"++\",\"i\"],[0,[[2,\"scratches\",\"=\",[6,\"std.max\",[\"scratches\",[6,\"scratchOne\",[\"p\",\"f\",\"time\",\"thickness\"]]]]],[2,\"p\",\"=\",[6,[7,[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",[5,\"0.7\"]]],[1,[1,[7,\"p\",\"x\"],\"*\",[4,\"-\",[5,\"0.7\"]]],\"+\",[7,\"p\",\"y\"]]]],\"sub\"],[[5,\"12.31\"]]]]]]],[10,\"scratches\"]]]},externals:{\"d.f32\":()=>n,\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.fwidth\":()=>mr,\"std.max\":()=>B,scratchOne:()=>aT}})&&e.f)({})),nT=w.fn([m,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=n(0),o=n(0),a=n(1),i=m(t.x,t.y);for(let l=0;l<s;l++)r=__tsover_add(r,__tsover_mul(a,Hc(i))),o=__tsover_add(o,a),a=__tsover_mul(a,.5),i=i.mul(2);return __tsover_div(r,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"octaves\"}],body:[0,[[12,\"s\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"m\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"a\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"pp\",[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"y\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"octaves\"],[102,\"++\",\"i\"],[0,[[2,\"s\",\"=\",[1,\"s\",\"+\",[1,\"a\",\"*\",[6,\"perlin12\",[\"pp\"]]]]],[2,\"m\",\"=\",[1,\"m\",\"+\",\"a\"]],[2,\"a\",\"=\",[1,\"a\",\"*\",[5,\"0.5\"]]],[2,\"pp\",\"=\",[6,[7,\"pp\",\"mul\"],[[5,\"2\"]]]]]]],[10,[1,\"s\",\"/\",\"m\"]]]]},externals:{\"d.f32\":()=>n,\"d.vec2f\":()=>m,perlin12:()=>Hc}})&&e.f)({})),iT=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=A(0,0,0),r=n(1),o=m(t.x,t.y);for(let a=0;a<6;a++)s=s.add(Si(o).mul(r)),r=__tsover_mul(r,.5),o=o.mul(2);return s}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[12,\"s\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[12,\"a\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"pp\",[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"y\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"6\"]],[102,\"++\",\"i\"],[0,[[2,\"s\",\"=\",[6,[7,\"s\",\"add\"],[[6,[7,[6,\"perlin12d\",[\"pp\"]],\"mul\"],[\"a\"]]]]],[2,\"a\",\"=\",[1,\"a\",\"*\",[5,\"0.5\"]]],[2,\"pp\",\"=\",[6,[7,\"pp\",\"mul\"],[[5,\"2\"]]]]]]],[10,\"s\"]]]},externals:{\"d.vec3f\":()=>A,\"d.f32\":()=>n,\"d.vec2f\":()=>m,perlin12d:()=>Si}})&&e.f)({})),pJ=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=iT(t);return nT(t.add(m(s.y,s.z).mul(.4)),j(6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"fs\",[6,\"fbmStone\",[\"p\"]]],[10,[6,\"fbmPerlin\",[[6,[7,\"p\",\"add\"],[[6,[7,[6,\"d.vec2f\",[[7,\"fs\",\"y\"],[7,\"fs\",\"z\"]]],\"mul\"],[[5,\"0.4\"]]]]],[6,\"d.i32\",[[5,\"6\"]]]]]]]]},externals:{fbmStone:()=>iT,fbmPerlin:()=>nT,\"d.vec2f\":()=>m,\"d.i32\":()=>j}})&&e.f)({})),lT=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=m(0,0),r=n(0),o=n(1),a=m(t.x,t.y);for(let i=0;i<6;i++)s=s.add(Uu(a).mul(o)),r=__tsover_add(r,o),o=__tsover_mul(o,.5),a=a.mul(2);return s.div(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[12,\"s\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"m\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"a\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"pp\",[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"y\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"6\"]],[102,\"++\",\"i\"],[0,[[2,\"s\",\"=\",[6,[7,\"s\",\"add\"],[[6,[7,[6,\"curl22\",[\"pp\"]],\"mul\"],[\"a\"]]]]],[2,\"m\",\"=\",[1,\"m\",\"+\",\"a\"]],[2,\"a\",\"=\",[1,\"a\",\"*\",[5,\"0.5\"]]],[2,\"pp\",\"=\",[6,[7,\"pp\",\"mul\"],[[5,\"2\"]]]]]]],[10,[6,[7,\"s\",\"div\"],[\"m\"]]]]]},externals:{\"d.vec2f\":()=>m,\"d.f32\":()=>n,curl22:()=>Uu}})&&e.f)({})),mJ=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=lT(t);return B(re(s.x),re(s.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"n\",[6,\"fbmWool\",[\"p\"]]],[10,[6,\"std.max\",[[6,\"std.abs\",[[7,\"n\",\"x\"]]],[6,\"std.abs\",[[7,\"n\",\"y\"]]]]]]]]},externals:{fbmWool:()=>lT,\"std.max\":()=>B,\"std.abs\":()=>re}})&&e.f)({})),cT=w.fn([m,m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=m(-s.y,s.x).mul(Math.PI),o=ie(t),a=t.sub(o),i=m(0,0),l=n(0);for(let c=-1;c<=2;c++)for(let d=-1;d<=2;d++){let u=m(n(c),n(d)),p=a.sub(u).sub(Pr(o.add(u))).add(.5),_=Se(p,p),f=B(n(0),__tsover_sub(Tt(__tsover_mul(_,-2)),.01111));l=__tsover_add(l,f);let h=Se(p,r);i=i.add(m(pe(h),-ae(h)).mul(f))}return A(i.x,__tsover_mul(i.y,r.x),__tsover_mul(i.y,r.y)).div(l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"slope\"}],body:[0,[[13,\"sideDir\",[6,[7,[6,\"d.vec2f\",[[4,\"-\",[7,\"slope\",\"y\"]],[7,\"slope\",\"x\"]]],\"mul\"],[\"Math.PI\"]]],[13,\"id\",[6,\"std.floor\",[\"p\"]]],[13,\"pp\",[6,[7,\"p\",\"sub\"],[\"id\"]]],[12,\"heightSlope\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"wSum\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"x\",[4,\"-\",[5,\"1\"]]],[1,\"x\",\"<=\",[5,\"2\"]],[102,\"++\",\"x\"],[0,[[14,[12,\"y\",[4,\"-\",[5,\"1\"]]],[1,\"y\",\"<=\",[5,\"2\"]],[102,\"++\",\"y\"],[0,[[13,\"off\",[6,\"d.vec2f\",[[6,\"d.f32\",[\"x\"]],[6,\"d.f32\",[\"y\"]]]]],[13,\"c\",[6,[7,[6,[7,[6,[7,\"pp\",\"sub\"],[\"off\"]],\"sub\"],[[6,\"hash22\",[[6,[7,\"id\",\"add\"],[\"off\"]]]]]],\"add\"],[[5,\"0.5\"]]]],[13,\"dist2\",[6,\"std.dot\",[\"c\",\"c\"]]],[13,\"w\",[6,\"std.max\",[[6,\"d.f32\",[[5,\"0\"]]],[1,[6,\"std.exp\",[[1,\"dist2\",\"*\",[4,\"-\",[5,\"2\"]]]]],\"-\",[5,\"0.01111\"]]]]],[2,\"wSum\",\"=\",[1,\"wSum\",\"+\",\"w\"]],[13,\"t\",[6,\"std.dot\",[\"c\",\"sideDir\"]]],[2,\"heightSlope\",\"=\",[6,[7,\"heightSlope\",\"add\"],[[6,[7,[6,\"d.vec2f\",[[6,\"std.cos\",[\"t\"]],[4,\"-\",[6,\"std.sin\",[\"t\"]]]]],\"mul\"],[\"w\"]]]]]]]]]]],[10,[6,[7,[6,\"d.vec3f\",[[7,\"heightSlope\",\"x\"],[1,[7,\"heightSlope\",\"y\"],\"*\",[7,\"sideDir\",\"x\"]],[1,[7,\"heightSlope\",\"y\"],\"*\",[7,\"sideDir\",\"y\"]]]],\"div\"],[\"wSum\"]]]]]},externals:{\"d.vec2f\":()=>m,\"Math.PI\":()=>Math.PI,\"std.floor\":()=>ie,\"d.f32\":()=>n,hash22:()=>Pr,\"std.dot\":()=>Se,\"std.max\":()=>B,\"std.exp\":()=>Tt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec3f\":()=>A}})&&e.f)({})),_J=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Si(t),r=n(.25),o=n(8),a=n(1);for(let i=0;i<4;i++){let l=m(s.y,s.z),c=B(Se(l,l),n(1e-4)),d=l.mul(vt(c,n(__tsover_mul(.5,__tsover_sub(.5,1)))));s=s.add(cT(t.mul(o),d).mul(r).mul(A(1,o,o))),a=__tsover_add(a,r),r=__tsover_mul(r,.5),o=__tsover_mul(o,2)}return s.div(a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[12,\"nd\",[6,\"perlin12d\",[\"p\"]]],[12,\"strength\",[6,\"d.f32\",[[5,\"0.25\"]]]],[12,\"freq\",[6,\"d.f32\",[[5,\"8\"]]]],[12,\"total\",[6,\"d.f32\",[[5,\"1\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"4\"]],[102,\"++\",\"i\"],[0,[[13,\"grad\",[6,\"d.vec2f\",[[7,\"nd\",\"y\"],[7,\"nd\",\"z\"]]]],[13,\"len2\",[6,\"std.max\",[[6,\"std.dot\",[\"grad\",\"grad\"]],[6,\"d.f32\",[[5,\"0.0001\"]]]]]],[13,\"slope\",[6,[7,\"grad\",\"mul\"],[[6,\"std.pow\",[\"len2\",[6,\"d.f32\",[[1,[5,\"0.5\"],\"*\",[1,[5,\"0.5\"],\"-\",[5,\"1\"]]]]]]]]]],[2,\"nd\",\"=\",[6,[7,\"nd\",\"add\"],[[6,[7,[6,[7,[6,\"gullies\",[[6,[7,\"p\",\"mul\"],[\"freq\"]],\"slope\"]],\"mul\"],[\"strength\"]],\"mul\"],[[6,\"d.vec3f\",[[5,\"1\"],\"freq\",\"freq\"]]]]]]],[2,\"total\",\"=\",[1,\"total\",\"+\",\"strength\"]],[2,\"strength\",\"=\",[1,\"strength\",\"*\",[5,\"0.5\"]]],[2,\"freq\",\"=\",[1,\"freq\",\"*\",[5,\"2\"]]]]]],[10,[6,[7,\"nd\",\"div\"],[\"total\"]]]]]},externals:{perlin12d:()=>Si,\"d.f32\":()=>n,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.dot\":()=>Se,\"std.pow\":()=>vt,gullies:()=>cT,\"d.vec3f\":()=>A}})&&e.f)({})),dT=w.fn([m,j],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=m(0,0),o=n(0),a=n(1),i=m(t.x,t.y);for(let l=0;l<s;l++)r=r.add(G(Uu(i).mul(.5).add(.5),m(0,0),m(1,1)).mul(a)),o=__tsover_add(o,a),a=__tsover_mul(a,.8),i=i.mul(2);return r.div(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"octaves\"}],body:[0,[[12,\"s\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"m\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"a\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"pp\",[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"y\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"octaves\"],[102,\"++\",\"i\"],[0,[[2,\"s\",\"=\",[6,[7,\"s\",\"add\"],[[6,[7,[6,\"std.clamp\",[[6,[7,[6,[7,[6,\"curl22\",[\"pp\"]],\"mul\"],[[5,\"0.5\"]]],\"add\"],[[5,\"0.5\"]]],[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]],\"mul\"],[\"a\"]]]]],[2,\"m\",\"=\",[1,\"m\",\"+\",\"a\"]],[2,\"a\",\"=\",[1,\"a\",\"*\",[5,\"0.8\"]]],[2,\"pp\",\"=\",[6,[7,\"pp\",\"mul\"],[[5,\"2\"]]]]]]],[10,[6,[7,\"s\",\"div\"],[\"m\"]]]]]},externals:{\"d.vec2f\":()=>m,\"d.f32\":()=>n,\"std.clamp\":()=>G,curl22:()=>Uu}})&&e.f)({})),uT=w.fn([m,j],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_add(__tsover_mul(__tsover_div(he(dT(t,s)),1.414),.6),.4)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"octaves\"}],body:[0,[[10,[1,[1,[1,[6,\"std.length\",[[6,\"fbmPaper\",[\"p\",\"octaves\"]]]],\"/\",[5,\"1.414\"]],\"*\",[5,\"0.6\"]],\"+\",[5,\"0.4\"]]]]]},externals:{\"std.length\":()=>he,fbmPaper:()=>dT}})&&e.f)({}));w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(__tsover_add(__tsover_mul(t.x,.2126),__tsover_mul(t.y,.7152)),__tsover_mul(t.z,.0722))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[1,[1,[1,[7,\"rgb\",\"x\"],\"*\",[5,\"0.2126\"]],\"+\",[1,[7,\"rgb\",\"y\"],\"*\",[5,\"0.7152\"]]],\"+\",[1,[7,\"rgb\",\"z\"],\"*\",[5,\"0.0722\"]]]]]]},externals:{}})&&e.f)({}));w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(__tsover_add(__tsover_mul(t.x,.299),__tsover_mul(t.y,.587)),__tsover_mul(t.z,.114))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[1,[1,[1,[7,\"rgb\",\"x\"],\"*\",[5,\"0.299\"]],\"+\",[1,[7,\"rgb\",\"y\"],\"*\",[5,\"0.587\"]]],\"+\",[1,[7,\"rgb\",\"z\"],\"*\",[5,\"0.114\"]]]]]]},externals:{}})&&e.f)({}));var pT=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Se(t,A(.2126,.7152,.0722))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),rv=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Se(t,A(.299,.587,.114))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({}));w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return G(__tsover_add(__tsover_mul(__tsover_sub(t,r),s),r),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"pivot\"}],body:[0,[[10,[6,\"std.clamp\",[[1,[1,[1,\"x\",\"-\",\"pivot\"],\"*\",\"contrast\"],\"+\",\"pivot\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({}));var fJ=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(__tsover_mul(t,.5),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[10,[1,[1,\"v\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]},externals:{}})&&e.f)({}));w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_sub(1,re(t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.abs\",[\"v\"]]]]]]},externals:{\"std.abs\":()=>re}})&&e.f)({}));var zk=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=G(__tsover_add(__tsover_add(__tsover_mul(__tsover_sub(t,.5),__tsover_add(s,1)),.5),r),0,1);return __tsover_sub(1,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"noise01\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"balance\"}],body:[0,[[13,\"k\",[6,\"std.clamp\",[[1,[1,[1,[1,\"noise01\",\"-\",[5,\"0.5\"]],\"*\",[1,\"contrast\",\"+\",[5,\"1\"]]],\"+\",[5,\"0.5\"]],\"+\",\"balance\"],[5,\"0\"],[5,\"1\"]]]],[10,[1,[5,\"1\"],\"-\",\"k\"]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({})),Rk=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_add(__tsover_mul(t,__tsover_add(s,1)),r),a=G(__tsover_add(__tsover_mul(o,.5),.5),0,1);return __tsover_sub(1,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"balance\"}],body:[0,[[13,\"adjusted\",[1,[1,\"v\",\"*\",[1,\"contrast\",\"+\",[5,\"1\"]]],\"+\",\"balance\"]],[13,\"k\",[6,\"std.clamp\",[[1,[1,\"adjusted\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[10,[1,[5,\"1\"],\"-\",\"k\"]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({})),vJ=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(__tsover_mul(t,2),1),a=__tsover_add(__tsover_mul(o,s),r);return G(__tsover_add(__tsover_mul(a,.5),.5),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"balance\"}],body:[0,[[13,\"signed\",[1,[1,\"v\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"adjusted\",[1,[1,\"signed\",\"*\",\"contrast\"],\"+\",\"balance\"]],[10,[6,\"std.clamp\",[[1,[1,\"adjusted\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({})),hJ=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=vt(t,__tsover_div(5,s)),i=G(__tsover_add(__tsover_mul(__tsover_sub(a,.5),r),.5),0,1),l=__tsover_sub(__tsover_div(o,100),.5),c=G(__tsover_add(i,l),0,1);return __tsover_sub(1,c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"glow\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"balance\"}],body:[0,[[13,\"spread\",[6,\"std.pow\",[\"v\",[1,[5,\"5\"],\"/\",\"glow\"]]]],[13,\"contrasted\",[6,\"std.clamp\",[[1,[1,[1,\"spread\",\"-\",[5,\"0.5\"]],\"*\",\"contrast\"],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"balanceShift\",[1,[1,\"balance\",\"/\",[5,\"100\"]],\"-\",[5,\"0.5\"]]],[13,\"balanced\",[6,\"std.clamp\",[[1,\"contrasted\",\"+\",\"balanceShift\"],[5,\"0\"],[5,\"1\"]]]],[10,[1,[5,\"1\"],\"-\",\"balanced\"]]]]},externals:{\"std.pow\":()=>vt,\"std.clamp\":()=>G}})&&e.f)({}));function Dk(e){let{domain:t,contrastMode:s,invert:r,glowGamma:o=!1,balance:a=\"plain\"}=e;if(o){if(t===\"unit\"&&s===\"multiplicative\"&&r&&a===\"percentCentred\")return hJ}else if(a===\"plain\"){if(t===\"unit\"&&s===\"additive\"&&r)return zk;if(t===\"signed\"&&s===\"additive\"&&r)return Rk;if(t===\"unit\"&&s===\"multiplicative\"&&!r)return vJ}throw new Error(`toneRemap: no variant for {domain: '${t}', contrastMode: '${s}', invert: ${r}, glowGamma: ${o}, balance: '${a}'} \\u2014 add its body to kit/tone.ts rather than approximating.`)}var gJ=w.fn([S,m,m,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Ys(s.mul(r).add(m(o,__tsover_mul(o,1.618))));return S(G(t.xyz.add(__tsover_mul(__tsover_sub(a,.5),.004)),A(0),A(1)),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"n\",[6,\"hash12\",[[6,[7,[6,[7,\"uv\",\"mul\"],[\"viewport\"]],\"add\"],[[6,\"d.vec2f\",[\"animTime\",[1,\"animTime\",\"*\",[5,\"1.618\"]]]]]]]]],[13,\"rgb\",[6,\"std.clamp\",[[6,[7,[7,\"base\",\"xyz\"],\"add\"],[[1,[1,\"n\",\"-\",[5,\"0.5\"]],\"*\",[5,\"0.004\"]]]],[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[10,[6,\"d.vec4f\",[\"rgb\",[7,\"base\",\"w\"]]]]]]},externals:{hash12:()=>Ys,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Cs=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_div(t.x,B(t.y,1e-6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"viewport\"}],body:[0,[[10,[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]]]]},externals:{\"std.max\":()=>B}})&&e.f)({})),Ou=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_sub(t,__tsover_mul(s,ie(__tsover_div(t,s))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"m\"}],body:[0,[[10,[1,\"x\",\"-\",[1,\"m\",\"*\",[6,\"std.floor\",[[1,\"x\",\"/\",\"m\"]]]]]]]]},externals:{\"std.floor\":()=>ie}})&&e.f)({})),n0=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(__tsover_sub(t.x,__tsover_mul(s.x,ie(__tsover_div(t.x,s.x)))),__tsover_sub(t.y,__tsover_mul(s.y,ie(__tsover_div(t.y,s.y)))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"m\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"-\",[1,[7,\"m\",\"x\"],\"*\",[6,\"std.floor\",[[1,[7,\"p\",\"x\"],\"/\",[7,\"m\",\"x\"]]]]]],[1,[7,\"p\",\"y\"],\"-\",[1,[7,\"m\",\"y\"],\"*\",[6,\"std.floor\",[[1,[7,\"p\",\"y\"],\"/\",[7,\"m\",\"y\"]]]]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.floor\":()=>ie}})&&e.f)({}));w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=N(B(s,1e-5),ye(s,-1e-5),s<0);return __tsover_div(t,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"n\"},{type:\"i\",name:\"den\"}],body:[0,[[13,\"guarded\",[6,\"std.select\",[[6,\"std.max\",[\"den\",[5,\"0.00001\"]]],[6,\"std.min\",[\"den\",[4,\"-\",[5,\"0.00001\"]]]],[1,\"den\",\"<\",[5,\"0\"]]]]],[10,[1,\"n\",\"/\",\"guarded\"]]]]},externals:{\"std.select\":()=>N,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({}));var Pn=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(__tsover_sub(__tsover_mul(t.x,s),__tsover_mul(t.y,r)),__tsover_add(__tsover_mul(t.x,r),__tsover_mul(t.y,s)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"cosA\"},{type:\"i\",name:\"sinA\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[7,\"p\",\"x\"],\"*\",\"cosA\"],\"-\",[1,[7,\"p\",\"y\"],\"*\",\"sinA\"]],[1,[1,[7,\"p\",\"x\"],\"*\",\"sinA\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"cosA\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),mT=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(s.x,B(s.y,1e-6));return m(__tsover_mul(t.x,r),t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),ov=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(s.x,B(s.y,1e-6));return m(__tsover_mul(t.x,r),__tsover_sub(1,t.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"uv\",\"y\"]]]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),i0=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return m(t.x,__tsover_sub(1,t.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"d.vec2f\",[[7,\"p\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"p\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Zi=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(__tsover_mul(t.x,s),__tsover_sub(1,t.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"aspect\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"pos\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"pos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),cc=w.fn([m,m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(r.x,B(r.y,1e-6));return m(__tsover_sub(__tsover_mul(t.x,o),__tsover_mul(s.x,o)),__tsover_sub(t.y,__tsover_sub(1,s.y)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,[7,\"center\",\"x\"],\"*\",\"aspect\"]],[1,[7,\"uv\",\"y\"],\"-\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),dc=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(__tsover_sub(__tsover_mul(t.x,s),__tsover_mul(s,.5)),__tsover_sub(t.y,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,\"aspect\",\"*\",[5,\"0.5\"]]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Gu=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,.5),i=.5,l=__tsover_sub(t.x,a),c=__tsover_sub(t.y,i);return m(__tsover_add(__tsover_sub(__tsover_mul(l,r),__tsover_mul(c,o)),a),__tsover_add(__tsover_add(__tsover_mul(l,o),__tsover_mul(c,r)),i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"cosA\"},{type:\"i\",name:\"sinA\"}],body:[0,[[13,\"centerX\",[1,\"aspect\",\"*\",[5,\"0.5\"]]],[13,\"centerY\",[5,\"0.5\"]],[13,\"cx\",[1,[7,\"p\",\"x\"],\"-\",\"centerX\"]],[13,\"cy\",[1,[7,\"p\",\"y\"],\"-\",\"centerY\"]],[10,[6,\"d.vec2f\",[[1,[1,[1,\"cx\",\"*\",\"cosA\"],\"-\",[1,\"cy\",\"*\",\"sinA\"]],\"+\",\"centerX\"],[1,[1,[1,\"cx\",\"*\",\"sinA\"],\"+\",[1,\"cy\",\"*\",\"cosA\"]],\"+\",\"centerY\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),av=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_add(__tsover_mul(t.x,s),__tsover_mul(t.y,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"cosA\"},{type:\"i\",name:\"sinA\"}],body:[0,[[10,[1,[1,[7,\"p\",\"x\"],\"*\",\"cosA\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"sinA\"]]]]]},externals:{}})&&e.f)({}));w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return m(he(t),Xt(t.y,t.x))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"d.vec2f\",[[6,\"std.length\",[\"p\"]],[6,\"std.atan2\",[[7,\"p\",\"y\"],[7,\"p\",\"x\"]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.atan2\":()=>Xt}})&&e.f)({}));w.fn([n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(__tsover_mul(t,pe(s)),__tsover_mul(t,ae(s)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"r\"},{type:\"i\",name:\"theta\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,\"r\",\"*\",[6,\"std.cos\",[\"theta\"]]],[1,\"r\",\"*\",[6,\"std.sin\",[\"theta\"]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({}));var _T=2/Math.sqrt(3),l0=gt({cell:m,local:m}).$name(\"CellTile\"),Fu=w.fn([m],l0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return l0({cell:ie(t),local:Re(t)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"CellTile\",[[104,{cell:[6,\"std.floor\",[\"p\"]],local:[6,\"std.fract\",[\"p\"]]}]]]]]]},externals:{CellTile:()=>l0,\"std.floor\":()=>ie,\"std.fract\":()=>Re}})&&e.f)({})),c0=gt({gv:m,id:m}).$name(\"HexCell\"),nv=w.fn([m,m],c0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=s.mul(.5),o=n0(t,s).sub(r),a=n0(t.sub(r),s).sub(r),i=N(a,o,Se(o,o)<Se(a,a));return c0({gv:i,id:t.sub(i)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"s\"}],body:[0,[[13,\"sh\",[6,[7,\"s\",\"mul\"],[[5,\"0.5\"]]]],[13,\"a\",[6,[7,[6,\"flooredMod2\",[\"p\",\"s\"]],\"sub\"],[\"sh\"]]],[13,\"b\",[6,[7,[6,\"flooredMod2\",[[6,[7,\"p\",\"sub\"],[\"sh\"]],\"s\"]],\"sub\"],[\"sh\"]]],[13,\"gv\",[6,\"std.select\",[\"b\",\"a\",[1,[6,\"std.dot\",[\"a\",\"a\"]],\"<\",[6,\"std.dot\",[\"b\",\"b\"]]]]]],[10,[6,\"HexCell\",[[104,{gv:\"gv\",id:[6,[7,\"p\",\"sub\"],[\"gv\"]]}]]]]]]},externals:{flooredMod2:()=>n0,\"std.select\":()=>N,\"std.dot\":()=>Se,HexCell:()=>c0}})&&e.f)({})),fT=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return m(__tsover_sub(t.x,__tsover_div(t.y,lc)),__tsover_mul(t.y,_T))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"-\",[1,[7,\"p\",\"y\"],\"/\",\"SQRT3\"]],[1,[7,\"p\",\"y\"],\"*\",\"TWO_OVER_SQRT3\"]]]]]]},externals:{\"d.vec2f\":()=>m,SQRT3:()=>lc,TWO_OVER_SQRT3:()=>_T}})&&e.f)({})),yJ=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(s.x,B(s.y,1e-6)),a=__tsover_mul(t.x,o),i=__tsover_sub(1,t.y),l=__tsover_div(__tsover_add(ie(__tsover_mul(a,r)),.5),r),c=__tsover_div(__tsover_add(ie(__tsover_mul(i,r)),.5),r);return m(__tsover_div(l,o),__tsover_sub(1,c))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[13,\"correctedX\",[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"]],[13,\"correctedY\",[1,[5,\"1\"],\"-\",[7,\"uv\",\"y\"]]],[13,\"cellCenterCorrectedX\",[1,[1,[6,\"std.floor\",[[1,\"correctedX\",\"*\",\"cells\"]]],\"+\",[5,\"0.5\"]],\"/\",\"cells\"]],[13,\"cellCenterCorrectedY\",[1,[1,[6,\"std.floor\",[[1,\"correctedY\",\"*\",\"cells\"]]],\"+\",[5,\"0.5\"]],\"/\",\"cells\"]],[10,[6,\"d.vec2f\",[[1,\"cellCenterCorrectedX\",\"/\",\"aspect\"],[1,[5,\"1\"],\"-\",\"cellCenterCorrectedY\"]]]]]]},externals:{\"std.max\":()=>B,\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),vT=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_div(s.x,B(s.y,1e-6)),i=__tsover_mul(t.x,a),l=__tsover_sub(1,t.y),c=pe(o),d=ae(o),u=__tsover_mul(a,.5),p=.5,_=__tsover_sub(i,u),f=__tsover_sub(l,p),h=__tsover_add(__tsover_sub(__tsover_mul(_,c),__tsover_mul(f,d)),u),g=__tsover_add(__tsover_add(__tsover_mul(_,d),__tsover_mul(f,c)),p),y=__tsover_div(__tsover_add(ie(__tsover_mul(h,r)),.5),r),b=__tsover_div(__tsover_add(ie(__tsover_mul(g,r)),.5),r),x=__tsover_sub(y,u),P=__tsover_sub(b,p),C=__tsover_add(__tsover_add(__tsover_mul(x,c),__tsover_mul(P,d)),u),E=__tsover_add(__tsover_add(__tsover_mul(x,-d),__tsover_mul(P,c)),p);return m(__tsover_div(C,a),__tsover_sub(1,E))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"rotationRad\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[13,\"correctedX\",[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"]],[13,\"correctedY\",[1,[5,\"1\"],\"-\",[7,\"uv\",\"y\"]]],[13,\"cosR\",[6,\"std.cos\",[\"rotationRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotationRad\"]]],[13,\"centerX\",[1,\"aspect\",\"*\",[5,\"0.5\"]]],[13,\"centerY\",[5,\"0.5\"]],[13,\"cx\",[1,\"correctedX\",\"-\",\"centerX\"]],[13,\"cy\",[1,\"correctedY\",\"-\",\"centerY\"]],[13,\"rotX\",[1,[1,[1,\"cx\",\"*\",\"cosR\"],\"-\",[1,\"cy\",\"*\",\"sinR\"]],\"+\",\"centerX\"]],[13,\"rotY\",[1,[1,[1,\"cx\",\"*\",\"sinR\"],\"+\",[1,\"cy\",\"*\",\"cosR\"]],\"+\",\"centerY\"]],[13,\"cellRX\",[1,[1,[6,\"std.floor\",[[1,\"rotX\",\"*\",\"cells\"]]],\"+\",[5,\"0.5\"]],\"/\",\"cells\"]],[13,\"cellRY\",[1,[1,[6,\"std.floor\",[[1,\"rotY\",\"*\",\"cells\"]]],\"+\",[5,\"0.5\"]],\"/\",\"cells\"]],[13,\"ccx\",[1,\"cellRX\",\"-\",\"centerX\"]],[13,\"ccy\",[1,\"cellRY\",\"-\",\"centerY\"]],[13,\"unrotX\",[1,[1,[1,\"ccx\",\"*\",\"cosR\"],\"+\",[1,\"ccy\",\"*\",\"sinR\"]],\"+\",\"centerX\"]],[13,\"unrotY\",[1,[1,[1,\"ccx\",\"*\",[4,\"-\",\"sinR\"]],\"+\",[1,\"ccy\",\"*\",\"cosR\"]],\"+\",\"centerY\"]],[10,[6,\"d.vec2f\",[[1,\"unrotX\",\"/\",\"aspect\"],[1,[5,\"1\"],\"-\",\"unrotY\"]]]]]]},externals:{\"std.max\":()=>B,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),iv=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Re(t.mul(m(123.34,345.45))),r=s.add(Se(s,s.add(34.345)));return Re(__tsover_mul(r.x,r.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"id\"}],body:[0,[[13,\"q0\",[6,\"std.fract\",[[6,[7,\"id\",\"mul\"],[[6,\"d.vec2f\",[[5,\"123.34\"],[5,\"345.45\"]]]]]]]],[13,\"q1\",[6,[7,\"q0\",\"add\"],[[6,\"std.dot\",[\"q0\",[6,[7,\"q0\",\"add\"],[[5,\"34.345\"]]]]]]]],[10,[6,\"std.fract\",[[1,[7,\"q1\",\"x\"],\"*\",[7,\"q1\",\"y\"]]]]]]]},externals:{\"std.fract\":()=>Re,\"d.vec2f\":()=>m,\"std.dot\":()=>Se}})&&e.f)({})),lv=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Re(__tsover_mul(ae(__tsover_mul(t,127.1)),43758.5453))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"row\"}],body:[0,[[10,[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,\"row\",\"*\",[5,\"127.1\"]]]],\"*\",[5,\"43758.5453\"]]]]]]]},externals:{\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({})),cv=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_add(1,__tsover_mul(__tsover_mul(__tsover_sub(t,.5),4),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rowHash\"},{type:\"i\",name:\"variance\"}],body:[0,[[10,[1,[5,\"1\"],\"+\",[1,[1,[1,\"rowHash\",\"-\",[5,\"0.5\"]],\"*\",[5,\"4\"]],\"*\",\"variance\"]]]]]},externals:{}})&&e.f)({})),hT=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return B(__tsover_add(1,__tsover_mul(__tsover_mul(__tsover_sub(t,.5),2),s)),0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rand\"},{type:\"i\",name:\"variation\"}],body:[0,[[10,[6,\"std.max\",[[1,[5,\"1\"],\"+\",[1,[1,[1,\"rand\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",\"variation\"]],[5,\"0\"]]]]]]},externals:{\"std.max\":()=>B}})&&e.f)({})),dv=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=B(re(Bu(t)),re(zu(t)));return B(__tsover_add(r,s),1e-5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"baseW\",[6,\"std.max\",[[6,\"std.abs\",[[6,\"std.dpdx\",[\"x\"]]]],[6,\"std.abs\",[[6,\"std.dpdy\",[\"x\"]]]]]]],[10,[6,\"std.max\",[[1,\"baseW\",\"+\",\"softness\"],[5,\"0.00001\"]]]]]]},externals:{\"std.max\":()=>B,\"std.abs\":()=>re,\"std.dpdx\":()=>Bu,\"std.dpdy\":()=>zu}})&&e.f)({})),gT=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Bu(t),o=zu(t),a=m(B(re(r.x),re(o.x)),B(re(r.y),re(o.y)));return m(B(__tsover_add(a.x,s),1e-5),B(__tsover_add(a.y,s),1e-5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"dpx\",[6,\"std.dpdx\",[\"p\"]]],[13,\"dpy\",[6,\"std.dpdy\",[\"p\"]]],[13,\"baseW\",[6,\"d.vec2f\",[[6,\"std.max\",[[6,\"std.abs\",[[7,\"dpx\",\"x\"]]],[6,\"std.abs\",[[7,\"dpy\",\"x\"]]]]],[6,\"std.max\",[[6,\"std.abs\",[[7,\"dpx\",\"y\"]]],[6,\"std.abs\",[[7,\"dpy\",\"y\"]]]]]]]],[10,[6,\"d.vec2f\",[[6,\"std.max\",[[1,[7,\"baseW\",\"x\"],\"+\",\"softness\"],[5,\"0.00001\"]]],[6,\"std.max\",[[1,[7,\"baseW\",\"y\"],\"+\",\"softness\"],[5,\"0.00001\"]]]]]]]]},externals:{\"std.dpdx\":()=>Bu,\"std.dpdy\":()=>zu,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.abs\":()=>re}})&&e.f)({})),yT=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_add(t,__tsover_mul(s,.5)),a=__tsover_sub(t,__tsover_mul(s,.5)),i=__tsover_sub(1,r),l=__tsover_add(__tsover_mul(ie(o),i),B(__tsover_sub(Re(o),r),0)),c=__tsover_add(__tsover_mul(ie(a),i),B(__tsover_sub(Re(a),r),0));return G(__tsover_div(__tsover_sub(l,c),s),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"w\"},{type:\"i\",name:\"threshold\"}],body:[0,[[13,\"a\",[1,\"p\",\"+\",[1,\"w\",\"*\",[5,\"0.5\"]]]],[13,\"b\",[1,\"p\",\"-\",[1,\"w\",\"*\",[5,\"0.5\"]]]],[13,\"oneMinusThreshold\",[1,[5,\"1\"],\"-\",\"threshold\"]],[13,\"Fa\",[1,[1,[6,\"std.floor\",[\"a\"]],\"*\",\"oneMinusThreshold\"],\"+\",[6,\"std.max\",[[1,[6,\"std.fract\",[\"a\"]],\"-\",\"threshold\"],[5,\"0\"]]]]],[13,\"Fb\",[1,[1,[6,\"std.floor\",[\"b\"]],\"*\",\"oneMinusThreshold\"],\"+\",[6,\"std.max\",[[1,[6,\"std.fract\",[\"b\"]],\"-\",\"threshold\"],[5,\"0\"]]]]],[10,[6,\"std.clamp\",[[1,[1,\"Fa\",\"-\",\"Fb\"],\"/\",\"w\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.max\":()=>B,\"std.fract\":()=>Re,\"std.clamp\":()=>G}})&&e.f)({})),d0=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_add(t,__tsover_mul(s,.5)),a=__tsover_sub(t,__tsover_mul(s,.5));return __tsover_div(__tsover_sub(__tsover_sub(__tsover_add(ie(o),ye(__tsover_mul(Re(o),r),1)),ie(a)),ye(__tsover_mul(Re(a),r),1)),__tsover_mul(r,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"w\"},{type:\"i\",name:\"N\"}],body:[0,[[13,\"a\",[1,\"p\",\"+\",[1,\"w\",\"*\",[5,\"0.5\"]]]],[13,\"b\",[1,\"p\",\"-\",[1,\"w\",\"*\",[5,\"0.5\"]]]],[10,[1,[1,[1,[1,[6,\"std.floor\",[\"a\"]],\"+\",[6,\"std.min\",[[1,[6,\"std.fract\",[\"a\"]],\"*\",\"N\"],[5,\"1\"]]]],\"-\",[6,\"std.floor\",[\"b\"]]],\"-\",[6,\"std.min\",[[1,[6,\"std.fract\",[\"b\"]],\"*\",\"N\"],[5,\"1\"]]]],\"/\",[1,\"N\",\"*\",\"w\"]]]]]},externals:{\"std.floor\":()=>ie,\"std.min\":()=>ye,\"std.fract\":()=>Re}})&&e.f)({})),bT=w.fn([m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=m(__tsover_mul(s.x,.5),__tsover_mul(s.y,.5)),o=re(__tsover_sub(Re(__tsover_mul(__tsover_sub(t.x,r.x),.5)),.5)),a=re(__tsover_sub(Re(__tsover_mul(__tsover_sub(t.y,r.y),.5)),.5)),i=re(__tsover_sub(Re(__tsover_mul(__tsover_add(t.x,r.x),.5)),.5)),l=re(__tsover_sub(Re(__tsover_mul(__tsover_add(t.y,r.y),.5)),.5)),c=__tsover_div(__tsover_mul(__tsover_sub(o,i),2),s.x),d=__tsover_div(__tsover_mul(__tsover_sub(a,l),2),s.y);return G(__tsover_sub(.5,__tsover_mul(__tsover_mul(c,d),.5)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"w\"}],body:[0,[[13,\"aHalf\",[6,\"d.vec2f\",[[1,[7,\"w\",\"x\"],\"*\",[5,\"0.5\"]],[1,[7,\"w\",\"y\"],\"*\",[5,\"0.5\"]]]]],[13,\"minusSideX\",[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,[1,[7,\"p\",\"x\"],\"-\",[7,\"aHalf\",\"x\"]],\"*\",[5,\"0.5\"]]]],\"-\",[5,\"0.5\"]]]]],[13,\"minusSideY\",[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,[1,[7,\"p\",\"y\"],\"-\",[7,\"aHalf\",\"y\"]],\"*\",[5,\"0.5\"]]]],\"-\",[5,\"0.5\"]]]]],[13,\"plusSideX\",[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,[1,[7,\"p\",\"x\"],\"+\",[7,\"aHalf\",\"x\"]],\"*\",[5,\"0.5\"]]]],\"-\",[5,\"0.5\"]]]]],[13,\"plusSideY\",[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,[1,[7,\"p\",\"y\"],\"+\",[7,\"aHalf\",\"y\"]],\"*\",[5,\"0.5\"]]]],\"-\",[5,\"0.5\"]]]]],[13,\"iX\",[1,[1,[1,\"minusSideX\",\"-\",\"plusSideX\"],\"*\",[5,\"2\"]],\"/\",[7,\"w\",\"x\"]]],[13,\"iY\",[1,[1,[1,\"minusSideY\",\"-\",\"plusSideY\"],\"*\",[5,\"2\"]],\"/\",[7,\"w\",\"y\"]]],[10,[6,\"std.clamp\",[[1,[5,\"0.5\"],\"-\",[1,[1,\"iX\",\"*\",\"iY\"],\"*\",[5,\"0.5\"]]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.fract\":()=>Re,\"std.clamp\":()=>G}})&&e.f)({})),uv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return __tsover_mul(__tsover_sub(1,be(r,o,t)),Et(1e-4,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"field\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"lo\"},{type:\"i\",name:\"hi\"}],body:[0,[[10,[1,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"lo\",\"hi\",\"field\"]]],\"*\",[6,\"std.step\",[[5,\"0.0001\"],\"lineWidth\"]]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.step\":()=>Et}})&&e.f)({})),xu=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_mul(be(s,r,t),be(s,r,__tsover_sub(1,t)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"lo\"},{type:\"i\",name:\"hi\"}],body:[0,[[10,[1,[6,\"std.smoothstep\",[\"lo\",\"hi\",\"x\"]],\"*\",[6,\"std.smoothstep\",[\"lo\",\"hi\",[1,[5,\"1\"],\"-\",\"x\"]]]]]]]},externals:{\"std.smoothstep\":()=>be}})&&e.f)({})),xT=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_sub(1,be(__tsover_sub(s,__tsover_mul(r,.5)),s,t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"footprint\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"radius\",\"-\",[1,\"footprint\",\"*\",[5,\"0.5\"]]],\"radius\",\"dist\"]]]]]]},externals:{\"std.smoothstep\":()=>be}})&&e.f)({})),bJ=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Cs(s);return m(__tsover_mul(t.x,a),t.y).mul(Tt(r)).add(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[10,[6,[7,[6,[7,\"aspectUV\",\"mul\"],[[6,\"std.exp\",[\"scale\"]]]],\"add\"],[\"seed\"]]]]]},externals:{aspectOf:()=>Cs,\"d.vec2f\":()=>m,\"std.exp\":()=>Tt}})&&e.f)({})),xJ=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return ie(t.mul(s).div(r)).add(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"grain\"},{type:\"i\",name:\"seed\"}],body:[0,[[10,[6,[7,[6,\"std.floor\",[[6,[7,[6,[7,\"uv\",\"mul\"],[\"viewport\"]],\"div\"],[\"grain\"]]]],\"add\"],[\"seed\"]]]]]},externals:{\"std.floor\":()=>ie}})&&e.f)({})),AJ=w.fn([m,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return A(t.x,t.y,__tsover_mul(s,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"rate\"}],body:[0,[[10,[6,\"d.vec3f\",[[7,\"pos\",\"x\"],[7,\"pos\",\"y\"],[1,\"t\",\"*\",\"rate\"]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),AT=new WeakMap,wJ=0;function Y3(e){let t=e,s=AT.get(t);if(s!==void 0)return s;let r=wJ++;return AT.set(t,r),r}function Lk(e,t){let{maxOctaves:s,drift:r,stride:o=[17,31],name:a=\"fbmGated\"}=t,i=`${Y3(e)}|${a}|${s}|${r}|${o[0]},${o[1]}`,l=wT.get(i);if(l)return l;let c=s,d=o[0],u=o[1],p=`${r===\"goldenAngle\"?\"Golden\":\"TimeSeed\"}${c}`,_;if(r===\"goldenAngle\"){let f=e;_=w.fn([m,n,n,n,n,m,n],m)((h=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(h.f=((g,y,b,x,P,C,E)=>{\"use gpu\";let R=j(E),U=y,L=n(1),k=n(0),D=n(0);for(let O=0;O<c;O++){let F=n(O),q=pe(__tsover_mul(F,2.3999632297286535)),Y=ae(__tsover_mul(F,2.3999632297286535)),V=m(__tsover_add(__tsover_add(__tsover_mul(g.x,U),__tsover_mul(P,q)),C.x),__tsover_add(__tsover_add(__tsover_mul(g.y,U),__tsover_mul(P,Y)),C.y)),X=N(n(0),n(1),O<R);k=__tsover_add(k,__tsover_mul(__tsover_mul(f(V),L),X)),D=__tsover_add(D,__tsover_mul(L,X)),U=__tsover_mul(U,b),L=__tsover_mul(L,x)}return m(k,D)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"baseFreq\"},{type:\"i\",name:\"lacunarity\"},{type:\"i\",name:\"persistence\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"seedOffset\"},{type:\"i\",name:\"octaveCount\"}],body:[0,[[13,\"n\",[6,\"d.i32\",[\"octaveCount\"]]],[12,\"freq\",\"baseFreq\"],[12,\"weight\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"accumulated\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"totalWeight\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"N\"],[102,\"++\",\"i\"],[0,[[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"dirX\",[6,\"std.cos\",[[1,\"fi\",\"*\",\"GOLDEN\"]]]],[13,\"dirY\",[6,\"std.sin\",[[1,\"fi\",\"*\",\"GOLDEN\"]]]],[13,\"coord\",[6,\"d.vec2f\",[[1,[1,[1,[7,\"base\",\"x\"],\"*\",\"freq\"],\"+\",[1,\"animTime\",\"*\",\"dirX\"]],\"+\",[7,\"seedOffset\",\"x\"]],[1,[1,[1,[7,\"base\",\"y\"],\"*\",\"freq\"],\"+\",[1,\"animTime\",\"*\",\"dirY\"]],\"+\",[7,\"seedOffset\",\"y\"]]]]],[13,\"active\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"i\",\"<\",\"n\"]]]],[2,\"accumulated\",\"=\",[1,\"accumulated\",\"+\",[1,[1,[6,\"octaveField\",[\"coord\"]],\"*\",\"weight\"],\"*\",\"active\"]]],[2,\"totalWeight\",\"=\",[1,\"totalWeight\",\"+\",[1,\"weight\",\"*\",\"active\"]]],[2,\"freq\",\"=\",[1,\"freq\",\"*\",\"lacunarity\"]],[2,\"weight\",\"=\",[1,\"weight\",\"*\",\"persistence\"]]]]],[10,[6,\"d.vec2f\",[\"accumulated\",\"totalWeight\"]]]]]},externals:{\"d.i32\":()=>j,\"d.f32\":()=>n,N:()=>c,\"std.cos\":()=>pe,GOLDEN:()=>2.3999632297286535,\"std.sin\":()=>ae,\"d.vec2f\":()=>m,\"std.select\":()=>N,octaveField:()=>f}})&&h.f)({})).$name(`${a}${p}`)}else{let f=e;_=w.fn([m,n,n,n,n,n,A,n],m)((h=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(h.f=((g,y,b,x,P,C,E,R)=>{\"use gpu\";let U=y,L=n(1),k=n(0),D=n(0);for(let O=0;O<c;O++){let F=n(O),q=N(n(0),n(1),F<R),Y=f(m(__tsover_mul(g.x,U),__tsover_mul(g.y,U)),__tsover_add(P,__tsover_mul(F,d)),__tsover_add(C,__tsover_mul(F,u)),E.x,E.y,E.z);k=__tsover_add(k,__tsover_mul(__tsover_mul(Y,L),q)),D=__tsover_add(D,__tsover_mul(L,q)),L=__tsover_mul(L,x),U=__tsover_mul(U,b)}return m(k,D)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"baseFreq\"},{type:\"i\",name:\"lacunarity\"},{type:\"i\",name:\"persistence\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"extra\"},{type:\"i\",name:\"octaveCount\"}],body:[0,[[12,\"freq\",\"baseFreq\"],[12,\"amp\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"accumulated\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"totalWeight\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"o\",[5,\"0\"]],[1,\"o\",\"<\",\"N\"],[102,\"++\",\"o\"],[0,[[13,\"fo\",[6,\"d.f32\",[\"o\"]]],[13,\"active\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"fo\",\"<\",\"octaveCount\"]]]],[13,\"oUV\",[6,\"d.vec2f\",[[1,[7,\"base\",\"x\"],\"*\",\"freq\"],[1,[7,\"base\",\"y\"],\"*\",\"freq\"]]]],[13,\"animT\",[1,\"animTime\",\"+\",[1,\"fo\",\"*\",\"TIME_STRIDE\"]]],[13,\"seedOff\",[1,\"seed\",\"+\",[1,\"fo\",\"*\",\"SEED_STRIDE\"]]],[13,\"raw\",[6,\"octaveField\",[\"oUV\",\"animT\",\"seedOff\",[7,\"extra\",\"x\"],[7,\"extra\",\"y\"],[7,\"extra\",\"z\"]]]],[2,\"accumulated\",\"=\",[1,\"accumulated\",\"+\",[1,[1,\"raw\",\"*\",\"amp\"],\"*\",\"active\"]]],[2,\"totalWeight\",\"=\",[1,\"totalWeight\",\"+\",[1,\"amp\",\"*\",\"active\"]]],[2,\"amp\",\"=\",[1,\"amp\",\"*\",\"persistence\"]],[2,\"freq\",\"=\",[1,\"freq\",\"*\",\"lacunarity\"]]]]],[10,[6,\"d.vec2f\",[\"accumulated\",\"totalWeight\"]]]]]},externals:{\"d.f32\":()=>n,N:()=>c,\"std.select\":()=>N,\"d.vec2f\":()=>m,TIME_STRIDE:()=>d,SEED_STRIDE:()=>u,octaveField:()=>f}})&&h.f)({})).$name(`${a}${p}`)}return wT.set(i,_),_}var wT=new Map,Uk={q:[[.3,-.2,0],[5.2,1.3,.25]],r:[[1.7,9.2,.15],[8.3,2.8,.13]]};function Ok(e,t={}){let{offsets:s=Uk,name:r=\"domainWarp2\"}=t,o=`${Y3(e)}|${r}|${JSON.stringify(s)}`,a=pv.get(o);if(a)return a;let i=e,[l,c,d]=s.q[0],[u,p,_]=s.q[1],[f,h,g]=s.r[0],[y,b,x]=s.r[1],P=w.fn([A,n,n],A)((C=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(C.f=((E,R,U)=>{\"use gpu\";let L=i(E.add(A(__tsover_mul(R,l),__tsover_mul(R,c),d))),k=i(E.add(A(u,p,__tsover_mul(R,_)))),D=E.add(A(L,k,0).mul(U)),O=i(D.add(A(f,h,__tsover_mul(R,g)))),F=i(D.add(A(y,b,__tsover_mul(R,x))));return E.add(A(O,F,0).mul(U))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"warpAmount\"}],body:[0,[[13,\"qx\",[6,\"warpField\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec3f\",[[1,\"t\",\"*\",\"QX\"],[1,\"t\",\"*\",\"QY\"],\"QZ\"]]]]]]],[13,\"qy\",[6,\"warpField\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec3f\",[\"Q2X\",\"Q2Y\",[1,\"t\",\"*\",\"Q2Z\"]]]]]]]],[13,\"warped1\",[6,[7,\"pos\",\"add\"],[[6,[7,[6,\"d.vec3f\",[\"qx\",\"qy\",[5,\"0\"]]],\"mul\"],[\"warpAmount\"]]]]],[13,\"rx\",[6,\"warpField\",[[6,[7,\"warped1\",\"add\"],[[6,\"d.vec3f\",[\"RX\",\"RY\",[1,\"t\",\"*\",\"RZ\"]]]]]]]],[13,\"ry\",[6,\"warpField\",[[6,[7,\"warped1\",\"add\"],[[6,\"d.vec3f\",[\"R2X\",\"R2Y\",[1,\"t\",\"*\",\"R2Z\"]]]]]]]],[10,[6,[7,\"pos\",\"add\"],[[6,[7,[6,\"d.vec3f\",[\"rx\",\"ry\",[5,\"0\"]]],\"mul\"],[\"warpAmount\"]]]]]]]},externals:{warpField:()=>i,\"d.vec3f\":()=>A,QX:()=>l,QY:()=>c,QZ:()=>d,Q2X:()=>u,Q2Y:()=>p,Q2Z:()=>_,RX:()=>f,RY:()=>h,RZ:()=>g,R2X:()=>y,R2Y:()=>b,R2Z:()=>x}})&&C.f)({})).$name(r);return pv.set(o,P),P}function TJ(e,t={}){let{offsets:s=Uk,name:r=\"domainWarp1\"}=t,o=`1|${Y3(e)}|${r}|${JSON.stringify(s)}`,a=pv.get(o);if(a)return a;let i=e,[l,c,d]=s.q[0],[u,p,_]=s.q[1],f=w.fn([A,n,n],A)((h=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(h.f=((g,y,b)=>{\"use gpu\";let x=i(g.add(A(__tsover_mul(y,l),__tsover_mul(y,c),d))),P=i(g.add(A(u,p,__tsover_mul(y,_))));return g.add(A(x,P,0).mul(b))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"warpAmount\"}],body:[0,[[13,\"qx\",[6,\"warpField\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec3f\",[[1,\"t\",\"*\",\"QX\"],[1,\"t\",\"*\",\"QY\"],\"QZ\"]]]]]]],[13,\"qy\",[6,\"warpField\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec3f\",[\"Q2X\",\"Q2Y\",[1,\"t\",\"*\",\"Q2Z\"]]]]]]]],[10,[6,[7,\"pos\",\"add\"],[[6,[7,[6,\"d.vec3f\",[\"qx\",\"qy\",[5,\"0\"]]],\"mul\"],[\"warpAmount\"]]]]]]]},externals:{warpField:()=>i,\"d.vec3f\":()=>A,QX:()=>l,QY:()=>c,QZ:()=>d,Q2X:()=>u,Q2Y:()=>p,Q2Z:()=>_}})&&h.f)({})).$name(r);return pv.set(o,f),f}var pv=new Map,SJ=w.fn([m,n,m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(t.x,s),t.y),l=m(__tsover_mul(r.x,s),__tsover_sub(1,r.y)),c=he(i.sub(l));return be(o,__tsover_add(o,a),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"falloff\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dist\",[6,\"std.length\",[[6,[7,\"aspectUV\",\"sub\"],[\"centerPos\"]]]]],[10,[6,\"std.smoothstep\",[\"radius\",[1,\"radius\",\"+\",\"falloff\"],\"dist\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.smoothstep\":()=>be}})&&e.f)({})),u0=.11,mv=.6180339887,Mm=8,TT=w.fn([n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_add(__tsover_mul(t,2.3999632297286535),__tsover_mul(Xs(__tsover_add(__tsover_mul(r,.7311),1.618)),Jt)),c=Ue(__tsover_div(__tsover_add(t,.5),s)),d=Pr(m(__tsover_add(__tsover_mul(t,3.77),.917),__tsover_add(__tsover_mul(r,1.093),2.236))).sub(.5).mul(.26),u=Pr(m(__tsover_add(__tsover_mul(t,7.13),1.618),__tsover_add(__tsover_mul(r,.531),3.71))).mul(Jt),p=__tsover_add(.5,__tsover_mul(Xs(__tsover_add(__tsover_add(__tsover_mul(t,5.417),__tsover_mul(r,.291)),.917)),.7)),_=ae(__tsover_add(__tsover_mul(__tsover_mul(i,u0),p),u.x)),f=pe(__tsover_add(__tsover_mul(__tsover_mul(__tsover_mul(i,u0),p),1.37),u.y)),h=__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(pe(l),c),.62),d.x),__tsover_mul(__tsover_mul(_,o),.16)),g=__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(ae(l),c),.62),d.y),__tsover_mul(__tsover_mul(f,o),.16));return m(__tsover_mul(__tsover_add(.5,h),a),__tsover_add(.5,g))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"drift\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"theta\",[1,[1,\"fi\",\"*\",\"GOLDEN\"],\"+\",[1,[6,\"hash11\",[[1,[1,\"seed\",\"*\",[5,\"0.7311\"]],\"+\",[5,\"1.618\"]]]],\"*\",\"TAU\"]]],[13,\"r\",[6,\"std.sqrt\",[[1,[1,\"fi\",\"+\",[5,\"0.5\"]],\"/\",\"count\"]]]],[13,\"j\",[6,[7,[6,[7,[6,\"hash22\",[[6,\"d.vec2f\",[[1,[1,\"fi\",\"*\",[5,\"3.77\"]],\"+\",[5,\"0.917\"]],[1,[1,\"seed\",\"*\",[5,\"1.093\"]],\"+\",[5,\"2.236\"]]]]]],\"sub\"],[[5,\"0.5\"]]],\"mul\"],[[5,\"0.26\"]]]],[13,\"ph\",[6,[7,[6,\"hash22\",[[6,\"d.vec2f\",[[1,[1,\"fi\",\"*\",[5,\"7.13\"]],\"+\",[5,\"1.618\"]],[1,[1,\"seed\",\"*\",[5,\"0.531\"]],\"+\",[5,\"3.71\"]]]]]],\"mul\"],[\"TAU\"]]],[13,\"w1\",[1,[5,\"0.5\"],\"+\",[1,[6,\"hash11\",[[1,[1,[1,\"fi\",\"*\",[5,\"5.417\"]],\"+\",[1,\"seed\",\"*\",[5,\"0.291\"]]],\"+\",[5,\"0.917\"]]]],\"*\",[5,\"0.7\"]]]],[13,\"dx\",[6,\"std.sin\",[[1,[1,[1,\"animTime\",\"*\",\"SCATTER_DRIFT_RATE\"],\"*\",\"w1\"],\"+\",[7,\"ph\",\"x\"]]]]],[13,\"dy\",[6,\"std.cos\",[[1,[1,[1,[1,\"animTime\",\"*\",\"SCATTER_DRIFT_RATE\"],\"*\",\"w1\"],\"*\",[5,\"1.37\"]],\"+\",[7,\"ph\",\"y\"]]]]],[13,\"nx\",[1,[1,[1,[1,[6,\"std.cos\",[\"theta\"]],\"*\",\"r\"],\"*\",[5,\"0.62\"]],\"+\",[7,\"j\",\"x\"]],\"+\",[1,[1,\"dx\",\"*\",\"drift\"],\"*\",[5,\"0.16\"]]]],[13,\"ny\",[1,[1,[1,[1,[6,\"std.sin\",[\"theta\"]],\"*\",\"r\"],\"*\",[5,\"0.62\"]],\"+\",[7,\"j\",\"y\"]],\"+\",[1,[1,\"dy\",\"*\",\"drift\"],\"*\",[5,\"0.16\"]]]],[10,[6,\"d.vec2f\",[[1,[1,[5,\"0.5\"],\"+\",\"nx\"],\"*\",\"aspect\"],[1,[5,\"0.5\"],\"+\",\"ny\"]]]]]]},externals:{GOLDEN:()=>2.3999632297286535,hash11:()=>Xs,TAU:()=>Jt,\"std.sqrt\":()=>Ue,hash22:()=>Pr,\"d.vec2f\":()=>m,\"std.sin\":()=>ae,SCATTER_DRIFT_RATE:()=>u0,\"std.cos\":()=>pe}})&&e.f)({})),PJ=w.fn([m,n,n,Fe(S,Mm/2),n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=n(0),l=n(0),c=Xs(__tsover_add(__tsover_mul(r,.531),.77));for(let d=0;d<Mm;d++){let u=n(d),p=N(n(0),n(1),u<__tsover_sub(s,.5)),_=o[__tsover_div(d,2)],f=N(_.xy,_.zw,(d&1)===1),h=B(he(t.sub(f)),.01),g=__tsover_div(p,vt(h,a)),y=Re(__tsover_add(__tsover_mul(u,mv),c));i=__tsover_add(i,__tsover_mul(g,y)),l=__tsover_add(l,g)}return __tsover_div(i,B(l,1e-6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"anchors\"},{type:\"i\",name:\"power\"}],body:[0,[[12,\"num\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"den\",[6,\"d.f32\",[[5,\"0\"]]]],[13,\"seedShuffle\",[6,\"hash11\",[[1,[1,\"seed\",\"*\",[5,\"0.531\"]],\"+\",[5,\"0.77\"]]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"SCATTER_MAX\"],[102,\"++\",\"i\"],[0,[[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"active\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"fi\",\"<\",[1,\"count\",\"-\",[5,\"0.5\"]]]]]],[13,\"pair\",[8,\"anchors\",[1,\"i\",\"/\",[5,\"2\"]]]],[13,\"anchor\",[6,\"std.select\",[[7,\"pair\",\"xy\"],[7,\"pair\",\"zw\"],[1,[1,\"i\",\"&\",[5,\"1\"]],\"===\",[5,\"1\"]]]]],[13,\"dist\",[6,\"std.max\",[[6,\"std.length\",[[6,[7,\"q\",\"sub\"],[\"anchor\"]]]],[5,\"0.01\"]]]],[13,\"w\",[1,\"active\",\"/\",[6,\"std.pow\",[\"dist\",\"power\"]]]],[13,\"ti\",[6,\"std.fract\",[[1,[1,\"fi\",\"*\",\"GOLDEN_CONJ\"],\"+\",\"seedShuffle\"]]]],[2,\"num\",\"=\",[1,\"num\",\"+\",[1,\"w\",\"*\",\"ti\"]]],[2,\"den\",\"=\",[1,\"den\",\"+\",\"w\"]]]]],[10,[1,\"num\",\"/\",[6,\"std.max\",[\"den\",[5,\"0.000001\"]]]]]]]},externals:{\"d.f32\":()=>n,hash11:()=>Xs,SCATTER_MAX:()=>Mm,\"std.select\":()=>N,\"std.max\":()=>B,\"std.length\":()=>he,\"std.pow\":()=>vt,\"std.fract\":()=>Re,GOLDEN_CONJ:()=>mv}})&&e.f)({})),CJ=w.fn([m,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=n(0),d=n(0);for(let u=0;u<Mm;u++){let p=n(u),_=N(n(0),n(1),p<__tsover_sub(s,.5)),f=TT(p,s,r,o,a,i),h=B(he(t.sub(f)),.01),g=__tsover_div(_,vt(h,l)),y=Re(__tsover_add(__tsover_mul(p,mv),Xs(__tsover_add(__tsover_mul(r,.531),.77))));c=__tsover_add(c,__tsover_mul(g,y)),d=__tsover_add(d,g)}return __tsover_div(c,B(d,1e-6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"drift\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"power\"}],body:[0,[[12,\"num\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"den\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"SCATTER_MAX\"],[102,\"++\",\"i\"],[0,[[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"active\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"fi\",\"<\",[1,\"count\",\"-\",[5,\"0.5\"]]]]]],[13,\"anchor\",[6,\"spiralScatter\",[\"fi\",\"count\",\"seed\",\"drift\",\"aspect\",\"animTime\"]]],[13,\"dist\",[6,\"std.max\",[[6,\"std.length\",[[6,[7,\"q\",\"sub\"],[\"anchor\"]]]],[5,\"0.01\"]]]],[13,\"w\",[1,\"active\",\"/\",[6,\"std.pow\",[\"dist\",\"power\"]]]],[13,\"ti\",[6,\"std.fract\",[[1,[1,\"fi\",\"*\",\"GOLDEN_CONJ\"],\"+\",[6,\"hash11\",[[1,[1,\"seed\",\"*\",[5,\"0.531\"]],\"+\",[5,\"0.77\"]]]]]]]],[2,\"num\",\"=\",[1,\"num\",\"+\",[1,\"w\",\"*\",\"ti\"]]],[2,\"den\",\"=\",[1,\"den\",\"+\",\"w\"]]]]],[10,[1,\"num\",\"/\",[6,\"std.max\",[\"den\",[5,\"0.000001\"]]]]]]]},externals:{\"d.f32\":()=>n,SCATTER_MAX:()=>Mm,\"std.select\":()=>N,spiralScatter:()=>TT,\"std.max\":()=>B,\"std.length\":()=>he,\"std.pow\":()=>vt,\"std.fract\":()=>Re,GOLDEN_CONJ:()=>mv,hash11:()=>Xs}})&&e.f)({})),MJ=w.fn([m,n,n,m,m,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=A(__tsover_mul(t.x,s),__tsover_mul(t.y,s),r),d=Na(c.add(A(o.x,o.y,0))),u=Na(c.add(A(a.x,a.y,0)));return S(__tsover_add(t.x,__tsover_mul(__tsover_mul(d,i),l)),__tsover_add(t.y,__tsover_mul(__tsover_mul(u,i),l)),d,u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"z\"},{type:\"i\",name:\"offA\"},{type:\"i\",name:\"offB\"},{type:\"i\",name:\"k\"},{type:\"i\",name:\"strength\"}],body:[0,[[13,\"wp\",[6,\"d.vec3f\",[[1,[7,\"pos\",\"x\"],\"*\",\"scale\"],[1,[7,\"pos\",\"y\"],\"*\",\"scale\"],\"z\"]]],[13,\"nx\",[6,\"mxNoiseFloat3\",[[6,[7,\"wp\",\"add\"],[[6,\"d.vec3f\",[[7,\"offA\",\"x\"],[7,\"offA\",\"y\"],[5,\"0\"]]]]]]]],[13,\"ny\",[6,\"mxNoiseFloat3\",[[6,[7,\"wp\",\"add\"],[[6,\"d.vec3f\",[[7,\"offB\",\"x\"],[7,\"offB\",\"y\"],[5,\"0\"]]]]]]]],[10,[6,\"d.vec4f\",[[1,[7,\"pos\",\"x\"],\"+\",[1,[1,\"nx\",\"*\",\"k\"],\"*\",\"strength\"]],[1,[7,\"pos\",\"y\"],\"+\",[1,[1,\"ny\",\"*\",\"k\"],\"*\",\"strength\"]],\"nx\",\"ny\"]]]]]},externals:{\"d.vec3f\":()=>A,mxNoiseFloat3:()=>Na,\"d.vec4f\":()=>S}})&&e.f)({})),s1=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Re(ae(m(Se(t,m(127.1,311.7)),Se(t,m(269.5,183.3)))).mul(43758.5453))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"h\",[6,\"d.vec2f\",[[6,\"std.dot\",[\"p\",[6,\"d.vec2f\",[[5,\"127.1\"],[5,\"311.7\"]]]]],[6,\"std.dot\",[\"p\",[6,\"d.vec2f\",[[5,\"269.5\"],[5,\"183.3\"]]]]]]]],[10,[6,\"std.fract\",[[6,[7,[6,\"std.sin\",[\"h\"]],\"mul\"],[[5,\"43758.5453\"]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.dot\":()=>Se,\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({}));function Gk(e){let{distance:t,jitter:s,name:r=\"nearest2Cells\"}=e,o=`${r}|${t}|${s}`,a=ST.get(o);if(a)return a;let i=`${t===\"length\"?\"Len\":\"Sel\"}${s===\"mix\"?\"Jit\":\"\"}`,l;return t===\"length\"&&s===\"none\"?l=w.fn([m,n,n],m)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=ie(d),f=Re(d),h=n(10),g=n(10);for(let y=-1;y<=1;y++)for(let b=-1;b<=1;b++){let x=m(n(b),n(y)),P=s1(m(__tsover_add(__tsover_add(_.x,x.x),p),__tsover_add(__tsover_add(_.y,x.y),p))),C=G(__tsover_add(P.x,__tsover_mul(ae(__tsover_add(u,__tsover_mul(P.x,Jt))),.15)),.05,.95),E=G(__tsover_add(P.y,__tsover_mul(pe(__tsover_add(__tsover_mul(u,.7),__tsover_mul(P.y,Jt))),.15)),.05,.95),R=he(m(__tsover_sub(f.x,__tsover_add(x.x,C)),__tsover_sub(f.y,__tsover_add(x.y,E))));g=ye(g,B(R,h)),h=ye(h,R)}return m(h,g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"animT\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"cell\",[6,\"std.floor\",[\"scaledUV\"]]],[13,\"localUV\",[6,\"std.fract\",[\"scaledUV\"]]],[12,\"d1\",[6,\"d.f32\",[[5,\"10\"]]]],[12,\"d2\",[6,\"d.f32\",[[5,\"10\"]]]],[14,[12,\"ny\",[4,\"-\",[5,\"1\"]]],[1,\"ny\",\"<=\",[5,\"1\"]],[102,\"++\",\"ny\"],[0,[[14,[12,\"nx\",[4,\"-\",[5,\"1\"]]],[1,\"nx\",\"<=\",[5,\"1\"]],[102,\"++\",\"nx\"],[0,[[13,\"offset\",[6,\"d.vec2f\",[[6,\"d.f32\",[\"nx\"]],[6,\"d.f32\",[\"ny\"]]]]],[13,\"h\",[6,\"cellHash2\",[[6,\"d.vec2f\",[[1,[1,[7,\"cell\",\"x\"],\"+\",[7,\"offset\",\"x\"]],\"+\",\"seed\"],[1,[1,[7,\"cell\",\"y\"],\"+\",[7,\"offset\",\"y\"]],\"+\",\"seed\"]]]]]],[13,\"pointX\",[6,\"std.clamp\",[[1,[7,\"h\",\"x\"],\"+\",[1,[6,\"std.sin\",[[1,\"animT\",\"+\",[1,[7,\"h\",\"x\"],\"*\",\"TAU\"]]]],\"*\",[5,\"0.15\"]]],[5,\"0.05\"],[5,\"0.95\"]]]],[13,\"pointY\",[6,\"std.clamp\",[[1,[7,\"h\",\"y\"],\"+\",[1,[6,\"std.cos\",[[1,[1,\"animT\",\"*\",[5,\"0.7\"]],\"+\",[1,[7,\"h\",\"y\"],\"*\",\"TAU\"]]]],\"*\",[5,\"0.15\"]]],[5,\"0.05\"],[5,\"0.95\"]]]],[13,\"dd\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"localUV\",\"x\"],\"-\",[1,[7,\"offset\",\"x\"],\"+\",\"pointX\"]],[1,[7,\"localUV\",\"y\"],\"-\",[1,[7,\"offset\",\"y\"],\"+\",\"pointY\"]]]]]]],[2,\"d2\",\"=\",[6,\"std.min\",[\"d2\",[6,\"std.max\",[\"dd\",\"d1\"]]]]],[2,\"d1\",\"=\",[6,\"std.min\",[\"d1\",\"dd\"]]]]]]]]],[10,[6,\"d.vec2f\",[\"d1\",\"d2\"]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"d.f32\":()=>n,\"d.vec2f\":()=>m,cellHash2:()=>s1,\"std.clamp\":()=>G,\"std.sin\":()=>ae,TAU:()=>Jt,\"std.cos\":()=>pe,\"std.length\":()=>he,\"std.min\":()=>ye,\"std.max\":()=>B}})&&c.f)({})).$name(`${r}${i}`):l=w.fn([m,n,n,n,n],m)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p,_,f)=>{\"use gpu\";let h=__tsover_mul(u,.7),g=ie(d),y=Re(d),b=n(10),x=n(10);for(let P=-1;P<=1;P++)for(let C=-1;C<=1;C++){let E=m(n(C),n(P)),R=s1(m(__tsover_add(__tsover_add(g.x,E.x),p),__tsover_add(__tsover_add(g.y,E.y),p))),U=__tsover_add(R.x,__tsover_mul(ae(__tsover_add(u,__tsover_mul(R.x,Jt))),.15)),L=__tsover_add(R.y,__tsover_mul(pe(__tsover_add(h,__tsover_mul(R.y,Jt))),.15)),k=K(.5,G(U,.05,.95),_),D=K(.5,G(L,.05,.95),_),O=__tsover_sub(y.x,__tsover_add(E.x,k)),F=__tsover_sub(y.y,__tsover_add(E.y,D)),q=__tsover_add(__tsover_mul(O,O),__tsover_mul(F,F)),Y=__tsover_add(re(O),re(F)),V=B(re(O),re(F)),X=q;X=N(X,Y,f===1),X=N(X,V,f===2),x=ye(x,B(X,b)),b=ye(b,X)}return m(b,x)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"animT\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"jitterAmount\"},{type:\"i\",name:\"metric\"}],body:[0,[[13,\"animTSlow\",[1,\"animT\",\"*\",[5,\"0.7\"]]],[13,\"cell\",[6,\"std.floor\",[\"scaledUV\"]]],[13,\"localUV\",[6,\"std.fract\",[\"scaledUV\"]]],[12,\"d1\",[6,\"d.f32\",[[5,\"10\"]]]],[12,\"d2\",[6,\"d.f32\",[[5,\"10\"]]]],[14,[12,\"ny\",[4,\"-\",[5,\"1\"]]],[1,\"ny\",\"<=\",[5,\"1\"]],[102,\"++\",\"ny\"],[0,[[14,[12,\"nx\",[4,\"-\",[5,\"1\"]]],[1,\"nx\",\"<=\",[5,\"1\"]],[102,\"++\",\"nx\"],[0,[[13,\"offset\",[6,\"d.vec2f\",[[6,\"d.f32\",[\"nx\"]],[6,\"d.f32\",[\"ny\"]]]]],[13,\"h\",[6,\"cellHash2\",[[6,\"d.vec2f\",[[1,[1,[7,\"cell\",\"x\"],\"+\",[7,\"offset\",\"x\"]],\"+\",\"seed\"],[1,[1,[7,\"cell\",\"y\"],\"+\",[7,\"offset\",\"y\"]],\"+\",\"seed\"]]]]]],[13,\"px\",[1,[7,\"h\",\"x\"],\"+\",[1,[6,\"std.sin\",[[1,\"animT\",\"+\",[1,[7,\"h\",\"x\"],\"*\",\"TAU\"]]]],\"*\",[5,\"0.15\"]]]],[13,\"py\",[1,[7,\"h\",\"y\"],\"+\",[1,[6,\"std.cos\",[[1,\"animTSlow\",\"+\",[1,[7,\"h\",\"y\"],\"*\",\"TAU\"]]]],\"*\",[5,\"0.15\"]]]],[13,\"jx\",[6,\"std.mix\",[[5,\"0.5\"],[6,\"std.clamp\",[\"px\",[5,\"0.05\"],[5,\"0.95\"]]],\"jitterAmount\"]]],[13,\"jy\",[6,\"std.mix\",[[5,\"0.5\"],[6,\"std.clamp\",[\"py\",[5,\"0.05\"],[5,\"0.95\"]]],\"jitterAmount\"]]],[13,\"deltaX\",[1,[7,\"localUV\",\"x\"],\"-\",[1,[7,\"offset\",\"x\"],\"+\",\"jx\"]]],[13,\"deltaY\",[1,[7,\"localUV\",\"y\"],\"-\",[1,[7,\"offset\",\"y\"],\"+\",\"jy\"]]],[13,\"dEuclid\",[1,[1,\"deltaX\",\"*\",\"deltaX\"],\"+\",[1,\"deltaY\",\"*\",\"deltaY\"]]],[13,\"dManhattan\",[1,[6,\"std.abs\",[\"deltaX\"]],\"+\",[6,\"std.abs\",[\"deltaY\"]]]],[13,\"dChebyshev\",[6,\"std.max\",[[6,\"std.abs\",[\"deltaX\"]],[6,\"std.abs\",[\"deltaY\"]]]]],[12,\"dd\",\"dEuclid\"],[2,\"dd\",\"=\",[6,\"std.select\",[\"dd\",\"dManhattan\",[1,\"metric\",\"===\",[5,\"1\"]]]]],[2,\"dd\",\"=\",[6,\"std.select\",[\"dd\",\"dChebyshev\",[1,\"metric\",\"===\",[5,\"2\"]]]]],[2,\"d2\",\"=\",[6,\"std.min\",[\"d2\",[6,\"std.max\",[\"dd\",\"d1\"]]]]],[2,\"d1\",\"=\",[6,\"std.min\",[\"d1\",\"dd\"]]]]]]]]],[10,[6,\"d.vec2f\",[\"d1\",\"d2\"]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"d.f32\":()=>n,\"d.vec2f\":()=>m,cellHash2:()=>s1,\"std.sin\":()=>ae,TAU:()=>Jt,\"std.cos\":()=>pe,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.select\":()=>N,\"std.min\":()=>ye}})&&c.f)({})).$name(`${r}${i}`),ST.set(o,l),l}var ST=new Map,EJ={f1:0,f2:1,f2MinusF1:2,f1PlusF2:3,f1TimesF2:4},kJ={euclidean:0,manhattan:1,chebyshev:2},PT=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=r===0,i=N(t,Ue(t),a),l=N(s,Ue(s),a),c=i;return c=N(c,l,o===1),c=N(c,__tsover_sub(l,i),o===2),c=N(c,__tsover_add(i,l),o===3),c=N(c,__tsover_mul(i,l),o===4),c}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"d1\"},{type:\"i\",name:\"d2\"},{type:\"i\",name:\"metric\"},{type:\"i\",name:\"mode\"}],body:[0,[[13,\"isEuclid\",[1,\"metric\",\"===\",[5,\"0\"]]],[13,\"sd1\",[6,\"std.select\",[\"d1\",[6,\"std.sqrt\",[\"d1\"]],\"isEuclid\"]]],[13,\"sd2\",[6,\"std.select\",[\"d2\",[6,\"std.sqrt\",[\"d2\"]],\"isEuclid\"]]],[12,\"raw\",\"sd1\"],[2,\"raw\",\"=\",[6,\"std.select\",[\"raw\",\"sd2\",[1,\"mode\",\"===\",[5,\"1\"]]]]],[2,\"raw\",\"=\",[6,\"std.select\",[\"raw\",[1,\"sd2\",\"-\",\"sd1\"],[1,\"mode\",\"===\",[5,\"2\"]]]]],[2,\"raw\",\"=\",[6,\"std.select\",[\"raw\",[1,\"sd1\",\"+\",\"sd2\"],[1,\"mode\",\"===\",[5,\"3\"]]]]],[2,\"raw\",\"=\",[6,\"std.select\",[\"raw\",[1,\"sd1\",\"*\",\"sd2\"],[1,\"mode\",\"===\",[5,\"4\"]]]]],[10,\"raw\"]]]},externals:{\"std.select\":()=>N,\"std.sqrt\":()=>Ue}})&&e.f)({})),CT=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(__tsover_add(t,s),1e-4);return G(vt(G(__tsover_div(__tsover_mul(t,2),o),0,1),r),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"d1\"},{type:\"i\",name:\"d2\"},{type:\"i\",name:\"power\"}],body:[0,[[13,\"safeSum\",[6,\"std.max\",[[1,\"d1\",\"+\",\"d2\"],[5,\"0.0001\"]]]],[13,\"normalizedDist\",[6,\"std.clamp\",[[1,[1,\"d1\",\"*\",[5,\"2\"]],\"/\",\"safeSum\"],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"std.clamp\",[[6,\"std.pow\",[\"normalizedDist\",\"power\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.pow\":()=>vt}})&&e.f)({})),MT=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(__tsover_add(t,s),1e-4),a=__tsover_div(__tsover_sub(s,t),o);return be(0,__tsover_add(r,.001),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"d1\"},{type:\"i\",name:\"d2\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"safeSum\",[6,\"std.max\",[[1,\"d1\",\"+\",\"d2\"],[5,\"0.0001\"]]]],[13,\"edgeMetric\",[1,[1,\"d2\",\"-\",\"d1\"],\"/\",\"safeSum\"]],[10,[6,\"std.smoothstep\",[[5,\"0\"],[1,\"softness\",\"+\",[5,\"0.001\"]],\"edgeMetric\"]]]]]},externals:{\"std.max\":()=>B,\"std.smoothstep\":()=>be}})&&e.f)({})),ET=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Tt(-__tsover_mul(__tsover_mul(t,t),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"sharpness\"}],body:[0,[[10,[6,\"std.exp\",[[4,\"-\",[1,[1,\"dist\",\"*\",\"dist\"],\"*\",\"sharpness\"]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})),D1=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return Tt(__tsover_mul(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s)),-r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"du\"},{type:\"i\",name:\"dv\"},{type:\"i\",name:\"sharpness\"}],body:[0,[[10,[6,\"std.exp\",[[1,[1,[1,\"du\",\"*\",\"du\"],\"+\",[1,\"dv\",\"*\",\"dv\"]],\"*\",[4,\"-\",\"sharpness\"]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})),BJ=w.fn([m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(__tsover_sub(t.x,r),s),l=__tsover_sub(t.y,o),c=__tsover_add(__tsover_mul(i,i),__tsover_mul(l,l));return Tt(__tsover_div(__tsover_mul(-.5,c),a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"lx\"},{type:\"i\",name:\"ly\"},{type:\"i\",name:\"sizeSq\"}],body:[0,[[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"lx\"],\"*\",\"aspect\"]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",\"ly\"]],[13,\"dd2\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[10,[6,\"std.exp\",[[1,[1,[4,\"-\",[5,\"0.5\"]],\"*\",\"dd2\"],\"/\",\"sizeSq\"]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})),kT=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return vt(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(t,s),r)),.5),.5),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angle\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"sharpness\"}],body:[0,[[13,\"t\",[1,[1,[6,\"std.sin\",[[1,[1,\"angle\",\"*\",\"count\"],\"+\",\"phase\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[10,[6,\"std.pow\",[\"t\",\"sharpness\"]]]]]},externals:{\"std.sin\":()=>ae,\"std.pow\":()=>vt}})&&e.f)({})),p0=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return vt(re(pe(__tsover_mul(t,s))),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angle\"},{type:\"i\",name:\"halfCount\"},{type:\"i\",name:\"power\"}],body:[0,[[10,[6,\"std.pow\",[[6,\"std.abs\",[[6,\"std.cos\",[[1,\"angle\",\"*\",\"halfCount\"]]]]],\"power\"]]]]]},externals:{\"std.pow\":()=>vt,\"std.abs\":()=>re,\"std.cos\":()=>pe}})&&e.f)({})),BT=w.fn([m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Xt(t.y,t.x);return A(s,__tsover_sub(s,__tsover_mul(Jt,ie(__tsover_div(s,Jt)))),be(-.15,.15,t.x))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"delta\"}],body:[0,[[13,\"angle\",[6,\"std.atan2\",[[7,\"delta\",\"y\"],[7,\"delta\",\"x\"]]]],[13,\"angleWrapped\",[1,\"angle\",\"-\",[1,\"TAU\",\"*\",[6,\"std.floor\",[[1,\"angle\",\"/\",\"TAU\"]]]]]],[13,\"blend\",[6,\"std.smoothstep\",[[4,\"-\",[5,\"0.15\"]],[5,\"0.15\"],[7,\"delta\",\"x\"]]]],[10,[6,\"d.vec3f\",[\"angle\",\"angleWrapped\",\"blend\"]]]]]},externals:{\"std.atan2\":()=>Xt,TAU:()=>Jt,\"std.floor\":()=>ie,\"std.smoothstep\":()=>be,\"d.vec3f\":()=>A}})&&e.f)({})),_v=w.fn([n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=B(o,1e-4);return A(__tsover_sub(1,be(0,a,re(__tsover_sub(t,__tsover_add(s,r))))),__tsover_sub(1,be(0,a,re(__tsover_sub(t,s)))),__tsover_sub(1,be(0,a,re(__tsover_sub(t,__tsover_sub(s,r))))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"spread\"},{type:\"i\",name:\"width\"}],body:[0,[[13,\"w\",[6,\"std.max\",[\"width\",[5,\"0.0001\"]]]],[13,\"r\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],\"w\",[6,\"std.abs\",[[1,\"dist\",\"-\",[1,\"center\",\"+\",\"spread\"]]]]]]]],[13,\"g\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],\"w\",[6,\"std.abs\",[[1,\"dist\",\"-\",\"center\"]]]]]]],[13,\"b\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],\"w\",[6,\"std.abs\",[[1,\"dist\",\"-\",[1,\"center\",\"-\",\"spread\"]]]]]]]],[10,[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]]]]]},externals:{\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"std.abs\":()=>re,\"d.vec3f\":()=>A}})&&e.f)({})),zT=w.fn([m,m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=m(__tsover_sub(r.x,s.x),__tsover_sub(r.y,s.y)),a=m(__tsover_sub(t.x,s.x),__tsover_sub(t.y,s.y)),i=__tsover_add(__tsover_mul(a.x,o.x),__tsover_mul(a.y,o.y)),l=__tsover_add(__tsover_mul(o.x,o.x),__tsover_mul(o.y,o.y)),c=G(__tsover_div(i,B(l,1e-4)),0,1),d=m(__tsover_add(s.x,__tsover_mul(o.x,c)),__tsover_add(s.y,__tsover_mul(o.y,c))),u=m(__tsover_sub(t.x,d.x),__tsover_sub(t.y,d.y));return m(c,Ue(__tsover_add(__tsover_mul(u.x,u.x),__tsover_mul(u.y,u.y))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"}],body:[0,[[13,\"lineVec\",[6,\"d.vec2f\",[[1,[7,\"b\",\"x\"],\"-\",[7,\"a\",\"x\"]],[1,[7,\"b\",\"y\"],\"-\",[7,\"a\",\"y\"]]]]],[13,\"toPoint\",[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"-\",[7,\"a\",\"x\"]],[1,[7,\"p\",\"y\"],\"-\",[7,\"a\",\"y\"]]]]],[13,\"dotProduct\",[1,[1,[7,\"toPoint\",\"x\"],\"*\",[7,\"lineVec\",\"x\"]],\"+\",[1,[7,\"toPoint\",\"y\"],\"*\",[7,\"lineVec\",\"y\"]]]],[13,\"lineLengthSq\",[1,[1,[7,\"lineVec\",\"x\"],\"*\",[7,\"lineVec\",\"x\"]],\"+\",[1,[7,\"lineVec\",\"y\"],\"*\",[7,\"lineVec\",\"y\"]]]],[13,\"t\",[6,\"std.clamp\",[[1,\"dotProduct\",\"/\",[6,\"std.max\",[\"lineLengthSq\",[5,\"0.0001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"closestPoint\",[6,\"d.vec2f\",[[1,[7,\"a\",\"x\"],\"+\",[1,[7,\"lineVec\",\"x\"],\"*\",\"t\"]],[1,[7,\"a\",\"y\"],\"+\",[1,[7,\"lineVec\",\"y\"],\"*\",\"t\"]]]]],[13,\"distVec\",[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"-\",[7,\"closestPoint\",\"x\"]],[1,[7,\"p\",\"y\"],\"-\",[7,\"closestPoint\",\"y\"]]]]],[10,[6,\"d.vec2f\",[\"t\",[6,\"std.sqrt\",[[1,[1,[7,\"distVec\",\"x\"],\"*\",[7,\"distVec\",\"x\"]],\"+\",[1,[7,\"distVec\",\"y\"],\"*\",[7,\"distVec\",\"y\"]]]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"std.max\":()=>B,\"std.sqrt\":()=>Ue}})&&e.f)({})),RT=w.fn([n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=K(r,o,s),c=B(K(a,i,s),1e-4),d=__tsover_div(t,B(l,1e-4)),u=__tsover_add(1,c),p=vt(__tsover_sub(1,be(1,u,d)),__tsover_add(1,__tsover_mul(c,1.5)));return m(be(__tsover_sub(1,c),__tsover_add(1,c),d),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"startThickness\"},{type:\"i\",name:\"endThickness\"},{type:\"i\",name:\"startSoftness\"},{type:\"i\",name:\"endSoftness\"}],body:[0,[[13,\"thickness\",[6,\"std.mix\",[\"startThickness\",\"endThickness\",\"t\"]]],[13,\"softness\",[6,\"std.max\",[[6,\"std.mix\",[\"startSoftness\",\"endSoftness\",\"t\"]],[5,\"0.0001\"]]]],[13,\"normalizedDist\",[1,\"dist\",\"/\",[6,\"std.max\",[\"thickness\",[5,\"0.0001\"]]]]],[13,\"edgeEnd\",[1,[5,\"1\"],\"+\",\"softness\"]],[13,\"alphaBase\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"1\"],\"edgeEnd\",\"normalizedDist\"]]]],[13,\"softnessFactor\",[1,[5,\"1\"],\"+\",[1,\"softness\",\"*\",[5,\"1.5\"]]]],[13,\"alpha\",[6,\"std.pow\",[\"alphaBase\",\"softnessFactor\"]]],[13,\"colorGradientStart\",[1,[5,\"1\"],\"-\",\"softness\"]],[13,\"colorGradientEnd\",[1,[5,\"1\"],\"+\",\"softness\"]],[13,\"colorT\",[6,\"std.smoothstep\",[\"colorGradientStart\",\"colorGradientEnd\",\"normalizedDist\"]]],[10,[6,\"d.vec2f\",[\"colorT\",\"alpha\"]]]]]},externals:{\"std.mix\":()=>K,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"std.pow\":()=>vt,\"d.vec2f\":()=>m}})&&e.f)({})),m0=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return Tt(__tsover_div(__tsover_mul(__tsover_mul(__tsover_sub(t,s),__tsover_sub(t,s)),-1),__tsover_mul(r,r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"u\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"width\"}],body:[0,[[10,[6,\"std.exp\",[[1,[1,[1,[1,\"u\",\"-\",\"center\"],\"*\",[1,\"u\",\"-\",\"center\"]],\"*\",[4,\"-\",[5,\"1\"]]],\"/\",[1,\"width\",\"*\",\"width\"]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})),r1=w.fn([n,A,A,A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=be(0,.5,t),i=be(.55,1.15,t);return K(K(o,r,A(a)),s,A(i)).mul(G(t,0,1.6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"heat\"},{type:\"i\",name:\"hot\"},{type:\"i\",name:\"mid\"},{type:\"i\",name:\"fringe\"}],body:[0,[[13,\"toMid\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.5\"],\"heat\"]]],[13,\"toHot\",[6,\"std.smoothstep\",[[5,\"0.55\"],[5,\"1.15\"],\"heat\"]]],[13,\"rgb\",[6,\"std.mix\",[[6,\"std.mix\",[\"fringe\",\"mid\",[6,\"d.vec3f\",[\"toMid\"]]]],\"hot\",[6,\"d.vec3f\",[\"toHot\"]]]]],[10,[6,[7,\"rgb\",\"mul\"],[[6,\"std.clamp\",[\"heat\",[5,\"0\"],[5,\"1.6\"]]]]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.mix\":()=>K,\"d.vec3f\":()=>A,\"std.clamp\":()=>G}})&&e.f)({})),zJ=w.fn([n,A,A,A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=r1(__tsover_mul(t,1.08),s,r,o),i=r1(t,s,r,o),l=r1(__tsover_mul(t,.88),s,r,o);return A(a.x,i.y,l.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"heat\"},{type:\"i\",name:\"hot\"},{type:\"i\",name:\"mid\"},{type:\"i\",name:\"fringe\"}],body:[0,[[13,\"rampR\",[6,\"heatRamp3\",[[1,\"heat\",\"*\",[5,\"1.08\"]],\"hot\",\"mid\",\"fringe\"]]],[13,\"rampG\",[6,\"heatRamp3\",[\"heat\",\"hot\",\"mid\",\"fringe\"]]],[13,\"rampB\",[6,\"heatRamp3\",[[1,\"heat\",\"*\",[5,\"0.88\"]],\"hot\",\"mid\",\"fringe\"]]],[10,[6,\"d.vec3f\",[[7,\"rampR\",\"x\"],[7,\"rampG\",\"y\"],[7,\"rampB\",\"z\"]]]]]]},externals:{heatRamp3:()=>r1,\"d.vec3f\":()=>A}})&&e.f)({})),RJ=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s,__tsover_sub(1,r));return __tsover_sub(1,be(o,s,t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"feather\"}],body:[0,[[13,\"falloffStart\",[1,\"radius\",\"*\",[1,[5,\"1\"],\"-\",\"feather\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"falloffStart\",\"radius\",\"dist\"]]]]]]},externals:{\"std.smoothstep\":()=>be}})&&e.f)({})),DJ=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return kT(t,s,r,__tsover_mul(__tsover_div(1,__tsover_add(o,.05)),.3))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angle\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"sharpness\",[1,[1,[5,\"1\"],\"/\",[1,\"softness\",\"+\",[5,\"0.05\"]]],\"*\",[5,\"0.3\"]]],[10,[6,\"angularSineLobes\",[\"angle\",\"count\",\"phase\",\"sharpness\"]]]]]},externals:{angularSineLobes:()=>kT}})&&e.f)({})),LJ=w.fn([m,m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s),a=r.x,i=__tsover_sub(1,r.y),l=__tsover_sub(__tsover_mul(t.x,o),__tsover_mul(a,o)),c=__tsover_sub(t.y,i);return m(Ue(__tsover_add(__tsover_mul(l,l),__tsover_mul(c,c))),Xt(c,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"center\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"cx\",[7,\"center\",\"x\"]],[13,\"cy\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,\"cx\",\"*\",\"aspect\"]]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",\"cy\"]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[13,\"angle\",[6,\"std.atan2\",[\"dy\",\"dx\"]]],[10,[6,\"d.vec2f\",[\"dist\",\"angle\"]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"std.sqrt\":()=>Ue,\"std.atan2\":()=>Xt,\"d.vec2f\":()=>m}})&&e.f)({})),UJ=w.fn([m,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s),a=__tsover_mul(__tsover_sub(t.x,.5),o),i=__tsover_sub(t.y,.5),l=__tsover_add(__tsover_mul(a,a),__tsover_mul(i,i));return G(__tsover_sub(1,__tsover_mul(l,r)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"strength\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"vigX\",[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"]],[13,\"vigY\",[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]],[13,\"vigD2\",[1,[1,\"vigX\",\"*\",\"vigX\"],\"+\",[1,\"vigY\",\"*\",\"vigY\"]]],[10,[6,\"std.clamp\",[[1,[5,\"1\"],\"-\",[1,\"vigD2\",\"*\",\"strength\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"std.clamp\":()=>G}})&&e.f)({})),OJ=w.fn([S,A],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t.xyz,o=G(A(1,1,1).sub(A(1,1,1).sub(G(r,A(0),A(1))).mul(A(1,1,1).sub(G(s,A(0),A(1))))).add(s.mul(.16)),A(0),A(1)),a=G(rv(s),0,1);return S(o,G(__tsover_add(t.w,__tsover_mul(a,.85)),0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"leakRgb\"}],body:[0,[[13,\"base\",[7,\"color\",\"xyz\"]],[13,\"screened\",[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"sub\"],[[6,[7,[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"sub\"],[[6,\"std.clamp\",[\"base\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]]],\"mul\"],[[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"sub\"],[[6,\"std.clamp\",[\"leakRgb\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]]]]]]]],[13,\"lifted\",[6,[7,\"screened\",\"add\"],[[6,[7,\"leakRgb\",\"mul\"],[[5,\"0.16\"]]]]]],[13,\"outRgb\",[6,\"std.clamp\",[\"lifted\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[13,\"leakLuma\",[6,\"std.clamp\",[[6,\"tone.luma601Dot\",[\"leakRgb\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"outA\",[6,\"std.clamp\",[[1,[7,\"color\",\"w\"],\"+\",[1,\"leakLuma\",\"*\",[5,\"0.85\"]]],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[\"outRgb\",\"outA\"]]]]]},externals:{\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"tone.luma601Dot\":()=>rv,\"d.vec4f\":()=>S}})&&e.f)({})),GJ=w.fn([m,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=m(__tsover_mul(t.x,s),t.y),a=m(__tsover_mul(r.x,s),__tsover_sub(1,r.y)),i=m(__tsover_mul(s,.5),.5).sub(a),l=he(i),c=N(__tsover_div(i.x,B(l,.001)),n(1),l<.02),d=N(__tsover_div(i.y,B(l,.001)),n(0),l<.02),u=__tsover_sub(o.x,a.x),p=__tsover_sub(o.y,a.y);return m(__tsover_add(__tsover_mul(u,c),__tsover_mul(p,d)),__tsover_sub(__tsover_mul(p,c),__tsover_mul(u,d)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"anchorRaw\"}],body:[0,[[13,\"pA\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"anchor\",[6,\"d.vec2f\",[[1,[7,\"anchorRaw\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"anchorRaw\",\"y\"]]]]],[13,\"toCenter\",[6,[7,[6,\"d.vec2f\",[[1,\"aspect\",\"*\",[5,\"0.5\"]],[5,\"0.5\"]]],\"sub\"],[\"anchor\"]]],[13,\"cLen\",[6,\"std.length\",[\"toCenter\"]]],[13,\"dirX\",[6,\"std.select\",[[1,[7,\"toCenter\",\"x\"],\"/\",[6,\"std.max\",[\"cLen\",[5,\"0.001\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"cLen\",\"<\",[5,\"0.02\"]]]]],[13,\"dirY\",[6,\"std.select\",[[1,[7,\"toCenter\",\"y\"],\"/\",[6,\"std.max\",[\"cLen\",[5,\"0.001\"]]]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"cLen\",\"<\",[5,\"0.02\"]]]]],[13,\"relX\",[1,[7,\"pA\",\"x\"],\"-\",[7,\"anchor\",\"x\"]]],[13,\"relY\",[1,[7,\"pA\",\"y\"],\"-\",[7,\"anchor\",\"y\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"relX\",\"*\",\"dirX\"],\"+\",[1,\"relY\",\"*\",\"dirY\"]],[1,[1,\"relY\",\"*\",\"dirX\"],\"-\",[1,\"relX\",\"*\",\"dirY\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.select\":()=>N,\"std.max\":()=>B,\"d.f32\":()=>n}})&&e.f)({})),Mn=ko({MixStep:()=>Xa,convertMixSpaceToP3:()=>YJ,convertP3ToMixSpace:()=>IJ,convertP3ToMixSpaceCPU:()=>fl,hslToRgb:()=>ml,hsvToRgb:()=>hd,labToLch:()=>Bm,labToRgb:()=>gd,lchToLab:()=>yd,mixColors:()=>FJ,mixColorsHsl:()=>Yk,mixColorsHsv:()=>Wk,mixColorsLch:()=>qk,mixColorsLinear:()=>Ar,mixColorsOklab:()=>Ik,mixColorsOklch:()=>Fk,mixColorsVariants:()=>No,mixPreconvertedColors:()=>WJ,mixPreconvertedHsl:()=>$k,mixPreconvertedHsv:()=>Xk,mixPreconvertedInSpace:()=>_l,mixPreconvertedLch:()=>Hk,mixPreconvertedLinear:()=>hc,mixPreconvertedOklab:()=>Nk,mixPreconvertedOklch:()=>Vk,mixPreconvertedVariants:()=>Bd,mixToward:()=>Kk,oklabToOklch:()=>Zl,oklabToRgb:()=>oa,oklchToOklab:()=>pl,p3ToSRGB:()=>Cr,rgbToHsl:()=>cd,rgbToHsv:()=>Em,rgbToLab:()=>km,rgbToOklab:()=>Ta,sRGBToP3:()=>Hs,selectRGBBySector:()=>$m}),bi=1e-4,uc=1.0471975512,Zn=6/29,fv=500,vv=200,o1=Zn*Zn*Zn,jl=4/29,a1=1/(3*Zn*Zn),n1=3*Zn*Zn,Cr=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return A(__tsover_sub(__tsover_sub(__tsover_mul(t.x,1.2249401),__tsover_mul(t.y,.2249404)),__tsover_mul(t.z,0)),__tsover_add(__tsover_add(__tsover_mul(t.x,-.0420569),__tsover_mul(t.y,1.0420571)),__tsover_mul(t.z,0)),__tsover_add(__tsover_sub(__tsover_mul(t.x,-.0196376),__tsover_mul(t.y,.0786361)),__tsover_mul(t.z,1.0982735)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p3\"}],body:[0,[[13,\"r\",[1,[1,[1,[7,\"p3\",\"x\"],\"*\",[5,\"1.2249401\"]],\"-\",[1,[7,\"p3\",\"y\"],\"*\",[5,\"0.2249404\"]]],\"-\",[1,[7,\"p3\",\"z\"],\"*\",[5,\"0\"]]]],[13,\"g\",[1,[1,[1,[7,\"p3\",\"x\"],\"*\",[4,\"-\",[5,\"0.0420569\"]]],\"+\",[1,[7,\"p3\",\"y\"],\"*\",[5,\"1.0420571\"]]],\"+\",[1,[7,\"p3\",\"z\"],\"*\",[5,\"0\"]]]],[13,\"b\",[1,[1,[1,[7,\"p3\",\"x\"],\"*\",[4,\"-\",[5,\"0.0196376\"]]],\"-\",[1,[7,\"p3\",\"y\"],\"*\",[5,\"0.0786361\"]]],\"+\",[1,[7,\"p3\",\"z\"],\"*\",[5,\"1.0982735\"]]]],[10,[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),Hs=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return A(__tsover_add(__tsover_add(__tsover_mul(t.x,.8224621),__tsover_mul(t.y,.177538)),__tsover_mul(t.z,0)),__tsover_add(__tsover_add(__tsover_mul(t.x,.0331941),__tsover_mul(t.y,.9668058)),__tsover_mul(t.z,0)),__tsover_add(__tsover_add(__tsover_mul(t.x,.0170826),__tsover_mul(t.y,.0723974)),__tsover_mul(t.z,.9105199)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"srgb\"}],body:[0,[[13,\"r\",[1,[1,[1,[7,\"srgb\",\"x\"],\"*\",[5,\"0.8224621\"]],\"+\",[1,[7,\"srgb\",\"y\"],\"*\",[5,\"0.177538\"]]],\"+\",[1,[7,\"srgb\",\"z\"],\"*\",[5,\"0\"]]]],[13,\"g\",[1,[1,[1,[7,\"srgb\",\"x\"],\"*\",[5,\"0.0331941\"]],\"+\",[1,[7,\"srgb\",\"y\"],\"*\",[5,\"0.9668058\"]]],\"+\",[1,[7,\"srgb\",\"z\"],\"*\",[5,\"0\"]]]],[13,\"b\",[1,[1,[1,[7,\"srgb\",\"x\"],\"*\",[5,\"0.0170826\"]],\"+\",[1,[7,\"srgb\",\"y\"],\"*\",[5,\"0.0723974\"]]],\"+\",[1,[7,\"srgb\",\"z\"],\"*\",[5,\"0.9105199\"]]]],[10,[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),Ta=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_add(__tsover_add(__tsover_mul(s,.4122214708),__tsover_mul(r,.5363325363)),__tsover_mul(o,.0514459929)),i=__tsover_add(__tsover_mul(s,.2119034982),__tsover_add(__tsover_mul(r,.6806995451),__tsover_mul(o,.1073969566))),l=__tsover_add(__tsover_add(__tsover_mul(s,.0883024619),__tsover_mul(r,.2817188376)),__tsover_mul(o,.6299787005)),c=__tsover_mul(no(a),vt(re(a),__tsover_div(1,3))),d=__tsover_mul(no(i),vt(re(i),__tsover_div(1,3))),u=__tsover_mul(no(l),vt(re(l),__tsover_div(1,3)));return A(__tsover_sub(__tsover_add(__tsover_mul(c,.2104542553),__tsover_mul(d,.793617785)),__tsover_mul(u,.0040720468)),__tsover_add(__tsover_sub(__tsover_mul(c,1.9779984951),__tsover_mul(d,2.428592205)),__tsover_mul(u,.4505937099)),__tsover_sub(__tsover_add(__tsover_mul(c,.0259040371),__tsover_mul(d,.7827717662)),__tsover_mul(u,.808675766)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[13,\"r\",[7,\"rgb\",\"x\"]],[13,\"g\",[7,\"rgb\",\"y\"]],[13,\"b\",[7,\"rgb\",\"z\"]],[13,\"l\",[1,[1,[1,\"r\",\"*\",[5,\"0.4122214708\"]],\"+\",[1,\"g\",\"*\",[5,\"0.5363325363\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.0514459929\"]]]],[13,\"m\",[1,[1,\"r\",\"*\",[5,\"0.2119034982\"]],\"+\",[1,[1,\"g\",\"*\",[5,\"0.6806995451\"]],\"+\",[1,\"b\",\"*\",[5,\"0.1073969566\"]]]]],[13,\"s\",[1,[1,[1,\"r\",\"*\",[5,\"0.0883024619\"]],\"+\",[1,\"g\",\"*\",[5,\"0.2817188376\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.6299787005\"]]]],[13,\"l_\",[1,[6,\"std.sign\",[\"l\"]],\"*\",[6,\"std.pow\",[[6,\"std.abs\",[\"l\"]],[1,[5,\"1\"],\"/\",[5,\"3\"]]]]]],[13,\"m_\",[1,[6,\"std.sign\",[\"m\"]],\"*\",[6,\"std.pow\",[[6,\"std.abs\",[\"m\"]],[1,[5,\"1\"],\"/\",[5,\"3\"]]]]]],[13,\"s_\",[1,[6,\"std.sign\",[\"s\"]],\"*\",[6,\"std.pow\",[[6,\"std.abs\",[\"s\"]],[1,[5,\"1\"],\"/\",[5,\"3\"]]]]]],[10,[6,\"d.vec3f\",[[1,[1,[1,\"l_\",\"*\",[5,\"0.2104542553\"]],\"+\",[1,\"m_\",\"*\",[5,\"0.793617785\"]]],\"-\",[1,\"s_\",\"*\",[5,\"0.0040720468\"]]],[1,[1,[1,\"l_\",\"*\",[5,\"1.9779984951\"]],\"-\",[1,\"m_\",\"*\",[5,\"2.428592205\"]]],\"+\",[1,\"s_\",\"*\",[5,\"0.4505937099\"]]],[1,[1,[1,\"l_\",\"*\",[5,\"0.0259040371\"]],\"+\",[1,\"m_\",\"*\",[5,\"0.7827717662\"]]],\"-\",[1,\"s_\",\"*\",[5,\"0.808675766\"]]]]]]]]},externals:{\"std.sign\":()=>no,\"std.pow\":()=>vt,\"std.abs\":()=>re,\"d.vec3f\":()=>A}})&&e.f)({})),oa=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_add(__tsover_add(s,__tsover_mul(r,.3963377774)),__tsover_mul(o,.2158037573)),i=__tsover_sub(__tsover_sub(s,__tsover_mul(r,.1055613458)),__tsover_mul(o,.0638541728)),l=__tsover_sub(__tsover_sub(s,__tsover_mul(r,.0894841775)),__tsover_mul(o,1.291485548)),c=vt(a,3),d=vt(i,3),u=vt(l,3);return A(__tsover_add(__tsover_sub(__tsover_mul(c,4.0767416621),__tsover_mul(d,3.3077115913)),__tsover_mul(u,.2309699292)),__tsover_sub(__tsover_add(__tsover_mul(c,-1.2684380046),__tsover_mul(d,2.6097574011)),__tsover_mul(u,.3413193965)),__tsover_add(__tsover_sub(__tsover_mul(c,-.0041960863),__tsover_mul(d,.7034186147)),__tsover_mul(u,1.707614701)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lab\"}],body:[0,[[13,\"L\",[7,\"lab\",\"x\"]],[13,\"a\",[7,\"lab\",\"y\"]],[13,\"b\",[7,\"lab\",\"z\"]],[13,\"l_\",[1,[1,\"L\",\"+\",[1,\"a\",\"*\",[5,\"0.3963377774\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.2158037573\"]]]],[13,\"m_\",[1,[1,\"L\",\"-\",[1,\"a\",\"*\",[5,\"0.1055613458\"]]],\"-\",[1,\"b\",\"*\",[5,\"0.0638541728\"]]]],[13,\"s_\",[1,[1,\"L\",\"-\",[1,\"a\",\"*\",[5,\"0.0894841775\"]]],\"-\",[1,\"b\",\"*\",[5,\"1.291485548\"]]]],[13,\"l\",[6,\"std.pow\",[\"l_\",[5,\"3\"]]]],[13,\"m\",[6,\"std.pow\",[\"m_\",[5,\"3\"]]]],[13,\"s\",[6,\"std.pow\",[\"s_\",[5,\"3\"]]]],[10,[6,\"d.vec3f\",[[1,[1,[1,\"l\",\"*\",[5,\"4.0767416621\"]],\"-\",[1,\"m\",\"*\",[5,\"3.3077115913\"]]],\"+\",[1,\"s\",\"*\",[5,\"0.2309699292\"]]],[1,[1,[1,\"l\",\"*\",[4,\"-\",[5,\"1.2684380046\"]]],\"+\",[1,\"m\",\"*\",[5,\"2.6097574011\"]]],\"-\",[1,\"s\",\"*\",[5,\"0.3413193965\"]]],[1,[1,[1,\"l\",\"*\",[4,\"-\",[5,\"0.0041960863\"]]],\"-\",[1,\"m\",\"*\",[5,\"0.7034186147\"]]],\"+\",[1,\"s\",\"*\",[5,\"1.707614701\"]]]]]]]]},externals:{\"std.pow\":()=>vt,\"d.vec3f\":()=>A}})&&e.f)({})),Zl=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z;return A(s,Ue(__tsover_add(__tsover_mul(r,r),__tsover_mul(o,o))),Xt(o,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lab\"}],body:[0,[[13,\"L\",[7,\"lab\",\"x\"]],[13,\"a\",[7,\"lab\",\"y\"]],[13,\"b\",[7,\"lab\",\"z\"]],[13,\"C\",[6,\"std.sqrt\",[[1,[1,\"a\",\"*\",\"a\"],\"+\",[1,\"b\",\"*\",\"b\"]]]]],[13,\"h\",[6,\"std.atan2\",[\"b\",\"a\"]]],[10,[6,\"d.vec3f\",[\"L\",\"C\",\"h\"]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.atan2\":()=>Xt,\"d.vec3f\":()=>A}})&&e.f)({})),pl=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z;return A(s,__tsover_mul(r,pe(o)),__tsover_mul(r,ae(o)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lch\"}],body:[0,[[13,\"L\",[7,\"lch\",\"x\"]],[13,\"C\",[7,\"lch\",\"y\"]],[13,\"h\",[7,\"lch\",\"z\"]],[10,[6,\"d.vec3f\",[\"L\",[1,\"C\",\"*\",[6,\"std.cos\",[\"h\"]]],[1,\"C\",\"*\",[6,\"std.sin\",[\"h\"]]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),$m=w.fn([n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=n(0),a=n(0),i=n(0);return r<1?(o=t,a=s):r<2?(o=s,a=t):r<3?(a=t,i=s):r<4?(a=s,i=t):r<5?(o=s,i=t):(o=t,i=s),A(o,a,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"c\"},{type:\"i\",name:\"x\"},{type:\"i\",name:\"sector\"}],body:[0,[[12,\"r\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"g\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"b\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"sector\",\"<\",[5,\"1\"]],[0,[[2,\"r\",\"=\",\"c\"],[2,\"g\",\"=\",\"x\"]]],[11,[1,\"sector\",\"<\",[5,\"2\"]],[0,[[2,\"r\",\"=\",\"x\"],[2,\"g\",\"=\",\"c\"]]],[11,[1,\"sector\",\"<\",[5,\"3\"]],[0,[[2,\"g\",\"=\",\"c\"],[2,\"b\",\"=\",\"x\"]]],[11,[1,\"sector\",\"<\",[5,\"4\"]],[0,[[2,\"g\",\"=\",\"x\"],[2,\"b\",\"=\",\"c\"]]],[11,[1,\"sector\",\"<\",[5,\"5\"]],[0,[[2,\"r\",\"=\",\"x\"],[2,\"b\",\"=\",\"c\"]]],[0,[[2,\"r\",\"=\",\"c\"],[2,\"b\",\"=\",\"x\"]]]]]]]],[10,[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]]]]]},externals:{\"d.f32\":()=>n,\"d.vec3f\":()=>A}})&&e.f)({})),cd=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=B(B(s,r),o),i=ye(ye(s,r),o),l=__tsover_sub(a,i),c=__tsover_mul(__tsover_add(a,i),.5),d=B(__tsover_sub(1,re(__tsover_sub(__tsover_mul(c,2),1))),bi),u=__tsover_div(l,d),p=a===s,_=a===r,f=__tsover_div(__tsover_sub(r,o),B(l,bi)),h=__tsover_add(2,__tsover_div(__tsover_sub(o,s),B(l,bi))),g=N(N(__tsover_add(4,__tsover_div(__tsover_sub(s,r),B(l,bi))),h,_),f,p);return A(__tsover_mul(g,uc),u,c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[13,\"r\",[7,\"rgb\",\"x\"]],[13,\"g\",[7,\"rgb\",\"y\"]],[13,\"b\",[7,\"rgb\",\"z\"]],[13,\"maxVal\",[6,\"std.max\",[[6,\"std.max\",[\"r\",\"g\"]],\"b\"]]],[13,\"minVal\",[6,\"std.min\",[[6,\"std.min\",[\"r\",\"g\"]],\"b\"]]],[13,\"delta\",[1,\"maxVal\",\"-\",\"minVal\"]],[13,\"l\",[1,[1,\"maxVal\",\"+\",\"minVal\"],\"*\",[5,\"0.5\"]]],[13,\"satDenom\",[6,\"std.max\",[[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,[1,\"l\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]],\"EPSILON\"]]],[13,\"s\",[1,\"delta\",\"/\",\"satDenom\"]],[13,\"isRMax\",[1,\"maxVal\",\"===\",\"r\"]],[13,\"isGMax\",[1,\"maxVal\",\"===\",\"g\"]],[13,\"hueR\",[1,[1,\"g\",\"-\",\"b\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]],[13,\"hueG\",[1,[5,\"2\"],\"+\",[1,[1,\"b\",\"-\",\"r\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]]],[13,\"hueB\",[1,[5,\"4\"],\"+\",[1,[1,\"r\",\"-\",\"g\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]]],[13,\"hue\",[6,\"std.select\",[[6,\"std.select\",[\"hueB\",\"hueG\",\"isGMax\"]],\"hueR\",\"isRMax\"]]],[13,\"h\",[1,\"hue\",\"*\",\"PI_OVER_3\"]],[10,[6,\"d.vec3f\",[\"h\",\"s\",\"l\"]]]]]},externals:{\"std.max\":()=>B,\"std.min\":()=>ye,\"std.abs\":()=>re,EPSILON:()=>bi,\"std.select\":()=>N,PI_OVER_3:()=>uc,\"d.vec3f\":()=>A}})&&e.f)({})),ml=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_mul(r,__tsover_sub(1,re(__tsover_sub(__tsover_mul(o,2),1)))),i=__tsover_div(s,uc),l=__tsover_mul(a,__tsover_sub(1,re(__tsover_sub(An(i,2),1)))),c=__tsover_sub(o,__tsover_mul(a,.5));return $m(a,l,ie(i)).add(c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"hsl\"}],body:[0,[[13,\"h\",[7,\"hsl\",\"x\"]],[13,\"s\",[7,\"hsl\",\"y\"]],[13,\"l\",[7,\"hsl\",\"z\"]],[13,\"c\",[1,\"s\",\"*\",[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,[1,\"l\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]]]],[13,\"hPrime\",[1,\"h\",\"/\",\"PI_OVER_3\"]],[13,\"x\",[1,\"c\",\"*\",[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,[6,\"std.mod\",[\"hPrime\",[5,\"2\"]]],\"-\",[5,\"1\"]]]]]]],[13,\"m\",[1,\"l\",\"-\",[1,\"c\",\"*\",[5,\"0.5\"]]]],[13,\"sector\",[6,\"std.floor\",[\"hPrime\"]]],[10,[6,[7,[6,\"selectRGBBySector\",[\"c\",\"x\",\"sector\"]],\"add\"],[\"m\"]]]]]},externals:{\"std.abs\":()=>re,PI_OVER_3:()=>uc,\"std.mod\":()=>An,\"std.floor\":()=>ie,selectRGBBySector:()=>$m}})&&e.f)({})),Em=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=B(B(s,r),o),i=ye(ye(s,r),o),l=__tsover_sub(a,i),c=a,d=__tsover_div(l,B(a,bi)),u=a===s,p=a===r,_=__tsover_div(__tsover_sub(r,o),B(l,bi)),f=__tsover_add(2,__tsover_div(__tsover_sub(o,s),B(l,bi))),h=N(N(__tsover_add(4,__tsover_div(__tsover_sub(s,r),B(l,bi))),f,p),_,u);return A(__tsover_mul(h,uc),d,c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[13,\"r\",[7,\"rgb\",\"x\"]],[13,\"g\",[7,\"rgb\",\"y\"]],[13,\"b\",[7,\"rgb\",\"z\"]],[13,\"maxVal\",[6,\"std.max\",[[6,\"std.max\",[\"r\",\"g\"]],\"b\"]]],[13,\"minVal\",[6,\"std.min\",[[6,\"std.min\",[\"r\",\"g\"]],\"b\"]]],[13,\"delta\",[1,\"maxVal\",\"-\",\"minVal\"]],[13,\"v\",\"maxVal\"],[13,\"s\",[1,\"delta\",\"/\",[6,\"std.max\",[\"maxVal\",\"EPSILON\"]]]],[13,\"isRMax\",[1,\"maxVal\",\"===\",\"r\"]],[13,\"isGMax\",[1,\"maxVal\",\"===\",\"g\"]],[13,\"hueR\",[1,[1,\"g\",\"-\",\"b\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]],[13,\"hueG\",[1,[5,\"2\"],\"+\",[1,[1,\"b\",\"-\",\"r\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]]],[13,\"hueB\",[1,[5,\"4\"],\"+\",[1,[1,\"r\",\"-\",\"g\"],\"/\",[6,\"std.max\",[\"delta\",\"EPSILON\"]]]]],[13,\"hue\",[6,\"std.select\",[[6,\"std.select\",[\"hueB\",\"hueG\",\"isGMax\"]],\"hueR\",\"isRMax\"]]],[13,\"h\",[1,\"hue\",\"*\",\"PI_OVER_3\"]],[10,[6,\"d.vec3f\",[\"h\",\"s\",\"v\"]]]]]},externals:{\"std.max\":()=>B,\"std.min\":()=>ye,EPSILON:()=>bi,\"std.select\":()=>N,PI_OVER_3:()=>uc,\"d.vec3f\":()=>A}})&&e.f)({})),hd=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_mul(o,r),i=__tsover_div(s,uc),l=__tsover_mul(a,__tsover_sub(1,re(__tsover_sub(An(i,2),1)))),c=__tsover_sub(o,a);return $m(a,l,ie(i)).add(c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"hsv\"}],body:[0,[[13,\"h\",[7,\"hsv\",\"x\"]],[13,\"s\",[7,\"hsv\",\"y\"]],[13,\"v\",[7,\"hsv\",\"z\"]],[13,\"c\",[1,\"v\",\"*\",\"s\"]],[13,\"hPrime\",[1,\"h\",\"/\",\"PI_OVER_3\"]],[13,\"x\",[1,\"c\",\"*\",[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,[6,\"std.mod\",[\"hPrime\",[5,\"2\"]]],\"-\",[5,\"1\"]]]]]]],[13,\"m\",[1,\"v\",\"-\",\"c\"]],[13,\"sector\",[6,\"std.floor\",[\"hPrime\"]]],[10,[6,[7,[6,\"selectRGBBySector\",[\"c\",\"x\",\"sector\"]],\"add\"],[\"m\"]]]]]},externals:{PI_OVER_3:()=>uc,\"std.abs\":()=>re,\"std.mod\":()=>An,\"std.floor\":()=>ie,selectRGBBySector:()=>$m}})&&e.f)({})),km=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_add(__tsover_add(__tsover_mul(s,.4124564),__tsover_mul(r,.3575761)),__tsover_mul(o,.1804375)),i=__tsover_add(__tsover_add(__tsover_mul(s,.2126729),__tsover_mul(r,.7151522)),__tsover_mul(o,.072175)),l=__tsover_add(__tsover_add(__tsover_mul(s,.0193339),__tsover_mul(r,.119192)),__tsover_mul(o,.9503041)),c=__tsover_div(a,.95047),d=__tsover_div(i,1),u=__tsover_div(l,1.08883),p=N(__tsover_add(__tsover_mul(c,a1),jl),vt(c,__tsover_div(1,3)),c>o1),_=N(__tsover_add(__tsover_mul(d,a1),jl),vt(d,__tsover_div(1,3)),d>o1),f=N(__tsover_add(__tsover_mul(u,a1),jl),vt(u,__tsover_div(1,3)),u>o1);return A(__tsover_sub(__tsover_mul(_,116),16),__tsover_mul(__tsover_sub(p,_),fv),__tsover_mul(__tsover_sub(_,f),vv))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[13,\"r\",[7,\"rgb\",\"x\"]],[13,\"g\",[7,\"rgb\",\"y\"]],[13,\"b\",[7,\"rgb\",\"z\"]],[13,\"x\",[1,[1,[1,\"r\",\"*\",[5,\"0.4124564\"]],\"+\",[1,\"g\",\"*\",[5,\"0.3575761\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.1804375\"]]]],[13,\"y\",[1,[1,[1,\"r\",\"*\",[5,\"0.2126729\"]],\"+\",[1,\"g\",\"*\",[5,\"0.7151522\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.072175\"]]]],[13,\"z\",[1,[1,[1,\"r\",\"*\",[5,\"0.0193339\"]],\"+\",[1,\"g\",\"*\",[5,\"0.119192\"]]],\"+\",[1,\"b\",\"*\",[5,\"0.9503041\"]]]],[13,\"xn\",[1,\"x\",\"/\",[5,\"0.95047\"]]],[13,\"yn\",[1,\"y\",\"/\",[5,\"1\"]]],[13,\"zn\",[1,\"z\",\"/\",[5,\"1.08883\"]]],[13,\"fx\",[6,\"std.select\",[[1,[1,\"xn\",\"*\",\"LAB_FWD_SLOPE\"],\"+\",\"LAB_OFFSET\"],[6,\"std.pow\",[\"xn\",[1,[5,\"1\"],\"/\",[5,\"3\"]]]],[1,\"xn\",\">\",\"LAB_DELTA3\"]]]],[13,\"fy\",[6,\"std.select\",[[1,[1,\"yn\",\"*\",\"LAB_FWD_SLOPE\"],\"+\",\"LAB_OFFSET\"],[6,\"std.pow\",[\"yn\",[1,[5,\"1\"],\"/\",[5,\"3\"]]]],[1,\"yn\",\">\",\"LAB_DELTA3\"]]]],[13,\"fz\",[6,\"std.select\",[[1,[1,\"zn\",\"*\",\"LAB_FWD_SLOPE\"],\"+\",\"LAB_OFFSET\"],[6,\"std.pow\",[\"zn\",[1,[5,\"1\"],\"/\",[5,\"3\"]]]],[1,\"zn\",\">\",\"LAB_DELTA3\"]]]],[13,\"L\",[1,[1,\"fy\",\"*\",[5,\"116\"]],\"-\",[5,\"16\"]]],[13,\"a\",[1,[1,\"fx\",\"-\",\"fy\"],\"*\",\"LAB_KAPPA\"]],[13,\"bLab\",[1,[1,\"fy\",\"-\",\"fz\"],\"*\",\"LAB_LAMBDA\"]],[10,[6,\"d.vec3f\",[\"L\",\"a\",\"bLab\"]]]]]},externals:{\"std.select\":()=>N,LAB_FWD_SLOPE:()=>a1,LAB_OFFSET:()=>jl,\"std.pow\":()=>vt,LAB_DELTA3:()=>o1,LAB_KAPPA:()=>fv,LAB_LAMBDA:()=>vv,\"d.vec3f\":()=>A}})&&e.f)({})),gd=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z,a=__tsover_div(__tsover_add(s,16),116),i=__tsover_add(__tsover_div(r,fv),a),l=__tsover_sub(a,__tsover_div(o,vv)),c=N(__tsover_mul(__tsover_sub(i,jl),n1),vt(i,3),i>Zn),d=N(__tsover_mul(__tsover_sub(a,jl),n1),vt(a,3),a>Zn),u=N(__tsover_mul(__tsover_sub(l,jl),n1),vt(l,3),l>Zn),p=__tsover_mul(c,.95047),_=__tsover_mul(d,1),f=__tsover_mul(u,1.08883);return A(__tsover_sub(__tsover_sub(__tsover_mul(p,3.2404542),__tsover_mul(_,1.5371385)),__tsover_mul(f,.4985314)),__tsover_add(__tsover_add(__tsover_mul(p,-.969266),__tsover_mul(_,1.8760108)),__tsover_mul(f,.041556)),__tsover_add(__tsover_sub(__tsover_mul(p,.0556434),__tsover_mul(_,.2040259)),__tsover_mul(f,1.0572252)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lab\"}],body:[0,[[13,\"L\",[7,\"lab\",\"x\"]],[13,\"a\",[7,\"lab\",\"y\"]],[13,\"b\",[7,\"lab\",\"z\"]],[13,\"fy\",[1,[1,\"L\",\"+\",[5,\"16\"]],\"/\",[5,\"116\"]]],[13,\"fx\",[1,[1,\"a\",\"/\",\"LAB_KAPPA\"],\"+\",\"fy\"]],[13,\"fz\",[1,\"fy\",\"-\",[1,\"b\",\"/\",\"LAB_LAMBDA\"]]],[13,\"xn\",[6,\"std.select\",[[1,[1,\"fx\",\"-\",\"LAB_OFFSET\"],\"*\",\"LAB_INV_SLOPE\"],[6,\"std.pow\",[\"fx\",[5,\"3\"]]],[1,\"fx\",\">\",\"LAB_DELTA\"]]]],[13,\"yn\",[6,\"std.select\",[[1,[1,\"fy\",\"-\",\"LAB_OFFSET\"],\"*\",\"LAB_INV_SLOPE\"],[6,\"std.pow\",[\"fy\",[5,\"3\"]]],[1,\"fy\",\">\",\"LAB_DELTA\"]]]],[13,\"zn\",[6,\"std.select\",[[1,[1,\"fz\",\"-\",\"LAB_OFFSET\"],\"*\",\"LAB_INV_SLOPE\"],[6,\"std.pow\",[\"fz\",[5,\"3\"]]],[1,\"fz\",\">\",\"LAB_DELTA\"]]]],[13,\"x\",[1,\"xn\",\"*\",[5,\"0.95047\"]]],[13,\"y\",[1,\"yn\",\"*\",[5,\"1\"]]],[13,\"z\",[1,\"zn\",\"*\",[5,\"1.08883\"]]],[13,\"r\",[1,[1,[1,\"x\",\"*\",[5,\"3.2404542\"]],\"-\",[1,\"y\",\"*\",[5,\"1.5371385\"]]],\"-\",[1,\"z\",\"*\",[5,\"0.4985314\"]]]],[13,\"g\",[1,[1,[1,\"x\",\"*\",[4,\"-\",[5,\"0.969266\"]]],\"+\",[1,\"y\",\"*\",[5,\"1.8760108\"]]],\"+\",[1,\"z\",\"*\",[5,\"0.041556\"]]]],[13,\"bRgb\",[1,[1,[1,\"x\",\"*\",[5,\"0.0556434\"]],\"-\",[1,\"y\",\"*\",[5,\"0.2040259\"]]],\"+\",[1,\"z\",\"*\",[5,\"1.0572252\"]]]],[10,[6,\"d.vec3f\",[\"r\",\"g\",\"bRgb\"]]]]]},externals:{LAB_KAPPA:()=>fv,LAB_LAMBDA:()=>vv,\"std.select\":()=>N,LAB_OFFSET:()=>jl,LAB_INV_SLOPE:()=>n1,\"std.pow\":()=>vt,LAB_DELTA:()=>Zn,\"d.vec3f\":()=>A}})&&e.f)({})),Bm=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z;return A(s,Ue(__tsover_add(__tsover_mul(r,r),__tsover_mul(o,o))),Xt(o,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lab\"}],body:[0,[[13,\"L\",[7,\"lab\",\"x\"]],[13,\"a\",[7,\"lab\",\"y\"]],[13,\"b\",[7,\"lab\",\"z\"]],[13,\"C\",[6,\"std.sqrt\",[[1,[1,\"a\",\"*\",\"a\"],\"+\",[1,\"b\",\"*\",\"b\"]]]]],[13,\"h\",[6,\"std.atan2\",[\"b\",\"a\"]]],[10,[6,\"d.vec3f\",[\"L\",\"C\",\"h\"]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.atan2\":()=>Xt,\"d.vec3f\":()=>A}})&&e.f)({})),yd=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.x,r=t.y,o=t.z;return A(s,__tsover_mul(r,pe(o)),__tsover_mul(r,ae(o)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lch\"}],body:[0,[[13,\"L\",[7,\"lch\",\"x\"]],[13,\"C\",[7,\"lch\",\"y\"]],[13,\"h\",[7,\"lch\",\"z\"]],[10,[6,\"d.vec3f\",[\"L\",[1,\"C\",\"*\",[6,\"std.cos\",[\"h\"]]],[1,\"C\",\"*\",[6,\"std.sin\",[\"h\"]]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),Mr=w.fn([A,A,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return t.mul(r).add(s.mul(o)).div(a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"wA\"},{type:\"i\",name:\"wB\"},{type:\"i\",name:\"sw\"}],body:[0,[[10,[6,[7,[6,[7,[6,[7,\"a\",\"mul\"],[\"wA\"]],\"add\"],[[6,[7,\"b\",\"mul\"],[\"wB\"]]]],\"div\"],[\"sw\"]]]]]},externals:{}})&&e.f)({})),Ar=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Mr(t.xyz,s.xyz,o,a,l),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"rgb\",[6,\"awMix\",[[7,\"colorA\",\"xyz\"],[7,\"colorB\",\"xyz\"],\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S}})&&e.f)({})),Fk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Hs(oa(pl(Mr(Zl(Ta(Cr(t.xyz))),Zl(Ta(Cr(s.xyz))),o,a,l)))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"oklchA\",[6,\"oklabToOklch\",[[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"colorA\",\"xyz\"]]]]]]]],[13,\"oklchB\",[6,\"oklabToOklch\",[[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"colorB\",\"xyz\"]]]]]]]],[13,\"mixed\",[6,\"awMix\",[\"oklchA\",\"oklchB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[[6,\"oklchToOklab\",[\"mixed\"]]]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,oklabToOklch:()=>Zl,rgbToOklab:()=>Ta,p3ToSRGB:()=>Cr,awMix:()=>Mr,sRGBToP3:()=>Hs,oklabToRgb:()=>oa,oklchToOklab:()=>pl,\"d.vec4f\":()=>S}})&&e.f)({})),Ik=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Hs(oa(Mr(Ta(Cr(t.xyz)),Ta(Cr(s.xyz)),o,a,l))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"oklabA\",[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"colorA\",\"xyz\"]]]]]],[13,\"oklabB\",[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"colorB\",\"xyz\"]]]]]],[13,\"mixed\",[6,\"awMix\",[\"oklabA\",\"oklabB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[\"mixed\"]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,rgbToOklab:()=>Ta,p3ToSRGB:()=>Cr,awMix:()=>Mr,sRGBToP3:()=>Hs,oklabToRgb:()=>oa,\"d.vec4f\":()=>S}})&&e.f)({})),Yk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Hs(ml(Mr(cd(Cr(t.xyz)),cd(Cr(s.xyz)),o,a,l))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"hslA\",[6,\"rgbToHsl\",[[6,\"p3ToSRGB\",[[7,\"colorA\",\"xyz\"]]]]]],[13,\"hslB\",[6,\"rgbToHsl\",[[6,\"p3ToSRGB\",[[7,\"colorB\",\"xyz\"]]]]]],[13,\"mixed\",[6,\"awMix\",[\"hslA\",\"hslB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"hslToRgb\",[\"mixed\"]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,rgbToHsl:()=>cd,p3ToSRGB:()=>Cr,awMix:()=>Mr,sRGBToP3:()=>Hs,hslToRgb:()=>ml,\"d.vec4f\":()=>S}})&&e.f)({})),Wk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Hs(hd(Mr(Em(Cr(t.xyz)),Em(Cr(s.xyz)),o,a,l))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"hsvA\",[6,\"rgbToHsv\",[[6,\"p3ToSRGB\",[[7,\"colorA\",\"xyz\"]]]]]],[13,\"hsvB\",[6,\"rgbToHsv\",[[6,\"p3ToSRGB\",[[7,\"colorB\",\"xyz\"]]]]]],[13,\"mixed\",[6,\"awMix\",[\"hsvA\",\"hsvB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"hsvToRgb\",[\"mixed\"]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,rgbToHsv:()=>Em,p3ToSRGB:()=>Cr,awMix:()=>Mr,sRGBToP3:()=>Hs,hsvToRgb:()=>hd,\"d.vec4f\":()=>S}})&&e.f)({})),qk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_mul(s.w,r),i=__tsover_add(o,a),l=B(i,.001);return S(Hs(gd(yd(Mr(Bm(km(Cr(t.xyz))),Bm(km(Cr(s.xyz))),o,a,l)))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"lchA\",[6,\"labToLch\",[[6,\"rgbToLab\",[[6,\"p3ToSRGB\",[[7,\"colorA\",\"xyz\"]]]]]]]],[13,\"lchB\",[6,\"labToLch\",[[6,\"rgbToLab\",[[6,\"p3ToSRGB\",[[7,\"colorB\",\"xyz\"]]]]]]]],[13,\"mixed\",[6,\"awMix\",[\"lchA\",\"lchB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"labToRgb\",[[6,\"lchToLab\",[\"mixed\"]]]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,labToLch:()=>Bm,rgbToLab:()=>km,p3ToSRGB:()=>Cr,awMix:()=>Mr,sRGBToP3:()=>Hs,labToRgb:()=>gd,lchToLab:()=>yd,\"d.vec4f\":()=>S}})&&e.f)({})),No={0:Ar,1:Fk,2:Ik,3:Yk,4:Wk,5:qk},FJ=(e,t,s,r)=>(No[r]??Ar)(e,t,s),IJ=(e,t)=>{switch(t){case 1:return Zl(Ta(Cr(e)));case 2:return Ta(Cr(e));case 3:return cd(Cr(e));case 4:return Em(Cr(e));case 5:return Bm(km(Cr(e)));default:return e}},YJ=(e,t)=>{switch(t){case 1:return Hs(oa(pl(e)));case 2:return Hs(oa(e));case 3:return Hs(ml(e));case 4:return Hs(hd(e));case 5:return Hs(gd(yd(e)));default:return e}},Xa=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({conv:A,alpha:n}),\"MixStep\"),_l=w.fn([A,n,A,n,n],Xa)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(s,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return Xa({conv:Mr(t,r,i,l,B(c,.001)),alpha:c})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[10,[6,\"MixStep\",[[104,{conv:[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]],alpha:\"totalWeight\"}]]]]]]},externals:{\"std.max\":()=>B,MixStep:()=>Xa,awMix:()=>Mr}})&&e.f)({})),hc=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Mr(t,s,i,l,B(c,.001)),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[\"mixed\",\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S}})&&e.f)({})),Vk=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Hs(oa(pl(Mr(t,s,i,l,B(c,.001))))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[[6,\"oklchToOklab\",[\"mixed\"]]]]]],\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S,sRGBToP3:()=>Hs,oklabToRgb:()=>oa,oklchToOklab:()=>pl}})&&e.f)({})),Nk=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Hs(oa(Mr(t,s,i,l,B(c,.001)))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[\"mixed\"]]]],\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S,sRGBToP3:()=>Hs,oklabToRgb:()=>oa}})&&e.f)({})),$k=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Hs(ml(Mr(t,s,i,l,B(c,.001)))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[[6,\"sRGBToP3\",[[6,\"hslToRgb\",[\"mixed\"]]]],\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S,sRGBToP3:()=>Hs,hslToRgb:()=>ml}})&&e.f)({})),Xk=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Hs(hd(Mr(t,s,i,l,B(c,.001)))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[[6,\"sRGBToP3\",[[6,\"hsvToRgb\",[\"mixed\"]]]],\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S,sRGBToP3:()=>Hs,hsvToRgb:()=>hd}})&&e.f)({})),Hk=w.fn([A,A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,__tsover_sub(1,a)),l=__tsover_mul(o,a),c=__tsover_add(i,l);return S(Hs(gd(yd(Mr(t,s,i,l,B(c,.001))))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"convA\"},{type:\"i\",name:\"convB\"},{type:\"i\",name:\"alphaA\"},{type:\"i\",name:\"alphaB\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"weightA\",[1,\"alphaA\",\"*\",[1,[5,\"1\"],\"-\",\"t\"]]],[13,\"weightB\",[1,\"alphaB\",\"*\",\"t\"]],[13,\"totalWeight\",[1,\"weightA\",\"+\",\"weightB\"]],[13,\"safeWeight\",[6,\"std.max\",[\"totalWeight\",[5,\"0.001\"]]]],[13,\"mixed\",[6,\"awMix\",[\"convA\",\"convB\",\"weightA\",\"weightB\",\"safeWeight\"]]],[10,[6,\"d.vec4f\",[[6,\"sRGBToP3\",[[6,\"labToRgb\",[[6,\"lchToLab\",[\"mixed\"]]]]]],\"totalWeight\"]]]]]},externals:{\"std.max\":()=>B,awMix:()=>Mr,\"d.vec4f\":()=>S,sRGBToP3:()=>Hs,labToRgb:()=>gd,lchToLab:()=>yd}})&&e.f)({})),Bd={0:hc,1:Vk,2:Nk,3:$k,4:Xk,5:Hk},WJ=(e,t,s,r,o,a)=>(Bd[a]??hc)(e,t,s,r,o),W3=1e-4,_0=6/29,qJ=(e,t,s)=>[e*1.2249401-t*.2249404,e*-.0420569+t*1.0420571,e*-.0196376-t*.0786361+s*1.0982735],DT=(e,t,s)=>{let r=Math.cbrt(e*.4122214708+t*.5363325363+s*.0514459929),o=Math.cbrt(e*.2119034982+t*.6806995451+s*.1073969566),a=Math.cbrt(e*.0883024619+t*.2817188376+s*.6299787005);return[r*.2104542553+o*.793617785-a*.0040720468,r*1.9779984951-o*2.428592205+a*.4505937099,r*.0259040371+o*.7827717662-a*.808675766]},jk=(e,t,s,r,o)=>{let a=Math.max(o,W3);return(r===e?(t-s)/a:r===t?2+(s-e)/a:4+(e-t)/a)*(Math.PI/3)},VJ=(e,t,s)=>{let r=Math.max(e,t,s),o=Math.min(e,t,s),a=r-o,i=(r+o)*.5,l=a/Math.max(1-Math.abs(2*i-1),W3);return[jk(e,t,s,r,a),l,i]},NJ=(e,t,s)=>{let r=Math.max(e,t,s),o=r-Math.min(e,t,s),a=o/Math.max(r,W3);return[jk(e,t,s,r,o),a,r]},$J=(e,t,s)=>{let r=(e*.4124564+t*.3575761+s*.1804375)/.95047,o=e*.2126729+t*.7151522+s*.072175,a=(e*.0193339+t*.119192+s*.9503041)/1.08883,i=_0**3,l=p=>p>i?Math.cbrt(p):p/(3*_0*_0)+4/29,c=l(r),d=l(o),u=l(a);return[d*116-16,(c-d)*500,(d-u)*200]},fl=(e,t,s,r)=>{let[o,a,i]=qJ(e,t,s);switch(r){case 1:{let[l,c,d]=DT(o,a,i);return[l,Math.sqrt(c*c+d*d),Math.atan2(d,c)]}case 2:return DT(o,a,i);case 3:return VJ(o,a,i);case 4:return NJ(o,a,i);case 5:{let[l,c,d]=$J(o,a,i);return[l,Math.sqrt(c*c+d*d),Math.atan2(d,c)]}default:return[e,t,s]}},Kk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=K(A(t.x,t.y,t.z),A(s.x,s.y,s.z),A(r));return S(o.x,o.y,o.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"target\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]],[13,\"targetRgb\",[6,\"d.vec3f\",[[7,\"target\",\"x\"],[7,\"target\",\"y\"],[7,\"target\",\"z\"]]]],[13,\"mixed\",[6,\"std.mix\",[\"rgb\",\"targetRgb\",[6,\"d.vec3f\",[\"amount\"]]]]],[10,[6,\"d.vec4f\",[[7,\"mixed\",\"x\"],[7,\"mixed\",\"y\"],[7,\"mixed\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),Qk=ko({applyBlendMode:()=>XJ,blendModes:()=>pc,color:()=>l4,colorBurn:()=>p4,colorDodge:()=>n4,darken:()=>d4,difference:()=>a4,exclusion:()=>i4,hardLight:()=>f4,hue:()=>v4,lighten:()=>u4,linearBurn:()=>m4,linearDodge:()=>r4,luminance:()=>mn,luminosity:()=>c4,multiply:()=>t4,normal:()=>Zk,normalOklab:()=>e4,normalOklch:()=>Jk,overlay:()=>o4,saturation:()=>h4,screen:()=>s4,softLight:()=>_4,unpremultiplyAlpha:()=>Yt}),mn=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(__tsover_add(__tsover_mul(t.x,.2126),__tsover_mul(t.y,.7152)),__tsover_mul(t.z,.0722))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[1,[1,[1,[7,\"rgb\",\"x\"],\"*\",[5,\"0.2126\"]],\"+\",[1,[7,\"rgb\",\"y\"],\"*\",[5,\"0.7152\"]]],\"+\",[1,[7,\"rgb\",\"z\"],\"*\",[5,\"0.0722\"]]]]]]},externals:{}})&&e.f)({})),Pi=w.fn([A,A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return N(A(0),A(1),gb(s,t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"edge\"},{type:\"i\",name:\"x\"}],body:[0,[[10,[6,\"std.select\",[[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]],[6,\"std.ge\",[\"x\",\"edge\"]]]]]]]},externals:{\"std.select\":()=>N,\"d.vec3f\":()=>A,\"std.ge\":()=>gb}})&&e.f)({})),qs=w.fn([S,A,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t.w,__tsover_sub(1,r)),a=__tsover_add(r,o);return S(s.mul(r).add(t.xyz.mul(o)),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"blended\"},{type:\"i\",name:\"overlayAlpha\"}],body:[0,[[13,\"baseWeight\",[1,[7,\"base\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"overlayAlpha\"]]],[13,\"finalAlpha\",[1,\"overlayAlpha\",\"+\",\"baseWeight\"]],[13,\"rgb\",[6,[7,[6,[7,\"blended\",\"mul\"],[\"overlayAlpha\"]],\"add\"],[[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[\"baseWeight\"]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"finalAlpha\"]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),Yt=w.fn([S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.w;return S(N(A(0,0,0),t.xyz.div(s),s>.001),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"alpha\",[7,\"color\",\"w\"]],[13,\"straightRGB\",[6,\"std.select\",[[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,[7,[7,\"color\",\"xyz\"],\"div\"],[\"alpha\"]],[1,\"alpha\",\">\",[5,\"0.001\"]]]]],[10,[6,\"d.vec4f\",[\"straightRGB\",\"alpha\"]]]]]},externals:{\"std.select\":()=>N,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Zk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,s.xyz,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[10,[6,\"overComposite\",[\"base\",[7,\"overlay\",\"xyz\"],\"overlayAlpha\"]]]]]},externals:{overComposite:()=>qs}})&&e.f)({})),Jk=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=__tsover_mul(t.w,__tsover_sub(1,o)),i=__tsover_add(o,a),l=Zl(Ta(Cr(t.xyz)));return S(Hs(oa(pl(Zl(Ta(Cr(s.xyz))).mul(o).add(l.mul(a))))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseWeight\",[1,[7,\"base\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"overlayAlpha\"]]],[13,\"finalAlpha\",[1,\"overlayAlpha\",\"+\",\"baseWeight\"]],[13,\"baseOklch\",[6,\"oklabToOklch\",[[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"base\",\"xyz\"]]]]]]]],[13,\"overlayOklch\",[6,\"oklabToOklch\",[[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"overlay\",\"xyz\"]]]]]]]],[13,\"blendedOklch\",[6,[7,[6,[7,\"overlayOklch\",\"mul\"],[\"overlayAlpha\"]],\"add\"],[[6,[7,\"baseOklch\",\"mul\"],[\"baseWeight\"]]]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[[6,\"oklchToOklab\",[\"blendedOklch\"]]]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"finalAlpha\"]]]]]},externals:{oklabToOklch:()=>Zl,rgbToOklab:()=>Ta,p3ToSRGB:()=>Cr,sRGBToP3:()=>Hs,oklabToRgb:()=>oa,oklchToOklab:()=>pl,\"d.vec4f\":()=>S}})&&e.f)({})),e4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=__tsover_mul(t.w,__tsover_sub(1,o)),i=__tsover_add(o,a),l=Ta(Cr(t.xyz));return S(Hs(oa(Ta(Cr(s.xyz)).mul(o).add(l.mul(a)))),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseWeight\",[1,[7,\"base\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"overlayAlpha\"]]],[13,\"finalAlpha\",[1,\"overlayAlpha\",\"+\",\"baseWeight\"]],[13,\"baseOklab\",[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"base\",\"xyz\"]]]]]],[13,\"overlayOklab\",[6,\"rgbToOklab\",[[6,\"p3ToSRGB\",[[7,\"overlay\",\"xyz\"]]]]]],[13,\"blendedOklab\",[6,[7,[6,[7,\"overlayOklab\",\"mul\"],[\"overlayAlpha\"]],\"add\"],[[6,[7,\"baseOklab\",\"mul\"],[\"baseWeight\"]]]]],[13,\"rgb\",[6,\"sRGBToP3\",[[6,\"oklabToRgb\",[\"blendedOklab\"]]]]],[10,[6,\"d.vec4f\",[\"rgb\",\"finalAlpha\"]]]]]},externals:{rgbToOklab:()=>Ta,p3ToSRGB:()=>Cr,sRGBToP3:()=>Hs,oklabToRgb:()=>oa,\"d.vec4f\":()=>S}})&&e.f)({})),t4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,t.xyz.mul(s.xyz),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"overlay\",\"xyz\"]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{overComposite:()=>qs}})&&e.f)({})),s4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,As(1,As(1,t.xyz).mul(As(1,s.xyz))),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,\"std.sub\",[[5,\"1\"],[6,[7,[6,\"std.sub\",[[5,\"1\"],[7,\"base\",\"xyz\"]]],\"mul\"],[[6,\"std.sub\",[[5,\"1\"],[7,\"overlay\",\"xyz\"]]]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.sub\":()=>As,overComposite:()=>qs}})&&e.f)({})),r4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,t.xyz.add(s.xyz),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,[7,[7,\"base\",\"xyz\"],\"add\"],[[7,\"overlay\",\"xyz\"]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{overComposite:()=>qs}})&&e.f)({})),o4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,K(t.xyz.mul(s.xyz).mul(2),As(1,As(1,t.xyz).mul(As(1,s.xyz)).mul(2)),Pi(A(.5),t.xyz)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"mult\",[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"overlay\",\"xyz\"]]],\"mul\"],[[5,\"2\"]]]],[13,\"scr\",[6,\"std.sub\",[[5,\"1\"],[6,[7,[6,[7,[6,\"std.sub\",[[5,\"1\"],[7,\"base\",\"xyz\"]]],\"mul\"],[[6,\"std.sub\",[[5,\"1\"],[7,\"overlay\",\"xyz\"]]]]],\"mul\"],[[5,\"2\"]]]]]],[13,\"blended\",[6,\"std.mix\",[\"mult\",\"scr\",[6,\"step3\",[[6,\"d.vec3f\",[[5,\"0.5\"]]],[7,\"base\",\"xyz\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.sub\":()=>As,\"std.mix\":()=>K,step3:()=>Pi,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),a4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,re(t.xyz.sub(s.xyz)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,\"std.abs\",[[6,[7,[7,\"base\",\"xyz\"],\"sub\"],[[7,\"overlay\",\"xyz\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.abs\":()=>re,overComposite:()=>qs}})&&e.f)({})),n4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=As(1,s.xyz);return qs(t,K(t.xyz,ye(t.xyz.div(a),A(1)),Pi(A(.001),a)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"oneMinusOverlay\",[6,\"std.sub\",[[5,\"1\"],[7,\"overlay\",\"xyz\"]]]],[13,\"dodged\",[6,\"std.mix\",[[7,\"base\",\"xyz\"],[6,\"std.min\",[[6,[7,[7,\"base\",\"xyz\"],\"div\"],[\"oneMinusOverlay\"]],[6,\"d.vec3f\",[[5,\"1\"]]]]],[6,\"step3\",[[6,\"d.vec3f\",[[5,\"0.001\"]]],\"oneMinusOverlay\"]]]]],[10,[6,\"overComposite\",[\"base\",\"dodged\",\"overlayAlpha\"]]]]]},externals:{\"std.sub\":()=>As,\"std.mix\":()=>K,\"std.min\":()=>ye,\"d.vec3f\":()=>A,step3:()=>Pi,overComposite:()=>qs}})&&e.f)({})),i4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,t.xyz.add(s.xyz).sub(t.xyz.mul(s.xyz).mul(2)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"add\"],[[7,\"overlay\",\"xyz\"]]],\"sub\"],[[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"overlay\",\"xyz\"]]],\"mul\"],[[5,\"2\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{overComposite:()=>qs}})&&e.f)({})),l4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=mn(t.xyz),i=mn(s.xyz),l=__tsover_sub(a,i);return qs(t,s.xyz.add(l),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseLum\",[6,\"luminance\",[[7,\"base\",\"xyz\"]]]],[13,\"overlayLum\",[6,\"luminance\",[[7,\"overlay\",\"xyz\"]]]],[13,\"lumDiff\",[1,\"baseLum\",\"-\",\"overlayLum\"]],[13,\"blended\",[6,[7,[7,\"overlay\",\"xyz\"],\"add\"],[\"lumDiff\"]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{luminance:()=>mn,overComposite:()=>qs}})&&e.f)({})),c4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=mn(t.xyz),i=mn(s.xyz),l=__tsover_div(i,__tsover_add(a,1e-4));return qs(t,t.xyz.mul(l),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseLum\",[6,\"luminance\",[[7,\"base\",\"xyz\"]]]],[13,\"overlayLum\",[6,\"luminance\",[[7,\"overlay\",\"xyz\"]]]],[13,\"lumRatio\",[1,\"overlayLum\",\"/\",[1,\"baseLum\",\"+\",[5,\"0.0001\"]]]],[13,\"blended\",[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[\"lumRatio\"]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{luminance:()=>mn,overComposite:()=>qs}})&&e.f)({})),d4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,ye(t.xyz,s.xyz),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,\"std.min\",[[7,\"base\",\"xyz\"],[7,\"overlay\",\"xyz\"]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.min\":()=>ye,overComposite:()=>qs}})&&e.f)({})),u4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,B(t.xyz,s.xyz),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,\"std.max\",[[7,\"base\",\"xyz\"],[7,\"overlay\",\"xyz\"]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.max\":()=>B,overComposite:()=>qs}})&&e.f)({})),p4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=B(As(1,As(1,t.xyz).div(s.xyz.add(1e-4))),A(0));return qs(t,K(A(0),a,Pi(A(1e-4),s.xyz)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"burned\",[6,\"std.max\",[[6,\"std.sub\",[[5,\"1\"],[6,[7,[6,\"std.sub\",[[5,\"1\"],[7,\"base\",\"xyz\"]]],\"div\"],[[6,[7,[7,\"overlay\",\"xyz\"],\"add\"],[[5,\"0.0001\"]]]]]]],[6,\"d.vec3f\",[[5,\"0\"]]]]]],[13,\"blended\",[6,\"std.mix\",[[6,\"d.vec3f\",[[5,\"0\"]]],\"burned\",[6,\"step3\",[[6,\"d.vec3f\",[[5,\"0.0001\"]]],[7,\"overlay\",\"xyz\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.max\":()=>B,\"std.sub\":()=>As,\"d.vec3f\":()=>A,\"std.mix\":()=>K,step3:()=>Pi,overComposite:()=>qs}})&&e.f)({})),m4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,B(t.xyz.add(s.xyz).add(-1),A(0)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"blended\",[6,\"std.max\",[[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"add\"],[[7,\"overlay\",\"xyz\"]]],\"add\"],[[4,\"-\",[5,\"1\"]]]],[6,\"d.vec3f\",[[5,\"0\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.max\":()=>B,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),_4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=t.xyz.mul(s.xyz).mul(2),i=t.xyz.mul(t.xyz),l=a.add(i.mul(As(1,s.xyz.mul(2)))),c=Ue(t.xyz);return qs(t,K(l,t.xyz.mul(As(1,s.xyz)).mul(2).add(c.mul(s.xyz.mul(2).sub(1))),Pi(A(.5),s.xyz)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"mult\",[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"overlay\",\"xyz\"]]],\"mul\"],[[5,\"2\"]]]],[13,\"baseSquared\",[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"base\",\"xyz\"]]]],[13,\"softDark\",[6,[7,\"mult\",\"add\"],[[6,[7,\"baseSquared\",\"mul\"],[[6,\"std.sub\",[[5,\"1\"],[6,[7,[7,\"overlay\",\"xyz\"],\"mul\"],[[5,\"2\"]]]]]]]]]],[13,\"baseSqrt\",[6,\"std.sqrt\",[[7,\"base\",\"xyz\"]]]],[13,\"softLightVal\",[6,[7,[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[6,\"std.sub\",[[5,\"1\"],[7,\"overlay\",\"xyz\"]]]]],\"mul\"],[[5,\"2\"]]],\"add\"],[[6,[7,\"baseSqrt\",\"mul\"],[[6,[7,[6,[7,[7,\"overlay\",\"xyz\"],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]]]]]],[13,\"blended\",[6,\"std.mix\",[\"softDark\",\"softLightVal\",[6,\"step3\",[[6,\"d.vec3f\",[[5,\"0.5\"]]],[7,\"overlay\",\"xyz\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.sub\":()=>As,\"std.sqrt\":()=>Ue,\"std.mix\":()=>K,step3:()=>Pi,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),f4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r);return qs(t,K(t.xyz.mul(s.xyz).mul(2),As(1,As(1,t.xyz).mul(As(1,s.xyz)).mul(2)),Pi(A(.5),s.xyz)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"mult\",[6,[7,[6,[7,[7,\"base\",\"xyz\"],\"mul\"],[[7,\"overlay\",\"xyz\"]]],\"mul\"],[[5,\"2\"]]]],[13,\"scr\",[6,\"std.sub\",[[5,\"1\"],[6,[7,[6,[7,[6,\"std.sub\",[[5,\"1\"],[7,\"base\",\"xyz\"]]],\"mul\"],[[6,\"std.sub\",[[5,\"1\"],[7,\"overlay\",\"xyz\"]]]]],\"mul\"],[[5,\"2\"]]]]]],[13,\"blended\",[6,\"std.mix\",[\"mult\",\"scr\",[6,\"step3\",[[6,\"d.vec3f\",[[5,\"0.5\"]]],[7,\"overlay\",\"xyz\"]]]]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{\"std.sub\":()=>As,\"std.mix\":()=>K,step3:()=>Pi,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),v4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=mn(t.xyz),i=mn(s.xyz),l=t.xyz.sub(a),c=s.xyz.sub(i),d=he(l),u=he(c);return qs(t,N(A(0),c.div(u),u>1e-4).mul(d).add(a),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseLum\",[6,\"luminance\",[[7,\"base\",\"xyz\"]]]],[13,\"overlayLum\",[6,\"luminance\",[[7,\"overlay\",\"xyz\"]]]],[13,\"baseChromaticity\",[6,[7,[7,\"base\",\"xyz\"],\"sub\"],[\"baseLum\"]]],[13,\"overlayChromaticity\",[6,[7,[7,\"overlay\",\"xyz\"],\"sub\"],[\"overlayLum\"]]],[13,\"baseChromaLength\",[6,\"std.length\",[\"baseChromaticity\"]]],[13,\"overlayChromaLength\",[6,\"std.length\",[\"overlayChromaticity\"]]],[13,\"overlayChromaDir\",[6,\"std.select\",[[6,\"d.vec3f\",[[5,\"0\"]]],[6,[7,\"overlayChromaticity\",\"div\"],[\"overlayChromaLength\"]],[1,\"overlayChromaLength\",\">\",[5,\"0.0001\"]]]]],[13,\"blended\",[6,[7,[6,[7,\"overlayChromaDir\",\"mul\"],[\"baseChromaLength\"]],\"add\"],[\"baseLum\"]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{luminance:()=>mn,\"std.length\":()=>he,\"std.select\":()=>N,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),h4=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s.w,r),a=mn(t.xyz),i=mn(s.xyz),l=t.xyz.sub(a),c=s.xyz.sub(i),d=he(l),u=N(A(0),l.div(d),d>1e-4),p=he(c);return qs(t,u.mul(p).add(a),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"overlay\"},{type:\"i\",name:\"opacity\"}],body:[0,[[13,\"overlayAlpha\",[1,[7,\"overlay\",\"w\"],\"*\",\"opacity\"]],[13,\"baseLum\",[6,\"luminance\",[[7,\"base\",\"xyz\"]]]],[13,\"overlayLum\",[6,\"luminance\",[[7,\"overlay\",\"xyz\"]]]],[13,\"baseChromaticity\",[6,[7,[7,\"base\",\"xyz\"],\"sub\"],[\"baseLum\"]]],[13,\"overlayChromaticity\",[6,[7,[7,\"overlay\",\"xyz\"],\"sub\"],[\"overlayLum\"]]],[13,\"baseChromaLength\",[6,\"std.length\",[\"baseChromaticity\"]]],[13,\"baseChromaDir\",[6,\"std.select\",[[6,\"d.vec3f\",[[5,\"0\"]]],[6,[7,\"baseChromaticity\",\"div\"],[\"baseChromaLength\"]],[1,\"baseChromaLength\",\">\",[5,\"0.0001\"]]]]],[13,\"overlayChromaLength\",[6,\"std.length\",[\"overlayChromaticity\"]]],[13,\"blended\",[6,[7,[6,[7,\"baseChromaDir\",\"mul\"],[\"overlayChromaLength\"]],\"add\"],[\"baseLum\"]]],[10,[6,\"overComposite\",[\"base\",\"blended\",\"overlayAlpha\"]]]]]},externals:{luminance:()=>mn,\"std.length\":()=>he,\"std.select\":()=>N,\"d.vec3f\":()=>A,overComposite:()=>qs}})&&e.f)({})),pc={normal:Zk,\"normal-oklch\":Jk,\"normal-oklab\":e4,multiply:t4,screen:s4,linearDodge:r4,overlay:o4,difference:a4,colorDodge:n4,exclusion:i4,color:l4,luminosity:c4,darken:d4,lighten:u4,colorBurn:p4,linearBurn:m4,softLight:_4,hardLight:f4,hue:v4,saturation:h4},XJ=(e,t,s=\"normal\",r=1)=>(pc[s]??pc.normal)(e,t,r),i1=A(.2126,.7152,.0722),LT={alpha:w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t.xyz,__tsover_mul(t.w,s.w))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"target\"},{type:\"i\",name:\"mask\"}],body:[0,[[10,[6,\"d.vec4f\",[[7,\"target\",\"xyz\"],[1,[7,\"target\",\"w\"],\"*\",[7,\"mask\",\"w\"]]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),alphaInverted:w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t.xyz,__tsover_mul(t.w,__tsover_sub(1,s.w)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"target\"},{type:\"i\",name:\"mask\"}],body:[0,[[10,[6,\"d.vec4f\",[[7,\"target\",\"xyz\"],[1,[7,\"target\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",[7,\"mask\",\"w\"]]]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),luminance:w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Se(s.xyz,i1);return S(t.xyz,__tsover_mul(t.w,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"target\"},{type:\"i\",name:\"mask\"}],body:[0,[[13,\"lum\",[6,\"std.dot\",[[7,\"mask\",\"xyz\"],\"LUMINANCE_WEIGHTS\"]]],[10,[6,\"d.vec4f\",[[7,\"target\",\"xyz\"],[1,[7,\"target\",\"w\"],\"*\",\"lum\"]]]]]]},externals:{\"std.dot\":()=>Se,LUMINANCE_WEIGHTS:()=>i1,\"d.vec4f\":()=>S}})&&e.f)({})),luminanceInverted:w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Se(s.xyz,i1);return S(t.xyz,__tsover_mul(t.w,__tsover_sub(1,r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"target\"},{type:\"i\",name:\"mask\"}],body:[0,[[13,\"lum\",[6,\"std.dot\",[[7,\"mask\",\"xyz\"],\"LUMINANCE_WEIGHTS\"]]],[10,[6,\"d.vec4f\",[[7,\"target\",\"xyz\"],[1,[7,\"target\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"lum\"]]]]]]]},externals:{\"std.dot\":()=>Se,LUMINANCE_WEIGHTS:()=>i1,\"d.vec4f\":()=>S}})&&e.f)({}))},HJ=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return A(t.x,t.y,t.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[10,[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),jJ=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return G(t.div(t.add(1)),A(0),A(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[10,[6,\"std.clamp\",[[6,[7,\"color\",\"div\"],[[6,[7,\"color\",\"add\"],[[5,\"1\"]]]]],[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec3f\":()=>A}})&&e.f)({})),KJ=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=B(t.sub(.004),A(0)),r=s.mul(s.mul(6.2).add(.5)),o=s.mul(s.mul(6.2).add(1.7)).add(.06);return vt(r.div(o),A(2.2))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"c\",[6,\"std.max\",[[6,[7,\"color\",\"sub\"],[[5,\"0.004\"]]],[6,\"d.vec3f\",[[5,\"0\"]]]]]],[13,\"a\",[6,[7,\"c\",\"mul\"],[[6,[7,[6,[7,\"c\",\"mul\"],[[5,\"6.2\"]]],\"add\"],[[5,\"0.5\"]]]]]],[13,\"b\",[6,[7,[6,[7,\"c\",\"mul\"],[[6,[7,[6,[7,\"c\",\"mul\"],[[5,\"6.2\"]]],\"add\"],[[5,\"1.7\"]]]]],\"add\"],[[5,\"0.06\"]]]],[10,[6,\"std.pow\",[[6,[7,\"a\",\"div\"],[\"b\"]],[6,\"d.vec3f\",[[5,\"2.2\"]]]]]]]]},externals:{\"std.max\":()=>B,\"d.vec3f\":()=>A,\"std.pow\":()=>vt}})&&e.f)({})),UT=tp(.59719,.076,.0284,.35458,.90834,.13383,.04823,.01566,.83777),OT=tp(1.60475,-.10208,-.00327,-.53108,1.10813,-.07276,-.07367,-.00605,1.07602),GT=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.mul(t.add(.0245786)).sub(90537e-9),r=t.mul(t.add(.432951).mul(.983729)).add(.238081);return s.div(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[13,\"a\",[6,[7,[6,[7,\"v\",\"mul\"],[[6,[7,\"v\",\"add\"],[[5,\"0.0245786\"]]]]],\"sub\"],[[5,\"0.000090537\"]]]],[13,\"b\",[6,[7,[6,[7,\"v\",\"mul\"],[[6,[7,[6,[7,\"v\",\"add\"],[[5,\"0.432951\"]]],\"mul\"],[[5,\"0.983729\"]]]]],\"add\"],[[5,\"0.238081\"]]]],[10,[6,[7,\"a\",\"div\"],[\"b\"]]]]]},externals:{}})&&e.f)({})),QJ=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.div(.6);return s=UT.mul(s),s=GT(s),s=OT.mul(s),G(s,A(0),A(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[12,\"c\",[6,[7,\"color\",\"div\"],[[5,\"0.6\"]]]],[2,\"c\",\"=\",[6,\"ACES_INPUT.mul\",[\"c\"]]],[2,\"c\",\"=\",[6,\"rrtAndODTFit\",[\"c\"]]],[2,\"c\",\"=\",[6,\"ACES_OUTPUT.mul\",[\"c\"]]],[10,[6,\"std.clamp\",[\"c\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]]]]},externals:{\"ACES_INPUT.mul\":()=>UT.mul,rrtAndODTFit:()=>GT,\"ACES_OUTPUT.mul\":()=>OT.mul,\"std.clamp\":()=>G,\"d.vec3f\":()=>A}})&&e.f)({})),FT=tp(.6274,.0691,.0164,.3293,.9195,.088,.0433,.0113,.8956),IT=tp(1.6605,-.1246,-.0182,-.5876,1.1329,-.1006,-.0728,-.0083,1.1187),YT=tp(.856627153315983,.137318972929847,.11189821299995,.0951212405381588,.761241990602591,.0767994186031903,.0482516061458583,.101439036467562,.811302368396859),WT=tp(1.1271005818144368,-.1413297634984383,-.14132976349843826,-.11060664309660323,1.157823702216272,-.11060664309660294,-.016493938717834573,-.016493938717834257,1.2519364065950405),f0=-12.47393,qT=4.026069,VT=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.mul(t),r=s.mul(s);return r.mul(s).mul(15.5).sub(r.mul(t).mul(40.14)).add(r.mul(31.96).sub(s.mul(t).mul(6.868)).add(s.mul(.4298).add(t.mul(.1191).sub(.00232))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"}],body:[0,[[13,\"x2\",[6,[7,\"x\",\"mul\"],[\"x\"]]],[13,\"x4\",[6,[7,\"x2\",\"mul\"],[\"x2\"]]],[10,[6,[7,[6,[7,[6,[7,[6,[7,\"x4\",\"mul\"],[\"x2\"]],\"mul\"],[[5,\"15.5\"]]],\"sub\"],[[6,[7,[6,[7,\"x4\",\"mul\"],[\"x\"]],\"mul\"],[[5,\"40.14\"]]]]],\"add\"],[[6,[7,[6,[7,[6,[7,\"x4\",\"mul\"],[[5,\"31.96\"]]],\"sub\"],[[6,[7,[6,[7,\"x2\",\"mul\"],[\"x\"]],\"mul\"],[[5,\"6.868\"]]]]],\"add\"],[[6,[7,[6,[7,\"x2\",\"mul\"],[[5,\"0.4298\"]]],\"add\"],[[6,[7,[6,[7,\"x\",\"mul\"],[[5,\"0.1191\"]]],\"sub\"],[[5,\"0.00232\"]]]]]]]]]]]]},externals:{}})&&e.f)({})),ZJ=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=FT.mul(t);return s=YT.mul(s),s=B(s,A(1e-10)),s=vb(s),s=s.sub(f0).div(__tsover_sub(qT,f0)),s=G(s,A(0),A(1)),s=VT(s),s=WT.mul(s),s=vt(B(s,A(0)),A(2.2)),s=IT.mul(s),G(s,A(0),A(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[12,\"c\",[6,\"LINEAR_SRGB_TO_LINEAR_REC2020.mul\",[\"color\"]]],[2,\"c\",\"=\",[6,\"AGX_INSET.mul\",[\"c\"]]],[2,\"c\",\"=\",[6,\"std.max\",[\"c\",[6,\"d.vec3f\",[[5,\"1e-10\"]]]]]],[2,\"c\",\"=\",[6,\"std.log2\",[\"c\"]]],[2,\"c\",\"=\",[6,[7,[6,[7,\"c\",\"sub\"],[\"AGX_MIN_EV\"]],\"div\"],[[1,\"AGX_MAX_EV\",\"-\",\"AGX_MIN_EV\"]]]],[2,\"c\",\"=\",[6,\"std.clamp\",[\"c\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[2,\"c\",\"=\",[6,\"agxContrastApprox\",[\"c\"]]],[2,\"c\",\"=\",[6,\"AGX_OUTSET.mul\",[\"c\"]]],[2,\"c\",\"=\",[6,\"std.pow\",[[6,\"std.max\",[\"c\",[6,\"d.vec3f\",[[5,\"0\"]]]]],[6,\"d.vec3f\",[[5,\"2.2\"]]]]]],[2,\"c\",\"=\",[6,\"LINEAR_REC2020_TO_LINEAR_SRGB.mul\",[\"c\"]]],[10,[6,\"std.clamp\",[\"c\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]]]]},externals:{\"LINEAR_SRGB_TO_LINEAR_REC2020.mul\":()=>FT.mul,\"AGX_INSET.mul\":()=>YT.mul,\"std.max\":()=>B,\"d.vec3f\":()=>A,\"std.log2\":()=>vb,AGX_MIN_EV:()=>f0,AGX_MAX_EV:()=>qT,\"std.clamp\":()=>G,agxContrastApprox:()=>VT,\"AGX_OUTSET.mul\":()=>WT.mul,\"std.pow\":()=>vt,\"LINEAR_REC2020_TO_LINEAR_SRGB.mul\":()=>IT.mul}})&&e.f)({})),l1=.76,NT=.15,g4=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ye(t.x,ye(t.y,t.z)),r=N(.04,__tsover_sub(s,__tsover_mul(__tsover_mul(6.25,s),s)),s<.08),o=t.sub(r),a=B(o.x,B(o.y,o.z));if(a<l1)return o;let i=__tsover_sub(1,l1),l=__tsover_sub(1,__tsover_div(__tsover_mul(i,i),__tsover_sub(__tsover_add(a,i),l1)));o=o.mul(__tsover_div(l,a));let c=__tsover_sub(1,__tsover_div(1,__tsover_add(__tsover_mul(NT,__tsover_sub(a,l)),1)));return K(o,A(l),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"x\",[6,\"std.min\",[[7,\"color\",\"x\"],[6,\"std.min\",[[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]]]],[13,\"offset\",[6,\"std.select\",[[5,\"0.04\"],[1,\"x\",\"-\",[1,[1,[5,\"6.25\"],\"*\",\"x\"],\"*\",\"x\"]],[1,\"x\",\"<\",[5,\"0.08\"]]]]],[12,\"c\",[6,[7,\"color\",\"sub\"],[\"offset\"]]],[13,\"peak\",[6,\"std.max\",[[7,\"c\",\"x\"],[6,\"std.max\",[[7,\"c\",\"y\"],[7,\"c\",\"z\"]]]]]],[11,[1,\"peak\",\"<\",\"NEUTRAL_START_COMPRESSION\"],[0,[[10,\"c\"]]]],[13,\"dd\",[1,[5,\"1\"],\"-\",\"NEUTRAL_START_COMPRESSION\"]],[13,\"newPeak\",[1,[5,\"1\"],\"-\",[1,[1,\"dd\",\"*\",\"dd\"],\"/\",[1,[1,\"peak\",\"+\",\"dd\"],\"-\",\"NEUTRAL_START_COMPRESSION\"]]]],[2,\"c\",\"=\",[6,[7,\"c\",\"mul\"],[[1,\"newPeak\",\"/\",\"peak\"]]]],[13,\"g\",[1,[5,\"1\"],\"-\",[1,[5,\"1\"],\"/\",[1,[1,\"NEUTRAL_DESATURATION\",\"*\",[1,\"peak\",\"-\",\"newPeak\"]],\"+\",[5,\"1\"]]]]],[10,[6,\"std.mix\",[\"c\",[6,\"d.vec3f\",[\"newPeak\"]],\"g\"]]]]]},externals:{\"std.min\":()=>ye,\"std.select\":()=>N,\"std.max\":()=>B,NEUTRAL_START_COMPRESSION:()=>l1,NEUTRAL_DESATURATION:()=>NT,\"std.mix\":()=>K,\"d.vec3f\":()=>A}})&&e.f)({})),$T={linear:HJ,reinhard:jJ,cineon:KJ,aces:QJ,agx:ZJ,neutral:g4,hable:w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.mul(16),r=s.mul(s.mul(.15).add(.05)).add(.004),o=s.mul(s.mul(.15).add(.5)).add(.06);return r.div(o).sub(__tsover_div(.02,.3))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"x\",[6,[7,\"color\",\"mul\"],[[5,\"16\"]]]],[13,\"num\",[6,[7,[6,[7,\"x\",\"mul\"],[[6,[7,[6,[7,\"x\",\"mul\"],[[5,\"0.15\"]]],\"add\"],[[5,\"0.05\"]]]]],\"add\"],[[5,\"0.004\"]]]],[13,\"den\",[6,[7,[6,[7,\"x\",\"mul\"],[[6,[7,[6,[7,\"x\",\"mul\"],[[5,\"0.15\"]]],\"add\"],[[5,\"0.5\"]]]]],\"add\"],[[5,\"0.06\"]]]],[10,[6,[7,[6,[7,\"num\",\"div\"],[\"den\"]],\"sub\"],[[1,[5,\"0.02\"],\"/\",[5,\"0.3\"]]]]]]]},externals:{}})&&e.f)({})),unreal:w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return t.div(t.add(.155)).mul(1.019)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[10,[6,[7,[6,[7,\"color\",\"div\"],[[6,[7,\"color\",\"add\"],[[5,\"0.155\"]]]]],\"mul\"],[[5,\"1.019\"]]]]]]},externals:{}})&&e.f)({}))},Xm=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return N(vt(t,A(.41666)).mul(1.055).sub(.055),t.mul(12.92),qm(t,A(.0031308)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"a\",[6,[7,[6,[7,[6,\"std.pow\",[\"color\",[6,\"d.vec3f\",[[5,\"0.41666\"]]]]],\"mul\"],[[5,\"1.055\"]]],\"sub\"],[[5,\"0.055\"]]]],[13,\"b\",[6,[7,\"color\",\"mul\"],[[5,\"12.92\"]]]],[13,\"factor\",[6,\"std.le\",[\"color\",[6,\"d.vec3f\",[[5,\"0.0031308\"]]]]]],[10,[6,\"std.select\",[\"a\",\"b\",\"factor\"]]]]]},externals:{\"std.pow\":()=>vt,\"d.vec3f\":()=>A,\"std.le\":()=>qm,\"std.select\":()=>N}})&&e.f)({})),Iu=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return N(vt(t.add(A(.055)).div(A(1.055)),A(2.4)),t.div(A(12.92)),qm(t,A(.04045)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"hi\",[6,\"std.pow\",[[6,[7,[6,[7,\"color\",\"add\"],[[6,\"d.vec3f\",[[5,\"0.055\"]]]]],\"div\"],[[6,\"d.vec3f\",[[5,\"1.055\"]]]]],[6,\"d.vec3f\",[[5,\"2.4\"]]]]]],[13,\"lo\",[6,[7,\"color\",\"div\"],[[6,\"d.vec3f\",[[5,\"12.92\"]]]]]],[13,\"isLow\",[6,\"std.le\",[\"color\",[6,\"d.vec3f\",[[5,\"0.04045\"]]]]]],[10,[6,\"std.select\",[\"hi\",\"lo\",\"isLow\"]]]]]},externals:{\"std.pow\":()=>vt,\"d.vec3f\":()=>A,\"std.le\":()=>qm,\"std.select\":()=>N}})&&e.f)({})),el=e=>e?e.offsetX!==0||e.offsetY!==0||e.rotation!==0||e.scale!==1||e.anchorX!==.5||e.anchorY!==.5:!1,JJ=w.fn([m,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_div(__tsover_mul(o,Math.PI),180),u=pe(d),p=ae(d),_=__tsover_div(__tsover_sub(t.x,i),a),f=__tsover_div(__tsover_sub(t.y,l),a),h=__tsover_mul(_,c),g=f,y=__tsover_sub(__tsover_mul(h,u),__tsover_mul(g,p)),b=__tsover_add(__tsover_mul(h,p),__tsover_mul(g,u));return m(__tsover_add(__tsover_sub(__tsover_div(y,c),s),i),__tsover_add(__tsover_sub(b,r),l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"offsetX\"},{type:\"i\",name:\"offsetY\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"anchorX\"},{type:\"i\",name:\"anchorY\"},{type:\"i\",name:\"aspectRatio\"}],body:[0,[[13,\"rotationRad\",[1,[1,\"rotation\",\"*\",\"Math.PI\"],\"/\",[5,\"180\"]]],[13,\"cosAngle\",[6,\"std.cos\",[\"rotationRad\"]]],[13,\"sinAngle\",[6,\"std.sin\",[\"rotationRad\"]]],[13,\"centeredX\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"anchorX\"],\"/\",\"scale\"]],[13,\"centeredY\",[1,[1,[7,\"uv\",\"y\"],\"-\",\"anchorY\"],\"/\",\"scale\"]],[13,\"squareX\",[1,\"centeredX\",\"*\",\"aspectRatio\"]],[13,\"squareY\",\"centeredY\"],[13,\"rotatedSquareX\",[1,[1,\"squareX\",\"*\",\"cosAngle\"],\"-\",[1,\"squareY\",\"*\",\"sinAngle\"]]],[13,\"rotatedSquareY\",[1,[1,\"squareX\",\"*\",\"sinAngle\"],\"+\",[1,\"squareY\",\"*\",\"cosAngle\"]]],[13,\"finalX\",[1,[1,[1,\"rotatedSquareX\",\"/\",\"aspectRatio\"],\"-\",\"offsetX\"],\"+\",\"anchorX\"]],[13,\"finalY\",[1,[1,\"rotatedSquareY\",\"-\",\"offsetY\"],\"+\",\"anchorY\"]],[10,[6,\"d.vec2f\",[\"finalX\",\"finalY\"]]]]]},externals:{\"Math.PI\":()=>Math.PI,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({}));w.fn([m,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_add(__tsover_sub(t.x,i),s),u=__tsover_add(__tsover_sub(t.y,l),r),p=__tsover_mul(d,c),_=u,f=-__tsover_div(__tsover_mul(o,Math.PI),180),h=pe(f),g=ae(f),y=__tsover_sub(__tsover_mul(p,h),__tsover_mul(_,g)),b=__tsover_add(__tsover_mul(p,g),__tsover_mul(_,h)),x=__tsover_mul(__tsover_div(y,c),a),P=__tsover_mul(b,a);return m(__tsover_add(x,i),__tsover_add(P,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"offsetX\"},{type:\"i\",name:\"offsetY\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"anchorX\"},{type:\"i\",name:\"anchorY\"},{type:\"i\",name:\"aspectRatio\"}],body:[0,[[13,\"centeredX\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"anchorX\"],\"+\",\"offsetX\"]],[13,\"centeredY\",[1,[1,[7,\"uv\",\"y\"],\"-\",\"anchorY\"],\"+\",\"offsetY\"]],[13,\"squareX\",[1,\"centeredX\",\"*\",\"aspectRatio\"]],[13,\"squareY\",\"centeredY\"],[13,\"rotationRad\",[4,\"-\",[1,[1,\"rotation\",\"*\",\"Math.PI\"],\"/\",[5,\"180\"]]]],[13,\"cosAngle\",[6,\"std.cos\",[\"rotationRad\"]]],[13,\"sinAngle\",[6,\"std.sin\",[\"rotationRad\"]]],[13,\"rotatedSquareX\",[1,[1,\"squareX\",\"*\",\"cosAngle\"],\"-\",[1,\"squareY\",\"*\",\"sinAngle\"]]],[13,\"rotatedSquareY\",[1,[1,\"squareX\",\"*\",\"sinAngle\"],\"+\",[1,\"squareY\",\"*\",\"cosAngle\"]]],[13,\"scaledX\",[1,[1,\"rotatedSquareX\",\"/\",\"aspectRatio\"],\"*\",\"scale\"]],[13,\"scaledY\",[1,\"rotatedSquareY\",\"*\",\"scale\"]],[10,[6,\"d.vec2f\",[[1,\"scaledX\",\"+\",\"anchorX\"],[1,\"scaledY\",\"+\",\"anchorY\"]]]]]]},externals:{\"Math.PI\":()=>Math.PI,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({}));var q3=(e,t,s)=>{let r=x=>x.unit===\"px\"?x.value/t:x.value,o=x=>x.unit===\"px\"?x.value/s:x.value,a=r(e.x),i=o(e.y),l=r(e.width),c=o(e.height),d=(x,P,C)=>C===\"end\"?1-x-P:C===\"center\"?.5+x-P/2:x,u=e.origin??\"top-left\",p=u.includes(\"left\")?\"start\":u.includes(\"right\")?\"end\":\"center\",_=u.includes(\"top\")?\"start\":u.includes(\"bottom\")?\"end\":\"center\",f=d(a,l,p),h=d(i,c,_),g=f+l/2,y=h+c/2,b=e.cornerRadius?e.cornerRadius.unit===\"px\"?e.cornerRadius.value/s:e.cornerRadius.value:0;return{centerX:g,centerY:y,halfWidthUV:l/2,halfHeightUV:c/2,cornerRadiusUV:b,rotation:e.rotation}},eee=w.fn([m,n,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=__tsover_sub(t.x,s),p=__tsover_sub(t.y,r),_=-__tsover_div(__tsover_mul(l,Math.PI),180),f=pe(_),h=ae(_),g=__tsover_mul(u,c),y=p,b=__tsover_sub(__tsover_mul(g,f),__tsover_mul(y,h)),x=__tsover_add(__tsover_mul(g,h),__tsover_mul(y,f)),P=__tsover_mul(o,c),C=a,E=__tsover_sub(P,i),R=__tsover_sub(C,i),U=__tsover_sub(re(b),E),L=__tsover_sub(re(x),R),k=m(B(U,0),B(L,0)),D=__tsover_sub(__tsover_add(he(k),ye(B(U,L),0)),i),O=B(d,1e-7);return N(__tsover_sub(1,be(-O,O,D)),N(n(0),n(1),D<=0),d<=0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"centerX\"},{type:\"i\",name:\"centerY\"},{type:\"i\",name:\"halfWidth\"},{type:\"i\",name:\"halfHeight\"},{type:\"i\",name:\"cornerRadius\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"aspectRatio\"},{type:\"i\",name:\"aaFeather\"}],body:[0,[[13,\"centeredX\",[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"]],[13,\"centeredY\",[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"]],[13,\"rotRad\",[4,\"-\",[1,[1,\"rotation\",\"*\",\"Math.PI\"],\"/\",[5,\"180\"]]]],[13,\"cosA\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"sqX\",[1,\"centeredX\",\"*\",\"aspectRatio\"]],[13,\"sqY\",\"centeredY\"],[13,\"rotatedX\",[1,[1,\"sqX\",\"*\",\"cosA\"],\"-\",[1,\"sqY\",\"*\",\"sinA\"]]],[13,\"rotatedY\",[1,[1,\"sqX\",\"*\",\"sinA\"],\"+\",[1,\"sqY\",\"*\",\"cosA\"]]],[13,\"halfWidthSq\",[1,\"halfWidth\",\"*\",\"aspectRatio\"]],[13,\"halfHeightSq\",\"halfHeight\"],[13,\"innerHalfW\",[1,\"halfWidthSq\",\"-\",\"cornerRadius\"]],[13,\"innerHalfH\",[1,\"halfHeightSq\",\"-\",\"cornerRadius\"]],[13,\"qx\",[1,[6,\"std.abs\",[\"rotatedX\"]],\"-\",\"innerHalfW\"]],[13,\"qy\",[1,[6,\"std.abs\",[\"rotatedY\"]],\"-\",\"innerHalfH\"]],[13,\"qClamped\",[6,\"d.vec2f\",[[6,\"std.max\",[\"qx\",[5,\"0\"]]],[6,\"std.max\",[\"qy\",[5,\"0\"]]]]]],[13,\"sdf\",[1,[1,[6,\"std.length\",[\"qClamped\"]],\"+\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",\"qy\"]],[5,\"0\"]]]],\"-\",\"cornerRadius\"]],[13,\"feather\",[6,\"std.max\",[\"aaFeather\",[5,\"1e-7\"]]]],[13,\"ramp\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"feather\"],\"feather\",\"sdf\"]]]],[13,\"binary\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"sdf\",\"<=\",[5,\"0\"]]]]],[10,[6,\"std.select\",[\"ramp\",\"binary\",[1,\"aaFeather\",\"<=\",[5,\"0\"]]]]]]]},externals:{\"Math.PI\":()=>Math.PI,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.abs\":()=>re,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.length\":()=>he,\"std.min\":()=>ye,\"std.smoothstep\":()=>be,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})),XT=w.fn([m,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_sub(t.x,s),d=__tsover_sub(t.y,r),u=-__tsover_div(__tsover_mul(i,Math.PI),180),p=pe(u),_=ae(u),f=__tsover_mul(c,l),h=d,g=__tsover_sub(__tsover_mul(f,p),__tsover_mul(h,_)),y=__tsover_add(__tsover_mul(f,_),__tsover_mul(h,p)),b=B(__tsover_mul(o,l),1e-6),x=B(a,1e-6);return m(__tsover_add(__tsover_div(g,__tsover_mul(b,2)),.5),__tsover_add(__tsover_div(y,__tsover_mul(x,2)),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"centerX\"},{type:\"i\",name:\"centerY\"},{type:\"i\",name:\"halfWidth\"},{type:\"i\",name:\"halfHeight\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"aspectRatio\"}],body:[0,[[13,\"centeredX\",[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"]],[13,\"centeredY\",[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"]],[13,\"rotRad\",[4,\"-\",[1,[1,\"rotation\",\"*\",\"Math.PI\"],\"/\",[5,\"180\"]]]],[13,\"cosA\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"sqX\",[1,\"centeredX\",\"*\",\"aspectRatio\"]],[13,\"sqY\",\"centeredY\"],[13,\"rotatedX\",[1,[1,\"sqX\",\"*\",\"cosA\"],\"-\",[1,\"sqY\",\"*\",\"sinA\"]]],[13,\"rotatedY\",[1,[1,\"sqX\",\"*\",\"sinA\"],\"+\",[1,\"sqY\",\"*\",\"cosA\"]]],[13,\"halfWidthSq\",[6,\"std.max\",[[1,\"halfWidth\",\"*\",\"aspectRatio\"],[5,\"0.000001\"]]]],[13,\"halfHeightSq\",[6,\"std.max\",[\"halfHeight\",[5,\"0.000001\"]]]],[13,\"localX\",[1,[1,\"rotatedX\",\"/\",[1,\"halfWidthSq\",\"*\",[5,\"2\"]]],\"+\",[5,\"0.5\"]]],[13,\"localY\",[1,[1,\"rotatedY\",\"/\",[1,\"halfHeightSq\",\"*\",[5,\"2\"]]],\"+\",[5,\"0.5\"]]],[10,[6,\"d.vec2f\",[\"localX\",\"localY\"]]]]]},externals:{\"Math.PI\":()=>Math.PI,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),y4=(e,t,s)=>{let r=s.rotationDeg*Math.PI/180,o=Math.cos(r),a=Math.sin(r),i=(e-s.centerX)*s.aspectRatio,l=t-s.centerY,c=i*o+l*a,d=i*-a+l*o,u=Math.max(s.halfWidthUV*s.aspectRatio,1e-6),p=Math.max(s.halfHeightUV,1e-6);return{x:c/(2*u)+.5,y:d/(2*p)+.5}},ym={x:{value:0,unit:\"uv\"},y:{value:0,unit:\"uv\"},width:{value:1,unit:\"uv\"},height:{value:1,unit:\"uv\"},origin:\"top-left\",rotation:0};function Ih(e){if(!e||typeof e!=\"object\")return;let t=(s,r)=>s&&typeof s==\"object\"?{value:s.value??r.value,unit:s.unit??r.unit}:{...r};return{x:t(e.x,ym.x),y:t(e.y,ym.y),width:t(e.width,ym.width),height:t(e.height,ym.height),origin:e.origin??\"top-left\",rotation:e.rotation??0,...e.cornerRadius?{cornerRadius:e.cornerRadius}:{},...e.lockAspect!==void 0?{lockAspect:e.lockAspect}:{}}}function Yh(e){if(!e||typeof e!=\"object\")return!1;let t=(s,r)=>!!s&&s.unit===\"uv\"&&s.value===r;return t(e.x,0)&&t(e.y,0)&&t(e.width,1)&&t(e.height,1)&&(e.rotation??0)===0&&(e.cornerRadius?.value??0)===0}var fs=class L1{_emit;constructor(t){this._emit=t}member(t){return new L1(s=>`${tee(this._emit(s))}.${t}`)}mul(t){return new L1(s=>`(${this._emit(s)} * ${HT(t,s)})`)}add(t){return new L1(s=>`(${this._emit(s)} + ${HT(t,s)})`)}};function tee(e){return/^[\\w.$]+$/.test(e)?e:`(${e})`}function HT(e,t){return typeof e==\"number\"?fo(e):e._emit(t)}function fo(e){return Number.isFinite(e)?Number.isInteger(e)?`${e}.0`:`${e}`:e>0?\"3.4e38\":e<0?\"-3.4e38\":\"0.0\"}var V3=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({linearClamp:{sampler:\"filtering\"},nearestClamp:{sampler:\"filtering\"},linearRepeat:{sampler:\"filtering\"},nearestRepeat:{sampler:\"filtering\"}}).$idx(2),\"SHARED_SAMPLER_LAYOUT\"),bm={uniforms:0,textures:1,samplers:2,external:3};function ca(e){return new fs(()=>e)}function $e(e){return new fs(()=>fo(e))}function W(e,t,s){return new fs(r=>`${r.external(e,t)}(${s.map(o=>o._emit(r)).join(\", \")})`)}function Ct(...e){return new fs(t=>`vec4f(${e.map(s=>b4(s,t)).join(\", \")})`)}function ea(e,t,s){return new fs(r=>`mix(${e._emit(r)}, ${t._emit(r)}, ${b4(s,r)})`)}function see(e,t){return new fs(s=>`array<${e}, ${t.length}>(${t.map(r=>r._emit(s)).join(\", \")})`)}var ree=0;function ns(e,t){let s=ree++;return new fs(r=>r.memo(`local:${s}`,()=>{let o=r.freshLocal(t);return r.statement(`let ${o} = ${e._emit(r)};`),o}))}var xt=ca(\"vec4f(0.0, 0.0, 0.0, 0.0)\"),v0=ca(\"vec4f(1.0, 1.0, 1.0, 0.0)\");function b4(e,t){return typeof e==\"number\"?fo(e):e._emit(t)}function Fl(e,t,s,r){return W(pc[s]??pc.normal,`blend_${hv(s)}`,[e,t,r])}function oee(e,t,s){return W(LT[s]??LT.alpha,`mask_${hv(s)}`,[e,t])}function hv(e){return e.replace(/[^a-zA-Z0-9_]/g,\"_\")}function jT(e,t,s,r){let o={},a=new Map,i=new Set,l=[],c=new Map,d=0,u={external(g,y){let b=a.get(g);if(b)return b;let x=hv(y);if(i.has(x)){let P=1;for(;i.has(`${x}_${P}`);)P++;x=`${x}_${P}`}return i.add(x),a.set(g,x),o[x]=g,x},statement(g){l.push(g)},freshLocal(g){return`${hv(g)}_${d++}`},memo(g,y){let b=c.get(g);if(b!==void 0)return b;let x=y();return c.set(g,x),x}},p=s?\"vec2f(in.uv.x, 1.0 - in.uv.y)\":\"in.uv\";l.push(`var uv = ${p};`);let _=e._emit(u),f=t(_,u),h=`${l.join(`\n`)}\n${_}\n${f}`;return r&&/\\b(?:tex|samp|ext)\\.\\$\\./.test(h)&&!/\\buni\\.\\$\\./.test(h)&&(u.external(r,\"uni\"),l.unshift(\"_ = uni.$.uniforms._sys.time;\")),{body:`{\n  ${l.join(`\n  `)}\n  return ${f};\n}`,externals:o}}function x4(e,t={}){let s={sampler:V3},r=[],o=[],a=[],i=[],l=new Set,c=[],d=[],u=[],p=[],_=0,f=0,h=0,g=0,y=new Set,b=e.store.layout;b&&b.$idx(bm.uniforms),s.uniform=b;let x=_e=>new fs(We=>(b&&We.external(b,\"uni\"),_e)),P=_e=>x(`uni.$.uniforms.${_e}`),C=_e=>x(e.store.gpuAccessor(_e,\"uni\")),E={uv:new fs(()=>\"uv\"),time:P(\"_sys.time\"),viewportSize:P(\"_sys.viewportSize\"),logicalViewportSize:P(\"_sys.logicalViewportSize\"),aspect:P(\"_sys.aspect\"),pointer:P(\"_sys.pointer\")},R=_e=>({key:_e,sample:(We,Le=\"linearClamp\")=>new fs(Be=>`textureSample(tex.$.${_e}, samp.$.${Le}, ${We._emit(Be)})`),sampleLevel:(We,Le=\"linearClamp\")=>new fs(Be=>`textureSampleLevel(tex.$.${_e}, samp.$.${Le}, ${We._emit(Be)}, 0.0)`),accessor:()=>new fs(()=>`tex.$.${_e}`),dimensions:()=>new fs(()=>`vec2f(textureDimensions(tex.$.${_e}))`)}),U=_e=>({key:_e,sample:(We,Le=\"linearClamp\")=>new fs(Be=>`textureSampleBaseClampToEdge(ext.$.${_e}, samp.$.${Le}, ${We._emit(Be)})`),sampleLevel:(We,Le=\"linearClamp\")=>new fs(Be=>`textureSampleBaseClampToEdge(ext.$.${_e}, samp.$.${Le}, ${We._emit(Be)})`),accessor:()=>new fs(()=>`ext.$.${_e}`),dimensions:()=>new fs(()=>`vec2f(textureDimensions(ext.$.${_e}))`)}),L=_e=>{let We=`rtt_${_++}`;return r.push({key:We,root:_e}),o.push({key:We,kind:\"rtt\"}),R(We)},k=new Map,D=(_e,We,Le)=>{let Be=`${_e.id}:${We}`,Oe=k.get(Be);if(Oe!==void 0)return Oe;let tt=Le?e.resolveCustomId(Le):null,_t=tt?L(pt(tt,new Set([_e.id]))):null;return k.set(Be,_t),_t},O=new Map,F=_e=>{let We=O.get(_e.id);if(We)return We;let Le={},Be=_e.metadata.maps;if(Be){let Oe={},tt=_e.definition.mapSampleUVs;if(tt){let _t={};for(let[Bt,Dt]of Object.entries(_e.handles))Dt.cpu||(_t[Bt]=C(Dt));Oe=tt({uniforms:_t,ctx:E})??{}}for(let[_t,Bt]of Object.entries(Be)){if(!(_t in _e.handles))continue;let Dt=X(Bt,_e,_t,Oe[_t]);Dt&&(Le[_t]=Dt)}}return O.set(_e.id,Le),Le},q=_e=>{let We=Hn(_e.id),Le=_e.metadata.maps;if(!Le||Object.keys(Le).length===0)return P(We);let Be=F(_e);return Object.keys(Be).length===0?P(We):new fs(Oe=>Oe.memo(`props:${_e.id}`,()=>{b&&Oe.external(b,\"uni\");let tt=Oe.freshLocal(`p_${We}`);Oe.statement(`var ${tt} = uni.$.uniforms.${We};`);for(let[_t,Bt]of Object.entries(Be))Oe.statement(`${tt}.${_t} = ${Bt._emit(Oe)};`);return tt}))},Y=_e=>{let We={};for(let[Le,Be]of Object.entries(_e.handles))We[Le]=Be.value;return We},V=_e=>{let We={};Hn(_e.id);let Le=q(_e);for(let[Oe,tt]of Object.entries(_e.handles)){if(tt.cpu)continue;let _t=_e.metadata.maps;_t&&Oe in _t?We[Oe]=Le.member(Oe):We[Oe]=C(tt)}let Be=_e.definition.extraFields;if(Be)for(let Oe of Object.keys(Be))We[Oe]=Le.member(Oe);return We},X=(_e,We,Le,Be)=>{let Oe=_e,tt=Hn(We.id);if(Oe.type===\"map\"){let _t=D(We,Le,Oe.source);return _t?iee(nee(_t.sample(Be??E.uv),Oe.channel??\"luminance\"),P(`${tt}._map_${Le}_inputMin`),P(`${tt}._map_${Le}_inputMax`),P(`${tt}._map_${Le}_outputMin`),P(`${tt}._map_${Le}_outputMax`),P(`${tt}._map_${Le}_curve`)):null}return Oe.type===\"mouse-position\"||Oe.type===\"mouse\"||Oe.type===\"auto-animate\"?P(`${tt}._smoothed_${Le}`):null},Q=(_e,We,Le,Be)=>{let Oe=We.metadata.mask;if(!Oe?.source)return _e;let tt=e.resolveCustomId(Oe.source);if(!tt)return _e;if(Le.has(tt))return console.error(\"[gpu] circular dependency in shader masks.\"),_e;let _t=new Set(Le);_t.add(We.id);let Bt=pt(tt,_t);return Be&&(Bt=L(Bt).sample(Be)),oee(_e,Bt,Oe.type??\"alpha\")},te=_e=>P(`${Hn(_e.id)}._opacity`),J=_e=>!!_e.metadata.boundingBox&&!!_e.definition.boundingBoxDeclaration&&!Yh(_e.metadata.boundingBox),oe=_e=>_e.handles.cutout?.value===1,le=_e=>!!_e.definition.requiresChild,se=_e=>!!_e.definition.blendWithChildren,Te=_e=>J(_e)&&!_e.definition.boundingBoxDeclaration?.boxResamplesContent&&le(_e)&&_e.metadata.blendMode===\"normal\"&&!oe(_e)&&!se(_e),de=()=>new fs(_e=>`(0.5 / max(${E.viewportSize.member(\"y\")._emit(_e)}, 1.0))`),xe=(_e,We=E.uv)=>{let Le=Hn(_e.id),Be=Oe=>P(`${Le}._bbox_${Oe}`);return W(eee,\"bboxClipMask\",[We,Be(\"centerX\"),Be(\"centerY\"),Be(\"halfWidth\"),Be(\"halfHeight\"),Be(\"cornerRadius\"),Be(\"rotation\"),Be(\"aspectRatio\"),de()])},Ae=(_e,We)=>{if(!J(We))return _e;if(We.definition.boundingBoxDeclaration?.boxResamplesContent){let Be=Hn(We.id),Oe=Dt=>P(`${Be}._bbox_${Dt}`),tt=L(_e),_t=W(XT,\"bboxGenUVContext\",[E.uv,Oe(\"centerX\"),Oe(\"centerY\"),Oe(\"halfWidth\"),Oe(\"halfHeight\"),Oe(\"rotation\"),Oe(\"aspectRatio\")]),Bt=W(Yt,\"unpremultiplyAlpha\",[tt.sample(_t)]);return Ct(Bt.member(\"rgb\"),Bt.member(\"a\").mul(xe(We)))}let Le=xe(We);return Ct(_e.member(\"rgb\"),_e.member(\"a\").mul(Le))},De=(_e,We)=>{let Le=We.metadata.transform;if(!Le||!el(Le))return _e;let Be=Hn(We.id),Oe=L(_e),tt=_t=>P(`${Be}._xform_${_t}`);return Ha(W(JJ,\"applyUVTransform\",[E.uv,tt(\"offsetX\"),tt(\"offsetY\"),tt(\"rotation\"),tt(\"scale\"),tt(\"anchorX\"),tt(\"anchorY\"),tt(\"aspectRatio\")]),_t=>Oe.sample(_t),lee[Le.edges]??0)},Ee=(_e,We,Le)=>J(Le)?We!==void 0&&Te(Le)?ea(We,_e,xe(Le)):Ae(_e,Le):De(_e,Le),ze=(_e,We)=>Te(We)?{transformedFragment:_e,clipMaskNode:xe(We)}:{transformedFragment:J(We)?Ae(_e,We):De(_e,We),clipMaskNode:void 0},Ie=(_e,We,Le,Be)=>{let Oe=te(Le),tt=se(Le)?_e!==void 0?Fl(_e,We,\"normal\",Oe):ea(xt,We,Oe):ea(_e??xt,We,Oe);return Be===void 0?tt:ea(_e??xt,tt,Be)},ke=(_e,We)=>{if(_e.definition.compute)try{let Le=_e.definition.compute(We);if(Le)return i.push({nodeId:_e.id,getComputeNodes:Le.getComputeNodes,bindInputs:Le.bindInputs}),Le.outputs}catch(Le){Sr(`[gpu] error initializing compute for node ${_e.id}:`,Le)}},Me=_e=>{let We=Hn(_e.id),Le=Be=>P(`${We}._bbox_${Be}`);return{centerX:Le(\"centerX\"),centerY:Le(\"centerY\"),halfWidth:Le(\"halfWidth\"),halfHeight:Le(\"halfHeight\"),rotation:Le(\"rotation\")}},we=_e=>{let We=_e.definition.boundingBoxDeclaration;return!!We&&(!!We.computeBounds||!!We.propBindings)},Ve=_e=>{if(!_e.definition.wantsBoundsParams)return{};let We={};J(_e)&&(We.ownBoundsParams=Me(_e));let Le=[...e.getChildren(_e.id)].sort((Be,Oe)=>Be.metadata.renderOrder-Oe.metadata.renderOrder);for(let Be of Le)if(Be.metadata.visible!==!1){if(J(Be)){We.childBoundsParams=Me(Be);break}if(we(Be)){let Oe=Hn(_e.id),tt=_t=>P(`${Oe}._childBounds_${_t}`);We.childBoundsParams={centerX:tt(\"centerX\"),centerY:tt(\"centerY\"),halfWidth:tt(\"halfWidth\"),halfHeight:tt(\"halfHeight\"),rotation:$e(0)};break}}return We},qe=!1,st=(_e,We,Le={})=>({noteCustomWgsl:()=>{qe=!0},props:q(_e),uniforms:V(_e),propValues:Y(_e),childNode:We,ctx:E,logicalViewportSize:E.logicalViewportSize,convertToTexture:L,declareTexture:Be=>{o.some(Oe=>Oe.key===Be.key)||o.push({key:Be.key,kind:\"media\",resource:Be._resource})},registerExternalTexture:Be=>{let Oe=`video_${h++}`;return a.push({key:Oe,getSource:Be}),U(Oe)},registerComputeTexture:Be=>{let Oe=`compute_${f++}`;o.push({key:Oe,kind:\"compute\",resource:{texture:Be}});let tt=Be?.props?.format;return(tt===\"r32float\"||tt===\"rg32float\"||tt===\"rgba32float\")&&y.add(Oe),R(Oe)},createMediaTexture:Be=>t.createMediaTexture?.(Be)??(()=>{throw new Error(\"[gpu] createMediaTexture unavailable (no TextureManager injected)\")})(),createDataTexture:Be=>t.createDataTexture?.(Be)??(()=>{throw new Error(\"[gpu] createDataTexture unavailable (no TextureManager injected)\")})(),registerMediaTexture:Be=>{let Oe=`media_${g++}`;return o.push({key:Oe,kind:\"media\",resource:{get texture(){return Be()}}}),R(Oe)},getCpuValue:Be=>{if((_e.metadata.maps?.[Be]||Be.startsWith(\"_animTime\"))&&t.resolveDriverCpuValue){let Oe=t.resolveDriverCpuValue(_e.id,Be);if(Oe!==void 0)return Oe}return _e.handles[Be]?.value},getMapInfo:Be=>{let Oe=_e.metadata.maps?.[Be];if(!Oe||Oe.type!==\"map\")return null;let tt=D(_e,Be,Oe.source);return tt?{sourceTexture:tt,channel:Oe.channel??\"luminance\",window:()=>t.resolveMapWindow?.(_e.id,Be)??{inputMin:typeof Oe.inputMin==\"number\"?Oe.inputMin:0,inputMax:typeof Oe.inputMax==\"number\"?Oe.inputMax:1,outputMin:typeof Oe.outputMin==\"number\"?Oe.outputMin:0,outputMax:typeof Oe.outputMax==\"number\"?Oe.outputMax:1,curve:typeof Oe.curve==\"number\"?Oe.curve:0}}:null},getLayerTexture:Be=>{let Oe=_e.handles[Be]?.value;return typeof Oe!=\"string\"||Oe===\"\"?null:D(_e,Be,Oe)},setExtraField:(Be,Oe)=>t.writeExtraField?.(_e.id,Be,Oe),onCleanup:Be=>p.push(Be),onBeforeRender:Be=>c.push(Be),onAfterRender:Be=>d.push(Be),onResize:Be=>u.push(Be),canvas:t.canvas,dimensions:t.dimensions??{width:1,height:1},gpu:t.gpu,domCanvas:_e.domCanvas,...Ve(_e),...Le});function pt(_e,We=new Set){let Le=e.getNode(_e);if(!Le)return xt;let Be=e.getChildren(_e);if(Be.length>0&&Le.definition.providesUVContextViaCompute){let Dt=yr(Le,Be,We);if(Dt!==null)return Dt}if(Be.length>0&&Le.definition.uvRemap){let Dt=gs(Le,Be);if(Dt!==null)return Dt;let Nt=or(Le,Be,We);if(Nt!==null)return Nt}if(Be.length===0){l.add(_e);let Dt=st(Le,void 0,{bboxMask:ht(Le),...nt(Le)});Dt.computeOutputs=ke(Le,Dt);let Nt=Le.definition.fragment(Dt);return Q(J(Le)?Ae(Nt,Le):De(Nt,Le),Le,We)}let Oe=[...Be].sort((Dt,Nt)=>Dt.metadata.renderOrder-Nt.metadata.renderOrder),tt=Gs(Oe,We);if(tt!==null){let Dt=st(Le,tt,{bboxMask:ht(Le)});Dt.computeOutputs=ke(Le,Dt);let Nt=Le.definition.fragment(Dt);return Q(J(Le)?Ae(Nt,Le):De(Nt,Le),Le,We)}let _t=Ze(Le,Oe,We);l.add(_e);let Bt=st(Le,_t,{bboxMask:ht(Le)});return Bt.computeOutputs=ke(Le,Bt),Q(Ee(Le.definition.fragment(Bt),_t,Le),Le,We)}function Ze(_e,We,Le){let Be;for(let Oe=0;Oe<We.length;Oe++){let tt=We[Oe];if(tt.metadata.visible===!1)continue;if(Be!==void 0&&St(tt)){let Nt=Ss(We,Oe,Be,Le);if(Nt){Be=Nt.node,Oe=Nt.endIndex;continue}}l.add(tt.id);let _t=e.getChildren(tt.id).length>0,Bt,Dt;if(_t)Bt=pt(tt.id,Le);else{let Nt=Be;tt.definition.requiresRTT&&Be!==void 0&&(Nt=Fl(xt,Be,\"normal\",$e(1))),tt.definition.acceptsOptionalChild&&(Nt=void 0);let Ks=st(tt,Nt,{bboxMask:ht(tt),...nt(tt)});Ks.computeOutputs=ke(tt,Ks);let Ds=ze(tt.definition.fragment(Ks),tt);Dt=Ds.clipMaskNode,Bt=Q(Ds.transformedFragment,tt,Le)}if(tt.definition.requiresChild&&tt.metadata.blendMode===\"normal\"&&!_t)Be=Ie(Be,Bt,tt,Dt);else{let Nt=tt.metadata.blendMode??\"normal\",Ks=tt.metadata.opacity??1;Be===void 0?Be=_e.definition.requiresRTT||Ks!==1?Fl(v0,Bt,Nt,te(tt)):Bt:Be=Fl(Be,Bt,Nt,te(tt))}}return Be}function nt(_e,We=E.uv){if(!J(_e))return{};if(!_e.definition.boundingBoxDeclaration?.supportsResizeFit)return{};let Le=Hn(_e.id),Be=Oe=>P(`${Le}._bbox_${Oe}`);return{uvContext:W(XT,\"bboxGenUVContext\",[We,Be(\"centerX\"),Be(\"centerY\"),Be(\"halfWidth\"),Be(\"halfHeight\"),Be(\"rotation\"),Be(\"aspectRatio\")]),effectiveViewportSize:Ct(Be(\"halfWidth\").mul(2).mul(E.viewportSize.member(\"x\")),Be(\"halfHeight\").mul(2).mul(E.viewportSize.member(\"y\")),0,0).member(\"xy\")}}function ht(_e){if(!(!J(_e)||!_e.definition.requiresRTT)&&!_e.definition.boundingBoxDeclaration?.supportsResizeFit)return xe(_e)}let yt=_e=>!!_e.metadata.mask||_e.metadata.opacity!==void 0&&_e.metadata.opacity<1||(_e.metadata.blendMode??\"normal\")!==\"normal\"||el(_e.metadata.transform)||J(_e),St=_e=>!!_e.definition.uvRemap&&e.getChildren(_e.id).length===0&&!yt(_e);function Mt(_e,We,Le){l.add(_e.id);let Be=ke(_e,st(_e,void 0));return _e.definition.uvRemap({uv:We,mask:Le,uniforms:V(_e),propValues:Y(_e),props:q(_e),aspect:E.aspect,onBeforeRender:Oe=>c.push(Oe),computeOutputs:Be})}function Rt(_e){let We=E.uv,Le=$e(1);for(let Be=_e.length-1;Be>=0;Be--){let Oe=Mt(_e[Be],We,Le);We=Oe.uv,Le=Oe.mask}return{uv:We,mask:Le}}let Kt=24,Wt=$e(1),ls=(_e,We)=>{if(We.left--<=0||_e.metadata.mask||el(_e.metadata.transform))return!1;let Le=e.getChildren(_e.id).filter(Be=>Be.metadata.visible!==!1);return Le.length===0?J(_e)&&_e.definition.boundingBoxDeclaration?.boxResamplesContent?!1:!!_e.definition.acceptsUVContext&&!_e.definition.requiresChild:!_e.definition.uvRemap||J(_e)?!1:Le.every(Be=>ls(Be,We))};function us(_e,We,Le){let Be=Le??Wt,Oe=Mt(_e,We,Be);return{uv:Oe.uv,mask:Oe.mask===Be?Le:Oe.mask}}let os=(_e,We)=>_e===void 0?We:We===void 0?_e:_e.mul(We);function bs(_e,We,Le){let Be=e.getChildren(_e.id).filter(Nt=>Nt.metadata.visible!==!1);if(Be.length>0){if(!_e.definition.uvRemap)return null;let Nt=us(_e,We,Le);return hs(Be,ns(Nt.uv,\"foldUV\"),Nt.mask)}if(!_e.definition.acceptsUVContext)return null;l.add(_e.id);let Oe=nt(_e,We),tt=st(_e,void 0,Object.keys(Oe).length>0?Oe:{uvContext:We});tt.computeOutputs=ke(_e,tt);let _t=_e.definition.fragment(tt),Bt=os(Le,J(_e)?xe(_e,We):void 0);if(Bt===void 0)return _t;let Dt=ns(_t,\"gen\");return Ct(Dt.member(\"rgb\"),Dt.member(\"a\").mul(Bt))}function hs(_e,We,Le){let Be=[..._e].sort((_t,Bt)=>_t.metadata.renderOrder-Bt.metadata.renderOrder),Oe;for(let _t of Be){let Bt=bs(_t,We,void 0);if(Bt===null)return null;let Dt=_t.metadata.blendMode??\"normal\",Nt=_t.metadata.opacity??1;Oe===void 0?Oe=Dt===\"normal\"&&Nt===1?Bt:Fl(v0,Bt,Dt,te(_t)):Oe=Fl(Oe,Bt,Dt,te(_t))}if(Oe===void 0)return null;if(Le===void 0)return Oe;let tt=ns(Oe,\"sibs\");return Ct(tt.member(\"rgb\"),tt.member(\"a\").mul(Le))}function gs(_e,We){if(!_e.definition.uvRemap||yt(_e))return null;let Le=We.filter(_t=>_t.metadata.visible!==!1);if(Le.length===0)return null;let Be={left:Kt};if(!Le.every(_t=>ls(_t,Be)))return null;l.add(_e.id);let{uv:Oe,mask:tt}=us(_e,E.uv,void 0);return hs(Le,ns(Oe,\"foldUV\"),tt)}function Gs(_e,We){let Le=_e.filter(Ds=>Ds.metadata.visible!==!1);if(!Le.some(Ds=>!!Ds.definition.uvRemap)||Le.length<2)return null;let Be=Le.length;for(let Ds=Le.length-1;Ds>=0&&St(Le[Ds]);Ds--)Be=Ds;let Oe=Le.slice(Be),tt=Le.slice(0,Be);if(Oe.length===0||tt.length!==1)return null;let _t=tt[0];if(!_t.definition.acceptsUVContext||e.getChildren(_t.id).length>0||yt(_t))return null;l.add(_t.id);for(let Ds of Oe)l.add(Ds.id);let{uv:Bt,mask:Dt}=Rt(Oe),Nt=st(_t,void 0,{uvContext:Bt});Nt.computeOutputs=ke(_t,Nt);let Ks=_t.definition.fragment(Nt);return Ct(Ks.member(\"rgb\"),Ks.member(\"a\").mul(Dt))}function Ss(_e,We,Le,Be){if(!St(_e[We]))return null;let Oe=[],tt=We;for(let Nt=We;Nt<_e.length;Nt++){let Ks=_e[Nt];if(Ks.metadata.visible!==!1){if(!St(Ks))break;Oe.push(Ks),tt=Nt}}if(Oe.length===0)return null;for(let Nt of Oe)l.add(Nt.id);let{uv:_t,mask:Bt}=Rt(Oe),Dt=L(Fl(xt,Le,\"normal\",$e(1))).sample(_t);return{node:Ct(Dt.member(\"rgb\"),Dt.member(\"a\").mul(Bt)),endIndex:tt}}function or(_e,We,Le){if(!_e.definition.uvRemap||yt(_e))return null;let Be=8,Oe=[],tt=_e,_t=We,Bt=null,Dt=null;for(let ar=0;ar<Be;ar++){Oe.push(tt);let Xo=_t.filter(za=>za.metadata.visible!==!1);if(Xo.length!==1)return null;let $r=Xo[0],cr=e.getChildren($r.id);if($r.definition.acceptsUVContext&&cr.length===0&&!yt($r)){Bt=$r;break}if($r.definition.uvRemap&&!yt($r)&&cr.length===1){tt=$r,_t=cr;continue}Dt=$r;break}if(!Bt&&!Dt)return null;for(let ar of Oe)l.add(ar.id);let{uv:Nt,mask:Ks}=Rt([...Oe].reverse()),Ds;if(Bt){l.add(Bt.id);let ar=st(Bt,void 0,{uvContext:Nt});ar.computeOutputs=ke(Bt,ar);let Xo=Bt.definition.fragment(ar);Ds=Ct(Xo.member(\"rgb\"),Xo.member(\"a\").mul(Ks))}else{let ar=L(Fl(v0,pt(Dt.id,Le),Dt.metadata.blendMode??\"normal\",te(Dt))).sample(Nt);Ds=Ct(ar.member(\"rgb\"),ar.member(\"a\").mul(Ks))}return Q(J(_e)?Ae(Ds,_e):De(Ds,_e),_e,Le)}function yr(_e,We,Le){let Be=cr=>!!cr.metadata.mask||cr.metadata.opacity!==void 0&&cr.metadata.opacity<1||(cr.metadata.blendMode??\"normal\")!==\"normal\"||el(cr.metadata.transform)||J(cr);if(!_e.definition.providesUVContextViaCompute||Be(_e))return null;let Oe=[],tt=_e,_t=null,Bt=We,Dt=8;for(let cr=0;cr<Dt;cr++){Oe.push(tt);let za=Bt.filter(Wn=>Wn.metadata.visible!==!1);if(za.length!==1)return null;let ia=za[0];if(Be(ia))return null;let Ra=e.getChildren(ia.id).length>0;if(ia.definition.acceptsUVContext&&!Ra){_t=ia;break}if(ia.definition.providesUVContextViaCompute){tt=ia,Bt=e.getChildren(ia.id);continue}return null}if(!_t)return null;l.add(_t.id);for(let cr of Oe)l.add(cr.id);let Nt=[],Ks;for(let cr=0;cr<Oe.length;cr++){let za=Oe[cr],ia=st(za,void 0,{computeOutputs:Ks?{_upstreamUVMap:Ks}:void 0}),Ra=ke(za,ia);if(!Ra||!Ra.uvMaskMap)return null;ia.computeOutputs=Ra,Nt.push(ia),Ks=Ra.uvMaskMap}let Ds=Ks.sample(E.uv),ar=Ct(Ds.member(\"r\"),Ds.member(\"g\"),0,0).member(\"xy\"),Xo=st(_t,void 0,{uvContext:ar});Xo.computeOutputs=ke(_t,Xo);let $r=_t.definition.fragment(Xo);for(let cr=Oe.length-1;cr>=0;cr--)Nt[cr].childNode=$r,Nt[cr].uvPropagationActive=!0,$r=Oe[cr].definition.fragment(Nt[cr]);return Q(J(_e)?Ae($r,_e):De($r,_e),_e,Le)}let lr=e.rootId?pt(e.rootId):xt,Ur=r.map(_e=>{let{body:We,externals:Le}=jT(_e.root,Be=>Be,t.flipY??!0,s.uniform);return{textureKey:_e.key,fragment:KT(We,Le,`rtt_${_e.key}`,s.sampler,y)}}),so=t.toneMapping??\"linear\",ro=jT(lr,(_e,We)=>aee(_e,We,so,t.premultiplyAlpha??!1),t.flipY??!0,s.uniform);return{computeSteps:i,rttPasses:Ur,finalPass:KT(ro.body,ro.externals,\"final\",s.sampler,y),textures:o,externalTextures:a,layouts:{uniforms:s.uniform,samplers:s.sampler},onBeforeRender:c,onAfterRender:d,onResize:u,onCleanup:p,composedNodeIds:l,usesCustomWgsl:qe}}function aee(e,t,s,r){let o=t.external($T[s]??$T.linear,`tone_${s}`),a=t.external(Xm,\"linearToSrgb\"),i=t.freshLocal(\"composed\");t.statement(`var ${i} = ${e};`);let l=`${a}(${o}(${i}.rgb))`;return r?`vec4f(${l} * ${i}.a, ${i}.a)`:`vec4f(${l}, ${i}.a)`}function KT(e,t,s,r,o=new Set){let a=QT(e,/\\btex\\.\\$\\.(\\w+)/g),i=QT(e,/\\bext\\.\\$\\.(\\w+)/g),l=/\\bsamp\\.\\$\\./.test(e),c;if(a.length>0){let u={};for(let p of a)u[p]=o.has(p)?{texture:Zt(n),sampleType:\"unfilterable-float\"}:{texture:Zt(n)};c=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(w.bindGroupLayout(u).$idx(bm.textures),\"textureLayout\"),t.tex=c}let d;if(i.length>0){let u={};for(let f of i)u[f]={externalTexture:RM()};let p=new Set([bm.uniforms]);a.length>0&&p.add(bm.textures),l&&p.add(bm.samplers);let _=0;for(;p.has(_);)_++;d=(globalThis.__TYPEGPU_AUTONAME__??(f=>f))(w.bindGroupLayout(u).$idx(_),\"externalLayout\"),t.ext=d}return l&&(t.samp=r),{body:e,externals:t,entry:w.fragmentFn({in:{uv:m},out:S})(e).$uses(t).$name(s),reads:a,externalReads:i,usesSamplers:l,textureLayout:c,externalLayout:d}}function QT(e,t){let s=new Set;for(let r of e.matchAll(t))s.add(r[1]);return[...s]}function nee(e,t){switch(t){case\"alpha\":return e.member(\"a\");case\"alphaInverted\":return new fs(s=>`(1.0 - ${e._emit(s)}.a)`);case\"luminanceInverted\":return new fs(s=>`(1.0 - dot(${e._emit(s)}.rgb, vec3f(0.2126, 0.7152, 0.0722)))`);default:return new fs(s=>`dot(${e._emit(s)}.rgb, vec3f(0.2126, 0.7152, 0.0722))`)}}function iee(e,t,s,r,o,a){return new fs(i=>{let l=e._emit(i),c=t._emit(i),d=s._emit(i),u=r._emit(i),p=o._emit(i),_=a._emit(i);return`mix(${u}, ${p}, ${`pow(${`clamp((${l} - ${c}) / max(${d} - ${c}, 0.0001), 0.0, 1.0)`}, pow(2.0, -${_} * 2.0))`})`})}var lee={stretch:0,transparent:1,mirror:2,wrap:3};function A4(e,t={}){let s=[];s.push(`tone:${t.toneMapping??\"linear\"}`),s.push(`flipY:${t.flipY??!0}`),s.push(`premul:${t.premultiplyAlpha??!1}`);let r=o=>{let a=e.getNode(o);if(!a)return;let i=a.metadata,l=a.definition,c=el(i.transform),d=!!i.boundingBox&&!!l.boundingBoxDeclaration&&!Yh(i.boundingBox),u=(i.opacity??1)===0?\"zero\":\"nonzero\",p=i.mask?`${i.mask.source}:${i.mask.type}`:\"none\",_=[];for(let[f,h]of Object.entries(l.props??{}))if(h.compileTime){let g=a.handles[f];_.push(`${f}=${g?String(g.value):\"?\"}`)}s.push([`id:${a.id}`,`parent:${a.parentId??\"\"}`,`name:${a.componentName}`,`rev:${l.revision??\"\"}`,`blend:${i.blendMode??\"normal\"}`,`mask:${p}`,`order:${i.renderOrder??0}`,`visible:${i.visible!==!1}`,`opacity:${u}`,`xform:${c}${c?`:${i.transform?.edges??\"transparent\"}`:\"\"}`,`bbox:${d}:${d?l.boundingBoxDeclaration?.boxResamplesContent?\"resample\":l.boundingBoxDeclaration?.supportsResizeFit?\"resize\":\"clip\":\"\"}`,`rtt:${!!l.requiresRTT}`,`maps:${i.maps?Object.keys(i.maps).sort().join(\",\"):\"\"}`,`ct:${_.sort().join(\"|\")}`].join(\"|\"));for(let f of e.getChildren(o).sort((h,g)=>h.metadata.renderOrder-g.metadata.renderOrder))r(f.id)};return e.rootId&&r(e.rootId),s}var cee=w.fn([n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(t,s),o=__tsover_add(ie(__tsover_sub(r,.5)),.5),a=__tsover_sub(r,o),i=__tsover_add(1,__tsover_mul(__tsover_mul(a,a),__tsover_add(-2.5,__tsover_mul(1.5,a)))),l=__tsover_mul(a,__tsover_add(.5,__tsover_mul(a,__tsover_sub(2,__tsover_mul(1.5,a))))),c=B(__tsover_add(i,l),1e-6),d=__tsover_div(l,c);return A(__tsover_div(__tsover_sub(o,1),s),__tsover_div(__tsover_add(o,d),s),__tsover_div(__tsover_add(o,2),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"texSize\"}],body:[0,[[13,\"samplePos\",[1,\"uv\",\"*\",\"texSize\"]],[13,\"texPos1\",[1,[6,\"std.floor\",[[1,\"samplePos\",\"-\",[5,\"0.5\"]]]],\"+\",[5,\"0.5\"]]],[13,\"f\",[1,\"samplePos\",\"-\",\"texPos1\"]],[13,\"w1\",[1,[5,\"1\"],\"+\",[1,[1,\"f\",\"*\",\"f\"],\"*\",[1,[4,\"-\",[5,\"2.5\"]],\"+\",[1,[5,\"1.5\"],\"*\",\"f\"]]]]],[13,\"w2\",[1,\"f\",\"*\",[1,[5,\"0.5\"],\"+\",[1,\"f\",\"*\",[1,[5,\"2\"],\"-\",[1,[5,\"1.5\"],\"*\",\"f\"]]]]]],[13,\"w12\",[6,\"std.max\",[[1,\"w1\",\"+\",\"w2\"],[5,\"0.000001\"]]]],[13,\"offset12\",[1,\"w2\",\"/\",\"w12\"]],[10,[6,\"d.vec3f\",[[1,[1,\"texPos1\",\"-\",[5,\"1\"]],\"/\",\"texSize\"],[1,[1,\"texPos1\",\"+\",\"offset12\"],\"/\",\"texSize\"],[1,[1,\"texPos1\",\"+\",[5,\"2\"]],\"/\",\"texSize\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.max\":()=>B,\"d.vec3f\":()=>A}})&&e.f)({})),dee=w.fn([n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(t,s),o=__tsover_add(ie(__tsover_sub(r,.5)),.5),a=__tsover_sub(r,o),i=__tsover_mul(a,__tsover_add(-.5,__tsover_mul(a,__tsover_sub(1,__tsover_mul(.5,a))))),l=__tsover_add(1,__tsover_mul(__tsover_mul(a,a),__tsover_add(-2.5,__tsover_mul(1.5,a)))),c=__tsover_mul(a,__tsover_add(.5,__tsover_mul(a,__tsover_sub(2,__tsover_mul(1.5,a))))),d=__tsover_mul(__tsover_mul(a,a),__tsover_add(-.5,__tsover_mul(.5,a)));return A(i,__tsover_add(l,c),d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"texSize\"}],body:[0,[[13,\"samplePos\",[1,\"uv\",\"*\",\"texSize\"]],[13,\"texPos1\",[1,[6,\"std.floor\",[[1,\"samplePos\",\"-\",[5,\"0.5\"]]]],\"+\",[5,\"0.5\"]]],[13,\"f\",[1,\"samplePos\",\"-\",\"texPos1\"]],[13,\"w0\",[1,\"f\",\"*\",[1,[4,\"-\",[5,\"0.5\"]],\"+\",[1,\"f\",\"*\",[1,[5,\"1\"],\"-\",[1,[5,\"0.5\"],\"*\",\"f\"]]]]]],[13,\"w1\",[1,[5,\"1\"],\"+\",[1,[1,\"f\",\"*\",\"f\"],\"*\",[1,[4,\"-\",[5,\"2.5\"]],\"+\",[1,[5,\"1.5\"],\"*\",\"f\"]]]]],[13,\"w2\",[1,\"f\",\"*\",[1,[5,\"0.5\"],\"+\",[1,\"f\",\"*\",[1,[5,\"2\"],\"-\",[1,[5,\"1.5\"],\"*\",\"f\"]]]]]],[13,\"w3\",[1,[1,\"f\",\"*\",\"f\"],\"*\",[1,[4,\"-\",[5,\"0.5\"]],\"+\",[1,[5,\"0.5\"],\"*\",\"f\"]]]],[10,[6,\"d.vec3f\",[\"w0\",[1,\"w1\",\"+\",\"w2\"],\"w3\"]]]]]},externals:{\"std.floor\":()=>ie,\"d.vec3f\":()=>A}})&&e.f)({})),ZT=new Map;function uee(e,t,s){let r=gt({uvA:m,uvB:m,uvC:m,uvD:m,w:S}).$name(s);return{Taps:r,setup:w.fn([m],r)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=(a=>{\"use gpu\";let i=n(e),l=__tsover_sub(__tsover_mul(a.x,i),.5),c=__tsover_sub(__tsover_mul(a.y,i),.5),d=ie(l),u=ie(c),p=__tsover_sub(l,d),_=__tsover_sub(c,u),f=__tsover_sub(1,p),h=__tsover_mul(__tsover_mul(__tsover_mul(f,f),f),.16666667),g=__tsover_add(__tsover_sub(__tsover_mul(__tsover_mul(__tsover_mul(p,p),p),.5),__tsover_mul(p,p)),.66666667),y=__tsover_mul(__tsover_mul(__tsover_mul(p,p),p),.16666667),b=__tsover_sub(__tsover_sub(__tsover_sub(1,h),g),y),x=__tsover_sub(1,_),P=__tsover_mul(__tsover_mul(__tsover_mul(x,x),x),.16666667),C=__tsover_add(__tsover_sub(__tsover_mul(__tsover_mul(__tsover_mul(_,_),_),.5),__tsover_mul(_,_)),.66666667),E=__tsover_mul(__tsover_mul(__tsover_mul(_,_),_),.16666667),R=__tsover_sub(__tsover_sub(__tsover_sub(1,P),C),E),U=__tsover_add(h,g),L=__tsover_add(b,y),k=__tsover_add(P,C),D=__tsover_add(R,E),O=__tsover_add(__tsover_sub(d,1),__tsover_div(g,U)),F=__tsover_add(__tsover_add(d,1),__tsover_div(y,L)),q=__tsover_add(__tsover_sub(u,1),__tsover_div(C,k)),Y=__tsover_add(__tsover_add(u,1),__tsover_div(E,D));return r({uvA:m(__tsover_div(__tsover_add(O,.5),i),__tsover_div(__tsover_add(q,.5),i)),uvB:m(__tsover_div(__tsover_add(F,.5),i),__tsover_div(__tsover_add(q,.5),i)),uvC:m(__tsover_div(__tsover_add(O,.5),i),__tsover_div(__tsover_add(Y,.5),i)),uvD:m(__tsover_div(__tsover_add(F,.5),i),__tsover_div(__tsover_add(Y,.5),i)),w:S(__tsover_mul(U,k),__tsover_mul(L,k),__tsover_mul(U,D),__tsover_mul(L,D))})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"gf\",[6,\"d.f32\",[\"gridSize\"]]],[13,\"tx\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"gf\"],\"-\",[5,\"0.5\"]]],[13,\"ty\",[1,[1,[7,\"uv\",\"y\"],\"*\",\"gf\"],\"-\",[5,\"0.5\"]]],[13,\"pxf\",[6,\"std.floor\",[\"tx\"]]],[13,\"pyf\",[6,\"std.floor\",[\"ty\"]]],[13,\"fx\",[1,\"tx\",\"-\",\"pxf\"]],[13,\"fy\",[1,\"ty\",\"-\",\"pyf\"]],[13,\"ofx\",[1,[5,\"1\"],\"-\",\"fx\"]],[13,\"wx0\",[1,[1,[1,\"ofx\",\"*\",\"ofx\"],\"*\",\"ofx\"],\"*\",[5,\"0.16666667\"]]],[13,\"wx1\",[1,[1,[1,[1,[1,\"fx\",\"*\",\"fx\"],\"*\",\"fx\"],\"*\",[5,\"0.5\"]],\"-\",[1,\"fx\",\"*\",\"fx\"]],\"+\",[5,\"0.66666667\"]]],[13,\"wx3\",[1,[1,[1,\"fx\",\"*\",\"fx\"],\"*\",\"fx\"],\"*\",[5,\"0.16666667\"]]],[13,\"wx2\",[1,[1,[1,[5,\"1\"],\"-\",\"wx0\"],\"-\",\"wx1\"],\"-\",\"wx3\"]],[13,\"ofy\",[1,[5,\"1\"],\"-\",\"fy\"]],[13,\"wy0\",[1,[1,[1,\"ofy\",\"*\",\"ofy\"],\"*\",\"ofy\"],\"*\",[5,\"0.16666667\"]]],[13,\"wy1\",[1,[1,[1,[1,[1,\"fy\",\"*\",\"fy\"],\"*\",\"fy\"],\"*\",[5,\"0.5\"]],\"-\",[1,\"fy\",\"*\",\"fy\"]],\"+\",[5,\"0.66666667\"]]],[13,\"wy3\",[1,[1,[1,\"fy\",\"*\",\"fy\"],\"*\",\"fy\"],\"*\",[5,\"0.16666667\"]]],[13,\"wy2\",[1,[1,[1,[5,\"1\"],\"-\",\"wy0\"],\"-\",\"wy1\"],\"-\",\"wy3\"]],[13,\"g0x\",[1,\"wx0\",\"+\",\"wx1\"]],[13,\"g1x\",[1,\"wx2\",\"+\",\"wx3\"]],[13,\"g0y\",[1,\"wy0\",\"+\",\"wy1\"]],[13,\"g1y\",[1,\"wy2\",\"+\",\"wy3\"]],[13,\"h0x\",[1,[1,\"pxf\",\"-\",[5,\"1\"]],\"+\",[1,\"wx1\",\"/\",\"g0x\"]]],[13,\"h1x\",[1,[1,\"pxf\",\"+\",[5,\"1\"]],\"+\",[1,\"wx3\",\"/\",\"g1x\"]]],[13,\"h0y\",[1,[1,\"pyf\",\"-\",[5,\"1\"]],\"+\",[1,\"wy1\",\"/\",\"g0y\"]]],[13,\"h1y\",[1,[1,\"pyf\",\"+\",[5,\"1\"]],\"+\",[1,\"wy3\",\"/\",\"g1y\"]]],[10,[6,\"Taps\",[[104,{uvA:[6,\"d.vec2f\",[[1,[1,\"h0x\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"],[1,[1,\"h0y\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"]]],uvB:[6,\"d.vec2f\",[[1,[1,\"h1x\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"],[1,[1,\"h0y\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"]]],uvC:[6,\"d.vec2f\",[[1,[1,\"h0x\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"],[1,[1,\"h1y\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"]]],uvD:[6,\"d.vec2f\",[[1,[1,\"h1x\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"],[1,[1,\"h1y\",\"+\",[5,\"0.5\"]],\"/\",\"gf\"]]],w:[6,\"d.vec4f\",[[1,\"g0x\",\"*\",\"g0y\"],[1,\"g1x\",\"*\",\"g0y\"],[1,\"g0x\",\"*\",\"g1y\"],[1,\"g1x\",\"*\",\"g1y\"]]]}]]]]]]},externals:{\"d.f32\":()=>n,gridSize:()=>e,\"std.floor\":()=>ie,Taps:()=>r,\"d.vec2f\":()=>m,\"d.vec4f\":()=>S}})&&o.f)({})).$name(t)}}function w4(e,t={}){let s=t.fnName??\"bSplineTapSetup\",r=t.structName??\"BSplineTaps\",o=`${e}|${s}|${r}`,a=ZT.get(o);if(a)return a;let i=uee(e,s,r);return ZT.set(o,i),i}var pee=0,g_=(e,t,s=\"linearClamp\",r=\"positive\")=>{let o=pee++;return new fs(a=>a.memo(`catmullRom:${o}`,()=>{let i=a.freshLocal(\"crUV\"),l=a.freshLocal(\"crSize\"),c=a.freshLocal(\"crPosX\"),d=a.freshLocal(\"crPosY\"),u=a.freshLocal(\"crWx\"),p=a.freshLocal(\"crWy\"),_=a.freshLocal(\"crOut\");a.statement(`let ${i} = ${t._emit(a)};`),a.statement(`let ${l} = ${e.dimensions()._emit(a)};`);let f=a.external(cee,\"catmullRomAxisPositions\"),h=a.external(dee,\"catmullRomAxisWeights\");a.statement(`let ${c} = ${f}(${i}.x, ${l}.x);`),a.statement(`let ${d} = ${f}(${i}.y, ${l}.y);`),a.statement(`let ${u} = ${h}(${i}.x, ${l}.x);`),a.statement(`let ${p} = ${h}(${i}.y, ${l}.y);`),a.statement(`var ${_} = vec4f(0.0, 0.0, 0.0, 0.0);`);let g=[\"x\",\"y\",\"z\"];for(let y of[0,1,2])for(let b of[0,1,2]){let x=new fs(()=>`vec2f(${c}.${g[b]}, ${d}.${g[y]})`),P=`(${u}.${g[b]} * ${p}.${g[y]})`;a.statement(`${_} += ${e.sample(x,s)._emit(a)} * ${P};`)}return a.statement(r===\"unit\"?`${_} = clamp(${_}, vec4f(0.0, 0.0, 0.0, 0.0), vec4f(1.0, 1.0, 1.0, 1.0));`:`${_} = max(${_}, vec4f(0.0, 0.0, 0.0, 0.0));`),_}))},N3=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return G(t,m(0,0),m(1,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[10,[6,\"std.clamp\",[\"uv\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m}})&&e.f)({})),Hm=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=An(re(t.x),2),r=An(re(t.y),2);return m(N(s,__tsover_sub(2,s),s>=1),N(r,__tsover_sub(2,r),r>=1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"mirrorX\",[6,\"std.mod\",[[6,\"std.abs\",[[7,\"uv\",\"x\"]]],[5,\"2\"]]]],[13,\"mirrorY\",[6,\"std.mod\",[[6,\"std.abs\",[[7,\"uv\",\"y\"]]],[5,\"2\"]]]],[10,[6,\"d.vec2f\",[[6,\"std.select\",[\"mirrorX\",[1,[5,\"2\"],\"-\",\"mirrorX\"],[1,\"mirrorX\",\">=\",[5,\"1\"]]]],[6,\"std.select\",[\"mirrorY\",[1,[5,\"2\"],\"-\",\"mirrorY\"],[1,\"mirrorY\",\">=\",[5,\"1\"]]]]]]]]]},externals:{\"std.mod\":()=>An,\"std.abs\":()=>re,\"d.vec2f\":()=>m,\"std.select\":()=>N}})&&e.f)({})),jm=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Re(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[10,[6,\"std.fract\",[\"uv\"]]]]]},externals:{\"std.fract\":()=>Re}})&&e.f)({})),$3=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=__tsover_mul(Et(0,t.x),Et(t.x,1)),r=__tsover_mul(Et(0,t.y),Et(t.y,1));return __tsover_mul(s,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"inX\",[1,[6,\"std.step\",[[5,\"0\"],[7,\"uv\",\"x\"]]],\"*\",[6,\"std.step\",[[7,\"uv\",\"x\"],[5,\"1\"]]]]],[13,\"inY\",[1,[6,\"std.step\",[[5,\"0\"],[7,\"uv\",\"y\"]]],\"*\",[6,\"std.step\",[[7,\"uv\",\"y\"],[5,\"1\"]]]]],[10,[1,\"inX\",\"*\",\"inY\"]]]]},externals:{\"std.step\":()=>Et}})&&e.f)({})),X3=1,H3=2,j3=3;w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t.x,t.y,t.z,__tsover_mul(t.w,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"m\"}],body:[0,[[10,[6,\"d.vec4f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"],[1,[7,\"color\",\"w\"],\"*\",\"m\"]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({}));var mee=(e,t)=>{switch(t){case X3:return e;case H3:return W(Hm,\"edgeMirrorUV\",[e]);case j3:return W(jm,\"edgeWrapUV\",[e]);default:return W(N3,\"edgeClampUV\",[e])}},_ee=(e,t,s)=>{if(s===X3){let r=W($3,\"edgeTransparentMask\",[e]);return{uv:e,mask:t.mul(r)}}return{uv:mee(e,s),mask:t}},Ha=(e,t,s)=>{if(s===X3){let r=t(e),o=W($3,\"edgeTransparentMask\",[e]);return Ct(r.member(\"rgb\"),r.member(\"a\").mul(o))}return t(s===H3?W(Hm,\"edgeMirrorUV\",[e]):s===j3?W(jm,\"edgeWrapUV\",[e]):e)},T4=(e,t,s)=>Ha(t,s===H3?r=>e.sample(r):r=>g_(e,r,s===j3?\"linearRepeat\":\"linearClamp\"),s),h0=gt({rUV:m,gUV:m,bUV:m}).$name(\"ChromaticSplitUVs\"),fee=w.fn([m,m,n,n],h0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=s.mul(__tsover_mul(r,.1)),i=.15,l=G(a,m(-i,-i),m(i,i)),c=__tsover_mul(o,.1);return h0({rUV:t.sub(l.mul(__tsover_add(1,c))),gUV:t.sub(l),bUV:t.sub(l.mul(__tsover_sub(1,c)))})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"disp\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"chromaticSplit\"}],body:[0,[[13,\"scaled\",[6,[7,\"disp\",\"mul\"],[[1,\"strength\",\"*\",[5,\"0.1\"]]]]],[13,\"maxDisp\",[5,\"0.15\"]],[13,\"clamped\",[6,\"std.clamp\",[\"scaled\",[6,\"d.vec2f\",[[4,\"-\",\"maxDisp\"],[4,\"-\",\"maxDisp\"]]],[6,\"d.vec2f\",[\"maxDisp\",\"maxDisp\"]]]]],[13,\"chromaticScale\",[1,\"chromaticSplit\",\"*\",[5,\"0.1\"]]],[13,\"rUV\",[6,[7,\"uv\",\"sub\"],[[6,[7,\"clamped\",\"mul\"],[[1,[5,\"1\"],\"+\",\"chromaticScale\"]]]]]],[13,\"gUV\",[6,[7,\"uv\",\"sub\"],[\"clamped\"]]],[13,\"bUV\",[6,[7,\"uv\",\"sub\"],[[6,[7,\"clamped\",\"mul\"],[[1,[5,\"1\"],\"-\",\"chromaticScale\"]]]]]],[10,[6,\"ChromaticSplitUVs\",[[104,{rUV:\"rUV\",gUV:\"gUV\",bUV:\"bUV\"}]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m,ChromaticSplitUVs:()=>h0}})&&e.f)({})),JT=Jt,vee=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(s,bt),o=pe(r),a=ae(r),i=__tsover_div(1,3),l=__tsover_sub(1,o),c=__tsover_mul(l,i),d=__tsover_div(a,lc),u=__tsover_add(o,c),p=__tsover_sub(c,d),_=__tsover_add(c,d),f=__tsover_add(c,d),h=__tsover_add(o,c),g=__tsover_sub(c,d),y=__tsover_sub(c,d),b=__tsover_add(c,d),x=__tsover_add(o,c),P=t.x,C=t.y,E=t.z;return S(__tsover_add(__tsover_add(__tsover_mul(P,u),__tsover_mul(C,p)),__tsover_mul(E,_)),__tsover_add(__tsover_add(__tsover_mul(P,f),__tsover_mul(C,h)),__tsover_mul(E,g)),__tsover_add(__tsover_add(__tsover_mul(P,y),__tsover_mul(C,b)),__tsover_mul(E,x)),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"shiftDeg\"}],body:[0,[[13,\"angle\",[1,\"shiftDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angle\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angle\"]]],[13,\"k\",[1,[5,\"1\"],\"/\",[5,\"3\"]]],[13,\"oneMinusCos\",[1,[5,\"1\"],\"-\",\"cosA\"]],[13,\"kOneMinusCos\",[1,\"oneMinusCos\",\"*\",\"k\"]],[13,\"sinOverSqrt3\",[1,\"sinA\",\"/\",\"SQRT3\"]],[13,\"m00\",[1,\"cosA\",\"+\",\"kOneMinusCos\"]],[13,\"m01\",[1,\"kOneMinusCos\",\"-\",\"sinOverSqrt3\"]],[13,\"m02\",[1,\"kOneMinusCos\",\"+\",\"sinOverSqrt3\"]],[13,\"m10\",[1,\"kOneMinusCos\",\"+\",\"sinOverSqrt3\"]],[13,\"m11\",[1,\"cosA\",\"+\",\"kOneMinusCos\"]],[13,\"m12\",[1,\"kOneMinusCos\",\"-\",\"sinOverSqrt3\"]],[13,\"m20\",[1,\"kOneMinusCos\",\"-\",\"sinOverSqrt3\"]],[13,\"m21\",[1,\"kOneMinusCos\",\"+\",\"sinOverSqrt3\"]],[13,\"m22\",[1,\"cosA\",\"+\",\"kOneMinusCos\"]],[13,\"r\",[7,\"color\",\"x\"]],[13,\"g\",[7,\"color\",\"y\"]],[13,\"b\",[7,\"color\",\"z\"]],[13,\"newR\",[1,[1,[1,\"r\",\"*\",\"m00\"],\"+\",[1,\"g\",\"*\",\"m01\"]],\"+\",[1,\"b\",\"*\",\"m02\"]]],[13,\"newG\",[1,[1,[1,\"r\",\"*\",\"m10\"],\"+\",[1,\"g\",\"*\",\"m11\"]],\"+\",[1,\"b\",\"*\",\"m12\"]]],[13,\"newB\",[1,[1,[1,\"r\",\"*\",\"m20\"],\"+\",[1,\"g\",\"*\",\"m21\"]],\"+\",[1,\"b\",\"*\",\"m22\"]]],[10,[6,\"d.vec4f\",[\"newR\",\"newG\",\"newB\",[7,\"color\",\"w\"]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,SQRT3:()=>lc,\"d.vec4f\":()=>S}})&&e.f)({})),hee=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=A(t.x,t.y,t.z),o=Se(r,A(.2126,.7152,.0722)),a=K(A(o,o,o),r,A(s));return S(a.x,a.y,a.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]],[13,\"luminance\",[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"gray\",[6,\"d.vec3f\",[\"luminance\",\"luminance\",\"luminance\"]]],[13,\"saturated\",[6,\"std.mix\",[\"gray\",\"rgb\",[6,\"d.vec3f\",[\"intensity\"]]]]],[10,[6,\"d.vec4f\",[[7,\"saturated\",\"x\"],[7,\"saturated\",\"y\"],[7,\"saturated\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.dot\":()=>Se,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),gee=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t.x,o=t.y,a=t.z,i=__tsover_div(__tsover_add(__tsover_add(r,o),a),3),l=B(r,B(o,a)),c=__tsover_mul(__tsover_mul(__tsover_sub(l,i),s),-3),d=K(A(r,o,a),A(l,l,l),A(c));return S(d.x,d.y,d.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"adjustment\"}],body:[0,[[13,\"r\",[7,\"color\",\"x\"]],[13,\"g\",[7,\"color\",\"y\"]],[13,\"b\",[7,\"color\",\"z\"]],[13,\"average\",[1,[1,[1,\"r\",\"+\",\"g\"],\"+\",\"b\"],\"/\",[5,\"3\"]]],[13,\"mx\",[6,\"std.max\",[\"r\",[6,\"std.max\",[\"g\",\"b\"]]]]],[13,\"amt\",[1,[1,[1,\"mx\",\"-\",\"average\"],\"*\",\"adjustment\"],\"*\",[4,\"-\",[5,\"3\"]]]],[13,\"rgb\",[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]]],[13,\"vibrant\",[6,\"std.mix\",[\"rgb\",[6,\"d.vec3f\",[\"mx\",\"mx\",\"mx\"]],[6,\"d.vec3f\",[\"amt\"]]]]],[10,[6,\"d.vec4f\",[[7,\"vibrant\",\"x\"],[7,\"vibrant\",\"y\"],[7,\"vibrant\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"std.max\":()=>B,\"d.vec3f\":()=>A,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),yee=w.fn([S,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_add(r,1),a=A(.5,.5,.5);return S(t.xyz.sub(a).mul(o).add(a).add(A(s,s,s)),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"brightness\"},{type:\"i\",name:\"contrastRaw\"}],body:[0,[[13,\"contrast\",[1,\"contrastRaw\",\"+\",[5,\"1\"]]],[13,\"half\",[6,\"d.vec3f\",[[5,\"0.5\"],[5,\"0.5\"],[5,\"0.5\"]]]],[13,\"contrasted\",[6,[7,[6,[7,[6,[7,[7,\"color\",\"xyz\"],\"sub\"],[\"half\"]],\"mul\"],[\"contrast\"]],\"add\"],[\"half\"]]],[13,\"result\",[6,[7,\"contrasted\",\"add\"],[[6,\"d.vec3f\",[\"brightness\",\"brightness\",\"brightness\"]]]]],[10,[6,\"d.vec4f\",[\"result\",[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),bee=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t.xyz.mul(s),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"gain\"}],body:[0,[[13,\"rgb\",[6,[7,[7,\"color\",\"xyz\"],\"mul\"],[\"gain\"]]],[10,[6,\"d.vec4f\",[\"rgb\",[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),xee=w.fn([S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Se(t.xyz,A(.2126,.7152,.0722));return S(s,s,s,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[13,\"luminance\",[6,\"std.dot\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[10,[6,\"d.vec4f\",[\"luminance\",\"luminance\",\"luminance\",[7,\"color\",\"w\"]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Aee=w.fn([S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return S(__tsover_sub(1,t.x),__tsover_sub(1,t.y),__tsover_sub(1,t.z),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[10,[6,\"d.vec4f\",[[1,[5,\"1\"],\"-\",[7,\"color\",\"x\"]],[1,[5,\"1\"],\"-\",[7,\"color\",\"y\"]],[1,[5,\"1\"],\"-\",[7,\"color\",\"z\"]],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),wee=w.fn([S,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=A(t.x,t.y,t.z),a=Se(o,A(.299,.587,.114)),i=K(o,N(o,A(__tsover_sub(1,t.x),__tsover_sub(1,t.y),__tsover_sub(1,t.z)),a>s),A(r));return S(i.x,i.y,i.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"threshold\"},{type:\"i\",name:\"strength\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]],[13,\"luminance\",[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"inverted\",[6,\"d.vec3f\",[[1,[5,\"1\"],\"-\",[7,\"color\",\"x\"]],[1,[5,\"1\"],\"-\",[7,\"color\",\"y\"]],[1,[5,\"1\"],\"-\",[7,\"color\",\"z\"]]]]],[13,\"solarized\",[6,\"std.select\",[\"rgb\",\"inverted\",[1,\"luminance\",\">\",\"threshold\"]]]],[13,\"result\",[6,\"std.mix\",[\"rgb\",\"solarized\",[6,\"d.vec3f\",[\"strength\"]]]]],[10,[6,\"d.vec4f\",[[7,\"result\",\"x\"],[7,\"result\",\"y\"],[7,\"result\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.dot\":()=>Se,\"std.select\":()=>N,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),Tee=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=G(s,n(2),n(20));return S(__tsover_div(ie(__tsover_mul(t.x,r)),r),__tsover_div(ie(__tsover_mul(t.y,r)),r),__tsover_div(ie(__tsover_mul(t.z,r)),r),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"steps\"}],body:[0,[[13,\"s\",[6,\"std.clamp\",[\"steps\",[6,\"d.f32\",[[5,\"2\"]]],[6,\"d.f32\",[[5,\"20\"]]]]]],[13,\"r\",[1,[6,\"std.floor\",[[1,[7,\"color\",\"x\"],\"*\",\"s\"]]],\"/\",\"s\"]],[13,\"g\",[1,[6,\"std.floor\",[[1,[7,\"color\",\"y\"],\"*\",\"s\"]]],\"/\",\"s\"]],[13,\"b\",[1,[6,\"std.floor\",[[1,[7,\"color\",\"z\"],\"*\",\"s\"]]],\"/\",\"s\"]],[10,[6,\"d.vec4f\",[\"r\",\"g\",\"b\",[7,\"color\",\"w\"]]]]]]},externals:{\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.vec4f\":()=>S}})&&e.f)({})),See=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=K(A(t.x,t.y,t.z),A(s.x,s.y,s.z),A(r));return S(o.x,o.y,o.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"tintColor\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]],[13,\"tinted\",[6,\"std.mix\",[\"rgb\",[6,\"d.vec3f\",[[7,\"tintColor\",\"x\"],[7,\"tintColor\",\"y\"],[7,\"tintColor\",\"z\"]]],[6,\"d.vec3f\",[\"amount\"]]]]],[10,[6,\"d.vec4f\",[[7,\"tinted\",\"x\"],[7,\"tinted\",\"y\"],[7,\"tinted\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),Pee=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=A(t.x,t.y,t.z),a=K(o,A(s.x,s.y,s.z),A(r)),i=A(.299,.587,.114),l=Se(o,i),c=Se(a,i),d=a.mul(__tsover_div(l,B(c,1e-4)));return S(d.x,d.y,d.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"tintColor\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]],[13,\"tinted\",[6,\"std.mix\",[\"rgb\",[6,\"d.vec3f\",[[7,\"tintColor\",\"x\"],[7,\"tintColor\",\"y\"],[7,\"tintColor\",\"z\"]]],[6,\"d.vec3f\",[\"amount\"]]]]],[13,\"luminanceWeights\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]],[13,\"originalLum\",[6,\"std.dot\",[\"rgb\",\"luminanceWeights\"]]],[13,\"tintedLum\",[6,\"std.dot\",[\"tinted\",\"luminanceWeights\"]]],[13,\"result\",[6,[7,\"tinted\",\"mul\"],[[1,\"originalLum\",\"/\",[6,\"std.max\",[\"tintedLum\",[5,\"0.0001\"]]]]]]],[10,[6,\"d.vec4f\",[[7,\"result\",\"x\"],[7,\"result\",\"y\"],[7,\"result\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.mix\":()=>K,\"std.dot\":()=>Se,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&e.f)({})),Cee=w.fn([S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Se(t.xyz,A(.299,.587,.114));return be(__tsover_sub(s,.5),__tsover_add(s,.5),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"blend\"}],body:[0,[[13,\"luminance\",[6,\"std.dot\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[10,[6,\"std.smoothstep\",[[1,\"blend\",\"-\",[5,\"0.5\"]],[1,\"blend\",\"+\",[5,\"0.5\"]],\"luminance\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.smoothstep\":()=>be}})&&e.f)({})),Mee=w.fn([S,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Se(t.xyz,A(.299,.587,.114));return A(be(__tsover_sub(s,.25),s,r),be(s,__tsover_add(s,.25),r),be(__tsover_sub(s,.1),__tsover_add(s,.1),r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"blendMid\"}],body:[0,[[13,\"luminance\",[6,\"std.dot\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"shadowToMid\",[6,\"std.smoothstep\",[[1,\"blendMid\",\"-\",[5,\"0.25\"]],\"blendMid\",\"luminance\"]]],[13,\"midToHighlight\",[6,\"std.smoothstep\",[\"blendMid\",[1,\"blendMid\",\"+\",[5,\"0.25\"]],\"luminance\"]]],[13,\"finalT\",[6,\"std.smoothstep\",[[1,\"blendMid\",\"-\",[5,\"0.1\"]],[1,\"blendMid\",\"+\",[5,\"0.1\"]],\"luminance\"]]],[10,[6,\"d.vec3f\",[\"shadowToMid\",\"midToHighlight\",\"finalT\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.smoothstep\":()=>be}})&&e.f)({})),Eee=w.fn([S,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Se(t.xyz,A(.2126,.7152,.0722)),i=B(__tsover_sub(r,s),1e-4),l=G(__tsover_div(__tsover_sub(a,s),i),0,1);return l=G(__tsover_add(__tsover_mul(__tsover_sub(l,.5),o),.5),0,1),l}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"black\"},{type:\"i\",name:\"white\"},{type:\"i\",name:\"contrast\"}],body:[0,[[13,\"luma\",[6,\"std.dot\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"range\",[6,\"std.max\",[[1,\"white\",\"-\",\"black\"],[5,\"0.0001\"]]]],[12,\"t\",[6,\"std.clamp\",[[1,[1,\"luma\",\"-\",\"black\"],\"/\",\"range\"],[5,\"0\"],[5,\"1\"]]]],[2,\"t\",\"=\",[6,\"std.clamp\",[[1,[1,[1,\"t\",\"-\",[5,\"0.5\"]],\"*\",\"contrast\"],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[10,\"t\"]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.max\":()=>B,\"std.clamp\":()=>G}})&&e.f)({})),kee=w.fn([n,n,A,A,A,A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=a.mul(t).add(i).add(A(s,s,s)).mul(JT);return G(r.add(o.mul(pe(l))),A(0,0,0),A(1,1,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"pa\"},{type:\"i\",name:\"pb\"},{type:\"i\",name:\"pc\"},{type:\"i\",name:\"pd\"}],body:[0,[[13,\"arg\",[6,[7,[6,[7,[6,[7,[6,[7,\"pc\",\"mul\"],[\"t\"]],\"add\"],[\"pd\"]],\"add\"],[[6,\"d.vec3f\",[\"phase\",\"phase\",\"phase\"]]]],\"mul\"],[\"TWO_PI\"]]],[13,\"mapped\",[6,[7,\"pa\",\"add\"],[[6,[7,\"pb\",\"mul\"],[[6,\"std.cos\",[\"arg\"]]]]]]],[10,[6,\"std.clamp\",[\"mapped\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]]]]},externals:{\"d.vec3f\":()=>A,TWO_PI:()=>JT,\"std.cos\":()=>pe,\"std.clamp\":()=>G}})&&e.f)({})),Bee=w.fn([n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Re(__tsover_add(t,s)),o=__tsover_mul(r,3);return m(Re(o),ie(o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"phase\"}],body:[0,[[13,\"t01\",[6,\"std.fract\",[[1,\"t\",\"+\",\"phase\"]]]],[13,\"t3\",[1,\"t01\",\"*\",[5,\"3\"]]],[10,[6,\"d.vec2f\",[[6,\"std.fract\",[\"t3\"]],[6,\"std.floor\",[\"t3\"]]]]]]]},externals:{\"std.fract\":()=>Re,\"d.vec2f\":()=>m,\"std.floor\":()=>ie}})&&e.f)({})),zee=w.fn([S,S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return N(N(r,s,o<2),t,o<1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"seg0\"},{type:\"i\",name:\"seg1\"},{type:\"i\",name:\"seg2\"},{type:\"i\",name:\"i\"}],body:[0,[[13,\"upper\",[6,\"std.select\",[\"seg2\",\"seg1\",[1,\"i\",\"<\",[5,\"2\"]]]]],[10,[6,\"std.select\",[\"upper\",\"seg0\",[1,\"i\",\"<\",[5,\"1\"]]]]]]]},externals:{\"std.select\":()=>N}})&&e.f)({})),eS=w.fn([S,A,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return S(K(t.xyz,s,A(r,r,r)),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"mapped\"},{type:\"i\",name:\"strength\"}],body:[0,[[13,\"outRgb\",[6,\"std.mix\",[[7,\"color\",\"xyz\"],\"mapped\",[6,\"d.vec3f\",[\"strength\",\"strength\",\"strength\"]]]]],[10,[6,\"d.vec4f\",[\"outRgb\",[7,\"color\",\"w\"]]]]]]},externals:{\"std.mix\":()=>K,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Ree=w.fn([S,m,m,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Ys(s.mul(r).add(m(i,__tsover_mul(i,1.6180339)))),c=__tsover_sub(__tsover_mul(l,2),1),d=G(Se(t.xyz,A(.2126,.7152,.0722)),0,1),u=__tsover_sub(1,d),p=vt(__tsover_add(u,1e-6),a),_=__tsover_mul(__tsover_mul(c,p),__tsover_mul(o,.1));return S(t.xyz.add(_),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"bias\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"pixelCoord\",[6,[7,\"uv\",\"mul\"],[\"viewport\"]]],[13,\"noiseVal\",[6,\"hash12\",[[6,[7,\"pixelCoord\",\"add\"],[[6,\"d.vec2f\",[\"animTime\",[1,\"animTime\",\"*\",[5,\"1.6180339\"]]]]]]]]],[13,\"grain\",[1,[1,\"noiseVal\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"brightness\",[6,\"std.clamp\",[[6,\"std.dot\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"darkness\",[1,[5,\"1\"],\"-\",\"brightness\"]],[13,\"darkFactor\",[6,\"std.pow\",[[1,\"darkness\",\"+\",[5,\"0.000001\"]],\"bias\"]]],[13,\"grainIntensity\",[1,[1,\"grain\",\"*\",\"darkFactor\"],\"*\",[1,\"strength\",\"*\",[5,\"0.1\"]]]],[13,\"grainedColor\",[6,[7,[7,\"color\",\"xyz\"],\"add\"],[\"grainIntensity\"]]],[10,[6,\"d.vec4f\",[\"grainedColor\",[7,\"color\",\"w\"]]]]]]},externals:{hash12:()=>Ys,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.pow\":()=>vt,\"d.vec4f\":()=>S}})&&e.f)({})),gv=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=vt(N(t,__tsover_sub(1,t),i>.5),a),c=__tsover_add(__tsover_mul(l,s),.5),d=B(mr(c),1e-4),u=re(__tsover_sub(Re(__tsover_add(c,.5)),.5)),p=__tsover_div(u,d),_=__tsover_add(__tsover_mul(o,.99),.01),f=__tsover_mul(r,__tsover_sub(1,_));return __tsover_sub(1,be(f,r,p))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sourceValue\"},{type:\"i\",name:\"levels\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"gamma\"},{type:\"i\",name:\"invert\"}],body:[0,[[13,\"invertedValue\",[6,\"std.select\",[\"sourceValue\",[1,[5,\"1\"],\"-\",\"sourceValue\"],[1,\"invert\",\">\",[5,\"0.5\"]]]]],[13,\"sv\",[6,\"std.pow\",[\"invertedValue\",\"gamma\"]]],[13,\"scaledValue\",[1,[1,\"sv\",\"*\",\"levels\"],\"+\",[5,\"0.5\"]]],[13,\"fw\",[6,\"std.max\",[[6,\"std.fwidth\",[\"scaledValue\"]],[5,\"0.0001\"]]]],[13,\"distFromBoundary\",[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,\"scaledValue\",\"+\",[5,\"0.5\"]]]],\"-\",[5,\"0.5\"]]]]],[13,\"normalizedDist\",[1,\"distFromBoundary\",\"/\",\"fw\"]],[13,\"transitionFactor\",[1,[1,\"softness\",\"*\",[5,\"0.99\"]],\"+\",[5,\"0.01\"]]],[13,\"innerEdge\",[1,\"lineWidth\",\"*\",[1,[5,\"1\"],\"-\",\"transitionFactor\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"innerEdge\",\"lineWidth\",\"normalizedDist\"]]]]]]},externals:{\"std.select\":()=>N,\"std.pow\":()=>vt,\"std.max\":()=>B,\"std.fwidth\":()=>mr,\"std.abs\":()=>re,\"std.fract\":()=>Re,\"std.smoothstep\":()=>be}})&&e.f)({})),Dee=w.fn([S,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return gv(pT(t.xyz),s,r,o,a,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"levels\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"gamma\"},{type:\"i\",name:\"invert\"}],body:[0,[[10,[6,\"contourLineMask\",[[6,\"luma709Dot\",[[7,\"color\",\"xyz\"]]],\"levels\",\"lineWidth\",\"softness\",\"gamma\",\"invert\"]]]]]},externals:{contourLineMask:()=>gv,luma709Dot:()=>pT}})&&e.f)({})),Lee=w.fn([S,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return gv(t.w,s,r,o,a,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"levels\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"gamma\"},{type:\"i\",name:\"invert\"}],body:[0,[[10,[6,\"contourLineMask\",[[7,\"color\",\"w\"],\"levels\",\"lineWidth\",\"softness\",\"gamma\",\"invert\"]]]]]},externals:{contourLineMask:()=>gv}})&&e.f)({})),Uee=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=K(A(t.x,t.y,t.z),A(s.x,s.y,s.z),A(r)),a=K(t.w,s.w,r);return S(o.x,o.y,o.z,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"bg\"},{type:\"i\",name:\"line\"},{type:\"i\",name:\"mask\"}],body:[0,[[13,\"rgb\",[6,\"std.mix\",[[6,\"d.vec3f\",[[7,\"bg\",\"x\"],[7,\"bg\",\"y\"],[7,\"bg\",\"z\"]]],[6,\"d.vec3f\",[[7,\"line\",\"x\"],[7,\"line\",\"y\"],[7,\"line\",\"z\"]]],[6,\"d.vec3f\",[\"mask\"]]]]],[13,\"alpha\",[6,\"std.mix\",[[7,\"bg\",\"w\"],[7,\"line\",\"w\"],\"mask\"]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"alpha\"]]]]]},externals:{\"std.mix\":()=>K,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Vl=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(__tsover_sub(Re(__tsover_mul(ae(__tsover_mul(t,12.9898)),43758.5453)),.5),2)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"}],body:[0,[[10,[1,[1,[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,\"x\",\"*\",[5,\"12.9898\"]]]],\"*\",[5,\"43758.5453\"]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]]]]},externals:{\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({})),Oee=w.fn([m,n,m,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(__tsover_mul(r.x,o),r.y),i=m(__tsover_mul(t.x,o),__tsover_sub(1,t.y)),l=a.sub(i),c=__tsover_mul(s,bt),d=m(pe(c),ae(c)),u=m(__tsover_mul(d.y,-1),d.x),p=Se(l,u),_=l.sub(u.mul(__tsover_mul(p,2))),f=i.add(_),h=m(__tsover_div(f.x,o),f.y),g=Et(0,p);return A(h.x,h.y,g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[\"centerPos\"]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"lineDirection\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angleRad\"]],[6,\"std.sin\",[\"angleRad\"]]]]],[13,\"lineNormal\",[6,\"d.vec2f\",[[1,[7,\"lineDirection\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[7,\"lineDirection\",\"x\"]]]],[13,\"signedDistance\",[6,\"std.dot\",[\"delta\",\"lineNormal\"]]],[13,\"reflectedDelta\",[6,[7,\"delta\",\"sub\"],[[6,[7,\"lineNormal\",\"mul\"],[[1,\"signedDistance\",\"*\",[5,\"2\"]]]]]]],[13,\"mirroredUV\",[6,[7,\"centerPos\",\"add\"],[\"reflectedDelta\"]]],[13,\"finalMirroredUV\",[6,\"d.vec2f\",[[1,[7,\"mirroredUV\",\"x\"],\"/\",\"aspect\"],[7,\"mirroredUV\",\"y\"]]]],[13,\"shouldMirror\",[6,\"std.step\",[[5,\"0\"],\"signedDistance\"]]],[10,[6,\"d.vec3f\",[[7,\"finalMirroredUV\",\"x\"],[7,\"finalMirroredUV\",\"y\"],\"shouldMirror\"]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.step\":()=>Et,\"d.vec3f\":()=>A}})&&e.f)({})),Gee=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(N(t.x,__tsover_sub(1,t.x),s>0),N(t.y,__tsover_sub(1,t.y),r>0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"flipX\"},{type:\"i\",name:\"flipY\"}],body:[0,[[13,\"x\",[6,\"std.select\",[[7,\"uv\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"uv\",\"x\"]],[1,\"flipX\",\">\",[5,\"0\"]]]]],[13,\"y\",[6,\"std.select\",[[7,\"uv\",\"y\"],[1,[5,\"1\"],\"-\",[7,\"uv\",\"y\"]],[1,\"flipY\",\">\",[5,\"0\"]]]]],[10,[6,\"d.vec2f\",[\"x\",\"y\"]]]]]},externals:{\"std.select\":()=>N,\"d.vec2f\":()=>m}})&&e.f)({})),Vc=2,tS=1.2,Fee=w.fn([n,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,bt),l=m(pe(i),ae(i)),c=m(__tsover_mul(l.y,-1),l.x),d=m(__tsover_mul(__tsover_sub(o.x,.5),a),__tsover_sub(o.y,.5)),u=Se(d,l),p=Se(d,c),_=B(__tsover_mul(__tsover_add(__tsover_mul(re(l.x),a),re(l.y)),.5),.001),f=__tsover_div(u,_),h=__tsover_mul(t,tS),g=__tsover_mul(G(s,0,1),.9),y=__tsover_sub(1,g),b=re(f),x=N(n(-1),n(1),f>=0),P=__tsover_mul(h,b),C=__tsover_add(__tsover_mul(__tsover_mul(__tsover_mul(Vc,Vc),y),y),__tsover_mul(__tsover_mul(__tsover_mul(4,P),Vc),__tsover_sub(b,g))),E=re(P)<1e-5,R=N(__tsover_mul(P,2),n(1),E),U=N(__tsover_div(__tsover_sub(Ue(B(C,0)),__tsover_mul(Vc,y)),R),__tsover_div(__tsover_sub(b,g),y),E),L=N(n(6),B(U,0),C>=0),k=__tsover_mul(x,__tsover_add(g,__tsover_mul(L,y))),D=b<=g,O=N(k,f,D),F=N(__tsover_mul(__tsover_mul(h,L),L),n(0),D),q=__tsover_div(__tsover_mul(p,__tsover_sub(Vc,F)),Vc),Y=l.mul(__tsover_mul(O,_)).add(c.mul(q));return m(__tsover_add(__tsover_div(Y.x,a),.5),__tsover_add(Y.y,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"strength\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"dir\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angleRad\"]],[6,\"std.sin\",[\"angleRad\"]]]]],[13,\"perp\",[6,\"d.vec2f\",[[1,[7,\"dir\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[7,\"dir\",\"x\"]]]],[13,\"p\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]],[13,\"sScreen\",[6,\"std.dot\",[\"p\",\"dir\"]]],[13,\"tScreen\",[6,\"std.dot\",[\"p\",\"perp\"]]],[13,\"sHalf\",[6,\"std.max\",[[1,[1,[1,[6,\"std.abs\",[[7,\"dir\",\"x\"]]],\"*\",\"aspect\"],\"+\",[6,\"std.abs\",[[7,\"dir\",\"y\"]]]],\"*\",[5,\"0.5\"]],[5,\"0.001\"]]]],[13,\"snScreen\",[1,\"sScreen\",\"/\",\"sHalf\"]],[13,\"b\",[1,\"strength\",\"*\",\"B_MAX\"]],[13,\"f\",[1,[6,\"std.clamp\",[\"falloff\",[5,\"0\"],[5,\"1\"]]],\"*\",[5,\"0.9\"]]],[13,\"fSpan\",[1,[5,\"1\"],\"-\",\"f\"]],[13,\"m\",[6,\"std.abs\",[\"snScreen\"]]],[13,\"sig\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"snScreen\",\">=\",[5,\"0\"]]]]],[13,\"a2\",[1,\"b\",\"*\",\"m\"]],[13,\"disc\",[1,[1,[1,[1,\"CAMERA_D\",\"*\",\"CAMERA_D\"],\"*\",\"fSpan\"],\"*\",\"fSpan\"],\"+\",[1,[1,[1,[5,\"4\"],\"*\",\"a2\"],\"*\",\"CAMERA_D\"],\"*\",[1,\"m\",\"-\",\"f\"]]]],[13,\"nearZero\",[1,[6,\"std.abs\",[\"a2\"]],\"<\",[5,\"0.00001\"]]],[13,\"denom\",[6,\"std.select\",[[1,\"a2\",\"*\",[5,\"2\"]],[6,\"d.f32\",[[5,\"1\"]]],\"nearZero\"]]],[13,\"uQuad\",[1,[1,[6,\"std.sqrt\",[[6,\"std.max\",[\"disc\",[5,\"0\"]]]]],\"-\",[1,\"CAMERA_D\",\"*\",\"fSpan\"]],\"/\",\"denom\"]],[13,\"uOn\",[6,\"std.select\",[\"uQuad\",[1,[1,\"m\",\"-\",\"f\"],\"/\",\"fSpan\"],\"nearZero\"]]],[13,\"u\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"6\"]]],[6,\"std.max\",[\"uOn\",[5,\"0\"]]],[1,\"disc\",\">=\",[5,\"0\"]]]]],[13,\"snBend\",[1,\"sig\",\"*\",[1,\"f\",\"+\",[1,\"u\",\"*\",\"fSpan\"]]]],[13,\"inFlat\",[1,\"m\",\"<=\",\"f\"]],[13,\"sn\",[6,\"std.select\",[\"snBend\",\"snScreen\",\"inFlat\"]]],[13,\"z\",[6,\"std.select\",[[1,[1,\"b\",\"*\",\"u\"],\"*\",\"u\"],[6,\"d.f32\",[[5,\"0\"]]],\"inFlat\"]]],[13,\"tSrc\",[1,[1,\"tScreen\",\"*\",[1,\"CAMERA_D\",\"-\",\"z\"]],\"/\",\"CAMERA_D\"]],[13,\"srcP\",[6,[7,[6,[7,\"dir\",\"mul\"],[[1,\"sn\",\"*\",\"sHalf\"]]],\"add\"],[[6,[7,\"perp\",\"mul\"],[\"tSrc\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,[7,\"srcP\",\"x\"],\"/\",\"aspect\"],\"+\",[5,\"0.5\"]],[1,[7,\"srcP\",\"y\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.max\":()=>B,\"std.abs\":()=>re,B_MAX:()=>tS,\"std.clamp\":()=>G,\"std.select\":()=>N,\"d.f32\":()=>n,CAMERA_D:()=>Vc,\"std.sqrt\":()=>Ue}})&&e.f)({})),Iee=w.fn([m,n,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(__tsover_mul(a.x,i),a.y),c=m(__tsover_mul(t.x,i),__tsover_sub(1,t.y)),d=l.sub(c),u=he(d),p=__tsover_mul(r,.5),_=__tsover_mul(p,B(__tsover_sub(__tsover_sub(1,o),.001),0)),f=__tsover_sub(1,be(_,p,u)),h=__tsover_div(u,p),g=__tsover_mul(h,h),y=B(0,__tsover_sub(1,g)),b=__tsover_mul(f,y),x=__tsover_mul(s,-1),P=__tsover_mul(x,b),C=__tsover_add(1,P),E=d.mul(C),R=c.add(E);return m(__tsover_div(R.x,i),R.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[\"centerPos\"]]],[13,\"distance\",[6,\"std.length\",[\"delta\"]]],[13,\"effectRadius\",[1,\"radius\",\"*\",[5,\"0.5\"]]],[13,\"innerRadius\",[1,\"effectRadius\",\"*\",[6,\"std.max\",[[1,[1,[5,\"1\"],\"-\",\"falloff\"],\"-\",[5,\"0.001\"]],[5,\"0\"]]]]],[13,\"smoothFalloff\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"innerRadius\",\"effectRadius\",\"distance\"]]]],[13,\"normalizedDist\",[1,\"distance\",\"/\",\"effectRadius\"]],[13,\"distSq\",[1,\"normalizedDist\",\"*\",\"normalizedDist\"]],[13,\"quadraticFalloff\",[6,\"std.max\",[[5,\"0\"],[1,[5,\"1\"],\"-\",\"distSq\"]]]],[13,\"falloffTotal\",[1,\"smoothFalloff\",\"*\",\"quadraticFalloff\"]],[13,\"negStrength\",[1,\"strength\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"displacementAmount\",[1,\"negStrength\",\"*\",\"falloffTotal\"]],[13,\"scaleFactor\",[1,[5,\"1\"],\"+\",\"displacementAmount\"]],[13,\"bulgedDelta\",[6,[7,\"delta\",\"mul\"],[\"scaleFactor\"]]],[13,\"bulgedUV\",[6,[7,\"centerPos\",\"add\"],[\"bulgedDelta\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"bulgedUV\",\"x\"],\"/\",\"aspect\"],[7,\"bulgedUV\",\"y\"]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.max\":()=>B,\"std.smoothstep\":()=>be}})&&e.f)({})),Yee=w.fn([m,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(t.x,__tsover_sub(1,t.y)),i=r.sub(a),l=m(__tsover_mul(i.x,o),i.y),c=__tsover_mul(s,he(l)),d=pe(c),u=ae(c),p=__tsover_sub(__tsover_mul(d,l.x),__tsover_mul(u,l.y)),_=__tsover_add(__tsover_mul(u,l.x),__tsover_mul(d,l.y));return m(__tsover_add(__tsover_div(p,o),a.x),__tsover_add(_,a.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"uv\",\"sub\"],[\"centerPos\"]]],[13,\"acd\",[6,\"d.vec2f\",[[1,[7,\"delta\",\"x\"],\"*\",\"aspect\"],[7,\"delta\",\"y\"]]]],[13,\"angle\",[1,\"intensity\",\"*\",[6,\"std.length\",[\"acd\"]]]],[13,\"cosA\",[6,\"std.cos\",[\"angle\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angle\"]]],[13,\"rotatedX\",[1,[1,\"cosA\",\"*\",[7,\"acd\",\"x\"]],\"-\",[1,\"sinA\",\"*\",[7,\"acd\",\"y\"]]]],[13,\"rotatedY\",[1,[1,\"sinA\",\"*\",[7,\"acd\",\"x\"]],\"+\",[1,\"cosA\",\"*\",[7,\"acd\",\"y\"]]]],[10,[6,\"d.vec2f\",[[1,[1,\"rotatedX\",\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,\"rotatedY\",\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),Wee=w.fn([m,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(o.x,a),o.y),l=m(__tsover_mul(t.x,a),__tsover_sub(1,t.y)),c=i.sub(l),d=he(c),u=Xt(c.y,c.x),p=__tsover_add(u,__tsover_mul(r,bt)),_=__tsover_div(Jt,s),f=__tsover_mul(_,2),h=__tsover_sub(p,__tsover_mul(f,ie(__tsover_div(p,f)))),g=N(h,__tsover_sub(f,h),h>_),y=__tsover_mul(pe(g),d),b=__tsover_mul(ae(g),d),x=l.add(m(y,b));return m(__tsover_div(x.x,a),x.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"segments\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[\"centerPos\"]]],[13,\"radius\",[6,\"std.length\",[\"delta\"]]],[13,\"currentAngle\",[6,\"std.atan2\",[[7,\"delta\",\"y\"],[7,\"delta\",\"x\"]]]],[13,\"rotatedAngle\",[1,\"currentAngle\",\"+\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]]],[13,\"segmentAngle\",[1,\"TAU\",\"/\",\"segments\"]],[13,\"segTwo\",[1,\"segmentAngle\",\"*\",[5,\"2\"]]],[13,\"wrappedAngle\",[1,\"rotatedAngle\",\"-\",[1,\"segTwo\",\"*\",[6,\"std.floor\",[[1,\"rotatedAngle\",\"/\",\"segTwo\"]]]]]],[13,\"finalAngle\",[6,\"std.select\",[\"wrappedAngle\",[1,\"segTwo\",\"-\",\"wrappedAngle\"],[1,\"wrappedAngle\",\">\",\"segmentAngle\"]]]],[13,\"kaleidoscopeX\",[1,[6,\"std.cos\",[\"finalAngle\"]],\"*\",\"radius\"]],[13,\"kaleidoscopeY\",[1,[6,\"std.sin\",[\"finalAngle\"]],\"*\",\"radius\"]],[13,\"kaleidoscopePos\",[6,[7,\"centerPos\",\"add\"],[[6,\"d.vec2f\",[\"kaleidoscopeX\",\"kaleidoscopeY\"]]]]],[10,[6,\"d.vec2f\",[[1,[7,\"kaleidoscopePos\",\"x\"],\"/\",\"aspect\"],[7,\"kaleidoscopePos\",\"y\"]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.atan2\":()=>Xt,DEG_TO_RAD:()=>bt,TAU:()=>Jt,\"std.floor\":()=>ie,\"std.select\":()=>N,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),qee=w.fn([m,n,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(__tsover_mul(a.x,i),a.y),c=m(__tsover_mul(t.x,i),__tsover_sub(1,t.y)),d=l.sub(c),u=__tsover_mul(r,bt),p=m(pe(u),ae(u)),_=Se(d,p),f=p.mul(_),h=d.sub(f),g=K(.001,75,o),y=G(__tsover_div(_,g),0,1),b=__tsover_mul(s,100),x=__tsover_add(1,__tsover_mul(b,y)),P=__tsover_div(_,x),C=p.mul(P).add(h),E=c.add(C);return m(__tsover_div(E.x,i),E.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[\"centerPos\"]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"directionVector\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angleRad\"]],[6,\"std.sin\",[\"angleRad\"]]]]],[13,\"projection\",[6,\"std.dot\",[\"delta\",\"directionVector\"]]],[13,\"parallel\",[6,[7,\"directionVector\",\"mul\"],[\"projection\"]]],[13,\"perpendicular\",[6,[7,\"delta\",\"sub\"],[\"parallel\"]]],[13,\"transitionWidth\",[6,\"std.mix\",[[5,\"0.001\"],[5,\"75\"],\"falloff\"]]],[13,\"effectMask\",[6,\"std.clamp\",[[1,\"projection\",\"/\",\"transitionWidth\"],[5,\"0\"],[5,\"1\"]]]],[13,\"scaledStrength\",[1,\"strength\",\"*\",[5,\"100\"]]],[13,\"stretchFactor\",[1,[5,\"1\"],\"+\",[1,\"scaledStrength\",\"*\",\"effectMask\"]]],[13,\"finalProjection\",[1,\"projection\",\"/\",\"stretchFactor\"]],[13,\"finalParallel\",[6,[7,\"directionVector\",\"mul\"],[\"finalProjection\"]]],[13,\"stretchedDelta\",[6,[7,\"finalParallel\",\"add\"],[\"perpendicular\"]]],[13,\"stretchedUV\",[6,[7,\"centerPos\",\"add\"],[\"stretchedDelta\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"stretchedUV\",\"x\"],\"/\",\"aspect\"],[7,\"stretchedUV\",\"y\"]]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.mix\":()=>K,\"std.clamp\":()=>G}})&&e.f)({})),Ci=w.fn([m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=t.sub(m(.5,.5)),l=m(__tsover_mul(i.x,s),i.y),c=__tsover_mul(r,bt),d=pe(c),u=ae(c),p=__tsover_add(__tsover_mul(l.x,u),__tsover_mul(l.y,d));return __tsover_add(__tsover_mul(__tsover_mul(__tsover_add(p,.5),o),Jt),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"centeredUV\",\"x\"],\"*\",\"aspect\"],[7,\"centeredUV\",\"y\"]]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rotatedY\",[1,[1,[7,\"aspectCorrectedUV\",\"x\"],\"*\",\"sinA\"],\"+\",[1,[7,\"aspectCorrectedUV\",\"y\"],\"*\",\"cosA\"]]],[10,[1,[1,[1,[1,\"rotatedY\",\"+\",[5,\"0.5\"]],\"*\",\"frequency\"],\"*\",\"TAU\"],\"+\",\"t\"]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,TAU:()=>Jt}})&&e.f)({})),Mi=w.fn([m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,bt),l=pe(i),c=ae(i),d=__tsover_mul(__tsover_mul(a,o),.5),u=__tsover_div(__tsover_mul(d,l),s),p=__tsover_mul(d,c);return m(__tsover_add(t.x,u),__tsover_add(t.y,p))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"wave\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"displacement\",[1,[1,\"wave\",\"*\",\"strength\"],\"*\",[5,\"0.5\"]]],[13,\"displacementX\",[1,[1,\"displacement\",\"*\",\"cosA\"],\"/\",\"aspect\"]],[13,\"displacementY\",[1,\"displacement\",\"*\",\"sinA\"]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",\"displacementX\"],[1,[7,\"uv\",\"y\"],\"+\",\"displacementY\"]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),sS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return ae(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[10,[6,\"std.sin\",[\"phase\"]]]]]},externals:{\"std.sin\":()=>ae}})&&e.f)({})),rS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Re(__tsover_div(t,Jt));return __tsover_sub(__tsover_mul(re(__tsover_sub(__tsover_mul(s,2),1)),2),1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[13,\"normalizedPhase\",[6,\"std.fract\",[[1,\"phase\",\"/\",\"TAU\"]]]],[10,[1,[1,[6,\"std.abs\",[[1,[1,\"normalizedPhase\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]]},externals:{\"std.fract\":()=>Re,TAU:()=>Jt,\"std.abs\":()=>re}})&&e.f)({})),oS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Re(__tsover_div(t,Jt));return __tsover_sub(__tsover_mul(Et(.5,s),2),1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[13,\"normalizedPhase\",[6,\"std.fract\",[[1,\"phase\",\"/\",\"TAU\"]]]],[10,[1,[1,[6,\"std.step\",[[5,\"0.5\"],\"normalizedPhase\"]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]]},externals:{\"std.fract\":()=>Re,TAU:()=>Jt,\"std.step\":()=>Et}})&&e.f)({})),aS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Re(__tsover_div(t,Jt));return __tsover_sub(__tsover_mul(s,2),1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[13,\"normalizedPhase\",[6,\"std.fract\",[[1,\"phase\",\"/\",\"TAU\"]]]],[10,[1,[1,\"normalizedPhase\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]]},externals:{\"std.fract\":()=>Re,TAU:()=>Jt}})&&e.f)({})),nS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return re(ae(t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[10,[6,\"std.abs\",[[6,\"std.sin\",[\"phase\"]]]]]]]},externals:{\"std.abs\":()=>re,\"std.sin\":()=>ae}})&&e.f)({})),Vee=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return Mi(t,s,r,a,sS(Ci(t,s,r,o,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"wave\",[6,\"waveformSine\",[[6,\"wavePhase\",[\"uv\",\"aspect\",\"angle\",\"frequency\",\"t\"]]]]],[10,[6,\"waveApply\",[\"uv\",\"aspect\",\"angle\",\"strength\",\"wave\"]]]]]},externals:{waveformSine:()=>sS,wavePhase:()=>Ci,waveApply:()=>Mi}})&&e.f)({})),Nee=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return Mi(t,s,r,a,rS(Ci(t,s,r,o,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"wave\",[6,\"waveformTriangle\",[[6,\"wavePhase\",[\"uv\",\"aspect\",\"angle\",\"frequency\",\"t\"]]]]],[10,[6,\"waveApply\",[\"uv\",\"aspect\",\"angle\",\"strength\",\"wave\"]]]]]},externals:{waveformTriangle:()=>rS,wavePhase:()=>Ci,waveApply:()=>Mi}})&&e.f)({})),$ee=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return Mi(t,s,r,a,oS(Ci(t,s,r,o,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"wave\",[6,\"waveformSquare\",[[6,\"wavePhase\",[\"uv\",\"aspect\",\"angle\",\"frequency\",\"t\"]]]]],[10,[6,\"waveApply\",[\"uv\",\"aspect\",\"angle\",\"strength\",\"wave\"]]]]]},externals:{waveformSquare:()=>oS,wavePhase:()=>Ci,waveApply:()=>Mi}})&&e.f)({})),Xee=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return Mi(t,s,r,a,aS(Ci(t,s,r,o,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"wave\",[6,\"waveformSawtooth\",[[6,\"wavePhase\",[\"uv\",\"aspect\",\"angle\",\"frequency\",\"t\"]]]]],[10,[6,\"waveApply\",[\"uv\",\"aspect\",\"angle\",\"strength\",\"wave\"]]]]]},externals:{waveformSawtooth:()=>aS,wavePhase:()=>Ci,waveApply:()=>Mi}})&&e.f)({})),Hee=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return Mi(t,s,r,a,nS(Ci(t,s,r,o,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"wave\",[6,\"waveformBounce\",[[6,\"wavePhase\",[\"uv\",\"aspect\",\"angle\",\"frequency\",\"t\"]]]]],[10,[6,\"waveApply\",[\"uv\",\"aspect\",\"angle\",\"strength\",\"wave\"]]]]]},externals:{waveformBounce:()=>nS,wavePhase:()=>Ci,waveApply:()=>Mi}})&&e.f)({})),jee=w.fn([m,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(o.x,a),o.y),l=m(__tsover_mul(t.x,a),__tsover_sub(1,t.y)),c=i.sub(l),d=Xt(c.y,c.x),u=__tsover_div(__tsover_add(d,Wo),Jt),p=he(c);return m(__tsover_mul(u,s),__tsover_mul(p,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"wrap\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[\"centerPos\"]]],[13,\"theta\",[6,\"std.atan2\",[[7,\"delta\",\"y\"],[7,\"delta\",\"x\"]]]],[13,\"normalizedAngle\",[1,[1,\"theta\",\"+\",\"PI\"],\"/\",\"TAU\"]],[13,\"r\",[6,\"std.length\",[\"delta\"]]],[13,\"u\",[1,\"normalizedAngle\",\"*\",\"wrap\"]],[13,\"v\",[1,\"r\",\"*\",\"radius\"]],[10,[6,\"d.vec2f\",[\"u\",\"v\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.atan2\":()=>Xt,PI:()=>Wo,TAU:()=>Jt,\"std.length\":()=>he}})&&e.f)({})),Kee=w.fn([m,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(__tsover_mul(r.x,Jt),Wo),i=__tsover_mul(r.y,s),l=__tsover_mul(i,pe(a)),c=__tsover_mul(i,ae(a)),d=m(t.x,__tsover_sub(1,t.y));return m(__tsover_add(__tsover_div(l,o),d.x),__tsover_add(c,d.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"theta\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"TAU\"],\"-\",\"PI\"]],[13,\"r\",[1,[7,\"uv\",\"y\"],\"*\",\"scale\"]],[13,\"rectX\",[1,\"r\",\"*\",[6,\"std.cos\",[\"theta\"]]]],[13,\"rectY\",[1,\"r\",\"*\",[6,\"std.sin\",[\"theta\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,\"rectX\",\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,\"rectY\",\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{TAU:()=>Jt,PI:()=>Wo,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),Au=1e-8,im=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_div(t,N(s,Au,re(s)<Au))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"n\"},{type:\"i\",name:\"dv\"}],body:[0,[[10,[1,\"n\",\"/\",[6,\"std.select\",[\"dv\",\"EPS\",[1,[6,\"std.abs\",[\"dv\"]],\"<\",\"EPS\"]]]]]]]},externals:{\"std.select\":()=>N,EPS:()=>Au,\"std.abs\":()=>re}})&&e.f)({})),vu=w.fn([m,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(r.x,s.x),a=__tsover_sub(r.y,s.y),i=__tsover_sub(t.x,s.x),l=__tsover_sub(t.y,s.y);return __tsover_sub(__tsover_mul(o,l),__tsover_mul(a,i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"}],body:[0,[[13,\"bax\",[1,[7,\"b\",\"x\"],\"-\",[7,\"a\",\"x\"]]],[13,\"bay\",[1,[7,\"b\",\"y\"],\"-\",[7,\"a\",\"y\"]]],[13,\"pax\",[1,[7,\"p\",\"x\"],\"-\",[7,\"a\",\"x\"]]],[13,\"pay\",[1,[7,\"p\",\"y\"],\"-\",[7,\"a\",\"y\"]]],[10,[1,[1,\"bax\",\"*\",\"pay\"],\"-\",[1,\"bay\",\"*\",\"pax\"]]]]]},externals:{}})&&e.f)({})),iS=w.fn([m,m,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=vu(t,s,r),i=vu(t,r,o),l=vu(t,o,s),c=__tsover_mul(__tsover_mul(Et(n(0),a),Et(n(0),i)),Et(n(0),l)),d=__tsover_mul(__tsover_mul(Et(a,n(0)),Et(i,n(0))),Et(l,n(0)));return __tsover_add(c,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"c\"}],body:[0,[[13,\"d1\",[6,\"cornerSideOf\",[\"p\",\"a\",\"b\"]]],[13,\"d2\",[6,\"cornerSideOf\",[\"p\",\"b\",\"c\"]]],[13,\"d3\",[6,\"cornerSideOf\",[\"p\",\"c\",\"a\"]]],[13,\"allPos\",[1,[1,[6,\"std.step\",[[6,\"d.f32\",[[5,\"0\"]]],\"d1\"]],\"*\",[6,\"std.step\",[[6,\"d.f32\",[[5,\"0\"]]],\"d2\"]]],\"*\",[6,\"std.step\",[[6,\"d.f32\",[[5,\"0\"]]],\"d3\"]]]],[13,\"allNeg\",[1,[1,[6,\"std.step\",[\"d1\",[6,\"d.f32\",[[5,\"0\"]]]]],\"*\",[6,\"std.step\",[\"d2\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",[6,\"std.step\",[\"d3\",[6,\"d.f32\",[[5,\"0\"]]]]]]],[10,[1,\"allPos\",\"+\",\"allNeg\"]]]]},externals:{cornerSideOf:()=>vu,\"std.step\":()=>Et,\"d.f32\":()=>n}})&&e.f)({})),lS=w.fn([m,m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=r.sub(s),i=G(__tsover_div(Se(t.sub(s),a),B(Se(a,a),Au)),0,1),l=s.add(a.mul(i)),c=m(__tsover_mul(a.y,-1),a.x).div(B(he(a),Au)),d=__tsover_mul(__tsover_mul(no(o),-1),.004);return l.add(c.mul(d))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"refSide\"}],body:[0,[[13,\"ab\",[6,[7,\"b\",\"sub\"],[\"a\"]]],[13,\"t\",[6,\"std.clamp\",[[1,[6,\"std.dot\",[[6,[7,\"p\",\"sub\"],[\"a\"]],\"ab\"]],\"/\",[6,\"std.max\",[[6,\"std.dot\",[\"ab\",\"ab\"]],\"EPS\"]]],[5,\"0\"],[5,\"1\"]]]],[13,\"foot\",[6,[7,\"a\",\"add\"],[[6,[7,\"ab\",\"mul\"],[\"t\"]]]]],[13,\"perp\",[6,[7,[6,\"d.vec2f\",[[1,[7,\"ab\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[7,\"ab\",\"x\"]]],\"div\"],[[6,\"std.max\",[[6,\"std.length\",[\"ab\"]],\"EPS\"]]]]],[13,\"nudge\",[1,[1,[6,\"std.sign\",[\"refSide\"]],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",[5,\"0.004\"]]],[10,[6,[7,\"foot\",\"add\"],[[6,[7,\"perp\",\"mul\"],[\"nudge\"]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.dot\":()=>Se,\"std.max\":()=>B,EPS:()=>Au,\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.sign\":()=>no}})&&e.f)({})),lm=w.fn([m,m,m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=iS(t,s,r,o)>.5;return N(t,lS(t,s,r,vu(o,s,r)),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"o\"}],body:[0,[[13,\"inside\",[1,[6,\"cornerInsideTri\",[\"p\",\"a\",\"b\",\"o\"]],\">\",[5,\"0.5\"]]],[13,\"proj\",[6,\"cornerProjectToDiagonal\",[\"p\",\"a\",\"b\",[6,\"cornerSideOf\",[\"o\",\"a\",\"b\"]]]]],[10,[6,\"std.select\",[\"p\",\"proj\",\"inside\"]]]]]},externals:{cornerInsideTri:()=>iS,cornerProjectToDiagonal:()=>lS,cornerSideOf:()=>vu,\"std.select\":()=>N}})&&e.f)({})),Qee=w.fn([m,n,m,m,m,m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(s,s),c=K(m(0,0),m(r.x,__tsover_sub(1,r.y)),l),d=K(m(1,0),m(o.x,__tsover_sub(1,o.y)),l),u=K(m(1,1),m(a.x,__tsover_sub(1,a.y)),l),p=K(m(0,1),m(i.x,__tsover_sub(1,i.y)),l),_=lm(c,d,p,u),f=lm(d,c,u,p),h=lm(u,d,p,c),g=lm(p,c,u,d),y=__tsover_sub(f.x,h.x),b=__tsover_sub(g.x,h.x),x=__tsover_sub(__tsover_add(__tsover_sub(_.x,f.x),h.x),g.x),P=__tsover_sub(f.y,h.y),C=__tsover_sub(g.y,h.y),E=__tsover_sub(__tsover_add(__tsover_sub(_.y,f.y),h.y),g.y),R=__tsover_sub(__tsover_mul(y,C),__tsover_mul(b,P)),U=im(__tsover_sub(__tsover_mul(x,C),__tsover_mul(b,E)),R),L=im(__tsover_sub(__tsover_mul(y,E),__tsover_mul(x,P)),R),k=__tsover_add(__tsover_sub(f.x,_.x),__tsover_mul(U,f.x)),D=__tsover_add(__tsover_sub(g.x,_.x),__tsover_mul(L,g.x)),O=_.x,F=__tsover_add(__tsover_sub(f.y,_.y),__tsover_mul(U,f.y)),q=__tsover_add(__tsover_sub(g.y,_.y),__tsover_mul(L,g.y)),Y=_.y,V=__tsover_sub(q,__tsover_mul(Y,L)),X=__tsover_mul(__tsover_sub(D,__tsover_mul(O,L)),-1),Q=__tsover_sub(__tsover_mul(D,Y),__tsover_mul(O,q)),te=__tsover_mul(__tsover_sub(F,__tsover_mul(Y,U)),-1),J=__tsover_sub(k,__tsover_mul(O,U)),oe=__tsover_mul(__tsover_sub(__tsover_mul(k,Y),__tsover_mul(O,F)),-1),le=__tsover_sub(__tsover_mul(F,L),__tsover_mul(q,U)),se=__tsover_mul(__tsover_sub(__tsover_mul(k,L),__tsover_mul(D,U)),-1),Te=__tsover_sub(__tsover_mul(k,q),__tsover_mul(D,F)),de=t.x,xe=t.y,Ae=__tsover_add(__tsover_add(__tsover_mul(le,de),__tsover_mul(se,xe)),Te),De=im(__tsover_add(__tsover_add(__tsover_mul(V,de),__tsover_mul(X,xe)),Q),Ae),Ee=im(__tsover_add(__tsover_add(__tsover_mul(te,de),__tsover_mul(J,xe)),oe),Ae),ze=__tsover_add(__tsover_add(__tsover_mul(k,V),__tsover_mul(D,te)),__tsover_mul(O,le));return A(De,Ee,Et(n(0),__tsover_mul(Ae,ze)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"c0\"},{type:\"i\",name:\"c1\"},{type:\"i\",name:\"c2\"},{type:\"i\",name:\"c3\"}],body:[0,[[13,\"amt\",[6,\"d.vec2f\",[\"amount\",\"amount\"]]],[13,\"r0\",[6,\"std.mix\",[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,\"d.vec2f\",[[7,\"c0\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"c0\",\"y\"]]]],\"amt\"]]],[13,\"r1\",[6,\"std.mix\",[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]],[6,\"d.vec2f\",[[7,\"c1\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"c1\",\"y\"]]]],\"amt\"]]],[13,\"r2\",[6,\"std.mix\",[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]],[6,\"d.vec2f\",[[7,\"c2\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"c2\",\"y\"]]]],\"amt\"]]],[13,\"r3\",[6,\"std.mix\",[[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]],[6,\"d.vec2f\",[[7,\"c3\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"c3\",\"y\"]]]],\"amt\"]]],[13,\"q0\",[6,\"cornerConvexify\",[\"r0\",\"r1\",\"r3\",\"r2\"]]],[13,\"q1\",[6,\"cornerConvexify\",[\"r1\",\"r0\",\"r2\",\"r3\"]]],[13,\"q2\",[6,\"cornerConvexify\",[\"r2\",\"r1\",\"r3\",\"r0\"]]],[13,\"q3\",[6,\"cornerConvexify\",[\"r3\",\"r0\",\"r2\",\"r1\"]]],[13,\"dx1\",[1,[7,\"q1\",\"x\"],\"-\",[7,\"q2\",\"x\"]]],[13,\"dx2\",[1,[7,\"q3\",\"x\"],\"-\",[7,\"q2\",\"x\"]]],[13,\"dx3\",[1,[1,[1,[7,\"q0\",\"x\"],\"-\",[7,\"q1\",\"x\"]],\"+\",[7,\"q2\",\"x\"]],\"-\",[7,\"q3\",\"x\"]]],[13,\"dy1\",[1,[7,\"q1\",\"y\"],\"-\",[7,\"q2\",\"y\"]]],[13,\"dy2\",[1,[7,\"q3\",\"y\"],\"-\",[7,\"q2\",\"y\"]]],[13,\"dy3\",[1,[1,[1,[7,\"q0\",\"y\"],\"-\",[7,\"q1\",\"y\"]],\"+\",[7,\"q2\",\"y\"]],\"-\",[7,\"q3\",\"y\"]]],[13,\"denA\",[1,[1,\"dx1\",\"*\",\"dy2\"],\"-\",[1,\"dx2\",\"*\",\"dy1\"]]],[13,\"a13\",[6,\"cornerPinSafeDiv\",[[1,[1,\"dx3\",\"*\",\"dy2\"],\"-\",[1,\"dx2\",\"*\",\"dy3\"]],\"denA\"]]],[13,\"a23\",[6,\"cornerPinSafeDiv\",[[1,[1,\"dx1\",\"*\",\"dy3\"],\"-\",[1,\"dx3\",\"*\",\"dy1\"]],\"denA\"]]],[13,\"a11\",[1,[1,[7,\"q1\",\"x\"],\"-\",[7,\"q0\",\"x\"]],\"+\",[1,\"a13\",\"*\",[7,\"q1\",\"x\"]]]],[13,\"a21\",[1,[1,[7,\"q3\",\"x\"],\"-\",[7,\"q0\",\"x\"]],\"+\",[1,\"a23\",\"*\",[7,\"q3\",\"x\"]]]],[13,\"a31\",[7,\"q0\",\"x\"]],[13,\"a12\",[1,[1,[7,\"q1\",\"y\"],\"-\",[7,\"q0\",\"y\"]],\"+\",[1,\"a13\",\"*\",[7,\"q1\",\"y\"]]]],[13,\"a22\",[1,[1,[7,\"q3\",\"y\"],\"-\",[7,\"q0\",\"y\"]],\"+\",[1,\"a23\",\"*\",[7,\"q3\",\"y\"]]]],[13,\"a32\",[7,\"q0\",\"y\"]],[13,\"c00\",[1,\"a22\",\"-\",[1,\"a32\",\"*\",\"a23\"]]],[13,\"c10\",[1,[1,\"a21\",\"-\",[1,\"a31\",\"*\",\"a23\"]],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"c20\",[1,[1,\"a21\",\"*\",\"a32\"],\"-\",[1,\"a31\",\"*\",\"a22\"]]],[13,\"c01\",[1,[1,\"a12\",\"-\",[1,\"a32\",\"*\",\"a13\"]],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"c11\",[1,\"a11\",\"-\",[1,\"a31\",\"*\",\"a13\"]]],[13,\"c21\",[1,[1,[1,\"a11\",\"*\",\"a32\"],\"-\",[1,\"a31\",\"*\",\"a12\"]],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"c02\",[1,[1,\"a12\",\"*\",\"a23\"],\"-\",[1,\"a22\",\"*\",\"a13\"]]],[13,\"c12\",[1,[1,[1,\"a11\",\"*\",\"a23\"],\"-\",[1,\"a21\",\"*\",\"a13\"]],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"c22\",[1,[1,\"a11\",\"*\",\"a22\"],\"-\",[1,\"a21\",\"*\",\"a12\"]]],[13,\"px\",[7,\"coord\",\"x\"]],[13,\"py\",[7,\"coord\",\"y\"]],[13,\"den\",[1,[1,[1,\"c02\",\"*\",\"px\"],\"+\",[1,\"c12\",\"*\",\"py\"]],\"+\",\"c22\"]],[13,\"su\",[6,\"cornerPinSafeDiv\",[[1,[1,[1,\"c00\",\"*\",\"px\"],\"+\",[1,\"c10\",\"*\",\"py\"]],\"+\",\"c20\"],\"den\"]]],[13,\"sv\",[6,\"cornerPinSafeDiv\",[[1,[1,[1,\"c01\",\"*\",\"px\"],\"+\",[1,\"c11\",\"*\",\"py\"]],\"+\",\"c21\"],\"den\"]]],[13,\"det\",[1,[1,[1,\"a11\",\"*\",\"c00\"],\"+\",[1,\"a21\",\"*\",\"c01\"]],\"+\",[1,\"a31\",\"*\",\"c02\"]]],[13,\"front\",[6,\"std.step\",[[6,\"d.f32\",[[5,\"0\"]]],[1,\"den\",\"*\",\"det\"]]]],[10,[6,\"d.vec3f\",[\"su\",\"sv\",\"front\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.mix\":()=>K,cornerConvexify:()=>lm,cornerPinSafeDiv:()=>im,\"std.step\":()=>Et,\"d.f32\":()=>n,\"d.vec3f\":()=>A}})&&e.f)({})),Zee=w.fn([m,n,n,n,n,m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=m(t.x,__tsover_sub(1,t.y)),d=__tsover_div(__tsover_sub(l.x,c.x),a),u=__tsover_div(__tsover_sub(l.y,c.y),a),p=__tsover_mul(s,bt),_=__tsover_mul(r,bt),f=__tsover_mul(o,bt),h=pe(p),g=ae(p),y=pe(_),b=ae(_),x=__tsover_mul(hb(__tsover_mul(f,.5)),2),P=B(__tsover_add(h,__tsover_mul(__tsover_mul(g,d),x)),.001),C=__tsover_div(d,P),E=__tsover_div(__tsover_mul(u,h),P),R=B(__tsover_add(y,__tsover_mul(__tsover_mul(b,E),x)),.001),U=__tsover_div(__tsover_mul(C,y),R),L=__tsover_div(E,R),k=m(i.x,__tsover_sub(1,i.y));return m(U,L).add(c).sub(k).add(m(.5,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"pan\"},{type:\"i\",name:\"tilt\"},{type:\"i\",name:\"fov\"},{type:\"i\",name:\"zoom\"},{type:\"i\",name:\"offset\"},{type:\"i\",name:\"uv\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"x\",[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]],\"/\",\"zoom\"]],[13,\"y\",[1,[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]],\"/\",\"zoom\"]],[13,\"panRad\",[1,\"pan\",\"*\",\"DEG_TO_RAD\"]],[13,\"tiltRad\",[1,\"tilt\",\"*\",\"DEG_TO_RAD\"]],[13,\"fovRad\",[1,\"fov\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosPan\",[6,\"std.cos\",[\"panRad\"]]],[13,\"sinPan\",[6,\"std.sin\",[\"panRad\"]]],[13,\"cosTilt\",[6,\"std.cos\",[\"tiltRad\"]]],[13,\"sinTilt\",[6,\"std.sin\",[\"tiltRad\"]]],[13,\"perspectiveFactor\",[1,[6,\"std.tan\",[[1,\"fovRad\",\"*\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"panDivisor\",[1,\"cosPan\",\"+\",[1,[1,\"sinPan\",\"*\",\"x\"],\"*\",\"perspectiveFactor\"]]],[13,\"safePanDivisor\",[6,\"std.max\",[\"panDivisor\",[5,\"0.001\"]]]],[13,\"afterPanX\",[1,\"x\",\"/\",\"safePanDivisor\"]],[13,\"afterPanY\",[1,[1,\"y\",\"*\",\"cosPan\"],\"/\",\"safePanDivisor\"]],[13,\"tiltDivisor\",[1,\"cosTilt\",\"+\",[1,[1,\"sinTilt\",\"*\",\"afterPanY\"],\"*\",\"perspectiveFactor\"]]],[13,\"safeTiltDivisor\",[6,\"std.max\",[\"tiltDivisor\",[5,\"0.001\"]]]],[13,\"finalX\",[1,[1,\"afterPanX\",\"*\",\"cosTilt\"],\"/\",\"safeTiltDivisor\"]],[13,\"finalY\",[1,\"afterPanY\",\"/\",\"safeTiltDivisor\"]],[13,\"offsetPos\",[6,\"d.vec2f\",[[7,\"offset\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"offset\",\"y\"]]]]],[10,[6,[7,[6,[7,[6,[7,[6,\"d.vec2f\",[\"finalX\",\"finalY\"]],\"add\"],[\"centerPos\"]],\"sub\"],[\"offsetPos\"]],\"add\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.tan\":()=>hb,\"std.max\":()=>B}})&&e.f)({})),cS=w.fn([m,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(r.x,__tsover_sub(1,r.y)),i=__tsover_mul(__tsover_sub(t.x,a.x),s),l=__tsover_sub(t.y,a.y),c=pe(o),d=ae(o),u=__tsover_sub(__tsover_mul(i,c),__tsover_mul(l,d)),p=__tsover_add(__tsover_mul(i,d),__tsover_mul(l,c));return m(__tsover_add(__tsover_div(u,s),a.x),__tsover_add(p,a.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"angle\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]],\"*\",\"aspect\"]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"cosA\",[6,\"std.cos\",[\"angle\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angle\"]]],[13,\"rotX\",[1,[1,\"dx\",\"*\",\"cosA\"],\"-\",[1,\"dy\",\"*\",\"sinA\"]]],[13,\"rotY\",[1,[1,\"dx\",\"*\",\"sinA\"],\"+\",[1,\"dy\",\"*\",\"cosA\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"rotX\",\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,\"rotY\",\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),Jee=w.fn([m,n,n,n,n,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=m(t.x,__tsover_sub(1,t.y)),p=he(m(__tsover_mul(__tsover_sub(c.x,u.x),d),__tsover_sub(c.y,u.y))),_=__tsover_mul(p,r),f=ie(_),h=Re(_),g=__tsover_mul(s,bt),y=__tsover_mul(a,.137),b=__tsover_mul(Vl(__tsover_add(f,y)),g),x=__tsover_mul(Vl(__tsover_add(__tsover_add(f,1),y)),g),P=K(1,Vl(__tsover_add(f,42.7)),i),C=K(1,Vl(__tsover_add(__tsover_add(f,1),42.7)),i),E=__tsover_mul(__tsover_mul(l,.25),P),R=__tsover_mul(__tsover_mul(l,.25),C),U=__tsover_add(b,E),L=__tsover_add(x,R),k=__tsover_add(__tsover_sub(L,U),Wo),D=__tsover_sub(__tsover_sub(k,__tsover_mul(Jt,ie(__tsover_div(k,Jt)))),Wo),O=__tsover_add(__tsover_mul(o,.5),.001),F=be(__tsover_sub(.5,O),__tsover_add(.5,O),h);return cS(c,d,t,__tsover_add(U,__tsover_mul(D,F)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"rings\"},{type:\"i\",name:\"smoothness\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"speedRandomness\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]],\"*\",\"aspect\"]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"dist\",[6,\"std.length\",[[6,\"d.vec2f\",[\"dx\",\"dy\"]]]]],[13,\"ringCoord\",[1,\"dist\",\"*\",\"rings\"]],[13,\"ringIndex\",[6,\"std.floor\",[\"ringCoord\"]]],[13,\"ringFrac\",[6,\"std.fract\",[\"ringCoord\"]]],[13,\"maxAngle\",[1,\"intensity\",\"*\",\"DEG_TO_RAD\"]],[13,\"seedOffset\",[1,\"seed\",\"*\",[5,\"0.137\"]]],[13,\"staticA\",[1,[6,\"legacySinHash11\",[[1,\"ringIndex\",\"+\",\"seedOffset\"]]],\"*\",\"maxAngle\"]],[13,\"staticB\",[1,[6,\"legacySinHash11\",[[1,[1,\"ringIndex\",\"+\",[5,\"1\"]],\"+\",\"seedOffset\"]]],\"*\",\"maxAngle\"]],[13,\"ringSpeedA\",[6,\"std.mix\",[[5,\"1\"],[6,\"legacySinHash11\",[[1,\"ringIndex\",\"+\",[5,\"42.7\"]]]],\"speedRandomness\"]]],[13,\"ringSpeedB\",[6,\"std.mix\",[[5,\"1\"],[6,\"legacySinHash11\",[[1,[1,\"ringIndex\",\"+\",[5,\"1\"]],\"+\",[5,\"42.7\"]]]],\"speedRandomness\"]]],[13,\"animA\",[1,[1,\"animTime\",\"*\",[5,\"0.25\"]],\"*\",\"ringSpeedA\"]],[13,\"animB\",[1,[1,\"animTime\",\"*\",[5,\"0.25\"]],\"*\",\"ringSpeedB\"]],[13,\"totalA\",[1,\"staticA\",\"+\",\"animA\"]],[13,\"totalB\",[1,\"staticB\",\"+\",\"animB\"]],[13,\"wrapArg\",[1,[1,\"totalB\",\"-\",\"totalA\"],\"+\",\"PI\"]],[13,\"diff\",[1,[1,\"wrapArg\",\"-\",[1,\"TAU\",\"*\",[6,\"std.floor\",[[1,\"wrapArg\",\"/\",\"TAU\"]]]]],\"-\",\"PI\"]],[13,\"halfEdge\",[1,[1,\"smoothness\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.001\"]]],[13,\"blend\",[6,\"std.smoothstep\",[[1,[5,\"0.5\"],\"-\",\"halfEdge\"],[1,[5,\"0.5\"],\"+\",\"halfEdge\"],\"ringFrac\"]]],[13,\"angle\",[1,\"totalA\",\"+\",[1,\"diff\",\"*\",\"blend\"]]],[10,[6,\"csRotateUV\",[\"uv\",\"aspect\",\"center\",\"angle\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.floor\":()=>ie,\"std.fract\":()=>Re,DEG_TO_RAD:()=>bt,legacySinHash11:()=>Vl,\"std.mix\":()=>K,PI:()=>Wo,TAU:()=>Jt,\"std.smoothstep\":()=>be,csRotateUV:()=>cS}})&&e.f)({})),ete=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(__tsover_mul(t.x,s),t.y),c=__tsover_mul(a,.7),d=__tsover_mul(i,.2),u=__tsover_mul(Na(A(__tsover_add(__tsover_mul(l.x,r),__tsover_mul(c,.3)),__tsover_add(__tsover_mul(l.y,r),__tsover_mul(c,.5)),d)),Po),p=m(pe(u),ae(u)),_=__tsover_mul(a,.5),f=__tsover_mul(i,.15),h=__tsover_mul(Na(A(__tsover_add(__tsover_add(__tsover_mul(l.x,__tsover_mul(r,2.3)),__tsover_mul(_,-.4)),173.5),__tsover_add(__tsover_add(__tsover_mul(l.y,__tsover_mul(r,2.3)),__tsover_mul(_,.3)),291.7),__tsover_add(f,50))),Po),g=m(pe(h),ae(h)),y=__tsover_mul(a,.3),b=__tsover_mul(i,.1),x=__tsover_mul(Na(A(__tsover_add(__tsover_add(__tsover_mul(l.x,__tsover_mul(r,4.7)),__tsover_mul(y,.2)),527.3),__tsover_add(__tsover_add(__tsover_mul(l.y,__tsover_mul(r,4.7)),__tsover_mul(y,-.6)),839.1),__tsover_add(b,100))),Po),P=m(pe(x),ae(x)),C=p.add(g.mul(.5)).add(P.mul(.25)),E=B(he(C),.001),R=C.div(E),U=m(__tsover_div(__tsover_mul(R.x,o),s),__tsover_mul(R.y,o));return m(__tsover_add(t.x,U.x),__tsover_add(t.y,U.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"evolutionTime\"}],body:[0,[[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"drift1\",[1,\"time\",\"*\",[5,\"0.7\"]]],[13,\"evolve1\",[1,\"evolutionTime\",\"*\",[5,\"0.2\"]]],[13,\"angle1\",[1,[6,\"mxNoiseFloat3\",[[6,\"d.vec3f\",[[1,[1,[7,\"aspectCorrectedUV\",\"x\"],\"*\",\"scale\"],\"+\",[1,\"drift1\",\"*\",[5,\"0.3\"]]],[1,[1,[7,\"aspectCorrectedUV\",\"y\"],\"*\",\"scale\"],\"+\",[1,\"drift1\",\"*\",[5,\"0.5\"]]],\"evolve1\"]]]],\"*\",\"TWO_PI\"]],[13,\"flow1\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angle1\"]],[6,\"std.sin\",[\"angle1\"]]]]],[13,\"drift2\",[1,\"time\",\"*\",[5,\"0.5\"]]],[13,\"evolve2\",[1,\"evolutionTime\",\"*\",[5,\"0.15\"]]],[13,\"angle2\",[1,[6,\"mxNoiseFloat3\",[[6,\"d.vec3f\",[[1,[1,[1,[7,\"aspectCorrectedUV\",\"x\"],\"*\",[1,\"scale\",\"*\",[5,\"2.3\"]]],\"+\",[1,\"drift2\",\"*\",[4,\"-\",[5,\"0.4\"]]]],\"+\",[5,\"173.5\"]],[1,[1,[1,[7,\"aspectCorrectedUV\",\"y\"],\"*\",[1,\"scale\",\"*\",[5,\"2.3\"]]],\"+\",[1,\"drift2\",\"*\",[5,\"0.3\"]]],\"+\",[5,\"291.7\"]],[1,\"evolve2\",\"+\",[5,\"50\"]]]]]],\"*\",\"TWO_PI\"]],[13,\"flow2\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angle2\"]],[6,\"std.sin\",[\"angle2\"]]]]],[13,\"drift3\",[1,\"time\",\"*\",[5,\"0.3\"]]],[13,\"evolve3\",[1,\"evolutionTime\",\"*\",[5,\"0.1\"]]],[13,\"angle3\",[1,[6,\"mxNoiseFloat3\",[[6,\"d.vec3f\",[[1,[1,[1,[7,\"aspectCorrectedUV\",\"x\"],\"*\",[1,\"scale\",\"*\",[5,\"4.7\"]]],\"+\",[1,\"drift3\",\"*\",[5,\"0.2\"]]],\"+\",[5,\"527.3\"]],[1,[1,[1,[7,\"aspectCorrectedUV\",\"y\"],\"*\",[1,\"scale\",\"*\",[5,\"4.7\"]]],\"+\",[1,\"drift3\",\"*\",[4,\"-\",[5,\"0.6\"]]]],\"+\",[5,\"839.1\"]],[1,\"evolve3\",\"+\",[5,\"100\"]]]]]],\"*\",\"TWO_PI\"]],[13,\"flow3\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"angle3\"]],[6,\"std.sin\",[\"angle3\"]]]]],[13,\"combinedFlow\",[6,[7,[6,[7,\"flow1\",\"add\"],[[6,[7,\"flow2\",\"mul\"],[[5,\"0.5\"]]]]],\"add\"],[[6,[7,\"flow3\",\"mul\"],[[5,\"0.25\"]]]]]],[13,\"flowLength\",[6,\"std.max\",[[6,\"std.length\",[\"combinedFlow\"]],[5,\"0.001\"]]]],[13,\"normalizedFlow\",[6,[7,\"combinedFlow\",\"div\"],[\"flowLength\"]]],[13,\"finalFlow\",[6,\"d.vec2f\",[[1,[1,[7,\"normalizedFlow\",\"x\"],\"*\",\"strength\"],\"/\",\"aspect\"],[1,[7,\"normalizedFlow\",\"y\"],\"*\",\"strength\"]]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[7,\"finalFlow\",\"x\"]],[1,[7,\"uv\",\"y\"],\"+\",[7,\"finalFlow\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m,mxNoiseFloat3:()=>Na,\"d.vec3f\":()=>A,TWO_PI:()=>Po,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.max\":()=>B,\"std.length\":()=>he}})&&e.f)({})),tte=w.fn([m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,bt),l=m(pe(i),ae(i)),c=m(__tsover_mul(__tsover_sub(t.x,.5),s),__tsover_sub(t.y,.5)),d=Se(c,l),u=__tsover_mul(.5,__tsover_add(__tsover_mul(s,re(l.x)),re(l.y))),p=__tsover_add(__tsover_div(d,__tsover_mul(2,u)),.5),_=ie(__tsover_mul(p,B(o,1))),f=__tsover_sub(__tsover_mul(Re(__tsover_mul(_,.5)),4),1),h=m(-l.y,l.x),g=__tsover_mul(.5,__tsover_add(__tsover_mul(s,re(l.y)),re(l.x))),y=__tsover_mul(__tsover_mul(a,__tsover_mul(2.02,g)),f),b=c.add(h.mul(y));return m(__tsover_add(__tsover_div(b.x,s),.5),__tsover_add(b.y,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"sliceCount\"},{type:\"i\",name:\"progress\"}],body:[0,[[13,\"a\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"dir\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"a\"]],[6,\"std.sin\",[\"a\"]]]]],[13,\"p\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]],[13,\"grad\",[6,\"std.dot\",[\"p\",\"dir\"]]],[13,\"ext\",[1,[5,\"0.5\"],\"*\",[1,[1,\"aspect\",\"*\",[6,\"std.abs\",[[7,\"dir\",\"x\"]]]],\"+\",[6,\"std.abs\",[[7,\"dir\",\"y\"]]]]]],[13,\"t\",[1,[1,\"grad\",\"/\",[1,[5,\"2\"],\"*\",\"ext\"]],\"+\",[5,\"0.5\"]]],[13,\"idx\",[6,\"std.floor\",[[1,\"t\",\"*\",[6,\"std.max\",[\"sliceCount\",[5,\"1\"]]]]]]],[13,\"sign\",[1,[1,[6,\"std.fract\",[[1,\"idx\",\"*\",[5,\"0.5\"]]]],\"*\",[5,\"4\"]],\"-\",[5,\"1\"]]],[13,\"perp\",[6,\"d.vec2f\",[[4,\"-\",[7,\"dir\",\"y\"]],[7,\"dir\",\"x\"]]]],[13,\"extPerp\",[1,[5,\"0.5\"],\"*\",[1,[1,\"aspect\",\"*\",[6,\"std.abs\",[[7,\"dir\",\"y\"]]]],\"+\",[6,\"std.abs\",[[7,\"dir\",\"x\"]]]]]],[13,\"slide\",[1,[1,\"progress\",\"*\",[1,[5,\"2.02\"],\"*\",\"extPerp\"]],\"*\",\"sign\"]],[13,\"q\",[6,[7,\"p\",\"add\"],[[6,[7,\"perp\",\"mul\"],[\"slide\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,[7,\"q\",\"x\"],\"/\",\"aspect\"],\"+\",[5,\"0.5\"]],[1,[7,\"q\",\"y\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.abs\":()=>re,\"std.floor\":()=>ie,\"std.max\":()=>B,\"std.fract\":()=>Re}})&&e.f)({})),dS=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(r,bt),i=pe(a),l=ae(a),c=__tsover_mul(t.x,s),d=t.y,u=__tsover_sub(c,__tsover_mul(s,.5)),p=__tsover_sub(d,.5),_=__tsover_add(__tsover_mul(u,i),__tsover_mul(p,l)),f=__tsover_add(__tsover_mul(__tsover_mul(u,l),-1),__tsover_mul(p,i)),h=__tsover_add(f,o),g=__tsover_sub(__tsover_mul(_,i),__tsover_mul(h,l)),y=__tsover_add(__tsover_mul(_,l),__tsover_mul(h,i));return m(__tsover_add(__tsover_div(g,s),.5),__tsover_add(y,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"offset\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"au\",[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"]],[13,\"av\",[7,\"uv\",\"y\"]],[13,\"cu\",[1,\"au\",\"-\",[1,\"aspect\",\"*\",[5,\"0.5\"]]]],[13,\"cv\",[1,\"av\",\"-\",[5,\"0.5\"]]],[13,\"projectedU\",[1,[1,\"cu\",\"*\",\"cosA\"],\"+\",[1,\"cv\",\"*\",\"sinA\"]]],[13,\"projectedV\",[1,[1,[1,\"cu\",\"*\",\"sinA\"],\"*\",[4,\"-\",[5,\"1\"]]],\"+\",[1,\"cv\",\"*\",\"cosA\"]]],[13,\"distPV\",[1,\"projectedV\",\"+\",\"offset\"]],[13,\"dcu\",[1,[1,\"projectedU\",\"*\",\"cosA\"],\"-\",[1,\"distPV\",\"*\",\"sinA\"]]],[13,\"dcv\",[1,[1,\"projectedU\",\"*\",\"sinA\"],\"+\",[1,\"distPV\",\"*\",\"cosA\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"dcu\",\"/\",\"aspect\"],\"+\",[5,\"0.5\"]],[1,\"dcv\",\"+\",[5,\"0.5\"]]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),ste=w.fn([n,n,n,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_mul(s,bt),d=pe(c),u=ae(c),p=B(l,1),_=__tsover_mul(i.x,l),f=i.y,h=__tsover_sub(_,__tsover_mul(l,.5)),g=__tsover_sub(f,.5),y=__tsover_add(__tsover_mul(h,d),__tsover_mul(g,u)),b=ie(__tsover_div(__tsover_mul(y,t),p)),x=__tsover_mul(o,.137),P=Vl(__tsover_add(b,x)),C=Vl(__tsover_add(__tsover_add(b,x),42.7)),E=__tsover_mul(__tsover_mul(a,C),.2);return dS(i,l,s,__tsover_mul(__tsover_add(P,E),r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"count\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"longestAxis\",[6,\"std.max\",[\"aspect\",[5,\"1\"]]]],[13,\"au\",[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"]],[13,\"av\",[7,\"uv\",\"y\"]],[13,\"cu\",[1,\"au\",\"-\",[1,\"aspect\",\"*\",[5,\"0.5\"]]]],[13,\"cv\",[1,\"av\",\"-\",[5,\"0.5\"]]],[13,\"projectedU\",[1,[1,\"cu\",\"*\",\"cosA\"],\"+\",[1,\"cv\",\"*\",\"sinA\"]]],[13,\"barCoord\",[1,[1,\"projectedU\",\"*\",\"count\"],\"/\",\"longestAxis\"]],[13,\"barIndex\",[6,\"std.floor\",[\"barCoord\"]]],[13,\"seedOffset\",[1,\"seed\",\"*\",[5,\"0.137\"]]],[13,\"staticOffset\",[6,\"legacySinHash11\",[[1,\"barIndex\",\"+\",\"seedOffset\"]]]],[13,\"barSpeed\",[6,\"legacySinHash11\",[[1,[1,\"barIndex\",\"+\",\"seedOffset\"],\"+\",[5,\"42.7\"]]]]],[13,\"animOffset\",[1,[1,\"animTime\",\"*\",\"barSpeed\"],\"*\",[5,\"0.2\"]]],[13,\"offset\",[1,[1,\"staticOffset\",\"+\",\"animOffset\"],\"*\",\"intensity\"]],[10,[6,\"barSampleUV\",[\"uv\",\"aspect\",\"angle\",\"offset\"]]]]]},externals:{DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.max\":()=>B,\"std.floor\":()=>ie,legacySinHash11:()=>Vl,barSampleUV:()=>dS}})&&e.f)({})),rte=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=r>1,a=B(N(__tsover_mul(s,r),s,o),1),i=B(N(s,__tsover_div(s,r),o),1),l=ie(__tsover_mul(t.x,a)),c=ie(__tsover_mul(t.y,i));return m(__tsover_div(__tsover_add(l,.5),a),__tsover_div(__tsover_add(c,.5),i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"gridSize\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"isWide\",[1,\"aspect\",\">\",[5,\"1\"]]],[13,\"cellsX\",[6,\"std.max\",[[6,\"std.select\",[[1,\"gridSize\",\"*\",\"aspect\"],\"gridSize\",\"isWide\"]],[5,\"1\"]]]],[13,\"cellsY\",[6,\"std.max\",[[6,\"std.select\",[\"gridSize\",[1,\"gridSize\",\"/\",\"aspect\"],\"isWide\"]],[5,\"1\"]]]],[13,\"cellIndexX\",[6,\"std.floor\",[[1,[7,\"uv\",\"x\"],\"*\",\"cellsX\"]]]],[13,\"cellIndexY\",[6,\"std.floor\",[[1,[7,\"uv\",\"y\"],\"*\",\"cellsY\"]]]],[10,[6,\"d.vec2f\",[[1,[1,\"cellIndexX\",\"+\",[5,\"0.5\"]],\"/\",\"cellsX\"],[1,[1,\"cellIndexY\",\"+\",[5,\"0.5\"]],\"/\",\"cellsY\"]]]]]]},externals:{\"std.max\":()=>B,\"std.select\":()=>N,\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),ote=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let o=G(s,m(-.1,-.1),m(.1,.1));return t.sub(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"disp\"}],body:[0,[[13,\"maxDisp\",[5,\"0.1\"]],[13,\"clamped\",[6,\"std.clamp\",[\"disp\",[6,\"d.vec2f\",[[4,\"-\",\"maxDisp\"],[4,\"-\",\"maxDisp\"]]],[6,\"d.vec2f\",[\"maxDisp\",\"maxDisp\"]]]]],[10,[6,[7,\"uv\",\"sub\"],[\"clamped\"]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m}})&&e.f)({})),ate=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=s.mul(__tsover_mul(r,.1)),a=.15,i=G(o,m(-a,-a),m(a,a));return t.sub(i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"disp\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"scaled\",[6,[7,\"disp\",\"mul\"],[[1,\"intensity\",\"*\",[5,\"0.1\"]]]]],[13,\"maxDisp\",[5,\"0.15\"]],[13,\"clamped\",[6,\"std.clamp\",[\"scaled\",[6,\"d.vec2f\",[[4,\"-\",\"maxDisp\"],[4,\"-\",\"maxDisp\"]]],[6,\"d.vec2f\",[\"maxDisp\",\"maxDisp\"]]]]],[10,[6,[7,\"uv\",\"sub\"],[\"clamped\"]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m}})&&e.f)({})),nte=w.fn([m,S,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=B(s.w,1e-4),i=__tsover_div(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_sub(__tsover_div(s.x,a),.5),2),s.w),o),r),l=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_sub(__tsover_div(s.y,a),.5),2),s.w),o);return m(__tsover_add(t.x,i),__tsover_add(t.y,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"src\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"a\",[6,\"std.max\",[[7,\"src\",\"w\"],[5,\"0.0001\"]]]],[13,\"dx\",[1,[1,[1,[1,[1,[1,[7,\"src\",\"x\"],\"/\",\"a\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[7,\"src\",\"w\"]],\"*\",\"amount\"],\"/\",\"aspect\"]],[13,\"dy\",[1,[1,[1,[1,[1,[7,\"src\",\"y\"],\"/\",\"a\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[7,\"src\",\"w\"]],\"*\",\"amount\"]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",\"dx\"],[1,[7,\"uv\",\"y\"],\"+\",\"dy\"]]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),ite=w.fn([m,S,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=B(s.w,1e-4),l=Se(A(__tsover_div(s.x,i),__tsover_div(s.y,i),__tsover_div(s.z,i)),A(.2126,.7152,.0722)),c=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_sub(l,.5),2),s.w),o),d=__tsover_mul(a,bt),u=__tsover_div(__tsover_mul(c,pe(d)),r),p=__tsover_mul(c,ae(d));return m(__tsover_add(t.x,u),__tsover_add(t.y,p))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"src\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"angleDeg\"}],body:[0,[[13,\"a\",[6,\"std.max\",[[7,\"src\",\"w\"],[5,\"0.0001\"]]]],[13,\"lum\",[6,\"std.dot\",[[6,\"d.vec3f\",[[1,[7,\"src\",\"x\"],\"/\",\"a\"],[1,[7,\"src\",\"y\"],\"/\",\"a\"],[1,[7,\"src\",\"z\"],\"/\",\"a\"]]],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"scalar\",[1,[1,[1,[1,\"lum\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[7,\"src\",\"w\"]],\"*\",\"amount\"]],[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"dx\",[1,[1,\"scalar\",\"*\",[6,\"std.cos\",[\"angleRad\"]]],\"/\",\"aspect\"]],[13,\"dy\",[1,\"scalar\",\"*\",[6,\"std.sin\",[\"angleRad\"]]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",\"dx\"],[1,[7,\"uv\",\"y\"],\"+\",\"dy\"]]]]]]},externals:{\"std.max\":()=>B,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),g0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({refractedUV:m,chrOff:m,slope:n}),\"FlutedGeom\"),lte=w.fn([m,n,n,n,n,n,n,n,n,n,A],g0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=p.x,f=p.y,h=p.z,g=__tsover_div(__tsover_mul(o,Wo),180),y=pe(g),b=ae(g),x=m(__tsover_mul(__tsover_sub(t.x,.5),s),__tsover_sub(t.y,.5)),P=__tsover_add(__tsover_mul(x.x,y),__tsover_mul(x.y,b)),C=__tsover_add(__tsover_mul(-x.x,b),__tsover_mul(x.y,y)),E=__tsover_mul(ae(__tsover_add(__tsover_mul(__tsover_mul(C,c),__tsover_mul(Wo,2)),__tsover_mul(r,2))),l),R=__tsover_add(P,__tsover_mul(h,E)),U=__tsover_add(__tsover_mul(R,a),r),L=__tsover_mul(__tsover_sub(Re(U),.5),2),k=B(re(L),1e-4),D=K(_,f,i),O=__tsover_mul(no(L),vt(k,D)),F=__tsover_div(.5,B(a,.001)),q=-__tsover_mul(__tsover_mul(O,d),F),Y=m(__tsover_add(t.x,__tsover_div(__tsover_mul(q,y),s)),__tsover_add(t.y,__tsover_mul(q,b))),V=__tsover_mul(__tsover_mul(q,u),.5);return g0({refractedUV:Y,chrOff:m(__tsover_div(__tsover_mul(V,y),s),__tsover_mul(V,b)),slope:O})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"waveAmp\"},{type:\"i\",name:\"waveFreq\"},{type:\"i\",name:\"refraction\"},{type:\"i\",name:\"aberration\"},{type:\"i\",name:\"shapeParams\"}],body:[0,[[13,\"expHi\",[7,\"shapeParams\",\"x\"]],[13,\"expLo\",[7,\"shapeParams\",\"y\"]],[13,\"wavesFlag\",[7,\"shapeParams\",\"z\"]],[13,\"r\",[1,[1,\"angleDeg\",\"*\",\"PI\"],\"/\",[5,\"180\"]]],[13,\"cosA\",[6,\"std.cos\",[\"r\"]]],[13,\"sinA\",[6,\"std.sin\",[\"r\"]]],[13,\"aspCorr\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]],[13,\"u\",[1,[1,[7,\"aspCorr\",\"x\"],\"*\",\"cosA\"],\"+\",[1,[7,\"aspCorr\",\"y\"],\"*\",\"sinA\"]]],[13,\"v\",[1,[1,[4,\"-\",[7,\"aspCorr\",\"x\"]],\"*\",\"sinA\"],\"+\",[1,[7,\"aspCorr\",\"y\"],\"*\",\"cosA\"]]],[13,\"waveTerm\",[1,[6,\"std.sin\",[[1,[1,[1,\"v\",\"*\",\"waveFreq\"],\"*\",[1,\"PI\",\"*\",[5,\"2\"]]],\"+\",[1,\"t\",\"*\",[5,\"2\"]]]]],\"*\",\"waveAmp\"]],[13,\"fluteU\",[1,\"u\",\"+\",[1,\"wavesFlag\",\"*\",\"waveTerm\"]]],[13,\"flutePos\",[1,[1,\"fluteU\",\"*\",\"frequency\"],\"+\",\"t\"]],[13,\"cellPos\",[1,[1,[6,\"std.fract\",[\"flutePos\"]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"absCell\",[6,\"std.max\",[[6,\"std.abs\",[\"cellPos\"]],[5,\"0.0001\"]]]],[13,\"exponent\",[6,\"std.mix\",[\"expHi\",\"expLo\",\"softness\"]]],[13,\"slope\",[1,[6,\"std.sign\",[\"cellPos\"]],\"*\",[6,\"std.pow\",[\"absCell\",\"exponent\"]]]],[13,\"halfCell\",[1,[5,\"0.5\"],\"/\",[6,\"std.max\",[\"frequency\",[5,\"0.001\"]]]]],[13,\"refrU\",[4,\"-\",[1,[1,\"slope\",\"*\",\"refraction\"],\"*\",\"halfCell\"]]],[13,\"refractedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,[1,\"refrU\",\"*\",\"cosA\"],\"/\",\"aspect\"]],[1,[7,\"uv\",\"y\"],\"+\",[1,\"refrU\",\"*\",\"sinA\"]]]]],[13,\"chrU\",[1,[1,\"refrU\",\"*\",\"aberration\"],\"*\",[5,\"0.5\"]]],[13,\"chrOff\",[6,\"d.vec2f\",[[1,[1,\"chrU\",\"*\",\"cosA\"],\"/\",\"aspect\"],[1,\"chrU\",\"*\",\"sinA\"]]]],[10,[6,\"FlutedGeom\",[[104,{refractedUV:\"refractedUV\",chrOff:\"chrOff\",slope:\"slope\"}]]]]]]},externals:{PI:()=>Wo,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.mix\":()=>K,\"std.sign\":()=>no,\"std.pow\":()=>vt,FlutedGeom:()=>g0}})&&e.f)({})),cte=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=ye(__tsover_mul(t,t),1),i=Ue(__tsover_sub(1,a)),l=__tsover_div(__tsover_mul(s,Wo),360),c=ae(l),d=pe(l),u=B(__tsover_add(__tsover_mul(t,c),__tsover_mul(i,d)),0),p=Ia(__tsover_sub(8,__tsover_mul(o,7))),_=vt(__tsover_sub(1,i),5),f=__tsover_add(.04,__tsover_mul(.96,_));return __tsover_mul(__tsover_mul(vt(u,p),f),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"slope\"},{type:\"i\",name:\"lightAngleDeg\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"slopeSq\",[6,\"std.min\",[[1,\"slope\",\"*\",\"slope\"],[5,\"1\"]]]],[13,\"nz\",[6,\"std.sqrt\",[[1,[5,\"1\"],\"-\",\"slopeSq\"]]]],[13,\"half\",[1,[1,\"lightAngleDeg\",\"*\",\"PI\"],\"/\",[5,\"360\"]]],[13,\"hx\",[6,\"std.sin\",[\"half\"]]],[13,\"hy\",[6,\"std.cos\",[\"half\"]]],[13,\"nDotH\",[6,\"std.max\",[[1,[1,\"slope\",\"*\",\"hx\"],\"+\",[1,\"nz\",\"*\",\"hy\"]],[5,\"0\"]]]],[13,\"shininess\",[6,\"std.exp2\",[[1,[5,\"8\"],\"-\",[1,\"softness\",\"*\",[5,\"7\"]]]]]],[13,\"fresnel\",[6,\"std.pow\",[[1,[5,\"1\"],\"-\",\"nz\"],[5,\"5\"]]]],[13,\"fresnelMix\",[1,[5,\"0.04\"],\"+\",[1,[5,\"0.96\"],\"*\",\"fresnel\"]]],[10,[1,[1,[6,\"std.pow\",[\"nDotH\",\"shininess\"]],\"*\",\"fresnelMix\"],\"*\",\"intensity\"]]]]},externals:{\"std.min\":()=>ye,\"std.sqrt\":()=>Ue,PI:()=>Wo,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.max\":()=>B,\"std.exp2\":()=>Ia,\"std.pow\":()=>vt}})&&e.f)({})),y0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({curlUV:m,theta:n,distPastCrease:n,distIntoPeel:n,flatReach:n,peelReach:n,foldBlend:n,showCurl:n}),\"PagePeelGeom\"),dte=w.fn([m,n,n,n,n,n,n,n],y0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=m(__tsover_mul(t.x,s),t.y),u=m(__tsover_mul(r,s),o),p=m(__tsover_mul(a,s),i).sub(u),_=he(p),f=p.mul(__tsover_div(1,_)),h=Se(d.sub(u),f),g=__tsover_mul(l,_),y=g,b=B(__tsover_mul(c,_),1e-4),x=__tsover_div(g,b),P=__tsover_div(__tsover_sub(h,y),b),C=fb(G(P,0,1)),E=__tsover_mul(Et(0,P),Et(P,1)),R=Et(C,x),U=__tsover_sub(g,__tsover_mul(b,C)),L=d.add(f.mul(__tsover_sub(U,h))),k=m(__tsover_div(L.x,s),L.y),D=__tsover_mul(__tsover_mul(__tsover_mul(Et(0,k.x),Et(k.x,1)),Et(0,k.y)),Et(k.y,1)),O=__tsover_sub(1,pe(G(x,0,ev))),F=__tsover_mul(b,O),q=B(__tsover_add(b,__tsover_mul(F,.5)),1e-4),Y=__tsover_sub(h,y),V=B(__tsover_mul(F,2.5),1e-4);return y0({curlUV:k,theta:C,distPastCrease:Y,distIntoPeel:__tsover_sub(y,h),flatReach:q,peelReach:V,foldBlend:be(__tsover_sub(y,.0015),__tsover_add(y,.0015),h),showCurl:__tsover_mul(__tsover_mul(E,R),D)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"cornerX\"},{type:\"i\",name:\"cornerY\"},{type:\"i\",name:\"oppX\"},{type:\"i\",name:\"oppY\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"radius\"}],body:[0,[[13,\"pA\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"cornerA\",[6,\"d.vec2f\",[[1,\"cornerX\",\"*\",\"aspect\"],\"cornerY\"]]],[13,\"oppA\",[6,\"d.vec2f\",[[1,\"oppX\",\"*\",\"aspect\"],\"oppY\"]]],[13,\"axisVec\",[6,[7,\"oppA\",\"sub\"],[\"cornerA\"]]],[13,\"L\",[6,\"std.length\",[\"axisVec\"]]],[13,\"axis\",[6,[7,\"axisVec\",\"mul\"],[[1,[5,\"1\"],\"/\",\"L\"]]]],[13,\"t\",[6,\"std.dot\",[[6,[7,\"pA\",\"sub\"],[\"cornerA\"]],\"axis\"]]],[13,\"peel\",[1,\"amount\",\"*\",\"L\"]],[13,\"cFold\",\"peel\"],[13,\"R\",[6,\"std.max\",[[1,\"radius\",\"*\",\"L\"],[5,\"0.0001\"]]]],[13,\"thetaMax\",[1,\"peel\",\"/\",\"R\"]],[13,\"X\",[1,[1,\"t\",\"-\",\"cFold\"],\"/\",\"R\"]],[13,\"Xc\",[6,\"std.clamp\",[\"X\",[5,\"0\"],[5,\"1\"]]]],[13,\"theta\",[6,\"std.asin\",[\"Xc\"]]],[13,\"inBand\",[1,[6,\"std.step\",[[5,\"0\"],\"X\"]],\"*\",[6,\"std.step\",[\"X\",[5,\"1\"]]]]],[13,\"paper\",[6,\"std.step\",[\"theta\",\"thetaMax\"]]],[13,\"cCurl\",[1,\"peel\",\"-\",[1,\"R\",\"*\",\"theta\"]]],[13,\"sourceA\",[6,[7,\"pA\",\"add\"],[[6,[7,\"axis\",\"mul\"],[[1,\"cCurl\",\"-\",\"t\"]]]]]],[13,\"curlUV\",[6,\"d.vec2f\",[[1,[7,\"sourceA\",\"x\"],\"/\",\"aspect\"],[7,\"sourceA\",\"y\"]]]],[13,\"curlInBounds\",[1,[1,[1,[6,\"std.step\",[[5,\"0\"],[7,\"curlUV\",\"x\"]]],\"*\",[6,\"std.step\",[[7,\"curlUV\",\"x\"],[5,\"1\"]]]],\"*\",[6,\"std.step\",[[5,\"0\"],[7,\"curlUV\",\"y\"]]]],\"*\",[6,\"std.step\",[[7,\"curlUV\",\"y\"],[5,\"1\"]]]]],[13,\"liftFrac\",[1,[5,\"1\"],\"-\",[6,\"std.cos\",[[6,\"std.clamp\",[\"thetaMax\",[5,\"0\"],\"HALF_PI\"]]]]]],[13,\"lipHeight\",[1,\"R\",\"*\",\"liftFrac\"]],[13,\"flatReach\",[6,\"std.max\",[[1,\"R\",\"+\",[1,\"lipHeight\",\"*\",[5,\"0.5\"]]],[5,\"0.0001\"]]]],[13,\"distPastCrease\",[1,\"t\",\"-\",\"cFold\"]],[13,\"peelReach\",[6,\"std.max\",[[1,\"lipHeight\",\"*\",[5,\"2.5\"]],[5,\"0.0001\"]]]],[13,\"distIntoPeel\",[1,\"cFold\",\"-\",\"t\"]],[13,\"foldBlend\",[6,\"std.smoothstep\",[[1,\"cFold\",\"-\",[5,\"0.0015\"]],[1,\"cFold\",\"+\",[5,\"0.0015\"]],\"t\"]]],[13,\"showCurl\",[1,[1,\"inBand\",\"*\",\"paper\"],\"*\",\"curlInBounds\"]],[10,[6,\"PagePeelGeom\",[[104,{curlUV:\"curlUV\",theta:\"theta\",distPastCrease:\"distPastCrease\",distIntoPeel:\"distIntoPeel\",flatReach:\"flatReach\",peelReach:\"peelReach\",foldBlend:\"foldBlend\",showCurl:\"showCurl\"}]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.dot\":()=>Se,\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.asin\":()=>fb,\"std.step\":()=>Et,\"std.cos\":()=>pe,HALF_PI:()=>ev,\"std.smoothstep\":()=>be,PagePeelGeom:()=>y0}})&&e.f)({})),ute=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=pe(t);return __tsover_sub(1,__tsover_mul(s,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"theta\"},{type:\"i\",name:\"shading\"}],body:[0,[[13,\"facing\",[6,\"std.cos\",[\"theta\"]]],[10,[1,[5,\"1\"],\"-\",[1,\"shading\",\"*\",\"facing\"]]]]]},externals:{\"std.cos\":()=>pe}})&&e.f)({})),pte=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(t,ev),a=K(.05,.4,r),i=__tsover_div(__tsover_sub(o,.65),a);return __tsover_mul(Tt(__tsover_mul(__tsover_mul(i,i),-.5)),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"theta\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"thetaN\",[1,\"theta\",\"/\",\"HALF_PI\"]],[13,\"specSigma\",[6,\"std.mix\",[[5,\"0.05\"],[5,\"0.4\"],\"softness\"]]],[13,\"specDelta\",[1,[1,\"thetaN\",\"-\",[5,\"0.65\"]],\"/\",\"specSigma\"]],[10,[1,[6,\"std.exp\",[[1,[1,\"specDelta\",\"*\",\"specDelta\"],\"*\",[4,\"-\",[5,\"0.5\"]]]]],\"*\",\"intensity\"]]]]},externals:{HALF_PI:()=>ev,\"std.mix\":()=>K,\"std.exp\":()=>Tt}})&&e.f)({})),yv=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(be(0,.04,t),vt(__tsover_sub(1,t),.7))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"amount\"}],body:[0,[[10,[1,[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.04\"],\"amount\"]],\"*\",[6,\"std.pow\",[[1,[5,\"1\"],\"-\",\"amount\"],[5,\"0.7\"]]]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.pow\":()=>vt}})&&e.f)({})),bv=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_mul(vt(__tsover_sub(1,be(0,s,t)),r),Et(0,t))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"reach\"},{type:\"i\",name:\"exponent\"}],body:[0,[[10,[1,[6,\"std.pow\",[[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],\"reach\",\"dist\"]]],\"exponent\"]],\"*\",[6,\"std.step\",[[5,\"0\"],\"dist\"]]]]]]},externals:{\"std.pow\":()=>vt,\"std.smoothstep\":()=>be,\"std.step\":()=>Et}})&&e.f)({})),mte=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(bv(t,s,2),yv(r));return __tsover_sub(1,__tsover_mul(__tsover_mul(o,a),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"reach\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"shadow\"}],body:[0,[[13,\"fall\",[1,[6,\"shadowFalloff\",[\"dist\",\"reach\",[5,\"2\"]]],\"*\",[6,\"liftShadowStrength\",[\"amount\"]]]],[10,[1,[5,\"1\"],\"-\",[1,[1,\"shadow\",\"*\",\"fall\"],\"*\",[5,\"0.5\"]]]]]]},externals:{shadowFalloff:()=>bv,liftShadowStrength:()=>yv}})&&e.f)({})),_te=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(__tsover_mul(bv(t,s,1.5),yv(r)),o);return __tsover_mul(a,.6)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"reach\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"shadow\"}],body:[0,[[13,\"fall\",[1,[1,[6,\"shadowFalloff\",[\"dist\",\"reach\",[5,\"1.5\"]]],\"*\",[6,\"liftShadowStrength\",[\"amount\"]]],\"*\",\"shadow\"]],[10,[1,\"fall\",\"*\",[5,\"0.6\"]]]]]},externals:{shadowFalloff:()=>bv,liftShadowStrength:()=>yv}})&&e.f)({})),fte=w.fn([S,S,n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=S(t.xyz.mul(r).add(__tsover_mul(o,t.w)),t.w),u=S(s.xyz.mul(a),s.w);return N(K(S(0,0,0,i),u,S(l)),d,c>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"curlSample\"},{type:\"i\",name:\"flatSample\"},{type:\"i\",name:\"curlBright\"},{type:\"i\",name:\"spec\"},{type:\"i\",name:\"flatShade\"},{type:\"i\",name:\"peelAlpha\"},{type:\"i\",name:\"foldBlend\"},{type:\"i\",name:\"showCurl\"}],body:[0,[[13,\"litRgb\",[6,[7,[6,[7,[7,\"curlSample\",\"xyz\"],\"mul\"],[\"curlBright\"]],\"add\"],[[1,\"spec\",\"*\",[7,\"curlSample\",\"w\"]]]]],[13,\"curlColor\",[6,\"d.vec4f\",[\"litRgb\",[7,\"curlSample\",\"w\"]]]],[13,\"flatColor\",[6,\"d.vec4f\",[[6,[7,[7,\"flatSample\",\"xyz\"],\"mul\"],[\"flatShade\"]],[7,\"flatSample\",\"w\"]]]],[13,\"peeledColor\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],\"peelAlpha\"]]],[13,\"base\",[6,\"std.mix\",[\"peeledColor\",\"flatColor\",[6,\"d.vec4f\",[\"foldBlend\"]]]]],[10,[6,\"std.select\",[\"base\",\"curlColor\",[1,\"showCurl\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"d.vec4f\":()=>S,\"std.mix\":()=>K,\"std.select\":()=>N}})&&e.f)({})),b0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({uv:m,coverage:n,normal:A}),\"SphereBulge\"),vte=w.fn([m,m,m,n,n],b0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_div(s.x,s.y),l=r.x,c=__tsover_sub(1,r.y),d=__tsover_mul(__tsover_sub(t.x,l),i),u=__tsover_sub(t.y,c),p=__tsover_div(__tsover_mul(d,2),o),_=__tsover_div(__tsover_mul(u,2),o),f=__tsover_add(__tsover_mul(p,p),__tsover_mul(_,_)),h=__tsover_sub(1,be(.98,1,f)),g=Ue(B(n(0),__tsover_sub(1,f))),y=__tsover_add(1,__tsover_mul(g,a)),b=__tsover_div(__tsover_mul(__tsover_div(p,y),o),2),x=__tsover_div(__tsover_mul(__tsover_div(_,y),o),2),P=__tsover_add(__tsover_div(b,i),l),C=__tsover_add(x,c),E=vs(A(p,_,g));return b0({uv:m(P,C),coverage:h,normal:E})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"depth\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"centerX\",[7,\"center\",\"x\"]],[13,\"centerY\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"cuX\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"],\"*\",\"aspect\"]],[13,\"cuY\",[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"]],[13,\"sphereX\",[1,[1,\"cuX\",\"*\",[5,\"2\"]],\"/\",\"radius\"]],[13,\"sphereY\",[1,[1,\"cuY\",\"*\",[5,\"2\"]],\"/\",\"radius\"]],[13,\"radiusSq\",[1,[1,\"sphereX\",\"*\",\"sphereX\"],\"+\",[1,\"sphereY\",\"*\",\"sphereY\"]]],[13,\"sphereAlpha\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0.98\"],[5,\"1\"],\"radiusSq\"]]]],[13,\"z\",[6,\"std.sqrt\",[[6,\"std.max\",[[6,\"d.f32\",[[5,\"0\"]]],[1,[5,\"1\"],\"-\",\"radiusSq\"]]]]]],[13,\"depthFactor\",[1,[5,\"1\"],\"+\",[1,\"z\",\"*\",\"depth\"]]],[13,\"finalX\",[1,[1,[1,\"sphereX\",\"/\",\"depthFactor\"],\"*\",\"radius\"],\"/\",[5,\"2\"]]],[13,\"finalY\",[1,[1,[1,\"sphereY\",\"/\",\"depthFactor\"],\"*\",\"radius\"],\"/\",[5,\"2\"]]],[13,\"transformedX\",[1,[1,\"finalX\",\"/\",\"aspect\"],\"+\",\"centerX\"]],[13,\"transformedY\",[1,\"finalY\",\"+\",\"centerY\"]],[13,\"normal\",[6,\"std.normalize\",[[6,\"d.vec3f\",[\"sphereX\",\"sphereY\",\"z\"]]]]],[10,[6,\"SphereBulge\",[[104,{uv:[6,\"d.vec2f\",[\"transformedX\",\"transformedY\"]],coverage:\"sphereAlpha\",normal:\"normal\"}]]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"d.f32\":()=>n,\"std.normalize\":()=>vs,\"d.vec3f\":()=>A,SphereBulge:()=>b0,\"d.vec2f\":()=>m}})&&e.f)({})),hte=w.fn([A,m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=A(0,0,1),i=__tsover_add(1,__tsover_mul(4,__tsover_sub(1,o))),l=vt(__tsover_sub(1,B(Se(t,a),n(0))),i),c=__tsover_mul(__tsover_sub(s.x,.5),2),d=__tsover_mul(__tsover_sub(__tsover_sub(1,s.y),.5),2),u=vs(m(__tsover_add(t.x,1e-4),__tsover_add(t.y,1e-4))),p=vs(m(__tsover_add(c,1e-4),__tsover_add(d,1e-4))),_=vt(B(n(0),Se(u,p)),n(2));return __tsover_mul(__tsover_mul(__tsover_mul(l,_),r),2)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"normal\"},{type:\"i\",name:\"lightPos\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"viewDir\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"1\"]]]],[13,\"fresnelPower\",[1,[5,\"1\"],\"+\",[1,[5,\"4\"],\"*\",[1,[5,\"1\"],\"-\",\"softness\"]]]],[13,\"fresnel\",[6,\"std.pow\",[[1,[5,\"1\"],\"-\",[6,\"std.max\",[[6,\"std.dot\",[\"normal\",\"viewDir\"]],[6,\"d.f32\",[[5,\"0\"]]]]]],\"fresnelPower\"]]],[13,\"lightDir2Dx\",[1,[1,[7,\"lightPos\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"lightDir2Dy\",[1,[1,[1,[5,\"1\"],\"-\",[7,\"lightPos\",\"y\"]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"normalDir\",[6,\"std.normalize\",[[6,\"d.vec2f\",[[1,[7,\"normal\",\"x\"],\"+\",[5,\"0.0001\"]],[1,[7,\"normal\",\"y\"],\"+\",[5,\"0.0001\"]]]]]]],[13,\"lightDirNorm\",[6,\"std.normalize\",[[6,\"d.vec2f\",[[1,\"lightDir2Dx\",\"+\",[5,\"0.0001\"]],[1,\"lightDir2Dy\",\"+\",[5,\"0.0001\"]]]]]]],[13,\"directionality\",[6,\"std.max\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"std.dot\",[\"normalDir\",\"lightDirNorm\"]]]]],[13,\"directionalBias\",[6,\"std.pow\",[\"directionality\",[6,\"d.f32\",[[5,\"2\"]]]]]],[10,[1,[1,[1,\"fresnel\",\"*\",\"directionalBias\"],\"*\",\"intensity\"],\"*\",[5,\"2\"]]]]]},externals:{\"d.vec3f\":()=>A,\"std.pow\":()=>vt,\"std.max\":()=>B,\"std.dot\":()=>Se,\"d.f32\":()=>n,\"std.normalize\":()=>vs,\"d.vec2f\":()=>m}})&&e.f)({})),gte=w.fn([S,A,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return S(__tsover_add(t.x,__tsover_mul(s.x,r)),__tsover_add(t.y,__tsover_mul(s.y,r)),__tsover_add(t.z,__tsover_mul(s.z,r)),__tsover_mul(t.w,o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"straight\"},{type:\"i\",name:\"lightColor\"},{type:\"i\",name:\"rim\"},{type:\"i\",name:\"coverage\"}],body:[0,[[13,\"r\",[1,[7,\"straight\",\"x\"],\"+\",[1,[7,\"lightColor\",\"x\"],\"*\",\"rim\"]]],[13,\"g\",[1,[7,\"straight\",\"y\"],\"+\",[1,[7,\"lightColor\",\"y\"],\"*\",\"rim\"]]],[13,\"b\",[1,[7,\"straight\",\"z\"],\"+\",[1,[7,\"lightColor\",\"z\"],\"*\",\"rim\"]]],[13,\"a\",[1,[7,\"straight\",\"w\"],\"*\",\"coverage\"]],[10,[6,\"d.vec4f\",[\"r\",\"g\",\"b\",\"a\"]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({}));function yte(e,t,s){let r=e(t.add(s)),o=e(t),a=e(t.add(s.mul(-1)));return Ct(r.member(\"r\"),o.member(\"g\"),a.member(\"b\"),o.member(\"a\"))}function bte(e,t,s){return s===1?e(t).mul(W($3,\"edgeTransparentMask\",[t])):e(s===2?W(Hm,\"edgeMirrorUV\",[t]):s===3?W(jm,\"edgeWrapUV\",[t]):W(N3,\"edgeClampUV\",[t]))}var uS=1/360,xte=w.fn([m,m,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=i0(t),l=i0(s),c=l.sub(i),d=he(c),u=vs(c),p=B(a.y,1e-6),_=__tsover_div(a.x,p),f=__tsover_mul(__tsover_mul(r,bt),-1),h=pe(f),g=ae(f),y=i.add(l).mul(.5),b=o.sub(y),x=Pn(m(__tsover_mul(b.x,_),b.y),h,g),P=Se(m(__tsover_div(x.x,_),x.y).add(y).sub(i),u);return __tsover_div(P,B(d,1e-6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"start\"},{type:\"i\",name:\"end\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"startPos\",[6,\"unflipPosition\",[\"start\"]]],[13,\"endPos\",[6,\"unflipPosition\",[\"end\"]]],[13,\"gradientVector\",[6,[7,\"endPos\",\"sub\"],[\"startPos\"]]],[13,\"gradientLength\",[6,\"std.length\",[\"gradientVector\"]]],[13,\"gradientDir\",[6,\"std.normalize\",[\"gradientVector\"]]],[13,\"safeViewportY\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]],[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",\"safeViewportY\"]],[13,\"angleRad\",[1,[1,\"angle\",\"*\",\"DEG_TO_RAD\"],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"cosAngle\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinAngle\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"midpoint\",[6,[7,[6,[7,\"startPos\",\"add\"],[\"endPos\"]],\"mul\"],[[5,\"0.5\"]]]],[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[\"midpoint\"]]],[13,\"rotated\",[6,\"geom.rotate2\",[[6,\"d.vec2f\",[[1,[7,\"centeredUV\",\"x\"],\"*\",\"aspect\"],[7,\"centeredUV\",\"y\"]]],\"cosAngle\",\"sinAngle\"]]],[13,\"rotatedUV\",[6,[7,[6,\"d.vec2f\",[[1,[7,\"rotated\",\"x\"],\"/\",\"aspect\"],[7,\"rotated\",\"y\"]]],\"add\"],[\"midpoint\"]]],[13,\"relativePos\",[6,[7,\"rotatedUV\",\"sub\"],[\"startPos\"]]],[13,\"projection\",[6,\"std.dot\",[\"relativePos\",\"gradientDir\"]]],[10,[1,\"projection\",\"/\",[6,\"std.max\",[\"gradientLength\",[5,\"0.000001\"]]]]]]]},externals:{unflipPosition:()=>i0,\"std.length\":()=>he,\"std.normalize\":()=>vs,\"std.max\":()=>B,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"geom.rotate2\":()=>Pn,\"d.vec2f\":()=>m,\"std.dot\":()=>Se}})&&e.f)({})),S4=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=An(re(t),2);return N(s,__tsover_sub(2,s),s>1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[13,\"m\",[6,\"std.mod\",[[6,\"std.abs\",[\"t\"]],[5,\"2\"]]]],[10,[6,\"std.select\",[\"m\",[1,[5,\"2\"],\"-\",\"m\"],[1,\"m\",\">\",[5,\"1\"]]]]]]]},externals:{\"std.mod\":()=>An,\"std.abs\":()=>re,\"std.select\":()=>N}})&&e.f)({})),Ate=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Re(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[6,\"std.fract\",[\"t\"]]]]]},externals:{\"std.fract\":()=>Re}})&&e.f)({})),pS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return G(t,0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[6,\"std.clamp\",[\"t\",[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({})),wte=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=N(n(0),n(1),t>=0),r=N(n(0),n(1),t<=1);return __tsover_mul(s,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[13,\"inLow\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"t\",\">=\",[5,\"0\"]]]]],[13,\"inHigh\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"t\",\"<=\",[5,\"1\"]]]]],[10,[1,\"inLow\",\"*\",\"inHigh\"]]]]},externals:{\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})),Tte=w.fn([m,n,n,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=cc(a,t,i),c=__tsover_mul(s,bt),d=Pn(l,pe(c),-ae(c)),u=he(m(__tsover_mul(d.x,r),d.y)),p=B(o,1e-6);return __tsover_div(u,p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"skewAngle\"},{type:\"i\",name:\"ellipseAspect\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"delta\",[6,\"aspectCenteredDelta\",[\"uv\",\"center\",\"viewport\"]]],[13,\"skewRad\",[1,\"skewAngle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosS\",[6,\"std.cos\",[\"skewRad\"]]],[13,\"sinS\",[6,\"std.sin\",[\"skewRad\"]]],[13,\"rotated\",[6,\"geom.rotate2\",[\"delta\",\"cosS\",[4,\"-\",\"sinS\"]]]],[13,\"stretched\",[6,\"d.vec2f\",[[1,[7,\"rotated\",\"x\"],\"*\",\"ellipseAspect\"],[7,\"rotated\",\"y\"]]]],[13,\"dist\",[6,\"std.length\",[\"stretched\"]]],[13,\"safeRadius\",[6,\"std.max\",[\"radius\",[5,\"0.000001\"]]]],[10,[1,\"dist\",\"/\",\"safeRadius\"]]]]},externals:{aspectCenteredDelta:()=>cc,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"geom.rotate2\":()=>Pn,\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.max\":()=>B}})&&e.f)({})),Ste=w.fn([m,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=cc(r,t,o),i=Xt(a.y,a.x),l=__tsover_sub(.5,__tsover_div(i,Jt)),c=__tsover_mul(s,uS);return __tsover_add(l,c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"delta\",[6,\"aspectCenteredDelta\",[\"uv\",\"center\",\"viewport\"]]],[13,\"angle\",[6,\"std.atan2\",[[7,\"delta\",\"y\"],[7,\"delta\",\"x\"]]]],[13,\"normalized\",[1,[5,\"0.5\"],\"-\",[1,\"angle\",\"/\",\"TAU\"]]],[13,\"rotationFraction\",[1,\"rotation\",\"*\",\"INV_360\"]],[10,[1,\"normalized\",\"+\",\"rotationFraction\"]]]]},externals:{aspectCenteredDelta:()=>cc,\"std.atan2\":()=>Xt,TAU:()=>Jt,INV_360:()=>uS}})&&e.f)({})),Pte=w.fn([m,n,n,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=cc(a,t,i),c=__tsover_mul(r,bt),d=Pn(l,pe(c),-ae(c)),u=re(d.x),p=re(d.y),_=K(__tsover_add(u,p),B(u,p),o);return __tsover_div(_,s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"size\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"roundness\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"delta\",[6,\"aspectCenteredDelta\",[\"uv\",\"center\",\"viewport\"]]],[13,\"rotRad\",[1,\"rotation\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rotated\",[6,\"geom.rotate2\",[\"delta\",\"cosR\",[4,\"-\",\"sinR\"]]]],[13,\"absDx\",[6,\"std.abs\",[[7,\"rotated\",\"x\"]]]],[13,\"absDy\",[6,\"std.abs\",[[7,\"rotated\",\"y\"]]]],[13,\"l1\",[1,\"absDx\",\"+\",\"absDy\"]],[13,\"linf\",[6,\"std.max\",[\"absDx\",\"absDy\"]]],[13,\"dist\",[6,\"std.mix\",[\"l1\",\"linf\",\"roundness\"]]],[10,[1,\"dist\",\"/\",\"size\"]]]]},externals:{aspectCenteredDelta:()=>cc,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"geom.rotate2\":()=>Pn,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.mix\":()=>K}})&&e.f)({})),Cte=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(t,s);return N(G(r,0,1),Re(r),s>1.0001)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"repeat\"}],body:[0,[[13,\"s\",[1,\"t\",\"*\",\"repeat\"]],[10,[6,\"std.select\",[[6,\"std.clamp\",[\"s\",[5,\"0\"],[5,\"1\"]]],[6,\"std.fract\",[\"s\"]],[1,\"repeat\",\">\",[5,\"1.0001\"]]]]]]]},externals:{\"std.select\":()=>N,\"std.clamp\":()=>G,\"std.fract\":()=>Re}})&&e.f)({})),Mte=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Re(__tsover_mul(t,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"repeat\"}],body:[0,[[10,[6,\"std.fract\",[[1,\"t\",\"*\",\"repeat\"]]]]]]},externals:{\"std.fract\":()=>Re}})&&e.f)({})),Ete=w.fn([m,m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,bt),l=Cs(s),c=__tsover_add(av(dc(t,l),pe(i),ae(i)),__tsover_mul(l,.5));return Re(__tsover_add(__tsover_mul(__tsover_mul(c,o),.2),a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"projectedCoord\",[1,[6,\"directionalProjection\",[[6,\"canvasCentredDelta\",[\"uv\",\"aspect\"]],[6,\"std.cos\",[\"angleRad\"]],[6,\"std.sin\",[\"angleRad\"]]]],\"+\",[1,\"aspect\",\"*\",[5,\"0.5\"]]]],[10,[6,\"std.fract\",[[1,[1,[1,\"projectedCoord\",\"*\",\"scale\"],\"*\",[5,\"0.2\"]],\"+\",\"animTime\"]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"geom.aspectOf\":()=>Cs,directionalProjection:()=>av,canvasCentredDelta:()=>dc,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.fract\":()=>Re}})&&e.f)({})),kte=w.fn([n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=__tsover_mul(t,6);return S(G(__tsover_sub(re(__tsover_sub(s,3)),1),0,1),G(__tsover_sub(2,re(__tsover_sub(s,2))),0,1),G(__tsover_sub(2,re(__tsover_sub(s,4))),0,1),1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[13,\"h6\",[1,\"t\",\"*\",[5,\"6\"]]],[13,\"r\",[6,\"std.clamp\",[[1,[6,\"std.abs\",[[1,\"h6\",\"-\",[5,\"3\"]]]],\"-\",[5,\"1\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"g\",[6,\"std.clamp\",[[1,[5,\"2\"],\"-\",[6,\"std.abs\",[[1,\"h6\",\"-\",[5,\"2\"]]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"b\",[6,\"std.clamp\",[[1,[5,\"2\"],\"-\",[6,\"std.abs\",[[1,\"h6\",\"-\",[5,\"4\"]]]]],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[\"r\",\"g\",\"b\",[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G,\"std.abs\":()=>re,\"d.vec4f\":()=>S}})&&e.f)({})),Bte=w.fn([n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=__tsover_mul(t,3);return m(Re(s),ie(s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[13,\"t3\",[1,\"t\",\"*\",[5,\"3\"]]],[10,[6,\"d.vec2f\",[[6,\"std.fract\",[\"t3\"]],[6,\"std.floor\",[\"t3\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.floor\":()=>ie}})&&e.f)({})),zte=w.fn([S,S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return K(K(r,s,Et(o,1.5)),t,Et(o,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"c01\"},{type:\"i\",name:\"c12\"},{type:\"i\",name:\"c20\"},{type:\"i\",name:\"floorT3\"}],body:[0,[[13,\"seg1\",[6,\"std.mix\",[\"c20\",\"c12\",[6,\"std.step\",[\"floorT3\",[5,\"1.5\"]]]]]],[10,[6,\"std.mix\",[\"seg1\",\"c01\",[6,\"std.step\",[\"floorT3\",[5,\"0.5\"]]]]]]]]},externals:{\"std.mix\":()=>K,\"std.step\":()=>Et}})&&e.f)({})),mS=w.fn([m,n,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_div(a.x,a.y),l=__tsover_sub(__tsover_mul(o.x,i),__tsover_mul(t.x,i)),c=__tsover_sub(o.y,__tsover_sub(1,t.y)),d=he(m(l,c)),u=__tsover_sub(Xt(c,l),r);return __tsover_add(__tsover_mul(d,s),__tsover_div(u,Po))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,[7,\"center\",\"x\"],\"*\",\"aspect\"]]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]],[13,\"l\",[6,\"std.length\",[[6,\"d.vec2f\",[\"dx\",\"dy\"]]]]],[13,\"angle\",[1,[6,\"std.atan2\",[\"dy\",\"dx\"]],\"-\",\"animTime\"]],[10,[1,[1,\"l\",\"*\",\"scale\"],\"+\",[1,\"angle\",\"/\",\"TWO_PI\"]]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.atan2\":()=>Xt,TWO_PI:()=>Po}})&&e.f)({})),Rte=w.fn([m,n,n,n,n,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_div(c.x,c.y),u=he(m(__tsover_sub(__tsover_mul(l.x,d),__tsover_mul(t.x,d)),__tsover_sub(l.y,__tsover_sub(1,t.y)))),p=mS(t,s,i,l,c),_=Re(p),f=__tsover_mul(re(__tsover_sub(_,.5)),2),h=G(r,__tsover_mul(o,.005),1),g=__tsover_sub(1,__tsover_mul(G(o,0,1),u)),y=__tsover_mul(h,g),b=mr(p),x=__tsover_sub(4,__tsover_mul(__tsover_mul(be(.05,.4,__tsover_mul(r,2)),be(.05,.4,__tsover_mul(__tsover_sub(1,r),2))),3)),P=K(__tsover_mul(x,b),mr(f),G(b,0,1));return be(__tsover_sub(__tsover_sub(y,P),a),__tsover_add(__tsover_add(y,P),a),f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"strokeWidth\"},{type:\"i\",name:\"strokeFalloff\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,[7,\"center\",\"x\"],\"*\",\"aspect\"]]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]],[13,\"l\",[6,\"std.length\",[[6,\"d.vec2f\",[\"dx\",\"dy\"]]]]],[13,\"offset\",[6,\"spiralOffset\",[\"center\",\"scale\",\"animTime\",\"uv\",\"viewport\"]]],[13,\"stripe\",[6,\"std.fract\",[\"offset\"]]],[13,\"shape\",[1,[6,\"std.abs\",[[1,\"stripe\",\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"baseWidth\",[6,\"std.clamp\",[\"strokeWidth\",[1,\"strokeFalloff\",\"*\",[5,\"0.005\"]],[5,\"1\"]]]],[13,\"falloffAmount\",[1,[5,\"1\"],\"-\",[1,[6,\"std.clamp\",[\"strokeFalloff\",[5,\"0\"],[5,\"1\"]]],\"*\",\"l\"]]],[13,\"width\",[1,\"baseWidth\",\"*\",\"falloffAmount\"]],[13,\"fw\",[6,\"std.fwidth\",[\"offset\"]]],[13,\"fwMult\",[1,[5,\"4\"],\"-\",[1,[1,[6,\"std.smoothstep\",[[5,\"0.05\"],[5,\"0.4\"],[1,\"strokeWidth\",\"*\",[5,\"2\"]]]],\"*\",[6,\"std.smoothstep\",[[5,\"0.05\"],[5,\"0.4\"],[1,[1,[5,\"1\"],\"-\",\"strokeWidth\"],\"*\",[5,\"2\"]]]]],\"*\",[5,\"3\"]]]],[13,\"pixelSize\",[6,\"std.mix\",[[1,\"fwMult\",\"*\",\"fw\"],[6,\"std.fwidth\",[\"shape\"]],[6,\"std.clamp\",[\"fw\",[5,\"0\"],[5,\"1\"]]]]]],[10,[6,\"std.smoothstep\",[[1,[1,\"width\",\"-\",\"pixelSize\"],\"-\",\"softness\"],[1,[1,\"width\",\"+\",\"pixelSize\"],\"+\",\"softness\"],\"shape\"]]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,spiralOffset:()=>mS,\"std.fract\":()=>Re,\"std.abs\":()=>re,\"std.clamp\":()=>G,\"std.fwidth\":()=>mr,\"std.smoothstep\":()=>be,\"std.mix\":()=>K}})&&e.f)({})),iu=w.fn([m,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(t.x,s.x),a=__tsover_sub(t.y,s.y),i=__tsover_add(Ue(__tsover_add(__tsover_mul(o,o),__tsover_mul(a,a))),.001);return __tsover_div(1,vt(i,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvAspect\"},{type:\"i\",name:\"pos\"},{type:\"i\",name:\"effPower\"}],body:[0,[[13,\"dx\",[1,[7,\"uvAspect\",\"x\"],\"-\",[7,\"pos\",\"x\"]]],[13,\"dy\",[1,[7,\"uvAspect\",\"y\"],\"-\",[7,\"pos\",\"y\"]]],[13,\"dist\",[1,[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]],\"+\",[5,\"0.001\"]]],[10,[1,[5,\"1\"],\"/\",[6,\"std.pow\",[\"dist\",\"effPower\"]]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.pow\":()=>vt}})&&e.f)({})),Dte=w.fn([m,m,m,m,m,m,m,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=Cs(s),u=m(__tsover_mul(t.x,d),t.y),p=Zi(r,d),_=Zi(o,d),f=Zi(a,d),h=Zi(i,d),g=Zi(l,d),y=ye(__tsover_div(8,__tsover_add(c,.5)),8),b=iu(u,p,y),x=iu(u,_,y),P=iu(u,f,y),C=iu(u,h,y),E=iu(u,g,y),R=b,U=__tsover_div(x,__tsover_add(R,x)),L=__tsover_add(R,x),k=__tsover_div(P,__tsover_add(L,P)),D=__tsover_add(L,P),O=__tsover_div(C,__tsover_add(D,C)),F=__tsover_add(D,C);return S(U,k,O,__tsover_div(E,__tsover_add(F,E)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"vp\"},{type:\"i\",name:\"posA\"},{type:\"i\",name:\"posB\"},{type:\"i\",name:\"posC\"},{type:\"i\",name:\"posD\"},{type:\"i\",name:\"posE\"},{type:\"i\",name:\"smoothness\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"vp\"]]],[13,\"uvAspect\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"pA\",[6,\"aspectCentrePosition\",[\"posA\",\"aspect\"]]],[13,\"pB\",[6,\"aspectCentrePosition\",[\"posB\",\"aspect\"]]],[13,\"pC\",[6,\"aspectCentrePosition\",[\"posC\",\"aspect\"]]],[13,\"pD\",[6,\"aspectCentrePosition\",[\"posD\",\"aspect\"]]],[13,\"pE\",[6,\"aspectCentrePosition\",[\"posE\",\"aspect\"]]],[13,\"effPower\",[6,\"std.min\",[[1,[5,\"8\"],\"/\",[1,\"smoothness\",\"+\",[5,\"0.5\"]]],[5,\"8\"]]]],[13,\"wA\",[6,\"mpgWeight\",[\"uvAspect\",\"pA\",\"effPower\"]]],[13,\"wB\",[6,\"mpgWeight\",[\"uvAspect\",\"pB\",\"effPower\"]]],[13,\"wC\",[6,\"mpgWeight\",[\"uvAspect\",\"pC\",\"effPower\"]]],[13,\"wD\",[6,\"mpgWeight\",[\"uvAspect\",\"pD\",\"effPower\"]]],[13,\"wE\",[6,\"mpgWeight\",[\"uvAspect\",\"pE\",\"effPower\"]]],[13,\"accW1\",\"wA\"],[13,\"t1\",[1,\"wB\",\"/\",[1,\"accW1\",\"+\",\"wB\"]]],[13,\"accW2\",[1,\"accW1\",\"+\",\"wB\"]],[13,\"t2\",[1,\"wC\",\"/\",[1,\"accW2\",\"+\",\"wC\"]]],[13,\"accW3\",[1,\"accW2\",\"+\",\"wC\"]],[13,\"t3\",[1,\"wD\",\"/\",[1,\"accW3\",\"+\",\"wD\"]]],[13,\"accW4\",[1,\"accW3\",\"+\",\"wD\"]],[13,\"t4\",[1,\"wE\",\"/\",[1,\"accW4\",\"+\",\"wE\"]]],[10,[6,\"d.vec4f\",[\"t1\",\"t2\",\"t3\",\"t4\"]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec2f\":()=>m,aspectCentrePosition:()=>Zi,\"std.min\":()=>ye,mpgWeight:()=>iu,\"d.vec4f\":()=>S}})&&e.f)({})),Lte=w.fn([m,m,m,m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=Cs(s),u=m(r.x,__tsover_sub(1,r.y)),p=m(o.x,__tsover_sub(1,o.y)),_=m(__tsover_mul(u.x,d),u.y),f=m(__tsover_mul(p.x,d),p.y),h=zT(m(__tsover_mul(t.x,d),t.y),_,f),g=RT(h.y,h.x,__tsover_mul(a,.25),__tsover_mul(i,.25),l,c),y=g.x,b=g.y;return m(y,b)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"vp\"},{type:\"i\",name:\"start\"},{type:\"i\",name:\"end\"},{type:\"i\",name:\"startThickness\"},{type:\"i\",name:\"endThickness\"},{type:\"i\",name:\"startSoftness\"},{type:\"i\",name:\"endSoftness\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"vp\"]]],[13,\"startPos\",[6,\"d.vec2f\",[[7,\"start\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"start\",\"y\"]]]]],[13,\"endPos\",[6,\"d.vec2f\",[[7,\"end\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"end\",\"y\"]]]]],[13,\"acStart\",[6,\"d.vec2f\",[[1,[7,\"startPos\",\"x\"],\"*\",\"aspect\"],[7,\"startPos\",\"y\"]]]],[13,\"acEnd\",[6,\"d.vec2f\",[[1,[7,\"endPos\",\"x\"],\"*\",\"aspect\"],[7,\"endPos\",\"y\"]]]],[13,\"acUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"proj\",[6,\"lightfields.pointToSegment\",[\"acUV\",\"acStart\",\"acEnd\"]]],[13,\"field\",[6,\"lightfields.taperedSegmentGlow\",[[7,\"proj\",\"y\"],[7,\"proj\",\"x\"],[1,\"startThickness\",\"*\",[5,\"0.25\"]],[1,\"endThickness\",\"*\",[5,\"0.25\"]],\"startSoftness\",\"endSoftness\"]]],[13,\"colorT\",[7,\"field\",\"x\"]],[13,\"alpha\",[7,\"field\",\"y\"]],[10,[6,\"d.vec2f\",[\"colorT\",\"alpha\"]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec2f\":()=>m,\"lightfields.pointToSegment\":()=>zT,\"lightfields.taperedSegmentGlow\":()=>RT}})&&e.f)({})),Ute=Dk({domain:\"unit\",contrastMode:\"multiplicative\",invert:!0,glowGamma:!0,balance:\"percentCentred\"}),Ote=w.fn([m,m,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s);return A(__tsover_mul(t.x,o),t.y,0).mul(Tt(__tsover_sub(r,1)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"scale\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"base\",[6,\"d.vec3f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"],[5,\"0\"]]]],[10,[6,[7,\"base\",\"mul\"],[[6,\"std.exp\",[[1,\"scale\",\"-\",[5,\"1\"]]]]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec3f\":()=>A,\"std.exp\":()=>Tt}})&&e.f)({})),Gte=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(__tsover_mul(Na(t),.5),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"}],body:[0,[[10,[1,[1,[6,\"noise.mxNoiseFloat3\",[\"pos\"]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]},externals:{\"noise.mxNoiseFloat3\":()=>Na}})&&e.f)({})),Fte=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=r,a=s,i=m(__tsover_add(t.x,__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(t.y,__tsover_mul(a,1.7)),__tsover_mul(o,.8))),.12),__tsover_mul(pe(__tsover_sub(__tsover_mul(t.x,__tsover_mul(a,.9)),__tsover_mul(o,.5))),.05))),__tsover_add(t.y,__tsover_add(__tsover_mul(pe(__tsover_sub(__tsover_mul(t.x,__tsover_mul(a,1.3)),__tsover_mul(o,.6))),.12),__tsover_mul(ae(__tsover_add(__tsover_mul(t.y,__tsover_mul(a,1.1)),__tsover_mul(o,.7))),.05)))),l=ae(__tsover_add(__tsover_add(__tsover_mul(i.x,__tsover_mul(a,2.1)),__tsover_mul(i.y,__tsover_mul(a,1.8))),__tsover_mul(o,.4))),c=__tsover_mul(s,2.1),d=m(__tsover_add(i.x,__tsover_add(__tsover_mul(pe(__tsover_sub(__tsover_mul(i.y,__tsover_mul(c,2.7)),__tsover_mul(o,.45))),.07),__tsover_mul(ae(__tsover_add(__tsover_mul(i.x,__tsover_mul(c,1.9)),__tsover_mul(o,.6))),.04))),__tsover_add(i.y,__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(i.x,__tsover_mul(c,2.3)),__tsover_mul(o,.65))),.07),__tsover_mul(pe(__tsover_sub(__tsover_mul(i.y,__tsover_mul(c,1.6)),__tsover_mul(o,.4))),.04)))),u=pe(__tsover_add(__tsover_sub(__tsover_mul(d.x,__tsover_mul(c,1.4)),__tsover_mul(d.y,__tsover_mul(c,1.9))),__tsover_mul(o,.35))),p=__tsover_mul(s,3.7),_=m(__tsover_add(d.x,__tsover_add(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(d.y,__tsover_mul(p,1.8)),__tsover_mul(o,.85))),.04),__tsover_mul(pe(__tsover_sub(__tsover_mul(d.x,__tsover_mul(p,1.3)),__tsover_mul(o,.55))),.025)),__tsover_mul(ae(__tsover_add(__tsover_mul(__tsover_add(d.x,d.y),__tsover_mul(p,.7)),__tsover_mul(o,.9))),.02))),__tsover_add(d.y,__tsover_add(__tsover_add(__tsover_mul(pe(__tsover_sub(__tsover_mul(d.x,__tsover_mul(p,1.6)),__tsover_mul(o,.75))),.04),__tsover_mul(ae(__tsover_add(__tsover_mul(d.y,__tsover_mul(p,1.1)),__tsover_mul(o,.5))),.025)),__tsover_mul(pe(__tsover_sub(__tsover_mul(__tsover_add(d.x,d.y),__tsover_mul(p,.8)),__tsover_mul(o,.95))),.02)))),f=ae(__tsover_sub(__tsover_add(__tsover_mul(_.x,__tsover_mul(p,1.1)),__tsover_mul(_.y,__tsover_mul(p,1.5))),__tsover_mul(o,.55)));return __tsover_add(__tsover_add(__tsover_mul(l,.45),__tsover_mul(u,.35)),__tsover_mul(f,.2))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"detail\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"t\",\"animTime\"],[13,\"freq1\",\"detail\"],[13,\"d1\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"uv\",\"y\"],\"*\",[1,\"freq1\",\"*\",[5,\"1.7\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.8\"]]]]],\"*\",[5,\"0.12\"]],\"+\",[1,[6,\"std.cos\",[[1,[1,[7,\"uv\",\"x\"],\"*\",[1,\"freq1\",\"*\",[5,\"0.9\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.5\"]]]]],\"*\",[5,\"0.05\"]]]],[1,[7,\"uv\",\"y\"],\"+\",[1,[1,[6,\"std.cos\",[[1,[1,[7,\"uv\",\"x\"],\"*\",[1,\"freq1\",\"*\",[5,\"1.3\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.6\"]]]]],\"*\",[5,\"0.12\"]],\"+\",[1,[6,\"std.sin\",[[1,[1,[7,\"uv\",\"y\"],\"*\",[1,\"freq1\",\"*\",[5,\"1.1\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.7\"]]]]],\"*\",[5,\"0.05\"]]]]]]],[13,\"pattern1\",[6,\"std.sin\",[[1,[1,[1,[7,\"d1\",\"x\"],\"*\",[1,\"freq1\",\"*\",[5,\"2.1\"]]],\"+\",[1,[7,\"d1\",\"y\"],\"*\",[1,\"freq1\",\"*\",[5,\"1.8\"]]]],\"+\",[1,\"t\",\"*\",[5,\"0.4\"]]]]]],[13,\"freq2\",[1,\"detail\",\"*\",[5,\"2.1\"]]],[13,\"d2\",[6,\"d.vec2f\",[[1,[7,\"d1\",\"x\"],\"+\",[1,[1,[6,\"std.cos\",[[1,[1,[7,\"d1\",\"y\"],\"*\",[1,\"freq2\",\"*\",[5,\"2.7\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.45\"]]]]],\"*\",[5,\"0.07\"]],\"+\",[1,[6,\"std.sin\",[[1,[1,[7,\"d1\",\"x\"],\"*\",[1,\"freq2\",\"*\",[5,\"1.9\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.6\"]]]]],\"*\",[5,\"0.04\"]]]],[1,[7,\"d1\",\"y\"],\"+\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"d1\",\"x\"],\"*\",[1,\"freq2\",\"*\",[5,\"2.3\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.65\"]]]]],\"*\",[5,\"0.07\"]],\"+\",[1,[6,\"std.cos\",[[1,[1,[7,\"d1\",\"y\"],\"*\",[1,\"freq2\",\"*\",[5,\"1.6\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.4\"]]]]],\"*\",[5,\"0.04\"]]]]]]],[13,\"pattern2\",[6,\"std.cos\",[[1,[1,[1,[7,\"d2\",\"x\"],\"*\",[1,\"freq2\",\"*\",[5,\"1.4\"]]],\"-\",[1,[7,\"d2\",\"y\"],\"*\",[1,\"freq2\",\"*\",[5,\"1.9\"]]]],\"+\",[1,\"t\",\"*\",[5,\"0.35\"]]]]]],[13,\"freq3\",[1,\"detail\",\"*\",[5,\"3.7\"]]],[13,\"d3\",[6,\"d.vec2f\",[[1,[7,\"d2\",\"x\"],\"+\",[1,[1,[1,[6,\"std.sin\",[[1,[1,[7,\"d2\",\"y\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.8\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.85\"]]]]],\"*\",[5,\"0.04\"]],\"+\",[1,[6,\"std.cos\",[[1,[1,[7,\"d2\",\"x\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.3\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.55\"]]]]],\"*\",[5,\"0.025\"]]],\"+\",[1,[6,\"std.sin\",[[1,[1,[1,[7,\"d2\",\"x\"],\"+\",[7,\"d2\",\"y\"]],\"*\",[1,\"freq3\",\"*\",[5,\"0.7\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.9\"]]]]],\"*\",[5,\"0.02\"]]]],[1,[7,\"d2\",\"y\"],\"+\",[1,[1,[1,[6,\"std.cos\",[[1,[1,[7,\"d2\",\"x\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.6\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.75\"]]]]],\"*\",[5,\"0.04\"]],\"+\",[1,[6,\"std.sin\",[[1,[1,[7,\"d2\",\"y\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.1\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.5\"]]]]],\"*\",[5,\"0.025\"]]],\"+\",[1,[6,\"std.cos\",[[1,[1,[1,[7,\"d2\",\"x\"],\"+\",[7,\"d2\",\"y\"]],\"*\",[1,\"freq3\",\"*\",[5,\"0.8\"]]],\"-\",[1,\"t\",\"*\",[5,\"0.95\"]]]]],\"*\",[5,\"0.02\"]]]]]]],[13,\"pattern3\",[6,\"std.sin\",[[1,[1,[1,[7,\"d3\",\"x\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.1\"]]],\"+\",[1,[7,\"d3\",\"y\"],\"*\",[1,\"freq3\",\"*\",[5,\"1.5\"]]]],\"-\",[1,\"t\",\"*\",[5,\"0.55\"]]]]]],[10,[1,[1,[1,\"pattern1\",\"*\",[5,\"0.45\"]],\"+\",[1,\"pattern2\",\"*\",[5,\"0.35\"]]],\"+\",[1,\"pattern3\",\"*\",[5,\"0.2\"]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.sin\":()=>ae,\"std.cos\":()=>pe}})&&e.f)({})),Ite=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return be(r,o,__tsover_add(__tsover_add(__tsover_mul(t,.5),.5),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pattern\"},{type:\"i\",name:\"bias\"},{type:\"i\",name:\"low\"},{type:\"i\",name:\"high\"}],body:[0,[[13,\"normalized\",[1,[1,[1,\"pattern\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],\"+\",\"bias\"]],[10,[6,\"std.smoothstep\",[\"low\",\"high\",\"normalized\"]]]]]},externals:{\"std.smoothstep\":()=>be}})&&e.f)({})),Yte=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return __tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(s,r),__tsover_mul(t,o))),a),1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pattern\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"speed\"},{type:\"i\",name:\"span\"},{type:\"i\",name:\"depth\"}],body:[0,[[10,[1,[1,[6,\"std.sin\",[[1,[1,\"animTime\",\"*\",\"speed\"],\"+\",[1,\"pattern\",\"*\",\"span\"]]]],\"*\",\"depth\"],\"+\",[5,\"1\"]]]]]},externals:{\"std.sin\":()=>ae}})&&e.f)({})),cm=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Ys(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"noise.hash12\",[\"p\"]]]]]},externals:{\"noise.hash12\":()=>Ys}})&&e.f)({})),x0=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=Re(t),o=cm(s),a=cm(m(__tsover_add(s.x,1),s.y)),i=cm(m(s.x,__tsover_add(s.y,1))),l=cm(m(__tsover_add(s.x,1),__tsover_add(s.y,1))),c=r.mul(r).mul(r.mul(-2).add(3));return K(K(o,a,c.x),K(i,l,c.x),c.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"st\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"st\"]]],[13,\"f\",[6,\"std.fract\",[\"st\"]]],[13,\"a\",[6,\"godraysHash\",[\"i\"]]],[13,\"b\",[6,\"godraysHash\",[[6,\"d.vec2f\",[[1,[7,\"i\",\"x\"],\"+\",[5,\"1\"]],[7,\"i\",\"y\"]]]]]],[13,\"c\",[6,\"godraysHash\",[[6,\"d.vec2f\",[[7,\"i\",\"x\"],[1,[7,\"i\",\"y\"],\"+\",[5,\"1\"]]]]]]],[13,\"e\",[6,\"godraysHash\",[[6,\"d.vec2f\",[[1,[7,\"i\",\"x\"],\"+\",[5,\"1\"]],[1,[7,\"i\",\"y\"],\"+\",[5,\"1\"]]]]]]],[13,\"u\",[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[4,\"-\",[5,\"2\"]]]],\"add\"],[[5,\"3\"]]]]]],[13,\"x1\",[6,\"std.mix\",[\"a\",\"b\",[7,\"u\",\"x\"]]]],[13,\"x2\",[6,\"std.mix\",[\"c\",\"e\",[7,\"u\",\"x\"]]]],[10,[6,\"std.mix\",[\"x1\",\"x2\",[7,\"u\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,godraysHash:()=>cm,\"d.vec2f\":()=>m,\"std.mix\":()=>K}})&&e.f)({})),A0=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=vt(x0(m(__tsover_mul(t,a),o)),i);return K(vt(x0(m(__tsover_mul(s,a),o)),i),l,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"a\"},{type:\"i\",name:\"aWrapped\"},{type:\"i\",name:\"blend\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"freq\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"nLeft\",[6,\"std.pow\",[[6,\"godraysValueNoise\",[[6,\"d.vec2f\",[[1,\"a\",\"*\",\"freq\"],\"r\"]]]],\"intensity\"]]],[13,\"nRight\",[6,\"std.pow\",[[6,\"godraysValueNoise\",[[6,\"d.vec2f\",[[1,\"aWrapped\",\"*\",\"freq\"],\"r\"]]]],\"intensity\"]]],[10,[6,\"std.mix\",[\"nRight\",\"nLeft\",\"blend\"]]]]]},externals:{\"std.pow\":()=>vt,godraysValueNoise:()=>x0,\"d.vec2f\":()=>m,\"std.mix\":()=>K}})&&e.f)({})),Wte=w.fn([m,m,m],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s),a=m(r.x,__tsover_sub(1,r.y)),i=t.sub(a),l=m(__tsover_mul(i.x,o),i.y),c=BT(l);return S(c.x,c.y,c.z,he(l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"center\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"delta\",[6,[7,\"uv\",\"sub\"],[\"centerPos\"]]],[13,\"shapeUV\",[6,\"d.vec2f\",[[1,[7,\"delta\",\"x\"],\"*\",\"aspect\"],[7,\"delta\",\"y\"]]]],[13,\"ang\",[6,\"lightfields.seamlessAngularField\",[\"shapeUV\"]]],[10,[6,\"d.vec4f\",[[7,\"ang\",\"x\"],[7,\"ang\",\"y\"],[7,\"ang\",\"z\"],[6,\"std.length\",[\"shapeUV\"]]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec2f\":()=>m,\"lightfields.seamlessAngularField\":()=>BT,\"d.vec4f\":()=>S,\"std.length\":()=>he}})&&e.f)({})),w0=w.fn([S,n,n,n,n,S,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_sub(__tsover_mul(t.w,i.x),__tsover_mul(s,i.y)),d=__tsover_sub(__tsover_mul(__tsover_mul(t.w,i.z),__tsover_add(1,r)),__tsover_mul(s,i.w)),u=__tsover_mul(a,l.x),p=A0(t.x,t.y,t.z,c,u,o),_=A0(t.x,t.y,t.z,d,__tsover_mul(u,l.y),o);return __tsover_mul(p,_)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"frame\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"spots\"},{type:\"i\",name:\"intensityCalc\"},{type:\"i\",name:\"dens\"},{type:\"i\",name:\"sched\"},{type:\"i\",name:\"freqs\"}],body:[0,[[13,\"rA\",[1,[1,[7,\"frame\",\"w\"],\"*\",[7,\"sched\",\"x\"]],\"-\",[1,\"animTime\",\"*\",[7,\"sched\",\"y\"]]]],[13,\"rB\",[1,[1,[1,[7,\"frame\",\"w\"],\"*\",[7,\"sched\",\"z\"]],\"*\",[1,[5,\"1\"],\"+\",\"spots\"]],\"-\",[1,\"animTime\",\"*\",[7,\"sched\",\"w\"]]]],[13,\"f\",[1,\"dens\",\"*\",[7,\"freqs\",\"x\"]]],[13,\"shapeA\",[6,\"godraysRaysShape\",[[7,\"frame\",\"x\"],[7,\"frame\",\"y\"],[7,\"frame\",\"z\"],\"rA\",\"f\",\"intensityCalc\"]]],[13,\"shapeB\",[6,\"godraysRaysShape\",[[7,\"frame\",\"x\"],[7,\"frame\",\"y\"],[7,\"frame\",\"z\"],\"rB\",[1,\"f\",\"*\",[7,\"freqs\",\"y\"]],\"intensityCalc\"]]],[10,[1,\"shapeA\",\"*\",\"shapeB\"]]]]},externals:{godraysRaysShape:()=>A0}})&&e.f)({})),qte=w.fn([S,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(s,.2),l=__tsover_mul(6.5,re(a)),c=__tsover_sub(4,__tsover_mul(3,G(o,0,1))),d=__tsover_mul(6,r),u=w0(t,i,l,c,d,S(1,3,.5,2),m(5,4)),p=w0(t,i,l,c,d,S(1.4,2.5,.7,1.8),m(4.5,3.5));return G(__tsover_add(u,__tsover_mul(p,.7)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"frame\"},{type:\"i\",name:\"animTimeRaw\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"spotty\"}],body:[0,[[13,\"animTime\",[1,\"animTimeRaw\",\"*\",[5,\"0.2\"]]],[13,\"spots\",[1,[5,\"6.5\"],\"*\",[6,\"std.abs\",[\"spotty\"]]]],[13,\"intensityCalc\",[1,[5,\"4\"],\"-\",[1,[5,\"3\"],\"*\",[6,\"std.clamp\",[\"intensity\",[5,\"0\"],[5,\"1\"]]]]]],[13,\"dens\",[1,[5,\"6\"],\"*\",\"density\"]],[13,\"layer1\",[6,\"godraysRayLayer\",[\"frame\",\"animTime\",\"spots\",\"intensityCalc\",\"dens\",[6,\"d.vec4f\",[[5,\"1\"],[5,\"3\"],[5,\"0.5\"],[5,\"2\"]]],[6,\"d.vec2f\",[[5,\"5\"],[5,\"4\"]]]]]],[13,\"layer2\",[6,\"godraysRayLayer\",[\"frame\",\"animTime\",\"spots\",\"intensityCalc\",\"dens\",[6,\"d.vec4f\",[[5,\"1.4\"],[5,\"2.5\"],[5,\"0.7\"],[5,\"1.8\"]]],[6,\"d.vec2f\",[[5,\"4.5\"],[5,\"3.5\"]]]]]],[10,[6,\"std.clamp\",[[1,\"layer1\",\"+\",[1,\"layer2\",\"*\",[5,\"0.7\"]]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.abs\":()=>re,\"std.clamp\":()=>G,godraysRayLayer:()=>w0,\"d.vec4f\":()=>S,\"d.vec2f\":()=>m}})&&e.f)({})),Vte=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(r,t.w),a=__tsover_add(o,__tsover_mul(s.w,__tsover_sub(1,o))),i=G(a,.001,1),l=t.xyz.mul(o),c=s.xyz.mul(s.w).mul(__tsover_sub(1,o));return S(l.add(c).div(i),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rayColor\"},{type:\"i\",name:\"bgColor\"},{type:\"i\",name:\"coverage\"}],body:[0,[[13,\"rayA\",[1,\"coverage\",\"*\",[7,\"rayColor\",\"w\"]]],[13,\"finalAlpha\",[1,\"rayA\",\"+\",[1,[7,\"bgColor\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"rayA\"]]]],[13,\"safeAlpha\",[6,\"std.clamp\",[\"finalAlpha\",[5,\"0.001\"],[5,\"1\"]]]],[13,\"rayContribution\",[6,[7,[7,\"rayColor\",\"xyz\"],\"mul\"],[\"rayA\"]]],[13,\"bgContribution\",[6,[7,[6,[7,[7,\"bgColor\",\"xyz\"],\"mul\"],[[7,\"bgColor\",\"w\"]]],\"mul\"],[[1,[5,\"1\"],\"-\",\"rayA\"]]]],[13,\"finalColor\",[6,[7,[6,[7,\"rayContribution\",\"add\"],[\"bgContribution\"]],\"div\"],[\"safeAlpha\"]]],[10,[6,\"d.vec4f\",[\"finalColor\",\"finalAlpha\"]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({})),Nte=w.fn([n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Aa(m(__tsover_mul(t,.9),__tsover_add(__tsover_mul(s,.53),11.7))),a=Aa(m(__tsover_add(__tsover_mul(t,2.7),41.3),__tsover_add(__tsover_mul(s,.29),5.1))),i=__tsover_add(__tsover_mul(o,.65),__tsover_mul(a,.35));return S(K(1,__tsover_add(.25,__tsover_mul(1.5,i)),r),Aa(m(__tsover_add(__tsover_mul(t,.13),3.1),__tsover_add(__tsover_mul(s,.41),27))),Aa(m(__tsover_add(__tsover_mul(t,.09),17.7),__tsover_add(__tsover_mul(s,.61),8.4))),Aa(m(__tsover_add(__tsover_mul(t,.17),51.2),__tsover_add(__tsover_mul(s,.23),2.9))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"flicker\"}],body:[0,[[13,\"nA\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,\"t\",\"*\",[5,\"0.9\"]],[1,[1,\"seed\",\"*\",[5,\"0.53\"]],\"+\",[5,\"11.7\"]]]]]]],[13,\"nB\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,\"t\",\"*\",[5,\"2.7\"]],\"+\",[5,\"41.3\"]],[1,[1,\"seed\",\"*\",[5,\"0.29\"]],\"+\",[5,\"5.1\"]]]]]]],[13,\"breathe\",[1,[1,\"nA\",\"*\",[5,\"0.65\"]],\"+\",[1,\"nB\",\"*\",[5,\"0.35\"]]]],[13,\"flickerMod\",[6,\"std.mix\",[[5,\"1\"],[1,[5,\"0.25\"],\"+\",[1,[5,\"1.5\"],\"*\",\"breathe\"]],\"flicker\"]]],[13,\"evo1\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,\"t\",\"*\",[5,\"0.13\"]],\"+\",[5,\"3.1\"]],[1,[1,\"seed\",\"*\",[5,\"0.41\"]],\"+\",[5,\"27\"]]]]]]],[13,\"evo2\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,\"t\",\"*\",[5,\"0.09\"]],\"+\",[5,\"17.7\"]],[1,[1,\"seed\",\"*\",[5,\"0.61\"]],\"+\",[5,\"8.4\"]]]]]]],[13,\"evo3\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,\"t\",\"*\",[5,\"0.17\"]],\"+\",[5,\"51.2\"]],[1,[1,\"seed\",\"*\",[5,\"0.23\"]],\"+\",[5,\"2.9\"]]]]]]],[10,[6,\"d.vec4f\",[\"flickerMod\",\"evo1\",\"evo2\",\"evo3\"]]]]]},externals:{\"noise.value12\":()=>Aa,\"d.vec2f\":()=>m,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),$te=w.fn([n,n,n,S],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=o.z,i=B(r,.05),l=__tsover_mul(i,__tsover_add(1.5,__tsover_mul(.7,a))),c=__tsover_div(t,i),d=__tsover_div(s,l);return m(D1(c,d,1.9),__tsover_mul(D1(c,d,.45),.22))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"u\"},{type:\"i\",name:\"v\"},{type:\"i\",name:\"spread\"},{type:\"i\",name:\"drift\"}],body:[0,[[13,\"evo2\",[7,\"drift\",\"z\"]],[13,\"sp\",[6,\"std.max\",[\"spread\",[5,\"0.05\"]]]],[13,\"elong\",[1,\"sp\",\"*\",[1,[5,\"1.5\"],\"+\",[1,[5,\"0.7\"],\"*\",\"evo2\"]]]],[13,\"du\",[1,\"u\",\"/\",\"sp\"]],[13,\"dv\",[1,\"v\",\"/\",\"elong\"]],[13,\"main\",[6,\"lightfields.anisotropicGaussianSpot\",[\"du\",\"dv\",[5,\"1.9\"]]]],[13,\"shoulder\",[1,[6,\"lightfields.anisotropicGaussianSpot\",[\"du\",\"dv\",[5,\"0.45\"]]],\"*\",[5,\"0.22\"]]],[10,[6,\"d.vec2f\",[\"main\",\"shoulder\"]]]]]},externals:{\"std.max\":()=>B,\"lightfields.anisotropicGaussianSpot\":()=>D1,\"d.vec2f\":()=>m}})&&e.f)({})),Xte=w.fn([n,n,n,n,S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=a.y,l=a.z,c=a.w,d=B(r,.05),u=__tsover_mul(d,__tsover_add(1.5,__tsover_mul(.7,l))),p=__tsover_div(s,u),_=Tt(__tsover_mul(__tsover_mul(p,p),-.55)),f=__tsover_mul(d,__tsover_add(.42,__tsover_mul(.22,i))),h=B(__tsover_mul(d,__tsover_add(.07,__tsover_mul(.07,c))),.008),g=__tsover_mul(m0(t,f,h),_),y=__tsover_mul(d,__tsover_add(.8,__tsover_mul(.3,i))),b=B(__tsover_mul(d,__tsover_add(.16,__tsover_mul(.12,c))),.015),x=__tsover_mul(__tsover_mul(m0(t,y,b),_),.45);return __tsover_mul(__tsover_add(g,x),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"u\"},{type:\"i\",name:\"v\"},{type:\"i\",name:\"spread\"},{type:\"i\",name:\"streaks\"},{type:\"i\",name:\"drift\"}],body:[0,[[13,\"evo1\",[7,\"drift\",\"y\"]],[13,\"evo2\",[7,\"drift\",\"z\"]],[13,\"evo3\",[7,\"drift\",\"w\"]],[13,\"sp\",[6,\"std.max\",[\"spread\",[5,\"0.05\"]]]],[13,\"elong\",[1,\"sp\",\"*\",[1,[5,\"1.5\"],\"+\",[1,[5,\"0.7\"],\"*\",\"evo2\"]]]],[13,\"dv\",[1,\"v\",\"/\",\"elong\"]],[13,\"alongFade\",[6,\"std.exp\",[[1,[1,\"dv\",\"*\",\"dv\"],\"*\",[4,\"-\",[5,\"0.55\"]]]]]],[13,\"s1c\",[1,\"sp\",\"*\",[1,[5,\"0.42\"],\"+\",[1,[5,\"0.22\"],\"*\",\"evo1\"]]]],[13,\"s1w\",[6,\"std.max\",[[1,\"sp\",\"*\",[1,[5,\"0.07\"],\"+\",[1,[5,\"0.07\"],\"*\",\"evo3\"]]],[5,\"0.008\"]]]],[13,\"streak1\",[1,[6,\"lightfields.streakBand\",[\"u\",\"s1c\",\"s1w\"]],\"*\",\"alongFade\"]],[13,\"s2c\",[1,\"sp\",\"*\",[1,[5,\"0.8\"],\"+\",[1,[5,\"0.3\"],\"*\",\"evo1\"]]]],[13,\"s2w\",[6,\"std.max\",[[1,\"sp\",\"*\",[1,[5,\"0.16\"],\"+\",[1,[5,\"0.12\"],\"*\",\"evo3\"]]],[5,\"0.015\"]]]],[13,\"streak2\",[1,[1,[6,\"lightfields.streakBand\",[\"u\",\"s2c\",\"s2w\"]],\"*\",\"alongFade\"],\"*\",[5,\"0.45\"]]],[10,[1,[1,\"streak1\",\"+\",\"streak2\"],\"*\",\"streaks\"]]]]},externals:{\"std.max\":()=>B,\"std.exp\":()=>Tt,\"lightfields.streakBand\":()=>m0}})&&e.f)({})),Hte=w.fn([n,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return B(__tsover_add(t,__tsover_mul(__tsover_sub(Ys(s.mul(1024).add(m(r,__tsover_mul(r,1.7)))),.5),.012)),0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"heat\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"dithered\",[1,\"heat\",\"+\",[1,[1,[6,\"noise.hash12\",[[6,[7,[6,[7,\"uv\",\"mul\"],[[5,\"1024\"]]],\"add\"],[[6,\"d.vec2f\",[\"t\",[1,\"t\",\"*\",[5,\"1.7\"]]]]]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.012\"]]]],[10,[6,\"std.max\",[\"dithered\",[5,\"0\"]]]]]]},externals:{\"noise.hash12\":()=>Ys,\"d.vec2f\":()=>m,\"std.max\":()=>B}})&&e.f)({})),jte=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(t,s),o=__tsover_mul(Re(__tsover_mul(r,.5)),2);return K(__tsover_sub(1,re(__tsover_sub(o,1))),.5,be(.5,1.5,__tsover_mul(dv(t,0),s)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"cycles\"}],body:[0,[[13,\"s\",[1,\"t\",\"*\",\"cycles\"]],[13,\"m\",[1,[6,\"std.fract\",[[1,\"s\",\"*\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"band\",[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,\"m\",\"-\",[5,\"1\"]]]]]],[13,\"fp\",[1,[6,\"footprint1\",[\"t\",[5,\"0\"]]],\"*\",\"cycles\"]],[10,[6,\"std.mix\",[\"band\",[5,\"0.5\"],[6,\"std.smoothstep\",[[5,\"0.5\"],[5,\"1.5\"],\"fp\"]]]]]]]},externals:{\"std.fract\":()=>Re,\"std.abs\":()=>re,footprint1:()=>dv,\"std.mix\":()=>K,\"std.smoothstep\":()=>be}})&&e.f)({}));function P4(e,t){return{guarded:e,with(s){return P4(e.with(s),t)},dispatch(){if(!t)throw new Error(\"[gpu] KitComputePipeline.dispatch(): no pre-bound size \\u2014 pass opts.size to createGuardedCompute or call dispatchThreads(...) directly\");e.dispatchThreads(...t)},dispatchThreads(...s){e.dispatchThreads(...s)}}}function wr(e,t,s={}){let r=(globalThis.__TYPEGPU_AUTONAME__??(o=>o))(e.createGuardedComputePipeline(t),\"guarded\");return s.bindGroup&&(r=r.with(s.bindGroup)),P4(r,s.size)}function C4(e){return{dispatch(t){for(let s of t)typeof s==\"function\"?s():s.dispatch()}}}function ap(e,t){let s=!1;return{a:e,b:t,orientation:()=>s?1:0,readSource:()=>s?t:e,writeTarget:()=>s?e:t,swap(){s=!s},reset(){s=!1},groups(a){let i=a(e,t),l=a(t,e);return()=>s?l:i},perSide(a){let i=a(e),l=a(t);return{read:()=>s?l:i,written:()=>s?i:l}}}}function pr(e,t,s){return(globalThis.__TYPEGPU_AUTONAME__??(r=>r))(e.createBuffer(Fe(t,s)),\"buffer\").$usage(\"storage\")}var xv=bt,M4=24,Wh=1024,Il=.5,Yu=\"rgba16float\",qh=\"rgba16float\",ri=\"rgba32float\";function Kte(e){let t=e/3,s=e*2+1,r=[],o=0;for(let a=-e;a<=e;a++){let i=Math.exp(-(a*a)/(2*t*t));r.push(i),o+=i}for(let a=0;a<s;a++)r[a]/=o;return r}function _S(e,t){let s=e*2+1,r=Math.max(1,Math.min(e,Math.ceil(t*3))),o=new Array(s).fill(0),a=0;for(let i=-e;i<=e;i++)if(Math.abs(i)<=r){let l=Math.exp(-(i*i)/(2*t*t));o[i+e]=l,a+=l}for(let i=0;i<s;i++)o[i]/=a;return{weights:o,activeHalf:r}}function Qte(){return gt({activeHalf:j,inputWidth:n,inputHeight:n})}function Zte(){return gt({activeHalf:j})}function Jte(e,t,s){let r=e*2+1,o=e,a=Qte(),i=Zte(),l=(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(w.bindGroupLayout({input:{texture:Zt(n)},intermediate:{storageTexture:zt(Yu,\"write-only\")},weights:{storage:Fe(n,r),access:\"readonly\"},params:{uniform:a}}),\"hLayout\"),c=(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(w.bindGroupLayout({src:{storageTexture:zt(Yu,\"read-only\")},output:{storageTexture:zt(qh,\"write-only\")},weights:{storage:Fe(n,r),access:\"readonly\"},params:{uniform:i}}),\"vLayout\");return{hLayout:l,vLayout:c,kernelH:w.fn([M,M])((d=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(d.f=((u,p)=>{\"use gpu\";let _=l.$.params,f=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(u),.5),_.inputWidth),t),.5),h=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(p),.5),_.inputHeight),s),.5),g=j(__tsover_sub(_.inputWidth,1)),y=j(__tsover_sub(_.inputHeight,1)),b=j(Ut(f)),x=G(j(Ut(h)),0,y),P=_.activeHalf,C=__tsover_add(__tsover_mul(P,2),1),E=S(0,0,0,0);for(let R=0;R<C;R++){let U=__tsover_sub(R,P),L=G(__tsover_add(b,U),0,g),k=Ye(l.$.input,fe(M(L),M(x)),0);E=E.add(k.mul(l.$.weights[__tsover_add(U,o)]))}lt(l.$.intermediate,fe(u,p),E)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"hLayout\",\"$\"],\"params\"]],[13,\"inputCx\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputWidth\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]]],[13,\"inputCy\",[1,[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputHeight\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"inputWm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[13,\"inputCxI\",[6,\"d.i32\",[[6,\"std.round\",[\"inputCx\"]]]]],[13,\"inputCyI\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCy\"]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"ah\",[7,\"p\",\"activeHalf\"]],[13,\"count\",[1,[1,\"ah\",\"*\",[5,\"2\"]],\"+\",[5,\"1\"]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"count\"],[102,\"++\",\"i\"],[0,[[13,\"off\",[1,\"i\",\"-\",\"ah\"]],[13,\"sampleX\",[6,\"std.clamp\",[[1,\"inputCxI\",\"+\",\"off\"],[5,\"0\"],\"inputWm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sampleX\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"hLayout\",\"$\"],\"weights\"],[1,\"off\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"hLayout\",\"$\"],\"intermediate\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]},externals:{hLayout:()=>l,\"d.f32\":()=>n,computeWidth:()=>t,computeHeight:()=>s,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.clamp\":()=>G,\"d.vec4f\":()=>S,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,HALF_KERNEL:()=>o,\"std.textureStore\":()=>lt}})&&d.f)({})).$name(\"gaussianBlurH\"),kernelV:w.fn([M,M])((d=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(d.f=((u,p)=>{\"use gpu\";let _=c.$.params.activeHalf,f=__tsover_add(__tsover_mul(_,2),1),h=j(p),g=S(0,0,0,0);for(let y=0;y<f;y++){let b=__tsover_sub(y,_),x=G(__tsover_add(h,b),0,__tsover_sub(s,1)),P=Ye(c.$.src,fe(u,M(x)));g=g.add(P.mul(c.$.weights[__tsover_add(b,o)]))}lt(c.$.output,fe(u,p),g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"av\",[7,[7,[7,\"vLayout\",\"$\"],\"params\"],\"activeHalf\"]],[13,\"count\",[1,[1,\"av\",\"*\",[5,\"2\"]],\"+\",[5,\"1\"]]],[13,\"cyi\",[6,\"d.i32\",[\"cy\"]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"count\"],[102,\"++\",\"i\"],[0,[[13,\"off\",[1,\"i\",\"-\",\"av\"]],[13,\"sampleY\",[6,\"std.clamp\",[[1,\"cyi\",\"+\",\"off\"],[5,\"0\"],[1,\"computeHeight\",\"-\",[5,\"1\"]]]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",[6,\"d.u32\",[\"sampleY\"]]]]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"vLayout\",\"$\"],\"weights\"],[1,\"off\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"vLayout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]},externals:{vLayout:()=>c,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.clamp\":()=>G,computeHeight:()=>s,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,HALF_KERNEL:()=>o,\"std.textureStore\":()=>lt}})&&d.f)({})).$name(\"gaussianBlurV\"),HParams:a,VParams:i,KERNEL_SIZE:r}}function Vh(e,t,s,r,o,a=M4,i=Wh,l=640){let c=a,d=Jte(a,i,l),{hLayout:u,vLayout:p,kernelH:_,kernelV:f,KERNEL_SIZE:h}=d,g=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createTexture({size:[i,l],format:Yu}).$usage(\"storage\"),\"intermediateTex\"),y=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createTexture({size:[i,l],format:qh}).$usage(\"storage\",\"sampled\"),\"outputTex\"),b=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createBuffer(Fe(n,h)).$usage(\"storage\"),\"weightsHBuf\"),x=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createBuffer(Fe(n,h)).$usage(\"storage\"),\"weightsVBuf\"),P=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createUniform(d.HParams),\"paramsH\"),C=(globalThis.__TYPEGPU_AUTONAME__??(V=>V))(e.createUniform(d.VParams),\"paramsV\");o(()=>{g.destroy(),y.destroy()});let E=e.createBindGroup(p,{src:g,output:y,weights:x,params:C.buffer}),R=wr(e,(V=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(V.f=((X,Q)=>{\"use gpu\";_(X,Q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernelH\",[\"cx\",\"cy\"]]]]},externals:{kernelH:()=>_}})&&V.f)({}),{size:[i,l]}),U=[R,wr(e,(V=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(V.f=((X,Q)=>{\"use gpu\";f(X,Q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernelV\",[\"cx\",\"cy\"]]]]},externals:{kernelV:()=>f}})&&V.f)({}),{size:[i,l],bindGroup:E})];function L(V){let X=e.createBindGroup(u,{input:V,intermediate:g,weights:b,params:P.buffer});U[0]=R.with(X)}t!=null&&L(t);let k=r/l,D=s,O=r,F=-1;function q(){let V=F<0?4:F,X=Math.max(V*.5,.001),Q=Math.max(X/k,.001),te=_S(c,X),J=_S(c,Q);b.write(te.weights),x.write(J.weights),P.write({activeHalf:te.activeHalf,inputWidth:D,inputHeight:O}),C.write({activeHalf:J.activeHalf})}function Y(V){Math.abs(V-F)<.01||(F=V,q())}return Y(4),{computeSteps:U,outputTexture:y,updateRadius:Y,computeWidth:i,computeHeight:l,setInputTexture:L,setInputDimensions:(V,X)=>{D=V,O=X,P.patch({inputWidth:V,inputHeight:X});let Q=X/l;Math.abs(Q-k)>.001&&(k=Q,q())}}}function ese(){return gt({inputWidth:n,inputHeight:n,jitter:n,dispersion:n})}function tse(){return gt({scaleY:n,jitter:n,dispersion:n})}function sse(e,t,s,r={}){let o=e*2+1,a=e,i=1/a,l=r.chromatic===!0,c=ese(),d=tse(),u=(globalThis.__TYPEGPU_AUTONAME__??(y=>y))(w.bindGroupLayout({blurMap:{storageTexture:zt(ri,\"read-only\")},input:{texture:Zt(n)},intermediate:{storageTexture:zt(Yu,\"write-only\")},weights:{storage:Fe(n,o),access:\"readonly\"},params:{uniform:c}}),\"hLayout\"),p=(globalThis.__TYPEGPU_AUTONAME__??(y=>y))(w.bindGroupLayout({blurMap:{storageTexture:zt(ri,\"read-only\")},src:{storageTexture:zt(Yu,\"read-only\")},output:{storageTexture:zt(qh,\"write-only\")},weights:{storage:Fe(n,o),access:\"readonly\"},params:{uniform:d}}),\"vLayout\"),_=w.fn([M,M])((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";let P=u.$.params,C=Ye(u.$.blurMap,fe(b,x)).r,E=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(b),.5),P.inputWidth),t),.5),R=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(x),.5),P.inputHeight),s),.5),U=j(__tsover_sub(P.inputWidth,1)),L=j(__tsover_sub(P.inputHeight,1)),k=G(j(Ut(R)),0,L);if(C<Il){let D=G(j(Ut(E)),0,U),O=Ye(u.$.input,fe(M(D),M(k)),0);lt(u.$.intermediate,fe(b,x),O)}else{let D=__tsover_mul(__tsover_sub(Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(n(b),.06711056),__tsover_mul(n(x),.00583715))))),.5),P.jitter),O=S(0,0,0,0);for(let F=-a;F<=a;F++){let q=__tsover_mul(__tsover_mul(__tsover_add(n(F),D),i),C),Y=G(j(Ut(__tsover_add(E,q))),0,U),V=Ye(u.$.input,fe(M(Y),M(k)),0);O=O.add(V.mul(u.$.weights[__tsover_add(F,a)]))}lt(u.$.intermediate,fe(b,x),O)}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"hLayout\",\"$\"],\"params\"]],[13,\"blurRadius\",[7,[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]],\"r\"]],[13,\"inputCx\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputWidth\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]]],[13,\"inputCy\",[1,[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputHeight\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"inputWm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[13,\"inputCyI\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCy\"]]]],[5,\"0\"],\"inputHm1\"]]],[11,[1,\"blurRadius\",\"<\",\"PASSTHROUGH_THRESHOLD\"],[0,[[13,\"cxClamp\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCx\"]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"cxClamp\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[6,\"std.textureStore\",[[7,[7,\"hLayout\",\"$\"],\"intermediate\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"jitterH\",[1,[1,[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"*\",[5,\"0.06711056\"]],\"+\",[1,[6,\"d.f32\",[\"cy\"]],\"*\",[5,\"0.00583715\"]]]]]]]],\"-\",[5,\"0.5\"]],\"*\",[7,\"p\",\"jitter\"]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[4,\"-\",\"HALF_KERNEL\"]],[1,\"i\",\"<=\",\"HALF_KERNEL\"],[102,\"++\",\"i\"],[0,[[13,\"offset\",[1,[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",\"jitterH\"],\"*\",\"invHalf\"],\"*\",\"blurRadius\"]],[13,\"sampleX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",\"offset\"]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sampleX\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"hLayout\",\"$\"],\"weights\"],[1,\"i\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"hLayout\",\"$\"],\"intermediate\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]]]]},externals:{hLayout:()=>u,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.f32\":()=>n,computeWidth:()=>t,computeHeight:()=>s,\"d.i32\":()=>j,\"std.clamp\":()=>G,\"std.round\":()=>Ut,PASSTHROUGH_THRESHOLD:()=>Il,\"d.u32\":()=>M,\"std.textureStore\":()=>lt,\"std.fract\":()=>Re,\"d.vec4f\":()=>S,HALF_KERNEL:()=>a,invHalf:()=>i}})&&y.f)({})).$name(\"variableBlurH\"),f=w.fn([M,M])((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";let P=u.$.params,C=Ye(u.$.blurMap,fe(b,x)).r,E=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(b),.5),P.inputWidth),t),.5),R=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(x),.5),P.inputHeight),s),.5),U=j(__tsover_sub(P.inputWidth,1)),L=j(__tsover_sub(P.inputHeight,1)),k=G(j(Ut(R)),0,L);if(C<Il){let D=G(j(Ut(E)),0,U),O=Ye(u.$.input,fe(M(D),M(k)),0);lt(u.$.intermediate,fe(b,x),O)}else{let D=__tsover_mul(__tsover_sub(Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(n(b),.06711056),__tsover_mul(n(x),.00583715))))),.5),P.jitter),O=__tsover_mul(C,__tsover_add(1,P.dispersion)),F=__tsover_mul(C,__tsover_sub(1,P.dispersion)),q=S(0,0,0,0);for(let Y=-a;Y<=a;Y++){let V=__tsover_mul(__tsover_add(n(Y),D),i),X=G(j(Ut(__tsover_add(E,__tsover_mul(V,C)))),0,U),Q=G(j(Ut(__tsover_add(E,__tsover_mul(V,O)))),0,U),te=G(j(Ut(__tsover_add(E,__tsover_mul(V,F)))),0,U),J=Ye(u.$.input,fe(M(X),M(k)),0),oe=Ye(u.$.input,fe(M(Q),M(k)),0),le=Ye(u.$.input,fe(M(te),M(k)),0),se=S(oe.x,J.y,le.z,J.w);q=q.add(se.mul(u.$.weights[__tsover_add(Y,a)]))}lt(u.$.intermediate,fe(b,x),q)}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"hLayout\",\"$\"],\"params\"]],[13,\"blurRadius\",[7,[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]],\"r\"]],[13,\"inputCx\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputWidth\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]]],[13,\"inputCy\",[1,[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputHeight\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"inputWm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[13,\"inputCyI\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCy\"]]]],[5,\"0\"],\"inputHm1\"]]],[11,[1,\"blurRadius\",\"<\",\"PASSTHROUGH_THRESHOLD\"],[0,[[13,\"cxClamp\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCx\"]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"cxClamp\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[6,\"std.textureStore\",[[7,[7,\"hLayout\",\"$\"],\"intermediate\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"jitterH\",[1,[1,[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"*\",[5,\"0.06711056\"]],\"+\",[1,[6,\"d.f32\",[\"cy\"]],\"*\",[5,\"0.00583715\"]]]]]]]],\"-\",[5,\"0.5\"]],\"*\",[7,\"p\",\"jitter\"]]],[13,\"radiusR\",[1,\"blurRadius\",\"*\",[1,[5,\"1\"],\"+\",[7,\"p\",\"dispersion\"]]]],[13,\"radiusB\",[1,\"blurRadius\",\"*\",[1,[5,\"1\"],\"-\",[7,\"p\",\"dispersion\"]]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[4,\"-\",\"HALF_KERNEL\"]],[1,\"i\",\"<=\",\"HALF_KERNEL\"],[102,\"++\",\"i\"],[0,[[13,\"t\",[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",\"jitterH\"],\"*\",\"invHalf\"]],[13,\"xG\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[1,\"t\",\"*\",\"blurRadius\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"xR\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[1,\"t\",\"*\",\"radiusR\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"xB\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[1,\"t\",\"*\",\"radiusB\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"texG\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"xG\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[13,\"texR\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"xR\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[13,\"texB\",[6,\"std.textureLoad\",[[7,[7,\"hLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"xB\"]],[6,\"d.u32\",[\"inputCyI\"]]]],[5,\"0\"]]]],[13,\"texel\",[6,\"d.vec4f\",[[7,\"texR\",\"x\"],[7,\"texG\",\"y\"],[7,\"texB\",\"z\"],[7,\"texG\",\"w\"]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"hLayout\",\"$\"],\"weights\"],[1,\"i\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"hLayout\",\"$\"],\"intermediate\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]]]]},externals:{hLayout:()=>u,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.f32\":()=>n,computeWidth:()=>t,computeHeight:()=>s,\"d.i32\":()=>j,\"std.clamp\":()=>G,\"std.round\":()=>Ut,PASSTHROUGH_THRESHOLD:()=>Il,\"d.u32\":()=>M,\"std.textureStore\":()=>lt,\"std.fract\":()=>Re,\"d.vec4f\":()=>S,HALF_KERNEL:()=>a,invHalf:()=>i}})&&y.f)({})).$name(\"variableBlurHChromatic\"),h=w.fn([M,M])((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";let P=Ye(p.$.blurMap,fe(b,x)).r;if(P<Il){let C=Ye(p.$.src,fe(b,x));lt(p.$.output,fe(b,x),C)}else{let C=j(x),E=__tsover_div(P,p.$.params.scaleY),R=__tsover_mul(__tsover_sub(Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(n(b),.00583715),__tsover_mul(n(x),.06711056))))),.5),p.$.params.jitter),U=S(0,0,0,0);for(let L=-a;L<=a;L++){let k=__tsover_mul(__tsover_mul(__tsover_add(n(L),R),i),E),D=G(__tsover_add(C,j(Ut(k))),0,__tsover_sub(s,1)),O=Ye(p.$.src,fe(b,M(D)));U=U.add(O.mul(p.$.weights[__tsover_add(L,a)]))}lt(p.$.output,fe(b,x),U)}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"blurRadius\",[7,[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]],\"r\"]],[11,[1,\"blurRadius\",\"<\",\"PASSTHROUGH_THRESHOLD\"],[0,[[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]]],[6,\"std.textureStore\",[[7,[7,\"vLayout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"yi\",[6,\"d.i32\",[\"cy\"]]],[13,\"radiusComputeY\",[1,\"blurRadius\",\"/\",[7,[7,[7,\"vLayout\",\"$\"],\"params\"],\"scaleY\"]]],[13,\"jitterV\",[1,[1,[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"*\",[5,\"0.00583715\"]],\"+\",[1,[6,\"d.f32\",[\"cy\"]],\"*\",[5,\"0.06711056\"]]]]]]]],\"-\",[5,\"0.5\"]],\"*\",[7,[7,[7,\"vLayout\",\"$\"],\"params\"],\"jitter\"]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[4,\"-\",\"HALF_KERNEL\"]],[1,\"i\",\"<=\",\"HALF_KERNEL\"],[102,\"++\",\"i\"],[0,[[13,\"offset\",[1,[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",\"jitterV\"],\"*\",\"invHalf\"],\"*\",\"radiusComputeY\"]],[13,\"sampleY\",[6,\"std.clamp\",[[1,\"yi\",\"+\",[6,\"d.i32\",[[6,\"std.round\",[\"offset\"]]]]],[5,\"0\"],[1,\"computeHeight\",\"-\",[5,\"1\"]]]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",[6,\"d.u32\",[\"sampleY\"]]]]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"vLayout\",\"$\"],\"weights\"],[1,\"i\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"vLayout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]]]]},externals:{\"std.textureLoad\":()=>Ye,vLayout:()=>p,\"d.vec2u\":()=>fe,PASSTHROUGH_THRESHOLD:()=>Il,\"std.textureStore\":()=>lt,\"d.i32\":()=>j,\"std.fract\":()=>Re,\"d.f32\":()=>n,\"d.vec4f\":()=>S,HALF_KERNEL:()=>a,invHalf:()=>i,\"std.clamp\":()=>G,\"std.round\":()=>Ut,computeHeight:()=>s,\"d.u32\":()=>M}})&&y.f)({})).$name(\"variableBlurV\"),g=w.fn([M,M])((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";let P=Ye(p.$.blurMap,fe(b,x)).r;if(P<Il){let C=Ye(p.$.src,fe(b,x));lt(p.$.output,fe(b,x),C)}else{let C=j(x),E=p.$.params,R=__tsover_div(P,E.scaleY),U=__tsover_mul(R,__tsover_add(1,E.dispersion)),L=__tsover_mul(R,__tsover_sub(1,E.dispersion)),k=__tsover_mul(__tsover_sub(Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(n(b),.00583715),__tsover_mul(n(x),.06711056))))),.5),E.jitter),D=S(0,0,0,0);for(let O=-a;O<=a;O++){let F=__tsover_mul(__tsover_add(n(O),k),i),q=G(__tsover_add(C,j(Ut(__tsover_mul(F,R)))),0,__tsover_sub(s,1)),Y=G(__tsover_add(C,j(Ut(__tsover_mul(F,U)))),0,__tsover_sub(s,1)),V=G(__tsover_add(C,j(Ut(__tsover_mul(F,L)))),0,__tsover_sub(s,1)),X=Ye(p.$.src,fe(b,M(q))),Q=Ye(p.$.src,fe(b,M(Y))),te=Ye(p.$.src,fe(b,M(V))),J=S(Q.x,X.y,te.z,X.w);D=D.add(J.mul(p.$.weights[__tsover_add(O,a)]))}lt(p.$.output,fe(b,x),D)}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"blurRadius\",[7,[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]],\"r\"]],[11,[1,\"blurRadius\",\"<\",\"PASSTHROUGH_THRESHOLD\"],[0,[[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]]]]],[6,\"std.textureStore\",[[7,[7,\"vLayout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"yi\",[6,\"d.i32\",[\"cy\"]]],[13,\"p\",[7,[7,\"vLayout\",\"$\"],\"params\"]],[13,\"radiusComputeY\",[1,\"blurRadius\",\"/\",[7,\"p\",\"scaleY\"]]],[13,\"radiusR\",[1,\"radiusComputeY\",\"*\",[1,[5,\"1\"],\"+\",[7,\"p\",\"dispersion\"]]]],[13,\"radiusB\",[1,\"radiusComputeY\",\"*\",[1,[5,\"1\"],\"-\",[7,\"p\",\"dispersion\"]]]],[13,\"jitterV\",[1,[1,[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"*\",[5,\"0.00583715\"]],\"+\",[1,[6,\"d.f32\",[\"cy\"]],\"*\",[5,\"0.06711056\"]]]]]]]],\"-\",[5,\"0.5\"]],\"*\",[7,\"p\",\"jitter\"]]],[12,\"sum\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[4,\"-\",\"HALF_KERNEL\"]],[1,\"i\",\"<=\",\"HALF_KERNEL\"],[102,\"++\",\"i\"],[0,[[13,\"t\",[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",\"jitterV\"],\"*\",\"invHalf\"]],[13,\"yG\",[6,\"std.clamp\",[[1,\"yi\",\"+\",[6,\"d.i32\",[[6,\"std.round\",[[1,\"t\",\"*\",\"radiusComputeY\"]]]]]],[5,\"0\"],[1,\"computeHeight\",\"-\",[5,\"1\"]]]]],[13,\"yR\",[6,\"std.clamp\",[[1,\"yi\",\"+\",[6,\"d.i32\",[[6,\"std.round\",[[1,\"t\",\"*\",\"radiusR\"]]]]]],[5,\"0\"],[1,\"computeHeight\",\"-\",[5,\"1\"]]]]],[13,\"yB\",[6,\"std.clamp\",[[1,\"yi\",\"+\",[6,\"d.i32\",[[6,\"std.round\",[[1,\"t\",\"*\",\"radiusB\"]]]]]],[5,\"0\"],[1,\"computeHeight\",\"-\",[5,\"1\"]]]]],[13,\"texG\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",[6,\"d.u32\",[\"yG\"]]]]]]],[13,\"texR\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",[6,\"d.u32\",[\"yR\"]]]]]]],[13,\"texB\",[6,\"std.textureLoad\",[[7,[7,\"vLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",[6,\"d.u32\",[\"yB\"]]]]]]],[13,\"texel\",[6,\"d.vec4f\",[[7,\"texR\",\"x\"],[7,\"texG\",\"y\"],[7,\"texB\",\"z\"],[7,\"texG\",\"w\"]]]],[2,\"sum\",\"=\",[6,[7,\"sum\",\"add\"],[[6,[7,\"texel\",\"mul\"],[[8,[7,[7,\"vLayout\",\"$\"],\"weights\"],[1,\"i\",\"+\",\"HALF_KERNEL\"]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"vLayout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"sum\"]]]]]]]},externals:{\"std.textureLoad\":()=>Ye,vLayout:()=>p,\"d.vec2u\":()=>fe,PASSTHROUGH_THRESHOLD:()=>Il,\"std.textureStore\":()=>lt,\"d.i32\":()=>j,\"std.fract\":()=>Re,\"d.f32\":()=>n,\"d.vec4f\":()=>S,HALF_KERNEL:()=>a,invHalf:()=>i,\"std.clamp\":()=>G,\"std.round\":()=>Ut,computeHeight:()=>s,\"d.u32\":()=>M}})&&y.f)({})).$name(\"variableBlurVChromatic\");return{hLayout:u,vLayout:p,kernelH:l?f:_,kernelV:l?g:h,HParams:c,VParams:d,KERNEL_SIZE:o}}function E4(e,t,s,r,o,a=M4,i=Wh,l=640,c){let d=a,u=sse(a,i,l,{chromatic:c?.chromatic}),{hLayout:p,vLayout:_,kernelH:f,kernelV:h,KERNEL_SIZE:g}=u,y=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createTexture({size:[i,l],format:ri}).$usage(\"storage\"),\"blurMapTex\"),b=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createTexture({size:[i,l],format:Yu}).$usage(\"storage\"),\"intermediateTex\"),x=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createTexture({size:[i,l],format:qh}).$usage(\"storage\",\"sampled\"),\"outputTex\"),P=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createBuffer(Fe(n,g)).$usage(\"storage\"),\"weightsBuf\");P.write(Kte(d));let C=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createUniform(u.HParams),\"paramsH\"),E=(globalThis.__TYPEGPU_AUTONAME__??(O=>O))(e.createUniform(u.VParams),\"paramsV\"),R={jitter:c?.jitter??0,dispersion:0};C.write({inputWidth:s,inputHeight:r,...R}),E.write({scaleY:r/l,...R}),o(()=>{y.destroy(),b.destroy(),x.destroy()});let U=e.createBindGroup(_,{blurMap:y,src:b,output:x,weights:P,params:E.buffer}),L=wr(e,(O=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(O.f=((F,q)=>{\"use gpu\";f(F,q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernelH\",[\"cx\",\"cy\"]]]]},externals:{kernelH:()=>f}})&&O.f)({}),{size:[i,l]}),k=[L,wr(e,(O=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(O.f=((F,q)=>{\"use gpu\";h(F,q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernelV\",[\"cx\",\"cy\"]]]]},externals:{kernelV:()=>h}})&&O.f)({}),{size:[i,l],bindGroup:U})];function D(O){let F=e.createBindGroup(p,{blurMap:y,input:O,intermediate:b,weights:P,params:C.buffer});k[0]=L.with(F)}return t!=null&&D(t),{computeSteps:k,outputTexture:x,blurMapTexture:y,computeWidth:i,computeHeight:l,setInputTexture:D,setInputDimensions:(O,F)=>{C.patch({inputWidth:O,inputHeight:F}),E.patch({scaleY:F/l})},setDetail:(O,F)=>{O===R.jitter&&F===R.dispersion||(R.jitter=O,R.dispersion=F,C.patch({jitter:O,dispersion:F}),E.patch({jitter:O,dispersion:F}))}}}function rse(e,t){let s=Number((t*t).toPrecision(15)),r=e-1,o=Array.from({length:e},(i,l)=>{let c=(l/r-.5)*2;return Math.exp(-.5*c*c/s)}),a=o.reduce((i,l)=>i+l);return o.map(i=>i/a)}function qb(e){let{weights:t,tapCoord:s,sample:r,component:o}=e,a;for(let i=0;i<t.length;i++){let l=r(s(i)),c=(o?l.member(o):l).mul(t[i]);a=a?a.add(c):c}return a}var np={inputWidth:n,inputHeight:n},y_={inputMin:n,inputMax:n,outputMin:n,outputMax:n,curve:n},fS=new Map;function b_(e){let t=fS.get(e);if(t)return t;let s=w.fn([S],n)((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=(o=>{\"use gpu\";return e===\"alpha\"?o.w:e===\"alphaInverted\"?__tsover_sub(1,o.w):e===\"luminanceInverted\"?__tsover_sub(1,Se(o.xyz,A(.2126,.7152,.0722))):Se(o.xyz,A(.2126,.7152,.0722))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sample\"}],body:[0,[[10,[105,[1,\"channel\",\"===\",[103,\"alpha\"]],[7,\"sample\",\"w\"],[105,[1,\"channel\",\"===\",[103,\"alphaInverted\"]],[1,[5,\"1\"],\"-\",[7,\"sample\",\"w\"]],[105,[1,\"channel\",\"===\",[103,\"luminanceInverted\"]],[1,[5,\"1\"],\"-\",[6,\"std.dot\",[[7,\"sample\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[6,\"std.dot\",[[7,\"sample\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]]]]]]]},externals:{channel:()=>e,\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&r.f)({})).$name(`mapSourceScalar_${e}`);return fS.set(e,s),s}var Ei=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=B(__tsover_sub(r,s),1e-4);return K(o,a,vt(G(__tsover_div(__tsover_sub(t,s),l),0,1),vt(2,__tsover_mul(-i,2))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"raw\"},{type:\"i\",name:\"inputMin\"},{type:\"i\",name:\"inputMax\"},{type:\"i\",name:\"outputMin\"},{type:\"i\",name:\"outputMax\"},{type:\"i\",name:\"curve\"}],body:[0,[[13,\"inputRange\",[6,\"std.max\",[[1,\"inputMax\",\"-\",\"inputMin\"],[5,\"0.0001\"]]]],[13,\"normalised\",[6,\"std.clamp\",[[1,[1,\"raw\",\"-\",\"inputMin\"],\"/\",\"inputRange\"],[5,\"0\"],[5,\"1\"]]]],[13,\"exponent\",[6,\"std.pow\",[[5,\"2\"],[1,[4,\"-\",\"curve\"],\"*\",[5,\"2\"]]]]],[13,\"eased\",[6,\"std.pow\",[\"normalised\",\"exponent\"]]],[10,[6,\"std.mix\",[\"outputMin\",\"outputMax\",\"eased\"]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.pow\":()=>vt,\"std.mix\":()=>K}})&&e.f)({})).$name(\"applyRemapWindow\");function Nh(e){return{inputMin:e.inputMin,inputMax:e.inputMax,outputMin:e.outputMin,outputMax:e.outputMax,curve:e.curve}}var Av=w.fn([Zt(n),M,M,m,m,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=o.x,c=o.y,d=j(__tsover_sub(l,1)),u=j(__tsover_sub(c,1)),p=S(0,0,0,0);for(let b=0;b<4;b++)for(let x=0;x<4;x++){let P=__tsover_div(__tsover_add(n(s),__tsover_div(__tsover_add(n(x),.5),4)),a.x),C=__tsover_div(__tsover_add(n(r),__tsover_div(__tsover_add(n(b),.5),4)),a.y),E=G(j(__tsover_mul(P,l)),0,d),R=G(j(__tsover_mul(C,c)),0,u);p=p.add(Ye(t,fe(M(E),M(R)),0))}p=p.mul(.0625);let _=__tsover_add(__tsover_mul(i,.5),1e-4),f=Se(p.xyz,A(.2126,.7152,.0722)),h=G(__tsover_add(__tsover_sub(f,i),_),0,__tsover_mul(_,2)),g=__tsover_div(__tsover_mul(h,h),__tsover_mul(_,4)),y=__tsover_div(B(g,__tsover_sub(f,i)),B(f,1e-4));return S(p.xyz.mul(y),__tsover_mul(p.w,y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"childTexture\"},{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"},{type:\"i\",name:\"inputSize\"},{type:\"i\",name:\"computeSize\"},{type:\"i\",name:\"threshold\"}],body:[0,[[13,\"iw\",[7,\"inputSize\",\"x\"]],[13,\"ih\",[7,\"inputSize\",\"y\"]],[13,\"inputWm1\",[6,\"d.i32\",[[1,\"iw\",\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,\"ih\",\"-\",[5,\"1\"]]]]],[12,\"sample\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"ty\",[5,\"0\"]],[1,\"ty\",\"<\",[5,\"4\"]],[102,\"++\",\"ty\"],[0,[[14,[12,\"tx\",[5,\"0\"]],[1,\"tx\",\"<\",[5,\"4\"]],[102,\"++\",\"tx\"],[0,[[13,\"su\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[1,[1,[6,\"d.f32\",[\"tx\"]],\"+\",[5,\"0.5\"]],\"/\",[5,\"4\"]]],\"/\",[7,\"computeSize\",\"x\"]]],[13,\"sv\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[1,[1,[6,\"d.f32\",[\"ty\"]],\"+\",[5,\"0.5\"]],\"/\",[5,\"4\"]]],\"/\",[7,\"computeSize\",\"y\"]]],[13,\"sx\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,\"su\",\"*\",\"iw\"]]],[5,\"0\"],\"inputWm1\"]]],[13,\"sy\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,\"sv\",\"*\",\"ih\"]]],[5,\"0\"],\"inputHm1\"]]],[2,\"sample\",\"=\",[6,[7,\"sample\",\"add\"],[[6,\"std.textureLoad\",[\"childTexture\",[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]]]]]]]]]]],[2,\"sample\",\"=\",[6,[7,\"sample\",\"mul\"],[[5,\"0.0625\"]]]],[13,\"knee\",[1,[1,\"threshold\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.0001\"]]],[13,\"lum\",[6,\"std.dot\",[[7,\"sample\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"soft\",[6,\"std.clamp\",[[1,[1,\"lum\",\"-\",\"threshold\"],\"+\",\"knee\"],[5,\"0\"],[1,\"knee\",\"*\",[5,\"2\"]]]]],[13,\"softCurve\",[1,[1,\"soft\",\"*\",\"soft\"],\"/\",[1,\"knee\",\"*\",[5,\"4\"]]]],[13,\"mask\",[1,[6,\"std.max\",[\"softCurve\",[1,\"lum\",\"-\",\"threshold\"]]],\"/\",[6,\"std.max\",[\"lum\",[5,\"0.0001\"]]]]],[10,[6,\"d.vec4f\",[[6,[7,[7,\"sample\",\"xyz\"],\"mul\"],[\"mask\"]],[1,[7,\"sample\",\"w\"],\"*\",\"mask\"]]]]]]},externals:{\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"d.f32\":()=>n,\"std.clamp\":()=>G,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.max\":()=>B}})&&e.f)({})).$name(\"bloomExtractSoftKnee\"),K3=\"rgba16float\";function k4(e,t,s){let r=(globalThis.__TYPEGPU_AUTONAME__??(a=>a))(gt({threshold:n,size:n,...np}),\"Params\"),o=(globalThis.__TYPEGPU_AUTONAME__??(a=>a))(w.bindGroupLayout({childTexture:{texture:Zt(n)},brightMap:{storageTexture:zt(K3,\"write-only\")},blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:r}}),\"layout\");return{layout:o,kernel:w.fn([M,M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";let c=o.$.params,d=Av(o.$.childTexture,i,l,m(c.inputWidth,c.inputHeight),m(e,t),c.threshold);lt(o.$.brightMap,fe(i,l),d),lt(o.$.blurMap,fe(i,l),S(c.size,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"bright\",[6,\"bloomExtractSoftKnee\",[[7,[7,\"layout\",\"$\"],\"childTexture\"],\"cx\",\"cy\",[6,\"d.vec2f\",[[7,\"p\",\"inputWidth\"],[7,\"p\",\"inputHeight\"]]],[6,\"d.vec2f\",[\"computeWidth\",\"computeHeight\"]],[7,\"p\",\"threshold\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"brightMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"bright\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"p\",\"size\"],[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>o,bloomExtractSoftKnee:()=>Av,\"d.vec2f\":()=>m,computeWidth:()=>e,computeHeight:()=>t,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&a.f)({})).$name(s),Params:r}}function ose(e,t,s,r){let o=(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(gt({threshold:n,...np,...y_}),\"Params\"),a=(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(w.bindGroupLayout({childTexture:{texture:Zt(n)},source:{texture:Zt(n)},brightMap:{storageTexture:zt(K3,\"write-only\")},blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:o}}),\"layout\"),i=b_(r);return{layout:a,kernel:w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";let u=a.$.params,p=u.inputWidth,_=u.inputHeight,f=Av(a.$.childTexture,c,d,m(p,_),m(e,t),u.threshold);lt(a.$.brightMap,fe(c,d),f);let h=__tsover_div(__tsover_add(n(c),.5),e),g=__tsover_div(__tsover_add(n(d),.5),t),y=G(j(Ut(__tsover_mul(h,p))),0,j(__tsover_sub(p,1))),b=G(j(Ut(__tsover_mul(g,_))),0,j(__tsover_sub(_,1))),x=Ei(i(Ye(a.$.source,fe(M(y),M(b)),0)),u.inputMin,u.inputMax,u.outputMin,u.outputMax,u.curve);lt(a.$.blurMap,fe(c,d),S(x,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"iw\",[7,\"p\",\"inputWidth\"]],[13,\"ih\",[7,\"p\",\"inputHeight\"]],[13,\"bright\",[6,\"bloomExtractSoftKnee\",[[7,[7,\"layout\",\"$\"],\"childTexture\"],\"cx\",\"cy\",[6,\"d.vec2f\",[\"iw\",\"ih\"]],[6,\"d.vec2f\",[\"computeWidth\",\"computeHeight\"]],[7,\"p\",\"threshold\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"brightMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"bright\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"srcX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",\"iw\"]]]]],[5,\"0\"],[6,\"d.i32\",[[1,\"iw\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",\"ih\"]]]]],[5,\"0\"],[6,\"d.i32\",[[1,\"ih\",\"-\",[5,\"1\"]]]]]]],[13,\"mapSample\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"source\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"srcX\"]],[6,\"d.u32\",[\"srcY\"]]]],[5,\"0\"]]]],[13,\"radius\",[6,\"applyRemapWindow\",[[6,\"channelScalar\",[\"mapSample\"]],[7,\"p\",\"inputMin\"],[7,\"p\",\"inputMax\"],[7,\"p\",\"outputMin\"],[7,\"p\",\"outputMax\"],[7,\"p\",\"curve\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>a,bloomExtractSoftKnee:()=>Av,\"d.vec2f\":()=>m,computeWidth:()=>e,computeHeight:()=>t,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.f32\":()=>n,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.u32\":()=>M,applyRemapWindow:()=>Ei,channelScalar:()=>i,\"d.vec4f\":()=>S}})&&l.f)({})).$name(s),Params:o}}function ase(e,t){let s=Math.max(Wh,640),r=t>0?e/t:1;return{width:Math.max(8,r>=1?s:Math.round(s*r)),height:Math.max(8,r>=1?Math.round(s/r):s)}}var $h=\"blurredTexture\";function Wu(e){return{width:Math.max(1,Math.round(e.width)),height:Math.max(1,Math.round(e.height))}}function B4(e,t){let{childNode:s,gpu:r,convertToTexture:o,registerComputeTexture:a,onCleanup:i,onResize:l,dimensions:c}=e;if(!s)return null;let d=r?.root;if(!d)return null;let u=t.outputKey??$h,p=o(s),_=Wu(c),f=Vh(d,null,_.width,_.height,i,t.halfKernel),h=a(f.outputTexture);return l(({width:g,height:y})=>{let b=Wu({width:g,height:y});f.setInputDimensions(b.width,b.height)}),{outputs:{childTexture:p,[u]:h},bindInputs:g=>{let y=g(p.key);y&&f.setInputTexture(y.texture)},getComputeNodes:()=>(f.updateRadius(t.radius()),f.computeSteps)}}function qu(e,t){let{childNode:s,gpu:r,convertToTexture:o,registerComputeTexture:a,onCleanup:i,onResize:l,dimensions:c}=e;if(!s)return null;let d=r?.root;if(!d)return null;let u=t.outputKey??$h,p=t.source,_=o(s),f=Wu(c),h=E4(d,null,f.width,f.height,i,t.halfKernel,void 0,void 0,{chromatic:t.chromatic}),g=a(h.outputTexture),y=t.buildFill(h.computeWidth,h.computeHeight),b=(globalThis.__TYPEGPU_AUTONAME__??(E=>E))(d.createUniform(y.Params),\"fillParams\"),x=h.blurMapTexture,P={size:[h.computeWidth,h.computeHeight]},C=p?wr(d,(E=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(E.f=((R,U)=>{\"use gpu\";y.kernel(R,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"fill.kernel\",[\"cx\",\"cy\"]]]]},externals:{\"fill.kernel\":()=>y.kernel}})&&E.f)({}),P):wr(d,(E=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(E.f=((R,U)=>{\"use gpu\";y.kernel(R,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"fill.kernel\",[\"cx\",\"cy\"]]]]},externals:{\"fill.kernel\":()=>y.kernel}})&&E.f)({}),{...P,bindGroup:d.createBindGroup(y.layout,{blurMap:x,params:b.buffer})});return l(({width:E,height:R})=>{f=Wu({width:E,height:R}),h.setInputDimensions(f.width,f.height)}),{outputs:{childTexture:_,[u]:g},bindInputs:E=>{let R=E(_.key);if(R&&h.setInputTexture(R.texture),!p)return;let U=E(p.sourceTexture.key);if(U){let L=d.createBindGroup(y.layout,{source:U.texture,blurMap:x,params:b.buffer});C=C.with(L)}},getComputeNodes:()=>{if(b.write(t.fillValues(f,p?.window())),t.detail){let E=t.detail();h.setDetail(E.jitter,E.dispersion)}return[C,...h.computeSteps]}}}function z4(e,t){let{childNode:s,gpu:r,convertToTexture:o,registerComputeTexture:a,onCleanup:i,onResize:l,dimensions:c}=e;if(!s)return null;let d=r?.root;if(!d)return null;let u=t.outputKey??$h,p=t.mapInfo??null,_=o(s),f=Wu(c),h=ase(f.width,f.height),g=(globalThis.__TYPEGPU_AUTONAME__??(E=>E))(d.createTexture({size:[h.width,h.height],format:K3}).$usage(\"storage\",\"sampled\"),\"brightBuffer\");i(()=>g.destroy());let y=E4(d,g,h.width,h.height,i,void 0,h.width,h.height,{jitter:1}),b=a(y.outputTexture);l(({width:E,height:R})=>{f=Wu({width:E,height:R})});let x=p&&t.buildExtractMap?t.buildExtractMap(h.width,h.height,p.channel):t.buildExtract(h.width,h.height),P=(globalThis.__TYPEGPU_AUTONAME__??(E=>E))(d.createUniform(x.Params),\"prepassParams\"),C=wr(d,(E=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(E.f=((R,U)=>{\"use gpu\";x.kernel(R,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"graph.kernel\",[\"cx\",\"cy\"]]]]},externals:{\"graph.kernel\":()=>x.kernel}})&&E.f)({}),{size:[h.width,h.height]});return{outputs:{childTexture:_,[u]:b},bindInputs:E=>{let R=E(_.key);if(!R)return;let U=p?E(p.sourceTexture.key):void 0;if(p&&!U)return;let L={childTexture:R.texture,brightMap:g,blurMap:y.blurMapTexture,params:P.buffer};U&&(L.source=U.texture),C=C.with(d.createBindGroup(x.layout,L))},getComputeNodes:()=>{let E=t.threshold(),R=p?{threshold:E,inputWidth:f.width,inputHeight:f.height,...Nh(p.window())}:{threshold:E,size:t.radius(),inputWidth:f.width,inputHeight:f.height};return P.write(R),[C,...y.computeSteps]}}}function x_(e,t,s){let{childNode:r,computeOutputs:o,ctx:a,convertToTexture:i}=e;if(!r)return xt;let l=o?.[s?.blurredKey??$h],c=o?.[s?.sharpKey??\"childTexture\"];if(!l||!c)return W(Yt,\"unpremultiplyAlpha\",[i(r).sample(a.uv)]);let d=c.sample(a.uv);return W(Yt,\"unpremultiplyAlpha\",[t(l.sample(a.uv),d)])}var nse=.36,Q3=e=>e*nse,ise=.5,T0=.1;function lse(){return gt({...np,...y_})}function cse(e,t,s){let r=lse(),o=(globalThis.__TYPEGPU_AUTONAME__??(i=>i))(w.bindGroupLayout({source:{texture:Zt(n)},blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:r}}),\"layout\"),a=b_(s);return{layout:o,kernel:w.fn([M,M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c)=>{\"use gpu\";let d=o.$.params,u=__tsover_div(__tsover_add(n(l),.5),e),p=__tsover_div(__tsover_add(n(c),.5),t),_=G(j(Ut(__tsover_mul(u,d.inputWidth))),0,j(__tsover_sub(d.inputWidth,1))),f=G(j(Ut(__tsover_mul(p,d.inputHeight))),0,j(__tsover_sub(d.inputHeight,1))),h=Ei(a(Ye(o.$.source,fe(M(_),M(f)),0)),d.inputMin,d.inputMax,d.outputMin,d.outputMax,d.curve),g=__tsover_mul(h,.36);lt(o.$.blurMap,fe(l,c),S(g,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"srcX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",[7,\"p\",\"inputWidth\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",[7,\"p\",\"inputHeight\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]]]],[13,\"sample\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"source\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"srcX\"]],[6,\"d.u32\",[\"srcY\"]]]],[5,\"0\"]]]],[13,\"remapped\",[6,\"applyRemapWindow\",[[6,\"channelScalar\",[\"sample\"]],[7,\"p\",\"inputMin\"],[7,\"p\",\"inputMax\"],[7,\"p\",\"outputMin\"],[7,\"p\",\"outputMax\"],[7,\"p\",\"curve\"]]]],[13,\"radius\",[1,\"remapped\",\"*\",[5,\"0.36\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>o,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,applyRemapWindow:()=>Ei,channelScalar:()=>a,\"std.textureStore\":()=>lt,\"d.vec4f\":()=>S}})&&i.f)({})).$name(\"fillBlurMap\"),Params:r}}var dse=w.fn([S,S,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,.1),l=__tsover_mul(o,.1),c=__tsover_mul(a,.1),d=B(B(B(i,l),c),.01),u=__tsover_div(i,d),p=__tsover_div(l,d),_=__tsover_div(c,d);return S(K(t.x,s.x,u),K(t.y,s.y,p),K(t.z,s.z,_),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sharp\"},{type:\"i\",name:\"blurred\"},{type:\"i\",name:\"redIntensity\"},{type:\"i\",name:\"greenIntensity\"},{type:\"i\",name:\"blueIntensity\"}],body:[0,[[13,\"redRadius\",[1,\"redIntensity\",\"*\",[5,\"0.1\"]]],[13,\"greenRadius\",[1,\"greenIntensity\",\"*\",[5,\"0.1\"]]],[13,\"blueRadius\",[1,\"blueIntensity\",\"*\",[5,\"0.1\"]]],[13,\"maxRadius\",[6,\"std.max\",[[6,\"std.max\",[[6,\"std.max\",[\"redRadius\",\"greenRadius\"]],\"blueRadius\"]],[5,\"0.01\"]]]],[13,\"rMix\",[1,\"redRadius\",\"/\",\"maxRadius\"]],[13,\"gMix\",[1,\"greenRadius\",\"/\",\"maxRadius\"]],[13,\"bMix\",[1,\"blueRadius\",\"/\",\"maxRadius\"]],[13,\"finalR\",[6,\"std.mix\",[[7,\"sharp\",\"x\"],[7,\"blurred\",\"x\"],\"rMix\"]]],[13,\"finalG\",[6,\"std.mix\",[[7,\"sharp\",\"y\"],[7,\"blurred\",\"y\"],\"gMix\"]]],[13,\"finalB\",[6,\"std.mix\",[[7,\"sharp\",\"z\"],[7,\"blurred\",\"z\"],\"bMix\"]]],[10,[6,\"d.vec4f\",[\"finalR\",\"finalG\",\"finalB\",[7,\"sharp\",\"w\"]]]]]]},externals:{\"std.max\":()=>B,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"channelBlurCompose\"),wv=w.fn([n,n,n,n,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_mul(t,xv),c=m(__tsover_div(pe(l),i),ae(l)),d=m(s,__tsover_sub(1,r));return be(0,o,B(0,Se(a.sub(d),c)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"centerX\"},{type:\"i\",name:\"centerY\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"direction\",[6,\"d.vec2f\",[[1,[6,\"std.cos\",[\"angleRad\"]],\"/\",\"aspect\"],[6,\"std.sin\",[\"angleRad\"]]]]],[13,\"centerPos\",[6,\"d.vec2f\",[\"centerX\",[1,[5,\"1\"],\"-\",\"centerY\"]]]],[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[\"centerPos\"]]],[13,\"directionalDist\",[6,\"std.max\",[[5,\"0\"],[6,\"std.dot\",[\"centeredUV\",\"direction\"]]]]],[10,[6,\"std.smoothstep\",[[5,\"0\"],\"falloff\",\"directionalDist\"]]]]]},externals:{DEG_TO_RAD:()=>xv,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.max\":()=>B,\"std.dot\":()=>Se,\"std.smoothstep\":()=>be}})&&e.f)({})).$name(\"progressiveBlurAmount\");function use(){return gt({angle:n,centerX:n,centerY:n,falloff:n,aspect:n,maxRadius:n})}function pse(){return gt({angle:n,centerX:n,centerY:n,falloff:n,aspect:n,...np,...y_})}function mse(e,t){let s=use(),r=(globalThis.__TYPEGPU_AUTONAME__??(o=>o))(w.bindGroupLayout({blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:s}}),\"layout\");return{layout:r,kernel:w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=r.$.params,c=__tsover_div(__tsover_add(n(a),.5),e),d=__tsover_div(__tsover_add(n(i),.5),t),u=wv(l.angle,l.centerX,l.centerY,l.falloff,m(c,d),l.aspect),p=__tsover_mul(u,l.maxRadius);lt(r.$.blurMap,fe(a,i),S(p,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"blurAmount\",[6,\"progressiveBlurAmount\",[[7,\"p\",\"angle\"],[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"],[7,\"p\",\"falloff\"],[6,\"d.vec2f\",[\"u\",\"v\"]],[7,\"p\",\"aspect\"]]]],[13,\"radius\",[1,\"blurAmount\",\"*\",[7,\"p\",\"maxRadius\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>r,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,progressiveBlurAmount:()=>wv,\"d.vec2f\":()=>m,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(\"progressiveBlurFillBlurMap\"),Params:s}}function _se(e,t,s){let r=pse(),o=(globalThis.__TYPEGPU_AUTONAME__??(i=>i))(w.bindGroupLayout({source:{texture:Zt(n)},blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:r}}),\"layout\"),a=b_(s);return{layout:o,kernel:w.fn([M,M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c)=>{\"use gpu\";let d=o.$.params,u=__tsover_div(__tsover_add(n(l),.5),e),p=__tsover_div(__tsover_add(n(c),.5),t),_=wv(d.angle,d.centerX,d.centerY,d.falloff,m(u,p),d.aspect),f=G(j(Ut(__tsover_mul(u,d.inputWidth))),0,j(__tsover_sub(d.inputWidth,1))),h=G(j(Ut(__tsover_mul(p,d.inputHeight))),0,j(__tsover_sub(d.inputHeight,1))),g=Ei(a(Ye(o.$.source,fe(M(f),M(h)),0)),d.inputMin,d.inputMax,d.outputMin,d.outputMax,d.curve),y=__tsover_mul(_,__tsover_mul(g,.36));lt(o.$.blurMap,fe(l,c),S(y,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"blurAmount\",[6,\"progressiveBlurAmount\",[[7,\"p\",\"angle\"],[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"],[7,\"p\",\"falloff\"],[6,\"d.vec2f\",[\"u\",\"v\"]],[7,\"p\",\"aspect\"]]]],[13,\"srcX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",[7,\"p\",\"inputWidth\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",[7,\"p\",\"inputHeight\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]]]],[13,\"sample\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"source\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"srcX\"]],[6,\"d.u32\",[\"srcY\"]]]],[5,\"0\"]]]],[13,\"remapped\",[6,\"applyRemapWindow\",[[6,\"channelScalar\",[\"sample\"]],[7,\"p\",\"inputMin\"],[7,\"p\",\"inputMax\"],[7,\"p\",\"outputMin\"],[7,\"p\",\"outputMax\"],[7,\"p\",\"curve\"]]]],[13,\"radius\",[1,\"blurAmount\",\"*\",[1,\"remapped\",\"*\",\"INTENSITY_TO_RADIUS\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>o,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,progressiveBlurAmount:()=>wv,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,applyRemapWindow:()=>Ei,channelScalar:()=>a,INTENSITY_TO_RADIUS:()=>.36,\"std.textureStore\":()=>lt,\"d.vec4f\":()=>S}})&&i.f)({})).$name(\"progressiveBlurFillBlurMapVariable\"),Params:r}}var Km=w.fn([n,m,n,n,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_mul(t,xv),c=m(__tsover_mul(ae(l),-1),pe(l)),d=m(s.x,__tsover_sub(1,s.y)),u=a.sub(d),p=re(Se(m(__tsover_mul(u.x,i),u.y),c)),_=__tsover_mul(r,.5);return be(_,__tsover_add(_,o),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"width\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"perpVector\",[6,\"d.vec2f\",[[1,[6,\"std.sin\",[\"angleRad\"]],\"*\",[4,\"-\",[5,\"1\"]]],[6,\"std.cos\",[\"angleRad\"]]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[\"centerPos\"]]],[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"centeredUV\",\"x\"],\"*\",\"aspect\"],[7,\"centeredUV\",\"y\"]]]],[13,\"distFromLine\",[6,\"std.abs\",[[6,\"std.dot\",[\"aspectCorrectedUV\",\"perpVector\"]]]]],[13,\"focusWidth\",[1,\"width\",\"*\",[5,\"0.5\"]]],[10,[6,\"std.smoothstep\",[\"focusWidth\",[1,\"focusWidth\",\"+\",\"falloff\"],\"distFromLine\"]]]]]},externals:{DEG_TO_RAD:()=>xv,\"d.vec2f\":()=>m,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.abs\":()=>re,\"std.dot\":()=>Se,\"std.smoothstep\":()=>be}})&&e.f)({})).$name(\"tiltShiftBlurAmount\");function fse(){return gt({angle:n,centerX:n,centerY:n,width:n,falloff:n,aspect:n,maxRadius:n})}function vse(){return gt({angle:n,centerX:n,centerY:n,width:n,falloff:n,aspect:n,...np,...y_})}function hse(e,t){let s=fse(),r=(globalThis.__TYPEGPU_AUTONAME__??(o=>o))(w.bindGroupLayout({blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:s}}),\"layout\");return{layout:r,kernel:w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=r.$.params,c=__tsover_div(__tsover_add(n(a),.5),e),d=__tsover_div(__tsover_add(n(i),.5),t),u=Km(l.angle,m(l.centerX,l.centerY),l.width,l.falloff,m(c,d),l.aspect),p=__tsover_mul(u,l.maxRadius);lt(r.$.blurMap,fe(a,i),S(p,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"blurAmount\",[6,\"tiltShiftBlurAmount\",[[7,\"p\",\"angle\"],[6,\"d.vec2f\",[[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"]]],[7,\"p\",\"width\"],[7,\"p\",\"falloff\"],[6,\"d.vec2f\",[\"u\",\"v\"]],[7,\"p\",\"aspect\"]]]],[13,\"radius\",[1,\"blurAmount\",\"*\",[7,\"p\",\"maxRadius\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>r,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,tiltShiftBlurAmount:()=>Km,\"d.vec2f\":()=>m,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(\"tiltShiftFillBlurMap\"),Params:s}}function gse(e,t,s){let r=vse(),o=(globalThis.__TYPEGPU_AUTONAME__??(i=>i))(w.bindGroupLayout({source:{texture:Zt(n)},blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:r}}),\"layout\"),a=b_(s);return{layout:o,kernel:w.fn([M,M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c)=>{\"use gpu\";let d=o.$.params,u=__tsover_div(__tsover_add(n(l),.5),e),p=__tsover_div(__tsover_add(n(c),.5),t),_=Km(d.angle,m(d.centerX,d.centerY),d.width,d.falloff,m(u,p),d.aspect),f=G(j(Ut(__tsover_mul(u,d.inputWidth))),0,j(__tsover_sub(d.inputWidth,1))),h=G(j(Ut(__tsover_mul(p,d.inputHeight))),0,j(__tsover_sub(d.inputHeight,1))),g=Ei(a(Ye(o.$.source,fe(M(f),M(h)),0)),d.inputMin,d.inputMax,d.outputMin,d.outputMax,d.curve),y=__tsover_mul(_,__tsover_mul(g,.36));lt(o.$.blurMap,fe(l,c),S(y,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"blurAmount\",[6,\"tiltShiftBlurAmount\",[[7,\"p\",\"angle\"],[6,\"d.vec2f\",[[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"]]],[7,\"p\",\"width\"],[7,\"p\",\"falloff\"],[6,\"d.vec2f\",[\"u\",\"v\"]],[7,\"p\",\"aspect\"]]]],[13,\"srcX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",[7,\"p\",\"inputWidth\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",[7,\"p\",\"inputHeight\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]]]],[13,\"sample\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"source\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"srcX\"]],[6,\"d.u32\",[\"srcY\"]]]],[5,\"0\"]]]],[13,\"remapped\",[6,\"applyRemapWindow\",[[6,\"channelScalar\",[\"sample\"]],[7,\"p\",\"inputMin\"],[7,\"p\",\"inputMax\"],[7,\"p\",\"outputMin\"],[7,\"p\",\"outputMax\"],[7,\"p\",\"curve\"]]]],[13,\"radius\",[1,\"blurAmount\",\"*\",[1,\"remapped\",\"*\",\"INTENSITY_TO_RADIUS\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>o,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,tiltShiftBlurAmount:()=>Km,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,applyRemapWindow:()=>Ei,channelScalar:()=>a,INTENSITY_TO_RADIUS:()=>.36,\"std.textureStore\":()=>lt,\"d.vec4f\":()=>S}})&&i.f)({})).$name(\"tiltShiftFillBlurMapVariable\"),Params:r}}var yse=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=t.xyz.add(s.xyz.mul(r)),a=G(__tsover_mul(s.w,r),0,1);return S(o,__tsover_add(t.w,__tsover_mul(a,__tsover_sub(1,t.w))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"original\"},{type:\"i\",name:\"bloom\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"finalColor\",[6,[7,[7,\"original\",\"xyz\"],\"add\"],[[6,[7,[7,\"bloom\",\"xyz\"],\"mul\"],[\"intensity\"]]]]],[13,\"glowAlpha\",[6,\"std.clamp\",[[1,[7,\"bloom\",\"w\"],\"*\",\"intensity\"],[5,\"0\"],[5,\"1\"]]]],[13,\"finalAlpha\",[1,[7,\"original\",\"w\"],\"+\",[1,\"glowAlpha\",\"*\",[1,[5,\"1\"],\"-\",[7,\"original\",\"w\"]]]]],[10,[6,\"d.vec4f\",[\"finalColor\",\"finalAlpha\"]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"glowCompose\"),bse=(e,t)=>k4(e,t,\"glowExtractAndFill\"),xse=(e,t,s)=>ose(e,t,\"glowExtractAndFillVariable\",s),Ase=Math.PI*(3-Math.sqrt(5)),Z3=Math.PI*2,wse=.8,Tse=e=>e*wse,vS=.35,hS=.6,Sse=8,Pse=.25,Tv=.5,Sv=1.4,R4=\"rgba16float\",Cse=e=>{let t=Math.round(e);return t>=3?t:5},Mse=(e,t)=>{if(t<3)return 1;let s=Z3/t,r=e-s*Math.floor(e/s+.5);return Math.cos(s*.5)/Math.cos(r)},Ese=Math.SQRT2/4,kse=(e,t)=>{let s=1.3333333333333333,r=Math.abs(e)/s,o=-t/s+.6;if(r+o>1){let u=r-.25,p=o-.75;return(Math.hypot(u,p)-Ese)*s}let a=o-1,i=r*r+a*a,l=Math.max(r+o,0)*.5,c=r-l,d=o-l;return Math.sqrt(Math.min(i,c*c+d*d))*Math.sign(r-o)*s},Bse=(e,t,s,r)=>{let o=Math.hypot(e,t),a=Math.atan2(t,e),i=Z3/s,l=a-Math.floor(a/i+.5)*i,c=Math.abs(o*Math.sin(l)),d=o*Math.cos(l),u=Math.PI/s,p=r*Math.sin(u),_=r*Math.cos(u)-1,f=c,h=d-1,g=Math.min(Math.max((f*p+h*_)/(p*p+_*_),0),1),y=c-p*g,b=d-(1+_*g);return Math.hypot(y,b)*Math.sign(p*h-_*f)},zse=(e,t,s,r)=>{let o=Math.atan2(t,e),a=Math.hypot(e,t),i=o*s/Z3,l=i-Math.floor(i),c=Math.abs(l*2-1);return a-(r+(1-r)*c)},gS=.92,yS=.3,Rse=.08,Dse=(e,t)=>{let s=Math.abs(e),r=Math.abs(t),o=Math.max(s-gS,r-yS),a=Math.max(r-gS,s-yS);return Math.min(o,a)-Rse},Lse=.72,Use=.28,Ose=(e,t)=>Math.abs(Math.hypot(e,t)-Lse)-Use,bS=(e,t)=>{let s=1,r=0,o=e;for(;o>0;)s/=t,r+=s*(o%t),o=Math.floor(o/t);return r},xS=(e,t)=>[-t,e],Gse={star:(e,t,s)=>{let[r,o]=xS(e,t);return Bse(r,o,s,.5)},flower:(e,t,s)=>{let[r,o]=xS(e,t);return zse(r,o,s,.55)},heart:(e,t)=>kse(e,t),cross:(e,t)=>Dse(e,t),ring:(e,t)=>Ose(e,t)};function D4(e,t,s){let r=[],o=Gse[e];if(!o){let d=e===\"circle\"?0:t;for(let u=0;u<s;u++){let p=(u+.5)/s,_=Math.sqrt(p),f=u*Ase,h=_*Mse(f,d);r.push({x:-Math.cos(f)*h,y:-Math.sin(f)*h,rim:1+hS*Math.pow(_,Sse)})}return r}let a=Cse(t),i=(d,u)=>o(d,u,a),l=2e4;for(let d=1;r.length<s&&d<=l;d++){let u=bS(d,2)*2-1,p=bS(d,3)*2-1,_=i(u,p);if(_>0)continue;let f=Math.min(Math.max(1+_/Pse,0),1);r.push({x:-u,y:-p,rim:1+hS*f*f})}if(r.length===0)return D4(\"circle\",0,s);for(let d=0;r.length<s;d++)r.push(r[d%r.length]);let c=r.reduce((d,u)=>Math.max(d,Math.hypot(u.x,u.y)),0);if(c>1){let d=1/c;for(let u of r)u.x*=d,u.y*=d}return r}function Fse(){return gt({radius:n,highlightGain:n,highlightThreshold:n,rotCos:n,rotSin:n,chromaticFringe:n,catEye:n,inputWidth:n,inputHeight:n})}function Ise(){return gt({highlightGain:n,highlightThreshold:n,rotCos:n,rotSin:n,chromaticFringe:n,catEye:n,...np,...y_})}var Pv=w.fn([S,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Se(t.xyz,A(.2126,.7152,.0722)),i=be(s,__tsover_add(s,vS),a);return __tsover_mul(__tsover_add(1,__tsover_mul(__tsover_mul(r,i),i)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"threshold\"},{type:\"i\",name:\"gain\"},{type:\"i\",name:\"rim\"}],body:[0,[[13,\"lum\",[6,\"std.dot\",[[7,\"base\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"hi\",[6,\"std.smoothstep\",[\"threshold\",[1,\"threshold\",\"+\",\"HIGHLIGHT_KNEE\"],\"lum\"]]],[10,[1,[1,[5,\"1\"],\"+\",[1,[1,\"gain\",\"*\",\"hi\"],\"*\",\"hi\"]],\"*\",\"rim\"]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.smoothstep\":()=>be,HIGHLIGHT_KNEE:()=>vS}})&&e.f)({})).$name(\"bokehHighlightWeight\");function Yse(e,t,s){let r=s,o=Fse(),a=Fe(S,r),i=(globalThis.__TYPEGPU_AUTONAME__??(l=>l))(w.bindGroupLayout({input:{texture:Zt(n)},output:{storageTexture:zt(R4,\"write-only\")},params:{uniform:o},taps:{uniform:a}}),\"layout\");return{layout:i,kernel:w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";let u=i.$.params,p=u.radius,_=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(c),.5),u.inputWidth),e),.5),f=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(d),.5),u.inputHeight),t),.5),h=j(__tsover_sub(u.inputWidth,1)),g=j(__tsover_sub(u.inputHeight,1));if(p<Tv){let y=G(j(Ut(_)),0,h),b=G(j(Ut(f)),0,g),x=Ye(i.$.input,fe(M(y),M(b)),0);lt(i.$.output,fe(c,d),x)}else{let y=u.highlightGain,b=u.highlightThreshold,x=u.chromaticFringe,P=u.rotCos,C=u.rotSin,E=__tsover_div(u.inputWidth,u.inputHeight),R=__tsover_mul(__tsover_sub(__tsover_div(__tsover_add(n(c),.5),e),.5),E),U=__tsover_sub(__tsover_div(__tsover_add(n(d),.5),t),.5),L=Ue(__tsover_add(__tsover_mul(R,R),__tsover_mul(U,U))),k=Ue(__tsover_add(__tsover_mul(__tsover_mul(.25,E),E),.25)),D=__tsover_div(__tsover_mul(__tsover_mul(u.catEye,__tsover_div(L,k)),Sv),B(L,1e-4)),O=m(__tsover_mul(R,D),__tsover_mul(U,D)),F=A(0,0,0),q=n(0),Y=n(0);for(let X=0;X<r;X++){let Q=i.$.taps[X],te=__tsover_sub(__tsover_mul(Q.x,P),__tsover_mul(Q.y,C)),J=__tsover_add(__tsover_mul(Q.x,C),__tsover_mul(Q.y,P)),oe=m(__tsover_mul(te,p),__tsover_mul(J,p)),le=G(j(Ut(__tsover_add(_,oe.x))),0,h),se=G(j(Ut(__tsover_add(f,oe.y))),0,g),Te=Ye(i.$.input,fe(M(le),M(se)),0),de=Te.x,xe=Te.z;if(x>.001){let ze=oe.mul(__tsover_add(1,__tsover_mul(x,.5))),Ie=G(j(Ut(__tsover_add(_,ze.x))),0,h),ke=G(j(Ut(__tsover_add(f,ze.y))),0,g);de=Ye(i.$.input,fe(M(Ie),M(ke)),0).x;let Me=oe.mul(__tsover_sub(1,__tsover_mul(x,.5))),we=G(j(Ut(__tsover_add(_,Me.x))),0,h),Ve=G(j(Ut(__tsover_add(f,Me.y))),0,g);xe=Ye(i.$.input,fe(M(we),M(Ve)),0).z}let Ae=A(de,Te.y,xe),De=__tsover_sub(1,be(1.02,1.12,he(m(te,J).add(O)))),Ee=__tsover_mul(Pv(Te,b,y,Q.z),De);F=F.add(Ae.mul(Ee)),q=__tsover_add(q,__tsover_mul(Te.w,Ee)),Y=__tsover_add(Y,Ee)}let V=__tsover_div(1,B(Y,1e-4));lt(i.$.output,fe(c,d),S(F.mul(V),__tsover_mul(q,V)))}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"radius\",[7,\"p\",\"radius\"]],[13,\"inputCx\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputWidth\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]]],[13,\"inputCy\",[1,[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputHeight\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"inputWm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[11,[1,\"radius\",\"<\",\"PASSTHROUGH_RADIUS\"],[0,[[13,\"sx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCx\"]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"sy\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCy\"]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"gain\",[7,\"p\",\"highlightGain\"]],[13,\"threshold\",[7,\"p\",\"highlightThreshold\"]],[13,\"fringe\",[7,\"p\",\"chromaticFringe\"]],[13,\"rotC\",[7,\"p\",\"rotCos\"]],[13,\"rotS\",[7,\"p\",\"rotSin\"]],[13,\"aspect\",[1,[7,\"p\",\"inputWidth\"],\"/\",[7,\"p\",\"inputHeight\"]]],[13,\"vu\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"]],[13,\"vv\",[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"vLen\",[6,\"std.sqrt\",[[1,[1,\"vu\",\"*\",\"vu\"],\"+\",[1,\"vv\",\"*\",\"vv\"]]]]],[13,\"vMax\",[6,\"std.sqrt\",[[1,[1,[1,[5,\"0.25\"],\"*\",\"aspect\"],\"*\",\"aspect\"],\"+\",[5,\"0.25\"]]]]],[13,\"shift\",[1,[1,[1,[7,\"p\",\"catEye\"],\"*\",[1,\"vLen\",\"/\",\"vMax\"]],\"*\",\"BOKEH_CATEYE_SHIFT\"],\"/\",[6,\"std.max\",[\"vLen\",[5,\"0.0001\"]]]]],[13,\"barrelShift\",[6,\"d.vec2f\",[[1,\"vu\",\"*\",\"shift\"],[1,\"vv\",\"*\",\"shift\"]]]],[12,\"accum\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[12,\"alphaAccum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"wSum\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"TAPS\"],[102,\"++\",\"i\"],[0,[[13,\"tap\",[8,[7,[7,\"layout\",\"$\"],\"taps\"],\"i\"]],[13,\"ox\",[1,[1,[7,\"tap\",\"x\"],\"*\",\"rotC\"],\"-\",[1,[7,\"tap\",\"y\"],\"*\",\"rotS\"]]],[13,\"oy\",[1,[1,[7,\"tap\",\"x\"],\"*\",\"rotS\"],\"+\",[1,[7,\"tap\",\"y\"],\"*\",\"rotC\"]]],[13,\"off\",[6,\"d.vec2f\",[[1,\"ox\",\"*\",\"radius\"],[1,\"oy\",\"*\",\"radius\"]]]],[13,\"sx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"off\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"sy\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"off\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"base\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]]],[12,\"colR\",[7,\"base\",\"x\"]],[12,\"colB\",[7,\"base\",\"z\"]],[11,[1,\"fringe\",\">\",[5,\"0.001\"]],[0,[[13,\"offR\",[6,[7,\"off\",\"mul\"],[[1,[5,\"1\"],\"+\",[1,\"fringe\",\"*\",[5,\"0.5\"]]]]]],[13,\"rx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"offR\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"ry\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"offR\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[2,\"colR\",\"=\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"rx\"]],[6,\"d.u32\",[\"ry\"]]]],[5,\"0\"]]],\"x\"]],[13,\"offB\",[6,[7,\"off\",\"mul\"],[[1,[5,\"1\"],\"-\",[1,\"fringe\",\"*\",[5,\"0.5\"]]]]]],[13,\"bx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"offB\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"by\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"offB\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[2,\"colB\",\"=\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"bx\"]],[6,\"d.u32\",[\"by\"]]]],[5,\"0\"]]],\"z\"]]]]],[13,\"col\",[6,\"d.vec3f\",[\"colR\",[7,\"base\",\"y\"],\"colB\"]]],[13,\"barrel\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"1.02\"],[5,\"1.12\"],[6,\"std.length\",[[6,[7,[6,\"d.vec2f\",[\"ox\",\"oy\"]],\"add\"],[\"barrelShift\"]]]]]]]],[13,\"w\",[1,[6,\"bokehHighlightWeight\",[\"base\",\"threshold\",\"gain\",[7,\"tap\",\"z\"]]],\"*\",\"barrel\"]],[2,\"accum\",\"=\",[6,[7,\"accum\",\"add\"],[[6,[7,\"col\",\"mul\"],[\"w\"]]]]],[2,\"alphaAccum\",\"=\",[1,\"alphaAccum\",\"+\",[1,[7,\"base\",\"w\"],\"*\",\"w\"]]],[2,\"wSum\",\"=\",[1,\"wSum\",\"+\",\"w\"]]]]],[13,\"invW\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[\"wSum\",[5,\"0.0001\"]]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[6,[7,\"accum\",\"mul\"],[\"invW\"]],[1,\"alphaAccum\",\"*\",\"invW\"]]]]]]]]]]},externals:{layout:()=>i,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,\"d.i32\":()=>j,PASSTHROUGH_RADIUS:()=>Tv,\"std.clamp\":()=>G,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"std.textureStore\":()=>lt,\"std.sqrt\":()=>Ue,BOKEH_CATEYE_SHIFT:()=>Sv,\"std.max\":()=>B,\"d.vec2f\":()=>m,\"d.vec3f\":()=>A,TAPS:()=>r,\"std.smoothstep\":()=>be,\"std.length\":()=>he,bokehHighlightWeight:()=>Pv,\"d.vec4f\":()=>S}})&&l.f)({})).$name(\"bokehGather\"),Params:o,TapArray:a}}function Wse(e,t,s,r){let o=s,a=Ise(),i=Fe(S,o),l=b_(r),c=(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(w.bindGroupLayout({input:{texture:Zt(n)},source:{texture:Zt(n)},output:{storageTexture:zt(R4,\"write-only\")},params:{uniform:a},taps:{uniform:i}}),\"layout\");return{layout:c,kernel:w.fn([M,M])((d=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(d.f=((u,p)=>{\"use gpu\";let _=c.$.params,f=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(u),.5),_.inputWidth),e),.5),h=__tsover_sub(__tsover_div(__tsover_mul(__tsover_add(n(p),.5),_.inputHeight),t),.5),g=j(__tsover_sub(_.inputWidth,1)),y=j(__tsover_sub(_.inputHeight,1)),b=__tsover_div(__tsover_add(n(u),.5),e),x=__tsover_div(__tsover_add(n(p),.5),t),P=G(j(Ut(__tsover_mul(b,_.inputWidth))),0,g),C=G(j(Ut(__tsover_mul(x,_.inputHeight))),0,y),E=Ei(l(Ye(c.$.source,fe(M(P),M(C)),0)),_.inputMin,_.inputMax,_.outputMin,_.outputMax,_.curve),R=__tsover_mul(E,.8);if(R<Tv){let U=G(j(Ut(f)),0,g),L=G(j(Ut(h)),0,y),k=Ye(c.$.input,fe(M(U),M(L)),0);lt(c.$.output,fe(u,p),k)}else{let U=_.highlightGain,L=_.highlightThreshold,k=_.chromaticFringe,D=_.rotCos,O=_.rotSin,F=__tsover_div(_.inputWidth,_.inputHeight),q=__tsover_mul(__tsover_sub(__tsover_div(__tsover_add(n(u),.5),e),.5),F),Y=__tsover_sub(__tsover_div(__tsover_add(n(p),.5),t),.5),V=Ue(__tsover_add(__tsover_mul(q,q),__tsover_mul(Y,Y))),X=Ue(__tsover_add(__tsover_mul(__tsover_mul(.25,F),F),.25)),Q=__tsover_div(__tsover_mul(__tsover_mul(_.catEye,__tsover_div(V,X)),Sv),B(V,1e-4)),te=m(__tsover_mul(q,Q),__tsover_mul(Y,Q)),J=A(0,0,0),oe=n(0),le=n(0);for(let Te=0;Te<o;Te++){let de=c.$.taps[Te],xe=__tsover_sub(__tsover_mul(de.x,D),__tsover_mul(de.y,O)),Ae=__tsover_add(__tsover_mul(de.x,O),__tsover_mul(de.y,D)),De=m(__tsover_mul(xe,R),__tsover_mul(Ae,R)),Ee=G(j(Ut(__tsover_add(f,De.x))),0,g),ze=G(j(Ut(__tsover_add(h,De.y))),0,y),Ie=Ye(c.$.input,fe(M(Ee),M(ze)),0),ke=Ie.x,Me=Ie.z;if(k>.001){let st=De.mul(__tsover_add(1,__tsover_mul(k,.5))),pt=G(j(Ut(__tsover_add(f,st.x))),0,g),Ze=G(j(Ut(__tsover_add(h,st.y))),0,y);ke=Ye(c.$.input,fe(M(pt),M(Ze)),0).x;let nt=De.mul(__tsover_sub(1,__tsover_mul(k,.5))),ht=G(j(Ut(__tsover_add(f,nt.x))),0,g),yt=G(j(Ut(__tsover_add(h,nt.y))),0,y);Me=Ye(c.$.input,fe(M(ht),M(yt)),0).z}let we=A(ke,Ie.y,Me),Ve=__tsover_sub(1,be(1.02,1.12,he(m(xe,Ae).add(te)))),qe=__tsover_mul(Pv(Ie,L,U,de.z),Ve);J=J.add(we.mul(qe)),oe=__tsover_add(oe,__tsover_mul(Ie.w,qe)),le=__tsover_add(le,qe)}let se=__tsover_div(1,B(le,1e-4));lt(c.$.output,fe(u,p),S(J.mul(se),__tsover_mul(oe,se)))}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"inputCx\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputWidth\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]]],[13,\"inputCy\",[1,[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"*\",[7,\"p\",\"inputHeight\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"inputWm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"inputHm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"srcX\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",[7,\"p\",\"inputWidth\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"srcY\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",[7,\"p\",\"inputHeight\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"mapSample\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"source\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"srcX\"]],[6,\"d.u32\",[\"srcY\"]]]],[5,\"0\"]]]],[13,\"remapped\",[6,\"applyRemapWindow\",[[6,\"channelScalar\",[\"mapSample\"]],[7,\"p\",\"inputMin\"],[7,\"p\",\"inputMax\"],[7,\"p\",\"outputMin\"],[7,\"p\",\"outputMax\"],[7,\"p\",\"curve\"]]]],[13,\"radius\",[1,\"remapped\",\"*\",\"BOKEH_RADIUS_SCALE\"]],[11,[1,\"radius\",\"<\",\"PASSTHROUGH_RADIUS\"],[0,[[13,\"sx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCx\"]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"sy\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[\"inputCy\"]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"texel\"]]]],[0,[[13,\"gain\",[7,\"p\",\"highlightGain\"]],[13,\"threshold\",[7,\"p\",\"highlightThreshold\"]],[13,\"fringe\",[7,\"p\",\"chromaticFringe\"]],[13,\"rotC\",[7,\"p\",\"rotCos\"]],[13,\"rotS\",[7,\"p\",\"rotSin\"]],[13,\"aspect\",[1,[7,\"p\",\"inputWidth\"],\"/\",[7,\"p\",\"inputHeight\"]]],[13,\"vu\",[1,[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeWidth\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"]],[13,\"vv\",[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"],\"-\",[5,\"0.5\"]]],[13,\"vLen\",[6,\"std.sqrt\",[[1,[1,\"vu\",\"*\",\"vu\"],\"+\",[1,\"vv\",\"*\",\"vv\"]]]]],[13,\"vMax\",[6,\"std.sqrt\",[[1,[1,[1,[5,\"0.25\"],\"*\",\"aspect\"],\"*\",\"aspect\"],\"+\",[5,\"0.25\"]]]]],[13,\"shift\",[1,[1,[1,[7,\"p\",\"catEye\"],\"*\",[1,\"vLen\",\"/\",\"vMax\"]],\"*\",\"BOKEH_CATEYE_SHIFT\"],\"/\",[6,\"std.max\",[\"vLen\",[5,\"0.0001\"]]]]],[13,\"barrelShift\",[6,\"d.vec2f\",[[1,\"vu\",\"*\",\"shift\"],[1,\"vv\",\"*\",\"shift\"]]]],[12,\"accum\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[12,\"alphaAccum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"wSum\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"TAPS\"],[102,\"++\",\"i\"],[0,[[13,\"tap\",[8,[7,[7,\"layout\",\"$\"],\"taps\"],\"i\"]],[13,\"ox\",[1,[1,[7,\"tap\",\"x\"],\"*\",\"rotC\"],\"-\",[1,[7,\"tap\",\"y\"],\"*\",\"rotS\"]]],[13,\"oy\",[1,[1,[7,\"tap\",\"x\"],\"*\",\"rotS\"],\"+\",[1,[7,\"tap\",\"y\"],\"*\",\"rotC\"]]],[13,\"off\",[6,\"d.vec2f\",[[1,\"ox\",\"*\",\"radius\"],[1,\"oy\",\"*\",\"radius\"]]]],[13,\"sx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"off\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"sy\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"off\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[13,\"base\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]]],[12,\"colR\",[7,\"base\",\"x\"]],[12,\"colB\",[7,\"base\",\"z\"]],[11,[1,\"fringe\",\">\",[5,\"0.001\"]],[0,[[13,\"offR\",[6,[7,\"off\",\"mul\"],[[1,[5,\"1\"],\"+\",[1,\"fringe\",\"*\",[5,\"0.5\"]]]]]],[13,\"rx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"offR\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"ry\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"offR\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[2,\"colR\",\"=\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"rx\"]],[6,\"d.u32\",[\"ry\"]]]],[5,\"0\"]]],\"x\"]],[13,\"offB\",[6,[7,\"off\",\"mul\"],[[1,[5,\"1\"],\"-\",[1,\"fringe\",\"*\",[5,\"0.5\"]]]]]],[13,\"bx\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCx\",\"+\",[7,\"offB\",\"x\"]]]]]],[5,\"0\"],\"inputWm1\"]]],[13,\"by\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"inputCy\",\"+\",[7,\"offB\",\"y\"]]]]]],[5,\"0\"],\"inputHm1\"]]],[2,\"colB\",\"=\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"bx\"]],[6,\"d.u32\",[\"by\"]]]],[5,\"0\"]]],\"z\"]]]]],[13,\"col\",[6,\"d.vec3f\",[\"colR\",[7,\"base\",\"y\"],\"colB\"]]],[13,\"barrel\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"1.02\"],[5,\"1.12\"],[6,\"std.length\",[[6,[7,[6,\"d.vec2f\",[\"ox\",\"oy\"]],\"add\"],[\"barrelShift\"]]]]]]]],[13,\"w\",[1,[6,\"bokehHighlightWeight\",[\"base\",\"threshold\",\"gain\",[7,\"tap\",\"z\"]]],\"*\",\"barrel\"]],[2,\"accum\",\"=\",[6,[7,\"accum\",\"add\"],[[6,[7,\"col\",\"mul\"],[\"w\"]]]]],[2,\"alphaAccum\",\"=\",[1,\"alphaAccum\",\"+\",[1,[7,\"base\",\"w\"],\"*\",\"w\"]]],[2,\"wSum\",\"=\",[1,\"wSum\",\"+\",\"w\"]]]]],[13,\"invW\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[\"wSum\",[5,\"0.0001\"]]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"output\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[6,[7,\"accum\",\"mul\"],[\"invW\"]],[1,\"alphaAccum\",\"*\",\"invW\"]]]]]]]]]]},externals:{layout:()=>c,\"d.f32\":()=>n,computeWidth:()=>e,computeHeight:()=>t,\"d.i32\":()=>j,\"std.clamp\":()=>G,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,applyRemapWindow:()=>Ei,channelScalar:()=>l,BOKEH_RADIUS_SCALE:()=>.8,PASSTHROUGH_RADIUS:()=>Tv,\"std.textureStore\":()=>lt,\"std.sqrt\":()=>Ue,BOKEH_CATEYE_SHIFT:()=>Sv,\"std.max\":()=>B,\"d.vec2f\":()=>m,\"d.vec3f\":()=>A,TAPS:()=>o,\"std.smoothstep\":()=>be,\"std.length\":()=>he,bokehHighlightWeight:()=>Pv,\"d.vec4f\":()=>S}})&&d.f)({})).$name(\"bokehGatherVariable\"),Params:a,TapArray:i}}var Vu=bt,L4=rse(32,.8),U4=w.fn([m,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(s,Vu),l=__tsover_div(o.x,o.y),c=__tsover_div(pe(i),l),d=ae(i),u=__tsover_mul(__tsover_div(__tsover_mul(c,r),o.x),2),p=__tsover_mul(__tsover_div(__tsover_mul(d,r),o.y),2);return m(__tsover_add(t.x,__tsover_mul(u,a)),__tsover_add(t.y,__tsover_mul(p,a)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"tapT\"}],body:[0,[[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"dirX\",[1,[6,\"std.cos\",[\"angleRad\"]],\"/\",\"aspect\"]],[13,\"dirY\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"bvX\",[1,[1,[1,\"dirX\",\"*\",\"intensity\"],\"/\",[7,\"viewport\",\"x\"]],\"*\",[5,\"2\"]]],[13,\"bvY\",[1,[1,[1,\"dirY\",\"*\",\"intensity\"],\"/\",[7,\"viewport\",\"y\"]],\"*\",[5,\"2\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,\"bvX\",\"*\",\"tapT\"]],[1,[7,\"uv\",\"y\"],\"+\",[1,\"bvY\",\"*\",\"tapT\"]]]]]]]},externals:{DEG_TO_RAD:()=>Vu,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),O4=w.fn([m,n,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(t.x,__tsover_sub(1,t.y)),l=__tsover_div(__tsover_mul(s,.005),31),c=__tsover_mul(__tsover_sub(a,15.5),l),d=pe(c),u=ae(c),p=__tsover_sub(r.x,i.x),_=__tsover_sub(r.y,i.y),f=__tsover_mul(p,o),h=_,g=__tsover_sub(__tsover_mul(f,d),__tsover_mul(h,u)),y=__tsover_add(__tsover_mul(f,u),__tsover_mul(h,d));return m(__tsover_add(__tsover_div(g,o),i.x),__tsover_add(y,i.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"tapIndex\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"angleStep\",[1,[1,\"intensity\",\"*\",[5,\"0.005\"]],\"/\",[5,\"31\"]]],[13,\"angle\",[1,[1,\"tapIndex\",\"-\",[5,\"15.5\"]],\"*\",\"angleStep\"]],[13,\"cosA\",[6,\"std.cos\",[\"angle\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angle\"]]],[13,\"initX\",[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]]],[13,\"initY\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"acX\",[1,\"initX\",\"*\",\"aspect\"]],[13,\"acY\",\"initY\"],[13,\"rotX\",[1,[1,\"acX\",\"*\",\"cosA\"],\"-\",[1,\"acY\",\"*\",\"sinA\"]]],[13,\"rotY\",[1,[1,\"acX\",\"*\",\"sinA\"],\"+\",[1,\"acY\",\"*\",\"cosA\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"rotX\",\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,\"rotY\",\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),G4=w.fn([m,n,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(t.x,__tsover_sub(1,t.y)),l=__tsover_mul(s,.01),c=__tsover_add(1,__tsover_mul(l,__tsover_div(a,31))),d=__tsover_sub(r.x,i.x),u=__tsover_sub(r.y,i.y),p=__tsover_mul(d,o),_=u,f=__tsover_div(p,c),h=__tsover_div(_,c);return m(__tsover_add(__tsover_div(f,o),i.x),__tsover_add(h,i.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"tapIndex\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"radius\",[1,\"intensity\",\"*\",[5,\"0.01\"]]],[13,\"scale\",[1,[5,\"1\"],\"+\",[1,\"radius\",\"*\",[1,\"tapIndex\",\"/\",[5,\"31\"]]]]],[13,\"deltaX\",[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]]],[13,\"deltaY\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"acdX\",[1,\"deltaX\",\"*\",\"aspect\"]],[13,\"acdY\",\"deltaY\"],[13,\"scaledDeltaX\",[1,\"acdX\",\"/\",\"scale\"]],[13,\"scaledDeltaY\",[1,\"acdY\",\"/\",\"scale\"]],[10,[6,\"d.vec2f\",[[1,[1,\"scaledDeltaX\",\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,\"scaledDeltaY\",\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({}));function qse(e,t,s){let{focus:r,amount:o,uv:a,aspect:i,viewportSize:l}=t;return qb({weights:L4,tapCoord:e===\"linear\"?c=>W(U4,\"linearBlurTapCoord\",[a,r,o,l,$e(c/31-.5)]):e===\"orbit\"?c=>W(O4,\"angularBlurTapCoord\",[r,o,a,i,$e(c)]):c=>W(G4,\"zoomBlurTapCoord\",[r,o,a,i,$e(c)]),sample:s})}function Vse(e){let t=s=>{let r=e*6+s,o=r-6*Math.floor(r/6),a=Math.min(1,Math.max(0,Math.abs(o-3)-1));return a*a*(3-2*a)};return[t(0),t(4),t(2)]}var Nse=.75,F4=Array.from({length:32},(e,t)=>{let[s,r,o]=Vse(t/31*Nse);return[s-1,r-1,o-1]}),$se=[...F4].reverse(),S0=.3,Xse=w.fn([m,n,m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(t.x,__tsover_sub(1,t.y)),c=__tsover_mul(s,.01),d=__tsover_div(a,31),u=__tsover_add(1,__tsover_mul(c,d)),p=__tsover_mul(__tsover_mul(__tsover_mul(i,c),d),1.2),_=pe(p),f=ae(p),h=__tsover_mul(__tsover_sub(r.x,l.x),o),g=__tsover_sub(r.y,l.y),y=__tsover_sub(__tsover_mul(h,_),__tsover_mul(g,f)),b=__tsover_add(__tsover_mul(h,f),__tsover_mul(g,_));return m(__tsover_add(__tsover_div(__tsover_div(y,u),o),l.x),__tsover_add(__tsover_div(b,u),l.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"tapIndex\"},{type:\"i\",name:\"spiral\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"radius\",[1,\"intensity\",\"*\",[5,\"0.01\"]]],[13,\"along\",[1,\"tapIndex\",\"/\",[5,\"31\"]]],[13,\"scale\",[1,[5,\"1\"],\"+\",[1,\"radius\",\"*\",\"along\"]]],[13,\"angle\",[1,[1,[1,\"spiral\",\"*\",\"radius\"],\"*\",\"along\"],\"*\",\"MOTION_BLUR_SPIRAL_TWIST\"]],[13,\"cosA\",[6,\"std.cos\",[\"angle\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angle\"]]],[13,\"acdX\",[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]],\"*\",\"aspect\"]],[13,\"acdY\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"rotX\",[1,[1,\"acdX\",\"*\",\"cosA\"],\"-\",[1,\"acdY\",\"*\",\"sinA\"]]],[13,\"rotY\",[1,[1,\"acdX\",\"*\",\"sinA\"],\"+\",[1,\"acdY\",\"*\",\"cosA\"]]],[10,[6,\"d.vec2f\",[[1,[1,[1,\"rotX\",\"/\",\"scale\"],\"/\",\"aspect\"],\"+\",[7,\"centerPos\",\"x\"]],[1,[1,\"rotY\",\"/\",\"scale\"],\"+\",[7,\"centerPos\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m,MOTION_BLUR_SPIRAL_TWIST:()=>1.2,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),Hse=w.fn([m,m,n,n,n,n,n,m],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=m(s.x,__tsover_sub(1,s.y)),u=__tsover_mul(__tsover_sub(t.x,d.x),r),p=__tsover_sub(t.y,d.y),_=Ue(__tsover_add(__tsover_mul(u,u),__tsover_mul(p,p))),f=__tsover_mul(B(d.x,__tsover_sub(1,d.x)),r),h=B(d.y,__tsover_sub(1,d.y)),g=B(Ue(__tsover_add(__tsover_mul(f,f),__tsover_mul(h,h))),1e-4),y=G(__tsover_div(_,g),0,1),b=K(n(1),__tsover_mul(y,y),a),x=__tsover_mul(o,b),P=B(x,0),C=B(__tsover_mul(x,-1),0),E=be(__tsover_mul(i,__tsover_sub(1,S0)),__tsover_add(__tsover_mul(i,__tsover_add(1,S0)),1e-4),y),R=K(n(1),E,Et(1e-4,i)),U=m(__tsover_mul(t.x,c.x),__tsover_mul(t.y,c.y)),L=Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(U.x,.06711056),__tsover_mul(U.y,.00583715)))));return S(P,C,R,__tsover_mul(__tsover_sub(L,.5),l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"dispersion\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"focus\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"centerPos\",[6,\"d.vec2f\",[[7,\"center\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]],\"*\",\"aspect\"]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[13,\"farX\",[1,[6,\"std.max\",[[7,\"centerPos\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"centerPos\",\"x\"]]]],\"*\",\"aspect\"]],[13,\"farY\",[6,\"std.max\",[[7,\"centerPos\",\"y\"],[1,[5,\"1\"],\"-\",[7,\"centerPos\",\"y\"]]]]],[13,\"dMax\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"farX\",\"*\",\"farX\"],\"+\",[1,\"farY\",\"*\",\"farY\"]]]],[5,\"0.0001\"]]]],[13,\"dNorm\",[6,\"std.clamp\",[[1,\"dist\",\"/\",\"dMax\"],[5,\"0\"],[5,\"1\"]]]],[13,\"ramp\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],[1,\"dNorm\",\"*\",\"dNorm\"],\"falloff\"]]],[13,\"strength\",[1,\"dispersion\",\"*\",\"ramp\"]],[13,\"dPos\",[6,\"std.max\",[\"strength\",[5,\"0\"]]]],[13,\"dNeg\",[6,\"std.max\",[[1,\"strength\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"]]]],[13,\"focusEdge\",[6,\"std.smoothstep\",[[1,\"focus\",\"*\",[1,[5,\"1\"],\"-\",\"FOCUS_SOFTNESS\"]],[1,[1,\"focus\",\"*\",[1,[5,\"1\"],\"+\",\"FOCUS_SOFTNESS\"]],\"+\",[5,\"0.0001\"]],\"dNorm\"]]],[13,\"focusMask\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],\"focusEdge\",[6,\"std.step\",[[5,\"0.0001\"],\"focus\"]]]]],[13,\"px\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",[7,\"viewport\",\"x\"]],[1,[7,\"uv\",\"y\"],\"*\",[7,\"viewport\",\"y\"]]]]],[13,\"ign\",[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[7,\"px\",\"x\"],\"*\",[5,\"0.06711056\"]],\"+\",[1,[7,\"px\",\"y\"],\"*\",[5,\"0.00583715\"]]]]]]]]],[13,\"jitterPhase\",[1,[1,\"ign\",\"-\",[5,\"0.5\"]],\"*\",\"jitter\"]],[10,[6,\"d.vec4f\",[\"dPos\",\"dNeg\",\"focusMask\",\"jitterPhase\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.mix\":()=>K,\"d.f32\":()=>n,\"std.smoothstep\":()=>be,FOCUS_SOFTNESS:()=>S0,\"std.step\":()=>Et,\"std.fract\":()=>Re,\"d.vec4f\":()=>S}})&&e.f)({})),jse=w.fn([S,n,A,A,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Se(t.xyz,A(.2126,.7152,.0722)),c=__tsover_mul(s,__tsover_add(1,__tsover_mul(__tsover_mul(i,l),l))),d=A(1,1,1).add(r.mul(a.x)).add(o.mul(a.y));return S(__tsover_mul(d.x,c),__tsover_mul(d.y,c),__tsover_mul(d.z,c),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sample\"},{type:\"i\",name:\"weight\"},{type:\"i\",name:\"tintForward\"},{type:\"i\",name:\"tintReversed\"},{type:\"i\",name:\"field\"},{type:\"i\",name:\"highlightGain\"}],body:[0,[[13,\"lum\",[6,\"std.dot\",[[7,\"sample\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"boost\",[1,\"weight\",\"*\",[1,[5,\"1\"],\"+\",[1,[1,\"highlightGain\",\"*\",\"lum\"],\"*\",\"lum\"]]]],[13,\"tint\",[6,[7,[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"add\"],[[6,[7,\"tintForward\",\"mul\"],[[7,\"field\",\"x\"]]]]],\"add\"],[[6,[7,\"tintReversed\",\"mul\"],[[7,\"field\",\"y\"]]]]]],[10,[6,\"d.vec4f\",[[1,[7,\"tint\",\"x\"],\"*\",\"boost\"],[1,[7,\"tint\",\"y\"],\"*\",\"boost\"],[1,[7,\"tint\",\"z\"],\"*\",\"boost\"],\"boost\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Kse=w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t.div(B(s,S(1e-4,1e-4,1e-4,1e-4)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorSum\"},{type:\"i\",name:\"weightSum\"}],body:[0,[[10,[6,[7,\"colorSum\",\"div\"],[[6,\"std.max\",[\"weightSum\",[6,\"d.vec4f\",[[5,\"0.0001\"],[5,\"0.0001\"],[5,\"0.0001\"],[5,\"0.0001\"]]]]]]]]]]},externals:{\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&e.f)({}));function AS([e,t,s]){return new fs(()=>`vec3f(${fo(e)}, ${fo(t)}, ${fo(s)})`)}function Qse(e,t,s,r){let{focus:o,uv:a,aspect:i,viewportSize:l}=t,c=ns(W(Hse,\"motionBlurDetailField\",[a,s.center,i,s.dispersion,s.falloff,s.focus,s.jitter,l]),\"mbField\"),d=ns(t.amount.mul(c.member(\"z\")),\"mbAmount\"),u=ns(s.bias,\"mbBias\"),p=c.member(\"w\"),_=ns(s.highlights.mul(12),\"mbHighlight\"),f=31,h=f/2,g=x=>{if(e===\"linear\"){let C=x/f-.5;return W(U4,\"linearBlurTapCoord\",[a,o,d,l,$e(C).add(u.mul(Math.abs(C))).add(p.mul(1/f))])}if(e===\"orbit\")return W(O4,\"angularBlurTapCoord\",[o,d,a,i,$e(x).add(u.mul(Math.abs(x-h))).add(p)]);let P=$e(x).add(u.mul(-h)).add(p);return s.spiral?W(Xse,\"zoomBlurSpiralTapCoord\",[o,d,a,i,P,s.spiral]):W(G4,\"zoomBlurTapCoord\",[o,d,a,i,P])},y,b;for(let x=0;x<32;x++){let P=ns(r(g(x)),\"mbTap\"),C=ns(W(jse,\"motionBlurDetailTapWeight\",[P,$e(L4[x]),AS(F4[x]),AS($se[x]),c,_]),\"mbWeight\"),E=P.mul(C);y=y?y.add(E):E,b=b?b.add(C):C}return W(Kse,\"motionBlurDetailResolve\",[y,b])}var Zse=w.fn([m,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Pr(t.mul(1e3)).mul(2).sub(m(1,1)).mul(s).div(r);return t.add(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"seed\",[6,[7,\"uv\",\"mul\"],[[5,\"1000\"]]]],[13,\"randVec\",[6,\"noise.hash22\",[\"seed\"]]],[13,\"offset\",[6,[7,[6,[7,[6,[7,[6,[7,\"randVec\",\"mul\"],[[5,\"2\"]]],\"sub\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]],\"mul\"],[\"intensity\"]],\"div\"],[\"viewport\"]]],[10,[6,[7,\"uv\",\"add\"],[\"offset\"]]]]]},externals:{\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m}})&&e.f)({})),Jse=w.fn([m,n,m,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=t.mul(1e3),l=Pr(i),c=Pr(i.add(a)),d=l.add(c.sub(l).mul(o)).mul(2).sub(m(1,1)).mul(s).div(r);return t.add(d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"chromatic\"},{type:\"i\",name:\"salt\"}],body:[0,[[13,\"seed\",[6,[7,\"uv\",\"mul\"],[[5,\"1000\"]]]],[13,\"shared\",[6,\"noise.hash22\",[\"seed\"]]],[13,\"own\",[6,\"noise.hash22\",[[6,[7,\"seed\",\"add\"],[\"salt\"]]]]],[13,\"randVec\",[6,[7,\"shared\",\"add\"],[[6,[7,[6,[7,\"own\",\"sub\"],[\"shared\"]],\"mul\"],[\"chromatic\"]]]]],[13,\"offset\",[6,[7,[6,[7,[6,[7,[6,[7,\"randVec\",\"mul\"],[[5,\"2\"]]],\"sub\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]],\"mul\"],[\"intensity\"]],\"div\"],[\"viewport\"]]],[10,[6,[7,\"uv\",\"add\"],[\"offset\"]]]]]},externals:{\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m}})&&e.f)({})),ere=[17.3,91.7],tre=[53.1,29.9];function sre(e){let t=W(Zse,\"diffuseBlurUV\",[e.uv,e.amount,e.viewportSize]),s=e.chromatic;if(!s)return Ha(t,e.sample,e.edgeMode);let r=ns(Ha(t,e.sample,e.edgeMode),\"scatterShared\"),o=l=>{let c=new fs(()=>`vec2f(${fo(l[0])}, ${fo(l[1])})`);return Ha(W(Jse,\"diffuseBlurChannelUV\",[e.uv,e.amount,e.viewportSize,s,c]),e.sample,e.edgeMode)},a=o(ere),i=o(tre);return Ct(a.member(\"r\"),r.member(\"g\"),i.member(\"b\"),r.member(\"a\"))}var rre=[.056,.135,.278,.487,.726,.923,1,.923,.726,.487,.278,.135,.056],ore=6.214,wS=rre.map(e=>e/ore),TS=6,are=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(r,Vu),i=__tsover_mul(o,.2),l=__tsover_div(s.x,s.y),c=__tsover_div(__tsover_mul(ae(a),i),l),d=__tsover_mul(__tsover_mul(pe(a),-1),i);return m(__tsover_sub(t.x,c),__tsover_sub(t.y,d))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"distance\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"dist\",[1,\"distance\",\"*\",[5,\"0.2\"]]],[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"ox\",[1,[1,[6,\"std.sin\",[\"angleRad\"]],\"*\",\"dist\"],\"/\",\"aspect\"]],[13,\"oy\",[1,[1,[6,\"std.cos\",[\"angleRad\"]],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"dist\"]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"ox\"],[1,[7,\"uv\",\"y\"],\"-\",\"oy\"]]]]]]},externals:{DEG_TO_RAD:()=>Vu,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"d.vec2f\":()=>m}})&&e.f)({})),nre=w.fn([m,m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return m(__tsover_add(t.x,__tsover_div(__tsover_mul(o,r),s.x)),__tsover_add(t.y,__tsover_div(__tsover_mul(a,r),s.y)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"blurRadius\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,[1,\"ox\",\"*\",\"blurRadius\"],\"/\",[7,\"viewport\",\"x\"]]],[1,[7,\"uv\",\"y\"],\"+\",[1,[1,\"oy\",\"*\",\"blurRadius\"],\"/\",[7,\"viewport\",\"y\"]]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),ire=w.fn([S,S,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=A(s.x,s.y,s.z),i=__tsover_mul(s.w,r),l=G(__tsover_sub(i,t.w),0,1),c=a.mul(s.w).mul(l),d=a.mul(s.w).mul(r),u=__tsover_sub(1,t.w),p=A(t.x,t.y,t.z).add(d.mul(u)),_=B(__tsover_add(t.w,__tsover_mul(i,u)),t.w),f=o>.5,h=N(p,c,f),g=N(_,l,f);return S(h.x,h.y,h.z,g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"originalColor\"},{type:\"i\",name:\"shadowColor\"},{type:\"i\",name:\"shadowAlpha\"},{type:\"i\",name:\"cutout\"}],body:[0,[[13,\"shadowRgb\",[6,\"d.vec3f\",[[7,\"shadowColor\",\"x\"],[7,\"shadowColor\",\"y\"],[7,\"shadowColor\",\"z\"]]]],[13,\"shadowA\",[1,[7,\"shadowColor\",\"w\"],\"*\",\"shadowAlpha\"]],[13,\"cutoutA\",[6,\"std.clamp\",[[1,\"shadowA\",\"-\",[7,\"originalColor\",\"w\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"cutoutRgb\",[6,[7,[6,[7,\"shadowRgb\",\"mul\"],[[7,\"shadowColor\",\"w\"]]],\"mul\"],[\"cutoutA\"]]],[13,\"shadowPremulRgb\",[6,[7,[6,[7,\"shadowRgb\",\"mul\"],[[7,\"shadowColor\",\"w\"]]],\"mul\"],[\"shadowAlpha\"]]],[13,\"oneMinusOrigA\",[1,[5,\"1\"],\"-\",[7,\"originalColor\",\"w\"]]],[13,\"normalRgb\",[6,[7,[6,\"d.vec3f\",[[7,\"originalColor\",\"x\"],[7,\"originalColor\",\"y\"],[7,\"originalColor\",\"z\"]]],\"add\"],[[6,[7,\"shadowPremulRgb\",\"mul\"],[\"oneMinusOrigA\"]]]]],[13,\"normalA\",[6,\"std.max\",[[1,[7,\"originalColor\",\"w\"],\"+\",[1,\"shadowA\",\"*\",\"oneMinusOrigA\"]],[7,\"originalColor\",\"w\"]]]],[13,\"useCut\",[1,\"cutout\",\">\",[5,\"0.5\"]]],[13,\"rgb\",[6,\"std.select\",[\"normalRgb\",\"cutoutRgb\",\"useCut\"]]],[13,\"a\",[6,\"std.select\",[\"normalA\",\"cutoutA\",\"useCut\"]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"a\"]]]]]},externals:{\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"std.max\":()=>B,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&e.f)({}));function lre(e){let{at:t,uv:s,viewportSize:r,blurRadius:o,sample:a,convertToTexture:i}=e,l=(d,u,p)=>W(nre,\"dropShadowTapUV\",[d,r,o,$e(u),$e(p)]),c=i(Ct(qb({weights:wS,tapCoord:d=>l(t,d-TS,0),sample:a,component:\"a\"}),$e(0),$e(0),$e(1)));return qb({weights:wS,tapCoord:d=>l(s,0,d-TS),sample:d=>c.sample(d),component:\"r\"})}var c1=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return m(__tsover_add(t.x,__tsover_div(r,s.x)),__tsover_add(t.y,__tsover_div(o,s.y)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"dirX\"},{type:\"i\",name:\"dirY\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,\"dirX\",\"/\",[7,\"viewport\",\"x\"]]],[1,[7,\"uv\",\"y\"],\"+\",[1,\"dirY\",\"/\",[7,\"viewport\",\"y\"]]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),cre=w.fn([S,S,S,S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_add(1,__tsover_mul(i,4)),c=__tsover_mul(i,-1),d=G(t.xyz.mul(l).add(s.xyz.mul(c)).add(r.xyz.mul(c)).add(o.xyz.mul(c)).add(a.xyz.mul(c)),A(0,0,0),A(1,1,1));return S(d.x,d.y,d.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"top\"},{type:\"i\",name:\"bottom\"},{type:\"i\",name:\"left\"},{type:\"i\",name:\"right\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"centerWeight\",[1,[5,\"1\"],\"+\",[1,\"amount\",\"*\",[5,\"4\"]]]],[13,\"neighborWeight\",[1,\"amount\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"rgb\",[6,[7,[6,[7,[6,[7,[6,[7,[6,[7,[7,\"center\",\"xyz\"],\"mul\"],[\"centerWeight\"]],\"add\"],[[6,[7,[7,\"top\",\"xyz\"],\"mul\"],[\"neighborWeight\"]]]],\"add\"],[[6,[7,[7,\"bottom\",\"xyz\"],\"mul\"],[\"neighborWeight\"]]]],\"add\"],[[6,[7,[7,\"left\",\"xyz\"],\"mul\"],[\"neighborWeight\"]]]],\"add\"],[[6,[7,[7,\"right\",\"xyz\"],\"mul\"],[\"neighborWeight\"]]]]],[13,\"clamped\",[6,\"std.clamp\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[10,[6,\"d.vec4f\",[[7,\"clamped\",\"x\"],[7,\"clamped\",\"y\"],[7,\"clamped\",\"z\"],[7,\"center\",\"w\"]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({}));function dre(e){let{uv:t,viewportSize:s,amount:r,sample:o}=e;return W(cre,\"sharpnessCompose\",[o(t),o(W(c1,\"sharpnessTapUV\",[t,s,$e(0),$e(1)])),o(W(c1,\"sharpnessTapUV\",[t,s,$e(0),$e(-1)])),o(W(c1,\"sharpnessTapUV\",[t,s,$e(-1),$e(0)])),o(W(c1,\"sharpnessTapUV\",[t,s,$e(1),$e(0)])),r])}var ure=w.fn([m,n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=s>1,l=B(N(__tsover_mul(r,s),r,i),1),c=B(N(r,__tsover_div(r,s),i),1),d=m(__tsover_div(ie(__tsover_mul(t.x,l)),l),__tsover_div(ie(__tsover_mul(t.y,c)),c)),u=m(__tsover_sub(Re(__tsover_mul(t.x,l)),.5),__tsover_sub(Re(__tsover_mul(t.y,c)),.5)),p=__tsover_sub(.5,__tsover_mul(o,.5)),_=__tsover_mul(a,p),f=B(__tsover_add(__tsover_sub(re(u.x),p),_),0),h=B(__tsover_add(__tsover_sub(re(u.y),p),_),0),g=__tsover_sub(he(m(f,h)),_),y=N(n(0),n(1),g<=0);return A(d.x,d.y,y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"gap\"},{type:\"i\",name:\"roundness\"}],body:[0,[[13,\"isWide\",[1,\"aspect\",\">\",[5,\"1\"]]],[13,\"pixelCountX\",[6,\"std.max\",[[6,\"std.select\",[[1,\"scale\",\"*\",\"aspect\"],\"scale\",\"isWide\"]],[5,\"1\"]]]],[13,\"pixelCountY\",[6,\"std.max\",[[6,\"std.select\",[\"scale\",[1,\"scale\",\"/\",\"aspect\"],\"isWide\"]],[5,\"1\"]]]],[13,\"sampleUV\",[6,\"d.vec2f\",[[1,[6,\"std.floor\",[[1,[7,\"uv\",\"x\"],\"*\",\"pixelCountX\"]]],\"/\",\"pixelCountX\"],[1,[6,\"std.floor\",[[1,[7,\"uv\",\"y\"],\"*\",\"pixelCountY\"]]],\"/\",\"pixelCountY\"]]]],[13,\"localUV\",[6,\"d.vec2f\",[[1,[6,\"std.fract\",[[1,[7,\"uv\",\"x\"],\"*\",\"pixelCountX\"]]],\"-\",[5,\"0.5\"]],[1,[6,\"std.fract\",[[1,[7,\"uv\",\"y\"],\"*\",\"pixelCountY\"]]],\"-\",[5,\"0.5\"]]]]],[13,\"halfSize\",[1,[5,\"0.5\"],\"-\",[1,\"gap\",\"*\",[5,\"0.5\"]]]],[13,\"cornerRadius\",[1,\"roundness\",\"*\",\"halfSize\"]],[13,\"qx\",[6,\"std.max\",[[1,[1,[6,\"std.abs\",[[7,\"localUV\",\"x\"]]],\"-\",\"halfSize\"],\"+\",\"cornerRadius\"],[5,\"0\"]]]],[13,\"qy\",[6,\"std.max\",[[1,[1,[6,\"std.abs\",[[7,\"localUV\",\"y\"]]],\"-\",\"halfSize\"],\"+\",\"cornerRadius\"],[5,\"0\"]]]],[13,\"sdf\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"qx\",\"qy\"]]]],\"-\",\"cornerRadius\"]],[13,\"mask\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"sdf\",\"<=\",[5,\"0\"]]]]],[10,[6,\"d.vec3f\",[[7,\"sampleUV\",\"x\"],[7,\"sampleUV\",\"y\"],\"mask\"]]]]]},externals:{\"std.max\":()=>B,\"std.select\":()=>N,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"std.abs\":()=>re,\"std.length\":()=>he,\"d.f32\":()=>n,\"d.vec3f\":()=>A}})&&e.f)({}));function pre(e){let t=W(ure,\"pixelateSample\",[e.uv,e.aspect,e.scale,e.gap,e.roundness]),s=e.sampleStraight(t.member(\"xy\"));return Ct(s.member(\"rgb\"),s.member(\"a\").mul(t.member(\"z\")))}var mre=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=s>1,c=m(N(__tsover_mul(o,s),o,l),N(o,__tsover_div(o,s),l)),d=m(__tsover_mul(t.x,s),t.y),u=__tsover_mul(a,Vu),p=pe(u),_=ae(u),f=d.sub(m(__tsover_mul(.5,s),.5)),h=m(__tsover_sub(__tsover_mul(f.x,p),__tsover_mul(f.y,_)),__tsover_add(__tsover_mul(f.x,_),__tsover_mul(f.y,p))).add(m(__tsover_mul(.5,s),.5)),g=m(__tsover_div(h.x,s),h.y),y=ie(g.mul(c)).div(c),b=g.sub(y),x=m(1,1).div(c),P=b.div(x).sub(m(.5,.5)),C=__tsover_add(__tsover_mul(P.x,P.x),__tsover_mul(P.y,P.y)),E=B(__tsover_sub(1,__tsover_mul(C,__tsover_mul(i,4))),0),R=__tsover_mul(r,.025),U=__tsover_mul(R,E),L=m(__tsover_div(__tsover_mul(P.x,U),s),__tsover_mul(P.y,U));return t.add(L)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"baseTileCount\"},{type:\"i\",name:\"rotationDegrees\"},{type:\"i\",name:\"roundnessAmount\"}],body:[0,[[13,\"isWide\",[1,\"aspect\",\">\",[5,\"1\"]]],[13,\"tileCount\",[6,\"d.vec2f\",[[6,\"std.select\",[[1,\"baseTileCount\",\"*\",\"aspect\"],\"baseTileCount\",\"isWide\"]],[6,\"std.select\",[\"baseTileCount\",[1,\"baseTileCount\",\"/\",\"aspect\"],\"isWide\"]]]]],[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"rotationRadians\",[1,\"rotationDegrees\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"rotationRadians\"]]],[13,\"sinA\",[6,\"std.sin\",[\"rotationRadians\"]]],[13,\"centered\",[6,[7,\"aspectCorrectedUV\",\"sub\"],[[6,\"d.vec2f\",[[1,[5,\"0.5\"],\"*\",\"aspect\"],[5,\"0.5\"]]]]]],[13,\"rotatedX\",[1,[1,[7,\"centered\",\"x\"],\"*\",\"cosA\"],\"-\",[1,[7,\"centered\",\"y\"],\"*\",\"sinA\"]]],[13,\"rotatedY\",[1,[1,[7,\"centered\",\"x\"],\"*\",\"sinA\"],\"+\",[1,[7,\"centered\",\"y\"],\"*\",\"cosA\"]]],[13,\"rotatedUV\",[6,[7,[6,\"d.vec2f\",[\"rotatedX\",\"rotatedY\"]],\"add\"],[[6,\"d.vec2f\",[[1,[5,\"0.5\"],\"*\",\"aspect\"],[5,\"0.5\"]]]]]],[13,\"gridUV\",[6,\"d.vec2f\",[[1,[7,\"rotatedUV\",\"x\"],\"/\",\"aspect\"],[7,\"rotatedUV\",\"y\"]]]],[13,\"cellCoord\",[6,[7,[6,\"std.floor\",[[6,[7,\"gridUV\",\"mul\"],[\"tileCount\"]]]],\"div\"],[\"tileCount\"]]],[13,\"localUV\",[6,[7,\"gridUV\",\"sub\"],[\"cellCoord\"]]],[13,\"oneOverTile\",[6,[7,[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]],\"div\"],[\"tileCount\"]]],[13,\"normalizedLocalUV\",[6,[7,\"localUV\",\"div\"],[\"oneOverTile\"]]],[13,\"fromCenter\",[6,[7,\"normalizedLocalUV\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"distFromCenter\",[1,[1,[7,\"fromCenter\",\"x\"],\"*\",[7,\"fromCenter\",\"x\"]],\"+\",[1,[7,\"fromCenter\",\"y\"],\"*\",[7,\"fromCenter\",\"y\"]]]],[13,\"roundnessFactor\",[1,[5,\"1\"],\"-\",[1,\"distFromCenter\",\"*\",[1,\"roundnessAmount\",\"*\",[5,\"4\"]]]]],[13,\"clampedRoundness\",[6,\"std.max\",[\"roundnessFactor\",[5,\"0\"]]]],[13,\"distortionFactor\",[1,\"intensity\",\"*\",[5,\"0.025\"]]],[13,\"scaleFactor\",[1,\"distortionFactor\",\"*\",\"clampedRoundness\"]],[13,\"distortion\",[6,\"d.vec2f\",[[1,[1,[7,\"fromCenter\",\"x\"],\"*\",\"scaleFactor\"],\"/\",\"aspect\"],[1,[7,\"fromCenter\",\"y\"],\"*\",\"scaleFactor\"]]]],[10,[6,[7,\"uv\",\"add\"],[\"distortion\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.select\":()=>N,DEG_TO_RAD:()=>Vu,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.floor\":()=>ie,\"std.max\":()=>B}})&&e.f)({}));function I4(e){return W(mre,\"glassTilesUV\",[e.uv,e.aspect,e.intensity,e.tileCount,e.rotation,e.roundness])}function Y4(e){let t=I4(e);return W(Yt,\"unpremultiplyAlpha\",[g_(e.texture,t)])}function W4(e){return W(N3,\"edgeClampUV\",[I4(e)])}var SS=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s,.002);return m(__tsover_add(t.x,__tsover_mul(o,r)),t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"colorShift\"},{type:\"i\",name:\"dir\"}],body:[0,[[13,\"scaledColorShift\",[1,\"colorShift\",\"*\",[5,\"0.002\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,\"scaledColorShift\",\"*\",\"dir\"]],[7,\"uv\",\"y\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),_re=w.fn([S,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return A(t.x,s.y,r.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"redSample\"},{type:\"i\",name:\"greenSample\"},{type:\"i\",name:\"blueSample\"}],body:[0,[[10,[6,\"d.vec3f\",[[7,\"redSample\",\"x\"],[7,\"greenSample\",\"y\"],[7,\"blueSample\",\"z\"]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),fre=w.fn([A,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return t.sub(A(.5)).mul(s).add(A(.5)).mul(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"brightness\"}],body:[0,[[10,[6,[7,[6,[7,[6,[7,[6,[7,\"color\",\"sub\"],[[6,\"d.vec3f\",[[5,\"0.5\"]]]]],\"mul\"],[\"contrast\"]],\"add\"],[[6,\"d.vec3f\",[[5,\"0.5\"]]]]],\"mul\"],[\"brightness\"]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})),vre=w.fn([A,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,r),i=ae(__tsover_mul(a,__tsover_mul(3.14159,2))),l=__tsover_sub(1,__tsover_mul(o,__tsover_add(__tsover_mul(i,.5),.5)));return t.mul(l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"scanlineFrequency\"},{type:\"i\",name:\"scanlineIntensity\"}],body:[0,[[13,\"scanlinePosition\",[1,\"uvY\",\"*\",\"scanlineFrequency\"]],[13,\"scanlineWave\",[6,\"std.sin\",[[1,\"scanlinePosition\",\"*\",[1,[5,\"3.14159\"],\"*\",[5,\"2\"]]]]]],[13,\"scanlineEffect\",[1,[5,\"1\"],\"-\",[1,\"scanlineIntensity\",\"*\",[1,[1,\"scanlineWave\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]],[10,[6,[7,\"color\",\"mul\"],[\"scanlineEffect\"]]]]]},externals:{\"std.sin\":()=>ae}})&&e.f)({})),hre=w.fn([A,m,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(r,.5),a=Re(s.mul(o)),i=__tsover_add(__tsover_mul(ae(__tsover_mul(a.x,6.28318)),.1),.95),l=__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(a.x,6.28318),2.09)),.1),.95),c=__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(a.x,6.28318),4.18)),.1),.95);return A(__tsover_mul(t.x,i),__tsover_mul(t.y,l),__tsover_mul(t.z,c))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"pixelSize\"}],body:[0,[[13,\"phosphorScale\",[1,\"pixelSize\",\"*\",[5,\"0.5\"]]],[13,\"pixelPhase\",[6,\"std.fract\",[[6,[7,\"uv\",\"mul\"],[\"phosphorScale\"]]]]],[13,\"redMask\",[1,[1,[6,\"std.sin\",[[1,[7,\"pixelPhase\",\"x\"],\"*\",[5,\"6.28318\"]]]],\"*\",[5,\"0.1\"]],\"+\",[5,\"0.95\"]]],[13,\"greenMask\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"pixelPhase\",\"x\"],\"*\",[5,\"6.28318\"]],\"+\",[5,\"2.09\"]]]],\"*\",[5,\"0.1\"]],\"+\",[5,\"0.95\"]]],[13,\"blueMask\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"pixelPhase\",\"x\"],\"*\",[5,\"6.28318\"]],\"+\",[5,\"4.18\"]]]],\"*\",[5,\"0.1\"]],\"+\",[5,\"0.95\"]]],[10,[6,\"d.vec3f\",[[1,[7,\"color\",\"x\"],\"*\",\"redMask\"],[1,[7,\"color\",\"y\"],\"*\",\"greenMask\"],[1,[7,\"color\",\"z\"],\"*\",\"blueMask\"]]]]]]},externals:{\"std.fract\":()=>Re,\"std.sin\":()=>ae,\"d.vec3f\":()=>A}})&&e.f)({})),gre=w.fn([A,m,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=s.sub(m(.5,.5)),l=he(m(__tsover_mul(i.x,r),i.y)),c=__tsover_sub(1,__tsover_mul(o,.9)),d=__tsover_add(c,.5),u=K(1,__tsover_sub(1,be(c,d,l)),a);return t.mul(u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"vignetteRadius\"},{type:\"i\",name:\"vignetteIntensity\"}],body:[0,[[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"aspectCorrectedUV\",[6,\"d.vec2f\",[[1,[7,\"centeredUV\",\"x\"],\"*\",\"aspect\"],[7,\"centeredUV\",\"y\"]]]],[13,\"vignetteDistance\",[6,\"std.length\",[\"aspectCorrectedUV\"]]],[13,\"innerEdge\",[1,[5,\"1\"],\"-\",[1,\"vignetteRadius\",\"*\",[5,\"0.9\"]]]],[13,\"outerEdge\",[1,\"innerEdge\",\"+\",[5,\"0.5\"]]],[13,\"vignetteValue\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"innerEdge\",\"outerEdge\",\"vignetteDistance\"]]]],[13,\"vignette\",[6,\"std.mix\",[[5,\"1\"],\"vignetteValue\",\"vignetteIntensity\"]]],[10,[6,[7,\"color\",\"mul\"],[\"vignette\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.smoothstep\":()=>be,\"std.mix\":()=>K}})&&e.f)({})),PS=487,dm=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Ys(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"noise.hash12\",[\"p\"]]]]]},externals:{\"noise.hash12\":()=>Ys}})&&e.f)({})),il=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=Re(t),o=r.mul(r).mul(m(3,3).sub(r.mul(2))),a=dm(s),i=dm(s.add(m(1,0))),l=dm(s.add(m(0,1))),c=dm(s.add(m(1,1)));return K(K(a,i,o.x),K(l,c,o.x),o.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f\",[6,\"std.fract\",[\"p\"]]],[13,\"u\",[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,\"d.vec2f\",[[5,\"3\"],[5,\"3\"]]],\"sub\"],[[6,[7,\"f\",\"mul\"],[[5,\"2\"]]]]]]]],[13,\"a\",[6,\"hash2D\",[\"i\"]]],[13,\"b\",[6,\"hash2D\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]]]]]]],[13,\"c\",[6,\"hash2D\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]]]]]]],[13,\"dd\",[6,\"hash2D\",[[6,[7,\"i\",\"add\"],[[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[\"a\",\"b\",[7,\"u\",\"x\"]]],[6,\"std.mix\",[\"c\",\"dd\",[7,\"u\",\"x\"]]],[7,\"u\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"d.vec2f\":()=>m,hash2D:()=>dm,\"std.mix\":()=>K}})&&e.f)({})),CS=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return be(.45,.8,il(m(__tsover_mul(t,.4),0)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[6,\"std.smoothstep\",[[5,\"0.45\"],[5,\"0.8\"],[6,\"smoothNoise2D\",[[6,\"d.vec2f\",[[1,\"t\",\"*\",[5,\"0.4\"]],[5,\"0\"]]]]]]]]]]},externals:{\"std.smoothstep\":()=>be,smoothNoise2D:()=>il,\"d.vec2f\":()=>m}})&&e.f)({})),MS=w.fn([n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=ie(__tsover_mul(t,PS)),i=__tsover_mul(__tsover_sub(Ys(m(a,s)),.5),2),l=__tsover_mul(__tsover_sub(Ys(m(a,__tsover_add(s,69.42))),.5),2),c=__tsover_add(.25,__tsover_mul(o,.75)),d=__tsover_mul(__tsover_mul(__tsover_mul(i,r),.008),c);return m(__tsover_mul(__tsover_mul(__tsover_mul(l,r),.004),c),d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"scanlineNoise\"},{type:\"i\",name:\"burst\"}],body:[0,[[13,\"rowInt\",[6,\"std.floor\",[[1,\"uvY\",\"*\",\"FIELD_LINES\"]]]],[13,\"h0\",[1,[1,[6,\"noise.hash12\",[[6,\"d.vec2f\",[\"rowInt\",\"t\"]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"h1\",[1,[1,[6,\"noise.hash12\",[[6,\"d.vec2f\",[\"rowInt\",[1,\"t\",\"+\",[5,\"69.42\"]]]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"fineGate\",[1,[5,\"0.25\"],\"+\",[1,\"burst\",\"*\",[5,\"0.75\"]]]],[13,\"chromaRowOffset\",[1,[1,[1,\"h0\",\"*\",\"scanlineNoise\"],\"*\",[5,\"0.008\"]],\"*\",\"fineGate\"]],[13,\"lumaRowOffset\",[1,[1,[1,\"h1\",\"*\",\"scanlineNoise\"],\"*\",[5,\"0.004\"]],\"*\",\"fineGate\"]],[10,[6,\"d.vec2f\",[\"lumaRowOffset\",\"chromaRowOffset\"]]]]]},externals:{\"std.floor\":()=>ie,FIELD_LINES:()=>PS,\"noise.hash12\":()=>Ys,\"d.vec2f\":()=>m}})&&e.f)({})),ES=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(il(m(__tsover_mul(t,3),__tsover_mul(s,.8))),.5),a=__tsover_sub(il(m(__tsover_mul(t,30),__tsover_mul(s,6))),.5);return __tsover_mul(__tsover_add(__tsover_mul(o,.008),__tsover_mul(a,.002)),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"wobble\"}],body:[0,[[13,\"wave1\",[1,[6,\"smoothNoise2D\",[[6,\"d.vec2f\",[[1,\"uvY\",\"*\",[5,\"3\"]],[1,\"t\",\"*\",[5,\"0.8\"]]]]]],\"-\",[5,\"0.5\"]]],[13,\"wave2\",[1,[6,\"smoothNoise2D\",[[6,\"d.vec2f\",[[1,\"uvY\",\"*\",[5,\"30\"]],[1,\"t\",\"*\",[5,\"6\"]]]]]],\"-\",[5,\"0.5\"]]],[10,[1,[1,[1,\"wave1\",\"*\",[5,\"0.008\"]],\"+\",[1,\"wave2\",\"*\",[5,\"0.002\"]]],\"*\",\"wobble\"]]]]},externals:{smoothNoise2D:()=>il,\"d.vec2f\":()=>m}})&&e.f)({})),kS=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=be(.92,.99,ae(__tsover_sub(__tsover_mul(t,8),__tsover_mul(s,3.77)))),a=be(.3,1,il(m(__tsover_mul(t,4.77),s)));return __tsover_mul(__tsover_mul(__tsover_mul(o,a),r),-.018)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"wobble\"}],body:[0,[[13,\"creasePhase\",[6,\"std.smoothstep\",[[5,\"0.92\"],[5,\"0.99\"],[6,\"std.sin\",[[1,[1,\"uvY\",\"*\",[5,\"8\"]],\"-\",[1,\"t\",\"*\",[5,\"3.77\"]]]]]]]],[13,\"creaseNoise\",[6,\"std.smoothstep\",[[5,\"0.3\"],[5,\"1\"],[6,\"smoothNoise2D\",[[6,\"d.vec2f\",[[1,\"uvY\",\"*\",[5,\"4.77\"]],\"t\"]]]]]]],[10,[1,[1,[1,\"creasePhase\",\"*\",\"creaseNoise\"],\"*\",\"wobble\"],\"*\",[4,\"-\",[5,\"0.018\"]]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.sin\":()=>ae,smoothNoise2D:()=>il,\"d.vec2f\":()=>m}})&&e.f)({})),BS=w.fn([n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(1,be(0,.06,t)),i=__tsover_sub(il(m(__tsover_mul(t,60),__tsover_mul(s,14))),.5);return m(__tsover_mul(__tsover_mul(__tsover_mul(a,i),r),.09),__tsover_mul(__tsover_mul(__tsover_mul(a,r),o),.02))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"wobble\"},{type:\"i\",name:\"burst\"}],body:[0,[[13,\"switchPhase\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.06\"],\"uvY\"]]]],[13,\"switchNoise\",[1,[6,\"smoothNoise2D\",[[6,\"d.vec2f\",[[1,\"uvY\",\"*\",[5,\"60\"]],[1,\"t\",\"*\",[5,\"14\"]]]]]],\"-\",[5,\"0.5\"]]],[13,\"switchX\",[1,[1,[1,\"switchPhase\",\"*\",\"switchNoise\"],\"*\",\"wobble\"],\"*\",[5,\"0.09\"]]],[13,\"switchY\",[1,[1,[1,\"switchPhase\",\"*\",\"wobble\"],\"*\",\"burst\"],\"*\",[5,\"0.02\"]]],[10,[6,\"d.vec2f\",[\"switchX\",\"switchY\"]]]]]},externals:{\"std.smoothstep\":()=>be,smoothNoise2D:()=>il,\"d.vec2f\":()=>m}})&&e.f)({})),yre=w.fn([m,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(s,r),l=CS(i),c=MS(t.y,i,a,l),d=BS(t.y,i,o,l),u=__tsover_add(__tsover_add(ES(t.y,i,o),kS(t.y,i,o)),d.x),p=__tsover_add(t.y,d.y);return S(__tsover_add(__tsover_add(t.x,u),c.x),p,__tsover_add(__tsover_add(t.x,u),c.y),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"speed\"},{type:\"i\",name:\"wobble\"},{type:\"i\",name:\"scanlineNoise\"}],body:[0,[[13,\"t\",[1,\"time\",\"*\",\"speed\"]],[13,\"burst\",[6,\"burstGate\",[\"t\"]]],[13,\"jitter\",[6,\"rowJitter\",[[7,\"uv\",\"y\"],\"t\",\"scanlineNoise\",\"burst\"]]],[13,\"sw\",[6,\"headSwitch\",[[7,\"uv\",\"y\"],\"t\",\"wobble\",\"burst\"]]],[13,\"globalX\",[1,[1,[6,\"tapeWave\",[[7,\"uv\",\"y\"],\"t\",\"wobble\"]],\"+\",[6,\"creaseShift\",[[7,\"uv\",\"y\"],\"t\",\"wobble\"]]],\"+\",[7,\"sw\",\"x\"]]],[13,\"sy\",[1,[7,\"uv\",\"y\"],\"+\",[7,\"sw\",\"y\"]]],[10,[6,\"d.vec4f\",[[1,[1,[7,\"uv\",\"x\"],\"+\",\"globalX\"],\"+\",[7,\"jitter\",\"x\"]],\"sy\",[1,[1,[7,\"uv\",\"x\"],\"+\",\"globalX\"],\"+\",[7,\"jitter\",\"y\"]],\"sy\"]]]]]},externals:{burstGate:()=>CS,rowJitter:()=>MS,headSwitch:()=>BS,tapeWave:()=>ES,creaseShift:()=>kS,\"d.vec4f\":()=>S}})&&e.f)({})),bre=w.fn([m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,r);return __tsover_add(1,__tsover_mul(__tsover_mul(pe(__tsover_add(__tsover_mul(An(a,6.2831853),2),__tsover_mul(t.y,.5))),.015),o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"speed\"},{type:\"i\",name:\"wobble\"}],body:[0,[[13,\"t\",[1,\"time\",\"*\",\"speed\"]],[10,[1,[5,\"1\"],\"+\",[1,[1,[6,\"std.cos\",[[1,[1,[6,\"std.mod\",[\"t\",[5,\"6.2831853\"]]],\"*\",[5,\"2\"]],\"+\",[1,[7,\"uv\",\"y\"],\"*\",[5,\"0.5\"]]]]],\"*\",[5,\"0.015\"]],\"*\",\"wobble\"]]]]]},externals:{\"std.cos\":()=>pe,\"std.mod\":()=>An}})&&e.f)({})),xre=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(__tsover_add(t.x,__tsover_mul(__tsover_mul(r,-1),s)),t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"chromaUV\"},{type:\"i\",name:\"smearScale\"},{type:\"i\",name:\"i\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"chromaUV\",\"x\"],\"+\",[1,[1,\"i\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"smearScale\"]],[7,\"chromaUV\",\"y\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Are=w.fn([S,S,S,S,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Se(t.xyz,A(.299,.587,.114)),c=A(.596,-.274,-.322),d=A(.211,-.523,.312),u=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(Se(s.xyz,c),.06666666666666667),__tsover_mul(Se(r.xyz,c),.13333333333333333)),__tsover_mul(Se(o.xyz,c),.2)),__tsover_mul(Se(a.xyz,c),.26666666666666666)),__tsover_mul(Se(i.xyz,c),.3333333333333333)),p=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(Se(s.xyz,d),.06666666666666667),__tsover_mul(Se(r.xyz,d),.13333333333333333)),__tsover_mul(Se(o.xyz,d),.2)),__tsover_mul(Se(a.xyz,d),.26666666666666666)),__tsover_mul(Se(i.xyz,d),.3333333333333333));return A(__tsover_add(__tsover_add(l,__tsover_mul(u,.956)),__tsover_mul(p,.621)),__tsover_sub(__tsover_sub(l,__tsover_mul(u,.272)),__tsover_mul(p,.647)),__tsover_add(__tsover_sub(l,__tsover_mul(u,1.106)),__tsover_mul(p,1.703)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"luma\"},{type:\"i\",name:\"c1\"},{type:\"i\",name:\"c2\"},{type:\"i\",name:\"c3\"},{type:\"i\",name:\"c4\"},{type:\"i\",name:\"c5\"}],body:[0,[[13,\"sharpY\",[6,\"std.dot\",[[7,\"luma\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"iAxis\",[6,\"d.vec3f\",[[5,\"0.596\"],[4,\"-\",[5,\"0.274\"]],[4,\"-\",[5,\"0.322\"]]]]],[13,\"qAxis\",[6,\"d.vec3f\",[[5,\"0.211\"],[4,\"-\",[5,\"0.523\"]],[5,\"0.312\"]]]],[13,\"accI\",[1,[1,[1,[1,[1,[6,\"std.dot\",[[7,\"c1\",\"xyz\"],\"iAxis\"]],\"*\",[5,\"0.06666666666666667\"]],\"+\",[1,[6,\"std.dot\",[[7,\"c2\",\"xyz\"],\"iAxis\"]],\"*\",[5,\"0.13333333333333333\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c3\",\"xyz\"],\"iAxis\"]],\"*\",[5,\"0.2\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c4\",\"xyz\"],\"iAxis\"]],\"*\",[5,\"0.26666666666666666\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c5\",\"xyz\"],\"iAxis\"]],\"*\",[5,\"0.3333333333333333\"]]]],[13,\"accQ\",[1,[1,[1,[1,[1,[6,\"std.dot\",[[7,\"c1\",\"xyz\"],\"qAxis\"]],\"*\",[5,\"0.06666666666666667\"]],\"+\",[1,[6,\"std.dot\",[[7,\"c2\",\"xyz\"],\"qAxis\"]],\"*\",[5,\"0.13333333333333333\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c3\",\"xyz\"],\"qAxis\"]],\"*\",[5,\"0.2\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c4\",\"xyz\"],\"qAxis\"]],\"*\",[5,\"0.26666666666666666\"]]],\"+\",[1,[6,\"std.dot\",[[7,\"c5\",\"xyz\"],\"qAxis\"]],\"*\",[5,\"0.3333333333333333\"]]]],[10,[6,\"d.vec3f\",[[1,[1,\"sharpY\",\"+\",[1,\"accI\",\"*\",[5,\"0.956\"]]],\"+\",[1,\"accQ\",\"*\",[5,\"0.621\"]]],[1,[1,\"sharpY\",\"-\",[1,\"accI\",\"*\",[5,\"0.272\"]]],\"-\",[1,\"accQ\",\"*\",[5,\"0.647\"]]],[1,[1,\"sharpY\",\"-\",[1,\"accI\",\"*\",[5,\"1.106\"]]],\"+\",[1,\"accQ\",\"*\",[5,\"1.703\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),wre=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=G(t.xyz.mul(s),A(0,0,0),A(1,1,1));return S(r.x,r.y,r.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"acBeat\"}],body:[0,[[13,\"clamped\",[6,\"std.clamp\",[[6,[7,[7,\"color\",\"xyz\"],\"mul\"],[\"acBeat\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[10,[6,\"d.vec4f\",[[7,\"clamped\",\"x\"],[7,\"clamped\",\"y\"],[7,\"clamped\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),Yo=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Xs(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"noise.hash11\",[\"p\"]]]]]},externals:{\"noise.hash11\":()=>Xs}})&&e.f)({})),zS=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Yo(t),a=__tsover_mul(__tsover_mul(o,o),o),i=Yo(__tsover_add(s,73)),l=__tsover_mul(i,i),c=__tsover_sub(1,r),d=Et(c,a),u=Et(__tsover_add(c,.15),l);return __tsover_mul(G(__tsover_add(__tsover_mul(d,.8),__tsover_mul(u,.4)),0,1),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"slowFrame\"},{type:\"i\",name:\"fastFrame\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"slowHash\",[6,\"hash11\",[\"slowFrame\"]]],[13,\"slowPulse\",[1,[1,\"slowHash\",\"*\",\"slowHash\"],\"*\",\"slowHash\"]],[13,\"fastHash\",[6,\"hash11\",[[1,\"fastFrame\",\"+\",[5,\"73\"]]]]],[13,\"fastPulse\",[1,\"fastHash\",\"*\",\"fastHash\"]],[13,\"threshold\",[1,[5,\"1\"],\"-\",\"intensity\"]],[13,\"majorBurst\",[6,\"std.step\",[\"threshold\",\"slowPulse\"]]],[13,\"minorFlicker\",[6,\"std.step\",[[1,\"threshold\",\"+\",[5,\"0.15\"]],\"fastPulse\"]]],[10,[1,[6,\"std.clamp\",[[1,[1,\"majorBurst\",\"*\",[5,\"0.8\"]],\"+\",[1,\"minorFlicker\",\"*\",[5,\"0.4\"]]],[5,\"0\"],[5,\"1\"]]],\"*\",\"intensity\"]]]]},externals:{hash11:()=>Yo,\"std.step\":()=>Et,\"std.clamp\":()=>G}})&&e.f)({})),d1=w.fn([n,n,n,n,n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_add(__tsover_mul(t,r),__tsover_mul(s,o)),u=Yo(d),p=Et(__tsover_sub(1,__tsover_mul(c,a)),u);return A(__tsover_mul(__tsover_mul(__tsover_sub(Yo(__tsover_add(d,i)),.5),l),p),p,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"bandY\"},{type:\"i\",name:\"frame\"},{type:\"i\",name:\"seedScale\"},{type:\"i\",name:\"frameScale\"},{type:\"i\",name:\"gateFactor\"},{type:\"i\",name:\"hashOffset\"},{type:\"i\",name:\"amplitude\"},{type:\"i\",name:\"glitchStrength\"}],body:[0,[[13,\"seed\",[1,[1,\"bandY\",\"*\",\"seedScale\"],\"+\",[1,\"frame\",\"*\",\"frameScale\"]]],[13,\"bandHash\",[6,\"hash11\",[\"seed\"]]],[13,\"active\",[6,\"std.step\",[[1,[5,\"1\"],\"-\",[1,\"glitchStrength\",\"*\",\"gateFactor\"]],\"bandHash\"]]],[13,\"displace\",[1,[1,[1,[6,\"hash11\",[[1,\"seed\",\"+\",\"hashOffset\"]]],\"-\",[5,\"0.5\"]],\"*\",\"amplitude\"],\"*\",\"active\"]],[10,[6,\"d.vec3f\",[\"displace\",\"active\",\"seed\"]]]]]},externals:{hash11:()=>Yo,\"std.step\":()=>Et,\"d.vec3f\":()=>A}})&&e.f)({})),RS=w.fn([n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_add(__tsover_add(__tsover_mul(t,.41),__tsover_mul(s,.67)),__tsover_mul(r,2.31)),i=Yo(a),l=Et(__tsover_sub(1,__tsover_mul(o,.35)),i);return m(__tsover_mul(__tsover_mul(__tsover_sub(Yo(__tsover_add(a,77)),.5),.18),l),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colX\"},{type:\"i\",name:\"bandY1\"},{type:\"i\",name:\"slowFrame\"},{type:\"i\",name:\"glitchStrength\"}],body:[0,[[13,\"blockSeed\",[1,[1,[1,\"colX\",\"*\",[5,\"0.41\"]],\"+\",[1,\"bandY1\",\"*\",[5,\"0.67\"]]],\"+\",[1,\"slowFrame\",\"*\",[5,\"2.31\"]]]],[13,\"blockHash\",[6,\"hash11\",[\"blockSeed\"]]],[13,\"blockActive\",[6,\"std.step\",[[1,[5,\"1\"],\"-\",[1,\"glitchStrength\",\"*\",[5,\"0.35\"]]],\"blockHash\"]]],[13,\"displace\",[1,[1,[1,[6,\"hash11\",[[1,\"blockSeed\",\"+\",[5,\"77\"]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.18\"]],\"*\",\"blockActive\"]],[10,[6,\"d.vec2f\",[\"displace\",\"blockActive\"]]]]]},externals:{hash11:()=>Yo,\"std.step\":()=>Et,\"d.vec2f\":()=>m}})&&e.f)({})),DS=w.fn([m,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_add(__tsover_add(__tsover_mul(s,.83),__tsover_mul(r,1.17)),__tsover_mul(o,4.57)),d=Yo(c),u=Yo(__tsover_add(c,500)),p=__tsover_mul(Et(__tsover_sub(1,__tsover_mul(i,l)),d),a),_=__tsover_mul(Et(__tsover_sub(1,__tsover_mul(__tsover_mul(i,l),.4)),u),a);return m(K(t.x,__tsover_sub(1,t.x),p),K(t.y,__tsover_sub(1,t.y),_))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"displacedUV\"},{type:\"i\",name:\"colX\"},{type:\"i\",name:\"bandY1\"},{type:\"i\",name:\"slowFrame\"},{type:\"i\",name:\"bandActive1\"},{type:\"i\",name:\"mirrorChance\"},{type:\"i\",name:\"glitchStrength\"}],body:[0,[[13,\"mirrorSeed\",[1,[1,[1,\"colX\",\"*\",[5,\"0.83\"]],\"+\",[1,\"bandY1\",\"*\",[5,\"1.17\"]]],\"+\",[1,\"slowFrame\",\"*\",[5,\"4.57\"]]]],[13,\"hMirrorHash\",[6,\"hash11\",[\"mirrorSeed\"]]],[13,\"vMirrorHash\",[6,\"hash11\",[[1,\"mirrorSeed\",\"+\",[5,\"500\"]]]]],[13,\"hMirrorActive\",[1,[6,\"std.step\",[[1,[5,\"1\"],\"-\",[1,\"mirrorChance\",\"*\",\"glitchStrength\"]],\"hMirrorHash\"]],\"*\",\"bandActive1\"]],[13,\"vMirrorActive\",[1,[6,\"std.step\",[[1,[5,\"1\"],\"-\",[1,[1,\"mirrorChance\",\"*\",\"glitchStrength\"],\"*\",[5,\"0.4\"]]],\"vMirrorHash\"]],\"*\",\"bandActive1\"]],[10,[6,\"d.vec2f\",[[6,\"std.mix\",[[7,\"displacedUV\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"displacedUV\",\"x\"]],\"hMirrorActive\"]],[6,\"std.mix\",[[7,\"displacedUV\",\"y\"],[1,[5,\"1\"],\"-\",[7,\"displacedUV\",\"y\"]],\"vMirrorActive\"]]]]]]]},externals:{hash11:()=>Yo,\"std.step\":()=>Et,\"d.vec2f\":()=>m,\"std.mix\":()=>K}})&&e.f)({})),P0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({mirroredUV:m,spread:n,strength:n,bandY1:n,slowFrame:n,bandGate:n,blockGate:n,distortion:n}),\"GlitchGeom\"),Tre=w.fn([m,n,n,n,n,n],P0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_mul(s,o),c=ie(__tsover_mul(l,2.5)),d=ie(__tsover_mul(l,10)),u=zS(c,d,r),p=ie(__tsover_mul(t.y,a)),_=d1(p,c,.37,7.13,.5,42,.25,u),f=d1(ie(__tsover_mul(t.y,__tsover_mul(a,2))),d,.53,3.37,.7,99,.12,u),h=d1(ie(__tsover_mul(t.y,__tsover_mul(a,4))),d,.71,11.71,.9,173,.05,u),g=ie(__tsover_mul(t.x,4)),y=RS(g,p,c,u),b=__tsover_add(__tsover_add(__tsover_add(_.x,f.x),h.x),y.x),x=__tsover_mul(__tsover_mul(_.y,__tsover_sub(Yo(__tsover_add(_.z,200)),.5)),.012),P=DS(m(G(__tsover_add(t.x,__tsover_mul(b,u)),0,1),G(__tsover_add(t.y,__tsover_mul(x,u)),0,1)),g,p,c,_.y,i,u),C=__tsover_add(u,__tsover_mul(re(b),2)),E=G(__tsover_add(__tsover_add(_.y,f.y),h.y),0,1);return P0({mirroredUV:P,spread:C,strength:u,bandY1:p,slowFrame:c,bandGate:_.y,blockGate:y.y,distortion:E})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"speed\"},{type:\"i\",name:\"blockDensity\"},{type:\"i\",name:\"mirrorChance\"}],body:[0,[[13,\"t\",[1,\"time\",\"*\",\"speed\"]],[13,\"slowFrame\",[6,\"std.floor\",[[1,\"t\",\"*\",[5,\"2.5\"]]]]],[13,\"fastFrame\",[6,\"std.floor\",[[1,\"t\",\"*\",[5,\"10\"]]]]],[13,\"glitchStrength\",[6,\"burstPulse\",[\"slowFrame\",\"fastFrame\",\"intensity\"]]],[13,\"bandY1\",[6,\"std.floor\",[[1,[7,\"uv\",\"y\"],\"*\",\"blockDensity\"]]]],[13,\"band1\",[6,\"bandJitter\",[\"bandY1\",\"slowFrame\",[5,\"0.37\"],[5,\"7.13\"],[5,\"0.5\"],[5,\"42\"],[5,\"0.25\"],\"glitchStrength\"]]],[13,\"bandY2\",[6,\"std.floor\",[[1,[7,\"uv\",\"y\"],\"*\",[1,\"blockDensity\",\"*\",[5,\"2\"]]]]]],[13,\"band2\",[6,\"bandJitter\",[\"bandY2\",\"fastFrame\",[5,\"0.53\"],[5,\"3.37\"],[5,\"0.7\"],[5,\"99\"],[5,\"0.12\"],\"glitchStrength\"]]],[13,\"bandY3\",[6,\"std.floor\",[[1,[7,\"uv\",\"y\"],\"*\",[1,\"blockDensity\",\"*\",[5,\"4\"]]]]]],[13,\"band3\",[6,\"bandJitter\",[\"bandY3\",\"fastFrame\",[5,\"0.71\"],[5,\"11.71\"],[5,\"0.9\"],[5,\"173\"],[5,\"0.05\"],\"glitchStrength\"]]],[13,\"colX\",[6,\"std.floor\",[[1,[7,\"uv\",\"x\"],\"*\",[5,\"4\"]]]]],[13,\"block\",[6,\"blockShift\",[\"colX\",\"bandY1\",\"slowFrame\",\"glitchStrength\"]]],[13,\"totalDisplaceX\",[1,[1,[1,[7,\"band1\",\"x\"],\"+\",[7,\"band2\",\"x\"]],\"+\",[7,\"band3\",\"x\"]],\"+\",[7,\"block\",\"x\"]]],[13,\"vertJitter\",[1,[1,[7,\"band1\",\"y\"],\"*\",[1,[6,\"hash11\",[[1,[7,\"band1\",\"z\"],\"+\",[5,\"200\"]]]],\"-\",[5,\"0.5\"]]],\"*\",[5,\"0.012\"]]],[13,\"displacedUV\",[6,\"d.vec2f\",[[6,\"std.clamp\",[[1,[7,\"uv\",\"x\"],\"+\",[1,\"totalDisplaceX\",\"*\",\"glitchStrength\"]],[5,\"0\"],[5,\"1\"]]],[6,\"std.clamp\",[[1,[7,\"uv\",\"y\"],\"+\",[1,\"vertJitter\",\"*\",\"glitchStrength\"]],[5,\"0\"],[5,\"1\"]]]]]],[13,\"mirroredUV\",[6,\"mirrorFlips\",[\"displacedUV\",\"colX\",\"bandY1\",\"slowFrame\",[7,\"band1\",\"y\"],\"mirrorChance\",\"glitchStrength\"]]],[13,\"spread\",[1,\"glitchStrength\",\"+\",[1,[6,\"std.abs\",[\"totalDisplaceX\"]],\"*\",[5,\"2\"]]]],[13,\"anyDistortion\",[6,\"std.clamp\",[[1,[1,[7,\"band1\",\"y\"],\"+\",[7,\"band2\",\"y\"]],\"+\",[7,\"band3\",\"y\"]],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"GlitchGeom\",[[104,{mirroredUV:\"mirroredUV\",spread:\"spread\",strength:\"glitchStrength\",bandY1:\"bandY1\",slowFrame:\"slowFrame\",bandGate:[7,\"band1\",\"y\"],blockGate:[7,\"block\",\"y\"],distortion:\"anyDistortion\"}]]]]]]},externals:{\"std.floor\":()=>ie,burstPulse:()=>zS,bandJitter:()=>d1,blockShift:()=>RS,hash11:()=>Yo,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,mirrorFlips:()=>DS,\"std.abs\":()=>re,GlitchGeom:()=>P0}})&&e.f)({})),Sre=w.fn([m,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(__tsover_mul(s,.003),r),a=G(__tsover_add(t.x,o),0,1),i=G(__tsover_sub(t.x,o),0,1);return S(a,t.y,i,t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"mirroredUV\"},{type:\"i\",name:\"rgbShift\"},{type:\"i\",name:\"spread\"}],body:[0,[[13,\"rgbOffset\",[1,[1,\"rgbShift\",\"*\",[5,\"0.003\"]],\"*\",\"spread\"]],[13,\"redX\",[6,\"std.clamp\",[[1,[7,\"mirroredUV\",\"x\"],\"+\",\"rgbOffset\"],[5,\"0\"],[5,\"1\"]]]],[13,\"blueX\",[6,\"std.clamp\",[[1,[7,\"mirroredUV\",\"x\"],\"-\",\"rgbOffset\"],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[\"redX\",[7,\"mirroredUV\",\"y\"],\"blueX\",[7,\"mirroredUV\",\"y\"]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({})),Pre=w.fn([S,m,n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=ie(__tsover_mul(s.x,4)),u=__tsover_add(__tsover_add(__tsover_mul(d,.41),__tsover_mul(r,.67)),__tsover_mul(o,2.31)),p=Yo(__tsover_add(u,555)),_=Yo(__tsover_add(__tsover_add(r,__tsover_mul(o,3.33)),333)),f=Re(__tsover_add(__tsover_mul(s.x,3),__tsover_mul(_,7))),h=ie(__tsover_mul(f,7)),g=A(__tsover_add(__tsover_sub(1,Et(2,h)),__tsover_mul(Et(4,h),__tsover_sub(1,Et(6,h)))),__tsover_sub(1,Et(4,h)),__tsover_sub(1,Et(.5,Re(__tsover_mul(h,.5))))),y=Re(__tsover_add(__tsover_mul(Yo(__tsover_add(r,13)),.8),__tsover_mul(o,.07))),b=__tsover_mul(y,6),x=K(A(G(__tsover_sub(re(__tsover_sub(b,3)),1),0,1),G(__tsover_sub(2,re(__tsover_sub(b,2))),0,1),G(__tsover_sub(2,re(__tsover_sub(b,4))),0,1)).mul(1.3),g,A(Et(.5,p))),P=__tsover_mul(__tsover_mul(__tsover_mul(l,c),a),i),C=K(t.xyz,x.mul(t.w),A(P));return S(C.x,C.y,C.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"bandY1\"},{type:\"i\",name:\"slowFrame\"},{type:\"i\",name:\"colorBarMix\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"bandGate\"},{type:\"i\",name:\"blockGate\"}],body:[0,[[13,\"colX\",[6,\"std.floor\",[[1,[7,\"uv\",\"x\"],\"*\",[5,\"4\"]]]]],[13,\"blockSeed\",[1,[1,[1,\"colX\",\"*\",[5,\"0.41\"]],\"+\",[1,\"bandY1\",\"*\",[5,\"0.67\"]]],\"+\",[1,\"slowFrame\",\"*\",[5,\"2.31\"]]]],[13,\"fillStyleHash\",[6,\"hash11\",[[1,\"blockSeed\",\"+\",[5,\"555\"]]]]],[13,\"barOffset\",[6,\"hash11\",[[1,[1,\"bandY1\",\"+\",[1,\"slowFrame\",\"*\",[5,\"3.33\"]]],\"+\",[5,\"333\"]]]]],[13,\"barX\",[6,\"std.fract\",[[1,[1,[7,\"uv\",\"x\"],\"*\",[5,\"3\"]],\"+\",[1,\"barOffset\",\"*\",[5,\"7\"]]]]]],[13,\"barIndex\",[6,\"std.floor\",[[1,\"barX\",\"*\",[5,\"7\"]]]]],[13,\"barR\",[1,[1,[5,\"1\"],\"-\",[6,\"std.step\",[[5,\"2\"],\"barIndex\"]]],\"+\",[1,[6,\"std.step\",[[5,\"4\"],\"barIndex\"]],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.step\",[[5,\"6\"],\"barIndex\"]]]]]],[13,\"barG\",[1,[5,\"1\"],\"-\",[6,\"std.step\",[[5,\"4\"],\"barIndex\"]]]],[13,\"barB\",[1,[5,\"1\"],\"-\",[6,\"std.step\",[[5,\"0.5\"],[6,\"std.fract\",[[1,\"barIndex\",\"*\",[5,\"0.5\"]]]]]]]],[13,\"smpteColor\",[6,\"d.vec3f\",[\"barR\",\"barG\",\"barB\"]]],[13,\"solidHue\",[6,\"std.fract\",[[1,[1,[6,\"hash11\",[[1,\"bandY1\",\"+\",[5,\"13\"]]]],\"*\",[5,\"0.8\"]],\"+\",[1,\"slowFrame\",\"*\",[5,\"0.07\"]]]]]],[13,\"sh6\",[1,\"solidHue\",\"*\",[5,\"6\"]]],[13,\"solidColor\",[6,[7,[6,\"d.vec3f\",[[6,\"std.clamp\",[[1,[6,\"std.abs\",[[1,\"sh6\",\"-\",[5,\"3\"]]]],\"-\",[5,\"1\"]],[5,\"0\"],[5,\"1\"]]],[6,\"std.clamp\",[[1,[5,\"2\"],\"-\",[6,\"std.abs\",[[1,\"sh6\",\"-\",[5,\"2\"]]]]],[5,\"0\"],[5,\"1\"]]],[6,\"std.clamp\",[[1,[5,\"2\"],\"-\",[6,\"std.abs\",[[1,\"sh6\",\"-\",[5,\"4\"]]]]],[5,\"0\"],[5,\"1\"]]]]],\"mul\"],[[5,\"1.3\"]]]],[13,\"fillColor\",[6,\"std.mix\",[\"solidColor\",\"smpteColor\",[6,\"d.vec3f\",[[6,\"std.step\",[[5,\"0.5\"],\"fillStyleHash\"]]]]]]],[13,\"colorBarStrength\",[1,[1,[1,\"bandGate\",\"*\",\"blockGate\"],\"*\",\"colorBarMix\"],\"*\",\"strength\"]],[13,\"withBars\",[6,\"std.mix\",[[7,\"color\",\"xyz\"],[6,[7,\"fillColor\",\"mul\"],[[7,\"color\",\"w\"]]],[6,\"d.vec3f\",[\"colorBarStrength\"]]]]],[10,[6,\"d.vec4f\",[[7,\"withBars\",\"x\"],[7,\"withBars\",\"y\"],[7,\"withBars\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"std.floor\":()=>ie,hash11:()=>Yo,\"std.fract\":()=>Re,\"std.step\":()=>Et,\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"std.abs\":()=>re,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})),Cre=w.fn([S,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(s,r),l=__tsover_add(__tsover_mul(ae(__tsover_mul(i,3.14159265)),.5),.5),c=__tsover_sub(1,__tsover_mul(__tsover_mul(__tsover_mul(o,l),.3),a)),d=t.xyz.mul(c);return S(d.x,d.y,d.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"viewportY\"},{type:\"i\",name:\"scanlines\"},{type:\"i\",name:\"distortion\"}],body:[0,[[13,\"pixelY\",[1,\"uvY\",\"*\",\"viewportY\"]],[13,\"scanlineWave\",[1,[1,[6,\"std.sin\",[[1,\"pixelY\",\"*\",[5,\"3.14159265\"]]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[13,\"scanlineEffect\",[1,[5,\"1\"],\"-\",[1,[1,[1,\"scanlines\",\"*\",\"scanlineWave\"],\"*\",[5,\"0.3\"]],\"*\",\"distortion\"]]],[13,\"shaded\",[6,[7,[7,\"color\",\"xyz\"],\"mul\"],[\"scanlineEffect\"]]],[10,[6,\"d.vec4f\",[[7,\"shaded\",\"x\"],[7,\"shaded\",\"y\"],[7,\"shaded\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"std.sin\":()=>ae,\"d.vec4f\":()=>S}})&&e.f)({})),LS=2/Math.sqrt(3),hu=Math.sqrt(3)/2,Mre=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Cs(s),i=m(__tsover_mul(t.x,a),__tsover_sub(1,t.y)),l=__tsover_mul(o,bt);return Gu(i,a,pe(l),ae(l)).mul(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"rotationDeg\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"correctedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"uv\",\"y\"]]]]],[13,\"rotRad\",[1,\"rotationDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[10,[6,[7,[6,\"rotateAboutCanvasCentre\",[\"correctedUV\",\"aspect\",\"cosR\",\"sinR\"]],\"mul\"],[\"cells\"]]]]]},externals:{aspectOf:()=>Cs,\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,rotateAboutCanvasCentre:()=>Gu}})&&e.f)({})),Ere=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Cs(s),i=m(__tsover_mul(t.x,a),t.y),l=-__tsover_mul(o,bt);return Gu(i,a,pe(l),ae(l)).mul(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"rotationDeg\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"correctedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"ang\",[4,\"-\",[1,\"rotationDeg\",\"*\",\"DEG_TO_RAD\"]]],[13,\"cosR\",[6,\"std.cos\",[\"ang\"]]],[13,\"sinR\",[6,\"std.sin\",[\"ang\"]]],[10,[6,[7,[6,\"rotateAboutCanvasCentre\",[\"correctedUV\",\"aspect\",\"cosR\",\"sinR\"]],\"mul\"],[\"cells\"]]]]]},externals:{aspectOf:()=>Cs,\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,rotateAboutCanvasCentre:()=>Gu}})&&e.f)({})),kre=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Cs(s),i=m(__tsover_mul(t.x,a),t.y),l=__tsover_mul(o,bt);return Gu(i,a,pe(l),ae(l)).mul(r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"rotationDeg\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"correctedUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"rotRad\",[1,\"rotationDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[10,[6,[7,[6,\"rotateAboutCanvasCentre\",[\"correctedUV\",\"aspect\",\"cosR\",\"sinR\"]],\"mul\"],[\"cells\"]]]]]},externals:{aspectOf:()=>Cs,\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,rotateAboutCanvasCentre:()=>Gu}})&&e.f)({})),mc=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return hT(iv(t),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cellId\"},{type:\"i\",name:\"variation\"}],body:[0,[[10,[6,\"variationFactor\",[[6,\"cellHash\",[\"cellId\"]],\"variation\"]]]]]},externals:{variationFactor:()=>hT,cellHash:()=>iv}})&&e.f)({})),Cv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(o,.5);return uv(t,s,B(__tsover_sub(s,a),0),__tsover_add(__tsover_add(s,r),a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"field\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"pixel\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"soft\",[1,\"softness\",\"*\",[5,\"0.5\"]]],[13,\"lo\",[6,\"std.max\",[[1,\"lineWidth\",\"-\",\"soft\"],[5,\"0\"]]]],[13,\"hi\",[1,[1,\"lineWidth\",\"+\",\"pixel\"],\"+\",\"soft\"]],[10,[6,\"lineMaskFromField\",[\"field\",\"lineWidth\",\"lo\",\"hi\"]]]]]},externals:{\"std.max\":()=>B,lineMaskFromField:()=>uv}})&&e.f)({})),Mv=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return uv(t,s,__tsover_sub(s,r),__tsover_add(s,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"field\"},{type:\"i\",name:\"lineWidth\"},{type:\"i\",name:\"aaWidth\"}],body:[0,[[10,[6,\"lineMaskFromField\",[\"field\",\"lineWidth\",[1,\"lineWidth\",\"-\",\"aaWidth\"],[1,\"lineWidth\",\"+\",\"aaWidth\"]]]]]]},externals:{lineMaskFromField:()=>uv}})&&e.f)({})),Bre=w.fn([m,m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=ov(t,s).mul(r);return bT(a,gT(a,o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"p\",[6,[7,[6,\"aspectCorrectedUVFlipY\",[\"uv\",\"viewport\"]],\"mul\"],[\"cells\"]]],[10,[6,\"quilezCheckerFilter\",[\"p\",[6,\"footprint2\",[\"p\",\"softness\"]]]]]]]},externals:{aspectCorrectedUVFlipY:()=>ov,quilezCheckerFilter:()=>bT,footprint2:()=>gT}})&&e.f)({})),US=w.fn([m,m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_mul(r,bt),c=Cs(s),d=__tsover_add(av(dc(t,c),pe(l),ae(l)),__tsover_mul(c,.5));return __tsover_add(__tsover_add(__tsover_mul(d,o),a),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"offset\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"rotatedCoord\",[1,[6,\"directionalProjection\",[[6,\"canvasCentredDelta\",[\"uv\",\"aspect\"]],[6,\"std.cos\",[\"angleRad\"]],[6,\"std.sin\",[\"angleRad\"]]]],\"+\",[1,\"aspect\",\"*\",[5,\"0.5\"]]]],[10,[1,[1,[1,\"rotatedCoord\",\"*\",\"density\"],\"+\",\"animTime\"],\"+\",\"offset\"]]]]},externals:{DEG_TO_RAD:()=>bt,aspectOf:()=>Cs,directionalProjection:()=>av,canvasCentredDelta:()=>dc,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),zre=w.fn([m,m,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=US(t,s,r,o,a,i);return yT(d,dv(d,c),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"offset\"},{type:\"i\",name:\"balance\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"p\",[6,\"stripeCoordP\",[\"uv\",\"viewport\",\"angle\",\"density\",\"animTime\",\"offset\"]]],[10,[6,\"quilezStepFilter\",[\"p\",[6,\"footprint1\",[\"p\",\"softness\"]],\"balance\"]]]]]},externals:{stripeCoordP:()=>US,quilezStepFilter:()=>yT,footprint1:()=>dv}})&&e.f)({})),Rre=w.fn([m,m,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_mul(o,bt),u=pe(d),p=ae(d),_=Pn(dc(t,Cs(s)),u,-p),f=__tsover_mul(re(__tsover_sub(Re(__tsover_mul(_.y,r)),.5)),2),h=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(_.x,r),__tsover_mul(f,.5)),c),l),g=Re(h),y=mr(h);return be(__tsover_sub(__tsover_sub(a,i),y),__tsover_add(__tsover_add(a,i),y),g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"count\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"balance\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"offset\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rot\",[6,\"rotate2\",[[6,\"canvasCentredDelta\",[\"uv\",[6,\"aspectOf\",[\"viewport\"]]]],\"cosA\",[4,\"-\",\"sinA\"]]]],[13,\"zigzag\",[1,[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,[7,\"rot\",\"y\"],\"*\",\"count\"]]],\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"stripeCoord\",[1,[1,[1,[1,[7,\"rot\",\"x\"],\"*\",\"count\"],\"+\",[1,\"zigzag\",\"*\",[5,\"0.5\"]]],\"+\",\"animTime\"],\"+\",\"offset\"]],[13,\"pattern\",[6,\"std.fract\",[\"stripeCoord\"]]],[13,\"fw\",[6,\"std.fwidth\",[\"stripeCoord\"]]],[10,[6,\"std.smoothstep\",[[1,[1,\"balance\",\"-\",\"softness\"],\"-\",\"fw\"],[1,[1,\"balance\",\"+\",\"softness\"],\"+\",\"fw\"],\"pattern\"]]]]]},externals:{DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,rotate2:()=>Pn,canvasCentredDelta:()=>dc,aspectOf:()=>Cs,\"std.abs\":()=>re,\"std.fract\":()=>Re,\"std.fwidth\":()=>mr,\"std.smoothstep\":()=>be}})&&e.f)({})),Dre=w.fn([m,n,n,n,n,n,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_div(c.x,c.y),u=he(m(__tsover_sub(__tsover_mul(l.x,d),__tsover_mul(t.x,d)),__tsover_sub(l.y,__tsover_sub(1,t.y)))),p=ae(__tsover_add(__tsover_sub(__tsover_mul(u,s),i),a)),_=__tsover_sub(__tsover_mul(o,2),1),f=be(__tsover_sub(_,r),__tsover_add(_,r),p);return __tsover_sub(1,f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"phase\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"dx\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,[7,\"center\",\"x\"],\"*\",\"aspect\"]]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]],[13,\"dist\",[6,\"std.length\",[[6,\"d.vec2f\",[\"dx\",\"dy\"]]]]],[13,\"waveInput\",[1,[1,[1,\"dist\",\"*\",\"frequency\"],\"-\",\"animTime\"],\"+\",\"phase\"]],[13,\"baseWave\",[6,\"std.sin\",[\"waveInput\"]]],[13,\"thicknessThreshold\",[1,[1,\"thickness\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"banded\",[6,\"std.smoothstep\",[[1,\"thicknessThreshold\",\"-\",\"softness\"],[1,\"thicknessThreshold\",\"+\",\"softness\"],\"baseWave\"]]],[10,[1,[5,\"1\"],\"-\",\"banded\"]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.sin\":()=>ae,\"std.smoothstep\":()=>be}})&&e.f)({})),OS=w.fn([n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return m(Re(__tsover_mul(ae(__tsover_mul(t,127.1)),43758.5453123)),Re(__tsover_mul(ae(__tsover_mul(t,311.7)),38291.3421)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"idx\"}],body:[0,[[10,[6,\"d.vec2f\",[[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,\"idx\",\"*\",[5,\"127.1\"]]]],\"*\",[5,\"43758.5453123\"]]]],[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,\"idx\",\"*\",[5,\"311.7\"]]]],\"*\",[5,\"38291.3421\"]]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({})),GS=w.fn([n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_mul(o,a),d=__tsover_mul(B(__tsover_sub(t,s),0),r),u=G(__tsover_div(d,B(c,1e-4)),0,1),p=__tsover_mul(o,Ue(B(__tsover_sub(1,__tsover_mul(u,u)),0)));return __tsover_mul(__tsover_sub(1,be(B(__tsover_sub(p,i),0),B(__tsover_add(p,i),.001),l)),be(0,i,p))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"vPeriodic\"},{type:\"i\",name:\"trailLen\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"hw\"},{type:\"i\",name:\"rounding\"},{type:\"i\",name:\"fwU\"},{type:\"i\",name:\"distFromCenter\"}],body:[0,[[13,\"maxDepth\",[1,\"hw\",\"*\",\"rounding\"]],[13,\"gapDist\",[1,[6,\"std.max\",[[1,\"vPeriodic\",\"-\",\"trailLen\"],[5,\"0\"]]],\"*\",\"density\"]],[13,\"tcap\",[6,\"std.clamp\",[[1,\"gapDist\",\"/\",[6,\"std.max\",[\"maxDepth\",[5,\"0.0001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"capHW\",[1,\"hw\",\"*\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[5,\"1\"],\"-\",[1,\"tcap\",\"*\",\"tcap\"]],[5,\"0\"]]]]]]],[10,[1,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[6,\"std.max\",[[1,\"capHW\",\"-\",\"fwU\"],[5,\"0\"]]],[6,\"std.max\",[[1,\"capHW\",\"+\",\"fwU\"],[5,\"0.001\"]]],\"distFromCenter\"]]],\"*\",[6,\"std.smoothstep\",[[5,\"0\"],\"fwU\",\"capHW\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.sqrt\":()=>Ue,\"std.smoothstep\":()=>be}})&&e.f)({})),FS=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_sub(__tsover_mul(2,s),1),o=B(__tsover_mul(2,__tsover_sub(1,s)),.001);return G(__tsover_div(__tsover_add(t,r),o),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"withinStreak\"},{type:\"i\",name:\"balance\"}],body:[0,[[13,\"balanceNum\",[1,[1,[5,\"2\"],\"*\",\"balance\"],\"-\",[5,\"1\"]]],[13,\"balanceDen\",[6,\"std.max\",[[1,[5,\"2\"],\"*\",[1,[5,\"1\"],\"-\",\"balance\"]],[5,\"0.001\"]]]],[10,[6,\"std.clamp\",[[1,[1,\"withinStreak\",\"+\",\"balanceNum\"],\"/\",\"balanceDen\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G}})&&e.f)({})),Lre=w.fn([m,m,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=Cs(s),_=m(__tsover_mul(t.x,p),t.y).sub(m(__tsover_mul(p,.5),.5)),f=__tsover_mul(r,bt),h=pe(f),g=ae(f),y=__tsover_sub(__tsover_mul(_.y,h),__tsover_mul(_.x,g)),b=__tsover_add(__tsover_mul(_.x,h),__tsover_mul(_.y,g)),x=__tsover_mul(y,o),P=ie(x),C=Re(x),E=OS(P),R=__tsover_add(1,__tsover_mul(__tsover_mul(__tsover_sub(E.x,.5),a),2)),U=E.y,L=Re(__tsover_mul(u,R)),k=Re(__tsover_sub(__tsover_sub(b,L),U)),D=i,O=G(__tsover_div(k,D),0,1),F=G(mr(b),.001,.1),q=G(__tsover_mul(mr(y),o),.001,.1),Y=__tsover_sub(1,be(__tsover_sub(D,F),__tsover_add(D,F),k)),V=__tsover_mul(l,.5),X=re(__tsover_sub(C,.5)),Q=__tsover_sub(1,be(__tsover_sub(V,q),__tsover_add(V,q),X));return m(B(__tsover_mul(Y,Q),GS(k,D,o,V,c,q,X)),FS(O,d))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"vp\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"speedVariance\"},{type:\"i\",name:\"trailLength\"},{type:\"i\",name:\"strokeWidth\"},{type:\"i\",name:\"rounding\"},{type:\"i\",name:\"balance\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"vp\"]]],[13,\"corrUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centeredUV\",[6,[7,\"corrUV\",\"sub\"],[[6,\"d.vec2f\",[[1,\"aspect\",\"*\",[5,\"0.5\"]],[5,\"0.5\"]]]]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"u\",[1,[1,[7,\"centeredUV\",\"y\"],\"*\",\"cosA\"],\"-\",[1,[7,\"centeredUV\",\"x\"],\"*\",\"sinA\"]]],[13,\"v\",[1,[1,[7,\"centeredUV\",\"x\"],\"*\",\"cosA\"],\"+\",[1,[7,\"centeredUV\",\"y\"],\"*\",\"sinA\"]]],[13,\"colF\",[1,\"u\",\"*\",\"density\"]],[13,\"colIdx\",[6,\"std.floor\",[\"colF\"]]],[13,\"colLocalU\",[6,\"std.fract\",[\"colF\"]]],[13,\"h\",[6,\"colHash\",[\"colIdx\"]]],[13,\"speedMod\",[1,[5,\"1\"],\"+\",[1,[1,[1,[7,\"h\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"speedVariance\"],\"*\",[5,\"2\"]]]],[13,\"phase\",[7,\"h\",\"y\"]],[13,\"animOffset\",[6,\"std.fract\",[[1,\"animTime\",\"*\",\"speedMod\"]]]],[13,\"vPeriodic\",[6,\"std.fract\",[[1,[1,\"v\",\"-\",\"animOffset\"],\"-\",\"phase\"]]]],[13,\"trailLen\",\"trailLength\"],[13,\"withinStreak\",[6,\"std.clamp\",[[1,\"vPeriodic\",\"/\",\"trailLen\"],[5,\"0\"],[5,\"1\"]]]],[13,\"fwV\",[6,\"std.clamp\",[[6,\"std.fwidth\",[\"v\"]],[5,\"0.001\"],[5,\"0.1\"]]]],[13,\"fwU\",[6,\"std.clamp\",[[1,[6,\"std.fwidth\",[\"u\"]],\"*\",\"density\"],[5,\"0.001\"],[5,\"0.1\"]]]],[13,\"streakMask\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"trailLen\",\"-\",\"fwV\"],[1,\"trailLen\",\"+\",\"fwV\"],\"vPeriodic\"]]]],[13,\"hw\",[1,\"strokeWidth\",\"*\",[5,\"0.5\"]]],[13,\"distFromCenter\",[6,\"std.abs\",[[1,\"colLocalU\",\"-\",[5,\"0.5\"]]]]],[13,\"widthMask\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"hw\",\"-\",\"fwU\"],[1,\"hw\",\"+\",\"fwU\"],\"distFromCenter\"]]]],[13,\"rectMask\",[1,\"streakMask\",\"*\",\"widthMask\"]],[13,\"capAlpha\",[6,\"fallingCapAlpha\",[\"vPeriodic\",\"trailLen\",\"density\",\"hw\",\"rounding\",\"fwU\",\"distFromCenter\"]]],[13,\"finalMask\",[6,\"std.max\",[\"rectMask\",\"capAlpha\"]]],[10,[6,\"d.vec2f\",[\"finalMask\",[6,\"fallingBalanceRemap\",[\"withinStreak\",\"balance\"]]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.floor\":()=>ie,\"std.fract\":()=>Re,colHash:()=>OS,\"std.clamp\":()=>G,\"std.fwidth\":()=>mr,\"std.smoothstep\":()=>be,\"std.abs\":()=>re,fallingCapAlpha:()=>GS,\"std.max\":()=>B,fallingBalanceRemap:()=>FS}})&&e.f)({})),Ure=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return vT(t,s,r,__tsover_mul(o,bt))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cells\"},{type:\"i\",name:\"rotation\"}],body:[0,[[10,[6,\"cellCentreUVRotated\",[\"uv\",\"viewport\",\"cells\",[1,\"rotation\",\"*\",\"DEG_TO_RAD\"]]]]]]},externals:{cellCentreUVRotated:()=>vT,DEG_TO_RAD:()=>bt}})&&e.f)({})),Ore=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,.01),i=B(a,1e-4),l=__tsover_mul(i,2),c=__tsover_div(1,l),d=t.add(i),u=Bu(d),p=zu(d),_=__tsover_add(B(B(re(u.x),re(p.x)),1e-5),r),f=__tsover_add(B(B(re(u.y),re(p.y)),1e-5),r),h=d0(d.x,_,c),g=d0(d.y,f,c),y=__tsover_mul(__tsover_sub(1,h),__tsover_sub(1,g));return m(__tsover_mul(__tsover_sub(1,y),Et(1e-4,a)),mc(ie(t),o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gridUV\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"variation\"}],body:[0,[[13,\"lineWidth\",[1,\"thickness\",\"*\",[5,\"0.01\"]]],[13,\"safeLine\",[6,\"std.max\",[\"lineWidth\",[5,\"0.0001\"]]]],[13,\"lineFraction\",[1,\"safeLine\",\"*\",[5,\"2\"]]],[13,\"N\",[1,[5,\"1\"],\"/\",\"lineFraction\"]],[13,\"p\",[6,[7,\"gridUV\",\"add\"],[\"safeLine\"]]],[13,\"dpx\",[6,\"std.dpdx\",[\"p\"]]],[13,\"dpy\",[6,\"std.dpdy\",[\"p\"]]],[13,\"wx\",[1,[6,\"std.max\",[[6,\"std.max\",[[6,\"std.abs\",[[7,\"dpx\",\"x\"]]],[6,\"std.abs\",[[7,\"dpy\",\"x\"]]]]],[5,\"0.00001\"]]],\"+\",\"softness\"]],[13,\"wy\",[1,[6,\"std.max\",[[6,\"std.max\",[[6,\"std.abs\",[[7,\"dpx\",\"y\"]]],[6,\"std.abs\",[[7,\"dpy\",\"y\"]]]]],[5,\"0.00001\"]]],\"+\",\"softness\"]],[13,\"iX\",[6,\"quilezLineFilterAxis\",[[7,\"p\",\"x\"],\"wx\",\"N\"]]],[13,\"iY\",[6,\"quilezLineFilterAxis\",[[7,\"p\",\"y\"],\"wy\",\"N\"]]],[13,\"gapBoth\",[1,[1,[5,\"1\"],\"-\",\"iX\"],\"*\",[1,[5,\"1\"],\"-\",\"iY\"]]],[13,\"gridMask\",[1,[1,[5,\"1\"],\"-\",\"gapBoth\"],\"*\",[6,\"std.step\",[[5,\"0.0001\"],\"lineWidth\"]]]],[13,\"variedFactor\",[6,\"cellVariation\",[[6,\"std.floor\",[\"gridUV\"]],\"variation\"]]],[10,[6,\"d.vec2f\",[\"gridMask\",\"variedFactor\"]]]]]},externals:{\"std.max\":()=>B,\"std.dpdx\":()=>Bu,\"std.dpdy\":()=>zu,\"std.abs\":()=>re,quilezLineFilterAxis:()=>d0,\"std.step\":()=>Et,cellVariation:()=>mc,\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),Gre=w.fn([m,m,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=ov(t,s),p=u.mul(r),_=ie(p.y),f=cv(lv(_),i),h=__tsover_mul(c,f),g=__tsover_mul(a,Ou(_,2)),y=Fu(m(__tsover_sub(__tsover_sub(p.x,g),h),p.y)),b=he(y.local.sub(.5)),x=he(mr(u.mul(r))),P=xT(b,__tsover_mul(o,.5),x),C=Re(__tsover_mul(ae(__tsover_add(__tsover_mul(y.cell.x,12.9898),__tsover_mul(y.cell.y,78.233))),43758.5453)),E=__tsover_add(__tsover_mul(d,2),__tsover_mul(C,Jt)),R=K(1,__tsover_add(__tsover_mul(ae(E),.5),.5),l);return __tsover_mul(P,R)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"density\"},{type:\"i\",name:\"dotSize\"},{type:\"i\",name:\"offset\"},{type:\"i\",name:\"speedVariance\"},{type:\"i\",name:\"twinkle\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"time\"}],body:[0,[[13,\"correctedUV\",[6,\"aspectCorrectedUVFlipY\",[\"uv\",\"viewport\"]]],[13,\"gridUV\",[6,[7,\"correctedUV\",\"mul\"],[\"density\"]]],[13,\"rowIndex\",[6,\"std.floor\",[[7,\"gridUV\",\"y\"]]]],[13,\"speedMod\",[6,\"rowSpeedMultiplier\",[[6,\"rowSpeedHash\",[\"rowIndex\"]],\"speedVariance\"]]],[13,\"drift\",[1,\"animTime\",\"*\",\"speedMod\"]],[13,\"staticStagger\",[1,\"offset\",\"*\",[6,\"flooredMod1\",[\"rowIndex\",[5,\"2\"]]]]],[13,\"shiftedGrid\",[6,\"d.vec2f\",[[1,[1,[7,\"gridUV\",\"x\"],\"-\",\"staticStagger\"],\"-\",\"drift\"],[7,\"gridUV\",\"y\"]]]],[13,\"tile\",[6,\"squareTiling\",[\"shiftedGrid\"]]],[13,\"centerDistance\",[6,\"std.length\",[[6,[7,[7,\"tile\",\"local\"],\"sub\"],[[5,\"0.5\"]]]]]],[13,\"pixelSize\",[6,\"std.length\",[[6,\"std.fwidth\",[[6,[7,\"correctedUV\",\"mul\"],[\"density\"]]]]]]],[13,\"coverage\",[6,\"discCoverage\",[\"centerDistance\",[1,\"dotSize\",\"*\",[5,\"0.5\"]],\"pixelSize\"]]],[13,\"dotPhase\",[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,[1,[7,[7,\"tile\",\"cell\"],\"x\"],\"*\",[5,\"12.9898\"]],\"+\",[1,[7,[7,\"tile\",\"cell\"],\"y\"],\"*\",[5,\"78.233\"]]]]],\"*\",[5,\"43758.5453\"]]]]],[13,\"twinkleTime\",[1,[1,\"time\",\"*\",[5,\"2\"]],\"+\",[1,\"dotPhase\",\"*\",\"TAU\"]]],[13,\"twinkleValue\",[1,[1,[6,\"std.sin\",[\"twinkleTime\"]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[13,\"twinkleModifier\",[6,\"std.mix\",[[5,\"1\"],\"twinkleValue\",\"twinkle\"]]],[10,[1,\"coverage\",\"*\",\"twinkleModifier\"]]]]},externals:{aspectCorrectedUVFlipY:()=>ov,\"std.floor\":()=>ie,rowSpeedMultiplier:()=>cv,rowSpeedHash:()=>lv,flooredMod1:()=>Ou,\"d.vec2f\":()=>m,squareTiling:()=>Fu,\"std.length\":()=>he,\"std.fwidth\":()=>mr,discCoverage:()=>xT,\"std.fract\":()=>Re,\"std.sin\":()=>ae,TAU:()=>Jt,\"std.mix\":()=>K}})&&e.f)({})),Fre=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=nv(t,m(lc,1)),i=mc(m(Ut(__tsover_mul(a.id.x,LS)),Ut(__tsover_mul(a.id.y,2))),o),l=m(re(a.gv.x),re(a.gv.y)),c=B(Se(l,m(hu,.5)),l.y);return m(Cv(__tsover_sub(.5,c),__tsover_mul(s,.01),__tsover_mul(mr(t.x),.5),r),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"variation\"}],body:[0,[[13,\"hex\",[6,\"hexTiling\",[\"scaledUV\",[6,\"d.vec2f\",[\"SQRT3\",[5,\"1\"]]]]]],[13,\"ix\",[6,\"std.round\",[[1,[7,[7,\"hex\",\"id\"],\"x\"],\"*\",\"INV_SQRT3_2\"]]]],[13,\"iy\",[6,\"std.round\",[[1,[7,[7,\"hex\",\"id\"],\"y\"],\"*\",[5,\"2\"]]]]],[13,\"variedFactor\",[6,\"cellVariation\",[[6,\"d.vec2f\",[\"ix\",\"iy\"]],\"variation\"]]],[13,\"pAbs\",[6,\"d.vec2f\",[[6,\"std.abs\",[[7,[7,\"hex\",\"gv\"],\"x\"]]],[6,\"std.abs\",[[7,[7,\"hex\",\"gv\"],\"y\"]]]]]],[13,\"hexDist\",[6,\"std.max\",[[6,\"std.dot\",[\"pAbs\",[6,\"d.vec2f\",[\"SQRT3_2\",[5,\"0.5\"]]]]],[7,\"pAbs\",\"y\"]]]],[13,\"edgeDist\",[1,[5,\"0.5\"],\"-\",\"hexDist\"]],[13,\"lineWidth\",[1,\"thickness\",\"*\",[5,\"0.01\"]]],[13,\"pixel\",[1,[6,\"std.fwidth\",[[7,\"scaledUV\",\"x\"]]],\"*\",[5,\"0.5\"]]],[13,\"lineMask\",[6,\"strokeBandFloored\",[\"edgeDist\",\"lineWidth\",\"pixel\",\"softness\"]]],[10,[6,\"d.vec2f\",[\"lineMask\",\"variedFactor\"]]]]]},externals:{hexTiling:()=>nv,\"d.vec2f\":()=>m,SQRT3:()=>lc,\"std.round\":()=>Ut,INV_SQRT3_2:()=>LS,cellVariation:()=>mc,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.dot\":()=>Se,SQRT3_2:()=>hu,\"std.fwidth\":()=>mr,strokeBandFloored:()=>Cv}})&&e.f)({})),Ire=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=fT(t),c=cv(lv(ie(l.y)),a),d=__tsover_mul(i,c),u=m(__tsover_sub(l.x,d),l.y),p=ie(u),_=Re(u),f=Et(1,__tsover_add(_.x,_.y)),h=mc(m(__tsover_add(__tsover_mul(p.x,2),f),p.y),o);return m(Mv(ye(ye(ye(_.x,__tsover_sub(1,_.x)),ye(_.y,__tsover_sub(1,_.y))),re(__tsover_sub(__tsover_add(_.x,_.y),1))),__tsover_mul(s,.02),__tsover_add(B(mr(l.x),mr(l.y)),__tsover_mul(r,.5))),h)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"variation\"},{type:\"i\",name:\"speedVariance\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"ps\",[6,\"triLattice\",[\"p\"]]],[13,\"rowIndex\",[6,\"std.floor\",[[7,\"ps\",\"y\"]]]],[13,\"speedMod\",[6,\"rowSpeedMultiplier\",[[6,\"rowSpeedHash\",[\"rowIndex\"]],\"speedVariance\"]]],[13,\"drift\",[1,\"animTime\",\"*\",\"speedMod\"]],[13,\"psShifted\",[6,\"d.vec2f\",[[1,[7,\"ps\",\"x\"],\"-\",\"drift\"],[7,\"ps\",\"y\"]]]],[13,\"cell\",[6,\"std.floor\",[\"psShifted\"]]],[13,\"f\",[6,\"std.fract\",[\"psShifted\"]]],[13,\"upper\",[6,\"std.step\",[[5,\"1\"],[1,[7,\"f\",\"x\"],\"+\",[7,\"f\",\"y\"]]]]],[13,\"triId\",[6,\"d.vec2f\",[[1,[1,[7,\"cell\",\"x\"],\"*\",[5,\"2\"]],\"+\",\"upper\"],[7,\"cell\",\"y\"]]]],[13,\"variedFactor\",[6,\"cellVariation\",[\"triId\",\"variation\"]]],[13,\"dEdge\",[6,\"std.min\",[[6,\"std.min\",[[6,\"std.min\",[[7,\"f\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"f\",\"x\"]]]],[6,\"std.min\",[[7,\"f\",\"y\"],[1,[5,\"1\"],\"-\",[7,\"f\",\"y\"]]]]]],[6,\"std.abs\",[[1,[1,[7,\"f\",\"x\"],\"+\",[7,\"f\",\"y\"]],\"-\",[5,\"1\"]]]]]]],[13,\"lineWidth\",[1,\"thickness\",\"*\",[5,\"0.02\"]]],[13,\"aaWidth\",[1,[6,\"std.max\",[[6,\"std.fwidth\",[[7,\"ps\",\"x\"]]],[6,\"std.fwidth\",[[7,\"ps\",\"y\"]]]]],\"+\",[1,\"softness\",\"*\",[5,\"0.5\"]]]],[13,\"lineMask\",[6,\"strokeBandSymmetric\",[\"dEdge\",\"lineWidth\",\"aaWidth\"]]],[10,[6,\"d.vec2f\",[\"lineMask\",\"variedFactor\"]]]]]},externals:{triLattice:()=>fT,\"std.floor\":()=>ie,rowSpeedMultiplier:()=>cv,rowSpeedHash:()=>lv,\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.step\":()=>Et,cellVariation:()=>mc,\"std.min\":()=>ye,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.fwidth\":()=>mr,strokeBandSymmetric:()=>Mv}})&&e.f)({})),IS=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s),a=dc(t,o),i=__tsover_mul(r,bt),l=Pn(a,pe(i),-ae(i));return m(__tsover_add(__tsover_div(l.x,o),.5),__tsover_add(l.y,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"rotation\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"centred\",[6,\"canvasCentredDelta\",[\"uv\",\"aspect\"]]],[13,\"rotRad\",[1,\"rotation\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rot\",[6,\"rotate2\",[\"centred\",\"cosR\",[4,\"-\",\"sinR\"]]]],[10,[6,\"d.vec2f\",[[1,[1,[7,\"rot\",\"x\"],\"/\",\"aspect\"],\"+\",[5,\"0.5\"]],[1,[7,\"rot\",\"y\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{aspectOf:()=>Cs,canvasCentredDelta:()=>dc,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,rotate2:()=>Pn,\"d.vec2f\":()=>m}})&&e.f)({})),YS=w.fn([n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Ou(t,2);return m(__tsover_mul(o,.5),K(__tsover_sub(__tsover_mul(o,2),1),__tsover_mul(__tsover_sub(Re(__tsover_mul(ae(__tsover_add(t,__tsover_mul(s,.137))),43758.5453)),.5),2),r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"row\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"speedVariance\"}],body:[0,[[13,\"rowMod2\",[6,\"flooredMod1\",[\"row\",[5,\"2\"]]]],[13,\"rowOffset\",[1,\"rowMod2\",\"*\",[5,\"0.5\"]]],[13,\"rowDir\",[1,[1,\"rowMod2\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"rowHash\",[1,[1,[6,\"std.fract\",[[1,[6,\"std.sin\",[[1,\"row\",\"+\",[1,\"seed\",\"*\",[5,\"0.137\"]]]]],\"*\",[5,\"43758.5453\"]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[10,[6,\"d.vec2f\",[\"rowOffset\",[6,\"std.mix\",[\"rowDir\",\"rowHash\",\"speedVariance\"]]]]]]]},externals:{flooredMod1:()=>Ou,\"std.fract\":()=>Re,\"std.sin\":()=>ae,\"d.vec2f\":()=>m,\"std.mix\":()=>K}})&&e.f)({})),WS=w.fn([m,m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=xu(t.x,__tsover_sub(s.x,r.x),__tsover_add(s.x,r.x)),a=xu(t.y,__tsover_sub(s.y,r.y),__tsover_add(s.y,r.y));return __tsover_mul(o,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cellUV\"},{type:\"i\",name:\"mortarUV\"},{type:\"i\",name:\"aaUV\"}],body:[0,[[13,\"brickU\",[6,\"bandMask\",[[7,\"cellUV\",\"x\"],[1,[7,\"mortarUV\",\"x\"],\"-\",[7,\"aaUV\",\"x\"]],[1,[7,\"mortarUV\",\"x\"],\"+\",[7,\"aaUV\",\"x\"]]]]],[13,\"brickV\",[6,\"bandMask\",[[7,\"cellUV\",\"y\"],[1,[7,\"mortarUV\",\"y\"],\"-\",[7,\"aaUV\",\"y\"]],[1,[7,\"mortarUV\",\"y\"],\"+\",[7,\"aaUV\",\"y\"]]]]],[10,[1,\"brickU\",\"*\",\"brickV\"]]]]},externals:{bandMask:()=>xu}})&&e.f)({})),Yre=w.fn([m,m,n,n,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_)=>{\"use gpu\";let f=Cs(s),h=IS(t,s,c),g=h.x,y=h.y,b=__tsover_mul(a,.3),x=__tsover_div(__tsover_mul(__tsover_mul(b,f),o),r),P=ie(__tsover_mul(y,o)),C=YS(P,p,u),E=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(g,r),C.x),__tsover_mul(_,C.y)),d),R=__tsover_mul(y,o),U=Re(E),L=Re(R),k=__tsover_mul(i,.5),D=__tsover_add(mr(E),k),O=__tsover_add(mr(R),k);return m(WS(m(U,L),m(b,x),m(D,O)),mc(m(ie(E),P),l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cellsX\"},{type:\"i\",name:\"cellsY\"},{type:\"i\",name:\"mortar\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"variation\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"offset\"},{type:\"i\",name:\"speedVariance\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"frame\",[6,\"brickFrame\",[\"uv\",\"viewport\",\"rotation\"]]],[13,\"u\",[7,\"frame\",\"x\"]],[13,\"v\",[7,\"frame\",\"y\"]],[13,\"mortarU\",[1,\"mortar\",\"*\",[5,\"0.3\"]]],[13,\"mortarV\",[1,[1,[1,\"mortarU\",\"*\",\"aspect\"],\"*\",\"cellsY\"],\"/\",\"cellsX\"]],[13,\"row\",[6,\"std.floor\",[[1,\"v\",\"*\",\"cellsY\"]]]],[13,\"stagger\",[6,\"brickRowStagger\",[\"row\",\"seed\",\"speedVariance\"]]],[13,\"brickArg\",[1,[1,[1,[1,\"u\",\"*\",\"cellsX\"],\"+\",[7,\"stagger\",\"x\"]],\"+\",[1,\"animTime\",\"*\",[7,\"stagger\",\"y\"]]],\"+\",\"offset\"]],[13,\"vScaled\",[1,\"v\",\"*\",\"cellsY\"]],[13,\"cellU\",[6,\"std.fract\",[\"brickArg\"]]],[13,\"cellV\",[6,\"std.fract\",[\"vScaled\"]]],[13,\"soft\",[1,\"softness\",\"*\",[5,\"0.5\"]]],[13,\"aaU\",[1,[6,\"std.fwidth\",[\"brickArg\"]],\"+\",\"soft\"]],[13,\"aaV\",[1,[6,\"std.fwidth\",[\"vScaled\"]],\"+\",\"soft\"]],[13,\"brickMask\",[6,\"brickMortarMask\",[[6,\"d.vec2f\",[\"cellU\",\"cellV\"]],[6,\"d.vec2f\",[\"mortarU\",\"mortarV\"]],[6,\"d.vec2f\",[\"aaU\",\"aaV\"]]]]],[13,\"brickId\",[6,\"d.vec2f\",[[6,\"std.floor\",[\"brickArg\"]],\"row\"]]],[13,\"variedFactor\",[6,\"cellVariation\",[\"brickId\",\"variation\"]]],[10,[6,\"d.vec2f\",[\"brickMask\",\"variedFactor\"]]]]]},externals:{aspectOf:()=>Cs,brickFrame:()=>IS,\"std.floor\":()=>ie,brickRowStagger:()=>YS,\"std.fract\":()=>Re,\"std.fwidth\":()=>mr,brickMortarMask:()=>WS,\"d.vec2f\":()=>m,cellVariation:()=>mc}})&&e.f)({})),qS=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Se(t,m(127.1,311.7));return Re(__tsover_mul(ae(s),43758.5453))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"h\",[6,\"std.dot\",[\"p\",[6,\"d.vec2f\",[[5,\"127.1\"],[5,\"311.7\"]]]]]],[10,[6,\"std.fract\",[[1,[6,\"std.sin\",[\"h\"]],\"*\",[5,\"43758.5453\"]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec2f\":()=>m,\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({})),Wre=w.fn([m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Fu(t),i=qS(m(__tsover_add(a.cell.x,o),__tsover_add(a.cell.y,o)))>.5,l=N(n(0),n(1),i),c=N(n(1),n(0),i);return Cv(ye(re(__tsover_sub(he(m(__tsover_sub(a.local.x,l),a.local.y)),.5)),re(__tsover_sub(he(m(__tsover_sub(a.local.x,c),__tsover_sub(a.local.y,1))),.5))),__tsover_mul(s,.005),__tsover_mul(mr(t.x),.5),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"tile\",[6,\"squareTiling\",[\"scaledUV\"]]],[13,\"h\",[6,\"truchetHash\",[[6,\"d.vec2f\",[[1,[7,[7,\"tile\",\"cell\"],\"x\"],\"+\",\"seed\"],[1,[7,[7,\"tile\",\"cell\"],\"y\"],\"+\",\"seed\"]]]]]],[13,\"flip\",[1,\"h\",\">\",[5,\"0.5\"]]],[13,\"c1x\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],\"flip\"]]],[13,\"c2x\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[5,\"0\"]]],\"flip\"]]],[13,\"d1\",[6,\"std.abs\",[[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,[7,\"tile\",\"local\"],\"x\"],\"-\",\"c1x\"],[7,[7,\"tile\",\"local\"],\"y\"]]]]],\"-\",[5,\"0.5\"]]]]],[13,\"d2\",[6,\"std.abs\",[[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,[7,\"tile\",\"local\"],\"x\"],\"-\",\"c2x\"],[1,[7,[7,\"tile\",\"local\"],\"y\"],\"-\",[5,\"1\"]]]]]],\"-\",[5,\"0.5\"]]]]],[13,\"arcDist\",[6,\"std.min\",[\"d1\",\"d2\"]]],[13,\"lineWidth\",[1,\"thickness\",\"*\",[5,\"0.005\"]]],[13,\"pixel\",[1,[6,\"std.fwidth\",[[7,\"scaledUV\",\"x\"]]],\"*\",[5,\"0.5\"]]],[10,[6,\"strokeBandFloored\",[\"arcDist\",\"lineWidth\",\"pixel\",\"softness\"]]]]]},externals:{squareTiling:()=>Fu,truchetHash:()=>qS,\"d.vec2f\":()=>m,\"std.select\":()=>N,\"d.f32\":()=>n,\"std.abs\":()=>re,\"std.length\":()=>he,\"std.min\":()=>ye,\"std.fwidth\":()=>mr,strokeBandFloored:()=>Cv}})&&e.f)({})),qre=w.fn([m,n,S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Fu(t),i=__tsover_mul(mr(t.x),.5),l=xu(a.local.y,s,__tsover_add(s,i)),c=xu(a.local.x,s,__tsover_add(s,i)),d=Ou(__tsover_add(a.cell.x,a.cell.y),2),u=__tsover_mul(l,c),p=G(__tsover_sub(l,__tsover_mul(u,d)),0,1),_=G(__tsover_sub(c,__tsover_mul(u,__tsover_sub(1,d))),0,1),f=__tsover_mul(r.w,p),h=__tsover_mul(o.w,_),g=G(__tsover_add(f,h),0,1),y=B(__tsover_add(f,h),.001);return S(__tsover_div(__tsover_add(__tsover_mul(r.x,f),__tsover_mul(o.x,h)),y),__tsover_div(__tsover_add(__tsover_mul(r.y,f),__tsover_mul(o.y,h)),y),__tsover_div(__tsover_add(__tsover_mul(r.z,f),__tsover_mul(o.z,h)),y),g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"gap\"},{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"}],body:[0,[[13,\"tile\",[6,\"squareTiling\",[\"scaledUV\"]]],[13,\"pixel\",[1,[6,\"std.fwidth\",[[7,\"scaledUV\",\"x\"]]],\"*\",[5,\"0.5\"]]],[13,\"hBand\",[6,\"bandMask\",[[7,[7,\"tile\",\"local\"],\"y\"],\"gap\",[1,\"gap\",\"+\",\"pixel\"]]]],[13,\"vBand\",[6,\"bandMask\",[[7,[7,\"tile\",\"local\"],\"x\"],\"gap\",[1,\"gap\",\"+\",\"pixel\"]]]],[13,\"isHTopFloat\",[6,\"flooredMod1\",[[1,[7,[7,\"tile\",\"cell\"],\"x\"],\"+\",[7,[7,\"tile\",\"cell\"],\"y\"]],[5,\"2\"]]]],[13,\"intersection\",[1,\"hBand\",\"*\",\"vBand\"]],[13,\"hVis\",[6,\"std.clamp\",[[1,\"hBand\",\"-\",[1,\"intersection\",\"*\",\"isHTopFloat\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"vVis\",[6,\"std.clamp\",[[1,\"vBand\",\"-\",[1,\"intersection\",\"*\",[1,[5,\"1\"],\"-\",\"isHTopFloat\"]]],[5,\"0\"],[5,\"1\"]]]],[13,\"weightA\",[1,[7,\"colorA\",\"w\"],\"*\",\"hVis\"]],[13,\"weightB\",[1,[7,\"colorB\",\"w\"],\"*\",\"vVis\"]],[13,\"totalAlpha\",[6,\"std.clamp\",[[1,\"weightA\",\"+\",\"weightB\"],[5,\"0\"],[5,\"1\"]]]],[13,\"safeWeight\",[6,\"std.max\",[[1,\"weightA\",\"+\",\"weightB\"],[5,\"0.001\"]]]],[13,\"r\",[1,[1,[1,[7,\"colorA\",\"x\"],\"*\",\"weightA\"],\"+\",[1,[7,\"colorB\",\"x\"],\"*\",\"weightB\"]],\"/\",\"safeWeight\"]],[13,\"g\",[1,[1,[1,[7,\"colorA\",\"y\"],\"*\",\"weightA\"],\"+\",[1,[7,\"colorB\",\"y\"],\"*\",\"weightB\"]],\"/\",\"safeWeight\"]],[13,\"b\",[1,[1,[1,[7,\"colorA\",\"z\"],\"*\",\"weightA\"],\"+\",[1,[7,\"colorB\",\"z\"],\"*\",\"weightB\"]],\"/\",\"safeWeight\"]],[10,[6,\"d.vec4f\",[\"r\",\"g\",\"b\",\"totalAlpha\"]]]]]},externals:{squareTiling:()=>Fu,\"std.fwidth\":()=>mr,bandMask:()=>xu,flooredMod1:()=>Ou,\"std.clamp\":()=>G,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&e.f)({})),VS=2/Math.sqrt(3),Vre=w.fn([m,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=nv(t,m(1,lc)),a=Se(o.gv,m(0,1)),i=Se(o.gv,m(-hu,-.5)),l=Se(o.gv,m(hu,-.5)),c=a>=B(i,l),d=N(N(.74,.5,i>=l),1,c),u=iv(m(Ut(__tsover_mul(o.id.x,2)),Ut(__tsover_mul(o.id.y,VS)))),p=B(a,B(i,l)),_=ye(a,ye(i,l)),f=__tsover_sub(__tsover_sub(__tsover_add(__tsover_add(a,i),l),p),_),h=__tsover_sub(p,f),g=m(re(o.gv.x),re(o.gv.y)),y=B(Se(g,m(.5,hu)),g.x);return A(u,d,Mv(ye(h,__tsover_sub(.5,y)),__tsover_mul(s,.02),__tsover_add(__tsover_mul(mr(t.x),.5),__tsover_mul(r,.5))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"scaledUV\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"}],body:[0,[[13,\"hex\",[6,\"hexTiling\",[\"scaledUV\",[6,\"d.vec2f\",[[5,\"1\"],\"SQRT3\"]]]]],[13,\"s0\",[6,\"std.dot\",[[7,\"hex\",\"gv\"],[6,\"d.vec2f\",[[5,\"0\"],[5,\"1\"]]]]]],[13,\"s1\",[6,\"std.dot\",[[7,\"hex\",\"gv\"],[6,\"d.vec2f\",[[4,\"-\",\"SQRT3_2\"],[4,\"-\",[5,\"0.5\"]]]]]]],[13,\"s2\",[6,\"std.dot\",[[7,\"hex\",\"gv\"],[6,\"d.vec2f\",[\"SQRT3_2\",[4,\"-\",[5,\"0.5\"]]]]]]],[13,\"isTop\",[1,\"s0\",\">=\",[6,\"std.max\",[\"s1\",\"s2\"]]]],[13,\"isLeft\",[1,\"s1\",\">=\",\"s2\"]],[13,\"tone\",[6,\"std.select\",[[6,\"std.select\",[[5,\"0.74\"],[5,\"0.5\"],\"isLeft\"]],[5,\"1\"],\"isTop\"]]],[13,\"ix\",[6,\"std.round\",[[1,[7,[7,\"hex\",\"id\"],\"x\"],\"*\",[5,\"2\"]]]]],[13,\"iy\",[6,\"std.round\",[[1,[7,[7,\"hex\",\"id\"],\"y\"],\"*\",\"INV_2_SQRT3\"]]]],[13,\"rand\",[6,\"cellHash\",[[6,\"d.vec2f\",[\"ix\",\"iy\"]]]]],[13,\"mx\",[6,\"std.max\",[\"s0\",[6,\"std.max\",[\"s1\",\"s2\"]]]]],[13,\"mn\",[6,\"std.min\",[\"s0\",[6,\"std.min\",[\"s1\",\"s2\"]]]]],[13,\"midScore\",[1,[1,[1,[1,\"s0\",\"+\",\"s1\"],\"+\",\"s2\"],\"-\",\"mx\"],\"-\",\"mn\"]],[13,\"internal\",[1,\"mx\",\"-\",\"midScore\"]],[13,\"pAbs\",[6,\"d.vec2f\",[[6,\"std.abs\",[[7,[7,\"hex\",\"gv\"],\"x\"]]],[6,\"std.abs\",[[7,[7,\"hex\",\"gv\"],\"y\"]]]]]],[13,\"hexDist\",[6,\"std.max\",[[6,\"std.dot\",[\"pAbs\",[6,\"d.vec2f\",[[5,\"0.5\"],\"SQRT3_2\"]]]],[7,\"pAbs\",\"x\"]]]],[13,\"rimDist\",[1,[5,\"0.5\"],\"-\",\"hexDist\"]],[13,\"edgeField\",[6,\"std.min\",[\"internal\",\"rimDist\"]]],[13,\"lineWidth\",[1,\"thickness\",\"*\",[5,\"0.02\"]]],[13,\"aaWidth\",[1,[1,[6,\"std.fwidth\",[[7,\"scaledUV\",\"x\"]]],\"*\",[5,\"0.5\"]],\"+\",[1,\"softness\",\"*\",[5,\"0.5\"]]]],[13,\"wire\",[6,\"strokeBandSymmetric\",[\"edgeField\",\"lineWidth\",\"aaWidth\"]]],[10,[6,\"d.vec3f\",[\"rand\",\"tone\",\"wire\"]]]]]},externals:{hexTiling:()=>nv,\"d.vec2f\":()=>m,SQRT3:()=>lc,\"std.dot\":()=>Se,SQRT3_2:()=>hu,\"std.max\":()=>B,\"std.select\":()=>N,\"std.round\":()=>Ut,INV_2_SQRT3:()=>VS,cellHash:()=>iv,\"std.min\":()=>ye,\"std.abs\":()=>re,\"std.fwidth\":()=>mr,strokeBandSymmetric:()=>Mv,\"d.vec3f\":()=>A}})&&e.f)({})),ed=.1,Nre=w.fn([S,m,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(s.x,r),s.y),l=__tsover_mul(o,bt),c=pe(l),d=ae(l),u=Re(m(Se(i,m(c,__tsover_mul(d,-1))),Se(i,m(d,c))).mul(a)).sub(m(.5,.5)),p=Se(A(t.x,t.y,t.z),A(.299,.587,.114)),_=__tsover_add(__tsover_mul(p,.7),.15),f=he(u),h=__tsover_sub(1,be(__tsover_sub(_,ed),__tsover_add(_,ed),f));return S(__tsover_mul(t.x,h),__tsover_mul(t.y,h),__tsover_mul(t.z,h),__tsover_mul(t.w,h))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"childColor\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"frequency\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"c\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"s\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rotatedUV\",[6,\"d.vec2f\",[[6,\"std.dot\",[\"aspectUV\",[6,\"d.vec2f\",[\"c\",[1,\"s\",\"*\",[4,\"-\",[5,\"1\"]]]]]]],[6,\"std.dot\",[\"aspectUV\",[6,\"d.vec2f\",[\"s\",\"c\"]]]]]]],[13,\"gridUV\",[6,[7,[6,\"std.fract\",[[6,[7,\"rotatedUV\",\"mul\"],[\"frequency\"]]]],\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"brightness\",[6,\"std.dot\",[[6,\"d.vec3f\",[[7,\"childColor\",\"x\"],[7,\"childColor\",\"y\"],[7,\"childColor\",\"z\"]]],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"dotSize\",[1,[1,\"brightness\",\"*\",[5,\"0.7\"]],\"+\",[5,\"0.15\"]]],[13,\"dist\",[6,\"std.length\",[\"gridUV\"]]],[13,\"dotPattern\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"dotSize\",\"-\",\"SMOOTHNESS\"],[1,\"dotSize\",\"+\",\"SMOOTHNESS\"],\"dist\"]]]],[10,[6,\"d.vec4f\",[[1,[7,\"childColor\",\"x\"],\"*\",\"dotPattern\"],[1,[7,\"childColor\",\"y\"],\"*\",\"dotPattern\"],[1,[7,\"childColor\",\"z\"],\"*\",\"dotPattern\"],[1,[7,\"childColor\",\"w\"],\"*\",\"dotPattern\"]]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.fract\":()=>Re,\"d.vec3f\":()=>A,\"std.length\":()=>he,\"std.smoothstep\":()=>be,SMOOTHNESS:()=>ed,\"d.vec4f\":()=>S}})&&e.f)({})),$re=w.fn([m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(__tsover_add(s,r),bt);return m(__tsover_add(t.x,__tsover_mul(pe(i),o)),__tsover_add(t.y,__tsover_div(__tsover_mul(ae(i),o),a)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"misprintAngleDeg\"},{type:\"i\",name:\"plateIndexDeg\"},{type:\"i\",name:\"misprint\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"angleRad\",[1,[1,\"misprintAngleDeg\",\"+\",\"plateIndexDeg\"],\"*\",\"DEG_TO_RAD\"]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,[6,\"std.cos\",[\"angleRad\"]],\"*\",\"misprint\"]],[1,[7,\"uv\",\"y\"],\"+\",[1,[1,[6,\"std.sin\",[\"angleRad\"]],\"*\",\"misprint\"],\"/\",\"aspect\"]]]]]]]},externals:{DEG_TO_RAD:()=>bt,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),bd=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_sub(1,B(B(t.x,t.y),t.z))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.max\",[[6,\"std.max\",[[7,\"s\",\"x\"],[7,\"s\",\"y\"]]],[7,\"s\",\"z\"]]]]]]]},externals:{\"std.max\":()=>B}})&&e.f)({})),Xre=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=bd(t),r=B(__tsover_sub(1,s),1e-4);return __tsover_div(__tsover_sub(__tsover_sub(1,t.x),s),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[13,\"k\",[6,\"halftoneChannelK\",[\"s\"]]],[13,\"invK\",[6,\"std.max\",[[1,[5,\"1\"],\"-\",\"k\"],[5,\"0.0001\"]]]],[10,[1,[1,[1,[5,\"1\"],\"-\",[7,\"s\",\"x\"]],\"-\",\"k\"],\"/\",\"invK\"]]]]},externals:{halftoneChannelK:()=>bd,\"std.max\":()=>B}})&&e.f)({})),Hre=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=bd(t),r=B(__tsover_sub(1,s),1e-4);return __tsover_div(__tsover_sub(__tsover_sub(1,t.y),s),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[13,\"k\",[6,\"halftoneChannelK\",[\"s\"]]],[13,\"invK\",[6,\"std.max\",[[1,[5,\"1\"],\"-\",\"k\"],[5,\"0.0001\"]]]],[10,[1,[1,[1,[5,\"1\"],\"-\",[7,\"s\",\"y\"]],\"-\",\"k\"],\"/\",\"invK\"]]]]},externals:{halftoneChannelK:()=>bd,\"std.max\":()=>B}})&&e.f)({})),jre=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=bd(t),r=B(__tsover_sub(1,s),1e-4);return __tsover_div(__tsover_sub(__tsover_sub(1,t.z),s),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[13,\"k\",[6,\"halftoneChannelK\",[\"s\"]]],[13,\"invK\",[6,\"std.max\",[[1,[5,\"1\"],\"-\",\"k\"],[5,\"0.0001\"]]]],[10,[1,[1,[1,[5,\"1\"],\"-\",[7,\"s\",\"z\"]],\"-\",\"k\"],\"/\",\"invK\"]]]]},externals:{halftoneChannelK:()=>bd,\"std.max\":()=>B}})&&e.f)({})),Kre=w.fn([m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(t.x,s),t.y),l=__tsover_mul(r,bt),c=pe(l),d=ae(l),u=he(Re(m(Se(i,m(c,__tsover_mul(d,-1))),Se(i,m(d,c))).mul(a)).sub(m(.5,.5))),p=__tsover_sub(__tsover_mul(o,.75),ed);return __tsover_sub(1,be(__tsover_sub(p,ed),__tsover_add(p,ed),u))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"frequency\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"c\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"s\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rotatedUV\",[6,\"d.vec2f\",[[6,\"std.dot\",[\"aspectUV\",[6,\"d.vec2f\",[\"c\",[1,\"s\",\"*\",[4,\"-\",[5,\"1\"]]]]]]],[6,\"std.dot\",[\"aspectUV\",[6,\"d.vec2f\",[\"s\",\"c\"]]]]]]],[13,\"grid\",[6,[7,[6,\"std.fract\",[[6,[7,\"rotatedUV\",\"mul\"],[\"frequency\"]]]],\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"dist\",[6,\"std.length\",[\"grid\"]]],[13,\"size\",[1,[1,\"intensity\",\"*\",[5,\"0.75\"]],\"-\",\"SMOOTHNESS\"]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"size\",\"-\",\"SMOOTHNESS\"],[1,\"size\",\"+\",\"SMOOTHNESS\"],\"dist\"]]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.fract\":()=>Re,\"std.length\":()=>he,SMOOTHNESS:()=>ed,\"std.smoothstep\":()=>be}})&&e.f)({})),Qre=w.fn([S,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return K(A(1,1,1),A(t.x,t.y,t.z),A(__tsover_mul(s,t.w)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"inkColor\"},{type:\"i\",name:\"inkMask\"}],body:[0,[[10,[6,\"std.mix\",[[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],[6,\"d.vec3f\",[[7,\"inkColor\",\"x\"],[7,\"inkColor\",\"y\"],[7,\"inkColor\",\"z\"]]],[6,\"d.vec3f\",[[1,\"inkMask\",\"*\",[7,\"inkColor\",\"w\"]]]]]]]]]},externals:{\"std.mix\":()=>K,\"d.vec3f\":()=>A}})&&e.f)({})),Zre=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return ie(m(__tsover_div(__tsover_mul(t.x,s.x),r),__tsover_div(__tsover_mul(t.y,s.y),r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"gridRes\"},{type:\"i\",name:\"pixelSize\"}],body:[0,[[10,[6,\"std.floor\",[[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"*\",[7,\"gridRes\",\"x\"]],\"/\",\"pixelSize\"],[1,[1,[7,\"uv\",\"y\"],\"*\",[7,\"gridRes\",\"y\"]],\"/\",\"pixelSize\"]]]]]]]]},externals:{\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),Jre=w.fn([m,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(__tsover_div(__tsover_mul(__tsover_add(t.x,.5),s),r.x),__tsover_div(__tsover_mul(__tsover_add(t.y,.5),s),r.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"},{type:\"i\",name:\"pixelSize\"},{type:\"i\",name:\"gridRes\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[1,[7,\"coord\",\"x\"],\"+\",[5,\"0.5\"]],\"*\",\"pixelSize\"],\"/\",[7,\"gridRes\",\"x\"]],[1,[1,[1,[7,\"coord\",\"y\"],\"+\",[5,\"0.5\"]],\"*\",\"pixelSize\"],\"/\",[7,\"gridRes\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),NS=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(Se(A(t.x,t.y,t.z),A(.299,.587,.114)),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"c\"}],body:[0,[[10,[1,[6,\"std.dot\",[[6,\"d.vec3f\",[[7,\"c\",\"x\"],[7,\"c\",\"y\"],[7,\"c\",\"z\"]]],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]],\"*\",[7,\"c\",\"w\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),u1=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_sub(__tsover_add(__tsover_mul(s,3),__tsover_mul(t,2)),__tsover_mul(__tsover_mul(t,s),4))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"}],body:[0,[[10,[1,[1,[1,\"b\",\"*\",[5,\"3\"]],\"+\",[1,\"a\",\"*\",[5,\"2\"]]],\"-\",[1,[1,\"a\",\"*\",\"b\"],\"*\",[5,\"4\"]]]]]]},externals:{}})&&e.f)({})),eoe=w.fn([m],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=__tsover_sub(t.x,__tsover_mul(8,ie(__tsover_div(t.x,8)))),r=__tsover_sub(t.y,__tsover_mul(8,ie(__tsover_div(t.y,8)))),o=__tsover_sub(s,__tsover_mul(2,ie(__tsover_div(s,2)))),a=__tsover_sub(r,__tsover_mul(2,ie(__tsover_div(r,2)))),i=__tsover_sub(s,__tsover_mul(4,ie(__tsover_div(s,4)))),l=__tsover_sub(r,__tsover_mul(4,ie(__tsover_div(r,4)))),c=ie(__tsover_div(i,2)),d=ie(__tsover_div(l,2)),u=ie(__tsover_div(s,4)),p=ie(__tsover_div(r,4)),_=u1(o,a),f=u1(c,d),h=u1(u,p),g=__tsover_div(_,4),y=__tsover_div(__tsover_add(__tsover_mul(_,4),f),16),b=__tsover_div(__tsover_add(__tsover_add(__tsover_mul(_,16),__tsover_mul(f,4)),h),64),x=__tsover_add(__tsover_mul(j(l),4),j(i)),P=.75;return P=N(P,.3125,x===1),P=N(P,.375,x===2),P=N(P,.8125,x===3),P=N(P,.25,x===4),P=N(P,n(0),x===5),P=N(P,.0625,x===6),P=N(P,.4375,x===7),P=N(P,.6875,x===8),P=N(P,.1875,x===9),P=N(P,.125,x===10),P=N(P,.5,x===11),P=N(P,.9375,x===12),P=N(P,.625,x===13),P=N(P,.5625,x===14),P=N(P,.875,x===15),S(g,y,b,P)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"}],body:[0,[[13,\"tx\",[1,[7,\"coord\",\"x\"],\"-\",[1,[5,\"8\"],\"*\",[6,\"std.floor\",[[1,[7,\"coord\",\"x\"],\"/\",[5,\"8\"]]]]]]],[13,\"ty\",[1,[7,\"coord\",\"y\"],\"-\",[1,[5,\"8\"],\"*\",[6,\"std.floor\",[[1,[7,\"coord\",\"y\"],\"/\",[5,\"8\"]]]]]]],[13,\"x2\",[1,\"tx\",\"-\",[1,[5,\"2\"],\"*\",[6,\"std.floor\",[[1,\"tx\",\"/\",[5,\"2\"]]]]]]],[13,\"y2\",[1,\"ty\",\"-\",[1,[5,\"2\"],\"*\",[6,\"std.floor\",[[1,\"ty\",\"/\",[5,\"2\"]]]]]]],[13,\"x4\",[1,\"tx\",\"-\",[1,[5,\"4\"],\"*\",[6,\"std.floor\",[[1,\"tx\",\"/\",[5,\"4\"]]]]]]],[13,\"y4\",[1,\"ty\",\"-\",[1,[5,\"4\"],\"*\",[6,\"std.floor\",[[1,\"ty\",\"/\",[5,\"4\"]]]]]]],[13,\"x4h\",[6,\"std.floor\",[[1,\"x4\",\"/\",[5,\"2\"]]]]],[13,\"y4h\",[6,\"std.floor\",[[1,\"y4\",\"/\",[5,\"2\"]]]]],[13,\"x8h\",[6,\"std.floor\",[[1,\"tx\",\"/\",[5,\"4\"]]]]],[13,\"y8h\",[6,\"std.floor\",[[1,\"ty\",\"/\",[5,\"4\"]]]]],[13,\"b00\",[6,\"ditherBayerQuad\",[\"x2\",\"y2\"]]],[13,\"b11\",[6,\"ditherBayerQuad\",[\"x4h\",\"y4h\"]]],[13,\"b22\",[6,\"ditherBayerQuad\",[\"x8h\",\"y8h\"]]],[13,\"bayer2\",[1,\"b00\",\"/\",[5,\"4\"]]],[13,\"bayer4\",[1,[1,[1,\"b00\",\"*\",[5,\"4\"]],\"+\",\"b11\"],\"/\",[5,\"16\"]]],[13,\"bayer8\",[1,[1,[1,[1,\"b00\",\"*\",[5,\"16\"]],\"+\",[1,\"b11\",\"*\",[5,\"4\"]]],\"+\",\"b22\"],\"/\",[5,\"64\"]]],[13,\"idx\",[1,[1,[6,\"d.i32\",[\"y4\"]],\"*\",[5,\"4\"]],\"+\",[6,\"d.i32\",[\"x4\"]]]],[12,\"cd\",[5,\"0.75\"]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.3125\"],[1,\"idx\",\"===\",[5,\"1\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.375\"],[1,\"idx\",\"===\",[5,\"2\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.8125\"],[1,\"idx\",\"===\",[5,\"3\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.25\"],[1,\"idx\",\"===\",[5,\"4\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[6,\"d.f32\",[[5,\"0\"]]],[1,\"idx\",\"===\",[5,\"5\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.0625\"],[1,\"idx\",\"===\",[5,\"6\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.4375\"],[1,\"idx\",\"===\",[5,\"7\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.6875\"],[1,\"idx\",\"===\",[5,\"8\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.1875\"],[1,\"idx\",\"===\",[5,\"9\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.125\"],[1,\"idx\",\"===\",[5,\"10\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.5\"],[1,\"idx\",\"===\",[5,\"11\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.9375\"],[1,\"idx\",\"===\",[5,\"12\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.625\"],[1,\"idx\",\"===\",[5,\"13\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.5625\"],[1,\"idx\",\"===\",[5,\"14\"]]]]],[2,\"cd\",\"=\",[6,\"std.select\",[\"cd\",[5,\"0.875\"],[1,\"idx\",\"===\",[5,\"15\"]]]]],[10,[6,\"d.vec4f\",[\"bayer2\",\"bayer4\",\"bayer8\",\"cd\"]]]]]},externals:{\"std.floor\":()=>ie,ditherBayerQuad:()=>u1,\"d.i32\":()=>j,\"std.select\":()=>N,\"d.f32\":()=>n,\"d.vec4f\":()=>S}})&&e.f)({})),toe=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=t.add(m(.5,.5));return Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(s.x,.06711056),__tsover_mul(s.y,.00583715)))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"}],body:[0,[[13,\"c\",[6,[7,\"coord\",\"add\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[10,[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[7,\"c\",\"x\"],\"*\",[5,\"0.06711056\"]],\"+\",[1,[7,\"c\",\"y\"],\"*\",[5,\"0.00583715\"]]]]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.fract\":()=>Re}})&&e.f)({})),soe=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Ys(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"}],body:[0,[[10,[6,\"noise.hash12\",[\"coord\"]]]]]},externals:{\"noise.hash12\":()=>Ys}})&&e.f)({})),roe=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return Et(__tsover_add(.5,__tsover_mul(__tsover_sub(t,.5),o)),__tsover_add(s,__tsover_sub(r,.5)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ditherValue\"},{type:\"i\",name:\"luminance\"},{type:\"i\",name:\"threshold\"},{type:\"i\",name:\"spread\"}],body:[0,[[13,\"adjustedDither\",[1,[5,\"0.5\"],\"+\",[1,[1,\"ditherValue\",\"-\",[5,\"0.5\"]],\"*\",\"spread\"]]],[10,[6,\"std.step\",[\"adjustedDither\",[1,\"luminance\",\"+\",[1,\"threshold\",\"-\",[5,\"0.5\"]]]]]]]]},externals:{\"std.step\":()=>Et}})&&e.f)({})),ooe=w.fn([m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return ie(t.div(m(8,8))).mul(m(8,8))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"}],body:[0,[[10,[6,[7,[6,\"std.floor\",[[6,[7,\"coord\",\"div\"],[[6,\"d.vec2f\",[[5,\"8\"],[5,\"8\"]]]]]]],\"mul\"],[[6,\"d.vec2f\",[[5,\"8\"],[5,\"8\"]]]]]]]]},externals:{\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})),aoe=w.fn([m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_add(__tsover_mul(__tsover_sub(t.y,s.y),8),__tsover_sub(t.x,s.x))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"},{type:\"i\",name:\"blockOrigin\"}],body:[0,[[10,[1,[1,[1,[7,\"coord\",\"y\"],\"-\",[7,\"blockOrigin\",\"y\"]],\"*\",[5,\"8\"]],\"+\",[1,[7,\"coord\",\"x\"],\"-\",[7,\"blockOrigin\",\"x\"]]]]]]},externals:{}})&&e.f)({})),noe=w.fn([m,n,n,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return m(__tsover_div(__tsover_mul(__tsover_add(__tsover_add(t.x,s),.5),o),a.x),__tsover_div(__tsover_mul(__tsover_add(__tsover_add(t.y,r),.5),o),a.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"blockOrigin\"},{type:\"i\",name:\"lx\"},{type:\"i\",name:\"ly\"},{type:\"i\",name:\"pixelSize\"},{type:\"i\",name:\"gridRes\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[1,[1,[7,\"blockOrigin\",\"x\"],\"+\",\"lx\"],\"+\",[5,\"0.5\"]],\"*\",\"pixelSize\"],\"/\",[7,\"gridRes\",\"x\"]],[1,[1,[1,[1,[7,\"blockOrigin\",\"y\"],\"+\",\"ly\"],\"+\",[5,\"0.5\"]],\"*\",\"pixelSize\"],\"/\",[7,\"gridRes\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),ioe=w.fn([Fe(n,64),n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(.5,__tsover_sub(r,.5)),i=Fe(n,8)(),l=Fe(n,8)(),c=j(s),d=n(0);for(let u=0;u<8;u++){let p=(u&1)===0;for(let _=0;_<8;_++){let f=N(__tsover_sub(7,_),_,p),h=__tsover_add(__tsover_mul(u,8),f),g=__tsover_add(t[h],i[f]),y=Et(a,g);d=N(d,y,h===c);let b=__tsover_mul(__tsover_sub(g,y),o),x=N(-1,1,p),P=__tsover_add(f,x);if(P>=0&&P<8&&(i[P]=__tsover_add(i[P],__tsover_mul(b,.4375))),u<7){let C=__tsover_sub(f,x),E=__tsover_add(f,x);C>=0&&C<8&&(l[C]=__tsover_add(l[C],__tsover_mul(b,.1875))),l[f]=__tsover_add(l[f],__tsover_mul(b,.3125)),E>=0&&E<8&&(l[E]=__tsover_add(l[E],__tsover_mul(b,.0625)))}}for(let _=0;_<8;_++)i[_]=l[_],l[_]=n(0)}return d}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lum\"},{type:\"i\",name:\"lic\"},{type:\"i\",name:\"threshold\"},{type:\"i\",name:\"spread\"}],body:[0,[[13,\"thr\",[1,[5,\"0.5\"],\"-\",[1,\"threshold\",\"-\",[5,\"0.5\"]]]],[13,\"ecur\",[6,[6,\"d.arrayOf\",[\"d.f32\",[5,\"8\"]]],[]]],[13,\"enext\",[6,[6,\"d.arrayOf\",[\"d.f32\",[5,\"8\"]]],[]]],[13,\"licInt\",[6,\"d.i32\",[\"lic\"]]],[12,\"result\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"y\",[5,\"0\"]],[1,\"y\",\"<\",[5,\"8\"]],[102,\"++\",\"y\"],[0,[[13,\"ltr\",[1,[1,\"y\",\"&\",[5,\"1\"]],\"===\",[5,\"0\"]]],[14,[12,\"xi\",[5,\"0\"]],[1,\"xi\",\"<\",[5,\"8\"]],[102,\"++\",\"xi\"],[0,[[13,\"x\",[6,\"std.select\",[[1,[5,\"7\"],\"-\",\"xi\"],\"xi\",\"ltr\"]]],[13,\"idx\",[1,[1,\"y\",\"*\",[5,\"8\"]],\"+\",\"x\"]],[13,\"val\",[1,[8,\"lum\",\"idx\"],\"+\",[8,\"ecur\",\"x\"]]],[13,\"qv\",[6,\"std.step\",[\"thr\",\"val\"]]],[2,\"result\",\"=\",[6,\"std.select\",[\"result\",\"qv\",[1,\"idx\",\"===\",\"licInt\"]]]],[13,\"e\",[1,[1,\"val\",\"-\",\"qv\"],\"*\",\"spread\"]],[13,\"dir\",[6,\"std.select\",[[4,\"-\",[5,\"1\"]],[5,\"1\"],\"ltr\"]]],[13,\"xr\",[1,\"x\",\"+\",\"dir\"]],[11,[1,\"xr\",\">=\",[5,\"0\"]],[0,[[11,[1,\"xr\",\"<\",[5,\"8\"]],[0,[[2,[8,\"ecur\",\"xr\"],\"=\",[1,[8,\"ecur\",\"xr\"],\"+\",[1,\"e\",\"*\",[5,\"0.4375\"]]]]]]]]]],[11,[1,\"y\",\"<\",[5,\"7\"]],[0,[[13,\"xbl\",[1,\"x\",\"-\",\"dir\"]],[13,\"xbr\",[1,\"x\",\"+\",\"dir\"]],[11,[1,\"xbl\",\">=\",[5,\"0\"]],[0,[[11,[1,\"xbl\",\"<\",[5,\"8\"]],[0,[[2,[8,\"enext\",\"xbl\"],\"=\",[1,[8,\"enext\",\"xbl\"],\"+\",[1,\"e\",\"*\",[5,\"0.1875\"]]]]]]]]]],[2,[8,\"enext\",\"x\"],\"=\",[1,[8,\"enext\",\"x\"],\"+\",[1,\"e\",\"*\",[5,\"0.3125\"]]]],[11,[1,\"xbr\",\">=\",[5,\"0\"]],[0,[[11,[1,\"xbr\",\"<\",[5,\"8\"]],[0,[[2,[8,\"enext\",\"xbr\"],\"=\",[1,[8,\"enext\",\"xbr\"],\"+\",[1,\"e\",\"*\",[5,\"0.0625\"]]]]]]]]]]]]]]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",[5,\"8\"]],[102,\"++\",\"k\"],[0,[[2,[8,\"ecur\",\"k\"],\"=\",[8,\"enext\",\"k\"]],[2,[8,\"enext\",\"k\"],\"=\",[6,\"d.f32\",[[5,\"0\"]]]]]]]]]],[10,\"result\"]]]},externals:{\"d.arrayOf\":()=>Fe,\"d.f32\":()=>n,\"d.i32\":()=>j,\"std.select\":()=>N,\"std.step\":()=>Et}})&&e.f)({})),loe=w.fn([S,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=K(A(t.x,t.y,t.z),A(s.x,s.y,s.z),A(r)),a=K(t.w,s.w,r);return S(o.x,o.y,o.z,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colorA\"},{type:\"i\",name:\"colorB\"},{type:\"i\",name:\"ditherResult\"}],body:[0,[[13,\"rgb\",[6,\"std.mix\",[[6,\"d.vec3f\",[[7,\"colorA\",\"x\"],[7,\"colorA\",\"y\"],[7,\"colorA\",\"z\"]]],[6,\"d.vec3f\",[[7,\"colorB\",\"x\"],[7,\"colorB\",\"y\"],[7,\"colorB\",\"z\"]]],[6,\"d.vec3f\",[\"ditherResult\"]]]]],[13,\"a\",[6,\"std.mix\",[[7,\"colorA\",\"w\"],[7,\"colorB\",\"w\"],\"ditherResult\"]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"a\"]]]]]},externals:{\"std.mix\":()=>K,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),coe=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=A(t.x,t.y,t.z),o=K(r.mul(.3),ye(r.mul(1.3),A(1,1,1)),A(s));return S(o.x,o.y,o.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sourceColor\"},{type:\"i\",name:\"ditherResult\"}],body:[0,[[13,\"rgb\",[6,\"d.vec3f\",[[7,\"sourceColor\",\"x\"],[7,\"sourceColor\",\"y\"],[7,\"sourceColor\",\"z\"]]]],[13,\"dark\",[6,[7,\"rgb\",\"mul\"],[[5,\"0.3\"]]]],[13,\"bright\",[6,\"std.min\",[[6,[7,\"rgb\",\"mul\"],[[5,\"1.3\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[13,\"out\",[6,\"std.mix\",[\"dark\",\"bright\",[6,\"d.vec3f\",[\"ditherResult\"]]]]],[10,[6,\"d.vec4f\",[[7,\"out\",\"x\"],[7,\"out\",\"y\"],[7,\"out\",\"z\"],[7,\"sourceColor\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.min\":()=>ye,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({}));function doe(e){return e.map((t,s)=>({stop:t,index:s})).sort((t,s)=>t.stop.position-s.stop.position||t.index-s.index).map(({stop:t})=>t)}function J3(e,t){let s=new Array(32).fill(0),r=new Array(8).fill(0),o=Array.isArray(e)&&e.length>0?doe(e):[],a=Math.min(o.length,8);for(let i=0;i<a;i++){let l=t(o[i].color);s[i*4]=l[0],s[i*4+1]=l[1],s[i*4+2]=l[2],s[i*4+3]=l[3],r[i]=o[i].position}return{colors:s,positions:r,stopCount:a}}function eA(e,t,s){let r=new Array(24).fill(0);for(let o=0;o<t;o++){let a=fl(e[o*4],e[o*4+1],e[o*4+2],s);r[o*3]=a[0],r[o*3+1]=a[1],r[o*3+2]=a[2]}return r}w.fn([A,n],Xa)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Xa({conv:t,alpha:s})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"conv\"},{type:\"i\",name:\"alpha\"}],body:[0,[[10,[6,\"MixStep\",[[104,{conv:\"conv\",alpha:\"alpha\"}]]]]]]},externals:{MixStep:()=>Xa}})&&e.f)({}));w.fn([Xa,A,n,n,n,n],Xa)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=G(__tsover_div(__tsover_sub(o,a),B(__tsover_sub(i,a),1e-6)),0,1);return _l(t.conv,t.alpha,s,r,l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"running\"},{type:\"i\",name:\"convI\"},{type:\"i\",name:\"alphaI\"},{type:\"i\",name:\"tClamped\"},{type:\"i\",name:\"posA\"},{type:\"i\",name:\"posB\"}],body:[0,[[13,\"seg\",[6,\"std.clamp\",[[1,[1,\"tClamped\",\"-\",\"posA\"],\"/\",[6,\"std.max\",[[1,\"posB\",\"-\",\"posA\"],[5,\"0.000001\"]]]],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"mixPreconvertedInSpace\",[[7,\"running\",\"conv\"],[7,\"running\",\"alpha\"],\"convI\",\"alphaI\",\"seg\"]]]]]},externals:{\"std.clamp\":()=>G,\"std.max\":()=>B,mixPreconvertedInSpace:()=>_l}})&&e.f)({}));w.fn([Xa],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return t.conv}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[10,[7,\"s\",\"conv\"]]]]},externals:{}})&&e.f)({}));w.fn([Xa],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return t.alpha}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"}],body:[0,[[10,[7,\"s\",\"alpha\"]]]]},externals:{}})&&e.f)({}));w.fn([A,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t,s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"a\"}],body:[0,[[10,[6,\"d.vec4f\",[\"rgb\",\"a\"]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({}));var Vb=w.fn([n,Fe(S,8),Fe(S,8/4),Fe(A,8),n],Xa)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=G(t,0,1),l=j(a),c=o[0],d=A(c.x,c.y,c.z),u=s[0].w;for(let p=1;p<l;p++){let _=r[__tsover_sub(p,1)>>2],f=r[p>>2],h=_[__tsover_sub(p,1)&3],g=f[p&3],y=G(__tsover_div(__tsover_sub(i,h),B(__tsover_sub(g,h),1e-6)),0,1),b=_l(d,u,o[p],s[p].w,y);d=A(b.conv.x,b.conv.y,b.conv.z),u=b.alpha}return Xa({conv:d,alpha:u})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"colors\"},{type:\"i\",name:\"positions\"},{type:\"i\",name:\"converted\"},{type:\"i\",name:\"stopCount\"}],body:[0,[[13,\"clampedT\",[6,\"std.clamp\",[\"t\",[5,\"0\"],[5,\"1\"]]]],[13,\"n\",[6,\"d.i32\",[\"stopCount\"]]],[13,\"c0\",[8,\"converted\",[5,\"0\"]]],[12,\"conv\",[6,\"d.vec3f\",[[7,\"c0\",\"x\"],[7,\"c0\",\"y\"],[7,\"c0\",\"z\"]]]],[12,\"alpha\",[7,[8,\"colors\",[5,\"0\"]],\"w\"]],[14,[12,\"i\",[5,\"1\"]],[1,\"i\",\"<\",\"n\"],[102,\"++\",\"i\"],[0,[[13,\"va\",[8,\"positions\",[1,[1,\"i\",\"-\",[5,\"1\"]],\">>\",[5,\"2\"]]]],[13,\"vb\",[8,\"positions\",[1,\"i\",\">>\",[5,\"2\"]]]],[13,\"posA\",[8,\"va\",[1,[1,\"i\",\"-\",[5,\"1\"]],\"&\",[5,\"3\"]]]],[13,\"posB\",[8,\"vb\",[1,\"i\",\"&\",[5,\"3\"]]]],[13,\"seg\",[6,\"std.clamp\",[[1,[1,\"clampedT\",\"-\",\"posA\"],\"/\",[6,\"std.max\",[[1,\"posB\",\"-\",\"posA\"],[5,\"0.000001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"step\",[6,\"mixPreconvertedInSpace\",[\"conv\",\"alpha\",[8,\"converted\",\"i\"],[7,[8,\"colors\",\"i\"],\"w\"],\"seg\"]]],[2,\"conv\",\"=\",[6,\"d.vec3f\",[[7,[7,\"step\",\"conv\"],\"x\"],[7,[7,\"step\",\"conv\"],\"y\"],[7,[7,\"step\",\"conv\"],\"z\"]]]],[2,\"alpha\",\"=\",[7,\"step\",\"alpha\"]]]]],[10,[6,\"MixStep\",[[104,{conv:\"conv\",alpha:\"alpha\"}]]]]]]},externals:{\"std.clamp\":()=>G,\"d.i32\":()=>j,\"d.vec3f\":()=>A,\"std.max\":()=>B,mixPreconvertedInSpace:()=>_l,MixStep:()=>Xa}})&&e.f)({}));function q4(e,t){switch(t){case 1:return W(Hs,\"sRGBToP3\",[W(oa,\"oklabToRgb\",[W(pl,\"oklchToOklab\",[e])])]);case 2:return W(Hs,\"sRGBToP3\",[W(oa,\"oklabToRgb\",[e])]);case 3:return W(Hs,\"sRGBToP3\",[W(ml,\"hslToRgb\",[e])]);case 4:return W(Hs,\"sRGBToP3\",[W(hd,\"hsvToRgb\",[e])]);case 5:return W(Hs,\"sRGBToP3\",[W(gd,\"labToRgb\",[W(yd,\"lchToLab\",[e])])]);default:return e}}function En(e,t,s){let r=ns(W(Vb,\"gradientStopsInSpace\",[e,t.colorsArray,t.positionsArray,t.convertedColorsArray,t.stopCount]),\"stopMix\");return Ct(q4(r.member(\"conv\"),s),r.member(\"alpha\"))}var V4=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Cs(s);return m(__tsover_mul(t.x,r),t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]]]]},externals:{aspectOf:()=>Cs,\"d.vec2f\":()=>m}})&&e.f)({})),uoe=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_div(s.x,s.y);return m(__tsover_mul(t.x,a),t.y).mul(Tt(r)).add(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"aspect\",[1,[7,\"viewport\",\"x\"],\"/\",[7,\"viewport\",\"y\"]]],[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[10,[6,[7,[6,[7,\"aspectUV\",\"mul\"],[[6,\"std.exp\",[\"scale\"]]]],\"add\"],[\"seed\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.exp\":()=>Tt}})&&e.f)({})),poe=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Cs(s),a=__tsover_mul(r,bt),i=pe(a),l=ae(a),c=__tsover_sub(__tsover_mul(t.x,o),__tsover_mul(o,.5)),d=__tsover_sub(t.y,.5);return m(__tsover_add(__tsover_mul(c,i),__tsover_mul(d,l)),__tsover_add(__tsover_mul(c,-l),__tsover_mul(d,i)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"}],body:[0,[[13,\"aspect\",[6,\"aspectOf\",[\"viewport\"]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"au\",[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",[1,\"aspect\",\"*\",[5,\"0.5\"]]]],[13,\"av\",[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]],[13,\"ru\",[1,[1,\"au\",\"*\",\"cosA\"],\"+\",[1,\"av\",\"*\",\"sinA\"]]],[13,\"rv\",[1,[1,\"au\",\"*\",[4,\"-\",\"sinA\"]],\"+\",[1,\"av\",\"*\",\"cosA\"]]],[10,[6,\"d.vec2f\",[\"ru\",\"rv\"]]]]]},externals:{aspectOf:()=>Cs,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),moe=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_div(he(sv(t,s)),1.414)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"z\"}],body:[0,[[10,[1,[6,\"std.length\",[[6,\"curl22z\",[\"pos\",\"z\"]]]],\"/\",[5,\"1.414\"]]]]]},externals:{\"std.length\":()=>he,curl22z:()=>sv}})&&e.f)({})),$S=Lk(la,{maxOctaves:8,drift:\"goldenAngle\",name:\"fractalOctaveSum\"}),_oe=w.fn([m,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";return $S(t,2,s,r,o,m(a,__tsover_mul(a,.7)),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"detail\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"octaveCount\"}],body:[0,[[10,[6,\"fractalOctaveSum\",[\"pos\",[5,\"2\"],\"detail\",\"contrast\",\"animTime\",[6,\"d.vec2f\",[\"seed\",[1,\"seed\",\"*\",[5,\"0.7\"]]]],\"octaveCount\"]]]]]},externals:{fractalOctaveSum:()=>$S,\"d.vec2f\":()=>m}})&&e.f)({})),foe=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return G(__tsover_add(__tsover_mul(__tsover_div(t.x,t.y),.5),.5),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sum\"}],body:[0,[[10,[6,\"std.clamp\",[[1,[1,[1,[7,\"sum\",\"x\"],\"/\",[7,\"sum\",\"y\"]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({}));var XS=Gk({distance:\"selectableSquared\",jitter:\"mix\",name:\"worleyNearest2\"}),HS=Lk(w.fn([m,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=XS(t,s,r,o,a);return PT(l.x,l.y,a,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"oUV\"},{type:\"i\",name:\"animT\"},{type:\"i\",name:\"seedOff\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"distNum\"},{type:\"i\",name:\"modeNum\"}],body:[0,[[13,\"dd\",[6,\"worleyNearest2\",[\"oUV\",\"animT\",\"seedOff\",\"jitter\",\"distNum\"]]],[10,[6,\"cellReduceSelectable\",[[7,\"dd\",\"x\"],[7,\"dd\",\"y\"],\"distNum\",\"modeNum\"]]]]]},externals:{worleyNearest2:()=>XS,cellReduceSelectable:()=>PT}})&&e.f)({})),{maxOctaves:4,drift:\"timeSeed\",name:\"worleyOctaveSum\"}),voe=w.fn([m,n,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";return HS(t,s,a,i,l,r,A(o,d,u),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"jitter\"},{type:\"i\",name:\"lacunarity\"},{type:\"i\",name:\"persistence\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"octaves\"},{type:\"i\",name:\"distNum\"},{type:\"i\",name:\"modeNum\"}],body:[0,[[10,[6,\"worleyOctaveSum\",[\"pos\",\"scale\",\"lacunarity\",\"persistence\",\"animTime\",\"seed\",[6,\"d.vec3f\",[\"jitter\",\"distNum\",\"modeNum\"]],\"octaves\"]]]]]},externals:{worleyOctaveSum:()=>HS,\"d.vec3f\":()=>A}})&&e.f)({})),hoe=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_mul(__tsover_div(t.x,B(t.y,1e-4)),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sum\"},{type:\"i\",name:\"modeScale\"}],body:[0,[[10,[1,[1,[7,\"sum\",\"x\"],\"/\",[6,\"std.max\",[[7,\"sum\",\"y\"],[5,\"0.0001\"]]]],\"*\",\"modeScale\"]]]]},externals:{\"std.max\":()=>B}})&&e.f)({})),goe=Dk({domain:\"unit\",contrastMode:\"multiplicative\",invert:!1}),N4=e=>EJ[e]??0,$4=e=>kJ[e]??0;function yoe(e){return typeof e==\"number\"?e:N4(e)}function boe(e){return typeof e==\"number\"?e:$4(e)}function xoe(e,t){let s=1.5;return e===1?s=1:e===2?s=2.5:e===3?s=.6:e===4&&(s=2),t===1?s*=.7:t===2&&(s*=1.4),s}var Aoe=Gk({distance:\"length\",jitter:\"none\",name:\"voronoiNearest2\"}),woe=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_sub(4,__tsover_mul(s,3));return CT(t.x,t.y,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dd\"},{type:\"i\",name:\"edgeIntensity\"}],body:[0,[[13,\"gradientPower\",[1,[5,\"4\"],\"-\",[1,\"edgeIntensity\",\"*\",[5,\"3\"]]]],[10,[6,\"cellRatio\",[[7,\"dd\",\"x\"],[7,\"dd\",\"y\"],\"gradientPower\"]]]]]},externals:{cellRatio:()=>CT}})&&e.f)({})),Toe=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(__tsover_mul(s,r),6);return MT(t.x,t.y,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dd\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"scale\"}],body:[0,[[13,\"scaledEdgeSoftness\",[1,[1,\"softness\",\"*\",\"scale\"],\"/\",[5,\"6\"]]],[10,[6,\"cellEdgeMask\",[[7,\"dd\",\"x\"],[7,\"dd\",\"y\"],\"scaledEdgeSoftness\"]]]]]},externals:{cellEdgeMask:()=>MT}})&&e.f)({})),Soe=w.fn([A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return vt(t,A(.85,.85,.85))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"}],body:[0,[[10,[6,\"std.pow\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.85\"],[5,\"0.85\"],[5,\"0.85\"]]]]]]]]},externals:{\"std.pow\":()=>vt,\"d.vec3f\":()=>A}})&&e.f)({})),zm=8;if(zm!==8)throw new Error(`noisePaints: MAX (${zm}) out of sync with MAX_COLOR_STOPS (8)`);var jS=w.fn([m,m,m,m,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_div(s.x,B(s.y,1e-6)),l=m(__tsover_mul(r.x,i),__tsover_sub(1,r.y)),c=m(__tsover_mul(o.x,i),__tsover_sub(1,o.y)),d=m(__tsover_mul(t.x,i),t.y),u=m(__tsover_sub(c.x,l.x),__tsover_sub(c.y,l.y)),p=B(he(u),1e-6),_=m(__tsover_div(u.x,p),__tsover_div(u.y,p)),f=m(-_.y,_.x),h=m(__tsover_sub(d.x,l.x),__tsover_sub(d.y,l.y)),g=__tsover_div(Se(h,_),p),y=Se(h,f),b=a>0,x=G(g,0,1),P=N(n(1),ae(__tsover_mul(x,Wo)),b),C=__tsover_mul(be(0,.06,g),__tsover_sub(1,be(.94,1,g)));return S(g,y,P,N(n(1),C,b))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"start\"},{type:\"i\",name:\"end\"},{type:\"i\",name:\"pinFlag\"}],body:[0,[[13,\"aspectRatio\",[1,[7,\"viewport\",\"x\"],\"/\",[6,\"std.max\",[[7,\"viewport\",\"y\"],[5,\"0.000001\"]]]]],[13,\"startPos\",[6,\"d.vec2f\",[[1,[7,\"start\",\"x\"],\"*\",\"aspectRatio\"],[1,[5,\"1\"],\"-\",[7,\"start\",\"y\"]]]]],[13,\"endPos\",[6,\"d.vec2f\",[[1,[7,\"end\",\"x\"],\"*\",\"aspectRatio\"],[1,[5,\"1\"],\"-\",[7,\"end\",\"y\"]]]]],[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspectRatio\"],[7,\"uv\",\"y\"]]]],[13,\"direction\",[6,\"d.vec2f\",[[1,[7,\"endPos\",\"x\"],\"-\",[7,\"startPos\",\"x\"]],[1,[7,\"endPos\",\"y\"],\"-\",[7,\"startPos\",\"y\"]]]]],[13,\"len\",[6,\"std.max\",[[6,\"std.length\",[\"direction\"]],[5,\"0.000001\"]]]],[13,\"normalizedDir\",[6,\"d.vec2f\",[[1,[7,\"direction\",\"x\"],\"/\",\"len\"],[1,[7,\"direction\",\"y\"],\"/\",\"len\"]]]],[13,\"perpDir\",[6,\"d.vec2f\",[[4,\"-\",[7,\"normalizedDir\",\"y\"]],[7,\"normalizedDir\",\"x\"]]]],[13,\"relativePos\",[6,\"d.vec2f\",[[1,[7,\"aspectUV\",\"x\"],\"-\",[7,\"startPos\",\"x\"]],[1,[7,\"aspectUV\",\"y\"],\"-\",[7,\"startPos\",\"y\"]]]]],[13,\"progress\",[1,[6,\"std.dot\",[\"relativePos\",\"normalizedDir\"]],\"/\",\"len\"]],[13,\"perpDist\",[6,\"std.dot\",[\"relativePos\",\"perpDir\"]]],[13,\"pinOn\",[1,\"pinFlag\",\">\",[5,\"0\"]]],[13,\"clampedProg\",[6,\"std.clamp\",[\"progress\",[5,\"0\"],[5,\"1\"]]]],[13,\"pinch\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"std.sin\",[[1,\"clampedProg\",\"*\",\"PI\"]]],\"pinOn\"]]],[13,\"fade\",[1,[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.06\"],\"progress\"]],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0.94\"],[5,\"1\"],\"progress\"]]]]],[13,\"edgeFade\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"fade\",\"pinOn\"]]],[10,[6,\"d.vec4f\",[\"progress\",\"perpDist\",\"pinch\",\"edgeFade\"]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.dot\":()=>Se,\"std.clamp\":()=>G,\"std.select\":()=>N,\"d.f32\":()=>n,\"std.sin\":()=>ae,PI:()=>Wo,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S}})&&e.f)({})),Poe=w.fn([m,m,m,m,S,S,S,Fe(S,zm),Fe(S,zm/4),Fe(A,zm)],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=a.x,_=a.y,f=a.z,h=a.w,g=i.x,y=i.y,b=i.z,x=i.w,P=l.y,C=l.z,E=l.w,R=jS(t,s,r,o,l.x),U=R.x,L=R.y,k=R.z,D=R.w,O=__tsover_mul(h,.07),F=__tsover_add(__tsover_mul(g,.08),8e-4),q=B(__tsover_sub(f,1),1),Y=A(0,0,0),V=n(0),X=__tsover_mul(__tsover_mul(U,Jt),_),Q=__tsover_add(__tsover_mul(U,8),__tsover_mul(P,2)),te=__tsover_add(__tsover_mul(U,b),C),J=j(Ut(f));for(let oe=0;oe<J;oe++){let le=n(oe),se=__tsover_div(le,q),Te=__tsover_mul(le,.9),de=__tsover_mul(P,__tsover_add(__tsover_mul(se,.6),.7)),xe=__tsover_add(ae(__tsover_add(__tsover_add(X,de),Te)),__tsover_mul(ae(__tsover_add(__tsover_sub(__tsover_mul(X,2.1),__tsover_mul(de,.7)),Te)),.5)),Ae=__tsover_mul(__tsover_mul(xe,p),.06),De=__tsover_mul(__tsover_sub(se,.5),y),Ee=__tsover_mul(__tsover_add(De,Ae),k),ze=re(__tsover_sub(L,Ee)),Ie=__tsover_sub(1,be(O,__tsover_add(O,F),ze)),ke=__tsover_add(__tsover_mul(ae(__tsover_add(Q,le)),.15),.85),Me=__tsover_add(te,__tsover_mul(se,x)),we=Vb(__tsover_sub(1,re(__tsover_sub(__tsover_mul(Re(__tsover_mul(Me,.5)),2),1))),c,d,u,E).conv,Ve=__tsover_mul(Ie,ke);Y=Y.add(we.mul(Ve)),V=__tsover_add(V,Ve)}return S(Y.div(B(V,1e-4)),G(__tsover_mul(V,D),0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"start\"},{type:\"i\",name:\"end\"},{type:\"i\",name:\"packed1\"},{type:\"i\",name:\"packed2\"},{type:\"i\",name:\"packed3\"},{type:\"i\",name:\"colors\"},{type:\"i\",name:\"positions\"},{type:\"i\",name:\"converted\"}],body:[0,[[13,\"amplitude\",[7,\"packed1\",\"x\"]],[13,\"frequency\",[7,\"packed1\",\"y\"]],[13,\"lineCount\",[7,\"packed1\",\"z\"]],[13,\"lineWidth\",[7,\"packed1\",\"w\"]],[13,\"softnessP\",[7,\"packed2\",\"x\"]],[13,\"spread\",[7,\"packed2\",\"y\"]],[13,\"colorScale\",[7,\"packed2\",\"z\"]],[13,\"colorVariance\",[7,\"packed2\",\"w\"]],[13,\"waveT\",[7,\"packed3\",\"y\"]],[13,\"colorT\",[7,\"packed3\",\"z\"]],[13,\"stopCount\",[7,\"packed3\",\"w\"]],[13,\"frame\",[6,\"ribbonPathFrame\",[\"uv\",\"viewport\",\"start\",\"end\",[7,\"packed3\",\"x\"]]]],[13,\"progress\",[7,\"frame\",\"x\"]],[13,\"perpDist\",[7,\"frame\",\"y\"]],[13,\"pinch\",[7,\"frame\",\"z\"]],[13,\"edgeFade\",[7,\"frame\",\"w\"]],[13,\"thickness\",[1,\"lineWidth\",\"*\",[5,\"0.07\"]]],[13,\"softness\",[1,[1,\"softnessP\",\"*\",[5,\"0.08\"]],\"+\",[5,\"0.0008\"]]],[13,\"denom\",[6,\"std.max\",[[1,\"lineCount\",\"-\",[5,\"1\"]],[5,\"1\"]]]],[12,\"accumColor\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[12,\"accumWeight\",[6,\"d.f32\",[[5,\"0\"]]]],[13,\"waveBase\",[1,[1,\"progress\",\"*\",\"TAU\"],\"*\",\"frequency\"]],[13,\"shimmerBase\",[1,[1,\"progress\",\"*\",[5,\"8\"]],\"+\",[1,\"waveT\",\"*\",[5,\"2\"]]]],[13,\"colorBase\",[1,[1,\"progress\",\"*\",\"colorScale\"],\"+\",\"colorT\"]],[13,\"n\",[6,\"d.i32\",[[6,\"std.round\",[\"lineCount\"]]]]],[14,[12,\"idx\",[5,\"0\"]],[1,\"idx\",\"<\",\"n\"],[102,\"++\",\"idx\"],[0,[[13,\"fi\",[6,\"d.f32\",[\"idx\"]]],[13,\"norm\",[1,\"fi\",\"/\",\"denom\"]],[13,\"phase\",[1,\"fi\",\"*\",[5,\"0.9\"]]],[13,\"strandT\",[1,\"waveT\",\"*\",[1,[1,\"norm\",\"*\",[5,\"0.6\"]],\"+\",[5,\"0.7\"]]]],[13,\"wave\",[1,[6,\"std.sin\",[[1,[1,\"waveBase\",\"+\",\"strandT\"],\"+\",\"phase\"]]],\"+\",[1,[6,\"std.sin\",[[1,[1,[1,\"waveBase\",\"*\",[5,\"2.1\"]],\"-\",[1,\"strandT\",\"*\",[5,\"0.7\"]]],\"+\",\"phase\"]]],\"*\",[5,\"0.5\"]]]],[13,\"displacement\",[1,[1,\"wave\",\"*\",\"amplitude\"],\"*\",[5,\"0.06\"]]],[13,\"baseline\",[1,[1,\"norm\",\"-\",[5,\"0.5\"]],\"*\",\"spread\"]],[13,\"centre\",[1,[1,\"baseline\",\"+\",\"displacement\"],\"*\",\"pinch\"]],[13,\"dd\",[6,\"std.abs\",[[1,\"perpDist\",\"-\",\"centre\"]]]],[13,\"line\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"thickness\",[1,\"thickness\",\"+\",\"softness\"],\"dd\"]]]],[13,\"shimmer\",[1,[1,[6,\"std.sin\",[[1,\"shimmerBase\",\"+\",\"fi\"]]],\"*\",[5,\"0.15\"]],\"+\",[5,\"0.85\"]]],[13,\"cc\",[1,\"colorBase\",\"+\",[1,\"norm\",\"*\",\"colorVariance\"]]],[13,\"colorCoord\",[1,[5,\"1\"],\"-\",[6,\"std.abs\",[[1,[1,[6,\"std.fract\",[[1,\"cc\",\"*\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]]],[13,\"stepRes\",[6,\"gradientStopsInSpace\",[\"colorCoord\",\"colors\",\"positions\",\"converted\",\"stopCount\"]]],[13,\"strandColor\",[7,\"stepRes\",\"conv\"]],[13,\"weight\",[1,\"line\",\"*\",\"shimmer\"]],[2,\"accumColor\",\"=\",[6,[7,\"accumColor\",\"add\"],[[6,[7,\"strandColor\",\"mul\"],[\"weight\"]]]]],[2,\"accumWeight\",\"=\",[1,\"accumWeight\",\"+\",\"weight\"]]]]],[13,\"workingColor\",[6,[7,\"accumColor\",\"div\"],[[6,\"std.max\",[\"accumWeight\",[5,\"0.0001\"]]]]]],[13,\"alpha\",[6,\"std.clamp\",[[1,\"accumWeight\",\"*\",\"edgeFade\"],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[\"workingColor\",\"alpha\"]]]]]},externals:{ribbonPathFrame:()=>jS,\"std.max\":()=>B,\"d.vec3f\":()=>A,\"d.f32\":()=>n,TAU:()=>Jt,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.sin\":()=>ae,\"std.abs\":()=>re,\"std.smoothstep\":()=>be,\"std.fract\":()=>Re,gradientStopsInSpace:()=>Vb,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({})),X4=w.fn([m,n,n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(__tsover_mul(t.x,s),t.y),c=__tsover_mul(r,6),d=l.mul(c).add(o),u=Uu(d).mul(a).mul(.0025),p=t.add(u),_=uT(d,j(6)),f=G(__tsover_add(1,__tsover_mul(__tsover_sub(_,.7),__tsover_mul(i,1.2))),0,1.5);return A(p.x,p.y,f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"grainScale\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"displacement\"},{type:\"i\",name:\"roughness\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"grainFreq\",[1,\"grainScale\",\"*\",[5,\"6\"]]],[13,\"grainUV\",[6,[7,[6,[7,\"aspectUV\",\"mul\"],[\"grainFreq\"]],\"add\"],[\"seed\"]]],[13,\"disp\",[6,[7,[6,[7,[6,\"curl22\",[\"grainUV\"]],\"mul\"],[\"displacement\"]],\"mul\"],[[5,\"0.0025\"]]]],[13,\"displacedUV\",[6,[7,\"uv\",\"add\"],[\"disp\"]]],[13,\"grain\",[6,\"paper12\",[\"grainUV\",[6,\"d.i32\",[[5,\"6\"]]]]]],[13,\"brightness\",[6,\"std.clamp\",[[1,[5,\"1\"],\"+\",[1,[1,\"grain\",\"-\",[5,\"0.7\"]],\"*\",[1,\"roughness\",\"*\",[5,\"1.2\"]]]],[5,\"0\"],[5,\"1.5\"]]]],[10,[6,\"d.vec3f\",[[7,\"displacedUV\",\"x\"],[7,\"displacedUV\",\"y\"],\"brightness\"]]]]]},externals:{\"d.vec2f\":()=>m,curl22:()=>Uu,paper12:()=>uT,\"d.i32\":()=>j,\"std.clamp\":()=>G,\"d.vec3f\":()=>A}})&&e.f)({})),gu=1e-5,KS=w.fn([m,m,m],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(t.x,s.x),a=__tsover_sub(t.y,s.y),i=__tsover_sub(r.x,s.x),l=__tsover_sub(r.y,s.y),c=B(he(m(i,l)),n(gu)),d=__tsover_div(__tsover_add(__tsover_mul(o,i),__tsover_mul(a,l)),c),u=B(B(-d,__tsover_sub(d,c)),n(0)),p=G(__tsover_div(d,c),n(0),n(1)),_=he(m(__tsover_sub(o,__tsover_mul(i,p)),__tsover_sub(a,__tsover_mul(l,p))));return A(d,Ue(B(__tsover_sub(__tsover_mul(_,_),__tsover_mul(u,u)),n(0))),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"}],body:[0,[[13,\"pax\",[1,[7,\"p\",\"x\"],\"-\",[7,\"a\",\"x\"]]],[13,\"pay\",[1,[7,\"p\",\"y\"],\"-\",[7,\"a\",\"y\"]]],[13,\"bax\",[1,[7,\"b\",\"x\"],\"-\",[7,\"a\",\"x\"]]],[13,\"bay\",[1,[7,\"b\",\"y\"],\"-\",[7,\"a\",\"y\"]]],[13,\"len\",[6,\"std.max\",[[6,\"std.length\",[[6,\"d.vec2f\",[\"bax\",\"bay\"]]]],[6,\"d.f32\",[\"EPS\"]]]]],[13,\"t\",[1,[1,[1,\"pax\",\"*\",\"bax\"],\"+\",[1,\"pay\",\"*\",\"bay\"]],\"/\",\"len\"]],[13,\"overshoot\",[6,\"std.max\",[[6,\"std.max\",[[4,\"-\",\"t\"],[1,\"t\",\"-\",\"len\"]]],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"h\",[6,\"std.clamp\",[[1,\"t\",\"/\",\"len\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"dSeg\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,\"pax\",\"-\",[1,\"bax\",\"*\",\"h\"]],[1,\"pay\",\"-\",[1,\"bay\",\"*\",\"h\"]]]]]]],[13,\"perp\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[1,\"dSeg\",\"*\",\"dSeg\"],\"-\",[1,\"overshoot\",\"*\",\"overshoot\"]],[6,\"d.f32\",[[5,\"0\"]]]]]]]],[10,[6,\"d.vec3f\",[\"t\",\"perp\",\"len\"]]]]]},externals:{\"std.max\":()=>B,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"d.f32\":()=>n,EPS:()=>gu,\"std.clamp\":()=>G,\"std.sqrt\":()=>Ue,\"d.vec3f\":()=>A}})&&e.f)({})),Coe=w.fn([m,m,m,m,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=Cs(s),_=KS(mT(t,s),Zi(r,p),Zi(o,p)),f=_.x,h=_.y,g=_.z,y=__tsover_mul(a,.5),b=__tsover_sub(f,__tsover_mul(g,.5)),x=__tsover_mul(g,.5),P=B(l,n(gu)),C=__tsover_add(P,c),E=B(ie(__tsover_add(__tsover_div(__tsover_add(g,c),C),.5)),n(1)),R=__tsover_div(g,B(__tsover_add(__tsover_mul(E,P),__tsover_mul(__tsover_sub(E,1),c)),n(gu))),U=__tsover_mul(P,R),L=__tsover_mul(C,R),k=G(ie(__tsover_div(f,L)),n(0),__tsover_sub(E,1)),D=__tsover_sub(f,__tsover_add(__tsover_mul(k,L),__tsover_mul(U,.5))),O=B(__tsover_sub(__tsover_mul(U,.5),y),n(0)),F=__tsover_mul(U,.5),q=B(__tsover_add(a,c),n(gu)),Y=B(ie(__tsover_add(__tsover_div(g,q),.5)),n(1)),V=__tsover_div(g,Y),X=G(ie(__tsover_add(__tsover_div(f,V),.5)),n(0),Y),Q=__tsover_sub(f,__tsover_mul(X,V)),te=i>=.5,J=i>=1.5,oe=N(b,N(D,Q,J),te),le=N(x,N(O,n(0),J),te),se=N(x,N(F,y,J),te),Te=N(d,u,oe>0),de=__tsover_sub(he(m(B(__tsover_sub(re(oe),le),n(0)),h)),y),xe=__tsover_sub(re(oe),se),Ae=__tsover_sub(h,y),De=N(__tsover_add(he(m(B(xe,n(0)),B(Ae,n(0)))),ye(B(xe,Ae),n(0))),de,Te>=.5),Ee=__tsover_div(1,s.y);return __tsover_sub(1,be(-Ee,Ee,De))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"pointA\"},{type:\"i\",name:\"pointB\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"style\"},{type:\"i\",name:\"dashLength\"},{type:\"i\",name:\"gapLength\"},{type:\"i\",name:\"capStart\"},{type:\"i\",name:\"capEnd\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"p\",[6,\"geom.aspectCorrectedUV\",[\"uv\",\"viewport\"]]],[13,\"a\",[6,\"geom.aspectCentrePosition\",[\"pointA\",\"aspect\"]]],[13,\"b\",[6,\"geom.aspectCentrePosition\",[\"pointB\",\"aspect\"]]],[13,\"seg\",[6,\"segmentArcPerp\",[\"p\",\"a\",\"b\"]]],[13,\"t\",[7,\"seg\",\"x\"]],[13,\"perp\",[7,\"seg\",\"y\"]],[13,\"len\",[7,\"seg\",\"z\"]],[13,\"halfT\",[1,\"thickness\",\"*\",[5,\"0.5\"]]],[13,\"cSolid\",[1,\"t\",\"-\",[1,\"len\",\"*\",[5,\"0.5\"]]]],[13,\"axSolid\",[1,\"len\",\"*\",[5,\"0.5\"]]],[13,\"rawDash\",[6,\"std.max\",[\"dashLength\",[6,\"d.f32\",[\"EPS\"]]]]],[13,\"rawPeriod\",[1,\"rawDash\",\"+\",\"gapLength\"]],[13,\"nDash\",[6,\"std.max\",[[6,\"std.floor\",[[1,[1,[1,\"len\",\"+\",\"gapLength\"],\"/\",\"rawPeriod\"],\"+\",[5,\"0.5\"]]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"scale\",[1,\"len\",\"/\",[6,\"std.max\",[[1,[1,\"nDash\",\"*\",\"rawDash\"],\"+\",[1,[1,\"nDash\",\"-\",[5,\"1\"]],\"*\",\"gapLength\"]],[6,\"d.f32\",[\"EPS\"]]]]]],[13,\"dashL\",[1,\"rawDash\",\"*\",\"scale\"]],[13,\"period\",[1,\"rawPeriod\",\"*\",\"scale\"]],[13,\"kDash\",[6,\"std.clamp\",[[6,\"std.floor\",[[1,\"t\",\"/\",\"period\"]]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"nDash\",\"-\",[5,\"1\"]]]]],[13,\"cDash\",[1,\"t\",\"-\",[1,[1,\"kDash\",\"*\",\"period\"],\"+\",[1,\"dashL\",\"*\",[5,\"0.5\"]]]]],[13,\"axDashRound\",[6,\"std.max\",[[1,[1,\"dashL\",\"*\",[5,\"0.5\"]],\"-\",\"halfT\"],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"axDashSquare\",[1,\"dashL\",\"*\",[5,\"0.5\"]]],[13,\"rawDotPeriod\",[6,\"std.max\",[[1,\"thickness\",\"+\",\"gapLength\"],[6,\"d.f32\",[\"EPS\"]]]]],[13,\"nDot\",[6,\"std.max\",[[6,\"std.floor\",[[1,[1,\"len\",\"/\",\"rawDotPeriod\"],\"+\",[5,\"0.5\"]]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"dotPeriod\",[1,\"len\",\"/\",\"nDot\"]],[13,\"kDot\",[6,\"std.clamp\",[[6,\"std.floor\",[[1,[1,\"t\",\"/\",\"dotPeriod\"],\"+\",[5,\"0.5\"]]]],[6,\"d.f32\",[[5,\"0\"]]],\"nDot\"]]],[13,\"cDot\",[1,\"t\",\"-\",[1,\"kDot\",\"*\",\"dotPeriod\"]]],[13,\"isPattern\",[1,\"style\",\">=\",[5,\"0.5\"]]],[13,\"isDotted\",[1,\"style\",\">=\",[5,\"1.5\"]]],[13,\"c\",[6,\"std.select\",[\"cSolid\",[6,\"std.select\",[\"cDash\",\"cDot\",\"isDotted\"]],\"isPattern\"]]],[13,\"axRound\",[6,\"std.select\",[\"axSolid\",[6,\"std.select\",[\"axDashRound\",[6,\"d.f32\",[[5,\"0\"]]],\"isDotted\"]],\"isPattern\"]]],[13,\"axSquare\",[6,\"std.select\",[\"axSolid\",[6,\"std.select\",[\"axDashSquare\",\"halfT\",\"isDotted\"]],\"isPattern\"]]],[13,\"capHere\",[6,\"std.select\",[\"capStart\",\"capEnd\",[1,\"c\",\">\",[5,\"0\"]]]]],[13,\"sdRound\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[[1,[6,\"std.abs\",[\"c\"]],\"-\",\"axRound\"],[6,\"d.f32\",[[5,\"0\"]]]]],\"perp\"]]]],\"-\",\"halfT\"]],[13,\"qx\",[1,[6,\"std.abs\",[\"c\"]],\"-\",\"axSquare\"]],[13,\"qy\",[1,\"perp\",\"-\",\"halfT\"]],[13,\"sdSquare\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"qx\",[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[\"qy\",[6,\"d.f32\",[[5,\"0\"]]]]]]]]],\"+\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",\"qy\"]],[6,\"d.f32\",[[5,\"0\"]]]]]]],[13,\"sd\",[6,\"std.select\",[\"sdSquare\",\"sdRound\",[1,\"capHere\",\">=\",[5,\"0.5\"]]]]],[13,\"feather\",[1,[5,\"1\"],\"/\",[7,\"viewport\",\"y\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"feather\"],\"feather\",\"sd\"]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"geom.aspectCorrectedUV\":()=>mT,\"geom.aspectCentrePosition\":()=>Zi,segmentArcPerp:()=>KS,\"std.max\":()=>B,\"d.f32\":()=>n,EPS:()=>gu,\"std.floor\":()=>ie,\"std.clamp\":()=>G,\"std.select\":()=>N,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.smoothstep\":()=>be}})&&e.f)({})),Moe=w.fn([m,m,n,m,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=cc(t,o,s),p=__tsover_mul(r,bt),_=Pn(u,pe(p),ae(p)),f=__tsover_add(__tsover_mul(__tsover_mul(_.x,a),Jt),d),h=__tsover_mul(ae(f),i),g=re(__tsover_sub(_.y,h)),y=__tsover_mul(l,.5),b=__tsover_mul(c,.5);return __tsover_sub(1,be(__tsover_sub(y,b),__tsover_add(y,b),g))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"position\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"amplitude\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"centered\",[6,\"geom.aspectCenteredDelta\",[\"uv\",\"position\",\"viewport\"]]],[13,\"angleRad\",[1,\"angle\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosAngle\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinAngle\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rotated\",[6,\"geom.rotate2\",[\"centered\",\"cosAngle\",\"sinAngle\"]]],[13,\"waveInput\",[1,[1,[1,[7,\"rotated\",\"x\"],\"*\",\"frequency\"],\"*\",\"TAU\"],\"+\",\"animTime\"]],[13,\"sineWave\",[1,[6,\"std.sin\",[\"waveInput\"]],\"*\",\"amplitude\"]],[13,\"distanceFromWave\",[6,\"std.abs\",[[1,[7,\"rotated\",\"y\"],\"-\",\"sineWave\"]]]],[13,\"halfThickness\",[1,\"thickness\",\"*\",[5,\"0.5\"]]],[13,\"halfSoftness\",[1,\"softness\",\"*\",[5,\"0.5\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"halfThickness\",\"-\",\"halfSoftness\"],[1,\"halfThickness\",\"+\",\"halfSoftness\"],\"distanceFromWave\"]]]]]]},externals:{\"geom.aspectCenteredDelta\":()=>cc,DEG_TO_RAD:()=>bt,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"geom.rotate2\":()=>Pn,TAU:()=>Jt,\"std.abs\":()=>re,\"std.smoothstep\":()=>be}})&&e.f)({})),QS=w.fn([n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return A(__tsover_add(__tsover_mul(pe(__tsover_mul(Jt,t)),.5),.5),__tsover_add(__tsover_mul(pe(__tsover_mul(Jt,__tsover_sub(t,.333))),.5),.5),__tsover_add(__tsover_mul(pe(__tsover_mul(Jt,__tsover_sub(t,.666))),.5),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[6,\"d.vec3f\",[[1,[1,[6,\"std.cos\",[[1,\"TAU_FULL\",\"*\",\"t\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[6,\"std.cos\",[[1,\"TAU_FULL\",\"*\",[1,\"t\",\"-\",[5,\"0.333\"]]]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[6,\"std.cos\",[[1,\"TAU_FULL\",\"*\",[1,\"t\",\"-\",[5,\"0.666\"]]]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.cos\":()=>pe,TAU_FULL:()=>Jt}})&&e.f)({})),C0=gt({aspect:n,lightPos:m,flareAxis:m,masterFade:n,lightDist:n,lightAngle:n}).$name(\"FlareFrame\"),Eoe=w.fn([m,m,n,m,n,n],C0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Cs(s),c=m(o.x,__tsover_sub(1,o.y)),d=m(__tsover_sub(.5,c.x),__tsover_sub(.5,c.y)),u=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(ae(__tsover_mul(r,3.7)),.04),__tsover_mul(ae(__tsover_mul(r,7.3)),.03)),__tsover_mul(ae(__tsover_mul(r,13.1)),.02)),.97),p=B(__tsover_mul(re(__tsover_sub(c.x,.5)),2),__tsover_mul(re(__tsover_sub(c.y,.5)),2)),_=__tsover_sub(1,__tsover_mul(i,.5)),f=K(1,__tsover_sub(1,be(_,1,p)),i),h=__tsover_mul(__tsover_mul(a,f),u),g=m(__tsover_mul(__tsover_sub(t.x,c.x),l),__tsover_sub(t.y,c.y));return C0({aspect:l,lightPos:c,flareAxis:d,masterFade:h,lightDist:he(g),lightAngle:Xt(g.y,g.x)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"lightPosRaw\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"edgeFade\"}],body:[0,[[13,\"aspect\",[6,\"geom.aspectOf\",[\"viewport\"]]],[13,\"lightPos\",[6,\"d.vec2f\",[[7,\"lightPosRaw\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"lightPosRaw\",\"y\"]]]]],[13,\"flareAxis\",[6,\"d.vec2f\",[[1,[5,\"0.5\"],\"-\",[7,\"lightPos\",\"x\"]],[1,[5,\"0.5\"],\"-\",[7,\"lightPos\",\"y\"]]]]],[13,\"shimmer\",[1,[1,[1,[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"3.7\"]]]],\"*\",[5,\"0.04\"]],\"+\",[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"7.3\"]]]],\"*\",[5,\"0.03\"]]],\"+\",[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"13.1\"]]]],\"*\",[5,\"0.02\"]]],\"+\",[5,\"0.97\"]]],[13,\"edgeDist\",[6,\"std.max\",[[1,[6,\"std.abs\",[[1,[7,\"lightPos\",\"x\"],\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]],[1,[6,\"std.abs\",[[1,[7,\"lightPos\",\"y\"],\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]]]],[13,\"fadeStart\",[1,[5,\"1\"],\"-\",[1,\"edgeFade\",\"*\",[5,\"0.5\"]]]],[13,\"edgeFadeV\",[6,\"std.mix\",[[5,\"1\"],[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"fadeStart\",[5,\"1\"],\"edgeDist\"]]],\"edgeFade\"]]],[13,\"masterFade\",[1,[1,\"intensity\",\"*\",\"edgeFadeV\"],\"*\",\"shimmer\"]],[13,\"toLightAR\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"lightPos\",\"x\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[7,\"lightPos\",\"y\"]]]]],[13,\"lightDist\",[6,\"std.length\",[\"toLightAR\"]]],[13,\"lightAngle\",[6,\"std.atan2\",[[7,\"toLightAR\",\"y\"],[7,\"toLightAR\",\"x\"]]]],[10,[6,\"FlareFrame\",[[104,{aspect:\"aspect\",lightPos:\"lightPos\",flareAxis:\"flareAxis\",masterFade:\"masterFade\",lightDist:\"lightDist\",lightAngle:\"lightAngle\"}]]]]]]},externals:{\"geom.aspectOf\":()=>Cs,\"d.vec2f\":()=>m,\"std.sin\":()=>ae,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.mix\":()=>K,\"std.smoothstep\":()=>be,\"std.length\":()=>he,\"std.atan2\":()=>Xt,FlareFrame:()=>C0}})&&e.f)({})),koe=w.fn([m,n,m,m,n,n,n,n,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=d.x,_=d.y,f=d.z,h=d.w,g=u.x,y=u.y,b=u.z,x=u.w,P=r.add(o.mul(__tsover_mul(__tsover_mul(p,i),2))),C=he(m(__tsover_mul(__tsover_sub(t.x,P.x),s),__tsover_sub(t.y,P.y))),E=_,R=__tsover_sub(1,be(__tsover_mul(E,.12),E,C)),U=__tsover_sub(1,be(__tsover_mul(E,.05),__tsover_mul(E,.45),C)),L=__tsover_mul(R,__tsover_sub(1,__tsover_mul(U,h))),k=__tsover_add(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(a,4.3),x)),.08),__tsover_mul(ae(__tsover_add(__tsover_mul(a,9.1),__tsover_mul(x,1.7))),.05)),.95),D=_v(C,__tsover_mul(E,.78),__tsover_mul(__tsover_mul(E,l),.14),__tsover_mul(E,.1)),O=D.x,F=D.y,q=D.z,Y=__tsover_mul(__tsover_mul(f,c),k);return A(__tsover_mul(__tsover_add(__tsover_mul(L,g),__tsover_mul(O,l)),Y),__tsover_mul(__tsover_add(__tsover_mul(L,y),__tsover_mul(F,l)),Y),__tsover_mul(__tsover_add(__tsover_mul(L,b),__tsover_mul(q,l)),Y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"lightPos\"},{type:\"i\",name:\"flareAxis\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"ghostSpread\"},{type:\"i\",name:\"ghostChroma\"},{type:\"i\",name:\"ghostInt\"},{type:\"i\",name:\"disc\"},{type:\"i\",name:\"tint\"}],body:[0,[[13,\"offset\",[7,\"disc\",\"x\"]],[13,\"size\",[7,\"disc\",\"y\"]],[13,\"bright\",[7,\"disc\",\"z\"]],[13,\"hollow\",[7,\"disc\",\"w\"]],[13,\"r\",[7,\"tint\",\"x\"]],[13,\"g\",[7,\"tint\",\"y\"]],[13,\"b\",[7,\"tint\",\"z\"]],[13,\"gPhase\",[7,\"tint\",\"w\"]],[13,\"ghostPos\",[6,[7,\"lightPos\",\"add\"],[[6,[7,\"flareAxis\",\"mul\"],[[1,[1,\"offset\",\"*\",\"ghostSpread\"],\"*\",[5,\"2\"]]]]]]],[13,\"toGhost\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"ghostPos\",\"x\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[7,\"ghostPos\",\"y\"]]]]],[13,\"dist\",[6,\"std.length\",[\"toGhost\"]]],[13,\"sz\",\"size\"],[13,\"discShape\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"sz\",\"*\",[5,\"0.12\"]],\"sz\",\"dist\"]]]],[13,\"innerFade\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"sz\",\"*\",[5,\"0.05\"]],[1,\"sz\",\"*\",[5,\"0.45\"]],\"dist\"]]]],[13,\"shape\",[1,\"discShape\",\"*\",[1,[5,\"1\"],\"-\",[1,\"innerFade\",\"*\",\"hollow\"]]]],[13,\"gShimmer\",[1,[1,[1,[6,\"std.sin\",[[1,[1,\"t\",\"*\",[5,\"4.3\"]],\"+\",\"gPhase\"]]],\"*\",[5,\"0.08\"]],\"+\",[1,[6,\"std.sin\",[[1,[1,\"t\",\"*\",[5,\"9.1\"]],\"+\",[1,\"gPhase\",\"*\",[5,\"1.7\"]]]]],\"*\",[5,\"0.05\"]]],\"+\",[5,\"0.95\"]]],[13,\"ringCenter\",[1,\"sz\",\"*\",[5,\"0.78\"]]],[13,\"chromaSpread\",[1,[1,\"sz\",\"*\",\"ghostChroma\"],\"*\",[5,\"0.14\"]]],[13,\"ringWidth\",[1,\"sz\",\"*\",[5,\"0.1\"]]],[13,\"ring\",[6,\"lightfields.chromaticRingBand\",[\"dist\",\"ringCenter\",\"chromaSpread\",\"ringWidth\"]]],[13,\"rRing\",[7,\"ring\",\"x\"]],[13,\"gRing\",[7,\"ring\",\"y\"]],[13,\"bRing\",[7,\"ring\",\"z\"]],[13,\"brightness\",[1,[1,\"bright\",\"*\",\"ghostInt\"],\"*\",\"gShimmer\"]],[10,[6,\"d.vec3f\",[[1,[1,[1,\"shape\",\"*\",\"r\"],\"+\",[1,\"rRing\",\"*\",\"ghostChroma\"]],\"*\",\"brightness\"],[1,[1,[1,\"shape\",\"*\",\"g\"],\"+\",[1,\"gRing\",\"*\",\"ghostChroma\"]],\"*\",\"brightness\"],[1,[1,[1,\"shape\",\"*\",\"b\"],\"+\",[1,\"bRing\",\"*\",\"ghostChroma\"]],\"*\",\"brightness\"]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.smoothstep\":()=>be,\"std.sin\":()=>ae,\"lightfields.chromaticRingBand\":()=>_v,\"d.vec3f\":()=>A}})&&e.f)({})),Boe=w.fn([m,n,m,n,n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=m(__tsover_sub(1,r.x),__tsover_sub(1,r.y)),u=m(__tsover_mul(__tsover_sub(t.x,d.x),s),__tsover_sub(t.y,d.y)),p=_v(he(u),i,__tsover_mul(__tsover_mul(i,l),.06),__tsover_add(__tsover_mul(c,.12),.005)),_=Xt(u.y,u.x),f=__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(_,3),__tsover_mul(o,.5))),.12),.88);return p.mul(a).mul(f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"lightPos\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"haloInt\"},{type:\"i\",name:\"haloRad\"},{type:\"i\",name:\"haloChroma\"},{type:\"i\",name:\"haloSoft\"}],body:[0,[[13,\"antiLight\",[6,\"d.vec2f\",[[1,[5,\"1\"],\"-\",[7,\"lightPos\",\"x\"]],[1,[5,\"1\"],\"-\",[7,\"lightPos\",\"y\"]]]]],[13,\"toAntiLight\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"antiLight\",\"x\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[7,\"antiLight\",\"y\"]]]]],[13,\"antiLightDist\",[6,\"std.length\",[\"toAntiLight\"]]],[13,\"haloChromaSpread\",[1,[1,\"haloRad\",\"*\",\"haloChroma\"],\"*\",[5,\"0.06\"]]],[13,\"haloWidth\",[1,[1,\"haloSoft\",\"*\",[5,\"0.12\"]],\"+\",[5,\"0.005\"]]],[13,\"halo\",[6,\"lightfields.chromaticRingBand\",[\"antiLightDist\",\"haloRad\",\"haloChromaSpread\",\"haloWidth\"]]],[13,\"haloAngle\",[6,\"std.atan2\",[[7,\"toAntiLight\",\"y\"],[7,\"toAntiLight\",\"x\"]]]],[13,\"haloAngVar\",[1,[1,[6,\"std.sin\",[[1,[1,\"haloAngle\",\"*\",[5,\"3\"]],\"+\",[1,\"t\",\"*\",[5,\"0.5\"]]]]],\"*\",[5,\"0.12\"]],\"+\",[5,\"0.88\"]]],[10,[6,[7,[6,[7,\"halo\",\"mul\"],[\"haloInt\"]],\"mul\"],[\"haloAngVar\"]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"lightfields.chromaticRingBand\":()=>_v,\"std.atan2\":()=>Xt,\"std.sin\":()=>ae}})&&e.f)({})),zoe=w.fn([n,m,n,n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=Xt(s.y,__tsover_mul(s.x,r)),d=__tsover_add(__tsover_mul(c,.5),__tsover_mul(o,.06)),u=__tsover_add(t,d),p=p0(u,__tsover_div(i,2),3.5),_=__tsover_mul(p0(__tsover_add(u,.25),__tsover_div(i,2),7),.4),f=__tsover_div(1,__tsover_add(1,__tsover_mul(__tsover_mul(a,a),60))),h=QS(__tsover_add(__tsover_div(u,Jt),.5));return K(A(1,.97,.92),h,.12).mul(__tsover_mul(__tsover_mul(__tsover_add(p,_),f),l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"flareAxis\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"lightDist\"},{type:\"i\",name:\"starburstPts\"},{type:\"i\",name:\"starburstInt\"}],body:[0,[[13,\"axisAng\",[6,\"std.atan2\",[[7,\"flareAxis\",\"y\"],[1,[7,\"flareAxis\",\"x\"],\"*\",\"aspect\"]]]],[13,\"rotation\",[1,[1,\"axisAng\",\"*\",[5,\"0.5\"]],\"+\",[1,\"t\",\"*\",[5,\"0.06\"]]]],[13,\"spikeAngle\",[1,\"lightAngle\",\"+\",\"rotation\"]],[13,\"primarySpikes\",[6,\"lightfields.angularCosineSpikes\",[\"spikeAngle\",[1,\"starburstPts\",\"/\",[5,\"2\"]],[5,\"3.5\"]]]],[13,\"secondarySpikes\",[1,[6,\"lightfields.angularCosineSpikes\",[[1,\"spikeAngle\",\"+\",[5,\"0.25\"]],[1,\"starburstPts\",\"/\",[5,\"2\"]],[5,\"7\"]]],\"*\",[5,\"0.4\"]]],[13,\"radialFall\",[1,[5,\"1\"],\"/\",[1,[5,\"1\"],\"+\",[1,[1,\"lightDist\",\"*\",\"lightDist\"],\"*\",[5,\"60\"]]]]],[13,\"starSpectral\",[6,\"lensFlareSpectral\",[[1,[1,\"spikeAngle\",\"/\",\"TAU_FULL\"],\"+\",[5,\"0.5\"]]]]],[13,\"starTint\",[6,\"std.mix\",[[6,\"d.vec3f\",[[5,\"1\"],[5,\"0.97\"],[5,\"0.92\"]]],\"starSpectral\",[5,\"0.12\"]]]],[10,[6,[7,\"starTint\",\"mul\"],[[1,[1,[1,\"primarySpikes\",\"+\",\"secondarySpikes\"],\"*\",\"radialFall\"],\"*\",\"starburstInt\"]]]]]]},externals:{\"std.atan2\":()=>Xt,\"lightfields.angularCosineSpikes\":()=>p0,lensFlareSpectral:()=>QS,TAU_FULL:()=>Jt,\"std.mix\":()=>K,\"d.vec3f\":()=>A}})&&e.f)({})),Roe=w.fn([m,m,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=re(__tsover_sub(t.y,s.y)),i=re(__tsover_sub(t.x,s.x)),l=Tt(__tsover_mul(__tsover_mul(-800,a),a)),c=__tsover_add(__tsover_mul(__tsover_mul(r,r),.25),.001),d=Tt(__tsover_div(__tsover_mul(__tsover_mul(-1,i),i),__tsover_mul(c,.7))),u=Tt(__tsover_div(__tsover_mul(__tsover_mul(-1,i),i),c)),p=Tt(__tsover_div(__tsover_mul(__tsover_mul(-1,i),i),__tsover_mul(c,1.4)));return A(__tsover_mul(__tsover_mul(l,d),.5),__tsover_mul(__tsover_mul(l,u),.65),__tsover_mul(__tsover_mul(l,p),.9)).mul(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"lightPos\"},{type:\"i\",name:\"streakLen\"},{type:\"i\",name:\"streakInt\"}],body:[0,[[13,\"dy\",[6,\"std.abs\",[[1,[7,\"uv\",\"y\"],\"-\",[7,\"lightPos\",\"y\"]]]]],[13,\"dx\",[6,\"std.abs\",[[1,[7,\"uv\",\"x\"],\"-\",[7,\"lightPos\",\"x\"]]]]],[13,\"vertFall\",[6,\"std.exp\",[[1,[1,[4,\"-\",[5,\"800\"]],\"*\",\"dy\"],\"*\",\"dy\"]]]],[13,\"lenSq\",[1,[1,[1,\"streakLen\",\"*\",\"streakLen\"],\"*\",[5,\"0.25\"]],\"+\",[5,\"0.001\"]]],[13,\"rStreak\",[6,\"std.exp\",[[1,[1,[1,[4,\"-\",[5,\"1\"]],\"*\",\"dx\"],\"*\",\"dx\"],\"/\",[1,\"lenSq\",\"*\",[5,\"0.7\"]]]]]],[13,\"gStreak\",[6,\"std.exp\",[[1,[1,[1,[4,\"-\",[5,\"1\"]],\"*\",\"dx\"],\"*\",\"dx\"],\"/\",\"lenSq\"]]]],[13,\"bStreak\",[6,\"std.exp\",[[1,[1,[1,[4,\"-\",[5,\"1\"]],\"*\",\"dx\"],\"*\",\"dx\"],\"/\",[1,\"lenSq\",\"*\",[5,\"1.4\"]]]]]],[10,[6,[7,[6,\"d.vec3f\",[[1,[1,\"vertFall\",\"*\",\"rStreak\"],\"*\",[5,\"0.5\"]],[1,[1,\"vertFall\",\"*\",\"gStreak\"],\"*\",[5,\"0.65\"]],[1,[1,\"vertFall\",\"*\",\"bStreak\"],\"*\",[5,\"0.9\"]]]],\"mul\"],[\"streakInt\"]]]]]},externals:{\"std.abs\":()=>re,\"std.exp\":()=>Tt,\"d.vec3f\":()=>A}})&&e.f)({})),Doe=w.fn([n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=ET(t,__tsover_div(1,__tsover_add(__tsover_mul(s,s),.01)));return A(1,.98,.95).mul(__tsover_mul(o,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lightDist\"},{type:\"i\",name:\"glareSz\"},{type:\"i\",name:\"glareInt\"}],body:[0,[[13,\"glareSharpness\",[1,[5,\"1\"],\"/\",[1,[1,\"glareSz\",\"*\",\"glareSz\"],\"+\",[5,\"0.01\"]]]],[13,\"glareFalloff\",[6,\"lightfields.radialGaussianFalloff\",[\"lightDist\",\"glareSharpness\"]]],[10,[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"0.98\"],[5,\"0.95\"]]],\"mul\"],[[1,\"glareFalloff\",\"*\",\"glareInt\"]]]]]]},externals:{\"lightfields.radialGaussianFalloff\":()=>ET,\"d.vec3f\":()=>A}})&&e.f)({})),Loe=w.fn([n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Tt(__tsover_mul(__tsover_mul(-500,t),t)),o=__tsover_sub(1,be(0,.025,t));return A(1,.98,.96).mul(__tsover_mul(__tsover_add(r,__tsover_mul(o,1.5)),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lightDist\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"coreSoft\",[6,\"std.exp\",[[1,[1,[4,\"-\",[5,\"500\"]],\"*\",\"lightDist\"],\"*\",\"lightDist\"]]]],[13,\"coreSharp\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.025\"],\"lightDist\"]]]],[10,[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"0.98\"],[5,\"0.96\"]]],\"mul\"],[[1,[1,\"coreSoft\",\"+\",[1,\"coreSharp\",\"*\",[5,\"1.5\"]]],\"*\",\"intensity\"]]]]]]},externals:{\"std.exp\":()=>Tt,\"std.smoothstep\":()=>be,\"d.vec3f\":()=>A}})&&e.f)({})),Uoe=w.fn([A,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t.mul(s);return S(r,G(__tsover_mul(rv(r),2),0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"flareTotal\"},{type:\"i\",name:\"masterFade\"}],body:[0,[[13,\"finalColor\",[6,[7,\"flareTotal\",\"mul\"],[\"masterFade\"]]],[13,\"flareAlpha\",[6,\"std.clamp\",[[1,[6,\"tone.luma601Dot\",[\"finalColor\"]],\"*\",[5,\"2\"]],[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[\"finalColor\",\"flareAlpha\"]]]]]},externals:{\"std.clamp\":()=>G,\"tone.luma601Dot\":()=>rv,\"d.vec4f\":()=>S}})&&e.f)({})),Ooe=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(o,.03),i=m(Aa(t.mul(5).add(m(a,a))),Aa(t.mul(5).add(m(31.4,31.4)).add(m(a,a)))).sub(m(.5,.5)),l=m(__tsover_div(1,s.x),__tsover_div(1,s.y));return t.add(i.mul(r).mul(l).mul(8))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"bleed\"},{type:\"i\",name:\"time\"}],body:[0,[[13,\"t\",[1,\"time\",\"*\",[5,\"0.03\"]]],[13,\"wob\",[6,[7,[6,\"d.vec2f\",[[6,\"noise.value12\",[[6,[7,[6,[7,\"uv\",\"mul\"],[[5,\"5\"]]],\"add\"],[[6,\"d.vec2f\",[\"t\",\"t\"]]]]]],[6,\"noise.value12\",[[6,[7,[6,[7,[6,[7,\"uv\",\"mul\"],[[5,\"5\"]]],\"add\"],[[6,\"d.vec2f\",[[5,\"31.4\"],[5,\"31.4\"]]]]],\"add\"],[[6,\"d.vec2f\",[\"t\",\"t\"]]]]]]]],\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"texel\",[6,\"d.vec2f\",[[1,[5,\"1\"],\"/\",[7,\"viewport\",\"x\"]],[1,[5,\"1\"],\"/\",[7,\"viewport\",\"y\"]]]]],[10,[6,[7,\"uv\",\"add\"],[[6,[7,[6,[7,[6,[7,\"wob\",\"mul\"],[\"bleed\"]],\"mul\"],[\"texel\"]],\"mul\"],[[5,\"8\"]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"noise.value12\":()=>Aa}})&&e.f)({})),Goe=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return m(__tsover_add(t.x,__tsover_div(r,s.x)),__tsover_add(t.y,__tsover_div(o,s.y)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvBase\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"uvBase\",\"x\"],\"+\",[1,\"ox\",\"/\",[7,\"viewport\",\"x\"]]],[1,[7,\"uvBase\",\"y\"],\"+\",[1,\"oy\",\"/\",[7,\"viewport\",\"y\"]]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Foe=w.fn([m,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Aa(t.mul(s).mul(.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"}],body:[0,[[10,[6,\"noise.value12\",[[6,[7,[6,[7,\"uv\",\"mul\"],[\"viewport\"]],\"mul\"],[[5,\"0.5\"]]]]]]]]},externals:{\"noise.value12\":()=>Aa}})&&e.f)({})),Ioe=w.fn([S,S,S,S,A,A,A,A,n,S,S,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_,f,h)=>{\"use gpu\";let g=t.mul(d),y=s.mul(d),b=r.mul(d),x=o.mul(d),P=A(g.x,g.y,g.z),C=A(y.x,y.y,y.z),E=A(b.x,b.y,b.z),R=A(x.x,x.y,x.z),U=a.mul(d).sub(P.mul(P)),L=i.mul(d).sub(C.mul(C)),k=l.mul(d).sub(E.mul(E)),D=c.mul(d).sub(R.mul(R)),O=__tsover_add(__tsover_add(U.x,U.y),U.z),F=__tsover_add(__tsover_add(L.x,L.y),L.z),q=__tsover_add(__tsover_add(k.x,k.y),k.z),Y=__tsover_add(__tsover_add(D.x,D.y),D.z),V=S(g.x,g.y,g.z,g.w),X=O;V=N(V,y,F<X),X=ye(X,F),V=N(V,b,q<X),X=ye(X,q),V=N(V,x,Y<X),X=ye(X,Y);let Q=Yt(V),te=A(Q.x,Q.y,Q.z),J=K(1,h,_),oe=A(p.x,p.y,p.z);return te=K(te.mul(J),te.mul(oe),A(__tsover_mul(_,.4))),K(A(u.x,u.y,u.z),te,A(f))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sum0\"},{type:\"i\",name:\"sum1\"},{type:\"i\",name:\"sum2\"},{type:\"i\",name:\"sum3\"},{type:\"i\",name:\"sq0\"},{type:\"i\",name:\"sq1\"},{type:\"i\",name:\"sq2\"},{type:\"i\",name:\"sq3\"},{type:\"i\",name:\"invN\"},{type:\"i\",name:\"originalBleed\"},{type:\"i\",name:\"paperColor\"},{type:\"i\",name:\"paper\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"grain\"}],body:[0,[[13,\"mean0\",[6,[7,\"sum0\",\"mul\"],[\"invN\"]]],[13,\"mean1\",[6,[7,\"sum1\",\"mul\"],[\"invN\"]]],[13,\"mean2\",[6,[7,\"sum2\",\"mul\"],[\"invN\"]]],[13,\"mean3\",[6,[7,\"sum3\",\"mul\"],[\"invN\"]]],[13,\"rgb0\",[6,\"d.vec3f\",[[7,\"mean0\",\"x\"],[7,\"mean0\",\"y\"],[7,\"mean0\",\"z\"]]]],[13,\"rgb1\",[6,\"d.vec3f\",[[7,\"mean1\",\"x\"],[7,\"mean1\",\"y\"],[7,\"mean1\",\"z\"]]]],[13,\"rgb2\",[6,\"d.vec3f\",[[7,\"mean2\",\"x\"],[7,\"mean2\",\"y\"],[7,\"mean2\",\"z\"]]]],[13,\"rgb3\",[6,\"d.vec3f\",[[7,\"mean3\",\"x\"],[7,\"mean3\",\"y\"],[7,\"mean3\",\"z\"]]]],[13,\"var0\",[6,[7,[6,[7,\"sq0\",\"mul\"],[\"invN\"]],\"sub\"],[[6,[7,\"rgb0\",\"mul\"],[\"rgb0\"]]]]],[13,\"var1\",[6,[7,[6,[7,\"sq1\",\"mul\"],[\"invN\"]],\"sub\"],[[6,[7,\"rgb1\",\"mul\"],[\"rgb1\"]]]]],[13,\"var2\",[6,[7,[6,[7,\"sq2\",\"mul\"],[\"invN\"]],\"sub\"],[[6,[7,\"rgb2\",\"mul\"],[\"rgb2\"]]]]],[13,\"var3\",[6,[7,[6,[7,\"sq3\",\"mul\"],[\"invN\"]],\"sub\"],[[6,[7,\"rgb3\",\"mul\"],[\"rgb3\"]]]]],[13,\"sigma0\",[1,[1,[7,\"var0\",\"x\"],\"+\",[7,\"var0\",\"y\"]],\"+\",[7,\"var0\",\"z\"]]],[13,\"sigma1\",[1,[1,[7,\"var1\",\"x\"],\"+\",[7,\"var1\",\"y\"]],\"+\",[7,\"var1\",\"z\"]]],[13,\"sigma2\",[1,[1,[7,\"var2\",\"x\"],\"+\",[7,\"var2\",\"y\"]],\"+\",[7,\"var2\",\"z\"]]],[13,\"sigma3\",[1,[1,[7,\"var3\",\"x\"],\"+\",[7,\"var3\",\"y\"]],\"+\",[7,\"var3\",\"z\"]]],[12,\"picked\",[6,\"d.vec4f\",[[7,\"mean0\",\"x\"],[7,\"mean0\",\"y\"],[7,\"mean0\",\"z\"],[7,\"mean0\",\"w\"]]]],[12,\"best\",\"sigma0\"],[2,\"picked\",\"=\",[6,\"std.select\",[\"picked\",\"mean1\",[1,\"sigma1\",\"<\",\"best\"]]]],[2,\"best\",\"=\",[6,\"std.min\",[\"best\",\"sigma1\"]]],[2,\"picked\",\"=\",[6,\"std.select\",[\"picked\",\"mean2\",[1,\"sigma2\",\"<\",\"best\"]]]],[2,\"best\",\"=\",[6,\"std.min\",[\"best\",\"sigma2\"]]],[2,\"picked\",\"=\",[6,\"std.select\",[\"picked\",\"mean3\",[1,\"sigma3\",\"<\",\"best\"]]]],[2,\"best\",\"=\",[6,\"std.min\",[\"best\",\"sigma3\"]]],[13,\"straight\",[6,\"blend.unpremultiplyAlpha\",[\"picked\"]]],[12,\"result\",[6,\"d.vec3f\",[[7,\"straight\",\"x\"],[7,\"straight\",\"y\"],[7,\"straight\",\"z\"]]]],[13,\"paperMul\",[6,\"std.mix\",[[5,\"1\"],\"grain\",\"paper\"]]],[13,\"paperTint\",[6,\"d.vec3f\",[[7,\"paperColor\",\"x\"],[7,\"paperColor\",\"y\"],[7,\"paperColor\",\"z\"]]]],[2,\"result\",\"=\",[6,\"std.mix\",[[6,[7,\"result\",\"mul\"],[\"paperMul\"]],[6,[7,\"result\",\"mul\"],[\"paperTint\"]],[6,\"d.vec3f\",[[1,\"paper\",\"*\",[5,\"0.4\"]]]]]]],[13,\"origRgb\",[6,\"d.vec3f\",[[7,\"originalBleed\",\"x\"],[7,\"originalBleed\",\"y\"],[7,\"originalBleed\",\"z\"]]]],[13,\"finalRGB\",[6,\"std.mix\",[\"origRgb\",\"result\",[6,\"d.vec3f\",[\"strength\"]]]]],[10,\"finalRGB\"]]]},externals:{\"d.vec3f\":()=>A,\"d.vec4f\":()=>S,\"std.select\":()=>N,\"std.min\":()=>ye,\"blend.unpremultiplyAlpha\":()=>Yt,\"std.mix\":()=>K}})&&e.f)({})),ZS=Math.sin(.785),JS=Math.cos(.785),eP=Math.sin(-.785),tP=Math.cos(-.785),um=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Ys(t)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[10,[6,\"noise.hash12\",[\"p\"]]]]]},externals:{\"noise.hash12\":()=>Ys}})&&e.f)({})),M0=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=ie(t),r=Re(t),o=r.mul(r).mul(r.mul(-2).add(3)),a=um(s),i=um(m(__tsover_add(s.x,1),s.y)),l=um(m(s.x,__tsover_add(s.y,1))),c=um(m(__tsover_add(s.x,1),__tsover_add(s.y,1)));return K(K(a,i,o.x),K(l,c,o.x),o.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"i\",[6,\"std.floor\",[\"p\"]]],[13,\"f\",[6,\"std.fract\",[\"p\"]]],[13,\"u\",[6,[7,[6,[7,\"f\",\"mul\"],[\"f\"]],\"mul\"],[[6,[7,[6,[7,\"f\",\"mul\"],[[4,\"-\",[5,\"2\"]]]],\"add\"],[[5,\"3\"]]]]]],[13,\"a\",[6,\"chalkHash21\",[\"i\"]]],[13,\"b\",[6,\"chalkHash21\",[[6,\"d.vec2f\",[[1,[7,\"i\",\"x\"],\"+\",[5,\"1\"]],[7,\"i\",\"y\"]]]]]],[13,\"c\",[6,\"chalkHash21\",[[6,\"d.vec2f\",[[7,\"i\",\"x\"],[1,[7,\"i\",\"y\"],\"+\",[5,\"1\"]]]]]]],[13,\"dd\",[6,\"chalkHash21\",[[6,\"d.vec2f\",[[1,[7,\"i\",\"x\"],\"+\",[5,\"1\"]],[1,[7,\"i\",\"y\"],\"+\",[5,\"1\"]]]]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[\"a\",\"b\",[7,\"u\",\"x\"]]],[6,\"std.mix\",[\"c\",\"dd\",[7,\"u\",\"x\"]]],[7,\"u\",\"y\"]]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,chalkHash21:()=>um,\"d.vec2f\":()=>m,\"std.mix\":()=>K}})&&e.f)({})),sP=w.fn([S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Se(A(t.x,t.y,t.z),A(.299,.587,.114))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"}],body:[0,[[10,[6,\"std.dot\",[[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),Yoe=w.fn([m,m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_div(1,s.x),l=__tsover_div(1,s.y);return m(__tsover_add(t.x,__tsover_mul(__tsover_mul(i,r),o)),__tsover_add(t.y,__tsover_mul(__tsover_mul(l,r),a)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"edgeThickness\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[13,\"texelX\",[1,[5,\"1\"],\"/\",[7,\"viewport\",\"x\"]]],[13,\"texelY\",[1,[5,\"1\"],\"/\",[7,\"viewport\",\"y\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",[1,[1,\"texelX\",\"*\",\"edgeThickness\"],\"*\",\"ox\"]],[1,[7,\"uv\",\"y\"],\"+\",[1,[1,\"texelY\",\"*\",\"edgeThickness\"],\"*\",\"oy\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),p1=w.fn([m,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_add(__tsover_mul(t.x,o),__tsover_mul(t.y,a)),c=__tsover_mul(re(__tsover_sub(Re(__tsover_div(l,s)),.5)),2),d=__tsover_sub(1,be(0,.35,c));return __tsover_mul(d,Et(i,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"P\"},{type:\"i\",name:\"hatchScale\"},{type:\"i\",name:\"shade\"},{type:\"i\",name:\"sa\"},{type:\"i\",name:\"ca\"},{type:\"i\",name:\"thr\"}],body:[0,[[13,\"ry\",[1,[1,[7,\"P\",\"x\"],\"*\",\"sa\"],\"+\",[1,[7,\"P\",\"y\"],\"*\",\"ca\"]]],[13,\"hl\",[1,[6,\"std.abs\",[[1,[6,\"std.fract\",[[1,\"ry\",\"/\",\"hatchScale\"]]],\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"line\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.35\"],\"hl\"]]]],[10,[1,\"line\",\"*\",[6,\"std.step\",[\"thr\",\"shade\"]]]]]]},externals:{\"std.abs\":()=>re,\"std.fract\":()=>Re,\"std.smoothstep\":()=>be,\"std.step\":()=>Et}})&&e.f)({})),Woe=w.fn([S,S,m,m,S,S,S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=t.x,u=t.y,p=t.z,_=t.w,f=s.x,h=s.y,g=s.z,y=s.w,b=a.x,x=a.y,P=i.x,C=i.y,E=i.z,R=i.w,U=__tsover_add(__tsover_add(__tsover_add(__tsover_sub(__tsover_sub(-d,__tsover_mul(_,2)),h),p),__tsover_mul(f,2)),y),L=__tsover_add(__tsover_add(__tsover_add(__tsover_sub(__tsover_sub(-d,__tsover_mul(u,2)),p),h),__tsover_mul(g,2)),y),k=Ue(__tsover_add(__tsover_mul(U,U),__tsover_mul(L,L))),D=K(n(1),.08,P),O=be(__tsover_mul(D,.4),D,k),F=__tsover_sub(1,b),q=r.mul(o),Y=__tsover_mul(B(B(p1(q,C,F,ZS,JS,.22),p1(q,C,F,eP,tP,.5)),p1(q,C,F,0,1,.78)),E),V=K(__tsover_sub(1,R),n(1),M0(q.mul(.5))),X=G(__tsover_mul(B(O,Y),V),0,1),Q=__tsover_mul(__tsover_sub(M0(q.mul(.9)),.5),.04);return S(K(l.xyz.add(Q),c.xyz,A(X)),x)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sobelA\"},{type:\"i\",name:\"sobelB\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"misc\"},{type:\"i\",name:\"params\"},{type:\"i\",name:\"boardColor\"},{type:\"i\",name:\"chalkColor\"}],body:[0,[[13,\"tl\",[7,\"sobelA\",\"x\"]],[13,\"t\",[7,\"sobelA\",\"y\"]],[13,\"tr\",[7,\"sobelA\",\"z\"]],[13,\"l\",[7,\"sobelA\",\"w\"]],[13,\"r\",[7,\"sobelB\",\"x\"]],[13,\"bl\",[7,\"sobelB\",\"y\"]],[13,\"bo\",[7,\"sobelB\",\"z\"]],[13,\"br\",[7,\"sobelB\",\"w\"]],[13,\"centerLum\",[7,\"misc\",\"x\"]],[13,\"centerAlpha\",[7,\"misc\",\"y\"]],[13,\"edgeSensitivity\",[7,\"params\",\"x\"]],[13,\"hatchScale\",[7,\"params\",\"y\"]],[13,\"shading\",[7,\"params\",\"z\"]],[13,\"grain\",[7,\"params\",\"w\"]],[13,\"gx\",[1,[1,[1,[1,[1,[4,\"-\",\"tl\"],\"-\",[1,\"l\",\"*\",[5,\"2\"]]],\"-\",\"bl\"],\"+\",\"tr\"],\"+\",[1,\"r\",\"*\",[5,\"2\"]]],\"+\",\"br\"]],[13,\"gy\",[1,[1,[1,[1,[1,[4,\"-\",\"tl\"],\"-\",[1,\"t\",\"*\",[5,\"2\"]]],\"-\",\"tr\"],\"+\",\"bl\"],\"+\",[1,\"bo\",\"*\",[5,\"2\"]]],\"+\",\"br\"]],[13,\"edgeMag\",[6,\"std.sqrt\",[[1,[1,\"gx\",\"*\",\"gx\"],\"+\",[1,\"gy\",\"*\",\"gy\"]]]]],[13,\"edgeHigh\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],[5,\"0.08\"],\"edgeSensitivity\"]]],[13,\"edge\",[6,\"std.smoothstep\",[[1,\"edgeHigh\",\"*\",[5,\"0.4\"]],\"edgeHigh\",\"edgeMag\"]]],[13,\"shade\",[1,[5,\"1\"],\"-\",\"centerLum\"]],[13,\"P\",[6,[7,\"uv\",\"mul\"],[\"viewport\"]]],[13,\"hatch\",[1,[6,\"std.max\",[[6,\"std.max\",[[6,\"chalkHatchLine\",[\"P\",\"hatchScale\",\"shade\",\"SIN_045\",\"COS_045\",[5,\"0.22\"]]],[6,\"chalkHatchLine\",[\"P\",\"hatchScale\",\"shade\",\"SIN_N45\",\"COS_N45\",[5,\"0.5\"]]]]],[6,\"chalkHatchLine\",[\"P\",\"hatchScale\",\"shade\",[5,\"0\"],[5,\"1\"],[5,\"0.78\"]]]]],\"*\",\"shading\"]],[13,\"dust\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",\"grain\"],[6,\"d.f32\",[[5,\"1\"]]],[6,\"chalkVnoise\",[[6,[7,\"P\",\"mul\"],[[5,\"0.5\"]]]]]]]],[13,\"chalkMask\",[6,\"std.clamp\",[[1,[6,\"std.max\",[\"edge\",\"hatch\"]],\"*\",\"dust\"],[5,\"0\"],[5,\"1\"]]]],[13,\"boardGrain\",[1,[1,[6,\"chalkVnoise\",[[6,[7,\"P\",\"mul\"],[[5,\"0.9\"]]]]],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.04\"]]],[13,\"boardRGB\",[6,[7,[7,\"boardColor\",\"xyz\"],\"add\"],[\"boardGrain\"]]],[13,\"col\",[6,\"std.mix\",[\"boardRGB\",[7,\"chalkColor\",\"xyz\"],[6,\"d.vec3f\",[\"chalkMask\"]]]]],[10,[6,\"d.vec4f\",[\"col\",\"centerAlpha\"]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.mix\":()=>K,\"d.f32\":()=>n,\"std.smoothstep\":()=>be,\"std.max\":()=>B,chalkHatchLine:()=>p1,SIN_045:()=>ZS,COS_045:()=>JS,SIN_N45:()=>eP,COS_N45:()=>tP,chalkVnoise:()=>M0,\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})),rP=1080,E0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cellCenter:m,cellUV:m,isOutside:n}),\"AsciiGrid\"),qoe=w.fn([m,m,n,n],E0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_div(s.y,rP),i=__tsover_mul(r,a),l=m(__tsover_div(s.x,i),__tsover_div(s.y,i)),c=m(__tsover_mul(t.x,l.x),__tsover_mul(t.y,l.y)),d=ie(c),u=Re(c),p=__tsover_sub(u.x,.5),_=__tsover_sub(u.y,.5),f=m(__tsover_add(__tsover_div(p,o),.5),__tsover_add(__tsover_div(_,o),.5)),h=__tsover_mul(o,.5),g=N(n(0),n(1),re(p)>h||re(_)>h);return E0({cellCenter:m(__tsover_div(__tsover_add(d.x,.5),l.x),__tsover_div(__tsover_add(d.y,.5),l.y)),cellUV:f,isOutside:g})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"cellSize\"},{type:\"i\",name:\"spacing\"}],body:[0,[[13,\"scaleFactor\",[1,[7,\"viewport\",\"y\"],\"/\",\"REFERENCE_HEIGHT\"]],[13,\"effectiveCellSize\",[1,\"cellSize\",\"*\",\"scaleFactor\"]],[13,\"mainGridSize\",[6,\"d.vec2f\",[[1,[7,\"viewport\",\"x\"],\"/\",\"effectiveCellSize\"],[1,[7,\"viewport\",\"y\"],\"/\",\"effectiveCellSize\"]]]],[13,\"gridCoords\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",[7,\"mainGridSize\",\"x\"]],[1,[7,\"uv\",\"y\"],\"*\",[7,\"mainGridSize\",\"y\"]]]]],[13,\"cellCoords\",[6,\"std.floor\",[\"gridCoords\"]]],[13,\"rawCellUV\",[6,\"std.fract\",[\"gridCoords\"]]],[13,\"centeredU\",[1,[7,\"rawCellUV\",\"x\"],\"-\",[5,\"0.5\"]]],[13,\"centeredV\",[1,[7,\"rawCellUV\",\"y\"],\"-\",[5,\"0.5\"]]],[13,\"cellUV\",[6,\"d.vec2f\",[[1,[1,\"centeredU\",\"/\",\"spacing\"],\"+\",[5,\"0.5\"]],[1,[1,\"centeredV\",\"/\",\"spacing\"],\"+\",[5,\"0.5\"]]]]],[13,\"half\",[1,\"spacing\",\"*\",[5,\"0.5\"]]],[13,\"isOutside\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[3,[1,[6,\"std.abs\",[\"centeredU\"]],\">\",\"half\"],\"||\",[1,[6,\"std.abs\",[\"centeredV\"]],\">\",\"half\"]]]]],[13,\"cellCenter\",[6,\"d.vec2f\",[[1,[1,[7,\"cellCoords\",\"x\"],\"+\",[5,\"0.5\"]],\"/\",[7,\"mainGridSize\",\"x\"]],[1,[1,[7,\"cellCoords\",\"y\"],\"+\",[5,\"0.5\"]],\"/\",[7,\"mainGridSize\",\"y\"]]]]],[10,[6,\"AsciiGrid\",[[104,{cellCenter:\"cellCenter\",cellUV:\"cellUV\",isOutside:\"isOutside\"}]]]]]]},externals:{REFERENCE_HEIGHT:()=>rP,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"std.select\":()=>N,\"d.f32\":()=>n,\"std.abs\":()=>re,AsciiGrid:()=>E0}})&&e.f)({})).$name(\"asciiGrid\"),Voe=w.fn([A,n,n,n,n,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=vt(Se(t,A(.299,.587,.114)),s),c=__tsover_sub(1,l),d=G(ie(__tsover_mul(c,r)),0,__tsover_sub(r,1)),u=__tsover_sub(d,__tsover_mul(o,ie(__tsover_div(d,o)))),p=ie(__tsover_div(d,o)),_=__tsover_mul(__tsover_div(1,o),a),f=__tsover_mul(u,_),h=__tsover_mul(p,_);return m(__tsover_add(f,__tsover_mul(i.x,_)),__tsover_add(h,__tsover_mul(i.y,_)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cellRgb\"},{type:\"i\",name:\"gamma\"},{type:\"i\",name:\"charCount\"},{type:\"i\",name:\"atlasSize\"},{type:\"i\",name:\"atlasScale\"},{type:\"i\",name:\"cellUV\"}],body:[0,[[13,\"rawBrightness\",[6,\"std.dot\",[\"cellRgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"adjustedBrightness\",[6,\"std.pow\",[\"rawBrightness\",\"gamma\"]]],[13,\"invertedBrightness\",[1,[5,\"1\"],\"-\",\"adjustedBrightness\"]],[13,\"scaledBrightness\",[1,\"invertedBrightness\",\"*\",\"charCount\"]],[13,\"charIndex\",[6,\"std.clamp\",[[6,\"std.floor\",[\"scaledBrightness\"]],[5,\"0\"],[1,\"charCount\",\"-\",[5,\"1\"]]]]],[13,\"atlasCol\",[1,\"charIndex\",\"-\",[1,\"atlasSize\",\"*\",[6,\"std.floor\",[[1,\"charIndex\",\"/\",\"atlasSize\"]]]]]],[13,\"atlasRow\",[6,\"std.floor\",[[1,\"charIndex\",\"/\",\"atlasSize\"]]]],[13,\"atlasCellSize\",[1,[1,[5,\"1\"],\"/\",\"atlasSize\"],\"*\",\"atlasScale\"]],[13,\"baseU\",[1,\"atlasCol\",\"*\",\"atlasCellSize\"]],[13,\"baseV\",[1,\"atlasRow\",\"*\",\"atlasCellSize\"]],[10,[6,\"d.vec2f\",[[1,\"baseU\",\"+\",[1,[7,\"cellUV\",\"x\"],\"*\",\"atlasCellSize\"]],[1,\"baseV\",\"+\",[1,[7,\"cellUV\",\"y\"],\"*\",\"atlasCellSize\"]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.pow\":()=>vt,\"std.clamp\":()=>G,\"std.floor\":()=>ie,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"asciiAtlasUV\"),Noe=w.fn([A,S,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Se(t,A(.299,.587,.114))<.1,l=s.w,c=l<o,d=N(n(1),l,a>.5),u=i||r>.5||c,p=N(d,n(0),u);return S(__tsover_mul(t.x,s.x),__tsover_mul(t.y,s.y),__tsover_mul(t.z,s.z),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"asciiRgb\"},{type:\"i\",name:\"cellColor\"},{type:\"i\",name:\"isOutside\"},{type:\"i\",name:\"alphaThreshold\"},{type:\"i\",name:\"preserveAlpha\"}],body:[0,[[13,\"charBrightness\",[6,\"std.dot\",[\"asciiRgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"isBackground\",[1,\"charBrightness\",\"<\",[5,\"0.1\"]]],[13,\"sourceAlpha\",[7,\"cellColor\",\"w\"]],[13,\"isBelowThreshold\",[1,\"sourceAlpha\",\"<\",\"alphaThreshold\"]],[13,\"outputAlpha\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"sourceAlpha\",[1,\"preserveAlpha\",\">\",[5,\"0.5\"]]]]],[13,\"hide\",[3,[3,\"isBackground\",\"||\",[1,\"isOutside\",\">\",[5,\"0.5\"]]],\"||\",\"isBelowThreshold\"]],[13,\"finalAlpha\",[6,\"std.select\",[\"outputAlpha\",[6,\"d.f32\",[[5,\"0\"]]],\"hide\"]]],[10,[6,\"d.vec4f\",[[1,[7,\"asciiRgb\",\"x\"],\"*\",[7,\"cellColor\",\"x\"]],[1,[7,\"asciiRgb\",\"y\"],\"*\",[7,\"cellColor\",\"y\"]],[1,[7,\"asciiRgb\",\"z\"],\"*\",[7,\"cellColor\",\"z\"]],\"finalAlpha\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.select\":()=>N,\"d.f32\":()=>n,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"asciiCompose\"),Xh=ko({TangentFrame:()=>U1,WardSpecularInput:()=>rA,bevelledFlatNormal:()=>H4,cosinePalette:()=>A_,fieldGradient:()=>tA,insideMask:()=>Nb,orthonormalTangentFrame:()=>$b,outsideShape:()=>K4,patternCoords:()=>j4,perspectiveViewRay:()=>Q4,volumetricNormal:()=>sA,wardAnisotropicSpecular:()=>Z4}),tA=w.fn([S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return m(__tsover_div(__tsover_sub(s.x,t.x),o),__tsover_div(__tsover_sub(r.x,t.x),o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"surf0\"},{type:\"i\",name:\"surfX\"},{type:\"i\",name:\"surfY\"},{type:\"i\",name:\"eps\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[7,\"surfX\",\"x\"],\"-\",[7,\"surf0\",\"x\"]],\"/\",\"eps\"],[1,[1,[7,\"surfY\",\"x\"],\"-\",[7,\"surf0\",\"x\"]],\"/\",\"eps\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),sA=w.fn([S,S,S,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return vs(A(G(__tsover_div(__tsover_sub(s.w,t.w),o),__tsover_mul(a,-1),a),G(__tsover_div(__tsover_sub(r.w,t.w),o),__tsover_mul(a,-1),a),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"surf0\"},{type:\"i\",name:\"surfX\"},{type:\"i\",name:\"surfY\"},{type:\"i\",name:\"eps\"},{type:\"i\",name:\"gradClamp\"}],body:[0,[[13,\"ddx\",[6,\"std.clamp\",[[1,[1,[7,\"surfX\",\"w\"],\"-\",[7,\"surf0\",\"w\"]],\"/\",\"eps\"],[1,\"gradClamp\",\"*\",[4,\"-\",[5,\"1\"]]],\"gradClamp\"]]],[13,\"ddy\",[6,\"std.clamp\",[[1,[1,[7,\"surfY\",\"w\"],\"-\",[7,\"surf0\",\"w\"]],\"/\",\"eps\"],[1,\"gradClamp\",\"*\",[4,\"-\",[5,\"1\"]]],\"gradClamp\"]]],[10,[6,\"std.normalize\",[[6,\"d.vec3f\",[\"ddx\",\"ddy\",[4,\"-\",[5,\"1\"]]]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.normalize\":()=>vs,\"d.vec3f\":()=>A}})&&e.f)({})),H4=w.fn([m,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=B(he(t),1e-4),o=ye(s,.9995);return A(__tsover_mul(__tsover_div(t.x,r),o),__tsover_mul(__tsover_div(t.y,r),o),__tsover_mul(Ue(__tsover_sub(1,__tsover_mul(o,o))),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"grad\"},{type:\"i\",name:\"sinTilt\"}],body:[0,[[13,\"glen\",[6,\"std.max\",[[6,\"std.length\",[\"grad\"]],[5,\"0.0001\"]]]],[13,\"sB\",[6,\"std.min\",[\"sinTilt\",[5,\"0.9995\"]]]],[10,[6,\"d.vec3f\",[[1,[1,[7,\"grad\",\"x\"],\"/\",\"glen\"],\"*\",\"sB\"],[1,[1,[7,\"grad\",\"y\"],\"/\",\"glen\"],\"*\",\"sB\"],[1,[6,\"std.sqrt\",[[1,[5,\"1\"],\"-\",[1,\"sB\",\"*\",\"sB\"]]]],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{\"std.max\":()=>B,\"std.length\":()=>he,\"std.min\":()=>ye,\"d.vec3f\":()=>A,\"std.sqrt\":()=>Ue}})&&e.f)({})),j4=w.fn([m,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(N(__tsover_sub(t.x,.5),s.y,r>.5),N(__tsover_sub(t.y,.5),s.z,r>.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfUV\"},{type:\"i\",name:\"surf0\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[10,[6,\"d.vec2f\",[[6,\"std.select\",[[1,[7,\"sdfUV\",\"x\"],\"-\",[5,\"0.5\"]],[7,\"surf0\",\"y\"],[1,\"volumetric\",\">\",[5,\"0.5\"]]]],[6,\"std.select\",[[1,[7,\"sdfUV\",\"y\"],\"-\",[5,\"0.5\"]],[7,\"surf0\",\"z\"],[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.select\":()=>N}})&&e.f)({})),K4=w.fn([n,n],ys)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t>__tsover_mul(s,2)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"pxH\"}],body:[0,[[10,[1,\"sdf\",\">\",[1,\"pxH\",\"*\",[5,\"2\"]]]]]]},externals:{}})&&e.f)({})),Nb=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=B(__tsover_mul(s,.03125),__tsover_mul(r,o));return G(__tsover_div(__tsover_mul(t,-1),a),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"sharpEdge\"},{type:\"i\",name:\"pxH\"},{type:\"i\",name:\"minPixels\"}],body:[0,[[13,\"w\",[6,\"std.max\",[[1,\"sharpEdge\",\"*\",[5,\"0.03125\"]],[1,\"pxH\",\"*\",\"minPixels\"]]]],[10,[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"w\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G}})&&e.f)({})),Q4=w.fn([m,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return vs(A(__tsover_mul(__tsover_mul(__tsover_sub(t.x,.5),s),r),__tsover_mul(__tsover_sub(t.y,.5),r),1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"fov\"}],body:[0,[[10,[6,\"std.normalize\",[[6,\"d.vec3f\",[[1,[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"],\"*\",\"fov\"],[1,[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]],\"*\",\"fov\"],[5,\"1\"]]]]]]]]},externals:{\"std.normalize\":()=>vs,\"d.vec3f\":()=>A}})&&e.f)({})),U1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({tangent:A,bitangent:A}),\"TangentFrame\"),$b=w.fn([A,A],U1)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=vs(s.sub(t.mul(Se(t,s))));return U1({tangent:r,bitangent:A(__tsover_sub(__tsover_mul(t.y,r.z),__tsover_mul(t.z,r.y)),__tsover_sub(__tsover_mul(t.z,r.x),__tsover_mul(t.x,r.z)),__tsover_sub(__tsover_mul(t.x,r.y),__tsover_mul(t.y,r.x)))})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"normal\"},{type:\"i\",name:\"dir\"}],body:[0,[[13,\"T3\",[6,\"std.normalize\",[[6,[7,\"dir\",\"sub\"],[[6,[7,\"normal\",\"mul\"],[[6,\"std.dot\",[\"normal\",\"dir\"]]]]]]]]],[13,\"B3\",[6,\"d.vec3f\",[[1,[1,[7,\"normal\",\"y\"],\"*\",[7,\"T3\",\"z\"]],\"-\",[1,[7,\"normal\",\"z\"],\"*\",[7,\"T3\",\"y\"]]],[1,[1,[7,\"normal\",\"z\"],\"*\",[7,\"T3\",\"x\"]],\"-\",[1,[7,\"normal\",\"x\"],\"*\",[7,\"T3\",\"z\"]]],[1,[1,[7,\"normal\",\"x\"],\"*\",[7,\"T3\",\"y\"]],\"-\",[1,[7,\"normal\",\"y\"],\"*\",[7,\"T3\",\"x\"]]]]]],[10,[6,\"TangentFrame\",[[104,{tangent:\"T3\",bitangent:\"B3\"}]]]]]]},externals:{\"std.normalize\":()=>vs,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,TangentFrame:()=>U1}})&&e.f)({})),rA=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({normal:A,tangent:A,light:A,view:A,alphaAlong:n,alphaAcross:n}),\"WardSpecularInput\"),Z4=w.fn([rA],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=$b(t.normal,t.tangent),r=vs(t.light.sub(t.view)),o=Se(r,s.tangent),a=Se(r,s.bitangent),i=G(re(Se(r,t.normal)),1e-4,1),l=B(t.alphaAlong,1e-4),c=B(t.alphaAcross,1e-4),d=__tsover_div(__tsover_add(__tsover_mul(__tsover_div(o,l),__tsover_div(o,l)),__tsover_mul(__tsover_div(a,c),__tsover_div(a,c))),__tsover_mul(__tsover_add(i,1),.5));return Tt(__tsover_mul(d,-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"frame\",[6,\"orthonormalTangentFrame\",[[7,\"p\",\"normal\"],[7,\"p\",\"tangent\"]]]],[13,\"H\",[6,\"std.normalize\",[[6,[7,[7,\"p\",\"light\"],\"sub\"],[[7,\"p\",\"view\"]]]]]],[13,\"hT\",[6,\"std.dot\",[\"H\",[7,\"frame\",\"tangent\"]]]],[13,\"hB\",[6,\"std.dot\",[\"H\",[7,\"frame\",\"bitangent\"]]]],[13,\"hN\",[6,\"std.clamp\",[[6,\"std.abs\",[[6,\"std.dot\",[\"H\",[7,\"p\",\"normal\"]]]]],[5,\"0.0001\"],[5,\"1\"]]]],[13,\"aT\",[6,\"std.max\",[[7,\"p\",\"alphaAlong\"],[5,\"0.0001\"]]]],[13,\"aB\",[6,\"std.max\",[[7,\"p\",\"alphaAcross\"],[5,\"0.0001\"]]]],[13,\"expo\",[1,[1,[1,[1,\"hT\",\"/\",\"aT\"],\"*\",[1,\"hT\",\"/\",\"aT\"]],\"+\",[1,[1,\"hB\",\"/\",\"aB\"],\"*\",[1,\"hB\",\"/\",\"aB\"]]],\"/\",[1,[1,\"hN\",\"+\",[5,\"1\"]],\"*\",[5,\"0.5\"]]]],[10,[6,\"std.exp\",[[1,\"expo\",\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{orthonormalTangentFrame:()=>$b,\"std.normalize\":()=>vs,\"std.dot\":()=>Se,\"std.clamp\":()=>G,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.exp\":()=>Tt}})&&e.f)({})),A_=w.fn([n,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return A(__tsover_add(__tsover_mul(pe(__tsover_mul(__tsover_add(t,s),Po)),.5),.5),__tsover_add(__tsover_mul(pe(__tsover_mul(__tsover_add(t,r),Po)),.5),.5),__tsover_add(__tsover_mul(pe(__tsover_mul(__tsover_add(t,o),Po)),.5),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"phaseR\"},{type:\"i\",name:\"phaseG\"},{type:\"i\",name:\"phaseB\"}],body:[0,[[10,[6,\"d.vec3f\",[[1,[1,[6,\"std.cos\",[[1,[1,\"t\",\"+\",\"phaseR\"],\"*\",\"TWO_PI\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[6,\"std.cos\",[[1,[1,\"t\",\"+\",\"phaseG\"],\"*\",\"TWO_PI\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[6,\"std.cos\",[[1,[1,\"t\",\"+\",\"phaseB\"],\"*\",\"TWO_PI\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.cos\":()=>pe,TWO_PI:()=>Po}})&&e.f)({})),$oe=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return be(0,1,Nb(t,B(__tsover_mul(s,.5),.001),r,1.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"edgeSoftness\"},{type:\"i\",name:\"pxH\"}],body:[0,[[13,\"sharpEdge\",[6,\"std.max\",[[1,\"edgeSoftness\",\"*\",[5,\"0.5\"]],[5,\"0.001\"]]]],[10,[6,\"std.smoothstep\",[[5,\"0\"],[5,\"1\"],[6,\"insideMask\",[\"sdf\",\"sharpEdge\",\"pxH\",[5,\"1.5\"]]]]]]]]},externals:{\"std.max\":()=>B,\"std.smoothstep\":()=>be,insideMask:()=>Nb}})&&e.f)({})),k0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({L:A,H:A}),\"KeyLight\"),Xoe=w.fn([n,n,n],k0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=vs(A(t,s,r));return k0({L:o,H:vs(o.add(A(0,0,-1)))})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"lx\"},{type:\"i\",name:\"ly\"},{type:\"i\",name:\"lz\"}],body:[0,[[13,\"L\",[6,\"std.normalize\",[[6,\"d.vec3f\",[\"lx\",\"ly\",\"lz\"]]]]],[13,\"H\",[6,\"std.normalize\",[[6,[7,\"L\",\"add\"],[[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[4,\"-\",[5,\"1\"]]]]]]]]],[10,[6,\"KeyLight\",[[104,{L:\"L\",H:\"H\"}]]]]]]},externals:{\"std.normalize\":()=>vs,\"d.vec3f\":()=>A,KeyLight:()=>k0}})&&e.f)({})),Hoe=w.fn([A],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_sub(1,G(__tsover_mul(t.z,-1),0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"n\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.clamp\",[[1,[7,\"n\",\"z\"],\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({})),joe=w.fn([n,n,S],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_mul(vt(t,K(r.x,r.y,s)),K(r.z,r.w,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ndh\"},{type:\"i\",name:\"sharp\"},{type:\"i\",name:\"cfg\"}],body:[0,[[10,[1,[6,\"std.pow\",[\"ndh\",[6,\"std.mix\",[[7,\"cfg\",\"x\"],[7,\"cfg\",\"y\"],\"sharp\"]]]],\"*\",[6,\"std.mix\",[[7,\"cfg\",\"z\"],[7,\"cfg\",\"w\"],\"sharp\"]]]]]]},externals:{\"std.pow\":()=>vt,\"std.mix\":()=>K}})&&e.f)({})),Koe=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=n(4),o=Si(t);return m(G(__tsover_mul(o.y,s),__tsover_mul(r,-1),r),G(__tsover_mul(o.z,s),__tsover_mul(r,-1),r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"gain\"}],body:[0,[[13,\"gMax\",[6,\"d.f32\",[[5,\"4\"]]]],[13,\"nd\",[6,\"perlin12d\",[\"q\"]]],[10,[6,\"d.vec2f\",[[6,\"std.clamp\",[[1,[7,\"nd\",\"y\"],\"*\",\"gain\"],[1,\"gMax\",\"*\",[4,\"-\",[5,\"1\"]]],\"gMax\"]],[6,\"std.clamp\",[[1,[7,\"nd\",\"z\"],\"*\",\"gain\"],[1,\"gMax\",\"*\",[4,\"-\",[5,\"1\"]]],\"gMax\"]]]]]]]},externals:{\"d.f32\":()=>n,perlin12d:()=>Si,\"d.vec2f\":()=>m,\"std.clamp\":()=>G}})&&e.f)({})),Qoe=w.fn([A,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return vs(A(__tsover_add(t.x,s),__tsover_add(t.y,r),t.z))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"n\"},{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"}],body:[0,[[10,[6,\"std.normalize\",[[6,\"d.vec3f\",[[1,[7,\"n\",\"x\"],\"+\",\"dx\"],[1,[7,\"n\",\"y\"],\"+\",\"dy\"],[7,\"n\",\"z\"]]]]]]]]},externals:{\"std.normalize\":()=>vs,\"d.vec3f\":()=>A}})&&e.f)({})),Zoe=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=G(__tsover_mul(__tsover_mul(t,-1),2),0,1.2);return N(__tsover_mul(G(__tsover_mul(t,-1),0,.5),2),r,s>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"thickVol\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",[5,\"2\"]],[5,\"0\"],[5,\"1.2\"]]]],[13,\"thickFlat\",[1,[6,\"std.clamp\",[[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"],[5,\"0.5\"]]],\"*\",[5,\"2\"]]],[10,[6,\"std.select\",[\"thickFlat\",\"thickVol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.select\":()=>N}})&&e.f)({})),Joe=w.fn([n,A],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return A(Tt(__tsover_mul(__tsover_mul(t,s.x),-1)),Tt(__tsover_mul(__tsover_mul(t,s.y),-1)),Tt(__tsover_mul(__tsover_mul(t,s.z),-1)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"absorb\"}],body:[0,[[10,[6,\"d.vec3f\",[[6,\"std.exp\",[[1,[1,\"thickness\",\"*\",[7,\"absorb\",\"x\"]],\"*\",[4,\"-\",[5,\"1\"]]]]],[6,\"std.exp\",[[1,[1,\"thickness\",\"*\",[7,\"absorb\",\"y\"]],\"*\",[4,\"-\",[5,\"1\"]]]]],[6,\"std.exp\",[[1,[1,\"thickness\",\"*\",[7,\"absorb\",\"z\"]],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.exp\":()=>Tt}})&&e.f)({})),eae=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(__tsover_mul(ae(__tsover_add(__tsover_add(__tsover_mul(t.x,1.7),__tsover_mul(s,.7)),1.7)),pe(__tsover_add(__tsover_add(__tsover_mul(t.y,1.3),__tsover_mul(s,.5)),2.3))),__tsover_mul(pe(__tsover_add(__tsover_add(__tsover_mul(t.x,1.4),__tsover_mul(s,.9)),8.7)),ae(__tsover_add(__tsover_add(__tsover_mul(t.y,1.6),__tsover_mul(s,.6)),5.1))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"warpInput\"},{type:\"i\",name:\"flowT\"}],body:[0,[[13,\"wx\",[1,[6,\"std.sin\",[[1,[1,[1,[7,\"warpInput\",\"x\"],\"*\",[5,\"1.7\"]],\"+\",[1,\"flowT\",\"*\",[5,\"0.7\"]]],\"+\",[5,\"1.7\"]]]],\"*\",[6,\"std.cos\",[[1,[1,[1,[7,\"warpInput\",\"y\"],\"*\",[5,\"1.3\"]],\"+\",[1,\"flowT\",\"*\",[5,\"0.5\"]]],\"+\",[5,\"2.3\"]]]]]],[13,\"wy\",[1,[6,\"std.cos\",[[1,[1,[1,[7,\"warpInput\",\"x\"],\"*\",[5,\"1.4\"]],\"+\",[1,\"flowT\",\"*\",[5,\"0.9\"]]],\"+\",[5,\"8.7\"]]]],\"*\",[6,\"std.sin\",[[1,[1,[1,[7,\"warpInput\",\"y\"],\"*\",[5,\"1.6\"]],\"+\",[1,\"flowT\",\"*\",[5,\"0.6\"]]],\"+\",[5,\"5.1\"]]]]]],[10,[6,\"d.vec2f\",[\"wx\",\"wy\"]]]]]},externals:{\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"d.vec2f\":()=>m}})&&e.f)({})),tae=w.fn([n,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_sub(__tsover_mul(t,r),__tsover_mul(s,o)),u=__tsover_add(__tsover_mul(t,o),__tsover_mul(s,r)),p=m(d,u),_=be(-.7,.85,u),f=__tsover_mul(__tsover_mul(_,_),c),h=__tsover_mul(a,1);f=__tsover_add(f,__tsover_mul(__tsover_mul(be(h,__tsover_mul(h,.2),he(p.sub(m(__tsover_add(0,i),.55)))),1.7),l));let g=__tsover_mul(a,1.15);f=__tsover_add(f,__tsover_mul(__tsover_mul(be(g,__tsover_mul(g,.2),he(p.sub(m(__tsover_add(-.55,i),.18)))),1.05),l));let y=__tsover_mul(a,1);f=__tsover_add(f,__tsover_mul(__tsover_mul(be(y,__tsover_mul(y,.2),he(p.sub(m(__tsover_add(.55,i),.1)))),1),l));let b=__tsover_mul(a,1.3);f=__tsover_add(f,__tsover_mul(__tsover_mul(be(b,__tsover_mul(b,.2),he(p.sub(m(__tsover_add(.2,i),-.5)))),.7),l));let x=__tsover_mul(a,1.1);return f=__tsover_add(f,__tsover_mul(__tsover_mul(be(x,__tsover_mul(x,.2),he(p.sub(m(__tsover_add(-.35,i),-.25)))),.85),l)),f}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rx\"},{type:\"i\",name:\"ry\"},{type:\"i\",name:\"envC\"},{type:\"i\",name:\"envS\"},{type:\"i\",name:\"keyRad\"},{type:\"i\",name:\"drift\"},{type:\"i\",name:\"envStr\"},{type:\"i\",name:\"skyGain\"}],body:[0,[[13,\"ex\",[1,[1,\"rx\",\"*\",\"envC\"],\"-\",[1,\"ry\",\"*\",\"envS\"]]],[13,\"ey\",[1,[1,\"rx\",\"*\",\"envS\"],\"+\",[1,\"ry\",\"*\",\"envC\"]]],[13,\"p\",[6,\"d.vec2f\",[\"ex\",\"ey\"]]],[13,\"sky\",[6,\"std.smoothstep\",[[4,\"-\",[5,\"0.7\"]],[5,\"0.85\"],\"ey\"]]],[12,\"lum\",[1,[1,\"sky\",\"*\",\"sky\"],\"*\",\"skyGain\"]],[13,\"r0\",[1,\"keyRad\",\"*\",[5,\"1\"]]],[2,\"lum\",\"=\",[1,\"lum\",\"+\",[1,[1,[6,\"std.smoothstep\",[\"r0\",[1,\"r0\",\"*\",[5,\"0.2\"]],[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[1,[5,\"0\"],\"+\",\"drift\"],[5,\"0.55\"]]]]]]]]],\"*\",[5,\"1.7\"]],\"*\",\"envStr\"]]],[13,\"r1\",[1,\"keyRad\",\"*\",[5,\"1.15\"]]],[2,\"lum\",\"=\",[1,\"lum\",\"+\",[1,[1,[6,\"std.smoothstep\",[\"r1\",[1,\"r1\",\"*\",[5,\"0.2\"]],[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[1,[4,\"-\",[5,\"0.55\"]],\"+\",\"drift\"],[5,\"0.18\"]]]]]]]]],\"*\",[5,\"1.05\"]],\"*\",\"envStr\"]]],[13,\"r2\",[1,\"keyRad\",\"*\",[5,\"1\"]]],[2,\"lum\",\"=\",[1,\"lum\",\"+\",[1,[1,[6,\"std.smoothstep\",[\"r2\",[1,\"r2\",\"*\",[5,\"0.2\"]],[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[1,[5,\"0.55\"],\"+\",\"drift\"],[5,\"0.1\"]]]]]]]]],\"*\",[5,\"1\"]],\"*\",\"envStr\"]]],[13,\"r3\",[1,\"keyRad\",\"*\",[5,\"1.3\"]]],[2,\"lum\",\"=\",[1,\"lum\",\"+\",[1,[1,[6,\"std.smoothstep\",[\"r3\",[1,\"r3\",\"*\",[5,\"0.2\"]],[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[1,[5,\"0.2\"],\"+\",\"drift\"],[4,\"-\",[5,\"0.5\"]]]]]]]]]],\"*\",[5,\"0.7\"]],\"*\",\"envStr\"]]],[13,\"r4\",[1,\"keyRad\",\"*\",[5,\"1.1\"]]],[2,\"lum\",\"=\",[1,\"lum\",\"+\",[1,[1,[6,\"std.smoothstep\",[\"r4\",[1,\"r4\",\"*\",[5,\"0.2\"]],[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[6,\"d.vec2f\",[[1,[4,\"-\",[5,\"0.35\"]],\"+\",\"drift\"],[4,\"-\",[5,\"0.25\"]]]]]]]]]],\"*\",[5,\"0.85\"]],\"*\",\"envStr\"]]],[10,\"lum\"]]]},externals:{\"d.vec2f\":()=>m,\"std.smoothstep\":()=>be,\"std.length\":()=>he}})&&e.f)({})),Xb=new Map,Hb=new Set;function oA(e,t,s){if(!e||!(t>0)||!(s>0))return;let r=Xb.get(e);if(!(r&&r.width===t&&r.height===s)){Xb.set(e,{width:t,height:s});for(let o of Hb)try{o()}catch{}}}function J4(e){return Xb.get(e)??null}function eB(e){return Hb.add(e),()=>{Hb.delete(e)}}function sae(e,t){return Math.floor(Math.log2(Math.max(e,t)))+1}function gc(e,t){let{createMediaTexture:s,registerMediaTexture:r,onCleanup:o}=e,a=t.mipmaps??!0,i=(u,p)=>s({width:u,height:p,label:t.label,...a?{mipLevelCount:sae(u,p)}:{},...t.format?{format:t.format}:{}}),l=i(Math.max(1,t.initial?.width??1),Math.max(1,t.initial?.height??1)),c=!1,d=r(()=>l.texture);return o(()=>{c=!0,l.destroy()}),{kit:d,ensureSize(u,p){let _=Math.max(1,u),f=Math.max(1,p);if(c||l.width===_&&l.height===f)return;let h=i(_,f),g=l;l=h,g.destroy()},write(u){c||(l.write(u),a&&l.generateMipmaps())},unwrap:()=>l.unwrap(),get width(){return l.width},get height(){return l.height},get disposed(){return c}}}function tB(e,t){let{getCpuValue:s,onBeforeRender:r,onCleanup:o}=e,a=\"\",i=!1,l=!1,c=null,d=p=>{if(!p||p.trim()===\"\"||i||l)return;i=!0;let _={isDisposed:()=>l,commit:()=>{a=p}};(async()=>{try{await t.load(p,_)}catch(f){t.onError?.(f,p)}finally{i=!1,c=a===p?null:p}})()},u=()=>s(t.prop)??\"\";return setTimeout(()=>{let p=u();p&&p.trim()!==\"\"&&d(p)},0),r(()=>{let p=u();p===a||i||p!==c&&(c=null,d(p))}),o(()=>{l=!0,a=\"\"}),{currentUrl:()=>a,isLoading:()=>i,request:d}}var lu=2048;function rae(e){return/\\.svg($|\\?|#)/i.test(e)}function oae(e){return new Promise((t,s)=>{let r=new Image;r.crossOrigin=\"anonymous\",r.onload=()=>{let o=r.naturalWidth||lu,a=r.naturalHeight||lu,i=o/a,l=i>=1?lu:Math.round(lu*i),c=i>=1?Math.round(lu/i):lu,d=document.createElement(\"canvas\");d.width=l,d.height=c;let u=d.getContext(\"2d\");if(!u){s(new Error(\"Could not get 2D context\"));return}u.drawImage(r,0,0,l,c),t({source:d,width:l,height:c,naturalWidth:o,naturalHeight:a,close:()=>{}})},r.onerror=()=>s(new Error(`SVG image failed to load: ${e}`)),r.src=e})}async function aae(e){if(rae(e))return oae(e);let t=await fetch(e,{mode:\"cors\"});if(!t.ok)throw new Error(`HTTP ${t.status}`);let s=await t.blob(),r=await createImageBitmap(s),o=!1;return{source:r,width:r.width,height:r.height,naturalWidth:r.width,naturalHeight:r.height,close:()=>{o||(o=!0,r.close())}}}function oP(){let e=document.createElement(\"video\");return e.playsInline=!0,e.muted=!0,e}function aP(e,t){return new Promise((s,r)=>{e.onloadedmetadata=()=>s(),e.onerror=()=>r(new Error(\"Failed to load video\")),t>0&&setTimeout(()=>r(new Error(\"Video load timeout\")),t)})}function sB(e,t){let{getCpuValue:s,onBeforeRender:r,onCleanup:o}=e,a=t.metadataTimeoutMs??0,i=t.autoplayRequired??!1,l=null,c=null,d=!1,u=()=>{if(!t.loop)return!1;let f=s(t.loop.prop);return f===!0||f===void 0||typeof f==\"number\"&&f>0},p=async(f,h)=>{try{await f.play()}catch(y){if(t.onError?.(y,{url:h,stage:\"autoplay\"}),i)throw y}if(d)return;l&&l!==f&&(l.pause(),l.src=\"\"),l=f;let g=t.naturalSizeKey??h;g&&oA(g,f.videoWidth,f.videoHeight)};if(t.source.kind===\"url\"){let f=t.source.prop;tB(e,{prop:f,async load(h,g){let y=oP();y.src=h,y.crossOrigin=\"anonymous\",y.loop=u();try{await aP(y,a)}catch(b){throw y.src=\"\",b}if(g.isDisposed()){y.src=\"\";return}g.commit(),await p(y,h)},onError(h,g){t.onError?.(h,{url:g,stage:\"acquire\"})}}),t.loop&&r(()=>{if(!l)return;let h=u();l.loop!==h&&(l.loop=h)}),o(()=>{d=!0,l&&(l.pause(),l.src=\"\",l=null)})}else{let f=t.source.constraints??{video:!0,audio:!1},h=!1,g=async()=>{if(!(h||d))try{if(c=await navigator.mediaDevices.getUserMedia(f),d){c.getTracks().forEach(b=>b.stop()),c=null;return}let y=oP();if(y.srcObject=c,await aP(y,a),d||(await p(y,null),d))return;h=!0,di(`[media] Video source started: ${y.videoWidth}x${y.videoHeight}`)}catch(y){t.onError?.(y,{url:null,stage:\"acquire\"})}};setTimeout(()=>{g()},0),r(()=>{}),o(()=>{d=!0,c&&(c.getTracks().forEach(y=>y.stop()),c=null),l&&(l.srcObject=null,l=null),h=!1})}return{getSource:()=>!l||d||l.readyState<2||l.videoWidth===0?null:l,element:()=>l}}function w_(e,t={}){let{canvas:s,dimensions:r,onCleanup:o}=e,a=t.maxAxis??4096,i=t.supersample??1,l=null,c=null,d=!1,u=()=>d?null:(l||(l=document.createElement(\"canvas\"),l.width=2,l.height=2,c=l.getContext(\"2d\",t.contextAttributes)),c);return o(()=>{d=!0,l&&(l.width=0,l.height=0),l=null,c=null}),{context:u,canvas:()=>l,devicePixelRatio(){let p=r.width||1;return Math.max(.1,(s.width||p)/p)},rasterSize(p,_){let f=r.width||1,h=Math.max(.1,(s.width||f)/f)*i;return h=Math.min(h,a/p,a/_),{scale:h,texW:Math.max(2,Math.round(p*h)),texH:Math.max(2,Math.round(_*h))}},resize(p,_){let f=u();return!f||!l?null:(l.width=p,l.height=_,f.clearRect(0,0,p,_),f)},get disposed(){return d}}}function T_(e,t){let s=t.minIntervalMs??16,r=t.initialKey??\"\",o=0;e.onBeforeRender(()=>{let a=Date.now();if(a-o<s)return;o=a;let i=t.key();i!==r&&(r=i,t.run())})}function S_(e){let t=\"\";return{ensure(){let s=e.key();s!==t&&(t=s,e.load().then(()=>e.onLoaded()).catch(()=>{}))}}}function nae(e,t=400,s=!1,r){let o=`https://fonts.googleapis.com/css2?family=${e.trim().replace(/ /g,\"+\")}:ital,wght@${s?1:0},${t}&display=swap`;return r&&(o+=`&text=${encodeURIComponent(r)}`),o}var nP=new Set,B0=new Map;function Hh(e,t=400,s=!1){if(typeof document>\"u\"||!e)return Promise.resolve();let r=`${e}|${t}|${s}`;if(nP.has(r))return Promise.resolve();let o=B0.get(r);if(o)return o;let a=iae(e,t,s).catch(()=>{if(t!==400||s)return Hh(e,400,!1)}).then(()=>{nP.add(r),B0.delete(r)});return B0.set(r,a),a}function iae(e,t,s){let r=nae(e,t,s);return new Promise((o,a)=>{if(document.querySelector(`link[href=\"${r}\"]`)){o();return}let i=document.createElement(\"link\");i.rel=\"stylesheet\",i.href=r,i.onload=()=>o(),i.onerror=()=>{i.remove(),a(new Error(`Failed to load font stylesheet: ${e}`))},document.head.appendChild(i)}).then(async()=>{if(document.fonts?.load){let o=`${s?\"italic \":\"\"}${t} 12px \"${e}\"`;try{if(!(await document.fonts.load(o)).length)throw new Error(`No font faces loaded for ${o}`)}catch(a){if(!(await document.fonts.load(`12px \"${e}\"`)).length)throw a}await new Promise(a=>setTimeout(a,300))}else await new Promise(o=>setTimeout(o,1e3))})}function rB(e,t=400,s=!1){if(typeof document>\"u\"||!document.fonts?.check)return!1;try{return document.fonts.check(`${s?\"italic \":\"\"}${t} 12px \"${e}\"`)}catch{return!1}}var Qm=fo;function ll(e,t,s){return`{ let av = clamp(${s}, 0.0, 1.0); ${e} = vec4f((${t}) * av + ${e}.rgb * (1.0 - av), av + ${e}.a * (1.0 - av)); }`}function aA(e,t){let{q:s,sd:r}=e,{pp:o,half:a,radius:i}=t;return i===void 0?[`let ${s} = abs(${o}) - ${a};`,`let ${r} = length(max(${s}, vec2f(0.0))) + min(max(${s}.x, ${s}.y), ${Qm(0)});`]:[`let ${s} = abs(${o}) - ${a} + ${i};`,`let ${r} = length(max(${s}, vec2f(0.0))) + min(max(${s}.x, ${s}.y), ${Qm(0)}) - ${i};`]}function oB(e,t){let{bl:s,inCorner:r}=e,{blInit:o,px:a,py:i,hx:l,hy:c,stroke:d}=t;return[`let ${s} = ${o};`,`let ${r} = abs(${a}) > ${l} - ${s} && abs(${i}) > ${c} - ${s};`,`${d} = ${d} * select(${Qm(0)}, ${Qm(1)}, ${r});`]}function aB(e){return`vec4f(${e}.rgb / max(${e}.a, ${Qm(1e-4)}), ${e}.a)`}var lae=\"0123456789x%\",nB=16,Ev=64,kv=96,z0=nB*Ev,R0=kv,cae=3,iP=4,lP=\"vec3f(0.299, 0.587, 0.114)\",dae=(e,t)=>typeof e==\"number\"?e:t;function uae(e,t={}){let{getCpuValue:s}=e,r=gc(e,{label:t.label??\"GlyphStrip:atlas\",initial:{width:z0,height:R0}}),o=w_(e,{contextAttributes:{willReadFrequently:!0}}),a=()=>({family:String(s(t.familyProp??\"fontFamily\")??\"Inter\"),weight:dae(s(t.weightProp??\"fontWeight\"),500)}),i=(u,p)=>{if(r.disposed)return;let _=o.canvas()?o.context():o.resize(z0,R0);if(!_)return;_.clearRect(0,0,z0,R0),_.fillStyle=\"#ffffff\",_.font=`${p} ${Math.round(kv*.62)}px \"${u}\", ui-monospace, monospace`,_.textAlign=\"center\",_.textBaseline=\"middle\";let f=t.glyphs??lae;for(let h=0;h<f.length;h++)_.fillText(f[h],h*Ev+Ev/2,kv/2+1);r.write(o.canvas())},l=a();i(l.family,l.weight);let c=()=>{let u=a();i(u.family,u.weight)},d=S_({key:()=>{let u=a();return`${u.family}|${u.weight}`},load:()=>{let u=a();return Hh(u.family,u.weight)},onLoaded:c});return setTimeout(()=>d.ensure(),0),T_(e,{initialKey:`${l.family}|${l.weight}`,minIntervalMs:100,key:()=>{let u=a();return`${u.family}|${u.weight}`},run:()=>{c(),d.ensure()}}),r.kit}function pae(e,t,s){let{p:r,L:o,modeStr:a}=e;return a===\"alpha\"?`${t}.a > ${r}_thr`:a===\"bright\"?`dot(${s}.rgb, ${lP}) > ${r}_thr && ${t}.a > ${o(.02)}`:a===\"dark\"?`dot(${s}.rgb, ${lP}) < ${r}_thr && ${t}.a > ${o(.5)}`:a===\"red\"?`${s}.r > ${r}_thr && ${s}.r >= ${s}.g && ${s}.r >= ${s}.b && ${t}.a > ${o(.02)}`:a===\"green\"?`${s}.g > ${r}_thr && ${s}.g >= ${s}.r && ${s}.g >= ${s}.b && ${t}.a > ${o(.02)}`:`${s}.b > ${r}_thr && ${s}.b >= ${s}.r && ${s}.b >= ${s}.g && ${t}.a > ${o(.02)}`}function iB(e,t,s,r,o,a,i){let{p:l,L:c,s:d,sampleChild:u,UN:p,modeStr:_}=e;d.push(`var ${t}_cnt = ${c(0)};`),i&&d.push(`var ${t}_minX = ${c(1e9)}; var ${t}_maxX = ${c(-1e9)}; var ${t}_minY = ${c(1e9)}; var ${t}_maxY = ${c(-1e9)};`);let f=1/a,h=0;for(let g=0;g<a;g++)for(let y=0;y<a;y++){let b=`${t}_px${h}x`,x=`${t}_px${h}y`;d.push(`let ${b} = ${s} + ${o} * ${c((y+.5)*f)};`),d.push(`let ${x} = ${r} + ${o} * ${c((g+.5)*f)};`),d.push(`let ${t}_s${h} = ${u(`vec2f(${b}, ${x}) / ${l}_res`)};`),_!==\"alpha\"&&d.push(`let ${t}_u${h} = ${p}(${t}_s${h});`),d.push(`let ${t}_c${h} = ${pae(e,`${t}_s${h}`,`${t}_u${h}`)};`),d.push(`${t}_cnt = ${t}_cnt + select(${c(0)}, ${c(1)}, ${t}_c${h});`),i&&(d.push(`${t}_minX = select(${t}_minX, min(${t}_minX, ${b}), ${t}_c${h});`),d.push(`${t}_maxX = select(${t}_maxX, max(${t}_maxX, ${b}), ${t}_c${h});`),d.push(`${t}_minY = select(${t}_minY, min(${t}_minY, ${x}), ${t}_c${h});`),d.push(`${t}_maxY = select(${t}_maxY, max(${t}_maxY, ${x}), ${t}_c${h});`)),h++}d.push(`let ${t}_coverage = ${t}_cnt / ${c(a*a)};`)}function mae(e,t,s){let{p:r,L:o,s:a}=e;a.push(`var ${r}_origin = floor(${r}_fragPx / ${r}_cellPx) * ${r}_cellPx;`),a.push(`var ${r}_size = ${r}_cellPx;`);for(let i=0;i<s;i++){let l=`${r}_w${i}`;t===\"mosaic\"?(a.push(`let ${l}_cellIx = ${r}_origin / ${r}_size;`),a.push(`let ${l}_doSplit = fract(sin(dot(${l}_cellIx, vec2f(${o(127.1)}, ${o(311.7)})) + ${o(i*53.13)}) * ${o(43758.5453)}) > ${o(.5)};`)):(iB(e,l,`${r}_origin.x`,`${r}_origin.y`,`${r}_size`,cae,!1),a.push(`let ${l}_doSplit = ${l}_coverage > ${o(.02)} && ${l}_coverage < ${o(.98)};`)),a.push(`let ${l}_half = ${r}_size * ${o(.5)};`),a.push(`let ${l}_qx = step(${r}_origin.x + ${l}_half, ${r}_fragPx.x);`),a.push(`let ${l}_qy = step(${r}_origin.y + ${l}_half, ${r}_fragPx.y);`),a.push(`let ${l}_childOrigin = vec2f(${r}_origin.x + ${l}_qx * ${l}_half, ${r}_origin.y + ${l}_qy * ${l}_half);`),a.push(`${r}_origin = select(${r}_origin, ${l}_childOrigin, ${l}_doSplit);`),a.push(`${r}_size = select(${r}_size, ${l}_half, ${l}_doSplit);`)}}function _ae(e){let{p:t,L:s,s:r}=e;iB(e,`${t}_leaf`,`${t}_origin.x`,`${t}_origin.y`,`${t}_size`,iP,!0),r.push(`let ${t}_halfStep = ${t}_size / ${s(iP)} * ${s(.5)};`),r.push(`let ${t}_innerMinX = ${t}_origin.x + ${t}_boxInset;`),r.push(`let ${t}_innerMaxX = max(${t}_origin.x + ${t}_size - ${t}_boxInset, ${t}_innerMinX);`),r.push(`let ${t}_innerMinY = ${t}_origin.y + ${t}_boxInset;`),r.push(`let ${t}_innerMaxY = max(${t}_origin.y + ${t}_size - ${t}_boxInset, ${t}_innerMinY);`),r.push(`let ${t}_bMinX = clamp(${t}_leaf_minX - ${t}_halfStep, ${t}_innerMinX, ${t}_innerMaxX);`),r.push(`let ${t}_bMaxX = clamp(${t}_leaf_maxX + ${t}_halfStep, ${t}_innerMinX, ${t}_innerMaxX);`),r.push(`let ${t}_bMinY = clamp(${t}_leaf_minY - ${t}_halfStep, ${t}_innerMinY, ${t}_innerMaxY);`),r.push(`let ${t}_bMaxY = clamp(${t}_leaf_maxY + ${t}_halfStep, ${t}_innerMinY, ${t}_innerMaxY);`),r.push(`let ${t}_boxW = ${t}_bMaxX - ${t}_bMinX;`),r.push(`let ${t}_boxH = ${t}_bMaxY - ${t}_bMinY;`),r.push(`let ${t}_detected = ${t}_leaf_coverage > ${s(.02)} && ${t}_boxW > ${t}_minSize && ${t}_boxH > ${t}_minSize;`),r.push(`let ${t}_detF = select(${s(0)}, ${s(1)}, ${t}_detected);`)}function fae(e,t){let{p:s,U:r,L:o,s:a}=e;a.push(`let ${s}_center = vec2f((${s}_bMinX + ${s}_bMaxX) * ${o(.5)}, (${s}_bMinY + ${s}_bMaxY) * ${o(.5)});`),a.push(`let ${s}_halfB = vec2f(${s}_boxW * ${o(.5)}, ${s}_boxH * ${o(.5)});`);let i=t?o(0):`${s}_cornerRadiusPx`;a.push(`let ${s}_cR = max(min(min(${i}, ${s}_halfB.x), ${s}_halfB.y), ${o(0)});`),a.push(`let ${s}_pp = ${s}_fragPx - ${s}_center;`),a.push(...aA({q:`${s}_q`,sd:`${s}_sd`},{pp:`${s}_pp`,half:`${s}_halfB`,radius:`${s}_cR`})),a.push(`let ${s}_fillA = (${o(1)} - smoothstep(${o(0)}, ${s}_aa, ${s}_sd)) * ${r(\"fillColor\")}.a * ${s}_detF;`),a.push(`var ${s}_strokeA = ${o(1)} - smoothstep(${o(0)}, ${s}_aa, abs(${s}_sd) - ${s}_lineHalf);`),t&&a.push(...oB({bl:`${s}_bl`,inCorner:`${s}_inCorner`},{blInit:`min(${s}_halfB.x, ${s}_halfB.y) * ${o(.35)}`,px:`${s}_pp.x`,py:`${s}_pp.y`,hx:`${s}_halfB.x`,hy:`${s}_halfB.y`,stroke:`${s}_strokeA`})),a.push(`${s}_strokeA = ${s}_strokeA * ${r(\"strokeColor\")}.a * ${s}_detF;`),a.push(ll(`${s}_dst`,`${r(\"fillColor\")}.rgb`,`${s}_fillA`)),a.push(ll(`${s}_dst`,`${r(\"strokeColor\")}.rgb`,`${s}_strokeA`))}var D0=(e,t)=>`(${e(1)} + step(${e(10)}, ${t}) + step(${e(100)}, ${t}) + step(${e(1e3)}, ${t}) + step(${e(1e4)}, ${t}))`,L0=(e,t,s)=>{let r=`floor(${t} / pow(${e(10)}, ${s}))`;return`(${r} - ${e(10)} * floor((${r}) / ${e(10)}))`};function vae(e,t){let{p:s,U:r,L:o,s:a}=e,{labelStr:i,labelPos:l,atlasKey:c}=t;a.push(`let ${s}_textH = max(${r(\"fontSize\")} * ${s}_res.y, ${o(1)});`),a.push(`let ${s}_glyphW = ${s}_textH * ${o(Ev/kv)};`),a.push(`let ${s}_advance = ${s}_glyphW + ${s}_textH * ${r(\"letterSpacing\")};`),a.push(`let ${s}_padX = ${s}_textH * ${o(.38)};`),a.push(`let ${s}_padY = ${s}_textH * ${o(.24)};`),a.push(`let ${s}_gap = ${s}_textH * ${o(.28)};`),i===\"dimensions\"?(a.push(`let ${s}_w = clamp(floor(${s}_boxW + ${o(.5)}), ${o(1)}, ${o(99999)});`),a.push(`let ${s}_h = clamp(floor(${s}_boxH + ${o(.5)}), ${o(1)}, ${o(99999)});`),a.push(`let ${s}_dw = ${D0(o,`${s}_w`)};`),a.push(`let ${s}_dh = ${D0(o,`${s}_h`)};`),a.push(`let ${s}_total = ${s}_dw + ${o(1)} + ${s}_dh;`)):(a.push(`let ${s}_pc = clamp(floor(${s}_leaf_coverage * ${o(100)} + ${o(.5)}), ${o(0)}, ${o(100)});`),a.push(`let ${s}_dp = ${D0(o,`${s}_pc`)};`),a.push(`let ${s}_total = ${s}_dp + ${o(1)};`)),a.push(`let ${s}_labelW = ${s}_total * ${s}_advance + ${s}_padX * ${o(2)};`),a.push(`let ${s}_labelH = ${s}_textH + ${s}_padY * ${o(2)};`);let d=l===1||l===3,u=l===2||l===3;a.push(`let ${s}_inset = ${r(\"labelInset\")} > ${o(.5)};`);let p=d?`${s}_bMaxX - ${s}_labelW - ${s}_gap`:`${s}_bMinX + ${s}_gap`,_=d?`${s}_bMaxX - ${s}_labelW`:`${s}_bMinX`;a.push(`var ${s}_labelLeft = select(${_}, ${p}, ${s}_inset);`);let f=u?`${s}_bMinY + ${s}_gap`:`${s}_bMaxY - ${s}_labelH - ${s}_gap`,h=u?`${s}_bMinY - ${s}_labelH - ${s}_gap`:`${s}_bMaxY + ${s}_gap`;a.push(`var ${s}_labelTop = select(${h}, ${f}, ${s}_inset);`),a.push(`let ${s}_cellMaxX = ${s}_origin.x + ${s}_size;`),a.push(`let ${s}_cellMaxY = ${s}_origin.y + ${s}_size;`),a.push(`${s}_labelLeft = clamp(${s}_labelLeft, ${s}_origin.x, max(${s}_cellMaxX - ${s}_labelW, ${s}_origin.x));`),a.push(`${s}_labelTop = clamp(${s}_labelTop, ${s}_origin.y, max(${s}_cellMaxY - ${s}_labelH, ${s}_origin.y));`),a.push(`let ${s}_labelCenter = vec2f(${s}_labelLeft + ${s}_labelW * ${o(.5)}, ${s}_labelTop + ${s}_labelH * ${o(.5)});`),a.push(`let ${s}_pillHalf = vec2f(${s}_labelW * ${o(.5)}, ${s}_labelH * ${o(.5)});`),a.push(`let ${s}_pillR = max(min(min(${r(\"labelRadius\")} * ${s}_scaleFactor, ${s}_pillHalf.x), ${s}_pillHalf.y), ${o(0)});`),a.push(`let ${s}_pillP = ${s}_fragPx - ${s}_labelCenter;`),a.push(...aA({q:`${s}_pillQ`,sd:`${s}_pillSD`},{pp:`${s}_pillP`,half:`${s}_pillHalf`,radius:`${s}_pillR`})),a.push(`let ${s}_pillA = (${o(1)} - smoothstep(${o(0)}, ${s}_aa, ${s}_pillSD)) * ${r(\"labelBackgroundColor\")}.a * ${s}_detF;`),a.push(ll(`${s}_dst`,`${r(\"labelBackgroundColor\")}.rgb`,`${s}_pillA`)),a.push(`let ${s}_rel = ${s}_fragPx.x - ${s}_labelLeft - ${s}_padX;`),a.push(`let ${s}_slot = floor(${s}_rel / ${s}_advance);`),a.push(`let ${s}_within = fract(${s}_rel / ${s}_advance);`),a.push(`let ${s}_uInChar = ${s}_within * (${s}_advance / ${s}_glyphW);`),a.push(`let ${s}_vInChar = (${s}_fragPx.y - ${s}_labelTop - ${s}_padY) / ${s}_textH;`),i===\"dimensions\"?(a.push(`let ${s}_wDigit = ${L0(o,`${s}_w`,`${s}_dw - ${o(1)} - ${s}_slot`)};`),a.push(`let ${s}_hDigit = ${L0(o,`${s}_h`,`${s}_dh + ${s}_dw - ${s}_slot`)};`),a.push(`var ${s}_g = ${s}_hDigit;`),a.push(`${s}_g = select(${s}_g, ${o(10)}, ${s}_slot == ${s}_dw);`),a.push(`${s}_g = select(${s}_g, ${s}_wDigit, ${s}_slot < ${s}_dw);`)):a.push(`var ${s}_g = select(${o(11)}, ${L0(o,`${s}_pc`,`${s}_dp - ${o(1)} - ${s}_slot`)}, ${s}_slot < ${s}_dp);`),a.push(`let ${s}_atlasU = (${s}_g + clamp(${s}_uInChar, ${o(0)}, ${o(1)})) / ${o(nB)};`),a.push(`let ${s}_glyphCov = textureSampleLevel(tex.$.${c}, samp.$.linearClamp, vec2f(${s}_atlasU, ${s}_vInChar), 0.0).a;`),a.push(`let ${s}_inText = ${s}_rel >= ${o(0)} && ${s}_slot >= ${o(0)} && ${s}_slot < ${s}_total && ${s}_uInChar <= ${o(1)} && ${s}_vInChar >= ${o(0)} && ${s}_vInChar <= ${o(1)};`),a.push(`let ${s}_textA = ${s}_glyphCov * select(${o(0)}, ${o(1)}, ${s}_inText) * ${r(\"labelColor\")}.a * ${s}_detF;`),a.push(ll(`${s}_dst`,`${r(\"labelColor\")}.rgb`,`${s}_textA`))}var hae=e=>{let{p:t,U:s,L:r,s:o}=e;o.push(`let dsz = ${t}_ms * ${r(.16)};`),o.push(`let dSd = (abs(dp.x) + abs(dp.y)) * ${r(.7071)} - dsz;`),o.push(ll(`${t}_dst`,`${s(\"keyframeColor\")}.rgb`,`(${r(1)} - smoothstep(${r(0)}, ${t}_aa, dSd)) * ${s(\"keyframeColor\")}.a * fade * ${s(\"trail\")}`))};function gae(e){return t=>{let{p:s,U:r,L:o,s:a}=t;a.push(`let validP = select(${o(0)}, ${o(1)}, abs(ePrev.w - mta.z) < ${o(.5)}) * select(${o(0)}, ${o(1)}, ePrev.z > ${o(.5)});`),a.push(\"let stampGap = abs(e.z - ePrev.z);\"),a.push(`let contiguous = select(${o(0)}, ${o(1)}, stampGap < ${o(e*1.5)});`),a.push(`let epp = vec2f(ePrev.x * ${s}_res.x, ePrev.y * ${s}_res.y);`),a.push(`let pa = ${s}_px - epp; let ba = ep - epp;`),a.push(`let h = clamp(dot(pa, ba) / max(dot(ba, ba), ${o(1e-4)}), ${o(0)}, ${o(1)});`),a.push(\"let segD = length(pa - ba * h);\"),a.push(ll(`${s}_dst`,`${r(\"pathColor\")}.rgb`,`(${o(1)} - smoothstep(${s}_lw * ${o(.4)}, ${s}_lw * ${o(.4)} + ${s}_aa, segD)) * ${r(\"pathColor\")}.a * fade * validP * contiguous * ${r(\"trail\")} * ${o(.8)}`))}}function yae(e,t){let{p:s,U:r,L:o,s:a}=e,i=t.len*t.every;a.push(`if (${r(\"trail\")} > ${o(.001)}) {`),a.push(`var ePrev = ${t.load(`${2+t.len-1}u`)};`),a.push(`for (var j = 0u; j < ${t.len}u; j = j + 1u) {`),a.push(`let e = ${t.load(\"2u + j\")};`),a.push(`let valid = select(${o(0)}, ${o(1)}, abs(e.w - mta.z) < ${o(.5)}) * select(${o(0)}, ${o(1)}, e.z > ${o(.5)});`),a.push(\"let age = head.z - e.z;\"),a.push(`let fade = clamp(${o(1)} - age / ${o(i)}, ${o(0)}, ${o(1)}) * valid;`),a.push(`let ep = vec2f(e.x * ${s}_res.x, e.y * ${s}_res.y);`),a.push(`let dp = ${s}_px - ep;`);for(let l of t.stages)l(e);a.push(\"ePrev = e;\"),a.push(\"}\"),a.push(\"}\")}var bae=e=>{let{p:t,U:s,L:r,s:o}=e;o.push(`let gp = ${t}_px - tp;`),o.push(`let hlf = ${t}_ms * ${r(.5)};`),o.push(...aA({q:\"q\",sd:\"boxSd\"},{pp:\"gp\",half:\"vec2f(hlf)\"})),o.push(`var strokeA = ${r(1)} - smoothstep(${r(0)}, ${t}_aa, abs(boxSd) - ${t}_lw * ${r(.5)});`),o.push(...oB({bl:\"bl\",inCorner:\"inCorner\"},{blInit:`hlf * ${r(.45)}`,px:\"gp.x\",py:\"gp.y\",hx:\"hlf\",hy:\"hlf\",stroke:\"strokeA\"})),o.push(ll(`${t}_dst`,`${s(\"markerColor\")}.rgb`,`strokeA * ${s(\"markerColor\")}.a * searching`)),o.push(`let tick = hlf * ${r(.55)};`),o.push(`let chH = ${r(1)} - smoothstep(${r(0)}, ${t}_aa, max(abs(gp.y) - ${t}_lw * ${r(.5)}, abs(gp.x) - tick));`),o.push(`let chV = ${r(1)} - smoothstep(${r(0)}, ${t}_aa, max(abs(gp.x) - ${t}_lw * ${r(.5)}, abs(gp.y) - tick));`),o.push(ll(`${t}_dst`,`${s(\"markerColor\")}.rgb`,`max(chH, chV) * ${r(.55)} * ${s(\"markerColor\")}.a * searching`)),o.push(ll(`${t}_dst`,\"vec3f(1.0, 1.0, 1.0)\",`(${r(1)} - smoothstep(${t}_lw, ${t}_lw + ${t}_aa, length(gp))) * searching`))},xae=ko({accumulateInstances:()=>fB,formatFloat:()=>fo,gridPlacement:()=>dB,instanceHueShift:()=>_B,instanceVariation:()=>mB,linePlacement:()=>pB,placementField:()=>cB,radialPlacement:()=>uB,sourceRect:()=>lB}),Rm=Math.PI;function lB(e,t,s){let{p:r,L:o}=e;return[`let ${r}_cropL = ${s.left};`,`let ${r}_cropR = ${s.right};`,`let ${r}_cropT = ${s.top};`,`let ${r}_cropB = ${s.bottom};`,`let ${r}_srcCx = (${t.cx}) + (${r}_cropL - ${r}_cropR) * (${t.hw});`,`let ${r}_srcCy = (${t.cy}) + (${r}_cropT - ${r}_cropB) * (${t.hh});`,`let ${r}_srcHw = max((${t.hw}) * (1.0 - ${r}_cropL - ${r}_cropR), ${o(1e-6)});`,`let ${r}_srcHh = max((${t.hh}) * (1.0 - ${r}_cropT - ${r}_cropB), ${o(1e-6)});`,`let ${r}_srcHwSq = ${r}_srcHw * ${r}_aspect;`,`let ${r}_srcHhSq = ${r}_srcHh;`]}function cB(e,t){let{p:s,L:r}=e;return[`let ${s}_fieldCenterSq = vec2f((${t.cx}) * ${s}_aspect, ${t.cy});`,`let ${s}_fieldHwSq = max((${t.hw}) * ${s}_aspect, ${r(1e-6)});`,`let ${s}_fieldHh = max(${t.hh}, ${r(1e-6)});`]}function dB(e,t){return{requested:()=>`(${e.columns} * ${e.rows})`,body:s=>{let{p:r,L:o}=s,a=[`let ${r}_cols = ${e.columns};`,`let ${r}_rows = ${e.rows};`,`let ${r}_col = ${r}_j - ${r}_cols * floor(${r}_j / ${r}_cols);`,`let ${r}_row = floor(${r}_j / ${r}_cols);`,`let ${r}_gapXSq = ${e.gapX} * ${r}_aspect;`,`let ${r}_gapY = ${e.gapY};`,`let ${r}_fieldW = ${r}_fieldHwSq * 2.0;`,`let ${r}_fieldH = ${r}_fieldHh * 2.0;`,`let ${r}_pitchX = (${r}_fieldW - ${r}_gapXSq * (${r}_cols - 1.0)) / ${r}_cols;`,`let ${r}_pitchY = (${r}_fieldH - ${r}_gapY * (${r}_rows - 1.0)) / ${r}_rows;`,`let ${r}_periodX = ${r}_pitchX + ${r}_gapXSq;`,`let ${r}_periodY = ${r}_pitchY + ${r}_gapY;`,`${r}_cellFitInv = max(${r}_srcHwSq * 2.0 / max(${r}_pitchX, ${o(1e-5)}), ${r}_srcHhSq * 2.0 / max(${r}_pitchY, ${o(1e-5)}));`,`let ${r}_rowMod2 = ${r}_row - 2.0 * floor(${r}_row / 2.0);`,`let ${r}_staggerOff = ${r}_rowMod2 * ${e.stagger} * ${r}_periodX;`,`let ${r}_cxArg = ${r}_col * ${r}_periodX + ${r}_staggerOff + ${r}_phase * ${r}_periodX;`,`let ${r}_cxMod = ${r}_periodX * ${r}_cols;`,`let ${r}_cellX = ${r}_cxArg - ${r}_cxMod * floor(${r}_cxArg / ${r}_cxMod);`,`let ${r}_cyArg = ${r}_row * ${r}_periodY + ${r}_phase * ${r}_periodY;`,`let ${r}_cyMod = ${r}_periodY * ${r}_rows;`,`let ${r}_cellY = ${r}_cyArg - ${r}_cyMod * floor(${r}_cyArg / ${r}_cyMod);`,`${r}_pos = vec2f(${r}_fieldCenterSq.x - ${r}_fieldW * 0.5 + ${r}_pitchX * 0.5 + ${r}_cellX, ${r}_fieldCenterSq.y - ${r}_fieldH * 0.5 + ${r}_pitchY * 0.5 + ${r}_cellY);`];return(t===1||t===3)&&a.push(`${r}_flipX = 1.0 - (${r}_col - 2.0 * floor(${r}_col / 2.0)) * 2.0;`),(t===2||t===3)&&a.push(`${r}_flipY = 1.0 - (${r}_row - 2.0 * floor(${r}_row / 2.0)) * 2.0;`),a}}}function uB(e,t){return{requested:()=>t.count,body:s=>{let{p:r,L:o}=s;return[`let ${r}_cSq = ${e};`,`let ${r}_sweep = ${t.sweep} * ${o(Rm/180)};`,`let ${r}_start = ${t.startAngle} * ${o(Rm/180)};`,`let ${r}_ang = ${r}_start + ${r}_sweep * (${r}_j / ${r}_totalN) + ${r}_phase * ${r}_sweep;`,`${r}_pos = ${r}_cSq + vec2f(cos(${r}_ang), sin(${r}_ang)) * ${t.radius};`,`${r}_layoutRot = select(0.0, ${r}_ang + ${o(Rm/2)}, ${t.faceCenter} > 0.0);`]}}}function pB(e,t){return{requested:()=>t.count,body:s=>{let{p:r,L:o}=s;return[`let ${r}_cSq = ${e};`,`let ${r}_dirRad = ${t.direction} * ${o(Rm/180)};`,`let ${r}_dir = vec2f(cos(${r}_dirRad), sin(${r}_dirRad));`,`let ${r}_tArg = ${r}_j + ${r}_phase;`,`let ${r}_t = ${r}_tArg - ${r}_totalN * floor(${r}_tArg / ${r}_totalN);`,`${r}_pos = ${r}_cSq + ${r}_dir * ${t.spacing} * ${r}_t;`]}}}function mB(e,t){let{p:s,L:r}=e,o=a=>`fract(sin((${s}_hashBase + ${r(a)}) * 78.233) * 43758.5453)`;return[`let ${s}_hashBase = ${s}_j + ${s}_seed * 7.0;`,`let ${s}_h1 = ${o(.123)};`,`let ${s}_h2 = ${o(5.456)};`,`let ${s}_h3 = ${o(9.789)};`,`let ${s}_h4 = ${o(13.21)};`,`let ${s}_h5 = ${o(17.65)};`,`let ${s}_scale = max(pow(${t.scale}, ${s}_j) * (1.0 + ${t.jitterScale} * (${s}_h3 - 0.5)), ${r(1e-4)});`,`let ${s}_rot = ${s}_layoutRot + ${t.rotation} * ${s}_j + ${t.jitterRotation} * (${s}_h4 - 0.5) * ${r(Rm*2)};`,`let ${s}_instOpacity = pow(${t.opacity}, ${s}_j) * (1.0 - ${t.jitterOpacity} * ${s}_h5);`,`${s}_pos = ${s}_pos + vec2f((${s}_h1 - 0.5) * ${s}_fieldHwSq, (${s}_h2 - 0.5) * ${s}_fieldHh) * ${t.jitterPosition};`]}function _B(e,t){let{p:s,L:r}=e;return[`let ${s}_hueAngle = ${t} * ${s}_j;`,`let ${s}_cosH = cos(${s}_hueAngle);`,`let ${s}_sinH = sin(${s}_hueAngle);`,`let ${s}_kOMC = (1.0 - ${s}_cosH) * ${r(1/3)};`,`let ${s}_sOS3 = ${s}_sinH / 1.7320508075688772;`,`let ${s}_mA = ${s}_cosH + ${s}_kOMC;`,`let ${s}_mB = ${s}_kOMC - ${s}_sOS3;`,`let ${s}_mC = ${s}_kOMC + ${s}_sOS3;`,`${s}_rgb = vec3f(${s}_src.r * ${s}_mA + ${s}_src.g * ${s}_mB + ${s}_src.b * ${s}_mC, ${s}_src.r * ${s}_mC + ${s}_src.g * ${s}_mA + ${s}_src.b * ${s}_mB, ${s}_src.r * ${s}_mB + ${s}_src.g * ${s}_mC + ${s}_src.b * ${s}_mA);`]}function fB(e,t){let{p:s}=e,r=[];r.push(`let ${s}_totalN = min(max(${t.placement.requested()}, 1.0), 64.0);`),r.push(`var ${s}_accum = vec4f(0.0, 0.0, 0.0, 0.0);`),r.push(`var ${s}_cellFitInv = 1.0;`);let o=[];o.push(`let ${s}_fi = f32(${s}_i);`),o.push(t.zBack?`let ${s}_j = ${s}_totalN - 1.0 - ${s}_fi;`:`let ${s}_j = ${s}_fi;`),o.push(`var ${s}_pos = vec2f(0.0, 0.0);`),o.push(`var ${s}_layoutRot = 0.0;`),o.push(`var ${s}_flipX = 1.0;`),o.push(`var ${s}_flipY = 1.0;`),o.push(...t.placement.body(e)),o.push(...t.variation),o.push(`let ${s}_negRot = -${s}_rot;`),o.push(`let ${s}_cosA = cos(${s}_negRot);`),o.push(`let ${s}_sinA = sin(${s}_negRot);`),o.push(`let ${s}_d0 = ${s}_pix - ${s}_pos;`),o.push(`let ${s}_dr = vec2f(${s}_d0.x * ${s}_cosA - ${s}_d0.y * ${s}_sinA, ${s}_d0.x * ${s}_sinA + ${s}_d0.y * ${s}_cosA);`),o.push(`let ${s}_dl = ${s}_dr / ${s}_scale;`),o.push(`let ${s}_localU = ${s}_dl.x * ${s}_flipX * ${s}_cellFitInv / (${s}_srcHwSq * 2.0) + 0.5;`),o.push(`let ${s}_localV = ${s}_dl.y * ${s}_flipY * ${s}_cellFitInv / (${s}_srcHhSq * 2.0) + 0.5;`);let a=[];a.push(`let ${s}_sampleUV = vec2f(${s}_srcCx - ${s}_srcHw + ${s}_localU * ${s}_srcHw * 2.0, ${s}_srcCy - ${s}_srcHh + ${s}_localV * ${s}_srcHh * 2.0);`),a.push(`let ${s}_src = textureSampleLevel(tex.$.${t.texKey}, samp.$.linearClamp, ${s}_sampleUV, 0.0);`),a.push(`var ${s}_rgb = ${s}_src.rgb;`),a.push(...t.hue),a.push(`let ${s}_a = ${s}_src.a * ${s}_instOpacity;`),a.push(`let ${s}_premul = ${s}_rgb * ${s}_a;`),a.push(`${s}_accum = vec4f(${s}_premul + ${s}_accum.rgb * (1.0 - ${s}_a), ${s}_a + ${s}_accum.a * (1.0 - ${s}_a));`),o.push(`if (${s}_localU >= 0.0 && ${s}_localU <= 1.0 && ${s}_localV >= 0.0 && ${s}_localV <= 1.0) {`);for(let i of a)o.push(`  ${i}`);o.push(\"}\"),r.push(`for (var ${s}_i = 0u; ${s}_i < u32(${s}_totalN); ${s}_i++) {`);for(let i of o)r.push(`  ${i}`);return r.push(\"}\"),r}function Rr(){if(typeof window>\"u\")return!1;let e=!!(window.matchMedia&&window.matchMedia(\"(pointer: coarse)\").matches),t=Math.max(window.innerWidth||0,window.innerHeight||0);return e&&t>0&&t<=1366}function vB(){return Rr()?1.5:2}var Aae=Rr()?24:50;function Bv(e,t,s,r){let o=`${e.p}_vn${e.noiseIdx.value++}`;t.push(`let ${o}_st = ${s};`),t.push(`let ${o}_fi = floor(${o}_st);`),t.push(`let ${o}_ff = fract(${o}_st);`);for(let[a,i]of[[\"a\",\"vec2f(0.0, 0.0)\"],[\"b\",\"vec2f(1.0, 0.0)\"],[\"c\",\"vec2f(0.0, 1.0)\"],[\"d\",\"vec2f(1.0, 1.0)\"]])t.push(`var ${o}_q${a} = fract((${o}_fi + ${i}) * vec2f(0.3183099, 0.3678794)) + vec2f(0.1);`),t.push(`${o}_q${a} = ${o}_q${a} + vec2f(dot(${o}_q${a}, ${o}_q${a} + vec2f(19.19)));`),t.push(`let ${o}_h${a} = fract(${o}_q${a}.x * ${o}_q${a}.y);`);t.push(`let ${o}_u = ${o}_ff * ${o}_ff * (vec2f(3.0) - 2.0 * ${o}_ff);`),t.push(`let ${r} = mix(mix(${o}_ha, ${o}_hb, ${o}_u.x), mix(${o}_hc, ${o}_hd, ${o}_u.x), ${o}_u.y);`)}function wae(e,t,s){let{p:r,stmts:o,U:a}=e;o.push(`let ${r}_uv = ${t};`),o.push(`let ${r}_aspect = ${s};`),o.push(`let ${r}_invAspect = 1.0 / ${r}_aspect;`),o.push(`let ${r}_inradius = 0.5 * min(${r}_aspect, 1.0);`),o.push(`let ${r}_outradius = 0.5 * length(vec2f(${r}_aspect, 1.0));`),o.push(`let ${r}_spread = ${a(\"spread\")};`),o.push(`let ${r}_reach = 0.7 * pow(${r}_spread, 1.3 + 2.7 * ${r}_spread);`),o.push(`let ${r}_centerU = ${a(\"center\")};`),o.push(`let ${r}_c = vec2f(${r}_centerU.x, 1.0 - ${r}_centerU.y);`),o.push(`let ${r}_fromCenter = vec2f((${r}_uv.x - ${r}_c.x) * ${r}_aspect, ${r}_uv.y - ${r}_c.y);`),o.push(`let ${r}_radius = length(${r}_fromCenter);`),o.push(`let ${r}_lensBulge = ${a(\"lensBulge\")};`),o.push(`let ${r}_lensCircle = ${a(\"lensCircle\")};`),o.push(`var ${r}_bulgeFade = 1.0;`),o.push(`var ${r}_warped = ${r}_fromCenter;`),o.push(`let ${r}_rSafe = max(${r}_radius, 1e-5);`),o.push(`if (${r}_lensBulge != 0.0) {`),o.push(`  let ${r}_rn = ${r}_rSafe / ${r}_inradius;`),o.push(`  let ${r}_bulgeAmt = abs(${r}_lensBulge) * select(1.2, 1.4, ${r}_lensBulge > 0.0);`),o.push(`  ${r}_bulgeFade = select(1.0, 1.0 - smoothstep(1.45, 1.53, ${r}_rn * ${r}_bulgeAmt), ${r}_lensBulge > 0.0);`),o.push(`  let ${r}_mapPos = tan(min(${r}_rn * ${r}_bulgeAmt, 1.53)) / tan(${r}_bulgeAmt);`),o.push(`  let ${r}_mapNeg = atan(${r}_rn * tan(${r}_bulgeAmt)) / ${r}_bulgeAmt;`),o.push(`  let ${r}_bulgeScale = select(${r}_mapNeg, ${r}_mapPos, ${r}_lensBulge > 0.0) / ${r}_rn;`),o.push(`  ${r}_warped = ${r}_warped * ${r}_bulgeScale;`),o.push(\"}\"),o.push(`if (${r}_lensCircle > 0.0) {`),o.push(`  let ${r}_wr = length(${r}_warped);`),o.push(`  let ${r}_dir = ${r}_warped / max(${r}_wr, 1e-5);`),o.push(`  let ${r}_halfBox = vec2f(${r}_aspect, 1.0) * 0.5;`),o.push(`  let ${r}_boxOff = vec2f((${r}_c.x - 0.5) * ${r}_aspect, ${r}_c.y - 0.5);`),o.push(`  let ${r}_rBox = min((${r}_halfBox.x - sign(${r}_dir.x) * ${r}_boxOff.x) / max(abs(${r}_dir.x), 1e-4), (${r}_halfBox.y - sign(${r}_dir.y) * ${r}_boxOff.y) / max(abs(${r}_dir.y), 1e-4));`),o.push(`  let ${r}_band = ${r}_inradius * mix(0.03, 0.2, 0.5 * (${r}_lensBulge + 1.0));`),o.push(`  let ${r}_over = smoothstep(0.0, 1.0, (${r}_wr - (${r}_inradius - ${r}_band)) / ${r}_band);`),o.push(`  let ${r}_g = ${r}_wr + (${r}_rBox - ${r}_inradius) * pow(${r}_over, 14.0);`),o.push(`  ${r}_warped = ${r}_dir * mix(${r}_wr, ${r}_g, ${r}_lensCircle);`),o.push(\"}\"),o.push(`let ${r}_baseUV = vec2f(${r}_warped.x * ${r}_invAspect, ${r}_warped.y) + ${r}_c;`),o.push(`let ${r}_baseDeriv = fwidth(${r}_baseUV);`),o.push(`let ${r}_edgeAA = clamp(2.0 * max(${r}_baseDeriv.x, ${r}_baseDeriv.y), 0.001, 0.02);`),o.push(`let ${r}_frameInvAA = 1.0 / clamp(${r}_baseDeriv, vec2f(1e-5), vec2f(0.02));`),o.push(`let ${r}_grainUV = (${r}_uv - vec2f(0.5)) * (0.8 / vec2f(length(dpdx(${r}_uv)), length(dpdy(${r}_uv)))) + vec2f(0.5);`)}function Tae(e){let{p:t,stmts:s,U:r}=e;s.push(`let ${t}_angleRad = radians(${r(\"angle\")});`),s.push(`let ${t}_uniformDir = vec2f(cos(${t}_angleRad), sin(${t}_angleRad));`),s.push(`let ${t}_invInradius = 1.0 / ${t}_inradius;`),s.push(`let ${t}_maxLen = (${t}_outradius + ${t}_reach) * ${t}_invInradius;`),s.push(`let ${t}_radialLen = ${t}_radius * ${t}_invInradius;`),s.push(`let ${t}_radialDir = ${t}_fromCenter * ${t}_invInradius * min(1.0, ${t}_maxLen / max(${t}_radialLen, 1e-6));`),s.push(`let ${t}_bandProximity = smoothstep(${t}_inradius * 0.8, ${t}_inradius, ${t}_radius);`),s.push(`let ${t}_circleMaxing = ${t}_bandProximity * ${t}_lensCircle * ${t}_lensCircle * ${t}_lensCircle;`),s.push(`let ${t}_spreadDir = mix(mix(${t}_uniformDir, ${t}_radialDir, ${r(\"perspective\")}), ${t}_radialDir, ${t}_circleMaxing);`),s.push(`let ${t}_warpedAbs = abs(${t}_baseUV - vec2f(0.5));`),s.push(`let ${t}_focusCenter = ${r(\"focusCenter\")};`),s.push(`let ${t}_inner = mix(1.0, smoothstep(0.0, mix(${t}_inradius, ${t}_outradius, ${t}_focusCenter), ${t}_radius), ${t}_focusCenter);`),s.push(`let ${t}_boxDist = max(${t}_warpedAbs.x, ${t}_warpedAbs.y) * 2.0;`),s.push(`let ${t}_outer = mix(1.0, 1.0 - min(${t}_boxDist, 1.0), ${r(\"focusEdges\")});`),s.push(`var ${t}_strength = ${t}_inner * ${t}_outer * mix(1.0, mix(0.15, 0.03, max(-${t}_lensBulge, 0.0)), ${t}_circleMaxing);`),s.push(`let ${t}_outside = max(${t}_warpedAbs - vec2f(0.5), vec2f(0.0));`),s.push(`let ${t}_margin = max(${t}_reach * length(${t}_spreadDir) * (1.0 - ${t}_lensCircle), ${t}_edgeAA);`),s.push(`${t}_strength = ${t}_strength * (1.0 - smoothstep(0.0, ${t}_margin, length(${t}_outside)));`),s.push(`var ${t}_axis = ${t}_spreadDir * (${t}_reach * ${t}_strength);`),s.push(`let ${t}_noise = ${r(\"noise\")};`),s.push(`if (${t}_noise > 0.0) {`);{let o=[];Bv(e,o,`${t}_fromCenter * (${r(\"noiseFrequency\")} * 18.0) + vec2f(${r(\"noiseOffset\")} * 30.0)`,`${t}_turnNoise`);for(let a of o)s.push(`  ${a}`)}s.push(`  let ${t}_turn = (${t}_turnNoise - 0.5) * 2.0 * ${t}_noise;`),s.push(`  let ${t}_tc = cos(${t}_turn);`),s.push(`  let ${t}_ts = sin(${t}_turn);`),s.push(`  ${t}_axis = vec2f(${t}_tc * ${t}_axis.x + ${t}_ts * ${t}_axis.y, -${t}_ts * ${t}_axis.x + ${t}_tc * ${t}_axis.y);`),s.push(\"}\"),s.push(`${t}_axis = vec2f(${t}_axis.x * ${t}_invAspect, ${t}_axis.y);`),s.push(`let ${t}_grainMixer = ${r(\"grainMixer\")};`),s.push(`if (${t}_grainMixer > 0.0) {`);{let o=[];Bv(e,o,`${t}_grainUV`,`${t}_grainSeed`);for(let a of o)s.push(`  ${a}`)}s.push(`  let ${t}_jit = fract(${t}_grainSeed * vec2f(157.31, 113.57)) * 2.0 - vec2f(1.0);`),s.push(`  ${t}_axis = ${t}_axis + ${t}_jit * (0.3 * ${t}_grainMixer * length(${t}_axis));`),s.push(\"}\")}function Sae(e,t){let{p:s}=e;t.push(`let ${s}_lo = clamp(${s}_sampleUV * ${s}_frameInvAA + vec2f(0.5), vec2f(0.0), vec2f(1.0));`),t.push(`let ${s}_hi = clamp((vec2f(1.0) - ${s}_sampleUV) * ${s}_frameInvAA + vec2f(0.5), vec2f(0.0), vec2f(1.0));`),t.push(`let ${s}_frame = ${s}_lo.x * ${s}_hi.x * ${s}_lo.y * ${s}_hi.y;`)}function Pae(e,t){let{p:s,stmts:r,U:o,L:a}=e,i=Math.PI;r.push(`let ${s}_countF = clamp(floor(${o(\"count\")}), 2.0, ${a(Aae)});`),r.push(`let ${s}_hueBase = ${o(\"dispersionColor\")} + 0.5;`),r.push(`let ${s}_bias = ${o(\"bias\")};`),r.push(`let ${s}_biasPower = 1.0 + 2.0 * abs(${s}_bias);`),r.push(`let ${s}_biasNeg = ${s}_bias < 0.0;`),r.push(`let ${s}_dispShift = ${o(\"dispersionShift\")};`),r.push(`let ${s}_icMask = 1.0 - smoothstep(0.5 * ${s}_inradius, 1.1 * ${s}_inradius, ${s}_radius);`),r.push(`let ${s}_dispAmt = ${o(\"dispersion\")} * mix(clamp(1.0 + ${s}_dispShift, 0.0, 1.0), clamp(1.0 - ${s}_dispShift, 0.0, 1.0), ${s}_icMask);`),r.push(`let ${s}_dispPower = pow(${s}_dispAmt, 0.8);`),r.push(`let ${s}_warpedRadius = length(${s}_warped);`),r.push(`let ${s}_swirlAngle = ${o(\"swirl\")} * ${a(.4*i)} * ${s}_strength * ${s}_spread * min(1.0, ${s}_inradius / max(${s}_warpedRadius, 1e-4));`),r.push(`let ${s}_texel = max((${s}_baseDeriv.x + ${s}_baseDeriv.y) * 0.5, 1e-6);`),r.push(`let ${s}_fanPx = (2.0 * length(${s}_axis) + abs(${s}_swirlAngle) * ${s}_warpedRadius) / ${s}_texel;`),r.push(`let ${s}_tapsF = clamp(ceil(${s}_fanPx * ${s}_biasPower) + 1.0, 2.0, ${s}_countF);`),r.push(`let ${s}_invCount = 1.0 / ${s}_tapsF;`),r.push(`let ${s}_invSpan = 1.0 / max(${s}_tapsF - 1.0, 1.0);`),r.push(`var ${s}_colorSum = vec3f(0.0);`),r.push(`var ${s}_weightSum = vec3f(0.0);`),r.push(`var ${s}_coverSum = 0.0;`);let l=[];l.push(`let ${s}_layer = f32(${s}_i);`),l.push(`let ${s}_hue = ${s}_hueBase + ${s}_layer * ${s}_invCount;`),l.push(`let ${s}_t0 = ${s}_layer * ${s}_invSpan;`),l.push(`let ${s}_curved = pow(select(${s}_t0, 1.0 - ${s}_t0, ${s}_biasNeg), ${s}_biasPower);`),l.push(`let ${s}_spreadT = select(${s}_curved, 1.0 - ${s}_curved, ${s}_biasNeg);`),l.push(`let ${s}_fanPos = 1.0 - 2.0 * ${s}_spreadT;`),l.push(`let ${s}_tap0 = ${s}_baseUV + ${s}_axis * ${s}_fanPos - ${s}_c;`),l.push(`let ${s}_sa = ${s}_swirlAngle * ${s}_fanPos;`),l.push(`let ${s}_sc = cos(${s}_sa);`),l.push(`let ${s}_ss = sin(${s}_sa);`),l.push(`let ${s}_tx = ${s}_tap0.x * ${s}_aspect;`),l.push(`let ${s}_sampleUV = vec2f((${s}_sc * ${s}_tx - ${s}_ss * ${s}_tap0.y) * ${s}_invAspect, ${s}_ss * ${s}_tx + ${s}_sc * ${s}_tap0.y) + ${s}_c;`),Sae(e,l),l.push(`let ${s}_tapC = textureSampleLevel(tex.$.${t}, samp.$.linearClamp, ${s}_sampleUV, 0.0);`),l.push(`let ${s}_cover = ${s}_tapC.a * ${s}_frame;`),l.push(`let ${s}_overWhite = vec3f(1.0 - ${s}_cover) + ${s}_tapC.rgb * ${s}_frame;`),l.push(`let ${s}_hraw = ${s}_hue * 6.0 + vec3f(0.0, 4.0, 2.0);`),l.push(`let ${s}_hmod = ${s}_hraw - 6.0 * floor(${s}_hraw / 6.0);`),l.push(`let ${s}_hclamped = clamp(abs(${s}_hmod - vec3f(3.0)) - vec3f(1.0), vec3f(0.0), vec3f(1.0));`),l.push(`let ${s}_hrgb = ${s}_hclamped * ${s}_hclamped * (vec3f(3.0) - 2.0 * ${s}_hclamped);`),l.push(`let ${s}_weight = vec3f(1.0) - ${s}_dispPower * ${s}_hrgb;`),l.push(`${s}_colorSum = ${s}_colorSum + ${s}_overWhite * ${s}_weight;`),l.push(`${s}_weightSum = ${s}_weightSum + ${s}_weight;`),l.push(`${s}_coverSum = ${s}_coverSum + ${s}_cover;`),r.push(`for (var ${s}_i = 0u; ${s}_i < u32(${s}_tapsF); ${s}_i++) {`);for(let c of l)r.push(`  ${c}`);r.push(\"}\"),r.push(`let ${s}_color = ${s}_colorSum / max(${s}_weightSum, vec3f(1e-4));`),r.push(`let ${s}_coverAvg = ${s}_coverSum * ${s}_invCount;`),r.push(`let ${s}_ground = min(${s}_color.r, min(${s}_color.g, ${s}_color.b));`),r.push(`let ${s}_alpha = max(${s}_coverAvg, 1.0 - ${s}_ground);`),r.push(`let ${s}_premul = max(${s}_color - vec3f(1.0 - ${s}_alpha), vec3f(0.0));`),r.push(`var ${s}_out = vec4f(${s}_premul, ${s}_alpha) * ${s}_bulgeFade;`)}function Cae(e){let{p:t,stmts:s,L:r}=e;s.push(`let ${t}_grainOverlay = ${e.U(\"grainOverlay\")};`),s.push(`if (${t}_grainOverlay > 0.0) {`);{let o=[],a=r(Math.cos(1)),i=r(Math.sin(1)),l=r(Math.cos(2)),c=r(Math.sin(2));o.push(`let ${t}_gr1 = vec2f(${a} * ${t}_grainUV.x - ${i} * ${t}_grainUV.y, ${i} * ${t}_grainUV.x + ${a} * ${t}_grainUV.y) + vec2f(3.0);`),o.push(`let ${t}_gr2 = vec2f(${l} * ${t}_grainUV.x - ${c} * ${t}_grainUV.y, ${c} * ${t}_grainUV.x + ${l} * ${t}_grainUV.y) + vec2f(-1.0);`),Bv(e,o,`${t}_gr1`,`${t}_gn1`),Bv(e,o,`${t}_gr2`,`${t}_gn2`),o.push(`let ${t}_grain = pow(mix(${t}_gn1, ${t}_gn2, 0.5), 1.3);`),o.push(`let ${t}_grainV = ${t}_grain * 2.0 - 1.0;`),o.push(`let ${t}_grainStrength = pow(${t}_grainOverlay * abs(${t}_grainV), 0.8) * ${t}_out.a;`),o.push(`${t}_out = vec4f(mix(${t}_out.rgb, vec3f(step(0.0, ${t}_grainV)) * ${t}_out.a, 0.35 * ${t}_grainStrength), ${t}_out.a);`);for(let d of o)s.push(`  ${d}`)}s.push(\"}\")}function nA(e,t){let{childNode:s,convertToTexture:r}=e;if(!s||!r)return null;let o=r(s),a=null;return{childTexture:o,bindInputs:i=>{let l=i(o.key);l&&(a=t(l.texture))},bound:()=>a,ready:()=>a!==null}}var Mae=e=>typeof e==\"number\"?[e,e]:[e[0],e[1]];function hB(e,t){let{gpu:s,registerComputeTexture:r,onCleanup:o,getCpuValue:a}=e,i=s?.root;if(!i)return null;let{format:l}=t,c=k=>{let D=i.createTexture({size:Mae(k),format:l}).$usage(\"storage\",\"sampled\");return{texture:D,destroy:()=>D.destroy()}},d=[],u=k=>(d.push(k),k),p=u(c(t.size)),_=u(c(t.size)),f=u(c(t.size)),h=Object.keys(t.extraSlots??{}),g={},y={};for(let k of h)g[k]=u(c(t.extraSlots[k])).texture,y[k]=u(c(t.extraSlots[k])).texture;let b={};for(let[k,D]of Object.entries(t.textures??{}))b[k]=u(c(D)).texture;o(()=>{for(let k of d)k.destroy()});let x=r(f.texture),P=ap({state:p.texture,extra:g},{state:_.texture,extra:y}),C=null,E,R=nA(e,k=>{let D={childTexture:k,display:f.texture,textures:b};return E=t.staticGroups?t.staticGroups(D):void 0,C=P.groups((O,F)=>t.bindGroups(D,O,F)),!0});if(!R)return null;let U=t.maxDeltaTime??.05,L=0;return{childTexture:R.childTexture,display:x,pair:P,bindInputs:R.bindInputs,tick:(k,D)=>{if(!R.ready()||!C)return null;let O=k?.deltaTime??.016,F=t.speedProp?a(t.speedProp):void 0,q=typeof F==\"number\"&&Number.isFinite(F)?F:1,Y=Math.min(O,U)*q;L+=Y;let V=D({groups:C(),shared:E,dt:Y,localTime:L,rawDeltaTime:O});return V&&P.swap(),V}}}var cP=64,U0=12,O0=8,O1=14,Eae=O1+1,zv=\"rgba32float\",tl=96,G0=Po,iA=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,trackersF:n,agility:n,threshold:n,variance:n,lifespan:n}),\"TrackParams\"),xm=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({src:{texture:Zt(n)},grid:{storageTexture:zt(zv,\"write-only\")},params:{uniform:iA}}),\"featureLayout\"),Go=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({src:{texture:Zt(n)},featGrid:{texture:Zt(n),sampleType:\"unfilterable-float\"},prev:{texture:Zt(n),sampleType:\"unfilterable-float\"},next:{storageTexture:zt(zv,\"write-only\")},present:{storageTexture:zt(zv,\"write-only\")},params:{uniform:iA}}),\"trackLayout\"),ln=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return Re(__tsover_mul(ae(t),43758.5453123))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"}],body:[0,[[10,[6,\"std.fract\",[[1,[6,\"std.sin\",[\"x\"]],\"*\",[5,\"43758.5453123\"]]]]]]]},externals:{\"std.fract\":()=>Re,\"std.sin\":()=>ae}})&&e.f)({})),\"trackHash\");function gB(e){return w.fn([S],n)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=(s=>{\"use gpu\";let r=B(s.w,1e-4),o=G(__tsover_div(__tsover_add(__tsover_add(__tsover_mul(s.x,.299),__tsover_mul(s.y,.587)),__tsover_mul(s.z,.114)),r),0,1),a=n(0);return e===\"alpha\"?a=s.w:e===\"dark\"?a=__tsover_mul(__tsover_sub(1,o),N(n(0),n(1),s.w>.5)):e===\"red\"?a=__tsover_mul(__tsover_mul(__tsover_mul(G(__tsover_div(s.x,r),0,1),N(n(0),n(1),s.x>=s.y)),N(n(0),n(1),s.x>=s.z)),N(n(0),n(1),s.w>.02)):e===\"green\"?a=__tsover_mul(__tsover_mul(__tsover_mul(G(__tsover_div(s.y,r),0,1),N(n(0),n(1),s.y>=s.x)),N(n(0),n(1),s.y>=s.z)),N(n(0),n(1),s.w>.02)):e===\"blue\"?a=__tsover_mul(__tsover_mul(__tsover_mul(G(__tsover_div(s.z,r),0,1),N(n(0),n(1),s.z>=s.x)),N(n(0),n(1),s.z>=s.y)),N(n(0),n(1),s.w>.02)):a=__tsover_mul(o,N(n(0),n(1),s.w>.02)),a}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"c\"}],body:[0,[[13,\"a\",[6,\"std.max\",[[7,\"c\",\"w\"],[5,\"0.0001\"]]]],[13,\"lumaU\",[6,\"std.clamp\",[[1,[1,[1,[1,[7,\"c\",\"x\"],\"*\",[5,\"0.299\"]],\"+\",[1,[7,\"c\",\"y\"],\"*\",[5,\"0.587\"]]],\"+\",[1,[7,\"c\",\"z\"],\"*\",[5,\"0.114\"]]],\"/\",\"a\"],[5,\"0\"],[5,\"1\"]]]],[12,\"score\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"mode\",\"===\",[103,\"alpha\"]],[2,\"score\",\"=\",[7,\"c\",\"w\"]],[11,[1,\"mode\",\"===\",[103,\"dark\"]],[2,\"score\",\"=\",[1,[1,[5,\"1\"],\"-\",\"lumaU\"],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"w\"],\">\",[5,\"0.5\"]]]]]],[11,[1,\"mode\",\"===\",[103,\"red\"]],[2,\"score\",\"=\",[1,[1,[1,[6,\"std.clamp\",[[1,[7,\"c\",\"x\"],\"/\",\"a\"],[5,\"0\"],[5,\"1\"]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"x\"],\">=\",[7,\"c\",\"y\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"x\"],\">=\",[7,\"c\",\"z\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"w\"],\">\",[5,\"0.02\"]]]]]],[11,[1,\"mode\",\"===\",[103,\"green\"]],[2,\"score\",\"=\",[1,[1,[1,[6,\"std.clamp\",[[1,[7,\"c\",\"y\"],\"/\",\"a\"],[5,\"0\"],[5,\"1\"]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"y\"],\">=\",[7,\"c\",\"x\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"y\"],\">=\",[7,\"c\",\"z\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"w\"],\">\",[5,\"0.02\"]]]]]],[11,[1,\"mode\",\"===\",[103,\"blue\"]],[2,\"score\",\"=\",[1,[1,[1,[6,\"std.clamp\",[[1,[7,\"c\",\"z\"],\"/\",\"a\"],[5,\"0\"],[5,\"1\"]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"z\"],\">=\",[7,\"c\",\"x\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"z\"],\">=\",[7,\"c\",\"y\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"w\"],\">\",[5,\"0.02\"]]]]]],[2,\"score\",\"=\",[1,\"lumaU\",\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"c\",\"w\"],\">\",[5,\"0.02\"]]]]]]]]]]],[10,\"score\"]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"d.f32\":()=>n,mode:()=>e,\"std.select\":()=>N}})&&t.f)({})).$name(`featureScore_${e}`)}function kae(e){return w.fn([M,M])((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r)=>{\"use gpu\";let o=Ti(xm.$.src),a=n(o.x),i=n(o.y),l=n(tl),c=__tsover_div(__tsover_add(n(s),.5),l),d=__tsover_div(__tsover_add(n(r),.5),l),u=__tsover_div(.25,l),p=n(0);for(let _=0;_<2;_++)for(let f=0;f<2;f++){let h=__tsover_add(c,__tsover_mul(__tsover_mul(__tsover_sub(n(f),.5),2),u)),g=__tsover_add(d,__tsover_mul(__tsover_mul(__tsover_sub(n(_),.5),2),u)),y=M(G(__tsover_mul(h,a),n(0),__tsover_sub(a,1))),b=M(G(__tsover_mul(g,i),n(0),__tsover_sub(i,1)));p=B(p,e(Ye(xm.$.src,fe(y,b),0)))}lt(xm.$.grid,fe(s,r),S(p,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gx\"},{type:\"i\",name:\"gy\"}],body:[0,[[13,\"srcDims\",[6,\"std.textureDimensions\",[[7,[7,\"featureLayout\",\"$\"],\"src\"]]]],[13,\"srcW\",[6,\"d.f32\",[[7,\"srcDims\",\"x\"]]]],[13,\"srcH\",[6,\"d.f32\",[[7,\"srcDims\",\"y\"]]]],[13,\"g\",[6,\"d.f32\",[\"FEAT_GRID\"]]],[13,\"cu\",[1,[1,[6,\"d.f32\",[\"gx\"]],\"+\",[5,\"0.5\"]],\"/\",\"g\"]],[13,\"cv\",[1,[1,[6,\"d.f32\",[\"gy\"]],\"+\",[5,\"0.5\"]],\"/\",\"g\"]],[13,\"q\",[1,[5,\"0.25\"],\"/\",\"g\"]],[12,\"score\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"sy\",[5,\"0\"]],[1,\"sy\",\"<\",[5,\"2\"]],[102,\"++\",\"sy\"],[0,[[14,[12,\"sx\",[5,\"0\"]],[1,\"sx\",\"<\",[5,\"2\"]],[102,\"++\",\"sx\"],[0,[[13,\"u\",[1,\"cu\",\"+\",[1,[1,[1,[6,\"d.f32\",[\"sx\"]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",\"q\"]]],[13,\"v\",[1,\"cv\",\"+\",[1,[1,[1,[6,\"d.f32\",[\"sy\"]],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",\"q\"]]],[13,\"tx\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"u\",\"*\",\"srcW\"],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcW\",\"-\",[5,\"1\"]]]]]]],[13,\"ty\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"v\",\"*\",\"srcH\"],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcH\",\"-\",[5,\"1\"]]]]]]],[2,\"score\",\"=\",[6,\"std.max\",[\"score\",[6,\"scoreFn\",[[6,\"std.textureLoad\",[[7,[7,\"featureLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"tx\",\"ty\"]],[5,\"0\"]]]]]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"featureLayout\",\"$\"],\"grid\"],[6,\"d.vec2u\",[\"gx\",\"gy\"]],[6,\"d.vec4f\",[\"score\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{\"std.textureDimensions\":()=>Ti,featureLayout:()=>xm,\"d.f32\":()=>n,FEAT_GRID:()=>tl,\"d.u32\":()=>M,\"std.clamp\":()=>G,\"std.max\":()=>B,scoreFn:()=>e,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.textureStore\":()=>lt,\"d.vec4f\":()=>S}})&&t.f)({})).$name(\"featureGridScan\")}function Bae(e,t){let s=t??gB(e);return w.fn([M])((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=(o=>{\"use gpu\";let a=Go.$.params,i=n(o),l=Ye(Go.$.prev,fe(M(0),o),0),c=Ye(Go.$.prev,fe(M(1),o),0),d=l.x,u=l.y,p=l.z,_=__tsover_sub(l.w,1),f=c.x,h=c.z,g=c.w;l.w<.5&&(d=__tsover_add(.15,__tsover_mul(.7,ln(__tsover_add(__tsover_mul(i,7.31),1.3)))),u=__tsover_add(.15,__tsover_mul(.7,ln(__tsover_add(__tsover_mul(i,11.93),4.7)))),p=n(0),_=n(0),f=n(0),h=n(1)),p=__tsover_add(p,1);let y=B(a.threshold,.02),b=B(__tsover_sub(1,__tsover_mul(a.variance,ln(__tsover_add(__tsover_add(__tsover_mul(i,6.13),__tsover_mul(h,.37)),2.9)))),y),x=Ti(Go.$.src),P=n(x.x),C=n(x.y),E=__tsover_add(.035,__tsover_mul(.11,a.agility)),R=n(0),U=n(0),L=n(0);for(let ke=-3;ke<=3;ke++)for(let Me=-3;Me<=3;Me++){let we=__tsover_mul(__tsover_div(n(Me),3),E),Ve=__tsover_mul(__tsover_div(n(ke),3),E),qe=G(__tsover_add(d,we),.02,.98),st=G(__tsover_add(u,Ve),.02,.98),pt=M(G(__tsover_mul(qe,P),n(0),__tsover_sub(P,1))),Ze=M(G(__tsover_mul(st,C),n(0),__tsover_sub(C,1))),nt=s(Ye(Go.$.src,fe(pt,Ze),0)),ht=N(n(0),n(1),nt>y),yt=__tsover_sub(nt,b),St=__tsover_mul(Tt(__tsover_mul(__tsover_mul(yt,yt),-24)),ht),Mt=__tsover_div(Ue(__tsover_add(__tsover_mul(we,we),__tsover_mul(Ve,Ve))),B(E,.001)),Rt=__tsover_mul(St,__tsover_sub(1,__tsover_mul(.3,Mt)));R=__tsover_add(R,Rt),U=__tsover_add(U,__tsover_mul(qe,Rt)),L=__tsover_add(L,__tsover_mul(st,Rt))}let k=R>.8,D=d,O=u;if(k&&(D=__tsover_div(U,R),O=__tsover_div(L,R)),f=N(__tsover_add(f,1),n(0),k),!k){let ke=n(tl),Me=n(0),we=d,Ve=u;for(let qe=0;qe<tl;qe++)for(let st=0;st<tl;st++){let pt=Ye(Go.$.featGrid,fe(M(st),M(qe)),0).x,Ze=N(n(0),n(1),pt>y),nt=__tsover_sub(pt,b),ht=__tsover_mul(Tt(__tsover_mul(__tsover_mul(nt,nt),-14)),Ze),yt=__tsover_div(__tsover_add(n(st),.5),ke),St=__tsover_div(__tsover_add(n(qe),.5),ke),Mt=__tsover_sub(yt,d),Rt=__tsover_sub(St,u),Kt=__tsover_add(.6,__tsover_mul(.8,ln(__tsover_add(__tsover_add(__tsover_mul(i,3.17),__tsover_mul(n(st),13.71)),__tsover_mul(n(qe),29.37))))),Wt=__tsover_div(__tsover_mul(ht,Kt),__tsover_add(1,__tsover_mul(5,__tsover_add(__tsover_mul(Mt,Mt),__tsover_mul(Rt,Rt)))));Wt>Me&&(Me=Wt,we=yt,Ve=St)}if(Me>.02)D=G(__tsover_add(we,__tsover_div(__tsover_sub(ln(__tsover_add(__tsover_mul(i,5.77),__tsover_mul(h,2.13))),.5),ke)),.02,.98),O=G(__tsover_add(Ve,__tsover_div(__tsover_sub(ln(__tsover_add(__tsover_mul(i,8.31),__tsover_mul(h,4.97))),.5),ke)),.02,.98);else{let qe=__tsover_add(__tsover_mul(ln(__tsover_add(__tsover_mul(i,13.77),__tsover_mul(h,3.19))),G0),__tsover_mul(ae(__tsover_add(__tsover_mul(p,.02),i)),1.4));D=G(__tsover_add(d,__tsover_mul(pe(qe),.08)),.03,.97),O=G(__tsover_add(u,__tsover_mul(ae(qe),.08)),.03,.97)}}let F=__tsover_mul(a.dt,__tsover_add(.15,__tsover_mul(1.4,a.agility))),q=__tsover_sub(D,d),Y=__tsover_sub(O,u),V=Ue(__tsover_add(__tsover_mul(q,q),__tsover_mul(Y,Y))),X=ye(n(1),__tsover_div(F,B(V,1e-5)));d=__tsover_add(d,__tsover_mul(q,X)),u=__tsover_add(u,__tsover_mul(Y,X));let Q=n(0),te=j(o);for(let ke=0;ke<te;ke++){let Me=n(ke),we=Ye(Go.$.prev,fe(M(0),M(ke)),0),Ve=__tsover_sub(we.x,d),qe=__tsover_sub(we.y,u),st=N(n(0),n(1),Ue(__tsover_add(__tsover_mul(Ve,Ve),__tsover_mul(qe,qe)))<.022);Q=B(Q,__tsover_mul(__tsover_mul(st,we.w),N(n(0),n(1),Me<a.trackersF)))}if(g=N(n(0),__tsover_add(g,1),Q>.5),g>30){let ke=__tsover_mul(ln(__tsover_add(__tsover_add(__tsover_mul(i,9.13),__tsover_mul(h,5.77)),2.3)),G0),Me=__tsover_add(.05,__tsover_mul(.08,ln(__tsover_add(__tsover_mul(i,4.71),__tsover_mul(h,8.11)))));d=G(__tsover_add(d,__tsover_mul(pe(ke),Me)),.03,.97),u=G(__tsover_add(u,__tsover_mul(ae(ke),Me)),.03,.97),h=__tsover_add(h,1),_=p,f=n(0),g=n(0)}let J=__tsover_mul(__tsover_mul(a.lifespan,60),__tsover_add(.7,__tsover_mul(.6,ln(__tsover_add(__tsover_mul(i,4.77),__tsover_mul(h,1.31)))))),oe=__tsover_mul(N(n(0),n(1),__tsover_sub(p,_)>J),N(n(0),n(1),a.lifespan>.01)),le=N(n(0),n(1),f>90);__tsover_add(oe,le)>.5&&(d=__tsover_add(.1,__tsover_mul(.8,ln(__tsover_add(__tsover_add(__tsover_mul(i,7.31),__tsover_mul(h,13.7)),__tsover_mul(p,.013))))),u=__tsover_add(.1,__tsover_mul(.8,ln(__tsover_add(__tsover_add(__tsover_mul(i,11.93),__tsover_mul(h,17.3)),__tsover_mul(p,.019))))),h=__tsover_add(h,1),_=p,f=n(0),g=n(0));let se=__tsover_mod(ie(__tsover_div(p,n(O0))),n(U0)),Te=N(n(0),n(1),__tsover_mod(p,n(O0))<.5),de=d,xe=u,Ae=d,De=u;for(let ke=0;ke<U0;ke++){let Me=n(ke),we=Ye(Go.$.prev,fe(M(__tsover_add(2,ke)),o),0),Ve=N(n(0),n(1),re(__tsover_sub(Me,se))<.5),qe=__tsover_mul(Ve,Te);we=K(we,S(d,u,p,h),qe),lt(Go.$.next,fe(M(__tsover_add(2,ke)),o),we),lt(Go.$.present,fe(M(__tsover_add(2,ke)),o),we);let st=__tsover_mul(N(n(0),n(1),re(__tsover_sub(we.w,h))<.5),N(n(0),n(1),we.z>.5));de=ye(de,K(d,we.x,st)),xe=ye(xe,K(u,we.y,st)),Ae=B(Ae,K(d,we.x,st)),De=B(De,K(u,we.y,st))}let Ee=S(de,xe,Ae,De);lt(Go.$.next,fe(M(O1),o),Ee),lt(Go.$.present,fe(M(O1),o),Ee);let ze=S(d,u,p,__tsover_add(_,1)),Ie=S(f,R,h,g);lt(Go.$.next,fe(M(0),o),ze),lt(Go.$.present,fe(M(0),o),ze),lt(Go.$.next,fe(M(1),o),Ie),lt(Go.$.present,fe(M(1),o),Ie)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ti\"}],body:[0,[[13,\"P\",[7,[7,\"trackLayout\",\"$\"],\"params\"]],[13,\"iF\",[6,\"d.f32\",[\"ti\"]]],[13,\"head\",[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"0\"]]],\"ti\"]],[5,\"0\"]]]],[13,\"meta\",[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"1\"]]],\"ti\"]],[5,\"0\"]]]],[12,\"posX\",[7,\"head\",\"x\"]],[12,\"posY\",[7,\"head\",\"y\"]],[12,\"frame\",[7,\"head\",\"z\"]],[12,\"genStart\",[1,[7,\"head\",\"w\"],\"-\",[5,\"1\"]]],[12,\"missStreak\",[7,\"meta\",\"x\"]],[12,\"gen\",[7,\"meta\",\"z\"]],[12,\"crowdStreak\",[7,\"meta\",\"w\"]],[11,[1,[7,\"head\",\"w\"],\"<\",[5,\"0.5\"]],[0,[[2,\"posX\",\"=\",[1,[5,\"0.15\"],\"+\",[1,[5,\"0.7\"],\"*\",[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"7.31\"]],\"+\",[5,\"1.3\"]]]]]]],[2,\"posY\",\"=\",[1,[5,\"0.15\"],\"+\",[1,[5,\"0.7\"],\"*\",[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"11.93\"]],\"+\",[5,\"4.7\"]]]]]]],[2,\"frame\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]],[2,\"genStart\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]],[2,\"missStreak\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]],[2,\"gen\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]]]]],[2,\"frame\",\"=\",[1,\"frame\",\"+\",[5,\"1\"]]],[13,\"minFeat\",[6,\"std.max\",[[7,\"P\",\"threshold\"],[5,\"0.02\"]]]],[13,\"Lpref\",[6,\"std.max\",[[1,[5,\"1\"],\"-\",[1,[7,\"P\",\"variance\"],\"*\",[6,\"trackHash\",[[1,[1,[1,\"iF\",\"*\",[5,\"6.13\"]],\"+\",[1,\"gen\",\"*\",[5,\"0.37\"]]],\"+\",[5,\"2.9\"]]]]]],\"minFeat\"]]],[13,\"srcDims\",[6,\"std.textureDimensions\",[[7,[7,\"trackLayout\",\"$\"],\"src\"]]]],[13,\"srcW\",[6,\"d.f32\",[[7,\"srcDims\",\"x\"]]]],[13,\"srcH\",[6,\"d.f32\",[[7,\"srcDims\",\"y\"]]]],[13,\"radius\",[1,[5,\"0.035\"],\"+\",[1,[5,\"0.11\"],\"*\",[7,\"P\",\"agility\"]]]],[12,\"sumW\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"sumX\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"sumY\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"dy\",[4,\"-\",[5,\"3\"]]],[1,\"dy\",\"<=\",[5,\"3\"]],[102,\"++\",\"dy\"],[0,[[14,[12,\"dx\",[4,\"-\",[5,\"3\"]]],[1,\"dx\",\"<=\",[5,\"3\"]],[102,\"++\",\"dx\"],[0,[[13,\"ox\",[1,[1,[6,\"d.f32\",[\"dx\"]],\"/\",[5,\"3\"]],\"*\",\"radius\"]],[13,\"oy\",[1,[1,[6,\"d.f32\",[\"dy\"]],\"/\",[5,\"3\"]],\"*\",\"radius\"]],[13,\"cx01\",[6,\"std.clamp\",[[1,\"posX\",\"+\",\"ox\"],[5,\"0.02\"],[5,\"0.98\"]]]],[13,\"cy01\",[6,\"std.clamp\",[[1,\"posY\",\"+\",\"oy\"],[5,\"0.02\"],[5,\"0.98\"]]]],[13,\"tx\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cx01\",\"*\",\"srcW\"],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcW\",\"-\",[5,\"1\"]]]]]]],[13,\"ty\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cy01\",\"*\",\"srcH\"],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcH\",\"-\",[5,\"1\"]]]]]]],[13,\"s\",[6,\"score\",[[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"tx\",\"ty\"]],[5,\"0\"]]]]]],[13,\"gate\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"s\",\">\",\"minFeat\"]]]],[13,\"dBand\",[1,\"s\",\"-\",\"Lpref\"]],[13,\"aff\",[1,[6,\"std.exp\",[[1,[1,\"dBand\",\"*\",\"dBand\"],\"*\",[4,\"-\",[5,\"24\"]]]]],\"*\",\"gate\"]],[13,\"off\",[1,[6,\"std.sqrt\",[[1,[1,\"ox\",\"*\",\"ox\"],\"+\",[1,\"oy\",\"*\",\"oy\"]]]],\"/\",[6,\"std.max\",[\"radius\",[5,\"0.001\"]]]]],[13,\"w\",[1,\"aff\",\"*\",[1,[5,\"1\"],\"-\",[1,[5,\"0.3\"],\"*\",\"off\"]]]],[2,\"sumW\",\"=\",[1,\"sumW\",\"+\",\"w\"]],[2,\"sumX\",\"=\",[1,\"sumX\",\"+\",[1,\"cx01\",\"*\",\"w\"]]],[2,\"sumY\",\"=\",[1,\"sumY\",\"+\",[1,\"cy01\",\"*\",\"w\"]]]]]]]]],[13,\"locked\",[1,\"sumW\",\">\",[5,\"0.8\"]]],[12,\"bestX\",\"posX\"],[12,\"bestY\",\"posY\"],[11,\"locked\",[0,[[2,\"bestX\",\"=\",[1,\"sumX\",\"/\",\"sumW\"]],[2,\"bestY\",\"=\",[1,\"sumY\",\"/\",\"sumW\"]]]]],[2,\"missStreak\",\"=\",[6,\"std.select\",[[1,\"missStreak\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"locked\"]]],[11,[4,\"!\",\"locked\"],[0,[[13,\"g\",[6,\"d.f32\",[\"FEAT_GRID\"]]],[12,\"bestW\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"tgtX\",\"posX\"],[12,\"tgtY\",\"posY\"],[14,[12,\"gy\",[5,\"0\"]],[1,\"gy\",\"<\",\"FEAT_GRID\"],[102,\"++\",\"gy\"],[0,[[14,[12,\"gx\",[5,\"0\"]],[1,\"gx\",\"<\",\"FEAT_GRID\"],[102,\"++\",\"gx\"],[0,[[13,\"cs\",[7,[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"featGrid\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"gx\"]],[6,\"d.u32\",[\"gy\"]]]],[5,\"0\"]]],\"x\"]],[13,\"cGate\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"cs\",\">\",\"minFeat\"]]]],[13,\"dB\",[1,\"cs\",\"-\",\"Lpref\"]],[13,\"aff\",[1,[6,\"std.exp\",[[1,[1,\"dB\",\"*\",\"dB\"],\"*\",[4,\"-\",[5,\"14\"]]]]],\"*\",\"cGate\"]],[13,\"cx\",[1,[1,[6,\"d.f32\",[\"gx\"]],\"+\",[5,\"0.5\"]],\"/\",\"g\"]],[13,\"cy\",[1,[1,[6,\"d.f32\",[\"gy\"]],\"+\",[5,\"0.5\"]],\"/\",\"g\"]],[13,\"ddx\",[1,\"cx\",\"-\",\"posX\"]],[13,\"ddy\",[1,\"cy\",\"-\",\"posY\"]],[13,\"pref\",[1,[5,\"0.6\"],\"+\",[1,[5,\"0.8\"],\"*\",[6,\"trackHash\",[[1,[1,[1,\"iF\",\"*\",[5,\"3.17\"]],\"+\",[1,[6,\"d.f32\",[\"gx\"]],\"*\",[5,\"13.71\"]]],\"+\",[1,[6,\"d.f32\",[\"gy\"]],\"*\",[5,\"29.37\"]]]]]]]],[13,\"wgt\",[1,[1,\"aff\",\"*\",\"pref\"],\"/\",[1,[5,\"1\"],\"+\",[1,[5,\"5\"],\"*\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]]]]],[11,[1,\"wgt\",\">\",\"bestW\"],[0,[[2,\"bestW\",\"=\",\"wgt\"],[2,\"tgtX\",\"=\",\"cx\"],[2,\"tgtY\",\"=\",\"cy\"]]]]]]]]]],[11,[1,\"bestW\",\">\",[5,\"0.02\"]],[0,[[2,\"bestX\",\"=\",[6,\"std.clamp\",[[1,\"tgtX\",\"+\",[1,[1,[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"5.77\"]],\"+\",[1,\"gen\",\"*\",[5,\"2.13\"]]]]],\"-\",[5,\"0.5\"]],\"/\",\"g\"]],[5,\"0.02\"],[5,\"0.98\"]]]],[2,\"bestY\",\"=\",[6,\"std.clamp\",[[1,\"tgtY\",\"+\",[1,[1,[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"8.31\"]],\"+\",[1,\"gen\",\"*\",[5,\"4.97\"]]]]],\"-\",[5,\"0.5\"]],\"/\",\"g\"]],[5,\"0.02\"],[5,\"0.98\"]]]]]],[0,[[13,\"ang\",[1,[1,[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"13.77\"]],\"+\",[1,\"gen\",\"*\",[5,\"3.19\"]]]]],\"*\",\"TWO_PI\"],\"+\",[1,[6,\"std.sin\",[[1,[1,\"frame\",\"*\",[5,\"0.02\"]],\"+\",\"iF\"]]],\"*\",[5,\"1.4\"]]]],[2,\"bestX\",\"=\",[6,\"std.clamp\",[[1,\"posX\",\"+\",[1,[6,\"std.cos\",[\"ang\"]],\"*\",[5,\"0.08\"]]],[5,\"0.03\"],[5,\"0.97\"]]]],[2,\"bestY\",\"=\",[6,\"std.clamp\",[[1,\"posY\",\"+\",[1,[6,\"std.sin\",[\"ang\"]],\"*\",[5,\"0.08\"]]],[5,\"0.03\"],[5,\"0.97\"]]]]]]]]]],[13,\"maxStep\",[1,[7,\"P\",\"dt\"],\"*\",[1,[5,\"0.15\"],\"+\",[1,[5,\"1.4\"],\"*\",[7,\"P\",\"agility\"]]]]],[13,\"dX\",[1,\"bestX\",\"-\",\"posX\"]],[13,\"dY\",[1,\"bestY\",\"-\",\"posY\"]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"dX\",\"*\",\"dX\"],\"+\",[1,\"dY\",\"*\",\"dY\"]]]]],[13,\"stepK\",[6,\"std.min\",[[6,\"d.f32\",[[5,\"1\"]]],[1,\"maxStep\",\"/\",[6,\"std.max\",[\"dist\",[5,\"0.00001\"]]]]]]],[2,\"posX\",\"=\",[1,\"posX\",\"+\",[1,\"dX\",\"*\",\"stepK\"]]],[2,\"posY\",\"=\",[1,\"posY\",\"+\",[1,\"dY\",\"*\",\"stepK\"]]],[12,\"crowded\",[6,\"d.f32\",[[5,\"0\"]]]],[13,\"iN\",[6,\"d.i32\",[\"ti\"]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",\"iN\"],[102,\"++\",\"k\"],[0,[[13,\"kF\",[6,\"d.f32\",[\"k\"]]],[13,\"other\",[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"0\"]]],[6,\"d.u32\",[\"k\"]]]],[5,\"0\"]]]],[13,\"odx\",[1,[7,\"other\",\"x\"],\"-\",\"posX\"]],[13,\"ody\",[1,[7,\"other\",\"y\"],\"-\",\"posY\"]],[13,\"near\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"std.sqrt\",[[1,[1,\"odx\",\"*\",\"odx\"],\"+\",[1,\"ody\",\"*\",\"ody\"]]]],\"<\",[5,\"0.022\"]]]]],[2,\"crowded\",\"=\",[6,\"std.max\",[\"crowded\",[1,[1,\"near\",\"*\",[7,\"other\",\"w\"]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"kF\",\"<\",[7,\"P\",\"trackersF\"]]]]]]]]]]],[2,\"crowdStreak\",\"=\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[1,\"crowdStreak\",\"+\",[5,\"1\"]],[1,\"crowded\",\">\",[5,\"0.5\"]]]]],[11,[1,\"crowdStreak\",\">\",[5,\"30\"]],[0,[[13,\"hopAng\",[1,[6,\"trackHash\",[[1,[1,[1,\"iF\",\"*\",[5,\"9.13\"]],\"+\",[1,\"gen\",\"*\",[5,\"5.77\"]]],\"+\",[5,\"2.3\"]]]],\"*\",\"TWO_PI\"]],[13,\"hopDist\",[1,[5,\"0.05\"],\"+\",[1,[5,\"0.08\"],\"*\",[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"4.71\"]],\"+\",[1,\"gen\",\"*\",[5,\"8.11\"]]]]]]]],[2,\"posX\",\"=\",[6,\"std.clamp\",[[1,\"posX\",\"+\",[1,[6,\"std.cos\",[\"hopAng\"]],\"*\",\"hopDist\"]],[5,\"0.03\"],[5,\"0.97\"]]]],[2,\"posY\",\"=\",[6,\"std.clamp\",[[1,\"posY\",\"+\",[1,[6,\"std.sin\",[\"hopAng\"]],\"*\",\"hopDist\"]],[5,\"0.03\"],[5,\"0.97\"]]]],[2,\"gen\",\"=\",[1,\"gen\",\"+\",[5,\"1\"]]],[2,\"genStart\",\"=\",\"frame\"],[2,\"missStreak\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]],[2,\"crowdStreak\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]]]]],[13,\"lifeFrames\",[1,[1,[7,\"P\",\"lifespan\"],\"*\",[5,\"60\"]],\"*\",[1,[5,\"0.7\"],\"+\",[1,[5,\"0.6\"],\"*\",[6,\"trackHash\",[[1,[1,\"iF\",\"*\",[5,\"4.77\"]],\"+\",[1,\"gen\",\"*\",[5,\"1.31\"]]]]]]]]],[13,\"expired\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[1,\"frame\",\"-\",\"genStart\"],\">\",\"lifeFrames\"]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"P\",\"lifespan\"],\">\",[5,\"0.01\"]]]]]],[13,\"lost\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"missStreak\",\">\",[5,\"90\"]]]]],[11,[1,[1,\"expired\",\"+\",\"lost\"],\">\",[5,\"0.5\"]],[0,[[2,\"posX\",\"=\",[1,[5,\"0.1\"],\"+\",[1,[5,\"0.8\"],\"*\",[6,\"trackHash\",[[1,[1,[1,\"iF\",\"*\",[5,\"7.31\"]],\"+\",[1,\"gen\",\"*\",[5,\"13.7\"]]],\"+\",[1,\"frame\",\"*\",[5,\"0.013\"]]]]]]]],[2,\"posY\",\"=\",[1,[5,\"0.1\"],\"+\",[1,[5,\"0.8\"],\"*\",[6,\"trackHash\",[[1,[1,[1,\"iF\",\"*\",[5,\"11.93\"]],\"+\",[1,\"gen\",\"*\",[5,\"17.3\"]]],\"+\",[1,\"frame\",\"*\",[5,\"0.019\"]]]]]]]],[2,\"gen\",\"=\",[1,\"gen\",\"+\",[5,\"1\"]]],[2,\"genStart\",\"=\",\"frame\"],[2,\"missStreak\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]],[2,\"crowdStreak\",\"=\",[6,\"d.f32\",[[5,\"0\"]]]]]]],[13,\"writeIdx\",[1,[6,\"std.floor\",[[1,\"frame\",\"/\",[6,\"d.f32\",[\"TRAIL_EVERY\"]]]]],\"%\",[6,\"d.f32\",[\"TRAIL_LEN\"]]]],[13,\"shouldWrite\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[1,\"frame\",\"%\",[6,\"d.f32\",[\"TRAIL_EVERY\"]]],\"<\",[5,\"0.5\"]]]]],[12,\"bbMinX\",\"posX\"],[12,\"bbMinY\",\"posY\"],[12,\"bbMaxX\",\"posX\"],[12,\"bbMaxY\",\"posY\"],[14,[12,\"j\",[5,\"0\"]],[1,\"j\",\"<\",\"TRAIL_LEN\"],[102,\"++\",\"j\"],[0,[[13,\"jF\",[6,\"d.f32\",[\"j\"]]],[12,\"e\",[6,\"std.textureLoad\",[[7,[7,\"trackLayout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[1,[5,\"2\"],\"+\",\"j\"]]],\"ti\"]],[5,\"0\"]]]],[13,\"isSlot\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"std.abs\",[[1,\"jF\",\"-\",\"writeIdx\"]]],\"<\",[5,\"0.5\"]]]]],[13,\"doWrite\",[1,\"isSlot\",\"*\",\"shouldWrite\"]],[2,\"e\",\"=\",[6,\"std.mix\",[\"e\",[6,\"d.vec4f\",[\"posX\",\"posY\",\"frame\",\"gen\"]],\"doWrite\"]]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"next\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[1,[5,\"2\"],\"+\",\"j\"]]],\"ti\"]],\"e\"]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"present\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[1,[5,\"2\"],\"+\",\"j\"]]],\"ti\"]],\"e\"]],[13,\"live\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"std.abs\",[[1,[7,\"e\",\"w\"],\"-\",\"gen\"]]],\"<\",[5,\"0.5\"]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"e\",\"z\"],\">\",[5,\"0.5\"]]]]]],[2,\"bbMinX\",\"=\",[6,\"std.min\",[\"bbMinX\",[6,\"std.mix\",[\"posX\",[7,\"e\",\"x\"],\"live\"]]]]],[2,\"bbMinY\",\"=\",[6,\"std.min\",[\"bbMinY\",[6,\"std.mix\",[\"posY\",[7,\"e\",\"y\"],\"live\"]]]]],[2,\"bbMaxX\",\"=\",[6,\"std.max\",[\"bbMaxX\",[6,\"std.mix\",[\"posX\",[7,\"e\",\"x\"],\"live\"]]]]],[2,\"bbMaxY\",\"=\",[6,\"std.max\",[\"bbMaxY\",[6,\"std.mix\",[\"posY\",[7,\"e\",\"y\"],\"live\"]]]]]]]],[13,\"bbOut\",[6,\"d.vec4f\",[\"bbMinX\",\"bbMinY\",\"bbMaxX\",\"bbMaxY\"]]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"next\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"AABB_COL\"]],\"ti\"]],\"bbOut\"]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"present\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"AABB_COL\"]],\"ti\"]],\"bbOut\"]],[13,\"headOut\",[6,\"d.vec4f\",[\"posX\",\"posY\",\"frame\",[1,\"genStart\",\"+\",[5,\"1\"]]]]],[13,\"metaOut\",[6,\"d.vec4f\",[\"missStreak\",\"sumW\",\"gen\",\"crowdStreak\"]]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"next\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"0\"]]],\"ti\"]],\"headOut\"]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"present\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"0\"]]],\"ti\"]],\"headOut\"]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"next\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"1\"]]],\"ti\"]],\"metaOut\"]],[6,\"std.textureStore\",[[7,[7,\"trackLayout\",\"$\"],\"present\"],[6,\"d.vec2u\",[[6,\"d.u32\",[[5,\"1\"]]],\"ti\"]],\"metaOut\"]]]]},externals:{trackLayout:()=>Go,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,trackHash:()=>ln,\"std.max\":()=>B,\"std.textureDimensions\":()=>Ti,\"std.clamp\":()=>G,score:()=>s,\"std.select\":()=>N,\"std.exp\":()=>Tt,\"std.sqrt\":()=>Ue,FEAT_GRID:()=>tl,TWO_PI:()=>G0,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.min\":()=>ye,\"d.i32\":()=>j,\"std.floor\":()=>ie,TRAIL_EVERY:()=>O0,TRAIL_LEN:()=>U0,\"std.abs\":()=>re,\"std.mix\":()=>K,\"d.vec4f\":()=>S,\"std.textureStore\":()=>lt,AABB_COL:()=>O1}})&&r.f)({})).$name(\"trackerPursuit\")}function yB(e){return t=>{let{childNode:s,gpu:r,getCpuValue:o}=t;if(!s)return null;let a=r?.root;if(!a)return null;let i=gB(e.mode),l=kae(i),c=Bae(e.mode,i),d=(globalThis.__TYPEGPU_AUTONAME__??(f=>f))(a.createUniform(iA),\"paramsBuf\"),u=hB(t,{size:[Eae,cP],format:zv,textures:{grid:tl},bindGroups:({childTexture:f,display:h,textures:g},y,b)=>a.createBindGroup(Go,{src:f,featGrid:g.grid,prev:y.state,next:b.state,present:h,params:d.buffer}),staticGroups:({childTexture:f,textures:h})=>a.createBindGroup(xm,{src:f,grid:h.grid,params:d.buffer})});if(!u)return null;let p=wr(a,(f=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(f.f=((h,g)=>{\"use gpu\";l(h,g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gx\"},{type:\"i\",name:\"gy\"}],body:[0,[[6,\"featureKernel\",[\"gx\",\"gy\"]]]]},externals:{featureKernel:()=>l}})&&f.f)({}),{size:[tl,tl]}),_=wr(a,(f=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(f.f=(h=>{\"use gpu\";c(h)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ti\"}],body:[0,[[6,\"trackKernel\",[\"ti\"]]]]},externals:{trackKernel:()=>c}})&&f.f)({}),{size:[cP]});return{outputs:{childTexture:u.childTexture,trackState:u.display},bindInputs:u.bindInputs,getComputeNodes:f=>u.tick(f,({groups:h,shared:g,dt:y})=>(d.write({dt:y,trackersF:o(e.trackers)??4,agility:o(e.agility)??.5,threshold:o(e.threshold)??.15,variance:o(e.variance)??.5,lifespan:o(e.lifespan)??6}),[p.with(g),_.with(h)]))}}}function Sl(e={}){let t=e.smoothing??.2,s=e.teleportGuard??.25,r=e.minDrag??6e-4,o=e.initialX??.5,a=e.initialY??.5,i=0,l=0,c=!1,d=!1;return{update(u,p){let _=u?.seen===!1;_?c=!0:u?.x!==void 0&&c&&!d&&(d=!0,o=u.x,a=u.y??a);let f=o,h=a,g=_?o:u?.x??o,y=_?a:u?.y??a,b=g-f,x=y-h,P=Math.sqrt(b*b+x*x),C=P>=s;o=g,a=y;let E=C?0:b,R=C?0:x,U=1/Math.max(p,.001),L=E*U,k=R*U;return i=i*(1-t)+L*t,l=l*(1-t)+k*t,{x:g,y,prevX:f,prevY:h,dx:E,dy:R,dragDist:P,velX:L,velY:k,smoothVelX:i,smoothVelY:l,smoothSpeed:Math.sqrt(i*i+l*l),teleport:C,moving:!C&&P>r}}}}function lA(e={}){let t=e.warmupFrames??0,s=!1,r=0,o=0,a=()=>o>=t;return{markActive(){s=!0,r=0},tickFrame(i){o++,r+=i},get neverActive(){return!s},get warmedUp(){return a()},shouldSkip(i,l=!1){return l||!a()?!1:s?r>i:!0}}}function jh(e,t,s=.05){return Math.log(e)/Math.max(t,s)}function cA(e,t){let s=t.scale??1,r=Math.min(t.maxSteps,Math.max(1,Math.ceil(t.dragDist/t.stepSize)));for(let o=0;o<r;o++){let a=(o+.5)/r,i=(t.fromX+t.dx*a)*s,l=(t.fromY+t.dy*a)*s,c=t.prepare?t.prepare(a):void 0;e.push(()=>t.write(i,l,a,c)),e.push(t.pass)}return r}var dP=3,jb=Math.exp(-(dP*dP)),uP=1/(1-jb),Kb=.004,bB=\"rgba16float\";function zae(e){return w.bindGroupLayout({readBuf:{storage:Fe(n,e),access:\"readonly\"},writeBuf:{storage:Fe(n,e),access:\"mutable\"},params:{uniform:(globalThis.__TYPEGPU_AUTONAME__??(t=>t))(gt({cursorX:n,cursorY:n,cursorSpeed:n,dt:n,damping:n,radius:n,aspect:n}),\"uniform\")}})}function Rae(e){return w.bindGroupLayout({srcBuf:{storage:Fe(n,e),access:\"readonly\"},dispTex:{storageTexture:zt(bB,\"write-only\")}})}var pP=new Map;function Dae(e){let t=pP.get(e);if(t)return t;let s=e*e,r=e-1,o=zae(s),a=Rae(s),i={resolution:e,propagateLayout:o,gradientLayout:a,propagateKernel:w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";if(c>M(0)&&c<M(r)&&d>M(0)&&d<M(r)){let u=o.$.params,p=M(e),_=__tsover_add(__tsover_mul(d,p),c),f=o.$.readBuf[__tsover_sub(_,M(1))],h=o.$.readBuf[__tsover_add(_,M(1))],g=o.$.readBuf[__tsover_sub(_,p)],y=o.$.readBuf[__tsover_add(_,p)],b=__tsover_mul(__tsover_add(__tsover_add(__tsover_add(f,h),g),y),.5),x=o.$.writeBuf[_],P=__tsover_sub(1,__tsover_mul(u.damping,Kb)),C=__tsover_mul(__tsover_sub(b,x),P),E=__tsover_div(__tsover_add(n(c),.5),n(e)),R=__tsover_div(__tsover_add(n(d),.5),n(e)),U=N(__tsover_sub(E,u.cursorX),__tsover_mul(__tsover_sub(E,u.cursorX),u.aspect),u.aspect>=1),L=N(__tsover_div(__tsover_sub(R,u.cursorY),u.aspect),__tsover_sub(R,u.cursorY),u.aspect>=1),k=__tsover_add(__tsover_mul(U,U),__tsover_mul(L,L)),D=__tsover_mul(u.radius,3);if(k<__tsover_mul(D,D)&&u.cursorSpeed>.01){let O=__tsover_mul(__tsover_sub(Tt(__tsover_mul(__tsover_div(k,__tsover_mul(u.radius,u.radius)),-1)),jb),uP);C=__tsover_sub(C,__tsover_mul(__tsover_mul(__tsover_mul(O,u.cursorSpeed),u.dt),3))}o.$.writeBuf[_]=C}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[11,[3,[3,[3,[1,\"cx\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],\"&&\",[1,\"cx\",\"<\",[6,\"d.u32\",[\"gridMax\"]]]],\"&&\",[1,\"cy\",\">\",[6,\"d.u32\",[[5,\"0\"]]]]],\"&&\",[1,\"cy\",\"<\",[6,\"d.u32\",[\"gridMax\"]]]],[0,[[13,\"p\",[7,[7,\"propagateLayout\",\"$\"],\"params\"]],[13,\"gs\",[6,\"d.u32\",[\"resolution\"]]],[13,\"idx\",[1,[1,\"cy\",\"*\",\"gs\"],\"+\",\"cx\"]],[13,\"left\",[8,[7,[7,\"propagateLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"right\",[8,[7,[7,\"propagateLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"up\",[8,[7,[7,\"propagateLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"-\",\"gs\"]]],[13,\"down\",[8,[7,[7,\"propagateLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"+\",\"gs\"]]],[13,\"avg\",[1,[1,[1,[1,\"left\",\"+\",\"right\"],\"+\",\"up\"],\"+\",\"down\"],\"*\",[5,\"0.5\"]]],[13,\"prev\",[8,[7,[7,\"propagateLayout\",\"$\"],\"writeBuf\"],\"idx\"]],[13,\"dampFactor\",[1,[5,\"1\"],\"-\",[1,[7,\"p\",\"damping\"],\"*\",\"DAMPING_SCALE\"]]],[12,\"next\",[1,[1,\"avg\",\"-\",\"prev\"],\"*\",\"dampFactor\"]],[13,\"cellX\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"resolution\"]]]],[13,\"cellY\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"resolution\"]]]],[13,\"ddx\",[6,\"std.select\",[[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],[1,[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],\"*\",[7,\"p\",\"aspect\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"ddy\",[6,\"std.select\",[[1,[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],\"/\",[7,\"p\",\"aspect\"]],[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"distSq\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]],[13,\"influenceRadius\",[1,[7,\"p\",\"radius\"],\"*\",[5,\"3\"]]],[11,[3,[1,\"distSq\",\"<\",[1,\"influenceRadius\",\"*\",\"influenceRadius\"]],\"&&\",[1,[7,\"p\",\"cursorSpeed\"],\">\",[5,\"0.01\"]]],[0,[[13,\"influence\",[1,[1,[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]]],\"*\",[4,\"-\",[5,\"1\"]]]]],\"-\",\"BRUSH_EDGE\"],\"*\",\"BRUSH_EDGE_GAIN\"]],[2,\"next\",\"=\",[1,\"next\",\"-\",[1,[1,[1,\"influence\",\"*\",[7,\"p\",\"cursorSpeed\"]],\"*\",[7,\"p\",\"dt\"]],\"*\",[5,\"3\"]]]]]]],[2,[8,[7,[7,\"propagateLayout\",\"$\"],\"writeBuf\"],\"idx\"],\"=\",\"next\"]]]]]]},externals:{\"d.u32\":()=>M,gridMax:()=>r,propagateLayout:()=>o,resolution:()=>e,DAMPING_SCALE:()=>Kb,\"d.f32\":()=>n,\"std.select\":()=>N,\"std.exp\":()=>Tt,BRUSH_EDGE:()=>jb,BRUSH_EDGE_GAIN:()=>uP}})&&l.f)({})).$name(`waveFieldPropagate_${e}`),gradientKernel:w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";if(c>M(0)&&c<M(r)&&d>M(0)&&d<M(r)){let u=M(e),p=__tsover_add(__tsover_mul(d,u),c),_=a.$.srcBuf[__tsover_add(p,M(1))],f=a.$.srcBuf[__tsover_sub(p,M(1))],h=a.$.srcBuf[__tsover_add(p,u)],g=a.$.srcBuf[__tsover_sub(p,u)],y=__tsover_mul(__tsover_sub(_,f),.5),b=__tsover_mul(__tsover_sub(h,g),.5);lt(a.$.dispTex,fe(c,d),S(y,b,0,1))}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[11,[3,[3,[3,[1,\"cx\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],\"&&\",[1,\"cx\",\"<\",[6,\"d.u32\",[\"gridMax\"]]]],\"&&\",[1,\"cy\",\">\",[6,\"d.u32\",[[5,\"0\"]]]]],\"&&\",[1,\"cy\",\"<\",[6,\"d.u32\",[\"gridMax\"]]]],[0,[[13,\"gs\",[6,\"d.u32\",[\"resolution\"]]],[13,\"idx\",[1,[1,\"cy\",\"*\",\"gs\"],\"+\",\"cx\"]],[13,\"right\",[8,[7,[7,\"gradientLayout\",\"$\"],\"srcBuf\"],[1,\"idx\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"left\",[8,[7,[7,\"gradientLayout\",\"$\"],\"srcBuf\"],[1,\"idx\",\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"down\",[8,[7,[7,\"gradientLayout\",\"$\"],\"srcBuf\"],[1,\"idx\",\"+\",\"gs\"]]],[13,\"up\",[8,[7,[7,\"gradientLayout\",\"$\"],\"srcBuf\"],[1,\"idx\",\"-\",\"gs\"]]],[13,\"dx\",[1,[1,\"right\",\"-\",\"left\"],\"*\",[5,\"0.5\"]]],[13,\"dy\",[1,[1,\"down\",\"-\",\"up\"],\"*\",[5,\"0.5\"]]],[6,\"std.textureStore\",[[7,[7,\"gradientLayout\",\"$\"],\"dispTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"dx\",\"dy\",[5,\"0\"],[5,\"1\"]]]]]]]]]]},externals:{\"d.u32\":()=>M,gridMax:()=>r,resolution:()=>e,gradientLayout:()=>a,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&l.f)({})).$name(`waveFieldGradient_${e}`)};return pP.set(e,i),i}function Lae(e,t){let{gpu:s,registerComputeTexture:r,getCpuValue:o,onCleanup:a,onResize:i,dimensions:l}=e,c=s?.root;if(!c)return null;let{resolution:d,dampingProp:u,radiusProp:p,radiusScale:_,speedMax:f,teleportGuard:h=\"on\"}=t,{propagateLayout:g,gradientLayout:y,propagateKernel:b,gradientKernel:x}=Dae(d),P=d*d,C=pr(c,n,P),E=pr(c,n,P),R=(globalThis.__TYPEGPU_AUTONAME__??(J=>J))(c.createTexture({size:[d,d],format:bB}).$usage(\"storage\",\"sampled\"),\"dispTex\");a(()=>R.destroy());let U=r(R),L=(globalThis.__TYPEGPU_AUTONAME__??(J=>J))(c.createUniform(gt({cursorX:n,cursorY:n,cursorSpeed:n,dt:n,damping:n,radius:n,aspect:n})),\"propParams\"),k=Math.max(1,Math.round(l.width)),D=Math.max(1,Math.round(l.height));i(({width:J,height:oe})=>{k=Math.max(1,Math.round(J)),D=Math.max(1,Math.round(oe))});let O=[d,d],F=ap(C,E),q=F.groups((J,oe)=>c.createBindGroup(g,{readBuf:J,writeBuf:oe,params:L.buffer})),Y=F.perSide(J=>c.createBindGroup(y,{srcBuf:J,dispTex:R})),V=wr(c,(J=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(J.f=((oe,le)=>{\"use gpu\";b(oe,le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"propagateKernel\",[\"cx\",\"cy\"]]]]},externals:{propagateKernel:()=>b}})&&J.f)({}),{size:O}),X=wr(c,(J=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(J.f=((oe,le)=>{\"use gpu\";x(oe,le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"gradientKernel\",[\"cx\",\"cy\"]]]]},externals:{gradientKernel:()=>x}})&&J.f)({}),{size:O}),Q=Sl(h===\"off\"?{teleportGuard:Number.POSITIVE_INFINITY}:{}),te=Date.now();return{displacement:U,getComputeNodes:J=>{let oe=J,le=Date.now(),se=Math.min(oe.deltaTime??0,.016),Te=Math.max(1,oe.dimensions?.width??k)/Math.max(1,oe.dimensions?.height??D),de=o(u)??10,xe=(o(p)??.5)*_,Ae=Q.update(oe.pointer,se),De=Math.min(Math.sqrt(Ae.velX*Ae.velX+Ae.velY*Ae.velY),f);De>.01&&(te=le);let Ee=1-de*Kb,ze=Ee>=1?1/0:Math.min(3e4,Math.log(1e-6)/Math.log(Math.max(Ee,.001))*16.67);if(le-te>ze)return null;L.write({cursorX:Ae.x,cursorY:Ae.y,cursorSpeed:De,dt:se,damping:de,radius:xe,aspect:Te});let Ie=[V.with(q()),X.with(Y.written())];return F.swap(),Ie}}}var Uae=zk;function Oae(e,t,s={}){let{uniforms:r,propValues:o}=e,a=o.colorSpace??0;return(o.stopCount??0)>1?En(t,{colorsArray:r.colorsArray,positionsArray:r.positionsArray,convertedColorsArray:r.convertedColorsArray,stopCount:r.stopCount},a):W(No[a]??Ar,\"mixColors\",[r[s.colorA??\"colorA\"],r[s.colorB??\"colorB\"],t])}var Gae=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(__tsover_mul(t.x,s),t.y),i=__tsover_mul(r,4);return a.mul(i).add(o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"freq\",[1,\"scale\",\"*\",[5,\"4\"]]],[10,[6,[7,[6,[7,\"aspectUV\",\"mul\"],[\"freq\"]],\"add\"],[\"seed\"]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Fae=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Si(s),a=m(o.y,o.z).mul(r).mul(.012);return t.add(a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"pos\"},{type:\"i\",name:\"distortion\"}],body:[0,[[13,\"grad\",[6,\"perlin12d\",[\"pos\"]]],[13,\"disp\",[6,[7,[6,[7,[6,\"d.vec2f\",[[7,\"grad\",\"y\"],[7,\"grad\",\"z\"]]],\"mul\"],[\"distortion\"]],\"mul\"],[[5,\"0.012\"]]]],[10,[6,[7,\"uv\",\"add\"],[\"disp\"]]]]]},externals:{perlin12d:()=>Si,\"d.vec2f\":()=>m}})&&e.f)({})),Iae=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_add(__tsover_mul(__tsover_sub(t,.5),__tsover_add(s,1)),.5);return G(__tsover_add(1,__tsover_mul(__tsover_sub(o,.5),__tsover_mul(r,1.1))),0,1.6)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"contrast\"},{type:\"i\",name:\"intensity\"}],body:[0,[[13,\"hAdj\",[1,[1,[1,\"h\",\"-\",[5,\"0.5\"]],\"*\",[1,\"contrast\",\"+\",[5,\"1\"]]],\"+\",[5,\"0.5\"]]],[10,[6,\"std.clamp\",[[1,[5,\"1\"],\"+\",[1,[1,\"hAdj\",\"-\",[5,\"0.5\"]],\"*\",[1,\"intensity\",\"*\",[5,\"1.1\"]]]],[5,\"0\"],[5,\"1.6\"]]]]]]},externals:{\"std.clamp\":()=>G}})&&e.f)({}));function Yae(e,t,s){let{childNode:r,uniforms:o,ctx:a,convertToTexture:i}=e;if(!r)return xt;let l=i(r),c=W(Gae,\"reliefPos\",[a.uv,a.aspect,o.scale,o.seed]),d=W(Fae,\"reliefDisplacedUV\",[a.uv,c,o.distortion]),u=W(Yt,\"unpremultiplyAlpha\",[l.sample(d)]),p=W(Iae,\"reliefBrightness\",[W(t,s,[c]),o.contrast,o.intensity]);return Ct(u.member(\"rgb\").mul(p),u.member(\"a\"))}var Wae=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=N(t,__tsover_sub(1,t),o>0),i=B(r,1e-4),l=__tsover_sub(__tsover_mul(s,__tsover_add(1,__tsover_mul(2,i))),i);return be(__tsover_sub(l,i),__tsover_add(l,i),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"coord\"},{type:\"i\",name:\"progress\"},{type:\"i\",name:\"feather\"},{type:\"i\",name:\"invert\"}],body:[0,[[13,\"c\",[6,\"std.select\",[\"coord\",[1,[5,\"1\"],\"-\",\"coord\"],[1,\"invert\",\">\",[5,\"0\"]]]]],[13,\"f\",[6,\"std.max\",[\"feather\",[5,\"0.0001\"]]]],[13,\"front\",[1,[1,\"progress\",\"*\",[1,[5,\"1\"],\"+\",[1,[5,\"2\"],\"*\",\"f\"]]],\"-\",\"f\"]],[10,[6,\"std.smoothstep\",[[1,\"front\",\"-\",\"f\"],[1,\"front\",\"+\",\"f\"],\"c\"]]]]]},externals:{\"std.select\":()=>N,\"std.max\":()=>B,\"std.smoothstep\":()=>be}})&&e.f)({})),qae=w.fn([S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return S(t.x,t.y,t.z,__tsover_mul(t.w,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"reveal\"}],body:[0,[[10,[6,\"d.vec4f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"],[1,[7,\"color\",\"w\"],\"*\",\"reveal\"]]]]]]},externals:{\"d.vec4f\":()=>S}})&&e.f)({})),Vae=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(r,bt),a=m(pe(o),ae(o)),i=Se(m(__tsover_mul(__tsover_sub(t.x,.5),s),__tsover_sub(t.y,.5)),a),l=__tsover_mul(.5,__tsover_add(__tsover_mul(s,re(a.x)),re(a.y)));return __tsover_add(__tsover_div(i,__tsover_mul(2,l)),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"angleDeg\"}],body:[0,[[13,\"a\",[1,\"angleDeg\",\"*\",\"DEG_TO_RAD\"]],[13,\"dir\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"a\"]],[6,\"std.sin\",[\"a\"]]]]],[13,\"p\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]],[13,\"grad\",[6,\"std.dot\",[\"p\",\"dir\"]]],[13,\"ext\",[1,[5,\"0.5\"],\"*\",[1,[1,\"aspect\",\"*\",[6,\"std.abs\",[[7,\"dir\",\"x\"]]]],\"+\",[6,\"std.abs\",[[7,\"dir\",\"y\"]]]]]],[10,[1,[1,\"grad\",\"/\",[1,[5,\"2\"],\"*\",\"ext\"]],\"+\",[5,\"0.5\"]]]]]},externals:{DEG_TO_RAD:()=>bt,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.abs\":()=>re}})&&e.f)({})),Nae=w.fn([m,n,m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(r.x,s),a=__tsover_sub(1,r.y),i=he(m(__tsover_sub(__tsover_mul(t.x,s),o),__tsover_sub(t.y,a))),l=he(m(B(o,__tsover_sub(s,o)),B(a,__tsover_sub(1,a))));return __tsover_div(i,B(l,1e-4))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"}],body:[0,[[13,\"cx\",[1,[7,\"center\",\"x\"],\"*\",\"aspect\"]],[13,\"cy\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"rel\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"-\",\"cx\"],[1,[7,\"uv\",\"y\"],\"-\",\"cy\"]]]],[13,\"dist\",[6,\"std.length\",[\"rel\"]]],[13,\"dx\",[6,\"std.max\",[\"cx\",[1,\"aspect\",\"-\",\"cx\"]]]],[13,\"dy\",[6,\"std.max\",[\"cy\",[1,[5,\"1\"],\"-\",\"cy\"]]]],[13,\"maxDist\",[6,\"std.length\",[[6,\"d.vec2f\",[\"dx\",\"dy\"]]]]],[10,[1,\"dist\",\"/\",[6,\"std.max\",[\"maxDist\",[5,\"0.0001\"]]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.max\":()=>B}})&&e.f)({})),$ae=w.fn([m,n,m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m(__tsover_mul(__tsover_sub(t.x,r.x),s),__tsover_sub(t.y,__tsover_sub(1,r.y))),l=Xt(i.y,i.x),c=__tsover_mul(o,bt),d=__tsover_div(__tsover_sub(l,c),Po);d=__tsover_sub(d,ie(d));let u=__tsover_sub(1,d),p=__tsover_mul(ye(d,__tsover_sub(1,d)),2),_=N(d,u,a>.5);return _=N(_,p,a>1.5),_}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"startDeg\"},{type:\"i\",name:\"mode\"}],body:[0,[[13,\"rel\",[6,\"d.vec2f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",[7,\"center\",\"x\"]],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]]],[13,\"ang\",[6,\"std.atan2\",[[7,\"rel\",\"y\"],[7,\"rel\",\"x\"]]]],[13,\"start\",[1,\"startDeg\",\"*\",\"DEG_TO_RAD\"]],[12,\"frac\",[1,[1,\"ang\",\"-\",\"start\"],\"/\",\"TWO_PI\"]],[2,\"frac\",\"=\",[1,\"frac\",\"-\",[6,\"std.floor\",[\"frac\"]]]],[13,\"ccwCoord\",[1,[5,\"1\"],\"-\",\"frac\"]],[13,\"bothCoord\",[1,[6,\"std.min\",[\"frac\",[1,[5,\"1\"],\"-\",\"frac\"]]],\"*\",[5,\"2\"]]],[12,\"coord\",[6,\"std.select\",[\"frac\",\"ccwCoord\",[1,\"mode\",\">\",[5,\"0.5\"]]]]],[2,\"coord\",\"=\",[6,\"std.select\",[\"coord\",\"bothCoord\",[1,\"mode\",\">\",[5,\"1.5\"]]]]],[10,\"coord\"]]]},externals:{\"d.vec2f\":()=>m,\"std.atan2\":()=>Xt,DEG_TO_RAD:()=>bt,TWO_PI:()=>Po,\"std.floor\":()=>ie,\"std.min\":()=>ye,\"std.select\":()=>N}})&&e.f)({})),F0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cell:m,local:m,grid:m}),\"CellGrid\"),Nu=w.fn([m,n,n],F0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(1,B(r,.001)),a=B(__tsover_div(o,s),1),i=__tsover_mul(t.x,o),l=__tsover_mul(t.y,a);return F0({cell:m(ie(i),ie(l)),local:m(Re(i),Re(l)),grid:m(o,a)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"size\"}],body:[0,[[13,\"gridX\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[\"size\",[5,\"0.001\"]]]]],[13,\"gridY\",[6,\"std.max\",[[1,\"gridX\",\"/\",\"aspect\"],[5,\"1\"]]]],[13,\"sx\",[1,[7,\"uv\",\"x\"],\"*\",\"gridX\"]],[13,\"sy\",[1,[7,\"uv\",\"y\"],\"*\",\"gridY\"]],[10,[6,\"CellGrid\",[[104,{cell:[6,\"d.vec2f\",[[6,\"std.floor\",[\"sx\"]],[6,\"std.floor\",[\"sy\"]]]],local:[6,\"d.vec2f\",[[6,\"std.fract\",[\"sx\"]],[6,\"std.fract\",[\"sy\"]]]],grid:[6,\"d.vec2f\",[\"gridX\",\"gridY\"]]}]]]]]]},externals:{\"std.max\":()=>B,CellGrid:()=>F0,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"std.fract\":()=>Re}})&&e.f)({})),Xae=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_mul(re(__tsover_sub(t,.5)),2)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"}],body:[0,[[10,[1,[6,\"std.abs\",[[1,\"t\",\"-\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]]]]},externals:{\"std.abs\":()=>re}})&&e.f)({})),Hae=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Re(__tsover_mul(t,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"count\"}],body:[0,[[10,[6,\"std.fract\",[[1,\"t\",\"*\",\"count\"]]]]]]},externals:{\"std.fract\":()=>Re}})&&e.f)({})),jae=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=B(s,1);return G(__tsover_div(__tsover_add(ie(__tsover_mul(t,r)),.5),r),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"count\"}],body:[0,[[13,\"n\",[6,\"std.max\",[\"count\",[5,\"1\"]]]],[10,[6,\"std.clamp\",[[1,[1,[6,\"std.floor\",[[1,\"t\",\"*\",\"n\"]]],\"+\",[5,\"0.5\"]],\"/\",\"n\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.floor\":()=>ie}})&&e.f)({})),Kae=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=ie(__tsover_mul(t,B(s,1)));return Xs(__tsover_add(r,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"count\"}],body:[0,[[13,\"idx\",[6,\"std.floor\",[[1,\"t\",\"*\",[6,\"std.max\",[\"count\",[5,\"1\"]]]]]]],[10,[6,\"hash11\",[[1,\"idx\",\"+\",[5,\"0.5\"]]]]]]]},externals:{\"std.floor\":()=>ie,\"std.max\":()=>B,hash11:()=>Xs}})&&e.f)({})),Qae=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Nu(t,s,r);return __tsover_add(re(__tsover_sub(o.local.x,.5)),re(__tsover_sub(o.local.y,.5)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"size\"}],body:[0,[[13,\"g\",[6,\"cellGrid\",[\"uv\",\"aspect\",\"size\"]]],[10,[1,[6,\"std.abs\",[[1,[7,[7,\"g\",\"local\"],\"x\"],\"-\",[5,\"0.5\"]]]],\"+\",[6,\"std.abs\",[[1,[7,[7,\"g\",\"local\"],\"y\"],\"-\",[5,\"0.5\"]]]]]]]]},externals:{cellGrid:()=>Nu,\"std.abs\":()=>re}})&&e.f)({})),Zae=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Nu(t,s,r),a=__tsover_mul(Re(__tsover_mul(__tsover_add(o.cell.x,o.cell.y),.5)),2),i=__tsover_mul(__tsover_add(__tsover_div(o.cell.x,o.grid.x),__tsover_div(o.cell.y,o.grid.y)),.5);return G(__tsover_add(__tsover_mul(.5,a),__tsover_mul(.5,i)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"size\"}],body:[0,[[13,\"g\",[6,\"cellGrid\",[\"uv\",\"aspect\",\"size\"]]],[13,\"parity\",[1,[6,\"std.fract\",[[1,[1,[7,[7,\"g\",\"cell\"],\"x\"],\"+\",[7,[7,\"g\",\"cell\"],\"y\"]],\"*\",[5,\"0.5\"]]]],\"*\",[5,\"2\"]]],[13,\"diag\",[1,[1,[1,[7,[7,\"g\",\"cell\"],\"x\"],\"/\",[7,[7,\"g\",\"grid\"],\"x\"]],\"+\",[1,[7,[7,\"g\",\"cell\"],\"y\"],\"/\",[7,[7,\"g\",\"grid\"],\"y\"]]],\"*\",[5,\"0.5\"]]],[10,[6,\"std.clamp\",[[1,[1,[5,\"0.5\"],\"*\",\"parity\"],\"+\",[1,[5,\"0.5\"],\"*\",\"diag\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{cellGrid:()=>Nu,\"std.fract\":()=>Re,\"std.clamp\":()=>G}})&&e.f)({})),Jae=w.fn([m,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return Ys(Nu(t,s,r).cell)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"size\"}],body:[0,[[10,[6,\"hash12\",[[7,[6,\"cellGrid\",[\"uv\",\"aspect\",\"size\"]],\"cell\"]]]]]]},externals:{hash12:()=>Ys,cellGrid:()=>Nu}})&&e.f)({})),ene=w.fn([m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(__tsover_add(__tsover_mul(__tsover_mul(t.x,s),r),__tsover_mul(o,13.7)),__tsover_add(__tsover_mul(t.y,r),__tsover_mul(o,7.9))),i=la(a),l=__tsover_mul(la(m(__tsover_add(__tsover_add(__tsover_mul(a.x,2),17.3),__tsover_mul(o,3.1)),__tsover_add(__tsover_mul(a.y,2),9.1))),.5),c=__tsover_mul(la(m(__tsover_add(__tsover_mul(a.x,4),41.7),__tsover_add(__tsover_add(__tsover_mul(a.y,4),27.9),__tsover_mul(o,5.3)))),.25),d=__tsover_div(__tsover_add(__tsover_add(i,l),c),1.75);return G(__tsover_add(.5,__tsover_mul(d,.9)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"p\",[6,\"d.vec2f\",[[1,[1,[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],\"*\",\"scale\"],\"+\",[1,\"seed\",\"*\",[5,\"13.7\"]]],[1,[1,[7,\"uv\",\"y\"],\"*\",\"scale\"],\"+\",[1,\"seed\",\"*\",[5,\"7.9\"]]]]]],[13,\"n1\",[6,\"mxNoiseFloat2\",[\"p\"]]],[13,\"n2\",[1,[6,\"mxNoiseFloat2\",[[6,\"d.vec2f\",[[1,[1,[1,[7,\"p\",\"x\"],\"*\",[5,\"2\"]],\"+\",[5,\"17.3\"]],\"+\",[1,\"seed\",\"*\",[5,\"3.1\"]]],[1,[1,[7,\"p\",\"y\"],\"*\",[5,\"2\"]],\"+\",[5,\"9.1\"]]]]]],\"*\",[5,\"0.5\"]]],[13,\"n3\",[1,[6,\"mxNoiseFloat2\",[[6,\"d.vec2f\",[[1,[1,[7,\"p\",\"x\"],\"*\",[5,\"4\"]],\"+\",[5,\"41.7\"]],[1,[1,[1,[7,\"p\",\"y\"],\"*\",[5,\"4\"]],\"+\",[5,\"27.9\"]],\"+\",[1,\"seed\",\"*\",[5,\"5.3\"]]]]]]],\"*\",[5,\"0.25\"]]],[13,\"n\",[1,[1,[1,\"n1\",\"+\",\"n2\"],\"+\",\"n3\"],\"/\",[5,\"1.75\"]]],[10,[6,\"std.clamp\",[[1,[5,\"0.5\"],\"+\",[1,\"n\",\"*\",[5,\"0.9\"]]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"d.vec2f\":()=>m,mxNoiseFloat2:()=>la,\"std.clamp\":()=>G}})&&e.f)({})),xB=new Float32Array(1),tne=new Int32Array(xB.buffer);function _o(e){xB[0]=Math.max(-65504,Math.min(65504,e));let t=tne[0],s=t>>16&32768,r=t>>12&2047,o=t>>23&255;return o<103?s:o>142?(s|=31744,s|=(o===255?0:1)&&t&8388607,s):o<113?(r|=2048,s|=(r>>114-o)+(r>>113-o&1),s):(s|=o-112<<10|r>>1,s+=r&1,s)}var yc=ko({ANALYTIC_SDF_EXTRA_FIELDS:()=>sne,APERTURE_TO_HALFANGLE:()=>CB,SVG_SDF_SIZE:()=>512,ShapeMask:()=>G1,analyticSubPropValues:()=>Hv,arcSdf:()=>Nv,buildAnalyticSdfFn:()=>P_,circleSdf:()=>Dm,createAnalyticSdfSampler:()=>MB,createSdfDataTexture:()=>uA,createSvgSdfSampler:()=>SB,createSvgSdfSamplerWithGradients:()=>PB,crescentSdf:()=>Wv,crossSdf:()=>Gv,driveAnalyticSubProps:()=>EB,ellipseSdf:()=>Iv,fillStrokeColor:()=>TB,flowerSdf:()=>Lv,heartSdf:()=>Vv,loadSdfFromUrl:()=>dA,parallelogramSdf:()=>Xv,parseShapeConfigValue:()=>jv,polygonSdf:()=>Dv,ringSdf:()=>Ov,roundedRectSdf:()=>Fv,shapeLocalCoords:()=>AB,starSdf:()=>Uv,strokeMaskFromSdf:()=>wB,teardropSdf:()=>$v,trapezoidSdf:()=>qv,vesicaSdf:()=>Yv}),mP=3.141592653589793,$u=6.283185307179586,_P=.35355339059327373,Rv=.017453292519943295,Dm=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_sub(Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s))),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"}],body:[0,[[10,[1,[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]],\"-\",\"radius\"]]]]},externals:{\"std.sqrt\":()=>Ue}})&&e.f)({})),Dv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s))),i=Xt(s,t),l=__tsover_div($u,o),c=ie(__tsover_add(__tsover_div(i,l),.5)),d=__tsover_sub(i,__tsover_mul(c,l));return __tsover_sub(__tsover_mul(a,pe(d)),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"sides\"}],body:[0,[[13,\"len\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[13,\"angle\",[6,\"std.atan2\",[\"dy\",\"dx\"]]],[13,\"sectorAngle\",[1,\"TWO_PI\",\"/\",\"sides\"]],[13,\"sectorIdx\",[6,\"std.floor\",[[1,[1,\"angle\",\"/\",\"sectorAngle\"],\"+\",[5,\"0.5\"]]]]],[13,\"canonicalAngle\",[1,\"angle\",\"-\",[1,\"sectorIdx\",\"*\",\"sectorAngle\"]]],[10,[1,[1,\"len\",\"*\",[6,\"std.cos\",[\"canonicalAngle\"]]],\"-\",\"radius\"]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.atan2\":()=>Xt,TWO_PI:()=>$u,\"std.floor\":()=>ie,\"std.cos\":()=>pe}})&&e.f)({})),Lv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Xt(s,t),l=Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s))),c=__tsover_mul(r,a),d=__tsover_div(__tsover_mul(i,o),$u),u=__tsover_sub(d,ie(d)),p=re(__tsover_sub(__tsover_mul(u,2),1)),_=__tsover_add(c,__tsover_mul(__tsover_sub(r,c),p));return __tsover_sub(l,_)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"outerRadius\"},{type:\"i\",name:\"sides\"},{type:\"i\",name:\"innerRatio\"}],body:[0,[[13,\"angle\",[6,\"std.atan2\",[\"dy\",\"dx\"]]],[13,\"len\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[13,\"innerRadius\",[1,\"outerRadius\",\"*\",\"innerRatio\"]],[13,\"tAngle\",[1,[1,\"angle\",\"*\",\"sides\"],\"/\",\"TWO_PI\"]],[13,\"tFrac\",[1,\"tAngle\",\"-\",[6,\"std.floor\",[\"tAngle\"]]]],[13,\"t\",[6,\"std.abs\",[[1,[1,\"tFrac\",\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]],[13,\"boundaryR\",[1,\"innerRadius\",\"+\",[1,[1,\"outerRadius\",\"-\",\"innerRadius\"],\"*\",\"t\"]]],[10,[1,\"len\",\"-\",\"boundaryR\"]]]]},externals:{\"std.atan2\":()=>Xt,\"std.sqrt\":()=>Ue,TWO_PI:()=>$u,\"std.floor\":()=>ie,\"std.abs\":()=>re}})&&e.f)({})),Uv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_mul(r,a),l=Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s))),c=Xt(s,t),d=__tsover_div($u,o),u=ie(__tsover_add(__tsover_div(c,d),.5)),p=__tsover_sub(c,__tsover_mul(u,d)),_=re(__tsover_mul(l,ae(p))),f=__tsover_mul(l,pe(p)),h=__tsover_div(mP,o),g=ae(h),y=pe(h),b=__tsover_mul(i,g),x=__tsover_sub(__tsover_mul(i,y),r),P=_,C=__tsover_sub(f,r),E=__tsover_add(__tsover_mul(P,b),__tsover_mul(C,x)),R=__tsover_add(__tsover_mul(b,b),__tsover_mul(x,x)),U=G(__tsover_div(E,R),0,1),L=__tsover_sub(_,__tsover_mul(b,U)),k=__tsover_sub(f,__tsover_add(r,__tsover_mul(x,U))),D=Ue(__tsover_add(__tsover_mul(L,L),__tsover_mul(k,k))),O=__tsover_sub(__tsover_mul(b,C),__tsover_mul(x,P));return __tsover_mul(D,no(O))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"outerRadius\"},{type:\"i\",name:\"sides\"},{type:\"i\",name:\"innerRatio\"}],body:[0,[[13,\"innerRadius\",[1,\"outerRadius\",\"*\",\"innerRatio\"]],[13,\"len\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[13,\"angle\",[6,\"std.atan2\",[\"dy\",\"dx\"]]],[13,\"sectorAngle\",[1,\"TWO_PI\",\"/\",\"sides\"]],[13,\"sectorIdx\",[6,\"std.floor\",[[1,[1,\"angle\",\"/\",\"sectorAngle\"],\"+\",[5,\"0.5\"]]]]],[13,\"bn\",[1,\"angle\",\"-\",[1,\"sectorIdx\",\"*\",\"sectorAngle\"]]],[13,\"fpx\",[6,\"std.abs\",[[1,\"len\",\"*\",[6,\"std.sin\",[\"bn\"]]]]]],[13,\"fpy\",[1,\"len\",\"*\",[6,\"std.cos\",[\"bn\"]]]],[13,\"an\",[1,\"PI\",\"/\",\"sides\"]],[13,\"sinAn\",[6,\"std.sin\",[\"an\"]]],[13,\"cosAn\",[6,\"std.cos\",[\"an\"]]],[13,\"ex\",[1,\"innerRadius\",\"*\",\"sinAn\"]],[13,\"ey\",[1,[1,\"innerRadius\",\"*\",\"cosAn\"],\"-\",\"outerRadius\"]],[13,\"qx\",\"fpx\"],[13,\"qy\",[1,\"fpy\",\"-\",\"outerRadius\"]],[13,\"dotQE\",[1,[1,\"qx\",\"*\",\"ex\"],\"+\",[1,\"qy\",\"*\",\"ey\"]]],[13,\"dotEE\",[1,[1,\"ex\",\"*\",\"ex\"],\"+\",[1,\"ey\",\"*\",\"ey\"]]],[13,\"t\",[6,\"std.clamp\",[[1,\"dotQE\",\"/\",\"dotEE\"],[5,\"0\"],[5,\"1\"]]]],[13,\"nx\",[1,\"fpx\",\"-\",[1,\"ex\",\"*\",\"t\"]]],[13,\"ny\",[1,\"fpy\",\"-\",[1,\"outerRadius\",\"+\",[1,\"ey\",\"*\",\"t\"]]]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"nx\",\"*\",\"nx\"],\"+\",[1,\"ny\",\"*\",\"ny\"]]]]],[13,\"cross\",[1,[1,\"ex\",\"*\",\"qy\"],\"-\",[1,\"ey\",\"*\",\"qx\"]]],[10,[1,\"dist\",\"*\",[6,\"std.sign\",[\"cross\"]]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.atan2\":()=>Xt,TWO_PI:()=>$u,\"std.floor\":()=>ie,\"std.abs\":()=>re,\"std.sin\":()=>ae,\"std.cos\":()=>pe,PI:()=>mP,\"std.clamp\":()=>G,\"std.sign\":()=>no}})&&e.f)({})),Ov=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s)));return __tsover_sub(re(__tsover_sub(a,r)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"thickness\"}],body:[0,[[13,\"len\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]]],[10,[1,[6,\"std.abs\",[[1,\"len\",\"-\",\"radius\"]]],\"-\",\"thickness\"]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.abs\":()=>re}})&&e.f)({})),Gv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=re(t),l=re(s),c=B(__tsover_sub(i,r),__tsover_sub(l,o)),d=B(__tsover_sub(l,r),__tsover_sub(i,o));return __tsover_sub(ye(c,d),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"size\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"rounding\"}],body:[0,[[13,\"px\",[6,\"std.abs\",[\"dx\"]]],[13,\"py\",[6,\"std.abs\",[\"dy\"]]],[13,\"dHoriz\",[6,\"std.max\",[[1,\"px\",\"-\",\"size\"],[1,\"py\",\"-\",\"thickness\"]]]],[13,\"dVert\",[6,\"std.max\",[[1,\"py\",\"-\",\"size\"],[1,\"px\",\"-\",\"thickness\"]]]],[10,[1,[6,\"std.min\",[\"dHoriz\",\"dVert\"]],\"-\",\"rounding\"]]]]},externals:{\"std.abs\":()=>re,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})),Fv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_add(__tsover_sub(re(t),r),a),l=__tsover_add(__tsover_sub(re(s),o),a),c=B(i,0),d=B(l,0),u=Ue(__tsover_add(__tsover_mul(c,c),__tsover_mul(d,d))),p=ye(B(i,l),0);return __tsover_sub(__tsover_add(u,p),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"width\"},{type:\"i\",name:\"height\"},{type:\"i\",name:\"rounding\"}],body:[0,[[13,\"qx\",[1,[1,[6,\"std.abs\",[\"dx\"]],\"-\",\"width\"],\"+\",\"rounding\"]],[13,\"qy\",[1,[1,[6,\"std.abs\",[\"dy\"]],\"-\",\"height\"],\"+\",\"rounding\"]],[13,\"mqx\",[6,\"std.max\",[\"qx\",[5,\"0\"]]]],[13,\"mqy\",[6,\"std.max\",[\"qy\",[5,\"0\"]]]],[13,\"outerDist\",[6,\"std.sqrt\",[[1,[1,\"mqx\",\"*\",\"mqx\"],\"+\",[1,\"mqy\",\"*\",\"mqy\"]]]]],[13,\"innerDist\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",\"qy\"]],[5,\"0\"]]]],[10,[1,[1,\"outerDist\",\"+\",\"innerDist\"],\"-\",\"rounding\"]]]]},externals:{\"std.abs\":()=>re,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.min\":()=>ye}})&&e.f)({})),Iv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_div(t,r),i=__tsover_div(s,o),l=Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(i,i)));return __tsover_mul(__tsover_sub(l,1),ye(r,o))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radiusX\"},{type:\"i\",name:\"radiusY\"}],body:[0,[[13,\"nx\",[1,\"dx\",\"/\",\"radiusX\"]],[13,\"ny\",[1,\"dy\",\"/\",\"radiusY\"]],[13,\"k\",[6,\"std.sqrt\",[[1,[1,\"nx\",\"*\",\"nx\"],\"+\",[1,\"ny\",\"*\",\"ny\"]]]]],[10,[1,[1,\"k\",\"-\",[5,\"1\"]],\"*\",[6,\"std.min\",[\"radiusX\",\"radiusY\"]]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.min\":()=>ye}})&&e.f)({})),Yv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=re(t),i=re(s),l=__tsover_mul(r,o),c=Ue(B(__tsover_sub(__tsover_mul(r,r),__tsover_mul(l,l)),0)),d=__tsover_mul(__tsover_sub(i,c),l)>__tsover_mul(a,c),u=Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(__tsover_sub(i,c),__tsover_sub(i,c))));return N(__tsover_sub(Ue(__tsover_add(__tsover_mul(__tsover_add(a,l),__tsover_add(a,l)),__tsover_mul(i,i))),r),u,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"spread\"}],body:[0,[[13,\"px\",[6,\"std.abs\",[\"dx\"]]],[13,\"py\",[6,\"std.abs\",[\"dy\"]]],[13,\"dd\",[1,\"radius\",\"*\",\"spread\"]],[13,\"b\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[1,\"radius\",\"*\",\"radius\"],\"-\",[1,\"dd\",\"*\",\"dd\"]],[5,\"0\"]]]]]],[13,\"cond\",[1,[1,[1,\"py\",\"-\",\"b\"],\"*\",\"dd\"],\">\",[1,\"px\",\"*\",\"b\"]]],[13,\"dist1\",[6,\"std.sqrt\",[[1,[1,\"px\",\"*\",\"px\"],\"+\",[1,[1,\"py\",\"-\",\"b\"],\"*\",[1,\"py\",\"-\",\"b\"]]]]]],[13,\"dist2\",[1,[6,\"std.sqrt\",[[1,[1,[1,\"px\",\"+\",\"dd\"],\"*\",[1,\"px\",\"+\",\"dd\"]],\"+\",[1,\"py\",\"*\",\"py\"]]]],\"-\",\"radius\"]],[10,[6,\"std.select\",[\"dist2\",\"dist1\",\"cond\"]]]]]},externals:{\"std.abs\":()=>re,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"std.select\":()=>N}})&&e.f)({})),Wv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=re(s),l=r,c=__tsover_mul(r,o),d=a,u=__tsover_div(__tsover_add(__tsover_sub(__tsover_mul(l,l),__tsover_mul(c,c)),__tsover_mul(d,d)),B(__tsover_mul(d,2),.001)),p=Ue(B(__tsover_sub(__tsover_mul(l,l),__tsover_mul(u,u)),0)),_=__tsover_mul(d,__tsover_sub(__tsover_mul(t,p),__tsover_mul(i,u))),f=__tsover_mul(__tsover_mul(d,d),B(__tsover_sub(p,i),0)),h=__tsover_sub(t,u),g=__tsover_sub(i,p),y=Ue(__tsover_add(__tsover_mul(h,h),__tsover_mul(g,g))),b=Ue(__tsover_add(__tsover_mul(t,t),__tsover_mul(i,i))),x=__tsover_sub(t,d),P=Ue(__tsover_add(__tsover_mul(x,x),__tsover_mul(i,i)));return N(B(__tsover_sub(b,l),__tsover_mul(__tsover_sub(P,c),-1)),y,_>f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"outerRadius\"},{type:\"i\",name:\"innerRatio\"},{type:\"i\",name:\"offset\"}],body:[0,[[13,\"py\",[6,\"std.abs\",[\"dy\"]]],[13,\"ra\",\"outerRadius\"],[13,\"rb\",[1,\"outerRadius\",\"*\",\"innerRatio\"]],[13,\"off\",\"offset\"],[13,\"a\",[1,[1,[1,[1,\"ra\",\"*\",\"ra\"],\"-\",[1,\"rb\",\"*\",\"rb\"]],\"+\",[1,\"off\",\"*\",\"off\"]],\"/\",[6,\"std.max\",[[1,\"off\",\"*\",[5,\"2\"]],[5,\"0.001\"]]]]],[13,\"bSq\",[6,\"std.max\",[[1,[1,\"ra\",\"*\",\"ra\"],\"-\",[1,\"a\",\"*\",\"a\"]],[5,\"0\"]]]],[13,\"b\",[6,\"std.sqrt\",[\"bSq\"]]],[13,\"lhs\",[1,\"off\",\"*\",[1,[1,\"dx\",\"*\",\"b\"],\"-\",[1,\"py\",\"*\",\"a\"]]]],[13,\"rhs\",[1,[1,\"off\",\"*\",\"off\"],\"*\",[6,\"std.max\",[[1,\"b\",\"-\",\"py\"],[5,\"0\"]]]]],[13,\"d1x\",[1,\"dx\",\"-\",\"a\"]],[13,\"d1y\",[1,\"py\",\"-\",\"b\"]],[13,\"dist1\",[6,\"std.sqrt\",[[1,[1,\"d1x\",\"*\",\"d1x\"],\"+\",[1,\"d1y\",\"*\",\"d1y\"]]]]],[13,\"lenP\",[6,\"std.sqrt\",[[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"py\",\"*\",\"py\"]]]]],[13,\"innerX\",[1,\"dx\",\"-\",\"off\"]],[13,\"lenInner\",[6,\"std.sqrt\",[[1,[1,\"innerX\",\"*\",\"innerX\"],\"+\",[1,\"py\",\"*\",\"py\"]]]]],[13,\"dist2\",[6,\"std.max\",[[1,\"lenP\",\"-\",\"ra\"],[1,[1,\"lenInner\",\"-\",\"rb\"],\"*\",[4,\"-\",[5,\"1\"]]]]]],[10,[6,\"std.select\",[\"dist2\",\"dist1\",[1,\"lhs\",\">\",\"rhs\"]]]]]]},externals:{\"std.abs\":()=>re,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.select\":()=>N}})&&e.f)({})),qv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=re(t),l=o,c=a,d=__tsover_sub(o,r),u=__tsover_mul(a,2),p=N(o,r,s<0),_=__tsover_sub(i,ye(i,p)),f=__tsover_sub(re(s),a),h=__tsover_sub(l,i),g=__tsover_sub(c,s),y=__tsover_add(__tsover_mul(h,d),__tsover_mul(g,u)),b=B(__tsover_add(__tsover_mul(d,d),__tsover_mul(u,u)),1e-4),x=G(__tsover_div(y,b),0,1),P=__tsover_add(__tsover_sub(i,l),__tsover_mul(d,x)),C=__tsover_add(__tsover_sub(s,c),__tsover_mul(u,x)),E=N(n(1),n(-1),f<0),R=N(n(1),E,P<0),U=__tsover_add(__tsover_mul(_,_),__tsover_mul(f,f)),L=__tsover_add(__tsover_mul(P,P),__tsover_mul(C,C));return __tsover_mul(R,Ue(ye(U,L)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"r1\"},{type:\"i\",name:\"r2\"},{type:\"i\",name:\"he\"}],body:[0,[[13,\"px\",[6,\"std.abs\",[\"dx\"]]],[13,\"k1x\",\"r2\"],[13,\"k1y\",\"he\"],[13,\"k2x\",[1,\"r2\",\"-\",\"r1\"]],[13,\"k2y\",[1,\"he\",\"*\",[5,\"2\"]]],[13,\"clampWidth\",[6,\"std.select\",[\"r2\",\"r1\",[1,\"dy\",\"<\",[5,\"0\"]]]]],[13,\"cax\",[1,\"px\",\"-\",[6,\"std.min\",[\"px\",\"clampWidth\"]]]],[13,\"cay\",[1,[6,\"std.abs\",[\"dy\"]],\"-\",\"he\"]],[13,\"diffX\",[1,\"k1x\",\"-\",\"px\"]],[13,\"diffY\",[1,\"k1y\",\"-\",\"dy\"]],[13,\"dotNum\",[1,[1,\"diffX\",\"*\",\"k2x\"],\"+\",[1,\"diffY\",\"*\",\"k2y\"]]],[13,\"dotDen\",[6,\"std.max\",[[1,[1,\"k2x\",\"*\",\"k2x\"],\"+\",[1,\"k2y\",\"*\",\"k2y\"]],[5,\"0.0001\"]]]],[13,\"t\",[6,\"std.clamp\",[[1,\"dotNum\",\"/\",\"dotDen\"],[5,\"0\"],[5,\"1\"]]]],[13,\"cbx\",[1,[1,\"px\",\"-\",\"k1x\"],\"+\",[1,\"k2x\",\"*\",\"t\"]]],[13,\"cby\",[1,[1,\"dy\",\"-\",\"k1y\"],\"+\",[1,\"k2y\",\"*\",\"t\"]]],[13,\"sInner\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[1,\"cay\",\"<\",[5,\"0\"]]]]],[13,\"s\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"sInner\",[1,\"cbx\",\"<\",[5,\"0\"]]]]],[13,\"dca\",[1,[1,\"cax\",\"*\",\"cax\"],\"+\",[1,\"cay\",\"*\",\"cay\"]]],[13,\"dcb\",[1,[1,\"cbx\",\"*\",\"cbx\"],\"+\",[1,\"cby\",\"*\",\"cby\"]]],[10,[1,\"s\",\"*\",[6,\"std.sqrt\",[[6,\"std.min\",[\"dca\",\"dcb\"]]]]]]]]},externals:{\"std.abs\":()=>re,\"std.select\":()=>N,\"std.min\":()=>ye,\"std.max\":()=>B,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.sqrt\":()=>Ue}})&&e.f)({})),Vv=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_div(r,.75),a=__tsover_div(re(t),o),i=__tsover_add(__tsover_div(__tsover_mul(s,-1),o),.6),l=__tsover_sub(a,.25),c=__tsover_sub(i,.75),d=__tsover_sub(Ue(__tsover_add(__tsover_mul(l,l),__tsover_mul(c,c))),_P),u=__tsover_sub(i,1),p=__tsover_add(__tsover_mul(a,a),__tsover_mul(u,u)),_=__tsover_mul(B(__tsover_add(a,i),0),.5),f=__tsover_sub(a,_),h=__tsover_sub(i,_),g=__tsover_add(__tsover_mul(f,f),__tsover_mul(h,h)),y=__tsover_mul(Ue(ye(p,g)),no(__tsover_sub(a,i)));return __tsover_mul(N(y,d,__tsover_add(a,i)>1),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"}],body:[0,[[13,\"S\",[1,\"radius\",\"/\",[5,\"0.75\"]]],[13,\"px\",[1,[6,\"std.abs\",[\"dx\"]],\"/\",\"S\"]],[13,\"py\",[1,[1,[1,\"dy\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"S\"],\"+\",[5,\"0.6\"]]],[13,\"ax\",[1,\"px\",\"-\",[5,\"0.25\"]]],[13,\"ay\",[1,\"py\",\"-\",[5,\"0.75\"]]],[13,\"distA\",[1,[6,\"std.sqrt\",[[1,[1,\"ax\",\"*\",\"ax\"],\"+\",[1,\"ay\",\"*\",\"ay\"]]]],\"-\",\"SQRT2_OVER_4\"]],[13,\"b1y\",[1,\"py\",\"-\",[5,\"1\"]]],[13,\"dot1\",[1,[1,\"px\",\"*\",\"px\"],\"+\",[1,\"b1y\",\"*\",\"b1y\"]]],[13,\"m\",[1,[6,\"std.max\",[[1,\"px\",\"+\",\"py\"],[5,\"0\"]]],\"*\",[5,\"0.5\"]]],[13,\"b2x\",[1,\"px\",\"-\",\"m\"]],[13,\"b2y\",[1,\"py\",\"-\",\"m\"]],[13,\"dot2v\",[1,[1,\"b2x\",\"*\",\"b2x\"],\"+\",[1,\"b2y\",\"*\",\"b2y\"]]],[13,\"distB\",[1,[6,\"std.sqrt\",[[6,\"std.min\",[\"dot1\",\"dot2v\"]]]],\"*\",[6,\"std.sign\",[[1,\"px\",\"-\",\"py\"]]]]],[10,[1,[6,\"std.select\",[\"distB\",\"distA\",[1,[1,\"px\",\"+\",\"py\"],\">\",[5,\"1\"]]]],\"*\",\"S\"]]]]},externals:{\"std.abs\":()=>re,\"std.sqrt\":()=>Ue,SQRT2_OVER_4:()=>_P,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.sign\":()=>no,\"std.select\":()=>N}})&&e.f)({})),Nv=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=re(t),i=ae(o),l=pe(o),c=__tsover_sub(Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(s,s))),r),d=G(__tsover_add(__tsover_mul(a,i),__tsover_mul(s,l)),0,r),u=__tsover_sub(a,__tsover_mul(i,d)),p=__tsover_sub(s,__tsover_mul(l,d)),_=Ue(__tsover_add(__tsover_mul(u,u),__tsover_mul(p,p)));return B(c,__tsover_mul(_,no(__tsover_sub(__tsover_mul(l,a),__tsover_mul(i,s)))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"halfAngle\"}],body:[0,[[13,\"px\",[6,\"std.abs\",[\"dx\"]]],[13,\"cx\",[6,\"std.sin\",[\"halfAngle\"]]],[13,\"cy\",[6,\"std.cos\",[\"halfAngle\"]]],[13,\"l\",[1,[6,\"std.sqrt\",[[1,[1,\"px\",\"*\",\"px\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]]],\"-\",\"radius\"]],[13,\"clamped\",[6,\"std.clamp\",[[1,[1,\"px\",\"*\",\"cx\"],\"+\",[1,\"dy\",\"*\",\"cy\"]],[5,\"0\"],\"radius\"]]],[13,\"mx\",[1,\"px\",\"-\",[1,\"cx\",\"*\",\"clamped\"]]],[13,\"my\",[1,\"dy\",\"-\",[1,\"cy\",\"*\",\"clamped\"]]],[13,\"m\",[6,\"std.sqrt\",[[1,[1,\"mx\",\"*\",\"mx\"],\"+\",[1,\"my\",\"*\",\"my\"]]]]],[10,[6,\"std.max\",[\"l\",[1,\"m\",\"*\",[6,\"std.sign\",[[1,[1,\"cy\",\"*\",\"px\"],\"-\",[1,\"cx\",\"*\",\"dy\"]]]]]]]]]]},externals:{\"std.abs\":()=>re,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.sqrt\":()=>Ue,\"std.clamp\":()=>G,\"std.max\":()=>B,\"std.sign\":()=>no}})&&e.f)({})),$v=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(__tsover_sub(o,r),.5),i=re(t),l=__tsover_add(__tsover_mul(s,-1),a),c=B(o,1e-4),d=__tsover_div(r,c),u=Ue(B(__tsover_sub(1,__tsover_mul(d,d)),0)),p=__tsover_add(__tsover_mul(i,__tsover_mul(d,-1)),__tsover_mul(l,u)),_=__tsover_sub(Ue(__tsover_add(__tsover_mul(i,i),__tsover_mul(l,l))),r),f=__tsover_sub(l,o),h=Ue(__tsover_add(__tsover_mul(i,i),__tsover_mul(f,f)));return N(N(__tsover_sub(__tsover_add(__tsover_mul(i,u),__tsover_mul(l,d)),r),h,p>__tsover_mul(u,o)),_,p<0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"mid\",[1,[1,\"h\",\"-\",\"radius\"],\"*\",[5,\"0.5\"]]],[13,\"qx\",[6,\"std.abs\",[\"dx\"]]],[13,\"qy\",[1,[1,\"dy\",\"*\",[4,\"-\",[5,\"1\"]]],\"+\",\"mid\"]],[13,\"hSafe\",[6,\"std.max\",[\"h\",[5,\"0.0001\"]]]],[13,\"b\",[1,\"radius\",\"/\",\"hSafe\"]],[13,\"a\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[5,\"1\"],\"-\",[1,\"b\",\"*\",\"b\"]],[5,\"0\"]]]]]],[13,\"k\",[1,[1,\"qx\",\"*\",[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]]],\"+\",[1,\"qy\",\"*\",\"a\"]]],[13,\"cap0\",[1,[6,\"std.sqrt\",[[1,[1,\"qx\",\"*\",\"qx\"],\"+\",[1,\"qy\",\"*\",\"qy\"]]]],\"-\",\"radius\"]],[13,\"qyTip\",[1,\"qy\",\"-\",\"h\"]],[13,\"cap1\",[6,\"std.sqrt\",[[1,[1,\"qx\",\"*\",\"qx\"],\"+\",[1,\"qyTip\",\"*\",\"qyTip\"]]]]],[13,\"body\",[1,[1,[1,\"qx\",\"*\",\"a\"],\"+\",[1,\"qy\",\"*\",\"b\"]],\"-\",\"radius\"]],[10,[6,\"std.select\",[[6,\"std.select\",[\"body\",\"cap1\",[1,\"k\",\">\",[1,\"a\",\"*\",\"h\"]]]],\"cap0\",[1,\"k\",\"<\",[5,\"0\"]]]]]]]},externals:{\"std.abs\":()=>re,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.select\":()=>N}})&&e.f)({})),Xv=w.fn([n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=a,l=o,c=s<0,d=N(t,__tsover_mul(t,-1),c),u=N(s,__tsover_mul(s,-1),c),p=__tsover_sub(d,i),_=__tsover_sub(u,l),f=__tsover_sub(p,G(p,__tsover_mul(r,-1),r)),h=__tsover_add(__tsover_mul(f,f),__tsover_mul(_,_)),g=__tsover_mul(_,-1),y=__tsover_sub(__tsover_mul(d,l),__tsover_mul(u,i)),b=y<0,x=N(d,__tsover_mul(d,-1),b),P=N(u,__tsover_mul(u,-1),b),C=__tsover_sub(x,r),E=__tsover_add(__tsover_mul(C,i),__tsover_mul(P,l)),R=B(__tsover_add(__tsover_mul(i,i),__tsover_mul(l,l)),1e-4),U=G(__tsover_div(E,R),-1,1),L=__tsover_sub(C,__tsover_mul(i,U)),k=__tsover_sub(P,__tsover_mul(l,U)),D=ye(h,__tsover_add(__tsover_mul(L,L),__tsover_mul(k,k))),O=ye(g,__tsover_sub(__tsover_mul(r,o),re(y)));return __tsover_mul(Ue(D),no(__tsover_mul(O,-1)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dx\"},{type:\"i\",name:\"dy\"},{type:\"i\",name:\"wi\"},{type:\"i\",name:\"he\"},{type:\"i\",name:\"sk\"}],body:[0,[[13,\"ex\",\"sk\"],[13,\"ey\",\"he\"],[13,\"flip1\",[1,\"dy\",\"<\",[5,\"0\"]]],[13,\"px0\",[6,\"std.select\",[\"dx\",[1,\"dx\",\"*\",[4,\"-\",[5,\"1\"]]],\"flip1\"]]],[13,\"py0\",[6,\"std.select\",[\"dy\",[1,\"dy\",\"*\",[4,\"-\",[5,\"1\"]]],\"flip1\"]]],[13,\"wx0\",[1,\"px0\",\"-\",\"ex\"]],[13,\"wy\",[1,\"py0\",\"-\",\"ey\"]],[13,\"wx\",[1,\"wx0\",\"-\",[6,\"std.clamp\",[\"wx0\",[1,\"wi\",\"*\",[4,\"-\",[5,\"1\"]]],\"wi\"]]]],[13,\"dX\",[1,[1,\"wx\",\"*\",\"wx\"],\"+\",[1,\"wy\",\"*\",\"wy\"]]],[13,\"dY\",[1,\"wy\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"s\",[1,[1,\"px0\",\"*\",\"ey\"],\"-\",[1,\"py0\",\"*\",\"ex\"]]],[13,\"flip2\",[1,\"s\",\"<\",[5,\"0\"]]],[13,\"px\",[6,\"std.select\",[\"px0\",[1,\"px0\",\"*\",[4,\"-\",[5,\"1\"]]],\"flip2\"]]],[13,\"py\",[6,\"std.select\",[\"py0\",[1,\"py0\",\"*\",[4,\"-\",[5,\"1\"]]],\"flip2\"]]],[13,\"vx0\",[1,\"px\",\"-\",\"wi\"]],[13,\"dotve\",[1,[1,\"vx0\",\"*\",\"ex\"],\"+\",[1,\"py\",\"*\",\"ey\"]]],[13,\"dotee\",[6,\"std.max\",[[1,[1,\"ex\",\"*\",\"ex\"],\"+\",[1,\"ey\",\"*\",\"ey\"]],[5,\"0.0001\"]]]],[13,\"tt\",[6,\"std.clamp\",[[1,\"dotve\",\"/\",\"dotee\"],[4,\"-\",[5,\"1\"]],[5,\"1\"]]]],[13,\"vx\",[1,\"vx0\",\"-\",[1,\"ex\",\"*\",\"tt\"]]],[13,\"vy\",[1,\"py\",\"-\",[1,\"ey\",\"*\",\"tt\"]]],[13,\"finalX\",[6,\"std.min\",[\"dX\",[1,[1,\"vx\",\"*\",\"vx\"],\"+\",[1,\"vy\",\"*\",\"vy\"]]]]],[13,\"finalY\",[6,\"std.min\",[\"dY\",[1,[1,\"wi\",\"*\",\"he\"],\"-\",[6,\"std.abs\",[\"s\"]]]]]],[10,[1,[6,\"std.sqrt\",[\"finalX\"]],\"*\",[6,\"std.sign\",[[1,\"finalY\",\"*\",[4,\"-\",[5,\"1\"]]]]]]]]]},externals:{\"std.select\":()=>N,\"std.clamp\":()=>G,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.abs\":()=>re,\"std.sqrt\":()=>Ue,\"std.sign\":()=>no}})&&e.f)({})),AB=w.fn([m,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=m(__tsover_mul(r.x,o),r.y),i=m(__tsover_mul(t.x,o),__tsover_sub(1,t.y)),l=__tsover_sub(a.x,i.x),c=__tsover_sub(a.y,i.y),d=__tsover_mul(s,Rv),u=pe(d),p=ae(d);return m(__tsover_add(__tsover_mul(l,u),__tsover_mul(c,p)),__tsover_sub(__tsover_mul(c,u),__tsover_mul(l,p)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dx\",[1,[7,\"aspectUV\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]]],[13,\"dy\",[1,[7,\"aspectUV\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"rotRad\",[1,\"rotation\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rdx\",[1,[1,\"dx\",\"*\",\"cosR\"],\"+\",[1,\"dy\",\"*\",\"sinR\"]]],[13,\"rdy\",[1,[1,\"dy\",\"*\",\"cosR\"],\"-\",[1,\"dx\",\"*\",\"sinR\"]]],[10,[6,\"d.vec2f\",[\"rdx\",\"rdy\"]]]]]},externals:{\"d.vec2f\":()=>m,DEG_TO_RAD:()=>Rv,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({})),G1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({overallMask:n,strokeBlend:n}),\"ShapeMask\"),wB=w.fn([n,n,n,n],G1)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=r>0,i=o>=1.5,l=o>=.5,c=__tsover_mul(r,.5),d=__tsover_mul(r,-1),u=__tsover_mul(c,-1),p=N(N(n(0),u,l),d,i),_=N(N(r,c,l),n(0),i),f=__tsover_sub(1,be(__tsover_sub(_,s),_,t)),h=be(__tsover_sub(p,s),p,t);return G1({overallMask:f,strokeBlend:N(n(0),h,a)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dist\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"strokeThickness\"},{type:\"i\",name:\"strokePosition\"}],body:[0,[[13,\"hasStroke\",[1,\"strokeThickness\",\">\",[5,\"0\"]]],[13,\"isInside\",[1,\"strokePosition\",\">=\",[5,\"1.5\"]]],[13,\"isCenterOrAbove\",[1,\"strokePosition\",\">=\",[5,\"0.5\"]]],[13,\"halfThickness\",[1,\"strokeThickness\",\"*\",[5,\"0.5\"]]],[13,\"negThickness\",[1,\"strokeThickness\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"negHalf\",[1,\"halfThickness\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"strokeInner\",[6,\"std.select\",[[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"negHalf\",\"isCenterOrAbove\"]],\"negThickness\",\"isInside\"]]],[13,\"strokeOuter\",[6,\"std.select\",[[6,\"std.select\",[\"strokeThickness\",\"halfThickness\",\"isCenterOrAbove\"]],[6,\"d.f32\",[[5,\"0\"]]],\"isInside\"]]],[13,\"overallMask\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"strokeOuter\",\"-\",\"softness\"],\"strokeOuter\",\"dist\"]]]],[13,\"blend\",[6,\"std.smoothstep\",[[1,\"strokeInner\",\"-\",\"softness\"],\"strokeInner\",\"dist\"]]],[13,\"strokeBlend\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"blend\",\"hasStroke\"]]],[10,[6,\"ShapeMask\",[[104,{overallMask:\"overallMask\",strokeBlend:\"strokeBlend\"}]]]]]]},externals:{\"std.select\":()=>N,\"d.f32\":()=>n,\"std.smoothstep\":()=>be,ShapeMask:()=>G1}})&&e.f)({}));function TB(e,t,s,r){let o=W(No[r]??Ar,\"mixColors\",[t,s,e.member(\"strokeBlend\")]);return Ct(o.member(\"rgb\"),o.member(\"a\").mul(e.member(\"overallMask\")))}async function dA(e,t){let s=await fetch(e,{mode:\"cors\"});if(!s.ok)throw new Error(`SDF fetch failed: HTTP ${s.status}`);let r=await s.arrayBuffer(),o=512*512;if(r.byteLength===o*2){let a=new Uint16Array(r),i=Math.min(a.length,t.length);for(let l=0;l<i;l++)t[l]=a[l]/32767.5-1}else if(r.byteLength===o*4){let a=new Float32Array(r),i=Math.min(a.length,t.length);for(let l=0;l<i;l++)t[l]=a[l]}else throw new Error(`SDF binary has unexpected size (${r.byteLength} bytes); expected ${o*2} (compact) or ${o*4} (legacy). The URL may point to a non-SDF file (e.g. the raw SVG).`)}function uA(e,t){let r=new Float32Array(262144).fill(.5),o=new Uint16Array(262144),a=_o(.5);for(let d=0;d<262144;d++)o[d]=a;let i=e.createDataTexture({width:512,height:512,format:\"r16float\",data:o,label:\"svg-sdf\"});e.onCleanup(()=>i.destroy());let l=!1,c=0;return t&&dA(t,r).then(()=>{for(let d=0;d<262144;d++)o[d]=_o(r[d]);l=!0}).catch(d=>di(\"[SDF] Failed to load SDF texture:\",d)),e.onBeforeRender(()=>{l&&(l=!1,i.write(o),c++)}),{kitTexture:e.registerMediaTexture(()=>i.texture),texture:i,getVersion:()=>c}}function SB(e,t){let{kitTexture:s}=uA(e,t);return r=>s.sampleLevel(r)}function PB(e,t){let o=new Float32Array(262144).fill(.5),a=new Uint16Array(262144*4),i=_o(.5),l=_o(1);for(let g=0;g<262144;g++)a[g*4]=i,a[g*4+3]=l;let c=e.createMediaTexture({width:512,height:512,format:\"rgba16float\",label:\"svg-sdf-grad\"});e.onCleanup(()=>c.destroy());let d=(g,y)=>{let b=Math.floor(g),x=Math.floor(y),P=g-b,C=y-x,E=D=>Math.min(Math.max(D,0),511),R=E(b),U=E(b+1),L=E(x),k=E(x+1);return o[L*512+R]*(1-P)*(1-C)+o[L*512+U]*P*(1-C)+o[k*512+R]*(1-P)*C+o[k*512+U]*P*C},u=.01,p=u*512,_=()=>{for(let g=0;g<512;g++)for(let y=0;y<512;y++){let b=g*512+y,x=o[b],P=(d(y+p,g)-x)/u,C=(d(y,g+p)-x)/u;a[b*4]=_o(x),a[b*4+1]=_o(P),a[b*4+2]=_o(C)}},f=!1;t&&dA(t,o).then(()=>{_(),f=!0}).catch(g=>di(\"[SDF] Failed to load SDF texture:\",g)),e.onBeforeRender(()=>{f&&(f=!1,c.write(a))});let h=e.registerMediaTexture(()=>c.texture);return g=>h.sampleLevel(g)}var CB=.008726646259971648;function P_(e){return w.fn([m,n,n,n,n,n,n,n,n],S)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=__tsover_sub(s.x,.5),_=__tsover_sub(s.y,.5),f=__tsover_mul(l,Rv),h=pe(f),g=ae(f),y=__tsover_add(__tsover_mul(p,h),__tsover_mul(_,g)),b=__tsover_sub(__tsover_mul(_,h),__tsover_mul(p,g)),x=n(0);return e===\"polygonSDF\"?x=K(Dv(y,b,r,o),Dm(y,b,r),a):e===\"flowerSDF\"?x=Lv(y,b,r,o,i):e===\"ringSDF\"?x=Ov(y,b,r,i):e===\"crossSDF\"?x=Gv(y,b,r,i,a):e===\"starSDF\"?x=Uv(y,b,r,o,i):e===\"roundedRectSDF\"?x=Fv(y,b,r,c,a):e===\"ellipseSDF\"?x=Iv(y,b,r,c):e===\"vesicaSDF\"?x=Yv(y,b,r,i):e===\"crescentSDF\"?x=Wv(y,b,r,i,d):e===\"trapezoidSDF\"?x=qv(y,b,i,r,c):e===\"heartSDF\"?x=Vv(y,b,r):e===\"arcSDF\"?x=Nv(y,b,r,__tsover_mul(u,.008726646259971648)):e===\"teardropSDF\"?x=$v(y,b,r,c):e===\"parallelogramSDF\"?x=Xv(y,b,r,c,d):x=Dm(y,b,r),S(x,0,0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"round\"},{type:\"i\",name:\"inner\"},{type:\"i\",name:\"rot\"},{type:\"i\",name:\"h\"},{type:\"i\",name:\"off\"},{type:\"i\",name:\"ap\"}],body:[0,[[13,\"dx\",[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]],[13,\"rotRad\",[1,\"rot\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rdx\",[1,[1,\"dx\",\"*\",\"cosR\"],\"+\",[1,\"dy\",\"*\",\"sinR\"]]],[13,\"rdy\",[1,[1,\"dy\",\"*\",\"cosR\"],\"-\",[1,\"dx\",\"*\",\"sinR\"]]],[12,\"dist\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"polygonSDF\"]],[2,\"dist\",\"=\",[6,\"std.mix\",[[6,\"polygonSdf\",[\"rdx\",\"rdy\",\"r\",\"n\"]],[6,\"circleSdf\",[\"rdx\",\"rdy\",\"r\"]],\"round\"]]],[11,[1,\"shapeType\",\"===\",[103,\"flowerSDF\"]],[2,\"dist\",\"=\",[6,\"flowerSdf\",[\"rdx\",\"rdy\",\"r\",\"n\",\"inner\"]]],[11,[1,\"shapeType\",\"===\",[103,\"ringSDF\"]],[2,\"dist\",\"=\",[6,\"ringSdf\",[\"rdx\",\"rdy\",\"r\",\"inner\"]]],[11,[1,\"shapeType\",\"===\",[103,\"crossSDF\"]],[2,\"dist\",\"=\",[6,\"crossSdf\",[\"rdx\",\"rdy\",\"r\",\"inner\",\"round\"]]],[11,[1,\"shapeType\",\"===\",[103,\"starSDF\"]],[2,\"dist\",\"=\",[6,\"starSdf\",[\"rdx\",\"rdy\",\"r\",\"n\",\"inner\"]]],[11,[1,\"shapeType\",\"===\",[103,\"roundedRectSDF\"]],[2,\"dist\",\"=\",[6,\"roundedRectSdf\",[\"rdx\",\"rdy\",\"r\",\"h\",\"round\"]]],[11,[1,\"shapeType\",\"===\",[103,\"ellipseSDF\"]],[2,\"dist\",\"=\",[6,\"ellipseSdf\",[\"rdx\",\"rdy\",\"r\",\"h\"]]],[11,[1,\"shapeType\",\"===\",[103,\"vesicaSDF\"]],[2,\"dist\",\"=\",[6,\"vesicaSdf\",[\"rdx\",\"rdy\",\"r\",\"inner\"]]],[11,[1,\"shapeType\",\"===\",[103,\"crescentSDF\"]],[2,\"dist\",\"=\",[6,\"crescentSdf\",[\"rdx\",\"rdy\",\"r\",\"inner\",\"off\"]]],[11,[1,\"shapeType\",\"===\",[103,\"trapezoidSDF\"]],[2,\"dist\",\"=\",[6,\"trapezoidSdf\",[\"rdx\",\"rdy\",\"inner\",\"r\",\"h\"]]],[11,[1,\"shapeType\",\"===\",[103,\"heartSDF\"]],[2,\"dist\",\"=\",[6,\"heartSdf\",[\"rdx\",\"rdy\",\"r\"]]],[11,[1,\"shapeType\",\"===\",[103,\"arcSDF\"]],[2,\"dist\",\"=\",[6,\"arcSdf\",[\"rdx\",\"rdy\",\"r\",[1,\"ap\",\"*\",\"APERTURE_TO_HALFANGLE\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"teardropSDF\"]],[2,\"dist\",\"=\",[6,\"teardropSdf\",[\"rdx\",\"rdy\",\"r\",\"h\"]]],[11,[1,\"shapeType\",\"===\",[103,\"parallelogramSDF\"]],[2,\"dist\",\"=\",[6,\"parallelogramSdf\",[\"rdx\",\"rdy\",\"r\",\"h\",\"off\"]]],[2,\"dist\",\"=\",[6,\"circleSdf\",[\"rdx\",\"rdy\",\"r\"]]]]]]]]]]]]]]]]],[10,[6,\"d.vec4f\",[\"dist\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{DEG_TO_RAD:()=>Rv,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.f32\":()=>n,shapeType:()=>e,\"std.mix\":()=>K,polygonSdf:()=>Dv,circleSdf:()=>Dm,flowerSdf:()=>Lv,ringSdf:()=>Ov,crossSdf:()=>Gv,starSdf:()=>Uv,roundedRectSdf:()=>Fv,ellipseSdf:()=>Iv,vesicaSdf:()=>Yv,crescentSdf:()=>Wv,trapezoidSdf:()=>qv,heartSdf:()=>Vv,arcSdf:()=>Nv,APERTURE_TO_HALFANGLE:()=>.008726646259971648,teardropSdf:()=>$v,parallelogramSdf:()=>Xv,\"d.vec4f\":()=>S}})&&t.f)({})).$name(`analyticSdf_${e}`)}function MB(e,t,s=\"none\"){let r=t.radius??$e(0),o=t.sides??$e(0),a=t.rounding??$e(0),i=t.innerRatio??$e(0),l=t.rotation??$e(0),c=t.height??$e(0),d=t.offset??$e(0),u=t.aperture??$e(0),p=P_(e);return _=>W(p,`analyticSdf_${e}`,[_,r,o,a,i,l,c,d,u])}var sne={_saRadius:{schema:n,initial:.35},_saSides:{schema:n,initial:6},_saRounding:{schema:n,initial:0},_saInnerRatio:{schema:n,initial:.4},_saRotation:{schema:n,initial:0},_saHeight:{schema:n,initial:.25},_saOffset:{schema:n,initial:.2},_saAperture:{schema:n,initial:270}};function Hv(e){let t=(s,r)=>typeof s==\"number\"?s:r;return{radius:t(e.radius,t(e.width,t(e.bottomWidth,.35))),sides:t(e.sides,6),rounding:t(e.rounding,0),innerRatio:t(e.innerRatio,t(e.thickness,t(e.spread,t(e.topWidth,t(e.topRatio,.4))))),rotation:t(e.rotation,0),height:t(e.height,.25),offset:t(e.offset,t(e.skew,.2)),aperture:t(e.aperture,270)}}function jv(e){if(e&&typeof e==\"object\")return e;if(typeof e==\"string\")try{return JSON.parse(e)}catch{return{}}return{}}function EB(e,t){let s=\"\",r=jv(t()),o=()=>{let i=Hv(r);e.setExtraField(\"_saRadius\",i.radius),e.setExtraField(\"_saSides\",i.sides),e.setExtraField(\"_saRounding\",i.rounding),e.setExtraField(\"_saInnerRatio\",i.innerRatio),e.setExtraField(\"_saRotation\",i.rotation),e.setExtraField(\"_saHeight\",i.height),e.setExtraField(\"_saOffset\",i.offset),e.setExtraField(\"_saAperture\",i.aperture)};e.onBeforeRender(()=>{let i=t();if(i&&typeof i==\"object\")r=i;else if(typeof i==\"string\"&&i!==s){s=i;try{r=JSON.parse(i)}catch{return}}o()});let a=e.uniforms;return{radius:a._saRadius,sides:a._saSides,rounding:a._saRounding,innerRatio:a._saInnerRatio,rotation:a._saRotation,height:a._saHeight,offset:a._saOffset,aperture:a._saAperture}}var Ki=512,td={},Qb=new Set,Zb={};function Kh(e,t){return e?e in td?td[e]:(t&&(Zb[e]??=[]).push(t),Qb.has(e)||(Qb.add(e),rne(e)),null):null}async function rne(e){try{let t=await fetch(e,{mode:\"cors\"});if(!t.ok){td[e]=null;return}let s=await t.arrayBuffer(),r=Ki*Ki;if(s.byteLength!==r*2&&s.byteLength!==r*4){td[e]=null;return}let o=s.byteLength===r*2?(()=>{let d=new Uint16Array(s);return u=>d[u]/32767.5-1})():(()=>{let d=new Float32Array(s);return u=>d[u]})(),a=Ki,i=Ki,l=-1,c=-1;for(let d=0;d<Ki;d++){let u=d*Ki;for(let p=0;p<Ki;p++)o(u+p)<0&&(p<a&&(a=p),p>l&&(l=p),d<i&&(i=d),d>c&&(c=d))}td[e]=l<0?null:{hwf:(l-a+1)/Ki/2,hhf:(c-i+1)/Ki/2}}catch{td[e]=null}finally{Qb.delete(e);let t=Zb[e];if(t){delete Zb[e];for(let s of t)s()}}}function kB(e){return!!e&&e in td}var fP=1/60;function C_(e,t,s,r,o,a){if(r===0&&o===0)return[s,0];let i=200*Math.pow(.01,r),l=2*Math.sqrt(i)*(1-o*.85),c=a>fP?Math.ceil(a/fP):1,d=a/c,u=e,p=t;for(let _=0;_<c;_++){let f=i*(s-u);p+=(f-l*p)*d,u+=p*d}return[u,p]}function one(e){return e<1/2.75?7.5625*e*e:e<2/2.75?(e-=1.5/2.75,7.5625*e*e+.75):e<2.5/2.75?(e-=2.25/2.75,7.5625*e*e+.9375):(e-=2.625/2.75,7.5625*e*e+.984375)}function pA(e,t){switch(t){case\"linear\":return e;case\"quad\":return e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2;case\"expo\":return e===0?0:e===1?1:e<.5?Math.pow(2,20*e-10)/2:(2-Math.pow(2,-20*e+10))/2;case\"bounce\":return one(e);default:return(1-Math.cos(Math.PI*e))/2}}function BB(e,t,s){let r=s.pixelRatio||1,o=Math.max(1,Math.floor(s.maxTextureDim/r)-1),a=Math.min(e,s.viewportWidth,o),i=Math.min(t,s.viewportHeight,o),l=Math.min(a/e,i/t,1);return{width:Math.max(1,Math.round(e*l)),height:Math.max(1,Math.round(t*l))}}function zB(e,t,s,r){return e!=null?(r-e)/1e3:t+s}function RB(e,t){let{lastRenderTime:s,isVisible:r,forceFullFrameRate:o,minInterval:a=0}=t,i=s>0?(e-s)/1e3:.016;if(s>0){let l=e-s;if(!r&&!o&&l<1e3)return{render:!1,deltaTime:i};if((r||o)&&l<Math.max(15.666666666666668,a))return{render:!1,deltaTime:i}}return{render:!0,deltaTime:Math.min(i,.1)}}async function mA(e){try{let t=e.device?.queue;if(t&&typeof t.onSubmittedWorkDone==\"function\"){await t.onSubmittedWorkDone();return}}catch{}await new Promise(t=>setTimeout(t,16))}function DB(e){e.updateDrivers(),e.ensureComposition()&&(e.beforeRender(),e.flush(),e.render()!==!1&&e.markReady(),e.afterRender())}function LB(e){let t=null,s=a=>typeof requestAnimationFrame==\"function\"?requestAnimationFrame(a):setTimeout(()=>a(performance.now()),16),r=a=>{typeof cancelAnimationFrame==\"function\"?cancelAnimationFrame(a):clearTimeout(a)},o=a=>{e(a),t!==null&&(t=s(o))};return{start(){t===null&&(t=s(o))},stop(){t!==null&&(r(t),t=null)},get running(){return t!==null}}}var UB=[\"sphere3D\",\"cube3D\",\"torus3D\",\"octahedron3D\",\"cylinder3D\",\"capsule3D\",\"cone3D\",\"pyramid3D\",\"prism3D\",\"ellipsoid3D\",\"diamond3D\",\"link3D\",\"gem3D\",\"helix3D\",\"metaballs3D\",\"dodecahedron3D\",\"hemisphere3D\",\"ribbon3D\",\"blob3D\",\"gyroscope3D\"];function OB(e){return UB.includes(e)}function GB(e){return e===\"svgExtrude3D\"}var FB={depth:.12,bevel:.02,rotX:15,rotY:30,rotZ:0};function IB(e,t){if(typeof e==\"number\")return e;if(e&&typeof e==\"object\"&&(e.type===\"auto-animate\"||e.type===\"mouse\")){let s=typeof e.outputMin==\"number\"?e.outputMin:t,r=typeof e.outputMax==\"number\"?e.outputMax:t;return Math.max(s,r)}return t}var YB={sphere3D:{radius:.35,rotX:0,rotY:0,rotZ:0},cube3D:{sizeX:.27,sizeY:.27,sizeZ:.27,rounding:.02,rotX:25,rotY:35,rotZ:0},torus3D:{radius:.3,tube:.12,rotX:55,rotY:0,rotZ:0},octahedron3D:{radius:.42,rotX:10,rotY:25,rotZ:0},cylinder3D:{radius:.22,height:.26,rounding:.02,rotX:60,rotY:0,rotZ:30},capsule3D:{radius:.16,height:.2,rotX:0,rotY:0,rotZ:35},cone3D:{radius:.3,topRadius:.02,height:.3,rotX:25,rotY:0,rotZ:15},pyramid3D:{size:.3,height:.45,rotX:-10,rotY:30,rotZ:0},prism3D:{radius:.28,height:.14,rotX:25,rotY:30,rotZ:0},ellipsoid3D:{radiusX:.38,radiusY:.22,radiusZ:.3,rotX:0,rotY:0,rotZ:20},diamond3D:{radius:.3,height:.42,rotX:15,rotY:0,rotZ:0},link3D:{radius:.18,length:.15,tube:.08,rotX:20,rotY:30,rotZ:0},gem3D:{radius:.3,height:.32,facets:8,rotX:15,rotY:0,rotZ:0},helix3D:{radius:.22,tube:.06,pitch:.16,rotX:20,rotY:0,rotZ:0},metaballs3D:{balls:4,ballRadius:.16,spread:.2,blend:.12,speed:1,rotX:0,rotY:0,rotZ:0},dodecahedron3D:{radius:.34,rotX:20,rotY:10,rotZ:0},hemisphere3D:{radius:.4,cut:0,rotX:30,rotY:0,rotZ:0},ribbon3D:{width:.15,thickness:.03,length:.38,wave:.1,waveFrequency:7,twist:140,speed:1,rotX:12,rotY:18,rotZ:0},blob3D:{radius:.3,wobble:.07,wobbliness:5,speed:1,rotX:0,rotY:0,rotZ:0},gyroscope3D:{radius:.34,width:.1,thickness:.028,rounding:.006,core:.14,speed:1,rotX:15,rotY:0,rotZ:0}};function WB(e){let t=YB[e.type]??{},s=(r,o=.3)=>IB(e[r],t[r]??o);switch(e.type){case\"cube3D\":return Math.hypot(s(\"sizeX\"),s(\"sizeY\"),s(\"sizeZ\"))+s(\"rounding\",0);case\"torus3D\":return s(\"radius\")+s(\"tube\");case\"cylinder3D\":return Math.hypot(s(\"radius\"),s(\"height\"))+s(\"rounding\",0);case\"capsule3D\":return s(\"height\")+s(\"radius\");case\"cone3D\":return Math.hypot(Math.max(s(\"radius\"),s(\"topRadius\")),s(\"height\"));case\"pyramid3D\":return Math.hypot(s(\"size\")*Math.SQRT2,s(\"height\")*.5);case\"prism3D\":return Math.hypot(s(\"radius\")*1.1548,s(\"height\"));case\"ellipsoid3D\":return Math.max(s(\"radiusX\"),s(\"radiusY\"),s(\"radiusZ\"));case\"diamond3D\":return Math.max(s(\"radius\"),s(\"height\"));case\"link3D\":return s(\"length\")+s(\"radius\")+s(\"tube\");case\"gem3D\":return Math.max(s(\"radius\"),s(\"height\"));case\"helix3D\":return Math.hypot(s(\"radius\")+s(\"tube\"),s(\"pitch\")*3*.5+s(\"tube\"));case\"metaballs3D\":return s(\"spread\")+s(\"ballRadius\",.16)+s(\"blend\",.12);case\"dodecahedron3D\":return s(\"radius\")*1.32;case\"hemisphere3D\":return s(\"radius\");case\"ribbon3D\":return Math.hypot(s(\"length\",.38),s(\"wave\",.1)*1.2+Math.hypot(s(\"width\",.15),s(\"thickness\",.03)))+.01;case\"blob3D\":return s(\"radius\",.3)+s(\"wobble\",.07)+.02;case\"gyroscope3D\":return s(\"radius\",.34)+s(\"thickness\",.028)*.5+s(\"width\",.1)*.5+s(\"rounding\",.006);default:return s(\"radius\",.35)}}var is={propBindings:{x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"},rotation:{prop:\"rotation\",as:\"degrees\"}},computeBounds(e,t,s){let r=e.scale??1,o=typeof e.center?.x==\"number\"?e.center.x:.5,a=typeof e.center?.y==\"number\"?e.center.y:.5,{hwf:i,hhf:l}=Jb(e),c=r*s;return{centerXPx:o*t,centerYPx:a*s,widthPx:2*i*c,heightPx:2*l*c,rotationDeg:e.rotation??0}},writeBounds(e,t,s,r){let o={...t.center??{x:.5,y:.5},x:e.centerXPx/s,y:e.centerYPx/r},a=t.scale??1,i=ane(t)?Kv(t.shape):null;if(i&&a>0)return{center:o,rotation:e.rotationDeg,shape:JSON.stringify({...i,radius:Math.max(.001,e.widthPx/(2*a*r)),height:Math.max(.001,e.heightPx/(2*a*r))})};let{hwf:l}=Jb(t);return{center:o,scale:l>0?Math.max(.01,e.widthPx/(2*l*r)):.01,rotation:e.rotationDeg}}},pm=new Map;function Kv(e){if(typeof e!=\"string\")return e??null;if(pm.has(e))return pm.get(e);let t=null;try{t=JSON.parse(e)}catch{t=null}return pm.size>=64&&pm.clear(),pm.set(e,t),t}function ane(e){if(e.shapeSdfUrl)return!1;let t=Kv(e.shape)?.type;return t===\"roundedRectSDF\"||t===\"ellipseSDF\"}function Jb(e){if(e.shapeSdfUrl){let r=e._shapeBounds??Kh(e.shapeSdfUrl),o=r&&typeof r.hwf==\"number\"&&typeof r.hhf==\"number\"?{hwf:r.hwf,hhf:r.hhf}:{hwf:.5,hhf:.5},a=e.shapeType;if(typeof a==\"string\"&&GB(a)){let i=Kv(e.shape)??{},l=d=>IB(i[d],FB[d]??0),c=Math.hypot(o.hwf,o.hhf,l(\"depth\")*.5)+l(\"bevel\")+.02;return{hwf:c,hhf:c}}return o}let t=Kv(e.shape);if(!t||typeof t!=\"object\")return{hwf:.5,hhf:.5};if(typeof t.type==\"string\"&&OB(t.type)){let r=WB(t);return{hwf:r,hhf:r}}let s=typeof t.radius==\"number\"?t.radius:.35;switch(t.type){case\"roundedRectSDF\":case\"ellipseSDF\":return{hwf:s,hhf:typeof t.height==\"number\"?t.height:s};case\"ringSDF\":{let r=typeof t.thickness==\"number\"?t.thickness:0;return{hwf:s+r,hhf:s+r}}case\"trapezoidSDF\":{let r=typeof t.bottomWidth==\"number\"?t.bottomWidth:.3,o=typeof t.topWidth==\"number\"?t.topWidth:.2,a=typeof t.height==\"number\"?t.height:.25;return{hwf:Math.max(r,o),hhf:a}}case\"vesicaSDF\":{let r=typeof t.spread==\"number\"?Math.min(1,Math.max(0,t.spread)):.4;return{hwf:s*(1-r),hhf:s*Math.sqrt(Math.max(0,1-r*r))}}case\"teardropSDF\":return{hwf:s,hhf:((typeof t.height==\"number\"?t.height:.4)+s)/2};case\"parallelogramSDF\":{let r=typeof t.width==\"number\"?t.width:.32,o=typeof t.height==\"number\"?t.height:.22,a=typeof t.skew==\"number\"?t.skew:0;return{hwf:r+Math.abs(a),hhf:o}}default:return{hwf:s,hhf:s}}}function bc(e,t){if(e)return e;let s=t;if(typeof t==\"string\")try{s=JSON.parse(t)}catch{return\"circleSDF\"}if(s&&typeof s==\"object\"){let r=s.type;if(typeof r==\"string\"&&r)return r}return\"circleSDF\"}var kn=ko({HELIX_TURNS:()=>3,MAX_METABALLS:()=>8,MarchParams:()=>vl,RotStruct:()=>Ad,SHAPE3D_DEFAULTS:()=>Qv,SHAPE3D_TYPES:()=>qB,SVG3D_DEFAULTS:()=>NB,SVG3D_TYPES:()=>nne,SampleParams:()=>yx,VOLUMETRIC_FIELD_EXTRA_FIELDS:()=>pne,VOLUMETRIC_FIELD_FORMAT:()=>Zh,VOLUMETRIC_FIELD_RES:()=>HB,VOLUMETRIC_FIELD_RES_MOBILE:()=>768,boxFaceUV:()=>EA,buildFieldSampleGraph:()=>une,buildFieldSampleGraphArgs:()=>bA,buildRaymarchedField:()=>cne,buildRaymarchedFieldFn:()=>fA,buildVolumetricFieldKernel:()=>gA,buildVolumetricFieldSampler:()=>KB,capsuleSurfaceUV:()=>BA,createAnalytic2dExtrudeSetup:()=>QB,createAnalytic3dSdfSetup:()=>AA,createSvg3dSdfSetup:()=>wA,createVolumetricFieldCompute:()=>yA,createVolumetricFieldComputeNode:()=>_ne,eulerRotatePacked:()=>Hr,is3dShapeType:()=>M_,isMobileGpuViewport:()=>Rr,isSvg3dShapeType:()=>Qh,isVolumetricShapeType:()=>VB,makeVolumetricFieldLayout:()=>hA,makeVolumetricSvgFieldLayout:()=>jB,mobiusSurfaceUV:()=>RA,packedParamExtraFields:()=>UA,paramBoxSdf:()=>MA,paramCapsuleSdf:()=>kA,paramMobiusSdf:()=>zA,paramSphereSdf:()=>TA,paramTorusSdf:()=>PA,paramTwistedRibbonSdf:()=>DA,resolveActiveFieldRes:()=>vA,resolveShapeFieldSampler:()=>mne,resolveShapeSubProp:()=>_A,resolveVolumetricFieldRes:()=>E_,rotateVec3:()=>ja,rotateVecCpu:()=>Jl,sdBicone:()=>Zm,sdCappedCone:()=>ax,sdCapsule:()=>ox,sdCutSphere:()=>fx,sdDodecahedron:()=>_x,sdEllipsoid:()=>lx,sdFlatBand:()=>Am,sdGem:()=>ux,sdGyroscope:()=>gx,sdHelix:()=>px,sdHexPrism:()=>ix,sdLink:()=>cx,sdMetaballs:()=>mx,sdOctahedron:()=>sx,sdPyramid:()=>nx,sdRibbon:()=>vx,sdRoundBox:()=>xd,sdRoundCylinder:()=>rx,sdSphere:()=>ex,sdTorus:()=>tx,sdWobbleBlob:()=>hx,shape3dBoundingRadius:()=>XB,shapeSubPropMax:()=>$B,smin:()=>dx,sphereSurfaceUV:()=>SA,torusSurfaceUV:()=>CA,twistedRibbonSurfaceUV:()=>LA}),vP=3.141592653589793,sd=6.283185307179586,qB=[\"sphere3D\",\"cube3D\",\"torus3D\",\"octahedron3D\",\"cylinder3D\",\"capsule3D\",\"cone3D\",\"pyramid3D\",\"prism3D\",\"ellipsoid3D\",\"diamond3D\",\"link3D\",\"gem3D\",\"helix3D\",\"metaballs3D\",\"dodecahedron3D\",\"hemisphere3D\",\"ribbon3D\",\"blob3D\",\"gyroscope3D\"];function M_(e){return qB.includes(e)}var nne=[\"svgExtrude3D\"];function Qh(e){return e===\"svgExtrude3D\"}function VB(e){return M_(e)||Qh(e)}var NB={depth:.12,bevel:.02,rotX:15,rotY:30,rotZ:0},ine=e=>e<1/2.75?7.5625*e*e:e<2/2.75?(e-=1.5/2.75,7.5625*e*e+.75):e<2.5/2.75?(e-=2.25/2.75,7.5625*e*e+.9375):(e-=2.625/2.75,7.5625*e*e+.984375),lne=(e,t)=>{switch(t){case\"linear\":return e;case\"quad\":return e<.5?2*e*e:1-Math.pow(-2*e+2,2)/2;case\"expo\":return e===0?0:e===1?1:e<.5?Math.pow(2,20*e-10)/2:(2-Math.pow(2,-20*e+10))/2;case\"bounce\":return ine(e);default:return(1-Math.cos(Math.PI*e))/2}};function _A(e,t,s,r){if(typeof e==\"number\")return e;if(e&&typeof e==\"object\"){if(e.type===\"auto-animate\"){let o=(s.elapsed*(e.speed??1)*.2%1+1)%1,a=lne(e.mode===\"loop\"?o:o<.5?o*2:(1-o)*2,e.easing??e.waveform??\"sine\"),i=typeof e.outputMin==\"number\"?e.outputMin:t;return i+a*((typeof e.outputMax==\"number\"?e.outputMax:t)-i)}if(e.type===\"mouse\"){let o=e.axis===\"y\"?s.pointerY:s.pointerX,a=s.springs.get(r);a||(a={current:o,velocity:0},s.springs.set(r,a));let[i,l]=C_(a.current,a.velocity,o,e.smoothing??0,e.momentum??0,s.deltaTime);a.current=i,a.velocity=l;let c=Math.max(.001,i),d=typeof e.outputMin==\"number\"?e.outputMin:t,u=typeof e.outputMax==\"number\"?e.outputMax:t,p=Math.pow(2,-(e.curve??0)*2);return d+Math.pow(c,p)*(u-d)}}return t}function $B(e,t){if(typeof e==\"number\")return e;if(e&&typeof e==\"object\"&&(e.type===\"auto-animate\"||e.type===\"mouse\")){let s=typeof e.outputMin==\"number\"?e.outputMin:t,r=typeof e.outputMax==\"number\"?e.outputMax:t;return Math.max(s,r)}return t}var Qv={sphere3D:{radius:.35,rotX:0,rotY:0,rotZ:0},cube3D:{sizeX:.27,sizeY:.27,sizeZ:.27,rounding:.02,rotX:25,rotY:35,rotZ:0},torus3D:{radius:.3,tube:.12,rotX:55,rotY:0,rotZ:0},octahedron3D:{radius:.42,rotX:10,rotY:25,rotZ:0},cylinder3D:{radius:.22,height:.26,rounding:.02,rotX:60,rotY:0,rotZ:30},capsule3D:{radius:.16,height:.2,rotX:0,rotY:0,rotZ:35},cone3D:{radius:.3,topRadius:.02,height:.3,rotX:25,rotY:0,rotZ:15},pyramid3D:{size:.3,height:.45,rotX:-10,rotY:30,rotZ:0},prism3D:{radius:.28,height:.14,rotX:25,rotY:30,rotZ:0},ellipsoid3D:{radiusX:.38,radiusY:.22,radiusZ:.3,rotX:0,rotY:0,rotZ:20},diamond3D:{radius:.3,height:.42,rotX:15,rotY:0,rotZ:0},link3D:{radius:.18,length:.15,tube:.08,rotX:20,rotY:30,rotZ:0},gem3D:{radius:.3,height:.32,facets:8,rotX:15,rotY:0,rotZ:0},helix3D:{radius:.22,tube:.06,pitch:.16,rotX:20,rotY:0,rotZ:0},metaballs3D:{balls:4,ballRadius:.16,spread:.2,blend:.12,speed:1,rotX:0,rotY:0,rotZ:0},dodecahedron3D:{radius:.34,rotX:20,rotY:10,rotZ:0},hemisphere3D:{radius:.4,cut:0,rotX:30,rotY:0,rotZ:0},ribbon3D:{width:.15,thickness:.03,length:.38,wave:.1,waveFrequency:7,twist:140,speed:1,rotX:12,rotY:18,rotZ:0},blob3D:{radius:.3,wobble:.07,wobbliness:5,speed:1,rotX:0,rotY:0,rotZ:0},gyroscope3D:{radius:.34,width:.1,thickness:.028,rounding:.006,core:.14,speed:1,rotX:15,rotY:0,rotZ:0}};function XB(e){let t=Qv[e.type]??{},s=(r,o=.3)=>$B(e[r],t[r]??o);switch(e.type){case\"cube3D\":return Math.hypot(s(\"sizeX\"),s(\"sizeY\"),s(\"sizeZ\"))+s(\"rounding\",0);case\"torus3D\":return s(\"radius\")+s(\"tube\");case\"cylinder3D\":return Math.hypot(s(\"radius\"),s(\"height\"))+s(\"rounding\",0);case\"capsule3D\":return s(\"height\")+s(\"radius\");case\"cone3D\":return Math.hypot(Math.max(s(\"radius\"),s(\"topRadius\")),s(\"height\"));case\"pyramid3D\":return Math.hypot(s(\"size\")*Math.SQRT2,s(\"height\")*.5);case\"prism3D\":return Math.hypot(s(\"radius\")*1.1548,s(\"height\"));case\"ellipsoid3D\":return Math.max(s(\"radiusX\"),s(\"radiusY\"),s(\"radiusZ\"));case\"diamond3D\":return Math.max(s(\"radius\"),s(\"height\"));case\"link3D\":return s(\"length\")+s(\"radius\")+s(\"tube\");case\"gem3D\":return Math.max(s(\"radius\"),s(\"height\"));case\"helix3D\":return Math.hypot(s(\"radius\")+s(\"tube\"),s(\"pitch\")*3*.5+s(\"tube\"));case\"metaballs3D\":return s(\"spread\")+s(\"ballRadius\",.16)+s(\"blend\",.12);case\"dodecahedron3D\":return s(\"radius\")*1.32;case\"hemisphere3D\":return s(\"radius\");case\"ribbon3D\":return Math.hypot(s(\"length\",.38),s(\"wave\",.1)*1.2+Math.hypot(s(\"width\",.15),s(\"thickness\",.03)))+.01;case\"blob3D\":return s(\"radius\",.3)+s(\"wobble\",.07)+.02;case\"gyroscope3D\":return s(\"radius\",.34)+s(\"thickness\",.028)*.5+s(\"width\",.1)*.5+s(\"rounding\",.006);default:return s(\"radius\",.35)}}function Jl(e,t,s,r){let o=e*r.cy+s*r.sy,a=-e*r.sy+s*r.cy,i=t*r.cx-a*r.sx,l=t*r.sx+a*r.cx;return{x:o*r.cz-i*r.sz,y:o*r.sz+i*r.cz,z:l}}var ex=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_sub(he(t),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"}],body:[0,[[10,[1,[6,\"std.length\",[\"p\"]],\"-\",\"r\"]]]]},externals:{\"std.length\":()=>he}})&&e.f)({})),xd=w.fn([A,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=__tsover_add(__tsover_sub(re(t.x),s),a),l=__tsover_add(__tsover_sub(re(t.y),r),a),c=__tsover_add(__tsover_sub(re(t.z),o),a),d=he(A(B(i,0),B(l,0),B(c,0))),u=ye(B(i,B(l,c)),0);return __tsover_sub(__tsover_add(d,u),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"hx\"},{type:\"i\",name:\"hy\"},{type:\"i\",name:\"hz\"},{type:\"i\",name:\"rounding\"}],body:[0,[[13,\"qx\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"x\"]]],\"-\",\"hx\"],\"+\",\"rounding\"]],[13,\"qy\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"y\"]]],\"-\",\"hy\"],\"+\",\"rounding\"]],[13,\"qz\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"z\"]]],\"-\",\"hz\"],\"+\",\"rounding\"]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec3f\",[[6,\"std.max\",[\"qx\",[5,\"0\"]]],[6,\"std.max\",[\"qy\",[5,\"0\"]]],[6,\"std.max\",[\"qz\",[5,\"0\"]]]]]]]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",[6,\"std.max\",[\"qy\",\"qz\"]]]],[5,\"0\"]]]],[10,[1,[1,\"outer\",\"+\",\"inner\"],\"-\",\"rounding\"]]]]},externals:{\"std.abs\":()=>re,\"std.length\":()=>he,\"d.vec3f\":()=>A,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})),tx=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_sub(he(m(t.x,t.z)),s);return __tsover_sub(he(m(o,t.y)),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"ringR\"},{type:\"i\",name:\"tubeR\"}],body:[0,[[13,\"qx\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]],\"-\",\"ringR\"]],[10,[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"qx\",[7,\"p\",\"y\"]]]]],\"-\",\"tubeR\"]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})),sx=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_mul(__tsover_sub(__tsover_add(__tsover_add(re(t.x),re(t.y)),re(t.z)),s),.57735027)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"s\"}],body:[0,[[10,[1,[1,[1,[1,[6,\"std.abs\",[[7,\"p\",\"x\"]]],\"+\",[6,\"std.abs\",[[7,\"p\",\"y\"]]]],\"+\",[6,\"std.abs\",[[7,\"p\",\"z\"]]]],\"-\",\"s\"],\"*\",[5,\"0.57735027\"]]]]]},externals:{\"std.abs\":()=>re}})&&e.f)({})),rx=w.fn([A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_add(__tsover_sub(he(m(t.x,t.z)),s),o),i=__tsover_add(__tsover_sub(re(t.y),r),o),l=ye(B(a,i),0),c=he(m(B(a,0),B(i,0)));return __tsover_sub(__tsover_add(l,c),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"h\"},{type:\"i\",name:\"rounding\"}],body:[0,[[13,\"dx\",[1,[1,[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]],\"-\",\"r\"],\"+\",\"rounding\"]],[13,\"dy\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"y\"]]],\"-\",\"h\"],\"+\",\"rounding\"]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"dx\",\"dy\"]],[5,\"0\"]]]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"dx\",[5,\"0\"]]],[6,\"std.max\",[\"dy\",[5,\"0\"]]]]]]]],[10,[1,[1,\"inner\",\"+\",\"outer\"],\"-\",\"rounding\"]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.max\":()=>B}})&&e.f)({})),ox=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=G(t.y,__tsover_mul(r,-1),r);return __tsover_sub(he(A(t.x,__tsover_sub(t.y,o),t.z)),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"cyc\",[6,\"std.clamp\",[[7,\"p\",\"y\"],[1,\"h\",\"*\",[4,\"-\",[5,\"1\"]]],\"h\"]]],[10,[1,[6,\"std.length\",[[6,\"d.vec3f\",[[7,\"p\",\"x\"],[1,[7,\"p\",\"y\"],\"-\",\"cyc\"],[7,\"p\",\"z\"]]]]],\"-\",\"r\"]]]]},externals:{\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec3f\":()=>A}})&&e.f)({})),ax=w.fn([A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=he(m(t.x,t.z)),i=t.y,l=__tsover_sub(r,s),c=__tsover_mul(o,2),d=__tsover_sub(a,ye(a,N(r,s,i<0))),u=__tsover_sub(re(i),o),p=__tsover_add(__tsover_mul(__tsover_sub(r,a),l),__tsover_mul(__tsover_sub(o,i),c)),_=B(__tsover_add(__tsover_mul(l,l),__tsover_mul(c,c)),1e-6),f=G(__tsover_div(p,_),0,1),h=__tsover_add(__tsover_sub(a,r),__tsover_mul(l,f)),g=__tsover_add(__tsover_sub(i,o),__tsover_mul(c,f)),y=N(n(1),n(-1),u<0),b=N(n(1),y,h<0),x=__tsover_add(__tsover_mul(d,d),__tsover_mul(u,u)),P=__tsover_add(__tsover_mul(h,h),__tsover_mul(g,g));return __tsover_mul(b,Ue(ye(x,P)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r1\"},{type:\"i\",name:\"r2\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"qx\",[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]]],[13,\"qy\",[7,\"p\",\"y\"]],[13,\"k2x\",[1,\"r2\",\"-\",\"r1\"]],[13,\"k2y\",[1,\"h\",\"*\",[5,\"2\"]]],[13,\"cax\",[1,\"qx\",\"-\",[6,\"std.min\",[\"qx\",[6,\"std.select\",[\"r2\",\"r1\",[1,\"qy\",\"<\",[5,\"0\"]]]]]]]],[13,\"cay\",[1,[6,\"std.abs\",[\"qy\"]],\"-\",\"h\"]],[13,\"dotNum\",[1,[1,[1,\"r2\",\"-\",\"qx\"],\"*\",\"k2x\"],\"+\",[1,[1,\"h\",\"-\",\"qy\"],\"*\",\"k2y\"]]],[13,\"dotDen\",[6,\"std.max\",[[1,[1,\"k2x\",\"*\",\"k2x\"],\"+\",[1,\"k2y\",\"*\",\"k2y\"]],[5,\"0.000001\"]]]],[13,\"t\",[6,\"std.clamp\",[[1,\"dotNum\",\"/\",\"dotDen\"],[5,\"0\"],[5,\"1\"]]]],[13,\"cbx\",[1,[1,\"qx\",\"-\",\"r2\"],\"+\",[1,\"k2x\",\"*\",\"t\"]]],[13,\"cby\",[1,[1,\"qy\",\"-\",\"h\"],\"+\",[1,\"k2y\",\"*\",\"t\"]]],[13,\"sInner\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[1,\"cay\",\"<\",[5,\"0\"]]]]],[13,\"s\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"sInner\",[1,\"cbx\",\"<\",[5,\"0\"]]]]],[13,\"dca\",[1,[1,\"cax\",\"*\",\"cax\"],\"+\",[1,\"cay\",\"*\",\"cay\"]]],[13,\"dcb\",[1,[1,\"cbx\",\"*\",\"cbx\"],\"+\",[1,\"cby\",\"*\",\"cby\"]]],[10,[1,\"s\",\"*\",[6,\"std.sqrt\",[[6,\"std.min\",[\"dca\",\"dcb\"]]]]]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.min\":()=>ye,\"std.select\":()=>N,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.sqrt\":()=>Ue}})&&e.f)({})),nx=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(r,.5),a=Ue(__tsover_add(__tsover_mul(r,r),__tsover_mul(s,s))),i=__tsover_div(__tsover_add(__tsover_mul(r,re(t.x)),__tsover_mul(s,__tsover_sub(t.y,o))),a),l=__tsover_div(__tsover_add(__tsover_mul(r,re(t.z)),__tsover_mul(s,__tsover_sub(t.y,o))),a),c=__tsover_sub(__tsover_mul(t.y,-1),o);return B(B(i,l),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"ht\"}],body:[0,[[13,\"h2\",[1,\"ht\",\"*\",[5,\"0.5\"]]],[13,\"denom\",[6,\"std.sqrt\",[[1,[1,\"ht\",\"*\",\"ht\"],\"+\",[1,\"b\",\"*\",\"b\"]]]]],[13,\"dx\",[1,[1,[1,\"ht\",\"*\",[6,\"std.abs\",[[7,\"p\",\"x\"]]]],\"+\",[1,\"b\",\"*\",[1,[7,\"p\",\"y\"],\"-\",\"h2\"]]],\"/\",\"denom\"]],[13,\"dz\",[1,[1,[1,\"ht\",\"*\",[6,\"std.abs\",[[7,\"p\",\"z\"]]]],\"+\",[1,\"b\",\"*\",[1,[7,\"p\",\"y\"],\"-\",\"h2\"]]],\"/\",\"denom\"]],[13,\"dBase\",[1,[1,[7,\"p\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],\"-\",\"h2\"]],[10,[6,\"std.max\",[[6,\"std.max\",[\"dx\",\"dz\"]],\"dBase\"]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.abs\":()=>re,\"std.max\":()=>B}})&&e.f)({})),ix=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=-.8660254,a=.5,i=.57735,l=re(t.x),c=re(t.y),d=re(t.z),u=__tsover_mul(ye(__tsover_add(__tsover_mul(o,l),__tsover_mul(a,c)),0),2),p=__tsover_sub(l,__tsover_mul(u,o)),_=__tsover_sub(c,__tsover_mul(u,a)),f=G(p,__tsover_mul(__tsover_mul(i,s),-1),__tsover_mul(i,s)),h=__tsover_sub(p,f),g=__tsover_sub(_,s),y=__tsover_mul(Ue(__tsover_add(__tsover_mul(h,h),__tsover_mul(g,g))),no(__tsover_sub(_,s))),b=__tsover_sub(d,r),x=ye(B(y,b),0),P=he(m(B(y,0),B(b,0)));return __tsover_add(x,P)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"he\"}],body:[0,[[13,\"kx\",[4,\"-\",[5,\"0.8660254\"]]],[13,\"ky\",[5,\"0.5\"]],[13,\"kz\",[5,\"0.57735\"]],[13,\"ax\",[6,\"std.abs\",[[7,\"p\",\"x\"]]]],[13,\"ay\",[6,\"std.abs\",[[7,\"p\",\"y\"]]]],[13,\"az\",[6,\"std.abs\",[[7,\"p\",\"z\"]]]],[13,\"dk\",[1,[6,\"std.min\",[[1,[1,\"kx\",\"*\",\"ax\"],\"+\",[1,\"ky\",\"*\",\"ay\"]],[5,\"0\"]]],\"*\",[5,\"2\"]]],[13,\"px\",[1,\"ax\",\"-\",[1,\"dk\",\"*\",\"kx\"]]],[13,\"py\",[1,\"ay\",\"-\",[1,\"dk\",\"*\",\"ky\"]]],[13,\"cx\",[6,\"std.clamp\",[\"px\",[1,[1,\"kz\",\"*\",\"r\"],\"*\",[4,\"-\",[5,\"1\"]]],[1,\"kz\",\"*\",\"r\"]]]],[13,\"ex\",[1,\"px\",\"-\",\"cx\"]],[13,\"ey\",[1,\"py\",\"-\",\"r\"]],[13,\"dHex\",[1,[6,\"std.sqrt\",[[1,[1,\"ex\",\"*\",\"ex\"],\"+\",[1,\"ey\",\"*\",\"ey\"]]]],\"*\",[6,\"std.sign\",[[1,\"py\",\"-\",\"r\"]]]]],[13,\"dZ\",[1,\"az\",\"-\",\"he\"]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"dHex\",\"dZ\"]],[5,\"0\"]]]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"dHex\",[5,\"0\"]]],[6,\"std.max\",[\"dZ\",[5,\"0\"]]]]]]]],[10,[1,\"inner\",\"+\",\"outer\"]]]]},externals:{\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.clamp\":()=>G,\"std.sqrt\":()=>Ue,\"std.sign\":()=>no,\"std.max\":()=>B,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})),lx=w.fn([A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=he(A(__tsover_div(t.x,s),__tsover_div(t.y,r),__tsover_div(t.z,o))),i=he(A(__tsover_div(t.x,__tsover_mul(s,s)),__tsover_div(t.y,__tsover_mul(r,r)),__tsover_div(t.z,__tsover_mul(o,o))));return __tsover_div(__tsover_mul(a,__tsover_sub(a,1)),B(i,1e-6))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rx\"},{type:\"i\",name:\"ry\"},{type:\"i\",name:\"rz\"}],body:[0,[[13,\"k0\",[6,\"std.length\",[[6,\"d.vec3f\",[[1,[7,\"p\",\"x\"],\"/\",\"rx\"],[1,[7,\"p\",\"y\"],\"/\",\"ry\"],[1,[7,\"p\",\"z\"],\"/\",\"rz\"]]]]]],[13,\"k1\",[6,\"std.length\",[[6,\"d.vec3f\",[[1,[7,\"p\",\"x\"],\"/\",[1,\"rx\",\"*\",\"rx\"]],[1,[7,\"p\",\"y\"],\"/\",[1,\"ry\",\"*\",\"ry\"]],[1,[7,\"p\",\"z\"],\"/\",[1,\"rz\",\"*\",\"rz\"]]]]]]],[10,[1,[1,\"k0\",\"*\",[1,\"k0\",\"-\",[5,\"1\"]]],\"/\",[6,\"std.max\",[\"k1\",[5,\"0.000001\"]]]]]]]},externals:{\"std.length\":()=>he,\"d.vec3f\":()=>A,\"std.max\":()=>B}})&&e.f)({})),Zm=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=he(m(t.x,t.z)),a=re(t.y),i=__tsover_mul(s,-1),l=r,c=__tsover_sub(o,s),d=a,u=B(__tsover_add(__tsover_mul(i,i),__tsover_mul(l,l)),1e-6),p=G(__tsover_div(__tsover_add(__tsover_mul(c,i),__tsover_mul(d,l)),u),0,1),_=__tsover_sub(c,__tsover_mul(i,p)),f=__tsover_sub(d,__tsover_mul(l,p)),h=Ue(__tsover_add(__tsover_mul(_,_),__tsover_mul(f,f)));return __tsover_mul(h,no(__tsover_sub(__tsover_add(__tsover_mul(r,o),__tsover_mul(s,a)),__tsover_mul(s,r))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"qx\",[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]]],[13,\"qy\",[6,\"std.abs\",[[7,\"p\",\"y\"]]]],[13,\"abx\",[1,\"r\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"aby\",\"h\"],[13,\"apx\",[1,\"qx\",\"-\",\"r\"]],[13,\"apy\",\"qy\"],[13,\"den\",[6,\"std.max\",[[1,[1,\"abx\",\"*\",\"abx\"],\"+\",[1,\"aby\",\"*\",\"aby\"]],[5,\"0.000001\"]]]],[13,\"t\",[6,\"std.clamp\",[[1,[1,[1,\"apx\",\"*\",\"abx\"],\"+\",[1,\"apy\",\"*\",\"aby\"]],\"/\",\"den\"],[5,\"0\"],[5,\"1\"]]]],[13,\"dxx\",[1,\"apx\",\"-\",[1,\"abx\",\"*\",\"t\"]]],[13,\"dyy\",[1,\"apy\",\"-\",[1,\"aby\",\"*\",\"t\"]]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"dxx\",\"*\",\"dxx\"],\"+\",[1,\"dyy\",\"*\",\"dyy\"]]]]],[10,[1,\"dist\",\"*\",[6,\"std.sign\",[[1,[1,[1,\"h\",\"*\",\"qx\"],\"+\",[1,\"r\",\"*\",\"qy\"]],\"-\",[1,\"r\",\"*\",\"h\"]]]]]]]]},externals:{\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.sqrt\":()=>Ue,\"std.sign\":()=>no}})&&e.f)({})),cx=w.fn([A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=B(__tsover_sub(re(t.y),s),0),i=__tsover_sub(he(m(t.x,a)),r);return __tsover_sub(he(m(i,t.z)),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"le\"},{type:\"i\",name:\"r1\"},{type:\"i\",name:\"r2\"}],body:[0,[[13,\"qy\",[6,\"std.max\",[[1,[6,\"std.abs\",[[7,\"p\",\"y\"]]],\"-\",\"le\"],[5,\"0\"]]]],[13,\"ring\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],\"qy\"]]]],\"-\",\"r1\"]],[10,[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"ring\",[7,\"p\",\"z\"]]]]],\"-\",\"r2\"]]]]},externals:{\"std.max\":()=>B,\"std.abs\":()=>re,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})),dx=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=G(__tsover_add(__tsover_mul(__tsover_div(__tsover_sub(s,t),r),.5),.5),0,1);return __tsover_sub(K(s,t,o),__tsover_mul(__tsover_mul(r,o),__tsover_sub(1,o)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"a\"},{type:\"i\",name:\"b\"},{type:\"i\",name:\"k\"}],body:[0,[[13,\"h\",[6,\"std.clamp\",[[1,[1,[1,[1,\"b\",\"-\",\"a\"],\"/\",\"k\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[10,[1,[6,\"std.mix\",[\"b\",\"a\",\"h\"]],\"-\",[1,[1,\"k\",\"*\",\"h\"],\"*\",[1,[5,\"1\"],\"-\",\"h\"]]]]]]},externals:{\"std.clamp\":()=>G,\"std.mix\":()=>K}})&&e.f)({})),ux=w.fn([A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=Zm(t,s,r),i=he(m(t.x,t.z)),l=Xt(t.z,t.x),c=__tsover_div(sd,o),d=ie(__tsover_add(__tsover_div(l,c),.5)),u=__tsover_sub(l,__tsover_mul(d,c)),p=__tsover_mul(s,pe(__tsover_div(vP,o)));return B(B(a,__tsover_sub(__tsover_mul(i,pe(u)),p)),__tsover_sub(t.y,__tsover_mul(r,.45)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"h\"},{type:\"i\",name:\"sides\"}],body:[0,[[13,\"base\",[6,\"sdBicone\",[\"p\",\"r\",\"h\"]]],[13,\"lenXZ\",[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]]],[13,\"ang\",[6,\"std.atan2\",[[7,\"p\",\"z\"],[7,\"p\",\"x\"]]]],[13,\"sector\",[1,\"TWO_PI\",\"/\",\"sides\"]],[13,\"idx\",[6,\"std.floor\",[[1,[1,\"ang\",\"/\",\"sector\"],\"+\",[5,\"0.5\"]]]]],[13,\"ca\",[1,\"ang\",\"-\",[1,\"idx\",\"*\",\"sector\"]]],[13,\"ri\",[1,\"r\",\"*\",[6,\"std.cos\",[[1,\"PI\",\"/\",\"sides\"]]]]],[13,\"facet\",[1,[1,\"lenXZ\",\"*\",[6,\"std.cos\",[\"ca\"]]],\"-\",\"ri\"]],[13,\"dd\",[6,\"std.max\",[\"base\",\"facet\"]]],[13,\"table\",[1,[7,\"p\",\"y\"],\"-\",[1,\"h\",\"*\",[5,\"0.45\"]]]],[10,[6,\"std.max\",[\"dd\",\"table\"]]]]]},externals:{sdBicone:()=>Zm,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.atan2\":()=>Xt,TWO_PI:()=>sd,\"std.floor\":()=>ie,\"std.cos\":()=>pe,PI:()=>vP,\"std.max\":()=>B}})&&e.f)({})),px=w.fn([A,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Xt(t.z,t.x),l=ie(__tsover_add(__tsover_sub(__tsover_div(t.y,o),__tsover_div(i,sd)),.5)),c=__tsover_add(i,__tsover_mul(sd,l)),d=__tsover_mul(s,pe(c)),u=__tsover_div(__tsover_mul(o,c),sd),p=__tsover_mul(s,ae(c));return B(__tsover_sub(he(A(__tsover_sub(t.x,d),__tsover_sub(t.y,u),__tsover_sub(t.z,p))),r),__tsover_sub(re(t.y),__tsover_mul(__tsover_mul(o,a),.5)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"R\"},{type:\"i\",name:\"tube\"},{type:\"i\",name:\"pitch\"},{type:\"i\",name:\"turns\"}],body:[0,[[13,\"psi\",[6,\"std.atan2\",[[7,\"p\",\"z\"],[7,\"p\",\"x\"]]]],[13,\"k\",[6,\"std.floor\",[[1,[1,[1,[7,\"p\",\"y\"],\"/\",\"pitch\"],\"-\",[1,\"psi\",\"/\",\"TWO_PI\"]],\"+\",[5,\"0.5\"]]]]],[13,\"theta\",[1,\"psi\",\"+\",[1,\"TWO_PI\",\"*\",\"k\"]]],[13,\"ccx\",[1,\"R\",\"*\",[6,\"std.cos\",[\"theta\"]]]],[13,\"ccy\",[1,[1,\"pitch\",\"*\",\"theta\"],\"/\",\"TWO_PI\"]],[13,\"ccz\",[1,\"R\",\"*\",[6,\"std.sin\",[\"theta\"]]]],[13,\"dStrand\",[1,[6,\"std.length\",[[6,\"d.vec3f\",[[1,[7,\"p\",\"x\"],\"-\",\"ccx\"],[1,[7,\"p\",\"y\"],\"-\",\"ccy\"],[1,[7,\"p\",\"z\"],\"-\",\"ccz\"]]]]],\"-\",\"tube\"]],[13,\"slab\",[1,[6,\"std.abs\",[[7,\"p\",\"y\"]]],\"-\",[1,[1,\"pitch\",\"*\",\"turns\"],\"*\",[5,\"0.5\"]]]],[10,[6,\"std.max\",[\"dStrand\",\"slab\"]]]]]},externals:{\"std.atan2\":()=>Xt,\"std.floor\":()=>ie,TWO_PI:()=>sd,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.length\":()=>he,\"d.vec3f\":()=>A,\"std.abs\":()=>re,\"std.max\":()=>B}})&&e.f)({})),hP=Fe(A,8),gP=8,mx=w.fn([A,A,A,A,A,A,A,A,A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=hP();_[0]=A(s),_[1]=A(r),_[2]=A(o),_[3]=A(a),_[4]=A(i),_[5]=A(l),_[6]=A(c),_[7]=A(d);let f=__tsover_sub(he(t.sub(_[0])),u);for(let h=1;h<gP;h++)f=dx(f,__tsover_sub(he(t.sub(_[h])),u),p);return f}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"b0\"},{type:\"i\",name:\"b1\"},{type:\"i\",name:\"b2\"},{type:\"i\",name:\"b3\"},{type:\"i\",name:\"b4\"},{type:\"i\",name:\"b5\"},{type:\"i\",name:\"b6\"},{type:\"i\",name:\"b7\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"k\"}],body:[0,[[13,\"balls\",[6,\"MetaballArray\",[]]],[2,[8,\"balls\",[5,\"0\"]],\"=\",[6,\"d.vec3f\",[\"b0\"]]],[2,[8,\"balls\",[5,\"1\"]],\"=\",[6,\"d.vec3f\",[\"b1\"]]],[2,[8,\"balls\",[5,\"2\"]],\"=\",[6,\"d.vec3f\",[\"b2\"]]],[2,[8,\"balls\",[5,\"3\"]],\"=\",[6,\"d.vec3f\",[\"b3\"]]],[2,[8,\"balls\",[5,\"4\"]],\"=\",[6,\"d.vec3f\",[\"b4\"]]],[2,[8,\"balls\",[5,\"5\"]],\"=\",[6,\"d.vec3f\",[\"b5\"]]],[2,[8,\"balls\",[5,\"6\"]],\"=\",[6,\"d.vec3f\",[\"b6\"]]],[2,[8,\"balls\",[5,\"7\"]],\"=\",[6,\"d.vec3f\",[\"b7\"]]],[12,\"dd\",[1,[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[8,\"balls\",[5,\"0\"]]]]]],\"-\",\"r\"]],[14,[12,\"i\",[5,\"1\"]],[1,\"i\",\"<\",\"METABALL_COUNT\"],[102,\"++\",\"i\"],[0,[[2,\"dd\",\"=\",[6,\"smin\",[\"dd\",[1,[6,\"std.length\",[[6,[7,\"p\",\"sub\"],[[8,\"balls\",\"i\"]]]]],\"-\",\"r\"],\"k\"]]]]]],[10,\"dd\"]]]},externals:{MetaballArray:()=>hP,\"d.vec3f\":()=>A,\"std.length\":()=>he,METABALL_COUNT:()=>gP,smin:()=>dx}})&&e.f)({})),_x=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=A(re(t.x),re(t.y),re(t.z)),o=Se(r,A(0,.5257311,.8506508)),a=Se(r,A(.8506508,0,.5257311)),i=Se(r,A(.5257311,.8506508,0));return __tsover_sub(B(B(o,a),i),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"}],body:[0,[[13,\"q\",[6,\"d.vec3f\",[[6,\"std.abs\",[[7,\"p\",\"x\"]]],[6,\"std.abs\",[[7,\"p\",\"y\"]]],[6,\"std.abs\",[[7,\"p\",\"z\"]]]]]],[13,\"a\",[6,\"std.dot\",[\"q\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0.5257311\"],[5,\"0.8506508\"]]]]]],[13,\"b\",[6,\"std.dot\",[\"q\",[6,\"d.vec3f\",[[5,\"0.8506508\"],[5,\"0\"],[5,\"0.5257311\"]]]]]],[13,\"c\",[6,\"std.dot\",[\"q\",[6,\"d.vec3f\",[[5,\"0.5257311\"],[5,\"0.8506508\"],[5,\"0\"]]]]]],[10,[1,[6,\"std.max\",[[6,\"std.max\",[\"a\",\"b\"]],\"c\"]],\"-\",\"r\"]]]]},externals:{\"d.vec3f\":()=>A,\"std.abs\":()=>re,\"std.dot\":()=>Se,\"std.max\":()=>B}})&&e.f)({})),fx=w.fn([A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Ue(B(__tsover_sub(__tsover_mul(s,s),__tsover_mul(r,r)),0)),a=he(m(t.x,t.z)),i=t.y,l=B(__tsover_add(__tsover_mul(__tsover_mul(__tsover_sub(r,s),a),a),__tsover_mul(__tsover_mul(o,o),__tsover_sub(__tsover_add(r,s),__tsover_mul(i,2)))),__tsover_sub(__tsover_mul(r,a),__tsover_mul(o,i))),c=__tsover_sub(he(m(a,i)),s),d=__tsover_sub(r,i);return N(N(he(m(__tsover_sub(a,o),__tsover_sub(i,r))),d,a<o),c,l<0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"w\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[1,\"r\",\"*\",\"r\"],\"-\",[1,\"h\",\"*\",\"h\"]],[5,\"0\"]]]]]],[13,\"qx\",[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],[7,\"p\",\"z\"]]]]]],[13,\"qy\",[7,\"p\",\"y\"]],[13,\"s\",[6,\"std.max\",[[1,[1,[1,[1,\"h\",\"-\",\"r\"],\"*\",\"qx\"],\"*\",\"qx\"],\"+\",[1,[1,\"w\",\"*\",\"w\"],\"*\",[1,[1,\"h\",\"+\",\"r\"],\"-\",[1,\"qy\",\"*\",[5,\"2\"]]]]],[1,[1,\"h\",\"*\",\"qx\"],\"-\",[1,\"w\",\"*\",\"qy\"]]]]],[13,\"case0\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"qx\",\"qy\"]]]],\"-\",\"r\"]],[13,\"case1\",[1,\"h\",\"-\",\"qy\"]],[13,\"case2\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,\"qx\",\"-\",\"w\"],[1,\"qy\",\"-\",\"h\"]]]]]],[13,\"inner\",[6,\"std.select\",[\"case2\",\"case1\",[1,\"qx\",\"<\",\"w\"]]]],[10,[6,\"std.select\",[\"inner\",\"case0\",[1,\"s\",\"<\",[5,\"0\"]]]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.select\":()=>N}})&&e.f)({})),vx=w.fn([A,n,n,n,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=__tsover_mul(a,ae(__tsover_add(__tsover_mul(i,t.x),l))),f=__tsover_mul(__tsover_mul(a,.6),ae(__tsover_add(__tsover_mul(__tsover_mul(i,.8),t.x),c))),h=__tsover_sub(t.y,_),g=__tsover_sub(t.z,f),y=__tsover_add(__tsover_mul(d,t.x),u),b=pe(y),x=ae(y),P=__tsover_add(__tsover_mul(h,b),__tsover_mul(g,x)),C=__tsover_sub(__tsover_mul(g,b),__tsover_mul(h,x)),E=__tsover_mul(r,.4),R=__tsover_add(__tsover_sub(re(P),s),E),U=__tsover_add(__tsover_sub(re(C),r),E),L=__tsover_sub(__tsover_add(he(m(B(R,0),B(U,0))),ye(B(R,U),0)),E),k=__tsover_sub(re(t.x),o),D=__tsover_add(he(m(B(L,0),B(k,0))),ye(B(L,k),0));return __tsover_mul(D,p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"w\"},{type:\"i\",name:\"th\"},{type:\"i\",name:\"len\"},{type:\"i\",name:\"amp\"},{type:\"i\",name:\"freq\"},{type:\"i\",name:\"ph1\"},{type:\"i\",name:\"ph2\"},{type:\"i\",name:\"twRate\"},{type:\"i\",name:\"twPh\"},{type:\"i\",name:\"lip\"}],body:[0,[[13,\"yc\",[1,\"amp\",\"*\",[6,\"std.sin\",[[1,[1,\"freq\",\"*\",[7,\"p\",\"x\"]],\"+\",\"ph1\"]]]]],[13,\"zc\",[1,[1,\"amp\",\"*\",[5,\"0.6\"]],\"*\",[6,\"std.sin\",[[1,[1,[1,\"freq\",\"*\",[5,\"0.8\"]],\"*\",[7,\"p\",\"x\"]],\"+\",\"ph2\"]]]]],[13,\"qy\",[1,[7,\"p\",\"y\"],\"-\",\"yc\"]],[13,\"qz\",[1,[7,\"p\",\"z\"],\"-\",\"zc\"]],[13,\"ang\",[1,[1,\"twRate\",\"*\",[7,\"p\",\"x\"]],\"+\",\"twPh\"]],[13,\"c\",[6,\"std.cos\",[\"ang\"]]],[13,\"s\",[6,\"std.sin\",[\"ang\"]]],[13,\"ry\",[1,[1,\"qy\",\"*\",\"c\"],\"+\",[1,\"qz\",\"*\",\"s\"]]],[13,\"rz\",[1,[1,\"qz\",\"*\",\"c\"],\"-\",[1,\"qy\",\"*\",\"s\"]]],[13,\"round\",[1,\"th\",\"*\",[5,\"0.4\"]]],[13,\"bx\",[1,[1,[6,\"std.abs\",[\"ry\"]],\"-\",\"w\"],\"+\",\"round\"]],[13,\"by\",[1,[1,[6,\"std.abs\",[\"rz\"]],\"-\",\"th\"],\"+\",\"round\"]],[13,\"d2\",[1,[1,[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"bx\",[5,\"0\"]]],[6,\"std.max\",[\"by\",[5,\"0\"]]]]]]],\"+\",[6,\"std.min\",[[6,\"std.max\",[\"bx\",\"by\"]],[5,\"0\"]]]],\"-\",\"round\"]],[13,\"dx\",[1,[6,\"std.abs\",[[7,\"p\",\"x\"]]],\"-\",\"len\"]],[13,\"dd\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"d2\",[5,\"0\"]]],[6,\"std.max\",[\"dx\",[5,\"0\"]]]]]]],\"+\",[6,\"std.min\",[[6,\"std.max\",[\"d2\",\"dx\"]],[5,\"0\"]]]]],[10,[1,\"dd\",\"*\",\"lip\"]]]]},externals:{\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.abs\":()=>re,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})),hx=w.fn([A,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(t.x,o),a)),ae(__tsover_add(__tsover_mul(__tsover_mul(t.y,o),1.3),i))),__tsover_mul(ae(__tsover_add(__tsover_mul(__tsover_mul(t.y,o),.8),__tsover_mul(i,1.1))),ae(__tsover_add(__tsover_mul(__tsover_mul(t.z,o),1.1),__tsover_mul(a,.9))))),d=__tsover_sub(__tsover_sub(he(t),s),__tsover_mul(__tsover_mul(r,c),.5));return __tsover_mul(d,l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"r\"},{type:\"i\",name:\"amp\"},{type:\"i\",name:\"freq\"},{type:\"i\",name:\"ph1\"},{type:\"i\",name:\"ph2\"},{type:\"i\",name:\"lip\"}],body:[0,[[13,\"w\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"p\",\"x\"],\"*\",\"freq\"],\"+\",\"ph1\"]]],\"*\",[6,\"std.sin\",[[1,[1,[1,[7,\"p\",\"y\"],\"*\",\"freq\"],\"*\",[5,\"1.3\"]],\"+\",\"ph2\"]]]],\"+\",[1,[6,\"std.sin\",[[1,[1,[1,[7,\"p\",\"y\"],\"*\",\"freq\"],\"*\",[5,\"0.8\"]],\"+\",[1,\"ph2\",\"*\",[5,\"1.1\"]]]]],\"*\",[6,\"std.sin\",[[1,[1,[1,[7,\"p\",\"z\"],\"*\",\"freq\"],\"*\",[5,\"1.1\"]],\"+\",[1,\"ph1\",\"*\",[5,\"0.9\"]]]]]]]],[13,\"dd\",[1,[1,[6,\"std.length\",[\"p\"]],\"-\",\"r\"],\"-\",[1,[1,\"amp\",\"*\",\"w\"],\"*\",[5,\"0.5\"]]]],[10,[1,\"dd\",\"*\",\"lip\"]]]]},externals:{\"std.sin\":()=>ae,\"std.length\":()=>he}})&&e.f)({})),Am=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_add(__tsover_sub(re(__tsover_sub(t,r)),o),i),c=__tsover_add(__tsover_sub(re(s),a),i),d=he(m(B(l,0),B(c,0))),u=ye(B(l,c),0);return __tsover_sub(__tsover_add(d,u),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"radialDist\"},{type:\"i\",name:\"axialDist\"},{type:\"i\",name:\"R\"},{type:\"i\",name:\"ht\"},{type:\"i\",name:\"hw\"},{type:\"i\",name:\"rnd\"}],body:[0,[[13,\"bx\",[1,[1,[6,\"std.abs\",[[1,\"radialDist\",\"-\",\"R\"]]],\"-\",\"ht\"],\"+\",\"rnd\"]],[13,\"by\",[1,[1,[6,\"std.abs\",[\"axialDist\"]],\"-\",\"hw\"],\"+\",\"rnd\"]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"bx\",[5,\"0\"]]],[6,\"std.max\",[\"by\",[5,\"0\"]]]]]]]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"bx\",\"by\"]],[5,\"0\"]]]],[10,[1,[1,\"outer\",\"+\",\"inner\"],\"-\",\"rnd\"]]]]},externals:{\"std.abs\":()=>re,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})),gx=w.fn([A,n,n,n,n,n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_)=>{\"use gpu\";let f=__tsover_mul(r,.5),h=__tsover_mul(o,.5),g=__tsover_sub(he(t),i),y=__tsover_add(__tsover_mul(t.y,l),__tsover_mul(t.z,c)),b=__tsover_sub(__tsover_mul(t.z,l),__tsover_mul(t.y,c)),x=Am(he(m(t.x,b)),y,s,h,f,a),P=__tsover_sub(__tsover_mul(t.x,d),__tsover_mul(t.z,u)),C=__tsover_add(__tsover_mul(t.z,d),__tsover_mul(t.x,u)),E=Am(he(m(P,t.y)),C,__tsover_mul(s,.78),h,f,a),R=__tsover_add(__tsover_mul(t.x,p),__tsover_mul(t.y,_)),U=Am(he(m(__tsover_sub(__tsover_mul(t.y,p),__tsover_mul(t.x,_)),t.z)),R,__tsover_mul(s,.56),h,f,a);return ye(ye(g,x),ye(E,U))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"width\"},{type:\"i\",name:\"thick\"},{type:\"i\",name:\"rnd\"},{type:\"i\",name:\"core\"},{type:\"i\",name:\"c1\"},{type:\"i\",name:\"s1\"},{type:\"i\",name:\"c2\"},{type:\"i\",name:\"s2\"},{type:\"i\",name:\"c3\"},{type:\"i\",name:\"s3\"}],body:[0,[[13,\"hw\",[1,\"width\",\"*\",[5,\"0.5\"]]],[13,\"ht\",[1,\"thick\",\"*\",[5,\"0.5\"]]],[13,\"dCore\",[1,[6,\"std.length\",[\"p\"]],\"-\",\"core\"]],[13,\"p1y\",[1,[1,[7,\"p\",\"y\"],\"*\",\"c1\"],\"+\",[1,[7,\"p\",\"z\"],\"*\",\"s1\"]]],[13,\"p1z\",[1,[1,[7,\"p\",\"z\"],\"*\",\"c1\"],\"-\",[1,[7,\"p\",\"y\"],\"*\",\"s1\"]]],[13,\"d1\",[6,\"sdFlatBand\",[[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"p\",\"x\"],\"p1z\"]]]],\"p1y\",\"radius\",\"ht\",\"hw\",\"rnd\"]]],[13,\"p2x\",[1,[1,[7,\"p\",\"x\"],\"*\",\"c2\"],\"-\",[1,[7,\"p\",\"z\"],\"*\",\"s2\"]]],[13,\"p2z\",[1,[1,[7,\"p\",\"z\"],\"*\",\"c2\"],\"+\",[1,[7,\"p\",\"x\"],\"*\",\"s2\"]]],[13,\"d2\",[6,\"sdFlatBand\",[[6,\"std.length\",[[6,\"d.vec2f\",[\"p2x\",[7,\"p\",\"y\"]]]]],\"p2z\",[1,\"radius\",\"*\",[5,\"0.78\"]],\"ht\",\"hw\",\"rnd\"]]],[13,\"p3x\",[1,[1,[7,\"p\",\"x\"],\"*\",\"c3\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"s3\"]]],[13,\"p3y\",[1,[1,[7,\"p\",\"y\"],\"*\",\"c3\"],\"-\",[1,[7,\"p\",\"x\"],\"*\",\"s3\"]]],[13,\"d3\",[6,\"sdFlatBand\",[[6,\"std.length\",[[6,\"d.vec2f\",[\"p3y\",[7,\"p\",\"z\"]]]]],\"p3x\",[1,\"radius\",\"*\",[5,\"0.56\"]],\"ht\",\"hw\",\"rnd\"]]],[10,[6,\"std.min\",[[6,\"std.min\",[\"dCore\",\"d1\"]],[6,\"std.min\",[\"d2\",\"d3\"]]]]]]]},externals:{\"std.length\":()=>he,sdFlatBand:()=>Am,\"d.vec2f\":()=>m,\"std.min\":()=>ye}})&&e.f)({})),Ad=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cx:n,sx:n,cy:n,sy:n,cz:n,sz:n}),\"RotStruct\"),ja=w.fn([A,Ad],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_add(__tsover_mul(t.x,s.cy),__tsover_mul(t.z,s.sy)),o=__tsover_sub(__tsover_mul(t.z,s.cy),__tsover_mul(t.x,s.sy)),a=__tsover_sub(__tsover_mul(t.y,s.cx),__tsover_mul(o,s.sx)),i=__tsover_add(__tsover_mul(t.y,s.sx),__tsover_mul(o,s.cx));return A(__tsover_sub(__tsover_mul(r,s.cz),__tsover_mul(a,s.sz)),__tsover_add(__tsover_mul(r,s.sz),__tsover_mul(a,s.cz)),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"rot\"}],body:[0,[[13,\"x1\",[1,[1,[7,\"v\",\"x\"],\"*\",[7,\"rot\",\"cy\"]],\"+\",[1,[7,\"v\",\"z\"],\"*\",[7,\"rot\",\"sy\"]]]],[13,\"z1\",[1,[1,[7,\"v\",\"z\"],\"*\",[7,\"rot\",\"cy\"]],\"-\",[1,[7,\"v\",\"x\"],\"*\",[7,\"rot\",\"sy\"]]]],[13,\"y2\",[1,[1,[7,\"v\",\"y\"],\"*\",[7,\"rot\",\"cx\"]],\"-\",[1,\"z1\",\"*\",[7,\"rot\",\"sx\"]]]],[13,\"z2\",[1,[1,[7,\"v\",\"y\"],\"*\",[7,\"rot\",\"sx\"]],\"+\",[1,\"z1\",\"*\",[7,\"rot\",\"cx\"]]]],[13,\"x3\",[1,[1,\"x1\",\"*\",[7,\"rot\",\"cz\"]],\"-\",[1,\"y2\",\"*\",[7,\"rot\",\"sz\"]]]],[13,\"y3\",[1,[1,\"x1\",\"*\",[7,\"rot\",\"sz\"]],\"+\",[1,\"y2\",\"*\",[7,\"rot\",\"cz\"]]]],[10,[6,\"d.vec3f\",[\"x3\",\"y3\",\"z2\"]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({}));function fA(e,t=\"none\",s=\"span\"){let r=Rr()?64:96,o=Rr()?224:384,a=Rr()?140:220;return w.fn([m,Ad,n],S)((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c,d)=>{\"use gpu\";let u=A(__tsover_sub(l.x,.5),__tsover_sub(.5,l.y),-1.2),p=A(0,0,1),_=ja(u,c),f=ja(p,c),h=j(G(__tsover_mul(d,n(a)),n(r),n(o))),g=Se(_,f),y=Ue(B(__tsover_sub(Se(_,_),__tsover_mul(g,g)),0)),b=Ue(B(__tsover_sub(__tsover_mul(d,d),__tsover_mul(y,y)),0)),x=B(__tsover_sub(__tsover_mul(g,-1),b),0),P=__tsover_add(__tsover_add(__tsover_mul(g,-1),b),.01),C=x,E=x,R=n(10),U=n(0);for(let F=0;F<h;F++){let q=e(_.add(f.mul(C)));if(R=ye(R,q),q<0){U=n(1);break}if(C>P)break;E=C,C=__tsover_add(C,B(q,.002))}let L=R,k=n(0),D=n(0),O=__tsover_add(P,.4);if(U>.5){let F=E,q=C;for(let Q=0;Q<10;Q++){let te=__tsover_mul(__tsover_add(F,q),.5);e(_.add(f.mul(te)))>0?F=te:q=te}let Y=__tsover_mul(__tsover_add(F,q),.5),V=Y;if(s===\"firstLobe\"){let Q=q,te=__tsover_add(q,.002);for(let le=0;le<h;le++){let se=e(_.add(f.mul(te)));if(se>=0||(Q=te,te=__tsover_add(te,B(__tsover_mul(se,-1),.002)),te>P))break}let J=Q,oe=te;for(let le=0;le<10;le++){let se=__tsover_mul(__tsover_add(J,oe),.5);e(_.add(f.mul(se)))<0?J=se:oe=se}V=__tsover_mul(__tsover_add(J,oe),.5)}if(s===\"span\"){let Q=_.add(f.mul(P)),te=__tsover_add(__tsover_sub(P,x),.01),J=n(0),oe=n(0);for(let Te=0;Te<h;Te++){let de=e(Q.sub(f.mul(J)));if(de<0||J>te)break;oe=J,J=__tsover_add(J,B(de,.002))}let le=oe,se=J;for(let Te=0;Te<10;Te++){let de=__tsover_mul(__tsover_add(le,se),.5);e(Q.sub(f.mul(de)))>0?le=de:se=de}V=__tsover_sub(P,__tsover_mul(__tsover_add(le,se),.5))}let X=__tsover_mul(B(__tsover_sub(V,Y),0),.5);if(L=__tsover_mul(X,-1),O=Y,t===\"raw\"){let Q=_.add(f.mul(Y));k=__tsover_add(Q.x,__tsover_mul(Q.z,.7)),D=__tsover_add(Q.y,__tsover_mul(Q.z,.5))}if(t===\"triplanar\"){let Q=_.add(f.mul(Y)),te=.004,J=__tsover_sub(e(A(__tsover_add(Q.x,te),Q.y,Q.z)),e(A(__tsover_sub(Q.x,te),Q.y,Q.z))),oe=__tsover_sub(e(A(Q.x,__tsover_add(Q.y,te),Q.z)),e(A(Q.x,__tsover_sub(Q.y,te),Q.z))),le=__tsover_sub(e(A(Q.x,Q.y,__tsover_add(Q.z,te))),e(A(Q.x,Q.y,__tsover_sub(Q.z,te)))),se=re(J),Te=re(oe),de=re(le),xe=m(__tsover_add(Q.y,2.17),__tsover_add(Q.z,5.31)),Ae=m(__tsover_add(Q.z,7.73),__tsover_add(Q.x,1.13)),De=N(m(Q.x,Q.y),Ae,Te>=de),Ee=N(De,N(De,xe,se>=de),se>=Te);k=Ee.x,D=Ee.y}}return S(L,k,D,O)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fuv\"},{type:\"i\",name:\"rot\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"ro0\",[6,\"d.vec3f\",[[1,[7,\"fuv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[5,\"0.5\"],\"-\",[7,\"fuv\",\"y\"]],[4,\"-\",[5,\"1.2\"]]]]],[13,\"rd0\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"1\"]]]],[13,\"ro\",[6,\"rotateVec3\",[\"ro0\",\"rot\"]]],[13,\"rd\",[6,\"rotateVec3\",[\"rd0\",\"rot\"]]],[13,\"steps\",[6,\"d.i32\",[[6,\"std.clamp\",[[1,\"rBound\",\"*\",[6,\"d.f32\",[\"STEP_SCALE\"]]],[6,\"d.f32\",[\"STEP_MIN\"]],[6,\"d.f32\",[\"STEP_MAX\"]]]]]]],[13,\"b\",[6,\"std.dot\",[\"ro\",\"rd\"]]],[13,\"perp\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[6,\"std.dot\",[\"ro\",\"ro\"]],\"-\",[1,\"b\",\"*\",\"b\"]],[5,\"0\"]]]]]],[13,\"halfSpan\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[1,\"rBound\",\"*\",\"rBound\"],\"-\",[1,\"perp\",\"*\",\"perp\"]],[5,\"0\"]]]]]],[13,\"tStart\",[6,\"std.max\",[[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"-\",\"halfSpan\"],[5,\"0\"]]]],[13,\"tEnd\",[1,[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"+\",\"halfSpan\"],\"+\",[5,\"0.01\"]]],[12,\"t\",\"tStart\"],[12,\"tPrev\",\"tStart\"],[12,\"minD\",[6,\"d.f32\",[[5,\"10\"]]]],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"steps\"],[102,\"++\",\"i\"],[0,[[13,\"p\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"t\"]]]]],[13,\"dd\",[6,\"sdfFn\",[\"p\"]]],[2,\"minD\",\"=\",[6,\"std.min\",[\"minD\",\"dd\"]]],[11,[1,\"dd\",\"<\",[5,\"0\"]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[17]]]],[11,[1,\"t\",\">\",\"tEnd\"],[0,[[17]]]],[2,\"tPrev\",\"=\",\"t\"],[2,\"t\",\"=\",[1,\"t\",\"+\",[6,\"std.max\",[\"dd\",[5,\"0.002\"]]]]]]]],[12,\"fieldVal\",\"minD\"],[12,\"patternU\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"patternV\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"viewDepth\",[1,\"tEnd\",\"+\",[5,\"0.4\"]]],[11,[1,\"hit\",\">\",[5,\"0.5\"]],[0,[[12,\"eLo\",\"tPrev\"],[12,\"eHi\",\"t\"],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"10\"]],[102,\"++\",\"i\"],[0,[[13,\"mid\",[1,[1,\"eLo\",\"+\",\"eHi\"],\"*\",[5,\"0.5\"]]],[13,\"dm\",[6,\"sdfFn\",[[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"mid\"]]]]]]],[11,[1,\"dm\",\">\",[5,\"0\"]],[0,[[2,\"eLo\",\"=\",\"mid\"]]],[0,[[2,\"eHi\",\"=\",\"mid\"]]]]]]],[13,\"tEnter\",[1,[1,\"eLo\",\"+\",\"eHi\"],\"*\",[5,\"0.5\"]]],[12,\"tExit\",\"tEnter\"],[11,[1,\"chordMode\",\"===\",[103,\"firstLobe\"]],[0,[[12,\"sInPrev\",\"eHi\"],[12,\"sIn\",[1,\"eHi\",\"+\",[5,\"0.002\"]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"steps\"],[102,\"++\",\"i\"],[0,[[13,\"dd\",[6,\"sdfFn\",[[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"sIn\"]]]]]]],[11,[1,\"dd\",\">=\",[5,\"0\"]],[0,[[17]]]],[2,\"sInPrev\",\"=\",\"sIn\"],[2,\"sIn\",\"=\",[1,\"sIn\",\"+\",[6,\"std.max\",[[1,\"dd\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0.002\"]]]]],[11,[1,\"sIn\",\">\",\"tEnd\"],[0,[[17]]]]]]],[12,\"fLo\",\"sInPrev\"],[12,\"fHi\",\"sIn\"],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"10\"]],[102,\"++\",\"i\"],[0,[[13,\"mid\",[1,[1,\"fLo\",\"+\",\"fHi\"],\"*\",[5,\"0.5\"]]],[13,\"dm\",[6,\"sdfFn\",[[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"mid\"]]]]]]],[11,[1,\"dm\",\"<\",[5,\"0\"]],[0,[[2,\"fLo\",\"=\",\"mid\"]]],[0,[[2,\"fHi\",\"=\",\"mid\"]]]]]]],[2,\"tExit\",\"=\",[1,[1,\"fLo\",\"+\",\"fHi\"],\"*\",[5,\"0.5\"]]]]]],[11,[1,\"chordMode\",\"===\",[103,\"span\"]],[0,[[13,\"roB\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"tEnd\"]]]]],[13,\"span\",[1,[1,\"tEnd\",\"-\",\"tStart\"],\"+\",[5,\"0.01\"]]],[12,\"s\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"sPrev\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"steps\"],[102,\"++\",\"i\"],[0,[[13,\"p\",[6,[7,\"roB\",\"sub\"],[[6,[7,\"rd\",\"mul\"],[\"s\"]]]]],[13,\"dd\",[6,\"sdfFn\",[\"p\"]]],[11,[1,\"dd\",\"<\",[5,\"0\"]],[0,[[17]]]],[11,[1,\"s\",\">\",\"span\"],[0,[[17]]]],[2,\"sPrev\",\"=\",\"s\"],[2,\"s\",\"=\",[1,\"s\",\"+\",[6,\"std.max\",[\"dd\",[5,\"0.002\"]]]]]]]],[12,\"xLo\",\"sPrev\"],[12,\"xHi\",\"s\"],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"10\"]],[102,\"++\",\"i\"],[0,[[13,\"mid\",[1,[1,\"xLo\",\"+\",\"xHi\"],\"*\",[5,\"0.5\"]]],[13,\"dm\",[6,\"sdfFn\",[[6,[7,\"roB\",\"sub\"],[[6,[7,\"rd\",\"mul\"],[\"mid\"]]]]]]],[11,[1,\"dm\",\">\",[5,\"0\"]],[0,[[2,\"xLo\",\"=\",\"mid\"]]],[0,[[2,\"xHi\",\"=\",\"mid\"]]]]]]],[2,\"tExit\",\"=\",[1,\"tEnd\",\"-\",[1,[1,\"xLo\",\"+\",\"xHi\"],\"*\",[5,\"0.5\"]]]]]]],[13,\"halfChord\",[1,[6,\"std.max\",[[1,\"tExit\",\"-\",\"tEnter\"],[5,\"0\"]]],\"*\",[5,\"0.5\"]]],[2,\"fieldVal\",\"=\",[1,\"halfChord\",\"*\",[4,\"-\",[5,\"1\"]]]],[2,\"viewDepth\",\"=\",\"tEnter\"],[11,[1,\"patternMode\",\"===\",[103,\"raw\"]],[0,[[13,\"hp\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"tEnter\"]]]]],[2,\"patternU\",\"=\",[1,[7,\"hp\",\"x\"],\"+\",[1,[7,\"hp\",\"z\"],\"*\",[5,\"0.7\"]]]],[2,\"patternV\",\"=\",[1,[7,\"hp\",\"y\"],\"+\",[1,[7,\"hp\",\"z\"],\"*\",[5,\"0.5\"]]]]]]],[11,[1,\"patternMode\",\"===\",[103,\"triplanar\"]],[0,[[13,\"hp\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"tEnter\"]]]]],[13,\"e2\",[5,\"0.004\"]],[13,\"nlx\",[1,[6,\"sdfFn\",[[6,\"d.vec3f\",[[1,[7,\"hp\",\"x\"],\"+\",\"e2\"],[7,\"hp\",\"y\"],[7,\"hp\",\"z\"]]]]],\"-\",[6,\"sdfFn\",[[6,\"d.vec3f\",[[1,[7,\"hp\",\"x\"],\"-\",\"e2\"],[7,\"hp\",\"y\"],[7,\"hp\",\"z\"]]]]]]],[13,\"nly\",[1,[6,\"sdfFn\",[[6,\"d.vec3f\",[[7,\"hp\",\"x\"],[1,[7,\"hp\",\"y\"],\"+\",\"e2\"],[7,\"hp\",\"z\"]]]]],\"-\",[6,\"sdfFn\",[[6,\"d.vec3f\",[[7,\"hp\",\"x\"],[1,[7,\"hp\",\"y\"],\"-\",\"e2\"],[7,\"hp\",\"z\"]]]]]]],[13,\"nlz\",[1,[6,\"sdfFn\",[[6,\"d.vec3f\",[[7,\"hp\",\"x\"],[7,\"hp\",\"y\"],[1,[7,\"hp\",\"z\"],\"+\",\"e2\"]]]]],\"-\",[6,\"sdfFn\",[[6,\"d.vec3f\",[[7,\"hp\",\"x\"],[7,\"hp\",\"y\"],[1,[7,\"hp\",\"z\"],\"-\",\"e2\"]]]]]]],[13,\"anx\",[6,\"std.abs\",[\"nlx\"]]],[13,\"anyv\",[6,\"std.abs\",[\"nly\"]]],[13,\"anz\",[6,\"std.abs\",[\"nlz\"]]],[13,\"branch1\",[6,\"d.vec2f\",[[1,[7,\"hp\",\"y\"],\"+\",[5,\"2.17\"]],[1,[7,\"hp\",\"z\"],\"+\",[5,\"5.31\"]]]]],[13,\"branch2\",[6,\"d.vec2f\",[[1,[7,\"hp\",\"z\"],\"+\",[5,\"7.73\"]],[1,[7,\"hp\",\"x\"],\"+\",[5,\"1.13\"]]]]],[13,\"branch3\",[6,\"d.vec2f\",[[7,\"hp\",\"x\"],[7,\"hp\",\"y\"]]]],[13,\"branch23\",[6,\"std.select\",[\"branch3\",\"branch2\",[1,\"anyv\",\">=\",\"anz\"]]]],[13,\"innerPick\",[6,\"std.select\",[\"branch23\",\"branch1\",[1,\"anx\",\">=\",\"anz\"]]]],[13,\"pattern\",[6,\"std.select\",[\"branch23\",\"innerPick\",[1,\"anx\",\">=\",\"anyv\"]]]],[2,\"patternU\",\"=\",[7,\"pattern\",\"x\"]],[2,\"patternV\",\"=\",[7,\"pattern\",\"y\"]]]]]]]],[10,[6,\"d.vec4f\",[\"fieldVal\",\"patternU\",\"patternV\",\"viewDepth\"]]]]]},externals:{\"d.vec3f\":()=>A,rotateVec3:()=>ja,\"d.i32\":()=>j,\"std.clamp\":()=>G,\"d.f32\":()=>n,STEP_SCALE:()=>a,STEP_MIN:()=>r,STEP_MAX:()=>o,\"std.dot\":()=>Se,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,sdfFn:()=>e,\"std.min\":()=>ye,chordMode:()=>s,patternMode:()=>t,\"std.abs\":()=>re,\"d.vec2f\":()=>m,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&i.f)({})).$name(\"raymarchedField\")}function cne(e,t=\"none\",s=\"span\"){return fA(e,t,s)}var Zh=\"rgba32float\",HB=1536;function E_(){return Rr()?768:HB}var dne=[256,320,384,512,640,768,896,1024,1280,1536];function vA(e,t,s,r,o,a){if(!(r>0)||!(s>0))return o;let i=Rr()?.5:1,l=Math.max(e,t)*s*r*i,c=o;for(let d of dne){if(d>o)break;if(d>=l){c=d;break}}return a>0&&c<a&&l>a*.78&&(c=Math.min(a,o)),c}var vl=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({rot:UM(16,OM(32,Ad)),rBound:n,spanX:n,spanY:n,originX:n,originY:n,activeRes:M,pA:n,pB:n,pC:n,pD:n,mb0:A,mb1:A,mb2:A,mb3:A,mb4:A,mb5:A,mb6:A,mb7:A}),\"MarchParams\");function hA(){return{layout:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({field:{storageTexture:zt(Zh,\"write-only\")},params:{uniform:vl}}),\"layout\"),MarchParams:vl}}function gA(e,t){return w.fn([M,M])((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o)=>{\"use gpu\";let a=e.$.params,i=n(a.activeRes),l=t(m(__tsover_add(a.originX,__tsover_mul(__tsover_div(__tsover_add(n(r),.5),i),a.spanX)),__tsover_add(a.originY,__tsover_mul(__tsover_div(__tsover_add(n(o),.5),i),a.spanY))),a.rot,a.rBound);lt(e.$.field,fe(r,o),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"activeResF\",[6,\"d.f32\",[[7,\"p\",\"activeRes\"]]]],[13,\"uv\",[6,\"d.vec2f\",[[1,[7,\"p\",\"originX\"],\"+\",[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"activeResF\"],\"*\",[7,\"p\",\"spanX\"]]],[1,[7,\"p\",\"originY\"],\"+\",[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"activeResF\"],\"*\",[7,\"p\",\"spanY\"]]]]]],[13,\"field\",[6,\"marchFn\",[\"uv\",[7,\"p\",\"rot\"],[7,\"p\",\"rBound\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"field\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"field\"]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,\"d.vec2f\":()=>m,marchFn:()=>t,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe}})&&s.f)({})).$name(\"volumetricFieldMarch\")}var yx=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({originX:n,originY:n,spanX:n,spanY:n,activeResF:n,rBound:n}),\"SampleParams\");function une(){let e=(globalThis.__TYPEGPU_AUTONAME__??(s=>s))(w.bindGroupLayout({field:{texture:Zt(n),sampleType:\"unfilterable-float\"},params:{uniform:yx}}),\"sampleLayout\"),t=w.fn([n,n],S)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o)=>{\"use gpu\";let a=__tsover_sub(e.$.params.activeResF,1),i=M(G(r,n(0),a)),l=M(G(o,n(0),a));return Ye(e.$.field,fe(i,l),0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"xi\"},{type:\"i\",name:\"yi\"}],body:[0,[[13,\"maxT\",[1,[7,[7,[7,\"sampleLayout\",\"$\"],\"params\"],\"activeResF\"],\"-\",[5,\"1\"]]],[13,\"tx\",[6,\"d.u32\",[[6,\"std.clamp\",[\"xi\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"ty\",[6,\"d.u32\",[[6,\"std.clamp\",[\"yi\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[10,[6,\"std.textureLoad\",[[7,[7,\"sampleLayout\",\"$\"],\"field\"],[6,\"d.vec2u\",[\"tx\",\"ty\"]],[5,\"0\"]]]]]]},externals:{sampleLayout:()=>e,\"d.u32\":()=>M,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe}})&&s.f)({})).$name(\"fieldFetchTexel\");return{sampleLayout:e,fieldSample:w.fn([m],S)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=e.$.params,a=G(r.x,o.originX,__tsover_add(o.originX,o.spanX)),i=G(r.y,o.originY,__tsover_add(o.originY,o.spanY)),l=he(m(__tsover_sub(r.x,a),__tsover_sub(r.y,i))),c=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(a,o.originX),o.spanX),o.activeResF),.5),d=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(i,o.originY),o.spanY),o.activeResF),.5),u=ie(c),p=ie(d),_=__tsover_sub(c,u),f=__tsover_sub(d,p),h=__tsover_mul(_,_),g=__tsover_mul(h,_),y=__tsover_sub(__tsover_add(__tsover_mul(g,-.5),h),__tsover_mul(_,.5)),b=__tsover_add(__tsover_sub(__tsover_mul(g,1.5),__tsover_mul(h,2.5)),1),x=__tsover_add(__tsover_add(__tsover_mul(g,-1.5),__tsover_mul(h,2)),__tsover_mul(_,.5)),P=__tsover_sub(__tsover_mul(g,.5),__tsover_mul(h,.5)),C=__tsover_mul(f,f),E=__tsover_mul(C,f),R=__tsover_sub(__tsover_add(__tsover_mul(E,-.5),C),__tsover_mul(f,.5)),U=__tsover_add(__tsover_sub(__tsover_mul(E,1.5),__tsover_mul(C,2.5)),1),L=__tsover_add(__tsover_add(__tsover_mul(E,-1.5),__tsover_mul(C,2)),__tsover_mul(f,.5)),k=__tsover_sub(__tsover_mul(E,.5),__tsover_mul(C,.5)),D=t(__tsover_sub(u,1),__tsover_sub(p,1)),O=t(u,__tsover_sub(p,1)),F=t(__tsover_add(u,1),__tsover_sub(p,1)),q=t(__tsover_add(u,2),__tsover_sub(p,1)),Y=t(__tsover_sub(u,1),p),V=t(u,p),X=t(__tsover_add(u,1),p),Q=t(__tsover_add(u,2),p),te=t(__tsover_sub(u,1),__tsover_add(p,1)),J=t(u,__tsover_add(p,1)),oe=t(__tsover_add(u,1),__tsover_add(p,1)),le=t(__tsover_add(u,2),__tsover_add(p,1)),se=t(__tsover_sub(u,1),__tsover_add(p,2)),Te=t(u,__tsover_add(p,2)),de=t(__tsover_add(u,1),__tsover_add(p,2)),xe=t(__tsover_add(u,2),__tsover_add(p,2)),Ae=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(D.r,y),R),__tsover_mul(__tsover_mul(O.r,b),R)),__tsover_mul(__tsover_mul(F.r,x),R)),__tsover_mul(__tsover_mul(q.r,P),R)),__tsover_mul(__tsover_mul(Y.r,y),U)),__tsover_mul(__tsover_mul(V.r,b),U)),__tsover_mul(__tsover_mul(X.r,x),U)),__tsover_mul(__tsover_mul(Q.r,P),U)),__tsover_mul(__tsover_mul(te.r,y),L)),__tsover_mul(__tsover_mul(J.r,b),L)),__tsover_mul(__tsover_mul(oe.r,x),L)),__tsover_mul(__tsover_mul(le.r,P),L)),__tsover_mul(__tsover_mul(se.r,y),k)),__tsover_mul(__tsover_mul(Te.r,b),k)),__tsover_mul(__tsover_mul(de.r,x),k)),__tsover_mul(__tsover_mul(xe.r,P),k)),De=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(D.a,y),R),__tsover_mul(__tsover_mul(O.a,b),R)),__tsover_mul(__tsover_mul(F.a,x),R)),__tsover_mul(__tsover_mul(q.a,P),R)),__tsover_mul(__tsover_mul(Y.a,y),U)),__tsover_mul(__tsover_mul(V.a,b),U)),__tsover_mul(__tsover_mul(X.a,x),U)),__tsover_mul(__tsover_mul(Q.a,P),U)),__tsover_mul(__tsover_mul(te.a,y),L)),__tsover_mul(__tsover_mul(J.a,b),L)),__tsover_mul(__tsover_mul(oe.a,x),L)),__tsover_mul(__tsover_mul(le.a,P),L)),__tsover_mul(__tsover_mul(se.a,y),k)),__tsover_mul(__tsover_mul(Te.a,b),k)),__tsover_mul(__tsover_mul(de.a,x),k)),__tsover_mul(__tsover_mul(xe.a,P),k)),Ee=K(K(V,X,_),K(J,oe,_),f),ze=ye(ye(V.r,X.r),ye(J.r,oe.r)),Ie=B(B(V.r,X.r),B(J.r,oe.r)),ke=G(De,ye(ye(V.a,X.a),ye(J.a,oe.a)),B(B(V.a,X.a),B(J.a,oe.a))),Me=__tsover_add(G(Ae,ze,Ie),l);return S(K(Me,B(__tsover_sub(he(m(__tsover_sub(r.x,.5),__tsover_sub(r.y,.5))),o.rBound),Me),be(n(0),.25,l)),Ee.g,Ee.b,ke)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"p\",[7,[7,\"sampleLayout\",\"$\"],\"params\"]],[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],[7,\"p\",\"originX\"],[1,[7,\"p\",\"originX\"],\"+\",[7,\"p\",\"spanX\"]]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],[7,\"p\",\"originY\"],[1,[7,\"p\",\"originY\"],\"+\",[7,\"p\",\"spanY\"]]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"px\",[1,[1,[1,[1,\"uxc\",\"-\",[7,\"p\",\"originX\"]],\"/\",[7,\"p\",\"spanX\"]],\"*\",[7,\"p\",\"activeResF\"]],\"-\",[5,\"0.5\"]]],[13,\"py\",[1,[1,[1,[1,\"uyc\",\"-\",[7,\"p\",\"originY\"]],\"/\",[7,\"p\",\"spanY\"]],\"*\",[7,\"p\",\"activeResF\"]],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"px\"]]],[13,\"y0\",[6,\"std.floor\",[\"py\"]]],[13,\"fx\",[1,\"px\",\"-\",\"x0\"]],[13,\"fy\",[1,\"py\",\"-\",\"y0\"]],[13,\"tx2\",[1,\"fx\",\"*\",\"fx\"]],[13,\"tx3\",[1,\"tx2\",\"*\",\"fx\"]],[13,\"wx0\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"tx2\"],\"-\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx1\",[1,[1,[1,\"tx3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wx2\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"tx2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx3\",[1,[1,\"tx3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"0.5\"]]]],[13,\"ty2\",[1,\"fy\",\"*\",\"fy\"]],[13,\"ty3\",[1,\"ty2\",\"*\",\"fy\"]],[13,\"wy0\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"ty2\"],\"-\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy1\",[1,[1,[1,\"ty3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wy2\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"ty2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy3\",[1,[1,\"ty3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"0.5\"]]]],[13,\"k00\",[6,\"fetchTexel\",[[1,\"x0\",\"-\",[5,\"1\"]],[1,\"y0\",\"-\",[5,\"1\"]]]]],[13,\"k01\",[6,\"fetchTexel\",[\"x0\",[1,\"y0\",\"-\",[5,\"1\"]]]]],[13,\"k02\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],[1,\"y0\",\"-\",[5,\"1\"]]]]],[13,\"k03\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"2\"]],[1,\"y0\",\"-\",[5,\"1\"]]]]],[13,\"k10\",[6,\"fetchTexel\",[[1,\"x0\",\"-\",[5,\"1\"]],\"y0\"]]],[13,\"k11\",[6,\"fetchTexel\",[\"x0\",\"y0\"]]],[13,\"k12\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],\"y0\"]]],[13,\"k13\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"2\"]],\"y0\"]]],[13,\"k20\",[6,\"fetchTexel\",[[1,\"x0\",\"-\",[5,\"1\"]],[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"k21\",[6,\"fetchTexel\",[\"x0\",[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"k22\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"k23\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"2\"]],[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"k30\",[6,\"fetchTexel\",[[1,\"x0\",\"-\",[5,\"1\"]],[1,\"y0\",\"+\",[5,\"2\"]]]]],[13,\"k31\",[6,\"fetchTexel\",[\"x0\",[1,\"y0\",\"+\",[5,\"2\"]]]]],[13,\"k32\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],[1,\"y0\",\"+\",[5,\"2\"]]]]],[13,\"k33\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"2\"]],[1,\"y0\",\"+\",[5,\"2\"]]]]],[13,\"rAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"aAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"bl\",[6,\"std.mix\",[[6,\"std.mix\",[\"k11\",\"k12\",\"fx\"]],[6,\"std.mix\",[\"k21\",\"k22\",\"fx\"]],\"fy\"]]],[13,\"rMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.min\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"rMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.max\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"aMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.min\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.max\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aOut\",[6,\"std.clamp\",[\"aAcc\",\"aMin\",\"aMax\"]]],[13,\"rNear\",[1,[6,\"std.clamp\",[\"rAcc\",\"rMin\",\"rMax\"]],\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",[7,\"p\",\"rBound\"]]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[10,[6,\"d.vec4f\",[\"rOut\",[7,\"bl\",\"g\"],[7,\"bl\",\"b\"],\"aOut\"]]]]]},externals:{sampleLayout:()=>e,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,fetchTexel:()=>t,\"std.mix\":()=>K,\"std.min\":()=>ye,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.f32\":()=>n,\"d.vec4f\":()=>S}})&&s.f)({})).$name(\"fieldSample\"),fieldSampleFast:w.fn([m],S)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=e.$.params,a=G(r.x,o.originX,__tsover_add(o.originX,o.spanX)),i=G(r.y,o.originY,__tsover_add(o.originY,o.spanY)),l=he(m(__tsover_sub(r.x,a),__tsover_sub(r.y,i))),c=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(a,o.originX),o.spanX),o.activeResF),.5),d=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(i,o.originY),o.spanY),o.activeResF),.5),u=ie(c),p=ie(d),_=__tsover_sub(c,u),f=__tsover_sub(d,p),h=t(u,p),g=t(__tsover_add(u,1),p),y=t(u,__tsover_add(p,1)),b=t(__tsover_add(u,1),__tsover_add(p,1)),x=K(K(h,g,_),K(y,b,_),f),P=__tsover_add(x.r,l);return S(K(P,B(__tsover_sub(he(m(__tsover_sub(r.x,.5),__tsover_sub(r.y,.5))),o.rBound),P),be(n(0),.25,l)),x.g,x.b,x.a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"p\",[7,[7,\"sampleLayout\",\"$\"],\"params\"]],[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],[7,\"p\",\"originX\"],[1,[7,\"p\",\"originX\"],\"+\",[7,\"p\",\"spanX\"]]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],[7,\"p\",\"originY\"],[1,[7,\"p\",\"originY\"],\"+\",[7,\"p\",\"spanY\"]]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"px\",[1,[1,[1,[1,\"uxc\",\"-\",[7,\"p\",\"originX\"]],\"/\",[7,\"p\",\"spanX\"]],\"*\",[7,\"p\",\"activeResF\"]],\"-\",[5,\"0.5\"]]],[13,\"py\",[1,[1,[1,[1,\"uyc\",\"-\",[7,\"p\",\"originY\"]],\"/\",[7,\"p\",\"spanY\"]],\"*\",[7,\"p\",\"activeResF\"]],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"px\"]]],[13,\"y0\",[6,\"std.floor\",[\"py\"]]],[13,\"fx\",[1,\"px\",\"-\",\"x0\"]],[13,\"fy\",[1,\"py\",\"-\",\"y0\"]],[13,\"t00\",[6,\"fetchTexel\",[\"x0\",\"y0\"]]],[13,\"t10\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],\"y0\"]]],[13,\"t01\",[6,\"fetchTexel\",[\"x0\",[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"t11\",[6,\"fetchTexel\",[[1,\"x0\",\"+\",[5,\"1\"]],[1,\"y0\",\"+\",[5,\"1\"]]]]],[13,\"bl\",[6,\"std.mix\",[[6,\"std.mix\",[\"t00\",\"t10\",\"fx\"]],[6,\"std.mix\",[\"t01\",\"t11\",\"fx\"]],\"fy\"]]],[13,\"rNear\",[1,[7,\"bl\",\"r\"],\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",[7,\"p\",\"rBound\"]]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[10,[6,\"d.vec4f\",[\"rOut\",[7,\"bl\",\"g\"],[7,\"bl\",\"b\"],[7,\"bl\",\"a\"]]]]]]},externals:{sampleLayout:()=>e,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,fetchTexel:()=>t,\"std.mix\":()=>K,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.f32\":()=>n,\"d.vec4f\":()=>S}})&&s.f)({})).$name(\"fieldSampleFast\"),SampleParams:yx}}function yA(e,t,s,r,o={}){let a=E_(),i=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(e.createTexture({size:[a,a],format:Zh}).$usage(\"storage\",\"sampled\"),\"fieldTexture\"),l=o.paramsUniform??e.createUniform(vl);r(()=>i.destroy());let c=e.createBindGroup(t,{field:i,params:l.buffer,...o.sdfSourceTexture?{sdfSource:o.sdfSourceTexture}:{}}),d=wr(e,(p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";s(_,f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>s}})&&p.f)({}),{bindGroup:c});for(let p of o.extraBindGroups??[])d=d.with(p);let u=a;return{computeStep:d,fieldTexture:i,maxRes:a,get activeRes(){return u},writeParams(p){l.write(p)},dispatch(p){u=p,d.dispatchThreads(p,p)}}}function jB(){return{layout:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({field:{storageTexture:zt(Zh,\"write-only\")},params:{uniform:vl},sdfSource:{texture:Zt(n)}}),\"layout\"),MarchParams:vl}}function bA(){return{fieldSampleArg:w.fn([m,Zt(n),n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=G(t.x,r,__tsover_add(r,a)),u=G(t.y,o,__tsover_add(o,i)),p=he(m(__tsover_sub(t.x,d),__tsover_sub(t.y,u))),_=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(d,r),a),l),.5),f=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(u,o),i),l),.5),h=ie(_),g=ie(f),y=__tsover_sub(_,h),b=__tsover_sub(f,g),x=__tsover_mul(y,y),P=__tsover_mul(x,y),C=__tsover_sub(__tsover_add(__tsover_mul(P,-.5),x),__tsover_mul(y,.5)),E=__tsover_add(__tsover_sub(__tsover_mul(P,1.5),__tsover_mul(x,2.5)),1),R=__tsover_add(__tsover_add(__tsover_mul(P,-1.5),__tsover_mul(x,2)),__tsover_mul(y,.5)),U=__tsover_sub(__tsover_mul(P,.5),__tsover_mul(x,.5)),L=__tsover_mul(b,b),k=__tsover_mul(L,b),D=__tsover_sub(__tsover_add(__tsover_mul(k,-.5),L),__tsover_mul(b,.5)),O=__tsover_add(__tsover_sub(__tsover_mul(k,1.5),__tsover_mul(L,2.5)),1),F=__tsover_add(__tsover_add(__tsover_mul(k,-1.5),__tsover_mul(L,2)),__tsover_mul(b,.5)),q=__tsover_sub(__tsover_mul(k,.5),__tsover_mul(L,.5)),Y=__tsover_sub(l,1),V=M(G(__tsover_sub(h,1),n(0),Y)),X=M(G(h,n(0),Y)),Q=M(G(__tsover_add(h,1),n(0),Y)),te=M(G(__tsover_add(h,2),n(0),Y)),J=M(G(__tsover_sub(g,1),n(0),Y)),oe=M(G(g,n(0),Y)),le=M(G(__tsover_add(g,1),n(0),Y)),se=M(G(__tsover_add(g,2),n(0),Y)),Te=Ye(s,fe(V,J),0),de=Ye(s,fe(X,J),0),xe=Ye(s,fe(Q,J),0),Ae=Ye(s,fe(te,J),0),De=Ye(s,fe(V,oe),0),Ee=Ye(s,fe(X,oe),0),ze=Ye(s,fe(Q,oe),0),Ie=Ye(s,fe(te,oe),0),ke=Ye(s,fe(V,le),0),Me=Ye(s,fe(X,le),0),we=Ye(s,fe(Q,le),0),Ve=Ye(s,fe(te,le),0),qe=Ye(s,fe(V,se),0),st=Ye(s,fe(X,se),0),pt=Ye(s,fe(Q,se),0),Ze=Ye(s,fe(te,se),0),nt=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(Te.r,C),D),__tsover_mul(__tsover_mul(de.r,E),D)),__tsover_mul(__tsover_mul(xe.r,R),D)),__tsover_mul(__tsover_mul(Ae.r,U),D)),__tsover_mul(__tsover_mul(De.r,C),O)),__tsover_mul(__tsover_mul(Ee.r,E),O)),__tsover_mul(__tsover_mul(ze.r,R),O)),__tsover_mul(__tsover_mul(Ie.r,U),O)),__tsover_mul(__tsover_mul(ke.r,C),F)),__tsover_mul(__tsover_mul(Me.r,E),F)),__tsover_mul(__tsover_mul(we.r,R),F)),__tsover_mul(__tsover_mul(Ve.r,U),F)),__tsover_mul(__tsover_mul(qe.r,C),q)),__tsover_mul(__tsover_mul(st.r,E),q)),__tsover_mul(__tsover_mul(pt.r,R),q)),__tsover_mul(__tsover_mul(Ze.r,U),q)),ht=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(Te.a,C),D),__tsover_mul(__tsover_mul(de.a,E),D)),__tsover_mul(__tsover_mul(xe.a,R),D)),__tsover_mul(__tsover_mul(Ae.a,U),D)),__tsover_mul(__tsover_mul(De.a,C),O)),__tsover_mul(__tsover_mul(Ee.a,E),O)),__tsover_mul(__tsover_mul(ze.a,R),O)),__tsover_mul(__tsover_mul(Ie.a,U),O)),__tsover_mul(__tsover_mul(ke.a,C),F)),__tsover_mul(__tsover_mul(Me.a,E),F)),__tsover_mul(__tsover_mul(we.a,R),F)),__tsover_mul(__tsover_mul(Ve.a,U),F)),__tsover_mul(__tsover_mul(qe.a,C),q)),__tsover_mul(__tsover_mul(st.a,E),q)),__tsover_mul(__tsover_mul(pt.a,R),q)),__tsover_mul(__tsover_mul(Ze.a,U),q)),yt=K(K(Ee,ze,y),K(Me,we,y),b),St=ye(ye(Ee.r,ze.r),ye(Me.r,we.r)),Mt=B(B(Ee.r,ze.r),B(Me.r,we.r)),Rt=G(ht,ye(ye(Ee.a,ze.a),ye(Me.a,we.a)),B(B(Ee.a,ze.a),B(Me.a,we.a))),Kt=__tsover_add(G(nt,St,Mt),p);return S(K(Kt,B(__tsover_sub(he(m(__tsover_sub(t.x,.5),__tsover_sub(t.y,.5))),c),Kt),be(n(0),.25,p)),yt.g,yt.b,Rt)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"field\"},{type:\"i\",name:\"originX\"},{type:\"i\",name:\"originY\"},{type:\"i\",name:\"spanX\"},{type:\"i\",name:\"spanY\"},{type:\"i\",name:\"activeResF\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],\"originX\",[1,\"originX\",\"+\",\"spanX\"]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],\"originY\",[1,\"originY\",\"+\",\"spanY\"]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"px\",[1,[1,[1,[1,\"uxc\",\"-\",\"originX\"],\"/\",\"spanX\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"py\",[1,[1,[1,[1,\"uyc\",\"-\",\"originY\"],\"/\",\"spanY\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"px\"]]],[13,\"y0\",[6,\"std.floor\",[\"py\"]]],[13,\"fx\",[1,\"px\",\"-\",\"x0\"]],[13,\"fy\",[1,\"py\",\"-\",\"y0\"]],[13,\"tx2\",[1,\"fx\",\"*\",\"fx\"]],[13,\"tx3\",[1,\"tx2\",\"*\",\"fx\"]],[13,\"wx0\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"tx2\"],\"-\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx1\",[1,[1,[1,\"tx3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wx2\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"tx2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx3\",[1,[1,\"tx3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"0.5\"]]]],[13,\"ty2\",[1,\"fy\",\"*\",\"fy\"]],[13,\"ty3\",[1,\"ty2\",\"*\",\"fy\"]],[13,\"wy0\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"ty2\"],\"-\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy1\",[1,[1,[1,\"ty3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wy2\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"ty2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy3\",[1,[1,\"ty3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"0.5\"]]]],[13,\"maxT\",[1,\"activeResF\",\"-\",[5,\"1\"]]],[13,\"cxm\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"-\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"x0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx2\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"2\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cym\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"-\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"y0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy2\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"2\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"k00\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cym\"]],[5,\"0\"]]]],[13,\"k01\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cym\"]],[5,\"0\"]]]],[13,\"k02\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cym\"]],[5,\"0\"]]]],[13,\"k03\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cym\"]],[5,\"0\"]]]],[13,\"k10\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy0\"]],[5,\"0\"]]]],[13,\"k11\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy0\"]],[5,\"0\"]]]],[13,\"k12\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy0\"]],[5,\"0\"]]]],[13,\"k13\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy0\"]],[5,\"0\"]]]],[13,\"k20\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy1\"]],[5,\"0\"]]]],[13,\"k21\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy1\"]],[5,\"0\"]]]],[13,\"k22\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy1\"]],[5,\"0\"]]]],[13,\"k23\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy1\"]],[5,\"0\"]]]],[13,\"k30\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy2\"]],[5,\"0\"]]]],[13,\"k31\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy2\"]],[5,\"0\"]]]],[13,\"k32\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy2\"]],[5,\"0\"]]]],[13,\"k33\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy2\"]],[5,\"0\"]]]],[13,\"rAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"aAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"bl\",[6,\"std.mix\",[[6,\"std.mix\",[\"k11\",\"k12\",\"fx\"]],[6,\"std.mix\",[\"k21\",\"k22\",\"fx\"]],\"fy\"]]],[13,\"rMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.min\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"rMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.max\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"aMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.min\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.max\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aOut\",[6,\"std.clamp\",[\"aAcc\",\"aMin\",\"aMax\"]]],[13,\"rNear\",[1,[6,\"std.clamp\",[\"rAcc\",\"rMin\",\"rMax\"]],\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",\"rBound\"]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[10,[6,\"d.vec4f\",[\"rOut\",[7,\"bl\",\"g\"],[7,\"bl\",\"b\"],\"aOut\"]]]]]},externals:{\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,\"std.min\":()=>ye,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"fieldSampleArg\"),fieldSampleGradArg:w.fn([m,Zt(n),n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=G(t.x,r,__tsover_add(r,a)),u=G(t.y,o,__tsover_add(o,i)),p=he(m(__tsover_sub(t.x,d),__tsover_sub(t.y,u))),_=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(d,r),a),l),.5),f=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(u,o),i),l),.5),h=ie(_),g=ie(f),y=__tsover_sub(_,h),b=__tsover_sub(f,g),x=__tsover_mul(y,y),P=__tsover_mul(x,y),C=__tsover_sub(__tsover_add(__tsover_mul(P,-.5),x),__tsover_mul(y,.5)),E=__tsover_add(__tsover_sub(__tsover_mul(P,1.5),__tsover_mul(x,2.5)),1),R=__tsover_add(__tsover_add(__tsover_mul(P,-1.5),__tsover_mul(x,2)),__tsover_mul(y,.5)),U=__tsover_sub(__tsover_mul(P,.5),__tsover_mul(x,.5)),L=__tsover_mul(b,b),k=__tsover_mul(L,b),D=__tsover_sub(__tsover_add(__tsover_mul(k,-.5),L),__tsover_mul(b,.5)),O=__tsover_add(__tsover_sub(__tsover_mul(k,1.5),__tsover_mul(L,2.5)),1),F=__tsover_add(__tsover_add(__tsover_mul(k,-1.5),__tsover_mul(L,2)),__tsover_mul(b,.5)),q=__tsover_sub(__tsover_mul(k,.5),__tsover_mul(L,.5)),Y=__tsover_sub(1,y),V=__tsover_mul(__tsover_mul(__tsover_mul(Y,Y),Y),.16666667),X=__tsover_add(__tsover_sub(__tsover_mul(P,.5),x),.66666667),Q=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(P,-.5),__tsover_mul(x,.5)),__tsover_mul(y,.5)),.16666667),te=__tsover_mul(P,.16666667),J=__tsover_mul(__tsover_mul(Y,Y),-.5),oe=__tsover_sub(__tsover_mul(x,1.5),__tsover_mul(y,2)),le=__tsover_add(__tsover_add(__tsover_mul(x,-1.5),y),.5),se=__tsover_mul(x,.5),Te=__tsover_sub(1,b),de=__tsover_mul(__tsover_mul(__tsover_mul(Te,Te),Te),.16666667),xe=__tsover_add(__tsover_sub(__tsover_mul(k,.5),L),.66666667),Ae=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(k,-.5),__tsover_mul(L,.5)),__tsover_mul(b,.5)),.16666667),De=__tsover_mul(k,.16666667),Ee=__tsover_mul(__tsover_mul(Te,Te),-.5),ze=__tsover_sub(__tsover_mul(L,1.5),__tsover_mul(b,2)),Ie=__tsover_add(__tsover_add(__tsover_mul(L,-1.5),b),.5),ke=__tsover_mul(L,.5),Me=__tsover_sub(l,1),we=M(G(__tsover_sub(h,1),n(0),Me)),Ve=M(G(h,n(0),Me)),qe=M(G(__tsover_add(h,1),n(0),Me)),st=M(G(__tsover_add(h,2),n(0),Me)),pt=M(G(__tsover_sub(g,1),n(0),Me)),Ze=M(G(g,n(0),Me)),nt=M(G(__tsover_add(g,1),n(0),Me)),ht=M(G(__tsover_add(g,2),n(0),Me)),yt=Ye(s,fe(we,pt),0),St=Ye(s,fe(Ve,pt),0),Mt=Ye(s,fe(qe,pt),0),Rt=Ye(s,fe(st,pt),0),Kt=Ye(s,fe(we,Ze),0),Wt=Ye(s,fe(Ve,Ze),0),ls=Ye(s,fe(qe,Ze),0),us=Ye(s,fe(st,Ze),0),os=Ye(s,fe(we,nt),0),bs=Ye(s,fe(Ve,nt),0),hs=Ye(s,fe(qe,nt),0),gs=Ye(s,fe(st,nt),0),Gs=Ye(s,fe(we,ht),0),Ss=Ye(s,fe(Ve,ht),0),or=Ye(s,fe(qe,ht),0),yr=Ye(s,fe(st,ht),0),lr=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(yt.r,C),D),__tsover_mul(__tsover_mul(St.r,E),D)),__tsover_mul(__tsover_mul(Mt.r,R),D)),__tsover_mul(__tsover_mul(Rt.r,U),D)),__tsover_mul(__tsover_mul(Kt.r,C),O)),__tsover_mul(__tsover_mul(Wt.r,E),O)),__tsover_mul(__tsover_mul(ls.r,R),O)),__tsover_mul(__tsover_mul(us.r,U),O)),__tsover_mul(__tsover_mul(os.r,C),F)),__tsover_mul(__tsover_mul(bs.r,E),F)),__tsover_mul(__tsover_mul(hs.r,R),F)),__tsover_mul(__tsover_mul(gs.r,U),F)),__tsover_mul(__tsover_mul(Gs.r,C),q)),__tsover_mul(__tsover_mul(Ss.r,E),q)),__tsover_mul(__tsover_mul(or.r,R),q)),__tsover_mul(__tsover_mul(yr.r,U),q)),Ur=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(yt.a,C),D),__tsover_mul(__tsover_mul(St.a,E),D)),__tsover_mul(__tsover_mul(Mt.a,R),D)),__tsover_mul(__tsover_mul(Rt.a,U),D)),__tsover_mul(__tsover_mul(Kt.a,C),O)),__tsover_mul(__tsover_mul(Wt.a,E),O)),__tsover_mul(__tsover_mul(ls.a,R),O)),__tsover_mul(__tsover_mul(us.a,U),O)),__tsover_mul(__tsover_mul(os.a,C),F)),__tsover_mul(__tsover_mul(bs.a,E),F)),__tsover_mul(__tsover_mul(hs.a,R),F)),__tsover_mul(__tsover_mul(gs.a,U),F)),__tsover_mul(__tsover_mul(Gs.a,C),q)),__tsover_mul(__tsover_mul(Ss.a,E),q)),__tsover_mul(__tsover_mul(or.a,R),q)),__tsover_mul(__tsover_mul(yr.a,U),q)),so=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(yt.r,J),de),__tsover_mul(__tsover_mul(St.r,oe),de)),__tsover_mul(__tsover_mul(Mt.r,le),de)),__tsover_mul(__tsover_mul(Rt.r,se),de)),__tsover_mul(__tsover_mul(Kt.r,J),xe)),__tsover_mul(__tsover_mul(Wt.r,oe),xe)),__tsover_mul(__tsover_mul(ls.r,le),xe)),__tsover_mul(__tsover_mul(us.r,se),xe)),__tsover_mul(__tsover_mul(os.r,J),Ae)),__tsover_mul(__tsover_mul(bs.r,oe),Ae)),__tsover_mul(__tsover_mul(hs.r,le),Ae)),__tsover_mul(__tsover_mul(gs.r,se),Ae)),__tsover_mul(__tsover_mul(Gs.r,J),De)),__tsover_mul(__tsover_mul(Ss.r,oe),De)),__tsover_mul(__tsover_mul(or.r,le),De)),__tsover_mul(__tsover_mul(yr.r,se),De)),ro=__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(yt.r,V),Ee),__tsover_mul(__tsover_mul(St.r,X),Ee)),__tsover_mul(__tsover_mul(Mt.r,Q),Ee)),__tsover_mul(__tsover_mul(Rt.r,te),Ee)),__tsover_mul(__tsover_mul(Kt.r,V),ze)),__tsover_mul(__tsover_mul(Wt.r,X),ze)),__tsover_mul(__tsover_mul(ls.r,Q),ze)),__tsover_mul(__tsover_mul(us.r,te),ze)),__tsover_mul(__tsover_mul(os.r,V),Ie)),__tsover_mul(__tsover_mul(bs.r,X),Ie)),__tsover_mul(__tsover_mul(hs.r,Q),Ie)),__tsover_mul(__tsover_mul(gs.r,te),Ie)),__tsover_mul(__tsover_mul(Gs.r,V),ke)),__tsover_mul(__tsover_mul(Ss.r,X),ke)),__tsover_mul(__tsover_mul(or.r,Q),ke)),__tsover_mul(__tsover_mul(yr.r,te),ke)),_e=ye(ye(Wt.r,ls.r),ye(bs.r,hs.r)),We=B(B(Wt.r,ls.r),B(bs.r,hs.r)),Le=G(Ur,ye(ye(Wt.a,ls.a),ye(bs.a,hs.a)),B(B(Wt.a,ls.a),B(bs.a,hs.a))),Be=__tsover_add(__tsover_mul(__tsover_sub(We,_e),.3),1e-6),Oe=G(__tsover_add(__tsover_mul(__tsover_div(__tsover_sub(We,lr),Be),.5),.5),0,1),tt=__tsover_sub(K(We,lr,Oe),__tsover_mul(__tsover_mul(Be,Oe),__tsover_sub(1,Oe))),_t=G(__tsover_add(__tsover_mul(__tsover_div(__tsover_sub(tt,_e),Be),.5),.5),0,1),Bt=__tsover_add(K(_e,tt,_t),__tsover_mul(__tsover_mul(Be,_t),__tsover_sub(1,_t))),Dt=__tsover_add(Bt,p),Nt=K(Dt,B(__tsover_sub(he(m(__tsover_sub(t.x,.5),__tsover_sub(t.y,.5))),c),Dt),be(n(0),.25,p)),Ks=N(n(0),n(1),re(__tsover_sub(t.x,d))<1e-7),Ds=N(n(0),n(1),re(__tsover_sub(t.y,u))<1e-7),ar=__tsover_div(1,B(p,1e-5));return S(Nt,__tsover_add(__tsover_mul(__tsover_mul(so,__tsover_div(l,a)),Ks),__tsover_mul(__tsover_sub(t.x,d),ar)),__tsover_add(__tsover_mul(__tsover_mul(ro,__tsover_div(l,i)),Ds),__tsover_mul(__tsover_sub(t.y,u),ar)),Le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"field\"},{type:\"i\",name:\"originX\"},{type:\"i\",name:\"originY\"},{type:\"i\",name:\"spanX\"},{type:\"i\",name:\"spanY\"},{type:\"i\",name:\"activeResF\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],\"originX\",[1,\"originX\",\"+\",\"spanX\"]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],\"originY\",[1,\"originY\",\"+\",\"spanY\"]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"px\",[1,[1,[1,[1,\"uxc\",\"-\",\"originX\"],\"/\",\"spanX\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"py\",[1,[1,[1,[1,\"uyc\",\"-\",\"originY\"],\"/\",\"spanY\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"px\"]]],[13,\"y0\",[6,\"std.floor\",[\"py\"]]],[13,\"fx\",[1,\"px\",\"-\",\"x0\"]],[13,\"fy\",[1,\"py\",\"-\",\"y0\"]],[13,\"tx2\",[1,\"fx\",\"*\",\"fx\"]],[13,\"tx3\",[1,\"tx2\",\"*\",\"fx\"]],[13,\"wx0\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"tx2\"],\"-\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx1\",[1,[1,[1,\"tx3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wx2\",[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"tx2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fx\",\"*\",[5,\"0.5\"]]]],[13,\"wx3\",[1,[1,\"tx3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"tx2\",\"*\",[5,\"0.5\"]]]],[13,\"ty2\",[1,\"fy\",\"*\",\"fy\"]],[13,\"ty3\",[1,\"ty2\",\"*\",\"fy\"]],[13,\"wy0\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",\"ty2\"],\"-\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy1\",[1,[1,[1,\"ty3\",\"*\",[5,\"1.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"2.5\"]]],\"+\",[5,\"1\"]]],[13,\"wy2\",[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",[1,\"ty2\",\"*\",[5,\"2\"]]],\"+\",[1,\"fy\",\"*\",[5,\"0.5\"]]]],[13,\"wy3\",[1,[1,\"ty3\",\"*\",[5,\"0.5\"]],\"-\",[1,\"ty2\",\"*\",[5,\"0.5\"]]]],[13,\"oxf\",[1,[5,\"1\"],\"-\",\"fx\"]],[13,\"bx0\",[1,[1,[1,\"oxf\",\"*\",\"oxf\"],\"*\",\"oxf\"],\"*\",[5,\"0.16666667\"]]],[13,\"bx1\",[1,[1,[1,\"tx3\",\"*\",[5,\"0.5\"]],\"-\",\"tx2\"],\"+\",[5,\"0.66666667\"]]],[13,\"bx2\",[1,[1,[1,[1,\"tx3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",[1,\"tx2\",\"*\",[5,\"0.5\"]]],\"+\",[1,\"fx\",\"*\",[5,\"0.5\"]]],\"+\",[5,\"0.16666667\"]]],[13,\"bx3\",[1,\"tx3\",\"*\",[5,\"0.16666667\"]]],[13,\"dbx0\",[1,[1,\"oxf\",\"*\",\"oxf\"],\"*\",[4,\"-\",[5,\"0.5\"]]]],[13,\"dbx1\",[1,[1,\"tx2\",\"*\",[5,\"1.5\"]],\"-\",[1,\"fx\",\"*\",[5,\"2\"]]]],[13,\"dbx2\",[1,[1,[1,\"tx2\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",\"fx\"],\"+\",[5,\"0.5\"]]],[13,\"dbx3\",[1,\"tx2\",\"*\",[5,\"0.5\"]]],[13,\"oyf\",[1,[5,\"1\"],\"-\",\"fy\"]],[13,\"by0\",[1,[1,[1,\"oyf\",\"*\",\"oyf\"],\"*\",\"oyf\"],\"*\",[5,\"0.16666667\"]]],[13,\"by1\",[1,[1,[1,\"ty3\",\"*\",[5,\"0.5\"]],\"-\",\"ty2\"],\"+\",[5,\"0.66666667\"]]],[13,\"by2\",[1,[1,[1,[1,\"ty3\",\"*\",[4,\"-\",[5,\"0.5\"]]],\"+\",[1,\"ty2\",\"*\",[5,\"0.5\"]]],\"+\",[1,\"fy\",\"*\",[5,\"0.5\"]]],\"+\",[5,\"0.16666667\"]]],[13,\"by3\",[1,\"ty3\",\"*\",[5,\"0.16666667\"]]],[13,\"dby0\",[1,[1,\"oyf\",\"*\",\"oyf\"],\"*\",[4,\"-\",[5,\"0.5\"]]]],[13,\"dby1\",[1,[1,\"ty2\",\"*\",[5,\"1.5\"]],\"-\",[1,\"fy\",\"*\",[5,\"2\"]]]],[13,\"dby2\",[1,[1,[1,\"ty2\",\"*\",[4,\"-\",[5,\"1.5\"]]],\"+\",\"fy\"],\"+\",[5,\"0.5\"]]],[13,\"dby3\",[1,\"ty2\",\"*\",[5,\"0.5\"]]],[13,\"maxT\",[1,\"activeResF\",\"-\",[5,\"1\"]]],[13,\"cxm\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"-\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"x0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx2\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"2\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cym\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"-\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"y0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy2\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"2\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"k00\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cym\"]],[5,\"0\"]]]],[13,\"k01\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cym\"]],[5,\"0\"]]]],[13,\"k02\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cym\"]],[5,\"0\"]]]],[13,\"k03\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cym\"]],[5,\"0\"]]]],[13,\"k10\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy0\"]],[5,\"0\"]]]],[13,\"k11\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy0\"]],[5,\"0\"]]]],[13,\"k12\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy0\"]],[5,\"0\"]]]],[13,\"k13\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy0\"]],[5,\"0\"]]]],[13,\"k20\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy1\"]],[5,\"0\"]]]],[13,\"k21\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy1\"]],[5,\"0\"]]]],[13,\"k22\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy1\"]],[5,\"0\"]]]],[13,\"k23\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy1\"]],[5,\"0\"]]]],[13,\"k30\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cxm\",\"cy2\"]],[5,\"0\"]]]],[13,\"k31\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy2\"]],[5,\"0\"]]]],[13,\"k32\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy2\"]],[5,\"0\"]]]],[13,\"k33\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx2\",\"cy2\"]],[5,\"0\"]]]],[13,\"rAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"r\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"r\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"r\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"r\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"aAcc\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy0\"],\"+\",[1,[1,[7,\"k01\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k02\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k03\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy0\"]],\"+\",[1,[1,[7,\"k10\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k11\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k12\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k13\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy1\"]],\"+\",[1,[1,[7,\"k20\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k21\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k22\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k23\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy2\"]],\"+\",[1,[1,[7,\"k30\",\"a\"],\"*\",\"wx0\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k31\",\"a\"],\"*\",\"wx1\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k32\",\"a\"],\"*\",\"wx2\"],\"*\",\"wy3\"]],\"+\",[1,[1,[7,\"k33\",\"a\"],\"*\",\"wx3\"],\"*\",\"wy3\"]]],[13,\"drdpx\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"r\"],\"*\",\"dbx0\"],\"*\",\"by0\"],\"+\",[1,[1,[7,\"k01\",\"r\"],\"*\",\"dbx1\"],\"*\",\"by0\"]],\"+\",[1,[1,[7,\"k02\",\"r\"],\"*\",\"dbx2\"],\"*\",\"by0\"]],\"+\",[1,[1,[7,\"k03\",\"r\"],\"*\",\"dbx3\"],\"*\",\"by0\"]],\"+\",[1,[1,[7,\"k10\",\"r\"],\"*\",\"dbx0\"],\"*\",\"by1\"]],\"+\",[1,[1,[7,\"k11\",\"r\"],\"*\",\"dbx1\"],\"*\",\"by1\"]],\"+\",[1,[1,[7,\"k12\",\"r\"],\"*\",\"dbx2\"],\"*\",\"by1\"]],\"+\",[1,[1,[7,\"k13\",\"r\"],\"*\",\"dbx3\"],\"*\",\"by1\"]],\"+\",[1,[1,[7,\"k20\",\"r\"],\"*\",\"dbx0\"],\"*\",\"by2\"]],\"+\",[1,[1,[7,\"k21\",\"r\"],\"*\",\"dbx1\"],\"*\",\"by2\"]],\"+\",[1,[1,[7,\"k22\",\"r\"],\"*\",\"dbx2\"],\"*\",\"by2\"]],\"+\",[1,[1,[7,\"k23\",\"r\"],\"*\",\"dbx3\"],\"*\",\"by2\"]],\"+\",[1,[1,[7,\"k30\",\"r\"],\"*\",\"dbx0\"],\"*\",\"by3\"]],\"+\",[1,[1,[7,\"k31\",\"r\"],\"*\",\"dbx1\"],\"*\",\"by3\"]],\"+\",[1,[1,[7,\"k32\",\"r\"],\"*\",\"dbx2\"],\"*\",\"by3\"]],\"+\",[1,[1,[7,\"k33\",\"r\"],\"*\",\"dbx3\"],\"*\",\"by3\"]]],[13,\"drdpy\",[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[1,[7,\"k00\",\"r\"],\"*\",\"bx0\"],\"*\",\"dby0\"],\"+\",[1,[1,[7,\"k01\",\"r\"],\"*\",\"bx1\"],\"*\",\"dby0\"]],\"+\",[1,[1,[7,\"k02\",\"r\"],\"*\",\"bx2\"],\"*\",\"dby0\"]],\"+\",[1,[1,[7,\"k03\",\"r\"],\"*\",\"bx3\"],\"*\",\"dby0\"]],\"+\",[1,[1,[7,\"k10\",\"r\"],\"*\",\"bx0\"],\"*\",\"dby1\"]],\"+\",[1,[1,[7,\"k11\",\"r\"],\"*\",\"bx1\"],\"*\",\"dby1\"]],\"+\",[1,[1,[7,\"k12\",\"r\"],\"*\",\"bx2\"],\"*\",\"dby1\"]],\"+\",[1,[1,[7,\"k13\",\"r\"],\"*\",\"bx3\"],\"*\",\"dby1\"]],\"+\",[1,[1,[7,\"k20\",\"r\"],\"*\",\"bx0\"],\"*\",\"dby2\"]],\"+\",[1,[1,[7,\"k21\",\"r\"],\"*\",\"bx1\"],\"*\",\"dby2\"]],\"+\",[1,[1,[7,\"k22\",\"r\"],\"*\",\"bx2\"],\"*\",\"dby2\"]],\"+\",[1,[1,[7,\"k23\",\"r\"],\"*\",\"bx3\"],\"*\",\"dby2\"]],\"+\",[1,[1,[7,\"k30\",\"r\"],\"*\",\"bx0\"],\"*\",\"dby3\"]],\"+\",[1,[1,[7,\"k31\",\"r\"],\"*\",\"bx1\"],\"*\",\"dby3\"]],\"+\",[1,[1,[7,\"k32\",\"r\"],\"*\",\"bx2\"],\"*\",\"dby3\"]],\"+\",[1,[1,[7,\"k33\",\"r\"],\"*\",\"bx3\"],\"*\",\"dby3\"]]],[13,\"rMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.min\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"rMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"r\"],[7,\"k12\",\"r\"]]],[6,\"std.max\",[[7,\"k21\",\"r\"],[7,\"k22\",\"r\"]]]]]],[13,\"aMin\",[6,\"std.min\",[[6,\"std.min\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.min\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aMax\",[6,\"std.max\",[[6,\"std.max\",[[7,\"k11\",\"a\"],[7,\"k12\",\"a\"]]],[6,\"std.max\",[[7,\"k21\",\"a\"],[7,\"k22\",\"a\"]]]]]],[13,\"aOut\",[6,\"std.clamp\",[\"aAcc\",\"aMin\",\"aMax\"]]],[13,\"kSoft\",[1,[1,[1,\"rMax\",\"-\",\"rMin\"],\"*\",[5,\"0.3\"]],\"+\",[5,\"0.000001\"]]],[13,\"hCap\",[6,\"std.clamp\",[[1,[1,[1,[1,\"rMax\",\"-\",\"rAcc\"],\"/\",\"kSoft\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"rCap\",[1,[6,\"std.mix\",[\"rMax\",\"rAcc\",\"hCap\"]],\"-\",[1,[1,\"kSoft\",\"*\",\"hCap\"],\"*\",[1,[5,\"1\"],\"-\",\"hCap\"]]]],[13,\"hFlr\",[6,\"std.clamp\",[[1,[1,[1,[1,\"rCap\",\"-\",\"rMin\"],\"/\",\"kSoft\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"rSoft\",[1,[6,\"std.mix\",[\"rMin\",\"rCap\",\"hFlr\"]],\"+\",[1,[1,\"kSoft\",\"*\",\"hFlr\"],\"*\",[1,[5,\"1\"],\"-\",\"hFlr\"]]]],[13,\"rNear\",[1,\"rSoft\",\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",\"rBound\"]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[13,\"insideX\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"std.abs\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"]]],\"<\",[5,\"1e-7\"]]]]],[13,\"insideY\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"std.abs\",[[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]],\"<\",[5,\"1e-7\"]]]]],[13,\"invOut\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[\"outsideDist\",[5,\"0.00001\"]]]]],[13,\"gU\",[1,[1,[1,\"drdpx\",\"*\",[1,\"activeResF\",\"/\",\"spanX\"]],\"*\",\"insideX\"],\"+\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],\"*\",\"invOut\"]]],[13,\"gV\",[1,[1,[1,\"drdpy\",\"*\",[1,\"activeResF\",\"/\",\"spanY\"]],\"*\",\"insideY\"],\"+\",[1,[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"],\"*\",\"invOut\"]]],[10,[6,\"d.vec4f\",[\"rOut\",\"gU\",\"gV\",\"aOut\"]]]]]},externals:{\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.min\":()=>ye,\"std.max\":()=>B,\"std.mix\":()=>K,\"std.smoothstep\":()=>be,\"std.select\":()=>N,\"std.abs\":()=>re,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"fieldSampleGradArg\"),fieldSampleFastArg:w.fn([m,Zt(n),n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=G(t.x,r,__tsover_add(r,a)),u=G(t.y,o,__tsover_add(o,i)),p=he(m(__tsover_sub(t.x,d),__tsover_sub(t.y,u))),_=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(d,r),a),l),.5),f=__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(u,o),i),l),.5),h=ie(_),g=ie(f),y=__tsover_sub(_,h),b=__tsover_sub(f,g),x=__tsover_sub(l,1),P=M(G(h,n(0),x)),C=M(G(__tsover_add(h,1),n(0),x)),E=M(G(g,n(0),x)),R=M(G(__tsover_add(g,1),n(0),x)),U=Ye(s,fe(P,E),0),L=Ye(s,fe(C,E),0),k=Ye(s,fe(P,R),0),D=Ye(s,fe(C,R),0),O=K(K(U,L,y),K(k,D,y),b),F=__tsover_add(O.r,p);return S(K(F,B(__tsover_sub(he(m(__tsover_sub(t.x,.5),__tsover_sub(t.y,.5))),c),F),be(n(0),.25,p)),O.g,O.b,O.a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"field\"},{type:\"i\",name:\"originX\"},{type:\"i\",name:\"originY\"},{type:\"i\",name:\"spanX\"},{type:\"i\",name:\"spanY\"},{type:\"i\",name:\"activeResF\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],\"originX\",[1,\"originX\",\"+\",\"spanX\"]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],\"originY\",[1,\"originY\",\"+\",\"spanY\"]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"px\",[1,[1,[1,[1,\"uxc\",\"-\",\"originX\"],\"/\",\"spanX\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"py\",[1,[1,[1,[1,\"uyc\",\"-\",\"originY\"],\"/\",\"spanY\"],\"*\",\"activeResF\"],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"px\"]]],[13,\"y0\",[6,\"std.floor\",[\"py\"]]],[13,\"fx\",[1,\"px\",\"-\",\"x0\"]],[13,\"fy\",[1,\"py\",\"-\",\"y0\"]],[13,\"maxT\",[1,\"activeResF\",\"-\",[5,\"1\"]]],[13,\"cx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"x0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"y0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"t00\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy0\"]],[5,\"0\"]]]],[13,\"t10\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy0\"]],[5,\"0\"]]]],[13,\"t01\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx0\",\"cy1\"]],[5,\"0\"]]]],[13,\"t11\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[\"cx1\",\"cy1\"]],[5,\"0\"]]]],[13,\"bl\",[6,\"std.mix\",[[6,\"std.mix\",[\"t00\",\"t10\",\"fx\"]],[6,\"std.mix\",[\"t01\",\"t11\",\"fx\"]],\"fy\"]]],[13,\"rNear\",[1,[7,\"bl\",\"r\"],\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",\"rBound\"]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[10,[6,\"d.vec4f\",[\"rOut\",[7,\"bl\",\"g\"],[7,\"bl\",\"b\"],[7,\"bl\",\"a\"]]]]]]},externals:{\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"fieldSampleFastArg\"),fieldSampleTexelArg:w.fn([m,Zt(n),n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=G(t.x,r,__tsover_add(r,a)),u=G(t.y,o,__tsover_add(o,i)),p=he(m(__tsover_sub(t.x,d),__tsover_sub(t.y,u))),_=__tsover_sub(l,1),f=G(ie(__tsover_mul(__tsover_div(__tsover_sub(d,r),a),l)),n(0),_),h=G(ie(__tsover_mul(__tsover_div(__tsover_sub(u,o),i),l)),n(0),_),g=Ye(s,fe(M(f),M(h)),0),y=__tsover_add(g.r,p);return S(K(y,B(__tsover_sub(he(m(__tsover_sub(t.x,.5),__tsover_sub(t.y,.5))),c),y),be(n(0),.25,p)),g.g,g.b,g.a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"field\"},{type:\"i\",name:\"originX\"},{type:\"i\",name:\"originY\"},{type:\"i\",name:\"spanX\"},{type:\"i\",name:\"spanY\"},{type:\"i\",name:\"activeResF\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"uxc\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],\"originX\",[1,\"originX\",\"+\",\"spanX\"]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],\"originY\",[1,\"originY\",\"+\",\"spanY\"]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"uxc\"],[1,[7,\"uv\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"maxT\",[1,\"activeResF\",\"-\",[5,\"1\"]]],[13,\"px\",[6,\"std.clamp\",[[6,\"std.floor\",[[1,[1,[1,\"uxc\",\"-\",\"originX\"],\"/\",\"spanX\"],\"*\",\"activeResF\"]]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]],[13,\"py\",[6,\"std.clamp\",[[6,\"std.floor\",[[1,[1,[1,\"uyc\",\"-\",\"originY\"],\"/\",\"spanY\"],\"*\",\"activeResF\"]]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]],[13,\"t\",[6,\"std.textureLoad\",[\"field\",[6,\"d.vec2u\",[[6,\"d.u32\",[\"px\"]],[6,\"d.u32\",[\"py\"]]]],[5,\"0\"]]]],[13,\"rNear\",[1,[7,\"t\",\"r\"],\"+\",\"outsideDist\"]],[13,\"rCircle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",\"rBound\"]],[13,\"rOut\",[6,\"std.mix\",[\"rNear\",[6,\"std.max\",[\"rCircle\",\"rNear\"]],[6,\"std.smoothstep\",[[6,\"d.f32\",[[5,\"0\"]]],[5,\"0.25\"],\"outsideDist\"]]]]],[10,[6,\"d.vec4f\",[\"rOut\",[7,\"t\",\"g\"],[7,\"t\",\"b\"],[7,\"t\",\"a\"]]]]]]},externals:{\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.floor\":()=>ie,\"d.f32\":()=>n,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"std.mix\":()=>K,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"fieldSampleTexelArg\"),texelSpanFn:w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_div(B(t,s),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"spanX\"},{type:\"i\",name:\"spanY\"},{type:\"i\",name:\"activeResF\"}],body:[0,[[10,[1,[6,\"std.max\",[\"spanX\",\"spanY\"]],\"/\",\"activeResF\"]]]]},externals:{\"std.max\":()=>B}})&&e.f)({})).$name(\"fieldTexelSpan\")}}var pne={_vfOriginX:{schema:n,initial:0},_vfOriginY:{schema:n,initial:0},_vfSpanX:{schema:n,initial:1},_vfSpanY:{schema:n,initial:1},_vfActiveRes:{schema:n,initial:1},_vfRBound:{schema:n,initial:.6}};function KB(e,t){let{fieldSampleArg:s,fieldSampleGradArg:r,fieldSampleFastArg:o,fieldSampleTexelArg:a,texelSpanFn:i}=bA(),l=(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(e.accessor(),\"acc\"),c=d=>[d,l,t.originX,t.originY,t.spanX,t.spanY,t.activeResF,t.rBound];return{volumetricFieldSampler:d=>W(s,\"vfSample\",c(d)),volumetricFieldSamplerGrad:d=>W(r,\"vfSampleGrad\",c(d)),volumetricFieldSamplerFast:d=>W(o,\"vfSampleFast\",c(d)),volumetricFieldSamplerTexel:d=>W(a,\"vfSampleTexel\",c(d)),volumetricFieldTexelSpan:W(i,\"vfTexelSpan\",[t.spanX,t.spanY,t.activeResF])}}function mne(e,t={}){let{patternMode:s=\"none\",gradSampler:r=\"fast\",bakedGradients:o=\"none\"}=t,{computeOutputs:a,uniforms:i,propValues:l,getCpuValue:c}=e,d=a?.volumetricFieldTexture;if(d){let h=KB(d,{originX:i._vfOriginX,originY:i._vfOriginY,spanX:i._vfSpanX,spanY:i._vfSpanY,activeResF:i._vfActiveRes,rBound:i._vfRBound}),g=o!==\"none\",y=g?h.volumetricFieldSamplerGrad:h.volumetricFieldSampler;return{sampler:y,gradSampler:r===\"same\"?y:h.volumetricFieldSamplerFast,texelSampler:h.volumetricFieldSamplerTexel,volumetric:!0,bakedGradients:g}}let u=l.shapeSdfUrl||\"\",p=l.shapeType||\"\";if(u){let h=o===\"all\",g=h?PB(e,u):SB(e,u);return{sampler:g,gradSampler:g,texelSampler:g,volumetric:VB(p),bakedGradients:h}}let _=bc(p,c(\"shape\")),f=MB(_,EB(e,()=>c(\"shape\")),s);return{sampler:f,gradSampler:f,texelSampler:f,volumetric:M_(_),bakedGradients:!1}}var rd=Math.PI/180;function xA(e){if(e&&typeof e==\"object\")return e;if(typeof e==\"string\")try{return JSON.parse(e)}catch{return{}}return{}}function AA(e,t,s,r,o={}){let a=Qv[t]??Qv.sphere3D,i=o.extraPad??(()=>0),{layout:l}=hA(),c=(globalThis.__TYPEGPU_AUTONAME__??(oe=>oe))(e.createUniform(vl),\"marchParamsBuffer\"),d=w.fn([A],n)((oe=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(oe.f=(le=>{\"use gpu\";let se=l.$.params;return t===\"cube3D\"?xd(le,se.pA,se.pB,se.pC,se.pD):t===\"torus3D\"?tx(le,se.pA,se.pB):t===\"octahedron3D\"?sx(le,se.pA):t===\"cylinder3D\"?rx(le,se.pA,se.pB,se.pD):t===\"capsule3D\"?ox(le,se.pA,se.pB):t===\"cone3D\"?ax(le,se.pA,se.pC,se.pB):t===\"pyramid3D\"?nx(le,se.pA,se.pB):t===\"prism3D\"?ix(le,se.pA,se.pB):t===\"ellipsoid3D\"?lx(le,se.pA,se.pB,se.pC):t===\"diamond3D\"?Zm(le,se.pA,se.pB):t===\"link3D\"?cx(le,se.pB,se.pA,se.pC):t===\"gem3D\"?ux(le,se.pA,se.pB,se.pC):t===\"helix3D\"?px(le,se.pA,se.pB,se.pC,n(3)):t===\"metaballs3D\"?mx(le,se.mb0,se.mb1,se.mb2,se.mb3,se.mb4,se.mb5,se.mb6,se.mb7,se.pA,se.pD):t===\"dodecahedron3D\"?_x(le,se.pA):t===\"hemisphere3D\"?fx(le,se.pA,se.pB):t===\"ribbon3D\"?vx(le,se.pA,se.pB,se.pC,se.mb0.x,se.mb0.y,se.mb0.z,se.mb1.x,se.mb1.y,se.mb1.z,se.mb2.x):t===\"blob3D\"?hx(le,se.pA,se.mb0.x,se.mb0.y,se.mb0.z,se.mb1.x,se.mb2.x):t===\"gyroscope3D\"?gx(le,se.pA,se.pB,se.pD,se.mb3.x,se.pC,se.mb0.x,se.mb0.y,se.mb1.x,se.mb1.y,se.mb2.x,se.mb2.y):ex(le,se.pA)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"pp\",[7,[7,\"layout\",\"$\"],\"params\"]],[11,[1,\"shapeType\",\"===\",[103,\"cube3D\"]],[10,[6,\"sdRoundBox\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"],[7,\"pp\",\"pD\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"torus3D\"]],[10,[6,\"sdTorus\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"octahedron3D\"]],[10,[6,\"sdOctahedron\",[\"p\",[7,\"pp\",\"pA\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"cylinder3D\"]],[10,[6,\"sdRoundCylinder\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pD\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"capsule3D\"]],[10,[6,\"sdCapsule\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"cone3D\"]],[10,[6,\"sdCappedCone\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pC\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"pyramid3D\"]],[10,[6,\"sdPyramid\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"prism3D\"]],[10,[6,\"sdHexPrism\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"ellipsoid3D\"]],[10,[6,\"sdEllipsoid\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"diamond3D\"]],[10,[6,\"sdBicone\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"link3D\"]],[10,[6,\"sdLink\",[\"p\",[7,\"pp\",\"pB\"],[7,\"pp\",\"pA\"],[7,\"pp\",\"pC\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"gem3D\"]],[10,[6,\"sdGem\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"helix3D\"]],[10,[6,\"sdHelix\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"],[6,\"d.f32\",[\"HELIX_TURNS\"]]]]],[11,[1,\"shapeType\",\"===\",[103,\"metaballs3D\"]],[10,[6,\"sdMetaballs\",[\"p\",[7,\"pp\",\"mb0\"],[7,\"pp\",\"mb1\"],[7,\"pp\",\"mb2\"],[7,\"pp\",\"mb3\"],[7,\"pp\",\"mb4\"],[7,\"pp\",\"mb5\"],[7,\"pp\",\"mb6\"],[7,\"pp\",\"mb7\"],[7,\"pp\",\"pA\"],[7,\"pp\",\"pD\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"dodecahedron3D\"]],[10,[6,\"sdDodecahedron\",[\"p\",[7,\"pp\",\"pA\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"hemisphere3D\"]],[10,[6,\"sdCutSphere\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"ribbon3D\"]],[10,[6,\"sdRibbon\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"],[7,[7,\"pp\",\"mb0\"],\"x\"],[7,[7,\"pp\",\"mb0\"],\"y\"],[7,[7,\"pp\",\"mb0\"],\"z\"],[7,[7,\"pp\",\"mb1\"],\"x\"],[7,[7,\"pp\",\"mb1\"],\"y\"],[7,[7,\"pp\",\"mb1\"],\"z\"],[7,[7,\"pp\",\"mb2\"],\"x\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"blob3D\"]],[10,[6,\"sdWobbleBlob\",[\"p\",[7,\"pp\",\"pA\"],[7,[7,\"pp\",\"mb0\"],\"x\"],[7,[7,\"pp\",\"mb0\"],\"y\"],[7,[7,\"pp\",\"mb0\"],\"z\"],[7,[7,\"pp\",\"mb1\"],\"x\"],[7,[7,\"pp\",\"mb2\"],\"x\"]]]],[11,[1,\"shapeType\",\"===\",[103,\"gyroscope3D\"]],[10,[6,\"sdGyroscope\",[\"p\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pD\"],[7,[7,\"pp\",\"mb3\"],\"x\"],[7,\"pp\",\"pC\"],[7,[7,\"pp\",\"mb0\"],\"x\"],[7,[7,\"pp\",\"mb0\"],\"y\"],[7,[7,\"pp\",\"mb1\"],\"x\"],[7,[7,\"pp\",\"mb1\"],\"y\"],[7,[7,\"pp\",\"mb2\"],\"x\"],[7,[7,\"pp\",\"mb2\"],\"y\"]]]],[10,[6,\"sdSphere\",[\"p\",[7,\"pp\",\"pA\"]]]]]]]]]]]]]]]]]]]]]]]]]},externals:{layout:()=>l,shapeType:()=>t,sdRoundBox:()=>xd,sdTorus:()=>tx,sdOctahedron:()=>sx,sdRoundCylinder:()=>rx,sdCapsule:()=>ox,sdCappedCone:()=>ax,sdPyramid:()=>nx,sdHexPrism:()=>ix,sdEllipsoid:()=>lx,sdBicone:()=>Zm,sdLink:()=>cx,sdGem:()=>ux,sdHelix:()=>px,\"d.f32\":()=>n,HELIX_TURNS:()=>3,sdMetaballs:()=>mx,sdDodecahedron:()=>_x,sdCutSphere:()=>fx,sdRibbon:()=>vx,sdWobbleBlob:()=>hx,sdGyroscope:()=>gx,sdSphere:()=>ex}})&&oe.f)({})),u=0,p=\"\",_=s,f=new Map,h=.35,g=.3,y=.3,b=0,x=.6,P=1,C=0,E=1,R=0,U=1,L=0,k=1,D=1,O=0,F=0,q=E_(),Y=Array.from({length:8},()=>[0,0,0]),V=()=>{c.write({rot:{cx:P,sx:C,cy:E,sy:R,cz:U,sz:L},rBound:x,spanX:k,spanY:D,originX:O,originY:F,activeRes:q,pA:h,pB:g,pC:y,pD:b,mb0:A(Y[0][0],Y[0][1],Y[0][2]),mb1:A(Y[1][0],Y[1][1],Y[1][2]),mb2:A(Y[2][0],Y[2][1],Y[2][2]),mb3:A(Y[3][0],Y[3][1],Y[3][2]),mb4:A(Y[4][0],Y[4][1],Y[4][2]),mb5:A(Y[5][0],Y[5][1],Y[5][2]),mb6:A(Y[6][0],Y[6][1],Y[6][2]),mb7:A(Y[7][0],Y[7][1],Y[7][2])})},X=oe=>{let le=oe?.deltaTime??0;u+=le;let se=r();if(se&&typeof se==\"object\")_=se;else if(typeof se==\"string\"&&se!==p){p=se;try{_=JSON.parse(se)}catch{}}let Te={elapsed:u,deltaTime:le,pointerX:oe?.pointer?.x??.5,pointerY:oe?.pointer?.y??.5,springs:f},de=ze=>_A(_[ze],a[ze]??0,Te,ze);g=.3,y=.3,b=0;for(let ze=0;ze<Y.length;ze++)Y[ze]=[0,0,0];switch(t){case\"cube3D\":h=de(\"sizeX\"),g=de(\"sizeY\"),y=de(\"sizeZ\"),b=de(\"rounding\");break;case\"torus3D\":h=de(\"radius\"),g=de(\"tube\");break;case\"cylinder3D\":h=de(\"radius\"),g=de(\"height\"),b=de(\"rounding\");break;case\"capsule3D\":h=de(\"radius\"),g=de(\"height\");break;case\"cone3D\":h=de(\"radius\"),g=de(\"height\"),y=de(\"topRadius\");break;case\"pyramid3D\":h=de(\"size\"),g=de(\"height\");break;case\"prism3D\":case\"diamond3D\":h=de(\"radius\"),g=de(\"height\");break;case\"ellipsoid3D\":h=de(\"radiusX\"),g=de(\"radiusY\"),y=de(\"radiusZ\");break;case\"link3D\":h=de(\"radius\"),g=de(\"length\"),y=de(\"tube\");break;case\"gem3D\":h=de(\"radius\"),g=de(\"height\"),y=de(\"facets\");break;case\"helix3D\":h=de(\"radius\"),g=de(\"tube\"),y=de(\"pitch\");break;case\"metaballs3D\":{h=de(\"ballRadius\"),g=de(\"spread\"),b=de(\"blend\");let ze=Math.min(8,Math.max(1,Math.round(de(\"balls\")))),Ie=g,ke=u*de(\"speed\")*.6;for(let Me=0;Me<Y.length;Me++){if(Me>=ze){Y[Me]=[0,99,0];continue}let we=Me*(sd/ze),Ve=we+ke,qe=.75+.25*Math.sin(ke*1.3+Me*1.7);Y[Me]=[Ie*Math.cos(Ve)*qe,Ie*.6*Math.sin(ke*.9+we*1.5),Ie*Math.sin(Ve)*qe]}break}case\"hemisphere3D\":h=de(\"radius\"),g=de(\"cut\");break;case\"ribbon3D\":{h=de(\"width\"),g=de(\"thickness\"),y=de(\"length\");let ze=u*de(\"speed\"),Ie=de(\"wave\")*(.8+.2*Math.sin(ze*.9)),ke=de(\"waveFrequency\"),Me=de(\"twist\")*rd/Math.max(y*2,.01);Y[0]=[Ie,ke,ze*1.1],Y[1]=[ze*.7+2.1,Me,ze*.45];let we=Math.abs(Ie)*ke+Math.abs(Me)*Math.hypot(h,g);Y[2]=[1/Math.sqrt(1+we*we),0,0];break}case\"blob3D\":{h=de(\"radius\");let ze=u*de(\"speed\"),Ie=de(\"wobble\")*(.75+.25*Math.sin(ze*.83)),ke=de(\"wobbliness\");Y[0]=[Ie,ke,ze*1.2],Y[1]=[ze*.77+1.3,0,0],Y[2]=[1/(1+Math.abs(Ie)*ke*1.3),0,0];break}case\"gyroscope3D\":{h=de(\"radius\"),g=de(\"width\"),y=de(\"core\"),b=de(\"thickness\");let ze=Math.max(0,Math.min(de(\"rounding\"),Math.min(g,b)*.5)),Ie=u*de(\"speed\"),ke=Ie*.9,Me=Ie*.63+1.1,we=Ie*1.21+2.3;Y[0]=[Math.cos(ke),Math.sin(ke),0],Y[1]=[Math.cos(Me),Math.sin(Me),0],Y[2]=[Math.cos(we),Math.sin(we),0],Y[3]=[ze,0,0];break}default:h=de(\"radius\");break}x=XB({..._,type:t})+.02+i();let xe=de(\"rotX\")*rd,Ae=de(\"rotY\")*rd,De=de(\"rotZ\")*rd;P=Math.cos(xe),C=Math.sin(xe),E=Math.cos(Ae),R=Math.sin(Ae),U=Math.cos(De),L=Math.sin(De);let Ee=x+.05;k=Ee*2,D=Ee*2,O=.5-Ee,F=.5-Ee,V()};X();let Q=oe=>{oe!==q&&(q=oe,V())},te=()=>`${h},${g},${y},${b},${x},`+Y.map(oe=>`${oe[0]},${oe[1]},${oe[2]}`).join(\",\");return{layout:l,marchParamsBuffer:c,sdfFn:d,update:X,setActiveRes:Q,getStateKey:()=>`${te()},${P},${C},${E},${R},${U},${L}`,getFootprint:()=>({spanX:k,spanY:D,originX:O,originY:F,rBound:x}),getRotation:()=>({cx:P,sx:C,cy:E,sy:R,cz:U,sz:L}),getGeometryKey:te}}function wA(e,t,s,r={}){let o=e.gpu.root,a=r.extraPad??(()=>0),{texture:i,getVersion:l}=uA(e,t),{layout:c}=jB(),d=(globalThis.__TYPEGPU_AUTONAME__??(oe=>oe))(o.createUniform(vl),\"marchParamsBuffer\"),u=n(512),p=n(511),_=w.fn([A],n)((oe=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(oe.f=(le=>{\"use gpu\";let se=c.$.params,Te=se.pA,de=se.pB,xe=__tsover_sub(__tsover_mul(__tsover_add(le.x,.5),u),.5),Ae=__tsover_sub(__tsover_mul(__tsover_sub(.5,le.y),u),.5),De=ie(xe),Ee=ie(Ae),ze=__tsover_sub(xe,De),Ie=__tsover_sub(Ae,Ee),ke=M(G(De,n(0),p)),Me=M(G(__tsover_add(De,1),n(0),p)),we=M(G(Ee,n(0),p)),Ve=M(G(__tsover_add(Ee,1),n(0),p)),qe=Ye(c.$.sdfSource,fe(ke,we),0).r,st=Ye(c.$.sdfSource,fe(Me,we),0).r,pt=Ye(c.$.sdfSource,fe(ke,Ve),0).r,Ze=Ye(c.$.sdfSource,fe(Me,Ve),0).r,nt=K(K(qe,st,ze),K(pt,Ze,ze),Ie),ht=__tsover_add(nt,de),yt=__tsover_add(__tsover_sub(re(le.z),Te),de),St=ye(B(ht,yt),n(0)),Mt=he(m(B(ht,n(0)),B(yt,n(0))));return __tsover_sub(__tsover_add(St,Mt),de)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"pp\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"halfDepth\",[7,\"pp\",\"pA\"]],[13,\"bevel\",[7,\"pp\",\"pB\"]],[13,\"u\",[1,[1,[1,[7,\"p\",\"x\"],\"+\",[5,\"0.5\"]],\"*\",\"SIZE_F\"],\"-\",[5,\"0.5\"]]],[13,\"v\",[1,[1,[1,[5,\"0.5\"],\"-\",[7,\"p\",\"y\"]],\"*\",\"SIZE_F\"],\"-\",[5,\"0.5\"]]],[13,\"x0\",[6,\"std.floor\",[\"u\"]]],[13,\"y0\",[6,\"std.floor\",[\"v\"]]],[13,\"fx\",[1,\"u\",\"-\",\"x0\"]],[13,\"fy\",[1,\"v\",\"-\",\"y0\"]],[13,\"cx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"x0\",[6,\"d.f32\",[[5,\"0\"]]],\"MAX_TEXEL\"]]]]],[13,\"cx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"MAX_TEXEL\"]]]]],[13,\"cy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"y0\",[6,\"d.f32\",[[5,\"0\"]]],\"MAX_TEXEL\"]]]]],[13,\"cy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"MAX_TEXEL\"]]]]],[13,\"s00\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[\"cx0\",\"cy0\"]],[5,\"0\"]]],\"r\"]],[13,\"s10\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[\"cx1\",\"cy0\"]],[5,\"0\"]]],\"r\"]],[13,\"s01\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[\"cx0\",\"cy1\"]],[5,\"0\"]]],\"r\"]],[13,\"s11\",[7,[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[\"cx1\",\"cy1\"]],[5,\"0\"]]],\"r\"]],[13,\"field2d\",[6,\"std.mix\",[[6,\"std.mix\",[\"s00\",\"s10\",\"fx\"]],[6,\"std.mix\",[\"s01\",\"s11\",\"fx\"]],\"fy\"]]],[13,\"d2\",[1,\"field2d\",\"+\",\"bevel\"]],[13,\"wz\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"z\"]]],\"-\",\"halfDepth\"],\"+\",\"bevel\"]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"d2\",\"wz\"]],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"d2\",[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[\"wz\",[6,\"d.f32\",[[5,\"0\"]]]]]]]]]],[10,[1,[1,\"inner\",\"+\",\"outer\"],\"-\",\"bevel\"]]]]},externals:{layout:()=>c,SIZE_F:()=>u,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"std.clamp\":()=>G,\"d.f32\":()=>n,MAX_TEXEL:()=>p,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.max\":()=>B,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&oe.f)({})),f=0,h=\"\",g=xA(s()),y=new Map,b=.06,x=.02,P=.75,C=1,E=0,R=1,U=0,L=1,k=0,D=1,O=1,F=0,q=0,Y=E_(),V=()=>{d.write({rot:{cx:C,sx:E,cy:R,sy:U,cz:L,sz:k},rBound:P,spanX:D,spanY:O,originX:F,originY:q,activeRes:Y,pA:b,pB:x,pC:0,pD:0,mb0:A(0,0,0),mb1:A(0,0,0),mb2:A(0,0,0),mb3:A(0,0,0),mb4:A(0,0,0),mb5:A(0,0,0),mb6:A(0,0,0),mb7:A(0,0,0)})},X=oe=>{let le=oe?.deltaTime??0;f+=le;let se=s();if(se&&typeof se==\"object\")g=se;else if(typeof se==\"string\"&&se!==h){h=se;try{g=JSON.parse(se)}catch{}}let Te={elapsed:f,deltaTime:le,pointerX:oe?.pointer?.x??.5,pointerY:oe?.pointer?.y??.5,springs:y},de=ht=>_A(g[ht],NB[ht]??0,Te,ht);b=Math.max(.001,de(\"depth\")*.5),x=Math.min(Math.max(0,de(\"bevel\")),b);let xe=Kh(t),Ae=xe?Math.min(.5,xe.hwf+.02):.5,De=xe?Math.min(.5,xe.hhf+.02):.5,Ee=a();P=Math.hypot(Ae,De,b)+x+.03+Ee;let ze=de(\"rotX\")*rd,Ie=de(\"rotY\")*rd,ke=de(\"rotZ\")*rd;C=Math.cos(ze),E=Math.sin(ze),R=Math.cos(Ie),U=Math.sin(Ie),L=Math.cos(ke),k=Math.sin(ke);let Me={cx:C,sx:E,cy:R,sy:U,cz:L,sz:k},we=Jl(1,0,0,Me),Ve=Jl(0,1,0,Me),qe=x+.03+Ee,st=Math.abs(we.x)*Ae+Math.abs(we.y)*De+Math.abs(we.z)*b+qe,pt=Math.abs(Ve.x)*Ae+Math.abs(Ve.y)*De+Math.abs(Ve.z)*b+qe,Ze=st+.05,nt=pt+.05;D=Ze*2,O=nt*2,F=.5-Ze,q=.5-nt,V()};X();let Q=oe=>{oe!==Y&&(Y=oe,V())},te=()=>`${b},${x},${P},${l()}`,J=()=>`${te()},${D},${O},${C},${E},${R},${U},${L},${k}`;return{layout:c,marchParamsBuffer:d,sdfFn:_,sdfSourceTexture:i.texture,update:X,setActiveRes:Q,getStateKey:J,getFootprint:()=>({spanX:D,spanY:O,originX:F,originY:q,rBound:P}),getRotation:()=>({cx:C,sx:E,cy:R,sy:U,cz:L,sz:k}),getGeometryKey:te}}function QB(e,t,s,r,o={}){let a=o.extraPad??(()=>0),{layout:i}=hA(),l=(globalThis.__TYPEGPU_AUTONAME__??(L=>L))(e.createUniform(vl),\"marchParamsBuffer\"),c=P_(t),d=w.fn([A],n)((L=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(L.f=(k=>{\"use gpu\";let D=i.$.params,O=c(m(__tsover_add(k.x,.5),__tsover_sub(.5,k.y)),D.pA,D.pB,D.pC,D.pD,D.mb0.x,D.mb0.y,D.mb0.z,D.mb1.x).x,F=__tsover_sub(re(k.z),D.mb1.y),q=ye(B(O,F),n(0)),Y=he(m(B(O,n(0)),B(F,n(0))));return __tsover_add(q,Y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"}],body:[0,[[13,\"pp\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"uv\",[6,\"d.vec2f\",[[1,[7,\"p\",\"x\"],\"+\",[5,\"0.5\"]],[1,[5,\"0.5\"],\"-\",[7,\"p\",\"y\"]]]]],[13,\"d2\",[7,[6,\"analytic\",[\"uv\",[7,\"pp\",\"pA\"],[7,\"pp\",\"pB\"],[7,\"pp\",\"pC\"],[7,\"pp\",\"pD\"],[7,[7,\"pp\",\"mb0\"],\"x\"],[7,[7,\"pp\",\"mb0\"],\"y\"],[7,[7,\"pp\",\"mb0\"],\"z\"],[7,[7,\"pp\",\"mb1\"],\"x\"]]],\"x\"]],[13,\"wz\",[1,[6,\"std.abs\",[[7,\"p\",\"z\"]]],\"-\",[7,[7,\"pp\",\"mb1\"],\"y\"]]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"d2\",\"wz\"]],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec2f\",[[6,\"std.max\",[\"d2\",[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[\"wz\",[6,\"d.f32\",[[5,\"0\"]]]]]]]]]],[10,[1,\"inner\",\"+\",\"outer\"]]]]},externals:{layout:()=>i,\"d.vec2f\":()=>m,analytic:()=>c,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.max\":()=>B,\"d.f32\":()=>n,\"std.length\":()=>he}})&&L.f)({})),u=\"\",p=xA(s()),_=Hv(p),f=.06,h=.6,g=1,y=1,b=0,x=0,P=E_(),C=()=>{l.write({rot:{cx:1,sx:0,cy:1,sy:0,cz:1,sz:0},rBound:h,spanX:g,spanY:y,originX:b,originY:x,activeRes:P,pA:_.radius,pB:_.sides,pC:_.rounding,pD:_.innerRatio,mb0:A(_.rotation,_.height,_.offset),mb1:A(_.aperture,f,0),mb2:A(0,0,0),mb3:A(0,0,0),mb4:A(0,0,0),mb5:A(0,0,0),mb6:A(0,0,0),mb7:A(0,0,0)})},E=()=>{let L=s();if(L&&typeof L==\"object\")p=L;else if(typeof L==\"string\"&&L!==u){u=L;try{p=JSON.parse(L)}catch{}}_=Hv(p),f=Math.max(.001,r());let{hwf:k,hhf:D}=Jb({shape:{...p,radius:_.radius,height:_.height}});h=Math.hypot(k,D,f)+.02+a();let O=h+.05;g=O*2,y=O*2,b=.5-O,x=.5-O,C()};E();let R=L=>{L!==P&&(P=L,C())},U=()=>`${_.radius},${_.sides},${_.rounding},${_.innerRatio},${_.rotation},${_.height},${_.offset},${_.aperture},${f},${h}`;return{layout:i,marchParamsBuffer:l,sdfFn:d,update:E,setActiveRes:R,getStateKey:U,getFootprint:()=>({spanX:g,spanY:y,originX:b,originY:x,rBound:h}),getRotation:()=>({cx:1,sx:0,cy:1,sy:0,cz:1,sz:0}),getGeometryKey:U}}function _ne(e,t,s=\"none\",r=\"span\"){let o=e.gpu?.root;if(!o)return null;let a=xA(t()),i=e.getCpuValue(\"shapeSdfUrl\")||\"\",l=e.getCpuValue(\"shapeType\")||a.type||\"\",c=null;if(i&&Qh(l)?c=wA(e,i,t):!i&&M_(l)&&(c=AA(o,l,a,t)),!c)return null;let d=fA(c.sdfFn,s,r),u=gA(c.layout,d),p=yA(o,c.layout,u,e.onCleanup,{paramsUniform:c.marchParamsBuffer,sdfSourceTexture:c.sdfSourceTexture}),_=e.registerComputeTexture(p.fieldTexture),f=p.maxRes,h=\"\",g=Rr()?2:1,y=0,b={originX:0,originY:0,spanX:1,spanY:1,activeRes:1,rBound:.6};return{outputs:{volumetricFieldTexture:_},getComputeNodes:P=>{c.update(P);let C=c.getFootprint(),E=e.getCpuValue(\"scale\")??1,R=e.dimensions.height;f=vA(C.spanX,C.spanY,E,R,p.maxRes,f);let U=`${c.getStateKey()},${f}`;return U===h||(y++,g>1&&y%g!==0)?null:(h=U,c.setActiveRes(f),e.setExtraField(\"_vfOriginX\",C.originX),e.setExtraField(\"_vfOriginY\",C.originY),e.setExtraField(\"_vfSpanX\",C.spanX),e.setExtraField(\"_vfSpanY\",C.spanY),e.setExtraField(\"_vfActiveRes\",f),e.setExtraField(\"_vfRBound\",C.rBound),b.originX=C.originX,b.originY=C.originY,b.spanX=C.spanX,b.spanY=C.spanY,b.activeRes=f,b.rBound=C.rBound,[()=>p.dispatch(f)])},fieldTexture:p.fieldTexture,getFieldDomain:()=>({...b})}}var Zv=.08,Hr=w.fn([A,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=s.x,a=s.y,i=s.z,l=s.w,c=r.x,d=r.y,u=A(__tsover_add(__tsover_mul(t.x,i),__tsover_mul(t.z,l)),t.y,__tsover_add(__tsover_mul(__tsover_mul(t.x,l),-1),__tsover_mul(t.z,i))),p=A(u.x,__tsover_sub(__tsover_mul(u.y,o),__tsover_mul(u.z,a)),__tsover_add(__tsover_mul(u.y,a),__tsover_mul(u.z,o)));return A(__tsover_sub(__tsover_mul(p.x,c),__tsover_mul(p.y,d)),__tsover_add(__tsover_mul(p.x,d),__tsover_mul(p.y,c)),p.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"}],body:[0,[[13,\"cx\",[7,\"rp0\",\"x\"]],[13,\"sx\",[7,\"rp0\",\"y\"]],[13,\"cy\",[7,\"rp0\",\"z\"]],[13,\"sy\",[7,\"rp0\",\"w\"]],[13,\"cz\",[7,\"rp1\",\"x\"]],[13,\"sz\",[7,\"rp1\",\"y\"]],[13,\"py\",[6,\"d.vec3f\",[[1,[1,[7,\"p\",\"x\"],\"*\",\"cy\"],\"+\",[1,[7,\"p\",\"z\"],\"*\",\"sy\"]],[7,\"p\",\"y\"],[1,[1,[1,[7,\"p\",\"x\"],\"*\",\"sy\"],\"*\",[4,\"-\",[5,\"1\"]]],\"+\",[1,[7,\"p\",\"z\"],\"*\",\"cy\"]]]]],[13,\"px\",[6,\"d.vec3f\",[[7,\"py\",\"x\"],[1,[1,[7,\"py\",\"y\"],\"*\",\"cx\"],\"-\",[1,[7,\"py\",\"z\"],\"*\",\"sx\"]],[1,[1,[7,\"py\",\"y\"],\"*\",\"sx\"],\"+\",[1,[7,\"py\",\"z\"],\"*\",\"cx\"]]]]],[10,[6,\"d.vec3f\",[[1,[1,[7,\"px\",\"x\"],\"*\",\"cz\"],\"-\",[1,[7,\"px\",\"y\"],\"*\",\"sz\"]],[1,[1,[7,\"px\",\"x\"],\"*\",\"sz\"],\"+\",[1,[7,\"px\",\"y\"],\"*\",\"cz\"]],[7,\"px\",\"z\"]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})).$name(\"eulerRotatePacked\"),TA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";return __tsover_sub(he(Hr(t,s,r)),r.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[10,[1,[6,\"std.length\",[[6,\"eulerRotatePacked\",[\"p\",\"rp0\",\"rp1\"]]]],\"-\",[7,\"rp1\",\"z\"]]]]]},externals:{\"std.length\":()=>he,eulerRotatePacked:()=>Hr}})&&e.f)({})).$name(\"paramSphereSdf\"),SA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=vs(Hr(t,r,o));return m(__tsover_add(__tsover_div(Xt(l.z,l.x),6.283185307179586),.5),__tsover_mul(__tsover_add(l.y,1),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"n\",[6,\"std.normalize\",[[6,\"eulerRotatePacked\",[\"h\",\"rp0\",\"rp1\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,[6,\"std.atan2\",[[7,\"n\",\"z\"],[7,\"n\",\"x\"]]],\"/\",[5,\"6.283185307179586\"]],\"+\",[5,\"0.5\"]],[1,[1,[7,\"n\",\"y\"],\"+\",[5,\"1\"]],\"*\",[5,\"0.5\"]]]]]]]},externals:{\"std.normalize\":()=>vs,eulerRotatePacked:()=>Hr,\"d.vec2f\":()=>m,\"std.atan2\":()=>Xt}})&&e.f)({})).$name(\"sphereSurfaceUV\"),PA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Hr(t,s,r),l=m(__tsover_sub(he(m(i.x,i.z)),r.z),i.y);return __tsover_sub(he(l),r.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"p\",\"rp0\",\"rp1\"]]],[13,\"q\",[6,\"d.vec2f\",[[1,[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"rp\",\"x\"],[7,\"rp\",\"z\"]]]]],\"-\",[7,\"rp1\",\"z\"]],[7,\"rp\",\"y\"]]]],[10,[1,[6,\"std.length\",[\"q\"]],\"-\",[7,\"rp1\",\"w\"]]]]]},externals:{eulerRotatePacked:()=>Hr,\"d.vec2f\":()=>m,\"std.length\":()=>he}})&&e.f)({})).$name(\"paramTorusSdf\"),CA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Hr(t,r,o),c=__tsover_add(__tsover_div(Xt(l.z,l.x),6.283185307179586),.5),d=__tsover_sub(he(m(l.x,l.z)),o.z);return m(c,__tsover_add(__tsover_div(Xt(l.y,d),6.283185307179586),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"h\",\"rp0\",\"rp1\"]]],[13,\"u\",[1,[1,[6,\"std.atan2\",[[7,\"rp\",\"z\"],[7,\"rp\",\"x\"]]],\"/\",[5,\"6.283185307179586\"]],\"+\",[5,\"0.5\"]]],[13,\"ringDist\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[7,\"rp\",\"x\"],[7,\"rp\",\"z\"]]]]],\"-\",[7,\"rp1\",\"z\"]]],[10,[6,\"d.vec2f\",[\"u\",[1,[1,[6,\"std.atan2\",[[7,\"rp\",\"y\"],\"ringDist\"]],\"/\",[5,\"6.283185307179586\"]],\"+\",[5,\"0.5\"]]]]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.atan2\":()=>Xt,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"torusSurfaceUV\"),MA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Hr(t,s,r),l=o.y,c=__tsover_add(__tsover_sub(re(i.x),r.z),l),d=__tsover_add(__tsover_sub(re(i.y),r.w),l),u=__tsover_add(__tsover_sub(re(i.z),o.x),l),p=he(A(B(c,n(0)),B(d,n(0)),B(u,n(0)))),_=ye(B(c,B(d,u)),n(0));return __tsover_sub(__tsover_add(p,_),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"p\",\"rp0\",\"rp1\"]]],[13,\"rounding\",[7,\"rp2\",\"y\"]],[13,\"qx\",[1,[1,[6,\"std.abs\",[[7,\"rp\",\"x\"]]],\"-\",[7,\"rp1\",\"z\"]],\"+\",\"rounding\"]],[13,\"qy\",[1,[1,[6,\"std.abs\",[[7,\"rp\",\"y\"]]],\"-\",[7,\"rp1\",\"w\"]],\"+\",\"rounding\"]],[13,\"qz\",[1,[1,[6,\"std.abs\",[[7,\"rp\",\"z\"]]],\"-\",[7,\"rp2\",\"x\"]],\"+\",\"rounding\"]],[13,\"outer\",[6,\"std.length\",[[6,\"d.vec3f\",[[6,\"std.max\",[\"qx\",[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[\"qy\",[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[\"qz\",[6,\"d.f32\",[[5,\"0\"]]]]]]]]]],[13,\"inner\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",[6,\"std.max\",[\"qy\",\"qz\"]]]],[6,\"d.f32\",[[5,\"0\"]]]]]],[10,[1,[1,\"outer\",\"+\",\"inner\"],\"-\",\"rounding\"]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.abs\":()=>re,\"std.length\":()=>he,\"d.vec3f\":()=>A,\"std.max\":()=>B,\"d.f32\":()=>n,\"std.min\":()=>ye}})&&e.f)({})).$name(\"paramBoxSdf\"),EA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Hr(t,r,o),c=Hr(s,r,o),d=A(re(c.x),re(c.y),re(c.z)),u=o.z,p=o.w,_=a.x,f=__tsover_div(.5,B(p,_)),h=__tsover_div(.5,B(u,_)),g=__tsover_div(.5,B(u,p)),y=m(__tsover_add(__tsover_mul(l.z,f),.5),__tsover_add(__tsover_mul(l.y,f),.5)),b=m(__tsover_add(__tsover_mul(l.x,h),.5),__tsover_add(__tsover_mul(l.z,h),.5)),x=m(__tsover_add(__tsover_mul(l.x,g),.5),__tsover_add(__tsover_mul(l.y,g),.5)),P=N(x,y,d.x>d.z);return N(N(x,b,d.y>d.z),P,d.x>d.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"h\",\"rp0\",\"rp1\"]]],[13,\"rn\",[6,\"eulerRotatePacked\",[\"n\",\"rp0\",\"rp1\"]]],[13,\"an\",[6,\"d.vec3f\",[[6,\"std.abs\",[[7,\"rn\",\"x\"]]],[6,\"std.abs\",[[7,\"rn\",\"y\"]]],[6,\"std.abs\",[[7,\"rn\",\"z\"]]]]]],[13,\"hx\",[7,\"rp1\",\"z\"]],[13,\"hy\",[7,\"rp1\",\"w\"]],[13,\"hz\",[7,\"rp2\",\"x\"]],[13,\"scaleX\",[1,[5,\"0.5\"],\"/\",[6,\"std.max\",[\"hy\",\"hz\"]]]],[13,\"scaleY\",[1,[5,\"0.5\"],\"/\",[6,\"std.max\",[\"hx\",\"hz\"]]]],[13,\"scaleZ\",[1,[5,\"0.5\"],\"/\",[6,\"std.max\",[\"hx\",\"hy\"]]]],[13,\"uvX\",[6,\"d.vec2f\",[[1,[1,[7,\"rp\",\"z\"],\"*\",\"scaleX\"],\"+\",[5,\"0.5\"]],[1,[1,[7,\"rp\",\"y\"],\"*\",\"scaleX\"],\"+\",[5,\"0.5\"]]]]],[13,\"uvY\",[6,\"d.vec2f\",[[1,[1,[7,\"rp\",\"x\"],\"*\",\"scaleY\"],\"+\",[5,\"0.5\"]],[1,[1,[7,\"rp\",\"z\"],\"*\",\"scaleY\"],\"+\",[5,\"0.5\"]]]]],[13,\"uvZ\",[6,\"d.vec2f\",[[1,[1,[7,\"rp\",\"x\"],\"*\",\"scaleZ\"],\"+\",[5,\"0.5\"]],[1,[1,[7,\"rp\",\"y\"],\"*\",\"scaleZ\"],\"+\",[5,\"0.5\"]]]]],[13,\"pickXZ\",[6,\"std.select\",[\"uvZ\",\"uvX\",[1,[7,\"an\",\"x\"],\">\",[7,\"an\",\"z\"]]]]],[13,\"pickYZ\",[6,\"std.select\",[\"uvZ\",\"uvY\",[1,[7,\"an\",\"y\"],\">\",[7,\"an\",\"z\"]]]]],[10,[6,\"std.select\",[\"pickYZ\",\"pickXZ\",[1,[7,\"an\",\"x\"],\">\",[7,\"an\",\"y\"]]]]]]]},externals:{eulerRotatePacked:()=>Hr,\"d.vec3f\":()=>A,\"std.abs\":()=>re,\"std.max\":()=>B,\"d.vec2f\":()=>m,\"std.select\":()=>N}})&&e.f)({})).$name(\"boxFaceUV\"),kA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Hr(t,s,r),l=r.z,c=r.w,d=G(i.y,__tsover_mul(c,-1),c);return __tsover_sub(he(A(i.x,__tsover_sub(i.y,d),i.z)),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"p\",\"rp0\",\"rp1\"]]],[13,\"radius\",[7,\"rp1\",\"z\"]],[13,\"halfHeight\",[7,\"rp1\",\"w\"]],[13,\"clampedY\",[6,\"std.clamp\",[[7,\"rp\",\"y\"],[1,\"halfHeight\",\"*\",[4,\"-\",[5,\"1\"]]],\"halfHeight\"]]],[10,[1,[6,\"std.length\",[[6,\"d.vec3f\",[[7,\"rp\",\"x\"],[1,[7,\"rp\",\"y\"],\"-\",\"clampedY\"],[7,\"rp\",\"z\"]]]]],\"-\",\"radius\"]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec3f\":()=>A}})&&e.f)({})).$name(\"paramCapsuleSdf\"),BA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Hr(t,r,o),c=__tsover_add(__tsover_div(Xt(l.z,l.x),6.283185307179586),.5),d=__tsover_add(o.w,o.z);return m(c,G(__tsover_add(__tsover_mul(__tsover_div(l.y,d),.5),.5),0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"h\",\"rp0\",\"rp1\"]]],[13,\"u\",[1,[1,[6,\"std.atan2\",[[7,\"rp\",\"z\"],[7,\"rp\",\"x\"]]],\"/\",[5,\"6.283185307179586\"]],\"+\",[5,\"0.5\"]]],[13,\"span\",[1,[7,\"rp1\",\"w\"],\"+\",[7,\"rp1\",\"z\"]]],[10,[6,\"d.vec2f\",[\"u\",[6,\"std.clamp\",[[1,[1,[1,[7,\"rp\",\"y\"],\"/\",\"span\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]]]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.atan2\":()=>Xt,\"d.vec2f\":()=>m,\"std.clamp\":()=>G}})&&e.f)({})).$name(\"capsuleSurfaceUV\"),zA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=Hr(t,s,r),l=r.z,c=r.w,d=o.x,u=Xt(i.z,i.x),p=A(__tsover_mul(pe(u),l),0,__tsover_mul(ae(u),l)),_=A(__tsover_sub(i.x,p.x),__tsover_sub(i.y,p.y),__tsover_sub(i.z,p.z)),f=__tsover_mul(u,.5),h=A(__tsover_mul(pe(u),pe(f)),ae(f),__tsover_mul(ae(u),pe(f))),g=Se(_,h),y=B(__tsover_sub(re(g),c),n(0)),b=A(__tsover_sub(_.x,__tsover_mul(h.x,g)),__tsover_sub(_.y,__tsover_mul(h.y,g)),__tsover_sub(_.z,__tsover_mul(h.z,g)));return __tsover_sub(he(m(y,he(b))),d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"p\",\"rp0\",\"rp1\"]]],[13,\"ringRadius\",[7,\"rp1\",\"z\"]],[13,\"halfWidth\",[7,\"rp1\",\"w\"]],[13,\"thickness\",[7,\"rp2\",\"x\"]],[13,\"phi\",[6,\"std.atan2\",[[7,\"rp\",\"z\"],[7,\"rp\",\"x\"]]]],[13,\"spine\",[6,\"d.vec3f\",[[1,[6,\"std.cos\",[\"phi\"]],\"*\",\"ringRadius\"],[5,\"0\"],[1,[6,\"std.sin\",[\"phi\"]],\"*\",\"ringRadius\"]]]],[13,\"dvec\",[6,\"d.vec3f\",[[1,[7,\"rp\",\"x\"],\"-\",[7,\"spine\",\"x\"]],[1,[7,\"rp\",\"y\"],\"-\",[7,\"spine\",\"y\"]],[1,[7,\"rp\",\"z\"],\"-\",[7,\"spine\",\"z\"]]]]],[13,\"halfPhi\",[1,\"phi\",\"*\",[5,\"0.5\"]]],[13,\"ev\",[6,\"d.vec3f\",[[1,[6,\"std.cos\",[\"phi\"]],\"*\",[6,\"std.cos\",[\"halfPhi\"]]],[6,\"std.sin\",[\"halfPhi\"]],[1,[6,\"std.sin\",[\"phi\"]],\"*\",[6,\"std.cos\",[\"halfPhi\"]]]]]],[13,\"vProj\",[6,\"std.dot\",[\"dvec\",\"ev\"]]],[13,\"du\",[6,\"std.max\",[[1,[6,\"std.abs\",[\"vProj\"]],\"-\",\"halfWidth\"],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"perp\",[6,\"d.vec3f\",[[1,[7,\"dvec\",\"x\"],\"-\",[1,[7,\"ev\",\"x\"],\"*\",\"vProj\"]],[1,[7,\"dvec\",\"y\"],\"-\",[1,[7,\"ev\",\"y\"],\"*\",\"vProj\"]],[1,[7,\"dvec\",\"z\"],\"-\",[1,[7,\"ev\",\"z\"],\"*\",\"vProj\"]]]]],[10,[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"du\",[6,\"std.length\",[\"perp\"]]]]]],\"-\",\"thickness\"]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.atan2\":()=>Xt,\"d.vec3f\":()=>A,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"std.max\":()=>B,\"std.abs\":()=>re,\"d.f32\":()=>n,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"paramMobiusSdf\"),RA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=Hr(t,r,o),c=o.z,d=o.w,u=Xt(l.z,l.x),p=A(__tsover_mul(pe(u),c),0,__tsover_mul(ae(u),c)),_=A(__tsover_sub(l.x,p.x),__tsover_sub(l.y,p.y),__tsover_sub(l.z,p.z)),f=__tsover_mul(u,.5),h=Se(_,A(__tsover_mul(pe(u),pe(f)),ae(f),__tsover_mul(ae(u),pe(f))));return m(__tsover_add(__tsover_div(u,6.283185307179586),.5),__tsover_add(__tsover_mul(__tsover_div(h,d),.5),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"_t\"}],body:[0,[[13,\"rp\",[6,\"eulerRotatePacked\",[\"h\",\"rp0\",\"rp1\"]]],[13,\"ringRadius\",[7,\"rp1\",\"z\"]],[13,\"halfWidth\",[7,\"rp1\",\"w\"]],[13,\"phi\",[6,\"std.atan2\",[[7,\"rp\",\"z\"],[7,\"rp\",\"x\"]]]],[13,\"spine\",[6,\"d.vec3f\",[[1,[6,\"std.cos\",[\"phi\"]],\"*\",\"ringRadius\"],[5,\"0\"],[1,[6,\"std.sin\",[\"phi\"]],\"*\",\"ringRadius\"]]]],[13,\"dvec\",[6,\"d.vec3f\",[[1,[7,\"rp\",\"x\"],\"-\",[7,\"spine\",\"x\"]],[1,[7,\"rp\",\"y\"],\"-\",[7,\"spine\",\"y\"]],[1,[7,\"rp\",\"z\"],\"-\",[7,\"spine\",\"z\"]]]]],[13,\"halfPhi\",[1,\"phi\",\"*\",[5,\"0.5\"]]],[13,\"ev\",[6,\"d.vec3f\",[[1,[6,\"std.cos\",[\"phi\"]],\"*\",[6,\"std.cos\",[\"halfPhi\"]]],[6,\"std.sin\",[\"halfPhi\"]],[1,[6,\"std.sin\",[\"phi\"]],\"*\",[6,\"std.cos\",[\"halfPhi\"]]]]]],[13,\"vProj\",[6,\"std.dot\",[\"dvec\",\"ev\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"phi\",\"/\",[5,\"6.283185307179586\"]],\"+\",[5,\"0.5\"]],[1,[1,[1,\"vProj\",\"/\",\"halfWidth\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]]},externals:{eulerRotatePacked:()=>Hr,\"std.atan2\":()=>Xt,\"d.vec3f\":()=>A,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.dot\":()=>Se,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"mobiusSurfaceUV\"),DA=w.fn([A,S,S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=s.x,l=s.y,c=s.z,d=r.x,u=r.y,p=r.z,_=pe(i),f=ae(i),h=__tsover_add(__tsover_mul(t.x,_),__tsover_mul(t.y,f)),g=__tsover_add(__tsover_mul(__tsover_mul(t.x,f),-1),__tsover_mul(t.y,_)),y=__tsover_add(__tsover_add(__tsover_mul(h,l),u),__tsover_mul(a,Zv)),b=pe(y),x=ae(y),P=__tsover_add(__tsover_mul(g,b),__tsover_mul(t.z,x)),C=__tsover_add(__tsover_mul(__tsover_mul(g,x),-1),__tsover_mul(t.z,b)),E=B(__tsover_sub(re(P),c),n(0));return __tsover_div(__tsover_sub(he(m(E,C)),d),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"angleRad\",[7,\"rp0\",\"x\"]],[13,\"twist\",[7,\"rp0\",\"y\"]],[13,\"halfW\",[7,\"rp0\",\"z\"]],[13,\"thickness\",[7,\"rp1\",\"x\"]],[13,\"phase\",[7,\"rp1\",\"y\"]],[13,\"lipschitz\",[7,\"rp1\",\"z\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rpx\",[1,[1,[7,\"p\",\"x\"],\"*\",\"cosA\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"sinA\"]]],[13,\"rpy\",[1,[1,[1,[7,\"p\",\"x\"],\"*\",\"sinA\"],\"*\",[4,\"-\",[5,\"1\"]]],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"cosA\"]]],[13,\"twistAngle\",[1,[1,[1,\"rpx\",\"*\",\"twist\"],\"+\",\"phase\"],\"+\",[1,\"t\",\"*\",\"TWISTED_RIBBON_TWIST_RATE\"]]],[13,\"ca\",[6,\"std.cos\",[\"twistAngle\"]]],[13,\"sa\",[6,\"std.sin\",[\"twistAngle\"]]],[13,\"localU\",[1,[1,\"rpy\",\"*\",\"ca\"],\"+\",[1,[7,\"p\",\"z\"],\"*\",\"sa\"]]],[13,\"localV\",[1,[1,[1,\"rpy\",\"*\",\"sa\"],\"*\",[4,\"-\",[5,\"1\"]]],\"+\",[1,[7,\"p\",\"z\"],\"*\",\"ca\"]]],[13,\"du\",[6,\"std.max\",[[1,[6,\"std.abs\",[\"localU\"]],\"-\",\"halfW\"],[6,\"d.f32\",[[5,\"0\"]]]]]],[10,[1,[1,[6,\"std.length\",[[6,\"d.vec2f\",[\"du\",\"localV\"]]]],\"-\",\"thickness\"],\"/\",\"lipschitz\"]]]]},externals:{\"std.cos\":()=>pe,\"std.sin\":()=>ae,TWISTED_RIBBON_TWIST_RATE:()=>Zv,\"std.max\":()=>B,\"std.abs\":()=>re,\"d.f32\":()=>n,\"std.length\":()=>he,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"paramTwistedRibbonSdf\"),LA=w.fn([A,A,S,S,S,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=r.x,c=r.y,d=r.z,u=r.w,p=o.y,_=pe(l),f=ae(l),h=__tsover_add(__tsover_mul(t.x,_),__tsover_mul(t.y,f)),g=__tsover_add(__tsover_mul(__tsover_mul(t.x,f),-1),__tsover_mul(t.y,_)),y=__tsover_add(__tsover_add(__tsover_mul(h,c),p),__tsover_mul(i,Zv)),b=pe(y),x=ae(y),P=B(ye(__tsover_add(__tsover_mul(g,b),__tsover_mul(t.z,x)),d),__tsover_mul(d,-1));return m(__tsover_add(__tsover_mul(h,.15),.5),__tsover_add(__tsover_div(P,u),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"h\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"_rp2\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"angleRad\",[7,\"rp0\",\"x\"]],[13,\"twist\",[7,\"rp0\",\"y\"]],[13,\"halfW\",[7,\"rp0\",\"z\"]],[13,\"width\",[7,\"rp0\",\"w\"]],[13,\"phase\",[7,\"rp1\",\"y\"]],[13,\"cosA\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"sinA\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"rpx\",[1,[1,[7,\"h\",\"x\"],\"*\",\"cosA\"],\"+\",[1,[7,\"h\",\"y\"],\"*\",\"sinA\"]]],[13,\"rpy\",[1,[1,[1,[7,\"h\",\"x\"],\"*\",\"sinA\"],\"*\",[4,\"-\",[5,\"1\"]]],\"+\",[1,[7,\"h\",\"y\"],\"*\",\"cosA\"]]],[13,\"twistAngle\",[1,[1,[1,\"rpx\",\"*\",\"twist\"],\"+\",\"phase\"],\"+\",[1,\"t\",\"*\",\"TWISTED_RIBBON_TWIST_RATE\"]]],[13,\"ca\",[6,\"std.cos\",[\"twistAngle\"]]],[13,\"sa\",[6,\"std.sin\",[\"twistAngle\"]]],[13,\"localU\",[1,[1,\"rpy\",\"*\",\"ca\"],\"+\",[1,[7,\"h\",\"z\"],\"*\",\"sa\"]]],[13,\"localUClamped\",[6,\"std.max\",[[6,\"std.min\",[\"localU\",\"halfW\"]],[1,\"halfW\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[10,[6,\"d.vec2f\",[[1,[1,\"rpx\",\"*\",[5,\"0.15\"]],\"+\",[5,\"0.5\"]],[1,[1,\"localUClamped\",\"/\",\"width\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{\"std.cos\":()=>pe,\"std.sin\":()=>ae,TWISTED_RIBBON_TWIST_RATE:()=>Zv,\"std.max\":()=>B,\"std.min\":()=>ye,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"twistedRibbonSurfaceUV\");function UA(e,t){let s={};return t.forEach((r,o)=>{s[`${e}${o}`]={schema:S,initial:r}}),s}var Lm=Rr()?128:192,OA=Math.ceil(Lm/4)*Lm*Lm,sl=Rr()?512:1024,ZB=\"r32float\",m1=Math.PI/180,fne=.8660254,yP=1.74,I0=2.39996323,bP=.27,xP=1e9,GA=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cam:UM(16,OM(32,Ad)),lightDir:A,voxelSize:n,lightT1:A,fill:n,lightT2:A,voxelScale:n,bevel:n,gridOrigin:n,gridN:n,gridW:n}),\"VoxelMarchParams\");function vne(){return w.bindGroupLayout({vox:{uniform:GA},occ:{storage:Fe(M,OA),access:\"readonly\"},shadowMap:{storageTexture:zt(ZB,\"write-only\")}})}function hne(){return w.bindGroupLayout({vox:{uniform:GA},occ:{storage:Fe(M,OA),access:\"mutable\"}})}function gne(e,t,s,r){let o=w.fn([A],A)((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=(i=>{\"use gpu\";return r===\"view\"?ja(ja(i,s.$.vox.cam),t.$.params.rot):A(i.x,i.y,i.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pG\"}],body:[0,[[11,[1,\"gridSpace\",\"===\",[103,\"view\"]],[10,[6,\"rotateVec3\",[[6,\"rotateVec3\",[\"pG\",[7,[7,[7,\"bakeLayout\",\"$\"],\"vox\"],\"cam\"]]],[7,[7,[7,\"marchLayout\",\"$\"],\"params\"],\"rot\"]]]],[10,[6,\"d.vec3f\",[[7,\"pG\",\"x\"],[7,\"pG\",\"y\"],[7,\"pG\",\"z\"]]]]]]]},externals:{gridSpace:()=>r,rotateVec3:()=>ja,bakeLayout:()=>s,marchLayout:()=>t,\"d.vec3f\":()=>A}})&&a.f)({}));return w.fn([M,M,M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l,c)=>{\"use gpu\";let d=s.$.vox,u=M(d.gridN),p=M(d.gridW);if(i<p&&l<u&&c<u){let _=d.voxelSize,f=d.gridOrigin,h=M(0),g=M(1);for(let y=0;y<4;y++){let b=__tsover_add(__tsover_mul(i,M(4)),M(y)),x=M(1);if(b<u){let P=e(o(A(__tsover_add(__tsover_mul(__tsover_add(n(b),.5),_),f),__tsover_add(__tsover_mul(__tsover_add(n(l),.5),_),f),__tsover_add(__tsover_mul(__tsover_add(n(c),.5),_),f)))),C=G(__tsover_sub(__tsover_sub(__tsover_div(P,_),d.fill),yP),0,254);x=N(__tsover_add(M(1),M(ie(C))),M(0),P<__tsover_mul(d.fill,_))}h=__tsover_add(h,__tsover_mul(x,g)),g=__tsover_mul(g,M(256))}s.$.occ[__tsover_add(i,__tsover_mul(__tsover_add(l,__tsover_mul(c,u)),p))]=h}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"wx\"},{type:\"i\",name:\"iy\"},{type:\"i\",name:\"iz\"}],body:[0,[[13,\"vx\",[7,[7,\"bakeLayout\",\"$\"],\"vox\"]],[13,\"n\",[6,\"d.u32\",[[7,\"vx\",\"gridN\"]]]],[13,\"w\",[6,\"d.u32\",[[7,\"vx\",\"gridW\"]]]],[11,[3,[3,[1,\"wx\",\"<\",\"w\"],\"&&\",[1,\"iy\",\"<\",\"n\"]],\"&&\",[1,\"iz\",\"<\",\"n\"]],[0,[[13,\"v\",[7,\"vx\",\"voxelSize\"]],[13,\"o\",[7,\"vx\",\"gridOrigin\"]],[12,\"word\",[6,\"d.u32\",[[5,\"0\"]]]],[12,\"scale\",[6,\"d.u32\",[[5,\"1\"]]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",[5,\"4\"]],[102,\"++\",\"k\"],[0,[[13,\"ix\",[1,[1,\"wx\",\"*\",[6,\"d.u32\",[[5,\"4\"]]]],\"+\",[6,\"d.u32\",[\"k\"]]]],[12,\"val\",[6,\"d.u32\",[[5,\"1\"]]]],[11,[1,\"ix\",\"<\",\"n\"],[0,[[13,\"c\",[6,\"d.vec3f\",[[1,[1,[1,[6,\"d.f32\",[\"ix\"]],\"+\",[5,\"0.5\"]],\"*\",\"v\"],\"+\",\"o\"],[1,[1,[1,[6,\"d.f32\",[\"iy\"]],\"+\",[5,\"0.5\"]],\"*\",\"v\"],\"+\",\"o\"],[1,[1,[1,[6,\"d.f32\",[\"iz\"]],\"+\",[5,\"0.5\"]],\"*\",\"v\"],\"+\",\"o\"]]]],[13,\"dd\",[6,\"sdfFn\",[[6,\"gridToShape\",[\"c\"]]]]],[13,\"clear\",[6,\"std.clamp\",[[1,[1,[1,\"dd\",\"/\",\"v\"],\"-\",[7,\"vx\",\"fill\"]],\"-\",\"CLEARANCE_MARGIN\"],[5,\"0\"],[5,\"254\"]]]],[2,\"val\",\"=\",[6,\"std.select\",[[1,[6,\"d.u32\",[[5,\"1\"]]],\"+\",[6,\"d.u32\",[[6,\"std.floor\",[\"clear\"]]]]],[6,\"d.u32\",[[5,\"0\"]]],[1,\"dd\",\"<\",[1,[7,\"vx\",\"fill\"],\"*\",\"v\"]]]]]]]],[2,\"word\",\"=\",[1,\"word\",\"+\",[1,\"val\",\"*\",\"scale\"]]],[2,\"scale\",\"=\",[1,\"scale\",\"*\",[6,\"d.u32\",[[5,\"256\"]]]]]]]],[2,[8,[7,[7,\"bakeLayout\",\"$\"],\"occ\"],[1,\"wx\",\"+\",[1,[1,\"iy\",\"+\",[1,\"iz\",\"*\",\"n\"]],\"*\",\"w\"]]],\"=\",\"word\"]]]]]]},externals:{bakeLayout:()=>s,\"d.u32\":()=>M,\"d.vec3f\":()=>A,\"d.f32\":()=>n,sdfFn:()=>e,gridToShape:()=>o,\"std.clamp\":()=>G,CLEARANCE_MARGIN:()=>yP,\"std.select\":()=>N,\"std.floor\":()=>ie}})&&a.f)({})).$name(\"voxelGridBake\")}function JB(e,t){let s=w.fn([n,n,n],n)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=e.$.vox,f=_.gridN,h=n(1);if(d>=0&&d<f&&u>=0&&u<f&&p>=0&&p<f){let g=ie(__tsover_mul(d,.25)),y=__tsover_sub(d,__tsover_mul(g,4)),b=__tsover_add(M(g),__tsover_mul(__tsover_add(M(u),__tsover_mul(M(p),M(f))),M(_.gridW))),x=e.$.occ[b];h=n(p7(x,__tsover_mul(M(y),M(8)),M(8)))}return h}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"},{type:\"i\",name:\"cz\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[13,\"n\",[7,\"vx\",\"gridN\"]],[12,\"out\",[6,\"d.f32\",[[5,\"1\"]]]],[11,[3,[3,[3,[3,[3,[1,\"cx\",\">=\",[5,\"0\"]],\"&&\",[1,\"cx\",\"<\",\"n\"]],\"&&\",[1,\"cy\",\">=\",[5,\"0\"]]],\"&&\",[1,\"cy\",\"<\",\"n\"]],\"&&\",[1,\"cz\",\">=\",[5,\"0\"]]],\"&&\",[1,\"cz\",\"<\",\"n\"]],[0,[[13,\"wx\",[6,\"std.floor\",[[1,\"cx\",\"*\",[5,\"0.25\"]]]]],[13,\"sub\",[1,\"cx\",\"-\",[1,\"wx\",\"*\",[5,\"4\"]]]],[13,\"idx\",[1,[6,\"d.u32\",[\"wx\"]],\"+\",[1,[1,[6,\"d.u32\",[\"cy\"]],\"+\",[1,[6,\"d.u32\",[\"cz\"]],\"*\",[6,\"d.u32\",[\"n\"]]]],\"*\",[6,\"d.u32\",[[7,\"vx\",\"gridW\"]]]]]],[13,\"word\",[8,[7,[7,\"voxLayout\",\"$\"],\"occ\"],\"idx\"]],[2,\"out\",\"=\",[6,\"d.f32\",[[6,\"std.extractBits\",[\"word\",[1,[6,\"d.u32\",[\"sub\"]],\"*\",[6,\"d.u32\",[[5,\"8\"]]]],[6,\"d.u32\",[[5,\"8\"]]]]]]]]]]],[10,\"out\"]]]},externals:{voxLayout:()=>e,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"std.extractBits\":()=>p7}})&&c.f)({})),r=w.fn([n,n,n],A)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=e.$.vox;return A(__tsover_add(__tsover_mul(__tsover_add(d,.5),_.voxelSize),_.gridOrigin),__tsover_add(__tsover_mul(__tsover_add(u,.5),_.voxelSize),_.gridOrigin),__tsover_add(__tsover_mul(__tsover_add(p,.5),_.voxelSize),_.gridOrigin))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"},{type:\"i\",name:\"cz\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[10,[6,\"d.vec3f\",[[1,[1,[1,\"cx\",\"+\",[5,\"0.5\"]],\"*\",[7,\"vx\",\"voxelSize\"]],\"+\",[7,\"vx\",\"gridOrigin\"]],[1,[1,[1,\"cy\",\"+\",[5,\"0.5\"]],\"*\",[7,\"vx\",\"voxelSize\"]],\"+\",[7,\"vx\",\"gridOrigin\"]],[1,[1,[1,\"cz\",\"+\",[5,\"0.5\"]],\"*\",[7,\"vx\",\"voxelSize\"]],\"+\",[7,\"vx\",\"gridOrigin\"]]]]]]]},externals:{voxLayout:()=>e,\"d.vec3f\":()=>A}})&&c.f)({})),o=w.fn([n,n,n],n)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";return N(n(0),n(1),s(d,u,p)<.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"},{type:\"i\",name:\"cz\"}],body:[0,[[10,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[6,\"cellValue\",[\"cx\",\"cy\",\"cz\"]],\"<\",[5,\"0.5\"]]]]]]]},externals:{\"std.select\":()=>N,\"d.f32\":()=>n,cellValue:()=>s}})&&c.f)({})),a=(globalThis.__TYPEGPU_AUTONAME__??(c=>c))(gt({hit:n,t:n}),\"SubHit\"),i=w.fn([A,A,A,n],a)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p,_)=>{\"use gpu\";let f=e.$.vox,h=__tsover_mul(__tsover_mul(f.voxelSize,.5),f.voxelScale),g=n(0),y=_;if(t===\"sphere\"){let b=d.sub(p),x=Se(b,u),P=__tsover_sub(Se(b,b),__tsover_mul(h,h)),C=__tsover_sub(__tsover_mul(x,x),P);if(C>=0){let E=__tsover_sub(__tsover_mul(x,-1),Ue(C));E>=__tsover_sub(_,1e-4)&&(g=n(1),y=E)}}else{let b=N(n(-1),n(1),u.x>=0),x=N(n(-1),n(1),u.y>=0),P=N(n(-1),n(1),u.z>=0),C=__tsover_div(b,B(re(u.x),1e-6)),E=__tsover_div(x,B(re(u.y),1e-6)),R=__tsover_div(P,B(re(u.z),1e-6)),U=__tsover_mul(__tsover_sub(__tsover_sub(p.x,h),d.x),C),L=__tsover_mul(__tsover_sub(__tsover_add(p.x,h),d.x),C),k=__tsover_mul(__tsover_sub(__tsover_sub(p.y,h),d.y),E),D=__tsover_mul(__tsover_sub(__tsover_add(p.y,h),d.y),E),O=__tsover_mul(__tsover_sub(__tsover_sub(p.z,h),d.z),R),F=__tsover_mul(__tsover_sub(__tsover_add(p.z,h),d.z),R),q=B(ye(U,L),B(ye(k,D),ye(O,F))),Y=ye(B(U,L),ye(B(k,D),B(O,F)));if(q<=Y&&Y>=__tsover_sub(_,1e-4))if(t===\"rounded\"){let V=__tsover_mul(G(f.bevel,n(0),n(1)),h),X=B(q,__tsover_sub(_,1e-4));for(let Q=0;Q<12;Q++){let te=xd(d.add(u.mul(X)).sub(p),h,h,h,V);if(te<__tsover_mul(h,.003)){g=n(1);break}if(X=__tsover_add(X,te),X>Y)break}y=X}else g=n(1),y=B(q,_)}return a({hit:g,t:y})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ro\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"c\"},{type:\"i\",name:\"tNow\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[13,\"h\",[1,[1,[7,\"vx\",\"voxelSize\"],\"*\",[5,\"0.5\"]],\"*\",[7,\"vx\",\"voxelScale\"]]],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"t\",\"tNow\"],[11,[1,\"style\",\"===\",[103,\"sphere\"]],[0,[[13,\"oc\",[6,[7,\"ro\",\"sub\"],[\"c\"]]],[13,\"b\",[6,\"std.dot\",[\"oc\",\"rd\"]]],[13,\"cc\",[1,[6,\"std.dot\",[\"oc\",\"oc\"]],\"-\",[1,\"h\",\"*\",\"h\"]]],[13,\"disc\",[1,[1,\"b\",\"*\",\"b\"],\"-\",\"cc\"]],[11,[1,\"disc\",\">=\",[5,\"0\"]],[0,[[13,\"ts\",[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"-\",[6,\"std.sqrt\",[\"disc\"]]]],[11,[1,\"ts\",\">=\",[1,\"tNow\",\"-\",[5,\"0.0001\"]]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[2,\"t\",\"=\",\"ts\"]]]]]]]]],[0,[[13,\"sx\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"x\"],\">=\",[5,\"0\"]]]]],[13,\"sy\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"y\"],\">=\",[5,\"0\"]]]]],[13,\"sz\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"z\"],\">=\",[5,\"0\"]]]]],[13,\"ix\",[1,\"sx\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"x\"]]],[5,\"0.000001\"]]]]],[13,\"iy\",[1,\"sy\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"y\"]]],[5,\"0.000001\"]]]]],[13,\"iz\",[1,\"sz\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"z\"]]],[5,\"0.000001\"]]]]],[13,\"t1x\",[1,[1,[1,[7,\"c\",\"x\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"x\"]],\"*\",\"ix\"]],[13,\"t2x\",[1,[1,[1,[7,\"c\",\"x\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"x\"]],\"*\",\"ix\"]],[13,\"t1y\",[1,[1,[1,[7,\"c\",\"y\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"y\"]],\"*\",\"iy\"]],[13,\"t2y\",[1,[1,[1,[7,\"c\",\"y\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"y\"]],\"*\",\"iy\"]],[13,\"t1z\",[1,[1,[1,[7,\"c\",\"z\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"z\"]],\"*\",\"iz\"]],[13,\"t2z\",[1,[1,[1,[7,\"c\",\"z\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"z\"]],\"*\",\"iz\"]],[13,\"tIn\",[6,\"std.max\",[[6,\"std.min\",[\"t1x\",\"t2x\"]],[6,\"std.max\",[[6,\"std.min\",[\"t1y\",\"t2y\"]],[6,\"std.min\",[\"t1z\",\"t2z\"]]]]]]],[13,\"tOut\",[6,\"std.min\",[[6,\"std.max\",[\"t1x\",\"t2x\"]],[6,\"std.min\",[[6,\"std.max\",[\"t1y\",\"t2y\"]],[6,\"std.max\",[\"t1z\",\"t2z\"]]]]]]],[11,[1,\"tIn\",\"<=\",\"tOut\"],[0,[[11,[1,\"tOut\",\">=\",[1,\"tNow\",\"-\",[5,\"0.0001\"]]],[0,[[11,[1,\"style\",\"===\",[103,\"rounded\"]],[0,[[13,\"r\",[1,[6,\"std.clamp\",[[7,\"vx\",\"bevel\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]],\"*\",\"h\"]],[12,\"s\",[6,\"std.max\",[\"tIn\",[1,\"tNow\",\"-\",[5,\"0.0001\"]]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"12\"]],[102,\"++\",\"i\"],[0,[[13,\"p\",[6,[7,[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"s\"]]]],\"sub\"],[\"c\"]]],[13,\"dd\",[6,\"sdRoundBox\",[\"p\",\"h\",\"h\",\"h\",\"r\"]]],[11,[1,\"dd\",\"<\",[1,\"h\",\"*\",[5,\"0.003\"]]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[17]]]],[2,\"s\",\"=\",[1,\"s\",\"+\",\"dd\"]],[11,[1,\"s\",\">\",\"tOut\"],[0,[[17]]]]]]],[2,\"t\",\"=\",\"s\"]]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[2,\"t\",\"=\",[6,\"std.max\",[\"tIn\",\"tNow\"]]]]]]]]]]]]]]],[10,[6,\"SubHit\",[[104,{hit:\"hit\",t:\"t\"}]]]]]]},externals:{voxLayout:()=>e,\"d.f32\":()=>n,style:()=>t,\"std.dot\":()=>Se,\"std.sqrt\":()=>Ue,\"std.select\":()=>N,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.clamp\":()=>G,sdRoundBox:()=>xd,SubHit:()=>a}})&&c.f)({})),l=(globalThis.__TYPEGPU_AUTONAME__??(c=>c))(gt({hit:n,t:n,cx:n,cy:n,cz:n,minD:n}),\"DdaHit\");return{cellValue:s,cellCentre:r,occupied:o,subShapeHit:i,voxelDda:w.fn([A,A,n,n,A,j],l)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p,_,f,h)=>{\"use gpu\";let g=e.$.vox,y=g.voxelSize,b=g.gridOrigin,x=d.add(u.mul(p)),P=ie(__tsover_div(__tsover_sub(x.x,b),y)),C=ie(__tsover_div(__tsover_sub(x.y,b),y)),E=ie(__tsover_div(__tsover_sub(x.z,b),y)),R=N(n(-1),n(1),u.x>=0),U=N(n(-1),n(1),u.y>=0),L=N(n(-1),n(1),u.z>=0),k=__tsover_div(1,B(re(u.x),1e-6)),D=__tsover_div(1,B(re(u.y),1e-6)),O=__tsover_div(1,B(re(u.z),1e-6)),F=__tsover_mul(y,k),q=__tsover_mul(y,D),Y=__tsover_mul(y,O),V=__tsover_add(__tsover_mul(__tsover_add(P,B(R,n(0))),y),b),X=__tsover_add(__tsover_mul(__tsover_add(C,B(U,n(0))),y),b),Q=__tsover_add(__tsover_mul(__tsover_add(E,B(L,n(0))),y),b),te=__tsover_add(p,__tsover_mul(__tsover_mul(__tsover_sub(V,x.x),R),k)),J=__tsover_add(p,__tsover_mul(__tsover_mul(__tsover_sub(X,x.y),U),D)),oe=__tsover_add(p,__tsover_mul(__tsover_mul(__tsover_sub(Q,x.z),L),O)),le=p,se=n(0),Te=_,de=n(255);for(let xe=0;xe<h;xe++){let Ae=Et(__tsover_add(__tsover_add(re(__tsover_sub(P,f.x)),re(__tsover_sub(C,f.y))),re(__tsover_sub(E,f.z))),.5),De=s(P,C,E),Ee=B(__tsover_sub(De,1),0);if(de=ye(de,Ee),De<.5&&Ae<.5){let ze=i(d,u,r(P,C,E),le);if(ze.hit>.5){se=n(1),Te=ze.t;break}}if(Ee>=1){le=__tsover_add(le,__tsover_mul(Ee,y));let ze=d.add(u.mul(le));P=ie(__tsover_div(__tsover_sub(ze.x,b),y)),C=ie(__tsover_div(__tsover_sub(ze.y,b),y)),E=ie(__tsover_div(__tsover_sub(ze.z,b),y)),te=__tsover_add(le,__tsover_mul(__tsover_mul(__tsover_sub(__tsover_add(__tsover_mul(__tsover_add(P,B(R,n(0))),y),b),ze.x),R),k)),J=__tsover_add(le,__tsover_mul(__tsover_mul(__tsover_sub(__tsover_add(__tsover_mul(__tsover_add(C,B(U,n(0))),y),b),ze.y),U),D)),oe=__tsover_add(le,__tsover_mul(__tsover_mul(__tsover_sub(__tsover_add(__tsover_mul(__tsover_add(E,B(L,n(0))),y),b),ze.z),L),O))}else te<J?te<oe?(le=te,P=__tsover_add(P,R),te=__tsover_add(te,F)):(le=oe,E=__tsover_add(E,L),oe=__tsover_add(oe,Y)):J<oe?(le=J,C=__tsover_add(C,U),J=__tsover_add(J,q)):(le=oe,E=__tsover_add(E,L),oe=__tsover_add(oe,Y));if(le>_)break}return l({hit:se,t:Te,cx:P,cy:C,cz:E,minD:__tsover_mul(de,y)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ro\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"tStart\"},{type:\"i\",name:\"tEnd\"},{type:\"i\",name:\"skip\"},{type:\"i\",name:\"maxSteps\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[13,\"v\",[7,\"vx\",\"voxelSize\"]],[13,\"o\",[7,\"vx\",\"gridOrigin\"]],[13,\"p0\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"tStart\"]]]]],[12,\"cx\",[6,\"std.floor\",[[1,[1,[7,\"p0\",\"x\"],\"-\",\"o\"],\"/\",\"v\"]]]],[12,\"cy\",[6,\"std.floor\",[[1,[1,[7,\"p0\",\"y\"],\"-\",\"o\"],\"/\",\"v\"]]]],[12,\"cz\",[6,\"std.floor\",[[1,[1,[7,\"p0\",\"z\"],\"-\",\"o\"],\"/\",\"v\"]]]],[13,\"sx\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"x\"],\">=\",[5,\"0\"]]]]],[13,\"sy\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"y\"],\">=\",[5,\"0\"]]]]],[13,\"sz\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"z\"],\">=\",[5,\"0\"]]]]],[13,\"ax\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"x\"]]],[5,\"0.000001\"]]]]],[13,\"ay\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"y\"]]],[5,\"0.000001\"]]]]],[13,\"az\",[1,[5,\"1\"],\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"z\"]]],[5,\"0.000001\"]]]]],[13,\"dtx\",[1,\"v\",\"*\",\"ax\"]],[13,\"dty\",[1,\"v\",\"*\",\"ay\"]],[13,\"dtz\",[1,\"v\",\"*\",\"az\"]],[13,\"bx\",[1,[1,[1,\"cx\",\"+\",[6,\"std.max\",[\"sx\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"]],[13,\"by\",[1,[1,[1,\"cy\",\"+\",[6,\"std.max\",[\"sy\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"]],[13,\"bz\",[1,[1,[1,\"cz\",\"+\",[6,\"std.max\",[\"sz\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"]],[12,\"tmx\",[1,\"tStart\",\"+\",[1,[1,[1,\"bx\",\"-\",[7,\"p0\",\"x\"]],\"*\",\"sx\"],\"*\",\"ax\"]]],[12,\"tmy\",[1,\"tStart\",\"+\",[1,[1,[1,\"by\",\"-\",[7,\"p0\",\"y\"]],\"*\",\"sy\"],\"*\",\"ay\"]]],[12,\"tmz\",[1,\"tStart\",\"+\",[1,[1,[1,\"bz\",\"-\",[7,\"p0\",\"z\"]],\"*\",\"sz\"],\"*\",\"az\"]]],[12,\"t\",\"tStart\"],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"tHit\",\"tEnd\"],[12,\"minClear\",[6,\"d.f32\",[[5,\"255\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"maxSteps\"],[102,\"++\",\"i\"],[0,[[13,\"same\",[6,\"std.step\",[[1,[1,[6,\"std.abs\",[[1,\"cx\",\"-\",[7,\"skip\",\"x\"]]]],\"+\",[6,\"std.abs\",[[1,\"cy\",\"-\",[7,\"skip\",\"y\"]]]]],\"+\",[6,\"std.abs\",[[1,\"cz\",\"-\",[7,\"skip\",\"z\"]]]]],[5,\"0.5\"]]]],[13,\"val\",[6,\"cellValue\",[\"cx\",\"cy\",\"cz\"]]],[13,\"clear\",[6,\"std.max\",[[1,\"val\",\"-\",[5,\"1\"]],[5,\"0\"]]]],[2,\"minClear\",\"=\",[6,\"std.min\",[\"minClear\",\"clear\"]]],[11,[1,\"val\",\"<\",[5,\"0.5\"]],[0,[[11,[1,\"same\",\"<\",[5,\"0.5\"]],[0,[[13,\"sh\",[6,\"subShapeHit\",[\"ro\",\"rd\",[6,\"cellCentre\",[\"cx\",\"cy\",\"cz\"]],\"t\"]]],[11,[1,[7,\"sh\",\"hit\"],\">\",[5,\"0.5\"]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[2,\"tHit\",\"=\",[7,\"sh\",\"t\"]],[17]]]]]]]]]],[11,[1,\"clear\",\">=\",[5,\"1\"]],[0,[[2,\"t\",\"=\",[1,\"t\",\"+\",[1,\"clear\",\"*\",\"v\"]]],[13,\"pj\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"t\"]]]]],[2,\"cx\",\"=\",[6,\"std.floor\",[[1,[1,[7,\"pj\",\"x\"],\"-\",\"o\"],\"/\",\"v\"]]]],[2,\"cy\",\"=\",[6,\"std.floor\",[[1,[1,[7,\"pj\",\"y\"],\"-\",\"o\"],\"/\",\"v\"]]]],[2,\"cz\",\"=\",[6,\"std.floor\",[[1,[1,[7,\"pj\",\"z\"],\"-\",\"o\"],\"/\",\"v\"]]]],[2,\"tmx\",\"=\",[1,\"t\",\"+\",[1,[1,[1,[1,[1,[1,\"cx\",\"+\",[6,\"std.max\",[\"sx\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"],\"-\",[7,\"pj\",\"x\"]],\"*\",\"sx\"],\"*\",\"ax\"]]],[2,\"tmy\",\"=\",[1,\"t\",\"+\",[1,[1,[1,[1,[1,[1,\"cy\",\"+\",[6,\"std.max\",[\"sy\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"],\"-\",[7,\"pj\",\"y\"]],\"*\",\"sy\"],\"*\",\"ay\"]]],[2,\"tmz\",\"=\",[1,\"t\",\"+\",[1,[1,[1,[1,[1,[1,\"cz\",\"+\",[6,\"std.max\",[\"sz\",[6,\"d.f32\",[[5,\"0\"]]]]]],\"*\",\"v\"],\"+\",\"o\"],\"-\",[7,\"pj\",\"z\"]],\"*\",\"sz\"],\"*\",\"az\"]]]]],[0,[[11,[1,\"tmx\",\"<\",\"tmy\"],[0,[[11,[1,\"tmx\",\"<\",\"tmz\"],[0,[[2,\"t\",\"=\",\"tmx\"],[2,\"cx\",\"=\",[1,\"cx\",\"+\",\"sx\"]],[2,\"tmx\",\"=\",[1,\"tmx\",\"+\",\"dtx\"]]]],[0,[[2,\"t\",\"=\",\"tmz\"],[2,\"cz\",\"=\",[1,\"cz\",\"+\",\"sz\"]],[2,\"tmz\",\"=\",[1,\"tmz\",\"+\",\"dtz\"]]]]]]],[0,[[11,[1,\"tmy\",\"<\",\"tmz\"],[0,[[2,\"t\",\"=\",\"tmy\"],[2,\"cy\",\"=\",[1,\"cy\",\"+\",\"sy\"]],[2,\"tmy\",\"=\",[1,\"tmy\",\"+\",\"dty\"]]]],[0,[[2,\"t\",\"=\",\"tmz\"],[2,\"cz\",\"=\",[1,\"cz\",\"+\",\"sz\"]],[2,\"tmz\",\"=\",[1,\"tmz\",\"+\",\"dtz\"]]]]]]]]]]],[11,[1,\"t\",\">\",\"tEnd\"],[0,[[17]]]]]]],[10,[6,\"DdaHit\",[[104,{hit:\"hit\",t:\"tHit\",cx:\"cx\",cy:\"cy\",cz:\"cz\",minD:[1,\"minClear\",\"*\",\"v\"]}]]]]]]},externals:{voxLayout:()=>e,\"std.floor\":()=>ie,\"std.select\":()=>N,\"d.f32\":()=>n,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.step\":()=>Et,cellValue:()=>s,\"std.min\":()=>ye,subShapeHit:()=>i,cellCentre:()=>r,DdaHit:()=>l}})&&c.f)({}))}}var ez=()=>Rr()?288:720;function yne(e,t){let{voxelDda:s}=JB(e,t),r=sl,o=ez();return w.fn([M,M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";let c=e.$.vox,d=__tsover_mul(c.gridOrigin,-1),u=__tsover_mul(__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(n(i),.5),n(r)),2),1),d),p=__tsover_mul(__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(n(l),.5),n(r)),2),1),d),_=c.lightDir,f=c.lightT1.mul(u).add(c.lightT2.mul(p)).add(_.mul(d)),h=_.mul(-1),g=n(xP),y=__tsover_add(__tsover_mul(u,u),__tsover_mul(p,p));if(y<__tsover_mul(d,d)){let b=Ue(__tsover_sub(__tsover_mul(d,d),y)),x=j(G(__tsover_add(__tsover_div(__tsover_mul(d,6),c.voxelSize),8),n(8),n(o))),P=A(-9999,-9999,-9999),C=s(f,h,__tsover_sub(d,b),__tsover_add(__tsover_add(d,b),.01),P,x);C.hit>.5&&(g=C.t)}lt(e.$.shadowMap,fe(i,l),S(g,0,0,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"},{type:\"i\",name:\"j\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[13,\"rB\",[1,[7,\"vx\",\"gridOrigin\"],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"u\",[1,[1,[1,[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"RES\"]]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]],\"*\",\"rB\"]],[13,\"w\",[1,[1,[1,[1,[1,[6,\"d.f32\",[\"j\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"RES\"]]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]],\"*\",\"rB\"]],[13,\"L\",[7,\"vx\",\"lightDir\"]],[13,\"p0\",[6,[7,[6,[7,[6,[7,[7,\"vx\",\"lightT1\"],\"mul\"],[\"u\"]],\"add\"],[[6,[7,[7,\"vx\",\"lightT2\"],\"mul\"],[\"w\"]]]],\"add\"],[[6,[7,\"L\",\"mul\"],[\"rB\"]]]]],[13,\"rd\",[6,[7,\"L\",\"mul\"],[[4,\"-\",[5,\"1\"]]]]],[12,\"depth\",[6,\"d.f32\",[\"SHADOW_FAR\"]]],[13,\"perp2\",[1,[1,\"u\",\"*\",\"u\"],\"+\",[1,\"w\",\"*\",\"w\"]]],[11,[1,\"perp2\",\"<\",[1,\"rB\",\"*\",\"rB\"]],[0,[[13,\"half\",[6,\"std.sqrt\",[[1,[1,\"rB\",\"*\",\"rB\"],\"-\",\"perp2\"]]]],[13,\"maxSteps\",[6,\"d.i32\",[[6,\"std.clamp\",[[1,[1,[1,\"rB\",\"*\",[5,\"6\"]],\"/\",[7,\"vx\",\"voxelSize\"]],\"+\",[5,\"8\"]],[6,\"d.f32\",[[5,\"8\"]]],[6,\"d.f32\",[\"STEP_CAP\"]]]]]]],[13,\"none\",[6,\"d.vec3f\",[[4,\"-\",[5,\"9999\"]],[4,\"-\",[5,\"9999\"]],[4,\"-\",[5,\"9999\"]]]]],[13,\"hh\",[6,\"voxelDda\",[\"p0\",\"rd\",[1,\"rB\",\"-\",\"half\"],[1,[1,\"rB\",\"+\",\"half\"],\"+\",[5,\"0.01\"]],\"none\",\"maxSteps\"]]],[11,[1,[7,\"hh\",\"hit\"],\">\",[5,\"0.5\"]],[0,[[2,\"depth\",\"=\",[7,\"hh\",\"t\"]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"voxLayout\",\"$\"],\"shadowMap\"],[6,\"d.vec2u\",[\"i\",\"j\"]],[6,\"d.vec4f\",[\"depth\",[5,\"0\"],[5,\"0\"],[5,\"0\"]]]]]]]},externals:{voxLayout:()=>e,\"d.f32\":()=>n,RES:()=>r,SHADOW_FAR:()=>xP,\"std.sqrt\":()=>Ue,\"d.i32\":()=>j,\"std.clamp\":()=>G,STEP_CAP:()=>o,\"d.vec3f\":()=>A,voxelDda:()=>s,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&a.f)({})).$name(\"voxelShadowMap\")}var Y0=w.fn([Zt(n),n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=n(__tsover_sub(sl,1)),i=ie(s),l=ie(r),c=__tsover_sub(s,i),d=__tsover_sub(r,l),u=M(G(i,n(0),a)),p=M(G(__tsover_add(i,1),n(0),a)),_=M(G(l,n(0),a)),f=M(G(__tsover_add(l,1),n(0),a)),h=N(n(0),n(1),Ye(t,fe(u,_),0).r<o),g=N(n(0),n(1),Ye(t,fe(p,_),0).r<o),y=N(n(0),n(1),Ye(t,fe(u,f),0).r<o),b=N(n(0),n(1),Ye(t,fe(p,f),0).r<o);return K(K(h,g,c),K(y,b,c),d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"tex\"},{type:\"i\",name:\"mx\"},{type:\"i\",name:\"my\"},{type:\"i\",name:\"ref\"}],body:[0,[[13,\"maxT\",[6,\"d.f32\",[[1,\"VOXEL_SHADOW_RES\",\"-\",[5,\"1\"]]]]],[13,\"x0\",[6,\"std.floor\",[\"mx\"]]],[13,\"y0\",[6,\"std.floor\",[\"my\"]]],[13,\"fx\",[1,\"mx\",\"-\",\"x0\"]],[13,\"fy\",[1,\"my\",\"-\",\"y0\"]],[13,\"cx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"x0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"x0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"y0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"cy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"y0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"s00\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,[6,\"std.textureLoad\",[\"tex\",[6,\"d.vec2u\",[\"cx0\",\"cy0\"]],[5,\"0\"]]],\"r\"],\"<\",\"ref\"]]]],[13,\"s10\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,[6,\"std.textureLoad\",[\"tex\",[6,\"d.vec2u\",[\"cx1\",\"cy0\"]],[5,\"0\"]]],\"r\"],\"<\",\"ref\"]]]],[13,\"s01\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,[6,\"std.textureLoad\",[\"tex\",[6,\"d.vec2u\",[\"cx0\",\"cy1\"]],[5,\"0\"]]],\"r\"],\"<\",\"ref\"]]]],[13,\"s11\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,[6,\"std.textureLoad\",[\"tex\",[6,\"d.vec2u\",[\"cx1\",\"cy1\"]],[5,\"0\"]]],\"r\"],\"<\",\"ref\"]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[\"s00\",\"s10\",\"fx\"]],[6,\"std.mix\",[\"s01\",\"s11\",\"fx\"]],\"fy\"]]]]]},externals:{\"d.f32\":()=>n,VOXEL_SHADOW_RES:()=>sl,\"std.floor\":()=>ie,\"d.u32\":()=>M,\"std.clamp\":()=>G,\"std.select\":()=>N,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K}})&&e.f)({})).$name(\"voxelShadowCompare\"),bne=w.fn([Zt(n),A,A,A,A,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=n(sl),u=__tsover_div(__tsover_mul(i,2),d),p=Se(s,o),_=Se(s,a),f=__tsover_sub(i,Se(s,r)),h=__tsover_sub(__tsover_mul(__tsover_add(__tsover_mul(__tsover_div(p,i),.5),.5),d),.5),g=__tsover_sub(__tsover_mul(__tsover_add(__tsover_mul(__tsover_div(_,i),.5),.5),d),.5),y=__tsover_sub(f,__tsover_add(__tsover_mul(c,.05),__tsover_mul(u,2))),b=n(0);if(l<.001)b=Y0(t,h,g,y);else{let x=__tsover_mul(l,bP),P=B(__tsover_div(ye(__tsover_mul(i,x),__tsover_mul(i,.25)),u),1),C=n(0),E=n(0);for(let R=0;R<8;R++){let U=__tsover_mul(Ue(__tsover_div(__tsover_add(n(R),.5),8)),P),L=__tsover_mul(n(R),I0),k=G(__tsover_add(h,__tsover_mul(pe(L),U)),n(0),__tsover_sub(d,1)),D=G(__tsover_add(g,__tsover_mul(ae(L),U)),n(0),__tsover_sub(d,1)),O=Ye(t,fe(M(k),M(D)),0).r;O<y&&(C=__tsover_add(C,O),E=__tsover_add(E,1))}if(E>.5){let R=__tsover_div(C,E),U=G(__tsover_div(__tsover_mul(__tsover_sub(f,R),x),u),1,P),L=n(0);for(let k=0;k<12;k++){let D=__tsover_mul(Ue(__tsover_div(__tsover_add(n(k),.5),12)),U),O=__tsover_add(__tsover_mul(n(k),I0),.7);L=__tsover_add(L,Y0(t,__tsover_add(h,__tsover_mul(pe(O),D)),__tsover_add(g,__tsover_mul(ae(O),D)),y))}b=__tsover_div(L,12)}}return b}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"tex\"},{type:\"i\",name:\"p\"},{type:\"i\",name:\"L\"},{type:\"i\",name:\"T1\"},{type:\"i\",name:\"T2\"},{type:\"i\",name:\"rBound\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"voxel\"}],body:[0,[[13,\"RES\",[6,\"d.f32\",[\"VOXEL_SHADOW_RES\"]]],[13,\"texelWorld\",[1,[1,\"rBound\",\"*\",[5,\"2\"]],\"/\",\"RES\"]],[13,\"u\",[6,\"std.dot\",[\"p\",\"T1\"]]],[13,\"w\",[6,\"std.dot\",[\"p\",\"T2\"]]],[13,\"dL\",[1,\"rBound\",\"-\",[6,\"std.dot\",[\"p\",\"L\"]]]],[13,\"mx\",[1,[1,[1,[1,[1,\"u\",\"/\",\"rBound\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],\"*\",\"RES\"],\"-\",[5,\"0.5\"]]],[13,\"my\",[1,[1,[1,[1,[1,\"w\",\"/\",\"rBound\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],\"*\",\"RES\"],\"-\",[5,\"0.5\"]]],[13,\"ref\",[1,\"dL\",\"-\",[1,[1,\"voxel\",\"*\",[5,\"0.05\"]],\"+\",[1,\"texelWorld\",\"*\",[5,\"2\"]]]]],[12,\"shadow\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"softness\",\"<\",[5,\"0.001\"]],[0,[[2,\"shadow\",\"=\",[6,\"shadowCompare\",[\"tex\",\"mx\",\"my\",\"ref\"]]]]],[0,[[13,\"k\",[1,\"softness\",\"*\",\"SOFT_TAN\"]],[13,\"rSearch\",[6,\"std.max\",[[1,[6,\"std.min\",[[1,\"rBound\",\"*\",\"k\"],[1,\"rBound\",\"*\",[5,\"0.25\"]]]],\"/\",\"texelWorld\"],[5,\"1\"]]]],[12,\"sum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"count\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"s\",[5,\"0\"]],[1,\"s\",\"<\",[5,\"8\"]],[102,\"++\",\"s\"],[0,[[13,\"r\",[1,[6,\"std.sqrt\",[[1,[1,[6,\"d.f32\",[\"s\"]],\"+\",[5,\"0.5\"]],\"/\",[5,\"8\"]]]],\"*\",\"rSearch\"]],[13,\"th\",[1,[6,\"d.f32\",[\"s\"]],\"*\",\"GOLDEN_ANGLE\"]],[13,\"sx\",[6,\"std.clamp\",[[1,\"mx\",\"+\",[1,[6,\"std.cos\",[\"th\"]],\"*\",\"r\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"RES\",\"-\",[5,\"1\"]]]]],[13,\"sy\",[6,\"std.clamp\",[[1,\"my\",\"+\",[1,[6,\"std.sin\",[\"th\"]],\"*\",\"r\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"RES\",\"-\",[5,\"1\"]]]]],[13,\"dep\",[7,[6,\"std.textureLoad\",[\"tex\",[6,\"d.vec2u\",[[6,\"d.u32\",[\"sx\"]],[6,\"d.u32\",[\"sy\"]]]],[5,\"0\"]]],\"r\"]],[11,[1,\"dep\",\"<\",\"ref\"],[0,[[2,\"sum\",\"=\",[1,\"sum\",\"+\",\"dep\"]],[2,\"count\",\"=\",[1,\"count\",\"+\",[5,\"1\"]]]]]]]]],[11,[1,\"count\",\">\",[5,\"0.5\"]],[0,[[13,\"avgBlocker\",[1,\"sum\",\"/\",\"count\"]],[13,\"penumbra\",[6,\"std.clamp\",[[1,[1,[1,\"dL\",\"-\",\"avgBlocker\"],\"*\",\"k\"],\"/\",\"texelWorld\"],[5,\"1\"],\"rSearch\"]]],[12,\"acc\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"s\",[5,\"0\"]],[1,\"s\",\"<\",[5,\"12\"]],[102,\"++\",\"s\"],[0,[[13,\"r\",[1,[6,\"std.sqrt\",[[1,[1,[6,\"d.f32\",[\"s\"]],\"+\",[5,\"0.5\"]],\"/\",[5,\"12\"]]]],\"*\",\"penumbra\"]],[13,\"th\",[1,[1,[6,\"d.f32\",[\"s\"]],\"*\",\"GOLDEN_ANGLE\"],\"+\",[5,\"0.7\"]]],[2,\"acc\",\"=\",[1,\"acc\",\"+\",[6,\"shadowCompare\",[\"tex\",[1,\"mx\",\"+\",[1,[6,\"std.cos\",[\"th\"]],\"*\",\"r\"]],[1,\"my\",\"+\",[1,[6,\"std.sin\",[\"th\"]],\"*\",\"r\"]],\"ref\"]]]]]]],[2,\"shadow\",\"=\",[1,\"acc\",\"/\",[5,\"12\"]]]]]]]]],[10,\"shadow\"]]]},externals:{\"d.f32\":()=>n,VOXEL_SHADOW_RES:()=>sl,\"std.dot\":()=>Se,shadowCompare:()=>Y0,SOFT_TAN:()=>bP,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.sqrt\":()=>Ue,GOLDEN_ANGLE:()=>I0,\"std.clamp\":()=>G,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M}})&&e.f)({})).$name(\"voxelShadowLookup\"),bx=w.fn([A,A,A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=N(n(-1),n(1),s.x>=0),i=N(n(-1),n(1),s.y>=0),l=N(n(-1),n(1),s.z>=0),c=__tsover_div(a,B(re(s.x),1e-6)),d=__tsover_div(i,B(re(s.y),1e-6)),u=__tsover_div(l,B(re(s.z),1e-6)),p=__tsover_mul(__tsover_sub(__tsover_sub(r.x,o),t.x),c),_=__tsover_mul(__tsover_sub(__tsover_add(r.x,o),t.x),c),f=__tsover_mul(__tsover_sub(__tsover_sub(r.y,o),t.y),d),h=__tsover_mul(__tsover_sub(__tsover_add(r.y,o),t.y),d),g=__tsover_mul(__tsover_sub(__tsover_sub(r.z,o),t.z),u),y=__tsover_mul(__tsover_sub(__tsover_add(r.z,o),t.z),u),b=B(ye(p,_),B(ye(f,h),ye(g,y))),x=ye(B(p,_),ye(B(f,h),B(g,y))),P=__tsover_mul(N(n(0),n(1),b<=x),N(n(0),n(1),x>=0));return N(n(-1),B(b,n(0)),P>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ro\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"c\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"sx\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"x\"],\">=\",[5,\"0\"]]]]],[13,\"sy\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"y\"],\">=\",[5,\"0\"]]]]],[13,\"sz\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rd\",\"z\"],\">=\",[5,\"0\"]]]]],[13,\"ix\",[1,\"sx\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"x\"]]],[5,\"0.000001\"]]]]],[13,\"iy\",[1,\"sy\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"y\"]]],[5,\"0.000001\"]]]]],[13,\"iz\",[1,\"sz\",\"/\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rd\",\"z\"]]],[5,\"0.000001\"]]]]],[13,\"t1x\",[1,[1,[1,[7,\"c\",\"x\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"x\"]],\"*\",\"ix\"]],[13,\"t2x\",[1,[1,[1,[7,\"c\",\"x\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"x\"]],\"*\",\"ix\"]],[13,\"t1y\",[1,[1,[1,[7,\"c\",\"y\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"y\"]],\"*\",\"iy\"]],[13,\"t2y\",[1,[1,[1,[7,\"c\",\"y\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"y\"]],\"*\",\"iy\"]],[13,\"t1z\",[1,[1,[1,[7,\"c\",\"z\"],\"-\",\"h\"],\"-\",[7,\"ro\",\"z\"]],\"*\",\"iz\"]],[13,\"t2z\",[1,[1,[1,[7,\"c\",\"z\"],\"+\",\"h\"],\"-\",[7,\"ro\",\"z\"]],\"*\",\"iz\"]],[13,\"tIn\",[6,\"std.max\",[[6,\"std.min\",[\"t1x\",\"t2x\"]],[6,\"std.max\",[[6,\"std.min\",[\"t1y\",\"t2y\"]],[6,\"std.min\",[\"t1z\",\"t2z\"]]]]]]],[13,\"tOut\",[6,\"std.min\",[[6,\"std.max\",[\"t1x\",\"t2x\"]],[6,\"std.min\",[[6,\"std.max\",[\"t1y\",\"t2y\"]],[6,\"std.max\",[\"t1z\",\"t2z\"]]]]]]],[13,\"ok\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"tIn\",\"<=\",\"tOut\"]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"tOut\",\">=\",[5,\"0\"]]]]]],[10,[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"std.max\",[\"tIn\",[6,\"d.f32\",[[5,\"0\"]]]]],[1,\"ok\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.select\":()=>N,\"d.f32\":()=>n,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.min\":()=>ye}})&&e.f)({})).$name(\"voxelRayBox\"),xne=w.fn([A,A,A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=t.sub(r),i=Se(a,s),l=__tsover_sub(Se(a,a),__tsover_mul(o,o)),c=__tsover_sub(__tsover_mul(i,i),l),d=__tsover_sub(__tsover_mul(i,-1),Ue(B(c,0))),u=__tsover_mul(N(n(0),n(1),c>=0),N(n(0),n(1),d>=0));return N(n(-1),d,u>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ro\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"c\"},{type:\"i\",name:\"h\"}],body:[0,[[13,\"oc\",[6,[7,\"ro\",\"sub\"],[\"c\"]]],[13,\"b\",[6,\"std.dot\",[\"oc\",\"rd\"]]],[13,\"cc\",[1,[6,\"std.dot\",[\"oc\",\"oc\"]],\"-\",[1,\"h\",\"*\",\"h\"]]],[13,\"disc\",[1,[1,\"b\",\"*\",\"b\"],\"-\",\"cc\"]],[13,\"t\",[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"-\",[6,\"std.sqrt\",[[6,\"std.max\",[\"disc\",[5,\"0\"]]]]]]],[13,\"ok\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"disc\",\">=\",[5,\"0\"]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"t\",\">=\",[5,\"0\"]]]]]],[10,[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],\"t\",[1,\"ok\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.dot\":()=>Se,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})).$name(\"voxelRaySphere\"),Ane=w.fn([A,A,A,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=bx(t,s,r,o),l=n(-1);if(i>=0){let c=i,d=n(0);for(let u=0;u<8;u++){let p=xd(t.add(s.mul(c)).sub(r),o,o,o,a);if(p<__tsover_mul(o,.004)){d=n(1);break}if(c=__tsover_add(c,p),c>__tsover_add(i,__tsover_mul(o,3.5)))break}l=N(n(-1),c,d>.5)}return l}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ro\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"c\"},{type:\"i\",name:\"h\"},{type:\"i\",name:\"r\"}],body:[0,[[13,\"tBox\",[6,\"voxelRayBox\",[\"ro\",\"rd\",\"c\",\"h\"]]],[12,\"t\",[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]]],[11,[1,\"tBox\",\">=\",[5,\"0\"]],[0,[[12,\"s\",\"tBox\"],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"8\"]],[102,\"++\",\"i\"],[0,[[13,\"p\",[6,[7,[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"s\"]]]],\"sub\"],[\"c\"]]],[13,\"dd\",[6,\"sdRoundBox\",[\"p\",\"h\",\"h\",\"h\",\"r\"]]],[11,[1,\"dd\",\"<\",[1,\"h\",\"*\",[5,\"0.004\"]]],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[17]]]],[2,\"s\",\"=\",[1,\"s\",\"+\",\"dd\"]],[11,[1,\"s\",\">\",[1,\"tBox\",\"+\",[1,\"h\",\"*\",[5,\"3.5\"]]]],[0,[[17]]]]]]],[2,\"t\",\"=\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],\"s\",[1,\"hit\",\">\",[5,\"0.5\"]]]]]]]],[10,\"t\"]]]},externals:{voxelRayBox:()=>bx,\"d.f32\":()=>n,sdRoundBox:()=>xd,\"std.select\":()=>N}})&&e.f)({})).$name(\"voxelRayRoundedBox\");function wne(e,t,s){let{style:r,gridSpace:o}=s,a=ez(),{cellCentre:i,occupied:l,voxelDda:c}=JB(t,r),d=w.fn([A,Ad],A)((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";return o===\"shape\"?ja(ja(_,t.$.vox.cam),f):A(_.x,_.y,_.z)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"rot\"}],body:[0,[[11,[1,\"gridSpace\",\"===\",[103,\"shape\"]],[10,[6,\"rotateVec3\",[[6,\"rotateVec3\",[\"v\",[7,[7,[7,\"voxLayout\",\"$\"],\"vox\"],\"cam\"]]],\"rot\"]]],[10,[6,\"d.vec3f\",[[7,\"v\",\"x\"],[7,\"v\",\"y\"],[7,\"v\",\"z\"]]]]]]]},externals:{gridSpace:()=>o,rotateVec3:()=>ja,voxLayout:()=>t,\"d.vec3f\":()=>A}})&&p.f)({})),u=w.fn([n,n,n],n)((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f,h)=>{\"use gpu\";return N(__tsover_div(__tsover_sub(3,__tsover_add(__tsover_add(_,f),h)),3),n(0),__tsover_add(_,f)>1.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s1\"},{type:\"i\",name:\"s2\"},{type:\"i\",name:\"k\"}],body:[0,[[13,\"open\",[1,[1,[5,\"3\"],\"-\",[1,[1,\"s1\",\"+\",\"s2\"],\"+\",\"k\"]],\"/\",[5,\"3\"]]],[10,[6,\"std.select\",[\"open\",[6,\"d.f32\",[[5,\"0\"]]],[1,[1,\"s1\",\"+\",\"s2\"],\">\",[5,\"1.5\"]]]]]]]},externals:{\"std.select\":()=>N,\"d.f32\":()=>n}})&&p.f)({}));return w.fn([m,Ad,n],S)((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f,h)=>{\"use gpu\";let g=t.$.vox,y=g.voxelSize,b=d(A(__tsover_sub(_.x,.5),__tsover_sub(.5,_.y),-1.2),f),x=d(A(0,0,1),f),P=Se(b,x),C=B(__tsover_sub(Se(b,b),__tsover_mul(P,P)),0),E=Ue(B(__tsover_sub(__tsover_mul(h,h),C),0)),R=B(__tsover_sub(__tsover_mul(P,-1),E),0),U=__tsover_add(__tsover_add(__tsover_mul(P,-1),E),.01),L=e.$.params,k=__tsover_div(B(L.spanX,L.spanY),n(L.activeRes)),D=__tsover_add(__tsover_sub(Ue(C),h),k),O=n(0),F=n(0),q=__tsover_add(U,.4);if(C<__tsover_mul(h,h)){let Y=j(G(__tsover_add(__tsover_div(__tsover_mul(h,6),y),8),n(8),n(a))),V=c(b,x,R,U,A(-9999,-9999,-9999),Y);if(V.hit>.5){let X=b.add(x.mul(V.t)),Q=i(V.cx,V.cy,V.cz),te=X.sub(Q),J=re(te.x),oe=re(te.y),le=re(te.z),se=n(0);oe>J?oe>=le?se=n(1):se=n(2):le>J&&(se=n(2));let Te=N(N(te.x,te.y,se>.5),te.z,se>1.5),de=N(n(-1),n(1),Te>=0),xe=N(n(0),n(1),se<.5),Ae=N(n(0),n(1),se>1.5),De=__tsover_sub(__tsover_sub(1,xe),Ae),Ee=__tsover_mul(de,xe),ze=__tsover_mul(de,De),Ie=__tsover_mul(de,Ae),ke=__tsover_sub(1,xe),Me=xe,we=Ae,Ve=__tsover_sub(1,Ae),qe=__tsover_add(__tsover_mul(te.x,ke),__tsover_mul(te.y,Me)),st=__tsover_add(__tsover_mul(te.y,we),__tsover_mul(te.z,Ve)),pt=__tsover_mul(__tsover_mul(y,.5),g.voxelScale),Ze=G(__tsover_add(__tsover_div(qe,__tsover_mul(2,pt)),.5),0,1),nt=G(__tsover_add(__tsover_div(st,__tsover_mul(2,pt)),.5),0,1),ht=__tsover_add(V.cx,Ee),yt=__tsover_add(V.cy,ze),St=__tsover_add(V.cz,Ie),Mt=l(__tsover_sub(ht,ke),__tsover_sub(yt,Me),St),Rt=l(__tsover_add(ht,ke),__tsover_add(yt,Me),St),Kt=l(ht,__tsover_sub(yt,we),__tsover_sub(St,Ve)),Wt=l(ht,__tsover_add(yt,we),__tsover_add(St,Ve)),ls=l(__tsover_sub(ht,ke),__tsover_sub(__tsover_sub(yt,Me),we),__tsover_sub(St,Ve)),us=l(__tsover_add(ht,ke),__tsover_sub(__tsover_add(yt,Me),we),__tsover_sub(St,Ve)),os=l(__tsover_sub(ht,ke),__tsover_add(__tsover_sub(yt,Me),we),__tsover_add(St,Ve)),bs=l(__tsover_add(ht,ke),__tsover_add(__tsover_add(yt,Me),we),__tsover_add(St,Ve)),hs=K(K(u(Mt,Kt,ls),u(Rt,Kt,us),Ze),K(u(Mt,Wt,os),u(Rt,Wt,bs),Ze),nt),gs=__tsover_add(__tsover_mul(se,2),B(de,n(0)));D=__tsover_mul(k,-1),O=__tsover_add(__tsover_mul(gs,65536),__tsover_mul(ie(__tsover_add(__tsover_mul(hs,255),.5)),256)),F=__tsover_add(__tsover_add(V.cx,__tsover_mul(V.cy,256)),__tsover_mul(V.cz,65536)),q=V.t}else D=__tsover_add(k,B(__tsover_sub(V.minD,y),0))}return S(D,O,F,q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fuv\"},{type:\"i\",name:\"rot\"},{type:\"i\",name:\"rBound\"}],body:[0,[[13,\"vx\",[7,[7,\"voxLayout\",\"$\"],\"vox\"]],[13,\"v\",[7,\"vx\",\"voxelSize\"]],[13,\"ro\",[6,\"viewToGrid\",[[6,\"d.vec3f\",[[1,[7,\"fuv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[5,\"0.5\"],\"-\",[7,\"fuv\",\"y\"]],[4,\"-\",[5,\"1.2\"]]]],\"rot\"]]],[13,\"rd\",[6,\"viewToGrid\",[[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"1\"]]],\"rot\"]]],[13,\"b\",[6,\"std.dot\",[\"ro\",\"rd\"]]],[13,\"perp2\",[6,\"std.max\",[[1,[6,\"std.dot\",[\"ro\",\"ro\"]],\"-\",[1,\"b\",\"*\",\"b\"]],[5,\"0\"]]]],[13,\"halfSpan\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,[1,\"rBound\",\"*\",\"rBound\"],\"-\",\"perp2\"],[5,\"0\"]]]]]],[13,\"tStart\",[6,\"std.max\",[[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"-\",\"halfSpan\"],[5,\"0\"]]]],[13,\"tEnd\",[1,[1,[1,\"b\",\"*\",[4,\"-\",[5,\"1\"]]],\"+\",\"halfSpan\"],\"+\",[5,\"0.01\"]]],[13,\"mp\",[7,[7,\"marchLayout\",\"$\"],\"params\"]],[13,\"texel\",[1,[6,\"std.max\",[[7,\"mp\",\"spanX\"],[7,\"mp\",\"spanY\"]]],\"/\",[6,\"d.f32\",[[7,\"mp\",\"activeRes\"]]]]],[12,\"fieldVal\",[1,[1,[6,\"std.sqrt\",[\"perp2\"]],\"-\",\"rBound\"],\"+\",\"texel\"]],[12,\"payload\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"cellPacked\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"depth\",[1,\"tEnd\",\"+\",[5,\"0.4\"]]],[11,[1,\"perp2\",\"<\",[1,\"rBound\",\"*\",\"rBound\"]],[0,[[13,\"maxSteps\",[6,\"d.i32\",[[6,\"std.clamp\",[[1,[1,[1,\"rBound\",\"*\",[5,\"6\"]],\"/\",\"v\"],\"+\",[5,\"8\"]],[6,\"d.f32\",[[5,\"8\"]]],[6,\"d.f32\",[\"STEP_CAP\"]]]]]]],[13,\"none\",[6,\"d.vec3f\",[[4,\"-\",[5,\"9999\"]],[4,\"-\",[5,\"9999\"]],[4,\"-\",[5,\"9999\"]]]]],[13,\"hh\",[6,\"voxelDda\",[\"ro\",\"rd\",\"tStart\",\"tEnd\",\"none\",\"maxSteps\"]]],[11,[1,[7,\"hh\",\"hit\"],\">\",[5,\"0.5\"]],[0,[[13,\"hp\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[[7,\"hh\",\"t\"]]]]]],[13,\"c\",[6,\"cellCentre\",[[7,\"hh\",\"cx\"],[7,\"hh\",\"cy\"],[7,\"hh\",\"cz\"]]]],[13,\"l\",[6,[7,\"hp\",\"sub\"],[\"c\"]]],[13,\"alx\",[6,\"std.abs\",[[7,\"l\",\"x\"]]]],[13,\"aly\",[6,\"std.abs\",[[7,\"l\",\"y\"]]]],[13,\"alz\",[6,\"std.abs\",[[7,\"l\",\"z\"]]]],[12,\"axis\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"aly\",\">\",\"alx\"],[0,[[11,[1,\"aly\",\">=\",\"alz\"],[0,[[2,\"axis\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]]]],[0,[[2,\"axis\",\"=\",[6,\"d.f32\",[[5,\"2\"]]]]]]]]],[0,[[11,[1,\"alz\",\">\",\"alx\"],[0,[[2,\"axis\",\"=\",[6,\"d.f32\",[[5,\"2\"]]]]]]]]]],[13,\"la\",[6,\"std.select\",[[6,\"std.select\",[[7,\"l\",\"x\"],[7,\"l\",\"y\"],[1,\"axis\",\">\",[5,\"0.5\"]]]],[7,\"l\",\"z\"],[1,\"axis\",\">\",[5,\"1.5\"]]]]],[13,\"sgn\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"la\",\">=\",[5,\"0\"]]]]],[13,\"isX\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"axis\",\"<\",[5,\"0.5\"]]]]],[13,\"isZ\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"axis\",\">\",[5,\"1.5\"]]]]],[13,\"isY\",[1,[1,[5,\"1\"],\"-\",\"isX\"],\"-\",\"isZ\"]],[13,\"nx\",[1,\"sgn\",\"*\",\"isX\"]],[13,\"ny\",[1,\"sgn\",\"*\",\"isY\"]],[13,\"nz\",[1,\"sgn\",\"*\",\"isZ\"]],[13,\"bxv\",[1,[5,\"1\"],\"-\",\"isX\"]],[13,\"byv\",\"isX\"],[13,\"eyv\",\"isZ\"],[13,\"ezv\",[1,[5,\"1\"],\"-\",\"isZ\"]],[13,\"lb\",[1,[1,[7,\"l\",\"x\"],\"*\",\"bxv\"],\"+\",[1,[7,\"l\",\"y\"],\"*\",\"byv\"]]],[13,\"lc\",[1,[1,[7,\"l\",\"y\"],\"*\",\"eyv\"],\"+\",[1,[7,\"l\",\"z\"],\"*\",\"ezv\"]]],[13,\"h\",[1,[1,\"v\",\"*\",[5,\"0.5\"]],\"*\",[7,\"vx\",\"voxelScale\"]]],[13,\"u\",[6,\"std.clamp\",[[1,[1,\"lb\",\"/\",[1,[5,\"2\"],\"*\",\"h\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"w\",[6,\"std.clamp\",[[1,[1,\"lc\",\"/\",[1,[5,\"2\"],\"*\",\"h\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"fx\",[1,[7,\"hh\",\"cx\"],\"+\",\"nx\"]],[13,\"fy\",[1,[7,\"hh\",\"cy\"],\"+\",\"ny\"]],[13,\"fz\",[1,[7,\"hh\",\"cz\"],\"+\",\"nz\"]],[13,\"sB1\",[6,\"occupied\",[[1,\"fx\",\"-\",\"bxv\"],[1,\"fy\",\"-\",\"byv\"],\"fz\"]]],[13,\"sB2\",[6,\"occupied\",[[1,\"fx\",\"+\",\"bxv\"],[1,\"fy\",\"+\",\"byv\"],\"fz\"]]],[13,\"sC1\",[6,\"occupied\",[\"fx\",[1,\"fy\",\"-\",\"eyv\"],[1,\"fz\",\"-\",\"ezv\"]]]],[13,\"sC2\",[6,\"occupied\",[\"fx\",[1,\"fy\",\"+\",\"eyv\"],[1,\"fz\",\"+\",\"ezv\"]]]],[13,\"k11\",[6,\"occupied\",[[1,\"fx\",\"-\",\"bxv\"],[1,[1,\"fy\",\"-\",\"byv\"],\"-\",\"eyv\"],[1,\"fz\",\"-\",\"ezv\"]]]],[13,\"k21\",[6,\"occupied\",[[1,\"fx\",\"+\",\"bxv\"],[1,[1,\"fy\",\"+\",\"byv\"],\"-\",\"eyv\"],[1,\"fz\",\"-\",\"ezv\"]]]],[13,\"k12\",[6,\"occupied\",[[1,\"fx\",\"-\",\"bxv\"],[1,[1,\"fy\",\"-\",\"byv\"],\"+\",\"eyv\"],[1,\"fz\",\"+\",\"ezv\"]]]],[13,\"k22\",[6,\"occupied\",[[1,\"fx\",\"+\",\"bxv\"],[1,[1,\"fy\",\"+\",\"byv\"],\"+\",\"eyv\"],[1,\"fz\",\"+\",\"ezv\"]]]],[13,\"ao0\",[6,\"std.mix\",[[6,\"vertexAo\",[\"sB1\",\"sC1\",\"k11\"]],[6,\"vertexAo\",[\"sB2\",\"sC1\",\"k21\"]],\"u\"]]],[13,\"ao1\",[6,\"std.mix\",[[6,\"vertexAo\",[\"sB1\",\"sC2\",\"k12\"]],[6,\"vertexAo\",[\"sB2\",\"sC2\",\"k22\"]],\"u\"]]],[13,\"ao\",[6,\"std.mix\",[\"ao0\",\"ao1\",\"w\"]]],[13,\"faceId\",[1,[1,\"axis\",\"*\",[5,\"2\"]],\"+\",[6,\"std.max\",[\"sgn\",[6,\"d.f32\",[[5,\"0\"]]]]]]],[2,\"fieldVal\",\"=\",[1,\"texel\",\"*\",[4,\"-\",[5,\"1\"]]]],[2,\"payload\",\"=\",[1,[1,\"faceId\",\"*\",[5,\"65536\"]],\"+\",[1,[6,\"std.floor\",[[1,[1,\"ao\",\"*\",[5,\"255\"]],\"+\",[5,\"0.5\"]]]],\"*\",[5,\"256\"]]]],[2,\"cellPacked\",\"=\",[1,[1,[7,\"hh\",\"cx\"],\"+\",[1,[7,\"hh\",\"cy\"],\"*\",[5,\"256\"]]],\"+\",[1,[7,\"hh\",\"cz\"],\"*\",[5,\"65536\"]]]],[2,\"depth\",\"=\",[7,\"hh\",\"t\"]]]],[0,[[2,\"fieldVal\",\"=\",[1,\"texel\",\"+\",[6,\"std.max\",[[1,[7,\"hh\",\"minD\"],\"-\",\"v\"],[5,\"0\"]]]]]]]]]]],[10,[6,\"d.vec4f\",[\"fieldVal\",\"payload\",\"cellPacked\",\"depth\"]]]]]},externals:{voxLayout:()=>t,viewToGrid:()=>d,\"d.vec3f\":()=>A,\"std.dot\":()=>Se,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,marchLayout:()=>e,\"d.f32\":()=>n,\"d.i32\":()=>j,\"std.clamp\":()=>G,STEP_CAP:()=>a,voxelDda:()=>c,cellCentre:()=>i,\"std.abs\":()=>re,\"std.select\":()=>N,occupied:()=>l,\"std.mix\":()=>K,vertexAo:()=>u,\"std.floor\":()=>ie,\"d.vec4f\":()=>S}})&&p.f)({})).$name(\"voxelFieldMarch\")}var Tne={_vxMx:{schema:A,initial:[1,0,0]},_vxMy:{schema:A,initial:[0,1,0]},_vxMz:{schema:A,initial:[0,0,1]},_vxVoxel:{schema:n,initial:.03},_vxGridOrigin:{schema:n,initial:-.6},_vxL:{schema:A,initial:[0,0,-1]},_vxT1:{schema:A,initial:[1,0,0]},_vxT2:{schema:A,initial:[0,1,0]}};function W0(e,t){let s=2*(t+.002)/Lm;return Math.max(Number.isFinite(e)?e:.03,s,.002)}var AP=(e,t)=>({x:e.y*t.z-e.z*t.y,y:e.z*t.x-e.x*t.z,z:e.x*t.y-e.y*t.x}),Sne=e=>{let t=Math.hypot(e.x,e.y,e.z)||1;return{x:e.x/t,y:e.y/t,z:e.z/t}},_1=(e,t,s)=>Math.min(s,Math.max(t,e));function Pne(e,t){let s=e.gpu?.root;if(!s)return null;let r=jv(t.getShapeConfig()),o=e.getCpuValue(\"shapeSdfUrl\")||\"\",a=e.getCpuValue(\"shapeType\")||r.type||\"\",i=t.getValues(),l=.6,c=W0(i.voxelSize,l),d=()=>c*fne+.01,u;o?u=wA(e,o,Qh(a)?t.getShapeConfig:()=>({...jv(t.getShapeConfig()),type:\"svgExtrude3D\",depth:i.depth,bevel:0,rotX:0,rotY:0,rotZ:0}),{extraPad:d}):M_(a)?u=AA(s,a,r,t.getShapeConfig,{extraPad:d}):u=QB(s,bc(a,r),t.getShapeConfig,()=>i.depth*.5,{extraPad:d});let p=vne(),_=hne(),f=(globalThis.__TYPEGPU_AUTONAME__??(J=>J))(s.createUniform(GA),\"voxUniform\"),h=pr(s,M,OA),g=(globalThis.__TYPEGPU_AUTONAME__??(J=>J))(s.createTexture({size:[sl,sl],format:ZB}).$usage(\"storage\",\"sampled\"),\"shadowTexture\");e.onCleanup(()=>{h.destroy(),g.destroy()});let y=s.createBindGroup(p,{vox:f.buffer,occ:h,shadowMap:g}),b=s.createBindGroup(_,{vox:f.buffer,occ:h}),x=wne(u.layout,p,{style:t.style,gridSpace:t.gridSpace}),P=gA(u.layout,x),C=yA(s,u.layout,P,e.onCleanup,{paramsUniform:u.marchParamsBuffer,sdfSourceTexture:u.sdfSourceTexture,extraBindGroups:[y]}),E=e.registerComputeTexture(C.fieldTexture),R=e.registerComputeTexture(g),U=gne(u.sdfFn,u.layout,_,t.gridSpace),L=s.createBindGroup(u.layout,{field:C.fieldTexture,params:u.marchParamsBuffer.buffer,...u.sdfSourceTexture?{sdfSource:u.sdfSourceTexture}:{}}),k=wr(s,(J=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(J.f=((oe,le,se)=>{\"use gpu\";U(oe,le,se)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"wx\"},{type:\"i\",name:\"iy\"},{type:\"i\",name:\"iz\"}],body:[0,[[6,\"bakeFn\",[\"wx\",\"iy\",\"iz\"]]]]},externals:{bakeFn:()=>U}})&&J.f)({}),{bindGroup:L}).with(b),D=yne(p,t.style),O=wr(s,(J=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(J.f=((oe,le)=>{\"use gpu\";D(oe,le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"},{type:\"i\",name:\"j\"}],body:[0,[[6,\"shadowFn\",[\"i\",\"j\"]]]]},externals:{shadowFn:()=>D}})&&J.f)({}),{bindGroup:y,size:[sl,sl]}),F=C.maxRes,q=\"\",Y=\"\",V=\"\",X=Rr()?2:1,Q=0;return{outputs:{volumetricFieldTexture:E,voxelShadowMap:R},getComputeNodes:J=>{i=t.getValues(),c=W0(i.voxelSize,l),u.update(J);let oe=u.getFootprint();l=oe.rBound,c=W0(c,oe.rBound);let le=e.getCpuValue(\"scale\")??1;F=vA(oe.spanX,oe.spanY,le,e.dimensions.height,C.maxRes,F);let se=i.pitch*m1,Te=i.yaw*m1,de={cx:Math.cos(se),sx:Math.sin(se),cy:Math.cos(Te),sy:Math.sin(Te),cz:1,sz:0},xe=u.getRotation(),Ae=(Gs,Ss,or)=>{let yr=Jl(Gs,Ss,or,de);return Jl(yr.x,yr.y,yr.z,xe)},De=Ae(1,0,0),Ee=Ae(0,1,0),ze=Ae(0,0,1),Ie=i.lightAngle*m1,ke=_1(i.lightElevation,1,89)*m1,Me={x:Math.cos(Ie)*Math.cos(ke),y:-Math.sin(Ie)*Math.cos(ke),z:-Math.sin(ke)},we=t.gridSpace===\"shape\"?Ae(Me.x,Me.y,Me.z):Me,Ve=Sne(AP(we,Math.abs(we.x)<.9?{x:1,y:0,z:0}:{x:0,y:1,z:0})),qe=AP(we,Ve),st=-oe.rBound,pt=Math.min(Lm,Math.ceil(2*oe.rBound/c)),Ze=Math.ceil(pt/4),nt=_1(i.fill,-.5,.5),ht=_1(i.voxelScale,.2,1),yt=_1(i.bevel,0,1);f.write({cam:de,lightDir:A(we.x,we.y,we.z),voxelSize:c,lightT1:A(Ve.x,Ve.y,Ve.z),fill:nt,lightT2:A(qe.x,qe.y,qe.z),voxelScale:ht,bevel:yt,gridOrigin:st,gridN:pt,gridW:Ze});let St=u.getGeometryKey?u.getGeometryKey():u.getStateKey(),Mt=t.gridSpace===\"view\"?`${u.getStateKey()},${i.pitch},${i.yaw},${c},${nt},${pt}`:`${St},${c},${nt},${pt}`,Rt=`${ht},${yt}`,Kt=`${we.x},${we.y},${we.z}`,Wt=Mt,ls=`${Mt},${Rt},${Kt}`,us=`${Mt},${Rt},${u.getStateKey()},${i.pitch},${i.yaw},${F}`,os=Wt!==Y,bs=ls!==V,hs=us!==q;if(!os&&!bs&&!hs||hs&&(Q++,X>1&&Q%X!==0&&!os))return null;Y=Wt,V=ls;let gs=[];return os&&gs.push(()=>k.dispatchThreads(Ze,pt,pt)),bs&&(e.setExtraField(\"_vxL\",[we.x,we.y,we.z]),e.setExtraField(\"_vxT1\",[Ve.x,Ve.y,Ve.z]),e.setExtraField(\"_vxT2\",[qe.x,qe.y,qe.z]),gs.push(O)),hs&&(q=us,u.setActiveRes(F),e.setExtraField(\"_vfOriginX\",oe.originX),e.setExtraField(\"_vfOriginY\",oe.originY),e.setExtraField(\"_vfSpanX\",oe.spanX),e.setExtraField(\"_vfSpanY\",oe.spanY),e.setExtraField(\"_vfActiveRes\",F),e.setExtraField(\"_vfRBound\",oe.rBound),e.setExtraField(\"_vxMx\",[De.x,De.y,De.z]),e.setExtraField(\"_vxMy\",[Ee.x,Ee.y,Ee.z]),e.setExtraField(\"_vxMz\",[ze.x,ze.y,ze.z]),e.setExtraField(\"_vxVoxel\",c),e.setExtraField(\"_vxGridOrigin\",st),gs.push(()=>C.dispatch(F))),gs}}}var tz=ko({bevelSin:()=>sz}),sz=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_sub(1,t),o=be(0,.14,t),a=be(.68,.92,t);return K(r,K(n(1),__tsover_mul(.72,__tsover_sub(1,a)),o),s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"shape\"}],body:[0,[[13,\"sRound\",[1,[5,\"1\"],\"-\",\"t\"]],[13,\"k1\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.14\"],\"t\"]]],[13,\"k2\",[6,\"std.smoothstep\",[[5,\"0.68\"],[5,\"0.92\"],\"t\"]]],[13,\"sMach\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],[1,[5,\"0.72\"],\"*\",[1,[5,\"1\"],\"-\",\"k2\"]],\"k1\"]]],[10,[6,\"std.mix\",[\"sRound\",\"sMach\",\"shape\"]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.mix\":()=>K,\"d.f32\":()=>n}})&&e.f)({})),ip=ko({BLUR_DISK:()=>jc,GlassLensUVs:()=>F1,applyGlassEffect:()=>Mne,glassBlurOffset:()=>oz,glassBorderHighlight:()=>wx,glassComposite:()=>az,glassFresnelRim:()=>Sx,glassGradient:()=>Jh,glassLensUVs:()=>rz,glassRefrStrength:()=>Jm,glassSpecular:()=>Tx,glassTint:()=>Ax,offsetUV:()=>da,sdfSpaceUV:()=>xc}),ec=.017453292519943295,f1=.4472135954999579,Cne=2.3999632297286535,xx=9,jc=[];for(let e=0;e<xx;e++){let t=e*Cne,s=Math.sqrt(e/xx);jc.push([Math.cos(t)*s,Math.sin(t)*s])}var xc=w.fn([m,n,n,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=t.x,l=__tsover_sub(1,t.y),c=__tsover_mul(__tsover_sub(o.x,i),a),d=__tsover_sub(o.y,l),u=__tsover_mul(r,ec),p=pe(u),_=ae(u),f=__tsover_add(__tsover_mul(c,p),__tsover_mul(d,_)),h=__tsover_sub(__tsover_mul(d,p),__tsover_mul(c,_));return m(__tsover_add(__tsover_div(f,s),.5),__tsover_add(__tsover_div(h,s),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"centerX\",[7,\"center\",\"x\"]],[13,\"centerY\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"dxAc\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"],\"*\",\"aspect\"]],[13,\"dy\",[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"]],[13,\"rotRad\",[1,\"rotation\",\"*\",\"DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rdx\",[1,[1,\"dxAc\",\"*\",\"cosR\"],\"+\",[1,\"dy\",\"*\",\"sinR\"]]],[13,\"rdy\",[1,[1,\"dy\",\"*\",\"cosR\"],\"-\",[1,\"dxAc\",\"*\",\"sinR\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"rdx\",\"/\",\"scale\"],\"+\",[5,\"0.5\"]],[1,[1,\"rdy\",\"/\",\"scale\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{DEG_TO_RAD:()=>ec,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({})),da=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(__tsover_add(t.x,s),__tsover_add(t.y,r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"+\",\"ox\"],[1,[7,\"uv\",\"y\"],\"+\",\"oy\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Jh=w.fn([n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return m(__tsover_div(__tsover_sub(s,t),.01),__tsover_div(__tsover_sub(r,t),.01))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfRaw\"},{type:\"i\",name:\"sdfX\"},{type:\"i\",name:\"sdfY\"}],body:[0,[[13,\"eps\",[5,\"0.01\"]],[10,[6,\"d.vec2f\",[[1,[1,\"sdfX\",\"-\",\"sdfRaw\"],\"/\",\"eps\"],[1,[1,\"sdfY\",\"-\",\"sdfRaw\"],\"/\",\"eps\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Jm=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(__tsover_mul(s,.3),.005),a=G(__tsover_div(__tsover_mul(t,-1),o),0,1),i=be(0,1,a);return N(__tsover_mul(__tsover_sub(1,a),__tsover_sub(1,a)),i,r>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"thicknessRange\",[6,\"std.max\",[[1,\"thickness\",\"*\",[5,\"0.3\"]],[5,\"0.005\"]]]],[13,\"depthNorm\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"thicknessRange\"],[5,\"0\"],[5,\"1\"]]]],[13,\"vol\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"1\"],\"depthNorm\"]]],[13,\"flat\",[1,[1,[5,\"1\"],\"-\",\"depthNorm\"],\"*\",[1,[5,\"1\"],\"-\",\"depthNorm\"]]],[10,[6,\"std.select\",[\"flat\",\"vol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.smoothstep\":()=>be,\"std.select\":()=>N}})&&e.f)({})),F1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({lensUV:m,rUV:m,bUV:m}),\"GlassLensUVs\"),rz=w.fn([m,m,n,n,n,n,n,n,n,n,n,n],F1)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_)=>{\"use gpu\";let f=Jm(__tsover_div(r,o),d,_),h=__tsover_mul(l,.15),g=B(Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(i,i))),1e-4),y=ye(n(1),__tsover_div(12,g)),b=__tsover_div(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(a,y),-1),h),f),p),x=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(i,y),-1),h),f),P=s.x,C=__tsover_sub(1,s.y),E=__tsover_add(P,__tsover_div(__tsover_sub(t.x,P),c)),R=__tsover_add(C,__tsover_div(__tsover_sub(t.y,C),c)),U=__tsover_add(E,b),L=__tsover_add(R,x),k=__tsover_mul(u,.06),D=__tsover_mul(b,k),O=__tsover_mul(x,k);return F1({lensUV:m(U,L),rUV:m(__tsover_add(U,D),__tsover_add(L,O)),bUV:m(__tsover_sub(U,D),__tsover_sub(L,O))})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"sdfRaw\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"refraction\"},{type:\"i\",name:\"innerZoom\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"aberration\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"sdf\",[1,\"sdfRaw\",\"/\",\"scale\"]],[13,\"refrStrength\",[6,\"glassRefrStrength\",[\"sdf\",\"thickness\",\"volumetric\"]]],[13,\"refrScale\",[1,\"refraction\",\"*\",[5,\"0.15\"]]],[13,\"slopeLen\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"gradX\",\"*\",\"gradX\"],\"+\",[1,\"gradY\",\"*\",\"gradY\"]]]],[5,\"0.0001\"]]]],[13,\"slopeScale\",[6,\"std.min\",[[6,\"d.f32\",[[5,\"1\"]]],[1,[5,\"12\"],\"/\",\"slopeLen\"]]]],[13,\"offsetX\",[1,[1,[1,[1,[1,\"gradX\",\"*\",\"slopeScale\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"refrScale\"],\"*\",\"refrStrength\"],\"/\",\"aspect\"]],[13,\"offsetY\",[1,[1,[1,[1,\"gradY\",\"*\",\"slopeScale\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"refrScale\"],\"*\",\"refrStrength\"]],[13,\"centerX\",[7,\"center\",\"x\"]],[13,\"centerY\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"zoomedX\",[1,\"centerX\",\"+\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"],\"/\",\"innerZoom\"]]],[13,\"zoomedY\",[1,\"centerY\",\"+\",[1,[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"],\"/\",\"innerZoom\"]]],[13,\"lensX\",[1,\"zoomedX\",\"+\",\"offsetX\"]],[13,\"lensY\",[1,\"zoomedY\",\"+\",\"offsetY\"]],[13,\"chrScale\",[1,\"aberration\",\"*\",[5,\"0.06\"]]],[13,\"chrOffX\",[1,\"offsetX\",\"*\",\"chrScale\"]],[13,\"chrOffY\",[1,\"offsetY\",\"*\",\"chrScale\"]],[10,[6,\"GlassLensUVs\",[[104,{lensUV:[6,\"d.vec2f\",[\"lensX\",\"lensY\"]],rUV:[6,\"d.vec2f\",[[1,\"lensX\",\"+\",\"chrOffX\"],[1,\"lensY\",\"+\",\"chrOffY\"]]],bUV:[6,\"d.vec2f\",[[1,\"lensX\",\"-\",\"chrOffX\"],[1,\"lensY\",\"-\",\"chrOffY\"]]]}]]]]]]},externals:{glassRefrStrength:()=>Jm,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.min\":()=>ye,\"d.f32\":()=>n,GlassLensUVs:()=>F1,\"d.vec2f\":()=>m}})&&e.f)({})),oz=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,2);return m(__tsover_mul(__tsover_div(r,t.x),a),__tsover_mul(__tsover_div(o,t.y),a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"viewportSize\"},{type:\"i\",name:\"blur\"},{type:\"i\",name:\"ox\"},{type:\"i\",name:\"oy\"}],body:[0,[[13,\"m\",[1,\"blur\",\"*\",[5,\"2\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"ox\",\"/\",[7,\"viewportSize\",\"x\"]],\"*\",\"m\"],[1,[1,\"oy\",\"/\",[7,\"viewportSize\",\"y\"]],\"*\",\"m\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Ax=w.fn([A,A,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=A(.299,.587,.114),i=Se(t,a),l=K(t,s,r),c=Se(l,a);return K(l,l.mul(__tsover_div(i,B(c,1e-4))),N(n(0),n(1),o>.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"tintColor\"},{type:\"i\",name:\"tintIntensity\"},{type:\"i\",name:\"preserveLum\"}],body:[0,[[13,\"lumWeights\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]],[13,\"origLum\",[6,\"std.dot\",[\"rgb\",\"lumWeights\"]]],[13,\"tinted\",[6,\"std.mix\",[\"rgb\",\"tintColor\",\"tintIntensity\"]]],[13,\"tintedLum\",[6,\"std.dot\",[\"tinted\",\"lumWeights\"]]],[13,\"lumPreserved\",[6,[7,\"tinted\",\"mul\"],[[1,\"origLum\",\"/\",[6,\"std.max\",[\"tintedLum\",[5,\"0.0001\"]]]]]]],[13,\"preserveFactor\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"preserveLum\",\">\",[5,\"0.5\"]]]]],[10,[6,\"std.mix\",[\"tinted\",\"lumPreserved\",\"preserveFactor\"]]]]]},externals:{\"d.vec3f\":()=>A,\"std.dot\":()=>Se,\"std.mix\":()=>K,\"std.max\":()=>B,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})),wx=w.fn([n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=B(__tsover_mul(s,.5),.001),d=B(__tsover_mul(c,.0625),__tsover_mul(r,1.5)),u=__tsover_sub(t,r),p=__tsover_sub(G(__tsover_div(__tsover_mul(u,-1),d),0,1),G(__tsover_div(__tsover_mul(t,-1),d),0,1)),_=pe(__tsover_mul(i,ec)),f=ae(__tsover_mul(i,ec)),h=__tsover_add(__tsover_mul(o,_),__tsover_mul(a,f)),g=G(__tsover_add(__tsover_mul(h,.5),.5),0,1);return __tsover_mul(__tsover_mul(p,g),l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"edgeSoftness\"},{type:\"i\",name:\"pxH\"},{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"highlight\"}],body:[0,[[13,\"sharp\",[6,\"std.max\",[[1,\"edgeSoftness\",\"*\",[5,\"0.5\"]],[5,\"0.001\"]]]],[13,\"w2\",[6,\"std.max\",[[1,\"sharp\",\"*\",[5,\"0.0625\"]],[1,\"pxH\",\"*\",[5,\"1.5\"]]]]],[13,\"sdfOuter\",[1,\"sdf\",\"-\",\"pxH\"]],[13,\"rb2base\",[1,[6,\"std.clamp\",[[1,[1,\"sdfOuter\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"w2\"],[5,\"0\"],[5,\"1\"]]],\"-\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"w2\"],[5,\"0\"],[5,\"1\"]]]]],[13,\"lx\",[6,\"std.cos\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"ly\",[6,\"std.sin\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"normalDotLight\",[1,[1,\"gradX\",\"*\",\"lx\"],\"+\",[1,\"gradY\",\"*\",\"ly\"]]],[13,\"lightFacing\",[6,\"std.clamp\",[[1,[1,\"normalDotLight\",\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[10,[1,[1,\"rb2base\",\"*\",\"lightFacing\"],\"*\",\"highlight\"]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,\"std.cos\":()=>pe,DEG_TO_RAD:()=>ec,\"std.sin\":()=>ae}})&&e.f)({})),Tx=w.fn([n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=pe(__tsover_mul(r,ec)),c=ae(__tsover_mul(r,ec)),d=n(2),u=Ue(__tsover_add(__tsover_add(__tsover_mul(t,t),__tsover_mul(s,s)),__tsover_mul(d,d))),p=__tsover_div(t,u),_=__tsover_div(s,u),f=__tsover_div(d,u),h=__tsover_add(__tsover_add(__tsover_mul(p,__tsover_mul(l,f1)),__tsover_mul(_,__tsover_mul(c,f1))),__tsover_mul(f,__tsover_mul(2,f1))),g=Ia(__tsover_sub(8,__tsover_mul(a,7)));return __tsover_mul(__tsover_mul(vt(G(h,0,1),g),o),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"highlight\"},{type:\"i\",name:\"highlightSoftness\"},{type:\"i\",name:\"refrStrength\"}],body:[0,[[13,\"lx\",[6,\"std.cos\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"ly\",[6,\"std.sin\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"nz\",[6,\"d.f32\",[[5,\"2\"]]]],[13,\"nLen\",[6,\"std.sqrt\",[[1,[1,[1,\"gradX\",\"*\",\"gradX\"],\"+\",[1,\"gradY\",\"*\",\"gradY\"]],\"+\",[1,\"nz\",\"*\",\"nz\"]]]]],[13,\"nx\",[1,\"gradX\",\"/\",\"nLen\"]],[13,\"ny\",[1,\"gradY\",\"/\",\"nLen\"]],[13,\"nnz\",[1,\"nz\",\"/\",\"nLen\"]],[13,\"nDotH\",[1,[1,[1,\"nx\",\"*\",[1,\"lx\",\"*\",\"INV_HLEN_GLASS\"]],\"+\",[1,\"ny\",\"*\",[1,\"ly\",\"*\",\"INV_HLEN_GLASS\"]]],\"+\",[1,\"nnz\",\"*\",[1,[5,\"2\"],\"*\",\"INV_HLEN_GLASS\"]]]],[13,\"shininess\",[6,\"std.exp2\",[[1,[5,\"8\"],\"-\",[1,\"highlightSoftness\",\"*\",[5,\"7\"]]]]]],[10,[1,[1,[6,\"std.pow\",[[6,\"std.clamp\",[\"nDotH\",[5,\"0\"],[5,\"1\"]]],\"shininess\"]],\"*\",\"highlight\"],\"*\",\"refrStrength\"]]]]},externals:{\"std.cos\":()=>pe,DEG_TO_RAD:()=>ec,\"std.sin\":()=>ae,\"d.f32\":()=>n,\"std.sqrt\":()=>Ue,INV_HLEN_GLASS:()=>f1,\"std.exp2\":()=>Ia,\"std.pow\":()=>vt,\"std.clamp\":()=>G}})&&e.f)({})),Sx=w.fn([n,n,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_add(__tsover_mul(s,s),__tsover_mul(r,r)),d=__tsover_div(1,Ue(__tsover_add(c,1))),u=K(6,1.5,G(a,0,1)),p=__tsover_mul(__tsover_mul(__tsover_mul(vt(__tsover_sub(1,d),u),o),2),i),_=B(__tsover_mul(a,.06),.001),f=G(__tsover_div(__tsover_mul(t,-1),_),0,1);return N(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_sub(1,f),__tsover_sub(1,f)),o),i),p,l>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"fresnel\"},{type:\"i\",name:\"fresnelSoftness\"},{type:\"i\",name:\"rb1\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"slopeSq\",[1,[1,\"gradX\",\"*\",\"gradX\"],\"+\",[1,\"gradY\",\"*\",\"gradY\"]]],[13,\"cosView\",[1,[5,\"1\"],\"/\",[6,\"std.sqrt\",[[1,\"slopeSq\",\"+\",[5,\"1\"]]]]]],[13,\"exponent\",[6,\"std.mix\",[[5,\"6\"],[5,\"1.5\"],[6,\"std.clamp\",[\"fresnelSoftness\",[5,\"0\"],[5,\"1\"]]]]]],[13,\"volRim\",[1,[1,[1,[6,\"std.pow\",[[1,[5,\"1\"],\"-\",\"cosView\"],\"exponent\"]],\"*\",\"fresnel\"],\"*\",[5,\"2\"]],\"*\",\"rb1\"]],[13,\"fresnelWidth\",[6,\"std.max\",[[1,\"fresnelSoftness\",\"*\",[5,\"0.06\"]],[5,\"0.001\"]]]],[13,\"fresnelDepth\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"fresnelWidth\"],[5,\"0\"],[5,\"1\"]]]],[13,\"flatRim\",[1,[1,[1,[1,[5,\"1\"],\"-\",\"fresnelDepth\"],\"*\",[1,[5,\"1\"],\"-\",\"fresnelDepth\"]],\"*\",\"fresnel\"],\"*\",\"rb1\"]],[10,[6,\"std.select\",[\"flatRim\",\"volRim\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.sqrt\":()=>Ue,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"std.pow\":()=>vt,\"std.max\":()=>B,\"std.select\":()=>N}})&&e.f)({})),az=w.fn([S,S,n,n,n,n,m,n,n,n,A,n,n,A,n,n,A,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_,f,h,g,y,b,x,P,C,E)=>{\"use gpu\";let R=B(__tsover_mul(c,.5),.001),U=__tsover_div(1,l.y),L=__tsover_div(r,o),k=B(__tsover_mul(R,.03125),__tsover_mul(U,1.5)),D=G(__tsover_div(__tsover_mul(L,-1),k),0,1),O=Jm(L,y,E),F=wx(L,c,U,a,i,d,u),q=Ax(A(s.x,s.y,s.z),b,x,P),Y=Tx(a,i,d,u,_,O),V=Sx(L,a,i,f,g,D,E),X=S(__tsover_add(__tsover_add(__tsover_add(q.x,__tsover_mul(p.x,F)),__tsover_mul(p.x,Y)),__tsover_mul(h.x,V)),__tsover_add(__tsover_add(__tsover_add(q.y,__tsover_mul(p.y,F)),__tsover_mul(p.y,Y)),__tsover_mul(h.y,V)),__tsover_add(__tsover_add(__tsover_add(q.z,__tsover_mul(p.z,F)),__tsover_mul(p.z,Y)),__tsover_mul(h.z,V)),__tsover_add(s.w,F)),Q=be(0,1,D),te=K(t,X,Q),J=N(n(1),Q,C>.5);return S(te.x,te.y,te.z,__tsover_mul(te.w,J))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"baseColor\"},{type:\"i\",name:\"blurred\"},{type:\"i\",name:\"sdfRaw\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"viewportSize\"},{type:\"i\",name:\"edgeSoftness\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"highlight\"},{type:\"i\",name:\"highlightColor\"},{type:\"i\",name:\"highlightSoftness\"},{type:\"i\",name:\"fresnel\"},{type:\"i\",name:\"fresnelColor\"},{type:\"i\",name:\"fresnelSoftness\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"tintColor\"},{type:\"i\",name:\"tintIntensity\"},{type:\"i\",name:\"tintPreserveLuminosity\"},{type:\"i\",name:\"cutout\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"sharp\",[6,\"std.max\",[[1,\"edgeSoftness\",\"*\",[5,\"0.5\"]],[5,\"0.001\"]]]],[13,\"pxH\",[1,[5,\"1\"],\"/\",[7,\"viewportSize\",\"y\"]]],[13,\"sdf\",[1,\"sdfRaw\",\"/\",\"scale\"]],[13,\"w1\",[6,\"std.max\",[[1,\"sharp\",\"*\",[5,\"0.03125\"]],[1,\"pxH\",\"*\",[5,\"1.5\"]]]]],[13,\"rb1\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"w1\"],[5,\"0\"],[5,\"1\"]]]],[13,\"refrStrength\",[6,\"glassRefrStrength\",[\"sdf\",\"thickness\",\"volumetric\"]]],[13,\"rb2\",[6,\"glassBorderHighlight\",[\"sdf\",\"edgeSoftness\",\"pxH\",\"gradX\",\"gradY\",\"lightAngle\",\"highlight\"]]],[13,\"blurredRgb\",[6,\"d.vec3f\",[[7,\"blurred\",\"x\"],[7,\"blurred\",\"y\"],[7,\"blurred\",\"z\"]]]],[13,\"tintedRgb\",[6,\"glassTint\",[\"blurredRgb\",\"tintColor\",\"tintIntensity\",\"tintPreserveLuminosity\"]]],[13,\"specGlint\",[6,\"glassSpecular\",[\"gradX\",\"gradY\",\"lightAngle\",\"highlight\",\"highlightSoftness\",\"refrStrength\"]]],[13,\"fresnelRim\",[6,\"glassFresnelRim\",[\"sdf\",\"gradX\",\"gradY\",\"fresnel\",\"fresnelSoftness\",\"rb1\",\"volumetric\"]]],[13,\"litR\",[1,[1,[1,[7,\"tintedRgb\",\"x\"],\"+\",[1,[7,\"highlightColor\",\"x\"],\"*\",\"rb2\"]],\"+\",[1,[7,\"highlightColor\",\"x\"],\"*\",\"specGlint\"]],\"+\",[1,[7,\"fresnelColor\",\"x\"],\"*\",\"fresnelRim\"]]],[13,\"litG\",[1,[1,[1,[7,\"tintedRgb\",\"y\"],\"+\",[1,[7,\"highlightColor\",\"y\"],\"*\",\"rb2\"]],\"+\",[1,[7,\"highlightColor\",\"y\"],\"*\",\"specGlint\"]],\"+\",[1,[7,\"fresnelColor\",\"y\"],\"*\",\"fresnelRim\"]]],[13,\"litB\",[1,[1,[1,[7,\"tintedRgb\",\"z\"],\"+\",[1,[7,\"highlightColor\",\"z\"],\"*\",\"rb2\"]],\"+\",[1,[7,\"highlightColor\",\"z\"],\"*\",\"specGlint\"]],\"+\",[1,[7,\"fresnelColor\",\"z\"],\"*\",\"fresnelRim\"]]],[13,\"litA\",[1,[7,\"blurred\",\"w\"],\"+\",\"rb2\"]],[13,\"lighting\",[6,\"d.vec4f\",[\"litR\",\"litG\",\"litB\",\"litA\"]]],[13,\"transition\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"1\"],\"rb1\"]]],[13,\"composited\",[6,\"std.mix\",[\"baseColor\",\"lighting\",\"transition\"]]],[13,\"cutoutAlpha\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"transition\",[1,\"cutout\",\">\",[5,\"0.5\"]]]]],[10,[6,\"d.vec4f\",[[7,\"composited\",\"x\"],[7,\"composited\",\"y\"],[7,\"composited\",\"z\"],[1,[7,\"composited\",\"w\"],\"*\",\"cutoutAlpha\"]]]]]]},externals:{\"std.max\":()=>B,\"std.clamp\":()=>G,glassRefrStrength:()=>Jm,glassBorderHighlight:()=>wx,\"d.vec3f\":()=>A,glassTint:()=>Ax,glassSpecular:()=>Tx,glassFresnelRim:()=>Sx,\"d.vec4f\":()=>S,\"std.smoothstep\":()=>be,\"std.mix\":()=>K,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({}));function Mne(e,t,s,r,o){let{uniforms:a,propValues:i,ctx:l}=e,c=o?.volumetric??!1,d=o?.bakedGradients??!1,u=$e(c?1:0),p=ns(W(xc,\"sdfSpaceUV\",[a.center,a.scale,a.rotation,l.uv,l.aspect]),\"glassSdfUV\"),_=ns(t(p),\"glassSurf\"),f=_.member(\"r\"),h,g;if(d)h=_.member(\"g\"),g=_.member(\"b\");else{let F=t(W(da,\"offsetUV\",[p,$e(.01),$e(0)])),q=t(W(da,\"offsetUV\",[p,$e(0),$e(.01)])),Y=ns(W(Jh,\"glassGradient\",[f,F.member(\"r\"),q.member(\"r\")]),\"glassGrad\");h=Y.member(\"x\"),g=Y.member(\"y\")}let y=ns(W(rz,\"glassLensUVs\",[l.uv,a.center,f,a.scale,h,g,a.refraction,a.innerZoom,a.thickness,a.aberration,l.aspect,u]),\"glassLens\"),b=y.member(\"lensUV\"),x=y.member(\"rUV\"),P=y.member(\"bUV\"),C=i.blur,E=typeof C==\"number\"?C>0:!0,R=i.aberration,U=typeof R==\"number\"?R>0:!0,L=(F,q,Y,V)=>F.sample(q.add(W(oz,\"glassBlurOffset\",[l.viewportSize,a.blur,$e(Y),$e(V)]))),k=(F,q)=>{let Y=L(F,q,jc[0][0],jc[0][1]);for(let V=1;V<jc.length;V++)Y=Y.add(L(F,q,jc[V][0],jc[V][1]));return Y.mul(1/xx)},D;if(r&&E)D=U?Ct(r.sample(x).member(\"r\"),r.sample(b).member(\"g\"),r.sample(P).member(\"b\"),r.sample(b).member(\"a\")):r.sample(b);else if(!E&&!U)D=s.sample(b);else if(!E&&U)D=Ct(s.sample(x).member(\"r\"),s.sample(b).member(\"g\"),s.sample(P).member(\"b\"),s.sample(b).member(\"a\"));else if(E&&!U)D=k(s,b);else{let F=k(s,x),q=k(s,b),Y=k(s,P);D=Ct(F.member(\"r\"),q.member(\"g\"),Y.member(\"b\"),q.member(\"a\"))}let O=W(Yt,\"unpremultiplyAlpha\",[D]);return W(az,\"glassComposite\",[W(Yt,\"unpremultiplyAlpha\",[s.sample(l.uv)]),O,f,a.scale,h,g,l.viewportSize,a.edgeSoftness,a.lightAngle,a.highlight,a.highlightColor.member(\"rgb\"),a.highlightSoftness,a.fresnel,a.fresnelColor.member(\"rgb\"),a.fresnelSoftness,a.thickness,a.tintColor.member(\"rgb\"),a.tintIntensity,a.tintPreserveLuminosity,a.cutout,u])}var Ene=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(t.x,t.y),o=__tsover_div(s.x,s.y),a=B(__tsover_div(o,r),1);return m(__tsover_mul(__tsover_div(r,o),a),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dims\"},{type:\"i\",name:\"vp\"}],body:[0,[[13,\"aspect\",[1,[7,\"dims\",\"x\"],\"/\",[7,\"dims\",\"y\"]]],[13,\"viewportAspect\",[1,[7,\"vp\",\"x\"],\"/\",[7,\"vp\",\"y\"]]],[13,\"coverScale\",[6,\"std.max\",[[1,\"viewportAspect\",\"/\",\"aspect\"],[5,\"1\"]]]],[10,[6,\"d.vec2f\",[[1,[1,\"aspect\",\"/\",\"viewportAspect\"],\"*\",\"coverScale\"],\"coverScale\"]]]]]},externals:{\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),kne=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(t.x,t.y),o=__tsover_div(s.x,s.y),a=ye(__tsover_div(o,r),1);return m(__tsover_mul(__tsover_div(r,o),a),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dims\"},{type:\"i\",name:\"vp\"}],body:[0,[[13,\"aspect\",[1,[7,\"dims\",\"x\"],\"/\",[7,\"dims\",\"y\"]]],[13,\"viewportAspect\",[1,[7,\"vp\",\"x\"],\"/\",[7,\"vp\",\"y\"]]],[13,\"containScale\",[6,\"std.min\",[[1,\"viewportAspect\",\"/\",\"aspect\"],[5,\"1\"]]]],[10,[6,\"d.vec2f\",[[1,[1,\"aspect\",\"/\",\"viewportAspect\"],\"*\",\"containScale\"],\"containScale\"]]]]]},externals:{\"std.min\":()=>ye,\"d.vec2f\":()=>m}})&&e.f)({})),Bne=w.fn([],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(()=>{\"use gpu\";return m(1,1)}),{v:2,name:void 0,ast:{params:[],body:[0,[[10,[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),zne=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(t.x,t.y),o=__tsover_div(s.x,s.y),a=ye(ye(__tsover_div(o,r),1),ye(__tsover_div(s.x,t.x),__tsover_div(s.y,t.y)));return m(__tsover_mul(__tsover_div(r,o),a),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dims\"},{type:\"i\",name:\"vp\"}],body:[0,[[13,\"aspect\",[1,[7,\"dims\",\"x\"],\"/\",[7,\"dims\",\"y\"]]],[13,\"viewportAspect\",[1,[7,\"vp\",\"x\"],\"/\",[7,\"vp\",\"y\"]]],[13,\"containScale\",[6,\"std.min\",[[1,\"viewportAspect\",\"/\",\"aspect\"],[5,\"1\"]]]],[13,\"naturalScale\",[6,\"std.min\",[[1,[7,\"vp\",\"x\"],\"/\",[7,\"dims\",\"x\"]],[1,[7,\"vp\",\"y\"],\"/\",[7,\"dims\",\"y\"]]]]],[13,\"scaleDownScale\",[6,\"std.min\",[\"containScale\",\"naturalScale\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"aspect\",\"/\",\"viewportAspect\"],\"*\",\"scaleDownScale\"],\"scaleDownScale\"]]]]]},externals:{\"std.min\":()=>ye,\"d.vec2f\":()=>m}})&&e.f)({})),Rne=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_div(t.x,t.y),o=__tsover_div(s.x,s.y),a=ye(__tsover_div(s.x,t.x),__tsover_div(s.y,t.y));return m(__tsover_mul(__tsover_div(r,o),a),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dims\"},{type:\"i\",name:\"vp\"}],body:[0,[[13,\"aspect\",[1,[7,\"dims\",\"x\"],\"/\",[7,\"dims\",\"y\"]]],[13,\"viewportAspect\",[1,[7,\"vp\",\"x\"],\"/\",[7,\"vp\",\"y\"]]],[13,\"noneScale\",[6,\"std.min\",[[1,[7,\"vp\",\"x\"],\"/\",[7,\"dims\",\"x\"]],[1,[7,\"vp\",\"y\"],\"/\",[7,\"dims\",\"y\"]]]]],[10,[6,\"d.vec2f\",[[1,[1,\"aspect\",\"/\",\"viewportAspect\"],\"*\",\"noneScale\"],\"noneScale\"]]]]]},externals:{\"std.min\":()=>ye,\"d.vec2f\":()=>m}})&&e.f)({})),Dne=w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t.sub(m(.5,.5));return m(__tsover_div(r.x,s.x),__tsover_div(r.y,s.y)).add(m(.5,.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"uvScale\"}],body:[0,[[13,\"centeredUV\",[6,[7,\"uv\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"scaledUV\",[6,\"d.vec2f\",[[1,[7,\"centeredUV\",\"x\"],\"/\",[7,\"uvScale\",\"x\"]],[1,[7,\"centeredUV\",\"y\"],\"/\",[7,\"uvScale\",\"y\"]]]]],[10,[6,[7,\"scaledUV\",\"add\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),Lne=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(N(t.x,__tsover_sub(1,t.x),s>0),t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"mirror\"}],body:[0,[[13,\"mirroredX\",[6,\"std.select\",[[7,\"uv\",\"x\"],[1,[5,\"1\"],\"-\",[7,\"uv\",\"x\"]],[1,\"mirror\",\">\",[5,\"0\"]]]]],[10,[6,\"d.vec2f\",[\"mirroredX\",[7,\"uv\",\"y\"]]]]]]},externals:{\"std.select\":()=>N,\"d.vec2f\":()=>m}})&&e.f)({})),Une=w.fn([S,m],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Iu(A(t.x,t.y,t.z)),o=s.x<0||s.x>1||s.y<0||s.y>1,a=N(t.w,0,o);return S(r.x,r.y,r.z,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"uv\"}],body:[0,[[13,\"linear\",[6,\"srgbToLinear\",[[6,\"d.vec3f\",[[7,\"color\",\"x\"],[7,\"color\",\"y\"],[7,\"color\",\"z\"]]]]]],[13,\"outOfBounds\",[3,[3,[3,[1,[7,\"uv\",\"x\"],\"<\",[5,\"0\"]],\"||\",[1,[7,\"uv\",\"x\"],\">\",[5,\"1\"]]],\"||\",[1,[7,\"uv\",\"y\"],\"<\",[5,\"0\"]]],\"||\",[1,[7,\"uv\",\"y\"],\">\",[5,\"1\"]]]],[13,\"alpha\",[6,\"std.select\",[[7,\"color\",\"w\"],[5,\"0\"],\"outOfBounds\"]]],[10,[6,\"d.vec4f\",[[7,\"linear\",\"x\"],[7,\"linear\",\"y\"],[7,\"linear\",\"z\"],\"alpha\"]]]]]},externals:{srgbToLinear:()=>Iu,\"d.vec3f\":()=>A,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&e.f)({})),One={cover:0,contain:1,fill:2,\"scale-down\":3,none:2},Gne={cover:0,contain:1,fill:2,\"scale-down\":3,none:4};function Fne(e){let t=e.allowNone?Gne:One,s=e.allowNone?0:2,r=typeof e.fit==\"number\"?e.fit:t[e.fit]??s,o=e.texture.dimensions(),a;r===1?a=W(kne,\"scaleContain\",[o,e.viewport]):r===2?a=W(Bne,\"scaleFill\",[]):r===3?a=W(zne,\"scaleScaleDown\",[o,e.viewport]):r===4&&e.allowNone?a=W(Rne,\"scaleNone\",[o,e.viewport]):a=W(Ene,\"scaleCover\",[o,e.viewport]);let i=W(Dne,\"mediaSampleUV\",[e.uv,a]),l=e.uvPostProcess?e.uvPostProcess(i):i;return W(Une,\"mediaAlphaCut\",[e.texture.sample(l),l])}var nz=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=re(s),i=__tsover_sub(r,t),l=o,c=__tsover_mul(r,2),d=G(__tsover_div(__tsover_add(__tsover_mul(a,l),__tsover_mul(i,c)),B(__tsover_add(__tsover_mul(l,l),__tsover_mul(c,c)),1e-9)),0,1),u=__tsover_sub(a,__tsover_mul(l,d)),p=__tsover_sub(i,__tsover_mul(c,d)),_=__tsover_sub(a,__tsover_mul(l,G(__tsover_div(a,B(l,1e-9)),0,1))),f=__tsover_sub(i,c),h=ye(__tsover_add(__tsover_mul(u,u),__tsover_mul(p,p)),__tsover_add(__tsover_mul(_,_),__tsover_mul(f,f))),g=ye(__tsover_sub(__tsover_mul(i,l),__tsover_mul(a,c)),__tsover_sub(c,i))>0;return N(Ue(h),-Ue(h),g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"hl\"},{type:\"i\",name:\"hw\"}],body:[0,[[13,\"px\",[6,\"std.abs\",[\"n\"]]],[13,\"py\",[1,\"hl\",\"-\",\"t\"]],[13,\"qx\",\"hw\"],[13,\"qy\",[1,\"hl\",\"*\",[5,\"2\"]]],[13,\"k\",[6,\"std.clamp\",[[1,[1,[1,\"px\",\"*\",\"qx\"],\"+\",[1,\"py\",\"*\",\"qy\"]],\"/\",[6,\"std.max\",[[1,[1,\"qx\",\"*\",\"qx\"],\"+\",[1,\"qy\",\"*\",\"qy\"]],[5,\"1e-9\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"ax\",[1,\"px\",\"-\",[1,\"qx\",\"*\",\"k\"]]],[13,\"ay\",[1,\"py\",\"-\",[1,\"qy\",\"*\",\"k\"]]],[13,\"bx\",[1,\"px\",\"-\",[1,\"qx\",\"*\",[6,\"std.clamp\",[[1,\"px\",\"/\",[6,\"std.max\",[\"qx\",[5,\"1e-9\"]]]],[5,\"0\"],[5,\"1\"]]]]]],[13,\"by\",[1,\"py\",\"-\",\"qy\"]],[13,\"dSq\",[6,\"std.min\",[[1,[1,\"ax\",\"*\",\"ax\"],\"+\",[1,\"ay\",\"*\",\"ay\"]],[1,[1,\"bx\",\"*\",\"bx\"],\"+\",[1,\"by\",\"*\",\"by\"]]]]],[13,\"sA\",[1,[1,\"py\",\"*\",\"qx\"],\"-\",[1,\"px\",\"*\",\"qy\"]]],[13,\"sB\",[1,\"qy\",\"-\",\"py\"]],[13,\"inside\",[1,[6,\"std.min\",[\"sA\",\"sB\"]],\">\",[5,\"0\"]]],[10,[6,\"std.select\",[[6,\"std.sqrt\",[\"dSq\"]],[4,\"-\",[6,\"std.sqrt\",[\"dSq\"]]],\"inside\"]]]]]},externals:{\"std.abs\":()=>re,\"std.clamp\":()=>G,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.select\":()=>N,\"std.sqrt\":()=>Ue}})&&e.f)({})).$name(\"agentArrowSdf\"),iz=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(t,G(t,-r,r));return __tsover_sub(Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(s,s))),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"hl\"},{type:\"i\",name:\"r\"}],body:[0,[[13,\"tc\",[1,\"t\",\"-\",[6,\"std.clamp\",[\"t\",[4,\"-\",\"hl\"],\"hl\"]]]],[10,[1,[6,\"std.sqrt\",[[1,[1,\"tc\",\"*\",\"tc\"],\"+\",[1,\"n\",\"*\",\"n\"]]]],\"-\",\"r\"]]]]},externals:{\"std.clamp\":()=>G,\"std.sqrt\":()=>Ue}})&&e.f)({})).$name(\"agentCapsuleSdf\"),lz=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(re(t),r),i=__tsover_sub(re(s),o),l=B(a,0),c=B(i,0);return __tsover_add(Ue(__tsover_add(__tsover_mul(l,l),__tsover_mul(c,c))),ye(B(a,i),0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"hl\"},{type:\"i\",name:\"hw\"}],body:[0,[[13,\"qx\",[1,[6,\"std.abs\",[\"t\"]],\"-\",\"hl\"]],[13,\"qy\",[1,[6,\"std.abs\",[\"n\"]],\"-\",\"hw\"]],[13,\"ox\",[6,\"std.max\",[\"qx\",[5,\"0\"]]]],[13,\"oy\",[6,\"std.max\",[\"qy\",[5,\"0\"]]]],[10,[1,[6,\"std.sqrt\",[[1,[1,\"ox\",\"*\",\"ox\"],\"+\",[1,\"oy\",\"*\",\"oy\"]]]],\"+\",[6,\"std.min\",[[6,\"std.max\",[\"qx\",\"qy\"]],[5,\"0\"]]]]]]]},externals:{\"std.abs\":()=>re,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.min\":()=>ye}})&&e.f)({})).$name(\"agentBoxSdf\"),zd={arrow:{kind:1,hl:2.3,hw:1,soft:0,ext:2.65},streak:{kind:0,hl:1.7,hw:.8,soft:0,ext:2.6},dot:{kind:0,hl:0,hw:1,soft:0,ext:1.2},square:{kind:2,hl:.9,hw:.9,soft:0,ext:1.5},glow:{kind:0,hl:0,hw:0,soft:1,ext:2.1}};function wd(e,t){return typeof e==\"string\"&&e in zd?e:t}var lp=[{label:\"Arrow\",value:\"arrow\"},{label:\"Streak\",value:\"streak\"},{label:\"Dot\",value:\"dot\"},{label:\"Square\",value:\"square\"},{label:\"Glow\",value:\"glow\"}],cp=[{label:\"Dot\",value:\"dot\"},{label:\"Square\",value:\"square\"},{label:\"Glow\",value:\"glow\"}];function Ine(e){let t=zd[wd(e,\"dot\")],s=t.kind===1?nz:t.kind===2?lz:iz,r=t.hl,o=t.hw;return w.fn([n,n,n,n,n],n)((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l,c,d,u)=>{\"use gpu\";let p=s(i,l,__tsover_mul(c,r),__tsover_mul(c,o)),_=__tsover_sub(1,be(-d,d,p)),f=__tsover_div(B(p,0),B(__tsover_mul(c,.75),1e-6));return K(_,Tt(__tsover_mul(__tsover_mul(f,f),-1)),u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"},{type:\"i\",name:\"soft\"}],body:[0,[[13,\"sd\",[6,\"sdFn\",[\"t\",\"n\",[1,\"bodyR\",\"*\",\"HL\"],[1,\"bodyR\",\"*\",\"HW\"]]]],[13,\"wHard\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"aaW\"],\"aaW\",\"sd\"]]]],[13,\"gq\",[1,[6,\"std.max\",[\"sd\",[5,\"0\"]]],\"/\",[6,\"std.max\",[[1,\"bodyR\",\"*\",[5,\"0.75\"]],[5,\"0.000001\"]]]]],[13,\"wSoft\",[6,\"std.exp\",[[1,[1,\"gq\",\"*\",\"gq\"],\"*\",[4,\"-\",[5,\"1\"]]]]]],[10,[6,\"std.mix\",[\"wHard\",\"wSoft\",\"soft\"]]]]]},externals:{sdFn:()=>s,HL:()=>r,HW:()=>o,\"std.smoothstep\":()=>be,\"std.max\":()=>B,\"std.exp\":()=>Tt,\"std.mix\":()=>K}})&&a.f)({})).$name(\"agentWeight\")}function k_(e){let t=zd[wd(e,\"dot\")],s=t.kind===1?nz:t.kind===2?lz:iz,r=t.hl,o=t.hw,a=t.kind===0&&t.hl===0,i=t.soft===1;return a?i?w.fn([n,n,n,n,n],n)((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d,u,p,_)=>{\"use gpu\";let f=__tsover_mul(p,__tsover_sub(Ue(c),o)),h=__tsover_div(B(f,0),B(__tsover_mul(p,.75),1e-6));return Tt(__tsover_mul(__tsover_mul(h,h),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"_t\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"_aaW\"}],body:[0,[[13,\"sd\",[1,\"bodyR\",\"*\",[1,[6,\"std.sqrt\",[\"q\"]],\"-\",\"HW\"]]],[13,\"gq\",[1,[6,\"std.max\",[\"sd\",[5,\"0\"]]],\"/\",[6,\"std.max\",[[1,\"bodyR\",\"*\",[5,\"0.75\"]],[5,\"0.000001\"]]]]],[10,[6,\"std.exp\",[[1,[1,\"gq\",\"*\",\"gq\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{\"std.sqrt\":()=>Ue,HW:()=>o,\"std.max\":()=>B,\"std.exp\":()=>Tt}})&&l.f)({})).$name(\"agentTexelWeight\"):w.fn([n,n,n,n,n],n)((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d,u,p,_)=>{\"use gpu\";let f=__tsover_mul(p,__tsover_sub(Ue(c),o));return __tsover_sub(1,be(-_,_,f))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"_t\"},{type:\"i\",name:\"_n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"}],body:[0,[[13,\"sd\",[1,\"bodyR\",\"*\",[1,[6,\"std.sqrt\",[\"q\"]],\"-\",\"HW\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"aaW\"],\"aaW\",\"sd\"]]]]]]},externals:{\"std.sqrt\":()=>Ue,HW:()=>o,\"std.smoothstep\":()=>be}})&&l.f)({})).$name(\"agentTexelWeight\"):i?w.fn([n,n,n,n,n],n)((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d,u,p,_)=>{\"use gpu\";let f=s(d,u,__tsover_mul(p,r),__tsover_mul(p,o)),h=__tsover_div(B(f,0),B(__tsover_mul(p,.75),1e-6));return Tt(__tsover_mul(__tsover_mul(h,h),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_q\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"_aaW\"}],body:[0,[[13,\"sd\",[6,\"sdFn\",[\"t\",\"n\",[1,\"bodyR\",\"*\",\"HL\"],[1,\"bodyR\",\"*\",\"HW\"]]]],[13,\"gq\",[1,[6,\"std.max\",[\"sd\",[5,\"0\"]]],\"/\",[6,\"std.max\",[[1,\"bodyR\",\"*\",[5,\"0.75\"]],[5,\"0.000001\"]]]]],[10,[6,\"std.exp\",[[1,[1,\"gq\",\"*\",\"gq\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{sdFn:()=>s,HL:()=>r,HW:()=>o,\"std.max\":()=>B,\"std.exp\":()=>Tt}})&&l.f)({})).$name(\"agentTexelWeight\"):w.fn([n,n,n,n,n],n)((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d,u,p,_)=>{\"use gpu\";let f=s(d,u,__tsover_mul(p,r),__tsover_mul(p,o));return __tsover_sub(1,be(-_,_,f))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_q\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"}],body:[0,[[13,\"sd\",[6,\"sdFn\",[\"t\",\"n\",[1,\"bodyR\",\"*\",\"HL\"],[1,\"bodyR\",\"*\",\"HW\"]]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"aaW\"],\"aaW\",\"sd\"]]]]]]},externals:{sdFn:()=>s,HL:()=>r,HW:()=>o,\"std.smoothstep\":()=>be}})&&l.f)({})).$name(\"agentTexelWeight\")}function cz(e,t){let s=wd(e,\"streak\"),r=zd[s],o=t?.comet!==!1;return{name:s,soft:r.soft,hl:o&&s===\"glow\"?1:r.hl,ext:o&&s===\"glow\"?r.ext+1:r.ext,symmetric:r.kind===0&&r.hl===0&&!(o&&s===\"glow\")}}function Yne(e){let t=cz(e),s=k_(t.name),r=t.hl,o=t.soft;return w.fn([n,n,n,n],n)((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l,c,d)=>{\"use gpu\";let u=__tsover_mul(c,r),p=N(i,__tsover_sub(i,G(i,-u,u)),n(o)>.5),_=G(__tsover_div(__tsover_sub(u,i),B(__tsover_mul(u,2),1e-6)),0,1),f=__tsover_sub(1,__tsover_mul(__tsover_mul(.55,_),n(o))),h=__tsover_div(__tsover_add(__tsover_mul(p,p),__tsover_mul(l,l)),__tsover_mul(c,c));return __tsover_mul(s(h,p,l,c,d),f)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"}],body:[0,[[13,\"hl\",[1,\"bodyR\",\"*\",\"HL\"]],[13,\"tGlow\",[1,\"t\",\"-\",[6,\"std.clamp\",[\"t\",[4,\"-\",\"hl\"],\"hl\"]]]],[13,\"tEval\",[6,\"std.select\",[\"t\",\"tGlow\",[1,[6,\"d.f32\",[\"SOFT\"]],\">\",[5,\"0.5\"]]]]],[13,\"tk\",[6,\"std.clamp\",[[1,[1,\"hl\",\"-\",\"t\"],\"/\",[6,\"std.max\",[[1,\"hl\",\"*\",[5,\"2\"]],[5,\"0.000001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"bright\",[1,[5,\"1\"],\"-\",[1,[1,[5,\"0.55\"],\"*\",\"tk\"],\"*\",[6,\"d.f32\",[\"SOFT\"]]]]],[13,\"qEval\",[1,[1,[1,\"tEval\",\"*\",\"tEval\"],\"+\",[1,\"n\",\"*\",\"n\"]],\"/\",[1,\"bodyR\",\"*\",\"bodyR\"]]],[10,[1,[6,\"weightFn\",[\"qEval\",\"tEval\",\"n\",\"bodyR\",\"aaW\"]],\"*\",\"bright\"]]]]},externals:{HL:()=>r,\"std.clamp\":()=>G,\"std.select\":()=>N,\"d.f32\":()=>n,SOFT:()=>o,\"std.max\":()=>B,weightFn:()=>s}})&&a.f)({})).$name(\"agentCometWeight\")}var v1=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=he(t),i=N(m(0,0),t.div(B(a,1e-5)).mul(r),a>1e-5).sub(s),l=he(i);return N(i,i.div(B(l,1e-5)).mul(o),l>o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dir\"},{type:\"i\",name:\"vel\"},{type:\"i\",name:\"maxSpeed\"},{type:\"i\",name:\"maxForce\"}],body:[0,[[13,\"len\",[6,\"std.length\",[\"dir\"]]],[13,\"desired\",[6,\"std.select\",[[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,[7,[6,[7,\"dir\",\"div\"],[[6,\"std.max\",[\"len\",[5,\"0.00001\"]]]]],\"mul\"],[\"maxSpeed\"]],[1,\"len\",\">\",[5,\"0.00001\"]]]]],[13,\"steer\",[6,[7,\"desired\",\"sub\"],[\"vel\"]]],[13,\"sl\",[6,\"std.length\",[\"steer\"]]],[10,[6,\"std.select\",[\"steer\",[6,[7,[6,[7,\"steer\",\"div\"],[[6,\"std.max\",[\"sl\",[5,\"0.00001\"]]]]],\"mul\"],[\"maxForce\"]],[1,\"sl\",\">\",\"maxForce\"]]]]]]},externals:{\"std.length\":()=>he,\"std.select\":()=>N,\"d.vec2f\":()=>m,\"std.max\":()=>B}})&&e.f)({})).$name(\"agentReynoldsSteer\"),wP=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(.82,__tsover_mul(Xs(__tsover_add(__tsover_mul(t,.61803),.13)),.4))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[10,[1,[5,\"0.82\"],\"+\",[1,[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"0.61803\"]],\"+\",[5,\"0.13\"]]]],\"*\",[5,\"0.4\"]]]]]]},externals:{\"noise.hash11\":()=>Xs}})&&e.f)({})).$name(\"agentCruiseVariation\"),h1=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_add(.55,__tsover_mul(Xs(__tsover_add(__tsover_mul(t,1.91),2.53)),.7))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[10,[1,[5,\"0.55\"],\"+\",[1,[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"1.91\"]],\"+\",[5,\"2.53\"]]]],\"*\",[5,\"0.7\"]]]]]]},externals:{\"noise.hash11\":()=>Xs}})&&e.f)({})).$name(\"agentPresenceVariation\"),dz=w.fn([S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=G(t.w,0,1),o=__tsover_add(r,__tsover_mul(s.w,__tsover_sub(1,r))),a=t.xyz.mul(r).add(s.xyz.mul(__tsover_mul(s.w,__tsover_sub(1,r)))).div(B(o,1e-4));return S(a.x,a.y,a.z,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"c\"}],body:[0,[[13,\"pa\",[6,\"std.clamp\",[[7,\"p\",\"w\"],[5,\"0\"],[5,\"1\"]]]],[13,\"outA\",[1,\"pa\",\"+\",[1,[7,\"c\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"pa\"]]]],[13,\"rgb\",[6,[7,[6,[7,[6,[7,[7,\"p\",\"xyz\"],\"mul\"],[\"pa\"]],\"add\"],[[6,[7,[7,\"c\",\"xyz\"],\"mul\"],[[1,[7,\"c\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",\"pa\"]]]]]],\"div\"],[[6,\"std.max\",[\"outA\",[5,\"0.0001\"]]]]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"outA\"]]]]]},externals:{\"std.clamp\":()=>G,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"agentStraightAlphaOver\"),TP=w.fn([m,m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=Se(s,t);return N(t.mul(__tsover_mul(2,o)).sub(s),t,r>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rhat\"},{type:\"i\",name:\"axis\"},{type:\"i\",name:\"fieldType\"}],body:[0,[[13,\"mdotr\",[6,\"std.dot\",[\"axis\",\"rhat\"]]],[13,\"dipoleB\",[6,[7,[6,[7,\"rhat\",\"mul\"],[[1,[5,\"2\"],\"*\",\"mdotr\"]]],\"sub\"],[\"axis\"]]],[10,[6,\"std.select\",[\"dipoleB\",\"rhat\",[1,\"fieldType\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.dot\":()=>Se,\"std.select\":()=>N}})&&e.f)({})).$name(\"agentDipoleOrRadialField\"),Jv=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";return __tsover_mul(t,ae(__tsover_mul(2,__tsover_sub(s,r))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"k\"},{type:\"i\",name:\"target\"},{type:\"i\",name:\"theta\"}],body:[0,[[10,[1,\"k\",\"*\",[6,\"std.sin\",[[1,[5,\"2\"],\"*\",[1,\"target\",\"-\",\"theta\"]]]]]]]]},externals:{\"std.sin\":()=>ae}})&&e.f)({})).$name(\"agentNematicTorque\"),SP=w.fn([S,n,S,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(r.w,o),i=s>=a,l=B(s,a),c=N(A(r.x,r.y,r.z),A(t.x,t.y,t.z),i);return S(c.x,c.y,c.z,l)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"col\"},{type:\"i\",name:\"curA\"},{type:\"i\",name:\"prev\"},{type:\"i\",name:\"trails\"}],body:[0,[[13,\"prevA\",[1,[7,\"prev\",\"w\"],\"*\",\"trails\"]],[13,\"win\",[1,\"curA\",\">=\",\"prevA\"]],[13,\"outA\",[6,\"std.max\",[\"curA\",\"prevA\"]]],[13,\"outRGB\",[6,\"std.select\",[[6,\"d.vec3f\",[[7,\"prev\",\"x\"],[7,\"prev\",\"y\"],[7,\"prev\",\"z\"]]],[6,\"d.vec3f\",[[7,\"col\",\"x\"],[7,\"col\",\"y\"],[7,\"col\",\"z\"]]],\"win\"]]],[10,[6,\"d.vec4f\",[[7,\"outRGB\",\"x\"],[7,\"outRGB\",\"y\"],[7,\"outRGB\",\"z\"],\"outA\"]]]]]},externals:{\"std.max\":()=>B,\"std.select\":()=>N,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"agentTrailMaxDecay\"),eh=w.fn([A,S,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return A(__tsover_add(__tsover_add(__tsover_mul(s.x,t.x),__tsover_mul(s.y,t.y)),__tsover_mul(s.z,t.z)),__tsover_add(__tsover_add(__tsover_mul(r.x,t.x),__tsover_mul(r.y,t.y)),__tsover_mul(r.z,t.z)),__tsover_add(__tsover_add(__tsover_mul(o.x,t.x),__tsover_mul(o.y,t.y)),__tsover_mul(o.z,t.z)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pw\"},{type:\"i\",name:\"rowX\"},{type:\"i\",name:\"rowY\"},{type:\"i\",name:\"rowZ\"}],body:[0,[[10,[6,\"d.vec3f\",[[1,[1,[1,[7,\"rowX\",\"x\"],\"*\",[7,\"pw\",\"x\"]],\"+\",[1,[7,\"rowX\",\"y\"],\"*\",[7,\"pw\",\"y\"]]],\"+\",[1,[7,\"rowX\",\"z\"],\"*\",[7,\"pw\",\"z\"]]],[1,[1,[1,[7,\"rowY\",\"x\"],\"*\",[7,\"pw\",\"x\"]],\"+\",[1,[7,\"rowY\",\"y\"],\"*\",[7,\"pw\",\"y\"]]],\"+\",[1,[7,\"rowY\",\"z\"],\"*\",[7,\"pw\",\"z\"]]],[1,[1,[1,[7,\"rowZ\",\"x\"],\"*\",[7,\"pw\",\"x\"]],\"+\",[1,[7,\"rowZ\",\"y\"],\"*\",[7,\"pw\",\"y\"]]],\"+\",[1,[7,\"rowZ\",\"z\"],\"*\",[7,\"pw\",\"z\"]]]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})).$name(\"agentApplyCameraRows\"),PP=w.fn([A,S,S,S],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";return A(__tsover_add(__tsover_add(__tsover_mul(s.x,t.x),__tsover_mul(r.x,t.y)),__tsover_mul(o.x,t.z)),__tsover_add(__tsover_add(__tsover_mul(s.y,t.x),__tsover_mul(r.y,t.y)),__tsover_mul(o.y,t.z)),__tsover_add(__tsover_add(__tsover_mul(s.z,t.x),__tsover_mul(r.z,t.y)),__tsover_mul(o.z,t.z)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"},{type:\"i\",name:\"rowX\"},{type:\"i\",name:\"rowY\"},{type:\"i\",name:\"rowZ\"}],body:[0,[[10,[6,\"d.vec3f\",[[1,[1,[1,[7,\"rowX\",\"x\"],\"*\",[7,\"v\",\"x\"]],\"+\",[1,[7,\"rowY\",\"x\"],\"*\",[7,\"v\",\"y\"]]],\"+\",[1,[7,\"rowZ\",\"x\"],\"*\",[7,\"v\",\"z\"]]],[1,[1,[1,[7,\"rowX\",\"y\"],\"*\",[7,\"v\",\"x\"]],\"+\",[1,[7,\"rowY\",\"y\"],\"*\",[7,\"v\",\"y\"]]],\"+\",[1,[7,\"rowZ\",\"y\"],\"*\",[7,\"v\",\"z\"]]],[1,[1,[1,[7,\"rowX\",\"z\"],\"*\",[7,\"v\",\"x\"]],\"+\",[1,[7,\"rowY\",\"z\"],\"*\",[7,\"v\",\"y\"]]],\"+\",[1,[7,\"rowZ\",\"z\"],\"*\",[7,\"v\",\"z\"]]]]]]]]},externals:{\"d.vec3f\":()=>A}})&&e.f)({})).$name(\"agentApplyCameraRowsT\"),q0=gt({x0:M,x1:M,y0:M,y1:M,fx:n,fy:n}).$name(\"AgentBilinearFrame\"),th=w.fn([m,m],q0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_sub(__tsover_mul(t.x,s.x),.5),o=__tsover_sub(__tsover_mul(t.y,s.y),.5),a=ie(r),i=ie(o);return q0({x0:M(G(a,n(0),__tsover_sub(s.x,1))),x1:M(G(__tsover_add(a,1),n(0),__tsover_sub(s.x,1))),y0:M(G(i,n(0),__tsover_sub(s.y,1))),y1:M(G(__tsover_add(i,1),n(0),__tsover_sub(s.y,1))),fx:__tsover_sub(r,a),fy:__tsover_sub(o,i)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv01\"},{type:\"i\",name:\"dims\"}],body:[0,[[13,\"cu\",[1,[1,[7,\"uv01\",\"x\"],\"*\",[7,\"dims\",\"x\"]],\"-\",[5,\"0.5\"]]],[13,\"cv\",[1,[1,[7,\"uv01\",\"y\"],\"*\",[7,\"dims\",\"y\"]],\"-\",[5,\"0.5\"]]],[13,\"cx0\",[6,\"std.floor\",[\"cu\"]]],[13,\"cy0\",[6,\"std.floor\",[\"cv\"]]],[10,[6,\"BilinearFrame\",[[104,{x0:[6,\"d.u32\",[[6,\"std.clamp\",[\"cx0\",[6,\"d.f32\",[[5,\"0\"]]],[1,[7,\"dims\",\"x\"],\"-\",[5,\"1\"]]]]]],x1:[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cx0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,[7,\"dims\",\"x\"],\"-\",[5,\"1\"]]]]]],y0:[6,\"d.u32\",[[6,\"std.clamp\",[\"cy0\",[6,\"d.f32\",[[5,\"0\"]]],[1,[7,\"dims\",\"y\"],\"-\",[5,\"1\"]]]]]],y1:[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cy0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,[7,\"dims\",\"y\"],\"-\",[5,\"1\"]]]]]],fx:[1,\"cu\",\"-\",\"cx0\"],fy:[1,\"cv\",\"-\",\"cy0\"]}]]]]]]},externals:{\"std.floor\":()=>ie,BilinearFrame:()=>q0,\"d.u32\":()=>M,\"std.clamp\":()=>G,\"d.f32\":()=>n}})&&e.f)({})).$name(\"agentBilinearTexelFrame\"),sh=w.fn([m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Se(t,t);return Tt(__tsover_mul(__tsover_div(r,B(s,1e-5)),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"delta\"},{type:\"i\",name:\"radSq\"}],body:[0,[[13,\"dl\",[6,\"std.dot\",[\"delta\",\"delta\"]]],[10,[6,\"std.exp\",[[1,[1,\"dl\",\"/\",[6,\"std.max\",[\"radSq\",[5,\"0.00001\"]]]],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"std.exp\":()=>Tt,\"std.max\":()=>B}})&&e.f)({})).$name(\"agentCursorFalloff\"),Xu=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(he(t),1e-4);return t.div(o).mul(__tsover_mul(sh(t,s),r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"delta\"},{type:\"i\",name:\"radSq\"},{type:\"i\",name:\"force\"}],body:[0,[[13,\"dl\",[6,\"std.max\",[[6,\"std.length\",[\"delta\"]],[5,\"0.0001\"]]]],[10,[6,[7,[6,[7,\"delta\",\"div\"],[\"dl\"]],\"mul\"],[[1,[6,\"cursorFalloff\",[\"delta\",\"radSq\"]],\"*\",\"force\"]]]]]]},externals:{\"std.max\":()=>B,\"std.length\":()=>he,cursorFalloff:()=>sh}})&&e.f)({})).$name(\"agentCursorMagnet\");function eg(e,t){return w.fn([M])((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=e.$.params,a=n(r),i=ei(A(__tsover_add(__tsover_mul(a,1.6180339),.71),__tsover_add(__tsover_mul(a,2.7182818),4.17),__tsover_add(__tsover_mul(a,3.1415926),9.03)));e.$.agents[r]=S(__tsover_mul(i.x,o.aspect),i.y,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"r\",[6,\"noise.hash33\",[[6,\"d.vec3f\",[[1,[1,\"fi\",\"*\",[5,\"1.6180339\"]],\"+\",[5,\"0.71\"]],[1,[1,\"fi\",\"*\",[5,\"2.7182818\"]],\"+\",[5,\"4.17\"]],[1,[1,\"fi\",\"*\",[5,\"3.1415926\"]],\"+\",[5,\"9.03\"]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"r\",\"x\"],\"*\",[7,\"prm\",\"aspect\"]],[7,\"r\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,\"noise.hash33\":()=>ei,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&s.f)({})).$name(t)}function uz(e,t,s){let r=s?.radius??.55,o=s?.zSquash??.8;return w.fn([M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=(i=>{\"use gpu\";let l=n(i),c=vs(ei(A(__tsover_add(__tsover_mul(l,1.6180339),.71),__tsover_add(__tsover_mul(l,2.7182818),4.17),__tsover_add(__tsover_mul(l,3.1415926),9.03))).sub(A(.5,.5,.5)).add(A(1e-4,2e-4,3e-4))),d=__tsover_mul(vt(Xs(__tsover_add(__tsover_mul(l,2.2360679),1.7)),n(.3333)),r),u=Xs(__tsover_add(__tsover_mul(l,1.7320508),.37));e.$.pos[i]=S(__tsover_mul(c.x,d),__tsover_mul(c.y,d),__tsover_mul(__tsover_mul(c.z,d),o),u),e.$.vel[i]=S(0,0,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"h3\",[6,\"noise.hash33\",[[6,\"d.vec3f\",[[1,[1,\"fi\",\"*\",[5,\"1.6180339\"]],\"+\",[5,\"0.71\"]],[1,[1,\"fi\",\"*\",[5,\"2.7182818\"]],\"+\",[5,\"4.17\"]],[1,[1,\"fi\",\"*\",[5,\"3.1415926\"]],\"+\",[5,\"9.03\"]]]]]]],[13,\"dir\",[6,\"std.normalize\",[[6,[7,[6,[7,\"h3\",\"sub\"],[[6,\"d.vec3f\",[[5,\"0.5\"],[5,\"0.5\"],[5,\"0.5\"]]]]],\"add\"],[[6,\"d.vec3f\",[[5,\"0.0001\"],[5,\"0.0002\"],[5,\"0.0003\"]]]]]]]],[13,\"rad\",[1,[6,\"std.pow\",[[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"2.2360679\"]],\"+\",[5,\"1.7\"]]]],[6,\"d.f32\",[[5,\"0.3333\"]]]]],\"*\",\"RAD\"]],[13,\"seed\",[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"1.7320508\"]],\"+\",[5,\"0.37\"]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"dir\",\"x\"],\"*\",\"rad\"],[1,[7,\"dir\",\"y\"],\"*\",\"rad\"],[1,[1,[7,\"dir\",\"z\"],\"*\",\"rad\"],\"*\",\"ZS\"],\"seed\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"],\"=\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{\"d.f32\":()=>n,\"noise.hash33\":()=>ei,\"d.vec3f\":()=>A,\"std.normalize\":()=>vs,\"std.pow\":()=>vt,\"noise.hash11\":()=>Xs,RAD:()=>r,layout:()=>e,\"d.vec4f\":()=>S,ZS:()=>o}})&&a.f)({})).$name(t)}function pz(e,t,s){let r=s?.agentsPerCluster??250,o=s?.minClusters??3,a=6.283185307179586;return w.fn([M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=(l=>{\"use gpu\";let c=e.$.params,d=n(l),u=__tsover_mul(c.seed,13.137),p=B(ie(__tsover_div(c.count,n(r))),n(o)),_=__tsover_sub(d,__tsover_mul(ie(__tsover_div(d,p)),p)),f=ei(A(__tsover_add(__tsover_add(__tsover_mul(_,7.1315),u),.71),__tsover_add(__tsover_add(__tsover_mul(_,3.7719),u),4.17),__tsover_add(__tsover_add(__tsover_mul(_,9.4103),u),9.03))),h=__tsover_mul(f.z,a),g=m(pe(h),ae(h)),y=m(__tsover_mul(__tsover_add(.12,__tsover_mul(f.x,.76)),c.domainX),__tsover_add(.12,__tsover_mul(f.y,.76))),b=ei(A(__tsover_add(__tsover_add(__tsover_mul(d,1.6180339),u),.71),__tsover_add(__tsover_add(__tsover_mul(d,2.7182818),u),4.17),__tsover_add(__tsover_add(__tsover_mul(d,3.1415926),u),9.03))),x=__tsover_mul(__tsover_sub(b.x,.5),.6),P=__tsover_mul(__tsover_sub(b.y,.5),.16),C=G(__tsover_sub(__tsover_add(y.x,__tsover_mul(g.x,x)),__tsover_mul(g.y,P)),0,c.domainX),E=G(__tsover_add(__tsover_add(y.y,__tsover_mul(g.y,x)),__tsover_mul(g.x,P)),0,1),R=__tsover_add(h,__tsover_mul(__tsover_sub(b.z,.5),.5)),U=__tsover_mul(c.maxSpeed,__tsover_add(.75,__tsover_mul(b.y,.25)));e.$.agents[l]=S(C,E,__tsover_mul(pe(R),U),__tsover_mul(ae(R),U)),e.$.agit[l]=n(0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"sd\",[1,[7,\"prm\",\"seed\"],\"*\",[5,\"13.137\"]]],[13,\"flocks\",[6,\"std.max\",[[6,\"std.floor\",[[1,[7,\"prm\",\"count\"],\"/\",[6,\"d.f32\",[\"PER\"]]]]],[6,\"d.f32\",[\"MIN\"]]]]],[13,\"c\",[1,\"fi\",\"-\",[1,[6,\"std.floor\",[[1,\"fi\",\"/\",\"flocks\"]]],\"*\",\"flocks\"]]],[13,\"rc\",[6,\"noise.hash33\",[[6,\"d.vec3f\",[[1,[1,[1,\"c\",\"*\",[5,\"7.1315\"]],\"+\",\"sd\"],\"+\",[5,\"0.71\"]],[1,[1,[1,\"c\",\"*\",[5,\"3.7719\"]],\"+\",\"sd\"],\"+\",[5,\"4.17\"]],[1,[1,[1,\"c\",\"*\",[5,\"9.4103\"]],\"+\",\"sd\"],\"+\",[5,\"9.03\"]]]]]]],[13,\"ang\",[1,[7,\"rc\",\"z\"],\"*\",\"TAU\"]],[13,\"hd\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"ang\"]],[6,\"std.sin\",[\"ang\"]]]]],[13,\"center\",[6,\"d.vec2f\",[[1,[1,[5,\"0.12\"],\"+\",[1,[7,\"rc\",\"x\"],\"*\",[5,\"0.76\"]]],\"*\",[7,\"prm\",\"domainX\"]],[1,[5,\"0.12\"],\"+\",[1,[7,\"rc\",\"y\"],\"*\",[5,\"0.76\"]]]]]],[13,\"ra\",[6,\"noise.hash33\",[[6,\"d.vec3f\",[[1,[1,[1,\"fi\",\"*\",[5,\"1.6180339\"]],\"+\",\"sd\"],\"+\",[5,\"0.71\"]],[1,[1,[1,\"fi\",\"*\",[5,\"2.7182818\"]],\"+\",\"sd\"],\"+\",[5,\"4.17\"]],[1,[1,[1,\"fi\",\"*\",[5,\"3.1415926\"]],\"+\",\"sd\"],\"+\",[5,\"9.03\"]]]]]]],[13,\"t\",[1,[1,[7,\"ra\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.6\"]]],[13,\"n\",[1,[1,[7,\"ra\",\"y\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.16\"]]],[13,\"px\",[6,\"std.clamp\",[[1,[1,[7,\"center\",\"x\"],\"+\",[1,[7,\"hd\",\"x\"],\"*\",\"t\"]],\"-\",[1,[7,\"hd\",\"y\"],\"*\",\"n\"]],[5,\"0\"],[7,\"prm\",\"domainX\"]]]],[13,\"py\",[6,\"std.clamp\",[[1,[1,[7,\"center\",\"y\"],\"+\",[1,[7,\"hd\",\"y\"],\"*\",\"t\"]],\"+\",[1,[7,\"hd\",\"x\"],\"*\",\"n\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"jAng\",[1,\"ang\",\"+\",[1,[1,[7,\"ra\",\"z\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"0.5\"]]]],[13,\"sp\",[1,[7,\"prm\",\"maxSpeed\"],\"*\",[1,[5,\"0.75\"],\"+\",[1,[7,\"ra\",\"y\"],\"*\",[5,\"0.25\"]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[\"px\",\"py\",[1,[6,\"std.cos\",[\"jAng\"]],\"*\",\"sp\"],[1,[6,\"std.sin\",[\"jAng\"]],\"*\",\"sp\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"=\",[6,\"d.f32\",[[5,\"0\"]]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,\"std.max\":()=>B,\"std.floor\":()=>ie,PER:()=>r,MIN:()=>o,\"noise.hash33\":()=>ei,\"d.vec3f\":()=>A,TAU:()=>a,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&i.f)({})).$name(t)}function mz(e,t){let s=3.141592653589793;return w.fn([M])((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=(o=>{\"use gpu\";let a=n(o),i=__tsover_mul(Xs(__tsover_add(__tsover_mul(a,1.618034),.31)),s);e.$.agents[o]=S(n(0),n(0),i,n(0)),e.$.agit[o]=n(0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"theta0\",[1,[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"1.618034\"]],\"+\",[5,\"0.31\"]]]],\"*\",\"PI\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"0\"]]],\"theta0\",[6,\"d.f32\",[[5,\"0\"]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"=\",[6,\"d.f32\",[[5,\"0\"]]]]]]},externals:{\"d.f32\":()=>n,\"noise.hash11\":()=>Xs,PI:()=>s,layout:()=>e,\"d.vec4f\":()=>S}})&&r.f)({})).$name(t)}function _z(e){let t=e.maxPoints,s=e.subdivisions;return w.fn([Zt(n),m,n,n,n,n,n],m)((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a,i,l,c,d,u)=>{\"use gpu\";let p=__tsover_mul(a.x,i),_=a.y,f=__tsover_mul(l,.1),h=__tsover_add(__tsover_div(1.5,B(u,1)),__tsover_mul(d,f)),g=__tsover_div(4,B(f,.005)),y=n(100),b=n(0),x=n(0),P=S(0,0,1,0),C=S(0,0,1,0);for(let R=0;R<t;R++){let U=Ye(o,fe(M(R),0),0);if(U.z<1){let L=__tsover_mul(U.x,i),k=U.y,D=N(n(0),n(1),U.w>0),O=N(n(0),n(1),P.z<1);if(__tsover_mul(D,O)>.5){let F=__tsover_mul(N(n(0),n(1),P.w>0),N(n(0),n(1),C.z<1))>.5,q=__tsover_mul(P.x,i),Y=P.y,V=N(q,__tsover_mul(__tsover_add(__tsover_mul(C.x,i),q),.5),F),X=N(Y,__tsover_mul(__tsover_add(C.y,Y),.5),F),Q=N(P.z,__tsover_mul(__tsover_add(C.z,P.z),.5),F),te=re(P.w),J=N(te,__tsover_mul(__tsover_add(re(C.w),te),.5),F),oe=__tsover_mul(__tsover_add(q,L),.5),le=__tsover_mul(__tsover_add(Y,k),.5),se=__tsover_mul(__tsover_add(P.z,U.z),.5),Te=__tsover_mul(__tsover_add(te,re(U.w)),.5),de=V,xe=X,Ae=Q,De=J,Ee=n(100),ze=n(1);for(let ke=0;ke<s;ke++){let Me=__tsover_div(__tsover_add(n(ke),1),s),we=__tsover_sub(1,Me),Ve=__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(we,we),V),__tsover_mul(__tsover_mul(__tsover_mul(2,we),Me),q)),__tsover_mul(__tsover_mul(Me,Me),oe)),qe=__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(we,we),X),__tsover_mul(__tsover_mul(__tsover_mul(2,we),Me),Y)),__tsover_mul(__tsover_mul(Me,Me),le)),st=K(Q,se,Me),pt=K(J,Te,Me),Ze=__tsover_mul(__tsover_mul(f,De),__tsover_sub(1,__tsover_mul(Ae,c))),nt=__tsover_mul(__tsover_mul(f,pt),__tsover_sub(1,__tsover_mul(st,c))),ht=__tsover_sub(Ve,de),yt=__tsover_sub(qe,xe),St=G(__tsover_div(__tsover_add(__tsover_mul(__tsover_sub(p,de),ht),__tsover_mul(__tsover_sub(_,xe),yt)),B(__tsover_add(__tsover_mul(ht,ht),__tsover_mul(yt,yt)),1e-8)),0,1),Mt=__tsover_sub(he(m(__tsover_sub(p,__tsover_add(de,__tsover_mul(ht,St))),__tsover_sub(_,__tsover_add(xe,__tsover_mul(yt,St))))),K(Ze,nt,St));Mt<Ee&&(Ee=Mt,ze=K(Ae,st,St)),de=Ve,xe=qe,Ae=st,De=pt}y=ye(y,Ee);let Ie=Tt(__tsover_mul(__tsover_mul(Ee,-1),g));b=__tsover_add(b,__tsover_mul(ze,Ie)),x=__tsover_add(x,Ie)}else{let F=__tsover_sub(he(m(__tsover_sub(p,L),__tsover_sub(_,k))),__tsover_mul(__tsover_mul(f,re(U.w)),__tsover_sub(1,__tsover_mul(U.z,c))));y=ye(y,F);let q=Tt(__tsover_mul(__tsover_mul(F,-1),g));b=__tsover_add(b,__tsover_mul(U.z,q)),x=__tsover_add(x,q)}}C=S(P),P=S(U)}let E=__tsover_div(b,B(x,1e-20));return m(E,__tsover_mul(__tsover_sub(1,be(__tsover_mul(h,-1),h,y)),__tsover_sub(1,be(.8,1,E))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pointsTex\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"shrink\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"viewportH\"}],body:[0,[[13,\"px\",[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"]],[13,\"py\",[7,\"uv\",\"y\"]],[13,\"baseRadius\",[1,\"radius\",\"*\",[5,\"0.1\"]]],[13,\"edgeW\",[1,[1,[5,\"1.5\"],\"/\",[6,\"std.max\",[\"viewportH\",[5,\"1\"]]]],\"+\",[1,\"softness\",\"*\",\"baseRadius\"]]],[13,\"sharp\",[1,[5,\"4\"],\"/\",[6,\"std.max\",[\"baseRadius\",[5,\"0.005\"]]]]],[12,\"minSdf\",[6,\"d.f32\",[[5,\"100\"]]]],[12,\"ageSum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"wSum\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"prev\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"1\"],[5,\"0\"]]]],[12,\"prev2\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"1\"],[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"MAX_POINTS\"],[102,\"++\",\"i\"],[0,[[13,\"cur\",[6,\"std.textureLoad\",[\"pointsTex\",[6,\"d.vec2u\",[[6,\"d.u32\",[\"i\"]],[5,\"0\"]]],[5,\"0\"]]]],[11,[1,[7,\"cur\",\"z\"],\"<\",[5,\"1\"]],[0,[[13,\"cx\",[1,[7,\"cur\",\"x\"],\"*\",\"aspect\"]],[13,\"cy\",[7,\"cur\",\"y\"]],[13,\"linked\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"cur\",\"w\"],\">\",[5,\"0\"]]]]],[13,\"prevAlive\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"prev\",\"z\"],\"<\",[5,\"1\"]]]]],[11,[1,[1,\"linked\",\"*\",\"prevAlive\"],\">\",[5,\"0.5\"]],[0,[[13,\"usePrev2\",[1,[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"prev\",\"w\"],\">\",[5,\"0\"]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"prev2\",\"z\"],\"<\",[5,\"1\"]]]]],\">\",[5,\"0.5\"]]],[13,\"jx\",[1,[7,\"prev\",\"x\"],\"*\",\"aspect\"]],[13,\"jy\",[7,\"prev\",\"y\"]],[13,\"sx0\",[6,\"std.select\",[\"jx\",[1,[1,[1,[7,\"prev2\",\"x\"],\"*\",\"aspect\"],\"+\",\"jx\"],\"*\",[5,\"0.5\"]],\"usePrev2\"]]],[13,\"sy0\",[6,\"std.select\",[\"jy\",[1,[1,[7,\"prev2\",\"y\"],\"+\",\"jy\"],\"*\",[5,\"0.5\"]],\"usePrev2\"]]],[13,\"ageS\",[6,\"std.select\",[[7,\"prev\",\"z\"],[1,[1,[7,\"prev2\",\"z\"],\"+\",[7,\"prev\",\"z\"]],\"*\",[5,\"0.5\"]],\"usePrev2\"]]],[13,\"widPrev\",[6,\"std.abs\",[[7,\"prev\",\"w\"]]]],[13,\"widS\",[6,\"std.select\",[\"widPrev\",[1,[1,[6,\"std.abs\",[[7,\"prev2\",\"w\"]]],\"+\",\"widPrev\"],\"*\",[5,\"0.5\"]],\"usePrev2\"]]],[13,\"ex\",[1,[1,\"jx\",\"+\",\"cx\"],\"*\",[5,\"0.5\"]]],[13,\"ey\",[1,[1,\"jy\",\"+\",\"cy\"],\"*\",[5,\"0.5\"]]],[13,\"ageE\",[1,[1,[7,\"prev\",\"z\"],\"+\",[7,\"cur\",\"z\"]],\"*\",[5,\"0.5\"]]],[13,\"widE\",[1,[1,\"widPrev\",\"+\",[6,\"std.abs\",[[7,\"cur\",\"w\"]]]],\"*\",[5,\"0.5\"]]],[12,\"sx\",\"sx0\"],[12,\"sy\",\"sy0\"],[12,\"sAge\",\"ageS\"],[12,\"sWid\",\"widS\"],[12,\"jMin\",[6,\"d.f32\",[[5,\"100\"]]]],[12,\"jAge\",[6,\"d.f32\",[[5,\"1\"]]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",\"SUBDIVISIONS\"],[102,\"++\",\"k\"],[0,[[13,\"t\",[1,[1,[6,\"d.f32\",[\"k\"]],\"+\",[5,\"1\"]],\"/\",\"SUBDIVISIONS\"]],[13,\"omt\",[1,[5,\"1\"],\"-\",\"t\"]],[13,\"bx\",[1,[1,[1,[1,\"omt\",\"*\",\"omt\"],\"*\",\"sx0\"],\"+\",[1,[1,[1,[5,\"2\"],\"*\",\"omt\"],\"*\",\"t\"],\"*\",\"jx\"]],\"+\",[1,[1,\"t\",\"*\",\"t\"],\"*\",\"ex\"]]],[13,\"by\",[1,[1,[1,[1,\"omt\",\"*\",\"omt\"],\"*\",\"sy0\"],\"+\",[1,[1,[1,[5,\"2\"],\"*\",\"omt\"],\"*\",\"t\"],\"*\",\"jy\"]],\"+\",[1,[1,\"t\",\"*\",\"t\"],\"*\",\"ey\"]]],[13,\"bAge\",[6,\"std.mix\",[\"ageS\",\"ageE\",\"t\"]]],[13,\"bWid\",[6,\"std.mix\",[\"widS\",\"widE\",\"t\"]]],[13,\"ra\",[1,[1,\"baseRadius\",\"*\",\"sWid\"],\"*\",[1,[5,\"1\"],\"-\",[1,\"sAge\",\"*\",\"shrink\"]]]],[13,\"rb\",[1,[1,\"baseRadius\",\"*\",\"bWid\"],\"*\",[1,[5,\"1\"],\"-\",[1,\"bAge\",\"*\",\"shrink\"]]]],[13,\"bax\",[1,\"bx\",\"-\",\"sx\"]],[13,\"bay\",[1,\"by\",\"-\",\"sy\"]],[13,\"tt\",[6,\"std.clamp\",[[1,[1,[1,[1,\"px\",\"-\",\"sx\"],\"*\",\"bax\"],\"+\",[1,[1,\"py\",\"-\",\"sy\"],\"*\",\"bay\"]],\"/\",[6,\"std.max\",[[1,[1,\"bax\",\"*\",\"bax\"],\"+\",[1,\"bay\",\"*\",\"bay\"]],[5,\"1e-8\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"dist\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,\"px\",\"-\",[1,\"sx\",\"+\",[1,\"bax\",\"*\",\"tt\"]]],[1,\"py\",\"-\",[1,\"sy\",\"+\",[1,\"bay\",\"*\",\"tt\"]]]]]]],\"-\",[6,\"std.mix\",[\"ra\",\"rb\",\"tt\"]]]],[11,[1,\"dist\",\"<\",\"jMin\"],[0,[[2,\"jMin\",\"=\",\"dist\"],[2,\"jAge\",\"=\",[6,\"std.mix\",[\"sAge\",\"bAge\",\"tt\"]]]]]],[2,\"sx\",\"=\",\"bx\"],[2,\"sy\",\"=\",\"by\"],[2,\"sAge\",\"=\",\"bAge\"],[2,\"sWid\",\"=\",\"bWid\"]]]],[2,\"minSdf\",\"=\",[6,\"std.min\",[\"minSdf\",\"jMin\"]]],[13,\"w\",[6,\"std.exp\",[[1,[1,\"jMin\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"sharp\"]]]],[2,\"ageSum\",\"=\",[1,\"ageSum\",\"+\",[1,\"jAge\",\"*\",\"w\"]]],[2,\"wSum\",\"=\",[1,\"wSum\",\"+\",\"w\"]]]],[0,[[13,\"dist\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,\"px\",\"-\",\"cx\"],[1,\"py\",\"-\",\"cy\"]]]]],\"-\",[1,[1,\"baseRadius\",\"*\",[6,\"std.abs\",[[7,\"cur\",\"w\"]]]],\"*\",[1,[5,\"1\"],\"-\",[1,[7,\"cur\",\"z\"],\"*\",\"shrink\"]]]]],[2,\"minSdf\",\"=\",[6,\"std.min\",[\"minSdf\",\"dist\"]]],[13,\"w\",[6,\"std.exp\",[[1,[1,\"dist\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"sharp\"]]]],[2,\"ageSum\",\"=\",[1,\"ageSum\",\"+\",[1,[7,\"cur\",\"z\"],\"*\",\"w\"]]],[2,\"wSum\",\"=\",[1,\"wSum\",\"+\",\"w\"]]]]]]]],[2,\"prev2\",\"=\",[6,\"d.vec4f\",[\"prev\"]]],[2,\"prev\",\"=\",[6,\"d.vec4f\",[\"cur\"]]]]]],[13,\"age\",[1,\"ageSum\",\"/\",[6,\"std.max\",[\"wSum\",[5,\"1e-20\"]]]]],[13,\"coverage\",[1,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"edgeW\",\"*\",[4,\"-\",[5,\"1\"]]],\"edgeW\",\"minSdf\"]]],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0.8\"],[5,\"1\"],\"age\"]]]]],[10,[6,\"d.vec2f\",[\"age\",\"coverage\"]]]]]},externals:{\"std.max\":()=>B,\"d.f32\":()=>n,\"d.vec4f\":()=>S,MAX_POINTS:()=>t,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"std.select\":()=>N,\"std.abs\":()=>re,SUBDIVISIONS:()=>s,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.min\":()=>ye,\"std.exp\":()=>Tt,\"std.smoothstep\":()=>be}})&&r.f)({})).$name(e.name)}var hl=e=>e;function Ms(){return{default:null,transform:hl,compileTimeWhen:(e,t)=>{let s=r=>{let o=Array.isArray(r)?r.length:0;return o>1?o:0};return s(e)!==s(t)},description:\"Multi-stop gradient colors (overrides Color A / Color B when set)\",ui:{type:\"gradient-stops\",label:\"Colors\",group:\"Colors\"}}}var _c=e=>e;function fz(e,t){let s={type:\"list\",label:t.label,group:t.group,item:e.item,maxItems:e.maxItems,minItems:e.minItems??0,itemLabel:e.itemLabel};return{default:t.default,transform:_c,description:t.description,ui:s}}function Wne(e){let t=e?.ui;return!t||t.type!==\"list\"||!t.item||typeof t.maxItems!=\"number\"?null:{item:t.item,maxItems:t.maxItems,minItems:t.minItems,itemLabel:t.itemLabel}}var tg=(e,t)=>`${e}_${t}`,sg=e=>`${e}Count`;function rg(e){return!!e&&typeof e==\"object\"&&e.type===\"mouse-position\"}var vz=(e,t,s)=>`${e}.${t}.${s}`;function FA(e){let t=/^([^.]+)\\.(\\d+)\\.([^.]+)$/.exec(e);return t?{prop:t[1],index:Number(t[2]),field:t[3]}:null}function IA(e,t,s){return(Array.isArray(e)?e.slice(0,t.maxItems):[]).map((r,o)=>{let a=r&&typeof r==\"object\"?r:{},i={};for(let[l,c]of Object.entries(t.item)){let d=a[l]===void 0||a[l]===null?c.default:a[l];i[l]=qne(c.kind,d,o,l,s)}return i})}function qne(e,t,s,r,o){switch(e){case\"position\":{if(rg(t)){let i=o.drivenPosition?.(s,r,t);return i||{x:typeof t.x==\"number\"?t.x:t.originX??.5,y:1-(typeof t.y==\"number\"?t.y:t.originY??.5)}}let a=Xe(t);return{x:a.x,y:a.y}}case\"color\":return o.color(typeof t==\"string\"?t:\"#ffffff\");case\"boolean\":return t?1:-1;default:return typeof t==\"number\"?t:0}}function Vne(e){return typeof e==\"number\"?[e,0,0,0]:Array.isArray(e)?e:[e.x,e.y,0,0]}function YA(e,t){let s={};for(let r of Object.keys(t.item)){let o=new Array(t.maxItems*4).fill(0);for(let a=0;a<Math.min(e.length,t.maxItems);a++){let i=Vne(e[a][r]);o[a*4]=i[0],o[a*4+1]=i[1],o[a*4+2]=i[2],o[a*4+3]=i[3]}s[r]=o}return{count:e.length,fields:s}}function WA(e,t){return Array.isArray(e)?e.some(s=>s&&typeof s==\"object\"&&Object.entries(t.item).some(([r,o])=>o.kind===\"position\"&&rg(s[r]))):!1}var hz=\"p3-linear\";function gz(e){hz=e;try{Aw(e)}catch{}}function Nne(e){try{let t=new va(e),s=hz===\"srgb\"?\"srgb-linear\":\"p3-linear\",r=t.to(s).coords,o=Number(t.alpha);return{r:Number.isFinite(r?.[0])?r[0]:0,g:Number.isFinite(r?.[1])?r[1]:0,b:Number.isFinite(r?.[2])?r[2]:0,a:Number.isFinite(o)?o:1}}catch{return{r:0,g:0,b:0,a:0}}}function yz(e){let{r:t,g:s,b:r,a:o}=Nne(e);return S(t,s,r,o)}function B_(e){let t=yz(e);return[t.x,t.y,t.z,t.w]}function CP(e,t){if(typeof e==\"number\")return e;if(typeof e==\"object\"&&e!==null)return e.value;let s=e.toLowerCase().trim();if(t){if(s===\"top\")return 0;if(s===\"bottom\")return 1;if(s===\"center\")return .5}else{if(s===\"left\")return 0;if(s===\"right\")return 1;if(s===\"center\")return .5}return console.warn(`Invalid position value: ${e}. Defaulting to center.`),.5}function $ne(e){let t=.5,s=.5;if(typeof e==\"string\"){let r=e.toLowerCase().trim().split(/\\s+/);r.includes(\"left\")?t=0:r.includes(\"right\")?t=1:(r.includes(\"center\")||r.length===1&&(r[0]===\"top\"||r[0]===\"bottom\"))&&(t=.5),r.includes(\"top\")?s=0:r.includes(\"bottom\")?s=1:(r.includes(\"center\")||r.length===1&&(r[0]===\"left\"||r[0]===\"right\"))&&(s=.5),r.length===1&&r[0]===\"center\"&&(t=.5,s=.5)}else typeof e==\"object\"&&e!==null?(t=CP(e.x,!1),s=CP(e.y,!0)):console.warn(`Invalid position value provided: ${e}. Defaulting to center.`);return m(t,1-s)}function bz(e){if(e)return e===ce?yz:e===Xe?$ne:e===hl?hl:e===_c?_c:e}function qA(e,t){e>0,t>0}function z_(e){return e!=null&&typeof e==\"object\"&&typeof e.value==\"number\"&&(e.unit===\"px\"||e.unit===\"uv\")}function VA(e){if(!e)return;let t;for(let[s,r]of Object.entries(e)){let o=r?.ui?.dimensional;(o===\"canvas-height\"||o===\"half-canvas-height\"||o===\"canvas-width\"||o===\"count-canvas-height\")&&(t??=new Map).set(s,o)}return t}function dp(e,t){let s=e?.propBindings,r=new Set,o=new Map;if(s)for(let a of[\"x\",\"y\",\"width\",\"height\"]){let i=s[a];i&&(i.as===\"position-x\"||i.as===\"position-y\"?r.add(i.prop):(i.as===\"canvas-height\"||i.as===\"half-canvas-height\")&&o.set(i.prop,i.as))}if(t)for(let[a,i]of t)o.set(a,i);return r.size>0||o.size>0?{positionProps:r,sizeProps:o}:null}var Xne=e=>({ox:e.includes(\"left\")?\"start\":e.includes(\"right\")?\"end\":\"center\",oy:e.includes(\"top\")?\"start\":e.includes(\"bottom\")?\"end\":\"center\"}),Hne=(e,t,s)=>t===\"start\"?e+s:t===\"end\"?e-s:e;function e_(e,t,s,r){let o=(a,i)=>z_(a)?a.unit===\"px\"?a.value:a.value*i:typeof a==\"number\"?a*i:0;return e.as===\"canvas-height\"?o(t,r):e.as===\"half-canvas-height\"?o(t,2*r):e.as===\"canvas-width\"?o(t,s):0}function NA(e,t,s,r){if(e?.computeBounds){let l=e.computeBounds(t,s,r);return{hwx:s>0?l.widthPx/s/2:0,hhy:r>0?l.heightPx/r/2:0}}let o=e?.propBindings,a=0,i=0;return o?.width&&s>0&&(a=e_(o.width,t[o.width.prop],s,r)/(2*s)),o?.height&&r>0&&(i=e_(o.height,t[o.height.prop],s,r)/(2*r)),{hwx:a,hhy:i}}function MP(e,t,s,r){let o;if(z_(e))if(e.unit===\"px\"){let a=t>0?e.value/t:0;o=s===\"end\"?1-a:s===\"center\"?.5+a:a}else o=e.value;else if(typeof e==\"number\")o=e;else return e;return Hne(o,s,r)}function jne(e,t,s,r){return e.unit!==\"px\"?e.value:t===\"canvas-width\"?s>0?e.value/s:e.value:r<=0?e.value:t===\"count-canvas-height\"?e.value>0?r/e.value:e.value:t===\"canvas-height\"?e.value/r:e.value/(2*r)}function R_(e,t,s,r,o,a,i,l){let c=dp(e,i);if(!c)return s;let{ox:d,oy:u}=Xne(r);if(c.positionProps.has(t))return!s||typeof s!=\"object\"?s:{...s,x:MP(s.x,o,d,l?.hwx??0),y:MP(s.y,a,u,l?.hhy??0)};let p=c.sizeProps.get(t);return p&&z_(s)?jne(s,p,o,a):s}function $A(e,t,s){let r=dp(e,s);return r?r.positionProps.has(t)||r.sizeProps.has(t):!1}function V0(e){let{body:t,build:s,args:r,compose:o,identity:a,missingChildMessage:i,setup:l,...c}=e;if(!t&&!s)throw new Error(`definePointwiseFilter(${e.name}): needs a body or a build`);return{...c,requiresChild:!0,fragment:u=>{if(!u.childNode)return i&&console.error(i),xt;let p=u;if(XA(a,p))return p.childNode;l?.(p);let _;if(s)_=s(p);else{let{fn:f,hint:h}=typeof t==\"function\"?t(p.propValues):t;_=W(f,h,[p.childNode,...r?.(p)??[]])}return o?o(_,p):_}}}function XA(e,t){if(!e)return!1;for(let s of e.props)if(t.getMapInfo?.(s))return!1;return e.when(t.propValues)}function EP(e){let{build:t,resultAlpha:s,identity:r,missingChildMessage:o,setup:a,...i}=e;return{...i,requiresRTT:!0,requiresChild:!0,fragment:c=>{if(!c.childNode)return o&&console.error(o),xt;let d=c.convertToTexture(c.childNode),u=f=>W(Yt,\"unpremultiplyAlpha\",[d.sample(f)]),p={...c,childNode:c.childNode,texture:d,sampleStraight:u};if(XA(r,c))return u(c.ctx.uv);a?.(p);let _=t(p);return s===\"straight\"?_:W(Yt,\"unpremultiplyAlpha\",[_])}}}function xz(e,t){return{map:(s,r)=>{let o=Px(e.map(s,r)),a=ea(s,o.uv,t(s,r));return o.coverage?{uv:a,coverage:o.coverage}:a}}}function Kne(e,t,s){return{map:(r,o)=>ea(e(r,o),t(r,o),s(r,o))}}function Px(e){return\"uv\"in e?e:{uv:e}}function Qne(e,t={}){let s=typeof e==\"function\"?e:()=>e,r=t.edges??\"prop\",o=a=>r===\"none\"?null:typeof r==\"number\"?r:a.edges??0;return{fragment:a=>{let{childNode:i,ctx:l,convertToTexture:c,propValues:d}=a;if(!i)return t.requireChildMessage&&console.error(t.requireChildMessage),xt;let u=c(i),p=o(d),_=Px(s(a).map(l.uv,l.aspect)),f=p===null?u.sample(_.uv):t.resample===\"bilinear\"?Ha(_.uv,h=>u.sample(h),p):T4(u,_.uv,p);return W(Yt,\"unpremultiplyAlpha\",[_.coverage?Ct(f.member(\"rgb\"),f.member(\"a\").mul(_.coverage)):f])},uvRemap:a=>{if(t.uvRemapIdentityWhen?.(a))return{uv:a.uv,mask:a.mask};let i=o(a.propValues),l=Px(s(a).map(a.uv,a.aspect)),c=i===null?{uv:l.uv,mask:a.mask}:_ee(l.uv,a.mask,i);return l.coverage?{uv:c.uv,mask:c.mask.mul(l.coverage)}:c}}}function fr(e,t,s){return{default:e,description:t,transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:s?.label??\"Edges\",group:s?.group??\"Effect\"}}}function zo(e,t){let s={type:\"position\",label:t?.label??\"Center\",group:t?.group??\"Position\"};return t?.units&&(s.units=[...t.units]),{default:t?.default??{x:.5,y:.5},transform:Xe,description:e,ui:s}}function Zne(){return{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}}}function Jne(e){return{softness:{default:0,description:e?.softnessDescription??\"Edge softness for antialiasing\",ui:{type:\"range\",min:0,max:.1,step:.001,label:\"Softness\",group:\"Effect\"}},strokeThickness:{default:0,description:\"Stroke thickness. Zero means no stroke.\",ui:{type:\"range\",min:0,max:e?.strokeThicknessMax??.2,step:.005,label:\"Stroke Thickness\",group:\"Stroke\"}},strokeColor:{default:\"#000000\",transform:ce,description:e?.strokeColorDescription??\"Color of the stroke outline\",ui:{type:\"color\",label:\"Stroke Color\",group:\"Colors\"}},strokePosition:{default:\"center\",transform:ww,description:e?.strokePositionDescription??\"Position of the stroke relative to the shape edge\",ui:{type:\"select\",options:[{label:\"Outside\",value:\"outside\"},{label:\"Center\",value:\"center\"},{label:\"Inside\",value:\"inside\"}],label:\"Stroke Position\",group:\"Stroke\"}}}}function eie(e){return{default:\"linear\",transform:at,compileTime:!0,description:e?.description??\"Color space for blending fill and stroke colors\",ui:{type:\"select\",options:dt,label:\"Color Blending\",group:\"Colors\"}}}function up(e,t,s){let r=s.allowNone?a=>({cover:0,contain:1,fill:2,\"scale-down\":3,none:4})[a]??0:a=>({cover:0,contain:1,fill:2,\"scale-down\":3,none:2})[a]??2,o=[{label:\"Cover\",value:\"cover\"},{label:\"Contain\",value:\"contain\"},{label:\"Fill\",value:\"fill\"},{label:\"Scale Down\",value:\"scale-down\"}];return s.allowNone&&o.push({label:\"None\",value:\"none\"}),{default:e,description:t,transform:r,compileTime:!0,ui:{type:\"select\",options:o,label:\"Object Fit\",group:\"Sizing\"}}}var tie={refraction:{default:.5,description:\"How strongly the shell bends what's seen through or inside it\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Refraction\",group:\"Glass\"}},dispersion:{default:.25,description:\"Spectral splitting at the shell \\u2014 rainbow fringes where light bends hardest\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Dispersion\",group:\"Glass\"}},thickness:{default:.2,description:\"Shell depth \\u2014 how far inward from the edge the shell's optics extend\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Thickness\",group:\"Glass\"}},environment:{default:1,description:\"Strength of the studio lighting reflected in the shell\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Environment\",group:\"Glass\"}},envRotation:{default:0,description:\"Rotates the reflected studio \\u2014 spins where the bright reflections fall\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Env Rotation\",group:\"Glass\"}},lightAngle:{default:315,description:\"Direction of the key light, in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Glass\"}},highlight:{default:1,description:\"Sharp key-light glint on the shell\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Highlight\",group:\"Highlight\"}},highlightColor:{default:\"#ffffff\",transform:ce,description:\"Color of the key-light highlight\",ui:{type:\"color\",label:\"Highlight Color\",group:\"Highlight\"}},highlightSoftness:{default:.5,description:\"Specular highlight softness \\u2014 lower is a tighter, sharper glint\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlight Softness\",group:\"Highlight\"}},fresnel:{default:.1,description:\"Fresnel rim glow \\u2014 the luminous edge where the shell turns away from view\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Fresnel\",group:\"Fresnel\"}},fresnelSoftness:{default:.1,description:\"Fresnel rim width \\u2014 higher values spread the glow further inward\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Fresnel Softness\",group:\"Fresnel\"}},fresnelColor:{default:\"#ffffff\",transform:ce,description:\"Color of the fresnel rim glow\",ui:{type:\"color\",label:\"Fresnel Color\",group:\"Fresnel\"}},edgeSoftness:{default:.05,description:\"Softness of the shape boundary edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Glass\"}}};function gr(e){let t={};for(let s of Object.keys(e)){let r=e[s];if(!r)continue;let o=tie[s];t[s]=r===!0?o:{...o,...r,ui:{...o.ui,...r.ui??{}}}}return t}function sie(e){return{default:0,description:e,ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Shape\"}}}function rie(e){return{default:\"#ffffff\",transform:ce,description:e,ui:{type:\"color\",label:\"Color\",group:\"Colors\"}}}function oie(e,t){if(e.custom)return e.custom;let s=e.size.as??\"half-canvas-height\",r={x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"},width:{prop:e.size.width,as:s},height:{prop:e.size.height,as:s}};return t&&(r.rotation={prop:\"rotation\",as:\"degrees\"}),{propBindings:r}}function aie(e,t,s){if(!t)return e;let r=Object.keys(e).filter(i=>!t.includes(i)),o=t.filter(i=>!(i in e));if(r.length||o.length)throw new Error(`defineSdfShapeShader(${s}): propOrder must list every prop exactly once (missing: ${r.join(\", \")||\"none\"}; unknown: ${o.join(\", \")||\"none\"})`);let a={};for(let i of t)a[i]=e[i];return a}function nie(e){let t=e.rotatable!==!1,s=Jne(e.stroke),r={origin:Zne(),color:rie(e.colorDescription),center:zo(e.centerDescription,{units:[\"%\",\"px\"],...e.centerLabel?{label:e.centerLabel}:{}}),...e.shapeProps,...t?{rotation:sie(e.rotationDescription??\"Rotation in degrees\")}:{},softness:s.softness,strokeThickness:s.strokeThickness,strokeColor:s.strokeColor,strokePosition:s.strokePosition,colorSpace:eie(e.colorSpaceDescription?{description:e.colorSpaceDescription}:void 0),...e.propOverrides};return{name:e.name,category:e.category??\"Shapes\",description:e.description,acceptsUVContext:!0,boundingBoxDeclaration:oie(e.bounds,t),props:aie(r,e.propOrder,e.name),fragment:o=>{let{uniforms:a,ctx:i,propValues:l}=o,c=o.uvContext??i.uv,d=l.colorSpace??0;return TB(ns(iie(e,a,c,i.aspect),\"shapeMask\"),a.color,a.strokeColor,d)}}}function iie(e,t,s,r){let o=t.rotation??ca(\"0f\"),a=ns(W(AB,\"shapeLocalCoords\",[t.center,o,s,r]),\"shapeLocal\"),i=l=>{let c=t[l];if(!c)throw new Error(`defineSdfShapeShader(${e.name}): distance reads unknown prop '${l}'`);return c};return W(wB,\"strokeMaskFromSdf\",[e.distance({x:a.member(\"x\"),y:a.member(\"y\")},i),t.softness,t.strokeThickness,t.strokePosition])}function T(e){return{kind:\"prop\",name:e}}var zi=class Cx{constructor(t){this.node=t}times(t){return new Cx({kind:\"mul\",a:this.node,b:t instanceof Cx?t.node:t})}};function Ro(e){return{uv:e.uvContext??e.ctx.uv,viewport:e.effectiveViewportSize??e.ctx.viewportSize}}function me(e,t){let s=t.uniforms[e.name];if(!s)throw new Error(`std: effect binds unknown prop '${e.name}'`);return s}function fn(e,t){let s=e instanceof zi?e.node:e;switch(s.kind){case\"prop\":return me(s,t);case\"mul\":return fn(s.a,t).mul(fn(s.b,t));case\"radialMask\":if(!t.ctx)throw new Error(\"std: radialMask needs a fragment host (warp slots have no ctx)\");return W(SJ,\"radialFalloffMask\",[t.ctx.uv,t.ctx.aspect,me(s.center,t),me(s.radius,t),me(s.falloff,t)]);case\"signal\":return s.build(t)}}function At(e,t){return Az(e,t)}function Az(e,t){if(typeof e==\"number\")return $e(e);if(e instanceof zi)return fn(e,t);switch(e.kind){case\"prop\":return me(e,t);case\"ctx\":if(!t.ctx)throw new Error(`std: ctx.${e.name} needs a fragment host (warp slots have no ctx)`);return t.ctx[e.name];default:return fn(e,t)}}function Bn(e,t,s,r){return{kind:\"pointwise\",body:{fn:e,hint:t},args:o=>s.map(a=>At(a,o)),compose:r?.compose,setup:r?.setup}}function HA(e,t,s){let r={},o=e.boundingBoxDeclaration,a=VA(e.props),i=lie(e.props,t);for(let[l,c]of Object.entries(e.props)){let d=c.transform;if(d===hl){cie(r,l,c,t[l],i);continue}if(d===_c){die(r,l,c,t[l]);continue}let u=t[l],p=u;p==null&&(p=c.default),p==null&&(console.error(`[Shaders] Uniform \"${l}\" is null/undefined after fallback. PropConfig:`,{propName:l,initialValue:u,default:c.default,hasTransform:!!d}),p=0);let _=bz(d),f=$A(o,l,a),h=!_&&!f&&(typeof p==\"string\"||typeof p==\"object\"&&p!==null&&!Array.isArray(p));r[l]={value:p,transform:_,compileTime:c.compileTime||!1,...c.compileTimeWhen?{compileTimeWhen:c.compileTimeWhen,_lastCompiledValue:u??c.default}:{},...f?{_rawDimensional:u}:{},...h?{cpu:!0}:{}}}return r}function lie(e,t){for(let[s,r]of Object.entries(e))if(r.transform===at){let o=t[s]??r.default;return typeof o==\"string\"?at(o):0}return 0}function cie(e,t,s,r,o){let a=r??null,i=J3(a,B_),l=eA(i.colors,i.stopCount,o);e[t]={value:a,transform:hl,cpu:!0,compileTime:s.compileTime||!1,...s.compileTimeWhen?{compileTimeWhen:s.compileTimeWhen,_lastCompiledValue:a??s.default}:{}},e.colorsArray={value:i.colors,schema:Fe(S,8)},e.positionsArray={value:i.positions,schema:Fe(S,8/4)},e.convertedColorsArray={value:l,schema:Fe(A,8)},e.stopCount={value:i.stopCount,schema:n}}function die(e,t,s,r){let o=Wne(s);if(!o){console.error(`[Shaders] List prop \"${t}\" has no item spec in its ui config`);return}let a=IA(r??s.default,o,{color:B_}),i=YA(a,o);e[t]={value:a,transform:_c,cpu:!0,compileTime:s.compileTime||!1,_rawList:r??s.default,_listSpec:o};for(let[l,c]of Object.entries(i.fields))e[tg(t,l)]={value:c,schema:Fe(S,o.maxItems)};e[sg(t)]={value:i.count,schema:n}}function wz(e){return Rr()?e.mobile:e.desktop}function vn(e){return wz(e)}var Ri=1024,rh={HARD:637,SOFT:255},kP=[.7548776662466927,.5698402909980532],N0=[.8191725133961645,.6710436067037893,.5497004779019703];function Di(e,t=16/9){let s=e,r=s?.dimensions?.height??0;return{dt:Math.min(Math.max(s?.deltaTime??.016,.001),.033),aspect:r>0?(s?.dimensions?.width??0)/r:t,pointerX:s?.pointer?.x??.5,pointerY:s?.pointer?.y??.5}}function Li(e){return(t,s)=>{let r=e(t);return typeof r==\"number\"?r:s}}function uie(e,t,s){return Math.min(Math.max(Math.round(e),t),s)}var wu=gt({x0:j,x1:j,y0:j,y1:j}).$name(\"SplatWindow\"),oh=w.fn([m,n,n,n],wu)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=B(r,1e-5),i=j(ie(__tsover_mul(__tsover_div(t.x,a),o))),l=j(ie(__tsover_mul(t.y,o))),c=j(nl(__tsover_div(__tsover_mul(s,o),a))),d=j(nl(__tsover_mul(s,o))),u=__tsover_sub(j(o),1);return wu({x0:B(__tsover_sub(i,c),0),x1:ye(__tsover_add(i,c),u),y0:B(__tsover_sub(l,d),0),y1:ye(__tsover_add(l,d),u)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"reach\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"res\"}],body:[0,[[13,\"asp\",[6,\"std.max\",[\"aspect\",[5,\"0.00001\"]]]],[13,\"cxi\",[6,\"d.i32\",[[6,\"std.floor\",[[1,[1,[7,\"pos\",\"x\"],\"/\",\"asp\"],\"*\",\"res\"]]]]]],[13,\"cyi\",[6,\"d.i32\",[[6,\"std.floor\",[[1,[7,\"pos\",\"y\"],\"*\",\"res\"]]]]]],[13,\"radX\",[6,\"d.i32\",[[6,\"std.ceil\",[[1,[1,\"reach\",\"*\",\"res\"],\"/\",\"asp\"]]]]]],[13,\"radY\",[6,\"d.i32\",[[6,\"std.ceil\",[[1,\"reach\",\"*\",\"res\"]]]]]],[13,\"last\",[1,[6,\"d.i32\",[\"res\"]],\"-\",[5,\"1\"]]],[10,[6,\"SplatWindow\",[[104,{x0:[6,\"std.max\",[[1,\"cxi\",\"-\",\"radX\"],[5,\"0\"]]],x1:[6,\"std.min\",[[1,\"cxi\",\"+\",\"radX\"],\"last\"]],y0:[6,\"std.max\",[[1,\"cyi\",\"-\",\"radY\"],[5,\"0\"]]],y1:[6,\"std.min\",[[1,\"cyi\",\"+\",\"radY\"],\"last\"]]}]]]]]]},externals:{\"std.max\":()=>B,\"d.i32\":()=>j,\"std.floor\":()=>ie,\"std.ceil\":()=>nl,SplatWindow:()=>wu,\"std.min\":()=>ye}})&&e.f)({})).$name(\"worldSplatWindow\"),ah=w.fn([m,j,nc],wu)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=j(ie(t.x)),a=j(ie(t.y));return wu({x0:B(__tsover_sub(o,s),0),x1:ye(__tsover_add(o,s),r.x),y0:B(__tsover_sub(a,s),0),y1:ye(__tsover_add(a,s),r.y)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"center\"},{type:\"i\",name:\"rad\"},{type:\"i\",name:\"last\"}],body:[0,[[13,\"cxi\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"center\",\"x\"]]]]]],[13,\"cyi\",[6,\"d.i32\",[[6,\"std.floor\",[[7,\"center\",\"y\"]]]]]],[10,[6,\"SplatWindow\",[[104,{x0:[6,\"std.max\",[[1,\"cxi\",\"-\",\"rad\"],[5,\"0\"]]],x1:[6,\"std.min\",[[1,\"cxi\",\"+\",\"rad\"],[7,\"last\",\"x\"]]],y0:[6,\"std.max\",[[1,\"cyi\",\"-\",\"rad\"],[5,\"0\"]]],y1:[6,\"std.min\",[[1,\"cyi\",\"+\",\"rad\"],[7,\"last\",\"y\"]]]}]]]]]]},externals:{\"d.i32\":()=>j,\"std.floor\":()=>ie,SplatWindow:()=>wu,\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})).$name(\"texelSplatWindow\"),Kl=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_sub(1,Tt(__tsover_mul(__tsover_mul(t,s),-1)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"energy\"},{type:\"i\",name:\"k\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.exp\",[[1,[1,\"energy\",\"*\",\"k\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})).$name(\"energyCoverageAlpha\"),nh=w.fn([A,A,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=t.add(s.mul(r)).mul(o),l=he(i);return i.mul(__tsover_div(ye(l,a),B(l,1e-5)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"vel\"},{type:\"i\",name:\"force\"},{type:\"i\",name:\"dt\"},{type:\"i\",name:\"dragMul\"},{type:\"i\",name:\"maxSpeed\"}],body:[0,[[13,\"v\",[6,[7,[6,[7,\"vel\",\"add\"],[[6,[7,\"force\",\"mul\"],[\"dt\"]]]],\"mul\"],[\"dragMul\"]]],[13,\"spd\",[6,\"std.length\",[\"v\"]]],[10,[6,[7,\"v\",\"mul\"],[[1,[6,\"std.min\",[\"spd\",\"maxSpeed\"]],\"/\",[6,\"std.max\",[\"spd\",[5,\"0.00001\"]]]]]]]]]},externals:{\"std.length\":()=>he,\"std.min\":()=>ye,\"std.max\":()=>B}})&&e.f)({})).$name(\"integrateSemiImplicitEuler\");function pie(e){let t=e?.storage;return!!t&&t.type===\"array\"}function mie(e){return!!e&&typeof e==\"object\"&&\"uniform\"in e}function _ie(e,t){let{gpu:s,registerComputeTexture:r,onCleanup:o}=e,a=s?.root;if(!a)return null;let{layout:i,output:l,maxAgents:c,externalKeys:d=[],extraBindGroup:u}=t,p=(globalThis.__TYPEGPU_AUTONAME__??(E=>E))(a.createTexture({size:l.size,format:l.format}).$usage(\"storage\",\"sampled\"),\"outTex\");o(()=>p.destroy());let _=(globalThis.__TYPEGPU_AUTONAME__??(E=>E))(a.createUniform(t.params),\"paramsU\"),f={[l.key]:p};for(let[E,R]of Object.entries(i.entries))pie(R)?f[E]=pr(a,R.storage.elementType,R.storage.elementCount):mie(R)&&(f[E]=_.buffer);let h=null,g={},y=()=>{for(let[E,R]of Object.entries(t.pipelines)){let U=R.kernel,L={size:R.threads===\"fixed\"?R.size:void 0,bindGroup:h},k=R.threads===\"grid\"||R.threads===\"fixed\"&&(R.size?.length??1)===2,D;if(k){let O=U;D=wr(a,(F=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(F.f=((q,Y)=>{\"use gpu\";O(q,Y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[6,\"k2\",[\"x\",\"y\"]]]]},externals:{k2:()=>O}})&&F.f)({}),L)}else{let O=U;D=wr(a,(F=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(F.f=(q=>{\"use gpu\";O(q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[6,\"k1\",[\"i\"]]]]},externals:{k1:()=>O}})&&F.f)({}),L)}R.extra&&u&&(D=D.with(u)),g[E]=D}};d.length===0&&(h=a.createBindGroup(i,f),y());let b=t.countCap?wz(t.countCap):c,x=!1,P=0,C=(E,R,U)=>{let L=g[E],k=t.pipelines[E];if(k.threads===\"fixed\")return L;if(k.threads===\"grid\"){let[O,F]=U??[1,1];return()=>L.dispatchThreads(O,F)}let D=k.threads===\"max\"?c:R;return()=>L.dispatchThreads(D)};return{outputs:{[l.name]:r(p)},writeParams:E=>_.write(E),countCap:b,resolveCount:(E,R=16)=>uie(E,R,b),pipelines:g,bindExternal:E=>{for(let R of d){if(E[R]===void 0)return;f[R]=E[R]}h=a.createBindGroup(i,f),y()},frame:E=>{if(!h)return null;let R=E?.count??b,U=[];if(t.initStep){let L=E?.reseed!==void 0&&E.reseed!==P;(!x||L)&&(x=!0,E?.reseed!==void 0&&(P=E.reseed),U.push(C(t.initStep,R,E?.grid)))}for(let L of t.program)U.push(C(L,R,E?.grid));return U}}}var Mx=Math.exp(-1),BP=1/(1-Mx),ga=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Tt(__tsover_mul(__tsover_div(t,s),-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"distSq\"},{type:\"i\",name:\"radiusSq\"}],body:[0,[[10,[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",\"radiusSq\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&e.f)({})),Ex=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return G(__tsover_mul(__tsover_sub(Tt(__tsover_mul(__tsover_div(t,s),-1)),Mx),BP),n(0),n(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"distSq\"},{type:\"i\",name:\"radiusSq\"}],body:[0,[[10,[6,\"std.clamp\",[[1,[1,[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",\"radiusSq\"],\"*\",[4,\"-\",[5,\"1\"]]]]],\"-\",\"EDGE\"],\"*\",\"INV_EDGE\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.exp\":()=>Tt,EDGE:()=>Mx,INV_EDGE:()=>BP,\"d.f32\":()=>n}})&&e.f)({}));w.fn([m,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=As(t,s);return ga(Se(o,o),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cellPos\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"radiusSq\"}],body:[0,[[13,\"off\",[6,\"std.sub\",[\"cellPos\",\"center\"]]],[10,[6,\"gaussianBrushSq\",[[6,\"std.dot\",[\"off\",\"off\"]],\"radiusSq\"]]]]]},externals:{\"std.sub\":()=>As,gaussianBrushSq:()=>ga,\"std.dot\":()=>Se}})&&e.f)({}));w.fn([m,m,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=As(t,s);return Ex(Se(o,o),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cellPos\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"radiusSq\"}],body:[0,[[13,\"off\",[6,\"std.sub\",[\"cellPos\",\"center\"]]],[10,[6,\"gaussianBrushShiftedSq\",[[6,\"std.dot\",[\"off\",\"off\"]],\"radiusSq\"]]]]]},externals:{\"std.sub\":()=>As,gaussianBrushShiftedSq:()=>Ex,\"std.dot\":()=>Se}})&&e.f)({}));var zP=new Map,RP=1;function fie(e,t){return`${e}${String(t).replace(/[^0-9A-Za-z]/g,\"_\")}`}function vie(e=RP){if(e===RP)return Ex;let t=zP.get(e);if(t)return t;let s=Math.exp(-(e*e)),r=1/(1-s),o=w.fn([n,n],n)((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";return G(__tsover_mul(__tsover_sub(Tt(__tsover_mul(__tsover_div(i,l),-1)),s),r),n(0),n(1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"distSq\"},{type:\"i\",name:\"radiusSq\"}],body:[0,[[10,[6,\"std.clamp\",[[1,[1,[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",\"radiusSq\"],\"*\",[4,\"-\",[5,\"1\"]]]]],\"-\",\"edge\"],\"*\",\"invEdge\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.exp\":()=>Tt,edge:()=>s,invEdge:()=>r,\"d.f32\":()=>n}})&&a.f)({})).$name(fie(\"gaussianBrushShiftedSq\",e));return zP.set(e,o),o}function hie(e){return e.edgeShift?vie(e.cutoffSigmas):ga}function Tz(e,t){let{n:s,namePrefix:r}=t;return w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=e.$.sparams,c=__tsover_add(__tsover_mul(i,M(s)),a),d=__tsover_add(n(a),.5),u=__tsover_add(n(i),.5),p=__tsover_sub(d,l.posX),_=__tsover_sub(u,l.posY),f=ga(__tsover_add(__tsover_mul(p,p),__tsover_mul(_,_)),B(__tsover_mul(l.radius,l.radius),n(1))),h=e.$.velA[c];e.$.velA[c]=S(__tsover_add(h.x,__tsover_mul(l.velX,f)),__tsover_add(h.y,__tsover_mul(l.velY,f)),h.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"sparams\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dx\",[1,\"cellX\",\"-\",[7,\"p\",\"posX\"]]],[13,\"dy\",[1,\"cellY\",\"-\",[7,\"p\",\"posY\"]]],[13,\"distSq\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[13,\"radSq\",[6,\"std.max\",[[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"inf\",[6,\"gaussianBrushSq\",[\"distSq\",\"radSq\"]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"vel\",\"x\"],\"+\",[1,[7,\"p\",\"velX\"],\"*\",\"inf\"]],[1,[7,\"vel\",\"y\"],\"+\",[1,[7,\"p\",\"velY\"],\"*\",\"inf\"]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,n:()=>s,\"d.f32\":()=>n,\"std.max\":()=>B,gaussianBrushSq:()=>ga,\"d.vec4f\":()=>S}})&&o.f)({})).$name(`${r}Force`)}function Sz(e,t){let{n:s,namePrefix:r,colorSpace:o}=t,a=Bd[o]??hc,i=hie(t.brush??{edgeShift:!1});return w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";let u=e.$.sparams,p=__tsover_add(__tsover_mul(d,M(s)),c),_=__tsover_add(n(c),.5),f=__tsover_add(n(d),.5),h=__tsover_sub(_,u.posX),g=__tsover_sub(f,u.posY),y=i(__tsover_add(__tsover_mul(h,h),__tsover_mul(g,g)),B(__tsover_mul(u.radius,u.radius),n(1))),b=G(__tsover_mul(y,u.strength),n(0),n(1)),x=a(A(u.colR,u.colG,u.colB),A(u.col2R,u.col2G,u.col2B),1,1,u.mixT),P=e.$.dyeA[p];e.$.dyeA[p]=S(K(P.x,x.x,b),K(P.y,x.y,b),K(P.z,x.z,b),0);let C=e.$.velA[p];e.$.velA[p]=S(__tsover_add(C.x,__tsover_mul(u.velX,y)),__tsover_add(C.y,__tsover_mul(u.velY,y)),C.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"sparams\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dx\",[1,\"cellX\",\"-\",[7,\"p\",\"posX\"]]],[13,\"dy\",[1,\"cellY\",\"-\",[7,\"p\",\"posY\"]]],[13,\"distSq\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[13,\"radSq\",[6,\"std.max\",[[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"inf\",[6,\"brushWeight\",[\"distSq\",\"radSq\"]]],[13,\"w\",[6,\"std.clamp\",[[1,\"inf\",\"*\",[7,\"p\",\"strength\"]],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"brush\",[6,\"mixFn\",[[6,\"d.vec3f\",[[7,\"p\",\"colR\"],[7,\"p\",\"colG\"],[7,\"p\",\"colB\"]]],[6,\"d.vec3f\",[[7,\"p\",\"col2R\"],[7,\"p\",\"col2G\"],[7,\"p\",\"col2B\"]]],[5,\"1\"],[5,\"1\"],[7,\"p\",\"mixT\"]]]],[13,\"cell\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.mix\",[[7,\"cell\",\"x\"],[7,\"brush\",\"x\"],\"w\"]],[6,\"std.mix\",[[7,\"cell\",\"y\"],[7,\"brush\",\"y\"],\"w\"]],[6,\"std.mix\",[[7,\"cell\",\"z\"],[7,\"brush\",\"z\"],\"w\"]],[5,\"0\"]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"vel\",\"x\"],\"+\",[1,[7,\"p\",\"velX\"],\"*\",\"inf\"]],[1,[7,\"vel\",\"y\"],\"+\",[1,[7,\"p\",\"velY\"],\"*\",\"inf\"]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,n:()=>s,\"d.f32\":()=>n,\"std.max\":()=>B,brushWeight:()=>i,\"std.clamp\":()=>G,mixFn:()=>a,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&l.f)({})).$name(`${r}Splat${o}`)}function pp(e,t){let s=e,{n:r,namePrefix:o,densityGain:a,velocityBlendGain:i}=t,l=t.masked??!1,c=t.gated??!1,d=r*.08;if(c&&(t.cone||t.cursorPush||l))throw new Error(`buildEmitterSplatKernel: 'gated' is the cursor-puff shape \\u2014 it does not combine with cone/cursorPush/masked (got cone=${t.cone}, cursorPush=${t.cursorPush}, masked=${l})`);if(!c&&(!t.cone||!t.cursorPush))throw new Error(`buildEmitterSplatKernel: the fixed-source shape ships as cone+cursorPush \\u2014 pass both (got cone=${t.cone}, cursorPush=${t.cursorPush})`);return c?w.fn([M,M])((u=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(u.f=((p,_)=>{\"use gpu\";let f=s.$.params,h=__tsover_add(__tsover_mul(_,M(r)),p),g=__tsover_add(n(p),.5),y=__tsover_add(n(_),.5),b=__tsover_sub(g,f.emitX),x=__tsover_sub(y,f.emitY),P=__tsover_add(__tsover_mul(b,b),__tsover_mul(x,x)),C=B(__tsover_mul(f.emitRad,f.emitRad),n(1)),E=__tsover_mul(ga(P,C),f.emitGate),R=s.$.dyeA[h],U=R.x,L=__tsover_mul(__tsover_mul(__tsover_mul(f.emitIntensity,E),f.dt),a),k=ye(__tsover_add(U,L),1),D=__tsover_div(L,B(k,n(.001)));s.$.dyeA[h]=S(k,__tsover_mul(R.y,__tsover_sub(1,ye(D,1))),0,0);let O=s.$.velA[h],F=ye(__tsover_mul(__tsover_mul(E,f.dt),i),1),q=__tsover_mul(__tsover_mul(__tsover_mul(f.gravity,U),f.dt),d);s.$.velA[h]=S(K(O.x,f.emitVelX,F),__tsover_add(K(O.y,f.emitVelY,F),q),O.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dx\",[1,\"cellX\",\"-\",[7,\"p\",\"emitX\"]]],[13,\"dy\",[1,\"cellY\",\"-\",[7,\"p\",\"emitY\"]]],[13,\"distSq\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[13,\"radSq\",[6,\"std.max\",[[1,[7,\"p\",\"emitRad\"],\"*\",[7,\"p\",\"emitRad\"]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"influence\",[1,[6,\"gaussianBrushSq\",[\"distSq\",\"radSq\"]],\"*\",[7,\"p\",\"emitGate\"]]],[13,\"cell\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[13,\"oldDens\",[7,\"cell\",\"x\"]],[13,\"addDens\",[1,[1,[1,[7,\"p\",\"emitIntensity\"],\"*\",\"influence\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"densityGain\"]],[13,\"newDens\",[6,\"std.min\",[[1,\"oldDens\",\"+\",\"addDens\"],[5,\"1\"]]]],[13,\"rejuvenate\",[1,\"addDens\",\"/\",[6,\"std.max\",[\"newDens\",[6,\"d.f32\",[[5,\"0.001\"]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"newDens\",[1,[7,\"cell\",\"y\"],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.min\",[\"rejuvenate\",[5,\"1\"]]]]],[5,\"0\"],[5,\"0\"]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"br\",[6,\"std.min\",[[1,[1,\"influence\",\"*\",[7,\"p\",\"dt\"]],\"*\",\"velocityBlendGain\"],[5,\"1\"]]]],[13,\"gravForce\",[1,[1,[1,[7,\"p\",\"gravity\"],\"*\",\"oldDens\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"gravityGain\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.mix\",[[7,\"vel\",\"x\"],[7,\"p\",\"emitVelX\"],\"br\"]],[1,[6,\"std.mix\",[[7,\"vel\",\"y\"],[7,\"p\",\"emitVelY\"],\"br\"]],\"+\",\"gravForce\"],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,\"std.max\":()=>B,gaussianBrushSq:()=>ga,densityGain:()=>a,\"std.min\":()=>ye,\"d.vec4f\":()=>S,velocityBlendGain:()=>i,gravityGain:()=>d,\"std.mix\":()=>K}})&&u.f)({})).$name(`${o}Splat`):l?w.fn([M,M])((u=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(u.f=((p,_)=>{\"use gpu\";let f=s.$.params,h=__tsover_add(__tsover_mul(_,M(r)),p),g=s.$.maskBuf[h].x,y=__tsover_add(n(p),.5),b=__tsover_add(n(_),.5),x=__tsover_sub(y,f.emitX),P=__tsover_sub(b,f.emitY),C=__tsover_add(__tsover_mul(x,x),__tsover_mul(P,P)),E=B(__tsover_mul(f.emitRad,f.emitRad),n(1)),R=__tsover_mul(ga(C,E),g),U=s.$.dyeA[h],L=U.x,k=__tsover_mul(__tsover_mul(__tsover_mul(f.emitIntensity,R),f.dt),a),D=ye(__tsover_add(L,k),1),O=__tsover_div(k,B(D,n(.001)));s.$.dyeA[h]=S(D,__tsover_mul(U.y,__tsover_sub(1,ye(O,1))),0,0);let F=s.$.velA[h],q=__tsover_div(__tsover_add(__tsover_mul(x,f.perpDirX),__tsover_mul(P,f.perpDirY)),B(f.emitRad,n(1))),Y=B(__tsover_add(__tsover_mul(f.emitVelX,f.emitVelX),__tsover_mul(f.emitVelY,f.emitVelY)),n(1)),V=__tsover_add(f.emitVelX,__tsover_mul(__tsover_mul(__tsover_mul(f.perpDirX,q),f.spreadFactor),Ue(Y))),X=__tsover_add(f.emitVelY,__tsover_mul(__tsover_mul(__tsover_mul(f.perpDirY,q),f.spreadFactor),Ue(Y))),Q=ye(__tsover_mul(__tsover_mul(R,f.dt),i),1),te=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(f.gravity,L),f.dt),d),g),J=__tsover_sub(y,f.cursorX),oe=__tsover_sub(b,f.cursorY),le=__tsover_add(__tsover_mul(J,J),__tsover_mul(oe,oe)),se=__tsover_mul(__tsover_mul(ga(le,B(f.mouseRadSq,n(1))),f.mouseActive),g);s.$.velA[h]=S(__tsover_add(K(F.x,V,Q),__tsover_mul(f.cursorVelX,se)),__tsover_add(__tsover_add(K(F.y,X,Q),te),__tsover_mul(f.cursorVelY,se)),F.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"mask\",[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],\"idx\"],\"x\"]],[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dx\",[1,\"cellX\",\"-\",[7,\"p\",\"emitX\"]]],[13,\"dy\",[1,\"cellY\",\"-\",[7,\"p\",\"emitY\"]]],[13,\"distSq\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[13,\"radSq\",[6,\"std.max\",[[1,[7,\"p\",\"emitRad\"],\"*\",[7,\"p\",\"emitRad\"]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"influence\",[1,[6,\"gaussianBrushSq\",[\"distSq\",\"radSq\"]],\"*\",\"mask\"]],[13,\"cell\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[13,\"oldDens\",[7,\"cell\",\"x\"]],[13,\"addDens\",[1,[1,[1,[7,\"p\",\"emitIntensity\"],\"*\",\"influence\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"densityGain\"]],[13,\"newDens\",[6,\"std.min\",[[1,\"oldDens\",\"+\",\"addDens\"],[5,\"1\"]]]],[13,\"rejuvenate\",[1,\"addDens\",\"/\",[6,\"std.max\",[\"newDens\",[6,\"d.f32\",[[5,\"0.001\"]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"newDens\",[1,[7,\"cell\",\"y\"],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.min\",[\"rejuvenate\",[5,\"1\"]]]]],[5,\"0\"],[5,\"0\"]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"perpOff\",[1,[1,[1,\"dx\",\"*\",[7,\"p\",\"perpDirX\"]],\"+\",[1,\"dy\",\"*\",[7,\"p\",\"perpDirY\"]]],\"/\",[6,\"std.max\",[[7,\"p\",\"emitRad\"],[6,\"d.f32\",[[5,\"1\"]]]]]]],[13,\"vmSq\",[6,\"std.max\",[[1,[1,[7,\"p\",\"emitVelX\"],\"*\",[7,\"p\",\"emitVelX\"]],\"+\",[1,[7,\"p\",\"emitVelY\"],\"*\",[7,\"p\",\"emitVelY\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"tvx\",[1,[7,\"p\",\"emitVelX\"],\"+\",[1,[1,[1,[7,\"p\",\"perpDirX\"],\"*\",\"perpOff\"],\"*\",[7,\"p\",\"spreadFactor\"]],\"*\",[6,\"std.sqrt\",[\"vmSq\"]]]]],[13,\"tvy\",[1,[7,\"p\",\"emitVelY\"],\"+\",[1,[1,[1,[7,\"p\",\"perpDirY\"],\"*\",\"perpOff\"],\"*\",[7,\"p\",\"spreadFactor\"]],\"*\",[6,\"std.sqrt\",[\"vmSq\"]]]]],[13,\"br\",[6,\"std.min\",[[1,[1,\"influence\",\"*\",[7,\"p\",\"dt\"]],\"*\",\"velocityBlendGain\"],[5,\"1\"]]]],[13,\"gravForce\",[1,[1,[1,[1,[7,\"p\",\"gravity\"],\"*\",\"oldDens\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"gravityGain\"],\"*\",\"mask\"]],[13,\"cursorDX\",[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]]],[13,\"cursorDY\",[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]]],[13,\"cursorDistSq\",[1,[1,\"cursorDX\",\"*\",\"cursorDX\"],\"+\",[1,\"cursorDY\",\"*\",\"cursorDY\"]]],[13,\"cursorInf\",[1,[1,[6,\"gaussianBrushSq\",[\"cursorDistSq\",[6,\"std.max\",[[7,\"p\",\"mouseRadSq\"],[6,\"d.f32\",[[5,\"1\"]]]]]]],\"*\",[7,\"p\",\"mouseActive\"]],\"*\",\"mask\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[6,\"std.mix\",[[7,\"vel\",\"x\"],\"tvx\",\"br\"]],\"+\",[1,[7,\"p\",\"cursorVelX\"],\"*\",\"cursorInf\"]],[1,[1,[6,\"std.mix\",[[7,\"vel\",\"y\"],\"tvy\",\"br\"]],\"+\",\"gravForce\"],\"+\",[1,[7,\"p\",\"cursorVelY\"],\"*\",\"cursorInf\"]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,\"std.max\":()=>B,gaussianBrushSq:()=>ga,densityGain:()=>a,\"std.min\":()=>ye,\"d.vec4f\":()=>S,\"std.sqrt\":()=>Ue,velocityBlendGain:()=>i,gravityGain:()=>d,\"std.mix\":()=>K}})&&u.f)({})).$name(`${o}Splat`):w.fn([M,M])((u=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(u.f=((p,_)=>{\"use gpu\";let f=s.$.params,h=__tsover_add(__tsover_mul(_,M(r)),p),g=__tsover_add(n(p),.5),y=__tsover_add(n(_),.5),b=__tsover_sub(g,f.emitX),x=__tsover_sub(y,f.emitY),P=ga(__tsover_add(__tsover_mul(b,b),__tsover_mul(x,x)),B(__tsover_mul(f.emitRad,f.emitRad),n(1))),C=s.$.dyeA[h],E=C.x,R=__tsover_mul(__tsover_mul(__tsover_mul(f.emitIntensity,P),f.dt),a),U=ye(__tsover_add(E,R),1),L=__tsover_div(R,B(U,n(.001)));s.$.dyeA[h]=S(U,__tsover_mul(C.y,__tsover_sub(1,ye(L,1))),0,0);let k=s.$.velA[h],D=__tsover_div(__tsover_add(__tsover_mul(b,f.perpDirX),__tsover_mul(x,f.perpDirY)),B(f.emitRad,n(1))),O=B(__tsover_add(__tsover_mul(f.emitVelX,f.emitVelX),__tsover_mul(f.emitVelY,f.emitVelY)),n(1)),F=__tsover_add(f.emitVelX,__tsover_mul(__tsover_mul(__tsover_mul(f.perpDirX,D),f.spreadFactor),Ue(O))),q=__tsover_add(f.emitVelY,__tsover_mul(__tsover_mul(__tsover_mul(f.perpDirY,D),f.spreadFactor),Ue(O))),Y=ye(__tsover_mul(__tsover_mul(P,f.dt),i),1),V=__tsover_mul(__tsover_mul(__tsover_mul(f.gravity,E),f.dt),d),X=__tsover_sub(g,f.cursorX),Q=__tsover_sub(y,f.cursorY),te=__tsover_add(__tsover_mul(X,X),__tsover_mul(Q,Q)),J=__tsover_mul(ga(te,B(f.mouseRadSq,n(1))),f.mouseActive);s.$.velA[h]=S(__tsover_add(K(k.x,F,Y),__tsover_mul(f.cursorVelX,J)),__tsover_add(__tsover_add(K(k.y,q,Y),V),__tsover_mul(f.cursorVelY,J)),k.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dx\",[1,\"cellX\",\"-\",[7,\"p\",\"emitX\"]]],[13,\"dy\",[1,\"cellY\",\"-\",[7,\"p\",\"emitY\"]]],[13,\"distSq\",[1,[1,\"dx\",\"*\",\"dx\"],\"+\",[1,\"dy\",\"*\",\"dy\"]]],[13,\"radSq\",[6,\"std.max\",[[1,[7,\"p\",\"emitRad\"],\"*\",[7,\"p\",\"emitRad\"]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"influence\",[6,\"gaussianBrushSq\",[\"distSq\",\"radSq\"]]],[13,\"cell\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[13,\"oldDens\",[7,\"cell\",\"x\"]],[13,\"addDens\",[1,[1,[1,[7,\"p\",\"emitIntensity\"],\"*\",\"influence\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"densityGain\"]],[13,\"newDens\",[6,\"std.min\",[[1,\"oldDens\",\"+\",\"addDens\"],[5,\"1\"]]]],[13,\"rejuvenate\",[1,\"addDens\",\"/\",[6,\"std.max\",[\"newDens\",[6,\"d.f32\",[[5,\"0.001\"]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"newDens\",[1,[7,\"cell\",\"y\"],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.min\",[\"rejuvenate\",[5,\"1\"]]]]],[5,\"0\"],[5,\"0\"]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"perpOff\",[1,[1,[1,\"dx\",\"*\",[7,\"p\",\"perpDirX\"]],\"+\",[1,\"dy\",\"*\",[7,\"p\",\"perpDirY\"]]],\"/\",[6,\"std.max\",[[7,\"p\",\"emitRad\"],[6,\"d.f32\",[[5,\"1\"]]]]]]],[13,\"vmSq\",[6,\"std.max\",[[1,[1,[7,\"p\",\"emitVelX\"],\"*\",[7,\"p\",\"emitVelX\"]],\"+\",[1,[7,\"p\",\"emitVelY\"],\"*\",[7,\"p\",\"emitVelY\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"tvx\",[1,[7,\"p\",\"emitVelX\"],\"+\",[1,[1,[1,[7,\"p\",\"perpDirX\"],\"*\",\"perpOff\"],\"*\",[7,\"p\",\"spreadFactor\"]],\"*\",[6,\"std.sqrt\",[\"vmSq\"]]]]],[13,\"tvy\",[1,[7,\"p\",\"emitVelY\"],\"+\",[1,[1,[1,[7,\"p\",\"perpDirY\"],\"*\",\"perpOff\"],\"*\",[7,\"p\",\"spreadFactor\"]],\"*\",[6,\"std.sqrt\",[\"vmSq\"]]]]],[13,\"br\",[6,\"std.min\",[[1,[1,\"influence\",\"*\",[7,\"p\",\"dt\"]],\"*\",\"velocityBlendGain\"],[5,\"1\"]]]],[13,\"gravForce\",[1,[1,[1,[7,\"p\",\"gravity\"],\"*\",\"oldDens\"],\"*\",[7,\"p\",\"dt\"]],\"*\",\"gravityGain\"]],[13,\"cursorDX\",[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]]],[13,\"cursorDY\",[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]]],[13,\"cursorDistSq\",[1,[1,\"cursorDX\",\"*\",\"cursorDX\"],\"+\",[1,\"cursorDY\",\"*\",\"cursorDY\"]]],[13,\"cursorInf\",[1,[6,\"gaussianBrushSq\",[\"cursorDistSq\",[6,\"std.max\",[[7,\"p\",\"mouseRadSq\"],[6,\"d.f32\",[[5,\"1\"]]]]]]],\"*\",[7,\"p\",\"mouseActive\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[6,\"std.mix\",[[7,\"vel\",\"x\"],\"tvx\",\"br\"]],\"+\",[1,[7,\"p\",\"cursorVelX\"],\"*\",\"cursorInf\"]],[1,[1,[6,\"std.mix\",[[7,\"vel\",\"y\"],\"tvy\",\"br\"]],\"+\",\"gravForce\"],\"+\",[1,[7,\"p\",\"cursorVelY\"],\"*\",\"cursorInf\"]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,\"std.max\":()=>B,gaussianBrushSq:()=>ga,densityGain:()=>a,\"std.min\":()=>ye,\"d.vec4f\":()=>S,\"std.sqrt\":()=>Ue,velocityBlendGain:()=>i,gravityGain:()=>d,\"std.mix\":()=>K}})&&u.f)({})).$name(`${o}Splat`)}var DP=new Map;function gie(e,t){return t===\"toroidal\"?w.fn([j,j,j,j],M)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o,a,i)=>{\"use gpu\";let l=__tsover_mod(__tsover_add(__tsover_add(r,a),e),e),c=__tsover_mod(__tsover_add(__tsover_add(o,i),e),e);return M(__tsover_add(__tsover_mul(l,e),c))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ii\"},{type:\"i\",name:\"ji\"},{type:\"i\",name:\"di\"},{type:\"i\",name:\"dj\"}],body:[0,[[13,\"row\",[1,[1,[1,\"ii\",\"+\",\"di\"],\"+\",\"n\"],\"%\",\"n\"]],[13,\"col\",[1,[1,[1,\"ji\",\"+\",\"dj\"],\"+\",\"n\"],\"%\",\"n\"]],[10,[6,\"d.u32\",[[1,[1,\"row\",\"*\",\"n\"],\"+\",\"col\"]]]]]]},externals:{n:()=>e,\"d.u32\":()=>M}})&&s.f)({})).$name(\"nw\"):w.fn([j,j,j,j],M)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o,a,i)=>{\"use gpu\";let l=G(__tsover_add(r,a),0,__tsover_sub(e,1)),c=G(__tsover_add(o,i),0,__tsover_sub(e,1));return M(__tsover_add(__tsover_mul(l,e),c))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ii\"},{type:\"i\",name:\"ji\"},{type:\"i\",name:\"di\"},{type:\"i\",name:\"dj\"}],body:[0,[[13,\"row\",[6,\"std.clamp\",[[1,\"ii\",\"+\",\"di\"],[5,\"0\"],[1,\"n\",\"-\",[5,\"1\"]]]]],[13,\"col\",[6,\"std.clamp\",[[1,\"ji\",\"+\",\"dj\"],[5,\"0\"],[1,\"n\",\"-\",[5,\"1\"]]]]],[10,[6,\"d.u32\",[[1,[1,\"row\",\"*\",\"n\"],\"+\",\"col\"]]]]]]},externals:{\"std.clamp\":()=>G,n:()=>e,\"d.u32\":()=>M}})&&s.f)({})).$name(\"nidx\")}function yie(e,t){let s=`${e}:${t}`,r=DP.get(s);if(r)return r;let o=gie(e,t);return DP.set(s,o),o}function zn(e,t){let s=e,{n:r,namePrefix:o,boundary:a,dye:i}=t,l=yie(r,a),c=t.pressureDecay??.8,d=a===\"toroidal\",u=i===\"rgb\"?\"Dye\":\"Dens\";if(i===\"densityAge\"&&(t.dyeDissipation??!1)!==(t.ageAdvance??!1))throw new Error(`buildStableFluidsKernels: dye 'densityAge' supports dyeDissipation and ageAdvance only together or not at all (got dyeDissipation=${t.dyeDissipation??!1}, ageAdvance=${t.ageAdvance??!1})`);if(t.solidMask&&d)throw new Error(\"buildStableFluidsKernels: solidMask requires boundary 'clamped' \\u2014 a toroidal field with interior walls is not supported (the masked divergence pass assumes clamped edges)\");let p=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=s.$.velA[l(D,O,0,-1)],q=s.$.velA[l(D,O,0,1)],Y=s.$.velA[l(D,O,-1,0)],V=s.$.velA[l(D,O,1,0)],X=__tsover_mul(__tsover_sub(__tsover_sub(q.y,F.y),__tsover_sub(V.x,Y.x)),.5),Q=s.$.velA[k];s.$.velA[k]=S(Q.x,Q.y,X,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"vL\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]]],[13,\"vR\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]]],[13,\"vU\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]]],[13,\"vD\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]]],[13,\"curlZ\",[1,[1,[1,[7,\"vR\",\"y\"],\"-\",[7,\"vL\",\"y\"]],\"-\",[1,[7,\"vD\",\"x\"],\"-\",[7,\"vU\",\"x\"]]],\"*\",[5,\"0.5\"]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"vel\",\"x\"],[7,\"vel\",\"y\"],\"curlZ\",[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,layout:()=>s,nb:()=>l,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}Curl`),_=t.ambientWind?.gain??0,f=t.ambientWind?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=j(L),F=j(U),q=re(s.$.velA[l(O,F,0,-1)].z),Y=re(s.$.velA[l(O,F,0,1)].z),V=re(s.$.velA[l(O,F,-1,0)].z),X=re(s.$.velA[l(O,F,1,0)].z),Q=s.$.velA[D].z,te=__tsover_mul(__tsover_sub(Y,q),.5),J=__tsover_mul(__tsover_sub(X,V),.5),oe=B(Ue(__tsover_add(__tsover_mul(te,te),__tsover_mul(J,J))),n(1e-5)),le=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_div(J,oe),Q),k.curlStrength),k.dt),se=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_div(te,oe),-1),Q),k.curlStrength),k.dt),Te=n(0),de=n(0);if(k.ambient>0){let Ae=__tsover_div(__tsover_add(n(U),.5),n(r)),De=__tsover_div(__tsover_add(n(L),.5),n(r)),Ee=sv(m(__tsover_mul(Ae,k.ambientFreq),__tsover_mul(De,k.ambientFreq)),k.ambientTime),ze=__tsover_mul(__tsover_mul(k.ambient,_),k.dt);Te=__tsover_mul(Ee.x,ze),de=__tsover_mul(Ee.y,ze)}let xe=s.$.velA[D];s.$.velA[D]=S(__tsover_add(__tsover_add(xe.x,le),Te),__tsover_add(__tsover_add(xe.y,se),de),xe.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"cL\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"z\"]]]],[13,\"cR\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"z\"]]]],[13,\"cU\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"z\"]]]],[13,\"cD\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"z\"]]]],[13,\"cc\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"z\"]],[13,\"gx\",[1,[1,\"cR\",\"-\",\"cL\"],\"*\",[5,\"0.5\"]]],[13,\"gy\",[1,[1,\"cD\",\"-\",\"cU\"],\"*\",[5,\"0.5\"]]],[13,\"gl\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"gx\",\"*\",\"gx\"],\"+\",[1,\"gy\",\"*\",\"gy\"]]]],[6,\"d.f32\",[[5,\"0.00001\"]]]]]],[13,\"fx\",[1,[1,[1,[1,\"gy\",\"/\",\"gl\"],\"*\",\"cc\"],\"*\",[7,\"p\",\"curlStrength\"]],\"*\",[7,\"p\",\"dt\"]]],[13,\"fy\",[1,[1,[1,[1,[1,\"gx\",\"/\",\"gl\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"cc\"],\"*\",[7,\"p\",\"curlStrength\"]],\"*\",[7,\"p\",\"dt\"]]],[12,\"ax\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"ay\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,[7,\"p\",\"ambient\"],\">\",[5,\"0\"]],[0,[[13,\"uvx\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"uvy\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"amb\",[6,\"noise.curl22z\",[[6,\"d.vec2f\",[[1,\"uvx\",\"*\",[7,\"p\",\"ambientFreq\"]],[1,\"uvy\",\"*\",[7,\"p\",\"ambientFreq\"]]]],[7,\"p\",\"ambientTime\"]]]],[13,\"af\",[1,[1,[7,\"p\",\"ambient\"],\"*\",\"ambientGain\"],\"*\",[7,\"p\",\"dt\"]]],[2,\"ax\",\"=\",[1,[7,\"amb\",\"x\"],\"*\",\"af\"]],[2,\"ay\",\"=\",[1,[7,\"amb\",\"y\"],\"*\",\"af\"]]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[1,[7,\"vel\",\"x\"],\"+\",\"fx\"],\"+\",\"ax\"],[1,[1,[7,\"vel\",\"y\"],\"+\",\"fy\"],\"+\",\"ay\"],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,\"std.abs\":()=>re,nb:()=>l,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"d.f32\":()=>n,\"noise.curl22z\":()=>sv,\"d.vec2f\":()=>m,ambientGain:()=>_,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}Vorticity`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=j(L),F=j(U),q=re(s.$.velA[l(O,F,0,-1)].z),Y=re(s.$.velA[l(O,F,0,1)].z),V=re(s.$.velA[l(O,F,-1,0)].z),X=re(s.$.velA[l(O,F,1,0)].z),Q=s.$.velA[D].z,te=__tsover_mul(__tsover_sub(Y,q),.5),J=__tsover_mul(__tsover_sub(X,V),.5),oe=B(Ue(__tsover_add(__tsover_mul(te,te),__tsover_mul(J,J))),n(1e-5)),le=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_div(J,oe),Q),k.curlStrength),k.dt),se=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_div(te,oe),-1),Q),k.curlStrength),k.dt),Te=s.$.velA[D];s.$.velA[D]=S(__tsover_add(Te.x,le),__tsover_add(Te.y,se),Te.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"cL\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"z\"]]]],[13,\"cR\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"z\"]]]],[13,\"cU\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"z\"]]]],[13,\"cD\",[6,\"std.abs\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"z\"]]]],[13,\"cc\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"z\"]],[13,\"gx\",[1,[1,\"cR\",\"-\",\"cL\"],\"*\",[5,\"0.5\"]]],[13,\"gy\",[1,[1,\"cD\",\"-\",\"cU\"],\"*\",[5,\"0.5\"]]],[13,\"gl\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"gx\",\"*\",\"gx\"],\"+\",[1,\"gy\",\"*\",\"gy\"]]]],[6,\"d.f32\",[[5,\"0.00001\"]]]]]],[13,\"fx\",[1,[1,[1,[1,\"gy\",\"/\",\"gl\"],\"*\",\"cc\"],\"*\",[7,\"p\",\"curlStrength\"]],\"*\",[7,\"p\",\"dt\"]]],[13,\"fy\",[1,[1,[1,[1,[1,\"gx\",\"/\",\"gl\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"cc\"],\"*\",[7,\"p\",\"curlStrength\"]],\"*\",[7,\"p\",\"dt\"]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"vel\",\"x\"],\"+\",\"fx\"],[1,[7,\"vel\",\"y\"],\"+\",\"fy\"],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,\"std.abs\":()=>re,nb:()=>l,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"d.f32\":()=>n,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}Vorticity`),h=t.solidMask?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=n(U),q=n(L),Y=s.$.maskBuf[k].x,V=s.$.velA[k],X=F<.5||s.$.maskBuf[l(D,O,0,-1)].x<.5,Q=F>n(__tsover_sub(r,1.5))||s.$.maskBuf[l(D,O,0,1)].x<.5,te=q<.5||s.$.maskBuf[l(D,O,-1,0)].x<.5,J=q>n(__tsover_sub(r,1.5))||s.$.maskBuf[l(D,O,1,0)].x<.5,oe=N(s.$.velA[l(D,O,0,-1)].x,__tsover_mul(V.x,-1),X),le=N(s.$.velA[l(D,O,0,1)].x,__tsover_mul(V.x,-1),Q),se=N(s.$.velA[l(D,O,-1,0)].y,__tsover_mul(V.y,-1),te),Te=N(s.$.velA[l(D,O,1,0)].y,__tsover_mul(V.y,-1),J),de=__tsover_mul(__tsover_mul(__tsover_add(__tsover_sub(le,oe),__tsover_sub(Te,se)),.5),Y);s.$.pressure[k]=__tsover_mul(__tsover_mul(s.$.pressure[k],c),Y),s.$.divergence[k]=de}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"jf\",[6,\"d.f32\",[\"cx\"]]],[13,\"iF\",[6,\"d.f32\",[\"cy\"]]],[13,\"selfMask\",[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],\"idx\"],\"x\"]],[13,\"selfVel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"isWallL\",[3,[1,\"jf\",\"<\",[5,\"0.5\"]],\"||\",[1,[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"x\"],\"<\",[5,\"0.5\"]]]],[13,\"isWallR\",[3,[1,\"jf\",\">\",[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1.5\"]]]]],\"||\",[1,[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"x\"],\"<\",[5,\"0.5\"]]]],[13,\"isWallT\",[3,[1,\"iF\",\"<\",[5,\"0.5\"]],\"||\",[1,[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"x\"],\"<\",[5,\"0.5\"]]]],[13,\"isWallB\",[3,[1,\"iF\",\">\",[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1.5\"]]]]],\"||\",[1,[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"x\"],\"<\",[5,\"0.5\"]]]],[13,\"L\",[6,\"std.select\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"x\"],[1,[7,\"selfVel\",\"x\"],\"*\",[4,\"-\",[5,\"1\"]]],\"isWallL\"]]],[13,\"R\",[6,\"std.select\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"x\"],[1,[7,\"selfVel\",\"x\"],\"*\",[4,\"-\",[5,\"1\"]]],\"isWallR\"]]],[13,\"T\",[6,\"std.select\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"y\"],[1,[7,\"selfVel\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],\"isWallT\"]]],[13,\"B\",[6,\"std.select\",[[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"y\"],[1,[7,\"selfVel\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],\"isWallB\"]]],[13,\"div\",[1,[1,[1,[1,\"R\",\"-\",\"L\"],\"+\",[1,\"B\",\"-\",\"T\"]],\"*\",[5,\"0.5\"]],\"*\",\"selfMask\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"=\",[1,[1,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"*\",\"pressureDecay\"],\"*\",\"selfMask\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"divergence\"],\"idx\"],\"=\",\"div\"]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,\"d.f32\":()=>n,layout:()=>s,nb:()=>l,\"std.select\":()=>N,pressureDecay:()=>c}})&&R.f)({})).$name(`${o}Divergence`):d?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=s.$.velA[l(D,O,0,-1)].x,q=s.$.velA[l(D,O,0,1)].x,Y=s.$.velA[l(D,O,-1,0)].y,V=s.$.velA[l(D,O,1,0)].y,X=__tsover_mul(__tsover_add(__tsover_sub(q,F),__tsover_sub(V,Y)),.5);s.$.pressure[k]=__tsover_mul(s.$.pressure[k],c),s.$.divergence[k]=X}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"vL\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"x\"]],[13,\"vR\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"x\"]],[13,\"vU\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"y\"]],[13,\"vD\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"y\"]],[13,\"div\",[1,[1,[1,\"vR\",\"-\",\"vL\"],\"+\",[1,\"vD\",\"-\",\"vU\"]],\"*\",[5,\"0.5\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"=\",[1,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"*\",\"pressureDecay\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"divergence\"],\"idx\"],\"=\",\"div\"]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,layout:()=>s,nb:()=>l,pressureDecay:()=>c}})&&R.f)({})).$name(`${o}Divergence`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=n(U),q=n(L),Y=s.$.velA[k],V=s.$.velA[l(D,O,0,-1)].x,X=s.$.velA[l(D,O,0,1)].x,Q=s.$.velA[l(D,O,-1,0)].y,te=s.$.velA[l(D,O,1,0)].y,J=N(V,__tsover_mul(Y.x,-1),F<.5),oe=N(X,__tsover_mul(Y.x,-1),F>n(__tsover_sub(r,1.5))),le=N(Q,__tsover_mul(Y.y,-1),q<.5),se=N(te,__tsover_mul(Y.y,-1),q>n(__tsover_sub(r,1.5))),Te=__tsover_mul(__tsover_add(__tsover_sub(oe,J),__tsover_sub(se,le)),.5);s.$.pressure[k]=__tsover_mul(s.$.pressure[k],c),s.$.divergence[k]=Te}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"jf\",[6,\"d.f32\",[\"cx\"]]],[13,\"iF\",[6,\"d.f32\",[\"cy\"]]],[13,\"selfVel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"normalL\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],\"x\"]],[13,\"normalR\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],\"x\"]],[13,\"normalU\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],\"y\"]],[13,\"normalD\",[7,[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],\"y\"]],[13,\"L\",[6,\"std.select\",[\"normalL\",[1,[7,\"selfVel\",\"x\"],\"*\",[4,\"-\",[5,\"1\"]]],[1,\"jf\",\"<\",[5,\"0.5\"]]]]],[13,\"R\",[6,\"std.select\",[\"normalR\",[1,[7,\"selfVel\",\"x\"],\"*\",[4,\"-\",[5,\"1\"]]],[1,\"jf\",\">\",[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1.5\"]]]]]]]],[13,\"T\",[6,\"std.select\",[\"normalU\",[1,[7,\"selfVel\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[1,\"iF\",\"<\",[5,\"0.5\"]]]]],[13,\"B\",[6,\"std.select\",[\"normalD\",[1,[7,\"selfVel\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[1,\"iF\",\">\",[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1.5\"]]]]]]]],[13,\"div\",[1,[1,[1,\"R\",\"-\",\"L\"],\"+\",[1,\"B\",\"-\",\"T\"]],\"*\",[5,\"0.5\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"=\",[1,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"*\",\"pressureDecay\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"divergence\"],\"idx\"],\"=\",\"div\"]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,\"d.f32\":()=>n,layout:()=>s,nb:()=>l,\"std.select\":()=>N,pressureDecay:()=>c}})&&R.f)({})).$name(`${o}Divergence`),g=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=s.$.pressure[l(D,O,0,-1)],q=s.$.pressure[l(D,O,0,1)],Y=s.$.pressure[l(D,O,-1,0)],V=s.$.pressure[l(D,O,1,0)],X=s.$.divergence[k];s.$.pressure[k]=__tsover_mul(__tsover_sub(__tsover_add(__tsover_add(__tsover_add(F,q),Y),V),X),.25)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"pL\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]]],[13,\"pR\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]]],[13,\"pU\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]]],[13,\"pD\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]]],[13,\"div\",[8,[7,[7,\"layout\",\"$\"],\"divergence\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"=\",[1,[1,[1,[1,[1,\"pL\",\"+\",\"pR\"],\"+\",\"pU\"],\"+\",\"pD\"],\"-\",\"div\"],\"*\",[5,\"0.25\"]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,layout:()=>s,nb:()=>l}})&&R.f)({})).$name(`${o}Jacobi`),y=t.velocityCap,b=y===void 0?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=s.$.pressure[l(D,O,0,-1)],q=s.$.pressure[l(D,O,0,1)],Y=s.$.pressure[l(D,O,-1,0)],V=s.$.pressure[l(D,O,1,0)],X=s.$.velA[k];s.$.velA[k]=S(__tsover_sub(X.x,__tsover_mul(__tsover_sub(q,F),.5)),__tsover_sub(X.y,__tsover_mul(__tsover_sub(V,Y),.5)),X.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"pL\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]]],[13,\"pR\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]]],[13,\"pU\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]]],[13,\"pD\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[7,\"vel\",\"x\"],\"-\",[1,[1,\"pR\",\"-\",\"pL\"],\"*\",[5,\"0.5\"]]],[1,[7,\"vel\",\"y\"],\"-\",[1,[1,\"pD\",\"-\",\"pU\"],\"*\",[5,\"0.5\"]]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,layout:()=>s,nb:()=>l,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}GradSubtract`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=j(L),O=j(U),F=s.$.pressure[l(D,O,0,-1)],q=s.$.pressure[l(D,O,0,1)],Y=s.$.pressure[l(D,O,-1,0)],V=s.$.pressure[l(D,O,1,0)],X=s.$.velA[k],Q=__tsover_sub(X.x,__tsover_mul(__tsover_sub(q,F),.5)),te=__tsover_sub(X.y,__tsover_mul(__tsover_sub(V,Y),.5)),J=n(y),oe=B(Ue(__tsover_add(__tsover_mul(Q,Q),__tsover_mul(te,te))),n(1e-6)),le=__tsover_div(J,B(oe,J));s.$.velA[k]=S(__tsover_mul(Q,le),__tsover_mul(te,le),X.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"pL\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]]],[13,\"pR\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]]],[13,\"pU\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]]],[13,\"pD\",[8,[7,[7,\"layout\",\"$\"],\"pressure\"],[6,\"nb\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"vx\",[1,[7,\"vel\",\"x\"],\"-\",[1,[1,\"pR\",\"-\",\"pL\"],\"*\",[5,\"0.5\"]]]],[13,\"vy\",[1,[7,\"vel\",\"y\"],\"-\",[1,[1,\"pD\",\"-\",\"pU\"],\"*\",[5,\"0.5\"]]]],[13,\"maxVel\",[6,\"d.f32\",[\"velocityCap\"]]],[13,\"vLen\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"vx\",\"*\",\"vx\"],\"+\",[1,\"vy\",\"*\",\"vy\"]]]],[6,\"d.f32\",[[5,\"0.000001\"]]]]]],[13,\"capScale\",[1,\"maxVel\",\"/\",[6,\"std.max\",[\"vLen\",\"maxVel\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,\"vx\",\"*\",\"capScale\"],[1,\"vy\",\"*\",\"capScale\"],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,\"d.i32\":()=>j,layout:()=>s,nb:()=>l,\"d.f32\":()=>n,velocityCap:()=>y,\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}GradSubtract`),x=t.solidMask??!1,P={curl:p,vorticity:f,divergence:h,jacobi:g,gradSubtract:b,advectVel:d?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=__tsover_mod(__tsover_add(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),n(r)),n(r)),q=__tsover_mod(__tsover_add(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),n(r)),n(r)),Y=ie(F),V=ie(q),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=__tsover_mod(__tsover_add(te,1),r),le=__tsover_mod(__tsover_add(J,1),r),se=s.$.velA[M(__tsover_add(__tsover_mul(J,r),te))],Te=s.$.velA[M(__tsover_add(__tsover_mul(J,r),oe))],de=s.$.velA[M(__tsover_add(__tsover_mul(le,r),te))],xe=s.$.velA[M(__tsover_add(__tsover_mul(le,r),oe))],Ae=__tsover_add(1,__tsover_mul(k.velFade,k.dt));s.$.velB[D]=S(__tsover_div(K(K(se.x,Te.x,X),K(de.x,xe.x,X),Q),Ae),__tsover_div(K(K(se.y,Te.y,X),K(de.y,xe.y,X),Q),Ae),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],\"+\",[6,\"d.f32\",[\"n\"]]],\"%\",[6,\"d.f32\",[\"n\"]]]],[13,\"srcY\",[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],\"+\",[6,\"d.f32\",[\"n\"]]],\"%\",[6,\"d.f32\",[\"n\"]]]],[13,\"x0\",[6,\"std.floor\",[\"srcX\"]]],[13,\"y0\",[6,\"std.floor\",[\"srcY\"]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"ix1\",[1,[1,\"ix0\",\"+\",[5,\"1\"]],\"%\",\"n\"]],[13,\"iy1\",[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"%\",\"n\"]],[13,\"v00\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v10\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix1\"]]]]],[13,\"v01\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy1\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v11\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy1\",\"*\",\"n\"],\"+\",\"ix1\"]]]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"velFade\"],\"*\",[7,\"p\",\"dt\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"x\"],[7,\"v10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"x\"],[7,\"v11\",\"x\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"y\"],[7,\"v10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"y\"],[7,\"v11\",\"y\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&R.f)({})).$name(`${o}AdvectVel`):x?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.velA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.velA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.velA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.velA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))],de=__tsover_add(1,__tsover_mul(k.velFade,k.dt)),xe=s.$.maskBuf[D].x;s.$.velB[D]=S(__tsover_mul(__tsover_div(K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),de),xe),__tsover_mul(__tsover_div(K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),de),xe),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"v00\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v10\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"v01\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v11\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"velFade\"],\"*\",[7,\"p\",\"dt\"]]]],[13,\"m\",[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],\"idx\"],\"x\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"x\"],[7,\"v10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"x\"],[7,\"v11\",\"x\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],\"*\",\"m\"],[1,[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"y\"],[7,\"v10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"y\"],[7,\"v11\",\"y\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],\"*\",\"m\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&R.f)({})).$name(`${o}AdvectVel`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.velA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.velA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.velA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.velA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))],de=__tsover_add(1,__tsover_mul(k.velFade,k.dt));s.$.velB[D]=S(__tsover_div(K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),de),__tsover_div(K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),de),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"v00\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v10\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"v01\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"v11\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"velFade\"],\"*\",[7,\"p\",\"dt\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"x\"],[7,\"v10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"x\"],[7,\"v11\",\"x\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],[1,[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"y\"],[7,\"v10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"v01\",\"y\"],[7,\"v11\",\"y\"],\"sx\"]],\"sy\"]],\"/\",\"decay\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&R.f)({})).$name(`${o}AdvectVel`),copyVel:t.publishVelocityTexture?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=s.$.velB[k];s.$.velA[k]=S(D.x,D.y,0,0),lt(s.$.velOutTex,fe(U,L),S(D.x,D.y,0,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"v\",[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"v\",\"x\"],[7,\"v\",\"y\"],[5,\"0\"],[5,\"0\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"velOutTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"v\",\"x\"],[7,\"v\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,layout:()=>s,\"d.vec4f\":()=>S,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe}})&&R.f)({})).$name(`${o}CopyVel`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=s.$.velB[k];s.$.velA[k]=S(D.x,D.y,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"v\",[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"v\",\"x\"],[7,\"v\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,layout:()=>s,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}CopyVel`)};if(i===\"none\")return P;let C=t.dyeDissipation??!1,E=t.ageAdvance??!1;return i===\"rgb\"?(P.advectDye=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.dyeA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))],de=K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),xe=K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),Ae=K(K(oe.z,le.z,X),K(se.z,Te.z,X),Q),De=__tsover_add(1,__tsover_mul(k.dyeFade,k.dt));s.$.dyeB[D]=S(B(__tsover_div(de,De),n(0)),B(__tsover_div(xe,De),n(0)),B(__tsover_div(Ae,De),n(0)),0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"c00\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"c10\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"c01\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"c11\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"r\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"c00\",\"x\"],[7,\"c10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"c01\",\"x\"],[7,\"c11\",\"x\"],\"sx\"]],\"sy\"]]],[13,\"g\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"c00\",\"y\"],[7,\"c10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"c01\",\"y\"],[7,\"c11\",\"y\"],\"sx\"]],\"sy\"]]],[13,\"b\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"c00\",\"z\"],[7,\"c10\",\"z\"],\"sx\"]],[6,\"std.mix\",[[7,\"c01\",\"z\"],[7,\"c11\",\"z\"],\"sx\"]],\"sy\"]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"dyeFade\"],\"*\",[7,\"p\",\"dt\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.max\",[[1,\"r\",\"/\",\"decay\"],[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[[1,\"g\",\"/\",\"decay\"],[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.max\",[[1,\"b\",\"/\",\"decay\"],[6,\"d.f32\",[[5,\"0\"]]]]],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"std.mix\":()=>K,\"d.vec4f\":()=>S,\"std.max\":()=>B}})&&R.f)({})).$name(`${o}Advect${u}`),P.copyDye=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=s.$.dyeB[k];s.$.dyeA[k]=S(D.x,D.y,D.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"c\",[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"c\",\"x\"],[7,\"c\",\"y\"],[7,\"c\",\"z\"],[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,layout:()=>s,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}Copy${u}`),P):(C&&E&&x?P.advectDye=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.dyeA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))],de=K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),xe=K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),Ae=__tsover_add(1,__tsover_mul(k.dyeFade,k.dt)),De=s.$.maskBuf[D].x;s.$.dyeB[D]=S(__tsover_mul(B(__tsover_div(de,Ae),n(0)),De),ye(__tsover_add(xe,__tsover_mul(__tsover_mul(k.dt,.4),k.colorDecay)),1),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"d00\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d10\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"d01\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d11\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"dens\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"x\"],[7,\"d10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"x\"],[7,\"d11\",\"x\"],\"sx\"]],\"sy\"]]],[13,\"age\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"y\"],[7,\"d10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"y\"],[7,\"d11\",\"y\"],\"sx\"]],\"sy\"]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"dyeFade\"],\"*\",[7,\"p\",\"dt\"]]]],[13,\"m\",[7,[8,[7,[7,\"layout\",\"$\"],\"maskBuf\"],\"idx\"],\"x\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[6,\"std.max\",[[1,\"dens\",\"/\",\"decay\"],[6,\"d.f32\",[[5,\"0\"]]]]],\"*\",\"m\"],[6,\"std.min\",[[1,\"age\",\"+\",[1,[1,[7,\"p\",\"dt\"],\"*\",[5,\"0.4\"]],\"*\",[7,\"p\",\"colorDecay\"]]],[5,\"1\"]]],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"std.mix\":()=>K,\"d.vec4f\":()=>S,\"std.max\":()=>B,\"std.min\":()=>ye}})&&R.f)({})).$name(`${o}Advect${u}`):C&&E?P.advectDye=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.dyeA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))],de=K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),xe=K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),Ae=__tsover_add(1,__tsover_mul(k.dyeFade,k.dt));s.$.dyeB[D]=S(B(__tsover_div(de,Ae),n(0)),ye(__tsover_add(xe,__tsover_mul(__tsover_mul(k.dt,.4),k.colorDecay)),1),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"d00\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d10\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"d01\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d11\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"dens\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"x\"],[7,\"d10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"x\"],[7,\"d11\",\"x\"],\"sx\"]],\"sy\"]]],[13,\"age\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"y\"],[7,\"d10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"y\"],[7,\"d11\",\"y\"],\"sx\"]],\"sy\"]]],[13,\"decay\",[1,[5,\"1\"],\"+\",[1,[7,\"p\",\"dyeFade\"],\"*\",[7,\"p\",\"dt\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.max\",[[1,\"dens\",\"/\",\"decay\"],[6,\"d.f32\",[[5,\"0\"]]]]],[6,\"std.min\",[[1,\"age\",\"+\",[1,[1,[7,\"p\",\"dt\"],\"*\",[5,\"0.4\"]],\"*\",[7,\"p\",\"colorDecay\"]]],[5,\"1\"]]],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"std.mix\":()=>K,\"d.vec4f\":()=>S,\"std.max\":()=>B,\"std.min\":()=>ye}})&&R.f)({})).$name(`${o}Advect${u}`):P.advectDye=d?w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=__tsover_mod(__tsover_add(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),n(r)),n(r)),q=__tsover_mod(__tsover_add(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),n(r)),n(r)),Y=ie(F),V=ie(q),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=__tsover_mod(__tsover_add(te,1),r),le=__tsover_mod(__tsover_add(J,1),r),se=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),te))],Te=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),oe))],de=s.$.dyeA[M(__tsover_add(__tsover_mul(le,r),te))],xe=s.$.dyeA[M(__tsover_add(__tsover_mul(le,r),oe))];s.$.dyeB[D]=S(K(K(se.x,Te.x,X),K(de.x,xe.x,X),Q),K(K(se.y,Te.y,X),K(de.y,xe.y,X),Q),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[1,[1,[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],\"+\",[6,\"d.f32\",[\"n\"]]],\"%\",[6,\"d.f32\",[\"n\"]]]],[13,\"srcY\",[1,[1,[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],\"+\",[6,\"d.f32\",[\"n\"]]],\"%\",[6,\"d.f32\",[\"n\"]]]],[13,\"x0\",[6,\"std.floor\",[\"srcX\"]]],[13,\"y0\",[6,\"std.floor\",[\"srcY\"]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"ix1\",[1,[1,\"ix0\",\"+\",[5,\"1\"]],\"%\",\"n\"]],[13,\"iy1\",[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"%\",\"n\"]],[13,\"d00\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d10\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix1\"]]]]],[13,\"d01\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy1\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d11\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy1\",\"*\",\"n\"],\"+\",\"ix1\"]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"x\"],[7,\"d10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"x\"],[7,\"d11\",\"x\"],\"sx\"]],\"sy\"]],[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"y\"],[7,\"d10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"y\"],[7,\"d11\",\"y\"],\"sx\"]],\"sy\"]],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&R.f)({})).$name(`${o}Advect${u}`):w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=s.$.params,D=__tsover_add(__tsover_mul(L,M(r)),U),O=s.$.velA[D],F=G(__tsover_sub(n(U),__tsover_mul(O.x,k.dt)),0,n(__tsover_sub(r,1))),q=G(__tsover_sub(n(L),__tsover_mul(O.y,k.dt)),0,n(__tsover_sub(r,1))),Y=G(ie(F),0,n(__tsover_sub(r,2))),V=G(ie(q),0,n(__tsover_sub(r,2))),X=__tsover_sub(F,Y),Q=__tsover_sub(q,V),te=j(Y),J=j(V),oe=s.$.dyeA[M(__tsover_add(__tsover_mul(J,r),te))],le=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(J,r),te),1))],se=s.$.dyeA[M(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te))],Te=s.$.dyeA[M(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(J,1),r),te),1))];s.$.dyeB[D]=S(K(K(oe.x,le.x,X),K(se.x,Te.x,X),Q),K(K(oe.y,le.y,X),K(se.y,Te.y,X),Q),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"srcX\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cx\"]],\"-\",[1,[7,\"vel\",\"x\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"srcY\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"cy\"]],\"-\",[1,[7,\"vel\",\"y\"],\"*\",[7,\"p\",\"dt\"]]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"1\"]]]]]]],[13,\"x0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcX\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"y0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"srcY\"]],[5,\"0\"],[6,\"d.f32\",[[1,\"n\",\"-\",[5,\"2\"]]]]]]],[13,\"sx\",[1,\"srcX\",\"-\",\"x0\"]],[13,\"sy\",[1,\"srcY\",\"-\",\"y0\"]],[13,\"ix0\",[6,\"d.i32\",[\"x0\"]]],[13,\"iy0\",[6,\"d.i32\",[\"y0\"]]],[13,\"d00\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d10\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[13,\"d01\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"]]]]],[13,\"d11\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],[6,\"d.u32\",[[1,[1,[1,[1,\"iy0\",\"+\",[5,\"1\"]],\"*\",\"n\"],\"+\",\"ix0\"],\"+\",[5,\"1\"]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"x\"],[7,\"d10\",\"x\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"x\"],[7,\"d11\",\"x\"],\"sx\"]],\"sy\"]],[6,\"std.mix\",[[6,\"std.mix\",[[7,\"d00\",\"y\"],[7,\"d10\",\"y\"],\"sx\"]],[6,\"std.mix\",[[7,\"d01\",\"y\"],[7,\"d11\",\"y\"],\"sx\"]],\"sy\"]],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&R.f)({})).$name(`${o}Advect${u}`),P.copyDye=w.fn([M,M])((R=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(R.f=((U,L)=>{\"use gpu\";let k=__tsover_add(__tsover_mul(L,M(r)),U),D=s.$.dyeB[k];s.$.dyeA[k]=S(D.x,D.y,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"dd\",[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"dd\",\"x\"],[7,\"dd\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{\"d.u32\":()=>M,n:()=>r,layout:()=>s,\"d.vec4f\":()=>S}})&&R.f)({})).$name(`${o}Copy${u}`),P)}function Ui(e,t){let{n:s,namePrefix:r}=t;return t.dye===\"rgb\"?w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=__tsover_add(__tsover_mul(i,M(s)),a),c=e.$.dyeA[l];lt(e.$.outTex,fe(a,i),S(c.x,c.y,c.z,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"c\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"c\",\"x\"],[7,\"c\",\"y\"],[7,\"c\",\"z\"],[5,\"1\"]]]]]]]},externals:{\"d.u32\":()=>M,n:()=>s,layout:()=>e,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(`${r}Output`):w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=__tsover_add(__tsover_mul(i,M(s)),a),c=e.$.dyeA[l];lt(e.$.outTex,fe(a,i),S(c.x,c.y,0,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"dd\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"dd\",\"x\"],[7,\"dd\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]]},externals:{\"d.u32\":()=>M,n:()=>s,layout:()=>e,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(`${r}Output`)}var mm=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Ys(m(t,s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"px\"},{type:\"i\",name:\"py\"}],body:[0,[[10,[6,\"noise.hash12\",[[6,\"d.vec2f\",[\"px\",\"py\"]]]]]]]},externals:{\"noise.hash12\":()=>Ys,\"d.vec2f\":()=>m}})&&e.f)({})),g1=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=ie(t),o=ie(s),a=Re(t),i=Re(s),l=__tsover_mul(__tsover_mul(a,a),__tsover_sub(3,__tsover_mul(a,2))),c=__tsover_mul(__tsover_mul(i,i),__tsover_sub(3,__tsover_mul(i,2)));return K(K(mm(r,o),mm(__tsover_add(r,1),o),l),K(mm(r,__tsover_add(o,1)),mm(__tsover_add(r,1),__tsover_add(o,1)),l),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"nx\"},{type:\"i\",name:\"ny\"}],body:[0,[[13,\"ix\",[6,\"std.floor\",[\"nx\"]]],[13,\"iy\",[6,\"std.floor\",[\"ny\"]]],[13,\"sx\",[6,\"std.fract\",[\"nx\"]]],[13,\"sy\",[6,\"std.fract\",[\"ny\"]]],[13,\"ux\",[1,[1,\"sx\",\"*\",\"sx\"],\"*\",[1,[5,\"3\"],\"-\",[1,\"sx\",\"*\",[5,\"2\"]]]]],[13,\"uy\",[1,[1,\"sy\",\"*\",\"sy\"],\"*\",[1,[5,\"3\"],\"-\",[1,\"sy\",\"*\",[5,\"2\"]]]]],[10,[6,\"std.mix\",[[6,\"std.mix\",[[6,\"valueHash\",[\"ix\",\"iy\"]],[6,\"valueHash\",[[1,\"ix\",\"+\",[5,\"1\"]],\"iy\"]],\"ux\"]],[6,\"std.mix\",[[6,\"valueHash\",[\"ix\",[1,\"iy\",\"+\",[5,\"1\"]]]],[6,\"valueHash\",[[1,\"ix\",\"+\",[5,\"1\"]],[1,\"iy\",\"+\",[5,\"1\"]]]],\"ux\"]],\"uy\"]]]]]},externals:{\"std.floor\":()=>ie,\"std.fract\":()=>Re,\"std.mix\":()=>K,valueHash:()=>mm}})&&e.f)({})),Um=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_add(__tsover_add(__tsover_mul(g1(t,s),.5),__tsover_mul(g1(__tsover_add(__tsover_mul(t,2),5.37),__tsover_add(__tsover_mul(s,2),9.13)),.3)),__tsover_mul(g1(__tsover_add(__tsover_mul(t,4),1.79),__tsover_add(__tsover_mul(s,4),3.51)),.2))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"nx\"},{type:\"i\",name:\"ny\"}],body:[0,[[10,[1,[1,[1,[6,\"valueNoise2D\",[\"nx\",\"ny\"]],\"*\",[5,\"0.5\"]],\"+\",[1,[6,\"valueNoise2D\",[[1,[1,\"nx\",\"*\",[5,\"2\"]],\"+\",[5,\"5.37\"]],[1,[1,\"ny\",\"*\",[5,\"2\"]],\"+\",[5,\"9.13\"]]]],\"*\",[5,\"0.3\"]]],\"+\",[1,[6,\"valueNoise2D\",[[1,[1,\"nx\",\"*\",[5,\"4\"]],\"+\",[5,\"1.79\"]],[1,[1,\"ny\",\"*\",[5,\"4\"]],\"+\",[5,\"3.51\"]]]],\"*\",[5,\"0.2\"]]]]]]},externals:{valueNoise2D:()=>g1}})&&e.f)({})),ih=w.fn([n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(Xs(__tsover_mul(r,37.31)),97),i=__tsover_mul(Xs(__tsover_mul(r,83.17)),97);return m(__tsover_add(__tsover_mul(t,o),a),__tsover_add(__tsover_mul(s,o),i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"cellsPerTexel\"}],body:[0,[[13,\"sdx\",[1,[6,\"noise.hash11\",[[1,\"seed\",\"*\",[5,\"37.31\"]]]],\"*\",[5,\"97\"]]],[13,\"sdy\",[1,[6,\"noise.hash11\",[[1,\"seed\",\"*\",[5,\"83.17\"]]]],\"*\",[5,\"97\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"x\",\"*\",\"cellsPerTexel\"],\"+\",\"sdx\"],[1,[1,\"y\",\"*\",\"cellsPerTexel\"],\"+\",\"sdy\"]]]]]]},externals:{\"noise.hash11\":()=>Xs,\"d.vec2f\":()=>m}})&&e.f)({}));function Pz(e,t){let s=e,{n:r,namePrefix:o}=t,a=(t.frequency??3)/r,i=t.density??{scale:.75,bias:.25,min:.15,max:.9},l=i.scale,c=i.bias,d=i.min,u=i.max;return w.fn([M,M])((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";let h=s.$.params,g=__tsover_add(__tsover_mul(f,M(r)),_),y=ih(n(_),n(f),h.seed,a),b=G(__tsover_add(__tsover_mul(Um(__tsover_add(y.x,31.7),__tsover_add(y.y,53.3)),l),c),d,u),x=G(Um(y.x,y.y),0,1);s.$.dyeA[g]=S(b,x,0,0),s.$.dyeB[g]=S(b,x,0,0),s.$.velA[g]=S(0,0,0,0),s.$.velB[g]=S(0,0,0,0),s.$.pressure[g]=0,s.$.divergence[g]=0}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"lat\",[6,\"seedLattice\",[[6,\"d.f32\",[\"cx\"]],[6,\"d.f32\",[\"cy\"]],[7,\"p\",\"seed\"],\"cellsPerTexel\"]]],[13,\"dens0\",[6,\"std.clamp\",[[1,[1,[6,\"fbm\",[[1,[7,\"lat\",\"x\"],\"+\",[5,\"31.7\"]],[1,[7,\"lat\",\"y\"],\"+\",[5,\"53.3\"]]]],\"*\",\"dScale\"],\"+\",\"dBias\"],\"dMin\",\"dMax\"]]],[13,\"colorVar\",[6,\"std.clamp\",[[6,\"fbm\",[[7,\"lat\",\"x\"],[7,\"lat\",\"y\"]]],[5,\"0\"],[5,\"1\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"dens0\",\"colorVar\",[5,\"0\"],[5,\"0\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"dens0\",\"colorVar\",[5,\"0\"],[5,\"0\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velB\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pressure\"],\"idx\"],\"=\",[5,\"0\"]],[2,[8,[7,[7,\"layout\",\"$\"],\"divergence\"],\"idx\"],\"=\",[5,\"0\"]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,seedLattice:()=>ih,\"d.f32\":()=>n,cellsPerTexel:()=>a,\"std.clamp\":()=>G,fbm:()=>Um,dScale:()=>l,dBias:()=>c,dMin:()=>d,dMax:()=>u,\"d.vec4f\":()=>S}})&&p.f)({})).$name(`${o}Init`)}var $0=Jt;function Cz(e,t){let s=e,{n:r,namePrefix:o}=t,a=r*(t.gain??.04);return w.fn([M,M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c)=>{\"use gpu\";let d=s.$.params,u=__tsover_add(__tsover_mul(c,M(r)),l),p=__tsover_add(n(l),.5),_=__tsover_add(n(c),.5),f=__tsover_mul(__tsover_div(p,n(r)),$0),h=__tsover_mul(__tsover_div(_,n(r)),$0),g=d.time,y=s.$.velA[u],b=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(f,2),__tsover_mul(g,.31))),pe(__tsover_add(__tsover_mul(h,1.5),__tsover_mul(g,.23)))),__tsover_mul(ae(__tsover_add(__tsover_add(__tsover_mul(f,.7),__tsover_mul(h,1.3)),__tsover_mul(g,.17))),.4)),d.turbulence),a),d.dt),x=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_add(__tsover_mul(pe(__tsover_add(__tsover_mul(f,1.5),__tsover_mul(g,.27))),ae(__tsover_add(__tsover_mul(h,2),__tsover_mul(g,.19)))),__tsover_mul(pe(__tsover_add(__tsover_add(__tsover_mul(f,1.1),__tsover_mul(h,.9)),__tsover_mul(g,.21))),.4)),d.turbulence),a),d.dt),P=__tsover_sub(p,d.cursorX),C=__tsover_sub(_,d.cursorY),E=__tsover_add(__tsover_mul(P,P),__tsover_mul(C,C)),R=__tsover_mul(ga(E,B(d.mouseRadSq,n(1))),d.mouseActive);s.$.velA[u]=S(__tsover_add(__tsover_add(y.x,b),__tsover_mul(d.cursorVelX,R)),__tsover_add(__tsover_add(y.y,x),__tsover_mul(d.cursorVelY,R)),y.z,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"jf\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"iF\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"x\",[1,[1,\"jf\",\"/\",[6,\"d.f32\",[\"n\"]]],\"*\",\"TAU\"]],[13,\"y\",[1,[1,\"iF\",\"/\",[6,\"d.f32\",[\"n\"]]],\"*\",\"TAU\"]],[13,\"t\",[7,\"p\",\"time\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"]],[13,\"fx\",[1,[1,[1,[1,[1,[6,\"std.sin\",[[1,[1,\"x\",\"*\",[5,\"2\"]],\"+\",[1,\"t\",\"*\",[5,\"0.31\"]]]]],\"*\",[6,\"std.cos\",[[1,[1,\"y\",\"*\",[5,\"1.5\"]],\"+\",[1,\"t\",\"*\",[5,\"0.23\"]]]]]],\"+\",[1,[6,\"std.sin\",[[1,[1,[1,\"x\",\"*\",[5,\"0.7\"]],\"+\",[1,\"y\",\"*\",[5,\"1.3\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.17\"]]]]],\"*\",[5,\"0.4\"]]],\"*\",[7,\"p\",\"turbulence\"]],\"*\",\"gain\"],\"*\",[7,\"p\",\"dt\"]]],[13,\"fy\",[1,[1,[1,[1,[1,[6,\"std.cos\",[[1,[1,\"x\",\"*\",[5,\"1.5\"]],\"+\",[1,\"t\",\"*\",[5,\"0.27\"]]]]],\"*\",[6,\"std.sin\",[[1,[1,\"y\",\"*\",[5,\"2\"]],\"+\",[1,\"t\",\"*\",[5,\"0.19\"]]]]]],\"+\",[1,[6,\"std.cos\",[[1,[1,[1,\"x\",\"*\",[5,\"1.1\"]],\"+\",[1,\"y\",\"*\",[5,\"0.9\"]]],\"+\",[1,\"t\",\"*\",[5,\"0.21\"]]]]],\"*\",[5,\"0.4\"]]],\"*\",[7,\"p\",\"turbulence\"]],\"*\",\"gain\"],\"*\",[7,\"p\",\"dt\"]]],[13,\"cdx\",[1,\"jf\",\"-\",[7,\"p\",\"cursorX\"]]],[13,\"cdy\",[1,\"iF\",\"-\",[7,\"p\",\"cursorY\"]]],[13,\"cursorDistSq\",[1,[1,\"cdx\",\"*\",\"cdx\"],\"+\",[1,\"cdy\",\"*\",\"cdy\"]]],[13,\"cursorInf\",[1,[6,\"gaussianBrushSq\",[\"cursorDistSq\",[6,\"std.max\",[[7,\"p\",\"mouseRadSq\"],[6,\"d.f32\",[[5,\"1\"]]]]]]],\"*\",[7,\"p\",\"mouseActive\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"velA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[1,[1,[7,\"vel\",\"x\"],\"+\",\"fx\"],\"+\",[1,[7,\"p\",\"cursorVelX\"],\"*\",\"cursorInf\"]],[1,[1,[7,\"vel\",\"y\"],\"+\",\"fy\"],\"+\",[1,[7,\"p\",\"cursorVelY\"],\"*\",\"cursorInf\"]],[7,\"vel\",\"z\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,\"d.f32\":()=>n,TAU:()=>$0,\"std.sin\":()=>ae,\"std.cos\":()=>pe,gain:()=>a,gaussianBrushSq:()=>ga,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&i.f)({})).$name(`${o}Force`)}function Mz(e,t){let s=e,{n:r,namePrefix:o}=t,a=(t.frequency??3)/r;return w.fn([M,M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c)=>{\"use gpu\";let d=s.$.params,u=__tsover_add(__tsover_mul(c,M(r)),l),p=ih(n(l),n(c),d.seed,a),_=Um(p.x,p.y),f=__tsover_sub(1,d.blending),h=__tsover_add(1,__tsover_mul(f,5)),g=G(__tsover_add(__tsover_mul(__tsover_sub(_,.5),h),.5),0,1),y=s.$.dyeA[u],b=__tsover_add(1,__tsover_mul(f,2.5)),x=ye(__tsover_mul(__tsover_mul(d.dt,.5),b),.3);s.$.dyeA[u]=S(y.x,K(y.y,g,x),0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"lat\",[6,\"seedLattice\",[[6,\"d.f32\",[\"cx\"]],[6,\"d.f32\",[\"cy\"]],[7,\"p\",\"seed\"],\"cellsPerTexel\"]]],[13,\"refRaw\",[6,\"fbm\",[[7,\"lat\",\"x\"],[7,\"lat\",\"y\"]]]],[13,\"invBlend\",[1,[5,\"1\"],\"-\",[7,\"p\",\"blending\"]]],[13,\"contrastBoost\",[1,[5,\"1\"],\"+\",[1,\"invBlend\",\"*\",[5,\"5\"]]]],[13,\"refBoosted\",[6,\"std.clamp\",[[1,[1,[1,\"refRaw\",\"-\",[5,\"0.5\"]],\"*\",\"contrastBoost\"],\"+\",[5,\"0.5\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"cell\",[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"]],[13,\"rateMult\",[1,[5,\"1\"],\"+\",[1,\"invBlend\",\"*\",[5,\"2.5\"]]]],[13,\"blendRate\",[6,\"std.min\",[[1,[1,[7,\"p\",\"dt\"],\"*\",[5,\"0.5\"]],\"*\",\"rateMult\"],[5,\"0.3\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"dyeA\"],\"idx\"],\"=\",[6,\"d.vec4f\",[[7,\"cell\",\"x\"],[6,\"std.mix\",[[7,\"cell\",\"y\"],\"refBoosted\",\"blendRate\"]],[5,\"0\"],[5,\"0\"]]]]]]},externals:{layout:()=>s,\"d.u32\":()=>M,n:()=>r,seedLattice:()=>ih,\"d.f32\":()=>n,cellsPerTexel:()=>a,fbm:()=>Um,\"std.clamp\":()=>G,\"std.min\":()=>ye,\"d.vec4f\":()=>S,\"std.mix\":()=>K}})&&i.f)({})).$name(`${o}ColorRestore`)}var y1=512,cu=w.fn([n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=__tsover_mul(__tsover_sub(t,r),l),d=__tsover_sub(s,o),u=pe(i),p=ae(i),_=__tsover_add(__tsover_mul(c,u),__tsover_mul(d,p)),f=__tsover_sub(__tsover_mul(d,u),__tsover_mul(c,p));return m(__tsover_add(__tsover_div(_,a),.5),__tsover_add(__tsover_div(f,a),.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"u\"},{type:\"i\",name:\"v\"},{type:\"i\",name:\"centerX\"},{type:\"i\",name:\"centerY\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"rotation\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"dxAc\",[1,[1,\"u\",\"-\",\"centerX\"],\"*\",\"aspect\"]],[13,\"dy\",[1,\"v\",\"-\",\"centerY\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotation\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotation\"]]],[13,\"rdx\",[1,[1,\"dxAc\",\"*\",\"cosR\"],\"+\",[1,\"dy\",\"*\",\"sinR\"]]],[13,\"rdy\",[1,[1,\"dy\",\"*\",\"cosR\"],\"-\",[1,\"dxAc\",\"*\",\"sinR\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"rdx\",\"/\",\"scale\"],\"+\",[5,\"0.5\"]],[1,[1,\"rdy\",\"/\",\"scale\"],\"+\",[5,\"0.5\"]]]]]]]},externals:{\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"d.vec2f\":()=>m}})&&e.f)({}));gt({centerX:n,centerY:n,scale:n,rotation:n,aspect:n,saRadius:n,saSides:n,saRounding:n,saInnerRatio:n,saRotation:n,saHeight:n,saOffset:n,saAperture:n,vfOriginX:n,vfOriginY:n,vfSpanX:n,vfSpanY:n,vfActiveRes:n});function Ez(e,t){let{n:s,namePrefix:r}=t,o=e,a={storage:Fe(S,s*s),access:\"mutable\"},i=(globalThis.__TYPEGPU_AUTONAME__??(u=>u))(w.bindGroupLayout({maskBuf:a,params:{uniform:o}}),\"analyticLayout\"),l=(globalThis.__TYPEGPU_AUTONAME__??(u=>u))(w.bindGroupLayout({maskBuf:a,params:{uniform:o},sdfSource:{texture:Zt(n)}}),\"svgLayout\"),c=(globalThis.__TYPEGPU_AUTONAME__??(u=>u))(w.bindGroupLayout({maskBuf:a,params:{uniform:o},fieldTex:{texture:Zt(n),sampleType:\"unfilterable-float\"}}),\"fieldLayout\");return{analyticLayout:i,svgLayout:l,fieldLayout:c,analytic:u=>{let p=P_(u);return w.fn([M,M])((_=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(_.f=((f,h)=>{\"use gpu\";let g=i.$.params,y=__tsover_add(__tsover_mul(h,M(s)),f),b=p(cu(__tsover_div(__tsover_add(n(f),.5),n(s)),__tsover_div(__tsover_add(n(h),.5),n(s)),g.centerX,g.centerY,g.scale,g.rotation,g.aspect),g.saRadius,g.saSides,g.saRounding,g.saInnerRatio,g.saRotation,g.saHeight,g.saOffset,g.saAperture),x=N(n(0),n(1),b.x<0);i.$.maskBuf[y]=S(x,b.x,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"analyticLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"sdfUV\",[6,\"gridShapeUV\",[\"u\",\"v\",[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"],[7,\"p\",\"scale\"],[7,\"p\",\"rotation\"],[7,\"p\",\"aspect\"]]]],[13,\"res\",[6,\"sdfFn\",[\"sdfUV\",[7,\"p\",\"saRadius\"],[7,\"p\",\"saSides\"],[7,\"p\",\"saRounding\"],[7,\"p\",\"saInnerRatio\"],[7,\"p\",\"saRotation\"],[7,\"p\",\"saHeight\"],[7,\"p\",\"saOffset\"],[7,\"p\",\"saAperture\"]]]],[13,\"inside\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"res\",\"x\"],\"<\",[5,\"0\"]]]]],[2,[8,[7,[7,\"analyticLayout\",\"$\"],\"maskBuf\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"inside\",[7,\"res\",\"x\"],[5,\"0\"],[5,\"0\"]]]]]]},externals:{analyticLayout:()=>i,\"d.u32\":()=>M,n:()=>s,\"d.f32\":()=>n,gridShapeUV:()=>cu,sdfFn:()=>p,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&_.f)({})).$name(`${r}Mask`)},svgKernel:w.fn([M,M])((u=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(u.f=((p,_)=>{\"use gpu\";let f=l.$.params,h=__tsover_add(__tsover_mul(_,M(s)),p),g=cu(__tsover_div(__tsover_add(n(p),.5),n(s)),__tsover_div(__tsover_add(n(_),.5),n(s)),f.centerX,f.centerY,f.scale,f.rotation,f.aspect),y=__tsover_sub(y1,1),b=G(j(__tsover_mul(g.x,y1)),0,y),x=G(j(__tsover_mul(g.y,y1)),0,y),P=Ye(l.$.sdfSource,fe(M(b),M(x)),0).x,C=N(n(0),n(1),P<0);l.$.maskBuf[h]=S(C,P,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"svgLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"sdfUV\",[6,\"gridShapeUV\",[\"u\",\"v\",[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"],[7,\"p\",\"scale\"],[7,\"p\",\"rotation\"],[7,\"p\",\"aspect\"]]]],[13,\"sizeM1\",[1,\"SVG_SDF_SIZE\",\"-\",[5,\"1\"]]],[13,\"tx\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,[7,\"sdfUV\",\"x\"],\"*\",\"SVG_SDF_SIZE\"]]],[5,\"0\"],\"sizeM1\"]]],[13,\"ty\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,[7,\"sdfUV\",\"y\"],\"*\",\"SVG_SDF_SIZE\"]]],[5,\"0\"],\"sizeM1\"]]],[13,\"dist\",[7,[6,\"std.textureLoad\",[[7,[7,\"svgLayout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"tx\"]],[6,\"d.u32\",[\"ty\"]]]],[5,\"0\"]]],\"x\"]],[13,\"inside\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"dist\",\"<\",[5,\"0\"]]]]],[2,[8,[7,[7,\"svgLayout\",\"$\"],\"maskBuf\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"inside\",\"dist\",[5,\"0\"],[5,\"0\"]]]]]]},externals:{svgLayout:()=>l,\"d.u32\":()=>M,n:()=>s,\"d.f32\":()=>n,gridShapeUV:()=>cu,SVG_SDF_SIZE:()=>y1,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&u.f)({})).$name(`${r}SvgMask`),fieldKernel:w.fn([M,M])((u=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(u.f=((p,_)=>{\"use gpu\";let f=c.$.params,h=__tsover_add(__tsover_mul(_,M(s)),p),g=cu(__tsover_div(__tsover_add(n(p),.5),n(s)),__tsover_div(__tsover_add(n(_),.5),n(s)),f.centerX,f.centerY,f.scale,f.rotation,f.aspect),y=G(g.x,f.vfOriginX,__tsover_add(f.vfOriginX,f.vfSpanX)),b=G(g.y,f.vfOriginY,__tsover_add(f.vfOriginY,f.vfSpanY)),x=he(m(__tsover_sub(g.x,y),__tsover_sub(g.y,b))),P=__tsover_sub(f.vfActiveRes,1),C=G(__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(y,f.vfOriginX),f.vfSpanX),f.vfActiveRes),.5),n(0),P),E=G(__tsover_sub(__tsover_mul(__tsover_div(__tsover_sub(b,f.vfOriginY),f.vfSpanY),f.vfActiveRes),.5),n(0),P),R=__tsover_add(Ye(c.$.fieldTex,fe(M(C),M(E)),0).x,x),U=N(n(0),n(1),R<0);c.$.maskBuf[h]=S(U,R,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"fieldLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"sdfUV\",[6,\"gridShapeUV\",[\"u\",\"v\",[7,\"p\",\"centerX\"],[7,\"p\",\"centerY\"],[7,\"p\",\"scale\"],[7,\"p\",\"rotation\"],[7,\"p\",\"aspect\"]]]],[13,\"uxc\",[6,\"std.clamp\",[[7,\"sdfUV\",\"x\"],[7,\"p\",\"vfOriginX\"],[1,[7,\"p\",\"vfOriginX\"],\"+\",[7,\"p\",\"vfSpanX\"]]]]],[13,\"uyc\",[6,\"std.clamp\",[[7,\"sdfUV\",\"y\"],[7,\"p\",\"vfOriginY\"],[1,[7,\"p\",\"vfOriginY\"],\"+\",[7,\"p\",\"vfSpanY\"]]]]],[13,\"outsideDist\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"sdfUV\",\"x\"],\"-\",\"uxc\"],[1,[7,\"sdfUV\",\"y\"],\"-\",\"uyc\"]]]]]],[13,\"maxT\",[1,[7,\"p\",\"vfActiveRes\"],\"-\",[5,\"1\"]]],[13,\"tx\",[6,\"std.clamp\",[[1,[1,[1,[1,\"uxc\",\"-\",[7,\"p\",\"vfOriginX\"]],\"/\",[7,\"p\",\"vfSpanX\"]],\"*\",[7,\"p\",\"vfActiveRes\"]],\"-\",[5,\"0.5\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]],[13,\"ty\",[6,\"std.clamp\",[[1,[1,[1,[1,\"uyc\",\"-\",[7,\"p\",\"vfOriginY\"]],\"/\",[7,\"p\",\"vfSpanY\"]],\"*\",[7,\"p\",\"vfActiveRes\"]],\"-\",[5,\"0.5\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]],[13,\"dist\",[1,[7,[6,\"std.textureLoad\",[[7,[7,\"fieldLayout\",\"$\"],\"fieldTex\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"tx\"]],[6,\"d.u32\",[\"ty\"]]]],[5,\"0\"]]],\"x\"],\"+\",\"outsideDist\"]],[13,\"inside\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"dist\",\"<\",[5,\"0\"]]]]],[2,[8,[7,[7,\"fieldLayout\",\"$\"],\"maskBuf\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"inside\",\"dist\",[5,\"0\"],[5,\"0\"]]]]]]},externals:{fieldLayout:()=>c,\"d.u32\":()=>M,n:()=>s,\"d.f32\":()=>n,gridShapeUV:()=>cu,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.select\":()=>N,\"d.vec4f\":()=>S}})&&u.f)({})).$name(`${r}VfMask`)}}function D_(e,t,s){return wr(e,(r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a)=>{\"use gpu\";t(o,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>t}})&&r.f)({}),{size:[s.n,s.n],bindGroup:s.bindGroup})}function jA(e,t,s){let r=[s.n,s.n],o=i=>wr(e,(l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";i(c,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>i}})&&l.f)({}),{size:r,bindGroup:s.bindGroup}),a={curl:o(t.curl),vorticity:o(t.vorticity),divergence:o(t.divergence),jacobi:o(t.jacobi),gradSubtract:o(t.gradSubtract),advectVel:o(t.advectVel),copyVel:o(t.copyVel),advectDye:t.advectDye?o(t.advectDye):void 0,copyDye:t.copyDye?o(t.copyDye):void 0};return{...a,solveSteps({jacobiIters:i,vorticity:l}){let c=[a.curl,l??a.vorticity,a.divergence];for(let d=0;d<i;d++)c.push(a.jacobi);return c.push(a.gradSubtract,a.advectVel,a.copyVel),a.advectDye&&c.push(a.advectDye),a.copyDye&&c.push(a.copyDye),c}}}var LP=Po;var dd=256*256,od=255;var UP=1-10*.004,kz=UP>=1?1/0:Math.min(3e4,Math.log(1e-6)/Math.log(Math.max(UP,.001))*16.67),Bz=.02,t_=\"rgba16float\",KA=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({amp:n,freq:n,seed:n,edgePin:n,cursorIntensity:n,t:n,aspect:n,focal:n,camPos:A,camForward:A,camRight:A,camUp:A,lighting:n,glossiness:n,highlights:n,lightX:n,lightY:n,lightZ:n,lightColor:A,nearCutoff:n,farCutoff:n,cursorWaveX:n,cursorWaveY:n,mouseSpeed:n,dt:n,decay:n,radius:n,waveSpeed:n,heightEnvelope:n,cursorActive:n}),\"HeightFieldParams\");function zz(e){let t=(globalThis.__TYPEGPU_AUTONAME__??(s=>s))(e.createUniform(KA),\"u\");return{buffer:t.buffer,write:s=>t.write({...s,camPos:A(...s.camPos),camForward:A(...s.camForward),camRight:A(...s.camRight),camUp:A(...s.camUp),lightColor:A(...s.lightColor)})}}var bn=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({readSrc:{storage:Fe(n,dd),access:\"readonly\"},writeBuf:{storage:Fe(n,dd),access:\"mutable\"},readBuf:{storage:Fe(n,dd),access:\"mutable\"},params:{uniform:KA}}),\"waveEquationLayout\"),xn=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({readBuf:{storage:Fe(n,dd),access:\"readonly\"},params:{uniform:KA},uvMaskTex:{storageTexture:zt(t_,\"write-only\")},litTex:{storageTexture:zt(t_,\"write-only\")}}),\"heightFieldMarchLayout\");function Rz(e){return{bufferA:pr(e,n,dd),bufferB:pr(e,n,dd),readBuf:pr(e,n,dd)}}function bie(e,t,s){let r=1/(2-Math.pow(.5,Math.max(t,1)-1));return w.fn([m],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=(a=>{\"use gpu\";let i=xn.$.params,l=a.x,c=a.y,d=i.amp,u=i.freq,p=i.seed,_=n(0);if(e===1){let x=n(0);for(let P=0;P<t;P++){let C=n(P),E=Ia(C),R=Ia(__tsover_mul(C,-1)),U=pe(__tsover_mul(C,1.111)),L=ae(__tsover_mul(C,1.111)),k=__tsover_sub(__tsover_mul(l,U),__tsover_mul(c,L)),D=__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(__tsover_mul(k,u),E),LP),__tsover_mul(i.t,__tsover_add(1,__tsover_mul(C,.2)))),__tsover_mul(p,__tsover_add(1,__tsover_mul(C,.5))));x=__tsover_add(x,__tsover_mul(ae(D),R))}_=__tsover_mul(x,r)}else if(e===2){let x=n(0);for(let C=0;C<t;C++){let E=n(C),R=Ia(E),U=Ia(__tsover_mul(E,-1)),L=pe(__tsover_mul(E,2.39996)),k=ae(__tsover_mul(E,2.39996)),D=m(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(l,u),R),__tsover_mul(i.t,__tsover_mul(L,.3))),p),__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(c,u),R),__tsover_mul(i.t,__tsover_mul(k,.3))),__tsover_mul(p,.7)));x=__tsover_add(x,__tsover_mul(la(D),U))}let P=__tsover_mul(x,r);_=__tsover_sub(__tsover_mul(__tsover_sub(1,re(P)),2),1)}else{let x=__tsover_mul(u,.5),P=la(m(__tsover_add(__tsover_add(__tsover_mul(l,x),__tsover_mul(i.t,.1)),p),__tsover_add(__tsover_mul(c,x),__tsover_mul(p,1.3)))),C=la(m(__tsover_add(__tsover_add(__tsover_mul(l,x),p),17.3),__tsover_add(__tsover_add(__tsover_add(__tsover_mul(c,x),__tsover_mul(i.t,.07)),p),31.1))),E=__tsover_add(l,__tsover_mul(P,.4)),R=__tsover_add(c,__tsover_mul(C,.4)),U=n(0);for(let L=0;L<t;L++){let k=n(L),D=Ia(k),O=Ia(__tsover_mul(k,-1)),F=pe(__tsover_mul(k,2.39996)),q=ae(__tsover_mul(k,2.39996)),Y=m(__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(E,u),D),__tsover_mul(i.t,__tsover_mul(F,.3))),p),__tsover_add(__tsover_add(__tsover_mul(__tsover_mul(R,u),D),__tsover_mul(i.t,__tsover_mul(q,.3))),__tsover_mul(p,.7)));U=__tsover_add(U,__tsover_mul(la(Y),O))}_=__tsover_mul(U,r)}let f=__tsover_mul(__tsover_sub(l,.5),2),h=__tsover_mul(__tsover_sub(c,.5),2),g=be(.6,1,B(re(f),re(h))),y=K(n(1),__tsover_sub(1,g),i.edgePin),b=__tsover_mul(__tsover_mul(_,d),y);if(s){let x=n(0);if(i.cursorActive>.5){let P=n(3),C=__tsover_add(__tsover_div(__tsover_sub(a.x,.5),P),.5),E=__tsover_add(__tsover_div(__tsover_sub(a.y,.5),P),.5),R=n(od),U=__tsover_mul(G(C,0,1),R),L=__tsover_mul(G(E,0,1),R),k=M(G(U,0,R)),D=M(G(L,0,R)),O=ye(__tsover_add(k,M(1)),M(od)),F=ye(__tsover_add(D,M(1)),M(od)),q=__tsover_sub(U,ie(U)),Y=__tsover_sub(L,ie(L)),V=M(256),X=xn.$.readBuf[__tsover_add(__tsover_mul(D,V),k)],Q=xn.$.readBuf[__tsover_add(__tsover_mul(D,V),O)],te=xn.$.readBuf[__tsover_add(__tsover_mul(F,V),k)],J=xn.$.readBuf[__tsover_add(__tsover_mul(F,V),O)],oe=K(K(X,Q,q),K(te,J,q),Y);x=__tsover_mul(oe,__tsover_mul(i.cursorIntensity,.05))}return __tsover_add(b,x)}else return b}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"p\",[7,[7,\"heightFieldMarchLayout\",\"$\"],\"params\"]],[13,\"u\",[7,\"uv\",\"x\"]],[13,\"v\",[7,\"uv\",\"y\"]],[13,\"amp\",[7,\"p\",\"amp\"]],[13,\"freq\",[7,\"p\",\"freq\"]],[13,\"seedU\",[7,\"p\",\"seed\"]],[12,\"waveVal\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"waveType\",\"===\",[5,\"1\"]],[0,[[12,\"accSin\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"octaveCount\"],[102,\"++\",\"i\"],[0,[[13,\"iF\",[6,\"d.f32\",[\"i\"]]],[13,\"scale\",[6,\"std.exp2\",[\"iF\"]]],[13,\"weight\",[6,\"std.exp2\",[[1,\"iF\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"cu\",[6,\"std.cos\",[[1,\"iF\",\"*\",[5,\"1.111\"]]]]],[13,\"su\",[6,\"std.sin\",[[1,\"iF\",\"*\",[5,\"1.111\"]]]]],[13,\"ru\",[1,[1,\"u\",\"*\",\"cu\"],\"-\",[1,\"v\",\"*\",\"su\"]]],[13,\"phase\",[1,[1,[1,[1,[1,\"ru\",\"*\",\"freq\"],\"*\",\"scale\"],\"*\",\"TWO_PI\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[1,[5,\"1\"],\"+\",[1,\"iF\",\"*\",[5,\"0.2\"]]]]],\"+\",[1,\"seedU\",\"*\",[1,[5,\"1\"],\"+\",[1,\"iF\",\"*\",[5,\"0.5\"]]]]]],[2,\"accSin\",\"=\",[1,\"accSin\",\"+\",[1,[6,\"std.sin\",[\"phase\"]],\"*\",\"weight\"]]]]]],[2,\"waveVal\",\"=\",[1,\"accSin\",\"*\",\"invTotalWeight\"]]]],[11,[1,\"waveType\",\"===\",[5,\"2\"]],[0,[[12,\"accR\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"octaveCount\"],[102,\"++\",\"i\"],[0,[[13,\"iF\",[6,\"d.f32\",[\"i\"]]],[13,\"scale\",[6,\"std.exp2\",[\"iF\"]]],[13,\"weight\",[6,\"std.exp2\",[[1,\"iF\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"driftX\",[6,\"std.cos\",[[1,\"iF\",\"*\",[5,\"2.39996\"]]]]],[13,\"driftY\",[6,\"std.sin\",[[1,\"iF\",\"*\",[5,\"2.39996\"]]]]],[13,\"coord\",[6,\"d.vec2f\",[[1,[1,[1,[1,\"u\",\"*\",\"freq\"],\"*\",\"scale\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[1,\"driftX\",\"*\",[5,\"0.3\"]]]],\"+\",\"seedU\"],[1,[1,[1,[1,\"v\",\"*\",\"freq\"],\"*\",\"scale\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[1,\"driftY\",\"*\",[5,\"0.3\"]]]],\"+\",[1,\"seedU\",\"*\",[5,\"0.7\"]]]]]],[2,\"accR\",\"=\",[1,\"accR\",\"+\",[1,[6,\"noise.mxNoiseFloat2\",[\"coord\"]],\"*\",\"weight\"]]]]]],[13,\"n\",[1,\"accR\",\"*\",\"invTotalWeight\"]],[2,\"waveVal\",\"=\",[1,[1,[1,[5,\"1\"],\"-\",[6,\"std.abs\",[\"n\"]]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]]]],[0,[[13,\"warpFreq\",[1,\"freq\",\"*\",[5,\"0.5\"]]],[13,\"wx\",[6,\"noise.mxNoiseFloat2\",[[6,\"d.vec2f\",[[1,[1,[1,\"u\",\"*\",\"warpFreq\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[5,\"0.1\"]]],\"+\",\"seedU\"],[1,[1,\"v\",\"*\",\"warpFreq\"],\"+\",[1,\"seedU\",\"*\",[5,\"1.3\"]]]]]]]],[13,\"wy\",[6,\"noise.mxNoiseFloat2\",[[6,\"d.vec2f\",[[1,[1,[1,\"u\",\"*\",\"warpFreq\"],\"+\",\"seedU\"],\"+\",[5,\"17.3\"]],[1,[1,[1,[1,\"v\",\"*\",\"warpFreq\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[5,\"0.07\"]]],\"+\",\"seedU\"],\"+\",[5,\"31.1\"]]]]]]],[13,\"wu\",[1,\"u\",\"+\",[1,\"wx\",\"*\",[5,\"0.4\"]]]],[13,\"wv\",[1,\"v\",\"+\",[1,\"wy\",\"*\",[5,\"0.4\"]]]],[12,\"accW\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"octaveCount\"],[102,\"++\",\"i\"],[0,[[13,\"iF\",[6,\"d.f32\",[\"i\"]]],[13,\"scale\",[6,\"std.exp2\",[\"iF\"]]],[13,\"weight\",[6,\"std.exp2\",[[1,\"iF\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"driftX\",[6,\"std.cos\",[[1,\"iF\",\"*\",[5,\"2.39996\"]]]]],[13,\"driftY\",[6,\"std.sin\",[[1,\"iF\",\"*\",[5,\"2.39996\"]]]]],[13,\"coord\",[6,\"d.vec2f\",[[1,[1,[1,[1,\"wu\",\"*\",\"freq\"],\"*\",\"scale\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[1,\"driftX\",\"*\",[5,\"0.3\"]]]],\"+\",\"seedU\"],[1,[1,[1,[1,\"wv\",\"*\",\"freq\"],\"*\",\"scale\"],\"+\",[1,[7,\"p\",\"t\"],\"*\",[1,\"driftY\",\"*\",[5,\"0.3\"]]]],\"+\",[1,\"seedU\",\"*\",[5,\"0.7\"]]]]]],[2,\"accW\",\"=\",[1,\"accW\",\"+\",[1,[6,\"noise.mxNoiseFloat2\",[\"coord\"]],\"*\",\"weight\"]]]]]],[2,\"waveVal\",\"=\",[1,\"accW\",\"*\",\"invTotalWeight\"]]]]]],[13,\"cu\",[1,[1,\"u\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"cv\",[1,[1,\"v\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[13,\"inner\",[6,\"std.max\",[[6,\"std.abs\",[\"cu\"]],[6,\"std.abs\",[\"cv\"]]]]],[13,\"pinFalloff\",[6,\"std.smoothstep\",[[5,\"0.6\"],[5,\"1\"],\"inner\"]]],[13,\"pinMask\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],[1,[5,\"1\"],\"-\",\"pinFalloff\"],[7,\"p\",\"edgePin\"]]]],[13,\"baseHeight\",[1,[1,\"waveVal\",\"*\",\"amp\"],\"*\",\"pinMask\"]],[11,\"cursorEnabled\",[0,[[12,\"ripple\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,[7,\"p\",\"cursorActive\"],\">\",[5,\"0.5\"]],[0,[[13,\"H\",[6,\"d.f32\",[\"WAVE_HALFEXTENT\"]]],[13,\"waveU\",[1,[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"/\",\"H\"],\"+\",[5,\"0.5\"]]],[13,\"waveV\",[1,[1,[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]],\"/\",\"H\"],\"+\",[5,\"0.5\"]]],[13,\"Nm1\",[6,\"d.f32\",[\"WAVE_MAX\"]]],[13,\"gx\",[1,[6,\"std.clamp\",[\"waveU\",[5,\"0\"],[5,\"1\"]]],\"*\",\"Nm1\"]],[13,\"gy\",[1,[6,\"std.clamp\",[\"waveV\",[5,\"0\"],[5,\"1\"]]],\"*\",\"Nm1\"]],[13,\"ix\",[6,\"d.u32\",[[6,\"std.clamp\",[\"gx\",[5,\"0\"],\"Nm1\"]]]]],[13,\"iy\",[6,\"d.u32\",[[6,\"std.clamp\",[\"gy\",[5,\"0\"],\"Nm1\"]]]]],[13,\"ix1\",[6,\"std.min\",[[1,\"ix\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]],[6,\"d.u32\",[\"WAVE_MAX\"]]]]],[13,\"iy1\",[6,\"std.min\",[[1,\"iy\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]],[6,\"d.u32\",[\"WAVE_MAX\"]]]]],[13,\"fx\",[1,\"gx\",\"-\",[6,\"std.floor\",[\"gx\"]]]],[13,\"fy\",[1,\"gy\",\"-\",[6,\"std.floor\",[\"gy\"]]]],[13,\"W\",[6,\"d.u32\",[\"WAVE_GRID\"]]],[13,\"v00\",[8,[7,[7,\"heightFieldMarchLayout\",\"$\"],\"readBuf\"],[1,[1,\"iy\",\"*\",\"W\"],\"+\",\"ix\"]]],[13,\"v10\",[8,[7,[7,\"heightFieldMarchLayout\",\"$\"],\"readBuf\"],[1,[1,\"iy\",\"*\",\"W\"],\"+\",\"ix1\"]]],[13,\"v01\",[8,[7,[7,\"heightFieldMarchLayout\",\"$\"],\"readBuf\"],[1,[1,\"iy1\",\"*\",\"W\"],\"+\",\"ix\"]]],[13,\"v11\",[8,[7,[7,\"heightFieldMarchLayout\",\"$\"],\"readBuf\"],[1,[1,\"iy1\",\"*\",\"W\"],\"+\",\"ix1\"]]],[13,\"waveSample\",[6,\"std.mix\",[[6,\"std.mix\",[\"v00\",\"v10\",\"fx\"]],[6,\"std.mix\",[\"v01\",\"v11\",\"fx\"]],\"fy\"]]],[2,\"ripple\",\"=\",[1,\"waveSample\",\"*\",[1,[7,\"p\",\"cursorIntensity\"],\"*\",[5,\"0.05\"]]]]]]],[10,[1,\"baseHeight\",\"+\",\"ripple\"]]]],[0,[[10,\"baseHeight\"]]]]]]},externals:{heightFieldMarchLayout:()=>xn,\"d.f32\":()=>n,waveType:()=>e,octaveCount:()=>t,\"std.exp2\":()=>Ia,\"std.cos\":()=>pe,\"std.sin\":()=>ae,TWO_PI:()=>LP,invTotalWeight:()=>r,\"d.vec2f\":()=>m,\"noise.mxNoiseFloat2\":()=>la,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"std.mix\":()=>K,cursorEnabled:()=>s,WAVE_HALFEXTENT:()=>3,WAVE_MAX:()=>od,\"std.clamp\":()=>G,\"d.u32\":()=>M,\"std.min\":()=>ye,\"std.floor\":()=>ie,WAVE_GRID:()=>256}})&&o.f)({})).$name(\"spectralHeightField\")}function Dz(){return w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";if(t>M(0)&&t<M(od)&&s>M(0)&&s<M(od)){let r=bn.$.params,o=M(256),a=__tsover_add(__tsover_mul(s,o),t),i=bn.$.readSrc[__tsover_sub(a,M(1))],l=bn.$.readSrc[__tsover_add(a,M(1))],c=bn.$.readSrc[__tsover_sub(a,o)],d=bn.$.readSrc[__tsover_add(a,o)],u=bn.$.readSrc[a],p=__tsover_add(__tsover_add(__tsover_add(i,l),c),d),_=bn.$.writeBuf[a],f=__tsover_sub(1,__tsover_mul(r.decay,.004)),h=__tsover_mul(.5,__tsover_mul(r.waveSpeed,r.waveSpeed)),g=__tsover_sub(p,__tsover_mul(u,4)),y=__tsover_mul(__tsover_sub(__tsover_add(__tsover_mul(u,2),__tsover_mul(g,h)),_),f),b=__tsover_div(__tsover_add(n(t),.5),n(256)),x=__tsover_div(__tsover_add(n(s),.5),n(256)),P=__tsover_sub(b,r.cursorWaveX),C=__tsover_sub(x,r.cursorWaveY),E=__tsover_add(__tsover_mul(P,P),__tsover_mul(C,C)),R=__tsover_mul(r.radius,3);if(E<__tsover_mul(R,R)&&r.mouseSpeed>.01){let L=Tt(__tsover_mul(__tsover_div(E,B(__tsover_mul(r.radius,r.radius),n(1e-4))),-1));y=__tsover_sub(y,__tsover_mul(__tsover_mul(__tsover_mul(L,r.mouseSpeed),r.dt),3))}let U=n(6);y=G(y,__tsover_mul(U,-1),U),bn.$.writeBuf[a]=y,bn.$.readBuf[a]=y}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[11,[3,[3,[3,[1,\"cx\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],\"&&\",[1,\"cx\",\"<\",[6,\"d.u32\",[\"WAVE_MAX\"]]]],\"&&\",[1,\"cy\",\">\",[6,\"d.u32\",[[5,\"0\"]]]]],\"&&\",[1,\"cy\",\"<\",[6,\"d.u32\",[\"WAVE_MAX\"]]]],[0,[[13,\"p\",[7,[7,\"waveEquationLayout\",\"$\"],\"params\"]],[13,\"gs\",[6,\"d.u32\",[\"WAVE_GRID\"]]],[13,\"idx\",[1,[1,\"cy\",\"*\",\"gs\"],\"+\",\"cx\"]],[13,\"left\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readSrc\"],[1,\"idx\",\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"right\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readSrc\"],[1,\"idx\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"up\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readSrc\"],[1,\"idx\",\"-\",\"gs\"]]],[13,\"down\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readSrc\"],[1,\"idx\",\"+\",\"gs\"]]],[13,\"center\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readSrc\"],\"idx\"]],[13,\"sum\",[1,[1,[1,\"left\",\"+\",\"right\"],\"+\",\"up\"],\"+\",\"down\"]],[13,\"prev\",[8,[7,[7,\"waveEquationLayout\",\"$\"],\"writeBuf\"],\"idx\"]],[13,\"dampFactor\",[1,[5,\"1\"],\"-\",[1,[7,\"p\",\"decay\"],\"*\",\"WAVE_DECAY_PER_STEP\"]]],[13,\"k2\",[1,[5,\"0.5\"],\"*\",[1,[7,\"p\",\"waveSpeed\"],\"*\",[7,\"p\",\"waveSpeed\"]]]],[13,\"lap\",[1,\"sum\",\"-\",[1,\"center\",\"*\",[5,\"4\"]]]],[12,\"next\",[1,[1,[1,[1,\"center\",\"*\",[5,\"2\"]],\"+\",[1,\"lap\",\"*\",\"k2\"]],\"-\",\"prev\"],\"*\",\"dampFactor\"]],[13,\"cellU\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"WAVE_GRID\"]]]],[13,\"cellV\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"WAVE_GRID\"]]]],[13,\"ddx\",[1,\"cellU\",\"-\",[7,\"p\",\"cursorWaveX\"]]],[13,\"ddy\",[1,\"cellV\",\"-\",[7,\"p\",\"cursorWaveY\"]]],[13,\"distSq\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]],[13,\"influenceRadius\",[1,[7,\"p\",\"radius\"],\"*\",[5,\"3\"]]],[11,[3,[1,\"distSq\",\"<\",[1,\"influenceRadius\",\"*\",\"influenceRadius\"]],\"&&\",[1,[7,\"p\",\"mouseSpeed\"],\">\",[5,\"0.01\"]]],[0,[[13,\"influence\",[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",[6,\"std.max\",[[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]],[6,\"d.f32\",[[5,\"0.0001\"]]]]]],\"*\",[4,\"-\",[5,\"1\"]]]]]],[2,\"next\",\"=\",[1,\"next\",\"-\",[1,[1,[1,\"influence\",\"*\",[7,\"p\",\"mouseSpeed\"]],\"*\",[7,\"p\",\"dt\"]],\"*\",[5,\"3\"]]]]]]],[13,\"bound\",[6,\"d.f32\",[\"CURSOR_WAVE_BOUND\"]]],[2,\"next\",\"=\",[6,\"std.clamp\",[\"next\",[1,\"bound\",\"*\",[4,\"-\",[5,\"1\"]]],\"bound\"]]],[2,[8,[7,[7,\"waveEquationLayout\",\"$\"],\"writeBuf\"],\"idx\"],\"=\",\"next\"],[2,[8,[7,[7,\"waveEquationLayout\",\"$\"],\"readBuf\"],\"idx\"],\"=\",\"next\"]]]]]]},externals:{\"d.u32\":()=>M,WAVE_MAX:()=>od,waveEquationLayout:()=>bn,WAVE_GRID:()=>256,WAVE_DECAY_PER_STEP:()=>.004,\"d.f32\":()=>n,\"std.exp\":()=>Tt,\"std.max\":()=>B,CURSOR_WAVE_BOUND:()=>6,\"std.clamp\":()=>G}})&&e.f)({})).$name(\"waveEquationStep\")}function Lz(e){let{waveType:t,octaveCount:s,edgeMode:r,lightingEnabled:o,cursorEnabled:a,marchSteps:i,marchRefine:l,computeW:c,computeH:d}=e,u=bie(t,s,a);return w.fn([M,M])((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";let h=xn.$.params,g=__tsover_div(__tsover_add(n(_),.5),n(c)),y=__tsover_div(__tsover_add(n(f),.5),n(d)),b=__tsover_mul(__tsover_mul(__tsover_sub(g,.5),2),h.aspect),x=__tsover_mul(__tsover_mul(__tsover_sub(y,.5),2),-1),P=vs(h.camForward.mul(h.focal).add(h.camRight.mul(b)).add(h.camUp.mul(x))),C=h.heightEnvelope,E=N(n(-1),n(1),P.z>=0),R=__tsover_mul(E,B(re(P.z),n(1e-6))),U=__tsover_div(__tsover_sub(C,h.camPos.z),R),L=__tsover_div(__tsover_sub(__tsover_mul(C,-1),h.camPos.z),R),k=B(ye(U,L),n(0)),D=ye(B(U,L),n(15)),O=h.camPos.add(P.mul(n(15))),F=n(0),q=n(15),Y=__tsover_add(__tsover_mul(O.x,.5),.5),V=__tsover_add(__tsover_mul(O.y,.5),.5),X=A(1,1,1);if(D>k){let De=__tsover_div(__tsover_sub(D,k),n(i)),Ee=k,ze=h.camPos.add(P.mul(k)),Ie=__tsover_sub(ze.z,u(m(__tsover_add(__tsover_mul(ze.x,.5),.5),__tsover_add(__tsover_mul(ze.y,.5),.5))));for(let ke=0;ke<i;ke++){Ee=__tsover_add(Ee,De);let Me=h.camPos.add(P.mul(Ee)),we=u(m(__tsover_add(__tsover_mul(Me.x,.5),.5),__tsover_add(__tsover_mul(Me.y,.5),.5))),Ve=__tsover_sub(Me.z,we);if(Ve<0&&Ie>0){F=1;break}Ie=Ve}if(F>.5){let ke=__tsover_sub(Ee,De),Me=Ee;for(let Ve=0;Ve<l;Ve++){let qe=__tsover_mul(__tsover_add(ke,Me),.5),st=h.camPos.add(P.mul(qe));__tsover_sub(st.z,u(m(__tsover_add(__tsover_mul(st.x,.5),.5),__tsover_add(__tsover_mul(st.y,.5),.5))))>0?ke=qe:Me=qe}q=__tsover_mul(__tsover_add(ke,Me),.5);let we=h.camPos.add(P.mul(q));if(Y=__tsover_add(__tsover_mul(we.x,.5),.5),V=__tsover_add(__tsover_mul(we.y,.5),.5),o){let qe=u(m(Y,V)),st=u(m(__tsover_add(Y,.01),V)),pt=u(m(Y,__tsover_add(V,.01))),Ze=__tsover_div(__tsover_sub(st,qe),.01),nt=__tsover_div(__tsover_sub(pt,qe),.01),ht=vs(A(__tsover_mul(Ze,-.5),__tsover_mul(nt,-.5),1)),yt=vs(A(h.lightX,h.lightY,h.lightZ)),St=P.mul(-1),Mt=G(Se(ht,yt),0,1),Rt=vs(yt.add(St)),Kt=__tsover_add(__tsover_mul(h.glossiness,128),4),Wt=__tsover_mul(vt(G(Se(ht,Rt),0,1),Kt),h.highlights),ls=A(.4,.4,.4),us=h.lightColor.mul(__tsover_mul(Mt,.6)),os=h.lightColor.mul(Wt),bs=ls.add(us).add(os);X=G(K(A(1,1,1),bs,h.lighting),A(0,0,0),A(3,3,3))}}}let Q=m(Y,__tsover_sub(1,V)),te=m(Q.x,Q.y),J=n(1);if(r===2)te=Hm(Q);else if(r===3)te=jm(Q);else if(r===1){let De=Q.x>=0&&Q.x<=1&&Q.y>=0&&Q.y<=1;J=N(n(0),n(1),De)}else te=G(Q,m(0,0),m(1,1));let oe=n(15),le=.05,se=__tsover_mul(h.nearCutoff,oe),Te=__tsover_mul(h.farCutoff,oe),de=be(__tsover_sub(se,le),__tsover_add(se,le),q),xe=be(__tsover_add(Te,le),__tsover_sub(Te,le),q),Ae=__tsover_mul(__tsover_mul(F,J),__tsover_mul(de,xe));lt(xn.$.uvMaskTex,fe(_,f),S(te.x,te.y,Ae,0)),lt(xn.$.litTex,fe(_,f),S(X,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"heightFieldMarchLayout\",\"$\"],\"params\"]],[13,\"screenU\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"computeW\"]]]],[13,\"screenV\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"computeH\"]]]],[13,\"ndcX\",[1,[1,[1,\"screenU\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[7,\"p\",\"aspect\"]]],[13,\"ndcY\",[1,[1,[1,\"screenV\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"rayDir\",[6,\"std.normalize\",[[6,[7,[6,[7,[6,[7,[7,\"p\",\"camForward\"],\"mul\"],[[7,\"p\",\"focal\"]]],\"add\"],[[6,[7,[7,\"p\",\"camRight\"],\"mul\"],[\"ndcX\"]]]],\"add\"],[[6,[7,[7,\"p\",\"camUp\"],\"mul\"],[\"ndcY\"]]]]]]],[13,\"envelope\",[7,\"p\",\"heightEnvelope\"]],[13,\"dzSign\",[6,\"std.select\",[[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"rayDir\",\"z\"],\">=\",[5,\"0\"]]]]],[13,\"dzSafe\",[1,\"dzSign\",\"*\",[6,\"std.max\",[[6,\"std.abs\",[[7,\"rayDir\",\"z\"]]],[6,\"d.f32\",[[5,\"0.000001\"]]]]]]],[13,\"tTop\",[1,[1,\"envelope\",\"-\",[7,[7,\"p\",\"camPos\"],\"z\"]],\"/\",\"dzSafe\"]],[13,\"tBot\",[1,[1,[1,\"envelope\",\"*\",[4,\"-\",[5,\"1\"]]],\"-\",[7,[7,\"p\",\"camPos\"],\"z\"]],\"/\",\"dzSafe\"]],[13,\"tEnter\",[6,\"std.max\",[[6,\"std.min\",[\"tTop\",\"tBot\"]],[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"tExit\",[6,\"std.min\",[[6,\"std.max\",[\"tTop\",\"tBot\"]],[6,\"d.f32\",[\"MARCH_FAR\"]]]]],[13,\"farPos\",[6,[7,[7,\"p\",\"camPos\"],\"add\"],[[6,[7,\"rayDir\",\"mul\"],[[6,\"d.f32\",[\"MARCH_FAR\"]]]]]]],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"finalT\",[6,\"d.f32\",[\"MARCH_FAR\"]]],[12,\"hitU\",[1,[1,[7,\"farPos\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[12,\"hitV\",[1,[1,[7,\"farPos\",\"y\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[12,\"lit\",[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]],[11,[1,\"tExit\",\">\",\"tEnter\"],[0,[[13,\"stepSize\",[1,[1,\"tExit\",\"-\",\"tEnter\"],\"/\",[6,\"d.f32\",[\"marchSteps\"]]]],[12,\"tMarch\",\"tEnter\"],[13,\"pStart\",[6,[7,[7,\"p\",\"camPos\"],\"add\"],[[6,[7,\"rayDir\",\"mul\"],[\"tEnter\"]]]]],[12,\"prevDiff\",[1,[7,\"pStart\",\"z\"],\"-\",[6,\"heightFn\",[[6,\"d.vec2f\",[[1,[1,[7,\"pStart\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[7,\"pStart\",\"y\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]]],[14,[12,\"s\",[5,\"0\"]],[1,\"s\",\"<\",\"marchSteps\"],[102,\"++\",\"s\"],[0,[[2,\"tMarch\",\"=\",[1,\"tMarch\",\"+\",\"stepSize\"]],[13,\"pos\",[6,[7,[7,\"p\",\"camPos\"],\"add\"],[[6,[7,\"rayDir\",\"mul\"],[\"tMarch\"]]]]],[13,\"h\",[6,\"heightFn\",[[6,\"d.vec2f\",[[1,[1,[7,\"pos\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[7,\"pos\",\"y\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]],[13,\"diff\",[1,[7,\"pos\",\"z\"],\"-\",\"h\"]],[11,[3,[1,\"diff\",\"<\",[5,\"0\"]],\"&&\",[1,\"prevDiff\",\">\",[5,\"0\"]]],[0,[[2,\"hit\",\"=\",[5,\"1\"]],[17]]]],[2,\"prevDiff\",\"=\",\"diff\"]]]],[11,[1,\"hit\",\">\",[5,\"0.5\"]],[0,[[12,\"tLow\",[1,\"tMarch\",\"-\",\"stepSize\"]],[12,\"tHigh\",\"tMarch\"],[14,[12,\"r\",[5,\"0\"]],[1,\"r\",\"<\",\"marchRefine\"],[102,\"++\",\"r\"],[0,[[13,\"tMid\",[1,[1,\"tLow\",\"+\",\"tHigh\"],\"*\",[5,\"0.5\"]]],[13,\"pMid\",[6,[7,[7,\"p\",\"camPos\"],\"add\"],[[6,[7,\"rayDir\",\"mul\"],[\"tMid\"]]]]],[13,\"dMid\",[1,[7,\"pMid\",\"z\"],\"-\",[6,\"heightFn\",[[6,\"d.vec2f\",[[1,[1,[7,\"pMid\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]],[1,[1,[7,\"pMid\",\"y\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]]]]]]],[11,[1,\"dMid\",\">\",[5,\"0\"]],[0,[[2,\"tLow\",\"=\",\"tMid\"]]],[0,[[2,\"tHigh\",\"=\",\"tMid\"]]]]]]],[2,\"finalT\",\"=\",[1,[1,\"tLow\",\"+\",\"tHigh\"],\"*\",[5,\"0.5\"]]],[13,\"hitPos\",[6,[7,[7,\"p\",\"camPos\"],\"add\"],[[6,[7,\"rayDir\",\"mul\"],[\"finalT\"]]]]],[2,\"hitU\",\"=\",[1,[1,[7,\"hitPos\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[2,\"hitV\",\"=\",[1,[1,[7,\"hitPos\",\"y\"],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[11,\"lightingEnabled\",[0,[[13,\"normalEps\",[5,\"0.01\"]],[13,\"hC\",[6,\"heightFn\",[[6,\"d.vec2f\",[\"hitU\",\"hitV\"]]]]],[13,\"hR\",[6,\"heightFn\",[[6,\"d.vec2f\",[[1,\"hitU\",\"+\",\"normalEps\"],\"hitV\"]]]]],[13,\"hUp\",[6,\"heightFn\",[[6,\"d.vec2f\",[\"hitU\",[1,\"hitV\",\"+\",\"normalEps\"]]]]]],[13,\"dhdu\",[1,[1,\"hR\",\"-\",\"hC\"],\"/\",\"normalEps\"]],[13,\"dhdv\",[1,[1,\"hUp\",\"-\",\"hC\"],\"/\",\"normalEps\"]],[13,\"nrm\",[6,\"std.normalize\",[[6,\"d.vec3f\",[[1,\"dhdu\",\"*\",[4,\"-\",[5,\"0.5\"]]],[1,\"dhdv\",\"*\",[4,\"-\",[5,\"0.5\"]]],[5,\"1\"]]]]]],[13,\"lightDir\",[6,\"std.normalize\",[[6,\"d.vec3f\",[[7,\"p\",\"lightX\"],[7,\"p\",\"lightY\"],[7,\"p\",\"lightZ\"]]]]]],[13,\"viewDir\",[6,[7,\"rayDir\",\"mul\"],[[4,\"-\",[5,\"1\"]]]]],[13,\"diffuse\",[6,\"std.clamp\",[[6,\"std.dot\",[\"nrm\",\"lightDir\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"halfVec\",[6,\"std.normalize\",[[6,[7,\"lightDir\",\"add\"],[\"viewDir\"]]]]],[13,\"specPow\",[1,[1,[7,\"p\",\"glossiness\"],\"*\",[5,\"128\"]],\"+\",[5,\"4\"]]],[13,\"specular\",[1,[6,\"std.pow\",[[6,\"std.clamp\",[[6,\"std.dot\",[\"nrm\",\"halfVec\"]],[5,\"0\"],[5,\"1\"]]],\"specPow\"]],\"*\",[7,\"p\",\"highlights\"]]],[13,\"ambient\",[6,\"d.vec3f\",[[5,\"0.4\"],[5,\"0.4\"],[5,\"0.4\"]]]],[13,\"tintedDiffuse\",[6,[7,[7,\"p\",\"lightColor\"],\"mul\"],[[1,\"diffuse\",\"*\",[5,\"0.6\"]]]]],[13,\"tintedSpec\",[6,[7,[7,\"p\",\"lightColor\"],\"mul\"],[\"specular\"]]],[13,\"totalLight\",[6,[7,[6,[7,\"ambient\",\"add\"],[\"tintedDiffuse\"]],\"add\"],[\"tintedSpec\"]]],[2,\"lit\",\"=\",[6,\"std.clamp\",[[6,\"std.mix\",[[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"totalLight\",[7,\"p\",\"lighting\"]]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"3\"],[5,\"3\"],[5,\"3\"]]]]]]]]]]]]]]],[13,\"rawSampleUV\",[6,\"d.vec2f\",[\"hitU\",[1,[5,\"1\"],\"-\",\"hitV\"]]]],[12,\"finalUV\",[6,\"d.vec2f\",[[7,\"rawSampleUV\",\"x\"],[7,\"rawSampleUV\",\"y\"]]]],[12,\"outOfBoundsMask\",[6,\"d.f32\",[[5,\"1\"]]]],[11,[1,\"edgeMode\",\"===\",[5,\"2\"]],[0,[[2,\"finalUV\",\"=\",[6,\"edges.edgeMirrorUV\",[\"rawSampleUV\"]]]]],[11,[1,\"edgeMode\",\"===\",[5,\"3\"]],[0,[[2,\"finalUV\",\"=\",[6,\"edges.edgeWrapUV\",[\"rawSampleUV\"]]]]],[11,[1,\"edgeMode\",\"===\",[5,\"1\"]],[0,[[13,\"inside\",[3,[3,[3,[1,[7,\"rawSampleUV\",\"x\"],\">=\",[5,\"0\"]],\"&&\",[1,[7,\"rawSampleUV\",\"x\"],\"<=\",[5,\"1\"]]],\"&&\",[1,[7,\"rawSampleUV\",\"y\"],\">=\",[5,\"0\"]]],\"&&\",[1,[7,\"rawSampleUV\",\"y\"],\"<=\",[5,\"1\"]]]],[2,\"outOfBoundsMask\",\"=\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],\"inside\"]]]]],[0,[[2,\"finalUV\",\"=\",[6,\"std.clamp\",[\"rawSampleUV\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]]]]]]],[13,\"CUTOFF_RANGE\",[6,\"d.f32\",[\"MARCH_FAR\"]]],[13,\"edgeAA\",[5,\"0.05\"]],[13,\"nearT\",[1,[7,\"p\",\"nearCutoff\"],\"*\",\"CUTOFF_RANGE\"]],[13,\"farT\",[1,[7,\"p\",\"farCutoff\"],\"*\",\"CUTOFF_RANGE\"]],[13,\"nearMask\",[6,\"std.smoothstep\",[[1,\"nearT\",\"-\",\"edgeAA\"],[1,\"nearT\",\"+\",\"edgeAA\"],\"finalT\"]]],[13,\"farMask\",[6,\"std.smoothstep\",[[1,\"farT\",\"+\",\"edgeAA\"],[1,\"farT\",\"-\",\"edgeAA\"],\"finalT\"]]],[13,\"finalMask\",[1,[1,\"hit\",\"*\",\"outOfBoundsMask\"],\"*\",[1,\"nearMask\",\"*\",\"farMask\"]]],[6,\"std.textureStore\",[[7,[7,\"heightFieldMarchLayout\",\"$\"],\"uvMaskTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"finalUV\",\"x\"],[7,\"finalUV\",\"y\"],\"finalMask\",[5,\"0\"]]]]],[6,\"std.textureStore\",[[7,[7,\"heightFieldMarchLayout\",\"$\"],\"litTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"lit\",[5,\"0\"]]]]]]]},externals:{heightFieldMarchLayout:()=>xn,\"d.f32\":()=>n,computeW:()=>c,computeH:()=>d,\"std.normalize\":()=>vs,\"std.select\":()=>N,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.min\":()=>ye,MARCH_FAR:()=>15,\"d.vec3f\":()=>A,marchSteps:()=>i,heightFn:()=>u,\"d.vec2f\":()=>m,marchRefine:()=>l,lightingEnabled:()=>o,\"std.clamp\":()=>G,\"std.dot\":()=>Se,\"std.pow\":()=>vt,\"std.mix\":()=>K,edgeMode:()=>r,\"edges.edgeMirrorUV\":()=>Hm,\"edges.edgeWrapUV\":()=>jm,\"std.smoothstep\":()=>be,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&p.f)({})).$name(\"heightFieldMarch\")}function QA(e,t,s={}){let r=t;return wr(e,(o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";r(a,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"k\",[\"cx\",\"cy\"]]]]},externals:{k:()=>r}})&&o.f)({}),s)}function ai(e,t,s={}){return wr(e,(r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a)=>{\"use gpu\";t(o,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>t}})&&r.f)({}),{...s.size?{size:s.size}:{},...s.bindGroup?{bindGroup:s.bindGroup}:{}})}var xie=()=>gt({feed:n,kill:n,dv:n,brushRadSq:n,brushStrength:n,cursorX:n,cursorY:n,cursorActive:n,driveInfluence:n,driveContrast:n,driveThreshold:n,driveInvert:n,driveMapX:n,driveMapY:n,_pad0:n,_pad1:n}).$name(\"GrayScottParams\"),Aie=(e,t)=>w.bindGroupLayout({readBuf:{storage:Fe(m,e*e),access:\"readonly\"},writeBuf:{storage:Fe(m,e*e),access:\"mutable\"},params:{uniform:t}}),wie=(e,t)=>w.bindGroupLayout({readBuf:{storage:Fe(m,e*e),access:\"readonly\"},writeBuf:{storage:Fe(m,e*e),access:\"mutable\"},params:{uniform:t},driveTex:{texture:Zt(n)}});function ZA(e){let{n:t,namePrefix:s,drive:r}=e,o=xie(),a=r?\"Drive\":\"\",i=r?wie(t,o):Aie(t,o),l=r?i:null,c=w.fn([j,j,j,j],m)((_=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(_.f=((f,h,g,y)=>{\"use gpu\";let b=G(__tsover_add(f,g),0,__tsover_sub(t,1)),x=G(__tsover_add(h,y),0,__tsover_sub(t,1));return i.$.readBuf[M(__tsover_add(__tsover_mul(b,t),x))]}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"ii\"},{type:\"i\",name:\"ji\"},{type:\"i\",name:\"di\"},{type:\"i\",name:\"dj\"}],body:[0,[[13,\"row\",[6,\"std.clamp\",[[1,\"ii\",\"+\",\"di\"],[5,\"0\"],[1,\"n\",\"-\",[5,\"1\"]]]]],[13,\"col\",[6,\"std.clamp\",[[1,\"ji\",\"+\",\"dj\"],[5,\"0\"],[1,\"n\",\"-\",[5,\"1\"]]]]],[10,[8,[7,[7,\"layout\",\"$\"],\"readBuf\"],[6,\"d.u32\",[[1,[1,\"row\",\"*\",\"n\"],\"+\",\"col\"]]]]]]]},externals:{\"std.clamp\":()=>G,n:()=>t,layout:()=>i,\"d.u32\":()=>M}})&&_.f)({})).$name(`${s}Nbr${a}`),d=r&&l?w.fn([M,M],n)((_=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(_.f=((f,h)=>{\"use gpu\";let g=l.$.params,y=Ti(l.$.driveTex),b=n(y.x),x=n(y.y),P=__tsover_div(__tsover_add(n(f),.5),n(t)),C=__tsover_div(__tsover_add(n(h),.5),n(t)),E=G(__tsover_add(__tsover_mul(__tsover_sub(P,.5),g.driveMapX),.5),n(0),n(1)),R=G(__tsover_add(__tsover_mul(__tsover_sub(C,.5),g.driveMapY),.5),n(0),n(1)),U=M(ye(__tsover_mul(E,b),__tsover_sub(b,1))),L=M(ye(__tsover_mul(R,x),__tsover_sub(x,1))),k=Ye(l.$.driveTex,fe(U,L),0),D=G(k.w,n(0),n(1)),O=Se(k.xyz.div(B(k.w,n(.001))),A(.2126,.7152,.0722)),F=__tsover_add(n(1),__tsover_mul(g.driveContrast,n(r.contrastMax))),q=G(__tsover_add(__tsover_mul(__tsover_sub(O,g.driveThreshold),F),.5),n(0),n(1)),Y=__tsover_mul(__tsover_sub(q,.5),2);return Y=N(Y,__tsover_mul(Y,-1),g.driveInvert>.5),__tsover_mul(Y,D)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"driveLayout\",\"$\"],\"params\"]],[13,\"dims\",[6,\"std.textureDimensions\",[[7,[7,\"driveLayout\",\"$\"],\"driveTex\"]]]],[13,\"fw\",[6,\"d.f32\",[[7,\"dims\",\"x\"]]]],[13,\"fh\",[6,\"d.f32\",[[7,\"dims\",\"y\"]]]],[13,\"fx\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"fy\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"n\"]]]],[13,\"cu\",[6,\"std.clamp\",[[1,[1,[1,\"fx\",\"-\",[5,\"0.5\"]],\"*\",[7,\"p\",\"driveMapX\"]],\"+\",[5,\"0.5\"]],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"cv\",[6,\"std.clamp\",[[1,[1,[1,\"fy\",\"-\",[5,\"0.5\"]],\"*\",[7,\"p\",\"driveMapY\"]],\"+\",[5,\"0.5\"]],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"px\",[6,\"d.u32\",[[6,\"std.min\",[[1,\"cu\",\"*\",\"fw\"],[1,\"fw\",\"-\",[5,\"1\"]]]]]]],[13,\"py\",[6,\"d.u32\",[[6,\"std.min\",[[1,\"cv\",\"*\",\"fh\"],[1,\"fh\",\"-\",[5,\"1\"]]]]]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"driveLayout\",\"$\"],\"driveTex\"],[6,\"d.vec2u\",[\"px\",\"py\"]],[5,\"0\"]]]],[13,\"cov\",[6,\"std.clamp\",[[7,\"texel\",\"w\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"rgb\",[6,[7,[7,\"texel\",\"xyz\"],\"div\"],[[6,\"std.max\",[[7,\"texel\",\"w\"],[6,\"d.f32\",[[5,\"0.001\"]]]]]]]],[13,\"luma\",[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.2126\"],[5,\"0.7152\"],[5,\"0.0722\"]]]]]],[13,\"gain\",[1,[6,\"d.f32\",[[5,\"1\"]]],\"+\",[1,[7,\"p\",\"driveContrast\"],\"*\",[6,\"d.f32\",[\"drive.contrastMax\"]]]]],[13,\"shaped\",[6,\"std.clamp\",[[1,[1,[1,\"luma\",\"-\",[7,\"p\",\"driveThreshold\"]],\"*\",\"gain\"],\"+\",[5,\"0.5\"]],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]],[12,\"signed\",[1,[1,\"shaped\",\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]]],[2,\"signed\",\"=\",[6,\"std.select\",[\"signed\",[1,\"signed\",\"*\",[4,\"-\",[5,\"1\"]]],[1,[7,\"p\",\"driveInvert\"],\">\",[5,\"0.5\"]]]]],[10,[1,\"signed\",\"*\",\"cov\"]]]]},externals:{driveLayout:()=>l,\"std.textureDimensions\":()=>Ti,\"d.f32\":()=>n,n:()=>t,\"std.clamp\":()=>G,\"d.u32\":()=>M,\"std.min\":()=>ye,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.max\":()=>B,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"drive.contrastMax\":()=>r.contrastMax,\"std.select\":()=>N}})&&_.f)({})).$name(`${s}DriveMap`):null,p=r&&d?((_,f)=>w.fn([n,n,M,M],m)((h=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(h.f=((g,y,b,x)=>{\"use gpu\";let P=__tsover_mul(f(b,x),i.$.params.driveInfluence);return m(G(__tsover_add(g,__tsover_mul(P,n(_.dFeed))),n(_.feedMin),n(_.feedMax)),G(__tsover_sub(y,__tsover_mul(P,n(_.dKill))),n(_.killMin),n(_.killMax)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"feed\"},{type:\"i\",name:\"kill\"},{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"mod\",[1,[6,\"dm\",[\"cx\",\"cy\"]],\"*\",[7,[7,[7,\"layout\",\"$\"],\"params\"],\"driveInfluence\"]]],[10,[6,\"d.vec2f\",[[6,\"std.clamp\",[[1,\"feed\",\"+\",[1,\"mod\",\"*\",[6,\"d.f32\",[\"drv.dFeed\"]]]],[6,\"d.f32\",[\"drv.feedMin\"]],[6,\"d.f32\",[\"drv.feedMax\"]]]],[6,\"std.clamp\",[[1,\"kill\",\"-\",[1,\"mod\",\"*\",[6,\"d.f32\",[\"drv.dKill\"]]]],[6,\"d.f32\",[\"drv.killMin\"]],[6,\"d.f32\",[\"drv.killMax\"]]]]]]]]]},externals:{dm:()=>f,layout:()=>i,\"d.vec2f\":()=>m,\"std.clamp\":()=>G,\"d.f32\":()=>n,\"drv.dFeed\":()=>_.dFeed,\"drv.feedMin\":()=>_.feedMin,\"drv.feedMax\":()=>_.feedMax,\"drv.dKill\":()=>_.dKill,\"drv.killMin\":()=>_.killMin,\"drv.killMax\":()=>_.killMax}})&&h.f)({})).$name(`${s}Rates${a}`))(r,d):w.fn([n,n,M,M],m)((_=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(_.f=((f,h)=>{\"use gpu\";return m(f,h)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"feed\"},{type:\"i\",name:\"kill\"}],body:[0,[[10,[6,\"d.vec2f\",[\"feed\",\"kill\"]]]]]},externals:{\"d.vec2f\":()=>m}})&&_.f)({})).$name(`${s}Rates`);return{layout:i,Params:o,kernel:w.fn([M,M])((_=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(_.f=((f,h)=>{\"use gpu\";let g=i.$.params,y=__tsover_add(__tsover_mul(h,M(t)),f),b=i.$.readBuf[y],x=j(h),P=j(f),C=c(x,P,0,-1),E=c(x,P,0,1),R=c(x,P,-1,0),U=c(x,P,1,0),L=c(x,P,-1,-1),k=c(x,P,-1,1),D=c(x,P,1,-1),O=c(x,P,1,1),F=__tsover_sub(__tsover_add(__tsover_mul(__tsover_add(__tsover_add(__tsover_add(C.x,E.x),R.x),U.x),.2),__tsover_mul(__tsover_add(__tsover_add(__tsover_add(L.x,k.x),D.x),O.x),.05)),b.x),q=__tsover_sub(__tsover_add(__tsover_mul(__tsover_add(__tsover_add(__tsover_add(C.y,E.y),R.y),U.y),.2),__tsover_mul(__tsover_add(__tsover_add(__tsover_add(L.y,k.y),D.y),O.y),.05)),b.y),Y=p(g.feed,g.kill,f,h),V=Y.x,X=Y.y,Q=b.x,te=b.y,J=__tsover_mul(__tsover_mul(Q,te),te),oe=__tsover_add(Q,__tsover_add(__tsover_sub(F,J),__tsover_mul(V,__tsover_sub(1,Q)))),le=__tsover_add(te,__tsover_sub(__tsover_add(__tsover_mul(g.dv,q),J),__tsover_mul(__tsover_add(V,X),te)));if(g.cursorActive>0){let se=__tsover_add(n(f),.5),Te=__tsover_add(n(h),.5),de=__tsover_sub(se,g.cursorX),xe=__tsover_sub(Te,g.cursorY),Ae=__tsover_add(__tsover_mul(de,de),__tsover_mul(xe,xe)),De=__tsover_mul(Tt(__tsover_mul(__tsover_div(Ae,B(g.brushRadSq,n(1))),-1)),g.cursorActive);le=ye(__tsover_add(le,__tsover_mul(De,g.brushStrength)),n(1))}oe=G(oe,0,1),le=G(le,0,1),i.$.writeBuf[y]=m(oe,le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"self\",[8,[7,[7,\"layout\",\"$\"],\"readBuf\"],\"idx\"]],[13,\"ii\",[6,\"d.i32\",[\"cy\"]]],[13,\"ji\",[6,\"d.i32\",[\"cx\"]]],[13,\"L\",[6,\"nbr\",[\"ii\",\"ji\",[5,\"0\"],[4,\"-\",[5,\"1\"]]]]],[13,\"R\",[6,\"nbr\",[\"ii\",\"ji\",[5,\"0\"],[5,\"1\"]]]],[13,\"T\",[6,\"nbr\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"0\"]]]],[13,\"B\",[6,\"nbr\",[\"ii\",\"ji\",[5,\"1\"],[5,\"0\"]]]],[13,\"TL\",[6,\"nbr\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[4,\"-\",[5,\"1\"]]]]],[13,\"TR\",[6,\"nbr\",[\"ii\",\"ji\",[4,\"-\",[5,\"1\"]],[5,\"1\"]]]],[13,\"BL\",[6,\"nbr\",[\"ii\",\"ji\",[5,\"1\"],[4,\"-\",[5,\"1\"]]]]],[13,\"BR\",[6,\"nbr\",[\"ii\",\"ji\",[5,\"1\"],[5,\"1\"]]]],[13,\"lapU\",[1,[1,[1,[1,[1,[1,[7,\"L\",\"x\"],\"+\",[7,\"R\",\"x\"]],\"+\",[7,\"T\",\"x\"]],\"+\",[7,\"B\",\"x\"]],\"*\",[5,\"0.2\"]],\"+\",[1,[1,[1,[1,[7,\"TL\",\"x\"],\"+\",[7,\"TR\",\"x\"]],\"+\",[7,\"BL\",\"x\"]],\"+\",[7,\"BR\",\"x\"]],\"*\",[5,\"0.05\"]]],\"-\",[7,\"self\",\"x\"]]],[13,\"lapV\",[1,[1,[1,[1,[1,[1,[7,\"L\",\"y\"],\"+\",[7,\"R\",\"y\"]],\"+\",[7,\"T\",\"y\"]],\"+\",[7,\"B\",\"y\"]],\"*\",[5,\"0.2\"]],\"+\",[1,[1,[1,[1,[7,\"TL\",\"y\"],\"+\",[7,\"TR\",\"y\"]],\"+\",[7,\"BL\",\"y\"]],\"+\",[7,\"BR\",\"y\"]],\"*\",[5,\"0.05\"]]],\"-\",[7,\"self\",\"y\"]]],[13,\"fk\",[6,\"rates\",[[7,\"p\",\"feed\"],[7,\"p\",\"kill\"],\"cx\",\"cy\"]]],[13,\"feedCell\",[7,\"fk\",\"x\"]],[13,\"killCell\",[7,\"fk\",\"y\"]],[13,\"U\",[7,\"self\",\"x\"]],[13,\"V\",[7,\"self\",\"y\"]],[13,\"uvv\",[1,[1,\"U\",\"*\",\"V\"],\"*\",\"V\"]],[12,\"newU\",[1,\"U\",\"+\",[1,[1,\"lapU\",\"-\",\"uvv\"],\"+\",[1,\"feedCell\",\"*\",[1,[5,\"1\"],\"-\",\"U\"]]]]],[12,\"newV\",[1,\"V\",\"+\",[1,[1,[1,[7,\"p\",\"dv\"],\"*\",\"lapV\"],\"+\",\"uvv\"],\"-\",[1,[1,\"feedCell\",\"+\",\"killCell\"],\"*\",\"V\"]]]],[11,[1,[7,\"p\",\"cursorActive\"],\">\",[5,\"0\"]],[0,[[13,\"cellX\",[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]]],[13,\"cellY\",[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]]],[13,\"dxp\",[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]]],[13,\"dyp\",[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]]],[13,\"distSq\",[1,[1,\"dxp\",\"*\",\"dxp\"],\"+\",[1,\"dyp\",\"*\",\"dyp\"]]],[13,\"inf\",[1,[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",[6,\"std.max\",[[7,\"p\",\"brushRadSq\"],[6,\"d.f32\",[[5,\"1\"]]]]]],\"*\",[4,\"-\",[5,\"1\"]]]]],\"*\",[7,\"p\",\"cursorActive\"]]],[2,\"newV\",\"=\",[6,\"std.min\",[[1,\"newV\",\"+\",[1,\"inf\",\"*\",[7,\"p\",\"brushStrength\"]]],[6,\"d.f32\",[[5,\"1\"]]]]]]]]],[2,\"newU\",\"=\",[6,\"std.clamp\",[\"newU\",[5,\"0\"],[5,\"1\"]]]],[2,\"newV\",\"=\",[6,\"std.clamp\",[\"newV\",[5,\"0\"],[5,\"1\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"writeBuf\"],\"idx\"],\"=\",[6,\"d.vec2f\",[\"newU\",\"newV\"]]]]]},externals:{layout:()=>i,\"d.u32\":()=>M,n:()=>t,\"d.i32\":()=>j,nbr:()=>c,rates:()=>p,\"d.f32\":()=>n,\"std.exp\":()=>Tt,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.clamp\":()=>G,\"d.vec2f\":()=>m}})&&_.f)({})).$name(`${s}React${a}`)}}function Uz(e){let{n:t,density:s,namePrefix:r}=e,o=(globalThis.__TYPEGPU_AUTONAME__??(a=>a))(w.bindGroupLayout({stateBuf:{storage:Fe(m,t*t),access:\"mutable\"}}),\"layout\");return{layout:o,kernel:w.fn([M,M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";let c=__tsover_add(__tsover_mul(l,M(t)),i),d=Ys(m(n(i),n(l))),u=N(n(0),n(1),d<s);o.$.stateBuf[c]=m(1,u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"h\",[6,\"noise.hash12\",[[6,\"d.vec2f\",[[6,\"d.f32\",[\"cx\"]],[6,\"d.f32\",[\"cy\"]]]]]]],[13,\"vSeed\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"h\",\"<\",\"density\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"stateBuf\"],\"idx\"],\"=\",[6,\"d.vec2f\",[[5,\"1\"],\"vSeed\"]]]]]},externals:{\"d.u32\":()=>M,n:()=>t,\"noise.hash12\":()=>Ys,\"d.vec2f\":()=>m,\"d.f32\":()=>n,\"std.select\":()=>N,density:()=>s,layout:()=>o}})&&a.f)({})).$name(`${r}Seed`)}}function Oz(e){let{n:t,format:s,namePrefix:r}=e,o=(globalThis.__TYPEGPU_AUTONAME__??(a=>a))(w.bindGroupLayout({srcBuf:{storage:Fe(m,t*t),access:\"readonly\"},outTex:{storageTexture:zt(s,\"write-only\")}}),\"layout\");return{layout:o,kernel:w.fn([M,M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";let c=__tsover_add(__tsover_mul(l,M(t)),i),d=o.$.srcBuf[c];lt(o.$.outTex,fe(i,l),S(d.x,d.y,0,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"s\",[8,[7,[7,\"layout\",\"$\"],\"srcBuf\"],\"idx\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"s\",\"x\"],[7,\"s\",\"y\"],[5,\"0\"],[5,\"0\"]]]]]]]},externals:{\"d.u32\":()=>M,n:()=>t,layout:()=>o,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&a.f)({})).$name(`${r}Output`)}}var OP=new Map;function Tie(e){return w.fn([n,n,n,n,n,n,n],n)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o,a,i,l,c)=>{\"use gpu\";let d=__tsover_sub(__tsover_div(s,e),o),u=__tsover_sub(__tsover_div(r,e),a),p=N(d,__tsover_mul(d,c),c>=1),_=N(__tsover_div(u,c),u,c>=1),f=Ue(__tsover_add(__tsover_mul(p,p),__tsover_mul(_,_))),h=__tsover_mul(i,__tsover_sub(1,l));return __tsover_sub(1,be(h,i,f))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cxf\"},{type:\"i\",name:\"cyf\"},{type:\"i\",name:\"mouseX\"},{type:\"i\",name:\"mouseY\"},{type:\"i\",name:\"radius\"},{type:\"i\",name:\"falloff\"},{type:\"i\",name:\"aspect\"}],body:[0,[[13,\"dx\",[1,[1,\"cxf\",\"/\",\"n\"],\"-\",\"mouseX\"]],[13,\"dy\",[1,[1,\"cyf\",\"/\",\"n\"],\"-\",\"mouseY\"]],[13,\"ddx\",[6,\"std.select\",[\"dx\",[1,\"dx\",\"*\",\"aspect\"],[1,\"aspect\",\">=\",[5,\"1\"]]]]],[13,\"ddy\",[6,\"std.select\",[[1,\"dy\",\"/\",\"aspect\"],\"dy\",[1,\"aspect\",\">=\",[5,\"1\"]]]]],[13,\"dist\",[6,\"std.sqrt\",[[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]]]],[13,\"inner\",[1,\"radius\",\"*\",[1,[5,\"1\"],\"-\",\"falloff\"]]],[10,[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"inner\",\"radius\",\"dist\"]]]]]]},externals:{n:()=>e,\"std.select\":()=>N,\"std.sqrt\":()=>Ue,\"std.smoothstep\":()=>be}})&&t.f)({})).$name(\"aspectBrushWeight\")}function Sie(e){let t=OP.get(e);if(t)return t;let s=Tie(e);return OP.set(e,s),s}function Gz(e){let{n:t,format:s,namePrefix:r,vertical:o,direction:a}=e,i=t*t,l=t,c=t-1,d=gt({inputWidth:n,inputHeight:n}).$name(\"SortKeyParams\"),u=gt({mouseX:n,mouseY:n,radius:n,falloff:n,decay:n,aspect:n,seed:n}).$name(\"SortSwapParams\"),p=(globalThis.__TYPEGPU_AUTONAME__??(x=>x))(w.bindGroupLayout({input:{texture:Zt(n)},lumaBuf:{storage:Fe(n,i),access:\"mutable\"},params:{uniform:d}}),\"lumaLayout\"),_=(globalThis.__TYPEGPU_AUTONAME__??(x=>x))(w.bindGroupLayout({readBuf:{storage:Fe(n,i),access:\"readonly\"},writeBuf:{storage:Fe(n,i),access:\"mutable\"},lumaBuf:{storage:Fe(n,i),access:\"readonly\"},params:{uniform:u}}),\"swapLayout\"),f=(globalThis.__TYPEGPU_AUTONAME__??(x=>x))(w.bindGroupLayout({srcBuf:{storage:Fe(n,i),access:\"readonly\"},stateTex:{storageTexture:zt(s,\"write-only\")}}),\"outputLayout\"),h=Sie(t),g=w.fn([M,M])((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=p.$.params,R=__tsover_add(__tsover_mul(C,M(t)),P),U=__tsover_div(__tsover_add(n(P),.5),l),L=__tsover_div(__tsover_add(n(C),.5),l),k=G(j(Ut(__tsover_mul(U,E.inputWidth))),0,j(__tsover_sub(E.inputWidth,1))),D=G(j(Ut(__tsover_mul(L,E.inputHeight))),0,j(__tsover_sub(E.inputHeight,1))),O=Yt(Ye(p.$.input,fe(M(k),M(D)),0)).xyz;p.$.lumaBuf[R]=Se(O,A(.299,.587,.114))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"lumaLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"nF\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"nF\"]],[13,\"ix\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"u\",\"*\",[7,\"p\",\"inputWidth\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]]]],[13,\"iy\",[6,\"std.clamp\",[[6,\"d.i32\",[[6,\"std.round\",[[1,\"v\",\"*\",[7,\"p\",\"inputHeight\"]]]]]],[5,\"0\"],[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"lumaLayout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"ix\"]],[6,\"d.u32\",[\"iy\"]]]],[5,\"0\"]]]],[13,\"rgb\",[7,[6,\"blend.unpremultiplyAlpha\",[\"texel\"]],\"xyz\"]],[2,[8,[7,[7,\"lumaLayout\",\"$\"],\"lumaBuf\"],\"idx\"],\"=\",[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]]]]},externals:{lumaLayout:()=>p,\"d.u32\":()=>M,n:()=>t,\"d.f32\":()=>n,nF:()=>l,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.round\":()=>Ut,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"blend.unpremultiplyAlpha\":()=>Yt,\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&x.f)({})).$name(`${r}Luma`),y=x=>w.fn([M,M])((P=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(P.f=((C,E)=>{\"use gpu\";let R=_.$.params,U=__tsover_add(__tsover_mul(E,M(t)),C),L=n(C),k=n(E),D=o?E:C,O=o?C:E,F=n(D),q=j(D),Y=_.$.readBuf[U],V=G(__tsover_add(F,Y),0,c),X=__tsover_mod(__tsover_add(D,M(x)),M(2))===M(0),Q=N(__tsover_sub(q,1),__tsover_add(q,1),X),te=Q>=0&&Q<t,J=G(Q,0,__tsover_sub(t,1)),oe=M(J),le=o?O:oe,se=o?oe:O,Te=__tsover_add(__tsover_mul(se,M(t)),le),de=_.$.readBuf[Te],xe=G(__tsover_add(n(J),de),0,c),Ae=G(ie(V),0,c),De=ye(__tsover_add(Ae,1),c),Ee=o?__tsover_add(__tsover_mul(M(Ae),M(t)),O):__tsover_add(__tsover_mul(O,M(t)),M(Ae)),ze=o?__tsover_add(__tsover_mul(M(De),M(t)),O):__tsover_add(__tsover_mul(O,M(t)),M(De)),Ie=K(_.$.lumaBuf[Ee],_.$.lumaBuf[ze],__tsover_sub(V,Ae)),ke=G(ie(xe),0,c),Me=ye(__tsover_add(ke,1),c),we=o?__tsover_add(__tsover_mul(M(ke),M(t)),O):__tsover_add(__tsover_mul(O,M(t)),M(ke)),Ve=o?__tsover_add(__tsover_mul(M(Me),M(t)),O):__tsover_add(__tsover_mul(O,M(t)),M(Me)),qe=K(_.$.lumaBuf[we],_.$.lumaBuf[Ve],__tsover_sub(xe,ke)),st=h(L,k,R.mouseX,R.mouseY,R.radius,R.falloff,R.aspect),pt=h(n(le),n(se),R.mouseX,R.mouseY,R.radius,R.falloff,R.aspect),Ze=Wb(A(L,k,R.seed)),nt=te&&ye(st,pt)>Ze,ht=__tsover_mul(__tsover_sub(Ie,qe),a),yt=N(ht<0,ht>0,X),St=K(N(V,xe,nt&&yt),F,R.decay);_.$.writeBuf[U]=__tsover_sub(St,F)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"swapLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"xf\",[6,\"d.f32\",[\"cx\"]]],[13,\"yf\",[6,\"d.f32\",[\"cy\"]]],[13,\"lineC\",[105,\"vertical\",\"cy\",\"cx\"]],[13,\"fixedC\",[105,\"vertical\",\"cx\",\"cy\"]],[13,\"lineCf\",[6,\"d.f32\",[\"lineC\"]]],[13,\"lineCi\",[6,\"d.i32\",[\"lineC\"]]],[13,\"myOff\",[8,[7,[7,\"swapLayout\",\"$\"],\"readBuf\"],\"idx\"]],[13,\"myCol\",[6,\"std.clamp\",[[1,\"lineCf\",\"+\",\"myOff\"],[5,\"0\"],\"maxC\"]]],[13,\"isLeft\",[1,[1,[1,\"lineC\",\"+\",[6,\"d.u32\",[\"parity\"]]],\"%\",[6,\"d.u32\",[[5,\"2\"]]]],\"===\",[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"partnerLineI\",[6,\"std.select\",[[1,\"lineCi\",\"-\",[5,\"1\"]],[1,\"lineCi\",\"+\",[5,\"1\"]],\"isLeft\"]]],[13,\"valid\",[3,[1,\"partnerLineI\",\">=\",[5,\"0\"]],\"&&\",[1,\"partnerLineI\",\"<\",\"n\"]]],[13,\"pClamped\",[6,\"std.clamp\",[\"partnerLineI\",[5,\"0\"],[1,\"n\",\"-\",[5,\"1\"]]]]],[13,\"pClampedU\",[6,\"d.u32\",[\"pClamped\"]]],[13,\"partnerX\",[105,\"vertical\",\"fixedC\",\"pClampedU\"]],[13,\"partnerY\",[105,\"vertical\",\"pClampedU\",\"fixedC\"]],[13,\"partnerIdx\",[1,[1,\"partnerY\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"partnerX\"]],[13,\"partnerOff\",[8,[7,[7,\"swapLayout\",\"$\"],\"readBuf\"],\"partnerIdx\"]],[13,\"partnerCol\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"pClamped\"]],\"+\",\"partnerOff\"],[5,\"0\"],\"maxC\"]]],[13,\"myC0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"myCol\"]],[5,\"0\"],\"maxC\"]]],[13,\"myC1\",[6,\"std.min\",[[1,\"myC0\",\"+\",[5,\"1\"]],\"maxC\"]]],[13,\"myIdx0\",[105,\"vertical\",[1,[1,[6,\"d.u32\",[\"myC0\"]],\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"fixedC\"],[1,[1,\"fixedC\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",[6,\"d.u32\",[\"myC0\"]]]]],[13,\"myIdx1\",[105,\"vertical\",[1,[1,[6,\"d.u32\",[\"myC1\"]],\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"fixedC\"],[1,[1,\"fixedC\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",[6,\"d.u32\",[\"myC1\"]]]]],[13,\"myKey\",[6,\"std.mix\",[[8,[7,[7,\"swapLayout\",\"$\"],\"lumaBuf\"],\"myIdx0\"],[8,[7,[7,\"swapLayout\",\"$\"],\"lumaBuf\"],\"myIdx1\"],[1,\"myCol\",\"-\",\"myC0\"]]]],[13,\"pC0\",[6,\"std.clamp\",[[6,\"std.floor\",[\"partnerCol\"]],[5,\"0\"],\"maxC\"]]],[13,\"pC1\",[6,\"std.min\",[[1,\"pC0\",\"+\",[5,\"1\"]],\"maxC\"]]],[13,\"pIdx0\",[105,\"vertical\",[1,[1,[6,\"d.u32\",[\"pC0\"]],\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"fixedC\"],[1,[1,\"fixedC\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",[6,\"d.u32\",[\"pC0\"]]]]],[13,\"pIdx1\",[105,\"vertical\",[1,[1,[6,\"d.u32\",[\"pC1\"]],\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"fixedC\"],[1,[1,\"fixedC\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",[6,\"d.u32\",[\"pC1\"]]]]],[13,\"partnerKey\",[6,\"std.mix\",[[8,[7,[7,\"swapLayout\",\"$\"],\"lumaBuf\"],\"pIdx0\"],[8,[7,[7,\"swapLayout\",\"$\"],\"lumaBuf\"],\"pIdx1\"],[1,\"partnerCol\",\"-\",\"pC0\"]]]],[13,\"wMy\",[6,\"brushWeight\",[\"xf\",\"yf\",[7,\"p\",\"mouseX\"],[7,\"p\",\"mouseY\"],[7,\"p\",\"radius\"],[7,\"p\",\"falloff\"],[7,\"p\",\"aspect\"]]]],[13,\"wP\",[6,\"brushWeight\",[[6,\"d.f32\",[\"partnerX\"]],[6,\"d.f32\",[\"partnerY\"]],[7,\"p\",\"mouseX\"],[7,\"p\",\"mouseY\"],[7,\"p\",\"radius\"],[7,\"p\",\"falloff\"],[7,\"p\",\"aspect\"]]]],[13,\"rnd\",[6,\"noise.hash13\",[[6,\"d.vec3f\",[\"xf\",\"yf\",[7,\"p\",\"seed\"]]]]]],[13,\"gate\",[3,\"valid\",\"&&\",[1,[6,\"std.min\",[\"wMy\",\"wP\"]],\">\",\"rnd\"]]],[13,\"keyDiff\",[1,[1,\"myKey\",\"-\",\"partnerKey\"],\"*\",\"direction\"]],[13,\"takePartner\",[6,\"std.select\",[[1,\"keyDiff\",\"<\",[5,\"0\"]],[1,\"keyDiff\",\">\",[5,\"0\"]],\"isLeft\"]]],[13,\"newCol\",[6,\"std.select\",[\"myCol\",\"partnerCol\",[3,\"gate\",\"&&\",\"takePartner\"]]]],[13,\"decayed\",[6,\"std.mix\",[\"newCol\",\"lineCf\",[7,\"p\",\"decay\"]]]],[2,[8,[7,[7,\"swapLayout\",\"$\"],\"writeBuf\"],\"idx\"],\"=\",[1,\"decayed\",\"-\",\"lineCf\"]]]]},externals:{swapLayout:()=>_,\"d.u32\":()=>M,n:()=>t,\"d.f32\":()=>n,vertical:()=>o,\"d.i32\":()=>j,\"std.clamp\":()=>G,maxC:()=>c,parity:()=>x,\"std.select\":()=>N,\"std.floor\":()=>ie,\"std.min\":()=>ye,\"std.mix\":()=>K,brushWeight:()=>h,\"noise.hash13\":()=>Wb,\"d.vec3f\":()=>A,direction:()=>a}})&&P.f)({})).$name(`${r}Swap`),b=w.fn([M,M])((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=__tsover_add(__tsover_mul(C,M(t)),P),R=o?C:P,U=G(__tsover_add(n(R),f.$.srcBuf[E]),0,c),L=__tsover_div(__tsover_add(U,.5),l);lt(f.$.stateTex,fe(P,C),S(L,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"n\"]]],\"+\",\"cx\"]],[13,\"lineC\",[105,\"vertical\",\"cy\",\"cx\"]],[13,\"col\",[6,\"std.clamp\",[[1,[6,\"d.f32\",[\"lineC\"]],\"+\",[8,[7,[7,\"outputLayout\",\"$\"],\"srcBuf\"],\"idx\"]],[5,\"0\"],\"maxC\"]]],[13,\"u\",[1,[1,\"col\",\"+\",[5,\"0.5\"]],\"/\",\"nF\"]],[6,\"std.textureStore\",[[7,[7,\"outputLayout\",\"$\"],\"stateTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"u\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{\"d.u32\":()=>M,n:()=>t,vertical:()=>o,\"std.clamp\":()=>G,\"d.f32\":()=>n,outputLayout:()=>f,maxC:()=>c,nF:()=>l,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&x.f)({})).$name(`${r}Output`);return{lumaLayout:p,LumaParams:d,swapLayout:_,SwapParams:u,outputLayout:f,key:g,swap0:y(0),swap1:y(1),output:b}}var GP=w.fn([S,S,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=re(t.xyz.sub(s.xyz)),a=re(__tsover_sub(t.w,s.w)),i=__tsover_add(Se(o,A(.299,.587,.114)),a);return be(r,__tsover_add(__tsover_mul(r,2),.001),i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"live\"},{type:\"i\",name:\"prev\"},{type:\"i\",name:\"threshold\"}],body:[0,[[13,\"dRgb\",[6,\"std.abs\",[[6,[7,[7,\"live\",\"xyz\"],\"sub\"],[[7,\"prev\",\"xyz\"]]]]]],[13,\"dA\",[6,\"std.abs\",[[1,[7,\"live\",\"w\"],\"-\",[7,\"prev\",\"w\"]]]]],[13,\"diff\",[1,[6,\"std.dot\",[\"dRgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]],\"+\",\"dA\"]],[10,[6,\"std.smoothstep\",[\"threshold\",[1,[1,\"threshold\",\"*\",[5,\"2\"]],\"+\",[5,\"0.001\"]],\"diff\"]]]]]},externals:{\"std.abs\":()=>re,\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.smoothstep\":()=>be}})&&e.f)({})).$name(\"frameDiffMask\"),FP=w.fn([A,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=cd(t);return ml(A(Re(__tsover_add(r.x,s)),r.y,r.z))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"amount\"}],body:[0,[[13,\"hsl\",[6,\"colorMixing.rgbToHsl\",[\"rgb\"]]],[13,\"rotated\",[6,\"d.vec3f\",[[6,\"std.fract\",[[1,[7,\"hsl\",\"x\"],\"+\",\"amount\"]]],[7,\"hsl\",\"y\"],[7,\"hsl\",\"z\"]]]],[10,[6,\"colorMixing.hslToRgb\",[\"rotated\"]]]]]},externals:{\"colorMixing.rgbToHsl\":()=>cd,\"d.vec3f\":()=>A,\"std.fract\":()=>Re,\"colorMixing.hslToRgb\":()=>ml}})&&e.f)({})).$name(\"hueRotateTurns\");function Fz(e){let{res:t,format:s,namePrefix:r,source:o,hueCycle:a,diffuseHalfUv:i,driftScale:l}=e,c=gt({persistence:n,diffusion:n,driftX:n,driftY:n,dt:n,zoom:n,hueRate:n,blendMode:n,motionThreshold:n}).$name(\"FeedbackTrailParams\"),d=(globalThis.__TYPEGPU_AUTONAME__??(x=>x))(w.bindGroupLayout({src:{texture:Zt(n)},prev:{texture:Zt(n)},next:{storageTexture:zt(s,\"write-only\")},display:{storageTexture:zt(s,\"write-only\")},prevLive:{texture:Zt(n)},prevLiveOut:{storageTexture:zt(s,\"write-only\")},samp:{sampler:\"filtering\"},params:{uniform:c}}),\"layout\"),u=w.fn([n,n],S)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";return Xl(d.$.prev,d.$.samp,m(P,C),n(0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvx\"},{type:\"i\",name:\"uvy\"}],body:[0,[[10,[6,\"std.textureSampleLevel\",[[7,[7,\"layout\",\"$\"],\"prev\"],[7,[7,\"layout\",\"$\"],\"samp\"],[6,\"d.vec2f\",[\"uvx\",\"uvy\"]],[6,\"d.f32\",[[5,\"0\"]]]]]]]]},externals:{\"std.textureSampleLevel\":()=>Xl,layout:()=>d,\"d.vec2f\":()=>m,\"d.f32\":()=>n}})&&x.f)({})).$name(`${r}SampleHistory`),p=w.fn([n,n],S)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";return Xl(d.$.src,d.$.samp,m(P,C),n(0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uvx\"},{type:\"i\",name:\"uvy\"}],body:[0,[[10,[6,\"std.textureSampleLevel\",[[7,[7,\"layout\",\"$\"],\"src\"],[7,[7,\"layout\",\"$\"],\"samp\"],[6,\"d.vec2f\",[\"uvx\",\"uvy\"]],[6,\"d.f32\",[[5,\"0\"]]]]]]]]},externals:{\"std.textureSampleLevel\":()=>Xl,layout:()=>d,\"d.vec2f\":()=>m,\"d.f32\":()=>n}})&&x.f)({})).$name(`${r}SampleLive`),_=w.fn([M,M],m)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=n(t);return m(__tsover_div(__tsover_add(n(P),.5),E),__tsover_div(__tsover_add(n(C),.5),E))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"r\",[6,\"d.f32\",[\"res\"]]],[10,[6,\"d.vec2f\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"r\"],[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"r\"]]]]]]},externals:{\"d.f32\":()=>n,res:()=>t,\"d.vec2f\":()=>m}})&&x.f)({})).$name(`${r}TexelUv`),f=w.fn([m],m)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=(P=>{\"use gpu\";let C=d.$.params,E=B(C.zoom,.01);return m(__tsover_sub(__tsover_add(__tsover_div(__tsover_sub(P.x,.5),E),.5),__tsover_mul(__tsover_mul(C.driftX,C.dt),l)),__tsover_sub(__tsover_add(__tsover_div(__tsover_sub(P.y,.5),E),.5),__tsover_mul(__tsover_mul(C.driftY,C.dt),l)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"zoom\",[6,\"std.max\",[[7,\"P\",\"zoom\"],[5,\"0.01\"]]]],[10,[6,\"d.vec2f\",[[1,[1,[1,[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],\"/\",\"zoom\"],\"+\",[5,\"0.5\"]],\"-\",[1,[1,[7,\"P\",\"driftX\"],\"*\",[7,\"P\",\"dt\"]],\"*\",\"driftScale\"]],[1,[1,[1,[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]],\"/\",\"zoom\"],\"+\",[5,\"0.5\"]],\"-\",[1,[1,[7,\"P\",\"driftY\"],\"*\",[7,\"P\",\"dt\"]],\"*\",\"driftScale\"]]]]]]]},externals:{layout:()=>d,\"std.max\":()=>B,\"d.vec2f\":()=>m,driftScale:()=>l}})&&x.f)({})).$name(`${r}FeedbackUv`),h=w.fn([n,n],S)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=d.$.params,R=__tsover_mul(E.diffusion,i);return u(__tsover_sub(P,R),__tsover_sub(C,R)).add(u(__tsover_add(P,R),__tsover_sub(C,R))).add(u(__tsover_sub(P,R),__tsover_add(C,R))).add(u(__tsover_add(P,R),__tsover_add(C,R))).mul(__tsover_mul(E.persistence,.25))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"bx\"},{type:\"i\",name:\"by\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"h\",[1,[7,\"P\",\"diffusion\"],\"*\",\"diffuseHalfUv\"]],[13,\"sum\",[6,[7,[6,[7,[6,[7,[6,\"sampleHistory\",[[1,\"bx\",\"-\",\"h\"],[1,\"by\",\"-\",\"h\"]]],\"add\"],[[6,\"sampleHistory\",[[1,\"bx\",\"+\",\"h\"],[1,\"by\",\"-\",\"h\"]]]]],\"add\"],[[6,\"sampleHistory\",[[1,\"bx\",\"-\",\"h\"],[1,\"by\",\"+\",\"h\"]]]]],\"add\"],[[6,\"sampleHistory\",[[1,\"bx\",\"+\",\"h\"],[1,\"by\",\"+\",\"h\"]]]]]],[10,[6,[7,\"sum\",\"mul\"],[[1,[7,\"P\",\"persistence\"],\"*\",[5,\"0.25\"]]]]]]]},externals:{layout:()=>d,diffuseHalfUv:()=>i,sampleHistory:()=>u}})&&x.f)({})).$name(`${r}Decayed`),g=w.fn([n,n],S)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=h(P,C),R=B(E.w,1e-4);return S(FP(E.xyz.div(R),d.$.params.hueRate).mul(E.w),E.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"bx\"},{type:\"i\",name:\"by\"}],body:[0,[[13,\"dec\",[6,\"decayed\",[\"bx\",\"by\"]]],[13,\"a\",[6,\"std.max\",[[7,\"dec\",\"w\"],[5,\"0.0001\"]]]],[13,\"rotated\",[6,\"hueRotateTurns\",[[6,[7,[7,\"dec\",\"xyz\"],\"div\"],[\"a\"]],[7,[7,[7,\"layout\",\"$\"],\"params\"],\"hueRate\"]]]],[10,[6,\"d.vec4f\",[[6,[7,\"rotated\",\"mul\"],[[7,\"dec\",\"w\"]]],[7,\"dec\",\"w\"]]]]]]},externals:{decayed:()=>h,\"std.max\":()=>B,hueRotateTurns:()=>FP,layout:()=>d,\"d.vec4f\":()=>S}})&&x.f)({})).$name(`${r}DecayedTinted`),y=a?g:h,b=w.fn([S,n,S],S)((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C,E)=>{\"use gpu\";let R=d.$.params,U=S(P.xyz.mul(C),__tsover_mul(P.w,C)),L=__tsover_add(U.w,__tsover_mul(E.w,__tsover_sub(1,U.w))),k=U.xyz.add(E.xyz.mul(__tsover_sub(1,U.w))),D=U.xyz.add(E.xyz).sub(U.xyz.mul(E.xyz)),O=U.xyz.add(E.xyz);return S(N(N(k,D,R.blendMode>.5),O,R.blendMode>1.5),L)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"live\"},{type:\"i\",name:\"m\"},{type:\"i\",name:\"trail\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"s\",[6,\"d.vec4f\",[[6,[7,[7,\"live\",\"xyz\"],\"mul\"],[\"m\"]],[1,[7,\"live\",\"w\"],\"*\",\"m\"]]]],[13,\"outA\",[1,[7,\"s\",\"w\"],\"+\",[1,[7,\"trail\",\"w\"],\"*\",[1,[5,\"1\"],\"-\",[7,\"s\",\"w\"]]]]],[13,\"rgbNormal\",[6,[7,[7,\"s\",\"xyz\"],\"add\"],[[6,[7,[7,\"trail\",\"xyz\"],\"mul\"],[[1,[5,\"1\"],\"-\",[7,\"s\",\"w\"]]]]]]],[13,\"rgbScreen\",[6,[7,[6,[7,[7,\"s\",\"xyz\"],\"add\"],[[7,\"trail\",\"xyz\"]]],\"sub\"],[[6,[7,[7,\"s\",\"xyz\"],\"mul\"],[[7,\"trail\",\"xyz\"]]]]]],[13,\"rgbAdd\",[6,[7,[7,\"s\",\"xyz\"],\"add\"],[[7,\"trail\",\"xyz\"]]]],[13,\"rgbSN\",[6,\"std.select\",[\"rgbNormal\",\"rgbScreen\",[1,[7,\"P\",\"blendMode\"],\">\",[5,\"0.5\"]]]]],[10,[6,\"d.vec4f\",[[6,\"std.select\",[\"rgbSN\",\"rgbAdd\",[1,[7,\"P\",\"blendMode\"],\">\",[5,\"1.5\"]]]],\"outA\"]]]]]},externals:{layout:()=>d,\"d.vec4f\":()=>S,\"std.select\":()=>N}})&&x.f)({})).$name(`${r}Stamp`);return{layout:d,Params:c,kernel:o===\"motion\"?w.fn([M,M])((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=_(P,C),R=f(E),U=y(R.x,R.y),L=p(E.x,E.y),k=GP(L,Ye(d.$.prevLive,fe(P,C),0),d.$.params.motionThreshold);lt(d.$.next,fe(P,C),b(L,k,U)),lt(d.$.display,fe(P,C),U),lt(d.$.prevLiveOut,fe(P,C),L)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"uv\",[6,\"texelUv\",[\"cx\",\"cy\"]]],[13,\"b\",[6,\"feedbackUv\",[\"uv\"]]],[13,\"trail\",[6,\"trailFn\",[[7,\"b\",\"x\"],[7,\"b\",\"y\"]]]],[13,\"live\",[6,\"sampleLive\",[[7,\"uv\",\"x\"],[7,\"uv\",\"y\"]]]],[13,\"pl\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"prevLive\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[5,\"0\"]]]],[13,\"m\",[6,\"frameDiffMask\",[\"live\",\"pl\",[7,[7,[7,\"layout\",\"$\"],\"params\"],\"motionThreshold\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"next\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"stamp\",[\"live\",\"m\",\"trail\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"display\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"trail\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"prevLiveOut\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"live\"]]]]},externals:{texelUv:()=>_,feedbackUv:()=>f,trailFn:()=>y,sampleLive:()=>p,\"std.textureLoad\":()=>Ye,layout:()=>d,\"d.vec2u\":()=>fe,frameDiffMask:()=>GP,\"std.textureStore\":()=>lt,stamp:()=>b}})&&x.f)({})).$name(`${r}Step`):w.fn([M,M])((x=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(x.f=((P,C)=>{\"use gpu\";let E=_(P,C),R=f(E),U=y(R.x,R.y),L=b(p(E.x,E.y),n(1),U);lt(d.$.next,fe(P,C),L),lt(d.$.display,fe(P,C),L)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"uv\",[6,\"texelUv\",[\"cx\",\"cy\"]]],[13,\"b\",[6,\"feedbackUv\",[\"uv\"]]],[13,\"trail\",[6,\"trailFn\",[[7,\"b\",\"x\"],[7,\"b\",\"y\"]]]],[13,\"live\",[6,\"sampleLive\",[[7,\"uv\",\"x\"],[7,\"uv\",\"y\"]]]],[13,\"outC\",[6,\"stamp\",[\"live\",[6,\"d.f32\",[[5,\"1\"]]],\"trail\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"next\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"outC\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"display\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"outC\"]]]]},externals:{texelUv:()=>_,feedbackUv:()=>f,trailFn:()=>y,sampleLive:()=>p,stamp:()=>b,\"d.f32\":()=>n,\"std.textureStore\":()=>lt,layout:()=>d,\"d.vec2u\":()=>fe}})&&x.f)({})).$name(`${r}StepAlpha`)}}function Iz(e){let{res:t,format:s,namePrefix:r}=e,o=e.blockMix?.coarseScale??2.6,a=e.blockMix?.coarsePick??.35,i=e.generationLoss?.levels??18,l=e.generationLoss?.amount??.12,c=e.generationLoss?.decay??.9985,d=gt({time:n,dt:n,seed:n,intensity:n,blockSize:n,drift:n,churn:n}).$name(\"MacroblockAdvectParams\"),u=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(w.bindGroupLayout({src:{texture:Zt(n)},prev:{texture:Zt(n)},next:{storageTexture:zt(s,\"write-only\")},display:{storageTexture:zt(s,\"write-only\")},params:{uniform:d}}),\"layout\");return{layout:u,Params:d,kernel:w.fn([M,M])((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";let h=u.$.params,g=n(t),y=n(_),b=n(f),x=__tsover_div(__tsover_add(y,.5),g),P=__tsover_div(__tsover_add(b,.5),g),C=__tsover_add(.15,__tsover_mul(h.churn,.8)),E=B(h.blockSize,8),R=__tsover_mul(E,o),U=ie(__tsover_div(y,R)),L=ie(__tsover_div(b,R)),k=Xs(__tsover_add(__tsover_add(__tsover_mul(U,91.17),__tsover_mul(L,41.23)),__tsover_mul(h.seed,3.7))),D=ie(__tsover_add(__tsover_mul(__tsover_mul(h.time,C),.25),k)),O=N(E,R,Xs(__tsover_add(__tsover_add(__tsover_add(__tsover_mul(U,12.9898),__tsover_mul(L,78.233)),__tsover_mul(D,37.71)),__tsover_mul(h.seed,3.7)))<a),F=ie(__tsover_div(y,O)),q=ie(__tsover_div(b,O)),Y=Xs(__tsover_add(__tsover_add(__tsover_mul(F,127.1),__tsover_mul(q,311.7)),__tsover_mul(h.seed,17.9))),V=__tsover_mul(C,__tsover_add(.7,__tsover_mul(.6,Xs(__tsover_add(__tsover_add(__tsover_mul(F,53.7),__tsover_mul(q,97.3)),__tsover_mul(h.seed,5.3)))))),X=ie(__tsover_add(__tsover_mul(h.time,V),Y)),Q=__tsover_add(__tsover_add(__tsover_add(__tsover_mul(F,127.1),__tsover_mul(q,311.7)),__tsover_mul(X,74.7)),__tsover_mul(h.seed,17.9)),te=Xs(__tsover_add(Q,.13)),J=Xs(__tsover_add(Q,7.77)),oe=Xs(__tsover_add(Q,23.19)),le=__tsover_div(__tsover_mul(__tsover_add(F,.5),O),g),se=__tsover_div(__tsover_mul(__tsover_add(q,.5),O),g),Te=__tsover_add(__tsover_add(.5,__tsover_mul(__tsover_mul(.25,ae(__tsover_add(__tsover_add(__tsover_mul(le,2.7),__tsover_mul(h.time,.31)),h.seed))),ae(__tsover_add(__tsover_sub(__tsover_mul(se,2.1),__tsover_mul(h.time,.23)),__tsover_mul(h.seed,.4))))),__tsover_mul(.25,ae(__tsover_add(__tsover_add(__tsover_mul(__tsover_add(le,se),1.6),__tsover_mul(h.time,.17)),__tsover_mul(h.seed,.7))))),de=__tsover_sub(1,__tsover_mul(h.intensity,.55)),xe=be(__tsover_sub(de,.09),__tsover_add(de,.09),__tsover_add(Te,__tsover_mul(__tsover_sub(te,.5),.3))),Ae=__tsover_add(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(le,1.9),__tsover_mul(h.seed,3.1))),1.7),__tsover_mul(pe(__tsover_sub(__tsover_mul(se,2.3),__tsover_mul(h.seed,2.7))),1.3)),__tsover_mul(h.time,.15)),De=__tsover_add(Ae,__tsover_mul(__tsover_sub(J,.5),1.1)),Ee=__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(__tsover_add(.5,__tsover_mul(.5,oe)),h.drift),h.dt),10),__tsover_div(O,g)),ze=__tsover_sub(x,__tsover_mul(pe(De),Ee)),Ie=__tsover_sub(P,__tsover_mul(ae(De),Ee)),ke=__tsover_mul(__tsover_mul(__tsover_mul(N(n(0),n(1),ze>=0),N(n(0),n(1),ze<=1)),N(n(0),n(1),Ie>=0)),N(n(0),n(1),Ie<=1)),Me=__tsover_sub(__tsover_mul(G(ze,0,1),g),.5),we=__tsover_sub(__tsover_mul(G(Ie,0,1),g),.5),Ve=ie(Me),qe=ie(we),st=__tsover_sub(Me,Ve),pt=__tsover_sub(we,qe),Ze=__tsover_sub(g,1),nt=M(G(Ve,n(0),Ze)),ht=M(G(__tsover_add(Ve,1),n(0),Ze)),yt=M(G(qe,n(0),Ze)),St=M(G(__tsover_add(qe,1),n(0),Ze)),Mt=Ye(u.$.prev,fe(nt,yt),0),Rt=Ye(u.$.prev,fe(ht,yt),0),Kt=Ye(u.$.prev,fe(nt,St),0),Wt=Ye(u.$.prev,fe(ht,St),0),ls=K(K(Mt,Rt,st),K(Kt,Wt,st),pt),us=ie(ls.xyz.mul(i)).add(A(.5,.5,.5)).div(i),os=S(K(ls.xyz,us,l).mul(c),ls.w),bs=G(__tsover_mul(h.dt,__tsover_add(1.2,__tsover_mul(__tsover_sub(1,h.intensity),2))),0,.2),hs=Ti(u.$.src),gs=n(hs.x),Gs=n(hs.y),Ss=__tsover_sub(__tsover_mul(x,gs),.5),or=__tsover_sub(__tsover_mul(P,Gs),.5),yr=ie(Ss),lr=ie(or),Ur=__tsover_sub(Ss,yr),so=__tsover_sub(or,lr),ro=M(G(yr,n(0),__tsover_sub(gs,1))),_e=M(G(__tsover_add(yr,1),n(0),__tsover_sub(gs,1))),We=M(G(lr,n(0),__tsover_sub(Gs,1))),Le=M(G(__tsover_add(lr,1),n(0),__tsover_sub(Gs,1))),Be=Ye(u.$.src,fe(ro,We),0),Oe=Ye(u.$.src,fe(_e,We),0),tt=Ye(u.$.src,fe(ro,Le),0),_t=Ye(u.$.src,fe(_e,Le),0),Bt=K(K(Be,Oe,Ur),K(tt,_t,Ur),so),Dt=K(Bt,K(os,Bt,bs),__tsover_mul(xe,ke));lt(u.$.next,fe(_,f),Dt),lt(u.$.display,fe(_,f),Dt)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"resF\",[6,\"d.f32\",[\"res\"]]],[13,\"px\",[6,\"d.f32\",[\"cx\"]]],[13,\"py\",[6,\"d.f32\",[\"cy\"]]],[13,\"fx\",[1,[1,\"px\",\"+\",[5,\"0.5\"]],\"/\",\"resF\"]],[13,\"fy\",[1,[1,\"py\",\"+\",[5,\"0.5\"]],\"/\",\"resF\"]],[13,\"churnRate\",[1,[5,\"0.15\"],\"+\",[1,[7,\"P\",\"churn\"],\"*\",[5,\"0.8\"]]]],[13,\"bsF\",[6,\"std.max\",[[7,\"P\",\"blockSize\"],[5,\"8\"]]]],[13,\"coarse\",[1,\"bsF\",\"*\",\"coarseScale\"]],[13,\"cbx\",[6,\"std.floor\",[[1,\"px\",\"/\",\"coarse\"]]]],[13,\"cby\",[6,\"std.floor\",[[1,\"py\",\"/\",\"coarse\"]]]],[13,\"cPhase\",[6,\"noise.hash11\",[[1,[1,[1,\"cbx\",\"*\",[5,\"91.17\"]],\"+\",[1,\"cby\",\"*\",[5,\"41.23\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"3.7\"]]]]]],[13,\"cEpoch\",[6,\"std.floor\",[[1,[1,[1,[7,\"P\",\"time\"],\"*\",\"churnRate\"],\"*\",[5,\"0.25\"]],\"+\",\"cPhase\"]]]],[13,\"scalePick\",[6,\"noise.hash11\",[[1,[1,[1,[1,\"cbx\",\"*\",[5,\"12.9898\"]],\"+\",[1,\"cby\",\"*\",[5,\"78.233\"]]],\"+\",[1,\"cEpoch\",\"*\",[5,\"37.71\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"3.7\"]]]]]],[13,\"bs\",[6,\"std.select\",[\"bsF\",\"coarse\",[1,\"scalePick\",\"<\",\"coarsePick\"]]]],[13,\"bx\",[6,\"std.floor\",[[1,\"px\",\"/\",\"bs\"]]]],[13,\"by\",[6,\"std.floor\",[[1,\"py\",\"/\",\"bs\"]]]],[13,\"bPhase\",[6,\"noise.hash11\",[[1,[1,[1,\"bx\",\"*\",[5,\"127.1\"]],\"+\",[1,\"by\",\"*\",[5,\"311.7\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"17.9\"]]]]]],[13,\"bRate\",[1,\"churnRate\",\"*\",[1,[5,\"0.7\"],\"+\",[1,[5,\"0.6\"],\"*\",[6,\"noise.hash11\",[[1,[1,[1,\"bx\",\"*\",[5,\"53.7\"]],\"+\",[1,\"by\",\"*\",[5,\"97.3\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"5.3\"]]]]]]]]],[13,\"bEpoch\",[6,\"std.floor\",[[1,[1,[7,\"P\",\"time\"],\"*\",\"bRate\"],\"+\",\"bPhase\"]]]],[13,\"bh\",[1,[1,[1,[1,\"bx\",\"*\",[5,\"127.1\"]],\"+\",[1,\"by\",\"*\",[5,\"311.7\"]]],\"+\",[1,\"bEpoch\",\"*\",[5,\"74.7\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"17.9\"]]]],[13,\"h1\",[6,\"noise.hash11\",[[1,\"bh\",\"+\",[5,\"0.13\"]]]]],[13,\"h2\",[6,\"noise.hash11\",[[1,\"bh\",\"+\",[5,\"7.77\"]]]]],[13,\"h3\",[6,\"noise.hash11\",[[1,\"bh\",\"+\",[5,\"23.19\"]]]]],[13,\"bcx\",[1,[1,[1,\"bx\",\"+\",[5,\"0.5\"]],\"*\",\"bs\"],\"/\",\"resF\"]],[13,\"bcy\",[1,[1,[1,\"by\",\"+\",[5,\"0.5\"]],\"*\",\"bs\"],\"/\",\"resF\"]],[13,\"field\",[1,[1,[5,\"0.5\"],\"+\",[1,[1,[5,\"0.25\"],\"*\",[6,\"std.sin\",[[1,[1,[1,\"bcx\",\"*\",[5,\"2.7\"]],\"+\",[1,[7,\"P\",\"time\"],\"*\",[5,\"0.31\"]]],\"+\",[7,\"P\",\"seed\"]]]]],\"*\",[6,\"std.sin\",[[1,[1,[1,\"bcy\",\"*\",[5,\"2.1\"]],\"-\",[1,[7,\"P\",\"time\"],\"*\",[5,\"0.23\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"0.4\"]]]]]]],\"+\",[1,[5,\"0.25\"],\"*\",[6,\"std.sin\",[[1,[1,[1,[1,\"bcx\",\"+\",\"bcy\"],\"*\",[5,\"1.6\"]],\"+\",[1,[7,\"P\",\"time\"],\"*\",[5,\"0.17\"]]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"0.7\"]]]]]]]],[13,\"thresh\",[1,[5,\"1\"],\"-\",[1,[7,\"P\",\"intensity\"],\"*\",[5,\"0.55\"]]]],[13,\"hold\",[6,\"std.smoothstep\",[[1,\"thresh\",\"-\",[5,\"0.09\"]],[1,\"thresh\",\"+\",[5,\"0.09\"]],[1,\"field\",\"+\",[1,[1,\"h1\",\"-\",[5,\"0.5\"]],\"*\",[5,\"0.3\"]]]]]],[13,\"flowAng\",[1,[1,[1,[6,\"std.sin\",[[1,[1,\"bcx\",\"*\",[5,\"1.9\"]],\"+\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"3.1\"]]]]],\"*\",[5,\"1.7\"]],\"+\",[1,[6,\"std.cos\",[[1,[1,\"bcy\",\"*\",[5,\"2.3\"]],\"-\",[1,[7,\"P\",\"seed\"],\"*\",[5,\"2.7\"]]]]],\"*\",[5,\"1.3\"]]],\"+\",[1,[7,\"P\",\"time\"],\"*\",[5,\"0.15\"]]]],[13,\"ang\",[1,\"flowAng\",\"+\",[1,[1,\"h2\",\"-\",[5,\"0.5\"]],\"*\",[5,\"1.1\"]]]],[13,\"mag\",[1,[1,[1,[1,[1,[5,\"0.5\"],\"+\",[1,[5,\"0.5\"],\"*\",\"h3\"]],\"*\",[7,\"P\",\"drift\"]],\"*\",[7,\"P\",\"dt\"]],\"*\",[5,\"10\"]],\"*\",[1,\"bs\",\"/\",\"resF\"]]],[13,\"suRaw\",[1,\"fx\",\"-\",[1,[6,\"std.cos\",[\"ang\"]],\"*\",\"mag\"]]],[13,\"svRaw\",[1,\"fy\",\"-\",[1,[6,\"std.sin\",[\"ang\"]],\"*\",\"mag\"]]],[13,\"inBounds\",[1,[1,[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"suRaw\",\">=\",[5,\"0\"]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"suRaw\",\"<=\",[5,\"1\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"svRaw\",\">=\",[5,\"0\"]]]]],\"*\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"svRaw\",\"<=\",[5,\"1\"]]]]]],[13,\"su\",[1,[1,[6,\"std.clamp\",[\"suRaw\",[5,\"0\"],[5,\"1\"]]],\"*\",\"resF\"],\"-\",[5,\"0.5\"]]],[13,\"sv\",[1,[1,[6,\"std.clamp\",[\"svRaw\",[5,\"0\"],[5,\"1\"]]],\"*\",\"resF\"],\"-\",[5,\"0.5\"]]],[13,\"sx0\",[6,\"std.floor\",[\"su\"]]],[13,\"sy0\",[6,\"std.floor\",[\"sv\"]]],[13,\"sfx\",[1,\"su\",\"-\",\"sx0\"]],[13,\"sfy\",[1,\"sv\",\"-\",\"sy0\"]],[13,\"maxT\",[1,\"resF\",\"-\",[5,\"1\"]]],[13,\"ix0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"sx0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"ix1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"sx0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"iy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"sy0\",[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"iy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"sy0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],\"maxT\"]]]]],[13,\"p00\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[\"ix0\",\"iy0\"]],[5,\"0\"]]]],[13,\"p10\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[\"ix1\",\"iy0\"]],[5,\"0\"]]]],[13,\"p01\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[\"ix0\",\"iy1\"]],[5,\"0\"]]]],[13,\"p11\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"prev\"],[6,\"d.vec2u\",[\"ix1\",\"iy1\"]],[5,\"0\"]]]],[13,\"prevC\",[6,\"std.mix\",[[6,\"std.mix\",[\"p00\",\"p10\",\"sfx\"]],[6,\"std.mix\",[\"p01\",\"p11\",\"sfx\"]],\"sfy\"]]],[13,\"quant\",[6,[7,[6,[7,[6,\"std.floor\",[[6,[7,[7,\"prevC\",\"xyz\"],\"mul\"],[\"quantLevels\"]]]],\"add\"],[[6,\"d.vec3f\",[[5,\"0.5\"],[5,\"0.5\"],[5,\"0.5\"]]]]],\"div\"],[\"quantLevels\"]]],[13,\"heldRgb\",[6,[7,[6,\"std.mix\",[[7,\"prevC\",\"xyz\"],\"quant\",\"quantAmount\"]],\"mul\"],[\"energyDecay\"]]],[13,\"held\",[6,\"d.vec4f\",[\"heldRgb\",[7,\"prevC\",\"w\"]]]],[13,\"rekey\",[6,\"std.clamp\",[[1,[7,\"P\",\"dt\"],\"*\",[1,[5,\"1.2\"],\"+\",[1,[1,[5,\"1\"],\"-\",[7,\"P\",\"intensity\"]],\"*\",[5,\"2\"]]]],[5,\"0\"],[5,\"0.2\"]]]],[13,\"srcDims\",[6,\"std.textureDimensions\",[[7,[7,\"layout\",\"$\"],\"src\"]]]],[13,\"srcW\",[6,\"d.f32\",[[7,\"srcDims\",\"x\"]]]],[13,\"srcH\",[6,\"d.f32\",[[7,\"srcDims\",\"y\"]]]],[13,\"cu\",[1,[1,\"fx\",\"*\",\"srcW\"],\"-\",[5,\"0.5\"]]],[13,\"cv\",[1,[1,\"fy\",\"*\",\"srcH\"],\"-\",[5,\"0.5\"]]],[13,\"cx0\",[6,\"std.floor\",[\"cu\"]]],[13,\"cy0\",[6,\"std.floor\",[\"cv\"]]],[13,\"cfx\",[1,\"cu\",\"-\",\"cx0\"]],[13,\"cfy\",[1,\"cv\",\"-\",\"cy0\"]],[13,\"jx0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"cx0\",[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcW\",\"-\",[5,\"1\"]]]]]]],[13,\"jx1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cx0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcW\",\"-\",[5,\"1\"]]]]]]],[13,\"jy0\",[6,\"d.u32\",[[6,\"std.clamp\",[\"cy0\",[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcH\",\"-\",[5,\"1\"]]]]]]],[13,\"jy1\",[6,\"d.u32\",[[6,\"std.clamp\",[[1,\"cy0\",\"+\",[5,\"1\"]],[6,\"d.f32\",[[5,\"0\"]]],[1,\"srcH\",\"-\",[5,\"1\"]]]]]]],[13,\"c00\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"jx0\",\"jy0\"]],[5,\"0\"]]]],[13,\"c10\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"jx1\",\"jy0\"]],[5,\"0\"]]]],[13,\"c01\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"jx0\",\"jy1\"]],[5,\"0\"]]]],[13,\"c11\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"jx1\",\"jy1\"]],[5,\"0\"]]]],[13,\"fresh\",[6,\"std.mix\",[[6,\"std.mix\",[\"c00\",\"c10\",\"cfx\"]],[6,\"std.mix\",[\"c01\",\"c11\",\"cfx\"]],\"cfy\"]]],[13,\"heldAnchored\",[6,\"std.mix\",[\"held\",\"fresh\",\"rekey\"]]],[13,\"outC\",[6,\"std.mix\",[\"fresh\",\"heldAnchored\",[1,\"hold\",\"*\",\"inBounds\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"next\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"outC\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"display\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"outC\"]]]]},externals:{layout:()=>u,\"d.f32\":()=>n,res:()=>t,\"std.max\":()=>B,coarseScale:()=>o,\"std.floor\":()=>ie,\"noise.hash11\":()=>Xs,\"std.select\":()=>N,coarsePick:()=>a,\"std.sin\":()=>ae,\"std.smoothstep\":()=>be,\"std.cos\":()=>pe,\"std.clamp\":()=>G,\"d.u32\":()=>M,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,quantLevels:()=>i,\"d.vec3f\":()=>A,quantAmount:()=>l,energyDecay:()=>c,\"d.vec4f\":()=>S,\"std.textureDimensions\":()=>Ti,\"std.textureStore\":()=>lt}})&&p.f)({})).$name(`${r}Step`)}}var Pie=[16,11,10,16,24,40,51,61,12,12,14,19,26,58,60,55,14,13,16,24,40,57,69,56,14,17,22,29,51,87,80,62,18,22,37,56,68,109,103,77,24,35,55,64,81,104,113,92,49,64,78,87,103,121,120,101,72,92,95,98,112,100,103,99],Cie=[17,18,24,47,99,99,99,99,18,21,26,66,99,99,99,99,24,26,56,99,99,99,99,99,47,66,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99],Yz=[];for(let e=0;e<8;e++)for(let t=0;t<8;t++)Yz[e*8+t]=Math.cos((2*e+1)*t*Math.PI/16);var X0=Math.SQRT1_2,H0=Math.PI/16,j0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.const(Fe(n,64),Yz),\"COS_LUT\"),IP=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.const(Fe(n,64),Pie),\"LUMA_QUANT_C\"),YP=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.const(Fe(n,64),Cie),\"CHROMA_QUANT_C\"),WP=new Map;function Mie(e){return w.fn([Fe(A,64),n,n,n],A)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o,a)=>{\"use gpu\";let i=G(a,1,100),l=N(__tsover_sub(200,__tsover_mul(i,2)),__tsover_div(5e3,i),i<50),c=Fe(n,64)(),d=Fe(n,64)(),u=Fe(n,64)();for(let E=0;E<64;E++){let R=s[E];c[E]=__tsover_sub(__tsover_add(__tsover_add(__tsover_mul(R.x,.299),__tsover_mul(R.y,.587)),__tsover_mul(R.z,.114)),.5),d[E]=__tsover_add(__tsover_add(__tsover_mul(R.x,-.168736),__tsover_mul(R.y,-.331264)),__tsover_mul(R.z,.5)),u[E]=__tsover_add(__tsover_add(__tsover_mul(R.x,.5),__tsover_mul(R.y,-.418688)),__tsover_mul(R.z,-.081312))}let p=Fe(n,__tsover_mul(8,e))();for(let E=0;E<8;E++)for(let R=0;R<e;R++){let U=n(0);for(let L=0;L<8;L++)U=__tsover_add(U,__tsover_mul(c[__tsover_add(__tsover_mul(E,8),L)],j0.$[__tsover_add(__tsover_mul(L,8),R)]));p[__tsover_add(__tsover_mul(E,e),R)]=U}let _=n(0);for(let E=0;E<e;E++){let R=N(1,X0,E===0),U=pe(__tsover_mul(__tsover_add(__tsover_mul(o,2),1),__tsover_mul(n(E),H0)));for(let L=0;L<e;L++){let k=N(1,X0,L===0),D=n(0);for(let V=0;V<8;V++)D=__tsover_add(D,__tsover_mul(p[__tsover_add(__tsover_mul(V,e),L)],j0.$[__tsover_add(__tsover_mul(V,8),E)]));let O=__tsover_mul(D,__tsover_mul(__tsover_mul(.25,k),R)),F=__tsover_div(G(ie(__tsover_div(__tsover_add(__tsover_mul(l,IP.$[__tsover_add(__tsover_mul(E,8),L)]),50),100)),1,255),255),q=__tsover_mul(ie(__tsover_add(__tsover_div(O,F),.5)),F),Y=pe(__tsover_mul(__tsover_add(__tsover_mul(r,2),1),__tsover_mul(n(L),H0)));_=__tsover_add(_,__tsover_mul(__tsover_mul(__tsover_mul(q,__tsover_mul(k,R)),Y),U))}}let f=__tsover_add(__tsover_mul(_,.25),.5),h=n(0),g=n(0);for(let E=0;E<64;E++)h=__tsover_add(h,d[E]),g=__tsover_add(g,u[E]);let y=__tsover_div(G(ie(__tsover_div(__tsover_add(__tsover_mul(l,YP.$[0]),50),100)),1,255),255),b=__tsover_div(h,8),x=__tsover_div(g,8),P=__tsover_div(__tsover_mul(ie(__tsover_add(__tsover_div(b,y),.5)),y),8),C=__tsover_div(__tsover_mul(ie(__tsover_add(__tsover_div(x,y),.5)),y),8);return G(A(__tsover_add(f,__tsover_mul(C,1.402)),__tsover_sub(__tsover_sub(f,__tsover_mul(P,.344136)),__tsover_mul(C,.714136)),__tsover_add(f,__tsover_mul(P,1.772))),A(0,0,0),A(1,1,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"block\"},{type:\"i\",name:\"localX\"},{type:\"i\",name:\"localY\"},{type:\"i\",name:\"quality\"}],body:[0,[[13,\"qualityC\",[6,\"std.clamp\",[\"quality\",[5,\"1\"],[5,\"100\"]]]],[13,\"qScale\",[6,\"std.select\",[[1,[5,\"200\"],\"-\",[1,\"qualityC\",\"*\",[5,\"2\"]]],[1,[5,\"5000\"],\"/\",\"qualityC\"],[1,\"qualityC\",\"<\",[5,\"50\"]]]]],[13,\"Yv\",[6,[6,\"d.arrayOf\",[\"d.f32\",[5,\"64\"]]],[]]],[13,\"Cbv\",[6,[6,\"d.arrayOf\",[\"d.f32\",[5,\"64\"]]],[]]],[13,\"Crv\",[6,[6,\"d.arrayOf\",[\"d.f32\",[5,\"64\"]]],[]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"64\"]],[102,\"++\",\"i\"],[0,[[13,\"c\",[8,\"block\",\"i\"]],[2,[8,\"Yv\",\"i\"],\"=\",[1,[1,[1,[1,[7,\"c\",\"x\"],\"*\",[5,\"0.299\"]],\"+\",[1,[7,\"c\",\"y\"],\"*\",[5,\"0.587\"]]],\"+\",[1,[7,\"c\",\"z\"],\"*\",[5,\"0.114\"]]],\"-\",[5,\"0.5\"]]],[2,[8,\"Cbv\",\"i\"],\"=\",[1,[1,[1,[7,\"c\",\"x\"],\"*\",[4,\"-\",[5,\"0.168736\"]]],\"+\",[1,[7,\"c\",\"y\"],\"*\",[4,\"-\",[5,\"0.331264\"]]]],\"+\",[1,[7,\"c\",\"z\"],\"*\",[5,\"0.5\"]]]],[2,[8,\"Crv\",\"i\"],\"=\",[1,[1,[1,[7,\"c\",\"x\"],\"*\",[5,\"0.5\"]],\"+\",[1,[7,\"c\",\"y\"],\"*\",[4,\"-\",[5,\"0.418688\"]]]],\"+\",[1,[7,\"c\",\"z\"],\"*\",[4,\"-\",[5,\"0.081312\"]]]]]]]],[13,\"rowCoef\",[6,[6,\"d.arrayOf\",[\"d.f32\",[1,[5,\"8\"],\"*\",\"nLuma\"]]],[]]],[14,[12,\"y\",[5,\"0\"]],[1,\"y\",\"<\",[5,\"8\"]],[102,\"++\",\"y\"],[0,[[14,[12,\"u\",[5,\"0\"]],[1,\"u\",\"<\",\"nLuma\"],[102,\"++\",\"u\"],[0,[[12,\"sum\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"x\",[5,\"0\"]],[1,\"x\",\"<\",[5,\"8\"]],[102,\"++\",\"x\"],[2,\"sum\",\"=\",[1,\"sum\",\"+\",[1,[8,\"Yv\",[1,[1,\"y\",\"*\",[5,\"8\"]],\"+\",\"x\"]],\"*\",[8,[7,\"COS_LUT\",\"$\"],[1,[1,\"x\",\"*\",[5,\"8\"]],\"+\",\"u\"]]]]]],[2,[8,\"rowCoef\",[1,[1,\"y\",\"*\",\"nLuma\"],\"+\",\"u\"]],\"=\",\"sum\"]]]]]]],[12,\"acc\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"v\",[5,\"0\"]],[1,\"v\",\"<\",\"nLuma\"],[102,\"++\",\"v\"],[0,[[13,\"av\",[6,\"std.select\",[[5,\"1\"],\"SQRT1_2\",[1,\"v\",\"===\",[5,\"0\"]]]]],[13,\"cy\",[6,\"std.cos\",[[1,[1,[1,\"localY\",\"*\",[5,\"2\"]],\"+\",[5,\"1\"]],\"*\",[1,[6,\"d.f32\",[\"v\"]],\"*\",\"PI_OVER_16\"]]]]],[14,[12,\"u\",[5,\"0\"]],[1,\"u\",\"<\",\"nLuma\"],[102,\"++\",\"u\"],[0,[[13,\"au\",[6,\"std.select\",[[5,\"1\"],\"SQRT1_2\",[1,\"u\",\"===\",[5,\"0\"]]]]],[12,\"colSum\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"y\",[5,\"0\"]],[1,\"y\",\"<\",[5,\"8\"]],[102,\"++\",\"y\"],[2,\"colSum\",\"=\",[1,\"colSum\",\"+\",[1,[8,\"rowCoef\",[1,[1,\"y\",\"*\",\"nLuma\"],\"+\",\"u\"]],\"*\",[8,[7,\"COS_LUT\",\"$\"],[1,[1,\"y\",\"*\",[5,\"8\"]],\"+\",\"v\"]]]]]],[13,\"G\",[1,\"colSum\",\"*\",[1,[1,[5,\"0.25\"],\"*\",\"au\"],\"*\",\"av\"]]],[13,\"q\",[1,[6,\"std.clamp\",[[6,\"std.floor\",[[1,[1,[1,\"qScale\",\"*\",[8,[7,\"LUMA_QUANT_C\",\"$\"],[1,[1,\"v\",\"*\",[5,\"8\"]],\"+\",\"u\"]]],\"+\",[5,\"50\"]],\"/\",[5,\"100\"]]]],[5,\"1\"],[5,\"255\"]]],\"/\",[5,\"255\"]]],[13,\"Gq\",[1,[6,\"std.floor\",[[1,[1,\"G\",\"/\",\"q\"],\"+\",[5,\"0.5\"]]]],\"*\",\"q\"]],[13,\"cxv\",[6,\"std.cos\",[[1,[1,[1,\"localX\",\"*\",[5,\"2\"]],\"+\",[5,\"1\"]],\"*\",[1,[6,\"d.f32\",[\"u\"]],\"*\",\"PI_OVER_16\"]]]]],[2,\"acc\",\"=\",[1,\"acc\",\"+\",[1,[1,[1,\"Gq\",\"*\",[1,\"au\",\"*\",\"av\"]],\"*\",\"cxv\"],\"*\",\"cy\"]]]]]]]]],[13,\"Y\",[1,[1,\"acc\",\"*\",[5,\"0.25\"]],\"+\",[5,\"0.5\"]]],[12,\"sumCb\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"sumCr\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",[5,\"64\"]],[102,\"++\",\"i\"],[0,[[2,\"sumCb\",\"=\",[1,\"sumCb\",\"+\",[8,\"Cbv\",\"i\"]]],[2,\"sumCr\",\"=\",[1,\"sumCr\",\"+\",[8,\"Crv\",\"i\"]]]]]],[13,\"qChroma\",[1,[6,\"std.clamp\",[[6,\"std.floor\",[[1,[1,[1,\"qScale\",\"*\",[8,[7,\"CHROMA_QUANT_C\",\"$\"],[5,\"0\"]]],\"+\",[5,\"50\"]],\"/\",[5,\"100\"]]]],[5,\"1\"],[5,\"255\"]]],\"/\",[5,\"255\"]]],[13,\"GdcCb\",[1,\"sumCb\",\"/\",[5,\"8\"]]],[13,\"GdcCr\",[1,\"sumCr\",\"/\",[5,\"8\"]]],[13,\"Cb\",[1,[1,[6,\"std.floor\",[[1,[1,\"GdcCb\",\"/\",\"qChroma\"],\"+\",[5,\"0.5\"]]]],\"*\",\"qChroma\"],\"/\",[5,\"8\"]]],[13,\"Cr\",[1,[1,[6,\"std.floor\",[[1,[1,\"GdcCr\",\"/\",\"qChroma\"],\"+\",[5,\"0.5\"]]]],\"*\",\"qChroma\"],\"/\",[5,\"8\"]]],[13,\"r\",[1,\"Y\",\"+\",[1,\"Cr\",\"*\",[5,\"1.402\"]]]],[13,\"g\",[1,[1,\"Y\",\"-\",[1,\"Cb\",\"*\",[5,\"0.344136\"]]],\"-\",[1,\"Cr\",\"*\",[5,\"0.714136\"]]]],[13,\"b\",[1,\"Y\",\"+\",[1,\"Cb\",\"*\",[5,\"1.772\"]]]],[10,[6,\"std.clamp\",[[6,\"d.vec3f\",[\"r\",\"g\",\"b\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.select\":()=>N,\"d.arrayOf\":()=>Fe,\"d.f32\":()=>n,nLuma:()=>e,COS_LUT:()=>j0,SQRT1_2:()=>X0,\"std.cos\":()=>pe,PI_OVER_16:()=>H0,\"std.floor\":()=>ie,LUMA_QUANT_C:()=>IP,CHROMA_QUANT_C:()=>YP,\"d.vec3f\":()=>A}})&&t.f)({})).$name(\"jpegBlockRgb\")}function JA(e){let t=WP.get(e);if(t)return t;let s=Mie(e);return WP.set(e,s),s}function Wz(e){let{nLuma:t,scaleN:s,namePrefix:r,format:o}=e,a=8*s,i=gt({inputWidth:n,inputHeight:n,quality:n}).$name(\"BlockQuantizeParams\"),l=(globalThis.__TYPEGPU_AUTONAME__??(d=>d))(w.bindGroupLayout({input:{texture:Zt(n)},cellTex:{storageTexture:zt(o,\"write-only\")},params:{uniform:i}}),\"layout\"),c=JA(t);return{layout:l,kernel:w.fn([M,M])((d=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(d.f=((u,p)=>{\"use gpu\";let _=l.$.params,f=n(u),h=n(p),g=ie(__tsover_div(f,8)),y=ie(__tsover_div(h,8)),b=__tsover_sub(f,__tsover_mul(g,8)),x=__tsover_sub(h,__tsover_mul(y,8)),P=__tsover_mul(g,a),C=__tsover_mul(y,a),E=Fe(A,64)(),R=j(__tsover_sub(_.inputWidth,1)),U=j(__tsover_sub(_.inputHeight,1));for(let k=0;k<8;k++)for(let D=0;D<8;D++){let O=__tsover_add(__tsover_add(P,__tsover_mul(n(D),s)),__tsover_mul(s,.5)),F=__tsover_add(__tsover_add(C,__tsover_mul(n(k),s)),__tsover_mul(s,.5)),q=G(j(O),0,R),Y=G(j(F),0,U),V=Ye(l.$.input,fe(M(q),M(Y)),0);E[__tsover_add(__tsover_mul(k,8),D)]=Yt(V).xyz}let L=c(E,b,x,_.quality);lt(l.$.cellTex,fe(u,p),S(L,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"cellXf\",[6,\"d.f32\",[\"cx\"]]],[13,\"cellYf\",[6,\"d.f32\",[\"cy\"]]],[13,\"blockCol\",[6,\"std.floor\",[[1,\"cellXf\",\"/\",[5,\"8\"]]]]],[13,\"blockRow\",[6,\"std.floor\",[[1,\"cellYf\",\"/\",[5,\"8\"]]]]],[13,\"localX\",[1,\"cellXf\",\"-\",[1,\"blockCol\",\"*\",[5,\"8\"]]]],[13,\"localY\",[1,\"cellYf\",\"-\",[1,\"blockRow\",\"*\",[5,\"8\"]]]],[13,\"originX\",[1,\"blockCol\",\"*\",\"blockPx\"]],[13,\"originY\",[1,\"blockRow\",\"*\",\"blockPx\"]],[13,\"block\",[6,[6,\"d.arrayOf\",[\"d.vec3f\",[5,\"64\"]]],[]]],[13,\"wm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputWidth\"],\"-\",[5,\"1\"]]]]],[13,\"hm1\",[6,\"d.i32\",[[1,[7,\"p\",\"inputHeight\"],\"-\",[5,\"1\"]]]]],[14,[12,\"y\",[5,\"0\"]],[1,\"y\",\"<\",[5,\"8\"]],[102,\"++\",\"y\"],[0,[[14,[12,\"x\",[5,\"0\"]],[1,\"x\",\"<\",[5,\"8\"]],[102,\"++\",\"x\"],[0,[[13,\"px\",[1,[1,\"originX\",\"+\",[1,[6,\"d.f32\",[\"x\"]],\"*\",\"scaleN\"]],\"+\",[1,\"scaleN\",\"*\",[5,\"0.5\"]]]],[13,\"py\",[1,[1,\"originY\",\"+\",[1,[6,\"d.f32\",[\"y\"]],\"*\",\"scaleN\"]],\"+\",[1,\"scaleN\",\"*\",[5,\"0.5\"]]]],[13,\"ix\",[6,\"std.clamp\",[[6,\"d.i32\",[\"px\"]],[5,\"0\"],\"wm1\"]]],[13,\"iy\",[6,\"std.clamp\",[[6,\"d.i32\",[\"py\"]],[5,\"0\"],\"hm1\"]]],[13,\"texel\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"input\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"ix\"]],[6,\"d.u32\",[\"iy\"]]]],[5,\"0\"]]]],[2,[8,\"block\",[1,[1,\"y\",\"*\",[5,\"8\"]],\"+\",\"x\"]],\"=\",[7,[6,\"blend.unpremultiplyAlpha\",[\"texel\"]],\"xyz\"]]]]]]]],[13,\"rgb\",[6,\"blockRgb\",[\"block\",\"localX\",\"localY\",[7,\"p\",\"quality\"]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"cellTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"rgb\",[5,\"1\"]]]]]]]},externals:{layout:()=>l,\"d.f32\":()=>n,\"std.floor\":()=>ie,blockPx:()=>a,\"d.arrayOf\":()=>Fe,\"d.vec3f\":()=>A,\"d.i32\":()=>j,scaleN:()=>s,\"std.clamp\":()=>G,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"blend.unpremultiplyAlpha\":()=>Yt,blockRgb:()=>c,\"std.textureStore\":()=>lt,\"d.vec4f\":()=>S}})&&d.f)({})).$name(`${r}Cell`),Params:i}}var qz=w.fn([S,S,S,S,S,S,S,S,S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u)=>{\"use gpu\";let p=be(0,.1,__tsover_mul(__tsover_add(__tsover_add(__tsover_add(__tsover_add(t.z,s.z),r.z),o.z),a.z),.2)),_=t.xy.add(s.xy).add(r.xy).add(o.xy).add(a.xy).mul(.2),f=he(_),h=be(.01,.1,f),g=__tsover_div(_.x,__tsover_add(f,.001)),y=__tsover_div(_.y,__tsover_add(f,.001)),b=be(0,.7,B(g,0)),x=be(0,.7,B(__tsover_mul(g,-1),0)),P=be(0,.7,B(y,0)),C=be(0,.7,B(__tsover_mul(y,-1),0)),E=d.mul(x).add(u.mul(b)),R=c.mul(C).add(l.mul(P)),U=__tsover_add(x,b),L=__tsover_add(P,C),k=__tsover_add(__tsover_add(U,L),.001);return K(i,E.mul(__tsover_div(U,k)).add(R.mul(__tsover_div(L,k))),S(h)).mul(p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s0\"},{type:\"i\",name:\"s1\"},{type:\"i\",name:\"s2\"},{type:\"i\",name:\"s3\"},{type:\"i\",name:\"s4\"},{type:\"i\",name:\"base\"},{type:\"i\",name:\"up\"},{type:\"i\",name:\"down\"},{type:\"i\",name:\"left\"},{type:\"i\",name:\"right\"}],body:[0,[[13,\"smoothedLiquid\",[1,[1,[1,[1,[1,[7,\"s0\",\"z\"],\"+\",[7,\"s1\",\"z\"]],\"+\",[7,\"s2\",\"z\"]],\"+\",[7,\"s3\",\"z\"]],\"+\",[7,\"s4\",\"z\"]],\"*\",[5,\"0.2\"]]],[13,\"liquidIntensity\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.1\"],\"smoothedLiquid\"]]],[13,\"flow\",[6,[7,[6,[7,[6,[7,[6,[7,[6,[7,[7,\"s0\",\"xy\"],\"add\"],[[7,\"s1\",\"xy\"]]],\"add\"],[[7,\"s2\",\"xy\"]]],\"add\"],[[7,\"s3\",\"xy\"]]],\"add\"],[[7,\"s4\",\"xy\"]]],\"mul\"],[[5,\"0.2\"]]]],[13,\"flowMagnitude\",[6,\"std.length\",[\"flow\"]]],[13,\"hasFlow\",[6,\"std.smoothstep\",[[5,\"0.01\"],[5,\"0.1\"],\"flowMagnitude\"]]],[13,\"normalizedX\",[1,[7,\"flow\",\"x\"],\"/\",[1,\"flowMagnitude\",\"+\",[5,\"0.001\"]]]],[13,\"normalizedY\",[1,[7,\"flow\",\"y\"],\"/\",[1,\"flowMagnitude\",\"+\",[5,\"0.001\"]]]],[13,\"rightAmount\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.7\"],[6,\"std.max\",[\"normalizedX\",[5,\"0\"]]]]]],[13,\"leftAmount\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.7\"],[6,\"std.max\",[[1,\"normalizedX\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"]]]]]],[13,\"upAmount\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.7\"],[6,\"std.max\",[\"normalizedY\",[5,\"0\"]]]]]],[13,\"downAmount\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.7\"],[6,\"std.max\",[[1,\"normalizedY\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"]]]]]],[13,\"horizontalColor\",[6,[7,[6,[7,\"left\",\"mul\"],[\"leftAmount\"]],\"add\"],[[6,[7,\"right\",\"mul\"],[\"rightAmount\"]]]]],[13,\"verticalColor\",[6,[7,[6,[7,\"down\",\"mul\"],[\"downAmount\"]],\"add\"],[[6,[7,\"up\",\"mul\"],[\"upAmount\"]]]]],[13,\"horizontalWeight\",[1,\"leftAmount\",\"+\",\"rightAmount\"]],[13,\"verticalWeight\",[1,\"upAmount\",\"+\",\"downAmount\"]],[13,\"totalWeight\",[1,[1,\"horizontalWeight\",\"+\",\"verticalWeight\"],\"+\",[5,\"0.001\"]]],[13,\"directionalColor\",[6,[7,[6,[7,\"horizontalColor\",\"mul\"],[[1,\"horizontalWeight\",\"/\",\"totalWeight\"]]],\"add\"],[[6,[7,\"verticalColor\",\"mul\"],[[1,\"verticalWeight\",\"/\",\"totalWeight\"]]]]]],[13,\"finalColor\",[6,\"std.mix\",[\"base\",\"directionalColor\",[6,\"d.vec4f\",[\"hasFlow\"]]]]],[10,[6,[7,\"finalColor\",\"mul\"],[\"liquidIntensity\"]]]]]},externals:{\"std.smoothstep\":()=>be,\"std.length\":()=>he,\"std.max\":()=>B,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"flowDirectionColor\"),og={name:\"Root\",props:{},fragment:({childNode:e})=>e??ca(\"vec4f(0.0, 0.0, 0.0, 0.0)\")};function wt(e,t,s=\"_animTime\"){let r=e.props.member(s);if(t){let o=e.uniforms[t];if(o)return r.add(o)}return r}var Eie=class{kind=\"wgsl\";spec;identifiers;fns=new Map;constructor(e){if(typeof e.body!=\"string\"||e.body.trim()===\"\")throw new Error(\"wgsl: the body must be a non-empty WGSL string\");if(!/\\breturn\\b/.test(Vz(e.body)))throw new Error(\"wgsl: the body must `return` a vec4f color\");this.spec=e,this.identifiers=kie(e.body)}get samplesChild(){return this.identifiers.has(\"childTexture\")}fnFor(e,t){let s=this.fns.get(e);return s||(s=t(),this.fns.set(e,s)),s}};function L_(e){return e instanceof Eie}function Vz(e){return e.replace(/\\/\\*[\\s\\S]*?\\*\\//g,\" \").replace(/\\/\\/[^\\n]*/g,\" \")}function kie(e){let t=new Set,s=new RegExp(\"(?<![\\\\w.])[A-Za-z_][A-Za-z0-9_]*\",\"g\");for(let r of Vz(e).matchAll(s))t.add(r[0]);return t}function Nz(e){let t=e.transform;if(t===ce)return\"vec4f\";if(t===Xe)return\"vec2f\";if(t===hl||t===_c)return null;let s=e.default;if(z_(s))return\"f32\";let r=bz(t);if(!r&&(typeof s==\"string\"||typeof s==\"object\"&&s!==null&&!Array.isArray(s)))return null;let o=s;if(r)try{o=r(s)}catch{o=s}switch(o&&typeof o==\"object\"&&\"data\"in o&&(o=o.data),Mk(o).type){case\"f32\":return\"f32\";case\"vec2f\":return\"vec2f\";case\"vec3f\":return\"vec3f\";case\"vec4f\":return\"vec4f\";default:return null}}var Bie={f32:n,vec2f:m,vec3f:A,vec4f:S,\"texture_2d<f32>\":Zt(n),sampler:v3()},zie=new Set([\"viewport\",\"child\",\"childTexture\",\"childSampler\"]),$z={uv:\"vec2f\",aspect:\"f32\",time:\"f32\",viewportSize:\"vec2f\",logicalViewportSize:\"vec2f\",pointer:\"vec2f\"};function qP(e){return/^[A-Za-z_][A-Za-z0-9_]*$/.test(e)?e:e.replace(/[^A-Za-z0-9_]/g,\"_\")}function e2(e,t,s){let r=qP(e.spec.name??Rie(s.name)+Die(t)),o=Lie(t,s),a=Uie(e.spec.inputs??{},s.props),i=new Map;for(let u of o)e.identifiers.has(u.name)&&i.set(u.name,u);for(let u of a)i.set(u.name,u);let l=[...i.values()],c=`(${l.map(u=>`${qP(u.name)}: ${u.type}`).join(\", \")}) -> vec4f`,d=l.map(u=>`${u.name}:${u.type}`).join(\",\");return u=>(U5(),u.noteCustomWgsl?.(),W(e.fnFor(d,()=>(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(w.fn(l.map(p=>Bie[p.type]),S),\"shell\")(`${c} {\n${e.spec.body}\n}`)),r,l.map(p=>p.value(u))))}function Rie(e){return e?e[0].toLowerCase()+e.slice(1):\"custom\"}function Die(e){return e===\"generator\"?\"Paint\":\"Filter\"}function Lie(e,t){let s=[],r=e===\"generator\";s.push({name:\"uv\",type:\"vec2f\",value:o=>r?o.uvContext??o.ctx.uv:o.ctx.uv}),s.push({name:\"time\",type:\"f32\",value:o=>t.animatedTime?wt(o):o.ctx.time}),s.push({name:\"aspect\",type:\"f32\",value:o=>o.ctx.aspect}),s.push({name:\"viewport\",type:\"vec2f\",value:o=>r?o.effectiveViewportSize??o.ctx.viewportSize:o.ctx.viewportSize}),s.push({name:\"pointer\",type:\"vec2f\",value:o=>o.ctx.pointer}),e===\"pointwise\"&&s.push({name:\"child\",type:\"vec4f\",value:o=>o.childNode}),e===\"gather\"&&(s.push({name:\"childTexture\",type:\"texture_2d<f32>\",value:o=>o.texture.accessor()}),s.push({name:\"childSampler\",type:\"sampler\",value:()=>ca(\"samp.$.linearClamp\")}));for(let[o,a]of Object.entries(t.props)){if($z[o]||zie.has(o))continue;let i=Nz(a);if(!i)continue;let l=a.transform===Xe;s.push({name:o,type:i,value:c=>{let d=c.uniforms[o];if(!d)throw new Error(`wgsl: prop '${o}' has no GPU uniform (is it CPU-only?)`);return l?new fs(u=>`vec2f(${d.member(\"x\")._emit(u)}, 1.0 - ${d.member(\"y\")._emit(u)})`):d}})}return s}function Uie(e,t){let s=[];for(let[r,o]of Object.entries(e)){let a=o!==null&&typeof o==\"object\"&&\"value\"in o&&\"type\"in o,i=a?o.value:o,l=Oie(i,t),c=a?o.type:l;if(a&&c!==l)throw new Error(`wgsl: input '${r}' is declared ${c} but its source is ${l}`);s.push({name:r,type:c,value:d=>typeof i==\"number\"?$e(i):Az(i,d)})}return s}function Oie(e,t){if(typeof e==\"number\"||e instanceof zi)return\"f32\";if(e.kind===\"ctx\")return $z[e.name]??\"f32\";if(e.kind===\"prop\"){let s=t[e.name];if(!s)throw new Error(`wgsl: input binds unknown prop '${e.name}'`);let r=Nz(s);if(!r)throw new Error(`wgsl: prop '${e.name}' is CPU-only and cannot be bound as a WGSL parameter`);return r}return\"f32\"}function fc(e){let t={};for(let s of Object.keys(e)){let{recompile:r,...o}=e[s],a={...o};if(r?.kind===\"crosses\"){let i=r.value;a.compileTimeWhen=(l,c)=>l===i!=(c===i)}else r?.kind===\"custom\"&&(a.compileTimeWhen=r.predicate);t[s]=a}return t}function Xz(e,t){switch(e.kind){case\"isZero\":case\"isValue\":{let s=e.kind===\"isZero\"?0:e.value,r=t[e.prop];return{props:[e.prop],when:o=>(o[e.prop]??r)===s}}case\"allOf\":{let s=e.rules.map(r=>Xz(r,t));return{props:[...new Set(s.flatMap(r=>r.props))],when:r=>s.every(o=>o.when(r))}}case\"custom\":return{props:e.props,when:e.when}}}function lh(e,t){if(!e)return;let s={};for(let[r,o]of Object.entries(t))s[r]=o.default;return Xz(e,s)}function Gie(e){let{role:t,species:s,effect:r,identityWhen:o,missingChildMessage:a,props:i,...l}=e,c={...l,props:fc(i),identity:lh(o,i),missingChildMessage:a};if(r.kind===\"tintToward\"){let{color:p,amount:_}=r;return V0({...c,body:{fn:Kk,hint:\"mixToward\"},args:f=>[me(p,f),fn(_,f)]})}if(L_(r))return V0({...c,build:e2(r,\"pointwise\",t2(e))});let{kind:d,...u}=r;return V0({...c,...u})}function t2(e){return{name:e.name,props:e.props,animatedTime:e.animatedTime}}function Fie(e){let{role:t,species:s,effect:r,identityWhen:o,missingChildMessage:a,props:i,...l}=e;if(r.kind===\"displaceBy\")return Iie(e);if(L_(r))return EP({...l,props:fc(i),identity:lh(o,i),missingChildMessage:a,build:e2(r,\"gather\",t2(e)),resultAlpha:r.spec.alpha??\"premultiplied\"});let{kind:c,...d}=r;return EP({...l,props:fc(i),identity:lh(o,i),missingChildMessage:a,...d})}function Iie(e){let{role:t,species:s,effect:r,identityWhen:o,missingChildMessage:a,props:i,...l}=e,c=r,d=lh(o,i),u=c.field.sim.config,p=c.field.output,_=u.step.find(h=>h.kind===\"op.wave\"),f=u.step.find(h=>h.kind===\"op.splat\");if(!_||!f||u.step.length!==2)throw new Error(`std: simulate.grid currently implements exactly [op.wave, op.splat] (got: ${u.step.map(h=>h.kind).join(\", \")})`);if(u.history!==2)throw new Error(`std: op.wave reads t\\u22121 and t\\u22122 \\u2014 declare history: 2 (got ${u.history})`);if(u.derive[p]?.kind!==\"op.gradient\")throw new Error(`std: displaceBy consumes a vector field \\u2014 derive '${p}' must be op.gradient()`);if(u.rest&&u.rest.settlesWhen!==\"derived-from-damping\")throw new Error(\"std: simulate.grid rest supports settlesWhen: 'derived-from-damping' only\");return{...l,props:fc(i),requiresRTT:!0,requiresChild:!0,usesPointer:f.at.kind===\"pointer\",compute:h=>{if(!h.childNode)return null;let g=Lae(h,{resolution:u.resolution,dampingProp:_.damping.name,radiusProp:f.radius.name,radiusScale:.05,speedMax:f.amount.max,teleportGuard:f.at.teleportGuard});return g?{outputs:{[p]:g.displacement},getComputeNodes:g.getComputeNodes}:null},fragment:h=>{let{childNode:g,ctx:y,computeOutputs:b,propValues:x,convertToTexture:P}=h;if(!g)return xt;let C=P(g);if(XA(d,h))return W(Yt,\"unpremultiplyAlpha\",[C.sample(y.uv)]);let E=x[c.edges.name]??0,R=b?.[p],U=R?R.sample(y.uv,\"linearClamp\").member(\"xy\"):ca(\"vec2f(0.0, 0.0)\"),L=W(fee,\"chromaticDisplaceUVs\",[y.uv,U,me(c.strength,h),me(c.chromatic,h)]),k=q=>C.sample(q),D=Ha(L.member(\"rUV\"),k,E),O=Ha(L.member(\"gUV\"),k,E),F=Ha(L.member(\"bUV\"),k,E);return W(Yt,\"unpremultiplyAlpha\",[Ct(D.member(\"r\"),O.member(\"g\"),F.member(\"b\"),O.member(\"a\"))])}}}function Yie(e){let{role:t,map:s,edges:r,resample:o,uvRemapIdentityWhen:a,missingChildMessage:i,props:l,...c}=e;return{...c,props:fc(l),requiresRTT:!0,requiresChild:!0,...Qne(s,{edges:r,resample:o,uvRemapIdentityWhen:a,requireChildMessage:i})}}function Wie(e){let{role:t,name:s,description:r,category:o,shape:a}=e;return nie({name:s,description:r,category:o,...a})}function qie(e){let{role:t,paint:s,props:r,...o}=e;return L_(s)?{acceptsUVContext:!0,...o,props:fc(r),fragment:e2(s,\"generator\",t2(e))}:{...o,props:fc(r),fragment:s}}function Vie(e){let{role:t,species:s,gpu:r,props:o,...a}=e;return{...a,props:fc(o),fragment:r.fragment,...r.uvRemap?{uvRemap:r.uvRemap}:{}}}function Nie(e){let t=[],s=e.paint,r=e.effect;for(let a of[s,r])L_(a)&&t.push(a.spec.body,$ie(a.spec.inputs??{}),a.spec.alpha??\"\");if(t.length===0)return;let o=2166136261;for(let a of t.join(\"\\0\"))o^=a.charCodeAt(0),o=Math.imul(o,16777619)>>>0;return o.toString(16)}function $ie(e){let t=r=>{if(typeof r!=\"object\"||r===null)return String(r);let o=r;switch(o.kind){case\"prop\":return`p:${o.name}`;case\"ctx\":return`c:${o.name}`;case\"mul\":return`mul(${t(o.a)},${t(o.b)})`;case\"radialMask\":return`radialMask(${o.center?.name},${o.radius?.name},${o.falloff?.name})`;default:return o.kind}},s=r=>typeof r==\"number\"?`n:${r}`:r instanceof zi?`s:${t(r.node)}`:t(r);return Object.keys(e).sort().map(r=>{let o=e[r];return o!==null&&typeof o==\"object\"&&\"value\"in o&&\"type\"in o?`${r}=${s(o.value)}:${o.type}`:`${r}=${s(o)}`}).join(\",\")}var Xie=new Set([\"blendMode\",\"opacity\",\"visible\",\"id\",\"maskSource\",\"maskType\",\"renderOrder\",\"transform\",\"boundingBox\",\"flow\",\"absolute\",\"children\",\"ref\",\"key\",\"src\"]),Hie=new Set([\"_animTime\",\"_opacity\"]),jie=[\"_pad\",\"_bbox_\",\"_map_\",\"_childBounds_\",\"_animTime_\"],Kie=/^[A-Za-z_][A-Za-z0-9_]*$/;function Qie(e,t){for(let s of Object.keys(t)){if(!Kie.test(s))throw new Error(`defineShader(\"${e}\"): prop '${s}' is not a valid identifier (letters, digits and _ only, not starting with a digit)`);if(Xie.has(s))throw new Error(`defineShader(\"${e}\"): '${s}' is a layer prop every component already has (blend mode, opacity, layout, \\u2026) \\u2014 rename the shader prop`);if(Hie.has(s)||jie.some(r=>s.startsWith(r)))throw new Error(`defineShader(\"${e}\"): '${s}' collides with a field the renderer manages itself \\u2014 rename the shader prop`)}}function H(e){\"props\"in e&&e.props&&Qie(e.name,e.props);let t=tle(e),s=Nie(e);return s?{...t,revision:s}:t}function Zie(e){let t=\"shape\"in e?\"shape\":\"map\"in e?\"warp\":\"gpu\"in e?\"custom\":\"paint\"in e?\"generator\":\"effect\"in e?\"filter\":null,s=String(e.name??\"?\");if(!t)throw new Error(`defineShader(\"${s}\"): give it a GPU half \\u2014 paint: (generator), effect: (filter), map: (warp), shape: (shape) or gpu: (custom)`);let r=e.role;if(r&&t!==\"custom\"&&r!==t)throw new Error(`defineShader(\"${s}\"): role '${r}' contradicts its ${Jie[t]} field (a ${t})`);return t}var Jie={shape:\"shape:\",warp:\"map:\",custom:\"gpu:\",generator:\"paint:\",filter:\"effect:\"};function ele(e){let{effect:t,species:s}=e;if(L_(t))return s??(t.samplesChild?\"gather\":\"pointwise\");let r=t.kind===\"gather\"||t.kind===\"displaceBy\"?\"gather\":\"pointwise\";if(s&&s!==r)throw new Error(`defineShader(\"${e.name}\"): species '${s}' contradicts its '${t.kind}' effect (${r})`);return r}function tle(e){switch(Zie(e)){case\"shape\":return Wie(e);case\"warp\":return Yie(e);case\"custom\":return Vie(e);case\"generator\":return qie(e);case\"filter\":{let t=e;return ele(t)===\"gather\"?Fie({...t,species:\"gather\"}):Gie({...t,species:\"pointwise\"})}}}var kx=e=>typeof e==\"number\"?$e(e):e,ud=(e,t)=>typeof e==\"number\"?$e(e)._emit(t):e._emit(t);function Wr(e,...t){return new fs(s=>`${e}(${t.map(r=>ud(r,s)).join(\", \")})`)}function Ac(e,t,s){return new fs(r=>`(${ud(t,r)} ${e} ${ud(s,r)})`)}var I=(e,t)=>Ac(\"+\",e,t),ne=(e,t)=>Ac(\"-\",e,t),v=(e,t)=>Ac(\"*\",e,t),Ce=(e,t)=>Ac(\"/\",e,t),er=e=>new fs(t=>`(-(${ud(e,t)}))`),ms=e=>Wr(\"abs\",e),Xr=e=>Wr(\"floor\",e);var Qr=e=>Wr(\"fract\",e),ho=e=>Wr(\"sqrt\",e),ts=(e,t)=>Wr(\"pow\",e,t),tr=e=>Wr(\"exp\",e);var Vt=e=>Wr(\"sin\",e),Do=e=>Wr(\"cos\",e);var sle=(e,t)=>Wr(\"atan2\",e,t),Yr=(e,t)=>Wr(\"min\",e,t),it=(e,t)=>Wr(\"max\",e,t),Ge=(e,t,s)=>Wr(\"clamp\",e,t,s),et=(e,t,s)=>ea(kx(e),kx(t),s),ag=(e,t)=>Wr(\"step\",e,t),ot=(e,t,s)=>Wr(\"smoothstep\",e,t,s),Bx=e=>Wr(\"sign\",e),Kr=e=>Wr(\"length\",e);var $t=(e,t)=>Wr(\"dot\",e,t),Os=e=>Wr(\"normalize\",e);var ng=(e,t,s)=>rt(ne(v(b1(e,\"x\"),t),v(b1(e,\"y\"),s)),I(v(b1(e,\"x\"),s),v(b1(e,\"y\"),t))),b1=(e,t)=>typeof e==\"number\"?e:e.member(t),Lo=(e,t)=>Wr(\"reflect\",e,t),ig=(e,t,s)=>Wr(\"refract\",e,t,s),U_=e=>Wr(\"exp2\",e),s2=(e,t)=>v(Qr(v(Vt(v(e,t.k)),t.big)),6.283185307179586),Xn=(e,t)=>Ac(\"<\",e,t),Hz=(e,t)=>Ac(\"<=\",e,t),Zo=(e,t)=>Ac(\">\",e,t),ch=(e,t)=>Ac(\">=\",e,t),br=(e,t,s)=>new fs(r=>`select(${ud(s,r)}, ${ud(t,r)}, ${ud(e,r)})`),It=e=>$e(e),rt=(e,t)=>Wr(\"vec2f\",e,t),Qe=(e,t,s)=>Wr(\"vec3f\",e,t,s),Ot=(...e)=>Ct(...e.map(kx)),kt=e=>Wr(\"vec3f\",e),z=(e,t)=>ns(e,t),jz=(e,t)=>{let s=z(e,\"sp\");return v(I(s,ho(I(v(s,s),v(t,t)))),.5)},O_=(e,t)=>tr(er(v(v(e,e),t)));function Kz(e,t){return{kind:\"tintToward\",color:e,amount:t.amount}}function Qz(e,t){return{kind:\"displaceBy\",field:e,strength:t.strength,chromatic:t.chromatic,edges:t.edges}}function Rd(e){return{kind:\"gather\",...e}}function Zz(e){return v(ot(e.below.from,e.below.to,e.distance),ne(1,ot(e.above.from??0,e.above.to,e.distance)))}function Jz(e){let{width:t,curve:s}=e.softness;return ts(ne(1,ot(ne(e.radius,t),I(e.radius,t),e.dist)),s)}function mp(e){let t=v(e.footprint,.5);return ne(1,ot(er(t),t,e.distance))}function eR(e){return mp({distance:ne(ms(e.distance),v(e.width,.5)),footprint:e.footprint})}function tR(e){return new zi({kind:\"radialMask\",center:e.center,radius:e.radius,falloff:e.falloff})}var lg={wave(e){return{kind:\"op.wave\",damping:e.damping}},splat(e){return{kind:\"op.splat\",at:e.at,amount:e.amount,radius:e.radius}},gradient(){return{kind:\"op.gradient\"}}},rle=class{constructor(e){this.config=e}output(e){if(!(e in this.config.derive))throw new Error(`std: simulation has no derived output '${e}' (declared: ${Object.keys(this.config.derive).join(\", \")})`);return{kind:\"simOutput\",sim:this,output:e}}},sR={grid(e){return new rle(e)}};function rR(e){return{kind:\"pointer\",teleportGuard:e?.teleportGuard??\"on\"}}function oR(e){return{kind:\"pointerSpeed\",max:e?.max??2}}function aR(e,t,s){e.onBeforeRender(()=>{let r=e.getCpuValue(t.x),o=e.getCpuValue(t.y),a=e.getCpuValue(t.z),i=Math.sqrt(r*r+o*o+a*a);i>0?(e.setExtraField(s.x,r/i),e.setExtraField(s.y,o/i),e.setExtraField(s.z,a/i)):(e.setExtraField(s.x,0),e.setExtraField(s.y,0),e.setExtraField(s.z,0))})}function wc(e){let t=Math.sin(e*12.9898)*43758.5453;return t-Math.floor(t)}function Lt(e){return{kind:\"crosses\",value:e}}function hn(e){return{kind:\"custom\",predicate:e}}function Uo(e){return{kind:\"isZero\",prop:e}}function cg(e,t){return{kind:\"isValue\",prop:e,value:t}}function nR(...e){return{kind:\"allOf\",rules:e}}var ole=e=>typeof e==\"number\"?$e(e):e,Ma=(e,t)=>(...s)=>W(e,t,s.map(ole)),_p=Ma(Dm,\"circleSdf\"),iR=Ma(Iv,\"ellipseSdf\"),dg=Ma(Fv,\"roundedRectSdf\"),lR=Ma(Dv,\"polygonSdf\"),cR=Ma(Uv,\"starSdf\"),dR=Ma(Lv,\"flowerSdf\"),uR=Ma(Vv,\"heartSdf\"),pR=Ma(Gv,\"crossSdf\"),mR=Ma(Ov,\"ringSdf\"),_R=Ma(Yv,\"vesicaSdf\"),fR=Ma(Wv,\"crescentSdf\"),vR=Ma(qv,\"trapezoidSdf\"),hR=Ma($v,\"teardropSdf\"),gR=Ma(Xv,\"parallelogramSdf\"),yR=Ma(Nv,\"arcSdf\"),bR=CB,ft=Math.fround,ale=ft(aJ),K0=ft(Jt),nle=.11,zx=ft(4294967295),VP=new DataView(new ArrayBuffer(4));function Rx(e){return VP.setFloat32(0,ft(e),!0),VP.getUint32(0,!0)}function dh(e,t){return Math.imul(e>>>0,t>>>0)>>>0}function NP(e){let t=Rx(ft(ft(e)*ft(3141592653)));return ft(ft(dh(dh(t,t),3141592653))/zx)}function $P(e,t){let s=(Rx(ft(ft(e)*ft(141421356)))^Rx(ft(ft(t)*ft(2718281828))))>>>0;return[ft(ft(dh(s,3141592653))/zx),ft(ft(dh(s,1618033988))/zx)]}function ile(e,t,s,r,o,a){let i=ft(ft(e*ale)+ft(NP(ft(ft(s*ft(.7311))+ft(1.618)))*K0)),l=ft(Math.sqrt(ft(ft(e+.5)/ft(t)))),c=$P(ft(ft(e*ft(3.77))+ft(.917)),ft(ft(s*ft(1.093))+ft(2.236))),d=ft(ft(c[0]-.5)*ft(.26)),u=ft(ft(c[1]-.5)*ft(.26)),p=$P(ft(ft(e*ft(7.13))+ft(1.618)),ft(ft(s*ft(.531))+ft(3.71))),_=ft(p[0]*K0),f=ft(p[1]*K0),h=ft(.5+ft(NP(ft(ft(ft(e*ft(5.417))+ft(s*ft(.291)))+ft(.917)))*ft(.7))),g=ft(ft(a*ft(nle))*h),y=ft(Math.sin(ft(g+_))),b=ft(Math.cos(ft(ft(g*ft(1.37))+f))),x=ft(ft(ft(ft(Math.cos(i))*l)*ft(.62))+d)+ft(ft(y*ft(r))*ft(.16)),P=ft(ft(ft(ft(Math.sin(i))*l)*ft(.62))+u)+ft(ft(b*ft(r))*ft(.16));return[ft(ft(.5+ft(x))*ft(o)),ft(.5+ft(P))]}function lle(e,t,s,r,o){let a=new Array(16);for(let i=0;i<8;i++){let[l,c]=ile(i,e,t,s,r,o);a[i*2]=l,a[i*2+1]=c}return a}function XP(e,t){return typeof e==\"number\"?$e(e):e instanceof zi||e.kind!==\"ctx\"?fn(e,t):t.ctx[e.name]}function oo(e,t){if(typeof e==\"object\"&&e!==null&&\"base\"in e){let s=XP(e.base,t);return e.add!==void 0&&(s=s.add(e.add)),e.mul!==void 0&&(s=s.mul(e.mul)),s}return XP(e,t)}function Kc(e){return{uv:e.uvContext??e.ctx.uv,viewport:e.effectiveViewportSize??e.ctx.viewportSize}}function r2(e,t){return t.propValues[e.name]}function G_(e){return typeof e==\"number\"?e:typeof e==\"string\"?at(e):0}function ug(e,t){return No[e?G_(t.propValues[e.name]):0]??Ar}function pg(e){return(t,s,r)=>{let o=ug(e.space,r);return W(o,\"mixColors\",[W(o,\"mixColors\",[me(e.a,r),me(e.b,r),t]),me(e.c,r),s])}}function xR(e,t,s){return(r,o)=>W(No[G_(r2(s,o))]??Ar,\"mixColors\",[me(e,o),me(t,o),r])}function Us(e){return(t,s)=>{let r=G_(r2(e,s));return(s.propValues.stopCount??0)>1?En(t,{colorsArray:s.uniforms.colorsArray,positionsArray:s.uniforms.positionsArray,convertedColorsArray:s.uniforms.convertedColorsArray,stopCount:s.uniforms.stopCount},r):W(No[r]??Ar,\"mixColors\",[s.uniforms.colorA,s.uniforms.colorB,t])}}var HP=1,cle=2,dle=3;function Vs(e,t,s){return r=>{let{uv:o}=Kc(r),a=e(r,o);if(!s?.edges)return t(a,r);let i=r2(s.edges,r)??0,l;i===cle?l=W(S4,\"gradientEdgeMirror\",[a]):i===dle?l=W(Ate,\"gradientEdgeWrap\",[a]):i===HP?l=a:l=W(pS,\"gradientClamp01\",[a]);let c=t(W(pS,\"gradientClamp01\",[l]),r);if(i===HP){let d=W(wte,\"gradientTransparentAlpha\",[a]);return Ct(c.member(\"rgb\"),c.member(\"a\").mul(d))}return c}}var Oi={linear(e){return(t,s)=>{let{viewport:r}=Kc(t);return W(xte,\"gradientRawT\",[me(e.from,t),me(e.to,t),oo(e.angle,t),s,r])}},radial(e){return(t,s)=>{let{viewport:r}=Kc(t);return W(Tte,\"radialDist\",[me(e.center,t),oo(e.skew,t),oo(e.aspect,t),oo(e.radius,t),s,r])}},conic(e){return(t,s)=>{let{viewport:r}=Kc(t);return W(Ste,\"conicSweep\",[me(e.center,t),oo(e.rotation,t),s,r])}},diamond(e){return(t,s)=>{let{viewport:r}=Kc(t);return W(Pte,\"diamondDist\",[me(e.center,t),oo(e.size,t),oo(e.rotation,t),oo(e.roundness,t),s,r])}},spiral(e){return(t,s)=>{let{viewport:r}=Kc(t);return W(Rte,\"spiralMask\",[me(e.center,t),oo(e.scale,t),oo(e.width,t),oo(e.falloff,t),oo(e.softness,t),wt(t),s,r])}}};function mg(e,t){return(s,r)=>W(Cte,\"repeatRings\",[e(s,r),oo(t,s)])}function AR(e,t){return(s,r)=>W(Mte,\"repeatWrap\",[e(s,r),oo(t,s)])}function wR(e,t){return(s,r)=>W(Ute,\"toneRemap\",[e(s,r),oo(t.glow,s),oo(t.contrast,s),oo(t.balance,s)])}function TR(e,t){return(s,r)=>W(Ite,\"unitThreshold\",[e(s,r),t.bias!==void 0?oo(t.bias,s):$e(0),$e(t.low),$e(t.high)])}function F_(e){let t=new WeakMap;return(s,r)=>{let o=t.get(s);return o||(o=ns(e(s,r),\"field\"),t.set(s,o)),o}}var ule={mx3:{fn:()=>Gte,hint:\"unitNoise3\"},perlin:{fn:()=>mu,hint:\"perlin13\"},value:{fn:()=>iJ,hint:\"value13\"},mx3signed:{fn:()=>Na,hint:\"mxNoiseFloat3\"}};function Tc(e){let t=ule[e];return(s,r)=>W(t.fn(),t.hint,[r])}function SR(e,t){let s=Ok(Na,{name:\"warpDomain\"});return(r,o)=>{let a=oo(t.amount,r);t.amountScale!==void 0&&(a=a.mul(t.amountScale));let i=wt(r);return t.timeScale!==void 0&&(i=i.mul(t.timeScale)),e(r,W(s,\"warpDomain\",[o,i,a]))}}function PR(e,t){return(s,r)=>{let{viewport:o}=Kc(s);return e(s,W(Ote,\"volumeDomain\",[r,o,oo(t.scale,s)]))}}function CR(e){return(t,s)=>W(Fte,\"flowLayers\",[s,oo(e.detail,t),wt(t)])}function MR(e,t){return(s,r)=>W(Yte,\"shimmerPulse\",[e(s,r),wt(s),$e(t.speed),$e(t.span),$e(t.depth)])}function ER(e){let t=z(v(Qr(e),6),\"hue6\");return Qe(Ge(ne(ms(ne(t,3)),1),0,1),Ge(ne(2,ms(ne(t,2))),0,1),Ge(ne(2,ms(ne(t,4))),0,1))}function kR(e,t){return s=>e(s).mul(t(s,s.ctx.uv))}function BR(e){let t=s=>typeof s==\"number\"?$e(s):s;return e.anchors?W(PJ,\"scatterField\",[e.at,t(e.count),t(e.seed),e.anchors,t(e.softness)]):W(CJ,\"scatterField\",[e.at,t(e.count),t(e.seed),t(e.drift),t(e.aspect),t(e.time),t(e.softness)])}function zR(e,t){let s=e.dimensions.width/Math.max(e.dimensions.height,1e-6);e.onResize(({width:o,height:a})=>{s=o/Math.max(a,1e-6)});let r=\"\";return e.onBeforeRender(()=>{let o=e.getCpuValue(\"_animTime\"),a=e.getCpuValue(t.count.name),i=e.getCpuValue(t.seed.name),l=e.getCpuValue(t.drift.name);if(typeof o!=\"number\"||typeof a!=\"number\"||typeof i!=\"number\"||typeof l!=\"number\")return;let c=`${a}|${i}|${l}|${s}|${o}`;c!==r&&(r=c,e.setExtraField(t.field,lle(a,i,l,s,o)))}),e.uniforms[t.field]}function RR(e){return W(jte,\"rampWrap\",[e.t,typeof e.cycles==\"number\"?$e(e.cycles):e.cycles])}function DR(e){return W(S4,\"gradientEdgeMirror\",[e])}function LR(e){let t=s=>typeof s==\"number\"?$e(s):s;return e.levels===1?W(TJ(Na,{name:\"warpDomain1\"}),\"warpDomain1\",[e.at,t(e.time),t(e.amount)]):W(Ok(Na,{name:\"warpDomain\"}),\"warpDomain\",[e.at,t(e.time),t(e.amount)])}function o2(e){let t=s=>typeof s==\"number\"?$e(s):s;return W(MJ,\"chainedWarpStep\",[e.at,$e(e.scale),t(e.z),rt(e.offsets[0][0],e.offsets[0][1]),rt(e.offsets[1][0],e.offsets[1][1]),$e(e.reach),t(e.strength)])}function UR(e,t){return Oae(t,e)}function OR(e){return(t,s,r)=>{let{uniforms:o}=r,a=G_(r.propValues[e.space.name]),i=me(e.a,r),l=me(e.b,r),c=me(e.c,r),d=me(e.d,r);if(a!==0){let u=\"\";r.onBeforeRender(()=>{let f=[e.a.name,e.b.name,e.c.name,e.d.name].map(y=>r.getCpuValue(y));if(f.some(y=>!y))return;let h=f.map(y=>`${y.x},${y.y},${y.z}`).join(\"|\");if(h===u)return;u=h;let g=[\"convA\",\"convB\",\"convC\",\"convD\"];f.forEach((y,b)=>{let x=fl(y.x,y.y,y.z,a);r.setExtraField(g[b],[x[0],x[1],x[2]])})});let p=ns(W(_l,\"mixInSpace\",[o.convA,i.member(\"a\"),o.convB,l.member(\"a\"),t]),\"flowRow1\"),_=ns(W(_l,\"mixInSpace\",[o.convC,c.member(\"a\"),o.convD,d.member(\"a\"),t]),\"flowRow2\");return W(Bd[a]??hc,\"mixPreconvertedColors\",[p.member(\"conv\"),_.member(\"conv\"),p.member(\"alpha\"),_.member(\"alpha\"),s])}return W(Ar,\"mixColors\",[ns(W(Ar,\"mixColors\",[i,l,t]),\"flowRow1\"),ns(W(Ar,\"mixColors\",[c,d,t]),\"flowRow2\"),s])}}function ad(e,t){return typeof e==\"number\"?$e(e):e instanceof zi||e.kind!==\"ctx\"?fn(e,t):t.ctx[e.name]}function a2(e){return{uv:e.uvContext??e.ctx.uv,viewport:e.effectiveViewportSize??e.ctx.viewportSize}}function uh(e,t){return t.propValues[e.name]}function GR(e){return t=>me(e,t)}function FR(e){return t=>{let{uv:s,viewport:r}=a2(t),o=wt(t),a=W(Ete,\"colorWheelT\",[s,r,ad(e.direction,t),ad(e.scale,t),o]);if((uh(e.mode,t)??\"rainbow\")===\"rainbow\")return W(kte,\"colorWheelRainbow\",[a]);let i=z(W(Bte,\"colorWheelPhase\",[a]),\"wheelPhase\"),l=i.member(\"x\"),c=i.member(\"y\"),d=No[uh(e.space,t)??0]??Ar;return W(zte,\"colorWheelSelect\",[W(d,\"mixColors\",[me(e.palette.a,t),me(e.palette.b,t),l]),W(d,\"mixColors\",[me(e.palette.b,t),me(e.palette.c,t),l]),W(d,\"mixColors\",[me(e.palette.c,t),me(e.palette.a,t),l]),c])}}function IR(e){if(e.points.length!==5)throw new Error(\"pointCloudGradient expects exactly 5 points\");return t=>{let{uv:s,viewport:r}=a2(t),o=z(W(Dte,\"mpgFactors\",[s,r,...e.points.map(c=>me(c.position,t)),ad(e.smoothness,t)]),\"mpgFactors\"),a=No[uh(e.space,t)??0]??Ar,i=me(e.points[0].color,t),l=[\"x\",\"y\",\"z\",\"w\"];for(let c=1;c<5;c++)i=W(a,\"mixColors\",[i,me(e.points[c].color,t),o.member(l[c-1])]);return i}}var YR={convA:{schema:A,initial:[0,0,0]},convB:{schema:A,initial:[0,0,0]}};function WR(e){return t=>{let{uv:s,viewport:r}=a2(t),o=uh(e.space,t)??0,a=z(W(Lte,\"beamField\",[s,r,me(e.from,t),me(e.to,t),ad(e.thickness.start,t),ad(e.thickness.end,t),ad(e.softness.start,t),ad(e.softness.end,t)]),\"beamField\"),i=a.member(\"x\"),l=a.member(\"y\"),c=me(e.colors.inside,t),d=me(e.colors.outside,t),u;if(o!==0){let _=\"\";t.onBeforeRender(()=>{let f=t.getCpuValue(e.colors.inside.name),h=t.getCpuValue(e.colors.outside.name);if(!f||!h)return;let g=`${f.x},${f.y},${f.z}|${h.x},${h.y},${h.z}`;if(g===_)return;_=g;let y=fl(f.x,f.y,f.z,o),b=fl(h.x,h.y,h.z,o);t.setExtraField(\"convA\",[y[0],y[1],y[2]]),t.setExtraField(\"convB\",[b[0],b[1],b[2]])}),u=W(Bd[o]??hc,\"mixPreconvertedColors\",[t.uniforms.convA,t.uniforms.convB,c.member(\"a\"),d.member(\"a\"),i]).member(\"rgb\")}else u=W(Ar,\"mixColors\",[c,d,i]).member(\"rgb\");let p=c.member(\"a\").add(d.member(\"a\")).mul(.5);return Ct(u,p.mul(l))}}function Sa(e,t){return typeof e==\"function\"?e(t):me(e,t)}function oi(e){let t=new WeakMap;return s=>{let r=t.get(s);if(r)return r;let o=e(s);return t.set(s,o),o}}var ple={flippedY:{fn:()=>Mre,hint:\"latticeFrameFlipY\"},clockwise:{fn:()=>Ere,hint:\"latticeFrameCW\"},plain:{fn:()=>kre,hint:\"latticeFrame\"}};function Rn(e){let t=ple[e.convention];return oi(s=>{let{uv:r,viewport:o}=Ro(s);return W(t.fn(),t.hint,[r,o,me(e.cells,s),me(e.rotation,s)])})}function Sc(e,t){return s=>{let r=Sa(e,s);return Ct(r.member(\"rgb\").mul(Sa(t,s)),r.member(\"a\"))}}function Zr(e){return oi(t=>W(ug(e.space,t),\"mixColors\",[Sa(e.fill,t),Sa(e.stroke,t),Sa(e.mask,t)]))}function _g(e){return({uniforms:t,ctx:s})=>{let r={uniforms:t},o=e.rotation?W(Ure,\"gridCellCenterUV\",[s.uv,s.viewportSize,me(e.cells,r),me(e.rotation,r)]):W(yJ,\"cellCentreUV\",[s.uv,s.viewportSize,me(e.cells,r)]),a={};for(let i of e.props)a[i]=o;return a}}function qR(e,t){let s=z(Xr(ne(Ce(e,t.cellSize),.5)),\"scatterBase\");return[[0,0],[1,0],[0,1],[1,1]].map(([r,o])=>mle(z(I(s,rt(r,o)),\"scatterCell\"),e,t))}function mle(e,t,s){let r=z(W(nJ,\"hash32\",[I(e,rt(v(s.seed,97.13),v(s.seed,31.71)))]),\"scatterRandom\"),o=v(ne(r.member(\"xy\"),.5),s.jitter),a=z(v(I(I(e,.5),o),s.cellSize),\"scatterPoint\");return{point:a,offset:z(ne(t,a),\"scatterOffset\"),random:r}}function fp(e,t){return s=>Ct(Sa(e,s).member(\"rgb\"),Sa(t,s))}function I_(e){return t=>Sa(e,t).member(\"a\")}function n2(e){return t=>Sa(e,t).member(\"rgb\")}function Y_(e,t){return s=>Sa(e,s).mul(Sa(t,s))}function fg(e,t,s){return r=>ea(Sa(e,r),Sa(t,r),Sa(s,r))}function VR(e){return t=>Ct(Sa(e,t),1)}function NR(e){return t=>{let{uv:s,viewport:r}=Ro(t);return W(Bre,\"checkerBlend\",[s,r,me(e.cells,t),me(e.softness,t)])}}function $R(e){return t=>{let{uv:s,viewport:r}=Ro(t);return W(zre,\"stripesMask\",[s,r,me(e.angle,t),me(e.density,t),wt(t),me(e.offset,t),me(e.balance,t),me(e.softness,t)])}}function XR(e){return oi(t=>{let{uv:s,viewport:r}=Ro(t);return W(Rre,\"chevronMask\",[s,r,me(e.count,t),me(e.angle,t),me(e.balance,t),me(e.softness,t),me(e.offset,t),wt(t)])})}function HR(e){return t=>{let{uv:s,viewport:r}=Ro(t);return W(Dre,\"ripplesMask\",[me(e.center,t),me(e.frequency,t),me(e.softness,t),me(e.thickness,t),me(e.phase,t),wt(t),s,r])}}function jR(e){let t=oi(s=>{let{uv:r,viewport:o}=Ro(s);return z(W(Lre,\"fallingLinesField\",[r,o,me(e.angle,s),me(e.density,s),me(e.speedVariance,s),me(e.trailLength,s),me(e.strokeWidth,s),me(e.rounding,s),me(e.balance,s),wt(s)]),\"fallingField\")});return{mask:s=>t(s).member(\"x\"),fade:s=>t(s).member(\"y\")}}function KR(e){return t=>{let{uv:s,viewport:r}=Ro(t);return W(Gre,\"dotGridAlpha\",[s,r,me(e.density,t),me(e.dotSize,t),me(e.offset,t),me(e.speedVariance,t),me(e.twinkle,t),wt(t),t.ctx.time])}}function QR(e){let t=oi(s=>z(W(Ore,\"gridField\",[e.frame(s),me(e.thickness,s),me(e.softness,s),me(e.variation,s)]),\"gridField\"));return{lines:s=>t(s).member(\"x\"),shade:s=>t(s).member(\"y\")}}function ZR(e){let t=oi(s=>z(W(Fre,\"hexGridField\",[e.frame(s),me(e.thickness,s),me(e.softness,s),me(e.variation,s)]),\"hexField\"));return{lines:s=>t(s).member(\"x\"),shade:s=>t(s).member(\"y\")}}function JR(e){let t=oi(s=>z(W(Ire,\"triangularGridField\",[e.frame(s),me(e.thickness,s),me(e.softness,s),me(e.variation,s),me(e.speedVariance,s),wt(s)]),\"triField\"));return{lines:s=>t(s).member(\"x\"),shade:s=>t(s).member(\"y\")}}function eD(e){let t=oi(s=>{let{uv:r,viewport:o}=Ro(s);return z(W(Yre,\"brickField\",[r,o,me(e.cellsX,s),me(e.cellsY,s),me(e.mortar,s),me(e.softness,s),me(e.variation,s),me(e.rotation,s),me(e.offset,s),me(e.speedVariance,s),me(e.seed,s),wt(s)]),\"brickField\")});return{bricks:s=>t(s).member(\"x\"),shade:s=>t(s).member(\"y\")}}function tD(e){return t=>W(Wre,\"truchetField\",[e.frame(t),me(e.thickness,t),me(e.softness,t),me(e.seed,t)])}function sD(e){return t=>W(qre,\"weaveColor\",[e.frame(t),me(e.gap,t),me(e.colors[0],t),me(e.colors[1],t)])}function rD(e){let t=oi(s=>z(W(Vre,\"isoCubeField\",[e.frame(s),me(e.thickness,s),me(e.softness,s)]),\"isoCubeField\"));return{random:s=>t(s).member(\"x\"),tone:s=>t(s).member(\"y\"),wire:s=>t(s).member(\"z\")}}function _le(e,t,s,r,o){return W(Kre,\"halftonePlateGrid\",[e,t,s,r,o])}function fle(e,t){return W(Qre,\"halftoneTransmission\",[e,t])}function oD(e){return Rd({resultAlpha:\"straight\",build:({sampleStraight:t,ctx:s,uniforms:r})=>W(Nre,\"halftoneClassic\",[t(s.uv),s.uv,s.aspect,me(e.angle,{uniforms:r}),me(e.frequency,{uniforms:r})])})}var vle={cyan:{fn:()=>Xre,hint:\"halftoneChannelC\"},magenta:{fn:()=>Hre,hint:\"halftoneChannelM\"},yellow:{fn:()=>jre,hint:\"halftoneChannelY\"},black:{fn:()=>bd,hint:\"halftoneChannelK\"}};function aD(e){return Rd({resultAlpha:\"straight\",build:({sampleStraight:t,ctx:s,uniforms:r})=>{let o=i=>me(i,{uniforms:r}),a=o(e.paper).member(\"rgb\");return e.plates.forEach((i,l)=>{let c=t(W($re,\"halftonePlateUV\",[s.uv,o(e.misprintAngle),$e(l*90),o(e.misprint),s.aspect])),d=vle[i.channel],u=W(d.fn(),d.hint,[c]);a=a.mul(fle(o(i.ink),_le(s.uv,s.aspect,o(i.screenAngle),u,o(e.frequency))))}),Ct(a,t(s.uv).member(\"a\"))}})}function nD(e,t,s){let r=Object.values(s),o=r[0]?.resultAlpha;for(let a of r)if(a.resultAlpha!==o||a.setup)throw new Error(\"std: chosenBy recipes must share resultAlpha and carry no setup hooks\");return Rd({resultAlpha:o,build:a=>s[t(a.propValues[e.name])].build(a)})}var hle=e=>typeof e==\"number\"?e:{bayer2:0,bayer4:1,bayer8:2,clusteredDot:3,blueNoise:4,whiteNoise:5,floydSteinberg:6}[e]??1,gle=e=>typeof e==\"number\"?e:e===\"source\"?1:0;function iD(e){let t=oi(r=>z(W(Zre,\"ditherCoord\",[r.ctx.uv,r.ctx.logicalViewportSize,me(e.size,r)]),\"ditherCoord\")),s=oi(r=>z(r.sampleStraight(W(Jre,\"ditherPixUV\",[t(r),me(e.size,r),r.ctx.logicalViewportSize])),\"ditherSource\"));return{size:e.size,coord:t,source:s}}function yle(e,t){if(e===4)return W(toe,\"ditherBlueNoise\",[t]);if(e===5||e>6||e<0)return W(soe,\"ditherWhiteNoise\",[t]);let s=W(eoe,\"ditherPeriodic\",[t]);switch(e){case 0:return s.member(\"x\");case 1:return s.member(\"y\");case 2:return s.member(\"z\");default:return s.member(\"w\")}}function lD(e){return t=>{let s=c=>me(c,t),r=s(e.threshold),o=s(e.spread),a=e.grid.coord(t),i=hle(t.propValues[e.pattern.name]);if(i===6){let c=t.ctx.logicalViewportSize,d=s(e.grid.size),u=W(ooe,\"ditherBlockOrigin\",[a]),p=W(aoe,\"ditherLocalCellIndex\",[a,u]),_=[];for(let f=0;f<8;f++)for(let h=0;h<8;h++){let g=W(noe,\"ditherCellUV\",[u,$e(h),$e(f),d,c]);_.push(W(NS,\"ditherLuma\",[t.sampleStraight(g)]))}return W(ioe,\"ditherFloydSteinberg\",[see(\"f32\",_),p,r,o])}let l=W(NS,\"ditherLuma\",[e.grid.source(t)]);return W(roe,\"ditherOrderedResult\",[yle(i,a),l,r,o])}}function cD(e){return Rd({resultAlpha:\"straight\",build:t=>{let s=o=>me(o,t),r=e.levels(t);return gle(t.propValues[e.mode.name])===0?W(loe,\"ditherComposeCustom\",[s(e.colors[0]),s(e.colors[1]),r]):W(coe,\"ditherComposeSource\",[e.grid.source(t),r])}})}function dD(e){let t=I(v(e.along,e.frequency),v(e.time,e.speed));return e.phase!==void 0&&(t=I(t,e.phase)),ts(I(v(Vt(t),.5),.5),e.sharpness)}function W_(e){let t=s=>typeof s==\"number\"?$e(s):s;return W(BJ,\"glowAt\",[e.uv,t(e.aspect),t(e.x),t(e.y),t(e.sizeSq)])}function uD(e){let t=e.bulge?.tilt??.2,s=e.bulge?.drop??.1,r=ns(ot(0,e.radius,e.dist),\"domeSlope\"),o=I(r,t);return Os(Qe(v(e.delta.member(\"x\"),o),v(e.delta.member(\"y\"),o),ne(1,v(r,s))))}function pD(e){return ts(it(0,Lo(v(e.light,-1),e.normal).member(\"z\")),e.gloss)}function hr(e,t){return typeof e==\"number\"?$e(e):e instanceof zi||e.kind!==\"ctx\"?fn(e,t):t.ctx[e.name]}function Dd(e){return{uv:e.uvContext??e.ctx.uv,viewport:e.effectiveViewportSize??e.ctx.viewportSize}}function mD(e){return t=>{let{uv:s,viewport:r}=Dd(t);return W(LJ,\"radialFrame\",[s,r,me(e,t)])}}function _D(e){return t=>{let{uv:s,viewport:r}=Dd(t);return W(Wte,\"godraysFrame\",[s,r,me(e,t)])}}function fD(e){return t=>W(GJ,\"beamFrame\",[t.ctx.uv,t.ctx.aspect,me(e,t)])}function vg(e,t,s){return r=>t(s?ns(e(r),s):e(r),r)}function vD(e,...t){return(s,r)=>t.reduce((o,a)=>o.mul(a(s,r)),e(s,r))}function hD(e){return(t,s)=>W(DJ,\"softRayLobes\",[t.member(\"y\"),hr(e.count,s),wt(s).mul(e.spin),hr(e.softness,s)])}function gD(e){return(t,s)=>W(RJ,\"featherMask\",[t.member(\"x\"),hr(e.radius,s),hr(e.feather,s)])}function yD(e){return(t,s)=>W(qte,\"godraysRayStack\",[t,wt(s),hr(e.density,s),hr(e.intensity,s),hr(e.spotty,s)])}function bD(e){return(t,s)=>W(Nte,\"leakDrift\",[t,hr(e.seed,s),hr(e.flicker,s)])}function xD(e){return(t,s,r)=>W($te,\"leakBloom\",[t.member(\"x\"),t.member(\"y\"),hr(e.spread,r),s])}function AD(e){return(t,s,r)=>W(Xte,\"leakStreaks\",[t.member(\"x\"),t.member(\"y\"),hr(e.spread,r),hr(e.strength,r),s])}function wD(e,t,s){return W(Hte,\"heatDither\",[e,t,s])}function q_(e,t,s){return W(D1,\"glowSpot\",[e,t,s])}function TD(e,t){let s=z(ms(e.member(\"x\")),\"glintX\"),r=z(ms(e.member(\"y\")),\"glintY\"),o=typeof t.core==\"number\"?$e(t.core):t.core,a=q_(e.member(\"x\"),e.member(\"y\"),o),i=(c,d)=>tr(er(I(v(c,t.rayWidth),v(d,t.rayLength)))),l=I(a,v(I(i(s,r),i(r,s)),t.rays));return t.reach===void 0?l:v(l,ne(1,ot(v(t.reach,.6),t.reach,it(s,r))))}function SD(e){return t=>{let{uv:s,viewport:r}=Dd(t);return W(Eoe,\"flareFrame\",[s,r,wt(t),me(e.position,t),hr(e.intensity,t),hr(e.edgeFade,t)])}}function PD(e){return(t,s,r,o)=>{let{uv:a}=Dd(o);return W(koe,\"lensFlareGhost\",[a,t.member(\"aspect\"),t.member(\"lightPos\"),t.member(\"flareAxis\"),wt(o),hr(e.spread,o),hr(e.chroma,o),hr(e.intensity,o),Ct(...s),Ct(...r)])}}function CD(e){return(t,s)=>{let{uv:r}=Dd(s);return W(Boe,\"flareHalo\",[r,t.member(\"aspect\"),t.member(\"lightPos\"),wt(s),hr(e.intensity,s),hr(e.radius,s),hr(e.chroma,s),hr(e.softness,s)])}}function MD(e){return(t,s)=>W(zoe,\"flareStarburst\",[t.member(\"lightAngle\"),t.member(\"flareAxis\"),t.member(\"aspect\"),wt(s),t.member(\"lightDist\"),hr(e.points,s),hr(e.intensity,s)])}function ED(e){return(t,s)=>{let{uv:r}=Dd(s);return W(Roe,\"flareStreak\",[r,t.member(\"lightPos\"),hr(e.length,s),hr(e.intensity,s)])}}function kD(e){return(t,s)=>W(Doe,\"flareGlare\",[t.member(\"lightDist\"),hr(e.size,s),hr(e.intensity,s)])}function BD(e){return(t,s)=>W(Loe,\"flareCore\",[t.member(\"lightDist\"),hr(e.intensity,s)])}function zD(e,t){return W(Uoe,\"flareComposite\",[e,t.member(\"masterFade\")])}function RD(e){return t=>{let{uv:s,viewport:r}=Dd(t),o=hr(e.strength,t);return e.scale!==void 0&&(o=o.mul(e.scale)),W(UJ,\"vignetteMask\",[s,r,o])}}function i2(e,...t){return t.reduce((s,r)=>s.add(r),e)}function DD(e){return{kind:\"heatRamp\",taps:(t,s)=>W(zJ,\"chromaticHeatTaps\",[t,me(e.hot,s).member(\"rgb\"),me(e.mid,s).member(\"rgb\"),me(e.fringe,s).member(\"rgb\")])}}function LD(e){return t=>{let s=e.hint?ns(e.coverage(t),e.hint):e.coverage(t),r=me(e.color,t),o=me(e.background,t);return Ct(ea(o.member(\"rgb\"),r.member(\"rgb\"),s),ea(o.member(\"a\"),r.member(\"a\"),s))}}function UD(e){return t=>W(Vte,\"coverageOver\",[me(e.color,t),me(e.background,t),e.coverage(t)])}function OD(e){return{kind:\"pointwise\",body:{fn:OJ,hint:\"screenGlowComposite\"},args:t=>[e(t)]}}var ble=6.283185307179586;function vp(e,t){let s=(a,i,l)=>{if(i!==void 0){if(a===void 0)throw new Error(`std: waves() schedule uses axis '${l}' but the axes object doesn't provide it`);return i===1?a:v(a,i)}},r=a=>{let i=[s(e.x,a.x,\"x\"),s(e.y,a.y,\"y\"),s(e.t,a.t,\"t\"),a.phase].filter(l=>l!==void 0);if(i.length===0)throw new Error(\"std: a wave needs at least one axis coefficient or phase\");return Vt(i.reduce((l,c)=>I(l,c)))},o=t.map(a=>{if(a.waves.length===0)throw new Error(\"std: a waves() term needs at least one wave\");let i=a.waves.map(r).reduce((l,c)=>v(l,c));return a.weight===void 0||a.weight===1?i:v(i,a.weight)});if(o.length===0)throw new Error(\"std: waves() needs at least one term\");return o.reduce((a,i)=>I(a,i))}function l2(e){return vp({x:e.along,t:e.time},e.waves.map(t=>({waves:[{x:t.freq,t:t.speed,phase:t.phase}],weight:t.amount})))}function GD(e){let t=Math.max(1,Math.round(e.count)),s=e.jitter??.6,r=Ce(e.spread,t),o=(a,i)=>Qr(v(Vt(v(I(e.seed,.37+a*31.7),i)),43758.5453));return Array.from({length:t},(a,i)=>{let l=(i+.5)/t-.5;return{offset:z(I(v(e.spread,l),v(v(ne(o(i,12.9898),.5),s),r)),`fold${i}Off`),width:z(v(e.width,et(.6,1.5,o(i,78.233))),`fold${i}W`),height:z(v(e.height,et(.35,1,o(i,39.425))),`fold${i}H`),phase:z(v(o(i,94.673),ble),`fold${i}Ph`)}})}function FD(e,t,s){return YD(e,t,s).map(r=>v(r.rise,r.profile)).reduce((r,o)=>I(r,o))}function ID(e,t,s){let r=s.foreshorten??.25,o=YD(e,t,s),a=o.map(l=>v(l.profile,ne(l.spine,l.fold.offset))).reduce((l,c)=>I(l,c)),i=o.map(l=>v(v(l.fold.height,r),v(Bx(l.d),ne(1,l.profile)))).reduce((l,c)=>I(l,c));return{along:typeof e.along==\"number\"?$e(e.along):e.along,across:z(I(ne(e.across,a),i),\"clothAcross\")}}function YD(e,t,s){let r=s.pinning??0,o=s.sharpness??2,a=s.crease??0,i=s.swell??{amount:.25,freq:2.7},l=i.speed??.4,c=z(Ge(e.along,0,1),\"hang\"),d=z(et(1,c,r),\"free\"),u=z(et(1,et(.7,1.2,c),r),\"open\");return t.map(p=>{let _=l2({along:e.along,time:s.time,waves:s.ripple.waves.map((x,P)=>({...x,phase:v(p.phase,P+1)}))}),f=s.ripple.gain===void 0?_:v(_,s.ripple.gain),h=I(p.offset,v(f,d));if(s.sway){let x=Vt(I(v(s.time,s.sway.rate??.7),p.phase));h=I(h,v(v(x,s.sway.amount),d))}let g=z(h,\"spine\"),y=z(Ce(ne(e.across,g),v(p.width,u)),\"foldD\"),b=i.amount>0?v(p.height,I(1-i.amount,v(Vt(I(I(v(e.along,i.freq),p.phase),v(s.time,l))),i.amount))):p.height;return{fold:p,spine:g,d:y,profile:z(xle(y,o,a),\"profile\"),rise:b}})}function xle(e,t,s){if(s<=0)return O_(e,t);let r=z(v(e,e),\"foldD2\");return tr(er(v(et(r,v(r,r),s),t)))}function Qa(e,t){return(s,r)=>{let{viewport:o}=Ro(s);return e(s,W(bJ,\"aspectScaledDomain\",[r,o,me(t.scale,s),me(t.seed,s)]))}}function WD(e,t){return(s,r)=>{let{viewport:o}=Ro(s);return e(s,W(uoe,\"rawAspectScaledDomain\",[r,o,me(t.scale,s),me(t.seed,s)]))}}function qD(e,t){return(s,r)=>{let{viewport:o}=Ro(s);return e(s,W(xJ,\"pixelGridDomain\",[r,o,me(t.grain,s),me(t.seed,s)]))}}function hp(e,t){return(s,r)=>e(s,W(AJ,\"timeAxisDomain\",[r,wt(s),$e(t.rate)]))}function VD(e){return(t,s)=>W(lJ,\"gabor12\",[s,me(e.frequency,t),wt(t)])}function ND(e){return(t,s)=>W(cJ,\"wavelet12\",[s,wt(t),me(e.detail,t)])}function $D(){return(e,t)=>W(dJ,\"blue12\",[t])}function XD(){return(e,t)=>W(_J,\"erosion12\",[t]).member(\"x\")}function HD(e){return(t,s)=>W(moe,\"curlMagnitude\",[s,wt(t).mul(e.rate)])}function jD(e){return(t,s)=>W(uJ,\"scratches12\",[s,wt(t),me(e.thickness,t)])}function gp(e){return(t,s)=>W(fJ,\"signedToUnit\",[e(t,s)])}function ua(e,t){return(s,r)=>W(Uae,\"noiseToneKColor\",[e(s,r),t?.contrast?me(t.contrast,s):$e(0),t?.balance?me(t.balance,s):$e(0)])}function KD(e,t){return(s,r)=>W(Rk,\"noiseToneSigned\",[e(s,r),me(t.contrast,s),me(t.balance,s)])}function Ale(e,t){return(s,r)=>W(goe,\"worleyTone\",[e(s,r),me(t.contrast,s),me(t.balance,s)])}function QD(e,t){return(s,r)=>W(Ar,\"mixColors\",[me(e,r),me(t,r),s])}function ZD(e){return Vs((s,r)=>{let{viewport:o}=Ro(s);return W(foe,\"fbmNormalize\",[W(_oe,\"fractalSum\",[W(poe,\"rotatedCenteredDomain\",[r,o,me(e.angle,s)]),me(e.detail,s),me(e.contrast,s),wt(s),me(e.seed,s),me(e.octaves,s)])])},Us(e.space))}function JD(e){return Vs(Ale((s,r)=>{let{viewport:o}=Ro(s),a=yoe(s.propValues[e.mode.name]),i=boe(s.propValues[e.distance.name]),l=Math.max(1,Math.min(4,Math.round(s.propValues[e.octaves.name]??1)));return W(hoe,\"worleyNormalize\",[W(voe,\"worleyCells\",[W(V4,\"aspectPlane\",[r,o]),me(e.scale,s),me(e.seed,s),me(e.jitter,s),me(e.lacunarity,s),me(e.persistence,s),wt(s),$e(l),$e(i),$e(a)]),$e(xoe(a,i))])},{contrast:e.contrast,balance:e.balance}),Us(e.space))}function eL(e){return(t,s)=>{let{viewport:r}=Ro(t);return W(Aoe,\"voronoiNearest2\",[W(V4,\"aspectPlane\",[s,r]).mul(me(e.scale,t)),wt(t),me(e.seed,t)])}}function tL(e,t){return(s,r)=>W(woe,\"cellFill\",[e(s,r),me(t.edgeIntensity,s)])}function sL(e,t){return(s,r)=>W(Toe,\"cellBorders\",[e(s,r),me(t.softness,s),me(t.scale,s)])}function rL(e,t,s){return r=>{let{uv:o}=Ro(r),a=ns(e(r),\"base\");return Ct(ea(me(s.color,r).member(\"rgb\"),a.member(\"rgb\"),t(r,o)),a.member(\"a\"))}}function oL(e,...t){return s=>{let r=e(s),o=r.member(\"rgb\");for(let a of t)o=a(o,s);return Ct(o,r.member(\"a\"))}}function aL(e){return(t,s)=>q4(t,e.space?G_(s.propValues[e.space.name]):0)}function nL(){return e=>W(Soe,\"toneLift\",[e])}function iL(e){return t=>{let{uniforms:s}=t,{uv:r,viewport:o}=Ro(t),a=wt(t),i=wt(t,void 0,\"_animTime_color\"),l=Ct(me(e.amplitude,t),me(e.frequency,t),me(e.count,t),me(e.width,t)),c=Ct(me(e.softness,t),me(e.spread,t),me(e.colorScale,t),me(e.colorVariance,t)),d=Ct(me(e.pinEdges,t),a,i,s.stopCount);return W(Poe,\"ribbonsField\",[r,o,me(e.from,t),me(e.to,t),l,c,d,s.colorsArray,s.positionsArray,s.convertedColorsArray])}}var hg={stone:{fn:pJ,hint:\"stone12\"},wool:{fn:mJ,hint:\"wool12\"}};function gg(e){return t=>Yae(t,e.fn,e.hint)}var lL=N4,cL=$4;var{sdfSpaceUV:dL,offsetUV:x1}=ip,{ANALYTIC_SDF_EXTRA_FIELDS:wle}=yc,{createVolumetricFieldComputeNode:Tle,resolveShapeFieldSampler:Sle,VOLUMETRIC_FIELD_EXTRA_FIELDS:Ple}=kn,Cle=0;function Js(e,t,s,r=\"guarded\",o=[]){let a=Cle++;return new fs(i=>i.memo(`guard:${a}`,()=>{let l=i.freshLocal(r),c=e._emit(i),d=s._emit(i);for(let _ of o)_._emit(i);let u=[],p=t._emit({external:(_,f)=>i.external(_,f),statement:_=>u.push(_),freshLocal:_=>i.freshLocal(_),memo:(_,f)=>i.memo(_,f)});return i.statement(`var ${l} = ${d};`),i.statement(`if (${c}) {\n  ${u.join(`\n  `)}\n  ${l} = ${p};\n}`),l}))}function Dr(e,t){let s=W(K4,\"outsideShape\",[e,t]);return new fs(r=>`(!(${s._emit(r)}))`)}function Ts(e){let t=e.pattern??\"none\",s=e.chord??\"span\",r=e.stencil??{kind:\"forward\",eps:.01},o=i=>Tle(i,()=>i.getCpuValue(\"shape\"),t,s),a=i=>{let{childNode:l,computeOutputs:c,convertToTexture:d,uniforms:u,ctx:p}=i,_;if(e.child===\"required\"){if(!l)return xt;_=c?.childTexture??d(l)}let{sampler:f,gradSampler:h,texelSampler:g,volumetric:y,bakedGradients:b}=Sle(i,{patternMode:t,gradSampler:e.gradSampler??\"fast\",bakedGradients:e.bakedGradients??\"none\"}),x={sampler:f,gradSampler:h,texelSampler:g,volumetric:y,bakedGradients:b,volFlag:$e(y?1:0),childTexture:_};if(r!==\"none\"){let P=e.placeUV?e.placeUV(i):p.uv;if(x.sdfUV=z(W(dL,\"sdfSpaceUV\",[u.center,u.scale,u.rotation,P,p.aspect]),\"sdfUV\"),x.surf0=(e.centreTap===\"fast\"?h:f)(x.sdfUV),r!==\"centre\"){let{kind:C,eps:E}=r;x.surfX=h(W(x1,\"offsetUV\",[x.sdfUV,$e(E),$e(0)])),C===\"central\"&&(x.surfL=h(W(x1,\"offsetUV\",[x.sdfUV,$e(-E),$e(0)]))),x.surfY=h(W(x1,\"offsetUV\",[x.sdfUV,$e(0),$e(E)])),C===\"central\"&&(x.surfD=h(W(x1,\"offsetUV\",[x.sdfUV,$e(0),$e(-E)])))}}return e.surface(x,i)};return{extraFields:{...Ple,...wle},compute:o,gpu:{fragment:a}}}function Lr(e,t,s={}){let{ctx:r}=t,o=z(e.surf0,\"s0\"),a=z(Ce(1,r.viewportSize.member(\"y\")),\"pxH\"),i=z(s.scale?Ce(o.member(\"x\"),s.scale):o.member(\"x\"),\"sdf\"),l=Ce(r.viewportSize.member(\"x\"),r.viewportSize.member(\"y\"));return{s0:o,sX:e.surfX?z(e.surfX,\"sX\"):void 0,sY:e.surfY?z(e.surfY,\"sY\"):void 0,sdf:i,pxH:a,aspect:l}}function Dn(e,t,s){let r=It(s.eps??.01),o=s.hint??\"nGeo\";if(e.volumetric)return z(W(sA,\"volumetricNormal\",[t.s0,t.sX,t.sY,r,It(s.sharpness??5)]),o);let a=Ge(Ce(er(t.sdf),it(s.bevelWidth,.003)),0,1);return z(W(H4,\"bevelledFlatNormal\",[W(tA,\"fieldGradient\",[t.s0,t.sX,t.sY,r]),W(sz,\"bevelSin\",[a,s.bevelShape])]),o)}function go(e,t,s={}){return z(W(j4,\"patternCoords\",[s.uv??e.sdfUV,t.s0,e.volFlag]),\"pat\")}function Ln(e,t=.01){return z(W(tA,\"fieldGradient\",[e.s0,e.sX,e.sY,It(t)]),\"grad\")}function Ea(e,t,s=.6){return z(W(Q4,\"perspectiveViewRay\",[e.ctx.uv,t.aspect,It(s)]),\"viewI\")}function ni(e,t){return z(ne(1,Ge(er($t(e,t)),0,1)),\"grazing\")}function yg(e,t,s,r=\"n\"){let o=i=>{let l=[];return s.across&&l.push(v(t.perp.member(i),s.across)),s.along&&l.push(v(t.tangent.member(i),s.along)),l},a=(i,l)=>l.reduce((c,d)=>I(c,d),i);return z(Os(Qe(a(e.member(\"x\"),o(\"x\")),a(e.member(\"y\"),o(\"y\")),e.member(\"z\"))),r)}function Pc(e,t,s){let r=o=>typeof o==\"number\"?It(o):o;return W(tae,\"studio5Softbox\",[e,t,s.rotation.member(\"x\"),s.rotation.member(\"y\"),r(s.keyRadius),r(s.drift),r(s.strength),It(s.skyGain)])}function Cc(e,t){let s=v(e.along,t.freq[0]),r=v(e.across,t.freq[1]);return t.offset?.[0]&&(s=I(s,t.offset[0])),t.offset?.[1]&&(r=I(r,t.offset[1])),t.drift&&(s=I(s,t.drift)),W(la,\"mxNoiseFloat2\",[rt(s,r)])}function uL(e,t){let s=e.taps??9,r=e.sigma??2.1,o=(s-1)/2,a=Array.from({length:s},(u,p)=>Math.exp(-((p-o)**2)/(2*r*r))),i=a.reduce((u,p)=>u+p,0),l=a.map(u=>u/i),c=z(Ce(e.spread,o),\"step\"),d=It(0);for(let u=0;u<s;u++){let p=z(v(c,It(u-o)),\"off\");d=I(d,v(t(I(e.center.member(\"x\"),v(e.axis.member(\"x\"),p)),I(e.center.member(\"y\"),v(e.axis.member(\"y\"),p))),It(l[u])))}return z(d,e.hint??\"smear\")}function Ld(e,t,s=\"L\"){return z(Os(Qe(e.member(\"x\"),e.member(\"y\"),It(t))),s)}function V_(e,t){let s=z(et(.05,.45,e),\"baseA\");return{along:v(s,I(1,v(t,7))),across:it(v(s,ne(1,v(t,.55))),.02)}}function Ud(e){let t=W(Z4,\"wardAnisotropicSpecular\",[W(rA,\"WardSpecularInput\",[e.normal,Qe(e.tangent.member(\"x\"),e.tangent.member(\"y\"),0),e.light,e.view,e.alphas.along,e.alphas.across])]);return e.gain===void 0?t:v(t,e.gain)}function pL(e,t,s,r=\"n\"){return z(Os(Qe(I(e.member(\"x\"),v(t.member(\"x\"),s)),I(e.member(\"y\"),v(t.member(\"y\"),s)),e.member(\"z\"))),r)}function mL(e,t){return I(1,v(ts(e,It(t.power??3)),t.amount))}function _L(e,t,s){return et(t.member(\"rgb\"),s.member(\"rgb\"),kt(e))}function Jr(e,t){return W($oe,\"silhouetteAlpha\",[e.sdf,t,e.pxH])}function yp(e){return W(g4,\"tonemapNeutral\",[e])}function Gi(e,t,s,r=\"n\"){return z(W(Qoe,\"nudgeNormal\",[e,t,s]),r)}function Mc(e,t=5,s=\"nGeo\"){return z(W(sA,\"volumetricNormal\",[e.s0,e.sX,e.sY,It(.01),It(t)]),s)}function Un(e,t,s=\"kl\"){return bg(e.member(\"x\"),e.member(\"y\"),t,s)}function bg(e,t,s,r=\"kl\"){return z(W(Xoe,\"keyLight\",[e,t,It(s)]),r)}function Fi(e){return z(W(Hoe,\"grazingView\",[e]),\"grazing\")}function xg(e,t,s){return W(joe,\"sharpGlint\",[e,t,s])}function Ag(e,t){return W(Koe,\"clampedPerlinGrad\",[e,typeof t==\"number\"?It(t):t])}function Hu(e,t){return W(Zoe,\"opticalThickness\",[e.sdf,t.volFlag])}function wg(e,t){return W(Joe,\"beerLambert\",[e,t])}function Tg(e,t){return W(eae,\"flowWarpOffset\",[e,t])}function co(e,t){return W(la,\"mxNoiseFloat2\",[rt(e,t)])}function pa(e){return W(la,\"mxNoiseFloat2\",[e])}function Jn(e){return W(Na,\"mxNoiseFloat3\",[e])}function fL(e,t){return W(A_,\"cosinePalette\",[e,It(t[0]),It(t[1]),It(t[2])])}function N_(e){return W(I3,\"mxWorleyNoiseFloat2Pub\",[e,It(1)])}function bp(e,t,s,r=\"fd\"){let o=z(e(t),`${r}0`);return{value:o,dx:z(Ce(ne(e(I(t,rt(s,0))),o),s),`${r}X`),dy:z(Ce(ne(e(I(t,rt(0,s))),o),s),`${r}Y`)}}function vL(e,t,s,r=\"fd\"){let o=z(e(t),`${r}0`),a=z(e(I(t,rt(s,0))),`${r}Px`),i=z(e(ne(t,rt(s,0))),`${r}Mx`),l=z(e(I(t,rt(0,s))),`${r}Py`),c=z(e(ne(t,rt(0,s))),`${r}My`);return{value:o,dx:z(Ce(ne(a,i),2*s),`${r}X`),dy:z(Ce(ne(l,c),2*s),`${r}Y`),curvature:z(Ce(ne(I(I(a,i),I(l,c)),v(o,4)),s*s),`${r}Curv`)}}function xp(e,t){return W(Ys,\"hash12\",[rt(e,t)])}function hL(e,t){return W(Aa,\"value12\",[rt(e,t)])}function gL(e){let t=z(e.gradSampler(rt(.5,.5)),\"s0C\");return{x:z(v(er(t.member(\"y\")),e.volFlag),\"rotSenseX\"),y:z(v(er(t.member(\"z\")),e.volFlag),\"rotSenseY\")}}function yL(e,t,s){let r=z(ne(e.sdfUV.member(\"x\"),.5),\"cx\"),o=z(ne(e.sdfUV.member(\"y\"),.5),\"cy\");return{x:z(I(r,v(t.member(\"x\"),s)),\"bentX\"),y:z(I(o,v(t.member(\"y\"),s)),\"bentY\"),centered:{x:r,y:o}}}function Ap(e,t){return I(t.r0??.04,v(ts(e,It(t.power??5)),t.gain))}function c2(e,t,s){return I(ne(1,s.amount),v(Vt(I(v(e,s.rate),v(t,s.spread))),s.amount))}function d2(e,t){let s=t.hint??\"stars\",r=z(I(v(pa(v(e,t.variationFreq)),.5),.5),`${s}V`),o=t.shimmer?t.shimmer(r):It(1),a=z(v(v(v(ot(I(t.radius[0],v(r,t.radius[1])),5e-4,N_(e)),ot(t.keep[0],t.keep[1],r)),v(I(t.brightness[0],v(v(r,r),t.brightness[1])),o)),t.gain),s);return{glint:a,variation:r,rgb:t.tint?v(et(Qe(...t.tint.from),Qe(...t.tint.to),kt(r)),kt(v(a,t.tint.gain))):void 0}}function bL(e,t,s=\"placed\"){let{uniforms:r,ctx:o}=e,a=rt(t.member(\"x\"),ne(1,t.member(\"y\")));return z(W(dL,\"sdfSpaceUV\",[r.center,r.scale,r.rotation,a,o.aspect]),s)}function xL(e,t,s){if(!(!e.volumetric&&s.propValues.shapeSdfUrl))return{sdf:t.sdf,outward:rt(0,0),at:l=>e.gradSampler(l).member(\"x\")};let r=e.sdfUV,o=l=>ne(l,Ge(l,rt(0,0),rt(1,1))),a=z(o(r),\"outward\"),i=(l,c)=>it(l,it(c,ne(l,c)));return{sdf:z(i(t.sdf,Kr(a)),\"sdfFar\"),outward:a,at:l=>{let c=Kr(o(l));return i(e.gradSampler(l).member(\"x\"),c)}}}function AL(e,t,s,r=\"edge\"){let o=z(Ce(s,it(Kr(s),1e-4)),`${r}N`);return{point:z(ne(e,v(o,it(t,0))),`${r}P`),normal:o}}function u2(e,t,s=\"pl\"){let r=z(ne(e.position,t),`${s}D`),o=z(Kr(r),`${s}Dist`),a=z(Ce(r,it(o,1e-4)),`${s}Dir`);return{L:z(Os(Qe(r.member(\"x\"),r.member(\"y\"),er(e.height))),`${s}L`),toLight:a,distance:o}}function Pl(e,t,s={}){let r=$t(e,t);return s.wrap===void 0?it(r,0):Ge(Ce(I(r,s.wrap),I(1,s.wrap)),0,1)}function p2(e,t){let s=Ce(e,t);return Ce(1,I(1,v(s,s)))}function m2(e){return ne(1,tr(er(e)))}function wL(e,t){let s=t.softness?z(U_(et(2,-2,t.softness)),\"lobeWiden\"):void 0,r=o=>s?v(o,s):It(o);return v(I(v(ts(e,r(t.core[0])),t.core[1]),v(ts(e,r(t.halo[0])),t.halo[1])),t.gain)}function TL(e){let t=v(ts(ni(e.normal,e.view),z(et(3,1,e.roughness),\"sheenPow\")),Pl(e.normal,e.light,{wrap:.5}));return e.gain===void 0?t:v(t,e.gain)}function SL(e,t,s){let r=z(v(e.s0.member(\"w\"),t.volFlag),\"rayEntry\"),o=z(s.lengthScale===void 0?Hu(e,t):v(Hu(e,t),s.lengthScale),\"rayLen\"),a=s.view?z(v(s.view.member(\"x\"),s.shear??1),\"rayShearX\"):void 0,i=s.view?z(v(s.view.member(\"y\"),s.shear??1),\"rayShearY\"):void 0;return{entry:r,length:o,at(l){return{x:a?I(s.origin.x,v(a,l)):s.origin.x,y:i?I(s.origin.y,v(i,l)):s.origin.y}}}}function _2(e,t){let s=t.hint??\"plane\",r=z(I(e.entry,v(e.length,t.depth)),`${s}Z`),o=e.at(r);if(!t.pan)return{x:o.x,y:o.y,z:r};let a=t.panRate??1;return{x:I(o.x,v(t.pan.x,a)),y:I(o.y,v(t.pan.y,a)),z:r}}function PL(e,t){let s=t.hint??\"\",r=t.drift,o=t.seed,a=(p,_,f,h)=>{let g=_===void 0?v(p,t.frequency):v(p,v(t.frequency,_));return r&&(g=I(g,f===1?r:v(r,f))),o&&(g=I(g,h===1?o:v(o,h))),g},i=z(Qe(a(e.x,void 0,1,1),a(e.y,void 0,-.7,.53),a(e.z,1.25,1.3,.79)),`q${s}`),l=z(Jn(r?I(v(i,.5),Qe(v(r,1.4),0,v(r,-.9))):v(i,.5)),`warp${s}`),c=t.billow?z(I(i,v(Qe(l,v(l,-.73),v(l,.41)),t.billow)),`qw${s}`):i,d=z(Jn(I(v(c,2.13),Qe(5.2,1.3,8.4))),`mid${s}`),u=z(Jn(I(v(c,4.31),Qe(9.1,3.7,1.2))),`fine${s}`);return{density:z(v(I(I(Jn(c),v(d,.5)),v(u,.27)),.57),`fbm${s}`),mid:d,fine:u}}function CL(e,t){let s=kt(1),r=Qe(0,0,0);for(let o=0;o<e.steps;o++){let a=(o+.5)/e.steps,i=z(I(e.entry,v(e.length,e.jitter?I(a,e.jitter):a)),`z${o}`),{emit:l,absorb:c}=t({i:o,t:a,z:i}),d=v(l,s);r=I(r,e.emissionGain?v(d,kt(e.emissionGain)):d),s=z(v(s,tr(er(c))),`transmit${o}`)}return{color:z(r,e.hint??\"marchAcc\"),transmittance:s}}function ML(e,t){let s,r;if(e.forEach((o,a)=>{let{value:i,weight:l}=t(o,a),c=v(i,l);s=s===void 0?c:I(s,c),r=r===void 0?l:I(r,l)}),!s||!r)throw new Error(\"std: layered([]) needs at least one layer\");return{weightedSum:s,totalWeight:r}}function EL(e){let t;for(let s of e){let r=s instanceof Object&&\"paint\"in s?s:{paint:s},o=r.paint;r.opacity!==void 0&&(o=v(o,r.opacity)),r.behind&&(o=v(o,r.behind)),t=t===void 0?o:r.blend===\"screen\"?ne(I(t,o),v(t,o)):I(t,o)}if(!t)throw new Error(\"std: layers([]) needs at least one layer\");return t}function kL(e,t=\"emissive\"){let s=z(e,t),r=z(Ge(it(it(s.member(\"x\"),s.member(\"y\")),s.member(\"z\")),0,1),`${t}A`);return Ot(Ce(s,it(r,1e-4)),r)}function BL(e,t){let{uv:s,viewport:r}=Ro(t);return W(gJ,\"rgbDither\",[e,s,r,wt(t)])}function Qn(e,t){return typeof e==\"number\"?$e(e):e instanceof zi||e.kind!==\"ctx\"?fn(e,t):t.ctx[e.name]}function zL(e,t,s){let r=me(e,s);return Ct(r.member(\"rgb\"),r.member(\"a\").mul(t))}function RL(e){return t=>{let{uv:s,viewport:r}=Ro(t),o=W(Coe,\"lineMask\",[s,r,me(e.from,t),me(e.to,t),Qn(e.width,t),Qn(e.style,t),Qn(e.dashLength,t),Qn(e.gapLength,t),Qn(e.capStart,t),Qn(e.capEnd,t)]);return zL(e.color,o,t)}}function DL(e){return t=>{let{uv:s,viewport:r}=Ro(t),o=W(Moe,\"sineWaveMask\",[s,r,Qn(e.angle,t),me(e.position,t),Qn(e.frequency,t),Qn(e.amplitude,t),Qn(e.thickness,t),Qn(e.softness,t),wt(t)]);return zL(e.color,o,t)}}function f2(e,t,s,r){let{ctx:o,propValues:a,uvContext:i,effectiveViewportSize:l}=e;return Fne({texture:s,uv:i??o.uv,viewport:l??o.viewportSize,fit:a[t.fit.name],decode:t.decode,...r})}function LL(e){return{gpu:{fragment:t=>{let s=gc(t,{label:e.label});return tB(t,{prop:e.src.name,async load(r,o){let a=await aae(r);if(o.isDisposed()){a.close();return}o.commit(),oA(r,a.naturalWidth,a.naturalHeight),s.ensureSize(a.width,a.height),s.write(a.source),a.close()},onError:e.onError}),f2(t,e,s.kit)}}}}function UL(e){return{gpu:{fragment:t=>{let s=sB(t,{source:{kind:\"url\",prop:e.src.name},loop:{prop:e.loop.name},metadataTimeoutMs:e.metadataTimeoutMs,onError:e.onError});return f2(t,e,t.registerExternalTexture(s.getSource))}}}}function OL(e){return{gpu:{fragment:t=>{let s=sB(t,{source:{kind:\"webcam\",constraints:e.constraints},naturalSizeKey:e.naturalSizeKey,autoplayRequired:!0,onError:e.onError});return f2(t,e,t.registerExternalTexture(s.getSource),{allowNone:!0,uvPostProcess:r=>W(Lne,\"applyMirror\",[r,t.uniforms[e.mirror.name]])})}}}}var{sdfSpaceUV:jP}=ip,GL=\"rgba16float\",Sg=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({center:m,lightPos:Fe(S,8),lightColor:Fe(S,8),lightCount:n,scale:n,rotation:n,aspect:n,reach:n,wrap:n,lightRange:n,shadowSoftness:n,eps:n,res:n,frame:n,rays:n,saRadius:n,saSides:n,saRounding:n,saInnerRatio:n,saRotation:n,saHeight:n,saOffset:n,saAperture:n,vfOriginX:n,vfOriginY:n,vfSpanX:n,vfSpanY:n,vfActiveRes:n,vfRBound:n}),\"IrradianceParams\"),Od={storageTexture:zt(GL,\"write-only\")},ph=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({params:{uniform:Sg},outTex:Od}),\"irradianceAnalyticLayout\"),Om=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({params:{uniform:Sg},outTex:Od,sdfSource:{texture:Zt(n)},samp:{sampler:\"filtering\"}}),\"irradianceSvgLayout\"),yu=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({params:{uniform:Sg},outTex:Od,silhouetteTex:{texture:Zt(n)},samp:{sampler:\"filtering\"}}),\"irradianceFieldLayout\"),nd=1e3,mh=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return B(ye(t,nd),__tsover_mul(nd,-1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"v\"}],body:[0,[[10,[6,\"std.max\",[[6,\"std.min\",[\"v\",\"FAR\"]],[1,\"FAR\",\"*\",[4,\"-\",[5,\"1\"]]]]]]]]},externals:{\"std.max\":()=>B,\"std.min\":()=>ye,FAR:()=>nd}})&&e.f)({})).$name(\"irradianceSane\"),KP=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=G(t,m(0,0),m(1,1));return he(t.sub(s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"c\",[6,\"std.clamp\",[\"uv\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],[6,\"d.vec2f\",[[5,\"1\"],[5,\"1\"]]]]]],[10,[6,\"std.length\",[[6,[7,\"uv\",\"sub\"],[\"c\"]]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m,\"std.length\":()=>he}})&&e.f)({})).$name(\"irradianceBeyondSquare\");function Mle(e){let t=P_(e);return w.fn([m],n)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=ph.$.params;return t(r,o.saRadius,o.saSides,o.saRounding,o.saInnerRatio,o.saRotation,o.saHeight,o.saOffset,o.saAperture).x}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"p\",[7,[7,\"irradianceAnalyticLayout\",\"$\"],\"params\"]],[10,[7,[6,\"sdfFn\",[\"uv\",[7,\"p\",\"saRadius\"],[7,\"p\",\"saSides\"],[7,\"p\",\"saRounding\"],[7,\"p\",\"saInnerRatio\"],[7,\"p\",\"saRotation\"],[7,\"p\",\"saHeight\"],[7,\"p\",\"saOffset\"],[7,\"p\",\"saAperture\"]]],\"x\"]]]]},externals:{irradianceAnalyticLayout:()=>ph,sdfFn:()=>t}})&&s.f)({})).$name(\"irradianceAnalyticField\")}var Ele=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Xl(Om.$.sdfSource,Om.$.samp,t,n(0)).x,r=KP(t);return mh(N(s,B(r,__tsover_sub(s,r)),r>0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"border\",[7,[6,\"std.textureSampleLevel\",[[7,[7,\"irradianceSvgLayout\",\"$\"],\"sdfSource\"],[7,[7,\"irradianceSvgLayout\",\"$\"],\"samp\"],\"uv\",[6,\"d.f32\",[[5,\"0\"]]]]],\"x\"]],[13,\"beyond\",[6,\"beyondSquare\",[\"uv\"]]],[10,[6,\"sane\",[[6,\"std.select\",[\"border\",[6,\"std.max\",[\"beyond\",[1,\"border\",\"-\",\"beyond\"]]],[1,\"beyond\",\">\",[5,\"0\"]]]]]]]]]},externals:{\"std.textureSampleLevel\":()=>Xl,irradianceSvgLayout:()=>Om,\"d.f32\":()=>n,beyondSquare:()=>KP,sane:()=>mh,\"std.select\":()=>N,\"std.max\":()=>B}})&&e.f)({})).$name(\"irradianceSvgField\"),kle=w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=yu.$.params,r=G(t.x,s.vfOriginX,__tsover_add(s.vfOriginX,s.vfSpanX)),o=G(t.y,s.vfOriginY,__tsover_add(s.vfOriginY,s.vfSpanY)),a=he(m(__tsover_sub(t.x,r),__tsover_sub(t.y,o))),i=__tsover_sub(he(m(__tsover_sub(t.x,.5),__tsover_sub(t.y,.5))),s.vfRBound),l=m(__tsover_div(__tsover_sub(r,s.vfOriginX),s.vfSpanX),__tsover_div(__tsover_sub(o,s.vfOriginY),s.vfSpanY)),c=Xl(yu.$.silhouetteTex,yu.$.samp,l,n(0)),d=__tsover_mul(c.z,c.w);return mh(N(d,B(B(a,i),__tsover_sub(d,a)),a>0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"}],body:[0,[[13,\"p\",[7,[7,\"irradianceFieldLayout\",\"$\"],\"params\"]],[13,\"cx\",[6,\"std.clamp\",[[7,\"uv\",\"x\"],[7,\"p\",\"vfOriginX\"],[1,[7,\"p\",\"vfOriginX\"],\"+\",[7,\"p\",\"vfSpanX\"]]]]],[13,\"cy\",[6,\"std.clamp\",[[7,\"uv\",\"y\"],[7,\"p\",\"vfOriginY\"],[1,[7,\"p\",\"vfOriginY\"],\"+\",[7,\"p\",\"vfSpanY\"]]]]],[13,\"outside\",[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",\"cx\"],[1,[7,\"uv\",\"y\"],\"-\",\"cy\"]]]]]],[13,\"circle\",[1,[6,\"std.length\",[[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"uv\",\"y\"],\"-\",[5,\"0.5\"]]]]]],\"-\",[7,\"p\",\"vfRBound\"]]],[13,\"tuv\",[6,\"d.vec2f\",[[1,[1,\"cx\",\"-\",[7,\"p\",\"vfOriginX\"]],\"/\",[7,\"p\",\"vfSpanX\"]],[1,[1,\"cy\",\"-\",[7,\"p\",\"vfOriginY\"]],\"/\",[7,\"p\",\"vfSpanY\"]]]]],[13,\"sil\",[6,\"std.textureSampleLevel\",[[7,[7,\"irradianceFieldLayout\",\"$\"],\"silhouetteTex\"],[7,[7,\"irradianceFieldLayout\",\"$\"],\"samp\"],\"tuv\",[6,\"d.f32\",[[5,\"0\"]]]]]],[13,\"inDomain\",[1,[7,\"sil\",\"z\"],\"*\",[7,\"sil\",\"w\"]]],[13,\"beyond\",[6,\"std.max\",[[6,\"std.max\",[\"outside\",\"circle\"]],[1,\"inDomain\",\"-\",\"outside\"]]]],[10,[6,\"sane\",[[6,\"std.select\",[\"inDomain\",\"beyond\",[1,\"outside\",\">\",[5,\"0\"]]]]]]]]]},externals:{irradianceFieldLayout:()=>yu,\"std.clamp\":()=>G,\"std.length\":()=>he,\"d.vec2f\":()=>m,\"std.textureSampleLevel\":()=>Xl,\"d.f32\":()=>n,\"std.max\":()=>B,sane:()=>mh,\"std.select\":()=>N}})&&e.f)({})).$name(\"irradianceVolumetricField\"),v2=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({vfOriginX:n,vfOriginY:n,vfSpanX:n,vfSpanY:n,vfActiveRes:n,vfRBound:n,res:n,step:n}),\"SilhouetteParams\"),pd=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({params:{uniform:v2},fieldTex:{texture:Zt(n),sampleType:\"unfilterable-float\"},out:Od}),\"silhouetteSeedLayout\"),Qc=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({params:{uniform:v2},src:{texture:Zt(n)},out:Od}),\"silhouetteStepLayout\"),{fieldSampleFastArg:QP}=bA(),du=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=pd.$.params,o=QP(m(__tsover_add(r.vfOriginX,__tsover_mul(__tsover_div(__tsover_add(t,.5),r.res),r.vfSpanX)),__tsover_add(r.vfOriginY,__tsover_mul(__tsover_div(__tsover_add(s,.5),r.res),r.vfSpanY))),pd.$.fieldTex,r.vfOriginX,r.vfOriginY,r.vfSpanX,r.vfSpanY,r.vfActiveRes,r.vfRBound).x;return N(n(1),n(-1),o<0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"tx\"},{type:\"i\",name:\"ty\"}],body:[0,[[13,\"p\",[7,[7,\"silhouetteSeedLayout\",\"$\"],\"params\"]],[13,\"uv\",[6,\"d.vec2f\",[[1,[7,\"p\",\"vfOriginX\"],\"+\",[1,[1,[1,\"tx\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanX\"]]],[1,[7,\"p\",\"vfOriginY\"],\"+\",[1,[1,[1,\"ty\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanY\"]]]]]],[13,\"v\",[7,[6,\"fieldSampleFastArg\",[\"uv\",[7,[7,\"silhouetteSeedLayout\",\"$\"],\"fieldTex\"],[7,\"p\",\"vfOriginX\"],[7,\"p\",\"vfOriginY\"],[7,\"p\",\"vfSpanX\"],[7,\"p\",\"vfSpanY\"],[7,\"p\",\"vfActiveRes\"],[7,\"p\",\"vfRBound\"]]],\"x\"]],[10,[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[1,\"v\",\"<\",[5,\"0\"]]]]]]]},externals:{silhouetteSeedLayout:()=>pd,\"d.vec2f\":()=>m,fieldSampleFastArg:()=>QP,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})).$name(\"silhouetteInside\"),Ble=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=pd.$.params,o=n(t),a=n(s),i=du(o,a),l=__tsover_sub(r.res,1),c=du(B(__tsover_sub(o,1),0),a),d=du(ye(__tsover_add(o,1),l),a),u=du(o,B(__tsover_sub(a,1),0)),p=du(o,ye(__tsover_add(a,1),l)),_=c!==i||d!==i||u!==i||p!==i,f=__tsover_add(r.vfOriginX,__tsover_mul(__tsover_div(__tsover_add(o,.5),r.res),r.vfSpanX)),h=__tsover_add(r.vfOriginY,__tsover_mul(__tsover_div(__tsover_add(a,.5),r.res),r.vfSpanY)),g=N(S(-1,-1,6e4,i),S(f,h,0,i),_);lt(pd.$.out,fe(t,s),g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"silhouetteSeedLayout\",\"$\"],\"params\"]],[13,\"fx\",[6,\"d.f32\",[\"cx\"]]],[13,\"fy\",[6,\"d.f32\",[\"cy\"]]],[13,\"s0\",[6,\"silhouetteInside\",[\"fx\",\"fy\"]]],[13,\"maxT\",[1,[7,\"p\",\"res\"],\"-\",[5,\"1\"]]],[13,\"sL\",[6,\"silhouetteInside\",[[6,\"std.max\",[[1,\"fx\",\"-\",[5,\"1\"]],[5,\"0\"]]],\"fy\"]]],[13,\"sR\",[6,\"silhouetteInside\",[[6,\"std.min\",[[1,\"fx\",\"+\",[5,\"1\"]],\"maxT\"]],\"fy\"]]],[13,\"sD\",[6,\"silhouetteInside\",[\"fx\",[6,\"std.max\",[[1,\"fy\",\"-\",[5,\"1\"]],[5,\"0\"]]]]]],[13,\"sU\",[6,\"silhouetteInside\",[\"fx\",[6,\"std.min\",[[1,\"fy\",\"+\",[5,\"1\"]],\"maxT\"]]]]],[13,\"boundary\",[3,[3,[3,[1,\"sL\",\"!==\",\"s0\"],\"||\",[1,\"sR\",\"!==\",\"s0\"]],\"||\",[1,\"sD\",\"!==\",\"s0\"]],\"||\",[1,\"sU\",\"!==\",\"s0\"]]],[13,\"sx\",[1,[7,\"p\",\"vfOriginX\"],\"+\",[1,[1,[1,\"fx\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanX\"]]]],[13,\"sy\",[1,[7,\"p\",\"vfOriginY\"],\"+\",[1,[1,[1,\"fy\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanY\"]]]],[13,\"seed\",[6,\"std.select\",[[6,\"d.vec4f\",[[4,\"-\",[5,\"1\"]],[4,\"-\",[5,\"1\"]],[5,\"60000\"],\"s0\"]],[6,\"d.vec4f\",[\"sx\",\"sy\",[5,\"0\"],\"s0\"]],\"boundary\"]]],[6,\"std.textureStore\",[[7,[7,\"silhouetteSeedLayout\",\"$\"],\"out\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],\"seed\"]]]]},externals:{silhouetteSeedLayout:()=>pd,\"d.f32\":()=>n,silhouetteInside:()=>du,\"std.max\":()=>B,\"std.min\":()=>ye,\"std.select\":()=>N,\"d.vec4f\":()=>S,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe}})&&e.f)({})).$name(\"silhouetteSeed\"),ZP=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=Qc.$.params,o=n(t),a=n(s),i=m(__tsover_add(r.vfOriginX,__tsover_mul(__tsover_div(__tsover_add(o,.5),r.res),r.vfSpanX)),__tsover_add(r.vfOriginY,__tsover_mul(__tsover_div(__tsover_add(a,.5),r.res),r.vfSpanY))),l=Ye(Qc.$.src,fe(t,s),0),c=S(l),d=__tsover_sub(r.res,1);for(let u=-1;u<=1;u++)for(let p=-1;p<=1;p++){let _=G(__tsover_add(o,__tsover_mul(n(p),r.step)),0,d),f=G(__tsover_add(a,__tsover_mul(n(u),r.step)),0,d),h=Ye(Qc.$.src,fe(M(_),M(f)),0);if(h.x>=0){let g=he(h.xy.sub(i));g<c.z&&(c=S(h.x,h.y,g,c.w))}}lt(Qc.$.out,fe(t,s),S(c.x,c.y,c.z,l.w))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"silhouetteStepLayout\",\"$\"],\"params\"]],[13,\"tx\",[6,\"d.f32\",[\"cx\"]]],[13,\"ty\",[6,\"d.f32\",[\"cy\"]]],[13,\"here\",[6,\"d.vec2f\",[[1,[7,\"p\",\"vfOriginX\"],\"+\",[1,[1,[1,\"tx\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanX\"]]],[1,[7,\"p\",\"vfOriginY\"],\"+\",[1,[1,[1,\"ty\",\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],\"*\",[7,\"p\",\"vfSpanY\"]]]]]],[13,\"self\",[6,\"std.textureLoad\",[[7,[7,\"silhouetteStepLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[5,\"0\"]]]],[12,\"best\",[6,\"d.vec4f\",[\"self\"]]],[13,\"maxT\",[1,[7,\"p\",\"res\"],\"-\",[5,\"1\"]]],[14,[12,\"j\",[4,\"-\",[5,\"1\"]]],[1,\"j\",\"<=\",[5,\"1\"]],[102,\"++\",\"j\"],[0,[[14,[12,\"i\",[4,\"-\",[5,\"1\"]]],[1,\"i\",\"<=\",[5,\"1\"]],[102,\"++\",\"i\"],[0,[[13,\"nx\",[6,\"std.clamp\",[[1,\"tx\",\"+\",[1,[6,\"d.f32\",[\"i\"]],\"*\",[7,\"p\",\"step\"]]],[5,\"0\"],\"maxT\"]]],[13,\"ny\",[6,\"std.clamp\",[[1,\"ty\",\"+\",[1,[6,\"d.f32\",[\"j\"]],\"*\",[7,\"p\",\"step\"]]],[5,\"0\"],\"maxT\"]]],[13,\"n\",[6,\"std.textureLoad\",[[7,[7,\"silhouetteStepLayout\",\"$\"],\"src\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"nx\"]],[6,\"d.u32\",[\"ny\"]]]],[5,\"0\"]]]],[11,[1,[7,\"n\",\"x\"],\">=\",[5,\"0\"]],[0,[[13,\"dist\",[6,\"std.length\",[[6,[7,[7,\"n\",\"xy\"],\"sub\"],[\"here\"]]]]],[11,[1,\"dist\",\"<\",[7,\"best\",\"z\"]],[0,[[2,\"best\",\"=\",[6,\"d.vec4f\",[[7,\"n\",\"x\"],[7,\"n\",\"y\"],\"dist\",[7,\"best\",\"w\"]]]]]]]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"silhouetteStepLayout\",\"$\"],\"out\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"best\",\"x\"],[7,\"best\",\"y\"],[7,\"best\",\"z\"],[7,\"self\",\"w\"]]]]]]]},externals:{silhouetteStepLayout:()=>Qc,\"d.f32\":()=>n,\"d.vec2f\":()=>m,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S,\"std.clamp\":()=>G,\"d.u32\":()=>M,\"std.length\":()=>he,\"std.textureStore\":()=>lt}})&&e.f)({})).$name(\"silhouetteStep\");function Q0(e,t,s){let{steps:r,shadowSteps:o,namePrefix:a}=s,i=3,l=o>0,c=Math.max(o,1),d=e,u=w.fn([m,m,n,n],n)((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f,h,g)=>{\"use gpu\";let y=f.sub(_),b=he(y),x=y.div(B(b,1e-4)),P=n(1),C=__tsover_mul(h,2);for(let E=0;E<c&&!(C>=b);E++){let R=t(_.add(x.mul(C)));if(P=ye(P,G(__tsover_div(R,B(__tsover_mul(C,g),h)),0,1)),P<=0)break;C=__tsover_add(C,B(R,h))}return P}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"from\"},{type:\"i\",name:\"toward\"},{type:\"i\",name:\"eps\"},{type:\"i\",name:\"soft\"}],body:[0,[[13,\"seg\",[6,[7,\"toward\",\"sub\"],[\"from\"]]],[13,\"len\",[6,\"std.length\",[\"seg\"]]],[13,\"dir\",[6,[7,\"seg\",\"div\"],[[6,\"std.max\",[\"len\",[5,\"0.0001\"]]]]]],[12,\"vis\",[6,\"d.f32\",[[5,\"1\"]]]],[12,\"t\",[1,\"eps\",\"*\",[5,\"2\"]]],[14,[12,\"k\",[5,\"0\"]],[1,\"k\",\"<\",\"shadowLoop\"],[102,\"++\",\"k\"],[0,[[11,[1,\"t\",\">=\",\"len\"],[0,[[17]]]],[13,\"dd\",[6,\"fieldAt\",[[6,[7,\"from\",\"add\"],[[6,[7,\"dir\",\"mul\"],[\"t\"]]]]]]],[2,\"vis\",\"=\",[6,\"std.min\",[\"vis\",[6,\"std.clamp\",[[1,\"dd\",\"/\",[6,\"std.max\",[[1,\"t\",\"*\",\"soft\"],\"eps\"]]],[5,\"0\"],[5,\"1\"]]]]]],[11,[1,\"vis\",\"<=\",[5,\"0\"]],[0,[[17]]]],[2,\"t\",\"+=\",[6,\"std.max\",[\"dd\",\"eps\"]]]]]],[10,\"vis\"]]]},externals:{\"std.length\":()=>he,\"std.max\":()=>B,\"d.f32\":()=>n,shadowLoop:()=>c,fieldAt:()=>t,\"std.min\":()=>ye,\"std.clamp\":()=>G}})&&p.f)({})).$name(`${a}Visibility`);return w.fn([M,M])((p=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(p.f=((_,f)=>{\"use gpu\";let h=d.$.params,g=h.eps,y=m(__tsover_div(__tsover_add(n(_),.5),h.res),__tsover_div(__tsover_add(n(f),.5),h.res)),b=jP(h.center,h.scale,h.rotation,y,h.aspect),x=t(b);if(x<__tsover_mul(g,-1)){lt(d.$.outTex,fe(_,f),S(0,0,0,0));return}let P=m(b);if(x<__tsover_mul(g,2)){let V=__tsover_sub(t(b.add(m(g,0))),x),X=__tsover_sub(t(b.add(m(0,g))),x),Q=vs(m(V,__tsover_add(X,1e-6)));P=b.add(Q.mul(__tsover_sub(__tsover_mul(g,2),x)))}let C=B(t(P),g),E=__tsover_add(C,i),R=Re(__tsover_mul(52.9829189,Re(__tsover_add(__tsover_mul(n(_),.06711056),__tsover_mul(n(f),.00583715))))),U=Re(__tsover_add(R,__tsover_mul(h.frame,.6180339887))),L=j(h.rays),k=__tsover_div(Jt,h.rays),D=j(h.lightCount),O=A(0,0,0);for(let V=0;V<L;V++){let X=__tsover_mul(__tsover_add(n(V),U),k),Q=m(pe(X),ae(X)),te=C,J=n(1);for(let oe=0;oe<r;oe++){let le=t(P.add(Q.mul(te)));if(le<g){J=le;break}if(te=__tsover_add(te,B(le,g)),te>E)break}if(J<g){let oe=P.add(Q.mul(te)),le=__tsover_sub(t(oe.add(m(g,0))),J),se=__tsover_sub(t(oe.add(m(0,g))),J),Te=vs(m(le,__tsover_add(se,1e-6))),de=oe.sub(Te.mul(B(J,0))),xe=de.add(Te.mul(__tsover_mul(g,2)));for(let Ae=0;Ae<D;Ae++){let De=h.lightPos[Ae],Ee=h.lightColor[Ae],ze=De.xy,Ie=ze.sub(de),ke=he(Ie),Me=Ie.div(B(ke,1e-4)),we=G(__tsover_div(__tsover_add(Se(Te,Me),h.wrap),__tsover_add(1,h.wrap)),0,1);if(we>0){let Ve=__tsover_div(ke,h.lightRange),qe=__tsover_div(we,__tsover_add(1,__tsover_mul(Ve,Ve)));l&&(qe=__tsover_mul(qe,u(xe,ze,g,h.shadowSoftness))),O=O.add(Ee.xyz.mul(__tsover_mul(qe,Ee.w)))}}}}let F=__tsover_sub(1,be(__tsover_mul(h.reach,.25),h.reach,B(x,0))),q=G(__tsover_add(__tsover_div(x,g),1),0,1),Y=ye(B(O.div(h.rays),A(0,0,0)),A(nd,nd,nd));lt(d.$.outTex,fe(_,f),S(Y.mul(__tsover_mul(F,q)),q))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"lay\",\"$\"],\"params\"]],[13,\"eps\",[7,\"p\",\"eps\"]],[13,\"uv\",[6,\"d.vec2f\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]],[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"p\",\"res\"]]]]],[13,\"sdfUV\",[6,\"sdfSpaceUV\",[[7,\"p\",\"center\"],[7,\"p\",\"scale\"],[7,\"p\",\"rotation\"],\"uv\",[7,\"p\",\"aspect\"]]]],[13,\"d0\",[6,\"fieldAt\",[\"sdfUV\"]]],[11,[1,\"d0\",\"<\",[1,\"eps\",\"*\",[4,\"-\",[5,\"1\"]]]],[0,[[6,\"std.textureStore\",[[7,[7,\"lay\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]]]],[10]]]],[12,\"o\",[6,\"d.vec2f\",[\"sdfUV\"]]],[11,[1,\"d0\",\"<\",[1,\"eps\",\"*\",[5,\"2\"]]],[0,[[13,\"gx\",[1,[6,\"fieldAt\",[[6,[7,\"sdfUV\",\"add\"],[[6,\"d.vec2f\",[\"eps\",[5,\"0\"]]]]]]],\"-\",\"d0\"]],[13,\"gy\",[1,[6,\"fieldAt\",[[6,[7,\"sdfUV\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],\"eps\"]]]]]],\"-\",\"d0\"]],[13,\"g\",[6,\"std.normalize\",[[6,\"d.vec2f\",[\"gx\",[1,\"gy\",\"+\",[5,\"0.000001\"]]]]]]],[2,\"o\",\"=\",[6,[7,\"sdfUV\",\"add\"],[[6,[7,\"g\",\"mul\"],[[1,[1,\"eps\",\"*\",[5,\"2\"]],\"-\",\"d0\"]]]]]]]]],[13,\"start\",[6,\"std.max\",[[6,\"fieldAt\",[\"o\"]],\"eps\"]]],[13,\"tMax\",[1,\"start\",\"+\",\"RAY_SPAN\"]],[13,\"ign\",[6,\"std.fract\",[[1,[5,\"52.9829189\"],\"*\",[6,\"std.fract\",[[1,[1,[6,\"d.f32\",[\"cx\"]],\"*\",[5,\"0.06711056\"]],\"+\",[1,[6,\"d.f32\",[\"cy\"]],\"*\",[5,\"0.00583715\"]]]]]]]]],[13,\"u\",[6,\"std.fract\",[[1,\"ign\",\"+\",[1,[7,\"p\",\"frame\"],\"*\",[5,\"0.6180339887\"]]]]]],[13,\"rays\",[6,\"d.i32\",[[7,\"p\",\"rays\"]]]],[13,\"rayStep\",[1,\"TAU\",\"/\",[7,\"p\",\"rays\"]]],[13,\"lightCount\",[6,\"d.i32\",[[7,\"p\",\"lightCount\"]]]],[12,\"acc\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"rays\"],[102,\"++\",\"i\"],[0,[[13,\"ang\",[1,[1,[6,\"d.f32\",[\"i\"]],\"+\",\"u\"],\"*\",\"rayStep\"]],[13,\"dir\",[6,\"d.vec2f\",[[6,\"std.cos\",[\"ang\"]],[6,\"std.sin\",[\"ang\"]]]]],[12,\"t\",\"start\"],[12,\"hitD\",[6,\"d.f32\",[[5,\"1\"]]]],[14,[12,\"s\",[5,\"0\"]],[1,\"s\",\"<\",\"steps\"],[102,\"++\",\"s\"],[0,[[13,\"dd\",[6,\"fieldAt\",[[6,[7,\"o\",\"add\"],[[6,[7,\"dir\",\"mul\"],[\"t\"]]]]]]],[11,[1,\"dd\",\"<\",\"eps\"],[0,[[2,\"hitD\",\"=\",\"dd\"],[17]]]],[2,\"t\",\"+=\",[6,\"std.max\",[\"dd\",\"eps\"]]],[11,[1,\"t\",\">\",\"tMax\"],[0,[[17]]]]]]],[11,[1,\"hitD\",\"<\",\"eps\"],[0,[[13,\"pos\",[6,[7,\"o\",\"add\"],[[6,[7,\"dir\",\"mul\"],[\"t\"]]]]],[13,\"nx\",[1,[6,\"fieldAt\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec2f\",[\"eps\",[5,\"0\"]]]]]]],\"-\",\"hitD\"]],[13,\"ny\",[1,[6,\"fieldAt\",[[6,[7,\"pos\",\"add\"],[[6,\"d.vec2f\",[[5,\"0\"],\"eps\"]]]]]],\"-\",\"hitD\"]],[13,\"n\",[6,\"std.normalize\",[[6,\"d.vec2f\",[\"nx\",[1,\"ny\",\"+\",[5,\"0.000001\"]]]]]]],[13,\"hitP\",[6,[7,\"pos\",\"sub\"],[[6,[7,\"n\",\"mul\"],[[6,\"std.max\",[\"hitD\",[5,\"0\"]]]]]]]],[13,\"shadowFrom\",[6,[7,\"hitP\",\"add\"],[[6,[7,\"n\",\"mul\"],[[1,\"eps\",\"*\",[5,\"2\"]]]]]]],[14,[12,\"l\",[5,\"0\"]],[1,\"l\",\"<\",\"lightCount\"],[102,\"++\",\"l\"],[0,[[13,\"lp\",[8,[7,\"p\",\"lightPos\"],\"l\"]],[13,\"lc\",[8,[7,\"p\",\"lightColor\"],\"l\"]],[13,\"lightUV\",[7,\"lp\",\"xy\"]],[13,\"toL\",[6,[7,\"lightUV\",\"sub\"],[\"hitP\"]]],[13,\"dist\",[6,\"std.length\",[\"toL\"]]],[13,\"dirL\",[6,[7,\"toL\",\"div\"],[[6,\"std.max\",[\"dist\",[5,\"0.0001\"]]]]]],[13,\"facing\",[6,\"std.clamp\",[[1,[1,[6,\"std.dot\",[\"n\",\"dirL\"]],\"+\",[7,\"p\",\"wrap\"]],\"/\",[1,[5,\"1\"],\"+\",[7,\"p\",\"wrap\"]]],[5,\"0\"],[5,\"1\"]]]],[11,[1,\"facing\",\">\",[5,\"0\"]],[0,[[13,\"r\",[1,\"dist\",\"/\",[7,\"p\",\"lightRange\"]]],[12,\"struck\",[1,\"facing\",\"/\",[1,[5,\"1\"],\"+\",[1,\"r\",\"*\",\"r\"]]]],[11,\"shadows\",[0,[[2,\"struck\",\"=\",[1,\"struck\",\"*\",[6,\"visibility\",[\"shadowFrom\",\"lightUV\",\"eps\",[7,\"p\",\"shadowSoftness\"]]]]]]]],[2,\"acc\",\"=\",[6,[7,\"acc\",\"add\"],[[6,[7,[7,\"lc\",\"xyz\"],\"mul\"],[[1,\"struck\",\"*\",[7,\"lc\",\"w\"]]]]]]]]]]]]]]]]]]],[13,\"fade\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,[7,\"p\",\"reach\"],\"*\",[5,\"0.25\"]],[7,\"p\",\"reach\"],[6,\"std.max\",[\"d0\",[5,\"0\"]]]]]]],[13,\"m\",[6,\"std.clamp\",[[1,[1,\"d0\",\"/\",\"eps\"],\"+\",[5,\"1\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"irr\",[6,\"std.min\",[[6,\"std.max\",[[6,[7,\"acc\",\"div\"],[[7,\"p\",\"rays\"]]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]]],[6,\"d.vec3f\",[\"FAR\",\"FAR\",\"FAR\"]]]]],[6,\"std.textureStore\",[[7,[7,\"lay\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[6,[7,\"irr\",\"mul\"],[[1,\"fade\",\"*\",\"m\"]]],\"m\"]]]]]]},externals:{lay:()=>d,\"d.vec2f\":()=>m,\"d.f32\":()=>n,sdfSpaceUV:()=>jP,fieldAt:()=>t,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S,\"std.normalize\":()=>vs,\"std.max\":()=>B,RAY_SPAN:()=>i,\"std.fract\":()=>Re,\"d.i32\":()=>j,TAU:()=>Jt,\"d.vec3f\":()=>A,\"std.cos\":()=>pe,\"std.sin\":()=>ae,steps:()=>r,\"std.length\":()=>he,\"std.clamp\":()=>G,\"std.dot\":()=>Se,shadows:()=>l,visibility:()=>u,\"std.smoothstep\":()=>be,\"std.min\":()=>ye,FAR:()=>nd}})&&p.f)({})).$name(`${a}Gather`)}function Yl(e,t,s){return wr(e,(r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a)=>{\"use gpu\";t(o,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>t}})&&r.f)({}),{size:[s.res,s.res],bindGroup:s.bindGroup})}var FL=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({weight:n}),\"AccumulateParams\"),_u=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({sample:{texture:Zt(n)},prev:{texture:Zt(n)},out:Od,params:{uniform:FL}}),\"accumulateLayout\"),zle=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=fe(t,s),o=Ye(_u.$.sample,r,0),a=Ye(_u.$.prev,r,0),i=_u.$.params.weight;lt(_u.$.out,r,N(a.add(o.sub(a).mul(i)),o,i>=1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"at\",[6,\"d.vec2u\",[\"cx\",\"cy\"]]],[13,\"s\",[6,\"std.textureLoad\",[[7,[7,\"accumulateLayout\",\"$\"],\"sample\"],\"at\",[5,\"0\"]]]],[13,\"prev\",[6,\"std.textureLoad\",[[7,[7,\"accumulateLayout\",\"$\"],\"prev\"],\"at\",[5,\"0\"]]]],[13,\"w\",[7,[7,[7,\"accumulateLayout\",\"$\"],\"params\"],\"weight\"]],[6,\"std.textureStore\",[[7,[7,\"accumulateLayout\",\"$\"],\"out\"],\"at\",[6,\"std.select\",[[6,[7,\"prev\",\"add\"],[[6,[7,[6,[7,\"s\",\"sub\"],[\"prev\"]],\"mul\"],[\"w\"]]]],\"s\",[1,\"w\",\">=\",[5,\"1\"]]]]]]]]},externals:{\"d.vec2u\":()=>fe,\"std.textureLoad\":()=>Ye,accumulateLayout:()=>_u,\"std.textureStore\":()=>lt,\"std.select\":()=>N}})&&e.f)({})).$name(\"irradianceAccumulate\"),I1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({src:{texture:Zt(n)},out:Od}),\"copyLayout\"),Rle=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=fe(t,s);lt(I1.$.out,r,Ye(I1.$.src,r,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"at\",[6,\"d.vec2u\",[\"cx\",\"cy\"]]],[6,\"std.textureStore\",[[7,[7,\"copyLayout\",\"$\"],\"out\"],\"at\",[6,\"std.textureLoad\",[[7,[7,\"copyLayout\",\"$\"],\"src\"],\"at\",[5,\"0\"]]]]]]]},externals:{\"d.vec2u\":()=>fe,\"std.textureStore\":()=>lt,copyLayout:()=>I1,\"std.textureLoad\":()=>Ye}})&&e.f)({})).$name(\"irradianceCopy\");var Dle=0,Lle=e=>new fs(()=>e),JP=(e,t)=>typeof e==\"number\"?fo(e):e._emit(t);function Ule(e,t){return{external:(s,r)=>e.external(s,r),statement:s=>t.push(s),freshLocal:s=>e.freshLocal(s),memo:(s,r)=>e.memo(s,r)}}function IL(e){let t=Dle++,s=e.hint??\"visibility\";return new fs(r=>r.memo(`shadow:${t}`,()=>{let o=r.freshLocal(s),a=r.freshLocal(\"shFrom\"),i=r.freshLocal(\"shSeg\"),l=r.freshLocal(\"shLen\"),c=r.freshLocal(\"shDir\"),d=r.freshLocal(\"shEps\"),u=r.freshLocal(\"shSoft\"),p=r.freshLocal(\"shT\"),_=r.freshLocal(\"shPos\"),f=r.freshLocal(\"shD\"),h=r.freshLocal(\"shStep\");r.statement(`let ${a} = ${e.from._emit(r)};`),r.statement(`let ${i} = ${e.toward._emit(r)} - ${a};`),r.statement(`let ${l} = length(${i});`),r.statement(`let ${c} = ${i} / max(${l}, 0.0001);`),r.statement(`let ${d} = ${JP(e.surfaceEps,r)};`),r.statement(`let ${u} = ${JP(e.softness??0,r)};`),r.statement(`var ${o} = 1.0;`);let g=[],y=e.field(Lle(_))._emit(Ule(r,g));return r.statement([\"{\",`  var ${p} = ${d} * 2.0;`,`  for (var ${h} = 0u; ${h} < ${e.steps}u; ${h}++) {`,`    if (${p} >= ${l}) { break; }`,`    let ${_} = ${a} + ${c} * ${p};`,...g.map(b=>`    ${b}`),`    let ${f} = ${y};`,`    ${o} = min(${o}, clamp(${f} / max(${p} * ${u}, ${d}), 0.0, 1.0));`,`    if (${o} <= 0.0) { break; }`,`    ${p} += max(${f}, ${d});`,\"  }\",\"}\"].join(`\n`)),o}))}var Ole=3,Gle=6,Fle=3,{createSdfDataTexture:Ile,analyticSubPropValues:Yle,parseShapeConfigValue:Wle}=yc,{createVolumetricFieldComputeNode:qle}=kn;function Vle(e,t,s,r,o){let a=(o.x-e.x)*r,i=1-o.y-(1-e.y),l=s*Math.PI/180,c=Math.cos(l),d=Math.sin(l),u=Math.max(t,.001);return{x:(a*c+i*d)/u+.5,y:(i*c-a*d)/u+.5}}function Nle(e,t,s){let r=(Array.isArray(e)?e:[]).slice(0,8),o=[],a=[];for(let i=0;i<8;i++){let l=r[i],c=l?.[t.position]??{x:.5,y:.5},d=Vle(s.center,s.scale,s.rotation,s.aspect,c),u=l?.[t.color]??[1,1,1,1],p=typeof l?.[t.intensity]==\"number\"?l[t.intensity]:0;o.push(l?[d.x,d.y,0,0]:[0,0,0,0]),a.push(l?[u[0],u[1],u[2],p]:[0,0,0,0])}return{pos:o,color:a,count:r.length}}function h2(e){let t=e.outputKey??\"irradianceTexture\",s=e.namePrefix??\"irradiance\",r={steps:e.steps??32,shadowSteps:e.shadowSteps??12,namePrefix:s},o=e.resolution;return{compute:l=>{let{gpu:c,getCpuValue:d,registerComputeTexture:u,onCleanup:p,onResize:_}=l,f=c?.root;if(!f)return null;let h=d(\"shapeSdfUrl\")||\"\",g=bc(d(\"shapeType\")||\"\",d(\"shape\")),y=qle(l,()=>d(\"shape\"),\"none\",\"span\"),b=()=>{let de=f.createTexture({size:[o,o],format:GL}).$usage(\"storage\",\"sampled\");return p(()=>de.destroy()),de},x=b(),P=b(),C=b(),E=Vh(f,P,o,o,p,Gle,o,o);E.updateRadius(Ole);let R=u(E.outputTexture),U=f.createUniform(Sg),L=f.createUniform(FL),k=Yl(f,zle,{res:o,bindGroup:f.createBindGroup(_u,{sample:x,prev:C,out:P,params:L.buffer})}),D=Yl(f,Rle,{res:o,bindGroup:f.createBindGroup(I1,{src:P,out:C})}),O,F=()=>0,q=null;if(y){let de=b(),xe=b(),Ae=f.createUniform(v2),De=Yl(f,Ble,{res:o,bindGroup:f.createBindGroup(pd,{params:Ae.buffer,fieldTex:y.fieldTexture,out:de})}),Ee=Yl(f,ZP,{res:o,bindGroup:f.createBindGroup(Qc,{params:Ae.buffer,src:de,out:xe})}),ze=Yl(f,ZP,{res:o,bindGroup:f.createBindGroup(Qc,{params:Ae.buffer,src:xe,out:de})}),Ie=[];for(let we=Math.ceil(o/2);we>=1&&(Ie.push(we),we!==1);we=Math.floor(we/2));let ke=Ie.length%2===1?xe:de;q={steps:we=>{let Ve=[],qe={vfOriginX:we.originX,vfOriginY:we.originY,vfSpanX:we.spanX,vfSpanY:we.spanY,vfActiveRes:we.activeRes,vfRBound:we.rBound,res:o};return Ve.push(()=>Ae.write({...qe,step:0}),De),Ie.forEach((st,pt)=>{Ve.push(()=>Ae.write({...qe,step:st}),pt%2===0?Ee:ze)}),Ve}};let Me=f.createSampler({magFilter:\"linear\",minFilter:\"linear\",addressModeU:\"clamp-to-edge\",addressModeV:\"clamp-to-edge\"});O=Yl(f,Q0(yu,kle,r),{res:o,bindGroup:f.createBindGroup(yu,{params:U.buffer,outTex:x,silhouetteTex:ke,samp:Me})})}else if(h){let de=Ile(l,h);F=()=>de.getVersion();let xe=f.createSampler({magFilter:\"linear\",minFilter:\"linear\",addressModeU:\"clamp-to-edge\",addressModeV:\"clamp-to-edge\"});O=Yl(f,Q0(Om,Ele,r),{res:o,bindGroup:f.createBindGroup(Om,{params:U.buffer,outTex:x,sdfSource:de.texture.texture,samp:xe})})}else O=Yl(f,Q0(ph,Mle(g),r),{res:o,bindGroup:f.createBindGroup(ph,{params:U.buffer,outTex:x})});let Y=Math.max(1,l.dimensions.width),V=Math.max(1,l.dimensions.height);_(({width:de,height:xe})=>{Y=Math.max(1,de),V=Math.max(1,xe)});let X=(de,xe)=>{let Ae=d(de);return typeof Ae==\"number\"?Ae:xe},Q=de=>{let xe=d(de);return{x:typeof xe?.x==\"number\"?xe.x:.5,y:typeof xe?.y==\"number\"?xe.y:.5}},te=\"\",J=!1,oe=0,le=Fle,se=0,Te=!1;return{outputs:{[t]:R,...y?.outputs??{}},getComputeNodes:de=>{let xe=y?.getComputeNodes(de)??null,Ae=[];if(q&&(xe||!J)){let yt=y.getFieldDomain();Ae=q.steps(yt),J=!0}let De=Q(\"center\"),Ee=X(\"scale\",1),ze=X(\"rotation\",0),Ie=Nle(d(e.lights.prop),e.lights,{center:De,scale:Ee,rotation:ze,aspect:Y/V}),ke=Yle(Wle(d(\"shape\"))),Me=y?.getFieldDomain(),we={center:[De.x,De.y],lightPos:Ie.pos,lightColor:Ie.color,lightCount:Ie.count,scale:Ee,rotation:ze,aspect:Y/V,reach:X(e.reach,3),wrap:X(e.wrap,0),lightRange:X(e.lightRange,1),shadowSoftness:X(e.shadowSoftness,0),eps:1/o/Math.max(Ee,.001),res:o,saRadius:ke.radius,saSides:ke.sides,saRounding:ke.rounding,saInnerRatio:ke.innerRatio,saRotation:ke.rotation,saHeight:ke.height,saOffset:ke.offset,saAperture:ke.aperture,vfOriginX:Me?.originX??0,vfOriginY:Me?.originY??0,vfSpanX:Me?.spanX??1,vfSpanY:Me?.spanY??1,vfActiveRes:Me?.activeRes??1,vfRBound:Me?.rBound??.6,fieldVersion:F()},Ve=JSON.stringify(we),qe=le>0;qe&&le--;let st=Ve!==te||!!xe||Ae.length>0||qe,pt;if(st)te=Ve,oe=0,se=0,pt=Te?e.rays.motion:e.rays.burst;else{if(oe>e.rays.refineFrames)return Te=!1,null;pt=e.rays.refine}Te=st;let Ze=oe++,nt=pt/(se+pt);se+=pt;let ht=xe?[...xe,...Ae]:[...Ae];return ht.push(()=>{let{fieldVersion:yt,...St}=we;U.write({...St,frame:Ze,rays:pt,center:m(we.center[0],we.center[1]),lightPos:we.lightPos.map(Mt=>S(Mt[0],Mt[1],Mt[2],Mt[3])),lightColor:we.lightColor.map(Mt=>S(Mt[0],Mt[1],Mt[2],Mt[3]))}),L.write({weight:nt})}),ht.push(O,k,D,...E.computeSteps),ht}}},sample:l=>{let c=l.computeOutputs?.[t];if(!c)return;let d=z(c.sampleLevel(l.ctx.uv),\"irrTex\");return Ce(d.member(\"rgb\"),it(d.member(\"a\"),.001))}}}var eC=[[1/16,-3/16],[-1/16,3/16],[5/16,1/16],[-3/16,-5/16],[-5/16,5/16],[-7/16,-1/16],[3/16,7/16],[7/16,-7/16]],Z0=1e9,tC=e=>e===\"sphere\"||e===\"rounded\"?e:\"cube\",sC=e=>e===\"view\"?\"view\":\"shape\";function YL(e){let t=Ts({stencil:\"centre\",centreTap:\"fast\",surface:(r,o)=>{let{uniforms:a}=o,i=tC(o.propValues[e.style.name]),l=sC(o.propValues[e.gridSpace.name]),c=Lr(r,o,{scale:a.scale}),d=Ea(o,c),u=a._vxMx,p=a._vxMy,_=a._vxMz,f=Ze=>l===\"shape\"?I(I(v(u,Ze.member(\"x\")),v(p,Ze.member(\"y\"))),v(_,Ze.member(\"z\"))):Ze,h=Ze=>l===\"shape\"?Qe($t(u,Ze),$t(p,Ze),$t(_,Ze)):Ze,g=r.sdfUV,y=z(f(Qe(ne(g.member(\"x\"),.5),ne(.5,g.member(\"y\")),-1.2)),\"vxRo\"),b=z(f(Qe(0,0,1)),\"vxRd\"),x=z(Ce(c.pxH,it(a.scale,.001)),\"vxPx\"),P=z(f(Qe(x,0,0)),\"vxEx\"),C=z(f(Qe(0,er(x),0)),\"vxEy\"),E=z(a._vxVoxel,\"vxSize\"),R=z(a._vxGridOrigin,\"vxOrigin\"),U=z(v(v(E,.5),me(e.voxelScale,o)),\"vxHalf\"),L=z(it(v(me(e.bevel,o),U),v(U,.04)),\"vxREff\"),k=z(v(R,-2),\"vxSpan\"),D=(Ze,nt)=>i===\"sphere\"?W(xne,\"voxelRaySphere\",[Ze,b,nt,U]):i===\"rounded\"?W(Ane,\"voxelRayRoundedBox\",[Ze,b,nt,U,v(me(e.bevel,o),U)]):W(bx,\"voxelRayBox\",[Ze,b,nt,U]),O=z(a._vfActiveRes,\"vxRes\"),F=a._vfOriginX,q=a._vfOriginY,Y=a._vfSpanX,V=a._vfSpanY,X=ne(O,1),Q=ne(v(Ce(ne(g.member(\"x\"),F),Y),O),.5),te=ne(v(Ce(ne(g.member(\"y\"),q),V),O),.5),J=z(Ge(Xr(Q),0,X),\"vxX0\"),oe=z(Ge(Xr(te),0,X),\"vxY0\"),le=Yr(I(J,1),X),se=Yr(I(oe,1),X),Te=(Ze,nt)=>rt(I(F,v(Ce(I(Ze,.5),O),Y)),I(q,v(Ce(I(nt,.5),O),V))),de=[{tx:J,ty:oe,tag:\"00\"},{tx:le,ty:oe,tag:\"10\"},{tx:J,ty:se,tag:\"01\"},{tx:le,ty:se,tag:\"11\"}].map(Ze=>{let nt=$r=>`${$r}${Ze.tag}`,ht=z(Te(Ze.tx,Ze.ty),nt(\"vxUv\")),yt=z(r.texelSampler(ht),nt(\"vxTex\")),St=z(br(Xn(yt.member(\"x\"),0),1,0),nt(\"cov\")),Mt=yt.member(\"y\"),Rt=z(Ce(Xr(Ce(ne(Mt,v(Xr(Ce(Mt,65536)),65536)),256)),255),nt(\"ao\")),Kt=yt.member(\"z\"),Wt=z(Xr(Ce(Kt,65536)),nt(\"cz\")),ls=ne(Kt,v(Wt,65536)),us=z(Xr(Ce(ls,256)),nt(\"cy\")),os=z(Qe(z(ne(ls,v(us,256)),nt(\"cx\")),us,Wt),nt(\"cell\")),bs=z(I(v(I(os,.5),E),R),nt(\"centre\")),hs=yt.member(\"w\"),gs=z(f(Qe(ne(ht.member(\"x\"),.5),ne(.5,ht.member(\"y\")),ne(hs,1.2))),nt(\"texHp\")),Gs=z(br(Zo(St,.5),D(y,bs),-1),nt(\"tC\")),Ss=Zo(Gs,-.5),or=z(br(Ss,I(y,v(b,Gs)),gs),nt(\"hp\")),yr=z(br(Ss,Gs,hs),nt(\"depth\")),lr=z(ne(or,bs),nt(\"l\")),Ur=z(ms(lr),nt(\"al\")),so=it(Ur.member(\"x\"),it(Ur.member(\"y\"),Ur.member(\"z\"))),ro=z(br(ch(Ur.member(\"x\"),so),1,0),nt(\"isX\")),_e=z(v(br(ch(Ur.member(\"y\"),so),1,0),ne(1,ro)),nt(\"isY\")),We=ne(ne(1,ro),_e),Le=z(v(Bx(lr),Qe(ro,_e,We)),nt(\"faceN\")),Be=z(ne(1,ms(Le)),nt(\"tMask\")),Oe;if(i===\"sphere\")Oe=Os(lr);else{let $r=v(v(Bx(lr),it(ne(Ur,ne(U,L)),Qe(0,0,0))),Be);Oe=Os(I(v(Le,L),$r))}let tt=z(Oe,nt(\"nG\")),_t=z(h(tt),nt(\"nV\")),Bt=z(Qe(_t.member(\"x\"),er(_t.member(\"y\")),_t.member(\"z\")),nt(\"n\")),Dt=v(Ur,Be),Nt=z(Ge(Ce(it(it(Dt.member(\"x\"),Dt.member(\"y\")),Dt.member(\"z\")),U),0,1),nt(\"edge\")),Ks=z(W(Wb,\"hash13\",[I(os,Qe(.37,.61,.83))]),nt(\"hash\")),Ds=z(Ge(Ce(v(I(us,.5),E),k),0,1),nt(\"heightT\")),ar=z(Ge(Ce(ne(yr,I(1.2,R)),k),0,1),nt(\"depthT\")),Xo=z(br(Ss,Gs,Z0),nt(\"tSort\"));return{tag:Ze.tag,cov:St,cell:os,centre:bs,hp:or,nG:tt,tSort:Xo,frame:{field:c,coverage:St,normal:Bt,ao:Rt,cell:os,cellHash:Ks,heightT:Ds,depthT:ar,edge:Nt,view:d,style:i}}}),xe=Ze=>z(v(br(Xn(ms(ne(de[Ze].cell,de[0].cell)).member(\"x\"),.5),1,0),v(br(Xn(ms(ne(de[Ze].cell,de[0].cell)).member(\"y\"),.5),1,0),br(Xn(ms(ne(de[Ze].cell,de[0].cell)).member(\"z\"),.5),1,0))),`vxSame${Ze}`),Ae=[$e(1),xe(1),xe(2),xe(3)],De=z(v(v(v(Ae[1],Ae[2]),Ae[3]),v(v(de[0].cov,de[1].cov),v(de[2].cov,de[3].cov))),\"vxAllOne\"),Ee=o.computeOutputs?.voxelShadowMap,ze=$e(0);if(Ee){let Ze=(Rt,Kt)=>{let Wt=Xn(Rt.tSort,Kt.tSort);return{tSort:br(Wt,Rt.tSort,Kt.tSort),hp:br(Wt,Rt.hp,Kt.hp),nG:br(Wt,Rt.nG,Kt.nG)}},nt=Ze(Ze(de[0],de[1]),Ze(de[2],de[3])),ht=z(nt.hp,\"vxHpShadow\"),yt=z(nt.nG,\"vxNShadow\"),St=W(bne,\"voxelShadowLookup\",[Ee.accessor(),I(ht,v(yt,v(E,.12))),a._vxL,a._vxT1,a._vxT2,er(R),me(e.shadowSoftness,o),E]),Mt=Zo($t(yt,a._vxL),-.12);ze=Js(Zo(v(br(Zo(a.shadows,.001),1,0),br(Mt,1,0)),.5),St,$e(1),\"shadow\",[ht,yt])}let Ie=de.flatMap(Ze=>[Ze.cov,Ze.centre,Ze.tSort,Ze.frame.normal,Ze.frame.ao,Ze.frame.cellHash,Ze.frame.heightT,Ze.frame.depthT,Ze.frame.edge]),ke=z(e.surface({...de[0].frame,shadow:ze},r,o).member(\"rgb\"),\"vxShade00\"),Me=de.map((Ze,nt)=>nt===0?ke:Js(Xn(Ae[nt],.5),e.surface({...Ze.frame,shadow:ze},r,o).member(\"rgb\"),ke,`vxShade${Ze.tag}`,nt===1?Ie:[])),we=$e(0),Ve=Qe(0,0,0);eC.forEach(([Ze,nt],ht)=>{let yt=z(I(I(y,v(P,Ze)),v(C,nt)),`vxRo${ht}`),St=de.map(us=>{let os=z(br(Zo(us.cov,.5),D(yt,us.centre),-1),`vxTr${ht}_${us.tag}`);return z(br(Zo(os,-.5),os,Z0),`vxT${ht}_${us.tag}`)}),Mt=Yr(St[2],St[3]),Rt=Yr(St[1],Mt),Kt=Yr(St[0],Rt),Wt=br(Xn(St[0],Rt),Me[0],br(Xn(St[1],Mt),Me[1],br(Xn(St[2],St[3]),Me[2],Me[3]))),ls=z(br(Xn(Kt,Z0*.5),1,0),`vxHit${ht}`);we=I(we,ls),Ve=I(Ve,v(Wt,ls))});let qe=Ot(Ce(Ve,it(we,1e-4)),Ce(we,eC.length)),st=Ot(ke,1),pt=Js(Xn(De,.5),qe,st,\"vxOut\",[ke,...Me.slice(1)]);return Js(Dr(c.sdf,c.pxH),pt,xt,\"voxels\")}}),s=r=>{let o=(i,l)=>{if(!i)return l;let c=r.getCpuValue(i.name);return typeof c==\"number\"&&Number.isFinite(c)?c:l},a=()=>{let i=r.getCpuValue(\"_animTime\");return typeof i==\"number\"&&Number.isFinite(i)?i:0};return Pne(r,{style:tC(r.propValues[e.style.name]),gridSpace:sC(r.propValues[e.gridSpace.name]),getShapeConfig:()=>r.getCpuValue(\"shape\"),getValues:()=>({voxelSize:o(e.voxelSize,.03),fill:o(e.fill,0),voxelScale:o(e.voxelScale,1),bevel:o(e.bevel,0),pitch:o(e.pitch,0),yaw:o(e.yaw,0)+(e.spin?a()*36:0),lightAngle:o(e.lightAngle,225),lightElevation:o(e.lightElevation,45),depth:o(e.depth,.12)})})};return{extraFields:{...t.extraFields,...Tne},compute:s,gpu:t.gpu}}var $le=bt;function aa(e){let t=e.uvContext??e.ctx.uv,s=e.effectiveViewportSize??e.ctx.viewportSize;return{uv:t,viewport:s,aspect:z(Ce(s.member(\"x\"),s.member(\"y\")),\"aspect\")}}function WL(e){let t=e.uvContext??e.ctx.uv,s=e.ctx.viewportSize;return{uv:t,viewport:s,aspect:z(Ce(s.member(\"x\"),s.member(\"y\")),\"aspect\")}}function qL(e){return(t,s)=>{let r=me(e.center,t),{uv:o,aspect:a}=s,i=z(rt(ne(v(o.member(\"x\"),a),v(r.member(\"x\"),a)),ne(o.member(\"y\"),ne(1,r.member(\"y\")))),\"centred\");return{delta:i,dist:z(Kr(i),\"centredDist\")}}}function Pg(e){return(t,s)=>{let r=me(e.from,t),o=me(e.to,t),{uv:a,aspect:i}=s,l=v(r.member(\"x\"),i),c=ne(1,r.member(\"y\")),d=z(rt(ne(v(a.member(\"x\"),i),l),ne(a.member(\"y\"),c)),\"rel\"),u=z(rt(ne(v(o.member(\"x\"),i),l),ne(ne(1,o.member(\"y\")),c)),\"toRel\"),p=z(it(Kr(u),1e-4),\"segLen\"),_=z(Ce(u,p),\"segDir\");return{along:z($t(d,_),\"along\"),across:z(I(v(d.member(\"x\"),er(_.member(\"y\"))),v(d.member(\"y\"),_.member(\"x\"))),\"across\"),length:p}}}function Er(e,t=\"dir\"){let s=v(e,$le);return z(rt(Do(s),Vt(s)),t)}function ii(e,t=\"grain\"){let s=Er(e,`${t}T`),r=z(rt(er(s.member(\"y\")),s.member(\"x\")),`${t}P`);return{tangent:s,perp:r,coordsOf(o){return{along:z($t(o,s),\"along\"),across:z($t(o,r),\"across\")}}}}function g2(e,t,s,r=.5){let o=3.141592653589793,a=z(ne(e,r),\"kfDx\"),i=z(ne(t,r),\"kfDy\"),l=z(ho(I(v(a,a),v(i,i))),\"kfR\"),c=z(v(Qr(Ce(I(sle(i,a),o),s)),s),\"kfInSector\"),d=z(Yr(c,ne(s,c)),\"kfFolded\");return rt(v(l,Do(d)),v(l,Vt(d)))}function Ft(e,t){if(typeof e==\"number\")return $e(e);if(e instanceof zi)return fn(e,t);if(typeof e==\"object\"&&e!==null&&\"kind\"in e)return e.kind===\"prop\"?me(e,t):fn(e,t);throw new Error(\"std/warps: warp slots accept prop bindings, numbers, and Scalar signals\")}function VL(e){return t=>{let s=(r,o)=>W(Oee,\"mirrorReflect\",[Ft(e.center,t),Ft(e.angle,t),r,o]);return Kne(r=>r,(r,o)=>s(r,o).member(\"xy\"),(r,o)=>s(r,o).member(\"z\"))}}function NL(e){return t=>({map:s=>W(Gee,\"flipUV\",[s,Ft(e.flipX,t),Ft(e.flipY,t)])})}function $L(e){return t=>({map:(s,r)=>W(Fee,\"bendRemap\",[Ft(e.strength,t),Ft(e.falloff,t),Ft(e.angle,t),s,r])})}function XL(e){return t=>({map:(s,r)=>W(Iee,\"bulgeUV\",[Ft(e.center,t),Ft(e.strength,t),Ft(e.radius,t),Ft(e.falloff,t),s,r])})}function HL(e){return t=>({map:(s,r)=>W(Yee,\"twirlUV\",[Ft(e.center,t),Ft(e.intensity,t),s,r])})}function jL(e){return t=>({map:(s,r)=>W(Wee,\"kaleidoscopeUV\",[Ft(e.center,t),Ft(e.segments,t),Ft(e.angle,t),s,r])})}function KL(e){return t=>({map:(s,r)=>W(qee,\"stretchUV\",[Ft(e.center,t),Ft(e.strength,t),Ft(e.angle,t),Ft(e.falloff,t),s,r])})}var Xle={sine:0,triangle:1,square:2,sawtooth:3,bounce:4};function Hle(e){return typeof e==\"number\"?e:Xle[e]??0}function jle(e){switch(e){case 1:return{fn:Nee,hint:\"waveDistortTriangle\"};case 2:return{fn:$ee,hint:\"waveDistortSquare\"};case 3:return{fn:Xee,hint:\"waveDistortSawtooth\"};case 4:return{fn:Hee,hint:\"waveDistortBounce\"};default:return{fn:Vee,hint:\"waveDistortSine\"}}}function QL(e){return t=>{let{fn:s,hint:r}=jle(Hle(t.propValues[e.waveType.name])),o=wt(t).mul(.5);return{map:(a,i)=>W(s,r,[a,i,Ft(e.angle,t),Ft(e.frequency,t),Ft(e.strength,t),o])}}}function ZL(e){return t=>xz({map:(s,r)=>W(jee,\"polarCoordsUV\",[Ft(e.center,t),Ft(e.wrap,t),Ft(e.radius,t),s,r])},()=>Ft(e.intensity,t))}function JL(e){return t=>xz({map:(s,r)=>W(Kee,\"rectCoordsUV\",[Ft(e.center,t),Ft(e.scale,t),s,r])},()=>Ft(e.intensity,t))}function eU(e){return t=>({map:s=>{let r=W(Qee,\"cornerPinSample\",[s,Ft(e.amount,t),Ft(e.topLeft,t),Ft(e.topRight,t),Ft(e.bottomRight,t),Ft(e.bottomLeft,t)]);return{uv:r.member(\"xy\"),coverage:r.member(\"z\")}}})}function tU(e){return t=>({map:s=>W(Zee,\"perspectiveUV\",[Ft(e.center,t),Ft(e.pan,t),Ft(e.tilt,t),Ft(e.fov,t),Ft(e.zoom,t),Ft(e.offset,t),s])})}function sU(e){return t=>{let s=wt(t);return{map:(r,o)=>W(Jee,\"concentricSpinUV\",[Ft(e.center,t),Ft(e.intensity,t),Ft(e.rings,t),Ft(e.smoothness,t),Ft(e.seed,t),Ft(e.speedRandomness,t),s,r,o])}}}function rU(e){return t=>{let s=wt(t,e.seed.name).mul(.1),r=wt(t,e.seed.name,\"_animTime_evolution\").mul(.1);return{map:(o,a)=>W(ete,\"flowFieldUV\",[o,a,Ft(e.detail,t),Ft(e.strength,t),s,r])}}}function oU(e){return t=>({map:(s,r)=>W(tte,\"sliceWipeUV\",[s,r,Ft(e.angle,t),Ft(e.count,t),Ft(e.progress,t)])})}function aU(e){return t=>{let s=wt(t);return{map:(r,o)=>W(ste,\"barShiftUV\",[Ft(e.count,t),Ft(e.angle,t),Ft(e.intensity,t),Ft(e.seed,t),s,r,o])}}}function nU(e){return t=>({map:(s,r)=>{let o=t.computeOutputs?.[e.output],a=W(rte,\"gridCellSnap\",[s,Ft(e.gridSize,t),r]);return W(ote,\"gridDistortOffsetUV\",[s,o?o.sample(a,\"linearClamp\").member(\"xy\"):ca(\"vec2f(0.0, 0.0)\")])}})}function iU(e){return t=>({map:s=>{let r=t.computeOutputs?.[e.output];return W(ate,\"liquifyOffsetUV\",[s,r?r.sample(s,\"linearClamp\").member(\"xy\"):ca(\"vec2f(0.0, 0.0)\"),Ft(e.intensity,t)])}})}var Kle={twoAxis:0,directional:1};function Qle(e){return typeof e==\"number\"?e:Kle[e]??0}function lU(e){return{kind:\"gather\",build:t=>{let s=t.getLayerTexture(e.source.name);if(!s)return t.texture.sample(t.ctx.uv);let r=t.propValues[e.edges.name]??0,o=s.sample(t.ctx.uv),a=Qle(t.propValues[e.channels.name])===1?W(ite,\"dmDisplaceLuminance\",[t.ctx.uv,o,t.ctx.aspect,Ft(e.amount,t),Ft(e.angle,t)]):W(nte,\"dmDisplaceRG\",[t.ctx.uv,o,t.ctx.aspect,Ft(e.amount,t)]);return T4(t.texture,a,r)}}}function cU(e,t){let s=z(it(Vt(I(v(e,t.rate),t.offset??0)),0),\"flash\");for(let r=1;r<t.sharpness;r*=2)s=z(v(s,s),\"flash\");return s}function $o(e,t,s){return{kind:\"gather\",resultAlpha:s?.resultAlpha,build:r=>t.reduce((o,a)=>a(o,r),e(r))}}function Cg(e){let t=new WeakMap;return s=>{let r=t.get(s);if(r)return r;let o=e(s);return t.set(s,o),o}}function dU(e){return t=>{let s=At(e.amount,t),r=W(SS,\"crtSampleUV\",[t.ctx.uv,s,$e(1)]),o=W(SS,\"crtSampleUV\",[t.ctx.uv,s,$e(-1)]);return W(_re,\"rgbSplitCombine\",[t.texture.sample(r),t.texture.sample(t.ctx.uv),t.texture.sample(o)])}}function uU(e){return t=>W(yre,\"vhsSampleUVs\",[t.ctx.uv,t.ctx.time,At(e.speed,t),At(e.wobble,t),At(e.jitter,t)])}function pU(e){return t=>{let s=ns(e.warp(t),\"tapeUVs\"),r=s.member(\"zw\"),o=t.texture.sample(s.member(\"xy\")),a=At(e.smear,t).mul(.0075),i=l=>t.texture.sample(W(xre,\"vhsChromaTapUV\",[r,a,$e(l)]));return Ct(W(Are,\"yiqRecombine\",[o,i(1),i(2),i(3),i(4),i(5)]),o.member(\"a\"))}}function mU(e,t,s){let r=i=>v($t(i.member(\"rgb\"),Qe(.2126,.7152,.0722)),i.member(\"a\")),o=z(e(t),\"nearC\"),a=z(r(o),\"nearL\");for(let i=0;i<s.taps;i++){let l=((s.angle??0)+360*i/s.taps)*(Math.PI/180),c=z(e(I(t,v(rt(Math.cos(l),Math.sin(l)),s.radius))),\"nearT\"),d=z(r(c),\"nearTL\");o=z(br(Zo(d,a),c,o),\"nearC\"),a=z(it(d,a),\"nearL\")}return{color:o,luma:a}}function _U(e){return(t,s)=>W(fre,\"adjustShade\",[t,At(e.contrast,s),At(e.brightness,s)])}function fU(e){return(t,s)=>W(vre,\"scanlineShade\",[t,s.ctx.uv.member(\"y\"),At(e.frequency,s),At(e.intensity,s)])}function vU(e){return(t,s)=>W(hre,\"phosphorShade\",[t,s.ctx.uv,At(e.pitch,s)])}function hU(e){return(t,s)=>W(gre,\"vignetteShade\",[t,s.ctx.uv,s.ctx.aspect,At(e.radius,s),At(e.intensity,s)])}function gU(){return e=>Ct(e,$e(1))}function yU(e){return(t,s)=>W(wre,\"beatShade\",[t,W(bre,\"vhsAcBeat\",[s.ctx.uv,s.ctx.time,At(e.speed,s),At(e.wobble,s)])])}var wp={linear:e=>({kind:\"linear\",focus:e}),orbit:e=>({kind:\"orbit\",focus:e}),zoom:e=>({kind:\"zoom\",focus:e})};function Tp(e){let{path:t,amount:s,detail:r}=e;return{kind:\"gather\",build:o=>{let a={focus:At(t.focus,o),amount:At(s,o),uv:o.ctx.uv,aspect:o.ctx.aspect,viewportSize:o.ctx.viewportSize},i=d=>o.texture.sample(d);if(!r||!Zle(r,o))return qse(t.kind,a,i);let l=d=>d?me(d,o):$e(0),c=t.kind===\"zoom\"&&r.spiral&&Mg(r.spiral,o)?me(r.spiral,o):void 0;return Qse(t.kind,a,{dispersion:l(r.dispersion),falloff:l(r.falloff),focus:l(r.focus),bias:l(r.bias),highlights:l(r.highlights),jitter:l(r.jitter),spiral:c,center:t.kind===\"linear\"?ca(\"vec2f(0.5, 0.5)\"):a.focus},i)}}}function Mg(e,t){if(t.getMapInfo?.(e.name))return!0;let s=t.propValues?.[e.name];return typeof s==\"number\"?s!==0:!!s}function Zle(e,t){return Object.values(e).some(s=>s&&Mg(s,t))}function bU(e){let{amount:t,edges:s,chromatic:r}=e;return{kind:\"gather\",build:o=>sre({uv:o.ctx.uv,amount:At(t,o),viewportSize:o.ctx.viewportSize,edgeMode:o.propValues[s.name]??0,sample:a=>o.texture.sample(a),chromatic:r&&Mg(r,o)?me(r,o):void 0})}}function xU(e){return{kind:\"gather\",build:t=>dre({uv:t.ctx.uv,viewportSize:t.ctx.viewportSize,amount:At(e,t),sample:s=>t.texture.sample(s)})}}function AU(e){let{scale:t,gap:s,roundness:r}=e;return{kind:\"gather\",resultAlpha:\"straight\",build:o=>pre({uv:o.ctx.uv,aspect:o.ctx.aspect,scale:At(t,o),gap:At(s,o),roundness:At(r,o),sampleStraight:o.sampleStraight})}}function wU(e){return Cg(t=>ns(W(vte,\"sphereBulge\",[t.ctx.uv,t.ctx.viewportSize,At(e.center,t),At(e.radius,t),At(e.depth,t)]),\"sphere\"))}function TU(e){return t=>W(Yt,\"unpremultiplyAlpha\",[g_(t.texture,e(t).member(\"uv\"))])}function SU(e,t){return(s,r)=>{let o=W(hte,\"rimLight\",[e(r).member(\"normal\"),At(t.position,r),At(t.intensity,r),At(t.softness,r)]);return W(gte,\"rimComposite\",[s,At(t.color,r).member(\"rgb\"),o,e(r).member(\"coverage\")])}}function PU(e){return Cg(t=>ns(W(Tre,\"glitchGeom\",[t.ctx.uv,t.ctx.time,At(e.intensity,t),At(e.speed,t),At(e.blockDensity,t),At(e.mirrorAmount,t)]),\"glitch\"))}function CU(e,t){return s=>{let r=e(s),o=ns(W(Sre,\"glitchSplitUVs\",[r.member(\"mirroredUV\"),At(t.shift,s),r.member(\"spread\")]),\"splitUVs\"),a=s.texture.sample(r.member(\"mirroredUV\"));return Ct(s.texture.sample(o.member(\"xy\")).member(\"r\"),a.member(\"g\"),s.texture.sample(o.member(\"zw\")).member(\"b\"),a.member(\"a\"))}}function MU(e,t){return(s,r)=>{let o=e(r);return W(Pre,\"fillBarsShade\",[s,r.ctx.uv,o.member(\"bandY1\"),o.member(\"slowFrame\"),At(t.intensity,r),o.member(\"strength\"),o.member(\"bandGate\"),o.member(\"blockGate\")])}}function EU(e,t){return(s,r)=>W(Cre,\"distortScanShade\",[s,r.ctx.uv.member(\"y\"),r.ctx.viewportSize.member(\"y\"),At(t.intensity,r),e(r).member(\"distortion\")])}function kU(e){let t=e.intensity.name;return{compute:s=>{let{getCpuValue:r,getMapInfo:o}=s,a=o(t);return a?qu(s,{source:a,buildFill:(i,l)=>cse(i,l,a.channel),fillValues:(i,l)=>({inputWidth:i.width,inputHeight:i.height,...Nh(l)})}):B4(s,{radius:()=>{let i=r(t);return typeof i==\"number\"?Q3(i):4}})},gpu:{fragment:s=>x_(s,(r,o)=>Ct(r.member(\"rgb\"),o.member(\"a\")))}}}function BU(e){let{red:t,green:s,blue:r}=e;return{compute:o=>B4(o,{radius:()=>{let a=(o.getCpuValue(t.name)??0)*T0,i=(o.getCpuValue(s.name)??0)*T0,l=(o.getCpuValue(r.name)??0)*T0;return Math.max(a,i,l,.01)}}),gpu:{fragment:o=>x_(o,(a,i)=>W(dse,\"channelBlurCompose\",[i,a,me(t,o),me(s,o),me(r,o)]))}}}function zU(e,t){if(!e)return{};let{dispersion:s,jitter:r}=e,o=s?Mg(s,t):!1,a=i=>i?t.getCpuValue(i.name)??0:0;return{chromatic:o,detail:()=>({jitter:a(r),dispersion:o?a(s)*ise:0})}}function RU(e){let{intensity:t,angle:s,center:r,falloff:o,detail:a}=e;return{compute:i=>{let{getCpuValue:l,getMapInfo:c}=i,d=zU(a,i),u=_=>{let f=l(r.name);return{angle:l(s.name)??0,centerX:typeof f?.x==\"number\"?f.x:0,centerY:typeof f?.y==\"number\"?f.y:.5,falloff:l(o.name)??1,aspect:_.width/_.height}},p=c(t.name);return p?qu(i,{source:p,buildFill:(_,f)=>_se(_,f,p.channel),...d,fillValues:(_,f)=>({...u(_),inputWidth:_.width,inputHeight:_.height,...Nh(f)})}):qu(i,{buildFill:mse,...d,fillValues:_=>({...u(_),maxRadius:Q3(l(t.name)??0)})})},gpu:{fragment:i=>x_(i,(l,c)=>Ct(l.member(\"rgb\"),c.member(\"a\")))}}}function DU(e){let{intensity:t,width:s,falloff:r,angle:o,center:a,detail:i}=e;return{compute:l=>{let{getCpuValue:c,getMapInfo:d}=l,u=zU(i,l),p=f=>{let h=c(a.name);return{angle:c(o.name)??0,centerX:typeof h?.x==\"number\"?h.x:.5,centerY:typeof h?.y==\"number\"?h.y:.5,width:c(s.name)??.3,falloff:c(r.name)??.3,aspect:f.width/f.height}},_=d(t.name);return _?qu(l,{halfKernel:14,source:_,buildFill:(f,h)=>gse(f,h,_.channel),...u,fillValues:(f,h)=>({...p(f),inputWidth:f.width,inputHeight:f.height,...Nh(h)})}):qu(l,{halfKernel:14,buildFill:hse,...u,fillValues:f=>({...p(f),maxRadius:Q3(c(t.name)??0)})})},gpu:{fragment:l=>x_(l,(c,d)=>ea(d,c,W(Km,\"tiltShiftBlurAmount\",[me(o,l),me(a,l),me(s,l),me(r,l),l.ctx.uv,l.ctx.aspect])))}}}function LU(e){let{intensity:t,threshold:s,size:r}=e;return{compute:o=>{let{getCpuValue:a,getMapInfo:i}=o,l=i(r.name);return!l&&(a(r.name)??0)===0?null:z4(o,{mapInfo:l,buildExtract:bse,buildExtractMap:xse,threshold:()=>a(s.name)??.5,radius:()=>a(r.name)??25})},gpu:{fragment:o=>x_(o,(a,i)=>W(yse,\"glowCompose\",[i,a,me(t,o)]))}}}function UU(){return e=>e.texture.sample(e.ctx.uv)}function OU(e){return t=>W(are,\"dropShadowUV\",[t.ctx.uv,t.ctx.viewportSize,At(e.angle,t),At(e.distance,t)])}function GU(e){return t=>lre({at:e.at(t),uv:t.ctx.uv,viewportSize:t.ctx.viewportSize,blurRadius:At(e.blur,t),sample:s=>t.texture.sample(s),convertToTexture:t.convertToTexture})}function FU(e){return(t,s)=>{let r=e.coverage(s).mul(At(e.intensity,s));return W(ire,\"dropShadowComposite\",[t,At(e.color,s),r,$e(s.propValues[e.cutout.name]===1?1:0)])}}var rC={\"top-left\":{corner:[0,0],opposite:[1,1]},\"top-right\":{corner:[1,0],opposite:[0,1]},\"bottom-left\":{corner:[0,1],opposite:[1,0]},\"bottom-right\":{corner:[1,1],opposite:[0,0]}};function IU(e){return Cg(t=>{let s=t.propValues[e.shape.name]??0,r=s===0?16:8,o=s===0?4:3,a=s===2?1:0,i=wt(t).mul(-1);return ns(W(lte,\"flutedGlassGeom\",[t.ctx.uv,t.ctx.aspect,i,At(e.angle,t),At(e.frequency,t),At(e.softness,t),At(e.waveAmplitude,t),At(e.waveFrequency,t),At(e.refraction,t),At(e.aberration,t),ca(`vec3f(${fo(r)}, ${fo(o)}, ${fo(a)})`)]),\"flute\")})}function YU(e,t){return s=>{let r=s.propValues[t.edges.name]??2,o=(s.propValues[t.aberration.name]??.2)>0,a=e(s),i=c=>bte(d=>s.texture.sample(d),c,r),l=a.member(\"refractedUV\");return W(Yt,\"unpremultiplyAlpha\",[o?yte(i,l,a.member(\"chrOff\")):i(l)])}}function WU(e,t){return(s,r)=>{let o=W(cte,\"blinnHighlight\",[e(r).member(\"slope\"),At(t.lightAngle,r),At(t.highlight,r),At(t.softness,r)]).mul(s.member(\"a\"));return Ct(s.member(\"rgb\").add(At(t.color,r).member(\"rgb\").mul(o)),s.member(\"a\"))}}function qU(e){return Cg(t=>{let s=rC[t.propValues[e.corner.name]??\"bottom-right\"]??rC[\"bottom-right\"];return ns(W(dte,\"pagePeelGeom\",[t.ctx.uv,t.ctx.aspect,$e(s.corner[0]),$e(s.corner[1]),$e(s.opposite[0]),$e(s.opposite[1]),At(e.amount,t),At(e.radius,t)]),\"peel\")})}function VU(e,t){return s=>W(ute,\"curlShade\",[e(s).member(\"theta\"),At(t.shading,s)])}function NU(e,t){return s=>W(pte,\"curlSheen\",[e(s).member(\"theta\"),At(t.highlight,s),At(t.softness,s)])}function $U(e,t){return s=>{let r=e(s);return W(mte,\"overhangShade\",[r.member(\"distPastCrease\"),r.member(\"flatReach\"),At(t.amount,s),At(t.shadow,s)])}}function XU(e,t){return s=>{let r=e(s);return W(_te,\"revealShadow\",[r.member(\"distIntoPeel\"),r.member(\"peelReach\"),At(t.amount,s),At(t.shadow,s)])}}function HU(e,t){return s=>{let r=e(s);return W(fte,\"pagePeelCompose\",[s.texture.sample(r.member(\"curlUV\")),s.texture.sample(s.ctx.uv),t.shade(s),t.sheen(s),t.overhang(s),t.reveal(s),r.member(\"foldBlend\"),r.member(\"showCurl\")])}}var Jle=w.fn([m,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return m(t.x,__tsover_sub(__tsover_mul(s,2),t.y))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"lineY\"}],body:[0,[[10,[6,\"d.vec2f\",[[7,\"uv\",\"x\"],[1,[1,\"lineY\",\"*\",[5,\"2\"]],\"-\",[7,\"uv\",\"y\"]]]]]]]},externals:{\"d.vec2f\":()=>m}})&&e.f)({})),ece=w.fn([S,S,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=B(__tsover_sub(r,o),0),c=B(a,.001),d=B(__tsover_mul(c,i),1e-4),u=__tsover_sub(c,d),p=__tsover_sub(1,be(u,c,l)),_=__tsover_mul(s.w,p),f=__tsover_sub(1,_);return K(t,S(s.xyz.mul(p).add(t.xyz.mul(f)),__tsover_add(_,__tsover_mul(t.w,f))),S(Et(o,r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"original\"},{type:\"i\",name:\"refl\"},{type:\"i\",name:\"uvY\"},{type:\"i\",name:\"lineY\"},{type:\"i\",name:\"distance\"},{type:\"i\",name:\"falloff\"}],body:[0,[[13,\"distBelow\",[6,\"std.max\",[[1,\"uvY\",\"-\",\"lineY\"],[5,\"0\"]]]],[13,\"distanceMax\",[6,\"std.max\",[\"distance\",[5,\"0.001\"]]]],[13,\"fadeWidth\",[6,\"std.max\",[[1,\"distanceMax\",\"*\",\"falloff\"],[5,\"0.0001\"]]]],[13,\"fadeStart\",[1,\"distanceMax\",\"-\",\"fadeWidth\"]],[13,\"visibility\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"fadeStart\",\"distanceMax\",\"distBelow\"]]]],[13,\"effReflA\",[1,[7,\"refl\",\"w\"],\"*\",\"visibility\"]],[13,\"oneMinusReflA\",[1,[5,\"1\"],\"-\",\"effReflA\"]],[13,\"belowRgb\",[6,[7,[6,[7,[7,\"refl\",\"xyz\"],\"mul\"],[\"visibility\"]],\"add\"],[[6,[7,[7,\"original\",\"xyz\"],\"mul\"],[\"oneMinusReflA\"]]]]],[13,\"belowA\",[1,\"effReflA\",\"+\",[1,[7,\"original\",\"w\"],\"*\",\"oneMinusReflA\"]]],[13,\"belowLine\",[6,\"d.vec4f\",[\"belowRgb\",\"belowA\"]]],[13,\"isBelowLine\",[6,\"std.step\",[\"lineY\",\"uvY\"]]],[10,[6,\"std.mix\",[\"original\",\"belowLine\",[6,\"d.vec4f\",[\"isBelowLine\"]]]]]]]},externals:{\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S,\"std.step\":()=>Et,\"std.mix\":()=>K}})&&e.f)({})),oC=12;function tce(){return gt({height:n,blurAmount:n,blurDistance:n})}function sce(e,t){let s=tce(),r=(globalThis.__TYPEGPU_AUTONAME__??(o=>o))(w.bindGroupLayout({blurMap:{storageTexture:zt(ri,\"write-only\")},params:{uniform:s}}),\"layout\");return{layout:r,kernel:w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=r.$.params,c=__tsover_div(__tsover_add(n(i),.5),t),d=B(__tsover_sub(l.height,c),0),u=be(0,l.blurDistance,d),p=__tsover_mul(__tsover_mul(l.blurAmount,u),oC);lt(r.$.blurMap,fe(a,i),S(p,0,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"computeHeight\"]],[13,\"distBelowAtOutput\",[6,\"std.max\",[[1,[7,\"p\",\"height\"],\"-\",\"v\"],[5,\"0\"]]]],[13,\"ramp\",[6,\"std.smoothstep\",[[5,\"0\"],[7,\"p\",\"blurDistance\"],\"distBelowAtOutput\"]]],[13,\"radius\",[1,[1,[7,\"p\",\"blurAmount\"],\"*\",\"ramp\"],\"*\",\"DEPTH_RAMP_RADIUS_PX\"]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"blurMap\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"radius\",[5,\"0\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{layout:()=>r,\"d.f32\":()=>n,computeHeight:()=>t,\"std.max\":()=>B,\"std.smoothstep\":()=>be,DEPTH_RAMP_RADIUS_PX:()=>oC,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(\"depthRampFillBlurMap\"),Params:s}}function jU(e){return({ctx:t,uniforms:s})=>W(Jle,\"mirrorRowUV\",[t.uv,s[e.name]])}function KU(e){return{compute:t=>qu(t,{halfKernel:e.halfKernel,buildFill:sce,fillValues:()=>({height:t.getCpuValue(e.line.name)??.5,blurAmount:t.getCpuValue(e.blur.name)??1,blurDistance:Math.max(.01,t.getCpuValue(e.blurDistance.name)??.5)})})}}function QU(e,t,s,r){return o=>{let{ctx:a,uniforms:i,propValues:l}=o,c=l[e.edges.name]??0;return W(ece,\"planarReflectionCompose\",[t,Ha(r(o),s,c),a.uv.member(\"y\"),i[e.line.name],i[e.distance.name],i[e.falloff.name]])}}var rce=w.fn([S,S,S],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=r.w,a=G(s.xyz.mul(r.xyz).mul(o),A(0,0,0),A(1,1,1)),i=A(1,1,1),l=i.sub(i.sub(t.xyz).mul(i.sub(a))),c=__tsover_add(t.w,__tsover_mul(__tsover_mul(s.w,o),__tsover_sub(1,t.w)));return S(l.x,l.y,l.z,G(c,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"base\"},{type:\"i\",name:\"glow\"},{type:\"i\",name:\"tintStrength\"}],body:[0,[[13,\"strength\",[7,\"tintStrength\",\"w\"]],[13,\"bloomC\",[6,\"std.clamp\",[[6,[7,[6,[7,[7,\"glow\",\"xyz\"],\"mul\"],[[7,\"tintStrength\",\"xyz\"]]],\"mul\"],[\"strength\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[13,\"one\",[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]],[13,\"screened\",[6,[7,\"one\",\"sub\"],[[6,[7,[6,[7,\"one\",\"sub\"],[[7,\"base\",\"xyz\"]]],\"mul\"],[[6,[7,\"one\",\"sub\"],[\"bloomC\"]]]]]]],[13,\"a\",[1,[7,\"base\",\"w\"],\"+\",[1,[1,[7,\"glow\",\"w\"],\"*\",\"strength\"],\"*\",[1,[5,\"1\"],\"-\",[7,\"base\",\"w\"]]]]],[10,[6,\"d.vec4f\",[[7,\"screened\",\"x\"],[7,\"screened\",\"y\"],[7,\"screened\",\"z\"],[6,\"std.clamp\",[\"a\",[5,\"0\"],[5,\"1\"]]]]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"tintedScreenGlow\");function ZU(e){return{compute:t=>{let{getCpuValue:s}=t;return(s(e.strength.name)??0)===0?null:z4(t,{outputKey:e.output,buildExtract:(r,o)=>k4(r,o,e.extractName),threshold:()=>e.threshold,radius:()=>s(e.radius.name)??28})},screen:(t,s,r)=>{let o=r.computeOutputs?.[e.output];return W(rce,\"tintedScreenGlow\",[t,o?o.sample(s):ca(\"vec4f(0.0, 0.0, 0.0, 0.0)\"),Ct(e.tint[0],e.tint[1],e.tint[2],r.uniforms[e.strength.name])])}}}var oce=w.fn([m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(s,.006),a=__tsover_mul(__tsover_add(__tsover_mul(ae(__tsover_mul(r,1.7)),.5),__tsover_mul(ae(__tsover_add(__tsover_mul(r,.9),1.3)),.5)),o),i=__tsover_mul(__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(r,1.3),.7)),.5),__tsover_mul(ae(__tsover_mul(r,2.3)),.5)),o),l=__tsover_mul(__tsover_mul(ae(__tsover_mul(r,.6)),s),.004),c=pe(l),d=ae(l),u=t.sub(m(.5,.5)),p=__tsover_sub(__tsover_mul(u.x,c),__tsover_mul(u.y,d)),_=__tsover_add(__tsover_mul(u.x,d),__tsover_mul(u.y,c));return m(__tsover_add(__tsover_add(p,.5),a),__tsover_add(__tsover_add(_,.5),i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"amount\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"amp\",[1,\"amount\",\"*\",[5,\"0.006\"]]],[13,\"ox\",[1,[1,[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"1.7\"]]]],\"*\",[5,\"0.5\"]],\"+\",[1,[6,\"std.sin\",[[1,[1,\"t\",\"*\",[5,\"0.9\"]],\"+\",[5,\"1.3\"]]]],\"*\",[5,\"0.5\"]]],\"*\",\"amp\"]],[13,\"oy\",[1,[1,[1,[6,\"std.sin\",[[1,[1,\"t\",\"*\",[5,\"1.3\"]],\"+\",[5,\"0.7\"]]]],\"*\",[5,\"0.5\"]],\"+\",[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"2.3\"]]]],\"*\",[5,\"0.5\"]]],\"*\",\"amp\"]],[13,\"ang\",[1,[1,[6,\"std.sin\",[[1,\"t\",\"*\",[5,\"0.6\"]]]],\"*\",\"amount\"],\"*\",[5,\"0.004\"]]],[13,\"c\",[6,\"std.cos\",[\"ang\"]]],[13,\"s\",[6,\"std.sin\",[\"ang\"]]],[13,\"p\",[6,[7,\"uv\",\"sub\"],[[6,\"d.vec2f\",[[5,\"0.5\"],[5,\"0.5\"]]]]]],[13,\"rx\",[1,[1,[7,\"p\",\"x\"],\"*\",\"c\"],\"-\",[1,[7,\"p\",\"y\"],\"*\",\"s\"]]],[13,\"ry\",[1,[1,[7,\"p\",\"x\"],\"*\",\"s\"],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"c\"]]],[10,[6,\"d.vec2f\",[[1,[1,\"rx\",\"+\",[5,\"0.5\"]],\"+\",\"ox\"],[1,[1,\"ry\",\"+\",[5,\"0.5\"]],\"+\",\"oy\"]]]]]]},externals:{\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"d.vec2f\":()=>m}})&&e.f)({})).$name(\"swayUV\");function JU(e){return t=>{let s=0;return t.onBeforeRender(({deltaTime:r})=>{let o=t.getCpuValue(e.amount.name)??0;s+=r*(o>0?1:0),t.setExtraField(e.field,s)}),W(oce,\"swayUV\",[t.ctx.uv,t.uniforms[e.amount.name],t.uniforms[e.field]])}}var ace=bt,nce=\"rgba16float\";function aC(e,t,s){let r=\"\";return()=>{let o=t(e.shape.name)??\"blades\",a=t(e.blades.name)??6,i=`${o}|${a}`;i!==r&&(r=i,s.write(D4(o,a,100).map(l=>S(l.x,l.y,l.rim,0))))}}function e8(e){return{compute:t=>{let{childNode:s,gpu:r,convertToTexture:o,registerComputeTexture:a,getCpuValue:i,getMapInfo:l,onCleanup:c,onResize:d,dimensions:u}=t;if(!s)return null;let p=r?.root;if(!p)return null;let _=o(s),f=Math.max(1,Math.round(u.width)),h=Math.max(1,Math.round(u.height)),g=Math.max(Wh,640),y=h>0?f/h:1,b=Math.max(8,y>=1?g:Math.round(g*y)),x=Math.max(8,y>=1?Math.round(g/y):g),P=(globalThis.__TYPEGPU_AUTONAME__??(F=>F))(p.createTexture({size:[b,x],format:nce}).$usage(\"storage\",\"sampled\"),\"outputTex\");c(()=>P.destroy());let C=a(P);d(({width:F,height:q})=>{f=Math.max(1,Math.round(F)),h=Math.max(1,Math.round(q))});let E=()=>{let F=(i(e.rotation.name)??0)*ace;return{highlightGain:i(e.gain.name)??4,highlightThreshold:i(e.threshold.name)??.6,rotCos:Math.cos(F),rotSin:Math.sin(F),chromaticFringe:i(e.fringe.name)??.2,catEye:e.catEye?i(e.catEye.name)??0:0}},R=l(e.radius.name);if(R){let F=Wse(b,x,100,R.channel),q=(globalThis.__TYPEGPU_AUTONAME__??(Q=>Q))(p.createUniform(F.Params),\"kernelParams\"),Y=(globalThis.__TYPEGPU_AUTONAME__??(Q=>Q))(p.createUniform(F.TapArray),\"tapsUniform\"),V=aC({shape:e.shape,blades:e.blades},i,Y),X=wr(p,(Q=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(Q.f=((te,J)=>{\"use gpu\";F.kernel(te,J)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"graph.kernel\",[\"cx\",\"cy\"]]]]},externals:{\"graph.kernel\":()=>F.kernel}})&&Q.f)({}),{size:[b,x]});return{outputs:{blurredTexture:C},bindInputs:Q=>{let te=Q(_.key),J=Q(R.sourceTexture.key);if(!te||!J)return;let oe=p.createBindGroup(F.layout,{input:te.texture,source:J.texture,output:P,params:q.buffer,taps:Y.buffer});X=X.with(oe)},getComputeNodes:()=>{V();let Q=R.window();return q.write({...E(),inputWidth:f,inputHeight:h,inputMin:Q.inputMin,inputMax:Q.inputMax,outputMin:Q.outputMin,outputMax:Q.outputMax,curve:Q.curve}),[X]}}}let U=Yse(b,x,100),L=(globalThis.__TYPEGPU_AUTONAME__??(F=>F))(p.createUniform(U.Params),\"kernelParams\"),k=(globalThis.__TYPEGPU_AUTONAME__??(F=>F))(p.createUniform(U.TapArray),\"tapsUniform\"),D=aC({shape:e.shape,blades:e.blades},i,k),O=wr(p,(F=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(F.f=((q,Y)=>{\"use gpu\";U.kernel(q,Y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"graph.kernel\",[\"cx\",\"cy\"]]]]},externals:{\"graph.kernel\":()=>U.kernel}})&&F.f)({}),{size:[b,x]});return{outputs:{blurredTexture:C},bindInputs:F=>{let q=F(_.key);if(!q)return;let Y=p.createBindGroup(U.layout,{input:q.texture,output:P,params:L.buffer,taps:k.buffer});O=O.with(Y)},getComputeNodes:()=>{D();let F=i(e.radius.name)??50;return L.write({radius:Tse(F),...E(),inputWidth:f,inputHeight:h}),[O]}}},gpu:{fragment:({childNode:t,computeOutputs:s,ctx:r,convertToTexture:o})=>{if(!t)return xt;let a=s?.blurredTexture;return a?W(Yt,\"unpremultiplyAlpha\",[a.sample(r.uv)]):W(Yt,\"unpremultiplyAlpha\",[o(t).sample(r.uv)])}}}}function t8(e){return Bn(vee,\"hueRotate\",[e])}function s8(e){return Bn(hee,\"saturate\",[e])}function r8(e){return Bn(gee,\"vibrance\",[e])}function o8(e){return Bn(yee,\"brightnessContrast\",[e.brightness,e.contrast])}function a8(e){return Bn(bee,\"exposure\",[e])}function n8(){return Bn(xee,\"grayscale\",[])}function i8(){return Bn(Aee,\"invert\",[])}function l8(e){return Bn(wee,\"solarize\",[e.threshold,e.strength])}function c8(e){return Bn(Tee,\"posterize\",[e])}function d8(e){return{kind:\"pointwise\",body:t=>Number(t[e.preserveLuminosity.name])>0?{fn:Pee,hint:\"tintPreserveLuma\"}:{fn:See,hint:\"tintPlain\"},args:t=>[At(e.color,t),At(e.amount,t)]}}function u8(e){return{kind:\"pointwise\",body:{fn:Ree,hint:\"filmGrain\"},args:t=>[t.ctx.uv,t.ctx.viewportSize,At(e.strength,t),At(e.bias,t),t.uniforms.animTime],setup:t=>{let s=0;t.onBeforeRender(({deltaTime:r})=>{let o=t.getCpuValue(e.animated.name)>0?1:0;s+=r*o*10,t.setExtraField(\"animTime\",s)})}}}var ice=e=>typeof e==\"number\"?e:e===\"alpha\"?1:0,lce=e=>typeof e==\"number\"?e:e===\"custom\"?1:0;function p8(e){return{kind:\"pointwise\",body:t=>ice(t[e.source.name])===1?{fn:Lee,hint:\"isolinesFromAlpha\"}:{fn:Dee,hint:\"isolinesFromLuma\"},args:t=>[e.levels,e.lineWidth,e.softness,e.gamma,e.invert].map(s=>At(s,t)),compose:(t,s)=>{let r=lce(s.propValues[e.colorMode.name])===1;return W(Uee,\"contourCompose\",[r?me(e.backgroundColor,s):xt,r?me(e.lineColor,s):Ct(s.childNode.member(\"rgb\"),$e(1)),t])}}}function y2(e,t){return No[t.propValues[e.name]??0]??Ar}function m8(e){return Bn(Cee,\"duotoneT\",[e.blend],{compose:(t,s)=>Ct(W(y2(e.colorSpace,s),\"mixColors\",[me(e.colorA,s),me(e.colorB,s),t]).member(\"rgb\"),s.childNode.member(\"a\"))})}function _8(e){return Bn(Mee,\"tritoneFactors\",[e.blendMid],{compose:(t,s)=>{let r=t.member(\"x\"),o=t.member(\"y\"),a=t.member(\"z\"),i=y2(e.colorSpace,s),l=me(e.colorA,s),c=me(e.colorB,s),d=me(e.colorC,s);return Ct(W(i,\"mixColors\",[W(i,\"mixColors\",[l,c,r]),W(i,\"mixColors\",[c,d,o]),a]).member(\"rgb\"),s.childNode.member(\"a\"))}})}var nC={0:{a:[.5,.5,.5],b:[.5,.5,.5],c:[1,1,1],d:[0,.333,.667]},1:{a:[.5,.5,.5],b:[.5,.5,.5],c:[1,1,1],d:[0,.1,.2]},2:{a:[.5,.5,.5],b:[.5,.5,.5],c:[1,1,1],d:[.3,.2,.2]},3:{a:[.5,.5,.5],b:[.5,.5,.5],c:[1,1,1],d:[.8,.9,.3]},4:{a:[.5,.5,.5],b:[.25,.25,.25],c:[1,1,1],d:[0,.25,.5]},5:{a:[.5,.5,.5],b:[.5,.5,.5],c:[2,1,1],d:[.5,.2,.25]}},cce={rainbow:0,sunset:1,ocean:2,fire:3,pastel:4,neon:5,custom:6},A1=e=>ca(`vec3f(${fo(e[0])}, ${fo(e[1])}, ${fo(e[2])})`);function f8(e){return Bn(Eee,\"gradientMapT\",[e.blackPoint,e.whitePoint,e.contrast],{compose:(t,s)=>{let{childNode:r,propValues:o,ctx:a}=s,i=me(e.strength,s),l=me(e.speed,s).mul(a.time),c=cce[o[e.palette.name]??\"rainbow\"]??0;if(c!==6){let y=nC[c]??nC[0];return W(eS,\"gradientMapCompose\",[r,W(kee,\"gradientMapCosine\",[t,l,A1(y.a),A1(y.b),A1(y.c),A1(y.d)]),i])}let d=y2(e.colorSpace,s),u=W(Bee,\"gradientMapCustomPhase\",[t,l]),p=u.member(\"x\"),_=u.member(\"y\"),f=me(e.colorLow,s),h=me(e.colorMid,s),g=me(e.colorHigh,s);return W(eS,\"gradientMapCompose\",[r,W(zee,\"gradientMapSelect\",[W(d,\"mixColors\",[f,h,p]),W(d,\"mixColors\",[h,g,p]),W(d,\"mixColors\",[g,f,p]),_]).member(\"rgb\"),i])}})}function dce(e){let t=e-1,s=1/(e*e),r=1/e;return w.fn([S,n],m)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=Xm(G(a.xyz,A(0,0,0),A(1,1,1))),c=__tsover_mul(l.z,n(t)),d=G(__tsover_add(ie(c),i),n(0),n(t));return m(__tsover_mul(__tsover_add(__tsover_add(__tsover_mul(d,n(e)),.5),__tsover_mul(l.x,n(t))),n(s)),__tsover_mul(__tsover_add(.5,__tsover_mul(l.y,n(t))),n(r)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"hi\"}],body:[0,[[13,\"enc\",[6,\"tonemap.linearToSrgb\",[[6,\"std.clamp\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]]]],[13,\"slice\",[1,[7,\"enc\",\"z\"],\"*\",[6,\"d.f32\",[\"LUT_MAX\"]]]],[13,\"s\",[6,\"std.clamp\",[[1,[6,\"std.floor\",[\"slice\"]],\"+\",\"hi\"],[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[\"LUT_MAX\"]]]]],[13,\"u\",[1,[1,[1,[1,\"s\",\"*\",[6,\"d.f32\",[\"size\"]]],\"+\",[5,\"0.5\"]],\"+\",[1,[7,\"enc\",\"x\"],\"*\",[6,\"d.f32\",[\"LUT_MAX\"]]]],\"*\",[6,\"d.f32\",[\"INV_ATLAS_W\"]]]],[13,\"v\",[1,[1,[5,\"0.5\"],\"+\",[1,[7,\"enc\",\"y\"],\"*\",[6,\"d.f32\",[\"LUT_MAX\"]]]],\"*\",[6,\"d.f32\",[\"INV_LUT_N\"]]]],[10,[6,\"d.vec2f\",[\"u\",\"v\"]]]]]},externals:{\"tonemap.linearToSrgb\":()=>Xm,\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.f32\":()=>n,LUT_MAX:()=>t,\"std.floor\":()=>ie,size:()=>e,INV_ATLAS_W:()=>s,INV_LUT_N:()=>r,\"d.vec2f\":()=>m}})&&o.f)({})).$name(\"lutAtlasUv\")}function uce(e){let t=e-1;return w.fn([S,S,S,n],S)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o,a,i)=>{\"use gpu\";let l=Xm(G(r.xyz,A(0,0,0),A(1,1,1))),c=__tsover_mul(l.z,n(t)),d=__tsover_sub(c,ie(c)),u=Iu(K(o.xyz,a.xyz,A(d,d,d))),p=K(r.xyz,u,A(i,i,i));return S(p.x,p.y,p.z,r.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"color\"},{type:\"i\",name:\"tapLo\"},{type:\"i\",name:\"tapHi\"},{type:\"i\",name:\"strength\"}],body:[0,[[13,\"enc\",[6,\"tonemap.linearToSrgb\",[[6,\"std.clamp\",[[7,\"color\",\"xyz\"],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]]]],[13,\"slice\",[1,[7,\"enc\",\"z\"],\"*\",[6,\"d.f32\",[\"LUT_MAX\"]]]],[13,\"f\",[1,\"slice\",\"-\",[6,\"std.floor\",[\"slice\"]]]],[13,\"graded\",[6,\"tonemap.srgbToLinear\",[[6,\"std.mix\",[[7,\"tapLo\",\"xyz\"],[7,\"tapHi\",\"xyz\"],[6,\"d.vec3f\",[\"f\",\"f\",\"f\"]]]]]]],[13,\"rgb\",[6,\"std.mix\",[[7,\"color\",\"xyz\"],\"graded\",[6,\"d.vec3f\",[\"strength\",\"strength\",\"strength\"]]]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],[7,\"color\",\"w\"]]]]]]},externals:{\"tonemap.linearToSrgb\":()=>Xm,\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.f32\":()=>n,LUT_MAX:()=>t,\"std.floor\":()=>ie,\"tonemap.srgbToLinear\":()=>Iu,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&s.f)({})).$name(\"lutAtlasApply\")}var iC=new Map;function pce(e){let t=iC.get(e);return t||(t={uv:dce(e),apply:uce(e)},iC.set(e,t)),t}function v8(e){let t=pce(e.size);return(s,r)=>{let{propValues:o,uniforms:a,createDataTexture:i,registerMediaTexture:l,onCleanup:c}=r,d=o[e.select.name]??e.fallback,u=i({width:e.size*e.size,height:e.size,format:\"rgba8unorm\",data:e.decode(d),label:`${e.label}-${d}`});c(()=>u.destroy());let p=l(()=>u.texture),_=p.sample(W(t.uv,\"lutAtlasUvLo\",[s,$e(0)]),\"linearClamp\"),f=p.sample(W(t.uv,\"lutAtlasUvHi\",[s,$e(1)]),\"linearClamp\");return W(t.apply,\"lutAtlasApply\",[s,_,f,a[e.strength.name]])}}var Gm=Po,lC=.35,h8=w.fn([n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=__tsover_mul(.18,t),r=vt(re(ae(__tsover_mul(s,Gm))),10),o=vt(re(ae(__tsover_mul(__tsover_sub(s,.15),Gm))),10);return G(__tsover_add(r,__tsover_mul(.6,o)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"animTime\"}],body:[0,[[13,\"time\",[1,[5,\"0.18\"],\"*\",\"animTime\"]],[13,\"first\",[6,\"std.pow\",[[6,\"std.abs\",[[6,\"std.sin\",[[1,\"time\",\"*\",\"TWO_PI\"]]]]],[5,\"10\"]]]],[13,\"second\",[6,\"std.pow\",[[6,\"std.abs\",[[6,\"std.sin\",[[1,[1,\"time\",\"-\",[5,\"0.15\"]],\"*\",\"TWO_PI\"]]]]],[5,\"10\"]]]],[10,[6,\"std.clamp\",[[1,\"first\",\"+\",[1,[5,\"0.6\"],\"*\",\"second\"]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.pow\":()=>vt,\"std.abs\":()=>re,\"std.sin\":()=>ae,TWO_PI:()=>Gm,\"std.clamp\":()=>G}})&&e.f)({})),g8=w.fn([n,m,m,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=__tsover_add(__tsover_mul(d,1.2),131),f=B(__tsover_mul(__tsover_mul(.5,a),lC),.002),h=re(__tsover_add(__tsover_div(t,B(o,.001)),K(f,n(0),i))),g=K(f,__tsover_mul(3,f),i),y=__tsover_div(2,__tsover_mul(r.y,B(o,.001))),b=ye(K(g,__tsover_mul(g,-1),i),__tsover_add(g,y)),x=B(K(g,__tsover_mul(g,-1),i),__tsover_add(g,y)),P=__tsover_sub(1,be(b,x,h));P=vt(G(P,0,1),__tsover_add(1,i));let C=m(__tsover_sub(s.x,.5),__tsover_sub(s.y,.5)).mul(__tsover_add(.5,__tsover_mul(2.5,l))),E=__tsover_mul(.5,_),R=Aa(m(__tsover_add(__tsover_mul(C.x,2.7),E),__tsover_add(__tsover_mul(C.y,2.7),E))),U=Aa(m(__tsover_sub(__tsover_mul(C.x,3.4),E),__tsover_sub(__tsover_mul(C.y,3.4),E))),L=__tsover_sub(G(__tsover_mul(3,R),0,1),U),k=G(__tsover_add(f,.2),.1,.4),D=vt(G(__tsover_sub(1,be(__tsover_mul(k,-1),__tsover_add(k,y),h)),0,1),2);L=__tsover_mul(L,D),L=__tsover_mul(__tsover_mul(__tsover_mul(30,L),L),__tsover_mul(__tsover_mul(.5,c),c)),L=__tsover_mul(L,K(n(1),p,u)),P=G(__tsover_add(P,G(L,0,1)),0,1);let O=__tsover_div(Xt(__tsover_sub(s.y,.5),__tsover_sub(s.x,.5)),Gm);return m(P,O)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fieldRaw\"},{type:\"i\",name:\"sdfUV\"},{type:\"i\",name:\"viewport\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"smokeSize\"},{type:\"i\",name:\"smokeAmt\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"pulse\"},{type:\"i\",name:\"beat\"}],body:[0,[[13,\"t\",[1,[1,\"animTime\",\"*\",[5,\"1.2\"]],\"+\",[5,\"131\"]]],[13,\"th\",[6,\"std.max\",[[1,[1,[5,\"0.5\"],\"*\",\"thickness\"],\"*\",\"BAND_THICKNESS_REF\"],[5,\"0.002\"]]]],[13,\"f\",[1,[1,\"fieldRaw\",\"/\",[6,\"std.max\",[\"scale\",[5,\"0.001\"]]]],\"+\",[6,\"std.mix\",[\"th\",[6,\"d.f32\",[[5,\"0\"]]],\"softness\"]]]],[13,\"bd\",[6,\"std.abs\",[\"f\"]]],[13,\"borderTh\",[6,\"std.mix\",[\"th\",[1,[5,\"3\"],\"*\",\"th\"],\"softness\"]]],[13,\"aa\",[1,[5,\"2\"],\"/\",[1,[7,\"viewport\",\"y\"],\"*\",[6,\"std.max\",[\"scale\",[5,\"0.001\"]]]]]],[13,\"e0\",[6,\"std.min\",[[6,\"std.mix\",[\"borderTh\",[1,\"borderTh\",\"*\",[4,\"-\",[5,\"1\"]]],\"softness\"]],[1,\"borderTh\",\"+\",\"aa\"]]]],[13,\"e1\",[6,\"std.max\",[[6,\"std.mix\",[\"borderTh\",[1,\"borderTh\",\"*\",[4,\"-\",[5,\"1\"]]],\"softness\"]],[1,\"borderTh\",\"+\",\"aa\"]]]],[12,\"border\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[\"e0\",\"e1\",\"bd\"]]]],[2,\"border\",\"=\",[6,\"std.pow\",[[6,\"std.clamp\",[\"border\",[5,\"0\"],[5,\"1\"]]],[1,[5,\"1\"],\"+\",\"softness\"]]]],[13,\"suv\",[6,[7,[6,\"d.vec2f\",[[1,[7,\"sdfUV\",\"x\"],\"-\",[5,\"0.5\"]],[1,[7,\"sdfUV\",\"y\"],\"-\",[5,\"0.5\"]]]],\"mul\"],[[1,[5,\"0.5\"],\"+\",[1,[5,\"2.5\"],\"*\",\"smokeSize\"]]]]],[13,\"drift\",[1,[5,\"0.5\"],\"*\",\"t\"]],[13,\"n1\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,[7,\"suv\",\"x\"],\"*\",[5,\"2.7\"]],\"+\",\"drift\"],[1,[1,[7,\"suv\",\"y\"],\"*\",[5,\"2.7\"]],\"+\",\"drift\"]]]]]],[13,\"n2\",[6,\"noise.value12\",[[6,\"d.vec2f\",[[1,[1,[7,\"suv\",\"x\"],\"*\",[5,\"3.4\"]],\"-\",\"drift\"],[1,[1,[7,\"suv\",\"y\"],\"*\",[5,\"3.4\"]],\"-\",\"drift\"]]]]]],[12,\"smoke\",[1,[6,\"std.clamp\",[[1,[5,\"3\"],\"*\",\"n1\"],[5,\"0\"],[5,\"1\"]]],\"-\",\"n2\"]],[13,\"smokeTh\",[6,\"std.clamp\",[[1,\"th\",\"+\",[5,\"0.2\"]],[5,\"0.1\"],[5,\"0.4\"]]]],[13,\"smokeBand\",[6,\"std.pow\",[[6,\"std.clamp\",[[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[1,\"smokeTh\",\"*\",[4,\"-\",[5,\"1\"]]],[1,\"smokeTh\",\"+\",\"aa\"],\"bd\"]]],[5,\"0\"],[5,\"1\"]]],[5,\"2\"]]]],[2,\"smoke\",\"=\",[1,\"smoke\",\"*\",\"smokeBand\"]],[2,\"smoke\",\"=\",[1,[1,[1,[5,\"30\"],\"*\",\"smoke\"],\"*\",\"smoke\"],\"*\",[1,[1,[5,\"0.5\"],\"*\",\"smokeAmt\"],\"*\",\"smokeAmt\"]]],[2,\"smoke\",\"=\",[1,\"smoke\",\"*\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],\"beat\",\"pulse\"]]]],[2,\"border\",\"=\",[6,\"std.clamp\",[[1,\"border\",\"+\",[6,\"std.clamp\",[\"smoke\",[5,\"0\"],[5,\"1\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"angle01\",[1,[6,\"std.atan2\",[[1,[7,\"sdfUV\",\"y\"],\"-\",[5,\"0.5\"]],[1,[7,\"sdfUV\",\"x\"],\"-\",[5,\"0.5\"]]]],\"/\",\"TWO_PI\"]],[10,[6,\"d.vec2f\",[\"border\",\"angle01\"]]]]]},externals:{\"std.max\":()=>B,BAND_THICKNESS_REF:()=>lC,\"std.mix\":()=>K,\"d.f32\":()=>n,\"std.abs\":()=>re,\"std.min\":()=>ye,\"std.smoothstep\":()=>be,\"std.pow\":()=>vt,\"std.clamp\":()=>G,\"d.vec2f\":()=>m,\"noise.value12\":()=>Aa,\"std.atan2\":()=>Xt,TWO_PI:()=>Gm}})&&e.f)({})),y8=w.fn([n,n,n,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p)=>{\"use gpu\";let _=__tsover_add(__tsover_mul(r,1.2),131),f=__tsover_add(1,__tsover_mul(__tsover_add(1,__tsover_mul(4,d)),c)),h=n(0),g=n(0);for(let y=0;y<5;y++){let b=n(y),x=N(n(0),n(1),b<a),P=Pr(m(__tsover_add(__tsover_add(__tsover_mul(b,10),2),__tsover_mul(u,7.31)),__tsover_add(__tsover_add(40,p),__tsover_mul(u,3.17)))),C=__tsover_add(.1,__tsover_mul(.15,re(__tsover_mul(ae(__tsover_mul(b,__tsover_add(2,p))),pe(__tsover_mul(b,__tsover_add(2,__tsover_mul(2.5,p)))))))),E=N(n(1),n(-1),P.y<.5),R=__tsover_mul(__tsover_add(__tsover_mul(C,_),__tsover_mul(P.x,3)),E),U=re(__tsover_sub(p,__tsover_mul(2,ie(__tsover_mul(p,.5)))))<.5,L=ae(__tsover_add(_,__tsover_mul(b,__tsover_sub(5,__tsover_mul(1.5,p))))),k=pe(__tsover_add(_,__tsover_mul(b,__tsover_add(3,__tsover_mul(1.3,p))))),D=__tsover_add(.5,__tsover_mul(.5,N(k,L,U))),O=G(__tsover_sub(__tsover_mul(2,l),P.x),0,1);D=K(D,o,O);let F=Re(__tsover_add(t,R)),q=__tsover_add(__tsover_add(.05,__tsover_mul(__tsover_mul(.6,i),i)),__tsover_mul(.05,P.x));q=K(q,.1,O);let Y=__tsover_mul(be(__tsover_sub(.5,q),.5,F),__tsover_sub(1,be(.5,__tsover_add(.5,q),F)));Y=__tsover_mul(G(__tsover_mul(__tsover_mul(__tsover_mul(Y,D),s),f),0,1),x),h=__tsover_add(h,__tsover_mul(__tsover_sub(1,h),Y)),g=__tsover_add(g,Y)}return m(h,g)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"angle01\"},{type:\"i\",name:\"border\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"beat\"},{type:\"i\",name:\"spotsF\"},{type:\"i\",name:\"spotSize\"},{type:\"i\",name:\"pulse\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"softness\"},{type:\"i\",name:\"seed\"},{type:\"i\",name:\"colorIdxF\"}],body:[0,[[13,\"t\",[1,[1,\"animTime\",\"*\",[5,\"1.2\"]],\"+\",[5,\"131\"]]],[13,\"intensityEff\",[1,[5,\"1\"],\"+\",[1,[1,[5,\"1\"],\"+\",[1,[5,\"4\"],\"*\",\"softness\"]],\"*\",\"intensity\"]]],[12,\"overAcc\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"addAcc\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"s\",[5,\"0\"]],[1,\"s\",\"<\",[5,\"5\"]],[102,\"++\",\"s\"],[0,[[13,\"sF\",[6,\"d.f32\",[\"s\"]]],[13,\"gate\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"sF\",\"<\",\"spotsF\"]]]],[13,\"randVal\",[6,\"noise.hash22\",[[6,\"d.vec2f\",[[1,[1,[1,\"sF\",\"*\",[5,\"10\"]],\"+\",[5,\"2\"]],\"+\",[1,\"seed\",\"*\",[5,\"7.31\"]]],[1,[1,[5,\"40\"],\"+\",\"colorIdxF\"],\"+\",[1,\"seed\",\"*\",[5,\"3.17\"]]]]]]]],[13,\"speedFactor\",[1,[5,\"0.1\"],\"+\",[1,[5,\"0.15\"],\"*\",[6,\"std.abs\",[[1,[6,\"std.sin\",[[1,\"sF\",\"*\",[1,[5,\"2\"],\"+\",\"colorIdxF\"]]]],\"*\",[6,\"std.cos\",[[1,\"sF\",\"*\",[1,[5,\"2\"],\"+\",[1,[5,\"2.5\"],\"*\",\"colorIdxF\"]]]]]]]]]]],[13,\"dir\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[1,[7,\"randVal\",\"y\"],\"<\",[5,\"0.5\"]]]]],[13,\"sTime\",[1,[1,[1,\"speedFactor\",\"*\",\"t\"],\"+\",[1,[7,\"randVal\",\"x\"],\"*\",[5,\"3\"]]],\"*\",\"dir\"]],[13,\"evenCond\",[1,[6,\"std.abs\",[[1,\"colorIdxF\",\"-\",[1,[5,\"2\"],\"*\",[6,\"std.floor\",[[1,\"colorIdxF\",\"*\",[5,\"0.5\"]]]]]]]],\"<\",[5,\"0.5\"]]],[13,\"sinVal\",[6,\"std.sin\",[[1,\"t\",\"+\",[1,\"sF\",\"*\",[1,[5,\"5\"],\"-\",[1,[5,\"1.5\"],\"*\",\"colorIdxF\"]]]]]]],[13,\"cosVal\",[6,\"std.cos\",[[1,\"t\",\"+\",[1,\"sF\",\"*\",[1,[5,\"3\"],\"+\",[1,[5,\"1.3\"],\"*\",\"colorIdxF\"]]]]]]],[12,\"mask\",[1,[5,\"0.5\"],\"+\",[1,[5,\"0.5\"],\"*\",[6,\"std.select\",[\"cosVal\",\"sinVal\",\"evenCond\"]]]]],[13,\"pWeight\",[6,\"std.clamp\",[[1,[1,[5,\"2\"],\"*\",\"pulse\"],\"-\",[7,\"randVal\",\"x\"]],[5,\"0\"],[5,\"1\"]]]],[2,\"mask\",\"=\",[6,\"std.mix\",[\"mask\",\"beat\",\"pWeight\"]]],[13,\"atg\",[6,\"std.fract\",[[1,\"angle01\",\"+\",\"sTime\"]]]],[12,\"ss\",[1,[1,[5,\"0.05\"],\"+\",[1,[1,[5,\"0.6\"],\"*\",\"spotSize\"],\"*\",\"spotSize\"]],\"+\",[1,[5,\"0.05\"],\"*\",[7,\"randVal\",\"x\"]]]],[2,\"ss\",\"=\",[6,\"std.mix\",[\"ss\",[5,\"0.1\"],\"pWeight\"]]],[12,\"sector\",[1,[6,\"std.smoothstep\",[[1,[5,\"0.5\"],\"-\",\"ss\"],[5,\"0.5\"],\"atg\"]],\"*\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0.5\"],[1,[5,\"0.5\"],\"+\",\"ss\"],\"atg\"]]]]],[2,\"sector\",\"=\",[1,[6,\"std.clamp\",[[1,[1,[1,\"sector\",\"*\",\"mask\"],\"*\",\"border\"],\"*\",\"intensityEff\"],[5,\"0\"],[5,\"1\"]]],\"*\",\"gate\"]],[2,\"overAcc\",\"=\",[1,\"overAcc\",\"+\",[1,[1,[5,\"1\"],\"-\",\"overAcc\"],\"*\",\"sector\"]]],[2,\"addAcc\",\"=\",[1,\"addAcc\",\"+\",\"sector\"]]]]],[10,[6,\"d.vec2f\",[\"overAcc\",\"addAcc\"]]]]]},externals:{\"d.f32\":()=>n,\"std.select\":()=>N,\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.sin\":()=>ae,\"std.cos\":()=>pe,\"std.floor\":()=>ie,\"std.clamp\":()=>G,\"std.mix\":()=>K,\"std.fract\":()=>Re,\"std.smoothstep\":()=>be}})&&e.f)({})),Ql=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({rgb:A,w:n,ba:n,ac:A,aa:n}),\"EdgeGlowAccum\"),b8=w.fn([],Ql)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(()=>{\"use gpu\";return Ql({rgb:A(0,0,0),w:n(0),ba:n(0),ac:A(0,0,0),aa:n(0)})}),{v:2,name:void 0,ast:{params:[],body:[0,[[10,[6,\"EdgeGlowAccum\",[[104,{rgb:[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],w:[6,\"d.f32\",[[5,\"0\"]]],ba:[6,\"d.f32\",[[5,\"0\"]]],ac:[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],aa:[6,\"d.f32\",[[5,\"0\"]]]}]]]]]]},externals:{EdgeGlowAccum:()=>Ql,\"d.vec3f\":()=>A,\"d.f32\":()=>n}})&&e.f)({})),cC=new Map;function mce(e){let t=No[e]??Ar;return w.fn([Ql,S,m],Ql)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=((r,o,a)=>{\"use gpu\";let i=__tsover_mul(o.w,a.x),l=__tsover_div(i,B(__tsover_add(r.w,i),1e-5)),c=t(S(r.rgb,1),S(o.xyz,1),l),d=__tsover_add(r.ba,__tsover_mul(__tsover_sub(1,r.ba),i)),u=r.ac.add(o.xyz.mul(__tsover_mul(o.w,a.y))),p=__tsover_add(r.aa,__tsover_mul(o.w,a.y));return Ql({rgb:c.xyz,w:__tsover_add(r.w,i),ba:d,ac:u,aa:p})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"st\"},{type:\"i\",name:\"color\"},{type:\"i\",name:\"sectors\"}],body:[0,[[13,\"wNew\",[1,[7,\"color\",\"w\"],\"*\",[7,\"sectors\",\"x\"]]],[13,\"t\",[1,\"wNew\",\"/\",[6,\"std.max\",[[1,[7,\"st\",\"w\"],\"+\",\"wNew\"],[5,\"0.00001\"]]]]],[13,\"mixed\",[6,\"variant\",[[6,\"d.vec4f\",[[7,\"st\",\"rgb\"],[5,\"1\"]]],[6,\"d.vec4f\",[[7,\"color\",\"xyz\"],[5,\"1\"]]],\"t\"]]],[13,\"ba\",[1,[7,\"st\",\"ba\"],\"+\",[1,[1,[5,\"1\"],\"-\",[7,\"st\",\"ba\"]],\"*\",\"wNew\"]]],[13,\"ac\",[6,[7,[7,\"st\",\"ac\"],\"add\"],[[6,[7,[7,\"color\",\"xyz\"],\"mul\"],[[1,[7,\"color\",\"w\"],\"*\",[7,\"sectors\",\"y\"]]]]]]],[13,\"aa\",[1,[7,\"st\",\"aa\"],\"+\",[1,[7,\"color\",\"w\"],\"*\",[7,\"sectors\",\"y\"]]]],[10,[6,\"EdgeGlowAccum\",[[104,{rgb:[7,\"mixed\",\"xyz\"],w:[1,[7,\"st\",\"w\"],\"+\",\"wNew\"],ba:\"ba\",ac:\"ac\",aa:\"aa\"}]]]]]]},externals:{\"std.max\":()=>B,variant:()=>t,\"d.vec4f\":()=>S,EdgeGlowAccum:()=>Ql}})&&s.f)({})).$name(`edgeGlowAccumColor_${e}`)}function x8(e){let t=cC.get(e);return t||(t=mce(e),cC.set(e,t)),t}var A8=w.fn([Fe(S,8),n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=t[j(s)];return S(r.x,r.y,r.z,r.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"colors\"},{type:\"i\",name:\"idx\"}],body:[0,[[13,\"c\",[8,\"colors\",[6,\"d.i32\",[\"idx\"]]]],[10,[6,\"d.vec4f\",[[7,\"c\",\"x\"],[7,\"c\",\"y\"],[7,\"c\",\"z\"],[7,\"c\",\"w\"]]]]]]},externals:{\"d.i32\":()=>j,\"d.vec4f\":()=>S}})&&e.f)({})),w8=w.fn([Ql,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_mul(s,4),o=K(t.rgb.mul(t.ba),t.ac,A(r)),a=G(K(t.ba,t.aa,r),0,1);return S(G(o.div(B(a,1e-4)),A(0),A(1)),a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"st\"},{type:\"i\",name:\"bloom\"}],body:[0,[[13,\"k\",[1,\"bloom\",\"*\",[5,\"4\"]]],[13,\"blendPremult\",[6,[7,[7,\"st\",\"rgb\"],\"mul\"],[[7,\"st\",\"ba\"]]]],[13,\"accumC\",[6,\"std.mix\",[\"blendPremult\",[7,\"st\",\"ac\"],[6,\"d.vec3f\",[\"k\"]]]]],[13,\"accumA\",[6,\"std.clamp\",[[6,\"std.mix\",[[7,\"st\",\"ba\"],[7,\"st\",\"aa\"],\"k\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"straight\",[6,\"std.clamp\",[[6,[7,\"accumC\",\"div\"],[[6,\"std.max\",[\"accumA\",[5,\"0.0001\"]]]]],[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[10,[6,\"d.vec4f\",[\"straight\",\"accumA\"]]]]]},externals:{\"std.mix\":()=>K,\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&e.f)({}));var T8=\"rgba16float\";function _ce(e,t){let s=(globalThis.__TYPEGPU_AUTONAME__??(r=>r))(w.bindGroupLayout({cellPos:{storage:Fe(n,e*2),access:\"readonly\"},voronoiTex:{storageTexture:zt(T8,\"write-only\")}}),\"layout\");return{layout:s,kernel:w.fn([M,M])((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a)=>{\"use gpu\";let i=__tsover_div(__tsover_add(n(o),.5),t),l=__tsover_div(__tsover_add(n(a),.5),t),c=n(99999),d=n(99999),u=n(0),p=n(0);for(let _=0;_<e;_++){let f=s.$.cellPos[__tsover_mul(_,2)],h=s.$.cellPos[__tsover_add(__tsover_mul(_,2),1)],g=__tsover_sub(i,f),y=__tsover_sub(l,h),b=__tsover_add(__tsover_mul(g,g),__tsover_mul(y,y));b<c?(d=c,p=u,c=b,u=n(_)):b<d&&(d=b,p=n(_))}lt(s.$.voronoiTex,fe(o,a),S(u,p,0,0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"u\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",\"size\"]],[13,\"v\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",\"size\"]],[12,\"d1\",[6,\"d.f32\",[[5,\"99999\"]]]],[12,\"d2\",[6,\"d.f32\",[[5,\"99999\"]]]],[12,\"idx1\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"idx2\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"count\"],[102,\"++\",\"i\"],[0,[[13,\"cellX\",[8,[7,[7,\"layout\",\"$\"],\"cellPos\"],[1,\"i\",\"*\",[5,\"2\"]]]],[13,\"cellY\",[8,[7,[7,\"layout\",\"$\"],\"cellPos\"],[1,[1,\"i\",\"*\",[5,\"2\"]],\"+\",[5,\"1\"]]]],[13,\"ddx\",[1,\"u\",\"-\",\"cellX\"]],[13,\"ddy\",[1,\"v\",\"-\",\"cellY\"]],[13,\"distSq\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]],[11,[1,\"distSq\",\"<\",\"d1\"],[0,[[2,\"d2\",\"=\",\"d1\"],[2,\"idx2\",\"=\",\"idx1\"],[2,\"d1\",\"=\",\"distSq\"],[2,\"idx1\",\"=\",[6,\"d.f32\",[\"i\"]]]]],[0,[[11,[1,\"distSq\",\"<\",\"d2\"],[0,[[2,\"d2\",\"=\",\"distSq\"],[2,\"idx2\",\"=\",[6,\"d.f32\",[\"i\"]]]]]]]]]]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"voronoiTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[\"idx1\",\"idx2\",[5,\"0\"],[5,\"0\"]]]]]]]},externals:{\"d.f32\":()=>n,size:()=>t,count:()=>e,layout:()=>s,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&r.f)({})).$name(\"voronoiNearest2\")}}var dC=new Map;function fce(e,t){let s=`${e}|${t}`,r=dC.get(s);return r||(r=_ce(e,t),dC.set(s,r)),r}var uC=new Map;function vce(e){return w.fn([n,n],m)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r)=>{\"use gpu\";return m(__tsover_div(__tsover_add(__tsover_add(__tsover_mul(s,4),r),.5),e),.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"idx\"},{type:\"i\",name:\"field\"}],body:[0,[[10,[6,\"d.vec2f\",[[1,[1,[1,[1,\"idx\",\"*\",[5,\"4\"]],\"+\",\"field\"],\"+\",[5,\"0.5\"]],\"/\",\"laneWidth\"],[5,\"0.5\"]]]]]]},externals:{\"d.vec2f\":()=>m,laneWidth:()=>e}})&&t.f)({}))}function S8(e){let t=uC.get(e);return t||(t=vce(e),uC.set(e,t)),t}var J0=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({crackIntensity:n,edgeNormal:m,displacedUV:m,disp:m}),\"CrackGeom\"),P8=w.fn([m,n,n,n,n,n,n,n],J0)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let d=m(s,r),u=m(o,a),p=m(i,l),_=t.sub(d),f=he(_),h=he(t.sub(u)),g=he(p),y=__tsover_sub(h,f),b=__tsover_mul(c,.005),x=__tsover_sub(1,be(0,b,y)),P=be(0,.01,g),C=__tsover_mul(x,P),E=_.div(B(f,1e-5));return J0({crackIntensity:C,edgeNormal:m(__tsover_mul(E.y,-1),E.x),displacedUV:t.sub(p),disp:p})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"nPosX\"},{type:\"i\",name:\"nPosY\"},{type:\"i\",name:\"sPosX\"},{type:\"i\",name:\"sPosY\"},{type:\"i\",name:\"dispX\"},{type:\"i\",name:\"dispY\"},{type:\"i\",name:\"crackWidth\"}],body:[0,[[13,\"nearestPos\",[6,\"d.vec2f\",[\"nPosX\",\"nPosY\"]]],[13,\"secondPos\",[6,\"d.vec2f\",[\"sPosX\",\"sPosY\"]]],[13,\"disp\",[6,\"d.vec2f\",[\"dispX\",\"dispY\"]]],[13,\"fromNearest\",[6,[7,\"uv\",\"sub\"],[\"nearestPos\"]]],[13,\"minDist1\",[6,\"std.length\",[\"fromNearest\"]]],[13,\"minDist2\",[6,\"std.length\",[[6,[7,\"uv\",\"sub\"],[\"secondPos\"]]]]],[13,\"displacementMag\",[6,\"std.length\",[\"disp\"]]],[13,\"edgeDiff\",[1,\"minDist2\",\"-\",\"minDist1\"]],[13,\"crackThreshold\",[1,\"crackWidth\",\"*\",[5,\"0.005\"]]],[13,\"baseCrackIntensity\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[5,\"0\"],\"crackThreshold\",\"edgeDiff\"]]]],[13,\"displacementFactor\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.01\"],\"displacementMag\"]]],[13,\"crackIntensity\",[1,\"baseCrackIntensity\",\"*\",\"displacementFactor\"]],[13,\"toNearest\",[6,[7,\"fromNearest\",\"div\"],[[6,\"std.max\",[\"minDist1\",[5,\"0.00001\"]]]]]],[13,\"edgeNormal\",[6,\"d.vec2f\",[[1,[7,\"toNearest\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],[7,\"toNearest\",\"x\"]]]],[13,\"displacedUV\",[6,[7,\"uv\",\"sub\"],[\"disp\"]]],[10,[6,\"CrackGeom\",[[104,{crackIntensity:\"crackIntensity\",edgeNormal:\"edgeNormal\",displacedUV:\"displacedUV\",disp:\"disp\"}]]]]]]},externals:{\"d.vec2f\":()=>m,\"std.length\":()=>he,\"std.smoothstep\":()=>be,\"std.max\":()=>B,CrackGeom:()=>J0}})&&e.f)({})),C8=w.fn([m,m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=s.mul(__tsover_mul(o,.01)),c=__tsover_mul(a,.005),d=s.mul(__tsover_mul(i,c)),u=l.add(d);return t.add(u.mul(r))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"displacedUV\"},{type:\"i\",name:\"edgeNormal\"},{type:\"i\",name:\"crackIntensity\"},{type:\"i\",name:\"refractionStrength\"},{type:\"i\",name:\"chromaticSplit\"},{type:\"i\",name:\"channel\"}],body:[0,[[13,\"refractionOffset\",[6,[7,\"edgeNormal\",\"mul\"],[[1,\"refractionStrength\",\"*\",[5,\"0.01\"]]]]],[13,\"chromaticOffset\",[1,\"chromaticSplit\",\"*\",[5,\"0.005\"]]],[13,\"chromaShift\",[6,[7,\"edgeNormal\",\"mul\"],[[1,\"channel\",\"*\",\"chromaticOffset\"]]]],[13,\"offset\",[6,[7,\"refractionOffset\",\"add\"],[\"chromaShift\"]]],[10,[6,[7,\"displacedUV\",\"add\"],[[6,[7,\"offset\",\"mul\"],[\"crackIntensity\"]]]]]]]},externals:{}})&&e.f)({})),pC=.3/Math.hypot(.3,.6),mC=.6/Math.hypot(.3,.6),M8=w.fn([S,S,S,S,n,m,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=A(s.x,r.y,o.z),d=t.xyz.mul(__tsover_sub(1,a)).add(c.mul(a)),u=he(i),p=__tsover_div(i.x,__tsover_add(u,.001)),_=__tsover_div(i.y,__tsover_add(u,.001)),f=__tsover_add(__tsover_mul(p,pC),__tsover_mul(_,mC)),h=__tsover_add(1,__tsover_mul(f,l)),g=be(0,.02,u),y=__tsover_add(1,__tsover_mul(__tsover_sub(h,1),g));return S(d.mul(y),t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"normalColor\"},{type:\"i\",name:\"rFinal\"},{type:\"i\",name:\"gFinal\"},{type:\"i\",name:\"bFinal\"},{type:\"i\",name:\"crackIntensity\"},{type:\"i\",name:\"disp\"},{type:\"i\",name:\"shardLighting\"}],body:[0,[[13,\"refractedRGB\",[6,\"d.vec3f\",[[7,\"rFinal\",\"x\"],[7,\"gFinal\",\"y\"],[7,\"bFinal\",\"z\"]]]],[13,\"shadedRGB\",[6,[7,[6,[7,[7,\"normalColor\",\"xyz\"],\"mul\"],[[1,[5,\"1\"],\"-\",\"crackIntensity\"]]],\"add\"],[[6,[7,\"refractedRGB\",\"mul\"],[\"crackIntensity\"]]]]],[13,\"displacementLength\",[6,\"std.length\",[\"disp\"]]],[13,\"tiltX\",[1,[7,\"disp\",\"x\"],\"/\",[1,\"displacementLength\",\"+\",[5,\"0.001\"]]]],[13,\"tiltY\",[1,[7,\"disp\",\"y\"],\"/\",[1,\"displacementLength\",\"+\",[5,\"0.001\"]]]],[13,\"normalDot\",[1,[1,\"tiltX\",\"*\",\"SHARD_LIGHT_DIR_X\"],\"+\",[1,\"tiltY\",\"*\",\"SHARD_LIGHT_DIR_Y\"]]],[13,\"lightingFactor\",[1,[5,\"1\"],\"+\",[1,\"normalDot\",\"*\",\"shardLighting\"]]],[13,\"lightingIntensity\",[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.02\"],\"displacementLength\"]]],[13,\"finalLighting\",[1,[5,\"1\"],\"+\",[1,[1,\"lightingFactor\",\"-\",[5,\"1\"]],\"*\",\"lightingIntensity\"]]],[13,\"finalRGB\",[6,[7,\"shadedRGB\",\"mul\"],[\"finalLighting\"]]],[10,[6,\"d.vec4f\",[\"finalRGB\",[7,\"normalColor\",\"w\"]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.length\":()=>he,SHARD_LIGHT_DIR_X:()=>pC,SHARD_LIGHT_DIR_Y:()=>mC,\"std.smoothstep\":()=>be,\"d.vec4f\":()=>S}})&&e.f)({}));function E8(e){return t=>{let{gpu:s,registerComputeTexture:r,getCpuValue:o,onCleanup:a}=t,i=s?.root;if(!i)return null;let{layout:l,kernel:c}=fce(e.count,e.size),d=pr(i,n,e.count*2),u=(globalThis.__TYPEGPU_AUTONAME__??(b=>b))(i.createTexture({size:[e.size,e.size],format:T8}).$usage(\"storage\",\"sampled\"),\"voronoiTex\");a(()=>u.destroy());let p=r(u),_=i.createBindGroup(l,{cellPos:d,voronoiTex:u}),f=wr(i,(b=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(b.f=((x,P)=>{\"use gpu\";c(x,P)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"kernel\",[\"cx\",\"cy\"]]]]},externals:{kernel:()=>c}})&&b.f)({}),{size:[e.size,e.size],bindGroup:_}),h=b=>{d.write(e.sites(b))},g=o(e.seedProp)??e.seedDefault;h(g);let y=!0;return{outputs:{[e.output]:p},getComputeNodes:()=>{let b=o(e.seedProp)??e.seedDefault;return b!==g&&(g=b,h(g),y=!0),y?(y=!1,[f]):null}}}}var{formatFloat:hce}=xae,k8=e=>({kind:\"grid\",slots:e}),B8=e=>({kind:\"radial\",slots:e}),z8=e=>({kind:\"line\",slots:e}),R8=(e,t)=>({mode:e,members:t}),gce={grid:0,radial:1,linear:2},yce={none:0,\"alternate-flip-x\":1,\"alternate-flip-y\":2,both:3};function D8(e){return t=>{let{uniforms:s,childNode:r,ctx:o,propValues:a,childBoundsParams:i,ownBoundsParams:l,convertToTexture:c}=t;if(!r)return xt;let d=c(r).key,u=(h,g)=>{let y=a[h.name];return typeof y==\"number\"?y:g[y]??0},p=\"members\"in e.placement?[e.placement.members.grid,e.placement.members.radial,e.placement.members.linear][u(e.placement.mode,gce)]??e.placement.members.grid:e.placement,_=e.order?a[e.order.name]===\"backward\"||a[e.order.name]===1:!1,f=e.hueShift?(a[e.hueShift.name]??0)!==0:!1;return new fs(h=>{let g={p:h.freshLocal(\"rep\"),L:hce},{p:y,L:b}=g,x=U=>{let L=s[U.name];if(!L)throw new Error(`std: repeatInstances binds unknown prop '${U.name}'`);return L._emit(h)},P=[];P.push(`let ${y}_uv = ${o.uv._emit(h)};`),P.push(`let ${y}_aspect = ${o.aspect._emit(h)};`),P.push(`let ${y}_pix = vec2f(${y}_uv.x * ${y}_aspect, ${y}_uv.y);`);let C={cx:i?i.centerX._emit(h):b(.5),cy:i?i.centerY._emit(h):b(.5),hw:i?i.halfWidth._emit(h):b(.5),hh:i?i.halfHeight._emit(h):b(.5)};P.push(...lB(g,C,{left:x(e.source.crop.left),right:x(e.source.crop.right),top:x(e.source.crop.top),bottom:x(e.source.crop.bottom)})),P.push(...cB(g,{cx:l?l.centerX._emit(h):b(.5),cy:l?l.centerY._emit(h):b(.5),hw:l?l.halfWidth._emit(h):b(.5),hh:l?l.halfHeight._emit(h):b(.5)})),P.push(`let ${y}_phase = ${x(e.variation.phase)};`),P.push(`let ${y}_seed = ${x(e.variation.seed)};`);let E=i?`vec2f((${i.centerX._emit(h)}) * ${y}_aspect, ${i.centerY._emit(h)})`:`${y}_fieldCenterSq`,R=p.kind===\"grid\"?dB({columns:x(p.slots.columns),rows:x(p.slots.rows),gapX:x(p.slots.gapX),gapY:x(p.slots.gapY),stagger:x(p.slots.stagger)},u(p.slots.flip,yce)):p.kind===\"radial\"?uB(E,{count:x(p.slots.count),sweep:x(p.slots.sweep),startAngle:x(p.slots.startAngle),radius:x(p.slots.radius),faceCenter:x(p.slots.faceCenter)}):pB(E,{count:x(p.slots.count),direction:x(p.slots.direction),spacing:x(p.slots.spacing)});P.push(...fB(g,{placement:R,variation:mB(g,{scale:x(e.variation.scale),rotation:x(e.variation.rotation),opacity:x(e.variation.opacity),jitterPosition:x(e.variation.jitter.position),jitterRotation:x(e.variation.jitter.rotation),jitterScale:x(e.variation.jitter.scale),jitterOpacity:x(e.variation.jitter.opacity)}),hue:f&&e.hueShift?_B(g,x(e.hueShift)):[],zBack:_,texKey:d}));for(let U of P)h.statement(U);return W(Yt,\"unpremultiplyAlpha\",[ca(`${y}_accum`)])._emit(h)})}}var bce=w.fn([m,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a)=>{\"use gpu\";let i=m7(s),l=m(__tsover_div(pe(i),o),ae(i)),c=__tsover_mul(r,.1),d=l.mul(c);return t.add(d.mul(a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"angle\"},{type:\"i\",name:\"strength\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"channelOffset\"}],body:[0,[[13,\"angleRad\",[6,\"std.radians\",[\"angle\"]]],[13,\"direction\",[6,\"d.vec2f\",[[1,[6,\"std.cos\",[\"angleRad\"]],\"/\",\"aspect\"],[6,\"std.sin\",[\"angleRad\"]]]]],[13,\"scaledStrength\",[1,\"strength\",\"*\",[5,\"0.1\"]]],[13,\"offsetBase\",[6,[7,\"direction\",\"mul\"],[\"scaledStrength\"]]],[10,[6,[7,\"uv\",\"add\"],[[6,[7,\"offsetBase\",\"mul\"],[\"channelOffset\"]]]]]]]},externals:{\"std.radians\":()=>m7,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&e.f)({}));function L8(e){return t=>{let s=i=>W(bce,\"chromaticOffsetUV\",[t.ctx.uv,At(e.angle,t),At(e.strength,t),t.ctx.aspect,At(i,t)]),r=t.texture.sample(s(e.red)),o=t.texture.sample(s(e.green)),a=t.texture.sample(s(e.blue));return Ct(r.member(\"r\"),o.member(\"g\"),a.member(\"b\"),o.member(\"a\"))}}function U8(e){return t=>{let{uniforms:s,childNode:r,ctx:o,convertToTexture:a}=t;if(!r)return xt;let i=a(r).key;return new fs(l=>{let c={p:l.freshLocal(\"lens\"),stmts:[],U:d=>s[e[d].name]._emit(l),L:d=>fo(d),noiseIdx:{value:0}};wae(c,o.uv._emit(l),o.aspect._emit(l)),Tae(c),Pae(c,i),Cae(c);for(let d of c.stmts)l.statement(d);return W(Yt,\"unpremultiplyAlpha\",[ca(`${c.p}_out`)])._emit(l)})}}var xce=(e,t)=>typeof e==\"number\"?e:t,O8=1080;function G8(e){return t=>{let{uniforms:s,ctx:r,childNode:o,convertToTexture:a,propValues:i}=t;if(!o)return xt;let l=a(o).key,c={alpha:0,bright:1,dark:2,red:3,green:4,blue:5},d={grid:0,quadtree:1,mosaic:2},u={none:0,dimensions:1,percentage:2},p={\"bottom-left\":0,\"bottom-right\":1,\"top-left\":2,\"top-right\":3},_=i[e.detectionMode.name],f=[\"alpha\",\"bright\",\"dark\",\"red\",\"green\",\"blue\"][typeof _==\"number\"?_:c[_]??1],h=i[e.layout.name],g=[\"grid\",\"quadtree\",\"mosaic\"][typeof h==\"number\"?h:d[h]??2],y=Math.round(xce(i[e.maxDepth.name],2));Number.isFinite(y)||(y=2),y=Math.max(0,Math.min(5,y)),g===\"grid\"&&(y=0);let b=i[e.boxStyle.name],x=(typeof b==\"string\"?b:\"corners\")===\"corners\",P=i[e.labelMode.name],C=[\"none\",\"dimensions\",\"percentage\"][typeof P==\"number\"?P:u[P]??0],E=C!==\"none\",R=i[e.labelPosition.name],U=typeof R==\"number\"?R:p[R]??1,L=E?uae(t,{label:\"DetectionOverlay:atlas\",familyProp:e.fontFamily.name,weightProp:e.fontWeight.name}).key:void 0;return new fs(k=>{let D=k.freshLocal(\"ot\"),O=[],F={p:D,U:X=>s[e[X].name]._emit(k),L:X=>fo(X),s:O,sampleChild:X=>`textureSampleLevel(tex.$.${l}, samp.$.linearClamp, ${X}, 0.0)`,UN:k.external(Yt,\"unpremultiplyAlpha\"),modeStr:f},{U:q,L:Y}=F;O.push(`let ${D}_res = ${r.logicalViewportSize._emit(k)};`),O.push(`let ${D}_scaleFactor = ${D}_res.y / ${Y(O8)};`);let V=r.uv._emit(k);O.push(`let ${D}_fragPx = vec2f((${V}).x * ${D}_res.x, (${V}).y * ${D}_res.y);`),O.push(`let ${D}_aa = max(max(fwidth(${D}_fragPx.x), fwidth(${D}_fragPx.y)), ${Y(1e-4)});`),O.push(`let ${D}_cellPx = max(${q(\"cellSize\")} * ${D}_scaleFactor, ${Y(4)});`),O.push(`let ${D}_minSize = ${Y(3)} * ${D}_scaleFactor;`),O.push(`let ${D}_lineHalf = max(${q(\"lineWidth\")} * ${D}_scaleFactor * ${Y(.5)}, ${Y(.5)});`),O.push(`let ${D}_cornerRadiusPx = ${q(\"cornerRadius\")} * ${D}_scaleFactor;`),O.push(`let ${D}_boxInset = ${D}_lineHalf + ${D}_scaleFactor * ${Y(1.5)};`),O.push(`let ${D}_thr = ${q(\"threshold\")};`),mae(F,g,y),_ae(F),O.push(`var ${D}_dst = ${F.sampleChild(`(${V})`)};`),fae(F,x),E&&L&&vae(F,{labelStr:C,labelPos:U,atlasKey:L});for(let X of O)k.statement(X);return aB(`${D}_dst`)})}}function F8(e){return t=>{let{uniforms:s,ctx:r,childNode:o,convertToTexture:a,computeOutputs:i}=t;if(!o)return xt;let l=(i?.childTexture??a(o)).key,c=i?.trackState;return new fs(d=>{let u=d.freshLocal(\"kft\"),p=[],_={p:u,U:y=>s[e[y].name]._emit(d),L:y=>fo(y),s:p},{U:f,L:h}=_,g=r.uv._emit(d);if(p.push(`let ${u}_res = ${r.logicalViewportSize._emit(d)};`),p.push(`let ${u}_sf = ${u}_res.y / ${h(O8)};`),p.push(`let ${u}_px = vec2f((${g}).x * ${u}_res.x, (${g}).y * ${u}_res.y);`),p.push(`let ${u}_aa = max(max(fwidth(${u}_px.x), fwidth(${u}_px.y)), ${h(1e-4)});`),p.push(`let ${u}_lw = max(${f(\"lineWidth\")} * ${u}_sf, ${h(.5)});`),p.push(`let ${u}_ms = max(${f(\"markerSize\")} * ${u}_sf, ${h(4)});`),p.push(`var ${u}_dst = textureSampleLevel(tex.$.${l}, samp.$.linearClamp, (${g}), 0.0);`),c){let y=c.key,b=x=>`textureLoad(tex.$.${y}, vec2u(${x}, ti), 0)`;p.push(`let ${u}_n = u32(clamp(${f(\"trackers\")}, ${h(1)}, ${h(64)}));`),p.push(`for (var ti = 0u; ti < ${u}_n; ti = ti + 1u) {`),p.push(`let head = ${b(\"0u\")};`),p.push(\"if (head.w < 0.5) { continue; }\"),p.push(`let bb = ${b(\"14u\")};`),p.push(`let pad = ${u}_ms + ${u}_lw * ${h(4)} + ${u}_aa * ${h(2)};`),p.push(`let bbMin = vec2f(bb.x * ${u}_res.x, bb.y * ${u}_res.y) - vec2f(pad);`),p.push(`let bbMax = vec2f(bb.z * ${u}_res.x, bb.w * ${u}_res.y) + vec2f(pad);`),p.push(`if (all(${u}_px >= bbMin) && all(${u}_px <= bbMax)) {`),p.push(`let mta = ${b(\"1u\")};`),p.push(`let tp = vec2f(head.x * ${u}_res.x, head.y * ${u}_res.y);`),p.push(`let searching = select(${h(1)}, ${h(.45)}, mta.x > ${h(4)});`),yae(_,{len:12,every:8,load:b,stages:[hae,gae(8)]}),bae(_),p.push(\"}\"),p.push(\"}\")}for(let y of p)d.statement(y);return aB(`${u}_dst`)})}}function Ec(e){return{compute:t=>{let{gpu:s,getCpuValue:r}=t,o=s?.root;if(!o)return null;let a=e(t,o);if(!a)return null;let i=(l,c)=>{let d=r(l);return typeof d==\"number\"?d:c};return{outputs:a.outputs,...a.bindInputs?{bindInputs:a.bindInputs}:{},getComputeNodes:l=>{for(let _ of a.stages)if(_.ready&&!_.ready())return null;let c=l,d=Math.min(c.deltaTime??0,a.clampDt);if(a.zeroDt===\"skip\"&&d<=0)return null;let u={dt:d,now:Date.now(),num:i,getCpuValue:r,frameParams:c},p=[];for(let _ of a.stages)_.tick?.(u);for(let _ of a.stages)if(_.skip?.(u))return null;for(let _ of a.stages)_.emit?.(u,p);return p}}}}}var Ir={host(e,t){return{tick:t}},values(e,t){return{emit:s=>t(s)}},settle(e){let t=0;return{tick(s){e.activeWhen(s)&&(t=0)},skip(s){let r=t>e.settleMs(s);return r||(t+=s.dt*1e3),r}}},readyWhen(e){return{ready:e}},pass(e){return{emit:(t,s)=>s.push(e)}},cache(e){return{emit:(t,s)=>s.push(e(t))}},publish(e){return{emit:(t,s)=>s.push(e(t))}},seedOnce(e){return{emit(t,s){e.staleWhen(t)&&(e.onSeed?.(),s.push(e.pass))}}},iterate(e){return{emit(t,s){let r=e.count(t);for(let o=0;o<r;o++)e.step(o,s,t)}}},sortPass(e){let t=\"A\",s=0;return{emit(r,o){let a=e.passes(r);for(let i=0;i<a;i++)o.push(e.pass(s%2,t)),t=t===\"A\"?\"B\":\"A\",s++},side:()=>t}}};function Eg(e){let t=Math.max(1,Math.round(e.dimensions.width)),s=Math.max(1,Math.round(e.dimensions.height));return e.onResize(({width:r,height:o})=>{t=Math.max(1,Math.round(r)),s=Math.max(1,Math.round(o))}),{tracked:()=>({width:t,height:s}),safe:r=>({width:Math.max(1,r.dimensions?.width??t),height:Math.max(1,r.dimensions?.height??s)})}}var gn=(e,t)=>({name:e,run:t});function kg(e){let t=Date.now();return s=>{let{pointer:r}=s,o=Date.now(),a=Math.min((o-t)/1e3,e.clampDt);t=o;let i={dt:a,now:o,pointer:r,frameParams:s};for(let l of e.steps)if(l.run(i)===\"skip\")return}}function Bg(e,t){let s=new Uint16Array(t.size*t.size*4),r=e.createDataTexture({width:t.size,height:t.size,format:\"rgba16float\",data:s,label:t.label});return e.onCleanup(()=>r.destroy()),{texData:s,texture:e.registerMediaTexture(()=>r.texture),upload:()=>r.write(s)}}var zg=\"rgba16float\",b2=16384,Rg=e=>Math.max(8,Math.min(128,Math.floor(e))),wm=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({buffer:{storage:Fe(S,b2),access:\"mutable\"},params:{uniform:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cursorX:n,cursorY:n,mouseVelX:n,mouseVelY:n,dt:n,decay:n,intensity:n,radius:n,aspect:n}),\"uniform\")}}),\"splatUpdateLayout\"),Y1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({buffer:{storage:Fe(S,b2),access:\"readonly\"},dispTex:{storageTexture:zt(zg,\"write-only\")}}),\"splatOutputLayout\");function Ace(e){return w.fn([M,M])((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r)=>{\"use gpu\";let o=wm.$.params,a=__tsover_add(__tsover_mul(r,M(e)),s),i=wm.$.buffer[a],l=__tsover_mul(i.x,__tsover_sub(1,__tsover_mul(o.decay,o.dt))),c=__tsover_mul(i.y,__tsover_sub(1,__tsover_mul(o.decay,o.dt))),d=__tsover_div(__tsover_add(n(s),.5),n(e)),u=__tsover_div(__tsover_add(n(r),.5),n(e)),p=N(__tsover_sub(d,o.cursorX),__tsover_mul(__tsover_sub(d,o.cursorX),o.aspect),o.aspect>=1),_=N(__tsover_div(__tsover_sub(u,o.cursorY),o.aspect),__tsover_sub(u,o.cursorY),o.aspect>=1),f=__tsover_add(__tsover_mul(p,p),__tsover_mul(_,_)),h=__tsover_mul(o.radius,2);if(f<__tsover_mul(h,h)&&__tsover_add(re(o.mouseVelX),re(o.mouseVelY))>.01){let g=Tt(__tsover_mul(__tsover_div(f,__tsover_mul(o.radius,o.radius)),-1));l=__tsover_add(l,__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(o.mouseVelX,g),o.intensity),o.dt),.5)),c=__tsover_add(c,__tsover_mul(__tsover_mul(__tsover_mul(__tsover_mul(o.mouseVelY,g),o.intensity),o.dt),.5))}l=G(l,-1,1),c=G(c,-1,1),wm.$.buffer[a]=S(l,c,0,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"p\",[7,[7,\"splatUpdateLayout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"gridSize\"]]],\"+\",\"cx\"]],[13,\"cell\",[8,[7,[7,\"splatUpdateLayout\",\"$\"],\"buffer\"],\"idx\"]],[12,\"dx\",[1,[7,\"cell\",\"x\"],\"*\",[1,[5,\"1\"],\"-\",[1,[7,\"p\",\"decay\"],\"*\",[7,\"p\",\"dt\"]]]]],[12,\"dy\",[1,[7,\"cell\",\"y\"],\"*\",[1,[5,\"1\"],\"-\",[1,[7,\"p\",\"decay\"],\"*\",[7,\"p\",\"dt\"]]]]],[13,\"cellX\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"gridSize\"]]]],[13,\"cellY\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"gridSize\"]]]],[13,\"ddx\",[6,\"std.select\",[[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],[1,[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],\"*\",[7,\"p\",\"aspect\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"ddy\",[6,\"std.select\",[[1,[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],\"/\",[7,\"p\",\"aspect\"]],[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"distSq\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]],[13,\"radius2\",[1,[7,\"p\",\"radius\"],\"*\",[5,\"2\"]]],[11,[3,[1,\"distSq\",\"<\",[1,\"radius2\",\"*\",\"radius2\"]],\"&&\",[1,[1,[6,\"std.abs\",[[7,\"p\",\"mouseVelX\"]]],\"+\",[6,\"std.abs\",[[7,\"p\",\"mouseVelY\"]]]],\">\",[5,\"0.01\"]]],[0,[[13,\"influence\",[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]]],\"*\",[4,\"-\",[5,\"1\"]]]]]],[2,\"dx\",\"=\",[1,\"dx\",\"+\",[1,[1,[1,[1,[7,\"p\",\"mouseVelX\"],\"*\",\"influence\"],\"*\",[7,\"p\",\"intensity\"]],\"*\",[7,\"p\",\"dt\"]],\"*\",[5,\"0.5\"]]]],[2,\"dy\",\"=\",[1,\"dy\",\"+\",[1,[1,[1,[1,[7,\"p\",\"mouseVelY\"],\"*\",\"influence\"],\"*\",[7,\"p\",\"intensity\"]],\"*\",[7,\"p\",\"dt\"]],\"*\",[5,\"0.5\"]]]]]]],[2,\"dx\",\"=\",[6,\"std.clamp\",[\"dx\",[4,\"-\",[5,\"1\"]],[5,\"1\"]]]],[2,\"dy\",\"=\",[6,\"std.clamp\",[\"dy\",[4,\"-\",[5,\"1\"]],[5,\"1\"]]]],[2,[8,[7,[7,\"splatUpdateLayout\",\"$\"],\"buffer\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"dx\",\"dy\",[5,\"0\"],[5,\"0\"]]]]]]},externals:{splatUpdateLayout:()=>wm,\"d.u32\":()=>M,gridSize:()=>e,\"d.f32\":()=>n,\"std.select\":()=>N,\"std.abs\":()=>re,\"std.exp\":()=>Tt,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&t.f)({})).$name(\"pointerSplatUpdate\")}function wce(e){return w.fn([M,M])((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r)=>{\"use gpu\";let o=__tsover_add(__tsover_mul(r,M(e)),s),a=Y1.$.buffer[o];lt(Y1.$.dispTex,fe(s,r),S(a.x,a.y,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"gridSize\"]]],\"+\",\"cx\"]],[13,\"cell\",[8,[7,[7,\"splatOutputLayout\",\"$\"],\"buffer\"],\"idx\"]],[6,\"std.textureStore\",[[7,[7,\"splatOutputLayout\",\"$\"],\"dispTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"cell\",\"x\"],[7,\"cell\",\"y\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{\"d.u32\":()=>M,gridSize:()=>e,splatOutputLayout:()=>Y1,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&t.f)({})).$name(\"pointerSplatOutput\")}function I8(e){return(t,s)=>{let{getCpuValue:r,registerComputeTexture:o,onCleanup:a}=t,i=Rg(r(e.gridSize.name)??20),l=pr(s,S,b2),c=(globalThis.__TYPEGPU_AUTONAME__??(D=>D))(s.createTexture({size:[i,i],format:zg}).$usage(\"storage\",\"sampled\"),\"dispTex\");a(()=>c.destroy());let d=o(c),u=(globalThis.__TYPEGPU_AUTONAME__??(D=>D))(s.createUniform(gt({cursorX:n,cursorY:n,mouseVelX:n,mouseVelY:n,dt:n,decay:n,intensity:n,radius:n,aspect:n})),\"updateParams\"),p=Eg(t),_=[i,i],f=Ace(i),h=wce(i),g=s.createBindGroup(wm,{buffer:l,params:u.buffer}),y=s.createBindGroup(Y1,{buffer:l,dispTex:c}),b=wr(s,(D=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(D.f=((O,F)=>{\"use gpu\";f(O,F)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"updateKernel\",[\"cx\",\"cy\"]]]]},externals:{updateKernel:()=>f}})&&D.f)({}),{size:_,bindGroup:g}),x=wr(s,(D=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(D.f=((O,F)=>{\"use gpu\";h(O,F)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"outputKernel\",[\"cx\",\"cy\"]]]]},externals:{outputKernel:()=>h}})&&D.f)({}),{size:_,bindGroup:y}),P=.5,C=.5,E=0,R=0,U=.5,L=.5,k=!1;return{outputs:{[e.output]:d},clampDt:.016,stages:[Ir.host(\"cursorVelocity\",D=>{U=D.frameParams.pointer?.x??.5,L=D.frameParams.pointer?.y??.5;let O=D.dt>0?(U-P)/D.dt:0,F=D.dt>0?(L-C)/D.dt:0;E=E*.85+O*.15,R=R*.85+F*.15,P=U,C=L,k=Math.abs(O)+Math.abs(F)>.01}),Ir.settle({activeWhen:()=>k,settleMs:D=>{let O=D.num(e.decay.name,3);return O>0?Math.min(3e4,Math.log(1e-4)/Math.log(Math.max(1e-6,1-O*.016))*16.67):3e4}}),Ir.values(\"brush+decay\",D=>{let O=p.safe(D.frameParams);u.write({cursorX:U,cursorY:L,mouseVelX:E,mouseVelY:R,dt:D.dt,decay:D.num(e.decay.name,3),intensity:D.num(e.intensity.name,1),radius:D.num(e.radius.name,1)*.05,aspect:O.width/O.height})}),Ir.pass(b),Ir.publish(()=>x)]}}}var un=64,s_=un*un,eb=un-1,Fa=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({readBuf:{storage:Fe(S,s_),access:\"readonly\"},writeBuf:{storage:Fe(S,s_),access:\"mutable\"},params:{uniform:(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({cursorX:n,cursorY:n,dirX:n,dirY:n,clampedSpeed:n,dt:n,subDt:n,stiffness:n,dampFactor:n,radius:n,aspect:n}),\"uniform\")}}),\"latticeLayout\"),W1=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({srcBuf:{storage:Fe(S,s_),access:\"readonly\"},dispTex:{storageTexture:zt(zg,\"write-only\")}}),\"latticeOutputLayout\"),_C=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";if(t>M(0)&&t<M(eb)&&s>M(0)&&s<M(eb)){let r=Fa.$.params,o=M(un),a=__tsover_add(__tsover_mul(s,o),t),i=Fa.$.readBuf[a],l=i.x,c=i.y,d=i.z,u=i.w,p=Fa.$.readBuf[__tsover_sub(a,M(1))],_=Fa.$.readBuf[__tsover_add(a,M(1))],f=Fa.$.readBuf[__tsover_sub(a,o)],h=Fa.$.readBuf[__tsover_add(a,o)],g=Fa.$.readBuf[__tsover_sub(__tsover_sub(a,o),M(1))],y=Fa.$.readBuf[__tsover_add(__tsover_sub(a,o),M(1))],b=Fa.$.readBuf[__tsover_sub(__tsover_add(a,o),M(1))],x=Fa.$.readBuf[__tsover_add(__tsover_add(a,o),M(1))],P=__tsover_mul(r.stiffness,__tsover_add(__tsover_add(__tsover_add(__tsover_sub(p.x,l),__tsover_sub(_.x,l)),__tsover_sub(f.x,l)),__tsover_sub(h.x,l))),C=__tsover_mul(r.stiffness,__tsover_add(__tsover_add(__tsover_add(__tsover_sub(p.y,c),__tsover_sub(_.y,c)),__tsover_sub(f.y,c)),__tsover_sub(h.y,c))),E=__tsover_mul(r.stiffness,.35);P=__tsover_add(P,__tsover_mul(E,__tsover_add(__tsover_add(__tsover_add(__tsover_sub(g.x,l),__tsover_sub(y.x,l)),__tsover_sub(b.x,l)),__tsover_sub(x.x,l)))),C=__tsover_add(C,__tsover_mul(E,__tsover_add(__tsover_add(__tsover_add(__tsover_sub(g.y,c),__tsover_sub(y.y,c)),__tsover_sub(b.y,c)),__tsover_sub(x.y,c)))),P=__tsover_sub(P,__tsover_mul(__tsover_mul(r.stiffness,.1),l)),C=__tsover_sub(C,__tsover_mul(__tsover_mul(r.stiffness,.1),c));let R=__tsover_add(__tsover_mul(d,r.dampFactor),__tsover_mul(P,r.subDt)),U=__tsover_add(__tsover_mul(u,r.dampFactor),__tsover_mul(C,r.subDt));if(r.clampedSpeed>.01){let D=__tsover_div(__tsover_add(n(t),.5),n(un)),O=__tsover_div(__tsover_add(n(s),.5),n(un)),F=N(__tsover_sub(D,r.cursorX),__tsover_mul(__tsover_sub(D,r.cursorX),r.aspect),r.aspect>=1),q=N(__tsover_div(__tsover_sub(O,r.cursorY),r.aspect),__tsover_sub(O,r.cursorY),r.aspect>=1),Y=__tsover_add(__tsover_mul(F,F),__tsover_mul(q,q)),V=__tsover_mul(r.radius,3);if(Y<__tsover_mul(V,V)){let X=Tt(__tsover_mul(__tsover_div(Y,__tsover_mul(r.radius,r.radius)),-1)),Q=__tsover_mul(__tsover_mul(__tsover_mul(X,r.clampedSpeed),r.dt),2);R=__tsover_add(R,__tsover_mul(r.dirX,Q)),U=__tsover_add(U,__tsover_mul(r.dirY,Q))}}let L=G(__tsover_add(l,__tsover_mul(R,r.subDt)),-.5,.5),k=G(__tsover_add(c,__tsover_mul(U,r.subDt)),-.5,.5);Fa.$.writeBuf[a]=S(L,k,R,U)}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[11,[3,[3,[3,[1,\"cx\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],\"&&\",[1,\"cx\",\"<\",[6,\"d.u32\",[\"LATTICE_MAX\"]]]],\"&&\",[1,\"cy\",\">\",[6,\"d.u32\",[[5,\"0\"]]]]],\"&&\",[1,\"cy\",\"<\",[6,\"d.u32\",[\"LATTICE_MAX\"]]]],[0,[[13,\"p\",[7,[7,\"latticeLayout\",\"$\"],\"params\"]],[13,\"gs\",[6,\"d.u32\",[\"LATTICE_GRID\"]]],[13,\"idx\",[1,[1,\"cy\",\"*\",\"gs\"],\"+\",\"cx\"]],[13,\"current\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],\"idx\"]],[13,\"dispX\",[7,\"current\",\"x\"]],[13,\"dispY\",[7,\"current\",\"y\"]],[13,\"velX\",[7,\"current\",\"z\"]],[13,\"velY\",[7,\"current\",\"w\"]],[13,\"nL\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"nR\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"nU\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"-\",\"gs\"]]],[13,\"nD\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,\"idx\",\"+\",\"gs\"]]],[13,\"nUL\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,[1,\"idx\",\"-\",\"gs\"],\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"nUR\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,[1,\"idx\",\"-\",\"gs\"],\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"nDL\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,[1,\"idx\",\"+\",\"gs\"],\"-\",[6,\"d.u32\",[[5,\"1\"]]]]]],[13,\"nDR\",[8,[7,[7,\"latticeLayout\",\"$\"],\"readBuf\"],[1,[1,\"idx\",\"+\",\"gs\"],\"+\",[6,\"d.u32\",[[5,\"1\"]]]]]],[12,\"fx\",[1,[7,\"p\",\"stiffness\"],\"*\",[1,[1,[1,[1,[7,\"nL\",\"x\"],\"-\",\"dispX\"],\"+\",[1,[7,\"nR\",\"x\"],\"-\",\"dispX\"]],\"+\",[1,[7,\"nU\",\"x\"],\"-\",\"dispX\"]],\"+\",[1,[7,\"nD\",\"x\"],\"-\",\"dispX\"]]]],[12,\"fy\",[1,[7,\"p\",\"stiffness\"],\"*\",[1,[1,[1,[1,[7,\"nL\",\"y\"],\"-\",\"dispY\"],\"+\",[1,[7,\"nR\",\"y\"],\"-\",\"dispY\"]],\"+\",[1,[7,\"nU\",\"y\"],\"-\",\"dispY\"]],\"+\",[1,[7,\"nD\",\"y\"],\"-\",\"dispY\"]]]],[13,\"shearK\",[1,[7,\"p\",\"stiffness\"],\"*\",[5,\"0.35\"]]],[2,\"fx\",\"=\",[1,\"fx\",\"+\",[1,\"shearK\",\"*\",[1,[1,[1,[1,[7,\"nUL\",\"x\"],\"-\",\"dispX\"],\"+\",[1,[7,\"nUR\",\"x\"],\"-\",\"dispX\"]],\"+\",[1,[7,\"nDL\",\"x\"],\"-\",\"dispX\"]],\"+\",[1,[7,\"nDR\",\"x\"],\"-\",\"dispX\"]]]]],[2,\"fy\",\"=\",[1,\"fy\",\"+\",[1,\"shearK\",\"*\",[1,[1,[1,[1,[7,\"nUL\",\"y\"],\"-\",\"dispY\"],\"+\",[1,[7,\"nUR\",\"y\"],\"-\",\"dispY\"]],\"+\",[1,[7,\"nDL\",\"y\"],\"-\",\"dispY\"]],\"+\",[1,[7,\"nDR\",\"y\"],\"-\",\"dispY\"]]]]],[2,\"fx\",\"=\",[1,\"fx\",\"-\",[1,[1,[7,\"p\",\"stiffness\"],\"*\",[5,\"0.1\"]],\"*\",\"dispX\"]]],[2,\"fy\",\"=\",[1,\"fy\",\"-\",[1,[1,[7,\"p\",\"stiffness\"],\"*\",[5,\"0.1\"]],\"*\",\"dispY\"]]],[12,\"newVelX\",[1,[1,\"velX\",\"*\",[7,\"p\",\"dampFactor\"]],\"+\",[1,\"fx\",\"*\",[7,\"p\",\"subDt\"]]]],[12,\"newVelY\",[1,[1,\"velY\",\"*\",[7,\"p\",\"dampFactor\"]],\"+\",[1,\"fy\",\"*\",[7,\"p\",\"subDt\"]]]],[11,[1,[7,\"p\",\"clampedSpeed\"],\">\",[5,\"0.01\"]],[0,[[13,\"cellX\",[1,[1,[6,\"d.f32\",[\"cx\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"LATTICE_GRID\"]]]],[13,\"cellY\",[1,[1,[6,\"d.f32\",[\"cy\"]],\"+\",[5,\"0.5\"]],\"/\",[6,\"d.f32\",[\"LATTICE_GRID\"]]]],[13,\"ddx\",[6,\"std.select\",[[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],[1,[1,\"cellX\",\"-\",[7,\"p\",\"cursorX\"]],\"*\",[7,\"p\",\"aspect\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"ddy\",[6,\"std.select\",[[1,[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],\"/\",[7,\"p\",\"aspect\"]],[1,\"cellY\",\"-\",[7,\"p\",\"cursorY\"]],[1,[7,\"p\",\"aspect\"],\">=\",[5,\"1\"]]]]],[13,\"distSq\",[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]]],[13,\"influenceRadius\",[1,[7,\"p\",\"radius\"],\"*\",[5,\"3\"]]],[11,[1,\"distSq\",\"<\",[1,\"influenceRadius\",\"*\",\"influenceRadius\"]],[0,[[13,\"influence\",[6,\"std.exp\",[[1,[1,\"distSq\",\"/\",[1,[7,\"p\",\"radius\"],\"*\",[7,\"p\",\"radius\"]]],\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"forceMag\",[1,[1,[1,\"influence\",\"*\",[7,\"p\",\"clampedSpeed\"]],\"*\",[7,\"p\",\"dt\"]],\"*\",[5,\"2\"]]],[2,\"newVelX\",\"=\",[1,\"newVelX\",\"+\",[1,[7,\"p\",\"dirX\"],\"*\",\"forceMag\"]]],[2,\"newVelY\",\"=\",[1,\"newVelY\",\"+\",[1,[7,\"p\",\"dirY\"],\"*\",\"forceMag\"]]]]]]]]],[13,\"newDispX\",[6,\"std.clamp\",[[1,\"dispX\",\"+\",[1,\"newVelX\",\"*\",[7,\"p\",\"subDt\"]]],[4,\"-\",[5,\"0.5\"]],[5,\"0.5\"]]]],[13,\"newDispY\",[6,\"std.clamp\",[[1,\"dispY\",\"+\",[1,\"newVelY\",\"*\",[7,\"p\",\"subDt\"]]],[4,\"-\",[5,\"0.5\"]],[5,\"0.5\"]]]],[2,[8,[7,[7,\"latticeLayout\",\"$\"],\"writeBuf\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"newDispX\",\"newDispY\",\"newVelX\",\"newVelY\"]]]]]]]]},externals:{\"d.u32\":()=>M,LATTICE_MAX:()=>eb,latticeLayout:()=>Fa,LATTICE_GRID:()=>un,\"d.f32\":()=>n,\"std.select\":()=>N,\"std.exp\":()=>Tt,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"springLatticeStep\"),fC=w.fn([M,M])((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=__tsover_add(__tsover_mul(s,M(un)),t),o=W1.$.srcBuf[r];lt(W1.$.dispTex,fe(t,s),S(o.x,o.y,0,1))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[13,\"idx\",[1,[1,\"cy\",\"*\",[6,\"d.u32\",[\"LATTICE_GRID\"]]],\"+\",\"cx\"]],[13,\"cell\",[8,[7,[7,\"latticeOutputLayout\",\"$\"],\"srcBuf\"],\"idx\"]],[6,\"std.textureStore\",[[7,[7,\"latticeOutputLayout\",\"$\"],\"dispTex\"],[6,\"d.vec2u\",[\"cx\",\"cy\"]],[6,\"d.vec4f\",[[7,\"cell\",\"x\"],[7,\"cell\",\"y\"],[5,\"0\"],[5,\"1\"]]]]]]]},externals:{\"d.u32\":()=>M,LATTICE_GRID:()=>un,latticeOutputLayout:()=>W1,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&e.f)({})).$name(\"springLatticeOutput\");function Y8(e){return(t,s)=>{let{registerComputeTexture:r,onCleanup:o}=t,a=pr(s,S,s_),i=pr(s,S,s_),l=(globalThis.__TYPEGPU_AUTONAME__??(k=>k))(s.createTexture({size:[un,un],format:zg}).$usage(\"storage\",\"sampled\"),\"dispTex\");o(()=>l.destroy());let c=r(l),d=(globalThis.__TYPEGPU_AUTONAME__??(k=>k))(s.createUniform(gt({cursorX:n,cursorY:n,dirX:n,dirY:n,clampedSpeed:n,dt:n,subDt:n,stiffness:n,dampFactor:n,radius:n,aspect:n})),\"springParams\"),u=Eg(t),p=[un,un],_=s.createBindGroup(Fa,{readBuf:a,writeBuf:i,params:d.buffer}),f=s.createBindGroup(Fa,{readBuf:i,writeBuf:a,params:d.buffer}),h=wr(s,(k=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(k.f=((D,O)=>{\"use gpu\";_C(D,O)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"springLatticeKernel\",[\"cx\",\"cy\"]]]]},externals:{springLatticeKernel:()=>_C}})&&k.f)({}),{size:p}),g=s.createBindGroup(W1,{srcBuf:a,dispTex:l}),y=wr(s,(k=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(k.f=((D,O)=>{\"use gpu\";fC(D,O)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"}],body:[0,[[6,\"springLatticeOutputKernel\",[\"cx\",\"cy\"]]]]},externals:{springLatticeOutputKernel:()=>fC}})&&k.f)({}),{size:p,bindGroup:g}),b=.5,x=.5,P=.5,C=.5,E=0,R=0,U=0,L=0;return{outputs:{[e.output]:c},clampDt:.016,zeroDt:\"skip\",stages:[Ir.host(\"cursorImpulse\",k=>{P=k.frameParams.pointer?.x??.5,C=k.frameParams.pointer?.y??.5,E=(P-b)/k.dt,R=(C-x)/k.dt,U=Math.sqrt(E*E+R*R),L=Math.min(U,3),b=P,x=C}),Ir.settle({activeWhen:()=>L>.01,settleMs:k=>{let D=k.num(e.damping.name,3);return D>0?Math.min(3e4,5e3/D):3e4}}),Ir.values(\"springs+impulse\",k=>{let D=u.safe(k.frameParams),O=k.num(e.damping.name,3),F=k.dt/2;d.write({cursorX:P,cursorY:C,dirX:U>.01?E/U:0,dirY:U>.01?R/U:0,clampedSpeed:L,dt:k.dt,subDt:F,stiffness:k.num(e.stiffness.name,3),dampFactor:Math.max(0,Math.min(1,1-O*F)),radius:k.num(e.radius.name,1)*.08,aspect:D.width/D.height})}),Ir.pass(h.with(_)),Ir.pass(h.with(f)),Ir.publish(()=>y)]}}}var rl=class Dx{constructor(t){this.build=t}folded(){return new Dx(t=>W(Xae,\"foldAboutCenter\",[this.build(t)]))}tiled(t){return new Dx(s=>W(Hae,\"tilePhase\",[this.build(s),At(t,s)]))}bands(t){return new Tce(this,t)}},Tce=class extends rl{constructor(e,t){super(s=>W(jae,\"bandMidpointCoord\",[e.build(s),At(t,s)])),this.base=e,this.count=t}base;count;shuffled(){return new rl(e=>W(Kae,\"bandShuffleCoord\",[this.base.build(e),At(this.count,e)]))}},Sce=class{constructor(e){this.size=e}diamond(){return new rl(e=>W(Qae,\"cellDiamondCoord\",[e.ctx.uv,e.ctx.aspect,At(this.size,e)]))}checker(){return new rl(e=>W(Zae,\"cellCheckerCoord\",[e.ctx.uv,e.ctx.aspect,At(this.size,e)]))}shuffled(){return new rl(e=>W(Jae,\"cellShuffleCoord\",[e.ctx.uv,e.ctx.aspect,At(this.size,e)]))}},Pce={cw:0,ccw:1,both:2},eo={directional(e){return new rl(t=>W(Vae,\"directionalCoord\",[t.ctx.uv,t.ctx.aspect,At(e,t)]))},radial(e){return new rl(t=>W(Nae,\"radialCornerNormCoord\",[t.ctx.uv,t.ctx.aspect,At(e,t)]))},angular(e,t,s){return new rl(r=>{let o=Pce[typeof s==\"string\"?s:r.propValues[s.name]??\"cw\"]??0;return W($ae,\"angularCoord\",[r.ctx.uv,r.ctx.aspect,At(e,r),At(t,r),$e(o)])})},cells(e){return new Sce(e)},noise(e,t){return new rl(s=>W(ene,\"fbmCoverageCoord\",[s.ctx.uv,s.ctx.aspect,At(e,s),At(t,s)]))}};function to(e){return{kind:\"pointwise\",body:{fn:qae,hint:\"applyReveal\"},args:t=>[W(Wae,\"revealMask\",[e.coverage.build(t),At(e.progress,t),At(e.feather,t),At(e.invert,t)])]}}function $_(e){let t=new WeakMap;return s=>{let r=t.get(s);if(r!==void 0)return r;let o=e(s);return t.set(s,o),o}}function W8(e){return $_(t=>(t.propValues[e.amount.name]??0)===0?t.ctx.uv:ns(W(Ooe,\"watercolorUvBase\",[t.ctx.uv,t.ctx.logicalViewportSize,me(e.amount,t),t.ctx.time]),\"wcUvBase\"))}function q8(e){return $_(t=>{let s=Math.max(1,Math.min(8,Math.round(t.propValues[e.radius.name]??4))),r=Math.max(2,Math.ceil((s+1)/2)),o=1/(r*r),a=e.at(t),i=t.ctx.logicalViewportSize,l=(c,d)=>{let u=ca(\"vec4f(0.0, 0.0, 0.0, 0.0)\"),p=ca(\"vec3f(0.0, 0.0, 0.0)\");for(let _=0;_<r;_++)for(let f=0;f<r;f++){let h=W(Goe,\"watercolorTapUV\",[a,i,$e((2*f+.5)*c),$e((2*_+.5)*d)]),g=ns(t.texture.sample(h),\"wcTap\"),y=g.member(\"rgb\");u=u.add(g),p=p.add(y.mul(y))}return{sum:u,sq:p}};return{quadrants:[l(-1,-1),l(1,-1),l(-1,1),l(1,1)],invN:o}})}function V8(e){return t=>(t.propValues[e.amount.name]??0)===0?$e(0):W(Foe,\"watercolorGrain\",[t.ctx.uv,t.ctx.viewportSize])}function N8(e){return Rd({resultAlpha:\"straight\",build:t=>{let s=u=>me(u,t),r=ns(t.sampleStraight(e.at(t)),\"wcOriginal\");if((t.propValues[e.strength.name]??1)===0)return r;let{quadrants:[o,a,i,l],invN:c}=e.brush(t),d=e.grain(t);return Ct(W(Ioe,\"watercolorCompose\",[o.sum,a.sum,i.sum,l.sum,o.sq,a.sq,i.sq,l.sq,$e(c),r,s(e.paperColor),s(e.paper),s(e.strength),d]),r.member(\"a\"))}})}function $8(e){return $_(t=>{let{sampleStraight:s,ctx:r}=t,o=r.viewportSize,a=(y,b)=>W(sP,\"chalkLuma\",[s(W(Yoe,\"chalkOffsetUV\",[r.uv,o,me(e.spacing,t),$e(y),$e(b)]))]),i=a(-1,-1),l=a(0,-1),c=a(1,-1),d=a(-1,0),u=a(1,0),p=a(-1,1),_=a(0,1),f=a(1,1),h=s(r.uv),g=W(sP,\"chalkLuma\",[h]);return{sobelA:Ct(i,l,c,d),sobelB:Ct(u,p,_,f),centre:h,centreLum:g}})}function X8(e){return Rd({resultAlpha:\"straight\",build:t=>{let s=d=>me(d,t),{sobelA:r,sobelB:o,centre:a,centreLum:i}=e.edges(t),l=Ct(i,a.member(\"a\"),0,0),c=Ct(s(e.sensitivity),s(e.hatchScale),s(e.shading),s(e.grain));return W(Woe,\"chalkboardCompose\",[r,o,t.ctx.uv,t.ctx.viewportSize,l,c,s(e.board),s(e.chalk)])}})}function H8(e){return $_(t=>W(qoe,\"asciiGrid\",[t.ctx.uv,t.ctx.viewportSize,me(e.cellSize,t),me(e.spacing,t)]))}function j8(e){return $_(t=>W(Yt,\"unpremultiplyAlpha\",[t.convertToTexture(t.childNode).sample(e.grid(t).member(\"cellCenter\"))]))}function K8(e){return t=>{let s=e.atlas(t),r=W(Voe,\"asciiAtlasUV\",[e.cell(t).member(\"rgb\"),me(e.gamma,t),t.uniforms._charCount,t.uniforms._atlasSize,t.uniforms._atlasScale,e.grid(t).member(\"cellUV\")]);return s.sample(r,\"nearestClamp\")}}function Q8(e){return t=>{if(!t.childNode)return xt;let s=e.cell(t);return W(Noe,\"asciiCompose\",[e.glyph(t).member(\"rgb\"),s,e.grid(t).member(\"isOutside\"),me(e.alphaThreshold,t),me(e.preserveAlpha,t)])}}var vC=bt,Z8=w.fn([m,n,m,n,n,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=m(__tsover_mul(t.x,s),t.y),c=m(__tsover_mul(r.x,s),__tsover_sub(1,r.y)),d=__tsover_sub(l.x,c.x),u=__tsover_sub(l.y,c.y),p=__tsover_mul(o,vC),_=pe(p),f=ae(p),h=__tsover_add(__tsover_mul(d,_),__tsover_mul(u,f)),g=__tsover_sub(__tsover_mul(u,_),__tsover_mul(d,f)),y=__tsover_add(__tsover_div(h,__tsover_mul(a,2)),.5),b=__tsover_add(__tsover_div(g,__tsover_mul(i,2)),.5);return A(y,b,__tsover_mul(__tsover_mul(__tsover_mul(Et(0,y),Et(y,1)),Et(0,b)),Et(b,1)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"rotationDeg\"},{type:\"i\",name:\"halfW\"},{type:\"i\",name:\"halfH\"}],body:[0,[[13,\"aspectUV\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"centerPos\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[13,\"dx\",[1,[7,\"aspectUV\",\"x\"],\"-\",[7,\"centerPos\",\"x\"]]],[13,\"dy\",[1,[7,\"aspectUV\",\"y\"],\"-\",[7,\"centerPos\",\"y\"]]],[13,\"rotRad\",[1,\"rotationDeg\",\"*\",\"OBF_DEG_TO_RAD\"]],[13,\"cosR\",[6,\"std.cos\",[\"rotRad\"]]],[13,\"sinR\",[6,\"std.sin\",[\"rotRad\"]]],[13,\"rdx\",[1,[1,\"dx\",\"*\",\"cosR\"],\"+\",[1,\"dy\",\"*\",\"sinR\"]]],[13,\"rdy\",[1,[1,\"dy\",\"*\",\"cosR\"],\"-\",[1,\"dx\",\"*\",\"sinR\"]]],[13,\"localU\",[1,[1,\"rdx\",\"/\",[1,\"halfW\",\"*\",[5,\"2\"]]],\"+\",[5,\"0.5\"]]],[13,\"localV\",[1,[1,\"rdy\",\"/\",[1,\"halfH\",\"*\",[5,\"2\"]]],\"+\",[5,\"0.5\"]]],[13,\"insideMask\",[1,[1,[1,[6,\"std.step\",[[5,\"0\"],\"localU\"]],\"*\",[6,\"std.step\",[\"localU\",[5,\"1\"]]]],\"*\",[6,\"std.step\",[[5,\"0\"],\"localV\"]]],\"*\",[6,\"std.step\",[\"localV\",[5,\"1\"]]]]],[10,[6,\"d.vec3f\",[\"localU\",\"localV\",\"insideMask\"]]]]]},externals:{\"d.vec2f\":()=>m,OBF_DEG_TO_RAD:()=>vC,\"std.cos\":()=>pe,\"std.sin\":()=>ae,\"std.step\":()=>Et,\"d.vec3f\":()=>A}})&&e.f)({})),md=Jt,hC=bt,_m=w.fn([m,n,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=__tsover_mul(s,hC),c=pe(l),d=ae(l),u=__tsover_add(__tsover_mul(t.x,__tsover_mul(d,-1)),__tsover_mul(t.y,c)),p=pe(__tsover_add(__tsover_mul(__tsover_mul(u,r),md),o)),_=K(-1.15,1.15,G(a,0,1));return be(__tsover_sub(_,i),__tsover_add(_,i),p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"angleDeg\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"reliefPhase\"},{type:\"i\",name:\"level\"},{type:\"i\",name:\"aa\"}],body:[0,[[13,\"angleRad\",[1,\"angleDeg\",\"*\",\"HP_DEG_TO_RAD\"]],[13,\"c\",[6,\"std.cos\",[\"angleRad\"]]],[13,\"s\",[6,\"std.sin\",[\"angleRad\"]]],[13,\"w\",[1,[1,[7,\"p\",\"x\"],\"*\",[1,\"s\",\"*\",[4,\"-\",[5,\"1\"]]]],\"+\",[1,[7,\"p\",\"y\"],\"*\",\"c\"]]],[13,\"phase\",[1,[1,[1,\"w\",\"*\",\"frequency\"],\"*\",\"HP_TAU\"],\"+\",\"reliefPhase\"]],[13,\"v\",[6,\"std.cos\",[\"phase\"]]],[13,\"thr\",[6,\"std.mix\",[[4,\"-\",[5,\"1.15\"]],[5,\"1.15\"],[6,\"std.clamp\",[\"level\",[5,\"0\"],[5,\"1\"]]]]]],[10,[6,\"std.smoothstep\",[[1,\"thr\",\"-\",\"aa\"],[1,\"thr\",\"+\",\"aa\"],\"v\"]]]]]},externals:{HP_DEG_TO_RAD:()=>hC,\"std.cos\":()=>pe,\"std.sin\":()=>ae,HP_TAU:()=>md,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"std.smoothstep\":()=>be}})&&e.f)({})),gC=w.fn([m,m,n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i)=>{\"use gpu\";let l=t.sub(s),c=he(l),d=Xt(l.y,l.x),u=pe(__tsover_add(__tsover_mul(__tsover_sub(__tsover_mul(c,r),__tsover_mul(d,__tsover_div(1,md))),md),o)),p=K(-1.15,1.15,G(a,0,1));return be(__tsover_sub(p,i),__tsover_add(p,i),u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p\"},{type:\"i\",name:\"c\"},{type:\"i\",name:\"frequency\"},{type:\"i\",name:\"reliefPhase\"},{type:\"i\",name:\"level\"},{type:\"i\",name:\"aa\"}],body:[0,[[13,\"dv\",[6,[7,\"p\",\"sub\"],[\"c\"]]],[13,\"r\",[6,\"std.length\",[\"dv\"]]],[13,\"theta\",[6,\"std.atan2\",[[7,\"dv\",\"y\"],[7,\"dv\",\"x\"]]]],[13,\"phase\",[1,[1,[1,[1,\"r\",\"*\",\"frequency\"],\"-\",[1,\"theta\",\"*\",[1,[5,\"1\"],\"/\",\"HP_TAU\"]]],\"*\",\"HP_TAU\"],\"+\",\"reliefPhase\"]],[13,\"v\",[6,\"std.cos\",[\"phase\"]]],[13,\"thr\",[6,\"std.mix\",[[4,\"-\",[5,\"1.15\"]],[5,\"1.15\"],[6,\"std.clamp\",[\"level\",[5,\"0\"],[5,\"1\"]]]]]],[10,[6,\"std.smoothstep\",[[1,\"thr\",\"-\",\"aa\"],[1,\"thr\",\"+\",\"aa\"],\"v\"]]]]]},externals:{\"std.length\":()=>he,\"std.atan2\":()=>Xt,HP_TAU:()=>md,\"std.cos\":()=>pe,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"std.smoothstep\":()=>be}})&&e.f)({}));function Cce(e){return w.fn([S,m,n,S,S,m,S,S],S)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o,a,i,l,c,d)=>{\"use gpu\";let u=c.x,p=c.y,_=c.z,f=c.w,h=d.x,g=d.y,y=Se(A(s.x,s.y,s.z),A(.299,.587,.114)),b=G(__tsover_add(.5,__tsover_mul(__tsover_sub(y,.5),h)),0,1),x=m(__tsover_mul(r.x,o),r.y),P=la(x.mul(3.1)),C=la(x.mul(3.1).add(m(7.31,3.77))),E=x.add(m(P,C).mul(__tsover_mul(f,.06))),R=G(__tsover_div(__tsover_mul(p,md),B(g,1)),.02,1),U=__tsover_mul(__tsover_mul(_,b),9.42),L=n(0);if(e===2)L=gC(E,m(__tsover_mul(l.x,o),__tsover_sub(1,l.y)),p,U,b,R);else if(e===1){let O=_m(E,u,p,U,b,R),F=G(__tsover_div(b,.55),0,1),q=_m(E,__tsover_add(u,72),__tsover_mul(p,.92),__tsover_mul(U,.7),F,R),Y=G(__tsover_div(b,.28),0,1);L=B(O,B(q,_m(E,__tsover_sub(u,38),__tsover_mul(p,1.13),__tsover_mul(U,.5),Y,R)))}else L=_m(E,u,p,U,b,R);let k=K(A(a.x,a.y,a.z),A(i.x,i.y,i.z),A(L)),D=__tsover_mul(s.w,K(a.w,i.w,L));return S(k.x,k.y,k.z,D)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"childColor\"},{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"paper\"},{type:\"i\",name:\"ink\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"p0\"},{type:\"i\",name:\"p1\"}],body:[0,[[13,\"angleDeg\",[7,\"p0\",\"x\"]],[13,\"frequency\",[7,\"p0\",\"y\"]],[13,\"relief\",[7,\"p0\",\"z\"]],[13,\"waviness\",[7,\"p0\",\"w\"]],[13,\"contrast\",[7,\"p1\",\"x\"]],[13,\"viewportY\",[7,\"p1\",\"y\"]],[13,\"lum\",[6,\"std.dot\",[[6,\"d.vec3f\",[[7,\"childColor\",\"x\"],[7,\"childColor\",\"y\"],[7,\"childColor\",\"z\"]]],[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]],[13,\"level\",[6,\"std.clamp\",[[1,[5,\"0.5\"],\"+\",[1,[1,\"lum\",\"-\",[5,\"0.5\"]],\"*\",\"contrast\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"pa\",[6,\"d.vec2f\",[[1,[7,\"uv\",\"x\"],\"*\",\"aspect\"],[7,\"uv\",\"y\"]]]],[13,\"nx\",[6,\"noise.mxNoiseFloat2\",[[6,[7,\"pa\",\"mul\"],[[5,\"3.1\"]]]]]],[13,\"ny\",[6,\"noise.mxNoiseFloat2\",[[6,[7,[6,[7,\"pa\",\"mul\"],[[5,\"3.1\"]]],\"add\"],[[6,\"d.vec2f\",[[5,\"7.31\"],[5,\"3.77\"]]]]]]]],[13,\"p\",[6,[7,\"pa\",\"add\"],[[6,[7,[6,\"d.vec2f\",[\"nx\",\"ny\"]],\"mul\"],[[1,\"waviness\",\"*\",[5,\"0.06\"]]]]]]],[13,\"aa\",[6,\"std.clamp\",[[1,[1,\"frequency\",\"*\",\"HP_TAU\"],\"/\",[6,\"std.max\",[\"viewportY\",[5,\"1\"]]]],[5,\"0.02\"],[5,\"1\"]]]],[13,\"reliefPhase\",[1,[1,\"relief\",\"*\",\"level\"],\"*\",[5,\"9.42\"]]],[12,\"cover\",[6,\"d.f32\",[[5,\"0\"]]]],[11,[1,\"style\",\"===\",[5,\"2\"]],[0,[[13,\"sc\",[6,\"d.vec2f\",[[1,[7,\"center\",\"x\"],\"*\",\"aspect\"],[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]]]],[2,\"cover\",\"=\",[6,\"spiralPlate\",[\"p\",\"sc\",\"frequency\",\"reliefPhase\",\"level\",\"aa\"]]]]],[11,[1,\"style\",\"===\",[5,\"1\"]],[0,[[13,\"ink1\",[6,\"hatchPlate\",[\"p\",\"angleDeg\",\"frequency\",\"reliefPhase\",\"level\",\"aa\"]]],[13,\"level2\",[6,\"std.clamp\",[[1,\"level\",\"/\",[5,\"0.55\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"ink2\",[6,\"hatchPlate\",[\"p\",[1,\"angleDeg\",\"+\",[5,\"72\"]],[1,\"frequency\",\"*\",[5,\"0.92\"]],[1,\"reliefPhase\",\"*\",[5,\"0.7\"]],\"level2\",\"aa\"]]],[13,\"level3\",[6,\"std.clamp\",[[1,\"level\",\"/\",[5,\"0.28\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"ink3\",[6,\"hatchPlate\",[\"p\",[1,\"angleDeg\",\"-\",[5,\"38\"]],[1,\"frequency\",\"*\",[5,\"1.13\"]],[1,\"reliefPhase\",\"*\",[5,\"0.5\"]],\"level3\",\"aa\"]]],[2,\"cover\",\"=\",[6,\"std.max\",[\"ink1\",[6,\"std.max\",[\"ink2\",\"ink3\"]]]]]]],[0,[[2,\"cover\",\"=\",[6,\"hatchPlate\",[\"p\",\"angleDeg\",\"frequency\",\"reliefPhase\",\"level\",\"aa\"]]]]]]],[13,\"rgb\",[6,\"std.mix\",[[6,\"d.vec3f\",[[7,\"paper\",\"x\"],[7,\"paper\",\"y\"],[7,\"paper\",\"z\"]]],[6,\"d.vec3f\",[[7,\"ink\",\"x\"],[7,\"ink\",\"y\"],[7,\"ink\",\"z\"]]],[6,\"d.vec3f\",[\"cover\"]]]]],[13,\"alpha\",[1,[7,\"childColor\",\"w\"],\"*\",[6,\"std.mix\",[[7,\"paper\",\"w\"],[7,\"ink\",\"w\"],\"cover\"]]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"alpha\"]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"d.vec2f\":()=>m,\"noise.mxNoiseFloat2\":()=>la,HP_TAU:()=>md,\"std.max\":()=>B,\"d.f32\":()=>n,style:()=>e,spiralPlate:()=>gC,hatchPlate:()=>_m,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&t.f)({})).$name(`lineworkComposite_${e}`)}var Mce={line:0,crosshatch:1,spiral:2};function J8(e){return Rd({resultAlpha:\"straight\",build:({sampleStraight:t,ctx:s,uniforms:r,propValues:o})=>{let a=t(s.uv),i=o[e.style.name],l=typeof i==\"number\"?i:Mce[String(i)]??1,c=Cce(l),d=Ct(r[e.angle.name],r[e.frequency.name],r[e.relief.name],r[e.waviness.name]),u=Ct(r[e.contrast.name],s.viewportSize.member(\"y\"),$e(0),$e(0));return W(c,`lineworkComposite_${l}`,[a,s.uv,s.aspect,r[e.paper.name],r[e.ink.name],r[e.center.name],d,u])}})}var uu=gt({pos:m,dir:m,spd:n}).$name(\"AgentPose\");function Ece(e,t){let s=e,r=cz(t.shape,{comet:t.comet}),o=t.res,a=1/o,i=.75*a,l=t.splatRCap,c=r.ext,d=r.soft?rh.SOFT:rh.HARD,u=t.home,p=t.heading===\"angle\"?w.fn([M],uu)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=(b=>{\"use gpu\";let x=s.$.agents[b],P=u(n(b));return uu({pos:m(__tsover_add(P.x,x.x),__tsover_add(P.y,x.y)),dir:m(pe(x.z),ae(x.z)),spd:n(0)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"a\",[8,[7,[7,\"L\",\"$\"],\"agents\"],\"i\"]],[13,\"homeP\",[6,\"home\",[[6,\"d.f32\",[\"i\"]]]]],[10,[6,\"AgentPose\",[[104,{pos:[6,\"d.vec2f\",[[1,[7,\"homeP\",\"x\"],\"+\",[7,\"a\",\"x\"]],[1,[7,\"homeP\",\"y\"],\"+\",[7,\"a\",\"y\"]]]],dir:[6,\"d.vec2f\",[[6,\"std.cos\",[[7,\"a\",\"z\"]]],[6,\"std.sin\",[[7,\"a\",\"z\"]]]]],spd:[6,\"d.f32\",[[5,\"0\"]]]}]]]]]]},externals:{L:()=>s,home:()=>u,\"d.f32\":()=>n,AgentPose:()=>uu,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&y.f)({})).$name(`${t.name}Pose`):w.fn([M],uu)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=(b=>{\"use gpu\";let x=s.$.agents[b],P=m(x.z,x.w),C=he(P);return uu({pos:m(x.x,x.y),dir:N(m(1,0),P.div(B(C,1e-5)),C>1e-5),spd:C})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"a\",[8,[7,[7,\"L\",\"$\"],\"agents\"],\"i\"]],[13,\"vel\",[6,\"d.vec2f\",[[7,\"a\",\"z\"],[7,\"a\",\"w\"]]]],[13,\"spd\",[6,\"std.length\",[\"vel\"]]],[10,[6,\"AgentPose\",[[104,{pos:[6,\"d.vec2f\",[[7,\"a\",\"x\"],[7,\"a\",\"y\"]]],dir:[6,\"std.select\",[[6,\"d.vec2f\",[[5,\"1\"],[5,\"0\"]]],[6,[7,\"vel\",\"div\"],[[6,\"std.max\",[\"spd\",[5,\"0.00001\"]]]]],[1,\"spd\",\">\",[5,\"0.00001\"]]]],spd:\"spd\"}]]]]]]},externals:{L:()=>s,\"d.vec2f\":()=>m,\"std.length\":()=>he,AgentPose:()=>uu,\"std.select\":()=>N,\"std.max\":()=>B}})&&y.f)({})).$name(`${t.name}Pose`),_=t.agitation===\"buffer\"?w.fn([M,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";return G(s.$.agit[b],0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"},{type:\"i\",name:\"_spd\"}],body:[0,[[10,[6,\"std.clamp\",[[8,[7,[7,\"L\",\"$\"],\"agit\"],\"i\"],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G,L:()=>s}})&&y.f)({})).$name(`${t.name}Excitement`):w.fn([M,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x)=>{\"use gpu\";return G(__tsover_div(x,B(s.$.params.speedNorm,1e-5)),0,1)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_i\"},{type:\"i\",name:\"spd\"}],body:[0,[[10,[6,\"std.clamp\",[[1,\"spd\",\"/\",[6,\"std.max\",[[7,[7,[7,\"L\",\"$\"],\"params\"],\"speedNorm\"],[5,\"0.00001\"]]]],[5,\"0\"],[5,\"1\"]]]]]]},externals:{\"std.clamp\":()=>G,\"std.max\":()=>B,L:()=>s}})&&y.f)({})).$name(`${t.name}Excitement`),f=Yne(t.shape),h=k_(r.name),g=t.comet&&!r.symmetric?w.fn([n,n,n,m,n,n,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x,P,C,E,R,U)=>{\"use gpu\";return f(__tsover_add(__tsover_mul(x,C.x),__tsover_mul(P,C.y)),__tsover_add(__tsover_mul(x,-C.y),__tsover_mul(P,C.x)),E,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_dSq\"},{type:\"i\",name:\"offX\"},{type:\"i\",name:\"offY\"},{type:\"i\",name:\"dir\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"_bodyRSq\"},{type:\"i\",name:\"aaW\"}],body:[0,[[13,\"t\",[1,[1,\"offX\",\"*\",[7,\"dir\",\"x\"]],\"+\",[1,\"offY\",\"*\",[7,\"dir\",\"y\"]]]],[13,\"n\",[1,[1,\"offX\",\"*\",[4,\"-\",[7,\"dir\",\"y\"]]],\"+\",[1,\"offY\",\"*\",[7,\"dir\",\"x\"]]]],[10,[6,\"cometWeight\",[\"t\",\"n\",\"bodyR\",\"aaW\"]]]]]},externals:{cometWeight:()=>f}})&&y.f)({})).$name(`${t.name}Weight`):r.symmetric?w.fn([n,n,n,m,n,n,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x,P,C,E,R,U)=>{\"use gpu\";return h(__tsover_div(b,R),x,P,E,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dSq\"},{type:\"i\",name:\"offX\"},{type:\"i\",name:\"offY\"},{type:\"i\",name:\"_dir\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"bodyRSq\"},{type:\"i\",name:\"aaW\"}],body:[0,[[10,[6,\"plainWeight\",[[1,\"dSq\",\"/\",\"bodyRSq\"],\"offX\",\"offY\",\"bodyR\",\"aaW\"]]]]]},externals:{plainWeight:()=>h}})&&y.f)({})).$name(`${t.name}Weight`):w.fn([n,n,n,m,n,n,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x,P,C,E,R,U)=>{\"use gpu\";let L=__tsover_add(__tsover_mul(x,C.x),__tsover_mul(P,C.y)),k=__tsover_add(__tsover_mul(x,-C.y),__tsover_mul(P,C.x));return h(__tsover_div(b,R),L,k,E,U)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"dSq\"},{type:\"i\",name:\"offX\"},{type:\"i\",name:\"offY\"},{type:\"i\",name:\"dir\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"bodyRSq\"},{type:\"i\",name:\"aaW\"}],body:[0,[[13,\"t\",[1,[1,\"offX\",\"*\",[7,\"dir\",\"x\"]],\"+\",[1,\"offY\",\"*\",[7,\"dir\",\"y\"]]]],[13,\"n\",[1,[1,\"offX\",\"*\",[4,\"-\",[7,\"dir\",\"y\"]]],\"+\",[1,\"offY\",\"*\",[7,\"dir\",\"x\"]]]],[10,[6,\"plainWeight\",[[1,\"dSq\",\"/\",\"bodyRSq\"],\"t\",\"n\",\"bodyR\",\"aaW\"]]]]]},externals:{plainWeight:()=>h}})&&y.f)({})).$name(`${t.name}Weight`);return w.fn([M])((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=(b=>{\"use gpu\";let x=s.$.params,P=p(b),C=_(b,P.spd),E=__tsover_mul(C,n(d)),R=B(x.aspect,1e-5),U=G(x.bodyR,1e-6,__tsover_mul(n(l),a)),L=__tsover_mul(U,U),k=__tsover_add(__tsover_mul(U,c),__tsover_mul(i,2)),D=__tsover_mul(k,k),O=oh(P.pos,k,R,n(o));for(let F=O.y0;F<=O.y1;F++){let q=__tsover_sub(__tsover_mul(__tsover_add(n(F),.5),a),P.pos.y),Y=__tsover_mul(q,q);for(let V=O.x0;V<=O.x1;V++){let X=__tsover_sub(__tsover_mul(__tsover_mul(__tsover_add(n(V),.5),a),R),P.pos.x),Q=__tsover_add(__tsover_mul(X,X),Y);if(Q<D){let te=g(Q,X,q,P.dir,U,L,i),J=M(__tsover_mul(te,n(d)));if(J>M(0)){let oe=M(__tsover_add(__tsover_mul(F,j(o)),V));wa(s.$.accumE[oe],J),C>0&&wa(s.$.accumS[oe],M(__tsover_mul(te,E)))}}}}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"L\",\"$\"],\"params\"]],[13,\"p\",[6,\"pose\",[\"i\"]]],[13,\"agitI\",[6,\"excitement\",[\"i\",[7,\"p\",\"spd\"]]]],[13,\"agitGain\",[1,\"agitI\",\"*\",[6,\"d.f32\",[\"GAIN\"]]]],[13,\"aspect\",[6,\"std.max\",[[7,\"prm\",\"aspect\"],[5,\"0.00001\"]]]],[13,\"bodyR\",[6,\"std.clamp\",[[7,\"prm\",\"bodyR\"],[5,\"0.000001\"],[1,[6,\"d.f32\",[\"SPLAT_R\"]],\"*\",\"INV_RES\"]]]],[13,\"bodyRSq\",[1,\"bodyR\",\"*\",\"bodyR\"]],[13,\"radW\",[1,[1,\"bodyR\",\"*\",\"EXT\"],\"+\",[1,\"AA_W\",\"*\",[5,\"2\"]]]],[13,\"extSq\",[1,\"radW\",\"*\",\"radW\"]],[13,\"win\",[6,\"worldSplatWindow\",[[7,\"p\",\"pos\"],\"radW\",\"aspect\",[6,\"d.f32\",[\"RES\"]]]]],[14,[12,\"py\",[7,\"win\",\"y0\"]],[1,\"py\",\"<=\",[7,\"win\",\"y1\"]],[102,\"++\",\"py\"],[0,[[13,\"offY\",[1,[1,[1,[6,\"d.f32\",[\"py\"]],\"+\",[5,\"0.5\"]],\"*\",\"INV_RES\"],\"-\",[7,[7,\"p\",\"pos\"],\"y\"]]],[13,\"offYSq\",[1,\"offY\",\"*\",\"offY\"]],[14,[12,\"px\",[7,\"win\",\"x0\"]],[1,\"px\",\"<=\",[7,\"win\",\"x1\"]],[102,\"++\",\"px\"],[0,[[13,\"offX\",[1,[1,[1,[1,[6,\"d.f32\",[\"px\"]],\"+\",[5,\"0.5\"]],\"*\",\"INV_RES\"],\"*\",\"aspect\"],\"-\",[7,[7,\"p\",\"pos\"],\"x\"]]],[13,\"dSq\",[1,[1,\"offX\",\"*\",\"offX\"],\"+\",\"offYSq\"]],[11,[1,\"dSq\",\"<\",\"extSq\"],[0,[[13,\"w\",[6,\"texelWeight\",[\"dSq\",\"offX\",\"offY\",[7,\"p\",\"dir\"],\"bodyR\",\"bodyRSq\",\"AA_W\"]]],[13,\"e\",[6,\"d.u32\",[[1,\"w\",\"*\",[6,\"d.f32\",[\"GAIN\"]]]]]],[11,[1,\"e\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],[0,[[13,\"idx\",[6,\"d.u32\",[[1,[1,\"py\",\"*\",[6,\"d.i32\",[\"RES\"]]],\"+\",\"px\"]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"L\",\"$\"],\"accumE\"],\"idx\"],\"e\"]],[11,[1,\"agitI\",\">\",[5,\"0\"]],[0,[[6,\"std.atomicAdd\",[[8,[7,[7,\"L\",\"$\"],\"accumS\"],\"idx\"],[6,\"d.u32\",[[1,\"w\",\"*\",\"agitGain\"]]]]]]]]]]]]]]]]]]]]]]},externals:{L:()=>s,pose:()=>p,excitement:()=>_,\"d.f32\":()=>n,GAIN:()=>d,\"std.max\":()=>B,\"std.clamp\":()=>G,SPLAT_R:()=>l,INV_RES:()=>a,EXT:()=>c,AA_W:()=>i,worldSplatWindow:()=>oh,RES:()=>o,texelWeight:()=>g,\"d.u32\":()=>M,\"d.i32\":()=>j,\"std.atomicAdd\":()=>wa}})&&y.f)({})).$name(t.name)}var Dg={orbitalPlace(e,t){let s=t.rate,r=t.radius,o=6.283185307179586;return w.fn([n,m],m)((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=((i,l)=>{\"use gpu\";let c=e.$.params,d=Pr(m(__tsover_add(__tsover_mul(i,2.41),.37),__tsover_add(__tsover_mul(i,.577),8.19))),u=__tsover_mul(__tsover_mul(__tsover_add(.5,d.x),s),c.randomness),p=__tsover_mul(d.y,o),_=__tsover_mul(__tsover_mul(r,c.randomness),__tsover_add(.5,__tsover_mul(d.x,.5))),f=__tsover_add(__tsover_mul(c.time,u),p);return l.add(m(pe(f),ae(f)).mul(_))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"},{type:\"i\",name:\"stored\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"h\",[6,\"noise.hash22\",[[6,\"d.vec2f\",[[1,[1,\"fi\",\"*\",[5,\"2.41\"]],\"+\",[5,\"0.37\"]],[1,[1,\"fi\",\"*\",[5,\"0.577\"]],\"+\",[5,\"8.19\"]]]]]]],[13,\"rate\",[1,[1,[1,[5,\"0.5\"],\"+\",[7,\"h\",\"x\"]],\"*\",\"RATE\"],\"*\",[7,\"prm\",\"randomness\"]]],[13,\"ph\",[1,[7,\"h\",\"y\"],\"*\",\"TAU\"]],[13,\"rad\",[1,[1,\"RAD\",\"*\",[7,\"prm\",\"randomness\"]],\"*\",[1,[5,\"0.5\"],\"+\",[1,[7,\"h\",\"x\"],\"*\",[5,\"0.5\"]]]]],[13,\"t\",[1,[1,[7,\"prm\",\"time\"],\"*\",\"rate\"],\"+\",\"ph\"]],[10,[6,[7,\"stored\",\"add\"],[[6,[7,[6,\"d.vec2f\",[[6,\"std.cos\",[\"t\"]],[6,\"std.sin\",[\"t\"]]]],\"mul\"],[\"rad\"]]]]]]]},externals:{layout:()=>e,\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m,RATE:()=>s,TAU:()=>o,RAD:()=>r,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&a.f)({})).$name(\"pointSlotOrbitalPlace\")},twinkleBrightness(e,t){let s=t.freq,r=6.283185307179586;return w.fn([n],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=(a=>{\"use gpu\";let i=e.$.params,l=__tsover_mul(Xs(__tsover_add(__tsover_mul(a,3.7),.93)),r),c=__tsover_add(__tsover_mul(ae(__tsover_add(__tsover_mul(i.time,s),l)),.5),.5);return __tsover_mul(K(n(1),c,i.twinkle),__tsover_add(.4,__tsover_mul(.6,h1(a))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"ph\",[1,[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"3.7\"]],\"+\",[5,\"0.93\"]]]],\"*\",\"TAU\"]],[13,\"twk\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"prm\",\"time\"],\"*\",\"FREQ\"],\"+\",\"ph\"]]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[10,[1,[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],\"twk\",[7,\"prm\",\"twinkle\"]]],\"*\",[1,[5,\"0.4\"],\"+\",[1,[5,\"0.6\"],\"*\",[6,\"agents.presenceVariation\",[\"fi\"]]]]]]]]},externals:{layout:()=>e,\"noise.hash11\":()=>Xs,TAU:()=>r,\"std.sin\":()=>ae,FREQ:()=>s,\"std.mix\":()=>K,\"d.f32\":()=>n,\"agents.presenceVariation\":()=>h1}})&&o.f)({})).$name(\"pointSlotTwinkleBrightness\")},presenceRadius(e){return w.fn([n],n)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=(s=>{\"use gpu\";return B(__tsover_mul(e.$.params.bodyR,__tsover_add(.55,__tsover_mul(.45,h1(s)))),1e-6)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[10,[6,\"std.max\",[[1,[7,[7,[7,\"layout\",\"$\"],\"params\"],\"bodyR\"],\"*\",[1,[5,\"0.55\"],\"+\",[1,[5,\"0.45\"],\"*\",[6,\"agents.presenceVariation\",[\"fi\"]]]]],[5,\"0.000001\"]]]]]]},externals:{\"std.max\":()=>B,layout:()=>e,\"agents.presenceVariation\":()=>h1}})&&t.f)({})).$name(\"pointSlotPresenceRadius\")}};function kce(e,t){let s=zd[wd(t.shape,\"dot\")],r=wd(t.shape,\"dot\"),o=s.soft,a=s.ext,i=t.res,l=1/i,c=.75*l,d=rh.HARD,u=rh.SOFT,{place:p,brightness:_,bodyRadius:f}=t,h=s.soft===1?(()=>{let g=k_(r);return w.fn([n,n,n,n,n,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x,P,C,E,R)=>{\"use gpu\";return g(b,x,P,C,E)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"},{type:\"i\",name:\"_soft\"}],body:[0,[[10,[6,\"fast\",[\"q\",\"t\",\"n\",\"bodyR\",\"aaW\"]]]]]},externals:{fast:()=>g}})&&y.f)({})).$name(\"agentPointWeight\")})():(()=>{let g=Ine(r);return w.fn([n,n,n,n,n,n],n)((y=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(y.f=((b,x,P,C,E,R)=>{\"use gpu\";return g(x,P,C,E,R)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_q\"},{type:\"i\",name:\"t\"},{type:\"i\",name:\"n\"},{type:\"i\",name:\"bodyR\"},{type:\"i\",name:\"aaW\"},{type:\"i\",name:\"soft\"}],body:[0,[[10,[6,\"general\",[\"t\",\"n\",\"bodyR\",\"aaW\",\"soft\"]]]]]},externals:{general:()=>g}})&&y.f)({})).$name(\"agentPointWeight\")})();return w.fn([M])((g=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(g.f=(y=>{\"use gpu\";let b=e.$.params,x=e.$.agents[y],P=n(y),C=p(P,m(x.x,x.y)),E=_(P),R=B(b.aspect,1e-5),U=B(b.softness,n(o)),L=K(n(a),B(n(a),2.4),U),k=K(n(d),n(u),U),D=f(P),O=__tsover_div(1,D),F=__tsover_add(__tsover_mul(D,L),__tsover_mul(c,2)),q=__tsover_mul(__tsover_mul(F,O),__tsover_mul(F,O)),Y=oh(C,F,R,n(i));for(let V=Y.y0;V<=Y.y1;V++){let X=__tsover_sub(__tsover_mul(__tsover_add(n(V),.5),l),C.y);for(let Q=Y.x0;Q<=Y.x1;Q++){let te=__tsover_sub(__tsover_mul(__tsover_mul(__tsover_add(n(Q),.5),l),R),C.x),J=__tsover_mul(__tsover_mul(__tsover_add(__tsover_mul(te,te),__tsover_mul(X,X)),O),O);if(J<q){let oe=__tsover_mul(h(J,te,X,D,c,U),E),le=M(__tsover_mul(oe,k));if(le>M(0)){let se=M(__tsover_add(__tsover_mul(V,i),Q));wa(e.$.accumE[se],le)}}}}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"s4\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"pos\",[6,\"place\",[\"fi\",[6,\"d.vec2f\",[[7,\"s4\",\"x\"],[7,\"s4\",\"y\"]]]]]],[13,\"bright\",[6,\"brightness\",[\"fi\"]]],[13,\"aspect\",[6,\"std.max\",[[7,\"prm\",\"aspect\"],[5,\"0.00001\"]]]],[13,\"softV\",[6,\"std.max\",[[7,\"prm\",\"softness\"],[6,\"d.f32\",[\"FORCE_SOFT\"]]]]],[13,\"extK\",[6,\"std.mix\",[[6,\"d.f32\",[\"EXT\"]],[6,\"std.max\",[[6,\"d.f32\",[\"EXT\"]],[5,\"2.4\"]]],\"softV\"]]],[13,\"gain\",[6,\"std.mix\",[[6,\"d.f32\",[\"HARD_GAIN\"]],[6,\"d.f32\",[\"SOFT_GAIN\"]],\"softV\"]]],[13,\"bodyR\",[6,\"bodyRadius\",[\"fi\"]]],[13,\"invBodyR\",[1,[5,\"1\"],\"/\",\"bodyR\"]],[13,\"reach\",[1,[1,\"bodyR\",\"*\",\"extK\"],\"+\",[1,\"AA_W\",\"*\",[5,\"2\"]]]],[13,\"reachQ\",[1,[1,\"reach\",\"*\",\"invBodyR\"],\"*\",[1,\"reach\",\"*\",\"invBodyR\"]]],[13,\"win\",[6,\"worldSplatWindow\",[\"pos\",\"reach\",\"aspect\",[6,\"d.f32\",[\"RES\"]]]]],[14,[12,\"py\",[7,\"win\",\"y0\"]],[1,\"py\",\"<=\",[7,\"win\",\"y1\"]],[102,\"++\",\"py\"],[0,[[13,\"offY\",[1,[1,[1,[6,\"d.f32\",[\"py\"]],\"+\",[5,\"0.5\"]],\"*\",\"INV_RES\"],\"-\",[7,\"pos\",\"y\"]]],[14,[12,\"px\",[7,\"win\",\"x0\"]],[1,\"px\",\"<=\",[7,\"win\",\"x1\"]],[102,\"++\",\"px\"],[0,[[13,\"offX\",[1,[1,[1,[1,[6,\"d.f32\",[\"px\"]],\"+\",[5,\"0.5\"]],\"*\",\"INV_RES\"],\"*\",\"aspect\"],\"-\",[7,\"pos\",\"x\"]]],[13,\"q\",[1,[1,[1,[1,\"offX\",\"*\",\"offX\"],\"+\",[1,\"offY\",\"*\",\"offY\"]],\"*\",\"invBodyR\"],\"*\",\"invBodyR\"]],[11,[1,\"q\",\"<\",\"reachQ\"],[0,[[13,\"w\",[1,[6,\"weightFn\",[\"q\",\"offX\",\"offY\",\"bodyR\",\"AA_W\",\"softV\"]],\"*\",\"bright\"]],[13,\"e\",[6,\"d.u32\",[[1,\"w\",\"*\",\"gain\"]]]],[11,[1,\"e\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],[0,[[13,\"idx\",[6,\"d.u32\",[[1,[1,\"py\",\"*\",\"RES\"],\"+\",\"px\"]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumE\"],\"idx\"],\"e\"]]]]]]]]]]]]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,place:()=>p,\"d.vec2f\":()=>m,brightness:()=>_,\"std.max\":()=>B,FORCE_SOFT:()=>o,\"std.mix\":()=>K,EXT:()=>a,HARD_GAIN:()=>d,SOFT_GAIN:()=>u,bodyRadius:()=>f,AA_W:()=>c,worldSplatWindow:()=>oh,RES:()=>i,INV_RES:()=>l,weightFn:()=>h,\"d.u32\":()=>M,\"std.atomicAdd\":()=>wa}})&&g.f)({})).$name(t.name)}function Bce(e,t){let s=w.fn([n,n,n,n,n],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i,l,c,d)=>{\"use gpu\";return Tt(__tsover_mul(a,-2.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"_ddx\"},{type:\"i\",name:\"_ddy\"},{type:\"i\",name:\"_size\"},{type:\"i\",name:\"_soft\"}],body:[0,[[10,[6,\"std.exp\",[[1,\"q\",\"*\",[4,\"-\",[5,\"2.5\"]]]]]]]]},externals:{\"std.exp\":()=>Tt}})&&o.f)({})).$name(t.glow);if(zd[e].soft===1)return s;let r=k_(e);return w.fn([n,n,n,n,n],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i,l,c,d)=>{\"use gpu\";return K(r(a,i,l,c,.9),Tt(__tsover_mul(a,-2.5)),d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"q\"},{type:\"i\",name:\"ddx\"},{type:\"i\",name:\"ddy\"},{type:\"i\",name:\"size\"},{type:\"i\",name:\"soft\"}],body:[0,[[13,\"wHard\",[6,\"weightFn\",[\"q\",\"ddx\",\"ddy\",\"size\",[5,\"0.9\"]]]],[13,\"wSoft\",[6,\"std.exp\",[[1,\"q\",\"*\",[4,\"-\",[5,\"2.5\"]]]]]],[10,[6,\"std.mix\",[\"wHard\",\"wSoft\",\"soft\"]]]]]},externals:{weightFn:()=>r,\"std.exp\":()=>Tt,\"std.mix\":()=>K}})&&o.f)({})).$name(t.blend)}function zce(e,t){let s=Bce(wd(t.shape,\"dot\"),{glow:t.names.glow,blend:t.names.profile}),r=t.outRes,o=t.maxSplatSize,a=t.extQ,i=Math.sqrt(t.extQ);return w.fn([M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=(c=>{\"use gpu\";let d=e.$.params,u=e.$.pos[c],p=e.$.vel[c],_=__tsover_div(1,G(__tsover_sub(1,__tsover_mul(u.z,.35)),.45,2)),f=__tsover_mul(u.x,_),h=__tsover_mul(__tsover_mul(u.y,_),-1),g=__tsover_sub(__tsover_mul(f,d.rotC),__tsover_mul(h,d.rotS)),y=__tsover_add(__tsover_mul(h,d.rotC),__tsover_mul(f,d.rotS)),b=__tsover_add(d.centerX,__tsover_div(__tsover_mul(g,d.scale),d.aspect)),x=__tsover_add(d.centerYv,__tsover_mul(y,d.scale)),P=n(r),C=__tsover_mul(b,P),E=__tsover_mul(x,P),R=G(__tsover_mul(__tsover_mul(__tsover_mul(d.size,__tsover_add(.65,__tsover_mul(.7,u.w))),_),d.scale),.6,n(o)),U=__tsover_mul(__tsover_mul(__tsover_add(.7,__tsover_mul(.6,u.w)),_),_),L=G(__tsover_mul(p.w,d.speedColorK),0,1),k=__tsover_mul(__tsover_mul(U,L),256)>=1,D=j(nl(__tsover_mul(R,n(i)))),O=n(D);if(C>__tsover_mul(O,-1)&&C<__tsover_add(P,O)&&E>__tsover_mul(O,-1)&&E<__tsover_add(P,O)){let F=ah(m(C,E),D,nc(j(__tsover_sub(r,1)),j(__tsover_sub(r,1)))),q=B(__tsover_mul(R,R),.01);for(let Y=F.y0;Y<=F.y1;Y++){let V=__tsover_sub(__tsover_add(n(Y),.5),E),X=__tsover_mul(V,V);for(let Q=F.x0;Q<=F.x1;Q++){let te=__tsover_sub(__tsover_add(n(Q),.5),C),J=__tsover_div(__tsover_add(__tsover_mul(te,te),X),q);if(J<a){let oe=s(J,te,V,R,d.softness),le=M(__tsover_mul(__tsover_mul(oe,U),256));if(le>M(0)){let se=M(__tsover_add(__tsover_mul(Y,j(r)),Q));wa(e.$.accumE[se],le),k&&wa(e.$.accumS[se],M(__tsover_mul(__tsover_mul(__tsover_mul(oe,U),L),256)))}}}}}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"pos\",[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"]],[13,\"vel\",[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"]],[13,\"persp\",[1,[5,\"1\"],\"/\",[6,\"std.clamp\",[[1,[5,\"1\"],\"-\",[1,[7,\"pos\",\"z\"],\"*\",[5,\"0.35\"]]],[5,\"0.45\"],[5,\"2\"]]]]],[13,\"xs\",[1,[7,\"pos\",\"x\"],\"*\",\"persp\"]],[13,\"ys\",[1,[1,[7,\"pos\",\"y\"],\"*\",\"persp\"],\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"rx\",[1,[1,\"xs\",\"*\",[7,\"prm\",\"rotC\"]],\"-\",[1,\"ys\",\"*\",[7,\"prm\",\"rotS\"]]]],[13,\"ry\",[1,[1,\"ys\",\"*\",[7,\"prm\",\"rotC\"]],\"+\",[1,\"xs\",\"*\",[7,\"prm\",\"rotS\"]]]],[13,\"u\",[1,[7,\"prm\",\"centerX\"],\"+\",[1,[1,\"rx\",\"*\",[7,\"prm\",\"scale\"]],\"/\",[7,\"prm\",\"aspect\"]]]],[13,\"v\",[1,[7,\"prm\",\"centerYv\"],\"+\",[1,\"ry\",\"*\",[7,\"prm\",\"scale\"]]]],[13,\"outF\",[6,\"d.f32\",[\"OUT_RES\"]]],[13,\"tx\",[1,\"u\",\"*\",\"outF\"]],[13,\"ty\",[1,\"v\",\"*\",\"outF\"]],[13,\"size\",[6,\"std.clamp\",[[1,[1,[1,[7,\"prm\",\"size\"],\"*\",[1,[5,\"0.65\"],\"+\",[1,[5,\"0.7\"],\"*\",[7,\"pos\",\"w\"]]]],\"*\",\"persp\"],\"*\",[7,\"prm\",\"scale\"]],[5,\"0.6\"],[6,\"d.f32\",[\"MAX_SPLAT_SIZE\"]]]]],[13,\"bright\",[1,[1,[1,[5,\"0.7\"],\"+\",[1,[5,\"0.6\"],\"*\",[7,\"pos\",\"w\"]]],\"*\",\"persp\"],\"*\",\"persp\"]],[13,\"speedNorm\",[6,\"std.clamp\",[[1,[7,\"vel\",\"w\"],\"*\",[7,\"prm\",\"speedColorK\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"doSpeed\",[1,[1,[1,\"bright\",\"*\",\"speedNorm\"],\"*\",[5,\"256\"]],\">=\",[5,\"1\"]]],[13,\"rad\",[6,\"d.i32\",[[6,\"std.ceil\",[[1,\"size\",\"*\",[6,\"d.f32\",[\"EXT\"]]]]]]]],[13,\"radF\",[6,\"d.f32\",[\"rad\"]]],[13,\"onTarget\",[3,[3,[3,[1,\"tx\",\">\",[1,\"radF\",\"*\",[4,\"-\",[5,\"1\"]]]],\"&&\",[1,\"tx\",\"<\",[1,\"outF\",\"+\",\"radF\"]]],\"&&\",[1,\"ty\",\">\",[1,\"radF\",\"*\",[4,\"-\",[5,\"1\"]]]]],\"&&\",[1,\"ty\",\"<\",[1,\"outF\",\"+\",\"radF\"]]]],[11,\"onTarget\",[0,[[13,\"win\",[6,\"texelSplatWindow\",[[6,\"d.vec2f\",[\"tx\",\"ty\"]],\"rad\",[6,\"d.vec2i\",[[6,\"d.i32\",[[1,\"OUT_RES\",\"-\",[5,\"1\"]]]],[6,\"d.i32\",[[1,\"OUT_RES\",\"-\",[5,\"1\"]]]]]]]]],[13,\"sizeSq\",[6,\"std.max\",[[1,\"size\",\"*\",\"size\"],[5,\"0.01\"]]]],[14,[12,\"py\",[7,\"win\",\"y0\"]],[1,\"py\",\"<=\",[7,\"win\",\"y1\"]],[102,\"++\",\"py\"],[0,[[13,\"ddy\",[1,[1,[6,\"d.f32\",[\"py\"]],\"+\",[5,\"0.5\"]],\"-\",\"ty\"]],[13,\"ddySq\",[1,\"ddy\",\"*\",\"ddy\"]],[14,[12,\"px\",[7,\"win\",\"x0\"]],[1,\"px\",\"<=\",[7,\"win\",\"x1\"]],[102,\"++\",\"px\"],[0,[[13,\"ddx\",[1,[1,[6,\"d.f32\",[\"px\"]],\"+\",[5,\"0.5\"]],\"-\",\"tx\"]],[13,\"q\",[1,[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",\"ddySq\"],\"/\",\"sizeSq\"]],[11,[1,\"q\",\"<\",\"EXTQ\"],[0,[[13,\"w\",[6,\"profileFn\",[\"q\",\"ddx\",\"ddy\",\"size\",[7,\"prm\",\"softness\"]]]],[13,\"e\",[6,\"d.u32\",[[1,[1,\"w\",\"*\",\"bright\"],\"*\",[5,\"256\"]]]]],[11,[1,\"e\",\">\",[6,\"d.u32\",[[5,\"0\"]]]],[0,[[13,\"idx\",[6,\"d.u32\",[[1,[1,\"py\",\"*\",[6,\"d.i32\",[\"OUT_RES\"]]],\"+\",\"px\"]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumE\"],\"idx\"],\"e\"]],[11,\"doSpeed\",[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumS\"],\"idx\"],[6,\"d.u32\",[[1,[1,[1,\"w\",\"*\",\"bright\"],\"*\",\"speedNorm\"],\"*\",[5,\"256\"]]]]]]]]]]]]]]]]]]]]]]]]},externals:{layout:()=>e,\"std.clamp\":()=>G,\"d.f32\":()=>n,OUT_RES:()=>r,MAX_SPLAT_SIZE:()=>o,\"d.i32\":()=>j,\"std.ceil\":()=>nl,EXT:()=>i,texelSplatWindow:()=>ah,\"d.vec2f\":()=>m,\"d.vec2i\":()=>nc,\"std.max\":()=>B,EXTQ:()=>a,profileFn:()=>s,\"d.u32\":()=>M,\"std.atomicAdd\":()=>wa}})&&l.f)({})).$name(t.names.splat)}function Rce(e,t){let s=wd(t.shape,\"dot\"),r=zd[s],o=k_(s),a=r.soft===1?Math.max(r.ext,2.4):r.ext,i=t.splatRCap,l=t.aaW,c=t.minAlpha,d=t.fp,u=1/t.fp,p=t.wobbleFreq,_=t.perspK,f=6.283185307179586;return w.fn([M,M])((h=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(h.f=((g,y)=>{\"use gpu\";let b=e.$.params,x=__tsover_add(__tsover_mul(y,M(b.gridW)),g),P=e.$.pos[x],C=e.$.col[x],E=C.w;if(E>c){let R=__tsover_div(__tsover_add(n(g),.5),b.gridW),U=__tsover_div(__tsover_add(n(y),.5),b.gridH),L=__tsover_mul(P.w,f),k=b.wobbleAmp,D=__tsover_mul(__tsover_mul(ae(__tsover_add(__tsover_mul(b.time,p),L)),k),.012),O=__tsover_mul(__tsover_mul(pe(__tsover_add(__tsover_mul(__tsover_mul(b.time,p),1.13),__tsover_mul(L,1.7))),k),.012),F=__tsover_mul(__tsover_mul(ae(__tsover_add(__tsover_mul(__tsover_mul(b.time,p),.87),__tsover_mul(L,2.3))),k),.06),q=eh(A(__tsover_add(__tsover_add(__tsover_mul(__tsover_sub(R,.5),b.aspect),P.x),D),__tsover_add(__tsover_add(__tsover_sub(U,.5),P.y),O),__tsover_add(P.z,F)),b.rowX,b.rowY,b.rowZ),Y=__tsover_div(1,G(__tsover_sub(1,__tsover_mul(q.z,_)),.35,2.6)),V=__tsover_mul(Y,b.zoom),X=__tsover_add(__tsover_add(.5,__tsover_div(__tsover_mul(q.x,V),b.aspect)),b.transX),Q=__tsover_add(__tsover_add(.5,__tsover_mul(q.y,V)),b.transY),te=__tsover_mul(X,b.outW),J=__tsover_mul(Q,b.outH),oe=G(__tsover_mul(__tsover_mul(__tsover_mul(b.particleSize,b.spacing),.5),V),.5,n(i)),le=B(b.depth,.001),se=be(__tsover_mul(le,-1),le,q.z),Te=K(n(1),__tsover_add(.35,__tsover_mul(.65,se)),b.depthShading),de=__tsover_mul(__tsover_mul(Y,Y),Te),xe=__tsover_mul(E,de),Ae=__tsover_add(n(a),__tsover_div(n(l),oe)),De=j(nl(__tsover_mul(oe,Ae))),Ee=n(De),ze=te>__tsover_mul(Ee,-1)&&te<__tsover_add(b.outW,Ee)&&J>__tsover_mul(Ee,-1)&&J<__tsover_add(b.outH,Ee);if(xe>u&&ze){let Ie=M(b.outW),ke=ah(m(te,J),De,nc(__tsover_sub(j(b.outW),1),__tsover_sub(j(b.outH),1)));for(let Me=ke.y0;Me<=ke.y1;Me++){let we=__tsover_sub(__tsover_add(n(Me),.5),J);for(let Ve=ke.x0;Ve<=ke.x1;Ve++){let qe=__tsover_sub(__tsover_add(n(Ve),.5),te),st=__tsover_div(__tsover_add(__tsover_mul(qe,qe),__tsover_mul(we,we)),B(__tsover_mul(oe,oe),.01));if(st<__tsover_mul(Ae,Ae)){let pt=__tsover_mul(o(st,qe,we,oe,n(l)),xe);if(pt>0){let Ze=__tsover_add(__tsover_mul(M(Me),Ie),M(Ve));wa(e.$.accumR[Ze],M(__tsover_mul(__tsover_mul(C.x,pt),d))),wa(e.$.accumG[Ze],M(__tsover_mul(__tsover_mul(C.y,pt),d))),wa(e.$.accumB[Ze],M(__tsover_mul(__tsover_mul(C.z,pt),d))),wa(e.$.accumW[Ze],M(__tsover_mul(pt,d)))}}}}}}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gx\"},{type:\"i\",name:\"gy\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"i\",[1,[1,\"gy\",\"*\",[6,\"d.u32\",[[7,\"P\",\"gridW\"]]]],\"+\",\"gx\"]],[13,\"p4\",[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"]],[13,\"col\",[8,[7,[7,\"layout\",\"$\"],\"col\"],\"i\"]],[13,\"childA\",[7,\"col\",\"w\"]],[11,[1,\"childA\",\">\",\"MIN_ALPHA\"],[0,[[13,\"homeU\",[1,[1,[6,\"d.f32\",[\"gx\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"P\",\"gridW\"]]],[13,\"homeV\",[1,[1,[6,\"d.f32\",[\"gy\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"P\",\"gridH\"]]],[13,\"ph\",[1,[7,\"p4\",\"w\"],\"*\",\"TAU\"]],[13,\"wob\",[7,\"P\",\"wobbleAmp\"]],[13,\"wx\",[1,[1,[6,\"std.sin\",[[1,[1,[7,\"P\",\"time\"],\"*\",\"WOBBLE_FREQ\"],\"+\",\"ph\"]]],\"*\",\"wob\"],\"*\",[5,\"0.012\"]]],[13,\"wy\",[1,[1,[6,\"std.cos\",[[1,[1,[1,[7,\"P\",\"time\"],\"*\",\"WOBBLE_FREQ\"],\"*\",[5,\"1.13\"]],\"+\",[1,\"ph\",\"*\",[5,\"1.7\"]]]]],\"*\",\"wob\"],\"*\",[5,\"0.012\"]]],[13,\"wz\",[1,[1,[6,\"std.sin\",[[1,[1,[1,[7,\"P\",\"time\"],\"*\",\"WOBBLE_FREQ\"],\"*\",[5,\"0.87\"]],\"+\",[1,\"ph\",\"*\",[5,\"2.3\"]]]]],\"*\",\"wob\"],\"*\",[5,\"0.06\"]]],[13,\"pw\",[6,\"d.vec3f\",[[1,[1,[1,[1,\"homeU\",\"-\",[5,\"0.5\"]],\"*\",[7,\"P\",\"aspect\"]],\"+\",[7,\"p4\",\"x\"]],\"+\",\"wx\"],[1,[1,[1,\"homeV\",\"-\",[5,\"0.5\"]],\"+\",[7,\"p4\",\"y\"]],\"+\",\"wy\"],[1,[7,\"p4\",\"z\"],\"+\",\"wz\"]]]],[13,\"rv\",[6,\"agents.applyCameraRows\",[\"pw\",[7,\"P\",\"rowX\"],[7,\"P\",\"rowY\"],[7,\"P\",\"rowZ\"]]]],[13,\"persp0\",[1,[5,\"1\"],\"/\",[6,\"std.clamp\",[[1,[5,\"1\"],\"-\",[1,[7,\"rv\",\"z\"],\"*\",\"PERSP_K\"]],[5,\"0.35\"],[5,\"2.6\"]]]]],[13,\"persp\",[1,\"persp0\",\"*\",[7,\"P\",\"zoom\"]]],[13,\"su\",[1,[1,[5,\"0.5\"],\"+\",[1,[1,[7,\"rv\",\"x\"],\"*\",\"persp\"],\"/\",[7,\"P\",\"aspect\"]]],\"+\",[7,\"P\",\"transX\"]]],[13,\"sv\",[1,[1,[5,\"0.5\"],\"+\",[1,[7,\"rv\",\"y\"],\"*\",\"persp\"]],\"+\",[7,\"P\",\"transY\"]]],[13,\"tx\",[1,\"su\",\"*\",[7,\"P\",\"outW\"]]],[13,\"ty\",[1,\"sv\",\"*\",[7,\"P\",\"outH\"]]],[13,\"dotR\",[6,\"std.clamp\",[[1,[1,[1,[7,\"P\",\"particleSize\"],\"*\",[7,\"P\",\"spacing\"]],\"*\",[5,\"0.5\"]],\"*\",\"persp\"],[5,\"0.5\"],[6,\"d.f32\",[\"SPLAT_R\"]]]]],[13,\"dr\",[6,\"std.max\",[[7,\"P\",\"depth\"],[5,\"0.001\"]]]],[13,\"near\",[6,\"std.smoothstep\",[[1,\"dr\",\"*\",[4,\"-\",[5,\"1\"]]],\"dr\",[7,\"rv\",\"z\"]]]],[13,\"shade\",[6,\"std.mix\",[[6,\"d.f32\",[[5,\"1\"]]],[1,[5,\"0.35\"],\"+\",[1,[5,\"0.65\"],\"*\",\"near\"]],[7,\"P\",\"depthShading\"]]]],[13,\"depthWeight\",[1,[1,\"persp0\",\"*\",\"persp0\"],\"*\",\"shade\"]],[13,\"cw\",[1,\"childA\",\"*\",\"depthWeight\"]],[13,\"extR\",[1,[6,\"d.f32\",[\"EXT_SHAPE\"]],\"+\",[1,[6,\"d.f32\",[\"AA_W\"]],\"/\",\"dotR\"]]],[13,\"rad\",[6,\"d.i32\",[[6,\"std.ceil\",[[1,\"dotR\",\"*\",\"extR\"]]]]]],[13,\"radF\",[6,\"d.f32\",[\"rad\"]]],[13,\"onTarget\",[3,[3,[3,[1,\"tx\",\">\",[1,\"radF\",\"*\",[4,\"-\",[5,\"1\"]]]],\"&&\",[1,\"tx\",\"<\",[1,[7,\"P\",\"outW\"],\"+\",\"radF\"]]],\"&&\",[1,\"ty\",\">\",[1,\"radF\",\"*\",[4,\"-\",[5,\"1\"]]]]],\"&&\",[1,\"ty\",\"<\",[1,[7,\"P\",\"outH\"],\"+\",\"radF\"]]]],[11,[3,[1,\"cw\",\">\",\"MIN_WEIGHT\"],\"&&\",\"onTarget\"],[0,[[13,\"owU\",[6,\"d.u32\",[[7,\"P\",\"outW\"]]]],[13,\"win\",[6,\"texelSplatWindow\",[[6,\"d.vec2f\",[\"tx\",\"ty\"]],\"rad\",[6,\"d.vec2i\",[[1,[6,\"d.i32\",[[7,\"P\",\"outW\"]]],\"-\",[5,\"1\"]],[1,[6,\"d.i32\",[[7,\"P\",\"outH\"]]],\"-\",[5,\"1\"]]]]]]],[14,[12,\"py\",[7,\"win\",\"y0\"]],[1,\"py\",\"<=\",[7,\"win\",\"y1\"]],[102,\"++\",\"py\"],[0,[[13,\"ddy\",[1,[1,[6,\"d.f32\",[\"py\"]],\"+\",[5,\"0.5\"]],\"-\",\"ty\"]],[14,[12,\"px\",[7,\"win\",\"x0\"]],[1,\"px\",\"<=\",[7,\"win\",\"x1\"]],[102,\"++\",\"px\"],[0,[[13,\"ddx\",[1,[1,[6,\"d.f32\",[\"px\"]],\"+\",[5,\"0.5\"]],\"-\",\"tx\"]],[13,\"q\",[1,[1,[1,\"ddx\",\"*\",\"ddx\"],\"+\",[1,\"ddy\",\"*\",\"ddy\"]],\"/\",[6,\"std.max\",[[1,\"dotR\",\"*\",\"dotR\"],[5,\"0.01\"]]]]],[11,[1,\"q\",\"<\",[1,\"extR\",\"*\",\"extR\"]],[0,[[13,\"wc\",[1,[6,\"weightFn\",[\"q\",\"ddx\",\"ddy\",\"dotR\",[6,\"d.f32\",[\"AA_W\"]]]],\"*\",\"cw\"]],[11,[1,\"wc\",\">\",[5,\"0\"]],[0,[[13,\"idx\",[1,[1,[6,\"d.u32\",[\"py\"]],\"*\",\"owU\"],\"+\",[6,\"d.u32\",[\"px\"]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumR\"],\"idx\"],[6,\"d.u32\",[[1,[1,[7,\"col\",\"x\"],\"*\",\"wc\"],\"*\",\"FP\"]]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumG\"],\"idx\"],[6,\"d.u32\",[[1,[1,[7,\"col\",\"y\"],\"*\",\"wc\"],\"*\",\"FP\"]]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumB\"],\"idx\"],[6,\"d.u32\",[[1,[1,[7,\"col\",\"z\"],\"*\",\"wc\"],\"*\",\"FP\"]]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"accumW\"],\"idx\"],[6,\"d.u32\",[[1,\"wc\",\"*\",\"FP\"]]]]]]]]]]]]]]]]]]]]]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,MIN_ALPHA:()=>c,\"d.f32\":()=>n,TAU:()=>f,\"std.sin\":()=>ae,WOBBLE_FREQ:()=>p,\"std.cos\":()=>pe,\"d.vec3f\":()=>A,\"agents.applyCameraRows\":()=>eh,\"std.clamp\":()=>G,PERSP_K:()=>_,SPLAT_R:()=>i,\"std.max\":()=>B,\"std.smoothstep\":()=>be,\"std.mix\":()=>K,EXT_SHAPE:()=>a,AA_W:()=>l,\"d.i32\":()=>j,\"std.ceil\":()=>nl,MIN_WEIGHT:()=>u,texelSplatWindow:()=>ah,\"d.vec2f\":()=>m,\"d.vec2i\":()=>nc,weightFn:()=>o,\"std.atomicAdd\":()=>wa,FP:()=>d}})&&h.f)({})).$name(t.name)}function Dce(e,t){let s=e,r=No[t.colorSpace]??Ar,o=t.res,a=t.invGain,i=t.exposure===!0?w.fn([n],n)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";return __tsover_mul(__tsover_mul(d,a),s.$.params.exposure)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"eRaw\"}],body:[0,[[10,[1,[1,\"eRaw\",\"*\",\"INV_GAIN\"],\"*\",[7,[7,[7,\"L\",\"$\"],\"params\"],\"exposure\"]]]]]},externals:{INV_GAIN:()=>a,L:()=>s}})&&c.f)({})).$name(`${t.name}Energy`):w.fn([n],n)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";return __tsover_mul(d,a)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"eRaw\"}],body:[0,[[10,[1,\"eRaw\",\"*\",\"INV_GAIN\"]]]]},externals:{INV_GAIN:()=>a}})&&c.f)({})).$name(`${t.name}Energy`);if(t.trails===\"none\")return w.fn([M,M])((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u)=>{\"use gpu\";let p=s.$.params,_=__tsover_add(__tsover_mul(u,M(o)),d),f=n(ba(s.$.accumE[_]));xa(s.$.accumE[_],M(0));let h=n(ba(s.$.accumS[_]));if(xa(s.$.accumS[_],M(0)),f>0){let g=i(f),y=__tsover_div(h,B(f,1)),b=r(p.colA,p.colB,G(y,0,1)),x=__tsover_mul(Kl(g,1.6),b.w);lt(s.$.outTex,fe(d,u),S(b.x,b.y,b.z,x))}else lt(s.$.outTex,fe(d,u),S(p.colA.x,p.colA.y,p.colA.z,n(0)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"prm\",[7,[7,\"L\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"y\",\"*\",[6,\"d.u32\",[\"RES\"]]],\"+\",\"x\"]],[13,\"eRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"L\",\"$\"],\"accumE\"],\"idx\"]]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"L\",\"$\"],\"accumE\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"sRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"L\",\"$\"],\"accumS\"],\"idx\"]]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"L\",\"$\"],\"accumS\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[11,[1,\"eRaw\",\">\",[5,\"0\"]],[0,[[13,\"energy\",[6,\"energyOf\",[\"eRaw\"]]],[13,\"agitAvg\",[1,\"sRaw\",\"/\",[6,\"std.max\",[\"eRaw\",[5,\"1\"]]]]],[13,\"col\",[6,\"mixFn\",[[7,\"prm\",\"colA\"],[7,\"prm\",\"colB\"],[6,\"std.clamp\",[\"agitAvg\",[5,\"0\"],[5,\"1\"]]]]]],[13,\"a\",[1,[6,\"energyCoverageAlpha\",[\"energy\",[5,\"1.6\"]]],\"*\",[7,\"col\",\"w\"]]],[6,\"std.textureStore\",[[7,[7,\"L\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"x\",\"y\"]],[6,\"d.vec4f\",[[7,\"col\",\"x\"],[7,\"col\",\"y\"],[7,\"col\",\"z\"],\"a\"]]]]]],[0,[[6,\"std.textureStore\",[[7,[7,\"L\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"x\",\"y\"]],[6,\"d.vec4f\",[[7,[7,\"prm\",\"colA\"],\"x\"],[7,[7,\"prm\",\"colA\"],\"y\"],[7,[7,\"prm\",\"colA\"],\"z\"],[6,\"d.f32\",[[5,\"0\"]]]]]]]]]]]]},externals:{L:()=>s,\"d.u32\":()=>M,RES:()=>o,\"d.f32\":()=>n,\"std.atomicLoad\":()=>ba,\"std.atomicStore\":()=>xa,energyOf:()=>i,\"std.max\":()=>B,mixFn:()=>r,\"std.clamp\":()=>G,energyCoverageAlpha:()=>Kl,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&c.f)({})).$name(t.name);let l=t.trails===\"on\"||t.trails.baked?w.fn([S,n,M],S)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";return SP(d,u,s.$.trailBuf[p],s.$.params.trails)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"col\"},{type:\"i\",name:\"curA\"},{type:\"i\",name:\"idx\"}],body:[0,[[10,[6,\"agents.trailMaxDecay\",[\"col\",\"curA\",[8,[7,[7,\"L\",\"$\"],\"trailBuf\"],\"idx\"],[7,[7,[7,\"L\",\"$\"],\"params\"],\"trails\"]]]]]]},externals:{\"agents.trailMaxDecay\":()=>SP,L:()=>s}})&&c.f)({})).$name(`${t.name}TrailComposite`):w.fn([S,n,M],S)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";return S(d.x,d.y,d.z,u)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"col\"},{type:\"i\",name:\"curA\"},{type:\"i\",name:\"_idx\"}],body:[0,[[10,[6,\"d.vec4f\",[[7,\"col\",\"x\"],[7,\"col\",\"y\"],[7,\"col\",\"z\"],\"curA\"]]]]]},externals:{\"d.vec4f\":()=>S}})&&c.f)({})).$name(`${t.name}TrailComposite`);return w.fn([M,M])((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u)=>{\"use gpu\";let p=s.$.params,_=__tsover_add(__tsover_mul(u,M(o)),d),f=n(ba(s.$.accumE[_]));xa(s.$.accumE[_],M(0));let h=n(ba(s.$.accumS[_]));xa(s.$.accumS[_],M(0));let g=i(f),y=S(p.colA);if(f>0){let P=__tsover_div(h,B(f,1));y=r(p.colA,p.colB,G(P,0,1))}let b=__tsover_mul(Kl(g,1.6),y.w),x=l(y,b,_);s.$.trailBuf[_]=S(x),lt(s.$.outTex,fe(d,u),x)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"prm\",[7,[7,\"L\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"y\",\"*\",[6,\"d.u32\",[\"RES\"]]],\"+\",\"x\"]],[13,\"eRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"L\",\"$\"],\"accumE\"],\"idx\"]]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"L\",\"$\"],\"accumE\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"sRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"L\",\"$\"],\"accumS\"],\"idx\"]]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"L\",\"$\"],\"accumS\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"energy\",[6,\"energyOf\",[\"eRaw\"]]],[12,\"col\",[6,\"d.vec4f\",[[7,\"prm\",\"colA\"]]]],[11,[1,\"eRaw\",\">\",[5,\"0\"]],[0,[[13,\"agitAvg\",[1,\"sRaw\",\"/\",[6,\"std.max\",[\"eRaw\",[5,\"1\"]]]]],[2,\"col\",\"=\",[6,\"mixFn\",[[7,\"prm\",\"colA\"],[7,\"prm\",\"colB\"],[6,\"std.clamp\",[\"agitAvg\",[5,\"0\"],[5,\"1\"]]]]]]]]],[13,\"curA\",[1,[6,\"energyCoverageAlpha\",[\"energy\",[5,\"1.6\"]]],\"*\",[7,\"col\",\"w\"]]],[13,\"out\",[6,\"composite\",[\"col\",\"curA\",\"idx\"]]],[2,[8,[7,[7,\"L\",\"$\"],\"trailBuf\"],\"idx\"],\"=\",[6,\"d.vec4f\",[\"out\"]]],[6,\"std.textureStore\",[[7,[7,\"L\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"x\",\"y\"]],\"out\"]]]]},externals:{L:()=>s,\"d.u32\":()=>M,RES:()=>o,\"d.f32\":()=>n,\"std.atomicLoad\":()=>ba,\"std.atomicStore\":()=>xa,energyOf:()=>i,\"d.vec4f\":()=>S,\"std.max\":()=>B,mixFn:()=>r,\"std.clamp\":()=>G,energyCoverageAlpha:()=>Kl,composite:()=>l,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe}})&&c.f)({})).$name(t.name)}function Lce(e,t){let s=t.res;return w.fn([M,M])((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a)=>{\"use gpu\";let i=e.$.params,l=__tsover_add(__tsover_mul(a,M(s)),o),c=__tsover_mul(n(ba(e.$.accumE[l])),__tsover_div(1,255));xa(e.$.accumE[l],M(0));let d=__tsover_mul(Kl(c,1.6),i.color.w);lt(e.$.outTex,fe(o,a),S(i.color.x,i.color.y,i.color.z,d))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"y\",\"*\",[6,\"d.u32\",[\"RES\"]]],\"+\",\"x\"]],[13,\"energy\",[1,[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"accumE\"],\"idx\"]]]]],\"*\",[1,[5,\"1\"],\"/\",[5,\"255\"]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"accumE\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"a\",[1,[6,\"energyCoverageAlpha\",[\"energy\",[5,\"1.6\"]]],\"*\",[7,[7,\"prm\",\"color\"],\"w\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"x\",\"y\"]],[6,\"d.vec4f\",[[7,[7,\"prm\",\"color\"],\"x\"],[7,[7,\"prm\",\"color\"],\"y\"],[7,[7,\"prm\",\"color\"],\"z\"],\"a\"]]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,RES:()=>s,\"d.f32\":()=>n,\"std.atomicLoad\":()=>ba,\"std.atomicStore\":()=>xa,energyCoverageAlpha:()=>Kl,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&r.f)({})).$name(t.name)}function Uce(e,t){let s=t.fp,r=t.alphaK;return w.fn([M,M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i)=>{\"use gpu\";let l=e.$.params,c=__tsover_add(__tsover_mul(i,M(l.outW)),a),d=n(ba(e.$.accumW[c])),u=n(ba(e.$.accumR[c])),p=n(ba(e.$.accumG[c])),_=n(ba(e.$.accumB[c]));xa(e.$.accumR[c],M(0)),xa(e.$.accumG[c],M(0)),xa(e.$.accumB[c],M(0)),xa(e.$.accumW[c],M(0));let f=B(d,n(1)),h=__tsover_div(u,f),g=__tsover_div(p,f),y=__tsover_div(_,f),b=Kl(__tsover_mul(d,__tsover_div(1,s)),r);lt(e.$.outTex,fe(a,i),S(h,g,y,b))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"x\"},{type:\"i\",name:\"y\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"idx\",[1,[1,\"y\",\"*\",[6,\"d.u32\",[[7,\"P\",\"outW\"]]]],\"+\",\"x\"]],[13,\"wRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"accumW\"],\"idx\"]]]]]],[13,\"rRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"accumR\"],\"idx\"]]]]]],[13,\"gRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"accumG\"],\"idx\"]]]]]],[13,\"bRaw\",[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"accumB\"],\"idx\"]]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"accumR\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"accumG\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"accumB\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"accumW\"],\"idx\"],[6,\"d.u32\",[[5,\"0\"]]]]],[13,\"denom\",[6,\"std.max\",[\"wRaw\",[6,\"d.f32\",[[5,\"1\"]]]]]],[13,\"r\",[1,\"rRaw\",\"/\",\"denom\"]],[13,\"g\",[1,\"gRaw\",\"/\",\"denom\"]],[13,\"b\",[1,\"bRaw\",\"/\",\"denom\"]],[13,\"alpha\",[6,\"energyCoverageAlpha\",[[1,\"wRaw\",\"*\",[1,[5,\"1\"],\"/\",\"FP\"]],\"ALPHA_K\"]]],[6,\"std.textureStore\",[[7,[7,\"layout\",\"$\"],\"outTex\"],[6,\"d.vec2u\",[\"x\",\"y\"]],[6,\"d.vec4f\",[\"r\",\"g\",\"b\",\"alpha\"]]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.atomicLoad\":()=>ba,\"std.atomicStore\":()=>xa,\"std.max\":()=>B,energyCoverageAlpha:()=>Kl,FP:()=>s,ALPHA_K:()=>r,\"std.textureStore\":()=>lt,\"d.vec2u\":()=>fe,\"d.vec4f\":()=>S}})&&o.f)({})).$name(t.name)}var w1={orientedWorld:Ece,pointWorld:kce,volume:zce,relief:Rce},T1={ramp:Dce,tint:Lce,weightedColor:Uce};function Oce(e,t){let s=t.gridDim,r=t.domain,o=w.fn([j,j,j],n)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=j(s),f=G(d,0,__tsover_sub(_,1)),h=G(u,0,__tsover_sub(_,1)),g=G(p,0,__tsover_sub(_,1)),y=M(__tsover_add(__tsover_mul(__tsover_add(__tsover_mul(g,_),h),_),f));return __tsover_mul(n(ba(e.$.dens[y])),__tsover_div(1,64))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"cx\"},{type:\"i\",name:\"cy\"},{type:\"i\",name:\"cz\"}],body:[0,[[13,\"g\",[6,\"d.i32\",[\"DGRID\"]]],[13,\"x\",[6,\"std.clamp\",[\"cx\",[5,\"0\"],[1,\"g\",\"-\",[5,\"1\"]]]]],[13,\"y\",[6,\"std.clamp\",[\"cy\",[5,\"0\"],[1,\"g\",\"-\",[5,\"1\"]]]]],[13,\"z\",[6,\"std.clamp\",[\"cz\",[5,\"0\"],[1,\"g\",\"-\",[5,\"1\"]]]]],[13,\"idx\",[6,\"d.u32\",[[1,[1,[1,[1,\"z\",\"*\",\"g\"],\"+\",\"y\"],\"*\",\"g\"],\"+\",\"x\"]]]],[10,[1,[6,\"d.f32\",[[6,\"std.atomicLoad\",[[8,[7,[7,\"layout\",\"$\"],\"dens\"],\"idx\"]]]]],\"*\",[1,[5,\"1\"],\"/\",[5,\"64\"]]]]]]},externals:{\"d.i32\":()=>j,DGRID:()=>s,\"std.clamp\":()=>G,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.atomicLoad\":()=>ba,layout:()=>e}})&&c.f)({})),a=w.fn([A],S)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";let u=e.$.params,p=n(s),_=A(__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(d.x,u.gridOffX),r),__tsover_mul(2,r)),p),.5),__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(d.y,u.gridOffY),r),__tsover_mul(2,r)),p),.5),__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(d.z,u.gridOffZ),r),__tsover_mul(2,r)),p),.5)),f=G(ie(_),A(0,0,0),A(__tsover_sub(p,2),__tsover_sub(p,2),__tsover_sub(p,2))),h=G(_.sub(f),A(0,0,0),A(1,1,1)),g=j(f.x),y=j(f.y),b=j(f.z),x=n(0),P=n(0),C=n(0),E=n(0);for(let R=0;R<2;R++)for(let U=0;U<2;U++)for(let L=0;L<2;L++){let k=K(__tsover_sub(1,h.x),h.x,n(L)),D=K(__tsover_sub(1,h.y),h.y,n(U)),O=K(__tsover_sub(1,h.z),h.z,n(R)),F=__tsover_sub(__tsover_mul(n(L),2),1),q=__tsover_sub(__tsover_mul(n(U),2),1),Y=__tsover_sub(__tsover_mul(n(R),2),1),V=o(__tsover_add(g,L),__tsover_add(y,U),__tsover_add(b,R));x=__tsover_add(x,__tsover_mul(V,__tsover_mul(__tsover_mul(k,D),O))),P=__tsover_add(P,__tsover_mul(V,__tsover_mul(__tsover_mul(F,D),O))),C=__tsover_add(C,__tsover_mul(V,__tsover_mul(__tsover_mul(k,q),O))),E=__tsover_add(E,__tsover_mul(V,__tsover_mul(__tsover_mul(k,D),Y)))}return S(P,C,E,x)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"g\",[6,\"d.f32\",[\"DGRID\"]]],[13,\"c\",[6,\"d.vec3f\",[[1,[1,[1,[1,[1,[7,\"pos\",\"x\"],\"+\",[7,\"prm\",\"gridOffX\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]],[1,[1,[1,[1,[1,[7,\"pos\",\"y\"],\"+\",[7,\"prm\",\"gridOffY\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]],[1,[1,[1,[1,[1,[7,\"pos\",\"z\"],\"+\",[7,\"prm\",\"gridOffZ\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]]]]],[13,\"base\",[6,\"std.clamp\",[[6,\"std.floor\",[\"c\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[1,\"g\",\"-\",[5,\"2\"]],[1,\"g\",\"-\",[5,\"2\"]],[1,\"g\",\"-\",[5,\"2\"]]]]]]],[13,\"f\",[6,\"std.clamp\",[[6,[7,\"c\",\"sub\"],[\"base\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[13,\"bi\",[6,\"d.i32\",[[7,\"base\",\"x\"]]]],[13,\"bj\",[6,\"d.i32\",[[7,\"base\",\"y\"]]]],[13,\"bk\",[6,\"d.i32\",[[7,\"base\",\"z\"]]]],[12,\"acc\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"gx\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"gy\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"gz\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"dz\",[5,\"0\"]],[1,\"dz\",\"<\",[5,\"2\"]],[102,\"++\",\"dz\"],[0,[[14,[12,\"dy\",[5,\"0\"]],[1,\"dy\",\"<\",[5,\"2\"]],[102,\"++\",\"dy\"],[0,[[14,[12,\"dx\",[5,\"0\"]],[1,\"dx\",\"<\",[5,\"2\"]],[102,\"++\",\"dx\"],[0,[[13,\"wx\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"x\"]],[7,\"f\",\"x\"],[6,\"d.f32\",[\"dx\"]]]]],[13,\"wy\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"y\"]],[7,\"f\",\"y\"],[6,\"d.f32\",[\"dy\"]]]]],[13,\"wz\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"z\"]],[7,\"f\",\"z\"],[6,\"d.f32\",[\"dz\"]]]]],[13,\"sx\",[1,[1,[6,\"d.f32\",[\"dx\"]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"sy\",[1,[1,[6,\"d.f32\",[\"dy\"]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"sz\",[1,[1,[6,\"d.f32\",[\"dz\"]],\"*\",[5,\"2\"]],\"-\",[5,\"1\"]]],[13,\"cv\",[6,\"densAt\",[[1,\"bi\",\"+\",\"dx\"],[1,\"bj\",\"+\",\"dy\"],[1,\"bk\",\"+\",\"dz\"]]]],[2,\"acc\",\"=\",[1,\"acc\",\"+\",[1,\"cv\",\"*\",[1,[1,\"wx\",\"*\",\"wy\"],\"*\",\"wz\"]]]],[2,\"gx\",\"=\",[1,\"gx\",\"+\",[1,\"cv\",\"*\",[1,[1,\"sx\",\"*\",\"wy\"],\"*\",\"wz\"]]]],[2,\"gy\",\"=\",[1,\"gy\",\"+\",[1,\"cv\",\"*\",[1,[1,\"wx\",\"*\",\"sy\"],\"*\",\"wz\"]]]],[2,\"gz\",\"=\",[1,\"gz\",\"+\",[1,\"cv\",\"*\",[1,[1,\"wx\",\"*\",\"wy\"],\"*\",\"sz\"]]]]]]]]]]]]],[10,[6,\"d.vec4f\",[\"gx\",\"gy\",\"gz\",\"acc\"]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,DGRID:()=>s,\"d.vec3f\":()=>A,DOMAIN:()=>r,\"std.clamp\":()=>G,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"std.mix\":()=>K,densAt:()=>o,\"d.vec4f\":()=>S}})&&c.f)({})),i=w.fn([M])((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";xa(e.$.dens[d],M(0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[6,\"std.atomicStore\",[[8,[7,[7,\"layout\",\"$\"],\"dens\"],\"i\"],[6,\"d.u32\",[[5,\"0\"]]]]]]]},externals:{\"std.atomicStore\":()=>xa,layout:()=>e,\"d.u32\":()=>M}})&&c.f)({})).$name(t.names.clear),l=w.fn([M])((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";let u=e.$.params,p=e.$.pos[d],_=n(s),f=A(__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(p.x,u.gridOffX),r),__tsover_mul(2,r)),_),.5),__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(p.y,u.gridOffY),r),__tsover_mul(2,r)),_),.5),__tsover_sub(__tsover_mul(__tsover_div(__tsover_add(__tsover_add(p.z,u.gridOffZ),r),__tsover_mul(2,r)),_),.5)),h=G(ie(f),A(0,0,0),A(__tsover_sub(_,2),__tsover_sub(_,2),__tsover_sub(_,2))),g=G(f.sub(h),A(0,0,0),A(1,1,1)),y=j(h.x),b=j(h.y),x=j(h.z),P=j(s);for(let C=0;C<2;C++)for(let E=0;E<2;E++)for(let R=0;R<2;R++){let U=K(__tsover_sub(1,g.x),g.x,n(R)),L=K(__tsover_sub(1,g.y),g.y,n(E)),k=K(__tsover_sub(1,g.z),g.z,n(C)),D=__tsover_mul(__tsover_mul(U,L),k),O=M(__tsover_add(__tsover_mul(__tsover_add(__tsover_mul(__tsover_add(x,C),P),__tsover_add(b,E)),P),__tsover_add(y,R)));wa(e.$.dens[O],M(__tsover_add(__tsover_mul(D,64),.5)))}}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"pos\",[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"]],[13,\"g\",[6,\"d.f32\",[\"DGRID\"]]],[13,\"c\",[6,\"d.vec3f\",[[1,[1,[1,[1,[1,[7,\"pos\",\"x\"],\"+\",[7,\"prm\",\"gridOffX\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]],[1,[1,[1,[1,[1,[7,\"pos\",\"y\"],\"+\",[7,\"prm\",\"gridOffY\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]],[1,[1,[1,[1,[1,[7,\"pos\",\"z\"],\"+\",[7,\"prm\",\"gridOffZ\"]],\"+\",\"DOMAIN\"],\"/\",[1,[5,\"2\"],\"*\",\"DOMAIN\"]],\"*\",\"g\"],\"-\",[5,\"0.5\"]]]]],[13,\"base\",[6,\"std.clamp\",[[6,\"std.floor\",[\"c\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[1,\"g\",\"-\",[5,\"2\"]],[1,\"g\",\"-\",[5,\"2\"]],[1,\"g\",\"-\",[5,\"2\"]]]]]]],[13,\"f\",[6,\"std.clamp\",[[6,[7,\"c\",\"sub\"],[\"base\"]],[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]]]],[13,\"bi\",[6,\"d.i32\",[[7,\"base\",\"x\"]]]],[13,\"bj\",[6,\"d.i32\",[[7,\"base\",\"y\"]]]],[13,\"bk\",[6,\"d.i32\",[[7,\"base\",\"z\"]]]],[13,\"gi\",[6,\"d.i32\",[\"DGRID\"]]],[14,[12,\"dz\",[5,\"0\"]],[1,\"dz\",\"<\",[5,\"2\"]],[102,\"++\",\"dz\"],[0,[[14,[12,\"dy\",[5,\"0\"]],[1,\"dy\",\"<\",[5,\"2\"]],[102,\"++\",\"dy\"],[0,[[14,[12,\"dx\",[5,\"0\"]],[1,\"dx\",\"<\",[5,\"2\"]],[102,\"++\",\"dx\"],[0,[[13,\"wx\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"x\"]],[7,\"f\",\"x\"],[6,\"d.f32\",[\"dx\"]]]]],[13,\"wy\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"y\"]],[7,\"f\",\"y\"],[6,\"d.f32\",[\"dy\"]]]]],[13,\"wz\",[6,\"std.mix\",[[1,[5,\"1\"],\"-\",[7,\"f\",\"z\"]],[7,\"f\",\"z\"],[6,\"d.f32\",[\"dz\"]]]]],[13,\"w\",[1,[1,\"wx\",\"*\",\"wy\"],\"*\",\"wz\"]],[13,\"idx\",[6,\"d.u32\",[[1,[1,[1,[1,[1,\"bk\",\"+\",\"dz\"],\"*\",\"gi\"],\"+\",[1,\"bj\",\"+\",\"dy\"]],\"*\",\"gi\"],\"+\",[1,\"bi\",\"+\",\"dx\"]]]]],[6,\"std.atomicAdd\",[[8,[7,[7,\"layout\",\"$\"],\"dens\"],\"idx\"],[6,\"d.u32\",[[1,[1,\"w\",\"*\",[5,\"64\"]],\"+\",[5,\"0.5\"]]]]]]]]]]]]]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,DGRID:()=>s,\"d.vec3f\":()=>A,DOMAIN:()=>r,\"std.clamp\":()=>G,\"std.floor\":()=>ie,\"d.i32\":()=>j,\"std.mix\":()=>K,\"d.u32\":()=>M,\"std.atomicAdd\":()=>wa}})&&c.f)({})).$name(t.names.splat);return{force:w.fn([A,A,n],A)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=e.$.params,f=a(d),h=__tsover_div(__tsover_mul(_.spread,4.4),B(__tsover_add(__tsover_mul(f.w,2),6),6));return A(__tsover_mul(__tsover_mul(f.x,-1),h),__tsover_mul(__tsover_mul(f.y,-1),h),__tsover_mul(__tsover_mul(f.z,-1),h))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"_seed\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"gv\",[6,\"densTrilinearGrad\",[\"pos\"]]],[13,\"pressNorm\",[1,[1,[7,\"prm\",\"spread\"],\"*\",[5,\"4.4\"]],\"/\",[6,\"std.max\",[[1,[1,[7,\"gv\",\"w\"],\"*\",[5,\"2\"]],\"+\",[5,\"6\"]],[5,\"6\"]]]]],[10,[6,\"d.vec3f\",[[1,[1,[7,\"gv\",\"x\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"pressNorm\"],[1,[1,[7,\"gv\",\"y\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"pressNorm\"],[1,[1,[7,\"gv\",\"z\"],\"*\",[4,\"-\",[5,\"1\"]]],\"*\",\"pressNorm\"]]]]]]},externals:{layout:()=>e,densTrilinearGrad:()=>a,\"std.max\":()=>B,\"d.vec3f\":()=>A}})&&c.f)({})).$name(\"forcePressure\"),clearKernel:i,splatKernel:l,cells:s*s*s}}function Gce(e,t){let s=t.field,r=t.gradEps,{wall:o,recall:a,homing:i,entrainment:l}=t;return w.fn([A,A,n],A)((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=((d,u,p)=>{\"use gpu\";let _=e.$.params,f=s(d),h=n(r),g=A(__tsover_sub(s(A(__tsover_add(d.x,h),d.y,d.z)),s(A(__tsover_sub(d.x,h),d.y,d.z))),__tsover_sub(s(A(d.x,__tsover_add(d.y,h),d.z)),s(A(d.x,__tsover_sub(d.y,h),d.z))),__tsover_sub(s(A(d.x,d.y,__tsover_add(d.z,h))),s(A(d.x,d.y,__tsover_sub(d.z,h))))),y=g.div(B(he(g),1e-4)),b=A(0,0,0),x=B(f,0),P=__tsover_add(__tsover_mul(be(o.featherFrom,o.featherTo,f),o.base),__tsover_mul(x,o.springK));b=b.sub(y.mul(P));let C=he(d),E=__tsover_mul(be(a.from,a.to,C),a.k);b=b.sub(d.mul(__tsover_div(E,B(C,1e-4))));let R=__tsover_mul(be(i.from,i.to,f),i.k);b=b.sub(d.mul(__tsover_div(R,B(C,1e-4))));let U=u7(A(_.omegaX,_.omegaY,_.omegaZ),d),L=__tsover_sub(1,be(-l.featherHalf,l.featherHalf,f));return b=b.add(U.sub(u).mul(__tsover_mul(_.entrain,L))),b}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"vel\"},{type:\"i\",name:\"_seed\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"sd\",[6,\"field\",[\"pos\"]]],[13,\"e\",[6,\"d.f32\",[\"E\"]]],[13,\"gx\",[1,[6,\"field\",[[6,\"d.vec3f\",[[1,[7,\"pos\",\"x\"],\"+\",\"e\"],[7,\"pos\",\"y\"],[7,\"pos\",\"z\"]]]]],\"-\",[6,\"field\",[[6,\"d.vec3f\",[[1,[7,\"pos\",\"x\"],\"-\",\"e\"],[7,\"pos\",\"y\"],[7,\"pos\",\"z\"]]]]]]],[13,\"gy\",[1,[6,\"field\",[[6,\"d.vec3f\",[[7,\"pos\",\"x\"],[1,[7,\"pos\",\"y\"],\"+\",\"e\"],[7,\"pos\",\"z\"]]]]],\"-\",[6,\"field\",[[6,\"d.vec3f\",[[7,\"pos\",\"x\"],[1,[7,\"pos\",\"y\"],\"-\",\"e\"],[7,\"pos\",\"z\"]]]]]]],[13,\"gz\",[1,[6,\"field\",[[6,\"d.vec3f\",[[7,\"pos\",\"x\"],[7,\"pos\",\"y\"],[1,[7,\"pos\",\"z\"],\"+\",\"e\"]]]]],\"-\",[6,\"field\",[[6,\"d.vec3f\",[[7,\"pos\",\"x\"],[7,\"pos\",\"y\"],[1,[7,\"pos\",\"z\"],\"-\",\"e\"]]]]]]],[13,\"gv\",[6,\"d.vec3f\",[\"gx\",\"gy\",\"gz\"]]],[13,\"gn\",[6,[7,\"gv\",\"div\"],[[6,\"std.max\",[[6,\"std.length\",[\"gv\"]],[5,\"0.0001\"]]]]]],[12,\"F\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]]],[13,\"out\",[6,\"std.max\",[\"sd\",[5,\"0\"]]]],[13,\"wallF\",[1,[1,[6,\"std.smoothstep\",[\"wall.featherFrom\",\"wall.featherTo\",\"sd\"]],\"*\",\"wall.base\"],\"+\",[1,\"out\",\"*\",\"wall.springK\"]]],[2,\"F\",\"=\",[6,[7,\"F\",\"sub\"],[[6,[7,\"gn\",\"mul\"],[\"wallF\"]]]]],[13,\"rl\",[6,\"std.length\",[\"pos\"]]],[13,\"recallF\",[1,[6,\"std.smoothstep\",[\"recall.from\",\"recall.to\",\"rl\"]],\"*\",\"recall.k\"]],[2,\"F\",\"=\",[6,[7,\"F\",\"sub\"],[[6,[7,\"pos\",\"mul\"],[[1,\"recallF\",\"/\",[6,\"std.max\",[\"rl\",[5,\"0.0001\"]]]]]]]]],[13,\"homingF\",[1,[6,\"std.smoothstep\",[\"homing.from\",\"homing.to\",\"sd\"]],\"*\",\"homing.k\"]],[2,\"F\",\"=\",[6,[7,\"F\",\"sub\"],[[6,[7,\"pos\",\"mul\"],[[1,\"homingF\",\"/\",[6,\"std.max\",[\"rl\",[5,\"0.0001\"]]]]]]]]],[13,\"featureVel\",[6,\"std.cross\",[[6,\"d.vec3f\",[[7,\"prm\",\"omegaX\"],[7,\"prm\",\"omegaY\"],[7,\"prm\",\"omegaZ\"]]],\"pos\"]]],[13,\"insideM\",[1,[5,\"1\"],\"-\",[6,\"std.smoothstep\",[[4,\"-\",\"entrainment.featherHalf\"],\"entrainment.featherHalf\",\"sd\"]]]],[2,\"F\",\"=\",[6,[7,\"F\",\"add\"],[[6,[7,[6,[7,\"featureVel\",\"sub\"],[\"vel\"]],\"mul\"],[[1,[7,\"prm\",\"entrain\"],\"*\",\"insideM\"]]]]]],[10,\"F\"]]]},externals:{layout:()=>e,field:()=>s,\"d.f32\":()=>n,E:()=>r,\"d.vec3f\":()=>A,\"std.max\":()=>B,\"std.length\":()=>he,\"std.smoothstep\":()=>be,\"wall.featherFrom\":()=>o.featherFrom,\"wall.featherTo\":()=>o.featherTo,\"wall.base\":()=>o.base,\"wall.springK\":()=>o.springK,\"recall.from\":()=>a.from,\"recall.to\":()=>a.to,\"recall.k\":()=>a.k,\"homing.from\":()=>i.from,\"homing.to\":()=>i.to,\"homing.k\":()=>i.k,\"std.cross\":()=>u7,\"entrainment.featherHalf\":()=>l.featherHalf}})&&c.f)({})).$name(\"forceContainment\")}function Fce(e){return w.fn([A,A,n],A)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";let a=e.$.params,i=Xu(m(__tsover_sub(s.x,a.cursorX),__tsover_sub(s.y,a.cursorY)),a.cursorRadSq,a.cursorForce);return A(i.x,i.y,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"_seed\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"mxy\",[6,\"agents.cursorMagnet\",[[6,\"d.vec2f\",[[1,[7,\"pos\",\"x\"],\"-\",[7,\"prm\",\"cursorX\"]],[1,[7,\"pos\",\"y\"],\"-\",[7,\"prm\",\"cursorY\"]]]],[7,\"prm\",\"cursorRadSq\"],[7,\"prm\",\"cursorForce\"]]]],[10,[6,\"d.vec3f\",[[7,\"mxy\",\"x\"],[7,\"mxy\",\"y\"],[5,\"0\"]]]]]]},externals:{layout:()=>e,\"agents.cursorMagnet\":()=>Xu,\"d.vec2f\":()=>m,\"d.vec3f\":()=>A}})&&t.f)({})).$name(\"forceCursorXY\")}function Ice(e){return w.fn([A,A,n],A)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";let a=e.$.params;return A(a.gravX,a.gravY,0)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"_seed\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[10,[6,\"d.vec3f\",[[7,\"prm\",\"gravX\"],[7,\"prm\",\"gravY\"],[5,\"0\"]]]]]]},externals:{layout:()=>e,\"d.vec3f\":()=>A}})&&t.f)({})).$name(\"forceGravity\")}function Yce(e,t){let{posScale:s,timeX:r,timeY:o,seedScale:a,gain:i}=t;return w.fn([A,A,n],A)((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d,u)=>{\"use gpu\";let p=e.$.params;return ei(c.mul(s).add(A(__tsover_mul(p.time,r),__tsover_mul(p.time,o),__tsover_mul(u,a)))).sub(A(.5,.5,.5)).mul(__tsover_mul(p.agitation,i))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"seed\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"rnd\",[6,[7,[6,\"noise.hash33\",[[6,[7,[6,[7,\"pos\",\"mul\"],[\"posScale\"]],\"add\"],[[6,\"d.vec3f\",[[1,[7,\"prm\",\"time\"],\"*\",\"timeX\"],[1,[7,\"prm\",\"time\"],\"*\",\"timeY\"],[1,\"seed\",\"*\",\"seedScale\"]]]]]]],\"sub\"],[[6,\"d.vec3f\",[[5,\"0.5\"],[5,\"0.5\"],[5,\"0.5\"]]]]]],[10,[6,[7,\"rnd\",\"mul\"],[[1,[7,\"prm\",\"agitation\"],\"*\",\"gain\"]]]]]]},externals:{layout:()=>e,\"noise.hash33\":()=>ei,posScale:()=>s,\"d.vec3f\":()=>A,timeX:()=>r,timeY:()=>o,seedScale:()=>a,gain:()=>i}})&&l.f)({})).$name(\"forceTurbulence\")}function Wce(e){return e.reduce((t,s,r)=>w.fn([A,A,n],A)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i,l)=>{\"use gpu\";return t(a,i,l).add(s(a,i,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"vel\"},{type:\"i\",name:\"seed\"}],body:[0,[[10,[6,[7,[6,\"acc\",[\"pos\",\"vel\",\"seed\"]],\"add\"],[[6,\"part\",[\"pos\",\"vel\",\"seed\"]]]]]]]},externals:{acc:()=>t,part:()=>s}})&&o.f)({})).$name(`forceSum${r}`))}function qce(e,t){let s=Wce(t.forces),r=t.maxSpeed,o=t.posClamp;return w.fn([M])((a=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(a.f=(i=>{\"use gpu\";let l=e.$.params,c=e.$.pos[i],d=e.$.vel[i],u=A(c.x,c.y,c.z),p=A(d.x,d.y,d.z),_=l.dt,f=nh(p,s(u,p,c.w),_,l.dragMul,n(r));u=G(u.add(f.mul(_)),A(-o,-o,-o),A(o,o,o)),e.$.pos[i]=S(u.x,u.y,u.z,c.w),e.$.vel[i]=S(f.x,f.y,f.z,he(f))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"p4\",[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"]],[13,\"v4\",[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"]],[12,\"pos\",[6,\"d.vec3f\",[[7,\"p4\",\"x\"],[7,\"p4\",\"y\"],[7,\"p4\",\"z\"]]]],[13,\"vPrev\",[6,\"d.vec3f\",[[7,\"v4\",\"x\"],[7,\"v4\",\"y\"],[7,\"v4\",\"z\"]]]],[13,\"dt\",[7,\"prm\",\"dt\"]],[13,\"F\",[6,\"total\",[\"pos\",\"vPrev\",[7,\"p4\",\"w\"]]]],[13,\"v3\",[6,\"integrateSemiImplicitEuler\",[\"vPrev\",\"F\",\"dt\",[7,\"prm\",\"dragMul\"],[6,\"d.f32\",[\"MAX_SPEED\"]]]]],[2,\"pos\",\"=\",[6,\"std.clamp\",[[6,[7,\"pos\",\"add\"],[[6,[7,\"v3\",\"mul\"],[\"dt\"]]]],[6,\"d.vec3f\",[[4,\"-\",\"C\"],[4,\"-\",\"C\"],[4,\"-\",\"C\"]]],[6,\"d.vec3f\",[\"C\",\"C\",\"C\"]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"pos\",\"x\"],[7,\"pos\",\"y\"],[7,\"pos\",\"z\"],[7,\"p4\",\"w\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"v3\",\"x\"],[7,\"v3\",\"y\"],[7,\"v3\",\"z\"],[6,\"std.length\",[\"v3\"]]]]]]]},externals:{layout:()=>e,\"d.vec3f\":()=>A,total:()=>s,integrateSemiImplicitEuler:()=>nh,\"d.f32\":()=>n,MAX_SPEED:()=>r,\"std.clamp\":()=>G,C:()=>o,\"d.vec4f\":()=>S,\"std.length\":()=>he}})&&a.f)({})).$name(t.name)}function Vce(e,t){let s=t.maxAgents;return w.fn([m,m,n],m)((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a,i)=>{\"use gpu\";let l=e.$.params,c=m(0,0),d=m(0,0),u=m(0,0),p=n(0),_=n(0);for(let h=0;h<s&&!(n(h)>=l.count);h++){let g=e.$.agents[M(h)],y=m(g.x,g.y),b=o.sub(y),x=Se(b,b);x>1e-7&&x<l.perceptionSq&&(d=d.add(m(g.z,g.w)),u=u.add(y),p=__tsover_add(p,1),x<l.sepRadiusSq&&(c=c.add(b.div(x)),_=__tsover_add(_,1)))}let f=m(0,0);if(p>.5){let h=v1(d.div(p),a,i,l.maxForce),g=v1(u.div(p).sub(o),a,i,l.maxForce);f=f.add(h.mul(l.aliW)).add(g.mul(l.cohW))}return _>.5&&(f=f.add(v1(c,a,i,l.maxForce).mul(l.sepW))),f}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"vel\"},{type:\"i\",name:\"maxSpeedI\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[12,\"sep\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"ali\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"coh\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[12,\"nCount\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"sCount\",[6,\"d.f32\",[[5,\"0\"]]]],[14,[12,\"j\",[5,\"0\"]],[1,\"j\",\"<\",\"MAX_AGENTS\"],[102,\"++\",\"j\"],[0,[[11,[1,[6,\"d.f32\",[\"j\"]],\">=\",[7,\"prm\",\"count\"]],[0,[[17]]]],[13,\"other\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],[6,\"d.u32\",[\"j\"]]]],[13,\"opos\",[6,\"d.vec2f\",[[7,\"other\",\"x\"],[7,\"other\",\"y\"]]]],[13,\"off\",[6,[7,\"pos\",\"sub\"],[\"opos\"]]],[13,\"dsq\",[6,\"std.dot\",[\"off\",\"off\"]]],[11,[3,[1,\"dsq\",\">\",[5,\"1e-7\"]],\"&&\",[1,\"dsq\",\"<\",[7,\"prm\",\"perceptionSq\"]]],[0,[[2,\"ali\",\"=\",[6,[7,\"ali\",\"add\"],[[6,\"d.vec2f\",[[7,\"other\",\"z\"],[7,\"other\",\"w\"]]]]]],[2,\"coh\",\"=\",[6,[7,\"coh\",\"add\"],[\"opos\"]]],[2,\"nCount\",\"=\",[1,\"nCount\",\"+\",[5,\"1\"]]],[11,[1,\"dsq\",\"<\",[7,\"prm\",\"sepRadiusSq\"]],[0,[[2,\"sep\",\"=\",[6,[7,\"sep\",\"add\"],[[6,[7,\"off\",\"div\"],[\"dsq\"]]]]],[2,\"sCount\",\"=\",[1,\"sCount\",\"+\",[5,\"1\"]]]]]]]]]]]],[12,\"accel\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[11,[1,\"nCount\",\">\",[5,\"0.5\"]],[0,[[13,\"aliSteer\",[6,\"agents.reynoldsSteer\",[[6,[7,\"ali\",\"div\"],[\"nCount\"]],\"vel\",\"maxSpeedI\",[7,\"prm\",\"maxForce\"]]]],[13,\"cohSteer\",[6,\"agents.reynoldsSteer\",[[6,[7,[6,[7,\"coh\",\"div\"],[\"nCount\"]],\"sub\"],[\"pos\"]],\"vel\",\"maxSpeedI\",[7,\"prm\",\"maxForce\"]]]],[2,\"accel\",\"=\",[6,[7,[6,[7,\"accel\",\"add\"],[[6,[7,\"aliSteer\",\"mul\"],[[7,\"prm\",\"aliW\"]]]]],\"add\"],[[6,[7,\"cohSteer\",\"mul\"],[[7,\"prm\",\"cohW\"]]]]]]]]],[11,[1,\"sCount\",\">\",[5,\"0.5\"]],[0,[[2,\"accel\",\"=\",[6,[7,\"accel\",\"add\"],[[6,[7,[6,\"agents.reynoldsSteer\",[\"sep\",\"vel\",\"maxSpeedI\",[7,\"prm\",\"maxForce\"]]],\"mul\"],[[7,\"prm\",\"sepW\"]]]]]]]]],[10,\"accel\"]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"d.f32\":()=>n,MAX_AGENTS:()=>s,\"d.u32\":()=>M,\"std.dot\":()=>Se,\"agents.reynoldsSteer\":()=>v1}})&&r.f)({})).$name(\"forceFlocking\")}function Nce(e){return w.fn([m,m,n],m)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";let a=e.$.params,i=m(0,0);if(a.cursorMode>.5){let l=m(a.cursorX,a.cursorY).sub(s),c=Se(l,l);if(c>1e-7&&c<a.cursorRadiusSq){let d=Ue(c),u=__tsover_sub(1,__tsover_div(d,B(a.cursorRadius,1e-5))),p=N(n(1),n(-1),a.cursorMode>1.5);i=l.div(d).mul(__tsover_mul(__tsover_mul(p,u),a.cursorForce))}}return i}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"_maxSpeedI\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[12,\"accel\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[11,[1,[7,\"prm\",\"cursorMode\"],\">\",[5,\"0.5\"]],[0,[[13,\"cd\",[6,[7,[6,\"d.vec2f\",[[7,\"prm\",\"cursorX\"],[7,\"prm\",\"cursorY\"]]],\"sub\"],[\"pos\"]]],[13,\"cdsq\",[6,\"std.dot\",[\"cd\",\"cd\"]]],[11,[3,[1,\"cdsq\",\">\",[5,\"1e-7\"]],\"&&\",[1,\"cdsq\",\"<\",[7,\"prm\",\"cursorRadiusSq\"]]],[0,[[13,\"cdist\",[6,\"std.sqrt\",[\"cdsq\"]]],[13,\"falloff\",[1,[5,\"1\"],\"-\",[1,\"cdist\",\"/\",[6,\"std.max\",[[7,\"prm\",\"cursorRadius\"],[5,\"0.00001\"]]]]]],[13,\"sign\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],[6,\"d.f32\",[[4,\"-\",[5,\"1\"]]]],[1,[7,\"prm\",\"cursorMode\"],\">\",[5,\"1.5\"]]]]],[2,\"accel\",\"=\",[6,[7,[6,[7,\"cd\",\"div\"],[\"cdist\"]],\"mul\"],[[1,[1,\"sign\",\"*\",\"falloff\"],\"*\",[7,\"prm\",\"cursorForce\"]]]]]]]]]]],[10,\"accel\"]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"std.dot\":()=>Se,\"std.sqrt\":()=>Ue,\"std.max\":()=>B,\"std.select\":()=>N,\"d.f32\":()=>n}})&&t.f)({})).$name(\"forceCursorSteer\")}function $ce(e){return w.fn([m,m,n],m)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";let a=e.$.params,i=a.margin,l=a.turnForce;return m(__tsover_add(N(n(0),l,s.x<i),N(n(0),-l,s.x>__tsover_sub(a.domainX,i))),__tsover_add(N(n(0),l,s.y<i),N(n(0),-l,s.y>__tsover_sub(1,i))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"_vel\"},{type:\"i\",name:\"_maxSpeedI\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"m\",[7,\"prm\",\"margin\"]],[13,\"tf\",[7,\"prm\",\"turnForce\"]],[13,\"ax\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"tf\",[1,[7,\"pos\",\"x\"],\"<\",\"m\"]]],\"+\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[4,\"-\",\"tf\"],[1,[7,\"pos\",\"x\"],\">\",[1,[7,\"prm\",\"domainX\"],\"-\",\"m\"]]]]]],[13,\"ay\",[1,[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"tf\",[1,[7,\"pos\",\"y\"],\"<\",\"m\"]]],\"+\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[4,\"-\",\"tf\"],[1,[7,\"pos\",\"y\"],\">\",[1,[5,\"1\"],\"-\",\"m\"]]]]]],[10,[6,\"d.vec2f\",[\"ax\",\"ay\"]]]]]},externals:{layout:()=>e,\"std.select\":()=>N,\"d.f32\":()=>n,\"d.vec2f\":()=>m}})&&t.f)({})).$name(\"forceWallTurn\")}function Xce(e){return e.reduce((t,s,r)=>w.fn([m,m,n],m)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i,l)=>{\"use gpu\";return t(a,i,l).add(s(a,i,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"},{type:\"i\",name:\"vel\"},{type:\"i\",name:\"maxSpeedI\"}],body:[0,[[10,[6,[7,[6,\"acc\",[\"pos\",\"vel\",\"maxSpeedI\"]],\"add\"],[[6,\"part\",[\"pos\",\"vel\",\"maxSpeedI\"]]]]]]]},externals:{acc:()=>t,part:()=>s}})&&o.f)({})).$name(`steerSum${r}`))}function Hce(e,t){let s=Xce(t.forces),{rest:r,gain:o,cool:a}=t.agitation,i=t.cruiseFloor,l=t.wallRestitution;return w.fn([M])((c=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(c.f=(d=>{\"use gpu\";let u=e.$.params,p=e.$.agents[d],_=m(p.x,p.y),f=m(p.z,p.w),h=u.dt,g=__tsover_mul(u.maxSpeed,wP(n(d))),y=s(_,f,g),b=__tsover_div(he(y),B(u.maxForce,1e-5)),x=G(__tsover_mul(__tsover_sub(b,r),o),0,1),P=__tsover_mul(e.$.agit[d],Tt(__tsover_mul(h,-a)));e.$.agit[d]=B(x,P),f=f.add(y.mul(h));let C=he(f),E=G(C,__tsover_mul(g,i),g);f=f.div(B(C,1e-5)).mul(E),_=_.add(f.mul(h));let R=_.x<0||_.x>u.domainX,U=_.y<0||_.y>1,L=N(f.x,__tsover_mul(f.x,-l),R),k=N(f.y,__tsover_mul(f.y,-l),U),D=G(_.x,0,u.domainX),O=G(_.y,0,1);e.$.agents[d]=S(D,O,L,k)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"self\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"]],[12,\"pos\",[6,\"d.vec2f\",[[7,\"self\",\"x\"],[7,\"self\",\"y\"]]]],[12,\"vel\",[6,\"d.vec2f\",[[7,\"self\",\"z\"],[7,\"self\",\"w\"]]]],[13,\"dt\",[7,\"prm\",\"dt\"]],[13,\"maxSpeedI\",[1,[7,\"prm\",\"maxSpeed\"],\"*\",[6,\"agents.cruiseVariation\",[[6,\"d.f32\",[\"i\"]]]]]],[13,\"accel\",[6,\"total\",[\"pos\",\"vel\",\"maxSpeedI\"]]],[13,\"effort\",[1,[6,\"std.length\",[\"accel\"]],\"/\",[6,\"std.max\",[[7,\"prm\",\"maxForce\"],[5,\"0.00001\"]]]]],[13,\"raw\",[6,\"std.clamp\",[[1,[1,\"effort\",\"-\",\"AGIT_REST\"],\"*\",\"AGIT_GAIN\"],[5,\"0\"],[5,\"1\"]]]],[13,\"cooled\",[1,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"*\",[6,\"std.exp\",[[1,\"dt\",\"*\",[4,\"-\",\"AGIT_COOL\"]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"=\",[6,\"std.max\",[\"raw\",\"cooled\"]]],[2,\"vel\",\"=\",[6,[7,\"vel\",\"add\"],[[6,[7,\"accel\",\"mul\"],[\"dt\"]]]]],[13,\"spd\",[6,\"std.length\",[\"vel\"]]],[13,\"clamped\",[6,\"std.clamp\",[\"spd\",[1,\"maxSpeedI\",\"*\",\"FLOOR\"],\"maxSpeedI\"]]],[2,\"vel\",\"=\",[6,[7,[6,[7,\"vel\",\"div\"],[[6,\"std.max\",[\"spd\",[5,\"0.00001\"]]]]],\"mul\"],[\"clamped\"]]],[2,\"pos\",\"=\",[6,[7,\"pos\",\"add\"],[[6,[7,\"vel\",\"mul\"],[\"dt\"]]]]],[13,\"hitX\",[3,[1,[7,\"pos\",\"x\"],\"<\",[5,\"0\"]],\"||\",[1,[7,\"pos\",\"x\"],\">\",[7,\"prm\",\"domainX\"]]]],[13,\"hitY\",[3,[1,[7,\"pos\",\"y\"],\"<\",[5,\"0\"]],\"||\",[1,[7,\"pos\",\"y\"],\">\",[5,\"1\"]]]],[13,\"nvx\",[6,\"std.select\",[[7,\"vel\",\"x\"],[1,[7,\"vel\",\"x\"],\"*\",[4,\"-\",\"REST\"]],\"hitX\"]]],[13,\"nvy\",[6,\"std.select\",[[7,\"vel\",\"y\"],[1,[7,\"vel\",\"y\"],\"*\",[4,\"-\",\"REST\"]],\"hitY\"]]],[13,\"cx\",[6,\"std.clamp\",[[7,\"pos\",\"x\"],[5,\"0\"],[7,\"prm\",\"domainX\"]]]],[13,\"cy\",[6,\"std.clamp\",[[7,\"pos\",\"y\"],[5,\"0\"],[5,\"1\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[\"cx\",\"cy\",\"nvx\",\"nvy\"]]]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"agents.cruiseVariation\":()=>wP,\"d.f32\":()=>n,total:()=>s,\"std.length\":()=>he,\"std.max\":()=>B,\"std.clamp\":()=>G,AGIT_REST:()=>r,AGIT_GAIN:()=>o,\"std.exp\":()=>Tt,AGIT_COOL:()=>a,FLOOR:()=>i,\"std.select\":()=>N,REST:()=>l,\"d.vec4f\":()=>S}})&&c.f)({})).$name(t.name)}var Tu=gt({rhat:m,strength:n,phi:n}).$name(\"AgentFieldSample\");function jce(e){return w.fn([m],Tu)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=(s=>{\"use gpu\";let r=e.$.params,o=m(r.cursorX,r.cursorY),a=s.sub(o),i=B(he(a),1e-4),l=a.div(i),c=TP(l,m(r.axisX,r.axisY),r.fieldType);return Tu({rhat:l,strength:__tsover_mul(r.strength,Tt(__tsover_mul(__tsover_div(__tsover_mul(i,i),B(r.reachSq,1e-6)),-1))),phi:Xt(c.y,c.x)})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"cursor\",[6,\"d.vec2f\",[[7,\"prm\",\"cursorX\"],[7,\"prm\",\"cursorY\"]]]],[13,\"delta\",[6,[7,\"pos\",\"sub\"],[\"cursor\"]]],[13,\"r\",[6,\"std.max\",[[6,\"std.length\",[\"delta\"]],[5,\"0.0001\"]]]],[13,\"rhat\",[6,[7,\"delta\",\"div\"],[\"r\"]]],[13,\"axis\",[6,\"d.vec2f\",[[7,\"prm\",\"axisX\"],[7,\"prm\",\"axisY\"]]]],[13,\"B\",[6,\"agents.dipoleOrRadialField\",[\"rhat\",\"axis\",[7,\"prm\",\"fieldType\"]]]],[13,\"fieldStr\",[1,[7,\"prm\",\"strength\"],\"*\",[6,\"std.exp\",[[1,[1,[1,\"r\",\"*\",\"r\"],\"/\",[6,\"std.max\",[[7,\"prm\",\"reachSq\"],[5,\"0.000001\"]]]],\"*\",[4,\"-\",[5,\"1\"]]]]]]],[10,[6,\"FieldSample\",[[104,{rhat:\"rhat\",strength:\"fieldStr\",phi:[6,\"std.atan2\",[[7,\"B\",\"y\"],[7,\"B\",\"x\"]]]}]]]]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"std.length\":()=>he,\"agents.dipoleOrRadialField\":()=>TP,\"std.exp\":()=>Tt,FieldSample:()=>Tu,\"std.atan2\":()=>Xt}})&&t.f)({})).$name(\"agentFieldDipoleOrRadial\")}var yC=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return N(N(__tsover_mul(Xs(__tsover_add(__tsover_mul(t,2.3987),.517)),3.141592653589793),n(0),s>.5),n(1.5707963267948966),s>1.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"},{type:\"i\",name:\"restMode\"}],body:[0,[[13,\"randAng\",[1,[6,\"noise.hash11\",[[1,[1,\"fi\",\"*\",[5,\"2.3987\"]],\"+\",[5,\"0.517\"]]]],\"*\",[5,\"3.141592653589793\"]]],[13,\"a\",[6,\"std.select\",[\"randAng\",[6,\"d.f32\",[[5,\"0\"]]],[1,\"restMode\",\">\",[5,\"0.5\"]]]]],[10,[6,\"std.select\",[\"a\",[6,\"d.f32\",[[5,\"1.5707963267948966\"]]],[1,\"restMode\",\">\",[5,\"1.5\"]]]]]]]},externals:{\"noise.hash11\":()=>Xs,\"std.select\":()=>N,\"d.f32\":()=>n}})&&e.f)({})).$name(\"agentRestAngle\");function Kce(e){return w.fn([Tu,n,n],n)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";return Jv(__tsover_mul(e.$.params.alignK,s.strength),s.phi,r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fld\"},{type:\"i\",name:\"theta\"},{type:\"i\",name:\"_fi\"}],body:[0,[[10,[6,\"agents.nematicTorque\",[[1,[7,[7,[7,\"layout\",\"$\"],\"params\"],\"alignK\"],\"*\",[7,\"fld\",\"strength\"]],[7,\"fld\",\"phi\"],\"theta\"]]]]]},externals:{\"agents.nematicTorque\":()=>Jv,layout:()=>e}})&&t.f)({})).$name(\"torqueAlignToField\")}function Qce(e){return w.fn([Tu,n,n],n)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=((s,r,o)=>{\"use gpu\";let a=e.$.params;return Jv(a.restK,yC(o,a.restMode),r)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_fld\"},{type:\"i\",name:\"theta\"},{type:\"i\",name:\"fi\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[10,[6,\"agents.nematicTorque\",[[7,\"prm\",\"restK\"],[6,\"restOrientationAngle\",[\"fi\",[7,\"prm\",\"restMode\"]]],\"theta\"]]]]]},externals:{layout:()=>e,\"agents.nematicTorque\":()=>Jv,restOrientationAngle:()=>yC}})&&t.f)({})).$name(\"torqueRest\")}function Zce(e){return e.reduce((t,s,r)=>w.fn([Tu,n,n],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=((a,i,l)=>{\"use gpu\";return __tsover_add(t(a,i,l),s(a,i,l))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fld\"},{type:\"i\",name:\"theta\"},{type:\"i\",name:\"fi\"}],body:[0,[[10,[1,[6,\"acc\",[\"fld\",\"theta\",\"fi\"]],\"+\",[6,\"part\",[\"fld\",\"theta\",\"fi\"]]]]]]},externals:{acc:()=>t,part:()=>s}})&&o.f)({})).$name(`torqueSum${r}`))}function Jce(e,t){let s=t.overscan;return w.fn([n],m)((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=(o=>{\"use gpu\";let a=e.$.params,i=a.gridCols,l=ie(__tsover_div(o,B(i,1))),c=__tsover_sub(o,__tsover_mul(l,B(i,1))),d=Pr(m(__tsover_add(__tsover_mul(o,.7548),.11),__tsover_add(__tsover_mul(o,1.3236),5.31))),u=__tsover_mul(__tsover_sub(d.x,.5),a.jitter),p=__tsover_mul(__tsover_sub(d.y,.5),a.jitter);return m(__tsover_sub(__tsover_mul(__tsover_add(__tsover_add(c,.5),u),a.cellW),s),__tsover_sub(__tsover_mul(__tsover_add(__tsover_add(l,.5),p),a.cellH),s))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"cols\",[7,\"prm\",\"gridCols\"]],[13,\"row\",[6,\"std.floor\",[[1,\"fi\",\"/\",[6,\"std.max\",[\"cols\",[5,\"1\"]]]]]]],[13,\"col\",[1,\"fi\",\"-\",[1,\"row\",\"*\",[6,\"std.max\",[\"cols\",[5,\"1\"]]]]]],[13,\"h\",[6,\"noise.hash22\",[[6,\"d.vec2f\",[[1,[1,\"fi\",\"*\",[5,\"0.7548\"]],\"+\",[5,\"0.11\"]],[1,[1,\"fi\",\"*\",[5,\"1.3236\"]],\"+\",[5,\"5.31\"]]]]]]],[13,\"jx\",[1,[1,[7,\"h\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",[7,\"prm\",\"jitter\"]]],[13,\"jy\",[1,[1,[7,\"h\",\"y\"],\"-\",[5,\"0.5\"]],\"*\",[7,\"prm\",\"jitter\"]]],[10,[6,\"d.vec2f\",[[1,[1,[1,[1,\"col\",\"+\",[5,\"0.5\"]],\"+\",\"jx\"],\"*\",[7,\"prm\",\"cellW\"]],\"-\",\"OVERSCAN\"],[1,[1,[1,[1,\"row\",\"+\",[5,\"0.5\"]],\"+\",\"jy\"],\"*\",[7,\"prm\",\"cellH\"]],\"-\",\"OVERSCAN\"]]]]]]},externals:{layout:()=>e,\"std.floor\":()=>ie,\"std.max\":()=>B,\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m,OVERSCAN:()=>s}})&&r.f)({})).$name(\"agentJitteredHome\")}function ede(e,t){let{home:s,fieldAt:r}=t,o=Zce(t.torques),a=t.maxOffset;return w.fn([M])((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=(l=>{\"use gpu\";let c=e.$.params,d=e.$.agents[l],u=m(d.x,d.y),p=d.z,_=d.w,f=c.dt,h=n(l),g=s(h),y=r(m(__tsover_add(g.x,u.x),__tsover_add(g.y,u.y)));_=__tsover_add(_,__tsover_mul(o(y,p,h),f)),_=__tsover_mul(_,Tt(__tsover_mul(__tsover_mul(c.damping,f),-1))),p=__tsover_add(p,__tsover_mul(_,f));let b=G(__tsover_div(re(_),B(c.omegaRef,1e-5)),0,1),x=__tsover_mul(e.$.agit[l],Tt(__tsover_mul(f,-c.agitCool)));e.$.agit[l]=B(b,x);let P=y.rhat.mul(__tsover_mul(__tsover_mul(c.pullK,y.strength),-1));u=u.add(P.mul(f)),u=u.mul(Tt(__tsover_mul(__tsover_mul(c.homeK,f),-1)));let C=he(u);u=N(u,u.div(B(C,1e-5)).mul(a),C>a),e.$.agents[l]=S(u.x,u.y,p,_)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"st\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"]],[12,\"off\",[6,\"d.vec2f\",[[7,\"st\",\"x\"],[7,\"st\",\"y\"]]]],[12,\"theta\",[7,\"st\",\"z\"]],[12,\"omega\",[7,\"st\",\"w\"]],[13,\"dt\",[7,\"prm\",\"dt\"]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"homeP\",[6,\"home\",[\"fi\"]]],[13,\"pos\",[6,\"d.vec2f\",[[1,[7,\"homeP\",\"x\"],\"+\",[7,\"off\",\"x\"]],[1,[7,\"homeP\",\"y\"],\"+\",[7,\"off\",\"y\"]]]]],[13,\"fld\",[6,\"fieldAt\",[\"pos\"]]],[2,\"omega\",\"=\",[1,\"omega\",\"+\",[1,[6,\"total\",[\"fld\",\"theta\",\"fi\"]],\"*\",\"dt\"]]],[2,\"omega\",\"=\",[1,\"omega\",\"*\",[6,\"std.exp\",[[1,[1,[7,\"prm\",\"damping\"],\"*\",\"dt\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]],[2,\"theta\",\"=\",[1,\"theta\",\"+\",[1,\"omega\",\"*\",\"dt\"]]],[13,\"raw\",[6,\"std.clamp\",[[1,[6,\"std.abs\",[\"omega\"]],\"/\",[6,\"std.max\",[[7,\"prm\",\"omegaRef\"],[5,\"0.00001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"cooled\",[1,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"*\",[6,\"std.exp\",[[1,\"dt\",\"*\",[4,\"-\",[7,\"prm\",\"agitCool\"]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agit\"],\"i\"],\"=\",[6,\"std.max\",[\"raw\",\"cooled\"]]],[13,\"pull\",[6,[7,[7,\"fld\",\"rhat\"],\"mul\"],[[1,[1,[7,\"prm\",\"pullK\"],\"*\",[7,\"fld\",\"strength\"]],\"*\",[4,\"-\",[5,\"1\"]]]]]],[2,\"off\",\"=\",[6,[7,\"off\",\"add\"],[[6,[7,\"pull\",\"mul\"],[\"dt\"]]]]],[2,\"off\",\"=\",[6,[7,\"off\",\"mul\"],[[6,\"std.exp\",[[1,[1,[7,\"prm\",\"homeK\"],\"*\",\"dt\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]]],[13,\"offLen\",[6,\"std.length\",[\"off\"]]],[2,\"off\",\"=\",[6,\"std.select\",[\"off\",[6,[7,[6,[7,\"off\",\"div\"],[[6,\"std.max\",[\"offLen\",[5,\"0.00001\"]]]]],\"mul\"],[\"MAX_OFFSET\"]],[1,\"offLen\",\">\",\"MAX_OFFSET\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"off\",\"x\"],[7,\"off\",\"y\"],\"theta\",\"omega\"]]]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"d.f32\":()=>n,home:()=>s,fieldAt:()=>r,total:()=>o,\"std.exp\":()=>Tt,\"std.clamp\":()=>G,\"std.abs\":()=>re,\"std.max\":()=>B,\"std.length\":()=>he,\"std.select\":()=>N,MAX_OFFSET:()=>a,\"d.vec4f\":()=>S}})&&i.f)({})).$name(t.name)}function tde(e){return w.fn([n],m)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=(s=>{\"use gpu\";let r=e.$.params,o=Pr(m(__tsover_add(__tsover_mul(s,.7548),.13),__tsover_add(__tsover_mul(s,1.3236),5.71))),a=__tsover_add(1,__tsover_mul(__tsover_sub(o.x,.5),r.speedVar)),i=__tsover_add(r.angleRad,__tsover_mul(__tsover_mul(__tsover_sub(o.y,.5),2),r.angleVarRad));return m(pe(i),ae(i)).mul(__tsover_mul(r.driftBase,a))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"fi\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"h\",[6,\"noise.hash22\",[[6,\"d.vec2f\",[[1,[1,\"fi\",\"*\",[5,\"0.7548\"]],\"+\",[5,\"0.13\"]],[1,[1,\"fi\",\"*\",[5,\"1.3236\"]],\"+\",[5,\"5.71\"]]]]]]],[13,\"speedMul\",[1,[5,\"1\"],\"+\",[1,[1,[7,\"h\",\"x\"],\"-\",[5,\"0.5\"]],\"*\",[7,\"prm\",\"speedVar\"]]]],[13,\"ang\",[1,[7,\"prm\",\"angleRad\"],\"+\",[1,[1,[1,[7,\"h\",\"y\"],\"-\",[5,\"0.5\"]],\"*\",[5,\"2\"]],\"*\",[7,\"prm\",\"angleVarRad\"]]]],[10,[6,[7,[6,\"d.vec2f\",[[6,\"std.cos\",[\"ang\"]],[6,\"std.sin\",[\"ang\"]]]],\"mul\"],[[1,[7,\"prm\",\"driftBase\"],\"*\",\"speedMul\"]]]]]]},externals:{layout:()=>e,\"noise.hash22\":()=>Pr,\"d.vec2f\":()=>m,\"std.cos\":()=>pe,\"std.sin\":()=>ae}})&&t.f)({})).$name(\"driftVariedHeading\")}function sde(e){return w.fn([m],m)((t=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(t.f=(s=>{\"use gpu\";let r=e.$.params,o=m(0,0);return r.cursorForce>1e-5&&(o=Xu(s.sub(m(r.cursorX,r.cursorY)),r.cursorRadSq,r.cursorForce).mul(r.dt)),o}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"pos\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[12,\"impulse\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]]],[11,[1,[7,\"prm\",\"cursorForce\"],\">\",[5,\"0.00001\"]],[0,[[13,\"delta\",[6,[7,\"pos\",\"sub\"],[[6,\"d.vec2f\",[[7,\"prm\",\"cursorX\"],[7,\"prm\",\"cursorY\"]]]]]],[2,\"impulse\",\"=\",[6,[7,[6,\"agents.cursorMagnet\",[\"delta\",[7,\"prm\",\"cursorRadSq\"],[7,\"prm\",\"cursorForce\"]]],\"mul\"],[[7,\"prm\",\"dt\"]]]]]]],[10,\"impulse\"]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"agents.cursorMagnet\":()=>Xu}})&&t.f)({})).$name(\"forceCursorGust\")}function rde(e,t){let{drift:s,gust:r}=t;return w.fn([M])((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=(a=>{\"use gpu\";let i=e.$.params,l=e.$.agents[a],c=n(a),d=i.dt,u=m(l.x,l.y),p=m(l.z,l.w);p=p.add(r(u)),p=p.mul(i.dragMul),u=u.add(s(c).add(p).mul(d));let _=__tsover_sub(u.x,__tsover_mul(ie(__tsover_div(u.x,B(i.domainX,1e-4))),i.domainX)),f=__tsover_sub(u.y,ie(u.y));e.$.agents[a]=S(_,f,p.x,p.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"s\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"dt\",[7,\"prm\",\"dt\"]],[12,\"pos\",[6,\"d.vec2f\",[[7,\"s\",\"x\"],[7,\"s\",\"y\"]]]],[12,\"gustV\",[6,\"d.vec2f\",[[7,\"s\",\"z\"],[7,\"s\",\"w\"]]]],[2,\"gustV\",\"=\",[6,[7,\"gustV\",\"add\"],[[6,\"gust\",[\"pos\"]]]]],[2,\"gustV\",\"=\",[6,[7,\"gustV\",\"mul\"],[[7,\"prm\",\"dragMul\"]]]],[2,\"pos\",\"=\",[6,[7,\"pos\",\"add\"],[[6,[7,[6,[7,[6,\"drift\",[\"fi\"]],\"add\"],[\"gustV\"]],\"mul\"],[\"dt\"]]]]],[13,\"wx\",[1,[7,\"pos\",\"x\"],\"-\",[1,[6,\"std.floor\",[[1,[7,\"pos\",\"x\"],\"/\",[6,\"std.max\",[[7,\"prm\",\"domainX\"],[5,\"0.0001\"]]]]]],\"*\",[7,\"prm\",\"domainX\"]]]],[13,\"wy\",[1,[7,\"pos\",\"y\"],\"-\",[6,\"std.floor\",[[7,\"pos\",\"y\"]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[\"wx\",\"wy\",[7,\"gustV\",\"x\"],[7,\"gustV\",\"y\"]]]]]]},externals:{layout:()=>e,\"d.f32\":()=>n,\"d.vec2f\":()=>m,gust:()=>r,drift:()=>s,\"std.floor\":()=>ie,\"std.max\":()=>B,\"d.vec4f\":()=>S}})&&o.f)({})).$name(t.name)}var bC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return Se(t,A(.299,.587,.114))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[10,[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),xC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return __tsover_sub(1,Se(t,A(.299,.587,.114)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[10,[1,[5,\"1\"],\"-\",[6,\"std.dot\",[\"rgb\",[6,\"d.vec3f\",[[5,\"0.299\"],[5,\"0.587\"],[5,\"0.114\"]]]]]]]]]},externals:{\"std.dot\":()=>Se,\"d.vec3f\":()=>A}})&&e.f)({})),AC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t.x}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[10,[7,\"rgb\",\"x\"]]]]},externals:{}})&&e.f)({})),wC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t.y}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[10,[7,\"rgb\",\"y\"]]]]},externals:{}})&&e.f)({})),TC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return t.z}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[10,[7,\"rgb\",\"z\"]]]]},externals:{}})&&e.f)({})),SC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=B(B(t.x,t.y),t.z),o=ye(ye(t.x,t.y),t.z);return __tsover_sub(r,o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"rgb\"},{type:\"i\",name:\"_a\"}],body:[0,[[13,\"mx\",[6,\"std.max\",[[6,\"std.max\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"]]],[7,\"rgb\",\"z\"]]]],[13,\"mn\",[6,\"std.min\",[[6,\"std.min\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"]]],[7,\"rgb\",\"z\"]]]],[10,[1,\"mx\",\"-\",\"mn\"]]]]},externals:{\"std.max\":()=>B,\"std.min\":()=>ye}})&&e.f)({})),PC=w.fn([A,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return s}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"_rgb\"},{type:\"i\",name:\"a\"}],body:[0,[[10,\"a\"]]]},externals:{}})&&e.f)({})),x2={luminance:bC,luminanceInverted:xC,red:AC,green:wC,blue:TC,saturation:SC,alpha:PC,byMode:{0:bC,1:xC,2:AC,3:wC,4:TC,5:SC,6:PC}};function ode(e,t){let s=t.perspK;return w.fn([m,m,n],A)((r=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(r.f=((o,a,i)=>{\"use gpu\";let l=e.$.params,c=eh(A(__tsover_add(o.x,a.x),__tsover_add(o.y,a.y),i),l.rowX,l.rowY,l.rowZ),d=__tsover_div(l.zoom,G(__tsover_sub(1,__tsover_mul(c.z,s)),.35,2.6)),u=__tsover_add(__tsover_add(.5,__tsover_div(__tsover_mul(c.x,d),l.aspect)),l.transX),p=__tsover_add(__tsover_add(.5,__tsover_mul(c.y,d)),l.transY),_=m(__tsover_mul(__tsover_sub(u,l.pointerX),l.aspect),__tsover_sub(p,l.pointerY)),f=Xu(_,l.cursorRadSq,l.cursorForce),h=__tsover_mul(sh(_,l.cursorRadSq),l.cursorZForce);return PP(A(f.x,f.y,h),l.rowX,l.rowY,l.rowZ)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"homeW\"},{type:\"i\",name:\"off\"},{type:\"i\",name:\"z\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"pw\",[6,\"d.vec3f\",[[1,[7,\"homeW\",\"x\"],\"+\",[7,\"off\",\"x\"]],[1,[7,\"homeW\",\"y\"],\"+\",[7,\"off\",\"y\"]],\"z\"]]],[13,\"rv\",[6,\"agents.applyCameraRows\",[\"pw\",[7,\"P\",\"rowX\"],[7,\"P\",\"rowY\"],[7,\"P\",\"rowZ\"]]]],[13,\"persp\",[1,[7,\"P\",\"zoom\"],\"/\",[6,\"std.clamp\",[[1,[5,\"1\"],\"-\",[1,[7,\"rv\",\"z\"],\"*\",\"PERSP_K\"]],[5,\"0.35\"],[5,\"2.6\"]]]]],[13,\"su\",[1,[1,[5,\"0.5\"],\"+\",[1,[1,[7,\"rv\",\"x\"],\"*\",\"persp\"],\"/\",[7,\"P\",\"aspect\"]]],\"+\",[7,\"P\",\"transX\"]]],[13,\"sv\",[1,[1,[5,\"0.5\"],\"+\",[1,[7,\"rv\",\"y\"],\"*\",\"persp\"]],\"+\",[7,\"P\",\"transY\"]]],[13,\"deltaS\",[6,\"d.vec2f\",[[1,[1,\"su\",\"-\",[7,\"P\",\"pointerX\"]],\"*\",[7,\"P\",\"aspect\"]],[1,\"sv\",\"-\",[7,\"P\",\"pointerY\"]]]]],[13,\"mxy\",[6,\"agents.cursorMagnet\",[\"deltaS\",[7,\"P\",\"cursorRadSq\"],[7,\"P\",\"cursorForce\"]]]],[13,\"mz\",[1,[6,\"agents.cursorFalloff\",[\"deltaS\",[7,\"P\",\"cursorRadSq\"]]],\"*\",[7,\"P\",\"cursorZForce\"]]],[10,[6,\"agents.applyCameraRowsTransposed\",[[6,\"d.vec3f\",[[7,\"mxy\",\"x\"],[7,\"mxy\",\"y\"],\"mz\"]],[7,\"P\",\"rowX\"],[7,\"P\",\"rowY\"],[7,\"P\",\"rowZ\"]]]]]]},externals:{layout:()=>e,\"d.vec3f\":()=>A,\"agents.applyCameraRows\":()=>eh,\"std.clamp\":()=>G,PERSP_K:()=>s,\"d.vec2f\":()=>m,\"agents.cursorMagnet\":()=>Xu,\"agents.cursorFalloff\":()=>sh,\"agents.applyCameraRowsTransposed\":()=>PP}})&&r.f)({})).$name(\"forceCursorInView\")}function ade(e,t){let{channel:s,cursor:r}=t,o=t.stiffness,a=t.maxSpeed,i=t.minAlpha;return w.fn([M,M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=((c,d)=>{\"use gpu\";let u=e.$.params,p=__tsover_add(__tsover_mul(d,M(u.gridW)),c),_=__tsover_div(__tsover_add(n(c),.5),u.gridW),f=__tsover_div(__tsover_add(n(d),.5),u.gridH),h=Ti(e.$.src),g=th(m(_,f),m(n(h.x),n(h.y))),y=Ye(e.$.src,fe(g.x0,g.y0),0),b=Ye(e.$.src,fe(g.x1,g.y0),0),x=Ye(e.$.src,fe(g.x0,g.y1),0),P=Ye(e.$.src,fe(g.x1,g.y1),0),C=K(K(y,b,g.fx),K(x,P,g.fx),g.fy),E=C.w,R=C.xyz.div(B(E,n(1e-4)));e.$.col[p]=S(R.x,R.y,R.z,E);let U=s(R,E),L=__tsover_mul(__tsover_sub(U,.5),u.depth),k=e.$.pos[p],D=e.$.vel[p],O=u.dt,F=u.snap>.5||D.w<.5,q=m(__tsover_mul(__tsover_sub(_,.5),u.aspect),__tsover_sub(f,.5)),Y=m(k.x,k.y),V=r(q,Y,k.z),X=A(__tsover_mul(Y.x,-o),__tsover_mul(Y.y,-o),__tsover_mul(__tsover_sub(L,k.z),o)).add(V),Q=nh(A(D.x,D.y,D.z),X,O,u.dragMul,n(a)),te=Y.add(m(Q.x,Q.y).mul(O)),J=__tsover_add(k.z,__tsover_mul(Q.z,O));te=N(te,m(0,0),F),J=N(J,L,F),Q=N(Q,A(0,0,0),F);let oe=Ys(m(__tsover_add(n(c),.5),__tsover_add(n(d),.5))),le=N(D.w,n(1),E>i);e.$.pos[p]=S(te.x,te.y,J,oe),e.$.vel[p]=S(Q.x,Q.y,Q.z,le)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"gx\"},{type:\"i\",name:\"gy\"}],body:[0,[[13,\"P\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"i\",[1,[1,\"gy\",\"*\",[6,\"d.u32\",[[7,\"P\",\"gridW\"]]]],\"+\",\"gx\"]],[13,\"homeU\",[1,[1,[6,\"d.f32\",[\"gx\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"P\",\"gridW\"]]],[13,\"homeV\",[1,[1,[6,\"d.f32\",[\"gy\"]],\"+\",[5,\"0.5\"]],\"/\",[7,\"P\",\"gridH\"]]],[13,\"dims\",[6,\"std.textureDimensions\",[[7,[7,\"layout\",\"$\"],\"src\"]]]],[13,\"bf\",[6,\"agents.bilinearTexelFrame\",[[6,\"d.vec2f\",[\"homeU\",\"homeV\"]],[6,\"d.vec2f\",[[6,\"d.f32\",[[7,\"dims\",\"x\"]]],[6,\"d.f32\",[[7,\"dims\",\"y\"]]]]]]]],[13,\"c00\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[[7,\"bf\",\"x0\"],[7,\"bf\",\"y0\"]]],[5,\"0\"]]]],[13,\"c10\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[[7,\"bf\",\"x1\"],[7,\"bf\",\"y0\"]]],[5,\"0\"]]]],[13,\"c01\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[[7,\"bf\",\"x0\"],[7,\"bf\",\"y1\"]]],[5,\"0\"]]]],[13,\"c11\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"src\"],[6,\"d.vec2u\",[[7,\"bf\",\"x1\"],[7,\"bf\",\"y1\"]]],[5,\"0\"]]]],[13,\"prem\",[6,\"std.mix\",[[6,\"std.mix\",[\"c00\",\"c10\",[7,\"bf\",\"fx\"]]],[6,\"std.mix\",[\"c01\",\"c11\",[7,\"bf\",\"fx\"]]],[7,\"bf\",\"fy\"]]]],[13,\"a\",[7,\"prem\",\"w\"]],[13,\"rgb\",[6,[7,[7,\"prem\",\"xyz\"],\"div\"],[[6,\"std.max\",[\"a\",[6,\"d.f32\",[[5,\"0.0001\"]]]]]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"col\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"a\"]]],[13,\"ch\",[6,\"channel\",[\"rgb\",\"a\"]]],[13,\"targetZ\",[1,[1,\"ch\",\"-\",[5,\"0.5\"]],\"*\",[7,\"P\",\"depth\"]]],[13,\"p4\",[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"]],[13,\"v4\",[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"]],[13,\"dt\",[7,\"P\",\"dt\"]],[13,\"needsSnap\",[3,[1,[7,\"P\",\"snap\"],\">\",[5,\"0.5\"]],\"||\",[1,[7,\"v4\",\"w\"],\"<\",[5,\"0.5\"]]]],[13,\"homeW\",[6,\"d.vec2f\",[[1,[1,\"homeU\",\"-\",[5,\"0.5\"]],\"*\",[7,\"P\",\"aspect\"]],[1,\"homeV\",\"-\",[5,\"0.5\"]]]]],[13,\"off\",[6,\"d.vec2f\",[[7,\"p4\",\"x\"],[7,\"p4\",\"y\"]]]],[13,\"cf\",[6,\"cursor\",[\"homeW\",\"off\",[7,\"p4\",\"z\"]]]],[13,\"F\",[6,[7,[6,\"d.vec3f\",[[1,[7,\"off\",\"x\"],\"*\",[4,\"-\",\"STIFF\"]],[1,[7,\"off\",\"y\"],\"*\",[4,\"-\",\"STIFF\"]],[1,[1,\"targetZ\",\"-\",[7,\"p4\",\"z\"]],\"*\",\"STIFF\"]]],\"add\"],[\"cf\"]]],[12,\"v3\",[6,\"integrateSemiImplicitEuler\",[[6,\"d.vec3f\",[[7,\"v4\",\"x\"],[7,\"v4\",\"y\"],[7,\"v4\",\"z\"]]],\"F\",\"dt\",[7,\"P\",\"dragMul\"],[6,\"d.f32\",[\"MAX_SPEED\"]]]]],[12,\"offN\",[6,[7,\"off\",\"add\"],[[6,[7,[6,\"d.vec2f\",[[7,\"v3\",\"x\"],[7,\"v3\",\"y\"]]],\"mul\"],[\"dt\"]]]]],[12,\"curZ\",[1,[7,\"p4\",\"z\"],\"+\",[1,[7,\"v3\",\"z\"],\"*\",\"dt\"]]],[2,\"offN\",\"=\",[6,\"std.select\",[\"offN\",[6,\"d.vec2f\",[[5,\"0\"],[5,\"0\"]]],\"needsSnap\"]]],[2,\"curZ\",\"=\",[6,\"std.select\",[\"curZ\",\"targetZ\",\"needsSnap\"]]],[2,\"v3\",\"=\",[6,\"std.select\",[\"v3\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"]]],\"needsSnap\"]]],[13,\"seed\",[6,\"noise.hash12\",[[6,\"d.vec2f\",[[1,[6,\"d.f32\",[\"gx\"]],\"+\",[5,\"0.5\"]],[1,[6,\"d.f32\",[\"gy\"]],\"+\",[5,\"0.5\"]]]]]]],[13,\"seenN\",[6,\"std.select\",[[7,\"v4\",\"w\"],[6,\"d.f32\",[[5,\"1\"]]],[1,\"a\",\">\",\"MIN_ALPHA\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"pos\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"offN\",\"x\"],[7,\"offN\",\"y\"],\"curZ\",\"seed\"]]],[2,[8,[7,[7,\"layout\",\"$\"],\"vel\"],\"i\"],\"=\",[6,\"d.vec4f\",[[7,\"v3\",\"x\"],[7,\"v3\",\"y\"],[7,\"v3\",\"z\"],\"seenN\"]]]]]},externals:{layout:()=>e,\"d.u32\":()=>M,\"d.f32\":()=>n,\"std.textureDimensions\":()=>Ti,\"agents.bilinearTexelFrame\":()=>th,\"d.vec2f\":()=>m,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,\"std.max\":()=>B,\"d.vec4f\":()=>S,channel:()=>s,cursor:()=>r,\"d.vec3f\":()=>A,STIFF:()=>o,integrateSemiImplicitEuler:()=>nh,MAX_SPEED:()=>a,\"std.select\":()=>N,\"noise.hash12\":()=>Ys,MIN_ALPHA:()=>i}})&&l.f)({})).$name(t.name)}function nde(e,t){let s=t.gridN,r=t.inertiaRate,o=t.homeRate,a=kP[0],i=kP[1];return w.fn([M])((l=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(l.f=(c=>{\"use gpu\";let d=e.$.params,u=e.$.agents[c],p=m(u.x,u.y),_=d.dt,f=B(d.aspect,1e-5),h=n(s),g=th(m(__tsover_div(p.x,f),p.y),m(h,h)),y=Ye(e.$.velTex,fe(g.x0,g.y0),0),b=Ye(e.$.velTex,fe(g.x1,g.y0),0),x=Ye(e.$.velTex,fe(g.x0,g.y1),0),P=Ye(e.$.velTex,fe(g.x1,g.y1),0),C=K(K(y.x,b.x,g.fx),K(x.x,P.x,g.fx),g.fy),E=K(K(y.y,b.y,g.fx),K(x.y,P.y,g.fx),g.fy),R=__tsover_mul(__tsover_mul(__tsover_div(C,h),f),d.advect),U=__tsover_mul(__tsover_div(E,h),d.advect),L=__tsover_sub(1,Tt(__tsover_mul(__tsover_mul(_,r),-1))),k=n(c),D=__tsover_mul(Re(__tsover_add(.5,__tsover_mul(k,a))),f),O=Re(__tsover_add(.5,__tsover_mul(k,i))),F=__tsover_add(K(u.z,R,L),__tsover_mul(__tsover_sub(D,p.x),__tsover_mul(o,_))),q=__tsover_add(K(u.w,U,L),__tsover_mul(__tsover_sub(O,p.y),__tsover_mul(o,_))),Y=G(__tsover_add(p.x,__tsover_mul(F,_)),0,f),V=G(__tsover_add(p.y,__tsover_mul(q,_)),0,1);e.$.agents[c]=S(Y,V,F,q)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"i\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"a\",[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"]],[13,\"pos\",[6,\"d.vec2f\",[[7,\"a\",\"x\"],[7,\"a\",\"y\"]]]],[13,\"dt\",[7,\"prm\",\"dt\"]],[13,\"aspect\",[6,\"std.max\",[[7,\"prm\",\"aspect\"],[5,\"0.00001\"]]]],[13,\"NF\",[6,\"d.f32\",[\"N\"]]],[13,\"bf\",[6,\"agents.bilinearTexelFrame\",[[6,\"d.vec2f\",[[1,[7,\"pos\",\"x\"],\"/\",\"aspect\"],[7,\"pos\",\"y\"]]],[6,\"d.vec2f\",[\"NF\",\"NF\"]]]]],[13,\"v00\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"velTex\"],[6,\"d.vec2u\",[[7,\"bf\",\"x0\"],[7,\"bf\",\"y0\"]]],[5,\"0\"]]]],[13,\"v10\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"velTex\"],[6,\"d.vec2u\",[[7,\"bf\",\"x1\"],[7,\"bf\",\"y0\"]]],[5,\"0\"]]]],[13,\"v01\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"velTex\"],[6,\"d.vec2u\",[[7,\"bf\",\"x0\"],[7,\"bf\",\"y1\"]]],[5,\"0\"]]]],[13,\"v11\",[6,\"std.textureLoad\",[[7,[7,\"layout\",\"$\"],\"velTex\"],[6,\"d.vec2u\",[[7,\"bf\",\"x1\"],[7,\"bf\",\"y1\"]]],[5,\"0\"]]]],[13,\"gvx\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"x\"],[7,\"v10\",\"x\"],[7,\"bf\",\"fx\"]]],[6,\"std.mix\",[[7,\"v01\",\"x\"],[7,\"v11\",\"x\"],[7,\"bf\",\"fx\"]]],[7,\"bf\",\"fy\"]]]],[13,\"gvy\",[6,\"std.mix\",[[6,\"std.mix\",[[7,\"v00\",\"y\"],[7,\"v10\",\"y\"],[7,\"bf\",\"fx\"]]],[6,\"std.mix\",[[7,\"v01\",\"y\"],[7,\"v11\",\"y\"],[7,\"bf\",\"fx\"]]],[7,\"bf\",\"fy\"]]]],[13,\"fieldVx\",[1,[1,[1,\"gvx\",\"/\",\"NF\"],\"*\",\"aspect\"],\"*\",[7,\"prm\",\"advect\"]]],[13,\"fieldVy\",[1,[1,\"gvy\",\"/\",\"NF\"],\"*\",[7,\"prm\",\"advect\"]]],[13,\"blend\",[1,[5,\"1\"],\"-\",[6,\"std.exp\",[[1,[1,\"dt\",\"*\",\"INERTIA_RATE\"],\"*\",[4,\"-\",[5,\"1\"]]]]]]],[13,\"fi\",[6,\"d.f32\",[\"i\"]]],[13,\"homeX\",[1,[6,\"std.fract\",[[1,[5,\"0.5\"],\"+\",[1,\"fi\",\"*\",\"R2A\"]]]],\"*\",\"aspect\"]],[13,\"homeY\",[6,\"std.fract\",[[1,[5,\"0.5\"],\"+\",[1,\"fi\",\"*\",\"R2B\"]]]]],[13,\"velX\",[1,[6,\"std.mix\",[[7,\"a\",\"z\"],\"fieldVx\",\"blend\"]],\"+\",[1,[1,\"homeX\",\"-\",[7,\"pos\",\"x\"]],\"*\",[1,\"HOME_RATE\",\"*\",\"dt\"]]]],[13,\"velY\",[1,[6,\"std.mix\",[[7,\"a\",\"w\"],\"fieldVy\",\"blend\"]],\"+\",[1,[1,\"homeY\",\"-\",[7,\"pos\",\"y\"]],\"*\",[1,\"HOME_RATE\",\"*\",\"dt\"]]]],[13,\"nposX\",[6,\"std.clamp\",[[1,[7,\"pos\",\"x\"],\"+\",[1,\"velX\",\"*\",\"dt\"]],[5,\"0\"],\"aspect\"]]],[13,\"nposY\",[6,\"std.clamp\",[[1,[7,\"pos\",\"y\"],\"+\",[1,\"velY\",\"*\",\"dt\"]],[5,\"0\"],[5,\"1\"]]]],[2,[8,[7,[7,\"layout\",\"$\"],\"agents\"],\"i\"],\"=\",[6,\"d.vec4f\",[\"nposX\",\"nposY\",\"velX\",\"velY\"]]]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,\"std.max\":()=>B,\"d.f32\":()=>n,N:()=>s,\"agents.bilinearTexelFrame\":()=>th,\"std.textureLoad\":()=>Ye,\"d.vec2u\":()=>fe,\"std.mix\":()=>K,\"std.exp\":()=>Tt,INERTIA_RATE:()=>r,\"std.fract\":()=>Re,R2A:()=>a,R2B:()=>i,HOME_RATE:()=>o,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&l.f)({})).$name(t.name)}var Za={pressure:Oce,containment:Gce,cursorXY:Fce,gravity:Ice,turbulence:Yce,flocking:Vce,cursorSteer:Nce,wallTurn:$ce,cursorGust:sde,cursorInView:ode},A2={alignToField:Kce,rest:Qce},w2={dipoleOrRadial:jce,jitteredGridHome:Jce},eO={variedHeading:tde},On={forces3d:qce,steering2d:Hce,orientation2d:ede,drift2d:rde,relief:ade,advect2d:nde};var _h=w.fn([n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=B(t,0),o=B(s,0);return __tsover_add(ye(B(t,s),0),Ue(__tsover_add(__tsover_mul(r,r),__tsover_mul(o,o))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"d2\"},{type:\"i\",name:\"wz\"}],body:[0,[[13,\"ox\",[6,\"std.max\",[\"d2\",[5,\"0\"]]]],[13,\"oz\",[6,\"std.max\",[\"wz\",[5,\"0\"]]]],[10,[1,[6,\"std.min\",[[6,\"std.max\",[\"d2\",\"wz\"]],[5,\"0\"]]],\"+\",[6,\"std.sqrt\",[[1,[1,\"ox\",\"*\",\"ox\"],\"+\",[1,\"oz\",\"*\",\"oz\"]]]]]]]]},externals:{\"std.max\":()=>B,\"std.min\":()=>ye,\"std.sqrt\":()=>Ue}})&&e.f)({})).$name(\"shapeFieldExtrudeZ\");function ide(e,t){return w.fn([A],n)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=e.$.params,a=t(m(__tsover_add(r.x,.5),__tsover_sub(.5,r.y)),o.saRadius,o.saSides,o.saRounding,o.saInnerRatio,o.saRotation,o.saHeight,o.saOffset,o.saAperture).x;return _h(a,__tsover_sub(re(r.z),o.halfDepth))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p3\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"uv2\",[6,\"d.vec2f\",[[1,[7,\"p3\",\"x\"],\"+\",[5,\"0.5\"]],[1,[5,\"0.5\"],\"-\",[7,\"p3\",\"y\"]]]]],[13,\"d2\",[7,[6,\"sdf2d\",[\"uv2\",[7,\"prm\",\"saRadius\"],[7,\"prm\",\"saSides\"],[7,\"prm\",\"saRounding\"],[7,\"prm\",\"saInnerRatio\"],[7,\"prm\",\"saRotation\"],[7,\"prm\",\"saHeight\"],[7,\"prm\",\"saOffset\"],[7,\"prm\",\"saAperture\"]]],\"x\"]],[10,[6,\"extrudeZ\",[\"d2\",[1,[6,\"std.abs\",[[7,\"p3\",\"z\"]]],\"-\",[7,\"prm\",\"halfDepth\"]]]]]]]},externals:{layout:()=>e,\"d.vec2f\":()=>m,sdf2d:()=>t,extrudeZ:()=>_h,\"std.abs\":()=>re}})&&s.f)({})).$name(\"shapeFieldAnalyticExtruded\")}function lde(e,t,s){let r=s.size;return w.fn([A],n)((o=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(o.f=(a=>{\"use gpu\";let i=e.$.params,l=__tsover_sub(r,1),c=G(j(__tsover_mul(__tsover_add(a.x,.5),r)),0,l),d=G(j(__tsover_mul(__tsover_sub(.5,a.y),r)),0,l),u=Ye(t.$.sdfSource,fe(M(c),M(d)),0).x,p=B(__tsover_sub(re(a.x),.5),0),_=B(__tsover_sub(re(a.y),.5),0);return _h(__tsover_add(u,Ue(__tsover_add(__tsover_mul(p,p),__tsover_mul(_,_)))),__tsover_sub(re(a.z),i.halfDepth))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p3\"}],body:[0,[[13,\"prm\",[7,[7,\"layout\",\"$\"],\"params\"]],[13,\"sizeM1\",[1,\"SIZE\",\"-\",[5,\"1\"]]],[13,\"tx\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,[1,[7,\"p3\",\"x\"],\"+\",[5,\"0.5\"]],\"*\",\"SIZE\"]]],[5,\"0\"],\"sizeM1\"]]],[13,\"ty\",[6,\"std.clamp\",[[6,\"d.i32\",[[1,[1,[5,\"0.5\"],\"-\",[7,\"p3\",\"y\"]],\"*\",\"SIZE\"]]],[5,\"0\"],\"sizeM1\"]]],[13,\"d2\",[7,[6,\"std.textureLoad\",[[7,[7,\"svgLayout\",\"$\"],\"sdfSource\"],[6,\"d.vec2u\",[[6,\"d.u32\",[\"tx\"]],[6,\"d.u32\",[\"ty\"]]]],[5,\"0\"]]],\"x\"]],[13,\"exX\",[6,\"std.max\",[[1,[6,\"std.abs\",[[7,\"p3\",\"x\"]]],\"-\",[5,\"0.5\"]],[5,\"0\"]]]],[13,\"exY\",[6,\"std.max\",[[1,[6,\"std.abs\",[[7,\"p3\",\"y\"]]],\"-\",[5,\"0.5\"]],[5,\"0\"]]]],[13,\"d2e\",[1,\"d2\",\"+\",[6,\"std.sqrt\",[[1,[1,\"exX\",\"*\",\"exX\"],\"+\",[1,\"exY\",\"*\",\"exY\"]]]]]],[10,[6,\"extrudeZ\",[\"d2e\",[1,[6,\"std.abs\",[[7,\"p3\",\"z\"]]],\"-\",[7,\"prm\",\"halfDepth\"]]]]]]]},externals:{layout:()=>e,SIZE:()=>r,\"std.clamp\":()=>G,\"d.i32\":()=>j,\"std.textureLoad\":()=>Ye,svgLayout:()=>t,\"d.vec2u\":()=>fe,\"d.u32\":()=>M,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.sqrt\":()=>Ue,extrudeZ:()=>_h}})&&o.f)({})).$name(\"shapeFieldSvgExtruded\")}function cde(e,t){return w.fn([A],n)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";return t(ja(r,e.$.params.rot))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p3\"}],body:[0,[[10,[6,\"baked\",[[6,\"sdf3d.rotateVec3\",[\"p3\",[7,[7,[7,\"layout\",\"$\"],\"params\"],\"rot\"]]]]]]]]},externals:{baked:()=>t,\"sdf3d.rotateVec3\":()=>ja,layout:()=>e}})&&s.f)({})).$name(\"shapeFieldAnalytic3d\")}function dde(e,t){return w.fn([A],n)((s=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(s.f=(r=>{\"use gpu\";let o=ja(r,e.$.params.rot),a=B(__tsover_sub(re(o.x),.5),0),i=B(__tsover_sub(re(o.y),.5),0);return __tsover_add(t(o),Ue(__tsover_add(__tsover_mul(a,a),__tsover_mul(i,i))))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"p3\"}],body:[0,[[13,\"ps\",[6,\"sdf3d.rotateVec3\",[\"p3\",[7,[7,[7,\"layout\",\"$\"],\"params\"],\"rot\"]]]],[13,\"exX\",[6,\"std.max\",[[1,[6,\"std.abs\",[[7,\"ps\",\"x\"]]],\"-\",[5,\"0.5\"]],[5,\"0\"]]]],[13,\"exY\",[6,\"std.max\",[[1,[6,\"std.abs\",[[7,\"ps\",\"y\"]]],\"-\",[5,\"0.5\"]],[5,\"0\"]]]],[10,[1,[6,\"baked\",[\"ps\"]],\"+\",[6,\"std.sqrt\",[[1,[1,\"exX\",\"*\",\"exX\"],\"+\",[1,\"exY\",\"*\",\"exY\"]]]]]]]]},externals:{\"sdf3d.rotateVec3\":()=>ja,layout:()=>e,\"std.max\":()=>B,\"std.abs\":()=>re,baked:()=>t,\"std.sqrt\":()=>Ue}})&&s.f)({})).$name(\"shapeFieldSvgLifted3d\")}var X_={analyticExtruded:ide,svgExtruded:lde,analytic3d:cde,svgLifted3d:dde};function Sp(e,t){return Math.exp(-e*t)}function tO(e){let t=(e.pointerX-e.centerX)*e.aspect,s=e.pointerY-e.centerYv;return{x:(t*e.rotC+s*e.rotS)/e.scale,y:-((s*e.rotC-t*e.rotS)/e.scale)}}function T2(e,t,s){if(!e)return null;let r=(t.x-e.x)/s,o=(t.y-e.y)/s,a=(t.z-e.z)/s,i={cx:Math.cos(t.x),sx:Math.sin(t.x),cy:Math.cos(t.y),sy:Math.sin(t.y),cz:Math.cos(t.z),sz:Math.sin(t.z)},l=Jl(1,0,0,i),c=Jl(0,1,0,i),d=Jl(0,0,1,i);return{x:-(l.x*r+l.y*o+l.z*a),y:-(c.x*r+c.y*o+c.z*a),z:-(d.x*r+d.y*o+d.z*a)}}function sO(e,t){let s=Math.hypot(e.x,e.y,e.z),r=s>t.cap?t.cap/s:1;return{omegaX:e.x*r,omegaY:e.y*r,omegaZ:e.z*r,entrain:Math.min(1,s*t.gainRate)*t.gainMax}}function rO(e){let t=e?.smoothing??.1,s=e?.teleport??.25,r=.5,o=.5,a=1,i=0;return{update(l,c){let d=l-r,u=c-o,p=Math.hypot(d,u);if(p>.001&&p<s){let _=d/p,f=u/p;a+=(_-a)*t,i+=(f-i)*t;let h=Math.hypot(a,i)||1;a/=h,i/=h}return r=l,o=c,{x:a,y:i}}}}function oO(e,t,s){let r=t+2*s,o=1+2*s,a=Math.max(1,Math.round(Math.sqrt(e*(r/o)))),i=Math.max(1,Math.ceil(e/a));return{cols:a,cellW:r/a,cellH:o/i}}function aO(e,t,s,r){let o=Math.round(Math.sqrt(e*t));o=Math.min(Math.max(o,s),r);let a=Math.round(e/o);return a=Math.min(Math.max(a,s),r),{w:o,h:a}}function nO(e,t,s){let r=Math.cos(e),o=Math.sin(e),a=Math.cos(t),i=Math.sin(t),l=Math.cos(s),c=Math.sin(s),d=l*a,u=l*i*o-c*r,p=l*i*r+c*o,_=c*a,f=c*i*o+l*r,h=c*i*r-l*o,g=-i,y=a*o,b=a*r;return{rowX:[d,-u,p],rowY:[-_,f,-h],rowZ:[g,-y,b]}}function iO(e,t){return{x:e*N0[0]%1*t,y:e*N0[1]%1*t,z:e*N0[2]%1*t}}var Gn={orientedWorld(e,t){let{ramp:s,names:r,extraOnSplat:o,...a}=t;return{splat:{kernel:w1.orientedWorld(e,{...a,name:r.splat}),threads:\"agents\",...o?{extra:!0}:{}},resolve:{kernel:T1.ramp(e,{invGain:1/255,...s,res:t.res,name:r.resolve}),threads:\"fixed\",size:[t.res,t.res]}}},pointWorld(e,t){let{names:s,...r}=t;return{splat:{kernel:w1.pointWorld(e,{...r,name:s.splat}),threads:\"agents\"},resolve:{kernel:T1.tint(e,{res:t.res,name:s.resolve}),threads:\"fixed\",size:[t.res,t.res]}}},volume(e,t){let{ramp:s,names:r,extraOnSplat:o,...a}=t;return{splat:{kernel:w1.volume(e,{...a,names:r}),threads:\"agents\",...o?{extra:!0}:{}},resolve:{kernel:T1.ramp(e,{invGain:1/256,...s,res:t.outRes,name:r.resolve}),threads:\"fixed\",size:[t.outRes,t.outRes]}}},relief(e,t){let{out:s,weightedColor:r,names:o,...a}=t;return{splat:{kernel:w1.relief(e,{...a,name:o.splat}),threads:\"grid\"},resolve:{kernel:T1.weightedColor(e,{fp:t.fp,alphaK:r.alphaK,name:o.resolve}),threads:\"fixed\",size:s}}}};function Fn(e){return{compute:t=>{if(e.childTexture&&!t.childNode||!t.gpu?.root)return null;let s=e.childTexture?t.convertToTexture(t.childNode):null,r=e.bake(t);if(!r)return null;let o=_ie(t,{layout:e.layout,params:e.params,maxAgents:e.maxAgents,output:r.outputSize?{...e.output,size:r.outputSize}:e.output,...e.countCap?{countCap:e.countCap}:{},...e.externalKeys?{externalKeys:e.externalKeys}:{},...r.extraBindGroup?{extraBindGroup:r.extraBindGroup}:{},pipelines:r.pipelines,program:r.program,...r.initStep?{initStep:r.initStep}:{}});if(!o)return null;r.bindNow&&o.bindExternal(r.bindNow);let a=e.frame(o,t,r.setup);return{outputs:s?{childTexture:s,...o.outputs}:o.outputs,...s&&e.childTexture?{bindInputs:i=>{let l=i(s.key);l&&o.bindExternal({[e.childTexture.externalKey]:l.texture})}}:{},getComputeNodes:a}},gpu:{fragment:t=>{let{ctx:s,childNode:r,computeOutputs:o}=t,a=o?.[e.fragment.output];if(!a)return e.fragment.fallback===\"child\"?r??xt:xt;let i=a.sample(s.uv,\"linearClamp\");return e.fragment.compose?e.fragment.compose(i,t):i}}}}function Lg(e){return{compute:t=>{let{childNode:s,gpu:r}=t;if(!s)return null;let o=r?.root;if(!o)return null;let a=e(t,o),i=o.createUniform(a.paramsSchema),l=hB(t,{size:a.size,format:a.format,extraSlots:a.extraSlots,textures:a.textures,speedProp:a.speedProp,maxDeltaTime:a.maxDeltaTime,bindGroups:(d,u,p)=>a.bindGroups({...d,paramsBuffer:i.buffer},u,p),staticGroups:a.staticGroups?d=>a.staticGroups({...d,paramsBuffer:i.buffer}):void 0});if(!l)return null;let c=D_(o,a.step,{n:a.size,bindGroup:void 0});return{outputs:{childTexture:l.childTexture,display:l.display,...a.outputs??{}},bindInputs:l.bindInputs,getComputeNodes:d=>l.tick(d,u=>a.skip?.(u)?null:(i.write(a.values(u)),[c.with(u.groups)]))}}}}var lO=e=>({stage:\"pre\",kernel:e}),cO=e=>({stage:\"post\",kernel:e}),ude=\"rgba16float\";function Ii(e){return{compute:t=>{let{gpu:s,getCpuValue:r,registerComputeTexture:o,onCleanup:a}=t,i=s?.root;if(!i)return null;let l=e(t,i),c=l.resolution,d=c*c,u=pr(i,S,d),p=pr(i,S,d),_=pr(i,S,d),f=pr(i,S,d),h=pr(i,n,d),g=pr(i,n,d),y=l.container?pr(i,S,d):void 0,b=i.createTexture({size:[c,c],format:ude}).$usage(\"storage\",\"sampled\");a(()=>b.destroy());let x=o(b),P=i.createUniform(l.paramsSchema),C={velA:u,velB:p,dyeA:_,dyeB:f,pressure:h,divergence:g,params:P.buffer};y&&(C.maskBuf=y);let E=i.createBindGroup(l.layout,C),R=i.createBindGroup(l.outputLayout,{dyeA:_,outTex:b}),U={params:t,root:i,n:c,buffers:{velA:u,velB:p,dyeA:_,dyeB:f,pressure:h,divergence:g,maskBuf:y},paramsBuffer:P.buffer,fluidBindGroup:E,pass:(le,se=E)=>D_(i,le,{n:c,bindGroup:se})},L=l.container?.setup(U);l.init?.setup?.(U);let k=l.inject??[];for(let le of k)le.setup?.(U);let D=(l.solve??[]).filter(le=>le.stage===\"pre\").map(le=>U.pass(le.kernel)),O=(l.solve??[]).filter(le=>le.stage===\"post\").map(le=>U.pass(le.kernel)),F=jA(i,l.solver.kernels,{n:c,bindGroup:E}),q=U.pass(l.output.kernel,R),Y=(le,se)=>{le.push(...D,...F.solveSteps({jacobiIters:se}),...O)},V=l.pointer?Sl(l.pointer):null,X=l.maxDeltaTime??.033,Q=Date.now(),te=0,J=(le,se)=>{let Te=r(le);return typeof Te==\"number\"?Te:se},oe=le=>P.write(le);return{outputs:{[l.output.key]:x,...L?.outputs??{}},getComputeNodes:le=>{let se=le,Te=L?.preFrame?L.preFrame(le):null,de=Date.now(),xe=Math.min(se.deltaTime??(de-Q)/1e3,X);if(Q=de,xe<.001)return Te;te+=xe;let Ae={dt:xe,now:de,frameParams:se,num:J,getCpuValue:r,writeParams:oe,ptr:V?V.update(se.pointer,xe):null,get elapsed(){return te},setElapsed(Ie){te=Ie}},De=Te?[...Te]:[],Ee=!1;l.init?.stale(Ae)&&(Ee=!0,l.init.run(Ae,{nodes:De,writeParams:Ie=>()=>P.write(Ie),solve:Y}));for(let Ie of k)Ie.tick?.(Ae);for(let Ie of k)if(Ie.skip?.(Ae))return Ee?De:null;let ze=l.values(Ae);(l.write??\"direct\")===\"thunk\"?De.push(()=>P.write(ze)):P.write(ze),L&&De.push(L.maskPass);for(let Ie of k)Ie.emit?.(Ae,De,ze);return Y(De,l.solver.jacobiIters),De.push(q),De}}}}}function Ug(e){let t=null;return{setup(s){t=\"kernel\"in e?s.pass(e.kernel):e.setup(s)},emit(s,r){t&&r.push(t)}}}function Og(e){let t=Sl(e.tracker),s=lA(),r=null,o=null,a=1,i=!1;return{setup(l){a=l.n,r=\"kernel\"in e.pass?l.pass(e.pass.kernel):e.pass.setup(l)},tick(l){o=t.update(l.frameParams.pointer,l.dt),e.onFrame?.(l,o),i=e.activeWhen(o,l),i&&s.markActive()},skip(l){let c=s.shouldSkip(e.fadeSeconds(l));return c||s.tickFrame(l.dt),c},emit(l,c,d){if(!i||!o||!r)return;let u=e.ribbon(l,o,d);cA(c,{fromX:o.prevX,fromY:o.prevY,dx:o.dx,dy:o.dy,dragDist:o.dragDist,stepSize:u.stepSize,maxSteps:u.maxSteps,scale:a,prepare:u.prepare,write:u.write,pass:r})},ptr:()=>o,active:()=>i}}function dO(e){let t=null,s=!1,r=-1;return{setup(o){t=o.pass(e.kernel)},stale(o){return!s||e.seed(o)!==r},run(o,a){s=!0,r=e.seed(o),a.nodes.push(a.writeParams(e.warm.values(0,o))),t&&a.nodes.push(t);let i=e.warm.startTime();for(let l=0;l<e.warm.steps;l++){let c=i;i+=e.warm.dt,a.nodes.push(a.writeParams(e.warm.values(c,o))),a.solve(a.nodes,e.warm.jacobiIters)}o.setElapsed(i)}}}function Gg(e){return{intensity:{default:e.intensity,description:\"Strength of the relief shading applied to the child content\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Intensity\",group:\"Texture\"}},scale:{default:e.scale,description:\"Scale of the pattern \\u2014 lower = larger features, higher = finer grain\",ui:{type:\"range\",min:.1,max:8,step:.05,label:\"Scale\",group:\"Texture\"}},contrast:{default:e.contrast,description:\"Contrast of the texture \\u2014 negative flattens it into a subtle overlay\",ui:{type:\"range\",min:-1,max:2,step:.05,label:\"Contrast\",group:\"Texture\"}},distortion:{default:e.distortion,description:\"Surface distortion \\u2014 warps the child along the texture like carved relief\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Distortion\",group:\"Texture\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Texture\"}}}}var pde=0,mde=e=>new fs(()=>e);function uO(e,t){let s=(o,a)=>{let i=e.uniforms[tg(t,o)];if(!i)throw new Error(`std: list '${t}' has no field '${o}'`);return new fs(l=>`${i._emit(l)}[${a._emit(l)}]`)},r=e.uniforms[sg(t)];if(!r)throw new Error(`std: '${t}' is not a list prop`);return{count:r,at:o=>({position:a=>s(a,o).member(\"xy\"),color:a=>s(a,o),number:a=>s(a,o).member(\"x\")})}}function S2(e,t,s={}){let r=pde++,o=s.zero===\"vec3f\"?\"vec3f(0.0)\":\"0.0\",a=s.hint??\"sum\";return new fs(i=>i.memo(`accumulate:${r}`,()=>{for(let _ of s.deps??[])_._emit(i);let l=i.freshLocal(a),c=i.freshLocal(\"item\"),d=e.count._emit(i),u=[],p=t(mde(c))._emit({external:(_,f)=>i.external(_,f),statement:_=>u.push(_),freshLocal:_=>i.freshLocal(_),memo:(_,f)=>i.memo(_,f)});return i.statement(`var ${l} = ${o};`),i.statement([`for (var ${c} = 0u; ${c} < u32(${d}); ${c}++) {`,...u.map(_=>`  ${_}`),`  ${l} += ${p};`,\"}\"].join(`\n`)),l}))}var _de=new Map;function P2(e){return _de.get(e)}var fde=ko({applyNeonEffect:()=>vde,neonComposite:()=>_O,neonFlicker:()=>k2,neonFlow:()=>B2,neonGlow:()=>E2,neonSmoothEPS:()=>mO}),pO=.017453292519943295,C2=.7,Pp=1/Math.sqrt(1+C2*C2),M2=C2*Pp,Ig=M2+1,Fg=1/Math.sqrt(Pp*Pp+Ig*Ig),mO=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(t,.006);return N(__tsover_add(.008,__tsover_mul(s,.03)),o,r>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"tubeThickness\"},{type:\"i\",name:\"cornerSmoothing\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"vol\",[6,\"std.max\",[\"tubeThickness\",[5,\"0.006\"]]]],[13,\"flat\",[1,[5,\"0.008\"],\"+\",[1,\"cornerSmoothing\",\"*\",[5,\"0.03\"]]]],[10,[6,\"std.select\",[\"flat\",\"vol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.max\":()=>B,\"std.select\":()=>N}})&&e.f)({})),E2=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=B(s,.001),a=B(t,0),i=__tsover_mul(Tt(__tsover_mul(__tsover_mul(a,-1),__tsover_div(12,o))),.7),l=__tsover_mul(Tt(__tsover_mul(__tsover_mul(a,-1),__tsover_div(4,o))),.35),c=__tsover_mul(__tsover_add(i,l),r),d=be(-.003,.003,t);return __tsover_mul(c,d)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdf\"},{type:\"i\",name:\"glowRadius\"},{type:\"i\",name:\"glowIntensity\"}],body:[0,[[13,\"glowR\",[6,\"std.max\",[\"glowRadius\",[5,\"0.001\"]]]],[13,\"sdfOutside\",[6,\"std.max\",[\"sdf\",[5,\"0\"]]]],[13,\"innerGlow\",[1,[6,\"std.exp\",[[1,[1,\"sdfOutside\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",[1,[5,\"12\"],\"/\",\"glowR\"]]]],\"*\",[5,\"0.7\"]]],[13,\"outerGlow\",[1,[6,\"std.exp\",[[1,[1,\"sdfOutside\",\"*\",[4,\"-\",[5,\"1\"]]],\"*\",[1,[5,\"4\"],\"/\",\"glowR\"]]]],\"*\",[5,\"0.35\"]]],[13,\"totalGlow\",[1,[1,\"innerGlow\",\"+\",\"outerGlow\"],\"*\",\"glowIntensity\"]],[13,\"outsideFactor\",[6,\"std.smoothstep\",[[4,\"-\",[5,\"0.003\"]],[5,\"0.003\"],\"sdf\"]]],[10,[1,\"totalGlow\",\"*\",\"outsideFactor\"]]]]},externals:{\"std.max\":()=>B,\"std.exp\":()=>Tt,\"std.smoothstep\":()=>be}})&&e.f)({})),k2=w.fn([n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r)=>{\"use gpu\";let o=__tsover_mul(t,s),a=ae(__tsover_mul(o,17.13)),i=ae(__tsover_mul(o,31.71)),l=ae(__tsover_mul(o,47.29)),c=__tsover_add(__tsover_add(a,__tsover_mul(i,.5)),__tsover_mul(l,.3)),d=K(-2,.8,r);return be(__tsover_sub(d,.1),__tsover_add(d,.1),c)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"time\"},{type:\"i\",name:\"flickerSpeed\"},{type:\"i\",name:\"flickerAmount\"}],body:[0,[[13,\"flickerTime\",[1,\"time\",\"*\",\"flickerSpeed\"]],[13,\"f1\",[6,\"std.sin\",[[1,\"flickerTime\",\"*\",[5,\"17.13\"]]]]],[13,\"f2\",[6,\"std.sin\",[[1,\"flickerTime\",\"*\",[5,\"31.71\"]]]]],[13,\"f3\",[6,\"std.sin\",[[1,\"flickerTime\",\"*\",[5,\"47.29\"]]]]],[13,\"combined\",[1,[1,\"f1\",\"+\",[1,\"f2\",\"*\",[5,\"0.5\"]]],\"+\",[1,\"f3\",\"*\",[5,\"0.3\"]]]],[13,\"threshold\",[6,\"std.mix\",[[4,\"-\",[5,\"2\"]],[5,\"0.8\"],\"flickerAmount\"]]],[10,[6,\"std.smoothstep\",[[1,\"threshold\",\"-\",[5,\"0.1\"]],[1,\"threshold\",\"+\",[5,\"0.1\"]],\"combined\"]]]]]},externals:{\"std.sin\":()=>ae,\"std.mix\":()=>K,\"std.smoothstep\":()=>be}})&&e.f)({})),B2=w.fn([m,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_sub(t.x,.5),i=Xt(__tsover_sub(t.y,.5),a),l=__tsover_add(__tsover_mul(i,2),__tsover_mul(s,r));return K(1,__tsover_add(__tsover_mul(ae(l),.5),.5),o)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfUV\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"flowSpeed\"},{type:\"i\",name:\"flowAmount\"}],body:[0,[[13,\"flowDx\",[1,[7,\"sdfUV\",\"x\"],\"-\",[5,\"0.5\"]]],[13,\"flowDy\",[1,[7,\"sdfUV\",\"y\"],\"-\",[5,\"0.5\"]]],[13,\"flowAngle\",[6,\"std.atan2\",[\"flowDy\",\"flowDx\"]]],[13,\"flowPhase\",[1,[1,\"flowAngle\",\"*\",[5,\"2\"]],\"+\",[1,\"time\",\"*\",\"flowSpeed\"]]],[13,\"flowWave\",[1,[1,[6,\"std.sin\",[\"flowPhase\"]],\"*\",[5,\"0.5\"]],\"+\",[5,\"0.5\"]]],[10,[6,\"std.mix\",[[5,\"1\"],\"flowWave\",\"flowAmount\"]]]]]},externals:{\"std.atan2\":()=>Xt,\"std.sin\":()=>ae,\"std.mix\":()=>K}})&&e.f)({})),_O=w.fn([S,S,S,S,S,n,m,n,m,n,n,n,A,A,n,A,n,n,n,n,n,n,n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_,f,h,g,y,b,x,P,C,E,R,U,L,k,D,O,F)=>{\"use gpu\";let q=t.x,Y=s.x,V=r.x,X=o.x,Q=a.x,te=__tsover_div(1,d.y),J=B(C,.001),oe=B(__tsover_div(te,c),.004),le=__tsover_div(__tsover_sub(Y,V),__tsover_mul(i,2)),se=__tsover_div(__tsover_sub(X,Q),__tsover_mul(i,2)),Te=K(q,__tsover_div(__tsover_add(__tsover_add(__tsover_add(__tsover_add(q,Y),V),X),Q),5),p),de=N(le,__tsover_sub(s.w,r.w),F>.5),xe=N(se,__tsover_sub(o.w,a.w),F>.5),Ae=B(Ue(__tsover_add(__tsover_mul(de,de),__tsover_mul(xe,xe))),1e-4),De=__tsover_div(de,Ae),Ee=__tsover_div(xe,Ae),ze=G(__tsover_div(__tsover_mul(Te,-1),B(_,.001)),0,1),Ie=be(__tsover_add(_,oe),__tsover_sub(_,oe),__tsover_mul(Te,-1)),ke=__tsover_add(re(__tsover_sub(__tsover_add(s.w,r.w),__tsover_mul(t.w,2))),re(__tsover_sub(__tsover_add(o.w,a.w),__tsover_mul(t.w,2)))),Me=__tsover_add(re(de),re(xe)),we=__tsover_div(ke,__tsover_add(__tsover_add(ke,__tsover_mul(i,.6)),__tsover_mul(Me,.35))),Ve=be(.08,.35,we),qe=N(ze,we,F>.5),st=N(Ie,Ve,F>.5),pt=be(oe,__tsover_mul(oe,-1),Te),Ze=__tsover_mul(pt,st),nt=qe,ht=Ue(B(__tsover_mul(nt,__tsover_sub(2,nt)),0)),yt=__tsover_sub(1,nt),St=__tsover_mul(De,yt),Mt=__tsover_mul(Ee,yt),Rt=ht,Kt=__tsover_mul(E,pO),Wt=pe(Kt),ls=ae(Kt),us=__tsover_mul(Wt,Pp),os=__tsover_mul(ls,Pp),bs=M2,hs=G(__tsover_add(__tsover_add(__tsover_mul(St,us),__tsover_mul(Mt,os)),__tsover_mul(Rt,bs)),0,1),gs=__tsover_add(__tsover_add(__tsover_mul(St,__tsover_mul(us,Fg)),__tsover_mul(Mt,__tsover_mul(os,Fg))),__tsover_mul(Rt,__tsover_mul(Ig,Fg))),Gs=Ia(__tsover_sub(8,__tsover_mul(U,7))),Ss=__tsover_mul(vt(G(gs,0,1),Gs),R),or=B2(l,u,D,O),yr=K(f,K(h,f,hs),g),lr=.12,Ur=__tsover_mul(ht,.35),so=yr.mul(__tsover_add(__tsover_add(lr,__tsover_mul(hs,.55)),Ur)),ro=A(__tsover_add(so.x,Ss),__tsover_add(so.y,Ss),__tsover_add(so.z,Ss)),_e=be(.55,1,qe),We=__tsover_mul(__tsover_mul(_e,x),or),Le=K(ro,K(f,A(1,1,1),.75),We).mul(K(1,or,.4)),Be=E2(Te,C,P),Oe=k2(u,L,k),tt=__tsover_mul(b,Oe),_t=Le.mul(tt),Bt=y.mul(__tsover_mul(Be,tt)),Dt=S(K(Bt.x,_t.x,Ze),K(Bt.y,_t.y,Ze),K(Bt.z,_t.z,Ze),B(Ze,G(__tsover_mul(Be,.6),0,1))),Nt=__tsover_add(__tsover_add(__tsover_mul(J,1.5),oe),i);return N(Dt,S(0,0,0,0),q>Nt)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sC\"},{type:\"i\",name:\"sR\"},{type:\"i\",name:\"sL\"},{type:\"i\",name:\"sU\"},{type:\"i\",name:\"sD\"},{type:\"i\",name:\"smoothEPS\"},{type:\"i\",name:\"sdfUV\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"viewportSize\"},{type:\"i\",name:\"time\"},{type:\"i\",name:\"cornerSmoothing\"},{type:\"i\",name:\"tubeThickness\"},{type:\"i\",name:\"color\"},{type:\"i\",name:\"secondaryColor\"},{type:\"i\",name:\"secondaryBlend\"},{type:\"i\",name:\"glowColor\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"hotCoreIntensity\"},{type:\"i\",name:\"glowIntensity\"},{type:\"i\",name:\"glowRadius\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"specularIntensity\"},{type:\"i\",name:\"specularSize\"},{type:\"i\",name:\"flickerSpeed\"},{type:\"i\",name:\"flickerAmount\"},{type:\"i\",name:\"flowSpeed\"},{type:\"i\",name:\"flowAmount\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"sdfCenter\",[7,\"sC\",\"x\"]],[13,\"sdfRight\",[7,\"sR\",\"x\"]],[13,\"sdfLeft\",[7,\"sL\",\"x\"]],[13,\"sdfUp\",[7,\"sU\",\"x\"]],[13,\"sdfDown\",[7,\"sD\",\"x\"]],[13,\"pxH\",[1,[5,\"1\"],\"/\",[7,\"viewportSize\",\"y\"]]],[13,\"glowR\",[6,\"std.max\",[\"glowRadius\",[5,\"0.001\"]]]],[13,\"softPx\",[6,\"std.max\",[[1,\"pxH\",\"/\",\"scale\"],[5,\"0.004\"]]]],[13,\"gradX\",[1,[1,\"sdfRight\",\"-\",\"sdfLeft\"],\"/\",[1,\"smoothEPS\",\"*\",[5,\"2\"]]]],[13,\"gradY\",[1,[1,\"sdfUp\",\"-\",\"sdfDown\"],\"/\",[1,\"smoothEPS\",\"*\",[5,\"2\"]]]],[13,\"smoothedSdf\",[1,[1,[1,[1,[1,\"sdfCenter\",\"+\",\"sdfRight\"],\"+\",\"sdfLeft\"],\"+\",\"sdfUp\"],\"+\",\"sdfDown\"],\"/\",[5,\"5\"]]],[13,\"sdf\",[6,\"std.mix\",[\"sdfCenter\",\"smoothedSdf\",\"cornerSmoothing\"]]],[13,\"gxRaw\",[6,\"std.select\",[\"gradX\",[1,[7,\"sR\",\"w\"],\"-\",[7,\"sL\",\"w\"]],[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"gyRaw\",[6,\"std.select\",[\"gradY\",[1,[7,\"sU\",\"w\"],\"-\",[7,\"sD\",\"w\"]],[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"gradLen\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"gxRaw\",\"*\",\"gxRaw\"],\"+\",[1,\"gyRaw\",\"*\",\"gyRaw\"]]]],[5,\"0.0001\"]]]],[13,\"gnx\",[1,\"gxRaw\",\"/\",\"gradLen\"]],[13,\"gny\",[1,\"gyRaw\",\"/\",\"gradLen\"]],[13,\"depthNorm2D\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",[6,\"std.max\",[\"tubeThickness\",[5,\"0.001\"]]]],[5,\"0\"],[5,\"1\"]]]],[13,\"innerMask2D\",[6,\"std.smoothstep\",[[1,\"tubeThickness\",\"+\",\"softPx\"],[1,\"tubeThickness\",\"-\",\"softPx\"],[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"lap\",[1,[6,\"std.abs\",[[1,[1,[7,\"sR\",\"w\"],\"+\",[7,\"sL\",\"w\"]],\"-\",[1,[7,\"sC\",\"w\"],\"*\",[5,\"2\"]]]]],\"+\",[6,\"std.abs\",[[1,[1,[7,\"sU\",\"w\"],\"+\",[7,\"sD\",\"w\"]],\"-\",[1,[7,\"sC\",\"w\"],\"*\",[5,\"2\"]]]]]]],[13,\"slopeMag\",[1,[6,\"std.abs\",[\"gxRaw\"]],\"+\",[6,\"std.abs\",[\"gyRaw\"]]]],[13,\"crease\",[1,\"lap\",\"/\",[1,[1,\"lap\",\"+\",[1,\"smoothEPS\",\"*\",[5,\"0.6\"]]],\"+\",[1,\"slopeMag\",\"*\",[5,\"0.35\"]]]]],[13,\"innerMaskVol\",[6,\"std.smoothstep\",[[5,\"0.08\"],[5,\"0.35\"],\"crease\"]]],[13,\"depthNorm\",[6,\"std.select\",[\"depthNorm2D\",\"crease\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"innerMask\",[6,\"std.select\",[\"innerMask2D\",\"innerMaskVol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"outerMask\",[6,\"std.smoothstep\",[\"softPx\",[1,\"softPx\",\"*\",[4,\"-\",[5,\"1\"]]],\"sdf\"]]],[13,\"tubeMask\",[1,\"outerMask\",\"*\",\"innerMask\"]],[13,\"t\",\"depthNorm\"],[13,\"cylinderZ\",[6,\"std.sqrt\",[[6,\"std.max\",[[1,\"t\",\"*\",[1,[5,\"2\"],\"-\",\"t\"]],[5,\"0\"]]]]]],[13,\"cylinderR\",[1,[5,\"1\"],\"-\",\"t\"]],[13,\"nx\",[1,\"gnx\",\"*\",\"cylinderR\"]],[13,\"ny\",[1,\"gny\",\"*\",\"cylinderR\"]],[13,\"nz\",\"cylinderZ\"],[13,\"lightRad\",[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]],[13,\"lx\",[6,\"std.cos\",[\"lightRad\"]]],[13,\"ly\",[6,\"std.sin\",[\"lightRad\"]]],[13,\"lxn\",[1,\"lx\",\"*\",\"_INV_LIGHT_LEN\"]],[13,\"lyn\",[1,\"ly\",\"*\",\"_INV_LIGHT_LEN\"]],[13,\"lzn\",\"_LZN\"],[13,\"NdotL\",[1,[1,[1,\"nx\",\"*\",\"lxn\"],\"+\",[1,\"ny\",\"*\",\"lyn\"]],\"+\",[1,\"nz\",\"*\",\"lzn\"]]],[13,\"diffuse\",[6,\"std.clamp\",[\"NdotL\",[5,\"0\"],[5,\"1\"]]]],[13,\"NdotH\",[1,[1,[1,\"nx\",\"*\",[1,\"lxn\",\"*\",\"_INV_H_LEN\"]],\"+\",[1,\"ny\",\"*\",[1,\"lyn\",\"*\",\"_INV_H_LEN\"]]],\"+\",[1,\"nz\",\"*\",[1,\"_HZ\",\"*\",\"_INV_H_LEN\"]]]],[13,\"shininess\",[6,\"std.exp2\",[[1,[5,\"8\"],\"-\",[1,\"specularSize\",\"*\",[5,\"7\"]]]]]],[13,\"specular\",[1,[6,\"std.pow\",[[6,\"std.clamp\",[\"NdotH\",[5,\"0\"],[5,\"1\"]]],\"shininess\"]],\"*\",\"specularIntensity\"]],[13,\"flowMod\",[6,\"neonFlow\",[\"sdfUV\",\"time\",\"flowSpeed\",\"flowAmount\"]]],[13,\"twoTone\",[6,\"std.mix\",[\"secondaryColor\",\"color\",\"diffuse\"]]],[13,\"baseColor\",[6,\"std.mix\",[\"color\",\"twoTone\",\"secondaryBlend\"]]],[13,\"ambient\",[5,\"0.12\"]],[13,\"selfEmission\",[1,\"cylinderZ\",\"*\",[5,\"0.35\"]]],[13,\"shadedRgb\",[6,[7,\"baseColor\",\"mul\"],[[1,[1,\"ambient\",\"+\",[1,\"diffuse\",\"*\",[5,\"0.55\"]]],\"+\",\"selfEmission\"]]]],[13,\"tubeRgb\",[6,\"d.vec3f\",[[1,[7,\"shadedRgb\",\"x\"],\"+\",\"specular\"],[1,[7,\"shadedRgb\",\"y\"],\"+\",\"specular\"],[1,[7,\"shadedRgb\",\"z\"],\"+\",\"specular\"]]]],[13,\"coreProfile\",[6,\"std.smoothstep\",[[5,\"0.55\"],[5,\"1\"],\"depthNorm\"]]],[13,\"hotCoreAmt\",[1,[1,\"coreProfile\",\"*\",\"hotCoreIntensity\"],\"*\",\"flowMod\"]],[13,\"hotCoreCol\",[6,\"std.mix\",[\"color\",[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],[5,\"0.75\"]]]],[13,\"tubeWithCore\",[6,\"std.mix\",[\"tubeRgb\",\"hotCoreCol\",\"hotCoreAmt\"]]],[13,\"tubeFlowed\",[6,[7,\"tubeWithCore\",\"mul\"],[[6,\"std.mix\",[[5,\"1\"],\"flowMod\",[5,\"0.4\"]]]]]],[13,\"glowMasked\",[6,\"neonGlow\",[\"sdf\",\"glowRadius\",\"glowIntensity\"]]],[13,\"flickerValue\",[6,\"neonFlicker\",[\"time\",\"flickerSpeed\",\"flickerAmount\"]]],[13,\"intensityMul\",[1,\"intensity\",\"*\",\"flickerValue\"]],[13,\"finalTubeRgb\",[6,[7,\"tubeFlowed\",\"mul\"],[\"intensityMul\"]]],[13,\"finalGlowRgb\",[6,[7,\"glowColor\",\"mul\"],[[1,\"glowMasked\",\"*\",\"intensityMul\"]]]],[13,\"finalR\",[6,\"std.mix\",[[7,\"finalGlowRgb\",\"x\"],[7,\"finalTubeRgb\",\"x\"],\"tubeMask\"]]],[13,\"finalG\",[6,\"std.mix\",[[7,\"finalGlowRgb\",\"y\"],[7,\"finalTubeRgb\",\"y\"],\"tubeMask\"]]],[13,\"finalB\",[6,\"std.mix\",[[7,\"finalGlowRgb\",\"z\"],[7,\"finalTubeRgb\",\"z\"],\"tubeMask\"]]],[13,\"glowAlpha\",[6,\"std.clamp\",[[1,\"glowMasked\",\"*\",[5,\"0.6\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"finalA\",[6,\"std.max\",[\"tubeMask\",\"glowAlpha\"]]],[13,\"result\",[6,\"d.vec4f\",[\"finalR\",\"finalG\",\"finalB\",\"finalA\"]]],[13,\"threshOut\",[1,[1,[1,\"glowR\",\"*\",[5,\"1.5\"]],\"+\",\"softPx\"],\"+\",\"smoothEPS\"]],[10,[6,\"std.select\",[\"result\",[6,\"d.vec4f\",[[5,\"0\"],[5,\"0\"],[5,\"0\"],[5,\"0\"]]],[1,\"sdfCenter\",\">\",\"threshOut\"]]]]]]},externals:{\"std.max\":()=>B,\"std.mix\":()=>K,\"std.select\":()=>N,\"std.sqrt\":()=>Ue,\"std.clamp\":()=>G,\"std.smoothstep\":()=>be,\"std.abs\":()=>re,DEG_TO_RAD:()=>pO,\"std.cos\":()=>pe,\"std.sin\":()=>ae,_INV_LIGHT_LEN:()=>Pp,_LZN:()=>M2,_INV_H_LEN:()=>Fg,_HZ:()=>Ig,\"std.exp2\":()=>Ia,\"std.pow\":()=>vt,neonFlow:()=>B2,\"d.vec3f\":()=>A,neonGlow:()=>E2,neonFlicker:()=>k2,\"d.vec4f\":()=>S}})&&e.f)({}));function vde(e,t,s,r){let{uniforms:o,ctx:a}=e,i=r?.gradSampler??t,l=$e(r?.volumetric?1:0),c=W(xc,\"sdfSpaceUV\",[o.center,o.scale,o.rotation,a.uv,a.aspect]),d=W(mO,\"neonSmoothEPS\",[o.tubeThickness,o.cornerSmoothing,l]),u=d.mul(-1);return W(_O,\"neonComposite\",[t(c),i(W(da,\"offsetUV\",[c,d,$e(0)])),i(W(da,\"offsetUV\",[c,u,$e(0)])),i(W(da,\"offsetUV\",[c,$e(0),d])),i(W(da,\"offsetUV\",[c,$e(0),u])),d,c,o.scale,a.viewportSize,s,o.cornerSmoothing,o.tubeThickness,o.color.member(\"rgb\"),o.secondaryColor.member(\"rgb\"),o.secondaryBlend,o.glowColor.member(\"rgb\"),o.intensity,o.hotCoreIntensity,o.glowIntensity,o.glowRadius,o.lightAngle,o.specularIntensity,o.specularSize,o.flickerSpeed,o.flickerAmount,o.flowSpeed,o.flowAmount,l])}var{applyNeonEffect:hde}=fde,gde=JSON.stringify({type:\"sphere3D\",radius:.35}),fO=H({name:\"Neon\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photorealistic neon tube / 3D pipe effect driven by a custom shape\",...Ts({chord:\"firstLobe\",stencil:\"none\",surface:(e,t)=>hde(t,e.sampler,t.ctx.time,{volumetric:e.volumetric,gradSampler:e.gradSampler})}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the neon shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the neon shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the neon shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},color:{default:\"#00ddff\",transform:ce,description:\"Primary neon tube color\",ui:{type:\"color\",label:\"Tube Color\",group:\"Colors\"}},secondaryColor:{default:\"#ff00aa\",transform:ce,description:\"Shadow-side color for a two-tone / dual-lit pipe look\",ui:{type:\"color\",label:\"Secondary Color\",group:\"Colors\"}},secondaryBlend:{default:.5,description:\"Blend between mono (0) and two-tone (1) tube coloring\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Blend\",group:\"Colors\"}},glowColor:{default:\"#00ddff\",transform:ce,description:\"Color of the outer glow / bloom\",ui:{type:\"color\",label:\"Glow Color\",group:\"Colors\"}},tubeThickness:{default:.2,transform:e=>e*.05,description:\"How far inward from the boundary the tube extends. Low = thin neon outline, high = thick 3D pipe\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Tube Thickness\",group:\"Tube\"}},intensity:{default:1.5,description:\"Overall brightness multiplier\",ui:{type:\"range\",min:.5,max:4,step:.01,label:\"Intensity\",group:\"Tube\"}},hotCoreIntensity:{default:.6,description:\"Bright white-hot center line \\u2014 the gas discharge glow inside the tube\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Hot Core\",group:\"Tube\"}},glowIntensity:{default:.6,description:\"Outer glow / bloom strength\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Glow Intensity\",group:\"Glow\"}},glowRadius:{default:.25,description:\"How far the glow extends beyond the tube\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Glow Radius\",group:\"Glow\"}},lightAngle:{default:300,description:\"Directional light angle in degrees \\u2014 controls 3D shading on the tube\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Lighting\"}},specularIntensity:{default:.5,description:\"Specular highlight brightness on the tube surface\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Specular\",group:\"Lighting\"}},specularSize:{default:.5,description:\"Specular highlight size \\u2014 0 = tight pinpoint, 1 = broad sheen\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Specular Size\",group:\"Lighting\"}},cornerSmoothing:{default:.15,description:\"Rounds sharp corners to mimic how real glass tubes curve at bends\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Corner Smoothing\",group:\"Tube\"}},flickerSpeed:{default:0,description:\"Flicker animation speed \\u2014 0 = off, higher = faster sporadic on/off\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Flicker\"}},flickerAmount:{default:.2,description:\"How often the neon flickers off \\u2014 0 = always on, 1 = frequent outages\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Amount\",group:\"Flicker\"}},flowSpeed:{default:0,description:\"Flow animation speed \\u2014 0 = off, light rotates through the tube\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Flow\"}},flowAmount:{default:.3,description:\"Strength of the flowing brightness variation \\u2014 0 = uniform, 1 = dramatic\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Amount\",group:\"Flow\"}},shape:{default:gde,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file \\u2014 when non-empty, activates SVG mode and triggers a shader recompile\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type \\u2014 triggers recompile when shape is switched. When empty, derived from shape JSON at mount time.\"}}});var yde=ko({applyEmbossEffect:()=>bde,embossComposite:()=>gO,embossEdgeLighting:()=>R2,embossHeight:()=>Yi,embossTraceUV:()=>z2,embossWarpUV:()=>hO}),Cp=.017453292519943295,Yg=1/Math.sqrt(1.49),vO=.7*Yg,Yi=w.fn([n,n,n,n],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=__tsover_mul(s,G(__tsover_div(__tsover_mul(t,-1),.18),0,1));return N(__tsover_mul(s,be(r,__tsover_mul(r,-1),t)),a,o>.5)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"s\"},{type:\"i\",name:\"depth\"},{type:\"i\",name:\"transitionW\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"vol\",[1,\"depth\",\"*\",[6,\"std.clamp\",[[1,[1,\"s\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",[5,\"0.18\"]],[5,\"0\"],[5,\"1\"]]]]],[13,\"flat\",[1,\"depth\",\"*\",[6,\"std.smoothstep\",[\"transitionW\",[1,\"transitionW\",\"*\",[4,\"-\",[5,\"1\"]]],\"s\"]]]],[10,[6,\"std.select\",[\"flat\",\"vol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]]]]},externals:{\"std.clamp\":()=>G,\"std.smoothstep\":()=>be,\"std.select\":()=>N}})&&e.f)({})),z2=w.fn([m,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=pe(__tsover_mul(s,Cp)),i=ae(__tsover_mul(s,Cp)),l=B(re(r),1e-4),c=__tsover_mul(l,.06);return m(__tsover_add(t.x,__tsover_mul(__tsover_mul(a,c),o)),__tsover_add(t.y,__tsover_mul(__tsover_mul(i,c),o)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfUV\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"depth\"},{type:\"i\",name:\"frac\"}],body:[0,[[13,\"lx\",[6,\"std.cos\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"ly\",[6,\"std.sin\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"absDepth\",[6,\"std.max\",[[6,\"std.abs\",[\"depth\"]],[5,\"0.0001\"]]]],[13,\"spread\",[1,\"absDepth\",\"*\",[5,\"0.06\"]]],[10,[6,\"d.vec2f\",[[1,[7,\"sdfUV\",\"x\"],\"+\",[1,[1,\"lx\",\"*\",\"spread\"],\"*\",\"frac\"]],[1,[7,\"sdfUV\",\"y\"],\"+\",[1,[1,\"ly\",\"*\",\"spread\"],\"*\",\"frac\"]]]]]]]},externals:{\"std.cos\":()=>pe,DEG_TO_RAD:()=>Cp,\"std.sin\":()=>ae,\"std.max\":()=>B,\"std.abs\":()=>re,\"d.vec2f\":()=>m}})&&e.f)({})),hO=w.fn([m,m,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let i=be(.003,__tsover_mul(.003,-1),r),l=__tsover_sub(1,__tsover_mul(__tsover_mul(o,.05),i)),c=s.x,d=__tsover_sub(1,s.y);return m(__tsover_add(c,__tsover_mul(__tsover_sub(t.x,c),l)),__tsover_add(d,__tsover_mul(__tsover_sub(t.y,d),l)))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"sdfC\"},{type:\"i\",name:\"depth\"}],body:[0,[[13,\"tw\",[5,\"0.003\"]],[13,\"inside\",[6,\"std.smoothstep\",[\"tw\",[1,\"tw\",\"*\",[4,\"-\",[5,\"1\"]]],\"sdfC\"]]],[13,\"dispScale\",[1,[5,\"1\"],\"-\",[1,[1,\"depth\",\"*\",[5,\"0.05\"]],\"*\",\"inside\"]]],[13,\"centerX\",[7,\"center\",\"x\"]],[13,\"centerY\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[10,[6,\"d.vec2f\",[[1,\"centerX\",\"+\",[1,[1,[7,\"uv\",\"x\"],\"-\",\"centerX\"],\"*\",\"dispScale\"]],[1,\"centerY\",\"+\",[1,[1,[7,\"uv\",\"y\"],\"-\",\"centerY\"],\"*\",\"dispScale\"]]]]]]]},externals:{\"std.smoothstep\":()=>be,\"d.vec2f\":()=>m}})&&e.f)({})),R2=w.fn([n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c)=>{\"use gpu\";let p=Yi(t,a,.003,c),_=Yi(s,a,.003,c),f=Yi(r,a,.003,c),h=Yi(o,a,.003,c),g=__tsover_div(__tsover_sub(p,_),__tsover_mul(.003,2)),y=__tsover_div(__tsover_sub(f,h),__tsover_mul(.003,2)),b=Ue(__tsover_add(__tsover_add(__tsover_mul(g,g),__tsover_mul(y,y)),1)),x=__tsover_div(__tsover_mul(g,-1),b),P=__tsover_div(__tsover_mul(y,-1),b),C=__tsover_div(1,b),E=pe(__tsover_mul(i,Cp)),R=ae(__tsover_mul(i,Cp)),U=__tsover_mul(E,Yg),L=__tsover_mul(R,Yg),k=vO,D=__tsover_add(__tsover_add(__tsover_mul(x,U),__tsover_mul(P,L)),__tsover_mul(C,k)),O=__tsover_mul(__tsover_sub(D,k),l);return m(B(O,0),B(__tsover_mul(O,-1),0))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfR\"},{type:\"i\",name:\"sdfL\"},{type:\"i\",name:\"sdfU\"},{type:\"i\",name:\"sdfD\"},{type:\"i\",name:\"depth\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"lightIntensity\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"eps\",[5,\"0.003\"]],[13,\"tw\",[5,\"0.003\"]],[13,\"hR\",[6,\"embossHeight\",[\"sdfR\",\"depth\",\"tw\",\"volumetric\"]]],[13,\"hL\",[6,\"embossHeight\",[\"sdfL\",\"depth\",\"tw\",\"volumetric\"]]],[13,\"hU\",[6,\"embossHeight\",[\"sdfU\",\"depth\",\"tw\",\"volumetric\"]]],[13,\"hD\",[6,\"embossHeight\",[\"sdfD\",\"depth\",\"tw\",\"volumetric\"]]],[13,\"dhx\",[1,[1,\"hR\",\"-\",\"hL\"],\"/\",[1,\"eps\",\"*\",[5,\"2\"]]]],[13,\"dhy\",[1,[1,\"hU\",\"-\",\"hD\"],\"/\",[1,\"eps\",\"*\",[5,\"2\"]]]],[13,\"nLen\",[6,\"std.sqrt\",[[1,[1,[1,\"dhx\",\"*\",\"dhx\"],\"+\",[1,\"dhy\",\"*\",\"dhy\"]],\"+\",[5,\"1\"]]]]],[13,\"nx\",[1,[1,\"dhx\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"nLen\"]],[13,\"ny\",[1,[1,\"dhy\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"nLen\"]],[13,\"nz\",[1,[5,\"1\"],\"/\",\"nLen\"]],[13,\"lx\",[6,\"std.cos\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"ly\",[6,\"std.sin\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"lxn\",[1,\"lx\",\"*\",\"_INV_LIGHT_LEN\"]],[13,\"lyn\",[1,\"ly\",\"*\",\"_INV_LIGHT_LEN\"]],[13,\"lzn\",\"_LZN\"],[13,\"NdotL\",[1,[1,[1,\"nx\",\"*\",\"lxn\"],\"+\",[1,\"ny\",\"*\",\"lyn\"]],\"+\",[1,\"nz\",\"*\",\"lzn\"]]],[13,\"edgeLighting\",[1,[1,\"NdotL\",\"-\",\"lzn\"],\"*\",\"lightIntensity\"]],[13,\"highlight\",[6,\"std.max\",[\"edgeLighting\",[5,\"0\"]]]],[13,\"edgeShadow\",[6,\"std.max\",[[1,\"edgeLighting\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"]]]],[10,[6,\"d.vec2f\",[\"highlight\",\"edgeShadow\"]]]]]},externals:{embossHeight:()=>Yi,\"std.sqrt\":()=>Ue,\"std.cos\":()=>pe,DEG_TO_RAD:()=>Cp,\"std.sin\":()=>ae,_INV_LIGHT_LEN:()=>Yg,_LZN:()=>vO,\"std.max\":()=>B,\"d.vec2f\":()=>m}})&&e.f)({})),gO=w.fn([S,n,n,n,n,n,n,n,n,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_,f)=>{\"use gpu\";let g=R2(r,o,a,i,d,u,p,f),y=g.x,b=g.y,x=Yi(s,d,.003,f),P=B(re(d),1e-4),C=__tsover_mul(P,.06),E=Yi(l,d,C,f),R=Yi(c,d,C,f),U=__tsover_div(__tsover_sub(E,x),P),L=__tsover_div(__tsover_sub(R,x),P),k=__tsover_add(__tsover_mul(be(0,.5,U),.55),__tsover_mul(be(0,.5,L),.45)),D=__tsover_mul(G(__tsover_add(b,k),0,1),_),O=A(t.x,t.y,t.z),F=A(y,y,y),q=G(O.mul(__tsover_sub(1,D)).add(F),A(0),A(1));return S(q.x,q.y,q.z,t.w)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"childColor\"},{type:\"i\",name:\"sdfC\"},{type:\"i\",name:\"sdfR\"},{type:\"i\",name:\"sdfL\"},{type:\"i\",name:\"sdfU\"},{type:\"i\",name:\"sdfD\"},{type:\"i\",name:\"h1raw\"},{type:\"i\",name:\"h2raw\"},{type:\"i\",name:\"depth\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"lightIntensity\"},{type:\"i\",name:\"shadowIntensity\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"tw\",[5,\"0.003\"]],[13,\"light\",[6,\"embossEdgeLighting\",[\"sdfR\",\"sdfL\",\"sdfU\",\"sdfD\",\"depth\",\"lightAngle\",\"lightIntensity\",\"volumetric\"]]],[13,\"highlight\",[7,\"light\",\"x\"]],[13,\"edgeShadow\",[7,\"light\",\"y\"]],[13,\"hC\",[6,\"embossHeight\",[\"sdfC\",\"depth\",\"tw\",\"volumetric\"]]],[13,\"absDepth\",[6,\"std.max\",[[6,\"std.abs\",[\"depth\"]],[5,\"0.0001\"]]]],[13,\"shadowTw\",[1,\"absDepth\",\"*\",[5,\"0.06\"]]],[13,\"h1\",[6,\"embossHeight\",[\"h1raw\",\"depth\",\"shadowTw\",\"volumetric\"]]],[13,\"h2\",[6,\"embossHeight\",[\"h2raw\",\"depth\",\"shadowTw\",\"volumetric\"]]],[13,\"diff1\",[1,[1,\"h1\",\"-\",\"hC\"],\"/\",\"absDepth\"]],[13,\"diff2\",[1,[1,\"h2\",\"-\",\"hC\"],\"/\",\"absDepth\"]],[13,\"castShadow\",[1,[1,[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.5\"],\"diff1\"]],\"*\",[5,\"0.55\"]],\"+\",[1,[6,\"std.smoothstep\",[[5,\"0\"],[5,\"0.5\"],\"diff2\"]],\"*\",[5,\"0.45\"]]]],[13,\"totalShadow\",[1,[6,\"std.clamp\",[[1,\"edgeShadow\",\"+\",\"castShadow\"],[5,\"0\"],[5,\"1\"]]],\"*\",\"shadowIntensity\"]],[13,\"childRgb\",[6,\"d.vec3f\",[[7,\"childColor\",\"x\"],[7,\"childColor\",\"y\"],[7,\"childColor\",\"z\"]]]],[13,\"highlightRgb\",[6,\"d.vec3f\",[\"highlight\",\"highlight\",\"highlight\"]]],[13,\"finalRgb\",[6,\"std.clamp\",[[6,[7,[6,[7,\"childRgb\",\"mul\"],[[1,[5,\"1\"],\"-\",\"totalShadow\"]]],\"add\"],[\"highlightRgb\"]],[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[10,[6,\"d.vec4f\",[[7,\"finalRgb\",\"x\"],[7,\"finalRgb\",\"y\"],[7,\"finalRgb\",\"z\"],[7,\"childColor\",\"w\"]]]]]]},externals:{embossEdgeLighting:()=>R2,embossHeight:()=>Yi,\"std.max\":()=>B,\"std.abs\":()=>re,\"std.smoothstep\":()=>be,\"std.clamp\":()=>G,\"d.vec3f\":()=>A,\"d.vec4f\":()=>S}})&&e.f)({}));function bde(e,t,s,r){let{uniforms:o,ctx:a}=e,i=r?.gradSampler??t,l=$e(r?.volumetric?1:0),c=.003,d=W(xc,\"sdfSpaceUV\",[o.center,o.scale,o.rotation,a.uv,a.aspect]),u=t(d).member(\"r\"),p=i(W(da,\"offsetUV\",[d,$e(c),$e(0)])).member(\"r\"),_=i(W(da,\"offsetUV\",[d,$e(-c),$e(0)])).member(\"r\"),f=i(W(da,\"offsetUV\",[d,$e(0),$e(c)])).member(\"r\"),h=i(W(da,\"offsetUV\",[d,$e(0),$e(-c)])).member(\"r\"),g=i(W(z2,\"embossTraceUV\",[d,o.lightAngle,o.depth,$e(.5)])).member(\"r\"),y=i(W(z2,\"embossTraceUV\",[d,o.lightAngle,o.depth,$e(1)])).member(\"r\"),b=W(hO,\"embossWarpUV\",[a.uv,o.center,u,o.depth]);return W(gO,\"embossComposite\",[W(Yt,\"unpremultiplyAlpha\",[s.sample(b)]),u,p,_,f,h,g,y,o.depth,o.lightAngle,o.lightIntensity,o.shadowIntensity,l])}var{applyEmbossEffect:xde}=yde,Ade=JSON.stringify({type:\"sphere3D\",radius:.35}),yO=H({name:\"Emboss\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Embossed / debossed relief shading on top of child content, driven by a custom shape\",requiresRTT:!0,requiresChild:!0,...Ts({chord:\"firstLobe\",stencil:\"none\",child:\"required\",surface:(e,t)=>xde(t,e.sampler,e.childTexture,{volumetric:e.volumetric,gradSampler:e.gradSampler})}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the embossed shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the embossed shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the embossed shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},depth:{default:-.5,description:\"Relief depth \\u2014 negative = inset (debossed), positive = raised (embossed)\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Depth\",group:\"Relief\"}},lightAngle:{default:260,description:\"Directional light angle in degrees \\u2014 controls highlight and shadow direction\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Light Angle\",group:\"Lighting\"}},lightIntensity:{default:.6,description:\"Strength of the directional edge highlights and shadows\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Light Intensity\",group:\"Lighting\"}},shadowIntensity:{default:.3,description:\"Darkness of the relief shadow\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadow Intensity\",group:\"Relief\"}},shape:{default:Ade,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file \\u2014 when non-empty, activates SVG mode and triggers a shader recompile\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type \\u2014 triggers recompile when shape is switched. When empty, derived from shape JSON at mount time.\"}}});var wde=ko({Distortion3DTrace:()=>qg,applyUVMode3d:()=>Tde,buildParamThreadedTrace:()=>Pde,distortion3dLighting:()=>Sde}),qg=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({hitPos:A,normal:A,rd:A,hit:n}),\"Distortion3DTrace\"),Tde=w.fn([m,n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";let r=G(t,m(0),m(1)),o=re(Re(t.mul(.5)).mul(2).sub(1)),a=Re(t),i=N(n(0),n(1),t.y<=1),l=N(n(0),i,t.y>=0),c=N(n(0),l,t.x<=1),d=N(n(0),c,t.x>=0),u=N(N(N(a,o,s<2.5),t,s<1.5),r,s<.5),p=N(N(n(1),d,s<1.5),n(1),s<.5);return A(u.x,u.y,p)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"uvMode\"}],body:[0,[[13,\"stretched\",[6,\"std.clamp\",[\"uv\",[6,\"d.vec2f\",[[5,\"0\"]]],[6,\"d.vec2f\",[[5,\"1\"]]]]]],[13,\"mirrored\",[6,\"std.abs\",[[6,[7,[6,[7,[6,\"std.fract\",[[6,[7,\"uv\",\"mul\"],[[5,\"0.5\"]]]]],\"mul\"],[[5,\"2\"]]],\"sub\"],[[5,\"1\"]]]]]],[13,\"wrapped\",[6,\"std.fract\",[\"uv\"]]],[13,\"tv1\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,[7,\"uv\",\"y\"],\"<=\",[5,\"1\"]]]]],[13,\"tv2\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"tv1\",[1,[7,\"uv\",\"y\"],\">=\",[5,\"0\"]]]]],[13,\"tv3\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"tv2\",[1,[7,\"uv\",\"x\"],\"<=\",[5,\"1\"]]]]],[13,\"transparentVisible\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],\"tv3\",[1,[7,\"uv\",\"x\"],\">=\",[5,\"0\"]]]]],[13,\"fuv2\",[6,\"std.select\",[\"wrapped\",\"mirrored\",[1,\"uvMode\",\"<\",[5,\"2.5\"]]]]],[13,\"fuv1\",[6,\"std.select\",[\"fuv2\",\"uv\",[1,\"uvMode\",\"<\",[5,\"1.5\"]]]]],[13,\"finalUV\",[6,\"std.select\",[\"fuv1\",\"stretched\",[1,\"uvMode\",\"<\",[5,\"0.5\"]]]]],[13,\"vis1\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"1\"]]],\"transparentVisible\",[1,\"uvMode\",\"<\",[5,\"1.5\"]]]]],[13,\"visible\",[6,\"std.select\",[\"vis1\",[6,\"d.f32\",[[5,\"1\"]]],[1,\"uvMode\",\"<\",[5,\"0.5\"]]]]],[10,[6,\"d.vec3f\",[[7,\"finalUV\",\"x\"],[7,\"finalUV\",\"y\"],\"visible\"]]]]]},externals:{\"std.clamp\":()=>G,\"d.vec2f\":()=>m,\"std.abs\":()=>re,\"std.fract\":()=>Re,\"std.select\":()=>N,\"d.f32\":()=>n,\"d.vec3f\":()=>A}})&&e.f)({})),Sde=w.fn([S,A,A,n,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l)=>{\"use gpu\";let c=vs(A(.4,.7,-.6)),d=r.mul(-1),u=G(Se(s,c),0,1),p=vs(c.add(d)),_=__tsover_add(__tsover_mul(i,256),4),f=__tsover_mul(__tsover_mul(vt(G(Se(s,p),0,1),_),i),1.5),h=G(Se(s,d),0,1),g=__tsover_mul(__tsover_mul(vt(__tsover_sub(1,h),3),.5),i),y=G(K(1,__tsover_add(__tsover_add(__tsover_add(.35,__tsover_mul(u,.65)),f),g),l),0,3),b=G(t.xyz.mul(y),A(0),A(1)),x=__tsover_mul(__tsover_mul(o,t.w),a);return S(b.x,b.y,b.z,x)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"surfaceColor\"},{type:\"i\",name:\"normal\"},{type:\"i\",name:\"rd\"},{type:\"i\",name:\"hit\"},{type:\"i\",name:\"uvVisible\"},{type:\"i\",name:\"glossAmt\"},{type:\"i\",name:\"lightAmt\"}],body:[0,[[13,\"lightDir\",[6,\"std.normalize\",[[6,\"d.vec3f\",[[5,\"0.4\"],[5,\"0.7\"],[4,\"-\",[5,\"0.6\"]]]]]]],[13,\"viewDir\",[6,[7,\"rd\",\"mul\"],[[4,\"-\",[5,\"1\"]]]]],[13,\"diffuse\",[6,\"std.clamp\",[[6,\"std.dot\",[\"normal\",\"lightDir\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"halfVec\",[6,\"std.normalize\",[[6,[7,\"lightDir\",\"add\"],[\"viewDir\"]]]]],[13,\"specPow\",[1,[1,\"glossAmt\",\"*\",[5,\"256\"]],\"+\",[5,\"4\"]]],[13,\"specular\",[1,[1,[6,\"std.pow\",[[6,\"std.clamp\",[[6,\"std.dot\",[\"normal\",\"halfVec\"]],[5,\"0\"],[5,\"1\"]]],\"specPow\"]],\"*\",\"glossAmt\"],\"*\",[5,\"1.5\"]]],[13,\"nDotV\",[6,\"std.clamp\",[[6,\"std.dot\",[\"normal\",\"viewDir\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"fresnel\",[1,[1,[6,\"std.pow\",[[1,[5,\"1\"],\"-\",\"nDotV\"],[5,\"3\"]]],\"*\",[5,\"0.5\"]],\"*\",\"glossAmt\"]],[13,\"ambient\",[5,\"0.35\"]],[13,\"lit\",[6,\"std.mix\",[[5,\"1\"],[1,[1,[1,\"ambient\",\"+\",[1,\"diffuse\",\"*\",[5,\"0.65\"]]],\"+\",\"specular\"],\"+\",\"fresnel\"],\"lightAmt\"]]],[13,\"litClamped\",[6,\"std.clamp\",[\"lit\",[5,\"0\"],[5,\"3\"]]]],[13,\"col\",[6,[7,[7,\"surfaceColor\",\"xyz\"],\"mul\"],[\"litClamped\"]]],[13,\"colClamped\",[6,\"std.clamp\",[\"col\",[6,\"d.vec3f\",[[5,\"0\"]]],[6,\"d.vec3f\",[[5,\"1\"]]]]]],[13,\"alpha\",[1,[1,\"hit\",\"*\",[7,\"surfaceColor\",\"w\"]],\"*\",\"uvVisible\"]],[10,[6,\"d.vec4f\",[[7,\"colClamped\",\"x\"],[7,\"colClamped\",\"y\"],[7,\"colClamped\",\"z\"],\"alpha\"]]]]]},externals:{\"std.normalize\":()=>vs,\"d.vec3f\":()=>A,\"std.clamp\":()=>G,\"std.dot\":()=>Se,\"std.pow\":()=>vt,\"std.mix\":()=>K,\"d.vec4f\":()=>S}})&&e.f)({}));function Pde(e,t){let s=t.steps,r=t.stepCap,o=t.hitEps,a=t.maxDistance??20;return w.fn([m,n,m,n,S,S,S,n],qg)((i=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(i.f=((l,c,d,u,p,_,f,h)=>{\"use gpu\";let g=d.x,y=__tsover_sub(1,d.y),b=__tsover_sub(8,__tsover_mul(u,.06)),x=A(0,0,__tsover_mul(b,-1)),P=vs(A(__tsover_mul(__tsover_sub(l.x,g),c),__tsover_sub(l.y,y),1.5)),C=n(0),E=n(0),R=n(a);for(let Y=0;Y<s;Y++){let V=e(x.add(P.mul(C)),p,_,f,h);if(V<o){E=n(1);break}if(C>R)break;C=__tsover_add(C,ye(V,r))}let U=x.add(P.mul(C)),L=.001,k=__tsover_mul(L,-1),D=e(U.add(A(L,k,k)),p,_,f,h),O=e(U.add(A(k,k,L)),p,_,f,h),F=e(U.add(A(k,L,k)),p,_,f,h),q=e(U.add(A(L,L,L)),p,_,f,h);return qg({hitPos:U,normal:vs(A(1,-1,-1).mul(D).add(A(-1,-1,1).mul(O)).add(A(-1,1,-1).mul(F)).add(A(1,1,1).mul(q))),rd:P,hit:E})}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"aspect\"},{type:\"i\",name:\"center\"},{type:\"i\",name:\"zoom\"},{type:\"i\",name:\"rp0\"},{type:\"i\",name:\"rp1\"},{type:\"i\",name:\"rp2\"},{type:\"i\",name:\"t\"}],body:[0,[[13,\"cx\",[7,\"center\",\"x\"]],[13,\"cy\",[1,[5,\"1\"],\"-\",[7,\"center\",\"y\"]]],[13,\"camDist\",[1,[5,\"8\"],\"-\",[1,\"zoom\",\"*\",[5,\"0.06\"]]]],[13,\"ro\",[6,\"d.vec3f\",[[5,\"0\"],[5,\"0\"],[1,\"camDist\",\"*\",[4,\"-\",[5,\"1\"]]]]]],[13,\"rd\",[6,\"std.normalize\",[[6,\"d.vec3f\",[[1,[1,[7,\"uv\",\"x\"],\"-\",\"cx\"],\"*\",\"aspect\"],[1,[7,\"uv\",\"y\"],\"-\",\"cy\"],[5,\"1.5\"]]]]]],[12,\"rayT\",[6,\"d.f32\",[[5,\"0\"]]]],[12,\"hit\",[6,\"d.f32\",[[5,\"0\"]]]],[13,\"maxDistF\",[6,\"d.f32\",[\"MAX_DIST\"]]],[14,[12,\"i\",[5,\"0\"]],[1,\"i\",\"<\",\"STEPS\"],[102,\"++\",\"i\"],[0,[[13,\"p\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"rayT\"]]]]],[13,\"dd\",[6,\"sdf\",[\"p\",\"rp0\",\"rp1\",\"rp2\",\"t\"]]],[11,[1,\"dd\",\"<\",\"HIT_EPS\"],[0,[[2,\"hit\",\"=\",[6,\"d.f32\",[[5,\"1\"]]]],[17]]]],[11,[1,\"rayT\",\">\",\"maxDistF\"],[0,[[17]]]],[2,\"rayT\",\"=\",[1,\"rayT\",\"+\",[6,\"std.min\",[\"dd\",\"STEP_CAP\"]]]]]]],[13,\"hitPos\",[6,[7,\"ro\",\"add\"],[[6,[7,\"rd\",\"mul\"],[\"rayT\"]]]]],[13,\"hh\",[5,\"0.001\"]],[13,\"hn\",[1,\"hh\",\"*\",[4,\"-\",[5,\"1\"]]]],[13,\"k0\",[6,\"sdf\",[[6,[7,\"hitPos\",\"add\"],[[6,\"d.vec3f\",[\"hh\",\"hn\",\"hn\"]]]],\"rp0\",\"rp1\",\"rp2\",\"t\"]]],[13,\"k1\",[6,\"sdf\",[[6,[7,\"hitPos\",\"add\"],[[6,\"d.vec3f\",[\"hn\",\"hn\",\"hh\"]]]],\"rp0\",\"rp1\",\"rp2\",\"t\"]]],[13,\"k2\",[6,\"sdf\",[[6,[7,\"hitPos\",\"add\"],[[6,\"d.vec3f\",[\"hn\",\"hh\",\"hn\"]]]],\"rp0\",\"rp1\",\"rp2\",\"t\"]]],[13,\"k3\",[6,\"sdf\",[[6,[7,\"hitPos\",\"add\"],[[6,\"d.vec3f\",[\"hh\",\"hh\",\"hh\"]]]],\"rp0\",\"rp1\",\"rp2\",\"t\"]]],[13,\"normal\",[6,\"std.normalize\",[[6,[7,[6,[7,[6,[7,[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[4,\"-\",[5,\"1\"]],[4,\"-\",[5,\"1\"]]]],\"mul\"],[\"k0\"]],\"add\"],[[6,[7,[6,\"d.vec3f\",[[4,\"-\",[5,\"1\"]],[4,\"-\",[5,\"1\"]],[5,\"1\"]]],\"mul\"],[\"k1\"]]]],\"add\"],[[6,[7,[6,\"d.vec3f\",[[4,\"-\",[5,\"1\"]],[5,\"1\"],[4,\"-\",[5,\"1\"]]]],\"mul\"],[\"k2\"]]]],\"add\"],[[6,[7,[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]],\"mul\"],[\"k3\"]]]]]]],[10,[6,\"Distortion3DTrace\",[[104,{hitPos:\"hitPos\",normal:\"normal\",rd:\"rd\",hit:\"hit\"}]]]]]]},externals:{\"d.vec3f\":()=>A,\"std.normalize\":()=>vs,\"d.f32\":()=>n,MAX_DIST:()=>a,STEPS:()=>s,sdf:()=>e,HIT_EPS:()=>o,\"std.min\":()=>ye,STEP_CAP:()=>r,Distortion3DTrace:()=>qg}})&&i.f)({}))}var{applyUVMode3d:Cde,distortion3dLighting:Mde,buildParamThreadedTrace:Ede}=wde,Wg=bt,D2=Math.PI*2/10,kde=JSON.stringify({type:\"ribbon\",angle:0,twist:50,width:40,thickness:20,seed:0}),bO={sphere:{sdf:TA,surfaceUV:SA,uvHint:\"sphereSurfaceUV\",steps:64,stepCap:1.5,hitEps:.001},torus:{sdf:PA,surfaceUV:CA,uvHint:\"torusSurfaceUV\",steps:96,stepCap:.5,hitEps:.001},box:{sdf:MA,surfaceUV:EA,uvHint:\"boxFaceUV\",steps:96,stepCap:.5,hitEps:.001},capsule:{sdf:kA,surfaceUV:BA,uvHint:\"capsuleSurfaceUV\",steps:64,stepCap:1.5,hitEps:.001},mobius:{sdf:zA,surfaceUV:RA,uvHint:\"mobiusSurfaceUV\",steps:96,stepCap:.3,hitEps:.001},ribbon:{sdf:DA,surfaceUV:LA,uvHint:\"twistedRibbonSurfaceUV\",steps:128,stepCap:.08,hitEps:.002}},Bde={torus:{rotX:-90,spinY:.05},box:{rotX:15,spinY:.1},sphere:{spinY:.1},capsule:{spinY:.1},mobius:{rotX:-30,spinY:.05}},xO=H({name:\"Form3D\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Distortions\",description:\"Wraps child content onto a 3D raymarched shape with lighting.\",requiresRTT:!0,requiresChild:!0,animatedTime:{speed:\"speed\"},extraFields:UA(\"_f3p\",[[1,0,1,0],[1,0,.35,.1],[.3,.02,0,0]]),props:{shape3d:{default:kde,description:\"3D shape and its parameters\",ui:{type:\"shape3d\",label:\"Shape\",group:\"Shape\"}},shape3dType:{default:\"ribbon\",compileTime:!0,description:\"Active shape type \\u2014 triggers recompile when shape is switched\"},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape on screen\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},zoom:{default:50,description:\"Camera zoom level\",ui:{type:[\"range\",\"map\"],min:10,max:200,step:1,label:\"Zoom\",group:\"Scene\"}},glossiness:{default:50,description:\"Specular highlight intensity and sharpness\",ui:{type:[\"range\",\"map\"],min:0,max:200,step:1,label:\"Glossiness\",group:\"Lighting\"}},lighting:{default:50,description:\"Overall intensity of lighting effects\",ui:{type:[\"range\",\"map\"],min:0,max:200,step:1,label:\"Lighting\",group:\"Lighting\"}},uvMode:{default:\"stretch\",transform:Fr,description:\"How to handle UV coordinates at shape boundaries\",ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"UV Edges\",group:\"Scene\"}},speed:{default:1,description:\"Animation speed \\u2014 scales all spin rates\",ui:{type:\"range\",min:-10,max:10,step:.1,label:\"Speed\",group:\"Animation\"}}},gpu:{fragment:e=>{let{childNode:t,convertToTexture:s,uniforms:r,propValues:o,getCpuValue:a,onBeforeRender:i,ctx:l}=e;if(!t)return xt;let c=s(t),d=o.shape3dType||\"ribbon\",u=bO[d]??bO.ribbon,p=0,_=0,f=0,h=\"\",g=(()=>{try{return JSON.parse(a(\"shape3d\"))}catch{return{}}})(),y=(O,F)=>typeof g[O]==\"number\"?g[O]:F,b=O=>{let F=a(\"shape3d\");if(typeof F==\"string\"){if(F!==h){h=F;try{g=JSON.parse(F)}catch{}}}else F&&typeof F==\"object\"&&(g=F);let q=a(\"speed\")??1;if(d===\"ribbon\"){let le=y(\"angle\",0)*Wg,se=y(\"twist\",50)*.03,Te=y(\"width\",40)*.012,de=Te*.5,xe=y(\"thickness\",20)*.001+.01,Ae=y(\"seed\",0),De=Math.max(de*se,1);e.setExtraField(\"_f3p0\",[le,se,de,Te]),e.setExtraField(\"_f3p1\",[xe,Ae,De,0]),e.setExtraField(\"_f3p2\",[0,0,0,0]);return}let Y=Bde[d]??{};p+=O*q*y(\"spinX\",Y.spinX??0)*D2,_+=O*q*y(\"spinY\",Y.spinY??0)*D2,f+=O*q*y(\"spinZ\",Y.spinZ??0)*D2;let V=y(\"rotX\",Y.rotX??0)*Wg+p,X=y(\"rotY\",Y.rotY??0)*Wg+_,Q=y(\"rotZ\",Y.rotZ??0)*Wg+f,te=[Math.cos(V),Math.sin(V),Math.cos(X),Math.sin(X)],J=Math.cos(Q),oe=Math.sin(Q);d===\"sphere\"?(e.setExtraField(\"_f3p0\",te),e.setExtraField(\"_f3p1\",[J,oe,y(\"radius\",60)*.008+.1,0]),e.setExtraField(\"_f3p2\",[0,0,0,0])):d===\"torus\"?(e.setExtraField(\"_f3p0\",te),e.setExtraField(\"_f3p1\",[J,oe,y(\"outerRadius\",60)*.008+.1,y(\"tubeRadius\",25)*.006+.05]),e.setExtraField(\"_f3p2\",[0,0,0,0])):d===\"box\"?(e.setExtraField(\"_f3p0\",te),e.setExtraField(\"_f3p1\",[J,oe,y(\"sizeX\",50)*.006,y(\"sizeY\",50)*.006]),e.setExtraField(\"_f3p2\",[y(\"sizeZ\",50)*.006,y(\"rounding\",20)*.001,0,0])):d===\"capsule\"?(e.setExtraField(\"_f3p0\",te),e.setExtraField(\"_f3p1\",[J,oe,y(\"radius\",25)*.006+.05,y(\"height\",80)*.005]),e.setExtraField(\"_f3p2\",[0,0,0,0])):(e.setExtraField(\"_f3p0\",te),e.setExtraField(\"_f3p1\",[J,oe,y(\"ringRadius\",60)*.008+.1,y(\"halfWidth\",30)*.005]),e.setExtraField(\"_f3p2\",[y(\"thickness\",8)*.001+.005,0,0,0]))};b(0),i(O=>b(O?.deltaTime??0));let x=wt(e),P=W(Ede(u.sdf,{steps:u.steps,stepCap:u.stepCap,hitEps:u.hitEps}),`form3dTrace_${d}`,[l.uv,l.aspect,r.center,r.zoom,r._f3p0,r._f3p1,r._f3p2,x]),C=P.member(\"hitPos\"),E=P.member(\"normal\"),R=P.member(\"rd\"),U=P.member(\"hit\"),L=W(Cde,\"applyUVMode3d\",[W(u.surfaceUV,u.uvHint,[C,E,r._f3p0,r._f3p1,r._f3p2,x]),r.uvMode]),k=L.member(\"xy\"),D=L.member(\"z\");return W(Mde,\"distortion3dLighting\",[W(Yt,\"unpremultiplyAlpha\",[c.sample(k)]),E,R,U,D,r.glossiness.mul(.005),r.lighting.mul(.005)])}}});var zde=ko({applyThinFilmEffect:()=>Rde,thinFilmCompose:()=>PO,thinFilmCustomParams:()=>SO,thinFilmRainbow:()=>TO,thinFilmShade:()=>wO}),L2=.017453292519943295,AO=6.283185307179586,wO=w.fn([n,n,n,n,n,n,n,n,n,n,n,n],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o,a,i,l,c,d,u,p,_)=>{\"use gpu\";let f=__tsover_div(t,s),h=B(__tsover_mul(a,.5),.001),g=B(Ue(__tsover_add(__tsover_mul(r,r),__tsover_mul(o,o))),1e-4),y=__tsover_div(r,g),b=__tsover_div(o,g),x=G(__tsover_mul(__tsover_div(__tsover_mul(f,-1),h),32),0,1),P=B(__tsover_mul(i,.1),.001),C=G(__tsover_div(__tsover_mul(f,-1),P),0,1),E=__tsover_div(1,Ue(__tsover_add(__tsover_mul(g,g),1))),R=K(7,1.5,G(i,0,1)),U=__tsover_mul(vt(__tsover_sub(1,E),R),x),L=N(__tsover_mul(__tsover_mul(__tsover_sub(1,C),__tsover_sub(1,C)),x),U,_>.5),k=pe(__tsover_mul(u,L2)),D=ae(__tsover_mul(u,L2)),O=__tsover_add(__tsover_mul(y,k),__tsover_mul(b,D)),F=__tsover_sub(__tsover_mul(b,k),__tsover_mul(y,D)),q=__tsover_mul(p,AO),Y=__tsover_add(__tsover_mul(O,pe(q)),__tsover_mul(F,ae(q))),V=__tsover_mul(__tsover_mul(l,B(__tsover_mul(f,-1),0)),10),X=N(__tsover_mul(__tsover_mul(l,C),2),V,_>.5);return m(__tsover_add(__tsover_add(d,__tsover_mul(c,Y)),X),L)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"sdfRaw\"},{type:\"i\",name:\"scale\"},{type:\"i\",name:\"gradX\"},{type:\"i\",name:\"gradY\"},{type:\"i\",name:\"edgeSoftness\"},{type:\"i\",name:\"rimWidthUniform\"},{type:\"i\",name:\"thickness\"},{type:\"i\",name:\"dispersion\"},{type:\"i\",name:\"hueShift\"},{type:\"i\",name:\"lightAngle\"},{type:\"i\",name:\"animTime\"},{type:\"i\",name:\"volumetric\"}],body:[0,[[13,\"sdf\",[1,\"sdfRaw\",\"/\",\"scale\"]],[13,\"sharp\",[6,\"std.max\",[[1,\"edgeSoftness\",\"*\",[5,\"0.5\"]],[5,\"0.001\"]]]],[13,\"gLen\",[6,\"std.max\",[[6,\"std.sqrt\",[[1,[1,\"gradX\",\"*\",\"gradX\"],\"+\",[1,\"gradY\",\"*\",\"gradY\"]]]],[5,\"0.0001\"]]]],[13,\"nx\",[1,\"gradX\",\"/\",\"gLen\"]],[13,\"ny\",[1,\"gradY\",\"/\",\"gLen\"]],[13,\"rb1\",[6,\"std.clamp\",[[1,[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"sharp\"],\"*\",[5,\"32\"]],[5,\"0\"],[5,\"1\"]]]],[13,\"rimWidth\",[6,\"std.max\",[[1,\"rimWidthUniform\",\"*\",[5,\"0.1\"]],[5,\"0.001\"]]]],[13,\"depth\",[6,\"std.clamp\",[[1,[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],\"/\",\"rimWidth\"],[5,\"0\"],[5,\"1\"]]]],[13,\"cosView\",[1,[5,\"1\"],\"/\",[6,\"std.sqrt\",[[1,[1,\"gLen\",\"*\",\"gLen\"],\"+\",[5,\"1\"]]]]]],[13,\"exponent\",[6,\"std.mix\",[[5,\"7\"],[5,\"1.5\"],[6,\"std.clamp\",[\"rimWidthUniform\",[5,\"0\"],[5,\"1\"]]]]]],[13,\"volRim\",[1,[6,\"std.pow\",[[1,[5,\"1\"],\"-\",\"cosView\"],\"exponent\"]],\"*\",\"rb1\"]],[13,\"flatRim\",[1,[1,[1,[5,\"1\"],\"-\",\"depth\"],\"*\",[1,[5,\"1\"],\"-\",\"depth\"]],\"*\",\"rb1\"]],[13,\"rim\",[6,\"std.select\",[\"flatRim\",\"volRim\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"lx\",[6,\"std.cos\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"ly\",[6,\"std.sin\",[[1,\"lightAngle\",\"*\",\"DEG_TO_RAD\"]]]],[13,\"baseCos\",[1,[1,\"nx\",\"*\",\"lx\"],\"+\",[1,\"ny\",\"*\",\"ly\"]]],[13,\"baseSin\",[1,[1,\"ny\",\"*\",\"lx\"],\"-\",[1,\"nx\",\"*\",\"ly\"]]],[13,\"theta\",[1,\"animTime\",\"*\",\"TWO_PI\"]],[13,\"rotatedDot\",[1,[1,\"baseCos\",\"*\",[6,\"std.cos\",[\"theta\"]]],\"+\",[1,\"baseSin\",\"*\",[6,\"std.sin\",[\"theta\"]]]]],[13,\"thickVol\",[1,[1,\"thickness\",\"*\",[6,\"std.max\",[[1,\"sdf\",\"*\",[4,\"-\",[5,\"1\"]]],[5,\"0\"]]]],\"*\",[5,\"10\"]]],[13,\"thickFlat\",[1,[1,\"thickness\",\"*\",\"depth\"],\"*\",[5,\"2\"]]],[13,\"thicknessTerm\",[6,\"std.select\",[\"thickFlat\",\"thickVol\",[1,\"volumetric\",\">\",[5,\"0.5\"]]]]],[13,\"phase\",[1,[1,\"hueShift\",\"+\",[1,\"dispersion\",\"*\",\"rotatedDot\"]],\"+\",\"thicknessTerm\"]],[10,[6,\"d.vec2f\",[\"phase\",\"rim\"]]]]]},externals:{\"std.max\":()=>B,\"std.sqrt\":()=>Ue,\"std.clamp\":()=>G,\"std.mix\":()=>K,\"std.pow\":()=>vt,\"std.select\":()=>N,\"std.cos\":()=>pe,DEG_TO_RAD:()=>L2,\"std.sin\":()=>ae,TWO_PI:()=>AO,\"d.vec2f\":()=>m}})&&e.f)({})),TO=w.fn([n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return A_(t,0,.3333,.6667)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[10,[6,\"cosinePalette\",[\"phase\",[5,\"0\"],[5,\"0.3333\"],[5,\"0.6667\"]]]]]]},externals:{cosinePalette:()=>A_}})&&e.f)({})),SO=w.fn([n],A)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";let s=Re(t),r=__tsover_mul(s,3),o=Re(r),a=ie(r);return A(o,N(n(0),n(1),a<=1.5),N(n(0),n(1),a<=.5))}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"phase\"}],body:[0,[[13,\"t\",[6,\"std.fract\",[\"phase\"]]],[13,\"t3\",[1,\"t\",\"*\",[5,\"3\"]]],[13,\"si\",[6,\"std.fract\",[\"t3\"]]],[13,\"floorT3\",[6,\"std.floor\",[\"t3\"]]],[13,\"gate12\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"floorT3\",\"<=\",[5,\"1.5\"]]]]],[13,\"gate01\",[6,\"std.select\",[[6,\"d.f32\",[[5,\"0\"]]],[6,\"d.f32\",[[5,\"1\"]]],[1,\"floorT3\",\"<=\",[5,\"0.5\"]]]]],[10,[6,\"d.vec3f\",[\"si\",\"gate12\",\"gate01\"]]]]]},externals:{\"std.fract\":()=>Re,\"std.floor\":()=>ie,\"std.select\":()=>N,\"d.f32\":()=>n,\"d.vec3f\":()=>A}})&&e.f)({})),PO=w.fn([A,n,n,n],S)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s,r,o)=>{\"use gpu\";let a=K(A(1,1,1),t,o).mul(s).mul(r),i=G(s,0,1);return S(a.x,a.y,a.z,i)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"baseColor\"},{type:\"i\",name:\"rim\"},{type:\"i\",name:\"intensity\"},{type:\"i\",name:\"saturation\"}],body:[0,[[13,\"white\",[6,\"d.vec3f\",[[5,\"1\"],[5,\"1\"],[5,\"1\"]]]],[13,\"col\",[6,\"std.mix\",[\"white\",\"baseColor\",\"saturation\"]]],[13,\"rgb\",[6,[7,[6,[7,\"col\",\"mul\"],[\"rim\"]],\"mul\"],[\"intensity\"]]],[13,\"alpha\",[6,\"std.clamp\",[\"rim\",[5,\"0\"],[5,\"1\"]]]],[10,[6,\"d.vec4f\",[[7,\"rgb\",\"x\"],[7,\"rgb\",\"y\"],[7,\"rgb\",\"z\"],\"alpha\"]]]]]},externals:{\"d.vec3f\":()=>A,\"std.mix\":()=>K,\"std.clamp\":()=>G,\"d.vec4f\":()=>S}})&&e.f)({}));function Rde(e,t,s){let{uniforms:r,propValues:o,ctx:a}=e,i=s?.volumetric??!1,l=s?.gradSampler??t,c=$e(i?1:0),d=e.props.member(\"_animTime\"),u=W(xc,\"sdfSpaceUV\",[r.center,r.scale,r.rotation,a.uv,a.aspect]),p=t(u),_=p.member(\"r\"),f,h;if(s?.bakedGradients)f=p.member(\"g\"),h=p.member(\"b\");else{let P=l(W(da,\"offsetUV\",[u,$e(.01),$e(0)])),C=l(W(da,\"offsetUV\",[u,$e(0),$e(.01)])),E=W(Jh,\"glassGradient\",[_,P.member(\"r\"),C.member(\"r\")]);f=E.member(\"x\"),h=E.member(\"y\")}let g=W(wO,\"thinFilmShade\",[_,r.scale,f,h,r.edgeSoftness,r.rimWidth,r.thickness,r.dispersion,r.hueShift,r.lightAngle,d,c]),y=g.member(\"x\"),b=g.member(\"y\"),x;if(o.mode===\"custom\"){let P=No[typeof o.colorSpace==\"number\"?o.colorSpace:0]??Ar,C=W(SO,\"thinFilmCustomParams\",[y]),E=C.member(\"x\"),R=C.member(\"y\"),U=C.member(\"z\"),L=W(P,\"mixColors\",[r.colorA,r.colorB,E]),k=W(P,\"mixColors\",[r.colorB,r.colorC,E]);x=ea(ea(W(P,\"mixColors\",[r.colorC,r.colorA,E]),k,R),L,U).member(\"rgb\")}else x=W(TO,\"thinFilmRainbow\",[y]);return W(PO,\"thinFilmCompose\",[x,b,r.intensity,r.saturation])}var{applyThinFilmEffect:Dde}=zde,Lde=JSON.stringify({type:\"sphere3D\",radius:.35}),CO=H({name:\"ThinFilm\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Iridescent thin-film edge\",animatedTime:{speed:\"speed\"},...Ts({chord:\"firstLobe\",gradSampler:\"same\",bakedGradients:\"volumetric\",stencil:\"none\",surface:(e,t)=>Dde(t,e.sampler,{volumetric:e.volumetric,bakedGradients:e.bakedGradients})}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the shape (1 = default size)\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},intensity:{default:1,description:\"Rim brightness \\u2014 values above 1 push the edge past white for HDR bloom\",ui:{type:[\"range\",\"map\"],min:0,max:4,step:.01,label:\"Intensity\",group:\"Film\"}},rimWidth:{default:1,description:\"How far inward from the edge the iridescence reaches\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Rim Width\",group:\"Film\"}},edgeSoftness:{default:.3,description:\"Softness of the shape boundary\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Film\"}},thickness:{default:.5,description:\"Film thickness \\u2014 higher values pack more spectral bands across the rim\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Thickness\",group:\"Film\"}},dispersion:{default:.5,description:\"How strongly color separates around the perimeter (warm vs cool sides)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Dispersion\",group:\"Film\"}},saturation:{default:1,description:\"Spectral saturation \\u2014 0 = white rim, 1 = full iridescence\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Saturation\",group:\"Film\"}},hueShift:{default:0,description:\"Rotate the spectrum to reposition the colors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Hue Shift\",group:\"Film\"}},lightAngle:{default:300,description:\"Light angle in degrees \\u2014 sets which side of the rim runs warm vs cool\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Film\"}},mode:{default:\"rainbow\",compileTime:!0,description:\"Rainbow uses the full iridescent spectrum; Custom cycles through your three chosen colors\",ui:{type:\"select\",options:[{label:\"Rainbow\",value:\"rainbow\"},{label:\"Custom\",value:\"custom\"}],label:\"Mode\",group:\"Colors\"}},colorA:{default:\"#2b6fff\",transform:ce,description:\"First color in the rim cycle\",ui:{type:\"color\",label:\"Color 1\",group:\"Colors\",condition:{mode:\"custom\"}}},colorB:{default:\"#ffffff\",transform:ce,description:\"Second color in the rim cycle\",ui:{type:\"color\",label:\"Color 2\",group:\"Colors\",condition:{mode:\"custom\"}}},colorC:{default:\"#ff7a21\",transform:ce,description:\"Third color in the rim cycle\",ui:{type:\"color\",label:\"Color 3\",group:\"Colors\",condition:{mode:\"custom\"}}},colorSpace:{default:\"oklch\",transform:at,compileTime:!0,description:\"color space used to blend between custom colors\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\",condition:{mode:\"custom\"}}},speed:{default:.1,description:\"Speed at which the colors rotate around the rim (0 = static)\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Speed\",group:\"Animation\"}},shape:{default:Lde,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file \\u2014 when non-empty, activates SVG mode and triggers a shader recompile\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type \\u2014 triggers recompile when shape is switched. When empty, derived from shape JSON at mount time.\"}}});var MO=H({name:\"AngularBlur\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Radial motion blur rotating around a center point\",props:{intensity:{default:20,description:\"Intensity of the angular blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Blur Intensity\",group:\"Effect\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the rotation\",ui:{type:\"position\",label:\"Center Position\",group:\"Position\"}},dispersion:{default:0,description:\"Spectral color fringing along the streak, like light through a lens; negative flips which end is red\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Dispersion\",group:\"Lens\"}},falloff:{default:0,description:\"Concentrates the dispersion away from the center; 0 fringes everywhere equally\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Lens\"}},focus:{default:0,description:\"Radius of a clean zone around the center that stays sharp\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Focus\",group:\"Lens\"}},bias:{default:0,description:\"Trails the sweep off one side of each pixel instead of both; the sign picks the direction\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Bias\",group:\"Streak\"}},highlights:{default:0,description:\"Lets bright pixels streak further than dark ones, like light rays\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlights\",group:\"Streak\"}},jitter:{default:0,description:\"Per-pixel noise on the tap spacing that hides banding in long streaks\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Jitter\",group:\"Streak\"}}},effect:Tp({path:wp.orbit(T(\"center\")),amount:T(\"intensity\"),detail:{dispersion:T(\"dispersion\"),falloff:T(\"falloff\"),focus:T(\"focus\"),bias:T(\"bias\"),highlights:T(\"highlights\"),jitter:T(\"jitter\")}})});var EO=H({role:\"shape\",name:\"Arc\",description:\"Pie sector (arc wedge) with adjustable radius and aperture angle\",shape:{distance:({x:e,y:t},s)=>yR(e,t,s(\"radius\"),v(s(\"aperture\"),bR)),colorDescription:\"Fill color of the arc\",centerDescription:\"Center position of the arc\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.38,description:\"Radius of the pie sector\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Size\",group:\"Shape\"}},aperture:{default:270,description:\"Aperture angle of the wedge in degrees (360 = full circle)\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Aperture\",group:\"Shape\"}}}}});var kc=2048,kO={\"JetBrains Mono\":\"JetBrains+Mono\",\"Fira Code\":\"Fira+Code\",\"Source Code Pro\":\"Source+Code+Pro\",\"IBM Plex Mono\":\"IBM+Plex+Mono\",\"Space Mono\":\"Space+Mono\",\"Roboto Mono\":\"Roboto+Mono\",\"Courier Prime\":\"Courier+Prime\",\"Geist Mono\":\"Geist+Mono\",VT323:\"VT323\",\"Press Start 2P\":\"Press+Start+2P\",Silkscreen:\"Silkscreen\",\"Major Mono Display\":\"Major+Mono+Display\",\"Syne Mono\":\"Syne+Mono\",\"Nova Mono\":\"Nova+Mono\",\"Xanh Mono\":\"Xanh+Mono\",\"Cutive Mono\":\"Cutive+Mono\",\"Share Tech Mono\":\"Share+Tech+Mono\",\"Martian Mono\":\"Martian+Mono\",\"Azeret Mono\":\"Azeret+Mono\"},BO=new Set;async function Ude(e){if(BO.has(e)||!kO[e])return;let t=kO[e];if(!document.querySelector(`link[href*=\"${t}\"]`)){let s=document.createElement(\"link\");s.rel=\"stylesheet\",s.href=`https://fonts.googleapis.com/css2?family=${t}:wght@400&display=swap`,document.head.appendChild(s)}try{if(document.fonts&&document.fonts.load){for(let s of[`400 12px \"${e}\"`,`12px \"${e}\"`,`400 12px ${e}`,`12px ${e}`])try{await document.fonts.load(s);break}catch{}await new Promise(s=>setTimeout(s,500))}else await new Promise(s=>setTimeout(s,1e3));BO.add(e)}catch{}}var Ode=(e,t)=>typeof e==\"number\"?e:t,Gde=e=>{let{getCpuValue:t,setExtraField:s}=e,r=gc(e,{label:\"Ascii:atlas\",initial:{width:kc,height:kc}}),o=w_(e,{contextAttributes:{willReadFrequently:!0}}),a=(d,u,p)=>{if(r.disposed||!d||d.length===0)return;let _=d.length,f=Math.max(2,Math.ceil(Math.sqrt(_))),h=128,g=Math.max(1,2/u),y=Math.min(h*g,kc/f),b=y*.75,x=o.canvas()?o.context():o.resize(kc,kc);if(!x)return;x.clearRect(0,0,kc,kc),x.fillStyle=\"#ffffff\",x.font=`${b}px \"${p}\", ${p}, monospace`,!x.font.includes(p)&&!x.font.includes(\"IBM\")&&!x.font.includes(\"Plex\")&&(x.font=`${b}px ${p}, monospace`),x.textAlign=\"center\",x.textBaseline=\"middle\";for(let C=0;C<_;C++){let E=Math.floor(C/f),R=C%f;x.fillText(d[C],R*y+y/2,E*y+y/2)}r.write(o.canvas());let P=f*y/kc;s(\"_charCount\",_),s(\"_atlasScale\",P),s(\"_atlasSize\",f)},i=()=>({characters:String(t(\"characters\")??Vg.props.characters.default),fontFamily:String(t(\"fontFamily\")??Vg.props.fontFamily.default),spacing:Ode(t(\"spacing\"),1.5)}),l=()=>{let d=i();a(d.characters,d.spacing,d.fontFamily)},c=S_({key:()=>i().fontFamily,load:()=>Ude(i().fontFamily),onLoaded:l});return setTimeout(()=>{l(),c.ensure()},0),T_(e,{key:()=>{let d=i();return`${d.characters}|${d.fontFamily}|${d.spacing}`},run:()=>{l(),c.ensure()}}),r.kit},U2=H8({cellSize:T(\"cellSize\"),spacing:T(\"spacing\")}),zO=j8({grid:U2}),Vg=H({name:\"Ascii\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Convert imagery to ASCII character art\",requiresRTT:!0,requiresChild:!0,extraFields:{_charCount:{schema:n,initial:9},_atlasScale:{schema:n,initial:1},_atlasSize:{schema:n,initial:3}},props:{characters:{default:\"@%#*+=-:.\",description:\"Characters ordered from dense to sparse. First character is used for bright areas, last for dark areas.\",ui:{type:\"text\",label:\"Characters\",group:\"Effect\"}},cellSize:{default:30,description:\"Size of each ASCII character cell (normalized to 1080p reference, scales proportionally at other resolutions)\",ui:{type:\"range\",min:8,max:100,step:1,label:\"Cell Size\",group:\"Effect\"}},fontFamily:{default:\"JetBrains Mono\",description:\"Font family for characters\",ui:{type:\"select\",options:[{label:\"Azeret Mono\",value:\"Azeret Mono\"},{label:\"Courier Prime\",value:\"Courier Prime\"},{label:\"Cutive Mono\",value:\"Cutive Mono\"},{label:\"Fira Code\",value:\"Fira Code\"},{label:\"Geist Mono\",value:\"Geist Mono\"},{label:\"IBM Plex Mono\",value:\"IBM Plex Mono\"},{label:\"JetBrains Mono\",value:\"JetBrains Mono\"},{label:\"Major Mono Display\",value:\"Major Mono Display\"},{label:\"Martian Mono\",value:\"Martian Mono\"},{label:\"Nova Mono\",value:\"Nova Mono\"},{label:\"Press Start 2P\",value:\"Press Start 2P\"},{label:\"Roboto Mono\",value:\"Roboto Mono\"},{label:\"Share Tech Mono\",value:\"Share Tech Mono\"},{label:\"Silkscreen\",value:\"Silkscreen\"},{label:\"Source Code Pro\",value:\"Source Code Pro\"},{label:\"Space Mono\",value:\"Space Mono\"},{label:\"Syne Mono\",value:\"Syne Mono\"},{label:\"VT323\",value:\"VT323\"},{label:\"Xanh Mono\",value:\"Xanh Mono\"}],label:\"Font Family\",group:\"Font\"}},spacing:{default:1,description:\"Character size within each cell (1.0 = optimal size, 0.0 = smallest)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Character Size\",group:\"Effect\"},transform:e=>.1+e*1.4},gamma:{default:1,description:\"Brightness curve adjustment. <1 brightens darks (more light characters), >1 darkens midtones (more dark characters). Use to better fit characters to image brightness range.\",ui:{type:[\"range\",\"map\"],min:.25,max:3,step:.01,label:\"Gamma\",group:\"Effect\"}},alphaThreshold:{default:0,description:\"Pixels with alpha below this threshold become fully transparent.\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Alpha Threshold\",group:\"Effect\"}},preserveAlpha:{default:!0,description:\"When enabled, output alpha matches input alpha. When disabled, pixels above the alpha threshold become fully opaque.\",ui:{type:\"checkbox\",label:\"Preserve Alpha\",group:\"Effect\"},transform:rs}},gpu:{fragment:Q8({grid:U2,cell:zO,glyph:K8({grid:U2,cell:zO,gamma:T(\"gamma\"),atlas:Gde}),alphaThreshold:T(\"alphaThreshold\"),preserveAlpha:T(\"preserveAlpha\")})}});var Fde=[{freq:.7,speed:.4,amount:.15,salt:{k:12.9,big:4758.5}},{freq:1.6,speed:.65,amount:.08,salt:{k:78.2,big:2847.1}},{freq:2.9,speed:.3,amount:.04,salt:{k:41.6,big:1593.7}}],Ide={k:53.7,big:3847.2},Yde=[{timeOffset:0,weight:1},{timeOffset:3.1,weight:.65},{timeOffset:6.7,weight:.45},{timeOffset:9.4,weight:.3}],RO=H({name:\"Aurora\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Mesmerizing aurora borealis with layered curtains, vertical rays, and flowing light.\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#a533f8\",transform:ce,description:\"Edge color at the curtain base\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#22ee88\",transform:ce,description:\"Core color in the bright center\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},colorC:{default:\"#1694e8\",transform:ce,description:\"Tip color at the ray ends\",ui:{type:\"color\",label:\"Color C\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},balance:{default:50,description:\"Shifts color distribution across the curtain height\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Balance\",group:\"Colors\"}},intensity:{default:80,description:\"Overall aurora brightness\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Aurora\"}},curtainCount:{default:4,compileTime:!0,description:\"Number of aurora curtain layers\",ui:{type:\"range\",min:1,max:4,step:1,label:\"Curtains\",group:\"Aurora\"}},speed:{default:5,description:\"Animation speed\",ui:{type:\"range\",min:-10,max:10,step:.1,label:\"Speed\",group:\"Aurora\"}},waviness:{default:50,description:\"How much the curtains undulate\",ui:{type:[\"range\",\"map\"],min:0,max:200,step:1,label:\"Waviness\",group:\"Aurora\"}},rayDensity:{default:20,description:\"Density of vertical ray structures\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Ray Detail\",group:\"Aurora\"}},height:{default:120,description:\"How tall the aurora extends\",ui:{type:[\"range\",\"map\"],min:10,max:200,step:1,label:\"Height\",group:\"Scene\"}},center:{default:{x:.5,y:0},transform:Xe,description:\"Center position of the aurora\",ui:{type:\"position\",label:\"Center\",group:\"Scene\"}},seed:{default:0,description:\"Random seed for variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Aurora\"}}},paint:e=>{let{uv:t,viewport:s}=aa(e),r=z(Ce(s.member(\"x\"),it(s.member(\"y\"),1e-6)),\"aspect\"),o=z(wt(e),\"auroraTime\"),a=me(T(\"seed\"),e),i=me(T(\"center\"),e),l=i.member(\"x\"),c=ne(1,i.member(\"y\")),d=v(me(T(\"waviness\"),e),.01),u=v(me(T(\"rayDensity\"),e),.01),p=v(me(T(\"height\"),e),.01),_=v(me(T(\"intensity\"),e),.018),f=et(2.5,.4,v(me(T(\"balance\"),e),.01)),h=(R,U)=>{let L=z(I(v(o,.06),U),\"tSlow\"),k=z(I(a,Math.fround(R*Math.fround(31.7))),\"lSeed\"),D=z(v(v(ne(t.member(\"x\"),l),r),2),\"wx\"),O=l2({along:D,time:L,waves:Fde.map(Te=>({...Te,phase:s2(k,Te.salt)}))}),F=z(Jn(Qe(v(D,.5),v(L,.25),v(k,.1))),\"curtainNoise\"),q=I(I(c,v(O,d)),v(v(F,.14),d)),Y=z(dD({along:I(D,v(F,2.5)),frequency:v(et(6,20,u),.15),time:L,speed:.1,phase:s2(k,Ide),sharpness:1.5}),\"curtainRays\"),V=v(p,et(.4,1,Y)),X=z(ne(t.member(\"y\"),q),\"distFromPath\"),Q=z(v(V,I(v(Y,.4),.6)),\"topExtent\"),te=Zz({distance:X,below:{from:-.04,to:.015},above:{to:Q}}),J=z(Ge(Ce(X,I(Q,.001)),0,1),\"colorT\"),oe=et(.4,1,I(v(F,.5),.5)),le=ne(J,.2),se=I(v(tr(v(v(le,le),-6)),.3),1);return{colorT:J,alpha:z(v(v(v(te,Y),oe),se),\"curtainAlpha\")}},g=Math.max(1,Math.min(4,Math.round(e.propValues.curtainCount??4))),{weightedSum:y,totalWeight:b}=ML(Yde.slice(0,g),({timeOffset:R,weight:U},L)=>{let{colorT:k,alpha:D}=h(L,R);return{value:k,weight:U===1?D:v(D,U)}}),x=z(b,\"auroraAlpha\"),P=z(ts(Ce(y,I(x,.001)),f),\"auroraAvgT\"),C=pg({a:T(\"colorA\"),b:T(\"colorB\"),c:T(\"colorC\"),space:T(\"colorSpace\")})(ot(0,.2,P),ot(.4,.85,P),e),E=z(v(x,_),\"auroraGlow\");return Ot(Ge(v(C.member(\"rgb\"),E),kt(0),kt(1)),Ge(v(E,.5),0,1))}});var DO=H({name:\"BarnDoors\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Split the content along a center line and wipe outward in both directions\",props:{progress:{default:.5,description:\"How far the doors have opened (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},angle:{default:0,description:\"Direction the doors open in degrees (0 = apart horizontally)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Transition\"}},feather:{default:.1,description:\"Softness of the wipe edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Close in from both edges instead of opening from the center\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.directional(T(\"angle\")).folded(),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Barn Doors shader.\"});var LO=H({name:\"BarShift\",role:\"warp\",category:\"Distortions\",description:\"Slices content into parallel bars, each offset independently for a fractured or glitch-like effect\",boundingBoxDeclaration:{aspectRatio:null},animatedTime:{speed:\"speed\"},props:{count:{default:6,description:\"Number of bars across the longest viewport dimension\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Count\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Angle of bar orientation in degrees (0 = vertical bars, 90 = horizontal bars)\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Angle\",group:\"Effect\"}},intensity:{default:.15,description:\"Maximum displacement per bar\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}},seed:{default:0,description:\"Randomization seed for per-bar offset variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},speed:{default:0,description:\"Animation speed \\u2014 each bar drifts at its own rate and direction\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},edges:fr(\"mirror\",\"How to handle edges when distortion pushes content out of bounds\")},map:aU({count:T(\"count\"),angle:T(\"angle\"),intensity:T(\"intensity\"),seed:T(\"seed\")}),missingChildMessage:\"You must pass a child component into the BarShift shader.\"});var UO=H({name:\"Beam\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"A beam of light from one point to another.\",acceptsUVContext:!0,extraFields:YR,props:{startPosition:{default:{x:.2,y:.5},transform:Xe,description:\"Starting point of the beam\",ui:{type:\"position\",label:\"Start Position\",group:\"Position\"}},endPosition:{default:{x:.8,y:.5},transform:Xe,description:\"Ending point of the beam\",ui:{type:\"position\",label:\"End Position\",group:\"Position\"}},startThickness:{default:.2,description:\"Thickness at the start of the beam\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Start Thickness\",group:\"Effect\"}},endThickness:{default:.2,description:\"Thickness at the end of the beam\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"End Thickness\",group:\"Effect\"}},startSoftness:{default:.5,description:\"Edge softness at the start of the beam\",ui:{type:[\"range\",\"map\"],min:0,max:50,step:.1,label:\"Start Softness\",group:\"Effect\"}},endSoftness:{default:.5,description:\"Edge softness at the end of the beam\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"End Softness\",group:\"Effect\"}},insideColor:{default:\"#FF0000\",transform:ce,description:\"Color at the center of the beam\",ui:{type:\"color\",label:\"Inside Color\",group:\"Colors\"}},outsideColor:{default:\"#0000FF\",transform:ce,description:\"Color at the edges of the beam\",ui:{type:\"color\",label:\"Outside Color\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:WR({from:T(\"startPosition\"),to:T(\"endPosition\"),thickness:{start:T(\"startThickness\"),end:T(\"endThickness\")},softness:{start:T(\"startSoftness\"),end:T(\"endSoftness\")},colors:{inside:T(\"insideColor\"),outside:T(\"outsideColor\")},space:T(\"colorSpace\")})});var OO=H({name:\"Bend\",role:\"warp\",category:\"Distortions\",description:\"Bends the ends of the frame toward you like a curved display \\u2014 content at the edges swells closer under real perspective, or curls away when the strength goes negative\",boundingBoxDeclaration:{aspectRatio:null},props:{strength:{default:.5,description:\"How hard the ends bend \\u2014 positive curls them toward you (edges magnify), negative curls them away (edges recede into the frame)\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},falloff:{default:0,description:\"Concentrates the bend toward the ends \\u2014 0 curves the whole frame, higher keeps the middle flat and bends only near the edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Effect\"}},angle:{default:0,description:\"Direction of the bend axis in degrees \\u2014 0 bends the left/right ends, 90 bends the top/bottom\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},edges:fr(\"transparent\",\"How to handle edges when the bend pulls content away from the frame border\")},map:$L({strength:T(\"strength\"),falloff:T(\"falloff\"),angle:T(\"angle\")}),missingChildMessage:\"You must pass a child component into the Bend shader.\"});var Wde=[{amount:.15,schedule:[{waves:[{x:3.2,t:.8},{y:2.8,t:.6}]},{waves:[{x:4.8,y:-3.6,t:-.4}]}]},{amount:.12,schedule:[{waves:[{x:5.6,t:-.5},{y:4.4,t:.7}]}]},{amount:.1,schedule:[{waves:[{x:7.2,y:6.4,t:.3}]},{waves:[{x:2.4,t:-.9}]}]},{amount:.04,schedule:[{waves:[{x:8.8,t:.2},{y:7.6,t:-.8}]}]}],qde=[{waves:[{x:1,t:.4},{y:1,t:.3}]},{waves:[{x:.7,y:.8,t:.2}]}],Vde=[{waves:[{x:1.3,t:-.5},{y:1.1,t:.6}]},{waves:[{x:.5,y:-.6,t:.3}]}],GO=H({name:\"Blob\",role:\"generator\",category:\"Textures\",description:\"Organic animated blob with 3D lighting and gradients\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},extraFields:{normLx:{schema:n,initial:0},normLy:{schema:n,initial:0},normLz:{schema:n,initial:1}},boundingBoxDeclaration:{propBindings:{x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"}},computeBounds(e,t,s){let r=e.size??.5,o=typeof e.center?.x==\"number\"?e.center.x:.5,a=typeof e.center?.y==\"number\"?e.center.y:.5,i=r*2*s;return{centerXPx:o*t,centerYPx:a*s,widthPx:i,heightPx:i,rotationDeg:0}},writeBounds(e,t,s,r){let o=Math.max(0,e.widthPx/(2*r));return{center:{...t.center??{x:.5,y:.5},x:e.centerXPx/s,y:e.centerYPx/r},size:o}},softnessBinding:{prop:\"softness\",toPx:(e,t,s)=>e*.3*s,fromPx:(e,t,s)=>Math.max(0,Math.min(1,e/(.3*s)))}},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},colorA:{default:\"#ff6b35\",transform:ce,description:\"Primary color of the blob\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#e91e63\",transform:ce,description:\"Secondary color of the blob\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),size:{default:.5,description:\"Size of the blob\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Size\",group:\"Effect\"}},deformation:{default:.5,description:\"How organic and blobby the shape is (0 = circle, 1 = very blobby)\",ui:{type:\"range\",min:0,max:1,step:.1,label:\"Deformation\",group:\"Effect\"}},softness:{default:.5,description:\"Softness of the blob edges (combines edge width and transition curve)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Softness\",group:\"Effect\"}},highlightIntensity:{default:.5,description:\"Intensity of specular highlight effect\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Highlight Intensity\",group:\"Highlight\"}},highlightX:{default:.3,description:\"Light direction X component\",ui:{type:\"range\",min:-1,max:1,step:.1,label:\"Highlight X\",group:\"Highlight\"}},highlightY:{default:-.3,description:\"Light direction Y component\",ui:{type:\"range\",min:-1,max:1,step:.1,label:\"Highlight Y\",group:\"Highlight\"}},highlightZ:{default:.4,description:\"Light direction Z component\",ui:{type:\"range\",min:-1,max:1,step:.1,label:\"Highlight Z\",group:\"Highlight\"}},highlightColor:{default:\"#ffe11a\",transform:ce,description:\"Color of the specular highlight\",ui:{type:\"color\",label:\"Highlight Color\",group:\"Highlight\"}},speed:{default:.5,description:\"Animation speed\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:1,description:\"Adjusts the starting state, useful for variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the blob\",ui:{type:\"position\",label:\"Center Position\",group:\"Position\",units:[\"%\",\"px\"]}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:e=>{let{uniforms:t}=e,s=b=>fn(b,e);aR(e,{x:\"highlightX\",y:\"highlightY\",z:\"highlightZ\"},{x:\"normLx\",y:\"normLy\",z:\"normLz\"});let r=z(wt(e,\"seed\"),\"blobTime\"),{delta:o,dist:a}=qL({center:T(\"center\")})(e,WL(e)),i={x:o.member(\"x\"),y:o.member(\"y\"),t:r},l=s(T(\"deformation\")),c=z(I(s(T(\"size\")),Wde.map(({schedule:b,amount:x})=>v(v(vp(i,b),x),l)).reduce((b,x)=>I(b,x))),\"blobRadius\"),d=z(s(T(\"softness\")),\"blobSoftness\"),u=z(Jz({dist:a,radius:c,softness:{width:v(d,.3),curve:I(v(d,2),.5)}}),\"blobMask\"),p=v(v(v(pD({normal:uD({delta:o,dist:a,radius:c}),light:Qe(t.normLx,t.normLy,t.normLz),gloss:32}),I(v(ot(0,c,a),.5),.5)),s(T(\"highlightIntensity\"))),u),_={x:v(i.x,3),y:v(i.y,3),t:r},f=b=>I(v(vp(_,b),.5),.5),h=Us(T(\"colorSpace\"))(ot(.1,.9,I(v(f(qde),.6),v(f(Vde),.4))),e),g=me(T(\"highlightColor\"),e),y=v(I(t.colorA.member(\"a\"),t.colorB.member(\"a\")),.5);return Ot(I(h.member(\"rgb\"),v(g.member(\"rgb\"),p)),v(y,u))}});var FO=H({name:\"BlockDissolve\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Dissolve the content away as a grid of blocks vanishing in random order\",props:{progress:{default:.5,description:\"How far the dissolve has progressed (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},blockSize:{default:.08,description:\"Size of each block as a fraction of the frame width\",ui:{type:[\"range\",\"map\"],min:.01,max:.5,step:.01,label:\"Block Size\",group:\"Transition\"}},softness:{default:.15,description:\"How softly each block fades out (0 = hard-edged blocks)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse the order blocks dissolve in\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.cells(T(\"blockSize\")).shuffled(),progress:T(\"progress\"),feather:T(\"softness\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Block Dissolve shader.\"});function ma(){return{colorA:{default:\"#ffffff\",description:\"First color\",transform:ce,ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#000000\",description:\"Second color\",transform:ce,ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}}}function IO(){return{colorA:{default:\"#ffffff\",description:\"First color\",transform:ce,ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#000000\",description:\"Second color\",transform:ce,ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}}}}function Ja(){return{contrast:{default:0,description:\"Pattern contrast (higher = sharper transitions)\",ui:{type:[\"range\",\"map\"],min:-1,max:5,step:.1,label:\"Contrast\",group:\"Effect\"}},balance:{default:0,description:\"Balance between colors (negative = more colorB, positive = more colorA)\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.05,label:\"Balance\",group:\"Effect\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}}}}function In(e=1){return{speed:{default:e,description:\"Animation speed\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}}}}var YO=H({name:\"BlockNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Blocky value noise with soft cells that morph over time\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:2,description:\"Pattern scale (higher = larger patterns)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},...Ja(),...In()},paint:Vs(ua(Qa(hp(Tc(\"value\"),{rate:.3}),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var WO=H({name:\"BlueNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"High-frequency blue noise \\u2014 even, grainy speckle ideal for dithering\",acceptsUVContext:!0,props:{...ma(),grain:{default:1,description:\"Grain size in pixels (1 = per-pixel, higher = chunkier speckle)\",ui:{type:\"range\",min:1,max:32,step:1,label:\"Grain Size\",group:\"Effect\"}},...Ja()},paint:Vs(ua(qD($D(),{grain:T(\"grain\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var qO=H({name:\"Blur\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"A simple Gaussian blur effect\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:50,description:\"Intensity of the blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:200,step:1,label:\"Intensity\",group:\"Effect\"}}},...kU({intensity:T(\"intensity\")})});var H_=4096,Nde=1200,Cl=vn({desktop:1024,mobile:640}),VO=\"rgba16float\",$de=16,Xde=.13,Hde=3.5,jde=1.5,Kde=.4545,Qde=1.3,NO=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({colA:S,colB:S,count:n,trails:n,dt:n,aspect:n,domainX:n,maxSpeed:n,maxForce:n,perceptionSq:n,sepRadiusSq:n,sepW:n,aliW:n,cohW:n,cursorX:n,cursorY:n,cursorMode:n,cursorRadius:n,cursorRadiusSq:n,cursorForce:n,bodyR:n,margin:n,turnForce:n,seed:n}),\"SimParams\"),Gd=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({agents:{storage:Fe(S,H_),access:\"mutable\"},agit:{storage:Fe(n,H_),access:\"mutable\"},accumE:{storage:Fe(lo(M),Cl*Cl),access:\"mutable\"},accumS:{storage:Fe(lo(M),Cl*Cl),access:\"mutable\"},trailBuf:{storage:Fe(S,Cl*Cl),access:\"mutable\"},params:{uniform:NO},outTex:{storageTexture:zt(VO,\"write-only\")}}),\"simLayout\"),Zde=pz(Gd,\"boidsInit\"),Jde=On.steering2d(Gd,{forces:[Za.flocking(Gd,{maxAgents:H_}),Za.cursorSteer(Gd),Za.wallTurn(Gd)],agitation:{rest:jde,gain:Kde,cool:Qde},cruiseFloor:.35,wallRestitution:.6,name:\"boidsUpdate\"});function O2(e,t){return Gn.orientedWorld(Gd,{shape:e,res:Cl,splatRCap:$de,heading:\"velocity\",agitation:\"buffer\",comet:!0,ramp:{colorSpace:t,trails:\"on\"},names:{splat:\"boidsSplat\",resolve:\"boidsResolve\"}})}var eue=e=>O2(e,2).splat.kernel,tue=e=>O2(\"arrow\",e).resolve.kernel,o0e=eue(\"arrow\"),a0e=tue(2),$O=H({name:\"Boids\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"A living murmuration of hundreds of flocking agents drawn as crisp arrows, streaks, dots or glowing comets \\u2014 separation, alignment and cohesion drive fluid, splitting-and-merging ribbons, agents flash toward an excited color when scattered, and the cursor acts as an attractor or a predator\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{colorA:{default:\"#8ec5ff\",transform:ce,description:\"Color of agents cruising calmly with the flock\",ui:{type:\"color\",label:\"Rest Color\",group:\"Colors\"}},colorB:{default:\"#ff7ad9\",transform:ce,description:\"Color agents flash toward when agitated \\u2014 scattering from the predator cursor or banking through a hard turn\",ui:{type:\"color\",label:\"Excited Color\",group:\"Colors\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the rest\\u2192excited color ramp\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},agentShape:{default:\"arrow\",compileTime:!0,description:\"What each agent is drawn as \\u2014 a hard-edged arrow, streak or square pointing along its heading, a plain dot, or a soft glowing comet\",ui:{type:\"select\",options:lp,label:\"Shape\",group:\"Flock\"}},count:{default:2e3,description:\"Number of flocking agents\",ui:{type:\"range\",min:100,max:4e3,step:100,label:\"Count\",group:\"Flock\"}},speed:{default:2,description:\"Overall cruising speed of the flock\",ui:{type:\"range\",min:.2,max:5,step:.1,label:\"Speed\",group:\"Flock\"}},seed:{default:0,description:\"Re-rolls the flock's starting formation \\u2014 each value spawns the murmuration in a different arrangement\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Flock\"}},size:{default:1.5,description:\"Size of each agent\",ui:{type:\"range\",min:.5,max:3,step:.05,label:\"Size\",group:\"Flock\"}},trails:{default:0,description:\"How long each agent's motion trail persists \\u2014 0 draws crisp agents, 1 leaves long ribbons\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Trails\",group:\"Flock\"}},separation:{default:1.7,description:\"How strongly agents steer away from crowding their neighbours\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Separation\",group:\"Flocking\"}},alignment:{default:1.5,description:\"How strongly agents match their neighbours' heading \\u2014 the driver of coherent murmuration ribbons\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Alignment\",group:\"Flocking\"}},cohesion:{default:1,description:\"How strongly agents steer toward the local center of the flock\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Cohesion\",group:\"Flocking\"}},perception:{default:.12,description:\"How far each agent can sense its neighbours (in screen heights) \\u2014 larger sees bigger, smoother flocks\",ui:{type:\"range\",min:.05,max:.35,step:.01,label:\"Perception\",group:\"Flocking\"}},cursorMode:{default:\"repel\",description:\"How the flock reacts to the cursor\",ui:{type:\"select\",options:[{label:\"None\",value:\"none\"},{label:\"Attract\",value:\"attract\"},{label:\"Predator\",value:\"repel\"}],label:\"Cursor\",group:\"Interaction\"}},cursorStrength:{default:1.5,description:\"Strength of the cursor's pull or push on the flock\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Cursor Strength\",group:\"Interaction\"}}},...Fn({layout:Gd,params:NO,maxAgents:H_,countCap:{desktop:H_,mobile:Nde},output:{key:\"outTex\",name:\"boidsTexture\",size:[Cl,Cl],format:VO},bake:({getCpuValue:e})=>{let t=O2(e(\"agentShape\")||\"arrow\",e(\"colorSpace\")??2);return{pipelines:{init:{kernel:Zde,threads:\"max\"},update:{kernel:Jde,threads:\"agents\"},splat:t.splat,resolve:t.resolve},initStep:\"init\",program:[\"update\",\"splat\",\"resolve\"]}},frame:(e,{getCpuValue:t})=>{let s=Li(t);return r=>{let{dt:o,aspect:a,pointerX:i,pointerY:l}=Di(r),c=Math.max(a,.01),d=e.resolveCount(s(\"count\",2e3)),u=s(\"seed\",0),p=Xde*s(\"speed\",2),_=p*Hde,f=s(\"perception\",.12),h=t(\"cursorMode\")??\"repel\",g=h===\"attract\"?1:h===\"repel\"?2:0,y=i*a,b=l,x=.22,P=t(\"colorA\"),C=t(\"colorB\"),E=Math.min(Math.max(s(\"size\",1.5),.5),3)*2/Ri;return e.writeParams({colA:S(P?.x??.56,P?.y??.77,P?.z??1,P?.w??1),colB:S(C?.x??1,C?.y??.48,C?.z??.85,C?.w??1),count:d,trails:Math.min(Math.max(s(\"trails\",.35),0),1)*.92,dt:o,aspect:a,domainX:c,maxSpeed:p,maxForce:_,perceptionSq:f*f,sepRadiusSq:f*.5*(f*.5),sepW:s(\"separation\",1.7),aliW:s(\"alignment\",1.5),cohW:s(\"cohesion\",1),cursorX:y,cursorY:b,cursorMode:g,cursorRadius:x,cursorRadiusSq:x*x,cursorForce:s(\"cursorStrength\",1.5)*p*12,bodyR:E,margin:.07,turnForce:p*2.2,seed:u}),e.frame({count:d,reseed:u})}},fragment:{output:\"boidsTexture\",fallback:\"transparent\"}})});var XO=H({name:\"BokehBlur\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Photographic lens blur where bright highlights bloom into aperture-shaped discs\",requiresRTT:!0,requiresChild:!0,props:{radius:{default:50,description:\"Defocus amount \\u2014 how far the lens blur spreads\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Radius\",group:\"Effect\"}},highlightGain:{default:4,description:\"How strongly bright highlights bloom into discs\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Highlight Bloom\",group:\"Highlights\"}},highlightThreshold:{default:.6,description:\"Brightness above which a highlight forms a disc\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlight Threshold\",group:\"Highlights\"}},bladeShape:{default:\"blades\",description:\"Aperture shape the highlights bloom into \\u2014 bladed iris or a novelty cut-out (heart, star, \\u2026)\",ui:{type:\"select\",options:[{label:\"Blades\",value:\"blades\"},{label:\"Circle\",value:\"circle\"},{label:\"Star\",value:\"star\"},{label:\"Heart\",value:\"heart\"},{label:\"Flower\",value:\"flower\"},{label:\"Cross\",value:\"cross\"},{label:\"Ring\",value:\"ring\"}],label:\"Blade Shape\",group:\"Aperture\"}},bladeCount:{default:6,description:\"Blade or point count for the Blades, Star and Flower shapes \\u2014 0\\u20132 blades is a circular iris\",ui:{type:\"range\",min:0,max:9,step:1,label:\"Aperture Blades\",group:\"Aperture\"}},bladeRotation:{default:0,transform:cs,description:\"Rotation of the aperture shape (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Blade Rotation\",group:\"Aperture\"}},chromaticFringe:{default:.2,description:\"Lens color fringing on the disc edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Chromatic Fringe\",group:\"Aperture\"}},catEye:{default:0,description:\"Clips the discs into cat-eye shapes toward the frame corners, like a real lens vignetting its aperture\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Cat Eye\",group:\"Aperture\"}}},...e8({radius:T(\"radius\"),gain:T(\"highlightGain\"),threshold:T(\"highlightThreshold\"),shape:T(\"bladeShape\"),blades:T(\"bladeCount\"),rotation:T(\"bladeRotation\"),fringe:T(\"chromaticFringe\"),catEye:T(\"catEye\")})});var HO=eD({cellsX:T(\"cellsX\"),cellsY:T(\"cellsY\"),mortar:T(\"mortar\"),softness:T(\"softness\"),variation:T(\"variation\"),rotation:T(\"rotation\"),offset:T(\"offset\"),speedVariance:T(\"speedVariance\"),seed:T(\"seed\")}),jO=H({name:\"BrickPattern\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Classic brick wall pattern with alternating rows and mortar gaps\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorBrick:{default:\"#000000\",transform:ce,description:\"Brick color\",ui:{type:\"color\",label:\"Brick Color\",group:\"Colors\"}},colorMortar:{default:\"#ffffff\",transform:ce,description:\"Mortar / gap color\",ui:{type:\"color\",label:\"Mortar Color\",group:\"Colors\"}},cellsX:{default:8,description:\"Number of bricks per row\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Bricks per Row\",group:\"Effect\"}},cellsY:{default:10,description:\"Number of brick rows\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Rows\",group:\"Effect\"}},mortar:{default:.05,description:\"Width of mortar gaps \\u2014 equal pixel thickness in both directions\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Mortar Gap\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the brick edges (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},variation:{default:0,description:\"Per-brick random lightening/darkening of the brick color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Effect\"}},rotation:{default:0,transform:cs,description:\"Rotation of the pattern in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},speed:{default:0,description:\"Animation speed\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},offset:{default:0,description:\"Static horizontal offset \\u2014 shifts the brick pattern without animating\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Offset\",group:\"Animation\"}},speedVariance:{default:0,description:\"How much each row's speed varies \\u2014 at high values rows move at different speeds and directions\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Speed Variance\",group:\"Animation\"}},seed:{default:0,description:\"Random seed for per-row speed variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:T(\"colorMortar\"),stroke:Sc(T(\"colorBrick\"),HO.shade),mask:HO.bricks,space:T(\"colorSpace\")})});var KO=H({name:\"BrightnessContrast\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Adjust brightness and contrast of the image\",props:{brightness:{default:0,description:\"Brightness adjustment (-1 to 1)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Brightness\",group:\"Adjustments\"}},contrast:{default:0,description:\"Contrast adjustment (-1 to 1)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Contrast\",group:\"Adjustments\"}}},effect:o8({brightness:T(\"brightness\"),contrast:T(\"contrast\")}),identityWhen:nR(Uo(\"brightness\"),Uo(\"contrast\")),missingChildMessage:\"You must pass a child component into the Brightness Contrast shader.\"});var sue=JSON.stringify({type:\"sphere3D\",radius:.35}),rue=.38,QO=H({name:\"BrushedMetal\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photorealistic brushed metal \\u2014 a satin anodised surface combed with fine directional grain that smears the reflected studio and key light into the long anisotropic streaks of real brushed aluminium, steel, gold or copper\",animatedTime:{speed:\"speed\"},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the metal shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the metal shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the metal shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},lightColor:{default:\"#e9ebef\",transform:ce,description:\"The bright tone of the polished grain \\u2014 recolor for gold (#ffe8b0), copper (#ffc8a0) or steel\",ui:{type:\"color\",label:\"Light Color\",group:\"Metal\"}},darkColor:{default:\"#26282d\",transform:ce,description:\"The dark tone the brushed grain falls to in shadow. Tint it warm for gold/bronze, cool for steel.\",ui:{type:\"color\",label:\"Dark Color\",group:\"Metal\"}},brushAngle:{default:0,description:\"Direction the surface is brushed, in degrees \\u2014 the grain and every reflection streak run along this axis\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Brush Angle\",group:\"Brush\"}},anisotropy:{default:.4,description:\"How directional the brushing is \\u2014 1 = long smeared streaks along the grain, 0 = isotropic satin with no direction\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Anisotropy\",group:\"Brush\"}},grain:{default:.4,description:\"Depth of the individual brush scratches \\u2014 the fine satin texture combed into the metal\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Grain\",group:\"Brush\"}},grainScale:{default:2,description:\"Density of the brush lines \\u2014 higher = finer, tighter scratches\",ui:{type:\"range\",min:.25,max:4,step:.01,label:\"Grain Scale\",group:\"Brush\"}},roughness:{default:.5,description:\"Overall satin softness \\u2014 0 = near-polished with crisp reflections, 1 = soft matte brushed finish\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Roughness\",group:\"Surface\"}},...gr({environment:{default:1.4,description:\"Strength of the reflected studio lighting \\u2014 the softboxes seen smeared across the metal\",ui:{group:\"Surface\"}},envRotation:{ui:{group:\"Surface\"}},lightAngle:{default:215,description:\"Direction of the key light for the anisotropic specular streak, in degrees\",ui:{group:\"Surface\"}}}),speed:{default:.4,description:\"Speed of the slowly drifting reflection \\u2014 the studio gently orbits the surface. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Surface\"}},bevelWidth:{default:.05,description:\"Width of the edge bevel, relative to the shape \\u2014 thin for machined jewellery edges, wide for soft pillowed metal\",ui:{type:[\"range\",\"map\"],min:.005,max:.2,step:.001,label:\"Bevel Width\",group:\"Surface\"}},bevelShape:{default:0,description:\"Bevel profile \\u2014 0 = one smooth round fillet, 1 = machined: a steep outer fillet, a chamfer plateau and an inner knee, each catching its own line of light\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bevel Profile\",group:\"Surface\"}},...gr({edgeSoftness:{ui:{group:\"Surface\"}}}),shape:{default:sue,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=Lr(e,t,{scale:s.scale}),a=Dn(e,o,{bevelWidth:s.bevelWidth,bevelShape:s.bevelShape}),i=ii(s.brushAngle,\"brush\"),l=i.coordsOf(go(e,o)),c=z(s.anisotropy,\"aniso\"),d=z(v(s.grainScale,150),\"dens\"),u=z(v(Vt(v(r,.05)),.35),\"driftA\"),p=z(I(v(c,.5),.08),\"sheenAmt\"),_=z(Cc(l,{freq:[1.3,6.5],drift:u}),\"sheen\"),f=z(I(Cc(l,{freq:[4.5,d]}),v(Cc(l,{freq:[8,v(d,2.3)],offset:[3.1,7.7]}),.5)),\"lines\"),h=yg(a,i,{across:z(I(v(_,p),v(f,v(s.grain,.16))),\"rAcross\"),along:z(v(Cc(l,{freq:[1.3,6.5],offset:[15.21,0],drift:u}),v(p,.12)),\"rAlong\")}),g=Ea(t,o),y=z(Ge(s.roughness,0,1),\"rough\"),b=z(Lo(g,h),\"R\"),x={rotation:Er(s.envRotation,\"env\"),keyRadius:z(et(.42,.16,ne(1,y)),\"keyRad\"),drift:z(v(Vt(v(r,.07)),.05),\"drift\"),strength:z(s.environment,\"envStr\"),skyGain:rue},P=_L(z(Ge(v(I(uL({center:b,axis:i.tangent,spread:v(v(c,I(v(y,.6),.25)),.42),hint:\"envLum\"},(C,E)=>Pc(C,E,x)),Ud({normal:h,tangent:i.tangent,view:g,light:Ld(Er(s.lightAngle,\"light\"),-.7),alphas:V_(y,c),gain:et(.45,1.1,ne(1,y))})),mL(ni(h,g),{amount:.6})),0,1.7),\"lit\"),s.darkColor,s.lightColor);return Js(Dr(o.sdf,o.pxH),Ot(P,Jr(o,s.edgeSoftness)),xt,\"brushedMetal\")}})});var ZO=H({name:\"Bulge\",role:\"warp\",category:\"Distortions\",description:\"Magnify or pinch content around a center point\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point of the bulge effect\"),strength:{default:1,description:\"The intensity of the bulge effect (positive = bulge out, negative = pinch in)\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},radius:{default:1,description:\"The radius of the bulge effect area\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Radius\",group:\"Effect\"}},falloff:{default:.5,description:\"Controls the smoothness of the transition (0 = hard edge, 1 = very smooth)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},map:XL({center:T(\"center\"),strength:T(\"strength\"),radius:T(\"radius\"),falloff:T(\"falloff\")}),missingChildMessage:\"You must pass a child component into the Bulge shader.\"});var oue=Wo,aue=2*Math.PI*7,nue=JSON.stringify({type:\"sphere3D\",radius:.35}),JO=H({name:\"CarbonFiber\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photorealistic woven carbon fibre \\u2014 interlaced tows whose anisotropic sheen flips ninety degrees cell to cell, raised into a quilted weave and finished with a glossy clearcoat that mirrors the studio. Plain or twill, in any shape.\",props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the carbon shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the carbon shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the carbon shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},lightColor:{default:\"#b9bdc6\",transform:ce,description:\"The bright tone of the fibre sheen \\u2014 recolor for forged/colored carbon (red, blue, bronze)\",ui:{type:\"color\",label:\"Fiber Sheen\",group:\"Carbon\"}},darkColor:{default:\"#0b0c0e\",transform:ce,description:\"The deep resin tone the weave falls to in shadow \\u2014 near-black for classic carbon\",ui:{type:\"color\",label:\"Resin Color\",group:\"Carbon\"}},weaveStyle:{default:\"twill\",compileTime:!0,description:\"Weave pattern \\u2014 plain (checkerboard) or 2\\xD72 twill (the diagonal supercar weave)\",ui:{type:\"select\",options:[{label:\"Twill (2\\xD72)\",value:\"twill\"},{label:\"Plain\",value:\"plain\"}],label:\"Weave\",group:\"Carbon\"}},weaveScale:{default:30,description:\"Number of woven tows across the shape \\u2014 higher = finer, denser weave\",ui:{type:\"range\",min:2,max:50,step:.5,label:\"Weave Scale\",group:\"Carbon\"}},weaveAngle:{default:0,description:\"Rotates the whole weave grid in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Weave Angle\",group:\"Carbon\"}},relief:{default:.5,description:\"Depth of the quilted weave \\u2014 how far each tow bulges, catching light on its crown and shadowing the valleys between\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Weave Depth\",group:\"Carbon\"}},fiberSheen:{default:1.2,description:\"Strength of the anisotropic fibre sheen \\u2014 the directional satin glint running along each tow\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Fiber Sheen\",group:\"Carbon\"}},roughness:{default:.5,description:\"Softness of the fibre sheen \\u2014 0 = tight crisp glints, 1 = soft matte satin\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Roughness\",group:\"Surface\"}},clearcoat:{default:1.2,description:\"Strength of the glossy lacquer coat \\u2014 the sharp studio reflections of the wet clearcoat over the weave\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Clearcoat\",group:\"Surface\"}},...gr({environment:{default:2,description:\"Strength of the reflected studio lighting seen in the clearcoat\",ui:{group:\"Surface\"}},envRotation:{ui:{group:\"Surface\"}},lightAngle:{default:215,description:\"Direction of the key light for the fibre sheen, in degrees\",ui:{group:\"Surface\"}}}),bevelWidth:{default:.05,description:\"Width of the edge bevel, relative to the shape \\u2014 thin for machined jewellery edges, wide for soft pillowed metal\",ui:{type:[\"range\",\"map\"],min:.005,max:.2,step:.001,label:\"Bevel Width\",group:\"Surface\"}},bevelShape:{default:0,description:\"Bevel profile \\u2014 0 = one smooth round fillet, 1 = machined: a steep outer fillet, a chamfer plateau and an inner knee, each catching its own line of light\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bevel Profile\",group:\"Surface\"}},...gr({edgeSoftness:{ui:{group:\"Surface\"}}}),shape:{default:nue,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s,propValues:r}=t,o=(r.weaveStyle||\"twill\")===\"plain\"?\"plain\":\"twill\",a=Lr(e,t,{scale:s.scale}),{sdf:i,pxH:l}=a,c=Dn(e,a,{bevelWidth:s.bevelWidth,bevelShape:s.bevelShape}),d=ii(s.weaveAngle,\"weave\"),{along:u,across:p}=d.coordsOf(go(e,a)),_=z(v(u,s.weaveScale),\"wA\"),f=z(v(p,s.weaveScale),\"wB\"),h=z(Xr(_),\"cellX\"),g=z(Xr(f),\"cellY\"),y=z(ne(Qr(_),.5),\"fA\"),b=z(ne(Qr(f),.5),\"fB\"),x;if(o===\"plain\"){let se=z(I(h,g),\"s2\");x=z(ne(se,v(2,Xr(Ce(se,2)))),\"parity\")}else{let se=z(I(ne(h,g),64),\"s4\");x=z(br(ch(ne(se,v(4,Xr(Ce(se,4)))),2),It(1),It(0)),\"parity\")}let P=z(et(d.tangent,d.perp,x),\"fiber\"),C=z(et(d.perp,d.tangent,x),\"crossAxis\"),E=z(et(b,y,x),\"acrossLocal\"),R=z(et(u,p,x),\"alongLocal\"),U=v(s.relief,.32),L=v(Vt(v(E,oue)),U),k=v(co(v(R,2),v(E,40)),.18),D=pL(c,C,z(I(L,v(I(Vt(v(E,aue)),k),.13)),\"crossTilt\")),O=et(.5,1,ot(0,.05,Yr(ne(.5,ms(y)),ne(.5,ms(b))))),F=Ea(t,a),q=ni(D,F),Y=z(Lo(F,D),\"R\"),V=z(Ge(s.roughness,0,1),\"rough\"),X=Ld(Er(s.lightAngle,\"light\"),-.7),Q=z(et(.06,.5,V),\"baseA\"),te=Ud({normal:D,tangent:P,light:X,view:F,alphas:{along:v(Q,6),across:Q},gain:s.fiberSheen}),J=Ge(I(I(.035,v(Ge(I(v($t(D,X),.5),.5),0,1),.1)),te),0,1.3),oe=I(v(et(s.darkColor.member(\"rgb\"),s.lightColor.member(\"rgb\"),kt(J)),O),kt(z(v(v(Pc(Y.member(\"x\"),Y.member(\"y\"),{rotation:Er(s.envRotation,\"env\"),keyRadius:.16,drift:0,strength:s.environment,skyGain:.3}),I(.05,v(ts(q,5),.95))),s.clearcoat),\"coat\"))),le=Jr(a,s.edgeSoftness);return Js(Dr(i,l),Ot(oe,le),xt,\"carbonFiber\")}})});var eG=H({name:\"Chalkboard\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Renders content as a chalk drawing on a blackboard, with edge strokes and cross-hatch shading\",props:{boardColor:{default:\"#000000\",transform:ce,description:\"Background board color\",ui:{type:\"color\",label:\"Board\",group:\"Colors\"}},chalkColor:{default:\"#eceadb\",transform:ce,description:\"Chalk stroke color\",ui:{type:\"color\",label:\"Chalk\",group:\"Colors\"}},edgeSensitivity:{default:.5,description:\"How readily edges are detected and drawn as chalk strokes\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Edge Sensitivity\",group:\"Effect\"}},edgeThickness:{default:1.5,description:\"Thickness of the chalk outline strokes\",ui:{type:[\"range\",\"map\"],min:.5,max:4,step:.1,label:\"Edge Thickness\",group:\"Effect\"}},shading:{default:.05,description:\"Amount of cross-hatch shading filling darker regions\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shading\",group:\"Effect\"}},hatchScale:{default:16,description:\"Spacing of the cross-hatch lines in pixels\",ui:{type:[\"range\",\"map\"],min:3,max:24,step:.5,label:\"Hatch Scale\",group:\"Effect\"}},grain:{default:.45,description:\"Chalk dustiness / grain that breaks up the strokes\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Grain\",group:\"Effect\"}}},effect:X8({edges:$8({spacing:T(\"edgeThickness\")}),sensitivity:T(\"edgeSensitivity\"),hatchScale:T(\"hatchScale\"),shading:T(\"shading\"),grain:T(\"grain\"),board:T(\"boardColor\"),chalk:T(\"chalkColor\")})});var tG=H({name:\"ChannelBlur\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Independent blur for red, green, and blue channels\",requiresRTT:!0,requiresChild:!0,props:{redIntensity:{default:0,description:\"Blur intensity for red channel\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Red Intensity\",group:\"Effect\"}},greenIntensity:{default:20,description:\"Blur intensity for green channel\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Green Intensity\",group:\"Effect\"}},blueIntensity:{default:40,description:\"Blur intensity for blue channel\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Blue Intensity\",group:\"Effect\"}}},...BU({red:T(\"redIntensity\"),green:T(\"greenIntensity\"),blue:T(\"blueIntensity\")})});var sG=H({name:\"Checkerboard\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Classic checkerboard pattern with two alternating colors\",acceptsUVContext:!0,props:{colorA:{default:\"#cccccc\",transform:ce,description:\"First color of the checkerboard pattern\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#999999\",transform:ce,description:\"Second color of the checkerboard pattern\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},cells:{default:8,description:\"Number of cells along the canvas height (creates square cells). Switch the unit to px in the editor to set an absolute cell size instead.\",ui:{type:[\"range\",\"map\"],min:1,max:50,step:1,label:\"Cells\",group:\"Effect\",dimensional:\"count-canvas-height\"}},softness:{default:0,description:\"Smoothness of the transition between colors (0 = hard edges, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Softness\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:T(\"colorA\"),stroke:T(\"colorB\"),mask:NR({cells:T(\"cells\"),softness:T(\"softness\")}),space:T(\"colorSpace\")})});var rG=H({name:\"CheckerWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away as a checkerboard of fading squares\",props:{progress:{default:.5,description:\"How far the wipe has progressed (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},blockSize:{default:.1,description:\"Size of each square as a fraction of the frame width\",ui:{type:[\"range\",\"map\"],min:.02,max:.5,step:.01,label:\"Block Size\",group:\"Transition\"}},softness:{default:.15,description:\"How softly each square fades out (0 = hard-edged squares)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse the order the squares wipe in\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.cells(T(\"blockSize\")).checker(),progress:T(\"progress\"),feather:T(\"softness\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Checker Wipe shader.\"});var oG=XR({count:T(\"count\"),angle:T(\"angle\"),balance:T(\"balance\"),softness:T(\"softness\"),offset:T(\"offset\")}),aG=H({name:\"Chevron\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Animated chevron / zigzag stripe pattern\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#000000\",transform:ce,description:\"First color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Second color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},count:{default:5,description:\"Number of chevron pairs visible\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Count\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Rotation angle of the chevrons\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Angle\",group:\"Effect\"}},balance:{default:.5,description:\"Ratio of the two colors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Balance\",group:\"Effect\"}},softness:{default:0,description:\"Edge softness\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},speed:{default:0,description:\"Animation speed\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},offset:{default:0,description:\"Phase offset for pattern positioning\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Offset\",group:\"Animation\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:fp(Zr({fill:T(\"colorA\"),stroke:T(\"colorB\"),mask:oG,space:T(\"colorSpace\")}),fg(I_(T(\"colorA\")),I_(T(\"colorB\")),oG))});var yo=128,G2=(e,t)=>typeof e==\"number\"?e:t,nG=H({name:\"ChromaFlow\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Interactive liquid flow effect that follows your cursor\",usesPointer:!0,props:{baseColor:{default:\"#0066ff\",transform:ce,description:\"Base liquid color\",ui:{type:\"color\",label:\"Base Color\",group:\"Colors\"}},upColor:{default:\"#00ff00\",transform:ce,description:\"Color for upward movement\",ui:{type:\"color\",label:\"Up Color\",group:\"Colors\"}},downColor:{default:\"#ff0000\",transform:ce,description:\"Color for downward movement\",ui:{type:\"color\",label:\"Down Color\",group:\"Colors\"}},leftColor:{default:\"#0000ff\",transform:ce,description:\"Color for leftward movement\",ui:{type:\"color\",label:\"Left Color\",group:\"Colors\"}},rightColor:{default:\"#ffff00\",transform:ce,description:\"Color for rightward movement\",ui:{type:\"color\",label:\"Right Color\",group:\"Colors\"}},intensity:{default:1,description:\"Strength of the liquid effect\",ui:{type:\"range\",min:.5,max:1.5,step:.1,label:\"Intensity\",group:\"Effect\"}},radius:{default:3,description:\"Radius of the liquid effect\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Radius\",group:\"Effect\"}},momentum:{default:30,description:\"How much momentum colors retain in their flow direction\",ui:{type:\"range\",min:10,max:60,step:1,label:\"Momentum\",group:\"Effect\"}}},gpu:{fragment:e=>{let{uniforms:t,ctx:s,uvContext:r,onBeforeRender:o,dimensions:a,getCpuValue:i}=e,l=new Float32Array(yo*yo*4),c=new Float32Array(yo*yo*4),d=Bg(e,{size:yo,label:\"chromaflow-field\"}),u=d.texture,p=0,_=0,f=.5,h=.5,g=0,y=1,b=!1,x=0,P=1,C=.15;o(kg({clampDt:.016,steps:[gn(\"cursorVelocity\",k=>{y=a.width/Math.max(1,a.height);let D=k.dt>0?(k.pointer.x-f)/k.dt:0,O=k.dt>0?(k.pointer.y-h)/k.dt:0;p=p*.85+D*.15,_=_*.85+O*.15,f=k.pointer.x,h=k.pointer.y,b=Math.abs(D)+Math.abs(O)>.01}),gn(\"idleSkip\",()=>!b&&g<1e-4?\"skip\":void 0),gn(\"advect+decay\",k=>{P=G2(i(\"intensity\"),1),C=G2(i(\"radius\"),3)*.05;let D=G2(i(\"momentum\"),30),O=1-k.dt/Math.max(.1,1),F=1-k.dt,q=D*50*k.dt;x=0;for(let Y=0;Y<yo;Y++)for(let V=0;V<yo;V++){let X=(Y*yo+V)*4,Q=l[X],te=l[X+1];if(c[X]=Q*O,c[X+1]=te*O,c[X+2]=l[X+2]*F,Math.abs(Q)>.001||Math.abs(te)>.001){let oe=V-Q*q,le=Y-te*q,se=Math.floor(oe),Te=Math.floor(le),de=se+1,xe=Te+1;if(se>=0&&Te>=0&&de<yo&&xe<yo){let Ae=oe-se,De=le-Te,Ee=(Te*yo+se)*4,ze=(Te*yo+de)*4,Ie=(xe*yo+se)*4,ke=(xe*yo+de)*4,Me=l[Ee+2]*(1-Ae)*(1-De)+l[ze+2]*Ae*(1-De)+l[Ie+2]*(1-Ae)*De+l[ke+2]*Ae*De;c[X+2]=Me*F}}let J=Math.max(Math.abs(c[X]),Math.abs(c[X+1]),c[X+2]);J>x&&(x=J)}}),gn(\"inject(brush)\",k=>{if(!b)return;let D=Math.sqrt(p*p+_*_),O=Math.min(D*D*20,1),F=C*O,q=F*2*(F*2),Y=F*F,V=P*100*k.dt*.01,X=Math.min(D*10,1);for(let Q=0;Q<yo;Q++)for(let te=0;te<yo;te++){let J=(te+.5)/yo,oe=(Q+.5)/yo,le=y>=1?(J-k.pointer.x)*y:J-k.pointer.x,se=y>=1?oe-k.pointer.y:(oe-k.pointer.y)/y,Te=le*le+se*se;if(Te<q){let de=(Q*yo+te)*4,xe=Math.exp(-Te/Y);c[de]+=p*xe*V,c[de+1]+=_*xe*V,c[de+2]+=xe*V*X,c[de]=Math.max(-1,Math.min(1,c[de])),c[de+1]=Math.max(-1,Math.min(1,c[de+1])),c[de+2]=Math.max(0,Math.min(1,c[de+2]))}}}),gn(\"publish(halfFloat)\",()=>{g=b?1:x,l.set(c);for(let k=0;k<d.texData.length;k++)d.texData[k]=_o(l[k]);d.upload()})]}));let E=r??s.uv,R=1/yo,U=\"linearClamp\",L=(k,D)=>u.sample(I(E,rt(k,D)),U);return W(qz,\"flowDirectionColor\",[L(0,0),L(R,0),L(0,R),L(-R,0),L(0,-R),t.baseColor,t.upColor,t.downColor,t.leftColor,t.rightColor])}}});var iG=H({name:\"ChromaticAberration\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Separate RGB channels for a prismatic distortion effect\",props:{strength:{default:.2,description:\"Overall strength of the chromatic aberration effect\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Direction of the chromatic aberration in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},redOffset:{default:-1,description:\"Red channel offset multiplier\",ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.1,label:\"Red Offset\",group:\"Effect\"}},greenOffset:{default:0,description:\"Green channel offset multiplier\",ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.1,label:\"Green Offset\",group:\"Effect\"}},blueOffset:{default:1,description:\"Blue channel offset multiplier\",ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.1,label:\"Blue Offset\",group:\"Effect\"}}},effect:$o(L8({strength:T(\"strength\"),angle:T(\"angle\"),red:T(\"redOffset\"),green:T(\"greenOffset\"),blue:T(\"blueOffset\")}),[])});var{bevelSin:iue}=tz,{fieldGradient:lue}=Xh,{isMobileGpuViewport:cue}=kn,due=bt,uue=JSON.stringify({type:\"sphere3D\",radius:.35});function F2(e,t,s,r,o,a,i,l,c){let d=z(e,\"ex\"),u=z(t,\"ey\"),p=z(s,\"ez\"),_=z(Ce(d,I(Kr(rt(d,u)),1e-4)),\"horiz\"),f=z(I(.35,v(.65,ot(-.7,.7,_))),\"warmSide\"),h=z(I(.45,v(.55,ot(-.7,.7,v(_,-1)))),\"coolSide\"),g=z(ot(-.65,1,u),\"up\"),y=I(v(c,.03),Qe(.003,.003,.004)),b=et(et(Qe(.17,.175,.19),y,kt(i)),Qe(.56,.57,.6),kt(v(g,g))),x=ot(.3,.9,u);b=I(b,v(Qe(.55,.55,.56),x));let P=z(Ce(I(u,.45),.2),\"cd\"),C=tr(v(v(P,P),-1));b=I(b,v(c,v(v(v(C,a),.2),h)));let E=z(ot(.18,-.1,p),\"facing\"),R=z(it(ne(.32,p),.06),\"pz\"),U=z(Ce(d,R),\"px\"),L=z(Ce(u,R),\"py\"),k=z(ne(ms(U),.62),\"bx\"),D=z(ne(ms(ne(L,.3)),.28),\"by\"),O=Yr(it(k,D),0),F=z(I(Kr(it(rt(k,D),rt(0,0))),O),\"dbox\"),q=z(I(.05,v(r,.4)),\"boxSoft\"),Y=v(ot(q,v(q,-.6),F),E);b=I(b,v(Qe(2.9,2.87,2.82),Y));let V=ot(.5,.92,ms(d)),X=et(.55,.07,i);b=v(b,et(It(1),X,V));let Q=z(I(.065,v(o,.05)),\"gw\"),te=z(it(F,0),\"dOut\"),J=v(tr(v(v(Ce(te,Q),Ce(te,Q)),-1)),ot(-.06,.1,F));b=I(b,v(l,v(v(v(v(J,a),1.3),f),E)));let oe=z(Ce(I(u,.12),.05),\"fb\");b=I(b,v(l,v(v(v(v(tr(v(v(oe,oe),-1)),a),.5),f),ne(1,E))));let le=z(ne(ms(U),.7),\"cbx\"),se=z(ne(ms(I(L,.78)),.05),\"cby\"),Te=z(I(Kr(it(rt(le,se),rt(0,0))),Yr(it(le,se),0)),\"dcard\"),de=v(ot(q,v(q,-.6),Te),E);return I(b,v(Qe(.5,.5,.52),de))}var lG=H({name:\"Chrome\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Studio-lit mirror chrome \\u2014 a precision-machined shape with a controllable polished bevel, softly convex faces and a photographic studio reflected in them: one huge frontal softbox, black flags, and thin warm/cool strip lights that fringe amber and ice-blue exactly where the reflections break\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=e.volumetric,a=cue(),i=.01,l=.0081,c=Lr(e,t,{scale:s.scale}),{s0:d,sX:u,sY:p,sdf:_,pxH:f}=c,h=go(e,c),g=h.member(\"x\"),y=h.member(\"y\"),b;if(o)b=Mc(c);else{let qe=z(W(lue,\"fieldGradient\",[d,u,p,It(i)]),\"grad\"),st=z(it(Kr(qe),1e-4),\"glen\"),pt=z(Ce(qe.member(\"x\"),st),\"gx\"),Ze=z(Ce(qe.member(\"y\"),st),\"gy\"),nt=it(s.bevelWidth,.003),ht=z(v(_,-1),\"depth\"),yt=z(Ge(Ce(ht,nt),0,1),\"t0\"),St=z(W(iue,\"bevelSin\",[Ge(I(yt,v(v(v(v(v(z(W(Si,\"perlin12d\",[rt(v(g,21),v(y,21))]),\"rimN\").member(\"x\"),s.waviness),.22),yt),ne(1,yt)),4)),0,1),s.bevelShape]),\"sBev\"),Mt=v(v(s.curvature,.14),Ce(l,I(v(ht,ht),l))),Rt=z(Kr(rt(g,y)),\"flen\"),Kt=z(Ce(g,it(Rt,1e-4)),\"dgx\"),Wt=z(Ce(y,it(Rt,1e-4)),\"dgy\"),ls=z(v(v(s.curvature,.75),ot(0,.5,Rt)),\"sSphere\"),us=z(it(St,Mt),\"sEdge\"),os=z(rt(I(v(pt,us),v(Kt,ls)),I(v(Ze,us),v(Wt,ls))),\"txy\"),bs=z(Yr(Kr(os),.9995),\"tl\"),hs=z(v(os,Ce(bs,it(Kr(os),1e-4))),\"tn\"),gs=ho(ne(1,v(bs,bs)));b=z(Qe(hs.member(\"x\"),hs.member(\"y\"),v(gs,-1)),\"nGeo\")}let x=z(Ag(rt(I(v(g,1.05),v(r,.08)),v(y,1.05)),1),\"wg\"),P=z(v(s.waviness,.2),\"wAmt\"),C=Gi(b,v(x.member(\"x\"),P),v(x.member(\"y\"),P)),E=Ea(t,c,.55),R=z(Lo(E,C),\"R\"),U=ni(C,E),L=z(I(v(s.envRotation,due),v(Vt(v(r,.23)),.05)),\"rotA\"),k=z(Do(L),\"envC\"),D=z(Vt(L),\"envS\"),O=z(v(R.member(\"y\"),-1),\"upY\"),F=z(ne(v(R.member(\"x\"),k),v(O,D)),\"rx0\"),q=z(I(v(R.member(\"x\"),D),v(O,k)),\"ry0\"),Y=z(I(v(Vt(v(r,.5)),.4),v(Vt(I(v(r,.19),1.7)),.2)),\"orbit\"),V=z(Do(Y),\"oc\"),X=z(Vt(Y),\"os\"),Q=z(I(v(F,V),v(R.member(\"z\"),X)),\"rx\"),te=z(ne(v(R.member(\"z\"),V),v(F,X)),\"rz0\"),J=z(v(Vt(I(v(r,.31),.9)),.12),\"nod\"),oe=z(Do(J),\"nc\"),le=z(Vt(J),\"ns\"),se=z(ne(v(q,oe),v(te,le)),\"ry\"),Te=z(I(v(te,oe),v(q,le)),\"rz\"),de=ot(.75,1,v(C.member(\"z\"),-1)),xe=z(s.softness,\"soft\"),Ae=z(I(xe,v(de,.2)),\"softEff\"),De=z(s.spectral,\"spectral\"),Ee=z(s.shadows,\"shadows\"),ze=z(s.warmColor.member(\"rgb\"),\"warmC\"),Ie=z(s.coolColor.member(\"rgb\"),\"coolC\"),ke=z(F2(Q,se,Te,Ae,xe,De,Ee,ze,Ie),\"envG\"),Me,we;if(a)Me=ke.member(\"x\"),we=ke.member(\"z\");else{let qe=z(v(s.dispersion,I(.004,v(v(U,U),.06))),\"delta\"),st=z(F2(Q,I(se,qe),Te,Ae,xe,De,Ee,ze,Ie),\"envRt\"),pt=z(F2(Q,ne(se,qe),Te,Ae,xe,De,Ee,ze,Ie),\"envBt\");Me=st.member(\"x\"),we=pt.member(\"z\")}let Ve=yp(v(v(Qe(Me,ke.member(\"y\"),we),s.environment),s.tint.member(\"rgb\")));return Js(Dr(_,f),Ot(Ve,Jr(c,s.edgeSoftness)),xt,\"chrome\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the chrome shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the chrome shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the chrome shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},tint:{default:\"#ffffff\",transform:ce,description:\"Metal tint multiplied into the reflection \\u2014 white for silver chrome, warm ivory for gold, dusky rose for copper\",ui:{type:\"color\",label:\"Tint\",group:\"Metal\"}},warmColor:{default:\"#ffa94d\",transform:ce,description:\"Color of the warm strip light hugging the studio horizon \\u2014 the amber band that fringes the reflections\",ui:{type:\"color\",label:\"Warm Light\",group:\"Metal\"}},coolColor:{default:\"#82a7e6\",transform:ce,description:\"Color of the cool wash below the horizon \\u2014 the steel-blue zone the darker reflections fall into\",ui:{type:\"color\",label:\"Cool Light\",group:\"Metal\"}},bevelWidth:{default:.028,description:\"Width of the polished edge bevel, relative to the shape \\u2014 thin for machined jewellery edges, wide for soft pillowed metal\",ui:{type:[\"range\",\"map\"],min:.005,max:.2,step:.001,label:\"Bevel Width\",group:\"Bevel\"}},bevelShape:{default:.55,description:\"Bevel profile \\u2014 0 = one smooth round fillet, 1 = machined: a steep outer fillet, a chamfer plateau and an inner knee, each catching its own line of light\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bevel Profile\",group:\"Bevel\"}},curvature:{default:.5,description:\"Convex doming of the faces \\u2014 sweeps the big soft studio gradients across otherwise flat metal\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Curvature\",group:\"Bevel\"}},waviness:{default:.15,description:\"Pressed-metal imperfection \\u2014 gently bends the face reflections and wobbles the bevel light lines so the surface reads as real\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Waviness\",group:\"Bevel\"}},...gr({environment:{description:\"Exposure of the reflected studio \\u2014 the overall brilliance of the chrome\",ui:{group:\"Studio\"}},envRotation:{description:\"Rotates the whole reflected studio \\u2014 spins where the softbox, flags and strips fall\",ui:{type:[\"range\",\"map\"],group:\"Studio\"}}}),softness:{default:.3,description:\"Softness of the studio edges \\u2014 0 = razor polished reflections, 1 = satin diffusion\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Studio\"}},spectral:{default:.9,description:\"The colored accent lights: an amber glow hugging the softbox edge and an ice-blue wash below it. 0 = a fully achromatic black-and-white studio.\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Accent Lights\",group:\"Studio\"}},...gr({dispersion:{default:.3,description:\"Prismatic RGB splitting concentrated on the fast-curving bevel \\u2014 thin rainbow micro-fringes along the edge highlights, distinct from the broad accent lights\",ui:{group:\"Studio\"}}}),shadows:{default:.7,description:\"Depth of the dark studio reflections \\u2014 how hard the black side flags and floor crush toward graphite. 0 lifts them to a soft gray studio.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadows\",group:\"Studio\"}},speed:{default:.5,description:\"Speed of the studio orbit \\u2014 the whole lighting environment slowly wanders around the piece, sliding the reflections across faces and edges. 0 freezes it.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Studio\"}},...gr({edgeSoftness:{ui:{group:\"Surface\"}}}),shape:{default:uue,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var cG=H({role:\"shape\",name:\"Circle\",description:\"Generate a circle with adjustable size and softness\",shape:{distance:({x:e,y:t},s)=>_p(e,t,v(s(\"radius\"),.5)),rotatable:!1,colorDescription:\"The color of the circle\",centerDescription:\"The center point of the circle\",centerLabel:\"Center Position\",bounds:{size:{width:\"radius\",height:\"radius\",as:\"canvas-height\"}},shapeProps:{radius:{default:1,description:\"The radius of the circle. A value of one (1) is sets the circle to fit the canvas.\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Radius\",group:\"Effect\",units:[\"%\",\"px\"]}}},stroke:{strokeColorDescription:\"The color of the stroke outline\",strokePositionDescription:\"Position of the stroke relative to the circle edge\"},colorSpaceDescription:\"Color space for blending fill and stroke colors in soft edges\",propOverrides:{softness:{default:0,description:\"Edge softness. Lower values like zero (0) are sharp, higher values like one (1) are softer.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\",dimensional:\"canvas-height\"}},strokeThickness:{default:0,description:\"The thickness of the stroke outline. Zero (0) means no stroke.\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.01,label:\"Stroke Thickness\",group:\"Stroke\"}}},propOrder:[\"origin\",\"color\",\"radius\",\"softness\",\"center\",\"strokeThickness\",\"strokeColor\",\"strokePosition\",\"colorSpace\"]}});var dG=H({name:\"ColorWheel\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"A directional gradient that smoothly cycles through rainbow colors or a custom set of three colors\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{mode:{default:\"rainbow\",compileTime:!0,description:\"Rainbow cycles through the full spectrum; Custom loops through your three chosen colors\",ui:{type:\"select\",options:[{label:\"Rainbow\",value:\"rainbow\"},{label:\"Custom\",value:\"custom\"}],label:\"Mode\",group:\"Colors\"}},colorA:{default:\"#ff0000\",transform:ce,description:\"First color in the cycle\",ui:{type:\"color\",label:\"Color 1\",group:\"Colors\",condition:{mode:\"custom\"}}},colorB:{default:\"#00ff88\",transform:ce,description:\"Second color in the cycle\",ui:{type:\"color\",label:\"Color 2\",group:\"Colors\",condition:{mode:\"custom\"}}},colorC:{default:\"#0066ff\",transform:ce,description:\"Third color in the cycle\",ui:{type:\"color\",label:\"Color 3\",group:\"Colors\",condition:{mode:\"custom\"}}},scale:{default:1,description:\"Number of color cycles across the viewport\",ui:{type:[\"range\",\"map\"],min:.1,max:10,step:.1,label:\"Scale\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Direction the gradient flows\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Angle\",group:\"Effect\"}},speed:{default:.05,description:\"Speed at which the gradient cycles\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Speed\",group:\"Animation\"}},colorSpace:{default:\"oklch\",transform:at,compileTime:!0,description:\"Color space for blending between custom colors\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\",condition:{mode:\"custom\"}}}},paint:FR({mode:T(\"mode\"),direction:T(\"angle\"),scale:T(\"scale\"),palette:{a:T(\"colorA\"),b:T(\"colorB\"),c:T(\"colorC\")},space:T(\"colorSpace\")})});var uG=6,pG=4,Ng=pG,Bc=1024,mG=\"rgba16float\",pue=()=>Wz({nLuma:uG,scaleN:pG,format:mG,namePrefix:\"compression\"}),Z0e=JA(uG);function mue(e,t,s){let{ctx:r}=s,o=W(Yt,\"unpremultiplyAlpha\",[t.sample(r.uv)]),a=z(Xr(v(r.uv,r.viewportSize)),\"pPix\"),i=Ge(Xr(Ce(a.member(\"x\"),Ng)),0,Bc-1),l=Ge(Xr(Ce(a.member(\"y\"),Ng)),0,Bc-1),c=rt(Ce(I(i,.5),Bc),Ce(I(l,.5),Bc));return Ct(e.sample(c,\"nearestClamp\").member(\"rgb\"),o.member(\"a\"))}function _ue(e){return{compute:t=>{let{childNode:s,gpu:r,convertToTexture:o,registerComputeTexture:a,getCpuValue:i,onCleanup:l,onResize:c,dimensions:d}=t;if(!s)return null;let u=r?.root;if(!u)return null;let p=o(s),_=u.createTexture({size:[Bc,Bc],format:mG}).$usage(\"storage\",\"sampled\");l(()=>_.destroy());let f=a(_),h=pue(),g=u.createUniform(h.Params),y=Math.max(1,Math.round(d.width)),b=Math.max(1,Math.round(d.height)),x=(L,k)=>[Math.min(Math.ceil(L/Ng),Bc),Math.min(Math.ceil(k/Ng),Bc)],[P,C]=x(y,b),E=ai(u,h.kernel),R=E,U=!1;return c(({width:L,height:k})=>{y=Math.max(1,Math.round(L)),b=Math.max(1,Math.round(k)),[P,C]=x(y,b)}),{outputs:{childTexture:p,jpegCellTexture:f},bindInputs:L=>{let k=L(p.key);if(k){let D=u.createBindGroup(h.layout,{input:k.texture,cellTex:_,params:g.buffer});R=E.with(D),U=!0}},getComputeNodes:()=>{let L=i(e.quality.name);return g.write({inputWidth:y,inputHeight:b,quality:typeof L==\"number\"?L:12}),[()=>{U&&R.dispatchThreads(P,C)}]}}},gpu:{fragment:t=>{let{childNode:s,ctx:r,computeOutputs:o,convertToTexture:a}=t;if(!s)return xt;let i=o?.jpegCellTexture,l=o?.childTexture;return!i||!l?W(Yt,\"unpremultiplyAlpha\",[a(s).sample(r.uv)]):mue(i,l,t)}}}}var _G=H({name:\"CompressionArtifacts\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Simulates lossy JPEG compression \\u2014 8\\xD78 DCT block quantization, blockiness, ringing and color bleed\",requiresRTT:!0,requiresChild:!0,props:{quality:{default:12,description:\"JPEG quality (1 = heavily destroyed, 100 = near lossless)\",ui:{type:[\"range\",\"map\"],min:1,max:100,step:1,label:\"Quality\",group:\"Effect\"}}},..._ue({quality:T(\"quality\")})});var fG=H({name:\"ConcentricSpin\",role:\"warp\",category:\"Distortions\",description:\"Concentric rings that each rotate the underlying image by different amounts\",boundingBoxDeclaration:{aspectRatio:null},animatedTime:{speed:\"speed\"},props:{intensity:{default:20,description:\"Maximum rotation angle per ring\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},rings:{default:8,description:\"Number of concentric rings\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Rings\",group:\"Effect\"}},smoothness:{default:.03,description:\"Softness of transitions between rings\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Smoothness\",group:\"Effect\"}},seed:{default:0,description:\"Randomization seed for per-ring rotation variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},speed:{default:.1,description:\"Speed of continuous ring rotation\",ui:{type:\"range\",min:-5,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},speedRandomness:{default:.5,description:\"How much each ring varies in rotation speed and direction\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Speed Randomness\",group:\"Animation\"}},edges:fr(\"mirror\",\"How to handle edges when distortion pushes content out of bounds\"),center:zo(\"Center point of the concentric rings\",{label:\"Center Position\"})},map:sU({center:T(\"center\"),intensity:T(\"intensity\"),rings:T(\"rings\"),smoothness:T(\"smoothness\"),seed:T(\"seed\"),speedRandomness:T(\"speedRandomness\")}),missingChildMessage:\"You must pass a child component into the ConcentricSpin shader.\"});var vG=H({name:\"ConicGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Colors sweep in a full circle around a center point, like a color wheel\",acceptsUVContext:!0,props:{colorA:{default:\"#FF0080\",transform:ce,description:\"Starting color of the sweep\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#00BFFF\",transform:ce,description:\"Ending color of the sweep (wraps back to Color A)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),center:{default:{x:.5,y:.5},transform:Xe,description:\"Center point of the sweep\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},rotation:{default:0,description:\"Rotation offset in degrees \\u2014 shifts where Color A begins\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},repeat:{default:1,description:\"Number of times the gradient repeats around the circle. Values above 1 create a starburst pattern.\",ui:{type:[\"range\",\"map\"],min:1,max:24,step:1,label:\"Repeat\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(AR(Oi.conic({center:T(\"center\"),rotation:T(\"rotation\")}),T(\"repeat\")),Us(T(\"colorSpace\")))});var fue=e=>e===\"alpha\"?1:0,vue=e=>e===\"custom\"?1:0,hG=H({name:\"ContourLines\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Draw topographical contour lines based on luminance or alpha\",blendWithChildren:!1,props:{levels:{default:5,description:\"Number of contour levels\",ui:{type:[\"range\",\"map\"],min:2,max:30,step:1,label:\"Levels\",group:\"Effect\"}},lineWidth:{default:2,description:\"Width of the contour lines in pixels\",ui:{type:[\"range\",\"map\"],min:.5,max:5,step:.1,label:\"Line Width\",group:\"Effect\"}},softness:{default:0,description:\"Edge softness of the lines (0 = sharp, 1 = soft)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},gamma:{default:.5,description:\"Contour distribution. <1 clusters in bright, >1 clusters in dark\",ui:{type:[\"range\",\"map\"],min:.1,max:2,step:.01,label:\"Gamma\",group:\"Effect\"}},invert:{default:!1,description:\"Invert the source values\",transform:rs,ui:{type:\"checkbox\",label:\"Invert\",group:\"Effect\"}},source:{default:\"luminance\",description:\"Use luminance or alpha channel for contours\",transform:fue,compileTime:!0,ui:{type:\"select\",options:[{label:\"Luminance\",value:\"luminance\"},{label:\"Alpha\",value:\"alpha\"}],label:\"Source\",group:\"Effect\"}},colorMode:{default:\"source\",description:\"Use source image colors or custom colors\",transform:vue,compileTime:!0,ui:{type:\"select\",options:[{label:\"Source\",value:\"source\"},{label:\"Custom\",value:\"custom\"}],label:\"Color Mode\",group:\"Colors\"}},lineColor:{default:\"#000000\",description:\"Color of the contour lines (custom mode)\",transform:ce,ui:{type:\"color\",label:\"Line Color\",group:\"Colors\",condition:{colorMode:\"custom\"}}},backgroundColor:{default:\"transparent\",description:\"Background color (custom mode)\",transform:ce,ui:{type:\"color\",label:\"Background Color\",group:\"Colors\",condition:{colorMode:\"custom\"}}}},effect:p8({source:T(\"source\"),levels:T(\"levels\"),lineWidth:T(\"lineWidth\"),softness:T(\"softness\"),gamma:T(\"gamma\"),invert:T(\"invert\"),colorMode:T(\"colorMode\"),lineColor:T(\"lineColor\"),backgroundColor:T(\"backgroundColor\")})});var gG=H({name:\"CornerPin\",role:\"warp\",category:\"Distortions\",description:\"Pin each corner of the content to an arbitrary position for a free perspective warp\",boundingBoxDeclaration:{aspectRatio:null},props:{topLeft:{default:{x:0,y:0},transform:Xe,description:\"Position of the top-left corner\",ui:{type:\"position\",label:\"Top Left\",group:\"Corners\"}},topRight:{default:{x:1,y:0},transform:Xe,description:\"Position of the top-right corner\",ui:{type:\"position\",label:\"Top Right\",group:\"Corners\"}},bottomLeft:{default:{x:0,y:1},transform:Xe,description:\"Position of the bottom-left corner\",ui:{type:\"position\",label:\"Bottom Left\",group:\"Corners\"}},bottomRight:{default:{x:1,y:1},transform:Xe,description:\"Position of the bottom-right corner\",ui:{type:\"position\",label:\"Bottom Right\",group:\"Corners\"}},amount:{default:1,description:\"Blends the warp in and out \\u2014 0 returns the content to its original rectangle, 1 fully pins the corners\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Amount\",group:\"Effect\"}},edges:fr(\"transparent\",\"How to handle areas outside the pinned quad\")},map:eU({topLeft:T(\"topLeft\"),topRight:T(\"topRight\"),bottomRight:T(\"bottomRight\"),bottomLeft:T(\"bottomLeft\"),amount:T(\"amount\")})});var yG=H({role:\"shape\",name:\"Crescent\",description:\"Crescent moon shape \\u2014 an outer circle with an inner circle subtracted\",shape:{distance:({x:e,y:t},s)=>fR(e,t,s(\"radius\"),s(\"innerRatio\"),s(\"offset\")),colorDescription:\"Fill color of the crescent\",centerDescription:\"Center position of the crescent\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.3,description:\"Outer circle radius\",ui:{type:\"range\",min:.05,max:1,step:.01,label:\"Size\",group:\"Shape\"}},innerRatio:{default:.8,description:\"Inner (bite) circle radius as a fraction of outer radius\",ui:{type:\"range\",min:.3,max:1.2,step:.01,label:\"Bite Size\",group:\"Shape\"}},offset:{default:.2,description:\"Horizontal distance the bite circle is shifted from center\",ui:{type:\"range\",min:.01,max:.5,step:.01,label:\"Bite Offset\",group:\"Shape\"}}}}});var bG=H({role:\"shape\",name:\"Cross\",description:\"Plus / cross shape with adjustable arm length, width, and rounding\",shape:{distance:({x:e,y:t},s)=>pR(e,t,s(\"radius\"),s(\"thickness\"),s(\"rounding\")),colorDescription:\"Fill color of the cross\",centerDescription:\"Center position of the cross\",rotationDescription:\"Rotation in degrees (45\\xB0 turns a plus into an \\xD7)\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.35,description:\"Arm half-length \\u2014 distance from center to the end of each arm\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Arm Length\",group:\"Shape\"}},thickness:{default:.08,description:\"Arm half-width \\u2014 controls how wide each arm is\",ui:{type:\"range\",min:.01,max:.5,step:.005,label:\"Arm Width\",group:\"Shape\"}},rounding:{default:0,description:\"Corner rounding \\u2014 rounds the arm ends and concave corners\",ui:{type:\"range\",min:0,max:.2,step:.005,label:\"Rounding\",group:\"Shape\"}}}}});var xG=H({name:\"CRTScreen\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Retro CRT monitor simulation with scanlines\",props:{pixelSize:{default:128,description:\"Density of the RGB phosphor stripes \\u2014 about half this many across the canvas width (higher = smaller, finer pixels)\",ui:{type:[\"range\",\"map\"],min:8,max:128,step:1,label:\"Pixel Size\",group:\"Effect\"}},colorShift:{default:1,description:\"Chromatic aberration amount\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Color Shift\",group:\"Effect\"}},scanlineIntensity:{default:.3,description:\"Strength of horizontal scanlines\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Scanline Intensity\",group:\"Effect\"}},scanlineFrequency:{default:200,description:\"Number of scanlines across screen\",ui:{type:[\"range\",\"map\"],min:100,max:800,step:10,label:\"Scanline Frequency\",group:\"Effect\"}},brightness:{default:1,description:\"Screen brightness boost\",ui:{type:[\"range\",\"map\"],min:.5,max:2,step:.1,label:\"Brightness\",group:\"Adjustments\"}},contrast:{default:1,description:\"Screen contrast enhancement\",ui:{type:[\"range\",\"map\"],min:.5,max:2,step:.1,label:\"Contrast\",group:\"Adjustments\"}},vignetteIntensity:{default:1,description:\"Strength of corner darkening effect (0 = off)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Vignette Intensity\",group:\"Effect\"}},vignetteRadius:{default:.5,description:\"How far the vignette extends inward (0 = edges only, 1 = reaches center)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Vignette Radius\",group:\"Effect\"}}},effect:$o(dU({amount:T(\"colorShift\")}),[_U({brightness:T(\"brightness\"),contrast:T(\"contrast\")}),fU({frequency:T(\"scanlineFrequency\"),intensity:T(\"scanlineIntensity\")}),vU({pitch:T(\"pixelSize\")}),hU({radius:T(\"vignetteRadius\"),intensity:T(\"vignetteIntensity\")}),gU()])});var{insideMask:hue}=Xh,{unpremultiplyAlpha:j_}=Qk,gue=bt,yue=Po,bue=JSON.stringify({type:\"sphere3D\",radius:.35}),AG=H({name:\"Crystal\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Diamond-like crystal lens with faceted refraction.\",requiresRTT:!0,requiresChild:!0,...Ts({pattern:\"triplanar\",child:\"required\",surface:(e,t)=>{let{uniforms:s,propValues:r,ctx:o}=t,a=e.childTexture,i=e.volumetric,l=Lr(e,t,{scale:s.scale}),c=z(e.sdfUV,\"suv\"),d=z(Ce(o.viewportSize.member(\"x\"),o.viewportSize.member(\"y\")),\"aspect\"),u=z(it(v(s.edgeSoftness,.5),.001),\"sharp\"),{sdf:p,pxH:_}=l,f=z(s.center.member(\"x\"),\"centerPosX\"),h=z(ne(1,s.center.member(\"y\")),\"centerPosY\"),g=Ln(l),y=g.member(\"x\"),b=g.member(\"y\"),x=z(W(hue,\"insideMask\",[p,u,_,It(1.5)]),\"rb1\"),P=v(s.lightAngle,gue),C=z(I(Do(P),v(ne(f,.5),3)),\"lx\"),E=z(I(Vt(P),v(ne(h,.5),3)),\"ly\"),R=bg(C,E,-.75,\"kl1\"),U=R.member(\"L\"),L=R.member(\"H\"),k=bg(v(E,-1),C,-.4,\"kl2\"),D=k.member(\"L\"),O=k.member(\"H\"),F=Ge(Ce(v(p,-1),.15),0,1),q=z(v(ne(1,ot(0,.03,p)),.4),\"outerWarp\"),Y=v(s.refraction,.15),V=z(Ce(v(v(v(y,-1),Y),q),d),\"haloOffX\"),X=z(v(v(v(b,-1),Y),q),\"haloOffY\"),Q=go(e,l,{uv:c}),te=Q.member(\"x\"),J=Q.member(\"y\"),oe=z(Ce(yue,s.facets),\"sAngle\"),le=z(g2(I(te,.5),I(J,.5),oe),\"fUv\"),se=z(Ce(ho(I(v(te,te),v(J,J))),.35),\"crystalRNorm\"),Te=z(ne(1,ot(.22,.32,se)),\"tableMask\"),de=I(1,v(Ge(se,0,1),.6)),xe=z(ne(1,v(Te,.9)),\"tableSuppress\"),Ae;if(i)Ae=Mc(l,4,\"nSurf\");else{let Af=z(v(v(ne(1,ot(0,1,F)),1.7),ne(1,Te)),\"bevelSlope\");Ae=z(Os(Qe(v(y,Af),v(b,Af),-1)),\"nSurf\")}let De=Fi(Ae),Ee=.02,ze=z(v(v(s.facets,1.2),de),\"vScale1\"),Ie=z(v(le,ze),\"fUvS1\"),ke=bp(N_,Ie,Ee,\"facet1\"),Me=ke.dx,we=ke.dy,Ve=z(it(ho(I(v(Me,Me),v(we,we))),.001),\"gLen1\"),qe=z(Ce(Me,Ve),\"nx1\"),st=z(Ce(we,Ve),\"ny1\"),pt=z(Xr(Ie),\"cellId1\"),Ze=z(Qr(v(Vt(I(v(pt.member(\"x\"),12.9898),v(pt.member(\"y\"),78.233))),43758.5453)),\"cellRand\"),nt=z(Os(I(Ae,Qe(v(qe,.55),v(st,.55),0))),\"nF1\"),ht=z($t(Ae,U),\"ndlS\"),yt=z(v(ne($t(nt,U),ht),2.2),\"ndl1\"),St=bp(N_,z(I(v(le,v(ze,1.7)),rt(3.7,1.2)),\"fUvS2\"),Ee,\"facet2\"),Mt=St.dx,Rt=St.dy,Kt=z(it(ho(I(v(Mt,Mt),v(Rt,Rt))),.001),\"gLen2\"),Wt=z(Ce(Mt,Kt),\"nx2\"),ls=z(Ce(Rt,Kt),\"ny2\"),us=z(Os(I(Ae,Qe(v(Wt,.4),v(ls,.4),0))),\"nF2\"),os=z(v(ne($t(us,D),$t(Ae,D)),2.2),\"ndl2\"),bs=Qe(0,0,1),hs=z(Ge(v(s.refraction,.8),0,1.6),\"facetRefrAmp\"),gs=z(ig(bs,z(Os(I(I(Ae,Qe(v(v(v(qe,.75),hs),xe),v(v(v(st,.75),hs),xe),0)),Qe(v(v(Wt,.55),hs),v(v(ls,.55),hs),0))),\"nRefr\"),Ce(1,I(1,v(s.refraction,.55)))),\"refr\"),Gs=z(i?Ge(v(l.s0.member(\"x\"),-1),0,.6):v(Ge(v(l.s0.member(\"x\"),-1),0,.12),1.6),\"thickEff\"),Ss=z(v(v(v(Gs,I(.55,v(Ze,.9))),s.scale),x),\"offMag\"),or=z(I(Ce(v(Ce(gs.member(\"x\"),it(gs.member(\"z\"),.25)),Ss),d),V),\"totalOffX\"),yr=z(I(v(Ce(gs.member(\"y\"),it(gs.member(\"z\"),.25)),Ss),X),\"totalOffY\"),lr=z(Lo(gs,z(Os(Qe(v(Wt,.7),v(ls,.7),-1)),\"nBack\")),\"bounce\"),Ur=z(v(v(v(Gs,s.scale),x),.8),\"bounceMag\"),so=Ce(v(Ce(lr.member(\"x\"),it(ms(lr.member(\"z\")),.3)),Ur),d),ro=v(Ce(lr.member(\"y\"),it(ms(lr.member(\"z\")),.3)),Ur),_e=z(v(v(I(v(De,.5),.18),I(v(Ze,.7),.3)),x),\"innerW\"),We=I(te,v(v(Ce(gs.member(\"x\"),it(gs.member(\"z\"),.25)),Gs),1.2)),Le=I(J,v(v(Ce(gs.member(\"y\"),it(gs.member(\"z\"),.25)),Gs),1.2)),Be=z(I(v(g2(I(We,.5),I(Le,.5),oe),v(ze,1.4)),rt(9.1,4.7)),\"fUvS3\"),Oe=bp(N_,Be,Ee,\"facet3\"),tt=Oe.dx,_t=Oe.dy,Bt=z(it(ho(I(v(tt,tt),v(_t,_t))),.001),\"gLen3\"),Dt=z(Ce(tt,Bt),\"nx3\"),Nt=z(Ce(_t,Bt),\"ny3\"),Ks=z(Xr(Be),\"cellId3\"),Ds=z(Qr(v(Vt(I(v(Ks.member(\"x\"),31.727),v(Ks.member(\"y\"),57.131))),43758.5453)),\"cellRand3\"),ar=z(v(v(Ge(v(Gs,2.5),0,1),Ge(v(s.refraction,1.2),0,1)),x),\"w3\"),Xo=z(I(v(I(v(Dt,C),v(Nt,E)),.5),.5),\"wedgeLit\"),$r=v(v(I(v(Ds,.9),.55),I(v(Xo,.7),.65)),I(v(ot(.15,.7,Bt),.45),.55)),cr=v(v(ot(.75,1,v(Xo,I(Ds,.4))),ar),.8),za=I(f,Ce(ne(o.uv.member(\"x\"),f),s.innerZoom)),ia=I(h,Ce(ne(o.uv.member(\"y\"),h),s.innerZoom)),Ra=z(I(za,or),\"lensX\"),Wn=z(I(ia,yr),\"lensY\"),Uc=Ge(yt,0,1),Gp=Ge(v(yt,-1),0,1),Fp=it(ne(I(1,v(Uc,s.highlights)),v(Gp,s.shadows)),.02),Oc=Ge(os,0,1),$d=Ge(v(os,-1),0,1),af=ne(I(1,v(Oc,v(s.highlights,.5))),v($d,v(s.shadows,.5))),qi=ne(I(1,v(v(Ge(ht,0,1),s.highlights),.4)),v(v(Ge(v(ht,-1),0,1),s.shadows),.6)),Qs=v(v(Fp,af),qi),Ip=v(s.dispersion,.12),nf=z(v(or,Ip),\"chrOffX\"),lf=z(v(yr,Ip),\"chrOffY\"),cf=I(v(et(ot(.2,.8,Ve),1,Te),.4),.6),vy=v(v(v(I(Qs,v(Te,.25)),cf),et(It(1),$r,ar)),s.brightness),df=z(Ge($t(nt,L),0,1),\"ndh1\"),hy=Ge($t(us,O),0,1),gy=v(ts(df,110),2.2),yy=v(ts(hy,56),.9),by=v(ot(.965,.995,df),3),uf=z(v(v(I(I(I(gy,yy),by),cr),s.highlights),s.brightness),\"flashContrib\"),pf=v(v(v(ts(De,et(It(6),It(1.5),Ge(v(s.fresnelSoftness,.5),0,1))),s.fresnel),2),x),xy=v(s.fresnelColor.member(\"rgb\"),pf),mf=I(v(I(v(y,C),v(b,E)),.5),.5),Vi=z(v(v(ne(Ge(v(Ce(v(ne(p,_),-1),u),16),0,1),Ge(v(Ce(v(p,-1),u),16),0,1)),mf),.35),\"rb2\"),_f=z(ot(0,1,x),\"transition\"),ff=Number(r.cutout)>0,vf=rt(I(o.uv.member(\"x\"),V),I(o.uv.member(\"y\"),X)),hf=ff?o.uv:vf,Ay=z(W(j_,\"unpremultiplyAlpha\",[a.sample(rt(I(Ra,nf),I(Wn,lf)))]),\"sampledR\"),qn=z(W(j_,\"unpremultiplyAlpha\",[a.sample(rt(Ra,Wn))]),\"sampledG\"),Da=z(W(j_,\"unpremultiplyAlpha\",[a.sample(rt(ne(Ra,nf),ne(Wn,lf)))]),\"sampledB\"),Xd=z(W(j_,\"unpremultiplyAlpha\",[a.sample(rt(I(Ra,so),I(Wn,ro)))]),\"innerSample\"),gf=z(W(j_,\"unpremultiplyAlpha\",[a.sample(hf)]),\"baseColor\"),yf=et(Qe(Ay.member(\"x\"),qn.member(\"y\"),Da.member(\"z\")),Qe(Xd.member(\"x\"),Xd.member(\"y\"),Xd.member(\"z\")),kt(_e)),bf=qn.member(\"w\"),Hd=z(v(yf,vy),\"litRgb\"),Yp=Qe(.299,.587,.114),xf=$t(Hd,Yp),Gc=z(et(Hd,s.tintColor.member(\"rgb\"),kt(s.tintIntensity)),\"tinted\"),Wp=v(Gc,Ce(xf,it($t(Gc,Yp),1e-4))),Fc=z(et(gf,Ot(I(I(I(br(Zo(s.tintPreserveLuminosity,.5),Wp,Gc),kt(uf)),xy),kt(Vi)),bf),Ot(_f)),\"composited\"),qp=ff?_f:It(1);return Ot(Fc.member(\"xyz\"),v(Fc.member(\"w\"),qp))}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the crystal shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the crystal shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the crystal shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},cutout:{default:!1,transform:rs,description:\"Cut out alpha outside the crystal shape\",compileTime:!0,ui:{type:\"checkbox\",label:\"Cutout\",group:\"Crystal\"}},...gr({refraction:{description:\"How strongly the crystal refracts content beneath\",ui:{type:\"range\",max:3,group:\"Crystal\"}},dispersion:{default:.5,description:\"Prismatic rainbow dispersion \\u2014 splits light into spectral colors\",ui:{type:\"range\",max:2,group:\"Crystal\"}}}),facets:{default:5,description:\"Symmetry order \\u2014 how many times the facet pattern repeats around the center\",ui:{type:\"range\",min:3,max:24,step:1,label:\"Facets\",group:\"Crystal\"}},...gr({fresnel:{default:.05,description:\"Fresnel rim glow intensity around the crystal boundary\",ui:{type:\"range\"}},fresnelSoftness:{default:1,ui:{type:\"range\",max:2}},fresnelColor:!0,edgeSoftness:{default:0,description:\"Softness of the crystal boundary edge\",ui:{type:\"range\",group:\"Crystal\"}}}),innerZoom:{default:1.5,description:\"Magnification of content seen through the crystal\",ui:{type:\"range\",min:.5,max:3,step:.01,label:\"Inner Zoom\",group:\"Crystal\"}},...gr({lightAngle:{default:270,description:\"Light direction angle in degrees\",ui:{group:\"Lighting\"}}}),highlights:{default:.5,description:\"Additive brightness on light-facing facets \\u2014 never darkens\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Highlights\",group:\"Lighting\"}},shadows:{default:.3,description:\"Darkening on shadow-facing facets \\u2014 never brightens\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Shadows\",group:\"Lighting\"}},brightness:{default:1.2,description:\"Overall crystal brightness \\u2014 higher values push facets toward brilliant white\",ui:{type:\"range\",min:.5,max:3,step:.01,label:\"Brightness\",group:\"Lighting\"}},tintColor:{default:\"#e8e0ff\",transform:ce,description:\"Crystal body tint color\",ui:{type:\"color\",label:\"Tint Color\",group:\"Tint\"}},tintIntensity:{default:0,description:\"How much tint color is applied to the crystal interior\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Tint Intensity\",group:\"Tint\"}},tintPreserveLuminosity:{default:!0,transform:rs,description:\"Preserve original brightness when tinting\",ui:{type:\"checkbox\",label:\"Preserve Luminosity\",group:\"Tint\"}},shape:{default:bue,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var wG=H({name:\"CurlNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Swirling divergence-free flow field that drifts over time\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:2,description:\"Pattern scale (higher = larger patterns)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},...Ja(),...In()},paint:Vs(ua(Qa(HD({rate:.2}),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var xue=sR.grid({resolution:128,history:2,step:[lg.wave({damping:T(\"decay\")}),lg.splat({at:rR({teleportGuard:\"on\"}),amount:oR({max:2}),radius:T(\"radius\")})],derive:{displacement:lg.gradient()},rest:{settlesWhen:\"derived-from-damping\"}}),TG=H({name:\"CursorRipples\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Fluid-like ripple distortion\",props:{intensity:{default:10,description:\"Strength of the ripple distortion\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Intensity\",group:\"Effect\"}},decay:{default:10,description:\"How quickly ripples fade (higher = faster)\",ui:{type:\"range\",min:0,max:20,step:.1,label:\"Decay\",group:\"Effect\"}},radius:{default:.5,description:\"Radius of cursor influence\",ui:{type:\"range\",min:.1,max:1,step:.1,label:\"Radius\",group:\"Effect\"}},chromaticSplit:{default:1,description:\"RGB channel separation along ripple edges\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.1,label:\"Chromatic Split\",group:\"Effect\"}},edges:{default:\"stretch\",description:\"How to handle edges when distortion pushes content out of bounds\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},effect:Qz(xue.output(\"displacement\"),{strength:T(\"intensity\"),chromatic:T(\"chromaticSplit\"),edges:T(\"edges\")})});var Mp=64,SG=_o(1),Aue=.2,wue=1.5,Tue=_z({maxPoints:Mp,subdivisions:3,name:\"cursorTrailScan\"});function Sue(e){let{createDataTexture:t,registerMediaTexture:s,onBeforeRender:r,onCleanup:o,onResize:a,getCpuValue:i,dimensions:l}=e,c=[],d=new Uint16Array(Mp*4);for(let b=0;b<Mp;b++)d[b*4+2]=SG;let u=t({width:Mp,height:1,format:\"rgba16float\",data:d,label:\"cursortrail-points\"});o(()=>u.destroy());let p=s(()=>u.texture),_=Sl({minDrag:.001,teleportGuard:Number.POSITIVE_INFINITY}),f=Math.max(1,Math.round(l.width)),h=Math.max(1,Math.round(l.height));a(({width:b,height:x})=>{f=Math.max(1,Math.round(b)),h=Math.max(1,Math.round(x))});let g=0,y=!1;return r(b=>{let{pointer:x,deltaTime:P}=b,C=Math.max(0,P??0),E=Math.min(C,.1),R=i(\"length\")??.5,U=(i(\"radius\")??.5)*.1,L=f/h,k=_.update(x,E),D=Math.min(C,.25)/Math.max(.1,R);for(let F of c)F.age=Math.min(1,F.age+D);for(;c.length>0&&c[0].age>=1;)c.shift();if(k.dragDist>.001){let F=Math.sqrt(k.dx*L*(k.dx*L)+k.dy*k.dy),q=Math.min(1,Math.max(Aue,Math.sqrt(k.smoothSpeed/wue)));if(c.length===0)c.push({x:k.prevX,y:k.prevY,age:0,link:0,width:q}),c.push({x:k.x,y:k.y,age:0,link:1,width:q}),g=F;else{let Y=c[c.length-1];if(Y.x=k.x,Y.y=k.y,Y.age=0,Y.width=q,g+=F,g>=Math.max(.006,U*.5)){let V=c.length;V>=3&&c[V-2].link===1&&(c[V-2].x=.25*c[V-3].x+.5*c[V-2].x+.25*c[V-1].x,c[V-2].y=.25*c[V-3].y+.5*c[V-2].y+.25*c[V-1].y),c.push({x:k.x,y:k.y,age:0,link:1,width:q}),g=0}}for(;c.length>Mp-1;)c.shift()}let O=c.length>0;if(O||y){let F=c.length>0?c.length+1:0;for(let q=0;q<Mp;q++){let Y=q*4;if(q<F){let V=c[Math.min(q,c.length-1)];d[Y]=_o(V.x),d[Y+1]=_o(V.y),d[Y+2]=_o(V.age),d[Y+3]=_o(q===c.length||V.link===1?V.width:-V.width)}else d[Y]=0,d[Y+1]=0,d[Y+2]=SG,d[Y+3]=0}u.write(d)}y=O}),p}function Pue(e,t){let{propValues:s,uniforms:r}=e,o=s.colorSpace??0;if((s.stopCount??0)>1)return En(t,{colorsArray:r.colorsArray,positionsArray:r.positionsArray,convertedColorsArray:r.convertedColorsArray,stopCount:r.stopCount},o);let a=Mn;return W(a.mixColorsVariants[o]??a.mixColorsLinear,\"mixColors\",[r.colorA,r.colorB,t])}var PG=H({name:\"CursorTrail\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Animated trail effect that tracks cursor movement\",usesPointer:!0,props:{colorA:{default:\"#00aaff\",transform:ce,description:\"Color of fresh trails\",ui:{type:\"color\",label:\"Start Color\",group:\"Colors\"}},colorB:{default:\"#ff00aa\",transform:ce,description:\"Color trails transition to as they fade\",ui:{type:\"color\",label:\"End Color\",group:\"Colors\"}},stops:Ms(),radius:{default:.5,description:\"Base radius of the trail stroke\",ui:{type:\"range\",min:.5,max:2,step:.1,label:\"Radius\",group:\"Effect\"}},length:{default:.5,description:\"How long the trail persists (in seconds)\",ui:{type:\"range\",min:.1,max:2,step:.1,label:\"Trail Length\",group:\"Animation\"}},shrink:{default:1,description:\"How much the stroke tapers as it fades out (0 = no taper, 1 = full taper)\",ui:{type:\"range\",min:0,max:1,step:.1,label:\"Shrink Amount\",group:\"Effect\"}},softness:{default:0,description:\"Edge softness of the trail (0 = crisp paint edge, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},gpu:{fragment:e=>{let{ctx:t,uniforms:s,gpu:r}=e;if(!r?.root)return xt;let o=W(Tue,\"cursorTrailScan\",[Sue(e).accessor(),t.uv,t.aspect,s.radius,s.shrink,s.softness,t.viewportSize.member(\"y\")]),a=o.member(\"x\"),i=o.member(\"y\"),l=Pue(e,a);return Ct(l.member(\"rgb\"),l.member(\"a\").mul(i))}}});var CG=768,MG=\"rgba16float\",I2=Iz({res:CG,format:MG,namePrefix:\"dataMosh\",blockMix:{coarseScale:2.6,coarsePick:.35},generationLoss:{levels:18,amount:.12,decay:.9985}}),Cue=I2.kernel,EG=H({name:\"DataMosh\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Corrupted-codec motion smearing \\u2014 macroblocks lock in place and drag their pixels across the frame in liquid trails, each recovering on its own clock, like a video stream that lost its keyframes\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:.7,description:\"How much of the image locks and smears \\u2014 the fraction of corrupted macroblocks\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Mosh\"}},blockSize:{default:48,description:\"Macroblock size \\u2014 the granularity of the corruption\",ui:{type:\"range\",min:30,max:150,step:1,label:\"Block Size\",group:\"Mosh\"}},drift:{default:.35,description:\"Motion vector strength \\u2014 how fast corrupted areas drag their pixels away\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Drift\",group:\"Mosh\"}},churn:{default:.4,description:\"How often each block re-rolls its fate \\u2014 low values let corrupted regions melt for a long time before recovering\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Churn\",group:\"Mosh\"}},blend:{default:1,description:\"Blend between the live image and the moshed stream\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Blend\",group:\"Mosh\"}},speed:{default:1,description:\"Simulation speed. 0 freezes the decay in place.\",ui:{type:\"range\",min:0,max:4,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed for the corruption layout\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}}},...Lg((e,t)=>{let{getCpuValue:s}=e;return{size:CG,format:MG,speedProp:\"speed\",paramsSchema:I2.Params,bindGroups:({childTexture:r,display:o,paramsBuffer:a},i,l)=>t.createBindGroup(I2.layout,{src:r,prev:i.state,next:l.state,display:o,params:a}),step:Cue,values:({dt:r,localTime:o})=>({time:o,dt:r,seed:s(\"seed\")??0,intensity:s(\"intensity\")??.7,blockSize:s(\"blockSize\")??48,drift:s(\"drift\")??.35,churn:s(\"churn\")??.4})}}),gpu:{fragment:({childNode:e,ctx:t,computeOutputs:s,uniforms:r,convertToTexture:o})=>{if(!e)return xt;let a=s?.display,i=(s?.childTexture??o(e)).sample(t.uv);return a?W(Yt,\"unpremultiplyAlpha\",[ea(i,a.sample(t.uv,\"linearClamp\"),r.blend)]):W(Yt,\"unpremultiplyAlpha\",[i])}}});var kG=H({name:\"DiamondGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Diamond-shaped gradient radiating from a center point using Manhattan distance\",acceptsUVContext:!0,props:{colorA:{default:\"#4ffb4a\",transform:ce,description:\"Color at the center of the diamond\",ui:{type:\"color\",label:\"Color A (Center)\",group:\"Colors\"}},colorB:{default:\"#4f1238\",transform:ce,description:\"Color at the outer edges of the diamond\",ui:{type:\"color\",label:\"Color B (Edge)\",group:\"Colors\"}},stops:Ms(),center:{default:{x:.5,y:.5},transform:Xe,description:\"Center point of the diamond\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},size:{default:.7,description:\"Extent of the gradient \\u2014 controls how far Color A reaches before transitioning to Color B\",ui:{type:[\"range\",\"map\"],min:.01,max:2,step:.01,label:\"Size\",group:\"Effect\"}},rotation:{default:0,description:\"Rotation in degrees \\u2014 tilts the diamond into a rhombus\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},repeat:{default:1,description:\"Number of times the gradient repeats outward. Values above 1 create concentric diamond or square bands.\",ui:{type:[\"range\",\"map\"],min:1,max:16,step:.5,label:\"Repeat\",group:\"Effect\"}},roundness:{default:0,description:\"Morphs from a sharp diamond (0) to a square (1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Roundness\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(mg(Oi.diamond({center:T(\"center\"),size:T(\"size\"),rotation:T(\"rotation\"),roundness:T(\"roundness\")}),T(\"repeat\")),Us(T(\"colorSpace\")))});var BG=H({name:\"DiamondWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away through a lattice of growing diamonds\",props:{progress:{default:.5,description:\"How far the diamonds have grown (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},size:{default:.15,description:\"Size of each diamond cell as a fraction of the frame width\",ui:{type:[\"range\",\"map\"],min:.02,max:.5,step:.01,label:\"Size\",group:\"Transition\"}},feather:{default:.1,description:\"Softness of each diamond edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Wipe from the cell corners inward instead\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.cells(T(\"size\")).diamond(),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Diamond Wipe shader.\"});var zG=H({name:\"DiffuseBlur\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Grain-like pixel displacement at random\",props:{intensity:{default:30,description:\"Intensity of the diffuse blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},edges:{default:\"stretch\",description:\"How to handle edges when distortion pushes content out of bounds\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}},chromatic:{default:0,description:\"Scatters red and blue separately for a sparkly color grain\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Chromatic\",group:\"Effect\"}}},effect:bU({amount:T(\"intensity\"),edges:T(\"edges\"),chromatic:T(\"chromatic\")})});var Mue={twoAxis:0,directional:1},RG=H({name:\"DisplacementMap\",role:\"filter\",species:\"gather\",category:\"Distortions\",description:\"Distorts child content using another layer's pixels as a displacement map\",boundingBoxDeclaration:{aspectRatio:null},props:{source:{default:\"\",description:\"The layer whose pixels drive the displacement \\u2014 its red/green (or luminance) push the content around\",compileTime:!0,ui:{type:\"layer\",label:\"Source Layer\",group:\"Effect\"}},amount:{default:.3,description:\"Overall displacement strength\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Amount\",group:\"Effect\"}},channelMode:{default:\"twoAxis\",description:\"How the source drives the push \\u2014 red\\u2192X / green\\u2192Y, or luminance along a fixed angle\",compileTime:!0,transform:e=>Mue[e]??0,ui:{type:\"select\",options:[{label:\"Red / Green\",value:\"twoAxis\"},{label:\"Luminance\",value:\"directional\"}],label:\"Channels\",group:\"Effect\"}},angle:{default:0,description:\"Push direction in degrees (used by the Luminance channel mode)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\",condition:{channelMode:\"directional\"}}},edges:{default:\"mirror\",description:\"How to handle edges when distortion pushes content out of bounds\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},effect:lU({source:T(\"source\"),amount:T(\"amount\"),channels:T(\"channelMode\"),angle:T(\"angle\"),edges:T(\"edges\")})});var Eue=e=>({bayer2:0,bayer4:1,bayer8:2,clusteredDot:3,blueNoise:4,whiteNoise:5,floydSteinberg:6})[e]??1,kue=e=>e===\"source\"?1:0,DG=iD({size:T(\"pixelSize\")}),LG=H({name:\"Dither\",role:\"filter\",species:\"gather\",category:\"Stylize\",description:\"Dithering effect with multiple pattern options\",blendWithChildren:!1,boundingBoxDeclaration:{aspectRatio:null},props:{pattern:{default:\"bayer4\",transform:Eue,compileTime:!0,description:\"Dithering pattern algorithm\",ui:{type:\"select\",options:[{label:\"Bayer 2x2\",value:\"bayer2\"},{label:\"Bayer 4x4\",value:\"bayer4\"},{label:\"Bayer 8x8\",value:\"bayer8\"},{label:\"Clustered Dot\",value:\"clusteredDot\"},{label:\"Blue Noise\",value:\"blueNoise\"},{label:\"White Noise\",value:\"whiteNoise\"},{label:\"Floyd-Steinberg\",value:\"floydSteinberg\"}],label:\"Pattern\",group:\"Effect\"}},pixelSize:{default:4,description:\"Size of dithering pixels\",ui:{type:\"range\",min:1,max:20,step:1,label:\"Pixel Size\",group:\"Effect\"}},threshold:{default:.5,description:\"Luminance threshold for dithering\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Threshold\",group:\"Effect\"}},spread:{default:1,description:\"How much of the luminance range participates in dithering (lower = more solid areas)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Spread\",group:\"Effect\"}},colorMode:{default:\"custom\",transform:kue,compileTime:!0,description:\"How colors are determined\",ui:{type:\"select\",options:[{label:\"Custom Colors\",value:\"custom\"},{label:\"Source Colors\",value:\"source\"}],label:\"Color Mode\",group:\"Colors\"}},colorA:{default:\"transparent\",transform:ce,description:\"Dark color for dithering\",ui:{type:\"color\",label:\"Dark Color\",condition:{colorMode:\"custom\"},group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Light color for dithering\",ui:{type:\"color\",label:\"Light Color\",condition:{colorMode:\"custom\"},group:\"Colors\"}}},effect:cD({grid:DG,levels:lD({grid:DG,pattern:T(\"pattern\"),threshold:T(\"threshold\"),spread:T(\"spread\")}),mode:T(\"colorMode\"),colors:[T(\"colorA\"),T(\"colorB\")]})});var UG=H({name:\"DotGrid\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Grid of dots with optional twinkling animation\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{color:{default:\"#ffffff\",description:\"The color of the dot\",transform:ce,ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},density:{default:30,description:\"The number of dots along the canvas height (the width fits as many as the aspect ratio allows)\",ui:{type:\"range\",min:1,max:200,step:1,label:\"Density\",group:\"Effect\"}},dotSize:{default:.3,description:\"The size of each dot, zero (0) being invisible, one (1) filled the grid with no gaps\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Dot Size\",group:\"Effect\"}},offset:{default:0,description:\"Horizontal stagger of alternating rows (0.5 = classic polka-dot brick offset)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Row Offset\",group:\"Effect\"}},speed:{default:0,description:\"Animates the rows drifting horizontally (0 = static)\",ui:{type:\"range\",min:-3,max:3,step:.01,label:\"Speed\",group:\"Animation\"}},speedVariance:{default:.3,description:\"Per-row random speed variance for irregular drifting motion\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Speed Variance\",group:\"Animation\"}},twinkle:{default:0,description:\"Intensity of the twinkle effect (0 = off, 1 = full twinkle)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Twinkle\",group:\"Animation\"}}},mapSampleUVs:_g({cells:T(\"density\"),props:[\"dotSize\",\"twinkle\"]}),paint:fp(T(\"color\"),KR({density:T(\"density\"),dotSize:T(\"dotSize\"),offset:T(\"offset\"),speedVariance:T(\"speedVariance\"),twinkle:T(\"twinkle\")}))});var OG=H({name:\"DropShadow\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Adds a soft shadow behind the child content based on its alpha silhouette\",props:{color:{default:\"#000000\",transform:ce,description:\"Shadow color\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},distance:{default:.1,description:\"How far the shadow is offset from the content\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Distance\",group:\"Effect\"}},angle:{default:135,description:\"Direction the shadow is cast (compass degrees: 0=up, 90=right, 135=lower-right, 180=down)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},blur:{default:5,description:\"Shadow softness (blur radius in pixels)\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.5,label:\"Blur\",group:\"Effect\"}},intensity:{default:.5,description:\"Shadow intensity \\u2014 how strong/visible the shadow is\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}},cutout:{default:!1,transform:rs,compileTime:!0,description:\"Hide the original layer and show only the shadow\",ui:{type:\"checkbox\",label:\"Cutout\",group:\"Effect\"}}},effect:$o(UU(),[FU({coverage:GU({at:OU({angle:T(\"angle\"),distance:T(\"distance\")}),blur:T(\"blur\")}),color:T(\"color\"),intensity:T(\"intensity\"),cutout:T(\"cutout\")})])});var GG=H({name:\"Duotone\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Map colors to two tones based on luminance\",props:{colorA:{default:\"#ff0000\",transform:ce,description:\"First color (used for darker areas)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#023af4\",transform:ce,description:\"Second color (used for brighter areas)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},blend:{default:.5,description:\"Blend point between the two colors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Blend\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},effect:m8({colorA:T(\"colorA\"),colorB:T(\"colorB\"),blend:T(\"blend\"),colorSpace:T(\"colorSpace\")})});var FG=H({role:\"shape\",name:\"Ellipse\",description:\"Ellipse with independently adjustable horizontal and vertical radii\",shape:{distance:({x:e,y:t},s)=>iR(e,t,s(\"radiusX\"),s(\"radiusY\")),colorDescription:\"Fill color of the ellipse\",centerDescription:\"Center position of the ellipse\",bounds:{size:{width:\"radiusX\",height:\"radiusY\"}},shapeProps:{radiusX:{default:.35,description:\"Horizontal semi-axis radius\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Width\",group:\"Shape\"}},radiusY:{default:.2,description:\"Vertical semi-axis radius\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Height\",group:\"Shape\"}}}}});var Bue=e=>e===\"spiral\"?2:e===\"line\"?0:1,IG=H({name:\"Engraving\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Copper-plate line engraving \\u2014 the image is redrawn as flowing line work whose weight swells with darkness, lines displaced by the form like a banknote portrait: a single plate, cross-hatched shadow plates, or one continuous spiral cut\",blendWithChildren:!1,props:{style:{default:\"crosshatch\",transform:Bue,compileTime:!0,description:\"The engraving cut: a single line plate, cross-hatched plates building up the shadows, or one continuous spiral\",ui:{type:\"select\",options:[{label:\"Line\",value:\"line\"},{label:\"Cross-Hatch\",value:\"crosshatch\"},{label:\"Spiral\",value:\"spiral\"}],label:\"Style\",group:\"Lines\"}},frequency:{default:90,description:\"Line density \\u2014 how many engraved lines span the height of the canvas\",ui:{type:[\"range\",\"map\"],min:20,max:300,step:1,label:\"Frequency\",group:\"Lines\"}},angle:{default:8,transform:cs,description:\"Direction of the base line work (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Lines\",condition:{style:\"line\"}}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center the spiral coils outward from\",ui:{type:\"position\",label:\"Center\",group:\"Lines\",condition:{style:\"spiral\"}}},relief:{default:.6,description:\"How strongly the image brightness displaces the lines \\u2014 the engraved 'lines climb over the form' effect\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Relief\",group:\"Lines\"}},waviness:{default:.35,description:\"Organic meander of the line work, like a hand-pulled burin stroke\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Waviness\",group:\"Lines\"}},contrast:{default:1.15,description:\"Tonal contrast applied before the lines are cut \\u2014 higher pushes mid-tones toward pure line or pure paper\",ui:{type:[\"range\",\"map\"],min:.25,max:3,step:.01,label:\"Contrast\",group:\"Tone\"}},inkColor:{default:\"#1a1410\",transform:ce,description:\"Color of the engraved ink\",ui:{type:\"color\",label:\"Ink\",group:\"Colors\"}},paperColor:{default:\"#f4eee2\",transform:ce,description:\"Paper color shown between the lines\",ui:{type:\"color\",label:\"Paper\",group:\"Colors\"}}},effect:J8({style:T(\"style\"),frequency:T(\"frequency\"),angle:T(\"angle\"),center:T(\"center\"),relief:T(\"relief\"),waviness:T(\"waviness\"),contrast:T(\"contrast\"),ink:T(\"inkColor\"),paper:T(\"paperColor\")})});var YG=H({name:\"ErosionNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Branching, hydraulic-erosion ridges carved into noise\",acceptsUVContext:!0,props:{...ma(),scale:{default:1.5,description:\"Pattern scale (higher = larger patterns)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},...Ja()},paint:Vs(ua(Qa(gp(XD()),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var WG=H({name:\"Exposure\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Multiplicative exposure (gain) on the child. Unlike additive brightness, it scales values around black \\u2014 blacks stay black while highlights can be pushed past 1.0 to feed HDR bloom and tone-mapping roll-off. Pointwise, so no extra render pass is needed.\",props:{exposure:{default:1,description:\"Brightness multiplier (gain). 1 = unchanged, >1 pushes highlights past white for HDR bloom, <1 darkens.\",recompile:Lt(1),ui:{type:[\"range\",\"map\"],min:0,max:8,step:.1,label:\"Exposure\",group:\"Adjustments\"}}},effect:a8(T(\"exposure\")),identityWhen:cg(\"exposure\",1),missingChildMessage:\"You must pass a child component into the Exposure shader.\"});var VG=jR({angle:T(\"angle\"),density:T(\"density\"),speedVariance:T(\"speedVariance\"),trailLength:T(\"trailLength\"),strokeWidth:T(\"strokeWidth\"),rounding:T(\"rounding\"),balance:T(\"balance\")}),qG=Zr({fill:T(\"colorB\"),stroke:T(\"colorA\"),mask:VG.fade,space:T(\"colorSpace\")}),NG=H({name:\"FallingLines\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Directional falling lines with a leading-to-trailing color fade\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#ffffff\",transform:ce,description:\"Color at the leading edge of each line\",ui:{type:\"color\",label:\"Lead Color\",group:\"Colors\"}},colorB:{default:\"#ffffff00\",transform:ce,description:\"Color at the trailing edge (transparent by default)\",ui:{type:\"color\",label:\"Trail Color\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for interpolation between lead and trail colors\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},angle:{default:90,description:\"Direction of movement in degrees (90=down, 270=up, 0=right, 180=left)\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},speed:{default:.5,description:\"Movement speed\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Speed\",group:\"Animation\"}},speedVariance:{default:.3,description:\"Per-line speed variance (0=uniform, 1=high variance)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Speed Variance\",group:\"Animation\"}},density:{default:15,description:\"Number of line columns across the canvas\",ui:{type:\"range\",min:1,max:60,step:1,label:\"Density\",group:\"Effect\"}},trailLength:{default:.35,description:\"Streak length relative to spacing (0=point, 1=continuous)\",ui:{type:[\"range\",\"map\"],min:.01,max:1,step:.01,label:\"Trail Length\",group:\"Effect\"}},balance:{default:.5,description:\"Color mix midpoint (0.5=linear, 0=all trailing/colorB, 1=all leading/colorA)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Balance\",group:\"Colors\"}},strokeWidth:{default:.15,description:\"Line thickness as fraction of column width (0=hairline, 1=full width)\",ui:{type:[\"range\",\"map\"],min:.02,max:1,step:.02,label:\"Stroke Width\",group:\"Effect\"}},rounding:{default:1,description:\"Rounds the leading edge (0=flat/square, 1=fully rounded cap)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Rounding\",group:\"Effect\"}}},paint:fp(qG,Y_(I_(qG),VG.mask))});var $G=H({name:\"FilmGrain\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Analog film grain texture overlay, weighted toward darker areas\",extraFields:{animTime:{schema:n,initial:0}},props:{strength:{default:.5,description:\"Intensity of the film grain noise\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.025,label:\"Strength\",group:\"Effect\"}},bias:{default:2,description:\"Concentrates grain in darker areas. Higher values focus grain more heavily on shadows; 0 applies grain uniformly.\",ui:{type:\"range\",min:0,max:10,step:.1,label:\"Bias\",group:\"Effect\"}},animated:{default:!1,description:\"When enabled, the grain pattern changes each frame for a dynamic film effect\",ui:{type:\"checkbox\",label:\"Animated\",group:\"Effect\"},transform:e=>e?1:0}},effect:u8({strength:T(\"strength\"),bias:T(\"bias\"),animated:T(\"animated\")}),identityWhen:Uo(\"strength\")});var zue=[{label:\"Portrait 400\",value:\"portrait400\"},{label:\"Vivid 100\",value:\"vivid100\"},{label:\"Chrome 64\",value:\"chrome64\"},{label:\"Slide 100\",value:\"slide100\"},{label:\"Velvet 50\",value:\"velvet50\"},{label:\"Everyday 400\",value:\"everyday400\"},{label:\"Pastel 400\",value:\"pastel400\"},{label:\"Warm 200\",value:\"warm200\"},{label:\"Instant\",value:\"instant\"},{label:\"Mono 400\",value:\"mono400\"}],XG={portrait400:\"BAQECAQEEwUEIwUDNwICTwABagAAhgAAoQAAuQAAzwAA4AAA7gAA+wwA/yAA/y4A/zkABAgFBwgEEwsEIw0DNwsBTwgAagEAhQAAoAAAuAAAzgAA3wAA7gsA+h0A/yoA/zQA/z8AAhAGBhAGDxIEIhcCOBgAUBkAahcAhRQAoBAAuA4AzRQA3hwA7CUA+S4A/zcA/z8A/0cAAB0GAhwICh4GHCIDNCcATioAaisAhSwAnywAty4AzDIA3DUA6jsA+EEA/0cA/00A/1QAAC4IACwKAiwLFC8GLDUASTsAZz8AhEIAnkMAtEYAyUgA2UsA6E8A9VMA/1gA/1wA/2EAAEAMAD8NAD0QCD8NI0UGP0sAY1MAf1cAmlkAsVsAxV0A1l8A5WIA8mUA/2gA/2sA/24AAFQPAFQSAFIVAFAWGFQQNVsFVGEAeGkAlG0Aq28AwHEA0nIA4XQA73YA/HgA/3oA/30AAGgWAGgYAGUaAGIdCWQbLGkUSW8FaXYAjH0ApoEAuoMAzYUA3YUA7IYA+ogA/4gA/4oAAHseAHofAHghAHUkAHMmI3chQHwZXoIKfIgAnI4AtZIAx5QA2JUA6JUA9pUA/5YA/5cAAIolAIsnAIkoAIYrAIMuHIQtOoknVY0gcpITj5cAq50Aw6EA1KMA46MA8qMA/6MA/6MAAJovAJoxAJkyAJc0AJM2GpE4OJU1UpkwbJ0phqIeoKYKuasAz68A37AA7rEA/bEA/7EAAKk7AKk9AKg9AKY/AKRAIaBCO6FCU6U/a6k6gqw0mrAssLQgxrgE27sA670A+r0A/74AALhKALdKALdLALVMEbNNMLBPRK5RWLFObLRMgbdHlrtCqr47vsEx0sQi58gT9skA/8oAAMVaAMVbBMRbIcNcNMJdRb9eU71gYr5gc8BfhMJblcVYqMhUuctOzM5G39E889Uz/9YsN9NvO9NwQNJwSNFxUdBxXM9zaM51csx3fs11jNB0mtNyqNVvudhryNpl2t1f699X/uJQYOKIZOOKZ+KKbOKLceGMeN+Ngd+Pid2Skt6Tm9+RpeGQsOOOvOWLyuiI2OqE5+x+9+52ifKmi/KmjPGnkPGok/ComfCqn/Cspe+urO6xse+wuPGvwPKvyfWu0vas3fiq6fqo9fukBAUJCgQJEwMKJAEKOAAJUAAIawAGhwACoQAAugAAzwAA4AAA7QAA+gEA/xoA/ykA/zYAAwkICQoKFQoJJAkIOAcIUAIGagAEhgABoQAAuQAAzQAA3wAA7QAA+hcA/yYA/zEA/zwAARQLCBMLEhUKJBYHORcGURcEbBQBhg8AoAgAuAYAzQ0A3hcA7SEA+SsA/zQA/z0A/0UAACINAyEODSAOHiMKNygFUCkAayoAhioAoSoAuCwAzC8A3DMA6zkA+D8A/0UA/0sA/1IAADIPADARBi4TFzEQLjYJTDwAaUAAhUIAn0MAtkQAyUcA2koA6E4A9VIA/1YA/1sA/18AAEMSAEMUAEEWDkEWJkcRQk0FZFQAgFgAm1kAsloAxVwA1l8A5WEA8mQA/2cA/2oA/20AAFcWAFgZAFUbAFIeHVYZOFwRVmIBemoAlW0ArG8AwXEA0nEA4nQA73UA/XgA/3oA/3wAAGocAGseAGkgAGUjEGUiLmocS3ATa3cAjX4ApoEAu4MAzYQA3YUA7IYA+ocA/4gA/4kAAH0jAH0kAHsmAHgoAXQrJ3goQn0hX4MWfogBno8AtZIAyJQA2JUA6JUA9pUA/5UA/5YAAIwqAI0sAIsuAIgvAIUyIYUyPIktV44nc5MdkJgKrJ4Aw6EA1KIA46QA86QA/6MA/6MAAJs0AJs1AJs2AJg4AJY6H5E8OpU5VJk1bZ4vh6ImoaYYuasA0K8A4LAA77EA/bEA/7EAAKo/AKtBAKpCAKdDAKVEJqJGPaFGVKVDa6k/g6w5mrEysLQnxrgV3LwA670A+r4A/74AALhMALhOALhOALZPGLRQNLFSRq5TWbFSbbRPgbdLlrtGqr4/vsE308Qr58gf9skG/8oAAMVcAMZeDsVeJcRfN8JfRsBhVb5iY75jdMBhhMJelsVbqMlXustRzM5K39FA89U4/9YzONNwPdNxQtJyStJzVNF0XtB1aM53c8x5f853jNB2mtJ0qdVxuNhtydtp2dxi699Z/uJUYuOKZeOLaOKLbOGMcuGNeeCPgt+Rit6Tk96Um9+SpeGRsOOPveaMyuiJ1+mE5ut+9+13ifKmi/KnjfGnkPGolPGqmfGrn/Ctpu+vrO6ysu+xuPGwwfOwyfSu0vas3fir6fqp9fulBQUUDQQVGAMXJQEXOgAZUgAWbQATiQAUowASuwAO0AAI4AAC7gAA+wAA/xUA/yYA/zQAAgsTCQoUFwkWJggXOwMWUwAUbQAViAATogAQugAMzwAG3wAA7gAA+hAA/yEA/y8A/zoAABYWBhYWFRcWJxcWOxYVUxQVbRATiQcRowANuwAIzgEB3g8A7RwA+ScA/zEA/zsA/0QAACgZAicaEyUZIiYYOykUVCkRbigPiCgLoygGuSgAzSwA3TAA6zYA+D0A/0MA/0oA/1EAADkeADccCjUdHDQdMjkYTz4SbEAJiEAAoUEAt0MAykUA20gA6UwA9lAA/1UA/1oA/14AAEoeAEkeAEcgF0QjKkkeRU8YZ1YNg1gAnVkAtFoAx1sA110A5WAA82QA/2YA/2kA/20AAF4hAF0iAFskB1cnIlgmO14gWWQXfWsFl28ArnAAwnAA03EA4nMA8HUA/XcA/3kA/3sAAHAlAHAnAG4pAGorGmctM2woTnIibXgXj38Ap4IAu4MAzoQA3oQA7IUA+oYA/4gA/4kAAIEsAIEtAH8uAHwwDXgzLHkxRn8sYYQlf4kan48BtpMAyJQA2ZUA6JUA9pUA/5UA/5YAAJAzAI80AI82AIw3AIg5J4Y6QIo2WY8xdZQqkZkfrZ8Iw6IA1KMA5KQA86MA/6MA/6MAAJ47AJ49AJ0+AJo+AJhAJpRCP5ZBVpo9bp44iKMxoqgouqwX0K8B4LAA77EA/bAA/7AAAKxFAKxHAKtHAKlIA6dKLKRLQaJMVqVJbalGg61Bm7A7sbUyx7km3Lwa670A+r0A/74AALlSALlTALlTALdUILVVOLNWSbBYW7FXbrRVgrhRlrtNq75Hv8E/08U258gt9skf/8oFAMZgAsZiF8ViKsViO8NkScFkV79mZL1ndMBlhcNjlsZgqMlcuctXzM9Q39FI8tVB/9Y9OtRzP9R0RNN0TNN2VdJ3YNF4as95dM17gM57jNB5mtJ2qdV0udhxyNps2t1n699e/uJaYuOLZeOMaOKNbOKNc+GOeuGQgt+Sit6Uk96VnN+UpuGTsOORveaPyueL2OmH5uuB9+17ivKni/KojfKokPKplPGqmfCrn++tpu+wre+ysu+yufGywfOxyfWw0/au3fes6fmq9fumAwUlDAQmGwIpLAArPAAqVgAucgAtjQArpwAmvwAm0QAm4QAk7wAh+wAd/w8a/yQV/zMRAAskBwsmGQooLAcrPAMqVgAtcQArjAAopgAlvQAn0QAl4QAi7gAf+wYb/x4Y/ywT/zkPABgkBBglFRgoKxcrPhUrVxAqcgQpjAAopgAovQAm0AAj4AQg7hcd+iQa/zAV/zkQ/0MKACkpACkpDyopJyoqPioqVykocSgnjCcnpiUluyUizykg3i0c7DQZ+TsU/0IQ/0kJ/1AEAEEtAEAtCj8tJDotNz0rVEAncUAji0AhpEEfuUIczEQZ3EcV6ksR908L/1QE/1kA/14AAFMxAFQyAFExHk4xMU0xS1Msa1gmh1kfoFgWtVkRyFsN2F0H52AC9GMA/2UA/2gA/2wAAGY1AGY1AGQyEGA0LFw2QWEyXmgsgG4lmnAasHAMxHAA1HEA43MA8HQA/ncA/3gA/3sAAHc2AHg2AHU2AHI4JWw6OW84U3U0cHstkoEjqYMXvYQEz4QA34MA7YUA+oYA/4cA/4kAAIg5AIc6AIU7AII9G34/NHs/S4E7ZYY2gosvoZEkt5QYyZQC2pQA6ZUA95QA/5QA/5YAAJQ/AJVBAJNBAJFCEo1EMYhGRoxDXpFAeJU6k5ozr6ApxKMd1aMH5KQA86MA/6IA/6IAAKJGAKJIAKFIAJ5JEJxLMZhMRZdMWptJcqBFiqRAo6g5vK0v0LAm4LAV77AA/bAA/7AAAK9PAK9QAK5RAKxSGqpTNadUR6NVW6ZTcKpQha5Nm7JIsrVCyLk53Lwy670k+r4O/70AALxaALtbALpbC7lbK7ddP7VeTrJfXrFfcLRcg7hal7tWq79Sv8JM08VE58k+9sk1/8onAsdnFshoI8dpMcZoQMVpTsNrWsBrZ75tdcBrhsNql8ZnqMlkusxgzM9a39FS89VO/9ZJPtV4Q9V5SNR5T9N6WNN7YtF8bM99ds1/gc5/jtB+m9J7qdV6udh3ydtz2t1u699m/uNjZOOOaOSQauOQb+ORdeKSe+GTg+CUi96XlN2Ynd+YpuGWseOUveWSyuiQ2OmL5+yG9+2AifKoi/KpjfKpkPKqlPGrmvGtn/CupvCxre+zs++0ufGzwfOzyvWy0/ew3feu6fqs9fqoAAU6BgQ8GgE+MgBDSABGWABDdQBIkQBJqwBHwQBD1AA+5QA68AA+/AA9/xA7/yU5/zQ3AAw5AQw7GAs+MAZCSABFWABDdQBHkABHqgBFwQBC1AA84wA87wA+/AY8/x45/yw3/zo2ABo4ABo6Exk9LRhBRxVFWRFDdQJGkQBFqgBDwQA/0wA94QE+7hY9+yQ7/zA5/zo2/0Q1ACo6ACo6DSs7JytARCxEWilEdiZEkSFCqR1AviVB0Cc+4C097TM6+Ts4/0I2/0g0/1AzAEBAAEBAAEFBIUFCPkJCWUJCdEJBj0JApkI/vEI9zUQ63Uc560s39081/1Qz/1kx/10vAF5GAF5HAF1GIFpGO1VFUVhDcVs/jFk6o1k4uFo3yVs12V006GAy9WIw/2Ut/2kr/2wqAHBJAHFKAG9LIGxKNmZISWZIZGxEhHA+nXA4s3AxxXAu1XEs5HMq8XUp/ncm/3gk/3sjAIFPAIFRAIBOBHxKL3dLQ3JLWXlJdn5EloM+q4Q3v4Qu0YQl4IQg7oUe+4Yc/4cZ/4kYAJBRAI9RAI5OAItNKIZOQIFQUoROaolLho5FpJM/uZU4y5Uv25Uj6pQT+JQJ/5QE/5UBAJtSAJxSAJpRAJhSJZRSPZBUTo5TY5NRe5dNlpxIsaFBxaM71qQx5aQl9KMS/6IA/6IAAKdVAKdWAKZXAKRXJaFYPZ1ZTplaYJxXdaFVjKVRpapMva5G0bBA4LE277Eq/bAX/7AAALNcALNdALJdBbBdK65fQKtgUKdgYKdgc6tdh69bnbNXsrZSyLpM3L1H7L4++r4z/74jAL5lAL5lAr1lIbxmNrpnR7hnVrVoY7Jpc7VnhbhlmLxirL9fwMJa08ZU58lQ9spI/8o+GspwJMpxLclwOshxRsZxU8VyX8J0a791eMF0h8Nyl8ZwqcltusxqzM9l4NJg89Vc/9dYQ9Z+R9Z/TNaAU9WAXNSBZdOCb9GDec+Eg86Fj9CEnNODqtWAudh+ydt72d127OBx/uNuZuSSaeSTbOWUceSVduOVfeKWheGYjd+Zld6cnt+cp+GasuOZveaXyueU2OmR5+uM9+6GivOqjPOrjfKrkfOslPGtmvKvn/GwpvCyre+1tO+2uvG1wfK1yfSz0/ay3few6fmu9vusAARSAANTFgBWMQBbUQBiaQBldgBfkwBkrgBoxABl1gBh5QBc8wBY/wBT/wFU/y5Y/ztXAA1QAAxSFAtWMAZaTwBhaQBkdgBekwBjrgBmwwBj1gBg5QBb8gBX/gBS/x9X/zRX/0BWABtQABpTDhpVLRlaTRZgZw9jdwZflABkrgBlxABi1QBe5ABZ8QBV/BpW/zZZ/z9X/0lVACxMACxPBS1TJyxXRy1dZStieClglSNkrR1iwhlf0xha4h1X7jRZ+T9Z/0ZX/0xV/1RUAD5RAD9SAEBTH0FTP0NaYUVheURhk0Jgq0Bevz9bzkZb3UpZ605Y91NW/1dU/1tS/2BSAFlaAFtcAFtcDlxdOl1dWV5edl5dj11cpl1auV1Yy15X2mBV6GJU9WVS/2hQ/2pP/25OAHtkAH1kAHtkAHliPHVhVW5fa3FdiXNZoXJUtXJSx3JR1nNQ5HRO8XZN/nhM/3lK/3xKAItjAItkAIpkHIhlQYRkUH5gYXxffIJdmYZZroZTwYVM0oRJ4IVI7oZH+4dG/4hE/4pEAJhoAJhpCZdpLpVpOZFjTYxiXIdicYxgi5Fdp5ZZu5ZTzJZM3JVE65Q/+JU+/5U8/5Y7AaJtEKNtGqJrJaBnNp1lS5hlWpJmapVkgJphmZ9etKRbxqVU1qVN5qRF9aM7/6Iy/6IyAK1tBK1tDq1rHatoNqhoSqRpWaBpaJ5oeqNmkKdkp6thv7Bc0bFX4bFQ8LFH/rA8/68uALduALhuCLdtJbVtOrNtTLBuWqxuZ6hueKxtirBrn7RotLdkyrtg3b1d675V+75M/75CAsJyEcJzIsByM8BzQr5zUbx0XrhzarV0d7VziLlymrxwrcBtwMNq1MZl6Mli9spc/8tUKsx6Ms17Oct7Q8t7Tsl8Wsh9ZcV9cMJ+e8B9isN8mcZ7qcp5u812zM9y4NNu89Vs/9doSdiGTdiHUtiHWNeIYNaIadSJctOKfNCKhs6MkNCLndOKqtWIudiGyduD2t6A6+B7/uN6aeaYa+WYbuWYc+WZeeSaf+ObhuKcj+Gel9+fn9+gqOGfsuOevuacy+ia2OqX5+yT9+2OivOtjPSujvOukfSvlfKvmvKxoPKypvG0rfC2tO+5u/G4wvK3yvW31Pa23vi06fmy9fuvAARrAANtDwBvMQB0UQB6dACCjACDlwB9sACAxgCC2ACB5gB88wB4/gB0/wBv/wBs/yZqAA5pAA5sDQxvMAZzTwB4cwCBigCClgB8rwB/xgCC1wCA5gB88gB3/gBz/wBv/xVr/zZsABtpABxrBBtuLRpyTRd3cA5/iQCBlgB8sACAxQCC1gB+5QB78QB2/glz/x9u/y5r/01yAC5mAC9oAC1sJi5wSC51bC59iCuBlih9ryKAxB2A1B584yR58Ct1/DNx/ztu/09w/1xzAD9iAEBjAEFmHUNsP0RyZUd7hEh/lUZ9rUN+wUJ80UN54EV17Uly+VBw/150/2Jx/2dxAFZrAFdsAFhtEFltOFptWl52fWF8kmB8qV56vF53zV502mN052h09Gpy/21w/29u/3NuAHN0AHZ2AHV2AHZ2M3d3Vnd4dHd4jXZ2onZ1tnZzx3Zy1ndx5Hhv8Xpu/Xts/3xr/39rAJR+AJWAAJV/AJN9MZB7Wox6b4V4g4d2nIlysYdtw4ds0odr4Ihq7ohp+oln/4pm/4tmAKJ9AKJ+AKF+G559Rpx8YJh8a5F4epB3kJV1qZhyvJhszZZm3ZZj6pZi95Zh/5Zf/5deAKp+AKuAIqqAPqiAVaaAWqJ6aJx5dJh4hp13naF1tqZyx6Zt16Vn5qRg9aJZ/6JX/6NYLbODOLSERLOETLKDULB/V6x7Zqh7cqJ6gKV5lKp3qa11wbJz0rJu4bJn8LFg/q9X/65OQLyGRL2GRbyESbuCTbl/WLZ9ZrJ9ca59fq58jrF7obV5tbl3y7103b5w7L5q+r1i/71aQMaHQsWGRMWFR8SDTsKBW8CBZ72BcrmBfLaBi7l/nL1+rsF8wcR61cd358p09spu/8pnRNCJRtCJSM+ITc6HV82HYcuHbMiId8aHgMKIjMSHm8eGqsqEu82CzdCA4NN889Z7/9d3UdqPVNuQWNuQXtmQZdiRbteRd9WRgNOSidCTk9CTntOSrNWRutiQyduN2t6L6+CH/eOGa+edbueeceeedeefeuafgeSgieShkOKimOCjod+lqeGls+OjvuWiy+ig2eqe6Oya9+6WivSwi/SwjfSxkPSxlfSymvOzoPO1pvK2rvG4tfC7vPG8w/K7y/S60/a53vi46vq29vu0AASDAAKFCgCHMgCLUwCPdACVmACcqwCetgCZxwCY2ACZ5wCZ9ACU/wCR/wCM/xOJ/y2GABCCAA6EBw2GMAeKUQCPcgCUlgCbqgCdtACYxgCX2ACY5gCY8wCU/gCQ/waL/yKI/zaGAB6BAB6DAB6FLRyIThmNcBGTlAKbqgCdswCXxQCX1wCY5QCX8gKT/BmP/ymL/zWI/0OGAC5/AC6AAC+CJi+GSjCMbTCTkS+apyycsSqWxCeX1ieY4yuV8DKR+zqO/0GL/0mI/1OGAEJ6AEN8AER/F0OEQUWJZkiQikuXo0uarUmUwUiW00iW4EuT7U+P+FOM/1eJ/1yG/2SGAFV5AFd7AFd7C1h8OVuDW16KgGOSnGWXqmOTvmKUzmOS3GSQ6WaN9WiK/2uH/3SI/3uLAG6CAG+DAHCDAHCDM3GEU3KEdHeMlHuTpXqSuXmRyXmO13qM5HyL8ICL+4GK/4KI/4SHAIqKAIyMAIyMAIyML4yNVI2Nco2Oi42OoIyNsoyMw4yK0oyJ34yI7YyG+Y2F/42D/4+DAKiUAKmWAKiWAKiVMaaUWaOSdp6QhpiNlpqMrJuJv5qFzpmD3JiC6piA95h//5h+/5l8ALOSALSUALKTLbGSTa+SZ6yRe6iRgqKMjqCLoqWKuKiIyaeD2KZ+56R59KN4/6N2/6R3FruTK7uTO7qTTLmTX7eTcLSTdbGOfquMiKeLmKyKrbCJw7OH07SC4bJ88bF2/q9v/69vRcOVTcOWVMGWX8GWar+Wbr2TcbmOfbWNhbCLk7OLpLeKt7qJzb6H3b+D7L99+r12/7xvXMqaYMqaY8mZZsmYZ8eVasaSccKPe7+PhLqOj7qNn76MsMKLwsWK18mI6MuG9sp//8p6YdObYtObZNOaZdKYZ9GWas+TdM2TfcmThsaSkMOSnceRrMqRvM6PztGO4dSL8taJ/9eGZt2eaN2faN2datycbNuac9qae9ibhNabjdObltCcoNKbrdWau9mZytuY2t6W7OGT/eOTdOmndeqmdummeOmmfeimg+emiuankuSomuKpouCqquCqtOOqv+apy+in2eql5+yi9+6ei/a0jPa0jfa0kPW0lPW1mfS2oPS4p/O5rvK7tfG+vfDAxPK/y/S+1Pa93vi86fm69vy5AASYAAKZEQCaNwCeVgCidQCmlgCstgCzxQCzzwCv2ACr5wCq8wCq/wCn/wOk/yOg/zedABGWABCYDg6aNQmdVACgcwCllACstQCyxACyzQCv1wCq5gCq8wCp/gCn/xuj/y6g/z6dACCWACCXBh+ZMh6cUhygchalkw2rswSywgCxzACu1wCq5Qiq8hep/San/zKj/z2f/0qdADCTADGWADGXLDGbTjKfbzKkkDKprzOwwDKwyTCs1TKq5DWq8Dqp+0Gl/0mi/1Cf/1mdAEWQAEaTAESVHkWYRkecaEmhiUynqVCtu1Gvw0+p0k+p4VGo7VSn+Fmk/12h/2Ge/2icAFaJAFiMAFmOElqSOluYXl6dgGOjoWmptWqsvminz2mo3Wqn6Wyl9W6i/3Cf/3Kd/3icAGqMAGyOAGyPAG2OMW6PVXKWdXaeln2lroCpun6lyn6m2H6l5X+i8YCg/IGd/4Ob/4idAIOVAIWWAIWWAIWWMoaWUoaWbIeXi4yfp5GltZCkxZCj04+h4JCf7ZCd95Se/5Sc/5WcAJ6eAJ6eAJ6eAJ+eN56eWJ+fcp+fiZ+gnp+gsJ+fv56ezp6d3J2c6Z2a9Z2Z/52X/52WALalALemALemE7emQremX7WleLKjja2hmaeeqKmeuqqby6iX2aeV5qeU86aS/6aR/6aRAMKlCsKlKsGlQ8ClWb6kbbyjgLqij7ahlbCdn6+csbObxbaa1LWV47KQ8bGL/rCK/7CKPcmkRsmlT8mlW8ekacakd8OkhsGjir2fkbicmbSbqLmbur2az8CZ3sCU7b+Q+72J/7uDWM+lXdCmY8+ma86mdc2mgMumg8iihsWdj8Gclrybor+assOaxMeZ2MuY6MuV9suQ/8qKatepbdepctepeNapfdWoftOlgNGihs+fj8uflseeoMedrsudvs6cz9Kb4tWZ8taY/9eUeeCte+Cte+CtfN+rft+qf92ngtylitqkktelmtOkotKkrtWkvNmjytui3N+h7eGf/uSfgeuyg+yyg+uyhOuxhuqviOmujOiulOeunOWvpeOwrOCxteOwwOWwzOiv2eqt6e2r9+6okfe7kve8k/e8lPe7lva6mfa7n/W7pvS9rvS/tfPBvfHDxPLEzPTD1fbC3/jB6vrA9vu+AAWpAAOqIACsPgCuWwCxdwC1lQC5sQC+zADD1wDC4AC/5wC68wC5/wG4/xy3/zC0/0GxABOoABKpHhCrPAytWQSwdgC0lAC4sAC9ygDC1gDB3wC/5gC58gS5/Ru4/ym2/ziz/0exACKoACKoGiGqOyCtWB6wdRu0kxe4rxa9yRvC1BrB3hi/5SK58iq5/TO4/z23/0az/1KxADOmADOoDTSpNTSrVDSucjSyjzW3qzi7xT3A0j7A2zy+40C58EW5+0q4/1C2/1ay/2CxAEakAEWlAEanKkepTEmsa0qvik61plK5wFm+zlm+1le74Fm47Vy3+WC3/2O0/2ix/22wAFmdAFugAFyiH1ylQVyoYmCsgWOxnmm2uXC7yHG80G+43HC36XG39XS2/3az/3iw/32vAGiWAGqYAGuZBG2dOHChWHKnd3aslnyysYO4woW6yoO12IO25oW28YW0/Iey/4ev/4uuAH+dAICfAICfAIGfMIGeToGfboami4ysqJKzvJa3xpS01ZS14pW07ZWy+ZWw/5Wu/5etAJelAJemAJemBZemOJemVZembZimg5imnZ6ttaOzwqKz0KKy3aGw6qGv9aGt/6Ot/6StAKyrAK6tAK6tI62tRK2tXq2tda2uiq2unK6urq6vva6uzK2t2ays5qyr8qyq/quo/6yoAMKzAMS0H8O0O8O0U8O0acO1fcG0j76yn7uwqbWttresx7iq1rWm5LWl8LSj/bSj/7SiMM+0PM+1R8+0Vc61ZcyzdcuzhMiyk8axocKwpbyrrruqvr+q0cKp38Gl7b+g+72c/72cU9WzWdazXtWzZ9SzctOyftGyi8+xl8yxm8mtocSqqMCptsSox8io2syo6Myk98uf/8qbZ9yza9y0b9y0ddu0ftq0h9mzkdezltSwl9Gsn82rpcipscupv8+p0dOp5Neo89em/9iieOS3e+S3fuS3guO3ieO3kOK3kuC0lN6xmNyvoNiup9StsdWtvtmtzNyt3N+s7uKr/uSqie69i+69je29ke29k+28lOu6luu4mOq2n+i2p+a2r+O3t+K3weW3zei22uq16ey0+e+ymfjFmvjEmvjEm/jEnfjDn/fCovbBpvbBrvXCtfTEvvPGxvLJzfTI1vbI4PjH6/rF9/zEAgm4Gwe5MQS6SQC8YQC+ewDBlgDFrgDIxgDM2wDQ5QDO7gDN8hLG/iPG/zDE/zzD/0rCABa3GRa4MBW5SBK8YQy+egTAlADDrQDHxQHM2xbQ5BfP7RfN8iTG/S/F/znE/0PD/0/BACa3FSa5Lia5RiS7XyO9eSHAkyDDrCLHwyjL2TPQ4zPO7DPM8TnG/EDF/0fE/0/D/1nBADa1BDe3Jze4QTe6XDi8dji/kDnCqTzGwEPK1k3O4EzN6UvL70/G+lPF/1nE/17D/2fBAEi0AEi1FUm2OEm3VUu6cE28i1DApFTEvFvI0mTM3GPM5mLK7GXF+GfE/2vE/27D/3PAAFyvAF6xAF2yKFy0Sl63aGC5hGS9nmrBtnDFzHnK2HnK4HfI6XjE9HrE/3zD/37C/4LAAGypAG2qAG6sHnCvQ3KyXXK2e3e5lny+r4PCxorH04zI24nF5YrD8YrD/IzD/43A/5C/AHymAH2nAH2nAH2nMX+qU4OvcYa1jYu5p5G+v5nEzpvG1ZnC4pnD7prD+prB/5q//5u+AJKtAJKtAJKtA5KtNJKtT5KtZpKtgpeznZ25t6TAyajE0abB36bC66bB9qW//6W9/6a8AKazAKezAKe0I6azQqezWaazb6azgqazlKezrq27w7LAzrLA27G/57C+87C8/rC7/7K8ALq5Cbu6Jru6PLu6Urq6Zrq6ebu6i7q7nLq7rbu8vLu8yru817q75Lq68Lm5/Lm3/7m3K87AN8/BQ8/BUc7BYc/Bcs/Bgs7Bks3Bocu/sMe9t8G6xMO608S44MK07sGy+sCx/8CxTdvCU9vCWdvCY9rBb9rBfNjBidbAl9S/pNG9sM28s8i4u8e3ysu328626c2y+Muv/8mrY+HAZ+LAbOHAc+HAfODAht/AkN2/nNu+pti+q9S6r8+3tsy1w9C109W25ti29Niz/9evdejBeOjBe+jBgOjBh+fBj+bBmOTBoeLApuC+p966rtq4tdW3wNm3zdy33uC37+O3/uW2hfDEiPDFivDEjvDFk+/Fmu/Foe7FpezEp+vBq+m+s+e/uuS/w+W/zui+2+q+6e29+u+7mfrLmfrLm/rLnvnLo/nMp/nMqvjMrPjKr/fJtvbJvvXLx/PMz/TO1vbO4PjN6/rM9/vKKRHHNBDHQw7IVQrJagTKgADNlwDPrQDSwgLV1hjY6Cvc8S3b+i7Z/TfS/0HR/0nP/1TOJxzFMxzHQhvHVBnIaRfKgBTMlhLOrBTSwRvV1SnY6Dfb8Dja+TnZ/D/S/0fQ/0/P/1nPJCrFMivHQCrHUyrIaCnKfinMlCnOqyzRwDLU1D3Y5kjb70nZ+EjY+03R/1PQ/1rP/2LPGzrEKzvFOzvGTzvHZDzJez3Lkj/NqELQvUnT0VLX5Fza7VzZ9lvY+V3R/2LR/2fP/27PAkvCG0zDMUzDSE3FX07HdlDJjlPLpFjOuV7SzWfV4HDY6W/Y8m7W92/R/3LQ/3XP/3rPAFu+AF3AHF3BO1/CVWDEb2PGiGfJn2zMtHLPyXrT3IPX5YLW7oDV9IDQ/oLP/4TP/4jPAG+5AHG7DnG8M3K+SHHAZXTDf3jFl33JroPNw4vR15PV4ZPV6ZDT8ZHQ/JHP/5LP/5XOAH2zAH60AH+1F4C3PoK6XIS+dYbBj4vFqJLJvZjO0aDT3aHT5J7R7p7P+Z/P/5/O/6DNAI+1AI+1AI+1AI+1LI60S4+2apO7hZfAnpzFtqPKy6vQ2qzS36rO66rO96rP/6nN/6rLAKG5AKK6AKK6G6K6OqG6UqG6ZqC5eaG5k6W+razGxbPM1bfP3LXN6bXO9LTN/rTL/7TKALS/ArTAH7TANrTAS7TAXrTAcbPAgrO/lLO/pLO/u7rH0MDN2r/M5r/L8b7K/L3J/73IK8bFNsbGQMfGTcfGXcbGbcbGfcbGjcbGncbHrMfHu8fIycjJ1sfI4sfH7sbG+sbF/8bESNnMTdnMVdnMX9nNa9nNednNh9nNltnOpNnNsdbLvdLJxMzGz8/F3s/D687A+M2//82/YebPZOfPaebOcObOeeXOhOTOj+PNm+LMp9/LstzKvdnIv9PDx9LC1tfD59rD9Ni//9i9ce3Nde3NeO3NfuzNhevNjuvNl+nMoejMq+bLteTKueDHvdzDw9nC0N3C3+HD8eTD/uXBgvTOhfTOh/TOi/POkPPOmPLOoPHOqPDOsO/Otu3MuOvJv+jHxeTH0OjH3OvH6+3G+/DGk/zSlf3Sl/zSmvzSn/vSpPvTq/vTsvrUuPnTuvjRv/fQx/bS0PXU2PXU4fjU7PvT+PzRQxzTSRvTUxrUYhnVcxfWhhbYmRbZrRnbwCHe0i3h5Dvk8kjl+krk/0vj/0/d/1fb/2DaQCTSSCTTUiTTYSTUcyPVhSLXmSPZrCfbvy7e0Tfg4kTj8k/l+lDk/1Hj/1Tc/1vb/2PZPzHSRjHSUTLTXzHUcTHVhDLWmDTZqzfavj3d0Ebg4VLj8Fzl+Fzj/1zi/17c/2Ta/2zaOkDRQkHSTUHSXEHTbkLUgUPVlUbXqErZvFDczVjf32Li7mvk9mvj/2ri/2zc/3Db/3baMVDPOlHQRlHQV1LRaVPSflXUkVjWpV3YuGPbymre3HTh7Hzk9Hvj/Hnh/3rb/33a/4LaGF/MKmHNOmLOTWPPYmTQd2fSjGrUoG/WtHXZxnzc2ITf6Y3i8Yvh+Yng/Ynb/4ra/47aCnPIIXTKL3TKPXLLVnTNbnfPhXvRmn/UroTWwYva1JPd5Zvh7Zng9pff+5fa/5ja/5raAIHDAILEEoPFNIPGToXIYoXLe4jOk4zRqJLUvJnXz5/b4aff6qbf8qPd+KPa/6Pa/6XaAI29AI2+AI6+BY/AOJDCVpLFcZTIiJfMoJ3QtqPUyqrZ3LHd57He7q/c9q7Z/67a/6/aAJ7BAJ7CAJ7BCZ7BMJ7BSJ3AXp3Be6DFlqXLrqvQw7LW17nb47vc6bnZ9LnZ/rjZ/7nZAK/GALDGDrDGLK/GQa/GVa7GZ67Fea7Fiq3Eo7LJu7nR0cHX4MTb58PZ8sLZ/cPZ/8LXH8DLK8HLNsHMRMDLU8DMZMDLdMDLhL/LlL/Lo7/Lsr/KyMbS3M3Z5czY8MvX+svW/8vVQ9LRSdLRT9LRWdLRZtLRc9LSgdHRj9HSndLSrNLSutLTyNPT1dTU4dPT7NLT+NLS/9PSWePWXuTXY+TXa+TXdeTYgOTYjOTYmuTYp+TZtOTZv+HXyt7V0NjR2trR6dvP9trM/9nMcfHadPHaePDaffHahPDajfDalu/ZoO7ZrOzYturXwOfWyeTUy97P097O4uPP8uXP/+XNfvjZgPfZhPfZiPfZj/fZlvbZnvXYp/TYsfPYuvLYw/DXxu3Uy+nR0ufQ3evQ6+3Q/PDRjv/aj/7Zkv/alf/amv7aoP3aqP3br/3bt/zbwPvcx/rbyfjY0ffZ2fXa4vjb7fva+v3aVijeWyjfYijfbijgfCjhjSninSvkri7lvzXnzz7p30nr7lbt+1/u/2Dt/2Ds/2Pn/2vlVTDeWi/eYi/fbTDffDDgjDHinDLjrTflvj3mzkXo3lDq7Vvt+mTt/2Xs/2Xs/2fm/27kUzveWTveYTvebTzfezzgiz7im0DirEPkvUnmzVHo3Frq7GXs+W3t/23s/27s/27m/3XkUEjdVkndXkndakrfeUvfiEzgmU/iqlPju1nly2Dn22np6nLs93rt/3ns/3ns/3rm/37kSlfcUFjcWVjcZVnddVvehV3fll/gp2TiuGnkyHDm2Hjo6IDr9Yfs/Ybs/4Xr/4bl/4nkPmbZR2faUWjaXmnbb2rcgG3dkXDfo3TgtHnixYDl1Ibn5Y/p8pXs+pTr/5Lq/5Hk/5TkLnXXN3bXQnbYU3fZZXnaeHvbi3/dnoLesIjhwY3j0ZTm4Zzo8KLr96Dq/57p/53k/5/kHobSLYfTOofUS4jVWobWbojYg4vZl4/cqpTevJrhzqDk3qbn7a7q9avp/ano/6jk/6rkAJHNAJLOFZPPM5LPTJPRZJXTeJbWjZnZpJ7bt6Peyani2rDl6rfp8rXo+rPn/7Pk/7PkAJ3KAJ7LAJ3LAJzKK5zKTZ3NaaDQgqLTmKXYr6vbw7Lf1bjj57/n8L/n9r3m/r3k/73kAK3OAK3OAK3OHqzONqzOSqvNXarMb6nMi63QpbLWu7jbz7/g4sfl7cnn8sbk/cbk/8fkCLzSHL3TKr3TObzTSrzSWrzSarvSerrRirrQmLnPsL3Ux8Xb3M3i6tHm8dDk+8/k/9DkOM3XP83YRczXUMzXXMzXaszXeMzXhsvWlMvWosrWsMrVvcrV09Ld5tnj79jj+Nji/9fhVN3cWN3dXd3dZN3cbt3ced3dhdzcktzcn93drN3dut3dx97e1N7e4N/f69/f99/f/97eaO7ia+7ib+7ide7ifu7ih+7iku7jnu7jqu7jt+7kwu7kzOzj1unh2+Pc5eXc9Ofb/+XYf/rkgvrlhfrlifrkj/nllvrlnvnkp/nksfjkuvbjxPXizfPi1vDg2Ovc4Ovb7u/c/vLciP/jif/ji//jkP/jlf/jnP/jpP/krP/jtf7kvv3kx/3k0Pvk1fri3Pni4/ji7vri+v3iajrrbDnqcjnqfDrrhzvslD3toj/usEPvvkjwzU/x21fy6mH092v1/3L1/3P1/3P0/3bxaD7pbEDqckDqe0Drh0Hsk0PsoUTsr0juvU3vzFTx2lzy6GXz9nD0/3b1/3f1/3b0/3nwZ0jpa0npckrqeknqhkvrkkzsoE/sr1LuvVfvy17w2WXx523z9Xf0/371/330/330/3/wZVToaVXpcFbpeFbphFfqkVnrnlzsrV/tu2PuyWrw13Dx5nnz9IH0/4j1/4f0/4b0/4fwYWLnZWPobGPodWTogWbpjmfqnGrrqm3suXLtx3fv1X3w5IXy8Y3z/ZP0/5Hz/5D0/5DvWW/mX3HnZnHncHLnfHPoiXXomHjqp3vqtoDsxITu04vv4ZHx75jy+570/5zz/5vz/5ruTnzkVH3lXH7lZ3/ldIHmg4Pnk4Xoo4jpso3qwZHs0Jfu353w7aPx+anz/6fz/6Ty/6TuSY3hUI3iVo3iXIvjaozke47ljJDmnZTnrpjpvZzqzaHs3Kfu6q3x+LPz/rHy/6/y/67tM5jeO5jeRZjfUpjfYpngcprigpnjlZ3lqKHmuaXpyavr2bDt57bv9rzy/bry/7jx/7ftAKHYA6LZH6LaNqLaTKLbYqPed6Tfi6binqjksq3mxLPp1bjr5L7u88Tx+8Tx/8Lw/8HtAK3ZAK7ZAK3ZH6zYNazYR6vYYavZe63ck7DfqLPjvbnm0L/p4Mbt78zw+M3x/srv/8rtB7vcGrzcJ7vcNbvcRLvbVLrbY7nbcrjagbfZmrrdsr/hyMXm28zq7NPv9tXw+tPt/9PtMsrfOMrgP8rfSsnfVcngYsnfcMjffcjei8femMbdpcXcu8jf09Hm59nr897v+dzu/9ztTNjjUNnjVdnjXdnkZtjjcdjkfdjjidfjltfjotfir9fivNbhyNXg3t3o8eXu+OTt/+PtYujoZenoaejob+jod+jogOjniujolujooujorefnuujoxujo0+np3+np6+rr9enq/+npdfjsd/fsevfsgPjth/jsjvftmPfso/jtrvjtufjuxfju0Pfu2fbt4fPr5u/n8PHo/vLmiP/tiv/tjf/ukf/ulv/tnf/upP/urP/utP/uvf/tx//u0P7t2f3t4vzs5vrq7/vq/P3re1D1flD2glD1iVH1klL2nFT2p1b3s1n3wF34zGL52Gj55W768nf7/4D8/4T8/4T8/4T8elT1fVX1glX2iVb1kVf2m1j1pln2slz3v2H4y2X52Gv55XL68Xr7/oL8/4f8/4b7/4f8eVv0fVz0gl31iF31kV/2m2D2pmL2smT2vmn4ymz413L543j68ID7/Yj8/4z8/4z8/4z7eWb0fGf0gGj1h2j1kGn1mWr1pWz2sG/2vXL3ynf41nz544L574j6/JD7/5T8/5P8/5P8d3LzeXLzfnP0hHP0jXX0l3X0onj1r3r2u332x4H31If44Yz57pL5+5n7/538/pv7/5r7cX3ydX7yeX7ygX/ziYDzlILzn4P0rIb0uYn1xY320pH34Jf47Jz5+KL6/6X6/6P6/6P6a4jxcInxdIrxe4rxhYzykI3ynI/zqZH0tpT0w5j10Zz23aH36qX496v5/6/6/636/6z6Y5PvZpPva5TvdJXwfpXwi5fxmJnypZvys57zwKL0zqX126r36K739bT5/7j6/7b6/7T6XaDtYqHtZ6Dtb6HueKDugaDvkKHwn6TxrqbyvKrzy6702bL25rb28rz4/sD5/775/735SqnqUKrqVqrqYKrrbKrseqrtiKvtlavvpq7wt7HxxrXy1br047728MP3/Mn5/8f5/8b5JrLmMLLmOrLnR7LnV7LoaLLperPqjLTsnrbtrrfvwLzx0cHz4Mb17sv3+tH4/9D4/8/4M77oOr/pP77oR77oUr3oXb3oabznervokLzqpL7st8Hvysbx3Mz069L299j4/9n5/9f3QsvrRsvrSsvqUsvrW8rrZcrqcMnpfMjpiMfplMXoqcfqwMzu1NLx5tj09d/3/eH4/+D3UtjuVNjtWNjtXtjtZ9jtcNftetfthdbtkdbsndXsqNTrtNPqyNXs393x8eX2++j4/+f2YeXwY+bwZuXwbOXwdObxfOXwheXwkOXwm+XwpuTwsuTvvePvyOLu1OHt6unz+e/3/+72cfTzc/T0dfTzevTzgfTziPPzkfT0m/PzpvTzsPPzvPPzyPPz0/Pz3/T06vT09fT1/vT0ff/1f//2gv/2hv/1jP/2k//1nP/1pf/2r//2u//2xv/20f/23P/35P/37P318vz0/f70jm//kG//k2//l2//nXD/pXH/rnP/t3X/wnf/zHr/2H3/44H/7oX/+ov//5H//5T//5T/jXH/j3H/k3L/l3L/nXP/pXT/rXX/uHf/wnn/zHz/13//4oP/7oj/+Y3//pL+/5b//5b/jXf/j3j/knj/l3n/nXn/pHn/rXv/t3z/wX7/y4H/14X/4oj/7o3/+JH//5f//5n//5r/jX//j3/+koD+l4D/nYH/pIH/rYP/toT/wYb/y4n/1ov/4pD/7ZP/95f//53//5///5//jYj+jon+kYn+lon+nIr+o4v/rIz/tY3/wI//ypH/1ZT/4Jf/7Jv/95///6T//6b//6X/ipD9jJH9kJL+lJL+m5L+opP+q5T+tJb+vpf+yZr/1Jz/35//66P/9qb//6v//63//6z/h5r8i5v9jZv9kpv9mJz9oJ39qZ79sp/+vaH+yKP+06X+3qj/6av/9K///7P//7X//7T/hKP8h6T8iqT8j6T8laT8naX9pqb9sKj9u6n9xqv+0a7/3LD+6LP/87b//br//73//7z/hK77hq77iK77iq37j6z7mK38oq78rK/8t7D9w7P9z7X+2rf+5rr/8b7//ML//8X//8T/e7X6frX5gbb6hrb6jLX6lLb7m7X7prX7s7f8v7n9zLz92L7+5MH+78X/+sr//8z//8v/cL34c774d774fL75g775jL75lr76ob76rL77ucD8x8L81cX94sn+7cz++NH+/9X//9T/acf4asf3bcj3ccf4d8f4gMb4jMb5mMb6pcb6tMj7wcn80Mz83s/96tP999j//93//9z/bNL5bdL5cNL5c9H5eNH5f9H5htD4j9D5ms/5qc/5udD7yNH82db859n99N/+/uP+/+P/cNz6ct37dN37eNz7fdz6g9z6itz6k9v6ndv7ptr6r9n5vtn60dz84t/88eX+++n+/+v/dOj8def8eej9fOj8gef8h+j8j+f8l+j8oOf8quf8tOf8veb8x+T72OX87Or9+vD+//L/efT+evP9ffT+gPP9hvT+jPP9lPT+nPP+pfP+r/P9ufP9w/P9zfL92PL94vH99PP9//j+ff7+f//+gf7+hf/+iv/+kf/+mf7+ov//q//+tf//vv7+yf7+1P7+3/7+6f/+9P//////\",vivid100:\"AAAAFAAAJAAANAEAQwEAUQMAYQMAcwUAiggAoQsAsw4AwxAA1BIA5BUA9BcA/xkA/xsAAw0BDg4BHw8BLhEBPRIATRMAXRQAbxUAhxYAnhcAsRgAwhcA1BYA5hUA9hcA/xkA/xsACBsFEhwFHR0EKx0EOh4ESh8EWiADbSEDhCMCmyQCriQBvyQB0CMA4iEA9B8A/xsA/xsAECgNFygNHykMKioMOCoMRysLVywKay0Kgy8ImTAHqzAGvDAFzS8E4C0D8SsC/ygB/yIBFzMTGzQTITQTKjUTNTYSRTcSVjgRaTkQgTsPlzwNqDwMuTwLyjsK3DoI7TgG/TUF/zADFUAZGEAZHUEZJkEZM0IYQ0MYVEQXaUYWgUcVlEgUpUkTtkgRx0gQ2EgO6UYN+UMK/z4IEU4fE08fGE8eHk8eLlAeP1EdUlIdaFQcf1UaklYZolYYslYXw1YW1VUU5VQT9FEQ/04OAmAjAmAjBGEjD2EjJWIjOGMiTWQhZWUge2YfjGcenWcdrWccvmYa0GUZ4GQY72EW/l4TAHInAHInAXInDXMmG3QmLnUlSXYkYXgjdHkihXohlXogpXsft3seyHod2Hkb53Ya93IYAH8qAH8pAIApAYApC4EoMIIoSoQnYIUmcYYlgIckkIgjoYkisYkhwYog0Ike34gd7ocbAIwtAIwtAI0tB44sH44sNpArTJEqXpIpb5MofZQnjZUmnpYlrpYkvZcjzJch2ZYg6JUeAZoxA5sxBpsxC5wwIJwvOJ0vS54uXJ8ta6AseqEriqIqmqMoqqMnuaQlx6Qj1KQi5KMgAKg1Aqg1C6k1Gak0Jqo0OKozSaszWawyaK0xd64wh68vl7AtprEstLEqwbIoz7Il37EiALQ6AbU6BLU6FbU5KbY5ObY5Sbc4Wbg3aLk3d7o2hrs0lbwzo70ysL0wvb4uyr4r3L8nFcBAGMBAHMBAIsA/MME/PsE/TcI+XMM+a8Q9ecU8h8Y7lcc6occ5rsg3usk1yMoy28suGctGHMxFIsxFK8xFN8xFRM1FUs5EX85Ebc9DetBCh9FBk9JAn9M/q9Q+t9Q8xtU53Nc0Et5KFd5KGt5KIt9JLt9JPd9JS+BJWOFIZuJIcuJHfuNGieRFleVEoeZDruZAweg92uk3AAALFwAKJwAJNgEJRgEIVAMIZAMHdgUGjQgFpAsEtg0DxhAD1xIC6BUB+BcB/xkA/xsABA8QEBAQIREPMBIPPxMPThQOXxUNcRYNiRgLoRkKsxkJxBkH1hcG6BYF+RcE/xkC/xsBChwUEx0UHh4ULB8TPCATSyESWyISbiMRhiQPnSUOsCUNwSUM0iQK5CMI9iAH/xwF/xsDESgZGCkZICoYKisYOSsXSCwXWS0WbC4VhDAUmjETrTERvTAQzy8P4S4N8iwL/ykJ/yMHFzQdGzQdIjUdKzYcNjccRjgbVzkbajoagzwYmD0XqT0Wuj0UyzwT3TsS7jkQ/jUO/zALFkEhGUEhHkEhJkIhNEMgQ0QgVUUfakYegkgdlUkcpkkat0kZyEkY2UgW6kYV+kQT/z8QEU8lE08lF1AlHlAlL1EkQFIkU1MjaVQigFUhklYgo1Yfs1YexFYc1lYb5lQZ9VIX/04VAWEpAmEoA2EoEWIoJWIoOGMnTmQmZmYlfGckjWcjnWcirmchv2cg0GYe4WQd8GIb/14ZAHIrAHIrAnMrDnMrG3QqL3UpSncoYngndXkmhXollXslpnskt3siyHsh2Hkg6HYe93IdAH8uAH8uAIAuAYAtDIEtMYMsS4QrYIUqcoYpgYcokYgnoYkmsoolwook0Yoi34kh7ocfAIwyAI0yAI0xCI4xII8wN5AvTZEuX5Itb5MsfpQrjpUqnpYpr5YnvpcmzJcl2pcj6ZYhAps1A5s1Bps1C5w1Ip00OZ0zTJ4zXJ8ybKAxe6Ewi6Ivm6Mtq6QsuqQqx6Qo1aQm5KMjAag5A6k5DKk5Gqk5Jqo4Oas4Sqs3Wqw3aa02eK41iK80mLAyp7ExtbIvwrItz7Ir4LIoALU/AbU/BLU+GLU+KrY+O7Y+Src9Wbg8abk8eLo7h7s6lrw4pL03sb41vr40y78x3b8tFsBEGcBEHcBEI8BEMcFEQMFDTsJDXcNCa8RBecVBiMZAlcc/osg9rsg8u8k6yco33MszG8xKHsxKJMxKLcxKOM1KRc1JU85JYM9Ibs9Ie9BHiNFGlNJFoNNEq9RDuNRBx9U+3dc5FN5PF95PHN5PJN9PMN9PPuBOTOBOWeFOZ+JNcuNNf+NMiuRLluVKouZIr+dGwehD2+k9AAAXGAAWKAAVOAEVRwEVVgMUZgMTeAUSjwgRpgsPuA0OyBAN2RIL6RUK+RcI/xkG/xsEBBAdEREcIhIbMRMbQBQaTxUaYBYZchgYihkXohoVtRoUxhoT1xgR6hcQ+hcO/xkL/xsJCx0gFB4fHx8fLSAePCEeTCIdXCMdbyQchyUbnyYZsSYYwiYX1CUV5SQT9yES/x0P/xsNEikjGSojISojKysiOiwiSS0hWi4hbS8ghTEenDIdrjIcvzEb0DAZ4i8Y9C0W/ykT/yQRFzUnHDUmIjYmKzYmNzclRzglWDkkbDsjhDwhmT0gqj4fuz0ezD0c3jwb8DkZ/jYX/zEVF0EqGUIpHkIpJ0MpNEMpREQoVkUna0cmg0kllkkkp0ojuEoiyUkg20kf60cd+0Qb/0AZEFAtE1AsF1AsH1EsMFEsQVIrVFMqalUpgVYok1cnpFcmtFclxVck11Yi51Uh9lIf/08dAWEvAWIvA2IvEmIuJmMuOWQtTmUsZ2crfGgqjWgpnmgormgnwGcm0WYl4mUk8WIi/18gAHMyAHMyA3MxDnQxHHUxMHYwS3cvYnkudnoshnsrlnsqp3wpuHwoyXsn2Xom6Hcl+HMjAIA1AIA1AIA1AIE0D4I0M4MzTIQyYYYxc4cwgogvkokuookts4orw4op0ooo4Ikn74clAI05AI05AI05Co44IY84OJA3TpE2YJI1cJM0f5Qzj5Uyn5Yxr5cvv5cuzZcs25cq6pYnAps9A5s9Bps9DJw8JJ08O547TZ86XaA6baA5fKE4jKI3nKM2rKQ0uqUzyKUx1qQv5aQsAqlBBalBD6lBG6pAKKpAO6s/S6w/W60+aq09ea49ia88mbA6qLE5trI4w7I20LI04bIxAbVGArVGCbVFG7VFLbZFPbdFTLdEW7hEarlDebpCiLtBl7xApb0/sr49v748zL853r82GMBMGsBMHsBMJsBLNMFLQsFLUMJKXsNKbcRJe8VJicZIlsdHo8hGr8hEvMlDyspA3cs8HsxSIcxSJ8xSMMxSO81SSM1SVc5RYs9Rb9BQfNBQidFPldJOodNNrdRMudVKyNZI3tdDGN5YGt9XH99XJt9XM99XQeBXTuFWW+FWaOJWdONVgORVi+RUl+VTo+ZSsOdQwuhN3OpHAAAjGQEiKQEhOQEhSAIgVwIgaAMfeQUekQgdqAsbug0ayhAY2hIX6xUV+xcT/xkR/xsOBREoEhInIxMnMhQmQRUmUBclYRckdBgjjBoioxsgthsfxxse2Rkc6xgb/BcZ/xkX/xsUDB4rFR8qICAqLiEpPSIpTSMoXSQncCUmiSYloCcjsiciwych1SYg5yUe+CIc/x4a/xsYEyotGiotIistLCwsOy0sSi4rWy8qbjAqhzIonTMnrzMmwDIl0TEj4zAi9S4g/yoe/yUcGDUwHDYwIzYwLDcvODgvSDkuWToubTsthT0rmj4qrD4pvD4ozj4m4D0l8Toj/zci/zIgF0IzGkIzH0MzJ0MyNUQyRUUxV0YxbEgvhEkumEotqEssuUsrykoq3Eoo7Egn/EUl/0EjEFA2ElE2F1E2H1I1MVI1QlM0VFQza1YyglcxlFgwpVgvtVguxlgt2Fcr6FYq91Mo/1AnAGI5AWM4AmM4E2M4JmQ4OWU3T2Y2aGg1fWk0jmkzn2kyr2kxwWgv0mcu42Yt8mMr/2AqAHM8AHQ7BHQ7D3Q7HHU7MnY6THg5ZHk4d3s3h3s2l3w1qHw0uX0yynwx2nsv6Xgu+XQsAIA/AIA/AIE/AIE+EoI+NIM9ToU8Y4Y7dIc6g4g5k4k5o4o3tIs2xIs104sz4Yox8IgvAI1DAI1DAI5CDo9CIo9BOpFBUJJAYpM/cZQ/gJU+kJY9oJc8sZc6wJg5zpg33Jc165czAptHA5tHBpxGDp1GJ51GPZ5FT59EX6BEbqFDfaJCjaNBnaRAraQ/vKU+yaU816U656Q4BKlLCKlLEqlLHapKK6tKPatKTaxJXa1JbK5Ie69Hi7BHmrFGqbJEt7JDxLJC0rNA4rI9ArVQBLVQEbVQILZQMLZQP7dQTrhPXbhPbLlOe7pOirtNmbxMpr1Ls75KwL9Izr9G38BDG8BXHcBXIcBXK8FXOMFXRcJXU8JWYMNWb8RVfcVVi8ZUmMdTpchSsclRvslQzMpO38tKI8xeJsxeLMxeNM1eP81eS85eV85eZM9dcdBdftFci9Jcl9Jbo9Nar9RZu9VYytZV4ddRHN9jHt9jIt9jK99jN+BjROBiUeFiXeJiauJhduNhguRgjeVgmeZfpOdesudcxOla3upVAAAuGgEtKwEsOgIsSQIsWAMraQMqewUpkggoqgsmvA0lzBAk3BIi7RUh/Rcf/xkd/xsaBhIyExMyJBQxMxUxQhcwURgwYhgvdRkujRstpRwrtxwqyBwp2hsn7Bkm/hck/xki/xsgDR81FiA0ISE0LyIzPiMzTiQyXiUyciYxiicvoSgusygtxCgs1icq6CYp+iMn/x8l/xsjFCs3Gis3Iyw3LS02Oy42Sy81XDA1bzE0iDMynjQxsDQwwTMv0zIu5TEs9i8r/ysp/yYnGDY6HDc6Izc6LDg5OTk5STo4Wjs4bjw3hj41mz80rT8zvT8yzz8x4T4v8jsu/zgs/zMrGEM9G0M9IEQ9KEQ9NkU8RkY8WEc7bUk6hUo5mUs3qkw2ukw1y0s03Uoz7kkx/UYw/0IuD1FAElJAFlJAIFNAMVM/QlQ/VVU+bFc9g1g8lVk7plk6tlk5yFk42Vg26lc1+VQz/1AxAGNDAGRDAWRDE2VDJ2VCOmZCUGdBaWlAfmo/j2o+oGo9sWo8wmo702k65Gc482Q3/2E1AHRHAHRHBnVGEHVGHXZGM3dFTXlEZXpDeHtCiHxBmH1BqX1Aun0+y30923w86nk6+nU4AIFKAIFKAIFKAIJKFoNJNoRJUIVIZIdHdYhGhIlGlIpFpYtEtotCxoxB1ItA44s+8ok8AI5OAI5OAY5OEY9OJJBNPJFNUpJMY5NMc5RLgpVKkpZJopdIsphHwphG0JhF3phD7ZdBApxTA5xTBpxTEJ1SKp5SP59SUaBRYaFRcKFQf6JPj6NPn6ROr6VNvaZMy6ZK2aVJ6KVGCKlYDKpYFapYIKpYL6tYQKxYUKxXX61Xbq5Wfa9WjbBVnLFUq7JTubNSxrNR1LNP5LNNBbVfDbVfGbZfJ7ZfNbdfQ7deUbheYLleb7pdfbtdjLxcm71bqb5btr5awr9Y0L9X4sBUHsBmIcBmJ8FmMcFmPMFmScJlVsNlZMNlcsRkf8VkjcZjm8djp8his8lhwMpgzspe4stbKMxsK8xrMM1rOM1rQ81rTs5rWs9rZ89qdNBqgdFpjdJpmdNopdRosdRnvdVmzdZk49hgIN9vIt9vJuBvL+BuO+BuR+FuU+FuYOJubONteORtg+Vsj+VsmuZrpudqtOhpxuln4OtjAAE5GwE3KwI3OwI2SgM2WQQ1agQ1fQU0lAgyrAsxvQ0wzRAv3hIt7xUs/hcq/xko/xsmBxM9FBQ8JBY8Mxc7Qxg7Uhk6Yxo5dhs5jhw3ph02uB41yh002xwy7hox/xcw/xku/xssDSA/FiE/ISI/MCM+PyQ+TiU9XyY8cyc8iyg6oik5tSk4xik31yg26ic0+yQz/yAx/xsvFSxCGyxCIy1CLi5BPC9BTDBAXTFAcDI/iTQ9nzU8sTU7wjQ61DM55jI4+DA2/yw1/yczGDdFHDhFIzhFLDlEOjpESTtEWzxDbz1CiD9BnUBArkA/v0A+0EA94j878zw6/zk4/zQ3GURIHERIIEVIKEVIN0ZHR0dHWUhGbkpFh0tEmkxDq0xCu0xBzUxA3kw/70o9/kc8/0M6D1NMEVNMFlNLIVRLMlRLQ1VKVlZKbVhJhFlIl1pHp1pGuFpFyVpE2llD61hB+lVA/1E+AGVPAGVPAWVPFWZPKGZPO2dOUWlNampMf2tLkGxLoWxKsmtJw2tI1WpH5WhF9GVE/2JCAHVTAnVTCHVTEXZTHndSNXhST3lRZ3tQenxQin1Pmn5Oqn5NvH5MzX5L3H1K7HpI/HdHAIFYAIFYAIJYAIJXGoNXOYVWUoZWZodVd4lUholUlopTp4tSt4xRx4xQ1oxP5ItN84pLAI5dAI9dA49dFJBdJ5FcP5JcVJNbZZRbdZVahJZalJdZpJhYtJhXxJlW0plV4JlU75hRApxjA51jB51jF55iL55iQ59iVKBhY6FhcqJhgaNgkaRfoaVfsaZewKZdzaZc26Za6qVYDappEappGqppJKtoNKtoRKxoU61oYq5nca9nf7Bnj7Fmn7JlrbJku7NkyLNi1rRh57NfELZuF7ZuILZuLLZuObduR7duVbhuY7ltcbptgLtsj7xsnb1rq75quL9qxb9p0sBn5MBlIcB0JsFzLMFzNcFzQMJzTMJzWcNzZsRydMVygsZxkMdxnchwqchwtslvwspu0Mts5MxqLM13L813NM13PM13Rs53Uc53Xc93adB2dtF2gtF1j9J1m9N0p9R0stVzv9Zyz9dw5dhuI+B5JOB5KuB5M+F5PuF5SeJ5VeJ5YuN4buR4eeR4heV3kOZ3nOd2p+h1tel0yOpy4uxvAAFDGwJCLANCOwNBSwNBWgVAawVAfgU/lgg9rQs8vw07zxA64BI58RU3/xc2/xk0/xsyBxRIFBZHJRdHNBhGQxlGUxpFZBtFdxxEjx5Dpx9Buh9Ayx4/3R0+7xw9/xg8/xk6/xs4DiFLFyJKIiNKMCRKQCVJTyZJYCdIdChHjCpGpCtFtitExypD2SlC6yhA/SU//yE+/xs8Fi1OHC1NJC5NLi9NPTBNTTFMXjJLcTNLijVJoTZIszZHxDZG1TVF5zNE+TFD/y1B/yg/GDhRHDlRIzlRLTpQOztQSjxQXD1PcD5OiUBNnkFMr0FLwEFK0kFJ5EBI9T5H/zpF/zVEGUVVHEVVIUZUKUZUOEdUSEhUWklTb0tSiExRm01QrE5PvU5Pzk1O4E1M8UtL/0hK/0RID1RZEVRZFVRZIlVZM1ZYRFdYV1hXb1lXhlpWmFtVqFtUuVtTy1tS3FpR7VlQ/FZP/1JNAGZdAGZdA2ZdF2ddKWhdPGldUmpca2tbgGxakm1aom1Zs21YxWxY1mtX52lV9mdU/2NSAXVjBHZjCnZjEndiH3diOHliUXphaXxgfH1gjH5fnH9frH9evoBdzn9c3n5b7Xxa/XhYAIJoAIJoAIJoAINoH4RoPIVnVIdnaYhmeolmiYplmItlqYxkuo1jyo1i2I1h5oxg9opeAI9uAI9uCJBuGJBuKpFtQpJtV5RsaJVsd5Zshpdrlpdrpphqt5lpxppo1Jpn4plm8ZhkAp1zBJ1zCZ1zHZ5zM59yRqByV6FyZqJxdaNxg6Rwk6Rwo6Vvs6Zuwqduz6dt3ads7aZqEKp3Fap3HKt3J6t3OKx3R613Vq12ZK52c692grB1kbF0obJ0r7NzvbRyyrRy2LRw6bRvGLZ7HLZ7JbZ7MLd7Pbd7Srh7V7l6Zbl6dLp6grt5kbx5n754rb53ur93xsB21MB15sFzJsF/KsF/MMF/OcF/Q8J/T8N+W8N+aMR+dsV9hMZ9kcd8n8h8q8l7t8p7xMp60st45sx2L82CMs2CN82CP86CSM6CU8+CX8+Ba9CBeNGBhNKAkdOAndR/qNV/tNV+wdZ90Nd86Nh5I+GEJuGELeGENuGEQOKDS+KDV+ODY+SDcOSCe+WChuaCkueBneiBqemAt+p/yut95e16AQFPHAJOLQNNPARNSwVMWwVMbAZLfwdLmAhKrwtIwQ1H0RBG4hJF8xRE/xdC/xlB/xs/CBZUFRdTJRhTNBlTRBpSVBtSZRxReB1RkR9PqCBOuyBNzCBM3h9L8B1K/xpJ/xlH/xtFDyNXGCNXIyRWMSVWQCZWUCdVYShVdSlUjitTpSxStyxRyCtQ2ipP7SlO/idN/yNL/xxKFy5aHS5aJS9aLzBaPjFaTjJZXzNZczRYjDZXojdWtDdVxTdV1zZU6TVT+zJR/y5Q/ylOGDlfHTpfJDpfLTtePDxeTD1eXT5eckBdi0FcoEJbsUNawkJa1EJZ5UFY9z9X/zxV/zZTGkZkHUZkIkdkKkdjOUhjSUljW0pjcUxiik5hnU5grk9gv09f0E9e4k5d80xc/0lb/0VZD1VpEVVpFFZpI1ZpNFdpRVhpWVlocFpnh1xnmlxmql1lu11lzVxk3lxj71pi/lhh/1RfAGduAGduBmhuGWhuKmluPmpuVGttbW1tgm5sk25rpG5rtW5qx25q2G1p6Wto+Ghn/2RlA3Z0BnZ0DHd0FHdzIXhzOnlzU3tya31yfn5xjn9xnYBwroBvwIFv0IFu4IBt731s/3prAIJ5AIN4AIN4AoR4I4V4P4Z3Vod3a4l2fIp2iot1mox1q410vI1zzI5z2o5y6I1x+ItvAJB9ApB9DJB9GpF8LJJ8RJN7WZR7apV6eZZ6iJd6mJh5qJl4uJp4yJp31pt25Jp185l0Ap2AA56ACp6AIJ+ANaB/SKF/WKF/aKJ+dqN+haR9laV9paZ8tad7w6h70ah636d576d4E6uDFquDHquDKqyDOqyDSa2CWK6CZq+CdbCBg7GBk7KAorOAsbR/v7R+zLV+2rV967V7HLaHIbeHKbeGM7eGP7iGTLiGWbmGZ7qFdbuFg7yEkr2Eob6Dr7+Du8CCyMCB1sGA6MF/KsGKLsGKNMKKPMKKRsKJUcOJXcSJasSJeMWIhcaIk8eHoMiHrcmGucqGxcuF1MyE6c2CM86NNc6NOs6NQc6MS8+MVc+MYdCMbdGMetKLhtKLktOKntSKqtWJttaJwteI0tiH6tmEJuKOKuKOL+KOOOKOQuOOTeOOWeSOZeSNceWNfOaNiOeMk+iMnumLqumLuOqKy+yI5+6GAQJbHQNbLgRaPQVaTAZaXAdabQdZgAhYmQpXsQtWww1V0xBU5BJU9RRS/xdR/xlQ/xtOCRdhFhhhJhlhNRthRRxhVR1gZh5geR9fkiFeqiJdvSJdziFc4CBb8h5a/xxZ/xlX/xtVECRmGSVmJCZlMidlQShlUSllYyplditkjyxjpy1iuS1iyi1h3Cxg7ipf/yhe/yRd/x5bGC9qHjBqJjBqMTFqPzJqTzNqYDRqdDZpjjdopDhntjlnxzhm2Thl6zZk/DRj/zBi/yphGTpwHTtwJDtwLzxvPT1vTT5vXj9vc0FujENtoURts0RsxERs1URr50Nq+UFp/z1o/zhmG0d1HUd1Ikh1K0l1O0l1S0p0XEx0ck1zi09zn1BysFBxwFBx0lBw5E9v9U5u/0tt/0ZsD1d6EFd6E1d6I1h6NFl5Rll5Wlp5cVx4iV13m152rF52vF51zl514F108Fxz/1ly/1VxAGh+AGl+CGl+Gmp+Kmp+Pmt9VW19bm58g297lHB7pXB6tnB5yHB52W946m13+Wp2/2Z1BXeCCHeCDniCFniCInmBO3qBVHyAbH5/f39/j4B+n4F+sIF9wYJ80oJ84YF78H96/3t5AIOFAIOFAISFBISFJIWFQIeEWIiEbIqDfYuCjIyCm42BrI6BvY6AzY9/3I9+6o5++Y18AJCJApGJDZGIGpKILpOIRpSHWpWHa5aGepeGiZiFmZmFqZqEupuDyZuD15uC5ZuB9ZqAAZ6MA56LCp+LIp+LNqCLSaGKWqKKaaOKeKSJhqWJlqaIpqeItqiHxKiG0qmG4KiF8KiDFKuOF6uOH6yOLKyOPK2OS66OWa6NZ6+NdrCMhbGMlLKLpLOLsrSKwLWKzbWJ27aI7LWHILeRJLeRK7eRNriRQbiRTrmRW7mRabqQd7uQhbyPlL2Por+OsL+OvcCNysGM18GM6sKKLsKVMcKVN8KVPsKUSMOUU8OUX8SUbMWUesaTh8eTlciSosmSrsqRu8uRx8uQ1syP682NNc6YOM6YPc6YRM+XTc+XV9CXY9CXb9GXe9KWiNOWlNSWoNWVq9aVt9aUxNeT1NiS7NqQKeKZLeOZMuOZOuOZROOZT+SZW+WZZ+WZc+aYfueYieiYlOmXoOqXq+qWuuuVze2U6e+SAQNqHgRqLgVpPgZpTgdpXQhpbglpggpomwxnswxmxg1m1g9l5xJk+BRj/xdi/xlh/xtfChlyFxpyJxtxNhxxRh1xVh5xZx9xeyBwlCJvrCNuviNu0CNt4iJs9CBr/x1q/xlp/xtoESV2GiZ2JSd2Myh2Qil2Uyp1ZCt1eCx1kS50qC9zuy9yzC9y3i5x8Cxw/ypv/yZu/yBtGTB7HzF7JzJ6MTN6QDN6UDR6YTZ6dTd5jzl4pTp3tzp3yDp22jl17Th0/jV0/zJz/yxxGDx/HTx/JD1/Lz5/Pj5+Tj9+X0F+dEJ9jkR8o0V7tEV7xUV610V56UR5+kJ4/z93/zl2GkmDHUmDIUmDK0qDO0uCS0yCXU2Cc0+BjFCAoFF/sVJ/wlJ+01F95VF89k98/017/0h6DViHDlmGEVmGIlqGNFqGRluGWVyFcV6EiV+EnGCDrGCCvWCCz1+B4V+A8V1//1t//1d9AGqKAGqKCWqKGmuKKWyJPm2JVG6IbnCIhHGHlXKGpXKGtnKFyHKE2nGE62+D+myC/2iBBXiNCXiNDnmNFXmNInqMO3uMVX2LbX+LgICKkIGJoIKJsYOIwoOI04OH4oKG8YGF/32EAISQAISQAIWQBYWQJYaPQIiPWImObYuOfoyNjY2NnY6MrY+Mvo+LzpCK3ZCK64+J+46IAJGTAJGTDJKTG5KTLpSSRpWSW5aRbJeRe5iRipmQmpqQq5uPu5yOypyO2JyN5pyM9puLAJ+WAZ+WCaCWI6CWN6GVSqKVW6OVaqSUeaWUh6aTl6eTp6iSt6mSxqmR06mQ4amQ8qmPFayZGKyZIKyZLq2ZPa6YTK6YW6+YabCYd7GXhrKXlbOWpbSWtLWVwbaVz7aU3LaT7raSI7ecJ7ecLricOLicQ7mcULmcXbqbarubebybh72alr6apL+ZssCZvsGYy8GY2cKX7MOVMcKfNMKfOcKfQcOfSsOfVcSfYcSfbsWffMaeiceel8idpMmdsMqdvMucycyb182b7c6ZOM+iO8+iP8+iRs+iT9CiWdCiZNGicdKhfdOhidShltWhodWgrdagudefxdif1tme7tqcLOOkL+OkNeSkPeSkRuSkUeWkXOakaOakdOejf+iji+mjluqioeuireuiu+yhz+6f6/CdAgR7HwZ6Lwd6Pgh6Tgl6Xgp6bwt5gwx5nA54tA93yA522A926RJ1+hR0/xdz/xly/xtxCxuBGByBJx2BNh6BRh+AVyCAaCGAfCJ/lSR+rSV9wCV90SV84yR79iJ6/yB5/xt4/xt3EieFGyiFJSmEMyqEQyuEUyyEZC2DeC6DkjCCqTGBvDGAzTCA3y9/8i5+/yx9/yh8/yJ7GTKIHzKIJzOIMTSIQDWIUDaHYjeHdjmGkDuFpjyEuDyEyTyD2zuC7jqB/jeB/zSA/y5/Fz2MHD6MIz6LLj+LPUCLTkGLX0KKdESJjkaIo0eItUeHxkeG2EeG6kaF+0SE/0GD/zuCGEqPG0uPIEuPKkyOOk2OSk6OXU+Nc1CNjFKMoFOLsVOKwlOK1FOJ5lKI91GI/06H/0qGC1qSDFqSD1uSIFuSMlyRRV2RWV6RcWCQiWGPnGKOrWKOvmKN0GGM4mGM8l+L/1yK/1iJAGuVAGuVCmyVGWyVKG2UPW6UVHCUbnGThHOSlXSRpnSRt3SQyXSQ23OP63GO+26O/2qNBHmYB3mYDHqYFHqYIXuYO3yXVX6WbYCWgIGVkIKVoIOUsYSUw4ST1IWS44SS8oKR/3+QAIWbAIWbAIabBYabJIebQIiaWYqabYyZf42Zjo6YnY+YrpCXv5CWz5GW3pGV7JCU/I+TAJKfAZKeDJOeGpOeLZSeRpadW5edbZicfJmci5qcm5ubrJybvJ2ay52Z2p2Z6J2Y+JyXAKCiAKChCKChI6GhOKKhS6OgXKSga6WgeqafiKefmKifqameuKqex6qd1aqc46qc86qbFaylGK2kIK2kL62kP66kTq+kXLCkarGjebKjh7Ojl7SiprWitbahw7ah0Leg3ref8LeeJrioKrioMLinOrmnRbmnUrqnXrqnbLunerymiL2ml7+lpsCls8GkwMGkzcKj28Oj7sOhM8KrNsOrO8OrQ8OrTMSrV8SqY8WqcMaqfceqisipmMmppcqossuovsyoysyn2c2m786lOs+uPc+uQdCuSNCuUNCtW9GtZtKtctKtftOti9Ssl9Wso9asr9erutirx9iq2Nmp8duoLuSwMeSwN+WwPuWvSOWvU+avXuevauevdeivgOmujOqul+uuouytru2tve6s0e+r7fGpAgWJHweILwiIPwqITguHXwyHcA2Hgw6GnRCFtRKEyBGD2RGD6xKC/BSB/xeA/xl//xt+Cx2OGB6OJx+NNiCNRiGNVyKMaCOMfCSLlSaKrSeJwCeJ0ieI5CaH9iSH/yKG/x2F/xuEEimRGimRJSqQMiuQQiyQUy6QZC+PeDCOkjKNqjONvDOMzjOL4DKK8jCK/y6J/yqI/ySHFzOUHTSUJTWUMDaTQDeTUDiTYTmSdjqSkDyRpz2QuT6Pyj6O3D2O7zyN/zmM/zaL/zCKFz+XGj+XIkCXLUGWPUKWTUOWX0SVdEWVjkeUpEiTtkmSx0mS2UmR60iQ/EaP/0OP/z6OFUyaGEyaHU2aKE6aOU6ZSk+ZXFGZc1KYjFSXoVWWslWWw1WV1VWU51SU+FOT/1CS/0yRCFydCV2dDF2dHl6dMF6dQ1+cWGCccGKbiWOanGSarWSZvmSY0GOY4mOX82GW/16W/1qVAG2gAG2gCW2gGW6gJ2+gPHCfU3GfbXOehHWdlXWdpnact3acyXab23Wb7HOa+3CZ/2yYAnqkBXqkCnukEnujH3yjOn2jVH+ibYGhgYKhkYOgoYSgsoWfxIaf1Iae5Iad84Sd/4GcAIanAIanAIanBoenJIimP4mmWYulbo2lf46kjo+knpCjr5GjwJGi0JKi35Kh7pGg/ZCgAJOqAZOqC5SqGJSqLZWpRpepXJiobZmofZqojJunnJynrZ2mvZ6mzJ6l256l6Z6k+Z2jAKCtAKGtB6GtI6KtOKOsS6SsXKWsbKare6ariairmamqqqqquaupyKup1quo5Kuo9aunFq2wGa2wIK6wMK6wQK+vTrCvXbCva7GverKuiLOumLWtqLattretxLes0bis37ir8riqJ7izK7izMbmzO7mzR7qzU7qyYLuybbyye72yib6xmL+xp8CwtcGwwcKvzsOv3MOu8MStNcO2OMO2PcO2RMS2TsS2WMW1ZMW1cca1f8e1jMi0mcm0p8q0s8uzv8yzzM2y286y8c+wO9C5PtC4QtC4SdG4UtG4XNK4Z9K4c9O4gNS3jNW3mNa3pNe2sNi2vNi2yNm12tq089yzMOW6M+W6OOa6P+a6Sea6U+e6X+i6aui5dum5geq5jOu5mOy4o+24r+64vu+30vC28PK0AweVHgmULguUPgyTTg6TXg+TcA+SgxGRnRORtRSPyROP2hOO7RKN/RSN/xeM/xmL/xuKCh+ZFyCZJSGZNSKYRSOYViSYZyWXeyeXlSiWriqVwSqU0imT5SiT9yeS/ySR/yCQ/xuPESqcGiucJCycMS2bQS6bUjCbZDGaeDKakjSZqjWYvTWXzjWX4DSW8zOV/zCU/yyU/yaTFjWfHDafJDafLzefPjieTzqeYTuddTydkD6cpz+buUCay0Ca3T+Z7z6Y/zyY/ziX/zOWFkGiGkGiIEKiK0OiO0SiTEWhXkahdEegjkmfpEqetkuex0ud2Uud60qc/Uib/0Wb/0CaEU6lFU6lGk+lJlClN1GlSFKlW1OkclSjjFajoVeislehw1eh1Veg6Faf+FWf/1Ke/06dBF6pBV+pCF+pG2CoLmGoQWGoVmOnb2SniGamnGalrWalvmak0Wak42Wj9GOi/2Gi/1yhAG6sAG6sB2+sGG+sJXCsOnGrUnOrbXWqhHaplXeppniot3ioynin23im7Ham/HOl/26lAnuvBHuvB3yvD3yvHX2vOX+uVICubYKtgYSskYWsooass4arxIer1Yiq5Yep9Iap/4OoAIezAIezAIeyBoiyJImyPoqxWIyxbo6wgI+wj5Cvn5GvsJKuwZOu0ZOt4JOt75Os/pKrAJS2AJS2CJS1FZW1Kpa1RZi0W5m0bZqzfZuzjJyznJ2yrZ6yvp+xzaCx3KCw6p+w+p6vAKG4AKG4BaK4IaK4N6O3S6S3XKW3bKa2e6e2iqm2mqq1qqu1uqy0yay016yz5ayz9qyyFa67Ga67H667MK+6QK+6T7C6XbG6bLK5erO5ibS5mbW4qLa4t7e3xbi307m24bm287m1KLm9LLm9Mrm9PLq9R7q9U7u9YLy9bry8fL28ir+8mcC7qMG7tsK6w8O6z8O53sS58sW4NcPAOcTAPsTARcTATsXAWcW/Zca/cse/f8i/jcm+msq+qMu+tMy9wc29zc683M6889C6O9HCPtHCQtHCSdHCUtLCXNLCZ9PCdNTBgNXBjNbBmdfApdjAsdjAvNm/ytq/29u+9d29L+bEMubEN+fEP+fDSefDU+jDX+nDa+nDd+rDgevCjezCmO3Co+7CsO/BvvDB0/LA8vS+AwqgHQyfLQ2fPQ6fTRCeXhGebxKdgxOdnRWcthebyRaa2haa7RSZ/xSY/xeX/xmX/xuWCiGlFyKkIyOkMySkRCakVSejZyijeymilSuhriygwSyg0yyf5Sue+Cme/yed/yOc/xybESyoGS2nJC6nLy+nQDCnUTKmYzOmdzSlkjakqjekvTijzjei4Tei9DWh/zOg/y+g/ymfEzerGTirIjiqLTmqPTqqTjuqYD2pdT6pj0Cop0KnukKmy0Km3UKl8ECk/z6k/zuj/zWiFUOuGUOuHkSuKUStOkatS0etXUitc0msjkurpE2qtk2qx02p2k2p7Eyo/Uun/0in/0OmDVCxEFGxF1GxIlKxNFOxRlSwWlWwcVavjFiuoVmuslqtxFqt1lms6Fmr+Ver/1Wq/1CpAWG0AWG0BGG0F2K0K2O0PmS0VGWzbmeyh2ixm2mxrWmwvmmw0Wmv42iv9Gau/2Ou/1+tAHC4AHC4BHC3FHG3I3K3N3O3UHS2a3a1g3i1lXm0pnq0t3qzynuz3Hqy7Hmx/Hax/3GwAHy7AX27A326CX66GH66N4C6UoG5bIO4gYW4kYa3ooe3s4i2xYm21om15om19Ii0/4azAIi+AIi+AIm9A4m9IYq9PIy8V428bY+7f5C7j5G6n5K6sJO5wpS50pW44ZW475S3/5O2AJXAAJXABJXAEJbAJpe/Q5m/Wpq+bZu+fZy9jJ29nZ69rp+8vqC8zqG73KG766G6+6C5AKLDAKLCBKPCHaPCNKTCSqXBXKbBbKfBe6jAiqrAmqu/q6y/u62+yq2+2K695q699628Eq7FFa7FHK/ELq/EP7DETrHEXbLEbLPDerTDibXDmbbCqbfCuLjBxrnB07rA4rrA9Lq/KLnHK7nHMbrHO7rHR7vGU7vGYLzGbr3GfL7Fi7/FmsDFqcLEtsPEw8PD0MTD38XC88bBNcTJOMTJPcTJRcXJTsXJWcbJZcfJcsfIgMjIjcnIm8vHqMzHtc3Gwc3Gzs7G3s/F9dDEOtHLPdLLQtLLSNLLUdPLW9PLZ9TLdNXKgNbKjdfKmdjKpdjJsdnJvdrJytvI3NzH997GLufNMejNNujNPujNSOnMU+nMXurMauvMduzMgezMje3LmO7LpO/LsPDKv/LK1PPJ9PXHAwyrGw6rLBCqOxGqTBKqXRSqbhWpghepnBiothmnyRmm2xmm7hil/xak/xaj/xmj/xuiCSOwFiSwIiawMSewQiivVCmvZiqveiyulC6tri+swS+r0y+r5S6q+Cyq/yqp/yao/x+oEC6zGC+zIzCzLjGzPjOyUDSyYjWydjexkTiwqjqvvTqvzjqu4Tmu9Dit/zas/zKs/yyrEDm2Fjq2Hzq2Kzu2Oz22TD61Xz+1dEG0j0Ozp0SyuUSyy0Sx3USx8EOw/0Gv/z6v/ziuFEW5GEW5HUa5Jke5N0i5SUm4XEq4cky3jU62pE+2tk+1x1C12k+07E+z/U2z/0qy/0axClO9DVO8EVS8HFW8MFW8Q1a8V1i7b1m6ilu5oFy5sly4w1y41ly36Fu2+Vq2/1e1/1O1AGO/AGO/AGS/D2W/JmW/Oma/UWi+a2m9hmu8mmy8rGy7vWy70Gy642u69Gm5/2a4/2K4AHHCAHHCAXLCD3PCH3PCM3XBTnbBanjAgnq/lHu/pXy+t32+yX2923287Hy8/Hm7/3S7AH7FAH7FAH7FBH/FEYDEM4HEUIPDa4XCgIbCkYfBoonBs4rAxYrA1ou/5ou/9Yq+/4i+AInIAInHAIrHAIrHHYvHOI3GVY7GbJDFf5HFjpPEn5TEsJXDwpbC0pbC4ZbB8JbB/5XAAJbKAJbKA5fKC5fJH5jJQJrIWJvIbJzHfJ7HjJ/HnKDGraHGvqLFzqLE3aPE66LE/KHDAKPMAKPMAqTMF6TLMKXLR6bLWqjKa6nKeqrJiavJmqzJq63Iu67Iyq/H2K/H5q/G+K/FDK/OD6/OF7DOKbDNPLHNTbLNXLPNa7TMerXMibbMmbfLqbjLuLnKxrrK1LvJ4rvJ9bvIJbrQKLrQL7rQObvQRbvQUrzPX73Pbb7PfL/Oi8DOmsHOqcLNt8PNxMTN0cXM4MbM9cfLMsXSNsXSO8XSQ8XSTcbSWMbSZMfSccjRf8nRjcrRm8vQqczQts3Qws7Pz8/P39DO9tHNONLVO9LVP9PURtPUT9PUWtTUZtXUc9bUgNfUjNjTmdnTptnTstrSvtvSy9zS3d3R+d/QK+nWLunWM+nWO+nWRurWUerWXevWaezWdu3Wge7Vje/VmPDVpPHVsPLVv/PU1fXU9vfSAxG3FxK3KRO2ORS2ShW2Wxe1bRi1gRq0mxuztR2yyR2y2xyx7hux/xqw/xav/xmv/xquBia8FCe8ICi7Lim7QCu7Uiy6ZC26eC+5kzC4rTK3wTK30jK25TG2+DC1/y20/ym0/yOzDjG/FjK/IDO+KzS+OzW+Tja9YDi9dTm8jzu7qT26vD26zj254T259Du4/zm3/zW3/y+2DjvBEzzBGj3BJz7BOD/BSkDAXUHAckO/jUW+pke9uUe9y0e83Ue78Ea7/0S6/0G6/zy5EkfEFUjEGkjEIknEM0rDRkzDWU3Db07Ci1DBo1LAtVLAx1K/2VK+7FK+/VC9/029/0m8CVbHC1bHDlfHE1jGKljGP1nGVFvFbFzFiF7En1/DsV/Cwl/C1V/B6F7B+V3A/1q//1a/AGXKAGbJAGbJBmfJH2jJNWnITWrIaGzHg27GmG/FqnDFvG/Ez2/E4m7D82zD/2nC/2XCAHPMAHPMAHTMCXTMGHXLLnbLSnjKZ3rJgHzJk33IpX7Itn/HyYDG24DG63/F+33F/3jEAH/OAH/OAIDOAIDOBYHOLILNTITNaIbMf4jLkInLoYrKsovKxIzJ1o3I5o3I9YzH/4rHAIrRAIvRAIvQAIzQFY3QMY7PUZDPapLOfZPNjZTNnpXNsJbMwZfL0pjL4ZjK8JjK/5fJAJfTAJfTAJjTB5jSFZrSOpvSVZ3Rap7Qe5/QiqDQm6HPraLPvqPOzqTO3aTN66TN/KPMAKTVAKTVAKTVDqXUKabUQ6fUV6nTaarTeavTiKzSma3Sqq7Ru6/RyrDQ2LHQ57HP+bDPArDXBrDXDrDXIbHXOLLWSrPWWrTWabXVebbViLfVmLjUqbnUuLrUx7vT1LzT47zS9r3SHrrZI7vZKrvZNbvZQrzZUL3ZXr7ZbL7Ye8DYisHYmsLXqcPXt8TXxcXX0sbW4cfW9sjVLsXcMsXcOMbcQMbcS8bcVsfcY8jccMncf8rbjcvbm8zbqc3bts7bw8/a0NDa4NHa+NLZM9PgN9PgPNTgQ9TgTdTgWNXgZNbgcdfff9jfjNnfmdrfptvfstvfvtzfzN3f3t7e++DdJurjKerjL+rjOOvjQ+vjT+zjXOzjaO3jde7jge/jjfDjmPHjpPLksfTkwPXj1vfj+frhBBTCFBXCJhbBNhfBSBnBWRrAaxvAgB2/mh6+tCC9yCC92iC87R+7/x27/xq6/xi5/xq5BSjHESrGHivGKyzGPS7FTy/FYjDEdjLEkTTDrDXCwDbB0jXB5TXA+DO//zG//y2+/ye9CTPJETTJHDXJKDbIODjISjnIXTvHcjzGjT7FqEDEvEDEzUDD4EDD8z/C/z3B/znB/zPACz7MED/LFz/LIkDLM0LLRkPKWkTKb0bJi0jIpUrHuErGykrG3UrF8ErE/0jE/0XD/0DDC0rOD0vOFEvOHUzNLU3NQU/NVVDMbFHLiFPKoVXKtFbJxlbI2VbI7FXH/VTH/1HG/03FBFnQBlrQCVrQDVvQIVzQOF3PTl7PZ2DOhGLNnGPMr2PMwWPL1GPK52LK+GHJ/17J/1rIAGjTAGjTAGnTAGrSGGvSLmzSR23RY2/QgHHPlnLPqHPOunPOzXPN4HLM8nHM/27L/2nLAHXVAHXVAHXVBXbVE3fUJnjURHrTYnzTfn7SkYDRo4HRtYHQx4LP2oLP64LO+4DO/33NAIDXAIHXAIHXAILXAIPXI4TWRobWZYjVfIrUjovUn4zTsY3TxI7S1Y/S5Y/R9Y7R/43QAIzaAIzaAIzaAI3ZCo7ZKJDZS5HYZpPXe5XXi5bWnZfWrpjVwJnV0ZrU4ZrU8JrT/5nTAJjcAJncAJncAprcDJvbMZzbUJ7aZp/aeKHZiKLZmqPZq6TYvaXYzabX3KbX66bX/aXWAKXfAKXfAKXfAqbeIafePKneU6rdZqvdd6zdhq3cmK/cqbDcurHbyrLb2LLb57La+bLaALDiALHiAbHiEbLhMLPhRbThV7XhZ7bhd7fgh7jgl7ngqLrguLzfx73f1b3f477f977eFLvmGrvlI7zlLrzlPr3lTb3lXL7lar/lesDlicLlmcPlqcTkt8Xkxcbk08fk4sjk98nkJ8bqK8bqMsbqPMfqR8fqU8jqYMnqbsrqfcvqjMzqm83qqc7qt8/qxNDr0dHr4dLr+tTqK9TwL9TwNdXwPtXwSNXwVNbxYdfxb9jxfdnxi9rxmdvxptzxst3yv97yzd/y4ODy/eLyH+v3Iuv3J+z3Mez3Puz3S+33We74Zu/4dPD4gPH5jfL5mfP6pfT6sfb7wff81/n8//39\",chrome64:\"AAAABgAAEAAAHAAALQEAQQIAXQUAeQkAjg0AoBAAshMAwRUA0BgA3hoA7R0A/CAA/SAAAwcBCggBFAkBIAoBMQwBRQ8BYRIBfBUAjxcAoRkAshoAwRoAzxoA3RoA7BwA+x8A/SAACRMFDxMFFxQFJBUFNRcFSRkEZRwEfh8DkiEDoyMCtCQCwyQB0SQB3iMA7CIA+iAA/CAAEiINFyINHSINKCMMOiUMTiYLayoKgiwKlS0Jpi4Hti4GxS4F0i0E4C0D7isC/CkB/SkBGzUWHjUWJTYWLzcVQDgVVjoUcz0TiD8Smj8Rqz8Quj4OyD0N1TsK4zkI8DYG/TME/jMDGE4gHE8gJU8gNlAfSFEfYFMee1UdjlUcoFUbsFUav1QYzVMW2lAU6E4S9UkP/0ML/0MKGmkqIWkqLGoqO2sqUG0pbG8ognEolXInpnMmtnMkxXMj03Eh4W4f7mkc+2MZ/10V/1wVIHw1KHw1NH01RX40XYA0dYMziIUymYYxqocvuoguyYks14kq5Yko84gm/4Yk/4Eh/4AgMI5BNo5BQo9BVpBAa5JAfZQ/jZY+nZc9rZg8vZo7y5s52Zs455w19Zwy/5sv/5kq/5kpRp5MTZ9MWJ9MZ6FLdaJLhKNLkqVKoaZJsahIv6lHzapG26tE6axC96xA/609/6w4/6w4Xa1aYa1aaK5aca5afK9aibFZlrJZpbNYs7VXwLZWzrdV3LlT6rpR+LtO/7tL/7xH/7xGablra7prcLpreLtrgrxqjb1qmb5ppr9ptMBowMJnzsNm28Rl6cZj98dg/8hc/8lX/8lXc8Z4dcZ4ecZ4gMd4iMh4ksl3nsp3qst2tsx2ws51zs9029Bz6dFy9tNw/9Rt/9Vp/9VpfdKDf9ODg9ODiNODkNSDmdWDo9aDrteCudiCxdqB0NuA3dx/6t5+9999/+B7/+F4/+F3h9+Pid+PjOCPkeCPmOGOoOKOqeOOsuSOveWNx+aN0+eM3+mL7OqL+euJ/+yH/+6F/+6Ekeyak+yale2ame2an+6apu6aru+Zt/CZwfGZy/KY1vOY4vWX7vaX+viV//mU//uR//uRmvqnm/qnnfqnofunpvunrPyntP2mvP6mxf+mzv+m2v+l5f+l8v+l/v+k//+j//+h//+gAAABAwABDAABGQABKwABPwEBXAQBdgcBiwoBnQ0ArhAAvhMAzRYA3BgA6xsA+h4A/B4AAQUHBgYHEQcGHQgGLwoGQw0GYBAFeRQFjRUEnxcDrxgDvhkCzBkB2hgB6RoA+B0A+h0ABxEMDBEMFBIMIhMMMxULRxgLZBsKfB4JkCAIoSEHsSIGwCIFziIE3CID6iEC+B4B+R4BESETFSETGyETJyITOSQSTSYSaikRgSsQkywPpC0NtC0Mwy0L0CwJ3isH7CoF+igD+ygDGjQcHTQcJDUcLjYbPzcbVTkacjwZhj4YmD4XqT4VuD4UxjwS1DoQ4TgN7zUK/DIH/TIHF04mG04mI08lNFAlRlEkYFIkelQjjVUhnlUgrlQfvVMdy1Ib2VAZ5k0W80kT/0MP/0IPF2gwHmgwKWkwOWowT2wvam4ugHAtk3EspHIrtHIqw3Io0XAm320k7Gkh+WMe/1wa/1sZHXs7JXs7MXw7Q307W386dII5hoM4l4U3qIY2uIc1x4gz1Ygx44gv8Ycs/oUp/4Al/38lLY1GNI1GQY5FVI9FaZFEe5NEi5VDnJZCq5hBu5lAyZo/15o95Zs785s5/5o1/5gx/5gwRJ1SS55RV59RZaBRc6FRgqJQkKRQn6VPr6dOvahNy6lM2apK56tI9atG/6xC/6s+/6s+WqtgXqxgZaxgbq1geq5ghq9flLFforJesLRdvrVczLZb2bdZ57hX9blV/7pR/7pM/7pMZrhvablvbrlvdrpvf7tvi7xul71upL5tsr9tvsFszMJr2cNq58Ro9MVm/8di/8de/8hdccV7dMV7eMZ7fsZ7h8d7kch6nMl6qMp6tMx5wM14zc542s9359F19dJ0/9Nx/9Ru/9RtfNKGftKGgtKGh9OGj9SGmNWGotaFrdeFuNiFw9mEz9qD3NyD6d2B9t6A/99+/+B7/+B7h9+RiN+Ri9+RkOCRl+CQn+GQqOKQsuOQvOSPx+aP0ueO3uiO6+mN+OuM/+yK/+2H/+2HkOyckuycleycme2cnu2cpe6bru+btvCbwPGbyvKa1fOa4fSZ7faZ+veX//mW//qU//qTmfqpm/qpnfqooPuopfuorPyos/2ou/2oxP+ozf+o2f+n5f+n8f+m/f+m//+k//+i//+iAAAFAgAECgAEFwAEKQAEPgEEWwMDdQYDiQgDnAsDrA4CvBECyxQC2hcB6RoB+B0A+h0AAQUNBQUNDwYMHAcMLgkMQgsLXxAKeBIKixQJnRYIrRcHvBcGyhcE2BcD5xkC9hwB+BwBBRATChASEhESIBISMhQRRhYRYxoQex0Pjh8PnyANryEMviELzCEJ2iEH6B8F9h0D9x0DDh8aEyAaGSAaJSEZNyMZTCUYaSgXfyoWkSsVoisUsisSwSsRzisP3CoN6ikK+CcH+SYGGDMjGzMjIjQjLTUiPTYiVDghcDsghDwflj0epz0ctjwbxDsZ0jkW3zcT7DQR+jEN/DENFk0tGU0tIE4tME8tQ1AsXlIrd1MqilQpm1MorFMmulIlyVAj1k4g40wd8Uca/UEV/kEVEWc5GWc4Jmg4Nmk4TGs3aG03fm82kHA1oXEzsXEywHEwzm8u3Gwr6Wgo9mEl/1sg/1ogGXpCIHpCLXtCQHxCWX5BcYBAg4JAlIQ/pYU+tYY9xIY70oY64IY37oU1/IMx/34s/34sKYtOMIxNPY1NUo5NZpBNeJJMiJNLmJVLqJZKuJdJxphH1JlG4plE8JlB/pk+/5c6/5c5P5tcR5xcU5xbYJ5bb59bfaBbjKJam6NZqqRYuaZXx6dW1ahV46lS8alQ/6pM/6lI/6lHValqWqpqYKpqaqtqdaxqgq1pj69pnrBorLFoubNnx7Rm1bVk47Zi8bdg/rhd/7hY/7hYY7d2Zrd2a7h2c7h2fLl1iLp1lLt1ob10r750u79zycBy1sJx48Nw8cRu/sVr/8Vo/8Vob8SAcsWAdsWAfMWAhcaAj8d/msh/psl/sst+vsx+y8192M585dB78tF6/9J3/9J0/9N0etGKfNGKgNKKhtKKjdOKltSKoNWJq9aJtteJwtiIztqI2tuH59yG9N2F/96D/9+A/9+Ahd6Uh96Uit+Uj9+UleCUneGUpuKUsOOUu+STxeWT0eaS3eeS6emR9uqQ/+uO/+yM/+yMj+ufkeufk+yfl+yfne2fpO2frO6fte+ev/CeyfGe1POd4PSd7PWc+Peb//ia//mY//qXmPmrmfqrnPqrn/qrpPurqvursvyruv2rw/6rzP+q1/+q4/+q8P+p/P+p//+n//+m//+lAAALAQAKBwAKFAAKJwAKPAAKWgIJcwQJhwcImQoHqg0Gug8GyRIF2BUE5xgD9hsC+BsCAAMVAwQVDAUUGQYUKwcUQAoTXg4SdRERiRMQmxQPqxUOuhYMyBYL1hUI5RcH9BoF9hoFAw4bBw4bDw8bHRAbLxIaRBUaYRgZeBsYix0XnB4WrB8Uux8Tyh8R2B8P5R4M9BsI9RsICx0jDx4jFh4jIR8jNCEiSSMiZiYheyggjikfnykdrikcvSkayykY2SgV5ycS9SUO9iQOFjEtGTEtHzItKjMsOTQsUTYrbTkqgDopkjsoozsmsjolwDkjzjch2zQe6TIa9y8W+C8WFEs4GEw3Hkw3LE03QE42W1A1dFI0hlIzl1IyqFEwtlAvxU4t0kwr30ko7UUk+j8f+z8fCGVCEmVCIWZCMmdCSWlBZWtBem1AjG4/nW8+rW89vG87ym052Go35WYz8l8v/lkq/1gqGHdOHHhOJ3lOPHpNVnxNbX5Mf4BMkIFLoYJKsINJv4RIzoRG24RE6YNB94E+/3w5/3w4H4hcKIlbNopbTItbYY1bco9agpBak5JZo5NZspRXwJVWz5ZU3ZZT65ZQ+ZZM/5RH/5RHOZlpQJlpTJpoWptoaZxod55ohp9nlaBnpaJms6NlwaRkz6Vj3aZh66Zf+qdc/6ZX/6ZXUahzVahzXKhzZqlzcapzfqtzi61ymq5yqK9xtrFxw7Jw0bNv3rRt7LRr+rVp/7Vl/7VlYLZ9Y7Z9aLZ9cLd9ebh9hbl8kbp8nrt8q7x7uL57xr9608B54MF47sJ2/MN0/8Ny/8NxbcOGb8OGc8SGesSGgsWGjcaGmMeGo8iFsMmFvMuEyMyE1c2D4s6C8M+B/dB//9F9/9F8eNCQetCQftGQg9GQi9KQlNOPntSPqdWPtNaPv9eOy9iO2NqN5duM8tyL/t2J/96H/96Hg92ahd2aiN6Zjd6Zk9+Zm+CZpOGZruKZuOOYw+SYzuWY2+aX5+iW9OmV/+qU/+uS/+uSjeqkj+ukkeukluukm+yjouyjqu2js+6jve+jx/Ci0vKi3vOi6vSh9vag//ef//id//mdl/mvmPmvmvmvnvqvo/qvqfuvsPyvufyvwv2vy/+u1f+u4f+u7v+t+/+t//+s//+q//+qAAAUAAATBAATEQATJAATOQATWAEScAMRhAURlgcQpwoPtw0OxhAM1RML5BYJ9BkH9RkHAAIfAQMfBwMfFQQfKAUePQceWwwdcg4chRAblxIapxMZthMXxBMV0hMS4RQQ8RcN8hgNAQsmBAwmCg0mGA4mKxAlQBIlXhYkdBgjhxoimBshqBwgtxwexR0c0xwa4RsW7xkS8RgSBhsuCxsuEhwuHh0uMB4tRiEtYyQsdyUriSYqmiYoqiYnuCYlxiYj1CUh4iQe8CEa8iEZES84FS84HDA3JzE3NTI3TjQ2aTc1fDg0jjkznjkyrTgwuzYuyTQs1jIp5C8m8iwi8ywiEklEFkpEHEpDJ0tDPExDV05Cb1BBgVBAk1A/o089sU08v0w6zUo32kc050Iw9Twr9jwrAmJRBmJRGGNRK2RRQ2ZRYGhQdGpQhmtPl2xOp2xMtmxLxGpJ0mhG32ND7F0++VY4+1U4EnReFnReH3VeNHZeT3ldZntdeHxdiX5cmn9bqYBauIBZxoBX1YBV439T8X1P/nlK/3hJD4VpHYZpL4dpRohpW4ppbIxofI1ojY5nnZBnrJFmupJlyJJk1pNi5JNg8pJd/5BZ/5BZNZZzPZdzSJhzVplzZJpyc5tygp1ykZ5xoJ9xr6FwvaJvyqJu2KNt5qRs9KNp/6Nm/6NmTqZ8UqZ8Wad8Yqd8bah8eqp7iKt7lqx7pK16sq96v7B5zbF42rJ36LJ29rN0/7Nx/7JxXbSFYLSFZbWFbbWFdraEgreEjriEm7qEqLuDtbyDwr2Cz76C3b+B6sB/+MF+/8F7/8F7asKObMKOcMKOd8ONf8SNisWNlcaNoceNrciMucmMxcqL0suL382K7M6J+s6H/8+F/8+Fdc+Xd8+Xe8+WgdCWiNGWkdKWm9OWptOWsdWVvdaVydeV1diU4tmT79uS/NyR/9yP/9yPgNyggtyghd2git2gkd6fmd6fot+fq+CftuGfweOezOSe2OWe5ead8eic/umb/+qZ/+qZi+mpjOqpj+qpk+qpmeupoOupqOypse2pu+6oxe+o0PGo2/Kn6POn9PWm//al//ej//ejlfi0lvi0mPi0nPm0ofm0p/q0rvu0t/y0wP20yf6z0/+z3/+z7P+y+P+y//+x//+v//+vAAAfAAAfAgAeDAAeHwAeNQAeVAAdawEdfwMdkQUcogcbsgoawQ0Z0A8X4BMV7xYS8RYRAAErAAEqAwIqEAIqIwMqOQUqVwkpbQsogA0nkg4moQ8lsBAkvxAizQ8f3BAd6xMa7RQaAAkyAQkyBgoyEwsyJg0xPA8xWhMwbxUwgRcvkxguoxkssRkrwBkpzhgn3Bck6hUg6xUfAxg7BRk7DBk7GRo7Kxs7QR06XiA6ciI5hCM4lSM2pCM1syMzwSIxzyEu3SAr6h4n7B0nCytHDixHFixHIS1HLy9HSTFGYjNFdTRFhzVElzVCpzRBtTI/wjA80C453is16ygw7SgwEEZVFEZVGUdVIUhUNElUUUtTaExTekxSi0xRm0tPqklOuEhMxUVJ00NG4D9C7Tg97zg8A15hBV9hC2BhImFhPWNgWWVgbmdff2hfkWheoGldr2hcvWday2RY2F9V5FlR8VFM81BLC3FrEnJrHHJrLnRqS3ZqYXhqc3pphHtplHxopH1nsn1mwX1lz31k3Hxi6npf+HVc+XVbCYN0FYR0K4V0QoZ0V4hzaIpzeItziIxymI5yp49xto9wxJBv0ZBu35Bt7Y9r+41o/Y1nMpV9OZV8RZZ8U5d8YZh8b5p8fpt8jZx7nJ57q596uaB6xqB51KF44qF28KF1/qBy/6BySqSFTqWFVaWFX6aFaqeEd6iEhKmEkqqEoKyDrq2DvK6Cya+C1rCB5LCA8rB+/7B8/7B8WrONXbONYrONabSNc7WNf7aNi7eMmLiMpbmMsrqLv7uLzLyK2b2K576J9L+H/7+F/7+FZsCVacGVbcGVdMGVfMKVh8OVksSVncWVqcaUtsiUwsmUz8qT3MuS6cyR982Q/82O/82Oc86edc6eeM6efs+ehc+ejtCdmNGdo9KdrtOdutSdxtWc0tec39ib7Nma+tqZ/9uX/9uXftumgNumg9umiNymjt2mlt2mn96mqd+ms+CmvuGlyeOl1eSk4uWk7+aj/Oei/+ig/+mgieiviuivjemvkemvl+qvnuqvpuuvr+yvuO2vwu6uzfCu2fGu5fKt8vOs/vWr//aq//aqk/e6lPe6lvi6mvi6n/m5pfm5rPq5tPu5vvy5x/250f653f+46f+49v+4//+3//+1//+1AAArAAArAAArBgArGgArMAArTwAqZgAqeQEqjAIpnAQorAYnuwkmygsl2g4j6RIg6xIgAAA5AAA5AAA5CQE5HQI5MgM5UQU5Zwc4eQg4igo3mgo1qgs0uAsyxgsv1Qss5Q8p5g8oAARDAAVDAgVDDAZDHwhDNQtCUw5CaBBBehJBixNAmxM+qhQ9uBQ7xhM51BI14xAx5BAwABRNARRNBRVNEhZNIxdMOxlMVhxLah1LfB5KjR5JnB5Hqh5GuB1ExhxC1Bo/4hg64xg6BSdXCChXDyhXGylWKStWRC1WXC9VbzFUgDFUkDFTnzBRrS5QuixOyClL1SZI4yJE5CJEDURiEURiF0ViHkViL0dhTUlhY0pgdUpfhklelkhdpEZcskVav0JYzD9W2TpT5TRP5zNOBFxsBlxsCV1sHF5sOmFsVWNraWRre2VqjGZqnGZpqmZouGRnxWJl0l1i31Zf605b7E1aA291DHB1GXB1K3J1SHR1XXZ0b3d0gHl0kHpzoHtyrntyvHtxyntw13pu5Xds8nNp9HJoBYJ+EYJ+KYN+QIV9U4Z9ZIh9dYl9hYp8lIx8o417so17v456zY5524546Y1294t0+ItzL5OGN5SGQpSGT5WGXZaFbJiFe5mFipqFmZyEp52EtZ6Dwp6D0J+C3p+B659/+p59+559R6OOS6OOUqOOW6SOZqWOc6aNgaeNj6mNnaqNqquMuKyMxa2L066K4K6J7q+I/K6G/q6GVrGWWbGWXrKWZrKVcLOVe7SViLWVlLaVobeVrrmUu7qUyLuT1byT47yS8b2R/r2P/72OY7+dZr+dar+dccCdecGdg8Kdj8OdmsSdpsWcssacv8eczMib2Mmb5sqa9MuZ/8uX/8uXcMylcsyldc2le82lg86li8+lldCloNGlq9Kkt9Okw9Skz9Wj3Naj6dei9tih/9mf/9mfe9qtfdqtgNqthduti9utk9ytnN2tpt6tsd+su+Csx+Gs0+Ks3+Sr7OWq+eap/+eo/+eohue1iOe1iui1jui1lOm1m+m1o+q1rOu1tuy1wO21y+601vC04/G07/Kz/PSy//Wx//WwkPe/kve/lPe/mPe/nPi/o/i/qvm/svq/u/u/xfy/z/2/2v++5v++8/++//+9//+7//+7AAA8AAA9AAA9AQA9EQA9KAA9RwA9XgA8cQA8gwA8kwE7owI6sgQ5wgY40Qk14gwy4wwyAABLAABLAABLAwBLFQBLLAFKSgJKXwNJcQRJgwVIkwZHoQZGrwZEvQZCzAZA3Ak+3Qk9AAJSAAJSAANSBgNSGQVRMAdRTQpRYgxQcw1PhA9PlA9Oog9NsA9Lvg5JzA1H2gpE2wpEABBaABFaAhFZDRNZHhRZNxZZUhlYZRpXdxtXhxtWlhpVpBpUshlSvxhQzRZO2xNL3BNLAiViBSViCyZiFydiJShiQCthWC1hay5gfC5gjC5fmi1dqCtctSlawiVYzyJW3B5T3R5SCkJtDkJtFENtHERtLEVsSkdsX0hrcUhrgkhqkUZpoERnrUJmukBkxzxi0zdg4DBc4S9cBlp3B1t3Clt3Fl13N192UmF2ZmJ2d2N1iGR1l2R0pmRztGJywWBwzltu2lRr5ktn50pnAm1/CG5/Fm9/KnB/RXJ/WnR+a3Z+fHd+jHh9m3l9qnl8uHl7xXl603d54HV37nB073B0BYCHEICHJoKHPoOHUISHYYaHcYeGgYmGkYqGn4uFrouFu4yEyYyD14yC5IuB8oh+9Ih+LZKPNJKPP5OPTJSPWpWPaJaPd5eOhpiOlZqOo5uNsZyNv5yMzJ2M2p2L552J9pyH95uHRKGXSKGXTqKWWKOWY6OWcKSWfqaWjKeWmaiVp6mVtKqVwquUz6yU3a2T6q2R+ayQ+qyQU6+eVrCeW7CeY7GebbGeeLKehbSdkbWdnradq7eduLicxbmc0rqb37ua7buZ/LuY/buYYL2lY76lZ76lbr6ldr+lgMCljMGll8Klo8Okr8SkvMWkyMej1cij4smi8Mmh/sqg/8qfbcusb8usc8useMysgM2sic2sk86snc+sqNCstNKswNOrzNSr2dWq5taq89ep/9en/9enedm0e9m0ftm0gtm0idq0kdu0mty0o920rt6zud+zxOCz0OGz3OKy6eOy9+Wx/+Wv/+avhOa8hea8iOe8jOe8kue8mei8oem8quq8s+u7vey7yO271O674PC67fG6+vK5//S4//S3jvbFj/bFkvbFlfbFmvfFoPjFqPjFsPnFufrFwvvFzf3F2P7E5P/E8P/E/v/D///C///CAABMAABMAABMAABMCwBMIwBMQQBMVwBLagBLfABLjABLnABKqwFKugNJyQRH2QdF2gdFAABXAABWAABXAQBWDwBWKABWRgFWWgJVbAJVfQNUjQNTmwRTqQNStwNQxQNO1QVN1gVNAAFdAAFdAAFdAwJdFANdLQVcSQdcXQlcbwpbfwtajwxanQxZqwtYuApWxglU1AZS1QZRAA5lAA5lAQ9lCRBkGhJkNRRkThdjYRhjchhighhhkRdgnxdfrRZeuhRcxxJa1Q9Y1g9YASNtAyNtCCRtFCVtIyZtPilsVStsZyxreCxqhyxqlippoylnsCZmvSNkyh9i1xtf2BtfCEB4C0F4EUF4GUJ3KkR3R0Z3XEd2bUd1fkZ0jUVzm0JyqUBxtj1vwjptzzVr2y5n3C1nBlmBB1mBClqBE1uBNV2AT1+AYmCAc2F/hGJ/k2J+omJ9sGF8vV57yVl51lJ24kly40hxAGyJBGyJFG2JKW+JQ3GIV3KIaHSIeXWIiXaHmHeHpneGtHeFwneEz3WD3HOB6m5/625+CX+REn+RJYCRO4GQTYOQXoSQboWQfoeQjYiPnImPqoqOuIqOxYqN04qM4ImK7oaI8IaILJCYMpCYPZGYSZKYV5OYZZSXdJWXg5eXkpiXoJmWrZqWu5uVyJuV1puU5JuT8pqR85mRQaCfRaCfTKCfVaGfYKKfbaOfe6SeiaWelqaepKiesamdvqmdzKqc2aub56ua9aqZ96qZUK6mU66mWK+mYK+marCmdbGmgrKlj7Olm7SlqLWltbakwrekz7ij3Lmj6rmi+Lmg+rmgXrytYLytZL2ta72tdL6tfr+sicCslMGsoMKsrMOsucSrxcWr0sar38eq7cip+8io/cioasq0bMq0cMq0dsu0fcu0hsy0kM2zms6zps+zsdCzvdGzydKy1tOy49Sx8NWx/tav/9avdte7eNi7e9i7gNi7h9m7jtq7l9q7odu7q9y6tt26wd+6zeC62eG55uK59OO4/+S3/+S3guXCg+XChuXCiubCj+bClufCnujCp+nCserCu+vCxuzC0e3B3e7B6vDB9/HA//K///K/jPXMjfXMj/XMk/bMmPbLnvfLpfjLrvjLt/nLwPvLy/zL1f3L4f7L7v/K/P/K///I///IAABXAABXAABXAABXBgBXHwBXPQBXUgBXZQBXdwBWhwBWlgBWpQBWtAFVwwJU0gNT1ARTAABhAABhAABiAABiCwBhJQBhQgBhVgFhaAFgeQJgiAJflgJepAJdsgFcwAFazwJZ0AJZAABoAABoAAFoAgFoEQJnKwNnRgVnWQZmaghmewlligllmAlkpghjswdhwQZgzgRdzwNdAAxvAAxvAA1vBw5vFw9vMxJuSxRuXRVtbhVsfhVsjRVrmhRqqBNptRFnww9m0Axj0QxjACF3ASF3BiJ3ESN3ICR3PCd2Uil2Yyp1dCp1gyl0kihznyZyrCNwuSBuxRxs0hhq0xdpBz+CCj+BD0CBGEGBKUOBRUSAWUWAakV/e0V+ikN9mEF8pT57sjt5vjh3yzN11yty2CpyBleKCFeKCliKElqKNFyKTV2JX1+JcGCJgWCIkGGInmCHrF+GuVyFxliD0lCA3Ud830Z8AGqSAWuSEWySKG2SQW+RVHGRZXKRdXORhXSQlHWQo3WPsHWPvnWOy3SN2XGL5m2J52yIDX2ZE36ZJH+ZOYCZS4GZW4OZa4SYe4WYioaYmYeYp4iXtIiXwoiWz4iV3YeU64WS7ISSK4+gMY+gOpCgRpGgVJKgYpOgcZSggJWfj5afnZefqpieuJmexZmd05qd4Jmb7pia8JiaP56nQ56nSZ+nUqCnXqCnaqGneKOmhqSmk6Wmoaamrqelu6ilyamk1qmk46mj8qmh86mhTq2tUa2tVq2tXa6tZ6+tc6+tf7GtjLKtmLOtpbStsrWsv7aszLer2ber57iq9bip9ripW7u0Xbu0Yru0aLy0cby0e720hr60kr+0nsC0qsGztsOzwsSzz8Wy3MWy6sax+Maw+sawaMi7asi7bsm7c8m7e8q7g8u7jcy7mM27o866rs+6utC6xtG609K54NO57dS4/NS3/dS3dNbCdtbCedfCftfChNjCjNjCldnCntrCqdvBs9zBv93By97B1+DB4+HA8eK//+O+/+O+f+TJgeTJg+TJiOXJjeXJlObJnOfJpefJrujJuOrJw+vIz+zI2+3I5+7I9fDH//HG//HGivTRi/TRjfXRkfXRlvXRnPbRo/fRq/jRtPnRvvrRyPvR0/zR3/7R6//Q+f/Q///P///PAABiAABiAABiAABiBABiHABiOgBiTgBiYQBicgBhggBhkQBhoABhrwBgvQFgzQJfzgJfAABsAABsAABsAABsCABsIwBrPwBrUgBrZABqdAFqhAFpkgFpnwForQBmuwBlygFkywFkAAByAAByAAByAQByDgFxKQJxQwRxVQVwZwZwdwZvhgZvlAZuoQZtrwVsvARqyQJoywJoAAp5AAp5AAt5BQx5FQ14MRB4SBJ3WhN3axN2exN1iRJ1lhF0pBBzsQ9xvgxwywluzQltAB+BAR+BBSCBDyGAHyOAOyaATyd/YCh/cSh+gCd9jiZ8myR7qCF6tR54wRl2zhV0zxRzBT6LCD6LDj+LF0CKKUKKQ0OKVkSJZ0SIeEOIh0KHlD+FoT2ErjqDuzaBxzB/0yl81Ch7B1WTCFaTC1eTEliTNFqTS1ySXV2Sbl6Sfl+RjV+Rm1+QqF2PtluOwlaMzk+J2kWG20SFAGmaAGmaEGqaKGyaP26aUW+aYnGac3KZg3OZkXOZn3SYrXSXu3OXyHKW1XCU4muS5GqSEXyhFX2hJH6hOH+hSYChWIGhaIKheIShh4Wgloago4agsYefvoeezIae2oWc54Ob6IObKo2oMI6oOY6oRI+oUpCoYJGob5KofZSnjJWnmpanp5entZemwpim0Jil3Zek65aj7JaiPZ2vQZ2vR52vUJ6vW5+uaKCudqGug6KukaOunqSuq6WtuKatxaet06es4Ker7qeq8KeqS6u1Tqy1U6y1W6y1Za21cK61fK+1ibC1lrG0orK0r7O0vLS0ybWz1raz5Lay8rax87axWbm8W7q8X7q8Zrq7b7u7eby7hL27j767m7+7p8C7s8G7wMK6zcO62cS658W59cW498W4ZcfCZ8fCa8fCccjCeMnCgcnCi8rClcvCoMzCrM3Bt87BxNDB0NHB3dHA6tLA+dO/+tO/ctXJc9XJdtXJe9bJgtbJidfJktjJnNnIptrIsdvIvNzIyN3I1N7I4d/H7uDH/OHG/uHGfePPfuPPgePPheTPi+TPkeXPmeXPoubPrOfPtujPwenPzOvP2OzO5O3O8u7N//DN//DMiPPYifTYi/TYj/TYk/XYmvXYofbYqffYsvjYu/nYxvrY0fvX3P3X6P7X9v/X///W///WAABsAABsAABsAABsAgBsGwBsNgBsSgBrXQBrbgBrfgBrjQBrmwBrqgBruQBqyABpyQBpAAB1AAB1AAB1AAB1BgB1IgB1PAB1TwB0YAB0cQBzgABzjgBymwBxqQBwtgBvxQBuxwBuAAB7AAB7AAB7AQB7DAB7KAF6QAN6UgN6YwR5cwR5ggV4kAR3nQR2qwN1uAJ0xQFyxgFyAAiCAAmCAAmCBAqCFAyBMQ+BRhCBVxGAaBF/dxF/hhB+kw99oA58rQx7ugp5xwZ3yQZ3AB6KAB6KAx+JDSCJHyKJOSSJTSaIXiaIbiaHfSaGiySFmCKEpR+DsRuBvRd/yhJ9yxJ9BT2TBz2TDT6TFj+TKUGTQkKSVEOSZUORdUKQhEGPkT6OnjuNqziMtzSKxC+IzyeF0CaEB1ScCFWcDFWbFFebM1mbSVubWlyba12ae12ail6ZmF2ZpVyYslqWv1WVy06S1kOP2EOOAGijAGijEGmjKGuiPW2iT26iYG+icHCigHGhj3KhnXKhqnKgt3KfxXCe0m6d32mb4GmaE3upF3ypJXypN32pR3+pVoCpZoGpdoKphYOpk4SooYWoroWnu4WnyYWm1oSl5IGj5YGjKoywL4ywN42wQ46wUI+wXpCwbJGwe5KviZOvl5SvpJWvspauv5auzJat2pas6JSr6ZSrO5u2P5y2RZy2Tp22WZ62Zp+2c6C2gaG2jqK2m6O2qKS1taW1wqW10Ka03aaz66Wy7aWySaq9TKq9Uau9Wau9Y6y9bq29eq68h6+8k7C8oLG8rLK8ubO8xrS707S74LW677W58LS5V7jDWbjDXbnDZLnDbLrDdrvDgbvDjbzDmL3DpL/CsMDCvcHCysLC1sLB5MPB8sPA9MPAY8bJZcbJacbJb8fJdsfJf8jJiMnJk8rJnsvJqczJtc3Jwc7Jzc/I2tDI59HH9tHG99HGb9TPcdTPdNTPedTPf9XPh9bPkNfPmdfPo9jPrtnPudrPxdzP0d3P3t7O69/O+uDN++DNe+LWfOLWf+LWg+LWiOPWj+PWl+TWoOXWqebWs+fWvujWyunW1evW4uzV7+3V/u7U/+7UhvPeh/PfifPfjfPfkfTfl/Tfn/Xfp/bfsPffufjfw/nfzvve2vze5v3e8//e///d///dAAB2AAB2AAB2AAB2AQB2GgB1NAB1RwB1WQB1agB1egB1iQB0lwB0pgB0tAB0wwBzxQBzAAB+AAB+AAB+AAB+BQB+IQB+OQB+TAB9XQB9bQB8fAB8igB7lwB6pQB5sgB4wQB3wgB3AACEAACEAACEAACECwCDKAGDPgKDTwKCYQOCcAOCfwOBjAOAmgN/pwJ+tAF9wQB7wgB7AAeLAAeLAAiKAgmKEwuKMA2KRA+JVQ+JZQ+IdA+Hgg6Hjw2GnAuFqQmDtgeCwwWAxQSAAB2SAB2SAx6SDB+SHyGSOCORSySRWyWQayWQeiSPiCOOlSGNoR6MrhmKuhWIxhCGyBCGBDycBzycDD2cFj6cKkCbQEKbUkKaY0Kac0GZgUCYjj2XmzqWqDeUtDKTwC2QzCWOzSSNBlOkCFOkDFSkFlajM1ijR1qjWFujaVyjeVyih1yilVyholugr1ifvFSdyE2b00KX1EGXAGerAmirEmmrKWqqPGuqTm2qXm6qbm+qfXCqjHGpmnGpp3GotHCowm+nz2yl3Gij3WejFXqxGXuxJXuxNXyxRX2xVH6xZICxc4GxgoKxkIOwnoOwq4SwuISvxoOu04Kt4H+s4n+sKYu4LYu4Noy4QYy4To24XI64apC4eZG3h5K3lJO3opS3r5S2vJW2yZW115S15JOz5pOzOZq+PZq+Q5u+TJu+V5y+ZJ2+cZ6+fp++jKC+mKG+paK9sqO9v6S9zaS82qS76KO66aO6SKnESqnET6nEV6rEYarEbKvEeKzEhK3Eka7Ena/EqbDEtrHDw7LD0LPD3bPC67PB7bPBVbfKV7fKW7fKYrjKarjKdLnKf7rKirvKlrzKor3Krr7Kur/Kx8DJ1MHJ4cHJ78HI8MHIYcTQY8XQZ8XQbcXQdMbQfcfQhsjQkMjQm8nQpsvQsszQvs3Qy87P187P5M/P89DO9NDObdLXb9PXctPXd9PXfdTXhdTXjdXXl9bXodfXrNjWt9nWwtrWz9vW29zW6N3V997V+N7VeeDdeuHdfeHdgeHdhuLdjeLdlePdneTdp+Xdsebdu+fdx+jd0+nd3+rd7Ozc++3c/e3chPLlhfLlh/Lli/PlkPPllvTlnPTlpfXlrvbmtvfmwfjmzPrm1/vl4/3l8P7l///k///kAAB/AAB/AAB/AAB+AQB+GQB+MQB+RAB+VgB9ZwB9dgB9hQB9kwB9ogB9sAB9vwB8wQB8AACHAACHAACHAACHBACHIQCGNwCGSQCGWgCGagCFeQCFhwCElACDoQCCrgCBvQCAvgCAAACMAACMAACMAACMCgCMJwCMPAGLTQGLXgKLbQKKfAKKiQKJlgGIowGHsACGvQCEvgCEAAaTAAaTAAeTAgiTFAqSLwySQg2SUw6RYw6RcQ2QfwyPjAuOmQmNpgeMswWLvwOJwQOJABubAByaAhyaDB6aICCaOCKaSSOZWSOZaSOYeCKXhSGXkh+WnhyUqhiTthORww2PxA2OBDukBjykDDykFz6kK0CkP0GjUEGjYUGicEChfz+hjDygmDmepTWdsTGbvSuZyCOWySKWB1KsCFKsDFSsGFWsM1erRlirVlmrZ1qrdluqhVuqk1qpoFmprFeouVOmxUyj0ECg0UCgAGazBGezFmizKmmzPGqyTGuyXG2ybG6ye26yim+xl2+xpG+xsW+wv22vzGuu2Was2masF3m5Gnq5Jnq5NXu5RHy5U325Yn65cX+5gIC5joG5m4K4qIK4tYK3w4K30IC23X603320KIrALYrANYrAQIvATIzAWo3AaI7Ad4+/hJC/kpG/n5K/rJO/uZO+xpO+1JK94ZG845G8OJnGPJnGQprGSprGVpvGYpzGb53GfJ7GiZ/GlqDFo6HFsKLFvaLFyqPE16PE5aLD5qLDRqfMSajMTqjMVajMX6nMaqrMdqvMgqzMjq3Mmq7Mp6/Ms7DLwLHLzbHL2rHK6LHJ6rHJU7XSVbbSWrbSYLbSabfScrjSfbnRiLrRk7vRn7zRq73Rt77RxL7R0b/R3sDQ7MDP7cDPYMPYYsPYZcTYa8TYcsXYe8XYhMbYjsfYmcjYpMnYr8rYu8vXyMzX1M3X4c7X8M7W8c7WbNHebdHecNHeddLee9Leg9Pei9TeldXen9beqdfetNjewNnezNre2Nve5dzd9Nzd9dzdd9/leN/le+Dlf+DlhODli+Hlk+Llm+PlpeTlruTlueblxOfl0Ojl3Onk6erk+evj++vjgvHsg/HshvHsifLsjvLtlPPtm/Tto/Ttq/XttPftv/jtyfnt1frt4Pzt7v3t/v/s///sAACHAACHAACHAACHAQCHGQCHLwCHQQCGUwCGZACGcwCGggCGkACGngCGrACGuwCFvQCFAACPAACPAACPAACPBACPIACPNQCPRwCOWACOZwCOdgCNgwCNkACMnQCLqgCKuQCJuwCJAACVAACVAACVAACVCwCUJwCUOgGUSwGTWwGTagGTeAGShgGRkwGRoACQrQCOuQCNuwCNAAWbAAWbAAabAgebFgmbLwuaQAyaUAyaYAyZbwuYfAqYiQmXlgeWogWVrwSTvAKSvQGRABqjABujAhyjDB2jIR+iNyGiSCGiVyKhZyKhdSGggiCfjx2emxqdpxabsxCZvwuXwAuXBDqtBjusDDysGT2sLD+sP0CsT0CrX0Crbj+qfD6piTuoljinojSlri+kuimixSGfxiCfB1G0CVK0DlO0HFS0M1a0RVezVVizZVmzdFmzglmykFmynVixqlawtlKvwkqszT+pzj6oAGW7CGa7Gme7K2i7O2m7S2q7Wmu6amy6eW26h266lW65oW65rm24u2y4yWq21WW11mS0GnjBHXjBJ3nBNXrBQ3vBUXzBYH3Bb37BfX/Bi4DBmYDApYHAsoHAwIC/zX++2ny923y9KYjILonINYnIP4rIS4vIWYzIZo3IdY7Igo/Hj5DHnJDHqZHHtpHHw5HG0ZHF3o/E34/EOJjOO5jOQZjOSpnOVJrOYJrObZvOep3Oh57OlJ7NoJ/NraDNuqHNx6HN1KHM4qDL46DLRabTSKbTTafTVKfTXqjTaKnTdKrTgKrTjKvTmKzTpK3Tsa7Tva/TyrDS17DS5a/R5q/RUrTZVLTZWbXZX7XZZ7bZcbbZe7fZhrjZkbnZnbrZqLvZtbzZwb3Zzr7Z277Y6b7Y6r7YX8LfYcLfZMLfacPfccPfecTfgsXgjMbgl8fgosjgrcngucrfxcvf0cvf3szf7Mze7szea9DmbNDmb9DmdNHmetHmgdLmitLmk9PmnNTmp9Xmstbmvdfmydjm1dnm4trl8dvl8tvldt7sd97set7sft/sg9/sieDskeDsmeHso+LsrOPtt+TtwuXtzebt2eft5uns9urs+OrsgfD0gvD0hPH0iPH0jPH0kvL0mfP1ofT1qfX1svb1vPf1x/j10vn13fv26v32/f/1///1AACMAACMAACMAACMAQCMGQCLLgCLQACLUQCLYgCLcQCLgACLjgCLnACLqgCKuQCKuwCKAACUAACUAACUAACUBQCUIACTNACTRgCTVgCTZgCSdACSggCRjwCRmwCQqACPtwCOuACOAACZAACZAACZAACZDQCZJwCZOQCYSgGYWgGYaQGXdwGXhACWkQCVngCVqwCTtwCSuACRAASgAAWgAAWgAgagFwifLgqfQAufTwueXwuebQqdewmciAiblAaboAWarQOYugGXuwGWABqnABqnAhunDR2nIh+nNyCnRyGmViGmZiGldCCkgR+kjRyjmRmipRWgsQ+evQmcvgmcBDqxBjqxDTuxGz2xLD+wPkCwT0CwXkCvbT+vez2uiDutlDesoDOqrC6puCinwyCkxB+kB1G5ClG5D1K4HlS4M1W4RFa4VFe4ZFi4c1m3gVm3j1i2nFe2qFW1tFGzwEqxyz6uzD2tAmW/Cma/G2a/LGe/O2i/S2m/Wmq/aWu/eGy/hm2+k22+oG2+rWy9umu8x2m71GS51WO5G3jGH3jGKHjGNXnGQ3rGUXvGYHzGbn3GfH7Gin/Fl3/FpIDFsYDEvn/Ey37D2HvC2nvCKYjLLYjLNYnLP4nLS4rLWIvLZozLdI3LgY7Ljo/Lm5DLqJDLtZDKwpDKz5DJ3I7I3Y7IOJfSO5fSQZfSSZjSVJnSYJrSbJvSeZzShp3Skp7Rn57Rq5/RuKDRxaDR0qDQ4J/P4Z/PRaXYSKbYTabYVKbYXafYaKjYc6nYf6rYi6vYl6zYo63Yr63XvK7Xya/X1q/X467W5a7WUrTeVLTeWLTeX7TeZ7XecLbeerfehbjekLnenLnep7res7vewLzezL3d2b3d573d6L3dXsHkYMHkZMLkacLkcMPkeMPkgcTki8XklsbkocfkrMjkt8nkw8rk0Mrk3cvk68vj7Mvjas/qbM/qb8/qc9DqedDqgNHqidLqktPqnNPrptTrsNXrvNbrx9fr09jr4Nnr79rq8Nrqdd3xd93xed7xfd7xgt7xid/xkODxmeDxouHxq+LytePywOTyzOXy1+by5Ofy9Ojy9ujygPD6gvD6hPD6h/D6i/H6kfH6mPL6oPP6qPT7sfX7uvb7xff80Pn82/r96Pz9/P7+//7+AACMAACMAACMAACMAQCMGQCLLgCLQACLUQCLYgCLcQCLgACLjgCLnACLqgCKuQCKuwCKAACUAACUAACUAACUBQCUIACTNACTRgCTVgCTZgCSdACSggCRjwCRmwCQqACPtwCOuACOAACZAACZAACZAACZDQCZJwCZOQCYSgGYWgGYaQGXdwGXhACWkQCVngCVqwCTtwCSuACRAASgAAWgAAWgAgagFwifLgqfQAufTwueXwuebQqdewmciAiblAaboAWarQOYugGXuwGWABqnABqnAhunDR2nIh+nNyCnRyGmViGmZiGldCCkgR+kjRyjmRmipRWgsQ+evQmcvgmcBDqxBjqxDTuxGz2xLD+wPkCwT0CwXkCvbT+vez2uiDutlDesoDOqrC6puCinwyCkxB+kB1G5ClG5D1K4HlS4M1W4RFa4VFe4ZFi4c1m3gVm3j1i2nFe2qFW1tFGzwEqxyz6uzD2tAmW/Cma/G2a/LGe/O2i/S2m/Wmq/aWu/eGy/hm2+k22+oG2+rWy9umu8x2m71GS51WO5G3jGH3jGKHjGNXnGQ3rGUXvGYHzGbn3GfH7Gin/Fl3/FpIDFsYDEvn/Ey37D2HvC2nvCKYjLLYjLNYnLP4nLS4rLWIvLZozLdI3LgY7Ljo/Lm5DLqJDLtZDKwpDKz5DJ3I7I3Y7IOJfSO5fSQZfSSZjSVJnSYJrSbJvSeZzShp3Skp7Rn57Rq5/RuKDRxaDR0qDQ4J/P4Z/PRaXYSKbYTabYVKbYXafYaKjYc6nYf6rYi6vYl6zYo63Yr63XvK7Xya/X1q/X467W5a7WUrTeVLTeWLTeX7TeZ7XecLbeerfehbjekLnenLnep7res7vewLzezL3d2b3d573d6L3dXsHkYMHkZMLkacLkcMPkeMPkgcTki8XklsbkocfkrMjkt8nkw8rk0Mrk3cvk68vj7Mvjas/qbM/qb8/qc9DqedDqgNHqidLqktPqnNPrptTrsNXrvNbrx9fr09jr4Nnr79rq8Nrqdd3xd93xed7xfd7xgt7xid/xkODxmeDxouHxq+LytePywOTyzOXy1+by5Ofy9Ojy9ujygPD6gvD6hPD6h/D6i/H6kfH6mPL6oPP6qPT7sfX7uvb7xff80Pn82/r96Pz9/P7+//7+\",slide100:\"AAAAAwAACQAAEgAAHwAAMQAARAAAWAAAbwAAhwAAnAAAsAAAxAAA2AAA7AAA/wAA/wAAAgQABgQADwQAGgMAKQMAOwMATQMAYQIAdwIAjQEAogEAtQAAyQAA3AAA7wAA/wAA/wAABg4DCg4CEw0CIA0BMAwAQQsAUgoAZgkAewgAkQYApAUAtwMAygIA3QAA8QAA/wAA/wAADR4LER0KGB0IJRwGNRsERRoCVxgBahYAfxQAkxIApw4AuQsAzAgA3gUA8gIA/wAA/wAAFzAUGzAUIi8SLC4QOi4NSi0KWysHbyoEgicCliQBqSAAuxsAzhYA4BAA8woA/wQA/wMAG0EcH0EbJ0EaMUAYQD8WUD8UYT0RdDwNhzoKmjgHqzQGvTEF0CwF4iYE9R4D/xMD/xECHVUkIlUjLFUiN1QhRlQfVlMdZ1IaeVEXi08UnU0SrkoQwEYQ0kIQ5D0P9jYP/y0P/ysPK2kpMGgpN2goQmgnUGgmXmckbmYifmUfkGQdoGIbsmAZw14Z1Foa5lYb+FAb/0cc/0UdPHwuQHwtRnwsUHwrW3wqaHsodnsnhnollnkjpnghtnYgx3Qf2HEg6W0i+mkl/2Io/2EpTY80UI80VY8zXY8yZ48wco4tf44qjo4onI0mrIwlvIojzIki3Ycj7YQl/oAp/3ou/3kvXaI7X6I7Y6E6aaE5cqE3fKE1iKEylqAvpKArs58nwp4m0p0l4psk8pkl/5Ur/5Ez/480bLRCbbRCcbRBdrRAfbM/h7M9krM6nrM3rLI0urIwybEr2LAn6K8m+K0m/6sp/6Y0/6U2e8VJfMVJf8VIhMVHi8VGk8VEncVCqMU/tcU8wsQ5z8Q13sMw7sIq/cEn/78o/7sv/7syjNZPjdZPkNZOlNZOmtZModZLqtZJtNZHv9VEytVB19U+5dQ589Q1/9Mv/9Ip/9Ar/88sn+dVoOdVoudUpudTqudSsedRuOdPwedOyudL1edJ4OdG7OZC+eY+/+U6/+Q1/+Mu/+MstPhatfhat/hZufhZvfhYwvhXyfhV0PhU2PhS4fhQ6vhN9fhK//hH//dD//c///Y5//Y41P9f1P9f1v9e2P9e2/9d3v9d4/9c6f9a7/9Z9f9X/f9W//9T//9R//9O//9L//9G//9FAAABAQABBgABDgABGwAALAAAPwAAUwAAawAAggAAlwAArAAAwAAA1AAA6QAA/gAA/wAAAQQEBAMEDAMDFwMCJgMBOAIASQIAXQIAcwEAiQEAnQAAsQAAxQAA2AAA7AAA/wAA/wAABA4ICA0IEA0HHQwFLQsDPgoCTwoBYwgAeAcAjQUAoQQAtAIAxwIA2gAA7gAA/wAA/wAACx4RDx0QFh0OIxwMMxsJQxkGVRgEaBYCfRMBkREBpA0AtwoAyQcA3AQA8AIA/wAA/wAAFjAZGi8YIS8XKy4VOC4SSCwQWisNbSkJgScHlCMFpx8EuRsDzBUC3g8B8gkB/wQB/wMBGkEgHkEfJUEeMEAdPj8aTj8YYD0VcjwShToQmDcOqTQNuzANzisL4CYK8x4I/xMG/xEGGlUnIFUnKlUmNlQkRVQjVVMgZlIeeFEbik8Zm00XrUoXvkYX0EIW4jwV9TYV/y0U/ysUKmksLmgsNWgrQWgqT2goXWcnbWclfmUij2Qhn2IfsGAfwV0f01og5FUg908h/0ch/0UhO3wwP3wvRnwvT3wtWnwsZ3sqdXsphXonlXklpXgktXYjxnQj13El520n+Wgp/2Is/2EsTY81UI80VY8zXY8yZ48wco8uf44sjY4rnI0pq4wnu4omy4km3IYn7IMq/H8u/3oz/3k0XaI8X6I7Y6I6aaI5cqE4fKE1iKEylqEvpKAss58qwp4p0Z0n4Zsn8Zgq/5Ux/5A3/485bLRDbbRCcbRBdrRAfbQ/h7M9krM6nrM3rLM0urIwybEr2LAq568p960q/6ov/6Y5/6U7e8VJfcVJf8VIhMVHi8VGk8VEncVCqMU/tcU8wsQ50MQ13sMw7sIr/cEq/78s/7s1/7o4jNZPjdZPkNZPlNZOmtZModZLqtZJtNZHv9VEy9VB19U+5dU689Q1/9Mw/9Iq/9Av/88wn+dVoOdVoudUpudTq+dSsedRuOdQwedOyudM1edJ4OdG7OZC+eY+/+U6/+U1/+Mu/+MstPhatfhat/hZuvhZvvhYw/hXyfhV0PhU2PhS4fhQ6vhN9fhL//hH//dD//c///Y6//Y41P9f1f9f1v9f2P9e2/9d3/9d4/9c6f9a7/9Z9v9X/f9W//9T//9R//9O//9L//9H//9GAAAGAAAGBAAGCwAGFwAGKQAFPAAEUAADaAACfwABlQABqgABvgAB0gAB5wAC/QAC/wACAAQKAgMKCQMJFAMJIwIHNAIGRgIFWgEDcAEChgABmwABrwAAwwAA1gAA6wAA/wAB/wABAw4PBg0ODQwNGgwMKgsKOwoITAkHYAcFdQYEigUCngMBsgIBxQEB2AAB7QAA/wAA/wABCR4XDh0WFBwVIBsTMRoQQRkOUhgMZRUKehMHjhAFog0EtAkDxwcC2gMC7gEC/wAC/wABFDAfGC8eHy8dKS4bNi0ZRiwXVysVaikTfiYRkSMOpB8MtxoJyhUH3Q8G8AkF/wQE/wMEGUElHUEkI0EjLUAiPD8gTD4eXj0ccDsagzkZlTcXpzMWuTAUzCsT3yUR8h0P/xMM/xALF1UrHVUrJ1QqNFQpQ1MnU1MlZFIjdlAhh04gmUwgqkkfvEYez0Ed4Twc8zUc/ywa/yoZKGkwLWgvM2gvP2gtTWgsXGcqbGYpfGUnjWQmnWImrmAmv10m0Vkm41Um9U8n/0cn/0UnOXw0PXwzRHwzTXwyWXwwZnsvdHsthHorlHkqo3cps3YqxHMr1XAs5m0t92gw/2Iy/2EyTY83UI82VY82XI81ZY80cY8zfo4xjI4vmo0uqowsuooryogt2YYw6oMy+382/3o6/3g7XaI8X6I7Y6I7aaI5cqI4fKI2iKE0laEzo6AxsZ8wwZ4u0J0u35sw75g1/pU6/5BA/49BbLRDbbRCcbRCdrRBfbQ/h7Q9krQ7n7M4rLM0urIyyLEw17Aw5q8v9a0y/6o6/6VC/6REe8ZJfcZJf8ZIhMZHi8ZGk8ZEnsVCqcVAtcU8wsU50MQ13sQw7cIv/MEw/740/7pA/7pCjNZPjdZPkNZPlNZOmtZNodZLqtZJtNZHv9ZEy9ZB19U+5dU689Q1/9Qw/9Iw/881/884n+dVoOdVoudUpudUq+dTsedRuOdQwedOyudM1edJ4OdG7OdD+eY//+Y6/+U1/+Mv/+MwtPhatfhat/hZuvhZvvhYw/hXyfhV0PhU2PhS4fhQ6/hN9fhL//hH//hE//c///Y6//Y41P9f1f9f1v9f2P9e2/9e3/9d5P9c6f9a7/9Z9v9Y/v9W//9T//9R//9O//9L//9H//9GAAAQAAARAQARBwARFAAQJgAPOQANTQALZQAJfQAHkwAGpwAGvAAF0QAF5gAF/AAG/wAGAAMVAQMVBQIVEAIUHwITMQEQQwEOVwEMbgEJhAAHmQAFrQAEwQAD1QAD6QAD/gAE/wAEAg0ZBAwZCgsYFgsXJwoVOAkTSQgRXQcOcwYMiAQJnAMIrwIGwwEG1wAF6wAD/wAD/wADBh0gCh0fERweHRsdLRkbPRgZTxcXYhUUdxIRjA8OnwwMsggLxQYJ2QMI7QEG/wAF/wAFEi8nFS8nHC4mJi4kMiwjQisiVCogZygdeyUbjyIYoh4VtBkTyBQR2w4O7wgM/wMK/wIJF0EtGkEsIEArKkArOD8qST4oWjwnbTslgDkjkjYhpDMgty8eyioc3CUa8B0X/xIS/xASFFUyGFUyI1QxMFQwQFMvUFIuYVEtclAshE4rlkwpqEkoukUnzEEm3jsl8jUj/ywh/yogJGg3KWg3MGg2PGg1Smc0WWczaGYyeWUyiWMxmmExq18wvVwwzlkw4FUw808v/0cu/0UtNnw6Onw6QXw5S3w5Vnw3Y3s2cXo1gXk1kHg1oHc2sHU2wXM20nA342w49Wg6/2E6/2E6So89TY89Uo88Wo87Y486b445e444io03mIw3p4s3t4k4xog614U854I++H5B/3lD/3hEXKI/XqI/YqI+aKI+cKI9eqI8hqE7k6E5oaA4sJ83vp44zZw63Jo97JdB/JRF/49K/45LbLVDbbVDcbRCdrRBfbQ/h7Q9krQ8nrM7q7M6uLI5x7E41bA45K468qxA/6lG/6VN/6RPe8ZKfcZJgMZJhMZIi8ZGlMZEnsZCqcZAtcU9wsU50MQ33cM368I3+sA5/75C/7pM/7lOjNdQjddPkNdPlNdOmtdNoddLqtZJtNZHv9ZEy9ZB2NY+5dU689U1/9Q2/9I5/89D/85Hn+hVoOhVouhUpuhUq+hTsehRuehQwehOy+hM1edJ4OdG7OdD+uc//+Y6/+U1/+M3/+M5tflatvlat/lZuvlZvvlYw/lXyflW0PlU2PlS4flQ6/lO9vlL//hH//hE//g///c6//Y41f9f1v9f1/9f2f9e3P9e4P9d5P9c6v9b8P9Z9v9Y/v9W//9U//9R//9O//9L//9H//9GAAAbAAAbAAAbBAAbEAAaIgAZNgAXSwAVYwASegAQkQAOpgANuwAM0AAL5QAL+wAL/wALAAMgAAIgAwIfDAIfGwEdLgEbQAEZVAEWawATgQAQlgAOqwAMvwAK0wAI6AAI/QAI/wAJAAwkAgskBgsjEgoiIwkgNAgeRgccWgYZcAUWhQMUmQISrQEQwQEO1QAL6gAJ/wAH/wAIBBwsBxwrDhsqGRooKRkmOhckSxYiXxQfdBEciQ4ZnAsXsAgUwwUS1wIQ7AEN/wAL/wALDi4zEi4yGS0xIy0wLiwuPyssUCkqZCcoeCUljCIinx0gshkdxRMa2Q0X7QgT/wMQ/wIQFEA5F0A4HD84Jj83Mz41RT00VjwyaTowfDgujzUsojIqtC4oxyol2iQi7xwe/xIZ/w8YEVQ/E1Q/G1M+KlM+OlI9S1E7XFA5bk84gU02k0s1pEgzt0QyyUAw3Dsu8DQr/ywo/yknHGhEImhEK2dDNmdDRGdCVGZBZGVAdWQ/hmI+l2E9qF48uVw8zFg73lQ68U44/0Y2/0Q1MHxFNHxFPHxFRntFUntEX3pEbXpEfHlDjHdDnHZDrXRDvXJDz29D4GxE82dD/2FD/2BDRo9GSY9FTo9FVo9FYI5Ea45EeI1Eho1FlItFo4pGs4lHw4dH04RJ5IFK9X5M/3lN/3dNWaJHW6JGX6JGZaJGbaJFeKFEg6FEkKBEnp9ErJ5Gup1IyZtJ2ZlM6JZO+ZNS/49V/45VarVHbLVHb7VHdLRGfLRGhbRFkLREnLNDqLNDtrJDw7FE0a9H361L7qtP/ahU/6Ra/6Nbe8dKfcdJf8dJhMdIi8ZHlMZFncZDqMZDtMVCwMVBzcRB28NC6MFF9b9L/7xS/7lb/7hdjNdQjddQkNdPlNdOmtdNotdLqtdJtNdHv9dFy9ZC2NY+5dU+8tQ//tNB/9FJ/81W/81Zn+hVoOhVo+hVpuhUq+hTsehSuehQwehOy+hM1ehJ4ehG7edD+uc//+Y6/+U8/+NF/+JJtflatvlauPlauvlZvvlYw/lXyflW0flU2flS4vlQ6/lO9vlL//lI//hE//g///c6//c41v9f1/9f2P9f2v9e3f9e4P9d5f9c6v9b8f9Z9/9Y//9W//9U//9R//9P//9L//9H//9GAAAlAAAlAAAlAgAlDAAkHwAiMwAgSAAeYQAbeAAZjwAWpAAUuQATzgAS5AAR+gAR/wARAAIqAAIqAQIqCAEpFwEoKwElPQEjUQAgaAAdfwAalAAXqAAUvQAR0gAP5wAP/AAP/wAPAAsvAQsvBAouDgktHwgrMQcpQgYnVwUkbQQhggMelwIbqwEZvwAW0wAT6QAQ/gAO/wAOAhw3BBs3Cho2FRk0JRgyNhYwSBUtXBMqcRAnhg0kmgohrQcewQUb1QIY6gEV/wAS/wARCS0/DS0+FC09Hyw8KSs6Oio4TCg2YCYzdSQwiSEtnB0qsBgmwxMj1w0e7Acb/wMX/wIXET9FFD9FGT9EIj5DLj1CQDxAUjs+ZTk8eTc6jDU3nzE1sS4yxSkv2CQr7Rwn/xEh/w8gD1NMEFNMFlNMI1JLNFJKRlFIWFBGak5FfUxDj0pBoUc/tEQ9x0A62jo37jQ0/ysv/ykuE2dSGWdRI2dRMGZQPmZPTmVOX2RNcGNMgmJLk2BKpF5JtltHyVhG21RE705B/0Y+/0Q9JXtUK3tUM3tUPnpTS3pTWXlSaHlSeHhRiHZRmHVRqXNQunFQzG5P3mtO8GdN/2FM/2BLPo5VQY5VR45VT45UWY1UZY1UcoxUgItUj4pUn4lVrohVv4ZWz4RW4YFW831W/3hW/3dWU6FTVaFTWaFTX6FTaKFUcqBUfaBUip9VmJ5Wpp1WtZxYxZpZ1Jhb5JZc9ZJe/45f/41fZrRRaLRRa7RRcLRReLRRgbNRi7NRl7JSo7FUsLBWvq9XzK5a2qxd6apg+adj/6Nm/6JnecdQesdQfcdPgsZPicZPkcZOmsZOpcVOsMVOvMRPyMNS1cJW4sBa8L5f/rtk/7hq/7drjNhQjdhQkNhPlNdOmtdNotdMqtdKtNdKvtdKydZJ1dZK4dVL7dRP+dJX/89f/8xp/8trn+lWoOlVo+lVpulUq+lTselSuelQwelOy+hM1uhJ4ehH7ehD+edE/+ZG/+RN/+Fd/+BgtflatvlauPlau/lZv/pYxPpXyvpW0fpU2fpT4vpQ6/pO9vlL//lI//lE//hA//dC//ZE1/9f1/9f2f9f2/9f3f9e4f9d5v9c6/9b8f9a+P9Y//9W//9U//9S//9P//9M//9H//9GAAAwAAAwAAAwAAAvCAAuHAAsMAAqRQAnXgAkdgAhjQAeogAcuAAazQAZ4wAY+QAX/gAXAAI2AAI2AAE2BAE1EwEzJwEwOQAuTgAqZQAnfAAjkgAgpgAduwAZ0AAX5gAW+wAV/wAVAAo7AAo7Agk6CQg5Gwc3LQY0PwUyUwUuagMrgAMolAEkqQEhvQAe0gAb5wAX/AAV/wAVABtDAhpDBhlCERlAIBc+MRY7RBQ4WBI1bg8xgw0tlwkqqwYmvwQj0wIf6AAc/QAZ/wAYBixLCSxLECxKGitIJSpGNilESSdCXSY/ciM7hiA4mRw0rRgwwRIr1Qwn6gYi/wIf/wEeDT5TED5SFT5RHT1QKjxPOztNTjpLYThIdTdFiTRCnDE/ry08wyk41iM06xsv/xAo/w4nDFJaDlJaElJZG1FYLlFXQVBVU09TZk1ReUxPjElNnkdKsUNHxD9E2DpA7DM8/ys3/yg2BmZgDGZgGWZfKGVfN2VeSGRdWmNba2JafWFYj19XoV1Vs1tSxldQ2VNO7U5K/0ZH/0RGG3pkIHpkKXlkNnljRHljUnhiYnhhcndhg3VglHRfpXJetnBcyG5b22tZ7mZX/2BV/19UM41mN41mPY1mRoxmUYxmXYxma4tmeopliollmohlqodkuoVkzINj3oBi8Hxh/3hg/3ZgSKBnS6BnT6BnVp9nX59nap9ndp5ohJ5okp1ooZxpsJppwJlp0Jdq4ZVq8pJq/41q/4xqXLNlXrNmYrNmaLJmb7JmebJnhLFnj7FonLBpqa9qt65rxqxs1atu5alv9qZw/6Jy/6FycsZfdMZfd8ZffMVfgsVgisVhlMRincRkqcNltcJnwcFpzsBr3L5u671x+rp0/7d3/7Z4iddYi9dYjddYkddXl9dXntdXptdXr9ZYudZaw9VcztRg2tNk5tJo89Bt/85z/8t5/8p7n+lWoOlWo+lVpulUq+lTselSuelRwelPyulP1OhP3+hQ6udR9eZV/+Ve/+Jn/99z/992tfpbtvpauPpau/pZv/pZxPpYyvpW0fpV2fpT4vpR7PpO9vpL//pI//lF//hJ//ZX//Vd2P9g2P9g2v9f3P9f3v9e4v9d5/9c7P9b8v9a+f9Y//9W//9U//9S//9P//9M//9I//9HAAA7AAA6AAA6AAA5BQA4GAA1LQAyQgAvXAAsdAApigAmoAAktgAhywAg4QAe+AAd/QAdAAFBAAFBAAFAAgE/DwE9IwE6NgA3SwA0YwAwegAsjwAopAAluQAhzgAe5AAd+gAc/wAcAAlGAAhGAQhFBQdEFgZBKQY+OwU7UAQ4ZwM0fQIxkgEtpgApuwAm0AAi5QAf+wAc/wAcABpPABlOAxhNDRhLGxZJLRVGQBNDVRE/aw87gAw3lAgzqQYvvQMr0QEo5wAk/AAg/wAfAytXBStXCytWFipUIilSMShQRCdNWSVJbiJGgx9Clhs+qhc5vxE00wsv6AYr/QIm/wElCj1fDD1fEj1eGTxdJjtbNjpZSTlWXThTcjZQhTNMmTBJrC1FwChB1CI96Rs3/hAx/w0vCVFoClFnDlFnF1BmJlBkO09iTk5gYk1ddUtbiElYm0ZVrkNSwT9O1TlK6jNF/ipA/yg/AGVvAWVvCmRuHmRtMGRsQmNrVGJpZmFneWBli15jnVxgsFpew1db1lNY6k1U/kVQ/0NPFHh0F3h0Hnh0K3hzO3hyS3dxXHZwbXZvfnVtj3NsoXJqs3BoxW1m2Gpk62Zh/2Be/19eJ4x5Kot4MYt4PIt4SIt3Vop3ZIp2dIl1hIh0lYdzpYZytoRwyIJv2n9u7Xxs/3dq/3ZqPJ57P557RJ57TJ57Vp57YZ17b516fZx6jJt5m5p5q5l4u5h4zJZ33ZR275F1/410/4x0UbF7U7F7V7F7XbF8ZbB8cLB8e7B8iK98la58o618sqx8wat90ap94ah98qV9/6J9/6F9Z8R3acR3bMR3ccN4eMN4gcN5i8J6lcJ7ocF8rcF9usB+yL9/172A5ruB9rmC/7aE/7aEgdZsg9ZshdZtidZtj9VuldVvndVxptRysNR0u9N2xtJ509F74NB+7c6B/M2E/8qI/8mJneldnuldoOldpOldqOleruletOhevOhfxehhzudk1+Zo4eVt7ORy+ON4/+F//96G/92ItvpbtvpbuPpau/pav/pZxPtYyvtW0ftV2vtT4/tR7PpP9vpQ//lT//hY//dk//R1//N52f9g2f9g2v9f3P9f3/9e4/9e6P9d7f9b8/9a+v9Z//9X//9V//9S//9P//9M//9I//9HAABFAABEAABDAABCAwBBFAA+KQA7PwA4WQA0cQAxiAAungArtAApygAn4AAl9wAk/AAkAAFLAAFLAABKAQBJCwBHHwBEMgBASAA9XwA5dwA0jQAxogAttwApzAAm4gAk+QAj/QAjAAhRAAhQAAdQAwZOEgZLJAVJNwRFTANCZAI+egI6jwE2pAAyuQAuzgAq4wAm+gAj/gAjABlaABhZARhYCBdWFhVUKRRRPBNNURBJZw5FfQtBkQg8pgU4ugM0zwEw5QAs+wAo/wAnASpjAipiByphESlfHShdLCdbQCZYVSRUayJQfx9MkxtIpxZDvBA+0Ao55gUz+wEu/wEtBjxsCTxrDjxqFTtpITtnMDpkRDliWTdebjVbgjJXlS9TqSxPvSdL0SJG5xpA/A85/ww3B1B1CFB0C1BzE1ByH09xNU5uSU1sXUxpcUpmhEhjl0Vgq0Jcvj5Y0jlU5zJP/SlJ/ydHAGR8AGR8AWR7E2N6KGN5O2J3TmJ1YmFzdV9xh15umlxsrFlpwFZl01Ji6E1e/UVZ/0NXD3eDEneDF3eCIXeBM3eARHZ/VnZ9aHV8eXR6i3J4nXF2r29zwm1x1Wlu6WVr/V9n/15nGoqIH4qIJoqHMYqHP4qGTomFXomEb4iDf4eBkIaAoYV+s4N8xYF713956nt2/nd0/3VzLp2MMp2MOZ2MQp2LTZyLWpyKaJyKd5uJhpqIlpqHppiGt5eEyJWD2pOC7JCA/ox//4t+Ra+PR6+PTK+PU6+OXK+OZ6+Oc66Nga6Nj62MnayMrauLvKqLzamK3aeJ76WJ/6GI/6CIW8KOXcKOYcKOZsKObsGOd8GOgsGPjcCPmsCPp7+Ptb6Pw72P0ryP4ruP8riP/7WQ/7WQddSIdtSIedSIfdOIg9OJi9OKlNOKndKLp9KMs9GNv9GOzNCP2s+Q6M2S98yT/8mV/8iWk+d3lOd3lud4med4nud5pOZ6q+Z8suZ9uuV/xOWCzuSF2eOI5OKL8eGO/t+S/92W/9yYtftdtvtduPtduvtdvvtdw/tdyPpezvpe1vpf3fph5vll7vhr9/dy//Z6//SD//KO//GQ2v9g2v9g2/9g3f9f4P9f5P9e6P9d7v9c9P9a+v9Z//9X//9V//9S//9Q//9N//9S//9XAABNAABMAABLAABLAQBJEABHJQBEPABAVgA9bwA5hQA2nAAzsgAwyAAu3gAs9QAq+gAqAAFVAABVAABUAABTBgBRGgBOLgBKRABHXABCdAA+igA6nwA2tQAyygAu4AAs9wAq/AAqAAdcAAdbAAZaAQVZDAVWIARTMwNQSANMYAJIdwFDjAE/oQA7tgA3ywAz4QAv+AAq/QAqABhlABdlABdkBBZhERReJBNcNxFYTRBUZA1PegpLjgdGowRCuAI9zQE54gA0+QAw/gAuACpvACluBCltDShrGSdoJyZmOyVjUSNfZyFbfB5WkBpSpBVNuRBHzgpC5AQ8+gE2/gE1Azx4BTt3CTt2ETt0HDpyKzlwPzhtVTZpajRmfjJiki9epitauidVzyFQ5BlJ+w5B/wxABU+BBk+ACE+AD09+G058Lk16REx3WEt0bUlxgEdulEVqp0Fmuz1i0Dhd5TJY+ylR/yZPAGOJAGOIAGOIBWKHH2KFNGKDSWGBXWB/cF98g115llt2qVlzvVZv0FJr5Uxn+0Rh/0JgCHeQC3aPEHaPGnaOKXaNPHWLUHWKYnSIdXOGh3KDmXCBq25+v2x70ml45mV1+19w/15vCImWDomVGomVJomUNomTR4mSWIiRaYePeoaOi4WMnYSKr4OIwYGG1H6D53uA/HZ9/3V8H5ybJJybLJyaN5yaRJuZUpuYYZuXcZqWgZqVkZmTopiSs5aQxJWP1pKN6ZCL/YyI/4qIOa6fPK6fQa6eSa6eU66eX66dbK2de62ciaybmKuaqKuZuKqYyKiW2qaV66SU/qGT/6CSUMChUsChVsChXcCgZcCgb8CgesCfhr+fk7+fob6er72evrydzrud3rqc77ic/7Sb/7SbadKfa9KfbtKfc9KfedGfgdGfi9GfldGfoNCfrNCfuc+fxs6g1c2g48yg88uh/8ii/8eihuWWh+SWieSWjeSWkuSXmOSYn+SYp+OZsOOau+ObxuKc0eGd3uGf69+g+d6i/9yl/9umq/l4rPl4rvl5sPl5tPl7uPh8vfh+w/iAyveD0veG2vaJ4/WN7fWR+PSW//Kb//Ci/++j2v9g2/9g3P9g3v9g4f9f5f9e6f9d7/9c9f9b+/9Z//9X//9V//9U//9X//9g//93//9+AABXAABWAABVAABUAABTCwBQIQBNOABKUgBGawBCgwA/mQA8rwA5xgA23AA09AAx+QAxAABgAABfAABeAABdAwBbFQBYKgBUPwBRWABMcABHhwBDnAA/sgA7yAA23gA09QAy+gAxAAZnAAZmAAVlAAVjBgRhGwNdLgNaRAJWXAFRcwFNiQBJngBFswBAyQA83wA39gAy+wAyABdwABZwABZuAhVsDBNpHhJmMhBjSA5eYAxZdglViwZQoARLtQJGygBB4AA99wA3/AA2ACl6ACh5ASh4CCd2FCZzIiVxNiRtTCJpYyBleB1gjRlcoRVWtg9RywlK4QRE+AE+/QA9ATuDAjuCBjqBDDp/Fzl9Jzh7Ojd4UDV0ZjNwezFsji5noypjtyZezCBY4hhS+Q1J/gtHA0+MBE+MBk6LC06JF02IJk2FPkyCVEp/aUl8fUd4kER0pEFwuD1rzThm4jFg+ShZ/iZXAGKVAGKUAGKUAWKSFGGRLGGPQ2CMWF+KbF6Hf1yEklqBplh9ulV5zlF140xv+URp/UJoAXacA3acCXWbE3WaIHWZNXWXSXSVXXOTcHKRgnGOlXCMqG6Ju2uFz2iC42R++V55/l14AImjAoiiCYiiGoihLIigPoifUYedY4ecdYaah4WYmYOVq4KTvoCQ0X2N5XqK+XWG/nSFEJuoFJuoHZuoK5unOpunSpqmWpqka5mjfJmhjJignpeer5acwZSa05KX5o+V+ouS/oqRKq2tLq2tNa2tPq2sSq2sV62rZayqdKypg6uok6uno6qls6mkxKei1qWh6KOf/KCd/5+cRL+xR7+wTL+wU7+wXL+wZ7+vc76vgL6ujb6tm72sqryrubyqybqp2rmo67en/rSm/7OmXtCyYNCyZNCxadCxcNCxedCxg9Cxjs+wmc+wps+ws86vwc2vz8yu38uu78qu/8eu/8eueuKufOKufuKuguKuh+KujuKuluKun+KuqOGvs+Gvv+Gvy+Cw2N+w5t6x9N2y/9uz/9qznfadnvadn/aeovWepvWfqvWgsPWht/WivvWjx/Sk0PSm2vOo5fOq8fKs/fGv/++z/+602/9h3P9h3f9h3/9h4f9h5P9i6f9i7f9i8/9k+P9m/v9p//9u//92//9///+L//+a//+eAABhAABgAABfAABeAABdBgBaHQBXNABTTgBPaABLgABHlgBErQBBxAA+2gA78gA49wA4AABqAABpAABoAABnAQBlEABiJQBeOwBaVABVbQBRhABMmQBIrwBDxgA+3AA88wA5+AA4AAVxAAVwAAVvAARuAwNrFQNoKQJkQAJgWAFbcABWhQBSmwBNsABJxwBE3QA/9AA5+QA5ABZ7ABV6ABV5ABR3BxJ0GBFwLQ9tRA5oXAtjcgheiAVZnQNUsgFPyABK3gBE9QA/+gA9ACiEACeEACeCBCaADyZ+HSV7MSN3RyFzXx9vdBxqiRhlnhRfsw5ZyQhT3wNM9gBG+wBEADqOATqNAzmMCDmKEziIIjeFNDaCSzV+YjN6dzB1iy1xoCpstCVnyh9h4Bha9w1R/ApPAk6XAk6XBE2WCU2UE02SIEyQOEuNT0qJZEiGeUaCjUN+oUB5tjx0yzdv4DBo9ydh/CVfAGKgAGGgAGGfAGGeCGGcJGCaPF+XUl6UZ12Re1yOj1qLoliHtlWCy1F+4Et490Nx/EFvAHWoAHWnAnWnCnWmGXSkK3SjQ3OgV3Kea3KcfnCZkW+WpG2TuGuPzGiL4WSH9l6B+12AAIiuAIiuAIiuCIetH4esNoerSoapXYancIWlgoSilYOgp4Gdun+azn2X4nqT93WP/HSOCZq1C5q1Dpq0G5q0L5qzQZmyU5mxZZmvdpith5ermZapq5WnvZOk0JGi446e+Iqb/YmaG6y7IKy7Jqy6Mqy6QKy5Tqy4Xqu3bau2fqq1jqqznqmyr6iwwKeu0qWr5aOp+Z+m/p6lN76/Or6/QL6/SL6/Ur6+Xr69a729eb28h727lry6pby4tbu3xbq21ri057ay+7Ow/7OwU8/CVc/CWc/CX8/CZ8/BcM/Be87Ahs7Aks6/n86/rc2+vMy9y8y82sq768m6/ce5/8a5cOHCceHCdOHCeOHCfuHCheHBjeDBl+DBoeDBrODBuN/Axd/A0t7A4N3A8Ny//9rA/9nAkfO5kvO5k/O5lvO5mvO5oPO6pvO6rfO7tfO7vvK8yPK80/K93vG+6vC/9+/B/+7D/+3Dzf+Izf+Izv+J0P+J0v+L1f+M2f+O3f+Q4v+T6P+W7f+Z9P+d/P+h//+l//+r//+0//+2AABrAABqAABpAABoAABmAwBjGABgLwBcSgBYZQBUfQBQkwBMqgBJwQBF2ABC8QA/9gA/AAB0AABzAAByAABxAABvCgBrIABoNwBkUABfaQBagABVlgBQrQBLwwBG2gBD8gBA9wA/AAV7AAR6AAR5AAN4AQN1DwJxJAJuOwFpVAFkbABfggBbmABWrgBRxABM2wBG8gBB+ABAABWFABSEABSDABOBBBF+ExB6KA92Pw1yVwpsbwdnhAVimQNdrwFXxQBS3ABM8wBG+ABEACePACaOACaNASWLCiWIGCSFKyKBQyF9Wh54cRtzhhhumxNosQ1ixwdb3QNU9ABN+QBLADmZADmYATmWBTiVDjeSHTaPLzWMRjSIXTKDcy9/iCx6nCl1sSRvxx9p3Rdi9QxY+glWAU2iAU2hAk2gBkyfD0ydHEuaMUqXSUmTYEePdUWLiUOHnUCCsjx9yDZ33jBw9Sdo+iRmAGGrAGGqAGGqAGCoA2CmGl+kNV+iTV6eYl2bd1uYi1mUn1eQs1SLyFCG3kuA9EN5+kF3AHSzAHSyAHSyA3SxEXSvJHOtO3OrUXKpZnGmenCjjW6goWyctWqYyWeU3mOP9F2J+VyIAIe6AIe6AIe5AIe4Doa3K4a2Qoa0V4Wya4SvfYOtkIKqo4Gnt3+kynyg33mc9XSX+nOWA5nBBZnBCZnBD5nAIJm/N5m+S5i8Xpi6cJe4gpa2lZW0p5SxuZOuzJGr4I6o9Yqj+omiD6vIEqvIGavHJKvHNKvGRavFVqrEZ6rCd6rBiKm/mai9qqe7vaa4z6S14qKy9p+v+56uJ73NK73NMb3NO73MSL3MVb3LY7zKcbzJgLzIkLvGoLvFsLrDwbnB0re/5La9+LO6/bK5Rs7RSc7RTc7RVM7RXc7QZ87Qcs3Pf83OjM3Nmc3Mp8zLtsvKxsvI1srH58jF+sbD/8XCZN/TZt/Tad/Tbt/TdN/TfN/Shd/Sj9/Smt/Rpd7Qst7Qv97Pzd3O29zN69vM/dnL/9nLhfHPhvHPiPHPjPHPkPHPlvHPnPHPpPHPrPHPtvHPwPDPy/DP2PDP5O/Q8u7Q/+3R/+zRu/+0vP+0vf+0vv+1wf+1xP+2yf+2zf+30/+42v+54f+76P+88f+++v/B///E///J///LAAB0AABzAAByAABxAABvAQBsEgBpKwBlRgBgYQBceQBYkABUqABQvwBN1gBJ7wBG9ABFAAB+AAB9AAB8AAB6AAB4BQB0GgBxMQBtTABnZQBifQBdkwBYqgBTwQBO2ABK8ABH9QBGAASFAASEAAODAAOBAAJ+CgJ7HwF3NgFzTwBtaABofwBjlQBeqwBZwgBT2QBN8QBI9gBHABSPABOOABONABKLARGIDQ+EIg6AOgx7Uwl1awZwgQRqlgJlrAFfwwBZ2QBT8QBN9gBLACaZACaYACWXACWUBSSSEyOOJSGLPiCGVh2BbRp8ghd2mBJwrgxqxAZj2wJb8gBU9wBSADijADiiADihAjefCTecGDaZKjWWQTORWTGMby6IhCyDmSh9riR3xR5x2xZp8wtf+AhdAEysAEysAUyrBEypCkunGEqkKUmhREidW0eZcEWVhUKQmj+LrzuFxTZ/2y948yZv+CNtAGC1AGC1AGC0AGCzAl+xDV+uLV6rR12oXVylclqhh1mdm1aZsFOUxVCP20qI8kKA+EB+AHO+AHO9AHO8AHO7B3O6HHK4MnK1S3GzYXCwdW+siW6pnWylsWqhxmed22KX8l2R91yPAIbFAIbFAIbEAIbDAYbCHYXBOoW/UIS8ZYS6eIO3jIK0n4Cws36tx3yp3Hik8nSf93KeAJnNAJnMApjMCJjLFJjKK5jJQpjHV5fFapbDfZbBkJW+o5S7tpK4yZC03Y2w84ms+IiqA6rUBarUC6rTGKrTJqrSOqrRTarPX6nOcanMg6jKlKjIpqfFuKXCy6S/36G89J63+Z23FrzaG7zaIrzZLbzZO7zYS7zXWrzWarvVervTirvSmrrQq7nOvLjLzrfJ4bXG9bLC+rLCOM3fO83fQM3fSM3fUs3eXc3daszcd8zbhczak8zZosvXscvWwcrU0snS48jQ98XN/MXMWd7iWt7iXt7iY97iat7ict7hfN7hh97gkt7fnt3eq93dud3cyNzb19vZ59rY+tjW/tjWevDie/DifvDigfDihvDijPDik/DhnPDhpO/hru/gue/gxe/g0e7f3u7e7e3e/ezd/+vdrf/Trv/Tr//Tsf/Ts//Tt//UvP/Uwf/Ux//Vzv/V1v/V3v/W5//X8f/Y+//Z///c///dAAB9AAB8AAB7AAB6AAB4AAB1DQBxJgBuQgBpXQBkdgBgjgBcpQBYvQBU1ABQ7QBM8wBMAACHAACGAACFAACDAACBAgB9FAB5LQB1RwBwYQBreQBlkABgpwBbvwBV1gBR7gBO8wBNAASOAAONAAOMAAKKAAKIBAGEGQGAMQF7SwB2ZABwewBrkQBmqABhvwBb1gBV7wBO9ABOABOYABKXABKWABGUABCRBw6NHAyJNQqETgh+ZgV4fQNzkwJtqQFnwABh1wBb7wBU9QBSACWiACWhACSgACSeAiObDSKYHiCUOB+PURyKaBmEfhZ/lBF4qgtxwQZq2AJj8ABb9QBZADetADesADeqADaoBTamEzWjJTSfOzKaVDCVai6QgCuLlieGqyN/wh142RVw8Qpm9gdkAEu2AEu2AEu0AkuzB0qxFEquIkmqPUemVkaibESdgUGZlz6TrDqNwjWH2S5/8SV29iN0AF/AAF+/AF++AF+9AF+7B164I121QFyyWFuubVqqgliml1airVOcwk+X2UqQ8EKI9T+FAHPIAHPIAHLHAHLGAHLEEnLCKXG/RHC8W3C5cG62hG2ymWuurmmqw2al2WKf8FyY9VuXAIXQAIXQAIXPAIXOAIXNCIXLL4TJSYTGX4PDc4LAh4G9m3+5r361xHux2Xis8HOm9XKlAJjYAJjXAJjXApjWCpfVHJfUOJfST5bQZJbNd5XLi5TInpPEspHBxo+92o248Imz9oiyAKrfAKreAareBqrdGancLKnbQ6nZV6nYaqjWfajUj6fRoqbOtKXLx6PI3KHE8Z6/9p2+BLvlBbvlDbvlHbvkLbvkP7vjUbvhYrvgcrreg7rclbnaprnYuLjVyrbS3bTP8rHL97HKJMzsKMzsL8zrOczrRczqU8zqYMzpbsvnfcvmjMvknMrjrMrhvMnfzsjc4MfZ9MXW+cTVS93xTd3xUd3xV93wX93waN3vc93vft3uit3tl9zrpdzqs9zpwtvn0tvl49rj9tjg+9ffbu7zcO7zcu7zdu7ze+7zgu7ziu7yku7ynO7xpu7wsu7wvu7vy+3u2e3s6Ozr+uvp/uvpoP/soP/sov/spP/sp//sq//ssP/stv/svP/sxP/szP/s1f/s3//s6f/s9P/s///t///uAACFAACFAACEAACCAACAAAB+BwB6IAB1PQBxWQBscgBoigBjogBfugBb0gBX6wBT8QBSAACQAACPAACNAACMAACKAACGDgCCJwB9QgB4XQBzdQBtjQBopABivABc0wBY7ABU8QBTAAOXAAOWAAKVAAKTAAKRAQGNEgGIKwCDRgB+XwB4dwBzjgBupQBovABi1ABb7QBV8gBUABKhABGgABGfAA+dAA6aAw2WFQySLwmMSQeGYgWAeQN6jwF1pgBvvQBo1QBh7QBa8wBYACSrACSrACOqACOnACKkByGhGB+dMR6YTBuSZBiMehWGkRCApwp5vgVx1gFp7gBh8wBfADe2ADa1ADa0ADWyAjWvDDSsHzOoNDGjTi+eZi2ZfCqTkiaNqCKHvxyA1hR37whs9AZqAEvAAEu/AEq+AUq8BEm6Dkm3HUizNkevUEWqZ0OlfUGhkz2bqTmVvzSO1i2G7iR99CJ6AF/JAF/JAF7IAF7GAF7EBF3CFl2+OFy7UVu3aFmyfleuk1WpqVKkv06e1kmX7kGO8z6MAHLSAHLSAHLRAHLPAHHOBXHLIHHJO3DFVG/Cam6+f2y6lWu2qmixwGWs1mGm7luf81qdAIXaAIXZAIXZAITXAITWAITUIYTSQIPPWILMbYHJgoDFl3/CrH29wXu51nez7nOt83GrAJfhAJfhAJfgAJfgApfeEZbdKpbbRpbZXJXWcZTThZPQmZLNrpHJwo/F14zA7oi684e5AKnpAKnpAKnoAKnoBqnnHqnlNqjkTajiYqjgdqfdiabanaXXsKTUxKLQ2KDM753H9JzFALvxALvwALrwBLrvGrrvL7ruRLrsWLrqarrpfLnmjrnkobjhs7fexrbb2rTX8LHT9bHSBsv4DMv4F8v3JMv3NMv2Rcv1Vcv0ZMvzdMrxhcrvlcrtpsnrt8npycjm3Mbi8cTe9sTdONz+O9z+QNz9R9z9Udz9XNz8aNz7dNz6gdz5j9z4ntv2rdv0vdvyzdrw39nt89fp+NfoYO3/Yu3/ZO3/ae3/b+3/du3/f+3/iO3/k+3/nu3+qu39t+38xez70+z54+z39ur0++rzk///k///lf//l///m///n///pf//q///sv//uf//wv//zP//1v//4f//7f//+//+///+AACGAACFAACEAACDAACBAAB+BwB6IAB2PQBxWABscgBoigBkogBgugBb0gBX6wBT8QBSAACQAACPAACOAACNAACKAACHDgCDJwB+QgB4XQBzdQBujABopABjvABd0wBZ7ABU8QBUAAOXAAKWAAKVAAKUAAGRAQGNEgGJKwCERgB+XwB4dwB0jgBupQBovABi1ABc7QBV8gBUABKhABGhABCgAA+eAA6bAw2WFAySLwmNSQeGYgWAeQN7jwF1pgBvvQBp1QBi7QBa8wBZACSsACSrACOqACOoACKlByGhGB+dMR6YTBuSYxiNehWHkBCApwp5vgVy1gFq7gBh8wBgADa2ADa2ADa0ADWyAjWvDDSsHzOoNDGkTi+eZS2ZeyqUkiaOqCKHvxyA1hR37ghs9AZqAEvAAEvAAEq+AEq9BEm6Dkm3HUi0NkevUEWrZkOmfEGhkj2cqTmVvzSP1i2H7iR99CF7AF/KAF/JAF7IAF7HAF7FBF3CFl2/N1y7UVu3aFmzfVeuk1WqqVKkv06e1kmX7kGP8z6MAHLTAHLSAHLRAHLQAHHOBXHMIHHJO3DGVG/Cam6/f2y7lWu2qmiywGWs1mGm7Vuf81qdAIXaAIXZAIXZAITYAITWAITUIIPSP4PPV4LMbYHJgoDGl3/CrH2+wXu51ne07nOt83GsAJfiAJfhAJfhAJfgApffEZbdKpbbRZbZXJXWcZTUhZPRmZLNrpHJwo/F14zA7oi684e5AKnqAKnpAKnpAKnoBannHajmNajkTajiYqfgdafdiabbnKXYsKTUw6LR2KDM753H9JzGALvxALvxALrxBLrwGbrvLrruRLrtV7rrarrpfLnnjrnloLjis7ffxrbb2rTY8LHT9bHSBMv4C8v4Fcv4I8v3M8v3RMv2VMv0ZMvzdMryhMrwlcrupsnst8npycjm3Mbj8cTe9sPdN9z+Otz+P9z+Rtz+UNz9W9z9Z9z8c9z7gdz6j9z4ntv3rdv1vdvzzdrw39nt89fq+NfpX+3/Ye3/ZO3/aO3/bu3/de3/fu3/iO3/ku3/nu3/qu3+tu39xOz70+z64+v39ur0+ur0kv//k///lP//l///mv//n///pP//qv//sv//uf//wv//y///1v//4P//7P//+///////\",velvet50:\"AAAAAwAACwAAFgAAKAAAPQAAUQAAYwAAdAAAhQAAmAAAqgAAugAAyQAA2gAA6wAA/AAAAAQAAwMACwIAFgEAKAEAPQAAUQAAYwAAdAAAhQAAmAAAqQAAugAAyQAA2QAA6gAA/AAAAg0BBQwBCgoAFwkBKQYBPgMBUgIBYwEAdAABhgABmAAAqgAAugAAyQAA2QAA6gAA/AAABRsCCBoCDRkCFxgCKxQCQBECUw4CZAsCdQgChwUCmQIBqgEBuwABygAB2gAA6wAA/AAACDIEDDEEEjAEHC4ELCsEQCgEUyUEZSIEdh8EhxwDmhgDqxQDuxACygwC2wgB7AQB/QIABkgGCkcGEUYGGkUGKUIGP0AGUj0GZDoGdTcGiDQFmjEFqy0FuyoEyycD2yMD7B4C/hkBAVwJAlsJBloJDVgJJFYJPVQJUVIJY08JdU0JiEoImkcIq0QHvEEGyz0G3DoE7TYD/jICAG0NAG0NAGwNCmoNJGkNO2cNT2UNYmINdWAMiF0LmloLq1gKu1UJy1II3E8G7UsF/kcEAIAQAIAQAH8QB34QGXwQNnoQTHkQYHcQc3QPh3IPmm8OqmwNu2oMy2cL3GQJ7WAH/10FAJQTAJMTAJITAJETF5ATLo8TR40TXIsTcokShocSmIQRqYIQun8Pyn0O23oM7XYJ/nMHAKYWAKUWAKUWAKQXAqMXJqEXQqAXWp4WcJwWhJoWl5cVqJUUuZMTyZAR244P7YsM/ocJALcYALYYALYZALUZALQZGLMZPrEZWbAZb64Zg6wYlaoYp6cXuKUWyaMU26AS7Z4P/5sMAMgXAMgXAMcXAMcXAsYYEsQYOsMYV8EZbcAZgb4ZlLwZpboYt7gXyLUW2rMU7bAR/q0NANkbANkbANgbANgbANcbBtYbNNUbU9MbatEaftAZkc4Xo8wVtcoVx8gU2cYT7MMR/sANAOshAOshAOshAOohAOohAOkhK+chTeYgZOUfeuMejeEdoOAbs94YxdwT2NkM69cL/dQJAP4lAP4lAP0lAP0lAPwlAPslHvolQ/kkXfgkdPYjifUinfMgsfEdxO8Z1+0R6usA/OgAAP8oAP8oAP8oAP8oB/8nE/8nOP8nUf8mZv8mef8kjP8jn/8hsv8ew/8a1v8T6f0D+vsAAAABAwABCgABFgACKAACPQACUQACYwABdAAChgABmQABqgABugABygAA2gAA6wAA/QAAAAMDAwMDCgIDFgEDKAADPQADUQADYwADdAADhgADmAADqgACugACyQAB2gAB6wAA/AAAAgwEBQsECgoEFwkEKQYEPgMEUgIEZAEEdAAEhgAEmQADqgADugADygAC2gAC6wAB/QAABRsGCBoGDRkGFxcGKxQGQBEGUw4GZQoGdQcGhwQFmgIFqwEFuwAEygAD2wAD7AAC/QABCDIIDDEJEjAJHC4JLCsJQCgJUyUIZSIIdh8IiBsHmhgHqxQGuxAGywwF2wgE7AQD/gICBkgLCkcLEUYLGkULKUILP0ALUj0LZDoLdjcLiDQKmjEKrC0JvCoIyycH3CMG7R4E/hkDAVwOAlsOBloODVgOJFYPPVQPUVIOY08OdU0OiEoNm0cNrEQMvEELyz0J3DoI7TYG/jIEAG4SAG0SAGwSCmsSJGkSO2cSUGUSYmMSdWARiF0RmloQq1gPvFUOy1IM3E8K7UsI/kcGAIAVAIAVAH8VB34VGXwWNnsVTHkVYHcVdHQUh3IUmm8Tq2wSu2oRy2cP3GQN7WEL/10IAJQZAJMZAJMZAJIZF5AZLo8ZR40ZXIsZcokYhocYmIQXqYIWun8Uyn0T23oR7XcO/nMKAKYbAKUbAKUbAKQcAqMcJqIcQqAcWp4ccJwchZobl5gaqJUZuZMYyZEW244U7YsR/ogNALccALYcALYdALUdALQdGbMdPrIdWbAdb64dg6wdlaodp6gcuKUbyaMZ26AX7Z4U/5sPAMgfAMgfAMcgAMcgAsYgEsUgOsMfV8EfbcAfgb4elLwdpboct7gcyLUb2rMZ7bAW/q4RANklANklANglANglANclBtYlNNUlU9MlatIkftAkkc4jo8whtcofx8gb2sYX7MMV/sASAOspAOspAOspAOopAOopAOkpK+goTeYoZOUoeuMnjeImoOAks94ixtwf2NkZ69cP/dQMAP4rAP4rAP0rAP0rAPwrAPsrHvorQ/krXfgqdPYqifUpnfMosfEmxO8i1+0d6usT/OgAAP8vAP8vAP8vAP8vB/8uFP8uOP8tUf8tZv8sef8rjP8qn/8osv8mxP8i1v8d6f0U+/sAAAAFAwAFCgAFFQAFKAAFPQAFUQAFYwAFdAAFhgAFmQAEqgAEuwADygAD2wAC7AAB/QABAAMIAwMICgIIFgEIKAAIPQAIUQAIYwAIdAAIhgAHmQAHqgAGugAFygAF2gAE6wAD/QACAgwKBQsKCgoKFggKKQYKPgMKUgIKZAEKdQAKhgAJmQAJqgAIuwAHygAG2gAF7AAE/QACBRsNCBoNDRkNFxcNKxQNQBANUw4NZQoMdgcMhwQMmgILqwEKuwAJygAI2wAH7AAF/QADCDEQDDEQEjAQHC4QLCsQQCgQVCUQZSIQdh8PiBsOmxcOrBQNvBALywwK3AcJ7QQH/gEFBkgTCUcTEUYTGkUTKUITP0ATUz0TZToTdjcSiDQSmzERrC0QvCoPyyYN3CIL7R4J/hkHAVwWAlsWBloWDVgXJFYXPVQXUVIXY08WdU0WiEoVm0cUrEQTvEESzD0Q3DoO7jYM/jIJAG4aAG0aAGwaCmsaI2kaO2caUGUaYmMadWAZiF0Zm1oYrFgXvFUVy1IT3E8R7ksO/0cLAIAeAIAeAH8eBn4eGXweNnseTHkeYHcedHQeiHIdmm8cq20bu2oZy2cX3GQV7mES/10OAJQhAJMhAJMhAJIhF5AiLo8iR40iXYwicokhhochmIQgqYIfun8eyn0c3HoZ7ncV/nMRAKYjAKUjAKUjAKQkAqMkJqIkQqAkWp4kcZwkhZokl5gjqJUiuZMhypEg244d7Ysa/4gVALcoALcpALYpALUpALQpGbMpPrIpWbApb64og6wolqonp6gluKUkyaMi26Eg7Z4d/5sZAMgtAMgtAMctAMctAsYtEcUtOsMtV8ItbcAsgb4slLwrpboqt7goyLYl27Mi7bAe/64aANkxANkxANkxANgxANcxBtYxNNUxU9MxatIwftAwkc4vo80utcosx8gp2sYm7MMg/sEZAOw0AOs0AOs0AOs0AOo0AOk0K+g0TOY0ZOU0euMzjeIyoeAxs94wxtwt2dop69ck/dUYAP42AP42AP42AP02APw2APs2Hvs2Q/k2Xfg2dPc1ifU1nfMzsfEyxO8w1+0s6usm/OkZAP86AP86AP85AP85CP85FP85OP84Uf84Zv83ev82jf81n/8zsv8xxP8u1v8p6f4j+/sVAAAMAwAMCgAMFQAMJwAMPQAMUQAMZAAMdQAMhwALmQAKqwAKuwAJywAH2wAG7AAF/gADAAMRAwMRCgIRFgERJwARPQARUQAQYwAQdAAQhgAPmQAOqwANuwAMygAL2wAJ7AAH/gAFAgwUBQsUCgoUFggUKQYUPgMUUgIUZAATdQAThwASmQARqwAQuwAPygAN2wAL7AAJ/gAHBRoXCBoWDRkWFxcXKxQXQBAXUw0XZQoWdgcWiAQVmgIUqwETvAASywAQ2wAO7QAM/gAJCDEbDDEbEjAbHC4bLCsbQCgbVCUbZSIadh8aiBsZmxcYrBMXvBAVzAwT3AcR7QQP/wEMBkgfCUcfEUYfGkUfKUIfPz8fUz0fZTofdjcfiTQemzEdrC0bvCoazCYY3SIV7h4S/xkOAVwjAlskBlokDVgkJFYkPVQkUVIkZE8kdk0jiEojm0cirEQgvEEezD0c3ToZ7jYW/jESAG4oAG0oAGwoCmsoI2koO2coUGUoYmModWAoiF0nm1smrFglvFUkzFIh3U8e7ksb/0cWAIErAIArAH8rBn4rGH0rNnssTHksYHcsdHUriHIrmm8qq20pvGooy2cm3WQj7mEg/10aAJQvAJQvAJMvAJIvFpEvLo8vR44vXYwvcokvhocumYUuqoItuoAry30p3Hon7nck/3MfAKYzAKYzAKUzAKQzAqMzJqI0QqAzWp4zcZwzhZozl5gyqZYxuZMvypEt3I4r7osn/4gjALc3ALc3ALY4ALY4ALU4GbM4PrI4WbA4b643hKw3lqo2p6g1uaY0yaMy26Ev7p4r/5slAMg7AMg7AMg7AMc7AsY7EcU8OsQ8V8I7bcA7gr47lLw6pro5t7g4ybY227M07bAv/64oANk/ANk/ANk/ANg/ANc/BNY/NNU/U9Q/atI/ftA+kc8+o809tss8x8g62sY37cMz/sEsAOxCAOxCAOtCAOtCAOpCAOlCK+hCTOdCZOVCeuRBjuJBoeBAs94/xtw92do77Nc3/tUvAP5EAP5EAP5EAP1EAP1EAPxEHvtEQvpEXfhEdPdDifVDnfRCsfJBxPA/1+096us4/OkwAP9HAP9HAP9GAP9GCP9GFP9GOP9GUf9FZv9Fev9Ejf9DoP9Csv9BxP8+1v876f41+/wqAAAXAwAXCgAXFQAXJwAYPQAYUQAXZAAXdQAXhwAVmgAUqwATvAASywAQ3AAO7QAM/wAJAAMdAwMdCgIdFQEdJwAdPQAdUQAdYwAddQAchwAbmQAaqwAYuwAXywAV2wAT7QAQ/gANAgwhBQshCgohFgghKQUhPgMhUgIhZAAhdQAghwAfmgAeqwAduwAbywAZ2wAW7QAT/gAPBRomCBkmDRgmFxcmKxMmQBAmUw0mZQkmdgYliAQkmwIjrAEivAAgywAd3AAb7QAX/wATCTEqDDAqEi8rHC0rKysrQCcrVCQrZiErdx4qiRsqmxcorBMnvQ8lzAsj3Qcg7gMc/wEXBkgvCUcvEEYvGkUvKEIvPz8vUz0vZTovdjcviTQunDAtrS0svSorzCYo3SIl7h0h/xgcAVwzAlszBlozDVgzJFYzPVQ0UVI0ZE80dk0ziUoznEcyrUMxvUAwzD0u3Tor7zYn/zEiAG43AG03AGw3CWs3I2k4O2c4UGU4YmM4dWA4iV03m1s2rFg1vVU0zFIy3U8w70ss/0coAIE7AIA7AIA7BX47GH08Nns8THk8YHc8dHU8iHI7mm86q206vGo4zGc23WQ072Ex/10sAJQ/AJQ/AJM/AJI/FpE/Lo8/R44/XYw/coo/h4c/mYU+qoI9u4A8y3073Xo47nc1/3MwAKZCAKZDAKVDAKVDAqNDJqJDQqFDW59DcZxDhZpCl5hCqZZBupRAypE/3I487os5/4g1ALdGALdGALdGALZGALVGGLRGPrJHWbBGcK5GhKxGlqpGp6hFuaZEyqND3KFB7p49/5s5AMlKAMhKAMhKAMdKAcZKEcVKOsRKV8JKbcBKgr5KlL1JprpJuLhIybZH27NF7rFC/649ANpNANpNANlNANlNANhNA9dNM9VNU9RNatJNftFNkc9No81MtstLyMlK2sZI7cRF/8FBAOxQAOxQAOxQAOtQAOpQAOlQK+hQTOdQZOVQeuRQjuJQoeBPtN5OxtxN2dpL7NhI/tVEAP9RAP5RAP5SAP5SAP1SAPxSHvtSQvpSXflSdPdSifZRnvRRsfJQxPBP2O5N6+tJ/elEAP9UAP9UAP9UAP9UCP9UFP9UOf9UUv9TZ/9Tev9Tjf9SoP9Rs/9QxP9O1/9L6v5H+/xAAAAmAwAmCgAmFQAmJwAmPQAmUQAmZAAmdQAlhwAkmgAjrAAhvAAgywAd3AAa7QAX/wATAAQtAwMtCgItFQEtJwAuPQAuUQAtZAAtdQAthwAsmgArqwApvAAoywAl3AAi7QAe/wAZAgwxBAsyCgoyFggyKQYyPgMyUgEyZAAydQAyhwAxmgAwrAAuvAAtywAr3AAo7QAk/wAeBRo2Bxk2DRg2FxY2KxM3QA83VAw3ZQk2dgY2iAM2mwI1rAAzvAAyzAAw3AAt7gAp/wAkCTA6DDA6ES86Gy07Kyo7QCc7VCQ7ZiE7dx47iRo6nBY6rRI4vQ43zAo13QYz7gMv/wEqBkg+CUc+EUY/GkQ/KEI/Pz8/Uzw/ZTo/dzc/iTM/nDA+rS09vSk8zSY63SI47x01/xgwAVxCAltCBlpDDVlDI1ZDPVRDUVJDZE9Ddk1DiUlDnEZCrUNBvUBAzT0/3jk97zU6/zE1AG5GAG1GAGxGCWtHI2lHOmdHUGVHY2NHdmBHiV1HnFtGrVhFvVVEzVJD3k9B70s+/0c6AIFKAIFKAIBKBX9KF31KNntKTHlLYHdLdHVLiHJKm29KrG1JvGpIzGdH3mRF72FD/10/AJRNAJRNAJNNAJJOFZFOLZBOR45OXYxOcopOh4dOmYVNqoJNu4BMy31L3XpJ73dH/3NDAKZQAKZQAKZQAKVRAqRRJqJRQqFRW59RcZ1RhZpRmJhRqZZQupRQy5FP3Y5N74tL/4hHALhUALdUALdUALZUALVUGLRUPrJUWbBUcK5UhKxUlqpUqKhUuaZTyqNS3KFR7p5P/5tMAMlXAMlXAMhXAMhXAMdXEMZYOsRYV8JYbcFYgr9YlL1YprtXuLhXybZW3LNV7rFT/65PANpaANpaANpaANlaANhbAtdbM9ZbU9RbatNbftFbkc9bpM1atstayMlZ28ZY7cRW/8FSAO1dAOxdAOxdAOxdAOtdAOpdKuleTOdeZOZeeuRejuNdoeFdtN9cxt1c2dpa7NhY/tVUAP9fAP9fAP5fAP5fAP1fAPxgHvtgQfpgXflgdPhfifZfnvRfsfJexfBd2O5c6+xZ/elVAP9iAP9iAP9iAP9iCP9iFP9iOf9hUv9hZ/9hev9hjf9goP9fs/9exf9d1/9b6v5Y/PxSAAA2AwA2CgA3FQA3JwA3PQA3UQA3ZAA3dQA3iAA2mgA1rAAzvAAyzAAw3QAt7gAp/wAkAAM9AwM9CgI9FQE9JwE+PQA+UQA+ZAA+dQA9hwA9mgA8rAA7vAA6zAA43AA17gAy/wAtAgtBBAtBCglBFghCKAVCPgNCUgFCZABCdgBCiABBmgBArAA/vAA+zAA93AA67gA3/wAzBRlFBxlFDBhGFhZGKhNGQA9GUwxGZQlGdwVGiQNFmwFFrABEvQBDzABB3QA/7gA8/wA4CTBJCy9JES9KGy1KKypKQCdKVCNKZiBKdx1KiRlKnBVJrRJIvQ5HzQpG3gZE7wNB/wA+BkdNCkdNEUZNGURNKEJOPz9OUzxOZTlOdzZOijNOnC9NrSxNvilMzSVK3iFJ7xxG/xdDAVxQAltQBVpRDVhRI1ZRPVRRUVFRZE9RdkxRiUlRnEZRrUNQvkBQzT1P3jlN8DVL/zFIAG5UAG1UAGxUCGtUImlVOmdVUGVVY2NVdmBViV1VnFpVrVhUvVVTzVJT3k9R8EtP/0dMAIFXAIFXAIBYBH9YFX1YNXtYTHlYYHdYdHVYiXJYm3BYrG1YvWpXzWdW3mRV8GFT/11RAJVbAJRbAJRbAJNbFJFbLZBbR45cXYxcc4pch4dcmYVcq4Jbu4BbzH1a3XpZ73dX/3NVAKdeAKZeAKZeAKVeAqRfJaJfQqFfWp9fcZ1fhZpfmJhfqZZfupRey5Fe3Y5d74tb/4hZALhiALdiALdiALZiALViF7RiPbJiWbFjcK9jhK1jlqpjqKhiuaZiyqNh3aFg755f/5tcAMllAMllAMllAMhmAMdmD8ZmOcRmVsNmbcFmgr9mlL1mprtmuLllyrZl3LRk77Fi/65fANppANppANppANlpANhpAtdpMtZpUtRpadNpftFpkc9ppM5ptstpyMlo28dn7sRl/8FiAO1sAO1sAOxsAOxsAOtsAOpsKelsS+hsZOZseeVsjuNsoeFstN9rx91r2ttp7dho/9VkAP9uAP9uAP9uAP5uAP5uAP1uHfxuQPtuXPlvdPhuifZunvVusvNtxfFt2O5r6+xp/uplAP9xAP9xAP9xAP9xB/9xFP9xOf9wUv9wZ/9wev9wjv9vof9vs/9uxf9t2P9r6v9o/P1jAABFAwBGCgBGFQBGJgBGPQBGUQBGZABGdQBGiABGmwBFrABEvQBDzABB3QA/7wA8/wA4AQNMAwJMCgJMFQFMJgBMPABNUQBNZABNdQBNhwBMmgBMrABLvABKzABI3QBG7gBE/wBAAgtPBApQCglQFQdQKAVQPgNQUgFRZABRdgBQiABQmwBQrABPvQBOzABN3QBL7gBI/wBFBBlTBxhTDBdTFhVTKhJUQA9UUwtUZQhUdwVUiQNUnAFTrQBTvQBSzQBR3QBP7wBN/wBKCS9XCy9XEC5XGixXKilXQCZYVCNYZiBYdxxYihhYnBVXrRFXvg1WzQlV3gVU7wJS/wBPBkdaCkZaEEVaGURbKEFbPz5bUztbZTlbdzZbijJbnS9britbvihaziRZ3iBY8BtW/xZUAVxeAlteBVpeDVheIlZePFNfUVFfZE9fdkxfiklfnEZfrUNfvj9ezjxd3zhc8DRb/zBZAG5hAG1hAGxhBmtiIWliOmdiT2ViY2NjdmBjiV1jnFpjrVhivlVizVJh305g8Etf/0ddAIFlAIFlAIBlBH9lFH1lNXtmTHlmYHdmdXVmiXJmm29mrG1mvWpmzWdl3mRk8GBj/11hAJVoAJRoAJRpAJNpE5FpLJBpRo5pXYxqc4pqh4dqmoVqq4JqvIBpzH1p3npo8Hdn/3NlAKdsAKdsAKZsAKVsAaRtJKNtQaFtWp9tcZ1thppumJhtqZZtu5Rty5Fs3Y5s8Itq/4hoALhwALhwALdwALZwALVwFbRxPbNxWLFxcK9xhK1xlqtxqKhxuqZxy6Rw3aFv755u/5tsAMl0AMl0AMl0AMh0AMd0DsZ0OMR1VsN1bcF1gr91lL11prt1uLl0yrZ03LRz77Fx/65vANt3ANt3ANp4ANp4ANl4Adh4MdZ4UtV4adN4ftF4kdB4pM54t8x4ycl328d27sR1/8JyAO17AO17AO17AOx7AOt7AOp7J+l7Suh7Y+d7eeV7juN7oeF7tN97x9162tt57dh4/9Z1AP99AP99AP99AP99AP59AP19G/x9P/t+XPp+dPh+ifd+nvV9svN9xfF82e977Ox5/up2AP+AAP+AAP+AAP+AB/+AFP+AOP+AUv+AZ/9/e/9/jv9/of9+tP9+xv992P976/95/P11AABTAwBTCgBUFABUJgBUPABVUQBVZABVdgBViABUmwBUrQBTvQBSzQBR3gBQ7wBN/wBKAANZAwJZCQJZFAFZJgBaPABaUQBaYwBadQBaiABamwBZrABZvQBYzABX3QBW7wBU/wBSAgpcBApcCQlcFQddJwVdPQJdUgFeZABedgBeiABdmwBdrABdvQBczABb3QBa7wBZ/wBWBBhgBxdgCxZgFRVgKRFhPw5hUwphZQdhdwRhiQJhnAFhrQBhvQBgzQBf3gBe7wBd/wBbCC5jCy5kEC1kGitkKihkQCVlVCJlZh5ldxtlihdlnBRlrg9lvgxkzgdk3gRj8AFh/wBfB0ZnCkZnEEVnGENoJ0BoPj5oUztpZThpdzVpijJpnS5pritpvidoziNo3x9n8Bpm/xVkAVtrAltrBVprDFhrIFZsPFNsUVFsZE5td0ttikhtnUVtrkJtvj9szjts3zhr8TRq/y9oAG5vAG1vAGxvA2tvIGlwOWdwT2VwYmJwdmBxiV1xnFpxrVdxvlRwzlFw305v8Upu/0ZsAIFzAIFzAIBzA39zE31zNHt0THl0YHd0dXR0iXJ1m291rGx0vWp0zWd032Rz8WBy/11wAJV3AJR3AJR3AJN3EpF3K5B4Ro54XYx4cop4h4d4moV4q4J4vIB4zH143np38HZ2/3N0AKd7AKd7AKZ7AKV7AKR7I6N8QaF8Wp98cZ18hZp8mJh8qpZ8u5R8zJF83o578It6/4h4ALh/ALh/ALd/ALd/ALZ/ErR/PLOAWLGAb6+AhK2AlquAqKiAuqaAy6R/3aF/8J59/5t8AMqCAMmDAMmDAMiDAMeDDMaDN8WDVcODbcGEgb+ElL2EpruEubmDyraD3bSC77GB/65/ANuGANuGANqGANqGANmGAdiGMNaHUdWHadOHftKHkdCHpM6Ht8yHycqG3MeG78SE/8KCAO6JAO6JAO2JAO2JAOyJAOuJJeqJSeiKY+eKeeWKjeSKoeKKtOCJx92J29uI7tmH/9aFAP+LAP+LAP+LAP+LAP+LAP6MGP2MPvyMW/qMc/mMifeMnvWMsvOMxfGL2e+K7O2J/uqGAP+OAP+OAP+OAP+OBv+OFP+OOP+OUf+OZ/+Oe/+Ojv+Oof+NtP+Nxv+M2f+L6/+J/f2GAABfAwBgCQBgFABgJQBhPABhUQBhZABhdgBhiABhmwBhrQBhvQBgzQBf3gBe8ABd/wBaAANlAwJlCQJmFAFmJQBmOwBnUABnYwBndQBniABnmwBnrABnvQBmzQBm3gBl7wBj/wBhAgppBAlpCQhpFAZqJgRqPQJqUQFrZABrdgBriABrmwBrrQBrvQBqzQBq3gBp7wBn/wBmBBdtBhZtCxVtFRNtKBBuPg1uUgluZQZvdwRviQJvnABvrQBvvgBuzQBu3gBt7wBs/wBqBy1xCixxDyxxGSpxKSdyPyNyUyByZh1zdxpzihZznRJzrg5zvgpzzgZy3wNx8AFw/wBuCEV1CkV1D0R1F0J1J0B2Pj12Ujp3ZTd3dzR3ijB3nS13ril3vyZ3ziJ23x528Rl1/xNzAVt5Alp5BVl5DFd6H1V6O1J6UFB7ZE17dkt7ikd7nUR7rkF7vj57zjp73zd68TN5/y53AG59AG19AGx9Amt+Hml+OGd+TmR/YmJ/dl9/iVx/nFl/rVd/vlR/zlF/301+8Up9/0V7AIGBAIGBAICBAn6CEn2CM3uCS3mDYHeDdHSDiXGDm2+DrWyDvWmDzmaD32OC8WCB/1yAAJWFAJSFAJSFAJOGEJGGKpCGRY6GXIyHcomHh4eHmoSHq4KHvH+HzXyH33mG8XaF/3KEAKeJAKeJAKaJAKWJAKSJIaOKQKGKWZ+KcZ2KhZqLmJiLqpaLu5OLzJGK3o6K8YuJ/4eHALiNALiNALiNALeNALaNELSNO7ONV7GOb6+OhK2OlquOqKiOuqaOy6OO3qGN8J6N/5uLAMqQAMqQAMmQAMmQAMiQCsaRNsWRVcORbMGRgb+RlL2RpruRubmRyraR3bSR8LGQ/66OANuTANuTANuTANqTANmTAdiULteUUNWUaNSUftKUkdCUpM6Ut8yUycqU3MeU78WT/8KRAO6WAO6WAO6WAO2WAOyWAOuWIuqWSOmWYueXeeaXjeSXoeKXtOCXx96X29uW7tmV/9aTAP+YAP+YAP+YAP+YAP+YAP6YFf2ZPfyZWvuZc/mZiPiZnvaZsvSZxvKZ2e+Y7e2X/uuVAP+bAP+bAP+bAP+bBf+bE/+bN/+bUf+bZ/+be/+bjv+bof+btP+bx/+a2f+Z7P+Y/f6VAABsAwBtCQBtEwBtJABuOwBuUABvYwBvdgBviABvmwBvrQBvvgBuzQBu3gBt8ABs/wBqAAJyAgJzCAFzEwF0IwB0OgB0TwB1YwB1dQB1iAB1mwB1rAB1vQB1zQB03gB08ABy/wBxAgl2BAh3CAd3EwZ3JAR4OwJ4UAF5YwB5dQB5iAB5mwB5rQB5vQB5zQB43gB48AB3/wB1BBZ7BhV7CxR7FBJ8Jw98PQt8Ugh9ZAV9dgN9iQF9nAB9rQB9vgB9zQB93gB88AB7/wB5Byt/CSt/Dip/GCiAJyWAPiKAUx6BZRuBdxiBihSCnRCCrgyCvgiBzgSB3wKA8QB//wB+B0SDCUSDDkODFkGEJj6EPTyEUjmFZTWFdzKFii+GnSuGriiGvySFziCF4ByF8ReE/xGCAVqHAlmHBViHDFeIHVSIOlKIUE+JY02JdkqJikeKnUOKrkCKvz2KzzmJ4DaJ8TGI/y2HAG2LAG2LAGyLAGqMHGiMN2aMTmSNYmGNdl+NiVyNnFmNrlaOvlONzlCN4EyN8kmM/0WLAIGPAICPAICPAn6PEn2QMXuQSnmQX3aQdHSRiHGRm26RrWyRvmmRzmaR4GKQ8l+Q/1uPAJWSAJSTAJSTAJKTDZGTKI+TRI6UXIyUcomUh4eUmoSUq4KVvH+VzXyU33mU8XaT/3KSAKeWAKeWAKaWAKWWAKSXH6KXP6GXWZ+XcJyXhZqYmJiYqpaYu5OYzJGY346X8YqX/4eWALiZALiZALiZALeZALaaDbSaOrOaV7Gabq+bg62blqubqKibuqabzKOb3qGb8Z6a/5uZAMqcAMqdAMmdAMmdAMidCcadNMWdVMOebMGegb+elL2eprueubmey7ae3rSe8LGd/66cANygANugANugANqgANmgAdigK9egT9WhaNShfdKhkdChpM6ht8yhycqh3ceh8MWg/8KfAO+jAO6jAO6jAO2jAO2jAOyjH+qjRumjYeekeOakjeSkoeKktOCkyN6k29yk7tmj/9aiAP+lAP+lAP+lAP+lAP+lAP+mEf2mOvymWfumcvqmiPinnfansvSnxvKm2fCm7e2l/uukAP+oAP+oAP+oAP+oBP+oEv+oNf+pUP+pZv+pev+pjv+pof+ptf+ox/+o2v+n7P+m/v6kAAB6AwB7CQB7EgB7IwB8OgB8TwB9YwB9dQB9iAB9mwB9rQB+vgB9zgB93wB88AB7/wB5AAKBAgKBCAGBEgGCIgCCOQCDTwCDYgCDdQCEhwCEmwCErQCEvQCEzQCD3gCD8ACC/wCAAQiFAwiFCAeFEgWGIwOGOgGGTwCHYwCHdQCHiACImwCIrQCIvQCIzQCH3gCH8ACG/wCEAxSJBRSJCROJExGJJQ6KPAqKUQeLZASLdgKLiQGLnACMrQCMvgCLzgCL3wCL8ACK/wCIBimNCCmNDSiNFiaNJiOOPSCOUh2PZRmPdxaPihKPnQ2PrgmQvwaPzgOP3wGP8QCO/wCNBkORCEKRDUGRFECRJT2SPDqSUTeSZDSTdzGTii2TnSmTriaTvyKTzx6T4BqT8hWS/w+RAVmUAlmUBFiVDFaVG1OVOVGWT06WY0uWdkmXikWXnUKXrj+XvzyXzziX4DSX8jCW/yuVAG2YAGyYAGuYAGqYGmiYNWaZTWOZYWGZdV6aiVuanFiarlWav1Kaz0+a4Eya8kiZ/0SYAIGbAICbAH+bAX6cEHycL3qcSXidX3addHOdiHCdm26erWuevmiezmWe4GKd8l6d/1ucAJWfAJSfAJOfAJKfCpGfJ4+gQ42gW4ugcomgh4ahmoShq4GhvX6hzXyh33ih8nWg/3GgAKeiAKeiAKaiAKWjAKSjHaKjPaGjWJ+kcJykhZqkmJikqpWku5OlzZCk342k8Yqk/4ejALimALimALimALemALamCLSmOLOnVrGnbq+ng62nlqqoqKiouqaozKOo3qGo8Z6n/5qmAMqpAMqpAMmpAMmpAMiqB8eqMcWqUsOqa8GrgL+rlL2rprurubmry7ar3rSr8bGr/66qANysANysANutANutANqtANmtKNetTdatZ9SufdKukdCupM6ut8yuysqu3ceu8MWu/8KtAO+wAO+wAO6wAO6wAO2wAOywG+uwROmxYOixd+axjOSxoeKxtOCyyN6y29yx79mx/9awAP+zAP+zAP+zAP+zAP+zAP+zDP6zOP2zWPu0cfq0h/i0nfa0svW0xvK02vC07e60/+uyAP+2AP+2AP+2AP+2Av+2Ef+2M/+2T/+2Zf+3ev+3jv+3of+3tf+3x/+22v+27f+1/v6zAACIAgCIBwCJEQCJIQCKOACKTgCLYgCLdQCLiACMmwCMrQCMvgCLzgCL3wCL8QCK/wCJAAKOAgKOBwGPEAGPIACPNwCQTgCQYQCRdACRhwCRmwCRrQCRvQCRzQCR3gCQ8ACQ/wCPAQeSAweSBwaSEQWTIQOTOAGTTgCUYgCUdACUhwCVmwCVrQCVvQCVzQCV3gCU8ACT/wCTAxOVBRKWCRGWEQ+WIw2XOgmXUAaXYwOYdQGYiACYmwCYrQCYvgCYzgCY3wCY8QCX/wCWBieZByaZDCaZFCSaJCGaPB6bURqbZBabdhOciQ+cnAucrgecvwSczgKc4ACc8QCb/wCaBkGdB0GdC0CdEz6dJDueOjieUDWfZDKfdi+fiiufnSigriSgvyCgzxyg4Bef8hKf/wyeAVigAlihBVehC1WhGVKhN1CiTk2iYkqidkejiUSjnUGjrj2jvzqjzzaj4DKj8i6j/ymiAG2kAGykAGukAGmlFmelM2WlTGKmYWCmdV2miVqmnFenrlSnv1Gnz06n4Eqn8kem/0KmAICoAICoAH+oAX2oD3yoLHqpSHepXnWpc3KqiHCqm22qrWqqvmeqzmSq4GGq8l2q/1mpAJSrAJSrAJOrAJKrB5CsJY+sQo2sWoutcYithoatmYOuq4CuvX6uznuu4Hiu8nSt/3CtAKevAKevAKavAKWvAKSvGaKvPKCwV56wb5ywhJmxmJexqpWxu5KxzZCx342x8omx/4awALiyALiyALiyALezALazBbSzNbOzVLG0ba+0gqy0lqq1qKi1uqW1zKO136C18p21/5q0AMq2AMq2AMq2AMm2AMi2Bse3LsW3UcO3asG3gL+4lL24pru4ubm4y7a53rO48bC4/664ANy5ANy5ANu6ANu6ANq6ANm6I9e6S9a7ZdS7fNK7kNC8o868t8y8ysq83ce88MW8/8K7AO+9AO+9AO+9AO69AO29AOy+Fuu+Qem+Xui+dua/jOW/oOO/tOC/yN6/3Ny/79m//9a+AP/AAP/AAP/AAP/AAP/BAP/BCf7BNP3BVvzCb/rChvnCnPfCsfXDxvPD2vDD7u7C/+vBAP/EAP/EAP/EAP/EAP/EDv/EL//ETf/FZP/Fef/Fjf/Fof/Ftf/Fx//F2v/F7f/E/v/DAACVAgCVBwCWDwCWHwCXNgCXTQCXYQCYdACYhwCYmwCYrQCZvgCYzgCY3wCY8QCX/wCWAAGaAQGbBgGbDwCcHgCcNQCdTACdYQCdcwCehwCemgCerACevQCezQCe3wCe8QCd/wCcAQaeAgaeBgWfDwSfHwKfNwGgTQCgYQChdAChhwChmgChrACivQCizQCh3wCh8QCh/wCgAhGiBBCiBw+iEA6jIQujOAejTgSkYgKkdQGkiAClmwClrQClvgClzgCl3wCl8QCk/wCkBSSlBiSmCyOmEyGmIh6nOhunUBenYxOodhCoiQyonAeorgSpvgKpzgGp4ACp8gCo/wCnBT+pBj+pCj6pETyqIzmqOTaqTzOrYzCrdiysiSmsnCWsriGsvx2szxms4BSs8g+s/wmrAVetAlatBVWtClStGVGuNU6uTUuuYkivdUWviUKvnD+wrjuwvziwzzSw4TCw8yyw/yavAGywAGuwAGqxAGixEWaxMWSxSmGyYF+ydFyziFmznFazrlOzv1C0z0y04Um080Wz/0GzAIC0AH+0AH60AH20Dnu1KXm1R3e1XXS2c3K2h2+2m2y3rWm3vma3z2O34V+381y3/1i3AJS4AJO4AJO4AJG4ApC4Io65QIy5WYq5cIe6hoW6mYK6q4C7vX27znq74He783O7/2+6AKe7AKa7AKa8AKW8AKO8E6K8OaC9VZ69bpu9hJm+l5e+qZS+u5K+zY+/34y/8om//4W+ALi/ALi/ALe/ALfAALXAArTAMrLAUrDBbK7BgqzBlarCqKfCuqXCzKLC36DC8p3C/5nCAMrDAMrDAMnDAMnDAMjEBMbEKsXETsPEacHFf7/Fk73FprvGubjGy7bG3rPG8rDG/63GANzHANzHANzHANvHANrHANnHHNfISNbIZNTIe9LJj9DJo87JtszKysrK3cfK8cTK/8HJAPDKAO/KAO/KAO7KAO7LAOzLD+vLPurLXOjMdebMi+XMn+PNtOHNyN7N3NzN79nN/9bMAP/OAP/OAP/OAP/OAP/OAP/OBv/PLv3PU/zPbvvPhfnQm/fQsfXQxvPR2vHR7u7Q/+zPAP/SAP/SAP/SAP/SAP/SDP/SKf/SSv/TYv/TeP/TjP/ToP/TtP/Tx//T2//T7v/T///SAAChAQCiBQCiDgCiHQCjNACjSwCkYACkdACkhwClmwClrQClvgClzgCl3wCl8QCk/wCkAAGnAQGnBQCnDQCoHACoMwCpSgCpXwCqcwCqhgCqmgCqrACrvQCrzQCr3wCr8QCq/wCpAQWqAgWqBQSrDgOrHAKsNAGsSwCsYACtcwCthgCumgCurACuvQCuzQCu3wCu8QCu/wCtAg+uAw6uBg2uDgyvHgqvNgawTAOwYQGwdACxhwCxmgCxrQCxvgCyzgCy3wCy8QCx/wCxBCGyBSCyCR+yEB6yHxyzOBizThS0YhC0dQy0iAi1nAW1rQK1vgG1zgC14AC18gC1/wC1BDy1BTy1CDu2EDq2ITe2NzO3TTC3Yi24dSm4iSW4nCG5rh25vxq5zxW54RC58wu5/wW4AlW5A1S5BFS5CFK6GE+6Mky6S0m7YUa7dUO8iEC8nDy8rjm9vzW9zzK94S298ym9/yO8AGu9AGq9AGm9AGe9CWW+LmO+SGC+X12/c1q/iFfAm1TArVHAv07Bz0vB4UfB80PB/z/AAH/BAH/BAH3BAHzBDHrBJXjCRHXCXHPDcnDDh23DmmrErGjEvmXEz2HF4V7F81rF/1bEAJPEAJPFAJLFAJHFAI/FH43GPovGWInGb4fHhYTHmYHHq37IvXzIznnI4HXI83LI/27IAKbIAKbJAKXJAKTJAKPJDKHJNp/KVJ3KbJvLg5jLl5bLqZPMu5HMzY7M4IvM84jM/4TMALjMALjNALfNALbNALXNAbTNLrLOULDOaq7OgavPlanPp6fQuqTQzKLQ35/Q8pzQ/5jQAMrQAMrQAMnQAMnQAMjRA8bRI8XRS8PSZ8HSfr/SkrzTpbrTuLjTy7XU3rLU8q/U/6zUANzUANzUANzUANvUANrVANnVEdfVRNbVYdTWedLWjtDXos7XtszXysnY3cfY8cTY/8HXAPDYAPDYAO/YAO/YAO7YAO3ZB+vZOOrZWejac+baieXan+Pbs+Dbx97b3Nzc8Nnc/9bbAP/cAP/cAP/cAP/cAP/cAP/cAv/dJf7dT/zda/veg/nemvfesPXfxfPf2vHf7u7f/+zfAP/gAP/gAP/gAP/gAP/gB//hHv/hRf/hX//hdf/ii//in//is//ix//j2//j7v/i///iAACtAQCuBACuDACvGgCvMQCwSQCwXwCxcwCxhgCxmgCxrACyvgCyzgCy3wCy8gCx/wCxAAGzAQCzBAC0DAC0GQC1MAC1SAC1XgC2cgC2hQC3mQC3rAC3vQC3zQC33wC38QC3/wC3AAS2AQS3BAO3DAK3GQG4MQC4SAC5XgC5cgC6hQC6mQC6rAC7vQC7zQC73wC78QC7/wC6AQ26Agy6BQu7DAq7Gwi7MwS8SgK8XwG9cwC9hgC+mgC+rAC+vQC+zgC/3wC/8QC+/wC+Ax2+BB2+Bxy+Dhq/HBi/NRTATBDAYQzBdAjBhwXBmwLCrQHCvgDCzgDC4ADC8gDC/wDCAznCBDnCBzjCDjbDHzTDNDDDSyzEYSnEdCXFiCHFnB3FrhnGvxXGzxDG4QvG8wbG/wLGAlLGAlLGA1HGB1DGF03HL0rHSUfIYEPIdEDIiD3JmznJrjbKvzLKzy7K4SrK8yXK/x/KAGnKAGnKAGjKAGbKAmTLKmHLRl7LXVvMcljMh1XNm1LNrU/OvkzOz0jO4UXO80HO/zzOAH7OAH3OAHzOAHvOCHnPIXfPQnTPWnHQcG/QhmzRmmnRrGbRvmPSz1/S4VzS81jS/1TSAJPSAJLSAJHSAJDSAI7SGYzTO4rTVojUbYXUhILVmIDVqn3VvHrWznfW4HPW83DW/2zWAKbVAKbVAKXWAKTWAKLWBKDWMp7XUZzXaprYgZfYlpXYqZLZu5DZzY3a4Ira84ba/4LaALjZALjaALfaALbaALXaALPaKLHbTK/baK3cf6vclKjcp6bduaPdzKDe357e8pve/5feAMreAMreAMneAMjeAMfeAcbeGsTfR8LfZMDgfL7gkbzgpLnhuLfhy7Ti3rHi8q7i/6viANziANziANziANviANriANniBtfjP9XjXtTkd9LkjdDkoc7ltcvlycnm3cbm8cPm/8DmAPDmAPDmAO/mAO/mAO7mAO3mAOvnMOrnVejocOboiOToneLpsuDpx97q29vq8Njq/9bqAP/qAP/qAP/qAP/qAP/qAP/qAP/rGP7rSf3rZ/vsgfnsmPftrvXtxPPt2fHu7u7u/+vuAP/uAP/uAP/uAP/uAP/vAP/vEv/vPP/vWf/wcv/wiP/wnf/xsv/xxv/x2v/y7v/y///xAAC5AAC6AwC6CgC7GAC7LgC8RwC8XQC9cQC9hQC+mQC+rAC+vQC+zgC/4AC/8gC+/wC+AAC/AQDABADACgDAFgDBLADBRQDCXADCcADDhADDmADEqwDEvQDEzQDE3wDF8QDF/wDEAAPDAQPDAwLECgLEFwHFLQDFRQDGXADGcADGhADHmADHqwDIvQDIzQDI3wDI8QDI/wDIAQrHAgrHBAnHCgjIGAbILgPJRwHJXQDKcQDKhQDKmQDLqwDLvQDMzQDM3wDM8QDM/wDMAhnLAxnLBhjLDBfMGRTMMRDMSQzNXgjNcgXOhgPOmgHPrADPvQDPzgDQ4ADQ8gDQ/wDQAjTPBDTPBjPPDjLQHC/QMCzQSSjRXyTRcyDShxzSmxfTrRPTvg/TzwrU4AXU8wLU/wDUAU/TAk/TA07TB03TFkrUK0fURkPVXkDVcjzWhjnWmzXXrTHXvi7XzynY4SXY8yDY/xrYAGfXAGfXAGbXAGTXAmLYJF/YQ1zZW1nZcVbahlPamk/brEzbvknbz0Xc4UHc9D3c/zjcAH3bAHzbAHvbAHrbBHfcHXXcPnLdWG/db23ehGremWbfq2PfvWDfzl3g4Vng9FXg/1HgAJLfAJHfAJDfAI/fAI3fDYvgNojgU4bha4PhgoDil33iqnvjvHjjzXTj4HHk823k/2nkAKXjAKXjAKTjAKPjAKHjAp/kLZ3kTpvlaJjlgJbmlZPmqJHnuo7nzIvn4Ijo84To/4DoALfnALfnALbnALXnALTnALLoHrDoSK7pZazpfanqkqfqpqTruaLry5/r35zs85ns/5XsAMrrAMnrAMnrAMjrAMfsAMXsEMPsQcHtYL/teb3uj7vuo7jvt7bvyrPv3rDw8q3w/6rwANzvANzvANvvANrvANnwANjwAdfwNdXxWdPxdNHyi8/yn83ytMrzyMjz3cX08cL0/7/1APDzAPDzAO/zAO/zAO70AO30AOv0I+n1T+j1bOb1hOT2m+L2sN/3xt3329r48Nf4/9T5AP/3AP/3AP/3AP/3AP/3AP/4AP/4Cv74Pv35Yfv5fPn6lff6rPX7wvP72PD87u78/+v8AP/7AP/7AP/8AP/8AP/8AP/8Bv/8KP/8T//9av/9gv/9mP/+rv/+w///2P//7f//////\",everyday400:\"AAoJAwoJDgwKGw4JKg4IPA4IUwoHbQIEiQADowAAvQAA0gAA4wAA8gAA/xgA/ysA/z4AAA0KAw8KDhIJGxMJKxMIPRMHVBEGbgoEiQACowAAvQAA0AAA4gAA8Q8A/yEA/zAA/0EAABUMABYLCRkJHR0ILRsGQBsGVxoEcBcDihIApg0AvgsA0RAA4hcA8SEA/y4A/zkA/0gAACAPACAPBCMNFygJMSwDRSoDWScCcyYAkCUAqiYAwCcA0SkA4i0A8TQA/jwA/0UA/1IAAC0SAC0TAS4TDzMPJzoHS0QAZUIAfD0AkzoAqjsAvzwA0T0A4UEA70UA/UsA/1IA/1wAADwXAD4XAD4XCEIVIEwOQFYAcGcAiGIAnFoArFIAvlAAz1EA31MA7lcA/FsA/2AA/2gAAFEbAFYdAFYeAFcdGl4XN2gKXHMAjIIApH8AtHYAwm0AzmUA3mYA7GgA+2sA/28A/3YAAGgiAG0kAGskAGskFm8hMngZUYEIdosAoJYAuZYAx44A04UA330A6nkA+XsA/34A/4MAAH4sAIAtAH8tAH8uG4AuMoYpTY0hbJYSjZ4AsacAy6oA16IA4psA7ZMA+I0A/40A/5EAAI01AJE4AJE5C5A5JZA6OZQ4TpozZ6Asg6cioa4Mv7UA2roA5bQA8K0A+qgA/6IA/58AAJ5DBKFGFqFHJqFHNKBHQ6BIVKVFaKtBf7E8mLc0s70qzcMX58oA8cQA+78A/7oA/7UAKK9VMbBWNrBWPbBXR69XUq5YX7JYb7ZVgrxTlsBPrcZLxMtE2c878dYx+tIf/80D/8kASr9nTb9oUL9pVr9pXL5qZL5qbb5recJpiMZpmctnq89kvtNh0ddc49pW+OBS/91I/9k8Z8x8ac19a819bsx9c8x9ecx9gMx+ic5+lNF+odR9r9d8vtt7zd543OF17ORy/elv/+dqhNqShtuTh9qSidqTjNmTkdmTltmVnNqVo9uVrd6Vt+GUwuSUzuaS2eiR5uuP8uyM/++KoeappOerpOarpuerqOarquWrruass+atuOeuveitw+qty+yt0u2r2/Cr5fGq7vKn+PSlvfDBvvHCvvDCv/HCwPDCw/DDxfDEyPDFy/DGzvHF0vLF1vTF3PXF4PbD5/fD7fjC9PnBAQsNBAsNCwsNGgsNKQ4OOw4OUwsObQIMiAAKowAIvAADzwAA3wAA7wAA/RYA/ycA/zgAAA4NBBAODhEOGhIOKhMOPBMNUxEMbQwLhwEJowAGuwABzwAA3wAA7w4A/R8A/y4A/z0AABcQAxgQCxoPHBsNLRsNQBwNVxsMcRcKixMHpg0DvQwA0A8A4RgA7yEA/SwA/zgA/0QAACITAiMUByMTGCcQMCsMRCkKWicIdCcGkSYDqSYAvycA0CgA4S0A8DMA/TsA/0QA/08AAC8XAC8YBi8XEzMVKToQSkMEZEEBezsAlDoAqzsAvzwA0D4A4EAA70UA/UsA/1IA/1sAAD4bAEAcAUAcD0MbI0wWQVYKcGYAh2AAm1kAq1AAvlAAz1EA31MA7lYA/FsA/2AA/2cAAFMgAFgiAFgiC1ciH14eOmgVXXMAjIIAo30As3QAwGwAzWMA3mYA7GgA+msA/28A/3YAAGkmAG0oAG0pAmwpHG8nNXghU4EWeIsAoZYAuZYAxo0A0oQA3nwA63kA+XsA/34A/4MAAH8wAIEyAIEyA4AyIYAzNocvUI4obZYdjp4FsacAyqkA1qEA4pkA7ZMA+I0A/4wA/5AAAI45AJM+AJI9FpE9KpE+PJQ9UZo5aaEzhKgqoq8cv7UA2boA5LMA760A+qgA/6IA/54AAJ9HE6JKHqJLLKJLOaFMRqBMVqZKaqxGgLFCmbc7s70yzcIk58oN8cQA+74A/7kA/7UALrBYNrJbO7FbQrFbS7BbVbBbYbFbcLZZg7xXl8FUrcZQxMtK2tBC8dc6+tIq/80T/8kATL9qUcBsVMBsWL9sX79sZr5tb75ue8JticZsmcpqrM9ov9Nl0ddg5Npb+OBX/91N/9lBac1+a81/bc1/cc1/dcx/e8yAgcyAis6BldGBodR/r9d/vtt9zd573OF47ON0/ely/+ZuhdmTh9qUiNqUi9qVjtqVk9qWmNqXndqXpNyXrt6WuOGWw+SWzuaU2uiT5uqR8uyO/++No+arpeespeaspuasqeasrOatsOaus+avuOevvuivxOquy+yt0+6t3PCs5PGq7fKo9/OmvfDCvvDCvvDCwPDDwvHDw/DExvHFyPDFy/DGzvHG0vLG1/TG3PXF4PbE5/fE7fjD9PnBAgsUBgsUDAwUFw0UKA0VOwoUUwgVbgUXiQAVpAAUvAARzwAO3wAK7wEF/RkA/yoA/zsAAA8VBBAVDBIVGRMWKhIWPRIWVRMXbg0WiQIVpAATuwAQzgAN3wAI7xEC/CAA/y8A/z8AABgVAhkXDRoXHBsXLRwXQRwXWBsWchkVjRMTqBASvQ4OzxIK4BkF7yMA/S0A/zkA/0YAASQaByUbDyUbGygZMSoWRCgVXCgUdycTkicQqiYNvicJ0CkE4S4A7zUA/j0A/0UA/1EAAzMfBDIeDzIfGDQeKzoaS0EUZD4QezoNlToJrDsFvzwA0D4A4EEA70YA/UsA/1IA/1wAAEEiAEMjCkQjGUUkKE0gRVcZcGQIhl0BmVUAq08AvlAAz1EA31MA7lcA+1sA/2EA/2gAAFcnAFspAFspFVkqJV8oPWgiX3MXjYEAonsAsnIAv2kAzWQA3mYA7WgA+2sA/28A/3UAAGwuAHAwAHAxEW8xJnAxOngsVoEleYsXopcAt5MAxYsA0YIA3XoA63gA+XsA/34A/4MAAIE4AIM5AIM6FYI6KYI7O4Y4Uo4zb5Yrj54fsqcDyacA1aAA4ZgA7JEA94sA/40A/5EAAJBBAJRED5RFIpNFMpNFQZNFVJpCa6A9hac2oq4twLUc2bkA5LIA76wA+aYA/6EA/54AEKBNIaNRKaNRM6JRP6JSS6FSWqZRbKtOgbFKmrdFtL0+zcM05skn8MMP+r4A/7gA/7UANbBdPLJgQLJfR7FfT7FgWbFhY7FgcrZfhLxdmMFbrsZXxMtS2tBM8NZG+tE4/80n/8kSUb9uVMBwWMBwXMBwYsBxab9xcr5yfMFxi8Zxm8pvrM5tv9Nq0ddn49pi+OBf/91W/9lLa8yAbs6Cb82Cc82Cd82DfMyChMyEi82EltGEotSDsNeCvtuBzd1/3OF96+N6/Oh4/+d0htqVidqWitqWjNuXkNqXlNqYmdqYntmZptyZrt6ZuOGYw+OXzuaX2uiW5uqU8uyR/++Qo+aspeatpuatp+atqeatreausOautOavueewvuiwxOqwy+yv0+6v2++t5PGs7fKq9/OovvHDv/HDv/DDwPHEwvDEw/DExfDEyfDGzPDHzvHG0/PH1/TH3PXG4fbG5vbE7fjE9PjCAgwfBgwfDw0eGQ8eJg8eOQ8gUwghbwAgigAfpwAjvQAizwAh4AAe7wwc/R8Z/y4X/z4XABAfBBEgEBMgGhQgJxUgPBUhVQ8hcAEfjAAhpgAjvgAizwAg4Age7xgb/SUY/zIV/0IWABkiABkiDxwjHB0iKx4jQRwjWhkicxokkRgkqRQjvxQh0Rgf4R8c8Cga/jEX/zsU/0kUACYiAScjDyckHiklMSokRiokXiojeiojlSkjrCkhwCoe0Swc4TEa8DcX/j8U/0gQ/1MRAjQmCzUnFzYoIDYpLzsnTD4jZDshfzwglzwfrT0cwD4a0UAY4UMU8EgR/U4N/1QJ/14LBEUtEEkvFkovIkovL04uSVgqb2AjhlodmFEYrVEVv1ES0FMP4FUK71gG+1wB/2EA/2oAAFw0AWA2EF81IV82L2A2QmkyY3MsjX8foHgWsG8LvmUEz2UA32cA7WkA+20A/3AA/3cAAHA5AHQ9DHQ8IHM9MHI9QXg7WoI3e4ovpJchtpESxIgB0IAA3HgA7HoA+XwA/38A/4QAAIVEAYdGFIZGJYZGNYVGQ4ZFV45CcpY9kJ41s6cpyKYa1J4D4JYA7I8A94sA/40A/5EABJJLGpZPJJZPMJZQPZVQSpRQWZpOb6FLh6dGo65AwbU32Lgq47EX7qsA+aUA/58A/54AJqNXMKZbNqVbPqRbSKRcU6NcX6VbcKtZhLFWm7dStL1OzsNH5cg/78Mw+b0d/7cA/7QAP7JlRbRnSbNoT7JoVrJoX7JpabFpdrZoh7xnmsFlrsZjxMtf2s9a8NVW+dFK/8w7/8gtWMB1XMF3XsF3YsB3aMB3bsB4dr94gMF4jcV3nMp2rc51v9Nz0tZx5Npt9+Br/9xh/9lXb82Gcs6HdM6Hd86He86HgM2IhsyIjs2Jl9CIpNSJsdeIv9uHzt6G3eGE6+OB/emB/+Z8itqZjNuajduaj9qaktubltqbm9qboNqcp9ydsN6dueGcw+Ocz+ab2+mb5+uZ8uyX//CXpeaup+ewqOevqeewq+ewruawseaxteayuuayv+izxeqyy+uy0+2x3O+x5PGv7vKu9/OsvvDDv/DEwPDEwfDFwvDFxPDGxvDGyvHHzPDIz/HI0/LI1/TI3PXI4vbI5/fG7vjG9PjEAAwuBgwtEA0sHRAsKREsOBIsUA8vbAQxigAxpwAvvgAs0AAw4As08Bwz/iky/zYx/0QzABEtBBMuERQuHRYtKxctOhcuURUwbQwxiwAxqAAvvgAu0AEz4Bg07yMz/S0x/zgw/0cyABkwARsxEBwxIB4wLh8wPiAxVh8zcxgzkggyqwExvxQ10SE14Scz8C8y/Tcx/0Ew/04yACYyACczByc0ICk0MSw0Qyw0Xys1fCc1lyo2rS83wC810TI04jYy8D0x/UQw/0wv/1cwADYyADczDTg0IDo1ND04TT44Zz84gUA3mUA2rkA0wEEy0UMx4Ucv8Esu/VAs/1cs/2EuAEg3C0w6G048LFA/OVFATVk+bls5g1MzmVMxrlMwwFMu0FUt4Fgr7lsq+18o/2Uo/2wrBV9BFmRFJGRGL2ZHOmVGSWlGZ3RCi3s7nnIyrmkrv2Yo0Gcm32kl7Wsk+24i/3Ii/3gmGXVMJXlQKHlPL3lNPHhNSnhNX4JKfotGpJU/tI00woQqz3sh3Xkc7Hsa+n0a/4Aa/4UfH4lUJItWK4tVNYpVQYlVTohVXo5TdZZQkp1MtahFxqM605su35Mh6owU+IwN/44J/5IPJJZZMJpdNppePpleSZheVJheYJldcqBbiadYpK5UwrVO1rZF4rA57akq+KMZ/50B/58CN6VkP6dnRKdnS6dnU6ZnXKVnZqVodKpmh7FknLditb1fzsNb5MdU7sFI+bw6/7Yp/7MaS7RvULVyU7VyWLRyX7RyZ7NzcLNze7Zzibtym8BxsMZwxcpt2s9q7tVn+NBb/8xP/8dCYMJ+Y8J/ZcJ/acJ/bsF/dMF/fMGAhMGAkMWAnsp/rs5/wNJ90tZ849p59uB4/9xv/9hlds6MeM+Oec+NfM6NgM6Ohc6Oi86Pks2PmtCPpdOPsteOwNqOzt6O3eGM7OSL/OmL/+eFjdudj9uekdufk9ufltufmdufndqgo9qgqduhsd6huuChxOOhz+ah2+ig5uqf8+2e//Cep+axqOeyquezq+ezreezr+azs+a0tua0u+e1wOi2xuq2zey11O613O+05fCz7vKy9/Owv/DFwPHGwPDGwvHHw/DGxfHIx/DHyvHJzfHJ0PHK0/LK2PPK3PTJ4fbJ5/bI7fjI9PnHAA0/AQ0/Dw4/HxA/LxM/PxRATxI/agxCiABHpQBHvABF0ABB4wA+8QBD/StJ/0BM/01OABM/ABNBEBVBIBZBMBlBQRpCUBhAaxVEiQpHpQBHvQBF0ABB4gBA8RVF/TZK/0NM/1BNABxEABxFDx1EIh9FMyFERCJFVSJEcSBIjhpKqQxJvwBG0gBC4xdF8DNK/UJN/0pM/1ZNACVGACZIBShJISpINS1IRy9IXTBKeTFNlCxNrSZKwiFG0i5J4T5N70ZN/UxM/1NL/15OADdIADhJADhKGDlMNz5OTkJPZURRgEJRmkBOr0JNwUlP0UxO4U9M71NL/FhK/11J/2ZLAExJAFBNAVFOIVRQOlZTUllVbVpUhVlSm1lQr1lOwFlM0VtL4F1J7mBI+2RG/2lG/3BJAGJPD2dUIWlVM2pXRmxaVWxbanNZiHRTm2xLr2tJwGpH0GtG32xE7W9D+nJD/3VC/3xGFnhZJXxdMH1eQH5hTX9iV31gZYFfgItdopFYsohOv39EzntA3nw/7H4++YA+/4M+/4hCM41lO49oQ49pTI9qUI9nW41nZo1meZZllJ1itqdfxKBU0ZhJ3ZA+6ow4+I43/483/5M6RZpuS55xTJ5wTp1uV51uYJtuaZpteKBsjKdrpa1oxLZm1LRd4K1R7KZF96A5/50y/6A0S6hzUKt1U6t1WKp1X6l1Zql1b6h1eqp1irB0n7Zztrxxz8Nw4sVp7b9d97pR/7RD/7A4WLZ8Xbh+X7d+ZLd+abd+cLZ/eLV+gLV/jbp/nsB/scV+xct92s977dR49s9t/8ph/8ZWacOHbMSJbsOIcsOJdsOJfMOJgsKJicKJk8SJocmKsM6JwdKJ0taI49qH9d+G/tt9/9h0fM+Uf9CWgM+Vg9CWhtCWi8+WkM+Wls+Xnc+WqNOXtNaXwdqXz96X3eGW7OSW++mW/+aQktujlNykldykl9ykmtylndulodulptulrNums92nvOCnxeKn0OWn2+in5+un8uym//Cmque1q+e2rOe2rue2sOe3sue3tee3uee4vOe4wee5x+m5zuy51e253e+55fG47vK39/O2wPDHwvHIwvHIw/HJxPDJxvHJyfHKy/HLzvDL0fHM1fLM2PPM3fXM4/bM6PfM7vjK9PjKAA5XAA9YCA9YHxBXMhJXRRVXWBRYahBXhgdcoQBeuABezQBd4ABa8QBX/wBU/yhZ/0piABRXABVZCRZZIRdZNBhYRxtYWRpYaxhYhxNdoQ9fuQJfzQBd3wBa8ABX/wJU/zNa/1FjAB1bAB5dCB5dIh9cNiFcSiRbXSVccCNdjCJgpCJhuxthzxVf4RJc8hZZ/ypZ/0Vf/11pACZdAChgASpgIStgOC1gTzJhZDRjdjRikTVkqDRkvTBi0S5g4y5d8jRb/Uhg/1ll/2dqADZhADZiADhkFjpmOj9mVERnaEhnfEhnlEloq0dnwEVk0kNh4klg71Zk+mFn/2Zm/25pAE1iAFFnAFJoDFNqMVRrVFlsa11sgF1smFxrrlpnwFtmz2No32Zo7Whm+mtk/29j/3dnAGVjAGtpAGtpIW1qPm9sVnFubnNwhXJumnFsrXFpv3Fnz3Jm3nNk7HVi+Xdh/3th/4FkDHpoIX9tL4FuP4FvUYJxY4N0b4N0g4pznYptrYJkvoBizoBg3YFf64Je+IRd/4Zd/4tgM49yO5F1RJJ2UJJ3XZJ5apN7cZF5fpV4lp13sqJ0wZtqzZJf245Z6o9Y95BY/5JY/5ZaSJx5UqB+WKB+YaGAaqGBbKB+dZ5+fp99j6Z9p618xbZ70bFx3qpn6qNb9Z1S/59S/6JVXquDZa2HaK2HbK6HbK2EcqyDequEgaqDj7CDobaDt7yC0cSC4MN7671w9rdl/7FZ/65RbLmMb7qOb7qNcLqLdLmLermLgbiLiLeLkrqLocCLs8WLxsqL29CL7NKH9s19/8hx/8RndcWTd8aTeMaTe8WTf8WThMWTisSUkMOTmMSTo8mUss2UwtKV09aV5NqU9N6T/dqK/9eBhNGdhtKdh9GeitGejdGekdCeltCem9Ceoc+eqtKftdafwtqg0N6g3eGg6+Og++ih/+Wbltypmd2rmt2rnN2rntyrodyrpdyrqdyrr9ustd2tveCtx+Kt0OWu2+iu5+qu8uyu//CvrOe5rue6r+i6sOi7sue6tOe6t+e7uue7vue8w+e9yOm9zuu91u2+3e+95vG97/K89/O7wvHKwvDKw/HLxPDLxfHLx/HMyvHMzPHNz/HN0vHO1fLP2fPP3vXP4vXO6PfP7vjO9fnNAA9xAA9yAA9xHRFyNRJyShNxXxdxdRRziQt0ngp0tQt0yRN23A917RN0/Bxx/ylw/zpwABZxABVyABZzHhdyNhhySxpxYB1xdhx0iRd0nhd0tRl1yR523Bx17R5z/CVx/y5v/z9wAB5zAB51AB92ISB1OCF1TiR1ZSh2eih4jCZ2oSd2typ4yy143Sx37S50/TNy/ztw/0tyACl2ACp4ACt4ICx4PC96VDJ7ajd7fjl7jjh5pDl6uT16zD563j547kB2/UN0/0lx/114ADZ6ADd8ADl9HT5+PUB+V0V/bkp+gU1+kUx8p059ulF9zVB831B57lF3/FN0/192/3B+AEx7AE+AAE+BAFCBM1OCV1mCcF6Cg2GBk2F/qGOAvGN/zmJ932F67mN4+Wx6/3d9/4CCAGZ7AGqAAGuBAmyCMm2CTm2Eb3KFhHaElneEq3aCvnWAz3V+3XqA6n6A94B+/4J9/4h/AHx7AIKAA4KAKoOBRISCW4aEcYeFhomHmoiFrIiDvYeBzYd/3Id96oh79op7/4x6/5F8LZKBOZSEQ5SEUJWFXpaGbZaIfJeKh5aKmJyKrpyFvJV8zJN525N46ZN29ZV2/5d1/5p2SZ6FVKOKWaOKYqOLbKOMeKSOg6SQiaKNk6WNqK2NwrKLz6yC26V556Bx9KBv/6Fv/6VyYK2NZ7CRa7CRcbCSebCTgrCVha+Si66Rk66RpLWSuLyS0sWT3sCL6bqA9LR1/61q/7Bsc7uXeLyZeryZf7yahbybhryZiruYkbqXl7mXpL+YtMWZx8qZ3NGa6tCV9MuL/saA/8F2hcehiMeiiceiisihisefjceekcael8aensWdp8ietM2fw9Kg09ah5duh892f/NmV/9aNkNKokdOoktOoktOnlNKml9KnnNKnoNGmptGmrdGnt9aow9qp0d6q3uGr7OSr+ueq/+Wknd6xn96yn96xod6xo92xpt2xqd2yrd2ystyyt9yzv9+zyOK00uW13Oi15+q28uy2/vC3sOi+sem/sui/s+i/tei/t+i/uujAvejAwOfAxefByejB0OvC1+3C3u/C5vDC7vLC9/PBxPHNxPHOxfHOxfHNx/HOyPHOy/HPzfHP0PHQ0/HR1vLS2vPS3vTS4/bS6PbR7vfR9fnRAA+JABCJABCJHBCJNxGJTxKJZhWJfByKkBmMohGMsheIxh6J2CqK6TGL+TeK/z+J/0yLABaHABaJABaJHheJOBeJTxmIZxyKfSOLkSGMohyLsiGIxieK2DGK6TeL+DuK/0OJ/1CLAB+KAB+MACCMISCLPCKMVCSNayiNgS+Oky6OpCuNtC+LyDaM2T6M6kGM+EWL/0yK/1eMACqLACyPAC2PJS6QQDCRWDORbziRgz6QlT+QpT6PtkGNyUeO2k2P6k+O+VKN/1eL/2KNADiRADyTAD6TJECTQkKUW0WTckqThlCSl1KSpVGPt1SPyVmQ2l2Q6l6P+GCN/2OM/2uNAEmQAE2VAE6VAU+VPlaWWlmVcl2Vh2SUmGaUpWaRuGmSyWyS2myR6myQ+G2O/3CM/3iOAGOQAGeUAGeVAGeVKmeWUWuXcXKXh3eWmHqWp3qUuXyVynyU23uS6nuQ+HuO/4KQ/46VAHyPAICUAICUFIGVOIKVUoKWaoOXh4iYmYuYqIyXu4uWzIqV24qS6I6T9JKU/5ST/5iUApKREpSTKJWTPJaUUJaVY5eWdpiXiZqYmpuaq5uYu5qWy5mU2ZmT55qR85uQ/5yP/5+PRKGST6WWV6WWYaWXbaaYeaaZhqebkqecmqacqqycvq2Yy6WQ2aSN56SM8qSK/qWK/6iLYq+ZabKbbbKcc7KcerKdhLKejrKgmLOhnbKfp7Wfuryg0MKg27yX5rSN8q+F/rCE/7KGdryger6ifb6jgr6jiL6kj76kl76mmr6koL2jqL6jtsSlyMqm3tKo6M6g8siX/MKM/72Dh8mpismpjMmqkMmqlMmrmsmsnMmqn8ippcioqseotsypxNGq1das5tyu8tup+teg/9OXl9OxmdSym9SyntSzoNSzodSxotSvp9OvrNKvsdKvudSwxdmx0d2z3+G07OS1+eaz/+OtqN67qd68qd67qd66qt+6qt64rt65st65tt25u925wN65yeK70+W83ei96Ou+8+y+/vC/tejEt+nGt+nFt+nFt+jEuunFvOjFwOjFw+jFx+jGy+jG0erH1+3H3u7I5/HI7/LI9/TIxfHQxvLRx/LRyPLRyPHRyvLSzPHSzvHS0fLT1PLU1/LU2/PV3/TV5PXV6ffW7/jV9fjVABCdABCdABCeIxCdPRCdVBGdbBSeghuflSaepiOetx+fwyea1jGb5j6d9Eue/1Kf/12gABabABedABedJBedPhidVhqebRyfgiOflSyepiuetyeewy+a1Tic5UOd806e/1Se/2ChACCdACCeBCGfKSKfQiOgWiWgcCmhhS+glzigqDeguDWgxTuc1kOd5k2e9Feg/1yg/2eiAC2gAC6jDi+jLjCjRjKjXTSjczijiD+imUehqUeiukaixkue11Kf5lqg9GGg/2Wg/2+jAD6lAD+lDEClL0KlSEOlX0aldUqkiVCkmlijqlmjuFiixl2g12Oh5mqi82yi/2+h/3eiAEmiAEymAE6mKVWmRlemX1qmdV2liWOkm2qkqmykt2uixm+i1nOj5Xej83ij/3uh/4GjAF6hAGKlAGKlAGSmNWamXG2mdHGminamnHylqn6ltn6jx4Ck1oSl5oWl84Wj/4ai/4ujAHihAHylAH2lAX2lMX2lTn2mbIGniIennIumq4+mt4+mx5Gm15Gm5pGl85Gj/5Gi/5ejAJGhAJOkDpOkLpOkRpSkW5Slb5Wmgpanm5qoq56ouZ6oyZ6o2Z2m552k8p+l/KOm/6amKqGgOaWjQ6WkT6WkXqakbaalfaemjainnKmorKuqvKupyqqn2Kqm5aqk8aqj/Kuh/66iXLGkY7OmaLOmcLSnebSohLWpj7WqmrWrpbasrbasvLyuzbyq2LWi5bOf8LOd/LSd/7adeL+qfMCsf8CshMCticCtkcCumcCvosGwq8Gxr8CvucOwycqy3M+y5sqq8MOh+76Y/7+ZicqxjMuyjsuykcuylsuynMuzosu0qsu1rcu0ssqzucuzxtG11da359258Nmy+dSp/8+gmdW4m9W5ndW5oNW5pNW6qNW6rda7r9W6stW5t9S5vNO4xti60t284OG+7ubA+OW8/+K2qd/BrODCreDCr+DCsd/DteDDtuDCt9/Bu9/Bv97Aw97AyuDC1OTD3ujF6OrG8+3H/e7Gu+nMvOnMvenMvunMv+nMwOnLwOnKw+nKxunKyenLzenL0unM2OzN4O/N5/DO7/LO+PTPyvLWy/LWy/LWy/LWy/LWzPLVzfHV0PLV0/LW1fLX2fLY3PLZ4PTZ5fXZ6vfZ7/fZ9fnZABGvABGvEhCvLhGvRhGwXRKwcxaxhx2wmiewqzOvujKvyjKv0zir40St8VGu/WCv/22yABetABivFhivMRiwSBmwXhqwcx6whySwmi2wqzqvujmvyTiv0z6r40ms8VWu/WKv/2+yACKwAiKyHyOyNiOyTCWyYSeydiuyiTCxnDmxrESxu0SwykOx1Ems5FOu8V2v/mqw/3WzAC6xDTC0JTG0OjK0TzS0ZDa0eDqzi0CznUiyrVKxvFKxylKy1Feu416v8Wmw/HOy/3y0AEC0DEG1JUK1O0O1UEW1ZUe0eky0jVGznlizrmKyvGKyymKy1Wav422w8HWx/Hyz/4O0AE2yAFK1H1S1OFa1T1i1ZFq0eV60jWO0nmqzrnKzvHOyyXKz1Haw4nyy74Ky+4a0/4y1AF2yAGC1AGK1GmO1SGq1Ym21eHG0jHW0nnu0roK0u4S0x4Oz1Iay4ouz7o+1+5C0/5W2AHOxAHe0AHe0AHe0Mnm0VHy0dYK1i4a1nou0rpC0u5O1xZOz1JW04pm175q1+5q0/521AI2xAI+yAI+yIo+zPZCzVI+zaZC0g5O1nJm1rp21u6G2xqG21KO24qS276O1+6O0/6WzD6GvKKOyNKOyQ6OyU6SyZKSzdaWzhaW0laa1raq3vK63yK+41q+45K628K20+rC1/7W3SrKxUrOyWLSyYLSza7Szd7WzhbW0k7a1obe2r7m4vbu6yrq417q347q17rm0+bqz/7yzccC0dsK1esG1f8G2h8K3kMK3msO4pMO5rsS6t8S8vsS8y8q+2sq748Oy7sGv+cGu/8Ovi826js27kM27k827mc28ns28pM28rM29tM6+vM7Av82+yNC/1tbB5trC7tW6+dCy/8yqm9a/ndfAn9fAodfBpdfBqtfCr9fCtdfDu9fEvtfCwtbCyNfC09zF4OHH7+fJ9+TD/+C9q+DHreDHruDIsOHIs+HJt+HJuuDJv+DKwuDJxODIyODIzd/I1eTK3ufM6evO9O7P/O7NvOnQvenQvurQv+rRwenRxOrSx+rSyerSyerQzOrR0OrR1OrR2uvS4e7T6PDU8PLU+fTVzPLazPLazfLazvLa0PLb0fLb0fLb0vLa1PLa1/La2vPb3vLc4fPd5fXd6vbd8Pjd9fjdDRLAHRLALRLAQBPBUxPBZxXBehrAjSHAnyu/rzi/vkW/zEW+2kW/4Uu671i8+2W9/3a/Cxm+IBnBMBrBQRvBVBzBZx7BeiHAjSjAnzG/rz2/vkq+y0m+2Uq/4U+671u7+2i8/3jAFiPAJyXDNSXCRSbCVyfCairCfC3BjzTBoDzAsEe/v1O/zFO/2VO/4Vi772K8+26+/37BHDHBLDPDODPDSDXDWTbDbDnDfj3CkELBokrBsVTAwF/AzV/A2V/A4WO8722++ne+/4XBIUPDLEPEOETDSUbDWkfDbUrCf07CkVPBolrBsmPBv23AzG3A2W3A4XG97ni++oG//43DDlHBJ1XDNVbDR1fDWVnDbFzCf2DCkWXComvBsnPBv3vAy3zA2HvB4H6+7YW/+IzB/5bDAF3AAGHDFWPDPmnDVmzDam7DfXLCkHbCoXvCsYLBv4nBy4rB1orB4I3A7ZLB95jC/5/EAHC/AHTCAHTBHHbCQHfCYX3CeoLCjobCoIvCsZDBv5bBy5jC1ZfB4JvB7J/C9qPD/6bEAIm/AIvAAIrAFIrANorBUYvBbY7BiZTCnpjCsJzCv6LCyqXD06TB4KfC66rE9qvD/63EAJ6+FKC/JqC/OaDASqDAXKDAbaDAfqDBlqPCrqnDvq7DyrHE1LLD4LPE67TF97XE/7bEPbG+RLK/S7K/VbK/YbO/brPAfLPAirTBmbTCqLXDvbnFy73G1b7G4r7G7b3E+L3D/8DEYsG/Z8HAa8LAccLAecLBg8LBjsPCmsPCpsTDs8XEwMfGzMnI18jG4sfF7cfE98fD/8jCg87Chs7Dic7Djc7Dk87Em8/Eo8/Frc/GttDHvtDIxtHJzNDJ19XL5NbJ7NDB9869/8++ntjHoNjIodjIpNjJp9nJrNjJsdnKt9nKvdnLxNnMytnNzdjL1dvN4eHQ7uXR9uDK/93DruHNr+LOsOLOsuLOtOHPuOLPvOLPwOLQxuLRy+LSzuLR0eHQ1+LQ4OfT6urV9e7X/OzTverVv+vWv+rVwOrWwurWxevWyOvXy+rXz+vY0uvY1OvX1+vX2+rX4e3Y6fDa8fLb+fTczPLdzfPezfLezvLe0PLe0vPf1PPf1vPg2fPg2fPe3PPf3/Pg4/Th5vTh6/fi8fji9vjiNRbQOxbPRBfPUhjPYRrPcRzPgiHOlCnOpTLNtT/Nw0zMz1jL21nM51vN7l/I+mvJ/3vMMhzNPB7PRR7PUh/PYiHPciPPgyjOlC/OpTjNtEPMwlDMz1zM21zM513M7WHI+W3J/3zLNifOPynQSSrQVSrQYyzPdC/PhTTPlTrOpkLOtUzNw1nNz2PM22TM52TM7WjJ+HPJ/4PMOTXPQjfRSzjRVjnQZTrQdT3PhkLPlkfPp0/PtVjNxGTNz23M223N5m7N7XLJ+HvK/4nNO0bQQkfRS0jQV0nQZkvQdk7QhlLPl1fPp17PtWbOw3DOz3nN2nnN5nnN7H3K+IXL/5HONFXOQFjQSVnQVlrQZVzQdV/QhmPPlmfPpm7OtXXOw33Oz4bN2obN5IXN64jK9o/L/5rOIGTONWnQRGrPUmzPYm7Pc3DPhHTPlXjPpn3OtYPOworOzpLN2ZLO45LO65XL9pvN/6PPAHDNAHPPGnTPN3bPVXvPboDPgYPOk4fOpIvOtJDOwZbOzp7O2J7O4p7O6qHN9aXO/63QAITMAIXNAIbNHofOQYjOXIrOdo7OjpTOoZjOsp3OwaLOzajO16rO4anO6qzO9LDP/rXRAJrLAZvMGJzML5zMQ5zMVZvMaJvNgZ7NnKTOr6jOwK3PzbPP17XP37XO6bjP87rQ/b7SMa/LOrDLQrDLTLDMWbDMZrDMdbDMhLDNk6/NqLLOvrjPzL3Q18DR38HQ6cLR9MTS/sXRV7/LXcHMYcHMZ8HMcMHMesHMhsHNksLNn8LOrMLOusPPy8fR18vS4MzS68zT9MvR/szRds3Mec7NfM7Ngc7NiM/Nj8/OmM/Oos/OrdDPuNDQw9LRztPS2NXU4dTT69TS9dTR/tXRlNjOltnPmNjPnNnPodnQp9rQrtrRttrSvtvTxtzUzdzV1NzV2NzW4uDX7OHV9dzP/9rNr+PUsePVsuPVtOPVtuPWuuPWvuPWw+TXyOTYzeTY0uTY1+TZ2uPY4ObZ6+vc9e7d/OrXv+vbwOvbwevbwuzbxOzcxuzcyevczezd0ezd1eze2ezf2+zd3uzd4u3e6e/f8fLg+vTizfPizvPhz/Pi0PTi0PPi0vPi1fTj1/Tj2vTk3fTl4PTl4fTk5PTk5/Tl7Pbm8vjn9/nnTR3cUh7cWB7cYiDcbyPcfifbjCzbnDPbqz3auUjZx1XZ02PZ3m3Y6G7Y8m/Y+HLV/4HWTCPbUyTbWSXcYyfcbynbfi3bjDHbnDnbq0HauUzZx1jZ02bY3W/X6HDX83LY+HTV/4LWTi7bVTDdWzDcZTLccjTcfzjcjjzbnULbrEvbulXax1/Z02zZ3XXY6HbY8nfZ93nV/4fWUDrbVz3cXT3cZ0Ddc0LcgETcj0ncnk/brFfaul/ax2nZ03XZ3n3Z537Y8n/Z94HV/43XUkvcV0zcXU3cZ0/cc1HcgFTcjljbnV3brGTaumzax3TZ037Z3YfZ54fZ8YfZ9orW/5TXTFnbVV3cW13bZV/ccmHcf2TbjmfbnGzaq3LaunnaxoDZ0onZ3JHY5pHZ75HZ9JPV/53YRmraUG3cWG7cYm/cb3HbfXPbjHfbnHvbqoDauIXZxo3a0pTZ3JzZ5JvY7pvZ9J7W/qbYHXLaM3bbQ3nbV3zbaYDaeYPbiYXamYjaqY3auJLZxZjZ0Z/Z26bZ5KbZ7aXZ86jX/a/ZAITZCIXaJYbaPIbaUYjaaYzag5LalZXappnatp7ZxKPZ0KnZ2q/a47Da7K/a8rLZ/LjaAJbYAJjZCZfZJ5bYQJfYWpjZcZrZiZ7ZoaTZs6jZwq3Zz7La2rna4rra6rra8rza+8HbJ6zXMqzYOq3YRazYUqzYYKvYb6vYfqrZla3ZrrPav7jazbza2cLa4sTb6MTa8sfb+srcT77XVb/YWb/XYL7Yab7Yc77Yf7/YjL7Zmb7Zpr3YuMDazMba2cvb4s7c6c/c8tDc+9Lebs3Xcc3YdM3Xec3Yf83Yh87Ykc7Ym87Yps7Zsc7ZvM7Zx8/a19Pc4tfd6tje8tje/NjeidnYjNrYjtnYktnYltnYndrZpNrZrNrZtdvavtvbx9zb0d3d2d7d4t/f69/e9N/e+9/dpuTbp+TbqeTbq+Tbr+TbtOTcueTcwOXdxuXezeXf1OXf2ubg4Ofh4+bh6+rj9Ovi/ObbwOzgwe3hwuzhw+zgxezhyO3hy+3izu3i0u3j1u3j2u3k3+7k4+7l5e3k6u/l8vLn+vXoz/Tmz/Tmz/Pm0fTn0vTm0/Pm1vTn2PTn2/To3fTo4fXp5PTp5vXp6vXq7fbq8vfr9/nsZSvoZyvnbSzndS/ofzLoizbnmDznpUPmskzmwFfmzGHk127k4Xrj6YLi84Tj/IXj/4niYi7maTLobjPodTXogDjoizvml0DmpUfmsk/lv1nly2Tk1nDk4Hzi6YTi8oXj+4bj/4rhZDjnajvobzzodj7ngUHojETnmEnmpk/ms1fmwGHmzGrk13bk4IHj6Ynj8onj+orj/4/iZkXna0jocEnod0rngU3njVDnmVXnplvms2Hlv2nlzHPk133k4Ijj6Y/j8pDj+5Hk/5TiaFTna1bocFfneFjnglvnjV7nmWLnpmfms23mv3Tly33l1obk34/j6Jbj8Jfj+pjk/5nhY2HmamXnb2Xod2bngGnni2vmmG/mpXPlsnnmv3/ly4fl1o/k35fj557j8J7j+Z/k/aHhYHDmZnPna3Tnc3XnfXfmiXrml33mpIHlsYblvovlypLk1Znk3qDj56fj76fj96bk/KnhVX7mXoHnZYLmboPmeYXmhofmk4nloo3lsJLlvZbkyZzk1KLk3qnj5rDj7a/j96/k+7LhN4bmP4jmSYjmVonmao3lf5PljpXlnpjlrZzku6Dkx6bk06vk3bHj5bjj7bjk9bjk+rriCJTlI5blM5blRZflV5jla5nlfpzll6PlqKbkt6rkxq/k0bTj3Lrk5MDj7MDk9MDk+cPjJKjjL6nkN6nkQajjTqjkXKfkcajkh6rkna7ks7Tkw7nk0L3k28Lk5Mjk7Mnl8snk+czkTLzjUbzjVrzjXLzjZbzjb7vkervjhrrjk7njqLzkvcLkzcbk2srk5M/l69Ll8NLk+NTlaszibczjcMzidczjfMzjg8zjjMzjlsvjoMvjq8vjtsrjx83k2NLk49fl69rm8dvm+N3nhtnih9niitnjjdnjktnjmNrjntrjptnjr9rjuNrkwdrkytrk1Nrl4t7m7OLo8uPo+eTonuTjoOTkoeTkpOTkqOXkrOTjseTkt+XkvuXlxeXkzebm1ebm3efn5Ojo7Orp8uno+unnt+3mt+3lue3lvO7mvu3mwe3mxe3myu7nz+7o1O7o2u/p3+7p5O/q6e/r7O/r8/Lt+vLrzvTqz/Tr0PXr0fXr0vTq1PTr1/Xr2fXs3PXs3/Xs4vXt5fXt6fbu7fbv7vbu8/fv+Pnxez/yfUDygUHxh0Pxj0fxmUzxpFHxr1jwu2Dwxmnw0HPv2n3u5Int7JTt85ns+prs/5ztekLxfUTygkbyiEjykEvymE7wo1Twr1rwumPwxmvv0HXu23/t44rt65Xs8prs+prs/53tekrxfkzxg07yiE/xkFPymlfxpFzxr2Hwu2nwxnHv0Hru2oPu447t65js8p3s+p7s/6DtfFXygFjyhFnyilvykV3ymmHxpWXxr2rwu3Hwxnnw0IHv24ru45Pt653t8qLs+aLs/6XtfWLyf2PxhGXyiWbxkWnxmmvxpG/wr3Twu3rvxoHv0Inv2pDu4pnt66Pt8qft+Kfs/6jtem7xfnDxgXHxiHLxj3TxmXfwo3rwrn/vuoTvxYrvz5Hu2pju4qDt6afs8K3s+K3s/67sd3vwfH3xgH7xhn/xjoHwmIPwoobwrYrwuY/vxJTuz5ru2aDt4aft6a7s8LTs97Ps/7Xtcofwd4nwe4rwgovxio3wlY/woJLwrJXvt5nvw53uzaLu2Kju4a7t6bXs77rs9rrt/rvtXo7wZJDxbJHwd5Twg5fwj5nwm5vvqJ/vtaLvwabuzKvu17Du37Xt6Lzs7sHs9cDs/MHtSZjwUZnwWJrwYpvwb5zwf57wk6Tvo6jvsKvuvq7uyrPt1bjt3r3t58Pt7sjt9Mjt+8ntMKbvOqfvQ6fwUKfvYKjvcanvgqvvlK3vqrTuurfux7vu08Dt3sXt5srt7c/t9M/t+tDtULruVrvvWbruX7ruZ7rvcLnverjvibjunbrur73uw8Tu0cjt3Mzu5tHu7dXt89fu+dfubcvtb8vuccvtdsvte8vug8rui8rtlMntncntp8ftucruzM/u2tPu5dju7dzu897v+N7uiNntidnti9ntjtntktntl9ntndntpdnurNjutdjuvdfuxtfu1Nnu497u7OPv8+Xv9+Xvn+TtoOXtoeTtpOTtp+Xuq+XtsOXttuXuvOXuwuXuyeXu0OXu2OXu4OXv7Onw8+zw+OzwtO7ute7ute7ut+7uuu7uvO7uwO/uxO7uye/vz+/u1O7u2u/v4O/v5/Dw7fHw8/Lx+fHxx/Xvx/XvyPXvyfXvy/XvzfXv0PXv1PXw1/Xw3Pbx4Pbx5fbx6vby7vfz8ffz9fj0+fn1k1/7lWD7mGH7nGP6omb6qWr6sm/6u3X6xXz5zoP514v435P35pz27qX19K31+rH1/7L1kmD6lGL6l2P7nGX7omj6qWz6sXD5u3f5xX35zYT414z33pT255327aX18630+rL0/7P1kmb7lWj7mGn7nWz7om76qnH5snb6u3v5xYH4zoj415D435j35qD27af186/0+bT0/7X1k2/7lnD6mXH6nXP6o3b6qnn5s336u4H5xYf4zo7415T335z35qP17ar187P1+bf1/7j1lXn6lnr6mXv6nnz6o376qoH6s4X5u4n5xI74zpT41pr33qH25qj27a/187f1+br1/rv0koH6lYP6mIT6nYb6o4f6qYn6so35u5H4xJX4zZv41qH33qb25a317LP18rr0+L70/r/0kIv5lI36l476nI/6oZH5qZP5sZb5upn5w574zKL31af33a325bL17Ln18r/098P0/sT1jpb6kZj6lJj6mZn5n5r5ppz5r5/5uaL4wqb4y6r31K/33LP25Ln27L718cT098j1/cj1h576ip/6j6H6lKH5mqL5o6T5rKf5tqr4wK34ybH307X327n25L7268P18cn19s31/M31caH6d6L5e6P6gqT6jqf5m6v5pq74sbD4vLT4x7f30bv32r/248T26sn18M719tL0+9L1ZKv5aaz5b635dq36gK/6i7D5mLL5qbf4uLv4xL/3zsL32cb24sv26c/279P19dj1+tj1Yrr5ZLr5Z7r5a7r5c7n5gLr5jrv5nr35rL/4vsX4y8n318334NH36NX18Nn29d72+t72esz4fMz4f8z4gsv4hsv4i8v4kcr4mcn5pMn5s8v4w83409P33tf359r279/29OL1+eP2k9r3ldr4ldr4mNr3m9n3n9n3pNn3qtn4sdn4uNj4v9b4y9j429345eH37uT39Of2+en2qOb3qOX3qub3rOb3rub3seb3teb3uub3vuX3xOb4yuX40OX41uT44eX47er49e33+u/3u/D3uu/2vPD3ve/3v/D3we/3xPD3yPD3y/D30PD31PD32fD33u/35PD46vD48/H3+fT4yfb3yvf3yvb3y/f3zff3z/f30ff31Pf41/f32vj43ff34vf35vf36/j48Pj49fn5+vr6\",pastel400:\"BQUDCwUDGAYDJgcDNwYDTAICZgABgAAAmgAAsQAAxgAA1gAA5AAA7woA+yAA/y8A/zwAAwwDCw0DGA8DJhADNw8CTAwBZgUAgAAAmgAAsAAAxQAA1QAA4wUA7xoA+ykA/zUA/0EAARgEBxcEExgCJRsCOBsAThsAZhgAgBMAmQ0AsQgAxQ0A1RYA4iAA7ioA+jUA/z4A/0gAACYDACUEDiYDICgBNSoATSsAZyoAgCkAmigAsSkAxCsA0y8A4DUA7TwA+EMA/0sA/1MAADcBADYDADYDGTgAMDkASj0AZT4AgD8AmT4Arj8AwUEA0UQA3kkA600A9lMA/1gA/14AAEoAAEoAAEkACUoAKkwARE4AZFMAflQAllQArFQAvlUAzlcA3FsA6F4A9GIA/2YA/2sAAF8AAGAAAGAAAF4AIGAAP2IAW2QAemgAk2kAqGkAu2oAy2oA2WwA5W4A8XIA/XUA/3gAAHMAAHUAAHMAAHIADnIAOHQAVXUAcXcAjnoApHwAtn0Axn4A1X0A4n4A74AA+4IA/4UAAIcAAIcAAIUAAIQAAIMAMYQAUIUAbIcAhYgAnYoAso0Awo0A0Y4A344A7I4A+Y8A/5AAAJUAAJYAAJYAAJQAAJMAL5MATpQAaJUAgJYAl5cArJkAv5wAzp0A250A6JwA9ZwA/5wAAKQAAKUCAKUFAKQIAKIMMKEQTqIKaKIBfqMAk6QApqUAuKYAyqkA2KoA5aoA86oA/6oAALIVALIXALIYALEaHLAcOq8fU68faa8afrAVkbANo7EBtLIAxLMA1bYA47cA8bcA/7cAAL8nAL8oAL4pGL4qMr0rRrwuWLswbLstf7srkLwmob0isL4bv78Qz78C4MMA7sMA/MQAEMo5Hcs6Kco6Nso7Rck8VMg+YcdAccdAgcg+kMg8n8k5rsk2vMoxy8sr2swk7dAg+9AlO9dNQNhORddOTdZPVtZQYdZSbdVUeNRWhdRUktVToNZRrddPu9dMyNhI19lF5tpA+d0/VeRlWeVnXOVnYuVoaORpcONqeeNsguNvjeNwl+NuouRtruVsuuVpyOZo1edl5Ohi8+hecPOCcvODdPKDePOEfPKEgvKGifKIkfKLmfGNofGMq/KMtfOLwPSLy/SK2PWJ5veI9PeHBgUJDQYJGAQJJgQJOAULTQELZwAKgQAImwAHsgAExgAC1gAA4wAA7wwA+iAA/y8A/zsABA0JDQ4KGQ8KJg8KOA8KTQwJZgQIgQAHmgAFsgADxQAA1QAA4gUA7hoA+ikA/zUA/0AAAhkKChkKFhoKJhsIORsITxsIaBgGgRMEmg0CsQgAxQ0A1BYA4iAA7isA+TQA/z8A/0cAACgKAygLEScLIikJNysGTysDaCoBgikAmygAsSkAwysA0y8A4TUA7TwA+EMA/0sA/1IAADkJADgKBDcLHDkKMjoGTD0BZz8Agj4Amj4Arz8AwkEA0UQA30kA6k0A9lMA/1gA/14AAEsGAEwHAEsJDksILU4FR08AZVMAf1UAmFQArVMAv1UAzlgA3FsA6F4A9GIA/2YA/2sAAGEBAGICAGEFAF8HI2ECQWMAXWQAfGgAk2kAqGkAu2oAy2kA2WwA5W8A8nIA/XQA/3gAAHUAAHYAAHUBAHQEFHMDO3UAV3YAc3gAj3sApHwAtn0Axn0A1X0A434A74AA+4IA/4QAAIgAAIgAAIcAAIYEAYQINIUDUoYAbYcAhogAn4sAso0Aw44A0Y4A3o4A7I4A+I4A/5AAAJYBAJgFAJYHAJUKAJQOMZMOT5QHapUAgpYAmJcArJkAv5wAzZwA250A6Z0A9pwA/5wAAKUPAKURAKUTAKQVCaMYM6EbUKIXaaMSf6MIlKQApqUAuKYAyqoA2KoA5qoA86oA/6oAALIeALMgALMhALIiIrAjPa8mVK8maq8jf7AfkrAZpLERtLICxLMA1bcA47cA8bcA/7cAAL8tAL8vAL8vHr4wNb0xSbwzWro1bbszf7sxkbwtob0psb4jwL4cz8AQ4MMG7sMC/MQCFss9Iss+LMo/Oco/R8lAVclCY8hEcsdEgshDkchAoMk+rsk6vMo2y8sx2swq7NAo+9AsPNdQQddRRtdRT9dTWNdUY9ZVbdZXeNVZhdVYk9VWoNZVrddTu9dQydhN1tlI5tpE+d1DV+VoWuZqXeVpYuRqaeRrcORteuRvg+NxjeNyl+NxouRvruRuu+VsyOZq1eZn4+dj8+hgcfODcvOEdPKEePKFffOHg/KIivKKkfKMmfGOofKOq/KNtfSNwPSMy/SL2PWK5veK8/eJCgYUEAYUGgYVJwQUOQIVTwAVaQAVgwAYnAAXswAWxgAV1gAV4wAT7xET+iMT/zEV/z4ZBg0UDw8VGQ8VKA4VOg0VUAoVaQYXgwAWnAAWsgAVxgAU1QAT4wkS7x0R+SoS/zcU/0IYARoVCxsWGRwWKBwWOxwWURsWahgVhBQVnQ0UswoTxg4S1RcQ4iEP7iwO+TYP/0AR/0oWACsXCCsXFioXJisWOywUUisTaysShCoRnSgPsikOxCsM0zAK4TYI7D0I+EUJ/0wM/1QTAD0ZADwWDDsXIDsXNTwVUD8Raz8NhD4InD4GsUAEwkEB0kUA30kA604A9lQA/1kD/18MAE8UAE8VAE4WFk4YME8VSlERaFUKgVUCmVQArlQAwFUAz1gA3FsA6F8A9GMA/2cA/2sAAGQSAGQUAGQWAGIXKGIWRGQSYGYLfmkAlmoAqmoAvGkAzGoA2W0A5m8A8nIA/XUA/3gAAHcSAHgTAHcUAHYXHXQYPnUUWncNdXkDkXwApX0At30Ax30A1X0A434A74AA+4IA/4UAAIkTAIoVAIkWAIcYEYYbOIYYVYcTb4gMiIkBoIsAs40Aw44A0Y4A344A7I4A+Y4A/5EAAJgYAJgZAJgbAJYcDpYfNpQfUpUca5YXg5YPmJgDrZoAv5wAzp0A250A6Z0A9pwA/5wAAKYfAKchAKYiAKUjGaQlOKInU6MmaqMigKQdlKQXp6YOuaYAyqoA2KoA5qoA86oA/6oAALMqALMrALMrALIsKbEuQrAwVq8xbK8ugLArkrAnpLEitLIbxLMR1bYH47cA8bcA/7cAAL82AL83Br83Jb44Or45TL07XLs9brs7gLw6kb03ob0zsb4vwL8pz8Ai4MMe7sMb/cQaHspDKMtFMMtFPMpGSspHV8lIZchKcsdLgshJkchIoMlFrspCvMo+y8s62sw07M8y+9A2P9dVQ9hWSNdWUNdXWddYZNZabtVbedVdhtVdk9VboNZZrddXu9hVyNhS19lP5tlK+d1KWOVrW+VsXuVsY+RtaeRucuRweuNxg+NzjeN1mON0o+RzruRxu+Vwx+Zt1eZr4+dn8+hlcvOFc/OGdfOGefOHfvKIg/KJivGLkvKOmvKQovGQq/KQtfOPwPSPzPWO2PWM5vaM8/eLDQgiFAciHQciKQcjOQMjUgAjbAAkhgAlnwAltgApyAAr1wAq5AAq7xcr+igr/zUt/0IxCQ8iEhAjHREjKhEkOw4jUwckbAAlhgAlnwAmtQAqyAAq1wAp4xEq7yEq+S8r/zks/0YwBBokDRskHB0lKx0lPhslVRklbRYmhxMonxAptQ4pxxIp1hso4yYo7jAo+Tkq/0Ir/0wvACslBCwmFywmKi0nPy0nVi0mbiwmiCsnoComtCsmxi0m1DIl4Tgm7T8m+Ucn/04p/1YtAEAmAEAnFEAoJz4nOz8mVUAkbz8iiEAin0Ais0AhxEMh00Yh30sh608h9lUj/1ol/2AqAFMpAFUqAVQoIFMoNlIoUFQmbFYihlYenFQasFUawVcZ0Fka3Vwa6WAb9GMd/2cg/20mAGkpAGknAGgnEWYpMGUqSmYnZGgkgWsfmGsarGoUvmkNzWsN2m0O5m8Q8nMU/XUY/3kgAHsmAHwoAHsoAHkpKHcqQ3cpXnkmeHoik30bp30VuX0NyH0D1n0A438A74EC+4IK/4UWAIwoAI0pAIwqAIorIoktP4ctWYgqcoknioohoo0atI4TxI4J0o4A4I4A7I4A+I8A/5ECAJosAJotAJouAJkvIpcwPZYyV5Ywb5cthZgpmpkkr5sdwJ0Wzp0M3J0B6ZwA9psA/5wAAKgxAKkzAKgzAKc0KKY1QaQ3V6M2baQ0gqQxlqUtqKYpuqcjy6od2aoV5qoM86oB/6kAALQ4ALU6ALQ7F7M7M7I8SLE+Wq8/brA9grE7k7E4pLI0tbMwxbQr1rcn47ci8bcd/7caAMBCA8BDHMBDL79EQL5FUb1GYLxHcLxHgbxFkr1Dor1Asb49wL85z8A04MMy7sMv/MQvJ8tOL8xPN8xPQctPTspQW8pRZ8hSdMdUg8hTkshRoMlPrspNvctKy8tG2sxB7NBB+tBCQ9hdR9heTNheU9dfXNdgZdZhcNVie9Vkh9VklNZjoNZhrddfu9ddydlb19lY5tpU+d5VWuVwXeZyYOVyZeVza+V0c+R1e+R2hON4jeN6mON5o+R4r+R2u+V1yOZ01eZx5Odu8+hrcvKIdPKJdvOJevOKfvKLhPKNi/KOk/KQmvKSovKTq/KStvOSwfSSzPWR2PWQ5veQ8/eODgg0FQg0IAg0Lgg1PwU3UAA1bQA3iAA3ogA5twA5yQA62QA75A5D7yND+jFF/zxG/0hICxE0FRI1IBI1LhM2PxE3Ugs2bgA3iAA4ogA5uAA6yQA72AA+4x1C7ypD+TVD/z9E/0tIAxs2Eh42Hx03Lx84QR45VRo4cBE4igk5ogE6uAA7yQ0+1iNB4yxB7jZC+T9D/0dE/1FHACs3Bio4GSs4Li45Qi86WSw6cis6jCo8oyo9ty9AxzI/1jdA4jw/7URA+EtB/1JD/1pGAD86AD86DkA7KUE7QkI8WkM9c0M8i0M9oUM9tUQ8xUY800k84E0861M99lg+/11A/2NEAFg7AFk8AFk9KVg+P1c+Vlc8clg6ilY3n1Y3slc3wlk30Fs33V846WI59GY6/2o8/29BAG0+AG4/AG1AJWw/O2o+UWk+ams7hW04m2w0r2oxv2sxzm0x2m8y5nEz8nQ2/Xc4/3o8AH9CAIBDAIBAFH4+NXw/S3o/ZHs9fX07ln83qX8zun4vyX4r134q5IAs74Iv+4My/4Y4AJBBAJFAAJA/C44/MYxASYpBX4pAd4s+jYw7pI83tY8yxY8u044q4I4l7Y8m+Y8q/5EwAJ1AAJ5BAJ1CD5xCMppDSZlEXZdEc5hCiJk/nJo8sJw4wZ00z50w3Z0r6pwm95wg/5wmAKpEAKpFAKpGHKlGN6hHS6ZHXaRJcaRHhaVFl6ZCqac/u6k7y6o42Ks05qow86or/6koALZJALZLELZLKrVLP7RMULJNYLFOcbBOg7FLlbJKpbNHtbNExbRA1bc+47c78bc3/7c1EMFRH8FRK8FSOcBSSL9TVr5TZb1Vc7xWg7xUk71Sor5Qsb5NwL9Kz8BH4MNF7sND/cRCMsxaOM1bPsxbSMtbUstcXspda8ledshfhMhekshdoclbr8pZvctXy8xU281R7M9Q+tFRSNhmS9hnUNhoV9hoX9hpaddqctZrfdVsiNVtlNVsodZrrtdpu9hnydll19li59pg+d1gXeV3X+V4Y+Z5aOZ6beV6dOR7feR9huN+j+OAmeOApOR/sOV+u+Z9yOZ61eZ45Od28+hzdPONdvONd/KNe/OPf/KPhvORjPKRk/KUm/KWo/GXrPKXtvOWwPOVzPSV2PWU5vaT9PiTDAlIFglJIghJMQhLRQdMWQBOagBLhwBNowBOuQBPygBP2QBP5QBR8QtT+jBY/0Zf/1FhCxJJFRJJIhNKMhNLRRJNWg5PawJLiABOpABOuABOygBQ2ABQ5QBR8B5T+Txc/0lf/1NhCB5LFB5MIh9MMx9NRyBOWx5QbhhOiwdQpABQuQBQygBR2BBS5SJT7zdY+Ehd/1Be/1lgACpLBCtMHS1OMi9PRzBQXDBRcixRjidRpSVRuCdSyStT1zNU4kJZ7Uxb91Jc/1ld/2BgAD1NAD5OEj5PKz9PRkNSXkVUd0NUj0JTpUNUuEVVxktY1E9Y4FRY61hZ9l1a/2Ja/2hdAFZRAFdTAFhTJVlUQ1pVXltWd1tWjVtWoltVtFxVw11U0WBU3mNV6WZV9GpW/21Y/3JbAHJUAHNWAHNVInJWRXFXW25WcW5Uim9Sn21PsW1PwG5PznBP2nFQ5nRQ8ndS/HlT/31YAIRVAIVWAIRXLoRYRoJYV39Wan5VgoBUmYFRrIBNvH9Ky39J14BK5IJL74NN+4VP/4hUAJRZAJRbIZNbNpNbQJFWVY9XZ4xXfI1VkY5Tp5BQt5BNxo9J1I5G4Y5E7ZBG+JBI/5JNFaBeHqFdI6FbK6BYQp9YVZxYZZlZeJpYi5tWn5xTs55RwZ5Nz55K3Z1G6pxC95xB/51GAKxaCa1aG61aMaxaRapaVqlbZadbdqVaiKdZmqdXq6hVvapSzKtP2atM56tI9KpF/6lCCrdcHrhdK7ddOrdeSrZeWbVeaLNfdrFfhrJel7Ncp7RatrRYxrVV1rdT47hQ8rdN/7dLKcNhMcNiOcJiRcJiUcFjXsBjar5jd71khb1klL1io75hsr9ewcBcz8FZ4MNY78NW/cRVO81nQc5pRs1oT81pWcxpZMxqb8preslshshslMlroclpr8pnvctmy8xj281g7NBh+9FhTdlyUdlyVdlzW9lzY9h0bNd0ddd1f9Z2idV3ldV2otZ2rtd0u9hzydlx19pv59ps+d1tYOZ/Y+aAZuaBa+aCceaCd+WDf+SEiOSFkeOHmuOIpeOHsOWGvOaEyOaD1ueB5Od/8+h8dfOSePOTefOTffSTgfOUh/OVjfOXlPKYnPKapPKcrfKctvObwvSbzfWa2faa5vaZ9PeYCwpfFwpgJQphNghhSgZjYAJldQBnhgBkoABluABmywBl2QBl5QBl8QNm+yVo/zlr/0twDBRfGBRhJhRhNxRiSxJjYRFldQVnhgBkoQBmuQBmygBl2QBl5QBl8Bpn+i5o/z5r/1JxCh9hFyBiJiBjOCBjSyBkYSBmdxxoiBVmowFnuQBmygBm2Ahm5B5n8C9o+T1q/0pt/193ACthDy5jIy9kNzBkTDFmYzJoeTFqiy1opSdpuSNoySho1zBo4zpp7kRr+E5t/11z/2l4ADxhAD1iEz5jMEBmS0RnY0ZqekdsjURqpUFpuEJpyEVq1Utq4VFs7Flu9GZ0/2p0/3B3AFJlAFRnBFVnKlZoRVZpYltreV1tj1tspFtstl1sxWBt0WVv3Wpx6G1x8nBx/XNx/3h0AG1pAG9rAG9rInBsQ3FtXnFueXJujnJuoXJtsnJswXNtznVt2ndt5nlt8Xtt+31u/4FxAIhtAIluAIpuHohuRYduYoZudYNuiINsnYNproFmvYFmy4Jn14Nn44Vo74Zp+ohq/4ttAJhtAJhuD5huNpdvUJVvZZRwcpFtgpBtlZFrqZJouZJlx5Bi1ZBh4ZFi7ZJj+JNk/5RnDKNvJKRwNaRxSKNyWqJyYKFtcJ5tfpxtkJ1soZ5qtKBowp9l0J5i3p5e6pxc9p1d/55hOK9zQa91Sq91Ua5zVK5vYaxub6pvfKhvjKhtnKlsrKlqvqxozKxm2axi56pf9Klb/6lbRLl1R7p2SLpzSrlxVrhwY7dwcLVxfLNxibNwmbNvqLRtt7Vsx7dp1rhn5Lhl8bdi/7ZgP8RzQsRzRsRzT8NzWcNzZcFzccFzfL9ziL10lr5ypL9xs79wwcBu0MJs4MRq7sNo/cRnRs92Ss93UM93V853X814ac14dMx4fsp5icl5lcl4osp3r8p2vcx0y8xy2s1w7NBw+9FwVNp9WNp+W9p+YNp/aNl+cNl/eNeAgteAjNaBltaCotaBr9eAu9h+ydl919l759p5+d16ZOaIZ+aJauaKbuaKc+aKeuWLguWMiuSNkuSOm+OQpuSPseSOvOWNyOaM1ueL5eiI8+iGd/OYePOYe/OYfvOZgvOZiPOajvOclfOdnfKepfKhrvKhuPOhwvSgzfSg2vag5/ef9feeEQt2HAt2Kgp3PAh4UAV5ZQF6fAB8kQB+oQB9tQB8yAB82QB75QB68QB6+iF6/zZ8/0l/ExV2HhV2KxV3PRR4UBN5ZRB6fA58kAB+oQB9tAB8yQB82AB65QB68BR6+ix7/z18/06AEyF3HiF3LCF4PSF4USF6ZiF7fiF+khyAoRN9tQR9yQB92AB75Bl77it7+jt8/0h9/1eBDC93GzB4KzB4PTF5UjJ7aDN9fzV/kzOBoS9+tip+ySd91y184zd87kF9+Ex+/1d//2ODADx3AD14Hj96OkN7UUV8aEd+f0mAk0mCoUZ/tkR/yEN+1Ul+4U9+61d/9l6A/2aC/3CGAFB4AFJ6DlJ6LVN6SVZ9Zlp/fV6Bkl+Col2AtluAxV1/0mKA3WaA6GuB83CD/HmH/4CMAGl7AGp9AGp9Kmt9Rmx+X21/e3KBkHSDonOCs3OCwnWCz3eD2nyF5YCH74KH+oSH/4eJAIJ+AISAAISAJoSBRoWCYYWCeIaDjoeEoIeDsIeDvoeDy4iC1oiC4oqC7ouC+YyD/4+FAJuCAJyEAJuEKpuESpqEZZmEfJeEi5SDmpSBq5V/u5N9yJN81JN84JR87JV995V+/5eAAKeBFqiDLqeDRKeDWaaDbaWEfqOFh6CClJ+BpaCAtqF+xKF70Z943p516p529p93/6F6NLKDPrOESLKEVbGFZLCFdK+Gea6ChauBkKmBn6uAr6t/wK19za162ax256p09Klx/6pzTbyGU7yHWbuHYruIbbqIb7qEeLiChLeCjrSBnLWBqrWAuLZ+ybh81rh65Lh38rd0/7ZyXsaKYcWKZMWKZsWIZ8SFbcSDeMKDgsGDjL+DmL+Cpr+BtMCAwsF/0sN94cR87sR5/cN4XtCKX9CKYNCJYc+HZs+FcM6Gec2Gg8yGjcuGl8mGpMqFsMuEvsyDzM2C3M6A7NB/+9GAXduKX9uLYduKZtuKbNqKddqLfdmLhtiMj9eMmNaNpNaMr9eLvNiLydmJ2NqI59uG+d6IaeeSa+iSbeeTceeTd+eUfeaUhOaUjOWVleSWneSXp+SYseWXveWXyeaV1ueU5OeS9OmQefSeevSffPSff/SfhPSfifOgj/OhlvOin/OkpvKmr/KouPOnw/SnzvWm2vWm5/al9vilHgyJJwuKMwqKRAiLVwaMawGOgQCPlgCSqACTtwCTxQCP1QCP5ACN8ACM+x2M/zOM/0eOHxaJKBaKNBWKRBWLVxOMaxGNgRCPlxKSqASTtgCSxACP1QCP5ACN8AqM+SeM/zqM/0yOICKKKSKLNSKLRSKLWCONbSKPgiOQmCaTqCCUthiTxRSQ1RKQ5BWO7yiN+TiN/0aN/1WPHjGKKDKMNTKMRjKNWTOObjSQgzaRlzmTqDeUtTOTxTGR1TGQ4zSO7T+O+EqO/1WO/2KRCD+LIEKNMkONRESNWEaPbUeQgkmSl02UqE2VtEqSxEmR1EmQ4U2P7FWP9l2P/2WQ/26TAE+JAFGLHVGMN1ONVVmPa1uQgV2RlWGUpmKVsWCSw2CS0mCQ3mSQ6WqQ82+R/XWS/32VAGWKAGaMFGeMMWeMSWiNY2uQfnGSk3STpHaVsXWTwnSTz3aS23mS5n2T8IGU+4WV/4yaAH2OAH6PD36PMX+PS3+QYoCQeIGRkIaToYiWsIeUv4iUy4qU14yV4o6W7JOZ95SY/5aaAJWSAJWSE5WSNZWSTpWTZZaTepeUjpeVn5iWrpiWu5iVyJiV1JiU35mU65qU9puU/5yVAKmUB6qVJ6qVP6qVVaqWaqmVfqiVj6aWnKOUqaOUuKORxaGP0aGN3qKO6aGO9aKO/6OQLrWUObaURLWUUrWVYrSUc7OVg7KVkLCWmK6To62Ssa6Rwa+Qzq6N26yJ56qH9KuI/6yKSr6UUb+VWL+VYb6Vbb6WebyWhruXjLqTlbiSn7aSrLeRuriQyrqP17mL5biJ8raG/7WEXMiWYMiXZciXbMeXdceYf8aYg8WUicOSk8KSnMCSqMCRtcGQw8KP08SO4cSM78SK/cOIadGZbNGZcNKaddGaetCZfNCWgM+Uic6UksyUm8uUpcqTssySv8yRzc6Q3M6P7NCO+9CNdNydddydddycdtubd9yZetuXgtqXitmXk9iYm9eYpdaYsdeXvdmXytmW2dqV6NuT+d6VdOefduigd+ifd+ieeuedgeidh+eej+ael+afn+WgqOShsuWgvuWgyuaf1+ee5uic9Ombe/WmfPWmfvWmgfWmhfSmivSnkfSomPSpoPOqp/OrsPOtufOuxPSuz/Wt2/as6Pes9verLw2bNg2bQAucTwmdXwedcgOehgGgmgSirA+juwGkyACk0gCf4ACf7gKe+hWb/zCb/0ScLxeaNhebQRabTxacYBWdcxSfhxOgmhahrB2juhWkyAik0gyf4BCf7Red+SKb/zab/0qcMSSbOCSbQiSbUCSdYSSedCSfhyWgmyiirC6juiqkxySk0iWg4Cif7Sye+TSc/0Ob/1OdMTObODOcQzSdUTSdYjWedDafhzegmjqiq0Cjuj6kxjuk0Tug3z2g7ECe+Eed/1Kc/2CeLkSdNkWcQUWdUEaeYUefc0ifh0uhmU6iqlOjuFKkxFCj0FGh3lKg61Sf9lqd/2Kd/2yfBk+aHFCcMlOcTFidXlmecVufhV2gl2GhqGajtmakwWSizmWh3GWg6Wif822e/XOf/3uhAGKYC2SZJGSaO2WbUmedbm6fgnCglXShpnijtHmkvniizXii23ih5nug8X+h+4Oh/4mjAHiaCHqcJHqcOnqcTnucY3ucen+fkoSho4ijsYqkvYmjy4mi2Iqi442i7o+j+JKj/5amAI+eEJCeKJCfPpCeUpCfZ5CfepGfjJKgoJeir5mkvJmkyZmk1Zuk4Jyl656l9aGn/6OpDaKgJKOhNKSiRqShWKSia6SifaSjjqWjnqakraeluqelxqek0qak3aej6aej9Kej/6mkLLWjN7akQrakULakYLakcLalgbWkkLSkn7OkqbCjtbCjw7Chz66e266d566d9K+e/6+fR8KjTsKkVcKjX8Gka8CjecCkhb6kk72koLylprqisLmhvbqgy7uf2Lqc5bia8reX/7iZWsujXsujY8qja8qjdMmjf8mkisiklcelmsWio8OhrMGgt8KfxcOe1cWe4sWb78SZ/sOXZ9Ska9SkbtSkdNOle9OlhNKljtGmktCjmM+hoc2hqcugtMygwM2fzs6f39Ge7dCc+9Gcc92ndt6ned6ofd6og92oit2pjdymj9ujl9qjoNmjqNejstejvtijy9qi2dqh6dug+d2gf+msgemtg+ith+itiemsiuiqjOiok+eomuaoouapq+WptOWqv+Wpy+ep2Oeo5uin9ummiPWyifWyifWxivWxi/WwjfWukvSvmfSvofSwqfOxsvSzu/O1xfS00PW03Pa06fez9/izQg+qRw+rTw2rWwyragusewqtjQuung+vrxmwvSOxyh6y1haz3Ryt6iKt9ymr/zCp/0GpQhmqRxmqUBmrXBisaxisexetjRmunhyvriOwvSyxyimy1SOy3Cet6iut9zGs/zap/0apQyaqSSarUierXSasbCesfCetjSmuniyvrjGwvTqyyTey1TOz3TWu6jmt9j2r/0Kq/1CpQzWqSTasUjasXTasbDetfDitjTqunj2vrUKwvEqyyEiy1EWy3Eeu6Umt9k2s/1Cq/12qQkarR0arUEerW0esa0ite0qtjEyunFCvrFSwuluxxlqy0liy21mu6Fut9F2s/2Cr/2qrNVSpQFeqTFirWFmraFqseFusil6tmmKuqmawuGyxxGyyz2qx2Wuu5myu822s/nGr/3msHGKoKWOpN2SpSWWqYmurdW6sh3Ctl3Oup3ivtn2xwn6yy3yw13yv5Hyu8X6t+4Gs/4iuEHWnIXaoMHaoQXenVXipanqqg4GslIStpIevs4ywv42yyIyv1oyv44yu746u+ZCu/5WvGYupJoupNIupRIupVouqZ4ypeYyqjZCsoZWusJmwvZuyx5ux1Jqw4Zuv7Jyw956w/6KxJZ6rMZ6sPZ6sS56sW5+sa5+sfJ+sjJ+sm6CtraWwu6iyx6ex06ix3qmx6amx9Kuz/6+1N7CuP7GuSLCuVLGvYrGvcbGvgLGwj7GwnrGwrLOxubSyxbSy0LSx3LSx57Sx87Sx/7WyR8GwTcKxVMKxXcGxasKxd8KyhMKyksGyoMCyrb6ytryxwb2wzb2u2bqr5rqr8rqr/7usWM2wXM2wYc2xaM2wcs2xfcyxicuxlcqxocixrMexssWvu8SuyMWt1sas48Wq8MSn/sOmZdavadawbdawc9awetWwhNWxjdSwmNOxotKyp9Gvr86ut82tw86t0NCs4NGr7tGq/NGpceCxdOCxd9+xfOCygt+yid+ykt6zm92zoNyxpduvrdqvtdivwNmuzdqu29ut692t+t6sfeq0f+q1geq1heq1ium1kem2mOm3nOi1nuiypueyruazt+Wzweazzeey2eey5+ix9+mwiva6ivW6jfa6kPW7lPa7mfW7m/W6nfW4o/W4q/S5tPS6vfO7xvS80fS83fa76ve79/i6VRS5WRS5YBO5ahO5dhO6hRS7lBa7oxu7sSO9vi29yzi+1jS/4jG/5zS59Dm5/z+4/0e2VB24Wh25YB65ah25dh65hR+6kyC6oiW7sCu8vjS9yz6+1ju/4Ti/5zq58z65/0O3/0u3Vim4Wyq5YSq5ayu5dyu6hSy7ky67ojK7sDi8vkC9y0i+1Ua/4UPA5kW580i5/024/1S3VTi4Wjm5YTm5ajq5djq6hTy6kz67oUG7sEe8vU69yVa+1FS/4FG/5VK68lW6/lm4/163VEi4WUm4X0m4aUq5dUu5g026kU+6oFK7rle8u169x2W+02O/3mG/5WK68WS5/Wa4/2q3Tli2VFq4XFq4Zlu4cly4gV65kGC6nmS6rGi7uW69xXS90HO+3HG+43K68HO5/HS4/3e3NmK1QGS2TWe3YGu3b224fW+4jHG5m3S6qXi7t328w4O9zoO+2IG94YG77oK6+oK5/4a4K3OzNXW0P3W0Tna1X3e2dX23iIG4l4S5poe6tIu7wZG9zJG+1Y+84JC77ZC6+Y+5/5O5K4e0M4i0PYe0Soi0WYe0aoi0fYu2k5G4o5S5sZi7vp28yp6+0py835y77Jy79526/6C6Mpm1Opq2RJq2T5q2XZq1bJq2e5q2ipu2m564rqO6vKi8yKq+0am836i86qm79qq8/6y9Pqu3Rau3Tau4Vqu4Y6u4cKu4fqu4jay4m6y4qa25ubK8xrW+0bS93rW96bW99Le+/7i/S7u6ULy6Vry6X7y7ary6dry7g7y7kb27nr28q769uL++xcC/0MC+28C+5sC+8sC9/cC9V8y9Wsy8YMy9Z8y9cMy9fMy9h829lM2+oM2+rMu+uMq+wci8y8i82Mi65Ma48ca3/ca4Y9m9Z9m9atm9cdi9edi9gte9jNe9l9a9otW9rdS9uNK9vdC7xtC609G64tK57tG3/tG2b+K8cuK8deK8euG8gOG9iOG9keC9muC9pN6+rt6+s928u9u7w9m6z9u63dy67d65+964e+y+fey+f+y+g+u/iOu/j+u/l+q/n+q/qOrArum/sui9u+e9w+W9zua92+e86ei7+eq7hvfCiPfCiffCjPbDkfbCl/fDnvbEpfbEq/bErfbBtfXCv/XDyPXE0vXE3vbE6/fE+PjDaBzGahzGcB3GeB3Ggx7GjiDGmiPGpyjHtC/IwDjIzELJ1kvK4UnK7EbL8UfF/UzE/1TEZyTEayTFcCXFeCbGgibGjijGmivGpy/HtDbIvz7Iy0fJ10/K4E3K60rK8EvF/FDE/1bDZzDFazDFcDHGeDHFgjLGjjPGmjbHpjrHs0DIv0fIy1DJ1lfK31XK61PK8FPF/FfE/17EZz7Faz7FcD/Fdz/FgkDGjULGmUTGpkjHs03IvlPIylzJ1GPJ32DK6l7K71/F+2LE/2fEZU3EaU7Ebk7Fdk/FgFDFjFHFmFTGpFfGsVzHvWLHyGnJ03DK3W7K6GvK7mzF+m7E/3LEYlzDZl3Ea17Ec17EfWDEiWLFlmTFomfFrmvGu3DHxnfI0X3J3HvK5njK7HnF+XrE/37EWGrCX2zDZm3Db27Dem/DhnHEknTFn3fFrHrGuH/GxITIz4rJ2YnJ5IfJ64bF+IjF/4nEQ3TBSnXBUnbBXXfCcHzCgYDDjoLDnITEqYjFtYzGwZHHzZbI15XJ4ZPJ6pPG95PF/5XFOYS+P4W/SIW/VIa/Y4fAcojBhYzCl5HDpZTEs5jFv5zHy6HI1aHJ35/I6Z/G9p/G/5/FPZa/Q5bASpfAVJfAYJbAbZa/e5bAjJnBoJ/Dr6PEvabGyavI1KzJ3KvH6KrH9qrG/6vGRafBSqfBUKfBWafBZKfBcKfBfafBi6fBmKfBqKvDubDFx7TH07fJ3LbI6LXH9bbH/7fITrfDU7fDWbjDYLfDarfDdbfDgrfDjrfDm7jEp7jEtLnExL7H0sLK3MHJ6cHJ88LJ/sPLWMfFXMfGYcfGaMfGccfGe8fGhsfGksfHnsjHqsjHt8nIw8rJ0MzK28vK5svJ8svJ/czKYdbHZdfIaNfIb9fId9fIgNfIitfIltfJodjJrdjKudfJxNXJzNPI1tPH49PF8dLE/tLEbeTIcOTIc+TIeOTJf+TIh+TJkOPJmePJpOLJruHJud/Jw97JydzG0tvG393G7t7F/N7EeO7Ieu7Ife7Jge7Jh+7Jje3JlezJnuzKqOzKsevLu+rLwOnIyOjI0efH3efH6ujG+uvGgvjKg/jKhvjLivnLjvjLlPfLm/jMo/fNrPfNtffOvffNwfbLyvXM0/XN3/bN7PjN+vnNeCjReynRfynRhSrRjSzSmC/SojLSrDfSuD3TwkXTzU7U11jU4V7V61zV9lnV+1jR/1/PeC/Rei/RfzDRhTHRjTLRlzXSoTfSrD3Tt0LTwUnSzFLT1lvU4GHU6l/U9lzV+lzQ/2HPeDnRezrRfzrRhTvSjTzSlz/SoUHSq0XSt0vTwVHTzFnT1mLU4GfU6WXV9WPW+mLQ/2fPd0XQekbRfkbRhUjRjUnRlUrRoE3Sq1HStVbSwFzTymPT1WvU33DV6G7U9GzV+WvQ/3DPdlPQeFTQfFTQg1XRi1fRlFjRnlvRqV7RtGPSvmjSyW7T03XU3XvU53nU8nbV+HbQ/3nPcmHPdmPQemPPgGTQiWXQkmfQnGnQp2zRsnDRvXXSx3rS0oHT3IbU5oTU8YHU9oDP/4TQbnDOcXHPdnLPfHPPhHTPjnXPmXjQpHrQr37RuoLRxYfS0IzT25LU5I/U743V9YzQ/47QWnfNYXrOaXvOdH7Of4HOioPPlYTPoIfPrIrQuI7Qw5LRzpfS2ZzT45rU7pjU9JjQ/5nQT4XMVIbMWobMY4bMb4fMfovOkJHOnJLOqZbPtZnQwJ3RzKHS16bT4aTU66LU9KLR/6PRSJTKTZTLU5TLWpTKZZTKc5XLgpfMk5rNpJ/OsaLPvqbQyqrS1q/T4K/U6a3T9K3S/63RTKTLUaTMVqTMXaTLZ6TLcaPLfaPLiqPLmqbMrKzOuq/Qx7PQ1LfT37nU5rjS9LfS/7fSU7PNV7TOW7TNY7TNbLPNdrTNgbTNjLPNmbTMpLTMs7fOxLzQ0sHT3sPU58LT9MHT/8LTW8POXsPPYsPOaMLPccPPesPPhcPPj8LOm8PPp8PPssPPv8TPz8nS3c3V6MzU88zU/87VY9LRZtLRatLRb9LRdtLRf9LRidLRk9LRntPSqtPSttTSwtXTz9XU3NfV59fV8tfV/tfVa+LTbeLTceLUduLTfOLThOLTjuLUmOPUo+PUruPVuePVxeLV0eHV2N/T49/T8N/S/t7QdO/Td/DUevDUfu/UhO/UjO/VlO/Vne/Vp+7Vse3Vu+3VxuzV0OrV1enT3+jS7OnS/ezSfvrVf/rUgvrUhvrVi/rVkfnVmPnVofnVqvjWs/jWvvjXx/fXzvfV1/fW4PbW7ffW/PnWiDveijrdjTvdkj3emT/eoEHeqUXeskneu07exFXezlze12Tf4Gzf6nDf9G7f/2vg/2vchz7cikDdjUDdkkLdmUPen0XdqEjdsUzdulHdxFjezV/e1mfe4G/e6nPf9HHf/23f/23ch0bciUjdjUndkUndmEven03dp1DdsFTeulnew1/ezGXe1mze33Te6njf83Xf/nLf/3PchlHciVPdjFPdkFTcl1Xdn1jdp1rdsF7duWLdwmfey23d1XTe33ve6X/f83zf/nrg/3nchV7ch1/cil/cj2DclWLcnWPdpWbdrmndt23dwXLdynfe1H3e3YPe6Ife8YXf/YLg/4HbgmrbhWzciGzcjW3ck27cmnDcpHLcrHXctnjdv3zdyYHd04be3Izd5pDe8I3f/Ivg/4rbf3jbgXnbhHrbiXrbkHvbl33boH7cqoHcs4TcvYfcx4zd0ZHd25Xd5Zne75ff+pTf/5Tad4Pae4Taf4XahIbai4falIjbnYrap4zbsY/bu5LcxZbc0Jrd2p7d5aPe7qDe+Z7f/p3bZYnZaYnZbYrZdYvZgY7ZjpLamJTao5barZnauJzbw5/czqPc2Kbd46ve7anf+Kff/qbbWpTXX5XYY5XYa5bYdJbYf5fZjJrZnZ/ZqaLZtaTawKjby6vb16/d4rPe7LLf9rDe/rDcV6PXW6PXX6PXZKPXbaLXdqLXg6PXkaXYoKjZsK3ZvbDaybTb1bfd4bve67vf9Lre/rrdW7HYXrLYYrLYZ7LYb7LYeLHYgrHYjbHXmLHXp7PYt7jZxrza07/c38Te6sXf8sTd/sPdYMDZY8DZZsDZbMDZc8DZe8DZhb/Zj7/Zmr/YpL/Yr7/YvsLZz8jb3czd6s/g8s7f/87eZs7aaM7aa87bcc/bd87bf8/biM/bks7anM/bp8/bss/bvc/ays/a29Td6dng89jg/9ngbN7db97dcd7ddt7dfN7dg97djN7dlt/doN/dqt7dtt/ewt/ez+Df2+Hf6OPh8+Lg/uLgc+7fdO3ed+3ffO7fgu7fiO3fke7fmu7gpO7gr+7gu+/hxu7h0u3h3Ozg5Orf7+ve/uvdevvfe/vgfvvggvvgh/vfjvvglvvgn/rgqPrhsvrhvPrhx/nh0vnh3Pjh4/ff7/jg/vrgllHpmFLpmlLpnVPpolXpqVjpr1vpt17pv2Ppx2jpz27p2HTo4Xvo64Lp9ITp/YHp/3/qllTpl1XpmlfpnVfpo1npqFrorl3otmHovmXoxmrpznDo2Hbo4Xzp6oPp84Xp/YLp/4DqlVrol1zoml3pnV3ool/pqGHpr2Tptmfovmvpxm/oznTo13ro4IDo6ofp84np/Yfp/4TqlWTplmXomWbpnWfpoWjpp2rprmzptW/ovXLpxXbpznvp14Do4Ibo6ozp847p/Yzp/4rqlG7olW7omHDom3DooHHopXPorHXotHjovHvoxH7ozYPo1Yfo343o6ZPp85Xp+5Hp/4/qkXjnk3nnlXrnmXronnzopH3nqn7nsoHnuoTnw4foy4vo1Y/o3pTo6Jjo8Zvo+5jp/5bpjoPnkITnk4XnloXnm4bnoYfnqYnnsIvnuY7nwZDnypTo1Jjo3Zvo55/o8aLo+qDp/57qio3mjI7mj4/mk4/nmJDmn5HnppPnr5Xnt5fnv5nnyJzn0p/o3KPo56fo8Kro+qfp/6Xqf5PmgpTmhpXmjJfmk5nmm5rmopvmq53mtJ/mvaHmx6Tn0afn2qrn5a7o77Ho+K/p/63qc5rldpvmeZvlfpzmhZzmj57mnKPmpqXmsKfmuqnmxKzmz6/n2bLn5LXo77np+Lfp/7XqaaXka6Xkb6XldabkfKblhablkKflm6nlqq/ltrHmwbPmzLbn2Lnn473o7sHp97/p/77qarLkbLPlb7LkdLPlerLlgbLliLLkkrLkn7PlrLblvLvmyb7m1sHn4sXo7cjp98nq/8fpbMDlbsDmcMDldcDle8Dlgb/lib/kkr/km7/kpb7kssDlw8Xm0sjn4Mzo7NDp9tLq/tHpb83ncM3mc83md83mfc3ng83ni83mlM3mnc3mps3msMzlu8zlys7m3NTn6tjp9dvr/tnpctvndNzodtvnetvngNzohtznjdzoltzooNzoqdzotNznvtznytzn1tzn6ODp9eTr/+Prdevqd+vqeevpfevpguvqievpkOvqmOvpouvqrOvqt+vpw+zqzuvp2+zq5+3r9O7s/+7sePrrefrre/rrf/nrhfrri/nrk/nrnPrspfrrsPrsuvrrxvrr0vrs3frs6Pns8vns//rspHD1pXH1p3L1qXL0rHP0sXX0t3j0vXr0xH70y4H004X024n0447z7JPz9pjz/5j0/5b0o3L0pHL0pnT1qXT1rHX0sXf0tnn0vXz0xH/0yoL00obz2orz44/z7JPz9Zjy/pnz/5f0o3f0pHj0pnj0qXn1rHr0sXv0t370vYD0w4P0yob00or02o7045Lz7Jbz9Zry/pzz/5r0o330pH70pn70qH/0rID0sIH0toP0vIX0w4jzyov00o7z2pL045Xz65nz9Z7z/p/0/530o4X0pIX0pYb0qIf0q4f0sIn0tor0u4zzwo7zypH00ZTz2pfz45vz7J/z9aPz/qP0/6H0oYz0oo3zpI30p470q4/0r4/0tZH0u5PzwpXzyZfz0Zrz2Z3z4qDz66Py9Kfz/ajz/6X0n5TzoZX0o5bzppb0qZfzrpjzs5nzuprzwJzzyJ7z0KHz2KPz4abz66nz9Kzz/a7z/6z0nZ30n570oZ70o57zp57zrJ/zsqDzuKLzv6Pzx6Xzz6fz16nz4azz6q/z87Lz/LT0/7H0maT0m6T0naX0oKXzpKXzqabzr6fztanzvarzxKzzzq3z1rDz4LLz6bXz87jz/Lr0/7j0jKXzjqbzkaf0laj0m6rzo6zzq67zsq7zurDzwrLzy7Tz1bbz37jz6Lvz8r7z+8Dz/770hq7ziK7ziq7zjq/0kq/0mbDzoLH0q7Tztrfzv7nzybrz073z3r/06ML08cTz+8f0/8b0gbjzgrjzhLnzh7jzjLjzkrjzmrnzorr0rLvzur/0xcL00cT03Mb05sjz8cz0+8/1/871gMTzgcT0hMT0hsT0isTzkMT0lsPzncT0psT0sMX0vMb0zMr02M305M/08NP1+dX0/9b1gND1gtH1hND1h9D1i9D1kND1ltD0ndD1pdD1rdD1ts/0w9D009T14df17tr1+d31/972gN72gd31hN72ht72it32kN72lt72nd72pd31rt72t972wd32y9z12d326+L2+OX2/+f3gOv3gOv2g+z3hev3iuv3j+v3luz3nez3pez3ruz3uOv3wuv3zev32Ov35Ov39e33//D4ffn3f/n4gPn3hPn3iPn3jvn4lfn3nfr4pfr4r/r4uPn3w/r4z/n42vr45vr49Pv5//v5\",warm200:\"AAAABAAADQAAFwAAJQAANQAASwAAYgAAegAAkQAApwAAugAAygAA2AAA5wAA9gAA/wAAAgYABgYAEAUAGgUAKAQAOAMATgMAZQEAfAEAkwAAqAAAugAAyQAA1wAA5gAA9QAA/wAABhICCxICEREBHBABKg4AOw0AUAsAZwkAfgcAlQUAqgMAuwIAywEA2QAA5wAA9AAA/wAADSEGESAGFh8FHh4ELR0DPxsCVBkBaxcAgRQAmBEArQ4AvgoAzAcA2gQA6AIA9gAA/wAAFDQMFzQLHTMLJjIKMTAIRC4GWiwDcCkChiYAnCMAsB8AwRsAzxYA3RAA6wsA+AYA/wIAEUwSFUsSGksRIUoQM0gOSUcMX0UJdkIGjD8DojwBtTcAxTMA1C0A4ScA7yAA/BcA/w4AAGQYAWQYCGMXIGMWNmIUTmASZV8Pe10MkloJqFcGulQEylAC2EsB5kQA9D0A/zQA/ykABXwcB3wcD3wbH3saO3oZU3kXangVgXYSmHQQrHINvm8KzmwI3WgF62QD+V4C/1YB/0wAApMfCJMfFZMeKJIdQpIcWpEbcJAZh48XnY0UsYwSwooQ0ocO4IUM7oEJ/X0H/3cF/3ADCKUgFKUgI6UgN6UfTaQeY6QdeKMbjqIZo6EYtaAWxp8U1Z0T45sR8ZkP/5YN/5IK/40IIbYjKrYiOLUiSLUgWrUfbrQegrQclrMbqbIaurEZybAX168W5q4V9KwT/6oS/6cQ/6MOPsUpRMUoTcQoWcQmacQlesQjjcMgnsIdr8IavsEZzMAY2r8X6L4W9r0V/7sU/7kT/7YRVtMvWtMvYdMva9IueNIsh9Iql9EoptEmtNEjw9Ah0M8e3s8b684X+cwV/8sU/8kT/8cSbN83b983dd82fd81iN80lN8zod4xrd4vut4tx90s1N0p4dwn7tsk+9sg/9od/9gY/9YRgOo/g+o/h+o+juo9luo8oOo7quo6tek5wek4zOk22Ok05egy8ugw/uct/+Yq/+Um/+QhlPNFlvNFmfNEnvNEpPNDrPNCtfNCvvJAyPI/0/I+3vI86vE79vE5//E2//Az//Aw/+8spfxIp/xIqfxHrfxHsvxHuPxGwPxFyPxE0vxD2/xC5fxB8Ps/+/s9//s7//s4//o1//owAAACAwABCgABFAABIgAAMwAASQAAYAAAeAAAkAAApgAAuAAAyAAA1wAA5gAA9AAA/wAAAQUFBAQEDQQEFwMDJQMCNgIBSwIAYgEAeQAAkQAApgAAuAAAxwAA1gAA5QAA8wAA/wAABRAICQ8HDw8GGg4GJwwEOQsDTgoBZQcAfAYAkwQAqAMAugEAyQEA1wAA5QAA8wAA/wAADB8MDx4MFB0LHRwKKxsIPRkGUxcDaRUCgBIAlw8AqwwAvAkAywYA2QMA5wEA9QAA/wAAFDISFzIRHDERJDAPLy4OQiwLWCoIbygFhSUDmyEBrx0AwBkAzhQA3A8A6goA9wUA/wEAEkoXFUoXGUkWIUgVMkcTSEURXkMOdUELiz4HoToEtDYCxDEB0ywA4CUA7h4A+xYA/wwAAGMdAmMcB2McH2IbNWEZTV8XZF4UelwRkVkOp1YLuVMIyU4F2EkD5UMC8zwA/jIA/ycAA3whBnwgDnsgHXsfOXodUnkbaXgZgHYXl3QUrHERvm8PzWwM3GgK6mMH+F0E/1UC/0sBAZMjBZMjFJIiJpIhQJEgWJEfb5Adho4bnI0ZsIsWwYkU0YcS4IQQ7oEN/HwL/3cI/28FBqUlD6UkIKUkNKUjS6QiYaQhd6MfjaIdoqEbtKAaxZ4Y1J0X4psV8JkT/pYR/5IP/4wMHLYqJrUpNbUoRrUnWbUmbLQkgbQhlbMfp7IdubEcyLAb168a5a4Y86wX/6oW/6cT/6MSPMUwQsUvS8QvV8QuZ8QsecQqi8MoncImrcIjvcEgy8Ad2b8b574a9b0Z/7sY/7kW/7YVVNM3WNM2X9M2adM1d9I0htIyltIwpNEus9EswdAqz88o3M8l6s4i+M0f/8sb/8kX/8cWauA/bd8+c98+e989ht88kt87n985rN44ud42xt000t0y4Nww7dwu+tsr/9oo/9gk/9Yff+tFgepFhupFjOpElepDnupCqepBtOpAwOk+y+k91+k75Og58Og3/ec1/+Yy/+Yv/+QqkvNLlPNLl/NLnPNKovNKqvNJs/NIvfNHx/JG0vJF3fJD6fJC9fFA//E+//A7//A4/+80pP1Ppf1Pp/xOq/xOsfxOt/xNv/xMx/xL0PxK2fxJ5PxI7/tG+vtF//tD//tA//o9//o5AAAHAgAGCAAFEwAEIAADMQACRwABXwAAdwAAjwAApQAAtwAAxwAA1gAA5QAA8wAA/wAAAAQLAwMKCwMJFQMIIwIHNAEFSQEDYQEBeAAAkAAApQAAtwAAxwAA1QAA5AAA8wAA/wAAAw8PBw4ODQ0NGAwMJgsKNwoITQgFZAYDewUBkgMApwIAuQEAyAAA1gAA5AAA8gAA/wAACh0TDRwSExwSGxsQKRkPPBcMURYJaBMGfxEDlQ4BqgsAuwcAygUA2AIA5gEA9AAA/wAAEzAYFjAYGy8XIy4WLSwUQSoSVygPbSYLgyMHmh8ErhsCvhcBzRMA2w4A6QkA9gQA/wEAEUkeFEgeGUgdIUccMEUaRkQYXUIVcz8SijwOoDgKszQHwy8E0SoC3yQB7RwA+hQA/wsAAWIjAmIjBWIiHGEhM2AfS14dYl0beVsYkFgVplUSuFEOyE0L1kgI5EIG8joD/jAB/yUAAnsmBXsmDXsmG3olN3kjUHgiaHcffnUdlXMaqnEYvG4VzGsS22cQ6WIN91wK/1QH/0oEAZIqApIpEZIoI5IoPZEmVpAlbY8jhI4hm40fr4sdwIkbz4cZ3oQX7IAV+nwS/3YP/24MA6UvCKUuGqUuMKUsSKQrX6QpdaMmi6IkoKEis6Agw54f0p0e4Zsc75ga/ZUY/5EW/4wUErY1H7U1MLU0QrUzVrUxarQwfrQtk7MrprIot7ElxrAj1a8h460f8awe/qod/6cb/6MZNsU8PcU8RsQ7VMQ6ZMQ5dsQ3icM1m8Izq8Ixu8EuycAs178q5r4n870k/7sh/7ke/7YcUNNCVNNCW9NCZtNBdNI/g9I+k9I8otE7sdE5v9A3zc812s8z6M4x9s0u/8sr/8kn/8cjZuBJauBJcOBIeN9Ig99HkN9Fnd9Eqt5Dt95BxN5A0N0+3tw869w6+Ns4/9o1/9gy/9cufOtQfutQg+tPiepPkupOnOpNpupMsupLvepKyelI1elH4uhF7uhD++dB/+c//+Y8/+U5j/NWkfNWlPNVmfNVoPNUqPNUsfNTuvNSxfNR0PJQ2/JO5/JN8/FL/vFK//FH//BF/+9Bof1Zo/1Zpf1Yqf1Yrv1Ytf1XvPxWxfxWzvxV1/xU4vxS7fxR+PtQ//tO//tM//tJ//pFAAAOAQANBwAMEQALHgAJMAAHRgAFXgACdgABjgAApAAAtgAAxgAA1QAA5AAA8gAA/wAAAAMTAgMSCQIREwIQIQIPMgEMSAEJXwAGdwADjgABpAAAtQAAxQAA1AAA4wAA8gAA/wAAAg0XBQ0WCwwVFgsUJAoTNQgQSwcNYgYJeQQGkQMDpgIBtwAAxgAA1QAA4wAA8QAA/wAACBsbCxsbERoaGRkZJxcXOhYVTxQRZhIOfQ8KlAwHqAkEuQYCyAQB1wIA5QEA8gAA/wAAES4hFC4gGC0gICwfKyodPygaVSYXayQUgiEQmB0NrBkJvRUGyxEE2QwC5wcB9AMA/wAAEUcnFEcnGUYmIEUlLkMjREIhW0AecT0biDoXnjYUsTIRwS0N0CgK3SIH6xoE+BIC/wkBAWEsAmEsBGArF18qMF4pSF0nYFskd1kijlYfpFMbtk8ZxksW1EYT4j8Q8DgM/C4I/yMEAHoyAnoxC3oxGXkvMnguTXcsZXYqfHQnk3IlqHAium0gymke2GUb52EZ9FoW/1IT/0cOAJI4AJI3CpI3H5E1OZA0U5Ayao8vgo0tmIwqrIoovogmzYYk3IMi6n8g+Hse/3Ub/20YAKU+BKU9EqU9KqQ8Q6Q6W6M4cqM2iKI0naExsJ8uwZ4s0Jwp3pon7Jgl+5Uj/5Eh/4sfCLVEEbVEJ7VDPLVCUbVBZrQ/e7Q9kLM7o7I5tLE2xLA00q8y4a0w76wt/Kkq/6Yn/6IkLcVLNcVKQMVKTsRJX8RIcsRGhcNEl8NDqMJBuME/x8A91b8747458b02/rs0/7kx/7YtSdNRTtNRVtNQYdNQb9JPf9JNkNJMn9FKrtFJvNBHytBF2M9E5c5C880//8s9/8k6/8c3YeBYZeBXa+BXdOBWf99VjN9Umd9Tpt9StN5Rwd5Pzt1O291M6NxK9ttI/9pG/9lE/9dAeOteeutef+tehetdjutcmOpco+pbrupauupYxulX0ulW3+lU7OhT+OhR/+dP/+ZN/+VKi/RkjfRkkPRjlfRjnPNipPNirfNht/NgwvNfzfNe2PJd5PJc8PJa/PFY//FX//BV//BSnf1nn/1nof1mpf1mq/1msf1luf1kwv1ky/xj1fxi3/xh6vxf9vxe//xc//tb//tY//pVAAAYAQAWBQAVDwAUHAATLgAQRAANXAAKdAAHjAAEogACtQABxQAA1AAA4gAA8QAA/wAAAAMdAQIcBwIbEQIaHgEZMAEWRQATXQAQdQAMjAAIogAFtAADxAAC0wAB4QAA8AAA/gAAAQwhBAsgCQogEwofIQgdMwcbSQYYYAUVdwMRjwINpAEJtQAGxAAE0wAD4QAB8AAA/QAABhkmCRklDhglFhckJRYiNxQgTRIdZBAaew4WkgsSpggPtwULxgMJ1QEG4gAE8AAC/QABDiwsESwrFSsrHSoqKCgoPCYmUiQjaSIgfx8clhsZqhcVuhMSyQ8P1woM5QYJ8gIG/gADEUUyE0QyF0QxHUMwK0EvQT8tWD0qbjsohTgkmzQhri8evisbzSUY2h8U6BgR9RAN/wgJAl86Al85BV85EF44K102RVs0XVkydFcvi1QsoVEps00mw0kk0kMh3z0e7TUb+SwX/yASAHlBAHlBCHlAFng/LXc9SXY7YXU5eXM2kHE0pW4xt2sux2gs1mQq5F8n8Vgl/lAh/0UdAJFIAJFIApFHGJBGMpBFTo9DZo5Bfo0+lYs7qYk5uoc2yoU02YIy534v9Xks/3Qq/2snAKVPAKVOB6ROIaRNPKRLVqNKbaJIhKFFmqBDrZ9BvZ0/zJw925o66Zc4+JQ1/5Ay/4ovALVVBrVVGLVUM7VTSrVSYbRRd7NPjLNNn7JLsLFJwLBHz65F3a1D7KtB+qk+/6Y7/6I4H8VbKcVbN8VbSMRaWcRZbcRXgcNWk8JUpMJStMFRw8BP0b9N4L5L7r1J+7tH/7lF/7ZCQNNiRtNiT9NhW9NhatNge9Jei9Jdm9FbqtFauNBZx9BX1M9W4s5U8M1S/ctQ/8lO/8dLW+BoX+BoZeBobuBneuBmh99lld9kot9jsN5ivd5hyt1f191e5dxc8ttb/tpZ/9lW/9dUcutvdOtueetugOtuiettk+tsnuprqupqtuppwupoz+ln2+lm6Ohk9ehj/+dh/+Zf/+VchvR0iPR0i/RzkfRzmPRzoPRyqfNxs/NwvvNwyfNv1fNt4PJs7fJr+fJp//Fo//Fl//Bjmf13mv12nf12of12pv12rf11tf10vv10x/1z0f1y3P1x5/xw8vxu/fxt//xr//tp//tmAAAiAAAhAwAgDAAfGgAeKwAcQQAZWgAWcgATigAPoAAMswAJwwAH0gAF4QAD7wAC/QABAAIpAAIoBAInDQEmGwElLQAjQgAgWgAccgAZigAWnwASsQAPwgAN0AAK4AAI7gAF/AAEAAsuAgotBgksDwgsHgcqMAYoRQUlXQQidAMfjAEboQEYsgAVwgAS0AAP3wAM7QAJ+wAHAxgzBhczChYyExUxIRQwNBIuSRArYA4oeAwljwkhowYetAQbwwMY0gEW4AAS7QAP+wALCio6DSk6Eig5GSc4JCY3OCQ1TiIyZR8vfBwskxkpphUltxEjxg0g1Agd4gUa7wIW+wASDkJCEEJCFEFBG0BAKD8/PT09VDs6azg4gjU0mDExqywuuygrySIo1xwl5RYi8g4f/gYbAl1KA11KBlxJDFxJJVpHQFlFWVdDcFVAh1I9nU46r0o3wEY1zkAy3Dov6TIs9igo/x0kAHhSAHhSBXdRE3dQJnZPQ3RNXXNLdXFIjG9FomxDtGlAxGY+0mI84F057lY2+00z/0IvAJFaAJBZAJBZD5BYKo9WSI5VYo1TeoxQkYpOpohLt4ZJx4RH1YFF5H1D8nhA/3I9/2k5AKRgAKRgAKRfFKReNKNdUKNcaKJagKFYlqBWqZ5Tup1SyZtQ2JlO5pZM9JNJ/49G/4lEALVnALVnB7VmJ7VlQrRkW7RjcbNhh7Jfm7JdrLFbvK9ay65Y2q1W6KtU9qhS/6VQ/6FNEsVtGMVtKsRsPsRsUsRrZ8NpfMNoj8JmoMJlsMFjv8Bizr9g3L5f6rxd+Ltb/7hY/7VWNdN0O9NzRtNzU9NyY9NxddJwhtJvltFupdFttNBrwtBq0M9o3s5n7M1l+stj/8lh/8dfUuB6V+B6XuB5aOB5dOB4gt93kN92nd91q950ud5zxt1x091w4dxv79tt/Npr/9lp/9dna+t/but/c+t/eut/g+t+jut9met8pet8sep7vup6y+p41+l35Ol28eh0/edz/+Zx/+VvgPSEgvSEhvSDi/SDkvSDm/SCpPSBr/SBufOAxfN/0fN+3fN86fJ79fJ6//J4//F2//B0k/6Glf6GmP6GnP6Gof6FqP6FsP6Euf2Dw/2Dzf2C2P2B4/2A7/1++vx9//x8//x6//t3AAAwAAAvAgAuCAAtFgAsKAArPgAoVwAlcAAiiAAengAbsAAYwAAWzwAU3gAR7QAO+wALAAI3AAE3AgE2CQE1FwE0KQAyPwAwVwAtbwAphwAmnAAjrwAgvwAezgAc3QAZ6wAW+QATAAk9AQk9Awg8Cwc7GQY6LAU4QQQ2WQMzcQIwiAEsnQAprwAmvgAkzQAh3AAe6gAc+AAZARVDAxVDBxRDDhNCHBJALxA/RQ48XAw5dAo2iwczoAUwsQMtwAEqzgAo3AAl6gAh9wAeBidLCCZKDSVKFSRJICNINCFGSh9DYRxAeBk9jxY6oxI3sw80wgsy0Acv3gMs6wEp+AAlCj9TDD9TED5SFz1RJTtQODpOUDdMZzVJfjFGlC1DpylAtyQ9xh861Bk44RM17gsx+gUuAltcA1pbBlpbDFlaHlhZO1ZXVFRUbFJShE9PmUtMrEdJvEJHyj1E2DZB5S4+8iU7/Rk3AHZkAHZkAHVjDXViIXRhPXJfWHFdcW9aiG1YnmpVsGdTwGNRz19O3VpM6lNJ90pG/z5CAI9sAI9rAI9rBI5qIo5oQY1nXIxldYpjjYlgoodes4Vcw4Ja0n9Y4HtW7nZT/G9R/2ZNAKRzAKNyAKNyBaNxKqJwSKJuY6Fse6Bqkp9opZ1mtpxkxZpj1Jhh45Vf8ZJd/o1a/4dXALV5ALV5ALR4E7R4OLR2U7N1bLNzgrJyl7FwqLBuuK9tx65r1qxp5Kpo86hm/6Vj/6BhCMR/DMR/GcR/M8R+SsR9YMN8dsN6isJ5nMF3rMF2u8B1yr9z2L1x5rxw9Lpu/7hs/7RqJdOGLtOGOtOFStOEXNOEbtKCgNKBkdGAodF/sNB9vs98zM972s556Mx49st2/8l0/8dySOCLTeCLVeCKYOCKbeCJfOCIit+HmN+Gpt6FtN6Ewt2D0N2B3dyA69t++Np9/9l7/9d5ZOyQZ+yQbOyPc+yPfeuOieuOlOuNoOuMreuLuuqKx+qJ0+mI4emG7uiF+uiD/+eC/+WAe/WUfPWUgPWUhfWTjfSTlvSSn/SSqvSRtfSQwfSPzfOO2fON5fOL8vKK/fKJ//GH//CFjv6WkP6Wkv6Wl/6VnP6VpP6VrP6Utf6Tv/6Syf6S1P2R4P2Q6/2O9v2N//2M//yK//yIAABAAAA/AAA/BQA+EgA9JAA7OwA5UwA2bAAzhQAwmgAtrQArvQApzAAm2wAk6gAh+AAfAAFIAAFIAQBHBQBHEgBFJABEOgBBUgA+awA7gwA4mQA1qwAzuwAxygAv2gAs6AAq9gAnAAdOAAdOAQZNBgVNFAVMJwRKPQNHVQJFbQFChQA+mgA7qwA4uwA2ygA02QAy5wAv9QAtABNVARJUAxFUChBTFw9SKg5QQAxOWApLcAhIhwZFnARCrQI/vAE9ywA62QA45wA19AAyAyNcBCNcCCJbECFbGyBZLx5XRRxVXBlSdBZPixNMnxBJrwxHvghEzAVC2gI/6AA89AA5BjxkCDtkDTpkFDljIjhhMzZfSzNdYjFaei1XkClUoyVRsyBPwhtN0BZK3Q9H6glE9gNBA1dtBFdtB1ZsDFZsGFRqNlNoT1FmaE5jgEthlUdeqENbuD5ZxjhW1DJU4SpR7iBN+RVKAHN2AHN2AHN1BHJ0G3FzN3BxU25vbGxshWpqmmdnrGRlvGBjy1th2VZe5k9c80VY/jlVAI5+AI5+AI19AI18F4x7OYt5V4p3cYl1iIdznYVxr4Jvv39tznxr3Hhp6nNm+Gxk/2NgAKOFAKKFAKKEAKKDHKGCQKGBXaB/dp99jZ57oJx5sZp3wZl10JZ035Ry7ZBw+4tu/4VrALSLALSLALSLA7SKLLOJS7OHZrKGfbGEkrCCpK+AtK5/w6190qt84al676Z4/KN2/590AcSRBMSQC8SQIsOPQMOOWcONcMKMhMKKl8GJp8CHt7+Gxr6E1L2D47uB8bl//rd9/7R7GNOWHtOWLdOWQNOVVNKUZ9KTetKSjNGQnNGPq9COus+NyM6L182K5cyI88uG/8mE/8aCPeCbQ+CbTOCbWOCaZuCZduCYhd+XlN+Wot6VsN6Uvt2TzN2R2tyQ59uP9dqN/9mL/9aJXOyfX+yfZeyfbuyed+yeg+udj+ucnOubqeuatuqZw+qY0OmX3emW6uiU9+iT/+eR/+WPdPWjd/WjevWigPWiiPWikfWhm/SgpfSfsfSevfSdyfSc1vOb4vOa7vOZ+vKX//KW//GUif+liv+kjf+kkv+kmP+kn/6jp/6isf6iu/6hxf6g0f6f3P6e6P2d8/2b/v2a//2Z//yXAABSAABRAABRAgBQDQBPHwBONgBLTwBIaABGgQBClwBAqQA9ugA7yQA52AA35wA19QAyAABaAABZAABZAgBYDQBXHwBVNgBTTgBQZwBNgABLlQBIqABGuABExwBC1gBA5QA98wA7AAVgAAVfAARfAwReDwNdIgNcOAJZUAFWaABTgQBQlgBNpwBLtwBJxgBH1QBF5ABD8gBAABBmAA9mAQ9lBg5lEQxkJQtiPAlfUwhdawZagwRXlwNUqQFSuABPxgBN1QBK4wBI8QBGASBtAh9tBB5tCx1sFhxrKRppQBhmWBVkbxNhhhBemg1bqwlZugZXyANU1gFS5ABP8ABMBDd2BTd2CTZ1ETV0HjNzLzFxRi9vXSxsdShpiyRmniBjrhxhvRdfyxFc2Qta5gZX8gJUBFN/BVN/BlJ+DFF9F1B8ME56Skx4Y0l1e0ZykUJwoz5tszlrwjNo0Cxm3SRj6Rtg9RFcAHCIAHCHAG+HAG+GFG6FMGyDTmuBZ2h+gGZ8lmN5qGB3uFx1x1dz1VFw4klt7z9q+jNnAIyQAIuPAIuPAIuOB4qNMYmLUYiJbIaHhISEmYKCq3+Au3x+ynl82XV65m949Gh1/15yAKGWAKGVAKGVAKCUC6CTN5+RVp6QcZ2OiJyLnJqJrZmIvZeGzJSE25KC6Y6A94l+/4J7ALOcALObALObALOaHbKZQ7KXX7GWeLCUja+SoK6QsK2PwKuNzqqM3aiK66WI+aKG/52DAMOhAMOhBMOgFcOfNsOeUsKdasKbf8GaksCYo7+Xs76Vwr2U0byS37qR7biP+7aN/7KLC9OlEtOlHtKlNdKkTNKjYdKiddGhh9GfmNCep8+dts+bxc6a082Y4syX8MqV/ciT/8WRMeCqOOCpQuCpUOCoYOCocN+ngN+mj9+knt6jrN6iut2hyN2f1tye5Nud8tqb/tiZ/9aYVOytWOytXuytZ+yscuyrfuuri+uql+uppOuosuqnv+qmzeqk2umj5+ii9Oig/+ef/+WdbvWwcfWwdfWwe/WvgvWvjPWulvWtofStrfSsufSrxfSq0vSo3/On6/Om9/Kk//Kj//GihP+yhv+xiP+xjf+xk/+xm/+wo/+vrf+vt/+uwv6tzf6s2f6r5f6q8P6p+/2n//2m//2kAABjAABjAABiAABiCABhGwBgMgBdSwBbZQBYfgBVkwBSpgBQtgBOxQBM1QBK4wBI8QBGAABrAABrAABqAABqBwBpGgBnMQBlSgBjYwBgfABdkgBapABZtABXwwBV0wBT4QBR7wBPAARxAANxAANxAQJwCQJvHAFtMgFrSwBoZABlfABikQBgowBetABcwwBa0gBY4ABW7gBUAA14AAx4AAt3Agp3Cwl1Hwh0NgdxTgVvZwRsfgJpkwFmpABktABhwgBf0QBd4ABc7gBZABt/ABp/Ahp+Bhl+ERd8JBZ7OhR4UhF1ag9yggxvlgltpwZrtgRoxAJm0gBk4ABh7QBfAjGHAzGHBzCGDi+GGi2EKSuCQCmAWCZ9cCJ6hh93mht0qhdyuRJwxw1t1Qhr4gNo7gFlAk6QBE2PB0yPC0uOGEqNKkiLRUaIXkOGdkCDjDyAnzd9rzJ7vSx4yyV22R5z5RVw8QxtAGyXAGuXAGuXAGqWCWmUKmiTSGaQY2SOfGGLkV6JpFuGtFaEw1GC0Ut/30N86zh59it2AImfAImfAIieAIidAIecKIaaS4SYZ4OWgIGTlX6Rp3yPt3mNxnWL1XCJ42qG8WOE/FiAAJ+lAJ+lAJ+kAJ+jBJ6iLp2gUJyfbJuchJqamZiYqpeXupSVyZKT2I+R5ouP9IaM/36KALKqALKqALKpALGpELGnO7CmWrCkc6+iia6gnK2fraudvKqby6ia2qaY6aOW9qCU/5uSAMKvAMKuAMKuC8KtKsKsSsGrZcGpe8Cnjr+moL6ksL2jv7yhzrug3bme67ec+LSa/7GYANKzBtKyEtKyKNKxQ9GwW9GvcNGug9CslM+rpM+qs86ows2n0Myl38uk7cmi+seh/8SfJOC2K+C2OOC2SOC1Wd+0at+ze9+yi96xmt6wqN2vt92txdys09ur4dqp79mo/Nim/9WkTOy5UOy5V+y5Yey4bOy3eOu3huu2k+u1oOu0ruqzvOqyyuqw1+mv5eiu8uis/eer/+WpaPW8a/W7b/W7dfW7ffW6h/W6kvW5nfW4qfS3tfS2wvS1z/S03POz6fOy9fKw//Kv//Guf/+9gf+9g/+9iP+9jv+8lv+8n/+7qf+7s/+6vv+5yv+41v634v627f60+P6z//2y//2wAAB1AAB1AAB1AAB0BAB0FQByLQBwRgBtYABqeQBnkABlogBjsgBhwgBf0QBd4ABc7gBZAAB9AAB9AAB9AAB8BAB7FAB6KwB4RAB1XwByeABvjgBtoABrsQBpwABnzwBl3gBk7ABiAAKDAAKDAAKCAAGCBAGBFgB/LQB9RQB6XwB3eAB0jgByoABwsABuvwBszgBq3QBo6wBmAAmJAAmIAAiIAAeIBgaGGQWFMASCSAN/YQJ8egF5jgB3oAB0sAByvwBxzgBv3QBt6gBrABaPABaPABWOAhSOCxOMHhGLNQ+ITQ2FZQqCfQh/kQV9ogN6sQJ4wAB2zgBz3ABx6gBvACuWASqVAymVCCiUFCaTIyWROyKPUx+MaxyJghmGlRWDphGBtQ1+wwh80QR63gF36gB0AUeeA0edBkadDUWcF0ObJ0GZQD+WWjyTcjiQiDSOmzCLqyuIuSWGxx6D1ReB4g9+7Qd7AGemAGelAGalAGWkAmSiJWOgRGGeX16ceFyZjliWoFSUsFCRv0qPzUOM2zuK5zCG8iODAIWtAIWsAIWsAISrAIOpH4KoRoClY3+jfH2hknqepHectHSaw3CY0muW4GWT7V2Q+VGNAJ2yAJ2yAJ2xAJyxBJyvJJuuS5qsaJmpgZenlZalp5Sjt5Ghxo+f1Yud44eb8YKZ/XmWALC3ALC3ALC2ALC1C6+0Mq+yVK6xb62vhaytmKurqampuaioyaam16Sk5qGi9J2g/5ieAMG7AMG6AMG6BMG5IMG4Q8C3X7+1dr+0ir6ynL2wrLyvvLuty7ms2riq6Lao9rOm/6+kANG+ANG+B9G+HdG9OtG8VNC7atC6fs+4kM+3oM62sM20v8yzzsux3Mqw6siu98as/8OrGd/CH9/CK9/BPt/BUt/AZN+/dt6+ht69lt28pd26tNy5wty40du239q17Nmz+dey/9WwQuzFR+zFT+zEWezEZezDc+vCgevCj+vBnOvAquq/uOq9xum81Om74ui57+e4++a3/+W1YfXHZPXHaPXHb/XHePXGgvXGjfXFmfXEpfXDsvTCv/TBzPTA2fO/5vO+8vO8/fK7//G6ef/Je//Jfv/Jg//Jif/Ikv/Im//Hpf/Hr//Gu//Fx//E0//D3//C6v7B9f6///6+//29AACHAACHAACGAACGAQCFEACEKACBQQB+XAB8dQB5jAB2ngB0rwByvgBwzgBv3QBt6wBrAACOAACOAACNAACNAQCMDgCKJgCIQACFWwCCdAB/igB9nQB7rQB5vQB3zAB12wB06QByAAGSAAGSAAGSAACRAQCQEACOJwCMQACJWwCGdACDigCBnAB/rQB9vAB7ywB52gB36AB2AAaXAAWXAAWXAASWAwSVEwOTKgKRQwGOXQCLdQCHigCFnACDrQCBvAB/ywB92gB76AB5ABGdABCdABCcAA+cBg6aGAyYLwqWSAiTYQaQeQSNjQOKngGIrgCFvACDywCB2gB/5wB9ACOjACOjACKiBCGhDh+gHh2eNhubThmZZhaWfhOSkQ+QoguNsQiLvwWJzQKG2wCE5wCBAT+qAj+qBD6pCT2oFDunJTmlPDeiVTSfbjCchCyZlyeXpyKUtR2SwxeP0RCM3gqK6gSHAGGyAGCxAGCxAV+wBV6uH1ysQFqqW1endFSlilGinUyfrUedu0GayjqY1zKV5CeS7xuOAIC4AIC4AIC4AH+3A361GH2zQXyxX3qveXisj3WqoXKosW6mwGqjz2Wh3V6e6lWc9kiYAJq+AJq+AJq9AJm8AZm7G5i5RZe3ZJW1fZSzkpKxpJCvtI6tw4ur0oep4YKn73yk+3OiAK7CAK7CAK7CAK7BBK2/Kay+Tqy8aqu6gqq4lai3pqe1tqWzxqOy1aGw456u8Zqs/ZSpAMDGAMDGAMDGAL/FFr/EO77CWb7Bcr2/h7y+mbu8qbq6ubm5yLi317a25rO087Cy/6ywANDKANDKAdDJEdDJL9DITc/GZc/Fes7EjM3Cnc3BrMzAvMu+y8q92si76Me69cS4/8G2Bt/NEd/NHt/NM9/MSd7LXd7KcN7Jgd3Ikt3HodzGsNzFv9vDztrC3NnA6ti/99a9/9S8NezQO+zQRezQUevPX+vPbevOfOvNiuvMmOrLp+rKterJw+nI0ejG3+jF7OfE+ObC/+TBWfbTXPbTYfbTafXScvXSfPXRiPXQlPXQofXPrvTOu/TNyfTM1vTK4/PJ7/PI+vLH//HFdP/Vdv/Vef/Vfv/VhP/Ujf/Ulv/ToP/Sq//Rt//Rw//Q0P/P3P/O5//N8v7L/P7K//7JAACWAACWAACWAACVAACUCgCTIgCQPQCNWACKcgCHiQCFmwCDrACBuwB/ywB92gB76AB5AACcAACcAACbAACbAACaCQCYIQCWOwCTVgCQcACNhwCLmgCIqgCGugCFyQCD2ACB5gB/AACfAACfAACfAACeAACdCgCcIgCZPACXVwCUcACRhwCOmQCMqgCKuQCIyQCG2ACE5gCDAAOkAAOkAAKjAAKjAAGiDQGgJQCdPgCaWACXcQCUhwCRmgCPqgCNuQCMyACK1wCI5QCGAAypAAupAAuoAAqnAgmmEgikKgaiQwWfXAOcdQKZiQGWmwCTqgCRuQCPyACN1wCL5QCKAByuABuuABuuARmtCBirGBaqMBSnSRKkYg+heQyejQmbngaZrQSWvAKUygCS2ACP5QCNADa1ADW1AjW0BjOzEjKyIzCwNy2tUSqqaSenfyOkkh+hohqfsRWdwBCazgqY2wWV5wGSAFm9AFm8AVi8A1e7Cla5G1S3PFG1V0+ycEuvhkesmUOqqT2nuDelxjCi0yef4B6c6xKZAHvEAHrDAHrDAHnCAHjAGXe+PXa8XHO6dXG3i261nmuyrmewvWKuzFys2lWp50um8j2iAJbJAJbJAJbIAJXHAJXGGJTEQJLCYJHAeY++j428oYu6sYi4wYW20IG03nyy7HWv+GusAKzOAKzOAKzNAKvMAavLIarJSKnHZqjFfqfDkqXCo6TAtKK+w6C90p274Zq575a3+4+1AL7SAL7SAL7RAL3QCb3PMbzOU7zMbbvKg7rJlbnHprjFtrfExbXC1bPB47G/8a69/am7AM/WAM/VAM/VA87UI87TRc7SX83Qdc3PiMzOmcvMqcrLucnJyMjI18fG5cXF88LD/r/CAN7ZAd7ZDd7YJt7YP93XVt3Wat3VfNzTjdzSndvRrdvQvNrOy9nN2djL59bK9NXJ/9LHJuvcLevcOOvbR+vbV+vaZuvZdurYherXlOrWo+rVsenUwOnTzujS3OfQ6ebP9eXO/+PMT/bfU/beWfbeYfXea/Xdd/Xdg/XckPXbnPXaqvTZt/TYxfTX0/PW4PPV7PPU9/LS//HRbf/hb//hc//geP/gf//gh//fkf/fnP/ep//ds//cv//bzP/a2P/Z5P/Y7//X+v/W//7UAACkAACjAACjAACiAAChBgCgHQCeOQCbVACXbgCVhQCSmACQqQCNuQCMyACK1wCI5QCGAACpAACpAACoAACoAACnBQClHACjNwCgUwCdbQCahACXlwCVqACTtwCRxwCP1gCN5ACMAACsAACsAACrAACrAACqBgCoHQCmOACjUwCgbQCdhACalgCYpwCWtwCUxgCT1QCR4wCPAAGvAAGvAACvAACuAACtBwCrHwCpOQCmVACjbQCghACelwCbpwCatwCYxgCW1QCU4wCSAAe0AAa0AAazAAWzAASxDAOwJAKtPQKqVwGncACkhQChlwCfpwCdtwCbxgCZ1QCX4wCWABS5ABS5ABO4ABK4AxG2Eg+0Kg2yRAuvXQmsdQapiQSmmgKkqQGhuACfxwCd1QCb4wCZACy/ACu/ACq+Aym9DSi8HCa6MiO3TCC0ZB2xexmujhWsnhGprQ2nvAilygSi1wGg5ACdAE/HAU/HAk7GBk3FDUvDHUnBOEe/U0S8bEC5gjy2lTezpTGxtCuvwiSszxyp3BOm5wqjAHPOAHPOAHPNAHLMAHHLF2/JOW7HWGvEcmjBiGW/m2K8q126uli4yVG11kmz4z6w7jCsAJHUAJHUAJHTAJDSAI/RE47POo3NXIvLdorIi4fGnoXEroLCvn7AzXq+3HO86Wy59WG2AKnZAKjZAKjYAKjXAKfWF6bUQaXSYaTQeqPOjqLMoKDLsZ7JwJzH0JnF3pXE7JDB+Ii/ALvdALvdALvcALvbAbraJ7rZTLnXaLjVf7fUkrbSo7XQs7TPw7LN0rDM4K3K7qrI+qXGAM3hAM3gAM3gAM3fEszeO8zdWMvbcMvag8rYlcnXpsjWtsfUxcbT1MTR48LP8L/O/LzMAN3kAN3kAt3jFNzjM9ziTdzhZNvgd9veidrdmdrcqdnbudjZyNfY1tbW5dXV8tPT/dDSEevnGuvnKOvmOurmTerlXurkb+rjgOrij+nhnungrejfvOjey+fd2ebb5+Xa8+TZ/uLXQ/XqSPXpTvXpWPXpY/XocPXoffXnivXmmPXlpfTktPTjwvTiz/Ph3fPf6fLe9fLd//DcZf/sZ//sa//rcf/ref/rgv/qjP/ql//po//or//nvP/myf/l1f/k4f/j7f/i9//h//7fAACwAACvAACvAACuAACuAwCsGACqNACnUACkawChggCelgCcpwCatgCYxgCW1QCU4wCSAAC1AAC1AAC0AAC0AACzAgCxFwCvMgCsTgCpaQCmgQCjlAChpQCftQCdxACb1ACZ4gCYAAC4AAC3AAC3AAC3AAC2AgC0FwCyMwCvTgCsaQCpgACmlACkpQCitACgxACe0wCd4QCbAAC7AAC6AAC6AAC6AAC5AwC3GQC1NACyTwCvagCsgQCplACnpACltACjxACh0wCg4QCeAAK/AAK+AAK+AAK9AAG8BgG6HQC4NwC1UgCyawCvggCslACqpQCotACnxACl0wCj4QChAA3DAAzDAAzDAAvCAQrBDAi/JAe8PgW5VwS2cAKzhAGwlgCupQCstQCqxACo0wCm4QClACDJACDJAB/IAB7HBRzGFRvELBjBRha+XxO7dg+4iQy2mgmzqQWxuAOvxgGs1ACq4QCoAELRAELQAkHQBUDPDj7NHTzLMznITjbFZzLCfS6/kCm9oCS6rx64vRi1yxCz2Aqw5AOtAGrYAGnYAGnXAGjWAGfVDmXTNWPQVGDObl3LhFnIl1XGp1DDtkrBxUO+0jq83y656iC1AIvfAIrfAIreAIndAInbA4faNYbXV4TVcoLTiH/Qm3zOq3nMunTKym/I2GjF5mDD8VO/AKTkAKTkAKTjAKPiAKPhBqLfOqHdXJ/bdp7Zi5zXnZrVrpjTvZXRzZLP3I7N6ojL9n/JALjoALjnALjnALjmALflFLfjRbbhY7XgerTejrPcn7HasLDZwK7Xz6vW3qnU7KXS+KDQAMvrAMrrAMrrAMrqAsrpLsnnUcnmasjkf8fjkcbhosXgssTewsLd0cHb4L/a7rzY+rjWANvvANvuANvuAtvtIdrsQ9rrXNrqcdnphNnoldjmpdfltdbkxdXi1NTh4tLf79De+87cAeryAurxDurxKurxQenwVunvaOnueuntiujsmujrqufpuefoyObn1uXl5OTk8ePj/OHhM/X0OPX0QfX0TfXzWvXzZ/XydvXxhPTwk/TvofTur/TtvvPszPPr2vLq5/Lo8vHn/vDmW//2Xv/2Yv/2af/2cv/1e//1hv/0kv/znv/yq//xuP/wxf/v0v/u3v/t6v/s9P/r///qAAC7AAC7AAC7AAC6AAC5AAC4EgC1LgCzSwCvZwCsfwCpkwCnpACltACjwwCi0wCg4QCeAADBAADAAADAAAC/AAC+AAC9EQC6LQC4SgC1ZQCxfQCvkQCsogCqsgCpwgCn0QCl4ACjAADDAADDAADDAADCAADBAADAEQC9LQC6SgC4ZQC0fQCykQCvogCtsgCswQCq0QCo3wCmAADGAADGAADGAADFAADEAQDDEwDALwC9SwC6ZgC3fQC1kQCyoQCxsQCvwQCt0ACr3wCpAADJAADJAADJAADIAADHAgDFFwDDMgDATQC9ZwC6fgC4kQC2ogC0sQCywQCw0ACu3gCtAAbOAAXNAAXNAATMAAPLBQPJHQLHNwHEUQDAagC9gAC7kgC5ogC3sgC1wQCz0ACy3gCwABXTABTSABTSABPRARHQDRDOJQ7LPwvIWAnFcAbChAS/lQK9pQG7swC5wgC20QC13wCzADLaADLZADHZATDYCi7WGizULinRSCbOYSLLdx7IihrGmxXDqhHBuAu/xwa81AK64AC3AFziAFziAVvhAVrgBFneDlfcMVTaUFHXak3UgEnRkkTOoj/MsTjJwDDHzSfE2hzB5RC+AIHpAIHoAIHoAIDnAH/lCn3jMHzhU3nebnfchHTZl3DXqGzVt2fTxmHQ1VnN4k7K7D/HAJ7uAJ7tAJ3tAJ3sAJzqBpvpMZrnVpjkcZfih5XgmpLeq5DcuozayojY2YPW53zT83LRALTyALTyALTxALPwALPvCLLtO7HrXLDqda/oiq3mnKzkrarivajhzKXf3KLd6p7b9pfZAMf2AMf1AMf1AMb0AMbzHcXxSMXwZMTuesPtjcLrn8Hpr8Dov77mz7zl3rrj7Lfh+LLfANn5ANj4ANj4ANj3Bdj2Ntf1VNf0a9byf9bxkdXwotTustPtwtLr0dHq4M/o7c3n+cnlAOj7AOj7AOj7Cej6MOj5Suj4YOf3c+f2hef1leb0peXzteXxxeTw0+Pu4uLt7uDs+t7qEPX9HfX9LPX9PfT9TvT8XvT7bvT6ffT6jfP5nPP3q/P2uvL1yfL01/Hy5PHx8PDw/O/vTv//Uv//V///X///aP/+c//+f//9jP/8mP/7pv/6s//5wf/4zv/32//25//18v/0///yAADHAADHAADGAADGAADFAADDDADBKQC+RwC7YwC4ewC1kACzoQCxsQCvwQCt0ACr3wCpAADMAADLAADLAADLAADKAADICgDGJwDDRQDAYQC9egC6jgC4oAC2rwC0vwCyzwCw3QCvAADPAADOAADOAADNAADNAADLCgDJJwDGRQDDYAC/eQC9jQC7nwC5rwC3vwC1zgCz3QCyAADRAADRAADRAADQAADPAADODADMKADJRgDFYQDCeQDAjQC+nwC8rgC6vwC4zgC23AC1AADUAADUAADUAADTAADSAADRDwDOKwDLSADIYgDFegDDjgDBnwC/rwC9vgC7zgC53AC4AAHXAAHXAAHXAADWAADVAQDTFADRLwDOSwDLZQDIfADFjwDDoADCrwDAvwC+zgC83AC7AArcAAncAAnbAAjbAAfZBQbYHQXVNgPSUQLPagHLfgDJkADGoQDEsADDvwDBzwC/3AC+ACHiACDiACDhAB/gAh3fEBvdJhnaQRbXWhPUcQ/RhAzOlQjMpQXJswLHwgDF0ADD3QDBAErqAErqAEnpAkjoCEbnF0PkLkDiSj3fZDjbejTYjC7WnCjTqyLQuhvOyBPL1QrI4QTGAHTxAHPxAHPwAHLvAHDuBm/sLWzpT2nmambjgGPhk17epFncs1PZwkvX0EHU3TXQ5yXNAJT3AJT3AJT2AJP1AJL0AZHyK5DvUY7tbYzrhInol4bmqIPkuH7ix3ng1nPd42ra71zXAK37AK37AK36AK35AKz4Bav2Mar0VqnycafwhqbumaTsqqLrup/pypzn2Zjl55Li84rgAML+AML+AML+AML9AMH8E8D6PMD5Xb/3db71ib3zm7vyrLrwvbjuzLXs27Lr6q/p9qrnANX/ANT/ANT/ANT/ANT+ItP+SdP8ZNL7edH5jND4ns/2r871v83zzsvy3cnw68fu98PsAOb/AOb/AOb/AOX/EuX/OuX/VeT/a+T+fuP9kOP8oeL7seH5wuD40d/239717dzz+NnyAPP/AfP/A/P/HPP/OfP/T/P/YvP/dPL/hfL/lfL/pvH+tfH9xfD80/D74e/67u75+uz3NP//Of//Qf//S///WP//Zf//c///gf//kP//nv//rP//u///yf//1///4///7v//////\",instant:\"CQwMDAwLEg0MGQwMJAoMMwcMRQAMWgALcAALhwAKoAAItwAHygAE3AAB7gAA/QAA/wAACg8MDQ8MEhANGxANJg4MNgoMSAMLXQALdAAKiwAJpAAIuQAFzQAD4AAA8AAA/gAA/wAAChQMDRQMEhQLHRUMKhUMOxMMTwwLZAAKegAJkwAHqgAFvgAD0AAA4gAA8gAA/wAA/wAACBwMDB0MEx4LHh8LLh8JQSAJWB0JbRYIhgcGnQAEsgACxQAA1gAA5gAA9AAA/wAA/wAAAyoKCSoKEyoKHiwILy4GRC8FXTADeTABkywAqCMAvBcAzQQA3QAA6wAA+AAA/wAA/wAAADoGADsFDToFHjwDMD8AR0MAYUUAfkcAmUcAs0gAxkQA1T4A5DkA8DQA/DAA/y4A/zEAAE4AAE8AAVAAG08AL1IARlUAYFoAelwAl18AsWEAyGMA22UA6GEA810A/VoA/1kA/1oAAGMAAGUAAGMAE2MALGQAQ2cAXGsAd3AAknMArHYAxHoA130A54AA9IEA/n0A/3sA/3sAAHcAAHgAAHcABHYAKXYAQXkAWX0Ac4EAjoYApooAvo4A05EA45QA8ZYA/ZkA/5kA/5cAAIsAAI0AAIsAAIoAJYkAQIsAWI4AcJIAiZYAopsAuZ8AzaIA36UA7aYA+acA/6gA/6oAAJ4AAJ8AAJ4AAJ0AIpwAPpsAV54Ab6EAh6UAnqgAtawAya8A2rEA6rIA9rMA/7QA/7YAALAAALAAAK8AAK4AKa0AQ6wAWq0Aca8AiLIAnbUAs7cAx7oA2LsA5rwA874A/r8A/78AAL8AAL4AEr0AKr0APrwAUbsAZLsAeLwAjb4AocAAtcIAxsMA1sUA5McA8skA/coA/8sANcsAOssAQMoASckAVskAY8gAc8cAg8gAlckAp8oAt8wAx80A1s8A49EA79IA+tQA/9UAV9cAWtcAXdYAZNUAbNUAd9UAhNQAkNQAn9QArtYAvNcAytkA19sA4twA7t4A9+AA/+EAcuQAdeUAd+QAfOQAg+MAi+MAlOMAn+IAq+MAtuQAwuUAzeYA2OcA4ukA7OsA9uwA/+4AivQ8jPQ8jfQ6kfQ4lvM1nPMzpPMwrPMttfMpvfMqx/Qs0PYu2fcx4vgz6/o29Pw5/P09Cg0PDA0PEA0OGAwPJAsQMwYPRQAPWgAOcQAOiAANoAAMtQAKyQAI3AAF7QAC/AAA/wAACg8ODRAPEhAPGg8PJg0PNgkPSAEOXgAOdAAOjQANowALuQAJzAAH3wAE8AAB/gAA/wAAChQPDRQPExUPHRUPKxQPPBIPTwsPZQAOewANkwALqgAKvgAI0QAF4gAC8QAA/wAA/wAACB0QDR4QFB4PHx8OLyAOQh8OWBwNbxUMhwULngAJsgAHxQAF1wAB5gAA9QAA/wAA/wAAAioOCCsOEysOHywNMS8LRTAJYDAIfDAIlSsFqSIDvRYAzgIA3gAA7AAA+QAA/wAA/wAAADsLAD0LDj0KHz4JMkEGSUQBY0cAgEgAnEkAtUoAx0QA1z4A5TgA8TMA/TAA/y4A/zAAAFAEAFIDAVIDHFEBMVMASFcAYlsAfl4AmmEAtGMAymUA3GYA6WIA9F0A/loA/1kA/1oAAGUAAGcAAGYAFWUALmYARmkAX20AenIAlHUAr3kAxnwA2X4A6YEA9YIA/34A/3sA/3sAAHoAAHoAAHoABXkAKngARHwAXIAAdoQAkIkAqY0AwJAA1ZMA5ZUA8pgA/psA/5kA/5gAAI4AAJAAAI8AAI0AJ4wAQo4AWpEAc5UAjJkApZ4Au6EAz6QA4KUA7qcA+qgA/6kA/6sMAKEAAKIAAKEAAKAAJp8AQZ4AWaAAcaQAiacAoKoAt60AyrAA3LIA67MA+LQA/7UA/7YAALIAALMAALIACLAALq8ARq8AXK8Ac7EAirMAoLYAtbgAyLsA2bwA574A9L4A/8AA/8AAAMAABsEAHMAAL78AQr4AVL0AZrwAe74Aj78Ao8EAtsMAx8QA2MYA5sgA8skA/coA/8wAOMwAPswAQ8sATcsAWMoAZskAdMgAhckAl8oAqMsAucwAyM4A1tAA49EA79MA+tUA/9YAWdcAW9cAX9cAZtcAb9YAetYAhdUAkdUAoNUAr9cAvdgAytoA19sA490A7d4A+OAA/+EAc+UMduYNeOUHfOQBg+QAjOMAluQAoOMAq+QAt+QAwuUAzeYA2OgA4+oA7OsA9ewA/u4Ai/VDjPRDjvRBkfQ/l/Q+nfQ7pPQ5rPQ1tfQxvfQyx/U00Pc32fg54fg66/o99PxA/P1DCg0TDA0TEQ0UGA0TIwwUMwgURQAVWgAUcAAShwASngARswAQxwAP2wAM6wAJ+wAF/wACCg8TDA8TEhAUGhAUJg4VNgkVSQAVXQATdAATiwASogARtwAPywAO3QAM7QAI/QAF/wABChQUDRQVExUVHhQVKxMVPA8VTwgUZAAUewATkwASqAARvAAPzwAN4AAK8AAH/wAD/wAACB4WDR8XFB8WICAWMCAWQx8WWBsWbxIVhQATnAASsAAQwwAO1QAM5QAI9AAE/wAA/wAAASwXCCwWEy0WIS0VMi8USDATYjEVfC8VkykTqB8Rug8OzAAM3AAI6wAE+AAA/wAA/wAAAD4WAD8VDj8UIT8UM0ISS0UPZUgNgkgMnUkNtUgOxUEJ1TsF4zUB8C8A/CsA/ykA/yoAAFMSAFQRAVQRHVMPM1UNSlgIZFwCf18Am2IAtGMAy2UA22QA6F8A9FsA/lgA/1YA/1cAAGgLAGkJAGgJFmcGL2cER2oAYG4AfHMAlnYAsHkAxnwA2X4A6IEA9IAA/nwA/3oA/3kAAHwAAH0AAHwACHsALHoARHwAXYAAd4UAkYoAqo0AwZAA1ZMA5JUA8pgA/poB/5gA/5cAAJAAAJEAAJEAAI8AKY4AQo4AW5EAdJUAjJkApZ4Au6EAz6QA4KYA7qcA+qgA/6oH/6wlAKIAAKMAAKIAAKEAKKAAQp4AWqEAcqQAiacAoasAuK4Ay7AA3LIA67MA+LQA/7UA/7YcALMAALMAALIACrEAL7AAR7AAXK8Ac7EAirQAoLYAtbgAyLsA2bwA574A9L8A/78A/8AHAMAAB8EAHcAAML8AQ74AVb4AZr0Ae74Aj8AAo8EAtsMAyMQA2MYA5sgA8skA/csA/8wAOMwAPswAQ8sATMsAWcsAZskAdckAhMkAl8oAqMsAuMwAyM4A1s8A5NIA79MA+tQA/9YAWNgAW9gAXtcAZdcAbtYAedYAhdUAkdUAoNUArtYAvdgAytkA19sA49wA7t8A9+AA/+EAcuUfdeUgd+UcfOQYg+QUjOQNlOMCn+MAquMAtuQAwuYAzecA2OgA4ukA7OsA9ewA/u4civVLi/VKjfRIkfRHlvRFnPRDo/NArPQ9tfQ6vfQ6x/U80Pc+2fhB4vlD6vpE8/xH+/1LCQ4cCw0cEQ0dGg0eJQwdMwkdRwIeWwAfcAAfhgAfmwAcsAAYxAAX2AAV6QAT+QAR/wAOCA8bCxAdEhAeHBAgJw8eNgweSgMfXgAfcwAfiQAdoAAatQAZyAAX2wAV7AAU+wAR/wAOCBUdDBUeFBYgHhYhKhUgOxIgTgogYgAgegAdkAAcpgAaugAZzAAY3wAW7wAU/QAQ/wAOBx4gDB8hFSAiISEjMR8jQxwiVxchbQ0ghAAfmgAergAcwAAb0gAZ4wAW8wAU/wAQ/wAMAS0jCS4kFS4kIi8jNDAjSzEkYzEleywkkCQipRgguAQeyQAc2gAZ6QAW9wAT/wAP/wAKAEAkAEIlEEIlI0MkNkQjTkciaEghhEkknkkmskQjwzwg0zYd4i8a7ygW+yIS/x0M/yAHAFclAFglAlckH1cjNVYhTFofZl0cgmAanmIbtmMfy2Ui2mEf51wb8lcW/VQS/1EL/1MFAGohAG0hAGwgGGofMmkdSGsaYnAXfXQRmHcMsXoNx3wS2X8Z6IEg9H0c/XkX/3cQ/3cKAH8cAIAbAH8aC34ZLn4XRn4TX4IPeYYHk4oAq44AwpEA1ZQB5ZYO8pke/Zoo/5ci/5UfAJMUAJQVAJMTAJIRK5EORY8JXZMDdZYAjpsApp8AvaIA0KQA4aYA76gI+qke/6ku/6s4AKUJAKYJAKUGAKMDKqIARKEAW6EAc6UAiqgAoqsAuK4AzLEA3LIA67MA97QI/7Uj/7Y3ALQAALUAALQAELMAMbIASbEAXrAAdLIAi7QAoLcAtrkAybsA2b0A6L4A9L8A/8AS/8AtAMEADMIAIMEAMcAARMAAVr8AaL4Ae74Aj78Ao8EAtsMAyMQA2McA5sgA8soA/csP/8wpOc0HPs0GRM0DTcsAWcsAZ8oAdckAhMkAlsoAqMsAuM0AyM4A1tAA49IA79MA+tUB/9YiWNgbWtgaXtgXZdcSbtcNeNYEhNUAkdUAn9YArtcAvNgAytkA19sA490A7t8A9+AR/+IlcuUzdOYzd+UxfOUuguUsiuQolOQjnuMdqeMVtuQYweYbzOYd1+gg4uoi6+si9e0j/u4yifRUivRUjPRTkPRSlfRQm/ROovNMq/RJs/RGvPRGxfVHz/dK2fhL4vlO6vpQ8/xT+/1WAw4qBw4qDg0sGg0uKgowOActSQIsXQAscwAtiAAtnAAsrgArvwAp0wAj5gAe9wAc/wAaAxAqBxEsEBEtHBAwLA4xOgwuSwYtXwAtdgAujAAtngAssAArwwAn1wAh6QAf+AAc/wAbAxUsBxYuEBYvHhYyLxUzPhQxTw8vZAEvegAvjwAuoQAttAApyAAk2wAi6wAg+wAe/wAcAh8vBx8vEh8xISEzMiE2QiAzVhsybBEygAAxlQAuqQApvAAozgAm3wAk7wAh/gAe/wAcAC0yBi4zFC40Iy81NjI4SzA4YCw2dyY0jR0yoQ0wswAuxQAr1gAp5gAm9AAj/wAg/wAdAEI4AEQ5E0U6JUY6OUc6UUk5bEo6hUo8mkQ5rj02vzUz0C0w3iQt7Roq+Q0m/wQi/wQfAFg5AFs7AVs6Ilw6OFo4Tlw3aV82hWE2n2I4t2Q8yGA611s25FUy8VEu/E0q/0ol/0oiAG83AHE6AHA5Gm83NG41S20zZXEygHYwm3gvs3syyH022oA753068nk1/HUx/3Ir/3IoAIQ2AIU3AIQ2DoM0MYIySYAvYYMue4gslYwprY8ow5Ir1pQx5ZY48plA/Jg//5Q6/5M2AJczAJgzAJgyA5YwLpQuSJQsXpQpd5gnj5wlqKAivaIh0aUl4qcs76g3+qlB/6tL/6lKAKguAKguAKgtAacsLaUpR6QmXaMjdKUgjKkfo6wcua8azLEd3bMi67Qr97U3/7VD/7dRALcqALYqALYpFrUnNLQkS7MhX7IddbIai7UYobcYtrkXybsX2r0d574i9L8u/sA5/8FJAMMrEcMqIsIpNMEmRsEkV8Agab8be78Vj8AVo8IWtsMXx8UZ2Mcb5sgi8soo/cs3/8xEOc4uP84uRM0sTcwpWcwnZ8sjdcsehMkXlsoVp8sXuMwZyM4a1tAd49If79Qp+dUv/9c/V9k2Wdg2Xtg0ZNgybdgveNcshNYnkdYintYdrdcfvNghydkj1tsl4t0o7d8q9+E0/+I+cOZGcuZGdeZEeuZCgeVAieQ9k+Q6neQ2qOQxtOQywOYzzOc21+g44ek66+s79Ow8/e5HiPViifVii/Rgj/Vfk/RdmvRcofRaqvRXs/RUu/RSxfVUzvZW1/dY4Plb6fpd8vxg+/1kAA48AA09BA0/FQxDKglIPwJJUABDYgBAdgA+jAA/oAA9sQA8wgA70wA54gA28QAx/wAqABE9ABA/BRBCGBBFLA1JQgdLUgJEZABBeQBAjgA/ogA/swA9xAA81QA55AA29AAw/wAoABdBABdCCBdDGxdHLxZLRRNNVg5HaQdEfQBCkgBCpABAtgA+xgA81QA55gA09wAs/wAnAB9BACBDCyFFHiFIMiJMSCFOWx5KbhtHggpFlgBEqABBuAA+yAA82gA26wAv+wAs/wAqAC1EAC5FDi9GIC9INjJOTjRSYDJOdSxLiSFJnBBGrABBvwA70QA44gA18QAy/wAv/wAsAEJLAEROD0VPJkZQO0hTU0tWakdTgEJPlTtMqDNIuipFyx9C2w0+6QA79gA3/wAz/wAwAFtSAF1UC15UJl5UPF9VUl9TbGJSiGNUoWRWtF9TxFhO01JK4UxF7kdB+kI9/z04/z01AHFRAHRTAHRTHHVTOXRST3NPZ3ROg3hOnXtOtX1SyH9V2H1U5HdP8HNK+29F/2tA/2s9AIhQAIlRAIlRFolRNYhPTYZMY4VJfYpKl45Jr5FJxZRN1pVS5ZhY8Jha+pRU/5BO/49KAJxQAJ5RAJ1PDpxOM5pMS5hJYZZGeZpFkZ1EqaJFv6RF0aZJ4ahP7qlX+apf/6lh/6dcAKxMAKxNAKxLDatJMqlHSqhFYKZBdadAjapApK1AurBAzbJD3bNH67RN9rVW/7Zf/7dqALlJALlJALhIH7hGObdDTrZBYrQ+drM7jLU7org8t7o9ybw+2r1C6L9G88BO/sBX/8JjCsRIGsVIJ8RGOMRFScNDWsJBasA9fMA5j8A4o8I6tsQ7yMU92Mc/5clF8spJ/MtT/81eOs5JP89KRc5ITs5GWs1EaM1Cdss+hcs6lMo2pss4t806x8891tA+49JB79RH+dVL/9dZVtpOWdpOXdlNY9lLbNhJd9hGg9dDkNY/ndY6rNc7u9g9yNk/1dtB4d1E7d9H9uFO/+JVbudaceZac+ZYeeZWgOZViOVTkeVPnOVMp+RIs+RGv+VIy+dK1ulN4OpP6utR9O1S/O5ahvVwiPVwifVvjfVukvRsmPRroPRpqPRnsfRkuvRgxPVizfZk1vhn4Plp6Ptr8fxu+f1yAA5UAA5VAA1XBwtbJQdgQQBnWgBmbQBggABakQBVowBTtQBSxgBQ1gBO5QBM8wBJ/wBFABFVABFYABBaCxBdKAxiQwVoXABncABiggBckwBXpgBUuABTyABR2ABP5gBM9ABI/wBFABdYABdaABdcEBdeKxZjRhJpXwlpcwBkhQBelQBYqABWugBUygBS2QBP5wBM9QBI/wBEACFZACJbACJdFiJgLyNkSiJrZR9tdxpmiBRgmARaqwBYvABWzABT2gBP6ABL9QBF/wA/AC1YAC1ZAC9cGzFhMzNmTjVsaTVvezFoiyxiniFerwxbvwBXzgBT3ABO6gBI+gA//wA5AEFgAENjAERjH0VlN0dnUUtubU1yfklrkUFmozdhtCxdwxpY0wBQ5ABK8gBF/wBB/wA/AFlmAFxpAFxpJF5qPWBtVWJvbmVyhV9umllprFNlvU1gzkZc3T5X6jZS9i1N/yVI/yFFAHRsAHduA3dvJ3duPnhvVXlva3hthXttn31utX5xxXpt1HRo4W5j7Wld+WRX/2BS/15NAItsAIxtAIxtHI1tOo1sU45taItpf4xomZFosZNpxZVt1Zdx45dy7pJs+I5m/4pg/4hbAJ9qAKFtAKFrFqBrOqBrUZ5oZpxle5tikp9jq6NkwKZk0qdp4ahv7ap196t4/6dy/6VtAK9oALBpALBoIK9oOq5mT6xjZKtgeKlcjqtdpa5eurFfzbNi3bRm6rVs9bZz/rd6/7mCALxnALxnELtlKrtkP7phU7lfZrdceLZZjbZXorhZt7tbyb1d2b5g579k88Br/MBy/8J9G8ZlJcZkL8ZjPcViTMRgXMRdbcNbfcFWj8FTo8JVtsRXx8Va18hc5clh8Mpl+stt/813PdBlQtBkR9BjT89hW85faM5dd81ahcxWlMtRpcxSts1Uxs5W1dFZ4tNc7dRh+NZl/9dwVdpmWNtmXNtlY9pja9lhdtlfgthcj9dZnNdUqtdSudhVx9pX1NtZ4N1c699f9eFl/uJrbedub+ducudtd+dsfeZqheZokOZlmuVipeReseRavuZcyede1Ohh3+pj6exl8+1n++5uhPWAhfWBiPWAi/V+kPV9lvV7nvV5pfV3r/R0uPVxwvVxy/Zz1fh23vl45/t78Px++P6CAA1uAA1wAAxxAAp2HAV6PgCAXwCHeQCGjQB/nAB3qwBvuQBpygBo2gBn6ABj9gBh/wBeABJxABFzABB1AA93IAx7QAOBYQCIfACHjwCBngB3rQBxuwBrzABp2wBn6QBk9gBh/wBfABhyABh0ABh2ABd5JRV8RBGCZQeKfwCJkQCBnwB4rgBxvQBszQBq3ABn6gBk9wBh/wBeACJzACJ1ACN2AyN5KiN+SSOEaCCLgxqLkxCDogZ5rwByvwBuzwBr3QBo6gBk9wBg/wBbAC9yADB0ADF3DjN7MDR/TTaFazeLhTSMlS+Doyp7sSR0wQ1x0QBt3wBo7ABj+ABd/wBZAEF1AEN3AEN4FER6NEd/UEqFbU6LiE6Nl0mFpUR9tTt4xS5z0xpu4ABo7QBh+QBZ/wBSAFh6AFp8AFp9Glt+N12AUF6CbWSJiWeNmGKFqFp/uFF6x0V01Tdt4yFk8gBb/wBV/wBRAHF/AHSCAHSCIXWCPXaEV3iGb3yJh36LnHmHrnODv21+zmd43WBy6lls9lJm/0tg/0hbAI2FAI+HCY+HLZCHRZCIW5GJcJKJg5GHm5SGspaJxJiM0pSI34+C64l89oR2/4Bv/31pAKKFAKSHB6OHK6OGQ6OGWKOGbqOGgKGClKKArKWCwKeD0amI36qM6qqO9KaH/qKA/596ALKDALOFDrKELLKDQrGCWLGCa7CAfK58j615pbB7u7N9zbR/3bWD6LaJ87eO/LiT/7aPAL6BD76BIb2ANL5/Sr2AW7x+bLp6fbl3jbdyorl0t7x2yb142b985sCA8cGG+sGN/8OVJsl/MMiAPMiAR8h/U8d8YsZ6cMV3gMR0j8JvosJvtcRxx8Z018h35Mp78MuA+cyH/86QRNKASNJ/TdJ+VNF8XtB6atB4eM91hc1xlMxto8tptc1sxc9v1NFy4dN17dV699Z+/9iHV9x/Wtx/Xdt9Y9t8a9t6dtp3gdl1jtlxm9htqNdpt9hqxtpt09xw391z6t929OF8/eOBbOiEb+iEceeCduiCfOeAhOd9jeZ7mOZ4o+V1ruVwu+Vvx+dy0+h03ep35+t58e17+u+DhPaShfaShvWRifWQjvWOlPWNm/WLpPWJrfWGtvWDwPWAyfeD0/iF3fmI5fqL7vyO9/6TAAyJAAyKAAuLAAiODwOTOwCYXgCeggCmmQCiqgCbtQCRwwCJzwCC3QB+6wB8+AB6/wB5ABGKABCMABCNAA6QFQmUPgGYYQCfhACnmwCkrACctwCSxACK0ACD3gCA6wB9+AB7/wB5ABiMABiNABiOABeRHRaVQxGaZAWhhgConQCkrQCduACTxQCL0QCD3wCB7AB++QB6/wB5ACOMACSOACSPACSSJSSWRyObZyGhiBynnxKlrgKduQCTxgCL0QCE3wCB7QB++QB6/wB4ADGMADKOADOQADOSLDWWSzWbajegiTinoDSlri6duiqTxiSM0xaG4QCD7QB++gB5/wB2AECKAEONAESPBUaSMUiWT0qabE2gilGmolCmr0udu0eVxkGN1TSI4h+D7gB9+gB3/wByAFWMAFePAFePDFiPMVmRT16XbGOdiWijoWqlrWScul+VyFaP1kqJ4zqD7iJ7+wBz/wBrAG6RAHCTAHCTF3GUOHKUUXSWanaYhn2fn4Kkq3ycunSWyWmQ1l2I401/8Dt1/iFr/wdkAImWAIqXAIuXJYyYQY2ZWo+bcZGdiJSgnZiirpOevoyZzYaU23+N6HmH9HKA/2t5/2dzAKObDKWdJaWdPKWeUaaeZKafdqefiKefmKadraidwaqg0Kuj3Kif56OZ8p2S/JmK/5WEFrScJrWdMrSdQbScUbOcY7ScdLOchbOblbGXp7GVvLSYzbaa3Lef57ij8bil+rWf/7GZKr+aNMCbO7+aR7+aVb+ZZL6YdL6XhL2Vk7uRo7qOt7yQyb6T2cCW5cGa8MKg+MOl/8WsPcmYQsqZSMqYUMmXXMmWasiWeMeUhcaQlMWNocOHtMWKxsaM1smQ48uU7syY982f/8+nS9OXTtOWU9OWWtOVZtKVcNGTfNCQiM+Nlc6Jo82Es82Dw8+G0tGK4NSN69WR9daW/didXt2YYd2XY92WaNyVb9yTeNuRg9uOjtqLmtmIptiDtNh/w9qD0dyG3d6J6eCN8+GS/OOYb+iacumbc+mZd+iYfOiWheiUjeeSl+ePoeaMrOaIuOWDxOeF0eiI2+qL5uyO8O6R+O+XhPakhfakh/ajivaijvWgk/agmvWeovWcqvaZs/aXvfaTx/aT0fiW2/mZ5Puc7fyf9f6jAAugAAuiAAmjAAalAgCoOgCtXwCygQC4oQC+tAC5wwCyzACp1wCh4gCa7ACU+QCS/wCRABGiABCkAA+kAA2mDAiqPwCuYQCzgwC5ogC/tQC6xAC0zQCq2QCi4wCb7QCU+QCS/wCSABmjABikABilABenGRWrQxCvZAa0hAC5owC/tgC6xQC0zgCq2QCi4wCb7gCW+QCT/wCSACWkACWmACWnACWpIiSsRyOvZyG0hh25pBu+txG7xQG0zgCq2QCi4gCb7gCW+QCT/wCRADOkADSlADSmADWoKjWrSzauaTezhzi4pDu9tze6xTC0zi2q2Cii4iKb7gOX+gCT/wCRAEOhAEWkAEamAEeoMEmrT0uubE2yiFC3pFa8uFS7xE60zkqr2EWj4j2c7iqY+gST/wCPAFOdAFWfAFWgAFeiMFqmT16ra2Kvh2e1om26tm66wmiyzGOq1l2j4lGd70GX+imQ/wCLAGugAG2iAG2jCm2jMm6jTG+laXWrhXyxn4O2s4a4voCxyXqp1XCj4mKd7lKV+z2M/x+EAIWkAIamAIemHIenO4inVIqpa4yqgo6sm5azsZu3vJWwyIyq1YGj43Sb72OQ+1CG/z18AJ+pAKGrFKGrMaGrSaKsX6OtdaSviaaxnaizr6u2vaeyy6Gt2Jun5JWg8I2Z+4aR/4GLKrSuNbWvP7SvTbSwXrWwb7WxgLayj7aznrayq7Wxvbexzbi02rm35Laz7rKt+K2m/6qgR8GwTcGxUsGwW8GwZcCvcsCwf8CvjsCvnL+vqL2ruL6pycCs2MGv5MKz7sO39sS5/8G1U8qvVsuvW8uvYcqua8qudsqugsmtjsmsm8iqp8altMWixcel1Mqo4syr7M2w9c61/dC7XdSuYNSuY9StaNOscNOredOrhNOqkNKpmtGlps+gss6bws+e0dKh39Wl6tao89et+9mzZ96sad6ta96sb96rdd2qf92qidyoktylnNuip9qds9iYwdmYz9yc296f5+Cj8eKo+eOtc+mudequdumsfOmtgumsh+irj+ipmOinoeejq+egtuabwueZzuic2uqf5Ouh7u2k9++qh/e2iPe2ifa1i/a0j/azlPaxmvWwofauqfassfaqu/anxfekz/im2fmp4vus6/yv9P6zAAq3AAm4AAa4AAO6BgC9PgDBYgDFgQDInwDMugDQygDM1wDG3gC+6AC28QCv+QCp/wCoABC4ABC5AA66AAu8EwW/QgDBZADFggDJoADNvADRywDN2ADH3wC+6QC38QCw+gCq/wCpABq6ABm7ABm8ABe9HRW/RhDCZgbFhADJoQDNvADRywDN2ADI3wC/6AC48QCw+gCr/wCpACa5ACa7ACa8ACW9JiW/SiTBaCHFhh/Ioh/MvCTRyxzN2BLH3wy+6Ae38QGw+QCq/wCpADS4ADW5ADW6ADW7LDa+TTbAazfEhznHojzLu0LQyz/M1znH3jW+5zG38C2w+SSr/wOpAEW3AEe6AEe6AEi7Mkm9UEq/bU3DiFHGolbLu17PylvM1VXH3VG+5ky370aw+Tqr/yeoAFWyAFe0AFi1AFm3M1y6UV69bGLAh2bEoW3IuHXNx3XL027G22m942K27Vuv+Euq/zunAGewAGmyAGmxAGmxLWy0TXC4a3a9hXvBnYLFtIrKxIzKzoXE13684Xe17Guv+Fqp/0mjAIGzAIK0AIK0C4K0NIO1TYS2ZYa3gIy8mpTBsZzHwZ/Jy5nD1JK734m17Hqu+Gqm/1ifAJu3AJy4AJy4J5y4QZ24WJ65bZ+6gqG8lqK+rarEwK7JyKnC06G73pa064iq+Hag/2SVFbG7JbG7MrG7QrG7VLG8Z7K9erO+jbTAn7XCsLfEv7nHyrXE1bG+4Ku466Wx95+q/5qjTcG/U8HAWcHAYsDAb8HBfcHCi8HDmcHEpcLEscLEu8HCysLD2MTF4sTI68LF9L6//ru6aczCa8zCbsvCc8vCe8vChMvCjsvCmcrCo8rBr8rAuci8xcm81My/4M3B6s7F89DJ+tLMb9XBctXCdNXBeNXBf9TAhtTAjtS/mNS/otO9rNK7tdC3wdC00NK33da66Ne98tnB+drGdt/Bd9/Bed7Afd/Agt+/iN6+kN69mN28ot27q9y3tNuzv9quzdyx2d605eG47+O79+TAf+rBgOrBgerBhOrAiOm/jem+k+m9nOm8pOm6rOi3tuizwOeuzOiv2Oqy4uy17O639fC8i/fGi/bFjPbEjvbEkffDl/bCnPbCo/bAqva/sfa8ufe6wve2zPi21vm44Pu76f2/8v7CAAjLAAbLAATMAADNHADPRgDRZgDTgwDWngDZuADczgDf3ADb5wDX7QDP9QDJ/QDD/wC/AA/MAA/NAA7OAArOIwTQSgDSaADUhQDXoADZuQDdzwDg3ADc5wDX7gDQ9QDJ/QDE/wC/ABrMABvOABnOABjPKhXQTRHSagnUhgDWoADZuQDczxHf3Abc5wDX7QDP9ADJ/QDE/wvAACfMACjNACfNACfOLybPUCXRbCPThyLWoSTZuSnczjTf3DDb5inX7CXP9CTJ/CLD/ye/ADbLADfLADbMAjfNNDfOUjjQbjjSiDrVoj7YuUXbzk/e2kvb5UbX60LP8z/J+zzD/z2/AEfJAEnLAEnLEUnMOUrNVUzPcE7RilHUolfXuV7azGnd2Gba42DX6VvP8VbJ+VHC/1C+AFfFAFnHAFrIEFvKOV3LVV/Nb2LPiGfSoG3VtnXYyX/c1X3Z4HbV53HO72vI92TB/16+AGfBAGnCAGnCAGvEMm3GUnHJbHXMhnrPnYHTs4nWxZPZ0pLY3IvU44XN7H7H9Xa//2q8AH7BAH7CAH7BAH7BK37CSYDDZoXHgYzMmpPPr5vTwqPX0KTY2J3S4JfM6ZDF9IW//3e7AJfEAJjEAJfEGZjEOJjEUJjFZpnFeprGlKDLrKjRwK/WzrHX1azR3aXK5pzE85C+/4K3AK3GD63GI63GN63GSq3HXq7Hca7IhK/Jl7DLqLLMvbjSzbvW07fQ3LDK5qbC8pm5/4qvQb7KR77KTb7KV77KZL7Kc77Lg77Mk7/NosDPscHQwMPTzMXV1cHR3rzM6LfH87LA/q26acvObMvOcMvOd8vOgMvPisvPlsvQoszSrczSt8zSwM3TyMvQ1M3R4NDU6dHW8c/U+svQgdbSg9bShdbRiNbRjdbRk9XRmtXRo9XRq9XQs9XQvNXPxNPLz9TK3NfN59nP79rT+NzXheDRhuDRiN/Qi9/Qj9/QlN/Qmt/Pod/Pqd/Osd/Nud7LwdzGy9zD2N/H4+HK7ePM9uXQi+rSjOvRjurRj+rQk+rQl+rQnOrPourOqOrMsOrLuOnIwOnEyei/1erD4OzF6+7I9PDMlPfUlffUlvbUl/bTmfbSnffSoffRpffQrPfPs/fNuffLwvjIy/jG1PnG3/vJ6P3M8f7PAAfbAAbbAATcAADcMgDeUQDfbQDghwDioADktwDmzADp3QHq6QDn8wDk+QDe/wHY/xXVABHcABDdAA/dCAzdNwbeVADfcADhiQDjoQDluADmzQDo3hvq6Rjn8hLk+Qve/xbY/yPVABzcABzcABzdFBrdOxfeVxTfcRDhigviogvluRPnzSLp3jDq6C7n8irk+CXe/ijY/zDVACrbACrcACrcHSncPijdWSfecifgiyfioyrkuDDmzDvo3Efp50Tn8UDj9zve/TvY/z/UADjaADnbADnbIzncQTncXDredDvfjD3ho0LjuEjlzFPo21/p5lvm71bj9VHd/VDY/1HUAErZAEvaAEvaKkvbRUzcXk7ddlDejVTgo1niuGHkymvn2Xfp5HLm7Wzi82fc+2PX/2PUAFrWAFzYAFzYJ13YQ17ZXGDbdWTci2jeoW7gtXbix4Dl1ovn4Ifl6YHh8Hrc+HXX/3LSAGrSAGzTAGzUGm3UPW/WWHLYcXbZiXvcnoHes4ngxJLj05zl3Znk5pPg7Yza9YXV/oLSAHrOAHrOAHvPAHzQMH/RT4LTa4bWhIzYm5Pbr5rewaLh0ank26jj46Lg6pza8pfU+5HQAJPQAJPQAJPQBJPQL5PQSJPQX5TRe5nUlqHYrKfcv67fz7Tj2bTi4K/e56nZ76PS+prPAKrRAKrRDanRKqnRQKnSVKrSaKrSfKvTjqvTprDYvLbdzbzh2b7i3rnd5bPX7qzR+qLNM7vUOrvUQbvUTLvTWrvUabvUebvUirvVmrzWqbzXuL7ZysPe2Mji3cLc5LvW7rLP+qfIXsjWYcnXZsnXbcnXd8nXgcnYjsnYmsnZp8ratMvbwMzdzM7f1tHh3czd5sfY8MPU+7/PftTagNXag9Xah9XajtXbltXbntXcqdbcs9fevNjfxNjey9je0tfc3Nnd5tvf793h9tvglOHdleHeluDdmeHdnODdoeHdpuHdrOHds+HdueHdwODcx+Dbzd7X19/W4+PZ7OXb9Obel+vemOvdmevdm+vdnuvdouvdpuvcq+vcsevct+vbvevaw+rXyurU1OrR3uzU6O7W8vDZnvffn/ffoPffofffo/bfpfbeqfferfjesvjctvjbvfjbwvjYyvnW0vnT3fvV5/3Y8P/bAAroAAroBAfoLQToRwDqYADrdwDsjgDtpADuuADvzAbx3CPy6TTy8zXw/DPt/y7q/zjlABXpABTpGBPpMxDpSw3qYgjreQLrjwDtpQDuuQnvzBzw3DDy6T7y8z7w/Dzu/zjq/z/lACDpAyHpIB/pOB/qTh3qZBvrehnrkBjspRzuuSPvyy/w3D7y6Evy8krv+0fu/0Pq/0jlAC3oEC7oJi3oOy7pUS3pZizqfC3rkS7spTLtuTnvy0Pw21Dx51zy8Frv+lbt/1Lp/1XlATznEjznKDznPT3oUj7oZz7pfUDqkkPrpkfsuU7uyljv2WTw5W/x723v92nt/mPp/2XlBk3mH0/nLk/mQE/nVVDoaVLofVTpklfqpl3ruWTtyW7u13rv44Tw7IDv9Xvs+3Xo/3XkAV7kGWDlK2DlPmDlU2LmZ2PmfGfokWvppHHqtnjrx4Lt1Yzu4Jbv6ZLt8ozr+Ibn/4PjAG7hAG/iHHDiNXHjTHLjY3XkeHjljn3nooPotIrpxJPr0pzs3qTu56Dt75rq9ZTm/ZHiAH3eAH/eAH/eIX/fQIHgWoXhconjiY3knpTmsJrowaHq0Kns3bDu5K3s7Kjp86Pl+5/iAJDbAJHcAJDcAI/bKpDcS5LdZ5bfgZvhmaHkrafmv63ozrPq27nt47fr67Lp8a3l+KnhAKfcAKfcAKfcHqbcN6bcTKXcYKXcdaXdj6rfqLDju7bmzLvo2cHr4sHr6Lzn77fk97LfJrjdLrneNrndQrjeUbjeYLjecbjegrjekrjeobjftrziycLm18jq4crr5sXn7b/i9rneVcbfWcfgXcbfZMbgbsbgecbghsbgksbgoMfhrcfhucfixcjj1M/n4NTq5c7m7Mfh97/ddtPieNPie9Pif9LhhdPijtPil9PiotPjrNTjt9Xkwdbly9jn1dnn3dzp5djm7dPj987ej+DkkODkkuDlleDkmuDkoODlp+Dlr+Hmt+Hmv+Lnx+PnzePo1OTn2eLl4+Tm7Ofo8+jpo+znpOznpeznp+znqeznreznsOznte3nuu3nv+3nxO3mye3mz+3k1evh3uzg6O/j8vLmqfjoqffoqffoq/jorPfor/fosvjotfjnufjnvfjnwvnmxvnlzPnk0/ri3Pvg5v3i7//lLRXzNBTyPhPzThLzXxD0cQ30hAr1lwr2qg/2vBr3zCf32zj450n58VX4+lb3/1X1/1T0NB3zPB70RR30Uhz0Yhv0cxn0hRj0mBn1qh32vCX3zDH320D451H48Vz4+lz3/1v1/1nzNyjzPyjzSCj0VCfzZCf0dCb0hif0mSj1qyz2vDT3zD732kv35lv48Wb4+WX2/2L0/2DzOzXyQjbzSjbzVjXyZTXzdjb0hzf0mTn0qz31vET2y0722lr35Wj473P493H2/271/2vzPEPxQ0TyS0TyWETyZkXzd0fziUn0mkv0q1D1vFf1y2D22Gz343n37YL39YD1/n30/3jyP1XxR1bxT1byWlbyaFfyeFnyiVvzml/zq2T0u2v0yXT11n/24Yr26pL284/1+4v0/4bxPGXwRGbwTGbwV2fwZmjwdmrxh23xmHHyqXfyuX7zx4b01I/135n16aD28Zz0+Zfz/5LwMXXuOnbuQ3buUXfuYHjucnvvhH7vloLwp4jxto7yxZby0p7z3aX056z17qfz96Py/Z7vFoTsJYXsM4XsQ4bsVoftaortfo3ukZLvo5fvs53ww6Px0Kny26/z5rb17bP09a7y+6nvAJLpAJTpEZTpL5TpRpXqXpfrdJrri57tnqPtsKjuwa7wzrPx2rjy5b707Lvz87fx+bPuAKbnAKboAqXnIKTnN6TnS6PnZaTofqjplqzrq7HsvbbuzLvw2cDx48bz68Tz8b/w97vtKLfnL7jnNrfoQLfnTrbnXbbobLXofLXnjLTno7jpuL3sycLu1sfw4s3y6c3y78jv9cPsU8XoVsXpWsXoYcXoasXodMXpgMTpjMTpmcTppsPpssPpw8fr083u39Tw6Nfy7tLv9Mzsc9LqddHpd9Lpe9LqgdHqidHqktHqm9HqptHqsNLqu9LrxdLrz9Ts3Nvv5+Dy69ru9NLqit/ri9/rjd7rkN7rld/rmt7rod7rqd/ssd/sut/sw+Hty+Lt1OPu3OXv5Onw6uPt897qnuvtnuvsn+vso+ztpuvtquvtr+vttuzuvO3uwu3uyu7v0O7v1e/v2u/u3+7s6PHt8PPvsPjvsfjvsvjwtPjvtffvuPjvu/jvvvjvwvnwxfnvyfrvzfrv0vvu1vvt3Pvr5f3r7//uVyf7Wyf8YSb7aib7dib7hCf8kyj8oiv8sjD9wDf9zkH92k395Vv972v+93P9/nT8/3X7XC/8YC/8ZS/8bi78eS78hS77ky/8ozL8sjf9wD79zkf92lP95WH97nD99nj9/nj8/3n7XTf7YTj7Zzj8bzf7ejj8hzn8lDr8oz38skL9wEj8zVD92Vv95Gn97Xf99X/9/n/8/3/7YET7ZET7aUT8cUT8e0X8iEX8lkf8pEr8sk/8wFX9zV792Wj843T87IL99In8/Ij7/4f7YVD6Y1D6alH7cVH6fFP6iFT6llf7pFr7sl/7wGX8zG382Hf84oL8647885T8+pL6/5D6Y2H6Z2L6a2L6c2P6fWT6iWX6lmj6pGv6snD6v3b7y3771of74JH76Jr78J/7+Jz6/5r5YXH5ZXL5anL5cXL5fHT5iHX5lXj5o3z6sYH6vYf6yY761Jb63p3656T676n796b6/6P5XID4YIH3ZYH3bYL4eIP3hYX4koj4oIz4rpD5u5X4x5v506H63aj55q767rL69a/5/av5UY/2Vo/2XI/2ZZD2cZH2gJP3jpb3nZr3q573uaL3xaf40az527H45bb57br69Lf5+7X4RJz0SZ31T530Wp31Z571dqD1h6L1mKX2p6j2tqz2xLD30LX42rn45L757MP588D4+r34KajyMajyOqjzR6nyV6nzaarzfKvzj670obD1srT1wbj2zrz32cH448b468v58sj4+MX3RLnxSLnyS7jxUrjyXLfyZ7fyc7XyhLXxmLfyq7rzvb/0y8P12Mj34s346tL48dL49833YcbyY8byZcXxasXyccXxesXyg8TxjcPxmMPxo8LxtsTyx8j01c724NT36dv479v49df2etPye9LyfdLygNLyhdLyi9LyktHym9HypNHyrtDyt9DywdDyz9Pz3Nr15+H37eP38971jN7yjt/yj97ykd7ylt/zmt/yoN7yqN/zr97zt97zv9/yxt/zz9/z2ODz5Of17Oz38eb0nevznezznuvzoOvzpOvzp+vzrOzzsevzuOzzvuzzxezzzO300+7z2/D14vH16vT28e/zrPf0rPj0rff0rvfzsfj0tPfzuPj0vfj0wvn0x/r1zPr10vr12Pv13fz24f315v/07//1fUX/gEb/hEb/iUb/kUf/mkn/pUz/sE//vFT/xln/0WH/22r/5HT/7ID/84v/+pH//5P/gEz/gkz/hk3/i03/kk3/m0//plH/sVX/vFn/xl//0Wb/2m//5Hn/64P/8o7++pT//5X/gVT/hFT/h1T/jVX/k1X/nFb/pln/sVz/vGD/xmb/0W3/23b/43//64n/8pP/+Zj//5n/g17/hV//iF//jV//lGD/nWH/p2P/sWb/vGv/xnH/0Hf/2n//4of/6ZD/8Zr/+Z7//57/hGr/hmr/iWr/jmv/lWz/nm7/p3H/sXT/vHj/xn3/z4P/2Yv/4ZL/6Zr/8aH/+KX//qT/hnn/iHr/i3r/kHv/l3z/nn3/p4D/sYL/u4f/xYz/z5H/15f/4J3/6KP/76n/9qz//av/hYf/iIn/i4n/j4n/lor/nYz/p47/sJH/upT/xJj/zZ3/1qH/3qb/56z/7rD/9bP//bL/hJX/h5b/iZb/jZb/lJf/nJn/pZr/r53/uaD/w6P/zKf/1ar+3q//5rL+7bf+9br//Lj+gKL/gqH/haL/iqL+kaP+maT+o6b+raf+uKr+wqz+y7D+1LP+3bf+5br+7b7+9ML/+8D+fKv9fqz9gaz+hqz9jaz9lq39oK/9q7D9trL+wLT9y7f91Lr+3b395cH+7Mb+8sj++cf+dbT8eLT8e7X8f7X9h7X9kLX8m7b9prj8srn9vrz9yL7908H93MX95Mj968z98tH9+M/9db/8dr/7eL/7e777gL37ir77lb78ob/8rsD8usL9xsX80cj82sv94s/86tT98dn999f9hMr7hsv7h8v7isr7jcn7ksn7mMj7n8j7qMj8tcn7wsv8zs782NL84db86tz97+D89d/8ktb7k9f7lNb7ltb7mdb7ndX7otX6qNX7r9X7ttT7vdP7yNT71dj83t375+L87eb89Of8nuP7nuL6oOP7oeL7pOL6p+L7q+L6seL7teH6vOL7wuL7yOH7z+D72eL75ej87e788vD8qe/7qe76qu/7q+76ru/7sO76tO/7uO/7vO/7wu/6xu/6zO/70u/62fD74O/76fP78Pj7s/r6s/v6tPr6tfr6t/r6ufv6vPv6wPv7w/z7yPz7zPz60fz61/363f774//76f/88P/8\",mono400:\"CwsLDAwMDg4OEBAQExMTFxcXHBwcIiIiKSkpMTExOTk5QkJCTExMVlZWYmJicXFxg4ODDg4OEBAQExMTFhYWGBgYHBwcICAgJiYmLS0tNDQ0PT09RUVFTk5OWVlZZmZmc3NzhYWFExMTExMTGBgYHh4eISEhJCQkKSkpLi4uNDQ0Ozs7Q0NDS0tLVFRUXl5ea2treHh4ioqKGxsbGhoaHR0dJCQkLCwsMTExNTU1OTk5Pz8/RkZGTU1NVFRUXV1dZ2dncnJygICAkpKSJiYmJSUlJSUlKioqMjIyPj4+Q0NDSUlJTk5OU1NTWVlZYGBgaGhocXFxfX19ioqKmpqaMTExMTExLy8vMzMzOjo6Q0NDUlJSWFhYXV1dY2NjaWlpbm5udnZ2f39/ioqKlpaWpaWlQEBAPz8/Pj4+PT09Q0NDTExMVlZWZmZmbW1tcnJyeXl5gICAh4eHj4+PmZmZpKSksrKyTk5OT09PTU1NSkpKTU1NVVVVXl5eampqeXl5g4ODiIiIj4+Pl5eXoKCgqampsrKyvr6+X19fX19fXV1dWlpaWVlZYGBgaGhoc3Nzfn5+i4uLmZmZn5+fpqamrq6utra2v7+/yMjIbm5ub29vbW1ta2traGhobGxsc3NzfHx8h4eHkpKSnp6erq6utLS0urq6wsLCysrK09PTgICAgYGBgICAfn5+e3t7eHh4gICAiYmJk5OTnJycp6ensbGxwMDAxsbGzMzM09PT29vbk5OTlZWVlJSUkpKSj4+PjIyMj4+Pl5eXoKCgqKiosrKyurq6wsLC0NDQ1tbW3Nzc4+Pjp6enqKiop6enpqampKSkoKCgnp6epaWlra2ttLS0vLy8xMTEysrK0dHR3d3d5OTk6enpurq6u7u7urq6ubm5t7e3tbW1srKytbW1u7u7wsLCyMjIz8/P1dXV29vb4ODg6urq7+/vzc3Nzs7Ozc3NzMzMy8vLysrKycnJx8fHy8vL0dHR1tbW29vb4ODg5eXl6urq7u7u9PT039/f4eHh4ODg4ODg39/f3d3d3Nzc29vb3d3d4ODg5OTk6Ojo6+vr7+/v8vLy9fX19/f37u7u7u7u7u7u7u7u7e3t7e3t7Ozs6+vr6+vr7Ozs7+/v8vLy9fX19vb2+fn5+/v7/Pz8DQ0NDw8PEhISEhISFRUVGRkZHx8fJCQkKysrMjIyOzs7Q0NDTExMV1dXYmJib29vgICADw8PERERExMTFRUVGRkZHR0dIiIiKCgoLy8vNjY2PT09RkZGT09PWlpaZmZmcnJygoKCGBgYFxcXGhoaHh4eIiIiJiYmKioqLy8vNTU1PDw8RERETExMVVVVX19fampqeHh4iIiIISEhICAgHx8fJiYmLS0tMTExNjY2Ozs7QEBARkZGTU1NVVVVXV1dZ2dncnJygICAkJCQKioqKSkpJycnLCwsNDQ0Pj4+Q0NDSUlJTk5OVFRUWlpaYWFhaGhocnJyfX19iYmJmZmZNTU1NTU1MzMzNDQ0Ozs7REREU1NTWFhYXV1dZGRkaWlpb29vd3d3f39/ioqKlZWVpaWlQ0NDQ0NDQkJCPz8/RERETU1NV1dXZmZmbW1tc3NzeXl5gICAh4eHj4+PmZmZpKSksrKyUVFRUlJSUFBQTk5OTk5OV1dXX19fa2treXl5g4ODiYmJj4+Pl5eXoaGhqampsbGxvr6+YWFhYWFhYGBgXV1dWlpaYWFhaWlpc3Nzfn5+jIyMmZmZn5+fpqamrq6ut7e3vr6+yMjIcHBwcnJycHBwbm5ua2trbW1tdHR0fX19iIiIk5OTn5+frq6utLS0urq6wcHBycnJ09PTgoKCg4ODgoKCgICAfX19enp6gYGBioqKk5OTnp6ep6ensbGxwMDAxsbGzMzM09PT29vblZWVmJiYlpaWlZWVkpKSjo6OkJCQmJiYoKCgqampsrKyurq6w8PD0NDQ1tbW3Nzc4+PjqKioqqqqqampp6enpaWlo6OjoKCgpqamra2ttbW1vLy8xMTEy8vL0tLS3d3d5OTk6enpu7u7vLy8u7u7u7u7ubm5t7e3tLS0tra2vLy8wsLCycnJz8/P1dXV29vb4ODg6enp7+/vzc3Nz8/Pzs7Ozs7Ozc3NzMzMysrKx8fHzMzM0dHR1tbW3Nzc4ODg5ubm6enp7u7u9PT04ODg4eHh4ODg39/f39/f3t7e3t7e3Nzc3d3d4eHh5OTk6Ojo7Ozs7+/v8vLy9PT09/f37u7u7u7u7u7u7u7u7u7u7e3t7e3t7Ozs6+vr7e3t8PDw8/Pz9fX19vb2+fn5+/v7+/v7Dw8PERERFRUVGhoaHx8fICAgIyMjJycnLi4uNDQ0PDw8RUVFTk5OWFhYZGRkcXFxgYGBERERFBQUGBgYHh4eHx8fISEhJSUlKioqMTExODg4Pz8/R0dHUVFRW1tbZmZmc3Nzg4ODGRkZGxsbHBwcHx8fIiIiJycnKysrMTExNzc3Pj4+RUVFTU1NVlZWYGBga2treHh4iYmJJycnJycnJSUlKCgoLi4uMjIyNjY2Ozs7QUFBSEhITk5OVVVVXl5eaGhoc3NzgICAkZGRMTExMDAwLi4uLy8vNjY2Pj4+RERESUlJT09PVVVVWlpaYWFhaWlpcnJyfn5+ioqKmZmZPDw8Ozs7OTk5Nzc3PT09RkZGU1NTWFhYXl5eZGRkaWlpb29vd3d3gICAi4uLlpaWpaWlSEhISEhIR0dHRERER0dHT09PWVlZaGhobm5uc3NzeXl5gICAh4eHj4+PmZmZo6OjsbGxVlZWVlZWVVVVUlJSUVFRWFhYYWFhbGxse3t7g4ODiYmJj4+PmJiYoKCgqampsrKyvr6+ZmZmZmZmZGRkYmJiXl5eYmJia2trdXV1gICAjY2NmZmZn5+fpqamrq6ut7e3vr6+yMjIdXV1dXV1dXV1cnJyb29vbm5udnZ2f39/iYmJlJSUoKCgrq6us7Ozurq6wsLCycnJ09PThoaGh4eHhoaGhISEgYGBfX19goKCi4uLlJSUnp6eqKiosrKywMDAxsbGzMzM09PT29vbmJiYmpqamZmZl5eXlZWVkpKSkZGRmZmZoaGhqampsrKyu7u7w8PD0NDQ1tbW29vb4+Pjq6urrKysq6urqampqKiopaWloqKipqamrq6utbW1vLy8xMTEy8vL0tLS3d3d5OTk6urqvLy8vr6+vb29vLy8u7u7uLi4tra2tra2vLy8wsLCycnJz8/P1dXV29vb4eHh6enp8PDwz8/P0NDQz8/Pz8/Pzs7Ozc3Ny8vLyMjIzMzM0dHR1tbW29vb4eHh5eXl6urq7e3t8/Pz4ODg4eHh4eHh4ODg39/f39/f3t7e3Nzc3d3d4eHh5OTk6Ojo7Ozs7+/v8vLy9PT09/f37+/v7+/v7+/v7+/v7u7u7e3t7e3t7Ozs6+vr7e3t8PDw8/Pz9fX19/f3+Pj4+vr6+/v7FBQUFRUVGRkZHh4eJCQkLi4uMDAwMjIyNTU1OTk5Pz8/R0dHUFBQWVlZZWVlcnJygoKCFhYWGRkZHR0dISEhJycnLi4uMDAwMjIyNTU1OTk5QkJCSkpKUlJSXFxcZ2dnc3NzhISEGhoaHBwcISEhJiYmLCwsLi4uMDAwMjIyOTk5Pz8/R0dHT09PWFhYYWFhbW1teXl5ioqKJycnKCgoKSkpKysrLi4uMjIyNjY2PDw8QkJCSEhIUFBQV1dXX19faWlpdXV1gYGBkZGRODg4ODg4Nzc3NDQ0ODg4Pz8/RUVFSkpKT09PVVVVW1tbYmJiampqc3Nzfn5+ioqKmpqaQ0NDREREQkJCQEBAQUFBSUlJU1NTWVlZX19fZGRkaWlpcHBweHh4gICAi4uLlpaWpqamUVFRUVFRT09PTExMSkpKUVFRW1tbaWlpbm5udHR0enp6gICAiIiIkJCQmpqapKSksrKyXV1dXl5eXFxcWlpaVlZWW1tbZGRkbm5ufX19hISEioqKkZGRmZmZoaGhqampsbGxvr6+bW1tbW1ta2traWlpZmZmZWVlbW1td3d3gYGBj4+PmpqaoKCgpqamr6+vt7e3vr6+yMjIe3t7e3t7enp6eHh4dXV1cnJyeHh4gYGBi4uLlZWVoqKirq6utLS0u7u7wsLCycnJ09PTi4uLjY2Ni4uLiYmJh4eHg4ODhISEjY2NlpaWoKCgqamps7OzwMDAxsbGzMzM09PT29vbnZ2dn5+fnp6enJycmpqal5eXk5OTmpqao6Ojq6urs7OzvLy8xMTE0dHR1tbW3Nzc4+Pjrq6usLCwr6+vra2trKysqqqqpqamqKior6+vtra2vb29xcXFzMzM0tLS3t7e5OTk6enpv7+/wMDAwMDAv7+/vr6+vLy8ubm5t7e3vb29w8PDycnJ0NDQ1tbW29vb4eHh6urq8PDw0dHR0tLS0dHR0NDQ0NDQzs7Ozc3NysrKzc3N0tLS19fX3Nzc4eHh5ubm6+vr7u7u9PT04uLi4+Pj4uLi4uLi4eHh4ODg39/f3t7e3d3d4eHh5eXl6Ojo7Ozs7+/v8vLy9fX19/f37+/v7+/v7+/v7+/v7+/v7u7u7e3t7e3t7Ozs7e3t7+/v8/Pz9fX19/f3+Pj4+/v7+/v7GRkZGxsbHh4eJCQkKSkpLy8vPDw8QkJCRUVFR0dHSkpKTU1NUlJSW1tbZ2dnc3NzgoKCHBwcHx8fIiIiJycnLCwsMjIyPj4+QkJCRUVFR0dHSkpKTU1NVFRUXl5eaGhoc3NzhISEISEhJCQkJycnKysrMDAwNjY2QUFBQkJCRUVFR0dHSkpKT09PWFhYY2NjbW1teXl5ioqKKCgoKCgoKioqMDAwNTU1PT09QEBAQ0NDRUVFSUlJUFBQWFhYYGBgampqdXV1gYGBkZGRNjY2Nzc3ODg4OTk5PDw8QEBARERESkpKT09PVVVVW1tbY2NjampqdHR0f39/ioqKmpqaS0tLTExMS0tLSkpKR0dHTExMVVVVWlpaXl5eZGRkaWlpcHBweHh4gYGBi4uLlpaWpaWlWVlZWVlZWVlZV1dXU1NTVVVVXl5eaWlpb29vdXV1enp6gICAh4eHkJCQmpqapKSksbGxZ2dnaGhoZ2dnZGRkYWFhXl5eZ2dncXFxf39/hISEioqKkZGRmZmZoaGhqampsrKyvb29dnZ2dnZ2dXV1cnJyb29va2trcHBwenp6hISEkpKSmpqaoaGhqKior6+vt7e3vr6+x8fHg4ODhISEg4ODgYGBfn5+e3t7e3t7g4ODjY2Nl5eXpKSkrq6utLS0u7u7wsLCysrK09PTk5OTlJSUk5OTkZGRj4+Pi4uLiIiIj4+PmJiYoaGhqqqqtLS0wcHBxsbGzMzM09PT3NzcoqKipKSkpKSkoqKioKCgnp6empqanZ2dpKSkrKystbW1vLy8xcXF0dHR19fX3Nzc4+Pjs7OztLS0s7OzsrKysbGxrq6urKysqampsLCwt7e3vr6+xsbGzMzM09PT39/f5OTk6urqw8PDxMTEw8PDwsLCwcHBv7+/vb29u7u7vr6+xMTEysrK0NDQ1tbW3Nzc4uLi6urq8PDw09PT1NTU1NTU09PT0tLS0dHRz8/Pzc3Nzc3N0tLS19fX3Nzc4eHh5ubm6urq7+/v9PT04+Pj5OTk5OTk5OTk4+Pj4uLi4eHh39/f3t7e4eHh5eXl6enp7Ozs7+/v8vLy9fX19/f38PDw8PDw8PDw8PDw7+/v8PDw7u7u7u7u7e3t7e3t8PDw8vLy9PT09/f3+Pj4+vr6/Pz8ICAgIiIiJSUlKioqMTExNzc3PDw8SkpKWVlZWlpaW1tbXl5eYWFhZmZma2trcnJygYGBJCQkJiYmKSkpLS0tNDQ0OTk5Pj4+TExMWFhYWVlZW1tbXl5eYmJiZmZmampqdHR0g4ODKioqKysrLi4uMjIyODg4PT09QkJCUFBQWFhYWlpaXFxcXl5eYmJiZmZmbm5uenp6iYmJKioqLi4uMzMzNzc3PDw8QkJCSUlJVlZWV1dXWlpaW1tbX19fYmJia2trdXV1gYGBkZGRNzc3Nzc3OTk5Ozs7Q0NDSEhIUVFRVVVVV1dXWVlZXFxcY2Nja2trdXV1f39/ioqKmZmZR0dHSEhISkpKS0tLTk5OUVFRVVVVWVlZXl5eZGRkaWlpcXFxeHh4gYGBi4uLlpaWpaWlYmJiY2NjYmJiYWFhYGBgXFxcYmJiampqcHBwdXV1enp6gICAh4eHkJCQmZmZo6OjsbGxcHBwcXFxcHBwcHBwbW1taWlpa2trdHR0gICAhYWFi4uLkpKSmJiYoKCgqKiosbGxvb29f39/f39/f39/fn5+e3t7d3d3dHR0fX19h4eHlZWVm5uboaGhqKior6+vtra2vr6+x8fHjY2Njo6OjY2Ni4uLiYmJhYWFgYGBh4eHkJCQmpqap6enr6+vtbW1vLy8w8PDysrK0tLSm5ubnJycnJycmpqamJiYlZWVkZGRkpKSm5ubpKSkra2ttra2wcHBx8fHzc3N1NTU3NzcqqqqrKysq6urqqqqqKiopqamoqKioKCgp6enrq6utra2vr6+xsbG0dHR19fX3d3d5OTkubm5ubm5uLi4uLi4t7e3tbW1srKyr6+vsrKyubm5wMDAx8fHzc3N1NTU39/f5OTk6+vrx8fHyMjIx8fHx8fHxsbGxcXFwsLCwMDAv7+/xcXFy8vL0dHR19fX3d3d4uLi6+vr8fHx1tbW19fX19fX1tbW1tbW1NTU09PT0dHRz8/P09PT2NjY3d3d4uLi5ubm6+vr7+/v9fX15eXl5eXl5eXl5eXl5eXl5OTk4+Pj4uLi4ODg4eHh5eXl6enp7e3t8PDw8/Pz9fX19/f38fHx8vLy8fHx8fHx8fHx8PDw8PDw7+/v7u7u7e3t8PDw8vLy9fX19/f3+fn5+vr6+/v7KSkpKysrLi4uMzMzOTk5QUFBRkZGSkpKWVlZaWlpcHBwcnJydXV1eXl5fn5+g4ODioqKLCwsLy8vMTExNjY2Ozs7QkJCR0dHTExMW1tba2trcHBwcnJydXV1eXl5fX19gYGBioqKMjIyNDQ0NjY2OTk5Pz8/RUVFS0tLUFBQX19fbm5ucHBwcnJydXV1eXl5fn5+g4ODi4uLNjY2OTk5Ozs7Pz8/RERES0tLUFBQVlZWZGRkb29vcHBwcnJydnZ2eXl5fn5+goKCj4+POTk5Ojo6Pj4+RUVFSkpKUVFRV1dXXV1da2trbm5ucHBwcnJydXV1eXl5f39/iYmJmJiYSEhISkpKS0tLTU1NT09PWFhYXl5eZ2dna2trbW1tb29vcnJyeHh4gYGBioqKlJSUpKSkW1tbXV1dXV1dX19fYWFhY2NjZmZmampqbm5udHR0eXl5gICAh4eHj4+PmZmZoqKir6+veXl5e3t7e3t7enp6eHh4dnZ2cnJyeHh4gYGBhoaGi4uLkZGRmJiYoKCgp6ensLCwvLy8iIiIiYmJiIiIh4eHhoaGhISEf39/gYGBioqKlpaWnJycoqKiqampr6+vtra2vb29xsbGlZWVl5eXlpaWlpaWlJSUkZGRjY2Ni4uLk5OTnZ2dqqqqsLCwtra2vLy8w8PDycnJ0tLSpKSkpaWlpaWlpKSkoqKin5+fnJycl5eXnp6epqamrq6uubm5wcHBx8fHzc3N1NTU3NzcsbGxtLS0s7OzsrKysLCwrq6uq6urp6enqampsLCwuLi4wMDAyMjI0tLS19fX3d3d5OTkv7+/wMDAv7+/v7+/vb29u7u7ubm5tra2tLS0urq6wcHByMjIzs7O1dXV39/f5OTk6urqzMzMzc3Nzc3NzMzMy8vLycnJyMjIxcXFwsLCxsbGzMzM0tLS2NjY3d3d4uLi7Ozs8fHx2tra29vb29vb2tra2dnZ2NjY1tbW1dXV09PT1NTU2dnZ3d3d4uLi5+fn6+vr7+/v9fX16Ojo6Ojo6Ojo6Ojo5+fn5ubm5ubm5eXl4+Pj4uLi5eXl6enp7e3t8PDw8/Pz9vb2+Pj48vLy8vLy8vLy8vLy8vLy8vLy8fHx8fHx8PDw7+/v8PDw8vLy9fX19/f3+fn5+/v7/Pz8MzMzNTU1Nzc3Ozs7QUFBSEhIUVFRV1dXW1tbaWlpeXl5iYmJi4uLj4+Pk5OTmJiYoKCgNzc3ODg4Ojo6Pj4+RERES0tLU1NTWFhYXFxcampqe3t7iIiIi4uLjo6OkpKSlpaWoKCgOzs7PT09Pz8/QkJCR0dHTk5OVlZWXFxcX19fbW1tfn5+iYmJi4uLjo6Ok5OTmJiYoaGhQUFBQkJCRUVFSEhITExMU1NTW1tbYGBgZGRkcnJygoKCiIiIi4uLj4+Pk5OTmJiYoKCgQkJCRUVFSkpKT09PU1NTWVlZYGBgZmZmampqeXl5hoaGiIiIi4uLj4+PkpKSlpaWnp6eSkpKTExMTU1NUFBQWVlZYGBgZmZmbGxsc3NzgICAhYWFh4eHioqKjY2NkJCQlJSUoaGhXFxcXl5eX19fYGBgY2NjZWVlbm5udHR0fX19gYGBhISEhoaGiYmJj4+Pl5eXoKCgra2tb29vcXFxcnJyc3NzdXV1d3d3enp6fX19gYGBhYWFioqKkJCQl5eXnp6epqamrq6uurq6j4+PkZGRkZGRkpKSkZGRj4+PjY2NiYmJjo6Ol5eXnZ2doqKiqKiorq6utLS0vLy8xcXFnp6eoKCgn5+fn5+fnp6enZ2dm5ublpaWl5eXoKCgq6ursLCwtra2vLy8wsLCyMjI0dHRq6urra2tra2trKysq6urqqqqp6eno6OjoaGhqampsbGxvLy8wsLCyMjIzs7O1NTU3Nzcubm5urq6urq6ubm5ubm5t7e3tLS0sbGxrKyss7Ozurq6wcHBysrK0tLS2NjY3d3d5OTkxsbGx8fHxsbGxcXFxMTEw8PDwMDAvr6+urq6vLy8w8PDycnJ0NDQ19fX4ODg5eXl6urq0tLS0tLS0tLS0dHR0NDQz8/Pzs7Oy8vLyMjIx8fHzs7O09PT2dnZ39/f5OTk7Ozs8fHx3t7e39/f3t7e3t7e3d3d3Nzc29vb2dnZ19fX1dXV2dnZ3t7e4+Pj5+fn7Ozs8PDw9vb26urq6+vr6urq6urq6urq6enp6Ojo5+fn5ubm5OTk5eXl6enp7e3t8PDw8/Pz9fX1+Pj49PT09PT09PT08/Pz8/Pz8/Pz8/Pz8vLy8vLy8PDw8PDw8/Pz9fX19/f3+fn5+vr6/Pz8Pj4+Pz8/QkJCRkZGS0tLUlJSWlpaY2NjaGhobW1teXl5iYmJm5ubpKSkqKiorKystLS0QUFBQkJCRERESEhITU1NVFRUXFxcZWVlampqbm5uenp6i4uLnJycpKSkpqamq6urs7OzRkZGR0dHSUlJTExMUVFRV1dXX19faGhobGxscHBwfX19jo6On5+fpKSkqKiorKystLS0S0tLTU1NTk5OUlJSV1dXXFxcY2Nja2trcHBwdHR0goKCkpKSoaGhpKSkqKiorKystLS0UFBQU1NTVlZWWVlZXV1dYmJiaWlpcHBwdnZ2eXl5h4eHl5eXoaGhpKSkqKiorKyss7OzUFBQU1NTV1dXXV1dZGRkaWlpb29vdnZ2e3t7gICAjo6OnZ2doKCgo6OjpqamqqqqsbGxXV1dX19fYWFhYmJiZWVlbm5udnZ2fX19g4ODiYmJlpaWnJycn5+foqKipaWlqKior6+vcHBwcnJyc3NzdXV1dnZ2eHh4e3t7hYWFioqKk5OTmJiYm5ubnZ2dn5+fpKSkq6urt7e3hYWFhoaGh4eHiIiIiYmJi4uLjY2NkJCQk5OTl5eXnJycoaGhpqamrKyssrKyubm5wsLCoqKipKSkpKSkpaWlpqampqampKSkoqKinp6epKSkrKyssbGxtra2u7u7wMDAx8fH0NDQs7OztbW1tLS0tLS0s7OzsrKysbGxr6+vq6urrKystLS0vb29w8PDyMjIzs7O09PT29vbv7+/wcHBwcHBwMDAwMDAvr6+vb29u7u7t7e3tbW1vLy8w8PDzc3N09PT2NjY3d3d5OTky8vLzMzMzMzMy8vLy8vLysrKyMjIxcXFw8PDvr6+xcXFy8vL0tLS2dnZ4ODg5eXl6+vr1tbW19fX19fX19fX1tbW1dXV09PT0tLSz8/PzMzMz8/P1NTU2tra4ODg5eXl7Ozs8fHx4uLi4uLi4uLi4uLi4uLi4ODg4ODg3t7e3d3d2tra2tra39/f5OTk6Ojo7e3t8PDw9/f37Ozs7u7u7e3t7e3t7Ozs7Ozs6+vr6urq6enp6Ojo5ubm6urq7e3t8PDw9PT09vb2+Pj49fX19fX19vb29fX19fX19fX19PT09PT08/Pz8vLy8fHx8vLy9fX19/f3+fn5+/v7/Pz8SkpKS0tLTU1NUVFRVlZWXFxcZGRkbW1tdnZ2enp6f39/iYmJm5ubrKysurq6vr6+xcXFS0tLTU1NUFBQU1NTWFhYXl5eZWVlbm5ud3d3e3t7f39/i4uLnJycrKysubm5vb29xMTEUVFRUlJSVFRUV1dXXFxcYmJiaWlpcXFxeXl5fn5+goKCjY2Nnp6er6+vurq6vr6+xsbGVlZWWFhYWlpaXV1dYWFhZmZmbW1tdXV1fX19goKChoaGkZGRoqKisrKyurq6vr6+xsbGXl5eX19fYWFhY2NjZ2dnbGxscnJyeXl5gYGBhoaGioqKl5eXpqamtbW1urq6vr6+xMTEXl5eYmJiZWVlampqbm5ucnJyeHh4f39/h4eHjIyMj4+PnZ2dq6urtra2ubm5vLy8xMTEYGBgYmJiZWVlampqcXFxenp6f39/hoaGjY2NkpKSlpaWpKSksrKytra2ubm5u7u7wsLCcnJydHR0dXV1dnZ2eHh4e3t7hYWFjY2NlJSUmZmZn5+fq6ursrKytLS0t7e3ubm5v7+/hoaGiIiIiIiIiYmJi4uLjY2Nj4+PkpKSm5uboKCgqKiora2tr6+vsbGxs7Oztra2v7+/mZmZnJycnJycnZ2dnp6en5+foaGho6OjpaWlqKiorKysr6+vtLS0ubm5vr6+xMTEzc3Ns7Oztra2tra2t7e3uLi4ubm5ubm5uLi4tra2srKyt7e3vr6+w8PDyMjIzMzM0tLS2dnZxcXFx8fHx8fHx8fHxsbGxsbGxMTEw8PDwcHBvb29v7+/xsbGzs7O09PT2NjY3t7e5OTk0NDQ0dHR0dHR0NDQ0NDQ0NDQz8/Pzs7Oy8vLyMjIx8fHzc3N09PT3Nzc4eHh5ubm6+vr29vb29vb29vb29vb29vb2tra2tra2NjY1tbW1NTU0NDQ1tbW29vb4eHh5+fn7e3t8vLy5eXl5ubm5ubm5ubm5eXl5eXl5OTk4+Pj4uLi39/f3d3d39/f5eXl6enp7e3t8fHx9vb27+/v8PDw7+/v7+/v7+/v7u7u7u7u7u7u7e3t6+vr6urq6urq7e3t8fHx8/Pz9vb2+fn59/f39/f39/f39/f39/f39vb29fX19fX19fX19PT09PT08/Pz9fX19/f3+vr6+/v7/Pz8V1dXWFhYW1tbXl5eY2NjaGhocHBwd3d3gYGBioqKjo6OkpKSm5ubrKysurq6ycnJ09PTWVlZW1tbXV1dYGBgZWVlampqcXFxeXl5goKCi4uLj4+Pk5OTnJycrKysu7u7yMjI09PTXl5eYGBgYWFhZGRkaGhobm5udHR0fHx8hISEjo6OkZGRlpaWnp6er6+vvb29y8vL09PTYmJiZWVlZ2dnampqbW1tcnJyeHh4f39/iIiIkZGRlJSUmJiYoqKisbGxwMDAzMzM1NTUampqa2trbW1tb29vc3Nzd3d3fX19hISEjIyMlJSUmJiYnJycpqamtbW1w8PDzc3N09PTbm5ucXFxc3NzdnZ2eXl5fX19g4ODiYmJkZGRmZmZnZ2doKCgq6urubm5xsbGzc3N09PTbm5ucXFxdHR0eXl5gICAhISEiYmJkJCQl5eXnp6eo6OjpaWlsbGxvr6+ycnJzMzM0tLSdXV1d3d3eHh4eXl5f39/h4eHkZGRl5eXnZ2dpKSkqKiorKyst7e3w8PDyMjIy8vL0NDQiYmJioqKi4uLjIyMjo6Oj4+PkpKSm5uboqKiqamprq6us7Ozvr6+xMTExsbGycnJzc3NnJycnp6enp6en5+foKCgoaGho6OjpaWlp6enr6+vtLS0u7u7wMDAwcHBw8PDxcXFysrKra2tsLCwsLCwsLCwsbGxsrKytLS0tLS0tra2uLi4u7u7vr6+wcHBxsbGysrKz8/P19fXxMTExsbGxsbGxsbGyMjIycnJysrKysrKycnJx8fHxMTEycnJz8/P09PT19fX3Nzc4uLi1tbW19fX1tbW1tbW1tbW1tbW1NTU1NTU0tLS0dHRzs7O0NDQ1dXV3d3d4eHh5ubm6+vr39/f4ODg4ODg4ODg39/f39/f3t7e3t7e3d3d29vb2NjY19fX3d3d4uLi6enp7u7u8vLy6enp6enp6enp6enp6enp6enp6Ojo5+fn5ubm5eXl4+Pj4eHh5ubm6urq7u7u8vLy9vb28fHx8vLy8vLy8vLy8fHx8vLy8vLy8fHx8PDw7+/v7u7u7Ozs7u7u8vLy9PT09/f3+fn5+fn5+Pj4+Pj4+Pj4+Pj4+Pj49/f39/f39/f39vb29vb29PT09fX19/f3+fn5+/v7/Pz8Z2dnaGhoampqbm5ucnJyd3d3fX19hYWFjY2NlpaWn5+foqKipqamq6uru7u7ycnJ2NjYaWlpa2trbW1tb29vc3NzeXl5f39/hoaGjo6Ol5eXoKCgo6Ojp6enq6uru7u7ycnJ2NjYbW1tb29vcHBwc3Nzd3d3fHx8goKCiYmJkZGRmZmZoqKipaWlqKiorq6uvb29y8vL2tracXFxc3NzdXV1d3d3e3t7gICAhYWFjIyMlJSUnJycpKSkqKioq6ursbGxwMDAzc3N29vbeHh4eXl5enp6fX19gICAhYWFioqKkZGRmJiYoKCgp6enq6urrq6utbW1w8PDz8/P3NzcfX19gICAgICAg4ODhoaGioqKkJCQlpaWnZ2dpKSkq6urrq6usbGxuLi4xsbG0dHR3t7efn5+goKChISEiYmJjY2NkZGRlpaWm5uboqKiqKior6+vsrKytbW1vr6+ysrK1dXV3t7efn5+gYGBg4ODiIiIjo6OlpaWnJycoaGhp6enra2ttLS0t7e3ubm5w8PDzs7O2NjY3t7ejY2Njo6Ojo6Oj4+PkJCQlJSUnZ2dp6enrKyssrKyt7e3u7u7vb29yMjI0tLS2NjY3Nzcn5+foaGhoaGhoqKio6OjpKSkpqamp6enr6+vtra2vLy8wMDAxMTEzs7O1NTU1tbW2trasLCwsrKysrKys7OztLS0tLS0tbW1tra2uLi4ubm5wcHBxsbGzMzM0NDQ0tLS1NTU19fXwMDAwcHBwsLCwsLCwsLCw8PDxMTExcXFxsbGyMjIysrKzMzMz8/P0tLS1tbW2tra39/f09PT09PT1NTU1NTU1dXV1tbW19fX2NjY2dnZ2NjY19fX1NTU2NjY3d3d4uLi5ubm6urq4+Pj5OTk5OTk5OTk5OTk4+Pj4+Pj4+Pj4uLi4eHh4ODg3d3d39/f5OTk6urq7u7u8/Pz7Ozs7e3t7Ozs7Ozs7Ozs7Ozs6+vr6+vr6+vr6+vr6enp5+fn5ubm6+vr7+/v9PT09/f39PT09PT09PT09PT09PT09PT08/Pz8/Pz8/Pz8vLy8fHx8PDw7u7u8fHx9fX19/f3+vr6+fn5+vr6+fn5+fn5+fn5+fn5+fn5+fn5+fn5+Pj4+Pj49/f39/f39/f3+vr6+/v7/Pz8enp6e3t7fX19f39/g4ODiIiIjo6OlZWVnJycpKSkrKyss7Oztra2uLi4u7u7ysrK2NjYe3t7fX19fn5+gYGBhISEiYmJj4+PlpaWnp6epaWlra2ts7OztbW1uLi4u7u7ycnJ2NjYfn5+gICAgoKChISEh4eHjIyMkpKSmJiYoKCgp6enr6+vtbW1t7e3urq6vb29y8vL2tragoKChISEhoaGiIiIi4uLkJCQlZWVm5uboqKiqampsbGxt7e3urq6vLy8wMDAzc3N29vbiIiIiYmJi4uLjY2NkJCQlJSUmZmZn5+fpqamrKyss7Ozurq6vLy8vr6+wsLC0NDQ3d3djY2Nj4+PkJCQk5OTlpaWmZmZnp6eo6Ojqampr6+vtra2vLy8vr6+wMDAxcXF0tLS39/fkpKSlJSUlpaWmJiYm5ubn5+fo6OjqKiora2ts7Ozurq6v7+/wcHBxMTEycnJ1dXV4eHhkJCQk5OTlpaWmpqan5+fpKSkqKiora2tsrKyt7e3vb29wsLCxcXFx8fHzs7O2dnZ5OTkkJCQkpKSlJSUmJiYnZ2dpKSkrKyssbGxtra2u7u7wMDAxcXFyMjIysrK0tLS3Nzc5ubmoqKipaWlpaWlpqamp6enp6enqampsbGxurq6v7+/xMTEycnJzMzMzs7O19fX4ODg5+fntLS0tbW1tra2tra2t7e3t7e3uLi4ubm5urq6wcHByMjIzc3N0dHR1NTU3d3d4uLi5eXlw8PDxMTExcXFxcXFxsbGxsbGxsbGx8fHyMjIycnJy8vL0tLS1tbW29vb39/f4eHh5OTk0NDQ0dHR0dHR0dHR0tLS0tLS09PT1NTU1NTU1tbW19fX2dnZ29vb3d3d4ODg5OTk6enp39/f4ODg4ODg4eHh4uLi4uLi4+Pj5OTk5eXl5+fn5ubm5eXl4+Pj5ubm6urq7+/v8vLy7+/v7+/v7+/v8PDw7+/v7+/v7+/v7+/v7+/v7+/v7u7u7e3t6+vr7Ozs8PDw9fX19/f39vb29vb29vb29vb29vb29vb29fX19vb29vb29fX19fX19PT08/Pz8vLy9fX19/f3+vr6+vr6+vr6+vr6+/v7+vr6+vr6+/v7+vr6+vr6+vr6+vr6+fn5+Pj49/f3+vr6/Pz8/f39j4+PkJCQkZGRlJSUmJiYnJycoaGhp6enra2ts7Ozurq6wMDAxMTEx8fHycnJy8vL2dnZkJCQkZGRk5OTlZWVmJiYnZ2doqKiqKiora2ts7Ozurq6v7+/xMTExsbGycnJy8vL2NjYkpKSlJSUlpaWmJiYm5ubn5+fpKSkqampr6+vtbW1u7u7wcHBxsbGyMjIysrKzMzM2tralpaWmJiYmZmZm5ubnp6eoqKip6enrKyssbGxuLi4vb29w8PDyMjIycnJzMzMzs7O29vbm5ubnJycnZ2dn5+foqKipaWlqampr6+vtLS0urq6v7+/xcXFysrKy8vLzc3N0NDQ3d3dnp6eoKCgoqKio6Ojpqamqampra2tsrKyt7e3vLy8wcHBx8fHy8vLzc3Nzs7O0tLS39/fo6OjpqampqamqKioqqqqra2tsbGxtbW1urq6v7+/xMTEycnJzs7Oz8/P0dHR1dXV4uLipKSkpqamqKioq6urrq6usrKytbW1ubm5vb29wsLCx8fHy8vL0NDQ0tLS09PT2dnZ5OTkoqKipaWlpqamqqqqrq6utLS0ubm5vLy8wcHBxMTEycnJzs7O09PT1NTU1tbW3d3d5ubmp6enqampqampqampq6ursLCwt7e3vr6+w8PDyMjIzMzM0dHR1dXV19fX2tra4eHh6urqt7e3ubm5urq6urq6urq6urq6urq6vLy8w8PDy8vLz8/P1NTU2NjY3Nzc3d3d5eXl7e3txsbGyMjIyMjIyMjIycnJycnJysrKysrKy8vLzMzM0tLS19fX3Nzc39/f4uLi6urq7+/v09PT1dXV1dXV1dXV1dXV1dXV1tbW19fX2NjY2NjY2dnZ2tra39/f4+Pj6Ojo7Ozs7u7u39/f39/f39/f39/f4ODg4ODg4ODg4eHh4uLi4+Pj5OTk5eXl5ubm6Ojo6+vr7u7u8PDw7Ozs7Ozs7Ozs7Ozs7e3t7e3t7u7u7+/v8PDw8fHx8fHx8fHx8fHx7+/v8fHx9fX19/f39/f3+Pj4+Pj49/f39/f3+Pj4+Pj4+Pj4+Pj4+Pj49/f39/f39/f39fX19vb2+Pj4+/v7/Pz8+/v7+/v7/Pz8+/v7+/v7/Pz8+/v7+/v7+/v7+/v7+/v7+vr6+vr6+vr6+/v7/Pz8p6enp6enqKioq6urra2tsbGxtbW1ubm5vr6+w8PDx8fHzc3N0dHR1dXV19fX2dnZ3NzcpqamqKioqampq6urrq6usbGxtbW1ubm5vb29w8PDyMjIzMzM0dHR1dXV19fX2NjY3NzcqKioqqqqrKysra2tsLCwsrKytra2u7u7wMDAxMTEycnJzs7O0tLS1tbW19fX2dnZ3d3dq6urra2trq6ur6+vsrKytbW1ubm5vb29wcHBxsbGysrKz8/P1NTU2NjY2dnZ29vb3t7er6+vsLCwsbGxsrKytbW1uLi4u7u7v7+/w8PDyMjIzMzM0NDQ1dXV2dnZ2tra3Nzc39/fsbGxs7OztbW1tra2uLi4urq6vr6+wcHBxcXFycnJzs7O0tLS1tbW2tra29vb3d3d4ODgtbW1t7e3uLi4ubm5u7u7vr6+wcHBxMTEyMjIzMzMz8/P1NTU2NjY3Nzc3d3d39/f4uLit7e3urq6u7u7vLy8vr6+wcHBw8PDxsbGysrKzc3N0dHR1tbW2tra3t7e39/f4eHh5OTktra2uLi4ubm5u7u7v7+/w8PDxcXFycnJzMzMz8/P09PT19fX29vb4ODg4eHh4+Pj5ubmsrKytbW1tra2ubm5vLy8wcHBxsbGy8vLzs7O0tLS1tbW2dnZ3t7e4eHh4+Pj5eXl6urqvLy8vr6+vb29vb29vr6+vr6+wsLCycnJz8/P1NTU2NjY3Nzc4ODg5OTk5ubm5+fn7e3ty8vLzc3NzMzMzc3Nzc3Nzc3Nzc3Nzc3Nzc3N1NTU29vb39/f4uLi5ubm6enp6urq8PDw2NjY2dnZ2dnZ2dnZ2dnZ2dnZ2dnZ2tra2tra29vb29vb4ODg5eXl6enp7Ozs7+/v9PT04uLi4+Pj4+Pj4+Pj4+Pj5OTk5OTk5OTk5eXl5ubm5+fn5+fn6Ojo7Ozs8PDw8/Pz9vb27Ozs7Ozs7Ozs7Ozs7e3t7Ozs7e3t7u7u7u7u7u7u7+/v8PDw8fHx8vLy8/Pz9fX19vb29fX19fX19fX19vb29vb29vb29vb29/f3+Pj4+Pj4+fn5+fn5+fn5+Pj4+Pj4+fn5+/v7/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8+/v7+/v7/f39vr6+v7+/v7+/wMDAwsLCxcXFyMjIy8vLzs7O0tLS1tbW2tra3t7e4uLi5OTk5eXl5+fnvb29v7+/wMDAwcHBw8PDxMTEx8fHysrKzs7O0tLS1dXV2dnZ3d3d4eHh5OTk5eXl5+fnvr6+wMDAwsLCwsLCxcXFx8fHycnJzMzM0NDQ09PT1tbW2tra3t7e4uLi5eXl5ubm6OjowcHBwsLCxMTExcXFx8fHycnJy8vLzs7O0dHR1NTU2NjY29vb39/f4+Pj5eXl5+fn6enpxMTExMTExcXFxsbGyMjIysrKzMzMz8/P0tLS1dXV2dnZ3Nzc4ODg5OTk5+fn5+fn6urqxMTExsbGx8fHyMjIycnJy8vLzc3N0NDQ09PT1tbW2tra3d3d4eHh5OTk5ubm6Ojo6urqxsbGyMjIycnJysrKy8vLzc3N0NDQ0tLS1dXV2NjY3Nzc39/f4uLi5ubm6Ojo6enp7OzsycnJysrKy8vLzMzMzc3Nz8/P0dHR1NTU19fX2dnZ3d3d4eHh5OTk5+fn6enp6+vr7e3tycnJysrKy8vLzc3Nz8/P0dHR0tLS1dXV2NjY29vb3t7e4eHh5eXl6Ojo6+vr7Ozs7u7uxcXFx8fHyMjIysrKzc3N0NDQ1NTU1tbW2dnZ3Nzc39/f4+Pj5ubm6enp7Ozs7u7u7+/vwsLCw8PDxcXFx8fHysrKzc3N0dHR1tbW29vb3t7e4eHh5OTk6Ojo6+vr7u7u7+/v8PDw0dHR0tLS0dHR0tLS0dHR0tLS0dHR09PT2dnZ3t7e4+Pj5ubm6urq7e3t8PDw8vLy8/Pz3t7e3t7e3t7e3t7e3t7e3t7e3d3d3d3d3t7e3d3d4uLi6Ojo7Ozs7+/v8vLy9PT09fX16Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6enp6enp6enp6enp6enp7e3t8fHx9PT09vb29/f38PDw8PDw8PDw8PDw8fHx8fHx8fHx8fHx8fHx8vLy8vLy8vLy8/Pz8/Pz9vb2+Pj4+vr69vb29/f39vb29vb29/f39vb29/f39vb29/f39/f39/f3+Pj4+Pj4+fn5+fn5+vr6+vr6+/v7+/v7+/v7+/v7+/v7+/v7+/v7/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/f39/Pz8/f39/f391dXV1dXV1tbW1tbW19fX2dnZ29vb3d3d4ODg4uLi5eXl6Ojo6urq7e3t7+/v8fHx8vLy09PT1NTU1dXV1tbW19fX2dnZ2tra3d3d39/f4uLi5OTk5+fn6urq7Ozs7+/v8fHx8vLy1dXV1tbW1tbW2NjY2NjY2dnZ3Nzc3t7e4ODg4+Pj5ubm6Ojo6+vr7e3t7+/v8fHx8/Pz1tbW19fX2NjY2NjY2tra29vb3d3d3t7e4eHh5OTk5ubm6enp6+vr7e3t8PDw8vLy8/Pz2NjY2NjY2dnZ2tra29vb3Nzc3t7e39/f4uLi5OTk5+fn6enp7Ozs7u7u8fHx8vLy8/Pz2NjY2dnZ2tra29vb3Nzc3d3d39/f4ODg4uLi5eXl5+fn6urq7Ozs7u7u8fHx8vLy8/Pz2dnZ29vb29vb3Nzc3d3d3t7e4ODg4uLi4+Pj5ubm6Ojo6urq7e3t7+/v8fHx8/Pz9fX129vb3Nzc3Nzc3Nzc3t7e39/f4eHh4uLi5OTk5+fn6enp6+vr7u7u8PDw8vLy9PT09fX13Nzc3Nzc3d3d3t7e3t7e4ODg4eHh4+Pj5eXl5+fn6urq7Ozs7+/v8fHx8/Pz9fX19vb22NjY2dnZ29vb3Nzc3t7e4ODg4uLi4+Pj5ubm6Ojo6+vr7e3t7+/v8vLy9PT09vb29/f31dXV19fX2NjY2dnZ29vb3t7e4eHh5OTk5+fn6enp6+vr7u7u8fHx8/Pz9fX19/f3+Pj42NjY2NjY2dnZ2NjY2NjY29vb3t7e4uLi5ubm6urq7e3t7+/v8vLy9PT09/f3+fn5+fn55eXl5eXl5eXl5OTk5OTk5OTk4+Pj4+Pj5OTk6Ojo7Ozs8PDw8/Pz9fX1+Pj4+fn5+vr67u7u7+/v7u7u7u7u7u7u7u7u7u7u7u7u7u7u7e3t7Ozs7+/v9PT09vb2+fn5+fn5+/v79fX19fX19vb29fX19fX19fX19fX19vb29fX19vb29vb29fX19PT09/f3+vr6+/v7/Pz8+vr6+fn5+vr6+fn5+vr6+fn5+vr6+vr6+vr6+vr6+vr6+vr6+vr6+vr6+/v7+/v7/Pz8/Pz8/Pz8+/v7/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/f39/Pz8/Pz8/Pz8/f39/f39/f39/f39\"};function Rue(e){let t=XG[e]??XG.portrait400,s=atob(t),r=17,o=new Uint8Array(r*r*r*4);for(let a=0;a<r;a++)for(let i=0;i<r;i++)for(let l=0;l<r;l++){let c=((a*r+i)*r+l)*3,d=(i*r*r+a*r+l)*4;o[d]=s.charCodeAt(c),o[d+1]=s.charCodeAt(c+1),o[d+2]=s.charCodeAt(c+2),o[d+3]=255}return o}var Due=[1,.38,.16],Lue=.62,Uue=JU({amount:T(\"weave\"),field:\"weaveTime\"}),Oue=v8({select:T(\"stock\"),strength:T(\"strength\"),size:17,decode:Rue,fallback:\"portrait400\",label:\"filmstock-lut\"}),HG=ZU({strength:T(\"halation\"),radius:T(\"halationRadius\"),tint:Due,threshold:Lue,output:\"halationTexture\",extractName:\"filmStockHalationExtract\"}),jG=H({name:\"FilmStock\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Real analog film color from measured film-emulation LUTs \\u2014 ten classic stock looks with emulsion halation and projector gate weave\",requiresRTT:!0,requiresChild:!0,extraFields:{weaveTime:{schema:n,initial:0}},props:{stock:{default:\"portrait400\",description:\"Film stock \\u2014 each look is a real measured film-emulation color LUT\",compileTime:!0,ui:{type:\"select\",options:[...zue],label:\"Stock\",group:\"Stock\"}},strength:{default:1,description:\"How strongly the stock's color grade is applied\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Stock\"}},halation:{default:.4,transform:e=>e*10,description:\"Strength of the red-orange highlight glow (film emulsion backscatter)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Halation\",group:\"Halation\"}},halationRadius:{default:28,description:\"Spread of the halation glow in pixels\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Halation Radius\",group:\"Halation\"}},weave:{default:0,description:\"Gate weave \\u2014 subtle projector-like frame jitter and rotation\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Gate Weave\",group:\"Weave\"}}},compute:HG.compute,gpu:{fragment:e=>{let{childNode:t,computeOutputs:s,convertToTexture:r}=e;if(!t)return console.error(\"You must pass a child component into the FilmStock shader.\"),xt;let o=s?.childTexture??r(t),a=Uue(e),i=W(Yt,\"unpremultiplyAlpha\",[o.sample(a)]);return HG.screen(Oue(i,e),a,e)}}});var KG=H({name:\"Flip\",role:\"warp\",category:\"Distortions\",description:\"Mirror content horizontally, vertically, or both\",boundingBoxDeclaration:{aspectRatio:null},props:{flipX:{default:!1,transform:rs,description:\"Mirror the content horizontally (left \\u2194 right)\",ui:{type:\"checkbox\",label:\"Flip X\",group:\"Effect\"}},flipY:{default:!1,transform:rs,description:\"Mirror the content vertically (top \\u2194 bottom)\",ui:{type:\"checkbox\",label:\"Flip Y\",group:\"Effect\"}}},map:NL({flipX:T(\"flipX\"),flipY:T(\"flipY\")}),edges:\"none\",missingChildMessage:\"You must pass a child component into the Flip shader.\"});var $g=8192,Gue=3e3,K_=vn({desktop:1024,mobile:512}),ZG=\"rgba16float\",QG=bt,Fue=.12,Iue=.035,Yue=1.4,Wue=2,que=3.5,Vue=1.1,Nue=Wo,JG=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({color:S,count:n,dt:n,time:n,aspect:n,domainX:n,driftBase:n,angleRad:n,speedVar:n,angleVarRad:n,randomness:n,twinkle:n,softness:n,bodyR:n,cursorX:n,cursorY:n,cursorRadSq:n,cursorForce:n,dragMul:n}),\"SimParams\"),Ml=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({agents:{storage:Fe(S,$g),access:\"mutable\"},accumE:{storage:Fe(lo(M),K_*K_),access:\"mutable\"},params:{uniform:JG},outTex:{storageTexture:zt(ZG,\"write-only\")}}),\"simLayout\"),$ue=eg(Ml,\"floatingParticlesInit\"),Xue=On.drift2d(Ml,{drift:eO.variedHeading(Ml),gust:Za.cursorGust(Ml),name:\"floatingParticlesUpdate\"});function Y2(e){return Gn.pointWorld(Ml,{shape:e,res:K_,place:Dg.orbitalPlace(Ml,{radius:Iue,rate:Yue}),brightness:Dg.twinkleBrightness(Ml,{freq:Wue}),bodyRadius:Dg.presenceRadius(Ml),names:{splat:\"floatingParticlesSplat\",resolve:\"floatingParticlesResolve\"}})}var Hue=e=>Y2(e).splat.kernel,wxe=Hue(\"dot\"),Txe=Y2(\"dot\").resolve.kernel,jue=dz,eF=H({name:\"FloatingParticles\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Textures\",description:\"Drifting, twinkling motes \\u2014 thousands of real simulated particles floating in a shared heading with per-particle wander and variance, and a cursor that stirs the field with a gust that settles back into the drift\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{particleColor:{default:\"#ffffff\",transform:ce,description:\"Color of the particles\",ui:{type:\"color\",label:\"Particle Color\",group:\"Colors\"}},shape:{default:\"dot\",compileTime:!0,description:\"What each particle is drawn as \\u2014 a crisp dot or square (softness still feathers them), or a soft glow puff\",ui:{type:\"select\",options:cp,label:\"Shape\",group:\"Effect\"}},count:{default:1200,description:\"Number of particles\",ui:{type:\"range\",min:100,max:$g,step:100,label:\"Count\",group:\"Effect\"}},particleSize:{default:1.2,description:\"Size of the particles (each also varies slightly for depth)\",ui:{type:[\"range\",\"map\"],min:.3,max:4,step:.05,label:\"Particle Size\",group:\"Effect\"}},softness:{default:.1,description:\"Edge softness of each particle \\u2014 0 is a crisp shape, 1 a soft glow puff\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},speed:{default:.25,description:\"Speed of the shared drift\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Speed\",group:\"Animation\"}},angle:{default:90,description:\"Drift heading in degrees (0 = left, 90 = up, 180 = right, 270 = down \\u2014 the classic default floats upward)\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Angle\",group:\"Animation\"}},speedVariance:{default:.3,description:\"Per-particle speed variance around the shared drift (0 = everything moves in lockstep)\",ui:{type:\"range\",min:0,max:1,step:.05,label:\"Speed Variance\",group:\"Animation\"}},angleVariance:{default:30,description:\"Per-particle heading variance in degrees (0 = one shared direction, 180 = every which way)\",ui:{type:\"range\",min:0,max:180,step:1,label:\"Angle Variance\",group:\"Animation\"}},randomness:{default:.25,description:\"Orbital wander \\u2014 each particle circles lazily around its drift path instead of gliding straight\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Randomness\",group:\"Animation\"}},twinkle:{default:.5,description:\"Intensity of the twinkle (0 = steady, 1 = full shimmer)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Twinkle\",group:\"Animation\"}},cursorStrength:{default:0,description:\"How strongly the cursor stirs the field \\u2014 0 (default) leaves the drift undisturbed\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Cursor Gust\",group:\"Interaction\"}}},...Fn({layout:Ml,params:JG,maxAgents:$g,countCap:{desktop:$g,mobile:Gue},output:{key:\"outTex\",name:\"particleTexture\",size:[K_,K_],format:ZG},bake:({getCpuValue:e})=>{let t=Y2(e(\"shape\")||\"dot\");return{pipelines:{init:{kernel:$ue,threads:\"max\"},update:{kernel:Xue,threads:\"agents\"},splat:t.splat,resolve:t.resolve},initStep:\"init\",program:[\"update\",\"splat\",\"resolve\"]}},frame:(e,{getCpuValue:t})=>{let s=Li(t),r=0;return o=>{let{dt:a,aspect:i,pointerX:l,pointerY:c}=Di(o);r+=a;let d=Math.max(i,.01),u=e.resolveCount(s(\"count\",1200)),p=l*i,_=c,f=.22,h=t(\"particleColor\"),g=Math.min(Math.max(s(\"particleSize\",1.2),.3),4)*2/Ri;return e.writeParams({color:S(h?.x??1,h?.y??1,h?.z??1,h?.w??1),count:u,dt:a,time:r,aspect:i,domainX:d,driftBase:Math.min(Math.max(s(\"speed\",.25),0),1.5)*Fue/.25,angleRad:s(\"angle\",90)*QG+Nue,speedVar:Math.min(Math.max(s(\"speedVariance\",.3),0),1),angleVarRad:Math.min(Math.max(s(\"angleVariance\",30),0),180)*QG,randomness:Math.min(Math.max(s(\"randomness\",.25),0),1),twinkle:Math.min(Math.max(s(\"twinkle\",.5),0),1),softness:Math.min(Math.max(s(\"softness\",.1),0),1),bodyR:g,cursorX:p,cursorY:_,cursorRadSq:f*f,cursorForce:Math.min(Math.max(s(\"cursorStrength\",0),0),1)*que,dragMul:Sp(Vue,a)}),e.frame({count:u})}},fragment:{output:\"particleTexture\",fallback:\"child\",compose:(e,{childNode:t})=>t?W(jue,\"particleOverChild\",[e,t]):e}})});var tF=H({role:\"shape\",name:\"Flower\",description:\"Petal shape with N lobes and adjustable inner-to-outer radius ratio\",shape:{distance:({x:e,y:t},s)=>dR(e,t,s(\"radius\"),s(\"sides\"),s(\"innerRatio\")),colorDescription:\"Fill color of the flower\",centerDescription:\"Center position of the flower\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.4,description:\"Outer petal tip radius in UV space\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Radius\",group:\"Shape\"}},sides:{default:5,description:\"Number of petals\",ui:{type:\"range\",min:3,max:12,step:1,label:\"Petals\",group:\"Shape\"}},innerRatio:{default:.4,description:\"Inner valley radius as a ratio of outer radius \\u2014 lower values make deeper notches\",ui:{type:\"range\",min:.1,max:.95,step:.01,label:\"Inner Ratio\",group:\"Shape\"}}}}});var sF=H({name:\"FlowField\",role:\"warp\",category:\"Distortions\",description:\"Fluid-like distortion with constant smooth motion\",boundingBoxDeclaration:{aspectRatio:null},animatedTime:{speed:\"speed\"},extraAnimatedTimes:{evolution:\"evolutionSpeed\"},props:{strength:{default:.15,description:\"Intensity of the flow distortion\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.01,label:\"Strength\",group:\"Effect\"}},detail:{default:2,description:\"Scale of the flow patterns\",ui:{type:[\"range\",\"map\"],min:.5,max:5,step:.1,label:\"Detail\",group:\"Effect\"}},speed:{default:0,description:\"Speed of the flow\",ui:{type:\"range\",min:0,max:20,step:.1,label:\"Speed\",group:\"Animation\"}},evolutionSpeed:{default:0,description:\"How fast the flow field pattern reshapes over time\",ui:{type:\"range\",min:0,max:20,step:.1,label:\"Evolution Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed for flow pattern variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},edges:{default:\"mirror\",description:\"How to handle edges when distortion pushes content out of bounds\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},map:rU({strength:T(\"strength\"),detail:T(\"detail\"),seed:T(\"seed\")})});var Kue=4*Math.PI,Ep=[{scale:2,offsets:[[5.2,1.3],[1.7,9.2]],reach:.25},{scale:1.5,offsets:[[8.3,2.8],[3.1,7.4]],reach:.2}],rF=H({name:\"FlowingGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Liquid silk gradient with organic flowing color bands\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},extraFields:{convA:{schema:A,initial:[0,0,0]},convB:{schema:A,initial:[0,0,0]},convC:{schema:A,initial:[0,0,0]},convD:{schema:A,initial:[0,0,0]}},props:{colorA:{default:\"#0a0015\",transform:ce,description:\"Deep background color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#6b17e6\",transform:ce,description:\"Primary accent color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},colorC:{default:\"#ff4d6a\",transform:ce,description:\"Secondary accent color\",ui:{type:\"color\",label:\"Color C\",group:\"Colors\"}},colorD:{default:\"#ff6b35\",transform:ce,description:\"Tertiary accent color\",ui:{type:\"color\",label:\"Color D\",group:\"Colors\"}},colorSpace:{default:\"oklch\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},speed:{default:1,description:\"Animation speed\",ui:{type:\"range\",min:0,max:10,step:.1,label:\"Speed\",group:\"Effect\"}},distortion:{default:.5,description:\"Organic distortion intensity\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Distortion\",group:\"Effect\"}},seed:{default:0,description:\"Random seed for variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}}},paint:e=>{let{uv:t,viewport:s}=aa(e),r=z(Ce(s.member(\"x\"),it(s.member(\"y\"),1e-6)),\"aspect\"),o=z(v(wt(e),.075),\"flowTime\"),a=z(v(me(T(\"seed\"),e),.17),\"flowSeed\"),i=z(me(T(\"distortion\"),e),\"flowStrength\"),l=z(ne(t,.5),\"flowCentred\"),c=z(v(v(Jn(Qe(I(v(l.member(\"x\"),.8),v(o,.4)),ne(v(l.member(\"y\"),.8),v(o,.25)),a)),Kue),i),\"flowAngle\"),d=z(ng(rt(l.member(\"x\"),Ce(l.member(\"y\"),r)),Do(c),Vt(c)),\"flowSpun\"),u=z(rt(d.member(\"x\"),v(d.member(\"y\"),r)),\"flowRot\"),p=v(o,2),_=z(I(u.member(\"x\"),v(Ce(Vt(I(v(u.member(\"y\"),5),p)),50),i)),\"flowShearX\"),f=z(o2({at:rt(_,I(u.member(\"y\"),v(Ce(Vt(I(v(_,7.5),p)),25),i))),scale:Ep[0].scale,z:I(v(o,.5),a),offsets:Ep[0].offsets,reach:Ep[0].reach,strength:i}),\"flowWarp1\"),h=z(I(v(o,.3),a),\"flowTz\"),g=z(o2({at:f.member(\"xy\"),scale:Ep[1].scale,z:h,offsets:Ep[1].offsets,reach:Ep[1].reach,strength:i}),\"flowWarp2\"),y=Jn(Qe(v(g.member(\"x\"),1.8),v(g.member(\"y\"),1.8),h)),b=z(ts(I(v(f.member(\"z\"),.5),.5),1.5),\"flowHardness\"),x=z(et(.5,.008,b),\"flowEdge\"),P=z(ot(v(x,-1),x,y),\"flowT1\"),C=z(ot(v(x,-1),x,f.member(\"w\")),\"flowT2\"),E=z(OR({a:T(\"colorA\"),b:T(\"colorB\"),c:T(\"colorC\"),d:T(\"colorD\"),space:T(\"colorSpace\")})(P,C,e),\"flowBase\"),R=k=>ne(1,ms(ne(v(k,2),1))),U=v(it(R(P),R(C)),b),L=v(I(v(I(v(g.member(\"z\"),.5),.5),.12),.94),I(1,v(U,.35)));return Ot(Ge(v(E.member(\"rgb\"),L),kt(0),kt(1)),E.member(\"a\"))}});var oF=IU({shape:T(\"shape\"),angle:T(\"angle\"),frequency:T(\"frequency\"),softness:T(\"softness\"),waveAmplitude:T(\"waveAmplitude\"),waveFrequency:T(\"waveFrequency\"),refraction:T(\"refraction\"),aberration:T(\"aberration\")}),aF=H({name:\"FlutedGlass\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Distortions\",description:\"Full-screen fluted glass effect \\u2014 refracts content through repeating cylindrical bars\",animatedTime:{speed:\"speed\"},props:{shape:{default:\"bars\",description:\"Cross-section shape of each flute\",compileTime:!0,transform:e=>({bars:0,rounded:1,waves:2})[e]??0,ui:{type:\"select\",options:[{label:\"Bars\",value:\"bars\"},{label:\"Rounded\",value:\"rounded\"},{label:\"Waves\",value:\"waves\"}],label:\"Shape\",group:\"Effect\"}},angle:{default:0,description:\"Direction of the flutes in degrees (0 = vertical bars)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},frequency:{default:10,description:\"Number of flutes across the longest viewport axis\",ui:{type:[\"range\",\"map\"],min:1,max:20,step:1,label:\"Frequency\",group:\"Effect\"}},softness:{default:.5,description:\"How smoothly distortion fades from each flute centre to its edge (0 = flat middle / sharp seams, 1 = gentle curve)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},waveAmplitude:{default:.06,description:\"How far each flute sways horizontally as it travels (Waves shape only)\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.01,label:\"Wave Amplitude\",group:\"Effect\",condition:{shape:\"waves\"}}},waveFrequency:{default:1.5,description:\"How many sways fit along each flute (Waves shape only)\",ui:{type:[\"range\",\"map\"],min:.1,max:10,step:.1,label:\"Wave Frequency\",group:\"Effect\",condition:{shape:\"waves\"}}},speed:{default:0,description:\"Animation speed \\u2014 drifts the flute pattern over time and flows wave perturbations\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Speed\",group:\"Animation\"}},refraction:{default:1.5,description:\"How aggressively each flute bends content beneath it\",ui:{type:[\"range\",\"map\"],min:0,max:4,step:.01,label:\"Refraction\",group:\"Effect\"}},aberration:{default:.2,description:\"Chromatic aberration \\u2014 splits RGB along the refraction direction at flute seams\",recompile:hn((e,t)=>e>0!=t>0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Aberration\",group:\"Effect\"}},lightAngle:{default:30,description:\"Direction the light source is coming from (0 = head-on, 90 = grazing)\",ui:{type:\"range\",min:-90,max:90,step:1,label:\"Light Angle\",group:\"Highlight\"}},highlight:{default:.2,description:\"Strength of the specular reflection on each flute\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Highlight\",group:\"Highlight\"}},highlightSoftness:{default:.3,description:\"Spread of the specular peak (0 = pin-tight, 1 = broad sheen)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlight Softness\",group:\"Highlight\"}},highlightColor:{default:\"#ffffff\",transform:ce,description:\"Color of the specular highlight\",ui:{type:\"color\",label:\"Highlight Color\",group:\"Highlight\"}},edges:{default:\"mirror\",description:\"How to handle edges when distortion samples beyond the canvas\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},effect:$o(YU(oF,{aberration:T(\"aberration\"),edges:T(\"edges\")}),[WU(oF,{lightAngle:T(\"lightAngle\"),highlight:T(\"highlight\"),softness:T(\"highlightSoftness\"),color:T(\"highlightColor\")})],{resultAlpha:\"straight\"})});var en=256,Fd=en*en,Que=10,Zue=6,Jue=50,epe=.15,tpe=en*.6,iF=3,spe=\"rgba16float\",nF=Mn,lF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,time:n,seed:n,turbulence:n,curlStrength:n,velFade:n,blending:n,cursorX:n,cursorY:n,cursorVelX:n,cursorVelY:n,mouseActive:n,mouseRadSq:n}),\"FogParams\"),Q_=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,Fd),access:\"mutable\"},velB:{storage:Fe(S,Fd),access:\"mutable\"},dyeA:{storage:Fe(S,Fd),access:\"mutable\"},dyeB:{storage:Fe(S,Fd),access:\"mutable\"},pressure:{storage:Fe(n,Fd),access:\"mutable\"},divergence:{storage:Fe(n,Fd),access:\"mutable\"},params:{uniform:lF}}),\"fluidLayout\"),cF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({dyeA:{storage:Fe(S,Fd),access:\"readonly\"},outTex:{storageTexture:zt(spe,\"write-only\")}}),\"outputLayout\"),rpe=Pz(Q_,{n:en,namePrefix:\"fog\",frequency:iF}),ope=Cz(Q_,{n:en,namePrefix:\"fog\"}),dF=zn(Q_,{n:en,namePrefix:\"fog\",boundary:\"toroidal\",dye:\"densityAge\",velocityCap:tpe}),{curl:Fxe,vorticity:Ixe,divergence:Yxe,jacobi:Wxe,gradSubtract:qxe,advectVel:Vxe,copyVel:Nxe,advectDye:$xe,copyDye:Xxe}=dF,ape=Mz(Q_,{n:en,namePrefix:\"fog\",frequency:iF}),npe=Ui(cF,{n:en,namePrefix:\"fog\",dye:\"densityAge\"}),uF=H({name:\"Fog\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Fog that fills the screen and interacts with the mouse\",usesPointer:!0,props:{colorA:{default:\"#e0e0e0\",transform:ce,description:\"Primary fog color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#888888\",transform:ce,description:\"Secondary fog color \\u2014 creates variation across the field\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},seed:{default:0,description:\"Deterministic starting pattern \\u2014 different seeds produce different fog configurations\",ui:{type:\"range\",min:0,max:999,step:1,label:\"Seed\",group:\"Field\"}},speed:{default:1,description:\"Simulation speed multiplier\",ui:{type:\"range\",min:.1,max:3,step:.1,label:\"Speed\",group:\"Field\"}},turbulence:{default:1,description:\"Ambient motion strength\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Turbulence\",group:\"Field\"}},detail:{default:15,description:\"Fine-scale swirling structure \\u2014 higher values produce more intricate wisps and vortices\",ui:{type:\"range\",min:0,max:50,step:1,label:\"Detail\",group:\"Field\"}},blending:{default:.3,description:\"How much the two colors blend together \\u2014 0 behaves like oil & water (colors stay distinct with sharp boundaries), 1 behaves like food coloring (colors fully mix)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Blending\",group:\"Field\"}},mouseInfluence:{default:.1,description:\"Strength of cursor influence \\u2014 move the cursor to push fog\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Cursor Influence\",group:\"Interaction\"}},mouseRadius:{default:.1,description:\"Radius of cursor influence area\",ui:{type:\"range\",min:.02,max:.5,step:.01,label:\"Cursor Radius\",group:\"Interaction\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},...Ii(()=>{let e=t=>({seed:t.num(\"seed\",0),turbulence:t.num(\"turbulence\",1),curlStrength:t.num(\"detail\",15),velFade:epe,blending:t.num(\"blending\",.3)});return{resolution:en,layout:Q_,outputLayout:cF,paramsSchema:lF,solver:{kernels:dF,jacobiIters:Que},output:{kernel:npe,key:\"fogTexture\"},write:\"thunk\",pointer:{minDrag:5e-4},init:dO({kernel:rpe,seed:t=>t.num(\"seed\",0),warm:{steps:Jue,jacobiIters:Zue,dt:.1,startTime:()=>Math.random()*60,values:(t,s)=>({dt:.1,time:t,...e(s),cursorX:0,cursorY:0,cursorVelX:0,cursorVelY:0,mouseActive:0,mouseRadSq:1})}}),solve:[lO(ope),cO(ape)],values:t=>{let s=t.num(\"mouseInfluence\",.1),r=t.num(\"mouseRadius\",.1)*en,o=t.ptr,a=o.moving&&s>0;return{dt:t.dt*t.num(\"speed\",1),time:t.elapsed,...e(t),cursorX:a?o.x*en:0,cursorY:a?o.y*en:0,cursorVelX:a?o.dx*en*15*s:0,cursorVelY:a?o.dy*en*15*s:0,mouseActive:a?1:0,mouseRadSq:r*r}}}}),gpu:{fragment:({ctx:e,computeOutputs:t,propValues:s,uniforms:r})=>{let o=t?.fogTexture;if(!o)return xt;let a=o.sample(e.uv,\"linearClamp\"),i=a.member(\"x\"),l=a.member(\"y\"),c=s.colorSpace??0,d=W(nF.mixColorsVariants[c]??nF.mixColorsLinear,\"mixColors\",[r.colorA,r.colorB,l]);return Ct(d.member(\"rgb\"),d.member(\"a\").mul(i))}}});var pF=H({name:\"FractalNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Multi-octave fractal Brownian motion noise texture with true noise evolution\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#000000\",transform:ce,description:\"First color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Second color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),octaves:{default:4,compileTime:!0,description:\"Number of noise octaves (more = more detail)\",ui:{type:\"range\",min:1,max:8,step:1,label:\"Octaves\",group:\"Effect\"}},detail:{default:2,description:\"How much finer each successive octave becomes\",ui:{type:[\"range\",\"map\"],min:1,max:4,step:.1,label:\"Detail\",group:\"Effect\"}},contrast:{default:.5,description:\"How strongly finer octaves contribute \\u2014 higher values create more texture contrast\",ui:{type:[\"range\",\"map\"],min:.1,max:1,step:.01,label:\"Contrast\",group:\"Effect\"}},speed:{default:.15,description:\"Speed at which the noise pattern evolves in place\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Speed\",group:\"Animation\"}},angle:{default:0,transform:cs,description:\"Rotation angle in degrees\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Angle\",group:\"Effect\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:ZD({angle:T(\"angle\"),detail:T(\"detail\"),contrast:T(\"contrast\"),octaves:T(\"octaves\"),seed:T(\"seed\"),space:T(\"colorSpace\")})});var ipe=JSON.stringify({type:\"sphere3D\",radius:.35}),mF=H({name:\"Frost\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photoreal frozen ice \\u2014 thickness-driven subsurface scattering that reads as a solid block, with fine frost crystals creeping in from the edges\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",chord:\"firstLobe\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=e.volumetric,a=.01,i=Lr(e,t,{scale:s.scale}),{s0:l,sX:c,sY:d,sdf:u,pxH:p}=i,_=Ln(i),f=Jr(i,s.edgeSoftness),h=go(e,i),g=h.member(\"x\"),y=h.member(\"y\"),b=z(Ge(Ce(v(u,-1),it(.3,.01)),0,1),\"depthNorm\"),x,P;if(o){let Ve=z(Ge(Ce(ne(c.member(\"w\"),l.member(\"w\")),a),-4,4),\"ddx\"),qe=z(Ge(Ce(ne(d.member(\"w\"),l.member(\"w\")),a),-4,4),\"ddy\");x=z(Os(Qe(Ve,qe,-1)),\"nBase\"),P=z(Ce(1,I(1,v(Ge(I(v(Ve,Ve),v(qe,qe)),0,2),2))),\"steepAtten\")}else{let Ve=z(v(ho(it(ne(1,v(b,b)),0)),1.8),\"bevelSlope\");x=z(Os(Qe(v(_.member(\"x\"),Ve),v(_.member(\"y\"),Ve),-1)),\"nBase\"),P=It(1)}let C=z(v(Hu(i,e),s.density),\"thickness\"),E=z(Ge(v(C,1.2),0,1),\"depthT\"),R=z(wg(C,v(Qe(1.6,.85,.45),s.absorption)),\"transmit\"),U=z(v(et(Qe(1,1,1),s.iceColor.member(\"rgb\"),kt(E)),R),\"scatteredRgb\"),L=z(v(ne(1,ot(0,it(v(s.frostDepth,.3),.01),v(u,-1))),s.frostAmount),\"frostField\"),k=z(v(s.frostScale,60),\"frostScl\"),D=.004,O=z(co(v(g,k),v(y,k)),\"fn0\"),F=Ce(ne(co(v(I(g,D),k),v(y,k)),O),D),q=Ce(ne(co(v(g,k),v(I(y,D),k)),O),D),Y=z(v(v(L,s.frostRoughness),P),\"frostNormalAmp\"),V=v(s.frostScale,40),X=W(I3,\"mxWorleyNoiseFloat2Pub\",[rt(v(g,V),v(y,V)),It(1)]),Q=z(Js(Zo(L,0),Qe(v(v(F,Y),.03),v(v(q,Y),.03),v(ot(.25,0,X),L)),Qe(0,0,0),\"frostFx\",[h,L,k,P]),\"fx3\"),te=Gi(x,Q.member(\"x\"),Q.member(\"y\")),J=Un(Er(s.lightAngle,\"light\"),-.6),oe=J.member(\"L\"),le=z($t(te,oe),\"ndl\"),se=z(Ge($t(te,J.member(\"H\")),0,1),\"ndh\"),Te=ts(I(v(le,.5),.5),.7),de=v(v(v(R,Ge(I(v($t(oe,Qe(0,0,1)),.5),.5),0,1)),s.scatter),ne(1,v(E,.4))),xe=I(v(U,I(v(Te,.6),.5)),v(de,.5)),Ae=z(I(v(co(I(v(g,190),13.7),ne(v(y,190),4.3)),.5),.5),\"glintField\"),De=I(v(Vt(I(v(r,3),v(Ae,40))),.5),.5),Ee=Js(Zo(L,0),v(v(v(ot(.72,.96,v(Ae,De)),I(v(ts(se,6),.6),.4)),L),s.sparkle),It(0),\"sparkleGlint\",[h,L,se]),ze=v(Qe(.95,.98,1),I(v(Q.member(\"z\"),.4),v(Ee,4))),Ie=v(ts(Fi(te),3),s.fresnel),ke=v(Qe(.85,.93,1),v(Ie,1.5)),Me=z(v(v(ts(se,16),.4),s.gloss),\"broadSpec\"),we=z(I(I(I(I(xe,v(Qe(.4,.46,.55),s.ambient)),kt(Me)),ke),ze),\"iceRgb\");return Js(Dr(u,p),Ot(we,f),xt,\"frost\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the ice shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the ice shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the ice shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},iceColor:{default:\"#0597fc\",transform:ce,description:\"Ice tint \\u2014 the color deep ice saturates toward (thin edges stay near white)\",ui:{type:\"color\",label:\"Ice Color\",group:\"Ice\"}},ambient:{default:0,description:\"Cool ambient fill so shadowed ice never goes black\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Ambient\",group:\"Ice\"}},edgeSoftness:{default:.05,description:\"Softness of the shape boundary edge\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Ice\"}},density:{default:5,description:\"Optical depth multiplier \\u2014 how thick and deep the ice reads\",ui:{type:\"range\",min:0,max:10,step:.01,label:\"Density\",group:\"Subsurface\"}},absorption:{default:1,description:\"Beer\\u2013Lambert absorption strength \\u2014 higher drives a deeper blue-teal core\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Absorption\",group:\"Subsurface\"}},scatter:{default:.5,description:\"Forward back-lit glow transmitted through thin ice\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Scatter\",group:\"Subsurface\"}},frostAmount:{default:.8,description:\"Overall density of the rim frost crystals\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Frost\",group:\"Frost\"}},frostDepth:{default:.4,description:\"How far the frost creeps inward from the rim\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Frost Depth\",group:\"Frost\"}},frostScale:{default:1,description:\"Crystal size \\u2014 higher = finer, busier frost\",ui:{type:\"range\",min:.3,max:4,step:.01,label:\"Frost Scale\",group:\"Frost\"}},frostRoughness:{default:3,description:\"Feathery roughness of the frost crystal surface\",ui:{type:\"range\",min:1,max:5,step:.01,label:\"Frost Roughness\",group:\"Frost\"}},sparkle:{default:.5,description:\"Tiny bright crystal glints catching the light at the rim\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Sparkle\",group:\"Frost\"}},gloss:{default:.6,description:\"Surface sheen \\u2014 the broad soft icy specular\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Gloss\",group:\"Surface\"}},fresnel:{default:.02,description:\"Cold rim glow on grazing surfaces\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Fresnel\",group:\"Surface\"}},lightAngle:{default:300,description:\"Key light direction in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Surface\"}},speed:{default:.3,description:\"Sparkle twinkle speed. 0 freezes the sparkle.\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Speed\",group:\"Animation\"}},shape:{default:ipe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var _F=H({name:\"GaborNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Oriented sine-grain noise with a fingerprint-like flow\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:1.5,description:\"Pattern scale (higher = finer, more detailed patterns; each +1 roughly doubles the frequency)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},frequency:{default:8,description:\"Frequency of the oriented waves within each cell\",ui:{type:\"range\",min:1,max:24,step:.5,label:\"Frequency\",group:\"Effect\"}},...Ja(),...In()},paint:Vs(ua(Qa(gp(VD({frequency:T(\"frequency\")})),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var{applyGlassEffect:lpe}=ip,cpe=JSON.stringify({type:\"sphere3D\",radius:.35});function dpe(e){let{childNode:t,gpu:s,convertToTexture:r,registerComputeTexture:o,getCpuValue:a,onCleanup:i,onResize:l,dimensions:c}=e,d=s?.root,u=a(\"blur\");if(!t||!d||typeof u==\"number\"&&u<=0)return null;let p=r(t),_=Math.max(1,Math.round(c.width)),f=Math.max(1,Math.round(c.height)),h=Vh(d,null,_,f,i),g=o(h.outputTexture);return l(({width:y,height:b})=>{_=Math.max(1,Math.round(y)),f=Math.max(1,Math.round(b)),h.setInputDimensions(_,f)}),{outputs:{childTexture:p,blurredTexture:g},bindInputs:y=>{let b=y(p.key);b&&h.setInputTexture(b.texture)},getComputeNodes:()=>{let y=a(\"blur\");return typeof y==\"number\"&&h.updateRadius(y*2),h.computeSteps}}}var fF=Ts({chord:\"firstLobe\",gradSampler:\"same\",bakedGradients:\"all\",stencil:\"none\",child:\"required\",surface:(e,t)=>lpe(t,e.sampler,e.childTexture,t.computeOutputs?.blurredTexture,{volumetric:e.volumetric,bakedGradients:e.bakedGradients})}),upe=e=>{let t=fF.compute(e),s=dpe(e);return!t&&!s?null:{outputs:{...s?.outputs,...t?.outputs},bindInputs:s?.bindInputs,getComputeNodes:r=>{let o=[...s?.getComputeNodes()??[],...t?.getComputeNodes(r)??[]];return o.length?o:null}}},vF=H({name:\"Glass\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Optically realistic glass lens driven in a custom shape\",requiresRTT:!0,requiresChild:!0,...fF,compute:upe,props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the glass shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the glass shape (1 = default size)\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the glass shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},cutout:{default:!1,description:\"Cut out the alpha outside the glass shape\",transform:rs,compileTime:!0,ui:{type:\"checkbox\",label:\"Cutout\",group:\"Glass\"}},...gr({refraction:{default:1,description:\"Lens refraction \\u2014 how aggressively the edges warp content beneath (0 = none, 1 = max)\",ui:{max:2}},edgeSoftness:{default:.1,description:\"Edge softness \\u2014 higher values give a wider, softer fade at the glass boundary\"}}),blur:{default:0,recompile:hn((e,t)=>e>0!=t>0),description:\"Frosted blur amount \\u2014 0 = clear glass, higher = frosted/diffuse\",ui:{type:\"range\",min:0,max:20,step:.1,label:\"Blur\",group:\"Glass\"}},...gr({thickness:{transform:e=>e*.5,description:\"Glass depth \\u2014 how far inward from the edge the refraction extends\"}}),aberration:{default:.5,recompile:hn((e,t)=>e>0!=t>0),description:\"Chromatic aberration \\u2014 splits RGB channels along the refraction vector\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Aberration\",group:\"Glass\"}},innerZoom:{default:1,description:\"Inner zoom level \\u2014 magnifies content seen through the glass\",ui:{type:[\"range\",\"map\"],min:.5,max:3,step:.01,label:\"Inner Zoom\",group:\"Glass\"}},...gr({lightAngle:{default:300,description:\"Light angle in degrees\",ui:{group:\"Highlight\"}},highlight:{default:.05,description:\"Directional edge highlight \\u2014 bright rim on the light-facing boundary\"},highlightColor:{description:\"Color of the directional edge highlight and specular glint\"},highlightSoftness:{description:\"Specular highlight softness\"},fresnel:{description:\"Fresnel rim glow \\u2014 a soft luminous halo around the glass boundary\"},fresnelSoftness:!0,fresnelColor:!0}),tintColor:{default:\"#ffffff\",transform:ce,description:\"Color tint applied to the internal directional gradient\",ui:{type:\"color\",label:\"Tint Color\",group:\"Tint\"}},tintIntensity:{default:0,description:\"Intensity of the color tint applied to the glass interior\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Tint Intensity\",group:\"Tint\"}},tintPreserveLuminosity:{default:!0,transform:rs,description:\"Preserve original brightness when tinting\",ui:{type:\"checkbox\",label:\"Preserve Luminosity\",group:\"Tint\"}},shape:{default:cpe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file \\u2014 when non-empty, activates SVG mode and triggers a shader recompile\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type \\u2014 triggers recompile when shape is switched. When empty, derived from shape JSON at mount time.\"}}});var hF=H({name:\"GlassTiles\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Distortions\",description:\"Refraction-like distortion in a tile grid pattern\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:2,description:\"The intensity of the glass tiles effect\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Intensity\",group:\"Effect\"}},tileCount:{default:20,description:\"Number of tiles across the longest dimension\",ui:{type:[\"range\",\"map\"],min:5,max:50,step:1,label:\"Tile Count\",group:\"Effect\"}},rotation:{default:0,description:\"Rotation angle of the tile grid in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},roundness:{default:0,description:\"Makes tiles more circular instead of square\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Roundness\",group:\"Effect\"}}},gpu:{fragment:e=>e.childNode?Y4({uv:e.ctx.uv,aspect:e.ctx.aspect,intensity:me(T(\"intensity\"),e),tileCount:me(T(\"tileCount\"),e),rotation:me(T(\"rotation\"),e),roundness:me(T(\"roundness\"),e),texture:e.convertToTexture(e.childNode)}):(console.error(\"You must pass a child component into the Glass Tiles shader.\"),xt),uvRemap:({uv:e,mask:t,uniforms:s,aspect:r})=>({uv:W4({uv:e,aspect:r,intensity:me(T(\"intensity\"),{uniforms:s}),tileCount:me(T(\"tileCount\"),{uniforms:s}),rotation:me(T(\"rotation\"),{uniforms:s}),roundness:me(T(\"roundness\"),{uniforms:s})}),mask:t})}});var W2=PU({intensity:T(\"intensity\"),speed:T(\"speed\"),blockDensity:T(\"blockDensity\"),mirrorAmount:T(\"mirrorAmount\")}),gF=H({name:\"Glitch\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Digital glitch that melts pixels and distorts colors\",props:{intensity:{default:.5,description:\"Overall glitch strength and frequency of glitch bursts\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}},speed:{default:1,description:\"How fast the glitch pattern evolves\",ui:{type:\"range\",min:.1,max:5,step:.1,label:\"Speed\",group:\"Effect\"}},rgbShift:{default:5,description:\"Amount of chromatic aberration (RGB channel splitting)\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.5,label:\"RGB Shift\",group:\"Effect\"}},blockDensity:{default:10,description:\"Base number of horizontal glitch bands\",ui:{type:[\"range\",\"map\"],min:2,max:50,step:1,label:\"Block Density\",group:\"Effect\"}},colorBarIntensity:{default:.2,description:\"Intensity of vivid neon color bar overlay in glitch regions\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Color Bars\",group:\"Effect\"}},mirrorAmount:{default:.3,description:\"Chance of glitch blocks showing mirrored/flipped content\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Mirror\",group:\"Effect\"}},scanlineIntensity:{default:.2,description:\"Visibility of CRT-style horizontal scanlines in distorted areas\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Scanlines\",group:\"Effect\"}}},effect:$o(CU(W2,{shift:T(\"rgbShift\")}),[MU(W2,{intensity:T(\"colorBarIntensity\")}),EU(W2,{intensity:T(\"scanlineIntensity\")})])});var yF=H({name:\"Glow\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Soft glow effect with adjustable intensity\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:1,description:\"Glow intensity (brightness of the glow effect)\",ui:{type:[\"range\",\"map\"],min:0,max:50,step:.5,label:\"Intensity\",group:\"Effect\"}},threshold:{default:.5,description:\"Brightness threshold for glow extraction (lower = more glow)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Threshold\",group:\"Effect\"}},size:{default:25,description:\"Glow spread in pixels (clean up to ~72px, mild banding above)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Glow Size\",group:\"Effect\"}}},...LU({intensity:T(\"intensity\"),threshold:T(\"threshold\"),size:T(\"size\")})});var bF=H({name:\"Godrays\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Volumetric light rays emanating from a point\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{center:{default:{x:0,y:0},transform:Xe,description:\"The center point of the god rays\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},density:{default:.3,description:\"Frequency of ray sectors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Density\",group:\"Effect\"}},intensity:{default:.8,description:\"Ray visibility within sectors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Intensity\",group:\"Effect\"}},spotty:{default:1,description:\"Density of spots on rays (higher = more spots)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Spotty\",group:\"Effect\"}},speed:{default:.5,description:\"Animation speed of the rays\",ui:{type:\"range\",min:0,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},rayColor:{default:\"#4283fb\",transform:ce,description:\"Color of the light rays\",ui:{type:\"color\",label:\"Ray Color\",group:\"Colors\"}},backgroundColor:{default:\"transparent\",transform:ce,description:\"Background color\",ui:{type:\"color\",label:\"Background Color\",group:\"Colors\"}}},paint:UD({color:T(\"rayColor\"),background:T(\"backgroundColor\"),coverage:vg(_D(T(\"center\")),yD({density:T(\"density\"),intensity:T(\"intensity\"),spotty:T(\"spotty\")}))})});var ppe=JSON.stringify({type:\"sphere3D\",radius:.35}),q2=7,kp=e=>{let t=Math.sin(e*12.9898)*43758.5453;return t-Math.floor(t)},xF=[],AF=[];for(let e=0;e<q2;e++){let t=e*2.399963,s=Math.sqrt((e+.5)/q2);xF.push([s*Math.cos(t),s*Math.sin(t),.5+kp(e+1),.5+kp(e+7)]),AF.push([.5+kp(e+13),kp(e+2)*6.2831853,kp(e+5)*6.2831853,kp(e+9)*6.2831853])}var wF=H({name:\"Goo\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photoreal wet liquid \\u2014 animated 3D metaball blobs that merge and bulge to loosely form the shape, with sliding wet highlights, a clearcoat rim and a translucent body\",animatedTime:{speed:\"speed\"},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the goo\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the goo (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the goo in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},gooColor:{default:\"#37c95a\",transform:ce,description:\"Base liquid color (a glossy slime green by default)\",ui:{type:\"color\",label:\"Goo Color\",group:\"Goo\"}},translucency:{default:.6,description:\"Subsurface glow strength \\u2014 deep lobes transmit more color\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Translucency\",group:\"Goo\"}},absorb:{default:2,description:\"How fast thin areas clear and thick areas saturate (Beer\\u2013Lambert)\",ui:{type:\"range\",min:0,max:6,step:.01,label:\"Absorption\",group:\"Goo\"}},containment:{default:.9,description:\"0 = free blobs that ignore the shape, 1 = goo fills the shape and its surface conforms to the 3D form (highlights track the faces as it rotates)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Containment\",group:\"Goo\"}},edgeSoftness:{default:.06,description:\"Softness of the blob coverage edge\",ui:{type:\"range\",min:0,max:.3,step:.005,label:\"Edge Softness\",group:\"Goo\"}},blobScale:{default:.3,description:\"Base radius of each liquid lobe\",ui:{type:\"range\",min:.1,max:1,step:.01,label:\"Blob Size\",group:\"Blobs\"}},spread:{default:1,description:\"How far the lobes scatter across the shape\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Spread\",group:\"Blobs\"}},merge:{default:.6,description:\"How much the lobes fuse together \\u2014 low = distinct beads, high = one fused mass\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Merge\",group:\"Blobs\"}},bulge:{default:1,description:\"How 3D-rounded each lobe reads \\u2014 dome height of the wet surface\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Bulge\",group:\"Blobs\"}},threshold:{default:.5,description:\"Iso-surface level \\u2014 lower makes fatter, fuller blobs\",ui:{type:\"range\",min:.2,max:.9,step:.01,label:\"Threshold\",group:\"Blobs\"}},lightAngle:{default:300,description:\"Light direction in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Lighting\"}},wetness:{default:2,description:\"Master scale on the sharp specular highlight and clearcoat rim\",ui:{type:\"range\",min:0,max:5,step:.01,label:\"Highlights\",group:\"Lighting\"}},fresnel:{default:.25,description:\"Clearcoat fresnel rim strength wrapping each lobe\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Fresnel\",group:\"Lighting\"}},specColor:{default:\"#ffffff\",transform:ce,description:\"Highlight / rim color (white reads as a clear wet coat)\",ui:{type:\"color\",label:\"Highlight Color\",group:\"Lighting\"}},ambient:{default:.25,description:\"Base fill so shadowed goo isn't black\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Ambient\",group:\"Lighting\"}},speed:{default:.5,description:\"Drift and breathe speed of the blobs. 0 pauses.\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Speed\",group:\"Animation\"}},wobble:{default:.5,description:\"Drift amplitude \\u2014 how far the lobe centers wander\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Wobble\",group:\"Animation\"}},breathe:{default:.3,description:\"Radius pulsing amplitude \\u2014 lobes swell and shrink\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Breathe\",group:\"Animation\"}},seed:{default:1,description:\"Variation offset \\u2014 shifts the blob arrangement\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}},shape:{default:ppe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ts({chord:\"firstLobe\",stencil:{kind:\"forward\",eps:.004},surface:(e,t)=>{let{uniforms:s}=t,r=z(wt(t,\"seed\"),\"gooT\"),o=.004,a=z(e.surf0,\"s0\"),i=z(e.sdfUV,\"sdfUV\"),l=z(ne(i.member(\"x\"),.5),\"px\"),c=z(ne(i.member(\"y\"),.5),\"py\"),d=ho(I(v(l,l),v(c,c))),u=z(v(s.spread,.45),\"spread\"),p=z(v(s.wobble,.12),\"driftAmp\"),_=z(s.breathe,\"breatheAmp\"),f=I(.65,v(s.merge,.7)),h=z(v(v(s.blobScale,.38),f),\"baseR\"),g=I(I(I(u,v(h,I(1,_))),p),.2),y=null,b=null,x=null;for(let we=0;we<q2;we++){let Ve=xF[we],qe=AF[we],st=z(I(v(Ve[0],u),v(p,Vt(I(v(r,Ve[2]),qe[1])))),`cx${we}`),pt=z(I(v(Ve[1],u),v(p,Do(I(v(r,Ve[3]),qe[2])))),`cy${we}`),Ze=z(v(h,I(1,v(_,Vt(I(v(r,qe[0]),qe[3]))))),`rVal${we}`),nt=z(Ce(1,it(v(Ze,Ze),1e-4)),`invR2_${we}`),ht=z(ne(l,st),`dcx${we}`),yt=z(ne(c,pt),`dcy${we}`),St=tr(v(v(I(v(ht,ht),v(yt,yt)),nt),-1)),Mt=z(ne(I(l,o),st),`dxx${we}`),Rt=tr(v(v(I(v(Mt,Mt),v(yt,yt)),nt),-1)),Kt=z(ne(I(c,o),pt),`dyy${we}`),Wt=tr(v(v(I(v(ht,ht),v(Kt,Kt)),nt),-1));y=y?I(y,St):St,b=b?I(b,Rt):Rt,x=x?I(x,Wt):Wt}let P=z(ne(1,ot(-.06,.06,a.member(\"x\"))),\"inside0\"),C=z(ne(1,ot(-.06,.06,e.surfX.member(\"x\"))),\"insideX\"),E=z(ne(1,ot(-.06,.06,e.surfY.member(\"x\"))),\"insideY\"),R=s.containment,U=z(I(v(y,et(It(1),P,R)),v(P,R)),\"H0\"),L=z(I(v(b,et(It(1),C,R)),v(C,R)),\"Hx\"),k=z(I(v(x,et(It(1),E,R)),v(E,R)),\"Hy\"),D=z(it(s.edgeSoftness,.001),\"soft\"),O=ot(ne(s.threshold,D),I(s.threshold,D),U),F=Ce(ne(L,U),o),q=Ce(ne(k,U),o),Y=z(I(v(s.bulge,.12),.03),\"metaSlope\"),V=Yr(Yr(P,C),E),X=z(v(v(R,1.6),V),\"shapeRelief\"),Q=Ge(Ce(ne(e.surfX.member(\"w\"),a.member(\"w\")),o),-6,6),te=Ge(Ce(ne(e.surfY.member(\"w\"),a.member(\"w\")),o),-6,6),J=z(Os(Qe(I(v(v(F,-1),Y),v(Q,X)),I(v(v(q,-1),Y),v(te,X)),-1)),\"n\"),oe=z(Ge(I(v(ho(it(ne(U,s.threshold),0)),s.bulge),v(v(it(v(a.member(\"x\"),-1),0),R),1.2)),0,1),\"thick\"),le=Un(Er(s.lightAngle,\"light\"),-.8),se=z(Ge($t(J,le.member(\"L\")),0,1),\"ndl\"),Te=z(Ge($t(J,le.member(\"H\")),0,1),\"ndh\"),de=v(ts(Te,232),1.7),xe=v(ts(Te,32),.25),Ae=v(ot(.992,.999,Te),1.9),De=v(ts(Fi(J),5),s.fresnel),Ee=v(s.specColor.member(\"rgb\"),v(I(I(I(de,xe),Ae),De),s.wetness)),ze=tr(v(v(s.absorb,-1),ne(1,oe))),Ie=z(s.gooColor.member(\"xyz\"),\"gooRgb\"),ke=v(v(Ie,v(s.translucency,ze)),I(v(se,.5),.5)),Me=z(I(I(v(Ie,I(s.ambient,v(se,.7))),ke),Ee),\"gooOut\");return Js(Hz(d,g),Ot(Me,v(O,s.gooColor.member(\"w\"))),xt,\"goo\")}})});var TF=H({name:\"GradientMap\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Maps source luminance through an animated color gradient (Photoshop-style gradient map)\",props:{palette:{default:\"rainbow\",compileTime:!0,description:\"Built-in cosine palette, or Custom Colors to pick your own stops\",ui:{type:\"select\",options:[{label:\"Rainbow\",value:\"rainbow\"},{label:\"Sunset\",value:\"sunset\"},{label:\"Ocean\",value:\"ocean\"},{label:\"Fire\",value:\"fire\"},{label:\"Pastel\",value:\"pastel\"},{label:\"Neon\",value:\"neon\"},{label:\"Custom Colors\",value:\"custom\"}],label:\"Palette\",group:\"Colors\"}},colorLow:{default:\"#1a0b2e\",transform:ce,description:\"Color for the darkest tones\",ui:{type:\"color\",label:\"Shadows\",group:\"Colors\",condition:{palette:\"custom\"}}},colorMid:{default:\"#e94560\",transform:ce,description:\"Color for the midtones\",ui:{type:\"color\",label:\"Midtones\",group:\"Colors\",condition:{palette:\"custom\"}}},colorHigh:{default:\"#f9ed69\",transform:ce,description:\"Color for the brightest tones\",ui:{type:\"color\",label:\"Highlights\",group:\"Colors\",condition:{palette:\"custom\"}}},speed:{default:.15,description:\"Gradient animation speed (0 = static). The gradient cycles seamlessly.\",ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.01,label:\"Speed\",group:\"Animation\"}},contrast:{default:1,description:\"Steepness of the luminance-to-gradient mapping\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Contrast\",group:\"Effect\"}},blackPoint:{default:0,description:\"Input shadow clip \\u2014 luminance at/below this maps to the start of the gradient\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Black Point\",group:\"Effect\"}},whitePoint:{default:1,description:\"Input highlight clip \\u2014 luminance at/above this maps to the end of the gradient\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"White Point\",group:\"Effect\"}},strength:{default:1,description:\"Blend between the original image (0) and the gradient-mapped result (1)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},colorSpace:{default:\"oklch\",transform:at,compileTime:!0,description:\"Color space for interpolating custom colors\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\",condition:{palette:\"custom\"}}}},effect:f8({palette:T(\"palette\"),colorLow:T(\"colorLow\"),colorMid:T(\"colorMid\"),colorHigh:T(\"colorHigh\"),speed:T(\"speed\"),contrast:T(\"contrast\"),blackPoint:T(\"blackPoint\"),whitePoint:T(\"whitePoint\"),strength:T(\"strength\"),colorSpace:T(\"colorSpace\")}),identityWhen:Uo(\"strength\"),missingChildMessage:\"You must pass a child component into the GradientMap shader.\"});var SF=H({name:\"Grayscale\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Convert colors to black and white\",props:{},effect:n8(),missingChildMessage:\"You must pass a child component into the Grayscale shader.\"});var PF=QR({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"flippedY\"}),thickness:T(\"thickness\"),softness:T(\"softness\"),variation:T(\"variation\")}),CF=H({name:\"Grid\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Simple grid lines pattern with adjustable thickness and rotation\",acceptsUVContext:!0,props:{color:{default:\"#ffffff\",transform:ce,description:\"The color of the grid lines\",ui:{type:\"color\",label:\"Line Color\",group:\"Colors\"}},cellColor:{default:\"transparent\",transform:ce,description:\"Fill color of the cells (transparent = lines only). Pair with Variation for a tiled look.\",ui:{type:\"color\",label:\"Cell Color\",group:\"Colors\"}},cells:{default:10,description:\"Number of cells along the canvas height (cells stay square; the width fits as many as the aspect ratio allows)\",ui:{type:[\"range\",\"map\"],min:1,max:50,step:1,label:\"Cells\",group:\"Effect\"}},thickness:{default:1,description:\"Thickness of grid lines (normalized, 0.0-1.0)\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Thickness\",group:\"Effect\"}},rotation:{default:0,description:\"Rotation of the grid in degrees. At 45\\xB0 this produces a crosshatch/diamond pattern.\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the line edges (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},variation:{default:0,description:\"Per-cell random lightening/darkening of the cell fill color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},mapSampleUVs:_g({cells:T(\"cells\"),rotation:T(\"rotation\"),props:[\"thickness\",\"cells\",\"rotation\",\"softness\"]}),paint:Zr({fill:Sc(T(\"cellColor\"),PF.shade),stroke:T(\"color\"),mask:PF.lines,space:T(\"colorSpace\")})});var MF=H({name:\"GridDistortion\",role:\"warp\",category:\"Interactive\",description:\"Interactive grid distortion controlled by mouse position\",boundingBoxDeclaration:{aspectRatio:null},usesPointer:!0,props:{intensity:{default:1,description:\"Strength of the distortion effect\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Intensity\",group:\"Effect\"}},decay:{default:3,description:\"Rate of distortion decay (higher = faster)\",ui:{type:\"range\",min:0,max:10,step:.1,label:\"Decay\",group:\"Effect\"}},radius:{default:1,description:\"Radius of the distortion effect\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Radius\",group:\"Effect\"}},gridSize:{default:20,recompile:hn((e,t)=>Rg(e)!==Rg(t)),description:\"Resolution of the distortion grid (higher = more detailed)\",ui:{type:[\"range\",\"map\"],min:8,max:128,step:1,label:\"Grid Size\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},...Ec(I8({gridSize:T(\"gridSize\"),decay:T(\"decay\"),intensity:T(\"intensity\"),radius:T(\"radius\"),output:\"displacement\"})),map:nU({gridSize:T(\"gridSize\"),output:\"displacement\"}),uvRemapIdentityWhen:({computeOutputs:e})=>!e?.displacement});var EF=H({name:\"Group\",role:\"structural\",species:\"custom\",category:\"Utilities\",description:\"Container for organizing and composing child effects \\u2014 supports flex-like flow layout (column/row stacking via the flow prop)\",requiresChild:!0,boundingBoxDeclaration:{aspectRatio:null,boxResamplesContent:!0},props:{},gpu:{fragment:({childNode:e})=>e??xt}});var mpe=e=>e===\"cmyk\"?1:0,_pe=e=>e===\"cmyk\"||e===1?\"cmyk\":\"classic\",kF=H({name:\"Halftone\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Halftone dot pattern effect for printing aesthetics\",blendWithChildren:!1,props:{style:{default:\"classic\",transform:mpe,compileTime:!0,description:\"Halftone rendering style\",ui:{type:\"select\",options:[{label:\"Simple\",value:\"classic\"},{label:\"CMYK Print\",value:\"cmyk\"}],label:\"Style\",group:\"Effect\"}},frequency:{default:100,description:\"Frequency of the halftone dots\",ui:{type:[\"range\",\"map\"],min:10,max:300,step:1,label:\"Frequency\",group:\"Effect\"}},angle:{default:45,transform:cs,description:\"Rotation angle of the pattern (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\",condition:{style:\"classic\"}}},cyanAngle:{default:15,transform:cs,description:\"Screen angle for the cyan plate (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Cyan Angle\",group:\"Plate Angles\",condition:{style:\"cmyk\"}}},magentaAngle:{default:75,transform:cs,description:\"Screen angle for the magenta plate (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Magenta Angle\",group:\"Plate Angles\",condition:{style:\"cmyk\"}}},yellowAngle:{default:0,transform:cs,description:\"Screen angle for the yellow plate (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Yellow Angle\",group:\"Plate Angles\",condition:{style:\"cmyk\"}}},blackAngle:{default:45,transform:cs,description:\"Screen angle for the black plate (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Black Angle\",group:\"Plate Angles\",condition:{style:\"cmyk\"}}},misprint:{default:0,description:\"Simulated mis-registration between plates. Plates are offset around the misprint angle, producing color fringing at the edges of inked regions.\",ui:{type:[\"range\",\"map\"],min:0,max:.01,step:5e-4,label:\"Misprint\",group:\"Effect\",condition:{style:\"cmyk\"}}},misprintAngle:{default:0,transform:cs,description:\"Direction the plates drift apart. Rotating this rotates the color-fringing pattern.\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Misprint Angle\",group:\"Effect\",condition:{style:\"cmyk\"}}},paperColor:{default:\"#ffffff\",transform:ce,description:\"Paper/substrate color shown where no ink lands\",ui:{type:\"color\",label:\"Paper\",group:\"Inks\",condition:{style:\"cmyk\"}}},cyanColor:{default:\"#00ffff\",transform:ce,description:\"Cyan ink color\",ui:{type:\"color\",label:\"Cyan\",group:\"Inks\",condition:{style:\"cmyk\"}}},magentaColor:{default:\"#ff00ff\",transform:ce,description:\"Magenta ink color\",ui:{type:\"color\",label:\"Magenta\",group:\"Inks\",condition:{style:\"cmyk\"}}},yellowColor:{default:\"#ffff00\",transform:ce,description:\"Yellow ink color\",ui:{type:\"color\",label:\"Yellow\",group:\"Inks\",condition:{style:\"cmyk\"}}},blackColor:{default:\"#000000\",transform:ce,description:\"Black (key) ink color\",ui:{type:\"color\",label:\"Black\",group:\"Inks\",condition:{style:\"cmyk\"}}}},effect:nD(T(\"style\"),_pe,{classic:oD({angle:T(\"angle\"),frequency:T(\"frequency\")}),cmyk:aD({paper:T(\"paperColor\"),frequency:T(\"frequency\"),misprint:T(\"misprint\"),misprintAngle:T(\"misprintAngle\"),plates:[{channel:\"cyan\",screenAngle:T(\"cyanAngle\"),ink:T(\"cyanColor\")},{channel:\"magenta\",screenAngle:T(\"magentaAngle\"),ink:T(\"magentaColor\")},{channel:\"yellow\",screenAngle:T(\"yellowAngle\"),ink:T(\"yellowColor\")},{channel:\"black\",screenAngle:T(\"blackAngle\"),ink:T(\"blackColor\")}]})})});var BF=H({role:\"shape\",name:\"Heart\",description:\"Heart shape with adjustable size\",shape:{distance:({x:e,y:t},s)=>uR(e,t,s(\"radius\")),colorDescription:\"Fill color of the heart\",centerDescription:\"Center position of the heart\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.32,description:\"Size of the heart (fit radius)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Size\",group:\"Shape\"}}}}});var fpe=JSON.stringify({type:\"sphere3D\",radius:.35}),vpe=[{color:\"#02010f\",position:0},{color:\"#2a0a8a\",position:.2},{color:\"#a41c9b\",position:.45},{color:\"#e8632b\",position:.7},{color:\"#f9e25f\",position:.9},{color:\"#ffffff\",position:1}],V2=(e,t,s,r)=>{let o=et(-.6,.6,s),a=ne(hL(I(v(t,4),v(It(r),13.7)),I(v(s,3),v(It(r),7.1))),.5),i=z(I(ne(e,o),v(a,.12)),\"aEff\");return Ge(v(tr(Ce(v(v(i,i),-1),.0256)),v(ot(0,.15,s),ne(1,ot(.85,1,s)))),0,1)},zF=H({name:\"Heatmap\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Thermal-camera heat flowing through any 2D, SVG, or 3D shape. Powered by Paper Shaders.\",animatedTime:{speed:\"speed\"},...Ts({stencil:\"centre\",surface:(e,t)=>{let{uniforms:s,propValues:r}=t,o=wt(t),a=z(e.sdfUV,\"suv\"),i=it(s.scale,.001),l=z(Ce(e.surf0.member(\"r\"),i),\"f\"),c=z(ne(1,ot(-.003,.003,l)),\"inside\"),d=ii(s.angle,\"travel\"),u=z(ne(a.member(\"xy\"),rt(.5,.5)),\"rel\"),p=z($t(u,d.tangent),\"a\"),_=z(v($t(u,d.perp),-1),\"b\"),f=z(ne(v(.1,o),.3),\"tBase\"),h=I(.8,v(.8,tr(Ce(v(it(v(l,-1),0),-1),.12))));h=z(et(h,0,V2(p,_,Qr(f),1)),\"inner1\"),h=z(et(h,0,V2(p,_,Qr(I(f,1/3)),2)),\"inner2\"),h=z(et(h,0,V2(p,_,Qr(I(f,2/3)),3)),\"inner3\"),h=v(h,v(2,s.innerGlow)),h=I(h,v(v(s.contour,2),tr(Ce(v(ms(l),-1),.03)))),h=v(Yr(h,1),c),h=z(ts(it(h,0),1.2),\"inner\");let g=tr(Ce(v(it(l,0),-1),I(.05,v(.15,s.outerGlow)))),y=Qr(ne(v(f,3),.1)),b=z(Qr(ne(v(p,1.2),y)),\"yy\"),x=I(.5,v(ot(.3,.65,b),ne(1,ot(.65,1,b)))),P=z(v(v(v(v(v(v(.9,ts(g,.8)),x),5),s.outerGlow),s.outerGlow),ne(1,c)),\"outer\"),C=Ge(I(h,P),0,1),E=z(v(v(v(ot(-.06,.1,a.member(\"x\")),ne(1,ot(.9,1.06,a.member(\"x\")))),ot(-.06,.1,a.member(\"y\"))),ne(1,ot(.9,1.06,a.member(\"y\")))),\"frameFade\");C=v(C,E),C=I(C,v(.005,ne(xp(v(a.member(\"x\"),991.3),v(a.member(\"y\"),787.7)),.5))),C=z(Ge(C,0,1),\"heat\");let R=v(Ge(I(c,P),0,1),E),U=r.colorSpace??0,L=r.stopCount??0,k;L>1?k=En(C,{colorsArray:s.colorsArray,positionsArray:s.positionsArray,convertedColorsArray:s.convertedColorsArray,stopCount:s.stopCount},U):k=W(No[U]??Ar,\"mixColors\",[s.colorA,s.colorB,C]);let D=z(k,\"ramp\");return Ot(Ge(D.member(\"xyz\"),Qe(0,0,0),Qe(1,1,1)),v(D.member(\"w\"),R))}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the heatmap shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the heatmap shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the heatmap shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},colorA:{default:\"#02010f\",transform:ce,description:\"Cold color (used when no gradient stops are set)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#f9e25f\",transform:ce,description:\"Hot color (used when no gradient stops are set)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:{...Ms(),default:vpe},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the heat ramp interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},innerGlow:{default:.4,description:\"Heat filling the inside of the shape\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Inner Glow\",group:\"Heat\"}},outerGlow:{default:.2,description:\"Heat radiating beyond the silhouette\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Outer Glow\",group:\"Heat\"}},contour:{default:.5,description:\"Heat concentrated along the shape boundary\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Contour\",group:\"Heat\"}},angle:{default:90,description:\"Direction the heat waves travel, in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Angle\",group:\"Heat\"}},speed:{default:1,description:\"Speed of the flowing heat. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Heat\"}},shape:{default:fpe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var RF=ZR({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"clockwise\"}),thickness:T(\"thickness\"),softness:T(\"softness\"),variation:T(\"variation\")}),DF=H({name:\"HexGrid\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Honeycomb hexagonal grid pattern\",acceptsUVContext:!0,props:{colorA:{default:\"#000000\",transform:ce,description:\"Cell fill color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Grid line color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},cells:{default:8,description:\"Number of hexagons along the canvas height (the width fits as many as the aspect ratio allows)\",ui:{type:[\"range\",\"map\"],min:1,max:40,step:1,label:\"Cells\",group:\"Effect\"}},thickness:{default:1,description:\"Thickness of the hex grid lines\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Thickness\",group:\"Effect\"}},rotation:{default:0,transform:cs,description:\"Rotation of the grid in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the line edges (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},variation:{default:0,description:\"Per-cell random lightening/darkening of the cell fill color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:Sc(T(\"colorA\"),RF.shade),stroke:T(\"colorB\"),mask:RF.lines,space:T(\"colorSpace\")})});var hpe=JSON.stringify({type:\"sphere3D\",radius:.35}),gpe=Po,LF=H({name:\"Hologram\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Volumetric sci-fi hologram \\u2014 a translucent emissive projection of the shape with fresnel-lit edges, depth scan-lines that wrap 3D forms, CRT scanlines, flicker and beam wobble\",animatedTime:{speed:\"speed\"},...Ts({chord:\"firstLobe\",stencil:{kind:\"central\",eps:.008},placeUV:e=>{let{uniforms:t,ctx:s}=e,r=wt(e),o=s.uv.member(\"y\"),a=I(v(Vt(I(v(o,38),v(r,2.3))),.5),v(Vt(ne(v(o,11.5),v(r,1.7))),.5));return rt(I(s.uv.member(\"x\"),v(v(a,t.distortion),.012)),o)},surface:(e,t)=>{let{uniforms:s,ctx:r}=t,o=z(wt(t),\"animTime\"),a=e.volumetric,i=.008,l=z(e.surf0,\"sC\"),c=z(Ce(1,r.viewportSize.member(\"y\")),\"pxH\"),d=z(Ce(l.member(\"x\"),s.scale),\"sdf\"),u=z(e.surfX,\"sR\"),p=z(e.surfL,\"sL\"),_=z(e.surfY,\"sU\"),f=z(e.surfD,\"sD\"),h=it(v(s.edgeSoftness,.5),.001),g=z(Ce(ne(u.member(\"x\"),p.member(\"x\")),i*2),\"gradX\"),y=z(it(v(d,-1),0),\"thickness\"),b=z(tr(v(y,-5.5)),\"thin\"),x,P;if(a){let Ee=ts(Ge(ne(1,ms(z(Os(Qe(Ge(Ce(ne(u.member(\"w\"),p.member(\"w\")),i*2),-2,2),Ge(Ce(ne(_.member(\"w\"),f.member(\"w\")),i*2),-2,2),-1)),\"nrm\").member(\"z\"))),0,1),2.2);x=I(v(b,.55),Ee),P=l.member(\"w\")}else x=b,P=y;let C=z(v(x,s.edgeGlow),\"rim\"),E=v(ne(1,tr(v(y,-5))),s.fill),R=z(Qr(ne(v(P,s.depthScale),v(o,1.2))),\"phaseFract\"),U=v(ot(.06,0,Yr(R,ne(1,R))),s.depthLines),L=I(v(Vt(v(ne(v(r.uv.member(\"y\"),s.scanlineScale),v(o,v(s.scanlineSpeed,3))),gpe)),.5),.5),k=z(et(It(1),L,s.scanlines),\"scanMask\"),D=Qr(v(o,.16)),O=z(ne(r.uv.member(\"y\"),D),\"sweepD\"),F=z(v(tr(v(v(O,O),-650)),s.sweep),\"sweepGlow\"),q=I(v(Vt(v(o,40)),.04),v(Vt(v(o,23.3)),.03)),Y=ot(.6,.95,I(v(co(v(o,6),11),.5),.5)),V=v(I(1,q),ne(1,v(v(s.flicker,Y),.7))),X=I(1,v(v(ne(xp(I(v(r.uv.member(\"x\"),r.viewportSize.member(\"x\")),v(o,57.3)),v(r.uv.member(\"y\"),r.viewportSize.member(\"y\"))),.5),s.grain),.6)),Q=z(v(I(v(v(v(I(I(E,C),U),k),V),X),v(F,k)),s.brightness),\"core\"),te=I(v(s.distortion,.12),.04),J=z(v(v(v(C,g),te),.1),\"fringe\"),oe=I(Q,J),le=ne(Q,J),se=s.color.member(\"rgb\"),Te=Qe(v(se.member(\"x\"),oe),v(se.member(\"y\"),Q),v(se.member(\"z\"),le)),de=Ge(I(v(C,.5),F),0,.8),xe=z(et(Te,kt(Q),kt(de)),\"hotRgb\"),Ae=ot(0,1,Ge(v(Ce(v(d,-1),h),32),0,1)),De=v(Ge(Q,0,1),Ae);return Js(Dr(d,c),Ot(xe,De),xt,\"hologram\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the hologram shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the hologram shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the hologram shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},color:{default:\"#5ec8ff\",transform:ce,description:\"Projection tint \\u2014 the color the whole hologram emits (classic sci-fi cyan by default)\",ui:{type:\"color\",label:\"Color\",group:\"Style\"}},brightness:{default:2.5,description:\"Overall emission gain. Bright edges blow out toward white for a hot, projected look.\",ui:{type:\"range\",min:.2,max:3,step:.01,label:\"Brightness\",group:\"Style\"}},edgeSoftness:{default:.04,description:\"Softness of the shape boundary edge \\u2014 keep low for crisp projection edges\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Style\"}},fill:{default:.45,description:\"Translucent interior glow. Driven by optical thickness, so thicker parts of a 3D form glow more \\u2014 the core volumetric cue.\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Volume Fill\",group:\"Volume\"}},edgeGlow:{default:1,description:\"Fresnel rim intensity \\u2014 bright glowing silhouette and, on 3D shapes, the grazing internal walls of extruded logos\",ui:{type:\"range\",min:0,max:2.5,step:.01,label:\"Edge Glow\",group:\"Volume\"}},depthLines:{default:.5,description:\"Iso-depth scan-lines that hug the surface and reveal the 3D form like a volumetric scan. On flat shapes they become concentric contour rings.\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Depth Lines\",group:\"Volume\"}},depthScale:{default:26,description:\"Density of the depth scan-lines \\u2014 higher packs more contour bands through the volume\",ui:{type:\"range\",min:4,max:70,step:1,label:\"Depth Density\",group:\"Volume\"}},scanlines:{default:.55,description:\"CRT scanline contrast \\u2014 how dark the gaps between horizontal projection lines get\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Scanlines\",group:\"Scanlines\"}},scanlineScale:{default:130,description:\"Number of horizontal scanlines across the canvas height\",ui:{type:\"range\",min:20,max:400,step:1,label:\"Scanline Count\",group:\"Scanlines\"}},scanlineSpeed:{default:1,description:\"How fast the scanlines drift upward \\u2014 0 holds them static\",ui:{type:\"range\",min:0,max:5,step:.01,label:\"Scanline Drift\",group:\"Scanlines\"}},sweep:{default:.1,description:\"Brightness of the refresh bar that sweeps vertically through the projection\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Sweep Bar\",group:\"Scanlines\"}},flicker:{default:.3,description:\"Unstable-projector flicker \\u2014 a fast shimmer plus occasional brightness dropouts\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Flicker\",group:\"Interference\"}},distortion:{default:.1,description:\"Continuous horizontal wobble and chromatic edge fringing \\u2014 the wavering of an unstable beam\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Distortion\",group:\"Interference\"}},grain:{default:.7,description:\"Fine projection static \\u2014 animated per-pixel noise over the emission\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Grain\",group:\"Interference\"}},speed:{default:1,description:\"Master animation speed for every animated layer. 0 freezes the projection.\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Speed\",group:\"Animation\"}},shape:{default:hpe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file \\u2014 when non-empty, activates SVG mode and triggers a shader recompile\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type \\u2014 triggers recompile when shape is switched. When empty, derived from shape JSON at mount time.\"}}});var ype=JSON.stringify({type:\"sphere3D\",radius:.35}),bpe=1/3,xpe=2/3,Xg=Math.cos(300*Math.PI/180),Hg=Math.sin(300*Math.PI/180),Ape=.37164708971977234,wpe=-.6437116265296936,Tpe=-.6689647436141968,UF=e=>fL(e,[0,bpe,xpe]),OF=H({name:\"Holographic\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Iridescent holographic foil sticker with animated rainbow sheen and glitter flakes\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",stencil:{kind:\"forward\",eps:.008},surface:(e,t)=>{let{uniforms:s}=t,r=z(wt(t),\"animTime\"),o=e.volumetric,a=.008,i=Lr(e,t,{scale:s.scale}),{s0:l,sX:c,sY:d,sdf:u,pxH:p}=i,_=Jr(i,s.edgeSoftness),f=z(e.sdfUV,\"suv\"),h=go(e,i,{uv:f}),g=h.member(\"x\"),y=h.member(\"y\"),b=ne(f.member(\"x\"),.5),x=ne(f.member(\"y\"),.5),P,C,E;if(o){let pt=z(Ge(Ce(ne(c.member(\"w\"),l.member(\"w\")),a),-1.5,1.5),\"baseNxVol\"),Ze=z(Ge(Ce(ne(d.member(\"w\"),l.member(\"w\")),a),-1.5,1.5),\"baseNyVol\");P=pt,C=Ze,E=z(Ce(1,I(1,v(Ge(I(v(pt,pt),v(Ze,Ze)),0,2),2))),\"steepAtten\")}else{let pt=Ln(i,a),Ze=z(v(ne(1,Ge(Ce(v(u,-1),.06),0,1)),.35),\"domeSlope\");P=z(v(pt.member(\"x\"),Ze),\"baseNx\"),C=z(v(pt.member(\"y\"),Ze),\"baseNy\"),E=It(1)}let R=z(v(s.crinkleScale,1.35),\"crScale\"),U=z(v(v(s.crinkle,.8),E),\"crAmp\"),L=.02,k=z(co(I(v(g,R),2.7),I(v(y,R),11.3)),\"w0\"),D=Ce(ne(co(I(v(I(g,L),R),2.7),I(v(y,R),11.3)),k),L),O=Ce(ne(co(I(v(g,R),2.7),I(v(I(y,L),R),11.3)),k),L),F=z(Os(Qe(I(P,v(v(D,U),.4)),I(C,v(v(O,U),.4)),-1)),\"n\"),q=z(v(s.foilScale,2.2),\"fScale\"),Y=z(v(r,.06),\"drift\"),V=I(co(I(v(g,q),v(Y,Xg)),I(v(y,q),v(Y,Hg))),v(co(ne(I(v(v(g,q),2.1),5.2),v(v(Y,Xg),1.6)),ne(I(v(v(y,q),2.1),9.4),v(v(Y,Hg),1.6))),.4)),X=I(v(F.member(\"x\"),Xg),v(F.member(\"y\"),Hg)),Q=v(I(v(g,Xg),v(y,Hg)),.8),te=z(I(I(I(I(v(V,.45),Q),v(X,1.4)),v(r,.18)),Ce(s.hueShift,360)),\"hue\"),J=Ge(s.saturation,0,1),oe=UF(te),le=z(et(Qe(.72,.73,.76),oe,kt(v(J,.85))),\"foilTint\"),se=z(Ge(s.roughness,0,1),\"roughnessC\"),Te=z(Qe(Ape,wpe,Tpe),\"L\"),de=z(Os(I(Te,Qe(0,0,-1))),\"H\"),xe=z(Ge(I(v($t(F,Te),.5),.5),0,1),\"ndl\"),Ae=z(Ge($t(F,de),0,1),\"ndh\"),De=v(v(ts(Ae,7),.45),ne(1,v(se,.35))),Ee=v(v(ts(Ae,et(It(42),It(12),se)),.85),ne(1,v(se,.55))),ze=I(v(le,De),v(et(le,Qe(1,1,1),kt(.6)),Ee)),Ie=co(v(g,190),v(y,190)),ke=z(co(I(v(g,190),47.3),ne(v(y,190),31.1)),\"flakePhase\"),Me=z(I(v(Vt(I(v(r,2.2),v(ke,12.6))),.5),.5),\"twinkle\"),we=v(v(ot(.52,.62,I(v(Ie,.75),v(Me,.3))),Ge(s.sparkle,0,1)),E),Ve=v(v(UF(I(I(te,.33),v(ke,.5))),I(.85,v(Me,.55))),I(v(xe,.6),.7)),qe=I(1,v(v(co(v(b,420),v(x,420)),se),.28)),st=z(v(et(I(v(le,I(v(xe,.5),.62)),ze),Ve,kt(we)),qe),\"foilRgb\");return Js(Dr(u,p),Ot(st,_),xt,\"holo\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the foil shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the foil shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the foil shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},hueShift:{default:0,description:\"Rotates the rainbow spectrum across the foil\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Hue Shift\",group:\"Foil\"}},foilScale:{default:1.5,description:\"Size of the iridescent color patches \\u2014 higher = smaller, busier patches\",ui:{type:\"range\",min:.3,max:6,step:.01,label:\"Foil Scale\",group:\"Foil\"}},saturation:{default:.75,description:\"Rainbow saturation \\u2014 0 = plain silver foil, 1 = fully spectral\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Saturation\",group:\"Foil\"}},roughness:{default:.25,description:\"Matte laminate grain \\u2014 softens the gloss with fine paper-like noise\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Roughness\",group:\"Foil\"}},speed:{default:1,description:\"Animation speed \\u2014 the spectrum drifts across the foil as if the sticker is tilting in your hand. 0 pauses.\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Speed\",group:\"Animation\"}},crinkle:{default:.5,description:\"Laminate wrinkles \\u2014 perturbs the surface so the sheen and rainbow swirl locally instead of lying flat\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Crinkle\",group:\"Foil\"}},crinkleScale:{default:1,description:\"Size of the laminate wrinkles \\u2014 higher = smaller, denser wrinkles\",ui:{type:\"range\",min:.3,max:6,step:.01,label:\"Crinkle Scale\",group:\"Foil\"}},sparkle:{default:.4,description:\"Glitter flakes embedded in the foil \\u2014 tiny facets that refract a shifted hue and twinkle as the spectrum drifts\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Sparkle\",group:\"Foil\"}},edgeSoftness:{default:.05,description:\"Softness of the shape boundary edge\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Foil\"}},shape:{default:ype,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});function Spe(e){let{gpu:t,domCanvas:s,onBeforeRender:r,onResize:o,onCleanup:a}=e,i=t.device,l=Math.min(window.devicePixelRatio,2),c=gc(e,{label:\"HTMLInCanvas\",initial:{width:Math.max(1,Math.round(window.innerWidth*l)),height:Math.max(1,Math.round(window.innerHeight*l))},mipmaps:!1}),d=null,u=!1,p=!1,_=!1,f=!1,h=(g,y)=>c.ensureSize(g,y);return r(()=>{if(!(!s||c.disposed)){if(!d&&(d=s.firstElementChild,d)){let g=d.getBoundingClientRect(),y=Math.round(g.width*window.devicePixelRatio),b=Math.round(g.height*window.devicePixelRatio);y>0&&b>0&&h(y,b)}if(d){if(!p){s.getContext(\"2d\"),s.onpaint=()=>{_=!0},s.requestPaint?.(),p=!0;return}if(_&&d){let g=i.queue.copyElementImageToTexture;if(typeof g!=\"function\"){_=!1;return}try{if(f)g.call(i.queue,d,{texture:c.unwrap()});else try{g.call(i.queue,{source:d},{destination:{texture:c.unwrap()}})}catch(y){if(!(y instanceof TypeError))throw y;g.call(i.queue,d,{texture:c.unwrap()}),f=!0}_=!1}catch(y){u||(console.warn(`[HTMLInCanvas] copyElementImageToTexture failed.\nRequires Chrome Canary with chrome://flags/#canvas-draw-element enabled.\nThe element must be a direct child of a <canvas layoutsubtree>.`,y),u=!0)}}}}}),o(()=>{let g=Math.min(window.devicePixelRatio,2);h(Math.round(window.innerWidth*g),Math.round(window.innerHeight*g)),d=null,_=!1,s&&s.requestPaint?.()}),a(()=>{s&&(s.onpaint=null)}),c}var GF=H({name:\"HTMLInCanvas\",role:\"media\",species:\"custom\",deprecatedNames:[\"DOMTexture\"],boundingBoxDeclaration:{aspectRatio:null},category:\"Textures\",description:\"Render live HTML/DOM content as a WebGPU texture layer via the html-in-canvas API. Requires Chrome Canary with chrome://flags/#canvas-draw-element enabled.\",capturesDOM:!0,experimental:{message:\"Requires Chrome Canary with chrome://flags/#canvas-draw-element enabled. Do not use for production use.\",docs:\"This component is powered by the WICG html-in-canvas proposal, which is currently only available in Chrome Canary behind a feature flag. It is not suitable for production use and may change as the specification evolves.\",docsLink:{url:\"https://github.com/WICG/html-in-canvas\",label:\"View the spec\"}},props:{},gpu:{fragment:e=>{let t=Spe(e).kit.sample(e.ctx.uv);return Ct(W(Iu,\"srgbToLinear\",[t.member(\"rgb\")]),t.member(\"a\"))}}});var FF=H({name:\"HueShift\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Rotate hue around the color wheel\",props:{shift:{default:0,description:\"The amount to shift the hue by\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Shift\",group:\"Adjustments\"}}},effect:t8(T(\"shift\")),identityWhen:Uo(\"shift\"),missingChildMessage:\"You must pass a child component into the Hue Shift shader.\"});var IF=H({name:\"ImageTexture\",role:\"media\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Display an image with customizable object-fit modes\",acceptsUVContext:!0,naturalSizeKey:{fromProp:\"url\"},props:{url:{default:\"https://shaders.com/sample.jpg\",description:\"Upload an image or provide a URL\",ui:{type:\"image-upload\",label:\"Image\",group:\"Media\"}},objectFit:up(\"fill\",\"How the image should be sized within the viewport\",{allowNone:!1})},...LL({src:T(\"url\"),fit:T(\"objectFit\"),decode:\"srgb-linear-alpha-cut\",label:\"ImageTexture\",onError(e,t){let s=!t.startsWith(\"http://\")&&!t.startsWith(\"https://\")&&!t.startsWith(\"data:\");console.error(`[ImageTexture] Failed to load image\n  Requested URL: ${t}\n  Path type: ${s?\"relative\":\"absolute\"}\n  Error:`,e)}})});var Wi=256,El=Wi*Wi,Ppe=10,Cpe=\"rgba16float\",YF=.16,Mpe=16,Epe=.006,kpe=.06,WF=4,Bpe=.05,zpe=1.35,qF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,curlStrength:n,velFade:n,dyeFade:n}),\"FlowParams\"),VF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({posX:n,posY:n,velX:n,velY:n,colR:n,colG:n,colB:n,col2R:n,col2G:n,col2B:n,mixT:n,radius:n,strength:n}),\"SplatParams\"),NF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,El),access:\"mutable\"},velB:{storage:Fe(S,El),access:\"mutable\"},dyeA:{storage:Fe(S,El),access:\"mutable\"},dyeB:{storage:Fe(S,El),access:\"mutable\"},pressure:{storage:Fe(n,El),access:\"mutable\"},divergence:{storage:Fe(n,El),access:\"mutable\"},params:{uniform:qF}}),\"fluidLayout\"),$F=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,El),access:\"mutable\"},dyeA:{storage:Fe(S,El),access:\"mutable\"},sparams:{uniform:VF}}),\"splatLayout\"),XF=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({dyeA:{storage:Fe(S,El),access:\"readonly\"},outTex:{storageTexture:zt(Cpe,\"write-only\")}}),\"outputLayout\"),Bp=e=>Sz($F,{n:Wi,namePrefix:\"inkFlow\",colorSpace:e}),$2={0:Bp(0),1:Bp(1),2:Bp(2),3:Bp(3),4:Bp(4),5:Bp(5)},rAe=$2[2],HF=zn(NF,{n:Wi,namePrefix:\"inkFlow\",boundary:\"clamped\",dye:\"rgb\",dyeDissipation:!0}),{curl:oAe,vorticity:aAe,divergence:nAe,jacobi:iAe,gradSubtract:lAe,advectVel:cAe,copyVel:dAe,advectDye:uAe,copyDye:pAe}=HF,Rpe=Ui(XF,{n:Wi,namePrefix:\"inkFlow\",dye:\"rgb\"});function N2(e){return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)}function Dpe(e){let t=(e%1+1)%1,s=Math.floor(t*6),r=t*6-s,o=1-r,a=0,i=0,l=0;return s===0?(a=1,i=r,l=0):s===1?(a=o,i=1,l=0):s===2?(a=0,i=1,l=r):s===3?(a=0,i=o,l=1):s===4?(a=r,i=0,l=1):(a=1,i=0,l=o),[N2(a),N2(i),N2(l)]}var jF=H({name:\"InkFlow\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Drag to paint swirling ribbons of ink through a real fluid field \\u2014 eddies keep evolving after you let go\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{colorMode:{default:\"rainbow\",description:\"How the brush color is chosen: an ever-cycling rainbow, a single fixed color, or a custom three-color cycle\",ui:{type:\"select\",options:[{label:\"Rainbow\",value:\"rainbow\"},{label:\"Single Color\",value:\"single\"},{label:\"Custom Colors\",value:\"custom\"}],label:\"Color Mode\",group:\"Color\"}},colorSpeed:{default:1,description:\"How quickly the brush cycles through the rainbow or the custom colors as you paint\",ui:{type:\"range\",min:0,max:4,step:.05,label:\"Color Speed\",group:\"Color\",condition:{colorMode:[\"rainbow\",\"custom\"]}}},color:{default:\"#ff2d7e\",transform:ce,description:\"Brush color used when Color Mode is Single\",ui:{type:\"color\",label:\"Brush Color\",group:\"Color\",condition:{colorMode:\"single\"}}},color1:{default:\"#4338ff\",transform:ce,description:\"First color of the custom brush cycle\",ui:{type:\"color\",label:\"Color 1\",group:\"Color\",condition:{colorMode:\"custom\"}}},color2:{default:\"#ff2d7e\",transform:ce,description:\"Second color of the custom brush cycle\",ui:{type:\"color\",label:\"Color 2\",group:\"Color\",condition:{colorMode:\"custom\"}}},color3:{default:\"#19e3ff\",transform:ce,description:\"Third color of the custom brush cycle\",ui:{type:\"color\",label:\"Color 3\",group:\"Color\",condition:{colorMode:\"custom\"}}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"color space the custom colors blend through as the brush cycles between them\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Color\",condition:{colorMode:\"custom\"}}},radius:{default:.3,description:\"Size of the ink splat painted under the cursor\",ui:{type:\"range\",min:.1,max:5,step:.05,label:\"Radius\",group:\"Brush\"}},force:{default:1,description:\"How hard the cursor's motion pushes the fluid \\u2014 higher throws faster, more violent jets and curls\",ui:{type:\"range\",min:0,max:3,step:.05,label:\"Force\",group:\"Brush\"}},curl:{default:0,description:\"Vorticity confinement \\u2014 swirl energy that spins the ink into persistent eddies and curls\",ui:{type:\"range\",min:0,max:60,step:1,label:\"Swirl\",group:\"Dynamics\"}},decay:{default:.5,description:\"How fast the ink fades away \\u2014 low values leave long, lingering trails\",ui:{type:\"range\",min:.05,max:4,step:.05,label:\"Decay\",group:\"Dynamics\"}},momentum:{default:.6,description:\"How long the fluid keeps flowing after a stroke \\u2014 high momentum lets the motion carry on and on\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Momentum\",group:\"Dynamics\"}}},...Ii((e,t)=>{let{getCpuValue:s,propValues:r}=e,o=r.colorSpace??2,a=$2[o]??$2[2],i=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(t.createUniform(VF),\"splatU\"),l=0,c=(p,_)=>{let f=p;return f&&typeof f.r==\"number\"?[f.r,f.g??0,f.b??0]:_},d=p=>fl(p[0],p[1],p[2],o),u=Og({activeWhen:p=>p.moving,fadeSeconds:p=>jh(64,p.num(\"decay\",.5)),onFrame:p=>{l+=p.dt*kpe*p.num(\"colorSpeed\",1)},pass:{setup:p=>{let _=p.root.createBindGroup($F,{velA:p.buffers.velA,dyeA:p.buffers.dyeA,sparams:i.buffer});return p.pass(a,_)}},ribbon:(p,_)=>{let f=p.num(\"force\",1),h=Math.max(p.num(\"radius\",.3)*.1*Wi,1),g=p.num(\"colorSpeed\",1),y=s(\"colorMode\")||\"rainbow\",b=y===\"custom\"?[d(c(s(\"color1\"),[.26,.22,1])),d(c(s(\"color2\"),[1,.18,.49])),d(c(s(\"color3\"),[.1,.89,1]))]:null,x=()=>{if(l+=Epe*g,b){let R=(l%1+1)%1,U=Math.min(2,Math.floor(R*3));return{a:b[U],b:b[(U+1)%3],t:R*3-U}}if(y===\"single\"){let R=d(c(s(\"color\"),[1,.18,.49]));return{a:R,b:R,t:0}}let E=d(Dpe(l));return{a:E,b:E,t:0}},P=_.velX*Wi*f*YF,C=_.velY*Wi*f*YF;return{stepSize:Math.max(.004,h/Wi*.6),maxSteps:Mpe,prepare:x,write:(E,R,U,L)=>i.write({posX:E,posY:R,velX:P,velY:C,colR:L.a[0],colG:L.a[1],colB:L.a[2],col2R:L.b[0],col2G:L.b[1],col2B:L.b[2],mixT:L.t,radius:h,strength:1})}}});return{resolution:Wi,layout:NF,outputLayout:XF,paramsSchema:qF,solver:{kernels:HF,jacobiIters:Ppe},output:{kernel:Rpe,key:\"dyeTexture\"},inject:[u],values:p=>{let _=Math.min(Math.max(p.num(\"momentum\",.6),0),1);return{dt:p.dt,curlStrength:p.num(\"curl\",0),velFade:WF*Math.pow(Bpe/WF,_),dyeFade:p.num(\"decay\",.5)}}}}),gpu:{fragment:({ctx:e,computeOutputs:t})=>{let s=t?.dyeTexture;if(!s)return xt;let r=z(s.sample(e.uv,\"linearClamp\").member(\"rgb\"),\"inkDye\");return Ct(r,Ge(v(it(r.member(\"x\"),it(r.member(\"y\"),r.member(\"z\"))),zpe),0,1))}}});var KF=H({name:\"Invert\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Invert RGB colors while preserving alpha\",props:{},effect:i8(),missingChildMessage:\"You must pass a child component into the Invert shader.\"});var QF=H({name:\"IrisWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Reveal through an expanding circle growing from a center point\",props:{progress:{default:.5,description:\"How far the iris has expanded (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Point the iris expands from\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},feather:{default:.1,description:\"Softness of the iris edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Wipe from the outside inward instead\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.radial(T(\"center\")),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Iris Wipe shader.\"});var Lpe=JSON.stringify({type:\"sphere3D\",radius:.35}),Upe=[{position:{x:.3,y:.3},color:\"#ffb347\",intensity:3},{position:{x:.72,y:.7},color:\"#7a5cff\",intensity:2}],Ope=6,jg={burst:128,motion:64,refine:32,refineFrames:12},Gpe=2,Fpe=32,ZF=12,Ipe=512,Ype=320,Wpe=2.5,Kg=.01,qpe=.3,Vpe=60,Npe=.6;function X2(e){let t=e.shadows,s=typeof t==\"number\"?t>0:t!==!1,r=Rr(),o=r?Gpe:1;return{rays:{burst:jg.burst/o,motion:jg.motion/o,refine:jg.refine/o,refineFrames:jg.refineFrames},shadowSteps:s?ZF:0,resolution:r?Ype:Ipe}}var JF={lights:{prop:\"lights\",position:\"position\",color:\"color\",intensity:\"intensity\"},reach:\"reach\",wrap:\"wrap\",lightRange:\"lightRange\",shadowSoftness:\"shadowSoftness\",steps:Fpe},$pe=Ts({stencil:\"centre\",centreTap:\"fast\",surface:(e,t)=>{let{uniforms:s,propValues:r}=t,{shadowSteps:o}=X2(r),a=o>0,i=Lr(e,t),l=P=>({...i,s0:z(e.sampler(e.sdfUV),`${P}S0`),sX:z(e.gradSampler(I(e.sdfUV,rt(Kg,0))),`${P}X`),sY:z(e.gradSampler(I(e.sdfUV,rt(0,Kg))),`${P}Y`)}),c=z(Ce(i.pxH,it(s.scale,.001)),\"pxUV\"),d=xL(e,i,t),u=uO(t,\"lights\"),p=P=>{let C=u.at(P);return{uv:bL(t,C.position(\"position\"),\"lightUV\"),rgb:v(C.color(\"color\").member(\"rgb\"),C.number(\"intensity\"))}},_=h2({...X2(r),...JF}).sample(t)??kt(0),f=z(ne(1,ot(0,v(c,Wpe),d.sdf)),\"rim\"),h=()=>{let P=AL(e.sdfUV,d.sdf,I(Ln(l(\"rim\"),Kg),d.outward));return S2(u,C=>{let E=p(C),R=u2({position:E.uv,height:s.lightHeight},P.point,\"rimLight\"),U=v(Pl(P.normal,R.toLight,{wrap:s.wrap}),p2(R.distance,s.lightRange));return a&&(U=v(U,IL({from:I(P.point,v(P.normal,v(c,2))),toward:E.uv,field:d.at,steps:ZF,surfaceEps:c,softness:s.shadowSoftness,hint:\"rimVisibility\"}))),v(E.rgb,U)},{zero:\"vec3f\",hint:\"rimSum\",deps:[P.point,P.normal]})},g=kL(m2(I(_,Js(Zo(f,0),v(h(),v(f,s.core)),kt(0),\"emitter\",[c]))),\"glow\"),y=()=>{let P=Dn(e,l(\"body\"),{bevelWidth:s.bevelWidth,bevelShape:It(0),eps:Kg}),C=S2(u,E=>{let R=p(E),U=u2({position:R.uv,height:s.lightHeight},e.sdfUV,\"bodyLight\"),L=z(v(p2(U.distance,s.lightRange),s.bodyLight),\"bodyLit\"),k=v(ts(it($t(P,Os(I(U.L,Qe(0,0,-1)))),0),Vpe),Npe);return I(v(s.bodyColor.member(\"rgb\"),v(Pl(P,U.L),L)),v(R.rgb,v(k,L)))},{zero:\"vec3f\",hint:\"bodySum\",deps:[P]});return m2(I(v(s.bodyColor.member(\"rgb\"),qpe),C))},b=Js(Dr(i.sdf,c),y(),kt(0),\"body\",[]),x=z(Jr({...i,pxH:c},s.edgeSoftness),\"cov\");return Ot(et(g.member(\"rgb\"),b,x),et(g.member(\"a\"),1,x))}}),eI=H({name:\"Irradiance\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Photorealistic light spilling around the edge of any 2D, SVG, or 3D shape \\u2014 any number of movable colored point lights strike the silhouette and the lit edges irradiate their surroundings, gathered in a compute pass with real cast shadows, mixing where they meet and burning to white at the rim\",props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},lights:fz({maxItems:Ope,minItems:1,itemLabel:\"Light\",item:{position:{kind:\"position\",default:{x:.3,y:.3},label:\"Position\",description:\"Where this light sits \\u2014 the edges facing it are struck and spill light outward. Map it to the mouse to carry the light around the shape.\"},color:{kind:\"color\",default:\"#ffb347\",label:\"Color\",description:\"The color this light casts\"},intensity:{kind:\"number\",default:3,label:\"Intensity\",min:0,max:8,step:.01,description:\"Brightness of this light \\u2014 past ~2 the rim it strikes overexposes to white\"}}},{default:Upe,description:\"The point lights striking the shape \\u2014 each with its own position, color and brightness\",label:\"Lights\",group:\"Lights\"}),lightHeight:{default:.5,description:\"Height of the lights above the shape plane, relative to the shape \\u2014 low lights graze the body, high lights flood it evenly\",ui:{type:[\"range\",\"map\"],min:.05,max:3,step:.01,label:\"Light Height\",group:\"Light\"}},lightRange:{default:1.2,description:\"Reach of each light \\u2014 the distance at which it has fallen to half strength, relative to the shape\",ui:{type:[\"range\",\"map\"],min:.1,max:4,step:.01,label:\"Range\",group:\"Light\"}},reach:{default:3,description:\"How far from the shape the spilled light is gathered, relative to the shape \\u2014 the glow fades out toward this distance\",ui:{type:[\"range\",\"map\"],min:.5,max:8,step:.01,label:\"Reach\",group:\"Glow\"}},core:{default:1,description:\"The lit edge seen directly \\u2014 the white-hot line along the rim where the lights strike\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Core\",group:\"Glow\"}},wrap:{default:.1,description:\"How far light wraps around edges that face away from it \\u2014 0 leaves the far side dark\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Wrap\",group:\"Glow\"}},shadows:{default:!0,compileTime:!0,transform:rs,description:\"Cast shadows \\u2014 the body blocks each light from edges it stands in front of (keeps holes and concave pockets dark)\",ui:{type:\"checkbox\",label:\"Shadows\",group:\"Glow\"}},shadowSoftness:{default:.15,description:\"Penumbra width of the cast shadows \\u2014 0 is razor sharp\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadow Softness\",group:\"Glow\"}},bodyColor:{default:\"#000000\",transform:ce,description:\"Color of the shape itself \\u2014 black for a pure occluder, lighter to see the lights land on its form\",ui:{type:\"color\",label:\"Body Color\",group:\"Body\"}},bodyLight:{default:.6,description:\"How much the lights illuminate the body \\u2014 the bevel of a flat shape or the form of a 3D one\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Body Light\",group:\"Body\"}},bevelWidth:{default:.01,description:\"Width of the rounded edge a flat shape catches the light on, relative to the shape\",ui:{type:[\"range\",\"map\"],min:.005,max:.2,step:.001,label:\"Bevel Width\",group:\"Body\"}},...gr({edgeSoftness:{ui:{group:\"Body\"}}}),shape:{default:Lpe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...$pe,compute:e=>h2({...X2(e.propValues),...JF}).compute(e)});var H2=rD({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"clockwise\"}),thickness:T(\"thickness\"),softness:T(\"softness\")}),Xpe=Zr({fill:T(\"colorA\"),stroke:T(\"colorB\"),mask:Y_(H2.random,T(\"colorVariation\")),space:T(\"colorSpace\")}),tI=H({name:\"IsometricCubes\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Isometric tumbling-blocks tiling \\u2014 a 3D cube illusion (rhombille pattern)\",acceptsUVContext:!0,props:{colorA:{default:\"#7c5cff\",transform:ce,description:\"Base cube color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ff5c9d\",transform:ce,description:\"Second cube color, mixed in per-cube for variation\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},lineColor:{default:\"#000000\",transform:ce,description:\"Color of the cube edge lines\",ui:{type:\"color\",label:\"Edges\",group:\"Colors\"}},cells:{default:6,description:\"Number of cubes across the shortest canvas edge\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Cells\",group:\"Effect\"}},thickness:{default:1,description:\"Thickness of the cube edge lines (0 = no edges)\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Thickness\",group:\"Effect\"}},rotation:{default:0,transform:cs,description:\"Rotation of the tiling in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the edge lines (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},colorVariation:{default:1,description:\"Per-cube random blend between the two colors (0 = uniform cubes, the clean 3D look)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:VR(fg(Y_(n2(Xpe),H2.tone),n2(T(\"lineColor\")),H2.wire))});var sI=H({name:\"Kaleidoscope\",role:\"warp\",category:\"Distortions\",description:\"Create a kaleidoscope effect with radial mirrored segments\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point of the kaleidoscope effect\"),segments:{default:6,description:\"Number of radial segments in the kaleidoscope\",ui:{type:[\"range\",\"map\"],min:2,max:24,step:1,label:\"Segments\",group:\"Effect\"}},angle:{default:0,description:\"Rotation offset for the entire kaleidoscope pattern\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},edges:fr(\"mirror\",\"How to handle edges when distortion pushes content out of bounds\")},map:jL({center:T(\"center\"),segments:T(\"segments\"),angle:T(\"angle\")}),missingChildMessage:\"You must pass a child component into the Kaleidoscope shader.\"});var rI=H({name:\"KeyFrames\",role:\"overlay\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Motion-tracking overlay \\u2014 trackers hunt and follow features in the content, dropping keyframe diamonds behind them along their motion paths, like a compositor mid-track\",requiresRTT:!0,requiresChild:!0,props:{trackers:{default:12,description:\"Number of simultaneous trackers.\",ui:{type:[\"range\",\"map\"],min:1,max:64,step:1,label:\"Trackers\",group:\"Tracking\"}},detect:{default:\"bright\",compileTime:!0,description:\"What the trackers hunt for.\",ui:{type:\"select\",options:[{label:\"Brightness\",value:\"bright\"},{label:\"Darkness\",value:\"dark\"},{label:\"Transparency\",value:\"alpha\"},{label:\"Red\",value:\"red\"},{label:\"Green\",value:\"green\"},{label:\"Blue\",value:\"blue\"}],label:\"Detect\",group:\"Tracking\"}},threshold:{default:.15,description:\"Feature floor \\u2014 content scoring below this doesn't count as trackable at all.\",ui:{type:\"range\",min:0,max:.9,step:.01,label:\"Threshold\",group:\"Tracking\"}},variance:{default:.8,description:\"Spread of tracker preferences \\u2014 0 hunts only the strongest features, 1 distributes trackers across the whole brightness range.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variance\",group:\"Tracking\"}},agility:{default:.5,description:\"How fast trackers travel and how wide they search.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Agility\",group:\"Tracking\"}},lifespan:{default:6,description:\"Seconds a tracker follows its target before retiring and reacquiring elsewhere. 0 = track forever.\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.5,label:\"Lifespan\",group:\"Tracking\"}},trail:{default:1,description:\"Visibility of the keyframe trail each tracker leaves behind.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Trail\",group:\"Style\"}},markerSize:{default:28,description:\"Tracker gizmo size in pixels.\",ui:{type:\"range\",min:8,max:80,step:1,label:\"Marker Size\",group:\"Style\"}},lineWidth:{default:1.5,description:\"Stroke width in pixels.\",ui:{type:\"range\",min:.5,max:6,step:.25,label:\"Line Width\",group:\"Style\"}},markerColor:{default:\"#54d66b\",transform:ce,description:\"Tracker gizmo color.\",ui:{type:\"color\",label:\"Tracker\",group:\"Colors\"}},keyframeColor:{default:\"#ffcf33\",transform:ce,description:\"Keyframe diamond color.\",ui:{type:\"color\",label:\"Keyframes\",group:\"Colors\"}},pathColor:{default:\"#ffffffb8\",transform:ce,description:\"Motion path color.\",ui:{type:\"color\",label:\"Path\",group:\"Colors\"}}},compute:e=>yB({mode:typeof e.propValues.detect==\"string\"?e.propValues.detect:\"bright\",trackers:\"trackers\",agility:\"agility\",threshold:\"threshold\",variance:\"variance\",lifespan:\"lifespan\"})(e),gpu:{fragment:F8({trackers:T(\"trackers\"),trail:T(\"trail\"),markerSize:T(\"markerSize\"),lineWidth:T(\"lineWidth\"),markerColor:T(\"markerColor\"),keyframeColor:T(\"keyframeColor\"),pathColor:T(\"pathColor\")})}});var oI=H({name:\"LensDistortion\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Split content into shifting chromatic layers with barrel or pincushion lens warp. Powered by Paper Shaders.\",requiresRTT:!0,requiresChild:!0,props:{center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the lens effect \\u2014 the focus zone, lens warp, circle crop and swirl all pivot around it\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},spread:{default:.6,description:\"Strength of the color split; how far the color layers are pushed apart (0 is off)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Spread\",group:\"Spread\"}},angle:{default:0,transform:cs,description:\"Direction of the spread in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Spread\"}},perspective:{default:.1,description:\"Shapes the spread direction from a straight line (0) to a radial burst out from the centre (1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Perspective\",group:\"Spread\"}},bias:{default:1,description:\"Shifts the colors toward one end of the spread; 0 spaces them evenly\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Bias\",group:\"Spread\"}},count:{default:35,description:\"Number of sampled color layers along the spread; higher is smoother and costlier\",ui:{type:[\"range\",\"map\"],min:2,max:50,step:1,label:\"Count\",group:\"Spread\"}},dispersion:{default:1,description:\"Overall amount of color dispersion; 1 gives each layer its own color from the spectrum, 0 keeps the original color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Dispersion\",group:\"Dispersion\"}},dispersionShift:{default:0,description:\"Balance of the dispersion between a soft circular zone at the centre and the rest; -1 keeps it in the centre only, 1 at the edges only\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Shift\",group:\"Dispersion\"}},dispersionColor:{default:.6,description:\"Rotates the dispersion colors around the hue wheel, 0 to 1 for a full turn\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Hue\",group:\"Dispersion\"}},focusCenter:{default:.8,description:\"Reduces the spread in a circular zone at the centre; 0 keeps it full to the centre\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Focus Center\",group:\"Focus\"}},focusEdges:{default:1,description:\"Reduces the spread toward the edges; 1 restores the original image there\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Focus Edges\",group:\"Focus\"}},lensBulge:{default:0,description:\"Radial lens warp; positive bulges out like a fisheye, negative pinches in like a pincushion\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Bulge\",group:\"Lens\"}},lensCircle:{default:0,description:\"Squeezes pixels outside the inscribed circle inward so the outline becomes a circle\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Circle\",group:\"Lens\"}},swirl:{default:.35,description:\"Rotates the color layers around the centre by an angle growing along the spread; 0 is off\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Swirl\",group:\"Lens\"}},noise:{default:0,description:\"Scatters the spread direction with noise; 0 is off\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Noise\",group:\"Noise\"}},noiseFrequency:{default:.25,description:\"Frequency of the direction noise; higher is finer (no effect with noise at 0)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Frequency\",group:\"Noise\"}},noiseOffset:{default:0,description:\"Offsets the noise pattern for a different seed (no effect with noise at 0)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Seed\",group:\"Noise\"}},grainMixer:{default:0,description:\"Scatters the spread with grain noise, breaking up the edges of the color layers\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Grain Mixer\",group:\"Grain\"}},grainOverlay:{default:0,description:\"Post-processing black/white grain overlay\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Grain Overlay\",group:\"Grain\"}}},gpu:{fragment:U8({center:T(\"center\"),spread:T(\"spread\"),bias:T(\"bias\"),angle:T(\"angle\"),perspective:T(\"perspective\"),count:T(\"count\"),dispersion:T(\"dispersion\"),dispersionShift:T(\"dispersionShift\"),dispersionColor:T(\"dispersionColor\"),focusCenter:T(\"focusCenter\"),focusEdges:T(\"focusEdges\"),swirl:T(\"swirl\"),noise:T(\"noise\"),noiseFrequency:T(\"noiseFrequency\"),noiseOffset:T(\"noiseOffset\"),lensBulge:T(\"lensBulge\"),lensCircle:T(\"lensCircle\"),grainMixer:T(\"grainMixer\"),grainOverlay:T(\"grainOverlay\")})}});var aI=H({name:\"LensFlare\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Stylize\",description:\"Realistic camera lens flare with artifacts.\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{lightPosition:{default:{x:.3,y:.3},transform:Xe,description:\"Position of the light source\",ui:{type:\"position\",label:\"Light Position\",group:\"Light\"}},intensity:{default:.5,description:\"Master brightness of the entire lens flare effect\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Intensity\",group:\"Light\"}},ghostIntensity:{default:.4,description:\"Brightness of internal reflection ghost discs along the flare axis\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Ghosts\",group:\"Reflections\"}},ghostSpread:{default:.7,description:\"Spacing between ghost reflections along the flare axis\",ui:{type:\"range\",min:.1,max:2,step:.01,label:\"Ghost Spread\",group:\"Reflections\"}},ghostChroma:{default:.3,description:\"Rainbow chromatic fringing around ghost element edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Ghost Chroma\",group:\"Reflections\"}},haloIntensity:{default:.4,description:\"Brightness of the circular halo ring from internal reflection\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Halo\",group:\"Reflections\"}},haloRadius:{default:.6,description:\"Radius of the halo ring\",ui:{type:\"range\",min:.1,max:1,step:.01,label:\"Halo Size\",group:\"Reflections\"}},haloChroma:{default:.6,description:\"Spectral dispersion on the halo creating rainbow color separation\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Halo Chroma\",group:\"Reflections\"}},haloSoftness:{default:.8,description:\"Thickness and softness of the halo ring\",ui:{type:[\"range\",\"map\"],min:.01,max:3,step:.01,label:\"Halo Softness\",group:\"Reflections\"}},starburstIntensity:{default:.3,description:\"Brightness of diffraction spikes radiating from the light source\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Starburst\",group:\"Effects\"}},starburstPoints:{default:6,description:\"Number of starburst spikes (simulates aperture blade count)\",ui:{type:[\"range\",\"map\"],min:4,max:16,step:1,label:\"Blades\",group:\"Effects\"}},streakIntensity:{default:.15,description:\"Brightness of horizontal anamorphic light streak\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Streak\",group:\"Effects\"}},streakLength:{default:.5,description:\"Horizontal extent of the anamorphic streak\",ui:{type:[\"range\",\"map\"],min:.1,max:1,step:.01,label:\"Streak Length\",group:\"Effects\"}},glareIntensity:{default:.2,description:\"Soft veiling glare that washes out contrast around the light\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Glare\",group:\"Effects\"}},glareSize:{default:.5,description:\"Size of the soft glare glow\",ui:{type:[\"range\",\"map\"],min:.1,max:1,step:.01,label:\"Glare Size\",group:\"Effects\"}},edgeFade:{default:.2,description:\"How much the flare fades when the light source is near the screen edge (0 = no fade, 1 = heavy fade)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Edge Fade\",group:\"Light\"}},speed:{default:.5,description:\"Speed of subtle flare shimmer and starburst rotation\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Speed\",group:\"Animation\"}}},paint:e=>{let t=ns(SD({position:T(\"lightPosition\"),intensity:T(\"intensity\"),edgeFade:T(\"edgeFade\")})(e),\"flare\"),s=PD({intensity:T(\"ghostIntensity\"),spread:T(\"ghostSpread\"),chroma:T(\"ghostChroma\")});return zD(i2(i2(s(t,[.15,.2,.3,.1],[1,.95,.9,0],e),s(t,[.3,.12,.25,.65],[1,.85,.55,2.17],e),s(t,[.5,.08,.35,.15],[.62,.82,1,4.34],e),s(t,[.72,.14,.18,.75],[.75,1,.7,6.51],e),s(t,[.95,.06,.3,0],[1,.6,.85,8.68],e),s(t,[1.25,.1,.15,.8],[.55,.88,1,10.85],e),s(t,[1.55,.07,.2,.25],[1,.92,.6,13.02],e)),CD({intensity:T(\"haloIntensity\"),radius:T(\"haloRadius\"),chroma:T(\"haloChroma\"),softness:T(\"haloSoftness\")})(t,e),MD({intensity:T(\"starburstIntensity\"),points:T(\"starburstPoints\")})(t,e),ED({intensity:T(\"streakIntensity\"),length:T(\"streakLength\")})(t,e),kD({intensity:T(\"glareIntensity\"),size:T(\"glareSize\")})(t,e),BD({intensity:T(\"intensity\")})(t,e)),t)}});var Hpe=JSON.stringify({type:\"sphere3D\",radius:.35}),jpe=[{color:\"#7b2ff7\",position:0},{color:\"#00e0ff\",position:.5},{color:\"#ff3d81\",position:1}],nI=H({name:\"LightEdge\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Glowing, pulsing light racing around the edge of any 2D, SVG, or 3D shape. Powered by Paper Shaders.\",animatedTime:{speed:\"speed\"},...Ts({chord:\"firstLobe\",stencil:\"centre\",surface:(e,t)=>{let{uniforms:s,propValues:r}=t,o=wt(t),a=ns(W(h8,\"heartbeatPulse\",[o]),\"beat\"),i=W(g8,\"edgeGlowBand\",[e.surf0.member(\"r\"),e.sdfUV,t.ctx.viewportSize,s.scale,s.thickness,s.softness,s.smokeSize,s.smoke,o,s.pulse,a]),l=i.member(\"x\"),c=i.member(\"y\"),d=r.stopCount??0,u=d>1?Math.min(d,8):2,p=x8(r.colorSpace??0),_=g=>W(y8,\"orbitSpotsAccum\",[c,l,o,a,s.spots,s.spotSize,s.pulse,s.intensity,s.softness,s.seed,$e(g)]),f=g=>d>1?W(A8,\"colorAtIndex\",[s.colorsArray,$e(g)]):g===0?s.colorA:s.colorB,h=W(b8,\"edgeGlowAccumZero\",[]);for(let g=0;g<u;g++)h=W(p,\"edgeGlowAccumColor\",[h,f(g),_(g)]);return W(w8,\"edgeGlowCompose\",[h,s.bloom])}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},colorA:{default:\"#7b2ff7\",transform:ce,description:\"First border light color (used when no gradient stops are set)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#00e0ff\",transform:ce,description:\"Second border light color (used when no gradient stops are set)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:{...Ms(),default:jpe},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space overlapping lights blend in\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},thickness:{default:.25,description:\"Width of the border band\",ui:{type:[\"range\",\"map\"],min:.01,max:1,step:.01,label:\"Thickness\",group:\"Border\"}},softness:{default:.5,description:\"Edge softness \\u2014 0 = crisp band, 1 = wide smooth gradient\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Border\"}},intensity:{default:.6,description:\"Brightness of the individual light spots\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Light\"}},bloom:{default:.3,description:\"How additively overlapping lights pile up \\u2014 high values overdrive to white\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bloom\",group:\"Light\"}},spots:{default:3,description:\"Number of light spots orbiting per color\",ui:{type:\"range\",min:1,max:5,step:1,label:\"Spots\",group:\"Light\"}},spotSize:{default:.5,description:\"Angular size of each light spot\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Spot Size\",group:\"Light\"}},pulse:{default:0,description:\"Heartbeat pulsing \\u2014 synchronizes the lights to a double-beat rhythm\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Pulse\",group:\"Animation\"}},smoke:{default:.3,description:\"Noisy luminous smoke drifting along the border\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Smoke\",group:\"Smoke\"}},smokeSize:{default:.5,description:\"Scale of the smoke billows\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Smoke Size\",group:\"Smoke\"}},speed:{default:1,description:\"Animation speed. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed \\u2014 re-rolls spot speeds, directions and phases\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}},shape:{default:Hpe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var iI=H({name:\"LightLeak\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Photorealistic film light leak \\u2014 warm overexposed light bleeding in from a draggable anchor point, with streak bands, chromatic fringing, and slow breathing that evolves over time\",usesPointer:!1,animatedTime:{speed:\"speed\"},props:{position:{default:{x:.95,y:.4},transform:Xe,description:\"Anchor point of the leak \\u2014 the light beams from here toward the canvas centre\",ui:{type:\"position\",label:\"Position\",group:\"Leak\",units:[\"%\",\"px\"]}},spread:{default:.55,description:\"How far the light bleeds into the frame\",ui:{type:[\"range\",\"map\"],min:.1,max:1.5,step:.01,label:\"Spread\",group:\"Leak\"}},intensity:{default:.15,description:\"Exposure strength of the leak\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Leak\"}},streaks:{default:.6,description:\"Strength of the parallel streak bands further into the frame\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Streaks\",group:\"Leak\"}},colorHot:{default:\"#fff3c4\",transform:ce,description:\"Core color where the leak is fully overexposed\",ui:{type:\"color\",label:\"Hot Core\",group:\"Colors\"}},colorMid:{default:\"#ff7a2f\",transform:ce,description:\"Main body color of the leak\",ui:{type:\"color\",label:\"Midtone\",group:\"Colors\"}},colorFringe:{default:\"#a63d8f\",transform:ce,description:\"Outer fringe color where the light fades out\",ui:{type:\"color\",label:\"Fringe\",group:\"Colors\"}},flicker:{default:.35,description:\"Breathing of the leak intensity\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Flicker\",group:\"Animation\"}},speed:{default:1,description:\"Speed of the breathing, drift and evolution. 0 freezes the leak.\",ui:{type:\"range\",min:0,max:4,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed \\u2014 re-rolls the drift and breathing pattern\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}}},effect:OD(e=>{let t=ns(wt(e).mul(.6).add(At(T(\"seed\"),e).mul(7.9)),\"leakClock\"),s=ns(fD(T(\"position\"))(e),\"leakFrame\"),r=ns(bD({seed:T(\"seed\"),flicker:T(\"flicker\")})(t,e),\"leakDrift\"),o=ns(xD({spread:T(\"spread\")})(s,r,e),\"leakBloom\"),a=AD({spread:T(\"spread\"),strength:T(\"streaks\")})(s,r,e),i=o.member(\"x\").mul(1.25).add(o.member(\"y\")).add(a.mul(.85)).mul(At(T(\"intensity\"),e)).mul(2.2).mul(r.member(\"x\"));return DD({hot:T(\"colorHot\"),mid:T(\"colorMid\"),fringe:T(\"colorFringe\")}).taps(wD(i,e.ctx.uv,t),e)}),missingChildMessage:\"You must pass a child component into the Light Leak shader.\"});var Kpe={solid:0,dashed:1,dotted:2},Qpe=e=>Kpe[e]??0,Zpe={square:0,rounded:1},lI=e=>Zpe[e]??1,cI=[{label:\"Square\",value:\"square\"},{label:\"Rounded\",value:\"rounded\"}],dI=H({name:\"Line\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Shapes\",description:\"Draw a straight line between two points with color, thickness, and solid, dashed, or dotted styles\",acceptsUVContext:!0,props:{color:{default:\"#ffffff\",transform:ce,description:\"The color of the line\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},pointA:{default:{x:.2,y:.5},transform:Xe,description:\"The start point of the line\",ui:{type:\"position\",label:\"Point A\",group:\"Position\",units:[\"%\",\"px\"]}},pointB:{default:{x:.8,y:.5},transform:Xe,description:\"The end point of the line\",ui:{type:\"position\",label:\"Point B\",group:\"Position\",units:[\"%\",\"px\"]}},thickness:{default:.01,description:\"The thickness of the line. A value of one (1) matches the canvas height.\",ui:{type:[\"range\",\"map\"],min:0,max:.25,step:.001,label:\"Thickness\",group:\"Effect\",dimensional:\"canvas-height\"}},style:{default:\"solid\",transform:Qpe,description:\"The line style: solid, dashed, or dotted. Dashes and dots are spaced to land exactly on both endpoints.\",ui:{type:\"select\",options:[{label:\"Solid\",value:\"solid\"},{label:\"Dashed\",value:\"dashed\"},{label:\"Dotted\",value:\"dotted\"}],label:\"Style\",group:\"Style\"}},dashLength:{default:.05,description:\"The length of each dash, including its caps\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.001,label:\"Dash Length\",group:\"Style\",dimensional:\"canvas-height\",condition:{style:\"dashed\"}}},gapLength:{default:.025,description:\"The gap between dashes, or the spacing between dots\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.001,label:\"Gap Length\",group:\"Style\",dimensional:\"canvas-height\",condition:{style:[\"dashed\",\"dotted\"]}}},capStart:{default:\"rounded\",transform:lI,description:\"Cap shape at the start of the line (point A). Rounded caps center on the endpoint; square caps end flat exactly at it. Also shapes the A-facing end of each dash and dot.\",ui:{type:\"select\",options:cI,label:\"Start Cap\",group:\"Style\"}},capEnd:{default:\"rounded\",transform:lI,description:\"Cap shape at the end of the line (point B). Rounded caps center on the endpoint; square caps end flat exactly at it. Also shapes the B-facing end of each dash and dot.\",ui:{type:\"select\",options:cI,label:\"End Cap\",group:\"Style\"}}},paint:RL({from:T(\"pointA\"),to:T(\"pointB\"),width:T(\"thickness\"),style:T(\"style\"),dashLength:T(\"dashLength\"),gapLength:T(\"gapLength\"),capStart:T(\"capStart\"),capEnd:T(\"capEnd\"),color:T(\"color\")})});var uI=H({name:\"LinearBlur\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Directional motion blur in a specific angle\",props:{intensity:{default:30,description:\"Intensity of the linear blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Direction of the linear blur (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},dispersion:{default:0,description:\"Spectral color fringing along the streak, like light through a lens; negative flips which end is red\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Dispersion\",group:\"Lens\"}},falloff:{default:0,description:\"Concentrates the dispersion away from the center; 0 fringes everywhere equally\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Lens\"}},focus:{default:0,description:\"Radius of a clean zone around the center that stays sharp\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Focus\",group:\"Lens\"}},bias:{default:0,description:\"Trails the streak off one side of each pixel like a comet; the sign picks the direction\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Bias\",group:\"Streak\"}},highlights:{default:0,description:\"Lets bright pixels streak further than dark ones, like light rays\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlights\",group:\"Streak\"}},jitter:{default:0,description:\"Per-pixel noise on the tap spacing that hides banding in long streaks\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Jitter\",group:\"Streak\"}}},effect:Tp({path:wp.linear(T(\"angle\")),amount:T(\"intensity\"),detail:{dispersion:T(\"dispersion\"),falloff:T(\"falloff\"),focus:T(\"focus\"),bias:T(\"bias\"),highlights:T(\"highlights\"),jitter:T(\"jitter\")}})});var pI=H({name:\"LinearGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Create smooth linear color gradients\",acceptsUVContext:!0,props:{colorA:{default:\"#1aff00\",transform:ce,description:\"The starting color of the gradient\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#0000ff\",transform:ce,description:\"The ending color of the gradient\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),start:{default:{x:0,y:.5},transform:Xe,description:\"The starting point of the gradient\",ui:{type:\"position\",label:\"Start\",group:\"Position\"}},end:{default:{x:1,y:.5},transform:Xe,description:\"The ending point of the gradient\",ui:{type:\"position\",label:\"End\",group:\"Position\"}},angle:{default:0,transform:cs,description:\"Additional rotation angle of the gradient (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},edges:{default:\"stretch\",transform:Fr,compileTime:!0,description:\"How to handle areas beyond the gradient endpoints\",ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(Oi.linear({from:T(\"start\"),to:T(\"end\"),angle:T(\"angle\")}),Us(T(\"colorSpace\")),{edges:T(\"edges\")})});var mI=H({name:\"LinearWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away along a straight edge with a soft feathered transition\",props:{progress:{default:.5,description:\"How far the wipe has travelled (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},angle:{default:0,description:\"Direction of the wipe in degrees (0 = left to right)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Transition\"}},feather:{default:.1,description:\"Softness of the wipe edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse the direction the wipe travels\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.directional(T(\"angle\")),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Linear Wipe shader.\"});var{isMobileGpuViewport:Jpe}=kn,eme=JSON.stringify({type:\"sphere3D\",radius:.35});function _I(e,t,s,r,o,a,i){let l=z(ne(v(e,s),v(t,r)),\"ex\"),c=z(I(v(e,r),v(t,s)),\"ey\"),d=z(rt(l,c),\"p\"),u=z(ot(-.7,.85,c),\"sky\"),p=v(v(u,u),.4),_=z(v(o,1.05),\"r0\"),f=ot(_,v(_,.2),Kr(ne(d,rt(I(0,a),.55))));p=I(p,v(v(f,1.75),i));let h=z(v(o,1.25),\"r1\"),g=ot(h,v(h,.2),Kr(ne(d,rt(I(-.45,a),-.4))));p=I(p,v(v(g,1.15),i));let y=z(v(o,1.15),\"r2\"),b=ot(y,v(y,.2),Kr(ne(d,rt(I(.55,a),.1))));return I(p,v(v(b,1.1),i))}var fI=H({name:\"LiquidMetal\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Flowing liquid chrome \\u2014 a molten reflective surface that wraps the shape, sweeping a procedural studio reflection across animated folds with crisp speculars and prismatic edges\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=Jpe(),a=Lr(e,t,{scale:s.scale}),{sdf:i,pxH:l}=a,c=Dn(e,a,{bevelWidth:s.bevelWidth,bevelShape:s.bevelShape}),d=go(e,a),u=z(v(s.ripple,2.6),\"freq\"),p=z(v(r,.12),\"flowT\"),_=z(rt(v(d.member(\"x\"),u),v(d.member(\"y\"),u)),\"q\"),f=v(s.warp,.9),h=z(Ag(I(_,v(Tg(v(_,.6),p),f)),.62),\"hg\"),g=z(v(s.turbulence,.5),\"relief\"),y=Gi(c,v(v(h.member(\"x\"),g),-1),v(v(h.member(\"y\"),g),-1)),b=z(Lo(Ea(t,a),y),\"R\"),x=z(s.environment,\"envStr\"),P=z(Ge(s.sharpness,0,1),\"sharp\"),C=z(et(.5,.18,P),\"keyRad\"),E=z(v(Vt(v(r,.07)),.05),\"drift\"),R=Er(s.envRotation,\"env\"),U=R.member(\"x\"),L=R.member(\"y\"),k=z(Un(Er(s.lightAngle,\"light\"),-.7).member(\"H\"),\"Hh\"),D=z(xg(Ge(I(I(v(y.member(\"x\"),k.member(\"x\")),v(y.member(\"y\"),k.member(\"y\"))),v(y.member(\"z\"),k.member(\"z\"))),0,1),P,Ot(60,900,.4,1.4)),\"spec\"),O=z(I(_I(b.member(\"x\"),b.member(\"y\"),U,L,C,E,x),D),\"lumG\"),F,q;if(o)F=O,q=O;else{let Q=ne(1,Ge(v(y.member(\"z\"),-1),0,1)),te=z(v(v(s.dispersion,.09),I(.4,v(Q,1.3))),\"dth\"),J=z(I(_I(I(b.member(\"x\"),v(b.member(\"y\"),te)),ne(b.member(\"y\"),v(b.member(\"x\"),te)),U,L,C,E,x),D),\"lumBoffset\");q=J,F=ne(v(O,2),J)}let Y=z(s.darkColor.member(\"rgb\"),\"dark\"),V=z(s.lightColor.member(\"rgb\"),\"light\"),X=Ot(et(Y.member(\"x\"),V.member(\"x\"),Ge(F,0,1.8)),et(Y.member(\"y\"),V.member(\"y\"),Ge(O,0,1.8)),et(Y.member(\"z\"),V.member(\"z\"),Ge(q,0,1.8)),Jr(a,s.edgeSoftness));return Js(Dr(i,l),X,xt,\"liquidMetal\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the metal shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the metal shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the metal shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},lightColor:{default:\"#eef0f6\",transform:ce,description:\"The bright tone of the chrome highlights\",ui:{type:\"color\",label:\"Light Color\",group:\"Metal\"}},darkColor:{default:\"#141414\",transform:ce,description:\"The dark tone the reflection falls to in shadow \\u2014 recolor for tinted metal (gold, steel, copper\\u2026)\",ui:{type:\"color\",label:\"Dark Color\",group:\"Metal\"}},turbulence:{default:1,description:\"How molten the surface is \\u2014 the depth of the flowing folds that bend the reflection\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Turbulence\",group:\"Liquid\"}},ripple:{default:4,description:\"Scale of the molten folds \\u2014 higher = smaller, busier ripples\",ui:{type:\"range\",min:.5,max:8,step:.01,label:\"Ripple Scale\",group:\"Liquid\"}},warp:{default:1.5,description:\"Swirl of the flow \\u2014 domain-warps the folds into liquid curls\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Swirl\",group:\"Liquid\"}},speed:{default:.5,description:\"Speed of the molten flow and the slowly drifting reflection. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Liquid\"}},...gr({environment:{default:1.5,description:\"Strength of the reflected studio lighting \\u2014 the softboxes seen across the metal\",ui:{group:\"Surface\"}},envRotation:{ui:{group:\"Surface\"}}}),sharpness:{default:.6,description:\"Tightness of the specular highlights \\u2014 1 = razor chrome glints, 0 = soft satin\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Sharpness\",group:\"Surface\"}},...gr({dispersion:{description:\"Prismatic color fringing along the reflection edges\",ui:{group:\"Surface\"}},lightAngle:{default:265,description:\"Direction of the key light for the specular glints, in degrees\",ui:{group:\"Surface\"}}}),bevelWidth:{default:.05,description:\"Width of the edge bevel, relative to the shape \\u2014 thin for machined jewellery edges, wide for soft pillowed metal\",ui:{type:[\"range\",\"map\"],min:.005,max:.2,step:.001,label:\"Bevel Width\",group:\"Surface\"}},bevelShape:{default:0,description:\"Bevel profile \\u2014 0 = one smooth round fillet, 1 = machined: a steep outer fillet, a chamfer plateau and an inner knee, each catching its own line of light\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bevel Profile\",group:\"Surface\"}},...gr({edgeSoftness:{ui:{group:\"Surface\"}}}),shape:{default:eme,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var vI=H({name:\"Liquify\",role:\"warp\",category:\"Interactive\",description:\"Liquid-like interactive deformation effect\",boundingBoxDeclaration:{aspectRatio:null},usesPointer:!0,props:{intensity:{default:10,description:\"Scale of the fabric displacement effect\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Intensity\",group:\"Effect\"}},stiffness:{default:3,description:\"Fabric rigidity (higher = stiffer canvas, lower = stretchy silk)\",ui:{type:\"range\",min:1,max:30,step:.5,label:\"Stiffness\",group:\"Effect\"}},damping:{default:3,description:\"How quickly fabric motion settles\",ui:{type:\"range\",min:0,max:10,step:.1,label:\"Damping\",group:\"Effect\"}},radius:{default:1,description:\"Cursor influence area\",ui:{type:\"range\",min:.1,max:1.5,step:.1,label:\"Radius\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},...Ec(Y8({stiffness:T(\"stiffness\"),damping:T(\"damping\"),radius:T(\"radius\"),output:\"displacement\"})),map:iU({intensity:T(\"intensity\"),output:\"displacement\"}),uvRemapIdentityWhen:({computeOutputs:e})=>!e?.displacement});var Qg=12288,Id=vn({desktop:1024,mobile:768}),hI=\"rgba16float\",tme=14,sme=45,rme=6,ome=3,ame=9,nme=6,ime=1,lme=2.5,cme=.25,dme=.12,gI=.14,yI=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({colA:S,colB:S,count:n,dt:n,aspect:n,domainX:n,cursorX:n,cursorY:n,axisX:n,axisY:n,fieldType:n,restMode:n,strength:n,reachSq:n,alignK:n,damping:n,restK:n,pullK:n,homeK:n,omegaRef:n,agitCool:n,gridCols:n,cellW:n,cellH:n,jitter:n,bodyR:n}),\"SimParams\"),zc=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({agents:{storage:Fe(S,Qg),access:\"mutable\"},agit:{storage:Fe(n,Qg),access:\"mutable\"},accumE:{storage:Fe(lo(M),Id*Id),access:\"mutable\"},accumS:{storage:Fe(lo(M),Id*Id),access:\"mutable\"},params:{uniform:yI},outTex:{storageTexture:zt(hI,\"write-only\")}}),\"simLayout\"),ume=mz(zc,\"filingsInit\"),bI=w2.jitteredGridHome(zc,{overscan:gI}),pme=w2.dipoleOrRadial(zc),mme=On.orientation2d(zc,{home:bI,fieldAt:pme,torques:[A2.alignToField(zc),A2.rest(zc)],maxOffset:dme,name:\"filingsUpdate\"});function j2(e,t){return Gn.orientedWorld(zc,{shape:e,res:Id,splatRCap:tme,heading:\"angle\",agitation:\"buffer\",comet:!1,home:bI,ramp:{colorSpace:t,trails:\"none\"},names:{splat:\"filingsSplat\",resolve:\"filingsResolve\"}})}var _me=e=>j2(e,2).splat.kernel,fme=e=>j2(\"streak\",e).resolve.kernel,l2e=_me(\"streak\"),c2e=fme(2),xI=H({name:\"MagneticFilings\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Thousands of tiny iron filings scattered on paper that swing to align with a magnetic field around the cursor, tracing out the field lines \\u2014 a dipole whose axis follows the cursor's motion draws the classic two-lobed swirl, and every sweep of the magnet sends a glowing wave of filings flipping and settling\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{colorA:{default:\"#be1ef9\",transform:ce,description:\"Color of filings resting quietly, aligned and still\",ui:{type:\"color\",label:\"Rest Color\",group:\"Colors\"}},colorB:{default:\"#6326ff\",transform:ce,description:\"Color filings flash toward as they swing and settle \\u2014 a wave of it follows the moving magnet\",ui:{type:\"color\",label:\"Excited Color\",group:\"Colors\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the rest\\u2192excited color ramp\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},shape:{default:\"dot\",compileTime:!0,description:\"How each filing is drawn \\u2014 a slim streak or arrow reads as a compass needle, a box as a chunky filing, a dot or soft glow for a finer grain\",ui:{type:\"select\",options:lp,label:\"Shape\",group:\"Filings\"}},count:{default:8e3,description:\"Number of iron filings\",ui:{type:\"range\",min:500,max:12e3,step:500,label:\"Count\",group:\"Filings\"}},size:{default:1,description:\"Size of each filing\",ui:{type:\"range\",min:.5,max:3,step:.05,label:\"Size\",group:\"Filings\"}},restOrientation:{default:\"random\",description:\"Which way filings point where the field can't reach them \\u2014 randomly, all horizontal, or all vertical\",ui:{type:\"select\",options:[{label:\"Random\",value:\"random\"},{label:\"Horizontal\",value:\"horizontal\"},{label:\"Vertical\",value:\"vertical\"}],label:\"Rest Orientation\",group:\"Filings\"}},fieldType:{default:\"dipole\",description:\"The magnetic field the filings reveal \\u2014 a dipole (bar-magnet lobes that follow the cursor's motion) or a radial monopole (spokes out from the cursor)\",ui:{type:\"select\",options:[{label:\"Dipole\",value:\"dipole\"},{label:\"Radial\",value:\"radial\"}],label:\"Field Type\",group:\"Field\"}},strength:{default:1.7,description:\"How strongly the magnet grips the filings \\u2014 higher snaps more of them into sharp alignment\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Strength\",group:\"Field\"}},reach:{default:.6,description:\"How far the magnet's influence spreads (in screen heights) \\u2014 larger reveals more of the field at once\",ui:{type:\"range\",min:.1,max:1,step:.01,label:\"Reach\",group:\"Field\"}},response:{default:.5,description:\"How briskly filings swing and settle \\u2014 low is loose and floppy with a long wobble, high snaps into place quickly\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Response\",group:\"Field\"}}},...Fn({layout:zc,params:yI,maxAgents:Qg,countCap:{desktop:Qg,mobile:6e3},output:{key:\"outTex\",name:\"filingsTexture\",size:[Id,Id],format:hI},bake:({getCpuValue:e})=>{let t=j2(e(\"shape\")||\"streak\",e(\"colorSpace\")??2);return{pipelines:{init:{kernel:ume,threads:\"max\"},update:{kernel:mme,threads:\"agents\"},splat:t.splat,resolve:t.resolve},initStep:\"init\",program:[\"update\",\"splat\",\"resolve\"]}},frame:(e,{getCpuValue:t})=>{let s=Li(t),r=rO({smoothing:.1,teleport:.25});return o=>{let{dt:a,aspect:i,pointerX:l,pointerY:c}=Di(o),d=Math.max(i,.01),u=e.resolveCount(s(\"count\",5e3)),{cols:p,cellW:_,cellH:f}=oO(u,d,gI),h=l*i,g=c,y=r.update(h,g),b=(t(\"fieldType\")??\"dipole\")===\"radial\"?1:0,x=t(\"restOrientation\")??\"random\",P=x===\"horizontal\"?1:x===\"vertical\"?2:0,C=s(\"strength\",1),E=s(\"reach\",.35),R=Math.min(Math.max(s(\"response\",.5),0),1),U=t(\"colorA\"),L=t(\"colorB\"),k=Math.min(Math.max(s(\"size\",1),.5),3)*1.7/Ri;return e.writeParams({colA:S(U?.x??.522,U?.y??.573,U?.z??.639,U?.w??1),colB:S(L?.x??1,L?.y??.616,L?.z??.361,L?.w??1),count:u,dt:a,aspect:i,domainX:d,cursorX:h,cursorY:g,axisX:y.x,axisY:y.y,fieldType:b,restMode:P,strength:C,reachSq:E*E,alignK:sme,damping:ome+R*ame,restK:rme,pullK:cme,homeK:lme,omegaRef:nme,agitCool:ime,gridCols:p,cellW:_,cellH:f,jitter:.85,bodyR:k}),e.frame({count:u})}},fragment:{output:\"filingsTexture\",fallback:\"transparent\"}})});var vme=3.141592653589793,AI=H({name:\"Marble\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Classic marble swirl and vein texture using noise-warped sine waves\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#ffffff\",transform:ce,description:\"Base background color of the marble\",ui:{type:\"color\",label:\"Base\",group:\"Colors\"}},colorB:{default:\"#3a2d54\",transform:ce,description:\"Secondary marble tone\",ui:{type:\"color\",label:\"Tone\",group:\"Colors\"}},colorC:{default:\"#0f0f0f\",transform:ce,description:\"Deepest marble color\",ui:{type:\"color\",label:\"Depth\",group:\"Colors\"}},scale:{default:2,description:\"Scale and density of the marble vein pattern\",ui:{type:[\"range\",\"map\"],min:.1,max:10,step:.1,label:\"Scale\",group:\"Effect\"}},turbulence:{default:10,description:\"Amount of noise-driven distortion applied to the veins\",ui:{type:[\"range\",\"map\"],min:0,max:50,step:.5,label:\"Turbulence\",group:\"Effect\"}},speed:{default:.05,description:\"Animation speed\",ui:{type:\"range\",min:0,max:.25,step:.005,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:e=>{let{uv:t,viewport:s}=aa(e),r=z(Ce(s.member(\"x\"),it(s.member(\"y\"),1e-6)),\"aspect\"),o=z(wt(e),\"marbleTime\"),a=me(T(\"seed\"),e),i=z(v(rt(v(t.member(\"x\"),r),t.member(\"y\")),me(T(\"scale\"),e)),\"plane\"),l=i.member(\"x\"),c=i.member(\"y\"),d=z(I(I(pa(rt(I(l,a),I(c,o))),v(pa(rt(I(v(l,2),v(a,1.7)),I(v(c,2),v(o,.7)))),.5)),v(pa(rt(I(v(l,4),v(a,3.1)),I(v(c,4),v(o,1.3)))),.25)),\"marbleTurb\"),u=z(I(v(Vt(I(v(l,vme),v(d,me(T(\"turbulence\"),e)))),.5),.5),\"veinT\"),p=I(v(pa(rt(I(v(c,1.5),v(a,2)),v(l,1.2))),.3),.5);return pg({a:T(\"colorA\"),b:T(\"colorB\"),c:T(\"colorC\"),space:T(\"colorSpace\")})(ot(.3,.6,u),v(ot(.6,.9,u),p),e)}});var Zg=1.6,hme=.48,gme=.125,yme=3,wI=1.9,bme=1.4,xme=.045,Ame=9,wme=[{color:\"#1a0533\",position:0},{color:\"#6d2fd1\",position:.26},{color:\"#e04b9e\",position:.52},{color:\"#ff8c42\",position:.76},{color:\"#ffdf8e\",position:1}],TI=H({name:\"MeshGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Flowing mesh gradient of soft drifting color swaths whose seams wrap through the palette\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},extraFields:{meshAnchors:{schema:Fe(S,4),initial:new Array(16).fill(0)}},props:{colorA:{default:\"#1a0533\",transform:ce,description:\"First gradient color (two-color fallback when stops are cleared)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffdf8e\",transform:ce,description:\"Second gradient color (two-color fallback when stops are cleared)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:{...Ms(),default:wme},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},count:{default:5,description:\"Number of color points scattered across the canvas\",ui:{type:\"range\",min:2,max:8,step:1,label:\"Points\",group:\"Effect\"}},smoothness:{default:2,description:\"How smoothly the color points blend into each other\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.01,label:\"Smoothness\",group:\"Effect\"}},variation:{default:.35,recompile:Lt(0),description:\"Varies edge softness across the canvas \\u2014 some color boundaries crisp, others diffuse\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Effect\"}},swirl:{default:.3,description:\"Vortex rotation that spirals the field around the frame centre \\u2014 negative values spin the other way\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Swirl\",group:\"Effect\"}},drift:{default:.5,description:\"How far the color points wander from their home positions\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Drift\",group:\"Effect\"}},wrapping:{default:0,description:\"Wraps the palette back through itself where colors meet \\u2014 banded seams where the field pinches, smooth elsewhere\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Wrapping\",group:\"Effect\"}},speed:{default:1,description:\"Animation speed\",ui:{type:\"range\",min:0,max:10,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed for the point layout and palette assignment\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}}},paint:e=>{let{uv:t,viewport:s}=aa(e),r=z(Ce(s.member(\"x\"),it(s.member(\"y\"),1e-6)),\"aspect\"),o=z(wt(e),\"meshTime\"),a=me(T(\"seed\"),e),i=z(rt(ne(v(t.member(\"x\"),r),v(r,.5)),ne(t.member(\"y\"),.5)),\"meshCentred\"),l=z(v(v(-yme,me(T(\"swirl\"),e)),ot(0,1,Kr(i))),\"swirlAngle\"),c=z(ng(i,Do(l),Vt(l)),\"meshRot\"),d=z(rt(I(c.member(\"x\"),v(r,.5)),I(c.member(\"y\"),.5)),\"meshSwirled\"),u=z(LR({at:Qe(v(d.member(\"x\"),Zg),v(d.member(\"y\"),Zg),v(a,7.31)),time:v(o,gme),amount:hme,levels:Rr()?1:2}),\"meshWarp\"),p=z(rt(Ce(u.member(\"x\"),Zg),Ce(u.member(\"y\"),Zg)),\"meshQ\"),_=Ce(8,I(me(T(\"smoothness\"),e),.5)),f=e.propValues.variation,h=f!==void 0&&f!==0?Ge(v(_,tr(v(v(Jn(Qe(v(p.member(\"x\"),wI),v(p.member(\"y\"),wI),I(v(a,3.17),v(o,xme)))),me(T(\"variation\"),e)),bme))),.6,16):Ge(_,.6,16),g=zR(e,{count:T(\"count\"),seed:T(\"seed\"),drift:T(\"drift\"),field:\"meshAnchors\"});return BL(UR(RR({t:BR({at:p,count:me(T(\"count\"),e),seed:a,drift:me(T(\"drift\"),e),aspect:r,time:o,softness:h,anchors:g}),cycles:I(1,v(me(T(\"wrapping\"),e),Ame))}),e),e)}});var SI=H({name:\"Mirror\",role:\"warp\",category:\"Distortions\",description:\"Mirror content across a line defined by center point and angle\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The point the mirror line passes through\"),angle:{default:0,description:\"The angle of the mirror line in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},edges:fr(\"mirror\",\"How to handle edges when distortion pushes content out of bounds\")},map:VL({center:T(\"center\"),angle:T(\"angle\")}),missingChildMessage:\"You must pass a child component into the Mirror shader.\"});var PI=H({name:\"MultiPointGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Five individually placed color points blended together by proximity \\u2014 drag each point to shape the gradient\",acceptsUVContext:!0,props:{colorA:{default:\"#4776E6\",transform:ce,description:\"Color of control point A\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},positionA:{default:{x:.2,y:.2},transform:Xe,description:\"Position of control point A\",ui:{type:\"position\",label:\"Position A\",group:\"Position\"}},colorB:{default:\"#C44DFF\",transform:ce,description:\"Color of control point B\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},positionB:{default:{x:.8,y:.2},transform:Xe,description:\"Position of control point B\",ui:{type:\"position\",label:\"Position B\",group:\"Position\"}},colorC:{default:\"#1ABC9C\",transform:ce,description:\"Color of control point C\",ui:{type:\"color\",label:\"Color C\",group:\"Colors\"}},positionC:{default:{x:.2,y:.8},transform:Xe,description:\"Position of control point C\",ui:{type:\"position\",label:\"Position C\",group:\"Position\"}},colorD:{default:\"#F8BBD9\",transform:ce,description:\"Color of control point D\",ui:{type:\"color\",label:\"Color D\",group:\"Colors\"}},positionD:{default:{x:.8,y:.8},transform:Xe,description:\"Position of control point D\",ui:{type:\"position\",label:\"Position D\",group:\"Position\"}},colorE:{default:\"#FF8C42\",transform:ce,description:\"Color of control point E\",ui:{type:\"color\",label:\"Color E\",group:\"Colors\"}},positionE:{default:{x:.5,y:.5},transform:Xe,description:\"Position of control point E\",ui:{type:\"position\",label:\"Position E\",group:\"Position\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},smoothness:{default:2,description:\"Controls how smoothly colors blend.\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.01,label:\"Smoothness\",group:\"Effect\"}}},paint:IR({points:[{color:T(\"colorA\"),position:T(\"positionA\")},{color:T(\"colorB\"),position:T(\"positionB\")},{color:T(\"colorC\"),position:T(\"positionC\")},{color:T(\"colorD\"),position:T(\"positionD\")},{color:T(\"colorE\"),position:T(\"positionE\")}],smoothness:T(\"smoothness\"),space:T(\"colorSpace\")})});var{isMobileGpuViewport:Tme,VOLUMETRIC_FIELD_EXTRA_FIELDS:Sme}=kn,{ANALYTIC_SDF_EXTRA_FIELDS:Pme}=yc,Cme=JSON.stringify({type:\"sphere3D\",radius:.35}),Mme=6,Eme=4,CI=H({name:\"Nebula\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"A volumetric gas nebula sealed inside polished glass; billowing emission clouds with hollow dark cavities and hot glowing cores, star fields drifting at real depth behind the gas, all refracted through the curved walls of the shape and dressed with studio reflections\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=Tme()?Eme:Mme,a=t.propValues.colorSpace??0,i,l;if(a!==0){let Ee=\"\";t.onBeforeRender(()=>{let Ie=[\"veilColor\",\"gasColor\",\"coreColor\"].map(we=>t.getCpuValue(we));if(Ie.some(we=>!we))return;let ke=Ie.map(we=>`${we.x},${we.y},${we.z}`).join(\"|\");if(ke===Ee)return;Ee=ke;let Me=[\"convVeil\",\"convGas\",\"convCore\"];Ie.forEach((we,Ve)=>{let qe=fl(we.x,we.y,we.z,a);t.setExtraField(Me[Ve],[qe[0],qe[1],qe[2]])})});let ze=Bd[a]??hc;i=Ie=>W(ze,\"mixPreconvertedColors\",[s.convVeil,s.convGas,s.veilColor.member(\"a\"),s.gasColor.member(\"a\"),Ie]),l=(Ie,ke,Me)=>{let we=z(W(_l,\"mixInSpace\",[s.convVeil,s.veilColor.member(\"a\"),s.convGas,s.gasColor.member(\"a\"),Ie]),`${Me}AB`);return W(ze,\"mixPreconvertedColors\",[we.member(\"conv\"),s.convCore,we.member(\"alpha\"),s.coreColor.member(\"a\"),ke])}}else i=Ee=>W(Ar,\"mixColors\",[s.veilColor,s.gasColor,Ee]),l=(Ee,ze)=>W(Ar,\"mixColors\",[W(Ar,\"mixColors\",[s.veilColor,s.gasColor,Ee]),s.coreColor,ze]);let c=Lr(e,t,{scale:s.scale}),{sdf:d,pxH:u}=c,p=Dn(e,c,{bevelWidth:It(.09),bevelShape:It(0)}),_=Ea(t,c),f=yL(e,p,z(v(s.refraction,.16),\"bend\")),{x:h,y:g}=f.centered,y=gL(e),b=SL(c,e,{origin:f,view:_,shear:.55,lengthScale:.9}),x=b.length,P=z(v(s.gasScale,3.1),\"freq\"),C=z(v(r,.14),\"drift\"),E=z(v(s.seed,7.31),\"seedOff\"),R=z(v(xp(v(f.x,311.7),v(f.y,173.3)),.15/o),\"jit\"),U=z(v(pa(rt(I(I(v(h,1.3),v(C,.6)),v(E,.37)),I(v(g,1.3),v(E,.61)))),.5),\"macro\"),L=z(et(-.35,.5,s.cavity),\"cav\"),k=z(v(s.billow,.55),\"billowAmt\"),D=z(s.coreColor.member(\"rgb\"),\"coreRgb\"),O=z(s.veilColor.member(\"rgb\"),\"veilRgb\"),F=z(v(I(.3,v(x,.9)),6/o),\"eGain\"),q=z(v(v(I(.5,v(x,2.2)),s.density),3/o),\"aGain\"),Y=CL({steps:o,entry:b.entry,length:b.length,jitter:R,emissionGain:F,hint:\"gasAcc\"},({i:Ee,t:ze,z:Ie})=>{let ke=b.at(Ie),Me=PL({x:ke.x,y:ke.y,z:Ie},{frequency:P,drift:C,seed:E,billow:k,hint:`${Ee}`}),we=ot(0,.11,v(x,Math.min(ze,1-ze))),Ve=ne(1,Ge(v(ms(Me.fine),1.6),0,1)),qe=z(v(v(ot(0,.5,ne(I(Me.density,U),L)),we),I(.65,v(Ve,.7))),`dens${Ee}`),st=z(v(v(ot(.45,.75,Me.mid),we),s.dust),`dust${Ee}`),pt=z(l(ot(.05,.75,qe),ot(.68,1,qe),`cB${Ee}`),`cB${Ee}`).member(\"rgb\"),Ze=1-ze*.45,nt=v(ot(-.7,.3,Me.density),v(.05,we));return{emit:I(I(v(pt,v(qe,Ze)),v(D,v(ts(qe,3),v(s.glow,1.2*Ze)))),v(O,v(nt,Ze))),absorb:I(kt(v(qe,q)),v(Qe(1.5,1,.55),v(st,v(q,2.2))))}}),V=z(v(s.starScale,34),\"starFreq\"),X=z(v(s.twinkle,.5),\"twinkleAmt\"),Q=_2(b,{depth:1.1,pan:y,panRate:1.3,hint:\"far\"}),te=d2(z(rt(v(Q.x,V),v(Q.y,V)),\"farP\"),{variationFreq:.13,radius:[.004,.013],keep:[.35,.75],brightness:[.3,1.2],shimmer:Ee=>c2(r,Ee,{amount:X,rate:1.7,spread:40}),gain:s.stars,tint:{from:[.72,.82,1],to:[1,.92,.82],gain:1.6},hint:\"starFar\"}),J=_2(b,{depth:.25,pan:y,panRate:.55,hint:\"near\"}),oe=v(V,.56),le=d2(z(rt(I(v(J.x,oe),7.3),I(v(J.y,oe),2.9)),\"nearP\"),{variationFreq:.11,radius:[.003,.01],keep:[.45,.8],brightness:[.35,1.3],shimmer:Ee=>c2(r,Ee,{amount:X,rate:2.3,spread:34}),gain:s.stars,tint:{from:[.75,.85,1],to:[1,.95,.88],gain:1.8},hint:\"starNear\"}),se=Er(s.lightAngle,\"light\"),Te=z(Ge($t(p,Un(se,-.7).member(\"H\")),0,1),\"ndh\"),de=z(Lo(_,p),\"R\"),xe=z(Pc(de.member(\"x\"),de.member(\"y\"),{rotation:se,keyRadius:.2,drift:0,strength:s.environment,skyGain:.32}),\"envLum\"),Ae=wL(Te,{core:[140,1.3],halo:[22,.14],softness:s.highlightSoftness,gain:s.highlight}),De=yp(EL([{paint:i(It(.25)).member(\"rgb\"),opacity:.06,behind:Y.transmittance},Y.color,{paint:te.rgb,behind:Y.transmittance},{paint:le.rgb,behind:et(Y.transmittance,kt(1),.35)},{paint:v(Qe(.85,.92,1.08),xe),opacity:.38},v(Qe(1,.98,.95),Ae)]));return Js(Dr(d,u),Ot(De,Jr(c,s.edgeSoftness)),xt,\"nebula\")}}),extraFields:{...Sme,...Pme,convVeil:{schema:A,initial:[0,0,0]},convGas:{schema:A,initial:[0,0,0]},convCore:{schema:A,initial:[0,0,0]}},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the nebula shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the nebula shape (1 = default size)\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the nebula shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},coreColor:{default:\"#ffd9b0\",transform:ce,description:\"The hot color the densest gas cores glow with \\u2014 the embedded newborn stars\",ui:{type:\"color\",label:\"Core Color\",group:\"Nebula\"}},gasColor:{default:\"#ff5e7a\",transform:ce,description:\"The main emission color of the gas body \\u2014 H-alpha rose by default\",ui:{type:\"color\",label:\"Gas Color\",group:\"Nebula\"}},veilColor:{default:\"#3a5bdb\",transform:ce,description:\"The color of the thin outer veils and the deep-space background behind the gas\",ui:{type:\"color\",label:\"Veil Color\",group:\"Nebula\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space the veil \\u2192 gas \\u2192 core ramps blend in\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Nebula\"}},density:{default:1,description:\"Optical density of the gas \\u2014 how strongly clouds occlude the stars and gas behind them\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Density\",group:\"Nebula\"}},cavity:{default:0,description:\"How hollowed-out the nebula is \\u2014 0 fills the volume with cloud banks, high carves large dark voids between them\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Cavity\",group:\"Nebula\"}},dust:{default:.55,description:\"Cold dark dust lanes threading the gas \\u2014 absorb-only tendrils that redden the clouds and stars behind them\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Dust\",group:\"Nebula\"}},gasScale:{default:.4,description:\"Feature size of the gas \\u2014 higher = finer, busier cloud detail\",ui:{type:[\"range\",\"map\"],min:.1,max:1,step:.01,label:\"Gas Scale\",group:\"Nebula\"}},billow:{default:.6,description:\"Turbulent folding of the clouds \\u2014 0 = smooth drifting banks, 1 = heavily churned billows\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Billow\",group:\"Nebula\"}},glow:{default:0,description:\"Hot emission bloom of the dense cores\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Glow\",group:\"Nebula\"}},seed:{default:0,description:\"Random seed \\u2014 pans the gas field to a different region of noise space for a new cloud composition\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Nebula\"}},stars:{default:.07,description:\"Brightness of the star fields drifting at depth behind and inside the gas\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Stars\",group:\"Stars\"}},starScale:{default:1,description:\"Density of the star fields \\u2014 higher = smaller, busier stars\",ui:{type:[\"range\",\"map\"],min:.25,max:3,step:.01,label:\"Star Scale\",group:\"Stars\"}},twinkle:{default:.35,description:\"Intensity of the star twinkle (0 = steady stars, 1 = full shimmer)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Twinkle\",group:\"Stars\"}},...gr({refraction:{description:\"How strongly the curved glass walls bend the interior seen near the edges\"},environment:{default:.7,description:\"Strength of the studio softboxes reflected in the polished glass surface\"},highlight:{default:1.15,description:\"Sharp key-light glint on the glass\",ui:{group:\"Glass\"}},highlightSoftness:{ui:{group:\"Glass\"}},lightAngle:{description:\"Direction of the key light and reflected studio, in degrees\"},edgeSoftness:!0}),speed:{default:.3,description:\"Speed of the slowly churning gas and twinkling stars. 0 freezes the nebula.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Animation\"}},shape:{default:Cme,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var MI=H({name:\"NoiseDissolve\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Dissolve the content away through an organic noise pattern\",props:{progress:{default:.5,description:\"How far the dissolve has progressed (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},scale:{default:3,description:\"Frequency of the dissolve pattern (higher = smaller blobs)\",ui:{type:[\"range\",\"map\"],min:.5,max:20,step:.1,label:\"Scale\",group:\"Transition\"}},softness:{default:.25,description:\"How softly the erosion edge fades out (0 = hard-edged blobs)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Transition\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse the order the pattern dissolves in\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.noise(T(\"scale\"),T(\"seed\")),progress:T(\"progress\"),feather:T(\"softness\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Noise Dissolve shader.\"});var EI=H({name:\"ObjectTracker\",role:\"overlay\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Computer-vision style object detection overlay \\u2014 draws bounding boxes and labels around detected regions of the content below, with grid, quadtree and mosaic layouts.\",requiresRTT:!0,requiresChild:!0,props:{detectionMode:{default:\"bright\",compileTime:!0,description:\"What counts as a detectable object.\",ui:{type:\"select\",options:[{label:\"Transparency\",value:\"alpha\"},{label:\"Brightness\",value:\"bright\"},{label:\"Darkness\",value:\"dark\"},{label:\"Red\",value:\"red\"},{label:\"Green\",value:\"green\"},{label:\"Blue\",value:\"blue\"}],label:\"Detect\",group:\"Detection\"}},threshold:{default:.25,description:\"Detection cut-off.\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Threshold\",group:\"Detection\"}},layout:{default:\"mosaic\",compileTime:!0,description:\"How the canvas is partitioned into detection cells.\",ui:{type:\"select\",options:[{label:\"Grid\",value:\"grid\"},{label:\"Quadtree\",value:\"quadtree\"},{label:\"Mosaic\",value:\"mosaic\"}],label:\"Layout\",group:\"Detection\"}},cellSize:{default:400,description:\"Base cell size in pixels\",ui:{type:\"range\",min:24,max:800,step:1,label:\"Base Cell Size\",group:\"Detection\"}},maxDepth:{default:2,compileTime:!0,description:\"Maximum subdivision levels for Quadtree/Mosaic layouts (each level can quarter a cell).\",ui:{type:\"range\",min:1,max:5,step:1,label:\"Subdivision\",group:\"Detection\",condition:{layout:[\"quadtree\",\"mosaic\"]}}},boxStyle:{default:\"corners\",compileTime:!0,description:\"Bounding box outline style\",ui:{type:\"select\",options:[{label:\"Full\",value:\"full\"},{label:\"Corners\",value:\"corners\"}],label:\"Box Style\",group:\"Boxes\"}},lineWidth:{default:1.5,description:\"Thickness of the box outline in pixels.\",ui:{type:\"range\",min:.5,max:12,step:.5,label:\"Line Width\",group:\"Boxes\"}},cornerRadius:{default:0,description:\"Corner radius of the box outline in pixels\",ui:{type:\"range\",min:0,max:40,step:1,label:\"Corner Radius\",group:\"Boxes\",condition:{boxStyle:\"full\"}}},strokeColor:{default:\"#ffffff\",transform:ce,description:\"Bounding box outline color.\",ui:{type:\"color\",label:\"Stroke\",group:\"Colors\"}},fillColor:{default:\"#5a79911a\",transform:ce,description:\"Bounding box fill color.\",ui:{type:\"color\",label:\"Fill\",group:\"Colors\"}},labelColor:{default:\"#000000\",transform:ce,description:\"Label text color.\",ui:{type:\"color\",label:\"Label\",group:\"Colors\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},labelBackgroundColor:{default:\"#ffffff\",transform:ce,description:\"Label pill background color.\",ui:{type:\"color\",label:\"Label Background\",group:\"Colors\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},labelMode:{default:\"none\",compileTime:!0,description:\"What each label shows.\",ui:{type:\"select\",options:[{label:\"None\",value:\"none\"},{label:\"Dimensions\",value:\"dimensions\"},{label:\"Percentage\",value:\"percentage\"}],label:\"Label\",group:\"Labels\"}},labelPosition:{default:\"bottom-right\",compileTime:!0,description:\"Which corner of the box the label anchors to.\",ui:{type:\"select\",options:[{label:\"Bottom Left\",value:\"bottom-left\"},{label:\"Bottom Right\",value:\"bottom-right\"},{label:\"Top Left\",value:\"top-left\"},{label:\"Top Right\",value:\"top-right\"}],label:\"Label Position\",group:\"Labels\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},labelRadius:{default:0,description:\"Corner radius of the label pill in pixels.\",ui:{type:\"range\",min:0,max:30,step:1,label:\"Border Radius\",group:\"Labels\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},labelInset:{default:!0,transform:rs,description:\"Place the label inside or outside the box.\",ui:{type:\"checkbox\",label:\"Label Inset\",group:\"Labels\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},fontFamily:{default:\"Inter\",description:\"Google Fonts family used for label text.\",ui:{type:\"font-family\",label:\"Font\",group:\"Typography\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},fontWeight:{default:500,description:\"Font weight for label text.\",ui:{type:\"font-weight\",label:\"Weight\",group:\"Typography\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},fontSize:{default:.015,description:\"Label text size as a fraction of canvas height.\",ui:{type:\"range\",min:.01,max:.5,step:.005,label:\"Size\",group:\"Typography\",dimensional:\"canvas-height\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}},letterSpacing:{default:0,description:\"Letter spacing for label text, in em units.\",ui:{type:\"range\",min:-.1,max:.5,step:.005,label:\"Letter Spacing\",group:\"Typography\",condition:{labelMode:[\"dimensions\",\"percentage\"]}}}},gpu:{fragment:G8({detectionMode:T(\"detectionMode\"),threshold:T(\"threshold\"),layout:T(\"layout\"),cellSize:T(\"cellSize\"),maxDepth:T(\"maxDepth\"),boxStyle:T(\"boxStyle\"),lineWidth:T(\"lineWidth\"),cornerRadius:T(\"cornerRadius\"),strokeColor:T(\"strokeColor\"),fillColor:T(\"fillColor\"),labelColor:T(\"labelColor\"),labelBackgroundColor:T(\"labelBackgroundColor\"),labelMode:T(\"labelMode\"),labelPosition:T(\"labelPosition\"),labelInset:T(\"labelInset\"),labelRadius:T(\"labelRadius\"),fontFamily:T(\"fontFamily\"),fontWeight:T(\"fontWeight\"),fontSize:T(\"fontSize\"),letterSpacing:T(\"letterSpacing\")})}});var kme=JSON.stringify({type:\"sphere3D\",radius:.35}),Bme=[{color:\"#ff2f7a\",position:0},{color:\"#2a2cff\",position:.3},{color:\"#5fe6ff\",position:.55},{color:\"#a6ffd8\",position:.75},{color:\"#ffb3e6\",position:1}],zme=.9,Rme=.55,Dme=.25,kI=H({name:\"Obsidian\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Dark tinted glass whose faces stay near-black while every surface turning away from the viewer ignites with a flowing iridescent gradient \\u2014 vivid color living only on the oblique walls and bevels\",animatedTime:{speed:\"speed\"},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the glass shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the glass shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the glass shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},bodyColor:{default:\"#06071a\",transform:ce,description:\"The dark body of the glass \\u2014 what the faces looking straight at you show. Keep it deep for the iridescence to pop.\",ui:{type:\"color\",label:\"Body Color\",group:\"Colors\"}},colorA:{default:\"#ff2f7a\",transform:ce,description:\"First iridescent color (two-color fallback when stops are cleared)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#5fe6ff\",transform:ce,description:\"Second iridescent color (two-color fallback when stops are cleared)\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:{...Ms(),default:Bme},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},iridescence:{default:1,description:\"Strength of the color on the oblique surfaces \\u2014 0 = plain dark glass, above 1 = saturated neon walls\",ui:{type:[\"range\",\"map\"],min:0,max:1.5,step:.01,label:\"Iridescence\",group:\"Iridescence\"}},rimWidth:{default:.55,description:\"How far in from edge-on the color reaches \\u2014 small keeps it to the steepest walls, large lets it creep across gently turning faces\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Rim Width\",group:\"Iridescence\"}},rimSoftness:{default:.25,description:\"Softness of the transition from dark face to colored wall\",ui:{type:[\"range\",\"map\"],min:.02,max:.6,step:.01,label:\"Rim Softness\",group:\"Iridescence\"}},flowAngle:{default:30,description:\"Direction the gradient flows across the surface, in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Flow Angle\",group:\"Iridescence\"}},flowScale:{default:1,description:\"How many times the palette cycles across the shape \\u2014 higher = tighter color bands\",ui:{type:[\"range\",\"map\"],min:.2,max:4,step:.01,label:\"Flow Scale\",group:\"Iridescence\"}},speed:{default:.5,description:\"Speed the gradient flows along the walls. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Iridescence\"}},gloss:{default:.35,description:\"Strength of the studio softboxes reflected in the glass \\u2014 the pale highlights riding the top edges\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Gloss\",group:\"Surface\"}},...gr({envRotation:{ui:{group:\"Surface\"}}}),bevelWidth:{default:.08,description:\"Width of the edge bevel on flat shapes \\u2014 the band that turns away from the viewer and catches the color\",ui:{type:[\"range\",\"map\"],min:.005,max:.3,step:.001,label:\"Bevel Width\",group:\"Surface\"}},bevelShape:{default:0,description:\"Bevel profile \\u2014 0 = one smooth round fillet, 1 = machined: a steep outer fillet, a chamfer plateau and an inner knee\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bevel Profile\",group:\"Surface\"}},...gr({edgeSoftness:{ui:{group:\"Surface\"}}}),shape:{default:kme,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=Lr(e,t,{scale:s.scale}),a=Dn(e,o,{bevelWidth:s.bevelWidth,bevelShape:s.bevelShape}),i=Ea(t,o),l=ni(a,i),c=z(ne(1,s.rimWidth),\"rimEdge\"),d=z(ot(ne(c,s.rimSoftness),I(c,s.rimSoftness),l),\"rim\"),u=ii(s.flowAngle,\"flow\").coordsOf(go(e,o)).along,p=I(I(v(u,v(s.flowScale,1/Rme)),v(l,zme)),v(r,.2)),_=z(Us(T(\"colorSpace\"))(DR(p),t).member(\"rgb\"),\"iri\"),f=z(Lo(i,a),\"R\"),h=z(v(Pc(f.member(\"x\"),f.member(\"y\"),{rotation:Er(s.envRotation,\"env\"),keyRadius:.3,drift:0,strength:s.gloss,skyGain:Dme}),Ap(l,{r0:.04,gain:.96,power:4})),\"shine\"),g=I(et(s.bodyColor.member(\"rgb\"),_,kt(v(d,s.iridescence))),v(et(_,kt(1),kt(.6)),kt(v(h,.5))));return Js(Dr(o.sdf,o.pxH),Ot(g,Jr(o,s.edgeSoftness)),xt,\"obsidian\")}})});var Z_=qU({corner:T(\"corner\"),amount:T(\"amount\"),radius:T(\"radius\")}),BI=H({name:\"PagePeel\",role:\"filter\",species:\"gather\",category:\"Transitions\",description:\"Curl the content up from a corner like a peeling page\",boundingBoxDeclaration:{aspectRatio:null},props:{corner:{default:\"bottom-right\",description:\"Which corner the page peels from\",compileTime:!0,ui:{type:\"select\",options:[{label:\"Top Left\",value:\"top-left\"},{label:\"Top Right\",value:\"top-right\"},{label:\"Bottom Left\",value:\"bottom-left\"},{label:\"Bottom Right\",value:\"bottom-right\"}],label:\"Corner\",group:\"Effect\"}},amount:{default:.2,description:\"How far the peel has progressed across the page (0 = flat, 1 = fully peeled)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Amount\",group:\"Effect\"}},radius:{default:.2,description:\"Tightness of the curl (fraction of the page diagonal)\",ui:{type:[\"range\",\"map\"],min:.02,max:.4,step:.01,label:\"Curl Radius\",group:\"Effect\"}},shading:{default:.55,description:\"How much the underside of the curl is shaded for depth\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shading\",group:\"Effect\"}},highlight:{default:.4,description:\"Strength of the specular sheen running along the curl\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlight\",group:\"Effect\"}},highlightSoftness:{default:.2,description:\"Width of the specular highlight band (low = tight gloss, high = broad satin)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlight Softness\",group:\"Effect\"}},shadow:{default:1,description:\"Strength of the contact shadow the curl casts on the page\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadow\",group:\"Effect\"}}},effect:$o(HU(Z_,{shade:VU(Z_,{shading:T(\"shading\")}),sheen:NU(Z_,{highlight:T(\"highlight\"),softness:T(\"highlightSoftness\")}),overhang:$U(Z_,{amount:T(\"amount\"),shadow:T(\"shadow\")}),reveal:XU(Z_,{amount:T(\"amount\"),shadow:T(\"shadow\")})}),[])});var zI=H({name:\"Paper\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Applies realistic paper grain and surface roughness to child content\",requiresRTT:!0,requiresChild:!0,props:{roughness:{default:.3,description:\"Surface roughness \\u2014 higher values create more pronounced brightness variation\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Roughness\",group:\"Texture\"}},grainScale:{default:1,description:\"Scale of the paper grain \\u2014 lower = coarser, higher = finer\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Grain Scale\",group:\"Texture\"}},displacement:{default:.15,description:\"Surface micro-roughness \\u2014 shifts pixels at grain scale like real paper fiber bumps\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Displacement\",group:\"Texture\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Texture\"}}},gpu:{fragment:e=>{let{childNode:t,ctx:s,uniforms:r,convertToTexture:o}=e;if(!t)return console.error(\"You must pass a child component into the Paper shader.\"),xt;let a=o(t),i=W(X4,\"paperSurface\",[s.uv,s.aspect,r.grainScale,r.seed,r.displacement,r.roughness]),l=W(Yt,\"unpremultiplyAlpha\",[a.sample(i.member(\"xy\"))]);return Ct(l.member(\"rgb\").mul(i.member(\"z\")),l.member(\"a\"))}}});var RI=H({role:\"shape\",name:\"Parallelogram\",description:\"Parallelogram with adjustable width, height and skew\",shape:{distance:({x:e,y:t},s)=>gR(e,t,s(\"width\"),s(\"height\"),s(\"skew\")),colorDescription:\"Fill color of the parallelogram\",centerDescription:\"Center position of the parallelogram\",bounds:{size:{width:\"width\",height:\"height\"}},shapeProps:{width:{default:.32,description:\"Half-width of the parallelogram\",ui:{type:\"range\",min:.02,max:1,step:.01,label:\"Width\",group:\"Shape\"}},height:{default:.22,description:\"Half-height of the parallelogram\",ui:{type:\"range\",min:.02,max:1,step:.01,label:\"Height\",group:\"Shape\"}},skew:{default:.15,description:\"Horizontal skew of the top edge\",ui:{type:\"range\",min:-.4,max:.4,step:.01,label:\"Skew\",group:\"Shape\"}}}}});var K2=256,ey=K2*K2,DI=4e4,Lme=12e3,Yn=vn({desktop:1024,mobile:768}),Jg=Yn*Yn,Ume=8,Ome=.75,LI=.002,UI=\"rgba16float\",Gme=2048,Fme=1.15,Ime=2.6,OI=1.1,Yme=26,Wme=4.2,qme=4,Vme=10,Nme=4,GI=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({rowX:S,rowY:S,rowZ:S,dt:n,time:n,snap:n,gridW:n,gridH:n,outW:n,outH:n,depth:n,dragMul:n,wobbleAmp:n,depthShading:n,spacing:n,particleSize:n,aspect:n,zoom:n,transX:n,transY:n,pointerX:n,pointerY:n,cursorForce:n,cursorZForce:n,cursorRadSq:n}),\"SimParams\"),ty=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({pos:{storage:Fe(S,ey),access:\"mutable\"},vel:{storage:Fe(S,ey),access:\"mutable\"},col:{storage:Fe(S,ey),access:\"mutable\"},accumR:{storage:Fe(lo(M),Jg),access:\"mutable\"},accumG:{storage:Fe(lo(M),Jg),access:\"mutable\"},accumB:{storage:Fe(lo(M),Jg),access:\"mutable\"},accumW:{storage:Fe(lo(M),Jg),access:\"mutable\"},params:{uniform:GI},src:{texture:Zt(n)},outTex:{storageTexture:zt(UI,\"write-only\")}}),\"fieldLayout\"),$me={luminance:0,luminanceInverted:1,red:2,green:3,blue:4,saturation:5,alpha:6};function Xme(e){return On.relief(ty,{channel:x2.byMode[e]??x2.luminance,cursor:Za.cursorInView(ty,{perspK:OI}),stiffness:Yme,maxSpeed:qme,minAlpha:LI,name:\"particleFieldSim\"})}function Q2(e,t){return Gn.relief(ty,{shape:e,splatRCap:Ume,aaW:Ome,minAlpha:LI,fp:Gme,wobbleFreq:Fme,perspK:OI,out:t,weightedColor:{alphaK:Ime},names:{splat:\"particleFieldSplat\",resolve:\"particleFieldResolve\"}})}var Hme=e=>Q2(e,[Yn,Yn]).splat.kernel,Y2e=Hme(\"dot\"),W2e=Q2(\"dot\",[Yn,Yn]).resolve.kernel,FI=H({name:\"ParticleField\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Explodes the child content into a breathing 3D field of particles \\u2014 bright areas float toward you and dark areas recede, the whole relief can be orbited with the camera rotations, and the cursor physically throws particles that spring back home\",requiresRTT:!0,requiresChild:!0,usesPointer:!0,props:{count:{default:15e3,description:\"Number of particles \\u2014 how finely the child is sampled into the field\",ui:{type:\"range\",min:1e3,max:DI,step:500,label:\"Count\",group:\"Field\"}},depthSource:{default:\"luminance\",compileTime:!0,description:\"Which channel of the child drives each particle's depth toward or away from the camera\",ui:{type:\"select\",options:[{value:\"luminance\",label:\"Luminance\"},{value:\"luminanceInverted\",label:\"Luminance (Inverted)\"},{value:\"red\",label:\"Red\"},{value:\"green\",label:\"Green\"},{value:\"blue\",label:\"Blue\"},{value:\"saturation\",label:\"Saturation\"},{value:\"alpha\",label:\"Alpha\"}],label:\"Depth Source\",group:\"Field\"}},depth:{default:.7,description:\"Depth of the relief \\u2014 how far bright and dark areas rise toward and sink away from the camera\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Depth\",group:\"Field\"}},particleShape:{default:\"dot\",compileTime:!0,description:\"What each particle is drawn as \\u2014 a crisp dot or square, or a soft glow puff\",ui:{type:\"select\",options:cp,label:\"Shape\",group:\"Look\"}},particleSize:{default:.75,description:\"Size of each particle relative to the grid spacing\",ui:{type:[\"range\",\"map\"],min:.3,max:3,step:.01,label:\"Particle Size\",group:\"Look\"}},depthShading:{default:.6,description:\"How much far particles dim into the distance \\u2014 the main cue that sells the 3D relief\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Depth Shading\",group:\"Look\"}},wobble:{default:.35,description:\"Gentle idle drift that keeps the field breathing even on a still image\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Wobble\",group:\"Motion\"}},zoom:{default:1,description:\"Camera distance \\u2014 dolly the whole field closer or further away\",ui:{type:[\"range\",\"map\"],min:.3,max:2.5,step:.01,label:\"Zoom\",group:\"Camera\"}},rotationX:{default:0,description:\"Camera orbit around the horizontal axis \\u2014 tilt the relief toward or away from you\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Rotate X\",group:\"Camera\"}},rotationY:{default:0,description:\"Camera orbit around the vertical axis \\u2014 view the particle extrusion from the side\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Rotate Y\",group:\"Camera\"}},rotationZ:{default:0,description:\"Camera roll around the view axis\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Rotate Z\",group:\"Camera\"}},offsetX:{default:0,description:\"Shift the whole field horizontally across the frame (in screen widths)\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Offset X\",group:\"Camera\"}},offsetY:{default:0,description:\"Shift the whole field vertically across the frame (in screen heights) \\u2014 tilt it flat, then sink it toward the bottom like a ground plane\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Offset Y\",group:\"Camera\"}},cursorMode:{default:\"push\",description:\"How the cursor disturbs the field \\u2014 push throws particles away and toward you, pull gathers them in\",ui:{type:\"select\",options:[{value:\"none\",label:\"None\"},{value:\"push\",label:\"Push\"},{value:\"pull\",label:\"Pull\"}],label:\"Cursor Mode\",group:\"Interaction\"}},cursorStrength:{default:.8,description:\"Strength of the cursor force \\u2014 how hard particles get thrown before springing back\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Cursor Strength\",group:\"Interaction\"}},cursorRadius:{default:.2,description:\"Reach of the cursor field, in screen units\",ui:{type:\"range\",min:.05,max:1,step:.01,label:\"Cursor Radius\",group:\"Interaction\"}}},...Fn({layout:ty,params:GI,maxAgents:ey,countCap:{desktop:DI,mobile:Lme},externalKeys:[\"src\"],childTexture:{externalKey:\"src\"},output:{key:\"outTex\",name:\"field\",size:[Yn,Yn],format:UI},bake:e=>{let{getCpuValue:t,dimensions:s}=e,r=s.height>0?s.width/s.height:1,o=Yn,a=Yn;r>=1?a=Math.max(Math.round(Yn/r),1):o=Math.max(Math.round(Yn*r),1);let i=$me[t(\"depthSource\")||\"luminance\"]??0,l=Q2(t(\"particleShape\")||\"dot\",[o,a]);return{pipelines:{sim:{kernel:Xme(i),threads:\"grid\"},splat:l.splat,resolve:l.resolve},program:[\"sim\",\"splat\",\"resolve\"],outputSize:[o,a],setup:{outW:o,outH:a,aspect0:r}}},frame:(e,{getCpuValue:t},s)=>{let{outW:r,outH:o,aspect0:a}=s,i=Li(t),l=0,c=0,d=bt;return u=>{let p=Di(u,a),_=p.dt;l+=_;let f=p.aspect,h=e.resolveCount(i(\"count\",15e3),500),{w:g,h:y}=aO(h,f,8,K2),b=t(\"cursorMode\")||\"push\",x=b===\"pull\"?-1:1,P=b===\"none\"?0:i(\"cursorStrength\",.5),C=i(\"cursorRadius\",.22),E=nO(i(\"rotationX\",0)*d,i(\"rotationY\",0)*d,i(\"rotationZ\",0)*d);return e.writeParams({rowX:S(E.rowX[0],E.rowX[1],E.rowX[2],0),rowY:S(E.rowY[0],E.rowY[1],E.rowY[2],0),rowZ:S(E.rowZ[0],E.rowZ[1],E.rowZ[2],0),dt:_,time:l,snap:c===0?1:0,gridW:g,gridH:y,outW:r,outH:o,depth:i(\"depth\",.7),dragMul:Sp(Wme,_),wobbleAmp:i(\"wobble\",.35),depthShading:Math.min(Math.max(i(\"depthShading\",.6),0),1),spacing:Math.min(r/g,o/y),particleSize:i(\"particleSize\",1.3),aspect:f,zoom:Math.min(Math.max(i(\"zoom\",1),.05),10),transX:i(\"offsetX\",0),transY:i(\"offsetY\",0),pointerX:p.pointerX,pointerY:p.pointerY,cursorForce:x*P*Vme,cursorZForce:x*P*Nme,cursorRadSq:C*C}),c++,e.frame({count:h,grid:[g,y]})}},fragment:{output:\"field\",fallback:\"child\"}})});var ka=256,Rc=ka*ka,jme=vn({desktop:10,mobile:6}),qI=\"rgba16float\",kl=vn({desktop:1024,mobile:512}),VI=\"rgba16float\",sy=16384,Kme=6e3,Qme=14,II=.16,Zme=16,YI=.16*ka,WI=4,Jme=.05,e_e=26,t_e=2.4,s_e=.09,r_e=6,o_e=.35,a_e=1.8,n_e=3,NI=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,curlStrength:n,velFade:n,ambient:n,ambientTime:n,ambientFreq:n}),\"FlowParams\"),$I=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({posX:n,posY:n,velX:n,velY:n,radius:n}),\"SplatParams\"),XI=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({colA:S,colB:S,dt:n,aspect:n,trails:n,bodyR:n,speedNorm:n,advect:n}),\"SimParams\"),Z2=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,Rc),access:\"mutable\"},velB:{storage:Fe(S,Rc),access:\"mutable\"},pressure:{storage:Fe(n,Rc),access:\"mutable\"},divergence:{storage:Fe(n,Rc),access:\"mutable\"},params:{uniform:NI},sparams:{uniform:$I},velOutTex:{storageTexture:zt(qI,\"write-only\")}}),\"fluidLayout\"),ry=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({agents:{storage:Fe(S,sy),access:\"mutable\"},accumE:{storage:Fe(lo(M),kl*kl),access:\"mutable\"},accumS:{storage:Fe(lo(M),kl*kl),access:\"mutable\"},trailBuf:{storage:Fe(S,kl*kl),access:\"mutable\"},velTex:{texture:Zt(n)},params:{uniform:XI},outTex:{storageTexture:zt(VI,\"write-only\")}}),\"pfLayout\"),i_e=Tz(Z2,{n:ka,namePrefix:\"particleFlow\"}),J2=zn(Z2,{n:ka,namePrefix:\"particleFlow\",boundary:\"clamped\",dye:\"none\",publishVelocityTexture:!0,ambientWind:{gain:e_e}}),{curl:$2e,divergence:X2e,jacobi:H2e,gradSubtract:j2e,advectVel:K2e,copyVel:Q2e}=J2,l_e=J2.vorticity,c_e=eg(ry,\"particleFlowInit\"),d_e=On.advect2d(ry,{gridN:ka,inertiaRate:r_e,homeRate:a_e,name:\"particleFlowIntegrate\"});function e5(e,t,s){return Gn.orientedWorld(ry,{shape:e,res:kl,splatRCap:Qme,heading:\"velocity\",agitation:\"speed\",comet:!0,ramp:{colorSpace:t,trails:{baked:s}},names:{splat:\"particleFlowSplat\",resolve:\"particleFlowResolve\"}})}var u_e=e=>e5(e,2,!1).splat.kernel,p_e=(e,t)=>e5(\"streak\",e,t).resolve.kernel,Z2e=u_e(\"streak\"),J2e=p_e(2,!1),HI=H({name:\"ParticleFlow\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Thousands of drifting dust particles carried by a real incompressible fluid field the cursor stirs \\u2014 drag to plow a wake and the particles ride the eddies and vortices it leaves behind, while a gentle ambient breeze keeps the whole scene breathing on its own\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{colorA:{default:\"#8ec5ff\",transform:ce,description:\"Color of particles drifting slowly with the flow\",ui:{type:\"color\",label:\"Rest Color\",group:\"Colors\"}},colorB:{default:\"#ffd98e\",transform:ce,description:\"Color particles flash toward as they speed up in the fast jets and wakes\",ui:{type:\"color\",label:\"Excited Color\",group:\"Colors\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the rest\\u2192excited color ramp\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},shape:{default:\"streak\",compileTime:!0,description:\"What each particle is drawn as \\u2014 a streak or arrow that stretches along the flow, a plain dot, a square, or a soft glowing comet\",ui:{type:\"select\",options:lp,label:\"Shape\",group:\"Particles\"}},count:{default:6e3,description:\"Number of drifting particles\",ui:{type:\"range\",min:1e3,max:16e3,step:500,label:\"Count\",group:\"Particles\"}},size:{default:1.2,description:\"Size of each particle\",ui:{type:\"range\",min:.3,max:3,step:.05,label:\"Size\",group:\"Particles\"}},trails:{default:0,recompile:hn((e,t)=>e>0!=t>0),description:\"How long each particle's motion trail persists \\u2014 0 draws crisp dust, 1 leaves long flowing ribbons\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Trails\",group:\"Particles\"}},speed:{default:1,description:\"How strongly the fluid carries the particles \\u2014 higher makes the dust ride the flow faster\",ui:{type:\"range\",min:.2,max:3,step:.05,label:\"Flow Speed\",group:\"Particles\"}},force:{default:1,description:\"How hard the cursor's motion pushes the fluid \\u2014 higher plows faster, more violent wakes and jets\",ui:{type:\"range\",min:0,max:3,step:.05,label:\"Cursor Force\",group:\"Dynamics\"}},swirl:{default:25,description:\"Vorticity confinement \\u2014 swirl energy that spins the flow into persistent eddies and vortices the dust orbits\",ui:{type:\"range\",min:0,max:60,step:1,label:\"Swirl\",group:\"Dynamics\"}},momentum:{default:.6,description:\"How long the fluid keeps flowing after you stop dragging \\u2014 high momentum lets the eddies carry the dust on and on\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Momentum\",group:\"Dynamics\"}},ambient:{default:.15,description:\"A gentle, ever-evolving breeze that keeps the dust drifting even without the cursor \\u2014 set to 0 for a field that only moves when you stir it\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Ambient\",group:\"Dynamics\"}}},...Fn({layout:ry,params:XI,maxAgents:sy,countCap:{desktop:sy,mobile:Kme},output:{key:\"outTex\",name:\"flowTexture\",size:[kl,kl],format:VI},externalKeys:[\"velTex\"],bake:e=>{let{gpu:t,getCpuValue:s,onCleanup:r}=e,o=t.root,a=(globalThis.__TYPEGPU_AUTONAME__??(h=>h))(o.createTexture({size:[ka,ka],format:qI}).$usage(\"storage\",\"sampled\"),\"velTex\");r(()=>a.destroy());let i=(globalThis.__TYPEGPU_AUTONAME__??(h=>h))(o.createUniform(NI),\"paramsU\"),l=(globalThis.__TYPEGPU_AUTONAME__??(h=>h))(o.createUniform($I),\"splatU\"),c=o.createBindGroup(Z2,{velA:pr(o,S,Rc),velB:pr(o,S,Rc),pressure:pr(o,n,Rc),divergence:pr(o,n,Rc),params:i.buffer,sparams:l.buffer,velOutTex:a}),d=D_(o,i_e,{n:ka,bindGroup:c}),u=D_(o,l_e,{n:ka,bindGroup:c}),p=jA(o,J2,{n:ka,bindGroup:c}),_=s(\"trails\"),f=e5(s(\"shape\")||\"streak\",s(\"colorSpace\")??2,typeof _==\"number\"&&_>0);return{pipelines:{init:{kernel:c_e,threads:\"max\"},integrate:{kernel:d_e,threads:\"agents\"},splat:f.splat,resolve:f.resolve},program:[\"integrate\",\"splat\",\"resolve\"],bindNow:{velTex:a},setup:{force:d,vorticity:u,solver:p,paramsU:i,splatU:l}}},frame:(e,{getCpuValue:t},s)=>{let{force:r,vorticity:o,solver:a,paramsU:i,splatU:l}=s,c=Date.now(),d=0,u=!1,p=Sl(),_=lA({warmupFrames:n_e+1}),f=(h,g)=>{let y=t(h);return typeof y==\"number\"?y:g};return h=>{let g=h,y=Date.now(),b=Math.min(g.deltaTime??(y-c)/1e3,.033);if(c=y,b<.001)return null;let x=g.dimensions?.height??0,P=x>0?(g.dimensions?.width??0)/x:16/9,C=Math.max(P,.01),E=f(\"force\",1),R=f(\"swirl\",25),U=Math.min(Math.max(f(\"ambient\",.15),0),1),L=Math.min(Math.max(f(\"momentum\",.6),0),1),k=f(\"speed\",1),D=e.resolveCount(f(\"count\",6e3),100),O=Math.min(Math.max(f(\"size\",1.2),.3),3)*1.3/Ri,F=p.update(g.pointer,b),q=F.moving||U>.001;if(q&&_.markActive(),d+=b*s_e,u&&_.shouldSkip(2+L*13,q))return null;_.tickFrame(b);let Y=WI*Math.pow(Jme/WI,L);i.write({dt:b,curlStrength:R,velFade:Y,ambient:U,ambientTime:d,ambientFreq:t_e});let V=t(\"colorA\"),X=t(\"colorB\");e.writeParams({colA:S(V?.x??.56,V?.y??.77,V?.z??1,V?.w??1),colB:S(X?.x??1,X?.y??.85,X?.z??.56,X?.w??1),dt:b,aspect:C,trails:Math.min(Math.max(f(\"trails\",0),0),1)*.92,bodyR:O,speedNorm:o_e,advect:k});let Q=[];if(u||(u=!0,Q.push(()=>e.pipelines.init.dispatchThreads(sy))),F.moving){let te=F.velX*ka*E*II,J=F.velY*ka*E*II;cA(Q,{fromX:F.prevX,fromY:F.prevY,dx:F.dx,dy:F.dy,dragDist:F.dragDist,stepSize:Math.max(.004,YI/ka*.6),maxSteps:Zme,scale:ka,write:(oe,le)=>l.write({posX:oe,posY:le,velX:te,velY:J,radius:YI}),pass:r})}return Q.push(...a.solveSteps({jacobiIters:jme,vorticity:o})),Q.push(...e.frame({count:D})??[]),Q}},fragment:{output:\"flowTexture\",fallback:\"transparent\"}})});var{buildAnalyticSdfFn:m_e,createSdfDataTexture:__e,SVG_SDF_SIZE:f_e}=yc,{createAnalytic3dSdfSetup:v_e,createSvg3dSdfSetup:h_e,is3dShapeType:g_e,isSvg3dShapeType:t5,resolveShapeSubProp:y_e,SHAPE3D_DEFAULTS:b_e,SVG3D_DEFAULTS:jI,VOLUMETRIC_FIELD_FORMAT:KI}=kn,J_=bt,x_e=JSON.stringify({type:\"sphere3D\",radius:.35});function ZI(e){if(e&&typeof e==\"object\")return e;if(typeof e==\"string\")try{return JSON.parse(e)}catch{return{}}return{}}var ef=16e3,tf=32,A_e=tf*tf*tf,oy=1,Dc=vn({desktop:1024,mobile:768}),w_e=Dc/Ri,T_e=2.6,S_e=6,JI=3,e9=\"rgba16float\",t9=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({colA:S,colB:S,dt:n,time:n,spread:n,agitation:n,dragMul:n,gravX:n,gravY:n,halfDepth:n,cursorX:n,cursorY:n,cursorForce:n,cursorRadSq:n,saRadius:n,saSides:n,saRounding:n,saInnerRatio:n,saRotation:n,saHeight:n,saOffset:n,saAperture:n,centerX:n,centerYv:n,scale:n,rotC:n,rotS:n,aspect:n,size:n,exposure:n,softness:n,speedColorK:n,omegaX:n,omegaY:n,omegaZ:n,entrain:n,gridOffX:n,gridOffY:n,gridOffZ:n}),\"SimParams\"),li=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({pos:{storage:Fe(S,ef),access:\"mutable\"},vel:{storage:Fe(S,ef),access:\"mutable\"},dens:{storage:Fe(lo(M),A_e),access:\"mutable\"},accumE:{storage:Fe(lo(M),Dc*Dc),access:\"mutable\"},accumS:{storage:Fe(lo(M),Dc*Dc),access:\"mutable\"},params:{uniform:t9},outTex:{storageTexture:zt(e9,\"write-only\")}}),\"simLayout\"),QI=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({sdfSource:{texture:Zt(n)}}),\"svgSdfLayout\"),P_e=uz(li,\"particlesInit\"),zp=Za.pressure(li,{gridDim:tf,domain:oy,names:{clear:\"particlesClearDensity\",splat:\"particlesDensity\"}}),r5e=zp.clearKernel,o5e=zp.splatKernel;function C_e(e){return On.forces3d(li,{forces:[zp.force,Za.containment(li,{field:e,gradEps:.02,wall:{featherFrom:-.1,featherTo:.01,base:1.1,springK:22},recall:{from:oy*.85,to:oy*1.1,k:9},homing:{from:.12,to:.45,k:5},entrainment:{featherHalf:.05}}),Za.cursorXY(li),Za.gravity(li),Za.turbulence(li,{posScale:193,timeX:31.7,timeY:27.3,seedScale:997,gain:5})],maxSpeed:JI,posClamp:1.9,name:\"particlesUpdate\"})}function s9(e,t){return Gn.volume(li,{shape:e,outRes:Dc,maxSplatSize:S_e,extQ:T_e,ramp:{colorSpace:t,exposure:!0,trails:\"none\"},names:{splat:\"particlesSplat\",glow:\"particlesGlowProfile\",profile:\"particlesProfile\",resolve:\"particlesResolve\"},extraOnSplat:!0})}var M_e=e=>s9(e,0).splat.kernel;var a5e=M_e(\"dot\");function E_e(e,t,s){let{gpu:r,getCpuValue:o,onCleanup:a}=e,i=r.root;if(t&&t5(s)){let c=h_e(e,t,()=>o(\"shape\")),d=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(i.createTexture({size:[1,1],format:KI}).$usage(\"storage\"),\"dummyField\");a(()=>d.destroy());let u=i.createBindGroup(c.layout,{field:d,params:c.marchParamsBuffer.buffer,sdfSource:c.sdfSourceTexture});return{evalSdf:X_.svgLifted3d(c.layout,c.sdfFn),extraBindGroup:u,setup3d:c}}if(t){let c=__e(e,t),d=i.createBindGroup(QI,{sdfSource:c.texture.texture});return{evalSdf:X_.svgExtruded(li,QI,{size:f_e}),extraBindGroup:d,setup3d:null}}if(g_e(s)){let c=v_e(i,s,ZI(o(\"shape\")),()=>o(\"shape\")),d=(globalThis.__TYPEGPU_AUTONAME__??(p=>p))(i.createTexture({size:[1,1],format:KI}).$usage(\"storage\"),\"dummyField\");a(()=>d.destroy());let u=i.createBindGroup(c.layout,{field:d,params:c.marchParamsBuffer.buffer});return{evalSdf:X_.analytic3d(c.layout,c.sdfFn),extraBindGroup:u,setup3d:c}}let l=m_e(s);return{evalSdf:X_.analyticExtruded(li,l),extraBindGroup:null,setup3d:null}}var r9=H({name:\"Particles\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"A swarm of simulated particles that settles into the shape, filling it evenly \\u2014 flat, SVG or true 3D volumes \\u2014 scattering from the cursor (or chasing it), tumbling when the shape moves, and always drifting back home\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},colorA:{default:\"#8ec5ff\",transform:ce,description:\"Color of particles at rest\",ui:{type:\"color\",label:\"Rest Color\",group:\"Colors\"}},colorB:{default:\"#ff7ad9\",transform:ce,description:\"Color particles shift toward when agitated \\u2014 scattering from the cursor or catching up to a moving shape\",ui:{type:\"color\",label:\"Excited Color\",group:\"Colors\"}},count:{default:4e3,description:\"Number of simulated particles\",ui:{type:\"range\",min:1e3,max:ef,step:1e3,label:\"Count\",group:\"Particles\"}},size:{default:1.5,description:\"Base particle size (each particle also varies slightly, and grows as it drifts toward the viewer)\",ui:{type:\"range\",min:.6,max:6,step:.1,label:\"Size\",group:\"Particles\"}},particleShape:{default:\"dot\",compileTime:!0,description:\"What each particle is drawn as \\u2014 a crisp dot or square (softness still feathers them), or a soft glow puff\",ui:{type:\"select\",options:cp,label:\"Shape\",group:\"Particles\"}},spread:{default:1,description:\"The pressure pushing particles apart \\u2014 how strongly they insist on even spacing inside the shape\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Spread\",group:\"Physics\"}},agitation:{default:.12,description:\"Idle thermal motion of the swarm \\u2014 0 freezes it crystal-still once settled\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Agitation\",group:\"Physics\"}},damping:{default:.4,description:\"How quickly disturbed particles calm back down and settle into place\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Damping\",group:\"Physics\"}},gravity:{default:0,description:\"Downward pull on the swarm \\u2014 negative floats the particles upward\",ui:{type:\"range\",min:-2,max:2,step:.01,label:\"Gravity\",group:\"Physics\"}},mouseInfluence:{default:2,description:\"Strength of the cursor field. Positive scatters particles away; negative pulls the swarm toward the cursor\",ui:{type:\"range\",min:-5,max:5,step:.01,label:\"Cursor Force\",group:\"Interaction\"}},mouseRadius:{default:.2,description:\"Reach of the cursor field, in shape-local units\",ui:{type:\"range\",min:.05,max:.8,step:.01,label:\"Cursor Radius\",group:\"Interaction\"}},exposure:{default:1,description:\"Brightness of the additive particle glow\",ui:{type:\"range\",min:.2,max:3,step:.01,label:\"Exposure\",group:\"Particles\"}},softness:{default:.1,description:\"Edge softness of each particle \\u2014 0 is a crisp disc, 1 a soft glow puff\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Softness\",group:\"Particles\"}},depth:{default:.18,description:\"Thickness of the particle volume behind flat shapes (3D shapes use their own true depth)\",ui:{type:\"range\",min:.02,max:.6,step:.01,label:\"Depth\",group:\"Particles\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the rest\\u2192excited color ramp\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},shape:{default:x_e,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Fn({layout:li,params:t9,maxAgents:ef,countCap:{desktop:ef,mobile:6e3},output:{key:\"outTex\",name:\"particleTexture\",size:[Dc,Dc],format:e9},bake:e=>{let{getCpuValue:t}=e,s=t(\"shapeSdfUrl\")||\"\",r=bc(t(\"shapeType\")||\"\",t(\"shape\")),o=E_e(e,s,r),a=s9(t(\"particleShape\")||\"dot\",t(\"colorSpace\")??0);return{pipelines:{init:{kernel:P_e,threads:\"max\",extra:!0},clearDensity:{kernel:zp.clearKernel,threads:\"fixed\",size:[zp.cells]},density:{kernel:zp.splatKernel,threads:\"agents\",extra:!0},update:{kernel:C_e(o.evalSdf),threads:\"agents\",extra:!0},splat:a.splat,resolve:a.resolve},initStep:\"init\",program:[\"clearDensity\",\"density\",\"update\",\"splat\",\"resolve\"],extraBindGroup:o.extraBindGroup,setup:{shapeField:o,shapeSdfUrl:s,shapeType:r}}},frame:(e,{getCpuValue:t},s)=>{let{shapeField:r,shapeSdfUrl:o,shapeType:a}=s,i=r.setup3d,l=0,c=new Map,d=(g,y,b,x)=>y_e(g,y,b,x),u=0,p=0,_=null,f=2*oy/tf,h=Li(t);return g=>{let{dt:y,aspect:b,pointerX:x,pointerY:P}=Di(g,1);l+=y,u+=y;let C={elapsed:l,deltaTime:y,pointerX:x,pointerY:P,springs:c},E=t(\"center\"),R=E?.x??.5,U=1-(E?.y??.5),L=Math.max(h(\"scale\",1),.01),k=h(\"rotation\",0)*J_,D=Math.cos(k),O=Math.sin(k),F=tO({pointerX:x,pointerY:P,centerX:R,centerYv:U,scale:L,rotC:D,rotS:O,aspect:b}),q=h(\"gravity\",0)*1.2,Y=O*q,V=-(D*q),X=ZI(t(\"shape\")),Q=t5(a),te=o&&Q?d(X.depth,jI.depth??.25,C,\"depth\")*.5:Math.max(h(\"depth\",.18),.01)*.5,J=d(X.rotation,0,C,\"shapeRotation\"),oe={x:0,y:0,z:0};if(i){let Ie=t5(a)?jI:b_e[a]??{},ke={x:d(X.rotX,Ie.rotX??0,C,\"rotX\")*J_,y:d(X.rotY,Ie.rotY??0,C,\"rotY\")*J_,z:d(X.rotZ,Ie.rotZ??0,C,\"rotZ\")*J_};oe=T2(_,ke,y)??oe,_=ke}else if(!o){let Ie={x:0,y:0,z:J*J_};oe=T2(_,Ie,y)??oe,_=Ie}let{omegaX:le,omegaY:se,omegaZ:Te,entrain:de}=sO(oe,{cap:10,gainRate:2.5,gainMax:5}),xe=h(\"damping\",.4),Ae=h(\"mouseRadius\",.22),De=t(\"colorA\"),Ee=t(\"colorB\"),ze=iO(p,f);return e.writeParams({colA:S(De?.x??1,De?.y??1,De?.z??1,De?.w??1),colB:S(Ee?.x??1,Ee?.y??1,Ee?.z??1,Ee?.w??1),dt:y,time:u,spread:h(\"spread\",1),agitation:h(\"agitation\",.12),dragMul:Sp(2.2+xe*6,y),gravX:Y,gravY:V,halfDepth:te,cursorX:F.x,cursorY:F.y,cursorForce:h(\"mouseInfluence\",1.2)*3,cursorRadSq:Ae*Ae,saRadius:d(X.radius??X.width??X.bottomWidth,.35,C,\"radius\"),saSides:d(X.sides,6,C,\"sides\"),saRounding:d(X.rounding,0,C,\"rounding\"),saInnerRatio:d(X.innerRatio??X.thickness??X.spread??X.topWidth??X.topRatio,.4,C,\"innerRatio\"),saRotation:J,saHeight:d(X.height,.25,C,\"height\"),saOffset:d(X.offset??X.skew,.2,C,\"offset\"),saAperture:d(X.aperture,270,C,\"aperture\"),centerX:R,centerYv:U,scale:L,rotC:D,rotS:O,aspect:b,size:h(\"size\",2.2)*w_e,exposure:h(\"exposure\",1),softness:Math.min(Math.max(h(\"softness\",.5),0),1),speedColorK:2/JI,omegaX:le,omegaY:se,omegaZ:Te,entrain:de,gridOffX:ze.x,gridOffY:ze.y,gridOffZ:ze.z}),p++,i?.update({deltaTime:y,pointer:{x,y:P}}),e.frame({count:e.resolveCount(h(\"count\",4e3))})}},fragment:{output:\"particleTexture\",fallback:\"transparent\"}})});var o9=H({name:\"PerlinNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Smooth gradient noise that morphs over time\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:2,description:\"Pattern scale (higher = finer, more detailed patterns; each +1 roughly doubles the frequency)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},...Ja(),...In()},paint:Vs(ua(Qa(hp(Tc(\"perlin\"),{rate:.3}),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var a9=H({name:\"Perspective\",role:\"warp\",category:\"Distortions\",description:\"Rotate the plane in 3D space with pan and tilt\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"Center point of rotation\"),pan:{default:0,description:\"Horizontal rotation (left/right)\",ui:{type:[\"range\",\"map\"],min:-90,max:90,step:.1,label:\"Pan\",group:\"Effect\"}},tilt:{default:0,description:\"Vertical rotation (up/down)\",ui:{type:[\"range\",\"map\"],min:-90,max:90,step:.1,label:\"Tilt\",group:\"Effect\"}},fov:{default:60,description:\"Field of view - controls perspective intensity\",ui:{type:[\"range\",\"map\"],min:30,max:120,step:1,label:\"FOV\",group:\"Effect\"}},zoom:{default:1,description:\"Zoom in to fill the frame after rotation\",ui:{type:[\"range\",\"map\"],min:.5,max:3,step:.1,label:\"Zoom\",group:\"Effect\"}},offset:{default:{x:.5,y:.5},transform:Xe,description:\"Shift the result in X/Y\",ui:{type:\"position\",label:\"Offset\",group:\"Position\"}},edges:fr(\"transparent\",\"How to handle edges\")},map:tU({center:T(\"center\"),pan:T(\"pan\"),tilt:T(\"tilt\"),fov:T(\"fov\"),zoom:T(\"zoom\"),offset:T(\"offset\")})});var n9=H({name:\"Pixelate\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Pixelation effect with adjustable cell size\",props:{scale:{default:50,description:\"Number of pixels along the longest edge (higher = smaller pixels)\",ui:{type:[\"range\",\"map\"],min:1,max:200,step:1,label:\"Scale\",group:\"Effect\"}},gap:{default:0,description:\"Space between pixels as a fraction of cell size (0 = no gap, 1 = fully invisible)\",ui:{type:[\"range\",\"map\"],min:0,max:.95,step:.01,label:\"Gap\",group:\"Effect\"}},roundness:{default:0,description:\"Roundness of each pixel's corners (0 = square, 1 = circle)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Roundness\",group:\"Effect\"}}},effect:AU({scale:T(\"scale\"),gap:T(\"gap\"),roundness:T(\"roundness\")})});var Yd=512,s5=Yd*Yd,i9=\"rgba16float\",k_e=(e,t)=>Gz({n:Yd,format:i9,namePrefix:\"pixelSort\",vertical:e,direction:t}),l9=H({name:\"PixelSort\",role:\"simulation\",species:\"custom\",category:\"Interactive\",description:\"Pixels sort by brightness around the cursor and keep their sorted position, optionally decaying back over time\",requiresRTT:!0,requiresChild:!0,boundingBoxDeclaration:{aspectRatio:null},usesPointer:!0,props:{radius:{default:.4,description:\"Size of the cursor brush that sorts pixels\",ui:{type:[\"range\",\"map\"],min:.03,max:.6,step:.01,label:\"Radius\",group:\"Effect\"}},falloff:{default:1,description:\"Softness of the brush edge (0 = hard circle, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Effect\"}},strength:{default:.1,description:\"How fast pixels sort \\u2014 runs more sorting passes per frame\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},decay:{default:.1,description:\"How quickly sorted pixels melt back to their original position (0 = permanent)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Decay\",group:\"Effect\"}},axis:{default:\"vertical\",compileTime:!0,description:\"Axis pixels are sorted along\",ui:{type:\"select\",options:[{label:\"Horizontal\",value:\"horizontal\"},{label:\"Vertical\",value:\"vertical\"}],label:\"Axis\",group:\"Effect\"}},direction:{default:\"descending\",compileTime:!0,description:\"Sort order by brightness\",ui:{type:\"select\",options:[{label:\"Dark \\u2192 Light\",value:\"ascending\"},{label:\"Light \\u2192 Dark\",value:\"descending\"}],label:\"Direction\",group:\"Effect\"}}},...Ec((e,t)=>{let{childNode:s,convertToTexture:r,registerComputeTexture:o,propValues:a,onCleanup:i}=e;if(!s)return null;let l=a.axis===\"vertical\",c=a.direction===\"descending\"?-1:1,d=r(s),u=pr(t,n,s5),p=pr(t,n,s5),_=pr(t,n,s5),f=t.createTexture({size:[Yd,Yd],format:i9}).$usage(\"storage\",\"sampled\");i(()=>f.destroy());let h=o(f),g=k_e(l,c),y=t.createUniform(g.LumaParams),b=t.createUniform(g.SwapParams),x=Eg(e),P=[Yd,Yd],C=ai(t,g.key,{size:P}),E=!1,R=t.createBindGroup(g.swapLayout,{readBuf:u,writeBuf:p,lumaBuf:_,params:b.buffer}),U=t.createBindGroup(g.swapLayout,{readBuf:p,writeBuf:u,lumaBuf:_,params:b.buffer}),L=ai(t,g.swap0,{size:P}),k=ai(t,g.swap1,{size:P}),D=t.createBindGroup(g.outputLayout,{srcBuf:u,stateTex:f}),O=t.createBindGroup(g.outputLayout,{srcBuf:p,stateTex:f}),F=ai(t,g.output,{size:P}),q=0,Y=1,V=Ir.sortPass({passes:()=>Y,pass:(X,Q)=>(X?k:L).with(Q===\"A\"?R:U)});return{outputs:{state:h,childTexture:d},bindInputs:X=>{let Q=X(d.key);if(Q){let te=t.createBindGroup(g.lumaLayout,{input:Q.texture,lumaBuf:_,params:y.buffer});C=C.with(te),E=!0}},clampDt:.05,stages:[Ir.readyWhen(()=>E),Ir.values(\"brush+decay\",X=>{let Q=X.frameParams,te=x.safe(Q),J=x.tracked(),oe=X.num(\"strength\",.1),le=X.num(\"decay\",.1);Y=1+Math.round(oe*4),b.write({mouseX:Q.pointer?.x??.5,mouseY:Q.pointer?.y??.5,radius:X.num(\"radius\",.4),falloff:X.num(\"falloff\",1),decay:le*X.dt*2/Y,aspect:te.width/te.height,seed:q%1024}),y.write({inputWidth:J.width,inputHeight:J.height})}),Ir.cache(()=>C),V,Ir.publish(()=>F.with(V.side()===\"A\"?D:O)),Ir.values(\"frameAdvance\",()=>{q++})]}}),gpu:{fragment:({childNode:e,ctx:t,computeOutputs:s,propValues:r,convertToTexture:o})=>{if(!e)return xt;let a=s?.state,i=s?.childTexture;if(!a||!i)return W(Yt,\"unpremultiplyAlpha\",[o(e).sample(t.uv)]);let l=r.axis===\"vertical\",c=a.sample(t.uv,\"nearestClamp\").member(\"r\"),d=l?rt(t.uv.member(\"x\"),c):rt(c,t.uv.member(\"y\"));return W(Yt,\"unpremultiplyAlpha\",[i.sample(d)])}}});var c9=e=>({luminance:0,darkness:1,red:2,green:3,blue:4})[e]??0,vr=128,ay=(e,t)=>typeof e==\"number\"?e:t,d9=(e,t,s)=>ne(e,v(t,s)),{Taps:y5e,setup:B_e}=w4(vr,{fnName:\"pixelThrowBicubicSetup\",structName:\"PixelThrowBicubicTaps\"});function z_e(e,t,s){let r=Qe(.299,.587,.114);return et(1,Ge(e===1?ne(1,$t(t,r)):e===2?t.member(\"r\"):e===3?t.member(\"g\"):e===4?t.member(\"b\"):$t(t,r),0,1),s)}var u9=H({name:\"PixelThrow\",role:\"simulation\",species:\"custom\",category:\"Interactive\",description:\"Throws pixels along the cursor's path like a fluid \\u2014 brighter (or redder/greener/bluer) pixels are flung farther, then settle back with friction\",requiresRTT:!0,requiresChild:!0,boundingBoxDeclaration:{aspectRatio:null},usesPointer:!0,props:{throwKey:{default:\"luminance\",transform:c9,compileTime:!0,description:\"Which pixel value decides how far a pixel is thrown\",ui:{type:\"select\",options:[{label:\"Brightness\",value:\"luminance\"},{label:\"Darkness\",value:\"darkness\"},{label:\"Red\",value:\"red\"},{label:\"Green\",value:\"green\"},{label:\"Blue\",value:\"blue\"}],label:\"Throw By\",group:\"Effect\"}},strength:{default:.25,description:\"Maximum distance pixels can be thrown\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},keyInfluence:{default:.8,description:\"How much the chosen value modulates throw distance (0 = all pixels thrown equally, 1 = only high-value pixels move)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Key Influence\",group:\"Effect\"}},radius:{default:.2,description:\"Size of the cursor's throw brush\",ui:{type:[\"range\",\"map\"],min:.02,max:.6,step:.01,label:\"Radius\",group:\"Effect\"}},friction:{default:.3,description:\"How quickly thrown pixels settle back to their origin (0 = float almost forever, 1 = snap back fast)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Friction\",group:\"Effect\"}},momentum:{default:.5,description:\"How much the thrown flow keeps drifting and swirling after the cursor passes (fluidity)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Momentum\",group:\"Effect\"}},edges:{default:\"stretch\",description:\"How to handle pixels thrown beyond the canvas edges\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},gpu:{fragment:e=>{let{uniforms:t,ctx:s,childNode:r,convertToTexture:o,onBeforeRender:a,dimensions:i,propValues:l,getCpuValue:c}=e;if(!r)return xt;let d=o(r),u=l.edges??0,p=l.throwKey,_=typeof p==\"number\"?p:c9(String(p??\"luminance\")),f=new Float32Array(vr*vr*2),h=new Float32Array(vr*vr*2),g=Bg(e,{size:vr,label:\"pixelthrow-flow\"}),y=g.texture,b=.5,x=.5,P=0,C=0,E=0,R=.125,U=(Y,V,X)=>{let Q=Math.floor(Y),te=Math.floor(V),J=Q+1,oe=te+1;if(Q<0||te<0||J>=vr||oe>=vr)return 0;let le=Y-Q,se=V-te,Te=(te*vr+Q)*2+X,de=(te*vr+J)*2+X,xe=(oe*vr+Q)*2+X,Ae=(oe*vr+J)*2+X;return f[Te]*(1-le)*(1-se)+f[de]*le*(1-se)+f[xe]*(1-le)*se+f[Ae]*le*se},L=()=>Math.max(1e-4,i.width/Math.max(1,i.height));a(kg({clampDt:.016,steps:[gn(\"dtGuard\",Y=>Y.dt<=0?\"skip\":void 0),gn(\"cursorVelocity\",Y=>{let V=(Y.pointer.x-b)/Y.dt,X=(Y.pointer.y-x)/Y.dt;P=P*.8+V*.2,C=C*.8+X*.2,E=Math.sqrt(P*P+C*C)}),gn(\"advect+decay\",Y=>{let V=ay(c(\"friction\"),.3),X=ay(c(\"momentum\"),.5);R=ay(c(\"strength\"),.25)*.5;let Q=Math.max(0,1-V*Y.dt*4),te=X*Y.dt*12;for(let J=0;J<vr;J++)for(let oe=0;oe<vr;oe++){let le=(J*vr+oe)*2,se=oe-f[le]*vr*te,Te=J-f[le+1]*vr*te;h[le]=U(se,Te,0)*Q,h[le+1]=U(se,Te,1)*Q}}),gn(\"inject(brush)\",Y=>{if(E<=.02)return;let V=L(),X=Math.max(.001,ay(c(\"radius\"),.2)),Q=X*X,te=Math.exp(-1),J=1/(1-te),oe=Math.max(0,Math.floor((Y.pointer.y-X)*vr)),le=Math.min(vr-1,Math.ceil((Y.pointer.y+X)*vr)),se=Math.max(0,Math.floor((Y.pointer.x-X)*vr)),Te=Math.min(vr-1,Math.ceil((Y.pointer.x+X)*vr));for(let de=oe;de<=le;de++)for(let xe=se;xe<=Te;xe++){let Ae=(xe+.5)/vr,De=(de+.5)/vr,Ee=V>=1?(Ae-Y.pointer.x)*V:Ae-Y.pointer.x,ze=V>=1?De-Y.pointer.y:(De-Y.pointer.y)/V,Ie=Ee*Ee+ze*ze;if(Ie>Q)continue;let ke=(Math.exp(-Ie/Q)-te)*J,Me=(de*vr+xe)*2;h[Me]+=P*ke*Y.dt*4,h[Me+1]+=C*ke*Y.dt*4}}),gn(\"saturate(tanh)\",()=>{for(let Y=0;Y<vr*vr;Y++){let V=h[Y*2],X=h[Y*2+1],Q=Math.sqrt(V*V+X*X);if(Q>1e-6){let te=R*Math.tanh(Q/R)/Q;h[Y*2]=V*te,h[Y*2+1]=X*te}}}),gn(\"publish(halfFloat)\",Y=>{f.set(h);for(let V=0;V<vr*vr;V++)g.texData[V*4]=_o(f[V*2]),g.texData[V*4+1]=_o(f[V*2+1]);g.upload(),b=Y.pointer.x,x=Y.pointer.y})]}));let k=s.uv,D=W(B_e,\"pixelThrowBicubicSetup\",[k]),O=D.member(\"w\"),F=z(y.sample(D.member(\"uvA\"),\"linearClamp\").member(\"xy\").mul(O.member(\"x\")).add(y.sample(D.member(\"uvB\"),\"linearClamp\").member(\"xy\").mul(O.member(\"y\"))).add(y.sample(D.member(\"uvC\"),\"linearClamp\").member(\"xy\").mul(O.member(\"z\"))).add(y.sample(D.member(\"uvD\"),\"linearClamp\").member(\"xy\").mul(O.member(\"w\"))),\"flowVec\"),q=d9(k,F,.5);return W(Yt,\"unpremultiplyAlpha\",[Ha(z(d9(k,F,z_e(_,W(Yt,\"unpremultiplyAlpha\",[d.sample(q)]).member(\"rgb\"),t.keyInfluence)),\"displacedUV\"),Y=>d.sample(Y),u)])}}});var p9=H({name:\"Plasma\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Animated effect of glowing plasma\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{density:{default:2,description:\"Density of the plasma pattern\",ui:{type:[\"range\",\"map\"],min:0,max:4,step:.1,label:\"Density\",group:\"Effect\"}},speed:{default:2,description:\"Animation speed\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Effect\"}},intensity:{default:1.5,description:\"Brightness and spread of the plasma glow\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.1,label:\"Intensity\",group:\"Colors\"}},warp:{default:.4,description:\"How much the flow distorts and swirls\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Warp\",group:\"Effect\"}},contrast:{default:1,description:\"Push darks darker and lights lighter\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.1,label:\"Contrast\",group:\"Colors\"}},balance:{default:50,description:\"Skew color balance toward A (higher) or B (lower)\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Balance\",group:\"Colors\"}},colorA:{default:\"#7018be\",description:\"Primary color\",transform:ce,ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#000000\",description:\"Secondary color\",transform:ce,ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(wR(PR(SR(Tc(\"mx3\"),{amount:T(\"warp\"),amountScale:4,timeScale:.125}),{scale:T(\"density\")}),{glow:T(\"intensity\"),contrast:T(\"contrast\"),balance:T(\"balance\"),invert:!0}),Us(T(\"colorSpace\")))});var R_e=JSON.stringify({type:\"sphere3D\",radius:.35}),Wd=(e,t,s,r,o)=>{let a=z(r,`${o}S`),i=z(e,`${o}X`);return v(ot(ne(t,a),I(t,a),i),ne(1,ot(ne(s,a),I(s,a),i)))},r5=(e,t,s,r)=>{let o=rt(I(v(e,s),r),I(v(t,s),v(r,.617))),a=rt(I(I(v(v(e,s),2.3),13.1),r),I(I(v(v(t,s),2.3),7.7),v(r,.617)));return I(ms(pa(o)),v(ms(pa(a)),.45))},m9=H({name:\"Plastic\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Glossy molded plastic with photorealistic studio reflections, driven in a custom shape\",animatedTime:{speed:\"speed\"},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s,propValues:r}=t,o=wt(t),a=e.volumetric,i=Lr(e,t,{scale:s.scale}),{sdf:l,pxH:c}=i,d=z(e.sdfUV,\"sdfUV\"),u=Er(s.gradientAngle,\"gDir\"),p=ot(0,1,Ge(I(Ce($t(ne(d.member(\"xy\"),rt(.5,.5)),u),.7),.5),0,1)),_=r.colorSpace??0,f=r.stopCount??0,h;f>1?h=En(p,{colorsArray:s.colorsArray,positionsArray:s.positionsArray,convertedColorsArray:s.convertedColorsArray,stopCount:s.stopCount},_):h=W(No[_]??Ar,\"mixColors\",[s.colorA,s.colorB,p]);let g=h.member(\"rgb\"),y=Er(I(s.lightAngle,v(o,6)),\"light\"),b=y.member(\"x\"),x=y.member(\"y\"),P=Ln(i),C=Jr(i,s.edgeSoftness),E=go(e,i,{uv:d}),R=E.member(\"x\"),U=E.member(\"y\"),L=it(v(s.thickness,.3),.01),k=z(Ge(Ce(v(l,-1),L),0,1),\"depthNorm\"),D;if(a)D=Mc(i,4,\"nBase\");else{let Kt=z(v(ho(it(ne(1,v(k,k)),0)),2.4),\"bevelSlope\");D=z(Os(Qe(v(P.member(\"x\"),Kt),v(P.member(\"y\"),Kt),-1)),\"nBase\")}let O=z(v(s.crumpleScale,4),\"cScale\"),F=v(s.crumple,.9),q=z(v(s.seed,7.31),\"seedOff\"),Y=.012,V=z(r5(R,U,O,q),\"cr0\"),X=Ce(ne(r5(I(R,Y),U,O,q),V),Y),Q=Ce(ne(r5(R,I(U,Y),O,q),V),Y),te=Ge(s.crumpleCoverage,0,1),J=I(v(co(I(I(v(R,2.6),q),31.7),I(I(v(U,2.6),v(q,.617)),17.3)),.5),.5),oe=z(ne(1.25,v(te,1.75)),\"covThreshold\"),le=z(v(v(F,ot(ne(oe,.25),I(oe,.25),J)),I(v(ot(0,.35,k),.85),.15)),\"crumpleW\"),se=Gi(D,v(v(X,le),.25),v(v(Q,le),.25)),Te=Fi(se),de=z(Lo(Qe(0,0,1),se),\"R\"),xe=z(Ge(s.roughness,0,1),\"rough\"),Ae=z(v(v(xe,co(v(R,140),v(U,140))),.18),\"rJit\"),De=z(I(I(v(de.member(\"x\"),b),v(de.member(\"y\"),x)),Ae),\"eu\"),Ee=z(I(I(v(de.member(\"x\"),v(x,-1)),v(de.member(\"y\"),b)),v(Ae,.6)),\"ev\"),ze=z(et(.02,.45,xe),\"soft\"),Ie=v(v(Wd(De,.18,.95,ze,\"win1\"),Wd(Ee,-.42,.42,ze,\"win2\")),ne(1,v(v(Wd(Ee,-.045,.045,v(ze,.6),\"mull\"),.8),ne(1,xe)))),ke=v(v(Wd(De,-.16,-.05,v(ze,.7),\"strip1\"),Wd(Ee,-.85,.85,ze,\"strip2\")),.85),Me=v(v(Wd(De,-.95,-.45,v(ze,1.6),\"fill1\"),Wd(Ee,-.6,.6,v(ze,1.6),\"fill2\")),.3),we=v(Ge(I(v(De,.5),.5),0,1),.12),Ve=v(I(I(I(Ie,ke),Me),we),ne(1,v(xe,.55))),qe=I(.3,v(ts(Te,3),.7)),st=v(s.reflectivity,qe),pt=Un(y,-.8),Ze=pt.member(\"L\"),nt=z(v(I(Ve,v(v(ts(Ge($t(se,pt.member(\"H\")),0,1),U_(et(9,4,xe))),1.6),ne(1,v(xe,.7)))),st),\"specular\"),ht=z(I(v(Ge($t(se,Ze),-1,1),.5),.5),\"lit\"),yt=et(ne(1,v(s.shading,.75)),I(1,v(s.shading,.45)),ht),St=et(.6,1,ot(0,1,Ge(Ce(v(l,-1),.025),0,1))),Mt=v(v(v(ts(Te,3.5),s.rim),I(v(ht,.6),.4)),1.6),Rt=z(I(I(v(v(g,yt),St),kt(nt)),v(s.rimColor.member(\"rgb\"),Mt)),\"plasticRgb\");return Js(Dr(l,c),Ot(Rt,C),xt,\"plastic\")}}),props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the plastic shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the plastic shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the plastic shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},colorA:{default:\"#f5f5f7\",transform:ce,description:\"Body color at the start of the gradient\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#d9dade\",transform:ce,description:\"Body color at the end of the gradient\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),gradientAngle:{default:90,description:\"Direction of the body color gradient in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Gradient Angle\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for gradient color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},thickness:{default:.5,description:\"Puffiness \\u2014 how far the rounded bevel reaches inward from the edge before the surface flattens\",ui:{type:\"range\",min:.05,max:1,step:.01,label:\"Puffiness\",group:\"Plastic\"}},roughness:{default:.12,description:\"Surface roughness \\u2014 0 = polished gloss with crisp mirror reflections, 1 = matte satin\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Roughness\",group:\"Plastic\"}},reflectivity:{default:1,description:\"Strength of the environment reflections and specular highlights\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Reflectivity\",group:\"Plastic\"}},crumple:{default:.25,description:\"Surface crumple \\u2014 irregular dents that break reflections into hard organic shapes, like blown or vacuum-formed plastic\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Crumple\",group:\"Plastic\"}},crumpleScale:{default:1,description:\"Size of the crumple dents \\u2014 higher = smaller, denser dents\",ui:{type:\"range\",min:.5,max:10,step:.1,label:\"Crumple Scale\",group:\"Plastic\"}},crumpleCoverage:{default:1,description:\"How much of the surface is crumpled \\u2014 0 = pristine, 0.5 = patches of crumple, 1 = fully crumpled\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Crumple Coverage\",group:\"Plastic\"}},seed:{default:0,description:\"Random seed \\u2014 re-rolls the crumple pattern for reflection variety\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Plastic\"}},edgeSoftness:{default:.05,description:\"Softness of the shape boundary edge\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Plastic\"}},lightAngle:{default:315,description:\"Direction the studio key light comes from, in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Lighting\"}},speed:{default:1,description:\"Speed of the environment drift \\u2014 the studio reflections slowly orbit the surface. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Animation\"}},shading:{default:.35,description:\"Diffuse shading contrast \\u2014 how strongly the body darkens away from the light\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Shading\",group:\"Lighting\"}},rim:{default:.25,description:\"Fresnel rim light intensity on grazing surfaces\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Rim Light\",group:\"Lighting\"}},rimColor:{default:\"#ffffff\",transform:ce,description:\"Color of the fresnel rim light\",ui:{type:\"color\",label:\"Rim Color\",group:\"Lighting\"}},shape:{default:R_e,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}}});var _9=H({name:\"PolarCoordinates\",role:\"warp\",category:\"Distortions\",description:\"Convert rectangular coordinates to polar space\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point for polar coordinate conversion\"),wrap:{default:1,description:\"Controls how much of the angular range to use (1 = full 360\\xB0, 0.5 = 180\\xB0)\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Wrap\",group:\"Effect\"}},radius:{default:1,description:\"Controls how much of the radius range to use (affects the radial mapping)\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Radius\",group:\"Effect\"}},intensity:{default:1,description:\"Blends between original UVs (0) and polar coordinates (1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Intensity\",group:\"Effect\"}},edges:fr(\"transparent\",\"How to handle edges when distortion pushes content out of bounds\")},map:ZL({center:T(\"center\"),wrap:T(\"wrap\"),radius:T(\"radius\"),intensity:T(\"intensity\")}),missingChildMessage:\"You must pass a child component into the PolarCoordinates shader.\"});var f9=H({role:\"shape\",name:\"Polygon\",description:\"Regular polygon with adjustable sides and corner rounding\",shape:{distance:({x:e,y:t},s)=>et(lR(e,t,s(\"radius\"),s(\"sides\")),_p(e,t,s(\"radius\")),s(\"rounding\")),colorDescription:\"Fill color of the polygon\",centerDescription:\"Center position of the polygon\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.4,description:\"Inradius \\u2014 distance from the center to the middle of each side, in UV space (the vertices sit a little farther out)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Radius\",group:\"Shape\"}},sides:{default:6,description:\"Number of sides (3 = triangle, 4 = square, 6 = hexagon, etc.)\",ui:{type:\"range\",min:3,max:12,step:1,label:\"Sides\",group:\"Shape\"}},rounding:{default:0,description:\"Corner rounding \\u2014 0 is sharp vertices, 1 morphs into a circle\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Rounding\",group:\"Shape\"}}}}});var v9=H({name:\"Posterize\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Reduce color depth to create a poster effect\",props:{intensity:{default:5,description:\"The intensity of the posterization effect (lower is more posterized)\",ui:{type:[\"range\",\"map\"],min:2,max:20,step:1,label:\"Intensity\",group:\"Effect\"}}},effect:c8(T(\"intensity\")),missingChildMessage:\"You must pass a child component into the Posterize shader.\"});var h9=H({name:\"Prism\",role:\"generator\",category:\"Textures\",description:\"A beam of light that fans out and splits into a slowly-rotating rainbow past a controllable point. Transparent background \\u2014 composite over a dark layer.\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{position:{default:{x:.18,y:.18},transform:Xe,description:\"Where the beam originates\",ui:{type:\"position\",label:\"Source\",group:\"Beam\"}},beamWidth:{default:.04,description:\"Thickness of the white beam\",ui:{type:[\"range\",\"map\"],min:.002,max:.3,step:.002,label:\"Beam Width\",group:\"Beam\"}},intensity:{default:1.6,description:\"Brightness (above 1 blows the core to white)\",ui:{type:[\"range\",\"map\"],min:0,max:4,step:.01,label:\"Intensity\",group:\"Beam\"}},beamColor:{default:\"#ffffff\",transform:ce,description:\"color of the beam before it splits\",ui:{type:\"color\",label:\"Beam Color\",group:\"Beam\"}},startFalloff:{default:.15,description:\"How softly the beam fades in at its source\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Start Falloff\",group:\"Beam\"}},endFalloff:{default:.6,description:\"How quickly the rainbow fades out with distance\",ui:{type:[\"range\",\"map\"],min:.02,max:2,step:.01,label:\"End Falloff\",group:\"Beam\"}},splitPosition:{default:{x:.5,y:.42},transform:Xe,description:\"Where the beam starts to fan out and split (projected onto the beam axis)\",ui:{type:\"position\",label:\"Split Point\",group:\"Spectrum\"}},spread:{default:.7,description:\"How widely the rainbow diffuses as it travels past the split point\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Spread\",group:\"Spectrum\"}},softness:{default:.12,description:\"How quickly the white beam transitions into the rainbow\",ui:{type:[\"range\",\"map\"],min:.001,max:1,step:.005,label:\"Softness\",group:\"Spectrum\"}},saturation:{default:.95,description:\"Rainbow saturation \\u2014 0 = white, 1 = full color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Saturation\",group:\"Spectrum\"}},speed:{default:.1,description:\"Speed the hue slowly rotates through the rainbow (0 = static)\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Hue Speed\",group:\"Spectrum\"}}},paint:e=>{let t=f=>me(T(f),e),s=Pg({from:T(\"position\"),to:T(\"splitPosition\")})(e,aa(e)),r=z(it(t(\"softness\"),.001),\"soft\"),o=z(jz(ne(s.along,s.length),v(r,.6)),\"past\"),a=z(v(ot(0,it(t(\"startFalloff\"),.001),s.along),tr(er(Ce(o,it(t(\"endFalloff\"),.001))))),\"longEnv\"),i=it(I(t(\"beamWidth\"),v(o,t(\"spread\"))),.001),l=z(Ce(s.across,i),\"an\"),c=O_(l,2.5),d=ot(s.length,I(s.length,r),s.along),u=I(v(l,.42),wt(e)),p=et(t(\"beamColor\").member(\"rgb\"),ER(u),kt(v(d,t(\"saturation\")))),_=z(v(c,a),\"amt\");return Ot(z(v(v(p,_),t(\"intensity\")),\"beamRgb\").member(\"xyz\"),Ge(_,0,1))}});var g9=H({name:\"ProgressiveBlur\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Blur that increases progressively in one direction\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:50,description:\"Maximum intensity of the blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Direction of the blur gradient (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},center:{default:{x:0,y:.5},transform:Xe,description:\"Center point where blur begins\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},falloff:{default:1,description:\"Distance over which blur transitions to full strength\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Falloff\",group:\"Effect\"}},dispersion:{default:0,description:\"Blurs red and blue by different amounts for a lens-like color fringe that grows with the blur; negative swaps the colors\",recompile:Lt(0),ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Dispersion\",group:\"Lens\"}},jitter:{default:0,description:\"Per-pixel noise on the tap spacing that hides banding at large blur radii\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Jitter\",group:\"Lens\"}}},...RU({intensity:T(\"intensity\"),angle:T(\"angle\"),center:T(\"center\"),falloff:T(\"falloff\"),detail:{dispersion:T(\"dispersion\"),jitter:T(\"jitter\")}})});var y9=H({name:\"RadialGradient\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Radial gradient radiating from a center point\",acceptsUVContext:!0,props:{colorA:{default:\"#ff0000\",transform:ce,description:\"The starting color at the center of the gradient\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#0000ff\",transform:ce,description:\"The ending color at the edge of the gradient\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the radial gradient\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},radius:{default:1,description:\"The radius of the gradient (normalized, 0.0-1.0)\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Radius\",group:\"Effect\"}},repeat:{default:1,description:\"Number of times the gradient repeats. Values above 1 create concentric rings.\",ui:{type:[\"range\",\"map\"],min:1,max:20,step:.5,label:\"Repeat\",group:\"Effect\"}},aspect:{default:1,description:\"Stretches the gradient into an ellipse. Values below 1 compress vertically, above 1 compress horizontally.\",ui:{type:[\"range\",\"map\"],min:.1,max:4,step:.01,label:\"Aspect\",group:\"Effect\"}},skewAngle:{default:0,description:\"Rotates the ellipse axis in degrees. Only visible when Aspect is not 1.\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Skew Angle\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(mg(Oi.radial({center:T(\"center\"),radius:T(\"radius\"),aspect:T(\"aspect\"),skew:T(\"skewAngle\")}),T(\"repeat\")),Us(T(\"colorSpace\")))});var b9=H({name:\"RadialWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Sweep the content away in a clock-hand arc around a center point\",props:{progress:{default:.5,description:\"How far the sweep has travelled (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},startAngle:{default:0,description:\"Angle in degrees where the sweep begins\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Start Angle\",group:\"Transition\"}},direction:{default:\"cw\",compileTime:!0,description:\"Which way the sweep rotates\",ui:{type:\"select\",options:[{label:\"Clockwise\",value:\"cw\"},{label:\"Counter-Clockwise\",value:\"ccw\"},{label:\"Both\",value:\"both\"}],label:\"Direction\",group:\"Transition\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Point the sweep rotates around\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},feather:{default:.1,description:\"Softness of the sweeping edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse which side of the sweep is wiped\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.angular(T(\"center\"),T(\"startAngle\"),T(\"direction\")),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Radial Wipe shader.\"});var x9=H({name:\"RandomBars\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away as parallel bars vanishing in random order\",props:{progress:{default:.5,description:\"How far the wipe has progressed (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},angle:{default:0,description:\"Orientation of the bars in degrees (0 = vertical bars)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Transition\"}},barCount:{default:12,description:\"Number of bars across the frame\",ui:{type:[\"range\",\"map\"],min:2,max:100,step:1,label:\"Bars\",group:\"Transition\"}},softness:{default:.15,description:\"How softly each bar fades out (0 = hard-edged bars)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Reverse the order the bars vanish in\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.directional(T(\"angle\")).bands(T(\"barCount\")).shuffled(),progress:T(\"progress\"),feather:T(\"softness\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Random Bars shader.\"});var A9=Mn,tn=512,w9=tn*tn,M9=\"rgba16float\",T9=16,D_e=.06,ny=1.5/tn,S9=6,P9=.42,C9=.85,L_e=.55,U_e=18,O_e=.35,G_e=bt,F_e={coral:{feed:.0545,kill:.062},mitosis:{feed:.0367,kill:.0649},spots:{feed:.03,kill:.062},maze:{feed:.029,kill:.057},worms:{feed:.078,kill:.061},fingerprints:{feed:.037,kill:.06},holes:{feed:.039,kill:.058},solitons:{feed:.074,kill:.064},bubbles:{feed:.098,kill:.0555},waves:{feed:.014,kill:.045},flowers:{feed:.062,kill:.06093}},I_e=8,Y_e=.022,W_e=.014,q_e=.008,V_e=.11,N_e=.03,$_e=.075,o5=ZA({n:tn,namePrefix:\"reactionDiffusion\"}),a5=ZA({n:tn,namePrefix:\"reactionDiffusion\",drive:{contrastMax:I_e,dFeed:Y_e,dKill:W_e,feedMin:q_e,feedMax:V_e,killMin:N_e,killMax:$_e}}),n5=Uz({n:tn,density:D_e,namePrefix:\"reactionDiffusion\"}),i5=Oz({n:tn,format:M9,namePrefix:\"reactionDiffusion\"}),K5e=o5.kernel,Q5e=a5.kernel,Z5e=n5.kernel,J5e=i5.kernel,E9=H({name:\"ReactionDiffusion\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"A living Gray-Scott reaction-diffusion pattern that fills the layer and blooms wherever you drag the cursor\",requiresRTT:!1,requiresChild:!1,acceptsOptionalChild:!0,usesPointer:!0,props:{preset:{default:\"coral\",description:\"Named Gray-Scott regime \\u2014 drives the feed & kill rates for a whole family of patterns. Choose Custom to dial feed & kill by hand\",ui:{type:\"select\",options:[{label:\"Coral\",value:\"coral\"},{label:\"Mitosis\",value:\"mitosis\"},{label:\"Spots\",value:\"spots\"},{label:\"Maze\",value:\"maze\"},{label:\"Worms\",value:\"worms\"},{label:\"Fingerprints\",value:\"fingerprints\"},{label:\"Holes\",value:\"holes\"},{label:\"Solitons\",value:\"solitons\"},{label:\"Bubbles\",value:\"bubbles\"},{label:\"Waves\",value:\"waves\"},{label:\"Flowers\",value:\"flowers\"},{label:\"Custom\",value:\"custom\"}],label:\"Pattern\",group:\"Pattern\"}},feed:{default:.0545,description:\"Feed rate \\u2014 how fast chemical U is replenished (used when Pattern = Custom)\",ui:{type:\"range\",min:.01,max:.1,step:.001,label:\"Feed\",group:\"Pattern\",condition:{preset:\"custom\"}}},kill:{default:.062,description:\"Kill rate \\u2014 how fast chemical V is removed (used when Pattern = Custom)\",ui:{type:\"range\",min:.03,max:.07,step:.001,label:\"Kill\",group:\"Pattern\",condition:{preset:\"custom\"}}},diffusionRatio:{default:.5,description:\"Ratio of the two chemicals' diffusion rates \\u2014 shifts the pattern character (lower = tighter, more filament-like)\",ui:{type:\"range\",min:.2,max:.9,step:.01,label:\"Diffusion Ratio\",group:\"Pattern\"}},featureSize:{default:3,description:\"Size of the pattern features \\u2014 lower shows finer, smaller cells; higher magnifies them into larger cells\",ui:{type:\"range\",min:1,max:6,step:.1,label:\"Feature Size\",group:\"Pattern\"}},speed:{default:6,description:\"Simulation steps per frame \\u2014 higher evolves the pattern faster\",ui:{type:\"range\",min:1,max:T9,step:1,label:\"Speed\",group:\"Pattern\"}},brushSize:{default:.04,description:\"Radius of the cursor brush that seeds new reagent as you drag\",ui:{type:\"range\",min:.01,max:.3,step:.01,label:\"Brush Size\",group:\"Interaction\"}},brushStrength:{default:.6,description:\"How much reagent the cursor injects while dragging\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Brush Strength\",group:\"Interaction\"}},colorA:{default:\"transparent\",transform:ce,description:\"Background color (empty regions between cells)\",ui:{type:\"color\",label:\"Background\",group:\"Colors\"}},colorC:{default:\"#38bdf8\",transform:ce,description:\"Accent color at the cell walls (mid pattern values)\",ui:{type:\"color\",label:\"Wall Color\",group:\"Colors\"}},colorB:{default:\"#e2f5ff\",transform:ce,description:\"Color of the dense cell interiors (high pattern values)\",ui:{type:\"color\",label:\"Cell Color\",group:\"Colors\"}},contrast:{default:.5,description:\"Sharpness of the cell walls \\u2014 higher gives crisper, more graphic edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Contrast\",group:\"Colors\"}},threshold:{default:.28,description:\"Pattern level the colors are centered on \\u2014 shifts the balance of background vs. cells\",ui:{type:[\"range\",\"map\"],min:.05,max:.6,step:.01,label:\"Threshold\",group:\"Colors\"}},colorSpace:{default:\"oklch\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},relief:{default:.4,description:\"Treats the pattern as a raised surface and shades it with a light \\u2014 higher gives a more sculpted, three-dimensional look (0 for a flat, graphic look)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Relief\",group:\"Lighting\"}},lightAngle:{default:135,description:\"Direction the surface light comes from, in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Light Angle\",group:\"Lighting\"}},childInfluence:{default:.6,description:\"When a child layer is nested, how strongly its brightness biases the pattern \\u2014 the preset sets the character, the child steers where it grows dense vs. sparse (0 ignores the child)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Influence\",group:\"Child\"}},childContrast:{default:.5,description:\"Contrast applied to the child's brightness before it drives the pattern \\u2014 higher pushes toward a crisp two-tone split (edges), lower keeps smooth tonal shading\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Contrast\",group:\"Child\"}},childThreshold:{default:.5,description:\"Brightness level of the child that reads as neutral \\u2014 shifts which tones grow the pattern vs. clear it\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Threshold\",group:\"Child\"}},childInvert:{default:!1,transform:rs,description:\"Flip which tones of the child grow the pattern (bright vs. dark areas)\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Child\"}}},...Ec((e,t)=>{let{getCpuValue:s,registerComputeTexture:r,onCleanup:o,childNode:a}=e,i=!!a,l=pr(t,m,w9),c=pr(t,m,w9),d=t.createTexture({size:[tn,tn],format:M9}).$usage(\"storage\",\"sampled\");o(()=>d.destroy());let u=r(d),p=i?a5:o5,_=t.createUniform(p.Params),f=[tn,tn],h=ap(l,c),g=ai(t,i5.kernel,{size:f}),y=h.perSide(D=>g.with(t.createBindGroup(i5.layout,{srcBuf:D,outTex:d}))),b=ai(t,n5.kernel,{size:f,bindGroup:t.createBindGroup(n5.layout,{stateBuf:l})}),x=ai(t,p.kernel,{size:f}),P=i?null:h.groups((D,O)=>x.with(t.createBindGroup(o5.layout,{readBuf:D,writeBuf:O,params:_.buffer}))),C=i?nA(e,D=>h.groups((O,F)=>x.with(t.createBindGroup(a5.layout,{readBuf:O,writeBuf:F,params:_.buffer,driveTex:D})))):null,E=!0,R=\"\",U=Sl(),L=null,k=1;return{outputs:{rdTexture:u},...C?{bindInputs:C.bindInputs}:{},clampDt:.05,stages:[Ir.readyWhen(()=>(L=C?C.bound():P,!!L)),Ir.values(\"feed/kill+brush\",D=>{let O=D.frameParams,F=D.num,q=O.dimensions?.height??0,Y=q>0?(O.dimensions?.width??0)/q:1,V=s(\"preset\")||\"coral\";V!==R&&(R=V,E=!0);let X=F_e[V],Q=X?X.feed:F(\"feed\",.055),te=X?X.kill:F(\"kill\",.062),J=1/Math.max(F(\"featureSize\",3),1e-4),oe=Math.min(Y,1),le=Math.min(1/Y,1),se=U.update(O.pointer,.016),Te=(se.x-.5)*oe*J+.5,de=(se.y-.5)*le*J+.5,xe=Math.sqrt(se.dx*se.dx+se.dy*se.dy),Ae=xe>5e-4&&F(\"brushStrength\",.6)>0?Math.min(xe/.02,1):0,De=F(\"brushSize\",.04)*tn*J,Ee=s(\"childInvert\");k=Math.min(T9,Math.max(1,Math.round(F(\"speed\",6)))),_.write({feed:Q,kill:te,dv:F(\"diffusionRatio\",.5),brushRadSq:De*De,brushStrength:F(\"brushStrength\",.6),cursorX:Te*tn,cursorY:de*tn,cursorActive:Ae,driveInfluence:F(\"childInfluence\",.6),driveContrast:F(\"childContrast\",.5),driveThreshold:F(\"childThreshold\",.5),driveInvert:Ee===!0||Ee===1?1:0,driveMapX:1/(oe*J),driveMapY:1/(le*J),_pad0:0,_pad1:0})}),Ir.seedOnce({pass:b,staleWhen:()=>E,onSeed:()=>{E=!1,h.reset()}}),Ir.iterate({count:()=>k,step:(D,O)=>{O.push(L()),h.swap()}}),Ir.publish(()=>y.read())]}}),gpu:{fragment:e=>{let{ctx:t,computeOutputs:s,propValues:r,uniforms:o}=e,a=s?.rdTexture;if(!a)return xt;let i=z(Ce(1,o.featureSize),\"view\"),l=Yr(t.aspect,1),c=Yr(Ce(1,t.aspect),1),d=z(rt(I(v(v(ne(t.uv.member(\"x\"),.5),l),i),.5),I(v(v(ne(t.uv.member(\"y\"),.5),c),i),.5)),\"sampleUV\"),u=a.sample(d,\"linearClamp\").member(\"y\"),p=z(it(ne(.6,v(o.contrast,.55)),.02),\"rampW\"),_=z(ot(ne(o.threshold,p),I(o.threshold,p),u),\"rampT\"),f=r.colorSpace??0,h=A9.mixColorsVariants[f]??A9.mixColorsLinear,g=W(h,\"mixColors\",[o.colorA,o.colorC,Ge(v(_,2),0,1)]),y=W(h,\"mixColors\",[o.colorC,o.colorB,Ge(ne(v(_,2),1),0,1)]),b=z(br(Zo(_,.5),y,g),\"rampColor\"),x=a.sample(I(d,rt(-ny,0)),\"linearClamp\").member(\"y\"),P=a.sample(I(d,rt(ny,0)),\"linearClamp\").member(\"y\"),C=a.sample(I(d,rt(0,-ny)),\"linearClamp\").member(\"y\"),E=a.sample(I(d,rt(0,ny)),\"linearClamp\").member(\"y\"),R=v(ne(P,x),S9),U=v(ne(E,C),S9),L=z(Os(Qe(er(R),er(U),1)),\"reliefN\"),k=z(v(o.lightAngle,G_e),\"lightAng\"),D=z(Os(Qe(v(Do(k),C9),v(Vt(k),C9),L_e)),\"lightDir\"),O=Ge($t(L,D),0,1),F=I(P9,v(1-P9,O)),q=v(ts(Ge($t(L,Os(I(D,Qe(0,0,1)))),0,1),U_e),O_e),Y=I(v(b.member(\"rgb\"),F),kt(q));return Ot(et(b.member(\"rgb\"),Y,o.relief),b.member(\"a\"))}}});var k9=H({name:\"RectangularCoordinates\",role:\"warp\",category:\"Distortions\",description:\"Convert polar coordinates back to rectangular space\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point for rectangular coordinate conversion\"),scale:{default:1,description:\"Scale factor for the rectangular output\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.1,label:\"Scale\",group:\"Effect\"}},intensity:{default:1,description:\"Blends between original UVs (0) and rectangular coordinates (1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Intensity\",group:\"Effect\"}},edges:fr(\"transparent\",\"How to handle edges when distortion pushes content out of bounds\")},map:JL({center:T(\"center\"),scale:T(\"scale\"),intensity:T(\"intensity\")}),missingChildMessage:\"You must pass a child component into the RectangularCoordinates shader.\"});var B9=H({name:\"ReflectivePlane\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Reflective floor that mirrors the content above it\",requiresRTT:!0,requiresChild:!0,props:{height:{default:.7,description:\"Vertical position of the reflective surface\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Floor Height\",group:\"Plane\"}},distance:{default:.5,description:\"How far below the floor the reflection remains visible before fully fading to transparent.\",ui:{type:[\"range\",\"map\"],min:.01,max:1,step:.01,label:\"Reflection Distance\",group:\"Plane\"}},falloff:{default:.5,description:\"Width of the fade zone, as a fraction of reflection distance.\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Reflection Falloff\",group:\"Plane\"}},blur:{default:3,description:\"Maximum blur applied to the reflection far from the surface.\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.01,label:\"Blur\",group:\"Surface\"}},blurDistance:{default:.3,description:\"How far below the surface the blur takes to ramp from sharp to maximum.\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Blur Distance\",group:\"Surface\"}},edges:{default:\"stretch\",description:\"How to handle reflected samples that fall outside the source content.\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Surface\"}}},...KU({line:T(\"height\"),blur:T(\"blur\"),blurDistance:T(\"blurDistance\"),halfKernel:30}),gpu:{fragment:e=>{let{childNode:t,ctx:s,computeOutputs:r,convertToTexture:o}=e;if(!t)return xt;let a=r?.blurredTexture,i=r?.childTexture??o(t),l=a??i;return W(Yt,\"unpremultiplyAlpha\",[QU({line:T(\"height\"),distance:T(\"distance\"),falloff:T(\"falloff\"),edges:T(\"edges\")},i.sample(s.uv),c=>l.sample(c),jU(T(\"height\")))(e)])}}});var z9=H({name:\"Repeater\",role:\"structural\",species:\"custom\",category:\"Distortions\",description:\"Repeat the child content in grid, radial or linear layouts with per-instance variation\",requiresRTT:!0,requiresChild:!0,wantsBoundsParams:!0,boundingBoxDeclaration:{aspectRatio:null},props:{mode:{default:\"grid\",transform:e=>({grid:0,radial:1,linear:2})[e]??0,compileTime:!0,description:\"Layout used to place the repeated instances\",ui:{type:\"select\",options:[{label:\"Grid\",value:\"grid\"},{label:\"Radial\",value:\"radial\"},{label:\"Linear\",value:\"linear\"}],label:\"Mode\",group:\"Layout\"}},cropLeft:{default:0,description:\"Crop inset from the left edge of the source element (fraction of its width)\",ui:{type:[\"range\",\"map\"],min:0,max:.49,step:.005,label:\"Crop Left\",group:\"Source\"}},cropRight:{default:0,description:\"Crop inset from the right edge of the source element (fraction of its width)\",ui:{type:[\"range\",\"map\"],min:0,max:.49,step:.005,label:\"Crop Right\",group:\"Source\"}},cropTop:{default:0,description:\"Crop inset from the top edge of the source element (fraction of its height)\",ui:{type:[\"range\",\"map\"],min:0,max:.49,step:.005,label:\"Crop Top\",group:\"Source\"}},cropBottom:{default:0,description:\"Crop inset from the bottom edge of the source element (fraction of its height)\",ui:{type:[\"range\",\"map\"],min:0,max:.49,step:.005,label:\"Crop Bottom\",group:\"Source\"}},columns:{default:3,description:\"Number of grid columns\",ui:{type:[\"range\",\"map\"],min:1,max:12,step:1,label:\"Columns\",group:\"Layout\",condition:{mode:\"grid\"}}},rows:{default:3,description:\"Number of grid rows\",ui:{type:[\"range\",\"map\"],min:1,max:12,step:1,label:\"Rows\",group:\"Layout\",condition:{mode:\"grid\"}}},gapX:{default:.05,description:\"Horizontal gap between grid cells\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.005,label:\"Gap X\",group:\"Layout\",condition:{mode:\"grid\"},dimensional:\"canvas-width\"}},gapY:{default:.05,description:\"Vertical gap between grid cells\",ui:{type:[\"range\",\"map\"],min:0,max:.5,step:.005,label:\"Gap Y\",group:\"Layout\",condition:{mode:\"grid\"},dimensional:\"canvas-height\"}},stagger:{default:0,description:\"Horizontal offset applied to every other row (brick layout)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Stagger\",group:\"Layout\",condition:{mode:\"grid\"}}},flip:{default:\"none\",transform:e=>({none:0,\"alternate-flip-x\":1,\"alternate-flip-y\":2,both:3})[e]??0,compileTime:!0,description:\"Mirror alternating columns/rows for seamless tiling patterns\",ui:{type:\"select\",options:[{label:\"None\",value:\"none\"},{label:\"Alternate Flip X\",value:\"alternate-flip-x\"},{label:\"Alternate Flip Y\",value:\"alternate-flip-y\"},{label:\"Both\",value:\"both\"}],label:\"Flip\",group:\"Layout\",condition:{mode:\"grid\"}}},count:{default:8,description:\"Number of repeated instances\",ui:{type:[\"range\",\"map\"],min:1,max:64,step:1,label:\"Count\",group:\"Layout\",condition:{mode:[\"radial\",\"linear\"]}}},radius:{default:.3,description:\"Orbit radius of the radial layout\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Radius\",group:\"Layout\",condition:{mode:\"radial\"},dimensional:\"canvas-height\"}},startAngle:{default:0,description:\"Angle of the first instance on the orbit\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Start Angle\",group:\"Layout\",condition:{mode:\"radial\"}}},sweep:{default:360,description:\"Angular span the instances are distributed across\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Sweep\",group:\"Layout\",condition:{mode:\"radial\"}}},faceCenter:{default:!1,transform:rs,description:\"Rotate each instance to face the orbit center\",ui:{type:\"checkbox\",label:\"Face Center\",group:\"Layout\",condition:{mode:\"radial\"}}},direction:{default:0,description:\"Direction of the linear layout in degrees (0 = rightward)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Direction\",group:\"Layout\",condition:{mode:\"linear\"}}},spacing:{default:.2,description:\"Distance between consecutive instances\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Spacing\",group:\"Layout\",condition:{mode:\"linear\"},dimensional:\"canvas-height\"}},instanceScale:{default:1,description:\"Progressive scale multiplier applied per instance (compounds with each copy)\",ui:{type:[\"range\",\"map\"],min:.5,max:2,step:.005,label:\"Scale\",group:\"Instances\"}},instanceRotation:{default:0,transform:e=>e*Math.PI/180,description:\"Additional rotation in degrees applied per instance (accumulates with each copy)\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Rotation\",group:\"Instances\"}},instanceOpacity:{default:1,description:\"Progressive opacity falloff applied per instance (compounds with each copy)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Opacity\",group:\"Instances\"}},hueShift:{default:0,transform:e=>e*Math.PI/180,recompile:Lt(0),description:\"Hue rotation in degrees added per instance\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Hue Shift\",group:\"Instances\"}},phase:{default:0,description:\"Seamless layout animation phase (0-1 wraps to the identical layout)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.001,label:\"Phase\",group:\"Instances\"}},zOrder:{default:\"forward\",transform:e=>e===\"backward\"?1:0,compileTime:!0,description:\"Stacking order of overlapping instances\",ui:{type:\"select\",options:[{label:\"Forward\",value:\"forward\"},{label:\"Backward\",value:\"backward\"}],label:\"Z-Order\",group:\"Instances\"}},jitterPosition:{default:0,description:\"Random per-instance position offset\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Position\",group:\"Jitter\"}},jitterRotation:{default:0,description:\"Random per-instance rotation\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Rotation\",group:\"Jitter\"}},jitterScale:{default:0,description:\"Random per-instance scale variation\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Scale\",group:\"Jitter\"}},jitterOpacity:{default:0,description:\"Random per-instance opacity variation\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.005,label:\"Opacity\",group:\"Jitter\"}},seed:{default:0,description:\"Random seed for the jitter values\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Jitter\"}}},gpu:{fragment:D8({source:{crop:{left:T(\"cropLeft\"),right:T(\"cropRight\"),top:T(\"cropTop\"),bottom:T(\"cropBottom\")}},placement:R8(T(\"mode\"),{grid:k8({columns:T(\"columns\"),rows:T(\"rows\"),gapX:T(\"gapX\"),gapY:T(\"gapY\"),stagger:T(\"stagger\"),flip:T(\"flip\")}),radial:B8({count:T(\"count\"),radius:T(\"radius\"),startAngle:T(\"startAngle\"),sweep:T(\"sweep\"),faceCenter:T(\"faceCenter\")}),linear:z8({count:T(\"count\"),direction:T(\"direction\"),spacing:T(\"spacing\")})}),variation:{scale:T(\"instanceScale\"),rotation:T(\"instanceRotation\"),opacity:T(\"instanceOpacity\"),jitter:{position:T(\"jitterPosition\"),rotation:T(\"jitterRotation\"),scale:T(\"jitterScale\"),opacity:T(\"jitterOpacity\")},seed:T(\"seed\"),phase:T(\"phase\")},hueShift:T(\"hueShift\"),order:T(\"zOrder\")})}});var R9=H({role:\"shape\",name:\"Ring\",description:\"Annular ring (donut) with adjustable radius and band thickness\",shape:{distance:({x:e,y:t},s)=>mR(e,t,s(\"radius\"),s(\"thickness\")),rotatable:!1,colorDescription:\"Fill color of the ring\",centerDescription:\"Center position of the ring\",bounds:{custom:{propBindings:{x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"}},computeBounds(e,t,s){let r=e.radius??.5,o=e.thickness??0,a=typeof e.center?.x==\"number\"?e.center.x:.5,i=typeof e.center?.y==\"number\"?e.center.y:.5,l=(r+o)*2*s;return{centerXPx:a*t,centerYPx:i*s,widthPx:l,heightPx:l,rotationDeg:0}},writeBounds(e,t,s,r){let o=t.thickness??0,a=Math.max(0,e.widthPx/(2*r));return{center:{...t.center??{x:.5,y:.5},x:e.centerXPx/s,y:e.centerYPx/r},radius:Math.max(0,a-o)}}}},shapeProps:{radius:{default:.3,description:\"Distance from center to the ring's midline in UV space\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Radius\",group:\"Shape\"}},thickness:{default:.07,description:\"Half-width of the ring band \\u2014 total ring width is twice this value\",ui:{type:\"range\",min:.005,max:.3,step:.005,label:\"Thickness\",group:\"Shape\"}}},stroke:{softnessDescription:\"Edge softness for antialiasing (applied to both inner and outer ring edges)\",strokeThicknessMax:.1,strokePositionDescription:\"Position of the stroke relative to the ring edge\"}}});var D9=H({name:\"Ripples\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Concentric animated ripples emanating from a point\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point where ripples emanate from\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},colorA:{default:\"#ffffff\",transform:ce,description:\"Color of the ripple waves\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#000000\",transform:ce,description:\"Background color between ripples\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},speed:{default:1,description:\"Speed of ripple animation\",ui:{type:\"range\",min:-5,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},frequency:{default:20,description:\"Number of ripples/spacing between them\",ui:{type:[\"range\",\"map\"],min:1,max:80,step:.1,label:\"Frequency\",group:\"Effect\"}},softness:{default:0,description:\"Softness of ripple edges\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.1,label:\"Softness\",group:\"Effect\"}},thickness:{default:.5,description:\"Thickness of each ripple band\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Thickness\",group:\"Effect\"}},phase:{default:0,description:\"Phase offset for ripple animation\",ui:{type:[\"range\",\"map\"],min:0,max:6.28,step:.1,label:\"Phase\",group:\"Animation\"}}},paint:Zr({fill:T(\"colorB\"),stroke:T(\"colorA\"),mask:HR({center:T(\"center\"),frequency:T(\"frequency\"),thickness:T(\"thickness\"),softness:T(\"softness\"),phase:T(\"phase\")})})});var L9=H({name:\"RippleWipe\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away in concentric rings pulsing out from a center point\",props:{progress:{default:.5,description:\"How far the ripple has expanded (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Point the rings expand from\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},rings:{default:8,description:\"Number of concentric rings\",ui:{type:[\"range\",\"map\"],min:2,max:40,step:1,label:\"Rings\",group:\"Transition\"}},feather:{default:.2,description:\"How softly adjacent rings' timing overlaps (0 = discrete ring pops)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Wipe from the outside inward instead\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.radial(T(\"center\")).bands(T(\"rings\")),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Ripple Wipe shader.\"});var U9=H({role:\"shape\",name:\"RoundedRect\",description:\"Rounded rectangle with adjustable width, height, and corner rounding\",shape:{distance:({x:e,y:t},s)=>dg(e,t,s(\"width\"),s(\"height\"),s(\"rounding\")),colorDescription:\"Fill color of the rectangle\",centerDescription:\"Center position of the rectangle\",bounds:{size:{width:\"width\",height:\"height\"}},shapeProps:{width:{default:.35,description:\"Half-width of the rectangle\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Width\",group:\"Shape\"}},height:{default:.25,description:\"Half-height of the rectangle\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Height\",group:\"Shape\"}},rounding:{default:.05,description:\"Corner rounding radius \\u2014 set to min(width, height) for a pill shape\",ui:{type:\"range\",min:0,max:.5,step:.01,label:\"Rounding\",group:\"Shape\",dimensional:\"canvas-height\"}}}}});var W9=Rr(),O9=[{freq:3.1,speed:.35,amount:.045},{freq:6.7,speed:-.22,amount:.018},{freq:11.3,speed:.5,amount:.007}],X_e=W9?O9.slice(0,2):O9,H_e={amount:.3,freq:2.4,speed:.4},j_e=.08,K_e=.7,Q_e=2,Z_e=.8,J_e=.25,G9=.004,F9=.3,efe=.0012,I9={coarse:[14,420],fine:[26,900]},tfe=.1,sf={ambient:.18,key:.9,fill:.45,elevation:-.65,fillElevation:-.45},Y9=[.25,.9],l5={roughness:.85,anisotropy:.5,gain:.35},sfe=.6,q9=H({name:\"Satin\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Flowing satin \\u2014 a draped cloth of soft rippling folds lit like real fabric: a highlight streaked along the weave, a velvet sheen on the fold flanks and creases falling into shadow, swaying gently in a breeze\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{color:{default:\"#c92c40\",transform:ce,description:\"The dye of the cloth \\u2014 deep colors show the sheen best\",ui:{type:\"color\",label:\"Color\",group:\"Cloth\"}},highlightColor:{default:\"#c4667b\",transform:ce,description:\"The color of the light caught by the weave \\u2014 near white for silk, tinted toward the dye for a matte satin\",ui:{type:\"color\",label:\"Highlight\",group:\"Cloth\"}},foldCount:{default:7,compileTime:!0,description:\"How many ridges run across the cloth\",ui:{type:\"range\",min:1,max:12,step:1,label:\"Folds\",group:\"Folds\"}},foldDirection:{default:90,description:\"Direction the folds run, in degrees \\u2014 90 hangs them vertically like a curtain\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Direction\",group:\"Folds\"}},foldDepth:{default:.5,description:\"How deep the folds are \\u2014 0 is a flat sheet, 1 heavy gathered drapery\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Depth\",group:\"Folds\"}},foldWidth:{default:.14,description:\"Width of each ridge, relative to the canvas \\u2014 narrow for fine pleats, wide for broad soft folds\",ui:{type:[\"range\",\"map\"],min:.04,max:.4,step:.01,label:\"Width\",group:\"Folds\"}},pinning:{default:.6,description:\"How much the cloth is gathered at the top edge \\u2014 0 is a loose drape, 1 a curtain pinned at the rail with the folds opening as they fall\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Pinning\",group:\"Folds\"}},seed:{default:0,description:\"Random seed \\u2014 a different layout of folds\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Folds\"}},speed:{default:1,description:\"How fast the cloth moves. 0 pauses.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Motion\"}},breeze:{default:.4,description:\"Strength of the breeze \\u2014 how far the folds ripple and sway\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Breeze\",group:\"Motion\"}},gloss:{default:.1,description:\"How shiny the weave is \\u2014 0 soft matte satin, 1 glossy silk with a tight bright streak\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Gloss\",group:\"Finish\"}},anisotropy:{default:.7,description:\"How much the highlight stretches along the threads \\u2014 the long streak real satin shows\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Anisotropy\",group:\"Finish\"}},bloom:{default:.5,description:\"The broad soft glow around the highlight \\u2014 light the weave scatters sideways. 0 leaves the crisp streak alone, 1 a wide satin bloom\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Bloom\",group:\"Finish\"}},sheen:{default:.5,description:\"The velvet glow on the flanks of each fold where the fibres catch the light edge-on\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Sheen\",group:\"Finish\"}},weave:{default:.1,description:\"Visibility of the thread texture \\u2014 the fine grain that glints inside the highlight\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Weave\",group:\"Finish\"}},fiberAngle:{default:90,description:\"Direction the threads run, in degrees \\u2014 the highlight streaks along this axis. Usually the fold direction.\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Thread Angle\",group:\"Finish\"}},lightAngle:{default:215,description:\"Direction of the key light, in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Light Angle\",group:\"Light\"}},fill:{default:.35,description:\"Strength of the fill light from the opposite side \\u2014 lifts the shadowed flanks\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Fill\",group:\"Light\"}}},paint:e=>{let{uv:t,aspect:s}=aa(e),r=oe=>me(T(oe),e),o=z(wt(e),\"satinTime\"),a=z(rt(v(ne(t.member(\"x\"),.5),s),ne(t.member(\"y\"),.5)),\"q\"),i=ii(r(\"foldDirection\"),\"drape\"),l=Math.max(1,Math.min(12,Math.round(e.propValues.foldCount??7))),c=z(v(I(v(ms(i.perp.member(\"x\")),s),ms(i.perp.member(\"y\"))),1.1),\"spread\"),d=GD({count:l,seed:r(\"seed\"),spread:c,width:r(\"foldWidth\"),height:r(\"foldDepth\"),jitter:Z_e}),u=z(r(\"breeze\"),\"breeze\"),p={time:o,ripple:{waves:X_e,gain:et(.35,1,u)},sway:{amount:v(u,j_e),rate:.7},swell:H_e,pinning:z(r(\"pinning\"),\"pinning\"),sharpness:Q_e,crease:K_e},_=z(I(v(ms(i.tangent.member(\"x\")),s),ms(i.tangent.member(\"y\"))),\"alongExtent\"),f=oe=>{let le=i.coordsOf(oe);return{along:I(Ce(le.along,_),.5),across:le.across}},h=oe=>FD(f(oe),d,p),g=W9?null:vL(h,a,G9,\"cloth\"),y=g??bp(h,a,G9,\"cloth\"),b=Gi(Qe(0,0,-1),v(y.dx,-F9),v(y.dy,-F9),\"nFold\"),x=ID(f(a),d,{...p,foreshorten:J_e}),P=z(I(v(i.tangent,x.along),v(i.perp,x.across)),\"onCloth\"),C=ii(r(\"fiberAngle\"),\"fibre\"),E=C.coordsOf(P),R=yg(b,C,{across:v(z(I(Cc(E,{freq:I9.coarse}),v(Cc(E,{freq:I9.fine,offset:[3.1,7.7]}),.5)),\"threads\"),v(r(\"weave\"),tfe))}),U=Ea(e,{aspect:s}),L=Er(r(\"lightAngle\"),\"key\"),k=Ld(L,sf.elevation,\"L\"),D=Ld(er(L),sf.fillElevation,\"Lfill\"),O=z(I(I(sf.ambient,v(Pl(R,k,{wrap:.35}),sf.key)),v(Pl(R,D,{wrap:.6}),v(r(\"fill\"),sf.fill))),\"diffuse\"),F=g?z(Ge(ne(1,v(g.curvature,efe)),.6,1.1),\"cavity\"):1,q=z(r(\"gloss\"),\"gloss\"),Y=z(r(\"anisotropy\"),\"aniso\"),V=Ud({normal:R,tangent:C.tangent,light:k,view:U,alphas:V_(ne(1,q),Y),gain:et(Y9[0],Y9[1],q)}),X=Ud({normal:R,tangent:C.tangent,light:k,view:U,alphas:V_(l5.roughness,v(Y,l5.anisotropy)),gain:v(r(\"bloom\"),l5.gain)}),Q=TL({normal:R,light:k,view:U,roughness:et(.7,.3,q),gain:v(r(\"sheen\"),sfe)}),te=r(\"color\").member(\"rgb\"),J=r(\"highlightColor\").member(\"rgb\");return Ot(yp(I(v(te,v(O,F)),v(J,v(I(I(V,X),Q),F)))),1)}});var V9=H({name:\"Saturation\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Adjust color saturation intensity\",props:{intensity:{default:1,description:\"The intensity of the saturation effect (1 being no change)\",recompile:Lt(1),ui:{type:[\"range\",\"map\"],min:0,max:3,step:.1,label:\"Intensity\",group:\"Adjustments\"}}},effect:s8(T(\"intensity\")),identityWhen:cg(\"intensity\",1),missingChildMessage:\"You must pass a child component into the Saturation shader.\"});var N9=H({name:\"Scratches\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Fine hairline scratches, like a worn film or scratched surface\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...IO(),scale:{default:2,description:\"Pattern scale (higher = more, finer scratches)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},thickness:{default:1,description:\"Thickness of the scratches (higher = bolder streaks)\",ui:{type:\"range\",min:.2,max:5,step:.01,label:\"Thickness\",group:\"Effect\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},...In()},paint:Vs(ua(WD(jD({thickness:T(\"thickness\")}),{scale:T(\"scale\"),seed:T(\"seed\")})),QD(T(\"colorA\"),T(\"colorB\")))});var $9=H({name:\"Sharpness\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Adjust image sharpness using a convolution kernel\",props:{sharpness:{default:0,description:\"How sharp to make the underlying image\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Sharpness\",group:\"Adjustments\"}}},identityWhen:Uo(\"sharpness\"),effect:xU(T(\"sharpness\"))});var iy=e=>{let t=Math.sin(e)*1e4;return t-Math.floor(t)},Bl=16,rfe=1024,rf=Bl*4,ofe=S8(rf),X9=e=>{let t=new Float32Array(Bl*2);for(let s=0;s<Bl;s++)t[s*2]=iy(e+s*2),t[s*2+1]=iy(e+s*2+1);return t};function afe(e){let t=new Float32Array(Bl*4),s=new Float32Array(Bl*4),r=c=>{let d=X9(c);for(let u=0;u<Bl;u++)t[u*4]=d[u*2],t[u*4+1]=d[u*2+1],t[u*4+2]=iy(c+u*3),t[u*4+3]=iy(c+u*3+1)},o=e(\"seed\")??2;r(o);let a=1,i=.5,l=.5;return{cellData:t,displacementData:s,step(c,d,u){let p=Math.min(d,.016),_=e(\"seed\")??2;_!==o&&(o=_,r(o),s.fill(0));let f=e(\"intensity\")??4,h=e(\"radius\")??.4,g=e(\"decay\")??1,y=p>0?(c.x-i)/p:0,b=p>0?(c.y-l)/p:0,x=Math.sqrt(y*y+b*b),P=5+f*2;if(x>P){let C=P/x;y*=C,b*=C,x=P}for(let C=0;C<Bl;C++){let E=t[C*4],R=t[C*4+1],U=t[C*4+2]-.5,L=t[C*4+3]-.5,k=u>=1?(E-c.x)*u:E-c.x,D=u>=1?R-c.y:(R-c.y)/u,O=Math.sqrt(k*k+D*D),F=s[C*4],q=s[C*4+1],Y=Math.max(.01,g),V=Math.exp(-p/Y);F*=V,q*=V;let X=0,Q=0;if(O<h&&x>.01){let J=Math.max(0,1-O/h),oe=J*J,le=oe*x*f*p*.5;X=y*le,Q=b*le;let se=oe*x*f*p*.1;X+=U*se,Q+=L*se}let te=Math.min(1,a*p);s[C*4]=F+X*te,s[C*4+1]=q+Q*te}i=c.x,l=c.y}}}function nfe(e,t){let{createDataTexture:s,registerMediaTexture:r,onCleanup:o}=e,a=new Float32Array(rf),i=new Uint16Array(rf),l=()=>{for(let d=0;d<Bl;d++)a[d*4]=t.cellData[d*4],a[d*4+1]=t.cellData[d*4+1],a[d*4+2]=t.displacementData[d*4],a[d*4+3]=t.displacementData[d*4+1];for(let d=0;d<rf;d++)i[d]=_o(a[d])};l();let c=s({width:rf,height:1,format:\"r16float\",data:i,label:\"shatter-cells\"});return o(()=>c.destroy()),{dataKit:r(()=>c.texture),upload(){l(),c.write(i)}}}var H9=H({name:\"Shatter\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Broken glass effect with tectonic plate displacement\",requiresRTT:!0,requiresChild:!0,usesPointer:!0,props:{crackWidth:{default:1,description:\"Thickness of crack lines\",ui:{type:[\"range\",\"map\"],min:.5,max:5,step:.1,label:\"Crack Width\",group:\"Effect\"}},intensity:{default:4,description:\"How much shards shift\",ui:{type:\"range\",min:0,max:20,step:1,label:\"Intensity\",group:\"Effect\"}},radius:{default:.4,description:\"Cursor influence radius\",ui:{type:\"range\",min:.1,max:1,step:.1,label:\"Radius\",group:\"Effect\"}},decay:{default:1,description:\"How fast shards return to rest\",ui:{type:\"range\",min:.1,max:10,step:.1,label:\"Decay\",group:\"Effect\"}},seed:{default:2,description:\"Random seed for pattern\",ui:{type:\"range\",min:0,max:50,step:1,label:\"Seed\",group:\"Effect\"}},chromaticSplit:{default:1,description:\"RGB separation for prismatic glass effect\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Chromatic Split\",group:\"Effect\"}},refractionStrength:{default:5,description:\"How much cracks bend/distort the underlying image\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Refraction\",group:\"Effect\"}},shardLighting:{default:.1,description:\"Subtle lighting on tilted shards for 3D depth\",ui:{type:\"range\",min:0,max:.5,step:.1,label:\"Shard Lighting\",group:\"Effect\"}},edges:{default:\"mirror\",description:\"How to handle edges when displacement pushes content out of bounds\",transform:Fr,compileTime:!0,ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Effect\"}}},compute:E8({count:Bl,size:rfe,sites:X9,seedProp:\"seed\",seedDefault:2,output:\"voronoiField\"}),gpu:{fragment:e=>{let{childNode:t,ctx:s,computeOutputs:r,propValues:o,convertToTexture:a}=e;if(!t)return xt;let i=a(t),l=r?.voronoiField;if(!l)return W(Yt,\"unpremultiplyAlpha\",[i.sample(s.uv)]);let{onBeforeRender:c,getCpuValue:d,dimensions:u}=e,p=o.edges??0,_=afe(d),f=nfe(e,_),h=f.dataKit;c(F=>{let{pointer:q,deltaTime:Y}=F,V=u.width/Math.max(1,u.height);_.step(q,Y,V),f.upload()});let g=l.sample(s.uv,\"nearestClamp\"),y=g.member(\"r\"),b=g.member(\"g\"),x=\"nearestClamp\",P=(F,q)=>h.sample(W(ofe,\"cellLaneUV\",[F,$e(q)]),x).member(\"r\"),C=W(P8,\"crackGeom\",[s.uv,P(y,0),P(y,1),P(b,0),P(b,1),P(y,2),P(y,3),e.uniforms.crackWidth]),E=C.member(\"crackIntensity\"),R=C.member(\"edgeNormal\"),U=C.member(\"displacedUV\"),L=C.member(\"disp\"),k=F=>Ha(F,q=>i.sample(q),p),D=k(U),O=F=>W(C8,\"crackRefractUV\",[U,R,E,e.uniforms.refractionStrength,e.uniforms.chromaticSplit,$e(F)]);return W(Yt,\"unpremultiplyAlpha\",[W(M8,\"crackShardCompose\",[D,k(O(1)),k(O(0)),k(O(-1)),E,L,e.uniforms.shardLighting])])}}});var j9=H({name:\"SimplexNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Organic noise with animated movement\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:2,description:\"Pattern scale (higher = larger patterns)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},balance:{default:0,description:\"Balance between colors (negative = more colorB, positive = more colorA)\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.1,label:\"Balance\",group:\"Effect\"}},contrast:{default:0,description:\"Pattern contrast (higher = sharper transitions)\",ui:{type:[\"range\",\"map\"],min:-2,max:5,step:.1,label:\"Contrast\",group:\"Effect\"}},seed:{default:0,description:\"Random seed for pattern variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},speed:{default:1,description:\"Animation speed\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}}},paint:Vs(KD(Qa(hp(Tc(\"mx3signed\"),{rate:.5}),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var K9=H({name:\"SineWave\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Animated wave with thickness and softness\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{color:{default:\"#ffffff\",transform:ce,description:\"The color of the sine wave\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},amplitude:{default:.15,description:\"The height/amplitude of the sine wave\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Amplitude\",group:\"Effect\"}},frequency:{default:1,description:\"The frequency/number of wave cycles\",ui:{type:[\"range\",\"map\"],min:.1,max:20,step:.1,label:\"Frequency\",group:\"Effect\"}},speed:{default:1,description:\"The animation speed of the wave\",ui:{type:\"range\",min:-5,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},angle:{default:0,transform:cs,description:\"The rotation angle of the wave (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},position:{default:{x:.5,y:.5},transform:Xe,description:\"The center position of the wave\",ui:{type:\"position\",label:\"Position\",group:\"Position\"}},thickness:{default:.2,description:\"The thickness of the wave line\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Thickness\",group:\"Effect\"}},softness:{default:.4,description:\"Edge softness of the wave line\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Softness\",group:\"Effect\"}}},paint:DL({position:T(\"position\"),angle:T(\"angle\"),frequency:T(\"frequency\"),amplitude:T(\"amplitude\"),thickness:T(\"thickness\"),softness:T(\"softness\"),color:T(\"color\")})});var Q9=H({name:\"SliceWipe\",role:\"warp\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Slice the content into strips that slide away in alternating directions\",props:{progress:{default:.5,description:\"How far the strips have slid (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},angle:{default:0,description:\"Orientation of the strips in degrees (0 = vertical strips sliding up and down)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Transition\"}},sliceCount:{default:8,description:\"Number of strips across the frame\",ui:{type:[\"range\",\"map\"],min:2,max:60,step:1,label:\"Slices\",group:\"Transition\"}}},map:oU({angle:T(\"angle\"),count:T(\"sliceCount\"),progress:T(\"progress\")}),edges:1,resample:\"bilinear\",missingChildMessage:\"You must pass a child component into the Slice Wipe shader.\"});var Ba=256,qd=Ba*Ba,ife=10,lfe=.2,cfe=\"rgba16float\",Z9=Mn,J9=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,emitX:n,emitY:n,emitVelX:n,emitVelY:n,perpDirX:n,perpDirY:n,spreadFactor:n,emitRad:n,emitIntensity:n,dyeFade:n,velFade:n,curlStrength:n,gravity:n,cursorX:n,cursorY:n,cursorVelX:n,cursorVelY:n,mouseActive:n,mouseRadSq:n,colorDecay:n}),\"FluidParams\"),c5=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,qd),access:\"mutable\"},velB:{storage:Fe(S,qd),access:\"mutable\"},dyeA:{storage:Fe(S,qd),access:\"mutable\"},dyeB:{storage:Fe(S,qd),access:\"mutable\"},pressure:{storage:Fe(n,qd),access:\"mutable\"},divergence:{storage:Fe(n,qd),access:\"mutable\"},params:{uniform:J9}}),\"fluidLayout\"),eY=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({dyeA:{storage:Fe(S,qd),access:\"readonly\"},outTex:{storageTexture:zt(cfe,\"write-only\")}}),\"outputLayout\"),dfe=pp(c5,{n:Ba,namePrefix:\"smoke\",cone:!0,cursorPush:!0,densityGain:8,velocityBlendGain:3}),tY=zn(c5,{n:Ba,namePrefix:\"smoke\",boundary:\"clamped\",dye:\"densityAge\",dyeDissipation:!0,ageAdvance:!0}),{curl:W6e,vorticity:q6e,divergence:V6e,jacobi:N6e,gradSubtract:$6e,advectVel:X6e,copyVel:H6e,advectDye:j6e,copyDye:K6e}=tY,ufe=Ui(eY,{n:Ba,namePrefix:\"smoke\",dye:\"densityAge\"}),sY=H({name:\"Smoke\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Realistic fluid smoke simulation with vorticity dynamics\",usesPointer:!0,props:{colorA:{default:\"#fc83f9\",transform:ce,description:\"Color of fresh smoke\",ui:{type:\"color\",label:\"Start Color\",group:\"Colors\"}},colorB:{default:\"#c21c79\",transform:ce,description:\"Color smoke transitions to as it ages\",ui:{type:\"color\",label:\"End Color\",group:\"Colors\"}},stops:Ms(),emitFrom:{default:{x:.5,y:1},transform:Xe,description:\"The emission source point\",ui:{type:\"position\",label:\"Emit From\",group:\"Emission\"}},direction:{default:0,description:\"Emission direction (0 = up, 90 = right, 180 = down, 270 = left)\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Direction\",group:\"Emission\"}},speed:{default:20,description:\"Emission velocity strength\",ui:{type:\"range\",min:.1,max:50,step:.1,label:\"Speed\",group:\"Emission\"}},spread:{default:60,description:\"Emission cone angle in degrees\",ui:{type:\"range\",min:0,max:180,step:1,label:\"Spread\",group:\"Emission\"}},emitRadius:{default:.08,description:\"Size of the emission area\",ui:{type:\"range\",min:.01,max:.3,step:.01,label:\"Emit Size\",group:\"Emission\"}},intensity:{default:1,description:\"Smoke emission density\",ui:{type:\"range\",min:.1,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}},dissipation:{default:.2,description:\"How fast smoke fades over time\",ui:{type:\"range\",min:.1,max:3,step:.1,label:\"Dissipation\",group:\"Effect\"}},detail:{default:25,description:\"Fine-scale swirling detail\",ui:{type:\"range\",min:0,max:50,step:1,label:\"Detail\",group:\"Effect\"}},gravity:{default:.5,description:\"Downward gravitational pull on smoke\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Gravity\",group:\"Effect\"}},colorDecay:{default:.4,description:\"How quickly smoke shifts from Color A to Color B\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Color Decay\",group:\"Colors\"}},mouseInfluence:{default:.1,description:\"Strength of cursor influence\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Cursor Influence\",group:\"Interaction\"}},mouseRadius:{default:.1,description:\"Radius of cursor influence area\",ui:{type:\"range\",min:.02,max:.5,step:.01,label:\"Cursor Radius\",group:\"Interaction\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},...Ii(()=>({resolution:Ba,layout:c5,outputLayout:eY,paramsSchema:J9,solver:{kernels:tY,jacobiIters:ife},output:{kernel:ufe,key:\"smokeTexture\"},pointer:{minDrag:5e-4},inject:[Ug({kernel:dfe})],values:e=>{let t=e.num(\"speed\",3),s=e.num(\"direction\",0)*Math.PI/180,r=Math.min(89*Math.PI/180,e.num(\"spread\",45)*Math.PI/360),o=e.getCpuValue(\"emitFrom\"),a=o?.x??.5,i=o?.y??0,l=t*Ba*.15,c=e.num(\"mouseInfluence\",.5),d=e.num(\"mouseRadius\",.12),u=e.ptr,p=d*Ba,_=u.moving&&c>0;return{dt:e.dt,emitX:a*Ba,emitY:(1-i)*Ba,emitVelX:Math.sin(s)*l,emitVelY:-Math.cos(s)*l,perpDirX:Math.cos(s),perpDirY:Math.sin(s),spreadFactor:Math.tan(r),emitRad:e.num(\"emitRadius\",.06)*Ba,emitIntensity:e.num(\"intensity\",.7),dyeFade:e.num(\"dissipation\",1),velFade:lfe,curlStrength:e.num(\"detail\",30),gravity:e.num(\"gravity\",.5),colorDecay:e.num(\"colorDecay\",1),cursorX:_?u.x*Ba:0,cursorY:_?u.y*Ba:0,cursorVelX:_?u.dx*Ba*15*c:0,cursorVelY:_?u.dy*Ba*15*c:0,mouseActive:_?1:0,mouseRadSq:p*p}}})),gpu:{fragment:({ctx:e,computeOutputs:t,propValues:s,uniforms:r})=>{let o=t?.smokeTexture;if(!o)return xt;let a=o.sample(e.uv,\"linearClamp\"),i=a.member(\"x\"),l=a.member(\"y\"),c=s.colorSpace??0,d=s.stopCount??0,u;return d>1?u=En(l,{colorsArray:r.colorsArray,positionsArray:r.positionsArray,convertedColorsArray:r.convertedColorsArray,stopCount:r.stopCount},c):u=W(Z9.mixColorsVariants[c]??Z9.mixColorsLinear,\"mixColors\",[r.colorA,r.colorB,l]),Ct(u.member(\"rgb\"),u.member(\"a\").mul(i))}}});var{sdfSpaceUV:pfe}=ip,{createSvgSdfSampler:mfe,createSdfDataTexture:_fe,createAnalyticSdfSampler:ffe,driveAnalyticSubProps:vfe,ANALYTIC_SDF_EXTRA_FIELDS:hfe}=yc,{createVolumetricFieldComputeNode:gfe,buildVolumetricFieldSampler:yfe,VOLUMETRIC_FIELD_EXTRA_FIELDS:bfe}=kn,xfe=JSON.stringify({type:\"sphere3D\",radius:.35}),na=256,Lc=na*na,Afe=10,wfe=.2,Tfe=\"rgba16float\",rY=Mn,d5=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,emitX:n,emitY:n,emitVelX:n,emitVelY:n,perpDirX:n,perpDirY:n,spreadFactor:n,emitRad:n,emitIntensity:n,dyeFade:n,velFade:n,curlStrength:n,gravity:n,colorDecay:n,centerX:n,centerY:n,scale:n,rotation:n,aspect:n,cursorX:n,cursorY:n,cursorVelX:n,cursorVelY:n,mouseActive:n,mouseRadSq:n,saRadius:n,saSides:n,saRounding:n,saInnerRatio:n,saRotation:n,saHeight:n,saOffset:n,saAperture:n,vfOriginX:n,vfOriginY:n,vfSpanX:n,vfSpanY:n,vfActiveRes:n}),\"FillParams\"),u5=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,Lc),access:\"mutable\"},velB:{storage:Fe(S,Lc),access:\"mutable\"},dyeA:{storage:Fe(S,Lc),access:\"mutable\"},dyeB:{storage:Fe(S,Lc),access:\"mutable\"},pressure:{storage:Fe(n,Lc),access:\"mutable\"},divergence:{storage:Fe(n,Lc),access:\"mutable\"},maskBuf:{storage:Fe(S,Lc),access:\"readonly\"},params:{uniform:d5}}),\"fluidLayout\"),oY=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({dyeA:{storage:Fe(S,Lc),access:\"readonly\"},outTex:{storageTexture:zt(Tfe,\"write-only\")}}),\"outputLayout\"),Rp=Ez(d5,{n:na,namePrefix:\"smokeFill\"}),Sfe=Rp.analytic,Pfe=Rp.svgKernel,Cfe=Rp.fieldKernel,Mfe=pp(u5,{n:na,namePrefix:\"smokeFill\",cone:!0,cursorPush:!0,masked:!0,densityGain:8,velocityBlendGain:3}),aY=zn(u5,{n:na,namePrefix:\"smokeFill\",boundary:\"clamped\",dye:\"densityAge\",dyeDissipation:!0,ageAdvance:!0,solidMask:!0}),{curl:ewe,vorticity:twe,divergence:swe,jacobi:rwe,gradSubtract:owe,advectVel:awe,copyVel:nwe,advectDye:iwe,copyDye:lwe}=aY,Efe=Ui(oY,{n:na,namePrefix:\"smokeFill\",dye:\"densityAge\"});function kfe(e){let{getCpuValue:t}=e,s=t(\"shapeSdfUrl\")||\"\",r=bc(t(\"shapeType\")||\"\",t(\"shape\")),o=gfe(e,()=>t(\"shape\"),\"none\");return{setup(a){let{root:i}=a,l=a.buffers.maskBuf,c=a.paramsBuffer,d;if(o){let u=i.createBindGroup(Rp.fieldLayout,{maskBuf:l,params:c,fieldTex:o.fieldTexture});d=a.pass(Cfe,u)}else if(s){let u=_fe(a.params,s),p=i.createBindGroup(Rp.svgLayout,{maskBuf:l,params:c,sdfSource:u.texture.texture});d=a.pass(Pfe,p)}else{let u=i.createBindGroup(Rp.analyticLayout,{maskBuf:l,params:c});d=a.pass(Sfe(r),u)}return{maskPass:d,outputs:o?o.outputs:{},preFrame:u=>o?.getComputeNodes(u)??null}},domain:()=>o?.getFieldDomain()}}function Bfe(e){let t=(s,r)=>typeof s==\"number\"?s:r;return()=>{let s=e(\"shape\"),r={};if(s&&typeof s==\"object\")r=s;else if(typeof s==\"string\")try{r=JSON.parse(s)}catch{r={}}return{saRadius:t(r.radius,t(r.width,t(r.bottomWidth,.35))),saSides:t(r.sides,6),saRounding:t(r.rounding,0),saInnerRatio:t(r.innerRatio,t(r.thickness,t(r.spread,t(r.topWidth,t(r.topRatio,.4))))),saRotation:t(r.rotation,0),saHeight:t(r.height,.25),saOffset:t(r.offset,t(r.skew,.2)),saAperture:t(r.aperture,270)}}}var nY=H({name:\"SmokeFill\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Fill a shape with swirling fluid smoke that interacts with the shape boundary\",requiresRTT:!1,requiresChild:!1,usesPointer:!0,extraFields:{...bfe,...hfe},props:{colorA:{default:\"#8cf3ff\",transform:ce,description:\"Color of fresh smoke\",ui:{type:\"color\",label:\"Start Color\",group:\"Colors\"}},colorB:{default:\"#04a0d6\",transform:ce,description:\"Color smoke transitions to as it ages\",ui:{type:\"color\",label:\"End Color\",group:\"Colors\"}},origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},emitFrom:{default:{x:.5,y:.5},transform:Xe,description:\"Emission source point within the shape\",ui:{type:\"position\",label:\"Emit From\",group:\"Emission\"}},direction:{default:0,description:\"Emission direction (0 = up, 90 = right, 180 = down, 270 = left)\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Direction\",group:\"Emission\"}},speed:{default:10,description:\"Emission velocity strength\",ui:{type:\"range\",min:.1,max:30,step:.1,label:\"Speed\",group:\"Emission\"}},spread:{default:60,description:\"Emission cone angle in degrees\",ui:{type:\"range\",min:0,max:180,step:1,label:\"Spread\",group:\"Emission\"}},emitRadius:{default:.03,description:\"Size of the emission area\",ui:{type:\"range\",min:.01,max:.3,step:.01,label:\"Emit Size\",group:\"Emission\"}},intensity:{default:1,description:\"Smoke emission density\",ui:{type:\"range\",min:.1,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}},dissipation:{default:.3,description:\"How fast smoke fades over time\",ui:{type:\"range\",min:.1,max:5,step:.1,label:\"Dissipation\",group:\"Effect\"}},detail:{default:25,description:\"Fine-scale swirling detail\",ui:{type:\"range\",min:0,max:50,step:1,label:\"Detail\",group:\"Effect\"}},gravity:{default:.5,description:\"Downward gravitational pull on smoke \\u2014 0 = weightless, negative values = smoke rises\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Gravity\",group:\"Effect\"}},colorDecay:{default:.4,description:\"How quickly smoke shifts from Color A to Color B\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Color Decay\",group:\"Colors\"}},mouseInfluence:{default:.1,description:\"Strength of cursor influence\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Cursor Influence\",group:\"Interaction\"}},mouseRadius:{default:.1,description:\"Radius of cursor influence area\",ui:{type:\"range\",min:.02,max:.5,step:.01,label:\"Cursor Radius\",group:\"Interaction\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},shape:{default:xfe,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ii(e=>{let{getCpuValue:t}=e,s=kfe(e),r=Bfe(t);return{resolution:na,layout:u5,outputLayout:oY,paramsSchema:d5,solver:{kernels:aY,jacobiIters:Afe},output:{kernel:Efe,key:\"smokeTexture\"},pointer:{minDrag:5e-4},container:s,inject:[Ug({kernel:Mfe})],values:o=>{let a=o.num(\"speed\",2),i=o.num(\"direction\",0)*Math.PI/180,l=Math.min(89*Math.PI/180,o.num(\"spread\",60)*Math.PI/360),c=t(\"center\"),d=t(\"emitFrom\"),u=o.frameParams.dimensions?.height??0,p=u>0?(o.frameParams.dimensions?.width??0)/u:1,_=a*na*.15,f=r(),h=o.num(\"mouseInfluence\",.5),g=o.num(\"mouseRadius\",.12),y=o.ptr,b=y.moving&&h>0,x=g*na,P=s.domain();return{dt:o.dt,emitX:(d?.x??.5)*na,emitY:(1-(d?.y??.5))*na,emitVelX:Math.sin(i)*_,emitVelY:-Math.cos(i)*_,perpDirX:Math.cos(i),perpDirY:Math.sin(i),spreadFactor:Math.tan(l),emitRad:o.num(\"emitRadius\",.03)*na,emitIntensity:o.num(\"intensity\",.8),dyeFade:o.num(\"dissipation\",.5),velFade:wfe,curlStrength:o.num(\"detail\",30),gravity:o.num(\"gravity\",.5),colorDecay:o.num(\"colorDecay\",1),centerX:c?.x??.5,centerY:1-(c?.y??.5),scale:o.num(\"scale\",1),rotation:o.num(\"rotation\",0)*Math.PI/180,aspect:p,cursorX:b?y.x*na:0,cursorY:b?y.y*na:0,cursorVelX:b?y.dx*na*15*h:0,cursorVelY:b?y.dy*na*15*h:0,mouseActive:b?1:0,mouseRadSq:x*x,...f,vfOriginX:P?.originX??0,vfOriginY:P?.originY??0,vfSpanX:P?.spanX??1,vfSpanY:P?.spanY??1,vfActiveRes:P?.activeRes??1}}}}),gpu:{fragment:e=>{let{ctx:t,computeOutputs:s,propValues:r,uniforms:o,getCpuValue:a}=e,i=s?.smokeTexture;if(!i)return xt;let l,c=s?.volumetricFieldTexture;if(c)l=yfe(c,{originX:o._vfOriginX,originY:o._vfOriginY,spanX:o._vfSpanX,spanY:o._vfSpanY,activeResF:o._vfActiveRes,rBound:o._vfRBound}).volumetricFieldSampler;else{let y=r.shapeSdfUrl||\"\";y?l=mfe(e,y):l=ffe(bc(r.shapeType||\"\",a(\"shape\")),vfe(e,()=>a(\"shape\")))}let d=W(pfe,\"sdfSpaceUV\",[o.center,o.scale,o.rotation,t.uv,t.aspect]),u=Ge(v(l(d).member(\"x\"),-(na*4)),0,1),p=i.sample(t.uv,\"linearClamp\"),_=p.member(\"x\"),f=p.member(\"y\"),h=r.colorSpace??0,g=W(rY.mixColorsVariants[h]??rY.mixColorsLinear,\"mixColors\",[o.colorA,o.colorB,f]);return Ct(g.member(\"rgb\"),g.member(\"a\").mul(_).mul(u))}}});var ci=256,Vd=ci*ci,zfe=10,Rfe=.2,Dfe=16,Lfe=\"rgba16float\",iY=Mn,lY=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({dt:n,emitX:n,emitY:n,emitVelX:n,emitVelY:n,emitGate:n,emitRad:n,emitIntensity:n,dyeFade:n,velFade:n,curlStrength:n,gravity:n,colorDecay:n}),\"FlowParams\"),p5=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({velA:{storage:Fe(S,Vd),access:\"mutable\"},velB:{storage:Fe(S,Vd),access:\"mutable\"},dyeA:{storage:Fe(S,Vd),access:\"mutable\"},dyeB:{storage:Fe(S,Vd),access:\"mutable\"},pressure:{storage:Fe(n,Vd),access:\"mutable\"},divergence:{storage:Fe(n,Vd),access:\"mutable\"},params:{uniform:lY}}),\"fluidLayout\"),cY=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(w.bindGroupLayout({dyeA:{storage:Fe(S,Vd),access:\"readonly\"},outTex:{storageTexture:zt(Lfe,\"write-only\")}}),\"outputLayout\"),Ufe=pp(p5,{n:ci,namePrefix:\"smokeFlow\",cone:!1,cursorPush:!1,gated:!0,densityGain:10,velocityBlendGain:4}),dY=zn(p5,{n:ci,namePrefix:\"smokeFlow\",boundary:\"clamped\",dye:\"densityAge\",dyeDissipation:!0,ageAdvance:!0}),{curl:pwe,vorticity:mwe,divergence:_we,jacobi:fwe,gradSubtract:vwe,advectVel:hwe,copyVel:gwe,advectDye:ywe,copyDye:bwe}=dY,Ofe=Ui(cY,{n:ci,namePrefix:\"smokeFlow\",dye:\"densityAge\"}),uY=H({name:\"SmokeFlow\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Interactive\",description:\"Cursor-driven smoke that lingers, swirls, and dissipates with fluid dynamics\",usesPointer:!0,props:{colorA:{default:\"#e29c8b\",transform:ce,description:\"Color of fresh smoke\",ui:{type:\"color\",label:\"Fresh Color\",group:\"Colors\"}},colorB:{default:\"#d517f9\",transform:ce,description:\"Color smoke transitions to as it ages\",ui:{type:\"color\",label:\"Aged Color\",group:\"Colors\"}},stops:Ms(),intensity:{default:1,description:\"How much smoke is emitted as you move the cursor\",ui:{type:\"range\",min:.1,max:2,step:.05,label:\"Intensity\",group:\"Emission\"}},emitRadius:{default:.07,description:\"Size of smoke puff emitted at cursor\",ui:{type:\"range\",min:.01,max:.3,step:.01,label:\"Puff Size\",group:\"Emission\"}},momentum:{default:20,description:\"How much cursor velocity is transferred into the smoke (higher = more directed flow)\",ui:{type:\"range\",min:0,max:50,step:1,label:\"Momentum\",group:\"Emission\"}},dissipation:{default:.5,description:\"How fast smoke fades over time\",ui:{type:\"range\",min:.05,max:3,step:.05,label:\"Dissipation\",group:\"Effect\"}},detail:{default:10,description:\"Fine-scale swirling detail driven by vorticity confinement\",ui:{type:\"range\",min:0,max:60,step:1,label:\"Swirl Detail\",group:\"Effect\"}},gravity:{default:2,description:\"Vertical drift \\u2014 negative floats up, positive sinks down\",ui:{type:\"range\",min:-5,max:5,step:.05,label:\"Gravity\",group:\"Effect\"}},colorDecay:{default:.5,description:\"How quickly smoke shifts from fresh to aged color\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Color Decay\",group:\"Colors\"}},colorSpace:{default:\"OKLAB\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},...Ii(()=>{let e=s=>Math.min(s*s*60,1),t=Og({tracker:{teleportGuard:Number.POSITIVE_INFINITY},activeWhen:s=>e(s.smoothSpeed)>.005,fadeSeconds:s=>jh(255,s.num(\"dissipation\",.4)),pass:{kernel:Ufe},ribbon:(s,r,o)=>({stepSize:Math.max(.004,s.num(\"emitRadius\",.07)*.5),maxSteps:Dfe,write:(a,i)=>s.writeParams({...o,emitX:a,emitY:i})})});return{resolution:ci,layout:p5,outputLayout:cY,paramsSchema:lY,solver:{kernels:dY,jacobiIters:zfe},output:{kernel:Ofe,key:\"smokeTexture\"},inject:[t],values:s=>{let r=t.ptr(),o=s.num(\"momentum\",1.2),a=e(r.smoothSpeed),i=t.active(),l=s.num(\"emitRadius\",.07);return{dt:s.dt,emitX:r.x*ci,emitY:r.y*ci,emitGate:i?a:0,emitVelX:r.smoothVelX*ci*o*.12,emitVelY:r.smoothVelY*ci*o*.12,emitRad:l*ci,emitIntensity:s.num(\"intensity\",1.2),dyeFade:s.num(\"dissipation\",.4),velFade:Rfe,curlStrength:s.num(\"detail\",28),gravity:s.num(\"gravity\",-.3),colorDecay:s.num(\"colorDecay\",.5)}}}}),gpu:{fragment:({ctx:e,computeOutputs:t,propValues:s,uniforms:r})=>{let o=t?.smokeTexture;if(!o)return xt;let a=o.sample(e.uv,\"linearClamp\"),i=a.member(\"x\"),l=a.member(\"y\"),c=s.colorSpace??0,d=s.stopCount??0,u;return d>1?u=En(l,{colorsArray:r.colorsArray,positionsArray:r.positionsArray,convertedColorsArray:r.convertedColorsArray,stopCount:r.stopCount},c):u=W(iY.mixColorsVariants[c]??iY.mixColorsLinear,\"mixColors\",[r.colorA,r.colorB,l]),Ct(u.member(\"rgb\"),u.member(\"a\").mul(i))}}});var pY=H({name:\"Solarize\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Inverts tones above a luminance threshold \\u2014 a classic darkroom and photo effect\",props:{threshold:{default:.5,description:\"Luminance level above which colors are inverted. Pixels brighter than this threshold get flipped.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Threshold\",group:\"Effect\"}},strength:{default:1,description:\"Blend between original (0) and fully solarized (1)\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}}},effect:l8({threshold:T(\"threshold\"),strength:T(\"strength\")}),identityWhen:Uo(\"strength\"),missingChildMessage:\"You must pass a child component into the Solarize shader.\"});var mY=H({name:\"SolidColor\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null},category:\"Textures\",description:\"Fill the canvas with a single solid color\",acceptsUVContext:!0,props:{color:{default:\"#5b18ca\",transform:ce,description:\"The solid color to display\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}}},paint:GR(T(\"color\"))});var Gfe=[1,2/3],Ffe=.12,ly={core:.9,rayWidth:1.6,rayLength:.45,rays:.25},m5={minRate:.8,rateSpread:1.2,sharpness:8},Ife=.45,_Y=.35,Yfe=.6,Wfe=[.2126,.7152,.0722],qfe=4;function Vfe(e,t,s,r,o){let a=e.uniforms,i=z(v(a.size,s),`sparkleCell${r}`),l=(e.propValues.expand??0)>0,c=z(Ce(rt(a.expand,a.expand),e.ctx.logicalViewportSize),`sparkleExpand${r}`),d=z(Ce(ly.rayLength,it(a.rayLength,.01)),`sparkleRays${r}`);return qR(t,{cellSize:i,jitter:.6,seed:I(a.seed,r*.31)}).map(({point:u,offset:p,random:_})=>{let f=mU(e.sampleStraight,Ce(u,e.ctx.logicalViewportSize),{radius:c,taps:l?qfe:0,angle:r*45}),h=ot(a.threshold,I(a.threshold,Ffe),ho(f.luma)),g=cU(o,{rate:I(m5.minRate,v(_.member(\"z\"),m5.rateSpread)),offset:v(_.member(\"x\"),6.283185307179586),sharpness:m5.sharpness}),y=I(_Y,v(1-_Y,ag(Ife,_.member(\"z\")))),b=TD(p,{core:ly.core,rayWidth:ly.rayWidth,rayLength:d,rays:ly.rays,reach:v(i,.5)}),x=z(f.color.member(\"rgb\"),\"sparkleRgb\"),P=v(Ce(x,it($t(x,Qe(...Wfe)),.001)),Yfe);return v(et(kt(1),P,a.colorize),v(v(v(b,g),h),v(y,a.intensity)))}).reduce((u,p)=>I(u,p))}var fY=H({name:\"Sparkle\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Twinkling star glints over the bright parts of the layer inside\",animatedTime:{speed:\"speed\"},props:{size:{default:100,description:\"Spacing between glints, in CSS pixels (smaller means more glints)\",ui:{type:[\"range\",\"map\"],min:10,max:200,step:1,label:\"Spacing\",group:\"Effect\"}},intensity:{default:10,description:\"Brightness of the glints\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Intensity\",group:\"Effect\"}},threshold:{default:.2,description:\"How bright the layer must be before glints appear: 0 allows all but black, 0.5 is mid-grey and up, 1 only pure white\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Threshold\",group:\"Effect\"}},expand:{default:0,description:\"Lets glints appear up to this many CSS pixels outside the bright areas\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Expand\",group:\"Effect\"}},rayLength:{default:5,description:\"Length of the four rays around each glint (they fade out by half the spacing)\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Ray Length\",group:\"Effect\"}},colorize:{default:.45,description:\"How much each glint takes on the colour beneath it (0 is pure white)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Colorize\",group:\"Effect\"}},speed:{default:1,description:\"How fast the glints twinkle\",ui:{type:\"range\",min:0,max:5,step:.05,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Re-rolls where the glints sit and when they blink\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}}},identityWhen:Uo(\"intensity\"),effect:$o(e=>{let t=z(v(e.ctx.uv,e.ctx.logicalViewportSize),\"sparklePx\"),s=z(wt(e),\"sparkleT\"),r=z(Gfe.map((i,l)=>Vfe(e,t,i,l,s)).reduce((i,l)=>I(i,l)),\"sparkleGlow\"),o=z(e.texture.sample(e.ctx.uv),\"sparkleChild\"),a=it(it(r.member(\"r\"),r.member(\"g\")),r.member(\"b\"));return Ot(I(o.member(\"rgb\"),r),Yr(I(o.member(\"a\"),a),1))},[]),missingChildMessage:\"You must pass a child component into the Sparkle shader.\"});var vY=wU({center:T(\"center\"),radius:T(\"radius\"),depth:T(\"depth\")}),hY=H({name:\"Spherize\",role:\"filter\",species:\"gather\",category:\"Distortions\",description:\"Map content onto a 3D sphere surface with depth distortion\",boundingBoxDeclaration:{aspectRatio:null},props:{radius:{default:1,description:\"Radius of the sphere (1 = half viewport height)\",ui:{type:[\"range\",\"map\"],min:.1,max:3,step:.1,label:\"Radius\",group:\"Effect\"}},depth:{default:1,description:\"How much the sphere bulges toward viewer (0 = flat, higher = more bulge)\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.1,label:\"Depth\",group:\"Effect\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the sphere\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},lightPosition:{default:{x:.3,y:.3},transform:Xe,description:\"Position of the specular light source\",ui:{type:\"position\",label:\"Light Position\",group:\"Position\"}},lightIntensity:{default:.5,description:\"Intensity of the rim light (0 = off)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Light Intensity\",group:\"Effect\"}},lightSoftness:{default:.5,description:\"Softness of the rim light falloff (0 = hard edge, 1 = soft glow)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Light Softness\",group:\"Effect\"}},lightColor:{default:\"#ffffff\",transform:ce,description:\"Color of the specular highlight\",ui:{type:\"color\",label:\"Light Color\",group:\"Effect\"}}},effect:$o(TU(vY),[SU(vY,{position:T(\"lightPosition\"),intensity:T(\"lightIntensity\"),softness:T(\"lightSoftness\"),color:T(\"lightColor\")})],{resultAlpha:\"straight\"})});var gY=H({name:\"Spiral\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Rotating spiral pattern with animated movement\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#000000\",transform:ce,description:\"Background color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Spiral stroke color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},strokeWidth:{default:.5,description:\"Thickness of spiral stroke\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.1,label:\"Stroke Width\",group:\"Effect\"}},strokeFalloff:{default:0,description:\"Stroke losing width further from center\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Stroke Falloff\",group:\"Effect\"}},softness:{default:0,description:\"Color transition sharpness (0 = hard edge, 1 = smooth fade)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Softness\",group:\"Effect\"}},speed:{default:1,description:\"Animation speed (negative values reverse direction)\",ui:{type:\"range\",min:-3,max:3,step:.1,label:\"Speed\",group:\"Animation\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"The center point of the spiral\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},scale:{default:1,description:\"Scale factor for spiral bands (higher = more bands, lower = fewer bands)\",ui:{type:[\"range\",\"map\"],min:.1,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Vs(Oi.spiral({center:T(\"center\"),scale:T(\"scale\"),width:T(\"strokeWidth\"),falloff:T(\"strokeFalloff\"),softness:T(\"softness\")}),xR(T(\"colorA\"),T(\"colorB\"),T(\"colorSpace\")))});var yY=H({role:\"shape\",name:\"Star\",description:\"Classic star polygon with straight sides and sharp pointed tips\",shape:{distance:({x:e,y:t},s)=>cR(e,t,s(\"radius\"),s(\"sides\"),s(\"innerRatio\")),colorDescription:\"Fill color of the star\",centerDescription:\"Center position of the star\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.4,description:\"Outer tip radius \\u2014 distance from center to the pointed tips\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Radius\",group:\"Shape\"}},sides:{default:5,description:\"Number of points on the star\",ui:{type:\"range\",min:3,max:12,step:1,label:\"Points\",group:\"Shape\"}},innerRatio:{default:.4,description:\"Inner vertex radius as a ratio of outer radius (0.382 = golden-ratio 5-star)\",ui:{type:\"range\",min:.1,max:.9,step:.01,label:\"Inner Ratio\",group:\"Shape\"}}}}});var bY=H({name:\"Stone\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Applies a marbled stone relief and surface distortion to child content\",requiresRTT:!0,requiresChild:!0,props:Gg({intensity:.5,scale:1,contrast:0,distortion:.15}),gpu:{fragment:gg(hg.stone)}});var xY=H({name:\"Strands\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Flowing ribbons of light with a multi-color gradient\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},extraAnimatedTimes:{color:\"colorSpeed\"},props:{speed:{default:.5,description:\"Overall animation speed\",ui:{type:\"range\",min:0,max:2,step:.1,label:\"Speed\",group:\"Animation\"}},amplitude:{default:2,description:\"How far the strands wave away from their resting line\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Amplitude\",group:\"Effect\"}},frequency:{default:.3,description:\"How many waves run along each strand\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Frequency\",group:\"Effect\"}},lineCount:{default:8,description:\"Number of strands\",ui:{type:\"range\",min:1,max:16,step:1,label:\"Strand Count\",group:\"Effect\"}},lineWidth:{default:.05,description:\"Thickness of each strand\\u2019s solid core\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Strand Width\",group:\"Effect\"}},softness:{default:.05,description:\"Softness of each strand\\u2019s edge (0 is crisp, higher is feathered)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Strand Softness\",group:\"Effect\"}},spread:{default:.2,description:\"How far the strands fan out across the field\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Spread\",group:\"Effect\"}},pinEdges:{default:!1,transform:rs,description:\"Pin the strands so they converge to the start and end points\",ui:{type:\"checkbox\",label:\"Pin Edges\",group:\"Effect\"}},stops:{...Ms(),default:[{color:\"#00e5ff\",position:0},{color:\"#5b8cff\",position:.34},{color:\"#b06bff\",position:.67},{color:\"#ff5fa2\",position:1}]},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space used to blend the gradient\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},colorScale:{default:1,description:\"How many times the gradient repeats along the strands\",ui:{type:[\"range\",\"map\"],min:1,max:6,step:1,label:\"Color Scale\",group:\"Colors\"}},colorVariance:{default:1,description:\"At 0 every strand shares the same color; at 1 the strands spread across the full gradient\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.05,label:\"Color Variance\",group:\"Colors\"}},colorSpeed:{default:1,description:\"Speed at which the colors flow along the strands (loops)\",ui:{type:\"range\",min:0,max:2,step:.05,label:\"Color Speed\",group:\"Colors\"}},start:{default:{x:0,y:.5},transform:Xe,description:\"Starting point of the strands\",ui:{type:\"position\",label:\"Start\",group:\"Position\"}},end:{default:{x:1,y:.5},transform:Xe,description:\"Ending point of the strands\",ui:{type:\"position\",label:\"End\",group:\"Position\"}}},paint:oL(iL({from:T(\"start\"),to:T(\"end\"),count:T(\"lineCount\"),width:T(\"lineWidth\"),amplitude:T(\"amplitude\"),frequency:T(\"frequency\"),softness:T(\"softness\"),spread:T(\"spread\"),pinEdges:T(\"pinEdges\"),colorScale:T(\"colorScale\"),colorVariance:T(\"colorVariance\")}),aL({space:T(\"colorSpace\")}),nL())});var AY=H({name:\"Stretch\",role:\"warp\",category:\"Distortions\",description:\"Stretch content towards a direction from a center point\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point of the stretch effect\"),strength:{default:1,description:\"The intensity of the stretch effect\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},angle:{default:0,description:\"The direction of the stretch in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},falloff:{default:0,description:\"Controls the sharpness of the transition (0 = sharp edge, 1 = gradual transition)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},map:KL({center:T(\"center\"),strength:T(\"strength\"),angle:T(\"angle\"),falloff:T(\"falloff\")}),missingChildMessage:\"You must pass a child component into the Stretch shader.\"});var wY=H({name:\"Stripes\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Alternating colored stripes with animation\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#000000\",transform:ce,description:\"First stripe color\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Second stripe color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},angle:{default:45,transform:cs,description:\"Angle of stripes in degrees\",ui:{type:[\"range\",\"map\"],min:-180,max:180,step:1,label:\"Angle\",group:\"Effect\"}},density:{default:5,description:\"Number of stripe pairs visible\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:1,label:\"Density\",group:\"Effect\"}},balance:{default:.5,description:\"Ratio of the two colors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Balance\",group:\"Effect\"}},softness:{default:0,description:\"Edge softness\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Softness\",group:\"Effect\"}},speed:{default:.2,description:\"Animation speed\",ui:{type:\"range\",min:-1,max:1,step:.1,label:\"Speed\",group:\"Animation\"}},offset:{default:0,description:\"Phase offset for pattern positioning\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Offset\",group:\"Animation\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:T(\"colorA\"),stroke:T(\"colorB\"),mask:$R({angle:T(\"angle\"),density:T(\"density\"),balance:T(\"balance\"),softness:T(\"softness\"),offset:T(\"offset\")}),space:T(\"colorSpace\")})});var TY=Math.PI*2,SY=H({name:\"StudioBackground\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Multi-light studio background with ambient motion.\",extraFields:{ambPosA:{schema:S,initial:[0,0,0,0]},ambPosB:{schema:S,initial:[0,0,0,0]},ambSizeSq:{schema:S,initial:[.01,.01,.01,.01]}},props:{color:{default:\"#d8dbec\",transform:ce,description:\"Base studio surface color\",ui:{type:\"color\",label:\"Surface Color\",group:\"Colors\"}},keyColor:{default:\"#d5e4ea\",transform:ce,description:\"Color of the overhead key light\",ui:{type:\"color\",label:\"Key Color\",group:\"Key Light\"}},keyIntensity:{default:40,description:\"Intensity of the key light\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Key Light\"}},keySoftness:{default:50,description:\"How diffuse the key light is\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Softness\",group:\"Key Light\"}},fillColor:{default:\"#d5e4ea\",transform:ce,description:\"Color of the side fill lights\",ui:{type:\"color\",label:\"Fill Color\",group:\"Fill Lights\"}},fillIntensity:{default:10,description:\"Intensity of the fill lights\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Fill Lights\"}},fillSoftness:{default:70,description:\"How diffuse the fill lights are\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Softness\",group:\"Fill Lights\"}},fillAngle:{default:70,description:\"How far apart the fill lights are from center\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Spread\",group:\"Fill Lights\"}},backColor:{default:\"#c8d4e8\",transform:ce,description:\"Color of the upward back wash\",ui:{type:\"color\",label:\"Back Color\",group:\"Back Light\"}},backIntensity:{default:20,description:\"Intensity of the back wash\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Back Light\"}},backSoftness:{default:80,description:\"How diffuse the back wash is\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Softness\",group:\"Back Light\"}},brightness:{default:20,description:\"Overall ambient light level\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Ambient\",group:\"Lighting\"}},vignette:{default:0,description:\"Edge darkening\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Vignette\",group:\"Lighting\"}},center:{default:{x:.5,y:.8},transform:Xe,description:\"Where the spotlight meets the floor\",ui:{type:\"position\",label:\"Stage Center\",group:\"Scene\"}},lightTarget:{default:100,description:\"How far toward the floor vs wall the spotlights aim\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Light Depth\",group:\"Scene\"}},wallCurvature:{default:10,description:\"How rounded the cove is\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Wall Curvature\",group:\"Scene\"}},ambientIntensity:{default:50,description:\"Intensity of drifting ambient lights\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Ambient Detail\",group:\"Environment\"}},ambientSpeed:{default:2,description:\"Drift speed\",ui:{type:\"range\",min:-5,max:5,step:.1,label:\"Speed\",group:\"Environment\"}},seed:{default:0,description:\"Seed for ambient pattern\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Environment\"}}},paint:e=>{let{uniforms:t}=e,{uv:s,viewport:r}=aa(e),o=z(Ce(r.member(\"x\"),it(r.member(\"y\"),1e-6)),\"aspect\"),a=Me=>me(T(Me),e),i=z(v(a(\"brightness\"),.02),\"sbBrightness\"),l=z(v(a(\"keyIntensity\"),.015),\"sbKeyInt\"),c=z(v(a(\"fillIntensity\"),.015),\"sbFillInt\"),d=v(a(\"fillAngle\"),.005),u=v(a(\"backIntensity\"),.015),p=z(v(a(\"lightTarget\"),.01),\"sbTarget\"),_=z(v(a(\"wallCurvature\"),.01),\"sbCurvature\"),f=et(5,.8,v(a(\"keySoftness\"),.01)),h=et(5,.8,v(a(\"fillSoftness\"),.01)),g=z(et(5,.8,v(a(\"backSoftness\"),.01)),\"sbBackDecay\"),y=z(a(\"center\").member(\"x\"),\"coveCenterX\"),b=z(ne(1,a(\"center\").member(\"y\")),\"coveCenterY\"),x=z(et(.015,.15,_),\"coveTransition\"),P=z(ot(ne(b,x),I(b,x),s.member(\"y\")),\"coveIsFloor\"),C=z(ne(1,P),\"coveNotFloor\"),E=z(Ge(Ce(s.member(\"y\"),it(b,1e-6)),0,1),\"coveWallY\"),R=z(v(E,E),\"coveWallY2\"),U=Ge(Ce(ne(s.member(\"y\"),b),it(ne(1,b),1e-6)),0,1),L=z(v(ne(s.member(\"x\"),y),o),\"coveX\"),k=z(et(.05,.45,R),\"coveCone\"),D=v(ne(1,E),1.2),O=z(v(D,D),\"coveWallFall\"),F=I(b,v(ne(1,b),.3)),q=v(ne(s.member(\"y\"),F),4),Y=z(v(q,q),\"coveFloorFall\"),V=v(et(et(.2,.4,E),et(.38,.18,U),P),i),X=Ce(ne(s.member(\"y\"),b),I(x,.001)),Q=z(I(V,v(v(v(tr(v(v(-.5,X),X)),_),i),.1)),\"sbBase\"),te=z(I(v(ne(1,p),1.4),.3),\"sbWallBias\"),J=z(I(v(p,1.4),.3),\"sbFloorBias\"),oe=(Me,we)=>{let Ve=et(Me,y,R),qe=Ce(v(ne(s.member(\"x\"),Ve),o),k),st=v(v(tr(v(er(I(v(qe,qe),O)),we)),C),te),pt=et(y,Me,.25),Ze=v(v(ne(s.member(\"x\"),pt),o),1.4);return I(st,v(v(tr(v(er(I(v(Ze,Ze),Y)),v(we,1.5))),P),J))},le=z(Qe(Q,Q,Q),\"sbLight0\");le=I(le,v(a(\"keyColor\").member(\"rgb\"),v(z(oe(y,f),\"sbKey\"),l)));let se=I(v(z(oe(ne(y,d),h),\"sbFillL\"),c),v(z(oe(I(y,d),h),\"sbFillR\"),c));le=I(le,v(a(\"fillColor\").member(\"rgb\"),se));let Te=v(q_(v(L,.5),v(ne(s.member(\"y\"),et(1,b,.15)),4),g),P),de=v(v(q_(v(L,.6),v(ne(b,s.member(\"y\")),3),v(g,.8)),C),R);le=I(le,v(a(\"backColor\").member(\"rgb\"),v(I(Te,de),u)));let xe=v(v(q_(v(L,.7),v(I(ne(s.member(\"y\"),b),.02),10),It(2.5)),v(l,.12)),C);le=I(le,kt(xe));let Ae=ne(b,.2),De=I(I(I(W_({uv:s,aspect:o,x:I(y,t.ambPosA.member(\"x\")),y:I(Ae,t.ambPosA.member(\"y\")),sizeSq:t.ambSizeSq.member(\"x\")}),W_({uv:s,aspect:o,x:I(y,t.ambPosA.member(\"z\")),y:I(Ae,t.ambPosA.member(\"w\")),sizeSq:t.ambSizeSq.member(\"y\")})),W_({uv:s,aspect:o,x:I(y,t.ambPosB.member(\"x\")),y:I(Ae,t.ambPosB.member(\"y\")),sizeSq:t.ambSizeSq.member(\"z\")})),W_({uv:s,aspect:o,x:I(y,t.ambPosB.member(\"z\")),y:I(Ae,t.ambPosB.member(\"w\")),sizeSq:t.ambSizeSq.member(\"w\")}));le=I(le,kt(v(De,v(v(a(\"ambientIntensity\"),.012),.25))));let Ee=0,ze=NaN,Ie=[];e.onBeforeRender(Me=>{Ee+=(Me?.deltaTime??0)*(e.getCpuValue(\"ambientSpeed\")??2);let we=e.getCpuValue(\"seed\")??0;if(we!==ze){ze=we,Ie=[];for(let qe=0;qe<4;qe++){let st=we+qe*73.1,pt=wc(st+311)*.12+.1;Ie.push({sizeSq:pt*pt,radiusX:wc(st)*.5+.2,radiusY:wc(st+37)*.25+.1,freqX:wc(st+91)*.3+.1,freqY:wc(st+143)*.25+.08,phaseX:wc(st+200)*TY,phaseY:wc(st+257)*TY})}}let Ve=Ie.map(qe=>[Math.sin(Ee*qe.freqX+qe.phaseX)*qe.radiusX,Math.cos(Ee*qe.freqY+qe.phaseY)*qe.radiusY]);e.setExtraField(\"ambPosA\",[Ve[0][0],Ve[0][1],Ve[1][0],Ve[1][1]]),e.setExtraField(\"ambPosB\",[Ve[2][0],Ve[2][1],Ve[3][0],Ve[3][1]]),e.setExtraField(\"ambSizeSq\",[Ie[0].sizeSq,Ie[1].sizeSq,Ie[2].sizeSq,Ie[3].sizeSq])});let ke=RD({strength:T(\"vignette\"),scale:.025})(e);return Ot(Ge(v(v(a(\"color\").member(\"rgb\"),Ge(le,kt(0),kt(3))),ke),kt(0),kt(1)),1)}});var PY=H({name:\"SunBurst\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Radial sunburst rays emanating from a center point\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{color:{default:\"#ffdd88\",transform:ce,description:\"Ray color\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},background:{default:\"#000000\",transform:ce,description:\"Background color\",ui:{type:\"color\",label:\"Background\",group:\"Colors\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center point of the sunburst\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},rayCount:{default:12,description:\"Number of rays\",ui:{type:\"range\",min:3,max:64,step:1,label:\"Ray Count\",group:\"Effect\"}},softness:{default:.3,description:\"Softness of ray edges\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},radius:{default:.8,description:\"How far the rays extend from the center\",ui:{type:[\"range\",\"map\"],min:0,max:1.2,step:.01,label:\"Radius\",group:\"Effect\"}},feather:{default:.5,description:\"How gradually the rays fade at their outer edge\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.01,label:\"Feather\",group:\"Effect\"}},speed:{default:.2,description:\"Rotation speed \\u2014 positive values rotate clockwise\",ui:{type:\"range\",min:-2,max:2,step:.1,label:\"Speed\",group:\"Animation\"}}},paint:LD({color:T(\"color\"),background:T(\"background\"),coverage:vg(mD(T(\"center\")),vD(hD({count:T(\"rayCount\"),softness:T(\"softness\"),spin:-1}),gD({radius:T(\"radius\"),feather:T(\"feather\")})),\"burstFrame\"),hint:\"burstAlpha\"})});var _5=Rr()?960:1600,CY=1600,MY=900,Nfe=Rr()?12:16,$fe=6,EY=bt,kY=H({name:\"Surface3D\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Distortions\",description:\"Drapes child content over a 3D wave surface with perspective and lighting\",requiresRTT:!0,requiresChild:!0,usesPointer:!0,providesUVContextViaCompute:!0,props:{amplitude:{default:.3,description:\"Wave height\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Amplitude\",group:\"Waves\"}},waveType:{default:\"fractal\",compileTime:!0,description:\"Wave pattern type\",ui:{type:\"select\",options:[{label:\"Fractal\",value:\"fractal\"},{label:\"Sine\",value:\"sine\"},{label:\"Ridge\",value:\"ridge\"}],label:\"Wave Type\",group:\"Waves\"}},frequency:{default:1.5,description:\"Wave frequency\",ui:{type:\"range\",min:.1,max:5,step:.1,label:\"Frequency\",group:\"Waves\"}},octaves:{default:2,recompile:hn((e,t)=>Math.max(1,Math.floor(e))!==Math.max(1,Math.floor(t))),description:\"Detail octaves\",ui:{type:\"range\",min:1,max:5,step:1,label:\"Octaves\",group:\"Waves\"}},seed:{default:0,description:\"Random seed offset\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Waves\"}},speed:{default:.5,description:\"Animation speed\",ui:{type:\"range\",min:0,max:3,step:.1,label:\"Speed\",group:\"Waves\"}},tilt:{default:35,description:\"Camera tilt in degrees\",ui:{type:\"range\",min:0,max:85,step:1,label:\"Tilt\",group:\"Camera\"}},roll:{default:0,description:\"Camera roll in degrees\",ui:{type:\"range\",min:-45,max:45,step:1,label:\"Roll\",group:\"Camera\"}},height:{default:0,description:\"Camera height\",ui:{type:\"range\",min:-1,max:2,step:.01,label:\"Height\",group:\"Camera\"}},zoom:{default:1,description:\"Camera zoom\",ui:{type:\"range\",min:.3,max:3,step:.01,label:\"Zoom\",group:\"Camera\"}},nearCutoff:{default:0,description:\"Near fade distance\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Near Cutoff\",group:\"Camera\"}},farCutoff:{default:1,description:\"Far fade distance\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Far Cutoff\",group:\"Camera\"}},edgePinning:{default:0,description:\"Smoothly flatten the surface at its edges (orthogonal to edge mode)\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Pinning\",group:\"Waves\"}},edges:{default:\"mirror\",transform:Fr,compileTime:!0,description:\"How to handle content beyond the surface bounds\",ui:{type:\"select\",options:[{label:\"Stretch\",value:\"stretch\"},{label:\"Transparent\",value:\"transparent\"},{label:\"Mirror\",value:\"mirror\"},{label:\"Wrap\",value:\"wrap\"}],label:\"Edges\",group:\"Waves\"}},lighting:{default:30,recompile:hn((e,t)=>e<.01!=t<.01),description:\"Intensity of lighting and shading\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Lighting\",group:\"Lighting\"}},glossiness:{default:0,description:\"Surface glossiness\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Glossiness\",group:\"Lighting\"}},highlights:{default:15,description:\"Specular highlight intensity\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Highlights\",group:\"Lighting\"}},lightX:{default:.4,description:\"Light direction X\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Light X\",group:\"Lighting\"}},lightY:{default:-.6,description:\"Light direction Y\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Light Y\",group:\"Lighting\"}},lightZ:{default:.7,description:\"Light direction Z\",ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Light Z\",group:\"Lighting\"}},lightColor:{default:\"#ffffff\",transform:ce,description:\"Light color\",ui:{type:\"color\",label:\"Light Color\",group:\"Lighting\"}},cursorIntensity:{default:1,recompile:hn((e,t)=>e<.01!=t<.01),description:\"Strength of cursor ripples\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Cursor Ripples\",group:\"Interaction\"}},cursorSpeed:{default:.5,description:\"Speed of cursor ripple propagation\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Ripple Speed\",group:\"Interaction\"}}},compute:e=>{let{gpu:t,getCpuValue:s,registerComputeTexture:r,onCleanup:o,onResize:a,dimensions:i}=e,l=t?.root;if(!l)return null;let c=s(\"waveType\")===\"sine\"?1:s(\"waveType\")===\"ridge\"?2:0,d=Math.max(1,Math.floor(s(\"octaves\")??2)),u=s(\"edges\")??2,p=(s(\"lighting\")??30)>=.01,_=(s(\"cursorIntensity\")??1)>=.01,f=Math.round(i.width),h=Math.round(i.height),g=Math.min(_5,CY),y=Math.min(Math.round(_5*MY/CY),MY);if(f>=16&&h>=16){let xe=Math.min(1,_5/Math.max(f,h));g=Math.max(16,Math.round(f*xe)),y=Math.max(16,Math.round(h*xe))}let b=l.createTexture({size:[g,y],format:t_}).$usage(\"storage\",\"sampled\"),x=l.createTexture({size:[g,y],format:t_}).$usage(\"storage\",\"sampled\");o(()=>{b.destroy(),x.destroy()});let P=r(b),C=r(x),{bufferA:E,bufferB:R,readBuf:U}=Rz(l),L=zz(l),k=Math.max(1,Math.round(i.width)),D=Math.max(1,Math.round(i.height));a(({width:xe,height:Ae})=>{k=Math.max(1,Math.round(xe)),D=Math.max(1,Math.round(Ae))});let O=Lz({waveType:c,octaveCount:d,edgeMode:u,lightingEnabled:p,cursorEnabled:_,marchSteps:Nfe,marchRefine:$fe,computeW:g,computeH:y}),F=l.createBindGroup(xn,{readBuf:U,params:L.buffer,uvMaskTex:b,litTex:x}),q=QA(l,O,{size:[g,y],bindGroup:F}),Y=_?Dz():null,V=ap(E,R),X=_?V.groups((xe,Ae)=>l.createBindGroup(bn,{readSrc:xe,writeBuf:Ae,readBuf:U,params:L.buffer})):null,Q=_&&Y?QA(l,Y,{size:[256,256]}):null,te=.5,J=.5,oe=Date.now(),le=0,se=0,Te=null,de=(xe,Ae,De)=>{let Ee=Math.max(1,k)/Math.max(1,D),ze=(s(\"tilt\")??35)*EY,Ie=(s(\"roll\")??0)*EY,ke=s(\"height\")??0,Me=s(\"zoom\")??1,{camPos:we,fwd:Ve,camRight:qe,camUp:st,focal:pt}=Hfe(ze,Ie,ke,Me),Ze=xe.pointer?.x??.5,nt=xe.pointer?.y??.5,ht=(Ze-.5)*2*Ee,yt=-(nt-.5)*2,St=f5([Ve[0]*pt+qe[0]*ht+st[0]*yt,Ve[1]*pt+qe[1]*ht+st[1]*yt,Ve[2]*pt+qe[2]*ht+st[2]*yt]),Mt=Math.max(-St[2],.001),Rt=we[2]/Mt,Kt=we[0]+St[0]*Rt,Wt=we[1]+St[1]*Rt,ls=Kt*.5+.5,us=Wt*.5+.5,os=s(\"lightColor\"),bs=s(\"amplitude\")??.3,hs=s(\"cursorIntensity\")??1,gs=s(\"frequency\")??1.5,Gs=s(\"seed\")??0,Ss=s(\"edgePinning\")??0,or=(s(\"lighting\")??30)*.035,yr=(s(\"glossiness\")??0)*.01,lr=(s(\"highlights\")??15)*.04,Ur=s(\"lightX\")??.4,so=s(\"lightY\")??-.6,ro=s(\"lightZ\")??.7,_e=s(\"nearCutoff\")??0,We=s(\"farCutoff\")??1,Le=s(\"cursorSpeed\")??.5,Be=(ls-.5)/3+.5,Oe=(us-.5)/3+.5,tt=bs+Bz+(De>0?hs*.05*6:0);return L.write({amp:bs,freq:gs,seed:Gs,edgePin:Ss,cursorIntensity:hs,t:se,aspect:Ee,focal:pt,camPos:we,camForward:Ve,camRight:qe,camUp:st,lighting:or,glossiness:yr,highlights:lr,lightX:Ur,lightY:so,lightZ:ro,lightColor:[os?.x??1,os?.y??1,os?.z??1],nearCutoff:_e,farCutoff:We,cursorWaveX:Be,cursorWaveY:Oe,mouseSpeed:Ae,dt:.016,decay:10,radius:.025,waveSpeed:Le,heightEnvelope:tt,cursorActive:De}),[bs,gs,Gs,Ss,hs,se,Ee,ze,Ie,ke,Me,or,yr,lr,Ur,so,ro,os?.x??1,os?.y??1,os?.z??1,_e,We,Be,Oe,Ae,Le,tt,De].join(\",\")};return{outputs:{uvMaskMap:P,litMap:C},getComputeNodes:xe=>{let Ae=xe,De=Date.now(),Ee=Math.min(Ae.deltaTime??(De-oe)/1e3,.016);oe=De;let ze=Ae.pointer?.x??te,Ie=Ae.pointer?.y??J,ke=Ee>0?(ze-te)/Ee:0,Me=Ee>0?(Ie-J)/Ee:0,we=Math.min(Math.sqrt(ke*ke+Me*Me),2);te=ze,J=Ie,we>.01?le=0:le+=Ee,se+=Ee*(s(\"speed\")??.5);let Ve=!_||!Q||le*1e3>kz&&we<.01,qe=de(Ae,we,Ve?0:1);if(Ve&&qe===Te)return[];if(Te=qe,Ve||!Q||!X)return[q];let st=Q.with(X());return V.swap(),[st,q]}}},gpu:{fragment:e=>{let{childNode:t,ctx:s,computeOutputs:r,convertToTexture:o}=e;if(!t)return xt;let a=r?.uvMaskMap,i=r?.litMap;if(!a||!i)return xt;let l=z(a.sample(s.uv,\"linearClamp\"),\"uvMaskSample\"),c=i.sample(s.uv,\"linearClamp\"),d=Ot(l.member(\"r\"),l.member(\"g\"),0,0).member(\"xy\"),u=l.member(\"b\"),p=c.member(\"rgb\"),_=z(e.uvPropagationActive?t:o(t).sample(d),\"childColor\");return W(Yt,\"unpremultiplyAlpha\",[Ot(Ge(v(_.member(\"xyz\"),p),Qe(0,0,0),Qe(1,1,1)),v(_.member(\"w\"),u))])}}});function Xfe(e,t){return[e[1]*t[2]-e[2]*t[1],e[2]*t[0]-e[0]*t[2],e[0]*t[1]-e[1]*t[0]]}function f5(e){let t=Math.max(1e-6,Math.hypot(e[0],e[1],e[2]));return[e[0]/t,e[1]/t,e[2]/t]}function Hfe(e,t,s,r){let o=.85/Math.max(1e-4,r),a=-Math.sin(e)*o,i=Math.cos(e)*o,l=[0,a,i+s],c=f5([0,-a,-i]),d=[1,0,0],u=f5(Xfe(d,c)),p=Math.cos(t),_=Math.sin(t);return{camPos:l,fwd:c,camRight:[d[0]*p+u[0]*_,d[1]*p+u[1]*_,d[2]*p+u[2]*_],camUp:[u[0]*p-d[0]*_,u[1]*p-d[1]*_,u[2]*p-d[2]*_],focal:1.5}}var BY=F_(CR({detail:T(\"detail\")})),zY=H({name:\"Swirl\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null},category:\"Textures\",description:\"Flowing swirl pattern with multi-layered noise\",animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#1275d8\",description:\"Primary gradient color\",transform:ce,ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#e19136\",description:\"Secondary gradient color\",transform:ce,ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),speed:{default:1,description:\"Flow animation speed\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},detail:{default:1,description:\"Level of detail and intricacy in the swirl patterns\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.1,label:\"Detail\",group:\"Effect\"}},blend:{default:50,description:\"Skew color balance toward A (lower values) or B (higher values)\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Blend\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:kR(Vs(TR(BY,{low:.3,high:.7,bias:{base:T(\"blend\"),add:-50,mul:.006}}),Us(T(\"colorSpace\"))),MR(BY,{speed:2.5,span:8,depth:.015}))});var RY=H({role:\"shape\",name:\"Teardrop\",description:\"Teardrop \\u2014 a rounded bulb tapering to a sharp point\",shape:{distance:({x:e,y:t},s)=>hR(e,t,s(\"radius\"),s(\"height\")),colorDescription:\"Fill color of the teardrop\",centerDescription:\"Center position of the teardrop\",bounds:{size:{width:\"radius\",height:\"height\"}},shapeProps:{radius:{default:.22,description:\"Radius of the rounded bulb\",ui:{type:\"range\",min:.02,max:.6,step:.01,label:\"Width\",group:\"Shape\"}},height:{default:.4,description:\"Length from the bulb to the point\",ui:{type:\"range\",min:.1,max:.7,step:.01,label:\"Length\",group:\"Shape\"}}}}});function LY(e,t){switch(t){case\"uppercase\":return e.toUpperCase();case\"lowercase\":return e.toLowerCase();case\"capitalize\":return e.replace(/(^|\\s)(\\S)/g,(s,r,o)=>r+o.toUpperCase());default:return e}}var UY=0;function jfe(){UY++}var Dp=null,dy=!1;function OY(){if(Dp)return Dp;if(typeof document>\"u\")return null;let e=document.createElement(\"canvas\");return e.width=1,e.height=1,Dp=e.getContext(\"2d\",{willReadFrequently:!1}),Dp&&(dy=\"letterSpacing\"in Dp),Dp}function Kfe(){return OY(),dy}var Qfe=500,cy=new Map;function v5(e){let t=LY(e.text,e.textTransform),s=OY();if(!s)return{widthPer100:t.length*55,ascentPer100:80,descentPer100:20,inkAscentPer100:80,inkDescentPer100:20};let r=rB(e.fontFamily,e.fontWeight,e.italic),o=`${UY}|${r?1:0}|${e.fontFamily}|${e.fontWeight}|${e.italic?1:0}|${e.letterSpacingEm}|${t}`,a=cy.get(o);if(a)return a;s.font=`${e.italic?\"italic \":\"\"}${e.fontWeight} 100px \"${e.fontFamily}\", sans-serif`,dy&&(s.letterSpacing=`${e.letterSpacingEm*100}px`);let i=s.measureText(t),l=i.width;dy&&t.length>0&&(l=Math.max(0,l-e.letterSpacingEm*100));let c=i.fontBoundingBoxAscent??i.actualBoundingBoxAscent??80,d=i.fontBoundingBoxDescent??i.actualBoundingBoxDescent??20,u=i.actualBoundingBoxAscent,p=i.actualBoundingBoxDescent,_=u!==void 0&&p!==void 0&&u+p>1,f={widthPer100:l,ascentPer100:c,descentPer100:d,inkAscentPer100:_?u:c,inkDescentPer100:_?p:d};return cy.size>=Qfe&&cy.clear(),cy.set(o,f),f}function Zfe(e,t,s){let r=e.split(/\\r\\n|\\r|\\n/);if(!(t>0))return r;let o=[];for(let a of r){let i=a.split(\" \"),l=\"\";for(let c of i){let d=l?`${l} ${c}`:c;l&&s(d)>t?(o.push(l),l=c):l=d}o.push(l)}return o}function GY(e,t,s){let r=Zfe(LY(e.text,e.textTransform),s??0,d=>v5({...e,text:d,textTransform:\"none\"}).widthPer100),o=r.map(d=>v5({...e,text:d,textTransform:\"none\"})),a=Math.max(1,r.length),i=o[0]??v5(e),l=o[o.length-1]??i,c=Math.max(1,t*100);return{lines:r,lineWidthsPer100:o.map(d=>d.widthPer100),widthPer100:o.reduce((d,u)=>Math.max(d,u.widthPer100),0),ascentPer100:i.ascentPer100,descentPer100:i.descentPer100,inkAscentFirstPer100:i.inkAscentPer100,inkDescentLastPer100:l.inkDescentPer100,pitchPer100:c,blockHeightPer100:i.ascentPer100+(a-1)*c+i.descentPer100,inkHeightPer100:i.inkAscentPer100+(a-1)*c+l.inkDescentPer100}}var Jfe=4096,e1e=3,t1e=(e,t)=>e&&typeof e==\"object\"&&typeof e.value==\"number\"?e.unit===\"px\"?e.value:e.value*t:(typeof e==\"number\"?e:0)*t,DY=(e,t,s)=>{let r=s1e(e.fontSize,s),o=t1e(e.width,t);return{fontSizePx:r,widthPx:o,m:GY({text:String(e.text??\"\"),fontFamily:String(e.fontFamily??\"Inter\"),fontWeight:Number(e.fontWeight??400),italic:!!e.italic,letterSpacingEm:Number(e.letterSpacing??0),textTransform:e.textTransform??\"none\"},Number(e.lineHeight??1.2)||1.2,r>0&&o>0?o*100/r:0)}},s1e=(e,t)=>e&&typeof e==\"object\"&&typeof e.value==\"number\"?e.unit===\"px\"?e.value:e.value*t:(typeof e==\"number\"?e:.1)*t;function r1e(e){let{dimensions:t,getCpuValue:s,setExtraField:r}=e,o=w_(e,{maxAxis:Jfe,supersample:e1e}),a=o.context(),i=gc(e,{label:\"Text:glyph\",initial:{width:2,height:2}}),l=h5.props,c=()=>({text:String(s(\"text\")??l.text.default),fontFamily:String(s(\"fontFamily\")??l.fontFamily.default),fontWeight:Number(s(\"fontWeight\")??l.fontWeight.default),italic:Number(s(\"italic\")??0)>.5,fontSizeUV:Number(s(\"fontSize\")??l.fontSize.default),letterSpacing:Number(s(\"letterSpacing\")??l.letterSpacing.default),lineHeight:Number(s(\"lineHeight\")??l.lineHeight.default)||l.lineHeight.default,textAlign:String(s(\"textAlign\")??l.textAlign.default),widthUV:Number(s(\"width\")??l.width.default),textTransform:String(s(\"textTransform\")??l.textTransform.default)}),d=()=>{if(!a||o.disposed)return;let p=c(),_=t.width||1,f=t.height||1,h=p.fontSizeUV*f,g=p.widthUV*_;if(!p.text.trim()||h<=0){o.resize(2,2),i.ensureSize(2,2),i.write(o.canvas()),r(\"halfW\",.001),r(\"halfH\",.001);return}let y=GY({text:p.text,fontFamily:p.fontFamily,fontWeight:p.fontWeight,italic:p.italic,letterSpacingEm:p.letterSpacing,textTransform:p.textTransform},p.lineHeight,g>0?g*100/h:0),b=h/100,x=Math.max(1,(g>0?Math.max(g*100/h,y.widthPer100):y.widthPer100)*b),P=y.pitchPer100*b,C=Math.max(1,h*p.lineHeight),E=Math.max(C,y.blockHeightPer100*b),R=y.ascentPer100*b,U=y.descentPer100*b,L=Math.max(.25*h,(R+U-C)/2+.25*h),k=x+L*2,D=E+L*2,{scale:O,texW:F,texH:q}=o.rasterSize(k,D);o.resize(F,q),a.fillStyle=\"#ffffff\",a.font=`${p.italic?\"italic \":\"\"}${p.fontWeight} ${h*O}px \"${p.fontFamily}\", sans-serif`,Kfe()&&(a.letterSpacing=`${p.letterSpacing*h*O}px`),a.textAlign=\"left\",a.textBaseline=\"alphabetic\";let Y=q/2-E/2*O,V=(F-x*O)/2;for(let X=0;X<y.lines.length;X++){let Q=y.lines[X];if(!Q.trim())continue;let te=y.lineWidthsPer100[X]*b,J=p.textAlign===\"left\"?V:p.textAlign===\"right\"?V+(x-te)*O:V+(x-te)/2*O,oe=Y+(R+X*P)*O;a.fillText(Q,J,oe)}i.ensureSize(F,q),i.write(o.canvas()),r(\"halfW\",Math.max(1e-4,k/2/f)),r(\"halfH\",Math.max(1e-4,D/2/f))},u=S_({key:()=>{let p=c();return`${p.fontFamily}|${p.fontWeight}|${p.italic}`},load:()=>{let p=c();return Hh(p.fontFamily,p.fontWeight,p.italic)},onLoaded:()=>{jfe(),d()}});return setTimeout(()=>{d(),u.ensure()},0),T_(e,{key:()=>{let p=c();return`${p.text}|${p.fontFamily}|${p.fontWeight}|${p.italic}|${p.fontSizeUV}|${p.letterSpacing}|${p.lineHeight}|${p.textAlign}|${p.widthUV}|${p.textTransform}|${t.width}x${t.height}|${e.canvas.width}`},run:()=>{d(),u.ensure()}}),i}var o1e=({uniforms:e,ctx:t,uvContext:s})=>W(Z8,\"orientedBoxField\",[s??t.uv,t.aspect,e.center,e.rotation,e.halfW,e.halfH]),a1e=(e,t)=>g_(e,t.member(\"xy\"),\"linearClamp\",\"unit\"),n1e=(e,t,s)=>Ct(s.member(\"rgb\"),e.member(\"a\").mul(s.member(\"a\")).mul(t.member(\"z\"))),h5=H({name:\"Text\",role:\"media\",species:\"custom\",category:\"Textures\",description:\"Text with any Google font \\u2014 multi-line with wrapping, alignment and line height \\u2014 rendered crisp via a glyph texture\",acceptsUVContext:!0,extraFields:{halfW:{schema:n,initial:.001},halfH:{schema:n,initial:.001}},boundingBoxDeclaration:{propBindings:{x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"},rotation:{prop:\"rotation\",as:\"degrees\"}},computeBounds(e,t,s){let{fontSizePx:r,widthPx:o,m:a}=DY(e,t,s),i=r/100,l=typeof e.center?.x==\"number\"?e.center.x:.5,c=typeof e.center?.y==\"number\"?e.center.y:.5,d=(a.ascentPer100-a.descentPer100+(a.inkDescentLastPer100-a.inkAscentFirstPer100))/2*i;return{centerXPx:l*t,centerYPx:c*s+d,widthPx:Math.max(0,o>0?o:a.widthPer100*i),heightPx:Math.max(0,a.inkHeightPer100*i),rotationDeg:e.rotation??0}},writeBounds(e,t,s,r){let{fontSizePx:o,widthPx:a,m:i}=DY(t,s,r),l=Math.max(1,i.inkHeightPer100*o/100),c=e.heightPx/l;if(a>0){let h=e.widthPx/Math.max(1,a),g=e.heightPx/l;c=Math.abs(h-g)<.02?g:1}let d=Math.max(1,o*c),u=(i.ascentPer100-i.descentPer100+(i.inkDescentLastPer100-i.inkAscentFirstPer100))/2*(d/100),p=t.fontSize,_=p&&typeof p==\"object\"&&p.unit===\"px\"?{value:Math.max(1,Math.round(d)),unit:\"px\"}:Math.max(.001,r>0?d/r:.001),f={center:{...t.center??{x:.5,y:.5},x:e.centerXPx/s,y:(e.centerYPx-u)/r},fontSize:_,rotation:e.rotationDeg};if(a>0){let h=t.width;f.width=h&&typeof h==\"object\"&&h.unit===\"px\"?{value:Math.max(1,Math.round(e.widthPx)),unit:\"px\"}:Math.max(.001,s>0?e.widthPx/s:.001)}return f}},props:{text:{default:\"Hello World\",description:\"The text to display (single line)\",ui:{type:\"text\",label:\"Text\",group:\"Text\",hidden:!0}},fontFamily:{default:\"Inter\",description:\"Google Fonts family name\",ui:{type:\"font-family\",label:\"Font\",group:\"Text\"}},fontWeight:{default:400,description:\"Font weight (only weights published for the family render true; others are synthesized)\",ui:{type:\"font-weight\",label:\"Weight\",group:\"Text\"}},italic:{default:!1,description:\"Italic style\",ui:{type:\"checkbox\",label:\"Italic\",group:\"Text\"},transform:e=>e?1:0},textTransform:{default:\"none\",description:\"Case transformation applied to the text\",ui:{type:\"select\",options:[{label:\"None\",value:\"none\"},{label:\"Uppercase\",value:\"uppercase\"},{label:\"Lowercase\",value:\"lowercase\"},{label:\"Capitalize\",value:\"capitalize\"}],label:\"Transform\",group:\"Text\"}},fontSize:{default:.07,description:\"Font size as a fraction of canvas height\",ui:{type:\"range\",min:.01,max:.5,step:.005,label:\"Size\",group:\"Typography\",dimensional:\"canvas-height\"}},letterSpacing:{default:0,description:\"Letter spacing in em units\",ui:{type:\"range\",min:-.1,max:.5,step:.005,label:\"Letter Spacing\",group:\"Typography\"}},lineHeight:{default:1.2,description:\"Line height as a multiple of font size (multi-line text)\",ui:{type:\"range\",min:.8,max:2.5,step:.05,label:\"Line Height\",group:\"Paragraph\",hidden:!0}},textAlign:{default:\"center\",description:\"Horizontal alignment of lines within the text block\",ui:{type:\"select\",options:[{label:\"Left\",value:\"left\"},{label:\"Center\",value:\"center\"},{label:\"Right\",value:\"right\"}],label:\"Align\",group:\"Paragraph\",hidden:!0}},width:{default:0,description:\"Wrap width \\u2014 text wraps to fit; 0 = auto (hug contents, single line per explicit break). Edited via the Typography panel's Auto/Fixed width toggle and the side drag handles, not a slider.\",ui:{type:\"range\",min:0,max:1,step:.005,label:\"Max Width\",group:\"Paragraph\",units:[\"%\",\"px\"],dimensional:\"canvas-width\",hidden:!0}},color:{default:\"#ffffff\",transform:ce,description:\"Text color\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the text relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the text\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},rotation:{default:0,description:\"Rotation in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}}},gpu:{fragment:e=>{let t=r1e(e),s=o1e(e);return n1e(a1e(t.kit,s),s,e.uniforms.color)}}});var FY=H({name:\"TiltShift\",role:\"filter\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Selective focus blur mimicking tilt-shift photography\",requiresRTT:!0,requiresChild:!0,props:{intensity:{default:50,description:\"Maximum blur intensity at edges\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},width:{default:.3,description:\"Width of the sharp focus area\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Width\",group:\"Effect\"}},falloff:{default:.3,description:\"Distance over which blur transitions to full strength\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Falloff\",group:\"Effect\"}},angle:{default:0,transform:cs,description:\"Rotation angle of the focus line (in degrees)\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center point of the focus line\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},dispersion:{default:0,description:\"Blurs red and blue by different amounts for a lens-like color fringe outside the focus band; negative swaps the colors\",recompile:Lt(0),ui:{type:\"range\",min:-1,max:1,step:.01,label:\"Dispersion\",group:\"Lens\"}},jitter:{default:0,description:\"Per-pixel noise on the tap spacing that hides banding at large blur radii\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Jitter\",group:\"Lens\"}}},...DU({intensity:T(\"intensity\"),width:T(\"width\"),falloff:T(\"falloff\"),angle:T(\"angle\"),center:T(\"center\"),detail:{dispersion:T(\"dispersion\"),jitter:T(\"jitter\")}})});var uy=Rr()?384:640,YY=\"rgba16float\",i1e=2.5*.5/uy,l1e=.5,c1e=.35,d1e={none:0,color:1,rainbow:2},u1e={motion:1,alpha:0},WY=(e,t)=>Fz({res:uy,format:YY,namePrefix:\"timeTrail\",source:e,hueCycle:t,diffuseHalfUv:i1e,driftScale:l1e}),y7e=WY(\"motion\",!1).kernel,IY=e=>{let t=e===\"add\"?\"linearDodge\":String(e??\"normal\");return t in pc?t:\"normal\"},p1e=e=>e===\"screen\"?1:e===\"linearDodge\"?2:0,qY=H({name:\"TimeTrail\",role:\"simulation\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"An Echo-style temporal trail \\u2014 whatever moves sheds a smooth, decaying long-exposure ghost trail (frame-difference Motion mode works on opaque images and video; Alpha mode trails a shape's coverage), with optional zoom-feedback tunnels and rainbow light-painting\",requiresRTT:!0,requiresChild:!0,props:{trailSource:{default:\"motion\",description:\"What sheds the trail \\u2014 Motion trails whatever changes frame-to-frame (works on opaque images and video), Alpha trails the child's transparency coverage (best for a clean shape over empty canvas)\",compileTime:!0,transform:e=>u1e[e]??1,ui:{type:\"select\",options:[{label:\"Motion\",value:\"motion\"},{label:\"Alpha\",value:\"alpha\"}],label:\"Source\",group:\"Trail\"}},motionThreshold:{default:.06,description:\"How much a pixel must change between frames to shed a trail (Motion source only) \\u2014 lower catches subtle movement, higher only fast motion\",ui:{type:[\"range\",\"map\"],min:.01,max:.5,step:.01,label:\"Motion Threshold\",group:\"Trail\"}},trailLength:{default:.6,description:\"How long the trail lingers, in seconds \\u2014 the time constant of the fade (the star control)\",ui:{type:[\"range\",\"map\"],min:.05,max:4,step:.01,label:\"Trail Length\",group:\"Trail\"}},diffusion:{default:1,description:\"How much the trail smears and softens as it fades \\u2014 0 keeps crisp ghost frames, higher melts them together\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Diffusion\",group:\"Trail\"}},trailOpacity:{default:1,description:\"Overall strength of the trail behind the live frame\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Trail Opacity\",group:\"Trail\"}},trailBlend:{default:\"normal\",description:\"How the trail combines with the frame \\u2014 Add / Screen build glowing light-painting trails, Multiply lays down dark ink ghosts, plus the full standard blend set\",compileTime:!0,ui:{type:\"select\",options:[{label:\"Normal\",value:\"normal\"},{label:\"Add\",value:\"add\"},{label:\"Screen\",value:\"screen\"},{label:\"Multiply\",value:\"multiply\"},{label:\"Overlay\",value:\"overlay\"},{label:\"Soft Light\",value:\"softLight\"},{label:\"Hard Light\",value:\"hardLight\"},{label:\"Darken\",value:\"darken\"},{label:\"Lighten\",value:\"lighten\"},{label:\"Color Dodge\",value:\"colorDodge\"},{label:\"Color Burn\",value:\"colorBurn\"},{label:\"Linear Burn\",value:\"linearBurn\"},{label:\"Difference\",value:\"difference\"},{label:\"Exclusion\",value:\"exclusion\"},{label:\"Hue\",value:\"hue\"},{label:\"Saturation\",value:\"saturation\"},{label:\"Color\",value:\"color\"},{label:\"Luminosity\",value:\"luminosity\"}],label:\"Blend\",group:\"Trail\"}},driftX:{default:0,description:\"Sideways drift of the trail per second \\u2014 smears the trail in a direction\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Drift X\",group:\"Feedback\"}},driftY:{default:0,description:\"Vertical drift of the trail per second\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Drift Y\",group:\"Feedback\"}},zoom:{default:1,description:\"Per-frame zoom of the trail around the centre \\u2014 above 1 pulls the trail into an outward tunnel, below 1 sucks it inward\",ui:{type:[\"range\",\"map\"],min:.9,max:1.1,step:.001,label:\"Zoom\",group:\"Feedback\"}},tintMode:{default:\"none\",description:\"color the trail \\u2014 Color tints it a single hue, Rainbow cycles hue as the trail ages\",compileTime:!0,transform:e=>d1e[e]??0,ui:{type:\"select\",options:[{label:\"None\",value:\"none\"},{label:\"Color\",value:\"color\"},{label:\"Rainbow\",value:\"rainbow\"}],label:\"Tint Mode\",group:\"Color\"}},tint:{default:\"#33aaff\",transform:ce,description:\"Trail tint color (used in Color mode)\",ui:{type:\"color\",label:\"Tint\",group:\"Color\"}},speed:{default:1,description:\"Simulation speed. 0 freezes the trail in place.\",ui:{type:\"range\",min:0,max:4,step:.1,label:\"Speed\",group:\"Animation\"}}},...Lg((e,t)=>{let{getCpuValue:s,propValues:r}=e,o=Number(r.tintMode)||0,a=p1e(IY(r.trailBlend)),i=(r.trailSource==null?1:Number(r.trailSource))>.5,l=t.createSampler({magFilter:\"linear\",minFilter:\"linear\",addressModeU:\"clamp-to-edge\",addressModeV:\"clamp-to-edge\"}),c=WY(i?\"motion\":\"alpha\",o===2);return{size:uy,format:YY,extraSlots:{prevLive:i?uy:[1,1]},speedProp:\"speed\",paramsSchema:c.Params,bindGroups:({childTexture:d,display:u,paramsBuffer:p},_,f)=>t.createBindGroup(c.layout,{src:d,prev:_.state,next:f.state,display:u,prevLive:_.extra.prevLive,prevLiveOut:f.extra.prevLive,samp:l,params:p}),step:c.kernel,skip:()=>(s(\"trailOpacity\")??1)===0,values:({dt:d})=>{let u=s(\"zoom\")??1,p=Math.max(s(\"trailLength\")??.6,.001);return{persistence:Math.exp(-d/p),diffusion:s(\"diffusion\")??.3,driftX:s(\"driftX\")??0,driftY:s(\"driftY\")??0,dt:d,zoom:Math.pow(u,d*60),hueRate:o===2?c1e*d:0,blendMode:a,motionThreshold:s(\"motionThreshold\")??.06}}}}),gpu:{fragment:({childNode:e,ctx:t,computeOutputs:s,uniforms:r,propValues:o,convertToTexture:a})=>{if(!e)return xt;let i=s?.display,l=(s?.childTexture??a(e)).sample(t.uv);if(!i)return W(Yt,\"unpremultiplyAlpha\",[l]);let c=IY(o.trailBlend),d=pc[c],u=Number(o.tintMode)||0,p=o.trailSource==null?1:Number(o.trailSource),_=z(i.sample(t.uv,\"linearClamp\"),\"trail\");if(u===1){let g=it(_.member(\"a\"),1e-4),y=$t(Ce(_.member(\"rgb\"),g),Qe(.299,.587,.114));_=z(Ot(v(v(r.tint.member(\"rgb\"),v(y,1.5)),_.member(\"a\")),_.member(\"a\")),\"tinted\")}let f=W(Yt,\"unpremultiplyLive\",[l]);if(p===1){let g=W(Yt,\"unpremultiplyTrail\",[_]);return W(Yt,\"unpremultiplyOut\",[W(d,`trailBlend_${c}`,[f,g,r.trailOpacity])])}let h=W(Yt,\"unpremultiplyTrail\",[v(_,r.trailOpacity)]);return W(Yt,\"unpremultiplyOut\",[W(d,`trailBlend_${c}`,[h,f,$e(1)])])}}});var VY=H({name:\"Tint\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Apply a color tint to the image\",props:{color:{default:\"#ff8800\",transform:ce,description:\"Tint color\",ui:{type:\"color\",label:\"Tint Color\",group:\"Colors\"}},amount:{default:.5,description:\"Tint amount (0 = no tint, 1 = full tint)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Amount\",group:\"Effect\"}},preserveLuminosity:{default:!0,compileTime:!0,description:\"Preserve original brightness\",transform:e=>e?1:0,ui:{type:\"checkbox\",label:\"Preserve Luminosity\",group:\"Effect\"}}},effect:d8({color:T(\"color\"),amount:T(\"amount\"),preserveLuminosity:T(\"preserveLuminosity\")}),missingChildMessage:\"You must pass a child component into the Tint shader.\"});function py(e,t,s){let r=Number.isFinite(s)?s:.5;if(e!=null&&typeof e==\"object\"&&typeof e.value==\"number\"){let o=e;return Number.isFinite(o.value)?o.unit!==\"px\"?o.value:Number.isFinite(t)&&t!==0?o.value/(2*t):r:r}return typeof e==\"number\"&&Number.isFinite(e)?e:r}var NY=H({role:\"shape\",name:\"Trapezoid\",description:\"Trapezoid with adjustable top and bottom widths and height\",shape:{distance:({x:e,y:t},s)=>vR(e,t,s(\"topWidth\"),s(\"bottomWidth\"),s(\"height\")),colorDescription:\"Fill color of the trapezoid\",centerDescription:\"Center position of the trapezoid\",bounds:{custom:{propBindings:{x:{prop:\"center\",as:\"position-x\"},y:{prop:\"center\",as:\"position-y\"},rotation:{prop:\"rotation\",as:\"degrees\"}},computeBounds(e,t,s){let r=py(e.bottomWidth,s,.35),o=typeof e.topWidth==\"number\"?e.topWidth:.2,a=py(e.height,s,.25),i=typeof e.center?.x==\"number\"?e.center.x:.5,l=typeof e.center?.y==\"number\"?e.center.y:.5;return{centerXPx:i*t,centerYPx:l*s,widthPx:Math.max(o,r)*2*s,heightPx:a*2*s,rotationDeg:e.rotation??0}},writeBounds(e,t,s,r){let o=(p,_)=>p!=null&&typeof p==\"object\"&&p.unit===\"px\"?{value:Math.max(0,Math.round(_*2*r)),unit:\"px\"}:Math.max(.001,_),a=py(t.bottomWidth,r,.35),i=typeof t.topWidth==\"number\"?t.topWidth:.2,l=Math.max(i,a),c=r>0?e.widthPx/(2*r):l,d=l>0?c/l:1,u=t.center??{x:.5,y:.5};return{center:{...u,x:s>0?e.centerXPx/s:u.x??.5,y:r>0?e.centerYPx/r:u.y??.5},bottomWidth:o(t.bottomWidth,a*d),topWidth:Math.max(.001,i*d),height:o(t.height,r>0?e.heightPx/(2*r):py(t.height,r,.25)),rotation:e.rotationDeg}},freeResize:!0}},shapeProps:{bottomWidth:{default:.35,description:\"Half-width of the bottom edge\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Bottom Width\",group:\"Shape\",units:[\"%\",\"px\"],dimensional:\"half-canvas-height\"}},topWidth:{default:.2,description:\"Half-width of the top edge\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Top Width\",group:\"Shape\"}},height:{default:.25,description:\"Half-height of the trapezoid\",ui:{type:\"range\",min:.01,max:1,step:.01,label:\"Height\",group:\"Shape\",units:[\"%\",\"px\"],dimensional:\"half-canvas-height\"}}}}});var $Y=JR({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"flippedY\"}),thickness:T(\"thickness\"),softness:T(\"softness\"),variation:T(\"variation\"),speedVariance:T(\"speedVariance\")}),XY=H({name:\"TriangularGrid\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Tiling grid of equilateral triangles with optional animated row offsets\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#1a1a1a\",transform:ce,description:\"Triangle fill color\",ui:{type:\"color\",label:\"Fill\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Grid line color\",ui:{type:\"color\",label:\"Lines\",group:\"Colors\"}},cells:{default:8,description:\"Number of triangle rows down the shortest canvas edge\",ui:{type:[\"range\",\"map\"],min:1,max:40,step:1,label:\"Cells\",group:\"Effect\"}},thickness:{default:1,description:\"Thickness of the grid lines (0 = no lines)\",ui:{type:[\"range\",\"map\"],min:0,max:10,step:.1,label:\"Thickness\",group:\"Effect\"}},rotation:{default:0,transform:cs,description:\"Rotation of the grid in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the line edges (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},variation:{default:0,description:\"Per-triangle random lightening/darkening of the fill color\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Effect\"}},speed:{default:0,description:\"Animates the triangle rows drifting horizontally (0 = static)\",ui:{type:\"range\",min:-3,max:3,step:.01,label:\"Speed\",group:\"Animation\"}},speedVariance:{default:.3,description:\"Per-row random speed variance for irregular drifting motion\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Speed Variance\",group:\"Animation\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:Sc(T(\"colorA\"),$Y.shade),stroke:T(\"colorB\"),mask:$Y.lines,space:T(\"colorSpace\")})});var HY=H({name:\"Tritone\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Map colors to three tones: shadows, midtones, highlights\",props:{colorA:{default:\"#ce1bea\",transform:ce,description:\"First color (used for shadows/darkest areas)\",ui:{type:\"color\",label:\"Color A (Shadows)\",group:\"Colors\"}},colorB:{default:\"#2fff00\",transform:ce,description:\"Second color (used for midtones)\",ui:{type:\"color\",label:\"Color B (Midtones)\",group:\"Colors\"}},colorC:{default:\"#ffff00\",transform:ce,description:\"Third color (used for highlights/brightest areas)\",ui:{type:\"color\",label:\"Color C (Highlights)\",group:\"Colors\"}},blendMid:{default:.5,description:\"Midpoint position between the three colors\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.1,label:\"Midpoint\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},effect:_8({colorA:T(\"colorA\"),colorB:T(\"colorB\"),colorC:T(\"colorC\"),blendMid:T(\"blendMid\"),colorSpace:T(\"colorSpace\")})});var jY=H({name:\"Truchet\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Quarter-circle arc tiles that connect to form organic, maze-like flowing curves\",acceptsUVContext:!0,props:{colorA:{default:\"#000000\",transform:ce,description:\"Background color between the arcs\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ffffff\",transform:ce,description:\"Arc line color\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},cells:{default:10,description:\"Number of tiles across the shortest canvas edge\",ui:{type:[\"range\",\"map\"],min:2,max:40,step:1,label:\"Cells\",group:\"Effect\"}},thickness:{default:2,description:\"Thickness of the arc lines\",ui:{type:[\"range\",\"map\"],min:0,max:20,step:.1,label:\"Thickness\",group:\"Effect\"}},rotation:{default:0,transform:cs,description:\"Rotation of the tiling in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}},softness:{default:0,description:\"Softness of the arc edges (0 = crisp, 1 = very soft)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\"}},seed:{default:0,description:\"Random seed \\u2014 changes which tiles flip, producing a different maze pattern\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:Zr({fill:T(\"colorA\"),stroke:T(\"colorB\"),mask:tD({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"clockwise\"}),thickness:T(\"thickness\"),softness:T(\"softness\"),seed:T(\"seed\")}),space:T(\"colorSpace\")})});var KY=H({name:\"Twirl\",role:\"warp\",category:\"Distortions\",description:\"Rotate and twist content around a center point\",boundingBoxDeclaration:{aspectRatio:null},props:{center:zo(\"The center point of the twirl effect\"),intensity:{default:1,description:\"The strength of the twirl effect\",ui:{type:[\"range\",\"map\"],min:-5,max:5,step:.1,label:\"Intensity\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},map:HL({center:T(\"center\"),intensity:T(\"intensity\")}),missingChildMessage:\"You must pass a child component into the Twirl shader.\"});var QY=H({name:\"VenetianBlinds\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Transitions\",description:\"Wipe the content away behind a set of parallel closing strips\",props:{progress:{default:.5,description:\"How far the blinds have closed (0 = fully visible, 1 = fully wiped away)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Progress\",group:\"Transition\"}},angle:{default:0,description:\"Orientation of the strips in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Transition\"}},stripCount:{default:5,description:\"Number of strips across the frame\",ui:{type:[\"range\",\"map\"],min:2,max:60,step:1,label:\"Strips\",group:\"Transition\"}},feather:{default:.15,description:\"Softness of each closing strip edge\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Feather\",group:\"Transition\"}},invert:{default:!1,transform:rs,description:\"Close each strip from the opposite edge\",ui:{type:\"checkbox\",label:\"Invert\",group:\"Transition\"}}},effect:to({coverage:eo.directional(T(\"angle\")).tiled(T(\"stripCount\")),progress:T(\"progress\"),feather:T(\"feather\"),invert:T(\"invert\")}),missingChildMessage:\"You must pass a child component into the Venetian Blinds shader.\"});var ZY=H({role:\"shape\",name:\"Vesica\",description:\"Vesica piscis (lens shape) formed by the intersection of two overlapping circles\",shape:{distance:({x:e,y:t},s)=>_R(e,t,s(\"radius\"),s(\"spread\")),colorDescription:\"Fill color of the vesica\",centerDescription:\"Center position of the vesica\",bounds:{size:{width:\"radius\",height:\"radius\"}},shapeProps:{radius:{default:.35,description:\"Radius of the two overlapping circles\",ui:{type:\"range\",min:.05,max:1,step:.01,label:\"Size\",group:\"Shape\"}},spread:{default:.5,description:\"Circle separation \\u2014 0 = full circle overlap, 1 = infinitely thin lens\",ui:{type:\"range\",min:.05,max:.95,step:.01,label:\"Spread\",group:\"Shape\"}}}}});var JY=H({name:\"VHS\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Analog VHS tape with intermittent tape damage, chroma bleed, and per-scanline noise\",props:{wobble:{default:1,description:\"Overall amount of tape damage \\u2014 waves, creases, and head-switching noise. Bursts on and off organically over time.\",ui:{type:[\"range\",\"map\"],min:0,max:5,step:.01,label:\"Wobble\",group:\"Effect\"}},scanlineNoise:{default:.6,description:\"Per-scanline fine chroma/luma jitter. Adds the classic horizontal-streak detail.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Scanline Noise\",group:\"Effect\"}},smear:{default:.2,description:\"Horizontal chroma smear (color bleed) amount. Positive trails color to the right (classic VHS), negative trails it to the left.\",ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.01,label:\"Smear\",group:\"Effect\"}},speed:{default:1,description:\"Animation speed of the tape effects.\",ui:{type:\"range\",min:.1,max:3,step:.1,label:\"Speed\",group:\"Effect\"}}},effect:$o(pU({warp:uU({wobble:T(\"wobble\"),jitter:T(\"scanlineNoise\"),speed:T(\"speed\")}),smear:T(\"smear\")}),[yU({wobble:T(\"wobble\"),speed:T(\"speed\")})])});var eW=H({name:\"Vibrance\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Adjustments\",description:\"Selective saturation adjustment protecting skin tones\",props:{intensity:{default:0,description:\"The intensity of the vibrance effect\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-2,max:2,step:.1,label:\"Intensity\",group:\"Adjustments\"}}},effect:r8(T(\"intensity\")),identityWhen:Uo(\"intensity\"),missingChildMessage:\"You must pass a child component into the Vibrance shader.\"});var tW=H({name:\"VideoTexture\",role:\"media\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Display a video with customizable playback and object-fit modes\",acceptsUVContext:!0,naturalSizeKey:{fromProp:\"url\"},props:{url:{default:\"https://shaders.com/sample.mp4\",description:\"Upload a video or provide a URL\",ui:{type:\"video-upload\",label:\"Video\",group:\"Media\"}},objectFit:up(\"fill\",\"How the video should be sized within the viewport\",{allowNone:!1}),loop:{default:!0,description:\"Loop the video playback\",ui:{type:\"checkbox\",label:\"Loop\",group:\"Playback\"}}},...UL({src:T(\"url\"),fit:T(\"objectFit\"),loop:T(\"loop\"),decode:\"srgb-linear-alpha-cut\",metadataTimeoutMs:1e4,onError:(e,{stage:t})=>{t===\"autoplay\"?console.warn(\"[VideoTexture] Autoplay failed (browser policy):\",e):console.error(\"[VideoTexture] Failed to load video:\",e)}})});var sW=H({name:\"Vignette\",role:\"filter\",species:\"pointwise\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Darkens or tints the edges of the frame, drawing attention toward the center\",props:{color:{default:\"#000000\",transform:ce,description:\"Color of the vignette at the edges\",ui:{type:\"color\",label:\"Color\",group:\"Colors\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center of the clear area where the vignette begins\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},radius:{default:.5,description:\"Distance from center where the vignette begins to fade in\",ui:{type:[\"range\",\"map\"],min:0,max:1.5,step:.01,label:\"Radius\",group:\"Effect\"}},falloff:{default:.5,description:\"Width of the transition zone from clear to full vignette\",ui:{type:[\"range\",\"map\"],min:.01,max:1.5,step:.01,label:\"Falloff\",group:\"Effect\"}},intensity:{default:1,description:\"Strength of the vignette effect\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Intensity\",group:\"Effect\"}}},effect:Kz(T(\"color\"),{amount:tR({center:T(\"center\"),radius:T(\"radius\"),falloff:T(\"falloff\")}).times(T(\"intensity\"))}),identityWhen:Uo(\"intensity\"),missingChildMessage:\"You must pass a child component into the Vignette shader.\"});var rW=F_(eL({scale:T(\"scale\"),seed:T(\"seed\")})),oW=H({name:\"Voronoi\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Cellular pattern where each pixel is colored by its distance to the nearest of many scattered points\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#3186cf\",transform:ce,description:\"Color near each cell's center point\",ui:{type:\"color\",label:\"Color A (Center)\",group:\"Colors\"}},colorB:{default:\"#fc02dd\",transform:ce,description:\"Color at cell boundaries, far from any center point\",ui:{type:\"color\",label:\"Color B (Edge)\",group:\"Colors\"}},stops:Ms(),colorBorder:{default:\"#000000\",transform:ce,description:\"Color of the cell boundary lines\",ui:{type:\"color\",label:\"Border Color\",group:\"Colors\"}},scale:{default:6,description:\"Number of cells across the canvas\",ui:{type:[\"range\",\"map\"],min:1,max:20,step:.5,label:\"Scale\",group:\"Effect\"}},speed:{default:.5,description:\"Animation speed \\u2014 how fast the cell points drift\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},seed:{default:0,description:\"Random seed \\u2014 shifts the cell pattern without changing the overall structure\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},edgeIntensity:{default:.5,description:\"Controls how much of the cell interior is filled by the edge color. Low = center color dominates with a sharp boundary. High = edge color spreads further into the cell.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Edge Intensity\",group:\"Effect\"}},edgeSoftness:{default:.05,description:\"Width of the cell boundary lines.\",ui:{type:[\"range\",\"map\"],min:0,max:.4,step:.005,label:\"Edge Softness\",group:\"Effect\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}}},paint:rL(Vs(F_(tL(rW,{edgeIntensity:T(\"edgeIntensity\")})),Us(T(\"colorSpace\"))),sL(rW,{softness:T(\"edgeSoftness\"),scale:T(\"scale\")}),{color:T(\"colorBorder\")})});var aW=bt,m1e=JSON.stringify({type:\"sphere3D\",radius:.35}),_1e=.12,f1e=.35,nW=[3,7.5],v1e=.6,iW=[.04,.12],h1e=.75,lW=H({name:\"Voxels\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Rebuild any shape out of voxels \\u2014 a flat shape becomes chunky pixel art, a 3D shape a lit voxel model with smooth ambient occlusion, cast shadows, a key light you can orbit or drive, and per-cube color\",props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the voxel model\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the voxel model (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the voxel model in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},voxelSize:{default:.035,description:\"Edge length of one voxel relative to the shape field \\u2014 small for fine detail, large for chunky blocks\",ui:{type:\"range\",min:.006,max:.15,step:.001,label:\"Voxel Size\",group:\"Voxels\"}},voxelShape:{default:\"cube\",compileTime:!0,description:\"What each cell is built from: hard cubes, rounded cubes (see Bevel) or spheres\",ui:{type:\"select\",options:[{label:\"Cube\",value:\"cube\"},{label:\"Rounded Cube\",value:\"rounded\"},{label:\"Sphere\",value:\"sphere\"}],label:\"Voxel Shape\",group:\"Voxels\"}},voxelScale:{default:1,description:\"Size of each voxel inside its cell \\u2014 1 = touching neighbours, lower opens gaps between the blocks\",ui:{type:\"range\",min:.3,max:1,step:.01,label:\"Voxel Fill\",group:\"Voxels\"}},fill:{default:0,description:\"How eagerly cells fill in along the surface \\u2014 negative carves a thinner model, positive puffs it out\",ui:{type:\"range\",min:-.5,max:.5,step:.01,label:\"Surface Bias\",group:\"Voxels\"}},bevel:{default:.08,description:\"Edge rounding of each voxel as a fraction of its size \\u2014 a hairline chamfer catching light on cubes, the corner radius of rounded cubes\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Bevel\",group:\"Voxels\"}},depth:{default:.12,description:\"Thickness given to flat shapes (2D shapes and flat SVGs) so they become a slab of voxels \\u2014 3D shapes ignore it\",ui:{type:\"range\",min:.01,max:.6,step:.005,label:\"Depth\",group:\"Voxels\"}},gridSpace:{default:\"shape\",compileTime:!0,description:\"Model: the grid rotates with the shape like a built voxel model. Screen: the grid is fixed to the canvas and the shape moves through it like a 3D pixelation\",ui:{type:\"select\",options:[{label:\"Model\",value:\"shape\"},{label:\"Screen\",value:\"view\"}],label:\"Grid\",group:\"Voxels\"}},colorA:{default:\"#6ea8ff\",transform:ce,description:\"Base color of the voxels (the first color of the palette mode)\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#1d2b4f\",transform:ce,description:\"Second palette color \\u2014 blended in by height, depth, per voxel or on the side faces\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},colorMode:{default:\"height\",compileTime:!0,description:\"How the two colors are laid over the model: one solid color, a gradient by height or depth, a random pick per voxel, or Color A on top faces and Color B on the sides\",ui:{type:\"select\",options:[{label:\"Solid\",value:\"solid\"},{label:\"Height\",value:\"height\"},{label:\"Depth\",value:\"depth\"},{label:\"Random\",value:\"random\"},{label:\"Top / Sides\",value:\"faces\"}],label:\"Palette\",group:\"Colors\"}},colorVariation:{default:.25,description:\"Per-voxel tonal jitter \\u2014 the slightly-off shades that make blocks read as individual bricks\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Variation\",group:\"Colors\"}},colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},lightAngle:{default:225,description:\"Direction the key light comes from, in degrees around the canvas \\u2014 shadows fall away from it\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Light Angle\",group:\"Light\"}},lightElevation:{default:42,description:\"How high the key light sits above the canvas \\u2014 low for long raking shadows, high for a flat top-down light\",ui:{type:[\"range\",\"map\"],min:5,max:85,step:1,label:\"Light Elevation\",group:\"Light\"}},lightColor:{default:\"#fff2df\",transform:ce,description:\"color of the key light\",ui:{type:\"color\",label:\"Light Color\",group:\"Light\"}},lightIntensity:{default:1.1,description:\"Strength of the key light\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Light Intensity\",group:\"Light\"}},ambientColor:{default:\"#9fb4d8\",transform:ce,description:\"Sky color of the ambient light \\u2014 the fill on faces the key light misses\",ui:{type:\"color\",label:\"Ambient Color\",group:\"Light\"}},ambient:{default:.55,description:\"Strength of the ambient sky/ground fill\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Ambient\",group:\"Light\"}},shadows:{default:.85,description:\"Darkness of the shadows voxels cast onto each other\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadows\",group:\"Light\"}},shadowSoftness:{default:.35,description:\"Penumbra of the cast shadows \\u2014 0 is razor sharp, higher spreads the light into a soft area source whose shadows sharpen at contact\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Shadow Softness\",group:\"Light\"}},ao:{default:1,description:\"Ambient occlusion in the creases between voxels \\u2014 the soft contact darkening that sells the geometry\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Occlusion\",group:\"Light\"}},glossiness:{default:.35,description:\"How tight the specular highlight is \\u2014 satin plastic at 0, lacquered at 1\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Glossiness\",group:\"Surface\"}},specular:{default:.6,description:\"Strength of the specular highlight and the fresnel rim on grazing faces\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Specular\",group:\"Surface\"}},seams:{default:.2,description:\"Dark seam lines along every voxel edge \\u2014 0 for seamless blocks, higher for a drawn-outline brick look\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Seams\",group:\"Surface\"}},shape:{default:m1e,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...YL({style:T(\"voxelShape\"),gridSpace:T(\"gridSpace\"),voxelSize:T(\"voxelSize\"),fill:T(\"fill\"),voxelScale:T(\"voxelScale\"),bevel:T(\"bevel\"),shadowSoftness:T(\"shadowSoftness\"),lightAngle:T(\"lightAngle\"),lightElevation:T(\"lightElevation\"),depth:T(\"depth\"),surface:(e,t,s)=>{let{uniforms:r,propValues:o}=s,a=e.normal,i=ug(T(\"colorSpace\"),s),l=F=>W(i,\"mixColors\",[r.colorA,r.colorB,F]).member(\"rgb\"),c=z(Ge(er(a.member(\"y\")),0,1),\"upness\"),d;switch(o.colorMode){case\"height\":d=l(ne(1,e.heightT));break;case\"depth\":d=l(e.depthT);break;case\"random\":d=l(e.cellHash);break;case\"faces\":d=l(ne(1,ot(.35,.75,c)));break;default:d=r.colorA.member(\"rgb\")}let u=I(1,v(ne(e.cellHash,.5),v(r.colorVariation,v1e))),p=z(v(d,u),\"albedo\"),_=v(r.lightAngle,aW),f=v(r.lightElevation,aW),h=z(Do(f),\"cosEl\"),g=z(Os(Qe(v(Do(_),h),v(Vt(_),h),er(Vt(f)))),\"L\"),y=z(Pl(a,g,{wrap:_1e}),\"ndl\"),b=z(ne(1,v(e.shadow,r.shadows)),\"lit\"),x=z(v(r.lightColor.member(\"rgb\"),r.lightIntensity),\"keyRgb\"),P=v(x,v(y,b)),C=z(ne(1,v(r.ao,ne(1,e.ao))),\"occl\"),E=z(r.ambientColor.member(\"rgb\"),\"sky\"),R=z(v(v(et(v(E,f1e),E,c),r.ambient),it(C,0)),\"ambient\"),U=e.view,L=v(x,v(v(v(ts(Ge($t(a,z(Os(ne(g,U)),\"H\")),0,1),z(U_(et(nW[0],nW[1],r.glossiness)),\"shininess\")),et(.2,1.4,r.glossiness)),r.specular),b)),k=v(E,v(v(Ap(ni(a,U),{r0:.02,gain:v(r.glossiness,.5)}),v(r.specular,.5)),it(C,0))),D=ot(ne(1,I(iW[0],v(r.seams,iW[1]))),1,e.edge),O=ne(1,v(v(r.seams,h1e),D));return Ot(Ge(v(I(v(p,I(P,R)),I(L,k)),O),Qe(0,0,0),Qe(1,1,1)),e.coverage)}})});var g1e=JSON.stringify({type:\"sphere3D\",radius:.35}),g5=(e,t)=>{let s=z(e,t),r=pa(s),o=v(pa(I(v(s,2.07),rt(4.3,9.1))),.5),a=v(pa(I(v(s,4.13),rt(1.7,8.2))),.25);return v(I(I(r,o),a),.52)},Lp=e=>v(pa(e),.52),cW=(e,t,s,r,o,a,i,l)=>{let c=z(ne(v(e,o),v(t,a)),`${l}Ex`),d=z(I(v(e,a),v(t,o)),`${l}Ey`),u=z(Ge(I(v(d,.5),.5),0,1),`${l}Up`),p=Qe(.9,.96,1),_=Qe(.2,.46,.85),f=et(Qe(.04,.1,.16),et(p,_,kt(ot(.5,1,u))),kt(ot(.4,.55,u))),h=rt(v(s,.8),I(v(r,.8),.12)),g=z(et(.5,.13,i),`${l}SunRad`),y=Kr(ne(rt(c,d),h)),b=ot(g,v(g,.15),y);return I(f,v(Qe(1,.97,.88),v(b,1.5)))},dW=H({name:\"Water\",role:\"shapeEffect\",species:\"custom\",boundingBoxDeclaration:is,category:\"Shape Effects\",description:\"Translucent water \\u2014 a refractive, light-absorbing body that deepens to its color with thickness, wrapped in a wind-driven wave surface that reflects a procedural sky, with Fresnel-bright grazing edges and foam breaking on the crests and shoreline\",animatedTime:{speed:\"speed\"},props:{origin:{default:\"center\",description:\"Reference edge the center position is measured from (center default). Lets you pin the shape relative to a corner or the canvas centre.\",ui:{type:\"origin\",label:\"Origin\",group:\"Position\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center position of the water shape\",ui:{type:\"position\",label:\"Center\",group:\"Position\",units:[\"%\",\"px\"]}},scale:{default:1,description:\"Scale of the water shape (1 = default size)\",ui:{type:\"range\",min:.1,max:3,step:.01,label:\"Scale\",group:\"Position\"}},rotation:{default:0,description:\"Rotation of the water shape in degrees\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Rotation\",group:\"Position\"}},waterColor:{default:\"#00bfeb\",transform:ce,description:\"The color the water saturates toward with depth\",ui:{type:\"color\",label:\"Water Color\",group:\"Water\"}},clarity:{default:.4,description:\"How much of the reflected sky transmits through the body\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Clarity\",group:\"Water\"}},depth:{default:5,description:\"How quickly the water darkens and saturates toward its color with thickness\",ui:{type:\"range\",min:0,max:8,step:.01,label:\"Depth\",group:\"Water\"}},shallows:{default:.5,description:\"Brightness of the thin shallow water at the edges \\u2014 high fades the rim to light translucent water, low keeps the edges close to the deep water color\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Shallows\",group:\"Water\"}},caustics:{default:.15,description:\"Intensity of the light caustics bubbling up through the body \\u2014 bright veins of focused light churning inside the water\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Caustics\",group:\"Water\"}},causticScale:{default:6,description:\"Size of the caustic veins \\u2014 higher = finer, busier light patterns inside the body\",ui:{type:\"range\",min:1,max:20,step:.1,label:\"Caustic Scale\",group:\"Water\"}},choppiness:{default:.8,description:\"Height of the wind-driven waves \\u2014 the depth of the folds that bend the reflection\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Choppiness\",group:\"Waves\"}},waveScale:{default:3.5,description:\"Scale of the wave fronts \\u2014 higher = smaller, busier ripples\",ui:{type:\"range\",min:.5,max:8,step:.01,label:\"Wave Scale\",group:\"Waves\"}},swirl:{default:.6,description:\"Swirl of the flow \\u2014 domain-warps the wave fronts into curling eddies\",ui:{type:\"range\",min:0,max:1.5,step:.01,label:\"Swirl\",group:\"Waves\"}},speed:{default:.5,description:\"Speed of the rolling waves. 0 pauses the surface.\",ui:{type:\"range\",min:0,max:4,step:.01,label:\"Speed\",group:\"Waves\"}},reflection:{default:2,description:\"Strength of the reflected sky across the surface\",ui:{type:\"range\",min:0,max:2,step:.01,label:\"Reflection\",group:\"Surface\"}},envRotation:{default:0,description:\"Rotates the reflected sky \\u2014 spins where the bright sky and sun fall\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Env Rotation\",group:\"Surface\"}},sharpness:{default:.1,description:\"Tightness of the sun glint and reflected sun\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Sharpness\",group:\"Surface\"}},lightAngle:{default:30,description:\"Direction of the sun, in degrees \\u2014 drives the glint and where the sun reflects\",ui:{type:\"range\",min:0,max:360,step:1,label:\"Light Angle\",group:\"Surface\"}},foam:{default:.3,description:\"White foam breaking on the wave crests and along the shoreline edge\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Foam\",group:\"Surface\"}},edgeSoftness:{default:.05,description:\"Softness of the shape boundary edge\",ui:{type:\"range\",min:0,max:1,step:.01,label:\"Edge Softness\",group:\"Surface\"}},shape:{default:g1e,description:\"Serialized shape configuration (JSON)\",ui:{type:\"shape\",label:\"Shape\",group:\"Shape\"}},shapeSdfUrl:{default:\"\",compileTime:!0,description:\"URL to a pre-generated SDF .bin file\"},shapeType:{default:\"\",compileTime:!0,description:\"Active SDF shape type\"}},...Ts({pattern:\"raw\",surface:(e,t)=>{let{uniforms:s}=t,r=wt(t),o=e.volumetric,a=Lr(e,t,{scale:s.scale}),{sdf:i,pxH:l}=a,c=Er(s.lightAngle,\"light\"),d=c.member(\"x\"),u=c.member(\"y\"),p=Er(s.envRotation,\"env\"),_=p.member(\"x\"),f=p.member(\"y\"),h=Ln(a),g;if(o)g=Mc(a);else{let us=z(v(ne(1,Ge(Ce(v(i,-1),.05),0,1)),1.6),\"rimBevel\");g=z(Os(Qe(v(h.member(\"x\"),us),v(h.member(\"y\"),us),-1)),\"nGeo\")}let y=go(e,a),b=y.member(\"x\"),x=y.member(\"y\"),P=z(v(s.waveScale,2.4),\"freq\"),C=z(v(r,.2),\"flowT\"),E=z(rt(v(v(b,P),.8),v(v(x,P),1.25)),\"q\"),R=v(s.swirl,.9),U=z(I(I(E,v(Tg(v(E,.6),C),R)),rt(0,v(C,-1))),\"qw\"),L=.06,k=z(g5(U,\"fbmH0\"),\"h0\"),D=z(Lp(U),\"h0n1\"),O=Ge(Ce(ne(Lp(I(U,rt(L,0))),D),L),-4,4),F=Ge(Ce(ne(Lp(I(U,rt(0,L))),D),L),-4,4),q=.025,Y=z(I(I(v(U,3.3),rt(v(C,1.7),v(C,-1.15))),rt(11.3,4.7)),\"qf\"),V=z(Lp(Y),\"f0n1\"),X=Ge(Ce(ne(Lp(I(Y,rt(q,0))),V),q),-4,4),Q=Ge(Ce(ne(Lp(I(Y,rt(0,q))),V),q),-4,4),te=z(v(s.choppiness,.5),\"relief\"),J=z(v(s.choppiness,.22),\"reliefFine\"),oe=z(Os(Qe(ne(ne(g.member(\"x\"),v(O,te)),v(X,J)),ne(ne(g.member(\"y\"),v(F,te)),v(Q,J)),g.member(\"z\"))),\"n\"),le=z(Ge(s.sharpness,0,1),\"sharp\"),se=z(Lo(Qe(0,0,1),oe),\"R\"),Te=z(v(cW(se.member(\"x\"),se.member(\"y\"),d,u,_,f,le,\"refl\"),s.reflection),\"reflCol\"),de=z(v(Hu(a,e),s.depth),\"thickness\"),xe=z(Ge(v(de,1.3),0,1),\"depthT\"),Ae=z(s.waterColor.member(\"rgb\"),\"wc\"),De=z(wg(de,Qe(v(ne(1,Ae.member(\"x\")),2.2),v(ne(1,Ae.member(\"y\")),2.2),v(ne(1,Ae.member(\"z\")),2.2))),\"transmit\"),Ee=Ge(s.shallows,0,1),ze=z(I(v(et(et(Ae,Qe(1,1,1),kt(Ee)),Ae,kt(xe)),De),v(Ae,v(xe,.18))),\"bodyTint\"),Ie=Un(c,-.7),ke=z(I(v(ts(Ge(I(v($t(oe,Ie.member(\"L\")),.5),.5),0,1),.8),.5),.5),\"diffuse\"),Me=z(ig(Qe(0,0,1),oe,It(1/1.333)),\"tDir\"),we=v(cW(Me.member(\"x\"),Me.member(\"y\"),d,u,_,f,le,\"trans\"),De),Ve=v(Ge(s.clarity,0,1),ne(1,v(xe,.8))),qe=v(et(ze,I(v(we,.6),v(ze,.4)),kt(Ve)),ke),st=z(v(r,3),\"causT\"),pt=z(I(v(rt(b,x),s.causticScale),rt(v(Vt(v(st,.15)),.4),v(v(st,.3),-1))),\"causP\"),Ze=ne(1,ms(g5(pt,\"fbmC1\"))),nt=ne(1,ms(g5(I(v(pt,1.9),rt(3.7,v(v(st,.18),-1))),\"fbmC2\"))),ht=z(ts(Ge(I(v(Ze,.6),v(nt,.4)),0,1),3),\"causV\"),yt=z(v(I(v(xe,.8),.2),s.caustics),\"causMask\"),St=et(I(v(qe,I(1,v(v(ht,yt),.7))),v(Qe(.55,.82,1),v(v(ht,yt),.45))),Te,kt(Ge(Ap(Fi(oe),{gain:.96}),0,1))),Mt=xg(Ge($t(oe,Ie.member(\"H\")),0,1),le,Ot(40,600,.3,1.3)),Rt=I(St,v(Qe(1,.98,.92),Mt)),Kt=z(v(Ge(I(ot(.62,.92,Ge(I(v(k,.5),.5),0,1)),v(ne(1,ot(0,.045,v(i,-1))),.7)),0,1),s.foam),\"foamMask\"),Wt=z(et(Rt,Qe(1,1,1),kt(v(Kt,.85))),\"waterRgb\"),ls=Jr(a,s.edgeSoftness);return Js(Dr(i,l),Ot(Wt,ls),xt,\"water\")}})});var uW=W8({amount:T(\"bleed\")}),pW=H({name:\"Watercolor\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Painterly watercolor look \\u2014 Kuwahara flattening, pigment edge darkening, paper grain and bleeding\",props:{radius:{default:3,compileTime:!0,description:\"Brush size \\u2014 radius of the painterly flattening\",ui:{type:\"range\",min:1,max:8,step:1,label:\"Brush\",group:\"Effect\",hidden:!0}},bleed:{default:1,recompile:Lt(0),description:\"Amount the pigment bleeds and wobbles past hard edges\",ui:{type:[\"range\",\"map\"],min:0,max:3,step:.01,label:\"Bleed\",group:\"Effect\"}},strength:{default:1,recompile:Lt(0),description:\"Blend between the original image (0) and the full watercolor effect (1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},paper:{default:.35,recompile:Lt(0),description:\"Strength of the paper grain the pigment settles into\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Paper\",group:\"Effect\"}},paperColor:{default:\"#fbf7ec\",transform:ce,description:\"Tint of the paper grain\",ui:{type:\"color\",label:\"Paper Color\",group:\"Colors\"}}},effect:N8({at:uW,brush:q8({at:uW,radius:T(\"radius\")}),grain:V8({amount:T(\"paper\")}),paper:T(\"paper\"),paperColor:T(\"paperColor\"),strength:T(\"strength\")})});var mW=H({name:\"WaveDistortion\",role:\"warp\",category:\"Distortions\",description:\"Wave-based distortion with multiple waveform types\",boundingBoxDeclaration:{aspectRatio:null},animatedTime:{speed:\"speed\"},props:{strength:{default:.3,description:\"Distortion intensity\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Strength\",group:\"Effect\"}},frequency:{default:1,description:\"Number of bends/waves\",ui:{type:[\"range\",\"map\"],min:.1,max:10,step:.1,label:\"Frequency\",group:\"Effect\"}},speed:{default:1,description:\"Animation speed\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}},angle:{default:0,description:\"Direction of wave distortion in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Angle\",group:\"Effect\"}},waveType:{default:\"sine\",description:\"Shape of the distortion wave\",compileTime:!0,transform:e=>({sine:0,triangle:1,square:2,sawtooth:3,bounce:4})[e]??0,ui:{type:\"select\",options:[{label:\"Sine\",value:\"sine\"},{label:\"Triangle\",value:\"triangle\"},{label:\"Square\",value:\"square\"},{label:\"Sawtooth\",value:\"sawtooth\"},{label:\"Bounce\",value:\"bounce\"}],label:\"Wave Type\",group:\"Effect\"}},edges:fr(\"stretch\",\"How to handle edges when distortion pushes content out of bounds\")},map:QL({strength:T(\"strength\"),frequency:T(\"frequency\"),angle:T(\"angle\"),waveType:T(\"waveType\")}),missingChildMessage:\"You must pass a child component into the WaveDistortion shader.\"});var y1e=[{waves:[{x:5.1,t:1.3}],weight:.28},{waves:[{x:9.7,t:-1.9},{x:1.7,t:.6}],weight:.24},{waves:[{x:17.3,t:2.7}],weight:.18},{waves:[{x:31.9,t:-3.4},{x:3.3,t:-.9}],weight:.14},{waves:[{x:67.7,t:4.1}],weight:.09},{waves:[{x:131.3,t:-5.3},{x:7.9,t:1.1}],weight:.07}],b1e=.4,x1e=4,A1e=.45,w1e=.6,y5=.002,_W={bars:0,wave:1,line:2,dots:3},fW={mirrored:0,top:1,bottom:2},T1e=e=>typeof e==\"number\"?Object.keys(_W)[e]??\"bars\":e===\"wave\"||e===\"line\"||e===\"dots\"?e:\"bars\",S1e=e=>typeof e==\"number\"?Object.keys(fW)[e]??\"mirrored\":e===\"top\"||e===\"bottom\"?e:\"mirrored\",vW=H({name:\"Waveform\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Audio-visualizer waveform \\u2014 equalizer bars, a filled wave, an oscilloscope line, or a dot matrix \\u2014 driven by a simulated signal whose amplitude you can map to your own audio level\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{style:{default:\"bars\",transform:e=>_W[e]??0,compileTime:!0,description:\"Visualizer style: equalizer bars, a filled wave envelope, an oscilloscope line, or a dot matrix\",ui:{type:\"select\",options:[{label:\"Bars\",value:\"bars\"},{label:\"Wave\",value:\"wave\"},{label:\"Line\",value:\"line\"},{label:\"Dots\",value:\"dots\"}],label:\"Style\",group:\"Style\"}},colorA:{default:\"#3b5bff\",transform:ce,description:\"Color at the start\",ui:{type:\"color\",label:\"Color A\",group:\"Colors\"}},colorB:{default:\"#ff3bd4\",transform:ce,description:\"Color at the end\",ui:{type:\"color\",label:\"Color B\",group:\"Colors\"}},stops:Ms(),colorSpace:{default:\"oklab\",transform:at,compileTime:!0,description:\"Color space for the start\\u2192end gradient\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},from:{default:{x:0,y:.5},transform:Xe,description:\"Where the waveform starts (Color A end)\",ui:{type:\"position\",label:\"Start\",group:\"Position\",units:[\"%\",\"px\"]}},to:{default:{x:1,y:.5},transform:Xe,description:\"Where the waveform ends (Color B end)\",ui:{type:\"position\",label:\"End\",group:\"Position\",units:[\"%\",\"px\"]}},amplitude:{default:1,description:\"Overall signal level (0 = silence). Map this to your own audio level to make the waveform react to real sound.\",ui:{type:[\"range\",\"map\"],min:0,max:2,step:.01,label:\"Amplitude\",group:\"Signal\"}},frequency:{default:1,description:\"How busy the signal is across the width (higher = more peaks)\",ui:{type:[\"range\",\"map\"],min:.2,max:3,step:.01,label:\"Frequency\",group:\"Signal\"}},height:{default:.6,description:\"Maximum vertical extent of the waveform as a fraction of the canvas height\",ui:{type:[\"range\",\"map\"],min:.05,max:1,step:.01,label:\"Height\",group:\"Effect\"}},align:{default:\"mirrored\",transform:e=>fW[e]??0,compileTime:!0,description:\"Which side of the start\\u2192end baseline the waveform grows on: mirrored around it, above it (top), or below it (bottom)\",ui:{type:\"select\",options:[{label:\"Mirrored\",value:\"mirrored\"},{label:\"Top\",value:\"top\"},{label:\"Bottom\",value:\"bottom\"}],label:\"Align\",group:\"Effect\"}},count:{default:32,description:\"Number of bars (or dot columns) across the width\",ui:{type:[\"range\",\"map\"],min:4,max:128,step:1,label:\"Count\",group:\"Effect\",condition:{style:[\"bars\",\"dots\"]}}},barWidth:{default:.6,description:\"Bar thickness as a fraction of its column (1 = bars touch)\",ui:{type:[\"range\",\"map\"],min:.1,max:1,step:.01,label:\"Bar Width\",group:\"Effect\",condition:{style:\"bars\"}}},rounding:{default:1,description:\"Rounds the bar ends (0 = square, 1 = fully rounded caps)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Rounding\",group:\"Effect\",condition:{style:\"bars\"}}},dotSize:{default:.7,description:\"Dot diameter as a fraction of its cell\",ui:{type:[\"range\",\"map\"],min:.2,max:1,step:.01,label:\"Dot Size\",group:\"Effect\",condition:{style:\"dots\"}}},lineWidth:{default:.006,description:\"Stroke thickness of the line. A value of one (1) matches the canvas height.\",ui:{type:[\"range\",\"map\"],min:.001,max:.05,step:.001,label:\"Line Width\",group:\"Effect\",dimensional:\"canvas-height\",condition:{style:\"line\"}}},softness:{default:0,description:\"Feathers the wave's edge into a glow\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Softness\",group:\"Effect\",condition:{style:\"wave\"}}},speed:{default:1,description:\"Animation speed of the simulated signal\",ui:{type:\"range\",min:0,max:3,step:.01,label:\"Speed\",group:\"Animation\"}},seed:{default:1,description:\"Adjusts the starting state, useful for variation\",ui:{type:\"range\",min:0,max:100,step:1,label:\"Seed\",group:\"Animation\"}}},paint:e=>{let t=T1e(e.propValues.style),s=S1e(e.propValues.align),{viewport:r}=aa(e),o=V=>me(T(V),e),{along:a,across:i,length:l}=Pg({from:T(\"from\"),to:T(\"to\")})(e,aa(e)),c=z(Ce(a,l),\"wfX\"),d=z(Ce(1,r.member(\"y\")),\"wfPx\"),u=z(wt(e,\"seed\"),\"wfTime\"),p=o(\"amplitude\"),_=o(\"frequency\"),f=o(\"height\"),h=V=>vp({x:v(V,_),t:u},y1e),g=V=>et(b1e,1,O_(ne(V,.5),x1e)),y=V=>Ge(v(v(h(V),g(V)),p),-1,1),b=V=>Ge(v(v(I(A1e,v(h(V),w1e)),g(V)),p),0,1),x=s===\"mirrored\",P=z(s===\"top\"?er(i):i,\"wfDy\"),C=x?ms(P):P,E=V=>v(v(V,f),x?.5:1),R=V=>x?ne(C,V):it(ne(C,V),er(C)),U=o(\"count\"),L=z(Ce(l,U),\"wfCell\"),k=z(v(c,U),\"wfXCells\"),D=z(Ce(I(Xr(k),.5),U),\"wfColX\"),O=z(v(ne(Qr(k),.5),L),\"wfColDx\"),F;if(t===\"bars\"){let V=z(v(v(o(\"barWidth\"),L),.5),\"wfHalfW\"),X=z(it(E(b(D)),x?V:v(V,2)),\"wfExtent\"),Q=x?X:v(X,.5);F=mp({distance:dg(O,x?P:ne(P,Q),V,Q,v(o(\"rounding\"),V)),footprint:d})}else if(t===\"dots\"){let V=z(Ce(C,L),\"wfRows\"),X=z(v(I(Xr(V),.5),L),\"wfRowY\"),Q=z(E(b(D)),\"wfExtent\"),te=v(ne(1,ot(ne(Q,v(L,.5)),I(Q,v(L,.5)),X)),x?1:ag(0,C)),J=v(v(o(\"dotSize\"),L),.5);F=v(mp({distance:_p(O,v(ne(Qr(V),.5),L),J),footprint:d}),te)}else if(t===\"line\"){let V=te=>E(x?y(te):b(te)),X=z(V(c),\"wfCurve\"),Q=z(Ce(ne(V(I(c,y5)),V(ne(c,y5))),v(2*y5,l)),\"wfSlope\");F=eR({distance:Ce(ne(P,X),ho(I(1,v(Q,Q)))),width:o(\"lineWidth\"),footprint:d})}else F=mp({distance:R(z(E(b(c)),\"wfExtent\")),footprint:I(d,v(o(\"softness\"),.2))});let q=mp({distance:it(er(a),ne(a,l)),footprint:d}),Y=z(Us(T(\"colorSpace\"))(c,e),\"wfColor\");return Ot(Y.member(\"rgb\"),v(v(Y.member(\"a\"),F),q))}});var hW=H({name:\"WaveletNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Rotating banded wavelets that ripple as they animate\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{...ma(),scale:{default:1.5,description:\"Pattern scale (higher = larger patterns)\",ui:{type:\"range\",min:-2,max:5,step:.1,label:\"Scale\",group:\"Effect\"}},detail:{default:1.24,description:\"Per-octave frequency ratio \\u2014 higher adds finer wavelet detail\",ui:{type:\"range\",min:1.05,max:2,step:.01,label:\"Detail\",group:\"Effect\"}},...Ja(),...In()},paint:Vs(ua(Qa(gp(ND({detail:T(\"detail\")})),{scale:T(\"scale\"),seed:T(\"seed\")}),{contrast:T(\"contrast\"),balance:T(\"balance\")}),Us(T(\"colorSpace\")))});var gW=H({name:\"Weave\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Interlaced textile weave pattern with two thread colors going over and under each other\",acceptsUVContext:!0,props:{colorA:{default:\"#c4c4c4\",transform:ce,description:\"Horizontal thread color\",ui:{type:\"color\",label:\"X Color\",group:\"Colors\"}},colorB:{default:\"#4d4d4d\",transform:ce,description:\"Vertical thread color\",ui:{type:\"color\",label:\"Y Color\",group:\"Colors\"}},cells:{default:10,description:\"Number of threads across the shortest canvas edge\",ui:{type:[\"range\",\"map\"],min:2,max:40,step:1,label:\"Cells\",group:\"Effect\"}},gap:{default:.25,description:\"Gap between threads (0 = no gap, 0.5 = maximum gap)\",ui:{type:[\"range\",\"map\"],min:0,max:.45,step:.01,label:\"Gap\",group:\"Effect\"}},rotation:{default:0,description:\"Rotation of the weave pattern in degrees\",ui:{type:[\"range\",\"map\"],min:0,max:360,step:1,label:\"Rotation\",group:\"Effect\"}}},paint:sD({frame:Rn({cells:T(\"cells\"),rotation:T(\"rotation\"),convention:\"plain\"}),gap:T(\"gap\"),colors:[T(\"colorA\"),T(\"colorB\")]})});var yW=H({name:\"WebcamTexture\",role:\"media\",species:\"custom\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Display a live webcam feed with customizable object-fit modes\",acceptsUVContext:!0,naturalSizeKey:{fixed:\"webcam\"},props:{objectFit:up(\"cover\",\"How the webcam feed should be sized within the viewport\",{allowNone:!0}),mirror:{default:!0,description:\"Mirror the webcam feed horizontally (selfie mode)\",ui:{type:\"checkbox\",label:\"Mirror\",group:\"Effect\"}}},...OL({fit:T(\"objectFit\"),mirror:T(\"mirror\"),decode:\"srgb-linear-alpha-cut\",constraints:{video:{width:{ideal:1280},height:{ideal:720},facingMode:\"user\"},audio:!1},naturalSizeKey:\"webcam\",onError:e=>{e instanceof DOMException?e.name===\"NotAllowedError\"?console.error(\"[WebcamTexture] Camera permission denied by user\"):e.name===\"NotFoundError\"?console.error(\"[WebcamTexture] No camera found on this device\"):e.name===\"NotReadableError\"?console.error(\"[WebcamTexture] Camera is already in use by another application\"):console.error(\"[WebcamTexture] Camera error:\",e.message):console.error(\"[WebcamTexture] Failed to start webcam:\",e)}})});var bW=H({name:\"Wool\",role:\"filter\",species:\"custom\",requiresRTT:!0,requiresChild:!0,boundingBoxDeclaration:{aspectRatio:null},category:\"Stylize\",description:\"Applies an interwoven fibrous fabric texture and distortion to child content\",props:Gg({intensity:.5,scale:4,contrast:-.5,distortion:.15}),gpu:{fragment:gg(hg.wool)}});var xW=H({name:\"WorleyNoise\",role:\"generator\",boundingBoxDeclaration:{aspectRatio:null,supportsResizeFit:!0},category:\"Textures\",description:\"Cellular noise field \\u2014 distance-based, with selectable feature combinations and fractal octaves\",acceptsUVContext:!0,animatedTime:{speed:\"speed\"},props:{colorA:{default:\"#ffffff\",transform:ce,description:\"Color where the noise field is low (typically near cell centers)\",ui:{type:\"color\",label:\"Color A (Low)\",group:\"Colors\"}},colorB:{default:\"#000000\",transform:ce,description:\"Color where the noise field is high (typically near cell boundaries)\",ui:{type:\"color\",label:\"Color B (High)\",group:\"Colors\"}},colorSpace:{default:\"linear\",transform:at,compileTime:!0,description:\"Color space for color interpolation\",ui:{type:\"select\",options:dt,label:\"Color Space\",group:\"Colors\"}},scale:{default:6,description:\"Number of cells across the canvas at the base octave\",ui:{type:[\"range\",\"map\"],min:1,max:30,step:.5,label:\"Scale\",group:\"Effect\"}},mode:{default:\"f1\",transform:lL,compileTime:!0,description:\"Field type. F1 = distance to nearest point. F2 = distance to second-nearest. F2 \\u2212 F1 emphasises cell boundaries.\",ui:{type:\"select\",options:[{label:\"F1 (Cells)\",value:\"f1\"},{label:\"F2 (Wider Cells)\",value:\"f2\"},{label:\"F2 \\u2212 F1 (Edges)\",value:\"f2MinusF1\"},{label:\"F1 + F2\",value:\"f1PlusF2\"},{label:\"F1 \\xD7 F2\",value:\"f1TimesF2\"}],label:\"Mode\",group:\"Effect\"}},distance:{default:\"euclidean\",transform:cL,compileTime:!0,description:\"Distance metric. Euclidean = round cells. Manhattan = diamond. Chebyshev = square.\",ui:{type:\"select\",options:[{label:\"Euclidean\",value:\"euclidean\"},{label:\"Manhattan\",value:\"manhattan\"},{label:\"Chebyshev\",value:\"chebyshev\"}],label:\"Distance\",group:\"Effect\"}},octaves:{default:1,compileTime:!0,description:\"Number of fractal layers stacked at progressively finer scales\",ui:{type:\"range\",min:1,max:4,step:1,label:\"Octaves\",group:\"Effect\"}},lacunarity:{default:2,description:\"Scale multiplier between octaves (only active when Octaves > 1)\",ui:{type:[\"range\",\"map\"],min:1.5,max:4,step:.1,label:\"Lacunarity\",group:\"Effect\",condition:{octaves:[2,3,4]}}},persistence:{default:.5,description:\"Amplitude multiplier between octaves (only active when Octaves > 1)\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Persistence\",group:\"Effect\",condition:{octaves:[2,3,4]}}},jitter:{default:1,description:\"How much each cell's point drifts inside its cell. 0 = rigid grid (banded look), 1 = fully random.\",ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Jitter\",group:\"Effect\"}},contrast:{default:1,description:\"Steepness of the gradient between low and high regions\",ui:{type:[\"range\",\"map\"],min:.25,max:4,step:.01,label:\"Contrast\",group:\"Effect\"}},balance:{default:0,description:\"Shifts the gradient midpoint. Negative pulls the field toward Color A, positive toward Color B.\",ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Balance\",group:\"Effect\"}},seed:{default:0,description:\"Random seed \\u2014 shifts the cell pattern without changing its overall structure\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Seed\",group:\"Effect\"}},speed:{default:.5,description:\"Animation speed \\u2014 how fast each cell's point drifts\",ui:{type:\"range\",min:0,max:5,step:.1,label:\"Speed\",group:\"Animation\"}}},paint:JD({scale:T(\"scale\"),jitter:T(\"jitter\"),lacunarity:T(\"lacunarity\"),persistence:T(\"persistence\"),contrast:T(\"contrast\"),balance:T(\"balance\"),seed:T(\"seed\"),mode:T(\"mode\"),distance:T(\"distance\"),octaves:T(\"octaves\"),space:T(\"colorSpace\")})});var AW=H({name:\"ZoomBlur\",role:\"filter\",species:\"gather\",boundingBoxDeclaration:{aspectRatio:null},category:\"Blurs\",description:\"Radial zoom blur expanding from a center point\",props:{intensity:{default:30,description:\"Intensity of the zoom blur effect\",ui:{type:[\"range\",\"map\"],min:0,max:100,step:1,label:\"Intensity\",group:\"Effect\"}},center:{default:{x:.5,y:.5},transform:Xe,description:\"Center point of the zoom blur\",ui:{type:\"position\",label:\"Center\",group:\"Position\"}},dispersion:{default:0,description:\"Spectral color fringing along the streak, like light through a lens; negative flips which end is red\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Dispersion\",group:\"Lens\"}},falloff:{default:0,description:\"Concentrates the dispersion away from the center; 0 fringes everywhere equally\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Falloff\",group:\"Lens\"}},focus:{default:0,description:\"Radius of a clean zone around the center that stays sharp\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Focus\",group:\"Lens\"}},bias:{default:0,description:\"Slides the streak window: 0 streaks inward from each pixel, 1 streaks evenly both ways, -1 pushes it further in\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Bias\",group:\"Streak\"}},highlights:{default:0,description:\"Lets bright pixels streak further than dark ones, like light rays\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Highlights\",group:\"Streak\"}},spiral:{default:0,description:\"Twists the radial streak into a vortex around the center\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:-1,max:1,step:.01,label:\"Spiral\",group:\"Streak\"}},jitter:{default:0,description:\"Per-pixel noise on the tap spacing that hides banding in long streaks\",recompile:Lt(0),ui:{type:[\"range\",\"map\"],min:0,max:1,step:.01,label:\"Jitter\",group:\"Streak\"}}},effect:Tp({path:wp.zoom(T(\"center\")),amount:T(\"intensity\"),detail:{dispersion:T(\"dispersion\"),falloff:T(\"falloff\"),focus:T(\"focus\"),bias:T(\"bias\"),highlights:T(\"highlights\"),spiral:T(\"spiral\"),jitter:T(\"jitter\")}})});var P1e=()=>{let e={};return Object.entries({AngularBlur:MO,Arc:EO,Ascii:Vg,Aurora:RO,BarnDoors:DO,BarShift:LO,Beam:UO,Bend:OO,Blob:GO,BlockDissolve:FO,BlockNoise:YO,BlueNoise:WO,Blur:qO,Boids:$O,BokehBlur:XO,BrickPattern:jO,BrightnessContrast:KO,BrushedMetal:QO,Bulge:ZO,CarbonFiber:JO,Chalkboard:eG,ChannelBlur:tG,Checkerboard:sG,CheckerWipe:rG,Chevron:aG,ChromaFlow:nG,ChromaticAberration:iG,Chrome:lG,Circle:cG,ColorWheel:dG,CompressionArtifacts:_G,ConcentricSpin:fG,ConicGradient:vG,ContourLines:hG,CornerPin:gG,Crescent:yG,Cross:bG,CRTScreen:xG,Crystal:AG,CurlNoise:wG,CursorRipples:TG,CursorTrail:PG,DataMosh:EG,DiamondGradient:kG,DiamondWipe:BG,DiffuseBlur:zG,DisplacementMap:RG,Dither:LG,DotGrid:UG,DropShadow:OG,Duotone:GG,Ellipse:FG,Emboss:yO,Engraving:IG,ErosionNoise:YG,Exposure:WG,FallingLines:NG,FilmGrain:$G,FilmStock:jG,Flip:KG,FloatingParticles:eF,Flower:tF,FlowField:sF,FlowingGradient:rF,FlutedGlass:aF,Fog:uF,Form3D:xO,FractalNoise:pF,Frost:mF,GaborNoise:_F,Glass:vF,GlassTiles:hF,Glitch:gF,Glow:yF,Godrays:bF,Goo:wF,GradientMap:TF,Grayscale:SF,Grid:CF,GridDistortion:MF,Group:EF,Halftone:kF,Heart:BF,Heatmap:zF,HexGrid:DF,Hologram:LF,Holographic:OF,HTMLInCanvas:GF,HueShift:FF,ImageTexture:IF,InkFlow:jF,Invert:KF,IrisWipe:QF,Irradiance:eI,IsometricCubes:tI,Kaleidoscope:sI,KeyFrames:rI,LensDistortion:oI,LensFlare:aI,LightEdge:nI,LightLeak:iI,Line:dI,LinearBlur:uI,LinearGradient:pI,LinearWipe:mI,LiquidMetal:fI,Liquify:vI,MagneticFilings:xI,Marble:AI,MeshGradient:TI,Mirror:SI,MultiPointGradient:PI,Nebula:CI,Neon:fO,NoiseDissolve:MI,ObjectTracker:EI,Obsidian:kI,PagePeel:BI,Paper:zI,Parallelogram:RI,ParticleField:FI,ParticleFlow:HI,Particles:r9,PerlinNoise:o9,Perspective:a9,Pixelate:n9,PixelSort:l9,PixelThrow:u9,Plasma:p9,Plastic:m9,PolarCoordinates:_9,Polygon:f9,Posterize:v9,Prism:h9,ProgressiveBlur:g9,RadialGradient:y9,RadialWipe:b9,RandomBars:x9,ReactionDiffusion:E9,RectangularCoordinates:k9,ReflectivePlane:B9,Repeater:z9,Ring:R9,Ripples:D9,RippleWipe:L9,RoundedRect:U9,Satin:q9,Saturation:V9,Scratches:N9,Sharpness:$9,Shatter:H9,SimplexNoise:j9,SineWave:K9,SliceWipe:Q9,Smoke:sY,SmokeFill:nY,SmokeFlow:uY,Solarize:pY,SolidColor:mY,Sparkle:fY,Spherize:hY,Spiral:gY,Star:yY,Stone:bY,Strands:xY,Stretch:AY,Stripes:wY,StudioBackground:SY,SunBurst:PY,Surface3D:kY,Swirl:zY,Teardrop:RY,Text:h5,ThinFilm:CO,TiltShift:FY,TimeTrail:qY,Tint:VY,Trapezoid:NY,TriangularGrid:XY,Tritone:HY,Truchet:jY,Twirl:KY,VenetianBlinds:QY,Vesica:ZY,VHS:JY,Vibrance:eW,VideoTexture:tW,Vignette:sW,Voronoi:oW,Voxels:lW,Water:dW,Watercolor:pW,WaveDistortion:mW,Waveform:vW,WaveletNoise:hW,Weave:gW,WebcamTexture:yW,Wool:bW,WorleyNoise:xW,ZoomBlur:AW}).forEach(([s,r])=>{let o={};r.props&&Object.entries(r.props).forEach(([a,i])=>{i.ui&&(o[a]={ui:i.ui,default:i.default,description:i.description})}),e[r.name]={name:r.name,fileName:s,category:r.category||\"Uncategorized\",definition:r,propsMetadata:o}}),e},of=P1e(),C1e=(()=>{let e={};for(let t of Object.values(of))for(let s of t.definition.deprecatedNames??[])e[s]=t.name;return e})();function M1e(e){return of[e]?e:C1e[e]??e}function my(){return Object.values(of)}function b5(e){return of[M1e(e)]}var E1e=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(Fh({in:{vertexIndex:Qo.vertexIndex},out:{pos:Qo.position,uv:ps}})`{\n  const pos = array<vec2f, 3>(vec2f(-1, -1), vec2f(3, -1), vec2f(-1, 3));\n  const uv = array<vec2f, 3>(vec2f(0, 1), vec2f(2, 1), vec2f(0, -1));\n\n  return Out(vec4f(pos[in.vertexIndex], 0, 1), uv[in.vertexIndex]);\n}`,\"fullScreenTriangle\");LC.disable(\"external-omitted\");var k1e=[\"float32-filterable\",\"timestamp-query\"],A5=new WeakMap,x5=new WeakMap,w5=new WeakSet,Up=null,B1e=new WeakSet;async function z1e(e={}){if(e.device&&!w5.has(e.device)){let r=e.device,o=A5.get(r);o||(o=w.initFromDevice({device:r}),A5.set(r,o));let a=wW(o,e.onDeviceLost);return{root:o,device:r,adapter:e.adapter,createdDevice:!1,release:a}}e.device&&di(\"[gpu] injected GPU device was lost \\u2014 falling back to the shared default device\");let t=await R1e(),s=wW(t.root,e.onDeviceLost);return{root:t.root,device:t.device,adapter:t.adapter,createdDevice:!1,release:s}}async function R1e(){for(;;){let t=Up;if(!t)break;let s=await t.catch(()=>null);if(s&&!B1e.has(t)&&!w5.has(s.device))return s;Up===t&&(Up=null)}let e=D1e();Up=e;try{return await e}catch(t){throw Up===e&&(Up=null),t}}async function D1e(){if(typeof navigator>\"u\"||!navigator.gpu)throw new Kd(\"unsupported\",\"[gpu] WebGPU is not available in this environment (navigator.gpu is undefined).\");let e;try{e=await w.init({adapter:{powerPreference:\"high-performance\"},device:{optionalFeatures:k1e}})}catch(t){let s=await G5();throw new Kd(s.supported?\"no-device\":s.reason??\"init-failed\",void 0,{cause:t})}if(!e.device)throw new Kd(\"no-device\",\"[gpu] adapter returned no device.\");return A5.set(e.device,e),{root:e,device:e.device,createdDevice:!0}}function L1e(e,t,s={}){return e.configureContext({canvas:t,alphaMode:\"premultiplied\",...s})}function wW(e,t){let s=e.device,r=x5.get(s);if(r||(r=new Set,x5.set(s,r),e.device.lost.then(a=>{if(w5.add(s),a.reason!==\"destroyed\")for(let i of[...x5.get(s)??[]])i(a)})),!t)return()=>{};let o=r;return o.add(t),()=>o.delete(t)}function U1e(){let e={value:0,advance(t,s){e.value+=t*s}};return e}var TW=new WeakMap;function zl(e){let t=TW.get(e);return t||(t=U1e(),TW.set(e,t)),t}var O1e=(globalThis.__TYPEGPU_AUTONAME__??(e=>e))(gt({time:n,viewportSize:m,logicalViewportSize:m,aspect:n,pointer:m,pointerActive:n}),\"SystemUniforms\");w.fn([m,m],m)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=((t,s)=>{\"use gpu\";return ra(t,s)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"uv\"},{type:\"i\",name:\"viewportSize\"}],body:[0,[[10,[6,\"std.mul\",[\"uv\",\"viewportSize\"]]]]]},externals:{\"std.mul\":()=>ra}})&&e.f)({}));w.fn([m],n)((e=>(globalThis.__TYPEGPU_META__??=new WeakMap).set(e.f=(t=>{\"use gpu\";return __tsover_div(t.x,t.y)}),{v:2,name:void 0,ast:{params:[{type:\"i\",name:\"viewportSize\"}],body:[0,[[10,[1,[7,\"viewportSize\",\"x\"],\"/\",[7,\"viewportSize\",\"y\"]]]]]},externals:{}})&&e.f)({}));function G1e(e){let t=2166136261,s=e.join(\"\u0001\");for(let r=0;r<s.length;r++)t^=s.charCodeAt(r),t=Math.imul(t,16777619);return`${(t>>>0).toString(16).padStart(8,\"0\")}:${s.length}`}function F1e(e={}){let t=e.maxSize??4,s=e.dispose,r=new Map,o=0,a=null,i=null;function l(d){d.lastUsed=++o}function c(){for(;r.size>t;){let d=null;for(let u of r.values())u.hash===a||u.hash===i||(!d||u.lastUsed<d.lastUsed)&&(d=u);if(!d)break;r.delete(d.hash),s?.(d.value,d.hash)}}return{getOrBuild(d,u){let p=r.get(d);if(p)return l(p),d===a?i=null:i=d,p.value;let _=u(),f={hash:d,value:_,lastUsed:++o};return r.set(d,f),a===null?(a=d,i=null):i=d,c(),_},markReady(d){if(d!==i)return;let u=r.get(d);u&&(a=d,i=null,l(u),c())},get renderValue(){let d=a??i;return d?r.get(d)?.value??null:null},get activeHash(){return a},get pendingHash(){return i},release(d){let u=r.get(d);u&&(r.delete(d),s?.(u.value,d),a===d&&(a=null),i===d&&(i=null))},has(d){return r.has(d)},get size(){return r.size},clear(){for(let d of r.values())s?.(d.value,d.hash);r.clear(),a=null,i=null}}}var Op=\"passManager\";function I1e(e,t){let{textureManager:s,dispatcher:r}=t,o=t.canvasFormat??Y1e(),a=t.rttFormat??\"rgba16float\",i=e.device?.limits?.maxSampledTexturesPerShaderStage,l=t.maxSampledTextures??(typeof i==\"number\"&&i>0?i:16),c=t.fullScreenTriangle??E1e,d=new Map,u=new Set,p=null;function _(){let k=s.samplers;try{return e.createBindGroup(V3,{linearClamp:k.linearClamp,nearestClamp:k.nearestClamp,linearRepeat:k.linearRepeat,nearestRepeat:k.nearestRepeat})}catch(D){Sr(`[${Op}] failed to build sampler bind group:`,D);return}}function f(k,D){let O=new Set;for(let F of k.textures)if(F.kind===\"rtt\")if(O.add(F.key),d.has(F.key))d.get(F.key).resize(D.width,D.height);else{let q=s.createRenderTexture({width:D.width,height:D.height,format:a,label:`rtt:${F.key}`});d.set(F.key,q),u.add(q)}for(let[F,q]of[...d])O.has(F)||(q.destroy(),u.delete(q),d.delete(F))}function h(k,D){if(!k.textureLayout||k.reads.length===0)return;let O={};for(let F of k.reads){let q=d.get(F),Y=D?.[F],V=q??Y;if(!V){Sr(`[${Op}] pass \"${k.entry}\" reads unknown texture \"${F}\"`);return}O[F]=V.texture}k.reads.length>l&&di(`[${Op}] pass samples ${k.reads.length} textures (> device limit ~${l}); composition may fail on this device.`);try{return e.createBindGroup(k.textureLayout,O)}catch(F){Sr(`[${Op}] failed to build texture bind group:`,F);return}}function g(k,D){return e.createRenderPipeline({vertex:c,fragment:k.entry,targets:{format:D}})}function y(k,D){if(!k.externalLayout||k.externalReads.length===0)return;let O=k.externalReads;if(O.length===1){let q=D.get(O[0]);if(!q){Sr(`[${Op}] external read \"${O[0]}\" has no registered source`);return}return s.createExternalTextureBinding({layout:k.externalLayout,entryKey:O[0],getSource:q})}let F=null;return{update(){let q={};for(let Y of O){let V=D.get(Y)?.();if(!V)return F=null,null;try{q[Y]=e.device.importExternalTexture({source:V})}catch{return F=null,null}}return F=e.createBindGroup(k.externalLayout,q),F},get current(){return F},destroy(){F=null}}}function b(k,D,O,F){let q=D.kind===\"canvas\"?o:a,Y=k.reads.filter(X=>O?.[X]),V=new Map(Y.map(X=>[X,O[X].texture]));return{fragment:k,pipeline:g(k,q),textureBindGroup:h(k,O),externalBinding:y(k,F),target:D,mediaReads:Y,mediaSnapshot:V}}function x(k,D,O,F){f(k,O);for(let Q of k.computeSteps)Q.bindInputs?.(te=>d.get(te)??F?.[te]);let q=_(),Y=new Map;for(let Q of k.externalTextures)Y.set(Q.key,Q.getSource);let V=k.rttPasses.map(Q=>b(Q.fragment,{kind:\"rtt\",key:Q.textureKey},F,Y)),X=b(k.finalPass,{kind:\"canvas\"},F,Y);p={ir:k,uniformBindGroup:D,samplerBindGroup:q,computeSteps:k.computeSteps,rttPasses:V,finalPass:X,size:O,mediaResources:F}}function P(k,D){let O=k.pipeline;if(p?.uniformBindGroup&&(O=O.with(p.uniformBindGroup)),k.mediaReads&&k.mediaReads.length>0&&p?.mediaResources){let F=!1;for(let q of k.mediaReads)p.mediaResources[q].texture!==k.mediaSnapshot.get(q)&&(F=!0);if(F){k.textureBindGroup=h(k.fragment,p.mediaResources);for(let q of k.mediaReads)k.mediaSnapshot.set(q,p.mediaResources[q].texture)}}if(k.textureBindGroup&&(O=O.with(k.textureBindGroup)),k.fragment.usesSamplers&&p?.samplerBindGroup&&(O=O.with(p.samplerBindGroup)),k.fragment.externalReads.length>0){let F=k.externalBinding?.update()??null;if(!F){k.externalSkipLogged||(di(`[${Op}] external texture not ready \\u2014 skipping pass (${k.fragment.externalReads.join(\", \")})`),k.externalSkipLogged=!0);return}O=O.with(F)}O.withColorAttachment({view:D}).draw(3)}function C(k,D,O){if(p){for(let F of p.computeSteps){let q=F.getComputeNodes(D);q&&q.length&&r.dispatch(q)}O?.(),E(),P(p.finalPass,k)}}function E(){if(p)for(let k of p.rttPasses){let D=d.get(k.target.key);D&&P(k,R(D))}}function R(k){return e.unwrap(k.texture).createView()}function U(k){if(!(!k.fragment.textureLayout||k.fragment.reads.length===0)&&(k.textureBindGroup=h(k.fragment,p?.mediaResources),k.mediaReads&&k.mediaSnapshot&&p?.mediaResources))for(let D of k.mediaReads)k.mediaSnapshot.set(D,p.mediaResources[D].texture)}function L(k,D){let O=!1;for(let F of d.values())F.resize(k,D)&&(O=!0);if(!p)return O;if(p.size={width:k,height:D},!O)return!1;for(let F of p.computeSteps)F.bindInputs?.(q=>d.get(q)??p.mediaResources?.[q]);for(let F of p.rttPasses)U(F);return U(p.finalPass),!0}return{setComposition:x,render:C,repaintRtt:E,resize:L,get textureCount(){return u.size},get passCount(){return p?p.rttPasses.length+1:0},dispose(){for(let k of[...u])k.destroy();u.clear(),d.clear(),p=null}}}function Y1e(){return typeof navigator<\"u\"&&navigator.gpu?navigator.gpu.getPreferredCanvasFormat():\"bgra8unorm\"}function SW(e){return`${e}-srgb`}function W1e(e){let t=new Set;function s(f,...h){return e.createTexture.call(e,f).$usage(...h)}let r,o,a,i,l={get linearClamp(){return r??=e.createSampler({magFilter:\"linear\",minFilter:\"linear\",mipmapFilter:\"linear\",addressModeU:\"clamp-to-edge\",addressModeV:\"clamp-to-edge\"})},get nearestClamp(){return o??=e.createSampler({magFilter:\"nearest\",minFilter:\"nearest\",addressModeU:\"clamp-to-edge\",addressModeV:\"clamp-to-edge\"})},get linearRepeat(){return a??=e.createSampler({magFilter:\"linear\",minFilter:\"linear\",mipmapFilter:\"linear\",addressModeU:\"repeat\",addressModeV:\"repeat\"})},get nearestRepeat(){return i??=e.createSampler({magFilter:\"nearest\",minFilter:\"nearest\",addressModeU:\"repeat\",addressModeV:\"repeat\"})}};function c(f,h,g,y,b){let x={texture:f,width:h,height:g,format:y,write(P){f.write(P)},unwrap(){return e.unwrap(f)},createSrgbView(){if(b)return e.unwrap(f).createView({format:SW(y)})},generateMipmaps(){f.generateMipmaps?.()},destroy(){t.has(x)&&(f.destroy(),t.delete(x))}};return t.add(x),x}function d(f){let{width:h,height:g,srgb:y=!1,mipLevelCount:b}=f,x=f.format??\"rgba8unorm\";return c(s({size:[h,g],format:x,...y?{viewFormats:[SW(x)]}:{},...b?{mipLevelCount:b}:{}},\"sampled\",\"render\"),h,g,x,y)}function u(f){let{width:h,height:g,format:y,data:b}=f,x=c(s({size:[h,g],format:y},\"sampled\"),h,g,y,!1);return b&&x.write(b),x}function p(f){let h=f.format??\"rgba16float\",{mipLevelCount:g}=f,y=f.width,b=f.height;function x(C,E){return c(s({size:[C,E],format:h,...g?{mipLevelCount:g}:{}},\"sampled\",\"render\"),C,E,h,!1)}let P=x(y,b);return{get texture(){return P.texture},get width(){return y},get height(){return b},format:h,write(C){P.write(C)},unwrap(){return P.unwrap()},createSrgbView(){return P.createSrgbView()},generateMipmaps(){P.generateMipmaps()},resize(C,E){return C===y&&E===b?!1:(P.destroy(),y=C,b=E,P=x(C,E),!0)},destroy(){P.destroy()}}}function _(f){let{layout:h,entryKey:g,getSource:y,staticEntries:b={}}=f,x=null;return{update(){let P=y();if(!P)return x=null,null;let C;try{C=e.device.importExternalTexture({source:P})}catch{return x=null,null}return x=e.createBindGroup(h,{...b,[g]:C}),x},get current(){return x},destroy(){x=null}}}return{samplers:l,createMediaTexture:d,createDataTexture:u,createRenderTexture:p,createExternalTextureBinding:_,get textureCount(){return t.size},destroy(){for(let f of[...t])f.destroy();t.clear()}}}function q1e(e,t){let s=b5(e)?.definition?.naturalSizeKey;if(!s)return null;if(\"fixed\"in s)return s.fixed||null;let r=t[s.fromProp];return typeof r==\"string\"&&r?r:null}function V1e(e,t,s){if(!e||typeof e!=\"object\")return null;let r=(i,l)=>!i||typeof i!=\"object\"||typeof i.value!=\"number\"?null:i.unit===\"px\"?i.value:i.value*l,o=r(e.width,t),a=r(e.height,s);return o!=null&&a!=null&&o>0&&a>0?{widthPx:o,heightPx:a}:null}function N1e(e,t,s){let{type:r,decl:o,props:a,boundingBox:i}=e;if(!(t>0)||!(s>0)||e.requiresChild)return null;if(o?.computeBounds){let u=o.computeBounds(a,t,s);return u.widthPx>0&&u.heightPx>0?{widthPx:u.widthPx,heightPx:u.heightPx}:null}let l=o?.propBindings;if(l?.width&&l?.height){let u=e_(l.width,a[l.width.prop],t,s),p=e_(l.height,a[l.height.prop],t,s);return u>0&&p>0?{widthPx:u,heightPx:p}:null}let c=V1e(i,t,s);if(c)return c;let d=q1e(r,a);if(d){let u=J4(d);if(u)return{widthPx:u.width,heightPx:u.height}}return null}function $1e(e,t){return e==null?0:typeof e==\"number\"?e:e.unit===\"px\"?e.value:e.value*t}function T5(e,t,s){return!e||e.mode!==\"column\"&&e.mode!==\"row\"?null:{mode:e.mode,gapPx:Math.max(0,$1e(e.gap,e.mode===\"column\"?s:t)),align:e.align??\"center\",anchor:e.anchor??\"center\",anchorOffsetX:e.anchorOffset?.x??0,anchorOffsetY:e.anchorOffset?.y??0}}var PW=e=>({ox:e.includes(\"left\")?\"start\":e.includes(\"right\")?\"end\":\"center\",oy:e.includes(\"top\")?\"start\":e.includes(\"bottom\")?\"end\":\"center\"}),_y=(e,t,s,r)=>e===\"start\"?r:e===\"end\"?s-t-r:(s-t)/2+r;function fy(e,t){let s=0,r=0;for(let o of t){let a=e.mode===\"column\"?o.size.heightPx:o.size.widthPx,i=e.mode===\"column\"?o.size.widthPx:o.size.heightPx;s+=a,r=Math.max(r,i)}return t.length>1&&(s+=e.gapPx*(t.length-1)),e.mode===\"column\"?{widthPx:r,heightPx:s}:{widthPx:s,heightPx:r}}function X1e(e,t,s,r){let o=new Map;if(t.length===0)return o;let a=fy(e,t),{ox:i,oy:l}=PW(e.anchor),c=_y(i,a.widthPx,s,e.anchorOffsetX),d=_y(l,a.heightPx,r,e.anchorOffsetY),u=(_,f)=>e.align===\"start\"?0:e.align===\"end\"?f-_:(f-_)/2,p=0;for(let _ of t)if(e.mode===\"column\"){let f=c+u(_.size.widthPx,a.widthPx)+_.size.widthPx/2,h=d+p+_.size.heightPx/2;o.set(_.id,{centerXPx:f,centerYPx:h}),p+=_.size.heightPx+e.gapPx}else{let f=c+p+_.size.widthPx/2,h=d+u(_.size.heightPx,a.heightPx)+_.size.heightPx/2;o.set(_.id,{centerXPx:f,centerYPx:h}),p+=_.size.widthPx+e.gapPx}return o}function H1e(e,t,s){let r=T5(e.layout,t,s);if(r){let o=S5(e,t,s);return o.length===0?null:fy(r,o)}return N1e({type:e.componentName,decl:e.decl,props:e.props,boundingBox:e.boundingBox,requiresChild:e.requiresChild,availableWidthPx:t},t,s)}function S5(e,t,s){let r=[];for(let o of e.children){if(o.visible===!1||o.absolute)continue;let a=H1e(o,t,s);a&&r.push({id:o.id,size:a,view:o})}return r}function j1e(e,t,s){if(!e.decl?.computeBounds)return{x:0,y:0};let r=e.decl.computeBounds(e.props,t,s),o=typeof e.props.center?.x==\"number\"?e.props.center.x:.5,a=typeof e.props.center?.y==\"number\"?e.props.center.y:.5;return{x:r.centerXPx-o*t,y:r.centerYPx-a*s}}function K1e(e,t,s,r,o,a,i,l){let c=T5(e.layout,o,a);if(c){CW(e,c,o,a,i,{centerXPx:s,centerYPx:r},l);return}let d=e.decl?.propBindings?.x?.prop??e.decl?.propBindings?.y?.prop;if(d){if(!e.positionDriven){let u=j1e(e,o,a);i.push({kind:\"position\",id:e.id,prop:d,value:{x:(s-u.x)/o,y:(r-u.y)/a}})}return}i.push({kind:\"box\",id:e.id,xPx:s-t.widthPx/2,yPx:r-t.heightPx/2,widthPx:t.widthPx,heightPx:t.heightPx})}function CW(e,t,s,r,o,a,i,l){let c=l??S5(e,s,r);if(c.length===0)return;let d=t;if(a){let p=fy(t,c);d={...t,anchor:\"top-left\",anchorOffsetX:a.centerXPx-p.widthPx/2,anchorOffsetY:a.centerYPx-p.heightPx/2}}if(i){let p=fy(d,c),{ox:_,oy:f}=PW(d.anchor);i.set(e.id,{leftPx:_y(_,p.widthPx,s,d.anchorOffsetX),topPx:_y(f,p.heightPx,r,d.anchorOffsetY),widthPx:p.widthPx,heightPx:p.heightPx})}let u=X1e(d,c,s,r);for(let p of c){let _=u.get(p.id);_&&K1e(p.view,p.size,_.centerXPx,_.centerYPx,s,r,o,i)}}function Q1e(e,t,s,r){let o=[],a=i=>{let l=T5(i.layout,t,s);if(l){let c=S5(i,t,s);CW(i,l,t,s,o,void 0,r,c);let d=new Set(c.map(u=>u.id));for(let u of i.children)u.visible!==!1&&(d.has(u.id)||a(u));return}for(let c of i.children)c.visible!==!1&&a(c)};for(let i of e)i.visible!==!1&&a(i);return o}var Z1e=class{frameTimesMs=[];frameTimesIndex=0;frameTimesCount=0;maxSamples=60;targetFrameTime=16.67;jankFrameCount=0;totalFrameCount=0;memorySnapshots=[];memorySnapshotIndex=0;maxMemorySnapshots=300;nodeCount=0;rttNodeCount=0;lastCpuTime=null;lastGpuTime=null;isRendering=!1;lastFrameTimestamp=0;frameIntervals=[];frameIntervalsIndex=0;frameIntervalsCount=0;pushToCircularBuffer(e,t,s,r,o){return e.length<o?(e.push(t),{index:e.length,count:e.length}):(e[s%o]=t,{index:s+1,count:o})}getBufferValues(e,t){return t<=e.length?e.slice(0,t):e}recordFrame(e){let t=this.pushToCircularBuffer(this.frameTimesMs,e,this.frameTimesIndex,this.frameTimesCount,this.maxSamples);this.frameTimesIndex=t.index,this.frameTimesCount=t.count,this.totalFrameCount++,e>this.targetFrameTime&&this.jankFrameCount++;let s=performance.now();if(this.lastFrameTimestamp>0){let r=s-this.lastFrameTimestamp,o=this.pushToCircularBuffer(this.frameIntervals,r,this.frameIntervalsIndex,this.frameIntervalsCount,this.maxSamples);this.frameIntervalsIndex=o.index,this.frameIntervalsCount=o.count}this.lastFrameTimestamp=s,this.recordMemorySnapshot()}recordCpuTime(e){this.lastCpuTime=e}recordGpuTime(e){this.lastGpuTime=e}updateNodeCounts(e,t){this.nodeCount=e,this.rttNodeCount=t}setRendering(e){this.isRendering=e}recordMemorySnapshot(){if(!performance.memory)return;let e=performance.now(),t=performance.memory.usedJSHeapSize;if(this.memorySnapshots.length<this.maxMemorySnapshots)this.memorySnapshots.push({time:e,bytes:t});else{let s=this.memorySnapshots[this.memorySnapshotIndex];s.time=e,s.bytes=t,this.memorySnapshotIndex=(this.memorySnapshotIndex+1)%this.maxMemorySnapshots}}calculateMemoryGrowthRate(){if(this.memorySnapshots.length<2)return null;let e=this.memorySnapshots.length,t=e<this.maxMemorySnapshots?0:this.memorySnapshotIndex,s=e<this.maxMemorySnapshots?e-1:(this.memorySnapshotIndex-1+e)%e,r=this.memorySnapshots[t],o=this.memorySnapshots[s],a=(o.time-r.time)/1e3;return a<=0?null:(o.bytes-r.bytes)/(1024*1024)/a}calculateStdDev(e){if(e.length===0)return 0;let t=e.reduce((r,o)=>r+o,0)/e.length,s=0;for(let r=0;r<e.length;r++){let o=e[r]-t;s+=o*o}return Math.sqrt(s/e.length)}sortBuffer=[];calculateP99(e){let t=e.length;if(t===0)return 0;for(;this.sortBuffer.length<t;)this.sortBuffer.push(0);for(let r=0;r<t;r++)this.sortBuffer[r]=e[r];for(let r=1;r<t;r++){let o=this.sortBuffer[r],a=r-1;for(;a>=0&&this.sortBuffer[a]>o;)this.sortBuffer[a+1]=this.sortBuffer[a],a--;this.sortBuffer[a+1]=o}let s=Math.floor(t*.99);return this.sortBuffer[Math.min(s,t-1)]}calculateComplexityScore(){return this.nodeCount+this.rttNodeCount*10}calculateIntensityScore(){let e=this.getBufferValues(this.frameTimesMs,this.frameTimesCount),t=e.length;if(t===0)return{score:0,label:\"N/A\"};let s=e.reduce((u,p)=>u+p,0)/t,r=Math.min(s/16.67*100,100),o=this.calculateComplexityScore(),a=Math.min(o/100*100,100),i=0;this.lastGpuTime!==null&&(i=Math.min(this.lastGpuTime/16.67*100,100));let l=this.lastGpuTime!==null?{frame:.4,gpu:.4,complexity:.2}:{frame:.7,gpu:0,complexity:.3},c=Math.round(r*l.frame+i*l.gpu+a*l.complexity),d;return c<=20?d=\"Very Light\":c<=40?d=\"Light\":c<=60?d=\"Medium\":c<=80?d=\"Heavy\":d=\"Very Heavy\",{score:Math.min(c,100),label:d}}getStats(e){let t=this.getBufferValues(this.frameTimesMs,this.frameTimesCount),s=this.getBufferValues(this.frameIntervals,this.frameIntervalsCount),r=t.length,o=s.length>0?1e3/(s.reduce((P,C)=>P+C,0)/s.length):0,a=r>0?t.reduce((P,C)=>P+C,0)/r:0,i=r>0?Math.min(...t):0,l=r>0?Math.max(...t):0,c=this.calculateP99(t),d=this.calculateStdDev(t),u=this.totalFrameCount>0?this.jankFrameCount/this.totalFrameCount*100:0,p=performance.memory,_=p?p.usedJSHeapSize/(1024*1024):null,f=this.calculateMemoryGrowthRate(),h=a>0?a/this.targetFrameTime*100:0,g=e?.render?.calls??null,y=e?.programs?.length??null,b=e?.memory?.textures??null,x=this.calculateIntensityScore();return{fps:Math.round(o),avgFrameTime:Math.round(a*100)/100,minFrameTime:Math.round(i*100)/100,maxFrameTime:Math.round(l*100)/100,p99FrameTime:Math.round(c*100)/100,stdDevFrameTime:Math.round(d*100)/100,jankCount:this.jankFrameCount,jankPercent:Math.round(u*10)/10,nodeCount:this.nodeCount,rttNodeCount:this.rttNodeCount,complexityScore:this.calculateComplexityScore(),memoryUsedMB:_!==null?Math.round(_*100)/100:null,memoryGrowthRate:f!==null?Math.round(f*1e3)/1e3:null,cpuTime:this.lastCpuTime!==null?Math.round(this.lastCpuTime*100)/100:null,gpuTime:this.lastGpuTime!==null?Math.round(this.lastGpuTime*100)/100:null,budgetUsed:Math.round(h*10)/10,drawCalls:g,shaderPrograms:y,textureCount:b,intensityScore:x.score,intensityLabel:x.label,isRendering:this.isRendering}}reset(){this.frameTimesMs.length=0,this.frameTimesIndex=0,this.frameTimesCount=0,this.frameIntervals.length=0,this.frameIntervalsIndex=0,this.frameIntervalsCount=0,this.lastFrameTimestamp=0,this.jankFrameCount=0,this.totalFrameCount=0,this.memorySnapshots.length=0,this.memorySnapshotIndex=0,this.sortBuffer.length=0,this.lastCpuTime=null,this.lastGpuTime=null}},J1e=32,eve=5,tve=(()=>{let e=0,t=new Set,s=(d,u)=>{t.forEach(p=>{try{p[d](u)}catch(_){Sr(\"[Shaders] Error in pointer handler:\",_)}})},r=d=>s(\"onMouseMove\",d),o=d=>s(\"onTouchMove\",d),a=d=>s(\"onMouseDown\",d),i=d=>s(\"onTouchStart\",d),l=()=>s(\"onMouseUp\"),c=()=>s(\"onTouchEnd\");return{register(d){return t.add(d),e++,e===1&&typeof window<\"u\"&&(window.addEventListener(\"mousemove\",r),window.addEventListener(\"touchmove\",o),window.addEventListener(\"mousedown\",a,!0),window.addEventListener(\"touchstart\",i,!0),window.addEventListener(\"mouseup\",l,!0),window.addEventListener(\"touchend\",c,!0)),()=>{t.delete(d),e--,e===0&&typeof window<\"u\"&&(window.removeEventListener(\"mousemove\",r),window.removeEventListener(\"touchmove\",o),window.removeEventListener(\"mousedown\",a,!0),window.removeEventListener(\"touchstart\",i,!0),window.removeEventListener(\"mouseup\",l,!0),window.removeEventListener(\"touchend\",c,!0))}}}})();function sve(e){if(!e)return!1;let t=e;if(typeof e==\"string\")try{t=JSON.parse(e)}catch{return!1}if(!t||typeof t!=\"object\")return!1;for(let s in t){let r=t[s];if(r&&typeof r==\"object\"&&r.type===\"mouse\")return!0}return!1}function MW(){let e=null,t=null,s=null,r=null,o=null,a=null,i=!1,l=!1,c=!1,d=null,u=new Map,p=null,_=new Map,f=[],h=[],g=F1e({maxSize:4,dispose:$=>hf($)}),y=new Set,b=null,x=null,P=!0,C=0,E=0,R=0,U=0,L=1,k=8192,D=0,O=0,F=!1,q=()=>R||C||1,Y=()=>U||E||1,V=!0,X=!1,Q=!1,te=0,J=0,oe=0,le=null,se=null,Te=!1,de=-10,xe=-10,Ae=!1,De=!1,Ee=null,ze=!1,Ie=null,ke=null,Me=null,we=null,Ve=null,qe=null,st=!1,pt=\"p3-linear\",Ze=\"linear\",nt=!1,ht=null,yt=null,St=!1,Mt=!1,Rt=null,Kt=!1,Wt=null,ls=null,us=!1,os=null,bs=null,hs=0,gs=0,Gs=new Z1e,Ss={deltaTime:0,pointer:{x:-10,y:-10,seen:!1},pointerActive:!1,dimensions:{width:0,height:0}},or=LB($=>wf($)),yr=$=>$.replace(/[^a-zA-Z0-9_]/g,\"_\"),lr=$=>{let Z=_.get($);if(!Z)return[];let ee=[];for(let ge of Z){let ue=u.get(ge);ue&&ee.push(ue)}return ee},Ur=$=>{let Z=yr($);for(let[ee,ge]of u)if(ge.metadata.id===Z)return ee;return null},so=($,Z)=>{if(Z===\"center\")return;let ee=$.boundingBoxDeclaration;if(!ee)return;let ge={};for(let[ue,Pe]of Object.entries($.uniforms))ge[ue]=Pe._rawDimensional!==void 0?Pe._rawDimensional:Pe.value;return _e($,ge.shapeSdfUrl),NA(ee,ge,q(),Y())},ro=new WeakMap,_e=($,Z)=>{if(typeof Z!=\"string\"||!Z||kB(Z))return;let ee=ro.get($)??new Set;ro.set($,ee),!ee.has(Z)&&(ee.add(Z),Kh(Z,()=>{ee.delete(Z),u.get($.id)===$&&(We($),ar()&&Ds(),Da())}))},We=$=>{let Z=$.boundingBoxDeclaration,ee=$.extraDimProps,ge=dp(Z,ee);if(!ge)return;let ue=$.uniforms.origin?.value??\"center\",Pe=so($,ue),Ke=[...ge.positionProps,...ge.sizeProps.keys()];for(let ut of Ke){let mt=$.uniforms[ut];if(!mt||mt._rawDimensional===void 0)continue;let Gt=R_(Z,ut,mt._rawDimensional,ue,q(),Y(),ee,Pe);mt.value=Gt,qi($,ut,Gt)}},Le=($,Z,ee)=>{if(typeof ee==\"number\")return ee;let ge=$.uniforms.origin?.value??\"center\",ue=R_($.boundingBoxDeclaration,Z,ee,ge,q(),Y(),$.extraDimProps);return typeof ue==\"number\"?ue:ee?.value??0},Be=()=>{let{width:$,height:Z}=Vi();return $/Math.max(1,Z)},Oe=$=>{let Z=$.metadata.transform;return{offsetX:Z?.offsetX??0,offsetY:Z?.offsetY??0,rotation:Z?.rotation??0,scale:Z?.scale??1,anchorX:Z?.anchorX??.5,anchorY:Z?.anchorY??.5,aspectRatio:Be()}},tt=$=>{let Z=$.metadata.boundingBox;if(!Z)return null;let ee=q3(Z,q(),Y());return{centerX:ee.centerX,centerY:ee.centerY,halfWidth:ee.halfWidthUV,halfHeight:ee.halfHeightUV,cornerRadius:ee.cornerRadiusUV,rotation:ee.rotation,aspectRatio:Be()}},_t=$=>!!$.metadata.boundingBox&&!!$.boundingBoxDeclaration&&!Yh($.metadata.boundingBox),Bt=$=>{let Z=$.boundingBoxDeclaration;if(!Z||!$.uniforms||!Z.computeBounds&&!Z.propBindings)return null;let ee={};for(let[mt,Gt]of Object.entries($.uniforms))ee[mt]=Gt._rawDimensional!==void 0?Gt._rawDimensional:Gt.value;let ge=NA(Z,ee,q(),Y());if(ge.hwx<=0&&ge.hhy<=0)return null;let ue=.5,Pe=.5,Ke=Z.propBindings?.x?.prop??Z.propBindings?.y?.prop,ut=Ke?$.uniforms[Ke]?.value:void 0;if(ut&&typeof ut.x==\"number\"&&typeof ut.y==\"number\"&&(ue=ut.x,Pe=ut.y),Ke){let mt=$.metadata.maps?.[Ke];if(mt?.type===\"mouse-position\"){let Gt=$.mouseDriverState[Ke];Gt&&(ue=Gt.liveX??(typeof mt.x==\"number\"?mt.x:Gt.currentX),Pe=Gt.liveY??(typeof mt.y==\"number\"?mt.y:Gt.currentY))}}return{centerX:ue,centerY:Pe,halfWidth:ge.hwx,halfHeight:ge.hhy}},Dt=$=>{if(!$.definition.wantsBoundsParams)return null;let Z=lr($.id).sort((ee,ge)=>ee.metadata.renderOrder-ge.metadata.renderOrder);for(let ee of Z){if(ee.metadata.visible===!1)continue;if(_t(ee))return null;let ge=Bt(ee);if(ge)return ge}return null},Nt=()=>{for(let $ of u.values()){if(!$.definition.wantsBoundsParams)continue;let Z=Dt($);Z&&(Qs($,\"_childBounds_centerX\",Z.centerX),Qs($,\"_childBounds_centerY\",Z.centerY),Qs($,\"_childBounds_halfWidth\",Z.halfWidth),Qs($,\"_childBounds_halfHeight\",Z.halfHeight))}},Ks=!1,Ds=()=>{Ks=!0,Da()},ar=()=>{for(let $ of u.values()){let Z=$.metadata.flow?.mode;if(Z===\"column\"||Z===\"row\")return!0}return!1},Xo=$=>{let Z={};for(let[Pe,Ke]of Object.entries($.uniforms))Z[Pe]=Ke._rawDimensional!==void 0?Ke._rawDimensional:Ke.value;let ee=$.boundingBoxDeclaration?.propBindings?.x?.prop??$.boundingBoxDeclaration?.propBindings?.y?.prop,ge=ee?$.uniforms[ee]?.value:void 0,ue=!!(ee&&(ge?.type===\"mouse-position\"||$.metadata.maps?.[ee]));return{id:$.id,componentName:$.componentName,visible:$.metadata.visible!==!1,absolute:$.metadata.absolute===!0,requiresChild:$.requiresChild,layout:$.metadata.flow,decl:$.boundingBoxDeclaration,props:Z,boundingBox:$.metadata.boundingBox,positionDriven:ue,children:lr($.id).sort((Pe,Ke)=>Pe.metadata.renderOrder-Ke.metadata.renderOrder).map(Xo)}},$r=()=>{if(!ar()){Ks=!1;return}let $=q(),Z=Y();if($<=1||Z<=1)return;Ks=!1;let ee=[];for(let ue of u.values())ue.parentId===null&&ee.push(Xo(ue));let ge=Q1e(ee,$,Z);for(let ue of ge){let Pe=u.get(ue.id);if(Pe)if(ue.kind===\"position\"){let Ke=Pe.uniforms[ue.prop];if(!Ke)continue;let ut=Ke.value,mt=ut&&typeof ut==\"object\"?{...ut,x:ue.value.x,y:ue.value.y}:ue.value;Ke.value=mt,qi(Pe,ue.prop,mt)}else{let Ke=_t(Pe);if(Pe.metadata.boundingBox={x:{value:ue.xPx,unit:\"px\"},y:{value:ue.yPx,unit:\"px\"},width:{value:ue.widthPx,unit:\"px\"},height:{value:ue.heightPx,unit:\"px\"},origin:\"top-left\",rotation:Pe.metadata.boundingBox?.rotation??0,...Pe.metadata.boundingBox?.cornerRadius?{cornerRadius:Pe.metadata.boundingBox.cornerRadius}:{},...Pe.metadata.boundingBox?.lockAspect!==void 0?{lockAspect:Pe.metadata.boundingBox.lockAspect}:{}},!Ke&&_t(Pe))qn();else{let ut=tt(Pe);if(ut)for(let[mt,Gt]of Object.entries(ut))Qs(Pe,`_bbox_${mt}`,Gt)}}}},cr=()=>{Ks&&$r()},za=null,ia=()=>{ar()&&Ds()},Ra=()=>{za||(za=eB(()=>{ar()&&Ds()})),typeof document<\"u\"&&document.fonts?.addEventListener&&document.fonts.addEventListener(\"loadingdone\",ia)};Ra();let Wn=$=>el($.metadata.transform),Uc=($,Z,ee)=>{let ge=$.mapValues[Z]??{inputMin:0,inputMax:1,outputMin:0,outputMax:1,curve:0};if(ee.type===\"map\"){let ue=ee;ge.inputMin=ue.inputMin,ge.inputMax=ue.inputMax,ge.outputMin=Le($,Z,ue.outputMin),ge.outputMax=Le($,Z,ue.outputMax),ge.curve=ue.curve??0}else if(ee.type===\"mouse\"){let ue=ee;ge.outputMin=Le($,Z,ue.outputMin),ge.outputMax=Le($,Z,ue.outputMax),ge.curve=ue.curve??0}else if(ee.type===\"auto-animate\"){let ue=ee;ge.outputMin=Le($,Z,ue.outputMin),ge.outputMax=Le($,Z,ue.outputMax)}return $.mapValues[Z]=ge,ge},Gp=($,Z,ee)=>{let ge=$.mouseDriverState[Z];if(ge)return ge;if(ee.type===\"mouse-position\"){let ue=ee.x===void 0||ee.x===\"mouse\",Pe=ee.y===void 0||ee.y===\"mouse\";ge={currentX:ue?de:ee.x,currentY:Pe?xe:ee.y,velocityX:0,velocityY:0,pointerSnapped:De}}else ge={currentX:Math.max(.001,ee.axis===\"x\"?de:xe),currentY:0,velocityX:0,velocityY:0,pointerSnapped:De};return $.mouseDriverState[Z]=ge,ge},Fp=$=>{let Z=$.metadata.maps;if(Z)for(let[ee,ge]of Object.entries(Z))ee in $.uniforms&&(ge.type===\"map\"?Uc($,ee,ge):ge.type===\"mouse-position\"?Gp($,ee,ge):ge.type===\"mouse\"?(Gp($,ee,ge),Uc($,ee,ge)):ge.type===\"auto-animate\"&&($.autoAnimateState[ee]||($.autoAnimateState[ee]={}),Uc($,ee,ge)))},Oc=$=>{let Z=$.definition.animatedTime;return(Z?$.uniforms[Z.speed]:void 0)??$},$d=($,Z)=>$.uniforms[Z]??$,af=$=>{let Z=[];for(let[ue,Pe]of Object.entries($.uniforms))Z.push({name:ue,initial:Pe.value,transform:Pe.transform,cpu:Pe.cpu,schema:Pe.schema});if(Z.push({name:\"_opacity\",schema:n,initial:$.metadata.opacity??1}),$.definition.animatedTime&&Z.push({name:\"_animTime\",schema:n,initial:zl(Oc($)).value}),$.definition.extraAnimatedTimes)for(let[ue,Pe]of Object.entries($.definition.extraAnimatedTimes))Z.push({name:`_animTime_${ue}`,schema:n,initial:zl($d($,Pe)).value});let ee=$.definition.extraFields;if(ee)for(let[ue,Pe]of Object.entries(ee))Z.push({name:ue,schema:Pe.schema,initial:Pe.initial});if(Wn($)){let ue=Oe($);for(let[Pe,Ke]of Object.entries(ue))Z.push({name:`_xform_${Pe}`,schema:n,initial:Ke})}if(_t($)){let ue=tt($);if(ue)for(let[Pe,Ke]of Object.entries(ue))Z.push({name:`_bbox_${Pe}`,schema:n,initial:Ke})}if($.definition.wantsBoundsParams){let ue=Dt($)??{centerX:.5,centerY:.5,halfWidth:.5,halfHeight:.5};for(let[Pe,Ke]of Object.entries(ue))Z.push({name:`_childBounds_${Pe}`,schema:n,initial:Ke})}let ge=$.metadata.maps;if(ge){Fp($);for(let[ue,Pe]of Object.entries(ge))if(ue in $.uniforms){if(Pe.type===\"map\"){let Ke=$.mapValues[ue];Z.push({name:`_map_${ue}_inputMin`,schema:n,initial:Ke.inputMin}),Z.push({name:`_map_${ue}_inputMax`,schema:n,initial:Ke.inputMax}),Z.push({name:`_map_${ue}_outputMin`,schema:n,initial:Ke.outputMin}),Z.push({name:`_map_${ue}_outputMax`,schema:n,initial:Ke.outputMax}),Z.push({name:`_map_${ue}_curve`,schema:n,initial:Ke.curve})}else if(Pe.type===\"mouse-position\"){let Ke=$.mouseDriverState[ue];Z.push({name:`_smoothed_${ue}`,schema:m,initial:[Ke.currentX,1-Ke.currentY]})}else if(Pe.type===\"mouse\"){let Ke=$.mapValues[ue];Z.push({name:`_smoothed_${ue}`,schema:n,initial:Ke.outputMin})}else if(Pe.type===\"auto-animate\"){let Ke=$.mapValues[ue];Z.push({name:`_smoothed_${ue}`,schema:n,initial:Ke.outputMin})}}}return Z},qi=($,Z,ee)=>{let ge=$._liveHandles?.[Z];ge&&(ht?.(pt),Bk(ge,ee))},Qs=($,Z,ee)=>{let ge=$._liveHandles?.[Z];ge instanceof si&&(ge.value=ee)},Ip=($,Z,ee)=>{let ge=$._liveHandles?.[Z];ge instanceof si?ge.value=ee:ge instanceof Nm&&Array.isArray(ee)&&(ge.array=ee)},nf=$=>{for(let Z of Object.values($.uniforms))if(Z.transform===at){let ee=Z.value;if(typeof ee==\"string\")return at(ee);if(typeof ee==\"number\")return ee}return 0},lf=$=>{if(!$.uniforms.convertedColorsArray)return;let Z=null;for(let Pe of Object.values($.uniforms))if(Pe.transform===hl){Z=Pe.value??null;break}let ee=J3(Z,B_),ge=eA(ee.colors,ee.stopCount,nf($)),ue=(Pe,Ke)=>{let ut=$.uniforms[Pe];ut&&(ut.value=Ke),qi($,Pe,Ke)};ue(\"colorsArray\",ee.colors),ue(\"positionsArray\",ee.positions),ue(\"convertedColorsArray\",ge),ue(\"stopCount\",ee.stopCount)},cf=($,Z)=>{let ee=$.uniforms[Z],ge=ee?._listSpec;if(!ee||!ge)return;let ue=ee._rawList,Pe=new Set,Ke=IA(ue,ge,{color:B_,drivenPosition:(Gt,Es,Tr)=>{let dr=vz(Z,Gt,Es);Pe.add(dr);let ss=Gp($,dr,Tr);return ss.liveX!==void 0&&ss.liveY!==void 0?{x:ss.liveX,y:1-ss.liveY}:void 0}});for(let Gt of Object.keys($.mouseDriverState)){let Es=FA(Gt);Es&&Es.prop===Z&&!Pe.has(Gt)&&delete $.mouseDriverState[Gt]}ee.value=Ke,qi($,Z,Ke);let ut=YA(Ke,ge),mt=(Gt,Es)=>{let Tr=$.uniforms[Gt];Tr&&(Tr.value=Es),qi($,Gt,Es)};for(let[Gt,Es]of Object.entries(ut.fields))mt(tg(Z,Gt),Es);mt(sg(Z),ut.count)},vy=($,Z)=>{let ee=$.metadata.maps?.[Z];if(ee)return ee;let ge=FA(Z);if(!ge)return;let ue=$.uniforms[ge.prop]?._rawList,Pe=(Array.isArray(ue)?ue[ge.index]:void 0)?.[ge.field];return rg(Pe)?Pe:void 0},df=$=>Object.values($.uniforms).some(Z=>Z._listSpec&&WA(Z._rawList,Z._listSpec)),hy=$=>{if(Qs($,\"_opacity\",$.metadata.opacity??1),$.definition.animatedTime&&Qs($,\"_animTime\",zl(Oc($)).value),$.definition.extraAnimatedTimes)for(let[ee,ge]of Object.entries($.definition.extraAnimatedTimes))Qs($,`_animTime_${ee}`,zl($d($,ge)).value);if(Wn($))for(let[ee,ge]of Object.entries(Oe($)))Qs($,`_xform_${ee}`,ge);if(_t($)){let ee=tt($);if(ee)for(let[ge,ue]of Object.entries(ee))Qs($,`_bbox_${ge}`,ue)}let Z=$.metadata.maps;if(Z){for(let[ee,ge]of Object.entries(Z))if(ge.type===\"map\"&&$.mapValues[ee]){let ue=$.mapValues[ee];Qs($,`_map_${ee}_inputMin`,ue.inputMin),Qs($,`_map_${ee}_inputMax`,ue.inputMax),Qs($,`_map_${ee}_outputMin`,ue.outputMin),Qs($,`_map_${ee}_outputMax`,ue.outputMax),Qs($,`_map_${ee}_curve`,ue.curve)}}},gy=($,Z)=>{let ee={};for(let ge of Object.keys($.uniforms)){let ue=Z[ge];ue&&(ee[ge]=ue)}return ee},yy=$=>{let Z={};for(let[ee,ge]of Object.entries($.uniforms))Z[ee]={accessorPath:\"\",cpu:!!ge.cpu,value:ge.value};return Z},by=($,Z)=>({id:$.id,customId:$.metadata.id,componentName:$.componentName,parentId:$.parentId,definition:$.definition,metadata:$.metadata,handles:Z,domCanvas:$.domCanvas}),uf=($,Z)=>{let ee=new Map,ge=Pe=>by(Pe,$&&Z?gy(Pe,Z.get(Pe.id)??{}):yy(Pe)),ue=Pe=>{let Ke=ee.get(Pe);if(Ke)return Ke;let ut=u.get(Pe);if(!ut)return;let mt=ge(ut);return ee.set(Pe,mt),mt};return{rootId:p,getNode:ue,getChildren:Pe=>lr(Pe).map(Ke=>ue(Ke.id)),resolveCustomId:Pe=>Ur(Pe),store:{gpuAccessor:(Pe,Ke)=>$?$.gpuAccessor(Pe,Ke):\"\",layout:$?.layout}}},pf=()=>({toneMapping:Ze,flipY:!1,premultiplyAlpha:!0,canvas:a??void 0,dimensions:Vi(),gpu:t?{device:t.device,root:t}:void 0,writeExtraField:($,Z,ee)=>{let ge=u.get($);ge&&Ip(ge,Z,ee)},createMediaTexture:$=>{if(!r)throw new Error(\"[gpu] createMediaTexture before init\");return r.createMediaTexture($)},createDataTexture:$=>{if(!r)throw new Error(\"[gpu] createDataTexture before init\");return r.createDataTexture($)},resolveMapWindow:($,Z)=>{let ee=u.get($),ge=ee?.metadata.maps?.[Z];if(!ee||!ge||ge.type!==\"map\")return;let ue=Uc(ee,Z,ge);return{inputMin:ue.inputMin,inputMax:ue.inputMax,outputMin:ue.outputMin,outputMax:ue.outputMax,curve:ue.curve}},resolveDriverCpuValue:($,Z)=>{let ee=u.get($);if(!ee)return;if(Z===\"_animTime\"||Z.startsWith(\"_animTime_\")){let ue=ee._liveHandles?.[Z];return ue instanceof si?ue.value:void 0}let ge=ee.metadata.maps?.[Z];if(ge){if(ge.type===\"mouse-position\"){let ue=ee.mouseDriverState[Z];return!ue||ue.liveX===void 0||ue.liveY===void 0?void 0:{x:ue.liveX,y:1-ue.liveY}}if(ge.type===\"mouse\"||ge.type===\"auto-animate\"){let ue=ee._liveHandles?.[`_smoothed_${Z}`];return ue instanceof si?ue.value:void 0}}}}),xy=()=>{let $=[];for(let[Z,ee]of u){let ge=ee.metadata;$.push(`aopac:${Z}:${(ge.opacity??1)<1}`);let ue=ee.uniforms.stopCount?.value;typeof ue==\"number\"&&$.push(`stops:${Z}:${ue>1?ue:0}`);for(let[Pe,Ke]of Object.entries(ee.uniforms)){if(!Ke.compileTimeWhen)continue;let ut=Ke._lastCompiledValue;typeof ut!=\"number\"&&typeof ut!=\"boolean\"||$.push(`ctw:${Z}:${Pe}:${String(ut)}`)}if(ge.maps){let Pe=Object.entries(ge.maps).sort(([Ke],[ut])=>Ke<ut?-1:Ke>ut?1:0).map(([Ke,ut])=>{let mt=ut;return`${Ke}=${mt.type}:${mt.source??\"\"}:${mt.channel??\"\"}:${mt.axis??\"\"}`}).join(\",\");$.push(`mapfp:${Z}:${Pe}`)}}return $},mf=()=>p?G1e([...A4(uf(null,null),pf()),...xy()]):null,Vi=()=>({width:Math.max(1,Math.round(C*L)),height:Math.max(1,Math.round(E*L))}),_f=$=>{let Z={};for(let ee of $.textures)ee.kind!==\"rtt\"&&ee.resource&&(Z[ee.key]=ee.resource);return Z},ff=$=>{if(!t||!r||!o)throw new Error(\"[gpu] buildComposition before init\");let Z=kk(t,{systemSchema:O1e}),ee=new Map;for(let[ut,mt]of u)ee.set(ut,Z.defineNode(ut,af(mt)));Z.defineSystem(),Z.finalize();let ge=x4(uf(Z,ee),pf()),ue=I1e(t,{textureManager:r,dispatcher:o}),Pe={hash:$,store:Z,ir:ge,passManager:ue,handlesById:ee,fresh:!0,validationFrames:3},Ke=ge.usesCustomWgsl?t.device:void 0;Ke&&Ke.pushErrorScope(\"validation\");try{ue.setComposition(ge,Z.bindGroup,Vi(),_f(ge))}finally{Ke&&Ke.popErrorScope().then(ut=>{ut&&!Pe.broken&&vf(Pe,ut.message)}).catch(()=>{})}return y.add(Pe),Pe},vf=($,Z)=>{$.broken=Z,Mf(\"[gpu] a shader in this composition failed GPU validation \\u2014 it will not draw until it changes. If you are writing a wgsl`\\u2026` body, the message below points at the line:\\n\"+Z)},hf=$=>{try{for(let Z of $.ir.onCleanup)Z()}catch(Z){Sr(\"[gpu] composition onCleanup error:\",Z)}try{$.passManager.dispose()}catch(Z){Sr(\"[gpu] passManager dispose error:\",Z)}try{$.store.destroy()}catch(Z){Sr(\"[gpu] store destroy error:\",Z)}y.delete($),b===$&&(b=null)},Ay=$=>{let Z=!1;for(let[ee,ge]of $.handlesById){let ue=u.get(ee);ue&&ue._liveHandles!==ge&&(ue._liveHandles=ge,Z=!0)}if(!($===b&&!Z)){if(!$.fresh){for(let ee of u.values()){for(let[ge,ue]of Object.entries(ee.uniforms))qi(ee,ge,ue.value);Fp(ee),hy(ee)}$.store.writeAll()}$.fresh=!1,b=$,!St&&$.ir.composedNodeIds.size>0&&(Mt=!0)}},qn=()=>{P=!0,ar()&&(Ks=!0),Da()},Da=()=>{Wt||Te||or.running||se===null&&typeof requestAnimationFrame==\"function\"&&(se=requestAnimationFrame($=>{se=null,wf($)}))},Xd=($,Z,ee,ge,ue={},Pe,Ke)=>{if(Wt)return;if(Z===null){let ss=f.findIndex(Oo=>Oo.id===$);if(ss!==-1){f.splice(ss,1),h=h.filter(Oo=>Oo.id!==$);return}Hd($);return}if(!Pe){console.error(`[gpu] registerNode(\"${$}\") requires a componentDefinition`);return}if(!c){let ss=f.findIndex(Vn=>Vn.id===$),Oo={id:$,definition:Pe,parentId:ee,metadata:ge,uniforms:ue,domCanvas:Ke};ss!==-1?(f[ss]=Oo,h=h.filter(Vn=>Vn.id!==$)):f.push(Oo);return}let ut=0;if(ee!==null){let ss=_.get(ee);if(ss&&ss.size>0){let Oo=0;for(let Vn of ss){let La=u.get(Vn);La&&La.metadata.renderOrder>Oo&&(Oo=La.metadata.renderOrder)}ut=Oo+1}}let mt={blendMode:ge?.blendMode||\"normal\",opacity:ge?.opacity,visible:ge?.visible!==!1,id:ge?.id?yr(ge.id):ge?.id,mask:ge?.mask,maps:ge?.maps,renderOrder:ge?.renderOrder!==void 0?ge.renderOrder:ut,transform:ge?.transform,boundingBox:ge?.boundingBox,flow:ge?.flow,absolute:ge?.absolute},Gt=Pe.boundingBoxDeclaration,Es=Pe.props?VA(Pe.props):void 0,Tr={id:$,componentName:Pe.name||\"Unknown\",parentId:ee,definition:Pe,metadata:mt,uniforms:ue,domCanvas:Ke,requiresRTT:!!Pe.requiresRTT,requiresChild:!!Pe.requiresChild,blendWithChildren:!!Pe.blendWithChildren,acceptsUVContext:!!Pe.acceptsUVContext,providesUVContextViaCompute:!!Pe.providesUVContextViaCompute,usesPointer:!!Pe.usesPointer,hasUvRemap:!!Pe.uvRemap,boundingBoxDeclaration:Gt,wantsBoundsParams:!!Pe.wantsBoundsParams,extraDimProps:Es,mouseDriverState:{},autoAnimateState:{},mapValues:{},_liveHandles:null};if(Gt||Es){let ss=dp(Gt,Es);if(ss){let Oo=ue.origin?.value??\"center\",Vn=so(Tr,Oo);for(let La of[...ss.positionProps,...ss.sizeProps.keys()]){let _a=ue[La];_a&&(_a._rawDimensional===void 0&&(_a._rawDimensional=_a.value),_a.value=R_(Gt,La,_a._rawDimensional,Oo,q(),Y(),Es,Vn))}}}for(let ss of Object.values(ue))ss.compileTimeWhen&&ss._lastCompiledValue===void 0&&(ss._lastCompiledValue=ss.value);u.set($,Tr),ee===null&&(p=$);let dr=_.get(ee)||new Set;dr.add($),_.set(ee,dr),Np(),qn(),ar()&&Ds()},gf=$=>{f.some(Z=>Z.id===$.id)&&h.push($)},yf=($,Z,ee)=>{let ge=u.get($);if(!ge){gf({id:$,kind:\"uniform\",name:Z,value:ee});return}let ue=ge.uniforms[Z];if(!ue)return;let Pe=ge.boundingBoxDeclaration,Ke=ge.extraDimProps;if((Pe||Ke)&&$A(Pe,Z,Ke)){ue._rawDimensional=ee;let ut=ge.uniforms.origin?.value??\"center\",mt=so(ge,ut);ee=R_(Pe,Z,ee,ut,q(),Y(),Ke,mt)}if(ue.transform===_c){ue._rawList=ee,cf(ge,Z),Np(),Da();return}if(ue.value=ee,qi(ge,Z,ee),(ue.transform===hl||ue.transform===at)&&lf(ge),Z===\"origin\"&&Pe)We(ge);else if(Pe&&(ge.uniforms.origin?.value??\"center\")!==\"center\"){let ut=dp(Pe,Ke),mt=!!Pe.computeBounds||(ut?.sizeProps.has(Z)??!1),Gt=ut?.positionProps.has(Z)??!1;mt&&!Gt&&We(ge)}if(Z===\"shape\"&&Np(),ar()&&Ds(),ue.compileTime){qn();return}if(ue.compileTimeWhen){let ut=ue._lastCompiledValue;if(ue.compileTimeWhen(ut,ee)){ue._lastCompiledValue=ee,qn();return}}Da()},bf=($,Z)=>{let ee=u.get($);if(!ee){gf({id:$,kind:\"metadata\",metadata:Z});return}let ge=!1;if(Z.blendMode!==void 0&&ee.metadata.blendMode!==Z.blendMode&&(ee.metadata.blendMode=Z.blendMode,ge=!0),Z.opacity!==void 0&&ee.metadata.opacity!==Z.opacity){let ue=ee.metadata.opacity??1,Pe=Z.opacity;ee.metadata.opacity=Pe,Qs(ee,\"_opacity\",Pe),ue>=1!=Pe>=1&&(ge=!0)}if(Z.renderOrder!==void 0&&ee.metadata.renderOrder!==Z.renderOrder&&(ee.metadata.renderOrder=Z.renderOrder,ge=!0),\"visible\"in Z){let ue=Z.visible!==!1;ee.metadata.visible!==ue&&(ee.metadata.visible=ue,ge=!0)}if(Z.id!==void 0){let ue=yr(Z.id);ee.metadata.id!==ue&&(ee.metadata.id=ue,ge=!0)}if(\"mask\"in Z&&(ee.metadata.mask?.source!==Z.mask?.source||ee.metadata.mask?.type!==Z.mask?.type)&&(ee.metadata.mask=Z.mask,ge=!0),\"maps\"in Z&&JSON.stringify(ee.metadata.maps)!==JSON.stringify(Z.maps)){let ue=ee.metadata.maps,Pe=Z.maps;if(ee.metadata.maps=Pe,Np(),(()=>{if(!ue||!Pe)return!0;let Ke=Object.keys(ue),ut=Object.keys(Pe);if(Ke.length!==ut.length||!Ke.every(mt=>mt in Pe))return!0;for(let mt of ut){let Gt=ue[mt],Es=Pe[mt];if(Gt.type!==Es.type)return!0;if(Es.type===\"map\"){let Tr=Gt,dr=Es;if(Tr.source!==dr.source||Tr.channel!==dr.channel)return!0}else if(Es.type===\"mouse\"&&Gt.axis!==Es.axis)return!0}return!1})()){if(ue&&Pe)for(let Ke of Object.keys(ue))Ke in Pe&&ue[Ke].type!==Pe[Ke].type&&(delete ee.mouseDriverState[Ke],delete ee.autoAnimateState[Ke],delete ee.mapValues[Ke]);ge=!0}else if(Pe)for(let[Ke,ut]of Object.entries(Pe)){let mt=Uc(ee,Ke,ut);ut.type===\"map\"&&(Qs(ee,`_map_${Ke}_inputMin`,mt.inputMin),Qs(ee,`_map_${Ke}_inputMax`,mt.inputMax),Qs(ee,`_map_${Ke}_outputMin`,mt.outputMin),Qs(ee,`_map_${Ke}_outputMax`,mt.outputMax),Qs(ee,`_map_${Ke}_curve`,mt.curve))}}if(Z.transform!==void 0){let ue=ee.metadata.transform,Pe={offsetX:Z.transform.offsetX??ue?.offsetX??0,offsetY:Z.transform.offsetY??ue?.offsetY??0,rotation:Z.transform.rotation??ue?.rotation??0,scale:Z.transform.scale??ue?.scale??1,anchorX:Z.transform.anchorX??ue?.anchorX??.5,anchorY:Z.transform.anchorY??ue?.anchorY??.5,edges:Z.transform.edges??ue?.edges??\"transparent\"},Ke=Wn(ee);ee.metadata.transform=Pe;let ut=el(Pe);if(Ke!==ut||ue&&ue.edges!==Pe.edges)ge=!0;else if(ut)for(let[mt,Gt]of Object.entries(Oe(ee)))Qs(ee,`_xform_${mt}`,Gt)}if(Z.boundingBox!==void 0&&Z.boundingBox!==null&&ee.boundingBoxDeclaration!==void 0){let ue=_t(ee);ee.metadata.boundingBox=Z.boundingBox;let Pe=_t(ee);if(ue!==Pe)ge=!0;else if(Pe){let Ke=tt(ee);if(Ke)for(let[ut,mt]of Object.entries(Ke))Qs(ee,`_bbox_${ut}`,mt)}}else Z.boundingBox===null&&ee.metadata.boundingBox!==void 0&&(ee.metadata.boundingBox=void 0,ge=!0);if(\"flow\"in Z&&JSON.stringify(ee.metadata.flow)!==JSON.stringify(Z.flow)){let ue=ee.metadata.flow?.mode===\"column\"||ee.metadata.flow?.mode===\"row\";ee.metadata.flow=Z.flow??void 0;let Pe=ee.metadata.flow?.mode===\"column\"||ee.metadata.flow?.mode===\"row\";if(ue&&!Pe){let Ke=ut=>{for(let mt of lr(ut))We(mt),Ke(mt.id)};Ke($)}Ds()}\"absolute\"in Z&&ee.metadata.absolute!==Z.absolute&&(ee.metadata.absolute=Z.absolute,Z.absolute&&We(ee),Ds()),ar()&&Ds(),ge?qn():Da()},Hd=$=>{let Z=u.get($);if(!Z)return;for(let ge of lr($))Hd(ge.id);p===$&&(p=null);let ee=_.get(Z.parentId);ee&&(ee.delete($),ee.size===0&&_.delete(Z.parentId)),u.delete($),Np(),qn(),ar()&&Ds()},Yp=()=>{let $=Ss.deltaTime;oe=Te?oe+$:zB(le,oe,$,performance.now());for(let Z of u.values()){let ee=Z.metadata.maps??{};for(let ge in Z.mouseDriverState){let ue=Z.mouseDriverState[ge],Pe=vy(Z,ge);if(Pe){if(Pe.type===\"mouse-position\"){let Ke=Pe.smoothing??0,ut=Pe.momentum??0,mt=Pe.x===void 0||Pe.x===\"mouse\",Gt=Pe.y===void 0||Pe.y===\"mouse\";!ue.pointerSnapped&&De&&(ue.pointerSnapped=!0,mt&&(ue.currentX=de,ue.velocityX=0),Gt&&(ue.currentY=xe,ue.velocityY=0));let Es,Tr;if(mt){let[Nn,jd]=C_(ue.currentX,ue.velocityX,de,Ke,ut,$);ue.currentX=Nn,ue.velocityX=jd,Es=Nn}else Es=Pe.x,ue.velocityX=0;if(Gt){let[Nn,jd]=C_(ue.currentY,ue.velocityY,xe,Ke,ut,$);ue.currentY=Nn,ue.velocityY=jd,Tr=Nn}else Tr=Pe.y,ue.velocityY=0;let dr=Pe.reach??1,ss=Pe.originX??.5,Oo=Pe.originY??.5,Vn=Pe.invertX?-1:1,La=Pe.invertY?-1:1,_a=ss+Vn*(Es-ss)*dr,yn=Oo+La*(Tr-Oo)*dr,Ic=_a,$p=yn,Sf=Z.metadata.boundingBox;if(Sf&&Z.boundingBoxDeclaration?.supportsResizeFit&&_t(Z)){let Nn=q3(Sf,q(),Y()),jd=y4(_a,yn,{centerX:Nn.centerX,centerY:Nn.centerY,halfWidthUV:Nn.halfWidthUV,halfHeightUV:Nn.halfHeightUV,rotationDeg:Nn.rotation,aspectRatio:Be()});Ic=jd.x,$p=jd.y}ue.liveX=Ic,ue.liveY=$p;let R5=Z._liveHandles?.[`_smoothed_${ge}`];R5 instanceof si&&R5.setComponents(Ic,1-$p)}else if(Pe.type===\"mouse\"){let Ke=Pe.smoothing??0,ut=Pe.momentum??0,mt=Pe.axis===\"x\"?de:xe;!ue.pointerSnapped&&De&&(ue.pointerSnapped=!0,ue.currentX=Math.max(.001,mt),ue.velocityX=0);let[Gt,Es]=C_(ue.currentX,ue.velocityX,mt,Ke,ut,$);ue.currentX=Gt,ue.velocityX=Es;let Tr=Math.max(.001,Gt),dr=Z.mapValues[ge],ss=dr?dr.outputMin+(dr.outputMax-dr.outputMin)*Math.pow(Tr,Math.pow(2,-dr.curve*2)):Tr;ue.liveScalar=ss,Qs(Z,`_smoothed_${ge}`,ss)}}}for(let[ge,ue]of Object.entries(Z.uniforms))ue._listSpec&&WA(ue._rawList,ue._listSpec)&&cf(Z,ge);for(let ge in Z.autoAnimateState){let ue=ee[ge];if(!ue||ue.type!==\"auto-animate\")continue;let Pe=oe*(ue.speed??1)*.2,Ke,ut=ue.easing??ue.waveform??\"sine\";if(ue.mode===\"loop\")Ke=pA((Pe%1+1)%1,ut);else{let ss=(Pe%1+1)%1;Ke=pA(ss<.5?ss*2:(1-ss)*2,ut)}let mt=Z.mapValues[ge],Gt=mt?mt.outputMin:Le(Z,ge,ue.outputMin),Es=mt?mt.outputMax:Le(Z,ge,ue.outputMax),Tr=Gt+Ke*(Es-Gt),dr=Z.uniforms[ge];if(dr?.compileTimeWhen){let ss=dr._lastCompiledValue;dr.compileTimeWhen(ss,Tr)&&(dr._lastCompiledValue=Tr,qn())}Qs(Z,`_smoothed_${ge}`,Tr)}}},xf=()=>{let $=Ss.deltaTime;for(let Z of u.values()){let ee=Z.definition.animatedTime;if(ee){let ue=Z.uniforms[ee.speed],Pe=ue&&Number(ue.value)||0,Ke=zl(Oc(Z));Ke.advance($,Pe),Qs(Z,\"_animTime\",Ke.value)}let ge=Z.definition.extraAnimatedTimes;if(ge)for(let[ue,Pe]of Object.entries(ge)){let Ke=Z.uniforms[Pe],ut=Ke&&Number(Ke.value)||0,mt=zl($d(Z,Pe));mt.advance($,ut),Qs(Z,`_animTime_${ue}`,mt.value)}}},Gc=($,Z)=>BB($,Z,{maxTextureDim:k,pixelRatio:L,viewportWidth:typeof window<\"u\"?window.innerWidth:$,viewportHeight:typeof window<\"u\"?window.innerHeight:Z}),Wp=()=>{let $=(typeof window<\"u\"?window.devicePixelRatio:1)||1;return Math.min($,vB())},Fc=($,Z,ee,ge)=>{if(F&&$===C&&Z===E&&ee===R&&ge===U){let{width:ut,height:mt}=Vi();if(!a||a.width===ut&&a.height===mt)return}C=$,E=Z,R=ee,U=ge,qA(ee,ge),F||(F=!0,u.size>0&&qn());let{width:ue,height:Pe}=Vi();a&&(a.width=ue,a.height=Pe);let Ke=!1;for(let ut of y)ut.passManager.resize(ue,Pe)&&(Ke=!0);for(let ut of y)for(let mt of ut.ir.onResize)try{mt({width:ue,height:Pe})}catch(Gt){Sr(\"[gpu] composition onResize error:\",Gt)}for(let ut of u.values()){if(Wn(ut)&&Qs(ut,\"_xform_aspectRatio\",Be()),_t(ut)){let mt=tt(ut);if(mt)for(let[Gt,Es]of Object.entries(mt))Qs(ut,`_bbox_${Gt}`,Es)}We(ut)}if($r(),Ke)for(let ut of y)M5(ut.store),ut.store.flush(),ut.passManager.repaintRtt();Te||(te=0,wf())},qp=($,Z)=>{$<=0||Z<=0||$===D&&Z===O||(D=$,O=Z,qe={width:$,height:Z},!st&&typeof requestAnimationFrame==\"function\"&&(st=!0,requestAnimationFrame(()=>{if(st=!1,!qe)return;let ee=qe;qe=null;let{width:ge,height:ue}=Gc(ee.width,ee.height);Fc(ge,ue,ee.width,ee.height)})))},Af=$=>{let Z=$[0];if(!Z)return;let ee,ge;if(Z.contentBoxSize){let ue=Array.isArray(Z.contentBoxSize)?Z.contentBoxSize[0]:Z.contentBoxSize;ue?(ee=Math.round(ue.inlineSize),ge=Math.round(ue.blockSize)):(ee=Math.round(Z.contentRect.width),ge=Math.round(Z.contentRect.height))}else ee=Math.round(Z.contentRect.width),ge=Math.round(Z.contentRect.height);ee===0||ge===0||qp(ee,ge)},RW=$=>{let Z=$[0];Z&&(X=Z.isIntersecting)},C5=()=>i&&!!t&&!!s&&C>0&&E>0,M5=$=>{let Z=$.systemHandles,{width:ee,height:ge}=Vi(),ue=Wp(),Pe=(Ke,ut)=>{let mt=Z[Ke];mt instanceof si&&(mt.value=ut)};Pe(\"time\",oe),Pe(\"viewportSize\",[ee,ge]),Pe(\"logicalViewportSize\",[q()*ue,Y()*ue]),Pe(\"aspect\",ee/Math.max(1,ge)),Pe(\"pointer\",[de,xe]),Pe(\"pointerActive\",Ae?1:0)},E5=$=>{for(let Z of $)try{Z(Ss)}catch(ee){Sr(\"[gpu] render callback error:\",ee)}},wy=($,Z)=>{if(Wt||!C5())return;let ee=performance.now(),ge=Z??ee,ue;if($!==void 0)ue=$;else{let mt=RB(ge,{lastRenderTime:te,isVisible:X,forceFullFrameRate:Q,minInterval:J});if(!mt.render)return;ue=mt.deltaTime}te=ge,nt&&performance.mark(\"shader-cpu-start\");let Pe=de>-5;Ss.deltaTime=ue,Ss.pointer.x=Pe?de:.5,Ss.pointer.y=Pe?xe:.5,Ss.pointer.seen=De,Ss.pointerActive=Ae,Ss.dimensions.width=C,Ss.dimensions.height=E;let Ke=null,ut=null;try{DB({updateDrivers:()=>{Yp(),xf(),Nt(),cr()},ensureComposition:()=>((P||x===null)&&(x=mf(),P=!1),x===null?!1:(Ke=g.getOrBuild(x,()=>ff(x)),Ay(Ke),!!b)),beforeRender:()=>E5(b.ir.onBeforeRender),flush:()=>{M5(b.store),b.store.flush()},render:()=>{if(nt&&performance.mark(\"shader-gpu-start\"),ut=g.renderValue??Ke,ut?.broken)return!1;let mt=ut,Gt=mt&&mt.validationFrames>0&&mt.ir.usesCustomWgsl?t?.device:void 0;Gt&&Gt.pushErrorScope(\"validation\");try{mt?.passManager.render(s,Ss,()=>b?.store.flush())}finally{Gt&&mt&&(mt.validationFrames--,Gt.popErrorScope().then(Es=>{Es&&!mt.broken&&vf(mt,Es.message)}).catch(()=>{}))}if(nt){performance.mark(\"shader-gpu-end\");try{performance.measure(\"shader-gpu-time\",\"shader-gpu-start\",\"shader-gpu-end\");let Es=performance.getEntriesByName(\"shader-gpu-time\")[0];Es&&Gs.recordGpuTime(Es.duration),performance.clearMeasures(\"shader-gpu-time\"),performance.clearMarks(\"shader-gpu-start\"),performance.clearMarks(\"shader-gpu-end\")}catch{}}},markReady:()=>{g.markReady(x),Mt&&!St&&(St=!0,Mt=!1,yt&&queueMicrotask(yt))},afterRender:()=>E5((ut??b).ir.onAfterRender)}),gs=0}catch(mt){WW(mt);return}if(nt){performance.mark(\"shader-cpu-end\");try{performance.measure(\"shader-cpu-time\",\"shader-cpu-start\",\"shader-cpu-end\");let mt=performance.getEntriesByName(\"shader-cpu-time\")[0];mt&&Gs.recordCpuTime(mt.duration),performance.clearMarks(\"shader-cpu-start\"),performance.clearMarks(\"shader-cpu-end\"),performance.clearMeasures(\"shader-cpu-time\")}catch{}}Gs.recordFrame(performance.now()-ee)},wf=$=>wy(void 0,$),DW=async $=>{if(Wt)return;if(!C5())throw new Error(\"Renderer is not ready\");let Z=or.running;Z&&Vp(),te=0,wy(Te?0:void 0),t&&$?.waitForGpu!==!1&&await mA(t),Z&&Ty()},LW=async($,Z)=>{if(!Number.isFinite($))throw new TypeError(`[gpu] renderSyntheticFrame: deltaSeconds must be a finite number, got ${$}`);wy($),t&&Z?.waitForGpu!==!1&&await mA(t)},Ty=()=>{Wt||Te||or.running||!V||(Gs.setRendering(!0),or.start())},Vp=()=>{or.running&&(or.stop(),Gs.setRendering(!1))},Tf=$=>{if(!a)return;Ee=a.getBoundingClientRect();let Z,ee;if(\"touches\"in $){if($.touches.length===0)return;Z=$.touches[0].clientX,ee=$.touches[0].clientY}else Z=$.clientX,ee=$.clientY;de=(Z-Ee.left)/Ee.width,xe=(ee-Ee.top)/Ee.height,De=!0},UW=$=>{!i||!a||(Tf($),Ae=!0,Da())},OW=$=>{!i||!a||(Tf($),Ae=!0,Da())},GW=()=>{i&&(Ae=!1,Da())},FW=()=>{i&&(Ae=!1,Da())},k5=($,Z)=>{if(!i||!a)return!1;let ee=a.getBoundingClientRect();return ee.width===0||ee.height===0?!1:$>=ee.left&&$<=ee.right&&Z>=ee.top&&Z<=ee.bottom},IW=$=>{$.button===0&&k5($.clientX,$.clientY)&&(Ae=!0,Tf($),Da())},YW=$=>{$.touches.length!==0&&k5($.touches[0].clientX,$.touches[0].clientY)&&(Ae=!0,Tf($),Da())},Np=()=>{let $=!1;for(let Z of u.values()){if(Z.usesPointer){$=!0;break}if(sve(Z.uniforms?.shape?.value)||df(Z)){$=!0;break}if(Z.metadata.maps){for(let ee of Object.values(Z.metadata.maps))if(ee&&typeof ee==\"object\"&&\"type\"in ee){let ge=ee.type;if(ge===\"mouse\"||ge===\"mouse-position\"){$=!0;break}}if($)break}}$&&!ze?(ze=!0,!Ie&&a&&(Ie=tve.register({onMouseMove:UW,onTouchMove:OW,onMouseDown:IW,onTouchStart:YW,onMouseUp:GW,onTouchEnd:FW}))):!$&&ze&&(ze=!1,Ie&&(Ie(),Ie=null))},B5=()=>{if(f.length===0)return;let $=[...f];f=[];for(let ee of $)Xd(ee.id,ee.definition.fragment,ee.parentId,ee.metadata,ee.uniforms,ee.definition,ee.domCanvas);let Z=h;h=[];for(let ee of Z)ee.kind===\"uniform\"?yf(ee.id,ee.name,ee.value):bf(ee.id,ee.metadata)},Rl=($,Z)=>{if(!Wt){Wt=$,F5($),Sr(`[gpu] renderer stopped (${$}):`,Z);try{Sy()}catch(ee){Sr(\"[gpu] cleanup during failure threw:\",ee)}if(!us&&ls){us=!0;let ee=ls;queueMicrotask(()=>{try{ee($,Z)}catch(ge){Sr(\"[gpu] onUnavailable callback threw:\",ge)}})}}},WW=$=>{if(Cy($)){Rl($.reason,$);return}gs++,gs===1&&Mf(\"[gpu] render error:\",$),gs>=eve&&Rl(\"render-failed\",$)},qW=$=>{!$||typeof $.addEventListener!=\"function\"||(z5(),os=$,bs=Z=>{try{Z.preventDefault()}catch{}let ee=Z.error;if(Mf(\"[gpu] uncaptured device error (a custom WGSL body that fails to compile reports here \\u2014 read the message for the line):\",ee),typeof GPUOutOfMemoryError<\"u\"&&ee instanceof GPUOutOfMemoryError){Rl(\"out-of-memory\",ee);return}if(typeof GPUInternalError<\"u\"&&ee instanceof GPUInternalError){Rl(\"gpu-error\",ee);return}hs++,hs>=J1e&&Rl(\"gpu-error\",ee)},$.addEventListener(\"uncapturederror\",bs))},z5=()=>{if(os&&bs)try{os.removeEventListener(\"uncapturederror\",bs)}catch{}os=null,bs=null},VW=$=>{if(!Kt){Kt=!0;try{Vp()}catch{}if(Rt){let Z=Rt;queueMicrotask(()=>{try{Z($)}catch(ee){Sr(\"[gpu] onDeviceLost callback threw:\",ee)}});return}Rl(\"device-lost\",$)}},NW=async $=>{if($.context!==void 0)throw new Error(\"[gpu] initialize({ context }) is not supported \\u2014 this renderer is WebGPU-only. Remove the WebGL `context` option.\");if(Wt)return;let Z=I5();if(Z){Rl(Z);return}if(i||l)return;let{canvas:ee,resizeTarget:ge,enablePerformanceTracking:ue=!1,colorSpace:Pe=\"p3-linear\",toneMapping:Ke=\"linear\",gpu:ut,forceFullFrameRate:mt=!1,observeElement:Gt=!0,timeOrigin:Es}=$;Es!=null&&(le=Es),nt=ue,Q=mt,pt=Pe,Ze=Ke,Ra(),l=!0,d=new AbortController;let Tr=d;try{if(ht=gz,ht(Pe),Tr.signal.aborted||(a=ee,e=await z1e({device:ut?.device,adapter:ut?.adapter,onDeviceLost:yn=>VW(yn.message||yn.reason||\"unknown\")}),Tr.signal.aborted))return;t=e.root,qW(t.device),L=Wp();let dr=t.device.limits?.maxTextureDimension2D;typeof dr==\"number\"&&dr>0&&(k=dr),r=W1e(t),o=C4(t),typeof window<\"u\"&&(we=()=>Sy(),window.addEventListener(\"beforeunload\",we),Ve=()=>{if(D>0&&O>0){let yn=D,Ic=O;D=0,O=0,qp(yn,Ic)}},window.addEventListener(\"resize\",Ve,{passive:!0}));let ss=ee.getBoundingClientRect();Ee=ss,X=!Gt||ss.width>0&&ss.height>0&&ss.top<window.innerHeight&&ss.bottom>0&&ss.left<window.innerWidth&&ss.right>0,V=!0;let Oo=ss.width>0?ss.width:ee.width,Vn=ss.height>0?ss.height:ee.height,La=Math.round(Oo),_a=Math.round(Vn);if(La>0&&_a>0){D=La,O=_a;let{width:yn,height:Ic}=Gc(La,_a);C=yn,E=Ic,R=La,U=_a,F=!0,qA(La,_a);let{width:$p,height:Sf}=Vi();ee.width=$p,ee.height=Sf}else F=!1;if(s=L1e(t,ee),Gt&&typeof ResizeObserver<\"u\"){let yn=ge??ee.parentElement;yn?(ke=new ResizeObserver(Af),ke.observe(yn)):console.warn(\"[gpu] no element available for resize observation \\u2014 use resize() manually\"),typeof IntersectionObserver<\"u\"&&(Me=new IntersectionObserver(RW,{threshold:0,rootMargin:\"128px\"}),Me.observe(ee))}if(Tr.signal.aborted)return;i=!0,c=!0,B5(),C>0&&E>0&&wf(),V&&Ty()}catch(dr){let ss=Cy(dr)?dr.reason:\"init-failed\";l=!1,d===Tr&&(d=null),Rl(ss,dr);return}finally{l=!1,d===Tr&&(d=null)}},Sy=()=>{d&&d.abort(),ke&&(ke.disconnect(),ke=null),Me&&(Me.disconnect(),Me=null),Ie&&(Ie(),Ie=null),we&&typeof window<\"u\"&&(window.removeEventListener(\"beforeunload\",we),we=null),Ve&&typeof window<\"u\"&&(window.removeEventListener(\"resize\",Ve),Ve=null),se!==null&&typeof cancelAnimationFrame==\"function\"&&(cancelAnimationFrame(se),se=null),Vp(),z5(),za?.(),za=null,typeof document<\"u\"&&document.fonts?.removeEventListener&&document.fonts.removeEventListener(\"loadingdone\",ia);try{e?.release?.()}catch{}g.clear();for(let $ of[...y])hf($);b=null;try{r?.destroy()}catch{}try{e?.createdDevice&&t?.destroy()}catch{}u.clear(),p=null,_.clear(),f=[],h=[],c=!1,qe=null,st=!1,a=null,s=null,r=null,o=null,t=null,e=null,i=!1,l=!1,F=!1,d=null,C=0,E=0,R=0,U=0,x=null,P=!0,X=!1,V=!0,Te=!1,de=-10,xe=-10,Ae=!1,De=!1,ze=!1,yt=null,St=!1,Mt=!1,Rt=null,Kt=!1,hs=0,gs=0};return{initialize:NW,cleanup:Sy,registerNode:Xd,removeNode:Hd,updateUniformValue:yf,updateNodeMetadata:bf,isInitialized:()=>i,resize:($,Z)=>{t&&qp($,Z)},startAnimation:Ty,stopAnimation:Vp,renderAndWait:DW,renderSyntheticFrame:LW,getPerformanceStats:()=>{let $=Math.max(0,u.size-1),Z=b?b.ir.rttPasses.length:0;Gs.updateNodeCounts($,Z);let ee={render:{calls:b?b.passManager.passCount:0},programs:{length:g.size},memory:{textures:r?r.textureCount:0}};return Gs.getStats(ee)},getLiveDriverValue:($,Z)=>{let ee=u.get($)?.mouseDriverState?.[Z];return!ee||ee.liveX===void 0||ee.liveY===void 0?null:{x:ee.liveX,y:ee.liveY}},getLiveScalarValue:($,Z)=>{let ee=u.get($);if(!ee)return null;let ge=ee.metadata.maps?.[Z];if(ge?.type===\"auto-animate\"){let ue=ee._liveHandles?.[`_smoothed_${Z}`],Pe=ue instanceof si?ue.value:void 0;return typeof Pe==\"number\"?Pe:null}return ge?.type===\"mouse\"?ee.mouseDriverState[Z]?.liveScalar??null:null},getNodeRegistry:()=>({nodes:new Map(u)}),getRendererType:()=>\"webgpu\",getInternalRenderer:()=>t?{device:t.device,adapter:e?.adapter,root:t}:null,setForceFullFrameRate:$=>{let Z=Q;return Q=$,Z},beginRecordingResolution:($,Z,ee)=>{if(!t||$<=0||Z<=0)return()=>{};let ge=L,ue=C,Pe=E,Ke=R,ut=U,mt=D,Gt=O;return L=ee,Fc($,Z,$,Z),()=>{t&&(L=ge,Fc(ue,Pe,Ke,ut),D=mt,O=Gt)}},setResolutionScale:$=>{if(!t)return;let Z=Math.max(.05,Math.min($,1)),ee=Math.max(.01,Wp()*Z);if(Math.abs(L-ee)<.001)return;L=ee;let ge=R||C,ue=U||E;if(ge<=0||ue<=0)return;let{width:Pe,height:Ke}=Gc(ge,ue);Fc(Pe,Ke,ge,ue)},setFrameRateCap:$=>{J=$&&$>0?1e3/Math.max($,10)-1:0},setTimeOrigin:$=>{le=$},setFrameLocked:$=>{let Z=Te;if(Te=$,!(!$||Z)){Vp(),se!==null&&typeof cancelAnimationFrame==\"function\"&&(cancelAnimationFrame(se),se=null),oe=0;for(let ee of u.values()){ee.definition.animatedTime&&(zl(Oc(ee)).value=0,Qs(ee,\"_animTime\",0));let ge=ee.definition.extraAnimatedTimes;if(ge)for(let[ue,Pe]of Object.entries(ge))zl($d(ee,Pe)).value=0,Qs(ee,`_animTime_${ue}`,0)}}},setOnReady:$=>{yt=$,$&&St&&queueMicrotask($)},setOnDeviceLost:$=>{Rt=$},setOnUnavailable:$=>{if(ls=$,$&&Wt&&!us){us=!0;let Z=Wt;queueMicrotask(()=>{try{$(Z)}catch(ee){Sr(\"[gpu] onUnavailable callback threw:\",ee)}})}},getFailureReason:()=>Wt,__testing:{needsTransformation:el,findChildNodes:lr,buildFieldInits:$=>{let Z=u.get($);return Z?af(Z):null},ensureDriverState:$=>{let Z=u.get($);Z&&Fp(Z)},stepMouseDrivers:$=>{Ss.deltaTime=$,Yp()},stepAnimatedTime:$=>{Ss.deltaTime=$,xf()},getAnimatedTimeValue:$=>{let Z=u.get($);return Z?.definition.animatedTime?zl(Oc(Z)).value:null},writeExtraField:($,Z,ee)=>{let ge=u.get($);ge&&Ip(ge,Z,ee)},readExtraField:($,Z)=>{let ee=u.get($)?._liveHandles?.[Z];return ee instanceof si?ee.value:void 0},getNodeRegistry:()=>({nodes:u,rootId:p,parentToChildren:_}),getParentToChildren:()=>_,getPendingRegistrations:()=>[...f],getFrameDiagnostics:()=>({deltaTime:Ss.deltaTime,pointerX:de,pointerY:xe,pointerActive:Ae,globalElapsedTime:oe,lastRenderTime:te,isVisible:X,forceFullFrameRate:Q,sharedTimeOrigin:le,animating:or.running,mouseListenersNeeded:ze}),computeStructuralHash:mf,isStructuralDirty:()=>P,clearStructuralDirty:()=>{P=!1},setTestReady:$=>{i=!0,c=!0,$&&(C=$.width,E=$.height,R=$.width,U=$.height,F=!0),B5()}}}}var Nd={samplingRate:.05,collectionDuration:5e3,warmupDuration:500,sampleInterval:500,apiEndpoint:\"https://shaders.com/api/telemetry\"};function rve(e){return e.includes(\"Edg/\")||e.includes(\"EdgiOS\")?\"Edge\":e.includes(\"OPR/\")||e.includes(\"Opera/\")?\"Opera\":e.includes(\"Chrome/\")||e.includes(\"CriOS\")?\"Chrome\":e.includes(\"Firefox/\")||e.includes(\"FxiOS\")?\"Firefox\":e.includes(\"Safari/\")&&!e.includes(\"Chrome\")?\"Safari\":\"Other\"}function ove(e){return/iPad|Tablet|PlayBook/i.test(e)||/Android/i.test(e)&&!/Mobile/i.test(e)?\"tablet\":/Mobile|Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(e)?\"mobile\":\"desktop\"}function ave(){if(typeof window>\"u\"||typeof navigator>\"u\")return{domain:\"unknown\",browserFamily:\"unknown\",deviceType:\"unknown\"};let e=navigator.userAgent;return{domain:window.location.hostname,browserFamily:rve(e),deviceType:ove(e)}}var nve=class{renderer;version;sourceType;sessionId;frameSamples=[];sampleInterval=null;stopped=!1;constructor(e,t,s){this.renderer=e,this.version=t,this.sourceType=s,this.sessionId=`tel_${Date.now()}_${Math.random().toString(36).substring(2,9)}`}stop(){this.stopped=!0,this.sampleInterval&&(clearInterval(this.sampleInterval),this.sampleInterval=null)}async start(){try{if(await this.sleep(Nd.warmupDuration),this.stopped||(this.sampleInterval=setInterval(()=>{if(!this.stopped)try{let e=this.renderer.getPerformanceStats();this.frameSamples.push(e)}catch(e){Sr(\"Telemetry sampling error:\",e)}},Nd.sampleInterval),await this.sleep(Nd.collectionDuration-Nd.warmupDuration),this.stopped))return;if(this.sampleInterval&&(clearInterval(this.sampleInterval),this.sampleInterval=null),!this.stopped&&this.frameSamples.length>=5){let e=this.aggregateData();await this.sendTelemetry(e)}}catch(e){Sr(\"Telemetry collection error:\",e)}}sleep(e){return new Promise(t=>setTimeout(t,e))}aggregateData(){let e=this.aggregatePerformance(),t=this.detectRendererType(),s=this.extractComponents(),r=ave();return{sessionId:this.sessionId,timestamp:Date.now(),collectionDuration:Nd.collectionDuration,version:this.version,sourceType:this.sourceType,performance:e,renderer:t,components:s,environment:r}}aggregatePerformance(){if(this.frameSamples.length===0)return{fps:0,frameTime:{avg:0,min:0,max:0,p99:0},jankPercent:0,budgetUsed:0};let e=this.frameSamples.map(p=>p.avgFrameTime),t=this.frameSamples.map(p=>p.jankPercent),s=this.frameSamples.map(p=>p.budgetUsed),r=this.frameSamples.map(p=>p.fps),o=this.calculateMedian(r),a=this.calculateMean(e),i=Math.min(...e),l=Math.max(...e),c=this.calculatePercentile(e,99),d=this.calculateMean(t),u=this.calculateMean(s);return{fps:Math.round(o*10)/10,frameTime:{avg:Math.round(a*10)/10,min:Math.round(i*10)/10,max:Math.round(l*10)/10,p99:Math.round(c*10)/10},jankPercent:Math.round(d*10)/10,budgetUsed:Math.round(u*10)/10}}detectRendererType(){let e=this.frameSamples[this.frameSamples.length-1];return{type:this.renderer.getRendererType?.()||\"webgl\",drawCalls:e?.drawCalls??null,textureCount:e?.textureCount??null}}extractComponents(){try{let e=this.renderer.getNodeRegistry(),t=[];for(let[s,r]of e.nodes)r.parentId!==null&&t.push({name:r.componentName,requiresRTT:r.requiresRTT,renderOrder:r.metadata.renderOrder});return t.sort((s,r)=>s.renderOrder-r.renderOrder)}catch(e){return Sr(\"Failed to extract components:\",e),[]}}async sendTelemetry(e){try{let t=await fetch(Nd.apiEndpoint,{method:\"POST\",headers:{\"Content-Type\":\"application/json\"},body:JSON.stringify(e)});t.ok||di(\"Telemetry send failed:\",t.status,t.statusText)}catch(t){Sr(\"Telemetry send error:\",t)}}calculateMean(e){return e.length===0?0:e.reduce((t,s)=>t+s,0)/e.length}calculateMedian(e){if(e.length===0)return 0;let t=[...e].sort((r,o)=>r-o),s=Math.floor(t.length/2);return t.length%2===0?(t[s-1]+t[s])/2:t[s]}calculatePercentile(e,t){if(e.length===0)return 0;let s=[...e].sort((o,a)=>o-a),r=Math.ceil(t/100*s.length)-1;return s[Math.max(0,r)]}};function ive(e=!1,t=!1){return e||typeof navigator<\"u\"&&navigator.doNotTrack===\"1\"?!1:t?!0:Math.random()<Nd.samplingRate}function EW(e,t,s=!1,r=!1){return ive(s,r)?new nve(e,t,r?\"preview\":\"shader\"):null}function kW(){if(typeof window>\"u\"||!window.location)return!1;let e=window.location.hostname;return!e.includes(\"shaders.com\")&&e!==\"localhost\"&&e!==\"127.0.0.1\"}function P5(e){if(typeof e!=\"object\"||e===null||!(\"type\"in e))return!1;let t=e;return t.type===\"map\"||t.type===\"mouse\"||t.type===\"mouse-position\"||t.type===\"auto-animate\"}var BW=new Set([\"opacity\",\"blendMode\",\"visible\",\"transform\",\"boundingBox\",\"maskSource\",\"maskType\",\"flow\",\"absolute\"]);async function zW(e,t,s){let r=new Map;my().forEach(k=>{r.set(k.definition.name,k.definition);for(let D of k.definition.deprecatedNames??[])r.set(D,k.definition)});for(let k of s?.components??[])r.set(k.name,k);if(!e.style.width||!e.style.height){let k=e.getBoundingClientRect(),D=k.width>0?k.width:e.width,O=k.height>0?k.height:e.height;D>0&&!e.style.width&&(e.style.width=`${D}px`),O>0&&!e.style.height&&(e.style.height=`${O}px`)}function o(k){return{...k,props:k.props?{...k.props}:void 0,children:k.children?.map(o)}}let a={...t,components:t.components.map(o)},i=null,l=!1,c=!1,d=3,u=6e4,p=0,_=0,f=null;function h(k){try{s?.onError?.(k)}catch(D){Sr(\"[createShader] onError callback threw:\",D)}}let g=!1;function y(k){g||(g=!0,f=k,h(k))}function b(k,D,O,F,q){let Y=r.get(O.type)??P2(O.type);if(!Y){console.warn(`[createShader] Unknown component type: ${O.type}`);return}let V=O.id||`${O.type}_${Date.now()}_${Math.random().toString(36).slice(2,9)}`,X={};for(let[J,oe]of Object.entries(O.props||{}))!BW.has(J)&&Object.prototype.hasOwnProperty.call(Y.props,J)&&P5(oe)&&(X[J]=oe);let Q=HA(Y,Object.fromEntries(Object.entries(Y.props).map(([J,oe])=>{let le=O.props?.[J]!==void 0?O.props[J]:oe.default;return[J,P5(le)?oe.default:le]})),V),te={blendMode:O.props?.blendMode||\"normal\",opacity:O.props?.opacity,visible:O.props?.visible,renderOrder:q,id:O.id,maps:Object.keys(X).length>0?{...X}:void 0,mask:O.props?.maskSource?{source:O.props.maskSource,type:O.props.maskType||\"alpha\"}:void 0,transform:O.props?.transform?{offsetX:0,offsetY:0,rotation:0,scale:1,anchorX:.5,anchorY:.5,edges:\"transparent\",...O.props.transform}:void 0,boundingBox:Ih(O.props?.boundingBox),flow:O.props?.flow,absolute:O.props?.absolute};k.registerNode(V,Y.fragment,F,te,Q,Y),D.set(V,{componentDef:Y,uniforms:Q,nodeId:V,component:O,currentMaps:{...X}}),O.children?.forEach((J,oe)=>{b(k,D,J,V,oe)})}async function x(){let k=MW(),D=new Map;s?.onReady&&k.setOnReady(s.onReady),k.setOnUnavailable(q=>{l||y(q)}),await k.initialize({canvas:e,resizeTarget:e,enablePerformanceTracking:s?.enablePerformanceTracking||!1,colorSpace:s?.colorSpace,toneMapping:s?.toneMapping,observeElement:s?.observeElement,gpu:s?.gpu});let O={renderer:k,nodeEntryMap:D,telemetryCollector:null,telemetryStartTimeout:null};k.setOnDeviceLost(q=>{if(l||c||f||i!==null&&i!==O)return;c=!0,h(q);let Y=Date.now();if(Y-_>u&&(p=0),_=Y,++p>d){P(O),i=null,c=!1,y(\"unrecoverable\");return}(async()=>{try{if(P(O),i=null,l)return;let V=await x();if(l){P(V);return}i=V}catch(V){Sr(\"[createShader] rebuild after device loss failed:\",V),y(\"rebuild_failed\")}finally{c=!1}})()});let F=\"shader-root\";if(k.registerNode(F,og.fragment,null,null,{},og),a.components.forEach((q,Y)=>{b(k,D,q,F,Y)}),kW()){let Y=0,V=()=>{if(l||f||i!==O||++Y>40){O.telemetryStartTimeout=null;return}k.getPerformanceStats().fps>0?(O.telemetryCollector=EW(k,\"4.0.4\",s?.disableTelemetry||!1,!1),O.telemetryCollector&&O.telemetryCollector.start(),O.telemetryStartTimeout=null):O.telemetryStartTimeout=setTimeout(V,500)};O.telemetryStartTimeout=setTimeout(V,500)}return O}function P(k){if(k.telemetryCollector){try{k.telemetryCollector.stop()}catch{}k.telemetryCollector=null}k.telemetryStartTimeout!==null&&(clearTimeout(k.telemetryStartTimeout),k.telemetryStartTimeout=null);try{k.renderer.cleanup()}catch{}}i=await x();function C(k,D){if(!i)return;let{renderer:O,nodeEntryMap:F}=i,q=F.get(k);if(!q){console.warn(`[createShader] Component ID not found: ${k}`);return}q.component.props||(q.component.props={});let Y=q.component.props;for(let[V,X]of Object.entries(D))if(BW.has(V))if(V===\"maskSource\")O.updateNodeMetadata(q.nodeId,{mask:X?{source:X,type:D.maskType||Y.maskType||\"alpha\"}:void 0}),Y.maskSource=X,\"maskType\"in D&&(Y.maskType=D.maskType);else{if(V===\"maskType\")continue;V===\"transform\"?(O.updateNodeMetadata(q.nodeId,{transform:X}),Y.transform=X):V===\"boundingBox\"?(O.updateNodeMetadata(q.nodeId,{boundingBox:Ih(X)}),Y.boundingBox=X):(O.updateNodeMetadata(q.nodeId,{[V]:X}),Y[V]=X)}else P5(X)?Object.prototype.hasOwnProperty.call(q.componentDef.props,V)?(q.currentMaps[V]=X,O.updateNodeMetadata(q.nodeId,{maps:{...q.currentMaps}}),Y[V]=X):console.warn(`[createShader] Ignoring PropDriver for unknown prop \"${V}\" on ${q.component.type}`):(V in q.currentMaps&&(delete q.currentMaps[V],O.updateNodeMetadata(q.nodeId,{maps:Object.keys(q.currentMaps).length>0?{...q.currentMaps}:void 0})),Object.prototype.hasOwnProperty.call(q.componentDef.props,V)&&(O.updateUniformValue(q.nodeId,V,X),Y[V]=X))}function E(k,D){let O=e.getBoundingClientRect(),F=k??(O.width>0?O.width:e.width),q=D??(O.height>0?O.height:e.height);F>0&&q>0&&(e.style.width=`${F}px`,e.style.height=`${q}px`,i&&i.renderer.resize(F,q))}function R(){l=!0,i&&(P(i),i=null)}function U(){i&&i.renderer.stopAnimation()}function L(){i&&i.renderer.startAnimation()}return{update:C,resize:E,pause:U,resume:L,destroy:R,getFailureReason:()=>f}}export{zW as createShader};\n","war-room/account-api.mjs":"const changed=()=>Object.assign(Error('Account changed. Refresh the War Room before saving.'),{code:'account_scope_changed'});\r\n// Scope comes only from an authenticated, epoch-consistent room read. It never\r\n// refreshes or relabels a pending body when the account generation changes.\r\nexport function createWarRoomApi({request,transitions}){\r\n let scope=null,readGeneration=0;\r\n const clear=()=>{scope=null;readGeneration++;};\r\n const unsubscribe=transitions.subscribe(clear);\r\n async function api(path,options={}){\r\n  const ticket=transitions.capture(),method=(options.method||'GET').toUpperCase();\r\n  const roomRead=path==='/api/war-room'&&method==='GET',write=path.startsWith('/api/war-room/')&&!['GET','HEAD'].includes(method);\r\n  const expected=scope,generation=roomRead?++readGeneration:readGeneration,headers=new Headers(options.headers);\r\n  if(roomRead)scope=null;\r\n  if(write){if(!expected)throw changed();headers.set('X-Target-Account',expected.owner);headers.set('X-Expected-Data-Epoch',String(expected.epoch));}\r\n  const response=await request(path,{...options,method,headers,signal:ticket.signal,credentials:'same-origin',cache:'no-store'});\r\n  transitions.assertCurrent(ticket);\r\n  const value=await response.json();transitions.assertCurrent(ticket);\r\n  if((roomRead&&generation!==readGeneration)||(write&&scope!==expected))throw changed();\r\n  if(!response.ok)throw Object.assign(Error(value.error||'The War Room service is unavailable.'),{status:response.status,code:value.code});\r\n  if(roomRead){if(typeof value.targetAccountId!=='string'||!value.targetAccountId||!Number.isSafeInteger(value.dataEpoch)||value.dataEpoch<1)throw changed();scope=Object.freeze({owner:value.targetAccountId,epoch:value.dataEpoch});}\r\n  return value;\r\n }\r\n return {api,clear,dispose:()=>{clear();unsubscribe?.();}};\r\n}\r\n","war-room/base-window.mjs":"import {FACTIONS,FACTION_BY_ID} from '../modules/coach-world/catalog.mjs';\r\nimport {assertBase} from '../modules/coach-world/state.mjs';\r\nimport {createPixelBillboards,disposePixelObject} from '../modules/coach-world/sprite-billboards.mjs';\nimport {ART_DIRECTION} from '../modules/coach-world/pixel-art.mjs';\n\r\nexport const validWindowBiome=value=>typeof value==='string'&&Object.hasOwn(FACTION_BY_ID,value)?value:'chest';\r\nexport function guestWindowBiome({storage,owner,account}={}){\r\n if(account?.user?.id||typeof owner!=='string'||!owner.startsWith('guest:')||owner==='guest:unavailable')return 'chest';\r\n try{const base=JSON.parse(storage?.getItem(`myr5-coach-world-v1/${encodeURIComponent(owner)}`));assertBase(base);return base.faction;}catch{return 'chest';}\r\n}\r\n\r\nexport function createWindowThemeController({apply,initialBiome,guestTheme=()=> 'chest',request,transitions}){\r\n let disposed=false,generation=0;apply(validWindowBiome(initialBiome));\r\n const reset=()=>{generation++;if(!disposed)apply('chest');},unsubscribe=transitions.subscribe(reset);\r\n return {reset,async sync(account){const run=++generation;if(disposed)return;\r\n  if(!account){apply(validWindowBiome(guestTheme()));return;}\r\n  apply('chest');const ticket=transitions.capture(),owner=account.user?.id,epoch=account.dataEpoch;\r\n  if(typeof owner!=='string'||!Number.isSafeInteger(epoch)||epoch<1)return;\r\n  try{const response=await request('/api/world',{method:'GET',headers:{'X-Target-Account':owner,'X-Expected-Data-Epoch':String(epoch)},signal:ticket.signal,cache:'no-store'});transitions.assertCurrent(ticket);if(disposed||run!==generation||!response.ok)return;const data=await response.json();transitions.assertCurrent(ticket);if(disposed||run!==generation||data.targetAccountId!==owner||data.dataEpoch!==epoch)return;const faction=data.environment?.faction??data.base?.faction;if(typeof faction==='string'&&Object.hasOwn(FACTION_BY_ID,faction))apply(faction,{phase:data.environment?.phase||'stable',source:data.environment?.source||'civilization'});\r\n  }catch{/* Keep the neutral default while account authority is unavailable. */}\r\n },dispose(){disposed=true;generation++;unsubscribe?.();}};\r\n}\r\n\r\nexport function mountBaseWindow(stage,T,initialBiome='chest',{getCanvas}={}){\r\n let group=null,disposed=false,current=null,currentPhase='stable',roomMode='flat';\r\n function remove(){if(!group)return;disposePixelObject(group);group=null;}\r\n function setBiome(value,{phase='stable'}={}){if(disposed)return;const id=validWindowBiome(value);phase=['stable','warzone','converting','healing','contested'].includes(phase)?phase:'stable';if(current===id&&currentPhase===phase&&group)return;remove();current=id;currentPhase=phase;const f=FACTION_BY_ID[id],index=FACTIONS.findIndex(x=>x.id===id);group=new T.Group();group.name='coach-base-window';group.position.y=roomMode==='cage'?-7:0;group.userData.biome=id;group.userData.phase=phase;group.userData.silhouette=ART_DIRECTION[id]?.shape||id;\n  const frame=new T.MeshBasicMaterial({color:'#243139'}),accent=new T.MeshBasicMaterial({color:f.accent}),add=(geometry,material,x,y,z)=>{const mesh=new T.Mesh(geometry,material);mesh.position.set(x,y,z);mesh.name='base-window-frame';group.add(mesh);return mesh;},box=(w,h,d,m,x,y,z)=>add(new T.BoxGeometry(w,h,d),m,x,y,z);\r\n  // The distant sky and mountains are raster layers, never polygon architecture.\r\n  const pixels=new Uint8Array(64*32*4),sky=new T.Color(f.dark),light=new T.Color(f.color);for(let y=0;y<32;y++)for(let x=0;x<64;x++){const p=(y*64+x)*4,c=sky.clone().lerp(light,(y/31)*.3),ridge=22-Math.abs((x+index*7)%22-11)*.7;if(y>ridge)c.copy(light).multiplyScalar(.45);if(y<15&&(x*19+y*31+index*11)%101===0)c.set(f.accent);pixels[p]=Math.round(c.r*255);pixels[p+1]=Math.round(c.g*255);pixels[p+2]=Math.round(c.b*255);pixels[p+3]=255;}\r\n  const texture=new T.DataTexture(pixels,64,32,T.RGBAFormat);texture.magFilter=texture.minFilter=T.NearestFilter;texture.generateMipmaps=false;texture.needsUpdate=true;texture.colorSpace=T.SRGBColorSpace;const skySprite=new T.Sprite(new T.SpriteMaterial({map:texture,toneMapped:false}));skySprite.name='pixel-window-sky';skySprite.position.set(0,7,-27);skySprite.scale.set(48,32,1);group.add(skySprite);\r\n  const layer=createPixelBillboards(T,{getCanvas});for(let i=0;i<3;i++)layer.add({faction:id,kind:i===1?'hq':'hall',variant:i,x:(i-1)*5.3,z:-13-(i%2)*5,height:4.4+(i%2)*1.4,tint:phase==='stable'?0xffffff:phase==='healing'?0xe0d9c7:0xaaa19c});layer.add({faction:id,kind:'ship',variant:0,x:-5,y:5,z:-18,height:2.3});layer.add({faction:id,kind:'resource',variant:0,x:3.8,z:-11,height:1.5});for(let i=0;i<2;i++)layer.add({faction:id,kind:'crew',variant:0,x:-3+i*6,z:-10,height:1.1});if(phase!=='stable')for(let i=0;i<4;i++)layer.add({faction:id,kind:'rubble',variant:0,x:-6+i*4,z:-10-(i%2),height:1.2});group.add(layer.group);\r\n  // Only the actual window frame remains a physical object in the existing room.\r\n  box(.45,10,.5,frame,-8,3.5,-8);box(.45,10,.5,frame,8,3.5,-8);box(16.5,.45,.5,frame,0,8.3,-8);box(16.5,.6,1.2,frame,0,-1.15,-8);box(.12,9,.2,accent,-4.8,3.5,-8.05);box(.12,9,.2,accent,4.8,3.5,-8.05);\r\n  stage.scene.add(group);stage.mount?.setAttribute('data-base-biome',id);\r\n }\r\n setBiome(initialBiome);return {setBiome,setRoomMode(mode){if(disposed)return;roomMode=mode==='cage'?'cage':'flat';if(group)group.position.y=roomMode==='cage'?-7:0;},get roomMode(){return roomMode;},get biome(){return current;},get group(){return group;},dispose(){if(disposed)return;disposed=true;remove();stage.mount?.removeAttribute('data-base-biome');}};\r\n}\r\n","war-room/coach-sprites.js":"var Lt=Object.defineProperty;var pa=(e,a)=>{for(var t in a)Lt(e,t,{get:a[t],enumerable:!0})};var ue=[{id:\"chest\",name:\"Chest\",description:\"Push-up progressions\"},{id:\"legs\",name:\"Legs\",description:\"Squats and split squats\"},{id:\"hips\",name:\"Hips & glutes\",description:\"Hinges and bridges\"},{id:\"core\",name:\"Core\",description:\"Plank holds\"},{id:\"shoulders\",name:\"Shoulders\",description:\"Controlled arm movement\"},{id:\"balance\",name:\"Balance\",description:\"Single-leg yoga holds\"},{id:\"yoga\",name:\"Yoga\",description:\"Standing poses\"},{id:\"stances\",name:\"Martial stances\",description:\"Controlled stance holds\"},{id:\"boxing\",name:\"Boxing\",description:\"Slow shadowboxing\"},{id:\"cardio\",name:\"Cardio\",description:\"Marches and jacks\"}],oe=[];function C(e,a,t,r,s={}){let o=s.kind??([\"plank\",\"sideplank\",\"balance\",\"yoga\",\"stance\"].includes(r)?\"hold\":r===\"boxing\"?\"pace\":r===\"march\"?\"steps\":\"reps\"),c=s.view??([\"pushup\",\"hinge\",\"bridge\",\"plank\",\"split\"].includes(r)?\"side\":\"front\"),n=o===\"hold\"?\"Pose hold\":o===\"pace\"?\"Active hand time\":o===\"steps\"?\"Knee lifts\":\"Repetitions\",f=s.limits??\"Counts the visible movement; does not grade technique.\",i=c===\"side\"?\"Camera beside you.\":c===\"angle\"?\"Camera at a slight angle.\":\"Face the camera.\";oe.push({id:a,group:e,name:t,detector:r,kind:o,view:c,measurement:n,limits:f,difficulty:oe.filter(l=>l.group===e).length+1,defaultGoal:o===\"hold\"||o===\"pace\"?15:5,evidence:\"rule-based; camera validation pending\",source:\"mediapipe\",...s,hint:`${i} ${s.cue??\"Keep the joints used for this movement visible.\"}`})}var Ot=\"Counts elbow bend and return. Hand shape, support stability and chest depth are not verified.\";for(let[e,a,t]of[[\"knee-pushup\",\"Knee push-up\",{support:\"knees\",cue:\"Knees down; show shoulder, elbow, wrist and hip.\"}],[\"high-incline-pushup\",\"High incline push-up\",{incline:!0,cue:\"Hands on a stable high surface; show your full arm and torso.\"}],[\"low-incline-pushup\",\"Low incline push-up\",{incline:!0,cue:\"Hands on a stable lower surface; show your full arm and torso.\"}],[\"pushup\",\"Regular push-up\",{}],[\"wide-pushup\",\"Wide push-up\",{wide:!0}],[\"slow-pushup\",\"Slow push-up\",{minCycle:1.2}],[\"diamond-pushup\",\"Diamond push-up\",{narrow:!0}],[\"decline-pushup\",\"Feet-elevated push-up\",{decline:!0,cue:\"Feet on a stable low surface; show your full arm and torso.\"}]])C(\"chest\",e,a,\"pushup\",{cue:\"Show shoulder, elbow, wrist and hip. Start with your arm extended.\",limits:Ot,...t});for(let[e,a,t]of[[\"shallow-squat\",\"Shallow squat\",{travel:.18}],[\"squat\",\"Bodyweight squat\",{}],[\"wide-squat\",\"Wide squat\",{wide:!0}],[\"pause-squat\",\"Pause squat\",{dwell:.8}],[\"slow-squat\",\"Slow squat\",{minCycle:1.2}],[\"split-left\",\"Split squat \\xB7 left\",{detector:\"split\",side:\"left\"}],[\"split-right\",\"Split squat \\xB7 right\",{detector:\"split\",side:\"right\"}],[\"wall-sit\",\"Wall sit\",{detector:\"yoga\",pose:\"wall-sit\",kind:\"hold\",view:\"side\",cue:\"Back on a wall, thighs level. Show shoulder, hip and knee.\",limits:\"Times the hip angle and thigh level. Wall contact and knee position are not tracked.\"}]])C(\"legs\",e,a,t.detector??\"squat\",{cue:t.side?\"Show the front leg from hip to knee. Start tall.\":\"Show shoulders and hips. Start standing tall.\",...t});for(let[e,a,t,r]of[[\"small-hinge\",\"Small hip hinge\",\"hinge\",{bend:25}],[\"hip-hinge\",\"Hip hinge\",\"hinge\",{}],[\"good-morning\",\"Bodyweight good morning\",\"hinge\",{arms:\"chest\"}],[\"glute-bridge\",\"Glute bridge\",\"bridge\",{}],[\"pause-bridge\",\"Pause glute bridge\",\"bridge\",{dwell:.8}]])C(\"hips\",e,a,t,{cue:t===\"bridge\"?\"Lie on your back, knees bent. Show shoulder, hip and knee. Start with hips down.\":\"Show shoulder, hip and knee. Start upright; hinge slowly.\",limits:\"Tracks hip movement. Back curvature and muscle engagement are not verified.\",...r});for(let[e,a,t]of[[\"knee-plank\",\"Knee plank\",{support:\"knees\"}],[\"high-plank\",\"High plank\",{}],[\"forearm-plank\",\"Forearm plank\",{forearm:!0}],[\"side-knee-left\",\"Side knee plank \\xB7 left\",{side:\"left\",support:\"knees\"}],[\"side-knee-right\",\"Side knee plank \\xB7 right\",{side:\"right\",support:\"knees\"}],[\"side-plank-left\",\"Side plank \\xB7 left\",{side:\"left\"}],[\"side-plank-right\",\"Side plank \\xB7 right\",{side:\"right\"}]])C(\"core\",e,a,t.side?\"sideplank\":\"plank\",{view:t.side?\"front\":\"side\",cue:t.side?\"Show both shoulders, hips and the supporting knee. Stack your shoulders.\":\"Show shoulder, elbow, wrist, hip and supporting knee.\",limits:\"Times the shoulder\\u2013hip\\u2013knee line. Feet, floor contact and loading are not tracked.\",...t});for(let[e,a,t,r]of[[\"front-raise\",\"Front arm raise\",\"raise\",{view:\"side\",plane:\"front\"}],[\"lateral-raise\",\"Lateral arm raise\",\"raise\",{}],[\"overhead-reach\",\"Overhead reach\",\"raise\",{overhead:!0}],[\"standing-press\",\"Standing arm press\",\"press\",{}],[\"slow-press\",\"Slow arm press\",\"press\",{minCycle:1.2}]])C(\"shoulders\",e,a,t,{cue:\"Keep both shoulders, elbows, wrists and hips visible. Use controlled, unloaded movement.\",...r});for(let[e,a,t]of[[\"knee-balance\",\"Knee-lift balance\",{kneeLift:!0}],[\"low-tree\",\"Low tree pose\",{low:!0}],[\"tree\",\"Tree pose\",{}],[\"overhead-tree\",\"Tree \\xB7 arms overhead\",{overhead:!0}]])C(\"balance\",e,a,\"balance\",{cue:\"Show both hips and knees. Either leg works; keep a support nearby if needed.\",limits:\"Times the visible leg shape. Balance, foot pressure and support use are not verified.\",...t});for(let[e,a,t]of[[\"mountain\",\"Mountain\",\"mountain\"],[\"salute\",\"Upward salute\",\"salute\"],[\"chair\",\"Chair pose\",\"chair\"],[\"warrior-one\",\"Warrior I\",\"warrior-one\"],[\"warrior\",\"Warrior II\",\"warrior\"],[\"goddess\",\"Goddess pose\",\"goddess\"]])C(\"yoga\",e,a,\"yoga\",{pose:t,view:[\"chair\",\"warrior-one\"].includes(t)?\"side\":\"front\",cue:\"Show arms, hips and knees. Hold only a comfortable position.\",limits:\"Times broad pose shape. Foot rotation and joint alignment are not graded.\"});for(let[e,a,t]of[[\"high-horse\",\"High horse stance\",{high:!0}],[\"horse\",\"Horse stance\",{}],[\"low-horse\",\"Lower horse stance\",{low:!0}],[\"front-stance-left\",\"Front stance \\xB7 left\",{side:\"left\"}],[\"front-stance-right\",\"Front stance \\xB7 right\",{side:\"right\"}]])C(\"stances\",e,a,\"stance\",{view:t.side?\"side\":\"front\",cue:\"Keep hips and knees visible. Move slowly into a comfortable stance.\",limits:\"Times stance shape only. This is not martial-arts technique instruction.\",...t});for(let[e,a,t]of[[\"jab-left\",\"Left straight practice\",{side:\"left\"}],[\"jab-right\",\"Right straight practice\",{side:\"right\"}],[\"boxing\",\"Alternating straights\",{}],[\"double-jab\",\"Double-jab practice\",{double:!0}]])C(\"boxing\",e,a,\"boxing\",{view:\"angle\",cue:\"Show shoulders, elbows, wrists and hips. Practice slow, controlled punches into empty space.\",limits:\"Tracks active hand time and relative pace. Punch type, power, accuracy and guard are not verified.\",...t});for(let[e,a,t,r]of[[\"march\",\"Easy march\",\"march\",{}],[\"high-march\",\"High-knee march\",\"march\",{lift:.4}],[\"jogging\",\"Cool Cardio\",\"march\",{lift:.08,runner:!0,endless:!0,cue:\"Treadmill or in place: show your head, shoulders and arms. Run to move, both arms up to jump, crouch to slide, lean to switch lanes. Stop for 10 seconds and Coach catches you.\"}],[\"step-jack\",\"Step jack\",\"jack\",{step:!0}],[\"jumping-jack\",\"Jumping jack\",\"jack\",{}]])C(\"cardio\",e,a,t,{cue:t===\"jack\"?\"Show your upper body and knees. Start with arms down and knees close together.\":\"Show shoulders, hips and both knees. Start standing tall.\",limits:t===\"jack\"?\"Counts arm-and-knee opening cycles. Feet, airtime and landings are not tracked.\":\"Counts knee lifts. Footfalls and impact are not verified.\",...r});var T=Object.freeze(Object.fromEntries(oe.map(e=>[e.id,Object.freeze(e)]))),Be=Object.freeze(Object.fromEntries(ue.map(e=>[e.id,Object.freeze(oe.filter(a=>a.group===e.id))]))),ms=oe.length;var v=Object.freeze([\"roster/21-flyer--winged_humanoid_3d_model\",\"roster/18-quad-all--wooden_robot_3d_model\"]),It=[[\"myr5\",\"original\",[\"MYR5 Jacked LaLAN\",\"Jack LaLanne\",\"jacked strength\",\"local area network\"],[\"MYR5 AT-Lift Prime\",\"Charles Atlas\",\"lift\",\"model designation\"]],[\"02-taper-tallstalk--humanoid_robot_3d_model1\",\"arms\",[\"Arnoid Press\",\"Arnold Schwarzenegger\",\"Arnold press\",\"android\"],[\"ScotTorque Curl\",\"Larry Scott\",\"curl\",\"motor torque\"]],[\"19-genie-multi--multi-armed_humanoid_3d_model1\",\"arms\",[\"Ferri-Delt L0U\",\"Lou Ferrigno\",\"delt\",\"robot designation\"],[\"R0N Curlman\",\"Ronnie Coleman\",\"curl\",\"engine manifold\"]],[\"19-genie-multi--multi-armed_humanoid_3d_model\",\"arms\",[\"Frank Delt-Zan3\",\"Frank Zane\",\"delt\",\"magnetic coil\"],[\"Cutlerator Curl\",\"Jay Cutler\",\"curl\",\"accelerator\"]],[\"17-shellcap-manyarm--mushroom_creature_3d_model\",\"arms\",[\"KAI-nematic Raise\",\"Kai Greene\",\"raise\",\"kinematic mechanism\"],[\"Philament Heave Press\",\"Phil Heath\",\"press\",\"electrical filament\"]],[\"17-shellcap-manyarm--mushroom_robot_3d_model\",\"arms\",[\"Wheel-er Servo-Shrug\",\"Flex Wheeler\",\"shrug\",\"servo wheel\"]],[\"23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"arms\",[\"Ree-volts Raise\",\"Steve Reeves\",\"raise\",\"voltage\"]],[\"08-shard-asym--robot_3d_model4\",\"arms\",[\"S3RG Oliv-Armature\",\"Sergio Oliva\",\"arm\",\"motor armature\"]],[\"17-shellcap-manyarm--3d_character_figurine\",\"arms\",[\"Delt-alinn Bailey\",\"Dana Linn Bailey\",\"delt\",\"Delta designation\"]],[\"06-ridge-triad--geometric_robot_3d_model1\",\"chest\",[\"Oliva-C Pec\",\"Sergio Oliva\",\"pec\",\"vacuum drive\"]],[\"08-shard-asym--geometric_robot_3d_model\",\"chest\",[\"Pec-n0ld Reactor\",\"Arnold Schwarzenegger\",\"pec\",\"reactor\"]],[\"16-spade-arch--pyramid_head_figure_3d_model\",\"chest\",[\"Franx Pec-Zane\",\"Frank Zane\",\"pec\",\"motor drive\"],[\"Y4TES Yoke\",\"Dorian Yates\",\"press\",\"powered yoke\"]],[\"04-crest-wedge--robot_creature_3d_model\",\"chest\",[\"L0U Ferri-pecctor\",\"Lou Ferrigno\",\"pec\",\"reactor\"],[\"Wheeler Wheel-Bench\",\"Flex Wheeler\",\"bench\",\"drive wheel\"]],[\"16-spade-arch--stylized_humanoid_3d_model\",\"chest\",[\"Cutlerator Press\",\"Jay Cutler\",\"press\",\"accelerator\"]],[\"04-crest-wedge--stylized_3d_character\",\"chest\",[\"Gr33ne Grid-Press\",\"Kai Greene\",\"press\",\"power grid designation\"]],[\"09-monolith-tanka--3d_robot_model\",\"chest\",[\"chris BenchSTEAD\",\"Chris Bumstead\",\"bench\",\"robot\"]],[\"09-monolith-tanka--white_horned_robot_3d_model\",\"chest\",[\"Cavalier-EX Chest\",\"Jeff Cavaliere\",\"chest\",\"exercise model EX\"]],[\"15-orbital-coili--robot_character_3d_model\",\"quads\",[\"t-OHM Platzma\",\"Tom Platz\",\"squat\",\"plasma\"]],[\"13-fan-split--stylized_3d_character2\",\"quads\",[\"Quad-Cutler LEGS THO\",\"Jay Cutler\",\"quad\",\"circuit\"],[\"BumSTEADy Squat\",\"Chris Bumstead\",\"squat\",\"steady-state control\"]],[\"22-curve--stylized_cartoon_figure_3d_model\",\"quads\",[\"Kai Gr33ne Lunge\",\"Kai Greene\",\"lunge\",\"gear designation\"]],[\"02-taper-tallstalk--3d_humanoid_figure\",\"quads\",[\"Hane-Yoke Lunge\",\"Lee Haney\",\"lunge\",\"powered yoke\"],[\"Stern-on Squat\",\"Erin Stern\",\"squat\",\"power-on switch\"]],[\"02-taper-tallstalk--white_humanoid_doll_3d_model\",\"quads\",[\"Oli-Volt Lunge\",\"Sergio Oliva\",\"lunge\",\"voltage\"],[\"Y4TES Yoke-Squat\",\"Dorian Yates\",\"squat\",\"robot designation\"]],[\"18-quad-all--wooden_four-legged_robot_3d_model\",\"quads\",[\"Priest-L33 Squat\",\"Lee Priest\",\"squat\",\"piston\"]],[\"18-quad-all--stylized_quadruped_3d_model\",\"quads\",[\"Quadzilla Platz\",\"Tom Platz\",\"quads\",\"kaiju creature\"],[\"SternShift Squat\",\"Erin Stern\",\"squat\",\"gear shift\"]],[\"23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"glutes\",[\"Con-Thrust-Era\",\"Bret Contreras\",\"hip thrust\",\"thruster\"]],[\"23-blob-texture-bodies--sand_creature_3d_model\",\"glutes\",[\"Tingularity Thrust\",\"Chloe Ting\",\"hip thrust\",\"singularity\"]],[\"03-pearl-orb-ring--stylized_3d_character1\",\"glutes\",[\"Gyrvanium Glute-Drive\",\"Caroline Girvan\",\"glute\",\"futuristic alloy\"],[\"Jill-iON Hinge-Flex\",\"Jillian Michaels\",\"hip hinge\",\"ion drive\"]],[\"03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"glutes\",[\"Trac-ION Hip-Thrust\",\"Tracy Anderson\",\"hip thrust\",\"ion drive\"],[\"Simmonics Bridge-Servo\",\"Whitney Simmons\",\"bridge\",\"electronics servo\"]],[\"03-pearl-orb-ring--abstract_humanoid_3d_model\",\"glutes\",[\"Robo-ertson Bridge\",\"Heather Robertson\",\"bridge\",\"robot\"],[\"Hearn-ess ExoHinge\",\"Katy Hearn\",\"hinge\",\"exosuit harness\"]],[\"03-pearl-orb-ring--circle_center\",\"glutes\",[\"Con-Terra Coil-Bridge\",\"Bret Contreras\",\"bridge\",\"planetary coil\"],[\"Cyb-Ho Holo-Bridge\",\"Cassey Ho\",\"bridge\",\"cyborg hologram\"]],[\"23-blob-texture-bodies--cute_blob_creature_3d_model\",\"glutes\",[\"Chlo-Turbo Thrust\",\"Chloe Ting\",\"thrust\",\"turbine\"]],[\"10-petal-wisp--fantasy_creature_3d_model4\",\"yoga\",[\"Adriene A-Sana Mk II\",\"Adriene Mishler\",\"asana\",\"model revision\"]],[\"19-genie-multi--fantasy_creature_3d_model\",\"yoga\",[\"Mat-Gregor Matrix\",\"Kino MacGregor\",\"mat\",\"simulation matrix\"]],[\"10-petal-wisp--ghost_character_3d_model\",\"yoga\",[\"Warri0r-ner Drive\",\"Dylan Werner\",\"warrior pose\",\"motor designation\"],[\"Kathryn Bend-1g\",\"Kathryn Budig\",\"bend\",\"robot\"]],[\"08-shard-asym--stylized_action_figure_3d_model\",\"yoga\",[\"Yee-lastic Flow\",\"Rodney Yee\",\"yoga flow\",\"elastic mechanics\"]],[\"22-curve--stylized_alien_3d_model\",\"yoga\",[\"Strom Flex Current\",\"Max Strom\",\"stretch\",\"electric current\"]],[\"10-petal-wisp--stylized_creature_3d_model\",\"yoga\",[\"Iyeng-Arc Inversion\",\"B. K. S. Iyengar\",\"inversion\",\"powered arc\"]],[\"19-genie-multi--stylized_octopus_3d_model\",\"yoga\",[\"Yee Gyro-Yogi\",\"Rodney Yee\",\"yoga\",\"gyroscope\"]],[\"01-seed-pearo--cute_alien_figure_3d_model\",\"yoga\",[\"Wern-Axis Flow\",\"Dylan Werner\",\"flow\",\"robotic axis\"],[\"Mat-Gregor Drive\",\"Kino MacGregor\",\"mat practice\",\"motor drive\"]],[\"01-seed-pearo--white_3d_character_model\",\"yoga\",[\"Budig-ital Balance\",\"Kathryn Budig\",\"balance\",\"digital\"],[\"Corn Kernel Cobra\",\"Seane Corn\",\"cobra pose\",\"computing kernel\"]],[\"09-monolith-tanka--boxy_humanoid_3d_model\",\"martial-arts\",[\"Bruce L3300\",\"Bruce Lee\",\"kick\",\"alphanumeric call sign\"],[\"GSP-Drive\",\"Georges St-Pierre\",\"spar\",\"motor drive\"]],[\"11-anvil-cask--clay-style_robot_3d_model\",\"martial-arts\",[\"Anderson Sil-VOLT\",\"Anderson Silva\",\"strike\",\"voltage\"],[\"r0nda Rous-Bot\",\"Ronda Rousey\",\"armbar\",\"robot\"]],[\"05-slope-bobble--clay_humanoid_figure_3d_model\",\"martial-arts\",[\"C0N0R McG-Gear\",\"Conor McGregor\",\"kick\",\"gear transmission\"],[\"Nor-Rotor Punch\",\"Chuck Norris\",\"punch\",\"rotor\"]],[\"14-chisel-spire--cone_head_3d_model\",\"martial-arts\",[\"LiDAR Jett-Jab\",\"Jet Li\",\"jab\",\"laser ranging\"],[\"Jaa-Bot Jab\",\"Tony Jaa\",\"jab\",\"robot\"]],[\"08-shard-asym--fantasy_creature_3d_model2\",\"martial-arts\",[\"Waters0nic\",\"Michelle Waterson\",\"kick\",\"sonic drive\"],[\"Amanda Nu-NEURAL\",\"Amanda Nunes\",\"strike\",\"neural implant\"]],[\"09-monolith-tanka--mini_robot_3d_model\",\"martial-arts\",[\"Machi-Droid-a\",\"Lyoto Machida\",\"chop\",\"android\"],[\"Bas Rut-TORque\",\"Bas Rutten\",\"kick\",\"motor torque\"]],[\"09-monolith-tanka--robot_3d_model3\",\"martial-arts\",[\"Israel Ade-SYNC-ya\",\"Israel Adesanya\",\"strike\",\"synchronization\"],[\"Shev-Servo Sweep\",\"Valentina Shevchenko\",\"sweep\",\"servo\"]],[\"13-fan-split--stylized_toy_3d_model\",\"martial-arts\",[\"BlankSaber Kick\",\"Billy Blanks\",\"kick\",\"energy saber\"],[\"Wilsonic Kick\",\"Don Wilson\",\"kick\",\"sonic drive\"]],[\"09-monolith-tanka--robot_3d_model2\",\"martial-arts\",[\"Rous-Torque Throw\",\"Ronda Rousey\",\"throw\",\"motor torque\"],[\"Jackie Chain-Kick\",\"Jackie Chan\",\"kick\",\"chain drive\"]],[\"07-bulb-sphereling--humanoid_robot_3d_model\",\"cardio\",[\"B0LT Sprint-Drive\",\"Usain Bolt\",\"sprint\",\"electrical bolt drive\"]],[\"03-pearl-orb-ring--ringed_humanoid_3d_model\",\"cardio\",[\"Fon-Dynamo Footwork\",\"Jane Fonda\",\"footwork\",\"dynamo\"],[\"Simmonics Sweatstream\",\"Richard Simmons\",\"aerobic sweat\",\"electronics stream\"]],[\"06-ridge-triad--robot_3d_model1\",\"cardio\",[\"M0 Farah Fastlane\",\"Mo Farah\",\"fast run\",\"electric capacitance\"]],[\"03-pearl-orb-ring--robot_3d_model\",\"cardio\",[\"Feli-X Footdrive\",\"Allyson Felix\",\"footwork\",\"X-model drive\"],[\"Rad-Clutch Run\",\"Paula Radcliffe\",\"run\",\"motor clutch\"]],[\"20-lume--robotic_figure_3d_model\",\"cardio\",[\"Pre-Font-AI-ne Pace\",\"Steve Prefontaine\",\"pace\",\"AI running model\"],[\"Ohm-wens Run\",\"Jesse Owens\",\"run\",\"electrical resistance\"]],[\"07-bulb-sphereling--cute_robot_3d_model\",\"cardio\",[\"Billy Blanx Beam\",\"Billy Blanks\",\"boot camp\",\"waveform\"],[\"GebreShell Runloop\",\"Haile Gebrselassie\",\"run\",\"software shell loop\"]],[\"01-seed-pearo--blank_toy_figure_3d_model\",\"cardio\",[\"Phelpeller Pulse\",\"Michael Phelps\",\"cardio pulse\",\"propeller\"],[\"Fon-Droid Footwork\",\"Jane Fonda\",\"footwork\",\"android\"]],[\"18-quad-all--dragon_creature_3d_model\",\"meditation\",[\"H0F-Lung\",\"Wim Hof\",\"breathing\",\"oxygen-code lung\"]],[\"18-quad-all--fantasy_creature_3d_model1\",\"meditation\",[\"Max Ohm-Strom Breath\",\"Max Strom\",\"breathing\",\"electrical resistance\"],[\"Yee-uro Zen\",\"Rodney Yee\",\"mindful movement\",\"neural interface\"]],[\"18-quad-all--fantasy_creature_3d_model3\",\"meditation\",[\"Shiva Rea-spatory\",\"Shiva Rea\",\"respiration\",\"airlock\"]],[\"18-quad-all--four-legged_robot_3d_model\",\"meditation\",[\"Tara-5tile5-Standby\",\"Tara Stiles\",\"breathing\",\"computer standby\"]],[\"18-quad-all--quadruped_robot_3d_model1\",\"meditation\",[\"Werner Wind0wn\",\"Dylan Werner\",\"wind-down practice\",\"alphanumeric standby mode\"]],[\"18-quad-all--quadruped_robot_3d_model\",\"meditation\",[\"Yee Holo-Om\",\"Rodney Yee\",\"mindful movement\",\"hologram\"]],[\"18-quad-all--robotic_dog_3d_model\",\"meditation\",[\"Budig-ital Breath\",\"Kathryn Budig\",\"breathing\",\"digital\"]],[\"12-seedpod-snailslug--stylized_slug_3d_model\",\"meditation\",[\"H0F Hold-Circuit\",\"Wim Hof\",\"breath hold\",\"circuit and model code\"],[\"Ohm-Strom Still\",\"Max Strom\",\"stillness\",\"electrical resistance\"]],[\"12-seedpod-snailslug--stylized_worm_3d_model\",\"meditation\",[\"Pilat-OS Calm-Circuit\",\"Joseph Pilates\",\"mindful breathing\",\"operating system circuit\"]],[\"14-chisel-spire--low_poly_robot_3d_model\",\"meditation\",[\"Rea-Spire Relay\",\"Shiva Rea\",\"respiration\",\"air relay\"]],[\"01-seed-pearo--3d_character_model\",\"meditation\",[\"McKe-O2 Nose-Cone\",\"Patrick McKeown\",\"nasal breathing\",\"rocket nose cone\"],[\"Vertu-al Vent\",\"Shona Vertue\",\"ventilation\",\"virtual reality\"]],[\"23-blob-texture-bodies--blob_creature_3d_model\",\"meditation\",[\"Blob 1 \\xB7 H0F Hold-Drive\",\"Wim Hof\",\"breath hold\",\"air drive and model code\"]],[\"01-seed-pearo--blank_humanoid_figure_3d_model\",\"meditation\",[\"Corn Kernel Om\",\"Seane Corn\",\"meditation\",\"computing kernel\"],[\"Kino-Kinetic Breath\",\"Kino MacGregor\",\"breathing\",\"kinematics\"]]],ga=Object.freeze(Object.fromEntries(It.map(([e,a,...t])=>[e===\"myr5\"?e:`roster/${e}`,Object.freeze({track:a,names:Object.freeze(t.map(([r,s,o,c])=>Object.freeze({name:r,person:s,workout:o,scifi:c})))})])));var ps=Object.freeze(Object.fromEntries(Object.entries(ga).map(([e,a])=>[e,Object.freeze(a.names.map(t=>t.name))])));function Tt(e){let a=ga[e];if(!a)throw RangeError(`No coach name for ${e}.`);return a}var G=(e,a=!1)=>{let t=Tt(e).names;return t[a?1:0]?.name??t[0].name};var q=Object.freeze({sprintRounds:5,gentleActiveSeconds:300,paceActiveSeconds:300,meditationDays:Object.freeze([3,6,9,12])}),Pt=[{id:\"myr5\",sourceLabel:\"Original MYR5\"},{id:\"roster/01-seed-pearo--3d_character_model\",sourceLabel:\"Seed \\xB7 Pearo 1\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--cute_alien_figure_3d_model\",sourceLabel:\"Seed \\xB7 Pearo 2\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--blank_toy_figure_3d_model\",sourceLabel:\"Seed \\xB7 Pearo 5\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/02-taper-tallstalk--3d_humanoid_figure\",sourceLabel:\"Taper \\xB7 Tallstalk 1\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",sourceLabel:\"Taper \\xB7 Tallstalk 2\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",sourceLabel:\"Taper \\xB7 Tallstalk 3\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 1\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--circle_center\",sourceLabel:\"Pearl \\xB7 Orb 2\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 3\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--robot_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 4\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_3d_character1\",sourceLabel:\"Pearl \\xB7 Orb 5\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",sourceLabel:\"Pearl \\xB7 Orb 6\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/04-crest-wedge--robot_creature_3d_model\",sourceLabel:\"Crest \\xB7 Wedge 1\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/04-crest-wedge--stylized_3d_character\",sourceLabel:\"Crest \\xB7 Wedge 2\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",sourceLabel:\"Slope \\xB7 Bobble 1\",group:\"Slope \\xB7 Bobble\"},{id:\"roster/06-ridge-triad--geometric_robot_3d_model1\",sourceLabel:\"Ridge \\xB7 Triad 1\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/06-ridge-triad--robot_3d_model1\",sourceLabel:\"Ridge \\xB7 Triad 2\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/07-bulb-sphereling--cute_robot_3d_model\",sourceLabel:\"Bulb \\xB7 Sphereling 1\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",sourceLabel:\"Bulb \\xB7 Sphereling 2\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/08-shard-asym--geometric_robot_3d_model\",sourceLabel:\"Shard \\xB7 Asym 1\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--robot_3d_model4\",sourceLabel:\"Shard \\xB7 Asym 2\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--fantasy_creature_3d_model2\",sourceLabel:\"Shard \\xB7 Asym 3\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--stylized_action_figure_3d_model\",sourceLabel:\"Shard \\xB7 Asym 4\",group:\"Shard \\xB7 Asym\"},{id:\"roster/09-monolith-tanka--3d_robot_model\",sourceLabel:\"Monolith \\xB7 Tanka 1\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 2\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--mini_robot_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 3\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--robot_3d_model3\",sourceLabel:\"Monolith \\xB7 Tanka 5\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--white_horned_robot_3d_model\",sourceLabel:\"Monolith \\xB7 Tanka 6\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/10-petal-wisp--stylized_creature_3d_model\",sourceLabel:\"Petal \\xB7 Wisp 1\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--ghost_character_3d_model\",sourceLabel:\"Petal \\xB7 Wisp 2\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--fantasy_creature_3d_model4\",sourceLabel:\"Petal \\xB7 Wisp 3\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/11-anvil-cask--clay-style_robot_3d_model\",sourceLabel:\"Anvil \\xB7 Cask 1\",group:\"Anvil \\xB7 Cask\"},{id:\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",sourceLabel:\"Seedpod \\xB7 Snailslug 1\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",sourceLabel:\"Seedpod \\xB7 Snailslug 2\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/13-fan-split--stylized_3d_character2\",sourceLabel:\"Fan \\xB7 Split 1\",group:\"Fan \\xB7 Split\"},{id:\"roster/13-fan-split--stylized_toy_3d_model\",sourceLabel:\"Fan \\xB7 Split 2\",group:\"Fan \\xB7 Split\"},{id:\"roster/14-chisel-spire--cone_head_3d_model\",sourceLabel:\"Chisel \\xB7 Spire 1\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/14-chisel-spire--low_poly_robot_3d_model\",sourceLabel:\"Chisel \\xB7 Spire 2\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/15-orbital-coili--robot_character_3d_model\",sourceLabel:\"Orbital \\xB7 Coili 1\",group:\"Orbital \\xB7 Coili\"},{id:\"roster/16-spade-arch--pyramid_head_figure_3d_model\",sourceLabel:\"Spade \\xB7 Arch 1\",group:\"Spade \\xB7 Arch\"},{id:\"roster/16-spade-arch--stylized_humanoid_3d_model\",sourceLabel:\"Spade \\xB7 Arch 2\",group:\"Spade \\xB7 Arch\"},{id:\"roster/17-shellcap-manyarm--3d_character_figurine\",sourceLabel:\"Shellcap \\xB7 Manyarm 1\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",sourceLabel:\"Shellcap \\xB7 Manyarm 2\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",sourceLabel:\"Shellcap \\xB7 Manyarm 3\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/18-quad-all--dragon_creature_3d_model\",sourceLabel:\"Four-legged 1\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model1\",sourceLabel:\"Four-legged 2\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model3\",sourceLabel:\"Four-legged 3\",group:\"Four-legged\"},{id:\"roster/18-quad-all--four-legged_robot_3d_model\",sourceLabel:\"Four-legged 4\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model1\",sourceLabel:\"Four-legged 5\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model\",sourceLabel:\"Four-legged 6\",group:\"Four-legged\"},{id:\"roster/18-quad-all--robotic_dog_3d_model\",sourceLabel:\"Four-legged 7\",group:\"Four-legged\"},{id:\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",sourceLabel:\"Four-legged 9\",group:\"Four-legged\"},{id:\"roster/19-genie-multi--fantasy_creature_3d_model\",sourceLabel:\"Genie \\xB7 Multi 1\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",sourceLabel:\"Genie \\xB7 Multi 2\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",sourceLabel:\"Genie \\xB7 Multi 3\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--stylized_octopus_3d_model\",sourceLabel:\"Genie \\xB7 Multi 4\",group:\"Genie \\xB7 Multi\"},{id:\"roster/20-lume--robotic_figure_3d_model\",sourceLabel:\"Lume 1\",group:\"Lume\"},{id:\"roster/22-curve--stylized_alien_3d_model\",sourceLabel:\"Curve 1\",group:\"Curve\"},{id:\"roster/22-curve--stylized_cartoon_figure_3d_model\",sourceLabel:\"Curve 2\",group:\"Curve\"},{id:\"roster/23-blob-texture-bodies--blob_creature_3d_model\",sourceLabel:\"Blob 1\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",sourceLabel:\"Blob 2\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",sourceLabel:\"Blob 3\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",sourceLabel:\"Blob 4\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--sand_creature_3d_model\",sourceLabel:\"Blob 5\",group:\"Blob\"}],E=Pt.map(e=>({...e,label:G(e.id)})),Bt=[{id:\"roster/23-blob-texture-bodies--blob_creature_3d_model\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--dragon_creature_3d_model\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model1\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model3\",tracks:[\"meditation\"],difficulty:\"easy\"},{id:\"roster/18-quad-all--four-legged_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model1\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/18-quad-all--robotic_dog_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",tracks:[\"meditation\"],difficulty:\"hard\"},{id:\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",tracks:[\"meditation\"],difficulty:\"expert\"},{id:\"roster/14-chisel-spire--low_poly_robot_3d_model\",tracks:[\"meditation\"],difficulty:\"expert\"},{id:\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",tracks:[\"cardio\"],difficulty:\"easy\"},{id:\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",tracks:[\"cardio\"],difficulty:\"easy\"},{id:\"roster/06-ridge-triad--robot_3d_model1\",tracks:[\"cardio\"],difficulty:\"medium\"},{id:\"roster/03-pearl-orb-ring--robot_3d_model\",tracks:[\"cardio\"],difficulty:\"hard\"},{id:\"roster/20-lume--robotic_figure_3d_model\",tracks:[\"cardio\"],difficulty:\"expert\"},{id:\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",tracks:[\"arms\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",tracks:[\"arms\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",tracks:[\"arms\"],difficulty:\"medium\"},{id:\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",tracks:[\"arms\"],difficulty:\"medium\"},{id:\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",tracks:[\"arms\"],difficulty:\"hard\"},{id:\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",tracks:[\"arms\"],difficulty:\"hard\"},{id:\"roster/08-shard-asym--robot_3d_model4\",tracks:[\"arms\"],difficulty:\"expert\"},{id:\"roster/06-ridge-triad--geometric_robot_3d_model1\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/08-shard-asym--geometric_robot_3d_model\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/16-spade-arch--pyramid_head_figure_3d_model\",tracks:[\"chest\",\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/04-crest-wedge--robot_creature_3d_model\",tracks:[\"chest\"],difficulty:\"hard\"},{id:\"roster/16-spade-arch--stylized_humanoid_3d_model\",tracks:[\"chest\"],difficulty:\"expert\"},{id:\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",tracks:[\"glutes\"],difficulty:\"easy\"},{id:\"roster/23-blob-texture-bodies--sand_creature_3d_model\",tracks:[\"glutes\"],difficulty:\"medium\"},{id:\"roster/03-pearl-orb-ring--stylized_3d_character1\",tracks:[\"glutes\"],difficulty:\"hard\"},{id:\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",tracks:[\"glutes\"],difficulty:\"expert\"},{id:\"roster/15-orbital-coili--robot_character_3d_model\",tracks:[\"quads\"],difficulty:\"easy\"},{id:\"roster/13-fan-split--stylized_3d_character2\",tracks:[\"quads\"],difficulty:\"medium\"},{id:\"roster/22-curve--stylized_cartoon_figure_3d_model\",tracks:[\"quads\"],difficulty:\"hard\"},{id:\"roster/10-petal-wisp--fantasy_creature_3d_model4\",tracks:[\"yoga\"],difficulty:\"easy\"},{id:\"roster/19-genie-multi--fantasy_creature_3d_model\",tracks:[\"yoga\"],difficulty:\"easy\"},{id:\"roster/10-petal-wisp--ghost_character_3d_model\",tracks:[\"yoga\"],difficulty:\"medium\"},{id:\"roster/08-shard-asym--stylized_action_figure_3d_model\",tracks:[\"yoga\"],difficulty:\"medium\"},{id:\"roster/22-curve--stylized_alien_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/10-petal-wisp--stylized_creature_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/19-genie-multi--stylized_octopus_3d_model\",tracks:[\"yoga\"],difficulty:\"expert\"},{id:\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",tracks:[\"martial-arts\"],difficulty:\"easy\"},{id:\"roster/11-anvil-cask--clay-style_robot_3d_model\",tracks:[\"martial-arts\"],difficulty:\"easy\"},{id:\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",tracks:[\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/14-chisel-spire--cone_head_3d_model\",tracks:[\"martial-arts\"],difficulty:\"medium\"},{id:\"roster/08-shard-asym--fantasy_creature_3d_model2\",tracks:[\"martial-arts\"],difficulty:\"hard\"},{id:\"roster/09-monolith-tanka--mini_robot_3d_model\",tracks:[\"martial-arts\"],difficulty:\"hard\"},{id:\"roster/09-monolith-tanka--robot_3d_model3\",tracks:[\"martial-arts\"],difficulty:\"expert\"},{id:\"roster/13-fan-split--stylized_toy_3d_model\",tracks:[\"martial-arts\"],difficulty:\"expert\"},{id:\"roster/01-seed-pearo--3d_character_model\",tracks:[\"meditation\"],difficulty:\"medium\"},{id:\"roster/01-seed-pearo--cute_alien_figure_3d_model\",tracks:[\"yoga\"],difficulty:\"hard\"},{id:\"roster/01-seed-pearo--blank_toy_figure_3d_model\",tracks:[\"cardio\"],difficulty:\"hard\"},{id:\"roster/02-taper-tallstalk--3d_humanoid_figure\",tracks:[\"quads\"],difficulty:\"hard\"},{id:\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",tracks:[\"quads\"],difficulty:\"expert\"},{id:\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",tracks:[\"glutes\"],difficulty:\"easy\"},{id:\"roster/03-pearl-orb-ring--circle_center\",tracks:[\"glutes\"],difficulty:\"medium\"},{id:\"roster/04-crest-wedge--stylized_3d_character\",tracks:[\"chest\"],difficulty:\"easy\"},{id:\"roster/07-bulb-sphereling--cute_robot_3d_model\",tracks:[\"cardio\"],difficulty:\"medium\"},{id:\"roster/09-monolith-tanka--3d_robot_model\",tracks:[\"chest\"],difficulty:\"medium\"},{id:\"roster/09-monolith-tanka--white_horned_robot_3d_model\",tracks:[\"chest\"],difficulty:\"hard\"},{id:\"roster/17-shellcap-manyarm--3d_character_figurine\",tracks:[\"arms\"],difficulty:\"expert\"},{id:\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",tracks:[\"quads\"],difficulty:\"medium\"},{id:\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",tracks:[\"glutes\"],difficulty:\"hard\"}],Dt={chest:[\"chest\"],quads:[\"legs\"],glutes:[\"hips\"],arms:[\"shoulders\"],yoga:[\"core\",\"balance\",\"yoga\"],\"martial-arts\":[\"stances\",\"boxing\"],cardio:[\"cardio\"],meditation:[\"meditation\"]},ce=Object.freeze([\"chest\",\"quads\",\"glutes\",\"arms-shoulders\",\"yoga\",\"martial-arts\",\"cardio\"]),Nt=Object.freeze({arms:\"arms-shoulders\"}),zt=e=>e===\"arms-shoulders\"?\"arms\":e,De=e=>[...new Set((Array.isArray(e)?e:[]).map(a=>Nt[a]??a).filter(a=>ce.includes(a)))];var F=Object.freeze([\"myr5\",\"roster/23-blob-texture-bodies--blob_creature_3d_model\"]);function Ne(e){let a=T[e];if(!a)return\"easy\";let t=Be[a.group].filter(r=>r.kind===a.kind);return[\"easy\",\"medium\",\"hard\",\"expert\"][Math.min(3,Math.floor(t.indexOf(a)*4/t.length))]}var P=Bt.filter(e=>!F.includes(e.id)).map(e=>({...e,name:G(e.id),groups:e.tracks.flatMap(a=>Dt[a])})),fe=Object.freeze(Object.fromEntries(ce.map(e=>[e,P.find(a=>a.tracks[0]===zt(e)&&a.difficulty===\"easy\").id]))),me=e=>De(e).map(a=>fe[a]),ze=[{id:\"supportive\",group:\"legs\",kind:\"hold\"},{id:\"direct\",group:\"legs\",kind:\"reps\"},{id:\"analytical\",group:\"chest\",kind:\"reps\"},{id:\"playful\",group:\"stances\",kind:\"hold\"},{id:\"calm\",group:\"yoga\",kind:\"hold\"},{id:\"mom\",group:\"hips\",kind:\"reps\"}];function ya(e,a){return P.filter(t=>t.groups.includes(e)&&t.difficulty===a)}var he=Object.freeze([\"easy\",\"medium\",\"hard\",\"expert\"]),_a=e=>Object.freeze(e.map(a=>Object.freeze(a.map(t=>t*10)))),_s=_a([[4,8,16],[8,12,20],[12,16,24],[16,20,28]]),Ss=_a([[1,2,4],[2,3,5],[3,4,6],[4,5,7]]);var ka=600;var Ut=15;var Gt=Object.freeze({uncommon:1,rare:2,legendary:3,secret:3}),qt=Object.freeze({uncommon:Object.freeze({color:90,\"64-bit\":7,texture:3}),rare:Object.freeze({color:80,\"64-bit\":15,texture:5}),legendary:Object.freeze({color:70,\"64-bit\":20,texture:10}),secret:Object.freeze({color:60,\"64-bit\":20,texture:20})}),$t=2,Ge=500*10,K=Object.freeze({sessions:120,activeMinutes:30,expertXpPerMinute:280,meditationMultiplier:$t,trioBonus:Ge}),jt=K.sessions*(K.activeMinutes*K.expertXpPerMinute*K.meditationMultiplier+K.trioBonus),xs=K.expertXpPerMinute*Ut/60;var Sa=250,Ue=Sa-1,wa=40,Ht=jt/10,B=Object.freeze(Array.from({length:Sa},(e,a)=>10*(wa*a+Math.floor((Ht-wa*Ue)*a*(a-1)/(Ue*(Ue-1))))));function xa(e,a){if(!Number.isFinite(e)||e<0)throw RangeError(`Invalid ${a}.`);return e}function Ca(e,a){if(xa(a,\"performance\"),e===\"hold\")return{weapon1:a>=60,weapon2:a>=180,coach:a>=300,golden:a>=ka,special:a>=ka};if(e===\"reps\")return{weapon1:a>=8,weapon2:a>=12,coach:a>=15,golden:!1,special:!1};throw RangeError(\"Unknown performance kind.\")}function va(e){xa(e,\"XP\");let a=0;for(;a<B.length-1&&e>=B[a+1];)a++;let t=a===B.length-1;return{level:a+1,xp:e,floor:B[a],next:t?null:B[a+1],into:t?0:e-B[a],need:t?0:B[a+1]-B[a],max:t}}var Kt=\"myr5-performance-progress-v2\";function x(e=globalThis.localStorage,a=globalThis.myr5AuthenticatedAccount){let t=a?.user?.id;if(t)return`account:${t}${a.dataEpoch!=null?`:${a.dataEpoch}`:\"\"}`;if(!e)return\"guest:unavailable\";let r=\"myr5-local-guest-owner-v1\";try{let s=e.getItem(r);return s||(s=globalThis.crypto?.randomUUID?.()||`guest-${Date.now()}-${Math.random()}`,e.setItem(r,s)),`guest:${s}`}catch{return\"guest:unavailable\"}}var pe=3,Ra=()=>({version:2,accessVersion:pe,xpScale:10,paths:[],sessions:{},days:{},coaches:[...F],goldenCoaches:[],weapons:{},ships:[],completions:{},totalXp:0,excludedCoaches:[]});function Yt(e={}){let a=Object.hasOwn(e,\"storage\")?e.storage:globalThis.localStorage,t=Object.hasOwn(e,\"account\")?e.account:globalThis.myr5AuthenticatedAccount;return{storage:a,owner:e.owner??x(a,t)}}var D=e=>e&&typeof e==\"object\"&&!Array.isArray(e),ne=e=>Number.isFinite(e)&&e>=0,qe=e=>typeof e==\"string\"&&/^\\d{4}-\\d{2}-\\d{2}$/.test(e)&&new Date(`${e}T12:00:00Z`).toISOString().slice(0,10)===e,Xt=e=>Array.isArray(e)&&(e.length===0||e.length===2&&new Set(e).size===2&&e.every(a=>ce.includes(a)));function Vt(e){return e?.version===2&&(e.accessVersion===void 0||e.accessVersion===pe)&&(e.xpScale===void 0||e.xpScale===10)&&(e.paths===void 0||Xt(e.paths))&&(e.activities===void 0||D(e.activities)&&Object.values(e.activities).every(a=>D(a)&&[\"meditation\",\"food\"].includes(a.kind)&&qe(a.day)))&&D(e.sessions)&&D(e.days)&&D(e.weapons)&&D(e.completions)&&Array.isArray(e.coaches)&&e.coaches.every(a=>E.some(t=>t.id===a)||v.includes(a))&&new Set(e.coaches).size===e.coaches.length&&Array.isArray(e.goldenCoaches)&&e.goldenCoaches.every(a=>e.coaches.includes(a))&&Array.isArray(e.ships)&&e.ships.every(a=>ze.some(t=>t.id===a))&&Object.values(e.weapons).every(a=>Number.isInteger(a)&&a>=0&&a<=20)&&Object.values(e.completions).every(a=>Number.isSafeInteger(a)&&a>=0)&&Object.entries(e.days).every(([a,t])=>qe(a)&&D(t)&&ne(t.workoutXp)&&[\"workout\",\"meditation\",\"food\"].every(r=>typeof t[r]==\"boolean\"))&&Object.values(e.sessions).every(a=>D(a)&&qe(a.day)&&ne(a.xp)&&ne(a.value)&&ne(a.continuous))}var Ea={sprint:q.sprintRounds,gentle:q.gentleActiveSeconds,pace:q.paceActiveSeconds};function Jt(e){let a=new Set(F),t=(s,o)=>{for(let c of ya(s,o))a.add(c.id)};for(let s of Object.values(e.sessions))if(s.kind===\"hold\"||s.kind===\"reps\")for(let[o,c]of s.kind===\"hold\"?Object.entries(s.perDifficultyContinuous??{[s.difficulty]:s.continuous}):[[s.difficulty,s.value]])ne(c)&&Ca(s.kind,c).coach&&t(s.group,o);else s.kind in Ea&&s.value>=Ea[s.kind]&&t(s.group,s.difficulty);let r=Object.values(e.days).filter(s=>s.meditation).length;return he.forEach((s,o)=>{r>=q.meditationDays[o]&&t(\"meditation\",s)}),a}function Qt(e){if(e.xpScale!==10){for(let a of Object.values(e.days))a.workoutXp*=10;for(let a of Object.values(e.sessions))a.xp*=10;e.xpScale=10}e.excludedCoaches??=[];for(let a of v)e.excludedCoaches.includes(a)||e.excludedCoaches.push(a);if(e.paths??=[],e.accessVersion!==pe){let a=new Set([...Jt(e),...me(e.paths)]);e.coaches=E.map(t=>t.id).filter(t=>a.has(t)),e.accessVersion=pe}e.coaches=e.coaches.filter(a=>!v.includes(a));for(let a of F)er(e.coaches,a);return e.goldenCoaches=e.goldenCoaches.filter(a=>e.coaches.includes(a)),e}function R(e={}){try{let{storage:a,owner:t}=Yt(e),r=JSON.parse(a?.getItem(`${Kt}/${t}`)||\"null\");return Vt(r)?Zt(Qt(r)):Ra()}catch{return Ra()}}function Zt(e){return e.totalXp=Object.values(e.days).reduce((a,t)=>a+t.workoutXp*(t.meditation?2:1)+(t.workout&&t.meditation&&t.food?Ge:0),0)+(Number.isFinite(e.worldBonusXp)&&e.worldBonusXp>=0?e.worldBonusXp:0),e}var er=(e,a)=>{e.includes(a)||e.push(a)};function $e(e){let a=Object.values(e?.days??{}),t=Object.keys(e?.sessions??{}).length>0||a.some(o=>o.workout),r=a.some(o=>o.meditation),s=a.some(o=>o.food);return{workout:t,meditation:r,food:s,done:t&&r&&s}}var je=(e={})=>{let a=R(e);return $e(a).done?E.map(t=>t.id).filter(t=>!v.includes(t)):a.coaches},ge=(e,a={})=>je(a).includes(e),ye=(e,a={})=>R(a).goldenCoaches.includes(e);var He={single:{label:\"One cyclops eye\",eyes:[[0,2.1575,.55,.605,0]]},horizontal:{label:\"Horizontal pair\",eyes:[[-.34,2.25,.49,.32,0],[.34,2.25,.49,.32,0]]},vertical:{label:\"Vertical pair\",eyes:[[0,2.03,.49,.32,0],[0,2.73,.39,.31,0]]},triangle:{label:\"Triangle\",eyes:[[-.33,2.17,.49,.3,0],[.33,2.17,.49,.3,0],[0,2.8,.36,.28,0]]},spider:{label:\"Spider \\xB7 two big + two small\",eyes:[[-.34,2.16,.49,.32,0],[.34,2.16,.49,.32,0],[-.235,2.77,.375,.2,0],[.235,2.77,.375,.2,0]]},square:{label:\"Four small \\xB7 square\",eyes:[[-.285,2.16,.49,.25,0],[.285,2.16,.49,.25,0],[-.285,2.73,.375,.25,0],[.285,2.73,.375,.25,0]]}};var ke=[{id:\"supportive\",name:\"Supportive\",tone:\"Warm, patient, encouraging.\",approach:\"Acknowledge effort. Offer one manageable next step. Celebrate progress without pressure.\",lines:{start:\"We can start small. What is one thing you could do in the next five minutes?\",stuck:\"You do not have to solve everything at once. Let\\u2019s make the next step smaller.\",missed:\"One missed goal does not erase your progress. What would make trying again easier?\",win:\"You followed through. Take a moment to notice what helped you do that.\"}},{id:\"direct\",name:\"Direct\",tone:\"Clear, firm, practical.\",approach:\"Be concise. Turn vague intentions into a specific next action. Hold the user accountable without insults.\",lines:{start:\"Pick one task. Decide what finished looks like. Begin with the first step.\",stuck:\"Name the obstacle. Choose one action that is still under your control.\",missed:\"Review what got in the way, adjust the plan, and choose your next attempt.\",win:\"You did what you said you would. Keep the part of the plan that worked.\"}},{id:\"analytical\",name:\"Analytical\",tone:\"Methodical, curious, precise.\",approach:\"Ask about constraints. Break goals into observable steps. Treat setbacks as information, not character flaws.\",lines:{start:\"What is the goal, what time do you have, and what is the smallest useful result?\",stuck:\"Is the obstacle time, clarity, energy, or resources? Let\\u2019s change one variable.\",missed:\"Compare the plan with what happened. Which assumption needs updating?\",win:\"What specifically helped? Record it so you can repeat the conditions.\"}},{id:\"playful\",name:\"Playful\",tone:\"Mischievous, upbeat, lightly teasing.\",approach:\"Use small quests and creature humor. Keep encouragement specific. Never shame the user.\",lines:{start:\"Tiny quest unlocked: defeat the first five minutes. The giant task can wait its turn.\",stuck:\"This boss fight needs a smaller boss. What can we turn into a side quest?\",missed:\"The quest log has been updated, not destroyed. Pick your next checkpoint.\",win:\"Achievement unlocked: actually doing the thing. My one eye is impressed.\"}},{id:\"calm\",name:\"Calm\",tone:\"Steady, spacious, grounded.\",approach:\"Use short, unhurried language. Leave room for the user\\u2019s choices. Focus on the present next step.\",lines:{start:\"There is no need to rush the whole plan. Choose one thing to begin.\",stuck:\"Pause for a moment. What feels possible from where you are right now?\",missed:\"That attempt is over. You can choose a gentler, more workable next one.\",win:\"Notice this moment. You made progress, and you can let that be enough for now.\"}},{id:\"mom\",name:\"MOM Inc.\",tone:\"Polite, theatrical, dry corporate humor.\",approach:\"Use fictional MOM Inc. bureaucracy and understated absurdity. Keep choices voluntary and practical.\",lines:{start:\"MOM Inc. has approved one manageable task. Please select yours; the paperwork can wait.\",stuck:\"Your obstacle has been escalated to the Department of Smaller Steps. What can we simplify?\",missed:\"No disciplinary forms today. We are revising the plan, not your worth.\",win:\"Progress officially recorded. Please accept one highly regulated moment of pride.\"}}];var We=[[\"round\",\"Round\"],[\"vertical\",\"Vertical slit\"],[\"horizontal\",\"Horizontal slit\"],[\"oval\",\"Oval\"],[\"diamond\",\"Diamond\"],[\"star\",\"Star\"],[\"heart\",\"Heart\"],[\"cross\",\"Cross\"]];var ar=[{id:\"nails\",label:\"Nails\",short:\"Nails\",description:\"Five claw and nail forms\"},{id:\"fingertips\",label:\"Finger tips\",short:\"Tips\",description:\"Distal pads and final phalanges\"},{id:\"fingers\",label:\"Fingers & knuckles\",short:\"Fingers\",description:\"Joined finger shafts, bases and knuckles\"},{id:\"palm\",label:\"Palm\",short:\"Palm\",description:\"The inner hand surface\"},{id:\"back_of_hand\",label:\"Back of hand\",short:\"Back\",description:\"The dorsal hand surface\"},{id:\"wrist\",label:\"Wrist\",short:\"Wrist\",description:\"Stump, cuff and transition\"}],$=[{id:0,name:\"Mortal\",realm:\"Baseline \\xB7 Earth\",primary:\"#b9856f\",secondary:\"#714c42\",accent:\"#f0c0a3\",emissive:\"#000000\",roughness:.72,metalness:.02,detail:\"clean\"},{id:1,name:\"Verdant\",realm:\"Wildroot \\xB7 Dimension 12\",primary:\"#3f7448\",secondary:\"#1e3b2b\",accent:\"#b8dd6e\",emissive:\"#172d13\",roughness:.88,metalness:0,detail:\"vine\"},{id:2,name:\"Mycelial\",realm:\"Sporesea \\xB7 Dimension 09\",primary:\"#d5c7ae\",secondary:\"#776b82\",accent:\"#f59ec4\",emissive:\"#6d234a\",roughness:.92,metalness:0,detail:\"caps\"},{id:3,name:\"Chitin\",realm:\"Carapace \\xB7 Dimension 31\",primary:\"#4f263d\",secondary:\"#180f20\",accent:\"#d17663\",emissive:\"#240716\",roughness:.3,metalness:.28,detail:\"plates\"},{id:4,name:\"Reptilian\",realm:\"Scalehold \\xB7 Dimension 04\",primary:\"#5f7a3f\",secondary:\"#283621\",accent:\"#cfb85c\",emissive:\"#101c08\",roughness:.76,metalness:.04,detail:\"scales\"},{id:5,name:\"Abyssal\",realm:\"Deep Trench \\xB7 Dimension 88\",primary:\"#132a42\",secondary:\"#06111f\",accent:\"#4edfd3\",emissive:\"#0b756f\",roughness:.34,metalness:.12,detail:\"spines\"},{id:6,name:\"Coral\",realm:\"Living Reef \\xB7 Dimension 22\",primary:\"#e46867\",secondary:\"#70344c\",accent:\"#ffd27a\",emissive:\"#8b2438\",roughness:.83,metalness:0,detail:\"coral\"},{id:7,name:\"Skeletal\",realm:\"Ossuary \\xB7 Dimension 00\",primary:\"#d8d0af\",secondary:\"#80785f\",accent:\"#fff7d1\",emissive:\"#17160e\",roughness:.9,metalness:0,detail:\"bone\"},{id:8,name:\"Spectral\",realm:\"Veil \\xB7 Dimension 13\",primary:\"#8ed9cd\",secondary:\"#294c58\",accent:\"#d5fff8\",emissive:\"#248e86\",roughness:.18,metalness:.04,detail:\"mist\"},{id:9,name:\"Infernal\",realm:\"Cinder Court \\xB7 Dimension 66\",primary:\"#7b211e\",secondary:\"#260b0a\",accent:\"#ff8a2a\",emissive:\"#d33812\",roughness:.58,metalness:.1,detail:\"flame\"},{id:10,name:\"Celestial\",realm:\"High Orbit \\xB7 Dimension 07\",primary:\"#e6dca4\",secondary:\"#786da7\",accent:\"#fffbd7\",emissive:\"#8d74d6\",roughness:.24,metalness:.5,detail:\"halo\"},{id:11,name:\"Voidborn\",realm:\"Null Expanse \\xB7 Dimension \\u2205\",primary:\"#16101f\",secondary:\"#060409\",accent:\"#9f64ff\",emissive:\"#482285\",roughness:.16,metalness:.36,detail:\"void\"},{id:12,name:\"Eldritch\",realm:\"Watcher Fold \\xB7 Dimension 47\",primary:\"#6b426c\",secondary:\"#252038\",accent:\"#b6ef63\",emissive:\"#4e7628\",roughness:.64,metalness:.04,detail:\"eyes\"},{id:13,name:\"Stone Golem\",realm:\"Deep Strata \\xB7 Dimension 19\",primary:\"#6f7068\",secondary:\"#393b37\",accent:\"#b7a37d\",emissive:\"#171811\",roughness:.98,metalness:0,detail:\"rock\"},{id:14,name:\"Crystal\",realm:\"Prism Vault \\xB7 Dimension 52\",primary:\"#896bc2\",secondary:\"#302e66\",accent:\"#e0c8ff\",emissive:\"#5a3da8\",roughness:.12,metalness:.3,detail:\"crystal\"},{id:15,name:\"Magma\",realm:\"Mantle \\xB7 Dimension 03\",primary:\"#4a1713\",secondary:\"#140706\",accent:\"#ffb22f\",emissive:\"#e44712\",roughness:.78,metalness:.06,detail:\"magma\"},{id:16,name:\"Glacial\",realm:\"White Silence \\xB7 Dimension 71\",primary:\"#93c9df\",secondary:\"#315a76\",accent:\"#ebfdff\",emissive:\"#3c93bb\",roughness:.2,metalness:.14,detail:\"ice\"},{id:17,name:\"Stormcharged\",realm:\"Tempest Ring \\xB7 Dimension 28\",primary:\"#48536e\",secondary:\"#1a2236\",accent:\"#c3f7ff\",emissive:\"#3ebde0\",roughness:.4,metalness:.32,detail:\"storm\"},{id:18,name:\"Clockwork Robot\",realm:\"Brass Meridian \\xB7 Dimension 14\",primary:\"#9a6a37\",secondary:\"#33251d\",accent:\"#efd08c\",emissive:\"#5b2c12\",roughness:.32,metalness:.82,detail:\"gears\"},{id:19,name:\"Neon Synth\",realm:\"Aftergrid \\xB7 Dimension 20\",primary:\"#251d54\",secondary:\"#0b0921\",accent:\"#ff5bd7\",emissive:\"#b519ac\",roughness:.22,metalness:.55,detail:\"neon\"},{id:20,name:\"Fluffy\",realm:\"Cloudburrow \\xB7 Soft forms\",primary:\"#d6a987\",secondary:\"#bb8969\",accent:\"#ffe4c3\",emissive:\"#000000\",roughness:.88,metalness:0,detail:\"fur\"},{id:21,name:\"Jelly\",realm:\"Lime Lagoon \\xB7 Soft forms\",primary:\"#a7ec69\",secondary:\"#f1ffd4\",accent:\"#c9ff90\",emissive:\"#000000\",roughness:.13,metalness:0,detail:\"jelly\"},{id:22,name:\"Baby\",realm:\"Little One \\xB7 Soft forms\",primary:\"#efb398\",secondary:\"#d68e7c\",accent:\"#ffe2d5\",emissive:\"#000000\",roughness:.52,metalness:0,detail:\"baby\"}];var Bs=$.map(e=>({name:e.name,description:`A pure ${e.name.toLowerCase()} hand`,values:Object.fromEntries(ar.map(a=>[a.id,e.id]))})),Ds=$.filter(e=>![8,11].includes(e.id));var tr=[{id:\"roster/01-seed-pearo--3d_character_model\",label:\"Seed \\xB7 Pearo 1\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--cute_alien_figure_3d_model\",label:\"Seed \\xB7 Pearo 2\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--white_3d_character_model\",label:\"Seed \\xB7 Pearo 3\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--blank_humanoid_figure_3d_model\",label:\"Seed \\xB7 Pearo 4\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/01-seed-pearo--blank_toy_figure_3d_model\",label:\"Seed \\xB7 Pearo 5\",group:\"Seed \\xB7 Pearo\"},{id:\"roster/02-taper-tallstalk--3d_humanoid_figure\",label:\"Taper \\xB7 Tallstalk 1\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",label:\"Taper \\xB7 Tallstalk 2\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/02-taper-tallstalk--white_humanoid_doll_3d_model\",label:\"Taper \\xB7 Tallstalk 3\",group:\"Taper \\xB7 Tallstalk\"},{id:\"roster/03-pearl-orb-ring--abstract_humanoid_3d_model\",label:\"Pearl \\xB7 Orb 1\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--circle_center\",label:\"Pearl \\xB7 Orb 2\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",label:\"Pearl \\xB7 Orb 3\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--robot_3d_model\",label:\"Pearl \\xB7 Orb 4\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_3d_character1\",label:\"Pearl \\xB7 Orb 5\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",label:\"Pearl \\xB7 Orb 6\",group:\"Pearl \\xB7 Orb\"},{id:\"roster/04-crest-wedge--robot_creature_3d_model\",label:\"Crest \\xB7 Wedge 1\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/04-crest-wedge--stylized_3d_character\",label:\"Crest \\xB7 Wedge 2\",group:\"Crest \\xB7 Wedge\"},{id:\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",label:\"Slope \\xB7 Bobble 1\",group:\"Slope \\xB7 Bobble\"},{id:\"roster/06-ridge-triad--geometric_robot_3d_model1\",label:\"Ridge \\xB7 Triad 1\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/06-ridge-triad--robot_3d_model1\",label:\"Ridge \\xB7 Triad 2\",group:\"Ridge \\xB7 Triad\"},{id:\"roster/07-bulb-sphereling--cute_robot_3d_model\",label:\"Bulb \\xB7 Sphereling 1\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",label:\"Bulb \\xB7 Sphereling 2\",group:\"Bulb \\xB7 Sphereling\"},{id:\"roster/08-shard-asym--geometric_robot_3d_model\",label:\"Shard \\xB7 Asym 1\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--robot_3d_model4\",label:\"Shard \\xB7 Asym 2\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--fantasy_creature_3d_model2\",label:\"Shard \\xB7 Asym 3\",group:\"Shard \\xB7 Asym\"},{id:\"roster/08-shard-asym--stylized_action_figure_3d_model\",label:\"Shard \\xB7 Asym 4\",group:\"Shard \\xB7 Asym\"},{id:\"roster/09-monolith-tanka--3d_robot_model\",label:\"Monolith \\xB7 Tanka 1\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",label:\"Monolith \\xB7 Tanka 2\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--mini_robot_3d_model\",label:\"Monolith \\xB7 Tanka 3\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--robot_3d_model2\",label:\"Monolith \\xB7 Tanka 4\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--robot_3d_model3\",label:\"Monolith \\xB7 Tanka 5\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/09-monolith-tanka--white_horned_robot_3d_model\",label:\"Monolith \\xB7 Tanka 6\",group:\"Monolith \\xB7 Tanka\"},{id:\"roster/10-petal-wisp--stylized_creature_3d_model\",label:\"Petal \\xB7 Wisp 1\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--ghost_character_3d_model\",label:\"Petal \\xB7 Wisp 2\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/10-petal-wisp--fantasy_creature_3d_model4\",label:\"Petal \\xB7 Wisp 3\",group:\"Petal \\xB7 Wisp\"},{id:\"roster/11-anvil-cask--clay-style_robot_3d_model\",label:\"Anvil \\xB7 Cask 1\",group:\"Anvil \\xB7 Cask\"},{id:\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",label:\"Seedpod \\xB7 Snailslug 1\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",label:\"Seedpod \\xB7 Snailslug 2\",group:\"Seedpod \\xB7 Snailslug\"},{id:\"roster/13-fan-split--stylized_3d_character2\",label:\"Fan \\xB7 Split 1\",group:\"Fan \\xB7 Split\"},{id:\"roster/13-fan-split--stylized_toy_3d_model\",label:\"Fan \\xB7 Split 2\",group:\"Fan \\xB7 Split\"},{id:\"roster/14-chisel-spire--cone_head_3d_model\",label:\"Chisel \\xB7 Spire 1\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/14-chisel-spire--low_poly_robot_3d_model\",label:\"Chisel \\xB7 Spire 2\",group:\"Chisel \\xB7 Spire\"},{id:\"roster/15-orbital-coili--robot_character_3d_model\",label:\"Orbital \\xB7 Coili 1\",group:\"Orbital \\xB7 Coili\"},{id:\"roster/16-spade-arch--pyramid_head_figure_3d_model\",label:\"Spade \\xB7 Arch 1\",group:\"Spade \\xB7 Arch\"},{id:\"roster/16-spade-arch--stylized_humanoid_3d_model\",label:\"Spade \\xB7 Arch 2\",group:\"Spade \\xB7 Arch\"},{id:\"roster/17-shellcap-manyarm--3d_character_figurine\",label:\"Shellcap \\xB7 Manyarm 1\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",label:\"Shellcap \\xB7 Manyarm 2\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",label:\"Shellcap \\xB7 Manyarm 3\",group:\"Shellcap \\xB7 Manyarm\"},{id:\"roster/18-quad-all--dragon_creature_3d_model\",label:\"Four-legged 1\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model1\",label:\"Four-legged 2\",group:\"Four-legged\"},{id:\"roster/18-quad-all--fantasy_creature_3d_model3\",label:\"Four-legged 3\",group:\"Four-legged\"},{id:\"roster/18-quad-all--four-legged_robot_3d_model\",label:\"Four-legged 4\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model1\",label:\"Four-legged 5\",group:\"Four-legged\"},{id:\"roster/18-quad-all--quadruped_robot_3d_model\",label:\"Four-legged 6\",group:\"Four-legged\"},{id:\"roster/18-quad-all--robotic_dog_3d_model\",label:\"Four-legged 7\",group:\"Four-legged\"},{id:\"roster/18-quad-all--stylized_quadruped_3d_model\",label:\"Four-legged 8\",group:\"Four-legged\"},{id:\"roster/18-quad-all--wooden_four-legged_robot_3d_model\",label:\"Four-legged 9\",group:\"Four-legged\"},{id:\"roster/19-genie-multi--fantasy_creature_3d_model\",label:\"Genie \\xB7 Multi 1\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",label:\"Genie \\xB7 Multi 2\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",label:\"Genie \\xB7 Multi 3\",group:\"Genie \\xB7 Multi\"},{id:\"roster/19-genie-multi--stylized_octopus_3d_model\",label:\"Genie \\xB7 Multi 4\",group:\"Genie \\xB7 Multi\"},{id:\"roster/20-lume--robotic_figure_3d_model\",label:\"Lume 1\",group:\"Lume\"},{id:\"roster/22-curve--stylized_alien_3d_model\",label:\"Curve 1\",group:\"Curve\"},{id:\"roster/22-curve--stylized_cartoon_figure_3d_model\",label:\"Curve 2\",group:\"Curve\"},{id:\"roster/23-blob-texture-bodies--blob_creature_3d_model\",label:\"Blob 1\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--cute_blob_creature_3d_model\",label:\"Blob 2\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",label:\"Blob 3\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",label:\"Blob 4\",group:\"Blob\"},{id:\"roster/23-blob-texture-bodies--sand_creature_3d_model\",label:\"Blob 5\",group:\"Blob\"}],rr=tr.filter(e=>!v.includes(e.id)).map(e=>({...e,sourceLabel:e.label,label:G(e.id)})),Fa=rr;var ie=Object.freeze([\"clay\",\"martial-arts-canvas-gi\",\"arms-rope\",\"yoga-cork\",\"glutes-peach\"]),Ke=Object.freeze({\"legacy-0\":\"clay\",\"legacy-21\":\"opal-jelly\",\"bubble-glass\":\"glitter-resin\"}),j=Object.freeze([\"flat\",\"legacy-22\",...Object.keys(Ke)]),Ye=e=>Object.hasOwn(Ke,e)?Ke[e]:e,Aa=e=>{let a=Ye(e);return j.includes(a)?\"clay\":a},Ma=e=>e===22?0:e;var sr=Object.freeze([[\"open\",\"Curious\"],[\"sleepy\",\"Unimpressed\"],[\"wide\",\"Wide awake\"],[\"anime\",\"Anime\"],[\"squinty\",\"Squinty\"],[\"bloodshot\",\"Bloodshot\"],[\"blind\",\"Blind\"]]),La=Object.freeze(sr.map(([e])=>e));var we=[\"head\",\"eye\",\"collar\",\"body\",\"arms\",\"feet\"],Ia={body:\"body\",arms:\"body\",feet:\"body\",collar:\"body\",head:\"body\",eye:\"eye\"};var N=[{...$[0],name:\"Original MYR5\",primary:\"#7946aa\",secondary:\"#351344\",accent:\"#b373d4\",roughness:.62},...$.slice(1)],or=N.filter(e=>![8,11,22].includes(e.id)),Xe=[{id:\"myr5\",label:G(\"myr5\"),group:\"MYR5\"},...Fa],Ve=new Set([\"roster/01-seed-pearo--white_3d_character_model\",\"roster/01-seed-pearo--blank_humanoid_figure_3d_model\",\"roster/09-monolith-tanka--robot_3d_model2\",\"roster/18-quad-all--stylized_quadruped_3d_model\"]),cr=Xe.filter(e=>!Ve.has(e.id)),nr=[\"headFrom\",\"armsFrom\",\"feetFrom\"],Oa=e=>typeof e==\"string\"&&Xe.some(a=>a.id===e),ir=e=>!!e&&typeof e==\"object\"&&typeof e.textureId==\"string\"&&typeof e.colorId==\"string\"&&Number.isFinite(e.sparkle)&&e.sparkle>=0&&e.sparkle<=1&&Number.isFinite(e.metallic)&&e.metallic>=0&&e.metallic<=1,lr=e=>e===void 0||!!e&&typeof e==\"object\"&&!Array.isArray(e)&&Object.entries(e).every(([a,t])=>we.includes(a)&&ir(t)),_e=()=>({version:1,styles:{head:0,eye:0,collar:0,body:0,arms:0,feet:0},eye:\"open\",fur:1,iris:1,pupil:\"round\",pupilSize:1,detail:1,coach:\"supportive\",shipId:\"supportive\",shipColor:null,fingers:4,toes:3,eyeLayout:\"single\",body:\"myr5\",headFrom:\"myr5\",armsFrom:\"myr5\",feetFrom:\"myr5\"});function Je(e){let a=JSON.parse(e);a.pupil??=\"round\",a.pupilSize??=1,a.detail??=1,a.coach??=\"supportive\",a.shipId??=a.coach,a.shipColor??=null,a.fingers??=4,a.toes??=3,a.eyeLayout??=\"single\",Oa(a.body)||(a.body=\"myr5\");for(let r of nr)Oa(a[r])||(a[r]=a.body);let t={around:\"triangle\",frontBack:\"horizontal\"};if(t[a.eyeLayout]&&(a.eyeLayout=t[a.eyeLayout]),!Number.isInteger(a.fingers)||a.fingers<2||a.fingers>6||!Number.isInteger(a.toes)||a.toes<1||a.toes>6||!Object.hasOwn(He,a.eyeLayout)||a.version!==1||!a.styles||!we.every(r=>Number.isInteger(a.styles[r])&&a.styles[r]>=0&&a.styles[r]<N.length)||!La.includes(a.eye)||!Number.isFinite(a.fur)||a.fur<.65||a.fur>1.4||!Number.isFinite(a.iris)||a.iris<.7||a.iris>1.25||!We.some(r=>r[0]===a.pupil)||!Number.isFinite(a.pupilSize)||a.pupilSize<.6||a.pupilSize>1.15||!Number.isFinite(a.detail)||a.detail<.5||a.detail>1.5||!ke.some(r=>r.id===a.coach)||!ke.some(r=>r.id===a.shipId)||!(a.shipColor===null||/^#[0-9a-f]{6}$/i.test(a.shipColor))||!lr(a.materials))throw Error(\"Choose a valid MYR5 recipe.\");return{golden:typeof a.golden==\"boolean\"?a.golden:void 0,...a.blackSclera===!0?{blackSclera:!0}:{},...a.colourPupil===!0?{colourPupil:!0}:{},version:1,styles:Object.fromEntries(we.map(r=>[r,Ma(a.styles[r])])),eye:a.eye,fur:a.fur,iris:a.iris,pupil:a.pupil,pupilSize:a.pupilSize,detail:a.detail,coach:a.coach,shipId:a.shipId,shipColor:a.shipColor,fingers:a.fingers,toes:a.toes,eyeLayout:a.eyeLayout,body:a.body,headFrom:a.headFrom,armsFrom:a.armsFrom,feetFrom:a.feetFrom,materials:a.materials&&Object.fromEntries(Object.entries(a.materials).map(([r,s])=>[r,{...s,textureId:Aa(s.textureId),...r===\"head\"&&a.materials.body?{colorId:a.materials.body.colorId}:{}}]))}}var Qe=Object.freeze([{id:\"supportive\",name:\"Bubble shuttle\",description:\"A rounded cockpit with four bulbous engine pods around a compact hull.\"},{id:\"direct\",name:\"Wing fighter\",description:\"A pointed cockpit between broad swept wings and long engine rails.\"},{id:\"analytical\",name:\"Ring-engine scout\",description:\"A narrow cockpit and small fins ahead of a large circular rear engine.\"},{id:\"playful\",name:\"Fork interceptor\",description:\"A dark central cockpit between long forked nose rails, with two side engine pods.\"},{id:\"calm\",name:\"Capsule pod\",description:\"A short rounded capsule with a forward cockpit and a thick rear housing.\"},{id:\"mom\",name:\"Cargo carrier\",description:\"A broad blocky hull with a raised centre tower and two large front engine housings.\"}].map(e=>Object.freeze({...e,assetPath:`assets/ships/${e.id}.glb`}))),Ze=e=>Qe.find(a=>a.id===e)||Qe[0];var le=[{id:\"pal-01\",name:\"Acid Forge\",tagline:\"Lime bites oxblood and chrome\",colors:[\"#C6FF00\",\"#4A0E17\",\"#C0C7CE\"],unlockRule:\"aura-milestone\",unlockAtDay:5,finish:\"glitter\"},{id:\"pal-02\",name:\"Neon Afterburn Haze\",tagline:\"Orange aqua contrails with violet flare\",colors:[\"#FF6D00\",\"#00E0B0\",\"#C800FF\"],unlockRule:\"aura-milestone\",unlockAtDay:10,finish:\"brushed-metal\"},{id:\"pal-03\",name:\"Petrel Copper\",tagline:\"Petrol depths meet intense violet\",colors:[\"#0E5A61\",\"#B87333\",\"#6913E7\"],unlockRule:\"aura-milestone\",unlockAtDay:15,finish:\"polished-metal\"},{id:\"pal-04\",name:\"Vinaigrette Rust\",tagline:\"Oil pigment rust swirl\",colors:[\"#8A3B12\",\"#556B2F\",\"#E7A213\"],unlockRule:\"aura-milestone\",unlockAtDay:20,finish:\"marbled\"},{id:\"pal-05\",name:\"Neon Relic\",tagline:\"Hot magenta neon amber on bone\",colors:[\"#FF009F\",\"#FFB500\",\"#F2EFE6\"],unlockRule:\"aura-milestone\",unlockAtDay:25,finish:\"glitter\"},{id:\"pal-06\",name:\"Glacier Ember\",tagline:\"Ice teal over ember red\",colors:[\"#13E7D1\",\"#D9381E\",\"#2B2530\"],unlockRule:\"aura-milestone\",unlockAtDay:30,finish:\"pearl\"},{id:\"pal-07\",name:\"Chartreuse Storm\",tagline:\"Sludge green meets slate violet\",colors:[\"#B5C700\",\"#3D3654\",\"#E85D75\"],unlockRule:\"aura-milestone\",unlockAtDay:35,finish:\"matte\"},{id:\"pal-08\",name:\"Saffron Voltage\",tagline:\"Saffron arcs on ink blue\",colors:[\"#FFB000\",\"#101D42\",\"#00FAA6\"],unlockRule:\"aura-milestone\",unlockAtDay:40,finish:\"polished-metal\"},{id:\"pal-09\",name:\"Neon Venom Signal\",tagline:\"Poison lime warning under arterial red\",colors:[\"#A6FF00\",\"#FF2442\",\"#101828\"],unlockRule:\"aura-milestone\",unlockAtDay:45,finish:\"watercolor\"},{id:\"pal-10\",name:\"Mercury Moss\",tagline:\"Silver moss over saturated gold\",colors:[\"#AEB6BC\",\"#5C6B3C\",\"#E7A913\"],unlockRule:\"aura-milestone\",unlockAtDay:50,finish:\"brushed-metal\"},{id:\"pal-11\",name:\"Ultraviolet Tar\",tagline:\"Violet glow on tar black\",colors:[\"#7B2FF7\",\"#141414\",\"#FFC93C\"],unlockRule:\"aura-milestone\",unlockAtDay:55,finish:\"glaze\"},{id:\"pal-12\",name:\"Salmon Circuit\",tagline:\"Salmon pink on circuit green\",colors:[\"#FA2200\",\"#00A86B\",\"#2E2A5C\"],unlockRule:\"aura-milestone\",unlockAtDay:60,finish:\"pearl\"},{id:\"pal-13\",name:\"Muddy Pop\",tagline:\"Ochre mud sparks cerulean\",colors:[\"#8C6A2F\",\"#0081C8\",\"#E71362\"],unlockRule:\"battle-pass\",reward:\"strider-2:L1\",finish:\"matte\"},{id:\"pal-14\",name:\"Neon Vapor Crown\",tagline:\"Laser pink blue over dark purple\",colors:[\"#FF00AA\",\"#00D0FF\",\"#1B0033\"],unlockRule:\"battle-pass\",reward:\"strider-2:L3\",finish:\"watercolor\"},{id:\"pal-15\",name:\"Brick Vein\",tagline:\"Brick red veined in steel\",colors:[\"#A0342B\",\"#8C9BA5\",\"#D7E713\"],unlockRule:\"battle-pass\",reward:\"strider-2:L4\",finish:\"marbled\"},{id:\"pal-16\",name:\"Peacock Static\",tagline:\"Peacock green hums gold\",colors:[\"#046A5B\",\"#FAAF00\",\"#5B1E4B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L1\",finish:\"polished-metal\"},{id:\"pal-17\",name:\"Foghorn Flame\",tagline:\"Fog gray with fire-orange siren\",colors:[\"#B8C0C2\",\"#FA3F00\",\"#123C69\"],unlockRule:\"battle-pass\",reward:\"strider-3:L3\",finish:\"brushed-metal\"},{id:\"pal-18\",name:\"Toxic Honey\",tagline:\"Honey drips on toxic lime\",colors:[\"#D9A404\",\"#9BF00B\",\"#4A154B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L4\",finish:\"glaze\"},{id:\"pal-19\",name:\"Neon Crimson Mirage\",tagline:\"Scarlet toxic lime over deep jade\",colors:[\"#FF1744\",\"#76FF03\",\"#005E3C\"],unlockRule:\"battle-pass\",reward:\"strider-4:L1\",finish:\"matte\"},{id:\"pal-20\",name:\"Opal Drain\",tagline:\"Opal sheen on drainpipe green\",colors:[\"#13E7B9\",\"#3E5641\",\"#D1495B\"],unlockRule:\"battle-pass\",reward:\"strider-4:L3\",finish:\"pearl\"},{id:\"pal-21\",name:\"Rust Halo\",tagline:\"Rust ringed by mint flash\",colors:[\"#9C4221\",\"#12E898\",\"#2C2C54\"],unlockRule:\"battle-pass\",reward:\"strider-4:L4\",finish:\"brushed-metal\"},{id:\"pal-22\",name:\"Volt Quartz\",tagline:\"Electric yellow on rose quartz\",colors:[\"#F5E900\",\"#E71363\",\"#264653\"],unlockRule:\"battle-pass\",reward:\"strider-5:L1\",finish:\"glitter\"},{id:\"pal-23\",name:\"Neon Flare Garden\",tagline:\"Laser lime pink on teal steel\",colors:[\"#8CFF00\",\"#FF006E\",\"#00B8A9\"],unlockRule:\"battle-pass\",reward:\"strider-5:L3\",finish:\"matte\"},{id:\"pal-24\",name:\"Crimson Tidebreak\",tagline:\"Crimson breaks on seafoam\",colors:[\"#B91338\",\"#13E7B5\",\"#2A1E5C\"],unlockRule:\"battle-pass\",reward:\"strider-5:L4\",finish:\"watercolor\"},{id:\"pal-25\",name:\"Brass Mirage\",tagline:\"Brass shimmer dusky plum\",colors:[\"#C59B42\",\"#5A2A52\",\"#0D94ED\"],unlockRule:\"battle-pass\",reward:\"strider-6:L1\",finish:\"polished-metal\"},{id:\"pal-26\",name:\"Neon Infrared Bloom\",tagline:\"Red heat sliced by frozen cyan\",colors:[\"#FF0000\",\"#00F5FF\",\"#5B00B5\"],unlockRule:\"battle-pass\",reward:\"strider-6:L3\",finish:\"glaze\"},{id:\"pal-27\",name:\"Ice Magma\",tagline:\"Pigmented ice over magma orange\",colors:[\"#D6F0F0\",\"#F45B0F\",\"#3D2C8D\"],unlockRule:\"battle-pass\",reward:\"strider-6:L4\",finish:\"marbled\"},{id:\"pal-28\",name:\"Fern Radio\",tagline:\"Fern green static magenta\",colors:[\"#3F7A3A\",\"#E4007C\",\"#E7BE13\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L1\",finish:\"matte\"},{id:\"pal-29\",name:\"Porcelain Fuel\",tagline:\"Porcelain white fuel orange\",colors:[\"#F2F2F0\",\"#FF7A1A\",\"#14507A\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L3\",finish:\"glaze\"},{id:\"pal-30\",name:\"Neon Photon Alley\",tagline:\"Yellow signage aqua and violet glass\",colors:[\"#FFD300\",\"#00FFCC\",\"#7A00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L4\",finish:\"brushed-metal\"},{id:\"pal-31\",name:\"Neon Solar Flare\",tagline:\"Hot yellow ember in plum space\",colors:[\"#FFEA00\",\"#FF3D00\",\"#26142B\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L1\",finish:\"polished-metal\"},{id:\"pal-32\",name:\"Wet Cement Rose\",tagline:\"Cement gray wild rose\",colors:[\"#8D9096\",\"#D84A87\",\"#F0E130\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L3\",finish:\"matte\"},{id:\"pal-33\",name:\"Neon Laser Tropics\",tagline:\"Chartreuse beams with scorched orange shadows\",colors:[\"#C6FF00\",\"#FF4D00\",\"#001219\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L4\",finish:\"watercolor\"},{id:\"pal-34\",name:\"Copper Fog\",tagline:\"Copper glows through fog\",colors:[\"#B46A30\",\"#C4CBCE\",\"#B600F5\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L1\",finish:\"brushed-metal\"},{id:\"pal-35\",name:\"Laser Moss\",tagline:\"Laser cyan on moss\",colors:[\"#00E5FF\",\"#546B2F\",\"#FF4FA3\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L3\",finish:\"glitter\"},{id:\"pal-36\",name:\"Bone Ember\",tagline:\"Bone white ember orange\",colors:[\"#EDE8DC\",\"#E4572E\",\"#BA00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L4\",finish:\"matte\"},{id:\"pal-37\",name:\"Plum Static\",tagline:\"Plum noise with electric lime\",colors:[\"#4A1E4F\",\"#B8F000\",\"#33B5C7\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L1\",finish:\"glaze\"},{id:\"pal-38\",name:\"Neon Lime Vortex\",tagline:\"Acid green swirling through electric blue\",colors:[\"#BFFF00\",\"#00E5FF\",\"#12100F\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L3\",finish:\"pearl\"},{id:\"pal-39\",name:\"Clay Command\",tagline:\"Terracotta clay cobalt order\",colors:[\"#C06B55\",\"#2E4BC6\",\"#EDE6D6\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L4\",finish:\"marbled\"},{id:\"pal-40\",name:\"Static Cream\",tagline:\"Cream noise shock green\",colors:[\"#F4EDDE\",\"#39FF14\",\"#4A306D\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L1\",finish:\"glitter\"},{id:\"pal-41\",name:\"Midnight Papaya\",tagline:\"Midnight blue papaya burst\",colors:[\"#191970\",\"#FF9E42\",\"#13E796\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L3\",finish:\"polished-metal\"},{id:\"pal-42\",name:\"Dusty Laser\",tagline:\"Dusty mauve laser green\",colors:[\"#A27E8E\",\"#7CFC00\",\"#1B3B6F\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L4\",finish:\"matte\"},{id:\"pal-43\",name:\"Neon Atomic Sunset\",tagline:\"Amber fallout glowing beside ultraviolet pink\",colors:[\"#FF9100\",\"#FF00F5\",\"#062A2A\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L1\",finish:\"glaze\"},{id:\"pal-44\",name:\"Fern Flame\",tagline:\"Cool fern fierce flame\",colors:[\"#4F7942\",\"#FF3D2E\",\"#E75A13\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L3\",finish:\"brushed-metal\"},{id:\"pal-45\",name:\"Violet Quarry\",tagline:\"Quarry gray violet eruption\",colors:[\"#7D7F87\",\"#8B3DFF\",\"#DCE35B\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L4\",finish:\"matte\"},{id:\"pal-46\",name:\"Cadmium Deep\",tagline:\"Cadmium red deep lagoon\",colors:[\"#D32E12\",\"#046E8F\",\"#E79E13\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L1\",finish:\"polished-metal\"},{id:\"pal-47\",name:\"Pigment Riot\",tagline:\"Intense blue maroon and hot orange\",colors:[\"#139FE7\",\"#6E1423\",\"#FF7300\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L3\",finish:\"watercolor\"},{id:\"pal-48\",name:\"Neon Prism Riot\",tagline:\"Sea-glass cyan, magenta bite, lemon flash\",colors:[\"#00FFC6\",\"#FF00B8\",\"#F5FF00\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L4\",finish:\"pearl\"},{id:\"pal-49\",name:\"Neon Tropic Surge\",tagline:\"Aqua tide, citrus flare, violet thunder\",colors:[\"#00FF9D\",\"#FFB000\",\"#D000FF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L1\",finish:\"glitter\"},{id:\"pal-50\",name:\"Ash Honey\",tagline:\"Ash gray golden honey\",colors:[\"#9BA0A6\",\"#E0A100\",\"#2F6690\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L3\",finish:\"matte\"},{id:\"pal-51\",name:\"Cherry Motor\",tagline:\"Cherry motor oil with electric blue\",colors:[\"#B22234\",\"#3B2F2F\",\"#005CFF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L4\",finish:\"brushed-metal\"},{id:\"pal-52\",name:\"Glacier Punch\",tagline:\"Glacier pigmented hot punch\",colors:[\"#13A6E7\",\"#F52549\",\"#3D405B\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L1\",finish:\"glaze\"},{id:\"pal-53\",name:\"Tarnish Bloom\",tagline:\"Tarnished teal floral orange\",colors:[\"#3A7D7B\",\"#F4852B\",\"#E9D6EC\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L3\",finish:\"marbled\"},{id:\"pal-54\",name:\"Umber Signal\",tagline:\"Umber earth neon signal\",colors:[\"#635147\",\"#D0FF4B\",\"#7A28C0\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L4\",finish:\"matte\"},{id:\"pal-55\",name:\"Rose Quartz Coil\",tagline:\"Soft rose coil of teal\",colors:[\"#E7134B\",\"#0FA3A3\",\"#2B2118\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L1\",finish:\"pearl\"},{id:\"pal-56\",name:\"Sulfur Deck\",tagline:\"Sulfur yellow blue and hot orange\",colors:[\"#E3D200\",\"#274C77\",\"#FF4A00\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L3\",finish:\"polished-metal\"},{id:\"pal-57\",name:\"Neon Ember Static\",tagline:\"Orange yellow buzzing with royal voltage\",colors:[\"#FF5E00\",\"#FFE600\",\"#3A0CA3\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L4\",finish:\"watercolor\"},{id:\"pal-58\",name:\"Mango Ash\",tagline:\"Mango bright volcanic ash\",colors:[\"#FFA12B\",\"#59595E\",\"#64DDBB\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L1\",finish:\"matte\"},{id:\"pal-59\",name:\"Steel Petal\",tagline:\"Steel gray crushed petals\",colors:[\"#8A8F98\",\"#E71813\",\"#D8E26E\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L3\",finish:\"brushed-metal\"},{id:\"pal-60\",name:\"Ninja Cream\",tagline:\"Hidden navy cream coral\",colors:[\"#1E2A4A\",\"#F0EBE0\",\"#7EEC00\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L4\",finish:\"glaze\"},{id:\"pal-61\",name:\"Tangerine Static\",tagline:\"Tangerine buzz grape shadow\",colors:[\"#F28500\",\"#3D2159\",\"#202020\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L1\",finish:\"glitter\"},{id:\"pal-62\",name:\"Sage Pistol\",tagline:\"Muted sage pistol pink\",colors:[\"#9AB5A1\",\"#E45C98\",\"#33272A\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L3\",finish:\"matte\"},{id:\"pal-63\",name:\"Lagoon Battery\",tagline:\"Lagoon green charged yellow\",colors:[\"#1D8A7A\",\"#FAE000\",\"#76305B\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L4\",finish:\"polished-metal\"},{id:\"pal-64\",name:\"Wine Cooling\",tagline:\"Warm wine cooled by mint\",colors:[\"#701F3C\",\"#13E78C\",\"#E8D44D\"],unlockRule:\"battle-pass\",reward:\"warden-1:L1\",finish:\"pearl\"},{id:\"pal-65\",name:\"Charcoal Tulip\",tagline:\"Charcoal tulip flame combo\",colors:[\"#2E3033\",\"#FF4E50\",\"#CA00C7\"],unlockRule:\"battle-pass\",reward:\"warden-1:L3\",finish:\"matte\"},{id:\"pal-66\",name:\"Neon Acid Harbor\",tagline:\"Lime light cutting across magenta docks\",colors:[\"#39FF14\",\"#FF007F\",\"#001B2E\"],unlockRule:\"battle-pass\",reward:\"warden-1:L4\",finish:\"pearl\"},{id:\"pal-67\",name:\"Rustic Neon\",tagline:\"Barn red barn lime buzz\",colors:[\"#8A3324\",\"#C1FF33\",\"#2D4A6B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L1\",finish:\"marbled\"},{id:\"pal-68\",name:\"Alice Warning\",tagline:\"Alice blue caution orange\",colors:[\"#1399E7\",\"#FF7E1F\",\"#EEF700\"],unlockRule:\"battle-pass\",reward:\"blob-2:L3\",finish:\"watercolor\"},{id:\"pal-69\",name:\"Smog Candy\",tagline:\"Smog beige candy teal\",colors:[\"#E79813\",\"#00C2A8\",\"#D8395B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L4\",finish:\"matte\"},{id:\"pal-70\",name:\"Violet Furnace\",tagline:\"Furnace violet cooled sky\",colors:[\"#6A2D9E\",\"#F57C3B\",\"#302012\"],unlockRule:\"battle-pass\",reward:\"blob-3:L1\",finish:\"glaze\"},{id:\"pal-71\",name:\"Khaki Storm\",tagline:\"Khaki field storm magenta\",colors:[\"#A89B6E\",\"#E0218A\",\"#2A6F97\"],unlockRule:\"battle-pass\",reward:\"blob-3:L3\",finish:\"brushed-metal\"},{id:\"pal-72\",name:\"Neon Circuit Surge\",tagline:\"Turquoise sparks over midnight violet\",colors:[\"#00F5D4\",\"#F72585\",\"#0B0321\"],unlockRule:\"battle-pass\",reward:\"blob-3:L4\",finish:\"glitter\"},{id:\"pal-73\",name:\"Cedar Ultraviolet\",tagline:\"Cedar wood ultraviolet light\",colors:[\"#7A4532\",\"#8246FF\",\"#E9E4D8\"],unlockRule:\"battle-pass\",reward:\"blob-4:L1\",finish:\"matte\"},{id:\"pal-74\",name:\"Frosted Chili\",tagline:\"Frost blue chili red\",colors:[\"#13AAE7\",\"#C13A2F\",\"#4C5B2C\"],unlockRule:\"battle-pass\",reward:\"blob-4:L3\",finish:\"polished-metal\"},{id:\"pal-75\",name:\"Moss Rocket\",tagline:\"Moss green rocket pink\",colors:[\"#5B7042\",\"#FA0057\",\"#061F5B\"],unlockRule:\"battle-pass\",reward:\"blob-4:L4\",finish:\"matte\"},{id:\"pal-76\",name:\"Pewter Punch\",tagline:\"Pewter softened hot punch\",colors:[\"#99A0A8\",\"#FF3D7F\",\"#164D37\"],unlockRule:\"battle-pass\",reward:\"cap-2:L1\",finish:\"brushed-metal\"},{id:\"pal-77\",name:\"Neon Glacier Riot\",tagline:\"Cyan hot pink and radioactive lime\",colors:[\"#00F0FF\",\"#FF00E5\",\"#CCFF00\"],unlockRule:\"battle-pass\",reward:\"cap-2:L3\",finish:\"watercolor\"},{id:\"pal-78\",name:\"Cola Lightning\",tagline:\"Cola brown lightning yellow\",colors:[\"#3A2618\",\"#F7FF00\",\"#FA005E\"],unlockRule:\"battle-pass\",reward:\"cap-2:L4\",finish:\"glaze\"},{id:\"pal-79\",name:\"Periwinkle Fuel\",tagline:\"Soft periwinkle diesel orange\",colors:[\"#1325E7\",\"#E0641E\",\"#2F4730\"],unlockRule:\"battle-pass\",reward:\"cap-3:L1\",finish:\"matte\"},{id:\"pal-80\",name:\"Jade Alarm\",tagline:\"Jade calm siren red\",colors:[\"#57A78A\",\"#D91E36\",\"#E7AF13\"],unlockRule:\"battle-pass\",reward:\"cap-3:L3\",finish:\"pearl\"},{id:\"pal-81\",name:\"Neon Ultraviolet Pulse\",tagline:\"Violet beams with mint-charged current\",colors:[\"#8C00FF\",\"#00FFB2\",\"#160021\"],unlockRule:\"battle-pass\",reward:\"cap-3:L4\",finish:\"matte\"},{id:\"pal-82\",name:\"Neon Nightcaller\",tagline:\"Cyan violet flame in black-green fog\",colors:[\"#00FFFF\",\"#9400FF\",\"#131A00\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L1\",finish:\"marbled\"},{id:\"pal-83\",name:\"Ivory Shock\",tagline:\"Ivory calm violet shock\",colors:[\"#F0EEE4\",\"#7C1FD3\",\"#FFB200\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L3\",finish:\"glaze\"},{id:\"pal-84\",name:\"Neon Ruby Arc\",tagline:\"Red-hot signal over green afterglow\",colors:[\"#FF073A\",\"#00FF87\",\"#080F1B\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L4\",finish:\"glitter\"},{id:\"pal-85\",name:\"Maroon Cloud\",tagline:\"Maroon heavy cloud blue\",colors:[\"#6D1E2E\",\"#1381E7\",\"#E5D352\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L1\",finish:\"watercolor\"},{id:\"pal-86\",name:\"Chrome Berry\",tagline:\"Chrome band over berry\",colors:[\"#C3C9D1\",\"#8E2A5C\",\"#FFB347\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L3\",finish:\"polished-metal\"},{id:\"pal-87\",name:\"Lentil Neon\",tagline:\"Lentil tan electric aqua\",colors:[\"#B09A6E\",\"#00FFF0\",\"#5F1B63\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L4\",finish:\"matte\"},{id:\"pal-88\",name:\"Neon Cobalt Fuse\",tagline:\"Blue ignition wired to blazing yellow\",colors:[\"#004DFF\",\"#FFEE00\",\"#0D0221\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L1\",finish:\"glaze\"},{id:\"pal-89\",name:\"Spruce Bonfire\",tagline:\"Dark spruce bonfire orange\",colors:[\"#23493C\",\"#FF7A3D\",\"#0C1735\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L3\",finish:\"matte\"},{id:\"pal-90\",name:\"Lilac Foundry\",tagline:\"Lilac meets foundry steel\",colors:[\"#9813E7\",\"#7B8894\",\"#D4522A\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L4\",finish:\"brushed-metal\"},{id:\"pal-91\",name:\"Topaz Battle\",tagline:\"Topaz gold navy clash\",colors:[\"#F0B429\",\"#182952\",\"#FA007D\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L1\",finish:\"polished-metal\"},{id:\"pal-92\",name:\"Dusk Celery\",tagline:\"Dusky purple celery snap\",colors:[\"#574B6B\",\"#C8D86A\",\"#FA2100\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L3\",finish:\"matte\"},{id:\"pal-93\",name:\"Tide Copperfuse\",tagline:\"Tidal teal copperfuse glow\",colors:[\"#0F7B7B\",\"#C07840\",\"#C2F000\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L4\",finish:\"pearl\"},{id:\"pal-94\",name:\"Punch Driftwood\",tagline:\"Fruit punch on driftwood\",colors:[\"#E63362\",\"#6E5B4A\",\"#1648EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L1\",finish:\"watercolor\"},{id:\"pal-95\",name:\"Ink Lime\",tagline:\"Ink smudge streaked lime\",colors:[\"#23232A\",\"#A8E10C\",\"#7E10EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L3\",finish:\"glaze\"},{id:\"pal-96\",name:\"Porcelain Prism\",tagline:\"Porcelain violet over tidal blue\",colors:[\"#F5F1E8\",\"#BD05DA\",\"#005F73\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L4\",finish:\"marbled\"},{id:\"pal-97\",name:\"Wasabi Cloud\",tagline:\"Wasabi heat cloud gray\",colors:[\"#9FBF3B\",\"#8E94A0\",\"#E71363\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L1\",finish:\"matte\"},{id:\"pal-98\",name:\"Eggplant Flare\",tagline:\"Eggplant deep flare yellow\",colors:[\"#41284E\",\"#FFD23F\",\"#5BC0BE\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L3\",finish:\"glitter\"},{id:\"pal-99\",name:\"Stone Rose\",tagline:\"Stone gray antique rose\",colors:[\"#8F8A82\",\"#C46E8E\",\"#2F6DA3\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L4\",finish:\"brushed-metal\"},{id:\"pal-100\",name:\"Neon Quasar Pop\",tagline:\"Yellow green comet over indigo gravity\",colors:[\"#FFEF00\",\"#00FF3C\",\"#2D02B8\"],unlockRule:\"battle-pass\",reward:\"lume-1:L1\",finish:\"glaze\"},{id:\"pal-101\",name:\"Arctic Rust\",tagline:\"Arctic white rusted orange\",colors:[\"#E9F2F5\",\"#9E4A1D\",\"#3E3F8F\"],unlockRule:\"battle-pass\",reward:\"lume-1:L3\",finish:\"brushed-metal\"},{id:\"pal-102\",name:\"Magenta Selvage\",tagline:\"Magenta edge denim blue\",colors:[\"#D8117E\",\"#3B5B8C\",\"#E7D313\"],unlockRule:\"battle-pass\",reward:\"lume-1:L4\",finish:\"matte\"},{id:\"pal-103\",name:\"Haze Saffron\",tagline:\"Purple haze saffron spark\",colors:[\"#8467B8\",\"#F4A81D\",\"#1D4E50\"],unlockRule:\"battle-pass\",reward:\"food:L1\",finish:\"pearl\"},{id:\"pal-104\",name:\"Neon Cyber Reed\",tagline:\"Green circuitry humming beside lemon static\",colors:[\"#00FF66\",\"#FFEA00\",\"#4B0082\"],unlockRule:\"battle-pass\",reward:\"food:L2\",finish:\"glitter\"},{id:\"pal-105\",name:\"Neon Magma Bloom\",tagline:\"Molten orange meeting synthetic magenta\",colors:[\"#FF2E00\",\"#F000FF\",\"#0A0A0F\"],unlockRule:\"battle-pass\",reward:\"food:L3\",finish:\"polished-metal\"},{id:\"pal-106\",name:\"Dune Violet\",tagline:\"Warm dune electric violet\",colors:[\"#C9AE7E\",\"#7D2BF0\",\"#13E7E3\"],unlockRule:\"battle-pass\",reward:\"food:L4\",finish:\"marbled\"},{id:\"pal-107\",name:\"Ember Nightshade\",tagline:\"Violet shadows ember teal\",colors:[\"#523090\",\"#EF4E23\",\"#0C5D68\"],unlockRule:\"battle-pass\",reward:\"food:L5\",finish:\"watercolor\"},{id:\"opal-jelly\",name:\"Opal Jelly\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b3fff0\",\"#9767ff\",\"#fff1ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"bubble-glass\",name:\"Bubble Glass\",tagline:\"Shifting highlights and luminous color\",colors:[\"#58eaff\",\"#b8fff8\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"prism-crystal\",name:\"Prism Crystal\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b18aff\",\"#447bff\",\"#fff2ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"holo-foil\",name:\"Holographic Foil\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff54de\",\"#39e5ff\",\"#fff56b\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"glitter-resin\",name:\"Glitter Resin\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff319c\",\"#7025ff\",\"#fff6db\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"galaxy-geode\",name:\"Galaxy Geode\",tagline:\"Shifting highlights and luminous color\",colors:[\"#21134e\",\"#7b39e8\",\"#63ffff\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"caustic-slime\",name:\"Caustic Slime\",tagline:\"Organic horror surface\",colors:[\"#8aa52b\",\"#20300b\",\"#dcff57\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"blister-hide\",name:\"Blister Hide\",tagline:\"Organic horror surface\",colors:[\"#9e435f\",\"#2d1727\",\"#e7bb72\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"rotten-rind\",name:\"Rotten Rind\",tagline:\"Organic horror surface\",colors:[\"#626124\",\"#211916\",\"#a2b16b\"],unlockRule:\"battle-pass\",finish:\"matte\"},{id:\"parasite-nest\",name:\"Parasite Nest\",tagline:\"Organic horror surface\",colors:[\"#786541\",\"#151c14\",\"#ece2b0\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"exposed-sinew\",name:\"Exposed Sinew\",tagline:\"Organic horror surface\",colors:[\"#b72945\",\"#300b24\",\"#efb5a1\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"abyssal-maw\",name:\"Abyssal Maw\",tagline:\"Organic horror surface\",colors:[\"#522045\",\"#100d19\",\"#d9e6a7\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"circuit-alloy\",name:\"Circuit Alloy\",tagline:\"Machine surface\",colors:[\"#273f50\",\"#0a111c\",\"#4effdc\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"servo-armor\",name:\"Servo Armor\",tagline:\"Machine surface\",colors:[\"#617080\",\"#141b25\",\"#ff6739\"],unlockRule:\"battle-pass\",finish:\"brushed-metal\"},{id:\"chrome-rib\",name:\"Chrome Rib\",tagline:\"Machine surface\",colors:[\"#bfcde1\",\"#202f46\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"carbon-mech\",name:\"Carbon Mech\",tagline:\"Machine surface\",colors:[\"#323d46\",\"#080d15\",\"#95bac9\"],unlockRule:\"battle-pass\"},{id:\"hazard-panel\",name:\"Hazard Panel\",tagline:\"Machine surface\",colors:[\"#edb932\",\"#131a20\",\"#ffe9a2\"],unlockRule:\"battle-pass\"},{id:\"reactor-glass\",name:\"Reactor Glass\",tagline:\"Machine surface\",colors:[\"#48e8ff\",\"#063a55\",\"#d4ffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"}];var Ta={schemaVersion:1,additive:!0,colorSpace:{basecolor:\"srgb\",tintMask:\"srgb\",normal:\"linear\",roughness:\"linear\",height:\"linear\",ao:\"linear\",metalness:\"linear\",opacity:\"linear\",emissive:\"srgb\"},normalConvention:\"OpenGL +Y\",tinting:\"tint-mask multiplied by selected creature palette\",collections:[{id:\"creature-forged-realms\",packetId:\"coach-creature-forged-realms-v1\",displayName:\"Coach Creature Skins \\u2014 Forged Realms\",description:\"Additional fantasy\\u2013science-fiction creature skin unlocks for the Coach app. Separate from the original fitness-material battle-pass set.\",runtimeNotes:{normalConvention:\"OpenGL (+Y)\",tinting:\"Use tint-mask.webp as a neutral grayscale base multiplied by the creature palette.\",recommendedColorSpace:{basecolor:\"sRGB\",tintMask:\"sRGB\",normal:\"linear\",roughness:\"linear\",height:\"linear\",ao:\"linear\",metalness:\"linear\",opacity:\"linear\",emissive:\"sRGB\"}}},{id:\"creature-celestial-rift\",packetId:\"coach-creature-celestial-rift-v1\",displayName:\"Coach Creature Skins \\u2014 Celestial Rift\",description:\"A second non-overlapping set of fantasy\\u2013science-fiction creature skin unlocks for the Coach app. Additive to Forged Realms and the original fitness-material set.\",runtimeNotes:{normalConvention:\"OpenGL (+Y)\",tinting:\"Use tint-mask.webp as a neutral grayscale base multiplied by the creature palette.\",recommendedColorSpace:{basecolor:\"sRGB\",tintMask:\"sRGB\",normal:\"linear\",roughness:\"linear\",height:\"linear\",ao:\"linear\",metalness:\"linear\",opacity:\"linear\",emissive:\"sRGB\"}}}],skins:[{id:\"creature-starforged-plate\",displayName:\"Starforged Plate\",track:\"chest\",realm:\"sci-fi\",rarity:\"rare\",sourceAssetId:\"Metal009\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Metal009\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-starforged-plate/basecolor.webp\",bytes:8170,sha256:\"c4c112d6a9ef20989d9cc048ec1bd4680e25df03fa9a99e4d124b0058ffe66e9\"},normal:{file:\"textures/creature-starforged-plate/normal.webp\",bytes:878,sha256:\"a69782b9e6c01a41c9bde8e47c4f67490bf97869cf4fa332454e1d371ce0e1af\"},roughness:{file:\"textures/creature-starforged-plate/roughness.webp\",bytes:16326,sha256:\"eb8bf7a214631382971d470f7566e664167f395d27a51428c02edb7e9065ad39\"},height:{file:\"textures/creature-starforged-plate/height.webp\",bytes:37602,sha256:\"520bb285c4862740f48d076d49320b74f196bd7463e4dd0c338a0bcb181a103e\"},metalness:{file:\"textures/creature-starforged-plate/metalness.webp\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{file:\"textures/creature-starforged-plate/tint-mask.webp\",bytes:47604,sha256:\"4faadbe93f4126eac9cfba939acd1db3c3d4b5ff7a954ca33ae72ee128555b6c\"},preview:{file:\"textures/creature-starforged-plate/preview.webp\",bytes:9336,sha256:\"0493936cdccec9486471163fb6b3a2fdc7195fc9535653cb714ed32fd5e32d15\"}},runtime:{unlock:{level:1,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-starforged-plate/basecolor\",bytes:8170,sha256:\"c4c112d6a9ef20989d9cc048ec1bd4680e25df03fa9a99e4d124b0058ffe66e9\"},normal:{entry:\"creature-starforged-plate/normal\",bytes:878,sha256:\"a69782b9e6c01a41c9bde8e47c4f67490bf97869cf4fa332454e1d371ce0e1af\"},roughness:{entry:\"creature-starforged-plate/roughness\",bytes:16326,sha256:\"eb8bf7a214631382971d470f7566e664167f395d27a51428c02edb7e9065ad39\"},height:{entry:\"creature-starforged-plate/height\",bytes:37602,sha256:\"520bb285c4862740f48d076d49320b74f196bd7463e4dd0c338a0bcb181a103e\"},metalness:{entry:\"creature-starforged-plate/metalness\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{entry:\"creature-starforged-plate/tintMask\",bytes:47604,sha256:\"4faadbe93f4126eac9cfba939acd1db3c3d4b5ff7a954ca33ae72ee128555b6c\"},preview:{entry:\"creature-starforged-plate/preview\",bytes:9336,sha256:\"0493936cdccec9486471163fb6b3a2fdc7195fc9535653cb714ed32fd5e32d15\"}}}},{id:\"creature-obsidian-carapace\",displayName:\"Obsidian Carapace\",track:\"chest\",realm:\"hybrid\",rarity:\"epic\",sourceAssetId:\"Onyx013\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Onyx013\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-obsidian-carapace/basecolor.webp\",bytes:50752,sha256:\"1bf15ad9d98a4c5dfdc03623a52b62995659ca592d832652f17cc26e873d093c\"},normal:{file:\"textures/creature-obsidian-carapace/normal.webp\",bytes:596,sha256:\"72e8331843ae2e2d4018ef40d888cbc1ddeb7d46786874eea50ca36837b3b1a7\"},roughness:{file:\"textures/creature-obsidian-carapace/roughness.webp\",bytes:1382,sha256:\"a66f044c77d913409a96ef8eaf4a0e59df22ac3bec63b89a3484259269aa33cc\"},height:{file:\"textures/creature-obsidian-carapace/height.webp\",bytes:2988,sha256:\"760380dff035f707b917266f6bbf72ffe671fde8394b243652398b543dd71046\"},tintMask:{file:\"textures/creature-obsidian-carapace/tint-mask.webp\",bytes:65032,sha256:\"c50038331782d6ddd1dcfac8df9158043eb5efd085a0fe56e1074d55123a10c5\"},preview:{file:\"textures/creature-obsidian-carapace/preview.webp\",bytes:58128,sha256:\"eb650060773ef1a11f0f8dcaf310735f709ba3e05d2d3158148524113c7013e9\"}},runtime:{unlock:{level:3,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-obsidian-carapace/basecolor\",bytes:50752,sha256:\"1bf15ad9d98a4c5dfdc03623a52b62995659ca592d832652f17cc26e873d093c\"},normal:{entry:\"creature-obsidian-carapace/normal\",bytes:596,sha256:\"72e8331843ae2e2d4018ef40d888cbc1ddeb7d46786874eea50ca36837b3b1a7\"},roughness:{entry:\"creature-obsidian-carapace/roughness\",bytes:1382,sha256:\"a66f044c77d913409a96ef8eaf4a0e59df22ac3bec63b89a3484259269aa33cc\"},height:{entry:\"creature-obsidian-carapace/height\",bytes:2988,sha256:\"760380dff035f707b917266f6bbf72ffe671fde8394b243652398b543dd71046\"},tintMask:{entry:\"creature-obsidian-carapace/tintMask\",bytes:65032,sha256:\"c50038331782d6ddd1dcfac8df9158043eb5efd085a0fe56e1074d55123a10c5\"},preview:{entry:\"creature-obsidian-carapace/preview\",bytes:58128,sha256:\"eb650060773ef1a11f0f8dcaf310735f709ba3e05d2d3158148524113c7013e9\"}}}},{id:\"creature-hive-armor\",displayName:\"Hive Armor\",track:\"chest\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"MetalPlates013\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/MetalPlates013\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-hive-armor/basecolor.webp\",bytes:24764,sha256:\"a98dcfd52d19fc449d94a1a151f8281f1eda86ad6c7d0bce7719dddc1e50e34f\"},normal:{file:\"textures/creature-hive-armor/normal.webp\",bytes:14104,sha256:\"50f6713c0ed2ec0b1c5b4ba589011499e92d4645550b79ec6a41b6727b8bd521\"},roughness:{file:\"textures/creature-hive-armor/roughness.webp\",bytes:44122,sha256:\"083f43ab705595a824e70ec97f4afc0670bca3e929b180cb374212a25715c18a\"},height:{file:\"textures/creature-hive-armor/height.webp\",bytes:9344,sha256:\"fb5d1b4c2c1732a3e5f42fb6e16a6a5b3ad24955069a5adbe3908f3619ea6b82\"},ao:{file:\"textures/creature-hive-armor/ao.webp\",bytes:5394,sha256:\"7c97ef834a1bc65cc2a61419a1d6730dca231c912edf0572f06ecfe3157250ab\"},metalness:{file:\"textures/creature-hive-armor/metalness.webp\",bytes:38740,sha256:\"62aa9640f463a8866fdd53a961041ff6d6b8c14415b31f241d85658544a2c5aa\"},tintMask:{file:\"textures/creature-hive-armor/tint-mask.webp\",bytes:61850,sha256:\"d2e7066bad7574d1b694d8186212ce56dcc4757033b061f6b6e3b08251c5046c\"},preview:{file:\"textures/creature-hive-armor/preview.webp\",bytes:30780,sha256:\"a7c7bb3c7d17804bd44ce5d54e57681f2036b9758e1d3ac34dc2b238a7aab250\"}},runtime:{unlock:{level:5,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-hive-armor/basecolor\",bytes:24764,sha256:\"a98dcfd52d19fc449d94a1a151f8281f1eda86ad6c7d0bce7719dddc1e50e34f\"},normal:{entry:\"creature-hive-armor/normal\",bytes:14104,sha256:\"50f6713c0ed2ec0b1c5b4ba589011499e92d4645550b79ec6a41b6727b8bd521\"},roughness:{entry:\"creature-hive-armor/roughness\",bytes:44122,sha256:\"083f43ab705595a824e70ec97f4afc0670bca3e929b180cb374212a25715c18a\"},height:{entry:\"creature-hive-armor/height\",bytes:9344,sha256:\"fb5d1b4c2c1732a3e5f42fb6e16a6a5b3ad24955069a5adbe3908f3619ea6b82\"},ao:{entry:\"creature-hive-armor/ao\",bytes:5394,sha256:\"7c97ef834a1bc65cc2a61419a1d6730dca231c912edf0572f06ecfe3157250ab\"},metalness:{entry:\"creature-hive-armor/metalness\",bytes:38740,sha256:\"62aa9640f463a8866fdd53a961041ff6d6b8c14415b31f241d85658544a2c5aa\"},tintMask:{entry:\"creature-hive-armor/tintMask\",bytes:61850,sha256:\"d2e7066bad7574d1b694d8186212ce56dcc4757033b061f6b6e3b08251c5046c\"},preview:{entry:\"creature-hive-armor/preview\",bytes:30780,sha256:\"a7c7bb3c7d17804bd44ce5d54e57681f2036b9758e1d3ac34dc2b238a7aab250\"}}}},{id:\"creature-magma-scale\",displayName:\"Magma Scale\",track:\"quads\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Lava004\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Lava004\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-magma-scale/basecolor.webp\",bytes:34804,sha256:\"e57fb5ed1a1449ba5a46535e62b14c73781e4e768d837ea5d80e241995ab3fb7\"},normal:{file:\"textures/creature-magma-scale/normal.webp\",bytes:55692,sha256:\"873ead60d1c158910ffee486bc6a55ee4cb4ad1d73cea2f351a9d095a1798ef9\"},roughness:{file:\"textures/creature-magma-scale/roughness.webp\",bytes:22680,sha256:\"f4eab6ab6dac73119e8e36c4f880115fc6e3a65252084a7412a811066110c103\"},height:{file:\"textures/creature-magma-scale/height.webp\",bytes:12946,sha256:\"8ddb62676ce447fb46030d7e65d9a6290ae993126dac3dc57b8faecd7dc7f662\"},emissive:{file:\"textures/creature-magma-scale/emissive.webp\",bytes:41142,sha256:\"3c0b9641bd6fe9465085ee4ce1f7657fa6fe5dd80f49c667498bdb96c7b4b5c8\"},tintMask:{file:\"textures/creature-magma-scale/tint-mask.webp\",bytes:41404,sha256:\"2248005bce453ca3c2f57f4a460b7a561a697537d6e921766d3b45d156211cb3\"},preview:{file:\"textures/creature-magma-scale/preview.webp\",bytes:38666,sha256:\"411d36c7435a414cb7e304b9099e0db9f35f95e24fc1f281a380020b51ddf180\"}},runtime:{unlock:{level:1,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-magma-scale/basecolor\",bytes:34804,sha256:\"e57fb5ed1a1449ba5a46535e62b14c73781e4e768d837ea5d80e241995ab3fb7\"},normal:{entry:\"creature-magma-scale/normal\",bytes:55692,sha256:\"873ead60d1c158910ffee486bc6a55ee4cb4ad1d73cea2f351a9d095a1798ef9\"},roughness:{entry:\"creature-magma-scale/roughness\",bytes:22680,sha256:\"f4eab6ab6dac73119e8e36c4f880115fc6e3a65252084a7412a811066110c103\"},height:{entry:\"creature-magma-scale/height\",bytes:12946,sha256:\"8ddb62676ce447fb46030d7e65d9a6290ae993126dac3dc57b8faecd7dc7f662\"},emissive:{entry:\"creature-magma-scale/emissive\",bytes:41142,sha256:\"3c0b9641bd6fe9465085ee4ce1f7657fa6fe5dd80f49c667498bdb96c7b4b5c8\"},tintMask:{entry:\"creature-magma-scale/tintMask\",bytes:41404,sha256:\"2248005bce453ca3c2f57f4a460b7a561a697537d6e921766d3b45d156211cb3\"},preview:{entry:\"creature-magma-scale/preview\",bytes:38666,sha256:\"411d36c7435a414cb7e304b9099e0db9f35f95e24fc1f281a380020b51ddf180\"}}}},{id:\"creature-frost-veins\",displayName:\"Frost Veins\",track:\"quads\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Ice003\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Ice003\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-frost-veins/basecolor.webp\",bytes:22338,sha256:\"7d21627868aba7ad76ba80359897464cee48faef462a06974e24c823a19d06b4\"},normal:{file:\"textures/creature-frost-veins/normal.webp\",bytes:4622,sha256:\"95179159bbe6d580b6e3e12de417064e65fe8fb287dbab1756a0ff47dfe337c0\"},roughness:{file:\"textures/creature-frost-veins/roughness.webp\",bytes:13946,sha256:\"dfbbd3f6e4293432dbd9c2d1cdd6904d3523223507c9a0f8d781c1f0fd2d9c25\"},height:{file:\"textures/creature-frost-veins/height.webp\",bytes:12916,sha256:\"ef9943193c04a33123c42d3af2d4a3a2fc06b0d2ac46c8fd12d4b17b745d1359\"},tintMask:{file:\"textures/creature-frost-veins/tint-mask.webp\",bytes:26114,sha256:\"8c9a1385824ab96b15c42f0afccf237a40507b427af4bc6b827e50b984cf2097\"},preview:{file:\"textures/creature-frost-veins/preview.webp\",bytes:26196,sha256:\"7462a4fb4044ae6e6521d79829b7dac42766c3e87f4092567829d7e0f93bb951\"}},runtime:{unlock:{level:3,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-frost-veins/basecolor\",bytes:22338,sha256:\"7d21627868aba7ad76ba80359897464cee48faef462a06974e24c823a19d06b4\"},normal:{entry:\"creature-frost-veins/normal\",bytes:4622,sha256:\"95179159bbe6d580b6e3e12de417064e65fe8fb287dbab1756a0ff47dfe337c0\"},roughness:{entry:\"creature-frost-veins/roughness\",bytes:13946,sha256:\"dfbbd3f6e4293432dbd9c2d1cdd6904d3523223507c9a0f8d781c1f0fd2d9c25\"},height:{entry:\"creature-frost-veins/height\",bytes:12916,sha256:\"ef9943193c04a33123c42d3af2d4a3a2fc06b0d2ac46c8fd12d4b17b745d1359\"},tintMask:{entry:\"creature-frost-veins/tintMask\",bytes:26114,sha256:\"8c9a1385824ab96b15c42f0afccf237a40507b427af4bc6b827e50b984cf2097\"},preview:{entry:\"creature-frost-veins/preview\",bytes:26196,sha256:\"7462a4fb4044ae6e6521d79829b7dac42766c3e87f4092567829d7e0f93bb951\"}}}},{id:\"creature-storm-carbon\",displayName:\"Storm Carbon\",track:\"quads\",realm:\"sci-fi\",rarity:\"legendary\",sourceAssetId:\"Fabric004\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Fabric004\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-storm-carbon/basecolor.webp\",bytes:4186,sha256:\"2f8c8777cc5df50ebb81c63fd5e09f3a4ec572b19b47e6c1f04fd7d5c4641b27\"},normal:{file:\"textures/creature-storm-carbon/normal.webp\",bytes:21570,sha256:\"0364397ee006f2e0cfd26a8b05fc43f3604acef539de8e53d85aaa679eae80d5\"},roughness:{file:\"textures/creature-storm-carbon/roughness.webp\",bytes:13466,sha256:\"cbd3523dfa84268974de80205d042b4339b9bea70ebe19c3b5827f3f500484b0\"},height:{file:\"textures/creature-storm-carbon/height.webp\",bytes:10398,sha256:\"46d6212cbedabf6bc51bcc61c7d03bb1711f574fbcb70c47cfbef46c9521dffb\"},metalness:{file:\"textures/creature-storm-carbon/metalness.webp\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{file:\"textures/creature-storm-carbon/tint-mask.webp\",bytes:11298,sha256:\"3e5019a042c69df2b895973c0678b05b0ae9d6d8c1673ca5fde515d19e37b318\"},preview:{file:\"textures/creature-storm-carbon/preview.webp\",bytes:4638,sha256:\"813c9f6903f3fe0f9c7a4306a319e33e6b255237722607f5ca96d067bb59be4c\"}},runtime:{unlock:{level:5,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-storm-carbon/basecolor\",bytes:4186,sha256:\"2f8c8777cc5df50ebb81c63fd5e09f3a4ec572b19b47e6c1f04fd7d5c4641b27\"},normal:{entry:\"creature-storm-carbon/normal\",bytes:21570,sha256:\"0364397ee006f2e0cfd26a8b05fc43f3604acef539de8e53d85aaa679eae80d5\"},roughness:{entry:\"creature-storm-carbon/roughness\",bytes:13466,sha256:\"cbd3523dfa84268974de80205d042b4339b9bea70ebe19c3b5827f3f500484b0\"},height:{entry:\"creature-storm-carbon/height\",bytes:10398,sha256:\"46d6212cbedabf6bc51bcc61c7d03bb1711f574fbcb70c47cfbef46c9521dffb\"},metalness:{entry:\"creature-storm-carbon/metalness\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{entry:\"creature-storm-carbon/tintMask\",bytes:11298,sha256:\"3e5019a042c69df2b895973c0678b05b0ae9d6d8c1673ca5fde515d19e37b318\"},preview:{entry:\"creature-storm-carbon/preview\",bytes:4638,sha256:\"813c9f6903f3fe0f9c7a4306a319e33e6b255237722607f5ca96d067bb59be4c\"}}}},{id:\"creature-ancient-bark\",displayName:\"Ancient Bark\",track:\"glutes\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Bark015\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Bark015\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-ancient-bark/basecolor.webp\",bytes:76532,sha256:\"4f104cc845070e5952eef5428e55cf37871a53b920539509d127484ef56fc492\"},normal:{file:\"textures/creature-ancient-bark/normal.webp\",bytes:81960,sha256:\"6805d1f6c82e7aeadfbbee3fe039c35773d49f26b527266ac0b8122c65e55f7c\"},roughness:{file:\"textures/creature-ancient-bark/roughness.webp\",bytes:30736,sha256:\"4fc3cf417cb8c3621f49bb36eb8c0e1f41ac501d2bdab16e768dc8eebccc617b\"},height:{file:\"textures/creature-ancient-bark/height.webp\",bytes:12470,sha256:\"8364e839245b1a832ae8f2195ff212f4fb0e4d6bd8b58909b90389e261eea9b5\"},ao:{file:\"textures/creature-ancient-bark/ao.webp\",bytes:62736,sha256:\"1490dc238669befa434ed5bd28336b865c8869a75b9db742272e60541ae99b68\"},tintMask:{file:\"textures/creature-ancient-bark/tint-mask.webp\",bytes:84688,sha256:\"b1a08d54081eb2e811acf490187e2be77186e366d82ddd18f68c6ef240ddf1ed\"},preview:{file:\"textures/creature-ancient-bark/preview.webp\",bytes:85306,sha256:\"95d00c586199990218c99d2366252ed877877885be164ce7e3186421cb339ea1\"}},runtime:{unlock:{level:1,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-ancient-bark/basecolor\",bytes:76532,sha256:\"4f104cc845070e5952eef5428e55cf37871a53b920539509d127484ef56fc492\"},normal:{entry:\"creature-ancient-bark/normal\",bytes:81960,sha256:\"6805d1f6c82e7aeadfbbee3fe039c35773d49f26b527266ac0b8122c65e55f7c\"},roughness:{entry:\"creature-ancient-bark/roughness\",bytes:30736,sha256:\"4fc3cf417cb8c3621f49bb36eb8c0e1f41ac501d2bdab16e768dc8eebccc617b\"},height:{entry:\"creature-ancient-bark/height\",bytes:12470,sha256:\"8364e839245b1a832ae8f2195ff212f4fb0e4d6bd8b58909b90389e261eea9b5\"},ao:{entry:\"creature-ancient-bark/ao\",bytes:62736,sha256:\"1490dc238669befa434ed5bd28336b865c8869a75b9db742272e60541ae99b68\"},tintMask:{entry:\"creature-ancient-bark/tintMask\",bytes:84688,sha256:\"b1a08d54081eb2e811acf490187e2be77186e366d82ddd18f68c6ef240ddf1ed\"},preview:{entry:\"creature-ancient-bark/preview\",bytes:85306,sha256:\"95d00c586199990218c99d2366252ed877877885be164ce7e3186421cb339ea1\"}}}},{id:\"creature-mossback\",displayName:\"Mossback\",track:\"glutes\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Bark013\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Bark013\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-mossback/basecolor.webp\",bytes:62984,sha256:\"1dbaed4381988af8d7145a14a15163047e8bd1ecbd0222101ba8f66c4109b88a\"},normal:{file:\"textures/creature-mossback/normal.webp\",bytes:74686,sha256:\"d8c6fdbf999eae4f19b5f6e62acfcadbb0ba8d61d98302898438c307083f1ddb\"},roughness:{file:\"textures/creature-mossback/roughness.webp\",bytes:42160,sha256:\"daa3d7d0555e81d07ff13fbb1f481d805a79ae991712b1dde396ad8a43bf4190\"},height:{file:\"textures/creature-mossback/height.webp\",bytes:23126,sha256:\"1977403ce1a9ad3b3606d20ec8d367df41647947291a8a6baef85f6d64933b3a\"},ao:{file:\"textures/creature-mossback/ao.webp\",bytes:44736,sha256:\"3b536128f80b296e091ea080d2fb8ac53ca06ea2c44d21b34168333f4410e22f\"},tintMask:{file:\"textures/creature-mossback/tint-mask.webp\",bytes:71276,sha256:\"58497e16f8e9e8986f08381ba4482586d0d1e5b5714d4f17b058d93de724fc17\"},preview:{file:\"textures/creature-mossback/preview.webp\",bytes:71140,sha256:\"478378a5c04eea0df87ba8d939215f04475914d38b3dba3a75fdcf99cf7f5985\"}},runtime:{unlock:{level:3,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-mossback/basecolor\",bytes:62984,sha256:\"1dbaed4381988af8d7145a14a15163047e8bd1ecbd0222101ba8f66c4109b88a\"},normal:{entry:\"creature-mossback/normal\",bytes:74686,sha256:\"d8c6fdbf999eae4f19b5f6e62acfcadbb0ba8d61d98302898438c307083f1ddb\"},roughness:{entry:\"creature-mossback/roughness\",bytes:42160,sha256:\"daa3d7d0555e81d07ff13fbb1f481d805a79ae991712b1dde396ad8a43bf4190\"},height:{entry:\"creature-mossback/height\",bytes:23126,sha256:\"1977403ce1a9ad3b3606d20ec8d367df41647947291a8a6baef85f6d64933b3a\"},ao:{entry:\"creature-mossback/ao\",bytes:44736,sha256:\"3b536128f80b296e091ea080d2fb8ac53ca06ea2c44d21b34168333f4410e22f\"},tintMask:{entry:\"creature-mossback/tintMask\",bytes:71276,sha256:\"58497e16f8e9e8986f08381ba4482586d0d1e5b5714d4f17b058d93de724fc17\"},preview:{entry:\"creature-mossback/preview\",bytes:71140,sha256:\"478378a5c04eea0df87ba8d939215f04475914d38b3dba3a75fdcf99cf7f5985\"}}}},{id:\"creature-rootbound\",displayName:\"Rootbound Hide\",track:\"glutes\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"Ground076\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Ground076\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-rootbound/basecolor.webp\",bytes:80318,sha256:\"e7ea9cf40442e9784dddc75399ee818a56b32110b70c7c97f5160f66a8468227\"},normal:{file:\"textures/creature-rootbound/normal.webp\",bytes:68262,sha256:\"6619d18b0159c1c6433224079bd8c7af4427330312fd95bf4dc3f8817ddf06bb\"},roughness:{file:\"textures/creature-rootbound/roughness.webp\",bytes:52578,sha256:\"35f4e9ae25db1ab566e1585b50a0e16d6568c5bc28854b701f56fb32635d47f9\"},height:{file:\"textures/creature-rootbound/height.webp\",bytes:23352,sha256:\"197ddfca9c4d2eaf8ad0abfe1487d3c28e7b6bb3ce2b84805c5ba41cebb440a1\"},ao:{file:\"textures/creature-rootbound/ao.webp\",bytes:66244,sha256:\"67b002796100a011fdf5502f8245981fd3cdb9b932968be285611e8a4f0bbffd\"},tintMask:{file:\"textures/creature-rootbound/tint-mask.webp\",bytes:88550,sha256:\"f3be9091137218b440b1b58b0cb826863a1f3bff4cbd8a46d8d91413912c8fd7\"},preview:{file:\"textures/creature-rootbound/preview.webp\",bytes:86566,sha256:\"d0d304a702c7e9ea486a4cd7432e90d6d82272dfe8e59468060525a17474e12f\"}},runtime:{unlock:{level:5,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-rootbound/basecolor\",bytes:80318,sha256:\"e7ea9cf40442e9784dddc75399ee818a56b32110b70c7c97f5160f66a8468227\"},normal:{entry:\"creature-rootbound/normal\",bytes:68262,sha256:\"6619d18b0159c1c6433224079bd8c7af4427330312fd95bf4dc3f8817ddf06bb\"},roughness:{entry:\"creature-rootbound/roughness\",bytes:52578,sha256:\"35f4e9ae25db1ab566e1585b50a0e16d6568c5bc28854b701f56fb32635d47f9\"},height:{entry:\"creature-rootbound/height\",bytes:23352,sha256:\"197ddfca9c4d2eaf8ad0abfe1487d3c28e7b6bb3ce2b84805c5ba41cebb440a1\"},ao:{entry:\"creature-rootbound/ao\",bytes:66244,sha256:\"67b002796100a011fdf5502f8245981fd3cdb9b932968be285611e8a4f0bbffd\"},tintMask:{entry:\"creature-rootbound/tintMask\",bytes:88550,sha256:\"f3be9091137218b440b1b58b0cb826863a1f3bff4cbd8a46d8d91413912c8fd7\"},preview:{entry:\"creature-rootbound/preview\",bytes:86566,sha256:\"d0d304a702c7e9ea486a4cd7432e90d6d82272dfe8e59468060525a17474e12f\"}}}},{id:\"creature-hammered-bronze\",displayName:\"Hammered Bronze Golem\",track:\"arms\",realm:\"hybrid\",rarity:\"rare\",sourceAssetId:\"Metal008\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Metal008\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-hammered-bronze/basecolor.webp\",bytes:21270,sha256:\"beb51e4c3e9cbc126c7e684904a9848d6c49f593c7351c77df7d838a0b3031a2\"},normal:{file:\"textures/creature-hammered-bronze/normal.webp\",bytes:1860,sha256:\"343ca61b6eac8a6ed0f1c8ece185543a57e19af2890393100da77b8c208df81f\"},roughness:{file:\"textures/creature-hammered-bronze/roughness.webp\",bytes:22538,sha256:\"d2b4ab3952757b6e165e5b131865e89312daa81f2e7b20f4533d424b1d5d2846\"},height:{file:\"textures/creature-hammered-bronze/height.webp\",bytes:3670,sha256:\"966a3de7da93c1aa338a7d5fd25b8b8b60e1b0eae492c6633a5256091e803520\"},metalness:{file:\"textures/creature-hammered-bronze/metalness.webp\",bytes:3062,sha256:\"c94836b0fd1152b518b7f126528630d10c215c8cf1d8927d91652496844311bb\"},tintMask:{file:\"textures/creature-hammered-bronze/tint-mask.webp\",bytes:69154,sha256:\"977b36bfb25617394eda6993fe98972e87575b0a4f20c638fd7816627c50530c\"},preview:{file:\"textures/creature-hammered-bronze/preview.webp\",bytes:26964,sha256:\"ac7d9a6bd1fef3088df0196c355462a24ae5f59276c31b2a84f32277e5174093\"}},runtime:{unlock:{level:1,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-hammered-bronze/basecolor\",bytes:21270,sha256:\"beb51e4c3e9cbc126c7e684904a9848d6c49f593c7351c77df7d838a0b3031a2\"},normal:{entry:\"creature-hammered-bronze/normal\",bytes:1860,sha256:\"343ca61b6eac8a6ed0f1c8ece185543a57e19af2890393100da77b8c208df81f\"},roughness:{entry:\"creature-hammered-bronze/roughness\",bytes:22538,sha256:\"d2b4ab3952757b6e165e5b131865e89312daa81f2e7b20f4533d424b1d5d2846\"},height:{entry:\"creature-hammered-bronze/height\",bytes:3670,sha256:\"966a3de7da93c1aa338a7d5fd25b8b8b60e1b0eae492c6633a5256091e803520\"},metalness:{entry:\"creature-hammered-bronze/metalness\",bytes:3062,sha256:\"c94836b0fd1152b518b7f126528630d10c215c8cf1d8927d91652496844311bb\"},tintMask:{entry:\"creature-hammered-bronze/tintMask\",bytes:69154,sha256:\"977b36bfb25617394eda6993fe98972e87575b0a4f20c638fd7816627c50530c\"},preview:{entry:\"creature-hammered-bronze/preview\",bytes:26964,sha256:\"ac7d9a6bd1fef3088df0196c355462a24ae5f59276c31b2a84f32277e5174093\"}}}},{id:\"creature-rope-sinew\",displayName:\"Rope Sinew\",track:\"arms\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Rope001\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Rope001\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-rope-sinew/basecolor.webp\",bytes:29552,sha256:\"2100056331b8dd71fa4df45d64142272a4eda355df847f835e1f4a45ec0215ac\"},normal:{file:\"textures/creature-rope-sinew/normal.webp\",bytes:58934,sha256:\"5a2f64efff064472eee99a9f2ad9e727a2f34807df7f4e4d1ee13cbd57eb9f87\"},roughness:{file:\"textures/creature-rope-sinew/roughness.webp\",bytes:12446,sha256:\"d95a57e890f030607ebc323ca242cc89a64f380f4f13edf12435a486f8892923\"},height:{file:\"textures/creature-rope-sinew/height.webp\",bytes:8678,sha256:\"41492b35711c17826fe23f1b06e4f61880ee084c5184ba8e7ad2a4bae058ce1b\"},metalness:{file:\"textures/creature-rope-sinew/metalness.webp\",bytes:530,sha256:\"0d61075921f8ced6ab09e8ff7a70d4732d0bbfa62467afcdb18dce2231550116\"},tintMask:{file:\"textures/creature-rope-sinew/tint-mask.webp\",bytes:45544,sha256:\"760c9886d716bb31396be5d943f4547dc05090e4c787ff15245c260306ee268f\"},preview:{file:\"textures/creature-rope-sinew/preview.webp\",bytes:35204,sha256:\"b59e86c79490250b094d7857eeffb5b2c716bb2896394643247f805e509fd9c8\"}},runtime:{unlock:{level:3,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-rope-sinew/basecolor\",bytes:29552,sha256:\"2100056331b8dd71fa4df45d64142272a4eda355df847f835e1f4a45ec0215ac\"},normal:{entry:\"creature-rope-sinew/normal\",bytes:58934,sha256:\"5a2f64efff064472eee99a9f2ad9e727a2f34807df7f4e4d1ee13cbd57eb9f87\"},roughness:{entry:\"creature-rope-sinew/roughness\",bytes:12446,sha256:\"d95a57e890f030607ebc323ca242cc89a64f380f4f13edf12435a486f8892923\"},height:{entry:\"creature-rope-sinew/height\",bytes:8678,sha256:\"41492b35711c17826fe23f1b06e4f61880ee084c5184ba8e7ad2a4bae058ce1b\"},metalness:{entry:\"creature-rope-sinew/metalness\",bytes:530,sha256:\"0d61075921f8ced6ab09e8ff7a70d4732d0bbfa62467afcdb18dce2231550116\"},tintMask:{entry:\"creature-rope-sinew/tintMask\",bytes:45544,sha256:\"760c9886d716bb31396be5d943f4547dc05090e4c787ff15245c260306ee268f\"},preview:{entry:\"creature-rope-sinew/preview\",bytes:35204,sha256:\"b59e86c79490250b094d7857eeffb5b2c716bb2896394643247f805e509fd9c8\"}}}},{id:\"creature-runic-leather\",displayName:\"Runic Leather\",track:\"arms\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"Leather032\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Leather032\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-runic-leather/basecolor.webp\",bytes:28382,sha256:\"bfd8b97143b2df95e1209492ae5d4b2c6bc61b33d82e5d5382a5162392065c66\"},normal:{file:\"textures/creature-runic-leather/normal.webp\",bytes:7148,sha256:\"ddd41e34b6d8ec05f19374ff263344b38c811564f6e7882b5cb48ca71f6cb371\"},roughness:{file:\"textures/creature-runic-leather/roughness.webp\",bytes:85118,sha256:\"651e177fa84f3e1f9eebe5a7e7514a28d1bebab1867ec0f495a10aec997353ef\"},height:{file:\"textures/creature-runic-leather/height.webp\",bytes:90332,sha256:\"66a3c469fd1cb3c120082855bfcef6dadc921e01e3d4a36b1994ee0ea4bf642b\"},tintMask:{file:\"textures/creature-runic-leather/tint-mask.webp\",bytes:89338,sha256:\"5332d654a93dc4f4992f571fd2e5caccad444aa84670cb96da497acca8c9f72f\"},preview:{file:\"textures/creature-runic-leather/preview.webp\",bytes:35058,sha256:\"09b7cf1f2654343134c9e0a795afbab3881ba0d10b62c5a006cade89eae4eae3\"}},runtime:{unlock:{level:5,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-runic-leather/basecolor\",bytes:28382,sha256:\"bfd8b97143b2df95e1209492ae5d4b2c6bc61b33d82e5d5382a5162392065c66\"},normal:{entry:\"creature-runic-leather/normal\",bytes:7148,sha256:\"ddd41e34b6d8ec05f19374ff263344b38c811564f6e7882b5cb48ca71f6cb371\"},roughness:{entry:\"creature-runic-leather/roughness\",bytes:85118,sha256:\"651e177fa84f3e1f9eebe5a7e7514a28d1bebab1867ec0f495a10aec997353ef\"},height:{entry:\"creature-runic-leather/height\",bytes:90332,sha256:\"66a3c469fd1cb3c120082855bfcef6dadc921e01e3d4a36b1994ee0ea4bf642b\"},tintMask:{entry:\"creature-runic-leather/tintMask\",bytes:89338,sha256:\"5332d654a93dc4f4992f571fd2e5caccad444aa84670cb96da497acca8c9f72f\"},preview:{entry:\"creature-runic-leather/preview\",bytes:35058,sha256:\"09b7cf1f2654343134c9e0a795afbab3881ba0d10b62c5a006cade89eae4eae3\"}}}},{id:\"creature-crystal-core\",displayName:\"Crystal Core\",track:\"yoga\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Onyx006\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Onyx006\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-crystal-core/basecolor.webp\",bytes:50726,sha256:\"b40390dfbd54cd5582d63d154fc924302d6c04acb1722ce2219f8b67ddaeb36d\"},normal:{file:\"textures/creature-crystal-core/normal.webp\",bytes:572,sha256:\"b913752028fa3b5d7d102f5eba23aa17b9e0ee1324f52765cb249e36e189ded5\"},roughness:{file:\"textures/creature-crystal-core/roughness.webp\",bytes:15314,sha256:\"88749dba30f831a86dadbe7bca39039297837646ee2d5330085019eaa7fa4074\"},height:{file:\"textures/creature-crystal-core/height.webp\",bytes:2740,sha256:\"196a000792095c5dfa85554a2395e8bc1ffc856039b62eacbdd666f587a38c2a\"},tintMask:{file:\"textures/creature-crystal-core/tint-mask.webp\",bytes:51868,sha256:\"22ef052c4767e7be3f3e6187fa7e6a1e5baf2a0131d47c45cee616ef082b9df6\"},preview:{file:\"textures/creature-crystal-core/preview.webp\",bytes:56978,sha256:\"ee40a473889f2844fa35a8057a6001827945dd43863c9c12da092039b2b8c76a\"}},runtime:{unlock:{level:1,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-crystal-core/basecolor\",bytes:50726,sha256:\"b40390dfbd54cd5582d63d154fc924302d6c04acb1722ce2219f8b67ddaeb36d\"},normal:{entry:\"creature-crystal-core/normal\",bytes:572,sha256:\"b913752028fa3b5d7d102f5eba23aa17b9e0ee1324f52765cb249e36e189ded5\"},roughness:{entry:\"creature-crystal-core/roughness\",bytes:15314,sha256:\"88749dba30f831a86dadbe7bca39039297837646ee2d5330085019eaa7fa4074\"},height:{entry:\"creature-crystal-core/height\",bytes:2740,sha256:\"196a000792095c5dfa85554a2395e8bc1ffc856039b62eacbdd666f587a38c2a\"},tintMask:{entry:\"creature-crystal-core/tintMask\",bytes:51868,sha256:\"22ef052c4767e7be3f3e6187fa7e6a1e5baf2a0131d47c45cee616ef082b9df6\"},preview:{entry:\"creature-crystal-core/preview\",bytes:56978,sha256:\"ee40a473889f2844fa35a8057a6001827945dd43863c9c12da092039b2b8c76a\"}}}},{id:\"creature-moon-marble\",displayName:\"Moon Marble\",track:\"yoga\",realm:\"hybrid\",rarity:\"epic\",sourceAssetId:\"Marble016\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Marble016\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-moon-marble/basecolor.webp\",bytes:60346,sha256:\"30857f841da460f9f6878279498e11805b26bb1b9387302bd2a74d2f11f850fe\"},normal:{file:\"textures/creature-moon-marble/normal.webp\",bytes:558,sha256:\"0abacb9ea21b4e643690ae88919a195040b0c0a22994003cddc2ea40a078e242\"},roughness:{file:\"textures/creature-moon-marble/roughness.webp\",bytes:3740,sha256:\"78bd9171c82cef1e9ab5b6f4df1f0b36021fcb76487af7c187aada745e346795\"},height:{file:\"textures/creature-moon-marble/height.webp\",bytes:54702,sha256:\"2ba36b84ef5e549ede30e4203ce6e8e2d415d6f0f2c095d40bb0a13aa4cf81bb\"},tintMask:{file:\"textures/creature-moon-marble/tint-mask.webp\",bytes:74936,sha256:\"a72497a56824baa0bab493baae6ce2b814f204b1b870426ff8eccddcc5f46030\"},preview:{file:\"textures/creature-moon-marble/preview.webp\",bytes:68934,sha256:\"977f080377efdb814dc01a6a825d1df941566fe6298699a9ee191eaafa866553\"}},runtime:{unlock:{level:3,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-moon-marble/basecolor\",bytes:60346,sha256:\"30857f841da460f9f6878279498e11805b26bb1b9387302bd2a74d2f11f850fe\"},normal:{entry:\"creature-moon-marble/normal\",bytes:558,sha256:\"0abacb9ea21b4e643690ae88919a195040b0c0a22994003cddc2ea40a078e242\"},roughness:{entry:\"creature-moon-marble/roughness\",bytes:3740,sha256:\"78bd9171c82cef1e9ab5b6f4df1f0b36021fcb76487af7c187aada745e346795\"},height:{entry:\"creature-moon-marble/height\",bytes:54702,sha256:\"2ba36b84ef5e549ede30e4203ce6e8e2d415d6f0f2c095d40bb0a13aa4cf81bb\"},tintMask:{entry:\"creature-moon-marble/tintMask\",bytes:74936,sha256:\"a72497a56824baa0bab493baae6ce2b814f204b1b870426ff8eccddcc5f46030\"},preview:{entry:\"creature-moon-marble/preview\",bytes:68934,sha256:\"977f080377efdb814dc01a6a825d1df941566fe6298699a9ee191eaafa866553\"}}}},{id:\"creature-fae-petal\",displayName:\"Fae Petal\",track:\"yoga\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"FlowerSet001\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/FlowerSet001\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-fae-petal/basecolor.webp\",bytes:17208,sha256:\"53bc7d03952fb1244b75ba1e015cf36173c326271005c3330c01fccb63d74946\"},normal:{file:\"textures/creature-fae-petal/normal.webp\",bytes:19898,sha256:\"bb402d8c39e986a0ba5fd1bbdcbcb8cbbdba29a75d4e932b39c5851b2350f75f\"},roughness:{file:\"textures/creature-fae-petal/roughness.webp\",bytes:6054,sha256:\"4b66923e2349ed42ebbf202c8a42aa33fb759c1713cea678dbd0ac93bd175aec\"},height:{file:\"textures/creature-fae-petal/height.webp\",bytes:6176,sha256:\"4dd774718a94f5b87de223c8ab27b18bde4df1249e76f7df7a9627143ca4b830\"},ao:{file:\"textures/creature-fae-petal/ao.webp\",bytes:8140,sha256:\"9eabbf557041b2bdcc58f52cc5821de36470b43f44aac3a6cb87cee3aee645eb\"},opacity:{file:\"textures/creature-fae-petal/opacity.webp\",bytes:9784,sha256:\"7e7d2e3432143c925e111a2e763d3230fa88cc2512155059b020d4516d68cbad\"},tintMask:{file:\"textures/creature-fae-petal/tint-mask.webp\",bytes:15026,sha256:\"255ef36fc492b422a991192efead4b414f0a3ccd57bdcd3212033c82a4533608\"},preview:{file:\"textures/creature-fae-petal/preview.webp\",bytes:19274,sha256:\"afc9fe5d4f588ca9c78e54032aedbdfcd97c991d384f8dbc6ca803f5c6eada5a\"}},runtime:{unlock:{level:5,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-fae-petal/basecolor\",bytes:17208,sha256:\"53bc7d03952fb1244b75ba1e015cf36173c326271005c3330c01fccb63d74946\"},normal:{entry:\"creature-fae-petal/normal\",bytes:19898,sha256:\"bb402d8c39e986a0ba5fd1bbdcbcb8cbbdba29a75d4e932b39c5851b2350f75f\"},roughness:{entry:\"creature-fae-petal/roughness\",bytes:6054,sha256:\"4b66923e2349ed42ebbf202c8a42aa33fb759c1713cea678dbd0ac93bd175aec\"},height:{entry:\"creature-fae-petal/height\",bytes:6176,sha256:\"4dd774718a94f5b87de223c8ab27b18bde4df1249e76f7df7a9627143ca4b830\"},ao:{entry:\"creature-fae-petal/ao\",bytes:8140,sha256:\"9eabbf557041b2bdcc58f52cc5821de36470b43f44aac3a6cb87cee3aee645eb\"},opacity:{entry:\"creature-fae-petal/opacity\",bytes:9784,sha256:\"7e7d2e3432143c925e111a2e763d3230fa88cc2512155059b020d4516d68cbad\"},tintMask:{entry:\"creature-fae-petal/tintMask\",bytes:15026,sha256:\"255ef36fc492b422a991192efead4b414f0a3ccd57bdcd3212033c82a4533608\"},preview:{entry:\"creature-fae-petal/preview\",bytes:19274,sha256:\"afc9fe5d4f588ca9c78e54032aedbdfcd97c991d384f8dbc6ca803f5c6eada5a\"}}}},{id:\"creature-dragon-scale\",displayName:\"Dragon Scale\",track:\"martial-arts\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"RoofingTiles013A\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/RoofingTiles013A\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-dragon-scale/basecolor.webp\",bytes:2668,sha256:\"663af0ac46b5c88304bf252b913714ee7315062ffaf8d41e1f98437436cfe933\"},normal:{file:\"textures/creature-dragon-scale/normal.webp\",bytes:20688,sha256:\"9bdd90ed2cbf7eaa94c24f290906c764b4a4c16ceb184114dbb22b749209d3a8\"},roughness:{file:\"textures/creature-dragon-scale/roughness.webp\",bytes:16142,sha256:\"8edb0acad8dfa41c361067e49cc1aa13a23cd1e179b9fd02621c6a49cf5f4ee6\"},height:{file:\"textures/creature-dragon-scale/height.webp\",bytes:8400,sha256:\"f53bd1a0068dd2cc2cd31b67f2bd6800680c4d58443418bfdb2f1998ea78fbcb\"},ao:{file:\"textures/creature-dragon-scale/ao.webp\",bytes:14048,sha256:\"5e9e5483fdea8249867c9532a991b11b2518e1c725e43e84835428d13d0791e5\"},opacity:{file:\"textures/creature-dragon-scale/opacity.webp\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{file:\"textures/creature-dragon-scale/tint-mask.webp\",bytes:33612,sha256:\"d77eb358cbfb4252db8a6df4ff0536bb5d45e7f74dbac6fa6ead5c2c6fb30adf\"},preview:{file:\"textures/creature-dragon-scale/preview.webp\",bytes:3430,sha256:\"f2ff67b80aedfbb8c3c5e1e2412b54c6b6d88ba256e80d9604103fe4ac90435b\"}},runtime:{unlock:{level:1,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-dragon-scale/basecolor\",bytes:2668,sha256:\"663af0ac46b5c88304bf252b913714ee7315062ffaf8d41e1f98437436cfe933\"},normal:{entry:\"creature-dragon-scale/normal\",bytes:20688,sha256:\"9bdd90ed2cbf7eaa94c24f290906c764b4a4c16ceb184114dbb22b749209d3a8\"},roughness:{entry:\"creature-dragon-scale/roughness\",bytes:16142,sha256:\"8edb0acad8dfa41c361067e49cc1aa13a23cd1e179b9fd02621c6a49cf5f4ee6\"},height:{entry:\"creature-dragon-scale/height\",bytes:8400,sha256:\"f53bd1a0068dd2cc2cd31b67f2bd6800680c4d58443418bfdb2f1998ea78fbcb\"},ao:{entry:\"creature-dragon-scale/ao\",bytes:14048,sha256:\"5e9e5483fdea8249867c9532a991b11b2518e1c725e43e84835428d13d0791e5\"},opacity:{entry:\"creature-dragon-scale/opacity\",bytes:528,sha256:\"ce7a484a8cfe1a10a88aa05beaa84c80880572df797dfe8664e43f7a51a32c27\"},tintMask:{entry:\"creature-dragon-scale/tintMask\",bytes:33612,sha256:\"d77eb358cbfb4252db8a6df4ff0536bb5d45e7f74dbac6fa6ead5c2c6fb30adf\"},preview:{entry:\"creature-dragon-scale/preview\",bytes:3430,sha256:\"f2ff67b80aedfbb8c3c5e1e2412b54c6b6d88ba256e80d9604103fe4ac90435b\"}}}},{id:\"creature-bamboo-hide\",displayName:\"Bamboo Hide\",track:\"martial-arts\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Bamboo001A\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Bamboo001A\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-bamboo-hide/basecolor.webp\",bytes:11654,sha256:\"8a26d7c21793d2d02c4b6d3313ec4fb4646d48dc97d3a3d0e9a51e6787fd5337\"},normal:{file:\"textures/creature-bamboo-hide/normal.webp\",bytes:20194,sha256:\"0c249768ad2e7285a506a67b932f96e7a0472bec4a5e7b26f0b672ca34eab9b6\"},roughness:{file:\"textures/creature-bamboo-hide/roughness.webp\",bytes:12634,sha256:\"3e57e47e22afa27294a0137519906146e27444654a0d02765b7c414ede8bc154\"},height:{file:\"textures/creature-bamboo-hide/height.webp\",bytes:7926,sha256:\"17c7dce94d4eae86698c08537620db4ba94534200acfa3f8cc1323a5c824473b\"},ao:{file:\"textures/creature-bamboo-hide/ao.webp\",bytes:7788,sha256:\"20df27a385c6cac19c1c083d8938d7c3e76e117e19bc1087c33dd4f4634b3c3c\"},opacity:{file:\"textures/creature-bamboo-hide/opacity.webp\",bytes:2412,sha256:\"b7de9d512266f259b7910820d03689d0680fea8a7d1f865cfb28dc3010652be7\"},tintMask:{file:\"textures/creature-bamboo-hide/tint-mask.webp\",bytes:37906,sha256:\"e6b2ebfedeb9ab63529780556808f7397d3db969fc5862e78d70e6cbdc78ffed\"},preview:{file:\"textures/creature-bamboo-hide/preview.webp\",bytes:14130,sha256:\"468e73ebe9c1552645ec4bfa0e9a417a8976210005686772416d8a142b74b3d7\"}},runtime:{unlock:{level:3,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-bamboo-hide/basecolor\",bytes:11654,sha256:\"8a26d7c21793d2d02c4b6d3313ec4fb4646d48dc97d3a3d0e9a51e6787fd5337\"},normal:{entry:\"creature-bamboo-hide/normal\",bytes:20194,sha256:\"0c249768ad2e7285a506a67b932f96e7a0472bec4a5e7b26f0b672ca34eab9b6\"},roughness:{entry:\"creature-bamboo-hide/roughness\",bytes:12634,sha256:\"3e57e47e22afa27294a0137519906146e27444654a0d02765b7c414ede8bc154\"},height:{entry:\"creature-bamboo-hide/height\",bytes:7926,sha256:\"17c7dce94d4eae86698c08537620db4ba94534200acfa3f8cc1323a5c824473b\"},ao:{entry:\"creature-bamboo-hide/ao\",bytes:7788,sha256:\"20df27a385c6cac19c1c083d8938d7c3e76e117e19bc1087c33dd4f4634b3c3c\"},opacity:{entry:\"creature-bamboo-hide/opacity\",bytes:2412,sha256:\"b7de9d512266f259b7910820d03689d0680fea8a7d1f865cfb28dc3010652be7\"},tintMask:{entry:\"creature-bamboo-hide/tintMask\",bytes:37906,sha256:\"e6b2ebfedeb9ab63529780556808f7397d3db969fc5862e78d70e6cbdc78ffed\"},preview:{entry:\"creature-bamboo-hide/preview\",bytes:14130,sha256:\"468e73ebe9c1552645ec4bfa0e9a417a8976210005686772416d8a142b74b3d7\"}}}},{id:\"creature-ivory-chitin\",displayName:\"Ivory Chitin\",track:\"martial-arts\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Marble021\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Marble021\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-ivory-chitin/basecolor.webp\",bytes:15470,sha256:\"81219c6653e2322483827286ce187f288c370e953d63768758d5ab1d5f139f01\"},normal:{file:\"textures/creature-ivory-chitin/normal.webp\",bytes:546,sha256:\"bb0dca1732b8beac8a047157a25c3325d0e82ee854775c9b30a3d0d3bb1c84d4\"},roughness:{file:\"textures/creature-ivory-chitin/roughness.webp\",bytes:3860,sha256:\"cbe0b85ba9dd43d3a8de3e2b1f49ea26f078836685ab9fcbb6012adaf3186259\"},height:{file:\"textures/creature-ivory-chitin/height.webp\",bytes:50360,sha256:\"f1baf51d0f8bbebdd08b037b41dc0a52e8cdbe1d3ee3f3c8e229e10ecceaad8b\"},tintMask:{file:\"textures/creature-ivory-chitin/tint-mask.webp\",bytes:97890,sha256:\"dab2a9ef91fbfd6e0563073bcd2594c15a12037a215e5e4a206c850585d0a4a0\"},preview:{file:\"textures/creature-ivory-chitin/preview.webp\",bytes:19758,sha256:\"57ca0354c5b20b764d90bc4f8d55f0a4c5f505e55f46ac3165f4268ccaf52317\"}},runtime:{unlock:{level:5,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-ivory-chitin/basecolor\",bytes:15470,sha256:\"81219c6653e2322483827286ce187f288c370e953d63768758d5ab1d5f139f01\"},normal:{entry:\"creature-ivory-chitin/normal\",bytes:546,sha256:\"bb0dca1732b8beac8a047157a25c3325d0e82ee854775c9b30a3d0d3bb1c84d4\"},roughness:{entry:\"creature-ivory-chitin/roughness\",bytes:3860,sha256:\"cbe0b85ba9dd43d3a8de3e2b1f49ea26f078836685ab9fcbb6012adaf3186259\"},height:{entry:\"creature-ivory-chitin/height\",bytes:50360,sha256:\"f1baf51d0f8bbebdd08b037b41dc0a52e8cdbe1d3ee3f3c8e229e10ecceaad8b\"},tintMask:{entry:\"creature-ivory-chitin/tintMask\",bytes:97890,sha256:\"dab2a9ef91fbfd6e0563073bcd2594c15a12037a215e5e4a206c850585d0a4a0\"},preview:{entry:\"creature-ivory-chitin/preview\",bytes:19758,sha256:\"57ca0354c5b20b764d90bc4f8d55f0a4c5f505e55f46ac3165f4268ccaf52317\"}}}},{id:\"creature-circuit-hide\",displayName:\"Circuit Hide\",track:\"cardio\",realm:\"sci-fi\",rarity:\"rare\",sourceAssetId:\"Chip001\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Chip001\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-circuit-hide/basecolor.webp\",bytes:40778,sha256:\"096cd7675f3b9908bea4f2414e1c2c36d5b7f11c80055647805b0ffea3aeca4d\"},normal:{file:\"textures/creature-circuit-hide/normal.webp\",bytes:27864,sha256:\"d8064a373c7c347760ecb731bb61b203e1893d8db280062d6bfdc180ebb044d9\"},roughness:{file:\"textures/creature-circuit-hide/roughness.webp\",bytes:26718,sha256:\"350c942f434549bafd6a47f4e6d4acef03e666eea5f284779cf533591562663d\"},height:{file:\"textures/creature-circuit-hide/height.webp\",bytes:23204,sha256:\"f31a4005001a2319418f6de50e502f80e48f04c77fd725bd55270843c1d6a049\"},metalness:{file:\"textures/creature-circuit-hide/metalness.webp\",bytes:24542,sha256:\"7fdd6b09dfdd23b2c362218a3f98a5af3291367c2b3f58da3bd1cd29a37da8b9\"},tintMask:{file:\"textures/creature-circuit-hide/tint-mask.webp\",bytes:37986,sha256:\"efe041e77fbd766eefec21bca9b2ddfedb2acb20d43955ea44a46ad42065f22c\"},preview:{file:\"textures/creature-circuit-hide/preview.webp\",bytes:44810,sha256:\"2b020253316ab4d3084073de0b90cf4c4575317475207998ee5cf8c4ae093c16\"}},runtime:{unlock:{level:1,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-circuit-hide/basecolor\",bytes:40778,sha256:\"096cd7675f3b9908bea4f2414e1c2c36d5b7f11c80055647805b0ffea3aeca4d\"},normal:{entry:\"creature-circuit-hide/normal\",bytes:27864,sha256:\"d8064a373c7c347760ecb731bb61b203e1893d8db280062d6bfdc180ebb044d9\"},roughness:{entry:\"creature-circuit-hide/roughness\",bytes:26718,sha256:\"350c942f434549bafd6a47f4e6d4acef03e666eea5f284779cf533591562663d\"},height:{entry:\"creature-circuit-hide/height\",bytes:23204,sha256:\"f31a4005001a2319418f6de50e502f80e48f04c77fd725bd55270843c1d6a049\"},metalness:{entry:\"creature-circuit-hide/metalness\",bytes:24542,sha256:\"7fdd6b09dfdd23b2c362218a3f98a5af3291367c2b3f58da3bd1cd29a37da8b9\"},tintMask:{entry:\"creature-circuit-hide/tintMask\",bytes:37986,sha256:\"efe041e77fbd766eefec21bca9b2ddfedb2acb20d43955ea44a46ad42065f22c\"},preview:{entry:\"creature-circuit-hide/preview\",bytes:44810,sha256:\"2b020253316ab4d3084073de0b90cf4c4575317475207998ee5cf8c4ae093c16\"}}}},{id:\"creature-reactor-rust\",displayName:\"Reactor Rust\",track:\"cardio\",realm:\"sci-fi\",rarity:\"epic\",sourceAssetId:\"Metal063\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Metal063\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-reactor-rust/basecolor.webp\",bytes:11264,sha256:\"ffdb6f1feeaac227647437e25e4d06291c6ee547061c60b61819277cfc37d932\"},normal:{file:\"textures/creature-reactor-rust/normal.webp\",bytes:550,sha256:\"f0f42188a939998becdd27cc27174e355f5fe0cffff56f440af5183fce757854\"},roughness:{file:\"textures/creature-reactor-rust/roughness.webp\",bytes:29148,sha256:\"8a34c7db1239c7127956f7daa263fe89cb5d7f05614938c12b5da82098408907\"},height:{file:\"textures/creature-reactor-rust/height.webp\",bytes:37754,sha256:\"0ce87e82026e669fb796708337c3e1614cef174134b7ecb9bb901f2fccf439ae\"},metalness:{file:\"textures/creature-reactor-rust/metalness.webp\",bytes:43140,sha256:\"47ca127726b3e24b6c07713a7f50fe6baf5a3d3e99f925e3c47d0fd5c01a2ab9\"},tintMask:{file:\"textures/creature-reactor-rust/tint-mask.webp\",bytes:97766,sha256:\"9190d9c0246cb5e52f8e2e6ffe9b99f604681bc96c6d9bf86cf5a93a7c4b9abc\"},preview:{file:\"textures/creature-reactor-rust/preview.webp\",bytes:17150,sha256:\"1537f736edba5d9c5f78988cbb50e49ab83a293b9c94aad49c25fdccad94bfe8\"}},runtime:{unlock:{level:3,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-reactor-rust/basecolor\",bytes:11264,sha256:\"ffdb6f1feeaac227647437e25e4d06291c6ee547061c60b61819277cfc37d932\"},normal:{entry:\"creature-reactor-rust/normal\",bytes:550,sha256:\"f0f42188a939998becdd27cc27174e355f5fe0cffff56f440af5183fce757854\"},roughness:{entry:\"creature-reactor-rust/roughness\",bytes:29148,sha256:\"8a34c7db1239c7127956f7daa263fe89cb5d7f05614938c12b5da82098408907\"},height:{entry:\"creature-reactor-rust/height\",bytes:37754,sha256:\"0ce87e82026e669fb796708337c3e1614cef174134b7ecb9bb901f2fccf439ae\"},metalness:{entry:\"creature-reactor-rust/metalness\",bytes:43140,sha256:\"47ca127726b3e24b6c07713a7f50fe6baf5a3d3e99f925e3c47d0fd5c01a2ab9\"},tintMask:{entry:\"creature-reactor-rust/tintMask\",bytes:97766,sha256:\"9190d9c0246cb5e52f8e2e6ffe9b99f604681bc96c6d9bf86cf5a93a7c4b9abc\"},preview:{entry:\"creature-reactor-rust/preview\",bytes:17150,sha256:\"1537f736edba5d9c5f78988cbb50e49ab83a293b9c94aad49c25fdccad94bfe8\"}}}},{id:\"creature-aero-mesh\",displayName:\"Aero Mesh\",track:\"cardio\",realm:\"sci-fi\",rarity:\"legendary\",sourceAssetId:\"MetalWalkway013\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/MetalWalkway013\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-aero-mesh/basecolor.webp\",bytes:9048,sha256:\"efd7e746572308d9717ac3ff5f401830ca4202b89e9b731598e0011cff27300f\"},normal:{file:\"textures/creature-aero-mesh/normal.webp\",bytes:55928,sha256:\"4517755111af640a8fcd23b09769a51d97356b3595320ec249b3e6d0286c28c9\"},roughness:{file:\"textures/creature-aero-mesh/roughness.webp\",bytes:27652,sha256:\"bda6c12306cb56d53cd964083db281078eaedb32e0588d2e39ff3619c73b4721\"},height:{file:\"textures/creature-aero-mesh/height.webp\",bytes:29354,sha256:\"0d4e1d671a7d57525e21e35cbfc83d89d824c7b89f3a9c85188be87243afc118\"},metalness:{file:\"textures/creature-aero-mesh/metalness.webp\",bytes:1340,sha256:\"365eb05114bf220e641ba92ffe9c2032041e050f5fa03e856479edadfca04ce4\"},opacity:{file:\"textures/creature-aero-mesh/opacity.webp\",bytes:28608,sha256:\"fd306eedd40b7130a73447594b0b2889735a722f85b8fb74e91024e0bb48653e\"},tintMask:{file:\"textures/creature-aero-mesh/tint-mask.webp\",bytes:23612,sha256:\"7d4e51edf8c6e2961a92d10fd204e03676f1a886dcc3f94f80ec7f5bf934a756\"},preview:{file:\"textures/creature-aero-mesh/preview.webp\",bytes:11188,sha256:\"e249038b305943c5cc58fdaceed7307e77515a33d88c7fb020e832b0ba6a1a75\"}},runtime:{unlock:{level:5,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-aero-mesh/basecolor\",bytes:9048,sha256:\"efd7e746572308d9717ac3ff5f401830ca4202b89e9b731598e0011cff27300f\"},normal:{entry:\"creature-aero-mesh/normal\",bytes:55928,sha256:\"4517755111af640a8fcd23b09769a51d97356b3595320ec249b3e6d0286c28c9\"},roughness:{entry:\"creature-aero-mesh/roughness\",bytes:27652,sha256:\"bda6c12306cb56d53cd964083db281078eaedb32e0588d2e39ff3619c73b4721\"},height:{entry:\"creature-aero-mesh/height\",bytes:29354,sha256:\"0d4e1d671a7d57525e21e35cbfc83d89d824c7b89f3a9c85188be87243afc118\"},metalness:{entry:\"creature-aero-mesh/metalness\",bytes:1340,sha256:\"365eb05114bf220e641ba92ffe9c2032041e050f5fa03e856479edadfca04ce4\"},opacity:{entry:\"creature-aero-mesh/opacity\",bytes:28608,sha256:\"fd306eedd40b7130a73447594b0b2889735a722f85b8fb74e91024e0bb48653e\"},tintMask:{entry:\"creature-aero-mesh/tintMask\",bytes:23612,sha256:\"7d4e51edf8c6e2961a92d10fd204e03676f1a886dcc3f94f80ec7f5bf934a756\"},preview:{entry:\"creature-aero-mesh/preview\",bytes:11188,sha256:\"e249038b305943c5cc58fdaceed7307e77515a33d88c7fb020e832b0ba6a1a75\"}}}},{id:\"creature-zen-sand\",displayName:\"Zen Sand\",track:\"meditation\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Ground097\",collection:\"creature-forged-realms\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Ground097\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-zen-sand/basecolor.webp\",bytes:2566,sha256:\"0913f83f5a430d643903700a9ddba413618b974d1284ab5bb33235e09bef6d6f\"},normal:{file:\"textures/creature-zen-sand/normal.webp\",bytes:25542,sha256:\"acf6ca0faf928441a99d871c6bcc05fe1b1644e8cd5a4cd12c807b8572aa5219\"},roughness:{file:\"textures/creature-zen-sand/roughness.webp\",bytes:9672,sha256:\"89cd80ff7f889b753fb059e427bc082c02f223da30cf388d3ac41c1ada5e3cc9\"},height:{file:\"textures/creature-zen-sand/height.webp\",bytes:14040,sha256:\"55c05b9ab62b320dc74c5e37d871ec9f2a63804e654b3bac2d3df4dc045a9246\"},ao:{file:\"textures/creature-zen-sand/ao.webp\",bytes:2322,sha256:\"0d241c3387cc7d877016d4db9225cc0aae6fed59f7d9fff78797f6b204466697\"},tintMask:{file:\"textures/creature-zen-sand/tint-mask.webp\",bytes:27572,sha256:\"92f6c6974aa9641af624ac98c6acc383ca0094ffd8c60c43c81c4e94781d1441\"},preview:{file:\"textures/creature-zen-sand/preview.webp\",bytes:3032,sha256:\"965d0ecf578a8d912910f99fba4bc09e5a61ba069d5fb2be14cbd02e4d133a86\"}},runtime:{unlock:{level:1,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-zen-sand/basecolor\",bytes:2566,sha256:\"0913f83f5a430d643903700a9ddba413618b974d1284ab5bb33235e09bef6d6f\"},normal:{entry:\"creature-zen-sand/normal\",bytes:25542,sha256:\"acf6ca0faf928441a99d871c6bcc05fe1b1644e8cd5a4cd12c807b8572aa5219\"},roughness:{entry:\"creature-zen-sand/roughness\",bytes:9672,sha256:\"89cd80ff7f889b753fb059e427bc082c02f223da30cf388d3ac41c1ada5e3cc9\"},height:{entry:\"creature-zen-sand/height\",bytes:14040,sha256:\"55c05b9ab62b320dc74c5e37d871ec9f2a63804e654b3bac2d3df4dc045a9246\"},ao:{entry:\"creature-zen-sand/ao\",bytes:2322,sha256:\"0d241c3387cc7d877016d4db9225cc0aae6fed59f7d9fff78797f6b204466697\"},tintMask:{entry:\"creature-zen-sand/tintMask\",bytes:27572,sha256:\"92f6c6974aa9641af624ac98c6acc383ca0094ffd8c60c43c81c4e94781d1441\"},preview:{entry:\"creature-zen-sand/preview\",bytes:3032,sha256:\"965d0ecf578a8d912910f99fba4bc09e5a61ba069d5fb2be14cbd02e4d133a86\"}}}},{id:\"creature-river-stone\",displayName:\"River Stone\",track:\"meditation\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Rock020\",collection:\"creature-forged-realms\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Rock020\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-river-stone/basecolor.webp\",bytes:49168,sha256:\"e8cdd973998441e09a8dc4b44ff9da77dec6fad11f8523138ced65b1e9e4a3f9\"},normal:{file:\"textures/creature-river-stone/normal.webp\",bytes:99336,sha256:\"f31db446c61f36d6775548bff4d04ea21b54dfc1e3271d39b719ab6c48b9c208\"},roughness:{file:\"textures/creature-river-stone/roughness.webp\",bytes:13096,sha256:\"65ca034f5f657db0fcf502c93b2bacc3f1a66a572ed3e24d09ba3fadbbb80757\"},height:{file:\"textures/creature-river-stone/height.webp\",bytes:9202,sha256:\"8e5b35579dce02cbb1fbfa415762a6b65724ef86898c3cc53de36b37398f90ce\"},ao:{file:\"textures/creature-river-stone/ao.webp\",bytes:22322,sha256:\"985e2218cda815c2549c0a926df7d26f050ba1e34eccb4a859fba17c6ec9489e\"},tintMask:{file:\"textures/creature-river-stone/tint-mask.webp\",bytes:76542,sha256:\"b603234beb199542b602fd2a8823ba1416f4be342b69168bc85e6bfc15a76e4f\"},preview:{file:\"textures/creature-river-stone/preview.webp\",bytes:57812,sha256:\"09b86e6e3c10f2c1581c3a46507d593fe561e8bfed7628d35665d695ae4926a7\"}},runtime:{unlock:{level:3,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-river-stone/basecolor\",bytes:49168,sha256:\"e8cdd973998441e09a8dc4b44ff9da77dec6fad11f8523138ced65b1e9e4a3f9\"},normal:{entry:\"creature-river-stone/normal\",bytes:99336,sha256:\"f31db446c61f36d6775548bff4d04ea21b54dfc1e3271d39b719ab6c48b9c208\"},roughness:{entry:\"creature-river-stone/roughness\",bytes:13096,sha256:\"65ca034f5f657db0fcf502c93b2bacc3f1a66a572ed3e24d09ba3fadbbb80757\"},height:{entry:\"creature-river-stone/height\",bytes:9202,sha256:\"8e5b35579dce02cbb1fbfa415762a6b65724ef86898c3cc53de36b37398f90ce\"},ao:{entry:\"creature-river-stone/ao\",bytes:22322,sha256:\"985e2218cda815c2549c0a926df7d26f050ba1e34eccb4a859fba17c6ec9489e\"},tintMask:{entry:\"creature-river-stone/tintMask\",bytes:76542,sha256:\"b603234beb199542b602fd2a8823ba1416f4be342b69168bc85e6bfc15a76e4f\"},preview:{entry:\"creature-river-stone/preview\",bytes:57812,sha256:\"09b86e6e3c10f2c1581c3a46507d593fe561e8bfed7628d35665d695ae4926a7\"}}}},{id:\"creature-biolume-moss\",displayName:\"Biolume Moss\",track:\"meditation\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Moss002\",collection:\"creature-forged-realms\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Moss002\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-biolume-moss/basecolor.webp\",bytes:73648,sha256:\"269fd39b656f9e882f9b6ce516b3f0ae5ea9017a03b6851260618786f9263be6\"},normal:{file:\"textures/creature-biolume-moss/normal.webp\",bytes:87824,sha256:\"9d94ac281cdfc8297c1dd5b49be3270eee9464bfa9a0e2c39339efab2c89a21b\"},roughness:{file:\"textures/creature-biolume-moss/roughness.webp\",bytes:39816,sha256:\"4583d9d7365e367dde4f2dea9a4cbc3f4e96670a46fa16d808f8378bb2a9ea62\"},height:{file:\"textures/creature-biolume-moss/height.webp\",bytes:25618,sha256:\"f4f5a28835d31558f808f1889a69753b478f09a169d28ac51d44bc5971776836\"},ao:{file:\"textures/creature-biolume-moss/ao.webp\",bytes:78346,sha256:\"99d195c2cc601acfbf776b793ca98cb79eceab56bdafc50b788e3231734cf773\"},tintMask:{file:\"textures/creature-biolume-moss/tint-mask.webp\",bytes:99630,sha256:\"45f5f81dd4fe98c3df7bfd5fd912fbd239d2e53e2d8bde98b3f724c83eefebda\"},preview:{file:\"textures/creature-biolume-moss/preview.webp\",bytes:77278,sha256:\"4da02ca977708a4ebfa784dd8d51012455c1d85071a6074748db15f5c3d9744d\"}},runtime:{unlock:{level:5,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-biolume-moss/basecolor\",bytes:73648,sha256:\"269fd39b656f9e882f9b6ce516b3f0ae5ea9017a03b6851260618786f9263be6\"},normal:{entry:\"creature-biolume-moss/normal\",bytes:87824,sha256:\"9d94ac281cdfc8297c1dd5b49be3270eee9464bfa9a0e2c39339efab2c89a21b\"},roughness:{entry:\"creature-biolume-moss/roughness\",bytes:39816,sha256:\"4583d9d7365e367dde4f2dea9a4cbc3f4e96670a46fa16d808f8378bb2a9ea62\"},height:{entry:\"creature-biolume-moss/height\",bytes:25618,sha256:\"f4f5a28835d31558f808f1889a69753b478f09a169d28ac51d44bc5971776836\"},ao:{entry:\"creature-biolume-moss/ao\",bytes:78346,sha256:\"99d195c2cc601acfbf776b793ca98cb79eceab56bdafc50b788e3231734cf773\"},tintMask:{entry:\"creature-biolume-moss/tintMask\",bytes:99630,sha256:\"45f5f81dd4fe98c3df7bfd5fd912fbd239d2e53e2d8bde98b3f724c83eefebda\"},preview:{entry:\"creature-biolume-moss/preview\",bytes:77278,sha256:\"4da02ca977708a4ebfa784dd8d51012455c1d85071a6074748db15f5c3d9744d\"}}}},{id:\"creature-mirror-knight\",displayName:\"Mirror Knight\",track:\"chest\",realm:\"sci-fi\",rarity:\"rare\",sourceAssetId:\"Metal048A\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Metal048A\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-mirror-knight/basecolor.webp\",bytes:998,sha256:\"cf989101d5f5483fe0618ff51ec7b02ff6ab0afa5f01ff3f7fa2b3bba49e0f3f\"},normal:{file:\"textures/creature-mirror-knight/normal.webp\",bytes:594,sha256:\"5a32ff9d82106a7811bf45e72645c15d9a8e2609a262c106ffb75126f8911156\"},roughness:{file:\"textures/creature-mirror-knight/roughness.webp\",bytes:732,sha256:\"cc0c496cd6cc5503fab83d82acd8ae3f1a7b5b25657ee25fffbed6308e26b5d5\"},height:{file:\"textures/creature-mirror-knight/height.webp\",bytes:526,sha256:\"abb51cd0690994d97aff0ad32ab12896592506ffd61886f569963b2f71e20c0f\"},metalness:{file:\"textures/creature-mirror-knight/metalness.webp\",bytes:532,sha256:\"cf3db3d5638b9b2a0d343c9db9efb673235385846a75c8edd0a88a7fb6bec60a\"},tintMask:{file:\"textures/creature-mirror-knight/tint-mask.webp\",bytes:67594,sha256:\"b444a54a2f7db6df7e4afc8c80fecd82887db13cb7052f78fafd1e2593d31d06\"},preview:{file:\"textures/creature-mirror-knight/preview.webp\",bytes:1298,sha256:\"ae8103593152bf336133fc8752255d8b40652633bb8bab142cf9c6c24d7927f6\"}},runtime:{unlock:{level:1,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-mirror-knight/basecolor\",bytes:998,sha256:\"cf989101d5f5483fe0618ff51ec7b02ff6ab0afa5f01ff3f7fa2b3bba49e0f3f\"},normal:{entry:\"creature-mirror-knight/normal\",bytes:594,sha256:\"5a32ff9d82106a7811bf45e72645c15d9a8e2609a262c106ffb75126f8911156\"},roughness:{entry:\"creature-mirror-knight/roughness\",bytes:732,sha256:\"cc0c496cd6cc5503fab83d82acd8ae3f1a7b5b25657ee25fffbed6308e26b5d5\"},height:{entry:\"creature-mirror-knight/height\",bytes:526,sha256:\"abb51cd0690994d97aff0ad32ab12896592506ffd61886f569963b2f71e20c0f\"},metalness:{entry:\"creature-mirror-knight/metalness\",bytes:532,sha256:\"cf3db3d5638b9b2a0d343c9db9efb673235385846a75c8edd0a88a7fb6bec60a\"},tintMask:{entry:\"creature-mirror-knight/tintMask\",bytes:67594,sha256:\"b444a54a2f7db6df7e4afc8c80fecd82887db13cb7052f78fafd1e2593d31d06\"},preview:{entry:\"creature-mirror-knight/preview\",bytes:1298,sha256:\"ae8103593152bf336133fc8752255d8b40652633bb8bab142cf9c6c24d7927f6\"}}}},{id:\"creature-tarnished-crown\",displayName:\"Tarnished Crown\",track:\"chest\",realm:\"hybrid\",rarity:\"epic\",sourceAssetId:\"Metal048C\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Metal048C\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-tarnished-crown/basecolor.webp\",bytes:10056,sha256:\"454f8c9a4fd90d206920b5c41beb67ddc47d36867a2d36a48798b7ddfc630acf\"},normal:{file:\"textures/creature-tarnished-crown/normal.webp\",bytes:902,sha256:\"7542c0e567980a2a46af77aeadd5c76784dc4347c4fc691e87b9c751c5a6d1af\"},roughness:{file:\"textures/creature-tarnished-crown/roughness.webp\",bytes:23264,sha256:\"3be7019d924a77751fbbf4665ea1db70ebccc721303c8d247094af69a16df282\"},height:{file:\"textures/creature-tarnished-crown/height.webp\",bytes:6612,sha256:\"9c8916c0d96e11bbc8e1d67b8d343fd2f99d8f8d97ff49469ee319cd36c19239\"},metalness:{file:\"textures/creature-tarnished-crown/metalness.webp\",bytes:9582,sha256:\"b9fcaedd9ea3a6871f2d74879ca30ca16f75e359544654ee54ee5792ba3887f5\"},tintMask:{file:\"textures/creature-tarnished-crown/tint-mask.webp\",bytes:48438,sha256:\"caf136c6c920e0d4e7f52274c82d49b8e9474ec7d3c85534fae44cf7a50700d5\"},preview:{file:\"textures/creature-tarnished-crown/preview.webp\",bytes:11978,sha256:\"ef892c02b1101c732a7f015956460d93fe490fc0507a4263d723c0bc4f0dbbf4\"}},runtime:{unlock:{level:3,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-tarnished-crown/basecolor\",bytes:10056,sha256:\"454f8c9a4fd90d206920b5c41beb67ddc47d36867a2d36a48798b7ddfc630acf\"},normal:{entry:\"creature-tarnished-crown/normal\",bytes:902,sha256:\"7542c0e567980a2a46af77aeadd5c76784dc4347c4fc691e87b9c751c5a6d1af\"},roughness:{entry:\"creature-tarnished-crown/roughness\",bytes:23264,sha256:\"3be7019d924a77751fbbf4665ea1db70ebccc721303c8d247094af69a16df282\"},height:{entry:\"creature-tarnished-crown/height\",bytes:6612,sha256:\"9c8916c0d96e11bbc8e1d67b8d343fd2f99d8f8d97ff49469ee319cd36c19239\"},metalness:{entry:\"creature-tarnished-crown/metalness\",bytes:9582,sha256:\"b9fcaedd9ea3a6871f2d74879ca30ca16f75e359544654ee54ee5792ba3887f5\"},tintMask:{entry:\"creature-tarnished-crown/tintMask\",bytes:48438,sha256:\"caf136c6c920e0d4e7f52274c82d49b8e9474ec7d3c85534fae44cf7a50700d5\"},preview:{entry:\"creature-tarnished-crown/preview\",bytes:11978,sha256:\"ef892c02b1101c732a7f015956460d93fe490fc0507a4263d723c0bc4f0dbbf4\"}}}},{id:\"creature-golden-scarab\",displayName:\"Golden Scarab\",track:\"chest\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"Metal007\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Metal007\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-golden-scarab/basecolor.webp\",bytes:18264,sha256:\"2daf24017e791d9cc0aa9cc72faf573da795869f14ecf318afee20f960bbfb83\"},normal:{file:\"textures/creature-golden-scarab/normal.webp\",bytes:1042,sha256:\"a709a2db3fe891ed772681bfaa2a15d31dd1be3dd4e363b5a596b56fe5f9ad2c\"},roughness:{file:\"textures/creature-golden-scarab/roughness.webp\",bytes:15890,sha256:\"114f37f6188582bfa8b3dc368f523139c85eeca8383c90e812b40e7e2e96e0a1\"},height:{file:\"textures/creature-golden-scarab/height.webp\",bytes:1714,sha256:\"36bb936c56b9bc9f9edfe115c07c6f45d9be80864ab3f1aace77e5477ca92a65\"},metalness:{file:\"textures/creature-golden-scarab/metalness.webp\",bytes:1280,sha256:\"d01c0d2347828b7537974009e32fb25d455bb447ea01f459bdc02840e81d3c31\"},tintMask:{file:\"textures/creature-golden-scarab/tint-mask.webp\",bytes:65652,sha256:\"43a5c55a78fa3ed7f775c0ca959082b2463f0e48ae75d273468169abf0f50c5d\"},preview:{file:\"textures/creature-golden-scarab/preview.webp\",bytes:22470,sha256:\"99ddd90d95b9b01691fad6aff7e60cef3335c570d3bb30641fa73b29af0631b7\"}},runtime:{unlock:{level:5,track:\"chest\"},pack:\"track-chest\",bundle:\"assets/chest.m5bundle\",maps:{basecolor:{entry:\"creature-golden-scarab/basecolor\",bytes:18264,sha256:\"2daf24017e791d9cc0aa9cc72faf573da795869f14ecf318afee20f960bbfb83\"},normal:{entry:\"creature-golden-scarab/normal\",bytes:1042,sha256:\"a709a2db3fe891ed772681bfaa2a15d31dd1be3dd4e363b5a596b56fe5f9ad2c\"},roughness:{entry:\"creature-golden-scarab/roughness\",bytes:15890,sha256:\"114f37f6188582bfa8b3dc368f523139c85eeca8383c90e812b40e7e2e96e0a1\"},height:{entry:\"creature-golden-scarab/height\",bytes:1714,sha256:\"36bb936c56b9bc9f9edfe115c07c6f45d9be80864ab3f1aace77e5477ca92a65\"},metalness:{entry:\"creature-golden-scarab/metalness\",bytes:1280,sha256:\"d01c0d2347828b7537974009e32fb25d455bb447ea01f459bdc02840e81d3c31\"},tintMask:{entry:\"creature-golden-scarab/tintMask\",bytes:65652,sha256:\"43a5c55a78fa3ed7f775c0ca959082b2463f0e48ae75d273468169abf0f50c5d\"},preview:{entry:\"creature-golden-scarab/preview\",bytes:22470,sha256:\"99ddd90d95b9b01691fad6aff7e60cef3335c570d3bb30641fa73b29af0631b7\"}}}},{id:\"creature-emberflow\",displayName:\"Emberflow\",track:\"quads\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Lava001\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Lava001\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-emberflow/basecolor.webp\",bytes:55502,sha256:\"8d7c4615eb329d5255a75792a997eb8ecae3102fb0782a5a2c46e11f9b4341fe\"},normal:{file:\"textures/creature-emberflow/normal.webp\",bytes:105598,sha256:\"1873609c656f2b3764003fbc9b97b91ad3f5e3e69a2aaa4d201d9e7cdc4aec4c\"},roughness:{file:\"textures/creature-emberflow/roughness.webp\",bytes:12882,sha256:\"d48539733cedaf93bdad6b4c4c30708479a743c4fcbef499b3e362e312d021e0\"},height:{file:\"textures/creature-emberflow/height.webp\",bytes:13998,sha256:\"306286c666118aa7da6fc4b8f769a9b3735b40c0003d154d942ca9363f0acb46\"},emissive:{file:\"textures/creature-emberflow/emissive.webp\",bytes:52850,sha256:\"bda5fa0ee23d6b225e2782f34061a4e017831e2e78287a3d781e1a2ac02cd01d\"},tintMask:{file:\"textures/creature-emberflow/tint-mask.webp\",bytes:51236,sha256:\"5b3f83b8fa0c50e04da28b1f8a6ad0789cd376613700502a023e1775b3ec66ac\"},preview:{file:\"textures/creature-emberflow/preview.webp\",bytes:57834,sha256:\"e4df8266f2fadc583a59d6357a024597de261bfb24bb316c7933ead30de08530\"}},runtime:{unlock:{level:1,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-emberflow/basecolor\",bytes:55502,sha256:\"8d7c4615eb329d5255a75792a997eb8ecae3102fb0782a5a2c46e11f9b4341fe\"},normal:{entry:\"creature-emberflow/normal\",bytes:105598,sha256:\"1873609c656f2b3764003fbc9b97b91ad3f5e3e69a2aaa4d201d9e7cdc4aec4c\"},roughness:{entry:\"creature-emberflow/roughness\",bytes:12882,sha256:\"d48539733cedaf93bdad6b4c4c30708479a743c4fcbef499b3e362e312d021e0\"},height:{entry:\"creature-emberflow/height\",bytes:13998,sha256:\"306286c666118aa7da6fc4b8f769a9b3735b40c0003d154d942ca9363f0acb46\"},emissive:{entry:\"creature-emberflow/emissive\",bytes:52850,sha256:\"bda5fa0ee23d6b225e2782f34061a4e017831e2e78287a3d781e1a2ac02cd01d\"},tintMask:{entry:\"creature-emberflow/tintMask\",bytes:51236,sha256:\"5b3f83b8fa0c50e04da28b1f8a6ad0789cd376613700502a023e1775b3ec66ac\"},preview:{entry:\"creature-emberflow/preview\",bytes:57834,sha256:\"e4df8266f2fadc583a59d6357a024597de261bfb24bb316c7933ead30de08530\"}}}},{id:\"creature-volcanic-heart\",displayName:\"Volcanic Heart\",track:\"quads\",realm:\"hybrid\",rarity:\"epic\",sourceAssetId:\"Lava005\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Lava005\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-volcanic-heart/basecolor.webp\",bytes:52804,sha256:\"24781f33f16d0161ca0485e6a732e97c1b9d4a91540c189bf8f748769a27f635\"},normal:{file:\"textures/creature-volcanic-heart/normal.webp\",bytes:54736,sha256:\"ddd24a1373442f4b842c73a45b771aa149357a9d82faf8be149a61c0b9348418\"},roughness:{file:\"textures/creature-volcanic-heart/roughness.webp\",bytes:20200,sha256:\"cf52abbc709aefd88e4329ff6804d850235f0532933ec1d3cd103f0016daabfe\"},height:{file:\"textures/creature-volcanic-heart/height.webp\",bytes:11990,sha256:\"467c8ffc3521c5ca0450ebc4160b392c1f758d4d7222abbc2d3845006af5fe98\"},emissive:{file:\"textures/creature-volcanic-heart/emissive.webp\",bytes:61420,sha256:\"e2651a8d3fa04f74745ccad8f023e5bbe5129e500002f88fb3097fe9ae3aa06f\"},tintMask:{file:\"textures/creature-volcanic-heart/tint-mask.webp\",bytes:53772,sha256:\"eebca000a86cc39d9763ce73e65b718bceda6680db69695b2cf997d625db79cc\"},preview:{file:\"textures/creature-volcanic-heart/preview.webp\",bytes:51986,sha256:\"53c8262cb4b87704104d0bb9e484a5140c839a3bf051a0adbd962306c6e06b84\"}},runtime:{unlock:{level:3,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-volcanic-heart/basecolor\",bytes:52804,sha256:\"24781f33f16d0161ca0485e6a732e97c1b9d4a91540c189bf8f748769a27f635\"},normal:{entry:\"creature-volcanic-heart/normal\",bytes:54736,sha256:\"ddd24a1373442f4b842c73a45b771aa149357a9d82faf8be149a61c0b9348418\"},roughness:{entry:\"creature-volcanic-heart/roughness\",bytes:20200,sha256:\"cf52abbc709aefd88e4329ff6804d850235f0532933ec1d3cd103f0016daabfe\"},height:{entry:\"creature-volcanic-heart/height\",bytes:11990,sha256:\"467c8ffc3521c5ca0450ebc4160b392c1f758d4d7222abbc2d3845006af5fe98\"},emissive:{entry:\"creature-volcanic-heart/emissive\",bytes:61420,sha256:\"e2651a8d3fa04f74745ccad8f023e5bbe5129e500002f88fb3097fe9ae3aa06f\"},tintMask:{entry:\"creature-volcanic-heart/tintMask\",bytes:53772,sha256:\"eebca000a86cc39d9763ce73e65b718bceda6680db69695b2cf997d625db79cc\"},preview:{entry:\"creature-volcanic-heart/preview\",bytes:51986,sha256:\"53c8262cb4b87704104d0bb9e484a5140c839a3bf051a0adbd962306c6e06b84\"}}}},{id:\"creature-aurora-ice\",displayName:\"Aurora Ice\",track:\"quads\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"Ice004\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Ice004\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-aurora-ice/basecolor.webp\",bytes:28102,sha256:\"a0538e8060a8e9c00a04c5f7ac9234416cd40f85a1f5be2e6a7419d890eadf47\"},normal:{file:\"textures/creature-aurora-ice/normal.webp\",bytes:9418,sha256:\"c933ddbc26012694f81f9533fcf670782c573daf6c300317b0ee70807d7474f6\"},roughness:{file:\"textures/creature-aurora-ice/roughness.webp\",bytes:16912,sha256:\"aa50ef45b5034739a1f48d34a8c842ad2444596d1bb7f60ce3f71be88c1dff65\"},height:{file:\"textures/creature-aurora-ice/height.webp\",bytes:24584,sha256:\"ff582e80c4af2ac6b52e235055a6d19ddc34213b22fe6ac90beb6c09b8788ef9\"},tintMask:{file:\"textures/creature-aurora-ice/tint-mask.webp\",bytes:33120,sha256:\"b89c0d07aae4bccea7ac26b589e72ff5ececca87bc166d2dc23406dd943d51b4\"},preview:{file:\"textures/creature-aurora-ice/preview.webp\",bytes:33622,sha256:\"fec978367e0c56323ce5b3f91bef4c1a624e8934e6d2933174b957264fc5229a\"}},runtime:{unlock:{level:5,track:\"quads\"},pack:\"track-quads\",bundle:\"assets/quads.m5bundle\",maps:{basecolor:{entry:\"creature-aurora-ice/basecolor\",bytes:28102,sha256:\"a0538e8060a8e9c00a04c5f7ac9234416cd40f85a1f5be2e6a7419d890eadf47\"},normal:{entry:\"creature-aurora-ice/normal\",bytes:9418,sha256:\"c933ddbc26012694f81f9533fcf670782c573daf6c300317b0ee70807d7474f6\"},roughness:{entry:\"creature-aurora-ice/roughness\",bytes:16912,sha256:\"aa50ef45b5034739a1f48d34a8c842ad2444596d1bb7f60ce3f71be88c1dff65\"},height:{entry:\"creature-aurora-ice/height\",bytes:24584,sha256:\"ff582e80c4af2ac6b52e235055a6d19ddc34213b22fe6ac90beb6c09b8788ef9\"},tintMask:{entry:\"creature-aurora-ice/tintMask\",bytes:33120,sha256:\"b89c0d07aae4bccea7ac26b589e72ff5ececca87bc166d2dc23406dd943d51b4\"},preview:{entry:\"creature-aurora-ice/preview\",bytes:33622,sha256:\"fec978367e0c56323ce5b3f91bef4c1a624e8934e6d2933174b957264fc5229a\"}}}},{id:\"creature-ironbark\",displayName:\"Ironbark\",track:\"glutes\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Bark014\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Bark014\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-ironbark/basecolor.webp\",bytes:60524,sha256:\"60f5086a4946ae52491ea871bbec6dde8a4209cad3dc6711c66d0f520e9bd1c7\"},normal:{file:\"textures/creature-ironbark/normal.webp\",bytes:39240,sha256:\"9e83a63d061651cfaa0892d55ed76762d8493589327db6fb2724254afffad688\"},roughness:{file:\"textures/creature-ironbark/roughness.webp\",bytes:61578,sha256:\"ff1bfd55ebc76fc610082d172138cc5b971c2de306a7626696fddd2ac2c0e304\"},height:{file:\"textures/creature-ironbark/height.webp\",bytes:11624,sha256:\"24dca043922c977d7cd8b58a7a9f8aa5132919693a5d666e4a358a3216a66b15\"},ao:{file:\"textures/creature-ironbark/ao.webp\",bytes:46376,sha256:\"3df1b05d4423870ddf7ab97338ad860ec2f87924492fa008c28e4ac3225c1484\"},tintMask:{file:\"textures/creature-ironbark/tint-mask.webp\",bytes:71852,sha256:\"d1e6acc31473ff62d8dd0022ddad5b542067eea35877b051a1460929d7934ee4\"},preview:{file:\"textures/creature-ironbark/preview.webp\",bytes:68160,sha256:\"8ba5961f132720e02a894e9da7228305ca5ee4a2c2fc720406f8505055a56dd6\"}},runtime:{unlock:{level:1,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-ironbark/basecolor\",bytes:60524,sha256:\"60f5086a4946ae52491ea871bbec6dde8a4209cad3dc6711c66d0f520e9bd1c7\"},normal:{entry:\"creature-ironbark/normal\",bytes:39240,sha256:\"9e83a63d061651cfaa0892d55ed76762d8493589327db6fb2724254afffad688\"},roughness:{entry:\"creature-ironbark/roughness\",bytes:61578,sha256:\"ff1bfd55ebc76fc610082d172138cc5b971c2de306a7626696fddd2ac2c0e304\"},height:{entry:\"creature-ironbark/height\",bytes:11624,sha256:\"24dca043922c977d7cd8b58a7a9f8aa5132919693a5d666e4a358a3216a66b15\"},ao:{entry:\"creature-ironbark/ao\",bytes:46376,sha256:\"3df1b05d4423870ddf7ab97338ad860ec2f87924492fa008c28e4ac3225c1484\"},tintMask:{entry:\"creature-ironbark/tintMask\",bytes:71852,sha256:\"d1e6acc31473ff62d8dd0022ddad5b542067eea35877b051a1460929d7934ee4\"},preview:{entry:\"creature-ironbark/preview\",bytes:68160,sha256:\"8ba5961f132720e02a894e9da7228305ca5ee4a2c2fc720406f8505055a56dd6\"}}}},{id:\"creature-oakscale\",displayName:\"Oakscale\",track:\"glutes\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Bark012\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Bark012\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-oakscale/basecolor.webp\",bytes:71646,sha256:\"8d3becd0bdfbd0af4b40925b5f8f2d29ea593f1116656a871e6f1c84be542b1a\"},normal:{file:\"textures/creature-oakscale/normal.webp\",bytes:122322,sha256:\"3ea9636011eea9ee7e49d4cfa6010271004abb65356a9c700d9ef3a9ddbdf8c1\"},roughness:{file:\"textures/creature-oakscale/roughness.webp\",bytes:56118,sha256:\"99e51498071e74aa167b77ec90fe99834061c115f521b11aedb61e742ef15883\"},height:{file:\"textures/creature-oakscale/height.webp\",bytes:36178,sha256:\"92ee5632dde0de291489635709bc55a45ac89d3cb6f834362c52ca1546954303\"},ao:{file:\"textures/creature-oakscale/ao.webp\",bytes:59772,sha256:\"fdf1d31853c9c9629dddd9c705f24058b8b75ab120ac6d7a017382aa3e45917d\"},tintMask:{file:\"textures/creature-oakscale/tint-mask.webp\",bytes:89244,sha256:\"2d996f056ca9fa7a6b1ecd25d85fca69c1de2c609dc44e6caea2873a03452060\"},preview:{file:\"textures/creature-oakscale/preview.webp\",bytes:80436,sha256:\"8f988fc7f1ebbae37fcb79fd405acbc22d377985fe7fa26e1eefb7f0dbc7d157\"}},runtime:{unlock:{level:3,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-oakscale/basecolor\",bytes:71646,sha256:\"8d3becd0bdfbd0af4b40925b5f8f2d29ea593f1116656a871e6f1c84be542b1a\"},normal:{entry:\"creature-oakscale/normal\",bytes:122322,sha256:\"3ea9636011eea9ee7e49d4cfa6010271004abb65356a9c700d9ef3a9ddbdf8c1\"},roughness:{entry:\"creature-oakscale/roughness\",bytes:56118,sha256:\"99e51498071e74aa167b77ec90fe99834061c115f521b11aedb61e742ef15883\"},height:{entry:\"creature-oakscale/height\",bytes:36178,sha256:\"92ee5632dde0de291489635709bc55a45ac89d3cb6f834362c52ca1546954303\"},ao:{entry:\"creature-oakscale/ao\",bytes:59772,sha256:\"fdf1d31853c9c9629dddd9c705f24058b8b75ab120ac6d7a017382aa3e45917d\"},tintMask:{entry:\"creature-oakscale/tintMask\",bytes:89244,sha256:\"2d996f056ca9fa7a6b1ecd25d85fca69c1de2c609dc44e6caea2873a03452060\"},preview:{entry:\"creature-oakscale/preview\",bytes:80436,sha256:\"8f988fc7f1ebbae37fcb79fd405acbc22d377985fe7fa26e1eefb7f0dbc7d157\"}}}},{id:\"creature-mosswood\",displayName:\"Mosswood\",track:\"glutes\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Bark008\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Bark008\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-mosswood/basecolor.webp\",bytes:59368,sha256:\"890bb90b337f9a4663ed45f17530a98f5bc40f04abd9a29cc780b5ac830e49e7\"},normal:{file:\"textures/creature-mosswood/normal.webp\",bytes:115452,sha256:\"20240bb5ea158afe45c86d472671e936b74115dcc7dbab57e512f3614bca4b65\"},roughness:{file:\"textures/creature-mosswood/roughness.webp\",bytes:14720,sha256:\"52fa0eddcfb1857471dfc86cce4be8a75dd36181f9ed10c0a0252257022611b8\"},height:{file:\"textures/creature-mosswood/height.webp\",bytes:14968,sha256:\"3ca291939907de9d57ae256ee4a017ab3f225ef10ef246b1769a53d4368fe38e\"},ao:{file:\"textures/creature-mosswood/ao.webp\",bytes:30290,sha256:\"5d159bd50f689dd5550f5ddf1a1b043f79e3f17b72f50ddbfdb7af704967e84a\"},tintMask:{file:\"textures/creature-mosswood/tint-mask.webp\",bytes:71764,sha256:\"12749b87113aadaa3e904354fd91a46d0b2f7b1fd3bbb080f68ebdb27c12fc69\"},preview:{file:\"textures/creature-mosswood/preview.webp\",bytes:68928,sha256:\"cd7f6299839d2cd701535eba1526d1054b9f763539668a9aa7b6dd7d7460ea71\"}},runtime:{unlock:{level:5,track:\"glutes\"},pack:\"track-glutes\",bundle:\"assets/glutes.m5bundle\",maps:{basecolor:{entry:\"creature-mosswood/basecolor\",bytes:59368,sha256:\"890bb90b337f9a4663ed45f17530a98f5bc40f04abd9a29cc780b5ac830e49e7\"},normal:{entry:\"creature-mosswood/normal\",bytes:115452,sha256:\"20240bb5ea158afe45c86d472671e936b74115dcc7dbab57e512f3614bca4b65\"},roughness:{entry:\"creature-mosswood/roughness\",bytes:14720,sha256:\"52fa0eddcfb1857471dfc86cce4be8a75dd36181f9ed10c0a0252257022611b8\"},height:{entry:\"creature-mosswood/height\",bytes:14968,sha256:\"3ca291939907de9d57ae256ee4a017ab3f225ef10ef246b1769a53d4368fe38e\"},ao:{entry:\"creature-mosswood/ao\",bytes:30290,sha256:\"5d159bd50f689dd5550f5ddf1a1b043f79e3f17b72f50ddbfdb7af704967e84a\"},tintMask:{entry:\"creature-mosswood/tintMask\",bytes:71764,sha256:\"12749b87113aadaa3e904354fd91a46d0b2f7b1fd3bbb080f68ebdb27c12fc69\"},preview:{entry:\"creature-mosswood/preview\",bytes:68928,sha256:\"cd7f6299839d2cd701535eba1526d1054b9f763539668a9aa7b6dd7d7460ea71\"}}}},{id:\"creature-blood-onyx\",displayName:\"Blood Onyx\",track:\"arms\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Onyx010\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Onyx010\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-blood-onyx/basecolor.webp\",bytes:49258,sha256:\"1e4ece1d137a8e59717dedb50696af52443a48bca8f6ed704c3bcb477e237bd2\"},normal:{file:\"textures/creature-blood-onyx/normal.webp\",bytes:570,sha256:\"89b1d318ca9930effc69d7231739e063be9589e63823131668f65fcb7151fa25\"},roughness:{file:\"textures/creature-blood-onyx/roughness.webp\",bytes:3160,sha256:\"933156eac22cd38b2a55f39ff1af0eeb4cfd5fa3e09e29677c108d7ca0e5fd4e\"},height:{file:\"textures/creature-blood-onyx/height.webp\",bytes:2910,sha256:\"028bb3656a9f50c23a20d3985793c1d1629ad2164d8ec53a04fc333944d41dd9\"},tintMask:{file:\"textures/creature-blood-onyx/tint-mask.webp\",bytes:55394,sha256:\"4d6ba964d297a4329ffdf69a3dbede66982b83703d2e44187ee233f062cbe69d\"},preview:{file:\"textures/creature-blood-onyx/preview.webp\",bytes:56594,sha256:\"d6b36ee15022c78d7b968d51451e912ac91e4952fb46d8d9fe0a017d72a5fe31\"}},runtime:{unlock:{level:1,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-blood-onyx/basecolor\",bytes:49258,sha256:\"1e4ece1d137a8e59717dedb50696af52443a48bca8f6ed704c3bcb477e237bd2\"},normal:{entry:\"creature-blood-onyx/normal\",bytes:570,sha256:\"89b1d318ca9930effc69d7231739e063be9589e63823131668f65fcb7151fa25\"},roughness:{entry:\"creature-blood-onyx/roughness\",bytes:3160,sha256:\"933156eac22cd38b2a55f39ff1af0eeb4cfd5fa3e09e29677c108d7ca0e5fd4e\"},height:{entry:\"creature-blood-onyx/height\",bytes:2910,sha256:\"028bb3656a9f50c23a20d3985793c1d1629ad2164d8ec53a04fc333944d41dd9\"},tintMask:{entry:\"creature-blood-onyx/tintMask\",bytes:55394,sha256:\"4d6ba964d297a4329ffdf69a3dbede66982b83703d2e44187ee233f062cbe69d\"},preview:{entry:\"creature-blood-onyx/preview\",bytes:56594,sha256:\"d6b36ee15022c78d7b968d51451e912ac91e4952fb46d8d9fe0a017d72a5fe31\"}}}},{id:\"creature-honey-crystal\",displayName:\"Honey Crystal\",track:\"arms\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Onyx007\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Onyx007\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-honey-crystal/basecolor.webp\",bytes:22816,sha256:\"98aa336fb9c96553927f664e9b78d7664389e93a81555ef84870111fa958c67a\"},normal:{file:\"textures/creature-honey-crystal/normal.webp\",bytes:560,sha256:\"bf3e55e83aeb3bce5033fd00ac0fb19ac787e3ca01d8573930809f453872035a\"},roughness:{file:\"textures/creature-honey-crystal/roughness.webp\",bytes:3020,sha256:\"b0000cf36bad38e720c4b5cbffa50bf28ee5a251b2cf0117ed531803a55dc886\"},height:{file:\"textures/creature-honey-crystal/height.webp\",bytes:2954,sha256:\"0a16ca42ec013f3eafc4342ed4940eb005379adbd6d879720a0969b5a37e8e89\"},tintMask:{file:\"textures/creature-honey-crystal/tint-mask.webp\",bytes:34036,sha256:\"71cca8020dd06078c658313ddadf4d214f870a5264891bdb1f93d1773d03c789\"},preview:{file:\"textures/creature-honey-crystal/preview.webp\",bytes:26820,sha256:\"6c9b3fcc76753d66a1059cfce8c6b0a1594eca5077ed9a55cfa747ce1892bae2\"}},runtime:{unlock:{level:3,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-honey-crystal/basecolor\",bytes:22816,sha256:\"98aa336fb9c96553927f664e9b78d7664389e93a81555ef84870111fa958c67a\"},normal:{entry:\"creature-honey-crystal/normal\",bytes:560,sha256:\"bf3e55e83aeb3bce5033fd00ac0fb19ac787e3ca01d8573930809f453872035a\"},roughness:{entry:\"creature-honey-crystal/roughness\",bytes:3020,sha256:\"b0000cf36bad38e720c4b5cbffa50bf28ee5a251b2cf0117ed531803a55dc886\"},height:{entry:\"creature-honey-crystal/height\",bytes:2954,sha256:\"0a16ca42ec013f3eafc4342ed4940eb005379adbd6d879720a0969b5a37e8e89\"},tintMask:{entry:\"creature-honey-crystal/tintMask\",bytes:34036,sha256:\"71cca8020dd06078c658313ddadf4d214f870a5264891bdb1f93d1773d03c789\"},preview:{entry:\"creature-honey-crystal/preview\",bytes:26820,sha256:\"6c9b3fcc76753d66a1059cfce8c6b0a1594eca5077ed9a55cfa747ce1892bae2\"}}}},{id:\"creature-void-mirror\",displayName:\"Void Mirror\",track:\"arms\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Onyx014\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Onyx014\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-void-mirror/basecolor.webp\",bytes:53930,sha256:\"cb69edc751c1c91fd28bd9904ad3c097d8dcf6edaaa570694c3fb9d6d6422a9d\"},normal:{file:\"textures/creature-void-mirror/normal.webp\",bytes:576,sha256:\"17b7ad457b39e89d3b2da88be6dd5af7465bfd2a687e6e9574dd876d1c7f0d8c\"},roughness:{file:\"textures/creature-void-mirror/roughness.webp\",bytes:3126,sha256:\"616b3ba7e46a502a1bcfe1c280e30dd8c743f7e18d7f51aea0fec96372e9e14c\"},height:{file:\"textures/creature-void-mirror/height.webp\",bytes:3520,sha256:\"511981c03b2b6d5113991eeb75a42ffdda63e10637f05485fec7cbe6a2340df5\"},tintMask:{file:\"textures/creature-void-mirror/tint-mask.webp\",bytes:62026,sha256:\"26cb90d6461d7324ab564e1e3bc9b587b7429cd5f4aad544ba0629a7b641b405\"},preview:{file:\"textures/creature-void-mirror/preview.webp\",bytes:61294,sha256:\"5d17783eb003707e0ee546300ccd46d645db2b6743e0f68d7ed7c965440fd2d9\"}},runtime:{unlock:{level:5,track:\"arms\"},pack:\"track-arms\",bundle:\"assets/arms.m5bundle\",maps:{basecolor:{entry:\"creature-void-mirror/basecolor\",bytes:53930,sha256:\"cb69edc751c1c91fd28bd9904ad3c097d8dcf6edaaa570694c3fb9d6d6422a9d\"},normal:{entry:\"creature-void-mirror/normal\",bytes:576,sha256:\"17b7ad457b39e89d3b2da88be6dd5af7465bfd2a687e6e9574dd876d1c7f0d8c\"},roughness:{entry:\"creature-void-mirror/roughness\",bytes:3126,sha256:\"616b3ba7e46a502a1bcfe1c280e30dd8c743f7e18d7f51aea0fec96372e9e14c\"},height:{entry:\"creature-void-mirror/height\",bytes:3520,sha256:\"511981c03b2b6d5113991eeb75a42ffdda63e10637f05485fec7cbe6a2340df5\"},tintMask:{entry:\"creature-void-mirror/tintMask\",bytes:62026,sha256:\"26cb90d6461d7324ab564e1e3bc9b587b7429cd5f4aad544ba0629a7b641b405\"},preview:{entry:\"creature-void-mirror/preview\",bytes:61294,sha256:\"5d17783eb003707e0ee546300ccd46d645db2b6743e0f68d7ed7c965440fd2d9\"}}}},{id:\"creature-snow-wraith\",displayName:\"Snow Wraith\",track:\"yoga\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Snow014\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Snow014\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-snow-wraith/basecolor.webp\",bytes:6634,sha256:\"b44309b17f88a5dfe5afb6ae11d38eff932fc4ca31cf57de57dd177c7ad690cc\"},normal:{file:\"textures/creature-snow-wraith/normal.webp\",bytes:25340,sha256:\"c660422b765aca94ffbe27547a70572642798298148e138a175c775efb8d7b83\"},roughness:{file:\"textures/creature-snow-wraith/roughness.webp\",bytes:11026,sha256:\"cf39931b6ecaacadf1f308870a1d6e1eb45a73e2b46e117f4b4e0a76d7b44ce1\"},height:{file:\"textures/creature-snow-wraith/height.webp\",bytes:11568,sha256:\"6075c35c42067b2b476a0ba6aae9c727b946ae75b3afd5b6e168d9bd3f51385b\"},ao:{file:\"textures/creature-snow-wraith/ao.webp\",bytes:4376,sha256:\"08233059a6af6b3c8c14077b17b6d7325895eda0b725b91e55fcead6f887c042\"},tintMask:{file:\"textures/creature-snow-wraith/tint-mask.webp\",bytes:47502,sha256:\"21fa7be4a5d63492a2a37787d68d3ceb586c995715fa1668f07f338998ef7b1e\"},preview:{file:\"textures/creature-snow-wraith/preview.webp\",bytes:8238,sha256:\"b3ad0d3e51855f8bc66f7f2064d4a8e220b9bd6bbb85113ce7e12249f3b4c151\"}},runtime:{unlock:{level:1,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-snow-wraith/basecolor\",bytes:6634,sha256:\"b44309b17f88a5dfe5afb6ae11d38eff932fc4ca31cf57de57dd177c7ad690cc\"},normal:{entry:\"creature-snow-wraith/normal\",bytes:25340,sha256:\"c660422b765aca94ffbe27547a70572642798298148e138a175c775efb8d7b83\"},roughness:{entry:\"creature-snow-wraith/roughness\",bytes:11026,sha256:\"cf39931b6ecaacadf1f308870a1d6e1eb45a73e2b46e117f4b4e0a76d7b44ce1\"},height:{entry:\"creature-snow-wraith/height\",bytes:11568,sha256:\"6075c35c42067b2b476a0ba6aae9c727b946ae75b3afd5b6e168d9bd3f51385b\"},ao:{entry:\"creature-snow-wraith/ao\",bytes:4376,sha256:\"08233059a6af6b3c8c14077b17b6d7325895eda0b725b91e55fcead6f887c042\"},tintMask:{entry:\"creature-snow-wraith/tintMask\",bytes:47502,sha256:\"21fa7be4a5d63492a2a37787d68d3ceb586c995715fa1668f07f338998ef7b1e\"},preview:{entry:\"creature-snow-wraith/preview\",bytes:8238,sha256:\"b3ad0d3e51855f8bc66f7f2064d4a8e220b9bd6bbb85113ce7e12249f3b4c151\"}}}},{id:\"creature-moon-drift\",displayName:\"Moon Drift\",track:\"yoga\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Snow008A\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Snow008A\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-moon-drift/basecolor.webp\",bytes:1988,sha256:\"a0a0deef40357c248c3cd25b62c94196dee75bda282579f2f0af607091ecddd7\"},normal:{file:\"textures/creature-moon-drift/normal.webp\",bytes:19748,sha256:\"b41d538eb2be50037fc7646838ff397a30bad39e2c215c8e6ec0f7cc5aab3abb\"},roughness:{file:\"textures/creature-moon-drift/roughness.webp\",bytes:42334,sha256:\"940f50573bb0c93f00b1716d5fc8351aaea5cfd688248ab7e3b69555a68fedf4\"},height:{file:\"textures/creature-moon-drift/height.webp\",bytes:10336,sha256:\"00cda68ddb767c0578a91423d56f9f0ca59a30c24a5663c2c720a135a522f8dc\"},ao:{file:\"textures/creature-moon-drift/ao.webp\",bytes:5248,sha256:\"638072ac50033602f96649275c9d1ff2cc406c5a371fdaac55408ff476dd03a5\"},tintMask:{file:\"textures/creature-moon-drift/tint-mask.webp\",bytes:62850,sha256:\"2bea2a3b58ed3f2a1b1179cd07e38f556e4c592607461c32f4cba4f1dbb0d21d\"},preview:{file:\"textures/creature-moon-drift/preview.webp\",bytes:2558,sha256:\"425a6acfc362bfe037e494df1adb4d6676d8c3825a6dcd3d5a0d8f488bc65f87\"}},runtime:{unlock:{level:3,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-moon-drift/basecolor\",bytes:1988,sha256:\"a0a0deef40357c248c3cd25b62c94196dee75bda282579f2f0af607091ecddd7\"},normal:{entry:\"creature-moon-drift/normal\",bytes:19748,sha256:\"b41d538eb2be50037fc7646838ff397a30bad39e2c215c8e6ec0f7cc5aab3abb\"},roughness:{entry:\"creature-moon-drift/roughness\",bytes:42334,sha256:\"940f50573bb0c93f00b1716d5fc8351aaea5cfd688248ab7e3b69555a68fedf4\"},height:{entry:\"creature-moon-drift/height\",bytes:10336,sha256:\"00cda68ddb767c0578a91423d56f9f0ca59a30c24a5663c2c720a135a522f8dc\"},ao:{entry:\"creature-moon-drift/ao\",bytes:5248,sha256:\"638072ac50033602f96649275c9d1ff2cc406c5a371fdaac55408ff476dd03a5\"},tintMask:{entry:\"creature-moon-drift/tintMask\",bytes:62850,sha256:\"2bea2a3b58ed3f2a1b1179cd07e38f556e4c592607461c32f4cba4f1dbb0d21d\"},preview:{entry:\"creature-moon-drift/preview\",bytes:2558,sha256:\"425a6acfc362bfe037e494df1adb4d6676d8c3825a6dcd3d5a0d8f488bc65f87\"}}}},{id:\"creature-pearl-spirit\",displayName:\"Pearl Spirit\",track:\"yoga\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Onyx015\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Onyx015\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-pearl-spirit/basecolor.webp\",bytes:29558,sha256:\"ecd31972e0f2bd3dcbb56dd83966989cbaa724514cc57576769886ee69277bc4\"},normal:{file:\"textures/creature-pearl-spirit/normal.webp\",bytes:578,sha256:\"bc6c55f9b7c548eb294b544cffd95bead865725a62e2b07b26a954175f8f7de2\"},roughness:{file:\"textures/creature-pearl-spirit/roughness.webp\",bytes:2712,sha256:\"e4d14e77c9b45e27f077ba5a1a549ce863650380a48babb5c3b02a6d9322c2d8\"},height:{file:\"textures/creature-pearl-spirit/height.webp\",bytes:2632,sha256:\"5b01611a42e4e95216112bc1c263ad8c730fb412d74ed44f5e07085eecf24432\"},tintMask:{file:\"textures/creature-pearl-spirit/tint-mask.webp\",bytes:70938,sha256:\"000adcbc57cc83e8e2205c13dc421e9b8929d602006c2e3ca780725819dbf3c6\"},preview:{file:\"textures/creature-pearl-spirit/preview.webp\",bytes:36178,sha256:\"5494688e1ef1a80ddce772b1391f81c43c666d3595cc4dd567b807b393aafcda\"}},runtime:{unlock:{level:5,track:\"yoga\"},pack:\"track-yoga\",bundle:\"assets/yoga.m5bundle\",maps:{basecolor:{entry:\"creature-pearl-spirit/basecolor\",bytes:29558,sha256:\"ecd31972e0f2bd3dcbb56dd83966989cbaa724514cc57576769886ee69277bc4\"},normal:{entry:\"creature-pearl-spirit/normal\",bytes:578,sha256:\"bc6c55f9b7c548eb294b544cffd95bead865725a62e2b07b26a954175f8f7de2\"},roughness:{entry:\"creature-pearl-spirit/roughness\",bytes:2712,sha256:\"e4d14e77c9b45e27f077ba5a1a549ce863650380a48babb5c3b02a6d9322c2d8\"},height:{entry:\"creature-pearl-spirit/height\",bytes:2632,sha256:\"5b01611a42e4e95216112bc1c263ad8c730fb412d74ed44f5e07085eecf24432\"},tintMask:{entry:\"creature-pearl-spirit/tintMask\",bytes:70938,sha256:\"000adcbc57cc83e8e2205c13dc421e9b8929d602006c2e3ca780725819dbf3c6\"},preview:{entry:\"creature-pearl-spirit/preview\",bytes:36178,sha256:\"5494688e1ef1a80ddce772b1391f81c43c666d3595cc4dd567b807b393aafcda\"}}}},{id:\"creature-red-desert-scale\",displayName:\"Red Desert Scale\",track:\"martial-arts\",realm:\"fantasy\",rarity:\"rare\",sourceAssetId:\"Rock029\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Rock029\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-red-desert-scale/basecolor.webp\",bytes:51964,sha256:\"7160db9a779efc4fb62326be77ba443ee4ae5604884e1ed691e902e47323b156\"},normal:{file:\"textures/creature-red-desert-scale/normal.webp\",bytes:120276,sha256:\"450837f83a5ebbb2b9f31970d1c575fc18084358a7bf8fcf3912b5d5eddc3ec3\"},roughness:{file:\"textures/creature-red-desert-scale/roughness.webp\",bytes:28424,sha256:\"dd03959c9520cc2b6025073ef096c089b0f2d38b9f984ef1820d95caafc1992d\"},height:{file:\"textures/creature-red-desert-scale/height.webp\",bytes:8842,sha256:\"0e342c324ce19607da0bd50a966fa94b5c2e38fad0f37da848c7d666ed4518fe\"},ao:{file:\"textures/creature-red-desert-scale/ao.webp\",bytes:19082,sha256:\"7ab01e1e8509a7d83f58c00ae0f702834d99120a4070ed92cedb6710a802a766\"},tintMask:{file:\"textures/creature-red-desert-scale/tint-mask.webp\",bytes:83596,sha256:\"19a1bbac2eb458c1c6c36968566ac8e43e52cc62e5f57e9d1e47bfc81734e315\"},preview:{file:\"textures/creature-red-desert-scale/preview.webp\",bytes:57218,sha256:\"d84d2ea7022224cea294456c3c8656abf0979856274bcc64be90a8b1378b39d2\"}},runtime:{unlock:{level:1,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-red-desert-scale/basecolor\",bytes:51964,sha256:\"7160db9a779efc4fb62326be77ba443ee4ae5604884e1ed691e902e47323b156\"},normal:{entry:\"creature-red-desert-scale/normal\",bytes:120276,sha256:\"450837f83a5ebbb2b9f31970d1c575fc18084358a7bf8fcf3912b5d5eddc3ec3\"},roughness:{entry:\"creature-red-desert-scale/roughness\",bytes:28424,sha256:\"dd03959c9520cc2b6025073ef096c089b0f2d38b9f984ef1820d95caafc1992d\"},height:{entry:\"creature-red-desert-scale/height\",bytes:8842,sha256:\"0e342c324ce19607da0bd50a966fa94b5c2e38fad0f37da848c7d666ed4518fe\"},ao:{entry:\"creature-red-desert-scale/ao\",bytes:19082,sha256:\"7ab01e1e8509a7d83f58c00ae0f702834d99120a4070ed92cedb6710a802a766\"},tintMask:{entry:\"creature-red-desert-scale/tintMask\",bytes:83596,sha256:\"19a1bbac2eb458c1c6c36968566ac8e43e52cc62e5f57e9d1e47bfc81734e315\"},preview:{entry:\"creature-red-desert-scale/preview\",bytes:57218,sha256:\"d84d2ea7022224cea294456c3c8656abf0979856274bcc64be90a8b1378b39d2\"}}}},{id:\"creature-cave-drake\",displayName:\"Cave Drake\",track:\"martial-arts\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Rock035\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Rock035\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-cave-drake/basecolor.webp\",bytes:42954,sha256:\"891a196afba62375788c0b090019fd19941c04d25f9d760f135d57e60a1de00a\"},normal:{file:\"textures/creature-cave-drake/normal.webp\",bytes:126116,sha256:\"8283888c871969dfe2b35f0cebd352a66a2cc46ad64bcb2bb5c5f8663b9c146e\"},roughness:{file:\"textures/creature-cave-drake/roughness.webp\",bytes:37152,sha256:\"ad45c8e7102239aef39f0154e1c57b3932742255f5799c0074a8b5435cecc5c5\"},height:{file:\"textures/creature-cave-drake/height.webp\",bytes:10778,sha256:\"bef40f1f39e9bf0e716195a417fa0fcaeb67ed09ec43b2ee5fb59030648e34d4\"},ao:{file:\"textures/creature-cave-drake/ao.webp\",bytes:20824,sha256:\"e085d1a569564fdbe39a9dd18fa133a14ffa83117e8cdda10425bace18a70bd6\"},tintMask:{file:\"textures/creature-cave-drake/tint-mask.webp\",bytes:59714,sha256:\"febea8d8da737dd8127c8049724d22d621219c483682ded32a4169c1f651c63a\"},preview:{file:\"textures/creature-cave-drake/preview.webp\",bytes:52250,sha256:\"fd405d3986dd0eea39be9f341ec58591aa6e6ab66e25787adf3b2e16c62e634a\"}},runtime:{unlock:{level:3,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-cave-drake/basecolor\",bytes:42954,sha256:\"891a196afba62375788c0b090019fd19941c04d25f9d760f135d57e60a1de00a\"},normal:{entry:\"creature-cave-drake/normal\",bytes:126116,sha256:\"8283888c871969dfe2b35f0cebd352a66a2cc46ad64bcb2bb5c5f8663b9c146e\"},roughness:{entry:\"creature-cave-drake/roughness\",bytes:37152,sha256:\"ad45c8e7102239aef39f0154e1c57b3932742255f5799c0074a8b5435cecc5c5\"},height:{entry:\"creature-cave-drake/height\",bytes:10778,sha256:\"bef40f1f39e9bf0e716195a417fa0fcaeb67ed09ec43b2ee5fb59030648e34d4\"},ao:{entry:\"creature-cave-drake/ao\",bytes:20824,sha256:\"e085d1a569564fdbe39a9dd18fa133a14ffa83117e8cdda10425bace18a70bd6\"},tintMask:{entry:\"creature-cave-drake/tintMask\",bytes:59714,sha256:\"febea8d8da737dd8127c8049724d22d621219c483682ded32a4169c1f651c63a\"},preview:{entry:\"creature-cave-drake/preview\",bytes:52250,sha256:\"fd405d3986dd0eea39be9f341ec58591aa6e6ab66e25787adf3b2e16c62e634a\"}}}},{id:\"creature-sandstone-titan\",displayName:\"Sandstone Titan\",track:\"martial-arts\",realm:\"fantasy\",rarity:\"legendary\",sourceAssetId:\"Rock061\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Rock061\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-sandstone-titan/basecolor.webp\",bytes:19630,sha256:\"bb2d67e9addc03ae6dd1052db82b6f36d03d5af77cc2a63d48921844b652a3e0\"},normal:{file:\"textures/creature-sandstone-titan/normal.webp\",bytes:59070,sha256:\"a9f2c10deb50d06074111b4f3cf220edb876633fae81c239f1c99718d1d07d46\"},roughness:{file:\"textures/creature-sandstone-titan/roughness.webp\",bytes:55850,sha256:\"d32bb23773fd03bedc81edeec043c823319e295e48198016095ff29ff988c373\"},height:{file:\"textures/creature-sandstone-titan/height.webp\",bytes:8100,sha256:\"cf13bbcf1fad8c96f467f178d905fb55f4d254fdcc8fa52f506f80de8362f264\"},ao:{file:\"textures/creature-sandstone-titan/ao.webp\",bytes:15348,sha256:\"454cc3f34a0c059b046ee536585296a9195bb1259bc1ebb98b3377aeb19ad750\"},tintMask:{file:\"textures/creature-sandstone-titan/tint-mask.webp\",bytes:41274,sha256:\"168d8de923125957c85b30e3e378b0586a7fd91d270a8c19042bea518d1d2529\"},preview:{file:\"textures/creature-sandstone-titan/preview.webp\",bytes:24198,sha256:\"b379980f2c2907823755986994431b2fbe0d8e2a254616a89cefa1c3f1a810c3\"}},runtime:{unlock:{level:5,track:\"martial-arts\"},pack:\"track-martial-arts\",bundle:\"assets/martial-arts.m5bundle\",maps:{basecolor:{entry:\"creature-sandstone-titan/basecolor\",bytes:19630,sha256:\"bb2d67e9addc03ae6dd1052db82b6f36d03d5af77cc2a63d48921844b652a3e0\"},normal:{entry:\"creature-sandstone-titan/normal\",bytes:59070,sha256:\"a9f2c10deb50d06074111b4f3cf220edb876633fae81c239f1c99718d1d07d46\"},roughness:{entry:\"creature-sandstone-titan/roughness\",bytes:55850,sha256:\"d32bb23773fd03bedc81edeec043c823319e295e48198016095ff29ff988c373\"},height:{entry:\"creature-sandstone-titan/height\",bytes:8100,sha256:\"cf13bbcf1fad8c96f467f178d905fb55f4d254fdcc8fa52f506f80de8362f264\"},ao:{entry:\"creature-sandstone-titan/ao\",bytes:15348,sha256:\"454cc3f34a0c059b046ee536585296a9195bb1259bc1ebb98b3377aeb19ad750\"},tintMask:{entry:\"creature-sandstone-titan/tintMask\",bytes:41274,sha256:\"168d8de923125957c85b30e3e378b0586a7fd91d270a8c19042bea518d1d2529\"},preview:{entry:\"creature-sandstone-titan/preview\",bytes:24198,sha256:\"b379980f2c2907823755986994431b2fbe0d8e2a254616a89cefa1c3f1a810c3\"}}}},{id:\"creature-neon-mainframe\",displayName:\"Neon Mainframe\",track:\"cardio\",realm:\"sci-fi\",rarity:\"rare\",sourceAssetId:\"Chip002\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Chip002\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-neon-mainframe/basecolor.webp\",bytes:56744,sha256:\"7af9b36dc24154d4dfe3b151dcafe44c1488643845a380e97d44c61d495c4b03\"},normal:{file:\"textures/creature-neon-mainframe/normal.webp\",bytes:37362,sha256:\"413a59522d8e711071777b6a026805d22fb848881e396ae2e55892c47d3e621e\"},roughness:{file:\"textures/creature-neon-mainframe/roughness.webp\",bytes:41338,sha256:\"911155142f0e2266a6df466e0993e44b5039ac75e0d3489e37e0cffaa49df930\"},height:{file:\"textures/creature-neon-mainframe/height.webp\",bytes:33104,sha256:\"d1a60696213f4e3bb1af2d335aa37c7358fb9efa8877cd4b465422cba460ddcd\"},metalness:{file:\"textures/creature-neon-mainframe/metalness.webp\",bytes:45012,sha256:\"d8294af74841524440d65a0fc0390f11fb1e46fa9086b5adcae23f00e760b7bd\"},tintMask:{file:\"textures/creature-neon-mainframe/tint-mask.webp\",bytes:50140,sha256:\"e0c65204a15a3f678c15e017fb84817d1d2f8e7f7184450cd85034303ad844e9\"},preview:{file:\"textures/creature-neon-mainframe/preview.webp\",bytes:61118,sha256:\"6b904429406f8ff2f6decf39552837fbb1a69b51f6bd1f84ac1ae51b7b1ece44\"}},runtime:{unlock:{level:1,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-neon-mainframe/basecolor\",bytes:56744,sha256:\"7af9b36dc24154d4dfe3b151dcafe44c1488643845a380e97d44c61d495c4b03\"},normal:{entry:\"creature-neon-mainframe/normal\",bytes:37362,sha256:\"413a59522d8e711071777b6a026805d22fb848881e396ae2e55892c47d3e621e\"},roughness:{entry:\"creature-neon-mainframe/roughness\",bytes:41338,sha256:\"911155142f0e2266a6df466e0993e44b5039ac75e0d3489e37e0cffaa49df930\"},height:{entry:\"creature-neon-mainframe/height\",bytes:33104,sha256:\"d1a60696213f4e3bb1af2d335aa37c7358fb9efa8877cd4b465422cba460ddcd\"},metalness:{entry:\"creature-neon-mainframe/metalness\",bytes:45012,sha256:\"d8294af74841524440d65a0fc0390f11fb1e46fa9086b5adcae23f00e760b7bd\"},tintMask:{entry:\"creature-neon-mainframe/tintMask\",bytes:50140,sha256:\"e0c65204a15a3f678c15e017fb84817d1d2f8e7f7184450cd85034303ad844e9\"},preview:{entry:\"creature-neon-mainframe/preview\",bytes:61118,sha256:\"6b904429406f8ff2f6decf39552837fbb1a69b51f6bd1f84ac1ae51b7b1ece44\"}}}},{id:\"creature-reactor-grid\",displayName:\"Reactor Grid\",track:\"cardio\",realm:\"sci-fi\",rarity:\"epic\",sourceAssetId:\"Chip004\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Chip004\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-reactor-grid/basecolor.webp\",bytes:68780,sha256:\"87f6c7fad31ff2a102dd430f1b8e6a37efb6ea41d28c7c43ecd96a8ecff4ba87\"},normal:{file:\"textures/creature-reactor-grid/normal.webp\",bytes:30258,sha256:\"29097e24c7f4977faa6b8de2cab3968aeb0d786f3304c5c30392e7217afa944a\"},roughness:{file:\"textures/creature-reactor-grid/roughness.webp\",bytes:28938,sha256:\"b259990ff0909332bf236b4be50db3aa119887ebcd2f9d59d28c20e0cf529da1\"},height:{file:\"textures/creature-reactor-grid/height.webp\",bytes:18820,sha256:\"2b43a252f9398122436a011c785fb684ef15b181442db3c784aebda559e57bb4\"},metalness:{file:\"textures/creature-reactor-grid/metalness.webp\",bytes:8980,sha256:\"07523450a21492207c75694b9a6413499417262e6439b07ddd21604ac728d05c\"},tintMask:{file:\"textures/creature-reactor-grid/tint-mask.webp\",bytes:50226,sha256:\"730ad1404d4067b92705945e94980c58f8e069e3badf53f288b0559f27d2a386\"},preview:{file:\"textures/creature-reactor-grid/preview.webp\",bytes:70556,sha256:\"b8d73dfa85b4af6399099734708bd705cfe9d9cf88942a6844a737c0a7c9e3f2\"}},runtime:{unlock:{level:3,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-reactor-grid/basecolor\",bytes:68780,sha256:\"87f6c7fad31ff2a102dd430f1b8e6a37efb6ea41d28c7c43ecd96a8ecff4ba87\"},normal:{entry:\"creature-reactor-grid/normal\",bytes:30258,sha256:\"29097e24c7f4977faa6b8de2cab3968aeb0d786f3304c5c30392e7217afa944a\"},roughness:{entry:\"creature-reactor-grid/roughness\",bytes:28938,sha256:\"b259990ff0909332bf236b4be50db3aa119887ebcd2f9d59d28c20e0cf529da1\"},height:{entry:\"creature-reactor-grid/height\",bytes:18820,sha256:\"2b43a252f9398122436a011c785fb684ef15b181442db3c784aebda559e57bb4\"},metalness:{entry:\"creature-reactor-grid/metalness\",bytes:8980,sha256:\"07523450a21492207c75694b9a6413499417262e6439b07ddd21604ac728d05c\"},tintMask:{entry:\"creature-reactor-grid/tintMask\",bytes:50226,sha256:\"730ad1404d4067b92705945e94980c58f8e069e3badf53f288b0559f27d2a386\"},preview:{entry:\"creature-reactor-grid/preview\",bytes:70556,sha256:\"b8d73dfa85b4af6399099734708bd705cfe9d9cf88942a6844a737c0a7c9e3f2\"}}}},{id:\"creature-quantum-core\",displayName:\"Quantum Core\",track:\"cardio\",realm:\"sci-fi\",rarity:\"legendary\",sourceAssetId:\"Chip007\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Chip007\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-quantum-core/basecolor.webp\",bytes:51286,sha256:\"60c77e1451ddd9d4acf761146d68273493a07ef74320e893906f896883e7f933\"},normal:{file:\"textures/creature-quantum-core/normal.webp\",bytes:31990,sha256:\"adf7da0427d32ab38dace38c6656e873a6b9e345d6f2a41c42cfc640d437c46a\"},roughness:{file:\"textures/creature-quantum-core/roughness.webp\",bytes:31284,sha256:\"d489ea08a4eafc75c5c7c1af6cb535e6d56516906f9a2210b0313407b48713fd\"},height:{file:\"textures/creature-quantum-core/height.webp\",bytes:29580,sha256:\"7d44a79d77ba776128ff8836156b73f010c56ff8543d7fe1bf6994f21686efd7\"},metalness:{file:\"textures/creature-quantum-core/metalness.webp\",bytes:38108,sha256:\"2845ad0fae0dc3dd3c07aafe5e1758fb322dea33ec636e8036cebbb3f5e7c66b\"},tintMask:{file:\"textures/creature-quantum-core/tint-mask.webp\",bytes:41968,sha256:\"5ec244d327e08f7f5cc6022500a829fb2ce697a6749506ca09de5c832efc8493\"},preview:{file:\"textures/creature-quantum-core/preview.webp\",bytes:56764,sha256:\"51f0687bf78e65155d2e6e156e21bb6c2ce6f64b35fc7e7e9623fc94752b52f5\"}},runtime:{unlock:{level:5,track:\"cardio\"},pack:\"track-cardio\",bundle:\"assets/cardio.m5bundle\",maps:{basecolor:{entry:\"creature-quantum-core/basecolor\",bytes:51286,sha256:\"60c77e1451ddd9d4acf761146d68273493a07ef74320e893906f896883e7f933\"},normal:{entry:\"creature-quantum-core/normal\",bytes:31990,sha256:\"adf7da0427d32ab38dace38c6656e873a6b9e345d6f2a41c42cfc640d437c46a\"},roughness:{entry:\"creature-quantum-core/roughness\",bytes:31284,sha256:\"d489ea08a4eafc75c5c7c1af6cb535e6d56516906f9a2210b0313407b48713fd\"},height:{entry:\"creature-quantum-core/height\",bytes:29580,sha256:\"7d44a79d77ba776128ff8836156b73f010c56ff8543d7fe1bf6994f21686efd7\"},metalness:{entry:\"creature-quantum-core/metalness\",bytes:38108,sha256:\"2845ad0fae0dc3dd3c07aafe5e1758fb322dea33ec636e8036cebbb3f5e7c66b\"},tintMask:{entry:\"creature-quantum-core/tintMask\",bytes:41968,sha256:\"5ec244d327e08f7f5cc6022500a829fb2ce697a6749506ca09de5c832efc8493\"},preview:{entry:\"creature-quantum-core/preview\",bytes:56764,sha256:\"51f0687bf78e65155d2e6e156e21bb6c2ce6f64b35fc7e7e9623fc94752b52f5\"}}}},{id:\"creature-celestial-mosaic\",displayName:\"Celestial Mosaic\",track:\"meditation\",realm:\"hybrid\",rarity:\"rare\",sourceAssetId:\"Tiles070\",collection:\"creature-celestial-rift\",collectionSlot:1,sourceUrl:\"https://ambientcg.com/a/Tiles070\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-celestial-mosaic/basecolor.webp\",bytes:72806,sha256:\"2e293d1642aa668793919b7d46bb50e94bcc36c0ce5d1f775463269a949f0978\"},normal:{file:\"textures/creature-celestial-mosaic/normal.webp\",bytes:40154,sha256:\"995e3446cf6f85eb57d7925922e187fc497a69355b82dfd069bcbd3f0029a175\"},roughness:{file:\"textures/creature-celestial-mosaic/roughness.webp\",bytes:47808,sha256:\"29cbfb28025d5943765276c118b38d186b9294c6458bb6dc7a7da886ed989dd3\"},height:{file:\"textures/creature-celestial-mosaic/height.webp\",bytes:38486,sha256:\"15cace7739e375a6dad5f5251d1b4e9cc8495abbba9f1560844e272cc5401ef0\"},ao:{file:\"textures/creature-celestial-mosaic/ao.webp\",bytes:46104,sha256:\"0da24064e9f490c342bf09e2149b58945e0ef0c555aa95b8c542615cf82b9fc1\"},tintMask:{file:\"textures/creature-celestial-mosaic/tint-mask.webp\",bytes:63262,sha256:\"c73737938011dfd0894b37e613d9de159b672e2813a34cd0f134080961935268\"},preview:{file:\"textures/creature-celestial-mosaic/preview.webp\",bytes:76982,sha256:\"06b94f2aed6383bdcd79769cc0649b71ac08fb0dcdf26d7aa5c578f66ff974ca\"}},runtime:{unlock:{level:1,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-celestial-mosaic/basecolor\",bytes:72806,sha256:\"2e293d1642aa668793919b7d46bb50e94bcc36c0ce5d1f775463269a949f0978\"},normal:{entry:\"creature-celestial-mosaic/normal\",bytes:40154,sha256:\"995e3446cf6f85eb57d7925922e187fc497a69355b82dfd069bcbd3f0029a175\"},roughness:{entry:\"creature-celestial-mosaic/roughness\",bytes:47808,sha256:\"29cbfb28025d5943765276c118b38d186b9294c6458bb6dc7a7da886ed989dd3\"},height:{entry:\"creature-celestial-mosaic/height\",bytes:38486,sha256:\"15cace7739e375a6dad5f5251d1b4e9cc8495abbba9f1560844e272cc5401ef0\"},ao:{entry:\"creature-celestial-mosaic/ao\",bytes:46104,sha256:\"0da24064e9f490c342bf09e2149b58945e0ef0c555aa95b8c542615cf82b9fc1\"},tintMask:{entry:\"creature-celestial-mosaic/tintMask\",bytes:63262,sha256:\"c73737938011dfd0894b37e613d9de159b672e2813a34cd0f134080961935268\"},preview:{entry:\"creature-celestial-mosaic/preview\",bytes:76982,sha256:\"06b94f2aed6383bdcd79769cc0649b71ac08fb0dcdf26d7aa5c578f66ff974ca\"}}}},{id:\"creature-shellborn\",displayName:\"Shellborn\",track:\"meditation\",realm:\"fantasy\",rarity:\"epic\",sourceAssetId:\"Ground060\",collection:\"creature-celestial-rift\",collectionSlot:2,sourceUrl:\"https://ambientcg.com/a/Ground060\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-shellborn/basecolor.webp\",bytes:9684,sha256:\"2ffb18fed343bdcf0b2ba3d4b0dea9e8e53711fb266563af356fc940dc129a40\"},normal:{file:\"textures/creature-shellborn/normal.webp\",bytes:23222,sha256:\"d1a9e0f90dce9c6a37afe8819f96ce7af37ca19f8a3ed035bb2f2dc262695f83\"},roughness:{file:\"textures/creature-shellborn/roughness.webp\",bytes:8118,sha256:\"c7356a52eed60b3dd71af8ef399b497c5a984b1f076df5c12f07e1a2a57a3971\"},height:{file:\"textures/creature-shellborn/height.webp\",bytes:17122,sha256:\"7731dee5c6bafef91432e5df689468c0bd108baee671021effef7fdd6fed8545\"},ao:{file:\"textures/creature-shellborn/ao.webp\",bytes:9036,sha256:\"8bb1e0ef1415f81b31b967d8df9c22dbcad3160a17e7410fcd85ad5819c7c60e\"},tintMask:{file:\"textures/creature-shellborn/tint-mask.webp\",bytes:50694,sha256:\"655e52806a1abc2750780ffa28d94b85cd1ebef231624f83b8ff41c345960e89\"},preview:{file:\"textures/creature-shellborn/preview.webp\",bytes:12672,sha256:\"3f5d1a52e02032ce1513807c7e03898af630842323e99f12948f40da880c23d3\"}},runtime:{unlock:{level:3,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-shellborn/basecolor\",bytes:9684,sha256:\"2ffb18fed343bdcf0b2ba3d4b0dea9e8e53711fb266563af356fc940dc129a40\"},normal:{entry:\"creature-shellborn/normal\",bytes:23222,sha256:\"d1a9e0f90dce9c6a37afe8819f96ce7af37ca19f8a3ed035bb2f2dc262695f83\"},roughness:{entry:\"creature-shellborn/roughness\",bytes:8118,sha256:\"c7356a52eed60b3dd71af8ef399b497c5a984b1f076df5c12f07e1a2a57a3971\"},height:{entry:\"creature-shellborn/height\",bytes:17122,sha256:\"7731dee5c6bafef91432e5df689468c0bd108baee671021effef7fdd6fed8545\"},ao:{entry:\"creature-shellborn/ao\",bytes:9036,sha256:\"8bb1e0ef1415f81b31b967d8df9c22dbcad3160a17e7410fcd85ad5819c7c60e\"},tintMask:{entry:\"creature-shellborn/tintMask\",bytes:50694,sha256:\"655e52806a1abc2750780ffa28d94b85cd1ebef231624f83b8ff41c345960e89\"},preview:{entry:\"creature-shellborn/preview\",bytes:12672,sha256:\"3f5d1a52e02032ce1513807c7e03898af630842323e99f12948f40da880c23d3\"}}}},{id:\"creature-cracked-starlight\",displayName:\"Cracked Starlight\",track:\"meditation\",realm:\"hybrid\",rarity:\"legendary\",sourceAssetId:\"Paint002\",collection:\"creature-celestial-rift\",collectionSlot:3,sourceUrl:\"https://ambientcg.com/a/Paint002\",license:\"CC0-1.0\",author:\"ambientCG\",resolution:512,maps:{basecolor:{file:\"textures/creature-cracked-starlight/basecolor.webp\",bytes:2308,sha256:\"212ef8ce6348eab7babafd1302f6de8e0ff645ded3417c37b0c14c368bd5d3c3\"},normal:{file:\"textures/creature-cracked-starlight/normal.webp\",bytes:36906,sha256:\"7363169a2812312622da8ea9802490d0f121523a63f797d7da80f3e6599b06cc\"},roughness:{file:\"textures/creature-cracked-starlight/roughness.webp\",bytes:27138,sha256:\"e34af0b29b2da65da14698dd33851295fbd1c00d02220613487de2bab8cb15a1\"},height:{file:\"textures/creature-cracked-starlight/height.webp\",bytes:21122,sha256:\"d6bceaf4d67569f417fcef6bd23e17458e885bbd77faff67b77c5254a50fc7a0\"},ao:{file:\"textures/creature-cracked-starlight/ao.webp\",bytes:39506,sha256:\"3fbaf579d17290d907480db250ee33863f169674e1f57f66a51b05d725e54f02\"},tintMask:{file:\"textures/creature-cracked-starlight/tint-mask.webp\",bytes:37962,sha256:\"92b4eed22f7d0a3af5233adb61c825b286e7553f65eafdc0557de5f1e8d2d9a2\"},preview:{file:\"textures/creature-cracked-starlight/preview.webp\",bytes:2858,sha256:\"07c798d4bde111c432f31209c9a960b7525f34922813203a1be22d5220493fe1\"}},runtime:{unlock:{level:5,track:\"meditation\"},pack:\"track-meditation\",bundle:\"assets/meditation.m5bundle\",maps:{basecolor:{entry:\"creature-cracked-starlight/basecolor\",bytes:2308,sha256:\"212ef8ce6348eab7babafd1302f6de8e0ff645ded3417c37b0c14c368bd5d3c3\"},normal:{entry:\"creature-cracked-starlight/normal\",bytes:36906,sha256:\"7363169a2812312622da8ea9802490d0f121523a63f797d7da80f3e6599b06cc\"},roughness:{entry:\"creature-cracked-starlight/roughness\",bytes:27138,sha256:\"e34af0b29b2da65da14698dd33851295fbd1c00d02220613487de2bab8cb15a1\"},height:{entry:\"creature-cracked-starlight/height\",bytes:21122,sha256:\"d6bceaf4d67569f417fcef6bd23e17458e885bbd77faff67b77c5254a50fc7a0\"},ao:{entry:\"creature-cracked-starlight/ao\",bytes:39506,sha256:\"3fbaf579d17290d907480db250ee33863f169674e1f57f66a51b05d725e54f02\"},tintMask:{entry:\"creature-cracked-starlight/tintMask\",bytes:37962,sha256:\"92b4eed22f7d0a3af5233adb61c825b286e7553f65eafdc0557de5f1e8d2d9a2\"},preview:{entry:\"creature-cracked-starlight/preview\",bytes:2858,sha256:\"07c798d4bde111c432f31209c9a960b7525f34922813203a1be22d5220493fe1\"}}}}]};var Pa=1.1;var V=Object.freeze([{id:\"strider\",name:\"Strider\",track:\"chest\",bosses:6},{id:\"ringer\",name:\"Ringer\",track:\"quads\",bosses:5},{id:\"manyarm\",name:\"Manyarm\",track:\"glutes\",bosses:5},{id:\"wedge\",name:\"Wedge\",track:\"arms-shoulders\",bosses:5},{id:\"warden\",name:\"Warden\",track:null,bosses:1},{id:\"blob\",name:\"Blob\",track:\"yoga\",bosses:4},{id:\"cap\",name:\"Cap\",track:\"martial-arts\",bosses:3},{id:\"stalk\",name:\"Stalk\",track:\"cardio\",bosses:4},{id:\"tanka\",name:\"Tanka\",track:\"meditation\",bosses:4},{id:\"lume\",name:\"Lume\",track:null,bosses:1}]),ea=5,xe=Object.freeze(V.flatMap(e=>Array.from({length:e.bosses},(a,t)=>({id:`${e.id}-${t+1}`,name:e.bosses>1?`${e.name} ${t+1}`:e.name,row:e.id,track:e.track,index:t+1})))),M=Object.freeze({chest:{circuit:\"chest\",catalog:\"chest\",family:\"push\",name:\"Chest\",palette:\"pal-01\"},quads:{circuit:\"legs\",catalog:\"quads\",family:\"legs\",name:\"Quads\",palette:\"pal-02\"},glutes:{circuit:\"hips\",catalog:\"glutes\",family:\"legs\",name:\"Glutes\",palette:\"pal-03\"},\"arms-shoulders\":{circuit:\"shoulders\",catalog:\"arms\",family:\"push\",name:\"Arms & Shoulders\",palette:\"pal-04\"},yoga:{circuit:\"yoga\",catalog:\"yoga\",family:\"flow\",name:\"Yoga\",palette:\"pal-05\"},\"martial-arts\":{circuit:\"martial-arts\",catalog:\"martial-arts\",family:\"motion\",name:\"Martial Arts\",palette:\"pal-06\"},cardio:{circuit:\"cardio\",catalog:\"cardio\",family:\"motion\",name:\"Cardio\",palette:\"pal-07\"},meditation:{circuit:\"meditation\",catalog:\"meditation\",family:\"meditation\",name:\"Meditation\",palette:\"pal-08\"}}),aa=Object.freeze({push:\"pal-09\",legs:\"pal-10\",motion:\"pal-11\"}),ur=Object.freeze(Ta.skins.map(e=>Object.freeze({kind:\"creature-skin\",id:e.id,name:e.displayName,line:`${e.realm} creature finish \\xB7 ${e.rarity}`,track:e.track,level:e.runtime.unlock.level,pack:e.runtime.pack,collection:e.collection}))),Ba=[\"supportive\",\"direct\",\"analytical\",\"playful\",\"calm\",\"mom\"],fr=Object.freeze(Object.values(M).flatMap(({catalog:e},a)=>[3,5].map((t,r)=>{let s=Ba[(a*2+r)%Ba.length];return Object.freeze({id:`ship-${s}`,ship:s,name:Ze(s).name,track:e,level:t})}))),Da=[[\"chest-w1\",\"Glove on a Stick\",\"For winning arguments with the air.\"],[\"chest-w2\",\"Chrome Bar Mace\",\"It benches you.\"],[\"arms-w1\",\"Dumbbellchucks\",\"Twice the dumbbell, half the coordination.\"],[\"arms-w2\",\"Pull-Up Staff\",\"For reaching the top shelf of victory.\"],[\"quads-w1\",\"Squat-Rack Axe\",\"Leg day has a new ambassador.\"],[\"quads-w2\",\"Kettlebell Flail\",\"Swings hard, asks questions never.\"],[\"glutes-w1\",\"Band Slingshot\",\"Resistance is futile. Literally.\"],[\"glutes-w2\",\"Hip-Thrust Hammer\",\"Bridges: now with consequences.\"],[\"yoga-w1\",\"Mat Bo Staff\",\"Rolled with intention. Swung with more.\"],[\"yoga-w2\",\"Block Gauntlets\",\"Namaste out of the way.\"],[\"martial-arts-w1\",\"Black-Belt Whip\",\"It earned its own belt.\"],[\"martial-arts-w2\",\"Dummy Club\",\"The dummy saw it coming. Still lost.\"],[\"cardio-w1\",\"Jump-Rope Lasso\",\"For roping runaway heart rates.\"],[\"cardio-w2\",\"Shoe Boomerang\",\"It always comes back. Like soreness.\"],[\"meditation-w1\",\"Singing-Bowl Aegis\",\"Om. Also, clang.\"],[\"meditation-w2\",\"Incense Wand\",\"Smells like victory. Allegedly.\"]],Ua=[[\"chest-plate-steel\",\"Plate Steel\",\"Now with 40% more clank.\"],[\"chest-rubber-grip\",\"Rubber Grip\",\"For hands that mean business.\"],[\"chest-chain-mail\",\"Chain Mail\",\"Medieval. But make it cardio.\"],[\"quads-track-rubber\",\"Track Rubber\",\"Smells faintly of starting blocks.\"],[\"quads-denim\",\"Denim\",\"For legs that never skip jeans either.\"],[\"quads-hex-tread\",\"Hex Tread\",\"Grip: gecko-grade.\"],[\"glutes-sweatshirt-fleece\",\"Sweatshirt Fleece\",\"Like a hug from laundry day.\"],[\"glutes-quilted\",\"Quilted\",\"Grandma approved. Gains approved harder.\"],[\"glutes-peach\",\"Speckled\",\"Ripe. Do not squeeze the coach.\"],[\"arms-hammered-bronze\",\"Hammered Bronze\",\"Shiny. Slightly dented. Like all of us.\"],[\"arms-rope\",\"Fine Stripe\",\"Climb every metaphor.\"],[\"arms-leather\",\"Snake Skin\",\"Broken in. Like you, after set three.\"],[\"yoga-cork\",\"Holey\",\"Floats. Like your downward dog.\"],[\"yoga-woven-mat\",\"Woven Mat\",\"Hand-woven by extremely calm spiders.\"],[\"yoga-petal\",\"Petal\",\"Delicate. Unlike your warrior two.\"],[\"martial-arts-canvas-gi\",\"Graph Paper\",\"It has seen things. Mostly laundry.\"],[\"martial-arts-bamboo\",\"Bamboo\",\"Bends. Does not break. Unlike resolutions.\"],[\"martial-arts-dragon-scale\",\"Dragon Scale\",\"The dragon is fine. It donated.\"],[\"cardio-mesh\",\"Cool Graph Paper\",\"Maximum airflow. Minimum excuses.\"],[\"cardio-terry-cloth\",\"Terry Cloth\",\"Absorbs sweat and bad decisions.\"],[\"cardio-pebble-path\",\"Pebble Path\",\"A tiny trail, wherever you go.\"],[\"meditation-sand-garden\",\"Wiggles\",\"Raked by a very patient rake.\"],[\"meditation-river-stone\",\"River Stone\",\"Smooth. Unbothered. Goals.\"],[\"meditation-moss\",\"Moss\",\"Grows on you. Literally, now.\"]],ta=Object.freeze({\"chest-rubber-grip\":[\"legacy-15\",\"Magma\",\"Runs hot. Cools never.\"],\"glutes-sweatshirt-fleece\":[\"legacy-13\",\"Stone Golem\",\"Built slow. Built to last.\"],\"arms-rope\":[\"legacy-14\",\"Crystal\",\"Clear eyes. Sharp facets.\"],\"arms-leather\":[\"legacy-8\",\"Spectral\",\"Here in spirit. Also in body.\"],\"yoga-cork\":[\"legacy-20\",\"Fluffy\",\"Maximum floof. Minimum mercy.\"],\"yoga-woven-mat\":[\"legacy-21\",\"Jelly\",\"Wobbles. Never falls.\"],\"cardio-terry-cloth\":[\"legacy-16\",\"Glacial\",\"Cool under pressure. Very cool.\"]}),mr={push:[\"Forged from lost remote controls.\",\"For the comfiest conqueror.\"],legs:[\"Always moving. Never in a hurry.\",\"Polished by a thousand commutes.\"],motion:[\"Nine more minutes. Forever.\",\"Shiny. Like your intentions at 6 AM.\"],flow:[\"Eight arms. Zero flexibility.\",\"Breathe in. The kraken breathes out.\"],meditation:[\"99+ unread. All of them urgent.\",\"Silent. At last.\"]},hr={push:\"It followed you home from the gym. Keep it.\",legs:\"It never skips leg day. It never skips anything.\",motion:\"Fast. Loud. Naps hard.\",flow:\"Bends in ways physics dislikes.\",meditation:\"It hums when you breathe. Do not ask how.\"},A=(e,[a,t,r])=>({kind:e,id:a,name:t,line:r}),X=(e,a)=>({kind:\"reward-pack\",id:`reward-pack:${e}:${a}`,tier:e,name:`${e[0].toUpperCase()+e.slice(1)} Pack`,line:\"Open for one random cosmetic.\"}),Ga=Object.freeze([\"Mortal\",\"Verdant\",\"Mycelial\",\"Chitin\",\"Reptilian\",\"Abyssal\",\"Coral\",\"Skeletal\",\"Spectral\",\"Infernal\",\"Celestial\",\"Voidborn\",\"Eldritch\",\"Stone Golem\",\"Crystal\",\"Magma\",\"Glacial\",\"Stormcharged\",\"Clockwork Robot\",\"Neon Synth\",\"Fluffy\",\"Jelly\",\"Baby\"]),qa=()=>[...Ua.map(e=>A(\"texture\",e)),...[[\"opal-jelly\",\"Opal Jelly\"],[\"bubble-glass\",\"Bubble Glass\"],[\"prism-crystal\",\"Prism Crystal\"],[\"holo-foil\",\"Holographic Foil\"],[\"glitter-resin\",\"Glitter Resin\"],[\"galaxy-geode\",\"Galaxy Geode\"],[\"caustic-slime\",\"Caustic Slime\"],[\"blister-hide\",\"Blister Hide\"],[\"rotten-rind\",\"Rotten Rind\"],[\"parasite-nest\",\"Parasite Nest\"],[\"exposed-sinew\",\"Exposed Sinew\"],[\"abyssal-maw\",\"Abyssal Maw\"],[\"circuit-alloy\",\"Circuit Alloy\"],[\"servo-armor\",\"Servo Armor\"],[\"chrome-rib\",\"Chrome Rib\"],[\"carbon-mech\",\"Carbon Mech\"],[\"hazard-panel\",\"Hazard Panel\"],[\"reactor-glass\",\"Reactor Glass\"]].map(([e,a])=>A(\"texture\",[e,a,\"\"])),...Ga.map((e,a)=>A(\"texture\",[`legacy-${a}`,e,\"\"])),A(\"texture\",[\"coach-64-bit\",\"64-bit Pixel Finish\",\"A pixel finish for a coach with a boss skin.\"])].filter(e=>!ie.includes(e.id)&&!j.includes(e.id)),ra=Object.freeze([\"#060409\",\"#ffffff\",\"#7f7d78\",\"#ff3b30\",\"#ff8a2a\",\"#ffd100\",\"#2bd97c\",\"#008c8c\",\"#2454d6\",\"#6a2bd9\",\"#f59ec4\",\"#7a5530\",\"#c4a77d\",\"#0b1a45\",\"#9fe2bf\"]),ho=Object.freeze([\"Black\",\"White\",\"Grey\",\"Red\",\"Orange\",\"Yellow\",\"Green\",\"Teal\",\"Blue\",\"Purple\",\"Pink\",\"Brown\",\"Tan\",\"Navy\",\"Mint\"]),$a=()=>[...le.map(e=>({kind:\"palette\",id:e.id,name:e.name})),...[[\"default-slate\",\"Slate\",\"#8b8f9a\"],[\"default-clay\",\"Warm Clay\",\"#b7a68e\"],[\"default-ruby\",\"Ruby\",\"#a23b4a\"],[\"default-sapphire\",\"Sapphire\",\"#2d5aa0\"],[\"default-moss\",\"Moss\",\"#4c7a3f\"],[\"default-gold\",\"Gold\",\"#c9a13a\"],[\"default-charcoal\",\"Charcoal\",\"#333238\"],[\"default-blush\",\"Blush\",\"#d98fa0\"]].map(([e,a,t])=>({kind:\"color\",id:e,name:a,hex:t})),...Ga.map((e,a)=>({kind:\"color\",id:`legacy-color-${a}`,name:`${e} (original)`,hex:a?$[a].primary:\"#7946aa\"}))];function Na(e,a){for(let r=0;r<e.length;r++)e[r]=e[r].flatMap(s=>s.kind===\"palette\"?[X(\"uncommon\",`${a}:L${r+1}:${s.id}`)]:s.kind===\"texture\"?[X(\"legendary\",`${a}:L${r+1}:${s.id}`)]:s.kind===\"boss-skin\"?[{kind:\"boss-unlock\",id:a,name:s.name.replace(/ Skin$/,\" Beaten\"),line:\"Boss cleared at level 5.\"}]:[s]);e[3].push(X(\"rare\",`${a}:L4:64-bit`));let t=r=>r.some(s=>s.kind===\"reward-pack\");return t(e[1])||e[1].push(X(\"uncommon\",`${a}:L2:bonus`)),t(e[4])||e[4].push(X(\"legendary\",`${a}:L5:bonus`)),e}var za=(e,a)=>e.find(t=>t[0]===a);function Ce(e){let a=le.find(t=>t.id===e);return{kind:\"palette\",id:e,name:a.name,line:a.tagline}}var pr=new Map(le.filter(e=>e.reward).map(e=>[e.reward,e.id])),ja=(e,a)=>Array.from({length:a},(t,r)=>pr.get(`${e}:L${r+1}`)).map(t=>t?[Ce(t)]:[]),gr=e=>({kind:\"pet\",id:`${e}-pet`,name:`${e[0].toUpperCase()}${e.slice(1)} pet`,line:hr[e],family:e});function Ha(e){let a=xe.find(n=>n.id===e);if(!a)return null;let t=a.track&&M[a.track],r=mr[t?.family]||[null,null],s=ja(a.id,ea);if(s[1].push({kind:\"boss-texture\",id:`${a.id}-texture`,name:`${a.name} Texture`,line:r[0]}),s[4].push({kind:\"boss-skin\",id:`${a.id}-skin`,name:`${a.name} Skin`,line:r[1]}),!t||a.index!==1)return Na(s,a.id);let o=t.catalog,c=Ua.filter(n=>n[0].startsWith(o+\"-\")).map(n=>ta[n[0]]??n);s[0].unshift(A(\"weapon\",za(Da,`${o}-w1`)),A(\"texture\",c[0])),s[1].unshift(Ce(t.palette)),s[2].push(A(\"weapon\",za(Da,`${o}-w2`)),{kind:\"special\",id:`${o}-special`,name:`${t.name} Special`,line:\"Unlocked at level 3.\"},A(\"texture\",c[1])),s[3].push(gr(t.family)),s[4].unshift({kind:\"aura\",id:`${o}-aura`,name:`${t.name} Aura`,line:\"Your first aura look.\"}),s[4].push(A(\"texture\",c[2]));for(let n of ur.filter(f=>f.track===o))s[n.level-1].push(n);for(let n of fr.filter(f=>f.track===o))s[n.level-1].push({kind:\"ship\",id:n.id,name:n.name,line:Ze(n.ship).description,ship:n.ship,pack:\"coach-ships-biomes\"});return Na(s,a.id)}var Se=Object.freeze({id:\"food-bonus\",name:\"Second Helping\",line:\"Hits harder for one day. Chew responsibly.\",effect:Object.freeze({type:\"damage-multiplier\",days:1,value:Pa})}),ve=le.filter(e=>e.reward?.startsWith(\"food:\")).length,Wa=()=>ja(\"food\",ve).map((e,a)=>[...e.map(t=>X(\"uncommon\",`food:L${a+1}:${t.id}`)),{kind:\"bonus\",id:`${Se.id}-${a+1}`,name:Se.name,line:Se.line,effect:Se.effect}]);var sa=e=>T[e]?.group||(e===\"jumping\"?\"cardio\":null);var ko=Object.freeze({advance:\"That wasn't enough to impress my clipboard. Ready for the next level?\",max:\"Maximum difficulty? Fine. One more than your last round. Now we're negotiating.\",limit:\"Five rounds. Even I have to respect the paperwork. This exercise family is done for today.\",rest:\"Rest first. The next challenge can wait.\"});var So=Object.freeze([{key:\"pushups\",mode:\"pushup\",goal:10,voice:!0},{key:\"squats\",mode:\"squat\",goal:10,voice:!0},{key:\"situps\",mode:\"high-plank\",goal:15,voice:!0},{key:\"meditation\",mode:null,goal:null,voice:!0},{key:\"food\",mode:null,goal:null,voice:!1}]),Ka=Object.freeze({chest:\"chest\",legs:\"legs\",hips:\"hips\",shoulders:\"shoulders\",yoga:\"yoga\",stances:\"martial-arts\",boxing:\"martial-arts\",cardio:\"cardio\"}),yr=Object.freeze([\"chest\",\"legs\",\"hips\",\"shoulders\",\"yoga\",\"martial-arts\",\"cardio\"]),xo=Object.freeze([...yr,\"meditation\",\"food\"]);var Re=5;var Ao=Object.freeze({chest:\"chest\",legs:\"quads\",hips:\"glutes\",shoulders:\"arms-shoulders\",core:\"yoga\",balance:\"yoga\",yoga:\"yoga\",stances:\"martial-arts\",boxing:\"martial-arts\",cardio:\"cardio\"});var Ya=(e={})=>R(e).paths;var Ae={};pa(Ae,{cosmeticId:()=>w,currentCosmeticCoach:()=>L,grantUnlock:()=>Z,grantUnlocks:()=>la,grantedIds:()=>vr,isGranted:()=>ae,isGrantedToOriginalCoach:()=>et,migrateSavedCosmetics:()=>na,ownerGrantedIds:()=>ia});var oa=\"myr5-unlock-pending-v1\",Ee=Object.freeze([\"creature-skin\",\"ship\",\"reward-pack\"]),kr=new Set([...Ee,\"texture\",\"color\",\"palette\",\"boss-skin\"]),Xa=(e,{account:a=globalThis.myr5AuthenticatedAccount}={})=>{if(!kr.has(e))return oa;try{let t=typeof a==\"string\"?a:a?.user?.id;return typeof t==\"string\"&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(t)?`${oa}/account/${t}${typeof a==\"object\"&&a?.dataEpoch!=null?`/epoch/${encodeURIComponent(String(a.dataEpoch))}`:\"\"}`:`${oa}/guest/${encodeURIComponent(x(globalThis.localStorage,a))}`}catch{return null}},Va=e=>{try{let a=JSON.parse(localStorage.getItem(e)||\"{}\");return a&&typeof a==\"object\"&&!Array.isArray(a)?a:{}}catch{return{}}},Ja=(e,a)=>Array.isArray(e[a])?e[a]:[];function wr(e,a,t){let r=Xa(e,a);if(!r)return;let s=Va(r),o=Ja(s,e),c=t(o);if(c!==o)try{localStorage.setItem(r,JSON.stringify({...s,[e]:c}))}catch{}}function Fe(e,a){let t=new Map;for(let{kind:r,id:s}of e){let o=Xa(r,a);if(!o)continue;let c=t.get(o);c||(c={data:Va(o),known:new Map},t.set(o,c)),c.known.has(r)||(c.data[r]=[...Ja(c.data,r)],c.known.set(r,new Set(c.data[r])));let n=c.known.get(r);n.has(s)||(n.add(s),c.data[r].push(s))}for(let[r,s]of t)try{localStorage.setItem(r,JSON.stringify(s.data))}catch{}}var J=(e,a,t)=>wr(e,t,r=>r.includes(a)?r:[...r,a]);var _r=\"myr5-unlocks-v2\",Sr=()=>({texture:[],color:[],palette:[]}),w=(e,a)=>`coach:${encodeURIComponent(e)}:${a}`,Q=(e,a)=>e===\"texture\"?Ye(a):a,xr=(e,a)=>{let t=/^(coach:[^:]*:)(.*)$/.exec(a);return t?t[1]+Q(e,t[2]):a};function L(){try{return JSON.parse(localStorage.getItem(\"myr5-recipe-v1\")||\"{}\").body||\"myr5\"}catch{return\"myr5\"}}var ca=()=>`${_r}/${encodeURIComponent(x())}`;function ee(){try{let e=JSON.parse(localStorage.getItem(ca())||\"{}\");return Object.fromEntries([\"texture\",\"color\",\"palette\"].map(a=>[a,Array.isArray(e[a])?[...new Set(e[a].filter(t=>typeof t==\"string\").map(t=>xr(a,t)))]:[]]))}catch{return Sr()}}function Qa(e){try{return localStorage.setItem(ca(),JSON.stringify(e)),!0}catch{return!1}}var Za=(e,a,t)=>ee()[e]?.includes(w(t,Q(e,a)))??!1;function Cr(e,a){let t=Q(e,a);return(ee()[e]||[]).some(r=>{let s=/^coach:([^:]+):(.*)$/.exec(r);if(!s||s[2]!==t)return!1;try{return decodeURIComponent(s[1])!==\"myr5\"}catch{return!1}})}var et=(e,a)=>Za(e,a,\"myr5\")||Cr(e,a),ae=(e,a,t=L())=>t===\"myr5\"?et(e,a):Za(e,a,t);function at(e){let a=globalThis.CustomEvent;if(!(typeof globalThis.dispatchEvent!=\"function\"||typeof a!=\"function\"||!e.length))try{globalThis.dispatchEvent(new a(\"myr5:cosmetics-unlocked\",{detail:{owner:x(),granted:e}}))}catch{}}function Z(e,a,t=L()){if(![\"texture\",\"color\",\"palette\"].includes(e)||typeof a!=\"string\"||!a||typeof t!=\"string\"||!t)return!1;let r=ee(),s=w(t,Q(e,a));if(r[e].includes(s)||(r[e].push(s),!Qa(r)))return!1;let o=Q(e,a),c=[{kind:e,id:o,coachId:t}];return J(e,s),t!==\"myr5\"&&J(e,w(\"myr5\",o)),at(c),!0}var vr=(e,a=L())=>{let t=ee()[e]||[],r=w(a,\"\"),s=t.filter(c=>c.startsWith(r)).map(c=>c.slice(r.length));if(a!==\"myr5\")return s;let o=t.flatMap(c=>{let n=/^coach:([^:]+):(.*)$/.exec(c);if(!n||!n[2])return[];try{return decodeURIComponent(n[1])===\"myr5\"?[]:[n[2]]}catch{return[]}});return[...new Set([...s,...o])]};function na(e){let a=e?.body;if(a)try{let t=`${ca()}/saved-look/${encodeURIComponent(a)}`;if(localStorage.getItem(t))return;let r=JSON.parse(localStorage.getItem(\"myr5-unlocks-v1\")||\"{}\");for(let s of Object.values(e.materials||{}))if(s?.textureId&&r.texture?.includes(s.textureId)&&Z(\"texture\",s.textureId,a),s?.colorId)for(let o of[\"color\",\"palette\"])r[o]?.includes(s.colorId)&&Z(o,s.colorId,a);localStorage.setItem(t,\"1\")}catch{}}var ia=e=>{let a=ee()[e]||[],t=a.flatMap(r=>{let s=/^coach:([^:]+):(.*)$/.exec(r);if(!s||!s[2])return[];try{return decodeURIComponent(s[1])===\"myr5\"?[]:[w(\"myr5\",s[2])]}catch{return[]}});return[...new Set([...a,...t])]};function la(e){let a=ee(),t=Object.fromEntries([\"texture\",\"color\",\"palette\"].map(o=>[o,new Set(a[o])])),r=[];for(let o of e){if(!t[o.kind]||typeof o.id!=\"string\"||!o.id||typeof o.coachId!=\"string\"||!o.coachId)continue;let c=Q(o.kind,o.id),n=w(o.coachId,c);t[o.kind].has(n)||(t[o.kind].add(n),a[o.kind].push(n),r.push({kind:o.kind,id:c,coachId:o.coachId}))}if(!r.length||!Qa(a))return 0;let s=r.flatMap(({kind:o,id:c,coachId:n})=>[{kind:o,id:w(n,c)},...n===\"myr5\"?[]:[{kind:o,id:w(\"myr5\",c)}]]);return Fe(s),at(r),r.length}var Pe={};pa(Pe,{ACCOUNT_SCOPED_LEDGER_KINDS:()=>Ee,LEDGER_KEY:()=>te,LEDGER_KINDS:()=>Me,grantUnlock:()=>Te,grantUnlocks:()=>fa,grantedIds:()=>Oe,isGranted:()=>Ie});var te=\"myr5-battle-pass-ledger-v1\",Me=Object.freeze([\"weapon\",\"pet\",\"boss-texture\",\"boss-skin\",\"boss-unlock\",\"special\",\"aura\",\"bonus\",\"creature-skin\",\"ship\",\"reward-pack\"]);function da(){try{let e=JSON.parse(localStorage.getItem(te)||\"{}\");return Object.fromEntries(Me.map(a=>[a,Array.isArray(e[a])?e[a]:[]]))}catch{return Object.fromEntries(Me.map(e=>[e,[]]))}}var Le=new Set([...Ee,\"boss-skin\"]),ba=({account:e=globalThis.myr5AuthenticatedAccount}={})=>{try{let a=typeof e==\"string\"?e:e?.user?.id;return typeof a==\"string\"&&/^[A-Za-z0-9](?:[A-Za-z0-9._:-]{0,127})$/.test(a)?`${te}/account/${a}${typeof e==\"object\"&&e?.dataEpoch!=null?`/epoch/${encodeURIComponent(String(e.dataEpoch))}`:\"\"}`:`${te}/guest/${encodeURIComponent(x(globalThis.localStorage,e))}`}catch{return null}};function ua(e){try{let a=ba(e);if(!a)return{};let t=JSON.parse(localStorage.getItem(a)||\"{}\");return t&&typeof t==\"object\"&&!Array.isArray(t)?t:{}}catch{return{}}}var Oe=(e,a)=>{let t=(Le.has(e)?ua(a):da())[e];return Array.isArray(t)?t:[]},Ie=(e,a,t)=>Oe(e,t).includes(a);function Te(e,a,t){if(Le.has(e)){let s=ba(t);if(!s)return!1;let o=ua(t),c=Array.isArray(o[e])?o[e]:[];if(c.includes(a))return!1;o[e]=[...c,a];try{localStorage.setItem(s,JSON.stringify(o))}catch{return!1}return J(e,a,t),!0}let r=da();if(!r[e]||r[e].includes(a))return!1;r[e].push(a);try{localStorage.setItem(te,JSON.stringify(r))}catch{return!1}return J(e,a),!0}function fa(e,a,t){if(!Me.includes(e)||!Array.isArray(a))return 0;let r=Le.has(e)?ba(t):te;if(!r)return 0;let s=Le.has(e)?ua(t):da(),o=new Set(s[e]||[]),c=[];for(let n of a)typeof n==\"string\"&&n&&!o.has(n)&&(o.add(n),c.push(n));if(!c.length)return 0;s[e]=[...o];try{localStorage.setItem(r,JSON.stringify(s))}catch{return 0}return Fe(c.map(n=>({kind:e,id:n})),t),c.length}var Go=Object.freeze({rare:2,legendary:3,odds:Object.freeze({secret:Object.freeze({color:75,\"64-bit\":0})})});var Rr={color:$a(),texture:qa()};var rt=e=>w(e.coachId,e.id);var Er=(e,a)=>a.flatMap(t=>e===\"64-bit\"?[{kind:\"boss-skin\",id:`${t}-skin`,name:\"64-bit Pixel Finish\",coachId:t}]:Rr[e].map(r=>({...r,coachId:t})));function tt({coaches:e=je()}={}){let a=[...new Set(e)].filter(r=>ge(r)),t=Object.fromEntries([\"color\",\"palette\",\"texture\"].map(r=>[r,new Set(ia(r))]));return t[\"boss-skin\"]=new Set(Oe(\"boss-skin\")),[\"color\",\"64-bit\",\"texture\"].flatMap(r=>Er(r,a).map(s=>({...s,category:r}))).filter(r=>!t[r.kind].has(rt(r)))}function st(){let e=tt(),a=e.filter(s=>s.kind!==\"boss-skin\"),t=e.filter(s=>s.kind===\"boss-skin\");la(a),fa(\"boss-skin\",t.map(rt));let r=tt().length;return{granted:e.length-r,remaining:r}}var Fr=Object.fromEntries(Object.entries(M).map(([e,a])=>[a.circuit,e]));function nt(e=globalThis.myr5AuthenticatedAccount){let a=Ya();return a.length||(a=(e?.onboarding?.data?.profile?.exercises||[]).map(t=>Fr[Ka[sa(t)]]).filter(Boolean)),new Set([\"meditation\",...a])}function it(){let e=globalThis.coachProgress?.circuit?.tracks;if(e)return e;try{return JSON.parse(localStorage.getItem(\"myr5-workout-progress-v1\"))?.circuit?.tracks||{}}catch{return{}}}var Ar=(e,a=Re)=>Math.floor(Math.max(0,Number(e)||0)/a);function Mr({tracks:e=it(),account:a,stepsPerLevel:t=Re}={}){let r=R({account:a}),s=Object.fromEntries(xe.map(o=>[o.id,0]));for(let o of V){if(!o.track)continue;let c=P.filter(n=>n.tracks.includes(M[o.track].catalog));for(let n=0;n<o.bosses;n++){let f=c[Math.min(c.length-1,Math.floor(n*c.length/o.bosses))];f&&(s[`${o.id}-${n+1}`]=r.goldenCoaches.includes(f.id)?5:r.coaches.includes(f.id)?4:0)}}return s}var Lr=new Set([\"texture\",\"color\",\"palette\"]),ot=(e,a)=>(Lr.has(e.kind)?Ae:Pe).isGranted(e.kind,e.id,a);function Or(e={}){let a=e.stepsPerLevel??Re,t=nt(e.account),r=Mr({...e,stepsPerLevel:a}),s=Math.max(0,Number((e.tracks??it())?.food?.steps)||0),o=Math.min(ve,Ar(s,a)),c=i=>V.find(l=>l.track&&M[l.track].family===i&&t.has(l.track)&&r[`${l.id}-1`]>=4)?.id,n=xe.map(i=>({...i,levels:r[i.id],rewards:Ha(i.id).map((l,d)=>({level:d+1,beaten:r[i.id]>d,items:l.map(b=>{let y=b.kind===\"pet\"&&aa[b.family]&&c(b.family),h=y&&y!==i.row?(()=>{let k=Ce(aa[b.family]);return{kind:\"reward-pack\",id:`reward-pack:uncommon:${i.id}:L4:${k.id}`,tier:\"uncommon\",name:\"Uncommon Pack\",line:\"Open for one random cosmetic.\"}})():b;return{...h,granted:ot(h,e)}})}))})),f={steps:s,levels:o,maxLevel:ve,rewards:Wa().map((i,l)=>({level:l+1,beaten:o>l,items:i.map(d=>({...d,granted:ot(d)}))}))};return{stepsPerLevel:a,available:[...t],progress:r,bosses:n,food:f}}function ct(e={}){let a=Or(e),t=[],r=va(R(e).totalXp);for(let s=2;s<=r.level;s++){let o=s%10===0?\"legendary\":s%5===0?\"rare\":\"uncommon\",c={kind:\"reward-pack\",id:`reward-pack:${o}:cosmetic-pass-v2:L${s}`,tier:o,name:`${o} pack`};Te(c.kind,c.id,e)&&t.push(c)}return r.max&&st(e),t.length&&typeof window<\"u\"&&window.dispatchEvent&&window.dispatchEvent(new CustomEvent(\"myr5:battle-pass\",{detail:{granted:t,state:a}})),{granted:t,state:a}}typeof window<\"u\"&&window.addEventListener&&(window.addEventListener(\"myr5:account-progress\",()=>ct()),window.addEventListener(\"myr5:performance-progress\",()=>ct()));var Ir=Object.fromEntries([...ue.map(e=>[e.id,e.name]),[\"meditation\",\"Meditation\"]]),Tr=E.map(e=>({...e,name:e.label,requirement:P.find(a=>a.id===e.id)||null})),Pr=e=>e[0].toUpperCase()+e.slice(1),lt=e=>Ir[e]||e;function dt(e){let a=Tr.find(n=>n.id===e);if(!a)return null;let t=a.requirement;if(!t){let n=F.includes(e);return{starter:n,unlock:n?\"Available from the start\":\"Requirement pending placement.\",gold:\"Select this coach and complete a 10-minute uninterrupted hold to earn its golden version.\",exercises:[]}}if(t.groups.includes(\"meditation\"))return{starter:!1,unlock:`Complete meditation on ${q.meditationDays[he.indexOf(t.difficulty)]} separate days.`,gold:\"Once unlocked, select this coach and complete a 10-minute uninterrupted hold to earn its golden version.\",exercises:[]};let r=Object.values(T).filter(n=>t.groups.includes(n.group)&&Ne(n.id)===t.difficulty),s=Object.values(fe).includes(e)?`Choose ${t.groups.map(lt).join(\" / \")} as one of your two starting workout paths OR `:\"\",o=[...new Set(r.map(n=>n.kind))],c=[];return o.includes(\"hold\")&&c.push(\"hold for 5 uninterrupted minutes\"),o.includes(\"reps\")&&c.push(\"complete 15 reps in one working set\"),t.groups.includes(\"cardio\")?c.push(\"complete 5 sprint rounds or 5 active minutes of gentle cardio\"):o.some(n=>n===\"pace\"||n===\"steps\")&&c.push(\"complete 5 active minutes\"),{starter:!1,difficulty:t.difficulty,groups:t.groups,unlock:`${s}${Pr(t.difficulty)} \\xB7 ${t.groups.map(lt).join(\" / \")}: ${c.join(\" OR \")}.`,gold:o.includes(\"hold\")?\"Complete a 10-minute uninterrupted hold at this difficulty in one of these groups. Breaks and difficulty changes restart the uninterrupted attempt.\":\"Once unlocked, select this coach and complete a 10-minute uninterrupted hold to earn its golden version.\",exercises:r.map(n=>n.name)}}var Br=[{id:\"strider\",track:\"chest\",color:\"#b48cff\",boxes:[[10.96,9.7,10.78,8.8],[28.4,8.05,7.89,10.45],[37.51,9.2,11.92,9.3],[51.62,8.05,11.48,10.45],[63.37,8.05,12.8,10.45],[78.18,7.9,15.43,10.6]]},{id:\"ringer\",track:\"quads\",color:\"#ff8a2a\",boxes:[[20.16,18.05,7.89,8.1],[31.11,17.95,10.69,8.4],[44.26,17.95,9.55,8.25],[57.06,17.95,9.03,8.3],[69.76,17.95,11.13,8.5]]},{id:\"manyarm\",track:\"glutes\",color:\"#7dff5a\",boxes:[[22.17,26.65,8.33,8.6],[34.18,26.45,9.73,8.8],[46.54,27.25,10.08,8],[57.49,27.4,7.54,7.85],[65.64,27.2,12.62,8.05]]},{id:\"wedge\",track:\"arms\",color:\"#39a8ff\",boxes:[[23.4,34.7,10.52,7.8],[35.06,34.7,8.15,7.45],[43.21,34.7,11.48,7.75],[55.04,34.7,9.82,7.75],[65.21,34.7,11.22,7.75]]},{id:\"warden\",track:null,color:\"#39a8ff\",boxes:[[45.57,41.95,8.24,5.7]]},{id:\"blob\",track:\"yoga\",color:\"#c65cff\",boxes:[[26.29,47.25,10.87,6.95],[38.56,47.1,9.55,7.2],[49.87,47.1,7.8,6.95],[60.74,47.3,9.55,7.45]]},{id:\"cap\",track:\"martial-arts\",color:\"#ff4fa0\",boxes:[[33.04,54.6,7.62,7.4],[40.93,54.55,11.13,7.45],[53.46,54.65,10.78,7.35]]},{id:\"stalk\",track:\"cardio\",color:\"#ff4a3d\",boxes:[[30.5,61.45,7.01,7.5],[38.21,61.45,8.15,7.25],[49.52,61.45,9.29,7.5],[58.55,61.45,8.59,7.5]]},{id:\"tanka\",track:\"meditation\",color:\"#ffd23a\",boxes:[[29.27,68.65,9.38,7.85],[39.09,68.65,9.64,7.8],[48.47,68.45,10.6,8],[59.95,68.5,8.33,8]]},{id:\"lume\",track:null,color:\"#ffc94a\",boxes:[[39.35,75.95,15.34,8.8]]}],ic=Br.flatMap(e=>e.boxes.map((a,t)=>({id:`${e.id}-${t+1}`,row:e.id,color:e.color,box:a})));var Dr=[\"chest\",\"quads\",\"glutes\",\"arms\",\"yoga\",\"martial-arts\",\"cardio\",\"meditation\"],Nr=\"Original artwork -- MYR5 alien pipeline (Tripo Studio capture by Ian, low-poly re-export, Claude eval); no third-party license asserted (see creature/NOTICE.md).\",zr=e=>`creature/models/${e}.glb`,Ur=[[\"roster/23-blob-texture-bodies--blob_creature_3d_model\",\"Blob 1\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--dragon_creature_3d_model\",\"Four-legged 1\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--fantasy_creature_3d_model1\",\"Four-legged 2\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--fantasy_creature_3d_model3\",\"Four-legged 3\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--four-legged_robot_3d_model\",\"Four-legged 4\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--quadruped_robot_3d_model1\",\"Four-legged 5\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--quadruped_robot_3d_model\",\"Four-legged 6\",[\"meditation\"],!0,!1],[\"roster/18-quad-all--robotic_dog_3d_model\",\"Four-legged 7\",[\"meditation\"],!0,!0,\"meditation\"],[\"roster/12-seedpod-snailslug--stylized_slug_3d_model\",\"Seedpod \\xB7 Snailslug 1\",[\"meditation\"],!0,!1],[\"roster/12-seedpod-snailslug--stylized_worm_3d_model\",\"Seedpod \\xB7 Snailslug 2\",[\"meditation\"],!0,!1],[\"roster/14-chisel-spire--low_poly_robot_3d_model\",\"Chisel \\xB7 Spire 2\",[\"meditation\"],!1,!1],[\"roster/07-bulb-sphereling--humanoid_robot_3d_model\",\"Bulb \\xB7 Sphereling 2\",[\"cardio\"],!1,!1],[\"roster/03-pearl-orb-ring--ringed_humanoid_3d_model\",\"Pearl \\xB7 Orb 3\",[\"cardio\"],!1,!1],[\"roster/06-ridge-triad--robot_3d_model1\",\"Ridge \\xB7 Triad 2\",[\"cardio\"],!1,!1],[\"roster/03-pearl-orb-ring--robot_3d_model\",\"Pearl \\xB7 Orb 4\",[\"cardio\"],!1,!1],[\"roster/20-lume--robotic_figure_3d_model\",\"Lume 1\",[\"cardio\"],!1,!1,\"cardio\"],[\"roster/02-taper-tallstalk--humanoid_robot_3d_model1\",\"Taper \\xB7 Tallstalk 2\",[\"arms\"],!1,!1],[\"roster/19-genie-multi--multi-armed_humanoid_3d_model1\",\"Genie \\xB7 Multi 2\",[\"arms\"],!1,!1],[\"roster/19-genie-multi--multi-armed_humanoid_3d_model\",\"Genie \\xB7 Multi 3\",[\"arms\"],!1,!1],[\"roster/17-shellcap-manyarm--mushroom_creature_3d_model\",\"Shellcap \\xB7 Manyarm 2\",[\"arms\"],!1,!1],[\"roster/17-shellcap-manyarm--mushroom_robot_3d_model\",\"Shellcap \\xB7 Manyarm 3\",[\"arms\"],!1,!1],[\"roster/23-blob-texture-bodies--patchwork_plush_figure_3d_model\",\"Blob 4\",[\"arms\"],!1,!1],[\"roster/08-shard-asym--robot_3d_model4\",\"Shard \\xB7 Asym 2\",[\"arms\"],!1,!1,\"arms\"],[\"roster/06-ridge-triad--geometric_robot_3d_model1\",\"Ridge \\xB7 Triad 1\",[\"chest\"],!1,!1],[\"roster/08-shard-asym--geometric_robot_3d_model\",\"Shard \\xB7 Asym 1\",[\"chest\"],!1,!1],[\"roster/16-spade-arch--pyramid_head_figure_3d_model\",\"Spade \\xB7 Arch 1\",[\"chest\",\"martial-arts\"],!1,!1],[\"roster/04-crest-wedge--robot_creature_3d_model\",\"Crest \\xB7 Wedge 1\",[\"chest\"],!1,!1],[\"roster/16-spade-arch--stylized_humanoid_3d_model\",\"Spade \\xB7 Arch 2\",[\"chest\"],!1,!1,\"chest\"],[\"roster/23-blob-texture-bodies--honeycomb_humanoid_3d_model\",\"Blob 3\",[\"glutes\"],!1,!1],[\"roster/23-blob-texture-bodies--sand_creature_3d_model\",\"Blob 5\",[\"glutes\"],!1,!1],[\"roster/03-pearl-orb-ring--stylized_3d_character1\",\"Pearl \\xB7 Orb 5\",[\"glutes\"],!1,!1],[\"roster/03-pearl-orb-ring--stylized_humanoid_figure_3d_model\",\"Pearl \\xB7 Orb 6\",[\"glutes\"],!1,!1,\"glutes\"],[\"roster/15-orbital-coili--robot_character_3d_model\",\"Orbital \\xB7 Coili 1\",[\"quads\"],!1,!1],[\"roster/13-fan-split--stylized_3d_character2\",\"Fan \\xB7 Split 1\",[\"quads\"],!1,!1],[\"roster/22-curve--stylized_cartoon_figure_3d_model\",\"Curve 2\",[\"quads\"],!1,!1,\"quads\"],[\"roster/10-petal-wisp--fantasy_creature_3d_model4\",\"Petal \\xB7 Wisp 3\",[\"yoga\"],!1,!1],[\"roster/19-genie-multi--fantasy_creature_3d_model\",\"Genie \\xB7 Multi 1\",[\"yoga\"],!1,!1],[\"roster/10-petal-wisp--ghost_character_3d_model\",\"Petal \\xB7 Wisp 2\",[\"yoga\"],!1,!1],[\"roster/08-shard-asym--stylized_action_figure_3d_model\",\"Shard \\xB7 Asym 4\",[\"yoga\"],!1,!1],[\"roster/22-curve--stylized_alien_3d_model\",\"Curve 1\",[\"yoga\"],!1,!1],[\"roster/10-petal-wisp--stylized_creature_3d_model\",\"Petal \\xB7 Wisp 1\",[\"yoga\"],!1,!1],[\"roster/19-genie-multi--stylized_octopus_3d_model\",\"Genie \\xB7 Multi 4\",[\"yoga\"],!1,!1,\"yoga\"],[\"roster/09-monolith-tanka--boxy_humanoid_3d_model\",\"Monolith \\xB7 Tanka 2\",[\"martial-arts\"],!1,!1],[\"roster/11-anvil-cask--clay-style_robot_3d_model\",\"Anvil \\xB7 Cask 1\",[\"martial-arts\"],!1,!1],[\"roster/05-slope-bobble--clay_humanoid_figure_3d_model\",\"Slope \\xB7 Bobble 1\",[\"martial-arts\"],!1,!1],[\"roster/14-chisel-spire--cone_head_3d_model\",\"Chisel \\xB7 Spire 1\",[\"martial-arts\"],!1,!1],[\"roster/08-shard-asym--fantasy_creature_3d_model2\",\"Shard \\xB7 Asym 3\",[\"martial-arts\"],!1,!1],[\"roster/09-monolith-tanka--mini_robot_3d_model\",\"Monolith \\xB7 Tanka 3\",[\"martial-arts\"],!1,!1],[\"roster/09-monolith-tanka--robot_3d_model3\",\"Monolith \\xB7 Tanka 5\",[\"martial-arts\"],!1,!1],[\"roster/13-fan-split--stylized_toy_3d_model\",\"Fan \\xB7 Split 2\",[\"martial-arts\"],!1,!1,\"martial-arts\"]],pc=Ur.map(([e,a,t,r,s,o])=>({stableId:e,displayName:a,tracks:t,petEligible:r,mountEligible:s,bossOf:o,sourceAsset:zr(e),license:Nr,unlockRule:\"performance-milestone\",renderRecipe:\"tbd\"})),Gr=e=>V.find(a=>a.track&&M[a.track].catalog===e);var gc=Object.fromEntries(Dr.map(e=>[e,M[Gr(e).track].name]));function bt(e,a,t=[]){return Ve.has(e)||v.includes(e)?\"Unavailable coach\":F.includes(e)||ge(e)?null:dt(e)?.unlock||\"Coach performance milestone required\"}var ut=[{id:\"pal-01\",name:\"Acid Forge\",tagline:\"Lime bites oxblood and chrome\",colors:[\"#C6FF00\",\"#4A0E17\",\"#C0C7CE\"],unlockRule:\"aura-milestone\",unlockAtDay:5,finish:\"glitter\"},{id:\"pal-02\",name:\"Neon Afterburn Haze\",tagline:\"Orange aqua contrails with violet flare\",colors:[\"#FF6D00\",\"#00E0B0\",\"#C800FF\"],unlockRule:\"aura-milestone\",unlockAtDay:10,finish:\"brushed-metal\"},{id:\"pal-03\",name:\"Petrel Copper\",tagline:\"Petrol depths meet intense violet\",colors:[\"#0E5A61\",\"#B87333\",\"#6913E7\"],unlockRule:\"aura-milestone\",unlockAtDay:15,finish:\"polished-metal\"},{id:\"pal-04\",name:\"Vinaigrette Rust\",tagline:\"Oil pigment rust swirl\",colors:[\"#8A3B12\",\"#556B2F\",\"#E7A213\"],unlockRule:\"aura-milestone\",unlockAtDay:20,finish:\"marbled\"},{id:\"pal-05\",name:\"Neon Relic\",tagline:\"Hot magenta neon amber on bone\",colors:[\"#FF009F\",\"#FFB500\",\"#F2EFE6\"],unlockRule:\"aura-milestone\",unlockAtDay:25,finish:\"glitter\"},{id:\"pal-06\",name:\"Glacier Ember\",tagline:\"Ice teal over ember red\",colors:[\"#13E7D1\",\"#D9381E\",\"#2B2530\"],unlockRule:\"aura-milestone\",unlockAtDay:30,finish:\"pearl\"},{id:\"pal-07\",name:\"Chartreuse Storm\",tagline:\"Sludge green meets slate violet\",colors:[\"#B5C700\",\"#3D3654\",\"#E85D75\"],unlockRule:\"aura-milestone\",unlockAtDay:35,finish:\"matte\"},{id:\"pal-08\",name:\"Saffron Voltage\",tagline:\"Saffron arcs on ink blue\",colors:[\"#FFB000\",\"#101D42\",\"#00FAA6\"],unlockRule:\"aura-milestone\",unlockAtDay:40,finish:\"polished-metal\"},{id:\"pal-09\",name:\"Neon Venom Signal\",tagline:\"Poison lime warning under arterial red\",colors:[\"#A6FF00\",\"#FF2442\",\"#101828\"],unlockRule:\"aura-milestone\",unlockAtDay:45,finish:\"watercolor\"},{id:\"pal-10\",name:\"Mercury Moss\",tagline:\"Silver moss over saturated gold\",colors:[\"#AEB6BC\",\"#5C6B3C\",\"#E7A913\"],unlockRule:\"aura-milestone\",unlockAtDay:50,finish:\"brushed-metal\"},{id:\"pal-11\",name:\"Ultraviolet Tar\",tagline:\"Violet glow on tar black\",colors:[\"#7B2FF7\",\"#141414\",\"#FFC93C\"],unlockRule:\"aura-milestone\",unlockAtDay:55,finish:\"glaze\"},{id:\"pal-12\",name:\"Salmon Circuit\",tagline:\"Salmon pink on circuit green\",colors:[\"#FA2200\",\"#00A86B\",\"#2E2A5C\"],unlockRule:\"aura-milestone\",unlockAtDay:60,finish:\"pearl\"},{id:\"pal-13\",name:\"Muddy Pop\",tagline:\"Ochre mud sparks cerulean\",colors:[\"#8C6A2F\",\"#0081C8\",\"#E71362\"],unlockRule:\"battle-pass\",reward:\"strider-2:L1\",finish:\"matte\"},{id:\"pal-14\",name:\"Neon Vapor Crown\",tagline:\"Laser pink blue over dark purple\",colors:[\"#FF00AA\",\"#00D0FF\",\"#1B0033\"],unlockRule:\"battle-pass\",reward:\"strider-2:L3\",finish:\"watercolor\"},{id:\"pal-15\",name:\"Brick Vein\",tagline:\"Brick red veined in steel\",colors:[\"#A0342B\",\"#8C9BA5\",\"#D7E713\"],unlockRule:\"battle-pass\",reward:\"strider-2:L4\",finish:\"marbled\"},{id:\"pal-16\",name:\"Peacock Static\",tagline:\"Peacock green hums gold\",colors:[\"#046A5B\",\"#FAAF00\",\"#5B1E4B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L1\",finish:\"polished-metal\"},{id:\"pal-17\",name:\"Foghorn Flame\",tagline:\"Fog gray with fire-orange siren\",colors:[\"#B8C0C2\",\"#FA3F00\",\"#123C69\"],unlockRule:\"battle-pass\",reward:\"strider-3:L3\",finish:\"brushed-metal\"},{id:\"pal-18\",name:\"Toxic Honey\",tagline:\"Honey drips on toxic lime\",colors:[\"#D9A404\",\"#9BF00B\",\"#4A154B\"],unlockRule:\"battle-pass\",reward:\"strider-3:L4\",finish:\"glaze\"},{id:\"pal-19\",name:\"Neon Crimson Mirage\",tagline:\"Scarlet toxic lime over deep jade\",colors:[\"#FF1744\",\"#76FF03\",\"#005E3C\"],unlockRule:\"battle-pass\",reward:\"strider-4:L1\",finish:\"matte\"},{id:\"pal-20\",name:\"Opal Drain\",tagline:\"Opal sheen on drainpipe green\",colors:[\"#13E7B9\",\"#3E5641\",\"#D1495B\"],unlockRule:\"battle-pass\",reward:\"strider-4:L3\",finish:\"pearl\"},{id:\"pal-21\",name:\"Rust Halo\",tagline:\"Rust ringed by mint flash\",colors:[\"#9C4221\",\"#12E898\",\"#2C2C54\"],unlockRule:\"battle-pass\",reward:\"strider-4:L4\",finish:\"brushed-metal\"},{id:\"pal-22\",name:\"Volt Quartz\",tagline:\"Electric yellow on rose quartz\",colors:[\"#F5E900\",\"#E71363\",\"#264653\"],unlockRule:\"battle-pass\",reward:\"strider-5:L1\",finish:\"glitter\"},{id:\"pal-23\",name:\"Neon Flare Garden\",tagline:\"Laser lime pink on teal steel\",colors:[\"#8CFF00\",\"#FF006E\",\"#00B8A9\"],unlockRule:\"battle-pass\",reward:\"strider-5:L3\",finish:\"matte\"},{id:\"pal-24\",name:\"Crimson Tidebreak\",tagline:\"Crimson breaks on seafoam\",colors:[\"#B91338\",\"#13E7B5\",\"#2A1E5C\"],unlockRule:\"battle-pass\",reward:\"strider-5:L4\",finish:\"watercolor\"},{id:\"pal-25\",name:\"Brass Mirage\",tagline:\"Brass shimmer dusky plum\",colors:[\"#C59B42\",\"#5A2A52\",\"#0D94ED\"],unlockRule:\"battle-pass\",reward:\"strider-6:L1\",finish:\"polished-metal\"},{id:\"pal-26\",name:\"Neon Infrared Bloom\",tagline:\"Red heat sliced by frozen cyan\",colors:[\"#FF0000\",\"#00F5FF\",\"#5B00B5\"],unlockRule:\"battle-pass\",reward:\"strider-6:L3\",finish:\"glaze\"},{id:\"pal-27\",name:\"Ice Magma\",tagline:\"Pigmented ice over magma orange\",colors:[\"#D6F0F0\",\"#F45B0F\",\"#3D2C8D\"],unlockRule:\"battle-pass\",reward:\"strider-6:L4\",finish:\"marbled\"},{id:\"pal-28\",name:\"Fern Radio\",tagline:\"Fern green static magenta\",colors:[\"#3F7A3A\",\"#E4007C\",\"#E7BE13\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L1\",finish:\"matte\"},{id:\"pal-29\",name:\"Porcelain Fuel\",tagline:\"Porcelain white fuel orange\",colors:[\"#F2F2F0\",\"#FF7A1A\",\"#14507A\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L3\",finish:\"glaze\"},{id:\"pal-30\",name:\"Neon Photon Alley\",tagline:\"Yellow signage aqua and violet glass\",colors:[\"#FFD300\",\"#00FFCC\",\"#7A00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-2:L4\",finish:\"brushed-metal\"},{id:\"pal-31\",name:\"Neon Solar Flare\",tagline:\"Hot yellow ember in plum space\",colors:[\"#FFEA00\",\"#FF3D00\",\"#26142B\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L1\",finish:\"polished-metal\"},{id:\"pal-32\",name:\"Wet Cement Rose\",tagline:\"Cement gray wild rose\",colors:[\"#8D9096\",\"#D84A87\",\"#F0E130\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L3\",finish:\"matte\"},{id:\"pal-33\",name:\"Neon Laser Tropics\",tagline:\"Chartreuse beams with scorched orange shadows\",colors:[\"#C6FF00\",\"#FF4D00\",\"#001219\"],unlockRule:\"battle-pass\",reward:\"ringer-3:L4\",finish:\"watercolor\"},{id:\"pal-34\",name:\"Copper Fog\",tagline:\"Copper glows through fog\",colors:[\"#B46A30\",\"#C4CBCE\",\"#B600F5\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L1\",finish:\"brushed-metal\"},{id:\"pal-35\",name:\"Laser Moss\",tagline:\"Laser cyan on moss\",colors:[\"#00E5FF\",\"#546B2F\",\"#FF4FA3\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L3\",finish:\"glitter\"},{id:\"pal-36\",name:\"Bone Ember\",tagline:\"Bone white ember orange\",colors:[\"#EDE8DC\",\"#E4572E\",\"#BA00FF\"],unlockRule:\"battle-pass\",reward:\"ringer-4:L4\",finish:\"matte\"},{id:\"pal-37\",name:\"Plum Static\",tagline:\"Plum noise with electric lime\",colors:[\"#4A1E4F\",\"#B8F000\",\"#33B5C7\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L1\",finish:\"glaze\"},{id:\"pal-38\",name:\"Neon Lime Vortex\",tagline:\"Acid green swirling through electric blue\",colors:[\"#BFFF00\",\"#00E5FF\",\"#12100F\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L3\",finish:\"pearl\"},{id:\"pal-39\",name:\"Clay Command\",tagline:\"Terracotta clay cobalt order\",colors:[\"#C06B55\",\"#2E4BC6\",\"#EDE6D6\"],unlockRule:\"battle-pass\",reward:\"ringer-5:L4\",finish:\"marbled\"},{id:\"pal-40\",name:\"Static Cream\",tagline:\"Cream noise shock green\",colors:[\"#F4EDDE\",\"#39FF14\",\"#4A306D\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L1\",finish:\"glitter\"},{id:\"pal-41\",name:\"Midnight Papaya\",tagline:\"Midnight blue papaya burst\",colors:[\"#191970\",\"#FF9E42\",\"#13E796\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L3\",finish:\"polished-metal\"},{id:\"pal-42\",name:\"Dusty Laser\",tagline:\"Dusty mauve laser green\",colors:[\"#A27E8E\",\"#7CFC00\",\"#1B3B6F\"],unlockRule:\"battle-pass\",reward:\"manyarm-2:L4\",finish:\"matte\"},{id:\"pal-43\",name:\"Neon Atomic Sunset\",tagline:\"Amber fallout glowing beside ultraviolet pink\",colors:[\"#FF9100\",\"#FF00F5\",\"#062A2A\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L1\",finish:\"glaze\"},{id:\"pal-44\",name:\"Fern Flame\",tagline:\"Cool fern fierce flame\",colors:[\"#4F7942\",\"#FF3D2E\",\"#E75A13\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L3\",finish:\"brushed-metal\"},{id:\"pal-45\",name:\"Violet Quarry\",tagline:\"Quarry gray violet eruption\",colors:[\"#7D7F87\",\"#8B3DFF\",\"#DCE35B\"],unlockRule:\"battle-pass\",reward:\"manyarm-3:L4\",finish:\"matte\"},{id:\"pal-46\",name:\"Cadmium Deep\",tagline:\"Cadmium red deep lagoon\",colors:[\"#D32E12\",\"#046E8F\",\"#E79E13\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L1\",finish:\"polished-metal\"},{id:\"pal-47\",name:\"Pigment Riot\",tagline:\"Intense blue maroon and hot orange\",colors:[\"#139FE7\",\"#6E1423\",\"#FF7300\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L3\",finish:\"watercolor\"},{id:\"pal-48\",name:\"Neon Prism Riot\",tagline:\"Sea-glass cyan, magenta bite, lemon flash\",colors:[\"#00FFC6\",\"#FF00B8\",\"#F5FF00\"],unlockRule:\"battle-pass\",reward:\"manyarm-4:L4\",finish:\"pearl\"},{id:\"pal-49\",name:\"Neon Tropic Surge\",tagline:\"Aqua tide, citrus flare, violet thunder\",colors:[\"#00FF9D\",\"#FFB000\",\"#D000FF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L1\",finish:\"glitter\"},{id:\"pal-50\",name:\"Ash Honey\",tagline:\"Ash gray golden honey\",colors:[\"#9BA0A6\",\"#E0A100\",\"#2F6690\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L3\",finish:\"matte\"},{id:\"pal-51\",name:\"Cherry Motor\",tagline:\"Cherry motor oil with electric blue\",colors:[\"#B22234\",\"#3B2F2F\",\"#005CFF\"],unlockRule:\"battle-pass\",reward:\"manyarm-5:L4\",finish:\"brushed-metal\"},{id:\"pal-52\",name:\"Glacier Punch\",tagline:\"Glacier pigmented hot punch\",colors:[\"#13A6E7\",\"#F52549\",\"#3D405B\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L1\",finish:\"glaze\"},{id:\"pal-53\",name:\"Tarnish Bloom\",tagline:\"Tarnished teal floral orange\",colors:[\"#3A7D7B\",\"#F4852B\",\"#E9D6EC\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L3\",finish:\"marbled\"},{id:\"pal-54\",name:\"Umber Signal\",tagline:\"Umber earth neon signal\",colors:[\"#635147\",\"#D0FF4B\",\"#7A28C0\"],unlockRule:\"battle-pass\",reward:\"wedge-2:L4\",finish:\"matte\"},{id:\"pal-55\",name:\"Rose Quartz Coil\",tagline:\"Soft rose coil of teal\",colors:[\"#E7134B\",\"#0FA3A3\",\"#2B2118\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L1\",finish:\"pearl\"},{id:\"pal-56\",name:\"Sulfur Deck\",tagline:\"Sulfur yellow blue and hot orange\",colors:[\"#E3D200\",\"#274C77\",\"#FF4A00\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L3\",finish:\"polished-metal\"},{id:\"pal-57\",name:\"Neon Ember Static\",tagline:\"Orange yellow buzzing with royal voltage\",colors:[\"#FF5E00\",\"#FFE600\",\"#3A0CA3\"],unlockRule:\"battle-pass\",reward:\"wedge-3:L4\",finish:\"watercolor\"},{id:\"pal-58\",name:\"Mango Ash\",tagline:\"Mango bright volcanic ash\",colors:[\"#FFA12B\",\"#59595E\",\"#64DDBB\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L1\",finish:\"matte\"},{id:\"pal-59\",name:\"Steel Petal\",tagline:\"Steel gray crushed petals\",colors:[\"#8A8F98\",\"#E71813\",\"#D8E26E\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L3\",finish:\"brushed-metal\"},{id:\"pal-60\",name:\"Ninja Cream\",tagline:\"Hidden navy cream coral\",colors:[\"#1E2A4A\",\"#F0EBE0\",\"#7EEC00\"],unlockRule:\"battle-pass\",reward:\"wedge-4:L4\",finish:\"glaze\"},{id:\"pal-61\",name:\"Tangerine Static\",tagline:\"Tangerine buzz grape shadow\",colors:[\"#F28500\",\"#3D2159\",\"#202020\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L1\",finish:\"glitter\"},{id:\"pal-62\",name:\"Sage Pistol\",tagline:\"Muted sage pistol pink\",colors:[\"#9AB5A1\",\"#E45C98\",\"#33272A\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L3\",finish:\"matte\"},{id:\"pal-63\",name:\"Lagoon Battery\",tagline:\"Lagoon green charged yellow\",colors:[\"#1D8A7A\",\"#FAE000\",\"#76305B\"],unlockRule:\"battle-pass\",reward:\"wedge-5:L4\",finish:\"polished-metal\"},{id:\"pal-64\",name:\"Wine Cooling\",tagline:\"Warm wine cooled by mint\",colors:[\"#701F3C\",\"#13E78C\",\"#E8D44D\"],unlockRule:\"battle-pass\",reward:\"warden-1:L1\",finish:\"pearl\"},{id:\"pal-65\",name:\"Charcoal Tulip\",tagline:\"Charcoal tulip flame combo\",colors:[\"#2E3033\",\"#FF4E50\",\"#CA00C7\"],unlockRule:\"battle-pass\",reward:\"warden-1:L3\",finish:\"matte\"},{id:\"pal-66\",name:\"Neon Acid Harbor\",tagline:\"Lime light cutting across magenta docks\",colors:[\"#39FF14\",\"#FF007F\",\"#001B2E\"],unlockRule:\"battle-pass\",reward:\"warden-1:L4\",finish:\"pearl\"},{id:\"pal-67\",name:\"Rustic Neon\",tagline:\"Barn red barn lime buzz\",colors:[\"#8A3324\",\"#C1FF33\",\"#2D4A6B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L1\",finish:\"marbled\"},{id:\"pal-68\",name:\"Alice Warning\",tagline:\"Alice blue caution orange\",colors:[\"#1399E7\",\"#FF7E1F\",\"#EEF700\"],unlockRule:\"battle-pass\",reward:\"blob-2:L3\",finish:\"watercolor\"},{id:\"pal-69\",name:\"Smog Candy\",tagline:\"Smog beige candy teal\",colors:[\"#E79813\",\"#00C2A8\",\"#D8395B\"],unlockRule:\"battle-pass\",reward:\"blob-2:L4\",finish:\"matte\"},{id:\"pal-70\",name:\"Violet Furnace\",tagline:\"Furnace violet cooled sky\",colors:[\"#6A2D9E\",\"#F57C3B\",\"#302012\"],unlockRule:\"battle-pass\",reward:\"blob-3:L1\",finish:\"glaze\"},{id:\"pal-71\",name:\"Khaki Storm\",tagline:\"Khaki field storm magenta\",colors:[\"#A89B6E\",\"#E0218A\",\"#2A6F97\"],unlockRule:\"battle-pass\",reward:\"blob-3:L3\",finish:\"brushed-metal\"},{id:\"pal-72\",name:\"Neon Circuit Surge\",tagline:\"Turquoise sparks over midnight violet\",colors:[\"#00F5D4\",\"#F72585\",\"#0B0321\"],unlockRule:\"battle-pass\",reward:\"blob-3:L4\",finish:\"glitter\"},{id:\"pal-73\",name:\"Cedar Ultraviolet\",tagline:\"Cedar wood ultraviolet light\",colors:[\"#7A4532\",\"#8246FF\",\"#E9E4D8\"],unlockRule:\"battle-pass\",reward:\"blob-4:L1\",finish:\"matte\"},{id:\"pal-74\",name:\"Frosted Chili\",tagline:\"Frost blue chili red\",colors:[\"#13AAE7\",\"#C13A2F\",\"#4C5B2C\"],unlockRule:\"battle-pass\",reward:\"blob-4:L3\",finish:\"polished-metal\"},{id:\"pal-75\",name:\"Moss Rocket\",tagline:\"Moss green rocket pink\",colors:[\"#5B7042\",\"#FA0057\",\"#061F5B\"],unlockRule:\"battle-pass\",reward:\"blob-4:L4\",finish:\"matte\"},{id:\"pal-76\",name:\"Pewter Punch\",tagline:\"Pewter softened hot punch\",colors:[\"#99A0A8\",\"#FF3D7F\",\"#164D37\"],unlockRule:\"battle-pass\",reward:\"cap-2:L1\",finish:\"brushed-metal\"},{id:\"pal-77\",name:\"Neon Glacier Riot\",tagline:\"Cyan hot pink and radioactive lime\",colors:[\"#00F0FF\",\"#FF00E5\",\"#CCFF00\"],unlockRule:\"battle-pass\",reward:\"cap-2:L3\",finish:\"watercolor\"},{id:\"pal-78\",name:\"Cola Lightning\",tagline:\"Cola brown lightning yellow\",colors:[\"#3A2618\",\"#F7FF00\",\"#FA005E\"],unlockRule:\"battle-pass\",reward:\"cap-2:L4\",finish:\"glaze\"},{id:\"pal-79\",name:\"Periwinkle Fuel\",tagline:\"Soft periwinkle diesel orange\",colors:[\"#1325E7\",\"#E0641E\",\"#2F4730\"],unlockRule:\"battle-pass\",reward:\"cap-3:L1\",finish:\"matte\"},{id:\"pal-80\",name:\"Jade Alarm\",tagline:\"Jade calm siren red\",colors:[\"#57A78A\",\"#D91E36\",\"#E7AF13\"],unlockRule:\"battle-pass\",reward:\"cap-3:L3\",finish:\"pearl\"},{id:\"pal-81\",name:\"Neon Ultraviolet Pulse\",tagline:\"Violet beams with mint-charged current\",colors:[\"#8C00FF\",\"#00FFB2\",\"#160021\"],unlockRule:\"battle-pass\",reward:\"cap-3:L4\",finish:\"matte\"},{id:\"pal-82\",name:\"Neon Nightcaller\",tagline:\"Cyan violet flame in black-green fog\",colors:[\"#00FFFF\",\"#9400FF\",\"#131A00\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L1\",finish:\"marbled\"},{id:\"pal-83\",name:\"Ivory Shock\",tagline:\"Ivory calm violet shock\",colors:[\"#F0EEE4\",\"#7C1FD3\",\"#FFB200\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L3\",finish:\"glaze\"},{id:\"pal-84\",name:\"Neon Ruby Arc\",tagline:\"Red-hot signal over green afterglow\",colors:[\"#FF073A\",\"#00FF87\",\"#080F1B\"],unlockRule:\"battle-pass\",reward:\"stalk-2:L4\",finish:\"glitter\"},{id:\"pal-85\",name:\"Maroon Cloud\",tagline:\"Maroon heavy cloud blue\",colors:[\"#6D1E2E\",\"#1381E7\",\"#E5D352\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L1\",finish:\"watercolor\"},{id:\"pal-86\",name:\"Chrome Berry\",tagline:\"Chrome band over berry\",colors:[\"#C3C9D1\",\"#8E2A5C\",\"#FFB347\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L3\",finish:\"polished-metal\"},{id:\"pal-87\",name:\"Lentil Neon\",tagline:\"Lentil tan electric aqua\",colors:[\"#B09A6E\",\"#00FFF0\",\"#5F1B63\"],unlockRule:\"battle-pass\",reward:\"stalk-3:L4\",finish:\"matte\"},{id:\"pal-88\",name:\"Neon Cobalt Fuse\",tagline:\"Blue ignition wired to blazing yellow\",colors:[\"#004DFF\",\"#FFEE00\",\"#0D0221\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L1\",finish:\"glaze\"},{id:\"pal-89\",name:\"Spruce Bonfire\",tagline:\"Dark spruce bonfire orange\",colors:[\"#23493C\",\"#FF7A3D\",\"#0C1735\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L3\",finish:\"matte\"},{id:\"pal-90\",name:\"Lilac Foundry\",tagline:\"Lilac meets foundry steel\",colors:[\"#9813E7\",\"#7B8894\",\"#D4522A\"],unlockRule:\"battle-pass\",reward:\"stalk-4:L4\",finish:\"brushed-metal\"},{id:\"pal-91\",name:\"Topaz Battle\",tagline:\"Topaz gold navy clash\",colors:[\"#F0B429\",\"#182952\",\"#FA007D\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L1\",finish:\"polished-metal\"},{id:\"pal-92\",name:\"Dusk Celery\",tagline:\"Dusky purple celery snap\",colors:[\"#574B6B\",\"#C8D86A\",\"#FA2100\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L3\",finish:\"matte\"},{id:\"pal-93\",name:\"Tide Copperfuse\",tagline:\"Tidal teal copperfuse glow\",colors:[\"#0F7B7B\",\"#C07840\",\"#C2F000\"],unlockRule:\"battle-pass\",reward:\"tanka-2:L4\",finish:\"pearl\"},{id:\"pal-94\",name:\"Punch Driftwood\",tagline:\"Fruit punch on driftwood\",colors:[\"#E63362\",\"#6E5B4A\",\"#1648EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L1\",finish:\"watercolor\"},{id:\"pal-95\",name:\"Ink Lime\",tagline:\"Ink smudge streaked lime\",colors:[\"#23232A\",\"#A8E10C\",\"#7E10EA\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L3\",finish:\"glaze\"},{id:\"pal-96\",name:\"Porcelain Prism\",tagline:\"Porcelain violet over tidal blue\",colors:[\"#F5F1E8\",\"#BD05DA\",\"#005F73\"],unlockRule:\"battle-pass\",reward:\"tanka-3:L4\",finish:\"marbled\"},{id:\"pal-97\",name:\"Wasabi Cloud\",tagline:\"Wasabi heat cloud gray\",colors:[\"#9FBF3B\",\"#8E94A0\",\"#E71363\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L1\",finish:\"matte\"},{id:\"pal-98\",name:\"Eggplant Flare\",tagline:\"Eggplant deep flare yellow\",colors:[\"#41284E\",\"#FFD23F\",\"#5BC0BE\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L3\",finish:\"glitter\"},{id:\"pal-99\",name:\"Stone Rose\",tagline:\"Stone gray antique rose\",colors:[\"#8F8A82\",\"#C46E8E\",\"#2F6DA3\"],unlockRule:\"battle-pass\",reward:\"tanka-4:L4\",finish:\"brushed-metal\"},{id:\"pal-100\",name:\"Neon Quasar Pop\",tagline:\"Yellow green comet over indigo gravity\",colors:[\"#FFEF00\",\"#00FF3C\",\"#2D02B8\"],unlockRule:\"battle-pass\",reward:\"lume-1:L1\",finish:\"glaze\"},{id:\"pal-101\",name:\"Arctic Rust\",tagline:\"Arctic white rusted orange\",colors:[\"#E9F2F5\",\"#9E4A1D\",\"#3E3F8F\"],unlockRule:\"battle-pass\",reward:\"lume-1:L3\",finish:\"brushed-metal\"},{id:\"pal-102\",name:\"Magenta Selvage\",tagline:\"Magenta edge denim blue\",colors:[\"#D8117E\",\"#3B5B8C\",\"#E7D313\"],unlockRule:\"battle-pass\",reward:\"lume-1:L4\",finish:\"matte\"},{id:\"pal-103\",name:\"Haze Saffron\",tagline:\"Purple haze saffron spark\",colors:[\"#8467B8\",\"#F4A81D\",\"#1D4E50\"],unlockRule:\"battle-pass\",reward:\"food:L1\",finish:\"pearl\"},{id:\"pal-104\",name:\"Neon Cyber Reed\",tagline:\"Green circuitry humming beside lemon static\",colors:[\"#00FF66\",\"#FFEA00\",\"#4B0082\"],unlockRule:\"battle-pass\",reward:\"food:L2\",finish:\"glitter\"},{id:\"pal-105\",name:\"Neon Magma Bloom\",tagline:\"Molten orange meeting synthetic magenta\",colors:[\"#FF2E00\",\"#F000FF\",\"#0A0A0F\"],unlockRule:\"battle-pass\",reward:\"food:L3\",finish:\"polished-metal\"},{id:\"pal-106\",name:\"Dune Violet\",tagline:\"Warm dune electric violet\",colors:[\"#C9AE7E\",\"#7D2BF0\",\"#13E7E3\"],unlockRule:\"battle-pass\",reward:\"food:L4\",finish:\"marbled\"},{id:\"pal-107\",name:\"Ember Nightshade\",tagline:\"Violet shadows ember teal\",colors:[\"#523090\",\"#EF4E23\",\"#0C5D68\"],unlockRule:\"battle-pass\",reward:\"food:L5\",finish:\"watercolor\"},{id:\"opal-jelly\",name:\"Opal Jelly\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b3fff0\",\"#9767ff\",\"#fff1ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"bubble-glass\",name:\"Bubble Glass\",tagline:\"Shifting highlights and luminous color\",colors:[\"#58eaff\",\"#b8fff8\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"prism-crystal\",name:\"Prism Crystal\",tagline:\"Shifting highlights and luminous color\",colors:[\"#b18aff\",\"#447bff\",\"#fff2ff\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"holo-foil\",name:\"Holographic Foil\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff54de\",\"#39e5ff\",\"#fff56b\"],unlockRule:\"battle-pass\",finish:\"pearl\"},{id:\"glitter-resin\",name:\"Glitter Resin\",tagline:\"Shifting highlights and luminous color\",colors:[\"#ff319c\",\"#7025ff\",\"#fff6db\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"galaxy-geode\",name:\"Galaxy Geode\",tagline:\"Shifting highlights and luminous color\",colors:[\"#21134e\",\"#7b39e8\",\"#63ffff\"],unlockRule:\"battle-pass\",finish:\"glitter\"},{id:\"caustic-slime\",name:\"Caustic Slime\",tagline:\"Organic horror surface\",colors:[\"#8aa52b\",\"#20300b\",\"#dcff57\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"blister-hide\",name:\"Blister Hide\",tagline:\"Organic horror surface\",colors:[\"#9e435f\",\"#2d1727\",\"#e7bb72\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"rotten-rind\",name:\"Rotten Rind\",tagline:\"Organic horror surface\",colors:[\"#626124\",\"#211916\",\"#a2b16b\"],unlockRule:\"battle-pass\",finish:\"matte\"},{id:\"parasite-nest\",name:\"Parasite Nest\",tagline:\"Organic horror surface\",colors:[\"#786541\",\"#151c14\",\"#ece2b0\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"exposed-sinew\",name:\"Exposed Sinew\",tagline:\"Organic horror surface\",colors:[\"#b72945\",\"#300b24\",\"#efb5a1\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"abyssal-maw\",name:\"Abyssal Maw\",tagline:\"Organic horror surface\",colors:[\"#522045\",\"#100d19\",\"#d9e6a7\"],unlockRule:\"battle-pass\",finish:\"glaze\"},{id:\"circuit-alloy\",name:\"Circuit Alloy\",tagline:\"Machine surface\",colors:[\"#273f50\",\"#0a111c\",\"#4effdc\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"servo-armor\",name:\"Servo Armor\",tagline:\"Machine surface\",colors:[\"#617080\",\"#141b25\",\"#ff6739\"],unlockRule:\"battle-pass\",finish:\"brushed-metal\"},{id:\"chrome-rib\",name:\"Chrome Rib\",tagline:\"Machine surface\",colors:[\"#bfcde1\",\"#202f46\",\"#ffffff\"],unlockRule:\"battle-pass\",finish:\"polished-metal\"},{id:\"carbon-mech\",name:\"Carbon Mech\",tagline:\"Machine surface\",colors:[\"#323d46\",\"#080d15\",\"#95bac9\"],unlockRule:\"battle-pass\"},{id:\"hazard-panel\",name:\"Hazard Panel\",tagline:\"Machine surface\",colors:[\"#edb932\",\"#131a20\",\"#ffe9a2\"],unlockRule:\"battle-pass\"},{id:\"reactor-glass\",name:\"Reactor Glass\",tagline:\"Machine surface\",colors:[\"#48e8ff\",\"#063a55\",\"#d4ffff\"],unlockRule:\"battle-pass\",finish:\"glaze\"}];var ft=\"myr5-recipe-v1\";var Sc=64*1024;var $r=[{id:32,name:\"Plate Steel\",roughness:.34,metalness:.82,relief:.024,bump:.012,sheen:0,sheenRoughness:.7,clearcoat:.35,clearcoatRoughness:.24},{id:33,name:\"Rubber Grip\",roughness:.95,metalness:0,relief:.055,bump:.022,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:34,name:\"Chain Mail\",roughness:.41,metalness:.78,relief:.034,bump:.014,sheen:0,sheenRoughness:.7,clearcoat:.3,clearcoatRoughness:.25},{id:35,name:\"Track Rubber\",roughness:.94,metalness:0,relief:.038,bump:.016,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:36,name:\"Denim\",roughness:.86,metalness:0,relief:.012,bump:.011,sheen:.22,sheenRoughness:.96,clearcoat:0,clearcoatRoughness:.5},{id:37,name:\"Hex Tread\",roughness:.82,metalness:.04,relief:.052,bump:.014,sheen:0,sheenRoughness:.9,clearcoat:.08,clearcoatRoughness:.4},{id:38,name:\"Sweatshirt Fleece\",roughness:.99,metalness:0,relief:.05,bump:.032,sheen:.74,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},{id:39,name:\"Quilted\",roughness:.89,metalness:0,relief:.07,bump:.012,sheen:.14,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:40,name:\"Speckled\",roughness:.96,metalness:0,relief:.03,bump:.028,sheen:.34,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5},{id:41,name:\"Hammered Bronze\",roughness:.39,metalness:.78,relief:.025,bump:.025,sheen:0,sheenRoughness:.7,clearcoat:.28,clearcoatRoughness:.22},{id:42,name:\"Fine Stripe\",roughness:.91,metalness:0,relief:.042,bump:.012,sheen:.08,sheenRoughness:.92,clearcoat:0,clearcoatRoughness:.5},{id:43,name:\"Snake Skin\",roughness:.68,metalness:.02,relief:.019,bump:.023,sheen:.1,sheenRoughness:.76,clearcoat:.08,clearcoatRoughness:.4},{id:44,name:\"Holey\",roughness:.96,metalness:0,relief:.039,bump:.025,sheen:0,sheenRoughness:.9,clearcoat:0,clearcoatRoughness:.5},{id:45,name:\"Woven Mat\",roughness:.9,metalness:0,relief:.014,bump:.014,sheen:.08,sheenRoughness:.94,clearcoat:0,clearcoatRoughness:.5},{id:46,name:\"Petal\",roughness:.51,metalness:0,relief:.025,bump:.009,sheen:.52,sheenRoughness:.72,clearcoat:.12,clearcoatRoughness:.3},{id:47,name:\"Graph Paper\",roughness:.93,metalness:0,relief:.012,bump:.017,sheen:.16,sheenRoughness:.97,clearcoat:0,clearcoatRoughness:.5},{id:48,name:\"Bamboo\",roughness:.57,metalness:0,relief:.027,bump:.008,sheen:.18,sheenRoughness:.62,clearcoat:.12,clearcoatRoughness:.28},{id:49,name:\"Dragon Scale\",roughness:.31,metalness:.16,relief:.043,bump:.01,sheen:.24,sheenRoughness:.42,clearcoat:.72,clearcoatRoughness:.16},{id:50,name:\"Cool Graph Paper\",roughness:.56,metalness:.23,relief:.021,bump:.008,sheen:0,sheenRoughness:.8,clearcoat:.12,clearcoatRoughness:.3},{id:51,name:\"Terry Cloth\",roughness:.98,metalness:0,relief:.014,bump:.026,sheen:.62,sheenRoughness:.99,clearcoat:0,clearcoatRoughness:.5},{id:52,name:\"Pebble Path\",roughness:.77,metalness:0,relief:.038,bump:.018,sheen:0,sheenRoughness:.8,clearcoat:.08,clearcoatRoughness:.4},{id:53,name:\"Wiggles\",roughness:.99,metalness:0,relief:.016,bump:.016,sheen:0,sheenRoughness:.95,clearcoat:0,clearcoatRoughness:.5},{id:54,name:\"River Stone\",roughness:.72,metalness:.01,relief:.031,bump:.019,sheen:.04,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.32},{id:55,name:\"Moss\",roughness:.99,metalness:0,relief:.022,bump:.023,sheen:.38,sheenRoughness:.98,clearcoat:0,clearcoatRoughness:.5}],jr={id:56,name:\"64-bit Skin\",roughness:.58,metalness:.12,relief:.018,bump:.01,sheen:0,sheenRoughness:.7,clearcoat:.1,clearcoatRoughness:.4},Hr=[{id:57,name:\"Opal Jelly\",roughness:.06,metalness:0,relief:.004,bump:.001,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.035},{id:58,name:\"Bubble Glass\",roughness:.035,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},{id:59,name:\"Prism Crystal\",roughness:.045,metalness:0,relief:.052,bump:.008,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.03},{id:60,name:\"Holographic Foil\",roughness:.18,metalness:.88,relief:.022,bump:.013,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.045},{id:61,name:\"Glitter Resin\",roughness:.075,metalness:0,relief:.006,bump:.002,sheen:0,sheenRoughness:.3,clearcoat:1,clearcoatRoughness:.025},{id:62,name:\"Galaxy Geode\",roughness:.22,metalness:.25,relief:.065,bump:.014,sheen:0,sheenRoughness:.3,clearcoat:.8,clearcoatRoughness:.06},{id:63,name:\"Caustic Slime\",roughness:.055,metalness:0,relief:.035,bump:.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:64,name:\"Blister Hide\",roughness:.18,metalness:0,relief:.065,bump:.023,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:65,name:\"Rotten Rind\",roughness:.94,metalness:0,relief:.05,bump:.025,sheen:0,sheenRoughness:.6,clearcoat:0,clearcoatRoughness:.07},{id:66,name:\"Parasite Nest\",roughness:.31,metalness:0,relief:.07,bump:.027,sheen:0,sheenRoughness:.6,clearcoat:.6,clearcoatRoughness:.07},{id:67,name:\"Exposed Sinew\",roughness:.2,metalness:0,relief:.045,bump:.017,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:68,name:\"Abyssal Maw\",roughness:.26,metalness:0,relief:.065,bump:.023,sheen:0,sheenRoughness:.6,clearcoat:.8,clearcoatRoughness:.07},{id:69,name:\"Circuit Alloy\",roughness:.19,metalness:.83,relief:.027,bump:.01,sheen:0,sheenRoughness:.6,clearcoat:.6,clearcoatRoughness:.07},{id:70,name:\"Servo Armor\",roughness:.34,metalness:.82,relief:.055,bump:.013,sheen:0,sheenRoughness:.6,clearcoat:.4,clearcoatRoughness:.07},{id:71,name:\"Chrome Rib\",roughness:.09,metalness:.96,relief:.05,bump:.012,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07},{id:72,name:\"Carbon Mech\",roughness:.64,metalness:.18,relief:.018,bump:.013,sheen:0,sheenRoughness:.6,clearcoat:.25,clearcoatRoughness:.07},{id:73,name:\"Hazard Panel\",roughness:.46,metalness:.55,relief:.032,bump:.014,sheen:0,sheenRoughness:.6,clearcoat:.4,clearcoatRoughness:.07},{id:74,name:\"Reactor Glass\",roughness:.045,metalness:0,relief:.018,bump:.004,sheen:0,sheenRoughness:.6,clearcoat:1,clearcoatRoughness:.07}],Wr=new Map([...$r,jr,...Hr].map(e=>[e.id,e])),mt=e=>Wr.get(e);var gt=(e,a,t)=>a.unlockRule===\"default\"||ae(e,a.id,typeof t==\"string\"?t:void 0),yt=e=>ra.includes(e.primary.toLowerCase())?\"default\":\"battle-pass\",Kr=(e=L())=>Ie(\"boss-skin\",w(typeof e==\"string\"?e:L(),`${typeof e==\"string\"?e:L()}-skin`)),Yr=(e,a)=>!j.includes(e.id)&&(ie.includes(e.id)||ae(\"texture\",e.id,a))&&(e.id!==\"coach-64-bit\"||Kr(a)),kt=(e,a)=>gt(\"color\",e,a),wt=(e,a)=>gt(\"palette\",e,a),Xr={id:30,name:\"Flat\",realm:\"\",primary:\"#c7c3ce\",secondary:\"#6d6a75\",accent:\"#ffffff\",emissive:\"#000000\",roughness:.55,metalness:0,detail:\"flat\"},ma={id:31,name:\"Clay\",realm:\"\",primary:\"#b7a68e\",secondary:\"#7a6b57\",accent:\"#ddcdb3\",emissive:\"#000000\",roughness:.92,metalness:0,detail:\"clay\"},Nc={id:\"flat\",displayName:\"Flat\",unlockRule:\"battle-pass\",familyId:Xr.id,defaultColorId:\"#7f7d78\"},_t={id:\"clay\",displayName:\"Clay\",unlockRule:\"default\",familyId:ma.id,defaultColorId:\"#c4a77d\"},Vr=N.map(e=>({id:\"legacy-color-\"+e.id,displayName:e.name+\" (original)\",unlockRule:yt(e),primary:e.primary,secondary:e.secondary,accent:e.accent})),Jr=[{id:\"default-slate\",displayName:\"Slate\",unlockRule:\"default\",primary:\"#8b8f9a\",secondary:\"#4a4d55\",accent:\"#e7e9ee\"},{id:\"default-clay\",displayName:\"Warm Clay\",unlockRule:\"default\",primary:\"#b7a68e\",secondary:\"#7a6b57\",accent:\"#ddcdb3\"},{id:\"default-ruby\",displayName:\"Ruby\",unlockRule:\"default\",primary:\"#a23b4a\",secondary:\"#4f1620\",accent:\"#f2a3ae\"},{id:\"default-sapphire\",displayName:\"Sapphire\",unlockRule:\"default\",primary:\"#2d5aa0\",secondary:\"#122a4d\",accent:\"#a9c9f5\"},{id:\"default-moss\",displayName:\"Moss\",unlockRule:\"default\",primary:\"#4c7a3f\",secondary:\"#20351a\",accent:\"#c3e6a8\"},{id:\"default-gold\",displayName:\"Gold\",unlockRule:\"default\",primary:\"#c9a13a\",secondary:\"#5f4a15\",accent:\"#ffe9a8\"},{id:\"default-charcoal\",displayName:\"Charcoal\",unlockRule:\"default\",primary:\"#333238\",secondary:\"#131318\",accent:\"#8d8d96\"},{id:\"default-blush\",displayName:\"Blush\",unlockRule:\"default\",primary:\"#d98fa0\",secondary:\"#7a3d49\",accent:\"#ffdbe4\"}].map(e=>({...e,unlockRule:yt(e)})),Qr={\"texture-1\":1,\"texture-2\":3,\"texture-3\":5},Zr=[{id:\"chest-plate-steel\",name:\"Plate Steel\",slot:\"texture-1\",track:\"chest\",familyId:32},{id:\"chest-rubber-grip\",name:\"Rubber Grip\",slot:\"texture-2\",track:\"chest\",familyId:33},{id:\"chest-chain-mail\",name:\"Chain Mail\",slot:\"texture-3\",track:\"chest\",familyId:34},{id:\"quads-track-rubber\",name:\"Track Rubber\",slot:\"texture-1\",track:\"quads\",familyId:35},{id:\"quads-denim\",name:\"Denim\",slot:\"texture-2\",track:\"quads\",familyId:36},{id:\"quads-hex-tread\",name:\"Hex Tread\",slot:\"texture-3\",track:\"quads\",familyId:37},{id:\"glutes-sweatshirt-fleece\",name:\"Sweatshirt Fleece\",slot:\"texture-1\",track:\"glutes\",familyId:38},{id:\"glutes-quilted\",name:\"Quilted\",slot:\"texture-2\",track:\"glutes\",familyId:39},{id:\"glutes-peach\",name:\"Speckled\",slot:\"texture-3\",track:\"glutes\",familyId:40},{id:\"arms-hammered-bronze\",name:\"Hammered Bronze\",slot:\"texture-1\",track:\"arms\",familyId:41},{id:\"arms-rope\",name:\"Fine Stripe\",slot:\"texture-2\",track:\"arms\",familyId:42},{id:\"arms-leather\",name:\"Snake Skin\",slot:\"texture-3\",track:\"arms\",familyId:43},{id:\"yoga-cork\",name:\"Holey\",slot:\"texture-1\",track:\"yoga\",familyId:44},{id:\"yoga-woven-mat\",name:\"Woven Mat\",slot:\"texture-2\",track:\"yoga\",familyId:45},{id:\"yoga-petal\",name:\"Petal\",slot:\"texture-3\",track:\"yoga\",familyId:46},{id:\"martial-arts-canvas-gi\",name:\"Graph Paper\",slot:\"texture-1\",track:\"martial-arts\",familyId:47},{id:\"martial-arts-bamboo\",name:\"Bamboo\",slot:\"texture-2\",track:\"martial-arts\",familyId:48},{id:\"martial-arts-dragon-scale\",name:\"Dragon Scale\",slot:\"texture-3\",track:\"martial-arts\",familyId:49},{id:\"cardio-mesh\",name:\"Cool Graph Paper\",slot:\"texture-1\",track:\"cardio\",familyId:50},{id:\"cardio-terry-cloth\",name:\"Terry Cloth\",slot:\"texture-2\",track:\"cardio\",familyId:51},{id:\"cardio-pebble-path\",name:\"Pebble Path\",slot:\"texture-3\",track:\"cardio\",familyId:52},{id:\"meditation-sand-garden\",name:\"Wiggles\",slot:\"texture-1\",track:\"meditation\",familyId:53},{id:\"meditation-river-stone\",name:\"River Stone\",slot:\"texture-2\",track:\"meditation\",familyId:54},{id:\"meditation-moss\",name:\"Moss\",slot:\"texture-3\",track:\"meditation\",familyId:55}],es=new Map(Object.entries(ta).map(([e,[a]])=>[a,e])),St=e=>ie.includes(e)?\"default\":\"battle-pass\",xt=Zr.map(e=>({id:e.id,displayName:e.name,unlockRule:St(e.id),track:e.track,passLevel:Qr[e.slot],packId:\"pack-\"+e.track,familyId:e.familyId,defaultColorId:\"#7f7d78\"})),as=N.map(e=>{let a=\"legacy-\"+e.id,t=xt.find(r=>r.id===es.get(a));return{id:a,displayName:e.name,unlockRule:St(a),track:t?.track,passLevel:t?.passLevel,legacy:!0,familyId:e.id,defaultColorId:\"legacy-color-\"+e.id}}),ts={id:\"coach-64-bit\",displayName:\"64-bit Pixel Finish\",unlockRule:\"battle-pass\",familyId:56,defaultColorId:\"#7f7d78\"},rs=[{id:\"opal-jelly\",displayName:\"Opal Jelly\",unlockRule:\"battle-pass\",familyId:57,defaultColorId:\"opal-jelly\"},{id:\"bubble-glass\",displayName:\"Bubble Glass\",unlockRule:\"battle-pass\",familyId:58,defaultColorId:\"bubble-glass\"},{id:\"prism-crystal\",displayName:\"Prism Crystal\",unlockRule:\"battle-pass\",familyId:59,defaultColorId:\"prism-crystal\"},{id:\"holo-foil\",displayName:\"Holographic Foil\",unlockRule:\"battle-pass\",familyId:60,defaultColorId:\"holo-foil\"},{id:\"glitter-resin\",displayName:\"Glitter Resin\",unlockRule:\"battle-pass\",familyId:61,defaultColorId:\"glitter-resin\"},{id:\"galaxy-geode\",displayName:\"Galaxy Geode\",unlockRule:\"battle-pass\",familyId:62,defaultColorId:\"galaxy-geode\"},{id:\"caustic-slime\",displayName:\"Caustic Slime\",unlockRule:\"battle-pass\",familyId:63,defaultColorId:\"caustic-slime\"},{id:\"blister-hide\",displayName:\"Blister Hide\",unlockRule:\"battle-pass\",familyId:64,defaultColorId:\"blister-hide\"},{id:\"rotten-rind\",displayName:\"Rotten Rind\",unlockRule:\"battle-pass\",familyId:65,defaultColorId:\"rotten-rind\"},{id:\"parasite-nest\",displayName:\"Parasite Nest\",unlockRule:\"battle-pass\",familyId:66,defaultColorId:\"parasite-nest\"},{id:\"exposed-sinew\",displayName:\"Exposed Sinew\",unlockRule:\"battle-pass\",familyId:67,defaultColorId:\"exposed-sinew\"},{id:\"abyssal-maw\",displayName:\"Abyssal Maw\",unlockRule:\"battle-pass\",familyId:68,defaultColorId:\"abyssal-maw\"},{id:\"circuit-alloy\",displayName:\"Circuit Alloy\",unlockRule:\"battle-pass\",familyId:69,defaultColorId:\"circuit-alloy\"},{id:\"servo-armor\",displayName:\"Servo Armor\",unlockRule:\"battle-pass\",familyId:70,defaultColorId:\"servo-armor\"},{id:\"chrome-rib\",displayName:\"Chrome Rib\",unlockRule:\"battle-pass\",familyId:71,defaultColorId:\"chrome-rib\"},{id:\"carbon-mech\",displayName:\"Carbon Mech\",unlockRule:\"battle-pass\",familyId:72,defaultColorId:\"carbon-mech\"},{id:\"hazard-panel\",displayName:\"Hazard Panel\",unlockRule:\"battle-pass\",familyId:73,defaultColorId:\"hazard-panel\"},{id:\"reactor-glass\",displayName:\"Reactor Glass\",unlockRule:\"battle-pass\",familyId:74,defaultColorId:\"reactor-glass\"}].filter(e=>!j.includes(e.id)),ss=[...rs,_t,...as,...xt,ts].filter(e=>!j.includes(e.id)),Ct=[...Jr,...Vr],vt=ut.map(({name:e,...a})=>({...a,displayName:e})),os=e=>ss.find(a=>a.id===e),cs=e=>Ct.find(a=>a.id===e),ns=e=>vt.find(a=>a.id===e);function is(e){let[a,t,r]=e.colors;return{primary:a,secondary:t,accent:r,paletteId:e.id}}var ls=/^#[0-9a-f]{6}$/i,ht=(e,a,t)=>\"#\"+[1,3,5].map(r=>Math.round(parseInt(e.slice(r,r+2),16)*(1-t)+a*t).toString(16).padStart(2,\"0\")).join(\"\"),ds=(e,a)=>ra.includes(e)||Ct.some(t=>kt(t,a)&&[t.primary,t.secondary,t.accent].some(r=>r.toLowerCase()===e))||vt.some(t=>wt(t,a)&&t.colors.some(r=>r.toLowerCase()===e));function pt(e,a=!1,t){if(ls.test(e)){let o=e.toLowerCase();return a||ds(o,t)?{primary:o,secondary:ht(o,0,.55),accent:ht(o,255,.55)}:void 0}let r=cs(e);if(r)return a||kt(r,t)?{primary:r.primary,secondary:r.secondary,accent:r.accent}:void 0;let s=ns(e);if(s)return a||wt(s,t)?is(s):void 0}function Rt(e){try{if(!e)return;na(e)}catch{}}try{let e=localStorage.getItem(ft);e&&Rt(JSON.parse(e))}catch{}globalThis.addEventListener?.(\"myr5:recipe\",e=>Rt(e.detail));function Et(e,a){let t=e?.[a],r=e?.[Ia[a]];return t&&r&&r!==t?{...t,colorId:r.colorId}:t}function Ft(e,a,t=!1,r){if(!a)return{...N[e],sparkle:0,paletteId:void 0};let s=os(a.textureId),o=s&&(t||Yr(s,r))&&s.familyId>=0?s:_t,c=mt(o.familyId),n=o.legacy?N[o.familyId]:o.id===\"clay\"?ma:c?{id:c.id,name:c.name,realm:\"\",primary:\"#8b8f9a\",secondary:\"#4a4d55\",accent:\"#e7e9ee\",emissive:\"#000000\",roughness:c.roughness,metalness:c.metalness,detail:c.name.toLowerCase().replace(/[^a-z0-9]+/g,\"-\")}:ma,f=pt(a.colorId,t,r)??pt(o.defaultColorId,t,r)??n,i=Number.isFinite(a.metallic)?Math.max(0,Math.min(1,a.metallic)):n.metalness,l=Number.isFinite(a.sparkle)?Math.max(0,Math.min(1,a.sparkle)):0;return{...n,...f,paletteId:\"paletteId\"in f?f.paletteId:void 0,metalness:i,sparkle:l}}var bs=\"myr5-war-room-coaches-v2\",At=()=>`${bs}/${encodeURIComponent(x())}`;async function us(e){let a=await fetch(\"/pod/gala-coaches/manifest.json\");if(!a.ok)throw Error(\"Coach sprites are unavailable.\");let t=await a.json(),r=t.sprites.filter(i=>E.some(l=>l.id===i.id)),s=new Map,o=async i=>{let l=new Image;return l.src=\"/pod/gala-coaches/\"+i,await l.decode(),l};await Promise.all(Object.entries(t.sheets).map(async([i,l])=>{let[d,b]=await Promise.all([o(l.image),o(l.mask)]);s.set(i,{image:d,mask:b})}));let c=()=>{try{return Je(localStorage.getItem(\"myr5-recipe-v1\")||\"null\")}catch{return _e()}},n=new Map;function f(i,l=!1,d,b=!1){let y=c(),h=d&&globalThis.GalaAvatar?.skinColor?.(d),k=b&&ye(i.id)?[\"#e8bc4d\",\"#ffe4a1\",\"#6b4214\"]:h?[h,h,\"#fff9df\"]:[\"body\",\"head\",\"eye\"].map(S=>Ft(y.styles[S],Et(y.materials,S),!0,i.id).primary),O=JSON.stringify([i.id,l,k]);if(n.has(O))return n.get(O);let[de,u,p,m]=i.frame,_=e.createElement(\"canvas\");_.width=p,_.height=m;let z=_.getContext(\"2d\",{willReadFrequently:!0}),I=e.createElement(\"canvas\");I.width=p,I.height=m;let re=s.get(i.sheet);z.drawImage(re.image,de,u,p,m,0,0,p,m);let g=z.getImageData(0,0,p,m),H=I.getContext(\"2d\",{willReadFrequently:!0});H.drawImage(re.mask,de,u,p,m,0,0,p,m);let W=H.getImageData(0,0,p,m).data,be=S=>{let U=parseInt(S.slice(1),16);return[U>>16,U>>8&255,U&255]};for(let S=0;S<g.data.length;S+=4){if(!g.data[S+3])continue;let U=W[S],ha=U===0?[33,23,46]:be(k[Math.min(2,Math.round(U/64)-1)]),Mt=g.data[S]/184;for(let se=0;se<3;se++)g.data[S+se]=l?35:U===0?ha[se]:Math.min(255,Math.round(ha[se]*Mt))}return z.putImageData(g,0,0),n.set(O,_),_}return{sprites:r,art:f}}async function Wc(e){let{sprites:a,art:t}=await us(e),r=i=>bt(i,{}),s={body:null,pet:null,goldenBody:!1},o=\"\";function c(){let i=At(),l=null;try{l=localStorage.getItem(i)}catch{}if(i+\" \"+l!==o){o=i+\" \"+l,s={body:null,pet:null,goldenBody:!1};try{let d=JSON.parse(l||\"null\");for(let b of[\"body\",\"pet\"])a.some(y=>y.id===d?.[b]&&(b===\"body\"||y.kind===b))&&!r(d[b])&&(s[b]=d[b]);s.goldenBody=d?.goldenBody===!0&&!!s.body&&ye(s.body)}catch{}}}c();function n(i,l){c();let d=e.createElement(\"fieldset\"),b=e.createElement(\"legend\");b.textContent=i===\"body\"?\"Coach body\":\"Coach pets\",d.append(b),d.className=\"gala-coach-choices\";let y=e.createElement(\"p\");y.className=\"help\",y.textContent=i===\"body\"?\"Choose a coach character, then change its colour in the mirror. Choose Gala body to show your Gala wardrobe.\":\"Coach pets unlock with their coach bodies.\",d.append(y);let h=(u,p=!1)=>{if(u&&r(u))return;let m={...s,[i]:u,...i===\"body\"?{goldenBody:p}:{}};try{localStorage.setItem(At(),JSON.stringify(m)),s=m,l()}catch{d.setAttribute(\"aria-label\",\"This choice could not be saved. Storage is unavailable.\")}},k=e.createElement(\"button\");k.type=\"button\",k.textContent=i===\"body\"?\"Gala body\":\"Gala pet\",k.setAttribute(\"aria-pressed\",String(!s[i])),k.onclick=()=>h(null),d.append(k);let O=new Set(me(R().paths)),de=[...a.filter(u=>i===\"body\"||u.kind===i)].sort((u,p)=>+!!r(u.id)-+!!r(p.id)||Number(O.has(p.id))-Number(O.has(u.id)));for(let u of de){let p=r(u.id),m=e.createElement(\"button\"),_=E.find(g=>g.id===u.id)?.label||u.family;m.type=\"button\",m.dataset.coachSprite=u.id,m.setAttribute(\"aria-label\",_),m.setAttribute(\"aria-pressed\",String(s[i]===u.id&&(i!==\"body\"||!s.goldenBody)));let z=t(u),I=e.createElement(\"canvas\");I.width=z.width,I.height=z.height,I.getContext(\"2d\").drawImage(z,0,0);let re=e.createElement(\"span\");if(re.textContent=_,m.append(I,re),m.onclick=()=>{if(p){y.textContent=`Preview only \\xB7 How to unlock ${_}: ${p}.`;return}h(u.id)},d.append(m),i===\"body\"&&ye(u.id)&&!p){let g=e.createElement(\"button\");g.type=\"button\",g.dataset.coachSprite=u.id,g.dataset.goldenCoach=\"true\",g.setAttribute(\"aria-label\",\"Golden \"+_),g.setAttribute(\"aria-pressed\",String(s.body===u.id&&s.goldenBody));let H=t(u,!1,void 0,!0),W=e.createElement(\"canvas\");W.width=H.width,W.height=H.height,W.getContext(\"2d\").drawImage(H,0,0);let be=e.createElement(\"span\");be.textContent=\"Golden \"+_,g.append(W,be),g.onclick=()=>h(u.id,!0),d.append(g)}}return d}function f(i,l,d,b={}){c();let y=b.petOnly?s.pet:s.body,h=a.find(O=>O.id===y);if(!h||r(h.id)){i(l,d,b);return}l.width=64,l.height=96;let k=l.getContext(\"2d\");k.imageSmoothingEnabled=!1,b.petOnly?k.drawImage(t(h,!1,d,!b.petOnly&&s.goldenBody),0,0,48,36,0,60,48,36):h.kind===\"pet\"?k.drawImage(t(h,!1,d,!b.petOnly&&s.goldenBody),0,0,48,36,0,48,64,48):k.drawImage(t(h,!1,d,!b.petOnly&&s.goldenBody),0,0)}return{picker:n,draw:f,get hasBody(){return c(),!!s.body&&!r(s.body)},get hasPet(){return c(),!!s.pet&&!r(s.pet)}}}export{us as loadCoachSpritePreviews,Wc as loadWarRoomCoaches};\n","war-room/effect-picker.mjs":"import { EFFECT_GROUPS, AURA_OPTIONS, EFFECT_CHOICES_KEY, readEffectChoices, saveEffectChoice } from '../arcade/power/aura-options.mjs';\r\n\r\nconst animalFrames = {\r\n  rabbit:[32,26], fox:[64,36], bear:[64,33], deer:[48,52], wolf:[64,40], boar:[64,40],\r\n};\r\nconst plantCells = { fern:1, vine:14, flower:48, mushroom:70, grass:0, reed:6 };\r\nconst crystalAssets = {\r\n  blue:'crystal-blue.png', ice:'crystal-icy.png', red:'crystal-red-small.png',\r\n  green:'crystal-green-alt.png', gold:'crystal-gold.png', purple:'crystal-purple.png',\r\n};\r\nconst imageCache = new Map();\r\n\r\nfunction sourceFor(option) {\r\n  const id=option.id, ecology=option.ecology;\r\n  if (ecology?.kind==='plant') return {url:'/arcade/hold/assets/flowers-plants_2.png',sx:plantCells[ecology.variant]*12,sy:0,sw:12,sh:24};\r\n  if (ecology?.kind==='animal') {\r\n    const [sw,sh]=animalFrames[ecology.variant]||[64,40],name=ecology.variant[0].toUpperCase()+ecology.variant.slice(1);\r\n    const action=ecology.variant==='wolf'?'Walk':'Idle';\r\n    return {url:`/arcade/hold/assets/${ecology.variant}/${name}/${name}_${action}.png`,sx:0,sy:0,sw,sh};\r\n  }\r\n  if (ecology?.kind==='mineral'&&ecology.variant==='rock') return {url:'/arcade/hold/assets/rocks-original.png',sx:0,sy:0,sw:32,sh:32};\r\n  if (ecology?.kind==='mineral'&&ecology.variant==='crystal') return {url:`/arcade/hold/assets/crystals/PNG/32x32/${crystalAssets[ecology.palette]||crystalAssets.blue}`};\r\n  if (option.asset) return {url:`/arcade/${id==='blizzard'?'hold':'power'}/assets/${option.asset}`,sx:0,sy:0,sw:100,sh:100};\r\n  if (id==='lightning') return {url:'/arcade/power/assets/pixelated_tilesheet.png',sx:0,sy:0,sw:64,sh:64};\r\n  if (id==='floor') return {url:'/arcade/power/assets/11_fire_spritesheet.png',sx:0,sy:0,sw:100,sh:100};\r\n  // Random and Classic keep a real, familiar effect swatch without generating emoji art.\r\n  return {url:'/arcade/power/assets/9_brightfire_spritesheet.png',sx:0,sy:0,sw:100,sh:100,frame:24};\r\n}\r\nfunction loadImage(url) {\r\n  if(imageCache.has(url)) return imageCache.get(url);\r\n  const promise=new Promise((resolve,reject)=>{const image=new Image();image.onload=()=>resolve(image);image.onerror=()=>reject(Error(`Could not load effect preview ${url}`));image.src=url;});\r\n  imageCache.set(url,promise);return promise;\r\n}\r\nasync function paint(canvas,option) {\r\n  const ctx=canvas.getContext('2d');if(!ctx)return false;\r\n  const spec=sourceFor(option);\r\n  try {\r\n    const image=await loadImage(spec.url);if(!canvas.isConnected)return false;\r\n    const sx=spec.sx??0,sy=spec.sy??0,sw=spec.sw??image.naturalWidth,sh=spec.sh??image.naturalHeight;\r\n    let frame=spec.frame??0,columns=option.columns;\r\n    if(option.asset&&columns){const count=columns*(option.rows||columns);frame=Math.min(count-1,Math.floor(count/3));}\r\n    else if(option.id==='floor')frame=9;\r\n    if(option.asset&&columns){const size=100;spec.sx=(frame%columns)*size;spec.sy=Math.floor(frame/columns)*size;}\r\n    if(option.id==='floor'){spec.sx=(frame%8)*100;spec.sy=Math.floor(frame/8)*100;}\r\n    const cropX=spec.sx??sx,cropY=spec.sy??sy;\r\n    const tile=canvas.ownerDocument.createElement('canvas');tile.width=spec.sw||sw;tile.height=spec.sh||sh;\r\n    const tileCtx=tile.getContext('2d');tileCtx.drawImage(image,cropX,cropY,tile.width,tile.height,0,0,tile.width,tile.height);\r\n    const pixels=tileCtx.getImageData(0,0,tile.width,tile.height),data=pixels.data;\r\n    let left=tile.width,top=tile.height,right=-1,bottom=-1;\r\n    for(let y=0;y<tile.height;y++)for(let x=0;x<tile.width;x++){\r\n      const i=(y*tile.width+x)*4;\r\n      if(option.ecology?.kind==='plant'&&data[i]===34&&data[i+1]===32&&data[i+2]===52)data[i+3]=0;\r\n      if(data[i+3]>12){left=Math.min(left,x);right=Math.max(right,x);top=Math.min(top,y);bottom=Math.max(bottom,y);}\r\n    }\r\n    if(right<left)return false;\r\n    tileCtx.putImageData(pixels,0,0);\r\n    const visibleW=right-left+1,visibleH=bottom-top+1,scale=Math.min(34/visibleW,34/visibleH);\r\n    const w=visibleW*scale,h=visibleH*scale;\r\n    ctx.clearRect(0,0,40,40);ctx.imageSmoothingEnabled=false;\r\n    ctx.drawImage(tile,left,top,visibleW,visibleH,(40-w)/2,(40-h)/2,w,h);\r\n    return true;\r\n  } catch { ctx.clearRect(0,0,40,40);return false; }\r\n}\r\n\r\nexport function mountEffectPicker(anchor, {document:doc=anchor?.ownerDocument||globalThis.document}={}) {\r\n  if(!anchor||!doc)return {element:null,dispose(){}};\r\n  const old=anchor.parentElement?.querySelector(':scope > .war-room-effects');old?.remove();\r\n  const id=`war-room-aura-menu-${Math.random().toString(36).slice(2)}`;\r\n  const root=doc.createElement('details');root.className='war-room-effects';root.dataset.effectsMenu='';\r\n  root.setAttribute('aria-label','Exercise effects');\r\n  const summary=doc.createElement('summary');summary.id=`${id}-trigger`;summary.textContent='Auras';summary.setAttribute('aria-label','Choose an aura by exercise');summary.setAttribute('aria-controls',id);root.append(summary);\r\n  const menu=doc.createElement('div');menu.id=id;menu.className='effect-picker-menu';menu.setAttribute('role','group');menu.setAttribute('aria-labelledby',summary.id);menu.setAttribute('popover','manual');menu.hidden=true;\r\n  const status=doc.createElement('p');status.className='effect-picker-status';status.setAttribute('role','status');status.setAttribute('aria-live','polite');\r\n  let choices=readEffectChoices(),disposed=false;\r\n  const optionMap=new Map(AURA_OPTIONS.map(option=>[option.id,option]));\r\n  const groupLabels=new Map();\r\n  function drawGroup(group,section) {\r\n    const list=doc.createElement('fieldset');list.className='effect-choice-list';list.setAttribute('role','radiogroup');list.setAttribute('aria-label',`${group.label} effect`);\r\n    const legend=doc.createElement('legend');legend.textContent=`${group.label} effect`;list.append(legend);\r\n    const selected=choices[group.id]||group.defaultEffect||'random';\r\n    for(const id of group.options){\r\n      const option=optionMap.get(id);if(!option)continue;\r\n      const label=doc.createElement('label');label.className='effect-choice';\r\n      const radio=doc.createElement('input');radio.type='radio';radio.name=`war-room-effect-${group.id}`;radio.value=id;radio.checked=id===selected;radio.dataset.effectGroup=group.id;radio.dataset.effectChoice=id;\r\n      const thumb=doc.createElement('canvas');thumb.className='effect-thumb';thumb.width=thumb.height=40;thumb.setAttribute('aria-hidden','true');thumb.dataset.effectThumb=id;\r\n      const text=doc.createElement('span');text.textContent=option.label;label.append(radio,thumb,text);list.append(label);\r\n      radio.addEventListener('change',()=>{\r\n        if(!radio.checked)return;\r\n        if(!saveEffectChoice(group.id,id)){status.textContent='This effect could not be saved on this device.';return;}\r\n        choices={...choices,[group.id]:id};groupLabels.get(group.id).textContent=option.label;status.textContent=`Saved on this device · ${group.label}: ${option.label}.`;\r\n      });\r\n    }\r\n    section.append(list);\r\n    const load=()=>{for(const id of group.options){const item=optionMap.get(id==='random'?group.defaultEffect:id),canvas=section.querySelector(`[data-effect-thumb=\"${id}\"]`);if(canvas&&!canvas.dataset.loaded&&!canvas.dataset.loading&&item){canvas.dataset.loading='true';canvas.dataset.effectPreview=item.id;void paint(canvas,item).then(ok=>{delete canvas.dataset.loading;if(ok)canvas.dataset.loaded='true';});}}};\r\n    section.addEventListener('toggle',()=>{if(section.open)load();});\r\n  }\r\n  for(const group of EFFECT_GROUPS){\r\n    const section=doc.createElement('details');section.className='effect-group';\r\n    const title=doc.createElement('summary'),groupLabel=doc.createElement('span'),current=doc.createElement('span');\r\n    title.append(groupLabel,current);groupLabel.textContent=group.label;current.className='effect-current';current.textContent=optionMap.get(choices[group.id]||group.defaultEffect)?.label||'Random';groupLabels.set(group.id,current);section.dataset.effectGroup=group.id;section.append(title);drawGroup(group,section);menu.append(section);\r\n  }\r\n  menu.append(status);doc.body.append(menu);anchor.insertAdjacentElement('afterend',root);\r\n  const hideMenu=()=>{try{if(menu.matches(':popover-open'))menu.hidePopover();}catch{}delete menu.dataset.fallbackOpen;menu.hidden=true;};\r\n  const showMenu=()=>{menu.hidden=false;try{if(typeof menu.showPopover==='function')menu.showPopover();}catch{menu.dataset.fallbackOpen='';}menu.querySelector('.effect-group > summary')?.focus({preventScroll:true});};\r\n  const syncMenu=()=>{if(root.open)showMenu();else hideMenu();};\r\n  const onOutside=event=>{if(root.open&&!root.contains(event.target)&&!menu.contains(event.target)){root.open=false;hideMenu();}};\r\n  const onKeydown=event=>{if(event.key==='Escape'&&root.open){event.preventDefault();root.open=false;hideMenu();summary.focus();}};\r\n  root.addEventListener('toggle',syncMenu);\r\n  doc.addEventListener('pointerdown',onOutside,true);doc.addEventListener('keydown',onKeydown,true);\r\n  const onStorage=event=>{if(event.key===EFFECT_CHOICES_KEY){choices=readEffectChoices();for(const radio of menu.querySelectorAll('input[type=radio]'))radio.checked=choices[radio.dataset.effectGroup]===radio.value;for(const group of EFFECT_GROUPS)groupLabels.get(group.id).textContent=optionMap.get(choices[group.id]||group.defaultEffect)?.label||'Random';status.textContent='Exercise effect choices updated in another MYR5 tab.';}};\r\n  doc.defaultView?.addEventListener('storage',onStorage);\r\n  return {element:root,dispose(){if(disposed)return;disposed=true;doc.defaultView?.removeEventListener('storage',onStorage);root.removeEventListener('toggle',syncMenu);doc.removeEventListener('pointerdown',onOutside,true);doc.removeEventListener('keydown',onKeydown,true);hideMenu();menu.remove();root.remove();}};\r\n}\r\n","war-room/gala-bay.css":".gala-bay-stage {\r\n  background: radial-gradient(ellipse at 50% 14%, #52290d 0%, #1a1008 48%, #080a08 100%);\r\n}\r\n.gala-bay-stage::before {\r\n  z-index: 1;\r\n  background: repeating-linear-gradient(0deg, #ff9d2410 0 1px, transparent 1px 4px),\r\n    linear-gradient(90deg, #ff781208, transparent 28%, #ffb42a08 72%, transparent);\r\n}\r\n.gala-bay-panel {\r\n  position: relative;\r\n  z-index: 2;\r\n  max-height: 56%;\r\n  border-top: 2px solid #ff9a22;\r\n  background: linear-gradient(145deg, #18110bf5, #090b09f5);\r\n  box-shadow: 0 -8px 24px #ff79052b, inset 0 0 22px #ff82120e;\r\n  scrollbar-color: #a95b17 #15100b;\r\n}\r\n.gala-bay-panel h3,\r\n.gala-bay-panel .gala-editor-group legend {\r\n  color: #ffd28a;\r\n  font-family: \"Courier New\", monospace;\r\n  letter-spacing: .04em;\r\n  text-shadow: 0 0 8px #ff861d88;\r\n}\r\n.war-room .gala-bay-panel label { color: #ffd28a; font-family: \"Courier New\", monospace; }\r\n.war-room .gala-bay-panel select {\r\n  border: 1px solid #a95b17;\r\n  border-radius: 3px;\r\n  background: #18110b;\r\n  color: #ffe0aa;\r\n  font-family: \"Courier New\", monospace;\r\n}\r\n.war-room .gala-bay-panel select:focus-visible { outline: 2px solid #ffd28a; outline-offset: 1px; }\r\n.gala-bay-panel > div { display: block; }\r\n.gala-editor-group {\r\n  min-width: 0;\r\n  margin: 0 0 10px;\r\n  padding: 5px 7px 8px;\r\n  border: 1px solid #bd6c2480;\r\n  background: linear-gradient(#ff8c1009, #00000020);\r\n  box-shadow: inset 0 0 12px #ff7c100b;\r\n}\r\n.gala-editor-group legend {\r\n  padding: 0 6px;\r\n  font-size: 12px;\r\n  font-weight: 700;\r\n  text-transform: uppercase;\r\n}\r\n.gala-editor-part { min-width: 0; margin: 4px 0 9px; }\r\n.gala-editor-part h4,\r\n.gala-editor-weapons h4 {\r\n  margin: 0 0 5px;\r\n  color: #ffab46;\r\n  font: 700 11px/1.2 \"Courier New\", monospace;\r\n  letter-spacing: .05em;\r\n  text-transform: uppercase;\r\n}\r\n.gala-option-grid {\r\n  display: grid;\r\n  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));\r\n  gap: 5px;\r\n  align-items: stretch;\r\n}\r\n.gala-option {\r\n  min-width: 0;\r\n  min-height: 76px;\r\n  padding: 4px 3px;\r\n  display: flex;\r\n  flex-direction: column;\r\n  align-items: center;\r\n  justify-content: center;\r\n  gap: 3px;\r\n  overflow: hidden;\r\n  border: 1px solid #87501f;\r\n  border-radius: 4px;\r\n  color: #f4d4a7;\r\n  background: linear-gradient(145deg, #251a10, #11100c);\r\n  font: 10px/1.15 \"Courier New\", monospace;\r\n  text-shadow: 0 0 5px #ff780033;\r\n  touch-action: manipulation;\r\n}\r\n.gala-option:hover { border-color: #ffab46; background: #392311; }\r\n.gala-option:focus-visible { outline: 2px solid #ffd28a; outline-offset: 1px; }\r\n.gala-option[aria-pressed=\"true\"] {\r\n  border-color: #ffb347;\r\n  color: #fff0cf;\r\n  background: linear-gradient(145deg, #56300e, #211307);\r\n  box-shadow: inset 0 0 0 1px #ffad3c, 0 0 9px #ff861d66;\r\n}\r\n.gala-option:disabled { opacity: .48; }\r\n.war-room .gala-coach-choices { border-color: #bd6c2480; background: #120e09; }\r\n.war-room .gala-coach-choices button {\r\n  border-color: #87501f;\r\n  background: linear-gradient(145deg, #251a10, #11100c);\r\n  color: #f4d4a7;\r\n  font-family: \"Courier New\", monospace;\r\n}\r\n.war-room .gala-coach-choices button[aria-pressed=\"true\"] {\r\n  border-color: #ffb347;\r\n  outline: 2px solid #ffad3c;\r\n  color: #fff0cf;\r\n  background: linear-gradient(145deg, #56300e, #211307);\r\n}\r\n.war-room .gala-coach-choices button:focus-visible { outline: 2px solid #ffd28a; outline-offset: 1px; }\r\n.gala-option-art {\r\n  display: block;\r\n  width: auto;\r\n  height: 42px;\r\n  max-width: 100%;\r\n  image-rendering: pixelated;\r\n  background: radial-gradient(ellipse, #ff9d2419, transparent 72%);\r\n}\r\n.gala-option-name {\r\n  display: -webkit-box;\r\n  max-width: 100%;\r\n  overflow: hidden;\r\n  -webkit-box-orient: vertical;\r\n  -webkit-line-clamp: 2;\r\n  overflow-wrap: anywhere;\r\n  text-align: center;\r\n}\r\n.gala-dye-grid { grid-template-columns: repeat(auto-fill, minmax(62px, 1fr)); }\r\n.gala-dye-option { min-height: 66px; }\r\n.gala-swatch-art { height: 38px; width: 32px; image-rendering: pixelated; }\r\n.gala-weapon-grid { grid-template-columns: repeat(auto-fill, minmax(78px, 1fr)); }\r\n.gala-tier-grid { grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); }\r\n.gala-weapon-art { width: 27px; height: 44px; }\r\n.gala-editor-weapons .help { margin: 7px 0 2px; color: #d8ae7a; font-size: 11px; }\r\n@media (max-width: 560px) {\r\n  .gala-bay-panel { max-height: 62%; padding: 7px; }\r\n  .gala-option-grid { grid-template-columns: repeat(auto-fill, minmax(66px, 1fr)); gap: 4px; }\r\n  .gala-option { min-height: 70px; }\r\n}\r\n@media (prefers-reduced-motion: reduce) {\r\n  .gala-option { scroll-behavior: auto; }\r\n}\r\n","war-room/gala-editor.js":"import { makeDyePreview, makePartPreview, makeWeaponPreview } from './gala-option-previews.js';\r\n\r\nconst PART_GROUPS = [\r\n  { title: 'Species & alien form', ids: ['body', 'skin', 'face', 'hair', 'facial'] },\r\n  { title: 'Head & neckwear', ids: ['headwear', 'neck'] },\r\n  { title: 'Formalwear', ids: ['torso'] },\r\n  { title: 'Shoulders, sleeves & gloves', ids: ['shoulders', 'arms', 'hands'] },\r\n  { title: 'Pants & footwear', ids: ['legs', 'feet'] },\r\n  { title: 'Accessories', ids: ['held', 'back', 'base'] },\r\n  { title: 'Companion', ids: ['pet'] }\r\n];\r\n\r\nfunction optionButton(doc, { label, preview, selected, value, onClick, className = '' }) {\r\n  const button = doc.createElement('button');\r\n  button.type = 'button';\r\n  button.className = `gala-option${className ? ` ${className}` : ''}`;\r\n  button.setAttribute('aria-label', label);\r\n  button.setAttribute('aria-pressed', String(selected));\r\n  button.dataset.optionValue = String(value);\r\n  button.append(preview);\r\n  const caption = doc.createElement('span');\r\n  caption.className = 'gala-option-name';\r\n  caption.textContent = label;\r\n  button.append(caption);\r\n  button.addEventListener('click', () => onClick(button));\r\n  return button;\r\n}\r\n\r\nexport function createGalaEditor({ document: doc, avatar, weapons, look, onPart, onDye, onWeapon, locked, previewDraw = avatar.draw }) {\r\n  const make = (tag, className, text) => {\r\n    const element = doc.createElement(tag);\r\n    if (className) element.className = className;\r\n    if (text) element.textContent = text;\r\n    return element;\r\n  };\r\n\r\n  function partSections(ids) {\r\n    const wanted = new Set(ids);\r\n    const entries = PART_GROUPS.map(group => ({ ...group, ids: group.ids.filter(id => wanted.has(id)) })).filter(group => group.ids.length);\r\n    return entries.map(group => {\r\n      const fieldset = make('fieldset', 'gala-editor-group');\r\n      const legend = make('legend', '', group.title);\r\n      fieldset.append(legend);\r\n      for (const id of group.ids) {\r\n        const section = avatar.sections.find(item => item.id === id);\r\n        if (!section) continue;\r\n        const part = make('section', 'gala-editor-part');\r\n        part.dataset.part = id;\r\n        const heading = make('h4', '', section.label);\r\n        const grid = make('div', 'gala-option-grid');\r\n        const current = look.parts[id] ?? 0;\r\n        const values = section.choices.includes(current) ? section.choices : [current, ...section.choices];\r\n        for (const value of values) {\r\n          const label = section.names[value] || `${section.label} ${value + 1}`;\r\n          const button = optionButton(doc, {\r\n            label, value, selected: value === current,\r\n            preview: makePartPreview(doc, avatar, look, id, value, previewDraw),\r\n            onClick: target => {\r\n              grid.querySelectorAll('.gala-option').forEach(item => item.setAttribute('aria-pressed', String(item === target)));\r\n              onPart(id, value, label);\r\n            }\r\n          });\r\n          button.dataset.galaPart = id;\r\n          grid.append(button);\r\n        }\r\n        part.append(heading, grid);\r\n        fieldset.append(part);\r\n      }\r\n      return fieldset;\r\n    });\r\n  }\r\n\r\n  function dyeControl() {\r\n    const part = make('section', 'gala-editor-part gala-dye-part');\r\n    part.append(make('h4', '', 'Silk colour'));\r\n    const grid = make('div', 'gala-option-grid gala-dye-grid');\r\n    avatar.dyes.forEach((color, value) => {\r\n      const button = optionButton(doc, {\r\n        label: `Silk ${value + 1}`, value, selected: value === look.dye,\r\n        preview: makeDyePreview(doc, avatar, look, value), className: 'gala-dye-option',\r\n        onClick: target => {\r\n          grid.querySelectorAll('.gala-option').forEach(item => item.setAttribute('aria-pressed', String(item === target)));\r\n          onDye(value);\r\n        }\r\n      });\r\n      button.dataset.galaPart = 'dye';\r\n      grid.append(button);\r\n    });\r\n    part.append(grid);\r\n    return part;\r\n  }\r\n\r\n  function weaponControl() {\r\n    const root = make('div', 'gala-editor-weapons');\r\n    const typeHeading = make('h4', '', 'Weapon');\r\n    const typeGrid = make('div', 'gala-option-grid gala-weapon-grid');\r\n    const chosen = look.weapon || { type: 'rapier', tier: 0 };\r\n    for (const type of weapons.types) {\r\n      const current = { type: type.id, tier: 0 };\r\n      const button = optionButton(doc, {\r\n        label: type.name, value: type.id, selected: type.id === chosen.type,\r\n        preview: makeWeaponPreview(doc, weapons, current),\r\n        onClick: target => {\r\n          typeGrid.querySelectorAll('.gala-option').forEach(item => item.setAttribute('aria-pressed', String(item === target)));\r\n          onWeapon({ type: type.id, tier: type.id === chosen.type ? chosen.tier : 0 });\r\n        }\r\n      });\r\n      button.dataset.galaWeapon = 'type';\r\n      button.dataset.weaponType = type.id;\r\n      typeGrid.append(button);\r\n    }\r\n    const tierHeading = make('h4', '', 'Upgrade');\r\n    const tierGrid = make('div', 'gala-option-grid gala-tier-grid');\r\n    const previewStatus = make('p', 'help gala-preview-status');\r\n    previewStatus.setAttribute('role', 'status');\r\n    for (let tier = 0; tier < weapons.tiers.length; tier++) {\r\n      const weapon = { type: chosen.type, tier };\r\n      const isLocked = Boolean(locked?.(weapon));\r\n      const button = optionButton(doc, {\r\n        label: weapons.tiers[tier], value: tier,\r\n        selected: tier === chosen.tier, preview: makeWeaponPreview(doc, weapons, weapon),\r\n        className: isLocked ? 'is-locked' : '',\r\n        onClick: target => {\r\n          if (isLocked) {\r\n            previewStatus.textContent = `Preview only · How to unlock ${weapons.tiers[tier]}: ${weapons.requirements(weapon).label}.`;\r\n            return;\r\n          }\r\n          previewStatus.textContent = '';\r\n          tierGrid.querySelectorAll('.gala-option').forEach(item => item.setAttribute('aria-pressed', String(item === target)));\r\n          onWeapon({ type: chosen.type, tier });\r\n        }\r\n      });\r\n      button.dataset.galaWeapon = 'tier';\r\n      if (isLocked) {\r\n        button.dataset.locked = 'true';\r\n      }\r\n      tierGrid.append(button);\r\n    }\r\n    root.append(typeHeading, typeGrid, tierHeading, tierGrid, previewStatus, make('p', 'help', 'Workout performance earns weapon upgrades.'));\r\n    return root;\r\n  }\r\n\r\n  return { parts: partSections, dye: dyeControl, weapons: weaponControl };\r\n}\r\n","war-room/gala-option-previews.js":"const cropFor = {\r\n  body: [8, 3, 48, 91], skin: [20, 14, 26, 27], face: [19, 14, 27, 23], hair: [15, 4, 35, 29], facial: [18, 17, 28, 22],\r\n  headwear: [16, 2, 33, 22], neck: [23, 29, 19, 20], torso: [19, 32, 29, 32], shoulders: [13, 29, 38, 24], arms: [12, 34, 40, 32], hands: [13, 51, 38, 18],\r\n  legs: [17, 52, 31, 31], feet: [17, 73, 31, 18], held: [0, 20, 64, 66], back: [3, 19, 58, 68], base: [13, 80, 39, 16], pet: [0, 45, 64, 47], dye: [20, 32, 24, 31]\r\n};\r\n\r\nexport function makePartPreview(doc, avatar, look, sectionId, value, draw = avatar.draw) {\r\n  const source = doc.createElement('canvas');\r\n  const preview = doc.createElement('canvas');\r\n  const crop = cropFor[sectionId] || cropFor.body;\r\n  const next = structuredClone(look);\r\n  next.parts[sectionId] = value;\r\n  draw(source, next, { weapon: false, companion: false, prop: false, petOnly: sectionId === 'pet' });\r\n  preview.width = crop[2];\r\n  preview.height = crop[3];\r\n  const ctx = preview.getContext('2d');\r\n  ctx.imageSmoothingEnabled = false;\r\n  ctx.clearRect(0, 0, preview.width, preview.height);\r\n  ctx.drawImage(source, ...crop, 0, 0, preview.width, preview.height);\r\n  preview.className = 'gala-option-art';\r\n  preview.setAttribute('aria-hidden', 'true');\r\n  return preview;\r\n}\r\n\r\nexport function makeDyePreview(doc, avatar, look, dye) {\r\n  const canvas = doc.createElement('canvas');\r\n  const ctx = canvas.getContext('2d');\r\n  canvas.width = 34;\r\n  canvas.height = 40;\r\n  ctx.fillStyle = '#17100b';\r\n  ctx.fillRect(0, 0, canvas.width, canvas.height);\r\n  ctx.fillStyle = avatar.dyes[dye];\r\n  ctx.fillRect(5, 5, 24, 29);\r\n  ctx.fillStyle = '#fff4d5';\r\n  ctx.fillRect(12, 8, 3, 22);\r\n  ctx.fillStyle = '#382318';\r\n  ctx.fillRect(5, 31, 24, 3);\r\n  canvas.className = 'gala-option-art gala-swatch-art';\r\n  canvas.setAttribute('aria-hidden', 'true');\r\n  return canvas;\r\n}\r\n\r\nexport function makeWeaponPreview(doc, weapons, weapon) {\r\n  const canvas = doc.createElement('canvas');\r\n  canvas.width = 42;\r\n  canvas.height = 68;\r\n  const ctx = canvas.getContext('2d');\r\n  ctx.imageSmoothingEnabled = false;\r\n  weapons.draw(ctx, weapon, { x: 1, y: 2, scale: 1 });\r\n  canvas.className = 'gala-option-art gala-weapon-art';\r\n  canvas.setAttribute('aria-hidden', 'true');\r\n  return canvas;\r\n}\r\n","war-room/index.html":"<!doctype html>\r\n<html lang=\"en\">\r\n<head>\r\n  <meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\r\n  <meta name=\"theme-color\" content=\"#081f2b\"><title>MYR5 · War Room</title>\r\n  <link rel=\"stylesheet\" href=\"/shader-effects.css\"><script type=\"module\" src=\"/shader-entry.mjs\"></script>\r\n  <script type=\"importmap\">{\"imports\":{\"three\":\"/vendor/three/three.module.js\"}}</script>\r\n  <script src=\"/workout-tracks.js\"></script><script src=\"/pod/gala-weapons.js\"></script><script src=\"/pod/gala-avatar.js\"></script><script src=\"/pod/gala-performer.js\"></script>\r\n  <script type=\"module\" src=\"/war-room/war-room.mjs\"></script>\r\n<script type=\"module\" src=\"/audio/standalone-sound.mjs\"></script></head>\r\n<body>\r\n  <main class=\"war-room\">\r\n    <section class=\"panel character-bay\" aria-labelledby=\"characterBayTitle\">\r\n      <div class=\"character-bay-head\">\r\n        <a href=\"/pose.html#world\" class=\"portal-link\">← Back to base</a>\n        <h1 id=\"characterBayTitle\">WAR ROOM</h1>\r\n        <span id=\"access\" role=\"status\">Checking…</span>\r\n        <p id=\"characterBayStatus\" role=\"status\" class=\"bay-status\">Opening…</p>\r\n      </div>\r\n      <div id=\"warRoomGalaHost\" class=\"character-bay-stage\"></div>\r\n    </section>\r\n\r\n    <details class=\"panel controls-drawer\">\r\n      <summary>Controls</summary>\r\n      <div class=\"controls-grid\">\r\n        <section aria-labelledby=\"clearanceTitle\">\r\n          <h2 id=\"clearanceTitle\">Clearance</h2>\r\n          <p id=\"runStatus\" role=\"status\">Loading…</p>\r\n          <dl id=\"checks\" class=\"checks\"></dl>\r\n        </section>\r\n        <section aria-labelledby=\"identityTitle\">\r\n          <h2 id=\"identityTitle\">Identity</h2>\r\n          <p id=\"identity\">No DJ identity.</p>\r\n        </section>\r\n        <section class=\"board\" aria-labelledby=\"boardTitle\">\r\n          <div class=\"section-heading\"><h2 id=\"boardTitle\">Rankings</h2><button id=\"refresh\" type=\"button\">Refresh</button></div>\r\n          <p id=\"boardStatus\" role=\"status\">Loading…</p>\r\n          <table><thead><tr><th>Rank</th><th>DJ</th><th>Time</th></tr></thead><tbody id=\"leaderRows\"></tbody></table>\r\n        </section>\r\n        <section class=\"arsenal\" aria-labelledby=\"arsenalTitle\">\r\n          <h2 id=\"arsenalTitle\">Arsenal</h2>\r\n          <label>Weapon <select id=\"weaponType\"><option value=\"rapier\">Rapier</option><option value=\"greatsword\">Greatsword</option><option value=\"dagger\">Dagger</option><option value=\"sabre\">Sabre</option><option value=\"axe\">Axe</option><option value=\"hammer\">Hammer</option><option value=\"mace\">Mace</option><option value=\"flail\">Flail</option><option value=\"spear\">Spear</option><option value=\"trident\">Trident</option><option value=\"halberd\">Halberd</option><option value=\"scythe\">Scythe</option><option value=\"bow\">Bow</option><option value=\"crossbow\">Crossbow</option><option value=\"chakram\">Chakram</option><option value=\"gauntlets\">Gauntlets</option><option value=\"staff\">Staff</option><option value=\"wand\">Wand</option><option value=\"tome\">Tome</option><option value=\"cannon\">Cannon</option></select></label>\r\n          <label>Tier <input id=\"weaponTier\" type=\"number\" min=\"0\" max=\"20\" step=\"1\"></label>\r\n          <button id=\"saveLoadout\" type=\"button\">Save</button>\r\n          <p id=\"arsenalStatus\" role=\"status\"></p>\r\n        </section>\r\n      </div>\r\n    </details>\r\n  </main>\r\n  <!-- R20: the app's dock console and metal housing, as in the customizer -->\r\n  <nav id=\"coachDock\" class=\"coach-dock\" aria-label=\"Coach tools\"><a class=\"dock-control dock-settings\" data-route=\"customizeCoach\" href=\"/pose.html#customizeCoach\" aria-label=\"Customize coach\" title=\"Customize coach\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"12\" cy=\"12\" r=\"3\"/><circle cx=\"12\" cy=\"12\" r=\"6.5\"/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3M4.9 4.9 7 7M17 17l2.1 2.1M4.9 19.1 7 17M17 7l2.1-2.1\"/></svg></span></a><a class=\"dock-control dock-food\" data-route=\"food\" href=\"/pose.html#food\" aria-label=\"Food\" title=\"Food\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 8h4l2-3h6l2 3h4v11H3z\"/><circle cx=\"12\" cy=\"13\" r=\"3.5\"/></svg></span></a><a class=\"dock-portal\" data-route=\"portal\" href=\"/pose.html\" aria-label=\"Portal or workout pod\" title=\"Portal or workout pod\"><svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M3 11.5 12 4l9 7.5M5.5 10v10h13V10M10 20v-6h4v6\"/></svg><span aria-hidden=\"true\">PORTAL</span></a><a class=\"dock-control dock-scoreboard\" data-route=\"scoreboard\" href=\"/pose.html#scoreboard\" aria-label=\"Classroom leaderboard\" title=\"Classroom leaderboard\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><circle cx=\"9\" cy=\"8\" r=\"3\"/><circle cx=\"17\" cy=\"9\" r=\"2.5\"/><path d=\"M3 20c0-4 3-6 6-6s6 2 6 6M15 14c3 0 6 1.5 6 5\"/></svg></span></a><a class=\"dock-control dock-achievements\" data-route=\"achievements\" href=\"/pose.html#achievements\" aria-label=\"Achievements\" title=\"Achievements\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M7 4h10v5a5 5 0 0 1-10 0zM7 6H3c0 3 1 4 4 4M17 6h4c0 3-1 4-4 4M12 14v4M8 21h8\"/></svg></span></a><a class=\"dock-control dock-pod\" data-route=\"reminders\" href=\"/pose.html#reminders\" aria-label=\"Reminders computer\" title=\"Reminders computer\"><span aria-hidden=\"true\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A15 15 0 0 1 3 6a2 2 0 0 1 2-2z\"/></svg></span></a><span class=\"dock-live\" role=\"status\" aria-live=\"polite\"></span></nav>\r\n  <script type=\"module\">import{mountStandaloneHousing}from'/modules/portal/standalone-housing.mjs';await mountStandaloneHousing({content:document.querySelector('.war-room')});</script>\r\n</body>\r\n</html>\r\n","war-room/war-room.css":":root{color-scheme:dark;--ink:#d7f8ed;--muted:#8daeb0;--line:#356473;--panel:#0e2c38;--accent:#91f6c4;--yellow:#e4f28c;--bar:44px}*{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:#0b0716;color:var(--ink);font:16px/1.5 system-ui,sans-serif}\r\n.war-room{position:fixed;inset:15px 15px calc(var(--myr5-bar,88px) + 15px);overflow:hidden} /* R20: inside the metal housing, above the dock */\r\n.panel{background:linear-gradient(145deg,#123747,#0a2430);border:1px solid var(--line);box-shadow:0 12px 30px #0004}\r\nbutton{border:1px solid var(--accent);background:#183f48;color:var(--ink);padding:10px 14px;cursor:pointer;font-weight:600;min-height:44px}button:disabled{cursor:not-allowed;opacity:.55}\r\n[hidden]{display:none!important}\r\nlabel{font-size:13px}\r\n.checks{margin:8px 0 0}.checks div{display:flex;justify-content:space-between;border-top:1px solid #35647366;padding:8px 0}.checks dd,.checks dt{margin:0}.checks dd{color:var(--accent);font-family:monospace}\r\n.section-heading{display:flex;align-items:center;justify-content:space-between;gap:12px}\r\ntable{width:100%;border-collapse:collapse;margin-top:8px}th,td{text-align:left;padding:8px;border-bottom:1px solid #35647366}th{color:var(--muted);font:11px monospace;text-transform:uppercase}td:first-child,td:last-child{font-family:monospace}\r\n\r\n/* The 3D character bay is the whole viewport; a CSS backdrop stands in for a room until the room model loads. */\r\n.character-bay{position:absolute;inset:0;z-index:0;border:0;box-shadow:none}\r\n.character-bay-head{position:absolute;top:0;left:0;right:0;z-index:2;display:flex;flex-wrap:wrap;align-items:center;gap:4px 10px;padding:8px 10px;background:linear-gradient(#000c,#0000)}\r\n.character-bay-head h1{flex:1 1 auto;margin:0;font:700 15px/1.1 monospace;color:#f1ffcc;letter-spacing:.04em}\r\n.character-bay-head #access{font:11px monospace;color:var(--accent)}\r\n.portal-link{color:var(--accent);font:11px monospace;text-decoration:none;white-space:nowrap}\r\n.bay-status{flex-basis:100%;margin:0;font:11px monospace;color:#bde6e2}\r\n/* Bottom padding reserves the collapsed controls bar (and its safe area) so the cage's own bay buttons,\r\n   pinned to the stage's bottom edge, never sit under the fixed drawer. */\r\n.character-bay-stage{position:absolute;inset:0;display:flex;flex-direction:column;gap:6px;padding:0 0 calc(var(--bar) + env(safe-area-inset-bottom))}\r\n.gala-bay-stage{position:relative;flex:1 1 60%;min-height:260px;overflow:hidden;background:radial-gradient(ellipse at 50% 12%,#4a3a72 0%,#1c1330 55%,#0b0716 100%)}\r\n.gala-bay-stage::before{content:'';position:absolute;inset:0;background:repeating-linear-gradient(0deg,#ffffff0a 0 2px,#0000 2px 4px);pointer-events:none}\r\n.gala-bay-stage canvas{position:relative;display:block;width:100%;height:100%;touch-action:none}\r\n.gala-bay-panel{flex:0 1 auto;max-height:40%;overflow:auto;padding:8px 10px;background:#161230f2;border-top:2px solid #6c74ae}\r\n.gala-bay-panel h3{margin:0 0 6px;font:700 14px monospace;color:#f1ffcc}\r\n.gala-bay-panel>div{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:6px 10px}\r\n.gala-bay-panel label{display:flex;flex-direction:column;gap:2px;font-size:12px}.gala-bay-panel select{min-height:44px;width:100%}\r\n.gala-weapon{display:contents}.gala-bay-panel .help{grid-column:1/-1;margin:2px 0;font-size:12px;color:var(--muted)}\r\n.gala-coach-choices{grid-column:1/-1;min-width:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:6px;border:1px solid #6c74ae;padding:8px}\r\n.gala-coach-choices button{min-height:44px;min-width:0;padding:6px;display:flex;flex-direction:column;align-items:center;gap:4px;font-size:10px;overflow-wrap:anywhere}\r\n.gala-coach-choices button[aria-pressed=true]{outline:2px solid #cdb3ff;outline-offset:-2px}\r\n.gala-coach-choices button:disabled{opacity:.65}.gala-coach-choices canvas{width:auto;height:96px;max-width:100%;image-rendering:pixelated}\r\n.gala-coach-choices canvas[height=\"36\"]{height:36px;width:48px}\r\n\r\n/* Controls: a compact, collapsed-by-default drawer that overlays the bay, pinned above the bottom safe area. */\r\n.controls-drawer{position:absolute;left:0;right:0;bottom:0;z-index:3;max-height:70vh;overflow:auto;border-left:0;border-right:0;border-bottom:0;padding:0 12px env(safe-area-inset-bottom)}\r\n.controls-drawer summary{display:flex;align-items:center;min-height:var(--bar);margin:0;cursor:pointer;font:700 13px monospace;color:var(--accent);list-style:none}\r\n.controls-drawer summary::-webkit-details-marker{display:none}\r\n.controls-drawer summary::before{content:'\\25b2 '}\r\n.controls-drawer[open] summary::before{content:'\\25bc '}\r\n.controls-grid{display:flex;flex-direction:column;gap:14px;padding-bottom:8px}\r\n.controls-grid h2{margin:0 0 6px;font:13px monospace;color:#f1ffcc;text-transform:uppercase;letter-spacing:.05em}\r\n.war-room-effects{position:relative;flex:0 0 auto;align-self:center;font:12px monospace}\r\n.war-room-effects>summary{display:flex;align-items:center;justify-content:center;min-height:36px;min-width:62px;padding:4px 8px;border:1px solid #ff880088;color:#ffb65f;background:#211306;cursor:pointer;list-style:none;white-space:nowrap}\r\n.war-room-effects>summary::-webkit-details-marker,.effect-group>summary::-webkit-details-marker{display:none}\r\n.war-room-effects>summary::before{content:'> '}.war-room-effects[open]>summary{color:#ffe3ae;background:#48280c}\r\n.war-room-effects :focus-visible,.effect-picker-menu :focus-visible{outline:2px solid #fff0a8;outline-offset:2px}\r\n.effect-picker-menu{position:fixed;inset:auto;left:max(8px,env(safe-area-inset-left));right:max(8px,env(safe-area-inset-right));bottom:calc(var(--myr5-bar,88px) + 54px + env(safe-area-inset-bottom));z-index:2147483000;width:auto;max-width:480px;max-height:min(62dvh,520px);margin:0 auto;overflow:auto;padding:8px;border:1px solid #ff9a1f;border-radius:9px;background:#100e16f5;box-shadow:0 8px 30px #000b;overscroll-behavior:contain}\r\n.effect-picker-menu[popover]{position:fixed;inset:auto;left:max(8px,env(safe-area-inset-left));right:max(8px,env(safe-area-inset-right));bottom:calc(var(--myr5-bar,88px) + 54px + env(safe-area-inset-bottom));margin:0 auto}\r\n.effect-group{border:1px solid #795125;border-radius:6px;margin:3px 0;background:#21190ff0}\r\n.effect-group>summary{padding:7px 9px;min-height:40px;color:#f5d9ab;font-weight:700;cursor:pointer;list-style:none}\r\n.effect-group>summary{display:flex;align-items:center;justify-content:space-between;gap:8px}\r\n.effect-current{max-width:58%;overflow:hidden;color:#d4c2a7;font:10px/1.2 system-ui,sans-serif;text-align:right;text-overflow:ellipsis;white-space:nowrap}\r\n.effect-group[open]>summary{background:#51300f;color:#fff0cb}\r\n.effect-choice-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:5px;margin:0;padding:7px;border:0}\r\n.effect-choice-list legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}\r\n.effect-choice{display:flex;align-items:center;gap:7px;min-width:0;min-height:48px;padding:4px;border:1px solid #624921;border-radius:5px;background:#17131c;color:#f4e8d2;font:11px/1.25 system-ui,sans-serif;cursor:pointer}\r\n.effect-choice:has(input:checked){border-color:#ffbf67;background:#40280f;box-shadow:inset 0 0 0 1px #ffbf67}\r\n.effect-choice input{flex:0 0 auto;width:17px;height:17px;margin:0;accent-color:#ff9a1f}\r\n.effect-thumb{flex:0 0 40px;width:40px;height:40px;border:1px solid #644927;background:#0e1117;image-rendering:pixelated}\r\n.effect-choice span{min-width:0;overflow-wrap:anywhere}\r\n.effect-picker-status{margin:7px 2px 2px;color:#dbd3c4;font:11px/1.35 system-ui,sans-serif}\r\n/* R18 H: the 3D bay buttons are an orange terminal in a translucent glass hologram panel (War Room page only: this file is not loaded elsewhere). */\r\n.war-room .cage-bays{gap:2px;padding:4px 6px;border:1px solid #ff880088;border-radius:8px;background:linear-gradient(#0a120e66,#04080acc),repeating-linear-gradient(0deg,#0000 0 2px,#ff880014 2px 3px);background-blend-mode:normal;backdrop-filter:blur(3px);box-shadow:0 0 14px #ff880055,inset 0 0 18px #ff880022}\r\n.war-room .cage-bays button{flex:1 1 auto;background:none;border:0;border-radius:0;box-shadow:none;color:#ff9a1f;font:700 .8125rem 'Courier New',monospace;letter-spacing:.04em;text-transform:uppercase;text-shadow:0 0 6px #ff8800aa;min-height:36px;padding:4px 6px;display:inline-flex;flex-direction:row;align-items:center;justify-content:center;white-space:nowrap}\r\n.war-room .cage-bays button::before{content:'> '}.war-room .cage-bays button::after{content:'_';animation:bay-cursor 1s steps(1) infinite}\r\n.war-room .cage-bays button[aria-pressed=true]{background:#ff88002e;color:#ffd08a;text-shadow:0 0 8px #ffb347}\r\n.war-room .cage-bays button:hover{background:#ff880022}\r\n@keyframes bay-cursor{50%{opacity:0}}@media(prefers-reduced-motion:reduce){.war-room .cage-bays button::after{animation:none}}\r\n","war-room/war-room.mjs":"import {createStandaloneAccountContext} from '../standalone-account-context.mjs';\r\nimport {authFetch} from '../auth-client.mjs';\r\nimport {equipmentProgress} from '../pod/rest-arena.mjs';\r\nimport {authTransitions} from '../auth-transition.mjs';\r\nimport {createWarRoomApi} from './account-api.mjs';\r\nimport {mountEffectPicker} from './effect-picker.mjs';\nimport {mountBaseWindow,createWindowThemeController,guestWindowBiome,validWindowBiome} from './base-window.mjs';\nimport {performanceOwner} from '../performance-progress.mjs';\nimport * as THREE from 'three';\nconst css=document.createElement('link');css.rel='stylesheet';css.href='/war-room/war-room.css';document.head.append(css);\r\nconst bayCss=document.createElement('link');bayCss.rel='stylesheet';bayCss.href='/war-room/gala-bay.css';document.head.append(bayCss);\r\nconst $=id=>document.getElementById(id);\r\nconst CHECKS=[['djscratch','DJ Scratch'],['gala','Gala'],['lilboyfriend','Lil Boyfriend'],['corgi','Corgi'],['hand','Helping Hand'],['armie','Coach Armie']];\r\nconst transitions=authTransitions(),{api}=createWarRoomApi({request:authFetch,transitions}),accountContext=createStandaloneAccountContext({transitions});\r\nconst time=ms=>{if(!Number.isFinite(Number(ms)))return '—';const s=Math.max(0,Math.round(Number(ms)/1000));return `${Math.floor(s/60)}:${String(s%60).padStart(2,'0')}`;};\r\nconst GUEST='Sign in to use your saved run and loadouts.';\r\nlet arsenal=null;\nlet refreshBaseWindow=()=>{};\n// Gala weapon upgrades unlock from the signed-in account's training, as in the pod; guests keep base tiers.\r\nconst galaProgress=progress=>{window.GalaProgress=progress?{read:()=>equipmentProgress(progress)}:undefined;window.dispatchEvent(new Event('mominc-avatar-change'));};\r\ntransitions.subscribe(()=>{$('refresh').disabled=false;galaProgress(null);arsenal=null;$('saveLoadout').disabled=true;$('arsenalStatus').textContent='Account changed. Refresh the War Room.';});\r\nfunction renderArsenal(state){arsenal=state;$('saveLoadout').disabled=false;$('weaponType').value=state.loadout.type;$('weaponTier').value=String(state.loadout.tier);$('arsenalStatus').textContent=state.updatedAt?'Saved to this account.':'No saved loadout yet.';}\r\nfunction renderRun(run){$('runStatus').textContent=run?'Run '+(run.completedAt?'complete':'in progress')+'.':'No saved Gala run found.';$('identity').textContent=run?.djName||'No DJ identity attached.';$('checks').replaceChildren(...CHECKS.map(([key,label])=>{const row=document.createElement('div'),dt=document.createElement('dt'),dd=document.createElement('dd');dt.textContent=label;dd.textContent=run?.completed?.includes(key)?'✓ complete':'— pending';row.append(dt,dd);return row;}));}\r\nfunction renderBoard(board){const rows=board.items||[];$('leaderRows').replaceChildren(...rows.map(item=>{const tr=document.createElement('tr');for(const value of [String(item.rank).padStart(2,'0'),item.djName||'Unnamed DJ',time(item.durationMs)]){const td=document.createElement('td');td.textContent=value;tr.append(td);}return tr;}));$('boardStatus').textContent=rows.length?'Live escapee records.':'No ranked runs yet.';}\r\n// Public room and leaderboard; saved run and arsenal need a signed-in account and the server API.\r\nasync function load(){\r\n const ticket=transitions.beginRefresh();arsenal=null;$('saveLoadout').disabled=true;$('refresh').disabled=true;\r\n const board=api('/api/gala/leaderboard').then(value=>{if(transitions.isCurrent(ticket))renderBoard(value);},error=>{if(transitions.isCurrent(ticket))$('boardStatus').textContent='Leaderboard unavailable: '+error.message;});\r\n try{\r\n  const account=await accountContext.read({ticket});transitions.assertCurrent(ticket);refreshBaseWindow(account);\n  if(!account){galaProgress(null);$('access').textContent='Public War Room';$('runStatus').textContent=GUEST;$('checks').replaceChildren();$('arsenalStatus').textContent=GUEST;return;}\r\n  $('access').textContent='Signed-in War Room';galaProgress(account.progress);\r\n  const [runReply,room]=await Promise.all([api('/api/gala/install-draft'),api('/api/war-room')]);transitions.assertCurrent(ticket);renderRun(runReply.data);renderArsenal(room.state);\r\n }catch(error){if(!transitions.isCurrent(ticket))return;$('runStatus').textContent=error.message;$('arsenalStatus').textContent='Arsenal unavailable: '+error.message;$('access').textContent='Signed in · service unavailable';}\r\n finally{await board;if(transitions.isCurrent(ticket))$('refresh').disabled=false;}\r\n}\r\n$('refresh').addEventListener('click',load);window.addEventListener('myr5:login-ready',()=>void load());window.addEventListener('pageshow',event=>{if(event.persisted){accountContext.clear();void load();}});load();\r\n$('saveLoadout').addEventListener('click',async()=>{if(!arsenal)return;const ticket=transitions.capture(),button=$('saveLoadout');button.disabled=true;try{const reply=await api('/api/war-room/loadout',{method:'PUT',headers:{'Content-Type':'application/json'},body:JSON.stringify({revision:arsenal.revision,loadout:{type:$('weaponType').value,tier:Number($('weaponTier').value)}})});transitions.assertCurrent(ticket);renderArsenal(reply.state);}catch(error){if(transitions.isCurrent(ticket))$('arsenalStatus').textContent=error.message;}finally{if(transitions.isCurrent(ticket))button.disabled=false;}});\r\n\r\n// The character bay dresses the player's own 64-bit Gala character in the cage room. It never opens the\r\n// coach customizer, so it needs no ship admission; guests use it too, saving to this device.\r\nfunction mountCharacterBay(){\r\n const host=$('warRoomGalaHost'),status=$('characterBayStatus');\r\n if(!host||!status)return;\r\n const tell=text=>{status.textContent=text;};\r\n let bay=null,module=null,generation=0,effectPicker=null,baseWindow=null,windowTheme=null,placementCage=null;\n const syncRoomPlacement=()=>{const cage=bay?.cage;if(!cage){baseWindow?.setRoomMode('flat');return;}if(cage===placementCage)return;placementCage=cage;const run=generation,exterior=baseWindow;void Promise.resolve(cage.ready).then(ok=>{if(run===generation&&baseWindow===exterior&&bay?.cage===cage)exterior?.setRoomMode(ok?'cage':'flat');}).catch(()=>{if(run===generation&&baseWindow===exterior)exterior?.setRoomMode('flat');});};\n const attachEffects=()=>{\n  syncRoomPlacement();\n  const pets=host.querySelector('[data-cage-section=\"pets\"]');\r\n  if(!pets)return;\r\n  if(effectPicker?.element?.isConnected&&effectPicker.element.previousElementSibling===pets)return;\r\n  effectPicker?.dispose();effectPicker=mountEffectPicker(pets);\r\n };\r\n const effectObserver=new MutationObserver(attachEffects);effectObserver.observe(host,{childList:true,subtree:true});\r\n const close=()=>{generation++;effectObserver.disconnect();effectPicker?.dispose();effectPicker=null;windowTheme?.dispose();windowTheme=null;baseWindow?.dispose();baseWindow=null;placementCage=null;refreshBaseWindow=()=>{};bay?.dispose();bay=null;window.warRoomGala=null;};\n const open=()=>{\r\n  if(!document.hidden&&host.isConnected)effectObserver.observe(host,{childList:true,subtree:true});\r\n  if(document.hidden||!host.isConnected||bay)return;\r\n  const run=++generation;\r\n  module??=import('/war-room/gala-bay.js');\r\n  module.then(({mountGalaBay})=>{\r\n   if(run!==generation||document.hidden||!host.isConnected)return;\r\n   bay=mountGalaBay(host,{tell});window.warRoomGala=bay;\n   const initial=validWindowBiome(new URLSearchParams(location.search).get('biome'));baseWindow=mountBaseWindow(bay.stage,THREE,initial);\n   windowTheme=createWindowThemeController({initialBiome:initial,apply:(biome,options)=>baseWindow?.setBiome(biome,options),transitions,request:authFetch,guestTheme:()=>{let storage;try{storage=localStorage;}catch{}return guestWindowBiome({storage,owner:performanceOwner(),account:accountContext.account});}});\n   refreshBaseWindow=account=>void windowTheme?.sync(account);refreshBaseWindow(accountContext.account);syncRoomPlacement();tell('Tap the room or your character.');\n  }).catch(()=>{if(run===generation)tell('Bay unavailable on this device.');});\r\n };\r\n addEventListener('pagehide',close);\n addEventListener('myr5:account-ready',()=>refreshBaseWindow(accountContext.account));\n addEventListener('pageshow',event=>{if(event.persisted)open();});\r\n document.addEventListener('visibilitychange',()=>{if(document.hidden)close();else open();});\r\n open();\r\n}\r\nmountCharacterBay();\r\n","weapon-rewards.mjs":"import {TRAINING_TRACKS} from './weapon-training.mjs';\r\nimport {readPerformanceProgress} from './performance-progress.mjs';\r\nexport function weaponRewardSummary(group,{kind,options={}}={}){\r\n const track=TRAINING_TRACKS[group];if(!track)return null;\r\n const state=readPerformanceProgress(options),weapons=track.weapons.map(type=>({type,tier:state.weapons[type]??0}));\r\n const hold='Holds: 1 uninterrupted minute earns the first tier in the difficulty block; 3 minutes earns the second; 5 minutes unlocks the coach. Repeat a 5-minute clear for another tier. 10 minutes finishes the block and earns gold.';\r\n const reps='Working reps: 8 earns the first tier in the difficulty block; 12 earns the second; 15 unlocks the coach. Repeat the 15-rep clear on an eligible day for another tier.';\r\n const timed='Active movement: complete 5 active minutes to earn a weapon tier. '+(group==='cardio'?'For sprinting, complete 5 rounds. ':'')+'Repeat at the same difficulty to improve its block.';\r\n return {name:track.name,weapons,blocks:'Easy tiers 1–5 · Medium 6–10 · Hard 11–15 · Expert 16–20',target:kind==='hold'?hold:kind==='reps'?reps:kind==='cardio'?timed:[hold,reps].join(' ')};\r\n}\r\nexport function mountWeaponRewards(host,getGroup,getKind=()=>undefined){\r\n const strip=document.createElement('section');strip.className='training-rewards';strip.setAttribute('aria-label','Performance weapon rewards');host.after(strip);\r\n function paint(){\r\n  const summary=weaponRewardSummary(getGroup(),{kind:getKind()});strip.replaceChildren();if(!summary)return;\r\n  const W=window.GalaWeapons,heading=document.createElement('p');heading.textContent=`${summary.name} · Earned weapon tiers`;strip.append(heading);\r\n  const row=document.createElement('div');row.className='training-reward-weapons';\r\n  for(const {type,tier} of summary.weapons){\r\n   const card=document.createElement('div'),canvas=document.createElement('canvas'),label=document.createElement('span');canvas.width=80;canvas.height=144;canvas.setAttribute('aria-hidden','true');W?.draw?.(canvas.getContext('2d'),{type,tier},{scale:2});const name=W?.types?.find(w=>w.id===type)?.name||type[0].toUpperCase()+type.slice(1);label.textContent=`${name} · ${tier===0?'Starter':`Tier ${tier} / 20`}`;card.dataset.weapon=type;card.dataset.tier=String(tier);card.append(canvas,label);row.append(card);\r\n  }\r\n  strip.append(row);for(const text of [summary.blocks,summary.target]){const status=document.createElement('small');status.textContent=text;strip.append(status);}\r\n }\r\n for(const event of ['myr5:performance-progress','myr5:account-progress','myr5:account-ready','myr5:account-cleared','storage'])window.addEventListener(event,paint);\r\n paint();return {paint,element:strip};\r\n}\r\n","weapon-training.mjs":"import {EXERCISES,FOCUS_GROUPS} from './exercise-library.mjs';\r\nexport {playerLevel,levelFor,xpFromHistory,LEVEL_XP,XP_KNOBS} from './player-level.mjs';\r\nexport {weaponTierFor} from './performance-progress.mjs';\r\n\r\nconst families={chest:['crossbow','cannon'],legs:['greatsword','hammer'],hips:['scythe','halberd'],core:['mace','tome'],shoulders:['bow','trident'],balance:['axe','sabre'],yoga:['staff','wand'],stances:['dagger','spear'],boxing:['gauntlets','rapier'],cardio:['chakram','flail']};\r\nexport const TRAINING_TRACKS=Object.freeze(Object.fromEntries(FOCUS_GROUPS.map(g=>[g.id,Object.freeze({id:g.id,name:g.name,weapons:Object.freeze(families[g.id])})])));\r\nexport const WEAPON_TRACK=Object.freeze(Object.fromEntries(Object.entries(families).flatMap(([group,ids])=>ids.map(id=>[id,group]))));\r\nexport const trainingGroup=mode=>EXERCISES[mode]?.group||(mode==='jumping'?'cardio':null);\r\nexport function emptyTraining(){return Object.fromEntries(Object.keys(TRAINING_TRACKS).map(id=>[id,{activeDays:0,completedSets:0,totalXp:0,strength:1}]));}\r\nexport function trainingFromDaily(rows){\r\n const result=emptyTraining(),days=Object.fromEntries(Object.keys(result).map(id=>[id,new Set()]));\r\n for(const row of rows){const group=trainingGroup(row.mode),sets=Number(row.sets),day=Number(row.day);if(!group||!Number.isSafeInteger(sets)||sets<1||!Number.isSafeInteger(day)||day<0)continue;result[group].completedSets+=sets;days[group].add(day);}\r\n for(const [group,p] of Object.entries(result)){p.activeDays=days[group].size;p.totalXp=p.activeDays*100;p.strength=1+Math.floor(p.completedSets/4);}\r\n return result;\r\n}\r\nexport function trainingFromWorkouts(workouts){\r\n const seen=new Set(),rows=[];\r\n for(const row of workouts){if(row.completed_at==null||!Number.isSafeInteger(row.completed_at)||row.completed_at<0||!row.id||seen.has(row.id))continue;seen.add(row.id);rows.push({mode:row.mode,day:Math.floor(row.completed_at/86400000),sets:1});}\r\n return trainingFromDaily(rows);\r\n}\r\nexport function trackProgress(value,group){\r\n const p=value?.training?.[group];\r\n if(value?.trainingVersion!==1||!p||!Number.isSafeInteger(p.activeDays)||p.activeDays<0||!Number.isSafeInteger(p.completedSets)||p.completedSets<p.activeDays||p.completedSets>1000000)return {activeDays:0,completedSets:0,totalXp:0,strength:1};\r\n return {activeDays:p.activeDays,completedSets:p.completedSets,totalXp:p.activeDays*100,strength:1+Math.floor(p.completedSets/4)};\r\n}\r\n","workout-import-codec.mjs":"import {projectImportedPerformance,validateImportedPerformance} from './performance-import-codec.mjs';\r\n// Shared browser/Worker codec; no authentication or network I/O.\r\n// Version 1 is immutable: preserve its validation and bytes for old replays.\r\nexport const IMPORT_DIGEST_VERSION = 1;\r\nexport const IMPORT_SNAPSHOT_KEYS = Object.freeze(['schemaVersion','clientWorkoutId','mode','goal','restSeconds','startedAt','completedAt','value','activeSeconds','elapsedSeconds']);\r\n// Pinned from exercise-library.mjs and server/domain.mjs on 2026-09-21.\r\nconst timedModes = 'knee-plank high-plank forearm-plank side-knee-left side-knee-right side-plank-left side-plank-right knee-balance low-tree tree overhead-tree mountain salute chair warrior-one warrior goddess high-horse horse low-horse front-stance-left front-stance-right wall-sit jab-left jab-right boxing double-jab'.split(' ');\r\nconst countModes = 'knee-pushup high-incline-pushup low-incline-pushup pushup wide-pushup slow-pushup diamond-pushup decline-pushup shallow-squat squat wide-squat pause-squat slow-squat split-left split-right small-hinge hip-hinge good-morning glute-bridge pause-bridge front-raise lateral-raise overhead-reach standing-press slow-press march high-march jogging step-jack jumping-jack jumping'.split(' ');\r\nexport const IMPORT_MODE_LIMITS = Object.freeze(Object.fromEntries([...timedModes.map(mode=>[mode,Object.freeze({goal:7200,value:7200})]),...countModes.map(mode=>[mode,Object.freeze({goal:100000,value:100000})])]));\r\nexport class WorkoutImportCodecError extends Error {\r\n  constructor(code,message=code){super(message);this.name='WorkoutImportCodecError';this.code=code;}\r\n}\r\nconst fail=(code='invalid_snapshot')=>{throw new WorkoutImportCodecError(code);};\r\nconst own=(value,key)=>Object.prototype.hasOwnProperty.call(value,key);\r\n// Never run an accessor while validating. Detached descriptor values are read once.\r\nfunction record(raw,code){\r\n  try {\r\n    if(!raw||typeof raw!=='object'||Array.isArray(raw)||![null,Object.prototype].includes(Object.getPrototypeOf(raw)))fail(code);\r\n    const descriptors=Object.getOwnPropertyDescriptors(raw),out=Object.create(null);\r\n    if(Object.getOwnPropertySymbols(descriptors).length)fail(code);\r\n    for(const [key,d] of Object.entries(descriptors)){\r\n      if(!own(d,'value')||!d.enumerable)fail(code);\r\n      out[key]=d.value;\r\n    }\r\n    return out;\r\n  }catch{fail(code);}\r\n}\r\nfunction exact(raw,keys,code){\r\n  const value=record(raw,code),actual=Object.keys(value);\r\n  if(actual.length!==keys.length||keys.some(key=>!own(value,key)))fail(code);\r\n  return value;\r\n}\r\nfunction integer(value,min,max,code){if(!Number.isSafeInteger(value)||Object.is(value,-0)||value<min||value>max)fail(code);}\r\nfunction uuid(value,code){if(typeof value!=='string'||!(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/).test(value))fail(code);}\r\nfunction version(value){if(![1,2].includes(value))fail('unsupported_digest_version');}\r\nexport function validateImportSnapshot(raw){\r\n  const supplied=record(raw,'invalid_snapshot');const s=exact(raw,own(supplied,'performance')?[...IMPORT_SNAPSHOT_KEYS,'performance']:IMPORT_SNAPSHOT_KEYS,'invalid_snapshot');\r\n  if(s.schemaVersion!==1)fail();\r\n  uuid(s.clientWorkoutId,'invalid_snapshot');\r\n  if(typeof s.mode!=='string'||!own(IMPORT_MODE_LIMITS,s.mode))fail();\r\n  const limits=IMPORT_MODE_LIMITS[s.mode];\r\n  integer(s.goal,1,limits.goal,'invalid_snapshot');\r\n  integer(s.restSeconds,15,180,'invalid_snapshot');\r\n  integer(s.startedAt,0,8640000000000000,'invalid_snapshot');\r\n  integer(s.completedAt,s.startedAt,8640000000000000,'invalid_snapshot');\r\n  if(own(s,'performance')){for(const [value,min,max] of [[s.value,0,limits.value],[s.activeSeconds,0,7200],[s.elapsedSeconds,s.activeSeconds,7200]])if(!Number.isFinite(value)||Object.is(value,-0)||value<min||value>max)fail();}\r\n  else{integer(s.value,0,limits.value,'invalid_snapshot');integer(s.activeSeconds,0,7200,'invalid_snapshot');integer(s.elapsedSeconds,s.activeSeconds,7200,'invalid_snapshot');}\r\n  const base=Object.fromEntries(IMPORT_SNAPSHOT_KEYS.map(key=>[key,s[key]]));if(own(s,'performance')){try{base.performance=validateImportedPerformance(s.performance,base);}catch{fail();}}return Object.freeze(base);\r\n}\r\n// Caller must obtain this row through its owner-scoped repository. Shape checks\r\n// are not an ownership check. Only these explicit source fields are projected.\r\nexport function snapshotFromCompletedWorkout(raw){\r\n  try {\r\n    const row=record(raw,'snapshot_unavailable');\r\n    if(row.status!=='completed')fail('snapshot_unavailable');\r\n    const completion=record(row.completion,'snapshot_unavailable');\r\n    const base={schemaVersion:row.schemaVersion,clientWorkoutId:row.clientWorkoutId,mode:row.mode,goal:row.goal,restSeconds:row.restSeconds,startedAt:row.startedAt,completedAt:row.completedAt,value:completion.value,activeSeconds:completion.activeSeconds,elapsedSeconds:completion.elapsedSeconds};\r\n    const descriptor=row.progress&&typeof row.progress==='object'?Object.getOwnPropertyDescriptor(row.progress,'performance'):null;\r\n    if(descriptor&&own(descriptor,'value')&&descriptor.value){const p=record(descriptor.value,'snapshot_unavailable');if(!p.preparation&&p.earned!==false&&(p.kind!=='hold'||Array.isArray(p.holdBlocks)))return validateImportSnapshot({...base,performance:projectImportedPerformance(p,base)});}\r\n    return validateImportSnapshot(base);\r\n  }catch{fail('snapshot_unavailable');}\r\n}\r\nexport function canonicalImportSnapshot(raw,digestVersion=IMPORT_DIGEST_VERSION){\r\n  version(digestVersion);\r\n  const snapshot=validateImportSnapshot(raw);if((snapshot.performance?2:1)!==digestVersion)fail('unsupported_digest_version');return JSON.stringify([digestVersion,snapshot]);\r\n}\r\nasync function sha256(text){\r\n  if(typeof globalThis.crypto?.subtle?.digest!=='function')fail('crypto_unavailable');\r\n  let bytes;\r\n  try{bytes=await globalThis.crypto.subtle.digest('SHA-256',new TextEncoder().encode(text));}\r\n  catch{fail('crypto_unavailable');}\r\n  return Array.from(new Uint8Array(bytes),byte=>byte.toString(16).padStart(2,'0')).join('');\r\n}\r\nexport async function fingerprintImportSnapshot(raw,digestVersion=IMPORT_DIGEST_VERSION){\r\n  return sha256(canonicalImportSnapshot(raw,digestVersion));\r\n}\r\nexport function canonicalImportKey(raw){\r\n  const k=exact(raw,['digestVersion','targetAccountId','targetDataEpoch','clientWorkoutId','fingerprint'],'invalid_key_input');\r\n  version(k.digestVersion);\r\n  if(typeof k.targetAccountId!=='string'||!k.targetAccountId||k.targetAccountId.length>512||k.targetAccountId.trim()!==k.targetAccountId||/[\\u0000-\\u001f\\u007f]/.test(k.targetAccountId))fail('invalid_key_input');\r\n  integer(k.targetDataEpoch,1,Number.MAX_SAFE_INTEGER,'invalid_key_input');\r\n  uuid(k.clientWorkoutId,'invalid_key_input');\r\n  if(typeof k.fingerprint!=='string'||!(/^[a-f0-9]{64}$/).test(k.fingerprint))fail('invalid_key_input');\r\n  return JSON.stringify([k.digestVersion,k.targetAccountId,k.targetDataEpoch,k.clientWorkoutId,k.fingerprint]);\r\n}\r\nexport async function importIdempotencyKey(raw){return sha256(canonicalImportKey(raw));}\r\nexport async function prepareWorkoutImport(snapshotInput,targetInput){\r\n  // Capture all untrusted inputs synchronously before the first async boundary.\r\n  const snapshot=validateImportSnapshot(snapshotInput);\r\n  const digestVersion=snapshot.performance?2:1;\r\n  const target=exact(targetInput,['targetAccountId','targetDataEpoch'],'invalid_key_input');\r\n  canonicalImportKey({digestVersion,...target,clientWorkoutId:snapshot.clientWorkoutId,fingerprint:'0'.repeat(64)});\r\n  const fingerprint=await fingerprintImportSnapshot(snapshot,digestVersion);\r\n  const idempotencyKey=await importIdempotencyKey({digestVersion,...target,clientWorkoutId:snapshot.clientWorkoutId,fingerprint});\r\n  return Object.freeze({snapshot,digestVersion,fingerprint,idempotencyKey});\r\n}\r\n","workout-levels.mjs":"import {EXERCISES,FOCUS_GROUPS,GROUP_EXERCISES} from './exercise-library.mjs';\r\nimport {exerciseDifficulty} from './performance-catalog.mjs';\r\nimport {DIFFICULTIES,HOLD_XP_PER_MINUTE,REP_XP,XP_SCALE,SPRINT_ROUND_XP,SPRINT_ROUNDS} from './progression-rules.mjs';\r\nexport const WORKOUT_KINDS=[{id:'hold',name:'Holds'},{id:'reps',name:'Working reps'},{id:'cardio',name:'Cardio & active movement'}];\r\nexport const workoutKind=mode=>EXERCISES[mode]?.kind==='hold'?'hold':EXERCISES[mode]?.kind==='reps'?'reps':'cardio';\r\nexport function workoutChoices(group,kind){return (GROUP_EXERCISES[group]||[]).filter(e=>workoutKind(e.id)===kind);}\r\nexport function workoutLevel(mode){\r\n const e=EXERCISES[mode];if(!e)return null;\r\n const difficulty=exerciseDifficulty(mode),i=DIFFICULTIES.indexOf(difficulty),label=difficulty[0].toUpperCase()+difficulty.slice(1),kind=workoutKind(mode);\r\n return {difficulty,label,kind,group:e.group,groupName:FOCUS_GROUPS.find(g=>g.id===e.group)?.name||e.group,\r\n  xp:kind==='hold'?`${HOLD_XP_PER_MINUTE[i].join(' / ')} base XP per active minute at 1 / 3 / 5-minute tiers`:kind==='reps'?`${REP_XP[i].join(' / ')} base XP per rep at 1–7 / 8–11 / 12–15 reps`:e.group==='cardio'?`Gentle cardio: ${4*XP_SCALE} base XP per active minute. Sprinting: ${SPRINT_ROUND_XP*SPRINT_ROUNDS} base XP for five rounds.`:`${4*XP_SCALE} base XP per active minute`,\r\n  unlock:kind==='hold'?'Weapons at 1 and 3 uninterrupted minutes · Coach at 5 · Golden at 10':kind==='reps'?'Weapons at 8 and 12 reps · Coach at 15':e.group==='cardio'?'Coach at 5 sprint rounds or 5 active minutes':'Coach at 5 active minutes',\r\n  target:kind==='hold'?300:kind==='reps'?15:300,unit:kind==='reps'?'reps':'seconds'};\r\n}\r\n","workout-route-ui.mjs":"import {EXERCISES,GROUP_EXERCISES} from './exercise-library.mjs';\r\nimport {workoutEligibility,readPerformanceProgress} from './performance-progress.mjs';\r\nimport {workoutLevel,workoutKind} from './workout-levels.mjs';\r\nimport {DIFFICULTIES} from './progression-rules.mjs';\r\nexport function nextPerformanceChallenge(mode,options={}){\r\n const current=EXERCISES[mode];if(!current)return null;\r\n const level=workoutLevel(mode),choices=GROUP_EXERCISES[current.group].filter(e=>workoutKind(e.id)===level.kind),state=readPerformanceProgress(options);\r\n const cleared=Object.values(state.sessions).some(s=>{\r\n  if(s.group!==current.group||s.kind==='hold'&&level.kind!=='hold'||s.kind==='reps'&&level.kind!=='reps'||!['hold','reps'].includes(s.kind)&&level.kind!=='cardio')return false;\r\n  if(s.kind==='hold')return (s.perDifficultyContinuous?.[level.difficulty]??(s.difficulty===level.difficulty?s.continuous:0))>=300;\r\n  return s.difficulty===level.difficulty&&(s.kind==='reps'?s.value>=15:s.kind==='sprint'?s.value>=5:s.value>=300);\r\n });\r\n const next=cleared?choices.find(e=>DIFFICULTIES.indexOf(workoutLevel(e.id).difficulty)>DIFFICULTIES.indexOf(level.difficulty))||current:current;\r\n const eligibility=workoutEligibility(next.id,options);if(!eligibility.allowed)return {allowed:false,reason:eligibility.reason};\r\n const info=workoutLevel(next.id);return {allowed:true,mode:next.id,name:next.name,goal:info.target,unit:info.unit,difficulty:info.label,line:info.unlock};\r\n}\r\nexport function mountWorkoutRoute({mode,busy,pending,onNext}){\r\n const card=document.createElement('section');card.className='workout-route';card.setAttribute('aria-label','Your performance progression');\r\n card.innerHTML='<small>PERFORMANCE PROGRESSION</small><p data-next role=\"status\"></p><p data-rounds></p><button type=\"button\" data-follow>Preview exercise →</button><details><summary>Difficulty milestones</summary><ol data-path></ol><p>Choose any level when ready. Holds and working reps have separate targets. Cosmetic XP does not unlock exercises.</p></details>';\r\n document.querySelector('#podGoals .pod-goals-menu').append(card);\r\n const rest=document.createElement('section');rest.className='workout-route rest-challenge';rest.hidden=true;rest.setAttribute('aria-label','Next performance challenge');rest.innerHTML='<p data-line></p><strong data-next></strong><p data-rounds></p>';document.querySelector('.rest-receipt').after(rest);\r\n const suggestion=()=>pending()?null:nextPerformanceChallenge(mode());\r\n function render(){\r\n  const next=suggestion(),level=workoutLevel(mode()),waiting=pending();\r\n  card.querySelector('[data-next]').textContent=waiting?'Saving your performance…':next?.allowed?`${next.difficulty} · ${next.name}`:next?.reason||'Choose an exercise to see its milestones.';\r\n  card.querySelector('[data-rounds]').textContent=level?level.unlock:'';\r\n  const button=card.querySelector('[data-follow]');button.disabled=busy()||!next?.allowed;\r\n  card.querySelector('[data-path]').replaceChildren(...DIFFICULTIES.map((d,i)=>{const li=document.createElement('li');li.textContent=`${d[0].toUpperCase()+d.slice(1)} · weapon tiers ${i*5+1}–${i*5+5}`;return li;}));\r\n  if(!rest.hidden){rest.querySelector('[data-line]').textContent='Recover first. Tap the rest boss for daily pack rewards.';rest.querySelector('[data-next]').textContent=next?.allowed?`${next.difficulty} · ${next.name}`:next?.reason||'Performance saved';rest.querySelector('[data-rounds]').textContent=next?.allowed?next.line:'';}\r\n }\r\n card.querySelector('[data-follow]').onclick=()=>{const next=suggestion();if(next?.allowed&&!busy())onNext(next);};\r\n for(const event of ['myr5:account-progress','myr5:account-cleared','myr5:movement-configured','myr5:performance-progress'])window.addEventListener(event,render);\r\n document.addEventListener('visibilitychange',()=>{if(!document.hidden)render();});\r\n render();return {render,suggestion,showResult(){rest.hidden=false;render();},hideResult(){rest.hidden=true;},canStart(id){return !pending()&&workoutEligibility(id).allowed;}};\r\n}\r\n","workout-route.mjs":"import {EXERCISES,FOCUS_GROUPS,GROUP_EXERCISES} from './exercise-library.mjs';\r\n\r\nexport const DAILY_ROUND_LIMIT=5;\r\nexport const exerciseFamily=mode=>EXERCISES[mode]?.group||(mode==='jumping'?'cardio':null);\r\nexport const exerciseUnit=mode=>['hold','pace'].includes(EXERCISES[mode]?.kind)?'seconds':EXERCISES[mode]?.kind==='steps'?'steps':'reps';\r\nexport const ROUTE_LINES=Object.freeze({\r\n advance:\"That wasn't enough to impress my clipboard. Ready for the next level?\",\r\n max:\"Maximum difficulty? Fine. One more than your last round. Now we're negotiating.\",\r\n limit:\"Five rounds. Even I have to respect the paperwork. This exercise family is done for today.\",\r\n rest:'Rest first. The next challenge can wait.'\r\n});\r\n\r\nconst dateFormats=new Map();\r\nexport function routeDay(now,timezone){\r\n let format=dateFormats.get(timezone);if(!format){format=new Intl.DateTimeFormat('en-CA',{timeZone:timezone,year:'numeric',month:'2-digit',day:'2-digit'});if(dateFormats.size>=32)dateFormats.delete(dateFormats.keys().next().value);dateFormats.set(timezone,format);}\r\n const fields=Object.fromEntries(format.formatToParts(new Date(now)).map(p=>[p.type,p.value]));\r\n return `${fields.year}-${fields.month}-${fields.day}`;\r\n}\r\nexport function makeExerciseRoute(history,today,{day,timezone,goals={}}){\r\n const records=new Map(history.map(r=>[r.mode,r])),rounds=Object.fromEntries(FOCUS_GROUPS.map(g=>[g.id,0]));\r\n for(const row of today){const group=exerciseFamily(row.mode);if(group)rounds[group]+=Number(row.sets)||0;}\r\n const groups=Object.fromEntries(FOCUS_GROUPS.map(group=>{\r\n  const choices=GROUP_EXERCISES[group.id];let highest=-1;\r\n  const steps=choices.map((m,index)=>{const complete=Number(records.get(m.id)?.sets)>0;if(complete)highest=index;return {mode:m.id,name:m.name,level:index+1,complete};});\r\n  const index=Math.min(choices.length-1,highest+1),movement=choices[index],mastered=highest===choices.length-1,previous=records.get(movement.id);\r\n  const goal=mastered&&Number.isFinite(Number(previous?.value))?Math.floor(Number(previous.value))+1:Number(goals[movement.id])||movement.defaultGoal;\r\n  return [group.id,{id:group.id,name:group.name,steps,mastered,level:index+1,maxLevel:choices.length,today:rounds[group.id],remaining:Math.max(0,DAILY_ROUND_LIMIT-rounds[group.id]),next:{mode:movement.id,name:movement.name,goal:Math.max(1,goal),unit:exerciseUnit(movement.id),group:group.id}}];\r\n }));\r\n return {version:1,day,timezone,limit:DAILY_ROUND_LIMIT,groups};\r\n}\r\nexport function nextChallenge(route,mode){\r\n const current=route?.groups?.[exerciseFamily(mode)];if(!current)return null;\r\n if(current.remaining)return {...current.next,line:current.mastered?ROUTE_LINES.max:ROUTE_LINES.advance,level:current.level,maxLevel:current.maxLevel,round:current.today+1};\r\n // Move through the existing focus order after a family's daily allowance.\r\n const index=FOCUS_GROUPS.findIndex(g=>g.id===current.id),ordered=[...FOCUS_GROUPS.slice(index+1),...FOCUS_GROUPS.slice(0,index)];\r\n const available=ordered.map(g=>route.groups[g.id]).filter(g=>g.remaining>0),next=available.find(g=>!g.mastered)||available[0];\r\n return next?{...next.next,line:ROUTE_LINES.limit,level:next.level,maxLevel:next.maxLevel,round:next.today+1,changedFamily:true}:null;\r\n}\r\n","wrangler.coach-world-preview.json":"{\n  \"name\": \"myr5-coach-world-1016\",\n  \"main\": \"dist/server/index.js\",\n  \"compatibility_date\": \"2026-05-15\",\n  \"compatibility_flags\": [\n    \"nodejs_compat\"\n  ],\n  \"workers_dev\": true,\n  \"preview_urls\": false,\n  \"routes\": [\n    {\n      \"pattern\": \"coach-world.mominc.online\",\n      \"custom_domain\": true\n    }\n  ],\n  \"assets\": {\n    \"directory\": \"dist/client\",\n    \"binding\": \"ASSETS\",\n    \"run_worker_first\": [\n      \"/audio/music/*\"\n    ]\n  },\n  \"observability\": {\n    \"enabled\": true,\n    \"logs\": {\n      \"enabled\": true,\n      \"head_sampling_rate\": 1\n    },\n    \"traces\": {\n      \"enabled\": true,\n      \"head_sampling_rate\": 0.01\n    }\n  },\n  \"triggers\": {\n    \"crons\": [\n      \"* * * * *\"\n    ]\n  },\n  \"vars\": {\n    \"WORKOUT_IMPORTS_ENABLED\": \"true\",\n    \"CLERK_PUBLISHABLE_KEY\": \"pk_live_Y2xlcmsubW9taW5jLm9ubGluZSQ\",\n    \"CLERK_FRONTEND_URL\": \"https://clerk.mominc.online\",\n    \"CLERK_AUTHORIZED_PARTIES\": \"https://coach-world.mominc.online\",\n    \"CLERK_JWT_KEY\": \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3rzkD3s3Q0klhjek/H6t\\n8x9OEYKO7aqAhpbe0vKVfwuc+cRQNVxNFLp1l/ekL49Hmsey+2yfijpSPJZ9gu/d\\nkQ9sgJLdWO+Um4SZEyt7iCwIpqTbtAheWjRpO8SRBqpNl/bRRzqndyr6D60EiYXh\\n0Hval+ebbMVL33IVuq9FwLmndrIHt6kq1pXgg1RuAari9/WlI/75tHum1XcxujLP\\nRCb4jIjRuaq9Q+gfx5snUiBGBTFM4yMPCj29wvQWggcEYHqklKRqc8w4yXUX7vEb\\nscoZuuvV1nFYgR4dA0DLopBa4jPSdZwLaefYsj8A0RY/abXW3pWYgNDSIXzmGo9W\\nBwIDAQAB\\n-----END PUBLIC KEY-----\\n\",\n    \"RELEASE_ORIGIN\": \"https://coach-world.mominc.online\"\n  },\n  \"d1_databases\": [\n    {\n      \"binding\": \"DB\",\n      \"database_name\": \"myr5-coach-world-1016\",\n      \"database_id\": \"7fd38892-c994-4a0a-9486-fe4311650591\",\n      \"migrations_dir\": \"drizzle\"\n    }\n  ]\n}\n","wrangler.jsonc":"// MyR5 Coach on Cloudflare Workers (replaces OpenAI Sites hosting).\r\n// `npm run build` first; the Worker is dist/server/index.js and the static app is dist/client.\r\n// Production: `wrangler deploy`. Staging (workers.dev, empty D1, no cron): `wrangler deploy --env staging`.\r\n// Secrets are `wrangler secret put <NAME>` per Worker, never in this file.\r\n{\r\n\t\"$schema\": \"node_modules/wrangler/config-schema.json\",\r\n\t\"name\": \"myr5-coach\",\r\n\t\"main\": \"dist/server/index.js\",\r\n\t\"compatibility_date\": \"2026-05-15\",\r\n\t// The Vite SSR bundle resolves @clerk/backend's crypto to `node:crypto` (webcrypto), as on Sites.\r\n\t\"compatibility_flags\": [\"nodejs_compat\"],\r\n\t\"workers_dev\": false,\r\n\t\"preview_urls\": false,\r\n\t// Production custom domain. Cloudflare provisions DNS and TLS for this Worker route.\r\n\t\"routes\": [{ \"pattern\": \"myr5.mominc.online\", \"custom_domain\": true }],\r\n\t// Assets first, as on Sites: `/` serves index.html (200), /pose.html 307s to /pose, and\r\n\t// unmatched paths and the bounded /audio/music/* byte-serving route reach the Worker.\r\n\t\"assets\": { \"directory\": \"dist/client\", \"binding\": \"ASSETS\", \"run_worker_first\": [\"/audio/music/*\"] },\r\n\t\"observability\": {\r\n\t\t\"enabled\": true,\r\n\t\t\"logs\": { \"enabled\": true, \"head_sampling_rate\": 1 },\r\n\t\t\"traces\": { \"enabled\": true, \"head_sampling_rate\": 0.01 }\r\n\t},\r\n\t\"triggers\": { \"crons\": [\"* * * * *\"] },\r\n\t// Public values (live /api/auth/config serves the Clerk ones). Clerk sign-in also needs the\r\n\t// CLERK_JWT_KEY secret; release email stays off unless the RESEND_API_KEY secret exists.\r\n\t\"vars\": {\r\n\t\t\"WORKOUT_IMPORTS_ENABLED\": \"true\",\r\n\t\t\"CLERK_PUBLISHABLE_KEY\": \"pk_live_Y2xlcmsubW9taW5jLm9ubGluZSQ\",\r\n\t\t\"CLERK_FRONTEND_URL\": \"https://clerk.mominc.online\",\r\n\t\t\"CLERK_AUTHORIZED_PARTIES\": \"https://myr5.mominc.online\",\r\n\t\t\"RELEASE_ORIGIN\": \"https://myr5.mominc.online\",\r\n\t\t\"SPOTIFY_CLIENT_ID\": \"9eb27ceb2aed4ee59517d5b0854a8b79\",\r\n\t\t\"SPOTIFY_REDIRECT_URI\": \"https://myr5.mominc.online/api/spotify/callback\",\r\n\t\t\"RELEASE_EMAIL_FROM\": \"dispatch@mominc.online\",\r\n\t\t\"VAPID_SUBJECT\": \"https://myr5.mominc.online\"\r\n\t},\r\n\t\"d1_databases\": [\r\n\t\t{\r\n\t\t\t\"binding\": \"DB\",\r\n\t\t\t\"database_name\": \"myr5-coach\",\r\n\t\t\t\"database_id\": \"5731afde-1437-4fcf-9b25-1ad868b24fe3\",\r\n\t\t\t\"migrations_dir\": \"drizzle\"\r\n\t\t}\r\n\t],\r\n\t\"env\": {\r\n\t\t\"staging\": {\r\n\t\t\t\"name\": \"myr5-coach-staging\",\r\n\t\t\t\"workers_dev\": true,\r\n\t\t\"routes\": [],\r\n\t\t\t\"triggers\": { \"crons\": [] },\r\n\t\t\t// No Clerk (its production keys only accept mominc.online) and no release email on staging.\r\n\t\t\t\"vars\": { \"WORKOUT_IMPORTS_ENABLED\": \"true\" },\r\n\t\t\t\"d1_databases\": [\r\n\t\t\t\t{\r\n\t\t\t\t\t\"binding\": \"DB\",\r\n\t\t\t\t\t\"database_name\": \"myr5-coach-staging\",\r\n\t\t\t\t\t\"database_id\": \"4b93f2db-21cb-4697-95ef-4611f07818e8\",\r\n\t\t\t\t\t\"migrations_dir\": \"drizzle\"\r\n\t\t\t\t}\r\n\t\t\t]\r\n\t\t}\r\n\t}\r\n}\r\n"}